Implemented support for enabling/disabling encryption

This commit is contained in:
Kenneth Skovhede
2024-08-20 17:10:34 +02:00
parent ae6d5112f8
commit ff196eb284
4 changed files with 52 additions and 5 deletions
@@ -39,6 +39,7 @@ namespace Duplicati.Server.Database
public const int ANY_BACKUP_ID = -1;
public const int SERVER_SETTINGS_ID = -2;
private readonly Dictionary<string, Backup> m_temporaryBackups = new Dictionary<string, Backup>();
private readonly bool m_encryptSensitiveFields;
private static HashSet<string> _encryptedFields =
BackendLoader.Backends.SelectMany(x => x.SupportedCommands ?? [])
.Concat(EncryptionLoader.Modules.SelectMany(x => x.SupportedCommands ?? []))
@@ -54,7 +55,9 @@ namespace Duplicati.Server.Database
])
.ToHashSet(StringComparer.OrdinalIgnoreCase);
public Connection(System.Data.IDbConnection connection, bool disableFieldEncryption)
{
m_encryptSensitiveFields = !disableFieldEncryption;
m_connection = connection;
m_errorcmd = m_connection.CreateCommand();
m_errorcmd.CommandText = @"INSERT INTO ""ErrorLog"" (""BackupID"", ""Message"", ""Exception"", ""Timestamp"") VALUES (?,?,?,?)";
@@ -64,6 +67,31 @@ namespace Duplicati.Server.Database
this.ApplicationSettings = new ServerSettings(this);
}
public void ReWriteAllFieldsIfEncryptionChanged()
{
var activeToken = m_encryptSensitiveFields
? "enc-v1-canary"
: "no-encryption";
// The token is automatically decrypted when the settings are loaded
// In case the password has changed, this will fail and return the encrypted
// hex-string, but will crash before reaching this point
if (this.ApplicationSettings.EncryptionCanaryToken != activeToken)
{
var backups = this.Backups;
foreach (var b in backups)
{
((Backup)b).LoadChildren(this);
AddOrUpdateBackup(b, false, null);
}
this.SetSettings(this.GetSettings(ANY_BACKUP_ID), ANY_BACKUP_ID);
this.ApplicationSettings.EncryptionCanaryToken = m_encryptSensitiveFields
? EncryptedFieldHelper.Encrypt(activeToken)
: activeToken;
}
}
public void LogError(string backupid, string message, Exception ex)
{
lock (m_lock)
@@ -222,7 +250,7 @@ namespace Duplicati.Server.Database
lock (m_lock)
using (var tr = transaction == null ? m_connection.BeginTransaction() : null)
{
List<ISetting> intercepted = values.ToList();
if (m_encryptSensitiveFields)
values = values.Select(x => new Setting
{
Filter = x.Filter,
@@ -582,7 +610,7 @@ namespace Duplicati.Server.Database
n.Name,
n.Description ?? "" , // Description is optional but the column is set to NOT NULL, an additional check is welcome
string.Join(",", n.Tags ?? new string[0]),
EncryptedFieldHelper.Encrypt(n.TargetURL)
m_encryptSensitiveFields ? EncryptedFieldHelper.Encrypt(n.TargetURL) : n.TargetURL,
update ? item.ID : n.DBPath
};
});
@@ -1,4 +1,4 @@
// Copyright (C) 2024, The Duplicati Team
// Copyright (C) 2024, The Duplicati Team
// https://duplicati.com, hello@duplicati.com
//
// Permission is hereby granted, free of charge, to any person obtaining a
@@ -59,6 +59,7 @@ namespace Duplicati.Server.Database
public const string PBKDF_CONFIG = "pbkdf-config";
public const string AUTOGENERATED_PASSPHRASE = "autogenerated-passphrase";
public const string DISABLE_VISUAL_CAPTCHA = "disable-visual-captcha";
public const string ENCRYPTION_CANARY_TOKEN = "encryption-canary-token";
}
private readonly Dictionary<string, string> settings;
@@ -651,6 +652,20 @@ namespace Duplicati.Server.Database
SaveSettings();
}
}
public string EncryptionCanaryToken
{
get
{
return settings[CONST.ENCRYPTION_CANARY_TOKEN];
}
set
{
lock (databaseConnection.m_lock)
settings[CONST.ENCRYPTION_CANARY_TOKEN] = value;
SaveSettings();
}
}
}
}
+2
View File
@@ -46,6 +46,8 @@ Error message: {0}", error); }
public static string TempdirShort { get { return LC.L(@"Temporary storage folder"); } }
public static string WebserverResetJwtConfigDescription { get { return LC.L(@"Reset the JWT configuration, invalidating any issued login tokens"); } }
public static string WebserverDisableVisualCaptchaDescription { get { return LC.L(@"Disable the visual captcha"); } }
public static string DisabledbencryptionLong { get { return LC.L(@"Use this option to disable database encryption of sensitive fields"); } }
public static string DisabledbencryptionShort { get { return LC.L(@"Disable database encryption"); } }
}
internal static class Scheduler
{