Example #1
0
        /// <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);
        }
Example #2
0
        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);
        }
Example #3
0
        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);
        }
Example #4
0
        /// <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());
            }
        }