Beispiel #1
0
        internal static IOConnectionInfo GetAuxFileIoc(IOConnectionInfo iocBase)
        {
            IOConnectionInfo ioc = iocBase.CloneDeep();

            ioc.Path = UrlUtil.StripExtension(ioc.Path) + AuxFileExt;
            return(ioc);
        }
		public KeyProviderQueryContext(IOConnectionInfo ioInfo, bool bCreatingNewKey)
		{
			if(ioInfo == null) throw new ArgumentNullException("ioInfo");

			m_ioInfo = ioInfo.CloneDeep();
			m_bCreatingNewKey = bCreatingNewKey;
		}
		private void Initialize(IOConnectionInfo iocBaseFile, bool bTransacted)
		{
			if(iocBaseFile == null) throw new ArgumentNullException("iocBaseFile");

			m_bTransacted = bTransacted;
			m_iocBase = iocBaseFile.CloneDeep();

			string strPath = m_iocBase.Path;

			// Prevent transactions for FTP URLs under .NET 4.0 in order to
			// avoid/workaround .NET bug 621450:
			// https://connect.microsoft.com/VisualStudio/feedback/details/621450/problem-renaming-file-on-ftp-server-using-ftpwebrequest-in-net-framework-4-0-vs2010-only
			if(strPath.StartsWith("ftp:", StrUtil.CaseIgnoreCmp) &&
				(Environment.Version.Major >= 4) && !NativeLib.IsUnix())
				m_bTransacted = false;
			else
			{
				foreach(KeyValuePair<string, bool> kvp in g_dEnabled)
				{
					if(strPath.StartsWith(kvp.Key, StrUtil.CaseIgnoreCmp))
					{
						m_bTransacted = kvp.Value;
						break;
					}
				}
			}

			if(m_bTransacted)
			{
				m_iocTemp = m_iocBase.CloneDeep();
				m_iocTemp.Path += StrTempSuffix;
			}
			else m_iocTemp = m_iocBase;
		}
		public void InitEx(bool bSave, IOConnectionInfo ioc, bool bCanRememberCred,
			bool bTestConnection)
		{
			m_bSave = bSave;
			if(ioc != null) m_ioc = ioc.CloneDeep();
			m_bCanRememberCred = bCanRememberCred;
			m_bTestConnection = bTestConnection;
		}
Beispiel #5
0
        public void InitEx(bool bSave, IOConnectionInfo ioc, bool bCanRememberCred,
			bool bTestConnection)
        {
            m_bSave = bSave;
            if(ioc != null) m_ioc = ioc.CloneDeep();
            m_bCanRememberCred = bCanRememberCred;
            m_bTestConnection = bTestConnection;
        }
Beispiel #6
0
        public TransactedWrite(IOConnectionInfo ioc, NetFtpFileStorage fileStorage)
        {
            _ioc           = ioc;
            _iocTemp       = _ioc.CloneDeep();
            _iocTemp.Path += "." + new PwUuid(true).ToHexString().Substring(0, 6) + ".tmp";

            _fileStorage = fileStorage;
        }
Beispiel #7
0
        public KeyProviderQueryContext(IOConnectionInfo ioInfo, bool bCreatingNewKey)
        {
            if (ioInfo == null)
            {
                throw new ArgumentNullException("ioInfo");
            }

            m_ioInfo          = ioInfo.CloneDeep();
            m_bCreatingNewKey = bCreatingNewKey;
        }
		private void Initialize(IOConnectionInfo iocBaseFile, bool bTransacted)
		{
			if(iocBaseFile == null) throw new ArgumentNullException("iocBaseFile");

			m_bTransacted = bTransacted;
			m_iocBase = iocBaseFile.CloneDeep();

			string strPath = m_iocBase.Path;

			if(m_iocBase.IsLocalFile())
			{
				try
				{
					if(File.Exists(strPath))
					{
						// Symbolic links are realized via reparse points;
						// https://msdn.microsoft.com/en-us/library/windows/desktop/aa365503.aspx
						// https://msdn.microsoft.com/en-us/library/windows/desktop/aa365680.aspx
						// https://msdn.microsoft.com/en-us/library/windows/desktop/aa365006.aspx
						// Performing a file transaction on a symbolic link
						// would delete/replace the symbolic link instead of
						// writing to its target
						FileAttributes fa = File.GetAttributes(strPath);
						if((long)(fa & FileAttributes.ReparsePoint) != 0)
							m_bTransacted = false;
					}
				}
				catch(Exception) { Debug.Assert(false); }
			}

#if !KeePassUAP
			// Prevent transactions for FTP URLs under .NET 4.0 in order to
			// avoid/workaround .NET bug 621450:
			// https://connect.microsoft.com/VisualStudio/feedback/details/621450/problem-renaming-file-on-ftp-server-using-ftpwebrequest-in-net-framework-4-0-vs2010-only
			if(strPath.StartsWith("ftp:", StrUtil.CaseIgnoreCmp) &&
				(Environment.Version.Major >= 4) && !NativeLib.IsUnix())
				m_bTransacted = false;
#endif

			foreach(KeyValuePair<string, bool> kvp in g_dEnabled)
			{
				if(strPath.StartsWith(kvp.Key, StrUtil.CaseIgnoreCmp))
				{
					m_bTransacted = kvp.Value;
					break;
				}
			}

			if(m_bTransacted)
			{
				m_iocTemp = m_iocBase.CloneDeep();
				m_iocTemp.Path += StrTempSuffix;
			}
			else m_iocTemp = m_iocBase;
		}
        private IOConnectionInfo GetPseudoIoc(IOConnectionInfo folderPath, string filename)
        {
            IOConnectionInfo res = folderPath.CloneDeep();

            if (!res.Path.EndsWith("/"))
            {
                res.Path += "/";
            }
            res.Path += filename;
            return(res);
        }
        /// <summary>
        /// Get a key for an existing database.  First, the key file is located, either because its location
        /// and filename are the same as the database path (with the exception of the extension), or the user
        /// is asked.  Then, the key file is decrypted using a private key.
        /// </summary>
        /// <param name="strPath">Full filename of the database file.</param>
        /// <returns>A byte array with the key, or null if an error occurs.  If an error occurs, user is
        /// notified of the error.</returns>
        byte[] GetExistingKey(IOConnectionInfo ioc)
        {
            Stream stream = null;

            try
            {
                string           newpath = UrlUtil.StripExtension(ioc.Path) + "." + CertProtKeyFileExtension;
                IOConnectionInfo keyIoc  = ioc.CloneDeep();
                keyIoc.Path = newpath;
                stream      = IOConnection.OpenRead(keyIoc);
            }
            catch (Exception e)
            {
                // strPath may be a URL (even if IsLocalFile returns true?),
                // whatever the reason, fall through and the user can pick a
                // local file as the key file
            }

            if (stream == null || !stream.CanRead)
            {
                // fall back on opening a local file
                // FUTURE ENHANCEMENT: allow user to enter a URL and name/pwd as well

                OpenFileDialog ofd = UIUtil.CreateOpenFileDialog("KeePassX509Provider", UIUtil.CreateFileTypeFilter(CertProtKeyFileExtension, "x05KeyFile", true), 1, CertProtKeyFileExtension, false /* multi-select */, true);

                if (ofd.ShowDialog() != DialogResult.OK)
                {
                    return(null);
                }
                stream = IOConnection.OpenRead(IOConnectionInfo.FromPath(ofd.FileName));
            }
            try
            {
                BinaryReader reader = new BinaryReader(stream);
                byte[]       p7m    = reader.ReadBytes(MAX_KEY_FILE_LENGTH);
                // URL streams don't support seeking, and so Position doesn't work
                //bool tooBig = stream.Position >= MAX_KEY_FILE_LENGTH;
                bool tooBig = p7m.Length >= MAX_KEY_FILE_LENGTH;
                reader.Close();

                if (tooBig)
                {
                    MessageBox.Show("Kes File ist to big");
                    return(null);
                }
                Certmanager cert_mgr = new Certmanager();
                return(cert_mgr.DecryptMsg(p7m));
            }
            catch (SystemException ex)  // covers IOException and CryptographicException
            {
                MessageBox.Show("Error at encryption or IO error!\nIf you used a smart card for encryption, please provide/plugin fist!");
                return(null);
            }
        }
