Пример #1
0
        private bool TxfMoveWithTx()
        {
#if ModernKeePassLib
            return(true);
#else
            IntPtr hTx = new IntPtr((int)NativeMethods.INVALID_HANDLE_VALUE);
            Debug.Assert(hTx.ToInt64() == NativeMethods.INVALID_HANDLE_VALUE);
            try
            {
                string strTx = PwDefs.ShortProductName + " TxF - " +
                               StrUtil.AlphaNumericOnly(Convert.ToBase64String(
                                                            CryptoRandom.Instance.GetRandomBytes(16)));
                const int mchTx = NativeMethods.MAX_TRANSACTION_DESCRIPTION_LENGTH;
                if (strTx.Length >= mchTx)
                {
                    strTx = strTx.Substring(0, mchTx - 1);
                }

                hTx = NativeMethods.CreateTransaction(IntPtr.Zero,
                                                      IntPtr.Zero, 0, 0, 0, 0, strTx);
                if (hTx.ToInt64() == NativeMethods.INVALID_HANDLE_VALUE)
                {
                    Debug.Assert(false, (new Win32Exception()).Message);
                    return(false);
                }

                if (!NativeMethods.MoveFileTransacted(m_iocTemp.Path, m_iocBase.Path,
                                                      IntPtr.Zero, IntPtr.Zero, (NativeMethods.MOVEFILE_COPY_ALLOWED |
                                                                                 NativeMethods.MOVEFILE_REPLACE_EXISTING), hTx))
                {
                    Debug.Assert(false, (new Win32Exception()).Message);
                    return(false);
                }

                if (!NativeMethods.CommitTransaction(hTx))
                {
                    Debug.Assert(false, (new Win32Exception()).Message);
                    return(false);
                }

                Debug.Assert(!File.Exists(m_iocTemp.Path));
                return(true);
            }
            catch (Exception) { Debug.Assert(false); }
            finally
            {
                if (hTx.ToInt64() != NativeMethods.INVALID_HANDLE_VALUE)
                {
                    try { if (!NativeMethods.CloseHandle(hTx))
                          {
                              Debug.Assert(false);
                          }
                    }
                    catch (Exception) { Debug.Assert(false); }
                }
            }

            return(false);
#endif
        }
Пример #2
0
        public string GetTempFileName(string strFileExt)
        {
            if (string.IsNullOrEmpty(strFileExt))
            {
                return(GetTempFileName());
            }

            try
            {
                while (true)
                {
                    string str = UrlUtil.EnsureTerminatingSeparator(
                        UrlUtil.GetTempPath(), false);
                    str += "Temp_";

                    byte[] pbRandom = new byte[9];
                    Program.GlobalRandom.NextBytes(pbRandom);
                    str += StrUtil.AlphaNumericOnly(Convert.ToBase64String(
                                                        pbRandom, Base64FormattingOptions.None));

                    str += "." + strFileExt;

                    if (!File.Exists(str))
                    {
                        m_vFiles.Add(str);
                        return(str);
                    }
                }
            }
            catch (Exception) { Debug.Assert(false); }

            return(GetTempFileName());
        }
Пример #3
0
        internal static string GetUserID()
        {
            if (g_strUserID != null)
            {
                return(g_strUserID);
            }

            string strID = (Environment.UserName ?? string.Empty) + " @ " +
                           (Environment.MachineName ?? string.Empty);

            byte[] pbID = StrUtil.Utf8.GetBytes(strID);

            byte[] pbHash;
            using (SHA1Managed h = new SHA1Managed())
            {
                pbHash = h.ComputeHash(pbID);
            }

            string strShort = Convert.ToBase64String(pbHash);

            strShort = StrUtil.AlphaNumericOnly(strShort);
            if (strShort.Length > 8)
            {
                strShort = strShort.Substring(0, 8);
            }

            g_strUserID = strShort;
            return(strShort);
        }
Пример #4
0
        public static string GetCacheFile(PwUuid pwPluginUuid, bool bMustExist,
                                          bool bCreateDirectory)
        {
            if (pwPluginUuid == null)
            {
                return(null);
            }

            byte[] pbID = new byte[(int)PwUuid.UuidSize];
            Array.Copy(pwPluginUuid.UuidBytes, 0, pbID, 0, pbID.Length);
            Array.Reverse(pbID);
            string strID = Convert.ToBase64String(pbID, Base64FormattingOptions.None);

            strID = StrUtil.AlphaNumericOnly(strID);
            if (strID.Length > 8)
            {
                strID = strID.Substring(0, 8);
            }

            string strDir    = GetCacheDirectory(pwPluginUuid, bCreateDirectory);
            string strPlugin = strDir + Path.DirectorySeparatorChar + strID + ".dll";
            bool   bExists   = File.Exists(strPlugin);

            if (bMustExist && bExists)
            {
                try { File.SetLastAccessTime(strPlugin, DateTime.Now); }
                catch (Exception) { Debug.Assert(false); }
            }

            if (!bMustExist || bExists)
            {
                return(strPlugin);
            }
            return(null);
        }
