Exemple #1
0
        /// <summary>
        /// Convert the KeyList object to a composite key
        /// </summary>
        /// <param name="kList">KeyList containing the composite key information.</param>
        /// <returns>CompositeKey object.</returns>
        internal static CompositeKey ConvertToComposite(KeyList kList)
        {
            if (kList.Pass == null || kList.KeyName == null)
            {
                return(null);
            }
            int          kNumber = kList.Pass.Count();
            int          i       = 0;
            CompositeKey mKey    = new CompositeKey();

            for (i = 0; i < kNumber; ++i)
            {
                switch (kList.KeyName[i])
                {
                case "KeePassLib.Keys.KcpPassword":
                    byte[]   pb       = kList.Pass[i].ReadUtf8();
                    IUserKey mKeyPass = new KcpPassword(pb);
                    MemUtil.ZeroByteArray(pb);
                    mKey.AddUserKey(mKeyPass);
                    break;

                case "KeePassLib.Keys.KcpKeyFile":
                    IUserKey mKeyFile = new KcpKeyFile(kList.Pass[i].ReadString());
                    mKey.AddUserKey(mKeyFile);
                    break;

                case "KeePassLib.Keys.KcpUserAccount":
                    IUserKey mKeyUser = new KcpUserAccount();
                    mKey.AddUserKey(mKeyUser);
                    break;
                }
            }
            return(mKey);
        }
Exemple #2
0
        internal static string[] MakeCtxIndependent(string[] vCmdLineArgs)
        {
            if (vCmdLineArgs == null)
            {
                Debug.Assert(false); return(new string[0]);
            }

            CommandLineArgs cl   = new CommandLineArgs(vCmdLineArgs);
            List <string>   lFlt = new List <string>();

            foreach (string strArg in vCmdLineArgs)
            {
                KeyValuePair <string, string> kvpArg = CommandLineArgs.GetParameter(strArg);
                if (kvpArg.Key.Equals(AppDefs.CommandLineOptions.PasswordStdIn, StrUtil.CaseIgnoreCmp))
                {
                    KcpPassword kcpPw = ReadPasswordStdIn(true);

                    if ((cl[AppDefs.CommandLineOptions.Password] == null) &&
                        (cl[AppDefs.CommandLineOptions.PasswordEncrypted] == null) &&
                        (kcpPw != null))
                    {
                        lFlt.Add("-" + AppDefs.CommandLineOptions.Password + ":" +
                                 kcpPw.Password.ReadString());                        // No quote wrapping/encoding
                    }
                }
                else
                {
                    lFlt.Add(strArg);
                }
            }

            return(lFlt.ToArray());
        }
Exemple #3
0
        public ICollection <SecretEntryModel> ReadDatabase(string databasePath, string masterPassword)
        {
            _stringValidator.IsNullOrWhitespace(databasePath, nameof(databasePath));
            _stringValidator.IsNullOrWhitespace(masterPassword, nameof(masterPassword));
            _fileValidator.IsExist(databasePath);

            //How to read KeePass database taken from https://stackoverflow.com/a/9028433

            var result = default(ICollection <SecretEntryModel>);

            var connection = new IOConnectionInfo {
                Path = databasePath
            };
            var compositeKey = new CompositeKey();
            var password     = new KcpPassword(masterPassword);

            compositeKey.AddUserKey(password);
            var database = new KeePassLib.PwDatabase();

            try
            {
                database.Open(connection, compositeKey, null);

                var readData = from entry in database.RootGroup.GetEntries(true)
                               select new
                {
                    Group    = entry.ParentGroup.Name,
                    Title    = entry.Strings.ReadSafe("Title"),
                    UserName = entry.Strings.ReadSafe("UserName"),
                    Password = entry.Strings.ReadSafe("Password"),
                    URL      = entry.Strings.ReadSafe("URL"),
                    Notes    = entry.Strings.ReadSafe("Notes")
                };
                result = readData.Select(data => new SecretEntryModel
                {
                    Title    = data.Title,
                    UserName = data.UserName,
                    Password = data.Password,
                }).ToList();
            }
            catch (Exception exception)
            {
                Log.Logger.Error(exception, $"During reading KeePass database {databasePath} an error has been occured");
            }
            finally
            {
                if (database.IsOpen)
                {
                    database.Close();
                }
            }

            return(result);
        }
        /// <summary>
        /// This function checks if the actual SyncSource (this) represents exactly the same
        /// SyncSource that would occur if we will use the given entry and db to create a new one.
        /// </summary>
        /// <param name="entry">The PwEntry from our db that should represent a SyncSource.</param>
        /// <param name="db">The db which contains the given entry.</param>
        /// <returns>True if (entry + db) will create the same SyncSource object like "this".</returns>
        public bool IsEqual(PwEntry entry, PwDatabase db)
        {
            if (!IsSimilar(entry, db))
            {
                return(false);
            }
            IUserKey key1 = new KcpPassword(entry.Strings.ReadSafe(KeeShare.PasswordField));
            IUserKey key2 = m_key.GetUserKey(typeof(KcpPassword));

            // null is interpreted as equal
            return(key1 == key2 || key1.KeyData.Equals(key2.KeyData));
        }
        public void TestConstruct()
        {
            var expectedHash = new byte[32] {
                0x5E, 0x88, 0x48, 0x98, 0xDA, 0x28, 0x04, 0x71,
                0x51, 0xD0, 0xE5, 0x6F, 0x8D, 0xC6, 0x29, 0x27,
                0x73, 0x60, 0x3D, 0x0D, 0x6A, 0xAB, 0xBD, 0xD6,
                0x2A, 0x11, 0xEF, 0x72, 0x1D, 0x15, 0x42, 0xD8
            };

            var key     = new KcpPassword(testPassword);
            var keyData = key.KeyData.ReadData();

            Assert.That(keyData, Is.EqualTo(expectedHash));
        }
        public CompositeKey GetCompositeKey(KeyCipher keyCipher)
        {
            var password     = keyCipher.UnProtect(_protectedPassword);
            var compositeKey = new CompositeKey();

            foreach (var data in _keys)
            {
                IUserKey key     = null;
                byte[]   rawData = null;
                if (data.KcpType != KcpType.kcpUserAccount)
                {
                    rawData = keyCipher.Decrypt(data.EncryptedData, password);
                }

                try
                {
                    switch (data.KcpType)
                    {
                    case KcpType.kcpCustomKey:
                        key = new KcpCustomKey(data.CustomName, rawData, false);
                        break;

                    case KcpType.kcpPassword:
                        key = new KcpPassword(rawData);
                        break;

                    case KcpType.kcpKeyFile:
                        key = new KcpKeyFile(Encoding.UTF8.GetString(rawData));
                        break;

                    case KcpType.kcpUserAccount:
                        key = new KcpUserAccount();
                        break;
                    }
                }
                finally
                {
                    if (rawData != null)
                    {
                        MemUtil.ZeroByteArray(rawData);
                    }
                }

                Debug.Assert(key != null);
                compositeKey.AddUserKey(key);
            }

            return(compositeKey);
        }
        public static KeePassWrapper OpenWithPassword(string path, string password)
        {
            var wrapper = new KeePassWrapper
            {
                Path     = path,
                Database = new PwDatabase()
            };
            var io           = IOConnectionInfo.FromPath(path);
            var masterpass   = new KcpPassword(password);
            var compositeKey = new CompositeKey();

            compositeKey.AddUserKey(masterpass);
            wrapper.Database.Open(io, compositeKey, new NullStatusLogger());
            return(wrapper);
        }
        Database TryLoad(MemoryStream databaseStream)
        {
            //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
            {
                Database newDb = _app.LoadDatabase(_ioc, workingCopy, _compositeKey, StatusLogger, _format);
                Kp2aLog.Log("LoadDB OK");

                //make sure the stored access time for the actual file is more recent than that of its backup
                Thread.Sleep(10);
                SaveFileData(_ioc, _keyfileOrProvider);

                Finish(true, _format.SuccessMessage);
                return(newDb);
            }
            catch (OldFormatException)
            {
                _format = new KdbDatabaseFormat(_app);
                return(TryLoad(databaseStream));
            }
            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:
                    return(TryLoad(databaseStream));
                }
                else
                {
                    throw;
                }
            }
        }
