예제 #1
0
        public void TestSave()
        {
            var buffer = new byte[4096];

            using (var ms = new MemoryStream(buffer))
            {
                var database = new PwDatabase();
                database.New(new IOConnectionInfo(), new CompositeKey());
                var date = DateTime.Parse(testDate).ToUniversalTime();
                PwDatabase.LocalizedAppName = testLocalizedAppName;
                database.Name                              = testDatabaseName;
                database.NameChanged                       = date;
                database.Description                       = testDatabaseDescription;
                database.DescriptionChanged                = date;
                database.DefaultUserName                   = testDefaultUserName;
                database.DefaultUserNameChanged            = date;
                database.Color                             = Color.Red;
                database.MasterKeyChanged                  = date;
                database.RecycleBinChanged                 = date;
                database.EntryTemplatesGroupChanged        = date;
                database.RootGroup.Uuid                    = PwUuid.Zero;
                database.RootGroup.Name                    = testRootGroupName;
                database.RootGroup.Notes                   = testRootGroupNotes;
                database.RootGroup.DefaultAutoTypeSequence = testRootGroupDefaultAutoTypeSequence;
                database.RootGroup.CreationTime            = date;
                database.RootGroup.LastModificationTime    = date;
                database.RootGroup.LastAccessTime          = date;
                database.RootGroup.ExpiryTime              = date;
                database.RootGroup.LocationChanged         = date;
                var file = new KdbxFile(database);
                file.Save(ms, null, KdbxFormat.PlainXml, null);
            }
            var fileContents = Encoding.UTF8.GetString(buffer).Replace("\0", "");

            if (typeof(KdbxFile).Namespace.StartsWith("KeePassLib.") &&
                Environment.OSVersion.Platform != PlatformID.Win32NT)
            {
                // Upstream KeePassLib does not specify line endings for XmlTextWriter,
                // so it uses native line endings.
                fileContents = fileContents.Replace("\n", "\r\n");
            }
            Assert.That(fileContents, Is.EqualTo(testDatabase));
        }
예제 #2
0
        private bool ExportEx(PwExportInfo pwExportInfo, Stream sOutput,
                              IStatusLogger slLogger, string strXslFile)
        {
            XslCompiledTransform xsl = new XslCompiledTransform();

            try { xsl.Load(strXslFile); }
            catch (Exception exXsl)
            {
                throw new NotSupportedException(strXslFile + MessageService.NewParagraph +
                                                KPRes.NoXslFile + MessageService.NewParagraph + exXsl.Message);
            }

            MemoryStream msDataXml = new MemoryStream();

            PwDatabase pd  = (pwExportInfo.ContextDatabase ?? new PwDatabase());
            KdbxFile   kdb = new KdbxFile(pd);

            kdb.Save(msDataXml, pwExportInfo.DataGroup, KdbxFormat.PlainXml, slLogger);

            byte[] pbData = msDataXml.ToArray();
            msDataXml.Close();
            MemoryStream msDataRead    = new MemoryStream(pbData, false);
            XmlReader    xmlDataReader = XmlReader.Create(msDataRead);

            XmlWriterSettings xws = new XmlWriterSettings();

            xws.CheckCharacters    = false;
            xws.Encoding           = new UTF8Encoding(false);
            xws.NewLineChars       = MessageService.NewLine;
            xws.NewLineHandling    = NewLineHandling.None;
            xws.OmitXmlDeclaration = true;
            xws.ConformanceLevel   = ConformanceLevel.Auto;

            XmlWriter xmlWriter = XmlWriter.Create(sOutput, xws);

            xsl.Transform(xmlDataReader, xmlWriter);
            xmlWriter.Close();
            xmlDataReader.Close();
            msDataRead.Close();

            Array.Clear(pbData, 0, pbData.Length);
            return(true);
        }
