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)); }
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); }
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); }
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); }
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); } }
/// <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()); } }