Пример #5
0
        private void TxfPrepare()
        {
            try
            {
                if (NativeLib.IsUnix())
                {
                    return;
                }
                if (!m_iocBase.IsLocalFile())
                {
                    return;
                }

                string strID = StrUtil.AlphaNumericOnly(Convert.ToBase64String(
                                                            CryptoRandom.Instance.GetRandomBytes(16)));
                string strTempDir = UrlUtil.GetTempPath();
                // See also ClearOld method
                string strTemp = UrlUtil.EnsureTerminatingSeparator(strTempDir,
                                                                    false) + StrTxfTempPrefix + strID + StrTxfTempSuffix;

                char chB = UrlUtil.GetDriveLetter(m_iocBase.Path);
                char chT = UrlUtil.GetDriveLetter(strTemp);
                if (!TxfIsSupported(chB))
                {
                    return;
                }
                if ((chT != chB) && !TxfIsSupported(chT))
                {
                    return;
                }

                m_iocTxfMidFallback = m_iocTemp;
#if ModernKeePassLib
                var tempFile = ApplicationData.Current.TemporaryFolder.CreateFileAsync(m_iocTemp.Path).GetAwaiter()
                               .GetResult();
                m_iocTemp = IOConnectionInfo.FromFile(tempFile);
#else
                m_iocTemp = IOConnectionInfo.FromPath(strTemp);
#endif

                m_lToDelete.Add(m_iocTemp);
            }
            catch (Exception) { Debug.Assert(false); m_iocTxfMidFallback = null; }
        }
Пример #6
0
        private void TxfPrepare()
        {
            try
            {
                if (NativeLib.IsUnix())
                {
                    return;
                }
                if (!m_iocBase.IsLocalFile())
                {
                    return;
                }

                string strID = StrUtil.AlphaNumericOnly(Convert.ToBase64String(
                                                            CryptoRandom.Instance.GetRandomBytes(16)));
                string strTempDir = Path.GetTempPath();
                if (!Directory.Exists(strTempDir))
                {
                    Directory.CreateDirectory(strTempDir);
                }
                // See also ClearOld method
                string strTemp = UrlUtil.EnsureTerminatingSeparator(strTempDir,
                                                                    false) + StrTxfTempPrefix + strID + StrTxfTempSuffix;

                char chB = UrlUtil.GetDriveLetter(m_iocBase.Path);
                char chT = UrlUtil.GetDriveLetter(strTemp);
                if (!TxfIsSupported(chB))
                {
                    return;
                }
                if ((chT != chB) && !TxfIsSupported(chT))
                {
                    return;
                }

                m_iocTxfMidFallback = m_iocTemp;
                m_iocTemp           = IOConnectionInfo.FromPath(strTemp);

                m_lToDelete.Add(m_iocTemp);
            }
            catch (Exception) { Debug.Assert(false); m_iocTxfMidFallback = null; }
        }
Пример #7
0
        public static string GetCacheDirectory(PwUuid pwPluginUuid, bool bEnsureExists)
        {
            string strPlgID = Convert.ToBase64String(pwPluginUuid.UuidBytes,
                                                     Base64FormattingOptions.None);

            strPlgID = StrUtil.AlphaNumericOnly(strPlgID);
            if (strPlgID.Length > 16)
            {
                strPlgID = strPlgID.Substring(0, 16);
            }

            string strDir = GetCacheRoot() + Path.DirectorySeparatorChar +
                            strPlgID + "_" + GetAppID();

            if (bEnsureExists && !Directory.Exists(strDir))
            {
                Directory.CreateDirectory(strDir);
            }

            return(strDir);
        }