예제 #3
0
        public override bool Export(PwExportInfo pwExportInfo, Stream sOutput,
                                    IStatusLogger slLogger)
        {
            PwDatabase pd     = pwExportInfo.ContextDatabase;
            PwGroup    pgRoot = pwExportInfo.DataGroup;

            // Remove everything that requires KDBX 4 or higher;
            // see also KdbxFile.GetMinKdbxVersion

            PwUuid puCipher = pd.DataCipherUuid;

            if (puCipher.Equals(ChaCha20Engine.ChaCha20Uuid))
            {
                pd.DataCipherUuid = StandardAesEngine.AesUuid;
            }

            KdfParameters pKdf   = pd.KdfParameters;
            AesKdf        kdfAes = new AesKdf();

            if (!pKdf.KdfUuid.Equals(kdfAes.Uuid))
            {
                pd.KdfParameters = kdfAes.GetDefaultParameters();
            }

            VariantDictionary vdPublic = pd.PublicCustomData;

            pd.PublicCustomData = new VariantDictionary();

            List <PwGroup>            lCustomGK = new List <PwGroup>();
            List <StringDictionaryEx> lCustomGV = new List <StringDictionaryEx>();
            List <PwEntry>            lCustomEK = new List <PwEntry>();
            List <StringDictionaryEx> lCustomEV = new List <StringDictionaryEx>();

            GroupHandler gh = delegate(PwGroup pg)
            {
                if (pg == null)
                {
                    Debug.Assert(false); return(true);
                }
                if (pg.CustomData.Count > 0)
                {
                    lCustomGK.Add(pg);
                    lCustomGV.Add(pg.CustomData);
                    pg.CustomData = new StringDictionaryEx();
                }
                return(true);
            };
            EntryHandler eh = delegate(PwEntry pe)
            {
                if (pe == null)
                {
                    Debug.Assert(false); return(true);
                }
                if (pe.CustomData.Count > 0)
                {
                    lCustomEK.Add(pe);
                    lCustomEV.Add(pe.CustomData);
                    pe.CustomData = new StringDictionaryEx();
                }
                return(true);
            };

            gh(pgRoot);
            pgRoot.TraverseTree(TraversalMethod.PreOrder, gh, eh);

            try
            {
                KdbxFile kdbx = new KdbxFile(pd);
                kdbx.ForceVersion = KdbxFile.FileVersion32_3_1;
                kdbx.Save(sOutput, pgRoot, KdbxFormat.Default, slLogger);
            }
            finally
            {
                // Restore

                pd.DataCipherUuid   = puCipher;
                pd.KdfParameters    = pKdf;
                pd.PublicCustomData = vdPublic;

                for (int i = 0; i < lCustomGK.Count; ++i)
                {
                    lCustomGK[i].CustomData = lCustomGV[i];
                }
                for (int i = 0; i < lCustomEK.Count; ++i)
                {
                    lCustomEK[i].CustomData = lCustomEV[i];
                }
            }

            return(true);
        }
예제 #4
0
        private static void PerformXmlReplace(PwDatabase pd, XmlReplaceOptions opt,
                                              IStatusLogger sl)
        {
            if (opt.SelectNodesXPath.Length == 0)
            {
                return;
            }
            if (opt.Operation == XmlReplaceOp.None)
            {
                return;
            }

            bool bRemove    = (opt.Operation == XmlReplaceOp.RemoveNodes);
            bool bReplace   = (opt.Operation == XmlReplaceOp.ReplaceData);
            bool bMatchCase = ((opt.Flags & XmlReplaceFlags.CaseSensitive) != XmlReplaceFlags.None);
            bool bRegex     = ((opt.Flags & XmlReplaceFlags.Regex) != XmlReplaceFlags.None);

            Regex rxFind = null;

            if (bReplace && bRegex)
            {
                rxFind = new Regex(opt.FindText, (bMatchCase ? RegexOptions.None :
                                                  RegexOptions.IgnoreCase));
            }

            EnsureStandardFieldsExist(pd);

            KdbxFile     kdbxOrg = new KdbxFile(pd);
            MemoryStream msOrg   = new MemoryStream();

            kdbxOrg.Save(msOrg, null, KdbxFormat.PlainXml, sl);
            byte[] pbXml = msOrg.ToArray();
            msOrg.Close();
            string strXml = StrUtil.Utf8.GetString(pbXml);

            XmlDocument xd = XmlUtilEx.CreateXmlDocument();

            xd.LoadXml(strXml);

            XPathNavigator    xpNavRoot = xd.CreateNavigator();
            XPathNodeIterator xpIt      = xpNavRoot.Select(opt.SelectNodesXPath);

            // XPathNavigators must be cloned to make them independent
            List <XPathNavigator> lNodes = new List <XPathNavigator>();

            while (xpIt.MoveNext())
            {
                lNodes.Add(xpIt.Current.Clone());
            }

            if (lNodes.Count == 0)
            {
                return;
            }

            for (int i = lNodes.Count - 1; i >= 0; --i)
            {
                if ((sl != null) && !sl.ContinueWork())
                {
                    return;
                }

                XPathNavigator xpNav = lNodes[i];

                if (bRemove)
                {
                    xpNav.DeleteSelf();
                }
                else if (bReplace)
                {
                    ApplyReplace(xpNav, opt, rxFind);
                }
                else
                {
                    Debug.Assert(false);
                }                                             // Unknown action
            }

            MemoryStream msMod = new MemoryStream();

            using (XmlWriter xw = XmlUtilEx.CreateXmlWriter(msMod))
            {
                xd.Save(xw);
            }
            byte[] pbMod = msMod.ToArray();
            msMod.Close();

            PwDatabase pdMod = new PwDatabase();

            msMod = new MemoryStream(pbMod, false);
            try
            {
                KdbxFile kdbxMod = new KdbxFile(pdMod);
                kdbxMod.Load(msMod, KdbxFormat.PlainXml, sl);
            }
            catch (Exception)
            {
                throw new Exception(KPRes.XmlModInvalid + MessageService.NewParagraph +
                                    KPRes.OpAborted + MessageService.NewParagraph +
                                    KPRes.DbNoModBy.Replace(@"{PARAM}", @"'" + KPRes.XmlReplace + @"'"));
            }
            finally { msMod.Close(); }

            PrepareModDbForMerge(pdMod, pd);

            pd.Modified          = true;
            pd.UINeedsIconUpdate = true;
            pd.MergeIn(pdMod, PwMergeMethod.Synchronize, sl);
        }