Exemple #9
0
        public IKeePassService Open()
        {
            //TODO add support for composite database keys
            if (KeePassPasswordProvider.RetrievePassword() == null)
            {
                throw new ArgumentNullException("password", "Password provided by IKeePassPasswordValueProvider is not set. Please register Password before calling Open().");
            }

            var io           = IOConnectionInfo.FromPath(Configuration.Path);
            var masterpass   = new KcpPassword(KeePassPasswordProvider.RetrievePassword().ConvertToUnsecureString());
            var compositeKey = new CompositeKey();

            compositeKey.AddUserKey(masterpass);
            _database = new PwDatabase();
            _database.Open(io, compositeKey, new NullStatusLogger());
            return(this);
        }
Exemple #10
0
        private static KdbErrorCode SetDatabaseKey(KdbManager mgr, CompositeKey pwKey)
        {
            string strPassword = null;

            if (pwKey.ContainsType(typeof(KcpPassword)))
            {
                KcpPassword     p  = (pwKey.GetUserKey(typeof(KcpPassword)) as KcpPassword);
                ProtectedString ps = ((p != null) ? p.Password : null);
                if (ps == null)
                {
                    throw new Exception(KPRes.OptionReqOn + @" '" +
                                        KPRes.MasterPasswordRmbWhileOpen + @"'.");
                }
                strPassword = ps.ReadString();
            }

            string strKeyFile = null;

            if (pwKey.ContainsType(typeof(KcpKeyFile)))
            {
                strKeyFile = (pwKey.GetUserKey(typeof(KcpKeyFile)) as KcpKeyFile).Path;
            }

            KdbErrorCode e;

            if (!string.IsNullOrEmpty(strKeyFile))
            {
                e = mgr.SetMasterKey(strKeyFile, true, strPassword, IntPtr.Zero, false);
            }
            else if (strPassword != null)
            {
                e = mgr.SetMasterKey(strPassword, false, null, IntPtr.Zero, false);
            }
            else if (pwKey.ContainsType(typeof(KcpUserAccount)))
            {
                throw new Exception(KPRes.KdbWUA);
            }
            else
            {
                throw new Exception(KLRes.InvalidCompositeKey);
            }

            return(e);
        }
Exemple #11
0
        private static CompositeKey CreateCompositeKey(ProtectedString password, string keyFilePath)
        {
            CompositeKey key = new CompositeKey();

            if (!password.IsEmpty)
            {
                IUserKey mKeyPass = new KcpPassword(password.ReadUtf8());
                key.AddUserKey(mKeyPass);
            }

            // Load a keyfile for the target database if requested (and add it to the key)
            if (!string.IsNullOrEmpty(keyFilePath))
            {
                IUserKey mKeyFile = new KcpKeyFile(keyFilePath);
                key.AddUserKey(mKeyFile);
            }

            return(key);
        }
Exemple #12
0
        private static void GenerateEms(StringBuilder sb, PwDatabase pd, string strDbFile,
                                        GFunc <string, string> h, GFunc <string, string> ne, GFunc <string, string> ltrPath,
                                        string strFillInit, string strFillInitEx, string strFillEnd, string strFill)
        {
            sb.AppendLine("<p><strong>" + h(KPRes.DatabaseFile) + ":</strong></p>");
            sb.AppendLine(strFillInitEx + ne(h(ltrPath(strDbFile))) + strFillEnd);

            // if(pd.Name.Length > 0)
            //	sb.AppendLine("<p><strong>" + h(KPRes.Name) + ":</strong> " +
            //		h(pd.Name) + "</p>");
            // if(pd.Description.Length > 0)
            //	sb.AppendLine("<p><strong>" + h(KPRes.Description) + ":</strong> " +
            //		h(pd.Description));

            sb.AppendLine("<p>" + h(KPRes.BackupDatabase) + " " +
                          h(KPRes.BackupLocation) + "</p>");
            sb.AppendLine(strFill);

            CompositeKey ck = pd.MasterKey;

            if (ck.UserKeyCount > 0)
            {
                sb.AppendLine("<br />");
                sb.AppendLine("<h3>" + h(KPRes.MasterKey) + "</h3>");
                sb.AppendLine("<p>" + h(KPRes.MasterKeyComponents) + "</p>");
                sb.AppendLine("<ul>");

                foreach (IUserKey k in ck.UserKeys)
                {
                    KcpPassword    p  = (k as KcpPassword);
                    KcpKeyFile     kf = (k as KcpKeyFile);
                    KcpUserAccount a  = (k as KcpUserAccount);
                    KcpCustomKey   c  = (k as KcpCustomKey);

                    if (p != null)
                    {
                        sb.AppendLine("<li><p><strong>" + h(KPRes.MasterPassword) +
                                      ":</strong></p>");
                        sb.AppendLine(strFill + "</li>");
                    }
                    else if (kf != null)
                    {
                        sb.AppendLine("<li><p><strong>" + h(KPRes.KeyFile) +
                                      ":</strong></p>");
                        sb.AppendLine(strFillInitEx + ne(h(ltrPath(kf.Path))) + strFillEnd);

                        sb.AppendLine("<p>" + h(KPRes.BackupFile) + " " +
                                      h(KPRes.BackupLocation) + "</p>");
                        sb.AppendLine(strFill);

                        sb.AppendLine("</li>");
                    }
                    else if (a != null)
                    {
                        sb.AppendLine("<li><p><strong>" + h(KPRes.WindowsUserAccount) +
                                      ":</strong></p>");
                        sb.Append(strFillInitEx);
                        try
                        {
                            sb.Append(ne(h(ltrPath(Environment.UserDomainName +
                                                   "\\" + Environment.UserName))));
                        }
                        catch (Exception) { Debug.Assert(false); sb.Append(ne(string.Empty)); }
                        sb.AppendLine(strFillEnd);

                        sb.AppendLine("<p>" + h(KPRes.WindowsUserAccountBackup) + " " +
                                      h(KPRes.BackupLocation) + "</p>");
                        sb.AppendLine(strFill + "</li>");
                    }
                    else if (c != null)
                    {
                        sb.AppendLine("<li><p><strong>" + h(KPRes.KeyProvider) +
                                      ":</strong></p>");
                        sb.AppendLine(strFillInitEx + ne(h(ltrPath(c.Name))) + strFillEnd);

                        sb.AppendLine("</li>");
                    }
                    else
                    {
                        Debug.Assert(false);
                        sb.AppendLine("<li><p><strong>" + h(KPRes.Unknown) + ".</strong></p></li>");
                    }
                }

                sb.AppendLine("</ul>");
            }

            sb.AppendLine("<br />");
            sb.AppendLine("<h3>" + h(KPRes.InstrAndGenInfo) + "</h3>");

            sb.AppendLine("<ul class=\"withspc\">");

            sb.AppendLine("<li>" + h(KPRes.EmergencySheetInfo) + "</li>");
            // sb.AppendLine("<form class=\"scronly\" action=\"#\" onsubmit=\"javascript:window.print();\">");
            // sb.AppendLine("<input type=\"submit\" value=\"&#x1F5B6; " +
            //	h(KPRes.Print) + "\" />");
            // sb.AppendLine("</form></li>");

            sb.AppendLine("<li>" + h(KPRes.DataLoss) + "</li>");
            sb.AppendLine("<li>" + h(KPRes.LatestVersionWeb) + ": <a href=\"" +
                          h(PwDefs.HomepageUrl) + "\" target=\"_blank\">" +
                          h(PwDefs.HomepageUrl) + "</a>.</li>");
            sb.AppendLine("</ul>");
        }