Beispiel #11
0
        public IOConnectionInfo GetFilePath(IOConnectionInfo folderPath, string filename)
        {
            IOConnectionInfo res = folderPath.CloneDeep();

            if (!res.Path.EndsWith("/"))
            {
                res.Path += "/";
            }
            res.Path += filename;
            return(res);
        }
        private bool TryGetCachedFilePath(IOConnectionInfo folderPath, string filename, out IOConnectionInfo res)
        {
            res = folderPath.CloneDeep();
            string filePathCache = CachedFilePath(GetPseudoIoc(folderPath, filename)) + ".filepath";

            if (!File.Exists(filePathCache))
            {
                return(false);
            }
            res.Path = File.ReadAllText(filePathCache);
            return(true);
        }
		private void Initialize(IOConnectionInfo iocBaseFile, bool bTransacted)
		{
			if(iocBaseFile == null) throw new ArgumentNullException("iocBaseFile");

			m_bTransacted = bTransacted;
			m_iocBase = iocBaseFile.CloneDeep();

			if(m_bTransacted)
			{
				m_iocTemp = m_iocBase.CloneDeep();
				m_iocTemp.Path += StrTempSuffix;
			}
			else m_iocTemp = m_iocBase;
		}
Beispiel #14
0
        public static IOConnectionInfo GetParentPath(IOConnectionInfo ioc)
        {
            var iocParent = ioc.CloneDeep();
            if (iocParent.Path.EndsWith("/"))
                iocParent.Path = iocParent.Path.Substring(0, iocParent.Path.Length - 1);

            int slashPos = iocParent.Path.LastIndexOf("/", StringComparison.Ordinal);
            if (slashPos == -1)
                iocParent.Path = "";
            else
            {
                iocParent.Path = iocParent.Path.Substring(0, slashPos);
            }
            return iocParent;
        }
Beispiel #15
0
        public FileLock(IOConnectionInfo iocBaseFile)
        {
            if(iocBaseFile == null) throw new ArgumentNullException("strBaseFile");

            m_iocLockFile = iocBaseFile.CloneDeep();
            m_iocLockFile.Path += LockFileExt;

            LockFileInfo lfiEx = LockFileInfo.Load(m_iocLockFile);
            if(lfiEx != null)
            {
                m_iocLockFile = null; // Otherwise Dispose deletes the existing one
                throw new FileLockException(iocBaseFile.GetDisplayName(),
                    lfiEx.GetOwner());
            }

            LockFileInfo.Create(m_iocLockFile);
        }
        private static IOConnectionInfo IOFromParameters(string strPath,
                                                         string strUser, string strPassword)
        {
            IOConnectionInfo iocBase = IOConnectionInfo.FromPath(strPath);

            if (!string.IsNullOrEmpty(strUser))
            {
                iocBase.UserName = strUser;
            }
            if (!string.IsNullOrEmpty(strPassword))
            {
                iocBase.Password = strPassword;
            }

            if (!string.IsNullOrEmpty(iocBase.UserName))
            {
                iocBase.CredSaveMode = IOCredSaveMode.UserNameOnly;
            }
            if (!string.IsNullOrEmpty(iocBase.Password))
            {
                iocBase.CredSaveMode = IOCredSaveMode.SaveCred;
            }

            if (string.IsNullOrEmpty(iocBase.UserName) && string.IsNullOrEmpty(iocBase.Password))
            {
                MruList mru = Program.MainForm.FileMruList;
                for (uint u = 0; u < mru.ItemCount; ++u)
                {
                    IOConnectionInfo iocMru = (mru.GetItem(u).Value as IOConnectionInfo);
                    if (iocMru == null)
                    {
                        Debug.Assert(false); continue;
                    }

                    if (iocMru.Path == iocBase.Path)
                    {
                        iocBase = iocMru.CloneDeep();
                        break;
                    }
                }
            }

            return(MainForm.CompleteConnectionInfo(iocBase, false, true, true, false));
        }
Beispiel #17
0
        public static IOConnectionInfo GetParentPath(IOConnectionInfo ioc)
        {
            var iocParent = ioc.CloneDeep();

            if (iocParent.Path.EndsWith("/"))
            {
                iocParent.Path = iocParent.Path.Substring(0, iocParent.Path.Length - 1);
            }

            int slashPos = iocParent.Path.LastIndexOf("/", StringComparison.Ordinal);

            if (slashPos == -1)
            {
                iocParent.Path = "";
            }
            else
            {
                iocParent.Path = iocParent.Path.Substring(0, slashPos);
            }
            return(iocParent);
        }
