refactoring, use less UrlUtil and more IFileStorage

This commit is contained in:
Philipp Crocoll
2019-10-01 20:04:03 +02:00
parent 706debfa33
commit 99d0ecfd59
19 changed files with 66 additions and 167 deletions

View File

@@ -21,7 +21,6 @@
using System;
using System.Diagnostics;
using System.IO;
using System.Security;
#if !KeePassUAP
@@ -78,26 +77,7 @@ namespace KeePassLib.Keys
// m_pbKeyData = null;
// }
private static string GetUserKeyFilePath(bool bCreate)
{
#if KeePassRT
string strUserDir = Windows.Storage.ApplicationData.Current.RoamingFolder.Path;
#else
string strUserDir = Environment.GetFolderPath(
Environment.SpecialFolder.ApplicationData);
#endif
strUserDir = UrlUtil.EnsureTerminatingSeparator(strUserDir, false);
strUserDir += PwDefs.ShortProductName;
if (bCreate && !Directory.Exists(strUserDir))
Directory.CreateDirectory(strUserDir);
strUserDir = UrlUtil.EnsureTerminatingSeparator(strUserDir, false);
return strUserDir + UserKeyFileName;
}
private static byte[] LoadUserKey(bool bShowWarning)
private static byte[] LoadUserKey(bool bShowWarning)
{
byte[] pbKey = null;

View File

@@ -587,7 +587,7 @@ namespace KeePassLib
/// </summary>
/// <param name="ioConnection">IO connection of the new database.</param>
/// <param name="pwKey">Key to open the database.</param>
public void New(IOConnectionInfo ioConnection, CompositeKey pwKey)
public void New(IOConnectionInfo ioConnection, CompositeKey pwKey, string filenameWithoutPathAndExt)
{
Debug.Assert(ioConnection != null);
if(ioConnection == null) throw new ArgumentNullException("ioConnection");
@@ -602,26 +602,11 @@ namespace KeePassLib
m_bDatabaseOpened = true;
m_bModified = true;
m_pgRootGroup = new PwGroup(true, true,
UrlUtil.StripExtension(UrlUtil.GetFileName(ioConnection.Path)),
m_pgRootGroup = new PwGroup(true, true, filenameWithoutPathAndExt,
PwIcon.FolderOpen);
m_pgRootGroup.IsExpanded = true;
}
/// <summary>
/// Open a database. The URL may point to any supported data source.
/// </summary>
/// <param name="ioSource">IO connection to load the database from.</param>
/// <param name="pwKey">Key used to open the specified database.</param>
/// <param name="slLogger">Logger, which gets all status messages.</param>
public void Open(IOConnectionInfo ioSource, CompositeKey pwKey,
IStatusLogger slLogger, IDatabaseFormat format)
{
Open(IOConnection.OpenRead(ioSource), UrlUtil.StripExtension(
UrlUtil.GetFileName(ioSource.Path)), ioSource, pwKey, slLogger, format);
}
/// <summary>
/// Open a database. The URL may point to any supported data source.
@@ -669,37 +654,7 @@ namespace KeePassLib
throw;
}
}
/// <summary>
/// Save the currently opened database. The file is written to the location
/// it has been opened from.
/// </summary>
/// <param name="slLogger">Logger that recieves status information.</param>
public void Save(IStatusLogger slLogger)
{
Debug.Assert(!HasDuplicateUuids());
FileLock fl = null;
if(m_bUseFileLocks) fl = new FileLock(m_ioSource);
try
{
FileTransactionEx ft = new FileTransactionEx(m_ioSource,
m_bUseFileTransactions);
Stream s = ft.OpenWrite();
KdbxFile kdb = new KdbxFile(this);
kdb.Save(s, null, KdbpFile.GetFormatToUse(m_ioSource), slLogger);
ft.CommitWrite();
m_pbHashOfLastIO = kdb.HashOfFileOnDisk;
m_pbHashOfFileOnDisk = kdb.HashOfFileOnDisk;
Debug.Assert(m_pbHashOfFileOnDisk != null);
}
finally { if(fl != null) fl.Dispose(); }
m_bModified = false;
}
/// <summary>
/// Save the currently opened database. The file is written to the given stream which is expected to be the original location.
@@ -717,46 +672,6 @@ namespace KeePassLib
m_bModified = false;
}
/// <summary>
/// Save the currently opened database to a different location. If
/// <paramref name="bIsPrimaryNow" /> is <c>true</c>, the specified
/// location is made the default location for future saves
/// using <c>SaveDatabase</c>.
/// </summary>
/// <param name="ioConnection">New location to serialize the database to.</param>
/// <param name="bIsPrimaryNow">If <c>true</c>, the new location is made the
/// standard location for the database. If <c>false</c>, a copy of the currently
/// opened database is saved to the specified location, but it isn't
/// made the default location (i.e. no lock files will be moved for
/// example).</param>
/// <param name="slLogger">Logger that recieves status information.</param>
public void SaveAs(IOConnectionInfo ioConnection, bool bIsPrimaryNow,
IStatusLogger slLogger)
{
Debug.Assert(ioConnection != null);
if(ioConnection == null) throw new ArgumentNullException("ioConnection");
IOConnectionInfo ioCurrent = m_ioSource; // Remember current
m_ioSource = ioConnection;
byte[] pbHashCopy = m_pbHashOfFileOnDisk;
try { this.Save(slLogger); }
catch(Exception)
{
m_ioSource = ioCurrent; // Restore
m_pbHashOfFileOnDisk = pbHashCopy;
m_pbHashOfLastIO = null;
throw;
}
if(!bIsPrimaryNow)
{
m_ioSource = ioCurrent; // Restore
m_pbHashOfFileOnDisk = pbHashCopy;
}
}
/// <summary>
/// Closes the currently opened database. No confirmation message is shown

