public void TestCleanup()
 {
     if (RuntimeInformation.IsOSPlatform(OSPlatform.OSX))
     {
         MacKeyChain.DeleteKey(ServiceName, AccountName);
     }
 }
示例#2
0
        public void TestRetrieveKey()
        {
            string data = "applesauce";

            MacKeyChain.WriteKey(ServiceName, AccountName, Encoding.UTF8.GetBytes(data));
            VerifyKey(ServiceName, AccountName, expectedData: data);
        }
示例#3
0
        public void Write(byte[] data)
        {
            _logger.LogInformation("Before write to mac keychain");
            MacKeyChain.WriteKey(_keyChainServiceName, _keyChainAccountName, data);
            _logger.LogInformation("After write to mac keychain");

            // Change the "last modified" attribute and trigger file changed events
            FileIOWithRetries.TouchFile(_cacheFilePath, _logger);
        }
示例#4
0
        public void Clear()
        {
            _logger.LogInformation("Clearing cache");
            FileIOWithRetries.DeleteCacheFile(_cacheFilePath, _logger);

            _logger.LogInformation("Before delete mac keychain");
            MacKeyChain.DeleteKey(_keyChainServiceName, _keyChainAccountName);
            _logger.LogInformation("After delete mac keychain");
        }
示例#5
0
        private static void VerifyKeyIsNull(string serviceName, string accountName)
        {
            if (MacKeyChain.RetrieveKey(serviceName, accountName) != null)
            {
#pragma warning disable CA2201 // Do not raise reserved exception types
                throw new Exception(string.Format(CultureInfo.CurrentCulture, "key exists when it shouldn't be. keychainData=\"{0}\"", Encoding.UTF8.GetString(MacKeyChain.RetrieveKey(serviceName, accountName))));
#pragma warning restore CA2201 // Do not raise reserved exception types
            }
        }
示例#6
0
        public void Write(byte[] data)
        {
            _logger.LogInformation("Before write to mac keychain");
            MacKeyChain.WriteKey(_keyChainServiceName, _keyChainAccountName, data);
            _logger.LogInformation("After write to mac keychain");

            // Change data to 1 byte so we can write it to the cache file to update the last write time using the same write code used for windows.
            FileIOWithRetries.WriteDataToFile(_cacheFilePath, new byte[] { 1 }, _logger);
        }
示例#7
0
        public byte[] Read()
        {
            _logger.LogInformation("ReadDataCore");

            _logger.LogInformation($"ReadDataCore, Before reading from mac keychain");
            byte[] fileData = MacKeyChain.RetrieveKey(_keyChainServiceName, _keyChainAccountName, _logger);
            _logger.LogInformation($"ReadDataCore, read '{fileData?.Length}' bytes from the keychain");

            return(fileData);
        }
示例#8
0
        private static void VerifyKey(string serviceName, string accountName, string expectedData)
        {
            string keychainData = Encoding.UTF8.GetString(MacKeyChain.RetrieveKey(serviceName, accountName));

            if (!keychainData.Equals(expectedData))
            {
#pragma warning disable CA2201 // Do not raise reserved exception types
                throw new Exception(string.Format(CultureInfo.CurrentCulture, "keychainData=\"{0}\" doesn't match expected data=\"{1}\"", keychainData, expectedData));
#pragma warning restore CA2201 // Do not raise reserved exception types
            }
        }
示例#9
0
        public void TestWriteSameKeyTwiceWithDifferentData()
        {
            string data = "applesauce";

            MacKeyChain.WriteKey(ServiceName, AccountName, Encoding.UTF8.GetBytes(data));
            VerifyKey(ServiceName, AccountName, expectedData: data);

            data = "tomatosauce";
            MacKeyChain.WriteKey(ServiceName, AccountName, Encoding.UTF8.GetBytes(data));
            VerifyKey(ServiceName, AccountName, expectedData: data);
        }