Beispiel #18
0
        private static void SetLastUsedFile(IOConnectionInfo ioc)
        {
            if (ioc == null)
            {
                Debug.Assert(false); return;
            }

            AceApplication aceApp = Program.Config.Application;

            if (aceApp.Start.OpenLastFile)
            {
                if (!string.IsNullOrEmpty(ioc.Path))
                {
                    aceApp.LastUsedFile = ioc.CloneDeep();
                }
            }
            else
            {
                aceApp.LastUsedFile = new IOConnectionInfo();
            }
        }
		/// <summary>
		/// Open a database. This function opens the specified database and updates
		/// the user interface.
		/// </summary>
		public void OpenDatabase(IOConnectionInfo ioConnection, CompositeKey cmpKey,
			bool bOpenLocal)
		{
			if(!m_bFormLoaded && Program.Config.Application.Start.MinimizedAndLocked &&
				(ioConnection != null) && (ioConnection.Path.Length > 0))
			{
				PwDocument ds = m_docMgr.CreateNewDocument(true);
				ds.LockedIoc = ioConnection.CloneDeep();
				UpdateUI(true, ds, true, null, true, null, false);
				return;
			}

			SaveWindowState(); // KPF 1093

			IOConnectionInfo ioc;
			if(ioConnection == null)
			{
				if(bOpenLocal)
				{
					OpenFileDialogEx ofdDb = UIUtil.CreateOpenFileDialog(KPRes.OpenDatabaseFile,
						UIUtil.CreateFileTypeFilter(AppDefs.FileExtension.FileExt,
						KPRes.KdbxFiles, true), 1, null, false,
						AppDefs.FileDialogContext.Database);

					GlobalWindowManager.AddDialog(ofdDb.FileDialog);
					DialogResult dr = ofdDb.ShowDialog();
					GlobalWindowManager.RemoveDialog(ofdDb.FileDialog);
					if(dr != DialogResult.OK) return;

					ioc = IOConnectionInfo.FromPath(ofdDb.FileName);
				}
				else
				{
					ioc = CompleteConnectionInfo(new IOConnectionInfo(), false,
						true, true, true);
					if(ioc == null) return;
				}
			}
			else // ioConnection != null
			{
				ioc = CompleteConnectionInfo(ioConnection, false, true, true, false);
				if(ioc == null) return;
			}

			if(!ioc.CanProbablyAccess())
			{
				MessageService.ShowWarning(ioc.GetDisplayName(), KPRes.FileNotFoundError);
				return;
			}

			if(OpenDatabaseRestoreIfOpened(ioc)) return;

			PwDatabase pwOpenedDb = null;
			bool bAbort;
			if(cmpKey == null)
			{
				for(int iTry = 0; iTry < 3; ++iTry)
				{
					OdKpfConstructParams kpfParams = new OdKpfConstructParams();
					kpfParams.IOConnectionInfo = ioc;
					kpfParams.CanExit = IsFileLocked(null);

					DialogResult dr;
					OdKpfResult kpfResult;

					if(Program.Config.Security.MasterKeyOnSecureDesktop &&
						WinUtil.IsAtLeastWindows2000 &&
						!KeePassLib.Native.NativeLib.IsUnix())
					{
						kpfParams.SecureDesktopMode = true;

						ProtectedDialog dlg = new ProtectedDialog(OdKpfConstruct,
							OdKpfBuildResult);
						object objResult;
						dr = dlg.ShowDialog(out objResult, kpfParams);
						if(dr == DialogResult.None) { Debug.Assert(false); dr = DialogResult.Cancel; }
						
						kpfResult = (objResult as OdKpfResult);
						if(kpfResult == null) { Debug.Assert(false); continue; }

						if(kpfResult.ShowHelpAfterClose)
							AppHelp.ShowHelp(AppDefs.HelpTopics.KeySources, null);
					}
					else // Show dialog on normal desktop
					{
						Form dlg = OdKpfConstruct(kpfParams);
						dr = dlg.ShowDialog();

						kpfResult = (OdKpfBuildResult(dlg) as OdKpfResult);
						UIUtil.DestroyForm(dlg);
						if(kpfResult == null) { Debug.Assert(false); continue; }
					}

					if(dr == DialogResult.Cancel) break;
					else if(kpfResult.HasClosedWithExit)
					{
						Debug.Assert(dr == DialogResult.Abort);
						OnFileExit(null, null);
						return;
					}

					pwOpenedDb = OpenDatabaseInternal(ioc, kpfResult.Key,
						out bAbort);
					if((pwOpenedDb != null) || bAbort) break;
				}
			}
			else // cmpKey != null
			{
				pwOpenedDb = OpenDatabaseInternal(ioc, cmpKey, out bAbort);
			}

			if((pwOpenedDb == null) || !pwOpenedDb.IsOpen)
			{
				UpdateUIState(false); // Reset status bar text
				return;
			}

			string strName = pwOpenedDb.IOConnectionInfo.GetDisplayName();
			m_mruList.AddItem(strName, pwOpenedDb.IOConnectionInfo.CloneDeep());

			PwDocument dsExisting = m_docMgr.FindDocument(pwOpenedDb);
			if(dsExisting != null) m_docMgr.ActiveDocument = dsExisting;

			bool bCorrectDbActive = (m_docMgr.ActiveDocument.Database == pwOpenedDb);
			Debug.Assert(bCorrectDbActive);

			// AutoEnableVisualHiding();

			// SetLastUsedFile(pwOpenedDb.IOConnectionInfo);
			RememberKeySources(pwOpenedDb);

			PwGroup pgRestoreSelect = null;
			if(bCorrectDbActive)
			{
				m_docMgr.ActiveDocument.LockedIoc = new IOConnectionInfo(); // Clear

				pgRestoreSelect = pwOpenedDb.RootGroup.FindGroup(
					pwOpenedDb.LastSelectedGroup, true);
			}

			UpdateUI(true, null, true, pgRestoreSelect, true, null, false);
			if(bCorrectDbActive)
			{
				SetTopVisibleGroup(pwOpenedDb.LastTopVisibleGroup);
				if(pgRestoreSelect != null)
					SetTopVisibleEntry(pgRestoreSelect.LastTopVisibleEntry);
			}
			UpdateColumnSortingIcons();

			if((pwOpenedDb.MasterKeyChangeForce >= 0) &&
				((DateTime.Now - pwOpenedDb.MasterKeyChanged).Days >=
				pwOpenedDb.MasterKeyChangeForce))
			{
				while(true)
				{
					MessageService.ShowInfo(pwOpenedDb.IOConnectionInfo.GetDisplayName() +
						MessageService.NewParagraph + KPRes.MasterKeyChangeForce +
						MessageService.NewParagraph + KPRes.MasterKeyChangeInfo);
					if(ChangeMasterKey(pwOpenedDb))
					{
						UpdateUIState(true);
						break;
					}
					if(!AppPolicy.Current.ChangeMasterKey) break; // Prevent endless loop
				}
			}
			else if((pwOpenedDb.MasterKeyChangeRec >= 0) &&
				((DateTime.Now - pwOpenedDb.MasterKeyChanged).Days >=
				pwOpenedDb.MasterKeyChangeRec))
			{
				if(MessageService.AskYesNo(pwOpenedDb.IOConnectionInfo.GetDisplayName() +
					MessageService.NewParagraph + KPRes.MasterKeyChangeRec +
					MessageService.NewParagraph + KPRes.MasterKeyChangeQ))
					UpdateUIState(ChangeMasterKey(pwOpenedDb));
			}

			if(FixDuplicateUuids(pwOpenedDb, pwOpenedDb.IOConnectionInfo))
				UpdateUIState(false); // Already marked as modified

			if(this.FileOpened != null)
			{
				FileOpenedEventArgs ea = new FileOpenedEventArgs(pwOpenedDb);
				this.FileOpened(this, ea);
			}
			Program.TriggerSystem.RaiseEvent(EcasEventIDs.OpenedDatabaseFile,
				EcasProperty.Database, pwOpenedDb);

			if(bCorrectDbActive && pwOpenedDb.IsOpen)
			{
				ShowExpiredEntries(true,
					Program.Config.Application.FileOpening.ShowExpiredEntries,
					Program.Config.Application.FileOpening.ShowSoonToExpireEntries);

				// Avoid view being destroyed by the unlocking routine
				pwOpenedDb.LastSelectedGroup = PwUuid.Zero;
			}

			if(Program.Config.MainWindow.MinimizeAfterOpeningDatabase)
				UIUtil.SetWindowState(this, FormWindowState.Minimized);

			ResetDefaultFocus(null);
		}
		internal static IOConnectionInfo CompleteConnectionInfo(IOConnectionInfo ioc,
			bool bSave, bool bCanRememberCred, bool bTestConnection, bool bForceShow)
		{
			if(ioc == null) { Debug.Assert(false); return null; }
			if(!bForceShow && ((ioc.CredSaveMode == IOCredSaveMode.SaveCred) ||
				ioc.IsLocalFile() || ioc.IsComplete))
				return ioc.CloneDeep();

			IOConnectionForm dlg = new IOConnectionForm();
			dlg.InitEx(bSave, ioc.CloneDeep(), bCanRememberCred, bTestConnection);
			if(UIUtil.ShowDialogNotValue(dlg, DialogResult.OK)) return null;

			IOConnectionInfo iocResult = dlg.IOConnectionInfo;
			UIUtil.DestroyForm(dlg);
			return iocResult;
		}
		/// <summary>
		/// Open a database. This function opens the specified database and updates
		/// the user interface.
		/// </summary>
		public void OpenDatabase(IOConnectionInfo ioConnection, CompositeKey cmpKey,
			bool bOpenLocal)
		{
			// OnFileClose(null, null);
			// if(m_docMgr.ActiveDatabase.IsOpen) return;

			if(m_bFormLoading && Program.Config.Application.Start.MinimizedAndLocked &&
				(ioConnection != null) && (ioConnection.Path.Length > 0))
			{
				PwDocument ds = m_docMgr.CreateNewDocument(true);
				ds.LockedIoc = ioConnection.CloneDeep();
				UpdateUI(true, ds, true, null, true, null, false);
				return;
			}

			IOConnectionInfo ioc;
			if(ioConnection == null)
			{
				if(bOpenLocal)
				{
					OpenFileDialog ofdDb = UIUtil.CreateOpenFileDialog(KPRes.OpenDatabaseFile,
						UIUtil.CreateFileTypeFilter(AppDefs.FileExtension.FileExt,
						KPRes.KdbxFiles, true), 1, null, false, false);

					GlobalWindowManager.AddDialog(ofdDb);
					DialogResult dr = ofdDb.ShowDialog();
					GlobalWindowManager.RemoveDialog(ofdDb);
					if(dr != DialogResult.OK) return;

					ioc = IOConnectionInfo.FromPath(ofdDb.FileName);
				}
				else
				{
					ioc = CompleteConnectionInfo(new IOConnectionInfo(), false,
						true, true, true);
					if(ioc == null) return;
				}
			}
			else // ioConnection != null
			{
				ioc = CompleteConnectionInfo(ioConnection, false, true, true, false);
				if(ioc == null) return;
			}

			if(!ioc.CanProbablyAccess())
			{
				MessageService.ShowWarning(ioc.GetDisplayName(), KPRes.FileNotFoundError);
				return;
			}

			if(OpenDatabaseRestoreIfOpened(ioc)) return;

			PwDatabase pwOpenedDb = null;
			if(cmpKey == null)
			{
				for(int iTry = 0; iTry < 3; ++iTry)
				{
					KeyPromptForm kpf = new KeyPromptForm();
					kpf.InitEx(ioc, IsFileLocked(null), true);

					DialogResult dr = kpf.ShowDialog();
					if(dr == DialogResult.Cancel) break;
					else if(kpf.HasClosedWithExit)
					{
						Debug.Assert(dr == DialogResult.Abort);
						OnFileExit(null, null);
						return;
					}

					pwOpenedDb = OpenDatabaseInternal(ioc, kpf.CompositeKey);
					if(pwOpenedDb != null) break;
				}
			}
			else // cmpKey != null
			{
				pwOpenedDb = OpenDatabaseInternal(ioc, cmpKey);
			}

			if((pwOpenedDb == null) || !pwOpenedDb.IsOpen) return;

			string strName = pwOpenedDb.IOConnectionInfo.GetDisplayName();
			m_mruList.AddItem(strName, pwOpenedDb.IOConnectionInfo.CloneDeep(), true);

			PwDocument dsExisting = m_docMgr.FindDocument(pwOpenedDb);
			if(dsExisting != null) m_docMgr.ActiveDocument = dsExisting;

			bool bCorrectDbActive = (m_docMgr.ActiveDocument.Database == pwOpenedDb);
			Debug.Assert(bCorrectDbActive);

			// AutoEnableVisualHiding();

			SetLastUsedFile(pwOpenedDb.IOConnectionInfo);
			RememberKeyFilePath(pwOpenedDb);

			PwGroup pgRestoreSelect = null;
			if(bCorrectDbActive)
			{
				m_docMgr.ActiveDocument.LockedIoc = new IOConnectionInfo(); // Clear

				pgRestoreSelect = pwOpenedDb.RootGroup.FindGroup(
					pwOpenedDb.LastSelectedGroup, true);
			}

			UpdateUI(true, null, true, pgRestoreSelect, true, null, false);
			if(bCorrectDbActive)
			{
				SetTopVisibleGroup(pwOpenedDb.LastTopVisibleGroup);
				if(pgRestoreSelect != null)
					SetTopVisibleEntry(pgRestoreSelect.LastTopVisibleEntry);
			}
			UpdateColumnSortingIcons();

			if((pwOpenedDb.MasterKeyChangeForce >= 0) &&
				((DateTime.Now - pwOpenedDb.MasterKeyChanged).Days >=
				pwOpenedDb.MasterKeyChangeForce))
			{
				do
				{
					MessageService.ShowInfo(pwOpenedDb.IOConnectionInfo.GetDisplayName() +
						MessageService.NewParagraph + KPRes.MasterKeyChangeForce +
						MessageService.NewParagraph + KPRes.MasterKeyChangeInfo);
				}
				while(!ChangeMasterKey(pwOpenedDb));

				UpdateUIState(true);
			}
			else if((pwOpenedDb.MasterKeyChangeRec >= 0) &&
				((DateTime.Now - pwOpenedDb.MasterKeyChanged).Days >=
				pwOpenedDb.MasterKeyChangeRec))
			{
				if(MessageService.AskYesNo(pwOpenedDb.IOConnectionInfo.GetDisplayName() +
					MessageService.NewParagraph + KPRes.MasterKeyChangeRec +
					MessageService.NewParagraph + KPRes.MasterKeyChangeQ))
					UpdateUIState(ChangeMasterKey(pwOpenedDb));
			}

			if(this.FileOpened != null)
			{
				FileOpenedEventArgs ea = new FileOpenedEventArgs(pwOpenedDb);
				this.FileOpened(this, ea);
			}
			Program.TriggerSystem.RaiseEvent(EcasEventIDs.OpenedDatabaseFile,
				pwOpenedDb.IOConnectionInfo.Path);

			if(bCorrectDbActive && pwOpenedDb.IsOpen &&
				Program.Config.Application.FileOpening.ShowSoonToExpireEntries)
			{
				ShowExpiredEntries(true, 7);

				// Avoid view being destroyed by the unlocking routine
				pwOpenedDb.LastSelectedGroup = PwUuid.Zero;
			}
			else if(bCorrectDbActive && pwOpenedDb.IsOpen &&
				Program.Config.Application.FileOpening.ShowExpiredEntries)
			{
				ShowExpiredEntries(true, 0);

				// Avoid view being destroyed by the unlocking routine
				pwOpenedDb.LastSelectedGroup = PwUuid.Zero;
			}

			if(Program.Config.MainWindow.MinimizeAfterOpeningDatabase)
				this.WindowState = FormWindowState.Minimized;

			ResetDefaultFocus(null);
		}