Exemple #13
0
        private void OnFormLoad(object sender, EventArgs e)
        {
            m_bInitializing = true;

            GlobalWindowManager.AddWindow(this);
            // if(m_bRedirectActivation) Program.MainForm.RedirectActivationPush(this);

            string strBannerTitle = (!string.IsNullOrEmpty(m_strCustomTitle) ?
                                     m_strCustomTitle : KPRes.EnterCompositeKey);
            string strBannerDesc = WinUtil.CompactPath(m_ioInfo.Path, 45);

            BannerFactory.CreateBannerEx(this, m_bannerImage,
                                         Properties.Resources.B48x48_KGPG_Key2, strBannerTitle, strBannerDesc);
            this.Icon = AppIcons.Default;

            FontUtil.SetDefaultFont(m_cbPassword);
            FontUtil.AssignDefaultBold(m_cbPassword);
            FontUtil.AssignDefaultBold(m_cbKeyFile);
            FontUtil.AssignDefaultBold(m_cbUserAccount);

            UIUtil.ConfigureToolTip(m_ttRect);
            // m_ttRect.SetToolTip(m_cbHidePassword, KPRes.TogglePasswordAsterisks);
            m_ttRect.SetToolTip(m_btnOpenKeyFile, KPRes.KeyFileSelect);

            PwInputControlGroup.ConfigureHideButton(m_cbHidePassword, m_ttRect);

            string strStart = (!string.IsNullOrEmpty(m_strCustomTitle) ?
                               m_strCustomTitle : KPRes.OpenDatabase);
            string strNameEx = UrlUtil.GetFileName(m_ioInfo.Path);

            if (!string.IsNullOrEmpty(strNameEx))
            {
                this.Text = strStart + " - " + strNameEx;
            }
            else
            {
                this.Text = strStart;
            }

            m_tbPassword.Text = string.Empty;
            m_secPassword.SecureDesktopMode = m_bSecureDesktop;
            m_secPassword.Attach(m_tbPassword, ProcessTextChangedPassword, true);

            // m_cmbKeyFile.OrderedImageList = m_lKeyFileImages;
            AddKeyFileSuggPriv(KPRes.NoKeyFileSpecifiedMeta, true);

            // Do not directly compare with Program.CommandLineArgs.FileName,
            // because this may be a relative path instead of an absolute one
            string strCmdLineFile = Program.CommandLineArgs.FileName;

            if ((strCmdLineFile != null) && (Program.MainForm != null))
            {
                strCmdLineFile = Program.MainForm.IocFromCommandLine().Path;
            }
            if ((strCmdLineFile != null) && strCmdLineFile.Equals(m_ioInfo.Path,
                                                                  StrUtil.CaseIgnoreCmp))
            {
                string str;

                str = Program.CommandLineArgs[AppDefs.CommandLineOptions.Password];
                if (str != null)
                {
                    m_cbPassword.Checked = true;
                    m_tbPassword.Text    = str;
                }

                str = Program.CommandLineArgs[AppDefs.CommandLineOptions.PasswordEncrypted];
                if (str != null)
                {
                    m_cbPassword.Checked = true;
                    m_tbPassword.Text    = StrUtil.DecryptString(str);
                }

                str = Program.CommandLineArgs[AppDefs.CommandLineOptions.PasswordStdIn];
                if (str != null)
                {
                    KcpPassword kcpPw = KeyUtil.ReadPasswordStdIn(true);
                    if (kcpPw != null)
                    {
                        m_cbPassword.Checked = true;
                        m_tbPassword.Text    = kcpPw.Password.ReadString();
                    }
                }

                str = Program.CommandLineArgs[AppDefs.CommandLineOptions.KeyFile];
                if (str != null)
                {
                    m_cbKeyFile.Checked = true;
                    AddKeyFileSuggPriv(str, true);
                }

                str = Program.CommandLineArgs[AppDefs.CommandLineOptions.PreSelect];
                if (str != null)
                {
                    m_cbKeyFile.Checked = true;
                    AddKeyFileSuggPriv(str, true);
                }
            }

            m_cbHidePassword.Checked = true;
            OnCheckedHidePassword(sender, e);

            Debug.Assert(m_cmbKeyFile.Text.Length != 0);

            m_btnExit.Enabled = m_bCanExit;
            m_btnExit.Visible = m_bCanExit;

            ulong uKpf = Program.Config.UI.KeyPromptFlags;

            UIUtil.ApplyKeyUIFlags(uKpf, m_cbPassword, m_cbKeyFile,
                                   m_cbUserAccount, m_cbHidePassword);

            if ((uKpf & (ulong)AceKeyUIFlags.DisableKeyFile) != 0)
            {
                UIUtil.SetEnabled(m_cmbKeyFile, m_cbKeyFile.Checked);
                UIUtil.SetEnabled(m_btnOpenKeyFile, m_cbKeyFile.Checked);
            }

            if (((uKpf & (ulong)AceKeyUIFlags.CheckPassword) != 0) ||
                ((uKpf & (ulong)AceKeyUIFlags.UncheckPassword) != 0))
            {
                m_bPwStatePreset = true;
            }
            if (((uKpf & (ulong)AceKeyUIFlags.CheckUserAccount) != 0) ||
                ((uKpf & (ulong)AceKeyUIFlags.UncheckUserAccount) != 0))
            {
                m_bUaStatePreset = true;
            }

            CustomizeForScreenReader();
            EnableUserControls();

            m_bInitializing = false;

            // E.g. command line options have higher priority
            m_bCanModKeyFile = (m_cmbKeyFile.SelectedIndex == 0);

            m_aKeyAssoc = Program.Config.Defaults.GetKeySources(m_ioInfo);
            if (m_aKeyAssoc != null)
            {
                if (m_aKeyAssoc.Password && !m_bPwStatePreset)
                {
                    m_cbPassword.Checked = true;
                }

                if (m_aKeyAssoc.KeyFilePath.Length > 0)
                {
                    AddKeyFileSuggPriv(m_aKeyAssoc.KeyFilePath, null);
                }

                if (m_aKeyAssoc.UserAccount && !m_bUaStatePreset)
                {
                    m_cbUserAccount.Checked = true;
                }
            }

            foreach (KeyProvider prov in Program.KeyProviderPool)
            {
                AddKeyFileSuggPriv(prov.Name, null);
            }

            // Local, but thread will continue to run anyway
            Thread th = new Thread(new ThreadStart(this.AsyncFormLoad));

            th.Start();
            // ThreadPool.QueueUserWorkItem(new WaitCallback(this.AsyncFormLoad));

            this.BringToFront();
            this.Activate();
            // UIUtil.SetFocus(m_tbPassword, this); // See OnFormShown
        }