Пример #8
0
        public static string GetCacheFile(PlgxPluginInfo plgx, bool bMustExist,
                                          bool bCreateDirectory)
        {
            if (plgx == null)
            {
                Debug.Assert(false); return(null);
            }

            // byte[] pbID = new byte[(int)PwUuid.UuidSize];
            // Array.Copy(pwPluginUuid.UuidBytes, 0, pbID, 0, pbID.Length);
            // Array.Reverse(pbID);
            // string strID = Convert.ToBase64String(pbID, Base64FormattingOptions.None);
            // strID = StrUtil.AlphaNumericOnly(strID);
            // if(strID.Length > 8) strID = strID.Substring(0, 8);

            string strFileName = StrUtil.AlphaNumericOnly(plgx.BaseFileName);

            if (strFileName.Length == 0)
            {
                strFileName = "Plugin";
            }
            strFileName += ".dll";

            string strDir  = GetCacheDirectory(plgx, bCreateDirectory);
            string strPath = strDir + Path.DirectorySeparatorChar + strFileName;
            bool   bExists = File.Exists(strPath);

            if (bMustExist && bExists)
            {
                try { File.SetLastAccessTime(strPath, DateTime.Now); }
                catch (Exception) { }                // Might be locked by other KeePass instance
            }

            if (!bMustExist || bExists)
            {
                return(strPath);
            }
            return(null);
        }
Пример #9
0
        public static string GetCacheDirectory(PlgxPluginInfo plgx, bool bEnsureExists)
        {
            if (plgx == null)
            {
                Debug.Assert(false); return(null);
            }

            StringBuilder sb = new StringBuilder();

            sb.Append(plgx.BaseFileName);
            sb.Append(':');
            sb.Append(Convert.ToBase64String(plgx.FileUuid.UuidBytes,
                                             Base64FormattingOptions.None));
            sb.Append(';');
            sb.Append(GetAppEnvID());

            byte[]        pbID   = StrUtil.Utf8.GetBytes(sb.ToString());
            SHA256Managed sha256 = new SHA256Managed();

            byte[] pbHash = sha256.ComputeHash(pbID);

            string strHash = Convert.ToBase64String(pbHash, Base64FormattingOptions.None);

            strHash = StrUtil.AlphaNumericOnly(strHash);
            if (strHash.Length > 20)
            {
                strHash = strHash.Substring(0, 20);
            }

            string strDir = GetCacheRoot() + Path.DirectorySeparatorChar + strHash;

            if (bEnsureExists && !Directory.Exists(strDir))
            {
                Directory.CreateDirectory(strDir);
            }

            return(strDir);
        }