Beispiel #22
0
        private static void RaiseIOAccessPreEvent(IOConnectionInfo ioc,
			IOConnectionInfo ioc2, IOAccessType t)
        {
            if(ioc == null) { Debug.Assert(false); return; }
            // ioc2 may be null

            if(IOConnection.IOAccessPre != null)
            {
                IOConnectionInfo ioc2Lcl = ((ioc2 != null) ? ioc2.CloneDeep() : null);
                IOAccessEventArgs e = new IOAccessEventArgs(ioc.CloneDeep(), ioc2Lcl, t);
                IOConnection.IOAccessPre(null, e);
            }
        }
Beispiel #23
0
        private void Initialize(IOConnectionInfo iocBaseFile, bool bTransacted)
        {
            if(iocBaseFile == null) throw new ArgumentNullException("iocBaseFile");

            m_bTransacted = bTransacted;
            m_iocBase = iocBaseFile.CloneDeep();

            // Prevent transactions for FTP URLs under .NET 4.0 in order to
            // avoid/workaround .NET bug 621450:
            // https://connect.microsoft.com/VisualStudio/feedback/details/621450/problem-renaming-file-on-ftp-server-using-ftpwebrequest-in-net-framework-4-0-vs2010-only
            if(m_iocBase.Path.StartsWith("ftp:", StrUtil.CaseIgnoreCmp) &&
                (Environment.Version.Major >= 4) && !NativeLib.IsUnix())
                m_bTransacted = false;

            if(m_bTransacted)
            {
                m_iocTemp = m_iocBase.CloneDeep();
                m_iocTemp.Path += "."+new PwUuid(true).ToHexString().Substring(0,6)+ StrTempSuffix;
            }
            else m_iocTemp = m_iocBase;
        }