Exemple #14
0
        public static CompositeKey KeyFromCommandLine(CommandLineArgs args)
        {
            if (args == null)
            {
                throw new ArgumentNullException("args");
            }

            CompositeKey cmpKey           = new CompositeKey();
            string       strPassword      = args[AppDefs.CommandLineOptions.Password];
            string       strPasswordEnc   = args[AppDefs.CommandLineOptions.PasswordEncrypted];
            string       strPasswordStdIn = args[AppDefs.CommandLineOptions.PasswordStdIn];
            string       strKeyFile       = args[AppDefs.CommandLineOptions.KeyFile];
            string       strUserAcc       = args[AppDefs.CommandLineOptions.UserAccount];

            if (strPassword != null)
            {
                cmpKey.AddUserKey(new KcpPassword(strPassword));
            }
            else if (strPasswordEnc != null)
            {
                cmpKey.AddUserKey(new KcpPassword(StrUtil.DecryptString(strPasswordEnc)));
            }
            else if (strPasswordStdIn != null)
            {
                KcpPassword kcpPw = ReadPasswordStdIn(true);
                if (kcpPw != null)
                {
                    cmpKey.AddUserKey(kcpPw);
                }
            }

            if (strKeyFile != null)
            {
                if (Program.KeyProviderPool.IsKeyProvider(strKeyFile))
                {
                    KeyProviderQueryContext ctxKP = new KeyProviderQueryContext(
                        IOConnectionInfo.FromPath(args.FileName), false, false);

                    bool   bPerformHash;
                    byte[] pbProvKey = Program.KeyProviderPool.GetKey(strKeyFile, ctxKP,
                                                                      out bPerformHash);
                    if ((pbProvKey != null) && (pbProvKey.Length > 0))
                    {
                        try { cmpKey.AddUserKey(new KcpCustomKey(strKeyFile, pbProvKey, bPerformHash)); }
                        catch (Exception exCKP)
                        {
                            MessageService.ShowWarning(exCKP);
                            return(null);
                        }

                        Array.Clear(pbProvKey, 0, pbProvKey.Length);
                    }
                    else
                    {
                        return(null);                     // Provider has shown error message
                    }
                }
                else                 // Key file
                {
                    try { cmpKey.AddUserKey(new KcpKeyFile(strKeyFile)); }
                    catch (Exception exKey)
                    {
                        MessageService.ShowWarning(strKeyFile, KPRes.KeyFileError, exKey);
                        return(null);
                    }
                }
            }

            if (strUserAcc != null)
            {
                try { cmpKey.AddUserKey(new KcpUserAccount()); }
                catch (Exception exUA)
                {
                    MessageService.ShowWarning(exUA);
                    return(null);
                }
            }

            if (cmpKey.UserKeyCount > 0)
            {
                ClearKeyOptions(args, true);
                return(cmpKey);
            }

            return(null);
        }
