/// <summary> /// Finds all entries with a given group and tag (or multiple) /// </summary> /// <param name="sourceDb">Database to search for the entries.</param> /// <param name="groups">Groups to search for (multiple separated by ,).</param> /// <param name="tags">Tag to search for (multiple separated by ,).</param> /// <returns>A PwObjectList with all metching entries.</returns> private static PwObjectList <PwEntry> FindEntriesByGroupAndTag(PwDatabase sourceDb, string groups, string tags) { PwObjectList <PwEntry> entries = new PwObjectList <PwEntry>(); // Tag and group export foreach (string group in groups.Split(',').Select(x => x.Trim())) { PwGroup groupToExport = sourceDb.RootGroup.GetFlatGroupList().FirstOrDefault(g => g.Name == group); if (groupToExport == null) { throw new ArgumentException("No group with the name of the Group-Setting found."); } foreach (string tag in tags.Split(',').Select(x => x.Trim())) { PwObjectList <PwEntry> tagEntries = new PwObjectList <PwEntry>(); groupToExport.FindEntriesByTag(tag, tagEntries, true); // Prevent duplicated entries IEnumerable <PwUuid> existingUuids = entries.Select(x => x.Uuid); List <PwEntry> entriesToAdd = tagEntries.Where(x => !existingUuids.Contains(x.Uuid)).ToList(); entries.Add(entriesToAdd); } } return(entries); }
private static PwObjectList <PwEntry> GetMatching(PwDatabase sourceDb, Settings settings) { PwObjectList <PwEntry> entries = new PwObjectList <PwEntry>(); if (!string.IsNullOrEmpty(settings.Tag) && string.IsNullOrEmpty(settings.Group)) { // Tag only export sourceDb.RootGroup.FindEntriesByTag(settings.Tag, entries, true); } else if (string.IsNullOrEmpty(settings.Tag) && !string.IsNullOrEmpty(settings.Group)) { // Tag and group export PwGroup groupToExport = sourceDb.RootGroup.GetFlatGroupList().FirstOrDefault(g => g.Name == settings.Group); if (groupToExport == null) { throw new ArgumentException("No group with the name of the Group-Setting found."); } entries = groupToExport.GetEntries(true); } else if (!string.IsNullOrEmpty(settings.Tag) && !string.IsNullOrEmpty(settings.Group)) { // Tag and group export PwGroup groupToExport = sourceDb.RootGroup.GetFlatGroupList().FirstOrDefault(g => g.Name == settings.Group); if (groupToExport == null) { throw new ArgumentException("No group with the name of the Group-Setting found."); } groupToExport.FindEntriesByTag(settings.Tag, entries, true); } else { throw new ArgumentException("At least one of Tag or ExportFolderName must be set."); } return(entries); }
private static PwObjectList <PwEntry> GetMatching(PwDatabase sourceDb, Settings settings) { PwObjectList <PwEntry> entries = new PwObjectList <PwEntry>(); if (!string.IsNullOrEmpty(settings.Tag) && string.IsNullOrEmpty(settings.Group)) { // Tag only export // Support multiple tag (Tag1,Tag2) foreach (string tag in settings.Tag.Split(',')) { PwObjectList <PwEntry> tagEntries = new PwObjectList <PwEntry>(); sourceDb.RootGroup.FindEntriesByTag(tag, tagEntries, true); // Prevent duplicated entries IEnumerable <PwUuid> existingUuids = entries.Select(x => x.Uuid); List <PwEntry> entriesToAdd = tagEntries.Where(x => !existingUuids.Contains(x.Uuid)).ToList(); entries.Add(entriesToAdd); } } else if (string.IsNullOrEmpty(settings.Tag) && !string.IsNullOrEmpty(settings.Group)) { // Support multiple group (Group1,Group2) foreach (string group in settings.Group.Split(',')) { // Tag and group export PwGroup groupToExport = sourceDb.RootGroup.GetFlatGroupList().FirstOrDefault(g => g.Name == group); if (groupToExport == null) { throw new ArgumentException("No group with the name of the Group-Setting found."); } PwObjectList <PwEntry> groupEntries = groupToExport.GetEntries(true); // Prevent duplicated entries IEnumerable <PwUuid> existingUuids = entries.Select(x => x.Uuid); List <PwEntry> entriesToAdd = groupEntries.Where(x => !existingUuids.Contains(x.Uuid)).ToList(); entries.Add(entriesToAdd); } } else if (!string.IsNullOrEmpty(settings.Tag) && !string.IsNullOrEmpty(settings.Group)) { // Tag and group export foreach (string group in settings.Group.Split(',')) { PwGroup groupToExport = sourceDb.RootGroup.GetFlatGroupList().FirstOrDefault(g => g.Name == group); if (groupToExport == null) { throw new ArgumentException("No group with the name of the Group-Setting found."); } foreach (string tag in settings.Tag.Split(',')) { PwObjectList <PwEntry> tagEntries = new PwObjectList <PwEntry>(); groupToExport.FindEntriesByTag(tag, tagEntries, true); // Prevent duplicated entries IEnumerable <PwUuid> existingUuids = entries.Select(x => x.Uuid); List <PwEntry> entriesToAdd = tagEntries.Where(x => !existingUuids.Contains(x.Uuid)).ToList(); entries.Add(entriesToAdd); } } } else { throw new ArgumentException("At least one of Tag or ExportFolderName must be set."); } return(entries); }
/// <summary> /// Exports all entries with the given tag to a new database at the given path. /// </summary> /// <param name="sourceDb">The source database.</param> /// <param name="settings">The settings for this job.</param> private static void CopyToNewDb(PwDatabase sourceDb, Settings settings) { // Create a key for the target database CompositeKey key = new CompositeKey(); bool hasPassword = false; bool hasKeyFile = false; if (!settings.Password.IsEmpty) { byte[] passwordByteArray = settings.Password.ReadUtf8(); key.AddUserKey(new KcpPassword(passwordByteArray)); MemUtil.ZeroByteArray(passwordByteArray); hasPassword = true; } // Load a keyfile for the target database if requested (and add it to the key) if (!string.IsNullOrEmpty(settings.KeyFilePath)) { bool bIsKeyProv = Program.KeyProviderPool.IsKeyProvider(settings.KeyFilePath); if (!bIsKeyProv) { try { key.AddUserKey(new KcpKeyFile(settings.KeyFilePath, true)); hasKeyFile = true; } catch (InvalidDataException exId) { MessageService.ShowWarning(settings.KeyFilePath, exId); } catch (Exception exKf) { MessageService.ShowWarning(settings.KeyFilePath, KPRes.KeyFileError, exKf); } } else { KeyProviderQueryContext ctxKp = new KeyProviderQueryContext( ConnectionInfo, true, false); KeyProvider prov = Program.KeyProviderPool.Get(settings.KeyFilePath); bool bPerformHash = !prov.DirectKey; byte[] pbCustomKey = prov.GetKey(ctxKp); if ((pbCustomKey != null) && (pbCustomKey.Length > 0)) { try { key.AddUserKey(new KcpCustomKey(settings.KeyFilePath, pbCustomKey, bPerformHash)); hasKeyFile = true; } catch (Exception exCkp) { MessageService.ShowWarning(exCkp); } MemUtil.ZeroByteArray(pbCustomKey); } } } // Check if at least a password or a keyfile have been added to the key object if (!hasPassword && !hasKeyFile) { // Fail if not throw new InvalidOperationException("For the target database at least a password or a keyfile is required."); } // Create a new database PwDatabase targetDatabase = new PwDatabase(); // Apply the created key to the new database targetDatabase.New(new IOConnectionInfo(), key); // Copy database settings targetDatabase.Color = sourceDb.Color; targetDatabase.Compression = sourceDb.Compression; targetDatabase.DataCipherUuid = sourceDb.DataCipherUuid; targetDatabase.DefaultUserName = sourceDb.DefaultUserName; targetDatabase.Description = sourceDb.Description; targetDatabase.HistoryMaxItems = sourceDb.HistoryMaxItems; targetDatabase.HistoryMaxSize = sourceDb.HistoryMaxSize; targetDatabase.MaintenanceHistoryDays = sourceDb.MaintenanceHistoryDays; targetDatabase.MasterKeyChangeForce = sourceDb.MasterKeyChangeForce; targetDatabase.MasterKeyChangeRec = sourceDb.MasterKeyChangeRec; targetDatabase.Name = sourceDb.Name; targetDatabase.RecycleBinEnabled = sourceDb.RecycleBinEnabled; if (settings.KeyTransformationRounds == 0) { // keyTransformationRounds was not set -> use the one from the source database settings.KeyTransformationRounds = sourceDb.KdfParameters.GetUInt64(AesKdf.ParamRounds, 0); } // Set keyTransformationRounds (min PwDefs.DefaultKeyEncryptionRounds) targetDatabase.KdfParameters.SetUInt64(AesKdf.ParamRounds, Math.Max(PwDefs.DefaultKeyEncryptionRounds, settings.KeyTransformationRounds)); // Assign the properties of the source root group to the target root group targetDatabase.RootGroup.AssignProperties(sourceDb.RootGroup, false, true); HandleCustomIcon(targetDatabase, sourceDb, sourceDb.RootGroup); // Overwrite the root group name if requested if (!string.IsNullOrEmpty(settings.RootGroupName)) { targetDatabase.RootGroup.Name = settings.RootGroupName; } // Find all entries matching the tag PwObjectList <PwEntry> entries = new PwObjectList <PwEntry>(); if (!string.IsNullOrEmpty(settings.Tag) && string.IsNullOrEmpty(settings.Group)) { // Tag only export sourceDb.RootGroup.FindEntriesByTag(settings.Tag, entries, true); } else if (string.IsNullOrEmpty(settings.Tag) && !string.IsNullOrEmpty(settings.Group)) { // Tag and group export PwGroup groupToExport = sourceDb.RootGroup.GetFlatGroupList().FirstOrDefault(g => g.Name == settings.Group); if (groupToExport == null) { throw new ArgumentException("No group with the name of the Group-Setting found."); } entries = groupToExport.GetEntries(true); } else if (!string.IsNullOrEmpty(settings.Tag) && !string.IsNullOrEmpty(settings.Group)) { // Tag and group export PwGroup groupToExport = sourceDb.RootGroup.GetFlatGroupList().FirstOrDefault(g => g.Name == settings.Group); if (groupToExport == null) { throw new ArgumentException("No group with the name of the Group-Setting found."); } groupToExport.FindEntriesByTag(settings.Tag, entries, true); } else { throw new ArgumentException("At least one of Tag or ExportFolderName must be set."); } // Copy all entries to the new database foreach (PwEntry entry in entries) { // Get or create the target group in the target database (including hierarchy) PwGroup targetGroup = CreateTargetGroupInDatebase(entry, targetDatabase, sourceDb); // Clone entry PwEntry peNew = new PwEntry(false, false); peNew.Uuid = entry.Uuid; peNew.AssignProperties(entry, false, true, true); // Handle custom icon HandleCustomIcon(targetDatabase, sourceDb, entry); // Add entry to the target group in the new database targetGroup.AddEntry(peNew, true); } // Create target folder (if not exist) string targetFolder = Path.GetDirectoryName(settings.TargetFilePath); if (targetFolder == null) { throw new ArgumentException("Can't get target folder."); } Directory.CreateDirectory(targetFolder); // Save the new database under the target path KdbxFile kdbx = new KdbxFile(targetDatabase); using (FileStream outputStream = new FileStream(settings.TargetFilePath, FileMode.Create)) { kdbx.Save(outputStream, null, KdbxFormat.Default, new NullStatusLogger()); } }