Beispiel #24
0
		private static void SetLastUsedFile(IOConnectionInfo ioc)
		{
			if(ioc == null) { Debug.Assert(false); return; }

			AceApplication aceApp = Program.Config.Application;
			if(aceApp.Start.OpenLastFile)
			{
				if(!string.IsNullOrEmpty(ioc.Path))
					aceApp.LastUsedFile = ioc.CloneDeep();
			}
			else aceApp.LastUsedFile = new IOConnectionInfo();
		}
Beispiel #25
0
 public IOConnectionInfo GetFilePath(IOConnectionInfo folderPath, string filename)
 {
     IOConnectionInfo res = folderPath.CloneDeep();
     if (!res.Path.EndsWith("/"))
         res.Path += "/";
     res.Path += filename;
     return res;
 }
        private void PostSavingEx(bool bPrimary, PwDatabase pwDatabase, IOConnectionInfo ioc)
        {
            if(ioc == null) { Debug.Assert(false); return; }

            byte[] pbIO = WinUtil.HashFile(ioc);
            Debug.Assert((pbIO != null) && (pwDatabase.HashOfLastIO != null));
            if(pwDatabase.HashOfLastIO != null)
            {
                if(!MemUtil.ArraysEqual(pbIO, pwDatabase.HashOfLastIO))
                {
                    MessageService.ShowWarning(ioc.GetDisplayName(), KPRes.FileVerifyHashFail,
                        KPRes.FileVerifyHashFailRec);
                }
            }

            if(bPrimary)
            {
            #if DEBUG
                Debug.Assert(MemUtil.ArraysEqual(pbIO, pwDatabase.HashOfFileOnDisk));

                try
                {
                    PwDatabase pwCheck = new PwDatabase();
                    pwCheck.Open(ioc.CloneDeep(), pwDatabase.MasterKey, null);

                    Debug.Assert(MemUtil.ArraysEqual(pwDatabase.HashOfLastIO,
                        pwCheck.HashOfLastIO));

                    uint uGroups1, uGroups2, uEntries1, uEntries2;
                    pwDatabase.RootGroup.GetCounts(true, out uGroups1, out uEntries1);
                    pwCheck.RootGroup.GetCounts(true, out uGroups2, out uEntries2);
                    Debug.Assert((uGroups1 == uGroups2) && (uEntries1 == uEntries2));
                }
                catch(Exception exVerify) { Debug.Assert(false, exVerify.Message); }
            #endif

                m_mruList.AddItem(ioc.GetDisplayName(), ioc.CloneDeep());

                Program.Config.Application.LastUsedFile = ioc.CloneDeep();
            }

            WinUtil.FlushStorageBuffers(ioc.Path, true);
        }
        /// <summary>
        /// Open a database. This function opens the specified database and updates
        /// the user interface.
        /// </summary>
        public void OpenDatabase(IOConnectionInfo ioConnection, CompositeKey cmpKey,
            bool bOpenLocal)
        {
            // OnFileClose(null, null);
            // if(m_docMgr.ActiveDatabase.IsOpen) return;

            if(m_bFormLoading && Program.Config.Application.Start.MinimizedAndLocked &&
                (ioConnection != null) && (ioConnection.Path.Length > 0))
            {
                DocumentStateEx ds = m_docMgr.CreateNewDocument(true);
                ds.LockedIoc = ioConnection.CloneDeep();
                UpdateUI(true, ds, true, null, true, null, false);
                return;
            }

            IOConnectionInfo ioc;
            if(ioConnection == null)
            {
                if(bOpenLocal)
                {
                    OpenFileDialog ofdDb = UIUtil.CreateOpenFileDialog(KPRes.OpenDatabaseFile,
                        UIUtil.CreateFileTypeFilter("kdbx", KPRes.KdbxFiles, true), 1,
                        null, false, false);

                    GlobalWindowManager.AddDialog(ofdDb);
                    DialogResult dr = ofdDb.ShowDialog();
                    GlobalWindowManager.RemoveDialog(ofdDb);
                    if(dr != DialogResult.OK) return;

                    ioc = IOConnectionInfo.FromPath(ofdDb.FileName);
                }
                else
                {
                    IOConnectionForm iocf = new IOConnectionForm();
                    iocf.InitEx(false, new IOConnectionInfo(), true, true);
                    if(iocf.ShowDialog() != DialogResult.OK) return;

                    ioc = iocf.IOConnectionInfo;
                }
            }
            else // ioConnection != null
            {
                ioc = ioConnection.CloneDeep();

                if((ioc.CredSaveMode != IOCredSaveMode.SaveCred) &&
                    (!ioc.IsLocalFile()))
                {
                    IOConnectionForm iocf = new IOConnectionForm();
                    iocf.InitEx(false, ioc.CloneDeep(), true, true);
                    if(iocf.ShowDialog() != DialogResult.OK) return;

                    ioc = iocf.IOConnectionInfo;
                }
            }

            if((ioc == null) || !ioc.CanProbablyAccess())
            {
                MessageService.ShowWarning(ioc.GetDisplayName(), KPRes.FileNotFoundError);
                return;
            }

            if(OpenDatabaseRestoreIfOpened(ioc)) return;

            PwDatabase pwOpenedDb = null;
            if(cmpKey == null)
            {
                for(int iTry = 0; iTry < 3; ++iTry)
                {
                    KeyPromptForm kpf = new KeyPromptForm();
                    kpf.InitEx(ioc.GetDisplayName(), IsFileLocked(null));

                    DialogResult dr = kpf.ShowDialog();
                    if(dr == DialogResult.Cancel) break;
                    else if(kpf.HasClosedWithExit)
                    {
                        Debug.Assert(dr == DialogResult.Abort);
                        OnFileExit(null, null);
                        return;
                    }

                    pwOpenedDb = OpenDatabaseInternal(ioc, kpf.CompositeKey);
                    if(pwOpenedDb != null) break;
                }
            }
            else // cmpKey != null
            {
                pwOpenedDb = OpenDatabaseInternal(ioc, cmpKey);
            }

            if((pwOpenedDb == null) || !pwOpenedDb.IsOpen) return;

            string strName = pwOpenedDb.IOConnectionInfo.GetDisplayName();
            m_mruList.AddItem(strName, pwOpenedDb.IOConnectionInfo.CloneDeep());

            DocumentStateEx dsExisting = m_docMgr.FindDocument(pwOpenedDb);
            if(dsExisting != null) m_docMgr.ActiveDocument = dsExisting;

            bool bCorrectDbActive = (m_docMgr.ActiveDocument.Database == pwOpenedDb);
            Debug.Assert(bCorrectDbActive);

            AutoEnableVisualHiding();

            if(Program.Config.Application.Start.OpenLastFile)
                Program.Config.Application.LastUsedFile =
                    pwOpenedDb.IOConnectionInfo.CloneDeep();
            else
                Program.Config.Application.LastUsedFile = new IOConnectionInfo();

            if(bCorrectDbActive)
                m_docMgr.ActiveDocument.LockedIoc = new IOConnectionInfo(); // Clear

            if(this.FileOpened != null)
            {
                FileOpenedEventArgs ea = new FileOpenedEventArgs(pwOpenedDb);
                this.FileOpened(this, ea);
            }

            UpdateUI(true, null, true, null, true, null, false);
            UpdateColumnSortingIcons();

            if(bCorrectDbActive && pwOpenedDb.IsOpen &&
                Program.Config.Application.FileOpening.ShowSoonToExpireEntries)
            {
                ShowExpiredEntries(true, 7);

                // Avoid view being destroyed by the unlocking routine
                pwOpenedDb.LastSelectedGroup = PwUuid.Zero;
            }
            else if(bCorrectDbActive && pwOpenedDb.IsOpen &&
                Program.Config.Application.FileOpening.ShowExpiredEntries)
            {
                ShowExpiredEntries(true, 0);

                // Avoid view being destroyed by the unlocking routine
                pwOpenedDb.LastSelectedGroup = PwUuid.Zero;
            }

            ResetDefaultFocus(null);
        }