Exemple #15
0
        private static string GenerateHtml(PwDatabase pd, string strName)
        {
            bool   bRtl        = Program.Translation.Properties.RightToLeft;
            string strLogLeft  = (bRtl ? "right" : "left");
            string strLogRight = (bRtl ? "left" : "right");

            GFunc <string, string> h  = new GFunc <string, string>(StrUtil.StringToHtml);
            GFunc <string, string> ne = delegate(string str)
            {
                if (string.IsNullOrEmpty(str))
                {
                    return("&nbsp;");
                }
                return(str);
            };
            GFunc <string, string> ltrPath = delegate(string str)
            {
                return(bRtl ? StrUtil.EnsureLtrPath(str) : str);
            };

            StringBuilder sb = new StringBuilder();

            sb.AppendLine("<!DOCTYPE html>");

            sb.Append("<html xmlns=\"http://www.w3.org/1999/xhtml\"");
            string strLang = Program.Translation.Properties.Iso6391Code;

            if (string.IsNullOrEmpty(strLang))
            {
                strLang = "en";
            }
            strLang = h(strLang);
            sb.Append(" xml:lang=\"" + strLang + "\" lang=\"" + strLang + "\"");
            if (bRtl)
            {
                sb.Append(" dir=\"rtl\"");
            }
            sb.AppendLine(">");

            sb.AppendLine("<head>");
            sb.AppendLine("<meta http-equiv=\"Content-Type\" content=\"text/html; charset=utf-8\" />");
            sb.AppendLine("<meta http-equiv=\"X-UA-Compatible\" content=\"IE=edge\" />");
            sb.AppendLine("<meta http-equiv=\"expires\" content=\"0\" />");
            sb.AppendLine("<meta http-equiv=\"cache-control\" content=\"no-cache\" />");
            sb.AppendLine("<meta http-equiv=\"pragma\" content=\"no-cache\" />");

            sb.Append("<title>");
            sb.Append(h(strName + " - " + KPRes.EmergencySheet));
            sb.AppendLine("</title>");

            sb.AppendLine("<style type=\"text/css\">");
            sb.AppendLine("/* <![CDATA[ */");

            string strFont = "\"Arial\", \"Tahoma\", \"Verdana\", sans-serif;";

            // https://sourceforge.net/p/keepass/discussion/329220/thread/f98dece5/
            if (Program.Translation.IsFor("fa"))
            {
                strFont = "\"Tahoma\", \"Arial\", \"Verdana\", sans-serif;";
            }

            sb.AppendLine("body {");
            sb.AppendLine("\tcolor: #000000;");
            sb.AppendLine("\tbackground-color: #FFFFFF;");
            sb.AppendLine("\tfont-family: " + strFont);
            sb.AppendLine("\tfont-size: 12pt;");
            sb.AppendLine("}");

            sb.AppendLine("h3, p {");
            sb.AppendLine("\tmargin: 0.5em 0em 0.5em 0em;");
            sb.AppendLine("}");

            sb.AppendLine("ol, ul {");
            sb.AppendLine("\tmargin-bottom: 0em;");
            sb.AppendLine("}");

            sb.AppendLine("h1, h2, h3 {");
            sb.AppendLine("\tfont-family: \"Verdana\", \"Arial\", \"Tahoma\", sans-serif;");
            sb.AppendLine("}");
            sb.AppendLine("h1, h2 {");
            sb.AppendLine("\tmargin: 0pt 0pt 0pt 0pt;");
            sb.AppendLine("\ttext-align: center;");
            sb.AppendLine("}");
            sb.AppendLine("h1 {");
            sb.AppendLine("\tpadding: 3pt 0pt 0pt 0pt;");
            sb.AppendLine("}");
            sb.AppendLine("h2 {");
            sb.AppendLine("\tpadding: 1pt 0pt 3pt 0pt;");
            sb.AppendLine("}");
            // sb.AppendLine("h3 {");
            // sb.AppendLine("\tpadding: 3pt 3pt 3pt 3pt;");
            // sb.AppendLine("\tcolor: #000000;");
            // sb.AppendLine("\tbackground-color: #EEEEEE;");
            // sb.AppendLine("\tbackground-image: -webkit-linear-gradient(top, #E2E2E2, #FAFAFA);");
            // sb.AppendLine("\tbackground-image: -moz-linear-gradient(top, #E2E2E2, #FAFAFA);");
            // sb.AppendLine("\tbackground-image: -ms-linear-gradient(top, #E2E2E2, #FAFAFA);");
            // sb.AppendLine("\tbackground-image: linear-gradient(to bottom, #E2E2E2, #FAFAFA);");
            // sb.AppendLine("}");

            sb.AppendLine("a {");
            sb.AppendLine("\tcolor: #0000DD;");
            sb.AppendLine("\ttext-decoration: none;");
            sb.AppendLine("}");
            sb.AppendLine("a:hover, a:active {");
            sb.AppendLine("\tcolor: #6699FF;");
            sb.AppendLine("\ttext-decoration: underline;");
            sb.AppendLine("}");

            sb.AppendLine("img {");
            sb.AppendLine("\tborder: 0px none;");
            sb.AppendLine("}");

            sb.AppendLine(".withspc > li + li {");
            sb.AppendLine("\tmargin-top: 0.5em;");
            sb.AppendLine("}");

            sb.AppendLine("table.docheader {");
            sb.AppendLine("\twidth: 100%;");
            sb.AppendLine("\tbackground-color: #EEEEEE;");
            sb.AppendLine("\tmargin: 0px 0px 0px 0px;");
            sb.AppendLine("\tpadding: 0px 0px 0px 0px;");
            sb.AppendLine("\tborder: thin solid #808080;");
            // border-collapse is incompatible with border-radius
            // sb.AppendLine("\tborder-collapse: collapse;");
            sb.AppendLine("\t-webkit-border-radius: 5px;");
            sb.AppendLine("\t-moz-border-radius: 5px;");
            sb.AppendLine("\tborder-radius: 5px;");
            sb.AppendLine("}");

            sb.AppendLine("table.docheader tr td {");
            sb.AppendLine("\tborder: 0px none;");
            sb.AppendLine("\tborder-collapse: collapse;");
            sb.AppendLine("\tpadding: 0px 15px 0px 15px;");
            sb.AppendLine("\tvertical-align: middle;");
            sb.AppendLine("}");

            sb.AppendLine("table.fillinline {");
            sb.AppendLine("\twidth: 100%;");
            sb.AppendLine("\tmargin: 0px 0px 0px 0px;");
            sb.AppendLine("\tpadding: 0px 0px 0px 0px;");
            sb.AppendLine("\tborder: thin solid #808080;");
            sb.AppendLine("\tborder-collapse: collapse;");
            sb.AppendLine("\ttable-layout: fixed;");
            sb.AppendLine("\tempty-cells: show;");
            sb.AppendLine("}");
            sb.AppendLine("table.fillinline tr td {");
            sb.AppendLine("\tpadding: 4pt 4pt 4pt 4pt;");
            sb.AppendLine("\tvertical-align: middle;");
            sb.AppendLine("\tword-break: break-all;");
            sb.AppendLine("\toverflow-wrap: break-word;");
            sb.AppendLine("\tword-wrap: break-word;");
            sb.AppendLine("}");
            sb.AppendLine("table.fillinline tr td img {");
            sb.AppendLine("\tdisplay: block;");             // Inline results in additional space at the bottom
            sb.AppendLine("\tmargin: 0px " + (bRtl ? "auto 0px 0px;" : "0px 0px auto;"));
            sb.AppendLine("}");
            // sb.AppendLine("span.fillinlinesym {");
            // sb.AppendLine("\tdisplay: inline-block;");
            // sb.AppendLine("\ttransform: scale(1.75, 1.75) translate(-0.5pt, -0.5pt);");
            // sb.AppendLine("}");

            // sb.AppendLine("@media print {");
            // sb.AppendLine(".scronly {");
            // sb.AppendLine("\tdisplay: none;");
            // sb.AppendLine("}");
            // sb.AppendLine("}");

            // Add the temporary content identifier
            // (always, as the sheet should be printed, not saved)
            sb.AppendLine("." + Program.TempFilesPool.TempContentTag + " {");
            sb.AppendLine("\tfont-size: 12pt;");
            sb.AppendLine("}");

            sb.AppendLine("/* ]]> */");
            sb.AppendLine("</style>");
            sb.AppendLine("</head><body>");

            ImageArchive ia = new ImageArchive();

            ia.Load(Properties.Resources.Images_App_HighRes);

            sb.AppendLine("<table class=\"docheader\"><tr>");
            sb.AppendLine("<td style=\"text-align: " + strLogLeft + ";\">");
            sb.AppendLine("<img src=\"" + GfxUtil.ImageToDataUri(ia.GetForObject(
                                                                     "KeePass")) + "\" width=\"48\" height=\"48\" alt=\"" +
                          h(PwDefs.ShortProductName) + "\" /></td>");
            sb.AppendLine("<td style=\"text-align: center;\">");
            sb.AppendLine("<h1>" + h(PwDefs.ShortProductName) + "</h1>");
            sb.AppendLine("<h2>" + h(KPRes.EmergencySheet) + "</h2>");
            sb.AppendLine("</td>");
            sb.AppendLine("<td style=\"text-align: " + strLogRight + ";\">");
            sb.AppendLine("<img src=\"" + GfxUtil.ImageToDataUri(ia.GetForObject(
                                                                     "KOrganizer")) + "\" width=\"48\" height=\"48\" alt=\"" +
                          h(KPRes.EmergencySheet) + "\" /></td>");
            sb.AppendLine("</tr></table>");

            sb.AppendLine("<p style=\"text-align: " + strLogRight + ";\">" +
                          h(TimeUtil.ToDisplayStringDateOnly(DateTime.Now)) + "</p>");

            const string strFillInit    = "<table class=\"fillinline\"><tr><td>";
            const string strFillInitLtr = "<table class=\"fillinline\"><tr><td dir=\"ltr\">";
            const string strFillEnd     = "</td></tr></table>";
            string       strFillSym     = "<img src=\"" + GfxUtil.ImageToDataUri(
                Properties.Resources.B48x35_WritingHand) +
                                          "\" style=\"width: 1.3714em; height: 1em;" +
                                          (bRtl ? " transform: scaleX(-1);" : string.Empty) +
                                          "\" alt=\"&#x270D;\" />";
            string strFill = strFillInit + ne(string.Empty) +
                             // "</td><td style=\"text-align: right;\"><span class=\"fillinlinesym\">&#x270D;</span>" +
                             // "</td><td style=\"text-align: " + strLogRight + ";\">" +
                             "</td><td>" +
                             strFillSym + strFillEnd;

            string strFillInitEx = (bRtl ? strFillInitLtr : strFillInit);

            IOConnectionInfo ioc = pd.IOConnectionInfo;

            sb.AppendLine("<p><strong>" + h(KPRes.DatabaseFile) + ":</strong></p>");
            sb.AppendLine(strFillInitEx + ne(h(ltrPath(ioc.Path))) + strFillEnd);

            // if(pd.Name.Length > 0)
            //	sb.AppendLine("<p><strong>" + h(KPRes.Name) + ":</strong> " +
            //		h(pd.Name) + "</p>");
            // if(pd.Description.Length > 0)
            //	sb.AppendLine("<p><strong>" + h(KPRes.Description) + ":</strong> " +
            //		h(pd.Description));

            sb.AppendLine("<p>" + h(KPRes.BackupDatabase) + " " +
                          h(KPRes.BackupLocation) + "</p>");
            sb.AppendLine(strFill);

            CompositeKey ck = pd.MasterKey;

            if (ck.UserKeyCount > 0)
            {
                sb.AppendLine("<br />");
                sb.AppendLine("<h3>" + h(KPRes.MasterKey) + "</h3>");
                sb.AppendLine("<p>" + h(KPRes.MasterKeyComponents) + "</p>");
                sb.AppendLine("<ul>");

                foreach (IUserKey k in ck.UserKeys)
                {
                    KcpPassword    p  = (k as KcpPassword);
                    KcpKeyFile     kf = (k as KcpKeyFile);
                    KcpUserAccount a  = (k as KcpUserAccount);
                    KcpCustomKey   c  = (k as KcpCustomKey);

                    if (p != null)
                    {
                        sb.AppendLine("<li><p><strong>" + h(KPRes.MasterPassword) +
                                      ":</strong></p>");
                        sb.AppendLine(strFill + "</li>");
                    }
                    else if (kf != null)
                    {
                        sb.AppendLine("<li><p><strong>" + h(KPRes.KeyFile) +
                                      ":</strong></p>");
                        sb.AppendLine(strFillInitEx + ne(h(ltrPath(kf.Path))) + strFillEnd);

                        sb.AppendLine("<p>" + h(KPRes.BackupFile) + " " +
                                      h(KPRes.BackupLocation) + "</p>");
                        sb.AppendLine(strFill);

                        sb.AppendLine("</li>");
                    }
                    else if (a != null)
                    {
                        sb.AppendLine("<li><p><strong>" + h(KPRes.WindowsUserAccount) +
                                      ":</strong></p>");
                        sb.Append(strFillInitEx);
                        try
                        {
                            sb.Append(ne(h(ltrPath(Environment.UserDomainName +
                                                   "\\" + Environment.UserName))));
                        }
                        catch (Exception) { Debug.Assert(false); sb.Append(ne(string.Empty)); }
                        sb.AppendLine(strFillEnd);

                        sb.AppendLine("<p>" + h(KPRes.WindowsUserAccountBackup) + " " +
                                      h(KPRes.BackupLocation) + "</p>");
                        sb.AppendLine(strFill + "</li>");
                    }
                    else if (c != null)
                    {
                        sb.AppendLine("<li><p><strong>" + h(KPRes.KeyProvider) +
                                      ":</strong></p>");
                        sb.AppendLine(strFillInitEx + ne(h(ltrPath(c.Name))) + strFillEnd);

                        sb.AppendLine("</li>");
                    }
                    else
                    {
                        Debug.Assert(false);
                        sb.AppendLine("<li><p><strong>" + h(KPRes.Unknown) + ".</strong></p></li>");
                    }
                }

                sb.AppendLine("</ul>");
            }

            sb.AppendLine("<br />");
            sb.AppendLine("<h3>" + h(KPRes.InstrAndGenInfo) + "</h3>");

            sb.AppendLine("<ul class=\"withspc\">");

            sb.AppendLine("<li>" + h(KPRes.EmergencySheetInfo) + "</li>");
            // sb.AppendLine("<form class=\"scronly\" action=\"#\" onsubmit=\"javascript:window.print();\">");
            // sb.AppendLine("<input type=\"submit\" value=\"&#x1F5B6; " +
            //	h(KPRes.Print) + "\" />");
            // sb.AppendLine("</form></li>");

            sb.AppendLine("<li>" + h(KPRes.DataLoss) + "</li>");
            sb.AppendLine("<li>" + h(KPRes.LatestVersionWeb) + ": <a href=\"" +
                          h(PwDefs.HomepageUrl) + "\" target=\"_blank\">" +
                          h(PwDefs.HomepageUrl) + "</a>.</li>");
            sb.AppendLine("</ul>");

            sb.AppendLine("</body></html>");

            string strDoc = sb.ToString();

#if DEBUG
            XmlUtilEx.ValidateXml(strDoc, true);
#endif
            return(strDoc);
        }
