Introduced IDatabaseLoader
(kdb not yet working)
This commit is contained in:
		
							
								
								
									
										13
									
								
								src/KeePassLib2Android/IDatabaseLoader.cs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										13
									
								
								src/KeePassLib2Android/IDatabaseLoader.cs
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,13 @@ | |||||||
|  | using System.IO; | ||||||
|  | using KeePassLib.Interfaces; | ||||||
|  | using KeePassLib.Keys; | ||||||
|  |  | ||||||
|  | namespace KeePassLib | ||||||
|  | { | ||||||
|  | 	public interface IDatabaseLoader | ||||||
|  | 	{ | ||||||
|  | 		void PopulateDatabaseFromStream(PwDatabase db, CompositeKey key, Stream s, IStatusLogger slLogger); | ||||||
|  |  | ||||||
|  | 		byte[] HashOfLastStream { get; } | ||||||
|  | 	} | ||||||
|  | } | ||||||
| @@ -20,7 +20,7 @@ | |||||||
|     <DebugType>full</DebugType> |     <DebugType>full</DebugType> | ||||||
|     <Optimize>False</Optimize> |     <Optimize>False</Optimize> | ||||||
|     <OutputPath>bin\Debug</OutputPath> |     <OutputPath>bin\Debug</OutputPath> | ||||||
|     <DefineConstants>DEBUG;EXCLUDE_TWOFISH;EXCLUDE_KEYBOARD;EXCLUDE_KEYTRANSFORM;INCLUDE_FILECHOOSER;INCLUDE_JAVAFILESTORAGE</DefineConstants> |     <DefineConstants>DEBUG;EXCLUDE_TWOFISH;EXCLUDE_KEYBOARD;EXCLUDE_KEYTRANSFORM;EXCLUDE_FILECHOOSER;EXCLUDE_JAVAFILESTORAGE</DefineConstants> | ||||||
|     <ErrorReport>prompt</ErrorReport> |     <ErrorReport>prompt</ErrorReport> | ||||||
|     <WarningLevel>4</WarningLevel> |     <WarningLevel>4</WarningLevel> | ||||||
|     <ConsolePause>False</ConsolePause> |     <ConsolePause>False</ConsolePause> | ||||||
| @@ -58,6 +58,7 @@ | |||||||
|     <Reference Include="Mono.Security" /> |     <Reference Include="Mono.Security" /> | ||||||
|   </ItemGroup> |   </ItemGroup> | ||||||
|   <ItemGroup> |   <ItemGroup> | ||||||
|  |     <Compile Include="IDatabaseLoader.cs" /> | ||||||
|     <Compile Include="Kp2aLog.cs" /> |     <Compile Include="Kp2aLog.cs" /> | ||||||
|     <Compile Include="Resources\Resource.designer.cs" /> |     <Compile Include="Resources\Resource.designer.cs" /> | ||||||
|     <Compile Include="Resources\KLRes.Generated.cs" /> |     <Compile Include="Resources\KLRes.Generated.cs" /> | ||||||
| @@ -153,11 +154,11 @@ | |||||||
|   <ItemGroup> |   <ItemGroup> | ||||||
|     <AndroidResource Include="Resources\values\Strings.xml" /> |     <AndroidResource Include="Resources\values\Strings.xml" /> | ||||||
|   </ItemGroup> |   </ItemGroup> | ||||||
|   <Import Project="$(MSBuildExtensionsPath)\Novell\Novell.MonoDroid.CSharp.targets" /> |  | ||||||
|   <ItemGroup> |   <ItemGroup> | ||||||
|     <ProjectReference Include="..\kp2akeytransform\kp2akeytransform.csproj" Condition="!$(DefineConstants.Contains('EXCLUDE_KEYTRANSFORM'))"> |     <ProjectReference Include="..\KP2AKdbLibraryBinding\KP2AKdbLibraryBinding.csproj"> | ||||||
|       <Project>{A57B3ACE-5634-469A-88C4-858BB409F356}</Project> |       <Project>{70d3844a-d9fa-4a64-b205-a84c6a822196}</Project> | ||||||
|       <Name>kp2akeytransform</Name> |       <Name>KP2AKdbLibraryBinding</Name> | ||||||
|     </ProjectReference> |     </ProjectReference> | ||||||
|   </ItemGroup> |   </ItemGroup> | ||||||
|  |   <Import Project="$(MSBuildExtensionsPath)\Novell\Novell.MonoDroid.CSharp.targets" /> | ||||||
| </Project> | </Project> | ||||||
| @@ -3,6 +3,7 @@ using Android.App; | |||||||
| using System.IO; | using System.IO; | ||||||
| using Android.Content; | using Android.Content; | ||||||
| using Android.OS; | using Android.OS; | ||||||
|  | using KeePassLib; | ||||||
| using KeePassLib.Keys; | using KeePassLib.Keys; | ||||||
| using KeePassLib.Serialization; | using KeePassLib.Serialization; | ||||||
| using keepass2android.Io; | using keepass2android.Io; | ||||||
| @@ -23,7 +24,7 @@ namespace keepass2android | |||||||
| 		/// <summary> | 		/// <summary> | ||||||
| 		/// Loads the specified data as the currently open database, as unlocked. | 		/// Loads the specified data as the currently open database, as unlocked. | ||||||
| 		/// </summary> | 		/// </summary> | ||||||
| 		void LoadDatabase(IOConnectionInfo ioConnectionInfo, MemoryStream memoryStream, CompositeKey compKey, ProgressDialogStatusLogger statusLogger); | 		void LoadDatabase(IOConnectionInfo ioConnectionInfo, MemoryStream memoryStream, CompositeKey compKey, ProgressDialogStatusLogger statusLogger, IDatabaseLoader databaseLoader); | ||||||
|  |  | ||||||
| 		/// <summary> | 		/// <summary> | ||||||
| 		/// Returns the current database | 		/// Returns the current database | ||||||
|   | |||||||
| @@ -93,34 +93,15 @@ namespace keepass2android | |||||||
| 		/// <summary> | 		/// <summary> | ||||||
| 		/// Do not call this method directly. Call App.Kp2a.LoadDatabase instead. | 		/// Do not call this method directly. Call App.Kp2a.LoadDatabase instead. | ||||||
| 		/// </summary> | 		/// </summary> | ||||||
| 		public void LoadData(IKp2aApp app, IOConnectionInfo iocInfo, MemoryStream databaseData, CompositeKey compositeKey, ProgressDialogStatusLogger status) | 		public void LoadData(IKp2aApp app, IOConnectionInfo iocInfo, MemoryStream databaseData, CompositeKey compositeKey, ProgressDialogStatusLogger status, IDatabaseLoader databaseLoader) | ||||||
| 		{ | 		{ | ||||||
| 			PwDatabase pwDatabase = new PwDatabase(); | 			PwDatabase pwDatabase = new PwDatabase(); | ||||||
|  |  | ||||||
| 			IFileStorage fileStorage = _app.GetFileStorage(iocInfo); | 			IFileStorage fileStorage = _app.GetFileStorage(iocInfo); | ||||||
| 			var filename = fileStorage.GetFilenameWithoutPathAndExt(iocInfo); | 			Stream s = databaseData ?? fileStorage.OpenFileForRead(iocInfo); | ||||||
| 			try | 			var fileVersion = _app.GetFileStorage(iocInfo).GetCurrentFileVersionFast(iocInfo); | ||||||
| 			{ | 			PopulateDatabaseFromStream(pwDatabase, s, iocInfo, compositeKey, status, databaseLoader); | ||||||
| 				var fileVersion = _app.GetFileStorage(iocInfo).GetCurrentFileVersionFast(iocInfo); | 			LastFileVersion = fileVersion; | ||||||
| 				pwDatabase.Open(databaseData ?? fileStorage.OpenFileForRead(iocInfo), filename, iocInfo, compositeKey, status); |  | ||||||
| 				LastFileVersion = fileVersion; |  | ||||||
| 			} |  | ||||||
| 			catch (InvalidCompositeKeyException) |  | ||||||
| 			{ |  | ||||||
| 				KcpPassword passwordKey = (KcpPassword)compositeKey.GetUserKey(typeof(KcpPassword)); |  | ||||||
| 			 |  | ||||||
| 				if ((passwordKey != null) && (passwordKey.Password.ReadString() == "") && (compositeKey.UserKeyCount > 1)) |  | ||||||
| 				{ |  | ||||||
| 					//if we don't get a password, we don't know whether this means "empty password" or "no password" |  | ||||||
| 					//retry without password: |  | ||||||
| 					compositeKey.RemoveUserKey(compositeKey.GetUserKey(typeof (KcpPassword))); |  | ||||||
| 					var fileVersion = _app.GetFileStorage(iocInfo).GetCurrentFileVersionFast(iocInfo); |  | ||||||
| 					//don't reuse the memory stream databaseData: it's already closed. |  | ||||||
| 					//We could try to avoid reading the file again here, but probably the case is rare enough so this is ok. |  | ||||||
| 					pwDatabase.Open(fileStorage.OpenFileForRead(iocInfo), filename, iocInfo, compositeKey, status); |  | ||||||
| 					LastFileVersion = fileVersion;				} |  | ||||||
| 				else throw; |  | ||||||
| 			} |  | ||||||
| 			 | 			 | ||||||
| 			status.UpdateSubMessage(""); | 			status.UpdateSubMessage(""); | ||||||
|  |  | ||||||
| @@ -133,7 +114,14 @@ namespace keepass2android | |||||||
| 			SearchHelper = new SearchDbHelper(app); | 			SearchHelper = new SearchDbHelper(app); | ||||||
| 		} | 		} | ||||||
|  |  | ||||||
| 		 | 		protected  virtual void PopulateDatabaseFromStream(PwDatabase pwDatabase, Stream s, IOConnectionInfo iocInfo, CompositeKey compositeKey, ProgressDialogStatusLogger status, IDatabaseLoader databaseLoader) | ||||||
|  | 		{ | ||||||
|  | 			IFileStorage fileStorage = _app.GetFileStorage(iocInfo); | ||||||
|  | 			var filename = fileStorage.GetFilenameWithoutPathAndExt(iocInfo); | ||||||
|  | 			pwDatabase.Open(s, filename, iocInfo, compositeKey, status, databaseLoader); | ||||||
|  | 		} | ||||||
|  |  | ||||||
|  |  | ||||||
| 		public PwGroup SearchForText(String str) { | 		public PwGroup SearchForText(String str) { | ||||||
| 			PwGroup group = SearchHelper.SearchForText(this, str); | 			PwGroup group = SearchHelper.SearchForText(this, str); | ||||||
| 			 | 			 | ||||||
| @@ -162,7 +150,7 @@ namespace keepass2android | |||||||
| 		} | 		} | ||||||
|  |  | ||||||
|  |  | ||||||
| 		public void SaveData(Context ctx)  { | 		public virtual void SaveData(Context ctx)  { | ||||||
|              |              | ||||||
| 			KpDatabase.UseFileTransactions = _app.GetBooleanPreference(PreferenceKey.UseFileTransactions); | 			KpDatabase.UseFileTransactions = _app.GetBooleanPreference(PreferenceKey.UseFileTransactions); | ||||||
| 			using (IWriteTransaction trans = _app.GetFileStorage(Ioc).OpenWriteTransaction(Ioc, KpDatabase.UseFileTransactions)) | 			using (IWriteTransaction trans = _app.GetFileStorage(Ioc).OpenWriteTransaction(Ioc, KpDatabase.UseFileTransactions)) | ||||||
|   | |||||||
							
								
								
									
										76
									
								
								src/Kp2aBusinessLogic/database/KdbDatabaseLoader.cs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										76
									
								
								src/Kp2aBusinessLogic/database/KdbDatabaseLoader.cs
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,76 @@ | |||||||
|  | using System; | ||||||
|  | using System.IO; | ||||||
|  | using System.Security.Cryptography; | ||||||
|  | using Android.Content; | ||||||
|  | using Com.Keepassdroid.Database; | ||||||
|  | using Com.Keepassdroid.Database.Exception; | ||||||
|  | using Java.Lang; | ||||||
|  | using KeePassLib; | ||||||
|  | using KeePassLib.Cryptography; | ||||||
|  | using KeePassLib.Cryptography.Cipher; | ||||||
|  | using KeePassLib.Interfaces; | ||||||
|  | using KeePassLib.Keys; | ||||||
|  | using Exception = System.Exception; | ||||||
|  |  | ||||||
|  | namespace keepass2android | ||||||
|  | { | ||||||
|  | 	class KdbDatabaseLoader: IDatabaseLoader | ||||||
|  | 	{ | ||||||
|  | 		private Context _ctx; | ||||||
|  |  | ||||||
|  | 		public KdbDatabaseLoader(Context ctx) | ||||||
|  | 		{ | ||||||
|  | 			_ctx = ctx; | ||||||
|  | 		} | ||||||
|  |  | ||||||
|  | 		public void PopulateDatabaseFromStream(PwDatabase db, CompositeKey key, Stream s, IStatusLogger slLogger) | ||||||
|  | 		{ | ||||||
|  | 			var importer = new Com.Keepassdroid.Database.Load.ImporterV3(); | ||||||
|  |  | ||||||
|  | 			var hashingStream = new HashingStreamEx(s, false, new SHA256Managed()); | ||||||
|  |  | ||||||
|  | 			string password = "";//no need to distinguish between null and "" because empty passwords are invalid (and null is not allowed) | ||||||
|  | 			KcpPassword passwordKey = (KcpPassword)key.GetUserKey(typeof(KcpPassword)); | ||||||
|  | 			if (passwordKey != null) | ||||||
|  | 			{ | ||||||
|  | 				password = passwordKey.Password.ReadString(); | ||||||
|  | 			} | ||||||
|  |  | ||||||
|  | 			KcpKeyFile passwordKeyfile = (KcpKeyFile)key.GetUserKey(typeof(KcpKeyFile)); | ||||||
|  | 			string keyfile = "";  | ||||||
|  | 			if (passwordKeyfile != null) | ||||||
|  | 			{ | ||||||
|  | 				keyfile = passwordKeyfile.Path; | ||||||
|  | 			} | ||||||
|  |  | ||||||
|  |  | ||||||
|  | 			try | ||||||
|  | 			{ | ||||||
|  | 				var dbv3 = importer.OpenDatabase(hashingStream, password, keyfile); | ||||||
|  |  | ||||||
|  | 				db.Name = dbv3.Name; | ||||||
|  | 			} | ||||||
|  | 			catch (InvalidPasswordException e) { | ||||||
|  | 			 | ||||||
|  | 				return; | ||||||
|  | 			} | ||||||
|  | 			catch (Java.IO.FileNotFoundException e) | ||||||
|  | 			{ | ||||||
|  | 				throw new FileNotFoundException( | ||||||
|  | 					e.Message, e); | ||||||
|  | 			}   | ||||||
|  | 			catch (Java.Lang.Exception e) | ||||||
|  | 			{ | ||||||
|  | 				throw new Exception(e.LocalizedMessage ?? | ||||||
|  | 				e.Message ?? | ||||||
|  | 				e.GetType().Name, e); | ||||||
|  | 			} | ||||||
|  | 			 | ||||||
|  | 			HashOfLastStream = hashingStream.Hash; | ||||||
|  | 			if (HashOfLastStream == null) | ||||||
|  | 				throw new Exception("hashing didn't work"); //todo remove | ||||||
|  | 		} | ||||||
|  |  | ||||||
|  | 		public byte[] HashOfLastStream { get; private set; } | ||||||
|  | 	} | ||||||
|  | } | ||||||
							
								
								
									
										31
									
								
								src/Kp2aBusinessLogic/database/KdbxDatabaseLoader.cs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										31
									
								
								src/Kp2aBusinessLogic/database/KdbxDatabaseLoader.cs
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,31 @@ | |||||||
|  | using System.IO; | ||||||
|  | using KeePassLib; | ||||||
|  | using KeePassLib.Interfaces; | ||||||
|  | using KeePassLib.Keys; | ||||||
|  | using KeePassLib.Serialization; | ||||||
|  |  | ||||||
|  | namespace keepass2android | ||||||
|  | { | ||||||
|  | 	public class KdbxDatabaseLoader : IDatabaseLoader | ||||||
|  | 	{ | ||||||
|  | 		private readonly KdbxFormat _format; | ||||||
|  |  | ||||||
|  | 		public KdbxDatabaseLoader(KdbxFormat format) | ||||||
|  | 		{ | ||||||
|  | 			_format = format; | ||||||
|  | 		} | ||||||
|  |  | ||||||
|  | 		public void PopulateDatabaseFromStream(PwDatabase db, CompositeKey key, Stream s, IStatusLogger slLogger) | ||||||
|  | 		{ | ||||||
|  | 			KdbxFile kdbx = new KdbxFile(db); | ||||||
|  | 			kdbx.DetachBinaries = db.DetachBinaries; | ||||||
|  |  | ||||||
|  | 			kdbx.Load(s, _format, slLogger); | ||||||
|  | 			HashOfLastStream = kdbx.HashOfFileOnDisk; | ||||||
|  | 			s.Close(); | ||||||
|  |  | ||||||
|  | 		} | ||||||
|  |  | ||||||
|  | 		public byte[] HashOfLastStream { get; private set; } | ||||||
|  | 	} | ||||||
|  | } | ||||||
| @@ -19,6 +19,8 @@ using System; | |||||||
| using System.IO; | using System.IO; | ||||||
| using System.Linq; | using System.Linq; | ||||||
| using System.Threading.Tasks; | using System.Threading.Tasks; | ||||||
|  | using Android.App; | ||||||
|  | using KeePassLib; | ||||||
| using KeePassLib.Keys; | using KeePassLib.Keys; | ||||||
| using KeePassLib.Serialization; | using KeePassLib.Serialization; | ||||||
|  |  | ||||||
| @@ -50,10 +52,24 @@ namespace keepass2android | |||||||
| 			try | 			try | ||||||
| 			{ | 			{ | ||||||
| 				StatusLogger.UpdateMessage(UiStringKey.loading_database); | 				StatusLogger.UpdateMessage(UiStringKey.loading_database); | ||||||
| 				MemoryStream memoryStream = _databaseData == null ? null : _databaseData.Result; | 				//get the stream data into a single stream variable (databaseStream) regardless whether its preloaded or not: | ||||||
| 				_app.LoadDatabase(_ioc, memoryStream, _compositeKey, StatusLogger); | 				MemoryStream preloadedMemoryStream = _databaseData == null ? null : _databaseData.Result; | ||||||
| 				SaveFileData(_ioc, _keyfileOrProvider); | 				MemoryStream databaseStream;  | ||||||
|  | 				if (preloadedMemoryStream != null) | ||||||
|  | 					databaseStream = preloadedMemoryStream; | ||||||
|  | 				else | ||||||
|  | 				{ | ||||||
|  | 					using (Stream s = _app.GetFileStorage(_ioc).OpenFileForRead(_ioc)) | ||||||
|  | 					{ | ||||||
|  | 						databaseStream = new MemoryStream(); | ||||||
|  | 						s.CopyTo(databaseStream); | ||||||
|  | 						databaseStream.Seek(0, SeekOrigin.Begin); | ||||||
|  | 					} | ||||||
|  | 				} | ||||||
|  |  | ||||||
|  | 				//ok, try to load the database. Let's start with Kdbx format and retry later if that is the wrong guess: | ||||||
|  | 				IDatabaseLoader loader = new KdbxDatabaseLoader(KdbpFile.GetFormatToUse(_ioc));  | ||||||
|  | 				TryLoad(databaseStream, loader); | ||||||
| 			} | 			} | ||||||
| 			catch (KeyFileException) | 			catch (KeyFileException) | ||||||
| 			{ | 			{ | ||||||
| @@ -73,11 +89,6 @@ namespace keepass2android | |||||||
| 				Finish(false, _app.GetResourceString(UiStringKey.ErrorOcurred) + " " + message); | 				Finish(false, _app.GetResourceString(UiStringKey.ErrorOcurred) + " " + message); | ||||||
| 				return; | 				return; | ||||||
| 			} | 			} | ||||||
| 			catch (OldFormatException ) |  | ||||||
| 			{ |  | ||||||
| 				Finish(false, "Cannot open Keepass 1.x database. As explained in the app description, Keepass2Android is for Keepass 2 only! Please use the desktop application to convert your database to the new file format!"); |  | ||||||
| 				return; |  | ||||||
| 			} |  | ||||||
| 			catch (Exception e) | 			catch (Exception e) | ||||||
| 			{ | 			{ | ||||||
| 				Kp2aLog.Log("Exception: " + e); | 				Kp2aLog.Log("Exception: " + e); | ||||||
| @@ -85,10 +96,48 @@ namespace keepass2android | |||||||
| 				return; | 				return; | ||||||
| 			} | 			} | ||||||
| 			 | 			 | ||||||
| 			Kp2aLog.Log("LoadDB OK"); | 			 | ||||||
| 			Finish(true); |  | ||||||
| 		} | 		} | ||||||
| 		 |  | ||||||
|  | 		private void TryLoad(MemoryStream databaseStream, IDatabaseLoader loader) | ||||||
|  | 		{ | ||||||
|  | 			//create a copy of the stream so we can try again if we get an exception which indicates we should change parameters | ||||||
|  | 			//This is not optimal in terms of (short-time) memory usage but is hard to avoid because the Keepass library closes streams also in case of errors. | ||||||
|  | 			//Alternatives would involve increased traffic (if file is on remote) and slower loading times, so this seems to be the best choice. | ||||||
|  | 			MemoryStream workingCopy = new MemoryStream(); | ||||||
|  | 			databaseStream.CopyTo(workingCopy); | ||||||
|  | 			workingCopy.Seek(0, SeekOrigin.Begin); | ||||||
|  | 			//reset stream if we need to reuse it later: | ||||||
|  | 			databaseStream.Seek(0, SeekOrigin.Begin); | ||||||
|  | 			//now let's go: | ||||||
|  | 			try | ||||||
|  | 			{ | ||||||
|  | 				_app.LoadDatabase(_ioc, workingCopy, _compositeKey, StatusLogger, loader); | ||||||
|  | 				SaveFileData(_ioc, _keyfileOrProvider); | ||||||
|  | 				Kp2aLog.Log("LoadDB OK"); | ||||||
|  | 				Finish(true); | ||||||
|  | 			} | ||||||
|  | 			catch (OldFormatException) | ||||||
|  | 			{ | ||||||
|  | 				TryLoad(databaseStream, new KdbDatabaseLoader(Application.Context)); | ||||||
|  | 			} | ||||||
|  | 			catch (InvalidCompositeKeyException) | ||||||
|  | 			{ | ||||||
|  | 				KcpPassword passwordKey = (KcpPassword)_compositeKey.GetUserKey(typeof(KcpPassword)); | ||||||
|  |  | ||||||
|  | 				if ((passwordKey != null) && (passwordKey.Password.ReadString() == "") && (_compositeKey.UserKeyCount > 1)) | ||||||
|  | 				{ | ||||||
|  | 					//if we don't get a password, we don't know whether this means "empty password" or "no password" | ||||||
|  | 					//retry without password: | ||||||
|  | 					_compositeKey.RemoveUserKey(passwordKey); | ||||||
|  | 					//retry: | ||||||
|  | 					TryLoad(databaseStream, loader); | ||||||
|  | 				} | ||||||
|  | 				else throw; | ||||||
|  | 			} | ||||||
|  | 			 | ||||||
|  | 		} | ||||||
|  |  | ||||||
| 		private void SaveFileData(IOConnectionInfo ioc, String keyfileOrProvider) { | 		private void SaveFileData(IOConnectionInfo ioc, String keyfileOrProvider) { | ||||||
|  |  | ||||||
|             if (!_rememberKeyfile) |             if (!_rememberKeyfile) | ||||||
|   | |||||||
| @@ -16,6 +16,13 @@ | |||||||
|     <AndroidResgenFile>Resources\Resource.Designer.cs</AndroidResgenFile> |     <AndroidResgenFile>Resources\Resource.Designer.cs</AndroidResgenFile> | ||||||
|     <GenerateSerializationAssemblies>Off</GenerateSerializationAssemblies> |     <GenerateSerializationAssemblies>Off</GenerateSerializationAssemblies> | ||||||
|     <AndroidManifest>Properties\AndroidManifest.xml</AndroidManifest> |     <AndroidManifest>Properties\AndroidManifest.xml</AndroidManifest> | ||||||
|  |     <AndroidUseLatestPlatformSdk /> | ||||||
|  |     <TargetFrameworkVersion>v4.2</TargetFrameworkVersion> | ||||||
|  |     <AndroidSupportedAbis>armeabi,armeabi-v7a,x86</AndroidSupportedAbis> | ||||||
|  |     <AndroidStoreUncompressedFileExtensions /> | ||||||
|  |     <MandroidI18n /> | ||||||
|  |     <JavaMaximumHeapSize /> | ||||||
|  |     <JavaOptions /> | ||||||
|   </PropertyGroup> |   </PropertyGroup> | ||||||
|   <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' "> |   <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' "> | ||||||
|     <DebugSymbols>true</DebugSymbols> |     <DebugSymbols>true</DebugSymbols> | ||||||
| @@ -96,8 +103,12 @@ | |||||||
|       <Project>{53A9CB7F-6553-4BC0-B56B-9410BB2E59AA}</Project> |       <Project>{53A9CB7F-6553-4BC0-B56B-9410BB2E59AA}</Project> | ||||||
|       <Name>Kp2aBusinessLogic</Name> |       <Name>Kp2aBusinessLogic</Name> | ||||||
|     </ProjectReference> |     </ProjectReference> | ||||||
|  |     <ProjectReference Include="..\KP2AKdbLibraryBinding\KP2AKdbLibraryBinding.csproj"> | ||||||
|  |       <Project>{70d3844a-d9fa-4a64-b205-a84c6a822196}</Project> | ||||||
|  |       <Name>KP2AKdbLibraryBinding</Name> | ||||||
|  |     </ProjectReference> | ||||||
|     <ProjectReference Include="..\monodroid-unittesting\MonoDroidUnitTesting\MonoDroidUnitTesting.csproj"> |     <ProjectReference Include="..\monodroid-unittesting\MonoDroidUnitTesting\MonoDroidUnitTesting.csproj"> | ||||||
|       <Project>{a5f8fb02-00e0-4335-91ef-aeaa2c2f3c48}</Project> |       <Project>{A5F8FB02-00E0-4335-91EF-AEAA2C2F3C48}</Project> | ||||||
|       <Name>MonoDroidUnitTesting</Name> |       <Name>MonoDroidUnitTesting</Name> | ||||||
|     </ProjectReference> |     </ProjectReference> | ||||||
|   </ItemGroup> |   </ItemGroup> | ||||||
|   | |||||||
| @@ -20,13 +20,14 @@ namespace Kp2aUnitTests | |||||||
|             // Run all tests from this assembly |             // Run all tests from this assembly | ||||||
|             //runner.AddTests(Assembly.GetExecutingAssembly()); |             //runner.AddTests(Assembly.GetExecutingAssembly()); | ||||||
| 			//runner.AddTests(new List<Type> { typeof(TestSynchronizeCachedDatabase)}); | 			//runner.AddTests(new List<Type> { typeof(TestSynchronizeCachedDatabase)}); | ||||||
| 			runner.AddTests(typeof(TestLoadDb).GetMethod("LoadErrorWithCertificateTrustFailure")); | 			//runner.AddTests(typeof(TestLoadDb).GetMethod("LoadErrorWithCertificateTrustFailure")); | ||||||
| 			 |  | ||||||
| 			//runner.AddTests(new List<Type> { typeof(TestSaveDb) }); | 			//runner.AddTests(new List<Type> { typeof(TestLoadDb) }); | ||||||
| 			//runner.AddTests(new List<Type> { typeof(TestCachingFileStorage) }); | 			//runner.AddTests(new List<Type> { typeof(TestCachingFileStorage) }); | ||||||
| 			//runner.AddTests(typeof(TestCachingFileStorage).GetMethod("TestSaveToRemote")); | 			runner.AddTests(typeof(TestLoadDb).GetMethod("TestLoadKdb1")); | ||||||
| 			//runner.AddTests(typeof(TestLoadDb).GetMethod("TestLoadKdbpWithPasswordOnly")); | 			runner.AddTests(typeof(TestLoadDb).GetMethod("TestLoadWithKeyfileOnly")); | ||||||
| 			//runner.AddTests(typeof(TestSaveDb).GetMethod("TestLoadKdbxAndSaveKdbp_TestIdenticalFiles")); | 			runner.AddTests(typeof(TestLoadDb).GetMethod("TestLoadKdbpWithPasswordOnly")); | ||||||
|  | 			runner.AddTests(typeof(TestSaveDb).GetMethod("TestLoadKdbxAndSaveKdbp_TestIdenticalFiles")); | ||||||
|             return runner; |             return runner; | ||||||
|         } |         } | ||||||
|     } |     } | ||||||
|   | |||||||
| @@ -43,7 +43,7 @@ namespace Kp2aUnitTests | |||||||
|  |  | ||||||
| 			//ensure the the database can be loaded from file: | 			//ensure the the database can be loaded from file: | ||||||
| 			PwDatabase loadedDb = new PwDatabase(); | 			PwDatabase loadedDb = new PwDatabase(); | ||||||
| 			loadedDb.Open(ioc, new CompositeKey(), null); | 			loadedDb.Open(ioc, new CompositeKey(), null, new KdbxDatabaseLoader(KdbxFormat.Default)); | ||||||
|  |  | ||||||
| 			//Check whether the databases are equal | 			//Check whether the databases are equal | ||||||
| 			AssertDatabasesAreEqual(loadedDb, app.GetDb().KpDatabase); | 			AssertDatabasesAreEqual(loadedDb, app.GetDb().KpDatabase); | ||||||
|   | |||||||
| @@ -5,6 +5,7 @@ using System.Net.Security; | |||||||
| using Android.App; | using Android.App; | ||||||
| using Android.Content; | using Android.Content; | ||||||
| using Android.OS; | using Android.OS; | ||||||
|  | using KeePassLib; | ||||||
| using KeePassLib.Keys; | using KeePassLib.Keys; | ||||||
| using KeePassLib.Serialization; | using KeePassLib.Serialization; | ||||||
| using keepass2android; | using keepass2android; | ||||||
| @@ -48,10 +49,9 @@ namespace Kp2aUnitTests | |||||||
| 			throw new NotImplementedException(); | 			throw new NotImplementedException(); | ||||||
| 		} | 		} | ||||||
|  |  | ||||||
| 		public void LoadDatabase(IOConnectionInfo ioConnectionInfo, MemoryStream memoryStream, CompositeKey compKey, | 		public void LoadDatabase(IOConnectionInfo ioConnectionInfo, MemoryStream memoryStream, CompositeKey compKey, ProgressDialogStatusLogger statusLogger, IDatabaseLoader databaseLoader) | ||||||
| 		                         ProgressDialogStatusLogger statusLogger) |  | ||||||
| 		{ | 		{ | ||||||
| 			_db.LoadData(this, ioConnectionInfo, memoryStream, compKey, statusLogger); | 			_db.LoadData(this, ioConnectionInfo, memoryStream, compKey, statusLogger, databaseLoader); | ||||||
| 		} | 		} | ||||||
| 		public Database GetDb() | 		public Database GetDb() | ||||||
| 		{ | 		{ | ||||||
|   | |||||||
| @@ -20,10 +20,12 @@ namespace Kp2aUnitTests | |||||||
| 			app.CreateNewDatabase(); | 			app.CreateNewDatabase(); | ||||||
| 			bool loadSuccesful = false; | 			bool loadSuccesful = false; | ||||||
| 			var key = CreateKey(password, keyfile); | 			var key = CreateKey(password, keyfile); | ||||||
|  | 			string loadErrorMessage = ""; | ||||||
|  |  | ||||||
| 			LoadDb task = new LoadDb(app, new IOConnectionInfo { Path = TestDbDirectory+filenameWithoutDir }, null, | 			LoadDb task = new LoadDb(app, new IOConnectionInfo { Path = TestDbDirectory+filenameWithoutDir }, null, | ||||||
| 				key, keyfile, new ActionOnFinish((success, message) => | 				key, keyfile, new ActionOnFinish((success, message) => | ||||||
| 					{ | 					{ | ||||||
|  | 						loadErrorMessage = message; | ||||||
| 						if (!success) | 						if (!success) | ||||||
| 							Android.Util.Log.Debug("KP2ATest", "error loading db: " + message); | 							Android.Util.Log.Debug("KP2ATest", "error loading db: " + message); | ||||||
| 						loadSuccesful = success; 		 | 						loadSuccesful = success; 		 | ||||||
| @@ -34,7 +36,7 @@ namespace Kp2aUnitTests | |||||||
| 			pt.Run(); | 			pt.Run(); | ||||||
| 			pt.JoinWorkerThread(); | 			pt.JoinWorkerThread(); | ||||||
| 			Android.Util.Log.Debug("KP2ATest", "PT.run finished"); | 			Android.Util.Log.Debug("KP2ATest", "PT.run finished"); | ||||||
| 			Assert.IsTrue(loadSuccesful, "didn't succesfully load database :-("); | 			Assert.IsTrue(loadSuccesful, "didn't succesfully load database :-( "+loadErrorMessage); | ||||||
| 			 | 			 | ||||||
| 			Assert.AreEqual(6,app.GetDb().KpDatabase.RootGroup.Groups.Count()); | 			Assert.AreEqual(6,app.GetDb().KpDatabase.RootGroup.Groups.Count()); | ||||||
| 			Assert.AreEqual(2,app.GetDb().KpDatabase.RootGroup.Entries.Count()); | 			Assert.AreEqual(2,app.GetDb().KpDatabase.RootGroup.Entries.Count()); | ||||||
| @@ -48,6 +50,14 @@ namespace Kp2aUnitTests | |||||||
| 		{ | 		{ | ||||||
| 			RunLoadTest("passwordonly.kdbx", DefaultPassword, ""); | 			RunLoadTest("passwordonly.kdbx", DefaultPassword, ""); | ||||||
| 		} | 		} | ||||||
|  |  | ||||||
|  |  | ||||||
|  | 		[TestMethod] | ||||||
|  | 		public void TestLoadKdb1() | ||||||
|  | 		{ | ||||||
|  | 			RunLoadTest("test1.kdb", "12345", ""); | ||||||
|  | 		} | ||||||
|  |  | ||||||
| 		[TestMethod] | 		[TestMethod] | ||||||
| 		public void TestLoadWithKeyfileOnly() | 		public void TestLoadWithKeyfileOnly() | ||||||
| 		{ | 		{ | ||||||
|   | |||||||
| @@ -2,8 +2,8 @@ | |||||||
| <classpath> | <classpath> | ||||||
| 	<classpathentry kind="con" path="com.android.ide.eclipse.adt.ANDROID_FRAMEWORK"/> | 	<classpathentry kind="con" path="com.android.ide.eclipse.adt.ANDROID_FRAMEWORK"/> | ||||||
| 	<classpathentry exported="true" kind="con" path="com.android.ide.eclipse.adt.LIBRARIES"/> | 	<classpathentry exported="true" kind="con" path="com.android.ide.eclipse.adt.LIBRARIES"/> | ||||||
|  | 	<classpathentry exported="true" kind="con" path="com.android.ide.eclipse.adt.DEPENDENCIES"/> | ||||||
| 	<classpathentry kind="src" path="src"/> | 	<classpathentry kind="src" path="src"/> | ||||||
| 	<classpathentry kind="src" path="gen"/> | 	<classpathentry kind="src" path="gen"/> | ||||||
| 	<classpathentry exported="true" kind="con" path="com.android.ide.eclipse.adt.DEPENDENCIES"/> |  | ||||||
| 	<classpathentry kind="output" path="bin/classes"/> | 	<classpathentry kind="output" path="bin/classes"/> | ||||||
| </classpath> | </classpath> | ||||||
|   | |||||||
| @@ -1,5 +1,5 @@ | |||||||
| <manifest xmlns:android="http://schemas.android.com/apk/res/android" | <manifest xmlns:android="http://schemas.android.com/apk/res/android" | ||||||
|     package="keepass2android.kp2akeytransform" |     package="keepass2android.KdbLibrary" | ||||||
|     android:versionCode="1" |     android:versionCode="1" | ||||||
|     android:versionName="1.0" > |     android:versionName="1.0" > | ||||||
|  |  | ||||||
| @@ -7,8 +7,7 @@ | |||||||
|         android:minSdkVersion="8" |         android:minSdkVersion="8" | ||||||
|         android:targetSdkVersion="17" /> |         android:targetSdkVersion="17" /> | ||||||
|  |  | ||||||
|     <application |     <application> | ||||||
|         android:allowBackup="true"> |  | ||||||
|     </application> |     </application> | ||||||
|  |  | ||||||
| </manifest> | </manifest> | ||||||
										
											Binary file not shown.
										
									
								
							| @@ -835,7 +835,7 @@ namespace keepass2android | |||||||
| 			 | 			 | ||||||
| 		} | 		} | ||||||
|  |  | ||||||
| 		private MemoryStream LoadDbFile() | 		private MemoryStream PreloadDbFile() | ||||||
| 		{ | 		{ | ||||||
| 			if (KdbpFile.GetFormatToUse(_ioConnection) == KdbxFormat.ProtocolBuffers) | 			if (KdbpFile.GetFormatToUse(_ioConnection) == KdbxFormat.ProtocolBuffers) | ||||||
| 			{ | 			{ | ||||||
| @@ -998,7 +998,7 @@ namespace keepass2android | |||||||
| 					if (_loadDbTask == null && _prefs.GetBoolean(GetString(Resource.String.PreloadDatabaseEnabled_key), true)) | 					if (_loadDbTask == null && _prefs.GetBoolean(GetString(Resource.String.PreloadDatabaseEnabled_key), true)) | ||||||
| 					{ | 					{ | ||||||
| 						// Create task to kick off file loading while the user enters the password | 						// Create task to kick off file loading while the user enters the password | ||||||
| 						_loadDbTask = Task.Factory.StartNew<MemoryStream>(LoadDbFile); | 						_loadDbTask = Task.Factory.StartNew<MemoryStream>(PreloadDbFile); | ||||||
| 					} | 					} | ||||||
| 				} | 				} | ||||||
| 			} | 			} | ||||||
|   | |||||||
| @@ -24,6 +24,7 @@ using Android.Graphics.Drawables; | |||||||
| using Android.OS; | using Android.OS; | ||||||
| using Android.Runtime; | using Android.Runtime; | ||||||
| using Android.Widget; | using Android.Widget; | ||||||
|  | using KeePassLib; | ||||||
| using KeePassLib.Cryptography.Cipher; | using KeePassLib.Cryptography.Cipher; | ||||||
| using KeePassLib.Keys; | using KeePassLib.Keys; | ||||||
| using KeePassLib.Serialization; | using KeePassLib.Serialization; | ||||||
| @@ -108,9 +109,9 @@ namespace keepass2android | |||||||
| 			Application.Context.SendBroadcast(new Intent(Intents.DatabaseLocked)); | 			Application.Context.SendBroadcast(new Intent(Intents.DatabaseLocked)); | ||||||
|         } |         } | ||||||
|  |  | ||||||
| 		public void LoadDatabase(IOConnectionInfo ioConnectionInfo, MemoryStream memoryStream, CompositeKey compositeKey, ProgressDialogStatusLogger statusLogger) | 		public void LoadDatabase(IOConnectionInfo ioConnectionInfo, MemoryStream memoryStream, CompositeKey compositeKey, ProgressDialogStatusLogger statusLogger, IDatabaseLoader databaseLoader) | ||||||
| 		{ | 		{ | ||||||
| 			_db.LoadData(this, ioConnectionInfo, memoryStream, compositeKey, statusLogger); | 			_db.LoadData(this, ioConnectionInfo, memoryStream, compositeKey, statusLogger, databaseLoader); | ||||||
|  |  | ||||||
| 			UpdateOngoingNotification(); | 			UpdateOngoingNotification(); | ||||||
| 		} | 		} | ||||||
|   | |||||||
| @@ -30,7 +30,7 @@ | |||||||
|     <DebugType>full</DebugType> |     <DebugType>full</DebugType> | ||||||
|     <Optimize>false</Optimize> |     <Optimize>false</Optimize> | ||||||
|     <OutputPath>bin\Debug</OutputPath> |     <OutputPath>bin\Debug</OutputPath> | ||||||
|     <DefineConstants>DEBUG;EXCLUDE_TWOFISH;INCLUDE_KEYBOARD;INCLUDE_KEYTRANSFORM;INCLUDE_FILECHOOSER;INCLUDE_JAVAFILESTORAGE</DefineConstants> |     <DefineConstants>DEBUG;EXCLUDE_TWOFISH;EXCLUDE_KEYBOARD;EXCLUDE_KEYTRANSFORM;EXCLUDE_FILECHOOSER;EXCLUDE_JAVAFILESTORAGE</DefineConstants> | ||||||
|     <ErrorReport>prompt</ErrorReport> |     <ErrorReport>prompt</ErrorReport> | ||||||
|     <WarningLevel>4</WarningLevel> |     <WarningLevel>4</WarningLevel> | ||||||
|     <ConsolePause>False</ConsolePause> |     <ConsolePause>False</ConsolePause> | ||||||
| @@ -911,4 +911,10 @@ | |||||||
|   <ItemGroup> |   <ItemGroup> | ||||||
|     <AndroidResource Include="Resources\drawable\ic_storage_sftp.png" /> |     <AndroidResource Include="Resources\drawable\ic_storage_sftp.png" /> | ||||||
|   </ItemGroup> |   </ItemGroup> | ||||||
|  |   <ItemGroup> | ||||||
|  |     <AndroidResource Include="Resources\drawable-hdpi\4-collections-new-label.png" /> | ||||||
|  |   </ItemGroup> | ||||||
|  |   <ItemGroup> | ||||||
|  |     <AndroidResource Include="Resources\drawable-hdpi\device_access_new_account.png" /> | ||||||
|  |   </ItemGroup> | ||||||
| </Project> | </Project> | ||||||
| @@ -65,7 +65,7 @@ namespace MonoDroidUnitTesting { | |||||||
|     protected override void OnStart() { |     protected override void OnStart() { | ||||||
|       base.OnStart(); |       base.OnStart(); | ||||||
|  |  | ||||||
|       new Handler().Post(this.RunTests); |       //new Handler().Post(this.RunTests); | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     protected virtual void OnTestRunStarted() { } |     protected virtual void OnTestRunStarted() { } | ||||||
| @@ -171,6 +171,9 @@ namespace MonoDroidUnitTesting { | |||||||
|     protected override void OnResume() { |     protected override void OnResume() { | ||||||
|       base.OnResume(); |       base.OnResume(); | ||||||
|  |  | ||||||
|  | 	    TestRunner = null; | ||||||
|  | 		new Handler().Post(this.RunTests); | ||||||
|  |  | ||||||
|       if (TestRunner != null) { |       if (TestRunner != null) { | ||||||
|         // Only remember this view if the test run finished and therefore the previous activity has been restored. |         // Only remember this view if the test run finished and therefore the previous activity has been restored. | ||||||
|         ISharedPreferencesEditor e = GetPreferences().Edit(); |         ISharedPreferencesEditor e = GetPreferences().Edit(); | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user
	 Philipp Crocoll
					Philipp Crocoll