Beispiel #28
0
 private bool TryGetCachedFilePath(IOConnectionInfo folderPath, string filename, out IOConnectionInfo res)
 {
     res = folderPath.CloneDeep();
     string filePathCache = CachedFilePath(GetPseudoIoc(folderPath, filename)) + ".filepath";
     if (!File.Exists(filePathCache))
         return false;
     res.Path = File.ReadAllText(filePathCache);
     return true;
 }
Beispiel #29
0
 private IOConnectionInfo GetPseudoIoc(IOConnectionInfo folderPath, string filename)
 {
     IOConnectionInfo res = folderPath.CloneDeep();
     if (!res.Path.EndsWith("/"))
         res.Path += "/";
     res.Path += filename;
     return res;
 }
		private PwDatabase OpenDatabaseInternal(IOConnectionInfo ioc,
			CompositeKey cmpKey, out bool bAbort)
		{
			bAbort = false;

			PerformSelfTest();

			ShowWarningsLogger swLogger = CreateShowWarningsLogger();
			swLogger.StartLogging(KPRes.OpeningDatabase, true);

			PwDocument ds = null;
			string strPathNrm = ioc.Path.Trim().ToLower();
			for(int iScan = 0; iScan < m_docMgr.Documents.Count; ++iScan)
			{
				if(m_docMgr.Documents[iScan].LockedIoc.Path.Trim().ToLower() == strPathNrm)
					ds = m_docMgr.Documents[iScan];
				else if(m_docMgr.Documents[iScan].Database.IOConnectionInfo.Path == strPathNrm)
					ds = m_docMgr.Documents[iScan];
			}

			PwDatabase pwDb;
			if(ds == null) pwDb = m_docMgr.CreateNewDocument(true).Database;
			else pwDb = ds.Database;

			Exception ex = null;
			try
			{
				pwDb.Open(ioc, cmpKey, swLogger);

#if DEBUG
				byte[] pbDiskDirect = WinUtil.HashFile(ioc);
				Debug.Assert(MemUtil.ArraysEqual(pbDiskDirect, pwDb.HashOfFileOnDisk));
#endif
			}
			catch(Exception exLoad)
			{
				ex = exLoad;
				pwDb = null;
			}

			swLogger.EndLogging();

			if(pwDb == null)
			{
				if(ds == null) m_docMgr.CloseDatabase(m_docMgr.ActiveDatabase);
			}

			if(ex != null)
			{
				string strMsg = MessageService.GetLoadWarningMessage(
					ioc.GetDisplayName(), ex,
					(Program.CommandLineArgs[AppDefs.CommandLineOptions.Debug] != null));

				bool bShowStd = true;
				if(!ioc.IsLocalFile())
				{
					VistaTaskDialog vtd = new VistaTaskDialog();
					vtd.CommandLinks = false;
					vtd.Content = strMsg;
					vtd.DefaultButtonID = (int)DialogResult.Cancel;
					// vtd.VerificationText = KPRes.CredSpecifyDifferent;
					vtd.WindowTitle = PwDefs.ShortProductName;

					vtd.SetIcon(VtdIcon.Warning);
					vtd.AddButton((int)DialogResult.Cancel, KPRes.Ok, null);
					vtd.AddButton((int)DialogResult.Retry,
						KPRes.CredSpecifyDifferent, null);

					if(vtd.ShowDialog(this))
					{
						bShowStd = false;

						// if(vtd.ResultVerificationChecked)
						if(vtd.Result == (int)DialogResult.Retry)
						{
							IOConnectionInfo iocNew = ioc.CloneDeep();
							// iocNew.ClearCredentials(false);
							iocNew.CredSaveMode = IOCredSaveMode.NoSave;
							iocNew.IsComplete = false;
							// iocNew.Password = string.Empty;

							OpenDatabase(iocNew, null, false);

							bAbort = true;
						}
					}
				}

				if(bShowStd) MessageService.ShowWarning(strMsg);
				// MessageService.ShowLoadWarning(ioc.GetDisplayName(), ex,
				//	(Program.CommandLineArgs[AppDefs.CommandLineOptions.Debug] != null));
			}

			return pwDb;
		}
		private void PostSavingEx(bool bPrimary, PwDatabase pwDatabase,
			IOConnectionInfo ioc, IStatusLogger sl)
		{
			if(ioc == null) { Debug.Assert(false); return; }

			byte[] pbIO = null;
			if(Program.Config.Application.VerifyWrittenFileAfterSaving)
			{
				pbIO = WinUtil.HashFile(ioc);
				Debug.Assert((pbIO != null) && (pwDatabase.HashOfLastIO != null));
				if(!MemUtil.ArraysEqual(pbIO, pwDatabase.HashOfLastIO))
					MessageService.ShowWarning(ioc.GetDisplayName(),
						KPRes.FileVerifyHashFail, KPRes.FileVerifyHashFailRec);
			}

			if(bPrimary)
			{
#if DEBUG
				Debug.Assert(MemUtil.ArraysEqual(pbIO, pwDatabase.HashOfFileOnDisk));

				try
				{
					PwDatabase pwCheck = new PwDatabase();
					pwCheck.Open(ioc.CloneDeep(), pwDatabase.MasterKey, null);

					Debug.Assert(MemUtil.ArraysEqual(pwDatabase.HashOfLastIO,
						pwCheck.HashOfLastIO));

					uint uGroups1, uGroups2, uEntries1, uEntries2;
					pwDatabase.RootGroup.GetCounts(true, out uGroups1, out uEntries1);
					pwCheck.RootGroup.GetCounts(true, out uGroups2, out uEntries2);
					Debug.Assert((uGroups1 == uGroups2) && (uEntries1 == uEntries2));
				}
				catch(Exception exVerify) { Debug.Assert(false, exVerify.Message); }
#endif

				m_mruList.AddItem(ioc.GetDisplayName(), ioc.CloneDeep());

				// SetLastUsedFile(ioc);

				// if(Program.Config.Application.CreateBackupFileAfterSaving && bHashValid)
				// {
				//	try { pwDatabase.CreateBackupFile(sl); }
				//	catch(Exception exBackup)
				//	{
				//		MessageService.ShowWarning(KPRes.FileBackupFailed, exBackup);
				//	}
				// }

				// ulong uTotalBinSize = 0;
				// EntryHandler ehCnt = delegate(PwEntry pe)
				// {
				//	foreach(KeyValuePair<string, ProtectedBinary> kvpCnt in pe.Binaries)
				//	{
				//		uTotalBinSize += kvpCnt.Value.Length;
				//	}
				//
				//	return true;
				// };
				// pwDatabase.RootGroup.TraverseTree(TraversalMethod.PreOrder, null, ehCnt);
			}

			RememberKeySources(pwDatabase);
			WinUtil.FlushStorageBuffers(ioc.Path, true);
		}