Exemple #16
0
        public static string TryGetPassword(string url, string username)
        {
            if (group != null)
            {
                return(InternalGetPassword(url, username));
            }

            if (failed)
            {
                return(null);
            }

            context = AzusaContext.GetInstance();
            DirectoryInfo di         = new DirectoryInfo(".");
            FileInfo      dbFileInfo = di.GetFiles("*.kdbx").FirstOrDefault(x => x.Extension.ToLower().Equals(".kdbx"));

            if (dbFileInfo == null)
            {
                dbFileInfo = di.Parent.GetFiles("*.kdbx").FirstOrDefault(x => x.Extension.ToLower().Equals(".kdbx"));
            }
            if (dbFileInfo == null)
            {
                failed = true;
                return(null);
            }

            string pw = null;

            context.Splash.Invoke((MethodInvoker) delegate
            {
                pw = TextInputForm.PromptPassword(String.Format("Passwort für {0}?", dbFileInfo.Name), context.Splash);
            });
            if (string.IsNullOrEmpty(pw))
            {
                failed = true;
                return(null);
            }

            IOConnectionInfo connectionInfo = IOConnectionInfo.FromPath(dbFileInfo.FullName);
            KcpPassword      kcpPassword    = new KcpPassword(pw);
            CompositeKey     compositeKey   = new CompositeKey();

            compositeKey.AddUserKey(kcpPassword);
            database = new PwDatabase();
            try
            {
                database.Open(connectionInfo, compositeKey, null);
                group = FindPwGroup(database.RootGroup);
                if (group == null)
                {
                    failed = true;
                    return(null);
                }
                return(InternalGetPassword(url, username));
            }
            catch (InvalidCompositeKeyException)
            {
                failed = true;
                return(null);
            }
        }
Exemple #17
0
        public void PopulateDatabaseFromStream(PwDatabase db, Stream s, IStatusLogger slLogger)
        {
                        #if !EXCLUDE_KEYTRANSFORM
            var importer = new Com.Keepassdroid.Database.Load.ImporterV3();

            var hashingStream = new HashingStreamEx(s, false, new SHA256Managed());

            _metaStreams = new List <PwEntryV3>();

            string      password    = "";    //no need to distinguish between null and "" because empty passwords are invalid (and null is not allowed)
            KcpPassword passwordKey = (KcpPassword)db.MasterKey.GetUserKey(typeof(KcpPassword));
            if (passwordKey != null)
            {
                password = passwordKey.Password.ReadString();
            }

            KcpKeyFile   passwordKeyfile = (KcpKeyFile)db.MasterKey.GetUserKey(typeof(KcpKeyFile));
            MemoryStream keyfileStream   = null;
            if (passwordKeyfile != null)
            {
                keyfileStream = new MemoryStream(passwordKeyfile.RawFileData.ReadData());
            }


            try
            {
                var dbv3 = importer.OpenDatabase(hashingStream, password, keyfileStream);

                db.Name          = dbv3.Name;
                db.KdfParameters = (new AesKdf()).GetDefaultParameters();
                db.KdfParameters.SetUInt64(AesKdf.ParamRounds, (ulong)dbv3.NumKeyEncRounds);


                db.RootGroup = ConvertGroup(dbv3.RootGroup);
                if (dbv3.Algorithm == PwEncryptionAlgorithm.Rjindal)
                {
                    db.DataCipherUuid = StandardAesEngine.AesUuid;
                }
                else
                {
                    db.DataCipherUuid = new PwUuid(TwofishCipher.TwofishCipherEngine.TwofishCipherUuidBytes);
                }
            }
            catch (Java.IO.FileNotFoundException e)
            {
                throw new FileNotFoundException(
                          e.Message, e);
            }
            catch (Java.Lang.Exception e)
            {
                if (e.Message == "Invalid key!")
                {
                    throw new InvalidCompositeKeyException();
                }
                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
            }
#else
            throw new Exception("Kdb is excluded with Key transform!");
#endif
        }
Exemple #18
0
        public void Save(PwDatabase kpDatabase, Stream stream)
        {
            PwDatabaseV3 db       = new PwDatabaseV3();
            KcpPassword  pwd      = kpDatabase.MasterKey.GetUserKey <KcpPassword>();
            string       password = pwd != null?pwd.Password.ReadString() : "";

            KcpKeyFile keyfile         = kpDatabase.MasterKey.GetUserKey <KcpKeyFile>();
            Stream     keyfileContents = null;

            if (keyfile != null)
            {
                keyfileContents = new MemoryStream(keyfile.RawFileData.ReadData());
            }
            db.SetMasterKey(password, keyfileContents);

            AesKdf kdf = new AesKdf();

            if (!kdf.Uuid.Equals(kpDatabase.KdfParameters.KdfUuid))
            {
                db.NumRounds = (uint)PwDefs.DefaultKeyEncryptionRounds;
            }
            else
            {
                ulong uRounds = kpDatabase.KdfParameters.GetUInt64(
                    AesKdf.ParamRounds, PwDefs.DefaultKeyEncryptionRounds);
                uRounds = Math.Min(uRounds, 0xFFFFFFFEUL);

                db.NumRounds = (uint)uRounds;
            }


            db.Name = kpDatabase.Name;
            if (kpDatabase.DataCipherUuid.Equals(StandardAesEngine.AesUuid))
            {
                db.Algorithm = PwEncryptionAlgorithm.Rjindal;
            }
            else
            {
                db.Algorithm = PwEncryptionAlgorithm.Twofish;
            }

            //create groups
            db.Groups.Clear();
            var fromGroups = kpDatabase.RootGroup.GetGroups(true);
            Dictionary <int, PwGroupV3> groupV3s = new Dictionary <int, PwGroupV3>(fromGroups.Count());

            foreach (PwGroup g in fromGroups)
            {
                if (g == kpDatabase.RootGroup)
                {
                    continue;
                }
                PwGroupV3 groupV3 = ConvertGroup(g, db);
                db.Groups.Add(groupV3);
                groupV3s[groupV3.Id.Id] = groupV3;
            }

            //traverse again and assign parents
            db.RootGroup       = ConvertGroup(kpDatabase.RootGroup, db);
            db.RootGroup.Level = -1;

            AssignParent(kpDatabase.RootGroup, db, groupV3s);

            foreach (PwEntry e in kpDatabase.RootGroup.GetEntries(true))
            {
                PwEntryV3 entryV3 = ConvertEntry(e, db);
                entryV3.Parent = groupV3s[_groupData[e.ParentGroup.Uuid].Id];
                entryV3.Parent.ChildEntries.Add(entryV3);
                entryV3.GroupId = entryV3.Parent.Id.Id;
                db.Entries.Add(entryV3);
            }

            //add meta stream entries:
            if (db.Groups.Any())
            {
                foreach (var metaEntry in _metaStreams)
                {
                    metaEntry.GroupId = db.Groups.First().Id.Id;
                    db.Entries.Add(metaEntry);
                }
            }


            HashingStreamEx hashedStream = new HashingStreamEx(stream, true, null);
            PwDbV3Output    output       = new PwDbV3Output(db, hashedStream);

            output.Output();
            hashedStream.Close();
            HashOfLastStream = hashedStream.Hash;

            kpDatabase.HashOfLastIO = kpDatabase.HashOfFileOnDisk = HashOfLastStream;
            stream.Close();
        }