Пример #10
0
        private static byte[] OpenExternal(string strName, byte[] pbData,
                                           BinaryDataOpenOptions opt)
        {
            byte[] pbResult = null;

            try
            {
                string strBaseTempDir = UrlUtil.EnsureTerminatingSeparator(
                    UrlUtil.GetTempPath(), false);

                string strTempID, strTempDir;
                while (true)
                {
                    byte[] pbRandomID = CryptoRandom.Instance.GetRandomBytes(8);
                    strTempID = Convert.ToBase64String(pbRandomID);
                    strTempID = StrUtil.AlphaNumericOnly(strTempID);
                    if (strTempID.Length == 0)
                    {
                        Debug.Assert(false); continue;
                    }

                    strTempDir = strBaseTempDir + strTempID;
                    if (!Directory.Exists(strTempDir))
                    {
                        Directory.CreateDirectory(strTempDir);

                        strTempDir = UrlUtil.EnsureTerminatingSeparator(
                            strTempDir, false);

                        // Mark directory as encrypted, such that new files
                        // are encrypted automatically; there exists no
                        // Directory.Encrypt method, but we can use File.Encrypt,
                        // because this internally uses the EncryptFile API
                        // function, which works with directories
                        try { File.Encrypt(strTempDir); }
                        catch (Exception) { Debug.Assert(false); }

                        break;
                    }
                }

                string strFile = strTempDir + strName;
                File.WriteAllBytes(strFile, pbData);

                // Encrypt again, in case the directory encryption above failed
                try { File.Encrypt(strFile); }
                catch (Exception) { Debug.Assert(false); }

                ProcessStartInfo psi = new ProcessStartInfo();
                psi.FileName         = strFile;
                psi.UseShellExecute  = true;
                psi.WorkingDirectory = strTempDir;

                ParameterizedThreadStart pts = new ParameterizedThreadStart(
                    BinaryDataUtil.ShellOpenFn);
                Thread th = new Thread(pts);
                th.Start(psi);

                string strMsgMain = KPRes.AttachExtOpened + MessageService.NewParagraph +
                                    KPRes.AttachExtOpenedPost + ":";
                string strMsgImp        = KPRes.Import;
                string strMsgImpDesc    = KPRes.AttachExtImportDesc;
                string strMsgCancel     = KPRes.DiscardChangesCmd;
                string strMsgCancelDesc = KPRes.AttachExtDiscardDesc;

                VistaTaskDialog vtd = new VistaTaskDialog();
                vtd.CommandLinks    = true;
                vtd.Content         = strMsgMain;
                vtd.MainInstruction = strName;
                vtd.WindowTitle     = PwDefs.ShortProductName;
                vtd.SetIcon(VtdCustomIcon.Question);

                vtd.AddButton((int)DialogResult.OK, strMsgImp, strMsgImpDesc);
                vtd.AddButton((int)DialogResult.Cancel, strMsgCancel, strMsgCancelDesc);

                vtd.FooterText = KPRes.AttachExtSecDel;
                vtd.SetFooterIcon(VtdIcon.Information);

                bool bImport;
                if (vtd.ShowDialog())
                {
                    bImport = ((vtd.Result == (int)DialogResult.OK) ||
                               (vtd.Result == (int)DialogResult.Yes));
                }
                else
                {
                    StringBuilder sb = new StringBuilder();
                    sb.AppendLine(strName);
                    sb.AppendLine();
                    sb.AppendLine(strMsgMain);
                    sb.AppendLine();
                    sb.AppendLine("[" + KPRes.Yes + "]:");
                    sb.AppendLine(StrUtil.RemoveAccelerator(strMsgImp) +
                                  " - " + strMsgImpDesc);
                    sb.AppendLine();
                    sb.AppendLine("[" + KPRes.No + "]:");
                    sb.AppendLine(StrUtil.RemoveAccelerator(strMsgCancel) +
                                  " - " + strMsgCancelDesc);
                    sb.AppendLine();
                    sb.AppendLine(KPRes.AttachExtSecDel);

                    bImport = MessageService.AskYesNo(sb.ToString(),
                                                      PwDefs.ShortProductName);
                }

                if (bImport && !opt.ReadOnly)
                {
                    while (true)
                    {
                        try
                        {
                            pbResult = File.ReadAllBytes(strFile);
                            break;
                        }
                        catch (Exception exRead)
                        {
                            if (!AskForRetry(strFile, exRead.Message))
                            {
                                break;
                            }
                        }
                    }
                }

                string strReportObj = null;
                while (true)
                {
                    try
                    {
                        strReportObj = strFile;
                        if (File.Exists(strFile))
                        {
                            FileInfo fiTemp = new FileInfo(strFile);
                            long     cb     = fiTemp.Length;
                            if (cb > 0)
                            {
                                byte[] pbOvr = new byte[cb];
                                Program.GlobalRandom.NextBytes(pbOvr);
                                File.WriteAllBytes(strFile, pbOvr);
                            }

                            File.Delete(strFile);
                        }

                        strReportObj = strTempDir;
                        if (Directory.Exists(strTempDir))
                        {
                            Directory.Delete(strTempDir, true);
                        }

                        break;
                    }
                    catch (Exception exDel)
                    {
                        if (!AskForRetry(strReportObj, exDel.Message))
                        {
                            break;
                        }
                    }
                }
            }
            catch (Exception ex)
            {
                MessageService.ShowWarning(ex.Message);
            }

            return(pbResult);
        }
