public void Clear() { _logger.LogInformation("Clearing cache"); FileIOWithRetries.DeleteCacheFile(_cacheFilePath, _logger); _logger.LogInformation($"Before deleting secret from Linux keyring"); IntPtr error = IntPtr.Zero; Libsecret.secret_password_clear_sync( schema: GetLibsecretSchema(), cancellable: IntPtr.Zero, error: out error, attribute1Type: _attributeKey1, attribute1Value: _attributeValue1, attribute2Type: _attributeKey2, attribute2Value: _attributeValue2, end: IntPtr.Zero); if (error != IntPtr.Zero) { try { GError err = (GError)Marshal.PtrToStructure(error, typeof(GError)); _logger.LogError($"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.LogError($"An exception was encountered while processing libsecret error information during clearing secret in the {nameof(MsalCacheStorage)} ex:'{e}'"); } } _logger.LogInformation("After deleting secret from linux keyring"); }
private IntPtr GetLibsecretSchema() { if (_libsecretSchema == IntPtr.Zero) { _logger.TraceEvent(TraceEventType.Information, /*id*/ 0, "Before creating libsecret schema"); _libsecretSchema = Libsecret.secret_schema_new( name: _creationProperties.KeyringSchemaName, flags: (int)Libsecret.SecretSchemaFlags.SECRET_SCHEMA_DONT_MATCH_NAME, attribute1: _creationProperties.KeyringAttribute1.Key, attribute1Type: (int)Libsecret.SecretSchemaAttributeType.SECRET_SCHEMA_ATTRIBUTE_STRING, attribute2: _creationProperties.KeyringAttribute2.Key, attribute2Type: (int)Libsecret.SecretSchemaAttributeType.SECRET_SCHEMA_ATTRIBUTE_STRING, end: IntPtr.Zero); if (_libsecretSchema == IntPtr.Zero) { _logger.TraceEvent(TraceEventType.Error, /*id*/ 0, $"Failed to create libsecret schema from the {nameof(MsalCacheStorage)}"); } _logger.TraceEvent(TraceEventType.Information, /*id*/ 0, "After creating libsecret schema"); } return(_libsecretSchema); }
private IntPtr GetLibsecretSchema() { if (_libsecretSchema == IntPtr.Zero) { _logger.LogInformation("Before creating libsecret schema"); _libsecretSchema = Libsecret.secret_schema_new( name: _keyringSchemaName, flags: (int)Libsecret.SecretSchemaFlags.SECRET_SCHEMA_DONT_MATCH_NAME, attribute1: _attributeKey1, attribute1Type: (int)Libsecret.SecretSchemaAttributeType.SECRET_SCHEMA_ATTRIBUTE_STRING, attribute2: _attributeKey2, attribute2Type: (int)Libsecret.SecretSchemaAttributeType.SECRET_SCHEMA_ATTRIBUTE_STRING, end: IntPtr.Zero); if (_libsecretSchema == IntPtr.Zero) { _logger.LogError($"Failed to create libsecret schema from the {nameof(MsalCacheStorage)}"); } _logger.LogInformation("After creating libsecret schema"); } return(_libsecretSchema); }
public byte[] Read() { _logger.LogInformation("ReadDataCore"); _logger.LogInformation($"ReadDataCore, Before reading from linux keyring"); byte[] fileData = null; IntPtr error = IntPtr.Zero; string secret = Libsecret.secret_password_lookup_sync( schema: GetLibsecretSchema(), cancellable: IntPtr.Zero, error: out error, attribute1Type: _attributeKey1, attribute1Value: _attributeValue1, attribute2Type: _attributeKey2, attribute2Value: _attributeValue2, end: IntPtr.Zero); if (error != IntPtr.Zero) { try { GError err = (GError)Marshal.PtrToStructure(error, typeof(GError)); _logger.LogError($"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.LogError($"An exception was encountered while processing libsecret error information during reading in the {nameof(MsalCacheStorage)} ex:'{e}'"); } } else if (string.IsNullOrEmpty(secret)) { _logger.LogError("No matching secret found in the keyring"); } else { _logger.LogInformation("Base64 decoding the secret string"); fileData = Convert.FromBase64String(secret); _logger.LogInformation($"ReadDataCore, read '{fileData?.Length}' bytes from the keyring"); } return(fileData); }
public void Write(byte[] data) { _logger.LogInformation("Before saving to linux keyring"); IntPtr error = IntPtr.Zero; Libsecret.secret_password_store_sync( schema: GetLibsecretSchema(), collection: _keyringCollection, label: _keyringSecretLabel, password: Convert.ToBase64String(data), cancellable: IntPtr.Zero, error: out error, attribute1Type: _attributeKey1, attribute1Value: _attributeValue1, attribute2Type: _attributeKey2, attribute2Value: _attributeValue2, end: IntPtr.Zero); if (error != IntPtr.Zero) { try { GError err = (GError)Marshal.PtrToStructure(error, typeof(GError)); _logger.LogError($"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.LogError($"An exception was encountered while processing libsecret error information during saving in the {nameof(MsalCacheStorage)} ex:'{e}'"); } } _logger.LogInformation("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. FileIOWithRetries.WriteDataToFile(_cacheFilePath, new byte[] { 1 }, _logger); }
public void Write(byte[] data) { _logger.LogInformation("Before saving to linux keyring"); IntPtr error = IntPtr.Zero; Libsecret.secret_password_store_sync( schema: GetLibsecretSchema(), collection: _keyringCollection, label: _keyringSecretLabel, password: Convert.ToBase64String(data), cancellable: IntPtr.Zero, error: out error, attribute1Type: _attributeKey1, attribute1Value: _attributeValue1, attribute2Type: _attributeKey2, attribute2Value: _attributeValue2, end: IntPtr.Zero); if (error != IntPtr.Zero) { try { GError err = (GError)Marshal.PtrToStructure(error, typeof(GError)); _logger.LogError($"An error was encountered while saving secret to keyring in the {nameof(Storage)} domain:'{err.Domain}' code:'{err.Code}' message:'{err.Message}'"); } catch (Exception e) { _logger.LogError($"An exception was encountered while processing libsecret error information during saving in the {nameof(Storage)} ex:'{e}'"); } } _logger.LogInformation("After saving to linux keyring"); // Change the "last modified" attribute and trigger file changed events FileIOWithRetries.TouchFile(_cacheFilePath, _logger); }
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(); } }
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); }); }
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); }