View File

@@ -581,7 +581,7 @@ namespace KeePassLib.Serialization
return vEntries; */
PwDatabase pd = new PwDatabase();
pd.New(new IOConnectionInfo(), new CompositeKey());
pd.New(new IOConnectionInfo(), new CompositeKey(), "");
KdbxFile f = new KdbxFile(pd);
f.Load(msData, KdbxFormat.PlainXml, null);

View File

@@ -1048,7 +1048,7 @@ namespace KeePassLib.Serialization
return true; */
PwDatabase pd = new PwDatabase();
pd.New(new IOConnectionInfo(), new CompositeKey());
pd.New(new IOConnectionInfo(), new CompositeKey(), "");
PwGroup pg = pd.RootGroup;
if (pg == null) { Debug.Assert(false); return false; }

View File

@@ -26,10 +26,10 @@ namespace KeePassLib.Serialization
/// <summary>
/// Determines whether the database pointed to by the specified ioc should be (de)serialised in default (xml) or protocol buffers format.
/// </summary>
public static KdbxFormat GetFormatToUse(IOConnectionInfo ioc)
public static KdbxFormat GetFormatToUse(string fileExt)
{
// If the filename ends in .kdbp, use ProtocolBuffers format.
return UrlUtil.GetExtension(UrlUtil.GetFileName(ioc.Path)).Equals(KdbpFile.FileNameExtension, StringComparison.OrdinalIgnoreCase) ? KdbxFormat.ProtocolBuffers : KdbxFormat.Default;
return fileExt.Equals(KdbpFile.FileNameExtension, StringComparison.OrdinalIgnoreCase) ? KdbxFormat.ProtocolBuffers : KdbxFormat.Default;
}
public static void WriteDocument(PwDatabase database, Stream stream, byte[] protectedStreamKey, byte[] hashOfHeader)

View File

@@ -82,7 +82,12 @@ namespace keepass2android.Io
UrlUtil.GetFileName(ioc.Path));
}
public bool RequiresCredentials(IOConnectionInfo ioc)
public string GetFileExtension(IOConnectionInfo ioc)
{
return UrlUtil.GetExtension(ioc.Path);
}
public bool RequiresCredentials(IOConnectionInfo ioc)
{
return false;
}

View File

@@ -201,7 +201,12 @@ namespace keepass2android.Io
}
public bool RequiresCredentials(IOConnectionInfo ioc)
public string GetFileExtension(IOConnectionInfo ioc)
{
return UrlUtil.GetExtension(ioc.Path);
}
public bool RequiresCredentials(IOConnectionInfo ioc)
{
return (!ioc.IsLocalFile()) && (ioc.CredSaveMode != IOCredSaveMode.SaveCred);
}