示例#10
0
        private void ClearCore()
        {
            _logger.TraceEvent(TraceEventType.Information, /*id*/ 0, "Clearing cache");
            bool cacheFileExists = File.Exists(CacheFilePath);

            _logger.TraceEvent(TraceEventType.Information, /*id*/ 0, $"ReadDataCore Cache file exists '{cacheFileExists}'");

            TryProcessFile(() =>
            {
                _logger.TraceEvent(TraceEventType.Information, /*id*/ 0, "Before deleting the cache file");
                try
                {
                    File.Delete(CacheFilePath);
                }
                catch (Exception e)
                {
                    _logger.TraceEvent(TraceEventType.Error, /*id*/ 0, $"Problem deleting the cache file '{e}'");
                }

                _logger.TraceEvent(TraceEventType.Information, /*id*/ 0, $"After deleting the cache file.");
            });

            if (SharedUtilities.IsMacPlatform())
            {
                _logger.TraceEvent(TraceEventType.Information, /*id*/ 0, "Before delete mac keychain");
                MacKeyChain.DeleteKey(
                    _creationProperties.MacKeyChainServiceName,
                    _creationProperties.MacKeyChainAccountName);
                _logger.TraceEvent(TraceEventType.Information, /*id*/ 0, "After delete mac keychain");
            }
            else if (SharedUtilities.IsLinuxPlatform())
            {
                _logger.TraceEvent(TraceEventType.Information, /*id*/ 0, $"Before deletring secret from linux keyring");

                IntPtr error = IntPtr.Zero;

                Libsecret.secret_password_clear_sync(
                    schema: GetLibsecretSchema(),
                    cancellable: IntPtr.Zero,
                    error: out error,
                    attribute1Type: _creationProperties.KeyringAttribute1.Key,
                    attribute1Value: _creationProperties.KeyringAttribute1.Value,
                    attribute2Type: _creationProperties.KeyringAttribute2.Key,
                    attribute2Value: _creationProperties.KeyringAttribute2.Value,
                    end: IntPtr.Zero);

                if (error != IntPtr.Zero)
                {
                    try
                    {
                        GError err = (GError)Marshal.PtrToStructure(error, typeof(GError));
                        _logger.TraceEvent(TraceEventType.Error, /*id*/ 0, $"An error was encountered while clearing secret from keyring in the {nameof(MsalCacheStorage)} domain:'{err.Domain}' code:'{err.Code}' message:'{err.Message}'");
                    }
                    catch (Exception e)
                    {
                        _logger.TraceEvent(TraceEventType.Error, /*id*/ 0, $"An exception was encountered while processing libsecret error information during clearing secret in the {nameof(MsalCacheStorage)} ex:'{e}'");
                    }
                }

                _logger.TraceEvent(TraceEventType.Information, /*id*/ 0, "After deleting secret from linux keyring");
            }
            else if (!SharedUtilities.IsWindowsPlatform())
            {
                _logger.TraceEvent(TraceEventType.Information, /*id*/ 0, "Not supported platform");
                throw new PlatformNotSupportedException();
            }
        }
示例#11
0
        private void WriteDataCore(byte[] data)
        {
            if (data == null)
            {
                throw new ArgumentNullException(nameof(data));
            }

            _logger.TraceEvent(TraceEventType.Information, /*id*/ 0, $"Write Data core, going to write '{data.Length}' to the storage");

            if (SharedUtilities.IsMacPlatform() || SharedUtilities.IsLinuxPlatform())
            {
                if (SharedUtilities.IsMacPlatform())
                {
                    _logger.TraceEvent(TraceEventType.Information, /*id*/ 0, "Before write to mac keychain");
                    MacKeyChain.WriteKey(
                        _creationProperties.MacKeyChainServiceName,
                        _creationProperties.MacKeyChainAccountName,
                        data);

                    _logger.TraceEvent(TraceEventType.Information, /*id*/ 0, "After write to mac keychain");
                }
                else if (SharedUtilities.IsLinuxPlatform())
                {
                    _logger.TraceEvent(TraceEventType.Information, /*id*/ 0, "Before saving to linux keyring");

                    IntPtr error = IntPtr.Zero;

                    Libsecret.secret_password_store_sync(
                        schema: GetLibsecretSchema(),
                        collection: _creationProperties.KeyringCollection,
                        label: _creationProperties.KeyringSecretLabel,
                        password: Convert.ToBase64String(data),
                        cancellable: IntPtr.Zero,
                        error: out error,
                        attribute1Type: _creationProperties.KeyringAttribute1.Key,
                        attribute1Value: _creationProperties.KeyringAttribute1.Value,
                        attribute2Type: _creationProperties.KeyringAttribute2.Key,
                        attribute2Value: _creationProperties.KeyringAttribute2.Value,
                        end: IntPtr.Zero);

                    if (error != IntPtr.Zero)
                    {
                        try
                        {
                            GError err = (GError)Marshal.PtrToStructure(error, typeof(GError));
                            _logger.TraceEvent(TraceEventType.Error, /*id*/ 0, $"An error was encountered while saving secret to keyring in the {nameof(MsalCacheStorage)} domain:'{err.Domain}' code:'{err.Code}' message:'{err.Message}'");
                        }
                        catch (Exception e)
                        {
                            _logger.TraceEvent(TraceEventType.Error, /*id*/ 0, $"An exception was encountered while processing libsecret error information during saving in the {nameof(MsalCacheStorage)} ex:'{e}'");
                        }
                    }

                    _logger.TraceEvent(TraceEventType.Information, /*id*/ 0, "After saving to linux keyring");
                }

                // Change data to 1 byte so we can write it to the cache file to update the last write time using the same write code used for windows.
                data = new byte[] { 1 };
            }

            string directoryForCacheFile = Path.GetDirectoryName(CacheFilePath);

            if (!Directory.Exists(directoryForCacheFile))
            {
                string directory = Path.GetDirectoryName(CacheFilePath);
                _logger.TraceEvent(TraceEventType.Information, /*id*/ 0, $"Creating directory '{directory}'");
                Directory.CreateDirectory(directory);
            }

            _logger.TraceEvent(TraceEventType.Information, /*id*/ 0, $"Cache file directory exists. '{Directory.Exists(directoryForCacheFile)}' now writing cache file");

            TryProcessFile(() =>
            {
                File.WriteAllBytes(CacheFilePath, data);
            });
        }