예제 #5
0
        public void Save(Stream stream)
        {
            var kdbx = new KdbxFile(_db);

            kdbx.Save(stream, null, KdbxFormat.Default, null);
        }
        private async void AddKeeButton_Click(object sender, RoutedEventArgs e)
        {
            List <KeepassClass> PassList = new List <KeepassClass>();
            var           dbpath         = "";
            StorageFolder folder         = Windows.Storage.ApplicationData.Current.LocalFolder;
            StorageFile   file           = await folder.GetFileAsync((string)Windows.Storage.ApplicationData.Current.LocalSettings.Values["KeepassLocalFilePath"]);

            if (file != null)
            {
                dbpath = file.Path;
            }
            var masterpw   = MasterPassword.Password;
            var ioConnInfo = new IOConnectionInfo {
                Path = file.Path
            };
            var compKey = new CompositeKey();

            compKey.AddUserKey(new KcpPassword(MasterPassword.Password));
            var db = new KeePassLib.PwDatabase();

            /*  var kdbx = new KdbxFile(db);
             * using (var fs = await file.OpenReadAsync())
             * {
             *    await Task.Run(() =>
             *    {
             *        kdbx.Load(file.Path, KdbxFormat.Default, null);
             *    });
             *
             *   // return new KdbxDatabase(dbFile, db, dbFile.IdFromPath());
             * }*/
            db.Open(ioConnInfo, compKey, null);
            var pwEntry = new PwEntry(true, true);

            if (!string.IsNullOrEmpty(Title.Text))
            {
                pwEntry.Strings.Set(PwDefs.TitleField, new ProtectedString(true, Title.Text));
            }

            if (!string.IsNullOrEmpty(User.Text))
            {
                pwEntry.Strings.Set(PwDefs.UserNameField, new ProtectedString(true, User.Text));
            }

            if (!string.IsNullOrEmpty(Password.Text))
            {
                pwEntry.Strings.Set(PwDefs.PasswordField, new ProtectedString(true, Password.Text));
            }

            if (!string.IsNullOrEmpty(Notes.Text))
            {
                pwEntry.Strings.Set(PwDefs.NotesField, new ProtectedString(true, Notes.Text));
            }

            if (!string.IsNullOrEmpty(Url.Text))
            {
                pwEntry.Strings.Set(PwDefs.UrlField, new ProtectedString(true, Url.Text));
            }
            // db.RootGroup.AddEntry(pwEntry, true);
            db.RootGroup.Entries.Add(pwEntry);
            db.Modified = true;
            // db.Save();
            var stream = await file.OpenStreamForWriteAsync();

            var kdbx = new KdbxFile(db);

            kdbx.Save(stream, null, KdbxFormat.Default, null);
            db.Close();
            int duration = 3000;

            try {
                TabViewPage.InAppNotificationMain.Show("Saved, please refresh list", duration);
            }
            catch
            {
                IncognitoTabView.InAppNotificationMain.Show("Saved, please refresh list", duration);
            }
        }
예제 #7
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());
            }
        }