fixed problems with OTP, completed implementation to work with cloud storage
This commit is contained in:
		| @@ -20,7 +20,7 @@ | ||||
|     <DebugType>full</DebugType> | ||||
|     <Optimize>False</Optimize> | ||||
|     <OutputPath>bin\Debug</OutputPath> | ||||
|     <DefineConstants>DEBUG;EXCLUDE_TWOFISH;EXCLUDE_KEYBOARD;EXCLUDE_KEYTRANSFORM;EXCLUDE_FILECHOOSER;EXCLUDE_JAVAFILESTORAGE</DefineConstants> | ||||
|     <DefineConstants>DEBUG;EXCLUDE_TWOFISH;EXCLUDE_KEYBOARD;EXCLUDE_KEYTRANSFORM;INCLUDE_FILECHOOSER;INCLUDE_JAVAFILESTORAGE</DefineConstants> | ||||
|     <ErrorReport>prompt</ErrorReport> | ||||
|     <WarningLevel>4</WarningLevel> | ||||
|     <ConsolePause>False</ConsolePause> | ||||
|   | ||||
| @@ -275,6 +275,27 @@ namespace keepass2android.Io | ||||
| 			return _jfs.CreateFilePath(parent, newFilename); | ||||
| 		} | ||||
|  | ||||
| 		public IOConnectionInfo GetParentPath(IOConnectionInfo ioc) | ||||
| 		{ | ||||
| 			return IoUtil.GetParentPath(ioc); | ||||
| 		} | ||||
|  | ||||
| 		public IOConnectionInfo GetFilePath(IOConnectionInfo folderPath, string filename) | ||||
| 		{ | ||||
| 			try | ||||
| 			{ | ||||
| 				return IOConnectionInfo.FromPath( | ||||
| 				ListContents(folderPath).Where(desc => { return desc.DisplayName == filename; }) | ||||
| 					.Single() | ||||
| 					.Path); | ||||
| 			} | ||||
| 			catch (Exception e) | ||||
| 			{ | ||||
| 				throw new Exception("Error finding " + filename + " in " + folderPath.GetDisplayName(), e); | ||||
| 			} | ||||
| 			 | ||||
| 		} | ||||
|  | ||||
| 		private DateTime JavaTimeToCSharp(long javatime) | ||||
| 		{ | ||||
| 			return new DateTime(1970, 1, 1).AddMilliseconds(javatime); | ||||
|   | ||||
| @@ -20,7 +20,7 @@ | ||||
|     <DebugType>full</DebugType> | ||||
|     <Optimize>false</Optimize> | ||||
|     <OutputPath>bin\Debug\</OutputPath> | ||||
|     <DefineConstants>TRACE;DEBUG;EXCLUDE_TWOFISH;EXCLUDE_KEYBOARD;EXCLUDE_KEYTRANSFORM;EXCLUDE_FILECHOOSER;EXCLUDE_JAVAFILESTORAGE</DefineConstants> | ||||
|     <DefineConstants>TRACE;DEBUG;EXCLUDE_TWOFISH;EXCLUDE_KEYBOARD;EXCLUDE_KEYTRANSFORM;INCLUDE_FILECHOOSER;INCLUDE_JAVAFILESTORAGE</DefineConstants> | ||||
|     <ErrorReport>prompt</ErrorReport> | ||||
|     <WarningLevel>4</WarningLevel> | ||||
|   </PropertyGroup> | ||||
|   | ||||
| @@ -45,7 +45,7 @@ namespace keepass2android | ||||
| 		} | ||||
| 		 | ||||
| 		 | ||||
| 		public override void Run () | ||||
| 		public override void Run() | ||||
| 		{ | ||||
| 			try | ||||
| 			{ | ||||
|   | ||||
| @@ -368,56 +368,68 @@ namespace keepass2android | ||||
| 			return base.OnOptionsItemSelected(item); | ||||
| 		} | ||||
|  | ||||
| 		class SyncOtpAuxFile: OnFinish | ||||
| 		public class SyncOtpAuxFile: RunnableOnFinish | ||||
| 		{ | ||||
| 			private readonly IOConnectionInfo _ioc; | ||||
|  | ||||
| 			public SyncOtpAuxFile(IOConnectionInfo ioc) | ||||
| 			public SyncOtpAuxFile(IOConnectionInfo ioc) : base(null) | ||||
| 			{ | ||||
| 				_ioc = ioc; | ||||
| 			} | ||||
|  | ||||
| 			public override void Run() | ||||
| 			{ | ||||
| 				if (Handler != null) | ||||
| 				StatusLogger.UpdateMessage(UiStringKey.SynchronizingOtpAuxFile); | ||||
| 				try | ||||
| 				{ | ||||
| 					Handler.Post(DoSyncOtpAuxFile); | ||||
| 					//simply open the file. The file storage does a complete sync. | ||||
| 					using (App.Kp2a.GetOtpAuxFileStorage(_ioc).OpenFileForRead(_ioc)) | ||||
| 					{ | ||||
| 					} | ||||
|  | ||||
| 					Finish(true); | ||||
| 				} | ||||
| 				else | ||||
| 					DoSyncOtpAuxFile(); | ||||
| 				base.Run(); | ||||
| 				catch (Exception e) | ||||
| 				{ | ||||
| 				 | ||||
| 					Finish(false, e.Message); | ||||
| 				} | ||||
| 				 | ||||
| 				 | ||||
| 			} | ||||
|  | ||||
| 			private void DoSyncOtpAuxFile() | ||||
| 			{ | ||||
| 				StatusLogger.UpdateMessage(UiStringKey.SynchronizingOtpAuxFile); | ||||
| 				//simply open the file. The file storage does a complete sync. | ||||
| 				using (App.Kp2a.GetOtpAuxFileStorage(_ioc).OpenFileForRead(_ioc)) | ||||
| 				{ | ||||
| 					 | ||||
| 				} | ||||
| 			} | ||||
| 		} | ||||
|  | ||||
| 		private void Synchronize() | ||||
| 		{ | ||||
| 			var filestorage = App.Kp2a.GetFileStorage(App.Kp2a.GetDb().Ioc); | ||||
| 			RunnableOnFinish task; | ||||
| 			ActionOnFinish onFinishShowMessage = new ActionOnFinish((success, message) => | ||||
| 			OnFinish onFinish = new ActionOnFinish((success, message) => | ||||
| 			{ | ||||
| 				if (!String.IsNullOrEmpty(message)) | ||||
| 					Toast.MakeText(this, message, ToastLength.Long).Show(); | ||||
|  | ||||
| 				if (App.Kp2a.GetDb().OtpAuxFileIoc != null) | ||||
| 				{ | ||||
| 					var task2 = new SyncOtpAuxFile(App.Kp2a.GetDb().OtpAuxFileIoc); | ||||
| 					new ProgressTask(App.Kp2a, this, task2).Run(); | ||||
| 				} | ||||
| 			}); | ||||
| 			 | ||||
| 			if (filestorage is CachingFileStorage) | ||||
| 			{ | ||||
| 				 | ||||
| 				task = new SynchronizeCachedDatabase(this, App.Kp2a, onFinishShowMessage); | ||||
| 				task = new SynchronizeCachedDatabase(this, App.Kp2a, onFinish); | ||||
| 			} | ||||
| 			else | ||||
| 			{ | ||||
|  | ||||
| 				task = new CheckDatabaseForChanges(this, App.Kp2a, onFinishShowMessage); | ||||
| 				task = new CheckDatabaseForChanges(this, App.Kp2a, onFinish); | ||||
| 			} | ||||
|  | ||||
| 			 | ||||
| 									 | ||||
|  | ||||
| 			var progressTask = new ProgressTask(App.Kp2a, this, task); | ||||
| 			progressTask.Run(); | ||||
|  | ||||
|   | ||||
| @@ -269,7 +269,15 @@ namespace keepass2android | ||||
| 				//doInBackground | ||||
| 				delegate | ||||
| 				{ | ||||
| 					_otpInfo = OathHotpKeyProv.LoadOtpInfo(new KeyProviderQueryContext(_ioConnection, false, false)); | ||||
| 					try | ||||
| 					{ | ||||
| 						_otpInfo = OathHotpKeyProv.LoadOtpInfo(new KeyProviderQueryContext(_ioConnection, false, false)); | ||||
| 					} | ||||
| 					catch (Exception e) | ||||
| 					{ | ||||
| 						Kp2aLog.Log(e.ToString()); | ||||
| 					} | ||||
| 					 | ||||
| 					return null; | ||||
| 				}, | ||||
| 				//onPostExecute | ||||
| @@ -694,8 +702,8 @@ namespace keepass2android | ||||
|  | ||||
| 				try | ||||
| 				{ | ||||
| 					var lOtps = GetOtpsFromUI(); | ||||
| 					CreateOtpSecret(lOtps); | ||||
| 					var lOtps = GetOtpsFromUi(); | ||||
| 					OathHotpKeyProv.CreateOtpSecret(lOtps, _otpInfo); | ||||
| 				} | ||||
| 				catch (Exception) | ||||
| 				{ | ||||
| @@ -731,7 +739,12 @@ namespace keepass2android | ||||
| 			MakePasswordMaskedOrVisible(); | ||||
|  | ||||
| 			Handler handler = new Handler(); | ||||
| 			LoadDb task = new LoadDb(App.Kp2a, _ioConnection, _loadDbTask, compositeKey, _keyFileOrProvider, new AfterLoad(handler, this)); | ||||
| 			OnFinish onFinish = new AfterLoad(handler, this); | ||||
| 				  | ||||
| 			LoadDb task = (KeyProviderType == KeyProviders.Otp) ? | ||||
| 				new SaveOtpAuxFileAndLoadDb(App.Kp2a, _ioConnection, _loadDbTask, compositeKey, _keyFileOrProvider, onFinish, this) | ||||
| 				: | ||||
| 				new LoadDb(App.Kp2a, _ioConnection, _loadDbTask, compositeKey, _keyFileOrProvider, onFinish); | ||||
| 			_loadDbTask = null; // prevent accidental re-use | ||||
|  | ||||
| 			SetNewDefaultFile(); | ||||
| @@ -739,7 +752,7 @@ namespace keepass2android | ||||
| 			new ProgressTask(App.Kp2a, this, task).Run(); | ||||
| 		} | ||||
|  | ||||
| 		private List<string> GetOtpsFromUI() | ||||
| 		private List<string> GetOtpsFromUi() | ||||
| 		{ | ||||
| 			List<string> lOtps = new List<string>(); | ||||
| 			foreach (int otpId in _otpTextViewIds) | ||||
| @@ -751,43 +764,6 @@ namespace keepass2android | ||||
| 			return lOtps; | ||||
| 		} | ||||
|  | ||||
| 		private void CreateOtpSecret(List<string> lOtps) | ||||
| 		{ | ||||
| 			byte[] pbSecret; | ||||
| 			if (!string.IsNullOrEmpty(_otpInfo.EncryptedSecret)) // < v2.0 | ||||
| 			{ | ||||
| 				byte[] pbKey32 = OtpUtil.KeyFromOtps(lOtps.ToArray(), 0, | ||||
| 				                                     lOtps.Count, Convert.FromBase64String( | ||||
| 					                                     _otpInfo.TransformationKey), _otpInfo.TransformationRounds); | ||||
| 				if (pbKey32 == null) throw new InvalidOperationException(); | ||||
|  | ||||
| 				pbSecret = OtpUtil.DecryptData(_otpInfo.EncryptedSecret, | ||||
| 				                               pbKey32, Convert.FromBase64String(_otpInfo.EncryptionIV)); | ||||
| 				if (pbSecret == null) throw new InvalidOperationException(); | ||||
|  | ||||
| 				_otpInfo.Secret = pbSecret; | ||||
| 				_otpInfo.Counter += (ulong) _otpInfo.OtpsRequired; | ||||
| 			} | ||||
| 			else // >= v2.0, supporting look-ahead | ||||
| 			{ | ||||
| 				bool bSuccess = false; | ||||
| 				for (int i = 0; i < _otpInfo.EncryptedSecrets.Count; ++i) | ||||
| 				{ | ||||
| 					OtpEncryptedData d = _otpInfo.EncryptedSecrets[i]; | ||||
| 					pbSecret = OtpUtil.DecryptSecret(d, lOtps.ToArray(), 0, | ||||
| 					                                 lOtps.Count); | ||||
| 					if (pbSecret != null) | ||||
| 					{ | ||||
| 						_otpInfo.Secret = pbSecret; | ||||
| 						_otpInfo.Counter += ((ulong) _otpInfo.OtpsRequired + | ||||
| 						                     (ulong) i); | ||||
| 						bSuccess = true; | ||||
| 						break; | ||||
| 					} | ||||
| 				} | ||||
| 				if (!bSuccess) throw new InvalidOperationException(); | ||||
| 			} | ||||
| 		} | ||||
|  | ||||
| 		private void MakePasswordMaskedOrVisible() | ||||
| 		{ | ||||
| @@ -900,7 +876,7 @@ namespace keepass2android | ||||
| 			outState.PutStringArrayList(PendingOtpsKey, _pendingOtps); | ||||
| 			if (_otpInfo != null) | ||||
| 			{ | ||||
| 				outState.PutStringArrayList(EnteredOtpsKey, GetOtpsFromUI()); | ||||
| 				outState.PutStringArrayList(EnteredOtpsKey, GetOtpsFromUi()); | ||||
|  | ||||
| 				var sw = new StringWriter(); | ||||
|  | ||||
| @@ -1117,28 +1093,10 @@ namespace keepass2android | ||||
| 			{ | ||||
| 				_act = act; | ||||
| 			} | ||||
|  | ||||
|  | ||||
| 			public override void Run() { | ||||
|  | ||||
| 				if (_act.KeyProviderType == KeyProviders.Otp) | ||||
| 				{ | ||||
| 					try | ||||
| 					{ | ||||
| 						StatusLogger.UpdateMessage(UiStringKey.SavingOtpAuxFile); | ||||
|  | ||||
| 						if (!OathHotpKeyProv.CreateAuxFile(_act._otpInfo, new KeyProviderQueryContext(_act._ioConnection, false, false))) | ||||
| 							Toast.MakeText(_act, _act.GetString(Resource.String.ErrorUpdatingOtpAuxFile), ToastLength.Long).Show(); | ||||
| 					} | ||||
| 					catch (Exception e) | ||||
| 					{ | ||||
| 						Kp2aLog.Log(e.Message); | ||||
|  | ||||
| 						Toast.MakeText(_act, _act.GetString(Resource.String.ErrorUpdatingOtpAuxFile)+" "+e.Message, ToastLength.Long).Show(); | ||||
| 					} | ||||
| 				} | ||||
| 				 | ||||
|  | ||||
| 			public override void Run() | ||||
| 			{ | ||||
| 				if ( Success )  | ||||
| 				{ | ||||
| 					_act.SetEditText(Resource.Id.password, ""); | ||||
| @@ -1150,8 +1108,6 @@ namespace keepass2android | ||||
|  | ||||
| 					_act.LaunchNextActivity(); | ||||
|  | ||||
| 					if ((_act.KeyProviderType == KeyProviders.Otp) || (_act.KeyProviderType == KeyProviders.OtpRecovery)) | ||||
| 						App.Kp2a.GetDb().OtpAuxFileIoc = OathHotpKeyProv.GetAuxFileIoc(_act._ioConnection); | ||||
|  | ||||
| 					GC.Collect(); // Ensure temporary memory used while loading is collected | ||||
| 				}  | ||||
| @@ -1161,8 +1117,46 @@ namespace keepass2android | ||||
| 				} | ||||
| 			} | ||||
| 		} | ||||
|  | ||||
| 		class SaveOtpAuxFileAndLoadDb : LoadDb | ||||
| 		{ | ||||
| 			private readonly PasswordActivity _act; | ||||
|  | ||||
|  | ||||
| 			public SaveOtpAuxFileAndLoadDb(IKp2aApp app, IOConnectionInfo ioc, Task<MemoryStream> databaseData, CompositeKey compositeKey, string keyfileOrProvider, OnFinish finish, PasswordActivity act) : base(app, ioc, databaseData, compositeKey, keyfileOrProvider, finish) | ||||
| 			{ | ||||
| 				_act = act; | ||||
| 			} | ||||
|  | ||||
| 			public override void Run() | ||||
| 			{ | ||||
| 				try | ||||
| 				{ | ||||
| 					StatusLogger.UpdateMessage(UiStringKey.SavingOtpAuxFile); | ||||
|  | ||||
| 					KeyProviderQueryContext ctx = new KeyProviderQueryContext(_act._ioConnection, false, false); | ||||
| 					IOConnectionInfo auxFileIoc = OathHotpKeyProv.GetAuxFileIoc(_act._ioConnection); | ||||
| 					if (!OathHotpKeyProv.CreateAuxFile(_act._otpInfo, ctx, auxFileIoc)) | ||||
| 						Toast.MakeText(_act, _act.GetString(Resource.String.ErrorUpdatingOtpAuxFile), ToastLength.Long).Show(); | ||||
|  | ||||
| 					App.Kp2a.GetDb().OtpAuxFileIoc = auxFileIoc; | ||||
| 				} | ||||
| 				catch (Exception e) | ||||
| 				{ | ||||
| 					Kp2aLog.Log(e.Message); | ||||
|  | ||||
| 					Toast.MakeText(_act, _act.GetString(Resource.String.ErrorUpdatingOtpAuxFile) + " " + e.Message, | ||||
| 								   ToastLength.Long).Show(); | ||||
| 				} | ||||
|  | ||||
|  | ||||
| 				base.Run(); | ||||
|  | ||||
| 			} | ||||
| 		} | ||||
| 		 | ||||
| 	} | ||||
|  | ||||
| 	 | ||||
| } | ||||
|  | ||||
|   | ||||
							
								
								
									
										6593
									
								
								src/keepass2android/Resources/Resource.designer.cs
									
									
									
										generated
									
									
									
								
							
							
						
						
									
										6593
									
								
								src/keepass2android/Resources/Resource.designer.cs
									
									
									
										generated
									
									
									
								
							
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							| @@ -56,6 +56,7 @@ android:layout_height="match_parent" | ||||
| 			android:id="@+id/password_label" | ||||
| 			android:layout_width="wrap_content" | ||||
| 			android:layout_height="wrap_content" | ||||
| 			android:layout_marginTop="20dip" | ||||
| 			android:text="@string/master_key_type" /> | ||||
| 		<Spinner | ||||
| 		android:id="@+id/password_mode_spinner" | ||||
| @@ -68,6 +69,7 @@ android:layout_height="match_parent" | ||||
| 			android:id="@+id/passwordLine" | ||||
| 			android:layout_width="fill_parent" | ||||
| 			android:layout_height="wrap_content" | ||||
| 			android:baselineAligned="false" | ||||
| 			android:orientation="horizontal"> | ||||
| 			<EditText | ||||
| 				android:id="@+id/password" | ||||
| @@ -76,6 +78,7 @@ android:layout_height="match_parent" | ||||
| 				android:singleLine="true" | ||||
| 				android:inputType="textPassword" | ||||
| 				android:layout_weight="1" | ||||
| 				android:layout_gravity="bottom" | ||||
| 				android:hint="@string/hint_login_pass" /> | ||||
| 			<ImageButton | ||||
| 				android:id="@+id/toggle_password" | ||||
| @@ -87,6 +90,7 @@ android:layout_height="match_parent" | ||||
| 			android:id="@+id/keyfileLine" | ||||
| 			android:layout_width="fill_parent" | ||||
| 			android:layout_height="wrap_content" | ||||
| 			android:baselineAligned="false" | ||||
| 			android:orientation="horizontal"> | ||||
| 			<EditText | ||||
| 				android:id="@+id/pass_keyfile" | ||||
| @@ -94,6 +98,7 @@ android:layout_height="match_parent" | ||||
| 				android:layout_height="wrap_content" | ||||
| 				android:singleLine="true" | ||||
| 				android:layout_weight="1" | ||||
| 				android:layout_gravity="bottom" | ||||
| 				android:hint="@string/entry_keyfile" /> | ||||
| 			<ImageButton | ||||
| 				android:id="@+id/browse_button" | ||||
|   | ||||
| @@ -371,10 +371,13 @@ | ||||
| 	<string name="ChangeLog_title">Change log</string> | ||||
|  | ||||
| 	<string name="ChangeLog_0_9_2"> | ||||
| 		<b>Version 0.9.2a (preview)</b>\n | ||||
| 		<b>Version 0.9.2b (preview)</b>\n | ||||
| 		* Added OTP support (compatible with OtpKeyProv plugin)\n | ||||
| 		* Integrated NFC support for OTPs from YubiKey NEO \n | ||||
| 		* Several UI improvements\n | ||||
| 		* Integrated Keepass 2.24 library\n | ||||
| 		* Added option to kill the app process (see settings)\n | ||||
| 		* Bug fixes\n | ||||
| 	</string> | ||||
|  | ||||
| 	<string name="ChangeLog_0_9_1"> | ||||
|   | ||||
| @@ -137,7 +137,7 @@ namespace OtpKeyProv | ||||
|  | ||||
|  | ||||
| 		public static bool CreateAuxFile(OtpInfo otpInfo, | ||||
| 			KeyProviderQueryContext ctx) | ||||
| 			KeyProviderQueryContext ctx, IOConnectionInfo auxFileIoc) | ||||
| 		{ | ||||
| 			otpInfo.Type = ProvType; | ||||
| 			otpInfo.Version = ProvVersion; | ||||
| @@ -145,15 +145,54 @@ namespace OtpKeyProv | ||||
|  | ||||
| 			otpInfo.EncryptSecret(); | ||||
|  | ||||
| 			IOConnectionInfo ioc = GetAuxFileIoc(ctx); | ||||
| 			if(!OtpInfo.Save(ioc, otpInfo)) | ||||
| 			if(!OtpInfo.Save(auxFileIoc, otpInfo)) | ||||
| 			{ | ||||
| 				MessageService.ShowWarning("Failed to save auxiliary OTP info file:", | ||||
| 					ioc.GetDisplayName()); | ||||
| 					auxFileIoc.GetDisplayName()); | ||||
| 				return false; | ||||
| 			} | ||||
|  | ||||
| 			return true; | ||||
| 		} | ||||
|  | ||||
| 		public static void CreateOtpSecret(List<string> lOtps, OtpInfo otpInfo) | ||||
| 		{ | ||||
| 			 | ||||
| 			byte[] pbSecret; | ||||
| 			if (!string.IsNullOrEmpty(otpInfo.EncryptedSecret)) // < v2.0 | ||||
| 			{ | ||||
| 				byte[] pbKey32 = OtpUtil.KeyFromOtps(lOtps.ToArray(), 0, | ||||
| 				                                     lOtps.Count, Convert.FromBase64String( | ||||
| 					                                     otpInfo.TransformationKey), otpInfo.TransformationRounds); | ||||
| 				if (pbKey32 == null) throw new InvalidOperationException(); | ||||
|  | ||||
| 				pbSecret = OtpUtil.DecryptData(otpInfo.EncryptedSecret, | ||||
| 				                               pbKey32, Convert.FromBase64String(otpInfo.EncryptionIV)); | ||||
| 				if (pbSecret == null) throw new InvalidOperationException(); | ||||
|  | ||||
| 				otpInfo.Secret = pbSecret; | ||||
| 				otpInfo.Counter += otpInfo.OtpsRequired; | ||||
| 			} | ||||
| 			else // >= v2.0, supporting look-ahead | ||||
| 			{ | ||||
| 				bool bSuccess = false; | ||||
| 				for (int i = 0; i < otpInfo.EncryptedSecrets.Count; ++i) | ||||
| 				{ | ||||
| 					OtpEncryptedData d = otpInfo.EncryptedSecrets[i]; | ||||
| 					pbSecret = OtpUtil.DecryptSecret(d, lOtps.ToArray(), 0, | ||||
| 					                                 lOtps.Count); | ||||
| 					if (pbSecret != null) | ||||
| 					{ | ||||
| 						otpInfo.Secret = pbSecret; | ||||
| 						otpInfo.Counter += ((ulong) otpInfo.OtpsRequired + | ||||
| 						                     (ulong) i); | ||||
| 						bSuccess = true; | ||||
| 						break; | ||||
| 					} | ||||
| 				} | ||||
| 				if (!bSuccess) throw new InvalidOperationException(); | ||||
| 			} | ||||
| 		 | ||||
| 		} | ||||
| 	} | ||||
| } | ||||
|   | ||||
| @@ -37,11 +37,14 @@ namespace keepass2android.addons.OtpKeyProv | ||||
| 		{ | ||||
| 			OtpInfo remoteOtpInfo, localOtpInfo; | ||||
| 			//load both files | ||||
| 			XmlSerializer xs = new XmlSerializer(typeof (OtpInfo)); | ||||
| 			localOtpInfo = (OtpInfo) xs.Deserialize(File.OpenRead(cachedFilePath)); | ||||
| 			XmlSerializer xs = new XmlSerializer(typeof(OtpInfo)); | ||||
| 			using (var cacheStream = File.OpenRead(cachedFilePath)) | ||||
| 			{	 | ||||
| 				localOtpInfo = (OtpInfo) xs.Deserialize(cacheStream);	 | ||||
| 			} | ||||
| 			using (Stream remoteStream = _cachedStorage.OpenFileForRead(ioc)) | ||||
| 			{ | ||||
| 				remoteOtpInfo = (OtpInfo) xs.Deserialize(remoteStream); | ||||
| 				remoteOtpInfo = (OtpInfo)xs.Deserialize(remoteStream); | ||||
| 			} | ||||
|  | ||||
| 			//see which OtpInfo has the bigger Counter value and use this one: | ||||
|   | ||||
| @@ -24,7 +24,7 @@ | ||||
|     <DebugType>full</DebugType> | ||||
|     <Optimize>False</Optimize> | ||||
|     <OutputPath>bin\Debug</OutputPath> | ||||
|     <DefineConstants>DEBUG;EXCLUDE_TWOFISH;EXCLUDE_KEYBOARD;EXCLUDE_KEYTRANSFORM;EXCLUDE_FILECHOOSER;EXCLUDE_JAVAFILESTORAGE</DefineConstants> | ||||
|     <DefineConstants>DEBUG;EXCLUDE_TWOFISH;EXCLUDE_KEYBOARD;EXCLUDE_KEYTRANSFORM;INCLUDE_FILECHOOSER;INCLUDE_JAVAFILESTORAGE</DefineConstants> | ||||
|     <ErrorReport>prompt</ErrorReport> | ||||
|     <WarningLevel>4</WarningLevel> | ||||
|     <ConsolePause>False</ConsolePause> | ||||
|   | ||||
		Reference in New Issue
	
	Block a user
	 Philipp Crocoll
					Philipp Crocoll