示例#12
0
        private byte[] ReadDataCore()
        {
            _logger.TraceEvent(TraceEventType.Information, /*id*/ 0, "ReadDataCore");

            byte[] fileData = null;

            bool cacheFileExists = File.Exists(CacheFilePath);

            _logger.TraceEvent(TraceEventType.Information, /*id*/ 0, $"ReadDataCore Cache file exists '{cacheFileExists}'");

            if (SharedUtilities.IsWindowsPlatform())
            {
                if (cacheFileExists)
                {
                    TryProcessFile(() =>
                    {
                        fileData = File.ReadAllBytes(CacheFilePath);
                        _logger.TraceEvent(TraceEventType.Information, /*id*/ 0, $"ReadDataCore, read '{fileData.Length}' bytes from the file");
                    });
                }
            }
            else if (SharedUtilities.IsMacPlatform())
            {
                _logger.TraceEvent(TraceEventType.Information, /*id*/ 0, $"ReadDataCore, Before reading from mac keychain");
                fileData = MacKeyChain.RetrieveKey(_creationProperties.MacKeyChainServiceName, _creationProperties.MacKeyChainAccountName, _logger);

                _logger.TraceEvent(TraceEventType.Information, /*id*/ 0, $"ReadDataCore, read '{fileData?.Length}' bytes from the keychain");
            }
            else if (SharedUtilities.IsLinuxPlatform())
            {
                _logger.TraceEvent(TraceEventType.Information, /*id*/ 0, $"ReadDataCore, Before reading from linux keyring");

                IntPtr error = IntPtr.Zero;

                string secret = Libsecret.secret_password_lookup_sync(
                    schema: GetLibsecretSchema(),
                    cancellable: IntPtr.Zero,
                    error: out error,
                    attribute1Type: _creationProperties.KeyringAttribute1.Key,
                    attribute1Value: _creationProperties.KeyringAttribute1.Value,
                    attribute2Type: _creationProperties.KeyringAttribute2.Key,
                    attribute2Value: _creationProperties.KeyringAttribute2.Value,
                    end: IntPtr.Zero);

                if (error != IntPtr.Zero)
                {
                    try
                    {
                        GError err = (GError)Marshal.PtrToStructure(error, typeof(GError));
                        _logger.TraceEvent(TraceEventType.Error, /*id*/ 0, $"An error was encountered while reading secret from keyring in the {nameof(MsalCacheStorage)} domain:'{err.Domain}' code:'{err.Code}' message:'{err.Message}'");
                    }
                    catch (Exception e)
                    {
                        _logger.TraceEvent(TraceEventType.Error, /*id*/ 0, $"An exception was encountered while processing libsecret error information during reading in the {nameof(MsalCacheStorage)} ex:'{e}'");
                    }
                }
                else if (string.IsNullOrEmpty(secret))
                {
                    _logger.TraceEvent(TraceEventType.Error, /*id*/ 0, "No matching secret found in the keyring");
                }
                else
                {
                    _logger.TraceEvent(TraceEventType.Information, /*id*/ 0, "Base64 decoding the secret string");
                    fileData = Convert.FromBase64String(secret);
                    _logger.TraceEvent(TraceEventType.Information, /*id*/ 0, $"ReadDataCore, read '{fileData?.Length}' bytes from the keyring");
                }
            }
            else
            {
                _logger.TraceEvent(TraceEventType.Error, /*id*/ 0, "Platform not supported");
                throw new PlatformNotSupportedException();
            }

            return(fileData);
        }
示例#13
0
 public void TestDeleteNonExistingKey()
 {
     MacKeyChain.DeleteKey(ServiceName, AccountName);
 }
示例#14
0
 public void TestCleanup()
 {
     MacKeyChain.DeleteKey(ServiceName, AccountName);
 }
示例#15
0
 public void TestInitialize()
 {
     MacKeyChain.DeleteKey(ServiceName, AccountName);
 }