Beispiel #32
0
        private static void SetLastUsedFile(IOConnectionInfo ioc)
        {
            if(ioc == null) { Debug.Assert(false); return; }

            if(Program.Config.Application.Start.OpenLastFile)
                Program.Config.Application.LastUsedFile = ioc.CloneDeep();
            else
                Program.Config.Application.LastUsedFile = new IOConnectionInfo();
        }
        public long CreateFile(IOConnectionInfo ioc, String keyFile)
        {
            // Check to see if this filename is already used
            ICursor cursor;

            try {
                cursor = mDb.Query(true, FileTable, new[] { KeyFileId },
                                   KeyFileFilename + "=?", new[] { ioc.Path }, null, null, null, null);
            } catch (Exception) {
                return(-1);
            }

            IOConnectionInfo iocToStore = ioc.CloneDeep();

            if (ioc.CredSaveMode != IOCredSaveMode.SaveCred)
            {
                iocToStore.Password = "";
            }
            if (ioc.CredSaveMode == IOCredSaveMode.NoSave)
            {
                iocToStore.UserName = "";
            }

            iocToStore.Obfuscate(true);

            long result;

            // If there is an existing entry update it
            if (cursor.Count > 0)
            {
                cursor.MoveToFirst();
                long id = cursor.GetLong(cursor.GetColumnIndexOrThrow(KeyFileId));

                var vals = new ContentValues();
                vals.Put(KeyFileKeyfile, keyFile);
                vals.Put(KeyFileUpdated, Java.Lang.JavaSystem.CurrentTimeMillis());

                vals.Put(KeyFileUsername, iocToStore.UserName);
                vals.Put(KeyFilePassword, iocToStore.Password);
                vals.Put(KeyFileCredsavemode, (int)iocToStore.CredSaveMode);

                result = mDb.Update(FileTable, vals, KeyFileId + " = " + id, null);

                // Otherwise add the new entry
            }
            else
            {
                var vals = new ContentValues();
                vals.Put(KeyFileFilename, ioc.Path);
                vals.Put(KeyFileKeyfile, keyFile);
                vals.Put(KeyFileUsername, iocToStore.UserName);
                vals.Put(KeyFilePassword, iocToStore.Password);
                vals.Put(KeyFileCredsavemode, (int)iocToStore.CredSaveMode);
                vals.Put(KeyFileUpdated, Java.Lang.JavaSystem.CurrentTimeMillis());

                result = mDb.Insert(FileTable, null, vals);
            }
            // Delete all but the last five records
            try {
                DeleteAllBut(MaxFiles);
            } catch (Exception ex) {
                Android.Util.Log.Error("ex", ex.StackTrace);
            }

            cursor.Close();

            return(result);
        }
