refactoring, use less UrlUtil and more IFileStorage
This commit is contained in:
		| @@ -21,7 +21,6 @@ | ||||
|  | ||||
| using System; | ||||
| using System.Diagnostics; | ||||
| using System.IO; | ||||
| using System.Security; | ||||
|  | ||||
| #if !KeePassUAP | ||||
| @@ -78,25 +77,6 @@ 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) | ||||
| 		{ | ||||
| 			byte[] pbKey = null; | ||||
|   | ||||
| @@ -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. | ||||
| @@ -670,36 +655,6 @@ namespace KeePassLib | ||||
| 			} | ||||
| 		} | ||||
|          | ||||
| 		/// <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 | ||||
|   | ||||
| @@ -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); | ||||
|   | ||||
| @@ -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; } | ||||
|   | ||||
| @@ -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) | ||||
|   | ||||
| @@ -82,6 +82,11 @@ namespace keepass2android.Io | ||||
| 		        UrlUtil.GetFileName(ioc.Path)); | ||||
|         } | ||||
|  | ||||
| 	    public string GetFileExtension(IOConnectionInfo ioc) | ||||
| 	    { | ||||
| 	        return UrlUtil.GetExtension(ioc.Path); | ||||
|         } | ||||
|  | ||||
| 	    public bool RequiresCredentials(IOConnectionInfo ioc) | ||||
| 		{ | ||||
| 			return false; | ||||
|   | ||||
| @@ -201,6 +201,11 @@ namespace keepass2android.Io | ||||
|  | ||||
| 		} | ||||
|  | ||||
| 	    public string GetFileExtension(IOConnectionInfo ioc) | ||||
| 	    { | ||||
| 	        return UrlUtil.GetExtension(ioc.Path); | ||||
|         } | ||||
|  | ||||
| 	    public bool RequiresCredentials(IOConnectionInfo ioc) | ||||
| 		{ | ||||
| 			return (!ioc.IsLocalFile()) && (ioc.CredSaveMode != IOCredSaveMode.SaveCred); | ||||
|   | ||||
| @@ -448,6 +448,11 @@ namespace keepass2android.Io | ||||
| 			return _cachedStorage.GetFilenameWithoutPathAndExt(ioc); | ||||
| 		} | ||||
|  | ||||
| 	    public string GetFileExtension(IOConnectionInfo ioc) | ||||
| 	    { | ||||
| 	        return _cachedStorage.GetFileExtension(ioc); | ||||
| 	    } | ||||
|  | ||||
| 	    public bool RequiresCredentials(IOConnectionInfo ioc) | ||||
| 		{ | ||||
| 			return _cachedStorage.RequiresCredentials(ioc); | ||||
|   | ||||
| @@ -89,6 +89,8 @@ namespace keepass2android.Io | ||||
|  | ||||
| 		string GetFilenameWithoutPathAndExt(IOConnectionInfo ioc); | ||||
|  | ||||
| 	    string GetFileExtension(IOConnectionInfo ioc); | ||||
|  | ||||
|         /// <summary> | ||||
|         /// Returns true if the the given ioc must be filled with username/password | ||||
|         /// </summary> | ||||
|   | ||||
| @@ -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); | ||||
|   | ||||
| @@ -177,6 +177,11 @@ namespace keepass2android.Io | ||||
| 					_jfs.GetFilename(IocToPath(ioc))); | ||||
| 		} | ||||
|  | ||||
| 	    public string GetFileExtension(IOConnectionInfo ioc) | ||||
| 	    { | ||||
| 	        return UrlUtil.GetExtension(ioc.Path); | ||||
|         } | ||||
|  | ||||
| 	    public bool RequiresCredentials(IOConnectionInfo ioc) | ||||
| 		{ | ||||
| 			return false; | ||||
|   | ||||
| @@ -314,6 +314,11 @@ namespace keepass2android.Io | ||||
| 				UrlUtil.GetFileName(ioc.Path)); | ||||
| 		} | ||||
|  | ||||
| 	    public string GetFileExtension(IOConnectionInfo ioc) | ||||
| 	    { | ||||
| 	        return UrlUtil.GetExtension(ioc.Path); | ||||
|         } | ||||
|  | ||||
| 	    public bool RequiresCredentials(IOConnectionInfo ioc) | ||||
| 		{ | ||||
| 			return false; | ||||
|   | ||||
| @@ -78,6 +78,11 @@ namespace keepass2android.Io | ||||
| 			return _baseStorage.GetFilenameWithoutPathAndExt(ioc); | ||||
| 		} | ||||
|  | ||||
| 	    public string GetFileExtension(IOConnectionInfo ioc) | ||||
| 	    { | ||||
| 	        return _baseStorage.GetFileExtension(ioc); | ||||
| 	    } | ||||
|  | ||||
| 	    public bool RequiresCredentials(IOConnectionInfo ioc) | ||||
| 		{ | ||||
| 			return _baseStorage.RequiresCredentials(ioc); | ||||
|   | ||||
| @@ -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; | ||||
|   | ||||
| @@ -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,39 +87,6 @@ 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) | ||||
| 		{ | ||||
|   | ||||
| @@ -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"; | ||||
|   | ||||
| @@ -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); | ||||
|  | ||||
|  | ||||
|   | ||||
| @@ -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); | ||||
|   | ||||
| @@ -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(); | ||||
|   | ||||
		Reference in New Issue
	
	Block a user
	 Philipp Crocoll
					Philipp Crocoll