From f7800e8a2bde147095637a67f427657e52c8d39b Mon Sep 17 00:00:00 2001 From: verhoek <30193551+verhoek@users.noreply.github.com> Date: Tue, 20 Nov 2018 20:15:00 +0100 Subject: [PATCH] Functionality for backend to retrieve passphrase adhoc on restore, which is convenient for asymmetric gpg encryption. --- Duplicati/Server/Database/Connection.cs | 16 ++++++++++++-- Duplicati/Server/Runner.cs | 21 +++++++++++-------- .../Server/WebServer/RESTMethods/Backup.cs | 6 ++++-- .../Server/WebServer/RESTMethods/Backups.cs | 4 +++- 4 files changed, 33 insertions(+), 14 deletions(-) diff --git a/Duplicati/Server/Database/Connection.cs b/Duplicati/Server/Database/Connection.cs index f64d27c20..0feefc532 100644 --- a/Duplicati/Server/Database/Connection.cs +++ b/Duplicati/Server/Database/Connection.cs @@ -309,7 +309,7 @@ namespace Duplicati.Server.Database lock(m_lock) { var bk = ReadFromDb( - (rd) => new Schedule() { + (rd) => new Schedule { ID = ConvertToInt64(rd, 0), Tags = (ConvertToString(rd, 1) ?? "").Split(new char[] { ',' }, StringSplitOptions.RemoveEmptyEntries), Time = ConvertToDateTime(rd, 2), @@ -322,7 +322,19 @@ namespace Duplicati.Server.Database return bk; } - } + } + + internal Boolean IsPassphraseStored(long id) + { + lock (m_lock) + { + return ReadFromDb( + (rd) => ConvertToBoolean(rd, 0) + , + @"SELECT VALUE != """" FROM ""Option"" WHERE BackupID = ? AND NAME='passphrase'", id) + .FirstOrDefault(); + } + } internal long[] GetScheduleIDsFromTags(string[] tags) { diff --git a/Duplicati/Server/Runner.cs b/Duplicati/Server/Runner.cs index 4224b8753..66e364ec7 100644 --- a/Duplicati/Server/Runner.cs +++ b/Duplicati/Server/Runner.cs @@ -183,18 +183,21 @@ namespace Duplicati.Server filters); } - public static IRunnerData CreateRestoreTask(Duplicati.Server.Serialization.Interface.IBackup backup, string[] filters, DateTime time, string restoreTarget, bool overwrite, bool restore_permissions, bool skip_metadata) + public static IRunnerData CreateRestoreTask(Duplicati.Server.Serialization.Interface.IBackup backup, string[] filters, + DateTime time, string restoreTarget, bool overwrite, bool restore_permissions, + bool skip_metadata, string passphrase = null) { - var dict = new Dictionary(); - dict["time"] = Duplicati.Library.Utility.Utility.SerializeDateTime(time.ToUniversalTime()); + var dict = new Dictionary + { + ["time"] = Library.Utility.Utility.SerializeDateTime(time.ToUniversalTime()), + ["overwrite"] = overwrite? Boolean.TrueString : Boolean.FalseString, + ["restore-permissions"] = restore_permissions ? Boolean.TrueString : Boolean.FalseString, + ["skip-metadata"] = skip_metadata ? Boolean.TrueString : Boolean.FalseString, + ["passphrase"] = passphrase, + ["allow-passphrase-change"] = Boolean.TrueString + }; if (!string.IsNullOrWhiteSpace(restoreTarget)) dict["restore-path"] = SpecialFolders.ExpandEnvironmentVariables(restoreTarget); - if (overwrite) - dict["overwrite"] = "true"; - if (restore_permissions) - dict["restore-permissions"] = "true"; - if (skip_metadata) - dict["skip-metadata"] = "true"; return CreateTask( DuplicatiOperation.Restore, diff --git a/Duplicati/Server/WebServer/RESTMethods/Backup.cs b/Duplicati/Server/WebServer/RESTMethods/Backup.cs index 9eaa9b083..73badb396 100644 --- a/Duplicati/Server/WebServer/RESTMethods/Backup.cs +++ b/Duplicati/Server/WebServer/RESTMethods/Backup.cs @@ -187,7 +187,9 @@ namespace Duplicati.Server.WebServer.RESTMethods var input = info.Request.Form; string[] filters = parsePaths(input["paths"].Value ?? string.Empty); - + + var passphrase = string.IsNullOrEmpty(input["passphrase"].Value) ? null : input["passphrase"].Value; + var time = Duplicati.Library.Utility.Timeparser.ParseTimeInterval(input["time"].Value, DateTime.Now); var restoreTarget = input["restore-path"].Value; var overwrite = Duplicati.Library.Utility.Utility.ParseBool(input["overwrite"].Value, false); @@ -195,7 +197,7 @@ namespace Duplicati.Server.WebServer.RESTMethods var permissions = Duplicati.Library.Utility.Utility.ParseBool(input["permissions"].Value, false); var skip_metadata = Duplicati.Library.Utility.Utility.ParseBool(input["skip-metadata"].Value, false); - var task = Runner.CreateRestoreTask(backup, filters, time, restoreTarget, overwrite, permissions, skip_metadata); + var task = Runner.CreateRestoreTask(backup, filters, time, restoreTarget, overwrite, permissions, skip_metadata, passphrase); Program.WorkThread.AddTask(task); diff --git a/Duplicati/Server/WebServer/RESTMethods/Backups.cs b/Duplicati/Server/WebServer/RESTMethods/Backups.cs index db0b3bb7e..cbb000550 100644 --- a/Duplicati/Server/WebServer/RESTMethods/Backups.cs +++ b/Duplicati/Server/WebServer/RESTMethods/Backups.cs @@ -26,6 +26,7 @@ namespace Duplicati.Server.WebServer.RESTMethods { public class AddOrUpdateBackupData { + public Boolean HasPassphraseStored { get; set;} public Database.Schedule Schedule { get; set;} public Database.Backup Backup { get; set;} } @@ -36,7 +37,8 @@ namespace Duplicati.Server.WebServer.RESTMethods var backups = Program.DataConnection.Backups; var all = from n in backups - select new AddOrUpdateBackupData() { + select new AddOrUpdateBackupData { + HasPassphraseStored = Program.DataConnection.IsPassphraseStored(long.Parse(n.ID)), Backup = (Database.Backup)n, Schedule = (from x in schedules