diff --git a/Exporter.cs b/Exporter.cs index 8279283..6f2a435 100644 --- a/Exporter.cs +++ b/Exporter.cs @@ -9,6 +9,7 @@ using KeePassLib.Keys; using KeePassLib.Serialization; using KeePassLib.Utility; +using System.Text.RegularExpressions; namespace KeePassSubsetExport { @@ -90,7 +91,7 @@ private static PwGroup FindSettingsGroup(PwDatabase sourceDb, string settingsGro private static PwGroup FindGroupRecursive(PwGroup startGroup, string groupName) { - if(startGroup.Name == groupName) + if (startGroup.Name == groupName) { return startGroup; } @@ -183,13 +184,17 @@ private static void CopyToNewDb(PwDatabase sourceDb, Settings settings) CompositeKey key = CreateCompositeKey(settings); // Trigger an export for multiple target dbs (as we could also write to en existing db coping is not an option) - foreach (string targetFilePathLoopVar in settings.TargetFilePath.Split(',')) { + foreach (string targetFilePathLoopVar in settings.TargetFilePath.Split(',')) + { string targetFilePath = targetFilePathLoopVar; // Create or open the target database PwDatabase targetDatabase = CreateTargetDatabase(sourceDb, settings, key, ref targetFilePath); - // Copy database settings - CopyDatabaseSettings(sourceDb, targetDatabase); + if (settings.ExportDatebaseSettings) + { + // Copy database settings + CopyDatabaseSettings(sourceDb, targetDatabase); + } // Copy key derivation function parameters CopyKdfSettings(sourceDb, settings, targetDatabase); @@ -402,7 +407,7 @@ private static void CopyEntriesAndGroups(PwDatabase sourceDb, Settings settings, FieldHelper.GetFieldWRef(entry, sourceDb, PwDefs.UserNameField)); peNew.Strings.Set(PwDefs.PasswordField, FieldHelper.GetFieldWRef(entry, sourceDb, PwDefs.PasswordField)); - + // Handle custom icon HandleCustomIcon(targetDatabase, sourceDb, entry); } @@ -410,31 +415,51 @@ private static void CopyEntriesAndGroups(PwDatabase sourceDb, Settings settings, private static void SaveTargetDatabase(string targetFilePath, PwDatabase targetDatabase, bool overrideTargetDatabase) { - if (!overrideTargetDatabase && File.Exists(targetFilePath)) - { - // Save changes to existing target database - targetDatabase.Save(new NullStatusLogger()); - } - else + Regex rg = new Regex(@".+://.+", RegexOptions.None, TimeSpan.FromMilliseconds(200)); + if (!rg.IsMatch(targetFilePath)) { - // Create target folder (if not exist) - string targetFolder = Path.GetDirectoryName(targetFilePath); - - if (targetFolder == null) + // local file path + if (!overrideTargetDatabase && File.Exists(targetFilePath)) { - throw new ArgumentException("Can't get target folder."); + // Save changes to existing target database + targetDatabase.Save(new NullStatusLogger()); } + else + { + // Create target folder (if not exist) + string targetFolder = Path.GetDirectoryName(targetFilePath); - Directory.CreateDirectory(targetFolder); + if (targetFolder == null) + { + throw new ArgumentException("Can't get target folder."); + } - // Save the new database under the target path - KdbxFile kdbx = new KdbxFile(targetDatabase); + Directory.CreateDirectory(targetFolder); - using (FileStream outputStream = new FileStream(targetFilePath, FileMode.Create)) - { - kdbx.Save(outputStream, null, KdbxFormat.Default, new NullStatusLogger()); + // Save the new database under the target path + KdbxFile kdbx = new KdbxFile(targetDatabase); + + using (FileStream outputStream = new FileStream(targetFilePath, FileMode.Create)) + { + kdbx.Save(outputStream, null, KdbxFormat.Default, new NullStatusLogger()); + } } } + else + { + // Non local file (ftp, webdav, ...) + Uri targetUrl = new Uri(targetFilePath); + string[] userAndPw = targetUrl.UserInfo.Split(':'); + IOConnectionInfo conInfo = new IOConnectionInfo + { + Path = Regex.Replace(targetUrl.AbsoluteUri, @"(?<=//)[^@]+@", "", RegexOptions.None, TimeSpan.FromMilliseconds(200)), + CredSaveMode = IOCredSaveMode.NoSave, + UserName = userAndPw[0], + Password = userAndPw[1] + }; + + targetDatabase.SaveAs(conInfo, false, new NullStatusLogger()); + } } private static void CopyKdfSettings(PwDatabase sourceDb, Settings settings, PwDatabase targetDatabase) @@ -497,6 +522,19 @@ private static void CopyDatabaseSettings(PwDatabase sourceDb, PwDatabase targetD private static PwDatabase CreateTargetDatabase(PwDatabase sourceDb, Settings settings, CompositeKey key, ref string targetFilePath) { + Regex rg = new Regex(@".+://.+", RegexOptions.None, TimeSpan.FromMilliseconds(200)); + if (rg.IsMatch(targetFilePath)) + { + // Non local file (ftp, webdav, ...) + // Create a new database + PwDatabase targetDatabaseForUri = new PwDatabase(); + + // Apply the created key to the new database + targetDatabaseForUri.New(new IOConnectionInfo(), key); + + return targetDatabaseForUri; + } + // Default to same folder as sourceDb for target if no directory is specified if (!Path.IsPathRooted(targetFilePath)) { diff --git a/KeePassSubsetExport.Tests/KeePassSubsetExport.Tests.csproj b/KeePassSubsetExport.Tests/KeePassSubsetExport.Tests.csproj index 0496019..83de1fa 100644 --- a/KeePassSubsetExport.Tests/KeePassSubsetExport.Tests.csproj +++ b/KeePassSubsetExport.Tests/KeePassSubsetExport.Tests.csproj @@ -9,7 +9,7 @@ Properties KeePassSubsetExport.Tests KeePassSubsetExport.Tests - v4.7.1 + v4.7.2 512 {3AC096D0-A1C2-E12C-1390-A8335801FDAB};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC} 15.0 @@ -19,6 +19,7 @@ UnitTest + true diff --git a/KeePassSubsetExport.csproj b/KeePassSubsetExport.csproj index d8d072b..b65461f 100644 --- a/KeePassSubsetExport.csproj +++ b/KeePassSubsetExport.csproj @@ -9,7 +9,7 @@ Properties KeePassSubsetExport KeePassSubsetExport - v3.5 + v4.7.2 512 diff --git a/Properties/AssemblyInfo.cs b/Properties/AssemblyInfo.cs index 5004a07..46f6bbc 100644 --- a/Properties/AssemblyInfo.cs +++ b/Properties/AssemblyInfo.cs @@ -16,7 +16,7 @@ [assembly: Guid("3463A091-5683-487E-843F-47086294C5C1")] -[assembly: AssemblyVersion("0.6.0.0")] -[assembly: AssemblyFileVersion("0.6.0.0")] +[assembly: AssemblyVersion("0.7.0.0")] +[assembly: AssemblyFileVersion("0.7.0.0")] [assembly: InternalsVisibleTo("KeePassSubsetExport.Tests")] \ No newline at end of file diff --git a/Properties/Resources.Designer.cs b/Properties/Resources.Designer.cs index ff07340..ffc3675 100644 --- a/Properties/Resources.Designer.cs +++ b/Properties/Resources.Designer.cs @@ -19,7 +19,7 @@ namespace KeePassSubsetExport.Properties { // class via a tool like ResGen or Visual Studio. // To add or remove a member, edit your .ResX file then rerun ResGen // with the /str option, or rebuild your VS project. - [global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "15.0.0.0")] + [global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "16.0.0.0")] [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()] internal class Resources { diff --git a/Settings.cs b/Settings.cs index 3792e08..63c381c 100644 --- a/Settings.cs +++ b/Settings.cs @@ -74,6 +74,10 @@ public class Settings /// If true, only Username and Password will be exported to the target database. /// public bool ExportUserAndPassOnly { get; private set; } + /// + /// If true, the settings of the source database will be exported to the target database. + /// + public bool ExportDatebaseSettings { get; private set; } // Private constructor private Settings() @@ -112,7 +116,7 @@ private static uint GetUIntValue(string key, PwEntry settingsEntry) /// The entry to read the settings from. /// A database to resolve refs in the password field. /// A settings object containing all the settings for this job. - public static Settings Parse(PwEntry settingsEntry, PwDatabase sourceDb=null) + public static Settings Parse(PwEntry settingsEntry, PwDatabase sourceDb = null) { return new Settings() { @@ -131,7 +135,8 @@ public static Settings Parse(PwEntry settingsEntry, PwDatabase sourceDb=null) Argon2ParamMemory = GetUlongValue("SubsetExport_Argon2ParamMemory", settingsEntry), Argon2ParamParallelism = GetUIntValue("SubsetExport_Argon2ParamParallelism", settingsEntry), Disabled = (settingsEntry.Expires && DateTime.Now > settingsEntry.ExpiryTime), - ExportUserAndPassOnly = settingsEntry.Strings.ReadSafe("SubsetExport_ExportUserAndPassOnly").ToLower().Trim() == "true" + ExportUserAndPassOnly = settingsEntry.Strings.ReadSafe("SubsetExport_ExportUserAndPassOnly").ToLower().Trim() == "true", + ExportDatebaseSettings = settingsEntry.Strings.ReadSafe("SubsetExport_ExportDatebaseSettings").ToLower().Trim() != "false", }; } } diff --git a/keepass.version b/keepass.version index 623d3b5..d95b072 100644 --- a/keepass.version +++ b/keepass.version @@ -1,3 +1,3 @@ : -KeePassSubsetExport:0.6.0 +KeePassSubsetExport:0.7.0 :