Beispiel #34
0
        /// <summary>
        /// Get a key for an existing database.  First, the key file is located, either because its location
        /// and filename are the same as the database path (with the exception of the extension), or the user
        /// is asked.  Then, the key file is decrypted using a private key.
        /// </summary>
        /// <param name="strPath">Full filename of the database file.</param>
        /// <returns>A byte array with the key, or null if an error occurs.  If an error occurs, user is
        /// notified of the error.</returns>
        byte[] GetExistingKey(IOConnectionInfo ioc)
        {
            Stream stream = null;

            try
            {
                string           newpath = UrlUtil.StripExtension(ioc.Path) + "." + CertProtKeyFileExtension;
                IOConnectionInfo keyIoc  = ioc.CloneDeep();
                keyIoc.Path = newpath;
                stream      = IOConnection.OpenRead(keyIoc);
            }
            catch (Exception)
            {
                // strPath may be a URL (even if IsLocalFile returns true?),
                // whatever the reason, fall through and the user can pick a
                // local file as the key file
            }

            if (stream == null || !stream.CanRead)
            {
                // fall back on opening a local file
                // FUTURE ENHANCEMENT: allow user to enter a URL and name/pwd as well

                OpenFileDialog ofd = UIUtil.CreateOpenFileDialog(Res.str(Res.STR_OPEN_KEY_FILE),
                                                                 UIUtil.CreateFileTypeFilter(CertProtKeyFileExtension, Res.str(Res.STR_CERT_PROT_KEY_FILE), true),
                                                                 1, CertProtKeyFileExtension, false /* multi-select */, true);

                if (ofd.ShowDialog() != DialogResult.OK)
                {
                    return(null);
                }
                stream = IOConnection.OpenRead(IOConnectionInfo.FromPath(ofd.FileName));
            }

            try
            {
                BinaryReader reader = new BinaryReader(stream);
                byte[]       p7m    = reader.ReadBytes(MAX_KEY_FILE_LENGTH);
                // URL streams don't support seeking, and so Position doesn't work
                //bool tooBig = stream.Position >= MAX_KEY_FILE_LENGTH;
                bool tooBig = p7m.Length >= MAX_KEY_FILE_LENGTH;
                reader.Close();

                if (tooBig)
                {
                    MessageBox.Show(Res.str(Res.STR_KEY_FILE_TOO_BIG), Res.AppTitle);
                    return(null);
                }

                Cursor.Current = Cursors.WaitCursor;
                return(CryptoCmsTools.DecryptMsg(p7m));
            }
            catch (SystemException ex)  // covers IOException and CryptographicException
            {
                String msg = String.Format(Res.str(Res.STR_ERR_DECRYPTING_KEY), ex.ToString());
                //String msg = String.Format(Res.str(Res.STR_ERR_DECRYPTING_KEY), getCryptoExceptionDetails(ex));
                MessageBox.Show(msg, Res.AppTitle);
                return(null);
            }
            finally
            {
                Cursor.Current = Cursors.Default;
            }
        }