From 8de5588cff19d498c64e8136e19d87b2b34cc28b Mon Sep 17 00:00:00 2001 From: Philipp Crocoll Date: Mon, 9 Feb 2015 20:24:57 +0100 Subject: [PATCH] added UI for kdb support fixed issue with not keeping "meta stream entries" (database color, default username) and num encryption rounds fixed issues with recycle bin (wasn't updating group list correctly, couldn't access newly created recycle bin group) --- src/KeePassLib2Android/IDatabaseFormat.cs | 8 ++ src/KeePassLib2Android/PwDatabase.cs | 2 + .../database/KdbDatabaseFormat.cs | 64 ++++++++++- .../database/KdbxDatabaseFormat.cs | 40 +++++++ .../database/edit/DeleteEntry.cs | 10 +- .../database/edit/DeleteGroup.cs | 10 +- .../database/edit/DeleteRunnable.cs | 4 +- src/Kp2aUnitTests/MainActivity.cs | 10 +- src/Kp2aUnitTests/TestSaveDb.cs | 26 +++++ .../KP2AKdbLibrary/bin/kp2akdblibrary.jar | Bin 375272 -> 374936 bytes src/keepass2android/EntryEditActivity.cs | 41 ++++++- .../settings/DatabaseSettingsActivity.cs | 101 ++++++++++-------- 12 files changed, 255 insertions(+), 61 deletions(-) diff --git a/src/KeePassLib2Android/IDatabaseFormat.cs b/src/KeePassLib2Android/IDatabaseFormat.cs index a58b69a3..9cbd53b5 100644 --- a/src/KeePassLib2Android/IDatabaseFormat.cs +++ b/src/KeePassLib2Android/IDatabaseFormat.cs @@ -15,5 +15,13 @@ namespace KeePassLib void Save(PwDatabase kpDatabase, Stream stream); bool CanHaveEntriesInRootGroup { get; } + bool CanHaveMultipleAttachments { get; } + bool CanHaveCustomFields { get; } + bool HasDefaultUsername { get; } + bool HasDatabaseName { get; } + bool SupportsAttachmentKeys { get; } + bool SupportsTags { get; } + bool SupportsOverrideUrl { get; } + bool CanRecycle { get; } } } \ No newline at end of file diff --git a/src/KeePassLib2Android/PwDatabase.cs b/src/KeePassLib2Android/PwDatabase.cs index 3b194722..7c96cbbf 100644 --- a/src/KeePassLib2Android/PwDatabase.cs +++ b/src/KeePassLib2Android/PwDatabase.cs @@ -426,11 +426,13 @@ namespace KeePassLib public byte[] HashOfFileOnDisk { get { return m_pbHashOfFileOnDisk; } + set { m_pbHashOfFileOnDisk = value; } } public byte[] HashOfLastIO { get { return m_pbHashOfLastIO; } + set { m_pbHashOfLastIO = value; } } public bool UseFileTransactions diff --git a/src/Kp2aBusinessLogic/database/KdbDatabaseFormat.cs b/src/Kp2aBusinessLogic/database/KdbDatabaseFormat.cs index 4746024e..61a2143e 100644 --- a/src/Kp2aBusinessLogic/database/KdbDatabaseFormat.cs +++ b/src/Kp2aBusinessLogic/database/KdbDatabaseFormat.cs @@ -26,6 +26,7 @@ namespace keepass2android { private Dictionary _groupData = new Dictionary(); private static readonly DateTime _expireNever = new DateTime(2999,12,28,23,59,59); + private List _metaStreams; public void PopulateDatabaseFromStream(PwDatabase db, Stream s, IStatusLogger slLogger) { @@ -34,6 +35,8 @@ namespace keepass2android var hashingStream = new HashingStreamEx(s, false, new SHA256Managed()); + _metaStreams = new List(); + string password = "";//no need to distinguish between null and "" because empty passwords are invalid (and null is not allowed) KcpPassword passwordKey = (KcpPassword)db.MasterKey.GetUserKey(typeof(KcpPassword)); if (passwordKey != null) @@ -54,6 +57,7 @@ namespace keepass2android var dbv3 = importer.OpenDatabase(hashingStream, password, keyfileStream); db.Name = dbv3.Name; + db.KeyEncryptionRounds = (ulong) dbv3.NumKeyEncRounds; db.RootGroup = ConvertGroup(dbv3.RootGroup); if (dbv3.Algorithm == PwEncryptionAlgorithm.Rjindal) { @@ -126,7 +130,11 @@ namespace keepass2android { var entry = groupV3.GetEntryAt(i); if (entry.IsMetaStream) + { + _metaStreams.Add(entry); continue; + } + pwGroup.AddEntry(ConvertEntry(entry), true); } @@ -251,8 +259,6 @@ namespace keepass2android db.RootGroup.Level = -1; AssignParent(kpDatabase.RootGroup, db, groupV3s); - - foreach (PwEntry e in kpDatabase.RootGroup.GetEntries(true)) { @@ -263,12 +269,25 @@ namespace keepass2android db.Entries.Add(entryV3); } + //add meta stream entries: + if (db.Groups.Any()) + { + foreach (var metaEntry in _metaStreams) + { + metaEntry.GroupId = db.Groups.First().Id.Id; + db.Entries.Add(metaEntry); + } + + } + HashingStreamEx hashedStream = new HashingStreamEx(stream, true, null); PwDbV3Output output = new PwDbV3Output(db, hashedStream); output.Output(); hashedStream.Close(); HashOfLastStream = hashedStream.Hash; + + kpDatabase.HashOfLastIO = kpDatabase.HashOfFileOnDisk = HashOfLastStream; stream.Close(); } @@ -277,6 +296,46 @@ namespace keepass2android get { return false; } } + public bool CanHaveMultipleAttachments + { + get { return false; } + } + + public bool CanHaveCustomFields + { + get { return false; } + } + + public bool HasDefaultUsername + { + get { return false; } + } + + public bool HasDatabaseName + { + get { return false; } + } + + public bool SupportsAttachmentKeys + { + get { return false; } + } + + public bool SupportsTags + { + get { return false; } + } + + public bool SupportsOverrideUrl + { + get { return false; } + } + + public bool CanRecycle + { + get { return false; } + } + private void AssignParent(PwGroup kpParent, PwDatabaseV3 dbV3, Dictionary groupV3s) { PwGroupV3 parentV3; @@ -304,6 +363,7 @@ namespace keepass2android { PwGroupV3 toGroup = new PwGroupV3(); toGroup.Name = fromGroup.Name; + //todo remove Android.Util.Log.Debug("KP2A", "save kdb: group " + fromGroup.Name); toGroup.TCreation = new PwDate(ConvertTime(fromGroup.CreationTime)); diff --git a/src/Kp2aBusinessLogic/database/KdbxDatabaseFormat.cs b/src/Kp2aBusinessLogic/database/KdbxDatabaseFormat.cs index 2fe4b0b2..21535d54 100644 --- a/src/Kp2aBusinessLogic/database/KdbxDatabaseFormat.cs +++ b/src/Kp2aBusinessLogic/database/KdbxDatabaseFormat.cs @@ -38,5 +38,45 @@ namespace keepass2android { get { return true; } } + + public bool CanHaveMultipleAttachments + { + get { return true; } + } + + public bool CanHaveCustomFields + { + get { return true; } + } + + public bool HasDefaultUsername + { + get { return true; } + } + + public bool HasDatabaseName + { + get { return true; } + } + + public bool SupportsAttachmentKeys + { + get { return true; } + } + + public bool SupportsTags + { + get { return true; } + } + + public bool SupportsOverrideUrl + { + get { return true; } + } + + public bool CanRecycle + { + get { return true; } + } } } \ No newline at end of file diff --git a/src/Kp2aBusinessLogic/database/edit/DeleteEntry.cs b/src/Kp2aBusinessLogic/database/edit/DeleteEntry.cs index 4ab36ca7..4fcd4139 100644 --- a/src/Kp2aBusinessLogic/database/edit/DeleteEntry.cs +++ b/src/Kp2aBusinessLogic/database/edit/DeleteEntry.cs @@ -36,7 +36,7 @@ namespace keepass2android { get { - return CanRecycleGroup(_entry.ParentGroup); + return App.GetDb().DatabaseFormat.CanRecycle && CanRecycleGroup(_entry.ParentGroup); } } @@ -62,7 +62,8 @@ namespace keepass2android if(pgParent != null) { pgParent.Entries.Remove(pe); - + //TODO check if RecycleBin is deleted + //TODO no recycle bin in KDB if ((DeletePermanently) || (!CanRecycle)) { @@ -85,7 +86,7 @@ namespace keepass2android } else // Recycle { - EnsureRecycleBin(ref pgRecycleBin, ref bUpdateGroupList); + EnsureRecycleBinExists(ref pgRecycleBin, ref bUpdateGroupList); pgRecycleBin.AddEntry(pe, true, true); pe.Touch(false); @@ -97,6 +98,9 @@ namespace keepass2android Db.Dirty.Add(pgParent); // Mark new parent dirty Db.Dirty.Add(pgRecycleBin); + // mark root dirty if recycle bin was created + if (bUpdateGroupList) + Db.Dirty.Add(Db.Root); } else { // Let's not bother recovering from a failure to save a deleted entry. It is too much work. App.LockDatabase(false); diff --git a/src/Kp2aBusinessLogic/database/edit/DeleteGroup.cs b/src/Kp2aBusinessLogic/database/edit/DeleteGroup.cs index 7b1e01bd..6341eb91 100644 --- a/src/Kp2aBusinessLogic/database/edit/DeleteGroup.cs +++ b/src/Kp2aBusinessLogic/database/edit/DeleteGroup.cs @@ -56,7 +56,7 @@ namespace keepass2android { get { - return CanRecycleGroup(_group); + return App.GetDb().DatabaseFormat.CanRecycle && CanRecycleGroup(_group); } } @@ -91,8 +91,8 @@ namespace keepass2android } else // Recycle { - bool bDummy = false; - EnsureRecycleBin(ref pgRecycleBin, ref bDummy); + bool groupListUpdateRequired = false; + EnsureRecycleBinExists(ref pgRecycleBin, ref groupListUpdateRequired); pgRecycleBin.AddGroup(pg, true, true); pg.Touch(false); @@ -106,6 +106,10 @@ namespace keepass2android } //Mark old parent dirty: Db.Dirty.Add(pgParent); + + // mark root dirty if recycle bin was created + if (groupListUpdateRequired) + Db.Dirty.Add(Db.Root); } else { // Let's not bother recovering from a failure to save a deleted group. It is too much work. App.LockDatabase(false); diff --git a/src/Kp2aBusinessLogic/database/edit/DeleteRunnable.cs b/src/Kp2aBusinessLogic/database/edit/DeleteRunnable.cs index 5bde910d..df2c3f7e 100644 --- a/src/Kp2aBusinessLogic/database/edit/DeleteRunnable.cs +++ b/src/Kp2aBusinessLogic/database/edit/DeleteRunnable.cs @@ -66,7 +66,7 @@ namespace keepass2android } - protected void EnsureRecycleBin(ref PwGroup pgRecycleBin, + protected void EnsureRecycleBinExists(ref PwGroup pgRecycleBin, ref bool bGroupListUpdateRequired) { if ((Db == null) || (Db.KpDatabase == null)) { return; } @@ -87,7 +87,7 @@ namespace keepass2android }; Db.KpDatabase.RootGroup.AddGroup(pgRecycleBin, true); - + Db.Groups[pgRecycleBin.Uuid] = pgRecycleBin; Db.KpDatabase.RecycleBinUuid = pgRecycleBin.Uuid; bGroupListUpdateRequired = true; diff --git a/src/Kp2aUnitTests/MainActivity.cs b/src/Kp2aUnitTests/MainActivity.cs index 09b574d3..a5ba6de9 100644 --- a/src/Kp2aUnitTests/MainActivity.cs +++ b/src/Kp2aUnitTests/MainActivity.cs @@ -31,9 +31,13 @@ namespace Kp2aUnitTests //runner.AddTests(new List { typeof(TestSaveDb) }); //runner.AddTests(new List { typeof(TestCachingFileStorage) }); //runner.AddTests(typeof(TestLoadDb).GetMethod("TestLoadKdb1WithKeyfileOnly")); - runner.AddTests(typeof(TestSaveDb).GetMethod("TestLoadEditSaveWithSyncKdb")); - runner.AddTests(typeof(TestSaveDb).GetMethod("TestLoadAndSave_TestIdenticalFiles_kdb")); - runner.AddTests(typeof(TestSaveDb).GetMethod("TestCreateSaveAndLoad_TestIdenticalFiles_kdb")); + + //runner.AddTests(typeof(TestSaveDb).GetMethod("TestLoadEditSaveWithSyncKdb")); + //runner.AddTests(typeof(TestSaveDb).GetMethod("TestLoadAndSave_TestIdenticalFiles_kdb")); + //runner.AddTests(typeof(TestSaveDb).GetMethod("TestCreateSaveAndLoad_TestIdenticalFiles_kdb")); + + runner.AddTests(typeof(TestSaveDb).GetMethod("TestSaveTwice_kdb")); + //runner.AddTests(typeof(TestLoadDb).GetMethod("LoadAndSaveFromRemote1And1Ftp")); //runner.AddTests(typeof(TestLoadDb).GetMethod("TestLoadKdbpWithPasswordOnly")); //runner.AddTests(typeof(TestSaveDb).GetMethod("TestLoadKdbxAndSaveKdbp_TestIdenticalFiles")); diff --git a/src/Kp2aUnitTests/TestSaveDb.cs b/src/Kp2aUnitTests/TestSaveDb.cs index f07af98f..7428ea0e 100644 --- a/src/Kp2aUnitTests/TestSaveDb.cs +++ b/src/Kp2aUnitTests/TestSaveDb.cs @@ -373,6 +373,32 @@ namespace Kp2aUnitTests + } + + [TestMethod] + public void TestSaveTwice_kdb() + { + var filename = DefaultDirectory + "savetwice.kdb"; + //create the default database: + IKp2aApp app = SetupAppWithDatabase(filename); + DisplayGroups(app, "After create 1"); + //save it and reload it so we have a base version + Android.Util.Log.Debug("KP2A", "-- Save first version -- "); + SaveDatabase(app); + Android.Util.Log.Debug("KP2A", "-- Load DB -- "); + app = LoadDatabase(filename, DefaultPassword, DefaultKeyfile); + DisplayGroups(app, "After reload"); + + //save the database (first time): + Android.Util.Log.Debug("KP2A", "-- Save db first time "); + SaveDatabase(app); + + Android.Util.Log.Debug("KP2A", "-- Save db second time "); + SaveDatabase(app); + + //make sure the right question was asked + Assert.AreEqual(null, ((TestKp2aApp)app).LastYesNoCancelQuestionTitle); + } diff --git a/src/java/KP2AKdbLibrary/bin/kp2akdblibrary.jar b/src/java/KP2AKdbLibrary/bin/kp2akdblibrary.jar index db50f3f96c35cd0a4a0472e600bff1164793e020..21fe6725ebf5ffa18426a8558f15b10b42ea6bcd 100644 GIT binary patch delta 16371 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 delta 16652 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 diff --git a/src/keepass2android/EntryEditActivity.cs b/src/keepass2android/EntryEditActivity.cs index a0a57357..3b0a5b74 100644 --- a/src/keepass2android/EntryEditActivity.cs +++ b/src/keepass2android/EntryEditActivity.cs @@ -261,9 +261,8 @@ namespace keepass2android TextView keyView = (TextView) ees.FindViewById(Resource.Id.title); keyView.RequestFocus(); - - }; + SetAddExtraStringEnabled(); ((CheckBox)FindViewById(Resource.Id.entry_expires_checkbox)).CheckedChange += (sender, e) => { @@ -280,6 +279,12 @@ namespace keepass2android } + private void SetAddExtraStringEnabled() + { + if (!App.Kp2a.GetDb().DatabaseFormat.CanHaveCustomFields) + ((Button)FindViewById(Resource.Id.add_advanced)).Visibility = ViewStates.Gone; + } + private void MakePasswordVisibleOrHidden() { TextView password = (TextView) FindViewById(Resource.Id.entry_password); @@ -663,7 +668,12 @@ namespace keepass2android foreach (KeyValuePair pair in State.Entry.Binaries.OrderBy(p => p.Key) ) { String key = pair.Key; - Button binaryButton = new Button(this) {Text = key}; + String label = key; + if ((String.IsNullOrEmpty(label) || (!App.Kp2a.GetDb().DatabaseFormat.SupportsAttachmentKeys))) + { + label = ""; + } + Button binaryButton = new Button(this) {Text = label}; binaryButton.SetCompoundDrawablesWithIntrinsicBounds( Resources.GetDrawable(Android.Resource.Drawable.IcMenuDelete),null, null, null); binaryButton.Click += (sender, e) => @@ -680,6 +690,9 @@ namespace keepass2android Button addBinaryButton = new Button(this) {Text = GetString(Resource.String.add_binary)}; addBinaryButton.SetCompoundDrawablesWithIntrinsicBounds( Resources.GetDrawable(Android.Resource.Drawable.IcMenuAdd) , null, null, null); + addBinaryButton.Enabled = true; + if (!App.Kp2a.GetDb().DatabaseFormat.CanHaveMultipleAttachments) + addBinaryButton.Enabled = !State.Entry.Binaries.Any(); addBinaryButton.Click += (sender, e) => { Util.ShowBrowseDialog(this, Intents.RequestCodeFileBrowseForBinary, false); @@ -837,8 +850,26 @@ namespace keepass2android PopulateBinaries(); - PopulateText(Resource.Id.entry_override_url, State.Entry.OverrideUrl); - PopulateText(Resource.Id.entry_tags, StrUtil.TagsToString(State.Entry.Tags, true)); + if (App.Kp2a.GetDb().DatabaseFormat.SupportsOverrideUrl) + { + PopulateText(Resource.Id.entry_override_url, State.Entry.OverrideUrl); + } + else + { + FindViewById(Resource.Id.entry_override_url_label).Visibility = ViewStates.Gone; + FindViewById(Resource.Id.entry_override_url).Visibility = ViewStates.Gone; + } + + if (App.Kp2a.GetDb().DatabaseFormat.SupportsTags) + { + PopulateText(Resource.Id.entry_tags, StrUtil.TagsToString(State.Entry.Tags, true)); + } + else + { + FindViewById(Resource.Id.entry_tags_label).Visibility = ViewStates.Gone; + FindViewById(Resource.Id.entry_tags).Visibility = ViewStates.Gone; + } + UpdateExpires(); } diff --git a/src/keepass2android/settings/DatabaseSettingsActivity.cs b/src/keepass2android/settings/DatabaseSettingsActivity.cs index 6000b0f3..81d120ce 100644 --- a/src/keepass2android/settings/DatabaseSettingsActivity.cs +++ b/src/keepass2android/settings/DatabaseSettingsActivity.cs @@ -89,56 +89,71 @@ namespace keepass2android rounds.Enabled = db.CanWrite; Preference defaultUser = FindPreference(GetString(Resource.String.default_username_key)); - defaultUser.Enabled = db.CanWrite; - ((EditTextPreference)defaultUser).EditText.Text = db.KpDatabase.DefaultUserName; - ((EditTextPreference)defaultUser).Text = db.KpDatabase.DefaultUserName; - defaultUser.PreferenceChange += (sender, e) => + if (!db.DatabaseFormat.HasDefaultUsername) { - DateTime previousUsernameChanged = db.KpDatabase.DefaultUserNameChanged; - String previousUsername = db.KpDatabase.DefaultUserName; - db.KpDatabase.DefaultUserName = e.NewValue.ToString(); - - SaveDb save = new SaveDb(this, App.Kp2a, new ActionOnFinish( (success, message) => + ((PreferenceScreen) FindPreference(GetString(Resource.String.db_key))).RemovePreference(defaultUser); + } + else + { + defaultUser.Enabled = db.CanWrite; + ((EditTextPreference)defaultUser).EditText.Text = db.KpDatabase.DefaultUserName; + ((EditTextPreference)defaultUser).Text = db.KpDatabase.DefaultUserName; + defaultUser.PreferenceChange += (sender, e) => { - if (!success) - { - db.KpDatabase.DefaultUserName = previousUsername; - db.KpDatabase.DefaultUserNameChanged = previousUsernameChanged; - Toast.MakeText(this, message, ToastLength.Long).Show(); - } - })); - ProgressTask pt = new ProgressTask(App.Kp2a, this, save); - pt.Run(); - }; + DateTime previousUsernameChanged = db.KpDatabase.DefaultUserNameChanged; + String previousUsername = db.KpDatabase.DefaultUserName; + db.KpDatabase.DefaultUserName = e.NewValue.ToString(); + SaveDb save = new SaveDb(this, App.Kp2a, new ActionOnFinish((success, message) => + { + if (!success) + { + db.KpDatabase.DefaultUserName = previousUsername; + db.KpDatabase.DefaultUserNameChanged = previousUsernameChanged; + Toast.MakeText(this, message, ToastLength.Long).Show(); + } + })); + ProgressTask pt = new ProgressTask(App.Kp2a, this, save); + pt.Run(); + }; + + } + + Preference databaseName = FindPreference(GetString(Resource.String.database_name_key)); - databaseName.Enabled = db.CanWrite; - ((EditTextPreference)databaseName).EditText.Text = db.KpDatabase.Name; - ((EditTextPreference)databaseName).Text = db.KpDatabase.Name; - databaseName.PreferenceChange += (sender, e) => + if (!db.DatabaseFormat.HasDatabaseName) { - DateTime previousNameChanged = db.KpDatabase.NameChanged; - String previousName = db.KpDatabase.Name; - db.KpDatabase.Name = e.NewValue.ToString(); - - SaveDb save = new SaveDb(this, App.Kp2a, new ActionOnFinish( (success, message) => - { - if (!success) + ((PreferenceScreen) FindPreference(GetString(Resource.String.db_key))).RemovePreference(databaseName); + } + else + { + databaseName.Enabled = db.CanWrite; + ((EditTextPreference) databaseName).EditText.Text = db.KpDatabase.Name; + ((EditTextPreference) databaseName).Text = db.KpDatabase.Name; + databaseName.PreferenceChange += (sender, e) => { - db.KpDatabase.Name = previousName; - db.KpDatabase.NameChanged = previousNameChanged; - Toast.MakeText(this, message, ToastLength.Long).Show(); - } - else - { - // Name is reflected in notification, so update it - App.Kp2a.UpdateOngoingNotification(); - } - })); - ProgressTask pt = new ProgressTask(App.Kp2a, this, save); - pt.Run(); - }; + DateTime previousNameChanged = db.KpDatabase.NameChanged; + String previousName = db.KpDatabase.Name; + db.KpDatabase.Name = e.NewValue.ToString(); + SaveDb save = new SaveDb(this, App.Kp2a, new ActionOnFinish((success, message) => + { + if (!success) + { + db.KpDatabase.Name = previousName; + db.KpDatabase.NameChanged = previousNameChanged; + Toast.MakeText(this, message, ToastLength.Long).Show(); + } + else + { + // Name is reflected in notification, so update it + App.Kp2a.UpdateOngoingNotification(); + } + })); + ProgressTask pt = new ProgressTask(App.Kp2a, this, save); + pt.Run(); + }; + } Preference changeMaster = FindPreference(GetString(Resource.String.master_pwd_key)); if (App.Kp2a.GetDb().CanWrite) {