Пример #11
0
        public DialogResult ShowDialog(out object objResult, object objConstructParam)
        {
            objResult = null;

            ProcessMessagesEx();

            // Creating a window on the new desktop spawns a CtfMon.exe child
            // process by default. On Windows Vista, this process is terminated
            // correctly when the desktop is closed. However, on Windows 7 it
            // isn't terminated (probably a bug); creating multiple desktops
            // accumulates CtfMon.exe child processes.
            ChildProcessesSnapshot cpsCtfMons = new ChildProcessesSnapshot(
                "CtfMon.exe");

            ClipboardEventChainBlocker ccb = new ClipboardEventChainBlocker();

            byte[] pbClipHash = ClipboardUtil.ComputeHash();

            SecureThreadInfo stp = new SecureThreadInfo();

            foreach (Screen sc in Screen.AllScreens)
            {
                Bitmap bmpBack = UIUtil.CreateScreenshot(sc);
                if (bmpBack != null)
                {
                    UIUtil.DimImage(bmpBack);
                }
                stp.BackgroundBitmaps.Add(bmpBack);
            }

            DialogResult dr = DialogResult.None;

            try
            {
                uint   uOrgThreadId = NativeMethods.GetCurrentThreadId();
                IntPtr pOrgDesktop  = NativeMethods.GetThreadDesktop(uOrgThreadId);

                string strName = "D" + Convert.ToBase64String(
                    CryptoRandom.Instance.GetRandomBytes(16));
                strName = StrUtil.AlphaNumericOnly(strName);
                if (strName.Length > 15)
                {
                    strName = strName.Substring(0, 15);
                }

                NativeMethods.DesktopFlags deskFlags =
                    (NativeMethods.DesktopFlags.CreateMenu |
                     NativeMethods.DesktopFlags.CreateWindow |
                     NativeMethods.DesktopFlags.ReadObjects |
                     NativeMethods.DesktopFlags.WriteObjects |
                     NativeMethods.DesktopFlags.SwitchDesktop);

                IntPtr pNewDesktop = NativeMethods.CreateDesktop(strName,
                                                                 null, IntPtr.Zero, 0, deskFlags, IntPtr.Zero);
                if (pNewDesktop == IntPtr.Zero)
                {
                    throw new InvalidOperationException();
                }

                bool bNameSupported = NativeMethods.DesktopNameContains(pNewDesktop,
                                                                        strName).GetValueOrDefault(false);
                Debug.Assert(bNameSupported);

                stp.ThreadDesktop      = pNewDesktop;
                stp.FormConstructParam = objConstructParam;

                Thread th = new Thread(this.SecureDialogThread);
                th.CurrentCulture   = Thread.CurrentThread.CurrentCulture;
                th.CurrentUICulture = Thread.CurrentThread.CurrentUICulture;
                th.Start(stp);

                SecureThreadState st = SecureThreadState.None;
                while (st != SecureThreadState.Terminated)
                {
                    th.Join(150);

                    lock (stp) { st = stp.State; }

                    if ((st == SecureThreadState.ShowingDialog) && bNameSupported)
                    {
                        IntPtr hCurDesk = NativeMethods.OpenInputDesktop(0,
                                                                         false, NativeMethods.DesktopFlags.ReadObjects);
                        if (hCurDesk == IntPtr.Zero)
                        {
                            Debug.Assert(false); continue;
                        }
                        if (hCurDesk == pNewDesktop)
                        {
                            if (!NativeMethods.CloseDesktop(hCurDesk))
                            {
                                Debug.Assert(false);
                            }
                            continue;
                        }
                        bool?obOnSec = NativeMethods.DesktopNameContains(hCurDesk, strName);
                        if (!NativeMethods.CloseDesktop(hCurDesk))
                        {
                            Debug.Assert(false);
                        }

                        lock (stp) { st = stp.State; }                        // Update; might have changed

                        if (obOnSec.HasValue && !obOnSec.Value &&
                            (st == SecureThreadState.ShowingDialog))
                        {
                            HandleUnexpectedDesktopSwitch(pOrgDesktop, pNewDesktop, stp);
                        }
                    }
                }

                if (!NativeMethods.SwitchDesktop(pOrgDesktop))
                {
                    Debug.Assert(false);
                }
                NativeMethods.SetThreadDesktop(pOrgDesktop);

                th.Join();                 // Ensure thread terminated before closing desktop

                if (!NativeMethods.CloseDesktop(pNewDesktop))
                {
                    Debug.Assert(false);
                }
                NativeMethods.CloseDesktop(pOrgDesktop);                 // Optional

                dr        = stp.DialogResult;
                objResult = stp.ResultObject;
            }
            catch (Exception) { Debug.Assert(false); }

            byte[] pbNewClipHash = ClipboardUtil.ComputeHash();
            if ((pbClipHash != null) && (pbNewClipHash != null) &&
                !MemUtil.ArraysEqual(pbClipHash, pbNewClipHash))
            {
                ClipboardUtil.Clear();
            }
            ccb.Dispose();

            foreach (Bitmap bmpBack in stp.BackgroundBitmaps)
            {
                if (bmpBack != null)
                {
                    bmpBack.Dispose();
                }
            }
            stp.BackgroundBitmaps.Clear();

            cpsCtfMons.TerminateNewChildsAsync(4100);

            // If something failed, show the dialog on the normal desktop
            if (dr == DialogResult.None)
            {
                Form f = m_fnConstruct(objConstructParam);
                dr        = f.ShowDialog();
                objResult = m_fnResultBuilder(f);
                UIUtil.DestroyForm(f);
            }

            return(dr);
        }