View File

@@ -448,7 +448,12 @@ namespace keepass2android.Io
return _cachedStorage.GetFilenameWithoutPathAndExt(ioc);
}
public bool RequiresCredentials(IOConnectionInfo ioc)
public string GetFileExtension(IOConnectionInfo ioc)
{
return _cachedStorage.GetFileExtension(ioc);
}
public bool RequiresCredentials(IOConnectionInfo ioc)
{
return _cachedStorage.RequiresCredentials(ioc);
}

View File

@@ -88,11 +88,13 @@ namespace keepass2android.Io
IWriteTransaction OpenWriteTransaction(IOConnectionInfo ioc, bool useFileTransaction);
string GetFilenameWithoutPathAndExt(IOConnectionInfo ioc);
/// <summary>
/// Returns true if the the given ioc must be filled with username/password
/// </summary>
bool RequiresCredentials(IOConnectionInfo ioc);
string GetFileExtension(IOConnectionInfo ioc);
/// <summary>
/// Returns true if the the given ioc must be filled with username/password
/// </summary>
bool RequiresCredentials(IOConnectionInfo ioc);
/// <summary>
/// Creates the directory described by ioc

View File

@@ -128,10 +128,12 @@ namespace keepass2android.Io
}
//creates a local ioc where the sourceIoc can be stored to
public static IOConnectionInfo GetInternalIoc(IOConnectionInfo sourceIoc, Context ctx)
public static IOConnectionInfo GetInternalIoc(IOConnectionInfo sourceIoc, Context ctx, IKp2aApp app)
{
Java.IO.File internalDirectory = IoUtil.GetInternalDirectory(ctx);
string targetPath = UrlUtil.GetFileName(sourceIoc.Path);
var filestorage = app.GetFileStorage(sourceIoc);
string targetPath = filestorage.GetFilenameWithoutPathAndExt(sourceIoc);
targetPath = targetPath.Trim("|\\?*<\":>+[]/'".ToCharArray());
if (targetPath == "")
targetPath = "internal";
@@ -153,7 +155,7 @@ namespace keepass2android.Io
public static IOConnectionInfo ImportFileToInternalDirectory(IOConnectionInfo sourceIoc, Context ctx, IKp2aApp app)
{
var targetIoc = GetInternalIoc(sourceIoc, ctx);
var targetIoc = GetInternalIoc(sourceIoc, ctx, app);
IoUtil.Copy(targetIoc, sourceIoc, app);

View File

@@ -177,7 +177,12 @@ namespace keepass2android.Io
_jfs.GetFilename(IocToPath(ioc)));
}
public bool RequiresCredentials(IOConnectionInfo ioc)
public string GetFileExtension(IOConnectionInfo ioc)
{
return UrlUtil.GetExtension(ioc.Path);
}
public bool RequiresCredentials(IOConnectionInfo ioc)
{
return false;
}

View File

@@ -314,7 +314,12 @@ namespace keepass2android.Io
UrlUtil.GetFileName(ioc.Path));
}
public bool RequiresCredentials(IOConnectionInfo ioc)
public string GetFileExtension(IOConnectionInfo ioc)
{
return UrlUtil.GetExtension(ioc.Path);
}
public bool RequiresCredentials(IOConnectionInfo ioc)
{
return false;
}

View File

@@ -78,7 +78,12 @@ namespace keepass2android.Io
return _baseStorage.GetFilenameWithoutPathAndExt(ioc);
}
public bool RequiresCredentials(IOConnectionInfo ioc)
public string GetFileExtension(IOConnectionInfo ioc)
{
return _baseStorage.GetFileExtension(ioc);
}
public bool RequiresCredentials(IOConnectionInfo ioc)
{
return _baseStorage.RequiresCredentials(ioc);
}

View File

