mirror of
https://github.com/ckaczor/sqltoolsservice.git
synced 2026-01-24 09:35:39 -05:00
MSAL encrypted file system cache (#1945)
This commit is contained in:
@@ -0,0 +1,41 @@
|
||||
//
|
||||
// Copyright (c) Microsoft. All rights reserved.
|
||||
// Licensed under the MIT license. See LICENSE file in the project root for full license information.
|
||||
//
|
||||
|
||||
namespace Microsoft.SqlTools.Authentication.Utility
|
||||
{
|
||||
/// <summary>
|
||||
/// Configuration used by <see cref="Authenticator"/> to perform AAD authentication using MSAL.NET
|
||||
/// </summary>
|
||||
public class AuthenticatorConfiguration
|
||||
{
|
||||
/// <summary>
|
||||
/// Application Client ID to be used.
|
||||
/// </summary>
|
||||
public string AppClientId { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Application name used for public client application instantiation.
|
||||
/// </summary>
|
||||
public string AppName { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Cache folder path, to be used by MSAL.NET to store encrypted token cache.
|
||||
/// </summary>
|
||||
public string CacheFolderPath { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// File name to be used for token storage.
|
||||
/// Full path of file: <see cref="CacheFolderPath"/> \ <see cref="CacheFileName"/>
|
||||
/// </summary>
|
||||
public string CacheFileName { get; set; }
|
||||
|
||||
public AuthenticatorConfiguration(string appClientId, string appName, string cacheFolderPath, string cacheFileName) {
|
||||
AppClientId = appClientId;
|
||||
AppName = appName;
|
||||
CacheFolderPath = cacheFolderPath;
|
||||
CacheFileName = cacheFileName;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,76 @@
|
||||
//
|
||||
// Copyright (c) Microsoft. All rights reserved.
|
||||
// Licensed under the MIT license. See LICENSE file in the project root for full license information.
|
||||
//
|
||||
|
||||
using System.Security.Cryptography;
|
||||
|
||||
namespace Microsoft.SqlTools.Authentication.Utility
|
||||
{
|
||||
public static class EncryptionUtils
|
||||
{
|
||||
/// <summary>
|
||||
/// Encrypts provided byte array with 'aes-256-cbc' algorithm.
|
||||
/// </summary>
|
||||
/// <param name="plainText">Plain text data</param>
|
||||
/// <param name="key">Encryption Key</param>
|
||||
/// <param name="iv">Encryption IV</param>
|
||||
/// <returns>Encrypted data in bytes</returns>
|
||||
/// <exception cref="ArgumentNullException">When arguments are null or empty.</exception>
|
||||
public static byte[] AesEncrypt(byte[] plainText, byte[] key, byte[] iv)
|
||||
{
|
||||
// Check arguments.
|
||||
if (plainText == null || plainText.Length <= 0)
|
||||
{
|
||||
throw new ArgumentNullException(nameof(plainText));
|
||||
}
|
||||
|
||||
using var aes = CreateAes(key, iv);
|
||||
using var encryptor = aes.CreateEncryptor();
|
||||
return encryptor.TransformFinalBlock(plainText, 0, plainText.Length);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Decrypts provided byte array with 'aes-256-cbc' algorithm.
|
||||
/// </summary>
|
||||
/// <param name="cipherText">Encrypted data</param>
|
||||
/// <param name="key">Encryption Key</param>
|
||||
/// <param name="iv">Encryption IV</param>
|
||||
/// <returns>Plain text data in bytes</returns>
|
||||
/// <exception cref="ArgumentNullException">When arguments are null or empty.</exception>
|
||||
public static byte[] AesDecrypt(byte[] cipherText, byte[] key, byte[] iv)
|
||||
{
|
||||
// Check arguments.
|
||||
if (cipherText == null || cipherText.Length <= 0)
|
||||
{
|
||||
throw new ArgumentNullException(nameof(cipherText));
|
||||
}
|
||||
|
||||
using var aes = CreateAes(key, iv);
|
||||
using var decryptor = aes.CreateDecryptor();
|
||||
return decryptor.TransformFinalBlock(cipherText, 0, cipherText.Length);
|
||||
}
|
||||
|
||||
private static Aes CreateAes(byte[] key, byte[] iv)
|
||||
{
|
||||
// Check arguments.
|
||||
if (key == null || key.Length <= 0)
|
||||
{
|
||||
throw new ArgumentNullException(nameof(key));
|
||||
}
|
||||
if (iv == null || iv.Length <= 0)
|
||||
{
|
||||
throw new ArgumentNullException(nameof(iv));
|
||||
}
|
||||
|
||||
var aes = Aes.Create();
|
||||
aes.Mode = CipherMode.CBC;
|
||||
aes.Padding = PaddingMode.PKCS7;
|
||||
aes.KeySize = 256;
|
||||
aes.BlockSize = 128;
|
||||
aes.Key = key;
|
||||
aes.IV = iv;
|
||||
return aes;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -4,7 +4,6 @@
|
||||
//
|
||||
|
||||
using System.Net.Mail;
|
||||
using System.Runtime.InteropServices;
|
||||
using Microsoft.Identity.Client;
|
||||
using SqlToolsLogger = Microsoft.SqlTools.Utility.Logger;
|
||||
|
||||
@@ -30,59 +29,6 @@ namespace Microsoft.SqlTools.Authentication.Utility
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Builds directory path based on environment settings.
|
||||
/// </summary>
|
||||
/// <returns>Application directory path</returns>
|
||||
/// <exception cref="Exception">When called on unsupported platform.</exception>
|
||||
public static string BuildAppDirectoryPath()
|
||||
{
|
||||
var homedir = Environment.GetFolderPath(Environment.SpecialFolder.Personal);
|
||||
|
||||
// Windows
|
||||
if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows))
|
||||
{
|
||||
var appData = Environment.GetEnvironmentVariable("APPDATA");
|
||||
var userProfile = Environment.GetEnvironmentVariable("USERPROFILE");
|
||||
if (appData != null)
|
||||
{
|
||||
return appData;
|
||||
}
|
||||
else if (userProfile != null)
|
||||
{
|
||||
return string.Join(Environment.GetEnvironmentVariable("USERPROFILE"), "AppData", "Roaming");
|
||||
}
|
||||
else
|
||||
{
|
||||
throw new Exception("Not able to find APPDATA or USERPROFILE");
|
||||
}
|
||||
}
|
||||
|
||||
// Mac
|
||||
else if (RuntimeInformation.IsOSPlatform(OSPlatform.OSX))
|
||||
{
|
||||
return string.Join(homedir, "Library", "Application Support");
|
||||
}
|
||||
|
||||
// Linux
|
||||
else if (RuntimeInformation.IsOSPlatform(OSPlatform.Linux))
|
||||
{
|
||||
var xdgConfigHome = Environment.GetEnvironmentVariable("XDG_CONFIG_HOME");
|
||||
if (xdgConfigHome != null)
|
||||
{
|
||||
return xdgConfigHome;
|
||||
}
|
||||
else
|
||||
{
|
||||
return string.Join(homedir, ".config");
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
throw new Exception("Platform not supported");
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Log callback handler used for MSAL Client applications.
|
||||
/// </summary>
|
||||
|
||||
Reference in New Issue
Block a user