Exemple #19
0
        private static string GenerateHtml(PwDatabase pd, string strName)
        {
            StrToStrDelegate h  = new StrToStrDelegate(StrUtil.StringToHtml);
            StrToStrDelegate ne = delegate(string str)
            {
                if (string.IsNullOrEmpty(str))
                {
                    return("&nbsp;");
                }
                return(str);
            };

            StringBuilder sb   = new StringBuilder();
            bool          bRtl = Program.Translation.Properties.RightToLeft;

            sb.AppendLine("<!DOCTYPE html PUBLIC \"-//W3C//DTD XHTML 1.0 Transitional//EN\"");
            sb.AppendLine("\t\"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd\">");

            sb.Append("<html xmlns=\"http://www.w3.org/1999/xhtml\"");
            string strLang = Program.Translation.Properties.Iso6391Code;

            if (string.IsNullOrEmpty(strLang))
            {
                strLang = "en";
            }
            strLang = h(strLang);
            sb.Append(" lang=\"" + strLang + "\" xml:lang=\"" + strLang + "\"");
            if (bRtl)
            {
                sb.Append(" dir=\"rtl\"");
            }
            sb.AppendLine(">");

            sb.AppendLine("<head>");
            sb.AppendLine("<meta http-equiv=\"Content-Type\" content=\"text/html; charset=UTF-8\" />");
            sb.Append("<title>");
            sb.Append(h(strName + " - " + KPRes.EmergencySheet));
            sb.AppendLine("</title>");
            sb.AppendLine("<meta http-equiv=\"expires\" content=\"0\" />");
            sb.AppendLine("<meta http-equiv=\"cache-control\" content=\"no-cache\" />");
            sb.AppendLine("<meta http-equiv=\"pragma\" content=\"no-cache\" />");

            sb.AppendLine("<style type=\"text/css\"><!--");

            sb.AppendLine("body, p, div, h1, h2, h3, h4, h5, h6, ol, ul, li, td, th, dd, dt, a {");
            sb.AppendLine("\tfont-family: \"Arial\", \"Tahoma\", \"Verdana\", sans-serif;");
            sb.AppendLine("\tfont-size: 12pt;");
            sb.AppendLine("}");

            sb.AppendLine("body, p, div, table {");
            sb.AppendLine("\tcolor: #000000;");
            sb.AppendLine("\tbackground-color: #FFFFFF;");
            sb.AppendLine("}");

            sb.AppendLine("p, h3 {");
            sb.AppendLine("\tmargin: 0.5em 0em 0.5em 0em;");
            sb.AppendLine("}");

            sb.AppendLine("ol, ul {");
            sb.AppendLine("\tmargin-bottom: 0em;");
            sb.AppendLine("}");

            sb.AppendLine("h1, h2, h3 {");
            sb.AppendLine("\tfont-family: \"Verdana\", \"Arial\", \"Tahoma\", sans-serif;");
            sb.AppendLine("}");
            sb.AppendLine("h1, h2 {");
            sb.AppendLine("\ttext-align: center;");
            sb.AppendLine("\tmargin: 0pt 0pt 0pt 0pt;");
            sb.AppendLine("}");
            sb.AppendLine("h1 {");
            sb.AppendLine("\tfont-size: 2em;");
            sb.AppendLine("\tpadding: 3pt 0pt 0pt 0pt;");
            sb.AppendLine("}");
            sb.AppendLine("h2 {");
            sb.AppendLine("\tfont-size: 1.5em;");
            sb.AppendLine("\tpadding: 1pt 0pt 3pt 0pt;");
            sb.AppendLine("}");
            sb.AppendLine("h3 {");
            sb.AppendLine("\tfont-size: 1.2em;");
            // sb.AppendLine("\tpadding: 3pt 3pt 3pt 3pt;");
            // sb.AppendLine("\tcolor: #000000;");
            // sb.AppendLine("\tbackground-color: #EEEEEE;");
            // sb.AppendLine("\tbackground-image: -webkit-linear-gradient(top, #E2E2E2, #FAFAFA);");
            // sb.AppendLine("\tbackground-image: -moz-linear-gradient(top, #E2E2E2, #FAFAFA);");
            // sb.AppendLine("\tbackground-image: -ms-linear-gradient(top, #E2E2E2, #FAFAFA);");
            // sb.AppendLine("\tbackground-image: linear-gradient(to bottom, #E2E2E2, #FAFAFA);");
            sb.AppendLine("}");
            sb.AppendLine("h4 { font-size: 1em; }");
            sb.AppendLine("h5 { font-size: 0.89em; }");
            sb.AppendLine("h6 { font-size: 0.6em; }");

            sb.AppendLine("a:visited {");
            sb.AppendLine("\ttext-decoration: none;");
            sb.AppendLine("\tcolor: #0000DD;");
            sb.AppendLine("}");
            sb.AppendLine("a:active {");
            sb.AppendLine("\ttext-decoration: none;");
            sb.AppendLine("\tcolor: #6699FF;");
            sb.AppendLine("}");
            sb.AppendLine("a:link {");
            sb.AppendLine("\ttext-decoration: none;");
            sb.AppendLine("\tcolor: #0000DD;");
            sb.AppendLine("}");
            sb.AppendLine("a:hover {");
            sb.AppendLine("\ttext-decoration: underline;");
            sb.AppendLine("\tcolor: #6699FF;");
            sb.AppendLine("}");

            sb.AppendLine("img {");
            sb.AppendLine("\tborder: 0px none;");
            sb.AppendLine("}");

            sb.AppendLine(".withspc > li + li {");
            sb.AppendLine("\tmargin-top: 0.5em;");
            sb.AppendLine("}");

            sb.AppendLine("table.docheader {");
            sb.AppendLine("\twidth: 100%;");
            sb.AppendLine("\tbackground-color: #EEEEEE;");
            sb.AppendLine("\tmargin: 0px 0px 0px 0px;");
            sb.AppendLine("\tpadding: 0px 0px 0px 0px;");
            sb.AppendLine("\tborder: thin solid #808080;");
            // border-collapse is incompatible with border-radius
            // sb.AppendLine("\tborder-collapse: collapse;");
            sb.AppendLine("\t-webkit-border-radius: 5px;");
            sb.AppendLine("\t-moz-border-radius: 5px;");
            sb.AppendLine("\tborder-radius: 5px;");
            sb.AppendLine("}");

            sb.AppendLine("table.docheader tr td {");
            sb.AppendLine("\tvertical-align: middle;");
            sb.AppendLine("\tpadding: 0px 15px 0px 15px;");
            sb.AppendLine("}");

            sb.AppendLine("table.fillinline {");
            sb.AppendLine("\twidth: 100%;");
            sb.AppendLine("\tmargin: 0px 0px 0px 0px;");
            sb.AppendLine("\tpadding: 0px 0px 0px 0px;");
            sb.AppendLine("\tborder: thin solid #808080;");
            sb.AppendLine("\tborder-collapse: collapse;");
            sb.AppendLine("\tempty-cells: show;");
            sb.AppendLine("}");
            sb.AppendLine("table.fillinline tr td {");
            sb.AppendLine("\tpadding: 4pt 4pt 4pt 4pt;");
            sb.AppendLine("\tvertical-align: middle;");
            sb.AppendLine("\tword-break: break-all;");
            sb.AppendLine("\toverflow-wrap: break-word;");
            sb.AppendLine("\tword-wrap: break-word;");
            sb.AppendLine("}");
            // sb.AppendLine("span.fillinlinesym {");
            // sb.AppendLine("\tdisplay: inline-block;");
            // sb.AppendLine("\ttransform: scale(1.75, 1.75) translate(-0.5pt, -0.5pt);");
            // sb.AppendLine("}");

            // sb.AppendLine("@media print {");
            // sb.AppendLine(".scronly {");
            // sb.AppendLine("\tdisplay: none;");
            // sb.AppendLine("}");
            // sb.AppendLine("}");

            // Add the temporary content identifier
            sb.AppendLine("." + Program.TempFilesPool.TempContentTag + " {");
            sb.AppendLine("\tfont-size: 12pt;");
            sb.AppendLine("}");

            sb.AppendLine("--></style>");
            sb.AppendLine("</head><body>");

            ImageArchive ia = new ImageArchive();

            ia.Load(Properties.Resources.Images_App_HighRes);

            sb.AppendLine("<table class=\"docheader\" cellspacing=\"0\" cellpadding=\"0\"><tr>");
            sb.AppendLine("<td style=\"text-align: left;\">");
            sb.AppendLine("<img src=\"" + GfxUtil.ImageToDataUri(ia.GetForObject(
                                                                     "KeePass")) + "\" width=\"48\" height=\"48\" alt=\"" +
                          h(PwDefs.ShortProductName) + "\" /></td>");
            sb.AppendLine("<td style=\"text-align: center;\">");
            sb.AppendLine("<h1>" + h(PwDefs.ShortProductName) + "</h1>");
            sb.AppendLine("<h2>" + h(KPRes.EmergencySheet) + "</h2>");
            sb.AppendLine("</td>");
            sb.AppendLine("<td style=\"text-align: right;\">");
            sb.AppendLine("<img src=\"" + GfxUtil.ImageToDataUri(ia.GetForObject(
                                                                     "KOrganizer")) + "\" width=\"48\" height=\"48\" alt=\"" +
                          h(KPRes.EmergencySheet) + "\" /></td>");
            sb.AppendLine("</tr></table>");

            sb.AppendLine("<p style=\"text-align: right;\">" + h(
                              TimeUtil.ToDisplayStringDateOnly(DateTime.Now)) + "</p>");

            const string strFillInit = "<table class=\"fillinline\"><tr><td>";
            const string strFillEnd  = "</td></tr></table>";
            string       strFillSym  = "<img src=\"" + GfxUtil.ImageToDataUri(
                Properties.Resources.B48x35_WritingHand) +
                                       "\" style=\"width: 1.3714em; height: 1em;\" alt=\"&#x270D;\" />";
            string strFill = strFillInit + ne(string.Empty) +
                             // "</td><td style=\"text-align: right;\"><span class=\"fillinlinesym\">&#x270D;</span>" +
                             "</td><td style=\"text-align: right;\">" + strFillSym + strFillEnd;

            IOConnectionInfo ioc = pd.IOConnectionInfo;

            sb.AppendLine("<p><strong>" + h(KPRes.DatabaseFile) + ":</strong></p>");
            sb.AppendLine(strFillInit + ne(h(ioc.Path)) + strFillEnd);

            // if(pd.Name.Length > 0)
            //	sb.AppendLine("<p><strong>" + h(KPRes.Name) + ":</strong> " +
            //		h(pd.Name) + "</p>");
            // if(pd.Description.Length > 0)
            //	sb.AppendLine("<p><strong>" + h(KPRes.Description) + ":</strong> " +
            //		h(pd.Description));

            sb.AppendLine("<p>" + h(KPRes.BackupDatabase) + " " +
                          h(KPRes.BackupLocation) + "</p>");
            sb.AppendLine(strFill);

            CompositeKey ck = pd.MasterKey;

            if (ck.UserKeyCount > 0)
            {
                sb.AppendLine("<br />");
                sb.AppendLine("<h3>" + h(KPRes.MasterKey) + "</h3>");
                sb.AppendLine("<p>" + h(KPRes.MasterKeyComponents) + "</p>");
                sb.AppendLine("<ul>");

                foreach (IUserKey k in ck.UserKeys)
                {
                    KcpPassword    p  = (k as KcpPassword);
                    KcpKeyFile     kf = (k as KcpKeyFile);
                    KcpUserAccount a  = (k as KcpUserAccount);
                    KcpCustomKey   c  = (k as KcpCustomKey);

                    if (p != null)
                    {
                        sb.AppendLine("<li><p><strong>" + h(KPRes.MasterPassword) +
                                      ":</strong></p>");
                        sb.AppendLine(strFill + "</li>");
                    }
                    else if (kf != null)
                    {
                        sb.AppendLine("<li><p><strong>" + h(KPRes.KeyFile) +
                                      ":</strong></p>");
                        sb.AppendLine(strFillInit + ne(h(kf.Path)) + strFillEnd);

                        sb.AppendLine("<p>" + h(KPRes.BackupFile) + " " +
                                      h(KPRes.BackupLocation) + "</p>");
                        sb.AppendLine(strFill);

                        sb.AppendLine("</li>");
                    }
                    else if (a != null)
                    {
                        sb.AppendLine("<li><p><strong>" + h(KPRes.WindowsUserAccount) +
                                      ":</strong></p>");
                        sb.Append(strFillInit);
                        try
                        {
                            sb.Append(ne(h(Environment.UserDomainName + "\\" +
                                           Environment.UserName)));
                        }
                        catch (Exception) { Debug.Assert(false); sb.Append(ne(string.Empty)); }
                        sb.AppendLine(strFillEnd);

                        sb.AppendLine("<p>" + h(KPRes.WindowsUserAccountBackup) + " " +
                                      h(KPRes.BackupLocation) + "</p>");
                        sb.AppendLine(strFill + "</li>");
                    }
                    else if (c != null)
                    {
                        sb.AppendLine("<li><p><strong>" + h(KPRes.KeyProvider) +
                                      ":</strong></p>");
                        sb.AppendLine(strFillInit + ne(h(c.Name)) + strFillEnd);

                        sb.AppendLine("</li>");
                    }
                    else
                    {
                        Debug.Assert(false);
                        sb.AppendLine("<li><p><strong>" + h(KPRes.Unknown) + ".</strong></p></li>");
                    }
                }

                sb.AppendLine("</ul>");
            }

            sb.AppendLine("<br />");
            sb.AppendLine("<h3>" + h(KPRes.InstrAndGenInfo) + "</h3>");

            sb.AppendLine("<ul class=\"withspc\">");

            sb.AppendLine("<li>" + h(KPRes.EmergencySheetInfo) + "</li>");
            // sb.AppendLine("<form class=\"scronly\" action=\"#\" onsubmit=\"javascript:window.print();\">");
            // sb.AppendLine("<input type=\"submit\" value=\"&#x1F5B6; " +
            //	h(KPRes.Print) + "\" />");
            // sb.AppendLine("</form></li>");

            sb.AppendLine("<li>" + h(KPRes.DataLoss) + "</li>");
            sb.AppendLine("<li>" + h(KPRes.LatestVersionWeb) + ": <a href=\"" +
                          h(PwDefs.HomepageUrl) + "\" target=\"_blank\">" +
                          h(PwDefs.HomepageUrl) + "</a>.</li>");
            sb.AppendLine("</ul>");

            sb.AppendLine("</body></html>");
            return(sb.ToString());
        }