@@ -491,6 +491,11 @@ namespace keepass2android.Io
GetFilename(IocToPath(ioc)));
}
public string GetFileExtension(IOConnectionInfo ioc)
{
return UrlUtil.GetExtension(OneDrive2ItemLocation.FromString(ioc.Path).LocalPathString);
}
private string GetFilename(string path)
{
string localPath = "/"+OneDrive2ItemLocation.FromString(path).LocalPath;

View File

@@ -25,9 +25,7 @@ using KeePass.Util.Spr;
using KeePassLib;
using KeePassLib.Collections;
using KeePassLib.Cryptography;
using KeePassLib.Delegates;
using KeePassLib.Security;
using KeePassLib.Utility;
namespace KeePass.Util
@@ -89,41 +87,8 @@ namespace KeePass.Util
return str;
}
*/
private static string ReplaceHmacOtpPlaceholder(string strText,
SprContext ctx)
{
PwEntry pe = ctx.Entry;
PwDatabase pd = ctx.Database;
if((pe == null) || (pd == null)) return strText;
string str = strText;
const string strHmacOtpPlh = @"{HMACOTP}";
if(str.IndexOf(strHmacOtpPlh, StrUtil.CaseIgnoreCmp) >= 0)
{
const string strKeyField = "HmacOtp-Secret";
const string strCounterField = "HmacOtp-Counter";
byte[] pbSecret = StrUtil.Utf8.GetBytes(pe.Strings.ReadSafe(
strKeyField));
string strCounter = pe.Strings.ReadSafe(strCounterField);
ulong uCounter;
ulong.TryParse(strCounter, out uCounter);
string strValue = HmacOtp.Generate(pbSecret, uCounter, 6, false, -1);
pe.Strings.Set(strCounterField, new ProtectedString(false,
(uCounter + 1).ToString()));
pd.Modified = true;
str = StrUtil.ReplaceCaseInsensitive(str, strHmacOtpPlh, strValue);
}
return str;
}
public static bool EntriesHaveSameParent(PwObjectList<PwEntry> v)
public static bool EntriesHaveSameParent(PwObjectList<PwEntry> v)
{
if(v == null) { Debug.Assert(false); return true; }
if(v.UCount == 0) return true;

View File

@@ -65,7 +65,7 @@ namespace keepass2android
_key = new CompositeKey(); //use a temporary key which should be changed after creation
}
db.KpDatabase.New(_ioc, _key);
db.KpDatabase.New(_ioc, _key, _app.GetFileStorage(_ioc).GetFilenameWithoutPathAndExt(_ioc));
db.KpDatabase.KdfParameters = (new AesKdf()).GetDefaultParameters();
db.KpDatabase.Name = "Keepass2Android Password Database";

View File

@@ -82,7 +82,7 @@ namespace keepass2android
}
//ok, try to load the database. Let's start with Kdbx format and retry later if that is the wrong guess:
_format = new KdbxDatabaseFormat(KdbpFile.GetFormatToUse(_ioc));
_format = new KdbxDatabaseFormat(KdbpFile.GetFormatToUse(_app.GetFileStorage(_ioc).GetFileExtension(_ioc)));
TryLoad(databaseStream);

View File

@@ -230,7 +230,7 @@ namespace keepass2android
PwDatabase pwImp = new PwDatabase();
PwDatabase pwDatabase = _db.KpDatabase;
pwImp.New(new IOConnectionInfo(), pwDatabase.MasterKey);
pwImp.New(new IOConnectionInfo(), pwDatabase.MasterKey, _app.GetFileStorage(ioc).GetFilenameWithoutPathAndExt(ioc));
pwImp.MemoryProtection = pwDatabase.MemoryProtection.CloneDeep();
pwImp.MasterKey = pwDatabase.MasterKey;
var stream = GetStreamForBaseFile(fileStorage, ioc);

View File

@@ -1552,7 +1552,7 @@ namespace keepass2android
private MemoryStream PreloadDbFile()
{
if (KdbpFile.GetFormatToUse(_ioConnection) == KdbxFormat.ProtocolBuffers)
if (KdbpFile.GetFormatToUse(App.Kp2a.GetFileStorage(_ioConnection).GetFileExtension(_ioConnection)) == KdbxFormat.ProtocolBuffers)
{
Kp2aLog.Log("Preparing kdbp serializer");
KdbpFile.PrepareSerializer();