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)
This commit is contained in:
Philipp Crocoll
2015-02-09 20:24:57 +01:00
parent bc235b3ba5
commit 8de5588cff
12 changed files with 255 additions and 61 deletions

View File

@@ -26,6 +26,7 @@ namespace keepass2android
{
private Dictionary<PwUuid, AdditionalGroupData> _groupData = new Dictionary<PwUuid, AdditionalGroupData>();
private static readonly DateTime _expireNever = new DateTime(2999,12,28,23,59,59);
private List<PwEntryV3> _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<PwEntryV3>();
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<int, PwGroupV3> 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));

View File

@@ -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; }
}
}
}

View File

@@ -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);

View File

@@ -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);

View File

@@ -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;