ShInstUtil/0000775000000000000000000000000013222754450011630 5ustar rootrootShInstUtil/ShInstUtil.sln0000664000000000000000000000156511632635050014420 0ustar rootroot Microsoft Visual Studio Solution File, Format Version 10.00 # Visual Studio 2008 Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "ShInstUtil", "ShInstUtil.vcproj", "{C9FBA6FD-04AC-4B2F-8277-B852B8013DAE}" EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Win32 = Debug|Win32 Release|Win32 = Release|Win32 EndGlobalSection GlobalSection(ProjectConfigurationPlatforms) = postSolution {C9FBA6FD-04AC-4B2F-8277-B852B8013DAE}.Debug|Win32.ActiveCfg = Debug|Win32 {C9FBA6FD-04AC-4B2F-8277-B852B8013DAE}.Debug|Win32.Build.0 = Debug|Win32 {C9FBA6FD-04AC-4B2F-8277-B852B8013DAE}.Release|Win32.ActiveCfg = Release|Win32 {C9FBA6FD-04AC-4B2F-8277-B852B8013DAE}.Release|Win32.Build.0 = Release|Win32 EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE EndGlobalSection EndGlobal ShInstUtil/ShInstUtil.cpp0000664000000000000000000002203113222431372014373 0ustar rootroot/* KeePass Password Safe - The Open-Source Password Manager Copyright (C) 2003-2018 Dominik Reichl This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ #include "ShInstUtil.h" #pragma warning(push) #pragma warning(disable: 4996) // SCL warning #include #include #pragma warning(pop) static const std_string g_strNGenInstall = _T("ngen_install"); static const std_string g_strNGenUninstall = _T("ngen_uninstall"); static const std_string g_strNetCheck = _T("net_check"); static const std_string g_strPreLoadRegister = _T("preload_register"); static const std_string g_strPreLoadUnregister = _T("preload_unregister"); static LPCTSTR g_lpPathTrimChars = _T("\"' \t\r\n"); int WINAPI _tWinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPTSTR lpCmdLine, int nCmdShow) { UNREFERENCED_PARAMETER(hInstance); UNREFERENCED_PARAMETER(hPrevInstance); UNREFERENCED_PARAMETER(lpCmdLine); UNREFERENCED_PARAMETER(nCmdShow); INITCOMMONCONTROLSEX icc; ZeroMemory(&icc, sizeof(INITCOMMONCONTROLSEX)); icc.dwSize = sizeof(INITCOMMONCONTROLSEX); icc.dwICC = ICC_STANDARD_CLASSES; InitCommonControlsEx(&icc); std_string strCmdLine = GetCommandLine(); boost::trim_if(strCmdLine, boost::is_any_of(g_lpPathTrimChars)); std::transform(strCmdLine.begin(), strCmdLine.end(), strCmdLine.begin(), tolower); if((strCmdLine.size() >= g_strNGenInstall.size()) && (strCmdLine.substr( strCmdLine.size() - g_strNGenInstall.size()) == g_strNGenInstall)) { UpdateNativeImage(false); Sleep(200); UpdateNativeImage(true); } if((strCmdLine.size() >= g_strNGenUninstall.size()) && (strCmdLine.substr( strCmdLine.size() - g_strNGenUninstall.size()) == g_strNGenUninstall)) { UpdateNativeImage(false); } if((strCmdLine.size() >= g_strPreLoadRegister.size()) && (strCmdLine.substr( strCmdLine.size() - g_strPreLoadRegister.size()) == g_strPreLoadRegister)) { RegisterPreLoad(true); } if((strCmdLine.size() >= g_strPreLoadUnregister.size()) && (strCmdLine.substr( strCmdLine.size() - g_strPreLoadUnregister.size()) == g_strPreLoadUnregister)) { RegisterPreLoad(false); } if((strCmdLine.size() >= g_strNetCheck.size()) && (strCmdLine.substr( strCmdLine.size() - g_strNetCheck.size()) == g_strNetCheck)) { CheckDotNetInstalled(); } return 0; } void UpdateNativeImage(bool bInstall) { const std_string strNGen = FindNGen(); if(strNGen.size() == 0) return; const std_string strKeePassExe = GetKeePassExePath(); if(strKeePassExe.size() == 0) return; std_string strParam = (bInstall ? _T("") : _T("un")); strParam += _T("install \""); strParam += strKeePassExe + _T("\""); SHELLEXECUTEINFO sei; ZeroMemory(&sei, sizeof(SHELLEXECUTEINFO)); sei.cbSize = sizeof(SHELLEXECUTEINFO); sei.fMask = SEE_MASK_NOCLOSEPROCESS; sei.lpVerb = _T("open"); sei.lpFile = strNGen.c_str(); sei.lpParameters = strParam.c_str(); sei.nShow = SW_HIDE; ShellExecuteEx(&sei); if(sei.hProcess != NULL) { WaitForSingleObject(sei.hProcess, 16000); CloseHandle(sei.hProcess); } } void RegisterPreLoad(bool bRegister) { const std_string strPath = GetKeePassExePath(); if(strPath.size() == 0) return; HKEY hKey = NULL; if(RegOpenKeyEx(HKEY_LOCAL_MACHINE, _T("Software\\Microsoft\\Windows\\CurrentVersion\\Run"), 0, KEY_WRITE, &hKey) != ERROR_SUCCESS) return; if(hKey == NULL) return; const std_string strItemName = _T("KeePass 2 PreLoad"); std_string strItemValue = _T("\""); strItemValue += strPath; strItemValue += _T("\" --preload"); if(bRegister) RegSetValueEx(hKey, strItemName.c_str(), 0, REG_SZ, (const BYTE*)strItemValue.c_str(), static_cast((strItemValue.size() + 1) * sizeof(TCHAR))); else RegDeleteValue(hKey, strItemName.c_str()); RegCloseKey(hKey); } std_string GetNetInstallRoot() { std_string str; HKEY hNet = NULL; LONG lRes = RegOpenKeyEx(HKEY_LOCAL_MACHINE, _T("SOFTWARE\\Microsoft\\.NETFramework"), 0, KEY_READ, &hNet); if((lRes != ERROR_SUCCESS) || (hNet == NULL)) return str; const DWORD cbData = 2050; BYTE pbData[cbData]; ZeroMemory(pbData, cbData * sizeof(BYTE)); DWORD dwData = cbData - 2; lRes = RegQueryValueEx(hNet, _T("InstallRoot"), NULL, NULL, pbData, &dwData); if(lRes == ERROR_SUCCESS) str = (LPCTSTR)(LPTSTR)pbData; RegCloseKey(hNet); return str; } std_string GetKeePassExePath() { const DWORD cbData = 2050; TCHAR tszName[cbData]; ZeroMemory(tszName, cbData * sizeof(TCHAR)); GetModuleFileName(NULL, tszName, cbData - 2); for(int i = static_cast(_tcslen(tszName)) - 1; i >= 0; --i) { if(tszName[i] == _T('\\')) break; else tszName[i] = 0; } std_string strPath = tszName; boost::trim_if(strPath, boost::is_any_of(g_lpPathTrimChars)); if(strPath.size() == 0) return strPath; return strPath + _T("KeePass.exe"); } void EnsureTerminatingSeparator(std_string& strPath) { if(strPath.size() == 0) return; if(strPath.c_str()[strPath.size() - 1] == _T('\\')) return; strPath += _T("\\"); } std_string FindNGen() { std_string strNGen; std_string strRoot = GetNetInstallRoot(); if(strRoot.size() == 0) return strNGen; EnsureTerminatingSeparator(strRoot); ULONGLONG ullVersion = 0; FindNGenRec(strRoot, strNGen, ullVersion); return strNGen; } #pragma warning(push) #pragma warning(disable: 4127) // Conditional expression is constant void FindNGenRec(const std_string& strPath, std_string& strNGenPath, ULONGLONG& ullVersion) { const std_string strSearch = strPath + _T("*.*"); const std_string strNGen = _T("ngen.exe"); WIN32_FIND_DATA wfd; ZeroMemory(&wfd, sizeof(WIN32_FIND_DATA)); HANDLE hFind = FindFirstFile(strSearch.c_str(), &wfd); if(hFind == INVALID_HANDLE_VALUE) return; while(true) { if((wfd.cFileName[0] == 0) || (_tcsicmp(wfd.cFileName, _T(".")) == 0) || (_tcsicmp(wfd.cFileName, _T("..")) == 0)) { } else if((wfd.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) != 0) FindNGenRec((strPath + wfd.cFileName) + _T("\\"), strNGenPath, ullVersion); else if(_tcsicmp(wfd.cFileName, strNGen.c_str()) == 0) { const std_string strFullPath = strPath + strNGen; const ULONGLONG ullThisVer = SiuGetFileVersion(strFullPath); if(ullThisVer >= ullVersion) { strNGenPath = strFullPath; ullVersion = ullThisVer; } } if(FindNextFile(hFind, &wfd) == FALSE) break; } FindClose(hFind); } #pragma warning(pop) ULONGLONG SiuGetFileVersion(const std_string& strFilePath) { DWORD dwDummy = 0; const DWORD dwVerSize = GetFileVersionInfoSize( strFilePath.c_str(), &dwDummy); if(dwVerSize == 0) return 0; boost::scoped_array vVerInfo(new BYTE[dwVerSize]); if(vVerInfo.get() == NULL) return 0; // Out of memory if(GetFileVersionInfo(strFilePath.c_str(), 0, dwVerSize, vVerInfo.get()) == FALSE) return 0; VS_FIXEDFILEINFO* pFileInfo = NULL; UINT uFixedInfoLen = 0; if(VerQueryValue(vVerInfo.get(), _T("\\"), (LPVOID*)&pFileInfo, &uFixedInfoLen) == FALSE) return 0; if(pFileInfo == NULL) return 0; return ((static_cast(pFileInfo->dwFileVersionMS) << 32) | static_cast(pFileInfo->dwFileVersionLS)); } void CheckDotNetInstalled() { OSVERSIONINFO osv; ZeroMemory(&osv, sizeof(OSVERSIONINFO)); osv.dwOSVersionInfoSize = sizeof(OSVERSIONINFO); GetVersionEx(&osv); if(osv.dwMajorVersion >= 6) return; // .NET ships with Vista and higher const std_string strNGen = FindNGen(); if(strNGen.size() == 0) { std_string strMsg = _T("KeePass 2.x requires the Microsoft .NET Framework >= 2.0, "); strMsg += _T("however this framework currently doesn't seem to be installed "); strMsg += _T("on your computer. Without this framework, KeePass will not run.\r\n\r\n"); strMsg += _T("The Microsoft .NET Framework is available as free download from the "); strMsg += _T("Microsoft website.\r\n\r\n"); strMsg += _T("Do you want to visit the Microsoft website now?"); const int nRes = MessageBox(NULL, strMsg.c_str(), _T("KeePass Setup"), MB_ICONQUESTION | MB_YESNO); if(nRes == IDYES) { SHELLEXECUTEINFO sei; ZeroMemory(&sei, sizeof(SHELLEXECUTEINFO)); sei.cbSize = sizeof(SHELLEXECUTEINFO); sei.lpVerb = _T("open"); sei.lpFile = _T("https://msdn.microsoft.com/en-us/netframework/aa569263.aspx"); sei.nShow = SW_SHOW; ShellExecuteEx(&sei); } } } ShInstUtil/ShInstUtil.rc0000664000000000000000000000533413225117166014231 0ustar rootroot// Microsoft Visual C++ generated resource script. // #include "resource.h" #define APSTUDIO_READONLY_SYMBOLS ///////////////////////////////////////////////////////////////////////////// // // Generated from the TEXTINCLUDE 2 resource. // #include "afxres.h" ///////////////////////////////////////////////////////////////////////////// #undef APSTUDIO_READONLY_SYMBOLS ///////////////////////////////////////////////////////////////////////////// // German (Germany) resources #if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_DEU) #ifdef _WIN32 LANGUAGE LANG_GERMAN, SUBLANG_GERMAN #pragma code_page(1252) #endif //_WIN32 #ifdef APSTUDIO_INVOKED ///////////////////////////////////////////////////////////////////////////// // // TEXTINCLUDE // 1 TEXTINCLUDE BEGIN "resource.h\0" END 2 TEXTINCLUDE BEGIN "#include ""afxres.h""\r\n" "\0" END 3 TEXTINCLUDE BEGIN "\r\n" "\0" END #endif // APSTUDIO_INVOKED #endif // German (Germany) resources ///////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////// // English (U.S.) resources #if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_ENU) #ifdef _WIN32 LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US #pragma code_page(1252) #endif //_WIN32 ///////////////////////////////////////////////////////////////////////////// // // Version // VS_VERSION_INFO VERSIONINFO FILEVERSION 2,38,0,0 PRODUCTVERSION 2,38,0,0 FILEFLAGSMASK 0x17L #ifdef _DEBUG FILEFLAGS 0x1L #else FILEFLAGS 0x0L #endif FILEOS 0x4L FILETYPE 0x1L FILESUBTYPE 0x0L BEGIN BLOCK "StringFileInfo" BEGIN BLOCK "040904b0" BEGIN VALUE "CompanyName", "Dominik Reichl" VALUE "FileDescription", "ShInstUtil - KeePass Helper Utility" VALUE "FileVersion", "2.38.0.0" VALUE "InternalName", "ShInstUtil" VALUE "LegalCopyright", "Copyright (c) 2007-2018 Dominik Reichl" VALUE "OriginalFilename", "ShInstUtil.exe" VALUE "ProductName", "ShInstUtil - KeePass Helper Utility" VALUE "ProductVersion", "2.38.0.0" END END BLOCK "VarFileInfo" BEGIN VALUE "Translation", 0x409, 1200 END END #endif // English (U.S.) resources ///////////////////////////////////////////////////////////////////////////// #ifndef APSTUDIO_INVOKED ///////////////////////////////////////////////////////////////////////////// // // Generated from the TEXTINCLUDE 3 resource. // ///////////////////////////////////////////////////////////////////////////// #endif // not APSTUDIO_INVOKED ShInstUtil/Resource.h0000664000000000000000000000062711247000604013563 0ustar rootroot//{{NO_DEPENDENCIES}} // Microsoft Visual C++ generated include file. // Used by ShInstUtil.rc // Nchste Standardwerte fr neue Objekte // #ifdef APSTUDIO_INVOKED #ifndef APSTUDIO_READONLY_SYMBOLS #define _APS_NEXT_RESOURCE_VALUE 101 #define _APS_NEXT_COMMAND_VALUE 40001 #define _APS_NEXT_CONTROL_VALUE 1001 #define _APS_NEXT_SYMED_VALUE 101 #endif #endif ShInstUtil/Resources/0000775000000000000000000000000012606740442013603 5ustar rootrootShInstUtil/Resources/TrustInfoManifest.xml0000664000000000000000000000064411247225200017743 0ustar rootroot ShInstUtil/ShInstUtil.vcproj0000664000000000000000000001053512167520112015120 0ustar rootroot ShInstUtil/ShInstUtil.h0000664000000000000000000000572313222431372014051 0ustar rootroot/* KeePass Password Safe - The Open-Source Password Manager Copyright (C) 2003-2018 Dominik Reichl This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ #ifndef ___SH_INST_UTIL_H___ #define ___SH_INST_UTIL_H___ #pragma once #ifndef VC_EXTRALEAN #define VC_EXTRALEAN #endif #ifndef WIN32_LEAN_AND_MEAN #define WIN32_LEAN_AND_MEAN #endif #ifndef WINVER #define WINVER 0x0501 #endif #ifndef _WIN32_WINNT #define _WIN32_WINNT 0x0501 #endif #ifndef _WIN32_WINDOWS #define _WIN32_WINDOWS 0x0410 #endif #ifndef _WIN32_IE #define _WIN32_IE 0x0600 #endif #ifndef MMNOMIDI #define MMNOMIDI #endif #ifndef MMNOAUX #define MMNOAUX #endif #ifndef MMNOMIXER #define MMNOMIXER #endif #if (_MSC_VER >= 1400) // Manifest linking #if defined(_M_IX86) #pragma comment(linker, "/manifestdependency:\"type='win32' " \ "name='Microsoft.Windows.Common-Controls' " \ "version='6.0.0.0' " \ "processorArchitecture='x86' " \ "publicKeyToken='6595b64144ccf1df' " \ "language='*'\"") #elif defined(_M_AMD64) #pragma comment(linker, "/manifestdependency:\"type='win32' " \ "name='Microsoft.Windows.Common-Controls' " \ "version='6.0.0.0' " \ "processorArchitecture='amd64' " \ "publicKeyToken='6595b64144ccf1df' " \ "language='*'\"") #elif defined(_M_IA64) #pragma comment(linker, "/manifestdependency:\"type='win32' " \ "name='Microsoft.Windows.Common-Controls' " \ "version='6.0.0.0' " \ "processorArchitecture='ia64' " \ "publicKeyToken='6595b64144ccf1df' " \ "language='*'\"") #endif #endif // (_MSC_VER >= 1400) #include #include #include #include #include #include #include typedef std::basic_string std_string; int WINAPI _tWinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPTSTR lpCmdLine, int nCmdShow); void UpdateNativeImage(bool bInstall); void RegisterPreLoad(bool bRegister); std_string GetNetInstallRoot(); std_string GetKeePassExePath(); void EnsureTerminatingSeparator(std_string& strPath); std_string FindNGen(); void FindNGenRec(const std_string& strPath, std_string& strNGenPath, ULONGLONG& ullVersion); ULONGLONG SiuGetFileVersion(const std_string& strFilePath); void CheckDotNetInstalled(); #endif // ___SH_INST_UTIL_H___ Translation/0000775000000000000000000000000013225117636012062 5ustar rootrootTranslation/TrlUtil/0000775000000000000000000000000013225117636013461 5ustar rootrootTranslation/TrlUtil/MainForm.Designer.cs0000664000000000000000000011421712172725654017272 0ustar rootrootnamespace TrlUtil { partial class MainForm { /// /// Erforderliche Designervariable. /// private System.ComponentModel.IContainer components = null; /// /// Verwendete Ressourcen bereinigen. /// /// True, wenn verwaltete Ressourcen gelöscht werden sollen; andernfalls False. protected override void Dispose(bool disposing) { if(disposing && (components != null)) { components.Dispose(); } base.Dispose(disposing); } #region Vom Windows Form-Designer generierter Code /// /// Erforderliche Methode für die Designerunterstützung. /// Der Inhalt der Methode darf nicht mit dem Code-Editor geändert werden. /// private void InitializeComponent() { System.ComponentModel.ComponentResourceManager resources = new System.ComponentModel.ComponentResourceManager(typeof(MainForm)); this.m_tabMain = new System.Windows.Forms.TabControl(); this.m_tabProps = new System.Windows.Forms.TabPage(); this.m_cbRtl = new System.Windows.Forms.CheckBox(); this.m_lblAuthorContact = new System.Windows.Forms.Label(); this.m_tbAuthorContact = new System.Windows.Forms.TextBox(); this.m_linkLangCode = new System.Windows.Forms.LinkLabel(); this.m_lblLangIDSample = new System.Windows.Forms.Label(); this.m_tbLangID = new System.Windows.Forms.TextBox(); this.m_lblLangID = new System.Windows.Forms.Label(); this.m_lblAuthorName = new System.Windows.Forms.Label(); this.m_tbAuthorName = new System.Windows.Forms.TextBox(); this.m_lblNameLclSample = new System.Windows.Forms.Label(); this.m_tbNameLcl = new System.Windows.Forms.TextBox(); this.m_lblNameLcl = new System.Windows.Forms.Label(); this.m_lblNameEngSample = new System.Windows.Forms.Label(); this.m_lblNameEng = new System.Windows.Forms.Label(); this.m_tbNameEng = new System.Windows.Forms.TextBox(); this.m_tabStrings = new System.Windows.Forms.TabPage(); this.m_lblStrSaveHint = new System.Windows.Forms.Label(); this.m_tbStrTrl = new System.Windows.Forms.TextBox(); this.m_tbStrEng = new System.Windows.Forms.TextBox(); this.m_lblStrTrl = new System.Windows.Forms.Label(); this.m_lblStrEng = new System.Windows.Forms.Label(); this.m_lvStrings = new KeePass.UI.CustomListViewEx(); this.m_tabDialogs = new System.Windows.Forms.TabPage(); this.m_lblIconColorHint = new System.Windows.Forms.Label(); this.m_grpControl = new System.Windows.Forms.GroupBox(); this.m_grpControlLayout = new System.Windows.Forms.GroupBox(); this.m_lblLayoutHint2 = new System.Windows.Forms.Label(); this.m_lblLayoutHint = new System.Windows.Forms.Label(); this.m_tbLayoutH = new System.Windows.Forms.TextBox(); this.m_tbLayoutW = new System.Windows.Forms.TextBox(); this.m_tbLayoutY = new System.Windows.Forms.TextBox(); this.m_tbLayoutX = new System.Windows.Forms.TextBox(); this.m_lblLayoutH = new System.Windows.Forms.Label(); this.m_lblLayoutW = new System.Windows.Forms.Label(); this.m_lblLayoutY = new System.Windows.Forms.Label(); this.m_lblLayoutX = new System.Windows.Forms.Label(); this.m_tbCtrlTrlText = new System.Windows.Forms.TextBox(); this.m_tbCtrlEngText = new System.Windows.Forms.TextBox(); this.m_lblCtrlTrlText = new System.Windows.Forms.Label(); this.m_lblCtrlEngText = new System.Windows.Forms.Label(); this.m_tvControls = new System.Windows.Forms.TreeView(); this.m_tabUnusedText = new System.Windows.Forms.TabPage(); this.m_btnClearUnusedText = new System.Windows.Forms.Button(); this.m_rtbUnusedText = new KeePass.UI.CustomRichTextBoxEx(); this.m_menuMain = new KeePass.UI.CustomMenuStripEx(); this.m_menuFile = new System.Windows.Forms.ToolStripMenuItem(); this.m_menuFileOpen = new System.Windows.Forms.ToolStripMenuItem(); this.m_menuFileSave = new System.Windows.Forms.ToolStripMenuItem(); this.m_menuFileSaveAs = new System.Windows.Forms.ToolStripMenuItem(); this.m_menuFileSep0 = new System.Windows.Forms.ToolStripSeparator(); this.m_menuFileImport = new System.Windows.Forms.ToolStripMenuItem(); this.m_menuFileImportLng = new System.Windows.Forms.ToolStripMenuItem(); this.m_menuFileImportPo = new System.Windows.Forms.ToolStripMenuItem(); this.m_menuFileImportSep0 = new System.Windows.Forms.ToolStripSeparator(); this.m_menuFileImport2xNoChecks = new System.Windows.Forms.ToolStripMenuItem(); this.m_menuFileSep1 = new System.Windows.Forms.ToolStripSeparator(); this.m_menuFileExit = new System.Windows.Forms.ToolStripMenuItem(); this.m_menuEdit = new System.Windows.Forms.ToolStripMenuItem(); this.m_menuEditNextUntrl = new System.Windows.Forms.ToolStripMenuItem(); this.m_tsMain = new KeePass.UI.CustomToolStripEx(); this.m_tbOpen = new System.Windows.Forms.ToolStripButton(); this.m_tbSave = new System.Windows.Forms.ToolStripButton(); this.m_tbSep0 = new System.Windows.Forms.ToolStripSeparator(); this.m_tbNextUntrl = new System.Windows.Forms.ToolStripButton(); this.m_tbSep1 = new System.Windows.Forms.ToolStripSeparator(); this.m_tbFind = new System.Windows.Forms.ToolStripTextBox(); this.m_tabMain.SuspendLayout(); this.m_tabProps.SuspendLayout(); this.m_tabStrings.SuspendLayout(); this.m_tabDialogs.SuspendLayout(); this.m_grpControl.SuspendLayout(); this.m_grpControlLayout.SuspendLayout(); this.m_tabUnusedText.SuspendLayout(); this.m_menuMain.SuspendLayout(); this.m_tsMain.SuspendLayout(); this.SuspendLayout(); // // m_tabMain // this.m_tabMain.Controls.Add(this.m_tabProps); this.m_tabMain.Controls.Add(this.m_tabStrings); this.m_tabMain.Controls.Add(this.m_tabDialogs); this.m_tabMain.Controls.Add(this.m_tabUnusedText); this.m_tabMain.Location = new System.Drawing.Point(12, 53); this.m_tabMain.Name = "m_tabMain"; this.m_tabMain.SelectedIndex = 0; this.m_tabMain.Size = new System.Drawing.Size(605, 461); this.m_tabMain.TabIndex = 0; this.m_tabMain.SelectedIndexChanged += new System.EventHandler(this.OnTabMainSelectedIndexChanged); // // m_tabProps // this.m_tabProps.Controls.Add(this.m_cbRtl); this.m_tabProps.Controls.Add(this.m_lblAuthorContact); this.m_tabProps.Controls.Add(this.m_tbAuthorContact); this.m_tabProps.Controls.Add(this.m_linkLangCode); this.m_tabProps.Controls.Add(this.m_lblLangIDSample); this.m_tabProps.Controls.Add(this.m_tbLangID); this.m_tabProps.Controls.Add(this.m_lblLangID); this.m_tabProps.Controls.Add(this.m_lblAuthorName); this.m_tabProps.Controls.Add(this.m_tbAuthorName); this.m_tabProps.Controls.Add(this.m_lblNameLclSample); this.m_tabProps.Controls.Add(this.m_tbNameLcl); this.m_tabProps.Controls.Add(this.m_lblNameLcl); this.m_tabProps.Controls.Add(this.m_lblNameEngSample); this.m_tabProps.Controls.Add(this.m_lblNameEng); this.m_tabProps.Controls.Add(this.m_tbNameEng); this.m_tabProps.Location = new System.Drawing.Point(4, 22); this.m_tabProps.Name = "m_tabProps"; this.m_tabProps.Padding = new System.Windows.Forms.Padding(3); this.m_tabProps.Size = new System.Drawing.Size(597, 435); this.m_tabProps.TabIndex = 0; this.m_tabProps.Text = "Properties"; this.m_tabProps.UseVisualStyleBackColor = true; // // m_cbRtl // this.m_cbRtl.AutoSize = true; this.m_cbRtl.Location = new System.Drawing.Point(9, 238); this.m_cbRtl.Name = "m_cbRtl"; this.m_cbRtl.Size = new System.Drawing.Size(149, 17); this.m_cbRtl.TabIndex = 14; this.m_cbRtl.Text = "Script is written right-to-left"; this.m_cbRtl.UseVisualStyleBackColor = true; // // m_lblAuthorContact // this.m_lblAuthorContact.AutoSize = true; this.m_lblAuthorContact.Location = new System.Drawing.Point(6, 206); this.m_lblAuthorContact.Name = "m_lblAuthorContact"; this.m_lblAuthorContact.Size = new System.Drawing.Size(80, 13); this.m_lblAuthorContact.TabIndex = 12; this.m_lblAuthorContact.Text = "Author contact:"; // // m_tbAuthorContact // this.m_tbAuthorContact.Location = new System.Drawing.Point(147, 203); this.m_tbAuthorContact.Name = "m_tbAuthorContact"; this.m_tbAuthorContact.Size = new System.Drawing.Size(435, 20); this.m_tbAuthorContact.TabIndex = 13; // // m_linkLangCode // this.m_linkLangCode.AutoSize = true; this.m_linkLangCode.Location = new System.Drawing.Point(144, 151); this.m_linkLangCode.Name = "m_linkLangCode"; this.m_linkLangCode.Size = new System.Drawing.Size(156, 13); this.m_linkLangCode.TabIndex = 9; this.m_linkLangCode.TabStop = true; this.m_linkLangCode.Text = "See ISO 639-1 language codes"; this.m_linkLangCode.LinkClicked += new System.Windows.Forms.LinkLabelLinkClickedEventHandler(this.OnLinkLangCodeClicked); // // m_lblLangIDSample // this.m_lblLangIDSample.AutoSize = true; this.m_lblLangIDSample.Location = new System.Drawing.Point(144, 135); this.m_lblLangIDSample.Name = "m_lblLangIDSample"; this.m_lblLangIDSample.Size = new System.Drawing.Size(65, 13); this.m_lblLangIDSample.TabIndex = 8; this.m_lblLangIDSample.Text = "Example: de"; // // m_tbLangID // this.m_tbLangID.Location = new System.Drawing.Point(147, 112); this.m_tbLangID.Name = "m_tbLangID"; this.m_tbLangID.Size = new System.Drawing.Size(435, 20); this.m_tbLangID.TabIndex = 7; // // m_lblLangID // this.m_lblLangID.AutoSize = true; this.m_lblLangID.Location = new System.Drawing.Point(6, 115); this.m_lblLangID.Name = "m_lblLangID"; this.m_lblLangID.Size = new System.Drawing.Size(132, 13); this.m_lblLangID.TabIndex = 6; this.m_lblLangID.Text = "ISO 639-1 language code:"; // // m_lblAuthorName // this.m_lblAuthorName.AutoSize = true; this.m_lblAuthorName.Location = new System.Drawing.Point(6, 180); this.m_lblAuthorName.Name = "m_lblAuthorName"; this.m_lblAuthorName.Size = new System.Drawing.Size(70, 13); this.m_lblAuthorName.TabIndex = 10; this.m_lblAuthorName.Text = "Author name:"; // // m_tbAuthorName // this.m_tbAuthorName.Location = new System.Drawing.Point(147, 177); this.m_tbAuthorName.Name = "m_tbAuthorName"; this.m_tbAuthorName.Size = new System.Drawing.Size(435, 20); this.m_tbAuthorName.TabIndex = 11; // // m_lblNameLclSample // this.m_lblNameLclSample.AutoSize = true; this.m_lblNameLclSample.Location = new System.Drawing.Point(144, 86); this.m_lblNameLclSample.Name = "m_lblNameLclSample"; this.m_lblNameLclSample.Size = new System.Drawing.Size(93, 13); this.m_lblNameLclSample.TabIndex = 5; this.m_lblNameLclSample.Text = "Example: Deutsch"; // // m_tbNameLcl // this.m_tbNameLcl.Location = new System.Drawing.Point(147, 63); this.m_tbNameLcl.Name = "m_tbNameLcl"; this.m_tbNameLcl.Size = new System.Drawing.Size(435, 20); this.m_tbNameLcl.TabIndex = 4; // // m_lblNameLcl // this.m_lblNameLcl.AutoSize = true; this.m_lblNameLcl.Location = new System.Drawing.Point(6, 66); this.m_lblNameLcl.Name = "m_lblNameLcl"; this.m_lblNameLcl.Size = new System.Drawing.Size(117, 13); this.m_lblNameLcl.TabIndex = 3; this.m_lblNameLcl.Text = "Native language name:"; // // m_lblNameEngSample // this.m_lblNameEngSample.AutoSize = true; this.m_lblNameEngSample.Location = new System.Drawing.Point(144, 38); this.m_lblNameEngSample.Name = "m_lblNameEngSample"; this.m_lblNameEngSample.Size = new System.Drawing.Size(90, 13); this.m_lblNameEngSample.TabIndex = 2; this.m_lblNameEngSample.Text = "Example: German"; // // m_lblNameEng // this.m_lblNameEng.AutoSize = true; this.m_lblNameEng.Location = new System.Drawing.Point(6, 18); this.m_lblNameEng.Name = "m_lblNameEng"; this.m_lblNameEng.Size = new System.Drawing.Size(120, 13); this.m_lblNameEng.TabIndex = 0; this.m_lblNameEng.Text = "English language name:"; // // m_tbNameEng // this.m_tbNameEng.Location = new System.Drawing.Point(147, 15); this.m_tbNameEng.Name = "m_tbNameEng"; this.m_tbNameEng.Size = new System.Drawing.Size(435, 20); this.m_tbNameEng.TabIndex = 1; // // m_tabStrings // this.m_tabStrings.Controls.Add(this.m_lblStrSaveHint); this.m_tabStrings.Controls.Add(this.m_tbStrTrl); this.m_tabStrings.Controls.Add(this.m_tbStrEng); this.m_tabStrings.Controls.Add(this.m_lblStrTrl); this.m_tabStrings.Controls.Add(this.m_lblStrEng); this.m_tabStrings.Controls.Add(this.m_lvStrings); this.m_tabStrings.Location = new System.Drawing.Point(4, 22); this.m_tabStrings.Name = "m_tabStrings"; this.m_tabStrings.Padding = new System.Windows.Forms.Padding(3); this.m_tabStrings.Size = new System.Drawing.Size(597, 435); this.m_tabStrings.TabIndex = 1; this.m_tabStrings.Text = "String Tables"; this.m_tabStrings.UseVisualStyleBackColor = true; // // m_lblStrSaveHint // this.m_lblStrSaveHint.AutoSize = true; this.m_lblStrSaveHint.Location = new System.Drawing.Point(66, 410); this.m_lblStrSaveHint.Name = "m_lblStrSaveHint"; this.m_lblStrSaveHint.Size = new System.Drawing.Size(248, 13); this.m_lblStrSaveHint.TabIndex = 5; this.m_lblStrSaveHint.Text = "Press [Return] to save/accept the translated string."; // // m_tbStrTrl // this.m_tbStrTrl.Location = new System.Drawing.Point(69, 387); this.m_tbStrTrl.Name = "m_tbStrTrl"; this.m_tbStrTrl.Size = new System.Drawing.Size(522, 20); this.m_tbStrTrl.TabIndex = 4; this.m_tbStrTrl.KeyDown += new System.Windows.Forms.KeyEventHandler(this.OnStrKeyDown); this.m_tbStrTrl.KeyUp += new System.Windows.Forms.KeyEventHandler(this.OnStrKeyUp); // // m_tbStrEng // this.m_tbStrEng.Location = new System.Drawing.Point(69, 328); this.m_tbStrEng.Multiline = true; this.m_tbStrEng.Name = "m_tbStrEng"; this.m_tbStrEng.ReadOnly = true; this.m_tbStrEng.ScrollBars = System.Windows.Forms.ScrollBars.Vertical; this.m_tbStrEng.Size = new System.Drawing.Size(522, 53); this.m_tbStrEng.TabIndex = 2; // // m_lblStrTrl // this.m_lblStrTrl.AutoSize = true; this.m_lblStrTrl.Location = new System.Drawing.Point(3, 390); this.m_lblStrTrl.Name = "m_lblStrTrl"; this.m_lblStrTrl.Size = new System.Drawing.Size(60, 13); this.m_lblStrTrl.TabIndex = 3; this.m_lblStrTrl.Text = "Translated:"; // // m_lblStrEng // this.m_lblStrEng.AutoSize = true; this.m_lblStrEng.Location = new System.Drawing.Point(3, 331); this.m_lblStrEng.Name = "m_lblStrEng"; this.m_lblStrEng.Size = new System.Drawing.Size(44, 13); this.m_lblStrEng.TabIndex = 1; this.m_lblStrEng.Text = "English:"; // // m_lvStrings // this.m_lvStrings.FullRowSelect = true; this.m_lvStrings.HeaderStyle = System.Windows.Forms.ColumnHeaderStyle.Nonclickable; this.m_lvStrings.HideSelection = false; this.m_lvStrings.Location = new System.Drawing.Point(6, 6); this.m_lvStrings.MultiSelect = false; this.m_lvStrings.Name = "m_lvStrings"; this.m_lvStrings.ShowItemToolTips = true; this.m_lvStrings.Size = new System.Drawing.Size(585, 316); this.m_lvStrings.TabIndex = 0; this.m_lvStrings.UseCompatibleStateImageBehavior = false; this.m_lvStrings.View = System.Windows.Forms.View.Details; this.m_lvStrings.SelectedIndexChanged += new System.EventHandler(this.OnStringsSelectedIndexChanged); this.m_lvStrings.DoubleClick += new System.EventHandler(this.OnStrDoubleClick); // // m_tabDialogs // this.m_tabDialogs.Controls.Add(this.m_lblIconColorHint); this.m_tabDialogs.Controls.Add(this.m_grpControl); this.m_tabDialogs.Controls.Add(this.m_tvControls); this.m_tabDialogs.Location = new System.Drawing.Point(4, 22); this.m_tabDialogs.Name = "m_tabDialogs"; this.m_tabDialogs.Size = new System.Drawing.Size(597, 435); this.m_tabDialogs.TabIndex = 2; this.m_tabDialogs.Text = "Dialogs"; this.m_tabDialogs.UseVisualStyleBackColor = true; // // m_lblIconColorHint // this.m_lblIconColorHint.AutoSize = true; this.m_lblIconColorHint.Location = new System.Drawing.Point(221, 407); this.m_lblIconColorHint.Name = "m_lblIconColorHint"; this.m_lblIconColorHint.Size = new System.Drawing.Size(307, 13); this.m_lblIconColorHint.TabIndex = 5; this.m_lblIconColorHint.Text = "In a correct translation, all icons in the tree on the left are green."; // // m_grpControl // this.m_grpControl.Controls.Add(this.m_grpControlLayout); this.m_grpControl.Controls.Add(this.m_tbCtrlTrlText); this.m_grpControl.Controls.Add(this.m_tbCtrlEngText); this.m_grpControl.Controls.Add(this.m_lblCtrlTrlText); this.m_grpControl.Controls.Add(this.m_lblCtrlEngText); this.m_grpControl.Location = new System.Drawing.Point(224, 6); this.m_grpControl.Name = "m_grpControl"; this.m_grpControl.Size = new System.Drawing.Size(367, 357); this.m_grpControl.TabIndex = 1; this.m_grpControl.TabStop = false; this.m_grpControl.Text = "Selected Control"; // // m_grpControlLayout // this.m_grpControlLayout.Controls.Add(this.m_lblLayoutHint2); this.m_grpControlLayout.Controls.Add(this.m_lblLayoutHint); this.m_grpControlLayout.Controls.Add(this.m_tbLayoutH); this.m_grpControlLayout.Controls.Add(this.m_tbLayoutW); this.m_grpControlLayout.Controls.Add(this.m_tbLayoutY); this.m_grpControlLayout.Controls.Add(this.m_tbLayoutX); this.m_grpControlLayout.Controls.Add(this.m_lblLayoutH); this.m_grpControlLayout.Controls.Add(this.m_lblLayoutW); this.m_grpControlLayout.Controls.Add(this.m_lblLayoutY); this.m_grpControlLayout.Controls.Add(this.m_lblLayoutX); this.m_grpControlLayout.Location = new System.Drawing.Point(9, 174); this.m_grpControlLayout.Name = "m_grpControlLayout"; this.m_grpControlLayout.Size = new System.Drawing.Size(352, 174); this.m_grpControlLayout.TabIndex = 4; this.m_grpControlLayout.TabStop = false; this.m_grpControlLayout.Text = "Layout"; // // m_lblLayoutHint2 // this.m_lblLayoutHint2.Location = new System.Drawing.Point(6, 127); this.m_lblLayoutHint2.Name = "m_lblLayoutHint2"; this.m_lblLayoutHint2.Size = new System.Drawing.Size(340, 40); this.m_lblLayoutHint2.TabIndex = 9; this.m_lblLayoutHint2.Text = "The values must be entered according to the \"en-US\" culture, i.e. the decimal poi" + "nt is represented by a dot (.), the negative sign is leading the number."; // // m_lblLayoutHint // this.m_lblLayoutHint.Location = new System.Drawing.Point(6, 77); this.m_lblLayoutHint.Name = "m_lblLayoutHint"; this.m_lblLayoutHint.Size = new System.Drawing.Size(340, 41); this.m_lblLayoutHint.TabIndex = 8; this.m_lblLayoutHint.Text = "All values need be entered in % relative to the current position/size. For exampl" + "e, entering -50 in the width field will shrink the control\'s width to half of it" + "s previous value."; // // m_tbLayoutH // this.m_tbLayoutH.Location = new System.Drawing.Point(246, 45); this.m_tbLayoutH.Name = "m_tbLayoutH"; this.m_tbLayoutH.Size = new System.Drawing.Size(100, 20); this.m_tbLayoutH.TabIndex = 7; this.m_tbLayoutH.TextChanged += new System.EventHandler(this.OnLayoutHeightTextChanged); // // m_tbLayoutW // this.m_tbLayoutW.Location = new System.Drawing.Point(53, 45); this.m_tbLayoutW.Name = "m_tbLayoutW"; this.m_tbLayoutW.Size = new System.Drawing.Size(100, 20); this.m_tbLayoutW.TabIndex = 5; this.m_tbLayoutW.TextChanged += new System.EventHandler(this.OnLayoutWidthTextChanged); // // m_tbLayoutY // this.m_tbLayoutY.Location = new System.Drawing.Point(246, 19); this.m_tbLayoutY.Name = "m_tbLayoutY"; this.m_tbLayoutY.Size = new System.Drawing.Size(100, 20); this.m_tbLayoutY.TabIndex = 3; this.m_tbLayoutY.TextChanged += new System.EventHandler(this.OnLayoutYTextChanged); // // m_tbLayoutX // this.m_tbLayoutX.Location = new System.Drawing.Point(53, 19); this.m_tbLayoutX.Name = "m_tbLayoutX"; this.m_tbLayoutX.Size = new System.Drawing.Size(100, 20); this.m_tbLayoutX.TabIndex = 1; this.m_tbLayoutX.TextChanged += new System.EventHandler(this.OnLayoutXTextChanged); // // m_lblLayoutH // this.m_lblLayoutH.AutoSize = true; this.m_lblLayoutH.Location = new System.Drawing.Point(199, 48); this.m_lblLayoutH.Name = "m_lblLayoutH"; this.m_lblLayoutH.Size = new System.Drawing.Size(41, 13); this.m_lblLayoutH.TabIndex = 6; this.m_lblLayoutH.Text = "Height:"; // // m_lblLayoutW // this.m_lblLayoutW.AutoSize = true; this.m_lblLayoutW.Location = new System.Drawing.Point(6, 48); this.m_lblLayoutW.Name = "m_lblLayoutW"; this.m_lblLayoutW.Size = new System.Drawing.Size(38, 13); this.m_lblLayoutW.TabIndex = 4; this.m_lblLayoutW.Text = "Width:"; // // m_lblLayoutY // this.m_lblLayoutY.AutoSize = true; this.m_lblLayoutY.Location = new System.Drawing.Point(199, 22); this.m_lblLayoutY.Name = "m_lblLayoutY"; this.m_lblLayoutY.Size = new System.Drawing.Size(17, 13); this.m_lblLayoutY.TabIndex = 2; this.m_lblLayoutY.Text = "Y:"; // // m_lblLayoutX // this.m_lblLayoutX.AutoSize = true; this.m_lblLayoutX.Location = new System.Drawing.Point(6, 22); this.m_lblLayoutX.Name = "m_lblLayoutX"; this.m_lblLayoutX.Size = new System.Drawing.Size(17, 13); this.m_lblLayoutX.TabIndex = 0; this.m_lblLayoutX.Text = "X:"; // // m_tbCtrlTrlText // this.m_tbCtrlTrlText.Location = new System.Drawing.Point(9, 113); this.m_tbCtrlTrlText.Name = "m_tbCtrlTrlText"; this.m_tbCtrlTrlText.Size = new System.Drawing.Size(352, 20); this.m_tbCtrlTrlText.TabIndex = 3; this.m_tbCtrlTrlText.TextChanged += new System.EventHandler(this.OnCtrlTrlTextChanged); this.m_tbCtrlTrlText.KeyDown += new System.Windows.Forms.KeyEventHandler(this.OnCtrlTrlTextKeyDown); this.m_tbCtrlTrlText.KeyUp += new System.Windows.Forms.KeyEventHandler(this.OnCtrlTrlTextKeyUp); // // m_tbCtrlEngText // this.m_tbCtrlEngText.Location = new System.Drawing.Point(9, 41); this.m_tbCtrlEngText.Multiline = true; this.m_tbCtrlEngText.Name = "m_tbCtrlEngText"; this.m_tbCtrlEngText.ReadOnly = true; this.m_tbCtrlEngText.ScrollBars = System.Windows.Forms.ScrollBars.Vertical; this.m_tbCtrlEngText.Size = new System.Drawing.Size(352, 53); this.m_tbCtrlEngText.TabIndex = 1; // // m_lblCtrlTrlText // this.m_lblCtrlTrlText.AutoSize = true; this.m_lblCtrlTrlText.Location = new System.Drawing.Point(6, 97); this.m_lblCtrlTrlText.Name = "m_lblCtrlTrlText"; this.m_lblCtrlTrlText.Size = new System.Drawing.Size(60, 13); this.m_lblCtrlTrlText.TabIndex = 2; this.m_lblCtrlTrlText.Text = "Translated:"; // // m_lblCtrlEngText // this.m_lblCtrlEngText.AutoSize = true; this.m_lblCtrlEngText.Location = new System.Drawing.Point(6, 25); this.m_lblCtrlEngText.Name = "m_lblCtrlEngText"; this.m_lblCtrlEngText.Size = new System.Drawing.Size(44, 13); this.m_lblCtrlEngText.TabIndex = 0; this.m_lblCtrlEngText.Text = "English:"; // // m_tvControls // this.m_tvControls.HideSelection = false; this.m_tvControls.Location = new System.Drawing.Point(6, 6); this.m_tvControls.Name = "m_tvControls"; this.m_tvControls.ShowNodeToolTips = true; this.m_tvControls.ShowRootLines = false; this.m_tvControls.Size = new System.Drawing.Size(200, 423); this.m_tvControls.TabIndex = 0; this.m_tvControls.AfterSelect += new System.Windows.Forms.TreeViewEventHandler(this.OnCustomControlsAfterSelect); // // m_tabUnusedText // this.m_tabUnusedText.Controls.Add(this.m_btnClearUnusedText); this.m_tabUnusedText.Controls.Add(this.m_rtbUnusedText); this.m_tabUnusedText.Location = new System.Drawing.Point(4, 22); this.m_tabUnusedText.Name = "m_tabUnusedText"; this.m_tabUnusedText.Padding = new System.Windows.Forms.Padding(3); this.m_tabUnusedText.Size = new System.Drawing.Size(597, 435); this.m_tabUnusedText.TabIndex = 3; this.m_tabUnusedText.Text = "Unused Text"; this.m_tabUnusedText.UseVisualStyleBackColor = true; // // m_btnClearUnusedText // this.m_btnClearUnusedText.Location = new System.Drawing.Point(516, 406); this.m_btnClearUnusedText.Name = "m_btnClearUnusedText"; this.m_btnClearUnusedText.Size = new System.Drawing.Size(75, 23); this.m_btnClearUnusedText.TabIndex = 1; this.m_btnClearUnusedText.Text = "&Clear"; this.m_btnClearUnusedText.UseVisualStyleBackColor = true; this.m_btnClearUnusedText.Click += new System.EventHandler(this.OnBtnClearUnusedText); // // m_rtbUnusedText // this.m_rtbUnusedText.Location = new System.Drawing.Point(6, 6); this.m_rtbUnusedText.Name = "m_rtbUnusedText"; this.m_rtbUnusedText.Size = new System.Drawing.Size(585, 394); this.m_rtbUnusedText.TabIndex = 0; this.m_rtbUnusedText.Text = ""; // // m_menuMain // this.m_menuMain.Items.AddRange(new System.Windows.Forms.ToolStripItem[] { this.m_menuFile, this.m_menuEdit}); this.m_menuMain.Location = new System.Drawing.Point(0, 0); this.m_menuMain.Name = "m_menuMain"; this.m_menuMain.Size = new System.Drawing.Size(629, 24); this.m_menuMain.TabIndex = 1; this.m_menuMain.TabStop = true; // // m_menuFile // this.m_menuFile.DropDownItems.AddRange(new System.Windows.Forms.ToolStripItem[] { this.m_menuFileOpen, this.m_menuFileSave, this.m_menuFileSaveAs, this.m_menuFileSep0, this.m_menuFileImport, this.m_menuFileSep1, this.m_menuFileExit}); this.m_menuFile.Name = "m_menuFile"; this.m_menuFile.Size = new System.Drawing.Size(39, 20); this.m_menuFile.Text = "&File"; // // m_menuFileOpen // this.m_menuFileOpen.Image = global::TrlUtil.Properties.Resources.B16x16_Folder_Yellow_Open; this.m_menuFileOpen.Name = "m_menuFileOpen"; this.m_menuFileOpen.ShortcutKeys = ((System.Windows.Forms.Keys)((System.Windows.Forms.Keys.Control | System.Windows.Forms.Keys.O))); this.m_menuFileOpen.Size = new System.Drawing.Size(154, 22); this.m_menuFileOpen.Text = "&Open..."; this.m_menuFileOpen.Click += new System.EventHandler(this.OnFileOpen); // // m_menuFileSave // this.m_menuFileSave.Image = global::TrlUtil.Properties.Resources.B16x16_FileSave; this.m_menuFileSave.Name = "m_menuFileSave"; this.m_menuFileSave.ShortcutKeys = ((System.Windows.Forms.Keys)((System.Windows.Forms.Keys.Control | System.Windows.Forms.Keys.S))); this.m_menuFileSave.Size = new System.Drawing.Size(154, 22); this.m_menuFileSave.Text = "&Save"; this.m_menuFileSave.Click += new System.EventHandler(this.OnFileSave); // // m_menuFileSaveAs // this.m_menuFileSaveAs.Image = global::TrlUtil.Properties.Resources.B16x16_FileSaveAs; this.m_menuFileSaveAs.Name = "m_menuFileSaveAs"; this.m_menuFileSaveAs.Size = new System.Drawing.Size(154, 22); this.m_menuFileSaveAs.Text = "Save &As..."; this.m_menuFileSaveAs.Click += new System.EventHandler(this.OnFileSaveAs); // // m_menuFileSep0 // this.m_menuFileSep0.Name = "m_menuFileSep0"; this.m_menuFileSep0.Size = new System.Drawing.Size(151, 6); // // m_menuFileImport // this.m_menuFileImport.DropDownItems.AddRange(new System.Windows.Forms.ToolStripItem[] { this.m_menuFileImportLng, this.m_menuFileImportPo, this.m_menuFileImportSep0, this.m_menuFileImport2xNoChecks}); this.m_menuFileImport.Name = "m_menuFileImport"; this.m_menuFileImport.Size = new System.Drawing.Size(154, 22); this.m_menuFileImport.Text = "&Import"; // // m_menuFileImportLng // this.m_menuFileImportLng.Name = "m_menuFileImportLng"; this.m_menuFileImportLng.Size = new System.Drawing.Size(311, 22); this.m_menuFileImportLng.Text = "KeePass &1.x LNG File..."; this.m_menuFileImportLng.Click += new System.EventHandler(this.OnImport1xLng); // // m_menuFileImportPo // this.m_menuFileImportPo.Name = "m_menuFileImportPo"; this.m_menuFileImportPo.Size = new System.Drawing.Size(311, 22); this.m_menuFileImportPo.Text = "&PO File..."; this.m_menuFileImportPo.Click += new System.EventHandler(this.OnImportPo); // // m_menuFileImportSep0 // this.m_menuFileImportSep0.Name = "m_menuFileImportSep0"; this.m_menuFileImportSep0.Size = new System.Drawing.Size(308, 6); // // m_menuFileImport2xNoChecks // this.m_menuFileImport2xNoChecks.Name = "m_menuFileImport2xNoChecks"; this.m_menuFileImport2xNoChecks.Size = new System.Drawing.Size(311, 22); this.m_menuFileImport2xNoChecks.Text = "KeePass &2.x LNGX File (No Base Checks)..."; this.m_menuFileImport2xNoChecks.Click += new System.EventHandler(this.OnImport2xNoChecks); // // m_menuFileSep1 // this.m_menuFileSep1.Name = "m_menuFileSep1"; this.m_menuFileSep1.Size = new System.Drawing.Size(151, 6); // // m_menuFileExit // this.m_menuFileExit.Name = "m_menuFileExit"; this.m_menuFileExit.Size = new System.Drawing.Size(154, 22); this.m_menuFileExit.Text = "&Exit"; this.m_menuFileExit.Click += new System.EventHandler(this.OnFileExit); // // m_menuEdit // this.m_menuEdit.DropDownItems.AddRange(new System.Windows.Forms.ToolStripItem[] { this.m_menuEditNextUntrl}); this.m_menuEdit.Name = "m_menuEdit"; this.m_menuEdit.Size = new System.Drawing.Size(40, 20); this.m_menuEdit.Text = "&Edit"; // // m_menuEditNextUntrl // this.m_menuEditNextUntrl.Image = global::TrlUtil.Properties.Resources.B16x16_Down; this.m_menuEditNextUntrl.Name = "m_menuEditNextUntrl"; this.m_menuEditNextUntrl.ShortcutKeys = ((System.Windows.Forms.Keys)((System.Windows.Forms.Keys.Control | System.Windows.Forms.Keys.U))); this.m_menuEditNextUntrl.Size = new System.Drawing.Size(245, 22); this.m_menuEditNextUntrl.Text = "Go to Next &Untranslated"; this.m_menuEditNextUntrl.Click += new System.EventHandler(this.OnEditNextUntrl); // // m_tsMain // this.m_tsMain.Items.AddRange(new System.Windows.Forms.ToolStripItem[] { this.m_tbOpen, this.m_tbSave, this.m_tbSep0, this.m_tbNextUntrl, this.m_tbSep1, this.m_tbFind}); this.m_tsMain.Location = new System.Drawing.Point(0, 24); this.m_tsMain.Name = "m_tsMain"; this.m_tsMain.Size = new System.Drawing.Size(629, 25); this.m_tsMain.TabIndex = 2; this.m_tsMain.TabStop = true; // // m_tbOpen // this.m_tbOpen.DisplayStyle = System.Windows.Forms.ToolStripItemDisplayStyle.Image; this.m_tbOpen.Image = global::TrlUtil.Properties.Resources.B16x16_Folder_Yellow_Open; this.m_tbOpen.ImageTransparentColor = System.Drawing.Color.Magenta; this.m_tbOpen.Name = "m_tbOpen"; this.m_tbOpen.Size = new System.Drawing.Size(23, 22); this.m_tbOpen.Text = "Open... (Ctrl+O)"; this.m_tbOpen.Click += new System.EventHandler(this.OnFileOpen); // // m_tbSave // this.m_tbSave.DisplayStyle = System.Windows.Forms.ToolStripItemDisplayStyle.Image; this.m_tbSave.Image = global::TrlUtil.Properties.Resources.B16x16_FileSave; this.m_tbSave.ImageTransparentColor = System.Drawing.Color.Magenta; this.m_tbSave.Name = "m_tbSave"; this.m_tbSave.Size = new System.Drawing.Size(23, 22); this.m_tbSave.Text = "Save (Ctrl+S)"; this.m_tbSave.Click += new System.EventHandler(this.OnFileSave); // // m_tbSep0 // this.m_tbSep0.Name = "m_tbSep0"; this.m_tbSep0.Size = new System.Drawing.Size(6, 25); // // m_tbNextUntrl // this.m_tbNextUntrl.DisplayStyle = System.Windows.Forms.ToolStripItemDisplayStyle.Image; this.m_tbNextUntrl.Image = global::TrlUtil.Properties.Resources.B16x16_Down; this.m_tbNextUntrl.ImageTransparentColor = System.Drawing.Color.Magenta; this.m_tbNextUntrl.Name = "m_tbNextUntrl"; this.m_tbNextUntrl.Size = new System.Drawing.Size(23, 22); this.m_tbNextUntrl.Text = "Go to Next Untranslated (Ctrl+U)"; this.m_tbNextUntrl.Click += new System.EventHandler(this.OnEditNextUntrl); // // m_tbSep1 // this.m_tbSep1.Name = "m_tbSep1"; this.m_tbSep1.Size = new System.Drawing.Size(6, 25); // // m_tbFind // this.m_tbFind.AcceptsReturn = true; this.m_tbFind.Name = "m_tbFind"; this.m_tbFind.Size = new System.Drawing.Size(180, 25); this.m_tbFind.KeyDown += new System.Windows.Forms.KeyEventHandler(this.OnFindKeyDown); this.m_tbFind.KeyUp += new System.Windows.Forms.KeyEventHandler(this.OnFindKeyUp); this.m_tbFind.TextChanged += new System.EventHandler(this.OnFindTextChanged); // // MainForm // this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F); this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; this.ClientSize = new System.Drawing.Size(629, 526); this.Controls.Add(this.m_tsMain); this.Controls.Add(this.m_tabMain); this.Controls.Add(this.m_menuMain); this.FormBorderStyle = System.Windows.Forms.FormBorderStyle.FixedDialog; this.Icon = ((System.Drawing.Icon)(resources.GetObject("$this.Icon"))); this.MainMenuStrip = this.m_menuMain; this.MaximizeBox = false; this.Name = "MainForm"; this.Text = "KeePass Translation Utility"; this.Load += new System.EventHandler(this.OnFormLoad); this.m_tabMain.ResumeLayout(false); this.m_tabProps.ResumeLayout(false); this.m_tabProps.PerformLayout(); this.m_tabStrings.ResumeLayout(false); this.m_tabStrings.PerformLayout(); this.m_tabDialogs.ResumeLayout(false); this.m_tabDialogs.PerformLayout(); this.m_grpControl.ResumeLayout(false); this.m_grpControl.PerformLayout(); this.m_grpControlLayout.ResumeLayout(false); this.m_grpControlLayout.PerformLayout(); this.m_tabUnusedText.ResumeLayout(false); this.m_menuMain.ResumeLayout(false); this.m_menuMain.PerformLayout(); this.m_tsMain.ResumeLayout(false); this.m_tsMain.PerformLayout(); this.ResumeLayout(false); this.PerformLayout(); } #endregion private System.Windows.Forms.TabControl m_tabMain; private System.Windows.Forms.TabPage m_tabProps; private System.Windows.Forms.TabPage m_tabStrings; private System.Windows.Forms.TabPage m_tabDialogs; private System.Windows.Forms.Label m_lblNameLclSample; private System.Windows.Forms.TextBox m_tbNameLcl; private System.Windows.Forms.Label m_lblNameLcl; private System.Windows.Forms.Label m_lblNameEngSample; private System.Windows.Forms.Label m_lblNameEng; private System.Windows.Forms.TextBox m_tbNameEng; private System.Windows.Forms.Label m_lblLangIDSample; private System.Windows.Forms.TextBox m_tbLangID; private System.Windows.Forms.Label m_lblLangID; private System.Windows.Forms.Label m_lblAuthorName; private System.Windows.Forms.TextBox m_tbAuthorName; private System.Windows.Forms.LinkLabel m_linkLangCode; private System.Windows.Forms.Label m_lblAuthorContact; private System.Windows.Forms.TextBox m_tbAuthorContact; private KeePass.UI.CustomMenuStripEx m_menuMain; private System.Windows.Forms.ToolStripMenuItem m_menuFile; private System.Windows.Forms.ToolStripMenuItem m_menuFileOpen; private System.Windows.Forms.ToolStripMenuItem m_menuFileSave; private System.Windows.Forms.ToolStripSeparator m_menuFileSep0; private System.Windows.Forms.ToolStripMenuItem m_menuFileExit; private KeePass.UI.CustomListViewEx m_lvStrings; private System.Windows.Forms.TextBox m_tbStrTrl; private System.Windows.Forms.TextBox m_tbStrEng; private System.Windows.Forms.Label m_lblStrTrl; private System.Windows.Forms.Label m_lblStrEng; private System.Windows.Forms.Label m_lblStrSaveHint; private System.Windows.Forms.ToolStripMenuItem m_menuFileSaveAs; private System.Windows.Forms.TreeView m_tvControls; private System.Windows.Forms.GroupBox m_grpControl; private System.Windows.Forms.Label m_lblCtrlEngText; private System.Windows.Forms.TextBox m_tbCtrlTrlText; private System.Windows.Forms.TextBox m_tbCtrlEngText; private System.Windows.Forms.Label m_lblCtrlTrlText; private System.Windows.Forms.GroupBox m_grpControlLayout; private System.Windows.Forms.TextBox m_tbLayoutH; private System.Windows.Forms.TextBox m_tbLayoutW; private System.Windows.Forms.TextBox m_tbLayoutY; private System.Windows.Forms.TextBox m_tbLayoutX; private System.Windows.Forms.Label m_lblLayoutH; private System.Windows.Forms.Label m_lblLayoutW; private System.Windows.Forms.Label m_lblLayoutY; private System.Windows.Forms.Label m_lblLayoutX; private System.Windows.Forms.Label m_lblLayoutHint2; private System.Windows.Forms.Label m_lblLayoutHint; private System.Windows.Forms.Label m_lblIconColorHint; private System.Windows.Forms.TabPage m_tabUnusedText; private System.Windows.Forms.Button m_btnClearUnusedText; private KeePass.UI.CustomRichTextBoxEx m_rtbUnusedText; private System.Windows.Forms.ToolStripMenuItem m_menuFileImport; private System.Windows.Forms.ToolStripMenuItem m_menuFileImportLng; private System.Windows.Forms.ToolStripSeparator m_menuFileSep1; private KeePass.UI.CustomToolStripEx m_tsMain; private System.Windows.Forms.ToolStripButton m_tbOpen; private System.Windows.Forms.ToolStripButton m_tbSave; private System.Windows.Forms.ToolStripSeparator m_tbSep0; private System.Windows.Forms.ToolStripTextBox m_tbFind; private System.Windows.Forms.ToolStripSeparator m_menuFileImportSep0; private System.Windows.Forms.ToolStripMenuItem m_menuFileImport2xNoChecks; private System.Windows.Forms.CheckBox m_cbRtl; private System.Windows.Forms.ToolStripMenuItem m_menuFileImportPo; private System.Windows.Forms.ToolStripSeparator m_tbSep1; private System.Windows.Forms.ToolStripButton m_tbNextUntrl; private System.Windows.Forms.ToolStripMenuItem m_menuEdit; private System.Windows.Forms.ToolStripMenuItem m_menuEditNextUntrl; } } Translation/TrlUtil/AccelKeysCheck.cs0000664000000000000000000001057313222430420016601 0ustar rootroot/* KeePass Password Safe - The Open-Source Password Manager Copyright (C) 2003-2018 Dominik Reichl This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ using System; using System.Collections.Generic; using System.Text; using System.Windows.Forms; using System.Diagnostics; using KeePassLib.Translation; using KeePassLib.Utility; namespace TrlUtil { public static class AccelKeysCheck { private static char GetAccelKey(string strText) { if(strText == null) { Debug.Assert(false); return char.MinValue; } if(strText.Length == 0) return char.MinValue; strText = strText.Replace(@"&&", string.Empty); Debug.Assert(strText.IndexOf('&') == strText.LastIndexOf('&')); int nIndex = strText.IndexOf('&'); Debug.Assert(nIndex != (strText.Length - 1)); if((nIndex >= 0) && (nIndex < (strText.Length - 1))) return char.ToUpper(strText[nIndex + 1]); return char.MinValue; } public static string Validate(KPTranslation trl) { if(trl == null) { Debug.Assert(false); return null; } foreach(KPFormCustomization kpfc in trl.Forms) { string str = Validate(kpfc); if(str != null) return str; } return null; } private static string Validate(KPFormCustomization kpfc) { if(kpfc == null) { Debug.Assert(false); return null; } if(kpfc.FormEnglish == null) { Debug.Assert(false); return null; } string str = Validate(kpfc, kpfc.FormEnglish, null); if(str != null) return str; return null; } private static string Validate(KPFormCustomization kpfc, Control c, Dictionary dictParent) { if(kpfc == null) { Debug.Assert(false); return null; } if(kpfc.FormEnglish == null) { Debug.Assert(false); return null; } if(c == null) { Debug.Assert(false); return null; } Dictionary dictAccel = new Dictionary(); foreach(Control cSub in c.Controls) { string strText = Translate(kpfc, cSub); char chKey = GetAccelKey(strText); if(chKey == char.MinValue) continue; string strId = kpfc.FullName + "." + cSub.Name + " - \"" + strText + "\""; bool bCollides = dictAccel.ContainsKey(chKey); bool bCollidesParent = ((dictParent != null) ? dictParent.ContainsKey(chKey) : false); if(bCollides || bCollidesParent) { string strMsg = "Key " + chKey.ToString() + ":"; strMsg += MessageService.NewLine; strMsg += (bCollides ? dictAccel[chKey] : dictParent[chKey]); strMsg += MessageService.NewLine + strId; return strMsg; } dictAccel.Add(chKey, strId); } Dictionary dictSub = MergeDictionaries(dictParent, dictAccel); foreach(Control cSub in c.Controls) { string str = Validate(kpfc, cSub, dictSub); if(str != null) return str; } return null; } private static string Translate(KPFormCustomization kpfc, Control c) { string strName = c.Name; if(string.IsNullOrEmpty(strName)) return string.Empty; foreach(KPControlCustomization cc in kpfc.Controls) { if(cc.Name == strName) { if(!string.IsNullOrEmpty(cc.TextEnglish)) { Debug.Assert(c.Text == cc.TextEnglish); } return cc.Text; } } return c.Text; } private static Dictionary MergeDictionaries( Dictionary x, Dictionary y) { Dictionary d = new Dictionary(); if(x != null) { foreach(KeyValuePair kvp in x) d[kvp.Key] = kvp.Value; } if(y != null) { foreach(KeyValuePair kvp in y) d[kvp.Key] = kvp.Value; } return d; } } } Translation/TrlUtil/PreviewForm.cs0000664000000000000000000001124413222430420016241 0ustar rootroot/* KeePass Password Safe - The Open-Source Password Manager Copyright (C) 2003-2018 Dominik Reichl This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ using System; using System.Collections.Generic; using System.Diagnostics; using System.Drawing; using System.Reflection; using System.Text; using System.Windows.Forms; using KeePass.UI; using KeePassLib.Cryptography; namespace TrlUtil { public sealed class PreviewForm : Form { private static Random m_rand = CryptoRandom.NewWeakRandom(); public PreviewForm() { try { this.DoubleBuffered = true; } catch(Exception) { Debug.Assert(false); } } protected override void OnKeyDown(KeyEventArgs e) { if(e.KeyCode == Keys.Escape) UIUtil.SetHandled(e, true); else base.OnKeyDown(e); } protected override void OnKeyUp(KeyEventArgs e) { if(e.KeyCode == Keys.Escape) UIUtil.SetHandled(e, true); else base.OnKeyUp(e); } public void CopyForm(Form f) { this.SuspendLayout(); this.MinimizeBox = false; this.MaximizeBox = false; this.ControlBox = false; this.FormBorderStyle = FormBorderStyle.FixedDialog; this.Controls.Clear(); this.ClientSize = f.ClientSize; this.Text = f.Text; CopyChildControls(this, f); this.ResumeLayout(true); } private void CopyChildControls(Control cDest, Control cSource) { if((cDest == null) || (cSource == null)) return; foreach(Control c in cSource.Controls) { Type t = c.GetType(); Control cCopy; bool bCopyChilds = true; if(t == typeof(Button)) cCopy = new Button(); else if(t == typeof(Label)) { cCopy = new Label(); // (cCopy as Label).AutoSize = (c as Label).AutoSize; } else if(t == typeof(CheckBox)) cCopy = new CheckBox(); else if(t == typeof(RadioButton)) cCopy = new RadioButton(); else if(t == typeof(GroupBox)) cCopy = new GroupBox(); // NumericUpDown leads to GDI objects leak // else if(t == typeof(NumericUpDown)) cCopy = new NumericUpDown(); else if(t == typeof(Panel)) cCopy = new Panel(); else if(t == typeof(TabControl)) cCopy = new TabControl(); else if(t == typeof(TabPage)) cCopy = new TabPage(); else if(t == typeof(ComboBox)) { cCopy = new ComboBox(); (cCopy as ComboBox).DropDownStyle = (c as ComboBox).DropDownStyle; } else if(t == typeof(PromptedTextBox)) { cCopy = new PromptedTextBox(); (cCopy as PromptedTextBox).Multiline = (c as PromptedTextBox).Multiline; } else if(t == typeof(TextBox)) { cCopy = new TextBox(); (cCopy as TextBox).Multiline = (c as TextBox).Multiline; } else if((t == typeof(RichTextBox)) || // RTB leads to GDI objects leak (t == typeof(CustomRichTextBoxEx))) { cCopy = new TextBox(); (cCopy as TextBox).Multiline = true; } else { cCopy = new Label(); bCopyChilds = false; } Color clr = Color.FromArgb(128 + m_rand.Next(0, 128), 128 + m_rand.Next(0, 128), 128 + m_rand.Next(0, 128)); cCopy.Name = c.Name; cCopy.Font = c.Font; cCopy.BackColor = clr; cCopy.Text = c.Text; // Type tCopy = cCopy.GetType(); // PropertyInfo piAutoSizeSrc = t.GetProperty("AutoSize", typeof(bool)); // PropertyInfo piAutoSizeDst = tCopy.GetProperty("AutoSize", typeof(bool)); // if((piAutoSizeSrc != null) && (piAutoSizeDst != null)) // { // MethodInfo miSrc = piAutoSizeSrc.GetGetMethod(); // MethodInfo miDst = piAutoSizeDst.GetSetMethod(); // miDst.Invoke(cCopy, new object[] { miSrc.Invoke(c, null) }); // } cCopy.AutoSize = c.AutoSize; cCopy.Location = c.Location; cCopy.Size = c.Size; // Debug.Assert(cCopy.ClientSize == c.ClientSize); if(c.Dock != DockStyle.None) cCopy.Dock = c.Dock; try { cDest.Controls.Add(cCopy); if(bCopyChilds) CopyChildControls(cCopy, c); } catch(Exception) { Debug.Assert(false); } } } } } Translation/TrlUtil/Program.cs0000664000000000000000000001446113222430420015407 0ustar rootroot/* KeePass Password Safe - The Open-Source Password Manager Copyright (C) 2003-2018 Dominik Reichl This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ using System; using System.Collections.Generic; using System.Windows.Forms; using System.Text; using System.IO; using System.IO.Compression; using System.Xml; using KeePassLib.Utility; namespace TrlUtil { public static class Program { [STAThread] public static void Main(string[] args) { Application.EnableVisualStyles(); Application.SetCompatibleTextRenderingDefault(false); if((args != null) && (args.Length == 2)) { try { ExecuteCmd(args[0], args[1]); } catch(Exception exCmd) { MessageBox.Show(exCmd.Message, "TrlUtil", MessageBoxButtons.OK, MessageBoxIcon.Warning); } return; } Application.Run(new MainForm()); } private static void ExecuteCmd(string strCmd, string strFile) { if(strCmd == "convert_resx") { StreamWriter swOut = new StreamWriter(strFile + ".lng.xml", false, new UTF8Encoding(false)); XmlDocument xmlIn = new XmlDocument(); xmlIn.Load(strFile); foreach(XmlNode xmlChild in xmlIn.DocumentElement.ChildNodes) { if(xmlChild.Name != "data") continue; swOut.Write("\r\n\t" + xmlChild.SelectSingleNode("value").InnerXml + "\r\n\r\n"); } swOut.Close(); } /* else if(strCmd == "compress") { byte[] pbData = File.ReadAllBytes(strFile); FileStream fs = new FileStream(strFile + ".lngx", FileMode.Create, FileAccess.Write, FileShare.None); GZipStream gz = new GZipStream(fs, CompressionMode.Compress); gz.Write(pbData, 0, pbData.Length); gz.Close(); fs.Close(); } */ else if(strCmd == "src_from_xml") { XmlDocument xmlIn = new XmlDocument(); xmlIn.Load(strFile); foreach(XmlNode xmlTable in xmlIn.DocumentElement.SelectNodes("StringTable")) { StreamWriter swOut = new StreamWriter(xmlTable.Attributes["Name"].Value + ".Generated.cs", false, new UTF8Encoding(false)); swOut.WriteLine("// This is a generated file!"); swOut.WriteLine("// Do not edit manually, changes will be overwritten."); swOut.WriteLine(); swOut.WriteLine("using System;"); swOut.WriteLine("using System.Collections.Generic;"); swOut.WriteLine(); swOut.WriteLine("namespace " + xmlTable.Attributes["Namespace"].Value); swOut.WriteLine("{"); swOut.WriteLine("\t/// "); swOut.WriteLine("\t/// A strongly-typed resource class, for looking up localized strings, etc."); swOut.WriteLine("\t/// "); swOut.WriteLine("\tpublic static class " + xmlTable.Attributes["Name"].Value); swOut.WriteLine("\t{"); swOut.WriteLine("\t\tprivate static string TryGetEx(Dictionary dictNew,"); swOut.WriteLine("\t\t\tstring strName, string strDefault)"); swOut.WriteLine("\t\t{"); swOut.WriteLine("\t\t\tstring strTemp;"); swOut.WriteLine(); swOut.WriteLine("\t\t\tif(dictNew.TryGetValue(strName, out strTemp))"); swOut.WriteLine("\t\t\t\treturn strTemp;"); swOut.WriteLine(); swOut.WriteLine("\t\t\treturn strDefault;"); swOut.WriteLine("\t\t}"); swOut.WriteLine(); swOut.WriteLine("\t\tpublic static void SetTranslatedStrings(Dictionary dictNew)"); swOut.WriteLine("\t\t{"); swOut.WriteLine("\t\t\tif(dictNew == null) throw new ArgumentNullException(\"dictNew\");"); swOut.WriteLine(); foreach(XmlNode xmlData in xmlTable.SelectNodes("Data")) { string strName = xmlData.Attributes["Name"].Value; swOut.WriteLine("\t\t\tm_str" + strName + " = TryGetEx(dictNew, \"" + strName + "\", m_str" + strName + ");"); } swOut.WriteLine("\t\t}"); swOut.WriteLine(); swOut.WriteLine("\t\tprivate static readonly string[] m_vKeyNames = {"); XmlNodeList xNodes = xmlTable.SelectNodes("Data"); for(int i = 0; i < xNodes.Count; ++i) { XmlNode xmlData = xNodes.Item(i); swOut.WriteLine("\t\t\t\"" + xmlData.Attributes["Name"].Value + "\"" + ((i != xNodes.Count - 1) ? "," : string.Empty)); } swOut.WriteLine("\t\t};"); swOut.WriteLine(); swOut.WriteLine("\t\tpublic static string[] GetKeyNames()"); swOut.WriteLine("\t\t{"); swOut.WriteLine("\t\t\treturn m_vKeyNames;"); swOut.WriteLine("\t\t}"); foreach(XmlNode xmlData in xmlTable.SelectNodes("Data")) { string strName = xmlData.Attributes["Name"].Value; string strValue = xmlData.SelectSingleNode("Value").InnerText; if(strValue.Contains("\"")) { // Console.WriteLine(strValue); strValue = strValue.Replace("\"", "\"\""); } swOut.WriteLine(); swOut.WriteLine("\t\tprivate static string m_str" + strName + " ="); swOut.WriteLine("\t\t\t@\"" + strValue + "\";"); swOut.WriteLine("\t\t/// "); swOut.WriteLine("\t\t/// Look up a localized string similar to"); swOut.WriteLine("\t\t/// '" + StrUtil.StringToHtml(strValue) + "'."); swOut.WriteLine("\t\t/// "); swOut.WriteLine("\t\tpublic static string " + strName); swOut.WriteLine("\t\t{"); swOut.WriteLine("\t\t\tget { return m_str" + strName + "; }"); swOut.WriteLine("\t\t}"); } swOut.WriteLine("\t}"); // Close class swOut.WriteLine("}"); swOut.Close(); } } } } } Translation/TrlUtil/FormTrlMgr.cs0000664000000000000000000002017513222430420016032 0ustar rootroot/* KeePass Password Safe - The Open-Source Password Manager Copyright (C) 2003-2018 Dominik Reichl This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ using System; using System.Collections.Generic; using System.Text; using System.Reflection; using System.Diagnostics; using System.Windows.Forms; using KeePass.Forms; using KeePass.UI; using KeePassLib.Translation; namespace TrlUtil { public static class FormTrlMgr { private static bool m_bIgnoreBaseHash = false; public static bool IgnoreBaseHash { get { return m_bIgnoreBaseHash; } set { m_bIgnoreBaseHash = value; } } public static List CreateListOfCurrentVersion() { List l = new List(); AddForm(l, new AboutForm()); AddForm(l, new AutoTypeCtxForm()); AddForm(l, new CharPickerForm()); AddForm(l, new ColumnsForm()); AddForm(l, new CsvImportForm()); AddForm(l, new DatabaseOperationsForm()); AddForm(l, new DatabaseSettingsForm()); AddForm(l, new DataEditorForm()); AddForm(l, new DataViewerForm()); AddForm(l, new DuplicationForm()); AddForm(l, new EcasActionForm()); AddForm(l, new EcasConditionForm()); AddForm(l, new EcasEventForm()); AddForm(l, new EcasTriggerForm()); AddForm(l, new EcasTriggersForm()); AddForm(l, new EditAutoTypeItemForm()); AddForm(l, new EditStringForm()); AddForm(l, new EntropyForm()); AddForm(l, new EntryReportForm()); AddForm(l, new ExchangeDataForm()); AddForm(l, new FieldPickerForm()); AddForm(l, new FieldRefForm()); AddForm(l, new FileBrowserForm()); AddForm(l, new GroupForm()); AddForm(l, new HelpSourceForm()); AddForm(l, new IconPickerForm()); AddForm(l, new ImportMethodForm()); AddForm(l, new InternalBrowserForm()); AddForm(l, new IOConnectionForm()); AddForm(l, new KeyCreationForm()); AddForm(l, new KeyPromptForm()); AddForm(l, new LanguageForm()); AddForm(l, new ListViewForm()); AddForm(l, new KeePass.Forms.MainForm()); AddForm(l, new OptionsForm()); AddForm(l, new PluginsForm()); AddForm(l, new PrintForm()); AddForm(l, new ProxyForm()); AddForm(l, new PwEntryForm()); AddForm(l, new PwGeneratorForm()); AddForm(l, new SearchForm()); AddForm(l, new SingleLineEditForm()); AddForm(l, new StatusLoggerForm()); AddForm(l, new StatusProgressForm()); AddForm(l, new TanWizardForm()); AddForm(l, new TextEncodingForm()); AddForm(l, new UpdateCheckForm()); AddForm(l, new UrlOverrideForm()); AddForm(l, new UrlOverridesForm()); AddForm(l, new WebDocForm()); AddForm(l, new XmlReplaceForm()); return l; } private static void AddForm(List listForms, Form f) { KPFormCustomization kpfc = new KPFormCustomization(); kpfc.FullName = f.GetType().FullName; kpfc.FormEnglish = f; kpfc.Window.TextEnglish = f.Text; kpfc.Window.BaseHash = KPControlCustomization.HashControl(f); foreach(Control c in f.Controls) AddControl(kpfc, c); kpfc.Controls.Sort(); listForms.Add(kpfc); } private static void AddControl(KPFormCustomization kpfc, Control c) { if((kpfc == null) || (c == null)) { Debug.Assert(false); return; } bool bAdd = true; Type t = c.GetType(); if(c.Text.Length == 0) bAdd = false; else if(c.Name.Length == 0) bAdd = false; else if(t == typeof(MenuStrip)) bAdd = false; else if(t == typeof(PictureBox)) bAdd = false; else if(t == typeof(TreeView)) bAdd = false; else if(t == typeof(ToolStrip)) bAdd = false; else if(t == typeof(WebBrowser)) bAdd = false; else if(t == typeof(Panel)) bAdd = false; else if(t == typeof(StatusStrip)) bAdd = false; else if(c.Text.StartsWith(@"<") && c.Text.EndsWith(@">")) bAdd = false; if(t == typeof(TabControl)) bAdd = true; else if(t == typeof(ProgressBar)) bAdd = true; else if(t == typeof(TextBox)) bAdd = true; else if(t == typeof(PromptedTextBox)) bAdd = true; else if(t == typeof(RichTextBox)) bAdd = true; else if(t == typeof(KeePass.UI.CustomRichTextBoxEx)) bAdd = true; else if(t == typeof(ComboBox)) bAdd = true; else if(t == typeof(KeePass.UI.ImageComboBoxEx)) bAdd = true; else if(t == typeof(Label)) bAdd = true; else if(t == typeof(ListView)) bAdd = true; else if(t == typeof(CustomListViewEx)) bAdd = true; else if(t == typeof(Button)) bAdd = true; else if(t == typeof(KeePass.UI.QualityProgressBar)) bAdd = true; else if(t == typeof(DateTimePicker)) bAdd = true; else if(t == typeof(CheckedListBox)) bAdd = true; if(bAdd && (c.Name.Length > 0)) { KPControlCustomization kpcc = new KPControlCustomization(); kpcc.Name = c.Name; kpcc.BaseHash = KPControlCustomization.HashControl(c); if((t != typeof(TabControl)) && (t != typeof(NumericUpDown))) kpcc.TextEnglish = c.Text; else kpcc.TextEnglish = string.Empty; kpfc.Controls.Add(kpcc); } foreach(Control cSub in c.Controls) AddControl(kpfc, cSub); } public static void RenderToTreeControl(List listCustoms, TreeView tv) { tv.BeginUpdate(); tv.Nodes.Clear(); foreach(KPFormCustomization kpfc in listCustoms) { string strName = kpfc.FullName; int nLastDot = strName.LastIndexOf('.'); if(nLastDot >= 0) strName = strName.Substring(nLastDot + 1); TreeNode tnForm = tv.Nodes.Add(strName); tnForm.Tag = kpfc; TreeNode tnWindow = tnForm.Nodes.Add("Window"); tnWindow.Tag = kpfc.Window; foreach(KPControlCustomization kpcc in kpfc.Controls) { TreeNode tnControl = tnForm.Nodes.Add(kpcc.Name); tnControl.Tag = kpcc; } tnForm.ExpandAll(); } tv.EndUpdate(); } public static void MergeForms(List lInto, List lFrom, StringBuilder sbUnusedText) { foreach(KPFormCustomization kpInto in lInto) { foreach(KPFormCustomization kpFrom in lFrom) { if(kpInto.FullName == kpFrom.FullName) MergeFormCustomizations(kpInto, kpFrom, sbUnusedText); } } } private static void MergeFormCustomizations(KPFormCustomization kpInto, KPFormCustomization kpFrom, StringBuilder sbUnusedText) { MergeControlCustomizations(kpInto.Window, kpFrom.Window, sbUnusedText); foreach(KPControlCustomization ccInto in kpInto.Controls) { foreach(KPControlCustomization ccFrom in kpFrom.Controls) { if(ccInto.Name == ccFrom.Name) MergeControlCustomizations(ccInto, ccFrom, sbUnusedText); } } } private static void MergeControlCustomizations(KPControlCustomization ccInto, KPControlCustomization ccFrom, StringBuilder sbUnusedText) { if(ccFrom.Text.Length > 0) { bool bTextValid = true; if(!m_bIgnoreBaseHash && (ccFrom.BaseHash.Length > 0) && !ccInto.MatchHash(ccFrom.BaseHash)) bTextValid = false; if(bTextValid) ccInto.Text = ccFrom.Text; else // Create a backup { string strTrimmed = ccFrom.Text.Trim(); if(strTrimmed.Length > 0) sbUnusedText.AppendLine(strTrimmed); } } if(ccFrom.Layout.X.Length > 0) ccInto.Layout.X = ccFrom.Layout.X; if(ccFrom.Layout.Y.Length > 0) ccInto.Layout.Y = ccFrom.Layout.Y; if(ccFrom.Layout.Width.Length > 0) ccInto.Layout.Width = ccFrom.Layout.Width; if(ccFrom.Layout.Height.Length > 0) ccInto.Layout.Height = ccFrom.Layout.Height; } } } Translation/TrlUtil/Resources/0000775000000000000000000000000013062036160015422 5ustar rootrootTranslation/TrlUtil/Resources/B16x16_Keyboard_Layout.png0000664000000000000000000000206610131465222022177 0ustar rootrootPNG  IHDRagAMA7tEXtSoftwareAdobe ImageReadyqe<IDATxAi33<(/C H#*ݏe Yq_ϔR`gW60a`PQb`xP |~ X~qqn_x")% % P!χ), 8V(z<0 7\q"QR?jl/yf,  bŃ8 u7Fe @,30? P3?P1\@[/8N= ++>AC& RaWc EAJ&16ع ݪܰRU  %,f 7dff`gROh@ad` 5xY^{-Š (͠pbQFU%9)1!6V,f'babbbPRfeLc``e``! hAI 00prC_p<4D+/'0<Ӈ[ 2e`@,cf`cc +mG~0ں{8u.c'eFfF!by+Ñ#7޽t.bb" 8}&Nvbx{>0}  of^p]_7ؘei ,,~7!~ay} } -@nHXIENDB`Translation/TrlUtil/Resources/B16x16_Down.png0000664000000000000000000000162010133443504020005 0ustar rootrootPNG  IHDRagAMA7tEXtSoftwareAdobe ImageReadyqe<"IDATxb?% X@t `bb5k_,Pǟ'߿,B/d0_~άלea-1q031zVC, lKg̠l`s#[@o>30\yo ^g:d!z .$?" @u20w b߾dG U6N@l/6]1Y?1 ? <\ 6F_y@6?P[ ïĸO ?IA1l2o?a)-[a K>1l|??^~ps]a^٫n2ї 0̜s?X3P ^z^% \L ~U: h_ f-=IE}x @0kâ.X& /10az'!bt؎>u@1vie0A4~o@e`􊑁{-c#!Tp%(8xـ.`7Рo@b`8h>Cbeg`: 6PWm"@3B @1fip0q  #Q  /fj Y| X~g𛓏A@9 A0bHoo'x L@ہ001 H@@.&@ 랿bxeb'n32ab `C! L ݵ^e>;D! c10\9v҉&o fـ u+7(7D3й ٜ c8Â9G' t'~8w҃oԹ؀)XY9 W/e+> /󟁡KB=R=-A΋GD(+{ܶڅ8K3ÿo\e4A*KPumuxi޽~o Q5,3~9 V#W ,1(i1/z+%&f-/cPw ̏8~C ` #А@C30x=gb?}. fF =]6gwe`Pzhff.h?r 7ÍY"h TTtbP1PP.y3(  X8@'@Ca`Sb`30zP-P;@V >>jbX$a 1 & X?6N6nk@PPabFϿX~N?  h; W/^`ng $ @`x33H ]/W?3X0>g`a W{0؀?h @?@1 fɻwƠ)DSe(tX}6^L LL c20|ə _TN0q)Eb7P;3$YAt̓s_2H)10< ù'u ĭx?U}e & Ŀ?_W1]ge`0W /41țx22F?F Ͼ0197ßO3Ch/݋of|,=^`0CR@]p?o~0~}Š '0\eaɑð~Ù,T^v_20( a(piGw9fjG[;X] oH0 ~0u)321(g2&10 Q s@A\o 30ea`ffx9gbc`bxt)LLg 3q20|_BIo |f_?dY~dc?X/@]pu̓\|wg>^Vg?!NYɗo ?aŻ߯9@g:|k㭏IENDB`Translation/TrlUtil/Resources/B16x16_FileSave.png0000664000000000000000000000160210133443104020570 0ustar rootrootPNG  IHDRagAMA7tEXtSoftwareAdobe ImageReadyqe<IDATxb?Z\~11004@az{>r /_/ ğ?/ (AU'7[*xvkwѰA !ŪDZ?e>,q6cd``b;?# 7P7L@^>A.~baFF@El@H8L@ 8@`db2Clg`27P32102C ؘA 85yh.'T@Af?mF#P߿ /! _??3|_w3WY|v@À/$Z33;?0FX fc7 ˯ L _12 F~3L`3e`gf@Aߟ@ge0w_S&s}6@qr220Xjb_P4 Vq2pbPt67;#ODy^- 4j@A4   X Y3|AT/F &l| ٘0ewt30ДU>ad VHL؀ /6}3p]Fh"bFWp|afxo參 KC4>Sg%IENDB`Translation/TrlUtil/Resources/B16x16_Binary.png0000664000000000000000000000150710130001210020303 0ustar rootrootPNG  IHDRagAMA7tEXtSoftwareAdobe ImageReadyqe<IDATxb:a߿ LLL  Ab lllR1aX?X{@%XQ3@U陹dDpww63'sl0 @1bll\#Vb&zfZ 3L"UÝfO1 rǏ60 {$r.'߿@jA@ -[| R6A -7@~<<< W KQ(l!!؂XHRݱ仫 \  c,l>d  pJx "03S.nfF}(3 V"@ MLL PL  9PX X@ ++ ,kkk@ @lk Vp @A 1H  e%>  nG]fʆq N ₢ @^}xp 60=rq3{)=l'c8 _}xyY2h(333 /ÿ"=+Yy~2|g1egP3k(101o _l5c0|f 17Pb_w |Xdws<>@]vZ_xYX1袯@+ϛ e`afes(@٨j0= ~1H23003l/c?T xD$ 03+? ~exxAE û?z;/&!v AKyHaXM-Pa֋-mDƈ8PHn)@ 4JSG$Q}MfxKC>lEu+ZY wxrP#; 0؁AX(&a6+y`bxebe/4s^b @ t*ֿ< 'ֿg bb`cq뵇W*+`b7@2 (6V g<n fy 8ŕ[PTKS?@޵w`= f>56qc7>s0|܉ &`X=?2pFbd05d~<98س$dDD/??~sӁڟ8Y ̡Q*_iIENDB`Translation/TrlUtil/Resources/B16x16_View_Remove.png0000664000000000000000000000130410133443340021322 0ustar rootrootPNG  IHDRagAMA7tEXtSoftwareAdobe ImageReadyqe<VIDATxbTUg20 4*ba(PD/?܏ l +7˻O 6D $G ^ ׿ Z Z PgPR_͐@fdb`e`@?;?@?X5 r߿j ]Дi`M C` j3@c`p4N_F<@!A@l@,. 0d_Aa0@j`\0WE1 @/8$HH]@@/` N ,̠@[ TLyh+ Y1p2gb NNnyL8d ,@w>2fgg ڸ?ofP 6F2H)|@gq>IENDB`Translation/TrlUtil/Resources/B16x16_LedGreen.png0000664000000000000000000000221010133447034020561 0ustar rootrootPNG  IHDRagAMA7tEXtSoftwareAdobe ImageReadyqe<IDATxAK >e"> n]Z  /?fsâ Νÿ 6WH1xB'Pc&dg1лʠc`dA%7:-JbKd) "Ɔ%7/_2`߯ O?3w $_2 Y51=ffao1|ݏw fx-(@p1۰02`Ű&?tD؄Y8.o~̰N?83p]g4 &~?Xd8aã?79xY|G ;;;;mz2222////,7kkgggaa<WA***)''''''''########/kkkgggaDW%qkkkgggDL%qqkkkgg< 8}ssspppjjjjdddd]]]]SSSNVtqqkkkg0+" &xvttqqkkk+F )!xxvttqqkzF )!zxxvttqqb )!zzxxvttqM  zzzxxvt"%|zzzxxv.CC66zzzx(F{pmzzzF0 nc *zfb)[nnQ'|Mf pw [G ~_DC[}bR.-lbZ\F"8L\\L8"FF++F??( @      (,04 ,$ 0$ ($$0($4($8($0((,,,0,,00,40,80,000<0,400422840P4(444<44@84888D84P80@88X<0D<8<<<X@4pD4pH8PHDtL<L8LLLXLHtL@lPDP<P<\PLtPDP@T<xTHTDxXLXHXLXL\Hx\P\Lx\T\P`P`Lx`X`Tbbbxd\dddpd`dXxd`h\hhhhXl`xlhlX|lhldpdpdtLtttthxPxpxtxxxxTxtxxxl|t|X||||x\txdhlptx|윀위전절줌쨐谜ฬĴȸȼ̼V)  )VV,33( Ql'mg$e/{)d{xvsrnnkk[{xvsrnnkbf|){xvsrnnkb_|)`h{xvsrnnkb_[eb_QkbfQ)aSSNNJKZA>>:5?nkb$t%nnkkgQ^IIGBBDW84421;rnnkV& 0srnn ) # +vsrn, 6p]]\XUUSSNJHECALxvsr}36{xvs3 &jTPPMMIIGBB@@==F{xv. &7!-{x )Q7-{Qz<0m/R 9'O~cUiV&"wo`q.TT*ydl u& Y" T qh&")`/zt)`O&66&QQ&  &Q??(      (%$)&%C()((;("0(&*));*$0*(C*";,&<-)///0//>>g?0]?5T@9hA4NA=BBBCCCDDDEEE^E=^H@`IA`LEkTLmYQg]hhhiiijZk]kkkl[lllnnnn_oooqqqrrrsmupuevqwaxQ{j|v~r~j[|}|admvߤ禍ѯ»ƶʽ˽˾̾G HC%cvrps`"D4U{e^[YSXmL5AWygda^[YSNdJD&o Nn$Fhwr/!BMSX`Hzu:76KR*)-YSs}z;98@E.+0[Yp~}1 ^[q~Z uroj ?a^vDkbxurlOdecG,| Izu<fg{'=]_QoyTC2\tVPiwW3>,kh(AD##FPNG  IHDR\rf IDATxw|8;NlȞdA  )=j-mZ RZ?J %ve%@ !=^c>?uw;Iɶ^}:}ޟ|GgH8j:@?_]6u>n(>T l65QcIʵt ^@ϺN9JGsew@(wf9#O(8 T֠8R8ܫ0 L&y9({ _riPK_`,0 eM"`!ʳG|5ʀiI4<|s*=-5`gnqȼ@8"'O.ޑ=p=?vעtV < T{X_-QXOh;nO#Gi8{\)AY`XQFdZ&7.큣f[ \Vw%%f]ѓ.]бCGڶmGvhۮm۶@qq1n@e" P[ˑ#G8x@}{~NmJ dl@yH%JBw04Ƕ$ЧO_ ̠AY^N=(//sR$I9B$C$lhiP !ؽ{[lfۖlڼ5kVjJ6nXO$bKξFα-4 30xƏuk@7g?͞=Yfj{QZ4qZ8\.'xW_}5gy^>́?vC_E">Cz1p8R+ V1g(CxΧ׺ukzwa(vƜ>SO>FeeEؖ(jfډ:(CNAJKKkɍ?uf؍LW{ ;vd}Z(ӗ5+5Gpʃ6"[5A_`(Ăs}oS䒱*P#=̓4(Dlo+m/" " R):F" I$Wݧ.KK[G•Ǝ/ك_}YyW]cu)rXOסL\@9-W=[= <epY.GD‚`XrDC/x4SD kH 1aKx{%|> WR.F_-YyWe )rH+:@c98Qe7/~7~$4.y($F q0#6>~DO"?O/h\bY_+ 䞻"+*P/F%w @ʠ'+3v\\|%ꫜq}e! AMZPU#H<_(j2 dLe A9=mdhWS7 ٍ&KiFAecePSx p5/,5??￟x/Gkda t tf{0BULυ+Y?@~Ag<={ bDn(ˬ0[{ :!5gygPDPw72(衸s ǵ\Šo,cV7*CeX䤮ΝKNR3 DT׊wك_`Gev *kמ/|)uKBlcm':;(//Gynnw?ԯD r.}A="TU ]x{?*ÉSN7%QZZ-oPXݺucy=:m\ýl ~+qHڵqS^UIf9W\~۶nI!݊HmdOhYh}IW/V&1}Dn;gu`AaaN:3kօ,Koߪ1MPi6]rɥ̙3/D@zȂxZ ٶm7|ǖ-ټa-[Iejk>J P\X#[ӧ z@YޏҲr<_ ە/?I+Q\ѡH'jAn鏘%SGcVd.D'$n]2Y~!Nnְ%|C>M} !~P"|$  Iл Ɵ0c&3pq}Jm=Lp _.,TA;~vpp>ǜ9sKuOnT.>t7^{W?UpI.$I"^@Acs0e,[e]Kb7 ~^z~qӵOBʾ(ӌ2Q(VAASLje T_L@ /=ŧ-QSۉi|>?Hc0ٌ*úsӧ̋p?EoqRkeR0e)(aHL2),,dt>R{}{_qO!zoBABBk[Irzxsэ}+~=G? ǖ)*;`hؒsgRUUrRk 0ؓiFf+P2qdRRR…3n8]S)=b.&r }{yb<# AVW9s-Ϗu޵sOiӶc~J@n^:,7T, =C訕 DȅpLd:t୷fذa'_QԳGVs<&hC#yΏߒ_PS-Nm<Sy@Zr9<뫔ZD m4QV֭y뭷1be8Z+D q%YHE"adYfúoxTڃ9w0B|$݉Сcg&t w^(L[QO27x'ꊟ pDP9b"7oټ~}_/Py.I;`8?ѭG%Ѿ$P귁_- 9-g2JL21lDDєYp!'odC qe3~6R>q 0hLNBi>h]s*ߨt)c1y](26 % |>,X@1CӾ}pJZcwҞի/][0 rU5= nvn&: G/TUV4R׶,Gjx^~LsƄ?zjdiH7^"ncaD">_jj8*L)*wo7ݷ_eXXr曮"aA&/!,K0"gGE(mb&؟hlݺo׬0W1/YY1'2o޼y)Gkg9=wE'e_OJ>)gG?!Ca:9aC%IbɧOa~(q$9Jʦ p=zwޡ8ml=~ʿY?TB2È g {)mN2+]nSNWqaSuUl-0exxͷLOˏ-Sپ߷RaUBA ?!gG/@еv jl gI{LZ~ @v_{zG9Kofnw7 Yn9?/ӥ)z;莎;ӥoaeXU8(OM[oM/vyy=ra,ڣ?z3E]5 <4$?y!ݳ+6T*uFYu3h@|?j(>Syi !%\tԜK ?@IrѾCgKVm)nUBq6a*+Sq ۷!A=^~;fLW_;=3`: yDV\n Ԫf/+2IfKM/ڡk>ȴr~dqz}r֌710pqt-+4^PwlfYxK?G\$E__RT&GeP/}1JT'd"QްtWs&~Gԃ jlҽW+/K>\QI1mq% 82%h횥ڳIIlt8xnelOy׸*虧7k ޵*PBgyJ8GGkWw$I=^:u57IKc>:_'Kr]bpd>Zcw5J>G9?H4¼4p>N9q$/M~fGe[(Sy=S12ix2PHDdpqOR$F_DYqx=>V.YdKb÷_r'L6~BuWF/GfxH.fΜm.ix2AN3}_,x>$?9ϾτNEruڮ| ~5@f4V#6CiWJ>Cs  5.kU~ǰf 6N%4ȍKE3`*𮙄[fUtU3<vL8G3!6n79?ĥr> Da}Nw" yjSaѻLP05Q[ŔRQa4u5L)Az!&M ~F[2+|$z__`?%IlW4\.<}a3l s0L^|R}t#V["ӳKˌe8KM4{_so*ehռ[6m)Crv2|avKcК~H0Pq\t\^_\,.tq|R۪ `֙'KӝIhvrN7p\w@ `/GGpe\.|x&0`8{\-)_|_GdVnVޝk&t&Y6{ 19fħG=];xmYyq{ۜWoP?{B3(/v[Mv[=oS]Ƭk9fyFyhOV;wEEE1/_ygoYvn%F=l۾>C?x|5 }-s(\*qTq# 02'G qWHw'OO᰽?| ٥O[MhA X KrmWrW~ R:ĄiI ITG;޸ 3z 4r}z*&" Aa+71ph.f̺=`r=|+?vk}#~Zp=0`ߨ8嵃avm1|VLuM /q+umvhvG?[W߉km+`ǖUڱ6Gٰ=1ѯν={zbԈ L6dJWez2?yᳰ)v^ޏ3gnG?θ]{rY7gj+wG|>BNKWˍ?j@ߒs/ȹ6g-^[~ լWһ}v? k~‚ JTg}}0V ވz@gLg[y@7,d[¿{i*4%Iʐ= @ރ$:ܿCѰuۃT= H?n6^:ꉨ  ѣfc~P K>5\nk~r{?e6/`7a7"u Ģ.ΥKn鉨H\o?" $a>dA ;tf- ~ 9mtHR(X˚5mOb@rVETW]8 HBGZj峯0?(+~şgD~gκ<2|<!!d|-~_@:).n.z$я~LVچ'?Z3ܱT L~A_8B!QT};l `8)Z**ny^a/-@;,Gu\{v% ~!`o^8A彏Si+_#:vK7SIic˜c[5]:z#gmREHާ:3?" Ba `˦uz}LtZ ە/ѧ^F$Ş7~!aTSCB@ײL<~ QVN.0磌Jؗ ~ n/b+#`ㆵjy(I#Lj US՛NpE߁2qORrGܹ3g:ƪ>_֮!PAƶh;HؚBزlhuԢde~)@{ IDAT3رTgMh2)Y`*p.& Ϟ}^oCt~lۺXePIhSz2ڻkB]%xgͺHW'f& L I$.|vw= l{PUUa>R{-ԵzKښJ[g H"ZGuVR92 i1L=BHfge|\.z_[ ˺G!‘a]S*Pޫ/]*t HV?HT眣<3 ?(~TUU鮇tr=wWԪkm sVUǠ4G7N1KOLOiF Ig=Hë?;/Tn >,\SS|`0GdLyf_Ek2|Fs;v{hؑ~=ѣ$^gM /eUݺT~!;nI$~.]1d(lHiOh?@m?@ ˢk>2- ~!êE0Xk{dD N9Z43qF-Na?{/! RW$鲽Κf 5$I/5F jTNy;G lk9W޺@ D_ rg_:Gmܡ1J0 ={ӽ9:NSPfiJ[U, T-;BGN|H f w:ԆFCaY-h[)IHM~!Vfwt91#`҉wSws'͋UIog!X X%!HR?mOX7Ǎoj23v&L$??_7`ˆ_@ְHxjo}WHq[j/`HÝu!|QM8ӤW@+/b¬@YY#`Ձnc`$<@FGt7^È$C&4C Ie12lVA?Q ȏX0hNѣ㒥?M~/`ECzK$ 5) L ?cN~\tCeȐ:  ng_Gg}钔vrv틎L?@QQ+245$کWƩ :GhmBgrY25`Gejd q% Mэ"1bD!LBWM ~=lK~ D^sǾL:44@ ?475cHI 67k_tfo( ;ÀDi,NjZy#`!n-ذ}8@G^^nxV{%#ii_p˧Aa!`M~,C̾eU&B(?G4Oq 08IHJPn4F  j7YS+5 kRm h^ ?@$:_S3fV2Ĕ/z/F6!q (+뙺BUʫB=EIai0ܴ(o>j$8וa2ď}$ַHn{?A& A2EӔu"VRu<(o{5_P7~!Kt^gM -~_˄]6'%^sv_8rT9D?jH@hʼ<:u`L KAY9Y v?b;k/C0s"R)p*uQOQN] / P!Ɋ!Խ{)/G}).\/d8'=Ik/C0-8DbXs"ħSwB@m B0,y_\.m+K=u76j#Rb3E+x ւ ~I?vG󯨒i_G JKM9.Tw ?@8b_SU-ubl%u*6mMΔh.:~XjgJ?@6h GFVv_46JJ:`upx-;PS+R^񼕴1;uJHI@l:Q˒]j*cN؀@B81dawdgjj5R.٢Vz߅@|>_JcwYHv_1&l4|z c f ]w-WvW l~ sLdH޺ d{';/DTwz ߠ ntul1hy1޳1_M9dɁߑ=eGANWfr@J ?>OG-Nv?湔3]@hP!I:$ac[ PmfJ^)  Ҁ_z%l /wp`0h9m 0zZPxUF1"&O]3ouyck'UXJۣ20j{Bj[x[m4튺-.H?@(ҊN&Z$)+CϐL$]|i򜈄8I2'޿OKA a&[nbհ9(ԶkYf~kN~P0P h+4 p$~r%H$Ɂ?ʜ5-טW|Ĩ޴ CFS8? -[y"ڞŗ!i9a)ωHӒ@A^1 :|@:Nu` R$a0o,x2yfj qyL$~ig^τ(Q2o>੿YTf=.cƞK[O| >s=OmPů<Ѵ'e* B9VG"!j+*-Bnt/>hpa~[-"iAl7'~Ol_F9Ɏ#uqAZaf;mv1nݢ~[ 9 (Ms5σ`-zJ`[7o ?`G|Z#%DssV]E.6j6Mi&Zq݁c-/mMvl3/_h͚U&%Z|>C@Lxd7:kh`w,fhp^jeIIr4_",VxgzGva4o+#B@w:I(۷iߎJhp+SDT$a5G@667Ë;*W5~t ?ukbWXV\~j@:w} Ixu ntf \tP?>%Fz`/J'Czs-B;?l6@g?@Ea~pς,YS@R/[7~_ɷ2L'sg\GաĝSu70b@ï~e3EZN4i_qzͰdQ"7nWt"m)ͭƅ?/űq⍋ ۲y}$+%_^2sy*a__+xVR~nI7_zlQ̥n#z5xA&BlLU7z!$1n`! FWrQ^ ޽{x-=J)vקilEhόo~u a}}_+,z)(=|5Q^&=3O?J.6#9аxܪ1h}WN|?钅iQ_f4=~Cc8c в],bLاP eNr.4WgA9`ܐ<&ڬ+/=$$*0Ċ;4bvYr=ee´j͖ GO81hdŸ (s|b4ӮS}Ok{>ݼ>1~VΘrkdR=j$a?N/6bTs;]6; ~`4d+?ٹ~H3s'5#E a.J\)m(@:%UmJ@UU =,F:=.uQUU%<*FIwuuOjF5lvp9b6cU#b:t==F-ҵe+ +#Y9Zax#64}:BkN:fnj [3f؜*|TLFkzN6sѩņCqޙ,f* ?]tozZ(߹r9&:=:{8\_۾cFA;j*8$8yt!|?f艨`i^'$ӽp8f_:ϟcwԲԘϙʧcZ=ˑO^7)G ۓiurHT;y%KODR'2]8*_}Զϳe:%=ǽxϸ-p"(:N *#1] Kb:,3-#8Mxgcw?йZ;&xI [0ivllhie.juo_. ube~\0sr@-?'Z_:Ma۶-g~_:GQ#rЍ^G7myĉۙ'v:3LsA.t[O*hUf ]y8{R){yc,2z HzH0y;бcg>tw Km@xu-?6̙C 1Zd.~rNkڶjX u^)t>Ι1u =fG-@TwL#nX{kg#VK krO]f~wIp)ŦB8 NEAL37o@N 6"!,ѯy.^" ?N(bh߸^S3$0L}}ߗ~d*Sف_7G0ml~o-=@mؚåUt pL⚚j@}f19' @n>:iX](Ӂ߁ sj|g2}%n:T+`Ϟ߿Moة~2Z6nVƅ˼\4~5kyݷ3n^$xY>I7_ӵk7$IwsB6qw <̞/ }:ckj9p%&&,,Qy >~_: KVrRW_g u^:jŗ\qT c09O*Y @;&j8` ~Gb< $~U3ZO/~(ep O8羁ϟE)! |#U2FÕ3ZSo OuGIGx@+p9:oʦM>l$Ijȕ'!z=n=PS+4/N^A+ !7tan S6@ 8l߭] B0adCGrItPLuиc^]\1>sŃb âgj0%˓Ͼ̔i'_md֠]"~5ap>'"0_p>p@-{ Uc9(3A^^>Ͻr;^ڲ+Ȳ2&1nPܘ~C~rYR% 0 ؜I&z՘dM2/s؉q ŷBA߂/bvb˿ǗNuuT Q:5RՍ @M(Ng o,\S ZIDATةT3N:]ta_E8נ?cܼ8_v?}U7SfbD+:U۶yqޛ lQ,z]-w|/'!`oW/+s42pr@>06LZjs/ƨ77͆po{<3&O+r?ȑRij)JHL+X $B<\7QUV,^Uá !́ߩQZG39z@*Mmơʥ8`L2M+C$<_eWT=K'0#;8(dx[W_~ZN>u:O] Q$ˀ,_e~؁_vt$Seʨu7ֆTڼq-r֮Y#. [ڿYղ-ZK(o2vaG7L3 ].ңԋJ@@o ~IXg扅0Es) ];ݻ눭K*Ve ٽy3/]Dt)寏Ō(4 V$ as1(.~G}K_yVf 5J@tCǿqZ ‹Ȃm|5{ʪ)cׇ#%ֱE鮟gJgZiԔ@ N9 ХKYBX&H-A6~Z8J\ g?TKngv;΢秈eJa~jje*n՚_v.:\.ia4@pRf m RQ-H[8Ǡ^~w꽝 B^y_<[8YUNFUSt(])huƣL u߿`m{lbߑH(MO~ݼtBQ7VÿzR_bRgKhI}E@F}ZtCiF]ʸڛTf-UY2E_G"Ebm\/ЩNm=dno-?q;oN*S-fHSwgS2lkYwל{ݞF?JQZ Tյ2|mHDQ$\W-/''QR覤ȕ8frg~Yy߱}ƤYǀ&j&0hӟ~kfu.7!<<^lI ]C o-|3[Oa]:\ ̓42X@:t̅\W@ʴ J3<ă޵#eR jl5WJnDyJkYb- +nkYw8)ؑxwdu 1+ʌףLPlߡ3ϹY_Ny[6cKOg9x`_ K,U kj) ^(3Oñw,Mκ}~v>X*2˿ZHPzXטͥZ̗Đa9mLᯭf5nkW/童azrGKQZ};qw`x [^0[^uIײtT8Ae{vsVvش[[6YtV6PP&xaK@EMT)5 %(HE$*v/lu6JNC;Q.skfcX+5v;刢!*݆c J)%L1 Ot(u(:}ďAF&}Q `R'3@# D6B@s #_?cLOH *(PvVrVDUAGxG<1ͺ?8۹u:lĀ!dcIENDB`(@ R||Q10 rq ~($#PHEuif}{tgcOFC(#"}^g]ZeYUf"JCAG><!PQKI˻ɻﭖǯOEBV$"!읃omkhfda_][}X{VhĴ*%#vmjòxvtromkhfda_][}X{VyTxQ`ﮗrd_Ǹ}{xvtromkhfda_][}X{VyTxQvO|Xﭗﮗퟄ읂}{xvtromkhfda_][}X{VyTxQvOtMcijּ"*(';ퟄ읂}{xvtromkhfda_][}X{VyTxQvOtMsMĻ*%#T禍ퟄ읂}{xvtromkhfda_][}X{VyTxQvOtMrKuĻR#ﭖ䀹禍ퟄ읂}{xvtromkhfda_][}X{VyTxQvOtMrKjѸ"ﯙﭖ䀹禍ퟄ읂}{xvtromkhfda_][}X{VyTxQvOtMrKjbwpnǸﯙﭖ䀹禍ퟄ읂}{xvtromkhfda_][}X{VyTxQvOtMrKurd_]&$#`G>                              \0"xQvOtMrK朗(#!XA9T-yTxQvOtMsMij} RNMǷXB:T. {VyTxQvOtMbOEB tdLC                              `5&}X{VyTxQvOtMﭗɱrIFEȹ²ﯙﭖ䀹禍ퟄ읂}{xvtromkhfda_][}X{VyTxQvO{WG><4ƶĴ²lSJ9'!ퟄ읂o[""""""""""""k<,][}X{VyTxQvOﮗ0ȹƶĴ²XD>ퟄ읂iVU0#_][}X{VyTxQ_ied˽ʻȹƶĴ²XE>ퟄjXU1$a_][}X{VyTxQĴdXT˽ʻȹƶĴ²ZG@!kYU2%da_][}X{VyTS˽ʻȹƶĴ²ﯙﭖ䀹禍젅蜁}{yvtrpmkigfda_][}X{VhQ+))˽ʻȹƶĴgRK   2$禍ta      f=/hfda_][}X{V(#"|RPO˽ʻȹƶYGB䀹禍o^U3(khfda_][}XNEByvu˽ʻȹYHBﭖ䀹禍p_U4(mkhfda_][tgc˽ʻ`NI            (ﯙﭖ䀹禍sbX6+omkhfda_]z˽ʻȹƶĴ²ﯙﭖ䀹禍ퟄ읂}{xvtromkhfda_n\U   jC5tromkhfdaYKFV7,vtromkhfdYKGV7-xvtromkhfZLGV8.{xvtromkhﭗ|yxw˽ʻȹƶĴ²ﯙﭖ䀹禍ퟄ읂}{xvtromktieSQQw^MGƶĴ²ﯙﭖ䀹[A8 eUퟄ읂}{xvtromɻNGD,++~w_OIȹƶĴ²ﯙﭖ\B9cTퟄ읂}{xvtro)%$}Tx`OJʻȹƶĴ²ﯙ]C:cTퟄ읂}{xvt읃Ry`PK˽ʻȹƶĴ²]D<dUퟄ읂}{xvlkj|_PK˽ʻȹƶĴ²^E<eVퟄ읂}{xg]ZTGC˽ʻȹƶĴ²Q<5ziퟄ읂}좇5ٿ;30˽ʻȹƶĴ²9+&ӗ禍ퟄ읂ò1LKK ٺ˽ʻȹƶĴ²ӡ ꪓ䀹禍ퟄJCAtQHEj\W˽ʻȹƶĴ²gOGO:3ﯙﭖ䀹禍Ǹ̼rUTT{vŪ˽ʻȹƶĴ²dXﯙﭖ䀹禍ﮗQKI *&$0*(ڼ˽ʻȹƶĴ²ث.$!*讚ﯙﭖ䀹禍~***}x*$#˽ʻȹƶ)!g]ﯙﭖ䀹禍ʻ(%$dzyyF@= SHD}ʽöwRC> E61ﯙﭖvmj_1,*&!& 0&#௞#ҿ7106+(Σ"U!!!RJHRB=纫²ǸY,,,>86>4/ȹƶĴ²*(' sfbE=:3-+3,)E;7sb\˽ʻȹƶĴ²Ǹ#!!˽ʻȹƶǹzyy˽wpn&&&*((QUTTQMLX$LKKIFE#^kjiiedo+**SQQxwvxutRPO+))tt 54T~S????(0` WWlk 61/\SPrfc~ql~plreaZQM5/. o'$#tpIJí~pk'"!%KDBǸƸ˽H?<$P0,+³淚sjgda^[_wﯗ.(&N`~urﬕzvspmjgda^[|XzTyRo|mhgf잂|yvspmjgda^[|XzTxQuNmʻ dQ;잂|yvspmjgda^[|XzTxQuNtMʲN$ ±禍잂|yvspmjgda^[|XzTxQuNsKz̴ 'ﮘﬕ禍잂|yvspmjgda^[|XzTxQuNsKowywȹﮘﬕ禍잂|yvspmjgda^[|XzTxQuNsKy|mhs1/.I6/                      F%xQuNsKﭖ/)'ƼB1+?"zTxQuNuNɺMJI̿M93                      I(|XzTxQuNmH?<mļijפ˙ʗʕʓʑ~ʎ{ɍyɋvȉsߗ}잂|̂iˀf~c{az^x[uYtVqTtU[|XzTxQuNj*((ƶijB3.aR잂?$^[|XzTxQp'"!˼ȹƶijB4/cT잂@%a^[|XzTyR~pkY˼ȹƶijoXO=/+=/*<.)<-(<-(<,'<,&<+%<*%ud8&7$6#6#6"6"6!6!6 h=.da^[|XzTﯗíV˼ȹƶijylbj`i^h]f[eYdXbVaTƌy^N\L[JYHXGVEUCTAR@bJgda^[|Xx :87˼ȹƶC61gY禍@'jgda^[`5/._]\˼ȹC62h[ﬕ禍@'mjgda^[[QNurr˼{i`h_f]e\dZbXaW`U_TĐ~ﮘﬕ禍zVIyTGySEyRDxQBxOAxN?xL>xK<^Jpmjgda^̽pd`}}kdTE@TD?TD>TC=TB8S>7S=5R<4R;3R:2R:1R90R8/R7.Q7-Q5,Q5+Q4*|N>spmjgdaǸ}ok~}C85A)!vspmjgdȺ}pkussD96A*"yvspmjgpea_^^ʬ}{yvtrpm}k|iyfxdvah|yvspmj\SP:99 L>:ƶijﮘﬕJ4-  잂|yvsps61/PB=ȹƶijﮘL70잂|yvs轢 ZPB>˼ȹƶijL81잂|yvIJWMB>˼ȹƶijL71잂|ztp***,&%=41˼ȹƶij;,'+禍잂ﬕ'$#nD;9ĸ˼ȹƶij߫ B0*ﬕ禍잂kONNykh{je˼ȹƶijw\RuWLﮘﬕ禍JCBȴ ˼ȹƶij Ēﮘﬕ禍³333_UR"˼ȹƶ|^H@ﮘﬕ禍̽0,+x*%%ODA|uwnN@;* ٧ﮘ±~urt$μ7207-)ˤȹ¾(S|w2-+2*'phŶƶijPgį||mh|lf}wŨ˼ȹƶij̿m`˼ywhS333Ƽ1/.Q'ONNļMJI&o+***((:99_^^vtt~~~vss_]\977nmZY????( @ WV ?97SJGSJG>75":53{ſ׿zt82/*'&ʻﱛzv움0*(.xuvrmhd_[{V|V|mh- ퟄ{vrmhd_[{VxQzT Ƿ禍ퟄ{vrmhd_[{VxQtM힄zx˽ﭖ禍ퟄ{vrmhd_[{VxQtMퟄ|mh%.,+1$ /xQtM1+)"±4'"2{VxQyT ;98²vieYcWaT_R]O`QퟄnYUDRAQ>N[{VxQ82/ X˽ƶ²," ퟄP4+*_[{V|VytUʻƶ²rgy^Uy\RxZPxYNxWK[NjXtL>sKh@ ? qs1 31#~I0r ܊@2x/!W؀C@>ӿ>  q2N1H; h(#+Xُ[{`W]h3j?5ge`bv;5\ۇ p/wyW8D H~aՎ )@C?$a/ o~%H3_ 4~<?°7b? ? `Qǁ@ x3î? V z+~lalH!PHw :t @۫ D@L cĠ&D@?y(8^ `DC @L3(0IENDB`Translation/TrlUtil/Resources/B16x16_KRec_Record.png0000664000000000000000000000130310125245344021221 0ustar rootrootPNG  IHDRagAMA7bKGD pHYsHHFk>.IDATxڕ_HSQǿsALAd$!|9/C`UЫIJ zN$",-+4n+*ZP$\Z?pϟs]$IH);i%)`Y,!0+Fs$>6FffJb%^ V_25EQf Q z?\?vlm2ѲIK@Pn蠥ޒxMZ- 1 Z)V76 5BR@ ,=B!55BUU/+#5w#D8Y|8Y%<L],F,8l^Ŀ1W\B)wFt%JA,}+y2Lu7vNn Mp\j܍pnBv4lOtEXtSoftwareAdobe ImageReadyqe<IENDB`Translation/TrlUtil/MainForm.resx0000664000000000000000000012156712172725654016115 0ustar rootroot text/microsoft-resx 2.0 System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 17, 17 137, 17 AAABAAgAICAQAAEABADoAgAAhgAAABAQEAABAAQAKAEAAG4DAAAwMAAAAQAIAKgOAACWBAAAICAAAAEA CACoCAAAPhMAABAQAAABAAgAaAUAAOYbAAAwMAAAAQAgAKglAABOIQAAICAAAAEAIACoEAAA9kYAABAQ AAABACAAaAQAAJ5XAAAoAAAAIAAAAEAAAAABAAQAAAAAAAACAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA gAAAgAAAAICAAIAAAACAAIAAgIAAAICAgADAwMAAAAD/AAD/AAAA//8A/wAAAP8A/wD//wAA////AAAA AAAAB3AAAAdwAAAAAAAAAAAABwAHd3dwAHcAAAAAAAAABwB3f///93cAcAAAAAAAAAB3j//////4dwAA AAAAAAAH//////////9wAAAAAAAAf///////////9wAAAAAHB//0RERERERET/9wcAAAcH//9ERERERE RE//9wcAAAeP//////////////hwAAcH///0RERP9ERET///cHAAeP//9ERET/RERE///4cAcH////// ///////////3B3B////0RERP9ERET///9wcHj///9ERET/RERE////hwB///////////////////cAf/ ///0RERERERET////3AH////9ERERERERE////9wB///////////////////cAeP////9E////RP//// +HBwf/////RP///0T/////cHcH/////0T///9E/////3AAB4////9E////RP////hwAHB/////RP///0 T////3BwAAf////0T///9E////hwAABwf///9ET//0RP///3dwAABwf///9ERERE////cHAAAAAAf/// 9ERET///9wAAAAAAAAf//////////3AAAAAAAABwd4//////+HcHAAAAAAAABwB3eP//h3cAcAAAAAAA AAAHAAd3d3AAcAAAAAAAAAAAAAdwAAAHcAAAAAAA/+AH//+AAP/+AAB//AAAP/gAAB/wAAAP4AAAB8AA AAPAAAADgAAAAYAAAAEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABgAAAAYAA AAHAAAADwAAAA+AAAAfwAAAP+AAAH/wAAD/+AAB//4AB///gB/8oAAAAEAAAACAAAAABAAQAAAAAAIAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAgAAAgAAAAICAAIAAAACAAIAAgIAAAICAgADAwMAAAAD/AAD/ AAAA//8A/wAAAP8A/wD//wAA////AAAAAAAAAAAAAAcG//9gcAAAAP////8AAAcPd3d3d/BwAP9ERERE /wAG/3d/93f/YA//RE/0RP/wD/93d3d3//AP/0RERET/8A//9P//T//wBv/0//9P/2AA//R/90//AAcP /0d0//BwAAD/9E//AAAABwb//2BwAAAAAAAAAAAA+B8AAOAHAADAAwAAgAEAAIABAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAACAAQAAgAEAAMADAADgBwAA+B8AACgAAAAwAAAAYAAAAAEACAAAAAAAAAkAAAAA AAAAAAAAAAEAAAABAAAAAAAABAMDAAQEAwAEBAQACwoKAA0NDQAfEQ0AEBAQAB8UEAAgEg0AIBUSACAY FQAhHBoAJSAeADMkHwAhISEAJiMiACUkIwAlJSUAKyUjAC4oJgAvKyoAPCwnADEtLAA3MC4AODEvADMz MwA3MjAANjY2ADgzMQA7NDIAOTc2AD83NQA5OTkAUi8jAFIxJQBSNSsAUzguAEA6OQBAPTwAVDszAFQ/ OABVQjsAWUM7AEJCQgBMRkQAVEZAAFRIRABbSkQAVkxIAFdPTABaT0wAV1BNAFpQTQBeUEwAV1VUAFxa WQBzUEMAbV9aAHFcVQBtbW0AeWdhAHlpYwB0dHQAjkozAIRNOwCPTzgAhFA+AJBQOgCFVEMAhllKAJFV QQCSXUoAhF5SAKZeRQCIYlUAiGZaAIVpXwCJaV4AnW5eALVjRgC1ZUoAtmlOAKdoUQCrbVgAtm1TALxt UQCscFsAt3FZAL1zWQCBamIAiW1iAIpwZwCLcmoAnHRmAIJ3cwCGd3EAh3hzAId6dQCPfnkArXZjAK54 ZgC5e2UAun5pANBxTwDkc0wA5XZQAOV4UgDlelUA5nxWAOZ9WQCOgHsAjoF8AJOCfQC6gW0Au4VyALyJ dwC8jHwA54BbAOeAXQDaiW0AzIlyANOMdADOkn0A2pZ+AOeDYADohWIA6IZkAOiIZgDoimkA6YxrAOmN bQDpj3AA6pJzAOWWewDrlngA65l9AImGhgCKiIgAlIiDAJaKhgCdjIYAlIyKAJeQjgCSkZAAmZiYAKiM ggClkYoAp5ONAKeUjgCpk4wAvZOEAL6XigC/m44AuaWeAKunpQCrqKcAq6moAL+wqgC9urgAy52NANWX gQDTmoUAwJ6SAOGdhgDsnYIAwKGWAMGlmwDBqJ8A2aiXAO2ghQDtoogA7aSKAO6mjQDuqI8A46aRAO6r kwDvrpgA8K+YAPCwmgDwspwA8LSfAMCooADIsKcAxLCpAMiwqADNs6sAzbSrANS3rQDKtrAAyrmyAMm6 tADPv7oA1761ANi7sADgtaUA8bahAPG5pQDyu6gA8r2qAPK+rQDOwr0A0cK9AN3CuQDdx78A88CuAOzD tQDhxbsA6cW4AOXJvwDzwrEA9MOzAPPEswDzxLQA9MW1APTHuAD0yLkA9cu8APXMvgDMxMEAzczMANDF wQDeysMA0tHRAOXJwADsy8AA9c7AAPbRxADx08gA9tXJAPfXzAD32M0A+NnPAOjX0QDh2dcA6drUAOHd 3AD32tAA9t7WAPja0AD43NIA+N7VAPjg1wD25N4A+OHZAPnj3AD55d0A4uDgAOvq6gD65uAA+urkAPvu 6QD78e0A/PXyAP349gD9+/oAAAAAAAAAAAAAAAAAAAAAAAAAADwsDwUAAAcPLDwAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAABwAAAAAAAAAAAAAAAAAACEAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAD8FAAAAAA82YZW2mpVhMw0AAAAABT8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABQAAAB5x 3vHy8fHx8fHx7+3PYx4AAAAFAAAAAAAAAAAAAAAAAAAAAAAAAAAAACwAAAA2vfT08vLx79nGxtbl8e3t 8ee3MQAAACwAAAAAAAAAAAAAAAAAAAAAAAAABQAAJr709fX12bOHfnZubGxsgazW5+3x77kgAAAFAAAA AAAAAAAAAAAAAAAAAAAAAAWM9fX18salgYF+fnZ2bmxsbGpqfrDl7+/ncQUAAAAAAAAAAAAAAAAAAAAA AAAAE8D5+fXWpYWFgYGBfn5+bnZsbGxqampssOfx5rkTAAAAAAAAAAAAAAAAAAAAAAAc6fn557CIiIeF hYGBgYB+fnZubmxsampqaX3W8e/RFQAAAAAAAAAAAAAAAAAHABPp+fnZrKqliIiFh4WFgYGAfn52bmxs bGpqaWlqsOfv4BMABwAAAAAAAAAAACwABcn5+9awrKyqpYiIh4WFhYGBgX5+dnZsbGtramlpaYjn8bkF ACwAAAAAAAAAAAAAj/v75bCwsKysqqqIiIiFhYSBgYF+fn52bmxsamppaWmw7+9xAAAAAAAAAAAABQAm +/vys7OxCgoLCgsKCggKCgoKCAYKCAYGCAYGBgZAaWlp1ufvHgAFAAAAAAA/AADb+/nWxrOzCwsKCwoK CgoKCAYGCgYGCAYGCAYGBgZAaWlpfufvuQAAPwAAAAAFADf8/PHGxsazCwsLCgoKCgoKCgoKCAoGCAYG CAYGBgZAa2tqabLx7zMABQAAAAAAANv8+9bGxsbGdXV0dHNzcmdnZoaIhXhYVVVSUlFQUFBoa2traWzn 77cAAAAAABwAH/z88dbW1sbGCwsLCwoLCgoKCnqIiFQKCAYGCAYIBgZAbW1ra2qw7e0ZABwAAAAAj/z8 5dbW1sbGDAsLCwsKCwoLCnqqiFcGCgoGCAYIBgZCdm1ta2uB5+1vAAAAAAAA6v354tnX1tbWKioqKikp KSklKXyqqmYlJCQjIyMjIyJKfXZtbWxr1vHPAAAAPAAP/f315dnZ2dbWW1tOTkxMTExJSaSsqnlGRUVF RUNDQ0FWfX19bW1sru3tDQA8LAA4/f3x5eLi2dnWDAsMCwsLCgoKC3ysrGQKCgsGCwYIBgZHgX59bXZt hPLxNgAsDwCJ/f3m5eXl2dnZDAwLCwwLCwsLC6KwrmUKCgoICAgICAhHgX5+fXZ2duftYQAPBQCb/fzx 5+Xl5eLZXV1bXVtbTk5MTK+xsHtJSUlGRkZDRUNZgoGBfn12dtnxlQAHAACf/vvx8e/l5eXiLy4uKi4q KioqKSkpKSklJSUlJSMlJSNThIGBgX52dsjxmgAAAACf/vzy8fHv5eXlDAwMDAwMDAsLCwsKCgoKCwsI CwoICApIhYSEgYGBdsjymgAABwCd/v318vHx7+XmDAwMDAwLDAsMCwsLCwsLCgsKCgsKCghIhYWEgYGB gdnylQAHDwCK/v359fLx8e/lqKenpqajmZmYl5eXdXV1dHR0cnJyZmZ6h4eFhISBge/yYQAPLAA4/v77 9fX18fHx5sIMDAxa2dbW1sbGxsazs7CwDgoLJaqIiIiHhYSEiPXyNgAsPAAP/v79+fn19fLx8eUUDAwu 2dnW1tbGxsbGxLOiCgsKOauqqoiHh4WExPL0DQA8AAAA9/7++/n59fXx8ecvDAwN0NnZ19bWyMbGxsRe CwoLT62qqqWIiIeF5fLeAAAAAAAAkf7+/fn5+fX18vFhDAwMlePZ2dnW1sjGxsYrCwsLoa6srKqqiIiq 9fVxAAMAACEAIf7+/vz7+fn59fK4DAwMNuPl2dnW1tbIxqkNCwsWsLCwrKyqqojW+fUcACEAAAAAAN/+ /v37+/n5+fXxHg8ME7zl4uLZ2dbW1kwLCwtJs7GwsKysqq719b4AAAAAAAAFADj+/v78+/v5+fn1YQ0M DDrl5eXZ2dnWwxMMCwygxLOxsLCsrNn1+TQABwAAAAA/AADf/v79/Pv7+fn53hQPDA+o5eXl2dnZOwwL DDDGxLOzs7Cws/n5vgMAPwAAAAAABQAs/v7+/fz8/Pn7+WEPDAwez+Xl5eKSDAwLDaDGxsbEs7Ox8vn5 JwAFAAAAAAAAAAAAkf7+/v38/Pz5+esmDwwPFZXhwj0MDAwMTdbGxsbGxLPj+fmPAAAAAAAAAAAAACwA Bd/+/v78/Pz8+/nKFA8MDQwTDAwMDAwwztbWyMbGxtn7+d0FACwAAAAAAAAAAAAHABL4/v7+/fz5/Pn5 wBQPDA0MDQwMDDDQ2dnW1sjI5/v76xIABwAAAAAAAAAAAAAAAAMc+P7+/v78/Pz8+d0tDQ8MDA8TPuHl 2dnZ1tn5+/vrHAAAAAAAAAAAAAAAAAAAAAAAEt/+/v7+/fz5/Pnznoxvb43B5+bl4uLi9fv8+90PAAAA AAAAAAAAAAAAAAAAAAADAwWR/v7+/v79/Pn7+fX59fLx8eXl5/X8/Pz8jwUAAAAAAAAAAAAAAAAAAAAA AAAABwADLN/+/v7+/v78+fn59fXy9fn7/f39/NsmAAAHAAAAAAAAAAAAAAAAAAAAAAAAACwAAAM43/7+ /v7+/v79/f39/f39/f3bNwAAACwAAAAAAAAAAAAAAAAAAAAAAAAAAAAABQAAACeQ9/7+/v7+/v7+/v3s jxwAAAAFAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD8FAAADAxI4kJ2fn52JOA8AAAAABT8AAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAABwDAAMDAAADAAAAAAAAACEAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAADwsDwUDAwUPLDwAAAAAAAAAAAAAAAAAAAAAAAAA///gB///AAD//wAA//8AAP/4 AAAf/wAA//AAAA//AAD/wAAAA/8AAP+AAAAB/wAA/wAAAAD/AAD+AAAAAH8AAPwAAAAAPwAA+AAAAAAf AADwAAAAAA8AAPAAAAAADwAA4AAAAAAHAADAAAAAAAMAAMAAAAAAAwAAwAAAAAADAACAAAAAAAEAAIAA AAAAAQAAgAAAAAABAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAIAAAAAAAQAAgAAAAAABAACAAAAAAAEAAMAA AAAAAwAAwAAAAAADAADAAAAAAAMAAOAAAAAABwAA8AAAAAAPAADwAAAAAA8AAPgAAAAAHwAA/AAAAAA/ AAD+AAAAAH8AAP8AAAAA/wAA/4AAAAH/AAD/wAAAA/8AAP/wAAAP/wAA//gAAB//AAD//wAA//8AAP// 4Af//wAAKAAAACAAAABAAAAAAQAIAAAAAAAABAAAAAAAAAAAAAAAAQAAAAEAAAAAAAAFBAQACgkJAB8Q CwATExMAFhUUAB8fHwAgEg0AIRcUACQeHAApHBgAOSUdACwkIgArJyUANCgkADooIgAyLSwAPzIuADQ0 NABUOC8ARTw5AEU/PABUPDMAVD42AGk2JQBqOCcAajsqAElAPQBrQDEAbEQ2AEJCQgBHRkYAWktGAF5T TwBeVFAAY1ZRAGBeXgB/YVYAZGRkAHVqZgB6bGcAemxoAH16egCDSTUAhE06AIRQPQCFVkUAh1xNAIpe TgCRWkcAh15QAKhbQACTYE8AiGRXAIlnXACJaV0AqWFIAKBqVwCraVIAoXFfAKxwWwCJbGEAinBnAINz bQCLcmkAlnlvAIx3cACMeXIAsXtpAKV+cADkdE0A5XZQAOZ8VgDmfloA54FeAMGPfgDnhGEA6IZkAOiI ZgDoimkA6o9wAOqUdgDrlngA7Jp+AJeFgACZjooAmpGOAJqTkACcm5sApouCAKKNhQCklI4AvpqNAKWW kQC3nJMAtqOcALuimQCioqIAp6KgAKimpQDsnYEA7J+EAOCgigDtoogA7qeOAO6pkQDwr5kA8LKcAMmw qADTsKMAyriyAMu+uQDuuacA7LqpAPG1oQDxuaUA8r2qAMzBvQDzwa8A9MW1APTHuADNxcIAzs3MANrI wgD1zsEA7NHHAOzWzQD20MMA9tXJAPfXzAD42s8A79jQAPfa0AD43tUA+eDXAPnh2QD65+AA+urkAPDq 6ADx7u4A++3pAPzu6gD88e0A/fb0AP349gD9+vkAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAmEgQAAAQSJgAAAAAAAAAAAAAAAAAAAAAAAAAAACYCAAAQIykpIhAAAAImAAAAAAAAAAAAAAAAAAAA AGEAABVbfoaFhYWFgn1bFQAAYQAAAAAAAAAAAAAAAAAeABVuh4d8a2RPTVFpd4KCbBUAHgAAAAAAAAAA AAAABgJVh4d3ZE9OTEpJSEhGTWuCglQCBgAAAAAAAAAAAAYEbomBaFJRT09PTUpJSEhGRkp2hWwEBgAA AAAAAAAeAm+JeGhTU1NRUU9OTUpJSEhGRkZogmwCHgAAAAAAYQBWiXxpaGhkU1NRUU9PTUpJSEhGRkZl hVQAYQAAAAAAFY2Ha2tpZ2VTU1FRT09NSklISEZGRkZ2hBUAAAAAJgB5jXdzawgICAgHBwcHCAcHBwcD AxhIRkyCbAAmAAACHo6FdnRzCAgICAgIBwgHBwcHBwcHGUhHRmuFFQIAAABhjn93d3Q2NTUvLy85U1Ex LSwsKyszSUhITYJbAAAmAIqJfHh3dwgICAgICBNlUwsIBwcHBxpKSUhId30AJhISj4d/f3h3PT02NjU1 O2VlNC4uLS0sOE1KSUhphRASBCSPh4J/f3gGCAgICAgWaWcPCAcIBwgaT01MSlOFIgQAKpCHhYF/f0A+ PT09Nzc1NS8vLy4uLjpPT01MT4UpAAAqkIeFhYGBBggGCAYICAgICAgICAgHHFJPT01RhSkABCSRiYeF hYFDQkBAPT09NzY2NTIvLy88UlFQT2SHIgQSEpCOiIeFhYEhBiB4eHd0c3JraQoIMGRTUlFPc4cQEiYA i5CJiIeHhT8GDHh4eHd0c3JLCAhEaFNTU1F/gwAmAABjkY6JiYeHXwYGXn94d3d0dCUICGZlaGRTaIVd AAAAAh6RkI2JiYeBDAYjf394eHdxDggWa2loaGR3iRUCAAAmAHqRjo2JiYcnBglsgXx4eEEIBkVya2lo a4luACYAAAAAHpGRjo2JiXsMBht8gX9tDAgRcHNya2qCiBUAAAAAAGEAWJGRjo6JiVQGBhVaQw4GCVx3 dHNyfIlVAGEAAAAAAB4CepGRj42JiygJBgYGBgZad3d3dIGJbwIeAAAAAAAAAAYEepGRj46JiVYRCQkb YHx/eHiHjnUECQAAAAAAAAAAAAYCWJGRkI6JiYmHh4WCgYKHj45XAgYAAAAAAAAAAAAAAB4AHnqRkZGP jYmIiYmOj491FQAeAAAAAAAAAAAAAAAAAGEAAB9ji5GRkZCQj4tiHgAAYQAAAAAAAAAAAAAAAAAAAAAm AgACEiQqKiQSAAACJgAAAAAAAAAAAAAAAAAAAAAAAAAAACYSBAAABBImAAAAAAAAAAAAAAAA//AP//+A Af/+AAB//AAAP/gAAB/wAAAP4AAAB8AAAAPAAAADgAAAAYAAAAGAAAABAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAACAAAABgAAAAYAAAAHAAAADwAAAA+AAAAfwAAAP+AAAH/wAAD/+AAB//4AB///w D/8oAAAAEAAAACAAAAABAAgAAAAAAAABAAAAAAAAAAAAAAABAAAAAQAAAAAAACASDQAgFREAIRcUACMY FQAkIB4ALiIeADIqKAAxMC8AMTAwADcyMQA6NDEAOzo5AEQkGABSLyMAUjEmAFI1KgBTOC8AQTQwAEA3 NABEOTUAQzs4AEQ+PABUOTAAVD01AG08KwBKQT4AVUE5AFVDPABVRD4AbkAwAG5ENQBvSTsAREFAAEVF RABWRkEAV0pFAFZMSABmXVoAfWFXAGhoaACOZFUAlWxeAKhsVgCqcl8As3ZhALR9agDldE0A5XhSAOZ7 VgDmfFcA5n5aAJiGfwCkgHMA54JfAMWGcADng2AA6IViAOiIZgDpimkA6YxsAOqScwDqk3QA6pR1AOya fgCYhoAAlIiEAJiIggCajooAmpCNAJuTkACZmZkAnJybALOelgC2oJkAt6afALenogC5sq8AurSxALq5 uADCpZsA7aOJAO6mjQDjqZQA66mRAO+qkgDvrZUA8LSfAOa7qwDxtaAA8bilAPK9qgDyvqwA7MW3AOjJ vgDzwrEA9Ma2APHHuADyyLoA9cu8APXNvwDzzcAA9c7BAODRywDm0MgA49TPAPPQxAD10cQA99bKAPfY zQD439YA+eDXAPnl3gD65+EA+ujiAPns5wD67uoA/O/rAPzw7AD88/AA+vTyAPr29AD99/UA/fn3AP35 +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAKAgLCwgoAAAA AAAAAABHFktlWllhSxRHAAAAAAAoRGtRPDkzMDlcNCgAAABHRWNRQD88OTMwL1FDRwAAIW9XAwMDAQMB AQEvXBYAKE1jXBgYES0rDw4ZMDxKKAlzZWABAQEuEQEBATgwYwgMc21lIx0YKhEREB48OFoLDHZubQEB AQEBAQEBPzxcCwl4cW9JHmNfWlMeN0A/ZQkoT3NzaAVQY2A1BlRRVEwoACF8c3MmJGtdEidXVmwWAABH R3pzZwsaExRYXGtFRwAAAChIfHZpQkNebHFFKAAAAAAARyFPenh2c04hRwAAAAAAAAAAKAkMDAkoAAAA AAD4HwAA4AcAAMADAACAAQAAgAEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAIABAACAAQAAwAMAAOAH AAD4HwAAKAAAADAAAABgAAAAAQAgAAAAAACAJQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABAAAAHQAA AFwAAACSAAAAvAAAAN4AAADxAAAA/AAAAPwAAADxAAAA3gAAALwAAACSAAAAXAAAAB0AAAABAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFgAA AHEAAADJAAAA+gAAAP8AAAD+AAAA/gAAAP8AAAD+AAAA/gAAAP8AAAD+AAAA/gAAAP8AAAD+AAAA/gAA APoAAADJAAAAcQAAABYAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAImJ iRsODg6TAAAA8gAAAP8AAAD+AAAA/gAAAP8jHx79WVBM/Yd4c/6nlY79uaWe/rmlnf6nk439hndx/llO S/0jHx39AAAA/gAAAP8AAAD+AAAA/wAAAPIODg6TiYmJGwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AADo6OgIXFxcewAAAPQAAAD/AAAA/wICAv43MjD9j4F8/d3Hv/3439b/+d/V//ne1f/53tT/+N3U//jd 0//43NL/+NzS//jc0f/329H/3cK5/Y99eP03MC79AgIB/gAAAP8AAAD/AAAA9FxcXHvo6OgIAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAALi4uC0VFRXNAAAA/wAAAP4DAwP+VU1K/Mq2sP344dn++OHY/vng2P/44Nf++N/W/vfZ zv/1yrv+8ryp/vK7qP/0yLj+99bL/vjc0v/329H+99vR/vjb0f/32tD+yLCn/VRKRvwDAwP+AAAA/wAA AP4VFRXNuLi4LQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAgYGBUwICAvEAAAD+AAAA/z85N/3KubL++ePb/vnj2//54tr++eHZ/vXO wP/wsJr+65Z5/uiFYv/ngFz+5n5Z/uZ7Vv/lelT+5ntW/umLav/tpYv+88W0/vfb0f/32tD++NrQ//fa z/7JsKj+PjY0/QAAAP4AAAD+AgIC8YGBgVMAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABxcXFuAAAA+wAAAP8LCgr+lYmF/Pnl3v765d3/+uTc//nf 1v/zv63/7Jt+/+mLav/oiWf/6IZk/+eEYv/ngl//54Bc/+Z+Wf/mfFf/5npU/+V4Uv/ldlD/5XVN/+eE Yf/vrZb/9tXJ//jb0P/42tD/99nP/pSCe/wLCQn+AAAA/wAAAPtxcXFuAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAHFxcW4AAAD9AAAA/iUiIf3Pv7r9+ufg//nm 3/7549v+88Sz/uycgf/qknT+6pBx/umObv/pi2v+6Ilo/uiHZf/ohGL+54Jf/ueAXf/mflr+5nxX/uZ6 Vf/leFL+5XdQ/uV1Tv/kc0z+5nxW/++tlv732M3++NrQ//faz/7Ns6v9JSAe/QAAAP4AAAD9cXFxbgAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAgYGBUwAAAPsAAAD+Mi8t/ujX 0f766OL++ufh//fYzv7vq5P+65p+/uuYe//rlXj+6pN0/uqQcf/pjm7+6Yxr/umJaP/oh2X+6IVi/ueD YP/ngF3+5n5a/uZ8WP/me1X+5XlT/uV3UP/ldU7+5HNM/+RySv7ohWP+9MW1//fa0P732s/+5cm//jEr Kf4AAAD+AAAA+4GBgVMAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAC4uLgtAgIC8QAA AP8lIyL96NnT/vvp4//66OL/9cu9/+2kiv/toIX/7J2C/+ybfv/rmHv/65Z4/+qTdf/qkXL/6Y5v/+mM bP/oimn/6Idm/+iFY//ng2D/54Fd/+Z/Wv/mfVj/5ntV/+V5U//ld1H/5XZO/+R0TP/kckr/5HNM/++s lf/32s//+NrQ/+XJwP4lIB79AAAA/wICAvG4uLgtAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAOjo 6AgVFRXNAAAA/gsKCv7Pw779+uvl/vrq5P/0xbX+7qiQ/+6ljP7to4n+7aCF/uyegv/sm3/+65l8/uuW ef/qlHX+6pFy/umPb//pjGz+6Ipp/uiIZv/ohmP+54Ng/ueBXv/mf1v+5n1Y/uZ7Vv/leVP+5XdR/+V1 T/7kdE3+5HJK/+RxSf7snYH+99rP//faz/7NtKv9CwkJ/gAAAP4VFRXN6OjoCAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAFxcXHsAAAD/AAAA/5aNivz77Of/++zm//bSxf/vrpf/76uT/+6okP/upo3/7aOJ/+2h hv/snoP/7Jt//+uZfP/rlnn/6pR2/+qSc//pj3D/6Y1s/+mKaf/oiGb/6IZk/+eEYf/ngV7/5n9b/+Z9 Wf/me1b/5XlU/+V3Uf/ldk//5XRN/+RzS//kcUn/76yV//ja0P/42tD/lIJ7/AAAAP8AAAD/XFxcewAA AAAAAAAAAAAAAAAAAAAAAAAAiYmJGwAAAPQAAAD+Pzw7/fvt6P777ej++eHZ/vG1oP/wsZv+766Y/yAX FP4gFxP+IBYT/iEWE/8gFhL+IBUS/iAVEf8gFRH+HxQQ/iAUEP8fEw/+HxMP/iATD/8fEg7+HxIO/iAS Df8fEg3+HxEM/iARDP8fEQz+IBEM/x8QC/4fEAv+jkkx/+R0Tf7kc0v+5HRM//PFtf732tD+99rP/j42 NP0AAAD+AAAA9ImJiRsAAAAAAAAAAAAAAAAAAAAADg4OkwAAAP8DAwP+zMK+/vzu6v/77Of+88Oz/vG3 ov/wtJ/+8LGb/yAXFP4gFxT+IBcT/iEXE/8gFhP+IBYS/iAWEv8gFRH+IBUR/iAUEP8fFBD+HxQP/iAT D/8fEw/+HxIO/iASDv8fEg3+HxIN/iASDf8fEQz+IBEM/x8QC/4fEAv+j0oz/+V3UP7kdU7+5HNM/+iG ZP732M3++NvQ/8mxqP4DAwP+AAAA/w4ODpMAAAAAAAAAAAAAAAAAAAAWAAAA8gAAAP9WUlD8+/Ds/vzv 6//42tD+8ryq/vK6pv/xt6P+8LSf/yAYFf4gFxT+IBcU/iEXFP8gFhP+IBYT/iEWEv8gFRL+IBUR/iAV Ef8fFBD+HxQQ/iAUEP8fEw/+HxMP/iATDv8fEg7+HxIN/iASDf8fEQz+IBEM/x8RDP4fEAv+j0w1/+V5 Uv7ld1D+5XVO/+RzTP7vrpj++NvR//fa0P5USkb8AAAA/wAAAPIAAAAWAAAAAAAAAAAAAABxAAAA/wIC Av7Mw8D9/PHt//vu6f/0xrb/87+u//K9qv/yuqf/8bej/7yNff+8i3r/vIl3/7uHdf+7hXL/u4Nw/7qB bf+6f2r/un1o/7l7Zf/llnv/65h7/+uWeP/aiW3/t3FZ/7dvVv+2bVT/tmxR/7ZqT/+2aE3/tWZL/7Vl Sf+1Y0b/0HFP/+Z7Vf/leVP/5XdR/+V1Tv/mfVn/99bK//jb0f/IsKj9AgIB/gAAAP8AAABxAAAAAAAA AAEAAADJAAAA/jg2Nf388u7+/PHu/vjf1v/0xbX+88Kx/vPArv/yvav+8rqn/yAZFv4gGBb+IBgV/iEY Ff8gFxT+IBcU/iEXE/8gFhP+IBYS/iAWEv/TjHT+7Jt//uuYe/+rbVj+HxQQ/iAUD/8fEw/+HxMO/iAT Dv8fEg7+IBIN/x8RDf4fEQz+j084/+Z9WP7me1b+5XlT/+V3Uf7ldU7+76+Y//fb0f732tH+NzAu/QAA AP4AAADJAAAAAQAAAB0AAAD6AAAA/pGMiv388+/+/PLu/vbRxP/0yLn+9MW1/vPDsv/zwK7+8r6r/yAZ Fv4gGRb+IBgW/iEYFf8gGBX+IBcU/iEXFP8gFhP+IBYT/iEWEv/Tj3f+7J6C/uybf/+scFv+HxQQ/iAU EP8fEw/+HxMP/iATDv8fEg7+IBIO/x8SDf4fEQ3+kFA6/+d/W/7mfVj+5ntW/+V5U/7leFH+6IZk//fb 0f7329H+j354/QAAAP4AAAD6AAAAHAAAAFwAAAD/AAAA/+HZ1/398/D/++vm//XOwP/1y7z/9Mi5//TG tv/zw7L/88Gv/1VDPf9VQjv/VUE6/1VAOf9VPzj/VD42/1Q9Nf9UPDT/VDsz/1Q7Mv/aln7/7aGG/+2e g/+8fGb/UzYs/1I1K/9SNCn/UjMp/1IzJ/9SMSb/UjEl/1IwJP9SLyP/pl5F/+eCXv/ngFv/5n5Z/+Z8 Vv/melT/5XhS//TGtv/43NL/3cO6/QAAAP8AAAD/AAAAXAAAAJIAAAD+JCMi/fz18v/89PH++eLa/vbR w//1zsD+9cu9/vXJuv/0xrb+88Sz/4ptY/6JbGH+iWpf/olpXf+JZ1v+iGZZ/ohkV/+IY1b+iGFU/odf Uv/hnYb+7aSK/u2hh//MiXL+hlhI/oVXRv+FVUX+hVRD/oVSQf+EUT/+hFA9/4ROPP6ETTr+vG1R/+eE Yf7ngl/+54Bc/+Z+Wf7mfFf+5XpU/+6njv743NP++NzS/yMfHf0AAAD+AAAAkgAAALwAAAD+W1hX/f31 8//89fL++NzS/vbTx//20cT+9c7B/vXMvf/0ybr+9Me3/yEaGP4gGhj+IBoX/iEaF/8gGRb+IBkW/iEY Ff8gGBX+IBcU/iEXFP/Vl4H+7qeO/u6kiv+tdmP+IBUS/iAVEf8gFRH+HxQQ/iAUEP8fEw/+IBMP/x8T D/4fEg7+kVVA/+iHZf7ohGL+54Jf/+eAXP7mflr+5nxX/+mObv743dP++NzT/1lPS/0AAAD+AAAAvAAA AN4AAAD/iYaF/v329P/89PH/+NrP//fWy//31Mj/9tHE//bPwf/1zL7/9cq6/yEbGf8hGxj/IRoY/yEa F/8hGhf/IRkX/yEZFv8hGRX/IRgV/yEYFf/VmoX/76qS/+6nj/+ueGb/IRYS/yAWEv8gFRH/IBUR/yAU EP8gFBD/IBQQ/yATD/8gEw//kVZC/+iJaP/oh2X/6IVi/+eDX//ngF3/5n5a/+eAXP/32Mz/+N3U/4Z3 cv4AAAD/AAAA3gAAAPEAAAD+q6el/f339f/88e3++NvR/vfZzv/318v+99TI/vbSxf/2z8H+9c2+/4tz a/6LcWn+inBn/opvZf+KbWP+iWxh/olqX/+JaF3+iWdb/ohlWf/jppH+762W/u+qkv/OkXz+h15Q/odc Tv+HW0z+hlpK/oZYSP+FV0b+hVVE/4VUQ/6FUkH+vXNZ/+mMa/7oiWj+6Idm/+iFY/7ng2D+54Fd/+Z/ Wv71yrv++N3U/6eUjv0AAAD+AAAA8QAAAPwAAAD+vbm4/v339f/77+r++N7V/vjc0v/42c/+99fM/vfU yP/20sX+9tDC/1ZIQ/5WR0L+VkZA/lVFP/9VRD7+VUM9/lVCPP9VQTr+VUA5/lQ/OP9UPzf+VD02/lQ9 NP9UOzP+VDsy/lQ6Mf9UOTD+Uzgu/lM3Lf9TNiz+UjUr/1I1Kv5SMyn+p2hR/+mPb/7pjGz+6Ypp/+iI Zv7ohWP+54Ng/+eBXv7yvqz++d7V/7mmn/4AAAD+AAAA/AAAAPwAAAD/vbq4/v749v/88Oz/+eHY//ne 1f/43NL/+NrP//fXzP/31cn/9tLG/yIcGv8iHBr/IRwa/yEbGf8hGxj/IRoY/yEaGP8hGhf/IRkX/yEZ Fv8hGRb/IRgV/yEYFf8hGBT/IRcU/yEXE/8hFxP/IRYT/yEWEv8gFRL/IBUR/yAVEf8gFBD/klxJ/+qR c//qj2//6Y1s/+mKaf/oiGb/6IZj/+eEYf/zv63/+d/W/7qmn/4AAAD/AAAA/AAAAPEAAAD+q6in/f75 9//99PH++ePc/vnh2f/539b++N3T/vja0P/32M3+99XK/yEcG/4hHBr+IRwa/iIbGv8hGxn+IRsZ/iEa GP8gGhj+IBkX/iEZF/8gGRb+IBgW/iEYFf8gGBX+IBcU/iEXFP8gFxP+IBYT/iEWEv8gFhL+IBUS/yAV Ef4gFBH+kl5L/+qUdv7qknP+6o9w/+mNbf7pi2r+6Ihn/+iGZP71zb/++d/W/6iWj/0AAAD+AAAA8QAA AN4AAAD+ioeH/v75+P/99/b++ubf/vnk3P/54dn++d/W/vjd0//42tD+99jN/8Gon/7Bppz+waSa/sGi l//AoJX+wJ6S/r+cj/+/mo3+vpeK/r6Vh/++k4X+vZGC/r2Pf/+8jX3+vIt6/ryJd/+7h3X+u4Vy/ruD b/+6gW3+un9q/7l9Z/65emX+1Ytx/+uXev7rlXf+6pJz/+qQcP7pjW3+6Ytq/+mMa/7429H++eDX/4d5 dP4AAAD+AAAA3gAAALwAAAD/W1pa/f76+f/++fj/++vm//rm3//65Nz/+eLa//nf1//43dT/+NvR//fY zf/YvLH/Ix4c/yIcGv8iHBr/gmxk//TJuv/0x7f/88S0//PBsP/zv63/8ryp//G6pv/xt6L/8LSf//Cy nP/wr5j/7qyU/zMkH/8hFxP/IRYT/1E3Lv/tn4T/7J2B/+yaff/rl3r/65V3/+qSdP/qkHH/6Y5u/+yd gf/54dn/+eDY/1lQTf0AAAD/AAAAvAAAAJIAAAD+JCQk/f36+f/9+vn+/PHt/vvo4v/65uD++uTd/vni 2v/54Nf++N7U//jb0f7x08j+Ligm/iIdG/8hHBr+UkVA/vXMvv/1yrv+9Me3/vTFtP/zwrH+87+t/vK9 qv/yuqf+8bej/vG1oP/wspz+0pqG/iEXFP8gFxT+IRcT/3NQQ/7tooj+7Z+F/+ydgf7smn7+65h7/+uV eP7qk3T+6pBx//G2of754tn++OHZ/yMgHv0AAAD+AAAAkgAAAFwAAAD+AAAA/uLf3/39+vn+/ff1/vvr 5f/66eP++ufg/vrl3f/54tr++eDX//je1P7429H+U0lF/iIdG/8hHRv+JyEf/unFuP/1zb/+9cq7/vTH uP/0xbT+88Kx/vPArv/yvar+8rqn/vG4pP/xtaD+nHRm/iEYFf8gFxT+IRcU/51uXv7upYz+7aKJ/+2g hf7snYL+7Jt+/+uYe/7rlnj+6pN1//bRxP754tr+3snC/QAAAP4AAAD+AAAAXAAAAB0AAAD6AAAA/5KR kP3++/r//vr5//zv6//76+b/+unj//rn4f/65d7/+ePb//ng2P/43tX/h3hz/yIeHP8iHRz/Ih0b/6uR if/20ML/9c2///XLvP/0yLj/9MW1//PDsv/zwK7/8r6r//K7qP/xuKT/WUM7/yEYFf8hGBX/IRgU/8+U f//uqI//7qaM/+2jif/toIX/7J6C/+ybf//rmXz/7aKI//nj3P/649v/kIJ+/QAAAP8AAAD6AAAAHAAA AAEAAADJAAAA/jg4OP39+/r+/fv6/v318//77en+++vm/vvp4//65+H++uXe//nj2/754dj+xLCp/iIe Hf8hHRz+IR0c/l5QTP/20sb+9tDD/vXNwP/1y7z+9Mi5/vTGtv/zw7L+88Cv/vK+q//ZqJf+Jh0a/iEZ Fv8gGBX+PCwn/++tl/7vq5T+7qiQ/+6mjf7to4n+7aGG/+yeg/7sm3/+88S0//nk3f7549z+NzIw/QAA AP4AAADJAAAAAQAAAAAAAABxAAAA/wICAv7NzMv9/vz7//37+v/88e3/++7p//vs5v/76uT/+ujh//rl 3v/549v/9t7W/zcyMP8iHh3/Ih4c/yYhH//Ut63/9tPH//bQw//1zsD/9cu9//TJuf/0xrb/9MOz//PB r/+FaV//IRkX/yEZFv8hGRb/gF9U//Cxm//vrpf/76yU/+6pkf/upo3/7aSK/+2hhv/upYz/+eLa//rl 3v/KubP9AgIC/gAAAP8AAABxAAAAAAAAAAAAAAAWAAAA8gAAAP9WVlb8/vz7/v78+//99/X+/PDs/vvu 6f/77Of+++rk//ro4f765t/++eTc/od7dv8hHh3+IR4d/iIeHP9tX1r+9tXK/vbTx//20cT+9c7B/vXM vf/0ybr+9Ma3/uC1pf8vJSL+IBoX/iEaF/8jGxj+zpyL//C0n/7wsZv+8K+Y/++slP7uqZH+7qeO/+2k iv70ybr++ubg//nm3/5VTkv8AAAA/wAAAPIAAAAWAAAAAAAAAAAAAAAADg4OkwAAAP8EAwP+zs3M/v78 +//++/v+/PPx/vzw7P/77ur+++zn//vr5f766OL++ubf/t/Mxf8qJiX+IR4d/iIeHf8kIB/+wKig/vfW y//21Mf+9tHE/vbOwf/1zL7+9Mm6/nFcVf8hGhj+IBoY/iEaF/9fSkL+8bmm//G3o/7wtJ/+8LKc//Cv mP7vrJX+76qS//C0n/765t/++ufh/8q7tf4DAwP+AAAA/w4ODpMAAAAAAAAAAAAAAAAAAAAAiYmJGwAA APQAAAD/QEBA/f78/P7+/Pz//fr5//zy7//88Oz//O/q//vt6P/76+X/+uni//rm4P+Cd3P/Ih8e/yIe Hf8iHh3/OzQy/+HFu//31sv/9tTI//bSxf/2z8H/qIyC/yIcGv8hGxn/IRsY/yUeG//Ino//8r2q//K6 p//xt6P/8bWg//CynP/wr5n/766X//jd0//76eL/+ujh/j86Of0AAAD/AAAA9ImJiRsAAAAAAAAAAAAA AAAAAAAAAAAAAFxcXHsAAAD+AAAA/piXl/z+/Pz+/vz8/v349//88u/+/PHt//vv6v777ej+++vl/vrp 4//t29T+QTs5/iIfHv8hHh3+IR4d/jcwLv+lkYr+6svA/tm7sP95Z2H+JB4c/iIcGv8hGxn+IRsZ/oFp YP/zwrH+88Cu//K9q/7yuqf+8bik//G1oP7ws53+9tHE//rq5P766eP+louH/AAAAP4AAAD+XFxcewAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAOjo6AgVFRXNAAAA/gsLC/7S0dH9/v38/v78/P/99/X+/PPv//zx 7f777+v+++3o/vvr5v/66eP+0MC7/i8rKv8hHx7+IR4d/iIeHf8hHhz+KiUj/iQgHv8hHRv+IRwb/iIc Gv8hHBr+WktF/u7DtP/0xbX+88Oy//PArv7yvqv+8ruo//G4pP71zb7++uvm//rr5f7Pwr39CwoK/gAA AP4VFRXN6OjoCAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAC4uLgtAgIC8QAAAP8mJib96+rq/v79 /P/+/Pz//fn3//zz8P/88e3//O/r//vt6f/77Ob/+unk/8i5tP8vKyr/Ih8e/yIfHf8iHh3/Ih4d/yIe HP8iHRz/Ih0b/yIdG/9YSkb/6sS3//XLvP/0yLn/9Ma2//PDsv/zwa//87+t//fYzf/77ej/++zn/+ja 1f4lIyL9AAAA/wMDA/G4uLgtAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAgYGBUwAA APsAAAD+MzMz/uvq6v7+/fz+/v38//36+f799fL+/PHu/vzw6//77un+++zm/vvq5P/TxL/+TEZE/iIf Hv8hHh3+IR4d/iIeHf8hHRz+JiEf/nlpY//uzMD+9tDD/vXOwP/1y73+9Mm6//TGtv71zL7++ubf//vu 6v777un+6dvX/jIvLv4AAAD+AAAA+4GBgVMAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAHFxcW4AAAD9AAAA/iYmJv3S0tH9/v38//78/P7+/Pv+/fj2/vzy7//88Oz+++7p/vvs 5//76uT+9uTe/r+wqv+UiIP+joF8/o6Ae/+djIb+1761/vfYzf/31sr+9tPH/vbRxP/1zsH+9s/C//ng 1/777+v+/PDs//vv6/7QxcH9JSMi/QAAAP4AAAD9cXFxbgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABxcXFuAAAA+wAAAP8LCwv+mJeX/P78/P7+/fz//vz8//77 +v/99/X//PLu//zu6v/77Of/++rl//ro4v/65t//+uTd//ni2v/54Nf/+N3U//jb0f/32c7/99bL//fZ zv/65N3//PHt//zy7v/88e3/+/Ds/paPjfwLCgr+AAAA/wAAAPtxcXFuAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAgYGBUwICAvEAAAD+AAAA/0BA QP3Ozc3+/vz8/v78/P/+/Pv+/fv6/v349//89PH+/O/r/vvr5v/66eL++ubg/vrk3f/54tr++eHY/vni 2//65+H+++/q/vz08f/89PH+/fPw//zy7/7MxMH+Pz08/QAAAP4AAAD+AwMD8YGBgVMAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAALi4 uC0VFRXNAAAA/wAAAP4EBAP+VlZW/M7MzP3+/Pv+/vz7/v77+//9+/r+/fr5/v35+P/99vT+/PPw/vzy 7//99PH+/fb0/v339f/89vT+/Pbz/v318v/89PH+zMXD/VZTUfwDAwP+AAAA/wAAAP4VFRXNuLi4LQAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAADo6OgIXFxcewAAAPQAAAD/AAAA/wICAv44ODj9kpGR/eLg4P3++/v//vv6//77 +v/++vn//vr4//75+P/++ff//vj2//349v/99/X/4dzZ/ZGNjP04Njb9AgIC/gAAAP8AAAD/AAAA9Fxc XHvo6OgIAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAImJiRsODg6TAAAA8gAAAP8AAAD+AAAA/gAA AP8kJCT9W1pa/YqIiP6rqaj9vbu6/r26uf6rqKf9iYeG/ltZWP0kIyP9AAAA/gAAAP8AAAD+AAAA/wAA APIODg6TiYmJGwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFgAA AHEAAADJAAAA+gAAAP8AAAD+AAAA/gAAAP8AAAD+AAAA/gAAAP8AAAD+AAAA/gAAAP8AAAD+AAAA/gAA APoAAADJAAAAcQAAABYAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAABAAAAHAAAAFwAAACSAAAAvAAAAN4AAADxAAAA/AAAAPwAAADxAAAA3gAA ALwAAACSAAAAXAAAABwAAAABAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAP//AAD//wAA//wAAD//AAD/8AAAD/8AAP/AAAAD/wAA/4AAAAH/ AAD/AAAAAP8AAP4AAAAAfwAA/AAAAAA/AAD4AAAAAB8AAPAAAAAADwAA4AAAAAAHAADgAAAAAAcAAMAA AAAAAwAAwAAAAAADAACAAAAAAAEAAIAAAAAAAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACAAAAAAAEAAIAAAAAAAQAAwAAAAAAD AADAAAAAAAMAAOAAAAAABwAA4AAAAAAHAADwAAAAAA8AAPgAAAAAHwAA/AAAAAA/AAD+AAAAAH8AAP8A AAAA/wAA/4AAAAH/AAD/wAAAA/8AAP/wAAAP/wAA//wAAD//AAD//wAA//8AACgAAAAgAAAAQAAAAAEA IAAAAAAAgBAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAADwAAAFkAAACbAAAAywAAAOwAAAD8AAAA/AAAAOwAAADLAAAAmwAAAFkAAAAPAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAQ0NDJQAAAJ0AAAD1AAAA/wUEBP4yLSv+XlRQ/npsaP56bGf+XlNP/jIsKv4FBAT+AAAA/wAA APUAAACdQ0NDJQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAA6+vrCldXV4wAAAD6AAAA/kU/PP6klI797NXM/vnf1v/53tX/+N3U//jd0//43NL/+NvR/+vQ xv6kkIn9RTw5/gAAAP4AAAD6V1dXjOvr6woAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAMfHxyUbGxvTAAAA/0I8Ov7KuLL9+eLa//nh2f/1z8H/8LOd/+ycgP/pimn/6Idl/+qV d//uqpL/9Me3//fb0f/42tD/ybCo/UE5Nv4AAAD/Gxsb08fHxyUAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAC7u7sxCwsL6goJCf6ZjYn9+eXe/vnj2//0xLT/7J2B/+mLav/oiGb/54Ri/+eB Xv/mfln/5ntW/+V4Uv/ldU//6IVi//CynP/32c7/99rP/peFf/0KCAj+CwsL6ru7uzEAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAx8fHJQsLC+oWFBT+y7y3/frn4f/21cn/7qeO/+uXef/qk3T/6o9w/+mM a//oiGf/6IVi/+eBXv/mflr/5ntW/+V5U//ldk//5HNM/+eCX//zwbD/+NrQ/8mwqP0WExL+CwsL6sfH xyUAAAAAAAAAAAAAAAAAAAAAAAAAAOvr6wobGxvTCgkJ/su+uf366eP/9Mi5/+2jif/sn4T/7Jt+/+uX ev/qk3X/6pBw/+mMbP/oiWf/6IVj/+eCX//mf1v/5nxX/+V5U//ldlD/5HRM/+RyS//up47/99nP/8mw qP0KCAj+Gxsb0+vr6woAAAAAAAAAAAAAAAAAAAAAV1dXjAAAAP+akY79++vm//XOwP/vq5P/7qeO/+2j if/tn4T/7Jt//+uYev/qlHb/6pBx/+mNbP/oiWj/6IZk/+eCX//mf1v/5nxX/+V5VP/ld1D/5HRN/+Ry Sv/up47/+NrQ/5eFf/0AAAD/V1dXjAAAAAAAAAAAAAAAAENDQyUAAAD6Qj89/vvt6f754Nf/8LSf//Cw mf/up47/7aOJ/+2fhP/sm3//65h6/+qUdv/qkHH/6Y1s/+iJaP/ohmT/54Jf/+Z/W//mfFf/5XlU/+V3 UP/kdE3/5XVN/+RzTP/zwbD/99rQ/kE5Nv4AAAD6Q0NDJQAAAAAAAAAAAAAAnQAAAP7Mwr/9++7p//TE tP/xuKT/8bSf/yEXFP8hFxP/IRYS/yAWEv8gFRH/IBQQ/yAUEP8gEw//IBMP/yATDv8gEg3/IBIN/yAR DP8gEQz/HxAL/2k2Jf/leFH/5XVO/+eEYf/32c7/ybGo/QAAAP4AAACdAAAAAAAAAA8AAAD1RkNC/vzx 7f/439b/88Gv//K9qv/xuaX/IRgV/yEXFP8hFxP/IRYT/yAWEv8gFRH/IBUR/yAUEP8gFA//IBMP/yAT Dv8gEg3/IBIN/yARDP8gEQz/ajgn/+Z7Vf/leFL/5XVO//Cznv/429H/RT06/gAAAPUAAAAPAAAAWQAA AP+noJ79/PLu//bQw//0xbX/88Gw//K9q/+IZlr/iGRX/4hiVP+HX1H/h11O/4dbTP+galf/65l9/+uW eP+RWkf/hFA+/4ROO/+ETDn/g0o3/4NJNP+oW0D/5n5a/+Z7Vv/leFL/6Idl//fb0f+kkYr9AAAA/wAA AFkAAACbBQQE/vDo5f777Of/9c7A//XKu//0xrb/88Kx/yEZFv8hGRb/IRgV/yEXFP8hFxP/IRYT/1Q4 L//snoL/7Jp9/zklHf8gFA//IBMP/yATDv8gEg7/IBIN/2o7Kv/ngl7/5n9a/+Z8Vv/leVP/9Mi5/+zR x/4FBAT+AAAAmwAAAMszMjH+/fXy//rl3v/20sX/9c7B//XKvP/0x7f/imxi/4lqX/+JaFz/iGVZ/4hj Vv+IYVT/oXFf/+2iiP/snoP/k2BP/4VWRf+FVEP/hVJA/4RQPf+ETjv/qWFI/+iFY//ngl//5n9b/+Z8 V//vrJX/+NzT/zIsKv4AAADLAAAA7GBeXf799vT/+eHZ//fWy//208b/9c/B//XLvP8hGhj/IRoX/yEZ F/8hGRb/IRgV/yEYFP9UPDP/7qeO/+2jif86JyD/IBUR/yAUEP8gFBD/IBMP/yATDv9rPi//6Ilo/+iG ZP/ng2D/54Bc/+uYfP/43dT/XlNQ/gAAAOwAAAD8fXp5/v339f/54dj/+NrQ//fXy//208f/9s/C/4tz a/+LcWj/im5l/4psYv+Jal//iWhc/4hmWf+IY1f/iGFU/4dfUf+HXU7/h1pL/4ZYSP+FVkX/hVRD/6tp Uv/pjW3/6Ypp/+iGZP/ng2D/6Yxs//ne1f96bWj+AAAA/AAAAPx9enr+/fj2//rk3f/43tX/+NvR//fX zP/21Mj/Ihwa/yEcGv8hGxn/IRsY/yEaGP8hGRf/IRkW/yEYFf8hGBX/IRcU/yEXE/8hFhP/IBYS/yAV Ef8gFRH/bEQ2/+qRc//pjm7/6Ypp/+iHZf/qj3D/+d/W/3ptaf4AAAD8AAAA7GBfXv7++ff/++vl//ni 2v/439b/+NvR//fYzf+MeXL/jHdw/4t1bf+Lcmr/inBn/4puZP+JbGH/iWle/4lnXP+IZVn/iGNW/4hg U/+HXlD/h1xN/4ZaSv+scFv/65Z4/+qSc//pjm//6Ytq/+2hh//54Nf/XlRR/gAAAOwAAADLMzMy/v76 +P/88e3/+ubf//nj2//54Nf/+NzS//fYzv9aTkr/Ihwa/1pLRv/0ybr/9Ma1//PCsP/yvqv/8rqm//G2 of/wspz/66uU/ykcGP8hFhP/il5O/+yegv/smn7/65Z5/+qTdP/qj2//8bij//nh2P8yLSz+AAAAywAA AJsFBQX+8e7t/v339f/76uT/+ufg//nj3P/54Nf/+N3T/4Nzbf8iHRv/LCUj//DJvP/1yrv/9Ma2//PC sf/yvqz/8rqn//G2ov/Bj37/IRcU/yEXFP+xe2n/7aKI/+yfg//sm37/65d5/+qTdf/20sb/7dfP/gUE BP4AAACbAAAAWQAAAP+opqX9/vv6//zv6//76uT/+ufh//nk3P/54dj/tqOc/yIeHP8iHRv/t5yT//bO wf/1y7z/9Me3//PDsv/zv63/8ruo/39hVv8hGBX/IxoW/+Cgiv/up47/7aOJ/+2fhP/sm3//7qWL//nj 3P+llpH9AAAA/wAAAFkAAAAPAAAA9UdGRv7+/Pv//ff0//vu6f/76+X/+ujh//rk3f/v2ND/Kycl/yIe HP9jVlH/9tPG//bPwv/1y73/9Me4//PDs//suqn/NCgk/yEZFv9VPzf/8K+Z/++rlP/up4//7aSK/+2g hf/0ybr/+uXd/0U/Pf4AAAD1AAAADwAAAAAAAACdAAAA/s7NzP39+/v//PLv//vu6f/76+b/+uji//rl 3v91amb/Ih4d/yMfHv/Msaj/9tPH//bPwv/1zL3/9Mi4/5Z5b/8hGhf/IRkX/6V+cP/xtJ//8LCa/++s lf/uqJD/8K+Z//rm3//KurX9AAAA/gAAAJ0AAAAAAAAAAENDQyUAAAD6Q0JC/v78/P79+fj//PHu//vu 6v/77Ob/+uni/9rIwv8mIyL/Ih4d/0lAPf/tz8T/99TI//bQw//TsKP/LCQh/yEbGP8/Mi7/7rmn//G5 pf/xtaD/8LGb/++tlv/42s//+ujh/kI9O/4AAAD6Q0NDJQAAAAAAAAAAAAAAAFdXV4wAAAD/nJub/f78 /P/9+Pb//PLu//zv6v/77Of/+unj/5CFgf8iHx7/Ih4d/0I6OP+ijYX/j3t0/y8oJf8iHBr/JR4c/76a jf/zwbD/8r2r//G5pv/xtaH/9s/B//vq5P+Zj4v9AAAA/1dXV4wAAAAAAAAAAAAAAAAAAAAA6+vrChsb G9MKCgr+zs3N/f78/P/9+Pb//PLv//zv6//77Of/+eji/3dua/8iHx7/Ih4d/yIeHP8iHRz/Ih0b/yQe HP+mi4L/9cq7//TGtv/zwrH/876s//fUyP/77Of/y7+6/QoJCf4bGxvT6+vrCgAAAAAAAAAAAAAAAAAA AAAAAAAAx8fHJQsLC+oWFhb+zs3N/f79/P/9+vn//PTx//zw6//77ej/+enj/5uPi/86NTP/Ih8e/yQg Hv9KQT7/u6KZ//bSxf/1zsD/9cq7//XNv//65d3//O7q/8zAvP0WFRT+CwsL6sfHxyUAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAu7u7MQsLC+oKCgr+nJub/f78/P7+/Pv//fj2//zy7v/77ej/++rl//rn 4f/65Nz/+eHY//jd1P/42s//99bL//fYzf/65N3//PHt//vw7P6ak5D9CgkJ/gsLC+q7u7sxAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAx8fHJRsbG9MAAAD/Q0NC/s7Nzf3+/Pz//vz7//35 9//89PH/++/q//vq5P/65+D/+ufh//rq5P/88Oz//PTy//308P/NxcL9Qj8+/gAAAP8bGxvTx8fHJQAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA6+vrCldXV4wAAAD6AAAA/kdG Rv6op6b98e/v/v77+v/++vn//vr4//759//9+Pb//ff1//Dq6P6noqD9RkRD/gAAAP4AAAD6V1dXjOvr 6woAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAEND QyUAAACdAAAA9QAAAP8FBQX+MzMz/mBfX/59e3v+fXt6/mBeXv4zMjL+BQUE/gAAAP8AAAD1AAAAnUND QyUAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAPAAAAWQAAAJsAAADLAAAA7AAAAPwAAAD8AAAA7AAAAMsAAACbAAAAWQAA AA8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA/8AD//8AAP/8AAA/+AAAH/AA AA/gAAAHwAAAA8AAAAOAAAABgAAAAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAIAAAAGAAAABwAAAA8AAAAPgAAAH8AAAD/gAAB/8AAA//wAA///AA/8oAAAAEAAAACAA AAABACAAAAAAAEAEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABAQEDAAAACXDQwL2TYw Lvk2MC35DQwL2QAAAJcQEBAwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA8fHxCVdXV5pDPTv9t6af/vPN wP7xuKT/8bWg//HHuP62oJn+Qjo3/VdXV5rx8fEJAAAAAAAAAAAAAAAA8fHxCTo6OcGajor+9tHE/u2j if/pi2v/6IVi/+Z+Wv/leFL/6Ihm//K9q/6Yhn/+Ojk5wfHx8QkAAAAAAAAAAFdXV5qakY3+9cu8/+2j if/sm3//6pR1/+mMbP/ohmP/5n9b/+V5U//ldE3/7qaN/5iGgP5XV1eaAAAAABAQEDBDQD/9+eDX/vC0 n/8hFxT/IBYT/yAVEf8gFBD/IBMP/yASDf8gEQz/IBEM/+V1Tv/yvqz+Qjo3/RAQEDAAAACXubKv/vXN v//yvav/VD83/1Q8NP9UOTD/s3Zh/6hsVv9SMSb/Ui8j/208K//me1b/6Ypp/7ahmf4AAACXDg0N2fjs 5/71zsD/9Ma2/yARDP8gEQz/IBEM/7R9av9TOC//IBEM/yARDP8gEQz/54Jf/+Z8V//yyLr+DQwL2Tc2 Nfn77Of/99fL//bPwv9WRkH/VUM9/1VBOv+VbF7/Uzgv/1M4L/9TNiv/bkQ1/+mKaP/ng2D/8bik/zYw Lvk3Njb5/PDs//jf1v/32M3/IBEM/yARDP8gEQz/IBEM/yARDP8gEQz/IBEM/yARDP/qknP/6Ytq//K8 qf82MC75Dg4O2fr08v765t//+eDX/7Oelv9uRDX/88m6//PCsf/yuqf/46mU/25ENf/FhnD/7Jp+/+qT dP/z0MT+DQwM2QAAAJe6ubj+/O/r//rn4f/m0Mj/JCAe/8Klm//1y7z/88Oy/6SAc/8uIh7/66mR/+2j if/vqpL/t6ei/gAAAJcQEBAwRERD/f359/777ur/+uji/2ZdWv9WTEj/9NHF/+zFt/9BNDD/fWFX//G0 n//vrZX/99bK/kM+PP0QEBAwAAAAAFdXV5qcnJv+/ff1//zv6//g0cv/NzIx/0pBPv9ANzT/RDk1/+a7 q//yvqv/9tHE/5qQjf5XV1eaAAAAAAAAAADx8fEJOjo6wZ2cm/79+fj+/PHu/+PUz/+UiIT/mIiC/+jJ vv/31cn/+eXd/puTkP46OjnB8fHxCQAAAAAAAAAAAAAAAPHx8QlXV1eaRERE/bq5uf769vT+/PPw//zw 7P/57+v+urSx/kRBQP1XV1ea8fHxCQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABAQEDAAAACXDg4O2Tc2 Nvk3Njb5Dg0N2QAAAJcQEBAwAAAAAAAAAAAAAAAAAAAAAPAPAADAAwAAgAEAAIABAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAIABAACAAQAAwAMAAPAPAAA= Translation/TrlUtil/TrlImport.cs0000664000000000000000000001047513222430420015735 0ustar rootroot/* KeePass Password Safe - The Open-Source Password Manager Copyright (C) 2003-2018 Dominik Reichl This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ using System; using System.Collections.Generic; using System.Text; using System.IO; using System.Diagnostics; using KeePassLib.Translation; using KeePassLib.Utility; namespace TrlUtil { public static class TrlImport { public static void Import1xLng(KPTranslation kpInto, string strFile) { if((strFile == null) || (strFile.Length == 0)) { Debug.Assert(false); return; } string strData = File.ReadAllText(strFile, StrUtil.Utf8); Dictionary dict = new Dictionary(); const int nStatePreEn = 0; const int nStateInEn = 1; const int nStateBetween = 2; const int nStateInTrl = 3; StringBuilder sbEn = new StringBuilder(); StringBuilder sbTrl = new StringBuilder(); int nState = nStatePreEn; for(int i = 0; i < strData.Length; ++i) { char ch = strData[i]; if(ch == '|') { if(nState == nStatePreEn) nState = nStateInEn; else if(nState == nStateInEn) nState = nStateBetween; else if(nState == nStateBetween) nState = nStateInTrl; else if(nState == nStateInTrl) { dict[sbEn.ToString()] = sbTrl.ToString(); sbEn = new StringBuilder(); sbTrl = new StringBuilder(); nState = nStatePreEn; } } else if(nState == nStateInEn) sbEn.Append(ch); else if(nState == nStateInTrl) sbTrl.Append(ch); } Debug.Assert(nState == nStatePreEn); dict[string.Empty] = string.Empty; MergeDict(kpInto, dict); } private static void MergeDict(KPTranslation kpInto, Dictionary dict) { if(kpInto == null) { Debug.Assert(false); return; } if(dict == null) { Debug.Assert(false); return; } foreach(KPStringTable kpst in kpInto.StringTables) { foreach(KPStringTableItem kpsti in kpst.Strings) { string strTrl; if(dict.TryGetValue(kpsti.ValueEnglish, out strTrl)) kpsti.Value = strTrl; } } foreach(KPFormCustomization kpfc in kpInto.Forms) { string strTrlWnd; if(dict.TryGetValue(kpfc.Window.TextEnglish, out strTrlWnd)) kpfc.Window.Text = strTrlWnd; foreach(KPControlCustomization kpcc in kpfc.Controls) { string strTrlCtrl; if(dict.TryGetValue(kpcc.TextEnglish, out strTrlCtrl)) kpcc.Text = strTrlCtrl; } } } public static void ImportPo(KPTranslation kpInto, string strFile) { if((strFile == null) || (strFile.Length == 0)) { Debug.Assert(false); return; } string strData = File.ReadAllText(strFile, StrUtil.Utf8); strData = StrUtil.NormalizeNewLines(strData, false); string[] vData = strData.Split('\n'); Dictionary dict = new Dictionary(); string strID = string.Empty; foreach(string strLine in vData) { string str = strLine.Trim(); if(str.StartsWith("msgid ", StrUtil.CaseIgnoreCmp)) strID = FilterPoValue(str.Substring(6)); else if(str.StartsWith("msgstr ", StrUtil.CaseIgnoreCmp)) { if(strID.Length > 0) { dict[strID] = FilterPoValue(str.Substring(7)); strID = string.Empty; } } } MergeDict(kpInto, dict); } private static string FilterPoValue(string str) { if(str == null) { Debug.Assert(false); return string.Empty; } if(str.StartsWith("\"") && str.EndsWith("\"") && (str.Length >= 2)) str = str.Substring(1, str.Length - 2); else { Debug.Assert(false); } str = str.Replace("\\\"", "\""); return str; } } } Translation/TrlUtil/MainForm.cs0000664000000000000000000010171413222430420015506 0ustar rootroot/* KeePass Password Safe - The Open-Source Password Manager Copyright (C) 2003-2018 Dominik Reichl This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ using System; using System.Collections.Generic; using System.ComponentModel; using System.Diagnostics; using System.Drawing; using System.Reflection; using System.Text; using System.Windows.Forms; using KeePass.App; using KeePass.Resources; using KeePass.UI; using KeePass.Util; using KeePass.Util.XmlSerialization; using KeePassLib; using KeePassLib.Resources; using KeePassLib.Serialization; using KeePassLib.Translation; using KeePassLib.Utility; namespace TrlUtil { public partial class MainForm : Form { private const string TrlUtilName = "TrlUtil"; private KPTranslation m_trl = new KPTranslation(); private string m_strFile = string.Empty; private ImageList m_ilStr = new ImageList(); private const string m_strFileFilter = "KeePass Translation (*.lngx)|*.lngx|All Files (*.*)|*.*"; private static readonly string[] m_vEmpty = new string[2] { @"", @"<>" }; private KPControlCustomization m_kpccLast = null; private const int m_inxWindow = 6; private const int m_inxMissing = 1; private const int m_inxOk = 4; private const int m_inxWarning = 5; private bool m_bModified = false; private PreviewForm m_prev = new PreviewForm(); private delegate void ImportFn(KPTranslation trlInto, IOConnectionInfo ioc); public MainForm() { InitializeComponent(); } private void OnFormLoad(object sender, EventArgs e) { this.Text += " " + PwDefs.VersionString; m_trl.Forms = FormTrlMgr.CreateListOfCurrentVersion(); m_rtbUnusedText.SimpleTextOnly = true; string strSearchTr = ((WinUtil.IsAtLeastWindowsVista ? string.Empty : " ") + "Search in active tab..."); UIUtil.SetCueBanner(m_tbFind, strSearchTr); this.CreateStringTableUI(); this.UpdateControlTree(); if(m_tvControls.SelectedNode == null) m_tvControls.SelectedNode = m_tvControls.Nodes[0]; UpdatePreviewForm(); m_prev.Show(); try { this.DoubleBuffered = true; } catch(Exception) { Debug.Assert(false); } UpdateUIState(); } private void CreateStringTableUI() { int nWidth = m_lvStrings.ClientSize.Width - 20; m_ilStr.ColorDepth = ColorDepth.Depth32Bit; m_ilStr.ImageSize = new Size(16, 16); m_ilStr.Images.Add(Properties.Resources.B16x16_Binary); m_ilStr.Images.Add(Properties.Resources.B16x16_KRec_Record); m_ilStr.Images.Add(Properties.Resources.B16x16_LedGreen); m_ilStr.Images.Add(Properties.Resources.B16x16_LedLightBlue); m_ilStr.Images.Add(Properties.Resources.B16x16_LedLightGreen); m_ilStr.Images.Add(Properties.Resources.B16x16_LedOrange); m_ilStr.Images.Add(Properties.Resources.B16x16_View_Remove); m_lvStrings.SmallImageList = m_ilStr; m_tvControls.ImageList = m_ilStr; m_lvStrings.Columns.Add("ID", nWidth / 5); m_lvStrings.Columns.Add("English", (nWidth * 2) / 5); m_lvStrings.Columns.Add("Translated", (nWidth * 2) / 5); m_trl.StringTables.Clear(); KPStringTable kpstP = new KPStringTable(); kpstP.Name = "KeePass.Resources.KPRes"; m_trl.StringTables.Add(kpstP); KPStringTable kpstL = new KPStringTable(); kpstL.Name = "KeePassLib.Resources.KLRes"; m_trl.StringTables.Add(kpstL); KPStringTable kpstM = new KPStringTable(); kpstM.Name = "KeePass.Forms.MainForm.m_menuMain"; m_trl.StringTables.Add(kpstM); KPStringTable kpstE = new KPStringTable(); kpstE.Name = "KeePass.Forms.MainForm.m_ctxPwList"; m_trl.StringTables.Add(kpstE); KPStringTable kpstG = new KPStringTable(); kpstG.Name = "KeePass.Forms.MainForm.m_ctxGroupList"; m_trl.StringTables.Add(kpstG); KPStringTable kpstT = new KPStringTable(); kpstT.Name = "KeePass.Forms.MainForm.m_ctxTray"; m_trl.StringTables.Add(kpstT); KPStringTable kpstET = new KPStringTable(); kpstET.Name = "KeePass.Forms.PwEntryForm.m_ctxTools"; m_trl.StringTables.Add(kpstET); KPStringTable kpstDT = new KPStringTable(); kpstDT.Name = "KeePass.Forms.PwEntryForm.m_ctxDefaultTimes"; m_trl.StringTables.Add(kpstDT); KPStringTable kpstLO = new KPStringTable(); kpstLO.Name = "KeePass.Forms.PwEntryForm.m_ctxListOperations"; m_trl.StringTables.Add(kpstLO); KPStringTable kpstPG = new KPStringTable(); kpstPG.Name = "KeePass.Forms.PwEntryForm.m_ctxPwGen"; m_trl.StringTables.Add(kpstPG); KPStringTable kpstSM = new KPStringTable(); kpstSM.Name = "KeePass.Forms.PwEntryForm.m_ctxStrMoveToStandard"; m_trl.StringTables.Add(kpstSM); KPStringTable kpstBA = new KPStringTable(); kpstBA.Name = "KeePass.Forms.PwEntryForm.m_ctxBinAttach"; m_trl.StringTables.Add(kpstBA); KPStringTable kpstTT = new KPStringTable(); kpstTT.Name = "KeePass.Forms.EcasTriggersForm.m_ctxTools"; m_trl.StringTables.Add(kpstTT); KPStringTable kpstDE = new KPStringTable(); kpstDE.Name = "KeePass.Forms.DataEditorForm.m_menuMain"; m_trl.StringTables.Add(kpstDE); KPStringTable kpstSD = new KPStringTable(); kpstSD.Name = "KeePassLib.Resources.KSRes"; m_trl.StringTables.Add(kpstSD); Type tKP = typeof(KPRes); ListViewGroup lvg = new ListViewGroup("KeePass Strings"); m_lvStrings.Groups.Add(lvg); foreach(string strKey in KPRes.GetKeyNames()) { PropertyInfo pi = tKP.GetProperty(strKey); MethodInfo mi = pi.GetGetMethod(); if(mi.ReturnType != typeof(string)) { MessageBox.Show(this, "Return type is not string:\r\n" + strKey, TrlUtilName + ": Fatal Error!", MessageBoxButtons.OK, MessageBoxIcon.Error); return; } string strEng = (mi.Invoke(null, null) as string); if(strEng == null) { MessageBox.Show(this, "English string is null:\r\n" + strKey, TrlUtilName + ": Fatal Error!", MessageBoxButtons.OK, MessageBoxIcon.Error); return; } KPStringTableItem kpstItem = new KPStringTableItem(); kpstItem.Name = strKey; kpstItem.ValueEnglish = strEng; kpstP.Strings.Add(kpstItem); ListViewItem lvi = new ListViewItem(); lvi.Group = lvg; lvi.Text = strKey; lvi.SubItems.Add(strEng); lvi.SubItems.Add(string.Empty); lvi.Tag = kpstItem; lvi.ImageIndex = 0; m_lvStrings.Items.Add(lvi); } Type tKL = typeof(KLRes); lvg = new ListViewGroup("KeePass Library Strings"); m_lvStrings.Groups.Add(lvg); foreach(string strLibKey in KLRes.GetKeyNames()) { PropertyInfo pi = tKL.GetProperty(strLibKey); MethodInfo mi = pi.GetGetMethod(); if(mi.ReturnType != typeof(string)) { MessageBox.Show(this, "Return type is not string:\r\n" + strLibKey, TrlUtilName + ": Fatal Error!", MessageBoxButtons.OK, MessageBoxIcon.Error); return; } string strEng = (mi.Invoke(null, null) as string); if(strEng == null) { MessageBox.Show(this, "English string is null:\r\n" + strLibKey, TrlUtilName + ": Fatal Error!", MessageBoxButtons.OK, MessageBoxIcon.Error); return; } KPStringTableItem kpstItem = new KPStringTableItem(); kpstItem.Name = strLibKey; kpstItem.ValueEnglish = strEng; kpstL.Strings.Add(kpstItem); ListViewItem lvi = new ListViewItem(); lvi.Group = lvg; lvi.Text = strLibKey; lvi.SubItems.Add(strEng); lvi.SubItems.Add(string.Empty); lvi.Tag = kpstItem; lvi.ImageIndex = 0; m_lvStrings.Items.Add(lvi); } lvg = new ListViewGroup("Main Menu Commands"); m_lvStrings.Groups.Add(lvg); KeePass.Forms.MainForm mf = new KeePass.Forms.MainForm(); TrlAddMenuCommands(kpstM, lvg, mf.MainMenu.Items); lvg = new ListViewGroup("Entry Context Menu Commands"); m_lvStrings.Groups.Add(lvg); TrlAddMenuCommands(kpstE, lvg, mf.EntryContextMenu.Items); lvg = new ListViewGroup("Group Context Menu Commands"); m_lvStrings.Groups.Add(lvg); TrlAddMenuCommands(kpstG, lvg, mf.GroupContextMenu.Items); lvg = new ListViewGroup("System Tray Context Menu Commands"); m_lvStrings.Groups.Add(lvg); TrlAddMenuCommands(kpstT, lvg, mf.TrayContextMenu.Items); KeePass.Forms.PwEntryForm ef = new KeePass.Forms.PwEntryForm(); lvg = new ListViewGroup("Entry Tools Context Menu Commands"); m_lvStrings.Groups.Add(lvg); TrlAddMenuCommands(kpstET, lvg, ef.ToolsContextMenu.Items); lvg = new ListViewGroup("Default Times Context Menu Commands"); m_lvStrings.Groups.Add(lvg); TrlAddMenuCommands(kpstDT, lvg, ef.DefaultTimesContextMenu.Items); lvg = new ListViewGroup("List Operations Context Menu Commands"); m_lvStrings.Groups.Add(lvg); TrlAddMenuCommands(kpstLO, lvg, ef.ListOperationsContextMenu.Items); lvg = new ListViewGroup("Password Generator Context Menu Commands"); m_lvStrings.Groups.Add(lvg); TrlAddMenuCommands(kpstPG, lvg, ef.PasswordGeneratorContextMenu.Items); KeePass.Forms.EcasTriggersForm tf = new KeePass.Forms.EcasTriggersForm(); lvg = new ListViewGroup("Ecas Trigger Tools Context Menu Commands"); m_lvStrings.Groups.Add(lvg); TrlAddMenuCommands(kpstTT, lvg, tf.ToolsContextMenu.Items); KeePass.Forms.DataEditorForm df = new KeePass.Forms.DataEditorForm(); lvg = new ListViewGroup("Data Editor Menu Commands"); m_lvStrings.Groups.Add(lvg); TrlAddMenuCommands(kpstDE, lvg, df.MainMenuEx.Items); lvg = new ListViewGroup("Standard String Movement Context Menu Commands"); m_lvStrings.Groups.Add(lvg); TrlAddMenuCommands(kpstSM, lvg, ef.StandardStringMovementContextMenu.Items); lvg = new ListViewGroup("Entry Attachments Context Menu Commands"); m_lvStrings.Groups.Add(lvg); TrlAddMenuCommands(kpstBA, lvg, ef.AttachmentsContextMenu.Items); Type tSD = typeof(KSRes); lvg = new ListViewGroup("KeePassLibSD Strings"); m_lvStrings.Groups.Add(lvg); foreach(string strLibSDKey in KSRes.GetKeyNames()) { PropertyInfo pi = tSD.GetProperty(strLibSDKey); MethodInfo mi = pi.GetGetMethod(); if(mi.ReturnType != typeof(string)) { MessageBox.Show(this, "Return type is not string:\r\n" + strLibSDKey, TrlUtilName + ": Fatal Error!", MessageBoxButtons.OK, MessageBoxIcon.Error); return; } string strEng = (mi.Invoke(null, null) as string); if(strEng == null) { MessageBox.Show(this, "English string is null:\r\n" + strLibSDKey, TrlUtilName + ": Fatal Error!", MessageBoxButtons.OK, MessageBoxIcon.Error); return; } KPStringTableItem kpstItem = new KPStringTableItem(); kpstItem.Name = strLibSDKey; kpstItem.ValueEnglish = strEng; kpstL.Strings.Add(kpstItem); ListViewItem lvi = new ListViewItem(); lvi.Group = lvg; lvi.Text = strLibSDKey; lvi.SubItems.Add(strEng); lvi.SubItems.Add(string.Empty); lvi.Tag = kpstItem; lvi.ImageIndex = 0; m_lvStrings.Items.Add(lvi); } } private void TrlAddMenuCommands(KPStringTable kpst, ListViewGroup grp, ToolStripItemCollection tsic) { foreach(ToolStripItem tsi in tsic) { if(tsi.Text.Length == 0) continue; if(tsi.Text.StartsWith(@"<") && tsi.Text.EndsWith(@">")) continue; KPStringTableItem kpstItem = new KPStringTableItem(); kpstItem.Name = tsi.Name; kpstItem.ValueEnglish = tsi.Text; kpst.Strings.Add(kpstItem); ListViewItem lvi = new ListViewItem(); lvi.Group = grp; lvi.Text = tsi.Name; lvi.SubItems.Add(tsi.Text); lvi.SubItems.Add(string.Empty); lvi.Tag = kpstItem; lvi.ImageIndex = 0; m_lvStrings.Items.Add(lvi); ToolStripMenuItem tsmi = (tsi as ToolStripMenuItem); if(tsmi != null) TrlAddMenuCommands(kpst, grp, tsmi.DropDownItems); } } private void UpdateStringTableUI() { foreach(ListViewItem lvi in m_lvStrings.Items) { KPStringTableItem kpstItem = (lvi.Tag as KPStringTableItem); Debug.Assert(kpstItem != null); if(kpstItem == null) continue; lvi.SubItems[2].Text = kpstItem.Value; } } private void UpdateControlTree() { FormTrlMgr.RenderToTreeControl(m_trl.Forms, m_tvControls); UpdateStatusImages(null); } private void UpdateUIState() { bool bTrlTab = ((m_tabMain.SelectedTab == m_tabStrings) || (m_tabMain.SelectedTab == m_tabDialogs)); m_menuEditNextUntrl.Enabled = bTrlTab; m_tbNextUntrl.Enabled = bTrlTab; m_tbFind.Enabled = bTrlTab; } private void OnLinkLangCodeClicked(object sender, LinkLabelLinkClickedEventArgs e) { try { Process.Start("https://en.wikipedia.org/wiki/List_of_ISO_639-1_codes"); } catch(Exception ex) { MessageBox.Show(this, ex.Message, TrlUtilName, MessageBoxButtons.OK, MessageBoxIcon.Warning); } } private void OnFileOpen(object sender, EventArgs e) { OpenFileDialogEx ofd = UIUtil.CreateOpenFileDialog("Open KeePass Translation", m_strFileFilter, 1, null, false, AppDefs.FileDialogContext.Attachments); if(ofd.ShowDialog() != DialogResult.OK) return; KPTranslation kpTrl = null; try { XmlSerializerEx xs = new XmlSerializerEx(typeof(KPTranslation)); kpTrl = KPTranslation.Load(ofd.FileName, xs); } catch(Exception ex) { MessageBox.Show(this, ex.Message, TrlUtilName, MessageBoxButtons.OK, MessageBoxIcon.Warning); return; } m_strFile = ofd.FileName; StringBuilder sbUnusedText = new StringBuilder(); if(kpTrl.UnusedText.Length > 0) { if(kpTrl.UnusedText.EndsWith("\r") || kpTrl.UnusedText.EndsWith("\n")) sbUnusedText.Append(kpTrl.UnusedText); else sbUnusedText.AppendLine(kpTrl.UnusedText); } m_trl.Properties = kpTrl.Properties; foreach(KPStringTable kpstNew in kpTrl.StringTables) { foreach(KPStringTable kpstInto in m_trl.StringTables) { if(kpstInto.Name == kpstNew.Name) MergeInStringTable(kpstInto, kpstNew, sbUnusedText); } } FormTrlMgr.MergeForms(m_trl.Forms, kpTrl.Forms, sbUnusedText); m_tbNameEng.Text = m_trl.Properties.NameEnglish; m_tbNameLcl.Text = m_trl.Properties.NameNative; m_tbLangID.Text = m_trl.Properties.Iso6391Code; m_tbAuthorName.Text = m_trl.Properties.AuthorName; m_tbAuthorContact.Text = m_trl.Properties.AuthorContact; m_cbRtl.Checked = m_trl.Properties.RightToLeft; m_rtbUnusedText.Text = sbUnusedText.ToString(); this.UpdateStringTableUI(); this.UpdateStatusImages(null); this.UpdatePreviewForm(); } private void MergeInStringTable(KPStringTable tbInto, KPStringTable tbSource, StringBuilder sbUnusedText) { foreach(KPStringTableItem kpSrc in tbSource.Strings) { bool bHasAssigned = false; foreach(KPStringTableItem kpDst in tbInto.Strings) { if(kpSrc.Name == kpDst.Name) { if(kpSrc.Value.Length > 0) { kpDst.Value = kpSrc.Value; bHasAssigned = true; } } } if(!bHasAssigned) { string strTrimmed = kpSrc.Value.Trim(); if(strTrimmed.Length > 0) sbUnusedText.AppendLine(strTrimmed); } } } private void UpdateInternalTranslation() { m_trl.Properties.NameEnglish = StrUtil.SafeXmlString(m_tbNameEng.Text); m_trl.Properties.NameNative = StrUtil.SafeXmlString(m_tbNameLcl.Text); m_trl.Properties.Iso6391Code = StrUtil.SafeXmlString(m_tbLangID.Text); m_trl.Properties.AuthorName = StrUtil.SafeXmlString(m_tbAuthorName.Text); m_trl.Properties.AuthorContact = StrUtil.SafeXmlString(m_tbAuthorContact.Text); m_trl.Properties.RightToLeft = m_cbRtl.Checked; } private void UpdateStatusImages(TreeNodeCollection vtn) { if(vtn == null) vtn = m_tvControls.Nodes; foreach(TreeNode tn in vtn) { KPFormCustomization kpfc = (tn.Tag as KPFormCustomization); KPControlCustomization kpcc = (tn.Tag as KPControlCustomization); if(kpfc != null) { tn.ImageIndex = m_inxWindow; tn.SelectedImageIndex = m_inxWindow; } else if(kpcc != null) { int iCurrentImage = tn.ImageIndex, iNewImage; if(Array.IndexOf(m_vEmpty, kpcc.TextEnglish) >= 0) iNewImage = ((kpcc.Text.Length == 0) ? m_inxOk : m_inxWarning); else if((kpcc.TextEnglish.Length > 0) && (kpcc.Text.Length > 0)) iNewImage = m_inxOk; else if((kpcc.TextEnglish.Length > 0) && (kpcc.Text.Length == 0)) iNewImage = m_inxMissing; else if((kpcc.TextEnglish.Length == 0) && (kpcc.Text.Length == 0)) iNewImage = m_inxOk; else if((kpcc.TextEnglish.Length == 0) && (kpcc.Text.Length > 0)) iNewImage = m_inxWarning; else iNewImage = m_inxWarning; if(iNewImage != iCurrentImage) { tn.ImageIndex = iNewImage; tn.SelectedImageIndex = iNewImage; } } else { Debug.Assert(false); } if(tn.Nodes != null) UpdateStatusImages(tn.Nodes); } } private void OnFileSave(object sender, EventArgs e) { UpdateInternalTranslation(); if(m_strFile.Length == 0) { OnFileSaveAs(sender, e); return; } PrepareSave(); try { XmlSerializerEx xs = new XmlSerializerEx(typeof(KPTranslation)); KPTranslation.Save(m_trl, m_strFile, xs); m_bModified = false; } catch(Exception ex) { MessageBox.Show(this, ex.Message, TrlUtilName, MessageBoxButtons.OK, MessageBoxIcon.Warning); } } private void PrepareSave() { m_trl.Properties.Application = PwDefs.ProductName; m_trl.Properties.ApplicationVersion = PwDefs.VersionString; m_trl.Properties.Generator = TrlUtilName; PwUuid pwUuid = new PwUuid(true); m_trl.Properties.FileUuid = pwUuid.ToHexString(); m_trl.Properties.LastModified = DateTime.UtcNow.ToString("u"); m_trl.UnusedText = m_rtbUnusedText.Text; if(!string.IsNullOrEmpty(m_trl.UnusedText)) ShowValidationWarning(@"It is recommended to clear the 'Unused Text' tab."); try { ValidateTranslation(); } catch(Exception) { Debug.Assert(false); } try { string strAccel = AccelKeysCheck.Validate(m_trl); if(strAccel != null) ShowValidationWarning("The following accelerator keys collide:" + MessageService.NewParagraph + strAccel); } catch(Exception) { Debug.Assert(false); } } private void ShowValidationWarning(string strText) { if(string.IsNullOrEmpty(strText)) { Debug.Assert(false); return; } const string strContinue = @"Click [OK] to continue saving."; string str = strText + MessageService.NewParagraph + strContinue; if(!VistaTaskDialog.ShowMessageBox(str, "Validation Warning", TrlUtilName, VtdIcon.Warning, this)) MessageBox.Show(this, "Validation Warning!" + MessageService.NewParagraph + str, TrlUtilName, MessageBoxButtons.OK, MessageBoxIcon.Warning); } private void ValidateTranslation() { string[] vCaseSensWords = new string[] { PwDefs.ShortProductName }; bool bRtl = m_trl.Properties.RightToLeft; foreach(KPStringTable kpst in m_trl.StringTables) { foreach(KPStringTableItem kpi in kpst.Strings) { string strEn = kpi.ValueEnglish; string strTrl = kpi.Value; if(string.IsNullOrEmpty(strEn) || string.IsNullOrEmpty(strTrl)) continue; // Check case-sensitive words foreach(string strWord in vCaseSensWords) { bool bWordEn = (strEn.IndexOf(strWord) >= 0); if(!bWordEn) { Debug.Assert(strEn.IndexOf(strWord, StrUtil.CaseIgnoreCmp) < 0); } if(bWordEn && (strTrl.IndexOf(strWord) < 0) && (strTrl.IndexOf(strWord, StrUtil.CaseIgnoreCmp) >= 0)) ShowValidationWarning("The English string" + MessageService.NewParagraph + strEn + MessageService.NewParagraph + @"contains the case-sensitive word '" + strWord + @"', but the translated string does not:" + MessageService.NewParagraph + strTrl); } // Check 3 dots bool bEllEn = (strEn.EndsWith("...") || strEn.EndsWith(@"…")); bool bEllTrl = (strTrl.EndsWith("...") || strTrl.EndsWith(@"…")); if(bEllEn && !bEllTrl && !bRtl) // Check doesn't support RTL ShowValidationWarning("The English string" + MessageService.NewParagraph + strEn + MessageService.NewParagraph + "ends with 3 dots, but the translated string does not:" + MessageService.NewParagraph + strTrl); } } } private void OnFileExit(object sender, EventArgs e) { if(m_bModified) OnFileSaveAs(sender, e); this.Close(); } private void OnStringsSelectedIndexChanged(object sender, EventArgs e) { ListView.SelectedListViewItemCollection lvsic = m_lvStrings.SelectedItems; if(lvsic.Count != 1) { m_tbStrEng.Text = string.Empty; m_tbStrTrl.Text = string.Empty; return; } KPStringTableItem kpstItem = (lvsic[0].Tag as KPStringTableItem); Debug.Assert(kpstItem != null); if(kpstItem == null) return; UIUtil.SetMultilineText(m_tbStrEng, lvsic[0].SubItems[1].Text); m_tbStrTrl.Text = lvsic[0].SubItems[2].Text; } private void OnStrKeyDown(object sender, KeyEventArgs e) { if((e.KeyCode == Keys.Return) || (e.KeyCode == Keys.Enter)) { UIUtil.SetHandled(e, true); ListView.SelectedListViewItemCollection lvsic = m_lvStrings.SelectedItems; if(lvsic.Count != 1) return; KPStringTableItem kpstItem = (lvsic[0].Tag as KPStringTableItem); if(kpstItem == null) { Debug.Assert(false); return; } kpstItem.Value = StrUtil.SafeXmlString(m_tbStrTrl.Text); this.UpdateStringTableUI(); int iIndex = lvsic[0].Index; if(iIndex < m_lvStrings.Items.Count - 1) { lvsic[0].Selected = false; UIUtil.SetFocusedItem(m_lvStrings, m_lvStrings.Items[ iIndex + 1], true); } m_bModified = true; } } private void OnStrKeyUp(object sender, KeyEventArgs e) { if((e.KeyCode == Keys.Return) || (e.KeyCode == Keys.Enter)) UIUtil.SetHandled(e, true); } private void OnFileSaveAs(object sender, EventArgs e) { SaveFileDialogEx sfd = UIUtil.CreateSaveFileDialog("Save KeePass Translation", m_tbNameEng.Text + ".lngx", m_strFileFilter, 1, "lngx", AppDefs.FileDialogContext.Attachments); if(sfd.ShowDialog() != DialogResult.OK) return; m_strFile = sfd.FileName; OnFileSave(sender, e); } private void OnStrDoubleClick(object sender, EventArgs e) { UIUtil.SetFocus(m_tbStrTrl, this); } private void OnCustomControlsAfterSelect(object sender, TreeViewEventArgs e) { ShowCustomControlProps(e.Node.Tag as KPControlCustomization); UpdatePreviewForm(); } private void ShowCustomControlProps(KPControlCustomization kpcc) { if(kpcc == null) return; // No assert m_kpccLast = kpcc; UIUtil.SetMultilineText(m_tbCtrlEngText, m_kpccLast.TextEnglish); m_tbCtrlTrlText.Text = m_kpccLast.Text; m_tbLayoutX.Text = KpccLayout.ToControlRelativeString(m_kpccLast.Layout.X); m_tbLayoutY.Text = KpccLayout.ToControlRelativeString(m_kpccLast.Layout.Y); m_tbLayoutW.Text = KpccLayout.ToControlRelativeString(m_kpccLast.Layout.Width); m_tbLayoutH.Text = KpccLayout.ToControlRelativeString(m_kpccLast.Layout.Height); } private void OnCtrlTrlTextChanged(object sender, EventArgs e) { string strText = m_tbCtrlTrlText.Text; if((m_kpccLast != null) && (m_kpccLast.Text != strText)) { m_kpccLast.Text = StrUtil.SafeXmlString(m_tbCtrlTrlText.Text); m_bModified = true; } UpdateStatusImages(null); UpdatePreviewForm(); } private void OnLayoutXTextChanged(object sender, EventArgs e) { if(m_kpccLast != null) { m_kpccLast.Layout.SetControlRelativeValue( KpccLayout.LayoutParameterEx.X, m_tbLayoutX.Text); m_bModified = true; UpdatePreviewForm(); } } private void OnLayoutYTextChanged(object sender, EventArgs e) { if(m_kpccLast != null) { m_kpccLast.Layout.SetControlRelativeValue( KpccLayout.LayoutParameterEx.Y, m_tbLayoutY.Text); m_bModified = true; UpdatePreviewForm(); } } private void OnLayoutWidthTextChanged(object sender, EventArgs e) { if(m_kpccLast != null) { m_kpccLast.Layout.SetControlRelativeValue( KpccLayout.LayoutParameterEx.Width, m_tbLayoutW.Text); m_bModified = true; UpdatePreviewForm(); } } private void OnLayoutHeightTextChanged(object sender, EventArgs e) { if(m_kpccLast != null) { m_kpccLast.Layout.SetControlRelativeValue( KpccLayout.LayoutParameterEx.Height, m_tbLayoutH.Text); m_bModified = true; UpdatePreviewForm(); } } private void OnCtrlTrlTextKeyDown(object sender, KeyEventArgs e) { if((e.KeyCode == Keys.Return) || (e.KeyCode == Keys.Enter)) { UIUtil.SetHandled(e, true); TreeNode tn = m_tvControls.SelectedNode; if(tn == null) return; try { TreeNode tnNew = tn.NextNode; if(tnNew != null) m_tvControls.SelectedNode = tnNew; } catch(Exception) { Debug.Assert(false); } } } private void OnCtrlTrlTextKeyUp(object sender, KeyEventArgs e) { if((e.KeyCode == Keys.Return) || (e.KeyCode == Keys.Enter)) UIUtil.SetHandled(e, true); } private void UpdatePreviewForm() { TreeNode tn = m_tvControls.SelectedNode; if(tn == null) return; if(tn.Parent != null) tn = tn.Parent; string strFormName = tn.Text; foreach(KPFormCustomization kpfc in m_trl.Forms) { if(kpfc.FullName.EndsWith(strFormName)) { UpdatePreviewForm(kpfc); break; } } } private void UpdatePreviewForm(KPFormCustomization kpfc) { // bool bResizeEng = (string.IsNullOrEmpty(kpfc.Window.Layout.Width) && // string.IsNullOrEmpty(kpfc.Window.Layout.Height)); m_prev.CopyForm(kpfc.FormEnglish); kpfc.ApplyTo(m_prev); } private void OnBtnClearUnusedText(object sender, EventArgs e) { m_rtbUnusedText.Text = string.Empty; } private void OnImport1xLng(object sender, EventArgs e) { PerformImport("lng", "KeePass 1.x LNG File", Import1xLng); } private static void Import1xLng(KPTranslation trlInto, IOConnectionInfo ioc) { TrlImport.Import1xLng(trlInto, ioc.Path); } private void PerformImport(string strFileExt, string strFileDesc, ImportFn f) { OpenFileDialogEx ofd = UIUtil.CreateOpenFileDialog("Import " + strFileDesc, strFileDesc + " (*." + strFileExt + ")|*." + strFileExt + "|All Files (*.*)|*.*", 1, strFileExt, false, AppDefs.FileDialogContext.Import); if(ofd.ShowDialog() != DialogResult.OK) return; try { f(m_trl, IOConnectionInfo.FromPath(ofd.FileName)); } catch(Exception ex) { MessageBox.Show(this, ex.Message, TrlUtilName, MessageBoxButtons.OK, MessageBoxIcon.Warning); } UpdateStringTableUI(); UpdateControlTree(); m_tvControls.SelectedNode = m_tvControls.Nodes[0]; UpdatePreviewForm(); } private void PerformQuickFind() { string str = m_tbFind.Text; if(string.IsNullOrEmpty(str)) return; bool bResult = true; if(m_tabMain.SelectedTab == m_tabStrings) bResult = PerformQuickFindStrings(str); else if(m_tabMain.SelectedTab == m_tabDialogs) bResult = PerformQuickFindDialogs(str); if(!bResult) m_tbFind.BackColor = AppDefs.ColorEditError; } private bool PerformQuickFindStrings(string strFind) { int nItems = m_lvStrings.Items.Count; if(nItems == 0) return false; ListViewItem lviStart = m_lvStrings.FocusedItem; int iOffset = ((lviStart != null) ? (lviStart.Index + 1) : 0); for(int i = 0; i < nItems; ++i) { int j = ((iOffset + i) % nItems); ListViewItem lvi = m_lvStrings.Items[j]; foreach(ListViewItem.ListViewSubItem lvsi in lvi.SubItems) { if(lvsi.Text.IndexOf(strFind, StrUtil.CaseIgnoreCmp) >= 0) { UIUtil.SetFocusedItem(m_lvStrings, lvi, false); m_lvStrings.SelectedItems.Clear(); lvi.Selected = true; m_lvStrings.EnsureVisible(j); return true; } } } return false; } private bool PerformQuickFindDialogs(string strFind) { List vNodes = new List(); List vValues = new List(); GetControlTreeItems(m_tvControls.Nodes, vNodes, vValues); int iOffset = vNodes.IndexOf(m_tvControls.SelectedNode) + 1; for(int i = 0; i < vNodes.Count; ++i) { int j = ((iOffset + i) % vNodes.Count); if(vValues[j].IndexOf(strFind, StrUtil.CaseIgnoreCmp) >= 0) { m_tvControls.SelectedNode = vNodes[j]; return true; } } return false; } private void GetControlTreeItems(TreeNodeCollection tnBase, List vNodes, List vValues) { foreach(TreeNode tn in tnBase) { KPFormCustomization kpfc = (tn.Tag as KPFormCustomization); KPControlCustomization kpcc = (tn.Tag as KPControlCustomization); vNodes.Add(tn); if(kpfc != null) vValues.Add(kpfc.Window.Name + "©" + kpfc.Window.TextEnglish + "©" + kpfc.Window.Text); else if(kpcc != null) vValues.Add(kpcc.Name + "©" + kpcc.TextEnglish + "©" + kpcc.Text); else vValues.Add(tn.Text); GetControlTreeItems(tn.Nodes, vNodes, vValues); } } private void OnFindKeyDown(object sender, KeyEventArgs e) { if((e.KeyCode == Keys.Return) || (e.KeyCode == Keys.Enter)) { UIUtil.SetHandled(e, true); PerformQuickFind(); return; } } private void OnFindKeyUp(object sender, KeyEventArgs e) { if((e.KeyCode == Keys.Return) || (e.KeyCode == Keys.Enter)) { UIUtil.SetHandled(e, true); return; } } private void OnFindTextChanged(object sender, EventArgs e) { m_tbFind.ResetBackColor(); } private void OnTabMainSelectedIndexChanged(object sender, EventArgs e) { UpdateUIState(); } private void OnImport2xNoChecks(object sender, EventArgs e) { FormTrlMgr.IgnoreBaseHash = true; OnFileOpen(sender, EventArgs.Empty); FormTrlMgr.IgnoreBaseHash = false; } private void OnImportPo(object sender, EventArgs e) { PerformImport("po", "PO File", ImportPo); } private static void ImportPo(KPTranslation trlInto, IOConnectionInfo ioc) { TrlImport.ImportPo(trlInto, ioc.Path); } private void OnEditNextUntrl(object sender, EventArgs e) { if(m_tabMain.SelectedTab == m_tabStrings) { int nItems = m_lvStrings.Items.Count; if(nItems == 0) { Debug.Assert(false); return; } ListViewItem lviStart = m_lvStrings.FocusedItem; int iOffset = ((lviStart != null) ? (lviStart.Index + 1) : 0); for(int i = 0; i < nItems; ++i) { int j = ((iOffset + i) % nItems); ListViewItem lvi = m_lvStrings.Items[j]; KPStringTableItem kpstItem = (lvi.Tag as KPStringTableItem); if(kpstItem == null) { Debug.Assert(false); continue; } if(string.IsNullOrEmpty(kpstItem.Value) && !string.IsNullOrEmpty(kpstItem.ValueEnglish)) { m_lvStrings.EnsureVisible(j); lvi.Selected = true; lvi.Focused = true; UIUtil.SetFocus(m_tbStrTrl, this); return; } } } else if(m_tabMain.SelectedTab == m_tabDialogs) { List vNodes = new List(); List vValues = new List(); GetControlTreeItems(m_tvControls.Nodes, vNodes, vValues); int iOffset = vNodes.IndexOf(m_tvControls.SelectedNode) + 1; for(int i = 0; i < vNodes.Count; ++i) { int j = ((iOffset + i) % vNodes.Count); TreeNode tn = vNodes[j]; string strEng = null, strText = null; KPControlCustomization kpcc = (tn.Tag as KPControlCustomization); if(kpcc != null) { strEng = kpcc.TextEnglish; strText = kpcc.Text; } if(string.IsNullOrEmpty(strEng) || (Array.IndexOf( m_vEmpty, strEng) >= 0)) strText = "Dummy"; if(string.IsNullOrEmpty(strText)) { m_tvControls.SelectedNode = tn; UIUtil.SetFocus(m_tbCtrlTrlText, this); return; } } } else { Debug.Assert(false); return; } // Unsupported tab // MessageService.ShowInfo("No untranslated strings found on the current tab page."); MessageBox.Show(this, "No untranslated strings found on the current tab page.", TrlUtilName, MessageBoxButtons.OK, MessageBoxIcon.Information); } } } Translation/TrlUtil/TrlUtil.csproj0000664000000000000000000001160512172704176016306 0ustar rootroot Debug AnyCPU 9.0.30729 2.0 {B7E890E7-BF50-4450-9A52-C105BD98651C} WinExe Properties TrlUtil TrlUtil Resources\KeePass.ico 2.0 true full false ..\ TRACE;DEBUG;KeeTranslationUtility prompt 4 pdbonly true ..\ TRACE;KeeTranslationUtility prompt 4 Form MainForm.cs Form Designer MainForm.cs ResXFileCodeGenerator Resources.Designer.cs Designer True Resources.resx True SettingsSingleFileGenerator Settings.Designer.cs True Settings.settings True {10938016-DEE2-4A25-9A5A-8FD3444379CA} KeePass Translation/TrlUtil/Properties/0000775000000000000000000000000013222747432015615 5ustar rootrootTranslation/TrlUtil/Properties/Resources.Designer.cs0000664000000000000000000001435012172704174021657 0ustar rootroot//------------------------------------------------------------------------------ // // This code was generated by a tool. // Runtime Version:2.0.50727.5466 // // Changes to this file may cause incorrect behavior and will be lost if // the code is regenerated. // //------------------------------------------------------------------------------ namespace TrlUtil.Properties { using System; /// /// A strongly-typed resource class, for looking up localized strings, etc. /// // This class was auto-generated by the StronglyTypedResourceBuilder // class via a tool like ResGen or Visual Studio. // To add or remove a member, edit your .ResX file then rerun ResGen // with the /str option, or rebuild your VS project. [global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "2.0.0.0")] [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()] internal class Resources { private static global::System.Resources.ResourceManager resourceMan; private static global::System.Globalization.CultureInfo resourceCulture; [global::System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")] internal Resources() { } /// /// Returns the cached ResourceManager instance used by this class. /// [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)] internal static global::System.Resources.ResourceManager ResourceManager { get { if (object.ReferenceEquals(resourceMan, null)) { global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("TrlUtil.Properties.Resources", typeof(Resources).Assembly); resourceMan = temp; } return resourceMan; } } /// /// Overrides the current thread's CurrentUICulture property for all /// resource lookups using this strongly typed resource class. /// [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)] internal static global::System.Globalization.CultureInfo Culture { get { return resourceCulture; } set { resourceCulture = value; } } internal static System.Drawing.Bitmap B16x16_Binary { get { object obj = ResourceManager.GetObject("B16x16_Binary", resourceCulture); return ((System.Drawing.Bitmap)(obj)); } } internal static System.Drawing.Bitmap B16x16_Down { get { object obj = ResourceManager.GetObject("B16x16_Down", resourceCulture); return ((System.Drawing.Bitmap)(obj)); } } internal static System.Drawing.Bitmap B16x16_FileSave { get { object obj = ResourceManager.GetObject("B16x16_FileSave", resourceCulture); return ((System.Drawing.Bitmap)(obj)); } } internal static System.Drawing.Bitmap B16x16_FileSaveAs { get { object obj = ResourceManager.GetObject("B16x16_FileSaveAs", resourceCulture); return ((System.Drawing.Bitmap)(obj)); } } internal static System.Drawing.Bitmap B16x16_Folder_Yellow_Open { get { object obj = ResourceManager.GetObject("B16x16_Folder_Yellow_Open", resourceCulture); return ((System.Drawing.Bitmap)(obj)); } } internal static System.Drawing.Bitmap B16x16_Keyboard_Layout { get { object obj = ResourceManager.GetObject("B16x16_Keyboard_Layout", resourceCulture); return ((System.Drawing.Bitmap)(obj)); } } internal static System.Drawing.Bitmap B16x16_KRec_Record { get { object obj = ResourceManager.GetObject("B16x16_KRec_Record", resourceCulture); return ((System.Drawing.Bitmap)(obj)); } } internal static System.Drawing.Bitmap B16x16_LedGreen { get { object obj = ResourceManager.GetObject("B16x16_LedGreen", resourceCulture); return ((System.Drawing.Bitmap)(obj)); } } internal static System.Drawing.Bitmap B16x16_LedLightBlue { get { object obj = ResourceManager.GetObject("B16x16_LedLightBlue", resourceCulture); return ((System.Drawing.Bitmap)(obj)); } } internal static System.Drawing.Bitmap B16x16_LedLightGreen { get { object obj = ResourceManager.GetObject("B16x16_LedLightGreen", resourceCulture); return ((System.Drawing.Bitmap)(obj)); } } internal static System.Drawing.Bitmap B16x16_LedOrange { get { object obj = ResourceManager.GetObject("B16x16_LedOrange", resourceCulture); return ((System.Drawing.Bitmap)(obj)); } } internal static System.Drawing.Bitmap B16x16_View_Remove { get { object obj = ResourceManager.GetObject("B16x16_View_Remove", resourceCulture); return ((System.Drawing.Bitmap)(obj)); } } internal static System.Drawing.Icon KeePass { get { object obj = ResourceManager.GetObject("KeePass", resourceCulture); return ((System.Drawing.Icon)(obj)); } } } } Translation/TrlUtil/Properties/AssemblyInfo.cs0000664000000000000000000000316613225116764020546 0ustar rootroot/* KeePass Password Safe - The Open-Source Password Manager Copyright (C) 2003-2018 Dominik Reichl This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.InteropServices; // General assembly properties [assembly: AssemblyTitle("KeePass Translation Utility")] [assembly: AssemblyDescription("KeePass Translation Utility")] [assembly: AssemblyConfiguration("")] [assembly: AssemblyCompany("Dominik Reichl")] [assembly: AssemblyProduct("KeePass Translation Utility")] [assembly: AssemblyCopyright("Copyright © 2008-2018 Dominik Reichl")] [assembly: AssemblyTrademark("")] [assembly: AssemblyCulture("")] // COM settings [assembly: ComVisible(false)] // Assembly GUID [assembly: Guid("39aa6f93-a1c9-497f-bad2-cc42a61d5710")] // Assembly version information [assembly: AssemblyVersion("2.38.0.*")] [assembly: AssemblyFileVersion("2.38.0.0")] Translation/TrlUtil/Properties/Settings.Designer.cs0000664000000000000000000000210010765174556021506 0ustar rootroot//------------------------------------------------------------------------------ // // This code was generated by a tool. // Runtime Version:2.0.50727.1433 // // Changes to this file may cause incorrect behavior and will be lost if // the code is regenerated. // //------------------------------------------------------------------------------ namespace TrlUtil.Properties { [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()] [global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.VisualStudio.Editors.SettingsDesigner.SettingsSingleFileGenerator", "9.0.0.0")] internal sealed partial class Settings : global::System.Configuration.ApplicationSettingsBase { private static Settings defaultInstance = ((Settings)(global::System.Configuration.ApplicationSettingsBase.Synchronized(new Settings()))); public static Settings Default { get { return defaultInstance; } } } } Translation/TrlUtil/Properties/Settings.settings0000664000000000000000000000037110755775352021212 0ustar rootroot Translation/TrlUtil/Properties/Resources.resx0000664000000000000000000002224112172704174020472 0ustar rootroot text/microsoft-resx 2.0 System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 ..\Resources\B16x16_Binary.png;System.Drawing.Bitmap, System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a ..\Resources\B16x16_FileSave.png;System.Drawing.Bitmap, System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a ..\Resources\B16x16_FileSaveAs.png;System.Drawing.Bitmap, System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a ..\Resources\B16x16_Folder_Yellow_Open.png;System.Drawing.Bitmap, System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a ..\Resources\B16x16_Keyboard_Layout.png;System.Drawing.Bitmap, System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a ..\Resources\B16x16_KRec_Record.png;System.Drawing.Bitmap, System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a ..\Resources\B16x16_LedGreen.png;System.Drawing.Bitmap, System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a ..\Resources\B16x16_LedLightBlue.png;System.Drawing.Bitmap, System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a ..\Resources\B16x16_LedLightGreen.png;System.Drawing.Bitmap, System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a ..\Resources\B16x16_LedOrange.png;System.Drawing.Bitmap, System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a ..\Resources\KeePass.ico;System.Drawing.Icon, System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a ..\Resources\B16x16_View_Remove.png;System.Drawing.Bitmap, System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a ..\Resources\B16x16_Down.png;System.Drawing.Bitmap, System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a Translation/DefaultText.xml0000664000000000000000000024136313222212700015027 0ustar rootroot Abort Abort current trigger execution Action Activate database (select tab) Active Add Entry Create a new entry. Add Group Create a new entry group. Add Entry String Field Create a new string field for the current entry. Advanced After Opening a Database Align Center Align Left Align Right All All Entries All Files All Supported Files Use alternating item background colors Application Application exit Application initialized Application started and ready Arguments &Ascending Do you want to continue? Asterisks The following file has already been attached to the current entry: Discard any changes made to the temporary file and do not modify the current attachment. Replace the attachment by the (modified) temporary file. KeePass has extracted the attachment to a (EFS-encrypted) temporary file and opened it using an external application. After viewing/editing and closing the file in the external application, please choose how to continue In any case, KeePass will securely delete the temporary file afterwards. Failed to attach file: Attach Files To Entry Attachments Save Attached File As Save attached files to: Do you wish to rename the new file or overwrite the existing attached file? Click [Yes] to rename the new file. Click [No] to overwrite the existing attached file. Click [Cancel] to skip this file. Author Auto Automatically create new Automatically generated passwords for new entries Remember and automatically open last used database on startup Automatically save when closing/locking the database Show expired entries (if any) Show entries that will expire soon (if any) Auto-Type Auto-Type has been aborted, because the target window is disallowed by the application policy (defined by your administrator). Always show global auto-type entry selection dialog Cancel auto-type when the target window title changes Cancel auto-type when the target window changes Auto-Type Entry Selection The following entries have been found for the currently active target window. Please select the entry that you want to auto-type into the target window. Multiple entries exist for the current window. If you want KeePass to search the active database for a matching entry and auto-type it, use the 'Global auto-type' hot key. An entry matches if one of its tags is contained in the target window title An entry matches if its title is contained in the target window title An entry matches if the host component of its URL is contained in the target window title An entry matches if its URL is contained in the target window title Auto-Type obfuscation may not work with all windows. Prepend special initialization sequence for Internet Explorer windows Send Alt keypress when only the Alt modifier is active To use the 'Auto-type selected entry' hot key, you first need to select an entry in KeePass. The specified auto-type sequence is invalid. The following auto-type placeholder or special key code is unknown/unsupported: The 'xdotool' utility/package is required for auto-type. For global auto-type, the 'xdotool' utility/package is required (version 2.20100818.3004 or higher!). Available Background Color You should regularly create a backup of the database file (onto an independent data storage device). You should create a backup of this file. Backups are stored here: Binary (no conversion) Bits bits Bold Both forms Browser built-in Built-in Button < &Back Default button &Finish &Next > Buttons Cancel Cannot move entries because they aren't stored in the same group. Change Master Key You are changing the composite master key for the currently opened database. ch. characters Check for update at KeePass startup Checking for updates Classic Clear master key command line parameters after using them once &Clear List Clipboard Clipboard will be cleared in [PARAM] seconds Clear clipboard when closing KeePass Data copied to clipboard. Use 'Clipboard Viewer Ignore' clipboard format Close active database &Close Close button [X] minimizes main window instead of terminating the application Closing database file Clusters of similar passwords. Each entry in the list below is the center of a cluster of entries that have similar, but not identical passwords. Click on an entry to see the cluster (list of entries with descending similarity). Column Columns Comments Company Comparison Component Condition Changes to the configuration/policy will affect you and all users of this KeePass installation. Changes to the configuration/policy will only affect you. Policy flags that are enforced by the administrator are reset after restarting KeePass. Failed to save the configuration. Configure Auto-Type Configure auto-type behaviour for this entry. Configure Auto-Type Item Associate a window title with a keystroke sequence. Configure Columns Configure entry list columns. Configure Keystroke Sequence Define a default keystroke sequence. Create New Database - Step 3 Contact Contains Copied entry data to clipboard Copy Copy All Copy Link Copy Copy Password to Clipboard Copy &Password Copy &TAN Copy URLs to clipboard instead of opening them &Copy URL(s) to Clipboard Copy User Name to Clipboard Copy Whole Entries Such a corruption is usually caused by a plugin or a KeePass port. Please try to find out which plugin/port is causing it and report the issue to the corresponding developer. Count Create Composite Master Key Create New Password Database Create new &IDs Creation Time Remember user name and password Do not remember user name and password Remember user name only &Specify different server credentials There must be exactly one .csproj or .vbproj file. CSV / Text File KeePass' global auto-type hot key Ctrl+Alt+A is in conflict with a system key combination that is producing '{PARAM}'. You can change the global auto-type hot key to a different key combination in 'Tools' -> 'Options' -> tab 'Integration'. Current Style Custom Custom Fields Customizable HTML File Add custom toolbar button Custom toolbar button clicked Remove custom toolbar button Cut Data Database Enter a short description of the database or leave it empty. Database file Your data will be stored in a KeePass database file, which is a regular file. After clicking [OK], you will be prompted to specify the location where KeePass should save this file. It is important that you remember where the database file is stored. Database has unsaved changes Database Maintenance Here you can maintain the currently opened database. The current database file has been modified Enter a name for the database or leave it empty. Database Settings Here you can configure various database settings. Data Editor If you lose the database file or any of the master key components (or forget the composition), all data stored in the database is lost. KeePass does not have any built-in file backup functionality. There is no backdoor and no universal key that can open your database. Data Viewer Show results of database maintenance in a dialog {PARAM} has not modified the database. Default Delete &Delete Delete Entries Delete Entry Are you sure you want to permanently delete the selected entries? Are you sure you want to permanently delete the selected entry? Delete Group Deleting a group will also delete all entries and subgroups in that group. Are you sure you want to permanently delete the selected group? &Descending Description Details Do not show this dialog again. Dialogs Disable Disabled Disable 'Save' command (instead of graying it out) if the database hasn't been modified &Discard changes Please see the documentation for more details. Drag&Drop Drop to background after copying data to the clipboard Duplicate Passwords Entries using the same password: List of entries that are using the same passwords. No duplicate passwords have been found. The string field name you specified already exists. String field names must be unique for each entry. &Edit Edit Entry You're editing an existing entry. Edit Group Edit properties of the currently selected group. Edit Entry String Field Edit one of the entry's string fields. eMail Emergency Sheet Ask whether to create an emergency sheet A KeePass emergency sheet contains all important information that is required to open your database. It should be printed, filled out and stored in a secure location, where only you and possibly a few other people that you trust have access to. KeePass will print an emergency sheet, which you can then fill out. Do you want to print an emergency sheet now? It is recommended that you create an emergency sheet for your database. Empty You have selected to use an empty master password. An empty master password is not the same as using no master password at all. Are you sure you want to use an empty master password? Are you sure you want to permanently delete the items? Enable Enabled Encoding Selected encoding is invalid. The file cannot be interpreted using the selected encoding. Ends with Enter Master Key Enter Current Master Key Generate additional random bits. Entropy Collection Entry Entry List Automatically resize entry list columns when resizing the main window When selecting an entry, automatically select its parent group, too Environment variable Equals Error Error Code Errors Esc minimizes to tray instead of locking the workspace Event Execute command line / URL Exit instead of locking the workspace after the specified time Always exit instead of locking the workspace Expired Entries Expired entries can match Expiry Time Expiry Time (Date Only) Export Export data to an external file. Export File/Data Export To HTML Export entries to a HTML file. Exporting... Export active database Export to: External External Application Fatal Error Feature Field Field Name The entered name exists already and cannot be used. The entered name is invalid and cannot be used. Please enter a field name. The selected field, which identifies the source entry, contains illegal characters (like '{', '}', newline characters, ...). Multiple entries match the specified identifying field. To avoid ambiguity, entries can be identified by their UUIDs, which are unique. Field Value File The file on disk/server has changed since it was loaded. Probably someone else has edited and saved the database. Save the current database to the file. Changes made by the other user will be lost. Load the file on disk/server and merge it with the current database in memory. File exists The following file exists already: Failed to create the file association. Make sure you have write access to the file associations list. Successfully associated KDBX files with KeePass! KDBX files will now be opened by KeePass when you double-click on them. KeePass Password Database File format The specified file is currently locked by the following user: KeePass will open the file, but note that you might overwrite changes each other when saving. This file path contains a semicolon (;) and therefore cannot be processed. Replace the semicolon and repeat the procedure. The specified file could not be found. File/URL Files Do you want to save the database now? Save database changes before closing the file? Save database changes before exiting KeePass? Save database changes before locking the workspace? Abort the current operation. The file will not be closed. KeePass will not be closed. The KeePass workspace will not be locked. Discard all changes made to the database and close the file. Discard all changes made to the database and exit KeePass. Discard all changes made to the database and lock the KeePass workspace. Save all changes made to the database and close the file. Save all changes made to the database and exit KeePass. Save all changes made to the database and lock the KeePass workspace. The file is too large. Extra-safe file transactions The new file's content does not match the data that KeePass has written, i.e. writing to the file has failed and it might be corrupted now. Please try saving again, and if that fails, save the database to a different location. Filter Find Focus quick search box when restoring from taskbar Focus quick search box when restoring from tray Focus entry list after a successful quick search Folder Font Default &Font Force using system font (Unix only) Format This file format doesn't support database descriptions. This file format doesn't support database names. This file format doesn't support root groups. All entries in the root group are moved to the first subgroup. To export to this file format, the root group must have at least one subgroup. This file format only supports one attachment per entry. Only the first attachment is saved, the others are ignored. General Generate Generated Passwords Count Enter number of passwords to generate. Please enter the number of passwords to generate: Generated Passwords Samples Generate a password Generic CSV Importer Remove selected profile Remove the currently selected profile. Save as Profile Save current settings as a profile. Please enter a name for the new password generator profile, or select an existing profile name to overwrite it: Accept this password? Derive from previous password The generated password contains a placeholder. When using this password (e.g. by copying it to the clipboard or auto-typing it), the placeholder will be replaced, i.e. effectively a different password might be used. Gradient Group The selected group cannot store any entries. {PARAM} groups skipped 1 group skipped This option is disabled, because local help is not installed. Help Source Selection Choose between local help and online help center. Hex Key - {PARAM}-Bit Hex Viewer Hidden Hide 'Close Database' toolbar button when at most one database is opened Hide field using asterisks History Homebanking Host It is highly recommended not to use global hot keys with only Alt or Alt-Shift as modifier. Recommended modifiers are Ctrl-Alt, Ctrl-Shift and Ctrl-Alt-Shift. Are you sure you want to use the specified hot keys? Icon ID Ignore This file uses a file format feature that is not supported. Image Viewer Import Import Behavior Select an import method. Import failed. Import an external file. Files to be imported: Import File/Data The import process has finished! Importing... It is indispensable that you read the documentation about this import method before continuing. Have you understood how the import process works and want to start it now? Import into active database incompatible with current environment incompatible with sorting Inherit setting from parent Installed Installed Languages Instructions and General Information Allow interleaved sending of keys Internal Editor Internal Viewer Internet Invalid Key The specified URL is invalid. The specified user name / password combination is invalid. IO Connection File Input/Output Connections Italic Iterations The KeePassLibC library is required to open and save KDB files created by KeePass 1.x. KDB files can be encrypted using a master password and/or a key file, not using a Windows User Account. KeePass KDBX Files The value of a key derivation function parameter lies outside the range of valid values. KeePass adjusts the value to the nearest valid value. Compute parameters that lead to a delay of 1 second on this computer. KeePassLibC (1.x File Support) KeePassLibC could not be found. Importing/exporting data from/to KDB files is only supported on Windows (because a library is used that contains the core code of KeePass 1.x, which is Windows-only). Please use a different file format for migrating your data. &Keep existing Alt Ctrl LCtrl Esc Key Modifiers Return Shift LShift Key file Create a new key file The specified key file could not be found or its format is unknown. Key Files Select key file manually Use an existing file as key file Key provider The selected key provider cannot be used, because it is incompatible with the secure desktop. If you want to use the selected key provider, you have to disable the secure desktop option in 'Tools' -> 'Options' -> tab 'Security'. The selected language has been activated. KeePass must be restarted in order to load the language. Last Access Time Last Modification Time Last Password Modification Time (Based on History) The latest KeePass version can be found on the KeePass website Limit to single instance One or more language files have been found in the KeePass application directory. Loading language files directly from the application directory is not supported. Language files should instead be stored in the 'Languages' folder of the application directory. Do you want to open the application directory (in order to move or delete language files)? Locked &Lock Workspace Un&lock Workspace Lock workspace when minimizing main window to taskbar Lock workspace when minimizing main window to tray Lock workspace when the remote control mode changes Lock workspace when locking the computer or switching the user Lock workspace when the computer is about to be suspended Main instruction Main Window Master Key The master key has been changed! In order to apply the new master key, the database must be saved. Master key changed The master key for this database has been used for quite a while and must be changed now. Click [OK] to open the master key changing dialog. Do you want to change the master key now? The master key for this database has been used for quite a while and it is recommended to change it now. The master key for this database file consists of the following components: Enter master key on secure desktop Master password The master password must be at least {PARAM} characters long! The estimated quality of the master password must be at least {PARAM} bits! The maximum supported attachment size is {PARAM}. Maximized Memory Menus Method Minimize main window after copying data to the clipboard Minimize main window after locking the workspace Minimize main window after opening a database Minimized Minimize to tray instead of taskbar More {PARAM} more entries Name Use native library for faster key transformations Navigation Network Never expires New New Database NewDatabase.kdbx A newer .NET Framework is required. New Group New line New state New version available No &No Make sure that it is not encrypted and not compressed. The operating system didn't grant KeePass read access to the specified file. (None) No Key Repeat None Normal &No Sort Not Not now (not recommended) Notes Not installed The selected file isn't a valid XSL stylesheet. The object with the specified name could not be found. {PARAM} object(s) deleted Off of OK Old Format On Operation aborted. &Open Open Database Open Database File Open database file Opened Opened database file Opening password database... &Open URL(s) Open with {PARAM} Optimize for screen reader (only enable if you're using a screen reader) Options Here you can configure the global KeePass program options. Other Placeholders Built-In Overrides Custom Overrides Overwrite Overwrite &existing Overwrite the existing file? Overwrite if &newer Overwrite if newer and apply &deletions Install this package and try again. Parallelism Detailed descriptions of all parameters can be found in the help manual. Parameters Password Password length Password Managers Password Generation Options Here you can define properties of generated passwords. Enter the password: Password Quality Estimated quality of the entry passwords. Password and repeated password aren't identical! Repeat the password to prevent typing errors. Paste Perform Auto-&Type Perform global auto-type Perform auto-type with selected entry Pick Characters Select the requested character positions. Pick Field Choose a field whose value will be inserted. Pick an icon. Plugin This plugin appears to be a plugin for KeePass 1.x. KeePass 1.x plugins cannot be used together with KeePass 2.x and vice versa. The plugin cache will be cleared and rebuilt if necessary when KeePass is restarted. The following plugin is incompatible with the current KeePass version: The plugin cannot be loaded. The current operating system is unsupported by the plugin. Provided by Plugins Plugins Compiling and loading plugins... Here you can configure all loaded KeePass plugins. Have a look at the plugin's website for an appropriate version. Allow auto-typing entries to other windows. Allow auto-typing using the 'Perform Auto-Type' command (Ctrl+V). Allow changing the master key of a database. Do not require entering current master key before changing it. Allow copying entry information to clipboard (main window only). Allow copying whole entries to clipboard. This operation is disallowed by the application policy. Ask your administrator to allow this operation. Allow sending information to other windows using drag&drop. Allow exporting entries. Do not require entering current master key before exporting. Allow importing entries from external files. Allow creating new database files. Allow loading plugins to extend KeePass functionality. Allow printing entry lists. Do not require entering current master key before printing. The following policy flag is required Allow saving databases to disk/URL. Allow editing triggers. Pre-release version Print Print password entries. Private Professional Quality Exclude expired entries in quick searches Search for passwords in quick searches Resolve field references in quick searches Quick Search (Toolbar) Random MAC Address Ready. recommended &Recommended Recycle Bin Collapse newly-created recycle bin tree node Are you sure you want to move the selected entries to the recycle bin? Are you sure you want to move the selected entry to the recycle bin? Are you sure you want to move the selected group to the recycle bin? Show confirmation dialog when moving entries/groups to the recycle bin Redo Remember password hiding setting in 'Edit Entry' window Remember key sources (key file paths, provider names, ...) Remember working directories Remote host is reachable (ping) &Repair Repair Mode In repair mode, the integrity of the data is not checked (in order to rescue as much data as possible). When no integrity checks are performed, corrupted/malicious data might be incorporated into the database. Are you sure you want to attempt to repair the selected file? Thus the repair functionality should only be used when there really is no other solution. If you use it, afterwards you should thoroughly check your whole database for corrupted/malicious data. Require password repetition only when hiding using asterisks is enabled Replace Do not replace Do you wish to restart KeePass now? Retry &Retry Root Directory Ensure same keyboard layouts during auto-type Sample Entry Save Do you want to save the changes you have made to this entry? Do you want to save the changes before closing? KeePass - Save Before Close/Lock? &Save Save Database Save active database Saved database file Do not ask whether to synchronize or overwrite; force synchronization Saving database... Saving database file after saving before saving Scheme Search... Search the password database for entries. {PARAM} entries found 1 entry found Search Results Searching Automatically search key files Automatically search key files also on removable media Type to search the database in Find Note: KeePass shows this simple file browser dialog, because standard Windows file dialogs cannot be shown on the secure desktop for security reasons. An application has switched from the secure desktop to a different desktop. Play UAC sound when switching to secure desktop Click [OK] to switch back to the secure desktop. Select All Select Color Please select a different group. Selected column selected Select a file. Select an icon Select Language Here you can change the user interface language. One or more of the KeePass self-tests failed. Sending Separator Sequence Show additional auto-type menu commands Show dereferenced data When showing dereferenced data, additionally show references Show dereferenced data asynchronously Show Entries Show entries by tag Show full path in title bar (instead of file name only) Show in Show message box Show tray icon only if main window has been sent to tray Similar Passwords Entries using similar passwords (similarity: {PARAM}): List of entries that are using similar passwords. The list shows entries that are using similar, but not identical passwords. For finding entries that are using the same passwords, use the 'Find Duplicate Passwords' command (in the main menu). Size Skip slow Expired Entries and Entries That Will Expire Soon Special Keys Accept invalid SSL certificates (self-signed, expired, ...) Select one of the standard expire times Standard Fields Start and Exit Start minimized and locked Starts with Status Strikeout String Success. Synchronization failed. Synchronize Synchronize active database with a file/URL Synchronizing... Make sure that the two databases use the same composite master key. This is required for synchronization. Synchronization completed successfully. System System Code Page Tag Add a new tag. New Tag Tags No tags found Mark TAN entries as expired when using them TAN Wizard With this TAN wizard you can easily add TAN entries. Target Window No templates found Test succeeded! Text Text Color Text Viewer Time span Title Toggle Show/hide password using asterisks New... Open... Save All Too many files have been selected. Select smaller groups and repeat the current procedure a few times. The key transformation took {PARAM} seconds. Tray Icon Use gray tray icon Single click instead of double click for default tray icon action Trigger The trigger action type is unknown. Add Trigger Create a new workflow automation. The trigger condition type is unknown. Edit Trigger Modify an existing workflow automation. The trigger event type is unknown. Trigger execution failed Triggering Trigger name Triggers Automate workflows using the trigger system. Edit Triggers Change trigger on/off state A newer KeePass version or a plugin might be required for this type. Underline Undo Unhide Passwords Allow displaying passwords as plain-text. Unhide button also unhides source characters Unknown An unknown error occurred. unsupported by Mono Update Check Enable automatic update check? Update check failed. Version information file cannot be downloaded. KeePass can automatically check for updates on each program start. No personal information is sent to the KeePass web server. KeePass just downloads a small version information file and compares the available version with the installed version. Automatic update checks are performed unintrusively in the background. A notification is only displayed when an update is available. Updates are not downloaded or installed automatically. The results of the update check. User interface state updated Up to date URL Open a database stored on a server. Open From URL URL Override URL Overrides Save current database on a server. Save To URL Use database lock files Use file transactions for writing databases User Name Enter the user name: User name UUID The database contains duplicate UUIDs. When closing this dialog, KeePass will fix the problem (by generating new UUIDs for duplicates) and continue. Validation failed Value Verb Verify written file after saving a database Version View &View View Entry You're viewing an entry. Wait Wait for exit Warning Warnings Web Browser Web Site Login Web Sites Windows Favorites Windows Window style Windows user account You should create a complete backup of your Windows user account. Without Context Workspace Locked The modified XML data is invalid. XML Replace Replace data in the XML representation of the database. Transform using XSL Stylesheet XSL Stylesheets Select XSL Transformation File XSL Stylesheets for KDBX XML Yes &Yes Zoom Failed to initialize encryption/decryption stream! The data is too large to be encrypted/decrypted securely using {PARAM}. An extended error report has been copied to the clipboard. Expect 100-Continue responses Fatal Error A fatal error has occurred! The file is corrupted. The file header is corrupted. Data is missing at the end of the file, i.e. the file is incomplete. Less data than expected could be read from the file. Failed to load the specified file! The file is locked, because the following user is currently writing to it: A newer KeePass version or a plugin is required to open this file. A newer KeePass version is required to open this file. The target file might be corrupted. Please try saving again. If that fails, save the database to a different location. Failed to save the current database to the specified location! The file signature is invalid. Either the file isn't a KeePass database file at all or it is corrupted. The file is encrypted using an unknown encryption algorithm! The file is compressed using an unknown compression algorithm! The file version is unsupported. Failed to create the final encryption/decryption key! The .NET framework/runtime under which KeePass is currently running does not support this operation. General The composite key is invalid! Make sure the composite key is correct and try again. Found invalid data while decoding. In order to import KeePass 1.x KDB files, create a new 2.x database file and click 'File' -> 'Import' in the main menu. In the import dialog, choose 'KeePass KDB (1.x)' as file format. {PARAM}-bit key Database files cannot be used as key files. The length of the master key seed is invalid! The selected file appears to be an old format Passive Pre-authenticate Timeout Please try it again in a few seconds. Unknown header ID! Unknown key derivation function! The operating system did not grant KeePass read/write access to the user profile folder, where the protected user key is stored. User agent Translation/DefaultUpdateCs.bat0000664000000000000000000000046611176572202015572 0ustar rootrootTrlUtil.exe src_from_xml DefaultText.xml MOVE /Y KPRes.Generated.cs ..\KeePass\Resources\KPRes.Generated.cs MOVE /Y KLRes.Generated.cs ..\KeePassLib\Resources\KLRes.Generated.cs TrlUtil.exe src_from_xml DefaultTextSD.xml MOVE /Y KSRes.Generated.cs ..\KeePassLib\Resources\KSRes.Generated.cs PAUSE CLSTranslation/DefaultTextSD.xml0000664000000000000000000000034011105612640015247 0ustar rootroot Test Ext/0000775000000000000000000000000013222436326010321 5ustar rootrootExt/Icons_15_VA/0000775000000000000000000000000013061473560012271 5ustar rootrootExt/Icons_15_VA/KeePass_Square_Blue/0000775000000000000000000000000013061030310016071 5ustar rootrootExt/Icons_15_VA/KeePass_Square_Blue/KeePass_Square_Blue_24.png0000664000000000000000000000210113061030254022727 0ustar rootrootPNG  IHDRw= pHYs}}HIDATHǥhU?^77ۯm+*V DPkY/E"HDȹ@" Q/$W%m9l[C9nױnnw9?xwgXpx~s<Y#?eû46QXT1.DD D='DRsJ4cxK\_ټ}B2(1(!NAZw bJ|  |!~DU_TJӶg=a/Pyk;RUW;J@EMnjQ6O]/[ .g{p+s+ x8abKGD pHYsjf3IDATxytU?$0@X@y8.30ʦ,0 m'㾜#! ; & [@_=fiY1NyZ/4;l`-'2*CG2dHrsӝc.L@5}-mvm]u:9:Qw} ϋmhpR稥qΔS|pŇvjj2O1{W^j2uLx11q:g^{G[Zq~0x'y6mP!4[@ESTe  _ }sN}yǏ1@P6xNxIIM˹<;DŽBB@JZc'IccnUjiXmJ^Xƌ;~ _l,˥QlE3s}d$o&O3c =`) "ZT@Nh_)&|ᣮo2CUJfۀ}L}cJP2 6/Voi7 XN ; Z;RuBn<&͘ˀ+F~w#N dH=PtxCw57xTR]UKN\bR*)]r_;n X-/85v{D\=I;j8|pKHe(R/8/:&[cDE*Pg G)=Iis F^O|R8}bHKtuzN@Jq'$o(ALLq*׮ ";3MzW~($'Pg:Uܾ _sf ah ਭY2f"mLt _ A( _ X ]9u=${݌ CGbbHZz(#G۸Xo[ڽ6_G] b5gjF,=x'|Y~0iFn Ew@ +A᫟,kt00|K)f_hJ/<ע;|! Pk/T.e _#|Gj֢+|%FiS:&..ظĶFlDDx6dCbIjIEaZݔR;@áB~2o_oOύ 2w:J@EK,V-!!zaxq䍙ʄ)OJ$|G^fR﬑ _B88<*ʄ kYB _gn'6 Ȃ/%'PV,!/4e|:$—tV,ZkHTfc^=UytoO`㞼̊0p@(%PNbrn^dyW |@A`QӡQo} /3wNV B1j=ۀ[ʵ/hϟ??&.WxWJ 3.W%_A:?hBg_ƫbeE+3% 3l"A?l1@ *DG=^A{*sGO!N"{{Y.<)#_A۔X,Yv51jmBr}`F(?ߥϟ,>gCV,@T-w)][WK%43_!] wu+?Z.s ߀]MT[W=kq}Lh5WσS?rF`vY@fvnk O[}ڏ@\,?ǀ!Z"Lar}ґ ЦYܾo{)[L~;܄BvRaW1C/ljXyT&NG׬>&| )ܲS6R\ tZ|V¶X LjӸb DěDj8SswJ"̳Z?"`s=w8].%5;Q"c=4YCn/7anKLh{\@twA<_{<#6!m;jrX_b*@=J<_Q`p!_ohfgvpNs*ԖĜ {4KZJ͖m8ׁP&.e8&{`!Z$CNKZ(_K`) HDf[{Te}ڒsJk1)IENDB`Ext/Icons_15_VA/KeePass_Square_Blue/KeePass_Square_Blue_256.png0000664000000000000000000002334112567604314023045 0ustar rootrootPNG  IHDR\rfbKGD pHYs55H@ IDATxy|߳C]EkExO}Ԫ֣jGU[E@ACp#@Bȝ&&ݙٙ}>׼\|GLx??Go~\Cy[ְ2;fPU0c fbkRSӸILrx2/(][ysߥ2F./0L_ɤˮnN]~7|T>T'B08#-7uB6m)D_7^SVZ'3_`S[S # p%˚T8݀lFo~9]HJj/~ɩ3hFO`O vm@eȢ[ggw执Yg~?uͲƋSRlZ~`e4 eӍ9wAC~?aGAn}>Wغ=[BS׈Ŋzq˳Ufk_O(I'*+F) zUY2hӤ3w8,D_w;b'UT[e%zÂymf1b8_|MAca,+@&P |5 :wӯ/7 u@= ە> 6ԅ%-y?4M[aO/ ͜٦=Β3/  ҁ-fi;c6';EߛsߟOuիh6]ڴ-1/ w!@-iL`3a! 3uq)羇եW ]z"w7fzmh0[apdu0eSF? !u0+40`+:Yw͋|C~+ኛ_MVY@k74~E:v$ Ooݶ#_a @7# kܩgr~_7NL? 8/ W=NRRYF`LC0֌;xtS~W ɸS2cl`_VYFڴ~dU^Ză7̨ 0kn~BRgf1:jhBD)),>쎝~ّ];6kwm{)W@mm  $%%Ӯ]6mmV; sw:w=.9G~ׁ<4esF~F2aMtm[ֳj^uk}Z % q΃=/^@ ڣ}ṟ'ӭG?4McRЪMoa~4[#wG_1/[w|Ʒ >e/(/y4~?Vg愓Ncg0iӮo1lZ:hq>Qߩ[|,W6}W.4<ct=ձGq/eبHMMw>a4!n̾=v 04p%~uE Me:mToT:vZ|V~5I71b=s? <DQ1 |>i#QÜ &_[[ç'6^-}Ğ/{p}~cJ|#ŴZ]}\٨*y?ooA>ih@vLNdSR~+J7(/myV^=Q TkwonĥR0~|稭 z=HQc~/^/> %%EKitJrCYK?J?0°E{ C Q¿p7{5^woONav|w{vQpd}hѳW?B[Ӟs0u/qsp wÃC>{QKNWRWXkoʃYJt?~.a¯tZ{ЫW??-.ʪߡtQκՋ!,_:GwޣFz;%7 k,/[}Ǟ'u XVvo/@:J;7eúۤcdg⾽qXB]gݏ[`Qیg`2[ MkV~}n|v]sXv䮖_?vL?y7I),)y4lX!nkl1 7W\5Fq,6[*nWj=ouzyTH=ևjkx ص}}|¯̇爥:p.nTV'䨾]:}{v=@%xYJ/F@Yi1w>e=Օzyڹ ?χחIx}>G Lh-1Tʉ>?ܵk#%9%^}ѣ1tEN?e ^YQNUe9esvm`ulް*>z ʁꛟKl  w9zA銁 g8v(3$!na6?R kYdkW}\  z?FcG1l􄄅H)6S@/ .]{qɜv$d^~Op͂f2qXPgнױt+2 TUq-kmiCO>_W]k:j߉s.'Oi"1+E ?^AmM++xo-I?Mvd?9+t?hlϽ&)A1av~e~I@}ꮃY*޿񎧹SI[x5?/)9+o|7?7CoxY)I%xtvXz$W M}2&,Mxy}څ^F_ȝI/v?Or/;wc3x8_yh1ZϛNAfWnWQƭ>1kt6WLL w?v`孿y9+]ƞu]rP pο_jI~odhE8|\~ͽ ~y}RL+_Ju 7'p!Z7UKWxQ{R1r/2􄅿^9N>׺^o|u1݀Jngy'~L㥿yiā@-~yM+>~]~e2 j߅_< Tr0mCKRm?Ẹtq^ghۖy,߶@._X<o#%9-פs7Yf|+է, Ǖ(/JII ~-n׌;$%Z*زaiz._?,o>_gVפf#$ހk ~c1#~/O崟O[1hظfaauߡitއ^} -ܻ{+QJgsbߨb"jsNBEE5^.y&Y6.[2K6殲,r0Tt b[#sy6ƗlIlÑG ú[ρY4&Kb׶ծ6EU|ۈnㆌ #(~uoptK*ǣ Jq ݀ ෴l4W z~%G[ia@X~' #{ ă.C3*@wVs3P<ï,_~K A m#] |D߸ Gaï79I@;d4!{Wvu2~N[{~_\o&G" 7kiX[6('s?ff?c~6⑀qBk~%;~CD߰p Bj ~BbVWڲ\}ۃ؎Æ"a>S+w_!R.WX.(f;7`0}?tɄKok2~kkj8P(pYmߵ3Tyjk/F7TF#\}#q ڣ/W,餖_qq{$KoCd~wۦV= ~od_~߅2Nh-9Slzb- >OvW'גR(447nTXkc~?7l!~s@go8?o8r(Θ @ XM 'ϟ/;bYp߹A>: m!H ֆ_K& u,F ; ߾@OX2'Qߥ7dC`V_BJozq2O~+Cno!pva>;b$Kbա | rFV9?+a,yBpbhjϚOI㮏l/-kT/fb9~c&]ϗBv^-ag)@kp<5[~nǍ7_Yh?LaV_4۶// $/ q ᯮ*gۦMOT'Jĵ# Cy^͞T22V?"MM*5 K%g8~e[yxjӡ΄_cTV;̒Sה`*K#\ jbo*~Qb  ??"rl(߿5` ? JmWꪊ#v[6ﯭ @)EM(cm2zGY, p_h#?Ez$k!kb ?~MK^4tVwTJ~GOkmf( ѻUV~Z~%~lZ@h.4K3߱Q_lZR_nռq? q? ~ ,UCXk]W}?e~_~q]سeYv54ouiE?l* q?440[@I!/Z-Â_W:?||3fwm`Ìoٻ'GQ ?+P[g7^H[&߽S~sYy,YߖmϤw~I a_=߽{1=ʦv`tW^E%lGcN1#9Pܛ _5ohR /o!5UYDr m:tEVg#%5 S+C*CC6F$5'or=-$<[7PkUԳfr=3ry=w䯭_SNmM95ETlh38L՗iuF@!Fۘ{ 9giDKwE{X lƛp/Hjˁu(+HDk;l72;o1KوD `4TD2?l_3$;+f_w_H!!GG>0 {٬vsW O''" R=m)5]@)c0J+`d`$6L,$`/4{U J "k&gC8io6E#c\| S @cu y?݊} S dܻ"%uN|e\;MIENDB`Ext/Icons_15_VA/KeePass_Square_Blue/KeePass_Square_Blue_32.png0000664000000000000000000000252412570045466022756 0ustar rootrootPNG  IHDR szzbKGD pHYs:IDATXõ{lE?۽E mT£`P`@ $-hx૕  T JH`bAKPՖrkKdg?ѻwId3gtD`)p5@ լ~0u\z5q)}{4j|KUq 0$!qxo.τTnV0?@J^/U{]47WBБ2]H),[Qyn~ή[ QB* yapt 꺞|ꧫeƄOMu%gOFKхL2 Do|p0q䅨@WR[34Z\΄ɳYڇ{S\qw<]]xtG: <46\ ࿁jLiv8+\H|@4o]̹<+x} ;7Qc=] ;aւ5p8 ٷ{>_"7S-."ޗŒoh&^u_Fӵ+Pt@l?x`7@;,g"fC(/#jok6SyYDۅeߓ6]a۫R1l4&b}j{))f<, p3~86BXP$pˁ wΏ!#Ƴh?拷#Yq>y<Jخ1C@<Ss(q eA81bq|i 3DN$$d{_=Wt`FaR\06Ͷ0yd ?ezJz9+Ɩw,EK)sRzaI~=@%Pj ?,#MOߜۏFRsӖqF9:p !Ȫۅa8ݓԫ`+3P8,(>)mPN;n6nӁ6 @)p<΢>/ Ӂe(IENDB`Ext/Icons_15_VA/KeePass_Square_Blue/KeePass_Square_Blue_64.png0000664000000000000000000000524012567604262022762 0ustar rootrootPNG  IHDR@@iqbKGD pHYsMM_ @IDATxݛ{pT?lHH AƄ$ Z>h[k*jR8Jб3B 2utc[a !@DB!Gv7wݽ7$Nv=~~~B5@.0Hd`@=P >[$xp2_ x(4 NJr;ac>/38a)+DzFÇv^WN{{[~SW`W< p#/#3.'?=.Q<7^A (#T@QT}]tRk#k*Wo`FxWk HЖo/.fٶW<ș'eP920Y[b|i9QZ>iP+dpױZOj‑@e ؼߦgѧ3heN57htZ[FP@ V lg $f,6;p쌊>t8Xϩ&)>ظ{˔Ld4|ŽA?C5i<~1"-rsqL8{\rȏځ$a;p"d :Exc ^s:!d"D^hWSk Z:2ݍ-6.JǨBbc\!C-+h M]fo<潸Ų3,C96o7Αh<VRPVaY'vq9ԪwB(k" hP ( hpJg7ӳu)Fh9GHںE@"ednXx] cgBzr2v{<6{۷5ӣtUTi M o$'h04}˧,nW$ozJX`&-Mu9o_zydnX);Gzer"wSz"b 4,`xPZ@8%QëB"d->Q@;@AEuU3+ILZfIX@Ë@bƕX$.YlCݞ^{c9z4 ,cK /VAˁ--nI^}S'7 ̾mr ;&pUnN1/frfFKnPLT ۣb3B29$тA2 u5ӡ̲FYaSYݽK: b|YYWۋFTy pxVGxBHC^-Aӻl̾ٳ}U)SsVM1؈'DhYOSnmK҃47ՇDcF~su,p8]&NA3G ;O囹~kSӹL5c:Ow#ڕ7лRd4. Ekn''6qhkF}8DvS3IHL A<|\rhk*z;CE?Ro:dVW<ƫByl1 G>?]8c~IENDB`Ext/Icons_15_VA/KeePass_Square_Blue/KeePass_Square_Blue_48.png0000664000000000000000000000405012567604242022760 0ustar rootrootPNG  IHDR00WbKGD pHYs?%IDATh͚l?N߉]'k2P@l]iZ`tVmc E [UUj*]Ґ(XJ@B;n~~m,=<{lb`_ ٢@m9 mt&OMzFR*-R)K}a ö$ F[E~_ i;0=ػ|Q$6lEO $ ]+=뀶\:ʽwy?~9sO fUWIUk|>jk;q\ϫO/~-iL`S:1zrzP lJUO--x>~t~Wl6ymws+oyt)w&/$$%Q|3}g*6dq̜Ou.4i裳LM+e WKl[3;y@@i ߼q_Xw&gp1<=T"-#2EIjOf~ ~X^~5Khk2z/ǙjH=ٲOMѤRvqܥz^߹M;HMwXS"; CÚͿºx3>˿SW9o +yf^KBw0%i;`X{9wUĖʝB@nDVϷ%^]݆hCKBʐ4uʃoQgG.mُg=ª/ҭd ||ǗWϹӺx%,e|a롎Bե&d!~!Qߞ`Sa-$=sT=4{L (&CHl׍׋Kq+[8sL ][1ᅐQf ۭ{+ ampMе o4CC kt][þB`tn^hk{8/ ŀBz !ÛBb / c+@`$l&1@78`/dOQ^VA „K62r91#]3Qq 5+Sh<\iTֶe7F#C2JG%a[M"b -W^FIHj^P~kʫr>܍ #NWH,@z3coqY}Y4mhC) HڏqLexpjRӝ9{R{clo\69dk><y!sIsS.= mL*$=eV$5>Ьz~Ɋ x={rj0R3y:U[VoHI17]]Ʌk`+ 8s?rw?}R݉x|Cp)̅Y~\oQe cS7^U"72$^Kx=}TϢڵ혠fWlg,)mSs|SoFR‰4 V >apʓҰj8w)l5!t !ig>JtCN4)n>E|K~硿9~[x!aRg8 O 7hI%8W7LO|.v['"vz${ZK,N*<-X!+cFځ=ɀ!Y<4ZmKW@wU|l13 ĕ uV88Ի eM̘8)iٷ~OxN~|J &8sS3 FF f#A}I`ˀj#VԎ?{Zq)x {=A7EFvIENDB`Ext/Icons_15_VA/KeePass_Square_Blue/KeePass_Square_Blue_16.png0000664000000000000000000000127312570042346022752 0ustar rootrootPNG  IHDRabKGD pHYsSSbj[IDAT8ˍ[HTQ3W/3(ИcY^ '*#%]Ȅ"ʇ)z(K+z  1MisΙ93s ?lZk{K8l4 p8"gJJW @Q'KVw%"x*3@~IWCxV_DU^%3]4'q!fsmcO9 ` ߺ~&vcͦ}(v9]:N`|N eX QLT^<}j".Aܞ"iʳ+Ap͚g +*dd㙿T'OYLzg!zC$鿵h.p%s }TEQ ؒ~NTLb3s !Z-2/4 mNR!bC "{IWGd Vlc&٥Ub(M xk& C_chg?Ћ Ldv݉d#lz ) E }E %4l{LWa_%Gw0:bPcOpM;A8y.IENDB`Ext/Icons_15_VA/KeePass_Square_Blue_Locked/0000775000000000000000000000000013061030506017361 5ustar rootrootExt/Icons_15_VA/KeePass_Square_Blue_Locked/KeePass_Square_Blue_Locked_48.png0000664000000000000000000000470612567604436025537 0ustar rootrootPNG  IHDR00WbKGD pHYs?% fIDATh͚ypU5 I @\!\n91J ( Ȯ[DX3İNBBܙctvW_UW{wע+@% LGa0t~F`_G&I=ێ2HCh@Ӧ"I%^Rֻ}${۾$~]ob6ת'08$]:'|6xe5pD DQ*⼶${n缶ݫԉ]Hj!?:ȴW´|:t^1^\mm-_BQ;et>^FF J }=ہˀDl޺/OH̩cTU>paw[m 8w( &DF7c$E5^@ fm+5@` bNaaƀG7CI**O2yt=AՕr;,6T!!X#0G:ȅ3ѧ3pE Abb)u \If u* tb6rHX2w3F8z3[=7Wb ^Aӻ 9=:.(Ld)߽Îk82gk9ظ696/m/ZwdǎVǶhCʪ^!*%3om$ykEsY{>}/xQBUm\&S.^C^C|.݇0s 8/~{^ 0KN*fpH5 թ`8IeYy[#ڷʊzn"iʫ &&VVWp.sOx@̵O$qQ|(yYJFF7 81E6SUQ~' xPSSTBmE_uU>EܺQ|+DfQ1=F,._^(oںA$'o}B*+ qq:46,%Kx Sߥc5'(yXd |W"1RdyReX*l /(2<-qg3nJqDv؄E8 .d1':V p ں(1Iblywi۷N ]k j\[iqzʒ;hl!QZV:ڴ?\R1/[^V҃{ b1{M)PQ Y R:OWzB _6\ =nx]+<sm3^>jd]X.z6Y`TglōjU!*p# .u;>:_ॶs$ɮt]V:cp|2ЭnC5 n\[}ZuD~3«#vvI.wN_oM1E1*ڀ{xu;{MYa;z=ϝU&$% d#UZ߸BCaR _,D^ :E2u ]EIa`Gx8e+W%P]\ IE @{^ G]p2~fou N%\@lBջFgƮ.Bu,*sCȻY(6Ԉ]]T(_ ޅd L]_}VBѫ٬6Jx^8j:(;`*IslgՊȝ"XTYv86CZ;Q@~:JMZp[5?l@CME}i+WD r{Ky &ņi\j+(/| Pn-Ys/YeoAܢ/MT_&%7_0!ig_|shu,7~QB{^1m1c o!7yǴ6 xJ.5} v hrԌI6ąeT=->͡ǁ ? w[OU+X-6 n^wYY7k'7w?p)yɻ9| - b49<˟0}wN3H&x/b~ճzh+\HWܭ'&je}]pUtt%{Q|A}^X\%;|< TLAo>F{[?'F%Vq}HViUMWxfzѿ1p9A_ _)hAK\}96BQ~ #6|'G9vnbNFNnRylxh])sO!߇QorS.1^̻vP?iOD&QX -\ |;J\./PsbڑV'.2+-pHKƓ!!bcoi6<#Q1|)\WA7-BD'{{y}4M>5O""%e4 H>Gμv/^ѵ}~@ClI9HG?yo~i G7BEۀo4Vh`80f3/DJ*ҁD`2TPx"/:_8S @<p?FNJJd!e\F)pw0ɭو#?3yғ2E`yQ]Z^&sl/))aZܜZAf]Kp-\ TT=Xxp6 \(#1o&2/71EV:4jԔ:uS)21DE 6 ~{QiU_:O G/.Շk(Zۧ?TEG/ t/޿KoB$;+4&s铇uNu@1F)Y*Ut֋:ӰQc"kĢ/hx8+%nW48>hOI0^vz=%_l;=%Sx;06ءܺ-m2Φ<1zP/soa0Ҭys^zK%_vN⾭Xatv+7F?,PMdd]?a7C.(R*~ /'K?H#Xbj/e-FBc >ٔS̛1?HFzJ1-> l =w;kD ?/OZj2s~i#0QX ,8dޣAC#"2R/w I6=s('=(CVnNdܟP7~ClD ?/jg0GHIZ+6PD]]nL.iA/ѡV&tso}S^_qU.G q~ HODd4z#B<6.F5vc2nDEE3︼ߕ6_t {9|d 2~ ӼM/֯)"_<8P+Y6?LM%/3=;w^'gmR7|n.7m⭧zL[ P<{WRM!4L~%>{ӧxT9yo kJ [v˻w%cn׃-:RGT4i{^{zvm]˦ٰz>60J۠`yYYQخDEu4oHaT'ofީ?aߞMx.]GsQ.kFKQ_x=IƂB ~F IO/+Z(=XBMhx_ZuڇKw՝M :S'Dr1ï I@}s Y*޿ѱ< ۅGr}c9ꍼʵJ@דÔ/s< Mߞ̛c@ry?_r{|kx_p a)9nI@ï0q˜$Eťxe4z1sx?SPU5 f֏c }_>?{vyI(\V-{ -F:~I PCOG^W;}u*ᷢ:y?OW|+x=V(*6z=,5g:~k``\n7+#|*dݵs~TU%&&J~" B, Ƙ\3[8~Xh&)gN }+i/}F|?T\/@HڴTao(.OAw)geoך_TXqK;o%*}d1)ko1#~ xr;pcwu^Aï5˃./ ~~ lٸMPGQS1rz.!ň({wB״ =72uoLGFFSu~ݵpa38u|лOr۟%^x.G8HV )I w ngaB؊4ߧcm؊(Ac\0(-J_u'FC/cA (4oSȘ]8ql_LL-@mK˸\W݄<9[] =|@Ra3 HDXl҉D !@pռM7vF2PVca푞ta ~8{&YRTV[_Ƶ*U%lX뤧&<&?萒$mS-*LkB|%#-1[ u =-E؃'/#T.)! @]/& l,Ǔ  !7WPE!&FE-**<cԌ!UQ[W_Uz#b#d<{t^MC(ߏ%Epb6᷶0?i~?6# T%%/bfS&I<"Co i$e|{ ?ۯ:we}`;Ge|GB]*+PE1* uV, IӺA uH`4Ȑ m&ݩm[Eܶ5Tرۈv_@ 5!8cwa)RoX;UN5H8~m+ ;4M^*+<^"RN9~ݬ/J:~[L ~Moi? Mx/Z)gس vcGme3)e/}2sK+Loi=bO\gTCЦ-qRa6X/qކ. 3 Mwo]xrim\fS|67ي`s;̚ӧºնdD#9N-  $JVϷW5l7FB\CfP"L'-M}0! n JIg?[ Ɛ0k}E~Β$P_  |ffC`|>}F_D[FS[¯0Y{N6]pi瀞nDPY pz:@ B p(e2c"P8~xNYY1?-\ۃ p , >dH#à+[oF ̕x@c?0pÁ5;U~ Ǐ9Oox /=xN (غ/.ŅЋaؾ(uX't#fL*V~af=qtE5RC!njL*TgYKB 3%v_T73NB)1eH/l$`?7\ꔬotvWiLí}_sGF?fLm\KO VءH"nZO?%=5ja @+Qt tj1'Z*Vsh.$jw("Q ׽1lk@Yk<`,ЩA UhҨ=%d|Yu6˱Oy u$f.湵(AsyΗ 1*1Ʋ~%${SemvHu[1X>u*K _I"n۴0˜@մC%~GT恶C@0j!CWL>X2H?(&}eblj֬4'zyO7 b*aC"ԨZ&}WB @}%NP"0P5%s)?*jԴUI`*?XPcD5Xjֶ",YF8~8aD`ia+δ@am12(ZbS8~ka6*+Á + [jl ?rE4f4ƊשiWz3׊2' ܴ?٢ڙd{ 䑚#N?'HCpЩB&(~OJ E 8rXaOߑQl('ɡ!miv p8!@ץk8 @pl 9DQ a@)!>I ۱5Z9Tr7 ;v~l˂C!'8W~v2u?^Yh*!T_X狈YV%Kǟ)1 (zx<lFЫͅ\vr|=8T+ x(Q mG+ 5{#= 6^ω9˄ ͬ#0<8q۬9p\a{n; 9s9$X붓VL۷B0ضlTTV䒹{Ey=%_TOs]p~ F/Uc7v0.>.oGc7D w괵':hZ_MCkNvi{p ?''H>%œy1'0С~+ׁ4 2dz*mc]= @60Gd#.g$X,v)s=%R7SE]^qޓ 9_zSrq|9o1<qOdزY@m:+'﹑[?:cHa4x9g>$v {Lha8;c~fve9c4l :/]jb UX[TK#`yaGo%:u\ n%}ĕd$WP%yIi?#~t8ՔJ[;%yf6WS@TEELЫ*V,I.ݍ7>#lvIoɌ?q$ho~ ReѪ?쾨;>54je+YMZ]K걬 לpz24+_[ NldFNXTwn YYaiw3k[Y_@ h=hai[? G \{L @ѕi 'gOjօe2gux8/eKʞFMAi,KzTe _ G78Z\k0k#toH#`v\ܛuJ-ΙgZY#g‰@I: C OʹTfdE~BG3Y'kf6_ ЭzBQ<ހ!}ai)CL\m!o~]~փd4$໢ `/G/"7ƹ].kYz k.ƆVW7?ԁf6" t. sYrbлQIZ;\XM"Khc/l\vx=q/}@u_t cb!0g-Z/vFm/^FVD'4 ? O>?܀cj}hK@0ףL.Ì=# Iàc yt_6SOdմf0 Eyqy1BG}8F(EArz(9c>hFY~[ :ܯR( h@ `9a$ h-C<0y"59l[~zDŻdMb65}= :is 3x`r-lشޖf[|~Wx]n 32 H*Y"pgV0;_f|ac v,Yh{v[#7,Bo_5 VN1J2 ƌ^e9SECW qи)\jւJP)X@! $'Ǐ5O ?9v;>} 1~ 8ņ٣9f^ǰ^VXF XLFT% 9?CvЗFp %) ѓ@./Y<T ݴA>qß|`fn꧀}£+zH;'CPۚ>1:Þ՟g'hހTי =᫖ .Uqpjl3S#?'46|޵#7;5PM}h _eow\(#X\JtE^2c~@q*nm?+)Xe# x&FYυ sB_>Ɂk2a|뇒C0%3{f*$aG-(eY`[fve`L9zsS:1b&*ԑ9YBKr1:{2@3#`\ŮҀ_=n,H BPǀ'0Jy 聯1BAPh$5T0" 8_ثI BPI{;ВR'xen5 ӏUY\*ϗ=z!y;Q/ @0&,cR_p76<4݀}Xu9U( }"F~@W޴z]7-Qw y^ w5FsH6c}$ZuvzO&` tL+tpA'Q bB.K-^nj!򡪣sޮa2oѭcX caaF TBmŘT%wwbcsnpV$pJ:$j_3w;5LJ K` (9iNj6RNoIENDB`Ext/Icons_15_VA/KeePass_Square_Blue_Locked/KeePass_Square_Blue_Locked_64.png0000664000000000000000000000637312567604450025533 0ustar rootrootPNG  IHDR@@iqbKGD pHYsMM_ IDATxݛwxTUofRH% $WJUPĂ q+kVDEQDX\@** 5C@hS?f&w$~owswyB  ҁ@RU@P4``K֡꒢}}aS%ұSWSޅ 4ߵw}] ׄ2Ο=т=TWWLcOe\>U),*\*B ܿOFP1k[,Ufw:BX)V> ҳeJJ3z;c ]x5kǷ{{C]<#3"m dzEvN,[5:u]«*4ImEϫobO)/=$? gSYշ6ols\1/OObO!@kp'<0B@\T,i`Fsbr .+AMIJn6}~ؽw5jʽ<|I~|Α> Νa`4LJji\=p4i0xw>C' S*h<ՠEgkǷl֔߱} Sv7XxWT7_{ثowd 8MȩG„GDف%",◢X-r;QR|y&e7N*K+OOa~)@tL_y-7HݥCdŒm-UUe>3uZ` /Tj+/$gsf)emB/Pu<>u>GҾ+ ^uG f6WjURV'1}9=t1/.%-6*~j+~x!SV`S3InkG$!Gf,h@U۷kkЮc:]Ε}GK>{nxtkϕ _3imgp34}(:*زie5lݝz6a_Q~=? )^pf`Q]K18s@_k zz iS[^lP ժb0$5 n`ڀAFWB@p.(y!.x3#M6b v1jŁJً7s[N]>ưzzk#i /b FoF ՅdK|S}CCcJSH+Pt}9^AW'/+%tZ2#!3kHAJ l62}Kf^q^s嶕l.qɡera4m1FSãthPjJ?;m_]1˅ԬQ]Br_^ d*:L;:uVY PrvDlوRrǜ=Fɽo P.M׼3a>:|v>=<#GClf_wfz&5U+,\Q g9{хHvUE`^ᝢ5%,CMm.maI2 Brg0v}>= JH0 5:_ˡf(݀e6b"9s+ep<^pD!$҃2B&>F觃BhI_/SǽNLNJdC UTy;(.(̝P78-L4j~!̃;nԦ#K0n6 jm@e㏍ w&|>A)=߸0RsHjz_!<4QZ}} ^ 1q͵ǗB $kK˂!SgS r:n" z cXJ?^F#}U`&%)#]A'6Iv;L}RH agл n] v+%^ p +tjz݄r4N/,Vf{F(phvn&P%k& g쯧tKo|ʱ fqz Kc;BBpd\)$$c 4W`dfwA pFؚ1 8թFKNR)0z(:O56Y# v~Bf7W@[ai d!:2!sv 6{/T 8[s了?>禩F#Pԑбs$.lVu?VjlaZ/ܵsX%SZuU@6猿KX Xfaw5(f><0 ,vg=3K!&XP vnkұ6ӃFu<`s\gUxx%ocl!D=?kن_ml%pK72|6Og3"%K!2jΔ~" s4AT_5BO#1@]/IGegQ}~XZbYeIENDB`Ext/Icons_15_VA/KeePass_Square_Blue_Locked/KeePass_Square_Blue_Locked_24.png0000664000000000000000000000242113061030460025475 0ustar rootrootPNG  IHDRw= pHYs}}HIDATHǝkLTGB(ETEkjjMk}G4MkF45hUhbbcBj5 X@}XiD| (;~e+jdrof3;goQ@H@&FpxKILRi@*J}R>!op.F`VgӖHe!5BzI}c+$wPV=@4eee=QLxSc=׮ 4$!i/ 3hq_n#/\T 5KDJf'k ܄+u.$Hi=u-.%$ "T1>xϖktjj,p+!:vp6BWg3S?c[qirΞ|:,p!5J@ >?|h/-$wQPT1)/dd<R!f˥s9ou esҏ XS >1cDhvpڽyqgRu"zinK@6WA)5?~%Cn_K1'=afpɼGT?v; (HM\ aqN\[+yۗ07i]>G2 `;铴4 A Zﻋ+?FI7NÎ֠5(q$ B.2ׅCDo2mtA5x;n -op$q%?ѓF#/w[{<|[tb_G+)b_i^7w64=~`(Mf0i2$EޚAwM@^R4h䈷 ɅV)z=dgyr'Р!@ZzHHQS3g#-abKGD pHYsjfIDATxy|E92')ʱ"ʲ޲.x,讋׮. *ȡ M!>&3cs{3yhիW^UkPFÁ+@G t;b8p j,S@^1]< >xhpV@'Z*g>@?b}Stܖkk{ 7Ѕ+ h2Q󘵟a? cwε5Oߩu;kͥrz⸜&J9wYEX+-4y|9 _jpnc#Gh SyԯHQrwL4-WٍoD ziߕ4R1Sy{vn iJڌ6W`&\ ;t:&MGfͥCNCkd4}L"XkdG  쯊I,X.7 "kM|t6Q (i.x+N=?q-U/G2lt,3GvJUH@ litR?)&ͅ2uCkU|VIշoz~~|L8"}OvV_ꮭUΙ_t9W7m:OX^@q5NCk%-~ķMYI'vI>!3o IZ{!cJ3 I @-p3Z,mef Eh4Zg B ;LoA-= _(S7:cаIR|ȟ!#^r:F^n%%E!ˆ!]g¢|~}FMï[lTpjߤ& J6!uvJK+0Q^^jmƀ`Bk:b"]Dg18C)JlRn|OOM-"> (-)yiRZRHiIaͱiټ~!$tIdYt9W8l3H@xSS6/_@~^Eɉ ,za#&VSY Lp!T ^9֬ѫkY7rsR^^JV1 Ȩ6}|^}W¯y9k3ZGggЌxG<|Sy Y,yKnNW05`1!W߰n%3_Ϟ_Ql #J 8/:nCdl\;_YYɋO$y& %g;h:/ 2  88kL̾TIqQ[אܗ`0;Ns~IqM)^ ƣTpN^see_~+Mï0xt-MҽXUjp2#WRѬ4+㤀V9cGa "*-ѭbjKdt[BâY,s٬Vfk>@s{_ԝn|FCDd !t֏CFѮ}Wc1`PQQN3d:'X <\4vx'ޟǔ/5| w򅀝IظsL.z6\5f&L~6(@BBhߩCGLB 8wV/cɻxkY3T*zý~ue| {&*TlIqos٧]*ԻPgqY=Sy_~W{ֵ特*|dϒy]RHz"gm6j}/+-$H*eHzmY+9Ix c#!@Ay ||4|!xAɭ'4,ACF{|!FJ.GCW ;%Ņ+.(8 /Ձ~L2Rv:߉4tarY? ]x%|!]>ҳlV,f/ $|!c+#mL`2x"qb $ZVG`PW@PpBJyY?t˯Wzi] }Z+#@Ѣhd$ =kG"&rW }k= _T@[QNx1*47 @P (%  bGKK(K" f{MeeSHcѕ{[k ~1PVp <f?y l{*?]jЉC`W$p0=ޮ>pwD:YhiB1HN?ǘ1c~X Sv 3xEn wτ? N]?wτ ش?m?%+G ԂVmd^V1"8x {E>n_mדaeݵW~\/]3`Qx`zzOmv ᢼkZ໕rtۺƽ¤eeɐ0 AVX໤1Q#޼/+P_﯃y|gv*F(TpSq`8ظEۼ(|`Q!ڟGg }o~dXh̀RenXMNEv_e nÇ/#-᪺Ftdp*_Vlszg\wJPQC±#nW }.ѹxA&WBt '+ J|KôoCX8wa!Dnk&P@еz7BhΗ)( _|sQ}H zaK|"5WČk :v%%/Cu*K4(S7mB}E F A/N$|NR1:> J7$ru-zȉ}_WGï6z Iih+ <_k|)/1ptە`Pɗ#x~fCbʀ U݁;w=q4+8^t$ݵ;0w #M6,.= ;nݧV;S9c\,<16VdMw{ F^*_A 9Ozt U&?_ s;~xx;XoY[x }PPiql L}7bX\|(=T D_}l*q_XRCJ}S WVDs 8](_(/rl?V6T Y__dI (pr +uڷ9?mӊ|,Z`Iz{)2lj$]b Υ:oiX`իw@ x6}{8^H?$m`Yƴ@}}2`@f/g,[WJNQ0GN0S7/ ZyC/<"sӸpr5c#p nE-%P"b؄؇YU>lG>™NyK ԙ1]<9<~ 3/;Mig}k)Q >-E0a,];Zb4Zo4oodO '4IWB` <L2On曑ϒ[Stᐔ~R SqL-wPlZ{W=6 6ƞ:mCi^IfS2ԙ#XW[̰u |=s7Thp!`V{0깧/D%O3,iH0$!n 8}o:?<&F#n} |>ּogg\mmR[ kw6۾~oWL!,3{wh˜2/f[[Î x^f w40wd\?wf7*᫖4/P֔ h Wy߷q>/=Ʊ%92*=6&3&|`UAV>, !}:%Nn2o=3jG|)aośWkF㪔`хQ(o0=q2T{ _[`y7@R}Zt<+'"oՠ覅::k@kHƞX$)˙6HA  ڌzK%P \Nǀyθ{'uT'XIENDB`Ext/Icons_15_VA/KeePass_Round_Keyhole/0000775000000000000000000000000012606740430016450 5ustar rootrootExt/Icons_15_VA/KeePass_Round_Keyhole/KeePass_Round_Keyhole_256.png0000664000000000000000000004072112567604154023750 0ustar rootrootPNG  IHDR\rfbKGD pHYs   v$ IDATxwxTU?wZ2)$&MJQ"ڷUW]]϶֕JSQ)RDj(!B R'Sqgp!{$9\&-sQjr[ hd4_@Z5JA[z$h}@Ϳuhk+A6G:iRƟ#3=[l481[`9X , d&>s/mRbJ9~l|:^WB3`L֪LfK|ρN2;IHnwuiJI( ^j%\Yj6u%Ͷ2;JEKCw%-cs))EkV%p-zEVB l`mpJD%x.8!!]ѩs'gѮ]Ƞ] HHH 55ՊE*>ʪ*PrqQ(/+z!Oa^[xkh RL-8bѫWoֽ;]v{t옍hSCG#5FgB,`{ٽg7[䑗];Z$g[7j" 8-A3zʠA9_`'x];wD2܅E@ Q/#aW׮]y衇>Vl6ɧ`WW"hWςG|?S, B]P-CE`ʧ~={vT~\/ȟ3;s?p YmV^`ʔ˛~@kshkw&(dYhkEQ gs?~}/uAp5f¤Ѧju)S.W^!333"*܂zz|6VBFV zB?R~q,i8mY[:X`:at:_s=GRRRZ+xM+NT fU9Tڥ+aW^Cn=X͗x4 ?:tԩ׳ٷoo8y@5Z|i 4 x)n԰S52O*ң>Ri{ :ep Pc-!+£>s= 5: 8%-<8XZ()Z\|Ea劥vOB?G@urpӁKgu 'Cm臶hdI?cǎ ~OP[/*8@$V=dY lCmP%hա;N͛Ǹq#s3?_WlepSB- T#Rh@2 h9sW/:Ȧ )س‚| >#t&Җ.]{۵]3Iovhob.jr>2ohq6#2waEQx׹[L/Ջ">U˿bsYz)C[[~ qcMfؙbQ1 tH2zo*3oƂ܈Pi=<ȣ!_[/0w0W|,J#ӥّ +~JN^1~XqZ6byQS&u{r"^ke̙  m`C?X,9"nASkdaʇBZK0 |6ߔ=w< ,p%FJ_O 7t؋ѾCnxMv*9I]1-믞Ī&-ƣu]P0]v/0=W{Di>/o~sl[Ksp' >y #~G(JLCGdgN~ƅ]Ogs(u0m0މ,]Ç?e%?e巋h:}9n_Wj:~cs\rv(݃aa0 1{_~I&T5W-_\i*) ߣWߡt-&mvhYNm( deuSN.  g-txoJwu7?l zo.ŋfݹ;]{ hA *U:ai,xC PI16mա- Xda1e˾=eԺbyYLe,E{̔n_gv9x*r2i,y֛M:`0% Vrr2 ,43_?֪[Drj} Z!On3QQgo 7n-f7^x)[/=]P]zӵ{VJM!U7w۵ˤmZ:_/Z`6I X*@dyʔ裏L j\~yx& O"9Q1?@Ya.?&mKC`Xo&Æ 7 ?7iĚjk*).Wڠ,8TkG-ب^OgMґ6⑅c09+r?1 ?haT5",7%_#VjgZYL 5*?l7@&_EMNaXE+*fvl۶-6ѹsgbJ4C%eef7Vtz?;9vb;t*+M|UmVq'zbmVqV,XWmM%b~{NC ?SRiӶ-_/2?js7qꫯ{E;jjE?rK&x3){7?l3XEāNϚM8mV1S'Xxٿ_"&x uU𥘂_GU6Q?w,MrOeN3mht=bֻoZ8e`n_ztk&I-2 |w}Xm6CT#b~xs2TYKYO76e6YoSec^FަMMuPS])+0"VNn8;0;h{a'k,oHb~;䡤{RSJj {3B5 rgZy]>>똊%?V w勛mvTN2z`]4.]ߧ <^ p&%KJLL ^*}'O9 c>Tr޻SnI_ 一?yut ?5W5l`ѳuؑ/d~4?2gKJ7V /%+T9`Don~xs|:vЪ u`ٸ| f \i 6(L6BۭHOoOrr?)-ɩqz.ǯj m=rC9 z~G~Žt3<^bnнGo2g:10-誫2?h~~ 2* W3붽ntT3l&1fW\q!} ~ :: 1q ?@qժn&_vMuh^pFѥkW#M/ q6mڦ-ɩ?*.B[b[[7:2f|?ۧ4sÝԁ^j3Iqkb%w7ʈhI c9%L6skF{m\/:3fb=`ߧo_z~{$qtwgs{ֽܺ']tDߋ.h~@#EaUǝ6E{As\;HS: $@D jhcM5/^4_lh9nOf7Iڥr00nD3I2cN'g}n9 ?%Axupq$$$I1a51ct:uvK^Ko[1= {tLbjN ?Vg;Ej^b,b &op퇎Wusc܆hqN042P]9+?~a> Y'ѣH c׮¾n054o'Fd9 6G"(}F0Is%^ vV㙍F2x餤+?BhzMe m;߾b7{u҆>}%3F|B;سp&agt"USu`S3J54;`x!aÆ_xT^{6?<v{BH䮇ft &-ݻ{bIMFk+'i6Oi3igA>asVrr}w$58)p{%Xie3w |k)/ LgVmAo8ϕ9 #wou/C>P2'x=n36[6,z΀8kU }6C@:r(..b(S+MSI#/$9]4  w.TUeH4zb'Y1ɮ.] G ~n G (9o < :n%_pp{rJ, ;PX(9uÏ1D t 5 ? K%Q IDAT?pFEn9f yp3rV3$6[l u 3pF ۙ)a222u4$&[Ĕl۸ U(/сDӼG2tï 3_S}L@Mu7J P[/tÏv uki_7,5UH ?@K -ԀL jT  "*BKEv nڙ2t AB*55U76  `֕x=. JjvJJ37@ C7@ s_^ZL!]H:&9g n?zkńC6.G@׹^S@dbK 8 BO?nr@'Z? c ~** 4={  37"6E>/[VH?JK $E7UUGMbYYL- 4عe5Z"훖J# (3^ee*? [6.!["0 T3R `xҲRآ)4UG~\pܔ.jU$Qu52nG~DnilV!0Bo۶m ?A xW`ebŅyTWJrlعccrL6L۴I7DEF`3ՕbB޺\&e ?sl^`ѣ_nAH?n\Lsjז0/vlۼm `ѣZB7M ~lߴ `?LXHMRtfn1- z6RUU  W}^vm]լP~h %as?O Uu%;󷘹my@r>5k ?@"wUWMsk϶o%asrV|fn٪ `U+ %I~!zZvm]*1)@[~hdVV7vB±@ YA[%hm"|δD7'(xiG ?f"zW-{w" 0lz: _WWLxrvR 5"~!  zZv7H޹v^j@5/\~DɆKO K;!pR <6B6#ۥ_M"186H|P7MHMh[|>D3yzXK3i# b4zdV]޳K7X%&ᯮ*-ܮjs{ _g @'ݘ,4s> ?@SnU$*-M{-s:guyfoB= 2z?@"Z%GhtDٶTo0 /_ϟmT+|BP=kH /l[" hj w7EaԀDC{~2T 84CJ|<#nWHOJ_֠ۖIsCz;hp&fg6e_5lonδI_-ؾTD58}>MOi.gj )A!5"? m+[Sy䀄+Nh/eV5UceÕW^zA7rbKp:jZT[ #yIG̷_0Pjo Gud!-"o[ߓVv,7s:`3uu%sfe6T_c_DxtPn]ܼU@<; /gLup^7s/?quNwLv* Kz W*>z~'h̗ނWizTnxF&J1Y: kG]V_$.4?ާ~3IEPr陧h!R `%F `@'Y6C>٤M1g)j|K6# ?uoQU_\ß`a!>3=;&~шlLuF>x^ج 9YnjP_wCE~\pFI C{^?MH\;y?A ck h+վeq v3OK4?oQo$/[".]3v_&# !0Wb1}ވ6?b^~(5IS=.jؿ{ձx_grҹ},.21Ng-,6(ݳm$$X9\ߪ ޵qZH2J+3;0Sg|f??DX ~m_.4n:>M1TWMc"~7 k;o~Z݉VrE8b~!ӝ̱uf80,ЬfK~cdSNS ][ń޷ʘC L2 _x4̎V-oES.1aU1 ݪp)V2Rl\]śh~mvG?D^`(Tsi0d: GCIڇ@*/2,_Zy_C߹,f'3'OGUe({KT/>>6@:h$Z1e%۩*9;eظb\)?o.C/0]塞!(t ?t,~HZS;,xq*vb_DHha С}tu JLPZ="ՀXߢҮ0B;(+=d6)KqOeUæ-7_5࿙iVN[ƨ, .=;޹v?%|=/ r-D[ؔݯnrlt˶>c짲$F L4[yCIoІEpہM@ѝjp'AKpj(ڳ́h4zH'mzդwkE 脿ŃzW[S gVP"~r-/?O|J_)[OQڑ9v]>B?| C <^<GkT ?d3m̘Xh/m[?tdg7p&D0X?ݹŭӮ9~|N63$H%!nKۚr~C?%,ƛ=1ެ8tOPh*S^ږdb]&ÚFu.&`bsc0 p9}{ٽ{'/EQ ZdΙ6*}Թ_¯v~zY=< ~3?_im`f}f1c5bEs{*uB/?%=:ٹ68s̗Cg"F݁!frR:ds?VQ:eڨTժ~ I+'nx֛3M*aC~=un!o'%X0ɨN,J5N ֯[ p-@[ip(S>C_p{ylƧJ[ \tf2IJfo q=r`p퇈X*[PT]UɇfՁA ?բaKG;5?؈9WVTKn s_s G*JÕ<`k%[N& $&:MXURe.{x%QWg;DN]G~z~|ˏ4cx0.o~70,Pu;9PG~E^9vDn ߳k?m[և+ -0k 75h^(+=EJj*C1X$9-̱5ێZ@p( 'pdDK;Ω,n^jɀ@@opp _=nFYۥN{{FM`DR-'MP(/屇Z} Un`m 3\lՑ'&$g<*(;=KxѩSNXo* :পVH>KK0g%v$/=|%>8s0f0_"R۴<-ޅb1 S38zQEʮnuSY%m, tɲ55z;, !y/QS]|VUҚ`j6'>3c`0^ K{8|矅{+ht{8ksp5ٸHBOi_o? EQb hڪOONm;a^/=|~u 0a^S~^HJ;ŝĈg5u*JP\Rzć+Z$6BV,Yvr;IMRNUрq3WyDq 5 /;pfp$D 5*>J+}qFHU I mR-XLѡlXPzX8w/ E,:J[>9F N :tkaڢ p{*GkTj]*.7ԺT.O>8VvZU!1BR3BC!1Q!-JZ@ݑ_UUc#ۻ+U> Ēt% .R'٫/w ^~56E `x,y/-ȏd: KĢoz>#4i?m%QO>|_{EO7EJ@݇JRRpur˭9?(̷_GDSɋ8? aaRX,3ko '^vz  ~cwKXŜHt55hy62`E- CJ4NپW^u3SF%&/س?xO?/eWЂwmFbG=Цg^͓ӟ'_e_G$M_|`,/|+\;x3o+ Wrҭ{O ?wO>|5|k#OD@v<J~q]3fy>{g6qukWj,j.w59"2!gʬͦD?ga؈ v))mbJ6ukWnr w+넪/"Nŭ=Z3#G6OLjjٙضy=k,gghkA>lQZvA~ݧ?]zۍ9}b*Jh/EEۻ[پm# wcHh3Zl-( Ne2ZpvιtؙvIO$-i2IKoGRR IZhRR26Ox=jkkk#e9RΑRSrp?[˽܊^~&qЭ'.Zp Cnc[\OBKI>[SYIDATC*k۷t+) B ,k[=&0HfOh)m& `mZdvjN ^%\h5/"KЦJ`óy/fl&D3!dcߠsN,BEGL]Se4Ji!Pb$bMv.ʼnmp? Ғ4Q )&o_//, @G%#0o{~ lD*m"NɆ"`` Zdn@w m=n |/% @*%tD}o-mA@oG׽}m2vZA-h#ǒ]ӓIENDB`Ext/Icons_15_VA/KeePass_Round_Keyhole/KeePass_Round_Keyhole_16.png0000664000000000000000000000147412567604046023664 0ustar rootrootPNG  IHDRabKGD pHYsaaU+IDAT8}]h\EϞݞbjlTIhibR)h+H(M ^XEmSD{UPP.. )5[[h6${3{E􃁁}ofVVmۅtM]۶ @/SqH&N}xrV]n,2Srd`ps 4ͳlV |(%LL{ɕIW ƛ4BbwFGFFwڍ)!XϪfvwxZ4@_& ?jRQr'-&@iic񗎼,Sl4=}[_ ~ T>Nf~gŪOi~,ܵ^4ēg?|$~~O#gPq?FYfITuDb~f5K9j5|ocB|W/74OixӏF4p4̕Jדl4)M$?aM[?S Lǖ~sߟJ5w mBvVg1VlX8|] >W^~ug #rR&F׀𿦲8';S]TWղ@o_>IENDB`Ext/Icons_15_VA/KeePass_Round_Keyhole/KeePass_Round_Keyhole_32.png0000664000000000000000000000340312567604066023656 0ustar rootrootPNG  IHDR szzbKGD pHYs0=IDATXåkpTl.l$l $XcCc(f+4j/:m:ъҖ) 4@:t"XPb.HLJQ-hl.ͅlvBJjߙ3sfsyG!l`zhnh*p#C('Dwf& 7f]] h+eȾ}VtK%%#KG,ٵg,ZDt` HEE-nːߔ^!W{ti6M>k5ѥД!S 252UUӶo΋/% Z`i`X`)Œܩ*}.="r5C'pPr8ڵpF}3bɘ?adXtO$ +wAJJ6ׄ@nqt "a#O)$ޝ 7+Glu;v%Pvm:ښhku|TuEĻg}ߠ ߹EQ X@? \*((7FM~iO y~[[ܗOvW.OCVC{71X0qMY9Swqp4 jKlPC Ңe|>mG b37L! gt.d5=8 ~͊isIHL( bzj8xX6Vpj(5h=i۶?z6>eMKhBGUk[T nBb Uˋܴ-͍tcJiASADho ]]^Z[q:྾^7ha:ZZg;]NsjT)\>2֐@Kc͔p玥px[ 3)4qII%p(U`x 2SDtfkWN"g~"5M`8|}EFvw>Net6n.ℿJX5 {{İ|4!{Պg1k蓖yy$͜Gq:YWwrޙ$;(ʢ{GJТaDd&8Y]dض]%h_Q~|ZdoD7ܡYbi~7){@͔@ik;N`2wfơ1u|'3tۯ0 (iB6nyNZam]:C€ƴ8WB;;ݱ*g chzx` A!Њ5dD>BgG+Q~PӁWma4=T@n Q3!wN2oGR~,9Y$~ȟI #鎀IENDB`Ext/Icons_15_VA/KeePass_Round_Keyhole/KeePass_Round_Keyhole_128.png0000664000000000000000000001757612567604134023760 0ustar rootrootPNG  IHDR>abKGD pHYsqזIDATxw|U3榐jZEz (bAba-OtW]]˪⮲ZkW\wCD$BB $Hn9?p;3! 9אeμ?sKn\vCUU)-IqQ1śټBV^EݡC-~߻O;M.f2nٜ5nv:6 DFZS$BzŋXbyKZ 78O_ssNl\p\;u*g}Imi-cѢ||nws?|=l%GsN2d(SNeʔh׾}#رbxݷ{hk~ 'cUv6W^9ӧs''c~q>E  kX`ncbʕWNaƌK#^G_Q TP@dYB$,ad~pQf?o+B>pPp,*:d2qͷ0c t4_Qx.wU6U+I`1X`1KX-_anAv.'c[j8oYLH';{_`ȑM|EǫxE(d?t6.lHN0R^9ׯowƚ?{FVmLOO硇bڴ0Laxnˣ"w $ %IMI2]UU>`.WVs??7]H>7u%\ٳi7_UN<*^X?򝾟fDFL EUQ{:y_}}]췔ij:!Mg͚IUN!G-i)2Y,$'I}#+̸N.WSg||*q'`!nݺ1w5;S]'1Se3u*_)ؾ\o]wēK]2y%뤥.ӭ6 ?v&w`6KTWȂ7u1=4MdM_nի z _U*Ȓ a=v#f3q:X˚+ng[+^K;-̯FryꩧWT8T7+`pkx IcݞĒEMFEBߺwagL>=߭E v,vDriFҵk-od8 #ҿ%xs2u ׻NЄ|l^Rkcj (?y ={aό&YYJ/"^;U*Sj֩TT+0a6I>}OCN,v:|^ V,3gdƌWKEQ+Y5YΖ~]~%9Ս=OdyxRF~fI ca׷<ģ<TDLv`Q[Y5+Sm_Yl0ԱY5bdalM3i#(_7_atɳ"!oٳ'WM6Ov<|4VFj"12"#5UU{pJwp&ך@0oдϛ7ݻ|vܮ֛8s],I)?"b /ZZyΰQUEP[Kc3pœ4 Eܷ_ǦGU|"8idD z[K{BNY$'[#|-ckޱ\r)O<6||O~4zK~D˺5{Y]s#? :Y|F7xАlڸ[tG~lQ`hܐMunq~e>&ODu~Qd[kHm[ eo?p++1ԓ>wè?3ͻY[EUOM~ jddSIdSXkK=_\i$raÆbC` *jl;vl PhY6|B?md?́#I  Og/.G@wBGL҃/2=&{_ܷ^:|n }@S 2Lf`닁&)WѫWwE߇ "jFACn=8KFu76% ='`׮~pv]1=-륢ZѴL)Fe/k,NZgunvMO61@jZfToqӟAG]n'`tcZM0Fߍ+#C!yU5`&]z%_';0Q e]t·s ]nQ/(BPX| \8JVϪ%vk`BctB)LŦp{Ԙ_z$9Rfwp7}G$%%1`piЍ;vf|7"5-N18IN͌)|!^EPV4S H0Z1c  ?-kNnw:!O~] /1Ʃl+Ç>x ײٓ1φZ1Η0[lq_( 0x(F 3r(Vf*Hgjn^AL ȭ`2YoosPW*zQ<@7v@lEwfv8 =b?VDZ ~^ާhzW6@[jfzEF:"f-]{YoB(> n z0(K2#>h_*ݫP|e^6 qZ3q?G'-|!@i1@+>3Nnolnq&M>͢s |zN82O3i㦷_Q4u7@w 񞤤$AEefލurUUVu[jf?+nxn=$.|՟ v/v29E/{ nE*p*{N 1 ˲LZ2TC;N˒vn{gjG 9Bm<#^3etBSR4g/6*^ ~LHa5 @3O_ݏ=7E 0i}^B\n혁4:`HML{ _(޸ x%M%$N5 %5U3V_" 55lFK8zh-~6@T~BPaY|MȀBwk5Wג ~]]-ۋ׆eڜx9?vAP[RW0Jy /N8B,izn{tɀBkjƟI %|!`㺰% 9`. hWxGH벩ʽ܎&&Bs,MRT7DؽG7V+N;tUEav12MWw_׭eΛdBlVlKT [6.KG .;3f/Qq%߇ApS3|_GL&Nhg|UmZJ4ʮ-K_0$i¯})Fat"p_ E][]kV퍒F~׎fЄ/`ӨһZ Vm9x5M08׆&E~E͂6ğ&!Y~mMS&bzT|+!253 Fifb.tR`TU"#UfOuvyhWwM%FE,/x38g.dI6&~ۯ4Xp8|Hu41M>y_}n8׿ DDirY61j!.dVDf6\vw m[&c[}ܣSFl* \3X2222tf~YK{ Nߵ/N'=Uօ{ щjm6BzC'eɂ۫RY.<5bJ!Me8y}4 VG}->*I!X03ڵAC5#W$c[3&T*x|Eq@9~i2%d @'F|p>.njt$_k{3*1 ?'٢i 7^~gՔs~W>-s`<;G*+;<1ė@`Hb!9IG9ۭ2r0iL* _UM5o @)e@=o"<mo<oqSX>:Q`P/NqؖR}D[ɏ@-:PJ.ټ; 6J~ .Jz>w .7̽w\ˮ&ZsրfjETs3Ejjk胷Z >P+aeU5*jrŸNDC6/ݷg3ΩT ?_4wl%8ϝ0;j"jx~+[Lk_y?p+&I~0XvVim&_uP/+'Xel!n\/c5|\8[T5x [8I1xHCvye yUJ ֚ٸ:dd"'BNE39`vo乿9x@ ؤbd)WmwY]6 _PRؽOZaOGm|gof"3D&;jg ~^<ȁm: \E;sba+37l94pNpj:]>Qج2V&,yKKWVh\VWb7`7e+& &^έKnG <ģ_Tk~qSMs=͓h1 I9wL.:23;%|֭]mɓ3aسceS9m9$%%~}!-/?}ey6/tEJ;Xf3 `ig1q >QpzV.˿gy7._k8-$ GK}ޛ.Ȳ,PVVZĎElR_Wrַ+DIr0#+bRVY]I$=-6{ii5ښ*z@6?ݱPKU?B|δK3KW`:D_R5h%m_@n^.cnjr18) $x:tz=w *˩(CUՋN?VGVFF|kn 22T?|UӧJONUٚFƭrdziD.|ە(rɒ[ } D^U{T 6OX64_6',\$EK%+LWn˗ᰐ 6*1(] 5A>e]cX6MҮ K[o[֗ځQͼ<6lM7-@Jm$C!?$ B"$v.s!%q.sC!)QahDm+Ҟ|xRA.{ 6aϰi&rssI#* 44$0vxwP_|f, ?BP Xl1bo ,fAg@j 2Rx?v2DQ m|Ǭ}>_}bI_0a۷ //τ m`޼/ap1 sJTWY|nwu/ /`\L:ݻ0a>x}U ! %aT C]vP`h0~'{w朗Հ 6YYY h H!O:PL}] BB\ IM,|ϾS|gbMAJPwo,?ֵR9_R뗄‘]zW^|ϋw"Dwlg0~\[0CJn_<&6`:p?S@W\c`[laƌ~׮wR^J)9w;>x!Om*l CӆS0i*od O*`qϰzswFW0R^~kBg;H6闅7OЦlv~/3i?0yd:DJ%@dUUeup(" L?gw-0)+ H) ܕ oS3*Yc m0()f8%E /3 M V޵d`U?2W ,ti}۫,s#7;hZ,a[HO:4и|q:?REԶ1ٌ5||2G/#k #EÛ d*o:6YXxǺs!SaktP bnv}ySg/\]Ȍ̜5f5ج_A$ D20V_.-ů&+~Ï͚ʃ?!m1 o@idO̷v5Ŧz|/DJJ!y՝ܴlE1{=<~ GU5nkRm#q f$ N'^g. uϞJe5o%scV^dSʸQ$m9 `tUp#9BrR[sw^ҡ QcHY└AUq7TUPzESG^H?$)r%[bq%'ՁO[#/|I^efqNk,;V8 xM>=< *$' Ӯ&aw<惊20`{  .?wx!<O/|ͦ^*?H(?^wx!!e7cYlUEE -BB鑽5*O^COWtMj(/75 BH>VxQԸh+­C'4CKQ뤺%B* j'%IfpҦIUU).*B5IJT (?5#t(nB@V )XIݻu 57x!xe=AEqWdJ ӼSkWGEkm[8+Q .B@y?P[Nksm\lУ[!>xO!w}O?TT{\ۛ=Sگx@uyIB$isv%KMfC_Y79 F9ۈ ^E |SV3|SaƤDEnnpg^࿌];s!@p{LB@~G cNӡ%CJx7Jf|M sPoxji~P;MM4W[S} `\|VhP g  MgʋGJMƮW6{0 lx|-\Hu)tD ᅐ,ΥB zaۿs1OU*FG:]!\ݩE UOĜ6W_Uefe.Y#Fͷ[~UdvI 5O3RZ)%R_@q ~|oæ!5ˬoKH҆"&f)/J4Ɗ͏tr95v.羿G[[ |"Z!mljdŲ9;J MId0Ƿ?9k6Ąoe[tH %KYŢwr`Sp`w(5ꕅGJ]s <%>euwT}ƍ1cJ4OK",ds8{4?VΞ9XJe>O.@{{mDde $)FV@h`'(,ĝRl3ngݪן5ry̎1*~m ~Ϛb(7.S#ҚXS]6N̊SW+/?~:?-O EOOXofe1{s1jTք8W]Dt0%kF:Lhb#TUl[ݖR}]֕UeR= &Mv ㇖@HhӮR b'cL|üϳ{=ծWmeu_ď^͜y q؝fqUG hDo`}E;w^S/HAbnPWe6knwr 9ki6B>߷]; fX=gtNF 1T/?}D/B#;\Ff!)d=;RW{jw%rJ-GG#x\, ԧǁǬc>5p*pX};U0J$fz>8?PB$7IENDB`Ext/Icons_15_VA/KeePass_Round_Keyhole/KeePass_Round_Keyhole_48.png0000664000000000000000000000543012567604102023656 0ustar rootrootPNG  IHDR00WbKGD pHYs"": IDAThŚ{pTn"BM( Ghb;0:jqdjGNU ( @BB"A1 }dwlОMΝ{;u)}$`0 d@=P T'$?%춒*F\0rdGzFjj(^oc6`-5?EEHIg [nV + CJJA%,vȟWUF(j9#`z_8! {안%1xϒs7XRhI_@ׯg{?sa|\z Ά,..fݺg0a"B;`X5DT>Abji6.ϝ~}]\xHsݬ^_DP6iBaK`i19hk\.~,\t.v#"-@Y23p?@nn.7UW]# ānYuZL3/4Axׇ}3f`w1zhD A8yx^kfP_PVz~5e0 8dwޝ;>dܸq@;?};*/eʴ9*||;s܌Tq46wD)@m\ƺn{ز psp|W_ZO$ݞnu{ WN]lGw`9($ &~Xzj-Z#_DkiZQvx'2eh h|A!#"ۻ {[x H)..f0 pD:^6/,3oN#;7 [wytAl8Wj` 0XYLek-yO%lxXJ:*45ǟ0 l{iˌs;w^H>^Imͩ8S O}.l %e!_<3gǫ,t+WƌTz̙N&ֶ ou-NY dJ xI޸{2{tu*l4q#@>P p cMY'lNn w#҄4̝D f8k~p',ۖ%,7,Ek#!xPu6xs6 pqfmۆwn[ΘWv?b4f^8ax"lɦ2rdaN #Onf u}0r,&pw ^)8}&bhXbھD.Onwo4:_64ٓ3׭a[9o+wx6i3 JC[ūh]]0M{>`=sZ&ǧMfeehXE~TҸeFiPUYݷmpcfk>P>\O#`@TFKFn^DfR: ffbYxe箎%zBSa ecO2yۤ/ nӝQR{>`i8_XW:{t8 \-_AD8i*R] )г I<0-Y3H3?֭//!9#QͷɲFǣ?hOo@SuS>!,»M͠|7c_*+;z֋q]h[Nd/xC\>٨%)CQ8'dtɤlX{vmsm~mNjvR:0tpοiӯh嘦+ƃ],EYA~nm'5@u >KJff6C G0xȥهnU?gpxy'XfD:gjGk$l*[\9hqݦ-wPIENDB`Ext/Icons_15_VA/KeePass_Square_Yellow/0000775000000000000000000000000012606740430016474 5ustar rootrootExt/Icons_15_VA/KeePass_Square_Yellow/KeePass_Square_Yellow_16.png0000664000000000000000000000135312567604534023732 0ustar rootrootPNG  IHDRabKGD pHYsSSbjIDAT8}_HSa眵柬UD:LQhQB$"$*("$QWMRUTe]]$fVkiTD5wv1]/{xQp9;ϗ$2y D@pR./;|Ғ2@2n{#=Ļ }ӷ4PhKig7`RSdMEɴ":sߙ?GAI>HjO&_miz$/#ʁ=%%$$ynQ]Y.[4h jc&ljcuy\SCE6s˝j+8M509ܰP< bQlD1u~q*`Sju9"hc ߞIٿg(hؾJ_]!Qb.Tʜ'=&X& i 8kR'ƂYN&K3##S&iԩ^we],`bKBĤ3?Q9*˼d@7Lx" Kvdg *"&,MQ,gzq#痕.:~qK SMupCI;Yx?Q8Ygcʣ̝1*]arUZ*3Ӧ՞}j)[6z(lIlQw#11<6ʈ@h]I]W”TU)elܲ+^Wp{|?.t= ݂x4V/t+)>i@,xUU c'/LV`}V߸r[HnN nmCWD_RP{`))0)\:O:e;V%eWp(%N!t:J/;MA<]@A;^MJP$߭=WVHn7b8]bZ&WF^vVdJ2yf0vfύPIJia=&z? KS0f(y#g?GnNZ0Rfbq_ yݕWa䊢b ^>JP$n'Vףcr (bVR4xl ;1?]GxJ=3cUcˈ`έv &c\<݌ă9\9V85iTV~n(Y~!OYm;L̏?XqePuӀL!eϿDu֏d֣v>wU[/Ett2xP&i)gw wQjl3nOj|w[0<_h MZBIENDB`Ext/Icons_15_VA/KeePass_Square_Yellow/KeePass_Square_Yellow_48.png0000664000000000000000000000377012567604566023751 0ustar rootrootPNG  IHDR00WbKGD pHYs?%IDATh͚{PT?. ,PwTGdHьGcM0IQԱ!iZ;ifI&>jhhZ!jhTCjZD!({gݻs{w;sBx܀Mwa;H-b)NFhV`' 99Sˈdj[@ ^v9z.B;87$h?n\Vb98RFPBu|,L# t^˾?FLU>`I"sauêWbZ) zv7f떍?xxdf)ںhh~8,Vݦ;~eՈ6뼲3tmttt!d /;=D~PHe<*8&%%l:KZjʐaKNNםV0G'>M_3Ss׽%|Rs0fݷXQ:a$%yld6V#5208{ @h^nv/71c<^;R^ 9YCMl1s/7:)N*"{Th즡s\>麺3XV][Hw$ZG(m <ɺϿa#3y|+-,)4=.Y_-8+7VG #ٰ~ տ.cGH8Z4X,W|~df:"37j9.!3#U7w D*'f3cZAjbUSDKkxEo`@vޣb傘GؕߞK#Ykpx YvJ'}̘AAnL,r^ h X6]R9C6yR[7\ᅢH`IK$'چmR[^ VӨ4(Cx4Pc$  Û4 ж B'#kW-b8VxPxilQ~?@!gdJt I~azgEXrEIxمl#A|>|Q _D7}DW..lWŬ@ T+XE4N(=6еqW^)LW::ivA UsHKp"8!>Z ej9^O^p$j<ēSul."ǡoLM@$I\Iј\7M-Nj/?7 E9PCxyI#mr\#nL_UV R#f!sUm=g?X ⧿;Cgq1|ƁHr(1 3@`o.*c i` >RGR\ ݷܒDAm,$}kxv&Q6x>-^1bM{j8sip𑲈*[Hƒ0Fޖ*Ś  > hk(>m⣓ R _j5Z)+=j p=^S '#SG#pQ]x7S LLA-x}Z:゛\N Ix 氖\`c\֫-ttsɣJB(M z_[\FUg'ݍ-{jS=iS5>q1pЖfQ|.fރ#~[{^ִi nN~l`ވ~cs(`D?M<qGzFQLˀm6vs@ .txIENDB`Ext/Icons_15_VA/KeePass_Square_Yellow/KeePass_Square_Yellow_128.png0000664000000000000000000001152112567604616024015 0ustar rootrootPNG  IHDR>abKGD pHYsjfIDATxytUڇΞD!D f pDqE<ǁGԑѣ898ʇ~Id1 @HBN'A$^+LstVխ[Mz#@?7$$9Z8ۀ,X& c]K@P ׵!,: rQ8wȣ \";?&?k9QQ :ayѷO6Y=GLt/es q8?^o{mm^lM444s)`Gae[Je G68mkUwdy>k+4R `DIbao3wL.KE7|<~'+65;k`?H]ʞ4d Y!s}T_-SPtY}D^Yb`K')W2L|x?zn| K2fmH5΀X("t,zOSP,ҕ[Rf`P tvdd$Yi| I~YX\-w5>}z-o6IF:k֣3 :ΓIMEf o5팞}GA10dZX`6.3^~&*E'  >B0:L/0|gl jJstuTUDrQ }zgaở`Wr^4Ƒ~veټX6q8 =!>#p׭א7Q}zuaU9o-f\"|g1ťԜAK =xA/[KrRg;|hLM@5+[qt񱺆t:XjcNUVS]S5q)ɝ(5'ggk1-|FSL.iЫ{ٰfz#|mNTTЈ)!.yut.tB!4][GU0枇9/<|zCǙ"n4,ʾ߷}dVqmشy'U5+՜'n ˾|iGf[s<ǿribs0}[f:/det[_&&&~c;'bǮ4ښ[c[)?^gKlLdWbcbtQcźNMv,a̽󩫳>B\ '|&lMuM 압N]uzt!{򟭵&Po6`/.6S |3L<i*aYuS ZZJZ|!iL.9|Uo0K2z3! U~7.`^Rj A!ۊMnċF_TUa$ߩڤ2|BPؼfZ|%@~,@A*;|!:ћA{FPP*=3$]-BzF l.4PPAPK{)<>nn> E 27$v`PTmS|f%+jɻ)ݵ:PV[jj%@:ꭍ^[>Wi]%?| rxZa,N$'--^ @xLK_>YxQq?MJ5/syTA׃$ד,| u,޽@c UxA:iY ,F)|xpM_ R _ k>J%j.iT8| ;|T T~LL$ 1Zum\)clZxז/Bf7%1Z376N7]] _* o]9|^=b򦠽&. v9GK\y9kڝKϛc Cweٚ Rf}1lߍj>b6pP2N+Ǝ%Pn_/Jn?lZ c@]TJ?(Tƫazh]Ji#T b!B~_\4/ F _R;W 4426zFP jƯg|氷8X~|#ik?Aoט랖,WY1$/@!|!֗Ձ`?0W~5f(}kµ>D JGSzW5^^ɪ/=RǦӁ `NW)w/]wa\oKKpq0df. o’jVl8.e`{Ln9f',rﲐY6nf_A?fk:mELnN/Y3~@x- /> :j fx}zX]@׋_?]s^Hi'՞pH,U Vm,T #93i8|/W>܏)YgzXv.ﰷԫ eh| EE=X+Gd,. ^l61aݍŀB%GX77W;[#4=lbU9LǘeW~}o`r62^x! hDX b,{^DVF QFG|[,eu>>:A!ښ44)Rv]),J Ĺmp+NNlFevVz(PfTj9JzrS;1zBkZaT>&} [˕K]Nb lG!,DJƐZV6 ,u:! d#K-@K?߷SzCAIENDB`Ext/Icons_15_VA/KeePass_Square_Yellow/KeePass_Square_Yellow_256.png0000664000000000000000000002303412567604632024017 0ustar rootrootPNG  IHDR\rfbKGD pHYs55H@ IDATxy|߳C"$`8Dr*UZJO-Z"jUPDAD9Cr'{|lr>k^d3y{iXW@sH:(rǀ"Uf/^еda@i[")) Uo{(V xo$A$ @20\h1/D$ x 4n&U"D/GbwOډDu =\,28P!Dcܽ*JCb3@u|>pUvxr"!jxeUFr9fUˤD"pcUhm0dEphFzu0_¦V*#=+KD$ - Ѐ'|"Q7X[y F-)vm[sZƤ6J%%9䤪O S%VO-s(ST][U@˨!2*2SKPƬgpjꩇUVVNIi%e-fClݑ˾#(d   (M8?_^t ௭? $2}O:{TeT XFPߩk;#0eu*nGC6UC`os5W _HLg`9;vbNӗ_,dl{3ŧ1S+Qmme>]i<@/`}(@uuC]țOEf/ :_hXRŰ 6k9N}Ͽ֨/HNJ`UIz | ϔE퀭`<&2on$''s^\fޢuz+fu@=G1a^ƍtLPӱ}we0@( 46 Zlsާ뙝~>7o/<豪p/!w zZsf# }ՂٯG @:pGC@2?))?y ~k.\>o}Ҳ #A jl>r0H].xM Exq: w/ BU`Gnw/ A<1.߮6:x=A+ x>}) WyT^(€'㌂?y3~e_u C)̰]4qox#3/ :y4}z#ÀO6mҭK +/~uE=dFn?nq֤D>W_ {i$ M\ 1O o0teQ`H^KkԈmWѤq/ _c%d2%Y 'q/ Op+MғFxg5,s7Efo=/9;k?kp8(PY馰x4FǑ4NoNi&38] h! H!H!=.}̈.n)G~˖nVȚuٺmn/t:zxu/矝NN2q.ZӫGg<{E6hM#hִӋn x,Z1C|r//Áx)ˉϧ|5J⁽dHo M~ϲ5>%zvڐqla2hWoX p8A@wƑ3~$'' &_=/3S} Yn-E+|`)ζ}:P}Koe;!k aqhW/S}5'kgX|!U7JgokO..3o`rxi׺9D|K727e驦hJf7eQA𗕕ƌ9mo#7b~St(GZ=@PK_7J7OA/r|ULFq0Noͦ-;KO4r!/>6xP_'_.Zɹa_^&>f|>E"&?6}߮C tm\׷";gĘ>zg_W{=}y^OUB^pL4:u  Wޡ[Q|BZ^vôG3N훡is0զM+oZ!Q#,]֬mVF>gKetBd4dK,?2,]C!7|ְ@bfz_2 ¯Ptl,tj z}<\9n /:Un2/߳zxЦiIP 6NO(SXX̨j47?a|$ 𐖚~ %5E௧CG:['d|j3?A)Rouٹ{?5[펺!V#;g?C};,R9 vIox9x̺;ZD8̪72__PG7+*`mIe\A΃2dĘTTToxr룼5Ma?upxy u%e19/|Ae\ySD NEB.NH/L@b?i1e+1f";wtrr8Wع7nv\{sݐm_4\Nnxzt:hEfFSRSII(()-Rru>n{XS啸\N^LUxݸ//=y[-2wXzCC)E>g3t`ON]p9 ۟|wsbxYo[%kYzE~[2rxsb;rS4-Źp=doɸ12lw/zuo.Α8TKy|~[+4޵-hn1 yE%?.MӸdH3߼'6ڞOf&LJ~E!=48WDRq{iU;ĒۯcLvG$rn V-M^=:±]Ws$W_ 4 =#OG 0WfG$i]:aym$lٵS^a" >xYp8?k3fպ1Xͯ rSp:s$&cX6ej]zיs#1!>]Nƽ)UDFƐW!wX" cV,e&v߽. `'Sj+!cL ?c}%KyzNs 6:m9%?+;,IA l 2~I@??8Y'w2I$'G?%<84MC Sjg?y@X~e(w_vw84\.'oL{;_PC*5vep:aɡx<^>j֠~$m?J̋or:䣷⺫j]7LG\s~&% hSwY ?=mCS! }H'm ?sS˪/MW -e.ړp8iI@ß{0o;á1嶇wF>`ߏ{TЦ f7Nu9t1s-8SX 7 <b~}n^'rs8?b ~^F)xh٩rm D<{ r$fId4ks*25g0}yX&{ dG0MuM].'r-WA>WPK8W0W{0(/..ዯŹxF)毣q?nPVVa_1 @?(>#eQ ~Uwnل?K&vU6`KL}x!9,X+^߬4p:7a4I wrRw2ӌex}W_= ~GKM{ %%&뛇_G_JbBiϿwD1^bɲL[21(5I௣LZjF4G dm_o`d`uI=ƎXoI!cmQZߑH~|,_xi)5=e ݹұ})}JrmN='7~c<r)6)w:<;,.`[c2=6ӒOKG EvcMIF)7m'ޤ`zZ l/pJ)҆RqN6f^[gHssi1. fozP ~37y$`]9*d(_o8f_cr a_xl~=KsC_j54ll xg;2xvQJxPQ&>ޠHno'6olv7ad}UV)-'oߞlP7Zh܀7u*^J*k9eN?-&[ZĤŧ=YrG^7( M~v w~? [qg _߸y'7 =!QI]G0Q*Jyy^2~I@ ٚHʎmE#$u~XY~+k{EU_LXN b X~KMXWH$Efl~ oo9eg Ĭ1Ҋl?&Z|b6b5#D?_5 $[9? UHJ+~{a/;)+ߞ+yr#<Ȓn_Y}5X|J/~+LB෼! 4V?{Z+͆_&~CB?t.8-7 yJiV}ڥBu Fq_0(8k[6/Vgsj6^o2s~ԝYߑ&Y|$/ !I@_~I@?/-"TxiIĹ4 - r61bUo_ԳwVe9>@C3Շj/MZkn/G5%- QOӂ[e2oqC HXl1!њF,/6 es d ߪqo\ ^dH^ , $?Vͫ=ihfmj#Y}/>S;VcX u|7C`Z}fkK%:I.u8j.b wt>5ꯇ@˄>Us90ceGA"m x:G7~OF?wUw_P{ ~?[gg _~㒀v?'?0?&$ !_?z!_}]gwjJJˢG( ,߼m "^}U׵ex}JJ,Dɺo2O @QIc~1ťx%Qփ8_$G~PGر/P"`gnI ֜_ (6ؾ(`_J* {8x<@)( Ep!W~D`|=7q!g/ha ?uyznAXF|>%b `=}NJ G"g){E# 2X ~PJX>Y^F*%P8 3g-f/Mߧ/m:l=gؽ/'Xq1Ƞ ++~<zokآ,3?Zb-_~cĭmqd)Mf閁?!>VML옝82+Ux;R*\mHsX f}ψր yc-k~<5}#/v= )(,#? 2 z."g+*.c {+Z'}m_v &s FIDAT8J<#JG~?jTT2j=&#κ |`M ?Vd?_:d5 L~coq 屮zGrwi Nռ#~x^ /o~k>g~ (n5p  3[v;]~_!@-^F}Ӳ8gebg`m m̚~(KO7pSV5@@)X^^^{~qY͏4~j_hp#9ycfMș[ uٲеws `Z>Xr>~=h4_ ?>Z ,8ZN6-x^v.]_#w(L=}4T{y5F_eּՔз3& 1)//?LJI ?hlU]ا3ӟfo1>ZνϬ0QVn@YW׼i<.! 1%yxڏfժΥy>Nx̺’ f[wkӻ{{6I~¿+n܋1 |\j&$q-C-Ci, hQ%~W?NG9p% CMWۖ1zxo:8P# Oi{!sG Px?Z_;`iSwvOtlw:) 6K+fO,[DzG8ZTIuABBj٘vh۲ '@Jr4p#6TW@KcT+ 8`X$YH>ho߳/c#=-pSA8[ڂ( `w.JCx3(8KڈFߏ?/[f2[3} R{K!  (?_R{6Ƒgŋ_tIENDB`Ext/Icons_15_VA/KeePass_Square_Yellow/KeePass_Square_Yellow_64.png0000664000000000000000000000516012567604602023731 0ustar rootrootPNG  IHDR@@iqbKGD pHYsMM_ IDATxݛ{pSUIS @RlBav<( 8 UD]".,2UgVyIy#"BA<҄Is{{ofZL&}{~=; <Tefd Gd녟▢>7'aM~ U).HMM"ک _1EV;&du\OU58]N]@/W `2x9|(1,Jn @!B7k} =~-X=xq8_ٱd !L> W$v3zxKCZ3=ۋ3ث)~@Y@y}K}$&}3aFˏ/55)"'J2~|W奾_i 9z\XԤx&l)a x'{wT3^\åa#>DX+*;x)nGߜLzHkN 5WoPvSg/p8U+x->$xvEa%r ujؑ3sgNuGeV-o4(8}"3_]'kb6a@Ax~Hwe`{ xoƒ٬_k-]iu9Tʪ B ;?lldGs7Q- )>W#/7CQ$ 6n* >0 Sʮ=-C$^fz"K.zKVbB >A#$v]'?4!wf"18?G'\τ/z|*;_2_z^*'k^_Vp`P~Â1 T_s-_0/'$ΗUv}†4y8Wn7cGnի6.wFDAb zAxpRzxf"LOlV+e8;@/B*Ƅl<L`2a ^Hb5Ю'ZxBjTmC7!0$ۉ mjDAADDo;u@LY n\D[KDGG3hKO -61xYX ]/^TĴ} >3 Wx*E]yߺOZd8#PcFLfLM|0ͻ\.n6:[ժI)ΌB!7]6 #Y3&,nE"ݠ*LׄW뽊Y@s˖ƛL11b m_][lԵ=ؤ^sDs!r<$x`FK) ~qfir{R䄩t@}Jv3*U!Da76P]YދN6)2y[Ms *۹όBY~ koD@gȷvǽ'yB}]ZUztm0[f CCp b>l8>א;Ycycv=MWԆ6 =Ԁ 3("պk85 Mx֓Ĕ]Ò3/GIZ /ǫik!ޡ7zetU5olj\JЫlew H$gC~_ۣ [l뚗i 1#t;/lU {Px:^3!&WNh-\St_jeٱ$ۋ3fX߀q{k\{k.^ !pG/ s|/WI VvwiɝZ!| /U_y3Lʚ67l<+Gh4A~ERKd6 p| _:;ms# r=>F ELLTw8\ژ8<Fv>';?'D+ڷ+0U6B e.@'õz'W)9wƦ`q&ԩܙ[gZ=s6O7v"%xN># IENDB`Ext/Icons_15_VA/KeePass_Round/0000775000000000000000000000000013062021652014763 5ustar rootrootExt/Icons_15_VA/KeePass_Round/KeePass_Round_128.png0000664000000000000000000002106112567600246020600 0ustar rootrootPNG  IHDR>abKGD pHYsؽ'_ IDATxy|3{or@ p""-*bEm[,oE녵Z Rp;{<n9<@vzvyn|`' a%}FW X n&-N`<Slm+(p.h8\,JZt/p`kx߂mɭc/g1^o%\R %@x^rѡC)))$$&v@Jj*8R| *+*)//xbX|X?hF T0xI dԩL|%m۵y׽wqI1_E/ӕS7<^;9&+&3{lN:0p- ~kl#{| EQ}Fx6-TOXMl۹̙3=zRW+@U@ U,KH@%,2X,R,;wO  x+R@ 7Ȝ9s A@o@[Ц Qsv$"c*aIA~d|yx. FܪcR,?[O1d"P>?"2'.v$8%\Yٸ{m}st3`^~^Ob/ ~U k_K .6IRe$~oUUy㵅npa4-*puD` pN'N.G~zNs?zME"5Im&Gm:βoG\W=-Y"=3gI"Oв#D6\rw.xYu+>78-Y @.Ν;p"Zԁ(*[0RdZItˆC?|Kl]w$h|tK/?Orr)|!x|j{ y|T ]2mX.Ғn[N3ZtK`dO>{ YMWElټ-()9BEE9~ߏlV6;TǙL{~H {,BV[5 wk?#=h$f;8;ܹs^5+*TzE #|EQrJ<$;wQTx4٤6eЩsw&]5G$ ~2}:q:$cxsQ !2̱OrLAGA}>/4K^{}{wSQQȕ;97.4 V/"Ḵfх^]?@ `VIhNz9k[~k…Lz)*c1ZVC}ī>7p'$ӥ)/T8p$@GжkXCQ{ʩtދ6 ,Y>nJ xذY$~iLj_PA]W N7^hݬ*PZ|֭fVpڐq\I1Wkte*% R-X-kWUm8=Zt @?L^xfͺ ^EAW~[gLa|^^gͪi.Nc<>"mج>SN,ojl`QX ,:pә;A7_PA-w?>|/凉JEy)G ?}Xp%ݐ(-)o*࿱ bGѲ[M޽U6=w o,~"x= :>fP`!$CF9?l-}Ǡeqc8 #ˡ[n,] e7_ﻃ7_)fQQVRĩ~*`_B% Igy.:%S`W< ,Ҍ|˖O.]8_ _$3Ho۞ddf.# V^Oq~{wagpC֌ dٰۤy՗PUH+03f= Wn-3nb>#0jF>̬\@u_EW_|aޝ:'{-"ǀ q=vHa׏#PQ%( 3ʸl~١[%%-#&~ჼ0]*fAOL&Ifin0G@5F%] ^2 򤦦|r < ?;\u˕)78\ 1vc.fOSR\b.G(.πP*Ӭga+/؂J { MGeԨQ@|<|S+eQ=Դv\~4s$$ipTϝY[UŞۢ%GwX۴P$'$'XW ;DV}QENB> MVN?t ?5S]rlzL~v - !1)-TE*gߞ{e/Rigf:իVnx,cT.Aq#$Y'u\T!#lݲy&%L.&o0HLJN{vmf_ r SK 5,sǫ) #,2vLv7xahYLd{ ~s+"ItpGN7VQq9eR-a8M5Kcia0Df1{l]Z&O|WVV}ۖ޴]z{htٝzDU?z?tw?yxIf:nTs [sn3үrrrts} Y+ȏS厹X&/X,v&~܉m"֯}V ^\sȵ WO݈/и2ebmDQY)ct|;wҏϋ[ehYF/.Utg!b.]h* pQw T@4l\aGa:pZfWj1,+;i4xۓ$a%j%x!'brrj0|ʖW$尴̬ڱ]7BF[JU'2YY%o~hq֨ 2CuLJ}N`#Pְ))iۓBw"/x}ckf$I U5 ~AҚ q @bRzc @@掠8d{SC%/sbx}oͨX઻Lwu-I:vRR*>: Y,DL> *:'R})$lEV\;z^e--VMT>,TUUgOVYk|&L!; 41Y}jOt(M|Ѳ&S i3TmfU)c2\^O6*Oob_pT~_HOM` l6mP yA,&K< i0ص3Ϭ ?Z-@):#nݬMs;Lst03Dv3rev'p2'立@ދL |0MaPJ=!a :n7p8j\T=3:yc_hfKۄ} GȐجJYa#FNJr\}( {_` ݷ_: Z٧ >2MpJ߬/n>GQL㒈odK>\YF5V]]mWn \ctW\GB yUUiMo*;o*e Հ\ev/k @k/|TVV)8Y"-ǥo$ >R_*;ǎԀ67 .<]w\H'|ݦ$Y7)TC u?[azj5x˺nEjGQh|S{'n{obvӠmVV|Åa$AJ`mLNt/..bgݶ\OhKvos]Պkr ߔG}@]lFM30T^`Wu)3ɤ$Z(,Q?!)ާ1GDy" 7*'OfN?kFu 5u_8={{ؽZC άp3Ԝ/8x `vo/>#3'!3M\~`Gy( @SFRVM_cӅZVڦbֵGX\Vj@6y7}ҿM}E׭8%=0& ~Y mau۽g.UQn_lݡ( <3a}^[&#ʾ@Lo{s"2&BqO?h`i]z]@3 ,\]GL+[ω]brH;$A|٭t6d~{HZ%r[c/)Z?,` SU(JDHpR ENom#·e~5.ho* yfu NYg#n/>82=slO~B 9|L:3$YWzu3ll]fMk׳𢉴mQ BǶVv ·ٜw0]ejE2"u04O,vS\нƒH^fDǺI\p%z;K1\K so*JХxUoe C5v4+9%[qBڧg癱)D[8 !` :úJ/>%55/`JdqD#NxSSHI ῱9yH^?[MCVzWucDL?d'WdhxusSك| F[|HŹ|۴mAuwƔ$ +&q$Fp#KY,I=*   6!z<=6;-ө%*i )v_?x#>-p:SUÅ3vf"l66\2( .3~KF'vHUEo#ҳ_tUCJħEosOCRZF}~>UON}A%JK׳zHk@CKrfegԿ_aCuP¦T}Jڢ'8%uw0pNυgt*|DK^#&?~7f,!f*Pm}R௽m—-ڿrȲ5UUy<ͦqY<X4>'_| 1_/(8砟=+a #Jn,Y6o[v,~N<hLq@#L:f#Yٝ" {*(jjLGl!=BFVN \-ػg% 8EKk@P)\V \En=zz+^M|~x5peV l C&)A6`тx}ѳf+w-k+0XP9D.wҳWz7=ODXO۶n?z?Xɕ[=ڄcIBe4pr,'yN~u--~i>d\,vIDAT\&K~2QO9 F.61gIS9cٸ\f_UY}{oWV5f8 TZzyV3bȱ 4٨%-jJZoׯo[_ T#rMڽ7]K^vAVv,_U vcG;eV6nXSDq" @Bg?7de琒NJJm Ġ;#E)d_A~Cl36펇r*T5z,o*Z2mktfE5A[+X ݏ`E.ڊq->mTsC~=L8Lh}6tfZ␕*/hC26!'TYP@>ڐhc!voS]IENDB`Ext/Icons_15_VA/KeePass_Round/KeePass_Round_48.png0000664000000000000000000000627512567600156020533 0ustar rootrootPNG  IHDR00WbKGD pHYsl ]IDAThŚ{tT?L&$BH3$^! ^ ڪȅ>kUk]ޮzjջ\UB[Eu`xA^L2o?朓dBgΜ3}w~|K &@dXF(p | qr{uڌ< ŨQe0`@>AN5a؏A`9+z@K[,++_bmP8*v%6%6%oߞ|ZJK:Hx^j# Ð3o7I$%@[T-Q9Ʀ46G%*-A%@켩%*k}"7M0\qL6e!+++YL8 !8 k(AuAb5a6!޶~ݻvmn,YK/La D@oՄB{:9xPgeb_Pywr\ ֋/dggr\s5ƃmB8"q@;@ڱ=wp)@vv.#'R2c(%LFS hnn< p! \F#BM'V#e97JEnv{qbN%apa=`{;p@YVo(}G}V;?p`/?{vnWaԘ+0&f/vTwq^ia-Ym΢vdds|Ԓ1ʗ QXb[̎W`@YYWNq9A勊z^i!-CG9N%$5 SQ<o+T̙36v-xɒd=xZ/Kp!?ٶ$ h4m7-,4hɅWS;x vD`7GkM $++#,v%f|+%$h8@1c VV ˨QeaW\.7L}hǎԴLi.W_ iQR)P4Dp{ij:XdsA 8V-%yw޴,u=5}IO3wW,1Sr7J]RUsot;s-mT7;eiWZv~i {I7plL/ xOkR¸kef;H]ty;/(?L.c:"G`=aDu fD;;@UHr'î^Kcb3 4x<1`ũ9_De-xo{4iY *wgz4#eĸ$4dm&ӊBRi :9xf;dT8zw[%ڴ*LEJA((]+-|k=T\9 bO4,3V29{OǙN YWJU쐭!h}of]_A?߻#[בQ/u2+іθ89rO;4ߍݻ@o+P>fXn cU'ة#{طkC0nm XЃeüiw8e7VX]6HI{oӀ։6t=- !;D{g=S ~ v'LTŹ/]N/Ǧ 1J:Oo#xVZ ʢ+_^x`}(.s[- fW ,~o'_dz*2L2RMζnʲ'ط.уN &i…d9pTO tS\x6NdX'ˁG_7mc+)*Lq[)BABmB%" j)Fqvle5-̸+"~n&bhCSp{xӺpn_uty|ov%؉šw?yGoHꡒ:=acGr`/<͋/Cm?ou ߹ %V0 3a7XhiZcx[(#g;ղϲqg;p受lmQ<[g3)3t9sl}{q >?/@ Zɹ;[FFF2 rr˰>5pIg|i> pzIENDB`Ext/Icons_15_VA/KeePass_Round/KeePass_Round_512.png0000664000000000000000000011007512567600304020574 0ustar rootrootPNG  IHDRxbKGD pHYsKKs< IDATxw|TUwf{Z^B"(]W~w]uWk/Z R-^ e=? L2Ν^̄s9S!8 <2Z3 9+\[-/?PxJ*\^;xO'W4HUmv@@ayG,jg`9xKL@$@$jr(9O5:\@$ptc1E+j=DD*1.2_^WZD""QD D/; u !DD!)C@4KLjm X|f$}06DN<~*"QQRrXG@4H70>a@4URi"Ql)1)Ep> w@$HdC''a{Q$U  <ʤIDDS.p"0 _&ce+Vi"jL<iQ@}D" D) 'w/09 @$j\\|I$R\9" D#+p&p2{_<c9DDiQ3Bie`4HQKU7w@4i/ ZВ Jvva(o:W},]#_~/\Ȣ_PQ!U" DuDiU2t(%%!RYw_E ˅,\׭=TaL]-M!@T܁OҍEE?~%%% ]vKo9ƍE_Gs% 8 7܀;=Z0v+F&DJJ1fƌK߾:m_׭]Â3o*+[2?@Q,b=Z]~N31c0 5 t[ÿTWWWd|>=VZђa5J j*X  ?{M<Ӭ]ԯ.k@d_ew56!!ɓO⢋.b1h M%y'y穩nU2" D6dQ>N]v ///@ ڪ(7^'aln+.WQU<LjnKLLdҤɇ z^yEہހ%EGS0sS5J9\233# \+*yis<ȃ[@b D) ;FҎfqWrgrL_okKu>!w7_0ҊV 'Nd֕3f@ <胼ʋ&ZlKqc2 L~:ڭ@ Zn ?>UG0v+=Ƭۑ^|.2X~}={*y{ٶuKsW_zdO DMi@v,W"77뮻Y$))" mkܼ4cX[Õ" Da*csc̚5t 2+ЕB_ו_\: 2.~JG`V+8*V@4p:CáQ/HUعsGgYA D!+#V+e]M7tR>+>=R(?u ǫ:_jS<0eWy4G 0pӡ2N';54ͬߺy*+ԓK߯ƁT:i$'h$'j$':HZ6Jۯƍc1V<)(%)c,X*tRRf]-BZZZN,ᯔq*^ VRh85qv𯭪*|!q]TV܊KjA][X*IyرcxN,<>"Reu4HHOv 1!|w -[6qSπ$!7&Իwo|!JJJw~1]ǫs" Rt8.Υ 5Fb՗_pX|i,$A5rJXU,611?<̳5;U5}:nJ7GwƣؽWggqC2ڶkϹ_Hrr2_}/&Vݥc! Cz. 6l?݂5#{k^]!ovwjF@fdG]_W֮暫.ĊLtgXh댌 n~ =^EUx^:  F@iNW9 >N 9+239sXT̗ ?sC\Ģcti^&Mm۶5T~ [:W8FvL7`g׭ÍWۯNJ}ct EXQ6f>#^֭[sws9tn5nǧ!pu?p8Mwv|Xm͛>7\{[l8%hd | {A/`o6i끻`_G/s}=р5nx !WwNHJlmj2.VXfgI@t n~ms=z훖}j*Z&@H/JbG}5:q -#AϙgOe>5X.(up] SO=ĉ]VW=5 Bo)ڷ#%I5j·rUPk]]c' $J7kϫ~+׍}g Hqоu)֭3ۯp-OAS(g.W_%;;;&끮#7[e~*ktĻ4[ --if_^NT%Y+p c=ƭފlJQH܃_߼Fe>܊D8Ef1)**fvt$`*Incڵkǫƀ"}f_WR&@H/?Q /EV#QO.[#w֯5h1wcƏܹܹTu% k6)Ғ7`'jʹig|O[k˥#7K6luixM55v2]7 D"] oɰalQ Ã޽,}>|5}>Ӣ/x qǟʰQHNN%'81dmἳk;*`([xI!Rv1oGtv?9 gWOFmҞ/DωǠq8_ۛwhCDA/L?u[6o}+^-90kuؑy>Vuv+~8ؾm3"/=[6o@F/XnkO:SgҺ?281ݴq=ӧgE,I>ݺuc޼(,,>c2舿b>d&@Şr8\2ig#!E-Ԏ8 ZNfm%h!.ӧ~8<_)#ǫqN|`=w~DW.8Y? 3NBtmh?]vpi'|ُv1-\#,@3(`.տ>Crrrlr+vʋOǶ(u;N?j&rʜ82QP{*9|Wv1+/p"0_B 1b.iiiۣp{UNM彷_M VmvLz!q \' uUUUg~l Jc{;f„xHJJu5uz9~N6oZ/Å]X9̸@EnsJ$dY:$h>JX19)̞=ȎB4~ضW|wzVԹko.z)4zuN$5I*n\ts>x.Pq_l!1` 2v8^{5lOQ/67]-ڹ]HkSng{ϳ~JvGJZ]~5RQRt:9q),[kjSj I)))wߵMM`Zˆf/ acD׮79= ' Ooq-%ZiC1]A1w<[LS*u_ߐC_+n2~e5աSwa3P@2,N !.􁑀mUUUr|B;O 0NSNՋ?QXW;}{[y%Osqr'v _gS|GB>]IKvD AS)X-n706 F>Uu҅O>VZE>1ޯ+}ݷ dv3U낎pSt5X_OFtF Aԓ+`:ses= qq1 |B6m=wr SQѢ7kڷ}МZߣl+HuD )L8$|66N _oDnm۶O>(w{n6o\uW-B uџo7Ck];Dsm޴'fS'*`:6oh"??O?[V>Cx{x "@%%r-Q2=eiWq<Gt~ᔉ#)+0^`0lf7!@MaTJR{lTT3[]]#$ly=,\&>}zZO~qM?@vVCKF48࿀G{I`t4 p8={6EvaOqKi B@\IJ$]%B|QQ#7E+ u;w@)MsZ4o.i.=Ì3] /+8{XV,A':H;m`zp^p IDAT'ogh3s|wpZIեkoX, j $E^xwuWT늪rf;]$~UsgSܥ7m tR''I3A%%Q3 XFM&s=❿x\}9TWW D_'3;]k}R??Q?_i* #%hnfF}'111z宿 YD_J/pLZu@`k5f܉,x;wDGP ,U[eE@| PXXȢE_ҶmۨWT ])~M<B4Qu┋i-JURm[|0lM0KEJbƌә?c:ꨨwdвuY&5Ⱦ;hqJR?z3ưxע{`2 .X '&&sܹsTl+?O<}B'%uw>z)}ne,p |tWE<K%whO %_ǽS?"Y?-"=# k[wtY[Sضs>x;1 x#GУ@IN~Wp-DJQ) W_AD-T?~?ub-ul{ {݋;ӏeQKvXHtq:x`,}"˖pTU|Q3TRr*?{ `X$R4eԱ|͢h45 IG|b ,RPY#[wܶ9vl*E]ٹ[ sDa&wdD Amٲ lWLc;-@ڨ4[o1idTU+9qs$&3o.AA"ڶ/MaGt /3IO">!(];mznYǦ ٲy-JTW]z }/>'О8ejޜwy4ǀ$_/!;5z { YҥK8xQۯD9}Ł)1'{,X/?JN8k~i1 O`Ԙ8 3`Ӎkw_A,S>|}^vr#$^`щG!U@`;hxȑ̟q7RTV+t%{n ^~)Z ~eL;23s"ÿ픗2gyصsKM'e#(=k ,bA54べ8qVV/}jt?].fzpΌkw4\{_ӏ^gݚ4} FK:tyIj-ݏݻKe8kF/ӦM5 _ ;1y|?vGoб ^~ c&v¿\O>~矺~kmzF.w?%zrR+MP̜-X & Fh fp7[O_nf˗-ip}.==[tt4\Hv^~^fUھ#9Fle8K76nXNJ?E,r%P!(lӺuk-[NVVaorg4;(\q~̸}uܷOw^}~k $o H8K=ыۢReƮۥЃhgO߯#?3ܻKgLrf.zz'C||? Ð(mfW.]q#..Q_O)=x 3HAA;hD'1H4z#&Nn)uUn}C}Wן7'k; /C~ ef3n$&躿Y5WNAAWcp:4? ڃdut D5s>Z}t-[NaaeWH+[Yn6[v܃4߈˚ߖrgqݪfaSܭ?WbH$Kp`Ik1c'oX/NWJNuaKiؽk Ѿ1꾫O~D٫/XaO4*Mp1`OHHӽ{wQ~CuQGsǶvymC>O.ub b|}{ 9%Q)\j_0x%$Vogʔ)~_?p'-νs<:v* ۆaM>bΘ8N!o^Ըy.KR:_.4fx|kz{믿!..2{}%?LKwd܈nTUY>phlRkmUt&?-4fm%1)'2r)ci*tzx ~^<fq Xh/2EEE_(x&r^&)9Eo"2Tʚ~b1i/dGG-?LӾxf:N'ݏū/= <X_# ȷ~Ç `,SJ2ؾ?3~*w?0D*.>:#OYޓTm5(|0qJ4L"/ Ь{r,SRRo/?|V|oakp?'n26o5ly0eQ840r~oܓHKcbe3cRpÍt2u#?RwΫ\2N%w^8LL's|Gj"ZCiq~MA[f\|e4L"Z[ݢ\q>9~[8W7E9;zjޓD c.7u?n|֍j&fq5eɬ wMJJ%FF׿_ɉUUU OƜnS؁<:(?x\Bb72yŜ=-x߸U#\'U~VSRR;aX8 -9x`8LˌF5%s.)g?}V?oVvknUScʦ)/4c߿b}~u/UVk~#i4U5r:_Ē4M;fo_ԃox$ܷAzw8]^QC}EN {,`E\au {y 82{<щ}<65ͼƞ,)<_Sc.0>Vutէ NrF4*,+ˁL+[.99;2:xCK5ؾC? mqgμG)l޳#?~PYLP7.6,=b:H+㠈+(,,H CΝb1eNny䴘C#_)߮mryG,57fHMM뮳 Sீ7^}6 6x? ;c:0s?b>/>-?ڲ>WDJe`jZB3'?KuWo n' J)^噘qGMd31Π1co/J)e~U _μW@Vv.iTAb5eeKeddp5X] C?O?|kbsmc?ϼYcXbkp06[a{-O-;gk / \7TwO#wJPX믷 ^,˘?WLƪ/#&llf?2oc.HK`%0i5@pe]n X' 1ဇ ;CF =`, n[-&oJ7J7A͸p9VV\[27|3iiiOOi\263P2Ʉ0\QFHNNK,/Ct\denݚK.끙nl`ÏH !:uK'wlY͎ka^'?ڣLh\`mi@-rWd:jDOĝ׌Ko7S}cLa^'OM?@bR2fLsplJ0|\;~GҭG3?@.}ֳllsl23 99jӈ0@$^P+[ fcIN7js;3ϛ%oSo{{ygx50<~on͔α4F1ppWZ]W=J&=j[;¶E 1A>&׺mfoKa?5[Tmdr̋pXmggY2ΝM?Y'K_dɧCs[_ Ä?9Z?Zc::uf6󁈌=D*84I^k ڿ?<+[;YŤߏw6Nֶz0m>v .%m̰d!l])~y0d,9y-()>l|s`1?>}Ym% XZotקo꟭Ιƌ?U|=xT[f2oU`v?\my :!y "N|W \6.>' [  +.6aF/o0Shߡaj,]qUWt:M7?uHMM@$%gУ[ +?^vM?w3-_^;ٔ/hjpƪ&%%q١?R T_V-s2|?=w~`ٟ$5uڹ$%%[ih6m:YYY_^7̿ڼ`p8 ?@O+MLi}HK`‰S6&1)@` /tTοe.]Ǝ[lX۶/m_t"uGiy-+t`ZjY36S0XLen2ș ]O7kWl;}K-t=zmu_6zM?A|T7+#]t1 7Ie޼ijc cmtcuŪ ^Sij9 mU9묳MRyv$z X/o/W)Sp󈏷ty %hS3ݿ_ #Qf;$%о_@]HHL(o"QPYk*s Fnl0n_PG lo@Q84_o4 uڱ^DktWawY36jթS'Fe:^+ீ[7֡v|_8mRgv(>̀#1MMB?@W).CPE/? h]xmrO?unSiN?J3q'YjUG" ]er:6#UkuU~W!?eUi~r- 9eɳKJQXXh*n*Pr,PAaGsj_?B~N? 6m9mYnp6m[ }{sltԉNL3;o)Vp0eT o22:RAzF_$eim2\UƝ>SᏂ'MԮšN0ψ#iӦp{Bqjp.}uiih_ ڭJa?WdH ? } T&X` Mt \̈́ǧ?ŮJ =.5-۶v#6mQYLP'Nt nF`Yj#ɔ)SM?*p/(q{lHSzq6@Z?+yT0TN2ьDJq75n]ao/{\+vy&U<& /5\Bj lLfU #W\__o8^?JmW#2 :!5`Z'2Tx|3oܭN__t?~n, NdBbv8J}q1F.7 Е IDAT]d [ܚސ7j r4xC J=qD Е ǂ7 c &7Ϲ=;C H?6j VHBXJ0HO0 p{¿^ 4~.pܚ>S0VZL !J`Y磎sgSԁ/l?V? 7ެA̓?(:uJEVm`„L?ׯj_o4MoS;?# iUiǏo*n% g!}~:=uWD#FY2 DF i*w -W^t7lV/~] -9xN98PK4r(M?קPJߢB_ @o"q4VZΈ#* L?(<^]/ 뭃/w5 A ej ҁ' #[va@ ʰp~.l {Is8˗ ,¨c":w>T _֓ROسdse{sr\Q4<o'ywi}sxܰ?fr [VM?zowK?n߳a73k ,x80,ѐ!CMR _/o6aMou/\oJA I}k4r/  # ]>Ю}Xe>@pAVlS(_/?cINIʂz~FCAq\8h6ߚ )UX (Z3 N^,[lDC #[}aNJ 9HNk[vL.c _ ra s^J4=Vp0p xr/ CF15Mq?8'd.iW@q8V'F U\ܙt* .l[v:l 0陴m*#Uub ɊTx Hv-oڭUV t8\pU%9cL$ǀjL;wK#Kc4/g/__/'@/𷯩j-DK4a=M?_9om+#i)E?HIIc"o(.l?os caоc1I)Q@W+Jгg>D^?/VЪi(`WnXVYRwj-)t={ Wh_ر1_ JA>?> ӱ-^ PX_٪W0?k]- =i7K'vr4|;\?Ȅ?ܮ i҉VCF/ øca/,PV2 P'?=#f.M{ !3+'=;t4`$ C  lx5?b;*t|QضC ($Xd*u]_:sdŸuW@uN[MϹ@gбi75? i̶ @N0D99v_/ᯀ}54VX0 iuDͿ4?|PSlK<4"_$\e?tm23- 2@u@iA$ ۿݺiGACYǓj*܄+H$Vj2 i\qdXq윐73 "($*WaQ_NFe @*FՕGD-$hk?0 `ߖgZeYd@*FH$2  ڭt"`HLGh G2}Q{lUlK6ƅbst $H@ %PC `L76$wiݝhٖ]i{=Ҕ3{>9#4ϺD"e?7B(S(`XRfVe^ D"cZƦpl7T,[q%D΁f##:Ҕx=^( $Ng> G?j tukeDa9tUBK>2 /H:Ls0 ?O%%=@/HSpذ P[eYn|%/o`:#V*[Y=q /K$X:W?6 6,@wT.P4On/UD"  B!7UVV>2=_"DӅ O+O+D.]_jD?yU\nU&0_H$w@RH$_W,T,:Cn/K$9Y(Ru(͖_%Itz3`0 *+eG _H$Ut2 #-{ _H$Q#w PHY% m/n/Hyw VUD.X{.}4M#-=F@$Ȇ(wY o.M VpM*l_Cq柞{wF>\v[a:qtᘋe [1knD]s c[?@SSQUXk !_ܚewJʍ u @_㌿o @k@?gV hjTWd5 Rgc@O F(YZuMeC/ +:]R@%UWX'g_+74fU z7PbIee_kUb 0V*+T2@_O3_9~uTR6PQQag'޻hFLMiQXn1:Ӻ~O,\ue:gp/w$3+~}n./ndٔ>oW>/SBqk]eA{---֒w#t B߅3`K _}6Ib$=#nzܑgTnFrhpXbߜ*B!eTv 2[X Kb%sQN|0\aP**-"oit ܙ;DO&~ T-uT@YeC/ V?ω%8oCKv)+*ʻpFc]{, /〿adiPU(U,,#4qk`)$asG>'LeTV(+B@%pƾc.Ms_O @,2MT"[Sb۷oʎu_%яoeT.0u7KOZX?[T%m "%-i捀$`/}%2x4W\-+YbQ!MMMۭ pI%1K$G?f,?HyY`0}#f ^#q#G?@n2#gv[-k?\_OI- vزee#/T Kk7Gb+bpV%elݺ2<MSo$@=ݖ:P4();ZGҁ /wy #5@u`%oٲ2 PL(q GmL}`ر]o߫)6[Q/ /SB; g1AVP b_ 9dwWVS]U-6ZU+-nvdЭ_$?(u[?ߩ<6Z\2 ZocХㄿJqQo{G#֭[`U'@wzu4_Mu z,`ú*K[FG? vk K- ,,Vj:`g{@Xb V^I8H^MCWKuͽ{-? 5Z~uۥ婯gMh/ [}s ?ijlP{oK{^7h[#r8%ֱ#s22֫Y{54MSlFx]~ܖoT6S ,@ nDS;x~sF6@"Y/|-y'ٜ/7:̧:,BrdX? :K?ɏӾyPoT|ŗvf05 ,ZɓOH Gϟ{upw~Ξ4:v/m0bۆ(!o_?R܎0̋o$ܕ)08n~~ E(]`{Y_OVeQ]W{<--:\n&yZa:w\11,{]Ԣ=朅?ןǟe{]?`.cnߺm"_Y.25Xd{:,?t&[r& E(GO1:} `y* e+k蛅Ak/ jRVX fyʯ (+ hH_cX?UUXj̟g`_?~.'Co `9_~n@,W{BG͵t]_X?>]j *,0p%dh _ƿƆQ|_7'n~Nrz At~N5X)-)V> ,&+)M 8kӨo2P_˵.}~>]wf|`ܯ`Ŗ:M!e46I uW K]p nÈ^KXx&𒾾?Uݧ~l)YiهBp/# m[?9l9])Akuf6lXg>ۭ PHLq$'&Y:YVQT]UkR|<2ݣWНt$ Fis])Rdg /汓c^K*[y;;+,]& /ǎ}:z,ſ^*❦&ze:dg IႿD'>8؃ۥY?P!`^w [Uk'Y$ɇB`f$N(θa>Kv $@].>Qfʹ0vi/ V/Sb?`yjnG[6obӦ-@ ;K_ `yoڸ7'\0hTƟR f4sKC%l07g)sf+}^k~fw>9-[8/Q0~!tZ++Xhh eK0ޱ k _+7k)fI(TQ]oX ({Y?Oxݚ/go ދ e g7Y|j|=]=u_F3%]-S}hlމ?:BۖI_ K/S~Ks? lި J2ihd낿Ir6'KhQdgʇk᩽X lyPX2#q ' q_:pR xrv*#ي]U[w_ 0_qk$r_geٿMYc-fR]t7ߞf)`N #%K- 9's0qMY3Rٲx^@0[,Z;[$:Z/v炿$^c i0ar wneՊ*@YIyW-l{3/L{{gz?fR=-?myn_" 0ir0ӧIx.`ڲe_95߫,tIӡ q1zR[U6@`-{g,@3 O%7b 0ฃ;E󪛲K txuAٱ" IDATIoee7n&K_O234rfʦlu(E@ͼ-@ӡ %K./~~\nRf"!PxU3>+ υt܉ׁ;9'sƤqiΛVݤ7з' [a:.Ǥ# ȁ3EIU(; ݣ?}V'7qqFL^]sFHڿXd¯ٴq.x߬usҋ/'zNZ)1R P8d6]$m0qF-FT~o}O4vOe3x4gKu`~ '4\\|NOȻ+*NkiiYn^QO<`06Y:/ *?A^X(ⵗ=ݖV]ߪxYp{lXR#a`@_wdf:L[6.^;+8p=ݟ[ a|1x1KHuQZJZC}b1tv1:\sEtau߶F{L}ѭݺDF':RCt4X9!C랤&w U7_Ǫ 4VLϞ,?@ˈ^%V b5lUrTWWX$Cz4_"vsqQJxهTbe=LeetjRH$ V$#WK Ucv4e7XYVK5<ȃ{nSE;xghxN]F<(m;%u $D8}RT7M QQƫ,?r#CV.K$"9r_-[Ȭh˯96AJmo]V0#_Dw0q቙h0{p^<.K nP>NFcߨvi,矼cGs`Ívu+5#K$?;>cQToii?ʮ&sΜ/pꅮZGq#uѻN_Dw q2}olܰڎ&2װ]@3g;a5Jd 7~lHR p*=]}\Rl^O?`Wk RxNy_݀aJpc# Dot .>% Gz[ۅao9]@َϟ5//%G3DZK 2#q껦i-gWsja_3X]wNa%G>n r݂D"qH3;DZ)ſ]-0C@waklQ[[í\!=M%ߚ\SO}T/}8؄ُ"xpi 5g/D"ۀϣqZTji|{vw!dz}py/KB,p MLN݈eh~~mD+|>Rٵeİy_`t[G#J:Q-նcLj}cO-.k\vZnx_W[ygBiIFcΉ#@kg!/J}YeGaG3[ h`Fw :gX{^k{hˈu/{c {'7u{Gltcۣm/g?9;x Tkxom7_t]*^2rhF8V=\TՇi / ).<1qYy;rn!K9vWNN._YʀI`/ J HkJUgNuu9":<` ↟^I0Rx=Fp/ h\qfr0s1.D Sz;o##=#&H / MQ?sOiZp6' j lܯ8qݭ?t߫SR_O:A}_r)ja& Ӱu=D;>d0>L%-l" TO)ҕX%Sbvy p6NH#a̻%c*+R?@ a_>=,?s?˲ p.PDhZ2cX˗0~! 1J碢:DcsX?gdq*]tNE֩"I|ep;޳W>}~(?yih2_.na.i/.ES&Q]e]끃1wdtF'Q@@)niܚ/ ៝s9ٶ7]b'pg_d 08ԎSڻ"#5z( /'~+ץq_}1Ns:Pˁl;? H|\!>" D^kɡoO-<_8g{B ywrDeMemoV7 / Ѹ9 kkW/ʋO$hUD*hݩSZxK)Ufu/ wWA^[𯮪pV;zd5!X(k;wlk/# )WF5_g? q-W؍ pc""Rhv wIJ$#M'+}/ۅE7g ?{ޟ6R):6M h\FèQc߶HiT_mY2>=_? D t` 0ڮXXd/ B]Edrg|՗L}/[4H.׮ӧ3?CIIek†/ .KNbP{qQ\NDDT'q(..ҋΦ \L_-ָl[񯯯מk7KT!1hyqVU+R#IdAݓ /}g06áR.c?`oI>|q-ټy#vqg+L\7EAa_ӹ,{f=@u"@-=p+egp㿻jpS\"4_VOͦ?xΕ%t.C\fС9pxGhᦤ2HsP{ɹ93o$|/h4p_2<c\ ϛ?#R۴4,ZDYuHK3rlyo,[2]u&YK༌9vDx >#6`;JZ_ca>Nr%'Q]Ua/Uᘗ":ɕ|WfEyw*[n ]F=+ 5njOSlǿp;_s7 H{f|<жw8)d*ǿmzHW8_a tX:yc%% )ڹ x"ٰLKmG6>N{E- `U/ <Ũި:+(NfƵNGBR$NzqHƌ[3>%7mG[M}+hh /sՙښ* ֬ZGb_F& 0 E2aGdffن$AE( SLlǿ/u#M/KʸHۀ^,57k`k`oUA_SM3o,|^45ruSXxS@&{зuηsrm??En>?yy4.:9I~oii7]‚9ōǀ&;Py)WdM]3Ϛ7mCV΀^nJ*CZ _\מ }ඛW/7s"H섕9xii6eL^=NJƋ'Nqb3LRT*yNXIG˿_}l[o6jS! kpQ{pCol]_8Ňj̛V Vœ,tLzH*jB,\H]! 㟗s 뎩Q_{-_Z0wMRXKWF7?wᄊ2nC;[_OPc,&Wݴ]u&w: R,8Փ9erz܋o1c!_<S'gҿ[g/?; GMTυ$: p jjjd[1x31tvkV0 ߟ! j5ISɊ;W'ͯn't0S|\BPgcNpZCU]&C_1zY2҇8W8w[Zןh"kB^y)*IOGwlǿm|j/-)cN[[O$RDVw~ t9hjs3k6 Uu]ȱ~N9"m8 WrOP\ix𚐶oBw~#G3|h,}{CSAU]X6gd3ao˟JG=䟒SJ| g:iyiTWUru1ϫ1<5a _;??Ņ'eqdum=P+u3--NF)a%r3W쨣OOB~~oGOg-,_9, slxuN8ϱj>'_UY\}y}Bʟ;qϾ!p$mbv4 5&34}?oͪeƋ)ܹթ}]#@pVB~Ao4ۥѿ^B! ?G|,[3^/y#ϩ'j2CKL{?q0+7Xbvk#u{x7߁9R+ xНr:ƀ Ml. R{9trwq w7]̊oqjl!4I*/y"ѣ?~oB`KaP=vdQ}g@uUSy!I ՙ xL23. ;J _O<5 FCXsMN%غe;'YN]AM7_w\=a7mfVol!טxc>0 ?y:qb =R8%=G??ꋙ)U1%R$D+aeO:Lw@BwaokafjZ_G, l{v#|L:OnVwes|DG_|o3)pމ9EufV6{yp"60ٸME- _p31~!}=hZ7coo[j41_c  s%t먀sGsO0b (qgw6 ?>An1r]b9<7͂ى_6/ R$KN¼/ 7V-ށKxh-mkfACO!}^;Lj\(-?x?H~8RȐ 2 eGGu|wBaA6}W ugea /zp}n͂_qD7cF YH+}gq2h¿ԇR eABaCO@ѡo7y5CߞO"vCw&ʣ}m38("H?Ix\~O;NJAqY-A6Pfư~^F2bW㛒z^|!DnB #) =Vw_n?p%WiDǿTֆY}]sѷ^o3PY&UC 45&bg~˗@o~9Fn"|zz]z57t{GKvqG_푆AYUua o2 FnL9:Y:y. \d8w_]U^'/=H^j0H OF`0.Q7 =#+oܔ<-A05_u! a0hi1lHku}~FfFN}^NNǭ)h¿7^ygDbN#K 2?y#22ʟqM#g8l/Ac)L 6@Pؠ9Z`k۽nw>x<.LZ:&QTſ_~wj++^t)$|d{&Foʫ?kO=™-p`N?njliQ^TI.{<ңg>S/Q ɊeE3|W^|d>|N麥į~}c^?8B~vm 1ZM?yhjlH>)Xqd]9q\u͍sd9Kʋ3B/.I-ڤbΟ4m8n_pΔpr/' p9?'Kԙ0ˍ~RH4{&kn ~#`TWWxعcK?5{K '}'smü^'.Z>$4M|k46&[/%]s!OW2nܐ#⫸`U ÿ?|^z W&k?SyMr8+ɺGv\./ۆ8fт/yghiIWK|8:d읁‹̹_F_;W>E wnMdptRH#9p%Ǝ93~C8hHWN>x˗OWƒ w@tRH/0 :&?!g}^M,g,]UYΜٳxo,Z%po DP)$p p*ݶ8 G;m着 |sf" R_QbI&rt 8LN84 ) y:=E_' }7[H$mNV85+9S8ؓ8b?ojl`|&_|^*ȷ,ƼtRHR#n¼a0er9Ix}Iwh mY0sf1s>9}@a=RHR21xZ ?cO8Î8 }&/ϒo0O(.!&̻A@"Fʮ3aL8h;h4';P(ȖXx˖cɢ)ܹM}>k7ˮH ;'c&xΘq2񰣘p1:ay=ײb7,]2+9Vqa^|$RHpp'0XvG)ݗq'0lā9'0dH\.MKKYr)7fkXr6Mg͘\H !^*- g q GaA[ogY5U|~M藲fշ6=S9d?n$ȕѽd1p z%/a 뀡#JJ[ZU6cݿQ;VjdwH+Y RX>p@3$7=ѣYٹ2*˩ *K(ܹ;Rs %ҸP)C"B7@{r͂ '=wr!=#? Ϸ2x{f;45PGKښjBn_˩,OY~O.KNJzH#< @b[Tw(e)%gc)nȗ|Wܾ6`H$NϱtWJ._յ[jH$ *3/+LCbeJ>p= dwH$d$D%)$I/p.p0YA%K@T(@OJ5:BvD I&5Wc<(ǥ$c`9MAvD \ "Cى6gewHH8:J $Jj?C^+@"Rms1o$HE+ouK$RH$KO̩O\K$6&|[@Sed@L0 x yf_"Dbkr1L=Ȓ]"cjY{ȋx$RH$ 8ut@%.d)~+ͲK$RH$7/wKH$ [ I_9[2UB;紞nHHy֑I#QiV!s}D"Dx6_HOX*ȗJW"@"%ZGƶ dN&ll=_5I|ÁaF~?Lj0kcD%)$$M^k0UZ[ۮ0P (~JD D~\m |w :0'ж{4M{^\|=Ѐ9$_6_m~_ K$QbdR IENDB`Ext/Icons_15_VA/KeePass_Round/KeePass_Round_32.png0000664000000000000000000000402112567600116020503 0ustar rootrootPNG  IHDR szzbKGD pHYs%%B3EIDATXå{pT?$ݐ@@@B"7ȳijZNJ0B@V;6C8@CDL+E#M!/ڽwO%DDfw=wƝ`.0 bw@p8 nɡ ^r|u'WFS}$F (R t]_z5˗6Ma`(0l_`(0Mw'86n-׾T:};E.+~۶m,\=|~oVUW;ZՊ2D= 2oωi wex IMdǎ%-J0/e^lݶ_ܞv yH(AojC]8n GYgh mb(.>ʲr`ęL1FHxDUW/tώb` _xhsc;`p.--YR)~n/S3&WWSھ >)㭜ginYseA͚'lwW,%y`n67p>,{7ZpI:^Hmҷߐ&=a g(wn \pgee1y4Z[%HOSǼ?Pvʜ/Ch 3>c2c3zvhD/^(>4w@t=[pC % 32?)̞st;3w||mp~-xHӝ 7\31{aSu`'1䁴$#G 0Ms!}e^'' `\OKK;ZTz+|-TW, ,KPkK,luTFO\tRB &xrlJT;ۍ]k{wu%$2b7[@LLo^NAįQr ? "Fj 'VYB(7SzLȗ ?4/o>ɒ G)DGh@C}-@(Ɖi! rt м'o+jW~uGDKpC)A`p 10.5C#P@3p 4;J>|̉Ө6n]D{ߡ0ܿ Az'B %843S'Jt[~=`|h0XпReau3E, La|xpaƕ%Yx :\vC7"y.޼7 ?tL/:ɀCe¸:뻁F27ő]<"R ĮB0求 q1ܡt1yLKOa~/0&&dip81-! ^3niFdFO$]Xh,"" lO?HXDXWbA@DDJ@Wo u(HX k,"")Kpz LE$>:`!pk,""@}k>.\Xh@DD 5S}t XDD ""- @CDDJ>:3`F"" )د uHD6fc!h@DDc;8}nH0/(8}h@DDIU/M4&{O|}Q}|WR5aLi$""Zsgp}0 ȀW""Z29/75PO^DDD ""c@#(s`_?h@D$V$ Hž`utA-DT`0HHD$>&a!pT#HrkoWK#)U!0x& "b*F""R!OF""p)HP}DDjJSC]5ZXxIHa-GvxHDD "L݁DDE!0 x X-TX#`pZ kۀwMDDN%}qHD1S5- CD$*>*%h@D$v#0PjBGDDbFkj""1%<}kA-Dp.p0D?ga9%`*HDD ""!nj""R-h@D$j%J""R>>#h"\ qH,^`!"Z k[nu`!"Zc?H8DD$ 8DD "" P CDD"@$!"Z9V@!""肁k4DxZ-H<(DD$ (DD "k}K?XxQD$/*GjTHL/a $'%o320[šn~~n_PXXH^^>܃йH}] "QHJOO'== 32HOXkժEFFqqqڑHjj*qqq>uwnXH^<|>ss9zr9ˡC?/{(Ç?IJߴ "Zh0DL6&33,fgIVV3jؐƍrBqTwrss_~ܵs'ssvI\v?o?D0=_""ZЇ5 oѢ% 6aÆhђ-if8'޴ª]H܃ڹ;wiF6mȮ];ٹs7mb۶|>H"DD "`xF!AVmZUVlيZѸqc6mJVV2?i*Cصk'۶me۶ml޴ ֳq6lXݻ_"~`F!"Zp+a"B曜aиqZjEVoՊVZӪUkRRȊ8w׳qF6nXo/l ؾg,K/JX ,(DD "Rc_?GI fӱcG:vDرNZ%3%Axظa=W dլ]4&5f`!"Zx8Zi-Ziѡ}:vHi׮=Iſb/??kWfjV^5Yj%6mT'ؤqD$wwJ\\m۶CǎtؑnݺӣGO֭{rS+'w0+WXj%׬fwvE,^>n!"Z`K ]@-CrѦM[uNn֭;]q«)7ſ⿺,^ be,_˗/[ED "UFYClzC>}֭;ݻIBBBKQ/}~~Z˗|+]W@iW9@-H ~eF!F]ݻ9vR/f?x"/^7Kf}hHU>-BD "xPj׮=gu6guу6mچJHoY_o-`Ѣi6*RO^-HY?NCʣE 0>}зo?7iRUWGCeϞ,n)_}uڀ }ǀh@D$tҮ]{zÀׯq=9Ƿ~üX^6Nr2G h@#i` "'h۶bۏ ;ſ_w!|b:e@Ng !"Z0xQHqu֥_ 0AΣYfvſRܽ{_-Zy vܡQ5 -H}[G.sE1dEtzGk(L+3oϛŋ(,,FO+}=D$ ;x, 1q\p B~璜\3W+C7 ?y0st>\OsOD؇w(bWǎrE\tE0,ſ?r⿴f*>d:3?%uwضQh@D"W6w`cOrr2;!CpChԨQЂEWGvo^fO>ΜٟwX4تQh@D" _ _>\zCo~$$$t?),,d6m*3}ľ}{q-! om4P^=?0xy\ՙ_/4MkNNbǎƎ8`F! ?Wk;5k֌K/99٫WW+*5kV1uL|]6lIi:DD "&_ǣGj׮Ç0tP8[AW+oe|dNk#W󗟈h@Di}":egg3cWI (Yw~ޝ];^ O XQh@DO{#dddpŗyO\\\AW+r̀)2wؿ6 Pqh@DB5葘aذ$''WS (h>xͼy2C>:G w\_}_Etp8ןѣGs饗V́W+}!OʻL`/,F%,`;@{h@DdPO|7Gr ciٲe _W?3q;l޼QMBD "Ry ?\l\tŌ=ϿYW+5m+^{L`0"5 -HŌ>׿FuѣԩSO_WGct!>1ޝys#b_%BD "rj 4Tn]~1s-:t@P+֬^ń or~}S\7?k"Zҍ^jk[;#Gyſ_WOkuT@: /mHXk8H,\yU7OW+%]wߞ믍'7DϰتQh@$ֿoR5ѡCFco$333AW+#;W^}oF0p7 " Mb"2$$$0b7={E@ (ɯ%_ū)xM*r|\(D +c_Wg̘k[iԨQ_WGow~u^z9v"^)DY7j]7nF&)))AW+c#x<|2c{,]E DNMF^8nF` (IK ӧM[x i"Z{]wѮ] ſ_WyFxe= Yط tk"ZT ExjҤ wy']ſ_/K^axei]' i"Z$~Znͭر7ၠW+x8֮7LCD "pF~uwUW]錂@P+Eɬ?O>ocx F H},"uY{ rQ_W+ԗ|O >9?9 BD "<<.61rN?( ſ_W<'x$~ ރ}zh@F(ƒ`ذ<#m6 AW+޲ek`x IHMxQ<ŕW^_j+ſ__?B@XnÒh@ڤ4 x6mDq (ǘiai>3)ޙ0J+0'59 _+ufZ/#DBLC[i> [@PGSߴ2\~ 3s˴ YuO<-(`Eiih8p8 p:}mo۶>4"n[߄k:J`F!PxH(jN||NAb( 1Ny;C,q>7xݣoo0Qh@uQ۹HKK Θ?۱[A Aſ⿪w   ]qG3O@ؿ{ D jo4jÇӼy)#2M>|۷P_/; $%$%$ q;?x oi^ӀQaB ZSNEٳ'S+;coy^ WW*{ 9 % )A0k[_mbbw<|Teط H9|Lziӆ? ,U}!WWyph %ARèmMq͜Mk'>(D "^Qq^ff&7&\.?Fx3ʎſ?oLHN0HIt8u0B/xxyp!4T?.h@$%bvFQ `Ԩ<ԯ+(3f bM)@w"wO?i_oZi3HN0HMqdt1|n+{ooD l(D "\}FZuᡇ[nq>X(zh*1%0 ! -AZG(#;e=ڹ|BXp.QN\\_'O_Fp5>xLZ ſ|paM =m3yw?اu: s=B_N [8$fN ^}йsS4M<>;*ſ?D.Wwn Nϛ{ Њh@$.(B'++z+v!|~3W+URAZ-{1 1e)?ÉЃ贀8QH)a۵Fa0z5L:_׊ߢG-9R+Q^5<0đO X[,Kw 6@fڏ$YEhtܙ/{?PoZv[_?7ɞe S*k6KݝXfvNBg'p).D $'E%%%oҼysſoQJ*eg^qOU?R&Z8ga\Whܸ sueW zY T`4Q-;x"ϴi6l8Ngh7;=>+1W+} 3AfG9.;n˦\eD  d80 QGѫSL}0iQPG L ~31W+y^#&|(k>4iƨk7+ Xn(H'(e˖?~WV-Đ_WWsON4v *7KfWqXV;CU+`Ӧ y@0[-H$ P/N~$''+CL" }U!ſ_WW幻=&(p[$ $II qII,Z8˪g5 S$*^z[ 8(>hӴo!Cſ_sNGqE 3nh٥y Y"A#$ m*gq]Ae<<ſ_WGhɮ}> -&дYse}۴sWqL3B .&~w7o& $mdĐ_W+C?&{$'F0b41Q9̲hGzfj g*&11_~V[ǿg_hGR )#.V+}_~ 1ٓ途$Gϑ%4Np[e高@::@H`9иqc&M̙gv[$ǿo;_{WEWDTrA^_=cζ[Wq$t˟5):߿m۶  sſ_W}y|#I'1@_G~,rF\+ufVLȿ(D ~_*`yHKKSrRnW+EWb?n/%;pBSd\%_igb^`F!ZtJxy衇p:K059ZXſ_B8P+QsEV̝>O;7(iRYT5kԨ|!=zˏ/V_W+#9K{_)>[Θ9lyv+h@XE*޽{b&nAW+hj9iEB(+wɘ9,N o(t Tƍ1r&MDff⿊Z仭RW+ſ:\ع%ۧ(+kJGmVA;cۀT?HE &ţ}s/=_nE W+ys,yå0")),HJEf(r9)AF.2S+ymgrOaA>x|ͺ\$%%LzF3jY~˨MzFm3ꐖQ:df֥n'(1MwҢWv5~\Oaav& \ |Q$z֭ˇNVW!=^BeWGm>tmmc?߱c+qԴ 5iAƁ&-nԂhԤ9 ITo9 hGz.}_,.ąݻ[;,(D  ]@Fqjv}1͛7WW~7-ſ?㿰 VnG~Z#۶ndϮu ,3z iܤ%tUNnי:WGlhЦq<)9- -}]J;s,(D R@Fqj{GzzoYXV5ſ?rϞq~Z͆Vlڴ."_ɯnueѮlՑӮc7lP+#&~0A8ZftT~;ȑ#ythf}6C(D R%jQmSO=G , =EHùk_eKe.'\n}|z:wItſ?b.h(?/xxA,mYVB QQ0xy?oPRvmb,_eKb՘ZIup84oٞ.gs^t9ٍZ(aM=NZ7'>|ߊxi[>+~B (N.>>^{+J_[WQoݲ_|ηKdŲݳK0TnۙУ 5mWU4ha8%Lx] ߩ} 4 L"mDi'ɓ7GoP2v-]׋x\VLݸgϯzKރHNIU+kkQNR+k(7m\ǂYd^Y2 ,~g0= i8Aqd=v@Y۷i#wj;!ZCc8N:1} 6m[W~$;k4MV,3>䋹ڰŐ 8wpNP+=ƓPWw+.fivjOwk ) ɓPW=[O?O&y&mЄz;2 F=1 C/ NAFŎP7ڠ]/Dx)ðaÙ0ar>|}~;kh:;M}[6hC&e՘s_BAC9k/2v`qi):4'1/zV1m̜!JTBv}?,K]WhkӦ s9e?7pJ(v+x[fy|ſ*}Ӹd2^Gy=,v>>hҬ__/z̽~^:R R/gN#76> kMGDbN1M6e޼4o\_inW++& H5q[/[TN >Pc6]r.[nx~bSB R31M4aylR_rmڷ3MJ?3&n#~mpDjHt.ZR^ƭ?vN_$6uV]r.۶N6%~ l( +N15b޼jJ_8R++ܷmW jc#&Nڛ;{M(^0C`"7m`%{ml ("LO8~̞=m*K(_ƿΛfƟ #{vmc7sѾӯ0ſBK-`A?iQ;bddfy1cd= 1DB R=ܬ1SNΝGǎ%->ſr}ilS>F$ >;_NM3S/[++4&28\/Y} 䣩qjsL ,( u!:}̘ ݻwWcşg;ǰkЈD{5-LӤpP+܏ZS/I\\w50ԫ׀}єK""24jx>#>O IDAT_ߴ((0(c1o=w^o/u<{* T+܋aˠkS1-r.ǭ1{n^-: r@;"/QoUyEIxP6m\HۿwfL -6mڟWWcsd?iЉ'c64706 ga0 ^|EF/(XAaQZ9rO [8D7>e󆕜sIOR+X~ v3H6iԸ)͜1 kZx\c8'oQ{BǧWW/_5׍·Kh"m^@vSa3ſBM -eC@ tgd2ogX ( U$hz__^~ϯWW>{QpXrsh"fΧw ]t*<8Aӈ/ҭz=|"m`lʧ4-Hsছn'P&Mf0vXw\GSν'QkW-es)?=~E:\ewhbo^C Rq5_/a+--|WW/]kG^ kaAlgwiծ+ 6W+y`~?uҝ$"}bn6.@s`F[4Ƶo_>C\.- )y2w2#Gk"܅|1k"x:tq_oŽ}~S$':b: οv1۶n,(3:u_|IffmzF+_nj'j""9g`9r,:'N\wC/U?hb+z+4 -þ_kԨ .iӦ=6yYGmTDTGߡIv9?h8>Ȯ۹³ٱ}6*@7 O:  --?Evq{}\Ž[Q2>3ߡQӶ4iN/W}@f6+=jqNLnw6,P>( <1@||~_8H)50a\vP?_h+{xge amY˯\W4|&YAcS$&MӢE+>1E``_8ݫqGw~;***XGMDM0fb4%RgDc98ւ }ay}g|ds]wq%z G6Q_c9̕ɋCQijiJ}_D~A5_FǾRVaE:n,;u%/?7xM\@"P pUWsm?O/W}oݲsGb(Jٳk }KSz/Ww)9aI4܌X];xbhL凞hSLAOd`ܸw}~O߲MUUEIY^zNPAS_ a99_⚀XFuUPXhcd1z `vXz쿞NΝyͷ(..4o 5M=eGQ$/knG*|?P0 >|铆j vhSd''^uW^QFƿe' 4G's<zܐ(K4ןƦ[!¿_^n|FO<ѣe^/'ՁnIڊ̍^H_& q~~~OQEIS/yp(H>#J!j=Q(yoW\\ByO?;W ׷g„¿/DZm]ϟ+USEQ2]?{`(uk(y4iҌmܿP!a3Nm 5LO><n+?F.ATQeͧcz {d޲`(~ ҡc_`( ɹ pgp=?{8{$oJ(Jֳq nZ̀¿`YmwZ5T+{kXrH= =0S2T.ٔ˯PPP {8+R%UQ=`7! JѷS>u3YKEE9OGb`Z^5?qhPˏrŧj+t9xj5J!ѧc>uKp"cٽk `^/!|4!UǯM/(('4#Q}/Ƿߏ3EQK&s~_~Z6`ρdԫߐ#{V%L@f27~;&OYG-jdc/;rs'TEEq|%o0h,r/d\;F)9&KMiҴ/|˥5X*x (8p >'P?~nwDSQczblۦk!¿_G-ؾ/B:rs|,ö\:FPTêj89=:˯PRR9v%-KG׫r*b|>Y&%Ӧi¿_ۄ6;GhR/3\p<)/?ղQj:x?NϞd e/ǵ{ u\,+('dk܏[ 7GQyդ[xc۶WF{S`*NKC@W7y=SyϿe¿_屯3]}EQ<۲Xs8Z#!sТi.&i0ci޼mۯ{tTEpRN'No~SeP^a8];8̱ݳKSQ%4bj7?2&us8a!,6_ղQ h< ||)YT>ғi޼9-N:&esh/PSQOuW/PPX]_~i\zzPr>&ǖ\6fz&6Aҩ 裏y!_oGQ\_QXz)w>k7.[vY6)wy^.z&| ^N9C6/Ƿo:~³EQ[p~N?V<-~, 5WKFu)jd%cyugq&wgg MEH{(eͧY\6{ Ǿ@>3N,zcYʫ%'_`gb'X t7o·~DZh 56QSWT>O60h JGӵ{?רs={?ѹ~V,}oG"W':CuKv+_c6ƍþ}{Z.RT ] <_o(>O='O ʃ6/7V.C)?ZT[ 6a#РQ,=;YޫY+9+`_U¿؛ˡoO?^}ysc۞ |/lD !`~u? C¿<)lܰVӃQT̰S5~}'777C|uc39|PӠq+TQ" qS<:4cMWş ^6ݻ7oyyy8bS~ųygT1=5j2d$FEQ;\wM$bѻ+OhatJI|޷S>MzPibR/ }j)I> h絁WVŋ?}eٔU|?_+U1=O#:s>M / *xxYk_~4bl.W|/5vО* _Wc VxTzaUoN@Jp~w3nx c_SL"zs+g]F6 9hՑQ0v9T^5+| FQq_mvhR/@NNyuԣz< VhӔKVG /ϗ$m(,[{8CY#UL(}>3.t8wd0jEx/jViծ y<_k5ޫ0&K~9X*S 6U͓G3N?6蒒{y=\?* {BҰ1nҙ3+i޲>¿o>1b?k?!8FD"!! q=9XfӴ~q2ñup}A**ʽV*j$!LR?dc׹+#SRg Ex 'ZQZ8摟_Wm ^v"jԯc4cQTDFMxṧX*6j8;<>z3El*¿}ر}*[.3ϣwῪz(X <#{ 7 6xE?ֱ p1+.=g~ԋ#/UT | ݤI,YJڵ=e/;ksxըԪ9řs/'/ǻȹ xٿ?=;tл<}M[& q1g!j?;4mRq{U̯G8ǀ/ ӭ[7o߮_>UKfq-.&~N 'W7@v{1iƅTVĺ fϨנ9-tn۰kf r ?@~A:vRQ 8@Ur/0kk<< Ǿ{.hWpq/F#s.\ɣKR&͸ g+?$paV~C̡/5pf! r(aEݳKyL5gU1^tÏ(,,+B6- sxy-0 6nMt.\߳k+6ZӅ?d|A_OhmУ}(cG V&,`* <4Ԡ~{qڴi G"6/'6_|{Peй'?CԬY" T^aSg8,c^l)-tq¿m理F9FҹKwV&|@>UL5Ny^W^ť^ G- _Oly(+;j;7~p8C˩ߠ̣^æ|]BZ5YF?|_2c_۱?Bz[Kf-z+@3`5LS S<{i-[G%//x[6TTX¿|۷y7T-]&rW! 76{2n<9ȚO?ITz/ q?ڎ}QZlQ@Cˀҡ^+?aUM5S4`#mڶ'ZEv<ҀϿܽ IDAT? ~ٰ~*Sz߹\yZKn~G̠yN,5¡NBŶ,m!=E`ciպׯeJO-ZrL7jԈWPRRbǂ fځڽ/?4m\Sm|w~7N{6Ms.U:!ٻs^j AOw? ?!.x6մ2K]QV]_8j0rY9|+tX֯^ȉ¿7(zTr. ߠ!/Ѩi>|=^)9rhիжS?_~?Is0lҩs7/zMyL46yFzj<aa!֭[|KԲ?ۻqûr]I;坺aS~ܵI/v5˸ٱmNV\T+ZLq¿~/gd;ˆk;`v=|,Wg|/\ɓM$* ɍ΅Eo !_:Y5o# ?@Z >,֯YƎt: p#?^6P,hP;XԪm[^*E@9gH׮]Yh1F?9Z! ɍ}'3kѨg^7@ G3d~eE߻OI'Xx4oUYzҸNU,p 3O= A{qPyiٲl(V?ޱp<|>.fN~/;ǭ>S>x7+iVmvl]͐g R?k(-搓3@#zLPj@W|%`/;Ot՜0Ka ¿tܗ-;/FtRg1wnU^4lVY(8bӢa.>yIl۶˖xL`f~}l'{" 4ǟhC6- Iݶmnv>vnsS\R_ϓ+ ,M[tGs+bm;Nn¿v.+ [0?Gye^)9@u_^Cp~_RV-l!_OlʋOl"])g14O7={W?wHMug1~⷟;5%%?Z0,w⡩C 3}¿(c_,{~#]%g1MJV~l7oHƭtg1ONlm+8e c9 ܪYL=n&*gY¿ףt:_Q¿oc߰9weZ>Kٲ{I_Oz;)Y:h,c&''KebK s<+ݻH `fd0+Gn[ƿmCE/f<֭TWYH.LJ^n¿o4cQivT ٹm-?%OTl#w{uRt̎FG&^9j h,*6QK{$[Wuemߕ9jO? Gʁ};U 2M1jE_O" eBj,՗RhgM0畣O>wF? Gl_O؟xA6m\+ Y6P\R[=X(֟?ET2=;7֫l-l1o? ѫ`r~7NeT+_퓌=DWN&-^д߳T.i4jF?%ςHl]~yOʍP wfv\H~r;P9߶?>=۶nҕpSN}?iа/{ԩۄw?OT 2=6ͻ+ߺ{̘}@ ^C#kժʕW^Nl?¿)YC] g(5CҦ]_{aӆ|ʎTPZm~]SvOf?=w2bpWLzdL0뭷ۂ`X7y]`rrrf-;ANN FaV.or/[Hyj/tM^^&/R`^92;te c|osm(_(mWT.=ۿV`^x^;\ Gm>ky^AmT&~;2Ck(?OMωBWT_Oׯ7|3 Ȕ ¿ es8pd(/z-V s[F^qnR WWaÆ1eTcoYP/e73a6\_m?3İ1sT@2۶y .Ŀs},8?RJj7_РN#N+4,Om^)Á׍qa;^9 9g?dž[?).~/  ˷jUAIs" =g_Ov썰~[|=zeʴ3T*n5i0& #O>YI͍ĿerYY,m{uś9g/ Y,~:UqIcjV_( I?KS-rcپ}+#wWJp ` Ϭu6A[S}L@v/ )?@^8TXҜ#O ,^uYn?@FMw^*<є@_ \D_>w8rܪ¿💟eUn3j Ιw/ )l;O9j ¿2DzeW-"?+7J V9+G… Ym 8v*/z[WiLf F|>.4hR&Y]m^% ) WUn?@E\s^*׫tyر#_`$rOg\$TQ}9'Z"_xsa" 1_ U,[29BZn21p`Mh܀yO38a.\H 0ѨM(b  ӕmse7ҭg_ȴ?6NcUpҘ_{H8( ),n p8nJש4zhӧ3f4PDSx_ӽ_r/4?7й`4},~_¿R~{+XYeҔt+b>H Z Gw܁Kw ae h4Zzr_O3|zQ PK J˾CQVoWD>pI-/eCeԨF߲*¿/'Mo6MMwѴE[_3_kʼ~ vX/ iKV8>r<JyT\ _#;4aT,k_{m%8+ бgӣ(t\6}!_OvDlRac,jd6gڴ 8HG6- i4'4:7-I?׋u7TҐ^;lͻ"l1}2rD뎙T BGU `…FB;EݻvJ6 [hҴ/ Y?@-8sTҐw銷?myѧ/}mc=jdT.g|9g.]t1M¿E}Ulҹko̽B,?3.}~*LiȢ7mCen 2ilonlLژ~4q-¿Sh$+/>+'''  >@N TbE"¿aM,p9K j?xh?Zje*B6- ,;o} 6ř}mM?死2vE*P){X¿ |Yr :-[esR.\gS5?_"77nHG6% U:? >fq-.F_O n UO)ƿsuyG,W\s#/1@w5җp͛7-[>6Dygt,6k Zo IzN?&g; }bмE+f:+*5ғӏ\`"j¿6;ot´iׅ/߁eԤ4kY+9z. i[6 \yM^p.OP Ź>k1wߍ{?xY\sO¿RJp?UJqb9tuPWn?@>,/|b5RQ/5{qJX * y5 Xr + Ϋ68Tf-Z3u^(3H]0 x['^O&I#uŒ3 ¿hӝ~0?|E~GmX:hckYת ~{yk8G6i27_IWzs貛?eGgw#>%5Y%_ȹqW hZlÔigx\ V \mÍ7h ĿoܰMJ5E; ڴ" )ÿ؛HY*d)صm/g\_*hcꚛF jQrgҶm[ _y/ )}c`_w!cso$AIM/g\s0mU,кM{Or1h@03 _ZOӉxYW)ʸIgҼe{_Oz_vаIJVAKQV|/g`앯~ih]X.{^X4P C7^*2aDzea ࿢{CW)Y_- )j9eW)ʪeoUoPVajc(@4dJ?vr`>p ߲+g* mAEQ] |_OY?@V]k [ U8uϯM, JFS`g1tP ض/gS]# ^8*eqN9?@8lɺQ(<^Bpeh4߲ ?cx 5RRxu(_OY{$ZvQKAsLDzrC zdکP\;Qp:vS?@E_mĆu49//, ]5|1i֕*p)έٻ{slD,ekF`܄j.Rj)7w7 m [¿og.zKW)HIt/ ?YRO.Y_c_Z92~.^pJ@@M2gYFj֬ .4 pOt!֮Y+$ӫ`Z$ q_  }*xIfƕ=rsׂYY|X9j4l p\jpESfMڄ#U0Tm%$3 ¿o0c1%۶X"_c/ma]5j2sP:.V)昼 .(É?t>Ic GOz$vջDz k̻J~e _ g&P=?u4Znm#QH`ɇ?ٌt&ՄwWMܼB —l`{3uٶ;QcТeF`z٨ LUo꫍?|=/CF",[HWIf¿/j(eE#!_(c/|&h ?G7tuh 0yՋ!Cq h V}GJ4ԭא ¿o*O]KU ` ٺa/g[wGu,7tH:unz4S\L\sQ`Pm`ɇ*4Ɍ;? ¿(e ( K4 eޅW^6\5發ׯ0 M8j VjR]&Qf ¿! $y2_ rQc0mYԭ1}=1yO/Xp UuD7hB_vOzMT +?+eɚ1^:j_~~>\rQDm[7N\o`E]RWId_y/ ߮m|<]0)V4" Y?aXΝG@ *glN? 6lh \p߰`E@Ƞ_7 q.=U!L"p V)ԮSEcl`N7@`lB[jYÿ |j>Haauz6HSOKnVWAL"6nf$f8mx^:jg֭; 4!_g?]+$һ0r_7vKNN QAL"[7~" Y~/O%8 o:v5|\@B:se˶ m0_ 2p8_=XT`/gֱ6 IDAT뷅9TfX21!@K/6AHW3,cPD7 ذ3H&}ƨ &m>qp8fΞKE&{0:wԬY[–oq##GmF]y&:иIK_?N?@-iؤ cٷ{3G9ׅtMa+PFSaz 9+[?8[ Ӏ& /ñOU4Wv!+m%7LO9v|йPƄcm*W🮱G-F?.3tAg7KKѳg/co<_v^S]u&n= q¿Ю$}*G9Z"p>:uN}M/!Y1?K?zm_wv޺e8HJe5UOH>{wmr4q {0lfx琅545u/֭[3SoS9_jY׷j$\5Q¿/ vzPA jm`$ Y,l30y6ff`ϟGAA-,KjY m{¿/im:SL0{vnGVج6LuelyLy?@EHjY'-z@s/ n? ݵQXV X<@ @Sހԩ1GlQ[w9~ Vg]q&= ¿&ۙ:WL0&Gs_ЅO3F87o]i&6n! ¿2QAsr^d+m);Oe[ww@&t|>IF̜@>0Խ4bHZʹN?@0$ $>vJ34l/?ISkj¿ڪ!#oMOA&@ @{iܹ߲*uVI~۶9x`4HͅCT?mB3ؖVk??lK=\ȳ\NJa!h;iӦ8/;XD('6_G~`&+衴6C#WoN,l`\Rnt7r\L2b#Pq¿{u`5i! ¿o;¿8Dzjc+Eh&j,aq&@ @]SΜ9s(lc[¿Z0|>@⿲>_w$*,6툸L6rHBn;VZ?CǍ'q}f$F[¿M`u s>_w$cc_!hFLQQ%%{O3v̚M~~Z6H| ¿gb ԩPlv>jj`ʎo¿mwe 72H42ulPLuSNrnH4%%u_OԨYG3}¿X_ ieʴ3M.)Mdiܸ1C 5 %;$;iT SPX]w1  +PLs ?O7Z Щ4xu=ki˘3,_/¿/TM}7iL %%uvvMTY[3Ds]7!۫He' ÄɳL.+i0=] f@wSYgeT]  POqIߥ?Q@ $ ҧNp:c:04.\tЁ^N3WqNpX DRD wWMM?hd_w:a0e4mԲ&`gn+ Z/% 6k ¿/Wy?h@b(_w l Vo> tS̙3?@0,kl iASPPMw, W&h$>P 6gB_n,'0R^T3qjՊ=zpƲl^E3KNn!''O3@X]G,v폺{qf074?kl#>`]-';9* $ ¿+b!*o;~%NuL4u86m-Z꿋f$]wT˵$W64 @H][Ä#:8o@/[I&J[*FDHy_?ɽ- 7!_w !"?@>ԯg̜KQ=×z]B!-H?e 07¿^X%z~FbrISoVYǿeA(b YPմ~H$@ 7G_%z(_w* S^a`m(4h@i  ,_],B?>_?$)& kt@&0jשgj9pb`k:m:@lټPմ.JA*|m¿5[SRoF6n<`cLӦM3Q&T`?Scףףdx Ǿk_Cee 2v4Lʬ)RF zTZĄaוoUSVMs]>5[R3 8x$P-=f,ǿ BsÂf/ ¿Jlw;5O6 8xe+I cO4G6Q3-'' ¿${0j2b+(5ϸ\b??sZ/o\`# nÿ nHn?[$1&aI)#M}aÆ?@(d ?, 7_I`ݖPeiߠ0Ҍ&HuM_R6Q[_US_57iwM. n?>j@op"c1j s<L\ i?_ǩP ¿˺*d=r8I7nL=\`3p{_q'J_w5m`ݶS?ڽ75P M |`[v򔩕\?,[҅ ¿/;_I ¿ X;u5r!a> `-;i$X_OgKIm _UpS ¿˺maW?Xf`[FLS=vM"g¿{}¿zÉpaАQZrf0-ZZ:jժѨEƮi¿Q¿i w(ÖPF=O@T`\Fz¿/+*o ¿Uyl/o 2Ԓ3FP-:fX=OOuϿ/ ߥףz;¿o6*o04E@l4nݺ__7wEDxC0hhSNmk&FΥС#͛7w5BI7Coڊ/ nǿۭO D6[wG\f-ZӬy+SKOB3ÜѣǸ-`ZO-%Z&cW?O gzB2c״/M/q{(!l@F:m@ С\pƲT4?%Л" ¿&& G;u5)o.JC Lz={f͚?T/kڿ_DO,]ڴ? &n!CGyM[I [=-h' 6?@ !ǿeA8j q] ¿i.ſO|¿ov|e_bj{v~ BqEcР?T/Ǐ/ wAޟs'G4Db)RZiW$n\uʵ.ˮ*%%FQE"1A"93a MΩ=3y|t'GĿ`Rxs Yx/P]t,Z(hsWĿkſ?6ӯ7ggc?(& -̳΍<\Z \*mr#9ꇶ_7vM;D(?[h|#<Vz2L7m#ſ?OĿdk_jAF٠Ǽ }A z\?Jɖ0 +b;Zw>WL_)/qͿosTm\L|)3(LGf _F7?/?g5(?'}Lԇ?(_?'_Dhph:cjxJ}Qv}?_7wx/1⿽`$_Gz^?k!| ^(\QZhg:hLmwھjuL4q|/ڷf'3mՠp󙘘c7NNv.oo(3`zF]C۴M9_nd @"'fZv"goՄ/}obNQzmnkgdLJk¿퓶݈_#*Ŀ0`_O2{ @sx{?uͿ O΃7)5ysLc,N]/smĿNoqͭ3A .{/^;|,X4 ffk?i/]/{= {74՝`E~N/@M^?=QĿF s??ph*cjwGNѹuUOv6_Gu;CO pi' nCLOw5_Xou^ B;on0@9 Y](hLU3mmӁ'`D?Ko_If.! E)\rɥ_eԪ"}ߕ).3/ſϋIĿ/Lf_ rs{92 \vٻ۾*i/}hb?_w<߶XHĿ/n`_υ,<`4p ,h6?]/?̛V_lQ Kcʇ-.p@PrͿ7 __w<?z P\pevHZ8$R.@e0S 6_ / -;Ty?y_LT{ .dhh(X,8'D_M[/ j5cۮj3ϱpLw;hLmm/z/?O"a_M;j-)ǹZ-gDW철?[ wmt/m#n vV 0@\;7mS(_ '_ OP 2pn+'I%\4ԲhO?iEyh1UqOWᶛƘ_ {ט .$n].(yY̛7/XLU;q8' ]9&^;_~v-Y gZ`+WctA+f뢋?t5_(/sǛV*_[wV=Ͻ0^ /0hLg5>ſwtm_$l9)P b.l0Q ?t5.rͿ7m79K+ +\4 ,߇sa@n-?8v_8WefH()HӔs=/XG\1C;m#ſ?O'pemw5Xss~#L`ul?3 >ſſÿ\m_8S D|)1L)D7`z&s>,|h0_nu@/ xC[RKŞ46 IDATpxwͿ7!m-/I*?)~ _0S͂?M,vd*ſ%-?⿐π:u0yv . 0[/MT/;ڷxo)_HF{ }SF3*$Oiy_,_隀_6_H{Xg~ j+OyB?LF5WZ}@/ [MxɲՅ,>眠Pɂ?M,__-D`f?81vO W8<wa/ſo?ZU⿰ha @cn]㬳 /濋 _w tg/8?νMCΊ{* W0ZχY/o) _DLd9>9?i-$̱S`8 _cg_ot! zl8?2ˁz݌2UQߚB\V}hO?mgo7P_۷Vkaց~.3sͿyy7ױs}SwMOufŋ_|L8e^8BdKyA`Ϟ]\~I_X lCyZl]bEyrͿ~?>G-pٝ[C}~X?/ſ/_/;A`QpZ gՙ/g5j#-ſ}:_?f̘΂?"(t`@0SsG>ſE?:_?v׳{_-XbVj陼?L5muN_.ſ_ $<%:IX[kO;o |C[/ q ;(+,w@XSKK˖֤<Zr=@rϺ0H_ſ v)i[`%PpԿ!+V\.C[w-?w!C?~ TT*,Z4@#^YnC+=9@rڿm/?q'Y`@gE,Z@_ˠe-t̾-ſ_cCƾaw,_[X[+Om7{BĿm/ſ_/;]Xu+WF9`%ˢ+s#5/ſ5_?࿞j`y(42 \/ſ5_C\π=@/bEK޲~9Z}yhjU/HͿ?M=IK¿o]X+C{Y{'Zw{t_捯<1v\ü3]KX*@K2/? `1Ƙ#/`;ohRJrl]{D5`ɒi,M?'ſ1#ſ:i2غw Fe˂l i 9?[vc1Ƅ^ -:s,^x#ؑZtҠ_`-ſ1cĿdLNg]}?Kb E]XtY7t?Nc?h_r^m`ҥf?ԟ7cLFQ?!`ٍ#L3B@ofo1 0"9&k]}?E7nҥitZֱ7⿭c1Fd2k3-pstY ?/1#@8 <`Q{,80?-YқI ?1Ko1" 7@^ha_o/3@{7ſ7c?T dhI3C3$aѢi_c1FPp_;-r@K͛G\@o;?`1ƈ/<[*FFb 0o\D%;_c1Lǀw)311@0-?Q/y|hc1&@n<'{PFcjټyz{u֚]/ſ1cmڿqP,&+LJ@Ui3z f̾c1Ai?Ne`b^tH:X5avL7oſ7cy?FOCKGYߡjM?P8rwc?j!M9=҉? ſ7c` `gLDת6 li⿿mc1ƈ/9·?D 0]Xo%m3'pc<9Qe7020[Z]޴c1?o8cNZ511ً([/ſ1cZͿ/3`K^`|<# ###_o}~R1#qڿo8 ` Ip @3/1#@Û rp՚<Zo8Ŀ7cQ`z&# 9 M[sxſ7c⿓~&';Yy͜F1/yf&\ E<P<|/{+cn9?@Wn @\ /&c1.;_7eZr@9sP }/ſ1cĿmJ?9 @vyBc_Z(]9 4 Nc1=ÊEq'_.̔S" @?ng/1#@5p ROͿ`1ƈ/; j֖غȗ__c1 A+!̯NߺG/ſ1czFƈ_7@-sg =Goſ7c?NɎm?k#NV1/X՘TV{]_c1F$lW3 6 }NMŶc1&8IoזzբOR^*ſ7c? 7MW)[ٛKt?/1_0 3.(Q@ަ[$_c1cr<'C?@p @tBo߉o1ƘJ ՚K(ԂIt_c1F{́: _D|_c1t;_$kj5 L?юCn1/c},_q*Mt:_c1ƈggnXt*ſ7cLƯ_Rҩ˶(7F7`С`s|ю7_c1ѱ]?TIkgpdl]LEĿK2җNt#7I/ư̋3$y=.iZo41 onӻ+! z@Y+mϽrGs1G/sr9@TT8P*kLN $o_};__%y? )yvͿ_7v/ſ?wO(3yep0%333LMMu[/4r#Ḟ?g8_/ſ!_3avZ[@thcFS_b/ſ_P) Ʒ[c^Ϳ_t/ſorQ9;?m/ſy_;<ul0) 0i_|_,ſx/~HRj|Ys0g  HR_ ſw3;ᶋ `.sFfp>ſ?:__V>< qng`i)q?/ſo_/ſ`wϮ( Q.ص{WH=|h/cǿſ πp'[v,$-ſ/6y_; <?4Xe` Dײs@P*_/ſ/:/?pfc`ױ3?nC[/ſ/(߇{]w'CKv9@`H m/_A8"G'7?, $`(gs@} @(m//ſwAm=wXYԪݻv>ſ~/ſ/>j   Tx,-Ďy?@)-Cн77|h{cgb'1-\cLlxget^CC\_M \vq__?0jо'O~ #ſ˸yl(Eqo|{j庙*7{/{;0t>K'F7jr?/>}1-:3)_ͥ4i~?ˢp@z?DSh`@^_O$_Ƙ^*۳O1-=_#C I'w^fff?@$ſ7Fca`t8m&Inda4|} ۷m78j@t8زesu3_]cĿcCiCg?[} [6o p /ſ1_c߳ 9le3B?g/Ӆ]lȉ9opѵp-Yc)휌?8gfv# -rزys(/ſ1_cĿ d @  -X tIYw/RYcƈ/رŘ] tuĿƈo_e7@_{ -[?@&$ǿmc</0XI$:1wQ3z<0/ſ1o?M?D?c+d۶j`P.c;6Fc"ߛ7oҠ_VٵkGl[oӹ0̰m[i`R.'_cĿ7t& g&FK`۶ԪU !^ R"ſ7FOƈ獦`㛯xo)D_PI/ſ1_cĿ9L`cNF( ߘ>#~xP)e/{z4.ſ1_K?Y)VJ 'KĿƈo?' $P%ѕ: G'$] ſ7@odLe$sm?#a|$/]jA M4)g\NĿ#ſ1DY8v 7ZiFffhRN0P_#ſ1c,Z珗$;o'8KƘZZVٸ`G_#ſ1SN4?7>\8ؼ ,'@mm@0PJĿƈ?2F`ھp^)XCjT^{-XT*_c0*/׳3 *`0PNĿ/1_#~?36cWj /[i/1{Ŀg{060XI?kFY8 W+_,u#/">~A a] %/ſ1Ŀ7&d`;{W_Yo lڴ}{D#ſ17 _%Ů];bNV`2K`F_codyk}ɂ.%3`+QNKE̙a/U^>Lٝ5Iu IDATĿoۍ1]. ݑ1_mwlʥ-| /X31/Ӎ }`@ToƘ69$o @O/l]?^ }}`_ĿEv#ſ1( ߻7/_`( ]xgsy_,->G>+5`(4Un `G_#ſ1L/i{3}e1M-x1j5^|`0tx/1--_{=.#OB_Ŀ"s#$cĿ?Q{,(N^j0gs='3</b$.ſ1_+?0뀩f Ov{.>`p0_sM@'#.ǎ̲>ǵ g`0TIſ.u#ſ1v2?wfv 3W^y]v<Xcƈ秏_ v`-ZȲ'x"X҄J%_#ſ11m}x4X<-%/]x_ ?#.ͧ.-gY-?J JQ `x0kwm퓌??k?,Ym8J"\v͚?[HĿD6*ߘ^=?$糏B?D;?Y O>8p X /1_/-,+bӟn j3<,+/1?J经_L$gVx5 ʏ"]&X3</ ſ1_v9eY)hC.< DWYI;6FcĿw ~Jx> OF NYX&h ſ7Fcጛ`hx6sd;c;*<$333RI(/;ƈ<>ɘGi?MMzuv33Ӭ1'{! ' %_cĿ7ƈʸV-t6{f-MP_b}a.=^س_xd\YWoャ w|֍g=y\ֺ ,kɀ>uq4m hj NҪ=:>oz=9X&~v ?k&X8~!?`JUſ?ݣeq>.z7HyO`hryץg=yeAm'?Y,nw?kpҍ Yx- H(A<, ~/1+g_ ?So?wނ9+N Yֽۃ?@?0ӯ ſ9?!/C;vg,/$a12{a Ycz-/¿oſ7`=V??π?Hu/У<ԑ_-_/ſ#& PsͮX à i"ſ /ſo;{]>X )(w-#<#}Ŀ?:_3ᶋҸxm8}yQ=Zx,Fod`MlGi][Bgt(_/ſk#/ot>gطoOg7ST#Tg_/]/ P'?Y4R/|Q"MVo`G 0@)MĿy?:_#y_32b?}^"MVon {w}F//ſ_3O$aчf Wc;R^| $_/ſos~Y^Y 7o/Qh4g /.^Og24yn"MSFo2;h *_A/ſ_8Ă4h< {_~7_/#sQ Sg}۷D/ӯ ſ9?!/C;gcx߶u3^~1F6c:jY[`l8!I/{ߕ|>^~7[sh{Y{U77y:kl< zs)reHwYO8 ?cDE`vc;rw7,ɠ& $8qޱm# ۬KgmD]t'7&ھk۫|cLcO]i{9mY>cే6oz~+#wt-M9p*ǹZa75Ӆ⿃m7ƴ0dAj xՎo2n+3W_ob1#s?씌}HCv6Ln%2`L_cĿ7.F7b$sWUZчn`ǎ<P)' &_cĿ7ƈʸXƛo4?^_#ſ1⿠1 \|@iƷv̤e"e㛃?Toƈ7'k%?]wHwe;bNn( D % _7v1$ccX_IJwyS̷my*<㑾ۘ OĿo8cĿ7Fp9QAyXo秀y*@=w$x,(/ߘu0_$9?p/?V6p<n1^ λߣVzL_7v1=n⿭>ҳZ[6!5͛x䑇ھ%4_#ſ1_)9kcXo㗀g\1֣ɖ4ߘ ſ7_t\rr˪/a7 .dYkz Y8Q⿡cĿ7F<xy,˸|w(迺֮yoE/9?Ǝ`)+EɃ|^yڃ_>ݻn9x׳d~IGƈoL]CQ'b/t-. l|$_R*Nw?D;7?s߅1iєWUںVn:[v3@*p}g疛Ğ=?̮ Z<$ſ1F ^"ƈNI6 {v{n-e&'' gɼI"ſ1Fcza&l ~|:{Ev`gg+*yc/?piuߌ t;ν/dAYcƈsm¡h+XcEfb(@,;W~+ &!C/0/J&ˢ~H̽*L?j3{5 ta*ſ1G; hBVG?v̷.fGSnl{]㿞JDpcW]<#mHyϹQ{necULT|$a/N Y_0@%?c]{f^nzƮؽ{W˥ JsN#ſ1;yGڞ&;7|K~c`S$߻(0XI?V#scL/~YK??C1ߖXzo}㟢=Ŀ7ƈood(^^nz}ay(0>2:o}¿1_7SY _|){fM̷Vz 51o}(_҅e/1_# ?wP4~{^\Oqy?‰DO,'"]ߏK謁hh ?ߢ=o`? wzw6 .p/ݾ IgΘo E(d1ɯ㗣=K)_;6`P?2 ?|f?wi\~k0; `邒/'^4?\4@%uo?Z~оܧƮټ⟾g>_ϲ%6!o|g\#5cw5d9;΍UYIsy`4gF+^4 b=$}l^e||"x6uf; y8Yk4ڞ{=qNHHKe 7!|(bq-;gor%~<";m__d)|h;'^džo~k_%9$d_/ſmϸd ƛ$]pwUύzg駞nŒM]j_/ſO˚|s?Ƚ{/K c~|v FUeÿoſx_=_U,[Ċ?꫱"|wٲySԥ_tӯ ſ9?!/ '떍vb/\I_98Q/k_J4J7/ſo/|)0/3=={ :ֳxze:};K__7v/gy!~Vc֘p~/󉒇pEgz۶\sU`ldv/y_/mo? }+v|KfBTc>_ϒeY⿞SN/ſwڿ/ KW}KF~n?{]`|$ah*c?:_#y?o>*Q{o矌p o=.+|/ſQ7{<7uRƺy*\| h0>2qx </Oo{?}|qN[Z q`j| 9miYLj/ſohy㋋$_~pT_V^&p(/Ls 6?66Ͻļ(_ 0νU/ſ_A\x Wǣ=W?^x*/Lpg߾\O_ W&/ſ_P>'q;rW~>ˡh02 IDATh~I7_/ 733sY_/֘-7qߎL O΃_/<⿔&\;뮹m[7Ŏm,<+bOE HY,}/ſ_/?pk*)@J6ӃEG~o9mI-;f0?ǿ۽s ω>s_éhV_Myrr)&,I빼V F@?PN{G?o6'd?k`=p;+1_'_J:-.3Sc1&Tg%ÌQ~kM?(w߄ Vx 3hzz~Q῞є% J⿓7cĿ{ =?Wx@w"\IW~ ^~y}T4N7cLjH7^UQnlb`]W4EJ9aҒotwc?4:|s+g`˩.u5Wk\Rax(⿋oc1_wECQ[_S!@ׁ_QZO|?@Y++|m'1/(4PՊp{|3_<! EnGwQ S+fO'~o1" KWriQ羻\"\]Fz:BFc1ƈ`?4?.ݴJ|=!fqm|sӗ[ 0cĿ(~LQ;o䱇)E`3d5& ׳bqTec1?T.Z/~cE&M7p=\k?@>m$sc1?X /$]Ϯ-]& 'jO| 'X\M<c1sqn\ϊr;U/PXc׽?__+ $7cR~}#QWmX_[;i s 2{4S+omo10 {2cD{v":w۶m+_EzNX<c1?h_z wɮۋr KCb* ]$?儳O twcώ26DejPQnۀ{,3Zk,[XfDۛkc-xC5s+-gb+NAfdY!;NCGsުʥ$~/c1F?4ۿ0-,3$/ORa>Dr%* g8_c1!2~ãK?-7~5?}HQt3c,DFd?=:YR|o10 ;O_V@xQW^y㗢h]U&qo1  Hx/ګ/vXcޢ\?eӦQv4)gRc1?wp-oWtGoc.yQν{QV.`<c1?W? p(Z|eEe ֆ\M!r巯GI>HWOc1FC)#ċ?}H}O,Oc2>_~Z0XIX}j Ŀ1c;??ʼG'cZ'???qn 󝊵k~ʷ(_ϲ%.(m1(/:kK\Uy"6?v>Z+ٱc{ù* Vc14=h|d4j޽NJvX=-Ebw_Ϣ?@p?c?I_#i]?i_k"1[#jEr/SODzXO_c1𡋇93kw^ۣFkVX \[Zm9 #ſ1cOtA_HϲLZ--fQ)Jc|> M.8s4qڿ7cx\J~er9ɉ0&=roniO"^(ҕؾ}[gb$g㤪?vK%""( %!v`k]+vڅ"b(bJ3;q~ 33sޯÇ:̜wNtr VJ)/0Dڷr4K 7Xm7yX6*;nYԱViv_WJ)^\ xk)*̷nRc f)+m/iNG69c¿RJ)e~Pɉaui%Wgؤn2W^Bp9 zwvbMbZ PJ)>$'a}]fmxWo+.[i}%=P⿦v3M7_)Rv4~֮j{@@6U+c5urd /c_)?nd.pãV;6Xm eoh=?OE ՅnJ)u>q6#/F]]nqPk<6_0c5bB~][ _kJ)oe2<)pu/ϭ[d+/XmojRM-dqRJKq1z+W-Xy'Vmy|Õ1g;IaRJ\m(.*N1 kw/L|V7x͊iC~tstaRJ)-KN04&5G1ח>ߴnۀ`6ګ.(f_SFn. C J)/מa#Sk}Tῼn̊{SZP7V-q[h4הjS;g?,("RJ ?Ay7*rXm/(@ 5Xm_y|ٜIT{>,RJ NO #`+Vr{`i,Ӻ"i5RJ Sl1:G*+KƋ0Mv jqzƘMN=\lRJ)Qn0it IFXiUw9[6ZqWp!6`Kma֌91Zcٚ"l㶛B>Cf^^d12԰<ݢ =;Vm74{K}iog!㿙uYb5Ӝ7i:wl۾G%0:ex g K.}_ =X`,F3vJ) ¿om:¿/7 )6.;%0( `\28+_ D۝Mkjm&.‚?aЯ{v! ¿oMm?UĿapT࿸[jE\/k=U8_SJ8_{xu_ LVk%p헓-׊8[{wed,vĪUѭ{߿oL''L¿/ ?:?H?Q9_e?kK<}V5ɀ%wXt}*p6:55/YJVvǘX?!/ ¿7Ͱ ͻ߯sǦb4(nfNp%EVW!]Jѥ%\~. (!xZ]$ڄ_cD_o8۷rp?p52Fu}W#֯%#rhL&aNn__wuڿ/.Sm\p| oZO׽K e O`ٳwLJ+|_?j7 0T:d:-W-cICXkˀWt{nUF>*.8L*K 5ݜ- ¿/G3ZO/[ O=77]}Uo uKԽ@ mx<**>☘M 60$ ¿'_]/7/cK>;1Vuڳ᮴d6%ѷo?UZةrU_ut_#cܐdK93].p"UP&Fzz] )sST__#ݳL>6ĉ2lRR\hUM$vUt<+nxqq\|~`@8Rl¿/ сui¿/7mZ:tL9% kpچoڸaC+1+* 7~S?ka_wͿvcS݈E!KK8AlhU-|Tg@|ޤ%6on)dͅa¿/GA ¿82/MduMr  Tmݺ282a7p_o$u3¿/GSm\xB-Rȕ(?w^ɼ9YU K-DC?V/&+#}<20hAN_@__OI FfÒ+ =-86@_5v_cRm]"v6^zxHl z @ӕ }!efeμEke)XAWxM__k48gl*=,m9yalۊ[ D6]ـr8p,iv_(uÿZO/ rgq* S IDATM.h6)+aͬc?)!F4;9;Ph|tͿXG{Ts7>nƿirT~3W:{]}V\i =(Ev _]|)l;we>Z~/_?S?!Ɣ )tlcmoF+ FY}~6;Y;.dfԶ L?*__}]om7ǧ_d\~~fi M|ـ-Zќoҥc5_71m/ DSKM#߼iN9|)fjp s?>x>iiMnoURnm__P?=hc奜sQWr >/Wh-c/,߸hY|> )`ȁ &ڄ_? S?3NL<}>/W^z,L7[ uk(,*`qMAV+~#~˥]'=s|N^VďK'>>AZvt¿/G7_Jwrr$5J3l1p,_qVѱc'ϒf3j2@ye@h¿N ¿;ŹcSq9f}ӯr@"` pFs?̀ѹо'@IE@_t_c{qTv/z_"#= z1/99| `W{X+ _7þ.7??$ !X)GQYY`j ZP{. X(m|0+;t,wlf/xj¿/ ¿/7! QCv߼i~$t *5 -XkУ~ᗤg4kڲǒS_Y:<~=qIq!q4k׬{J`0FY4l)pUq<18Orc%.sS ¿ ¿/[)6Bvf#_g\~ITW{tW`F|:^BB"w `/ ſNo}]VJzJ#Ab.:w,UU:+?03(!2Z}gQ=FK֙0AYIye@?$/ ^\LJrc+WœSQQxYct@niժU&7z[.۹|7z_:_]yP" Nhb ֮bQoν Ld7QUmx罹蹟K,o˶_cNG%3W\BG-G;0(w@+ڵfƬܹK]VE_OO1iLn߸~5S&"/Wۥ`FjFFW:ytYߥjen¿/ ¿_ [];xL* !@?gFΟ8-z|hs"zM5@QmgbIMKwmm&%~_ߒ7V}9st .rs63u(6oZݛ1Dw: vz8Ocع]άhӦ_Ks,Y¿o)Ͱ ¿w ?*CBq ?FvJDK9T(vYփw6m ~-wS ¿/ ¿OOqTZa6=5-_:_l'g 1|=տ%&B *2; 85s?ޜ1',gD3wljt" _?:opA38#TG1xUt{kB * Wcؽn{֌9m%"?u¿_R'12]a;vo=wƠ=\1^yOi>[CU )( ¿/ ¿endSlٺ 9Wn'08^僱C'zS:u"LXu¿/ ¿/G qÒBxcߺy;蠸fB *Jjݑf̡sn^~^ b몃=¿/ ¿/7+ =?vJ.M;B *6: xT-1{ "?q{¿/G¿/G N(W'0_n4ϮX<.UVV0s:p:{)9FvNJ*W?2O4¿/ uNLH}+𿏖;X t^b `b<7&@.݅tj鴑W/  n3qH"'B+ ']9N=k ZP`U=ަ[گZi"?^S_0vΟJqḈ7Y\yU:sb:?.0hq^g3lӎ QBYN|~/ ¿/ !| Ϥ1'=q˵S|:sOi@x)@Qۇ9Cf@Z-/ ¿/ {Sm9:aB <ȃw_iFu#h@Y2 $h7x~p=6sR1))_wo ¿nqwln7MGK{MiZPkp"C㨽]m 9#OΌ%O ;AjB?~/Do_^ǻlwxcKc^k/=׽?hZPmkNlGV,cNp 81$:)) P6?7!_wxn١9ְ=xd>XNBKO4 kghj{l|(/2-Z u<0M}_¿/ ¿/qN%1O|c%%SXdR4cWj {Gx$ mW7>__.흜rt2x \28֮Y}wpƠj"pF23Wg=u[C_?eca ?@GV¥S'/wJD([qRRR2O=G+=æ HhZKKv:Ȭ[[ÁjL}/žҵ;/2z ,w/ V>ߌA ¿}k'Dv>c6 OdtpY 'Bi@C@F22Z o2x z+=x}o%_.%0O>c?iJabchB+@յbtq=3 +'7Oa"NN* / _8Jl!7?|.=2=毎U'NBi@*z `8ޣ#ai$03Naiwu=¿N_#[9cD G Z`<]i>HpHJi@ pN-]U+W0r8N_m`G $O: $ c^w9*&܎-{aE+//7_m,{mtvlO_=~iI6̄aI':}kL4J tWnT (gdz())añCkZ ;6zttp7 _%50GQc=W]WCtWT(%*\\QԿ:{P~kr]5U51P=_mף_ob;C&pdxl l\M\[5WyPPcQԯܜ޿/tCݠMK=;81 n¿/ ln3;IǤҧ CE_dzn*55m}Nl4UUUvW1dQl*?{YhA.~(, ¿/ 1 -IcS+8&O=^7 54t j֐G/Ӫu?d;?fV/ ¿d$ڷt4ZpU:xkxwh J *_chXg3rÄǶw[_ώ.F LC#$ko/sgu5[ w@5U 2`4ZxweK\q2ha!?@RnYNZ;pWCIE@/uf/ ݳ>*#'d;o<՗EIq_(SM 'FѰƎ?~ ?mE~~^S\/ ¿dԡI{_Y%ŅvE|1}5xTPZPSZhxw'Ǡ MpVXo {cN ¿Zwv2zP"m!<woxylAY^K ~1TKTs8V wz4tп ->FvN3TVCY-¿/ MÀޝ\>2#'\ZQ~~nnbJt@d9B5u:@5gE<k%譶^T`kz1¿/ Sn;I.FHVkG>ٺ:F_Q(-(+v4Q44{I&wfXy5Vm¿/ a78'2' 󹳸))эYp0GPZPVn 0hQ4SN]=FBBo66u]5+Vn' m{`@8@Jb?+/>WjJ JWC4FρUC-_C)O`qĹx j7\y.ZƗQ(-(W]/t(W\\0l!~O¯r EImlQ(-(հmGb^M[ Uzo+5 B׉+@F7ISHNNVZ`źjVm¿/G gqH=Ys1#_gF/l]m6u/ `NNkGlz)9up~َ Wi@&,x QO>ۧ?DǼ>[|˦'Xg_tvrP8tqp4QoEw ̄@FT&k/=43'N0Bv!菲oeF/y?Ϳ/ y۷rЯGv#9!4xt;} &<= \x5 +cÎ[^*Ln淍^ ¿/ u ;}ѯ)оo aku,3'pFTtQx~5kq}5) D(̚zԟoUg8Kzh75?<|^^#mhJ JEnYE8 NͷO(ms#Ŀt;}ѫM&Ғ"yf=/L6jJ JE~I Ej*[nN:s7 #V\`jl_iͿ/G' ڵrЧ>]\H7雚}ﻞ@FTtm?*:xwL(G!wݮ*O>m!χk$Ϳ; :e:)$[޳?q?ttӀFTtv>$G0e8,@N?`5Ǻ>nҌ f¿mOO=I,'=;p9g Ғ"~.^{I~6›㥕RQޑ[@k"nn#m?$x߀9>r|_6:qҳiao-Gz|\\T`FTM𚮁EsAq9d?Fk>BlW?LOO-E,'ݳĻl܃_;t04-NkJ J^/8Oh7O iV!V;\ksl6_o ltrҵnY.2RlAy&>xUݿz TiJ JvN"q9o%8.?kٔesLOwqNIk۵t` AuW_|g244M>f>Bi@)tdjMS\}?9@?_[~l. l¿e4tХmdg:ٌFt?WiZ$4]gR֫.pFt?[n`cm>l5GJmtjS;v*=}Dz(-(eg5&|1 {x7;u-=׊*"yEK̰Lù6mV}kZ=JlM7OSJBi@)ewvr:]}ELVRRӄᇢr?[}lW䧨Կ7$?%]+8AV6`?_YY7/< [MxPPJ JQk@[ikѲ5W^}+gL-=פ$W觠O~I@n li6ZiA2$a޷hſןGS\To0TPJ J, `Few/3:f}P/(϶y~ J|@;km338F44M~pEPJ J+0VIs>\1fM8YC+L Kg / .0 f"Ftΰ2N} 7bR}7O&(p58R8E ]h:~O͛ xNPJ Jׁ^Ef3DtC#cRUm:& @E]NfarĹ e#e#.]6]粑2ORAB-d?M0hp:F w E,\utS#{&>I&xML3xvAw׿E2r7<l9ma`M 3ۂD7BPJ J5e'E,۾Э/,n3 /_}{Ƶ̃dUJZ4 Ts xQDBN_έ]}>|u~>T#3]Rip\r / ¿/ﱕ+~#G^&(p58Rpץ("C K0 ¿/ ѷoB^xA>,#\\B)-(QD^ǔ q'n_-@ _~3òӇcd)/hJi@hطqGձSΛrgLB||/ ¿o{|<佬[JO3Ji@)ը$Fefcq& ¿/ KKxxG)Ӈ_ Q(5'p5,1)OTRZPJS/(=S&rhJ_b>>x~@]p ?B)-(Wp/G(cؑ#9I3x/ ¿X > ~.J}XDo4 jxで,"kӦ'>^ocU=A)-(œ8b9OGp ¿/G~??gߤLoWp?p8R<(b'<am[Ῡ`|;vVjJi@)| <dj[vΌ2cƝȁ b/ 8o&?˧` zr ^R3J)-(j)i]vY5|,Gȣ¿/  2g;| r83 ^vq(Tu(QzFK1Of^ ¿_^sMGo-Goi(R*s jZ 9za'>>A^?]Uɷ ?gޜ|ZU|݀ݠRQT;O . \ 8#3jk- ¿_kf|9CjojNЩJi@) ([sq 9f ¿oQ~G-ǗďKb[ \NWJ JL"xZ_kڵjQ#q 6_c,z._}>_~La6B >52^p `8nrpv/ чo+~bтy,fKWt_twL,pBXbR2a#rp Ƶ,f^ QZR75k_?iJi@)e3{0tH!GBqq!-_¯?cuzR{jp=f3J)-("(7 MPZr4C ¿׭`K,`7 zcR{xpkJi@)jj ph {lwJKG[N)-2 CfD[29˼DcfMQNEc.ӌm2ܥ ڎ".-{:JҖsy眖ǧiVuČJQuhf 5/R Qn:W/!@, eB`XfW9U Nr o6οW6Sf/ׅzkF!@ҹZOmیB*`2 -ci V^u k^+3~bkyl"]|ŨZ[h@Sjxp9d )٭ayeL+NYLJ+(+u,VBVV8hem{9ʶ7 IR:pQ( (^Faa%L/#z^N,6⒲s SD8@{+wuV::Zwur֖ 'IE׀FLW@,Vb)L+,:c)L_@vvcS!//'{yR ǎ#ҟHwߟޞ8x'.N]z;8/@R7t bL&+$;;S>  bdM8fto]!џ;E"AoogBL(j$I l4u< l6I2rAn 8$Ii`xpWWC$Js$$coC$o%E!IJqW][C$>@qHP;@qH K'`qHNo!@F}k=Y=I.-7v$ IcOC46.8$YHҥQ|<`qHFQSGAd I!x8$Iak48j,$)y#p;ms _,$)> T$ Z g 4$ IJmY ǁ; F"Imxo$,$)TC2a`2Fd Ia"^U}OVC8ۿ8b,$)s-{!Ii h3Ir;HRZۿ#$ I:]}@qHRRxh2I Dn`qHRR!H$|N}T 9™?}F"I4fw \k4k7 !It,{!Ib/k`qH$%U!I \/I&Wn)恒tvGW a$d Ij.@H$e.qQ`STH,$) p.YO6pH$@22GHJ3~/$ I\CX"p'Pe$R^)º~#$ I-ʀW d$VGXӿw$ I+&l"x+p n"('F"Iѕ ʀہF"i!l޷7$ IҸZ*p p-0H$c7ECH$)961z^yjH$)ʀwF"iaI$)77gҔtIDAT q灿Gp~I$l`9.*nEJ;=? k7GÿI$)M+n0)t/.=O$@t6YR(5)?OX˿/$YH.R9p"~`R-@ |$ IҘ(E5ѐ?4 5I$)LkB`Pl,u /Evc$YHRI9X^)L7tff.:Jd IJ;1`ٰB`1P L4aC~ |F#I$e`~T!\1p7\Q9y&3I$I^ V ?z9Kd IJs*`nvMKt@P4DǡG#p܈$I$%Q̍>>Ɉ2ZgĐ?tl"$@40 (#50pg($@ }C[F%I$IY@)P TDK 3qm]?o޷%I$I-?*G)#E#^gNpt*O282'CGWTY:R@[xgPIz|/eOph47ߐԘ8niNOSs ={FkP"h 5WH?iaoN""/7%7(HN(\Oӟ2jy_'4AYM(% -8^Vgo'&&niLއi qPv\P@JC$ր fΎSxl븣S:22ZM-DŸ axÍs߶]隵. tH73k9T#j:1|^ |[vpp،CqfP< l;?{hKNv?+3wv?L}3 m@.lN$W7'@Jg繏DBIENDB`Ext/Icons_15_VA/KeePass_Round/KeePass_Round_256.png0000664000000000000000000004260512567600266020613 0ustar rootrootPNG  IHDR\rfbKGD pHYs & &b IDATxy|3{@BB oK9TP+x_bQm֣ڪUϊZPED[FIHbIMf^dwٙggy#a[ȏ>r,Y~I F>E@aGAl yM )tz=v@#@Tb&E tpO bXn{ v0`8୧Vρ]v! L X>l^Y087NR`!׮ےղ 쇮G ha7'ے/lMπQ4mRx(aM]X̚wm(xhe7GjsZ^ӶDpȴbgר#.v L`%c pM7UjINp6mҢe eӴi&4̤iL222x<p8%EQD" ѣG9|ÅF:O{kNxx u46[j @o˹#N':tGуiӆ|7EԟS'Q{UP=!cǎڱm۷~Z֮]-D,ُ_nTPX={1t0KϞڥ^'Sh+{~\5kXjK,fV7M#Euy>aÆ3tPΠAvVc*YZZw}˲Yk-[Byy/ \:p- 28v3f,cFaܸ񤧧W U_U,[?[g-b 4k bIs3aD۵;5p Nj,x=3}c75]-oQ쎩/֭;'O+]ځkW>dݼ<͝òeKj[ f3u#R\Lʔ)Si^_nk3gYpj+cQ1h @[1ɲ̨Q6m. |ݪE"sfߛG8v"U4uTOqLv7t3[ +_=g ' ^IDUZ.9#n 7o:@7E+--ak3xOgO .DM_f "@_D}Aݹ{<"NNlㅿC!͝MLd*Ƒ^D}A~~>wu^{_D P(AD@$,X!U<$9,,K8d YCSBW EQxwu˦DWP`CtkӦ sS^4x4pD@$,Ê@x,bPV^ߊI!t)qI.6Z)»#۷mIT{[ \l휨[f˟w]w}|%]mB`a"*^ _%|^)_ Bҿy).N$bG]C|)f,2W^y.{~m?2Ai TW"B=yBAy@P|LBQBy@(t#b18?` ͞T.AStaz먙_L#FSOӻwo_aA08BT}x$}2ReRRWZwe'=/{:f @-55W3 oA a"BTxT&2i)rxY\ߜfU$81 &ϒW}3HD?9ޏoW)4A^l:?pp?ޝ787*lcƦ<쳜5y_AA($*d_չ<Y2;$sr~3(.Frԥ. < >}:YYY _QʉQ{S{8d 9M+& [o^½iua`Lx'x'III1F+âlOd2#nK2 ~_J Lmg . 0n7j'0stܹ?P%m_5e;IOZyFn*V2Ypؔ.Ȩ8uCUV̞=jմ/b ~3GA~KW~eͪ\;"vaV۾u~ }:n#"R3\? k6oȎپe6(~ee(:dۋ/%/tԃкm'w"7/mI+&>D<7驲a+Z0~LI _/]'h$IwǷɊ~!ԠS Nj~./?M"F3 C;`?h${SIмv-]8d0??"k޴@ |Hyn7ӧO窫,5jS"X#EY[;w֮@d$I"L증.GA}93~2鍚ZqtjI0gr7 Ɲ08}QCnb]z [JJ saܸqïa-ߚ/v)/4np$cpTkC Y {E nqooV Gʼ @n4žT͛c?"b}}k_|W 3^PP(Vd\.N / K{NHt"?޲_qeSZZo&Q8-B222?} 7:T:Kӟd+ρd0ۃ\pɍ\tm4i]2:r4 V.>ÅV @]F)d͚5cӧO\ VYcJⵙ/~7_JZ_ik[5@h]K&V<`RZkVǰ5nܘ ?_~q(p/DpUX2HdH$(lٴ~6i׵G@i¡6vvJ6ng::e}&O2<ܗʂ0|GeP;o徻oKtN]{Vm:'$"qHh&+á/.:;ޘG#jEC?>gqF\C*'5:ٯq5i.[%‘yRcP//vJ4N ТE}͉gB uhpPTGq/ڨNhIn$Xb|f2 P Ԗ20ְJI/"&M6 Pր\6i4׭lpǼCwt=u ?R2&jgSLo׮#-Z¸2 -+)[o  庫'RZR\[[][Vr>YMcWiBQ晎& i?G}D"|x/X x7~%\?OsPWk?筙u!7HJB( K2إ_{EtpHa#ٹs;?_O&-`Q̙3焝y/*[c< _Sʏ{:? i"===;REn?Qqe qu"ttHᏽp89kD;GF(N&菺P^>Xh8w~kWo͎ غP(Hg&¡-*t4s[1xj<`>?-sΉo֫yluKIcuUAAaq͜HJ" /NnX]Fn{キ^ޟ??+";NdYBUV-tUu,Iy@PXв3Э{/ǚ?樻-1͞ XꫯOʫI>e~qu /㊋i_d</@9$լ9vQ7 Q@P|%%G(>z;6SX!<Nt>SAuŶd@ 9Ô3kVrŊ f7mTnM;LրȑÌݛ(JrQi4d {hӥ)_(=Y/]o>رȒ\&I23#-IL.z?f[69g'QƄ`0=~O30$(^Ej".2~Drr?2=*t_ùWumX{O&%kSEC>s#oou3{o3w:*uve  d9/w18"8ž?S_+K"'%7rϺ˝ݡ`/?PppotBSͥ>ȹnsE4Ȑ^r:u{k.QSoآE VXih^ERb%׭bġ2ҬY.W:Yk5oP|9u/j#p8iӮg{?T ~C5?oM8{+t#ʚ1c l*G" 7\s>:rp:x豗 79in֭Z,;PH<Ybˏ1)'_s-/%´i& ?@JJ*ZasV@-`&ȁ&M ?iga۳$s=tܓ~ʰ3!Ɏ:߱Gt=/cŔ-JX#!%E4̥Mu  BrAlfcֱSW֯_u@u9qƬY-[j <0fx+I+_[yYdH8̫/<ļ7I$8OΓ/&Q:{};zi \ǘ3zS\lxx}5jwP'(gy#F?"? kr$ ߞ~ɗ Y,W$?zw8Rt~ϵ8p8Lf.nI3HMKQ|pnıX<hĈ|ɧU.=զʄضJHpxwHl ~Rt/ Yyh<=ʜ9ȇC4Ns=N>˿3T~@yz̛n]YAN?ij?Z-Z~‚[^F]VoF^5E )=ؿ<%]{ӫz.Ѧ}O$ɼ B PTiwE3e:.mڴatGB-?%ž4c|q8=)lXD+75;~Ӣe+C\cH[ot?!aI%_/"hլ9mP w4nmZ=~֯rܮa "p:]\=&Ur. t5bkuV`ןrkRB(_%rKP31i76R%iF5(Rց].pWei鍸r;MW2 kxM?`][~`w#'u 35-Zu6>]n/vo$ǽjnSo6Rp2$ ==nxZn "emLr qv?{8.I#*2~bY GNrE]hך᧏5R%SޝJ ]'z2غeߤ*Ј ЭJN ٿge=_]ruFb m͛7PbWk/MV5 ң ?@nCYQ)žk, ?! yDsTH Lj\S^ ?PŮ>փvn5$ 7A/Gz,m_nG@3 &_aJ$ۭ2e.`P<(--6nӱrZ7^%?v>v G&/jz7:Cݏ\ 8k_ua}i|˲L=maڴH8D84B@0,ع/~HT@ =p^tE5ۏAiiiw)IFF FY&W YA8gdC`oID~2B@1@v8G4S[~}a*p%Fk70Jou6G@ HR/cJL Itכ$U2R/sÎfZlET(ۧ34VU_I MZ&!vmNHL0<7 VɈs34='E6RN0\1gm y),8: GY~+nc'Νi׾f%$:Rí쵭{hߞm%Dr0wܸԌ?Oܺ] IDAT<{B'zC5댑gTTY / PX_ÃK3{BJRvbGQ U 0&=qgh^oeE48թIJO3? ?iCFJ2T6l8>O3`Æb68)jm{_H3^_ }6U|'~0|.ETZ"׭@:ag%ÏG#M0h ꏚ'$HNeC ?77;Peßa@&03> ?@CT'*' %9N~P$# 2ͫT)=: ?@~V?*護^z~@8IOȌ~AF$~; ?@ZZ#:uazU%tC?D"")6_<˲0`e &co0H ,.@Fd  e8 $ܾfнg_#5pV.F={  +6U~ ?` A8vN']:w ?@0b*hK @2}Ef:vn4سt{tǎzEŸ*$(8yQUĢ^- QQtгg/}GzaI = ?BI-U4]zv _ݺu ?@(R ~=V&*8 `VzoN3Xd?/t @y4 <#* v|C@3GOÐN0wܛث+U<5 'ix%~!1E3- 6zz4o~PCJV콉?&GJfrrZv{@jv Zns+T!+qJkHd SQͲ$i`|lK *h_Ma9Ӑdffi_uMcYP^9;:4U 6YO, PG@FFS[:V!5͖kGmEJf2d,Ȉ p "aY/m6q/f2&22jtbV͆*H5xd $qݚ5 mV+/3g/]{q5_"<϶(ԡst˨t+h<^l-Qrj ~5`5<*JgO?=!jxAH6Y9h-A ]w:-~[ R@PA`P3^f?;dI`H @0 Tlm/'`0hF '8LRRΦH*;>(FUe U,Yޫ9 vs:]- ?,k_C@5Bh&^}OWdhؙ| HᏣ ;e3I.v&~/C ?@(4Ȁ_QŚG,K666G#ia({TaaLeن߆߆_+HJ8RThD;Gj!I7ek r5lD$q1y {)3f<=h6dG~gIY3E >@3?G4{/*<Ȯ@WIqiwH$M8,b@BÆP6h,W3WbaRf1xZ^CU+7_NJ !h"k?@!ػw>)[>W_̀ /4Y3~mX=j( ~@e9&)nK (߷H5엁z8_7NɆ.t3W{Hed%_lk Z~e4ɘ6Ģ aGRV+ ~x$KŸ߱g8uUR )5ϿF󼮦4;ϾO 98/cm)bU,_r\ذnXD* jlND(,,cI 5NQC2f9?<4I3?|Ĉ!W XMII&cx%;O_obowS_RZ̖ڪ#˿ ?@O V %1"bT| dlŌ5Fi) 𗕜ncװ"Q N/N2K@n~U @X S%_k%Kx<~a}`.lʝx@f?X~6sC3+B&ʫ)/+K9%}2eHp8H}H$l_~tly1Ve/\ӛ~K =U_ͬ>? Gj~U\vFw2W>xfRQoZφ?17Ni̩~|GFò $}BǬqlßL ~ds|<-,c#J?J=Rn̶[5ï Z7W=_=ڹtc& Nb*Xh￧~4!׆4__E.o.2˥~?y."_%zKl*I6';g~|`-h җ-BдTk4HзG{vog\" E u̝;G3^LOO=@\YFGed:xНe`;uf,Q{y 9X#_.>\KUz`oUSيg͚h!Ku=HtwMlqjvk8-#ᏝAfÆ?ܬU}M0C ?ܷfԷjZM4k B&co5.V[ 0qIo}چ_$t?1\ixLjGeÅk.DtG_sޛX }:iTyR-zC\槨3|4aoK;M,7IHߣH Tun0NOjs܉*iii8霩j+6Qu*s'p5x=?}nۣN˫ ~wz٨νYӛ)^=p8Xf3yy5;Sdؙ|)6ס6O{vrF-"#]B`NG$? ~Uȉno_H?f|h5E^0/g:G5"&Kq*ǩ byŨ>E>#+--a+/i?f]66~ ߧ ~9yJK>$i,nQgТe+VoҷADj ?yo"jGˆ <)xVSCalVo$N5Pc}SBG5qM6v/5o{;WK8]8xTrj,e! ~ڻysgsEk_m;9R9> !w6[CmKRRkK9Ч ~{(A` 8uD"nj^a߈< [l❷qtH- TGf.ޛ7729jc^Äa]}>C"/Yk?$ 39( p8 ZJm۶7^UW3%hm6fß䴮^]̛ {vo7ziOHu9{`0~tjɆ߶ &LCyըs&O9]vs S$Zd>o[C &&|zO-9u`=F/oziF5`Q/}+%?׉#'|m6f&3vPv^XplH9˃*@%:lm35&JtcF/!ף 6뵗Y{͕;ȋT601|zo\q ^ZP@E~–Sڦ ڷp26xtri)WGR@TqV9pٲżʋd9̅=5T0~CⲱiwyVU|św?۫z%:rf /O8=NϿz ˸8F8=#ޤ +yNr3.鵭Mo'/unx8zpP[d{.ӏ$q݁|xY4,]'v2d@EiȡÅhb eQxMPӈ붃sSQ?#ѣlmk ~YJ7?W:L p8۷m!''>}r$Elmk~HwGn 3kƿ&;35 +#`}}-;v E۸3}a~?_ ۖ¡F9 IkD 1#q W tЩ&~߫q?s0 kGP#OAA?AkM.V(~~ow:w 07X\W-[ѳW_ݙq%I"7Aa? lmMuv7_gW+086b Ycxywf+Z(,Xc f9v~㩽¿vw\{X@)DhX}tɗdһO]H- J*-nzvpt~gc 4ݷb ,2˯͘g낿 ;l? a=}L$a/>};np8P@%U7Uَ}aVn(66j1o}ί]@ `{m@Yp&A<]/gi?ҁa1@((l0)Jc+W\^-reeN,ۢ3hp1bXsr iPqY6 lg\oڰ_M=R)c`FmY5ms>G>~g o'/Hu+ )*,uu! O!57c!=!Vm z )1qx~mݚty=z8^Gc b] @3`)>BRRR+s8}XǬLarzNS'M#77˿~5cJ`;05 I6s/bxFn B cW>zy<+F @G @ˈ#Cq$awʦwd7uX0 2$1Y={7P|{B+Y`'qNTE/F<gshbcHts(8O2% qt53_g M .*-oټig4 Iy͜ $?754b@W/7`m]^xֲg(h37i$1Em{C<(l-GfCz87ZxVہԝ4yLM? n ņ ˲DƝJWAq˥wYmjaO2v*ڲh,`DYdeгWpNZ7wq,DnWK/.yϟ_nծjY]f䋯ǟDQ~E;tqi)e4x C坷cf[~u,lgŤ܅tJ.=L?"ূ $b̀Zh j s6_iV.? [ 믐NN3')>y.B ao$=äQ7iϟ_~sdmVۍ2`Vbv 0pUQg_8aEQ:\v{;B†^̀*W[_t%_|j|cuE@292fy/ 0 /v ? :,'zэ)ѩ ?x>xvRS ϓd9\ѢEW vS2a_Ὄ4^=!–ۉ~oY\vpn}G`7jw>5ބ,ˆᯩaV^TTuo;) F)2]huۦ/Óc'lFcU dԩ0Gy&_:f׾F4yn:r2}K¿nr;XDǷ$x IpǿЬY?~]UAw(2%o&*E@!pa2SU s[qÍsUp=U Ec E #p‘R?S2ede8i 4Ikp8fe^LRw|& Z[Kp8kSA KS(+2l IDATPW( ?#q#ZCIH2)n W"#AF|r"S^wWO>?;& 4Ib6 4MЙ~}7/e k>{' rPٮ7'Xĺ3c-,9_5)BMlkc%|)ۓp5R_ vmFi݉F\rٵ\s-kmß@ڳY3e[/TFez$7dY_EؘTɲ̐a9kyǻ6D"|K,h^"娋yVg8qfԄ iYrtLt :M}k}Åj&xuEk<ҎqIwe`_~gfK\%Phh)@N~$ѫ@Ξ01gNm~{~`||>m֭^^mb?j j['Ъu>Æa9}ę5j~)g:[<" Yb άuf3`0 J~HKkT//)-foXRV,_gxm>ԌS lF c8n=Хk/wϗbielټMײaJ_-V^-z}M1CKUvtғѪu;Ze^[srOc Eݳ={v{6mV{63JCAv4z:l+Nr۲͛if34"#)MhҔ4RRДTN FD(C!ˎRVVJBrapeO [^~ `X6oWs嘔R6ۆN k`ږ(0i7Oj˚[cXgl9Vx(L:ZcY+X֜Guu^lKDM"Sd}H4wnN1ۅk:`|uMJ+zO Qf.!G^/G%lh0ago=pQslg ul;IըCߠ. ?-3'Ƚ@n> 2ۀQ7G`[=4G}Ȋ>2&ƺh,"4sb2Խ C :;$?!dڗIENDB`Ext/Icons_15_VA/KeePass_Round/KeePass_Round_20.png0000664000000000000000000000206413062021630020472 0ustar rootrootPNG  IHDR IDAT8ˍ_Le?APJzi3rNDsYW-7LjօڼLFR r(qL8 Q'>{`p{@?O?۝_Q z^9|\aHW>J+*jEdnIB5etL;#NH?rRn $d8KV/X"!6aCyyMӤ//U%k鿥#&r/(/{ p)K.`0,Sd/Jn"I.eųn\䅜ŷru\ڣG_H =n@[[[A*U[dΜl9z]~限]q%#s)"ߴɑc' 0lN[XfMTMB\tod= MPuaToy/Un)YO7v31ij2E b:y Sd&$4a~^ rm&l"PR6Gk<^>ABzVŕ(tɳFz/@FF"j D_2+YT vk~ӶIENDB`Ext/Icons_15_VA/KeePass_Round/KeePass_Round_64.png0000664000000000000000000001027112567600200020506 0ustar rootrootPNG  IHDR@@iqbKGD pHYsIIw| YIDATx՛ytu?eaIHBX*GADvMu\Aqގu>Lk & IY7Ԓzy$:Իuw{.C"HR$&J#a`pj@i<A8qXGŴH4v;1p`Kbb" fN>EYY)%%AUpV/?P;u ,w /THWHWnvzTVe[-lnUeSv46ԙ*傅ʌpQ v{3(6m|e+}>!>iͪlhRe}_7eeMw儉S(p.ܹ//e}*|\W>'zd<~+z^YQu~|]v6hǎgB0b,,,dՌ?)5N|O/QDH\hBJT\hNBBBJ8M+={vǗpHq{>_~ =J1BS6˗?ɚ5k(((0>Ac#@Ux!55J*TU8 ӏ;ZgXy(6F#%JƍL|M&L03#5 dg U8+aWE1AǛYTWYn@^ӽ=磏6QXXh m~0|6ow_S_WCmư+54 3h P$( ȉ&qD9N;:҄HXiCifM#eF^uvB3!WbŌ~Zx\JAn/B¹̟;@Ok\vmZ</WUy9z&Ng|XUfSHIKhP۰)%@.ע`q|,\ȴ}~%=A;~8~Gl n}'_!vN N暱 -p5MU$L6/m|ʁ:24=nwkX|{CeAG +} EQřۇ|~qq-s;F3in- M32{o^"#+'"xcK•@l/a ~z&=L:Jf`"#We˖DxUHd7MCAUQ7s 3j ze‚7m95jAZ@Ho}q2u4j۷z"x|fN75e?'EƯ<) qSdk/*,ZdnEl9*+-,Ff>]/eO5V5-+UVfz,&LdG.7^4~/Nt0M%7CSs݊4y***k\|b  )oTT`g8@wSGҪ Tv0ݐ22xg%sa7-z{1$nO h7 F^ Y7yl65c:A"TKbWlQ- \i h%4ġz}o  OU:UAT7-kohVbGx_eJ8W230>LSeibʌm태޿:*P]ҷ&ܼ€abJoZQvf~CFt={D6k\l>2ihhΰcBJ>ifbbDͲEMbR_z׷#iNlBb@\hOxдkWj&zH[ cI\ː.2"oTBNCoNHhln< X_ ,Y8hH/v3$nnjot%M^-kO!ُ_Y/o䵕UPcymU|lc)HUz3gϘlJT;6SͼJP;EGjDB+n5WPj\:lQmWu J]ZL8% ^v+x۷jJG1)e!DR'"U)k?vlWj}w:^mK=1NCj(~]vHѷCnضyی@-QJ>޶IkkΉ XOreէSў+wPI"-+/ z M㓲‚F E{O7Q׶Yj`(L86j*&7"9~qG*Nq}3ٽsXoŚ <uG:t+ Ns?$N'ì۲&n正Y "7)=X50S7"t'g4Yi >35CL{+Nx%P#ڸzvD_ !?'V7@uma OHIwɶ?Ok|x}gl,D~NlG\|R5FF7#=.I5/yǸ{6#_=m~Y\rx>٧x/X I^gL4]=T7~NiM["L09\3>NWj沓`Hn,}{:̬Π`.Vv)ʊPˣMԻ,/Z'OŒGb+@s0?~mT$n4vJNVD %.o}=_ zZ:9]yzݜcM;2Ɖ8N9* n ШZ{^5.,|79&6=Spy\N;lvnZ߾aԳ;U)zRc)(ڲ+$/zf琐H|D47LŹS(/X 'K̠>)&WH}:^K2Ww W+/%Fމ6|?!((5IENDB`Ext/Icons_15_VA/KeePass_Round/KeePass_Round_24.png0000664000000000000000000000257413061027154020512 0ustar rootrootPNG  IHDRw= pHYs@.IDATHǍylU?_r d䖣MUh9Z j`$CE 44Q.%*%1rTP-vw)ۚnw)tZI7w{36M@06=@%P`{<Xt:3fb' \tG*+-c)eggˉ'E- 5RSgǯI/]ꂆe,`vwESXXcnө w>+7oU j{v|&,[#tY"u蹢(fqqh%WnɂoKl88 X8#BG/vEQ̎nm޼Y4͒:]<~MWdH||;Gr&ϖ^QeF嫣r&k>nWJ[{D˽^Iyfx9-) ?'_.G@^]<~ݮ{elv(Mp3a]h,44]8ZrEQxw6zLal g邦 5: 6,*@O.x*IN -ch xDiÈON%.-o!-Si3gѨ Z+fѹK7c0M=J/Tu&xQ :FM^//LK,hnF < !jk|8% 4II)u\ӅVPo#_捋'X|=T@L0h! B t LC0E0Mr0.` Ikúppv}_K$dW(y弣> _zy`\[T5L_F0Xie %8! 9VaiEtN=Z v\WUr"L5LG'O#s"(yl~ \ j#=QX @ H*\tpo' ՁeA8܈i ɁsR†0iLbc邩пى]FZM\B]/IObW[Ym*2},X-ܗ!yۆ \[nc7ޣ[Q9i 8HAA ץ&a9[*CeU IucX.rC -o)Wcm.]Z! nmi f W'ذDʡ_G`v3ow Iڷ;DR0~*t]0x&غe#?@_ .\..ਢ({a0UڦTև] k'-#KAu;Oe.m䭵 [/w/[E~?$b(-㋾GkKF0; 3 uUtuqp6Fp+>4]hm7 G(* N>#Ag<76;Hg<&Mgi^_6~O܆a\dH 9q Ʈ]!CkM< Lp]Y#PmŖz!9ڨf8nYVժp1yMH ̞~Sf>gP*?/ G΄0q2cMZH?^L!#Pס of,fNRrhM Œ`E`jvf͞CH3/sMPm#@j@׍p!Q"?23Ρˌ:3ė#gHIZpMņ+ 1zdeP_s4Kٻ6WgH^]vR8=< 044Cz=Yiq̽gPoWx^DY@ѵf8M@IcԄco"WDH]\LܳeraVVܼRv&h1E0 0 S0Lp&$* C>@Ljӟ;AUY)pWpBzW+KͼT6U##7kTjXI X0Z[u|!L{lJJLa=vGB n@KAD:p='OsPU'iSbIF> DXY͞;aX ٳ .wZ 8jh8ƹ$"GTWܘ+ѹ"-rv{t]t'/mk˂gˠrȚ칐'`Ͽn|c$3gOX8!v4z!ܒfSؾmخ(HVN'1ؼ#-צ{OwN#c<4C) E+/Х=&[$rr{:Cob&iD>#B7Uź#CAB8V$87>>\skLEobH'}m_: 8#oE֯L ( ltF\*tsz9 yIR*a@!=à􄭟jz#a+:;(akfnSUؑNJm_?Jw0Pbnaqۢ^ @;X=4$f dq!"5D?Dx8Ѵy].kw sUo-wZ僝rˠ;-kHF捎}?lL$Q Fv PRK=Gˏ#sTWcf@;#I"׭qV)k$'GpښHy[o F#ݬT'=@j~6sw؃i$5gq,fV f3]f \ |az_;zfu2-^ hBnF44CYgmĄUW01?1M(c<44iѲӁOPMri^%273y`ZfFM&pM;*Y0 E< 71ףvԨQ5kRfMjԨIff&4, $|!WY$A߻v}6\x x74S,@ù#V+͚5mvmۖyy撗Gݺ9Hr;8> T]%N=ٺu ۷ncͬYUVצ|l-t ~7)m Cޮ]{zN]֪5N'R7S񻲲2֮]ͪ+Y|).`ժFe(7ߙUXDRR{W^݇nݺzFm}Y\\E X/^Hii'Aei;G,N I 8g `AUU_ٮKKKYh!a޼9,[gxx(0\ PFD=9r$!IS`WvR׳fI,7DU < >Mk2dw@4ںuW\IMC_q];w0c4}9ŋF[ ~Fd32 ̊2II47''kŵ׎izp_d|:#R <ݦĿuFֽ[Oe?ѣG3tlS`_u+|;̜1 z4T4-`1rX5j"&_wθޡP: xUL9So7̘1vdfd [qq>_};uO+%})(,ЦM~j H/oni_Nbz֫@Si)yyy{\wX, //lS@ $%e Y,!`HX-`J̘>'6mг}܂X3`*J}-77Qj| j'^; -m[]rOq I"a*I6T(_~?ӧOG˖͛o+Lp4wSSS{Im}>rG+WYg+{?Z28Iv$DCj<O= +Dn<-Ĺx݋ŗeY+b\pGр/e(-K.Wp/G(sOKEX,tܝͲKT.AYtaz)g(_4}K/ӡC _q{n7x|D+h Q9THKIOIvJ:XsŋQ Ğ堤N333yG;VdY~W'D%'ǾSoHdɤ&U>C#&}1C򵮗QrI4@?krCx7hР+|~|GZ%jZ!˚_p߽w2}d. 99 zaO(22ܓٙjfX$m/_r?oc>M#Q73@#eMz!ƍ#;;[~(s \nQ{S{XddYWM<ᛯkY_(}at`4>ewMJJ_$99Ys}~% ~ԏ+N BT\g_2?N&i?@Rr2ƍ0x<($Xjz58೰K.1-[wje.&?54m%-Y`<*V,׌Y lz۽KZc4iu~_PR&u\C>IrH{*Y3K/#E7h @8;r:Yrl'+/kG}V(I69M$_̙Cf4DBq}XdK|/)9!HI.}~ԩS/g響c6-%Tk骫fܸqvM% no̖Mٺu#[6cPVVBI\2:dIRr Τd2h֢-Q4kANXF)djboرcD f#GxdXd .W|bczIJN)=:YVNkU+qɰ?iqMZQXxej`oԩSDpLofN溫Ÿ.|>/j>Ϧ ˙1]䴘ÏR?}ȰbJ֪]~g&Gh;S"{Q'KII믿O> J\o\'14ou:w4m3KDbhNv%lW.q^13:=7(IUYRR3g3ό~G#N߻k5ܐ8Y_KRrv)B(^>VTY5ݘH.P'Hmշ'L6->W ;/..aZ+Ǖl:vϿ~_1[JFv$I]bkf8 zG|Z$w}aÆ_(u ^cjR.vkV/v{v֡b ?b?%~jgYN:Tbx&ͩWΎ(P^p%p$;xᇹ;"%쯿P\T +.W)sFy&U\`5-  mu뢟#)ӁxH\r)B(3ż~c?yx^ Uĥ !,+3iުS~V8#E ݏm۶v͊Hls  ןɓ'2O)FxW~W%K#EtzV<ԭi=n@(ڭ 8<~] ;O%v1VSSqnn.}iiigkD^}K=llXIi4o5f,R)cڵRACfU$@YotJ_rX͚9 AY 7P?+Gܖ4=-f ԯeEdnӞ}{wrşj.ʪC ,g2ߥK~S: 2q꺱?sňc$ÉU$dתKIOAZz&iY0EE),g֍<!8I\e1ƣ/}CӺ u''JVr .߇U+-R=Ɉ d79K)))Ջv(z :G͎#5-n=ЭtNMXm!xY^f5ud'9oW`@^fa~,ҳ:5ak.og-}vQ%N5֫WKZ2aYCzEeV$G5oYLy~bm.Z%LS ~snW4s *ׇ~HNÆ?o}>?ctkٰX =yNCB ѠqK.x46"~~,i?9 }U ?@rr 2sdZpذ?K~W=bKUsχ \.aE;|+q8xo_hծ'O1# Yu+_}a@A:]¹~!_F]Z @]w. ~7${vd]ڡ/I<;Jxoվ7M!I ?C66ps2ͷޫ8.jk)Gs2|#G`85bjï/v#u2>`نn?‘ԫPUqh%*۱Xa aH].=z]@gU[rXlֹ{< ~գnQ[$7dE{tu]XQX\}:N|7v&e)56C?h_9 5E8C 7xaU|qߵs;kr] |Y_32<Q NC/<,5-K.WH&pno%,P2.B_p&iVa󚶦NNj ?@ڍװfi;ٽc!?lt"zX3Ye@QFa <^aXuͺl6;Wmw:ͮQ޿7~!^NpI6PA#q"qTn ~O#Ï6UVQeܭo_hݱ/Z%سsa>i"AHhu ~᧒U}6[ٔVMێ=5[fF~vn]ih6pD ?9v5FFbQaBdUҬM3Z/#lu͆_z+d,V+BMXaj lkGv  5rW{NkYiϺn>G㗎Ҽp2hyXֵk76m2+, 5[[elga^[͆>^ސ@^mIM G|#F ~P~kXdff>KM4ms  W#Ը_<,,}c]F_(9 Iɩ&wgRӃKK ?^ !0؁G4 ~8rH1$fxw:SdVUZlxPw~zҾC5EsvS @Z?T#r!k4{MBnޭv'ZdqRFDUsҀ^yj~Â-36~v),8Z;,Iq ld Enhْ&M \* `8t~Nw4kJ&@Td8pPXJƟx_жpE9 IDAT௝㽡*ufsM[*d (}T ~_n?&'K-[B2?{ˉ?hU @c83C*od^`T$ G ?@}q8T%S魩݇p7i/~'X v ?3);T#6C>a+ ~%:¯y VV2>W ]VS@Q ]dg!O+T (M8_f{!ЩK/5E -=YVv2LGu3W߷ ?@NԦV^tw/w 555d\8_+&z$~ ~tZlW&v{ ~O󉸄_xen8%~K!SjJ]Ea/D֩S<^~a¯:(kn8?Xv ڴ;]M `C|?c T6@4_~.R/ǹi%IܲQF'-$+6aV>Sy~hkyM_L5򃅌P VTz ؾ5+s@+3oP?d ,~Ǻ~Iįqx?m?Bݏ%7ꆢYZAwpE dgZN QsT @ wZٵZ ~޿yl,MEڼ'%W9ͨ jZa*Y3;d N?h6-YS߫6~B9 D?_#+KX @͐Wb'9O܊}v`md.fzRe:IዀAJ\"dYCtԨDi'r8z5Wa2e~22Y5\~ dF8ՂGT?e\B751˒$&r$<~!%B *Ȓ)!4TKKK ` wR;it`{6kF6 KS36+?fvjjbpȨHbCM{{9d}H0#^q=":?D`٣'=d_dO_7;I~7k&av2ɴ*\iJy5E`Qe %yքhx0,f͋ ŸbEj<~;ugH7LKSr`зi? S`w8'7*C-$*2 + ~x"d6;U#8e7f-3ـaĦb!IZ;O~0e2 eC,[d),ULpYV@nJEG D^$ uAN=n8 ː,e8|~شK}s~!"PvbOπ]GhڟyMClX/ſՆv;ٍTzJT\ ?qDT.*[!GEE>wu5,p|U<W\OqEȿb.Щ+u3Kwu5ga=fM r6-z.13~B?&[~ ?5-ZeWåWA=vV 8oz`/0} L0MImgei}M )db>}Wacgc8G>~ Y77HrH!PTTZe/> 6+nQW\ ?.QDj ^IR~/d2Jꠚ[oG*W/co&kb~1fv`;g=wMrk×G Gss1🆄C:8`H_7JKc ੗isںYaەX5>)]>Bż2/7B_8Jj=!T0qf_ kuER?$;8|X z_囯bw<%ICNxI%Fpz!f_AF2-MdirM ^ڴWwޫ!Xr~|M2S;_I" 2w$@C7Y5m~cl262~=w)=25_l^FK.13sU#`мeT{ƔH._c49dݥv V1%zsY ~!tpđC9Mh@`玭jo OWirexBQ;iN`PP+2vmSSl}-0<T@jL/!OzYC/Y[VPzTqtgCsP Dw 0ujZC`U#zAx*[v;IE-Hd¯7Vt4 T+p.́)(B-0M_iAB;oVS+ ʓ=q|Cs 2$: i'q/!i'먐ܗ#M/Olh^{GԔJ-n4Р-d6sˀA/ :1-&)}$HDhut=Sոe 5~WoDA9 O8orz~4c ~u_yXQ^nO?SYx^COh֞]FUvdjJIKB?+-kNmv;S{ӄ_cMר*_ܦjo]s ۴wz;WPo&/4k` ~,s1~uxQ}Jp {!oVd6nO>6=Q?+7oOg~5Pv:+P[N$/MC`:ge^b]=5GoS)>$LJ_%mD^78$бmt!G@N-+)I ?2u) b(>Lj ػ/.&^=t .s( yC{Xaٟ\'m5׬\3M|R_c"m|\>pPGׁ^wػ D}&=HݟkU<H_2T]2'@st+z%['ܯۮVHG@%c,{5 ? ~Ʊw+ԧzm;q m[XoݲAo*~P2@{KNkG!hjcV%gD<@,Jm ~sg'aհ<3& -&jG@&Wz-\$K4w53cXRYX';b¯~$8#,wšUz< H6Tz v`zyaz6;$Fv%d5Hc~G^H;5uu8n ~tj ~oR̓ Э6=fˮs$ȍ{3NL<{Xoݲk9 `A.zi?^ۮ;aX/.,R|9C:d_o[[]JJ k-":ޚ1_$zqaW\zRdt)dV1=uV?Pk@:6^q*7gUs?N?uɡg<Jz6jn5rx=GC|}S~_I. r~a0ujoU}iE"O&IЮKww[]DP36['޹ 檹-UJ @"W֤Ytִ7cYV*&4߄ $?&CmIOC]jDѫfL hۮ3wW\; XÂi?R{K=d$[ DYyfi{LO9),ń).*Ps;6GV@Y"uEr1ЬisX]Lq ZT`ə8闢鴕רtкCY' ^_LxKxC}Ƈ֫=.%if>ee]^Eԧ6Ԉ6cQx 2$?iغe+{9HfDUǿ#n$;z=O@$E'{c7?l+Os?s|8?9qqmHA03&py<6E ?2 뗊$Uƻo>VKܺd8f>}<7gz/3%Q5,>ީr!㠰xwlL@fݒÆ}|0SL9s2]7PrD  ? U ~#ŪET+0=>[_ '{)oH\vv*6JUxKU{n,Sa@lӆp]v_0ִ {x#3WknUլҶYP+Oo{kg<V{S#)+2m\_[ i fNGc֋ &UW?UnLM 4^M+MQu}=ysT{n?7+mԈضrKM>i'J(l~ŽxZ&SVHZxqi(+?ݪ0T7L?0+rߑ :}n3v"0m\"|(-wlQm)m߼i-/={$E=D\P5:$Rv괮o``>!r񟻯UZKѠ]^?R+_זH́9u9MZm l8;"t~N6[IQ? *Y[%j qo lXrvk&4XG/IFRˀWwF '8?E {>mi9ɶrt6uZ;<Q"2G]jwl)DS[ߨO_; C2 +q#u +{jȸ+_ D'&k.ب{B_/ʍfv+v? A_: <-&ۺ])$ ظahj}\XUHHEVSƽABY46mSu;UM$Mtn?/>̬>xo&U j7a_D[^yV|[E #Ux(W$vvIꕉ'F ވ.Q ѯ=DB:E|-Z%X,zn5'^\H VW|aB@:n Ī9sџ:\ۚwשaexG?1((-`H,J )˅=f$&*0,6uWim#2ɶF a9q"||a{>DI@mwLB[,:צּ7g)yUŢ)떑$8FW6Hbz8Z@}۬+Vm5qE[OȌML@C6E5 $AI\1(ZY'a'yd cW {*Uy`e3,>zNlob;vڅ5-ßmeXTײF@n_OLb]#SJu(aPJ;-A {mh2pL?=_+1 DY65t?zh8^ DW3~3_%:t0{ Nc6R׮^=^|v1WHB𿨜A_b @|/12j iregi F?$ PnY 4Y5o _~ s͘laF; 6Lڶ㨎~ӏԉkYJP3hSSgCfs FcM]1|QOO9-N&նKL>/>sG5b8'j -&g޴$8_T>ok.lsN'w4K(t5ӢAEk Kx{XTup/*'EH. #Z O<:/B({iqfq fg4cYu`?o8_NO5,p?J>?D i3YV=yM=%S+º51=lŋ'q_[3-4mam HKN 9{Aq=3rG2b?j˜n߇^ qJz;v4TL+ujXSJf$lz=so8;w\w)0(f5= p \8k_3|LlLH zf֐a [$NdDS&.tJdXLOLY2cg_c+P&iVSiDsP(f@0t Hb-zׅ0g6LQ0;_SUS#=7gN7a֍zUp3 d;@YfܘudYKУ|N8*9|?~9Kc_!θH_M^bzN>6oGvXe |jop8o s43o) ^EFҬq*m#QjD/fv>̚P.6Px H6oC.al0Ō'Tj!3ej9hq).5}PҍwD@!ȩ7g^q odE{L\Igdips LnXVUgMDM*NH\ 4G|/|)^8RZFXW N7$.F0 |uGGӇͤ e&h9H/e(P`6KNAu]n@{pm(+PE23 A*tG{C_,FTAh`%Dw, 17 C %~rEYԤPKʹ&{)x v!؎6[V:@Q.YN ꢤ_j^YKXPu +}KQkJD~kUfb{nEEIENDB`Ext/Icons_15_VA/KeePass_Round_Locked/KeePass_Round_Locked_16.png0000664000000000000000000000161612567602452023263 0ustar rootrootPNG  IHDRabKGD pHYsIt.IDAT8}mL?HBYQ(l=1ñlk XkVn (^5 禫eTS)9ֲVBpqn}wߋZKJJ%%Q:ҁ~Wi:D(?ǣ:i_g]놲8֦肩񩤎ҺW-{*ۂZw8yvLu5=]jMYXS)Of^}ur([хOƕwi U5S^M8xY{jp84r\SE@˲Jq0M_?<l'?Jt"19bičDNziY*+IGAb&Co߂o(,65v*F\YX,[~+lqb.b'[Wߙ>CyytFxeyWJVNђUImb³t+7?ryLSLHY"n,L2u?l56i5p  gOp!\N|iD8#-I҉>)-m(%2~|ݑ̜"{ê(s3/7yxE XGdq;| 27ç9 E^N[&V]g 53_J.S>);-5H]E "ő1 LTqw t.!pk|^(Z(8r e sIENDB`Ext/Icons_15_VA/KeePass_Round_Locked/KeePass_Round_Locked_64.png0000664000000000000000000001060212567602546023265 0ustar rootrootPNG  IHDR@@iqbKGD pHYsIIw| "IDATx՛yxeKNH @BD TUQYe\:2wDY|ETEF6#D@H!tުGuwsTWNswΩ$~ @&s@P N'vnSAN]@I=bu,udeeMFfi]b2F̍_(3g(*:,Y ^w ^O+99Y,xdJeabUf,-hȢYͲ07[C,H<8oHJ"{[+$I?~ر㯢bv"lv%d jE!QY,>=f$,f|ʔȑPݡxojvz,RM\leg8M^*l!nu V{U(n䋄_21L֬YèQB_]`+X`wdEP}EW@v+ !'*BUS+},}rOj pl((x-[VN(`+4 6;2!WJXcN^FQ 2BBBBiiݸwփV!@I0$HAtؑwyѣx<U*Td9׾^$=:$5j MMuVϜj$`3н{w>|'nE}ZSY? ;w}S_WCmp\BqddWNw /nRDIFIrDYY)3DmYB Vi}>77;wo J ` ooXomm` MkB޵/u2ɨp"3g\gLV׏t?(d744P|65l43xx~Sh{%3 I'!\)/I+5M@Osի|E`w ˞DZi3oҹK/3p;Q[[S3 H۶mcA*x|uu5 ǿ ,>)iwjiy^U<Ġawb4FzeR;$;;۷ p1~<ży>!>%82Dި;9Ix),bⴇsCt閉^o2g_]ғܒ7!t5W͂ b-ztJrDg=Ñ#G19@ye.[|W€#ۜK֯y?z$q}/-S)N#[BvcG li+@1xIXfC m[6zǪ7?^QٕIC=;7a4/ + ar$i3ijE'O!/$Y ^QMlgjԱOXGRr]S]BRgzb5q .t?WppYIeOԊY'h %Ibٲe^$GVG c"#33x$/yŧңAy[GFk)F,N~xn;oo8qC(S 3_2x׽ݵ(O٣}Cu}1N+ rݦ0;ŴA/]CtLIkxEĎ]IKY_SAm6+*' f|P+&YK(1c%m%S^invw'9 k_!D` v5j$6yb ^Q*!t$pN{@ "6(^C,(PuUIAqq虥L ,*,P0Q(:N2 Udp+2 |/Z}M]!$>(Ut0 =28[N  3+$6AcYTw!3; ?iv.#gR?{tbH?&@uLN*=2=fj+zeCHm5)# H{|TEYHڻ/ ^A>qumm݁=SL]͋cbb'ʲ rx[lx"$X'M0D}Pa!؅{&0"btWԘ[N|yU鮃}&x(:@`p?(G^ch-QƧ~m` Lѐ{<[x3by5hViDF'/  fxfgSO8yNb[7>V:۬(s~6YWęn׺\q~Q0{|q$!'&]Q0xYt;\Vp&KO M)w#{붓؉J9y𨄀 jb.'Ģg&a C#ɧagpXY?~z+D$PVAIi m||kˌ#Exv=pbh?VSefA?[ ^Q``N8CL|s;O,r~ E+^͞7%y0wF1!;۽ N7%dB'=6;au߫AP"ϧi3[,VfSc'C#Y>:Dk5nٽCj"$ z[lVx߮OL1 $i)Mq02:/xE}"@RNZ^lve3tgEsOBDd+ty>(1w{zmN\tRG/_O"VvY9v˝H^c 9c Z K^$KH!ci nj c[r#qOk_Ҷj/F,^AX"! {Ḯ=#;WϞ^q[@ `| y>8 Εx#L]R(Mj`xwje5ƚrXPDM 1Cƭ0No+;wֻ8;x#~v JKN{h\./KxxA-cC!-w= >yuzyrnwK52}tKޝlڰJ+zw]קZb* ~;K?+?NojM㫵 L4s+$$bo(/vWdVuWT{ !~h7+5=?{, |K%tF FMv(箠##D1slo ~?ER"Z4y`k+w˂>acDghP~̝@shc@8(0^8V:-o >ƞ~ Ţ9Nlw?q@WdNjx׿wNR)l >Τ> ̉ovnv 6mX%\ɋf!yt B /#lFɛ9VNNz>tM1:ySR|u@AUJ>:W$vݳw9w/b+ Ǹ'0 .ZOX= zbLR `M_ԉE]E]5|dzby7@ߛSgf5T\ xy̅\^@WV fqpe[ط˗}N/ C%?鶞XVi 2$Gj~o_ΏZ73S]` HvGR65illR9eŔEQ?\:C$UIJUĢXD{7G,5}:| W򶈥!1uvl/!љ(D@>i5@1#3a0Rި'?% l7{IENDB`Ext/Icons_15_VA/KeePass_Round_Locked/KeePass_Round_Locked_48.png0000664000000000000000000000643312567602526023274 0ustar rootrootPNG  IHDR00WbKGD pHYsl IDAThŚ{tTս?gI@2 $<[SyE@A "W(UVojM+Vkۥ@EAVW$#!$}~3LD^묙ۿvJ` 0z 8>*,e>@yVѺ!! ..Ar"11Ȩ(p\T]3"jm++a9{x]k_yJYRܬ3H;!ز]D )EF>K٧/[FƄ3if[>L1'0/rp~LmYu.F!N]}JK %L(8 DQZޮ+CXOyZBtz?~eL`Kvmc空z! 3GyYr;Jsbp!Ӕk[HMMCB]ChGʟ4QB+/5)$xeɩYOq7|!yD&Z+CHIЉ30g{4s ` "f?90\Rhhh?g3h=7WAʀfPv F3y`+X&1[bE H!>/"6'.X)xݣg@6~+7\0E ,_W WP~rxe=IU| 0uga db $y , pf]jkQ1]oEFŷpiv+C|K@b$0FGFt^`% xeW Ԍp_d1tpDBE۶L Rx;X@!!::9,ijc~CWoV󪷆 Nl\m#_`;Rk?k u?!++ 6׽L7ߺn Q8Sٟ7fM00 C~./O!,")9!oB}ѷݦY:3/ M~z:K&֒ZsFϝ}r&7;supinfZf.WăD)Va 6dE:6;NdT-+yz̘2ƀܡp<=8WyI'd']Q"A-Sr;X3>3@'G=5p>:-(xYX CnUPط`y6 k37ÿDxCFǥ ^pd]@ެ;bUۑ9(#Fb}ؾcћ[} 3d*;ۚ_$2 :ŽܼQmܶ!?xP]8~s#Voxz_v;3Y82ka4[C:F1t߅Zލ 2nfV_ ZmDƥUT;m6}Zʼno'Sb?npr/V^5=0ҿCʀ5 #YG;H}}lpzX /<8;wK s? zU|}#2$xC0(ٽ3iKoieC> Ӻ&Ru@2!۷7ҁLK#ǵ nseN|p.p?{Șa(P~fh6#"CJ"`6@̾6Z]ֱ*}?ZOXrJw<|FXK}tLkbpXofw=z< x(NRw}j6 ˭tĉcme^^莈fGbUѳf :8\NXP4s | nI 0n 罭Ho'(hKǞ9e&^VnegSGu 4'sD{kVM^^Yz)G}s%֮ZN"iX glg Xx S|m!+[:UKx ]"BHMf8sO=6:]n4"R[ seƉimКG8F]}t͋gȀ<>WWw ,O}~ lq.젲m266 = HsWyY暕(`)FGL`lj:}w~?yV%|:Us76蓠F~~ 9sH`w vRz0 MA -zX1X_8e%67Ne+1{%w}o||yǬt@79Xvg ќȁM>Awd h9D1;M;-d~Ll1O ~ g8w:s7࿝@l\Bb\{ .aE_N4c3anӐ W J!?k}VT_7 ́wiIENDB`Ext/Icons_15_VA/KeePass_Round_Locked/KeePass_Round_Locked_128.png0000664000000000000000000002164312567602576023360 0ustar rootrootPNG  IHDR>abKGD pHYsؽ'_ IDATxw|TUojfCO t^&JbCе RtSuu-, De-t%@hIH I潗7-=38ޛs=s%x"́̀LPw wM1ʀӾp;U.@_$F `R\y.À@A @W;w/vY\,#pM,+u߁fQtRRROH n'>>TGqq1%%QPONQ"2x0ӳg/.m۶u6iۆ&M2Up,>|=Ydef]ٳ ~8< oWNSb2ܹ  AKZ ,}U#xfY[[ ?>K M7>̅Vq 9r0͛w@e=V , `w祗^W^ʦXG-t .pE d]V=@|DMhjrlLb_#>y]O՝̙38qFQ7|KP8\2-+K  6ɉFR H6|eYSz&1 R`hu'^H,X@=,(s% k2J&j ll:y+>Sk}ҳ @O=s/$U - ʜ؂ᅬy 5o4,sۯ3}8?UxUbN_Njڴ)-wޕL!p*Tz ï]J&Ufm WWY>K PU#7$))IP9{x~T#1$E?[P}ngϪ}xgLǂ$'M?q$^x &|KPT؅ ٹwbvNAAE\N.0̘-VxRiն3^O6$CXύF뚽^4B0޷ԚXyd*s t{ULȁ~ |,Μ:IaaAp=dRӤi+Ft]/!$?OhBUR1/0'fO1pԆ% Z^z  dYtۯ÷9vE'PQ&Wϵ&`4C?6f ,^CLvkS`^'gHΚP9v--bܸK2P .ɷzRNr)q䷍߳'ѼU nrܔ &+:;ueS |,ԤS5++رT˄s:r|{u$li6oXdž[lA+4%2 z7a]TPXp. ~USx-AxI8r>##v Mͷ+i޼zo<ス d$V>u6aFS7̠^tcc2qv99z( Lv=xdA)7 XR%.z^G,{=`T< [ fiڠ!#-_5.>$#9@nv ",wvW}VK6ɓʪUWu;z7NwOxn2v#V[|;qqt}\ݿQ G\8{_2|!Lt4H3UdK C1N~\ P<z!tLRxc9rEoT+H{> rE`+Cp 3=cmgs-)bS $$s#e/ ++-ؑtc?! Y tr!֮qվQ+M 5oƍ |j8;B[ٛC4k n0eB ?. qqH2iMZQ;DcHV#!"yX¨1j>CRm9O8BxFlh* 3a#FuUf`W#{<].ˆB@~דV/rxe:TG2ީZEG\ݻo$Bݥk^ LkL8RRѬu#>@ڭwkƎ_NgdWW\:"|ZXkGu:8gc ʊs0׍Y8 tbaԨ׺9"hXNSْ$ѡsZ/ A˶=`"; uЩ n4UgQRxy5 'NiIK³[,qoиV iD LYG\U웥$jEI))jWt͊].U%FqqZ/X0sGPR&s8ץnX\[V+C U\ZQY'$|NmyYt.|w{/0Td@ҧŊ< >H,ԓC _(5aB..0?`ܵ4q pڙ P\rG/3^)qBxrNzg7wV.P%:(jDa# ']ЫOnӣGNWeRk~0K |! w|nfWMӯzb(bf6 ZZRA2p*CQ7,t꬚# lMP n^1 c%2s۩-BYZI |Y(ZnDd|aߊҦM n };ڋ^9J1`,C9f»K^|vϹl?e!<| _~f E|0~^I}' ڴ^}f=88[yp"W 5%$fhXB5J *Ֆ9ŜBr(:&YD׎a#e'OW+jp MO?McOQ1_$mfP$EE YL<fpCpxHH >ͷzc9kptȍ7&Q_C"j& EE =nHJt> />w^5 y”tLb)qd T_@q*sA e _i ?mBE\sqpk!,R|!@})EOB::!`(/Ҽ%|5xN9a`dMۛeYZi}3\.y“'jN $ +,]R_ǪISHNH$hL @*O%H0/.YJ0pX3/%5:@rZ #һ ֆt($Kt:.;[3)A P'_i*P>W_QzRw?O0ĎU;Ri8U&8 $kQEZ ϿjF ..>KZ8r[fkVn "`K|M"O`Մ׫@5 ku_rE/ޙ2f>l%Z(0ֺ ܷ?Rbbst([4BAGPT@hyZuB/tjaNQ7Hq*-0SFt\EDzt[u-N][پU464 RwA붺OM=3f1)AZ/UHAt3BXM>5wӧkϊΖz`>׽@ZƅAe:W/qfB%?ozǚ>,&/_čQ|!=őQפ8+sc8Wk A)@\B$I i0mV{+?sU5*#l ww${cE v6|! /UHw"䱠N DM(6̆&.֍|tOVWnAQS3Fh÷X ip9L݃,nb @Пȡ@m*1g%\|OZAqصCswih9/^Wie+"&3}ʛs@#(Eïd+1Z~]U@UؗM-5_y#ul0SMOI6,2[73i{;0__/#R g8ب3e&{Z$n&;ӧl>L5旁WU Ha]{D]i oդwd>r;GdkyG%Nwl ~^}%7}MDKy#aޓnZ8 ~ijD",x^-Jٴ_%uo>` 4mp^_I"!آUa/on!ո &LQm>^Bӟ 8(ucB ~ _ۏ*^ˈdl*+?Y.ښ |JO-x`$&d|jLAt<% o1K@VVMogK2щxlzzsfG_3dCn:(+YKj@|뾈AVܘŝ-I0,\@i@pu0ZGcHCf"j _Eٱ?<2y,GWj [L,E3-ԝ:M\}mn84;@L %]l$Q/` z8My Dy%AD6 9;n ?;K ~!Jvq+v-H$#ӌd60a3:9G9|tVgE9t$> ;“aXf-B{۷leCN=w|ݷb0l[ $TH?|G_ڹ# JZQ"D[}KwoDZq7p@18zvn7u^~`ĭwkw!Z(ʿ^W_.Zd^T%Lû)>3^CL V-cŧۦ"F% "A-J͓}0†_ZȐOuq^ u{OR!sGL*@y Wւ>Eh=7vnky6m\L^UVCU'!{I^&ŵ(]HIKt=rrr@}`bp[Q͢Vrg,AK,_.Q">))iXl$% :B SVVJ~Nq,p8oV~Vv5L@M%GL/˭^Y9X' x O9DZ1 NƤDZrJNӵ>owD q#5Zֹa kߎ71I Hp0R~|=6Ha'"b z`3V@O)R|J= |Fd!bKڳc̀v62@aǻ4T3%iߑ ƻmQ7hIENDB`Ext/Icons_15_VA/ReadMe.txt0000664000000000000000000000014712567570262014200 0ustar rootrootThanks a lot to Victor Andreyenkov for creating these refined versions of Christopher Bolin's icons! Ext/Icons_15_VA/LowResIcons/0000775000000000000000000000000013062033704014471 5ustar rootrootExt/Icons_15_VA/LowResIcons/KeePass_LR.ico0000664000000000000000000012723613062022070017122 0ustar rootroot (00 nh@@ (B~!00 %c  N  ~ h6( @  "" "$DDB" "4DDDDC"DDDDDDDD $DDDDDDDDBDAD $DADB4DDDDDDDDDDC DDAADD #DDAADD2 $DDDDDDDDDDDDB $DDAADDB4DDAADDC DDDDDDDDDDDDDD DDDADDD DDDADDD DDDDDDDDDDDDDD 4DDDADDADDDC $DDDADDADDDB $DDDADDADDDB#DDDADDADDD2DDDADDADDD 4DDADDADDC $DDADDDDBDDDDDD $DDADDBDDDDDDDD "4DDDDC""#DD2" ""   ??( DD 0DDDD3333@0DDD34C3D DAD@D3333D@DD@DADDD@DADDD DA4CDD1D@0DADDD 0(0`  (  8 ( @ $$$H(8( (((@( 0((8((,,,0,,@0(000800@00H00444P8(@80H80888P80h8(@88H@8P@8H@@P@@XH@HHHxH8LHHLLLxP@XPPP@xPHX@pXPXHxXPXH\\\`P`H`Xp```XhXhXxh`h`h`xhhxphpHpppphp`pPxpppXtttxpx`xXxPxpxxxhx`xXxh||Ȁ`X|xpȀh|x`xxȈphȈxȐxpȐxȘ蘀蠀Ƞ蠈ؠ訐بȨĬȰȸļȸȼF++F""F0@JJ<0FlM~D\({(zkgggaaaaq{MqqkkkgggaaaYUPkDvttqqkkkgggaaaYUPPku zxxvttqqkkkgggaaaYUPPPz zzzxxvttqqkkkgggaaaYUPPEqzzzxxvttqqkkkgggaaaYUPPEkufRzzzxxvttqqkkkgggaaaYUPPEqDl!PPEFUPPP{L-#YUPPk(yrrrooiihetvtt^^XTTOOOKIaYUPP{9xvtaaYUPk"Z =xxvaaaYUPD4Hzxx $gaaaYU~FcBBBB???==izzx955555331:ggaaaYqF+" ?zzzgggaaaa+8 ?zzkgggaaa0L`AAAA>;;;;mz2222////,7kkgggaa<WA***)''''''''########/kkkgggaDW%qkkkgggDL%qqkkkgg< 8}ssspppjjjjdddd]]]]SSSNVtqqkkkg0+" &xvttqqkkk+F )!xxvttqqkzF )!zxxvttqqb )!zzxxvttqM  zzzxxvt"%|zzzxxv.CC66zzzx(F{pmzzzF0 nc *zfb)[nnQ'|Mf pw [G ~_DC[}bR.-lbZ\F"8L\\L8"FF++F??( @      (,04 ,$ 0$ ($$0($4($8($0((,,,0,,00,40,80,000<0,400422840P4(444<44@84888D84P80@88X<0D<8<<<X@4pD4pH8PHDtL<L8LLLXLHtL@lPDP<P<\PLtPDP@T<xTHTDxXLXHXLXL\Hx\P\Lx\T\P`P`Lx`X`Tbbbxd\dddpd`dXxd`h\hhhhXl`xlhlX|lhldpdpdtLtttthxPxpxtxxxxTxtxxxl|t|X||||x\txdhlptx|윀위전절줌쨐谜ฬĴȸȼ̼V)  )VV,33( Ql'mg$e/{)d{xvsrnnkk[{xvsrnnkbf|){xvsrnnkb_|)`h{xvsrnnkb_[eb_QkbfQ)aSSNNJKZA>>:5?nkb$t%nnkkgQ^IIGBBDW84421;rnnkV& 0srnn ) # +vsrn, 6p]]\XUUSSNJHECALxvsr}36{xvs3 &jTPPMMIIGBB@@==F{xv. &7!-{x )Q7-{Qz<0m/R 9'O~cUiV&"wo`q.TT*ydl u& Y" T qh&")`/zt)`O&66&QQ&  &Q??(      (%$)&%C()((;("0(&*));*$0*(C*";,&<-)///0//>>g?0]?5T@9hA4NA=BBBCCCDDDEEE^E=^H@`IA`LEkTLmYQg]hhhiiijZk]kkkl[lllnnnn_oooqqqrrrsmupuevqwaxQ{j|v~r~j[|}|admvߤ禍ѯ»ƶʽ˽˾̾G HC%cvrps`"D4U{e^[YSXmL5AWygda^[YSNdJD&o Nn$Fhwr/!BMSX`Hzu:76KR*)-YSs}z;98@E.+0[Yp~}1 ^[q~Z uroj ?a^vDkbxurlOdecG,| Izu<fg{'=]_QoyTC2\tVPiwW3>,kh(AD##F(@ R||Q10 rq ~($#PHEuif}{tgcOFC(#"}^g]ZeYUf"JCAG><!PQKI˻ɻﭖǯOEBV$"!읃omkhfda_][}X{VhĴ*%#vmjòxvtromkhfda_][}X{VyTxQ`ﮗrd_Ǹ}{xvtromkhfda_][}X{VyTxQvO|Xﭗﮗퟄ읂}{xvtromkhfda_][}X{VyTxQvOtMcijּ"*(';ퟄ읂}{xvtromkhfda_][}X{VyTxQvOtMsMĻ*%#T禍ퟄ읂}{xvtromkhfda_][}X{VyTxQvOtMrKuĻR#ﭖ䀹禍ퟄ읂}{xvtromkhfda_][}X{VyTxQvOtMrKjѸ"ﯙﭖ䀹禍ퟄ읂}{xvtromkhfda_][}X{VyTxQvOtMrKjbwpnǸﯙﭖ䀹禍ퟄ읂}{xvtromkhfda_][}X{VyTxQvOtMrKurd_]&$#`G>                              \0"xQvOtMrK朗(#!XA9T-yTxQvOtMsMij} RNMǷXB:T. {VyTxQvOtMbOEB tdLC                              `5&}X{VyTxQvOtMﭗɱrIFEȹ²ﯙﭖ䀹禍ퟄ읂}{xvtromkhfda_][}X{VyTxQvO{WG><4ƶĴ²lSJ9'!ퟄ읂o[""""""""""""k<,][}X{VyTxQvOﮗ0ȹƶĴ²XD>ퟄ읂iVU0#_][}X{VyTxQ_ied˽ʻȹƶĴ²XE>ퟄjXU1$a_][}X{VyTxQĴdXT˽ʻȹƶĴ²ZG@!kYU2%da_][}X{VyTS˽ʻȹƶĴ²ﯙﭖ䀹禍젅蜁}{yvtrpmkigfda_][}X{VhQ+))˽ʻȹƶĴgRK   2$禍ta      f=/hfda_][}X{V(#"|RPO˽ʻȹƶYGB䀹禍o^U3(khfda_][}XNEByvu˽ʻȹYHBﭖ䀹禍p_U4(mkhfda_][tgc˽ʻ`NI            (ﯙﭖ䀹禍sbX6+omkhfda_]z˽ʻȹƶĴ²ﯙﭖ䀹禍ퟄ읂}{xvtromkhfda_n\U   jC5tromkhfdaYKFV7,vtromkhfdYKGV7-xvtromkhfZLGV8.{xvtromkhﭗ|yxw˽ʻȹƶĴ²ﯙﭖ䀹禍ퟄ읂}{xvtromktieSQQw^MGƶĴ²ﯙﭖ䀹[A8 eUퟄ읂}{xvtromɻNGD,++~w_OIȹƶĴ²ﯙﭖ\B9cTퟄ읂}{xvtro)%$}Tx`OJʻȹƶĴ²ﯙ]C:cTퟄ읂}{xvt읃Ry`PK˽ʻȹƶĴ²]D<dUퟄ읂}{xvlkj|_PK˽ʻȹƶĴ²^E<eVퟄ읂}{xg]ZTGC˽ʻȹƶĴ²Q<5ziퟄ읂}좇5ٿ;30˽ʻȹƶĴ²9+&ӗ禍ퟄ읂ò1LKK ٺ˽ʻȹƶĴ²ӡ ꪓ䀹禍ퟄJCAtQHEj\W˽ʻȹƶĴ²gOGO:3ﯙﭖ䀹禍Ǹ̼rUTT{vŪ˽ʻȹƶĴ²dXﯙﭖ䀹禍ﮗQKI *&$0*(ڼ˽ʻȹƶĴ²ث.$!*讚ﯙﭖ䀹禍~***}x*$#˽ʻȹƶ)!g]ﯙﭖ䀹禍ʻ(%$dzyyF@= SHD}ʽöwRC> E61ﯙﭖvmj_1,*&!& 0&#௞#ҿ7106+(Σ"U!!!RJHRB=纫²ǸY,,,>86>4/ȹƶĴ²*(' sfbE=:3-+3,)E;7sb\˽ʻȹƶĴ²Ǹ#!!˽ʻȹƶǹzyy˽wpn&&&*((QUTTQMLX$LKKIFE#^kjiiedo+**SQQxwvxutRPO+))tt 54T~S????(0` WWlk 61/\SPrfc~ql~plreaZQM5/. o'$#tpIJí~pk'"!%KDBǸƸ˽H?<$P0,+³淚sjgda^[_wﯗ.(&N`~urﬕzvspmjgda^[|XzTyRo|mhgf잂|yvspmjgda^[|XzTxQuNmʻ dQ;잂|yvspmjgda^[|XzTxQuNtMʲN$ ±禍잂|yvspmjgda^[|XzTxQuNsKz̴ 'ﮘﬕ禍잂|yvspmjgda^[|XzTxQuNsKowywȹﮘﬕ禍잂|yvspmjgda^[|XzTxQuNsKy|mhs1/.I6/                      F%xQuNsKﭖ/)'ƼB1+?"zTxQuNuNɺMJI̿M93                      I(|XzTxQuNmH?<mļijפ˙ʗʕʓʑ~ʎ{ɍyɋvȉsߗ}잂|̂iˀf~c{az^x[uYtVqTtU[|XzTxQuNj*((ƶijB3.aR잂?$^[|XzTxQp'"!˼ȹƶijB4/cT잂@%a^[|XzTyR~pkY˼ȹƶijoXO=/+=/*<.)<-(<-(<,'<,&<+%<*%ud8&7$6#6#6"6"6!6!6 h=.da^[|XzTﯗíV˼ȹƶijylbj`i^h]f[eYdXbVaTƌy^N\L[JYHXGVEUCTAR@bJgda^[|Xx :87˼ȹƶC61gY禍@'jgda^[`5/._]\˼ȹC62h[ﬕ禍@'mjgda^[[QNurr˼{i`h_f]e\dZbXaW`U_TĐ~ﮘﬕ禍zVIyTGySEyRDxQBxOAxN?xL>xK<^Jpmjgda^̽pd`}}kdTE@TD?TD>TC=TB8S>7S=5R<4R;3R:2R:1R90R8/R7.Q7-Q5,Q5+Q4*|N>spmjgdaǸ}ok~}C85A)!vspmjgdȺ}pkussD96A*"yvspmjgpea_^^ʬ}{yvtrpm}k|iyfxdvah|yvspmj\SP:99 L>:ƶijﮘﬕJ4-  잂|yvsps61/PB=ȹƶijﮘL70잂|yvs轢 ZPB>˼ȹƶijL81잂|yvIJWMB>˼ȹƶijL71잂|ztp***,&%=41˼ȹƶij;,'+禍잂ﬕ'$#nD;9ĸ˼ȹƶij߫ B0*ﬕ禍잂kONNykh{je˼ȹƶijw\RuWLﮘﬕ禍JCBȴ ˼ȹƶij Ēﮘﬕ禍³333_UR"˼ȹƶ|^H@ﮘﬕ禍̽0,+x*%%ODA|uwnN@;* ٧ﮘ±~urt$μ7207-)ˤȹ¾(S|w2-+2*'phŶƶijPgį||mh|lf}wŨ˼ȹƶij̿m`˼ywhS333Ƽ1/.Q'ONNļMJI&o+***((:99_^^vtt~~~vss_]\977nmZY????( @ WV ?97SJGSJG>75":53{ſ׿zt82/*'&ʻﱛzv움0*(.xuvrmhd_[{V|V|mh- ퟄ{vrmhd_[{VxQzT Ƿ禍ퟄ{vrmhd_[{VxQtM힄zx˽ﭖ禍ퟄ{vrmhd_[{VxQtMퟄ|mh%.,+1$ /xQtM1+)"±4'"2{VxQyT ;98²vieYcWaT_R]O`QퟄnYUDRAQ>N[{VxQ82/ X˽ƶ²," ퟄP4+*_[{V|VytUʻƶ²rgy^Uy\RxZPxYNxWK[NjXtL>sKKK>6@[K}GQ/zw+wK||xGr||xxh ||xxx ||xxut||xxuhVN||xxuG[(%xxu@$|xxxwC1-%||xx+vvsssqqqpnnjjjggggk||xxw&I||x#Q&J||xG;$$$$$$$$$Z7||}@^MMMMJJJJJqIFFFFFBBBU|@.#&J".9&J"8C\HHHHDDDDDo====<<<<:L> OH444440000000--------** 9~mmmiiiffffbbbbaaa````]e8.# ,( .@ 2(@ 2(S /(K&!)$z3AE??+@ wlo@8c_ 5VS2WddT0KVz ir { RP }YGGXytSN31[SQQ@#9CQQC9#@@..@??( @      (,0 , (,( 0 ,,,4$0$(0($4$000.2.,4,$8$242.6.444,8,0808888:84<4<<<4@48@84D48D8(P(0T0LLLDPD0X04X4HXHL\L4p48p8DlDbbbddd&  &>>+44*:Z(d`%T)uw&[Rs}~p&r}|q&N]}|RT}|:y}~w:'gVVSSQWjKHHFDX}%h.`:bCCBBAJf<;;76L>#3& ! /+ 0k^^^\YYVSSQOOMKa101 #eIGGEECCBAA??==U+ #4% 2&:4$ 3:i53d)@ 8(9q_\mz>#" nl Ncz -II, v[Ztuos# xP% $Is c]#{&N)ih'N9#00#::#  #:??(       $($%)%()()*)&0&(0(////0/010222";"$;$&;&/8/)<)585+<+1:1-<-4:4C"C"5<58;8)C)+C+>>>(K(BBBCCCDDDEEE$S$=N=9T9.\.2\25]5=^=@^@A`A0g0E`E4h4LkLQmQhhhiiikkklllnnnoooqqqrrr]]mmppqq]]||}}vvZZ__[[||rreejjaajjQQ[[aaddѣmmߐvvջA B> ZtsqpY?+Izieca_`mF,=Jxjhfeca_^hE?|o  ^n@\ws/&%NV"!-_`YByu943SX106a_p{y:75GM218caq}{.(ecs}T usol Lfet?][vuskUhiZA'rDyuCdjz#;QWRoxH>)PgOKbw~J*<']\$=?@(@ R||Q10 rq ~#(#EPEfuf}}{{ctcCOC"("}^ZgZUeUf"AJA`>                              "\"QQOOMMKK!(!9X9TTTQQOOMMMM} MRM:X: T VVTTQQOOMMbbBOB tʾCdC                  &`&XXVVTTQQOOMMɩrEIE}}{{xxvvttrroommkkhhffddaa__]][[XXVVTTQQOOWWX>VV#U#__]][[XXVVTTQQ__did>X>XX$U$aa__]][[XXVVTTQQTdT@Z@!YY%U%ddaa__]][[XXVVTTS}}{{yyvvttrrppmmkkiiggffddaa__]][[XXVVhhQ)+)KgK    2aa       /f/hhffddaa__]][[XXVV"("|OROBYB^^(U(kkhhffddaa__]][[XXBNBuyuBYB__(U(mmkkhhffddaa__]][[ctcI`I            (bb+X+oommkkhhffddaa__]]zz}}{{xxvvttrroommkkhhffddaa__UnU   5j5ttrroommkkhhffddaaFYF,V,vvttrroommkkhhffddGYG-V-xxvvttrroommkkhhffGZG.V.{{xxvvttrroommkkhh||wyw}}{{xxvvttrroommkketeQSQwwG^G8[8  UU}}{{xxvvttrroommDND+,+wwI_I9\9TT}}{{xxvvttrroo$)$}TxxJ`J:]:TT}}{{xxvvttRyyK`K<]<UU}}{{xxvvjlj||K_K<^<VV}}{{xxZgZCTC5Q5ii}}5ٸ0;0&9&ӂ1KLK ٯӐ AJAtEQEWjWGgG3O3̶rTUTvvšXXIQI $*$(0(ڲ؜!.!*~***xx#*#)]]$($dyzy=F= DSD}}ww>R> 1E1jvj_*1*&&#0##ҹ070(6(Γ"U!!!HRH=R=Y,,,6>6/>/'*' bsb:E:+3+)3)7E7\s\!#!yzynwn&&&(*(QTUTLQLX$KLKEIE#^ikidido*+*QSQvxvtxtORO)+)tt 54T~S????(0` WWlk  /6/P\Pcrcl~ll~laraMZM.5.  o#'#ppĭæk~k!'!%BKBx>T>=T=|>ssppmmjjggddaak}k}}5C5!A!vvssppmmjjggddk}ksus6D6"A"yyvvssppmmjjggapa^_^ʢ}}{{yyvvttrrppmmkkiiffddaahh||yyvvssppmmjjP\P9:9 :L:-J-  ||yyvvssppss/6/=P=0L0||yyvvss  Z>P>1L1||yyvvĭW>M>1L1||zzpp***%,%1=1';'+#'#n9D9ߘ  *B*kNONhyhe{eRwRLuLBJBȮ  ā®333R_R"||@^@+0+x%*%AOAuunn;N;*ٖr~rt$ε070)7)˖о(Sww+2+'2'hhνPgĩ||h|hf|fwwŞm`wwhS333ƺ.1.Q'NONĺIMI&o*+*(*(9:9^_^tvt~~~~svs\_\797nmZY????( @ WV 7?7GSGGSG5>5"3:3{{ٿ׷tt/8/&*&zzvv(0(.uuvvrrmmhhdd__[[VVVVh|h- {{vvrrmmhhdd__[[VVQQTT {{vvrrmmhhdd__[[VVQQMMxx{{vvrrmmhhdd__[[VVQQMMh|h%+.+ 1 /QQMM)1)""4"2VVQQTT 8;8iiYYWWTTRROOQQYYDDAA>><<99>>[[VVQQ/8/ X,  +P+*__[[VVVVttUggUyURyRPxPNxNKxKNNXX>t>#@~yyhccc[[[6P`BBBB?????j~~y777733333:hhccc[[A ZB00000,,,,,,,'''''''' 3hhhccc[HZ)mhhhcccHP*mmhhhccA >}tttqqqqiiidddd]]]TTTTNXsmmhhhc61( +~~% usssmmhhh"1M /~%uusssmmhyM /%yuusssmme .%yyuusssmO$#yyyuuss~(*{~yyyuus4GE;;~~yyyu-M |nj~~yyyM$6la 0~~yfe/WppS,{~Of q"w UK _HH\zeV$42oe^^M(>P^^P>(M$$M11M??( @   (,04 , 0$$0$$4$$8((,((0,,,,,4,,8..2000((P00400822444444<44@44D00T88888:88@88D04X44X<<<44p88pDDP<cc]#s~!jcccfR^IIFFCDU64421:ojccV% /pojc* $ )rpoj|, 9nZZZWTTPLLHEEBAJurpoy39yurp{3 %iSNNMMIIFCC@@<>>56]99T45h==NBBBCCCDDD==^EEE@@^AA`EE`LLkQRm]]ZZ]]hhhiii[[kkk__lllnnnoooqqqQRrrrmmeeabppqqjj[[jjvvrsab||}}||demnvwF! HC%cuqor`"D3Uzd]YWOSkM5AXxfb_]YWOGbLD&~n Gm$Egvq.@KOS`Hyt964JP*(+WOr|y:87=B-*/YWo}|0 ]Yp}Z tqni <_]uDlawtqjNbdcF,{ Iyt;efz'>\^RnxTC1[sVQhvX2?,lg)AD##E(@ R||Q10 rq ~##(EEPffu}}{{cctCCO""(}^ZZgUUef"AAJ<>`                              ""\QROPMNKL!!(9:X TTUQROPMNMN} MMR::X TVWTUQROPMNbcBBO tCCd                  &&`XYVWTUQROPMNrEEI}~{{xyvwturropmnkkhifgdeab_`]^[[XYVWTUQROPWX<>XVV#$U_`]^[[XYVWTUQR_`ddi>>XXX$%Uab_`]^[[XYVWTUQRTTd@AZ!YZ%&Udeab_`]^[[XYVWTUS}}{|yyvwtursppmnkliighfgdeab_`]^[[XYVWhiQ))+KKg   2ab      //fhifgdeab_`]^[[XYVW""(|OORBBY^^((Ukkhifgdeab_`]^[[XYBBNuuyBCY_`()Umnkkhifgdeab_`]^[[cctII`            (bb++Xopmnkkhifgdeab_`]^zz}~{{xyvwturropmnkkhifgdeab_`UVn   56jturropmnkkhifgdeabFFY,,VvwturropmnkkhifgdeGGY--VxyvwturropmnkkhifgGGZ..V{{xyvwturropmnkkhi||wwy}~{{xyvwturropmnkkeetQQSwwGG^88[ UU}~{{xyvwturropmnDDN++,wwII_99\TT}~{{xyvwturrop$$)}TxxJJ`:;]TT}~{{xyvwtuRyyKK`<<]UV}~{{xyvwjjl||KK_<<^VW}~{{xyZZgCCT55Qii}~500;&&91KKL AAJtEEQWWjGGg33OrTTUvwXXIIQ $$*((0!".*~***xx##*)]]$$(dyyz==F DDS}~ww>>R 11Ejjv_**1&&##0#007((6"U!!!HHR==RY,,,66>/0>''* bbs::E++3))378E\\s!!#yyznnw&&&((*QTTULLQX$KKLEEI#^iikddio**+QQSvvxttxOOR))+tt 54T~S????(0` WWlk //6PP\ccrll~ll~aarMMZ..5 o##'ppkk~!!'%BBK<>x<=xJKpqmnjkghdeab^_``p}}dd@@T??T>>T==T<?|stpqmnjkghdeabkk}}}55C!!Avwstpqmnjkghdekk}ssu66D""Ayzvwstpqmnjkghaap^^_}}{{yyvvttrrppmmkkiifgddabhi|}yzvwstpqmnjkPP\99: ::L--J  |}yzvwstpqst//6=>P00L|}yzvwst Z>>P11L|}yzvwW>>M11L|}z{pp***%%,11='';+##'n99D **BkNNOhhyee{RRwLLuBBJ  333RR_"|}@@^++0x%%*AAOuuno;;N*rr~t$007))7(Sww++2''2hiPg||hh|ff|wwm`wwhS333..1Q'NNOIIM&o**+((*99:^^_ttv~~~~ssv\\_779nmZY????( @ WV 77?GGSGGS55>"33:{{tt//8&&*z{vw((0.uuvwrrmnhide_`[[VWVWhh|- {{vwrrmnhide_`[[VWQRTU {{vwrrmnhide_`[[VWQRMNxx{{vwrrmnhide_`[[VWQRMNhh|%++. 1/QRMN))1""#42VWQRTU 88;iiYZWWTURROPQQYYDDAA>?<<9:>?[[VWQR//8 X, ++P*_`[[VWVWttUghUUyRRyPPxNNxKLxNNXY>?t<-0&)yzzxxxwwwussrrrppppn$M! L$O!C9#########[8v;]PPPPOOOOOwMKKKKKJJJZ;* $O"*7$O"6>\EEEEDDDDDm????====(": 7}hhhgggfffffcccbbbaaaa`l6* +' *; 2'; 2'vN ,'F$ {(#o.AB@@); nkmo;6_^ 5SN2VddU1FSqo ki| RQ qvXCCWtjNG.{y-YNLI; 7>II>7 ;;**;??( @    ((,, ,,(,,,,,00 00$00(00000.2244$44,44244444.66$88,880888888::,<<4<<<<<4@@8@@4DD8DDLLL(PPDPP0TT0XX4XXHXXL\\bbbdddhhhDll4pp`pp===;W}9!4&  2, /j\\\[ZZYYVUTTSQg1/1 !eGFFEEDDCBBAA??_, !5(#3&85$#4~8f64a*< :)7|p][n{9!" lk @X{ .GG- yPKrvst! uI% $Gt XR!|z&@*fc'@7!//!88!  !8??(     $((%))()))**///&00(00/00011222/88588";;$;;1::&;;4::)<<+<<8;;-<<5<<>>>CC"CC)CC+CCBBBCCCDDDEEE(KK=NN$SS9TT.\\2\\5]]=^^@^^A``E``0gg4hhhhhLkkiiiQmmkkklllnnnoooqqqrrr]pmq|}]v|Z_[rejajQ[admvA B>YqtsmW?*HzjfedbcoF+=IxlihfedbaiD?}r  ap@[wt/'&QX%$.bcWB|yv:43T\107dbm{y<65JP218eds~{-!,fet~S vtrn Ohfq?]ZuvtkVijYA#gEyvC`lz"9MURrxG>(K_NL^wI);#]|[ =?@(@ R||Q10 rq ~#((EPPfuu}{cttCOO"((}^ZggUeef"AJJ``                              "\\QOMK!((9XXTTTQOMM} MRR:XX TTVTQOMbBOO tCdd                 &``XVTQOMrEII}{xvtromkhfda_][XVTQOWXXV#UU_][XVTQ_dii>XXX$UUa_][XVTQTdd@ZZ!!Y%UUda_][XVTS}{yvtrpmkigfda_][XVhQ)++Kgg   22a      /ffhfda_][XV"((|ORRBYY^(UUkhfda_][XBNNuyyBYY_(UUmkhfda_][cttI``            ((b+XXomkhfda_]z}{xvtromkhfda_Unn   5jjtromkhfdaFYY,VVvtromkhfdGYY-VVxvtromkhfGZZ.VV{xvtromkh|wyy}{xvtromkettQSSwG^^8[[ U}{xvtromDNN+,,wI__9\\T}{xvtro$))}TxJ``:]]T}{xvtRyK``<]]U}{xvjll|K__<^^V}{xZggCTT5QQi}50;;&991KLL AJJtEQQWjjGgg3OOrTUUvXIQQ $**(00!..**~***x#**))]$((dyzz=FF DSS}w>RR 1EEjvv_*11&&&&#00#077(66"U!!!HRR=RRY,,,6>>/>>'** bss:EE+33)337EE\ss!##yzznww&&&(**QTUULQQX$KLLEII#^ikkdiio*++QSSvxxtxxORR)++tt 54T~S????(0` WWlk /66P\\crrl~~l~~arrMZZ.55 o#''pk~~!''%BKKxxTT=TT||spmjgdak}}}5CC!AAvspmjgdk}}suu6DD"AAyvspmjgapp^__}{yvtrpmkifdah|yvspmjP\\9:: :LL-JJ  |yvsps/66=PP0LL|yvs Z>PP1LL|yvW>MM1LL|zp***%,,1==';;++#''n9DD *BBkNOOhyye{{RwwLuuBJJ  333R__""|@^^+00x%**AOOun;NN**r~~t$077)77(Sw+22'22hPg|h||f||wm`whS333.11Q'NOOIMM&o*++(**9::^__tvv~~svv\__799nmZY????( @ WV 7??GSSGSS5>>"3::{t/88&**zv(00.uvrmhd_[VVh||- {vrmhd_[VQT {vrmhd_[VQMx{vrmhd_[VQMh||%+.. 11//QM)11""4422VQT 8;;iYWTROQYDA><9>[VQ/88 X,, +PP**_[VVtUgUyyRyyPxxNxxKxxNX>tt Ext/KeePass.iss0000664000000000000000000002302713225117352012376 0ustar rootroot; KeePass Password Safe Installation Script ; SEE THE DOCUMENTATION FOR DETAILS ON CREATING INNO SETUP SCRIPT FILES! ; Thanks to Hilbrand Edskes for installer improvements. #define MyAppNameShort "KeePass" #define MyAppNameShortEx "KeePass 2" #define MyAppName "KeePass Password Safe" #define MyAppNameEx "KeePass Password Safe 2" #define MyAppPublisher "Dominik Reichl" #define KeeVersionStr "2.38" #define KeeVersionStrWithMinor "2.38" #define KeeVersionStrWithMinorPath "2.38" #define KeeVersionWin "2.38.0.0" #define KeeVersionWinShort "2.38" #define MyAppURL "https://keepass.info/" #define MyAppExeName "KeePass.exe" #define MyAppUrlName "KeePass.url" #define MyAppHelpName "KeePass.chm" #define KeeDevPeriod "2003-2018" #define MyAppId "KeePassPasswordSafe2" [Setup] AppName={#MyAppName} AppVersion={#KeeVersionWinShort} AppVerName={#MyAppName} {#KeeVersionStrWithMinor} AppId={#MyAppId} AppPublisher={#MyAppPublisher} AppPublisherURL={#MyAppURL} AppSupportURL={#MyAppURL} AppUpdatesURL={#MyAppURL} AppCopyright=Copyright (c) {#KeeDevPeriod} {#MyAppPublisher} MinVersion=5.0 DefaultDirName={pf}\{#MyAppNameEx} DefaultGroupName={#MyAppNameEx} AllowNoIcons=yes LicenseFile=..\Docs\License.txt OutputDir=..\Build\KeePass_Distrib OutputBaseFilename={#MyAppNameShort}-{#KeeVersionStrWithMinorPath}-Setup Compression=lzma2/ultra SolidCompression=yes InternalCompressLevel=ultra UninstallDisplayIcon={app}\{#MyAppExeName} AppMutex=KeePassAppMutex,Global\KeePassAppMutexEx SetupMutex=KeePassSetupMutex2 VersionInfoVersion={#KeeVersionWin} VersionInfoCompany={#MyAppPublisher} VersionInfoDescription={#MyAppName} {#KeeVersionStr} Setup VersionInfoCopyright=Copyright (c) {#KeeDevPeriod} {#MyAppPublisher} WizardImageFile=compiler:WizModernImage-IS.bmp WizardSmallImageFile=compiler:WizModernSmallImage-IS.bmp DisableDirPage=auto AlwaysShowDirOnReadyPage=yes DisableProgramGroupPage=yes AlwaysShowGroupOnReadyPage=no [Languages] Name: english; MessagesFile: compiler:Default.isl Name: brazilianportuguese; MessagesFile: compiler:Languages\BrazilianPortuguese.isl Name: catalan; MessagesFile: compiler:Languages\Catalan.isl Name: czech; MessagesFile: compiler:Languages\Czech.isl Name: danish; MessagesFile: compiler:Languages\Danish.isl Name: dutch; MessagesFile: compiler:Languages\Dutch.isl Name: finnish; MessagesFile: compiler:Languages\Finnish.isl Name: french; MessagesFile: compiler:Languages\French.isl Name: german; MessagesFile: compiler:Languages\German.isl Name: hungarian; MessagesFile: compiler:Languages\Hungarian.isl Name: italian; MessagesFile: compiler:Languages\Italian.isl Name: norwegian; MessagesFile: compiler:Languages\Norwegian.isl Name: polish; MessagesFile: compiler:Languages\Polish.isl Name: portuguese; MessagesFile: compiler:Languages\Portuguese.isl Name: russian; MessagesFile: compiler:Languages\Russian.isl ; Name: slovak; MessagesFile: compiler:Languages\Slovak.isl Name: slovenian; MessagesFile: compiler:Languages\Slovenian.isl Name: spanish; MessagesFile: compiler:Languages\Spanish.isl [Tasks] Name: FileAssoc; Description: {cm:AssocFileExtension,{#MyAppNameShort},.kdbx} Name: DesktopIcon; Description: {cm:CreateDesktopIcon}; GroupDescription: {cm:AdditionalIcons}; Flags: unchecked Name: QuickLaunchIcon; Description: {cm:CreateQuickLaunchIcon}; GroupDescription: {cm:AdditionalIcons}; Flags: unchecked [Components] Name: Core; Description: Core KeePass Application Files; Flags: fixed; Types: full compact custom Name: UserDoc; Description: Help Manual; Types: full custom Name: KeePassLibC; Description: Native Support Library (KeePass 1.x); Types: full custom ; Name: NativeLib; Description: Native Crypto Library (Fast Key Transformations); Types: full custom Name: XSL; Description: XSL Stylesheets for KDBX XML Files; Types: full custom Name: NGen; Description: Optimize KeePass Performance; Types: full custom; ExtraDiskSpaceRequired: 1048576 Name: PreLoad; Description: Optimize KeePass On-Demand Start-Up Performance; Types: full custom; ExtraDiskSpaceRequired: 2048 ; Name: FileAssoc; Description: {cm:AssocFileExtension,{#MyAppNameShort},.kdbx}; Types: full custom [Dirs] Name: "{app}\Languages"; Flags: uninsalwaysuninstall Name: "{app}\Plugins"; Flags: uninsalwaysuninstall [Files] Source: ..\Build\KeePass_Distrib\KeePass.exe; DestDir: {app}; Flags: ignoreversion; Components: Core Source: ..\Build\KeePass_Distrib\KeePass.XmlSerializers.dll; DestDir: {app}; Flags: ignoreversion; Components: Core Source: ..\Build\KeePass_Distrib\KeePass.exe.config; DestDir: {app}; Flags: ignoreversion; Components: Core Source: ..\Build\KeePass_Distrib\KeePass.config.xml; DestDir: {app}; Flags: onlyifdoesntexist; Components: Core Source: ..\Build\KeePass_Distrib\License.txt; DestDir: {app}; Flags: ignoreversion; Components: Core Source: ..\Build\KeePass_Distrib\ShInstUtil.exe; DestDir: {app}; Flags: ignoreversion; Components: Core Source: ..\Build\KeePass_Distrib\KeePass.chm; DestDir: {app}; Flags: ignoreversion; Components: UserDoc Source: ..\Build\KeePass_Distrib\KeePassLibC32.dll; DestDir: {app}; Flags: ignoreversion; Components: KeePassLibC Source: ..\Build\KeePass_Distrib\KeePassLibC64.dll; DestDir: {app}; Flags: ignoreversion; Components: KeePassLibC ; Source: ..\Build\KeePass_Distrib\KeePassNtv32.dll; DestDir: {app}; Flags: ignoreversion; Components: NativeLib ; Source: ..\Build\KeePass_Distrib\KeePassNtv64.dll; DestDir: {app}; Flags: ignoreversion; Components: NativeLib Source: ..\Build\KeePass_Distrib\XSL\KDBX_Common.xsl; DestDir: {app}\XSL; Components: XSL Source: ..\Build\KeePass_Distrib\XSL\KDBX_DetailsFull_HTML.xsl; DestDir: {app}\XSL; Components: XSL Source: ..\Build\KeePass_Distrib\XSL\KDBX_DetailsLight_HTML.xsl; DestDir: {app}\XSL; Components: XSL Source: ..\Build\KeePass_Distrib\XSL\KDBX_PasswordsOnly_TXT.xsl; DestDir: {app}\XSL; Components: XSL Source: ..\Build\KeePass_Distrib\XSL\KDBX_Tabular_HTML.xsl; DestDir: {app}\XSL; Components: XSL [Registry] ; Always unregister .kdbx association at uninstall Root: HKCR; Subkey: .kdbx; Flags: uninsdeletekey; Tasks: not FileAssoc Root: HKCR; Subkey: kdbxfile; Flags: uninsdeletekey; Tasks: not FileAssoc ; Register .kdbx association at install, and unregister at uninstall Root: HKCR; Subkey: .kdbx; ValueType: string; ValueData: kdbxfile; Flags: uninsdeletekey; Tasks: FileAssoc Root: HKCR; Subkey: kdbxfile; ValueType: string; ValueData: KeePass Database; Flags: uninsdeletekey; Tasks: FileAssoc Root: HKCR; Subkey: kdbxfile; ValueType: string; ValueName: AlwaysShowExt; Flags: uninsdeletekey; Tasks: FileAssoc Root: HKCR; Subkey: kdbxfile\DefaultIcon; ValueType: string; ValueData: """{app}\{#MyAppExeName}"",0"; Flags: uninsdeletekey; Tasks: FileAssoc Root: HKCR; Subkey: kdbxfile\shell\open; ValueType: string; ValueData: &Open with {#MyAppName}; Flags: uninsdeletekey; Tasks: FileAssoc Root: HKCR; Subkey: kdbxfile\shell\open\command; ValueType: string; ValueData: """{app}\{#MyAppExeName}"" ""%1"""; Flags: uninsdeletekey; Tasks: FileAssoc ; [INI] ; Filename: {app}\{#MyAppUrlName}; Section: InternetShortcut; Key: URL; String: {#MyAppURL} [Icons] ; Name: {group}\{#MyAppName}; Filename: {app}\{#MyAppExeName} ; Name: {group}\{cm:ProgramOnTheWeb,{#MyAppName}}; Filename: {app}\{#MyAppUrlName} ; Name: {group}\Help; Filename: {app}\{#MyAppHelpName}; Components: UserDoc ; Name: {group}\{cm:UninstallProgram,{#MyAppName}}; Filename: {uninstallexe} Name: {commonprograms}\{#MyAppNameShortEx}; Filename: {app}\{#MyAppExeName} Name: {userdesktop}\{#MyAppNameShortEx}; Filename: {app}\{#MyAppExeName}; Tasks: DesktopIcon Name: {userappdata}\Microsoft\Internet Explorer\Quick Launch\{#MyAppNameShortEx}; Filename: {app}\{#MyAppExeName}; Tasks: QuickLaunchIcon [Run] ; Filename: {app}\KeePass.exe; Parameters: -RegisterFileExt; Components: FileAssoc Filename: {app}\ShInstUtil.exe; Parameters: net_check; WorkingDir: {app}; Flags: skipifdoesntexist skipifsilent Filename: {app}\ShInstUtil.exe; Parameters: preload_register; WorkingDir: {app}; StatusMsg: "Optimizing KeePass on-demand start-up performance..."; Flags: skipifdoesntexist; Components: PreLoad Filename: {app}\ShInstUtil.exe; Parameters: ngen_install; WorkingDir: {app}; StatusMsg: "Optimizing KeePass performance..."; Flags: skipifdoesntexist; Components: NGen Filename: {app}\{#MyAppExeName}; Description: {cm:LaunchProgram,{#MyAppNameShort}}; Flags: postinstall nowait skipifsilent [UninstallRun] ; Filename: {app}\KeePass.exe; Parameters: -UnregisterFileExt Filename: {app}\ShInstUtil.exe; Parameters: preload_unregister; WorkingDir: {app}; Flags: skipifdoesntexist; RunOnceId: "PreLoad"; Components: PreLoad Filename: {app}\ShInstUtil.exe; Parameters: ngen_uninstall; WorkingDir: {app}; Flags: skipifdoesntexist; RunOnceId: "NGen"; Components: NGen ; Delete old files when upgrading [InstallDelete] Name: {app}\{#MyAppUrlName}; Type: files Name: {app}\XSL\KDBX_DetailsFull.xsl; Type: files Name: {app}\XSL\KDBX_DetailsLite.xsl; Type: files Name: {app}\XSL\KDBX_PasswordsOnly.xsl; Type: files Name: {app}\XSL\KDBX_Styles.css; Type: files Name: {app}\XSL\KDBX_Tabular.xsl; Type: files Name: {app}\XSL\TableHeader.gif; Type: files Name: {group}\{#MyAppName}.lnk; Type: files Name: {group}\{cm:ProgramOnTheWeb,{#MyAppName}}.lnk; Type: files Name: {group}\Help.lnk; Type: files Name: {group}\{cm:UninstallProgram,{#MyAppName}}.lnk; Type: files Name: {group}; Type: dirifempty Name: {userdesktop}\{#MyAppName}.lnk; Type: files Name: {userappdata}\Microsoft\Internet Explorer\Quick Launch\{#MyAppName}.lnk; Type: files ; [UninstallDelete] ; Type: files; Name: {app}\{#MyAppUrlName} Ext/Icons_04_CB/0000775000000000000000000000000012606740430012242 5ustar rootrootExt/Icons_04_CB/plockb.ico0000664000000000000000000006117610062570676014232 0ustar rootroot 00h ( 00 h^"00 %'  nM h^(0`pwwpwvpxHΈ|pȇ|숏@茌xϏ|~@p舌x~쌌xw~wwLj@DD@@D@`@@p  Ȉx@ABBP`@$Έxxwwwwg|||@@@D||@0@ @wΏpgGRWawGGElpwvwevwgegG~wp@@|@PB@$xχwwwwwwwwWlgFteDdFDFD$W|~x A&`pB@!@Gxxxxwx|p@FDxp`'p@Gxxt wwpxt(x@`dxȌxA$菆p@xrt`FBxpaVa8@hpaAgwwphpxvgxvppPp??( @pww@pHvhwxxp@ww|Ljpp퇈xw|@D@@@DF\@@pogwwxwgGȄ@H|pgwgxgVu@@H~|RHxpwwwvvwwgwp@@@@@@Dpwwwwwwgwwx`@hw|Cp@x~@x@xxpH`p$Ah@pgt$xp@`'@ppgtpwwppG??( pww~xwxx|p@D`we'vGwGGtFȄxpwed4tOpxHhx@G@wxp4p(0`      !% 3$!!!&#"%$#%%%+%#.(&/+*<,'1-,70.81/333720666831;42976?75999R/#R1%R5+S8.@:9@=<T;3T?8UB;YC;BBBLFDTF@THD[JDVLHWOLZOLWPMZPM^PLWUT\ZYsPCm_Zq\UmmmygayictttJ3M;O8P>P:TCYJUA]J^R^EbUfZi_i^n^cFeJiNhQmXmSmQp[qYsYjbmbpgrjtfwswqxszu~yvcxf{e~iqOsLvPxRzU|V}Y{|}mrw|[]ډm̉rӌtΒ}ږ~`bdfikmps{x}˝՗Ӛᝆ읂٨㦑ﮘȰİȰͳʹԷʶʹɺϿ׾ػ൥½½¹ǿõŻŸɿ±óijĴŵǸȹ˼̾<,,<!?6aa3 ?qc,61,&ٳ~vnlll ƥ~~vvnllljj~q֥~~~nvllljjjl簈~~vnnlljjji}٬~~vnllljjiij,ְ~~vvllkkjiii,尰~~~vnlljjiiiq&򳳱   @iii?Ƴ  @iii~?7Ƴ  @kkji3uuttssrggfxXUURRQPPPhkkkil zT @mmkkj zW Bvmmkko****))))%)|f%$$#####"J}vmmlk<[[NNLLLLIIyFEEEECCCAV}}}mml <,8 |d  G~}mvm6, e G~~}vvva]][][[NNLL{IIIFFFCECY~}vv/..*.****)))))%%%%%#%%#S~vv   Hv H娧uuutttrrrffza,8 ZƳ %6,< .ij 9 </ ^ Oa + q!! 6Ʃ ! L I8a : ij4? ; 0ij?,a  ij'& = Mij,  0, 0-  >oo,&,87,'?88?!<,,<??( @    !$)9%,$"+'%4($:("2-,?2.444T8/E<9E?<T<3T>6i6%j8'j;*I@=k@1lD6BBBGFFZKF^SO^TPcVQ`^^aVdddujfzlgzlh}zzI5M:P=VE\M^NZG^P[@`OdWg\i]aHjWiRq_p[lapgsmriyowpyr{i~ptMvP|V~Z^~adfipvx~읁쟄ࠊɰӰʸ˾캩ŵǸ&&&#))"&a[~}[an|kdOMQiwlUwdONLJIHHFMkTnhRQOOOMJIHHFFJvloxhSSSQQONMJIHHFFFhlaV|ihhdSSQQOOMJIHHFFFeTakkigeSSQQOOMJIHHFFFFv&ywskHFLl&vtsHGFkawwt655///9SQ1-,,++3IHHM[&|xwweS JIHHw}&xw==6655;ee4..--,8MJIHi$xigOMLJS"*@>===7755///...:OOMLO)*ROOMQ)$CB@@===76652///<T90T=5m<+JA>UA9UC<UD>n@0nD5oI;DA@EEDVFAWJEVLHf]Z}aWhhhdUl^lVr_va}jtMxR{V|W~Zs_ņp`bfilstu~¥㩔멑朗ﭕ滫ŷɾ±ƶǸȺ˼Ϳ( (GKeZYaKG(DkQ<9309\4(GEcQ@?<930/QCG!oW/\(Mc\-+064񁁁Sqqqn ~jgdb_\~Y|WzTxRvPuMaﭖ{ qqqnqqqn%"!Ͽij윁tqnkheb_]~Z|WzUxRwPuNsL|Vﭖͳ% qqqnS2/-䀘~{xtqnkheb`]~Z|X{UySwPuNsLrJcŵɿ1+)S-%#"˽읂~{xurolifc`]Z}X{UySwQvNtLrJsLﬕ% 񸸸- þŵ잂|yurolifc`^[}X{VySwQuOtMrJqI읁ʹ \\\{ﮗ䀘잃|yvsplifda^[}Y{VyTwQvOtMsKqIﬕ{\\\{?<;ﮘ   !               I1tMsKtLŵ>64􉉉¾ó   !               J3wPuNsLdɱVRP   !  !           L5yRwPuNsLﮘTJFqƶ}zwurpmj}h{e{{xډmqYoVmTlQjOhMfKeIcFqO{UySwQuN}YȰq865ŵ±   !  !   ӌt{mX      O8}X{VySwQuNﯘ70.ȹŵò   !  !  !ӏw잂p[     P:[}X{VySxQd~x\˼ȹƶòUC=UB;UA:U@9U?8T>6T=5T<4T;3T;2ږ~힃|fS6,R5+R4)R3)R3'R1&R1%R0$R/#^E^[~Y|VzTxRƶú\$#"˽ɺƶijmclaj_i]g[fYdWcVaT_Rᝆ̉rXHWFUETCRAQ?P=NUC=UBN;L9J7I4[@~Z{VxReYʻƶ±!!!!!!T8/잂}9%      j;*^Z|VySȹ321ʼǷlbj_h\eYcVaTq_잃`OVETCR@P=N;aHc_[|Wﬕ2,*`^]˼!!!!!!T<3:'     k>/hd`\|^SP}zyskqhnelbj_h\fYcWaT_Q]NZKXHVETCiRmid`lzmh}zz"!!!!!!!!!!!   lD6sniepzmi`_^yrwpumrjpgndlai^g\eYcV`S^P\MZJp[xsoj^TQ332ZNJ"ZKFɺƵ°뫔)!^N잂~yto2-,sm",%#ɼʻƶ±~!!{i쟃~yuY""˼ǷòaV!#ࠊퟄYGFF+'%"cVQ˽Ǹó캩4($!U?7䀹ɺE?=ujf"#̱̽ȸyo!!~pﬕʺCCC%CBB&#""I@=Ӱ,$!!?2.ﭖB=;CCC%WWW""B:8{t/(%"%WWW  wnk"""""$ʻƶ±˿  % :53"$ JA>ʻͿ %1 껻1%CCBB?>% WWWGFFFDCWWW CCC%333`__}{{}{z`^^322CCC%YY??(  @0 60.60- 0 WWWC=;ǸB:7WWW ::9kb~ZxRf:99 WWW˼ulc[yStMWWW0C@?!        uNB:70ͿT?7T<4T90valVR1&R/#m<+{Vi ƶ    }jS8/    _|WȺ 765VFAUC=UA:l^S8/S8/S6+nD5h`60.766         sj60.nD5ɺ±㩔nD5ņp~t $ ¥˼òs."멑朗0DDCf]ZVLHŷA40}aWﭕC><0WWW721JA>@74D95滫WWW :::ɾ::9 WWWDDDDA@WWW 0766766 0Ext/Icons_04_CB/key-org.ico0000664000000000000000000006117610062625362014326 0ustar rootroot 00h ( 00 h^"00 %'  nM h^(0`pp3991p3p;;;;{{{yyy{ ;y ;p {9 ;;{9 13y 0 0;{y0  ;; ;9{ 1 y 1333s1y ;@9 9 10 0p ;9 39 ;;3;99 ;; 0{{9 { ;0;{ y ; ;; ;{;{; ;{;{0 {;;{ {{{ {;{{ {;;{;0p;{{;{;{{pppp( @p;p ;99;9;;;y;q@s;{3y 00;919 9 ;719{9;3;;{;{{{{{;;;;p;{3@p( p; ; 0 39 0[  00 ;; 1; ;;p { q`(0`        &&;#2.;4>-F&O#J4G8AL'P.a6i3n5n8i8n7vLMERH]Q`PhVjSo]lRpR}_yk{FFFQQQYYYfffyyy :[Z]]OGH]dbdr|{rt{Ikmfansuqx Xfhydruy}p []x aaenimqtrvz~  3647254 ;}lllljjjfjfffcccccc_cT8 6lllljjjjfffffcfcc_c___^3 lllljjjjfffffcccc_c___^ 6Clllljjjjjffffccccc_c__8llljjjfjffffcfccc_c_Tllllljjjjfffffccccc_c_llljjjjfffffcccc_c_llllljjjjjffffccccccllljjjjfffffcccc_llllljjjjfffffcccct:/@zllljjjjjfffffccSzllllljjjjffffcfcBLllljjjjffffcfHWllllljJfff ]lll>fff(@Ull?jffUll?jfjn,HLSSSSOOOM=NNN%Xjf+H jj q%jj jjw ll)r*%llE oA ll zzzzyyy[[[[[Y`ll,s -H'A1 ID'E}m;6 3&7mC4527463( @ ? %#-(5.;*>4; -@/J2@ ?A0L?N)X/j0jD\J^[i\viFFFmmmJMQanfpny KRT_]e {\~smknp{~ ]^ly|x `aeims~quz}   .ffhgddbbaaaGGGCCCAAA9A'pnfjhggddbbaGaGGCCCCAAA999MppnjfjhdddbaaGaGGGCCAAAA99'mpppnjjgggdbbbaGaGCGCCCAAA9AttppnnfjjggddbaaaGGGCCCCAAA9tttpppnjfjhddbbaaaaGGGCCAAAAutttppnnjjgggddbaaGaGGCCCCAAuutt- 0fjhddbbbaGGGGGCCAAyuu!,jgggddbaaaaD((/CCyyL7fjhddb >G3CC{y jjggg`5b3GC{U 0RRR61*5*:C{& ru% G~yuk G~$yyQ G~KKVaxS_^]]]YY[XX;==Ea#ttptnnnfjhggddbbx ruttptppnjfjhdddbw lyuuttppppnjjgggdd}N"$T{y{yuutttppnnfjjgdd~~~{{{yyuutttpppnjfhhd~~~{{{yyyutttppnnjjgf~~{{{yyuuttptpnnfjh~~~~{{yyuuttptpnnnfO~~{{{yyuuttppppn.~~~{{{yyyutttppnO~~~{{{yyuuttmM(   )0%^2e7}@^ Z^DDDnnnTgiaL~`eiyo Zbgolqw{}    2<:97$"" >B<<:97$""DCBB::97$""ED&<:97$""I<:7$ A..- "*,+%L@>523107O')EDCB<<:9POG'FIIEDCBB::PPPOMMIIEDCBB:HQPOMMMJIEDCB2HPPOOMJJIED> (0` %F;;;F ;;; --- ]  } {ywusqoml jhgedba` b X : ;;;F7L}{ywusqomljhgedba`^] [#JF}{ywusqomljh gedba_ ^] [ ;;;d}{ywusqonljhgedba`^] :}{ywusq onljhgedba`^ X}{ywusqon ljhgedba` `}{ywusqonljhgedba _}{ywusqomljhg edba}{ywu sqonljhgedb}{ywusqomljhged[R}]}{ywusqoml jhge#2-F }{ywus qomljhgb m }{ywtrpnmljhr y}{y.a   Imlj &8i7i6ip}{&OGomlH]Zf}'PHqo m 'h'PIsqo Sor4GkxvtsqomfOcb`;7vdsqVjt4G3nus>L4nwu4?.;5nywDR{  ];;; FLM7LF;;;  d --- ;;; F;;;F( @ :777:\\: -@ {  }zwtqnligdb` ` K?: .@ }zwtqnligeb`^ ]?777}zwtqnligeb`^ K}zwtqnl ig db` `}zwtqnligdb`}zwtqnligeb}zwtqnligd*>/J} }zwtqnligae}zsTR\liRPx}k/jnl#-0Lpn0jq n(5D\~{s_m])Xlqy#.nJti\vLwqJ^Mz2@O} |y~[if %.;4;?Nnp  {777 ?A  -@: ?A  .@:\\:777:(  @:::@^ }wqlgb Z%^::: }wqlgb Z}wqlgbTy}wqlgiai{L7}l  o2e0o~`ge)   ::: Z^  @^:::Ext/Icons_04_CB/lockred.ico0000664000000000000000000006117610062522472014372 0ustar rootroot 00h ( 00 h^"00 %'  nM h^(0`pwwpwwpx{ypyyy8pxyyx{Pyyyp8xq yyw9yx`xwpxypppwxx88yxxyxxy xpPwyp8wx0 xpx0xwp0pxwx0xxppx88pxq7xsp0pp??( @pwwp8yxpyyyyy`pQ117wywxpxxpy8pxwyyxwywpxp0{wppx0xp/xwwp0{8xwwppp7ws@pp7??( pwwxwxsp{0wxP0yx0xwxwpw8p!p(0`     "#!&% %!!! !%#$'%%& "**,2./3-.6(+8/0333366602934977:89:G$D&+E!(H+0G68A:;A;A48L7=]$.`2:a>Ej9BmBBBKMWNPWOQ[PQWSTWVVXPR\WXXZZ\\\]CHcCJnmmmcfuttt(7>J?KOXbgvyy|y~szARYffrcqr}+J,K.L0N2P5R6T9V;X=Y@UaqdvA]D_E`HbJdLfNhNhQjQjRlUn]sWpYq\s]u`wbxdzf|h~~yu{jln}ptxssuxy|}?2 2?"A9HH5A!s!2532*qa]YXVXh(xhdaa_]YYXVVRaxmmhhdaa_]YYXVVRRYrqqmmhhdda__]XXVVRRRa ǁ{xrqmmmjhhaa_]]XXVVVRRR 2é{xxrqmmmhhdaa]]YYVVRRRR2પxx YYXVVRRR*𯯬|x&#]]YVVVRRR(ACB__YYYVVSRdA7繷[Za__]YYVVVR3ù| hdd__]YYVVVY"/.hhdda__YYXVTLKmhhdda__YYXVdszimmhhhaa__]YXV?%$qqmmjhhaaa_]YY?2B<=F9@F=Dh:DxBBBCDGEFGPS_SU_TV_UV`UXf^^`VYjSXpW]|aaadddlo{lo|mp|zz}{|}IST\R\HVfoBV\g`lap,K.M0O2P5R6T9V;X=YA]D_E`HcJdLfNhPjRlUnWpZrYq\s]u`wbydzf|h~mjmopsuxz|~444,77-4x$vux'}dTR^|' lcTQQLLIHEQk ~îj^ZZTQQLLLHEDO| '~Ûfca^ZZTRQOLIIHDD|'xnşhfdc"!LHHDDkx'ŵjfd LLIHED4ŕf&#QLLIHHQ|4)ȴB?RQLLIHEyȟZTRQOLLHTt4 ^ZTTQOLLH4ʹ@=^^ZTTQOLL/ȴ`b^^ZZTQQLd-9ʮhfca^ZZTQQZ79˵;:hfdc^ZZTTZ7/˽>Ajfcc^[ZUh-õ%jhdca[Z4ʹ1?D)4o?@E;DqABEEEENSlFNyhhh,@2D9JARN_iv0O2P6T9V=ZC_FaHbIdOiQkSlUn]ubyikmsvx| 9SKHE(%#*;gSQKH,*%#V f[SRNH1.,*'M g][URND2/-*Q ka`[VD3/-\@fa`UHG3G<pfb_KHG]99kgeB ARN[69:pjea][[b79@lkgj@9 (0` %\\qq $OQ[wzvyNPZ$\\\{128}/18\\\{-LNVIKU͸-S9:@f}JdA]>Z;W8U;XUn57@񁁁Sqqqn lRkOiKfHcE`B]?[Z:W7U5R2P/M,K.M %񸸸- ~yvrnkg}cz`w\tYqUnRkNhKeHcD`A]>Z;X8U5S2P0N-L+Jt \\\{~zwsok# "?[J(7FbC_@\=Y:W7T4R1P/MOiQRV}yaq@UJeGbD`A]>Z;X8U5S2P0NIKUq~x QjOiKfHcE`B]?[;X8V6S3Q@\q669~2:a$.`VoSlOiLfIcFaB^?[Z;X$XY[OX?Kkh~d{`x]uYrVnRlOiLfHcE`B]?[]tNPZ{dvplh~e{ax^uZrWoSlPiLfIdFaC^E`wz&&xtqmif|by^v[sWpTmPjMgJdFaC_CJn9Bm}yuqnjf}cy_v\sXqTmQkNhJeGbr}cq}zvrnkg}dz`w\tYqUnRkOhKf  ~zwsolh~d{ax]uZrVoSlOiy!$u{xtplie|bx^uZrWoXqy|ZZ\48L>Ej|xuqmjf|by_v[stPR[$$%(+87=]}yvrnjg}cz_w $\bgfr~zvrokg~d{\+0G{wtpl|889 |xtp238q|yqVVW}NOV-.6CHc@@A :;@􉉉\\\{cfusz\\\{  "* -&&&y}z##&񸸸-S333/03Sqqqn&&&#$&qqqnqqqn qqqnS@@A=>@񁁁S-VWWSSW͸-\\\{899779\\\{$$%[[\YZ\#$$qq\\????( @ YYCCC%-.3TV_lo|lo{SU_,-3CCC% WWW>@F<=FWWW %<=BpRlNhf|8:B%1 oRlMgHcC_?[:W6S2PLf 껻1% }cz^vYqSmNhIdE`@\;X7T3P.MHc %  vpjd{_wZrUmOiJeFaA]Z:W5S1O/M8:BCCC%y:Dx&3vIcD_?[;W6T2PKeCDGapBVOiJdE`@\FY  ZrUnPjKeFaA]=Y8UQkY29[&/Zax\sVoQjLfGbB^>Z9V224\gHVg~by]tWpRkMgHcC_?[,-3^^`mnicz^uXqSlNhIdD`nSV_zz}%)= %={uojd{_vZrTmOiJeYrmp|z{}T\IS|vqke|`w[sVnPj^vnp|__afo`l}wrlg}ax\tWo{UV`3349=R=Dh~ysmh~by]u-.3SXpR\ztoidzY %{upYFGG|w?AFCCC%CCCPS_W]|=>CCCC%WWW/189C:Z 667  si^vTmJd017667)4o)4owlaxVo017NSlFNyyncz  |0DDD&>?D0WWW79B7:FWWW :::::: WWWDDDABDWWW 0677667 0Ext/Icons_04_CB/lockblue.ico0000664000000000000000000006117610062522270014543 0ustar rootroot 00h ( 00 h^"00 %'  nM h^(0`pwwpwwpxh|ϏpȈx|x·Ϗx猎w쏏pw|D|w@@p莌`ȏp~|ΈxxH||xgxΌp|ȏpxx|p舎@xpxP猌x|χHx~xw~xwwx@w~x與xp@w~~xpXw`~`wpxxxϏ@`xp@舏`xxpphx@hphpxvgxvpppap??( @pww@pHwxpxȌxȌΈppdddT|xx@|@`pxxp|xpH|x~Axp@Ȍp`|ppwPH$ppwxx/xxp`x@xwwpppgpwvppw??( pwwpwxwvuȇp@@w@~XpxHw`Ȅx@whp$p(0`       ! " %&!!!%" &%%)#!2-,8.+30/50.311666942954:87:99F'C+#H/'D1*F5.^9,K<7@:8A=;A>=\D<`C9H5BBBWPMWRPWUT[TQXXWXXX\[Z]\[]\\bNGiMClL@mRImmmujftttXIYIdWePoSmf}zve~orJsLtMvPxRzT|V}Yw|~n|[]Åp͊rތp`abegfikmpqtvx{|~ǒК읁ퟄΧ⢌꣉稒꫕䀹ﬕ̴˺ξھ굣㸪ŷ±óijŵǸȹʼ̾=/ /= ?3F}}F3? pշn/3Ծԛ0/+i]VPOOOaԛ+sըkba]]VVPOOLLK]pحffbbb]]]PPOOLLKKOԛΓkkfffbbb]]]VPPOOKKKK]ؽ kkfffbbb]]]VPPOOLKKKKԼ /ݭkkiffdbb`]]VPPOOLKKII՜/wPOOLKKKIq+ՠ$"PPOOOKKKK)?ڨ@.]PPOOLKKKaԛ?3ԢXD]]VPOOOKKK0ڨ `]]]VPPOOKKPԜ Ԩ-'bb]]]VPOOOLKvGCdbba]]VPPOOLaSػZfdbb]]]]PPOOLշ=%#kfffbbb]]VVPOO=/8B@kifffbbb]]]PPOd0/lYkkfffbbb]]]VPPFkkfffbbb]]]VP| <;kkfffdbb`]]]؀UTkkffdbb]]]؀  kkffffbbb]} mykkkfffbbbF/8(:kkfffb3/=,kkkfff=EHkkffطv %kko Ν  Κإ 5κ3 ?9ڴ?/| x>Qw/q zݴ/ Խ~nn ݲxw // /82/ xt ? 8mm8? =/  /???( @   $89&<*$3.-=.(422444V0#V2%_4%W4(X7+Y8-B<:B>=a>2C@?F@>L@;QA<ZA8tC2BBBFA@GFE_VR_WU_XUgLBwQDf[Wo]W`_^i\Xa`_{c[aaaddd{ro{sp}{{}|{}||^Qe[fZgTmSymufxirJsLtMvPxRzU|V~Yo]ޖ|`abdfikmpqtvy{|~읁쟄⩕䀹ﮘ˺¾¹ĵ±ijŵɺʼ̾222(44(2f$ed$f$$~lQOWw{$ \mQOMIGFFBN~[ qWUSQONIGFFBBN{ $olZWUUQONIGFFBBBq{$f\qqolZFFBBBq[f$|xqqom GGFCBB2~|xqqo*"MGGFFBN{2%~||vqH;WUSQQNIGFx-~rJlWUSQQNMGl(7~ollWWUQQNMQ3798qomlWUUQQNU4/=?qqomlZWUQQo( )vqqmlWWUS2,:vqqollWU2j xxqqolZoe%~xxqqom$2 ~|xqqx2%(0~||v$f`~|\f$a(.b$  f\ $%$$f%jg$f2277-222??(    +&,100:65;::I5.H72B;9E<9D?=D@?mB3DBAEEEoNCxXLkYRhhhX>[C`IfQr\tMxRzU|W~Zt]`bfilqt{|~靃ɨ䀹ﬕij±ƶǸɹ 36SIIP53/S>(%!(K.3/P>-A.3ZCA>#M7PICA&#(5^MKIF")(#!Q ^TPKIE:-((#I bVTQMIA<-)(K dZZTQA<-)T9bZYSCA>A6f^[XGCAV33f^]D ;KIQ/33fb]ZVQTZ/39fbbb73 (0` %\\qq$! ZSQ~z}yZSP$ \\\{842831\\\{-VPN̿ijò˺UNK͸-S@<:|c\~Y{VzT|Wm䀘˺?97񁁁Sqqqn Ŵ윀jgdb_\~Y|WzTxRvPuMc qqqnqqqn&##ɺ읂tqnkheb_]~Z|WzUxRwPuNsL}XϾ%" qqqnS30/ﭖ~{xtqnkheb`]~Z|X{UySwPuNsLrJf2-,S-&$#읂~{xurolifc`]Z}X{UySwQvNtLrJsL%" 񸸸- ȹ잂|yurolifc`^[}X{VySwQuOtMrJqIϾ \\\{ﮗ䀘잃"   ! }Y{VyTxQvOtMsKqI\\\{@>=ﮘﬔ잃H/'F'\~Y|WzTxRvPtMsKtM?97􉉉ĴﯘﬔXIH5_\~Z|WzTxRwPuNsLg˻VSRﯙﬕ朗ÅpoSb_]~Z|WzUyRwPuNsLUNKqǷﭖ朗꣉ geb`]Z}X{UySwQuN~Z˺q976ŵ±ﭖ望`C9^9,lifc`][}X{VySwQuN831ȹŵòﭗ䀘veePolifca^[}X{VySxQf\˼ȹƶòﮗ⢌  ތpspmjgda^[~Y|VzTxR\$$#˽ɺƶijﮘD1*C+#zvspmjgda_\~Y|WzTﭖ$ [ZY̽ɺǷijdWYI}zwtpnjheb_\~Z|WqZSP̾ʻǷĴ±К͊r읁~{wtqnkheb_]~Z]}z;ʻǸŴ±&&읂~{xuqnkhfc`]ZͿʼȸŵ±mRIlL@읂{xurolifc`^ŵͿ˼ȹƵò|n잃|yvsolifcaǷ˽ɹƶó굣  稒䀹잃윀|yvspmjgd̽ɺƶij $ǒﯘﬔ쟃윀}zwspmjl{\[Z̾ɺ㸪K<7iMC꫕ﬕ晴ퟄ읁}zwtqnퟄZTR%$$ŷ8.+\D<ﭕ朗ퟅ읁~{xtq$! \mf~oﭖ朗읂~{xu\F5.ﭖ䀘잂|988ھ ﮗ䀹잃ɺ843q̴ﮗﬔqWWVﬔVQO50.bNGﬕ朗¾A@@ Χ±ﮘ@<;􉉉\\\{ujfwȸŵ±\\\{ )#!Ϳ˼ȹŵò -&&&|~˼ȹƶò&$#񸸸-S333˽ɺƶͿ300Sqqqn&&&&$$qqqnqqqn qqqnSA@@@>=񁁁S-WWWVTS͸-\\\{999977\\\{%$$\[[[ZZ$$$qq\\????( @ YYCCC%3/._XV{ro{ro_WU3.-CCC% WWWFA@F@>WWW %B>=ퟄkg{˻B<:%1 ʻퟃjfb^~Y{VxRuOe  껻1% ÿytpkgb^~Z{VySvOsLb˼˺ %  ;쟄~zuplgc_[|WySvPtLsKﭖ˺  WWW䀘ퟄa>2X7+W5)W4(W3&V1$V0#_4%|WyTwPtMrJﭖWWWCCC%C@?ﬔ9&8\}XzTwQuMsL˽B<:CCC%ŵﬕwQDtC2a\}XzUxQuNd˻GEDﭖomSea]~Y{UxRuNF@>Yŵﭖ  nkfb^~Z{VxRhYʻƶ±ﮗZA8Y8-tpkgc^Z|VyS432ʼǷòufgTzuplgc_[|W3/-`_^˼Ƿò⩕ޖ|윀{vqmhd`\윀_XU}{{̽ȸij=.(<*$윀{wrmid`m{ro}{{̾ȹĴe[^Q읁|wsnier{spa`_Ϳɺŵymxiﭖ읂}xsoj_YV433ͿĵQA<gLB잂~yto3/.o]WfZﮘ朗쟃~yuY $䀘ퟄYGGG¹䀹FB@ﬕCCC%CCC_VR{c[ﭖB?=CCC%WWW720L@;ĵŵWWW  f[Wi\Xʻƶ±  % ʻ %1 껻1%CCCCA@% WWWGGGGEEWWW CCC%433a``}||}|{`__433CCC%YY??(  @0 621621 0 WWWC?>C>yStMﭕWWW0DBAﬕ,+\zUuNǸC><0ﭖoNCmB3f]{Vl ƶtr\pg_|W 766Ǹ  靃{rh`621776ɹr\r\|sj±631kYRxXL朗~t  䀹ﬕ0DDD&ﭕC@?0WWWijB;9E<9ɨŵWWW :::::: WWWDDDDBAWWW 07777760Ext/Icons_04_CB/plockb2.ico0000664000000000000000000005600610063620124014271 0ustar rootroot (n00 >h00 %N!  F hW( @ppwwpww~wpwwp~wwwwwwppp~ppp~p~p~ppppppp~p~~~ppppp~pwpp~~ppwww~wpwwpppp??( `pwwwwpw~w`wwww`~pp`p(0`      !% 3$!!!&#"%$#%%%+%#.(&/+*<,'1-,70.81/333720666831;42976?75999R/#R1%R5+S8.@:9@=<T;3T?8UB;YC;BBBLFDTF@THD[JDVLHWOLZOLWPMZPM^PLWUT\ZYsPCm_Zq\UmmmygayictttJ3M;O8P>P:TCYJUA]J^R^EbUfZi_i^n^cFeJiNhQmXmSmQp[qYsYjbmbpgrjtfwswqxszu~yvcxf{e~iqOsLvPxRzU|V}Y{|}mrw|[]ډm̉rӌtΒ}ږ~`bdfikmps{x}˝՗Ӛᝆ읂٨㦑ﮘȰİȰͳʹԷʶʹɺϿ׾ػ൥½½¹ǿõŻŸɿ±óijĴŵǸȹ˼̾<,,<!?6aa3 ?qc,61,&ٳ~vnlll ƥ~~vvnllljj~q֥~~~nvllljjjl簈~~vnnlljjji}٬~~vnllljjiij,ְ~~vvllkkjiii,尰~~~vnlljjiiiq&򳳱   @iii?Ƴ  @iii~?7Ƴ  @kkji3uuttssrggfxXUURRQPPPhkkkil zT @mmkkj zW Bvmmkko****))))%)|f%$$#####"J}vmmlk<[[NNLLLLIIyFEEEECCCAV}}}mml <,8 |d  G~}mvm6, e G~~}vvva]][][[NNLL{IIIFFFCECY~}vv/..*.****)))))%%%%%#%%#S~vv   Hv H娧uuutttrrrffza,8 ZƳ %6,< .ij 9 </ ^ Oa + q!! 6Ʃ ! L I8a : ij4? ; 0ij?,a  ij'& = Mij,  0, 0-  >oo,&,87,'?88?!<,,<??( @    !$)9%,$"+'%4($:("2-,?2.444T8/E<9E?<T<3T>6i6%j8'j;*I@=k@1lD6BBBGFFZKF^SO^TPcVQ`^^aVdddujfzlgzlh}zzI5M:P=VE\M^NZG^P[@`OdWg\i]aHjWiRq_p[lapgsmriyowpyr{i~ptMvP|V~Z^~adfipvx~읁쟄ࠊɰӰʸ˾캩ŵǸ&&&#))"&a[~}[an|kdOMQiwlUwdONLJIHHFMkTnhRQOOOMJIHHFFJvloxhSSSQQONMJIHHFFFhlaV|ihhdSSQQOOMJIHHFFFeTakkigeSSQQOOMJIHHFFFFv&ywskHFLl&vtsHGFkawwt655///9SQ1-,,++3IHHM[&|xwweS JIHHw}&xw==6655;ee4..--,8MJIHi$xigOMLJS"*@>===7755///...:OOMLO)*ROOMQ)$CB@@===76652///<T90T=5m<+JA>UA9UC<UD>n@0nD5oI;DA@EEDVFAWJEVLHf]Z}aWhhhdUl^lVr_va}jtMxR{V|W~Zs_ņp`bfilstu~¥㩔멑朗ﭕ滫ŷɾ±ƶǸȺ˼Ϳ( (GKeZYaKG(DkQ<9309\4(GEcQ@?<930/QCG!oW/\(Mc\-+064񁁁Sqqqn ~jgdb_\~Y|WzTxRvPuMaﭖ{ qqqnqqqn%"!Ͽij윁tqnkheb_]~Z|WzUxRwPuNsL|Vﭖͳ% qqqnS2/-䀘~{xtqnkheb`]~Z|X{UySwPuNsLrJcŵɿ1+)S-%#"˽읂~{xurolifc`]Z}X{UySwQvNtLrJsLﬕ% 񸸸- þŵ잂|yurolifc`^[}X{VySwQuOtMrJqI읁ʹ \\\{ﮗ䀘잃|yvsplifda^[}Y{VyTwQvOtMsKqIﬕ{\\\{?<;ﮘ   !               I1tMsKtLŵ>64􉉉¾ó   !               J3wPuNsLdɱVRP   !  !           L5yRwPuNsLﮘTJFqƶ}zwurpmj}h{e{{xډmqYoVmTlQjOhMfKeIcFqO{UySwQuN}YȰq865ŵ±   !  !   ӌt{mX      O8}X{VySwQuNﯘ70.ȹŵò   !  !  !ӏw잂p[     P:[}X{VySxQd~x\˼ȹƶòUC=UB;UA:U@9U?8T>6T=5T<4T;3T;2ږ~힃|fS6,R5+R4)R3)R3'R1&R1%R0$R/#^E^[~Y|VzTxRƶú\$#"˽ɺƶijmclaj_i]g[fYdWcVaT_Rᝆ̉rXHWFUETCRAQ?P=NUC=UBN;L9J7I4[@~Z{VxReYʻƶ±!!!!!!T8/잂}9%      j;*^Z|VySȹ321ʼǷlbj_h\eYcVaTq_잃`OVETCR@P=N;aHc_[|Wﬕ2,*`^]˼!!!!!!T<3:'     k>/hd`\|^SP}zyskqhnelbj_h\fYcWaT_Q]NZKXHVETCiRmid`lzmh}zz"!!!!!!!!!!!   lD6sniepzmi`_^yrwpumrjpgndlai^g\eYcV`S^P\MZJp[xsoj^TQ332ZNJ"ZKFɺƵ°뫔)!^N잂~yto2-,sm",%#ɼʻƶ±~!!{i쟃~yuY""˼ǷòaV!#ࠊퟄYGFF+'%"cVQ˽Ǹó캩4($!U?7䀹ɺE?=ujf"#̱̽ȸyo!!~pﬕʺCCC%CBB&#""I@=Ӱ,$!!?2.ﭖB=;CCC%WWW""B:8{t/(%"%WWW  wnk"""""$ʻƶ±˿  % :53"$ JA>ʻͿ %1 껻1%CCBB?>% WWWGFFFDCWWW CCC%333`__}{{}{z`^^322CCC%YY??(  @0 60.60- 0 WWWC=;ǸB:7WWW ::9kb~ZxRf:99 WWW˼ulc[yStMWWW0C@?!        uNB:70ͿT?7T<4T90valVR1&R/#m<+{Vi ƶ    }jS8/    _|WȺ 765VFAUC=UA:l^S8/S8/S6+nD5h`60.766         sj60.nD5ɺ±㩔nD5ņp~t $ ¥˼òs."멑朗0DDCf]ZVLHŷA40}aWﭕC><0WWW721JA>@74D95滫WWW :::ɾ::9 WWWDDDDA@WWW 0766766 0Ext/Icons_04_CB/plocky.ico0000664000000000000000000006117610062570746014257 0ustar rootroot 00h ( 00 h^"00 %'  nM h^(0`pwwpwpxxp?p00B'0p0A p0BxP00 p P!A p7sWqsR76qgpwwsws7wsw8p0 B70!!wwwwwwwww{777777'7373w BRP`pp! 74p$(px00@0x!'4psBh0a0Ap`'808p%%'wxp8pxs7xsp0p%p??( @pww0p7xp pp0000700p_wwxww{00 8pwwwsw80!h#0?pwxwwwww{p0!00pwwwwwww{00xap0pp0x0p8sphp0Cp0p87pwsppw??( pwwwp0w78s6x77sc4rqs?x/wx03pwwxpp(0`  "!"!"!"!""%%('!!!!&&&''!((%))))))0/'11$64,00-541545552885;:7>>9;;.A@;CC>CC9WU1[X5[X9[X=[XBBBINNGVUKVVA[YE[YF_]H[YNYYN\[N^^QYYVYYR^]T^]YYY[^^\^^MecSbaS|ymmmcqqawvm~}tttNQUY]GJNXdon|y}afilaquV]]xrimwzbejnmz~|vnkmquy};&  &;?4MM4 ?vv&4.& ᾲnllljj wônnmlllljjinvônmmmlllliiil罴mmlllliiiin߸mmmmlllliiii&ýmmllllilii&wώmmnllliiiiv&Elii ?Ellin?4 Ellil.eeebbbaaaa_a_hlllin \Ennlliu  \Ennnllv*********$f$$"$"$"""Xnnnll;RRRRPPPDDDCCCAAAAAAcnnnl;&7   ]Vnnn4& o  ^HnnM UUUTRRRRRPDDDDCCCCAgn*.**************$$$$$"$[ W S o癙eeM &7 J!7&; ( : ;( Y ZzN * v 9߹  K I7N < 4? < 9?&L &| > Kx&  3& 3'  >wuv}|x&&&74&zz?7po7?;&  &;??( @ "!"!"!"!"!&&+*$'')10)65/66%?=)?>0664448<<5CB?HH9[X6vr:vsBBBDDDAHHHHHBZYP^^UbaYggFvsdddmxxn~rzzp~}INVYeaeiaaqyZhktmqu}$$$!&&!$IFhkkkkkkdFIRmkg^YTTV]fkjPAmmfXTTT===;;T^kj@QmkZVVVTTTT==;;;TfkP QnfZYXXVTVTT====;;;ZkPIBng]ZZZXXXTVTTTT;=;;;]k@Ink^^ZZZXXWWUUUTU<<<<;;fj$`nf_^;;TjP$pkf__  =;;_kJpgfff000/0/8ZY-++***7TT;TkF$lngfff ZYTTT;fh$pmkggf1110008]Z3,,,+,7TTTT^k$pkkggg   ]]VTTTZk!)pmkjkg44411110000/0,,9XVTTVm&)qmkjjg  #XXVVXk($qnmkkk55544441111000/:ZXXV^k!qpnmmkk ggffff_\ 2]ZZZX^m$oqnnmmm( dgggfffM H]]ZZZkh$KqpnnnmO Lkggfff. [^]]]]mGqqpnnni "kjgggc f^_^]gm$aqpppnn& Rjkjg6 Df____n`$qqpppnb hjjS efff_mnICqqpppn? F4 NgfffkmBIaqqqppn( FkgggkmaaqqqqppB Okkjkkp` CqqqqppnnnnmmkmppB aqqqqqppnppqp`IKoqqqqqqlKI$$))$$$$??( "!"!"!%$ %%#10+441224885==;==<=="MJ7ED:CC=FE/[X2[X6[X9[X=[Y;zvAFFEFFDMMB[YE[YJ[YOZZ@zvEzvKzw`iihhhfenjsu~mqvy~" "49XLKV94"1XF@.,+.N/"42VFDC@@.,+F/4`L+N";XN(&,@9"bXV)@.X b]X% C@N ga`DCN gb`9XVNG>FF]"=gbR?]X6HKK9"kgb!`U#NL`44kgQ TX]24"5kkQ01S`b2"4=kggg;4" "(0` %\\qq##O[ZwvN[Z##\\\{187}087\\\{-LVUJVU͸-S9??wrpnln7??񁁁Sqqqn ~{ywuspnlkigx qqqnqqqn"%%|zxusqomkihfo %%qqqnS.33}{yvtrpnljhgez+32S-"%%~|ywusqomkigfg %%񸸸- }zxvtrpnljhfe \\\{~{ywurpnmkigf\\\{;??! ! ! "!! ! "!! ! "!! ! "!! ! "!! ! "!! "!! ! Bjhi7??􉉉! ! ! "!! ! "!! ! "!! ! "!! ! "!! ! "!! "!! ! Dljh}QVV! ! ! "!! ! "!! ! "!! ! "!! ! "!! ! "!! "!! ! FomkiJVUq}{ywukigeca`^\irpnluq588! ! ! "!! ! "!! ! "!h! "!! ! "!! "!! ! Iusqol087! ! ! "!! ! "!! ! "!k! "!! ! "!! "!! ! Kxvtqo~\AYW@YW?YW>YW=YWYW=YW387q177"""" &&k"!"!"!aqUVV|!!!!""`oo&00!!"!%#NVU&**!!"" $$^ut!!!!"!Kca???y""""""5<<#""!"!&&;??􉉉\\\{FFBB{xtqnkijh9BBCCC%"!"!"!"!"!"!"!"!"!"!"!"!"!"!"!1tpnk{CFF"!"!"!"!"!"!"!"!"!"!"!"!"!"!"!3tprol=FFYb`][YVdUKIGFDUvspY"!"!"!"!"!"!6YV"=;"!"!"!"!"!7tq{xuq133igeb`^m]SQNLJ\}yv-33]``"!"!"!"!"!"!:YW%=;"!"!"!"!"!DD0WWW377BKK8AA:EEWWW :::::: WWWDDDBDDWWW 0777677 0Ext/Icons_04_CB/plockr.ico0000664000000000000000000006117610062571274014245 0ustar rootroot 00h ( 00 h^"00 %'  nM h^(0`pwwpwspxyypwyyypwy0{0p!0yx!C @xxwwsyw9yy`! yypx5Ru5{Sp5su77sSSSyp ywwwswwwsw57yQq5q1w@ R!B!yxxxxwxxxpxxpxy4!؈wxpxyp0!Hx0xx@p xp1@(x@xxxp@BCx% xxp'wp8 pxs7xsp0Pp??( @pwwpsxpwxyppxyy0{pWwsxqqsxyp7sw75ywxpwwwqu770{pwwwwswSsyxX4pyx0xqxpGypW1xxp!p#pp7wq pqW??( Ap7spwwxpwq1ySqSy?57OSCVYxXx!4wxsxAp(0`        !!!!&%%3 %!!!"#&#$&%%%#$+)*/ #0')2,-3$(=-/8.07/1933366634999:%S(T25@79@:;@#+T)/R,3T06U4:U9=V7=Y=AU>D`"4*;4A9ESAMNWEPKUOYS\@N\bZbUa^hbinrqtswsxtxy|w|y}DTK[AUEXH[WeZhVg[kcrhvlyq}8R-L0N4R9V=YJ]YoctcvgynbvA]E`JdNhSlWp[s`wdzh~}vzosx{lvqsuy~D44D"$F=aa=F#he 4974(ˋ{zz{'ϕ{{zzxxe֕{{zzxxxzɌzzzxxxؙ{zzxxxwx4֛{zzzxxxw4ɛ{zzxxwwg(    Ixxx'F  IxxxF>   Izxzx:uttssqqqpp}|llTTRRRRvzzzx"# j J{{zxz " j J{{zze00.0.----+q*****&*%%Q{{zzD]]]ZZZYXXXNNMMKKHHGT{zD4@ n   O{=4 ɛo    Oa```]]]]]ZZɁWWWNNMMKK|::::./000-0----*-*-****i P   Pᵴuuttsrqqqqd4@ \ +<4D :˓ 3D6 _ ^b / ɛh$$ =Է ɛ#" ] Yɛ>c A ʛ=FB 2F4a #  )(C \4    :4  ="5 Cff4(4@>4$$F@@F$"D54F??( @   !!!$):!,!:!#,"%4*,3444+/@46A7:E<>F;>IK:I.C7KAMDPKUNXPXT]DQ^einahgmmriqpuJXDVO_Ta^lis.M0O5R8U=YE`IdNhPjWp`waxz}tj~pvz|)))%++%)jdcj!pxYQOSvn!_YQPONMMKJNxVq]TSSQPONMMKKJNn!r\[YTSSQQONNMLKJJ\n!j`v]\[YTSSQQPNNMLKJJ]Vjxx^\[YTSSQQPNNMLKIJJ~)t{x KKNn)!~~{  MKKxf~~:87765CYT2/..--3NMKPc)~ [Y NNML)<<::77F\[;0///.4PNNMv' ^^ QPONY%,?><<:::87765100DSQQOR+,  TSQQS+)@@>??<<<::87755ETTSR\&$ #~~{xu 7\YYTS{)=~~~{X G]\YYT)kh g~~9Zv]]Y]e!%|xxv]])* nA H{xxvxq)!m ~~{xxjaUcB l~~~{`j!+ W~~t!_ "ira`!!!j!kk!j)',,))))??(   !!"$.&(2//1/0111101702:99;E$S'S.1B25@36D68D:J (T$,T*1T.5U28U5:U7V,o&2p,7p3=q?@D=AW@AEDDEBFWFHWXZfRY~hhhLWU`zHXRaSc^llu0O2P6T8U=ZduA]HbJdMgRkSlUn`wby{knuz|- -PUqbbkSP-MrIA=:8=eE-PNnIGCA=<:6JEP%{`8e-Wne31!9AS- qk4!=:n xq& /!#A=b zxCBe |{R!nke\!;GDt -Y~u[nk5]K^V-(~+*rg,b`xPPv fhrNP-QwLEpx|O-P(ZX(P-  -(0` %\\qq$JMZosmqHKZ$\\\{.08x|sx,.7\\\{-HJUCFU͸-S68?czIdA]>Z;W8U:WQkx14?񁁁Sqqqn jRkOiKfHcE`B]?[Z:W7U5R2P/M,K.M%񸸸- ~yvrnkg}cz`w\tYqUnRkNhKeHcD`A]>Z;X8U5S2P0N-L+Jl \\\{~zwsokh~d{`x]uYrVoSlOiLfHcE`B^?[J.Z;X~$WX[!!!!! !  !s~zWe !  !  !   3COiLfHcE`B]?[YqILZ"""!!!!!!!xZh!!!!! ! ! ! !5ESlPiLfIdFaC^E`nsdkbi`h^f\dZbX`V^T\Q[nGQDPCN@L>KBWD`@@@qs"""02<}#""&89?􉉉\\\{9:A"!!-.7^bz$"!!\b\\\{ )*/!!"!"#*$!!"!BF[ -&&&)*/""""""""CGX!"&񸸸-S333CDL"!!"! &`ez-.2Sqqqn&&&z}y|"#&qqqnqqqn qqqnS@@@;<@񁁁S-VVWQRV͸-\\\{889668\\\{$$$ZZ[XY[##$qq\\????( @ YYCCC%*+3MP_dhzdgzLO^)*2CCC% WWW:Z9V113[cW`T]QZNXKUTawqDQ;G7E4B1?/=7KMgHcC_?[)+3\]`"!!!!!.4U~x!:!! ! !  %1lSlNhIdD`iMP_xy}ekah^f[cX`U]R[NXKUHREPBM>K;H8EDVZrTmOiJeWpei{yy}""""!!!!!!!!!!!.8n`w[sVnPj\tfi{^^`mrjpgmdkah^e[cX`T]Q[NXKUHRDPAMO_g}ax\tWowOR_223GJ["BF[)!FQsmh~by]u*,3in"!#,t!!^lztoidzY""PX!#~{up}YFFG$%+"NRd"%4!39U|w<>Fdgu"#iq"!isCCC%BBC!"&";>I!,"+/@:;BCCC%WWW""68Bpu$&/"%WWW  ilx"""""$}  % 34:"$?B% WWWFFGCDGWWW CCC%334__`z{}zz}]^`223CCC%YY??(  @0 ,.6,-6 0 WWW9;C57CWWW 99:uSlId?[6TMgz99: WWWvk`wUnKeA]8U0Oz{WWW0>?C!!! !   E2P58C028U.4U*1TScHX'S$S,oZ 557=AW9>V5:UU`LW)0T%-T,7pTmJd,.6567 axVo-/6 ,7p,7pduncz $lu.|0CCDXZfFHW.1BRY~;J25@36DWWW :::9:: WWWCDD?@DWWW 0667667 0Ext/Icons_04_CB/lockyellow.ico0000664000000000000000000006117610062522154015130 0ustar rootroot 00h ( 00 h^"00 %'  nM h^(0`pxwpwpxxp?p00pp+x Ppp0pp?x0p0p?p0p0p00pp08p8pxs7xsp0p4p??( @pww0pwwxppp7737000pxp800ppp0?p0p00pxpp0p87sp7spp@w??( pwwwp0wp xx?px0xpw8pp(0`   ! ! &$&%""'&)()(!!!#''%''%(((((1555552887;;0<;9;;'OL,JH/OM=CC2JI7LK?PO9igBBBRYYUYYV^^YYY]^^FcbCigSihPpnNtrTtsmmmnyxtttGVYqdeulkmquy}4( (46+FV[[VF+6KI(+g+(#~qEEBBBBn|f#NqnnEEBEBBBBAAE~KuppnnnEEEEBEBBAAABj~qqppnnnnEEEEBBBBBAAAE utqqqpppnnnnEEEEEBBBAAAA~ (||uuuqqpppnnnEEEEBEBBBBAAAuj(N|||u|uuqEBBBBAAA~K(~~||||uuu" EEBEBBBAA#6~~~||||u87EEEBEBBBAnf6,~~~~||||a?EEEEBEBBBA+~~|||snnnEEEBEBBBEf~~~||/'pnnnEnEEEBEAM~~~|>=pnnnnEEEEEBBpI~~xkppppnnnEEEEBB4~"!qqqpppnnnnEEEE|4(,<9ustqpppnnnnEEEq+(GdcuuttqqpppnnnEEnFX||uuuuqqpppnnnnEV ]32||||uuuqqppppnnE[]_^~||||uuuuqqpppnn[ X y~~~||||uustqppppV G`b~~~||u|uuuqqqppF(,w&1z~~~|~||uuuuqq|+(4.~~|||||uuuq4:T~~||||uuuM %~~~||||~K ~~||ui~~~|~,~~+6+6(Yh(Q5RN(N U([KK[ QN(((,,(MM6-GX]]XG-64((4??( @ ''?>&?>1554445::+BA/BA?ED/a^1a^5a^9b_3jhEE%)) WWW, ^^^{#&&KQQ}JQQ#&&^^^{ ::::$(']dd[dd#('::::  Z&&&PVV~MVU&&&ނZ vvvp!!!+..~xurpnnptz*..!!!vvvp vvvp >BB~|zwusqomkjmtBB~{ywusqomkihnz>8;;􅑐}xuuw|7;;=>>ר= 3>>>?CB{xuromov=CB=>>װ3sssHII9;;}tqmjgeghkoz7;;HIHðsss___ STT244񈑐M;ol6kg5kg4kg2kg3ok?gnkmw143STT___  ...4!""Y]]9b`  .b_groln{T]\!""...4 ())󦯮M| >{owtqnr&))%WZZl%$%$Xy|xurp{RZY %g'=<!=;o}yvsvg-//Gki  WV  8WUr|{z||`Xr|{ijj^}  [bjj NNNSji  "!TzwINN .//g~|"!f+//g1:: 6LKg%ZZZ(.-'54TZZ %)))󮯯066 6FF')) ...4"""]]]grqjX]]!""...4 ___ TTT444񐑑SZZ ##!&&Xih244STT___ sssIII;;;itsiwv:;;HIIðsss3>>>BCCACB>>>װ3 =>>>;;;:;;>>>ר=  3III444]]]Z]]344HIIð3 TTT""")))ZZZYZZ())"""TTTsss___ ...4///NNNjjj{||{||jjjNNN.//...4___ sss %g  g% ??(  @WWWEFF%&&C##1:9HWVGWV/:9##$&&CEFFWWWaedTaa懢Pa`_edWWWtyyzxqyxWWWEFFbedaOJRmw`edEFF%&&CZaa+)+)+)+)ityQa`$&&C!##?zv ?zvsyz##7::ٻs(>=(>=_}0:9SWW?zv(>=~IWVTWW(>=?zvJWV8::c{z "!Z2:9###098 -?> ##&&&C`aaELLCUTWaa%&&CFFFdee[ccZffbedEFFWWWyyyvyyWWWdeeaaa桢\aacedWWWFFF&&&C###9::VWWUWW8::"##%&&CEFFWWWExt/Icons_04_CB/Finals2/0000775000000000000000000000000012606740430013540 5ustar rootrootExt/Icons_04_CB/Finals2/plock-dis.ico0000664000000000000000000006117610063310766016134 0ustar rootroot 00h ( 00 h^"00 %'  nM h^(0`pp~p~p陙p陟~~wwwwwww  ~ ~ 興~~~~~陙興~陙~wwwwwwwwwwww~wwp~~~~~ppxp~p~ppx~pppp( @ppp~陙陙陟wwwwwwwww   wwww  wwww陟陙陙wwwww~ppppwwp~pp(  p w ffn~w~p~ w~ ~ff`npppp~wpp(0`     " :$,!3 4%<% #-%$) <:>=/$H HE"I&E*M-m,n/w'A,$F1$M2$N7)N8)W3!U;+Y:)T1:n6 g8$o>(|<(GB9\A1oA,|@'~D+H/bL;lL8~M8|U>OX\ #L-(Pf"`&-m>1b!+t-1tM5OH8cFFFQQQYYYpT@~U@}YBfff{{{/0798=>!?BF,L3S9E"I&N,M*O*Q-R0T1Y6Z;Z4a?b=CIKNRT'[0_8\0Y$_,`6a-g4i5k8[C[A]@dKhLjRnRdDdCkJgEgBiGpO|]uRxV|[yfqGqFwMwSxT[{QsE|OvDyGejpDŽ_O^][SWZ]ˉdԐiĕrۛrccitsΡ}Ҥ|zuvx  + ) 0$4(6%6NHXO ! #+%&'"64:)+-12)5)?0?4A,CJOJPjh~ww|•ԝګֿ峋řȜ͡ЫѦԩح۱HHNIINGG<:MII=´+_vvuttrrqqqqlllkkjjiV"N#DȿE_wuuttrrrqqqlllkkjjjjh HHA³+nvuuurrrqqqqlllkkjjjjhN/wvuuttrrrqqqlllkjjjjj"ɴBwwuuuttrrqqqqlllljjjjV@ǶPljjjjiɵOllkjjjOlllkjj,,,,!, WqlllkkǔsTqqlllkǚeOqqlqllÚeQqqqlllŚeSrrqqqlF```]\\\[[[[mrqrqql;4oQttqqrq4gRtttrqqC5gRuutrqrɽfcccbbb``^^puutttr<Uvuuttt?Uwvvuur>UwwwuutL$$$$#%##]wwvuuLL9x4333awwwvv{3vwww|dbww)(v ౱ wJ~ޱ-ޱ ޱ }ޱYxޱy}ޱZJ7   61ߘޱ8N ޱH0ޱ#N ޱLIMGNINH( @       05 0 1+17#8%:) 06+7=80I [ I'J,[#\'[)R-\+\.\0`*o,f.y,l1t5I8+\2 ^7%S<-^:(^<+u=%^A0\F6pC.vE-uF0vM7vO9vP; |FFFN@RiHC}\F}_I]Jdmmm12;6>$B(F-B#D$N.N5R9U=[>Y>G%Q.^>GHHLNRX-X#Z&f>e9`,c0f3i6m:p=YA]EfJjLqWiIkHnPxYtTexmBoBzNwE}L`jqفWفYXY_PTX\ًbޔj×tڝuj`dhhlorppwtx|| !#E?CMFROYJUDPGUde ! "$0%&,5*?*+-. 2"5 9!:,A.B,B-C6G0D/F0G%GX__]]ZZYWWVUTC 9wH`__]]ZZWWWVUUR ?j'a`__]]YZWWWVUUCȩ鬩 AWUUS饩WWUU鯩魩@WWWV鮩©qq\  &ZWWW鲩鴩rr\ZZWW䩩:rro!!! BZZZZǩ౩||n$_ZZYϼ ||n]_ZZϽ;22~~p////(((O_]_]Ô8#`_]]ς!a`__ddddKKKKJJJFFFFFEDPaa`_,eIqqaa`=.~[rqqaatirrqqqak.||rrqq1͑zQ~||rrqՁk͑. ~~|||rr)͑fM~~||rds0~~||u~~|u~~yg=< %/">#?&>.#K V @ `&E0$D4(N:,S6'Y7'Y7(U<-o@*fE2oO;zM5}R: [D(Cj;Mc8PDDD]SEm@VqNmnnn;?=E)N5N2S4W9F$C H%L)Q.O3V4Z9U1ENRX#])c0f4i6p=^CaGrWcCbFdGkGqMvS|XgzsKo@wHwE~L~P^fkWXT\؟xfciks~|iH ((;;rrPP^^iiڥĘʞΨϤԩٮ!%!TE#3==;:987%Y`dfea./'&(87Jcyykcc 98eyyjclf :9fygcjyf#;:ihcgyycE<;mchyyc><rmffc$HGF+6?>srq_]\ZPN?usrBQ_][VONvusp ^_CWVOwvusR[ZWVtwvusS ^]\ZU%"twvusrqon_]Y!%!(0` %F;;;F )< = ?>$;;;  ]( " # ! -O---  #L+*......,$'T1:O*i7i6g4e2c/a-_+])['Y%W#V!TRQONLKI?w';;;F-1t+.........., ! M5OO*j8i6g4e2c0a-_+])['Y%X#V!TRQONLKIHC:F&-m-..*A)5...$ T1:[0l9i6g4e2c0a-_+])['Y%X#V!T RQONLKJHC;;; #1..~w... #'|<(h8l9i6g4e2c0a-_+])['Y%W#V!TRQONLKIHw'%=..XO...- >1bY0n;k9i6g4e2c0a-_+])['Y%X#V!TRQONLKJ?"`..jh(6.....(* 0QONLKI'>..$4..2.. */RQONLK$...%6..2.. "?0T RQONL8...(..2..&Fd0n4n3n2n1n0n/n.n-n-n,m+m*m)m(BV!T RQON <...*..2..)*HoAwEtB`6I!I I HIHHH H H H =X#V!TRQO <..,49..2..);,GuFyGwEZ33Y%X#V!T RQ+..)JO..2..&N37|L{JyG[54['Y%X#V!T R..,JP..2..3l8#O~M{J_88])['Y%X#V"T (.-%4;..2..H8clCRO~LsES1R/P.O,M*K)J'I%G$F"D!T'_,])['Y%X#V!X..&'..5.."8E,TROa;7a-_,])['Z%X#(....--.1 'F-WTRc=9c0a._,])['Z%....&-..!+tH/YWTd?:e2c0a._+])['...-+.........NHeEiGgE{Q\YW|O]:[8Z7X5V3U1S0R.P,N*M)\0g4e2c0a._,])•0?...........[                    >!j7h4f2c0a._,w4A......*f=!l9j7h4e2c0a.ԝ|-(P </?"n;l9j7h4e2c0ė•~[DF2%F1%F1$F0#F/"F/"F.!E. E- E,E+E+E*E)E)E(E'E'E&E%E%E$E#E#E"E!E!N,p>n;l9j7h5e2ƚė•|\}XA|W@|U>YAuvsqnligda_\YWSF,{@'{?&{=$R0wEuCr@p>nnn;l9ˠʞȜƚė•T:+~{yvsqnligda_[4"qF~M|JyHwEuCs@p>n<̠͢ʞȜƚʕ,! z~{yvtqnligd] $ QO~M|JyHwEuCs@p>Ϥ͢ˠʞȜƚʖpT@nR~{yvtqnligdDg8$TRO~M|JzHwEuCs@ѦϤ̠͢ʞȜƚʖĕr7'~{yvtqnli>&gBWURO~M|JyHwEuCӨѦϤ΢̠ʞȜƚʖ'_~{yvtqouR  YZWURO~M|JzHwEԩӨѦϤ̠͢ʞȜƚʖjR2$~{yvto:%L3_\ZWTRP~M|JzH֫ԩӨѦϤ̠͢ʞȜƚĘ ]E~{yv[A \b_\ZWURP~M|J׭֫ԩӨѦϤ̠͢ʞȜƚĘpV}^~{xVS9gda_\ZWURO~Mٯ׭֫ԩӨѦϤ̠͢ʞȜƚ=/$iL9ڜtܚqoM83 iigdb_\ZWUROڰٮ׭֫թӨѦϤ΢̠ʞȜƚګ% ԉaoligdb_\ZWURܱڰٮح֫ԪӨѦϤ΢̠ʞȜƚΡ} DŽ_tqoligdb_]ZWUܱܳڰٮح֫ԪӨѦϤ̠͢ʞȜƚҤ  ͋eyvtqoljgdb_]Z[ֿݳܱڰٮ׭֫ԩӨѦϤ΢̠ʞȜƚ峋bL;\A1t~{ywtqoljgdb_\xTyf޴ݳܱڰٮ׭֫ԪӨѦϤ΢̠ʞȜƚĘ⯇pmkihz~|yvtqoljgdb_~M9;;;Ы޴ݳܱڰٮ׭֫ԪӨѦϤ̠͢ʞȜƚʖ~{yvtqoligd_ FGB9ѫ޴ݳܱ۰ٮح֫ԪӨѦϤ΢̠ʞȜƚʖ~{yvtqoljdA,$F;;;yfֿ۳ܱڰٯح֫ԪӨѦϤ΢̠ʞȜƚʖ~|yvtsψeU@  --- ;;; F;;;F( @ :777:\\:7#Y>exBQ0$ >K]Jdf.B#X-c1c0`,])Z&W#U RPNKH65 :8%فYde+....-$CO[)D$]0e2c0`,])Z&X#U RPNKJG5 777nPvp..!:cgsn.E..&FQl1S,e4f3c0`,])Z&X#U RPNLJ6Ɔ.. 9.. "6+7;T$\'[&[$[#["[![ [ 2PNLHiY.fb*?...+CM[ RPNL"5..B.0D":.AO) @I"I!I III I I 1U RPN..,A..CCW.BQM.l?e90 0 0 0 0 00y,X#U RP..E?6G.,B-D.FR^9uFe:["Z&X#U!R[V.% 2.1D.-N@RqF}KoB]-],]+])](]']&;])Z&X#U!...--C.MZ QPmB    o,`-])Z&X#j`..* " !&..9NWTnD[&c0`-])Z&yh......,5iHCpC.vE-\XzNu>&u<%t:#t9!t7t5t4G%f3c0`-]*ݣk!# | 0`*j7g3c0`-ڝu\)m:j7f3c0ė묂^F\DZBX@V>U$Q.p>m:j7f3ǛĘS<-fJwsplhd`\XI(N.wEtAp>m:j7ɞǛĘ^GZ>-{wsplhd`[ f>{IwEtAp>m:̡ʞǛĘj |{wtplhdkHP~M{IwEtBp>Ϥ̡ʞǛĘ xY{wtplh^9&R-TQ~M{IwEtBҧϤ̡ʞǛĘ\F6:*{wtp݊`^>XUQ~M{IwEԩҧϤ͡ʞǛĘ×tyZ{wt[;) ^\XTQ~M{I׬ԩҧϤ͡ʞǛĘI8+ ؛t{jL[>d`\YUQ~Mٮ׬ԩҧϤ͡ʞǛ۫  ^F`^A0?(khd`\YUQ۱ٮ׬ԪҧϤ͡ʞǛq +jplhd`\YUٱ۱ٮ׬ԪҧϤ͡ʞǛt ;)rxtplhd`\Zݳ۱ٮ׬ԩҧϤ͡ʞǛ츏qW}_I}]G}\F{\{xtplhd`jJ777=80ݴݳ۱ٮ׬ԪҧϤ͡ʞǛĘ{xtplhe9$:>80ٱ۱ٯ׬ԪҧϤ͡ʞǛĘ|xtpuU9&:\\:777:(  @:::Y7'WdGoAUj;MO3f4c0])X#RNEV :::f^A D(CF$C ?;=NE] ^^ $$$,RN PPiic8Po@*o@*o@*o@*X#R ((PPl@W)))$])X#fg((bFo@*o@*o@*o@*c0])ڥ;; l&j7c0Ęۦ eG|vSqMkGN2@ U1p>j7ʞĘN:, zsldo@*xIwEp>ϤʞĘrW^{ti >#T~MwEԩϤʞ /"~{}R:cC\U~MٮԩϤʞf%E0$S6'ld\UΨٮԩϤʞkD4(>.#wU?ytldX:::]SEΨٮԪϤʞĘ|tfY7(:::Ext/Icons_04_CB/Finals2/plockb.ico0000664000000000000000000005600610063513620015507 0ustar rootroot (n00 >h00 %N!  F hW( @ppwwpwwwpwwpDDDDDDOpppDDDDDDOpDDODDOppxDDODDOppDDODDODDODDOppDDDDDDOpDDDDDDOppOOppOOpOOxOOOOppOOppDDOwDDDDppDDOppwwwxwpwwpppp??( `pwwwwpDDDDww`DODwwwwDDDDOO`OGtpO`p(0`      !% 3$!!!&#"%$#%%%+%#.(&/+*<,'1-,70.81/333720666831;42976?75999R/#R1%R5+S8.@:9@=<T;3T?8UB;YC;BBBLFDTF@THD[JDVLHWOLZOLWPMZPM^PLWUT\ZYsPCm_Zq\UmmmygayictttJ3M;O8P>P:TCYJUA]J^R^EbUfZi_i^n^cFeJiNhQmXmSmQp[qYsYjbmbpgrjtfwswqxszu~yvcxf{e~iqOsLvPxRzU|V}Y{|}mrw|[]ډm̉rӌtΒ}ږ~`bdfikmps{x}˝՗Ӛᝆ읂٨㦑ﮘȰİȰͳʹԷʶʹɺϿ׾ػ൥½½¹ǿõŻŸɿ±óijĴŵǸȹ˼̾<,,<!?6aa3 ?qc,61,&ٳ~vnlll ƥ~~vvnllljj~q֥~~~nvllljjjl簈~~vnnlljjji}٬~~vnllljjiij,ְ~~vvllkkjiii,尰~~~vnlljjiiiq&򳳱   @iii?Ƴ  @iii~?7Ƴ  @kkji3uuttssrggfxXUURRQPPPhkkkil zT @mmkkj zW Bvmmkko****))))%)|f%$$#####"J}vmmlk<[[NNLLLLIIyFEEEECCCAV}}}mml <,8 |d  G~}mvm6, e G~~}vvva]][][[NNLL{IIIFFFCECY~}vv/..*.****)))))%%%%%#%%#S~vv   Hv H娧uuutttrrrffza,8 ZƳ %6,< .ij 9 </ ^ Oa + q!! 6Ʃ ! L I8a : ij4? ; 0ij?,a  ij'& = Mij,  0, 0-  >oo,&,87,'?88?!<,,<??( @    !$)9%,$"+'%4($:("2-,?2.444T8/E<9E?<T<3T>6i6%j8'j;*I@=k@1lD6BBBGFFZKF^SO^TPcVQ`^^aVdddujfzlgzlh}zzI5M:P=VE\M^NZG^P[@`OdWg\i]aHjWiRq_p[lapgsmriyowpyr{i~ptMvP|V~Z^~adfipvx~읁쟄ࠊɰӰʸ˾캩ŵǸ&&&#))"&a[~}[an|kdOMQiwlUwdONLJIHHFMkTnhRQOOOMJIHHFFJvloxhSSSQQONMJIHHFFFhlaV|ihhdSSQQOOMJIHHFFFeTakkigeSSQQOOMJIHHFFFFv&ywskHFLl&vtsHGFkawwt655///9SQ1-,,++3IHHM[&|xwweS JIHHw}&xw==6655;ee4..--,8MJIHi$xigOMLJS"*@>===7755///...:OOMLO)*ROOMQ)$CB@@===76652///<T90T=5m<+JA>UA9UC<UD>n@0nD5oI;DA@EEDVFAWJEVLHf]Z}aWhhhdUl^lVr_va}jtMxR{V|W~Zs_ņp`bfilstu~¥㩔멑朗ﭕ滫ŷɾ±ƶǸȺ˼Ϳ( (GKeZYaKG(DkQ<9309\4(GEcQ@?<930/QCG!oW/\(Mc\-+064񁁁Sqqqn ~jgdb_\~Y|WzTxRvPuMaﭖ{ qqqnqqqn%"!Ͽij윁tqnkheb_]~Z|WzUxRwPuNsL|Vﭖͳ% qqqnS2/-䀘~{xtqnkheb`]~Z|X{UySwPuNsLrJcŵɿ1+)S-%#"˽읂~{xurolifc`]Z}X{UySwQvNtLrJsLﬕ% 񸸸- þŵ잂|yurolifc`^[}X{VySwQuOtMrJqI읁ʹ \\\{ﮗ䀘잃|yvsplifda^[}Y{VyTwQvOtMsKqIﬕ{\\\{?<;ﮘ   !               I1tMsKtLŵ>64􉉉¾ó   !               J3wPuNsLdɱVRP   !  !           L5yRwPuNsLﮘTJFqƶ}zwurpmj}h{e{{xډmqYoVmTlQjOhMfKeIcFqO{UySwQuN}YȰq865ŵ±   !  !   ӌt{mX      O8}X{VySwQuNﯘ70.ȹŵò   !  !  !ӏw잂p[     P:[}X{VySxQd~x\˼ȹƶòUC=UB;UA:U@9U?8T>6T=5T<4T;3T;2ږ~힃|fS6,R5+R4)R3)R3'R1&R1%R0$R/#^E^[~Y|VzTxRƶú\$#"˽ɺƶijmclaj_i]g[fYdWcVaT_Rᝆ̉rXHWFUETCRAQ?P=NUC=UBN;L9J7I4[@~Z{VxReYʻƶ±!!!!!!T8/잂}9%      j;*^Z|VySȹ321ʼǷlbj_h\eYcVaTq_잃`OVETCR@P=N;aHc_[|Wﬕ2,*`^]˼!!!!!!T<3:'     k>/hd`\|^SP}zyskqhnelbj_h\fYcWaT_Q]NZKXHVETCiRmid`lzmh}zz"!!!!!!!!!!!   lD6sniepzmi`_^yrwpumrjpgndlai^g\eYcV`S^P\MZJp[xsoj^TQ332ZNJ"ZKFɺƵ°뫔)!^N잂~yto2-,sm",%#ɼʻƶ±~!!{i쟃~yuY""˼ǷòaV!#ࠊퟄYGFF+'%"cVQ˽Ǹó캩4($!U?7䀹ɺE?=ujf"#̱̽ȸyo!!~pﬕʺCCC%CBB&#""I@=Ӱ,$!!?2.ﭖB=;CCC%WWW""B:8{t/(%"%WWW  wnk"""""$ʻƶ±˿  % :53"$ JA>ʻͿ %1 껻1%CCBB?>% WWWGFFFDCWWW CCC%333`__}{{}{z`^^322CCC%YY??(  @0 60.60- 0 WWWC=;ǸB:7WWW ::9kb~ZxRf:99 WWW˼ulc[yStMWWW0C@?!        uNB:70ͿT?7T<4T90valVR1&R/#m<+{Vi ƶ    }jS8/    _|WȺ 765VFAUC=UA:l^S8/S8/S6+nD5h`60.766         sj60.nD5ɺ±㩔nD5ņp~t $ ¥˼òs."멑朗0DDCf]ZVLHŷA40}aWﭕC><0WWW721JA>@74D95滫WWW :::ɾ::9 WWWDDDDA@WWW 0766766 0Ext/Icons_04_CB/Finals2/plock.ico0000664000000000000000000006117610063242724015355 0ustar rootroot 00h ( 00 h^"00 %'  nM h^(0`pwwpwpxpp~p~pxp~p~~pp~~~pp~~~p~pp~~pp~p~p~pppxpwxwpppp??( @pwwpxxppp~p~~~ppppppppwwwwwwwppp~p~ppppwwpwwpp??( pwww~ppwpw~pwwwp~xwp~pwwwp(0`       +,+#""&1" .#3"3$8!!!!$$$-%#2&"3($:*$:,'0.-5.,50.;1.655<30><<N)W-M+ M, Q-!O6-R1%R4)M92G=:MA<zC/{E3{G5|K:BBBOIGREARHE_MFSMJWPMXQOTSRXUSjK@cPImmmtttF1H3H4Q>S:V>]>^>R@RAVEXG[LZEYD_Q]B_AaNaSbUdWfZi_h]k[m]aFcIaFhRu]k`pfvnrfxtxr}w}z}x}g|eiGlKhCy\lBnEoFpGqIsLtMvPxRzT|W}Y~p]̀ftǍxŐ}Ӕ`abdfikmpqtvyz|~ÑÔ͔ڜןŞ읁쟄ۡ¢åܦԩݬ襎䀹ﬕﮘﳞêʭ̴ر۵ֽؼ⶧뷥ṫļ¶°óijijŵŵǸɹʽʼ̾H< Dz{|{/m" F{P*'# d{{*odg1{K)h3e1uH5¾\f1H<C6 6\f13<n!G8O ee 7O qA! kkkbjjYbYYYYVVUTTTMMO;<EGľ4<*p(IEqE I**H< "*$".%"*'%0%!1*'=*#=,&1-+2.-20/>3/210444?62V,@)"@,%V/!E1)V0#V1$W4'X6*Y8-C95C;9A??Y;0Y<2Z>4p<+p>-A@?J@=Z@7VE?[B:[E>sA/j@1pA0tC2BBBDBBIDBZG@]TQ]WU^XV^ZYuSGk\W|d\bbbdddogdyolyqnzspztrF/G0M3O6W>[;]=\N\GbOcTj\t^u]qfxnyblJoNnImHpL_mCmEoGpGqIsLuMvPxRzT|W}Ylu~u]܇i~`abdfikmpqtvxz}~֚ß읁쟄ܡŧȦ复颉릎䀹ﬕﮘϭ޸ֿܼļźʿ±ijǷƵǸɹ˼̾P& &PP.@8.P)^l}xvtrrjXD*f}xvvrrpn\D`}xvvrrrnnV |}xvvrrrnn\D}}vvrrrnn\Dd}xvrrrnnV'}}xvvrppnP}vvvrrr\P3ľz]}xvvrrrN,}Z((irXPҕLc @grkP&"'b@hvv& H{ xv+ Sݽ" }v@T г }B JMGGG>><<775500B0 &#=Ļ&PFĻlPQ;Ļ_D̖ľ*PľyPDľ*ĻaDĻD Ļ eDDҡ'DDΔ3P&JTTK#PP& &P??(   ,(,5-!> 5 9!6)%1,+1,,210<30943965@*"@-&B62B95H>:g6&DCBUF@SLIigfhhh}ibumjD,S6U8^AdUk^`@gPnXnaujwq|toFoGrKpHsLtMuPxRzU}Y\чmp`abefjkmtvx~~읁֭䤍쥌朗䀹ﬕ⹪±ŵ˼̾   M*=972$ M 'HEC?9720#M,YVHEC?9722#Ma\TVJECA>823 NS&)% iVR;A 6h!]9 o/  = t"c_\XRJEB PtK.fdc_\YVJ+ xvtpmidca\YVMLxvtpmkdca^,M Lxvtpmkfc- MQvtpnOM  (0` %\\qqQ0%zF4T<^C\AQ8yB.P, \\\{1 P>x[_[}X{VySwQuOtLrJqIhFD.0\\\{-M4+t\jfca^[}Y{VyTwQvOtMrKqIpGoF\=K)͸-S8("{dspmjgda^\~Y{VzTxQvOtMsKqIpGnEmD\=6񁁁Sqqqn `Q~zwspmjgdb_\~Y|WzTxRvPuMsKqIpGnFmDmDF0 qqqnqqqn!sퟄ윁}zwtqnkheb_]~Z|WzUxRwPuNsLrJpGoFmDlB]=qqqnS.#ڜ읁~{xtqnkheb`]~Z|X{UySwPuNsLrJpHoFmDlCgB,S-!ۡ望읂~{xurolifc`]Z}X{UySwQvNtLrJqHoFnElCgB񸸸- Ôﭖ䀘잂|yurolifc`^[}X{VySwQuOtMrJqHoFnEmC^> \\\{ndﮗ䀘잃|yvsplifda^[}Y{VyTxQvOtMsKqIoGnEmCF1\\\{9/,ﮘﬔ잃윀}zvspmjgda^\~Y|WzTxRvPtMsKqIpGnEnF6􉉉ﯘﬔퟄ윀}zwtpmjgdb_\~Z|WzTxRwPuNsLqIpGnF]>PC?Ĵ°ﳞןŐ}͔襎ퟄ읁~zwtqnkheb_]~Z|WzUyRwPuNsLrJpHoFK*q¢ǸŴ±뷥rf2&"jK@Ӕ읁~{xuqnkheb`]Z}X{UySwQuNtLrJpH^@q3,*Ϳʻȸŵԩ3($ m]읂{xurolifc`][}X{VySwQuNtLrJqJ0wqͿ˼ٲ k[잂|yvrolifca^aFW-vOtMrKE0\ؼʽ?41 Ǎx힃윀|yvhR++S1%gdaaGO)xRvOtMkJ\ N80祝쟃윀}zaM2jgdcIO*zTxRvPuOVNKG=:J<7&ڝ쟄윁}bO1njheKN*|WzTxRvPP."ws -%#ṫǷcPI,|XzUySzD2ֽ;ʻǸ⶧ +Z}X{UT=˶ʭͿʼǸ+^[}XaFŽ~Ϳ۵+a^[bH β¶MA<+da^XB}zSLI,&$ i_k`j_h]g[eYdWbUaS_Q]O\M[KYIXGVFUDSBR@Q>ZEgdb{J9WSQ_MFﬕ晴ퟄ읁}zwtqnkheQ3( TNLذŴ±ﭕ朗ퟅ읁~{xtqnki\1., ʻǸŴ±ﭖ朗읂~{xuròe\OIG!Ϳ˼ȸŵòﭖ䀘잂|yurUD432TMK 930}w˼ȹƶòﮗ䀹잃|yw1"q˽ɹƶóﮗﬔ쟃윀}|fqRQP̽ɺƷijﬔퟄ읁M7/̾ɺǷĴ°ﬕ朗o<::̾ʻǷŴ±ﭖ朗8*%􉉉\\\{Ϳʻȸŵ±ﭖ䀘fY\\\{ Ϳ˼ȹŵòÑ -"""˼ȹƶòܦ!񸸸-S0//˽ɺƶijݬ.%"Sqqqn"""̽ɺǷĴŞ!qqqnqqqn ̾ʻǷtl qqqnS<;;å:2/񁁁S-RQQêPFC͸-\\\{433ļ|w3.,\\\{ WTS~{xWPN qq\\????( @ YYCCC%-U0#p>,p<+U. -CCC% WWW?(![F_\}XzUwQuNrJmHL2=!WWW %<)"xanjea]}YzUxQuNsKpHnE[;:%1 bS~xsojfb^~Y{VxRuOsKqHnFmDE. 껻1%  t잃~ytpkgb^~Z{VySvOsLqIoFmCZ:  %  }望쟄~zuplgc_[|WySvPtLqIoFmDZ: WWWpe䀘ퟄzvqlhd_[|WyTwPtMrJoGmDF/WWWCCC%=2.ﬔ윀{vrmid`\}XzTwQuMrJpGnE:CCC%ßܡ֚릎읁|wrniea\}XzUxQuNrKpH]=B84ɹŴu0%!\N颉읂}xsnjea]~Y{UxRuNsKpH="YͿɺ|d\E1)颉잂}xtokfb^W>V-V,nIsLN5YʿuSG잃~yu] :"gcsA/lJvOpL0,*?63.%" 复쟄t^!lgtC2oNySvP-\SPȦǷ~ |XzTU/"yolļ1*'̽Ƿ  \}Xp?.yqn źϭ a]pA0]WU*'%*$"k\WZG@[F?[E=[C;[B9Z@7Z?5Z=4Y<2Y;0Y9.Y8,X6*j@1faV3&1/.VE?°ﮗ잂~ytokf.IDB ޸ƶ±ﮘ朗쟃~yup܇iYogdJ@=ܼ˼Ƿò䀘ퟄzuaNYCAAֿ˽Ǹó䀹윀{?+$̽ȸijﬕkCCC%@>>̾ȹŴﭕ<+%CCC%WWWͿɺŵﭖi[WWW  ʻƶ±  % ʻƶ± %1 ˼Ƿwm  껻1%@?>ŧ>51% WWWCBBB:8WWW CCC%10/]YXztrzsp\VT1-,CCC%YY??(  @0 11 0 WWW>( gP`}YxQrKS6<WWW 988dU~tkb~ZxRsLoFD,976 WWWna䀘ulc[yStMoGE,WWW0@40䤍윀wme\zUuNpH<0֭6)%(p읂xof]^A`@U8 <30 쥌쟃чmg:!g6&uP 50/}ib⹪}X1521 H>:|t-#-"- -,,8!a1 umjUF@±朗~tj SLIwq˼ò䀹nX0BA@̾Ĵﬕ>+$0WWWͿŵk^WWW :::Ƿuj988 WWWBAA@73WWW 0 532521 0Ext/Icons_04_CB/Finals2/plock-blu.ico0000664000000000000000000006117610063243454016136 0ustar rootroot 00h ( 00 h^"00 %'  nM h^(0`pp~p~pppp~p~wwwwwwwwwwwwwp~~p~~~興p~~p~~~興p~pp~wwwwwwwwwwwwww~wwp~~~~~ppxp~p~ppx~pppp( @ppp~wwwwwwwwwwwwwwwwwwwww~wwwwwww~wwwwwwwwwwww~pppppwwp~pp( pwffffn~ww~p~ww~~wff`npppp~wpp(0`         " :$,!3 4%<%=/$H H H HE"I I%E&I&E*I(I+I,M-m)n-n/w'n0n2n4A,#E.!A,$F1$M2$N7)N8)W3![4"U;+Y:)n6 g8$n9"o;$o<&o>(|>%GB9\A1o@+oA,|@'~D+H/bL;lL8~M8|U>FFFQQQYYYpT@~U@}YBfffyyy/0034798=>!?BF,L3N6S9E"I&N,M*Q-Q0R0T1Y6Z;]:Z4a?b=CIIHJLNQRTT'_8\0U U!X#Z&])_,`6a-c0e2g4i5k9l9n<p=[C[A]@dKhLjRnRpVdDdCkJgEgBiGlKpO|]tSuRxV|[yfqGqFwMwSxT[{QsE|Or@tBwEyGzH|J~LejpDŽ_O^][SQTWZY]ȊeΉdԉaԐiĕrۛrcdaddcdeililntsspΡ}Ҥ|zuqtvx{|~ګֿ⯇峋řȜ͡ЫѦԩح۱N TOUMSOK|||zzyyu`, T2|||zzyyywtN|||zzyyywt T Q|||zyyyyw, ||||yyyy`7 X|yyyyv(V||zyyy(V|||zyy֓EEE@@@@@@;@;;;;;+;*******))a|||zzK(($((######h#^|||z4FqV|||4Fq[|||: bq ]|䬛rrrjjjhgggffff~|4G[6Gs\4Hs\ƥrnnnmmmjjii9  _5_6_R3333242$2$$$$$$$#######hRRLGFFFlũFom97 ѾPљ<ۣc ePJI Cū K TӽNB2UQOSMUOT N( @          " 05 0 0 1+1119%:)?(=80I I [ [ [!I!I#I%I'I(J*J,[#[%]&\'\(R-\+\,\.\0`*o,y,t5I8+\2 ]4"^7%^8&S<-[;)^:(^<+Z>-`4!t9"u=%^A0\F6wF.uF0uI2vK5vM7vO9vP;FFF}\F}_Immm12;6>$@&B(D*F-N.J1N5R9U=[>G%Q.^>GHHJLNPRU X#Z&])f>e:e9`,c0f3i6m:p=YA]EfJjLqWiIkHxY{\tTmBnDoBzNsAtAwEzH}L`jqtفWXY_PPTX^\ًbފ`ޔjڔl×tۛs؛tڝuj`dddhkhlorpppwstwx|{|۫묂츏ėřɞ̡Ϥҧҧԩ׬ٮٱ۱ݳݴNQ~wwvuussnmmkkihfUNwwvutssnmkkkihhdQwwvutssmnkkkihhU;93322020---***** Skhhe kkhh))))&&&&&&&Rkkkir6nkkkr*nnkk@@??9?9;2200---Tnnnm5tnnm-ttnnMLKKKHHGDDDD777autts4vuts0wvuuzzzy___^]]]ZZZZXXVbxwvu={&[wwvP@pwwō w@/Fcƞ@8 |`Ⱥ zEȎȎ Ƚ}POOQNQN(     $$ % 1 :> >%:>/">#:#:%?&;'>.#A K V @ ](`&E0$D4(N:,S6'Y7'Y7(U<-o@*fE2oO;zM5wU?}R:DDD]SEnnn;?=E)N5N2S4W9C H%L)Q.V4Z9U1ENRX#])c0i6p=^CaGrWcCkGqMvS|XsKo@wHxIwE~L~P^fkWXT\؟xfcdilklsty~z|ĘʞΨϤԩٮ*,*!VXQPCBA@?>=<,[\L:98765.-/=<b`1>=gb'$$$0M$$$$?>hgD3N @?ihE$$$4R$$$$A@ki& BAlkZ#%KJIH2;CBmlkgb`\$RPComlFSgb^XQPpomjeg)GYXQqpomT  ^\YXnqpomU)eb`\W,+nqpomlkihgb["*,*(0` %F;;;F ;;; ---  ~M8wSYTQO~L{JyGwEtBr@p=n;l9i6g4e2c/a-_+])['Y%W#V!TRQONLKI?w';;;FA,#^^\YVTQO~L{JyGwEtBr@p=n;l9i6g4e2c0a-_+])['Y%X#V!TRQONLKIHC:F cca^\YVTQO~L{JyGwEtBr@p=n;l9i6g4e2c0a-_+])['Y%X#V!T RQONLKJHC;;;T@ifca^\YVTQO~L{JyGwEuBr@p=n;l9i6g4e2c0a-_+])['Y%W#V!TRQONLKIHw'ψdkifca^\YVTQO~L{JyGwEtBr@p=n;k9i6g4e2c0a-_+])['Y%X#V!TRQONLKJ?snkifdaW3!0QONLKIsqnkifdM-/RQONLKvsqnkifM.0T RQONLxvsqnki]@oB-oA,o@+o?)o>(o='o<&o;$n:#n9"n8!n6 n5n4n3n2n1n0n/n.n-n-n,m+m*m)m(BV!T RQON{xvspnkN6I,I+I+I*I)I(I(I'I&I&I%Q0yGwEtB`6I!I I HIHHH H H H =X#V!TRQO}{xvsqnM0"~@'|JyGwEZ33Y%X#V!T RQ}{xvsqM1"~B(~M{JyG[54['Y%X#V!T R}{xvsY:)           G,O~M{J_88])['Y%X#V"T ~{xv[nMlLkJiHgFfDdCbAa?_=]!j7h4f2c0a._,N7)=!l9j7h4e2c0a.N8)?"n;l9j7h4e2c0ė•~[DF2%F1%F1$F0#F/"F/"F.!E. E- E,E+E+E*E)E)E(E'E'E&E%E%E$E#E#E"E!E!N,p>n;l9j7h5e2ƚė•|\}XA|W@|U>YAuvsqnligda_\YWSF,{@'{?&{=$R0wEuCr@p>nnn;l9ˠʞȜƚė•T:+~{yvsqnligda_[4"qF~M|JyHwEuCs@p>n<̠͢ʞȜƚʕ,! z~{yvtqnligd] $ QO~M|JyHwEuCs@p>Ϥ͢ˠʞȜƚʖpT@nR~{yvtqnligdDg8$TRO~M|JzHwEuCs@ѦϤ̠͢ʞȜƚʖĕr7'~{yvtqnli>&gBWURO~M|JyHwEuCӨѦϤ΢̠ʞȜƚʖ'_~{yvtqouR  YZWURO~M|JzHwEԩӨѦϤ̠͢ʞȜƚʖjR2$~{yvto:%L3_\ZWTRP~M|JzH֫ԩӨѦϤ̠͢ʞȜƚĘ ]E~{yv[A \b_\ZWURP~M|J׭֫ԩӨѦϤ̠͢ʞȜƚĘpV}^~{xVS9gda_\ZWURO~Mٯ׭֫ԩӨѦϤ̠͢ʞȜƚ=/$iL9ڜtܚqoM83 iigdb_\ZWUROڰٮ׭֫թӨѦϤ΢̠ʞȜƚګ% ԉaoligdb_\ZWURܱڰٮح֫ԪӨѦϤ΢̠ʞȜƚΡ} DŽ_tqoligdb_]ZWUܱܳڰٮح֫ԪӨѦϤ̠͢ʞȜƚҤ  ͋eyvtqoljgdb_]Z[ֿݳܱڰٮ׭֫ԩӨѦϤ΢̠ʞȜƚ峋bL;\A1t~{ywtqoljgdb_\xTyf޴ݳܱڰٮ׭֫ԪӨѦϤ΢̠ʞȜƚĘ⯇pmkihz~|yvtqoljgdb_~M9;;;Ы޴ݳܱڰٮ׭֫ԪӨѦϤ̠͢ʞȜƚʖ~{yvtqoligd_ FGB9ѫ޴ݳܱ۰ٮح֫ԪӨѦϤ΢̠ʞȜƚʖ~{yvtqoljdA,$F;;;yfֿ۳ܱڰٯح֫ԪӨѦϤ΢̠ʞȜƚʖ~|yvtsψeU@  --- ;;; F;;;F( @ :777:\\:9$iIYTP~LzHwEsAp=m:i6f3c0`,])Z&W#U RPNKH65 :9&d`\XTP~LzHwEsAp=m:i6f3c0`,])Z&X#U RPNKJG5 777tTgc`\XTP~LzIwEsAp=m:i6f3c0`,])Z&X#U RPNLJ6pkgdX\4"\2 \1\0\.\-\,\+\)\(\'[&[$[#["[![ [ 2PNLHsokgفW[ RPNLwsol_J,J+J*J)J(I'I&I%I$I#I"I!I III I I 1U RPN{wsoߋa11111103zHwEe90 0 0 0 0 00y,X#U RP{wsًb}LzIe:["Z&X#U!R{wj^<+^;)^:(^8&^7%^6#^4"`4!P~LoB]-],]+])](]']&;])Z&X#U!{ޔj     " TPmB    o,`-])Z&X#ڔlXTnD[&c0`-])Z&wvP;vO9vM7vK5uJ3uH1uF0wF.\XzNu>&u<%t:#t9!t7t5t4G%f3c0`-]*ۛs`*j7g3c0`-ڝu\)m:j7f3c0ė묂^F\DZBX@V>U$Q.p>m:j7f3ǛĘS<-fJwsplhd`\XI(N.wEtAp>m:j7ɞǛĘ^GZ>-{wsplhd`[ f>{IwEtAp>m:̡ʞǛĘj |{wtplhdkHP~M{IwEtBp>Ϥ̡ʞǛĘ xY{wtplh^9&R-TQ~M{IwEtBҧϤ̡ʞǛĘ\F6:*{wtp݊`^>XUQ~M{IwEԩҧϤ͡ʞǛĘ×tyZ{wt[;) ^\XTQ~M{I׬ԩҧϤ͡ʞǛĘI8+ ؛t{jL[>d`\YUQ~Mٮ׬ԩҧϤ͡ʞǛ۫  ^F`^A0?(khd`\YUQ۱ٮ׬ԪҧϤ͡ʞǛq +jplhd`\YUٱ۱ٮ׬ԪҧϤ͡ʞǛt ;)rxtplhd`\Zݳ۱ٮ׬ԩҧϤ͡ʞǛ츏qW}_I}]G}\F{\{xtplhd`jJ777=80ݴݳ۱ٮ׬ԪҧϤ͡ʞǛĘ{xtplhe9$:>80ٱ۱ٯ׬ԪҧϤ͡ʞǛĘ|xtpuU9&:\\:777:(  @:::Y7'WT~LwEp=i6c0])X#RNEV :::fcsKZ9V4Q.L)H%C ?;=NEskN5%% $ $ $ $$$,RN{szM5o@*o@*o@*E)o@o@*o@*o@*o@*X#R{^C* $) S4wH)))$])X#aGo@*o@*o@*W9~Po@*o@*o@*o@*c0])oO;&j7c0Ę؟xU<-fE2|XvSqMkGN2@ U1p>j7ʞĘN:, zsldo@*xIwEp>ϤʞĘrW^{ti >#T~MwEԩϤʞ /"~{}R:cC\U~MٮԩϤʞf%E0$S6'ld\UΨٮԩϤʞkD4(>.#wU?ytldX:::]SEΨٮԪϤʞĘ|tfY7(:::Ext/Icons_04_CB/Finals/0000775000000000000000000000000012606740430013456 5ustar rootrootExt/Icons_04_CB/Finals/plock-dis.ico0000664000000000000000000006117610063310766016052 0ustar rootroot 00h ( 00 h^"00 %'  nM h^(0`pp~p~p陙p陟~~wwwwwww  ~ ~ 興~~~~~陙興~陙~wwwwwwwwwwww~wwp~~~~~ppxp~p~ppx~pppp( @ppp~陙陙陟wwwwwwwww   wwww  wwww陟陙陙wwwww~ppppwwp~pp(  p w ffn~w~p~ w~ ~ff`npppp~wpp(0`     " :$,!3 4%<% #-%$) <:>=/$H HE"I&E*M-m,n/w'A,$F1$M2$N7)N8)W3!U;+Y:)T1:n6 g8$o>(|<(GB9\A1oA,|@'~D+H/bL;lL8~M8|U>OX\ #L-(Pf"`&-m>1b!+t-1tM5OH8cFFFQQQYYYpT@~U@}YBfff{{{/0798=>!?BF,L3S9E"I&N,M*O*Q-R0T1Y6Z;Z4a?b=CIKNRT'[0_8\0Y$_,`6a-g4i5k8[C[A]@dKhLjRnRdDdCkJgEgBiGpO|]uRxV|[yfqGqFwMwSxT[{QsE|OvDyGejpDŽ_O^][SWZ]ˉdԐiĕrۛrccitsΡ}Ҥ|zuvx  + ) 0$4(6%6NHXO ! #+%&'"64:)+-12)5)?0?4A,CJOJPjh~ww|•ԝګֿ峋řȜ͡ЫѦԩح۱HHNIINGG<:MII=´+_vvuttrrqqqqlllkkjjiV"N#DȿE_wuuttrrrqqqlllkkjjjjh HHA³+nvuuurrrqqqqlllkkjjjjhN/wvuuttrrrqqqlllkjjjjj"ɴBwwuuuttrrqqqqlllljjjjV@ǶPljjjjiɵOllkjjjOlllkjj,,,,!, WqlllkkǔsTqqlllkǚeOqqlqllÚeQqqqlllŚeSrrqqqlF```]\\\[[[[mrqrqql;4oQttqqrq4gRtttrqqC5gRuutrqrɽfcccbbb``^^puutttr<Uvuuttt?Uwvvuur>UwwwuutL$$$$#%##]wwvuuLL9x4333awwwvv{3vwww|dbww)(v ౱ wJ~ޱ-ޱ ޱ }ޱYxޱy}ޱZJ7   61ߘޱ8N ޱH0ޱ#N ޱLIMGNINH( @       05 0 1+17#8%:) 06+7=80I [ I'J,[#\'[)R-\+\.\0`*o,f.y,l1t5I8+\2 ^7%S<-^:(^<+u=%^A0\F6pC.vE-uF0vM7vO9vP; |FFFN@RiHC}\F}_I]Jdmmm12;6>$B(F-B#D$N.N5R9U=[>Y>G%Q.^>GHHLNRX-X#Z&f>e9`,c0f3i6m:p=YA]EfJjLqWiIkHnPxYtTexmBoBzNwE}L`jqفWفYXY_PTX\ًbޔj×tڝuj`dhhlorppwtx|| !#E?CMFROYJUDPGUde ! "$0%&,5*?*+-. 2"5 9!:,A.B,B-C6G0D/F0G%GX__]]ZZYWWVUTC 9wH`__]]ZZWWWVUUR ?j'a`__]]YZWWWVUUCȩ鬩 AWUUS饩WWUU鯩魩@WWWV鮩©qq\  &ZWWW鲩鴩rr\ZZWW䩩:rro!!! BZZZZǩ౩||n$_ZZYϼ ||n]_ZZϽ;22~~p////(((O_]_]Ô8#`_]]ς!a`__ddddKKKKJJJFFFFFEDPaa`_,eIqqaa`=.~[rqqaatirrqqqak.||rrqq1͑zQ~||rrqՁk͑. ~~|||rr)͑fM~~||rds0~~||u~~|u~~yg=< %/">#?&>.#K V @ `&E0$D4(N:,S6'Y7'Y7(U<-o@*fE2oO;zM5}R: [D(Cj;Mc8PDDD]SEm@VqNmnnn;?=E)N5N2S4W9F$C H%L)Q.O3V4Z9U1ENRX#])c0f4i6p=^CaGrWcCbFdGkGqMvS|XgzsKo@wHwE~L~P^fkWXT\؟xfciks~|iH ((;;rrPP^^iiڥĘʞΨϤԩٮ!%!TE#3==;:987%Y`dfea./'&(87Jcyykcc 98eyyjclf :9fygcjyf#;:ihcgyycE<;mchyyc><rmffc$HGF+6?>srq_]\ZPN?usrBQ_][VONvusp ^_CWVOwvusR[ZWVtwvusS ^]\ZU%"twvusrqon_]Y!%!(0` %F;;;F )< = ?>$;;;  ]( " # ! -O---  #L+*......,$'T1:O*i7i6g4e2c/a-_+])['Y%W#V!TRQONLKI?w';;;F-1t+.........., ! M5OO*j8i6g4e2c0a-_+])['Y%X#V!TRQONLKIHC:F&-m-..*A)5...$ T1:[0l9i6g4e2c0a-_+])['Y%X#V!T RQONLKJHC;;; #1..~w... #'|<(h8l9i6g4e2c0a-_+])['Y%W#V!TRQONLKIHw'%=..XO...- >1bY0n;k9i6g4e2c0a-_+])['Y%X#V!TRQONLKJ?"`..jh(6.....(* 0QONLKI'>..$4..2.. */RQONLK$...%6..2.. "?0T RQONL8...(..2..&Fd0n4n3n2n1n0n/n.n-n-n,m+m*m)m(BV!T RQON <...*..2..)*HoAwEtB`6I!I I HIHHH H H H =X#V!TRQO <..,49..2..);,GuFyGwEZ33Y%X#V!T RQ+..)JO..2..&N37|L{JyG[54['Y%X#V!T R..,JP..2..3l8#O~M{J_88])['Y%X#V"T (.-%4;..2..H8clCRO~LsES1R/P.O,M*K)J'I%G$F"D!T'_,])['Y%X#V!X..&'..5.."8E,TROa;7a-_,])['Z%X#(....--.1 'F-WTRc=9c0a._,])['Z%....&-..!+tH/YWTd?:e2c0a._+])['...-+.........NHeEiGgE{Q\YW|O]:[8Z7X5V3U1S0R.P,N*M)\0g4e2c0a._,])•0?...........[                    >!j7h4f2c0a._,w4A......*f=!l9j7h4e2c0a.ԝ|-(P </?"n;l9j7h4e2c0ė•~[DF2%F1%F1$F0#F/"F/"F.!E. E- E,E+E+E*E)E)E(E'E'E&E%E%E$E#E#E"E!E!N,p>n;l9j7h5e2ƚė•|\}XA|W@|U>YAuvsqnligda_\YWSF,{@'{?&{=$R0wEuCr@p>nnn;l9ˠʞȜƚė•T:+~{yvsqnligda_[4"qF~M|JyHwEuCs@p>n<̠͢ʞȜƚʕ,! z~{yvtqnligd] $ QO~M|JyHwEuCs@p>Ϥ͢ˠʞȜƚʖpT@nR~{yvtqnligdDg8$TRO~M|JzHwEuCs@ѦϤ̠͢ʞȜƚʖĕr7'~{yvtqnli>&gBWURO~M|JyHwEuCӨѦϤ΢̠ʞȜƚʖ'_~{yvtqouR  YZWURO~M|JzHwEԩӨѦϤ̠͢ʞȜƚʖjR2$~{yvto:%L3_\ZWTRP~M|JzH֫ԩӨѦϤ̠͢ʞȜƚĘ ]E~{yv[A \b_\ZWURP~M|J׭֫ԩӨѦϤ̠͢ʞȜƚĘpV}^~{xVS9gda_\ZWURO~Mٯ׭֫ԩӨѦϤ̠͢ʞȜƚ=/$iL9ڜtܚqoM83 iigdb_\ZWUROڰٮ׭֫թӨѦϤ΢̠ʞȜƚګ% ԉaoligdb_\ZWURܱڰٮح֫ԪӨѦϤ΢̠ʞȜƚΡ} DŽ_tqoligdb_]ZWUܱܳڰٮح֫ԪӨѦϤ̠͢ʞȜƚҤ  ͋eyvtqoljgdb_]Z[ֿݳܱڰٮ׭֫ԩӨѦϤ΢̠ʞȜƚ峋bL;\A1t~{ywtqoljgdb_\xTyf޴ݳܱڰٮ׭֫ԪӨѦϤ΢̠ʞȜƚĘ⯇pmkihz~|yvtqoljgdb_~M9;;;Ы޴ݳܱڰٮ׭֫ԪӨѦϤ̠͢ʞȜƚʖ~{yvtqoligd_ FGB9ѫ޴ݳܱ۰ٮح֫ԪӨѦϤ΢̠ʞȜƚʖ~{yvtqoljdA,$F;;;yfֿ۳ܱڰٯح֫ԪӨѦϤ΢̠ʞȜƚʖ~|yvtsψeU@  --- ;;; F;;;F( @ :777:\\:7#Y>exBQ0$ >K]Jdf.B#X-c1c0`,])Z&W#U RPNKH65 :8%فYde+....-$CO[)D$]0e2c0`,])Z&X#U RPNKJG5 777nPvp..!:cgsn.E..&FQl1S,e4f3c0`,])Z&X#U RPNLJ6Ɔ.. 9.. "6+7;T$\'[&[$[#["[![ [ 2PNLHiY.fb*?...+CM[ RPNL"5..B.0D":.AO) @I"I!I III I I 1U RPN..,A..CCW.BQM.l?e90 0 0 0 0 00y,X#U RP..E?6G.,B-D.FR^9uFe:["Z&X#U!R[V.% 2.1D.-N@RqF}KoB]-],]+])](]']&;])Z&X#U!...--C.MZ QPmB    o,`-])Z&X#j`..* " !&..9NWTnD[&c0`-])Z&yh......,5iHCpC.vE-\XzNu>&u<%t:#t9!t7t5t4G%f3c0`-]*ݣk!# | 0`*j7g3c0`-ڝu\)m:j7f3c0ė묂^F\DZBX@V>U$Q.p>m:j7f3ǛĘS<-fJwsplhd`\XI(N.wEtAp>m:j7ɞǛĘ^GZ>-{wsplhd`[ f>{IwEtAp>m:̡ʞǛĘj |{wtplhdkHP~M{IwEtBp>Ϥ̡ʞǛĘ xY{wtplh^9&R-TQ~M{IwEtBҧϤ̡ʞǛĘ\F6:*{wtp݊`^>XUQ~M{IwEԩҧϤ͡ʞǛĘ×tyZ{wt[;) ^\XTQ~M{I׬ԩҧϤ͡ʞǛĘI8+ ؛t{jL[>d`\YUQ~Mٮ׬ԩҧϤ͡ʞǛ۫  ^F`^A0?(khd`\YUQ۱ٮ׬ԪҧϤ͡ʞǛq +jplhd`\YUٱ۱ٮ׬ԪҧϤ͡ʞǛt ;)rxtplhd`\Zݳ۱ٮ׬ԩҧϤ͡ʞǛ츏qW}_I}]G}\F{\{xtplhd`jJ777=80ݴݳ۱ٮ׬ԪҧϤ͡ʞǛĘ{xtplhe9$:>80ٱ۱ٯ׬ԪҧϤ͡ʞǛĘ|xtpuU9&:\\:777:(  @:::Y7'WdGoAUj;MO3f4c0])X#RNEV :::f^A D(CF$C ?;=NE] ^^ $$$,RN PPiic8Po@*o@*o@*o@*X#R ((PPl@W)))$])X#fg((bFo@*o@*o@*o@*c0])ڥ;; l&j7c0Ęۦ eG|vSqMkGN2@ U1p>j7ʞĘN:, zsldo@*xIwEp>ϤʞĘrW^{ti >#T~MwEԩϤʞ /"~{}R:cC\U~MٮԩϤʞf%E0$S6'ld\UΨٮԩϤʞkD4(>.#wU?ytldX:::]SEΨٮԪϤʞĘ|tfY7(:::Ext/Icons_04_CB/Finals/key-grn.ico0000664000000000000000000006117610062624760015542 0ustar rootroot 00h ( 00 h^"00 %'  nM h^(0`pp7wwwzszszsc:r62pzzwzs:sc`pwww8zzzw6:z3zzz{zw77:zs x{w877`z{zwzzzzsszzsxxx77'0{zw{zzzzzzw::pwww777gwwzzz:zspw67w77zw:pz 'z:zzs:z0w8w:{szzw{z#spzw27rzp0wzzrzrx8{c7zr sw7 zpw '0rxp'r7pp'wx 'pw'z7 wwwwwwwjp www{{zzpwwxwzxz{p wwxxzr{zxzwwpcgxw{xxxxww87rxxxxwwzxxwxwxxx~7xwxwxwzpxxxwwxxxwxwxxxxxx pxwwz(xxwwwr7xxwww pp pp( @pwzwzw7:s#pzzw:w:rrww7:rz2wzzzw7z7:xwwzszszswx{zwzw7z:zww77:ssp xz zzpspw:70zw7xw c(w6rc xwwww s(z xxxsxz{wwzw xxzxxxxxxwwxxwzzp(xwxxxxw0p( pwzw:r'z77 xzz07zsp0z2 `p'p0pp (x8pxwxz0rxrxx#`(0`          '!,#+1:;:#"6%';*%>)*=-F#O(P!P)!O*!Q* U+"Q,-F13M75O:4T:3c<4d=(p7*q8)u92p>:^@=\B;cB:gB?cE9hB=tG?sIFFFQQQYYYFhLEoLFvN@xJIuQPwVXz]fffyyy$9'>;K=M:N?P,E-F.H/I1J3L4M5N7P9Q>U=UBPIUIVV]Q[T]AQHVJYL[N\Q^GYEXI[K\M^K^@W@XBYD[F]H^I_[c]d[dR`Zg_heoPaTcUdRbTeXg[hWhZiZjJ`LbNdOeQf^mUiShTi`lbpdqmxbpesfuhvctfvlxjxiyUjWlYm[p]q`s`tdvbvdwfxexg{hzhzi|l~zmπvwƅxdž}ƉnЀpтr҄t҅uԆwՈy֊{،}ٍېΕ̛ґڐܒޔܖ՚ٙ7A8B6@8(vllllggggRRQPPPPKKICAlllhhggRRRQPPPPKKILD7lljlgghgRRPPPLPKPLIDA3jjjlgggRRRPPPPKKKKLjjjlhghgRRRPPPPKKLCjlhhgggRRRPPPPKKIjjjlgggRRQPPPPKPmjjhggggRRQPPPLKjjjggggRRPPPPPjjjjigggRRRPPPú53<~mmjjggggRRRPPúr|jmjjigggRRRPÿ=WjjlggRgRRRYqjj,gRRè##b*ggR'5Hm,gggƸ[+lggs1Y$Wqq^^]]]U-HHEGgg2Zúlh$tlljj$Ï#/.#ot=#ж ~~||yyuuucubl$1Ѧ9n&=ÿ>nÿѽX%'oÿÿÿÿÿÿy?)A ÿ7B ?38@6B8A7( @  #$,)-/ 5"? !6% >%'6)%:)K$K%.I31R67V< v2+r9-s;/t=1t>3u@FFFDeIClJEuNNwUIzRS}YT[mmm.?0A9IE+R @?95-)'(T=/GGCA:721UTM=ILJGDCA:72WUTSONLJGGCA:7QWUTSONLJGDDA.QWVTSONLJGF9 (0` %F;;;F ;;; --- 3cVV 'F gwq҃oЁlj}h{fydwbu`s]q[pYnWlUjShQfOeMcKaI_G^E\CZBY@W>V ;;;:gBvԇsӅq҃oЁmj}h{fydwbu`s]r[pYnWlUjShQfOeMcKaI_G^E\CZAY@W>VVVVVV=T;S9Q8P6O5N3L2Kޕݓۑڏ}ٍz׋x։vՇtӅq҃oЁmπk~i{fzdxbv`t^r\pYnWlUjShQgOeMcKbI`G^E\D[BY@W>VV=U;S9R8P6O5NޕݓܑڏZg+:#Xgi|gydxbv`t^r\pYnWlUjSiQgOeMcKaI`G^F\D[BY@X>V=T;S9R8P6OޕܒFvN IVi{gzdxbv`t^r\pZnXlUkSiQgOeMcKbI`H^E\CZAX?W>UV=U;S4T:=tGk~i|gzexbv`t^r\pUh?POeMcKb:)q8@X?V=Uґ !l~k~i|gzexbv`t^rWjAQQgOeMc;+r9BY@X?V_h;cBR[%?)IUR_P^N\L[KZIXHVBP2p>>N=M;K, U+:NBY@X?cET]ޕّ%>)O(D[BY.G2ܖߕ`lP)F]D[';*"6%xdž P)H^F],D0#lx!Q*J`H^=\Bmx:^@"R+LbJ`]deo}ƉIuQ"R,NdLbΕ  iwjxhvfuescqap_n]m[kYiWhUfTdRbPaN_M^K\I[GYK^PfNd*?-;cBܒې}َ{،y֊wՈuԆr҄pтnπl~i|gzexcvat_s\qZoXmVkTiRgPfz  wƅݔܒې}َ{،y׊wՈuԆr҄pтnЀl~i|gzexcwau_s]qZoXmVkTiRgFhLU^ߖݔܒې}َ{،y׊wՈuԆr҄pтnЀl~i|hzexcwau_s\qZoXmVkTi5O:EoLߖݔܒې}َ{،y׊wՈuԆr҄pтnЀl~j|g{eycwau_s]qZoXmVkPwV [cߖݔܒې~َ{،y׊wՈuԆr҄pтnЀlj|gzeycwau_s]qZoXm՚V]/G3';*3M7[dٙߖޔܒې~َ{،y׊wՈuԆs҄pтnЀlj}hzeycwau_s]qZoߖޔܒې~َ|،y׊wՈuԆs҄pтnЀlj}g{eycwau_s]qߖޔܒې~َ{،y׊wՈuԆs҅pтnЁlj}h{eycwau_sߖݔܒې~َ|،y׊wՈuԆsӄpуnЁlj}h{fycwauߖޔܒې~ڎ|،y׊wՉuԆsӅqуnЁlj}h{eycwߖޔݒې~ڎ|؍y׊wՉuԇsӅqуnЁlj}h{fyߖޔܒې~ڎ|،z׋wՈuԇsӅqуoЁlj}dv̛ߖޔܒې~ڏ|؍z׊w։uԇsӅqуoЁlUdXz]ߖޔܒې~ڏ|؍z׋w։uԇsӅqуoЁ4d=;;;  ߖޔܓې~ڏ|؍z׋wՉuԇsӅeu F+<-ߖޔܓۑ~ڏ|؍z׋wՉiy2F;;;  Xz]̛ߖޔܒۑ{ԋdq;hC  --- ;;; F;;;F( @ :777:\\:,LYcudw`t]qZoWlTiQfNdKaH_E\BZ@W=U;S8Q6O4M2K0I,D v2 #:-ònπj}gzdwat]rZoWlTiQfNdKaH_E\BZ@W=U;S8Q6O4M2K0I.H+E #777UauԆq҃nπk}gzdwat]rZoWlTiQfNdKaH_E\BZ@W=U;S8Q6O4M2K0I.H v2u΅x։uԆq҃nЀk}gzdwau^rZoWlTiQgNdKaH_E\BZ@W=U;S8Q6O4M2K0I,Eڏ{،x։uԆq҃nЀk}gzdxau^rZoWlTiQgNdKaH_E\CZ@W=U;S8Q6O4M2K0Iܒڏ{،x։uԆq҃nЀk}g{dxau^rZoWlTiQgNdKaH_E\CZ@W=U;S9Q6O4M2Kޕܒڏ{،x։uԆr҃nЀk}h{dxau^r[oWlTiQgNdKaH_E\CZ@W=U;S9Q6O4MޕܒڏYe5" =%Tch{dxau^r[oWlTiQgNdKaH_E\CZ@X=U;S9Q6OޕEuNDPh{dxau^r[oXlTjQgNdKbH_CY0A.?3G;S9QblWgh{exau^r[oVk3u@1t>J^Kb@SK$>U;S)!?&k~h{exau^rXkEXNdBVK%@X>Uw/ 1R6WeYhVfSdQaK[Lb q€p~m|jygwdtaq^o[lXiUgRdObL_OcOeDeIIzRݓې|ٍy׊vԇr҄oЁl~h{exbv_s[pXmUjRg$!6%ܕߖݓې|ٍy׊vԇr҄oЁl~h{eybv_s[pXmUjל':*.I3֔ߖݓې|ٍy׊vՇr҄oЁli{eybv_s[pXmyS|YSZyߖݓې|ٍy׊vՇs҄oЁli|eybv_s[pߖݓې}ٍy׊vՇs҄oсli|eybv_sߖݓې}ٍy׊vՇsӅoЂli|fybvߖݓې}ٍy׊vՈsӅpтli|fyߖݓې}ٍz׋vՈsӅpтldvߖݓې}َz׋vՈsӅpтMZ777'6)ߖݓۑ}َz׋vՈp΂-:'6)ߖݔۑxЈVc.:\\:777:(  @:::(I.bsdw]qWlQfKaE\@W;S6O2K*B::::n}q҃k}dw]rWlQgKaE\@W;S6O2K*Bڏx։q҃k}dx^rWlQgKaE\@W;S6O2KޕڏYf9kCR`dx^rWlQgKaE\@W;S6OK}TAMdx^rWlARJ`-u;X+;Sۙ    aq\nTfEWK' "?Vw\evÃ8KLxSgr=O%yψs̃m}fx`rZmTgQfz   ozߖېy׊r҄l~ey_sXmyޞߖېy׊s҄ley_sߖېy׊sӅlfyߖېz׋sӅct:::@YDߖۑp(J.:::Ext/Icons_04_CB/Finals/plock-grn.png0000664000000000000000000010406410062625674016073 0ustar rootrootPNG  IHDR\rf pHYs   MiCCPPhotoshop ICC profilexڝSwX>eVBl"#Ya@Ņ VHUĂ H(gAZU\8ܧ}zy&j9R<:OHɽH gyx~t?op.$P&W " R.TSd ly|B" I>ةآ(G$@`UR,@".Y2GvX@`B, 8C L0ҿ_pH˕͗K3w!lBa)f "#HL 8?flŢko">!N_puk[Vh]3 Z zy8@P< %b0>3o~@zq@qanvRB1n#Dž)4\,XP"MyRD!ɕ2 w ONl~Xv@~- g42y@+͗\LD*A aD@ $<B AT:18 \p` Aa!:b""aH4 Q"rBj]H#-r9\@ 2G1Qu@Ơst4]k=Kut}c1fa\E`X&cX5V5cX7va$^lGXLXC%#W 1'"O%zxb:XF&!!%^'_H$ɒN !%2I IkHH-S>iL&m O:ňL $RJ5e?2BQͩ:ZImvP/S4u%͛Cˤ-Кigih/t ݃EЗkw Hb(k{/LӗT02goUX**|:V~TUsU?y TU^V}FUP թU6RwRPQ__c FHTc!2eXBrV,kMb[Lvv/{LSCsfffqƱ9ٜJ! {--?-jf~7zھbrup@,:m:u 6Qu>cy Gm7046l18c̐ckihhI'&g5x>fob4ekVyVV׬I\,mWlPW :˶vm))Sn1 9a%m;t;|rtuvlp4éĩWggs5KvSmnz˕ҵܭm=}M.]=AXq㝧/^v^Y^O&0m[{`:>=e>>z"=#~~~;yN`k5/ >B Yroc3g,Z0&L~oL̶Gli})*2.QStqt,֬Yg񏩌;jrvgjlRlc웸xEt$ =sl3Ttcܢ˞w|/%ҟ3gAMA|Q cHRMz%u0`:o_F}QIDATxieguWX(4!B b0a<%v<`N0m5f^K\`foG7f]<{=,fvͮ,J0=5Z7ރdAx6g0fע^k{,Hm5slϮu] O 8FgY< >Hh/> g:֟s*N9| xM|ˏ$h] ǿ7g4~Gq t?<YziOd~s{q;`dl7 _ht6)ϒ]mC;1@my=ݲ_?C{q {^=*"qWÖ ۰-xx&56> A-{]{.<[pǗ_߼ =rdG^Zky)%rX+O̘ay#?cT2. >#}rӘr¸xKr!2e)L?[;,]6w+B2Pb4M 3tg"7|NP:މ[|Sc~00q?:|}߫ҩ˵Sxņ#eiO82é2arF.39ӂm %M?R?)%;ߗ!"2f~b.0KΘq$} )V wR>U֫ a$w lS`>p7+\OJ>0?v㧾g2 Ǜb~aQ E^T OCC MtsX\TX3[S /ij锎dL1H"7Rk" N1Q)W,?貺\N#x)H𕿹_}~,XzLY{G@ΘW:_X:ӂ.nʥV.b:Ȉx.TS26 X9ll i*pvsYRLH˄ XLʬ{K cAlpvkq[zbvi je5w~w^*}궕Yk >oM˧RL}M07+NP豻`K-@@ҤW,&јąHh? r%7S]֡$cȐ8S1u9 8D` ɔ1a b+_w v-i_P*{|=4p=BfTo-|b0CC^) Hp|y  [VOPaAy{G;̰) tf7C>D%y߱4>ZV]YlcaϹ=&߉׾ՈԈ0oma"pu!,>3GN}CU!,\+[c$P=&ǰܒk #¢AvK ^t|)٤ 'ArF=Z.l%ݹ "mg~=!U a>ٸ_>p>~lz;.l;3iA3wr^sh1 nT-̒v޽ANNigiكp')ÊB:䧴ѨGLa#'h Q vy) $ p-Xisp ELih:mYI>~~^/vv]f?NL5"3 \kiiJa隀.chŐ%f2@<{Z2JPfih3EܫD*yaH,t8K B8rO({Bͽ8,HH L ҧ=_8tb,@/*pKY"K ty <|8O{&@;R>ElnѸIVsq\ MݚqEu8Vn>plZ]FQP8s@! inD^~spk,+jNN訢(6?rY^6P ېUck~R(AL dіT hkhA sOfS~ENl=g1:Lz'3#;ESEEWN[>]7=M3kJbK tQ{X2c2%L8LA7 Zg2X(BpB%vcU"]Ьd쪤ADeKHN/'=ض'\RsJN(ڡ(VA3)=ןe̩EᄌqC=yvGp!㽔aMlG Z /i[f hGYDi E / Bš]*oc>p4`yR"IdH=i'[sCZfz<34#  .FG8tb |^ _vTN992DZxH1M$+2΄cnND$"zor%چ ܔ< cz cE=O=oډ?u#nطg0,/3X]N?F̨Z\B& =-d BTz*A u Y iDzu5ө-\+J.yN\Z%_pH;qJ+̲6],^m C_7zRx5^h@1SDϑ 2a*06XF o}݂'ێ`/vľ=mxmbrqix?z%.",_6s%`f:7}FDŽ ӡ%3*MN|9;H~ 7~ݽKtx^~z|OK𜣞 UabteK^Hc~;l=oT@adX1v=)A>]I)0\|/> zo>'II5KM+e\ܠI~vZl3 "j8a!Cg lMo~yqz'^W]xQBt8 1-QK~^ۗ T"5JQjME6\o"_Ct60z?cwm^ OGcC1W 7BQ녻e }`{%4߲phЕf6cT}|?;ߎ7?nzo ZAקP7 iʙ @5䱛lRРX+$ٚo2#Y-~XΩi rxXvc*e|ӹ~:2"f\lf3g\*6?W5عuww|_/y&LW|7dpF΢ݣCIL L7}DOB"tq(ڹ_{Ʊ8uZYb6P{Q7q_K?GV1w3PAi3]X,}4yGl{#/9>_>mxG_}sAѿCHGOڡd^g˃d`޹dVS*;QXBLԢ| ɧ߰Эi'p!cYR볅P9gLQ{JG#TAL78~0v=c>mO{͒Qޒc)Sm鹅n;6VmLRTtϜwfsRTJ?Ǜ%qHg5q Ѹq`xo1$0Z^q7?=*; 6f0|/&5Њ]ۿ|~glzh˷^ħxb6o+8ݵ6MJS,G(XgK%X'>tqʧ {.jtC !4 l߸s 꽞[޲_QN[Y~G솄6F ۩hp 8kEV4!K_c<_>r5vo݂QܨH'AlX `v+,O~҅ePy:BـUI\p9l 㤨L + 1lMd"թYmEMlgY{I9ak6372 ſ2>?߄ڻ{nԭw[pkS+E{)-Dxxِ=!qB.F)o*M-*-XZ73瘝h.6neԖA07B|\"[ɸP|Czt5*>[wmx[6˱' sYqP0sl AYd{  ǡt<ҌA,w(¦uiDXFv2x2py6¥}h \:yN>\Wwx8ܯ>|#fpqA(+2L@٨C[XqJeA5J"|Kb[ٸk\yOOuL闳I]Dz]5$N b =X@1Sl-57 ۟M8x?>H[.ے7.;HHEIp bdַܥp={0>O oT|(d CpW_a>ww~Ok =~U]etgڔ*`^Š BmhvEY|fǒ_?B9= (~u&ʫѳ rNk}ל;f_xUT hq L]͏N8{/x-t0eCFhA"^}YwpP`T"T) v`0 gL8FTrU ANvv#1:@aS5`8T`~HtK;tC4`o~nO)ܔS'kO;bH)=`6vsg$Çn޷qn23au]7_g$C PWb,^}\Agֆh9%̃(?B|mXxtVô6m".xOnU܁hH` ʴZ3Taץ&Ɇ{6|,M?gXy cpGaVh ~+p'o K~eA|Cr2hIaYǒX4CE=ǷuH'QQ1K $m8JWEןgbXhpue6ޱ_WF[65Ǯi睂W?V-mرy7>Wv>?$>ވKD|{R#2-jPu-iQ m YO϶6%U図151A\7bۗi+_|998#a搌DIݵ;÷ou^}'vnݵYK?߇5ǯ ;&z v *̙ޛՄß n̙Id>`\bFԟWfa-)8eҍ' k;z_w[W 6À&t\ Bo_x5X3/\x ^׺hv՚Xf%֞z,^xq?q3n7uöE>ޏk.}˱չ+PusT{Hadϼ1(p`NP\j/o@8b;X x[oWA@G@uh6|YF|ϯ7mQS:"韾YNhktNOR]ѯν[|^`6T'>% (x< !8YW53֔?pLF`pqi@t*):h vfYioÉI 7ζYóUt}7ݏ/߇}{v9f5."'/Q'Y  bB%(k~1L'_/ZAk~.,9X}(!e(Ff^zv 扻4@q5`52kaР/ sm2E;4lnV䄺/xKw,9GtG9%j6VS@d:u{8 J+޹y=o`@|!k`5$L#] ECɾ4/E Of侥"!4 &iZO@CK6C@R4,b }N|>WW۰9\މGuxJ@w`~SKx~Vݽ _;2|. gk/qf#I ̀ S__rH5̓{z4ln^?!; pZKO~2t c%f *诎2fG2*w|xw 9nݏ'wuvn5u]X,fʳAsOp-J#9bӖ!: X)HfI42 " K2\&I~У $nvtխ X+m8uf)rPeDyD-)th5c`0 BKKWKo ^/=l߸S6uX>8SPR'z_e1 . kXجiWXTkY '%Tb} kp]Ens+~M8A2O^9aLw'!q/9<(X2zH]2|wJ"S-:`)&EƢ10Ѥ8ET:0'.bo]Glg#ss|%>TO hL@a7V1I]:GU y8Xjݣ{7`If% C%s؊+ݭҗ(iiJ^Bz 439hf,*O#p8!N #ͺ^}S8"=LWجKH*轺SdM?-݀ۯw(\ޛi,݃&k61 ufKҎBkf8D2F4-SH( Pbucݍ(٫~l{ 2!mj*u/)>6jh*ރI\I9,FVj P 8ZC[f8㤳_c.l}d{(^`zL@6Cֹҩs5}ˠUq{A@l&P5,^]ޖDZ0wGuŞ9ӏ.m*t1>{rhNLG;UϾ ^Tw/tK|oח: '#U]dk•( JsCvj&X:I,2HØ|[,RϽuj8l7mgJ+^#]+t`oQ&)5#^#tfc^v.|yXrقܳoy]uwRkjCEM( ^O$XZM07ڊ2ogbB!0-b)0uʎVBέ֚!b8'|fx<]b v]#}u42J ? Kq_姂 .NOP#;h}9o[چ=;%&j@ֲؗPmNV,Lu8)skˠ]viȂ)#+Ȝ (.~F%Y8{0M]_ >`3Osێ@J&v -W= {Ϡߺ\z&8rՂܻoڀbm9^XA3HqJ)6yڥ+sFE5"0NSl@ AFYsU_k}95I\T%}' u^LFa)+&2S0#`Euoj`pYL._9+pڅ,Ƚۻkmc9LB.28D}hCHRwxo`Y-z(F D1+1BC7 &U`1Iy*Ԏڱy';8k{SDxriPr2~"mt̘M7KZwV>głmwk&5m x;]  jIșf3zb!7e OxfG%Vs;SDP~V1ǟ݌|Ysp忺g4w[(,yS}(&塉Dz?9Ro*@RÙ؞ĥ8u kn|/oZ2g_h&z7FScp}(բ*Z0N6e/$:^B5bM.R l{#2_*)tȏFWTPQ]6 Km`?py_Gx.x xdFmcgv*l`.Itu٪p;tt- 8v= 5U  _\}L#%k jp?~}J>?M~,aDVXx3!&QUvRZȢ*gE){YϿL|/|X-Yv:Jf&8e8ԴK);^&,Od_`]{3ETL yʴtgSy;R#[eEzRb2?ekuT`Y:>1^UxzdB\A~߷Oo.LNEa:M?* 0/^A ]\/ 8$s9Ǯ;67siC ޤ<,?Q\sKO7@NX~Z1Qǻ,R,X`/ݵ"Jc3t e*kDu/=ugOɛQ -(+`ZnKaz?L%!`- ȕ/Z@vēΕHA.UCī!)?HdOzYe5.ELi$hbj4U`>ZN觹:Z@UWþkO<ģp,fى%[o._Rdv 5 A݊[#0J̆+Ni~!ge(yHsn5`9c4HSg$)>PҒ"Z`زyxQn>{Ɠ;¼]IRA0rbǧ#CQeԙd[}V82ur% V,å?r=yw_n@HEFJcUvI)1*R:.mD:`âH c7 h+ lA7&P\Md&B@ƽ[p=spԉG68`Ycb3~c,>hFF}~rly 3w9n?jFGԤAzY]]h]6`>c?&xxjP}ۭ|_? OAp݂'yV}Lj›H"EVemI"g4=:$tHEjGF:=~\ CB#>w^u roTبd);(ͬ,c)0P& LSFjolYCՑvnݍ?s˼/F3gވ ; ev|NU&y) gCܷ7tYNMӎ-j^W?1hCȭE݈@IlAǘIN%.Dd酹h I)[l}k=GqU=2,&Cw>k?y_V /{>V^7̺` 躌Z[!O}DaiPFT L8"KǮ; '=O< }nȨfe֠Y1`m՚d|ôR16d-/)ݣPG&K+1R 2d=Af;p-B[>>$,[ (pkm$/ *:E}OM2耗s8j6Y 8T=mC}yٱ޾1Dֈ``ؘfNWTc&> f6l&`܌KCX7,*zn22+w)r E׈;;;5ǬR>9q! @RxN*}jhuV-'PᾶO^w>ϻ4{[~bpOcaCM{+֡Es0..`؃Iʓ-בfb֖$!,U%؎-}}‘x?~%V=gۜqٗKA3؀90yJ˰" {Q0`kqYkן5عywO?"U? tJu('{_M&LЩ()&B K Q IȼS@͟ _uN<*OGRtq4UJ-Wy/@,.\"ż`mr)N2jEBp `dug~-ZOhQD _? )yCqT*u2?Q'UGL31xYTk>'*&w&FaLV\ B!ܛg^ԋ_{13t{wG,b )敚L%q0ld!5gN;Xjn JC(9VPRMk))܉:Aqޏ'*xOiAtr`jqi\Lp z&Gcs8zQ龭`ס҉f*Z8pPӫq΂)3D/߭If}Q0ԷdFD:.9:cnQ|W>|=y[_qFSaCJwB |e ?pĞ=W"]q*5gb|r򉻰m.0]b.i*]r&cK d ѭ8yRqqR/4gTU4EV7?ϯyy^ bC:urDEHźz pFk*I-WF}>K`q{^Ukw6`íc=!2Uw ,ը:B<աe&iDBu_DZN7GRm;>4]2 '݆s"tݸM'ʽqGlu5.M%C!=g%%J=rއv>?8XU58Ձ<9K8G B*ǡY zy}c1V"L61/*c:.f$j=W&- L}OQ @ոd %ro=}pZ]M`*t>gޟ]qVrM-DJ%iѭ jnۀ ~cLLꦆE\|dTI¢;p?矄;j҅!^¢xaf,(񬂈z +x—,7' tdpy'ሣMQԻƥdȇԟtQ6 p`U¦:^M[lXۖt3Pp=ƃ@ :>l߼s^%z9ν6Giȹb KV+ݸ='ب7Luy 7T(kO_ ==;:EhQRꨛª/hlEQ 2d3uR4"4Q5s"l%t~6-S[嫖ǜStcBbcE, (J^`$A<+ygFC)c=u{X}Lv]lavSqQY(-1Zaހ1PY뭽I-Y`f.M7!6Eiaq0v_eImޅ( uly`F4|D 4b`fe2c ny`o)m?83q @-&8>leݫl?b2cı2 =np(Wls-g31ښ%%6o~Ny ]:TյQuFCٞ$yCZMh*?uZFCuiŵ'su:*8UZUāudnn9il9N Lz~Z+ه03(=YY8g򠎣T2-p,Q9`٪8u:xs4w6C_Q+2f~'}Ř˺BZ"]j bW2U! OvP âpw+byؤnύlhV9z,?i9Q>À iQ : Wkr6ldpo u) ;Qc3`=d2;^K t-L+m @q[emKwnۅ}J3}Q0N8 8֟W+.o(*d4sZJJ'3fi:r440'^{x*G x_TG!# "S-N av;0҈uA>?w-rbBt1XB?ݿ;Xj9N9X~2 L gV.厵s'ڔԘnÙQӣ4@`X-Dj㨓G[nl[)?-QL4CP!sK8~˽L\:< JiE|\?ܔCGF!0 f;jH#.VZAe^VXup-G+N9r6#F8n~&0F(CʒȷP; t qA|zjHgt}]vNrI<d0He iZݵI~*G1UKW?ɤSq-|Էg_k[com-LXo0#E <;S\,zDK(} #I */vZo lɚЎf1׮Z|ahq R:a&a'cKQrf4=楳ahɍǡ&V5\R3QN\߭! +>lDVB; i:daQ:YͦT)g U,feFvXCYK<I1UQ[ ]5m#RҦMp95/V~׏̣drJV ok&3t {cB'f ͽ >8ܔoH LW//zu_"7&I'c-e1=сOc_J* ? a> e(Μ&Mc-HhQ~Μd\ ڛtDuv{/@BYDLχm%\u27R>M\)h~sfX3WQppA6G8/| SA"MՓEW2PA<w4tx?zo} t>!~gu߯golۋ~qlȥ12c-jl -.n~V~ 4e=kuR#w>5}(=e=R*a`j@˧uCmnt2m0 J]P&,뜈`A'SsOpfnd}§#!B1dA+-kve!0ѯLK'7a+k@7CnjO\Pq4YT8]J:EQV;=u{߇0KR$sfv[`3}o9k?%8>?`O{XS ]hc@)^0ܔJo(QP 5O[*&+s؛ 2cR]ʤ8Y4ĦxMA1!6C8lUe.\]WRWI *jN:Eo\% o@iZ^<אhJ2]M/X9CmkiFd4 Y9L6fr&%YDwǺ"2ʕqZk."*:`n#afǐ#i.Y WP1XOTƧp,$ s2f1tPߛ c*3dxTז@xhó\NVcڍ-GzB,]T?_vn,Xb 6N 0.21]iyi@N 5ξwo0kasvJl3n`mS OetDt1R%*ƖKxvg3OIHϸ wfB9˞FYkv̵LRy%%rXh KtZs6kήyDn2a`"xƣcpX]҅a`7+-ax#*Y]k~0T]>셩LUܚǝ} (( R[ml/?wz건Y;tT 6):}}g#w|p}Em~fQk?s]q4Y=J&N~͑@f>KɈB ̲td=wnmqI,"C4LКi XiyC 殞iBq w,DP$˲=uA@ev B5*A '!R\ӓ⍥w%5"QJ5(¤m&$Mu( nmTL.[q{c*ZT@D6p1'7S"' r`Se@i3`DuGgNCꬆ2b/D΋],4[[QJΒ[5I{n.gc'\.{6[|P>HX!8/ 8+2Ҳ߸7(ᘲ0:b,y.F9Vj8o6_7 4Q%FV.Ég9YNnD"{wǦ{L\ xw rAK-A{vsYHr%e1gWЍWN:|OSa D^q,,(K#pJ*IZo|h'ȏV%Ӕhi<؝c}}^!Ȱ{lc3 !\ӀfpTGGE=aWz&Aݦ}ِz RC)lJ)a e0 '\_w[T92urWN<4 TEAȢv=k"tvC-dt mwLL%/M"ǁsmUYœcF-,D&pj Z9r3*7IZ^EجI@ QoG rڰ44E~v V#*|+RfI#g1NmgutxuU19D*ZbEӱ%L(c/Rk{XSR{ hY\e7^f/5sԔ9CXJI7Di0H۸$-҃M'bQ5["ˆLR<Q4-:F8y=ܮUybKc3 vN;_,pg+"f1& *btH)OϮtb9V:X=0)vS ,~UR ͹7'F.e_׎Qn,s*sEiVbIF~3JocHq\j.7T S0y Vm)Zx?NڕVg` XjV/xSBE2 X?jy|hwwQ^f3Ath* dq89V5;e Ж0!ZxO֓{M=l|-ﲊCtghC$ӦNz8״d=+11z!a5,1ҰX%L4"#AUei9H!Hhmz]nF5$]OCbqT8sK j=JXg@Z>p8>Ana78NFV~ghliLJ,lu  EfSafQhv odp՞򦚲!g ȇV܏ `S^zQ@\Hl:s85 L`Su-%L~. rZ ~:kpF-0yQUf;]10ȁHoWM1R\YQ a;ze[6{ ?u }Đb󌟠̼4 UBR1]yYj4CsbIQ"E t&[\{!M[C@]4EWA$4uLJB6QZf`ҬTM\"N)CJ+Szw1 59Y&[y@M y=NӃN6(%}oP|= wN1.Y&TKfL\+:>LWQ[5M ( 9&}~B6C>V"Q'Z g~=p?AIܛaB5 Z,cT{Ok[LJ ,O~YYL0vo/(AX*TdhNπ'ATyN9D=S؆̢ZO*ϱZRnB@@L1VUru|na($haZY&g30n~k4k4P؄ gd@@ }A`T1itMu/wؿw?VZ43 K'o~=_ V AIgvg.ڟoe?G,_“>ۧuɃJ3O5x8 RYKf؜;jH 1'!*zH#W8` {wះ۵mJ,mѰ"O.'9pvY\|Ph9֛ٞ~3K@*Q(:2>TdQ& ݑ.X/XL")+k0t!=w"P_+,FY]8}?%BTDA#4W"L*0jvFK"V J423{ʼnlgjUX0ws^~H3LM6+G<)H1)d0~B,kRH8i _hSzM&cQa/vat=E=EdWYTT`#}7:Mӊr=Y$:vuLvPN\ |ڢnF2d䦻u9D/Rmk| QڏuMT>( CY<%Xl_sQK@>ew;v߆ uҫDDYm=U@$V[Uq⟨Dx?&`GGvC]5֫O9Mn;~)yRzh =m],'أ]w6j])&g\++Wz,}PVY%P8  e?u l*+ܙ{m:evK)w8S:M:+q MBg ++q*C˧ M |i`B$ "u8N*JQ8S%Bm.uwk*}DT4{xUʬ,OdD*=.rMڀ 8>dszyp"v6Y˧vW@A9N0c}}?fRb$WYg!V=N0Lg5w;SKJ8Gԕl[$ np)0|<}WeyIj q >PپAs#Ԉvg_BC'x7YPs<@%o2yak-s`dnQB2l˲H< GFYxijT娻dHʀ,W9-3KFpZJl|c6xDf1&^ 7{]Yćj{XqW`gT5eʶ?wXuJ,[fMAD>-#k= Dѧ~Ř[6>Hb`?]LQMuRE=z @aATǟ l:RtCB@7a"iL`%e;ΰZ,h!hys)/*,vBL%#}+Ce< Th/ |TvR<~M3aKGWZhc@:#m׎ԙ τ,h*X[ HA4 l)%T&=DC^P37oj#s9C|k{a_FMaѺfU-V?E){"B;ް:<$TjL00nX!Lr&F77Q, x |?_`jcS $i|9 Гt!(jfTs?' 2|p`eL:!^RWgG)@ *C)>G:D*<Fg051kNvl[YI7_솟Mf9dq]6jPXФ5 ~߻`>݀M 3=p6zcJ@T%IO#or[&}0P2+LZ|&?LM_ y0z2Yf;H_97wΟZSlibd@$iJfXF>s'uY`vMWI77 )T9$$c—7,(dr~g/p ugf8 S-;M }>(JDN!=0oCDYuCjl'T4UW6k޶>@F%觉I8IE'Sdޝ(#^Ϭy0Crͮ5y;/`)I?)Kp YB;c- taH*TV2^즻Pߙ$_̃kеOazk S zn>),zl4* L t&!NCr_ GE"Elmg[7lAG2 L+`u?G5jc:G=k~-[x>pfRUjm `(;xr6ݿ՝7>T/ b^'݉o=;-5Ц772g(i]0xHZ-jq v9^#OJy<ىl{er~fJWs/g3΃X.g-,ܤU(_e,{ 7_lI~ ؽqaXDP4O'dzӏsf*'Ϋ)8TKf-1sVW$;Eh'1JyEȈNVF Ùg[p8Wr#~ j, P0lVI `^"i,+`dG;ZY$}$-~xqz%m}ƊlJ"dZ@% *aeLw$ єŸ&zܹ]6熡'sp Fte2=f̆~q؟nRίsNiJlbJNncqߙAK$ec"&>gFQ՝{8׭֝*)C㡹 MzS`2>]'Yw$v<ⰡǑ 2anTڊ׉%+&e{'-%ŻN͉ML=ߟdnB hrN2,2脡$N\]^1N(-.l%XOܵ{*`T}7<nw\ԇIdiY$g uyP3zcvSۿ?9G%`-mYZn8wX]1U@C]~gviN8 mr6r\S?77#}*irZtpy*lJf'ܵt=2A $ $p#ڜE#25Y>ÈɒOH/G̝n)Q;^O"z ]Bؕʵ MX,; f~P B(eR򄔌-1UP-45:AoN:Yx[9bp>l?w]soiD&Hg iP.K8/Y.6bt۝^ը99g^4G"R(NK;ۊokfJXA zuF|O\+C)WBfb&b IJ[iڰiM7ޭNۿp`=0E5,ZFQƅ%:3STJuTqk C oCnE!S8Ofr"n2U;="EU<k_OFDLQMHr QSX'I9] Ԝ.>)Fe&V~Q~D*;w`S I^חMُ?v+`17)/YAU\#2ECªڍ#kRO -GTTI]57֫+׬5 'mCڝcLbbg fZ8=ڲ 71WO!}uSҎ9T(9tcWmi$LLp̵-/:/={i<i7>y9efƍqA@D*P i<q0J Qag5~bBS"aī& g14E8b-X3jkF0@b&BG3Fasi Z2& [2*L6tvt#Q[Ј?~e4a_xـiI D105 >=HAJSx0zKz۝> 7of"={LHG *jj̷ *j/]ڸ[ruRW.+ ?cz8`7C OMpDSbRf=dk A4Wm5Cxݼ_}r l)k Q8XH-+T yܳ"eIb=Z잮*?vODVMxmEmًVsS,J77N_V'Qbڊ]->(.n&|̸]*h\3as2j}=3g}lZ=li/|Pۀ;|oo5uifMLi,5bC`O"YG_[@M搪ĉ8io]r2 pj$")>ԬuϤu !hc_59V*Xj4 :qwͺLӫ/{ (sJ>~f |5ۦ._˯㶫n"H= Laebɿ.g RVdd#F%0\'e0N5;qF>+bpqnº‚#0WГ`tb(:GwlM %G@W[] *+rL׉ٙzp xo#ד@6w6|Ͼ>wx en_E&Bzvc#=FVmnr918Ezj)(=١0`C;d-KY !z Aw@^ OVQu\ۏuV~cPl4N%:jigTHV,P|vuq6M;r16\\|KexTn8d<20}M.a)@NO’G0PS+ʜ6WĪHà1Ne АX$CX 4`k@(KeDP3 C-O6_@fu(QVu:b OTF=CfGlֿtNd;Zb"%V锡 4,h^EI20-b5QVo_QPR4K$h0>#$UD!LK+R܆-)0o[_^&JKY5E( A4K wF$޵Oܱ [o=5%p%;i7cZEN:xpqX{18vQ8Gցlgi͇EjcRI *e>E @[,)f}tBVw͊.u^ĹHз(ش%#TKY1`,#X|q+Xžܼ7aC{" ~gCO_=~Z̮5zߤJ5_]kio_z:[  0f׷ ߪ(,̮I5C63 0fw6?Qavͮٵx/`So;X@] g_p%,k3FFޱg.[7b: Wn1??'"IENDB`Ext/Icons_04_CB/Finals/key-grn.png0000664000000000000000000011153710062624674015555 0ustar rootrootPNG  IHDR\rf pHYs   MiCCPPhotoshop ICC profilexڝSwX>eVBl"#Ya@Ņ VHUĂ H(gAZU\8ܧ}zy&j9R<:OHɽH gyx~t?op.$P&W " R.TSd ly|B" I>ةآ(G$@`UR,@".Y2GvX@`B, 8C L0ҿ_pH˕͗K3w!lBa)f "#HL 8?flŢko">!N_puk[Vh]3 Z zy8@P< %b0>3o~@zq@qanvRB1n#Dž)4\,XP"MyRD!ɕ2 w ONl~Xv@~- g42y@+͗\LD*A aD@ $<B AT:18 \p` Aa!:b""aH4 Q"rBj]H#-r9\@ 2G1Qu@Ơst4]k=Kut}c1fa\E`X&cX5V5cX7va$^lGXLXC%#W 1'"O%zxb:XF&!!%^'_H$ɒN !%2I IkHH-S>iL&m O:ňL $RJ5e?2BQͩ:ZImvP/S4u%͛Cˤ-Кigih/t ݃EЗkw Hb(k{/LӗT02goUX**|:V~TUsU?y TU^V}FUP թU6RwRPQ__c FHTc!2eXBrV,kMb[Lvv/{LSCsfffqƱ9ٜJ! {--?-jf~7zھbrup@,:m:u 6Qu>cy Gm7046l18c̐ckihhI'&g5x>fob4ekVyVV׬I\,mWlPW :˶vm))Sn1 9a%m;t;|rtuvlp4éĩWggs5KvSmnz˕ҵܭm=}M.]=AXq㝧/^v^Y^O&0m[{`:>=e>>z"=#~~~;yN`k5/ >B Yroc3g,Z0&L~oL̶Gli})*2.QStqt,֬Yg񏩌;jrvgjlRlc웸xEt$ =sl3Ttcܢ˞w|/%ҟ3gAMA|Q cHRMz%u0`:o_F|IDATxi]uH$EJf<Ʋ[RKv)'Tbw]IuRT*xlkV(88@g ǻ|{/H=Tb{{o^Hb>/3w1;u̮)pu0בQcs~~kz o}#l 76~zד~pG.?[n~kz)#^OM5&v} f;~5į]8n0O5yf34z'Gʋ̼9̶,zMm>7/!`^k^=0w0׼^F{-` 3?;7L7^ ڀ#?N7^?Q o`u';õĎc ۰y80H? ~okCb9`sy=G @fߵf_a"0oF >ϣ4&ݫJdT>G7Ho mE"9?xH/c+t1ocmmC8gwL 'n_ 鋮…kߵ{31z^sf7p)Ö0{A6=7Y ;CPr]d9 _%㓧t}p"\½kH^ڳc73vC`x=x8y\1z6{?p꛶>Qa[Hgs'^"lȼqglʂS _#f;fX`.Eѓq;} <;7ܧˇrCc(F4O¹ sw *héOOgtr-!DgY9$>;`lThǰNF.39ӂm <%M)kh۟ː[t3CDQ?%Yg8NпPnfJs')ruCYW8ŧ2 h h܌O'cѢEu=t KJW K5;Vgg%p~f.1/S\fd!3E?yh3HM͸K)%B@+R^2 m}7z>{3VJ0j.ux}yl\;o~_ w^WXxS/, ȋ dCM-#՛)iV]ƱQSja gXdA)# *]V!x5I?sq<2WABBi= xm~+?۟O<댩|U ΌS9-\j "l'eݙ`cC?jVgk=Y8M|V NbF2&é;2+aLX|7 8Q{?xGtx 45K$܆_􇥺Oݶ2=5+@vMASiT &x1 =vlPW/Ť\: оO[Nf:աcV t g*7Ƶ3)]\0!2#&CAl+O~9|wݏtW? >oi>+ziDž0ަ[7-`@_/[xV(RB6 udzoZQSn~{G;鿘auwawRBLIn@F ]D%y߱4>?ZV]n o܃ ;&Ç=>NM4> fW,S#¼%j{uo w68$SI|>6\&;wXg#zՃf}Ρ4Q}ld4פ[} rrJ- MOg6zT + %긓Fݢ~2P) ʊfmlKI ikzNØ`Xtf@-y5+i܇ݍʝȮl}7Y>0iFT~,f :C?pRpaǥ5x&}A1FOUHb@3MGxsMS ZN~CNE/ҪԶYZ@3ZG{H;:g:NRuxP7G<JƞPds/? >> "#Ft`*SBwL`[&>j| =ז_۠K M]%m3?ݹHC)uC"NO+99doYq_,^j#`-x"iXz*[]0ЮN0}aq[iubAƋTZ1cO9d1&d {0~7</Q8*pH p )'7TdԅHeMW}}`h`b|/ ba@`:n̬OEaֶV#[쟱#_kmumn_[,karQGR[!Jw`ˠ{=R =Sж`@N vd8-P??JF2Mm7-~% ЋB8R]H98N?aSzb&ЎOe4n!\3HSpfE}fE~U۬,#Ck$t׷i9PB?yn'6gw',|#+jNN訢(6?rY^6P ېUck~R(ALhK*@ۅCO5҅9<'cn)?"F'e3wؘJfHt&=Ձ)Ϣ+c|[B^-r@.|O0I3L>'>"l mL 0$(s{Pvz { pO& Bh׎?}졊^ĺB]]4ȕ7l0i򺟷/(-{ ?ܪ"J#xvhs k}o:cN,L.=cȳO? xg=Dk:`6>jbL~I۪6Kn@; &D&OSe(b }Y/8RyӰ6Sˠ˃URI$CRw`~ɟoL;iݚ 2C7`Hnx0v1:%0>`ǡ{KCRp;VrFs͑y Ơb)U#UQo{ tHkIzd"-:،xO)x+ADQ~_2G)(vYnwc,Ӯg 'g89h3WZ6]WQF1]I$YOεlCc1ۍFxb'a5Q?Zp{~i{1$ )ψE8R-)(DlsFLE=YX,lvDPq41&YlsG3iI2!+13*fT>=Qzɚl3"sQȥCCM/8_ZH0vW\ݶpulȩX0q*| b a"_d(ر+1,0(p$':mA!X)y -NY m +ClʕiFUN?<\pq(K_`S= hiH]pwHqiewMF{"M?tg+^axm;konҽǢBk8Q3:|~[%^G,+F,#*R@9,G$N Cg`H[L 5t`,ϒ3+DV D)G&m])>3|z!SaLvǻ7- ;s/o~/j=@S{=;F!GhӣD&ߡŪ&,0∉ŹѨ38F SҝCVl~vL!C68 :50 ] @ q-#I0 (*REs Fbu0<.=YITL[7aӍ?\{־bEb8X~($]RbNQɸ-&4TsӉ~X%DZh (S]ylؚY33h hu w캖BXd(pCx'a@Ò|TЬPCa(t|诮n7nH3 aء|8l=q~4[QGnW:P:~ 8QJGR ]]H7'LS;~LI222 :"jEi0R|0/ipDTHO ZM6M (a?tXAN<ʪIǖ LϡZ}k)I6i2A}M3Ky~:,έ bMZ6” $X3`Ϋ^5,tkg f$hR'՚ n5r F3HmR."oI%z|& 77tf[Wȁ/T 0ũ'h@bza@IH2{ 3t@ۃʾ;,юtC-B,Mլt;\lXe{'gK:ē҇n( y^4#(FGen! hCXNґx7}{`+ DixAelpg RˮmK}"ftpس@_"u)#$Y&`8 4,}. bF+J[Qݙ>О5F? cjSϯnMo*꾭56] S鐡h *;.9\oPRU<,t*U hShK[y4$2J`L(nPrpU'\B'eg^RrP( 1N:L}/b%Dve6;kG :iJ!1d5˾K|@ ?: !ԾƷ5FČ -,޲+{eq%WLb+ʼn pC/o5Rmei&4Rc茿2@*4 %8ˮc! ^rSFjg_͒SxEoYLZx5 τ~+* 19c4OI.1D/Ah-KX ULGGI@ >Bs,ib`Uj\.2f̝x)T;{rjf>PԘc IT-(E-cpPUZlkC)eNٔ(* ?G5^C%:YqAODs{H}}G,!Bw`4;VSC_sC95+Eђ^:|ל)G  $ZPLCDcos `Dϵ0D$P93hPLJ!TN@q߁AQ| o 4# ʪU>"HWnXFJ43VlVbB3dC7aZ#22s:}@1)}U&III/I-u7{;kcB`I̮@1\va8NBH–7"ʾg&'!#ɄmIR7`6zڮ X鯸$n5)vUV7LDœ{x=iQ :$W֌c-6` 嘠=lf(X>- eCk#a&e)&bbyr68\D?8qeqB*Ut>L;Ev%7K=RbjGBJil~)>uR5; 9T`r luԅȯבeTGZLft̃@@OO4WPI ڎJϘX dJ>o 4^L^C=32ܼ|7#.&{ZC2erR 7eRލY|bEEX kXXM;}_IƧ.%8SYu*2`*Z/ҏ(E~Aΰ9!,ƉKMf`($oz Rq<O!;̤L(2_Δv=" u 1VkLj)x ~;x $@u4f~ڢzMc×jO! ]v@e[@SDP$#I0)ӱz6Qu 0ƛtjd?H%Bz % N = _ 9, El&#ZhHJRڝFx΀Z$b[D[\%23,лZYD;o4#&1] M!jm,Vg5Aa(ŸYҨ_l_Ven45@(يP_<}jr:2-X(]?˵pTBP(& ^Rzȗ,F@H#YzJD[mCjdf; f2=PA$#1tag6!K,%t\a_Ȣ'uJg+-0ibp[ µL ![ Ğ:]d5MWks[:n~pqe[`e7{N Q+a6[+qL)coN:hĒ 0M4,Ubp:Hȿ fuZ@*'{^'b?,8Lί9r_1iFQ#J+jAZH{| &]rr`0ak͛ovǸ*=MJ}2dVd/Y>e8] VwGH\5\,6iFpϬlC|$]Ld=w%Lܐ\QobcTP&3ׄ cX;w4\62'MFQVxA KdbCUNU%%5)i#+~2C 8J)Vl@ UXW1V%͊4wsVx@viTXFߕW2UZt0a\@{ŇLdڢ _móRh5$ڎOĥ.1X-< N^FԠ"%&62/ZjD.FŖ0Ps7T TocyKLEؕA۠\T1DǶ9Ƣ=f[O&1 PD,m.a3˦a!1F!Dm@mg{ cB";iYT2N O5Y!ͬ܋XXi+ _K G~4/g\n1Z 4 @fdB3PH YK *&!SWH!u#a,X:nJ83tJajvt(z_h*&b(IC$sb>Jt.2+ Q$eA=C Q9Wu,%ِgedù߫i;%WƱ| 0 <_K)&"Et߉$0Z x7S놲6:=xzUaYqreoQ#wW*1*{ #PJDi+mJbx!VacX$e;lcRbڥf #m4qsR\&FQyq"iJ6MԔPl5(8dV)cY=pOBV|R!Ůj'DZi?#e| hLފ&2q596K߾P=ufT3n{i~(x h#0I\.{-Q/"R {FO5|{{UE Y8䱰0g@(ko=1YsVe:͉ kD=T ļ2L&5U:Ca8 s 鰞J3]U,_;SEzSZz"" 7wk0M*V X (48D _IW! T:*dфa۲Rgw=y+CNA/ ~bV,´P@@Z (g aYTY-Q]DF^pE\x >#؁8}L*êu+nZlܶW] n،-ڌ+wl-Z[$=ay$4?-2 -L1hU1ܮ)! U.K_4:_>zm^n ݷ]; $fՌazi8xVFeUS0YqdL1&="3甔Mx}uͨ70u<9DNG52`%WB~lɃ2u߀}<݅ġlqy8tųg<}m`ݦ5eGE,ONA"v^qf'E'${/\j黪œ,͊bWNڑ1ϩ-U,fےvEh cq7 Ԫ,X8D Dؾ2_'+_KP9>~_8C< /bSGO>ћ񞟾 [߄+\P!+8F\& 18q-^$Ҽ դ)Y!ٰ^O认@ݥ2Dn N(th,dYR;( H92J7N7K __W}x[3.uX.OOŝ?u۲,*}+WBM鑤BzYXwdtKu{N@Vd) A1Py%=N6)́ͦP2&\tʒ{ ~=>?Ԫg,1X0ׄɒұS£>A{]B$^y9;?quZ3s//d* GH\{ RkH?k;- F$3=RԶ/BI وy谣̊g燧s՝.TcTJʼ2WY4VK[[ M S_ML"iHN3x[z)<|uQ.}=GO7}z\"x!%7ϟ4,:ltuQt> :yhs<2Ju3 Dӟ٣l4&*~U2 N&h 6&s@cHŴMDu|)؄yrgŃ(z7|'C_| _9gO܆kͤ+%ҡqy -Fjuv4s-܋7;0vEg:c9]||?[/%<.\|m_ +7j4_NȨos*4Ȳ(BEV#/$jcJcqO/ȉ3eJP^  6dw`siJ)028ڢs9BD;y$~kxɽ?2)]ݥ_XnEˬ,\6a {*)+#&kDWcN PzlDPg֡f{IWekJLu1ϝqTQ=/gT=]iRl=г'[{_î'bG>|~.=b(~ѧ0wEucNj@b{3 @ Hz p*1XMF$a?9i8-^t&f&S -K1̊cѾxskϓ?3xR%?K>uLVϯ=9N޿jaq]8JjG䜃w D_8HQۯaB6h8>0~3lzCD6>gˌOjh q(4I勒AN:}yz|7 ׮pv=-2JX*0z^tra#5Ub'|7~wlm$ eR+>Q0+_x?O?,.]o_Ǒdž`h$?#\NҏSٰ5# dȸX(Tޫ0ܺACIauL)>Jes0}씥aD4mѭ41lL!;€SNu<WN|\_W["KXǔ70VD$^uLK8K CˊFT ] U={S!3 1O?KaҒ\nOsb71 m {Gc&AGG l.܇3'x>vCxoą.9 #BBtLऻM^lB%ޘG>1TzŷJ| (J;(@9]R1 !Y,13 cJbZ,]͉L(5A6l,Awy9||uw=%mdtihIzfwq-*-F$W q=u\ZbPc xߞ#@dhѨ3NATKQ0D>S(4VmmrTrPv#C{k|t#{?Gs3̝"˾w%@d:K_Ǎ?wq{;xmH4mKeL dZ1zn]C l nWs3Lu8d1M>:1pןXS}gxο6KzvEC{փM2B-;+RnΞ*cc$NJTȔH.~rNqG[pS"Pu-vZ|] Xn&̓ʂ)#I1b+x++ǧ;]_9' :`M傚-fX]̚Sҝ"d4̡Ѧ.ʐEtqYJiYI$uv.C0rpx5~,8 @ r\#%o=g|_8EzxC KJwpA'hѫv!YrǧScQ8 Nc,e*cݓQ9uj5MU@ @Y8b߰N IdNi/>86=,I<`F+EN=2oym=(Cail;#(]Kϩ *!6jH f4~ [(=hzqBZ@@4?ux8yϿc??]ѽxoĹTb,|J+ݶ4e..EKpt2wB>f5bsC7Ӡ5f`$I@u?FE,!m;BˎaiBb@( P834ۃ 9~v/sźpg ,6r~i!B/#kRnMYLjphfqb7h ܦu2'A)س+I',/&p}K/o?W^a!C4 :F+KNv?ɖ"S0C'D'?pjZ燃o :O\ڐA 2h8D7?xx]xm]^ާzPe.?-GgЧR{0ȹO3yQ䶽R-a{bw<:@bn>L mJ/]T`2O1%X8L%'߳5[GM7z(v=:%FYjUy։D— bЮs" W6Sfޏ[>r#,[2KxY] 88a7f̰az|Sw揼kRלfAPՅ 0rISC9f-^~Fwc\qt8&ZG:k܁{q:^s6 ɵI& `I1L/áGpif=|ݕI1N~sA M:.^7z0xf^!Ke;y?G#$`;:YSEgp]\OIKoyks[m-n؍XetNIJiX4]]iя8xrN3kWބWqcѬR%a ?k#nEyvctN9¤u"VXƐAK]Q 9iWO`ђEظ}=lc{hVa,#j}kcU+vzM0[6dѮ[ p &u<#33V}+zES=4yje-]k5&#^?LmBx+M>r% hưlRdg8k][13>׌,[2]krߟθ+oBiJ~^+ZqtUVb hR?^b>XLC \@T`swpohv ;eȆc  |/quxצkvzM.b "SҼ -٥W,u#gDK“*:D3 f+˛J4.ɩD r0ة@L?_?/Rjaa^mbf$m3yaOɯ]7 (v£&@E,8'Szf?q,_lN.o=8Μ8hy ؈C}x :"4̪бiV.Ivt` mزn c9N x flZuı'_=gtN plV'5 41g ,:, 3Xj9ڹK-yp|GԾ&8'qӅ:| APA0%3z&,]0ͅsvaي8wnZjhҒ (k/<_~'xj?n`+$(qQ$sndpkx8!7cݖոbr,^x6 ξb//=g߅{/HgW,/o?EKfS$/,NJZje,kt_؆Oă򃷼>ߍWuN8?Q#@^*͌ʾM\nuq|{ģKٟqb~؅ m͝rYDs-[jJ;pbv@m? Gwlk6`͕t\:;}]Gx=xكxa:K *m ΊMMFw ^iP BZkذ  >x7N޲r@.U&H*97$]k2bX<4JlGh*LP]y6l_7o =3G_>/NjƝnjݼW-åK;N8dlu?t'  ~C1 \ Ffn.EgpkXyeBm0KZ  lvnL`v_MDL?2JJ,]OydG}K_^n *fe ~l;j)IG2 ]$ֵV[d]OKWo9 Q~xq\ĶG}w>hCxK$b^vJX pŚ W/k\.pFShQpx[W({v@; Oi6? )9=rAXM6/@: Ď۶cuWMB:r)Ă gBdÓפVv VVjX.8֪qvs _g9zaLPB0߰?WuwOw󛸖\moŠW B&buƼ$,]hRACvX!JM$ %-s"笵(&egt:_ zэ06=LGl'1kqL1z~Vj0SϢ"T3{^=-v(YjKIͲ&kc=k &&wauG|SFTϣ4p!@Ђoך@wh&J3.@%]6{|-cź^k޻ w=]0 5$c+Do AlⰭ0ŖֻvTp$?bwO u4M&L -ʇ[d+7mܹWߵ̄tby.b-~@QMwFh+OkIկ#+LOF~deE/gFM?@{"L 28lu npŚiKC;醍ML$A*}3:وBԀ//oll#&ɲ3Rr2!?bV @샵e0Z-A"K;Nnx4seuw)1`qO]+3+xtæ G%^0ŸM"L\r'%qaxOH)µݹ0|j gK )oǻ?q nZ3ŵ'ŖxK#|!ݩe^<ߘI/0t&CMϪPEu%'j4q s3 f.NnI_(w%ӎ/]wl5۞y?`Z 2G }!;"3o]XЍFʣMɇ6+UQs1c Ctf;u{w3&T# 6_{Ltp`棭!ˍ"zԿ<x@m@l0]]v]`3G8PL ү3JGuN!-`$ǁMO"1H'e`-ك~a\8?[l1ոW* 2:qw%e̘GDYC z~d~)2 1ͣ_~YԞdS3i>4M^SëW0|G*RL9`{?w/<ݾXeUIQ2 ~ՠ٭Xm)ؠe변fjɃ XAP9%%d$)SSWR# `'&b bό 5NOԬ_+ } >ߏ ׽7kpoŎ7f,.LlQŷfO.uM45]IUC##Ʃķ#۠sx(Ü30Aځd)'3Hxu'Ӓq߹sn"PkfafL &Oq!^%3"qV7tREŲͳT .GcHYD(ќ#a$jh ArB敽Ċ99J#ZΟ.~GmKᦏ_?u+Y!WV-0x:x,d ^qrơ#E(FLc@ՑW 7D|-7?wPUA {Y@ecbDS3 *0:%$Weĕ;7ࣟwr̢\}VݎV,J KvDƾ%#w4J7!ʌR9-Tof Ú\x0Ԥ+j1H/0B,ʂk0DN{k߳`-[`-Wvl}Sg/pXֲ!Soź4ԣ:Z0[3 Q8Q3#TU4?&Lt';~!KuBhp\Vpy 袥p7W?9c7ݸxGwԁ`^3/OfyQe1ЪR]WlxS$Tk u()'/&>?No-{UD2##SWZMChydB=4WY.^}=tyYWk#woǭ?s\Y+gd'׆\M;˴tWA܊ > w" Y[vYOਉ"l`dCҰ (VeEG$:f΅%j<ÿ% :( 6:ie#04"[Vo\?n0u |aV亰 X6y@IʿSц9,>hcvRfvds3Ls[@˛?=Gd$=|9>|m hRY1);%VmX~f`q]o ݶ ͸g߅k7;*ՉH=Qc6 L k^rT*t<`W2q,'FA,DOgas gA5 R|$),*r˻<~!+3 >X"U b +OށW,!}b.#U-[7}vk|Ҹkb-6U4xL~Uڍ F=~"LI pJjsQx"<XaUio߇ ږA[kFW"͘z3xB݄ V&cG;!/RFH'*w+^[?q#Zx/3Qf +p_ܽmv+4|#|G_'t{^~g&<bf[@@MQQ+=+'SRRgƭ=#0͓´ZZE&Aeu跘,kWY /=cNk $Xtm_[~:c`MlŲYB]N׾VtS8G(ܦh%5~pe\Сige¡̞)Y`>Vp`ҟ&(b#id̴;31 d.܁XXCb*-Mo)kn][^&jYڊ?v nNڼ-whc*"5ҏJcRy 1Ȃw4nA\aإ}Au\P1Y!I@'X2d(ژ@]9g8 %_~q<'*7ZNj; 7Oɦ⥋x/߁ކ'4^^\_d{3}vkp5lR7c˝N]Z%[fbRtV!tİ(]R`K'EE3^_w5%#=P2bIin`XBpY-fjl} ^x%zx/^ze8p z]IHMܛ1,YKXWĎ;껶mǪM+p]|<%rϤݝ^(CV}o7d [&6{Z s I,FCд"Éby+9)U^}6;˭-ڍm8.B f59+c !uiI Xin]8QxC8.\;zr|٬57R-ZGѳ8sU;yNlv`3嫖aX XwVn붭6bXin]Ui*=ZoggRqK6?|ev9wڢBf<| Ojr5[4Eh9~'sQЬ'ٲY)Dy*DT0Jrf2B82ԃD 3nۨ~ݼ.vrӕ81uG}'qSë'^-31\fV]k7ƺnZ\yz\yzٲ 3 0,sPPA&XD,ttw̐3M qr(ٲh^B݇VoteJ˙Pԗb5]f'_XXh0'g 0.ǀM pH8%f**aCafff`qA085t=9%Kd5O&Tlm&i˲g;w3{GwQp@, [,k82eЄI:MneןRH1\H6QѴ$1GčC4X4^H34MjRґ`;[FX ,HJ⡹f1;O̡u@l.9/ #LgN7^T}Tl{@z<m~&t<.xG\Ĕ kȑG^Ijb,v) NEYʞDDd;aU1si%P]J %8}O8i P i6\|J %-=!#TvM[P Y2Ƶסּ*F5j~qtf(z=S]mV#9m`rURۣi&IuRNtPSO 3yh$;KA$P knv蠐2nxCeʒ䦪sY.t:tL2P˘e]D͵n?_0r G֭;=OڐUn|= P[eDV@ޯqhH7Ȃ97-v\@l"\xD7Qfz$ !|La]{2{@@Rd%'(\PQS6`! =4Qt@iH4Q6Ľub,&YB\AȵjU@Iu6T `ρ$\$f!_sA'HV!tI.oh K=)-FZg-Տ9s<5 =:q~~{9 yWOӡ C"#QdhQ)5 %Dy'ʒML= xm ?oLeF^C Z)ufMn:0qaլPDq]{Fz@T%es|tSbOE+J'(f#ViG XYA֣VV{c%2w08^tRZ*iyX7%oA/6+CS^ p]4LAIvd] J/фeZ۱h PLDu4Βd2P1mrTMVXKnI(:Qcp-HoHnŊ`NBZ< _~n2h.8]uUX{&;FQ!  4cyVZaΏΊzҊa`YK#[TtoB{>URY^qDF]g)2*HV 1; gatKPYPe'je6P<ꃈ!*Z'KwMi@:X|cփvT!2; )|!SHuCQA7 'Afͣ)G8D+%PtA}V9r{x*XlH6y' n:=(Ee޶* /ߵrp$6Fw`rv{oTsbP>d%\GE@;c- sPw V:NC _`UG>Sst 9-%r:o R.YHcPܙ:BP髰l&Ɠ@˘j]MY[{SE[tvJe*Ohbabt/+$mYQʂIs`lv_tC1f6|(6>"I34]ԍOrŒRjPĭI%iM-"R yF!F~?(4Vr[i?r("L@Uyy/8fǒ5Tk$*-@ǣKTz1N[)44 ('j_o[kS,SNgkD}Qs=ಮvc3Y8J4[ܽ@j,,MB $˜z{1r+@%./i=bR(,`)B? Wz%,36<ֿ: ^{ǥTmFCIyV!Phhdz|st̥  jWP`u"ewkEZnʅlF]Ġp! ΪE$ēp2ؓ+Tkǎ2!l!CPW6I" 8^ In82C;쌡t߫W3 fN 2r %Wfd\eeFt{`MKekś`X1-L:6 xܸQ;pM2h:Z{B΢U#Ѻ |T=}Z2ƙr-`Wif3Iꇪx蔙 7 ֎H[Jf߇7QqKpsЍAޭpv")Ry1EhE@we24ĢSx6u@UVR޸t"lxns5wRȀ2&D)oT0ŔJ c22$JƵcʌFΪӒa&!*UٔȐķuZLd]Ig0)3KAE?C/܏c[܀`п_xIu"`R톰4N%m2(ֹn18$ K;$bq^"ɽB*{v^Lę{'̌bDQK7`DLy:ڬF&ZUII⾅sa,N ٟ n(A./ sj'yS*GW)bj(s|t&& ń% ـķMi2dӇ S$=w7#/eC7<|1LF{]1i6PׁPPYYXcᡘ6 co(?>YǡMǂ39* 8@e"Qpn>&IM<Ԋ>0A; B%8Xdz^qK=x-ќmTz/ ԯz<"~os^ _2p.dGAn&S#76ypEY|=bۗߺCgPd-#9{!ӡzY⢝4M1f u64%z~&`/&6qRhT֎E18Ubj:.LC='cJ6]Z&hQPZlQ& Ǟ<=0$$,i+E;Όb^TB/E;;-]~Lo mqi ϡbIݙ{5uOb'rے]Dj^&&X+T\Ն '[TI{OHͣCD --T8_:[R2dg-ԚN|SP:bNupif.M&a^y޺1j3([ >wpU#p@f.eKqhs$6lm4&6* JK VoތW-)ƸI!*>k#htm$L2'Jƀj4:"L i`]B D{{.f*'NG+]TK r,ƏqQaimj_y?S;6_Lj 586lXC(vi2 4I1,J(.ŁL@`1q=-2^-~iێg6l>c}C[+%Pv $0d_JBU[[nSI6rZDH$ lhd=3Ggh"`[:y,(D#APCe6dqVxJV 88ŗHʪM@P ӌ pڰab^܋qwڞ;"T_5y CEmTp.O ?;| + n֑`_[zQ%"'+!K Xt5XpT9n̾.6E\g_VXwP*.ZK1YG83'_xv/ٛ,|K$| 슑J 2Jaj-5hzQ Zˢ㯻q+VuV2d'CJ<w2?t,85V61EvE,]+|qCA%:?aA5C떥]nfiGg/=D@ />7<VB.ߒ޻ 9GCvNm u?9G%NsVYa cFiQMsHqH(8v[o̮?S.d"?ެ (zRD/j>QNnB4oYQ<,tV3gNx8 `'Y H]XBe= S09I+#n{2wPz@p%VmmZ.I ԠaN.;/Y4v(Xv(M8_D1Ԍm2Sp X]ёa} t@)咒ۙ}Ppi<CMekuz-+2 ]BU,!Lg *X~DUi3ܠ $F-C<"<1KpV?36L)b# "Pv$S?"An}7/RugB(Z+/f"Je Wsin$ÏcNB#>$< ) > ՘gmR+# IO5v!蘷sX%7 怫@Z`&S|L#KҮHwKZ?(b+=G 0$Y+Jʟfァ2ef6*h 9=m;<3Δ/Fg|sCq0w]6[bgB>qx]9_<ǒg2  &SP]9def}PL2L`;4UyTivp  3VTgKOA<|L>p95Iؓ_z&B@Q4٧H) "T@epqڂ.6tx)h1X#O>RfG\I@5:iZi>QI/LW,Әs O%0p&*YۉTrb3 ]wDLهqEVW;1l*\yzkK:h2yA;@Vt |pʶ8k50qEjxx  )-HzeN̕zU%iY|,1B|^Cॉ!%x .z %%n1IU^3P45'ӖTT*0ó[ ǂ}JuVd<1ϋDe1ʀKa!kڲ 71WO!}u 6jS&_'Ce}^ ̵-/:nR¤^_|c9eXJ*z(s7@D*P i<"qॴvVWm-&ԞI&)#PkO6m]GC[oe^ \v(`#"WWIIҫ7?8G,ĞxkwNL2pfR? <}Ёn (`+sak2Z 8VSY*fF_vFdy3#w&{A;F1u,ti㪲,W,u2{F-Sb *n#]hm-R;%&jbO$F@%1KWMr!I?yDN6O;DQF?=eTG!XY1C]Nd٫zT$RߘU;KGym+G:tD7$^#dx֔C|J2>b4Z̏>7$Օ=Ke-!Ȟ!Vskk(}ZKGqW'Irp>o"M62 T1z'#گ-Gg!UqT޺NT4y(e&rSaUތItC6|b)p< [,dЗJHMi< S*y}X;wCxYHy`ϗbWV ?tO_MIj5 75 < -F (?JCOwfisr*Alܸ5N‹?Nts|[3I?v n5;ᚵ)P8U?zUap9OD&^#H5!?{bPKre!tTR|]pT9حb{oC0 c[T9 3g$2WO#'::HҸ|ppuZwoŎb+kAl(0NmR!X0E,RIз(Gy)%Ypcp#f%VȕgPJ\)nEh)VN9!L1(eâ(<9,UdȐu سgq38ى)ў?ϐ|2bM7nĕ׭džknjݲ ;߷5X=Qz: $Ej#RI *eN i -mK]Aw_߳7+^R*DFhazj55q8B XR'b݅k1.߰^=rg_&"&~.Co_s# ^kz-(7* G腧^ {77 kzHl{ÊN^?&i^d0 kzl 0n^kz~̢f_&p?m$ M5$~>\f%^Yߗ لow6ppzMwu'o&67y/9^z}T# -?[^)=/ns|+S)H8s=Y5~>|;W`֠(G)>Y{l~|Q|wy.[ߝ>@$g/v7IENDB`Ext/Icons_04_CB/Finals/plock.png0000664000000000000000000011635610063241370015302 0ustar rootrootPNG  IHDR\rf pHYs   MiCCPPhotoshop ICC profilexڝSwX>eVBl"#Ya@Ņ VHUĂ H(gAZU\8ܧ}zy&j9R<:OHɽH gyx~t?op.$P&W " R.TSd ly|B" I>ةآ(G$@`UR,@".Y2GvX@`B, 8C L0ҿ_pH˕͗K3w!lBa)f "#HL 8?flŢko">!N_puk[Vh]3 Z zy8@P< %b0>3o~@zq@qanvRB1n#Dž)4\,XP"MyRD!ɕ2 w ONl~Xv@~- g42y@+͗\LD*A aD@ $<B AT:18 \p` Aa!:b""aH4 Q"rBj]H#-r9\@ 2G1Qu@Ơst4]k=Kut}c1fa\E`X&cX5V5cX7va$^lGXLXC%#W 1'"O%zxb:XF&!!%^'_H$ɒN !%2I IkHH-S>iL&m O:ňL $RJ5e?2BQͩ:ZImvP/S4u%͛Cˤ-Кigih/t ݃EЗkw Hb(k{/LӗT02goUX**|:V~TUsU?y TU^V}FUP թU6RwRPQ__c FHTc!2eXBrV,kMb[Lvv/{LSCsfffqƱ9ٜJ! {--?-jf~7zھbrup@,:m:u 6Qu>cy Gm7046l18c̐ckihhI'&g5x>fob4ekVyVV׬I\,mWlPW :˶vm))Sn1 9a%m;t;|rtuvlp4éĩWggs5KvSmnz˕ҵܭm=}M.]=AXq㝧/^v^Y^O&0m[{`:>=e>>z"=#~~~;yN`k5/ >B Yroc3g,Z0&L~oL̶Gli})*2.QStqt,֬Yg񏩌;jrvgjlRlc웸xEt$ =sl3Ttcܢ˞w|/%ҟ3gAMA|Q cHRMz%u0`:o_F IDATx}wesLf&W@B QDQQ,*bYuu]uWbAQA&* *EVB 4 )Id&y-7p̤~>c0۾}{s<굷_L08OVC @9``#gm@;UVV-+f ` `n~o,<`Q,W5T2p 0;9BOXI̡zU@JK~&?^uǒGgK^m'kUz/6xO~B5⮃X$5|]IP`Z'&?êߒxzK`Op S\ npxzK`Oi^bkz ޵ ng][R ?NގrOnxs3z;k9z WHӓ|G$Y _=7h=C:kΝ8m#G׶ uuu(jP(;;l::.]d?}{G&e_ߟ\*Z0@ށ"G^3f\wS81a5 DTA}oɟY `J@M@Ɲ:<5?xuo\jп ϩ{{;蠃?r>ء'MLL0SQcuə[܍ob̆OOR|. WI=@Gf *x$OT QoXzzݚ!WoWa @9shhҬNxM$6Yz꧿@=74 ƕJY@3 :iVJu8eS&5@ܢ=W\v񆫯|w.p93?U L~կя}|G舙WW[[Oj{zztz/F~_gAIK IY@T>}]Yɋ v^O;.ǻ#?~sx׮|3/?([n*S>u<5% qMLI)!>%{~C&xށ؂`:Bp럮+4yM5%N )v577ok bs}C 8yD>f㉀ O8r/D{ )oLTdf pe"cY|LFuɏ;l:K:1"{DQIwPS+Z;ƚz6_濓 EZvקkfUY"1BK: ?}0I [i&P,x/X6fB?`VgT3hW^:C ZbˡeIЛ6V;f3@\ۃw9(9 LKO.[F/0ўXx3|4ȁ̋`Яiookk7Կ5G5j(tũk_l5\\(My@X؞ʫ,ېS> b ҄0S_gFd&d&@;xSnć߶};=fv>gP4夓Oik ֱA#YVʭ_t(Fc_ ?eVg!,h¥~祐?uV2wt 6l7G[{w'{>0K~/;sin!e Nې{(Uz̪'73kA ,^ri*_O[q3G@Yg >iL8U.gXZ MHfT_ _ Fנ w|;`}>o|nj3&'4:oN@uK3 (ׅBl0N3O}P l@e(9r,Q[z.ґ&L)xSH:=]/}[]9-K|V|Z|ms*tۡMOL<t^`4wGRGXypl|ܷ c'nV5Y7Yz)#%W As,8VcH=cOt݃[|g5 އ{ =^`x}cɞ5̩'C.bȺ5$ȺR飓(WҠaAHKXFAAK{<+l08l߷`)Pt o[ _,7j_͛~׎2uz-QG.2d#YޒZH Rdu:M d*fy p2w $b-B.#F: 44t,g޳dY7jI_0`2γζRZ ٴ7hN~)<$2ego6|v_O΅*IwLV # tPBt#-FYJ_nw~/Ӈ$X1|=gϞo5eZBD|Cirj`> 7M(zJm(C BD,-YğK'KQU&J$Ơ:g:R4v.߶ns J`3$^2ww>2vdo!LBBa{V響O1r 0#}tݞc뷛-(]G*s+3); d' 1%L]ɵ?o s؞Q K~;Qq]MOM䈵ҠAl-B{2/Q4hJ0n a:+'DVZU8NȖ${*޳C6t34jc\_Uff/oe6gjk{Xcq枙%#qTn =]kM@6CMmw^5)6H'/S0[>%/R/S9͘d%)& Iʳb| eCG7umc9Owwo(AdmW31P~L{O~>iJEjfzU/O` ن%Nc:JPCLPU[oO -,h?zΩ 5k 11".Or"MUo/7W]UfJyxg9ɢ2h%?9 P # ,>3+KlB(1s Ŵ3{RK2! )`9i) VE/\`;&H_=WteЉ)޻2FM<7?;nuG\=d2iy>UO<ȉ'g㑋4P3* =j 4=W(,7*OI:]7 ڼ;#e݁↎wP \Bmc ( 3C,:*;q\N{qz_N|H~~|>?.'C pˡTa'NTh%:\;FIi:= 7١rIajԜ@ P <#OK#άْ̌5ɲ"6 \G~.Ue{p~{+6wQc- '7"x{0;7ՂYMjGA8Qt46jaӰIɿ77-yc(p@M os;w^ci,C"kMlj@bFn|+eaqeDF}HZf7f=Uk Ɯy(>;~a%0b\$mΔ?%y4f?@Rx8F`ߚ욪C"$q5wQW[@w?w/* mw?CjSib9*jDI[`+dlg9!qMwdJDخK\6J#b%U Zvgi(+(4N‚)Z͟n *b9P g{@C~'{Lݸ2iH vr]gu~lfI+'$F?=w1T2'M<3{Oj, GAH0,q\q!b7j"/C/2z WJ_@I^F[j*brrSަQ%}XxڜF!&4LZdр ȠM]s~[.s|:3 Sig곟QB5x3Zl>1Pf&؉0T]ӂYe&PLǗJ` vh$S3v>q7"@ɩL)CRs 撣+ 08e3 k4kH T<{љ;rY< o8SNy}o :\.@W4ĉ=S#R?.`|6y$@|㷒 R}dziKMDRA Qe](L7d!rް'bH #6H@DPDv1Ə1!Y5u'=bWd^{T0q!{~ɲމ' #Ŷ #->ybwk[5鈧ɶ7φ̉Oݹ e7DTBR,6z#9x@K/6c03rB#DEMxvt3{@$if'.cԈs:`!/Ǖxi-+wu϶ 'ײTcOz-6m3Glĸ+ȢoCYB>t@ʠ[0!I2B 5HY/=caZ|Akb 3/ݨjq=+y\L]^r~l>쥽W.Q9 l3vzKm"bۺUطHeRj6RzTmD+ 0P,liW TJY}AQHv8 o:r5Pdø*P% FI)GC^ʾS 1FO:_^G?ۓ"zsgΗ/:Je`T9sY.="JV_P^`7X"D8JPt1\uXc'nI)/vd=Zl4Dp4/ܜ6LldV\*%+W*go"Ots J;8? ~,S{>HD\ MkU# c8*9N")20@evI[$d|{S0,G>;Q WoKͬvbTzkʭkoÊjgUqƱ|2v1rSks$,y ^쒝xbA>YZյ( (k4}.fecI Cm#UX;*+lJ)$5Ms[k~~GoJ֞[iy]?wFAyiJg4S(1M=p` Bq>Ag U`.qڒ۰rrN_F!oTBPor vHӕc<|&=e KHȲ,Xvaݣ{hwp'>8/c{^ f0"s}#􂖲׬k|זNPO?Pt+)PDZKڔRd"Jg0g7 -w,cE~䘘^pd _ j@MǕٍkL"xucIruXe!ܬE`Ʊ}ppMdY@ ?>wirU|[DS[̈́:!d3IVJ\Geg{X-Bម/`.Bg6!Q[iqi(3ysHSPCB=RXw~@In^zY甩k!?9lpr>[$x^kQ/ ĺ=ɶ7큩f "#g5(_ u@ |"C킕ȆnѬ)h`L&$1 E"Ze>I&hTNԴg.8-Znr?}姝rLS J8o޼w6h8z| zKe^9fg)TJ̓ؕ@8#V*hS ZjCSzvұ|?k%]LDl\wnayPLRY]O'YHT(!UZ\iz(6?qPf`({*.V8o%*?ENQ-ԑ%2FȀJPVL&e9B hW2bxluFdS{* xsdV@j>K`P׎˵,A>O k[`A:7 UIh#D= L`IVݗѻ@ֹtƆ&ҩ7GO;k!hBF |cH&#ߡڔ%H@N\]G9pFO.v+ʌL:fWX z r2f=yȎc`Zx`=Tl>"2'ڵ+ -Y[wΙqM*ؿ{]$TƆFbwQ^-`'Ғ|:I8g]'Lpeu’=?Db΁m!R(J- Sr 0ec ʱj)R_ l%`; =%&3pS3k:k+JU ӟ`Jw8s{9dn1u(#`f`|Y{ X{HGNT'ejKb -]^:d 7z`͆9mb1|rYC w!B0,L9$jKvAp^=(=hGBDf؃O=ݕg&{qוD4NE-{o 5%Dg 1@)]V;޻3GwJID{T걬d6S%U}:b6{L|V4Dҕ8-댘,ecz*a#*Y:Cˆu}}羕 ]ܱJwV/cN),."umiTj(Nc߮ͷBT`<;*nERO_^" ,յ 8F>PA*p2In@T{|ɑv3Rj1l0D18#jF\=OD 0Z"l$W0@LT. n頬HۆQ5T p S*yu7b{S+Qb[7bKhsfV5=a2Sxs/{"j FL2U S}֕'b#P.vBN$ G,Gc%CI3NeiBF֮#m03? TaK:;8iH )g;"$d'N^ECeD'Lќӄsp(f,W^~ M W%lf!wo8h`w,?}Re)0B-=VY;rɰ3!#)i͚G0s)1}5K͖ ) ut):>skUkB #+ H(`-A`M; x3l)řG}s +W_w>4l9 T9"SJ=z,5) %J"˕NhYax{G- *yg u9G~d{,XԗYHw,#63td:RGip!}2#}GkrtY49nv`<hva5qK .L)r`';PsiZvjGlf`Yxf=(T3dZxK%jԩk^sQM9z-cszL b>u0bĊ@FĦ$y  @US|I{]kfZv p|!"0V%!#1ڮ-i`a5!/ @CKK.=rL^d0 CtX ST2XZ;կnBz$\p>&XH8A2{Al4R[3ktr3y %<I$}+a4f:-rP"Pɉ~ fx2GLF\Ung:qƠ.$ݘKf@p|bk֏Hfa FEPSj/X- 2VAq*"#F HΟN+./+J$ul^[+%]/)jgV,rZT/Fa`t޽|ez~D0Q?$svCɞǓYC Xa;N9g? #* ;/KfX`262rFYM!Z>fgLJe%Ҥ8[q/@5@665,=yx_:-* OpS}mm# vSYD߂dٷNdPk̀,f h DJZD˰t",]+/ŪU+v[;7`kر\ohk#`?a2&M)faY?~J]+w&9C҅-*r!G] l0KpHqB[ .1Wbu{;֬i +Xn 6lXؼyN?cKKچ ǰ0rh3LYb13f"FR RZUGE<^_vgฝƋ`THMI(c1, qd- K$ۀ핖CTɃG dqgį-w~ 5Etq(E4謁1zW(йa::CaܢXbe*L7oŠǍ}fƬ!ŒY`ذhi"( xGD@>7PN 69$U#wZ.CYt: I3}BHubRpֻPYۚ4#e2w9HXȏj=ݯm0,ˏ l_i!ZW 2=<ΉAvz۷>4v-G͛+ֶ8N1'S@mMP˲ ̽Qhy-69>85 A4*a#Y| ;S+ZglDl NqE2I'z"4|kU %xjvBey[s[L\ly@P_$?胸_&n˟lضm+vյ}{VݏG 7u#G.rҥd3mXylA__vׇ==XK/SO>-Ԍ#Ƹa(.G6ì{QbKM&8ǧ|JɔKl>JXigR0#D㝷\&vfEq܀6q*\#m1=K!އ9ͨ͗&`>^.pl% np5B񿉥/@@Šxk ċWaO֭]ukWc%x7:cN($ښp @~(>ɂ=Aju2L.2idi9byQ\2PE?J~7O!O͎`2 hsH6)R/ P<^N0^γя~l]C@ ;hFi7ضx?=-^][6aْgxl@۰QhiBm9w")7!EN5h=B fekƚq ɛ'?+g2&I>R6M`社LLJ4z5YQQLnqNlglQC͵V/~摡e.|T8]g#G:{ m|FZ ~A@3ccS~o{Nn"] ))'r`]3-=Bxdڑojm%99 PRYo`GȽ>`ߙS!0]T pd% z}뜾\Ե~͖tn܀ ~}%x^{Xo>SߊC[s7YUOP!&#O6&XuYJY8R)sy}bTB$5t L6bRɋ0d، ܑIwo^γhәgd)eAApX \b;~K+.g{B:֯ FCÐs Sn_d( -ΟPP\8سiA (66 Hiw;M@ \;FPy{/Q] ,{?qݘ1kERV=Zr~qE˰l~` :bرӦƦf3琧vʶm eA!WDdl؈Q4xT5|aL/-"0^4`-)$eZL͗ >vpvf3[./0 EjR%,(37+*4r>G.ĥ?եظq^iU/xcDJ$q? qDA AVሬ69DfBLE@NVT`vI,ۅ1jt\8knTj&H0rcn`AqWI7%ϤQ:34`XzTrY7vK_\r+rKp+w)nѹt+L3O,<Drr B BD{$`x~.!%{=$Y +KizI+ A!+pKz(5VeSγ}˳ݿA0J+6e!^H Lcʹss5Zhmld{BęY{L&m=i/7 `<.֣>TAj8Pٗk~d!TxK0w0f:u OrLvR%jGsnnJ39[Q`(pLgm@dTc2ҕ#0NC`<#?sz=adSNӓS |t՘WeT^M:(%^eWF/DHGVB`+qP hڋS"6OC'@\@-@)T yɒt˹P+1.)3:8̶ Z^{vگUذŬv mF (-RARKhSVc1LPJ_OBj/(0R_Q02|iVAHc ٹ,Ns^2_Ӂ eZqJj# g;pIBlXS2w^S`_rH(tt޻nnӮmo7bc`O?:z2F4&v)GR1X 70X}HI`y8:[\#Tc!f,OL[.n|&}P|Nͦ`Hq֫L:%5f,Æ,Kb2`8٫VnV@J8/,֯qveFeE=9ci9^W[B2<;Y;W Yn1q2|X` AcPl"ND0ހFIgV̖+f'{> (OZrB~xI+y&+q߽wTOq;[le\htM?'>@ 䪥,퍏ަ'iRK 7 =[UdvRar\Dɿ e"e~($et#mm >dg`f >H7̐^>CM#ڲwv<p͆ +B^r)嗨SoR*2<] $V/g┖1a jcGq«yNf64dK e,:9+ݦǟJX3eQ<ءzΜ«"c@#yFvMXdqu-y{ mʁl,tUjlRxfga H-z![yHTq,G)H2%.Id&&$uY$5 V@ $#L,2L/'MDggJq}{qK[н/ZNz{R jbs-c +G\!d[3,c>AF*%r/?gAoAu)w17'yI:2L+MMC8g0b|HRݸ۱|]׊e`wGkAS\3^$[ P?"u&-C]H'5bn͑ B^mHa0Ź gqB)53;-}N"eS V`&`M,3fV b2\B,x >pwYS݅K}y|eoJXV:^פ$z]rx;lIř4T%AˑqPO 1n *ij]g&'ɕJ\E(M.sMMDSyzO/G)VYEU/X~גO$ 0敢e>4ϗ@^lB"i6cvgvGD$d#3VIYe 6D#0]݌Ïg)&L(wuH D $z!JCů^{KZrUڲi?z6[-17d1}~3_D$N,rlXj2Qhx[ُ̛<E!b-/Qc]R0!10ÐJ0bv6[`Єd˽gfCdؙxv8z3`Ҕ3v4cXjV,_Es(w1yL=FBmm]Vlَkx?bSc{n?d_L5gBA8IlE3s[hBNit!פ)`G=BM Z'L{=8QfX:7-ga#FWorjù#:LtW Ktȩe&FUXIHa9DK,BOACpio}#"FiY-c.-eZSk9 uE\q{4e|$QҖaCr )- qĨQ;$T"b^V,8Էu؈|s.^~T\&oԘ 8VKOО#4lpM~\:4 >)nvԤX`FM:L9'G`Gc"7{G`@Bu%W m-2kx]MiZSSoԠCV AY>hcMGa7> 8 GY6b4y2ZFTWr HzBPZL[qٲ e=XLIǒб~,3fQcZoH L>黱b}+z> S ^Z3P;]}\( XW|)2W90c :2cݠe3f폡-ò=(QJrZ2sniذc0i:^n||[ccWʵkY9]쪝͛6xԙh24'T;3'OhiqWWr Pvy2/>:+/ (DM/]c֭74v$՛26b pn+/pKoĈQ zUgjb0J\4Ή eg}vBc)QIKIo*c .P lzչVh'3I^ÐJ^fM³YKJmSB}kG@Ypǎf#KerqwZ Lgv moҶ1իzUFJS(/c8Ps z ʢuww-LQ)#tnt67?Yhz IfȪp+7kJ^9r1FR%j 6uu"^oΜ?ff*l߾?d"-K- BAZnރګzUI(IzHMnC*s@ޞMe!q0|LԴ(2Z[P$&եoa3YMe.YA9jsV\Z]ի2L*-ɼ]X&OQn v%۳ENO >2<kؼS|s^^:gWb!e?bٱ+W,Տ PVzZAQ`˭ ~G ;yN9oZaG@,^֯kw > `lTZ%=c,xn_=[]ի_#Bg3NٮZD :yĽgJXY vFşƂ)XJ)&#A;oǦMՕ\ a /kS@U]d]GPS`kئv'LFfPnl__/,ynALαpQXJ2$93 “ UaUW>xv8>}lB%`mvlQ5u ɒ* mG_z wBߎm Ѫ& xEEu(!xU-]pA ]otK 1{CЈ-l BޕmH|iơOk,dzrnBrJ!YdBiL./l/>P6}$̹S:5i%k+}!Czw : hԖH9$ ԣi-&290θ"9qEzmgErZq97`$l,(#FN >/JӲvL;$g+[,s>P0(IH/r&ߚl;^smy5YDdu߃#l䙊(t!8}S~Y0(r0 z~`Yt4LفDhRwi%-dX2g<5| [S 7o(?E{k1eZUbeSeͥ9k`  &é]F&Wϥ_c`2pGNZ FJigRs&Jr.ؽ>D``0e?Y2mGr?ƍD8%PMk(3:z J1s17a_Es'.kg/u.iT=XJΥE%mY2L0ed-Y> ۏҿh#<~ϯ*/'}? uvLJ8CK@ss+94O}ºf *=C~o3Xg0Wc G :Ek| Yu%l ɦ8qCP˼ŨRiU QGqBoX`]853 nBў&sN8mh4VLz9=Sn ),,I-]UAg)8[YȂȤd%TK xj0N90JZL1A/QI..xg{{8\Pՠ9 RVwyǡP􋪩~yGfS YAK[oST*F.+v63hރj_j&JV<8t~]/4#(feuUv.DGFW] #ہZgzuJ#p)o;?FGmsX8ʳ`%s6ئ&SzH: BV8w4ئdH1X<ӏmʼD/(Mȶw+ ()N\0|ݦ PCdaNK>q}]#~>,@]]:g1G.F| Q8e( b R'm{-uOmYB8¤`Y? ļ)i?rȖ㵑 ,˞[3iA[0$8zdsbٳx_`SqD백4N"UH,U#qQ#/++yBgpP_7xɾDy=RA,#DcUs.4G$ IF">'؊LL2fl |W]q񆚂HLrz$̚=o9pc p|#F{mc7 ?QV6,lKxHKW"=|ԊѥOuJ 6b@w 0z Rߧ?F}we%۱p%ev8מ*Մ@ E7o}'u8 $ {ԳJtOT{}M־[BZ[c۞4 = #6Lg ذn5le.ua}q)}C[G'b=|uӍg@fjȬzT4à,I[-!3qaɎtr"SM/-Yڈ|̹E?Go+:5/7p4ee=w}*4nPtP Lg4 iis4֮1;BM-&O?ǿ<~ܻ0d]#K %UIu!f3kn*a E, MpwD7d`b]`ֲ"!R T_KM3 2]v*@ k!%J򸩣_J| x}t!m7yvCzNV#RB[0q,;[6mUu}Nzӧ0gihhjɷ;HPJӵ Y'ӁEOJ:j(a֑ޓxd"LF%v%[fP&,|~VqgK <Ƈ0D?p}%(O];yСnPy=/uԐ^\lZ 0gCՉ0LX)qx[z/q;q_0w`9k0қxJ :|t B:lE obg.$Qy)djc5P8$~% (3f`_l*p2GcX>6m;ߧNFn~(4 FW0c1s-Wbذ~񇍜ǿ Sgliw qx`{{h?Դߓ `yQ%?TFʳ# ߷&MD~8۔R.]HdDGӚ"R~Zr*D@l~${ђK6eA 3f#O|7N>8ףmx=H*!V,H(}G!MSr'$ǝ$OL x vd}@o>'A@L%R R"y'bqyoo57hz톧ex vzP'y;T zh Z#gжɁ)wtcl؁MkhX)Z78؉b1u#0a:t$fN^{a`q%B0,ztه?b"}IbGH'2-LC( C>n8-̟#{L~-U~QɌ,J9&>?1wngP2pBģwu8V%G(d}%ec4R_E/ hiQ?y6f9 ׭Bgj,I_6nx:bl҉m[7tҊ!CeZFm,F SGKX 9m#&4_|QM6g*O$ 2B鳙Jܘo7#S<i{ `HNli@1%gd 7IGD--TeFD0@T"yGw  itݫZzj)kڔi`@d]Dx*0֮Y+cͪeX:;VcSZtmِP[WƦ iQh1GM1S1f>=~FX!Hq}aE`ٹD͵ *K ]83e :WD]8#ȶ9>;CM f!Yqlf%uƖB;rc=U`q&̚Wۼm[W%/KR||r֭]yxةG6ٞO9f~spJbjq(&1S1jTܓD&7.I9MZZLc`V?:tPR7z/I0J lo9|@d#Uw\ds]3D cꐱ/ּ4HK;`ӹaю%#rgnɞ}"XI>+#n^6|ͩ6?yKeE"qT8y+l؂\iT,#̓g! .!'HMIqO-c3x0@SO5=(4)HlZbJ .HpӶUfbTo4WtBE:c" ~ls'-Bec>XzZMĠ\kc@z z{GyXA66ɸ,$Ğ*5ӟ5De{Ki2*b \ Y KjTKԀ܈3t7g[&%Ǫ|О$Wy‚CehyA"NeBZSL'TϚTsXnJ?MClrq VfFjo9g/<ʷ P&Ґs8Yٞ0iIe kviXdAzm@,N7M.  AG M/9-/\6%(kyH1)3q/ VWd#S33'KTdx+yG+_X6lSQ%xg@i:;# N ߴnt荪k3J(M%VRwo '@`}2lҦWA{ "$TYB Ш,ʘ &~ NCF (X $Yb,$+)95EdE=V_-Pjimm[Ց~X.}RD!Ȝ ({%=4*庮`X<1kCZS t /y͑N@EOq)e ,K#P\߲),ډ(=eh9 ^XS-0Q c; BQ6X"6o8lJoyP$)xiL&#֛ rƬB+3`;񕋾NKʻycHV#ЯW&!U!*?Ydm@a=i@Iz|.eBv̅Qi$lX6UG7 f#)[]];򘇥RobdV$Б8$`S֦ż3\м))i2 C{Df/wWlArĜB~/8%g`G]6 Rٱ]xˁ;IO@>'+3+e;%Z3wBj0_mh5éі00j0EJo@P֡H!9CBJ 'ڔR~Y|eIenvC`7KƐR9-x rqHF 65{! ×cdTYrR~9ٱ+a2&×?,\ k.`l@oAD4Nz k0MkNeHu&gږZpA*~^0b 9&0r(~6]Z#ϊc-XJ+ÙZ0(Hu$HZJO|O~H2J%QArl[|:$~:ASq5 Of!iYtD3+|Py 9+J(G=a;+4\Rk,`XrX2e~fm-Opl&Qm=aj`N85b얓.=p$vis;4XATWdMJtuPBfD;=^'%b/ 3X 0Xg!ʾ-ɘfO]6 L"vuf z74KK'2[Sp\Pg \v_6g:)Sr/cN2\8b hW G!ٴ9~ܘ#7gHNC"ZlTђdn6Y_&Εp g&,R 2"eבڣEΉ|$6>Y:.cfxGZcQgսU'%n 9K9k]k4 >Iچڼf?VnB~O-6E7-89 #cJ͟TJl^b*V9#H!r(9:6B :q2 %g4OrT^gaSRJ6Z$/zU`>'>:kr XHZ??qᒎFyVTVǦ u:ʊ'=8*1D0S%A>D]hiB:{4s|IY1U_|;3/U!k,O~"@d)ui?S 裼 OnDKtʿ7+cgUVy~oJ5/<͈$`MyqdAå Lx%+ gfb"XN/5'v@ĘŴb,Lƽ",bK3[dxeb7ȅ&jxM9Py5oAW|id?ϒ=6`׀aboM}[vո}٪B޵h@%\cQ=ߏ&;=`RoQMWNl~>ɸ\ Swh0pۂsRݢ]kP>_X{PcVC~VKfNrW.]ӏeU/v_|P#n9_}qXskub3ԼM+>fjDZ9oV`VCo9їc݀%tX1$w@H FΝz$q;i}&$XV. FaՐ ty0?B'/w{ ~\&uZ1`)0b#h֑ՙ VPx!HPXBz2M<;F m(wtb_c}c&*b/XZ0I"TNJ1OoIt"0~d-V/fnЏ-dO 5%HEEkm-ckgvq aH؀mIpjlYҜY${!- &=cJjMāو{vi@֊jBgKb1ae'w6 ;Vdµ {= a!SL xCS?u>k^@$`aT f5i>c4}̢:"ƙp9 )##F4YLhVl3 o3 +f^~_` ن$)8$ 8Kum7&@h$-Qp D >bMo?7BͿǔ"r|t5me%bj(-D> ]fH%\5"on*!M5`5,8ms!d}rb]x$]X{m ]gLB/aq|zj̅n[:B,JI\GerɳtN LW_xFg?=2$A__\rC!l%t&"%(%Gj l6#;siE.blrS!Y(%I=*1Kq)H":s٤ȷM]!*!M);S~\׮ՏRl*+}_nnͿ޺C(3!zɸ eC'yK)8^?NjRN! RIq$Pz,Ձ/&NVsn|ۺjÕp(9C 7pSטi6wuCڃt^цN03-(B@pDѯE:[}pcuaE;u#=R |(FVbf я``t0W j'%cU10Cu܏s~=H7OPu'h޲ښW;w`F|~V:)i|0M>r`6&`e[ 2X6')uO? @\VtrkZtd ص]O@<,445g@6y~S^c/Fu66GnMi3Ђ^!J䘫{.klh쿽*:FےQ+1 ~crZ 4֩$ 7i=QG&300e~K|; I=hgDFϡ'Z5^6.7gRM(d-0 %AXzi3R n*_ x;OV\dq &+{nAֳ zVbvX&4==Fߓ6,-yC5[vWW[s$w"7f߬jd\n r%IC)"@; ,2I) A85u3K@ V츦NA[(yYG f dCV @O~Jc?ý *@M)75?o7' \8hڪzM#ƛ}a9Ym`z}#(f:|9"ܫƬr4Hi"ƳC 䗦oxٷߚ!o&{,|@?pb? B3; ڰNkWٱrEϘO_'T'4}\"Ze;[x9WBxUrh7WCH2!lQ@r,8jFl9,Oj#{S&d{Nzkm\|# ` @k絯;k> !A"G.{oNI,x7 #]XrzØiH0zM(jb/*p&I>VGc @ Dܘ`kͩ\8D+?:C٠ Mh|Ol%f 쥽/$o|@1c'ꅷkwe$%w  .) h k XZQT`B. B#Nw6ˠNK wPTO FBsa4hXyo)؜Y$˲DRĹy gޫ/<^AG{gH|m e۰6l%NiDfGx͑ԗ@~##IQ&Deq\D T͌Ƥ nq֛QR L1_: BMX7]p5hZ_=`u_'Nick)ʲ6P K?vv^3uf,$d$[SRƟDYW0YOfI5)sQZ)Mҝc"ljUׅ/JcdOC &AO}'.c7Ws`5_:ȔƮRgta4#'E4Argi Ea{,J F稈+?4&i Y~,m X΅^P`%N[t.EkI]}^짒?oDg@ooͣnT)Sߝ;8J$ 0#ZR!ivO֏jl(A 2M!:?Jy d~SFt]Da3CM۠#Dy3ml@)֨3{rM/]?{ReWlWD P;k>WfRd%\Rc/G"n4 uݖ|6❨S2J0e >CGІ!R_/<ȟ횐q52X尡oniGB_%@C} T=O's{k[{Gؤ}: d!;w15HU7VV#Y'HC>HI{츏Q#3?qg nMiK) nF&$ N^O % >2$`@=sGoX+h#bpj IA-h^/~"~hJEfR%E KoP:{xɦ([#2>k53O}xm?\zcB~} ɇ{ ={gqHD 8+Hҍ/1dُ!p HI1$Gfg|, ɽd4h @Xbn:hɁW> ?%z/wyy whKkQ4DٔYulNg3G؃Vu +ҲD0^\( ҋu$uYN딱v/³l6KF9OQ}u̖Q5[?O1H^KQbRnp +z6"2T o(nڌA$5dPt% LC]R5yAX8Ͽp|a>4S8wohL 9 !h>Aا_n@*6@M֛Hzlұ.C?J _H>C#&(@1{R/x 7\~AX](J}gwy 95[&K[[G԰r}qEtط drhMrcD4s (i#<'u(1$ F\Z\%o91ܷ婞~MkW/3K(,C3> @0~ʚ}-m|a-E@ncM`8e08婮RξHYWܶHId-$TXuې͚H̓=|@rN Ú\MC7} ӼztG-/@ѴܥdL1' /1CVx9aWsùn] aƄ^~o~wa۶A^Rס{^ c|,?دO}c3mn)tn .xfaY9yo^DRR:/l_>;rߑO9n$7~?T_11)/# ۲%,A Įv?!op>7;sOzFRZ&w+ eFe6;Q"=,FЊI onzLSPsdP{uhOƽlW@Lp^3yWЖ0t֡ C&EP]H Co`B?Pu(gyHm+N*=|u JF0+Yvז.0V1pWNni>]u_sO:[FnXYK[ opzNL/V dCng8]_qhv"@kHCG { ]Dsfe/^7wVqG4Sbg maYgkrqԳY3>b{a{JǛdDYBz*}`scFqwqogIsz tPz `Jvr5npsvTpP`~vT|$;Z%z-KN[:zK`OEkp* ޒ:܎b+/ޒjӯCO5[R {3^pc`zD%p7u}5L~^-{p^]"j0/z~uK~I~.j^:C8Gd6{@QIi <Wh0#rd(&5bX`m5Da\,F'mZ 0El:5s؁"v`crw$z-BVXY .R5SIENDB`Ext/Icons_04_CB/Finals/plockb.png0000664000000000000000000011502410062567156015447 0ustar rootrootPNG  IHDR\rf pHYs   MiCCPPhotoshop ICC profilexڝSwX>eVBl"#Ya@Ņ VHUĂ H(gAZU\8ܧ}zy&j9R<:OHɽH gyx~t?op.$P&W " R.TSd ly|B" I>ةآ(G$@`UR,@".Y2GvX@`B, 8C L0ҿ_pH˕͗K3w!lBa)f "#HL 8?flŢko">!N_puk[Vh]3 Z zy8@P< %b0>3o~@zq@qanvRB1n#Dž)4\,XP"MyRD!ɕ2 w ONl~Xv@~- g42y@+͗\LD*A aD@ $<B AT:18 \p` Aa!:b""aH4 Q"rBj]H#-r9\@ 2G1Qu@Ơst4]k=Kut}c1fa\E`X&cX5V5cX7va$^lGXLXC%#W 1'"O%zxb:XF&!!%^'_H$ɒN !%2I IkHH-S>iL&m O:ňL $RJ5e?2BQͩ:ZImvP/S4u%͛Cˤ-Кigih/t ݃EЗkw Hb(k{/LӗT02goUX**|:V~TUsU?y TU^V}FUP թU6RwRPQ__c FHTc!2eXBrV,kMb[Lvv/{LSCsfffqƱ9ٜJ! {--?-jf~7zھbrup@,:m:u 6Qu>cy Gm7046l18c̐ckihhI'&g5x>fob4ekVyVV׬I\,mWlPW :˶vm))Sn1 9a%m;t;|rtuvlp4éĩWggs5KvSmnz˕ҵܭm=}M.]=AXq㝧/^v^Y^O&0m[{`:>=e>>z"=#~~~;yN`k5/ >B Yroc3g,Z0&L~oL̶Gli})*2.QStqt,֬Yg񏩌;jrvgjlRlc웸xEt$ =sl3Ttcܢ˞w|/%ҟ3gAMA|Q cHRMz%u0`:o_F1IDATxw\W6QlYɒs'0 ˒ӂ?KX`I.x`csslfι%9ދ(Ga8N r=xRcQpz5pK2[ Ɂ[2c&o3 -p |8r -v ܒjiU9p3\Lűϭch~*]~˟5xfG#"۹9ƌp7ys^Z8qǵtRho7b c`)b-* ٳviv{晧rcw 6 $QE㨣'}t;^(0 1Qx]QTg^~ݺO<}'gp'߂#pݼNW?Ovg|vysۇVl)ȧG5Y6O=w Տ!m۶?)W~ED7 opp>Olx׻=tԩm` Ia 5CгX{5?ɣuD0`y ?Ws71lYm:AbOO)D53@3 "޽^z饞?mFnp3ۃq9|+_oacnj-KRgi?ͮb+2(+Xn]_϶ꑯ2X Zoy;c7_1lBq&y5~S`D@Zl޸z'?WC`k\s9y_~ǯjUkqBb8@O⥼=j}o ׮-;|s_"OW17/s̘1[os洵7&riLHo rY G~DDk1x?I^o_|`xװq5ԀSC/sJݔ"uVז/|_^'MD78c`3/w߽OjH^z]ݼS̻LD&_;zzzG}gve ~@D1g~;n?('s[)[8:f/ߋ;ġ=9'g`&YaJK,=̓nݺeh?/Dt׀1DUI_sn7wM8` b'%/\~k<'*BJoP,łɐ2 !DV .|$-="?/|rǏ_2026Kf32lko XBu$i55)L ER( Z[M3Y]uogG]%s3f#>9yc N"M|?o~W&+@ْ0%Pk,B:q I2RR@{kvǔ9ԈXbUg+"u~CuFӏ^xgmSIkf_@BTrZ760n .Qck 8w JE֪H14옌Xxz?fn[?-'xu. UOociY*8;~ ?Ņ{jJ`e„ЀcChlT6Љny&LDy ZZ:;LR\Ԑq׊24 Q.q}z%G`o&mp"g4/nǑL#ֱ(틕k-W rwb։zG#:YD# #2" KBT#b`PAkɤS j4ص{}`x*O<ɧp#o}.Rpb3?SO9 gYr# 37 #{h&;4 wzDB 9⯁@uyWRH$IxRŒAgA To0߿mv{.㏌iDb>Zyrγ>{ɯ#}AW!%4 ȒTb2lл:H+)R\Y ,J 9B*~ ^WBta0rhȨ>#}CM0Y;vn%"vE ~r^]7nl).3Č&̙;e8- 8aTiNQ;.K <;7绾j 5W}gtU@QFuF}܅ t-6{RKHDj"u2+r={hܸqu_Eop_CEP'fL|hMuu[[0 ò }!8@]p~s":,RA-;v[PUeRNUeAFqJwjk{-0|Yw:S;M'vp_^ KR[Bv`܍vȰ&a7&ON G_<}$NT!8=yyI^dI-jVDvf|֊+'0αidS#D_Gт<5T^ yu%UwCotQb~.PH vqF5֡!kNK g!xC: \ R|aeSV\U>j޴fOLuFYfmz;. };t 18Ϗspn91&X9xV\5eFܹ=xt#FbI8i*<3fŔf:_F# HH}ю!EZ-!f ;ws:~5*I 3U8 @P ,]}>]ji<}}}ao-&nUb]5da/ g,eK O>ݻZԉyÏ<G{ &O.@ qî"`a3Լ 6f'TK0vD؅ E_/nڨv< C$믿~%\:p]# ^nb$933!-ʓ dx y q=cm*4XHc̸8sp⩯C{"#RiPrHIܐRA j/``KogX7KYf3(p齏=؞xe dQb)Ǖ<)24C$v3ҝcʒŸp-7`Æ5wfI/9j,8bq%ށ]}_G=/=ZKI]rІIC7f  P4(qʈ#I$tR{-W|\sۗƸO#@h@ïܚfjn YL+~sMMr:짚u~?n ^;k.{p%oK) Gs#Y \(`H u*aؒM<$ ,YJI6 pU#Bm/@ FS]-JxJoL(.e;;(!<&)z.b]AACu)~O }ڨqݵ i`xF yi{au+E$˄Q%0 #(Fdk5}X}TdC&tYK>֛n{xOf c쓣G?#؝⦞JWU5ĕ{/o1^n#2$tEv/k~] =FKc]/?]dE'v(`%YmAX]q Ysto*eظ&0;`-裏O'5GpN=ꫯp% b΂6O~@:5a2ވ թ*-q)$4b=ຟسgwSnzY{뾏GMPWb%j$Lkdw#cy{Ê}k!"BK^xC?ohѽ8jbܔYfmzgG zobo Vx~Q!O<^wqY-үsI^Vw~fMO9Noxˇ׿ ׉`gYĤĠ"]c X rB# %̘RUMζ\Ùiz:p*Sz~۷{jxG֨ޞ۳+rFk>0/~?oO2iV;p[>^?".BDxxOH5فSnAd0vxLjA{a>[{vig4({!gJ߀Ƙ1m+V,GƜ`Z\4`.rN͐>$_)m ~{5M)c_טqקw\q &a4By# U! pp nC+xqy/6ouwN\xɥh6taowM4d`RA|Ap=S](2xb Ss?Dۻw7FVI A$0=؄(dL Q5 tmZ+fcxΐ"Y&OTwjҁ17rW^ySN93b8~-5jn9 .6q3?3`QB+ 5 uŵ;9*iuGuv&Ϯq￙)pDlǀșXV ;,%!K[wVb]6oX[N9w!y6Ƙ EyOj=i3ꪲe :"!O?{価$>w=09!cCq;>Ys Bl̙Ocn! \ɿu"ٌVbPIιOl?i&T6btKIsK3qQF8p'mXR'G=7tY3fs1uLKa/`җs?/1j$G|p<3]?,Dt`ъ>95[e,xzE#䵹b3snpou縱cc< O,NcԮ))bEIʁu #Z] Y)80c_5سg'qh^dCD44Dٺu2dHAޣwI/k@ZSrM `NA o|Kxg^2KpYc䨱" hu/7;oKb$,&N38d|,B8 N&P?+-e#iVQĬ)-7)۾c{FDЫ0μ衇w2#n;!Q՝Z)cMdh$'V$yy*ag7noJƟ]&|_^56.=2,ۻ=?rX\z{ 9M0~nuwW|;a%Y[2 y!(s hE\x;vW.k@#|w6Ѭ2w޺c=f',(!x)<U!ٍGjPW8?ݒO1~J#ŕfΜ6Ä QLйVs>c{ &N_w:FwݚE|-2hމCuB#%p(1s2.8EZ裏ty7 l1p-q *F%1[>B.jn\ grS#}\%淙:1ǟKv18 "(3j|3O=?xr ISf"4GJf_$U ҉ewIg%͞ڂ["mܙSND)]weň+qp9ay#,B!U76|e7_bSϸ'qÑu%``];I ;DO=?5@P5bՊEx?x#g ´&@aK#G0iY(BYu[*@u -e lK1W=1cl=S; \+3*SD$λPփG51x8ZΛEs I^pݷ?A?8pٛރISVe.}sPFL r6_8~œyǦdx#O=zg1Y=<p1\Ga8sۨFE~HɎ]sv ZओO5jּo`e'|zpXZj}cnٯm7ZFOd?kϯo^ܳg7n̓z~cO¥goDŽ%%Fdj/y;F\Y+Jl]x?gO\GI/x%R~ %ĎPƫ9 to=5Z]PM?>}K`<%y/|qqcKɼ~J &(VRexy$PpZLuyQwg{mٍ?%=?L'"^ƥx7 s<#@8X ~GcD[#{4#d-T 8C!e2V/nr„ J7K[w3/ꪫFNs0ä́+Wu2_;wov>5iBDi͸?eS"\|.ynDq^e 9,w{Sl f7ތ78)5rX YIHd:==}3 |"} 9yxw4$v0&FV+Շ*iM5 g"ODɈw݊'<8w4^{[dB(`gxfeN)"b(z k~W`#E)]_J=0|vG*uAD<}W7DI: 9"bSH6\ƳKzR:_i~[6 4]vZ{w[$ P.xAH- 1f+%7 $[lw_ћ0e ڋ*][alˈԃ;@)s߈،<ر}K|u\zH-$)ڎ: HX!O>yaO%t8NInw"|V'XExaIbٍ-ݮ198W޵dZ,tbb,D?ˈY}qE<#|N= zނw`Sw`O>M䴜\AuJ[!QdVo(ㅐ%}F_gΜ62Y x=ÏnA VOpn%Gnҡ+~u*׬^WƎm!y ߛʛ h9Kܹs7Lg{)6e\BKN-"}}",D\'q :TeUg ZLPc o0݁j'gIY,f % `-3gwv).-cؕ3 8٦9 LzÇ>qĖ!p'B̈~ٸa)MH;r9o>|x=zVxo 'z?DHbn>A@; gt9XV wD~L=x?!X߽ PNd& ;-ay3ZH/_W+)' gf:\ = gdQJ?WikFtl'IqsTc.#7{3kN9|z(@$,HU$B*Fj;QJCDGp> є_VPƯ.1D1yJͤTq'j{#@jDsF۰8iy[s~QZB`R-Q7|/moN>+Y.xdDԢ wG6p MDzfPj-@ cFk\Ȩ8𼞜A$0"$$ 8d iƯX_EVPB;ۨO8ajܜrED^G7X0NG%wU,DP}<_~w8rIf%!>#pUr!R!),T& ه矑Ӭ_xJYx.SI8IR:EH"%#qWj}_K{r:05~+_jCRHo5n9 I?A_+ˁz=x.j83#'c=ِ۳#"p0g\%q1ܗH[6ࠬȚtnIJOE Xk乑"C9Tb+%w>Q"&ʇ.v K{3e˛rӷSj}>0< ng\Mj..\5({CHJvX.O?X|K;x{YJӭLFj՜0w:%Y;Eu1؈K@ <1S݈,eɢATB܉Z*Kuq)P Z^!զ9P( UK :'8 YYm̘1[uo9Dɕ⨾րPU|!UaaM\X<ԣ >tŻ kXmZd) 4F rhnH\5g s<ս^."tIΒU^o =a|Hɍ'lto5su2bDW!gY-gvgLDSDZ! [`2nOF.;.NG=})~xƌǝ\70dp JB=y2V?[:TGs?#GOr\iSXS!EN3<+R( '~iTDϞ`'aa UEC=7ƒyJ]-gv7̞Ӗ(\?˃(WzR i=EАA&go}'că$1P-o40jda2Xsr#g\\ƎYNJ7Q@,%Os ".&P'9BPD%F%΄Xr"%a*e,.씶Ŗay?~S/>>?U=Bxj§m3zṧ7~uy)j &I9Q L*ׂP+T7A) sh]vŒsZepp$9(<K#'TkR/mmƜ,<>~UXts<`i3/$;) "G+NYwKsO7~rܣp"&bbC"%DHPՂ{aa1mQ:@%Ocúenw3L.! I&"tDRxi䊖to`[s#[ޏup]Mv'qƍ+ {ʰ]6[Μ"B 4ȁKŧcǶGRkrk='P\}5p(9҆sOp{voeωgGNN>_D4}bQA[eRA;v[/bk] cK9Ӏ:2kl. 8boK1bXչ/ /^q 1 `|l Vɢ͏{~],pؑ'xUt92 jaLG\ $7'f,I4bDW&1RU99'X~)2jJɓAj xRե@r_arݐ砊"6p']ࠬ7]1,*n'+5!<7XN1"᥅6e=c1{|f $DzgdK"׽Rر~I,Nt,8 Gd0mƑ>e4Qϫ%\S7̊Y  ބ=}{Oto*1#KEiXpP`۩@cEoHU*x ݑE3Jaō,h> Y&`K{@#ÎQ !#Qm"-O4 q`MnܖYr(cU ec͊*Ӯ-z'ъԠ '1EjuA`Y>_EL6SD5sre/嫛xO)US[5Wi3DZmh93uDO C;6Uh┆ =Cԡ\j^l@wHZUߦ:@Mã{勊7ʟƨw~J_@ H'gh˚eS th#>/WplOaSbO"O6[#:||Ϋ>xW01%>qr;f`#)YYs櫰Rw!iQp24 %ѤLT֥Z3`M"`#1#}H. x$jz/1k]Ց#gp6 8+(WWv& &.ٓb xo˓x`HO;flS=D?ʪ[}x(xk$ WdJRڐ4t\vҽ=wȥ`dv%kR'DJՌi& ZiZBI_k cdqkWJ3U!xf6E eq[8#ʰn{Hp0$ qƙg+we +nhP:0 aeX\?IGSkeO^ӹ >m̅Β5ިQj̵L7z VU q2IT%aA9(z$.KYM!8m 0noz hrsB_W(\UG`iM1~(bX`.{Nj!4>7R<4!,i35MILr83g MhЩw$7\Mx#ΨuM!~cK-}9Зt20 ԡY]@D C)beG%{gΎ<+oX_w~U VRNoբ9ϸ!$}5dgxI wI6!Zq2 {# 4N8S'AJ>;2^ `d^We/]3jQ9lrUv8$wy0[{ ,Y"yY25DTGj G|ՐT,fQ\YO5}.!JTs|Uy9C~ʻ+kPL,VT%?(yZnVXU+_ s]U YZ)ҎQ,6)zn&jqܘ8vL6ihuKi241U3!$!ZE4-{~He =+%BLfCs8C}`NO2ejkfhR;|blXG# )b*7^J&`CqbwXy=5H/Ĥ`".9L G;fgvbO/leoð)8@4QP"3^Aͨ-4 XrweV 09(yIS]*RX$K{bߧ>\g"'%Fl1pRs&9˪/SrPȭCU&ƅ'&.$ (1P=*xiEb ,3=0;0"kj4(oXxn ˆMi  )1τfղ}Mz=YKrQzX l>`ȝ5a԰W޽<:T7iNϯܼaE|l8azF # }m\٪Au"c y#!Y]ȿg{:Zg y&p)&6D-v@M`e M4δG@~OCS1e,AT"\F<4FnUڈb,d#8y26Bz;gbԘEGHD{g jpH:cغytZi gkY~`g=9x77Z~!}ekTkXݥRKMjQv_SZ$5aF* 9o^ kdknJiEJS`م0 z- ;g$hσ0z5_%ms;L2( i<1(Z;RA T)ZZ[NӸ4먣3&+ +FH '(:qyk¨|FmZ~MTm105$3xIN*›ADkX^/Sa|:pVO-kڢY$`ESNͪ,|4Wq3%.#p(bl^񿶆4=2+85|Dն7^9hƭ$a)ENՄR4Օ&ϔ`mYF Gc 0;,gГR NfhhQ%H%q>oaC+ k` 7#4[ $X8!K8u9IQp <'F)PtE+:(f~{K`G0L y~Sˬ0`Bac:҆'QG"4*ƏوHFP"|@a/ԙ\=l1\Lr0o-"X hLbB!KOtq@!UB3<}(a~YaX& e CȲa^W%GB xwH&Q w3!SbYVio0ZF#-6JqdC&F#{=M7jFX$ztwH 4L&D"!>xo,(Ypтi*Y]40)<7)Gl &nC@<UݏcNS gyF=ʸgab.F2:C7=5gmVNLÿ )LN\pZ*})£`8=G= 4 O.nA[@hHKgeQO3Q/o|S"cr*ǏtYFvM2jاQV@ˉA1RV ɍ+&B͏}g6~9GCj$Q%U L;T'_vi xsM+{vQ8k?tt(dÉ^9hB emJYu5#[3קM+wI<2 4Qd=M`Z]jIsz{T2E$z łd ML[T^|n6.C}iƏ9 =D+: *<9,AC gabnA10x_ 6beqU`*w.T.J6!TVV mMn,D75HSEFV)}~ܹX#Y)lEBgP45\y˼Cپ)kQ,JցbVIrwOGy|1>}@bߖg)%H/禼14 kDUZ OdIZ~f[UXج`2e*yH@LiBXLM!Z@F,/|4na&hɝRv;duLy5 f&kOQN5Ù5C\dCb1"cYzvWba,NB@!B_*\%Z /;1Ʉk(2KmmFM}ϴP,qw,SLׇ:-'įBWgXM4d0f%PbqQXD}0j2 e7 r;\Rk#EPXf+~Tո> )2 SDX>1]Bj/{:%;8;vaú L /k yG5G )H(W$dRǠB T1;-;DwOU%^~B@"ᬑ,G tU7F2($5nY3nS,m$OpTƇaNUW9$D]ZVMU/-bQsȃ[x#s#A(l%QaC `ΡaMt|<1Y) \'BL wn뉖?-KAk*ٙ˞5.H,XPmx֦ ^5Cm>lgyz1!z0p1g%5ªC /$ CMK(|ztb  j:`5v?vtFzq,mM^AI%8-nDkTlZLY{g[,ױ񰪥dIYwrx׬GOUa`Y.N$loO>kŤ詢 NQ{Y+&_kX'~1~3i$Ld&4'14Ip%obcR\|8wތfs)JVvR(T*伕e`:%DqykNJztxo7e~+GA@Iα vaG9O#:oMt v*QN1p;uK \Vz2oX疱yjឺaJŏ:Pn dɈ,#x= ̹k/uHzL2LN>gIѕ6!Yֶ\SUʀ %O Žb& @RFXJz @(=8TUQ2Y '/f玟fGR@&=$9,js~ KJH#qv} yAʈ`|N+Wr9Yߵg^v1R-yWz[UL+$sZ~8ADG4ˉ"•IyOR[''W(Fw+~̫z/r0=1̶]Ofm@ww[ӲH..ʶI9E΀u. 7̖&p1@l)gNF)!d5~; ܩMB bSϠQ6;1dA?^!'Y! Gwz8b uvbB՝OϘX>6 Cuˈ&3C)RJfKIsn2DwњHG_/u62(haFlT]7A1NXY K sb j/`OA_3O"˻ͯ5ai.8 C%`'w4W' 聛g O I0qD4-G#( j}Iz%!Z'$Idij`kƚ(ԄLs s i'5+ ? C,|'R_-$/A4ϐT ʧI/ld8)י(<1*U:$9B )kk©s^ [0 LGAVSU+q>rx .|ᩬ%@^u=R?o&|h$T:Zl@EFG5" @U$2ti70' е:1\;L]Ejԟ #Ga3>MArz*Ə*yqTq6:Y߽m[<ĜR渃IQv'A& \?{lJ_y!ϊr|Mk- A֭r$_xBe3m)|d[./I/ ^eTÉܸ7:䲡X8XC\RMN5%$5 0քCu|=1$<%ge5jYBS=X9g}׾IdRp$~g .uCOR@!$X:m?eM+rNшkL@cAr֟t"|W3w{qē Q- 7:pRv!p8vx s22{_ :|Gkc5$TkH~HF>Uit5vWXg0 r1'|riKgj8Bn/ +dsq!¤1Dzp"ܝ l0mܳwolHgRZc{LGBO2\=\'ۯ`_<_RU`/'tDM1O]<>i*b0,*5Φ,dՂoÆ1Ve 4޳7+\e彳fn VNrOq$xf$Dӄ#πGF랉~r>g%sΥmdE֒|G rh8rO4r,EMFe-\.-hx6AT? FNMS͘sDAa{¡U5VT-i")@#H@S\Dam7YD`d={$%E b!1 g@ O[X^ne  UC+tU8ΧGie&zd zrr"cFj$Qk5'uZӡ|;V8'p!QFW?󂾺][<,hK=GuTșR رV6R̅î?rvg.Q5x :UJM90k>:ӔFzӼL~?G2g),;j kU"x^ZiOp<\1?-F}Ct,]@>jHb(ef)B;IPdm]PpZ lӟW/h)%fH+ wD%u X/łې6Y?{2\YAթFj\ eHv_RwL~]8wjS<P"9pwV([҃fa6C\%:Y07yOthOH&R2ݍKW7"޻ _2~sZL% 3|Ezs<,t4l+wdLs#wb0fMh7 ~ndضɳ7nTIuſ w( 3XIH“%BM$~Q{CO7| yPk`nmڐl<Ҫ$y|EZ޿Zg,1G@**I]F wlU`ͮ߰)϶@f}ےw+tyrB"qLY]Ml o ͎~$$y~oĝQfFW(e9hSF.y-X |0䔱-?5% ~'_tx0am%>(KxB6LcXu(%Ϻb~") Gz4'LHKh@L z@~"$覎+6|l* oWȱRG<)y ZȤ#I$F- $#x}_{[jt30L3 ڀ( LQwSob,_19.>G%x4da Ɵ5fvV~Yszm:`ko5ar\AC:L&53c Hjt NFܭ)!NTsʵ BPk,2 +!r62~Gߟ!P˜bǍXޚ6< KI j(v .2P7͐.Q=l˽9 ՙs1S}Y?yUSC`_码Sdkie9fD[ ׬?aN8?IQ|:CBZ(ُ̙֚{u?|?@ _|Ǎ#e,! \` He,7j uL&ujd'!I0CX)(h% K@^} 80*+,2ğ{kT/4\azPkJB9duwIRYY`s؍8+Zb-R?ٻ>5fn21Ӗp`?!MpyL\.^&H*VZS~ #0cRKݵE#03;'ܕ6lXߵe6T罋B_dT.W'@BL.#>r'!KdyC uĂ*y?1B3D2Ohsۓ_ sv ]9]-gvpGG_!v .ʮ+!a:B%~&}0ryvæ~+lv@aɄ,6;57H,g:Mdt:*&"gjP1F( ̜Қj_YrԬߺvnjmm5Y𾿰vYCq&Pؑ4jCt獃O N*a ;.U|ec恫ÛQH>!`*$VmvbE4aGHpǯb`d 3$7c|PZQz4VҡR^:vPR% Gyx71v[ RP#֒ MDZ'(gY?Wm4kEy̮&䐐1ӴekH2+mUyɕ<ӴH3٨7l ƹAe/$IEF0=ߪh |g|4jdYuU~sHx"C#kfm Ж224|-=(uCߟ{v;?T.wۀd"d;Pw8q"k6Њ@!DZJU\ԮDԥA %'-ՌRqXsݾOxf5v2_栉%atmX[Q:f[}"Ň<߾x+5pȫ):#%"튵,A-8LG&ﭧК.&+2 nrժf#p )bax֜nF$P:C3# >?zrV9fxQ=I\!qIpy-M#7jg^T^"@V=(.z 8xPGjwMn_f٬8[!ϚyelI3_K\VĨ9QG\98Kv;`Z&flk$JQBϢԩ#ŀ3bԖLaQ#(/P(H?9 bʾ4cJ< OR< aS '`nYt*]Y$'Xo]Ma$QuP Al\^5jo.kuVfiy N/ァNH*G#())aB^Czɻr^-؃:Ăc]^z' zʸF+J.̈t"KZ&o⮟>'pxng8}נAcq a;0UKXCZ9X垜M?lsO:y絕a%+ʫ#e!7c̻;i7wyNu$2]}ĽWHKK]8zv[\.і lh3rR{UHq3|zTWx涆s P c'Rw7 lu CRgy$ZOwp+VY)wW6oU5b፟>#؃G:6_ΧF^ï,RjeBKqOح$jH+{@pktǻ)-8{6/&O@i~|䰃k? ?/9 JI4NƳu@`}yvi?sF,ѿa`(?YYѳP*[/psS.WyvF"cʹb1 _{Cڪ3;!^]8*f.A1jg6TRV̩-UruDsO{f\},AS}kB~މ s{0XG Ϟ֊Nh.;ngK lq: w].cł^`9\! i)TeTD&DyDY]2Y(ٰ𞋖$tqbƟe<(/1;\PÊIJ-;ILԉ)CnHxF&"sIGGQĽL[[ºi 0Qi6}/hm18vv;ܚk > 76`gnd7"~`e?cΝԢ=xb &)ɒ |3^ `y>JBe)Aԏo8>|"F[waUUsi,mƯ~OuAlye222)$>RxX07\O`"uvb;w>ccrJ?i/ !> yOVǍWPSz !kԤg@ a!9CG8&ႍlZbJJ~ZyRpw_ <am6F;O"K d9 y\1CO`#C|(ʼ]:˜j+l^O~-5둗V<0Z[[uR.?iK&,ƿ` |wE#/m g|k:rffOk|4sc;vLJQSl#dHswE.:dn9W>2RqZe%]ˏ ݻÄ`86N 3fx3ڙ٧5aҗF6`: l_~MXX2xmvŗn(Qe,^Ջ+S[!)I9pb^Od Ws]#QW#1RE" yaשR^j$m>OI`Pa#1'mǼ ϟWC??y`N޻r-9昣;*F_;rO3{^H4(8ssZRܕOAKWcȏYѿ!<"Sq* ܎A'#i^!0]- Q1sqYJEyOh_q"5 8&=иE9Z~`Gu1Ka.+uڀ"\ TxlGkjbъ_/{&9_oC,UZ4(v\+}ȚXWU F/bvuLzS(xI?*"llu ~gǟ҅}d{X+j}d[PHKzI( d!, n읗$0-̤И ezS$C!Ozj|)\x8o.`͚ NVBcǗs ~49O2jȢ `ٚ> @bєT(e \ .yR5|r$H:A +t3V gPqˮp{dtd't_`ȠцOo)C6lT9ĉ>AD[@p;Ϭ,?dmZW0 u>P&<2P{`t qÔ?/*2E6GrUbW,}vdV#{h= q\DI(S OJ`h6sP ӎfƇje~46u8Lhsߏ~ / SK|fq-c֊وd\ι3H>T䒤:_R%Eᜌ&HqRV)s r}͡ IV!!""6!#&)bAm8莺Ɯ7h~d{:@pW n> ORjs;HDg9@ [0<^ֶVӌ?)|#44Hc12VFaUÐGkUQ0F  U;P]rUޛM* mV̞ڂӏJ7TǗ|* \"xǗ=X]r8Nqrh!xP}}Γ180ԂD#:5~m.xI TI-=[*+Wu_ۘe΁&Fܴ̳KB%X!([O.Z8 F:PCLbjPJH1WO1Jhѻwu!`& 3bƤ0 ? ˝;?K7i >A%8rq?Vr5[5}X7tʂ܀>C>P $}}E@|=״a!ošb'!5Rؼy{.}lBf@pQWg4Hox9f1T""@y{ bͦJ0pBh_E5Iȃ+<ʭEIRut$8ቁ" :,G9V"Sǵ`ن#ri8׬]7kB@ڰc9zr}EQA)FH5PjHhq:ۣWx&kVBkpo-?.⻳Ɨ)lmh`JXkf;.)4@]'|JgPl(O2~/"ӎb2l,cO/yy NN>8dmau5G"Oh""VԱ-6gkp!5%BK:ul}כp hX#Gz-0a\R!Qk{"Tdul{S{{Dn{ЭK8+y0 &.aʸ̙ڂJFrBXˎ۹yӆ&/|Y]}E 4(*;U[i,yb6![,YՋM\ƖVnB-=qy$w"Ə*bfOmŘŚq|?T;v5?֦~KaI4.W?_ܲSN,K& Mu/U {c뷔~s=erXocD"%A4A<0|!<J7cJ86 iUz%r J4/8nknuw:΂TΟ:J'iw~"$~K>}h!x?}_ַȑ]KBzeT{DjX /ȺS&wclڴ?on>Z:DtLgΑFoO>gΜVc-F~!I}г^\po?"X G~DDk>jܜs~k„qbLT,Ɵ%$T0QTN2fʶx+ ֬Y[5zϾ=j/_ vPuxgs̾O}[/ƌY4mB._'jI mTOͯ^5UX \"uFgܫq/m䲷 ?nlGL c1oư? =c{_Ձ8# _sG{{?>cƌ) Q(U49TXrv֯+?{E/>5v?~w濁;.CR|t'~3ξu֜nj9xpݴJX,-"(is~ھ>;=-Rx[0`Hwtx+u?OO<P#۱_+Pc0iU9p3<;p;qtAt0ueVBl"#Ya@Ņ VHUĂ H(gAZU\8ܧ}zy&j9R<:OHɽH gyx~t?op.$P&W " R.TSd ly|B" I>ةآ(G$@`UR,@".Y2GvX@`B, 8C L0ҿ_pH˕͗K3w!lBa)f "#HL 8?flŢko">!N_puk[Vh]3 Z zy8@P< %b0>3o~@zq@qanvRB1n#Dž)4\,XP"MyRD!ɕ2 w ONl~Xv@~- g42y@+͗\LD*A aD@ $<B AT:18 \p` Aa!:b""aH4 Q"rBj]H#-r9\@ 2G1Qu@Ơst4]k=Kut}c1fa\E`X&cX5V5cX7va$^lGXLXC%#W 1'"O%zxb:XF&!!%^'_H$ɒN !%2I IkHH-S>iL&m O:ňL $RJ5e?2BQͩ:ZImvP/S4u%͛Cˤ-Кigih/t ݃EЗkw Hb(k{/LӗT02goUX**|:V~TUsU?y TU^V}FUP թU6RwRPQ__c FHTc!2eXBrV,kMb[Lvv/{LSCsfffqƱ9ٜJ! {--?-jf~7zھbrup@,:m:u 6Qu>cy Gm7046l18c̐ckihhI'&g5x>fob4ekVyVV׬I\,mWlPW :˶vm))Sn1 9a%m;t;|rtuvlp4éĩWggs5KvSmnz˕ҵܭm=}M.]=AXq㝧/^v^Y^O&0m[{`:>=e>>z"=#~~~;yN`k5/ >B Yroc3g,Z0&L~oL̶Gli})*2.QStqt,֬Yg񏩌;jrvgjlRlc웸xEt$ =sl3Ttcܢ˞w|/%ҟ3gAMA|Q cHRMz%u0`:o_FIDATxygU{y*ͣ%˒,Y &cpt  ,dutV C@Yq۝4N026`lA$eɚTRjPyx;ϹO{] z};g}Ul^"robtu;m.t-~`hu p'] "S`轏 "/Y׏]/z.S "?\;zkt}c~xEy ]w7FЮ/5_@D~ /X1z_kt : ේvob쏮5f _ĬywF ]zɶ?r~Ġe1kt]f}pV4i.F蚕kSf&գw0F׬^$6] 06ktvh / ؠ3kt"C~/aE@f ɟŗ^6ab2L=+.PB ` 7; ^djh7ϪZkst?[ۓ{lR\~5osc笥{4_~k[='5\~Sgϼug8wb=  a}淿U?7?"Wbn;/K Pε lټH0Eg/BiQڍn׋m&‹6u3UM& 6@n8nJ4lxinomN6x~\}o"`Y;ly=m6CQnLڎ} A4  bKpf|9Bk7m JXw@`6BfQ,f7 UAr~Rƅ(n"V9N,i?gmp <wK}d\mL4kdo68k \f'*ejwh,< ~7*|}'3yg6moށ3K75GӍ,50z=sI7AÞҷ{TRh>);j6Hp͟tY̩.p۬HH/l4IQgNj=yۇ?Av#&xR"TکW `OU:=tAM?СC3~=DihFz NۏnzpzƸM]=8n F7tZGhJLʊP*P)"'i 8cjRTVSp[[ u#N?p?nÁ2(#()W'T@[y\%EƔGY٧6{ߪt!) G1K _%=L9栆EZ_SZnSB?PZ!ҤT*O1nt2~5u;$Ks픐g }M{UϔRp! kASi+O4,aޞpeM2Lٞƌ=;D}XScZ]ՏS3_44J>;wOމ-7g&+PwFsݬvsSJ O4}6Eݤ[]0hbjul fOo~ sTi{4-uLmي&A)ƃT}y멞l"tO6], XSe}'3~,@w/,~l.} Ќ3nPp}ltf^ /zq `[H Mj P,AMaCpL$Sb7j)Z\)0miZ\ Tב8S^Ujf?TV*seK7<>GưcnK"P7/oR6\kO^LVǂx훑ĞF4H9w$q h=Gw'!z*>P;Y A n6[DP ?4pm~v'?>_%xEu6 \l۵b_UT)~ # ,9GivMVN G: D,b,5m lXqL"m7;ԃti־j6Ũ`$ARPɠT.hjK𛬘/,6uAvY|g{juPȖ7oev?;TgnЧVmS+pr ٥RU:J | J)]= l6U+Yb^CEAũٵmۭREw g])&)pRQs#X_5#Ũ),&.H%LGᖥk -˃{%t5  fZ.X-(-曊)tXe'E??&GaaDDlSC菡MWrmA=)1qKWЩ֮[M!DWY?ər\}`)TCs$ٰڅ-fWi.NU9_]UR:RgI)tE|ڟYkn sOQ1;=PZTܻUSZiܗ}>޽7~Ʈlmy:]z!/ԃ$R$.{:fSڿSJ>XHb㵦Ԥ Z~Ӥ@cHBb#p*7!pOv/dVڿ wQ`ݲш b0* *I{h2GC?c of?!u}ÿеS݆3iTʭA 5{R{:15DkJwT#S+/jxl{{PP 6q6l)=ĥRU1ǀPfpNpsUrECyQy.kyd{D\HL+"Z!&R)57# K=룿WFEsm&J9*IbXI:@; }1EwhZ>-Tx!K=]ٔAdCZvc{svjԔbA7:*X_:$T͑Hqa>+'&ٽwPp0~M7LQZ 8仞BN;!WH Z cS﩯Yk,Gy~=ދe7{]\յPLW,h2f@|X\]yi1HF֣Ր,&|Uk|dxIF:ߘf.TiHp A-ΡՕtpTp\Xjհm0&"C7/fԐ#AJ$XηcsU\n/SԀk\G M--մYC)䰼W @)ڌ’a_flه(}T$t3XwP0UNr)BL77V\Rټ'd*d@rb`a5naīoz{@<Յxu/,ˠ,IbHPo8`ʄu [Mo5LfU3yP2EZkQC*R&}.F:5qb,){BuyċVlf>:ҎLA*kp\Rj+))`*v lx4fͱa3K7Wf^)s7=  D ˤ:! cSWB3SSS;)4)"UIGez)$g3ufXF j18RBl=3ô[N 9eyh,uA Rv_9ltS<7fqh`h7 uI`-XC1s G/pFi<5UYGJ&}5)/PTB&ho%Wb- q&pcYÜ}Ձ۲}`IGm*U@[$~(@E[o+W]ҍM/eAj<۪$ PWc0xa$an'#˳1p\KJqbB2q 1[hk,8q1(J:҄Y91/Bx y~Ȁmд>J!=TI|ݕ fQ6D!u{O,|us'|o~g'up'OI;F_W.F%N;L"bP`[u y(vkHh 6`^6ԘH;}([TWpavfRIuMu3ٰx h5UK~O{QVMB7moѡ SMoG6 SmJD.tԏt1H "t*9pb&aL124E^Kր)2%`}{Dm5-¸385siT8S:]ۨ(MܔTU3Y~)Kt W\ӕfAkq Rɺ*9ȄV,9M62F$V% |Zm;u PAnM 6g׷6(EB|j$W+t%d-|e7B*cԌ8nð@z=+Cx mJ:Q N_VF]Ŧ[^$0̍J? ,6zNSBڙ;)Fhfv]Sb (MzO8U׾'rؖpb<&!=݈xV"Pn> cj݌zzf3ɵ$S1JKwgoV|ZGPĜ8tQU{Ғo,Y_8 j0s%0=e7;}SLOG ˂}ib9i:n63¬~y sjp[>9m`'dfP{Z+uK/Z< Ļ{K"dMZ+\&^ 弘f'"n2x|ڹ̩eI`)Rێ~xƜS!vU-LJ ſt2 ˡ쵎kgF@eJ.2? іV ;s3[`٪8Zf+Ioh"K')B2؀RJ)| 6iJR@O"#- {5lNV-*%mXH7oet,MZ1b\q.YD{ Y:4U /0`y3 )֎;CBB y_Dz:fQ(_xc9tϦI-T$pjM O6ؕ$).IwDx3Xt42C$Z ^K"q X9ƌ̹wFZp f=bJlU\&+ݦR1I<"GsYS5 l `AyDt=ì@ܷNmUq9, u!4L#LҴdRdg IDOY1a9gC;9 ]m3 FhX*":,N[$ 9NҊ4;R*Ҧ*}kµA5IAI؛ro?n1.aj@/1hZ/5mDx<@\/TԯIdEdfWVXmE!uԥ/\=xY#~P6%SɈ*y? ~XUԩ=q{4kA5Ԑ0a䵚[t"@sڵ@TZ+ $x0bZCMxw2Z!d~E1!9A~#$8;^o#C o8-®/rZȜ޵.чXxsU Jh'kdu7 h3R4OlJecҝ$S{2j3g>{:ZC\ qt6a֮*se/榸Xl^Xh{9Jݛ?B3ȞfK ^"AMJӹ=H;L;c’;uQj3iOT0W 8rlȮTcqNWa:P,PV% Xbt4߁W 11m-O&Łm<]ۑCJ<**Yӹ@p @{cY87;y%=aRD+"HChBN@;XOYŞwBv3s'R'MC|9_фG!i.y5NںDs HL)6P¯bȆe c!%y$u>JjeEЏY=2/÷%V]:GT%8P"B2؄imu3I@ݿu%$ɉ$^5IR*泓JΡW>z;W׮ոX=(>W!|cʹ訷e2YRڶ6p@}  :qg ݨ"!RNGΊ`դD-ixgIV ;*J'o_ƞPh!N 52p,'PӘ!T^.>y.!ouX/K଄kZޖd*tN} e_G& bm쩭tbAhh(8$h_ \a_x/ D%% (3;5V{'1AK[qfq ZsqA+(ox'V'^P@H,AAUû ң^ْBeA'S;u0UNMoٶxVDs<G픇zbH>!~C ơYjԝ P,zKK:,ukϩ|A.+jЦSZnOQV.G)XV:UX%S.n3"Q|8}cKm$j2< f wӻ N k͸,D{qHe  (M&8wʨ;\BN4x6ixLv ;TѓB-ʌH.^U2 0tG-L3K c( )4 JzdJIFa; ސsdݽg|rE_ybY{qFVL7"Ꝕm|`ug[JݐR11j'Q/cn*t!+^VJضK.p!RxngBsM$$>+/BCo3T8{}hh|h]nWhp@b`z xJOI{Y[8BSphԡ=Tl T](fQ()M3"ѵ;'{UIIL;˜BV YpYQ˗b-,.L;BU-(׃2t:?뽊&bo֚Oi;Ib seQZ|j,`glP+-* Khy0q ?~.R7@Vb |͙,=>4PڰRf>2sM,`d:AL]I55iIr`!ɧ_DM4  ?;! F/%7?Z]u?iۺah'~^IL&C.y'r?A4`LYj|K'`"4L!'! 3QOe]*IcߋD s0f" K?NRE'i8([ͨԊz0&Փcf s $h&`ֶZn$2@XJ=9elTka3J^k#qNC~PYMwێ DLԈ) '4%>PR$:}=%0jIR7Ys-I=3wtEhJƖEމnr{8dnQ\~:؛4HC[?Lϑ.dt=_fӆ*I]W0Vp%GlXisZsmv@HѪn$`LQۡ## i&RG(cM:1f_P1PcAVR4`;K:x0!%:<"y3>,ܘ.U7=$mH(z~܂nI WhAjplN1 - RVFBQ v=jbR9e.%"!#&wzz%@`K">UsEzӎ -\'jN7CFy:P?L>{ o;3VuLQV-֟5 `l(drb.0?>|&vmPan. 7B&vJq!;AȣjQNO}ivȗSofȀ)B&] gQݰnIa>f"N8Fe|PYQzfGSw4g@(o Ie, iF}7qsYZ d䲗%ZWC^a jx]<Űl;˞``EhyJ'E4E.ZƟ!I#TVg@HNr$L5bVMqFxǼ4 ͼ B@ $w՗:YxefFg)S(8o'|܎v?vp>:v(}26KWaŚXbx n\[cll2>Xz]m"F&r̯b J]n\Y+lR#5XD7o 'U]5 8$d4qnyMf(b%5Rrs/Df(;@u?؃bӏgq~?N=SǏԉ#ԉP(Ν=]cX2l:XVoƪ[sXD'!~źEǂ']*TiP`9!H8`[u"~Kq1Us@h ى[@mR+Br񇌛(tE&N-M$ш8Y8+Y -S{ &J#m&.J,CřS'qIT% :U_켴Zrm4hNigR*a= >s=/$#W xgeϛ8s ȩZ }L# tSy%G'q]bGػ!}a\wރ]EKV&3jr\Vqu!r#/4]K/m^(ʪ O}׼wcٚMgd:%Z ,>܄,AL}[i۽ ($ ?@j] ?Z ޚ`n >G^ 1bFsgc8u0?,n{+-]edrIo;j'O%FG5&|;,AˁtI9Y"Ycܙb^W -.Yno5]cxDF`~*wz M[Y %$)P]05%q 5]9F|[@w_=W0N'e(pzZ< G/~_'̣y.Uw)>u7Xt gT.0q{vH@$[!"ds;MӤS.ha*q.c2\Sj>76OiKth~ Rg5ؓJ"AR=3&;_ю/|33}{F<ލsgQ&q~ M6^]BDS[jƒjs[cD_13D @P@lw%W(I2 BnX VedY;g' Itl+w~zUv?mL? -O`5$8,#U뉣VOb*θbVMFuNz;(E-jq)]3G}z+I .dp0"2AqxNQ$iiBp}jrTJ-N?oʝsO>WۥZ/>m?;XB*"PLK0r@B`ݴ}oPg-a ͊ "Ӻ#EcXƌ>әhZ߹ 7ˣ?^~ ~Uzj_\ˣϝÃwǿڷ|sÓSS%*oW7ȼ;yg-znUyh[gY !"ӪL\ Hڳ]*ޅr.HLbEW͘8qd˺<7xj D!z{,@;,6{MTg$6|vmkS7?~Zآ<裝j= ݶ@(UA ^,Tf[.o>_a^\Aق{OXmk*U3ϊن-iT@3\;VnPTR15C͡ROuuu_/bb]v4ֲkuJOA@%OZ=Hߪ7ͅ K駪WҁE?~zV9qM;Ƿ}'pQw:XpJ W<8kJ48M &+`ya[lfVɧ+P'Njʛ.̀D2B jJ3LE( QPe8 }@1->[Ip9|w?/8u^ש_<ӘO^IIY3L˪ Bi})Ǽo>I<ݸÁ|ǰmQ,OIG&;S )Sɀ!wf'1wTn>@IpAQ `tZxR}0Ql€l0"+$s'5x$*}?/}]s۷/WٿوF3Kx^yoՠcT b3 x$ RLE(`'HgT/c*vNB8kbH fKa w~P%_Tqi< xt_ɩN~N9tSlkKm_?qu; W&8Y@V2]5Zj"Xl5,HnVg >bߍ&6Ne)Nٜ=ا^O]O{>#vڃ{j|Ktx!L4Zq قdLiZ?X{5|S*?@xC jZת QiZ Әv oڤCZ %njK&E)wv< ύvΟ3G&iufFw[n閼 |qwULu\JؠgCW6c6 I'R [Q]:{qE9~(%Vs8Y-k0Ȯ)3=Y~|2*JF3ـr'آ?|-t˶&xn[_}np/ؒ^m;O/߉l{~\oo~ wt*)ZbVѴӞ&`71&@fw|eVT2$jwPJHݴBP=Y6"+y%Xfh{Yt},q)z< 8uhOs=u;zęh,n8W e MB\miUS+s$ 619%T}Hgn{4G0%m˪&`cRulM&@A*5Cj 8BWP$UW͈eZph705yձ)XM&gPf(#𘭊^e&bخa5VmXn^`$rPAy)47)$:8q1+ػQl%^gNƮG¡ۃn0(/Jj~t$n3SO1/) HCf-.W24|1XM*# !d:ʊ:GdhCh_ xZ+iQg6xdԎ9 /F8?E 7ͦOW >!ԁv )+]ɽKF=jNC@)R NE56#'fG]-T@&H-:O;=?u~M>qL YrkG6\y 'c+z[vJ=xqmC&H@FQzDRl"NK/׆NzM=NSSyCsfF68RNP7S\N?Pwm>m?{z,Y{^!s{(ZҮ9̫T̥D)؛]J,ChO"'N=yFQ;XWwSԉJQ!&aPO"r!, DaV((lfj O=u?¨Y ->;>px)5nGnQD3斆@y4٬((qqj {lh׬6x=D=M gJ7]A4 `[i sퟏڏggN:w8> Giz*a?U (=@= =١4V3)1@ j]d- D ;!H8I(vHТiӮ';^ <0sˡmxAd,UrٌT%j?$l>iQT=%)/IuG ߥȕz ԁ^ApRm;kmNmKk & 4-*1`w\Vme\dͶDޫ]qQ=?rũ?IEJibn_^E;{H- xRRFnd= Q G$uva#pWۂ.򵛱lF,\ej 'ı{pdNΝ>1?{>>ʢ^=Qt5$# sܰz{Şܹ O`rmʛaXr,[ LM8^ؽ{v=v?8Ξ8h:/s6$>'20 "|O?G\0k nU׾=Xf3-Y ]pJX.Ny}x݅#+d aE抧 e$R^Z;=;g. .Xr#-˰j%XZ)?=GA`te՜$89PtBJRA:wn _ߌ;p-?EfPu7c骍P|볿cGzk`+3jٚsi< XiNá}\ߚMM.L@`lKi ]uoaO5Á )wv@u!Ƅ؃C)S3\[Cy ]=b[´aڭ ]3TIn(ͤ[a4ygN\q;q>+֤VK!PiTi ÍMW܂Xnhcx^gnf=>D:wbjW".ƍotq܄%PUL[K_\v;16>1Zk+g=dN%lFn#/< >6>[\ftMtrHek/e,_shŎ!6yn5D >I_6>v-]oz'`7lwe635>>.{6]vhŎ)9n Sztgj.&8zp21Z[~#硚4hWh10ňP <,[26>Zk@8:dXR͚@>~Eg8>o>^t%/[[.vdw% r(BXw ϋ'`1vX 6gXEKVwy5vJ'4%mD@cΰ-J}|ʛ,ҤbK q2Fvt qώ5qw֞5%@d=P[0Q$fZOzWpa>z-֫ i kE>Uv&{Z Νx W2slD:HN?{jfGP3ߺJL\u B h8qtRr /!x >93]\Jh6,zP8` ; uVTþ& aL\iF$39q',Fp QLaNdɇ+f :{'Sv<L;g[KD< Ⱦ8z9gG+utX 0K@I{᝗q ^ j kl|./¹3'gy?w;/\'cuo)Px7?<y! * t55CnqpN7 --.y&/ ٓxC8 \`ꋰ` ϛo2jt >~4v=y3_%x06>i xFBP7Ю{yo'XJCkNm[AoApEoDeVusA2s_D˼x X|- !`: =6]~3l6\cbbTps8w;;ؽ(Ν>6G?uW?d6c]~# ,ƴ@(04͔jg>~M[Q1z߿Lau[c`j5 B:)(߅b@pX}{fZ\JѵFCo7|`%'g h25/vb{jeX",] -Gq9,i kbbr34ef%Asf_RA*P"DK''<|?{ T !7H/5x=WgTܿHCb nͅ jX).5i6[O?x :v`x`Xf3 8s-̹J lwzY K[Нĥ:Vu9%7ZLJĜܫj>\Arܪ4 jޗט"1gTk/ ,W?%Xh%]0SZJ`n7NgD𧦒:fc.ڍ rŶ]2qٕU1MdMzV3nh7]z|ee]՛n'J)a\l9#svn&J $WQ8DQ;!i$!ֵ{-:nͦ(ՙ*yas޵a 7bn a[`HdZO(g@*Pf] 迸oW'3DK+CATiaNJvʼEga3d6sJ-mչnBI-ZpakΘ@ȫ_{]ze&z͵GI4ZnYK4[(CT֊ѺOUwUg&{U޽ GK.ݺn߀W|AXklb>l6Xf;5#WzhM:XT_B)^(#0OU@dx>vNB])j`=G6 tH%׿.88zWyђr͛tźѮ.Ecw`66ּ:!bNf AuUF$fX{,0G8u>Jm#1AyE#*̳e*6IW\t-Xu7/免ǪM7boZ%#;5״t$eD;J[אY'@qb0J@5Ŧ(p<y5sG(XmK.]Kox.]5/ᚿh6\6,[{es X\Fwd50L8rLB&Km F\E(@EꦲmgF+Q"vT P c:R2Gu(f 亷bG/{ &՟Ʀ}(==z5YȢzRX45۝ zhH7JXL:TC0+{wt'U{*# f{(j.' ވ+n~,N{[t}WJ zޝV/35{ &UF:| l㇕Bp2$!? RY>;S#αn2WxJNc[ʦD1oR\{㢫nN r+?ae^!trgpnH3bԠP)AB9l e* Y 2Eub%jj. W>,[qۓkMu6/R[z%-fhXI)]n҉8kK!| }Ybِkkٔ[/wu2I)h,aL8 `SI5r cz۰[1>15>kކ l DV8 ޚw[i0[shוe eST:e6ːfP0R=[NG\?W$ڔ_@ r1t%x_QE+6a55W6a_ f-%jtUJ]-Śj2sy׈t`s$ػDzTiQr Lgڬ38srʰAkb)Mi ԅ411.{6TV֋hp%ƮVV 3!b1A1`!=mlļc!> 0a @cХ{ q?Ep٭7c h||[`}%;ƥIBZ&z7fg@ wINfWn,TVA[w +0i (& d= zk=;=x?~[ qއ+n0/\ijl֚G*^L zIm>Jk@0*P$9A8eZ!N)dzZݩI= mA9O.ҳ:-F>Wm#7fB26u݁SP"1(ӞUmdT2aJZp5(H T$P#_ڕ4DA=DI{bcqDJDTv 0&C5kue!MC5/yXDX}p?5[~3Ԗ)i $a1+6V?=sXio;XqXlTk^m2vNjK3w `ދnMvd8˂J*9At[^8}&]j7M77 .=@9U/`džɬe]b +@7Dէ-jT[UD/1Ȁ4NK_=L F e|ތȩ nWch/2|z%_ Mk|W75) =<']z^FaU_9\r_NΑARfsw 84(kujY)}_؋ZGň+y{Ÿ6iͯ1)U=ֶwܓu{1f  {҃5H-Ӣepݛ_ff\qū]Y$Skv\lKou@$~mKs xr?bH`)dOqW"AqS@ayʰtbfn9 d~ߟUo{f?@Ҽ9%)@DE"VgX&\{Ǐ2܇2ua͖[p%7`)`M"-GD9KD5.>xb=]Chi`,2$mZ1B$0ZusH $ +c%TȍvUcfN`BmK9Kh8(`uM?y /~ 6Ο?* D01oV_|3#}97DIsGWx̬Sq+TO{3'ZJPY"?Q]r &#d!@A&GSםITf&*FcqoE[3 ?7͉ IGUL^)gy.X}p9îǾS2.]Wp0JcM5ikcU{TXKUB(|sN"瓟Sa‚8*-%-Uٮ|gR﵂b$j\6Rus 0@, (-Dq?/\[{'/Zk/~ 9'`˰k߇Uoļ|:lHIg֚X%u#kŌ{ͤt%K Q?64U38xg;>=Whv@@cʛܹ(ײݭ٧ uV+Fju.s!DHm~̤B -ބek.cO|gOuY?1 -|{wcъW:gQϻ)zZ+_{ =؅L*׶K `3!销aCL?QD@>2#A."p@@0) dJB] `||V ׾o`eaǿO3'±Xwmp;pѵ `.1ʽD7P`1ڮ{t5Gf1P:gqc }37 iHa'jJ-^;&bW-JB q'դElFI/T(:`T-\/_%6cåa/\p,Yky7n o`[,Xd.s~p1>,ݮ">'$AI{6֥:ӦQt HX-={`Z% Lm625ύhXD׎QBQ6LZ;Ko.{*=ʖwv>_Ɯf= K!+29Y{b )-H@;#ZFe%7W o,zєBeV3(MؒQ?ũ> #%`͸ao¡]:74hnyiED)A066K\Mc%a1oJ̛~fݴzэ2^ &DH0а 1oz z\0fG!q[M@NH՗X*R/ĕvǪ̸4kr^~ VyVρ/XMK~:ԏ.¥Xr3VǏqQ;}t@d E+`,X՗bhF,YWnފ3YxF̄<ؔ!a`ZS:fwYi01Lh`Y;bMf'Cʄ˶*v lI4X&xLMBR>V:!i԰Ӭn3Y]mD ݊+7LMapx8;û!"8sp aX|KVoŲ5a|5Xr 7Nj+fz^~E&ӳ2I$Ќv@凸My3 _&v`Y_#W!TV5s']`\Ff#&9"F=hҴ%(Ev`lb>Ɓʍ׺ETS̪מz:..+K`Ϋ5k@R9E5PMWe~$~AgG>>$ˎv`Pl%-?jE"~Q@i9<(9!@u؃+0EGv-R$jfH}֫ȴ6Cg!9'`JϜDֺ5vʅRGfͧ#Ai;dGDBuPw'Ea<2M\b3? î #^h#WJ=r kIH2 eM> |3<1ZB&JS"XJ& f:%{^kwqudϺkFBZU2#Pl'Ni6W/TAP؞t)b߻ٴ뉛ężXRK6q.\^cR˳-CTRDp UaQ|q y-{$02ܩ'?”3 R]W]J\2H2mcxB}MYF ~KUħ#iS]iDA ﹼ1.¼mfNƬ+iDh %Q(.M\j{tQ\K|!Z$2 VEFk֗ilD]ZXFOiFU+vj)sQ¸MYtWQ6&`#l'IOvob7L)0 ՄEcH&NJ37jguP ɬ )WqI5=Wi şj$ΝxwW>$`u L $¡sv=L6*zI'mVHodnKNɛQ`Pcc>u9 Ki۵4} `[R7Ae$bJi:4i*7ӄ Ì,A#.Ֆ0-D)^2&ʙRՎd]<@GMDYjq/ ]5RE<=yM/vw2KHVNŶ$M8#hНOVvKl$cDnHTyϟI~ΈM[Vݻ3qd--v[H©5IG!_g'RPat:oz\2گCzBq0q]xkZ*cUƀQOSoՙfOH> P?%lY"j+;'@@3{YCke y1'Q>}=wz54tj` #׿R#s0/Br9 Xq(ʦ4ث˦zL]Ā(geh1w%2%I6ej< FiJi]e3рk< 3` G/jJiOcT5L,`{4,7&+*qH5PFUbjf(<ϧJp0|,(Woe _Nɽ+z`b58#WNK'GJ۶ƍfmIrE 1dYFGlœOǹ 0,#5%rg|ۿEȽ`|INlR2Uh.l𨷲 w*5HZ}?UZ`*o#Xӧh\KTQ mRKeA֫g:7ڀ]RN]FB'OmռH$ӄn4E"gFsRk xK|#$'2c8M tMi<EYKZqϪiSӇ o ?*Eji) $5iCR\o0>2fΰBд4Yvu +p\++aY+э~NT FRkP%٬FЬ>),69fz*Tk  i麤e]6HD7yGIv<0K2O&n{ x piۑYtCE XY A,s>)%(dceW!iu[L6I614HN24cMf7ɹ'~e40djʾc:& >&7B |JeY J)[ M2 C׉BOͺХk5ڍA9- Ta<*20.6xLjjw.҃3#+npZ jO&>~_p=6YB[HX֍bs1×bcZj.! FZ Akt:=Ȗc/֓מc Z2H5MSg>Ai^â&؉ՃC=$2 lbIiזTӎt MzI )iWʴc尬1a, XlF_E&LVտzzK/H#dӒ&33b/e}ʛXZ+iXi~&^c.fasphi1n[U r`/R2ߤohcZo@-F UeuTf1E[?uNVULq-Yu.6r;X@S32eOfIcҩ;,W&PB6)Ҡs~:2u]3kۍ(H7#Ъ`צo:q:a$uwpGqZL'\0^0A3ϡNm'4M'ZaM;ʳ,X]M[JhL) U)DTN$}.L0R/ .RG"MD<Ng2[4թy}.[?9UbP\4Pm'zopȁ>fy2n8 GCBLknH{$;/9h4{P8^PR a$^e:+)RYiɌhfGni fɃ?#/,r)!^c?mJb Pv5a Y 3D5y9ʴe~ 4V2β{q 辕Y 뵧 U{AGV ~t6_UvA |3D۟|Hd T_*%Y(g 'I>v06yF[B--dqU;lS+M ]Go+ͦq^[ JJȵ#=?U;ئJ5nJ~t'!M߳V~ 0RX &f^dPjOkmk A\+Fndy$*>Uyګ{Ks'g[0r1K!?%Uȷw)Ok!(k7qIsHI;$QgU%SRrNy2%8ǵ^{"}&3oZN;=+ZYa~_om5A+;>Yէ)?y6epx*z3]%:+Kef^8&WRR4lw{T!'NzڗFHT[VJD={{䛆 b40 aS)ц}:w 7j wRK&l#,Lǻ7" hz!N+<gsYЩG@k}I`TRM8 TqZ`4QԕnW"Rr',\OZ^\XtӮtkGl6-?s C h&fn€_I怗 1dZc& ]GQ6]U\ W2K.S= :&F.oP^ "Yf3IbW}ڏZqm*fe8sPPJR Ä@~0vS;DsVU 5 BL  ,Eb 藩9x rb Rhͦ5'R[EUZZ7q@].vaq;3&4D)H~`='Eɋ)M-n`U3S jal}HHIW2tO6LS+IDu`k=}f4[Z&e?٧p"fSWUxc;%i)ڊ1euZjiڍ퉮ޣq5-ha:VJL̻#uQu.ۣL&ch lh4̝w,?ZS #/%Ћ5a 3l #Y𝂰sKcc]Qz dSS[Sd<R10`1HUv:\k.T{tH\SbAi>CM7YE J@tH\}g&Oy|N>hxV[FMYe^43BhIjWP6U($nѨ{ּ^vZ#!ko5=lPvrC"jBJcM_4)cl6-jM[4H!ƥK@G $/|i->%.޷sxϒhQt$Q%!DDĶVUI͂OJM>;d'E */12]I{M!m7$)XzLi'F |3j3S:+Ӱ(spGL+߸ia&mj֒t4k  N  {'带r]!L(A TJ,dJ-Hx n`i+bz+)]e82,hڵUY04%m,erSlj<+rVg|"LS1MO&>0 Y2a[ k(I%;GB8Y|?60a;?yO龩[}Mcǜ/q"aECZj,ޚLC"M%?yt y/d֑(nx`d,YDݶr&+9iqY/1PApb}XKFE];]L?lpp?_c ;E<6YUVtu%l:%?R8A-G"ȉ#YQBۉ];bV%,IK<@RR@V( z[,Iw7 X!h YW\[Zsns?yZ `0~C?hv թV>Bˉqf"ry:%HWㅴ:tfq3M%:准!AfXk>ݘklŀⰄ%?cE=ត-~Ŭ3*+50Xv@f`'2"xdO?ϱw|Rb fmktk_ Ђ%bA;Oh5 Bj j`a2?h `zd-ѵMDkwi'ʲe!L=M 4 cs!0(k ;kڙwXVet5[ O>;رs1ꩾ?w1ׯ ~&6{#vn;:=/=_f )vbOqvBcơ}Ih⒤BA Q U#tvR7 G?7;MLOGώO{e1[tŎ{T®t> uQ;T?L_xL|{S5pD{.mYUz즏Jl#yMP;Ʀ ЛeKS޹JKdY?w q,WEtt{Ի ! F4a4Hg@Yڵ!'}U/;>ኙw^xnMYQZ~[N;Sz<]~CׄΔRk6GTZPu>IiXFYtЏ5Z^ڗ|ӼI@JU4qV,V3Uw@ ٦ܻB ̖7(Q/]Z nZp?1(݇H7ܛNN v4OSS"plq#vTWޘϫl#ɠTLs"'h0l!r l# rN$3QTZJ@KF 5?(n,&N)I~]Ui/f.i~[+8 8 u]w=ڍkĥ$ݬAFʲl ,L>jP$fh[Jyg0:P5& ֌RZ@'dLӁe:-bEcZo'$ B u_ GOY0կ-ʼv?pXUS`/M|@U^am,\|{p`+1b_=3q&a@+{$t&m"uhv i㏵(vWhҊͣΎ׈[6(M+ZX |xy(rAܞ$b#Hʧ`B:<**q/. x،%؃gpSa_m~]kno_}) Q]?RU5^%{ 0F׫d`Fzl F]ڋn~ ,4F#~3|CT]ktM{}!دe]( S̐]~-k~/abktƮ6+0?H8Fws=Z WZX2zkt$=x\WRh-~b`w=9n:]vU67iIENDB`Ext/Icons_04_CB/Finals/plockbw-r.png0000664000000000000000000003443210062567250016073 0ustar rootrootPNG  IHDR\rf pHYs   MiCCPPhotoshop ICC profilexڝSwX>eVBl"#Ya@Ņ VHUĂ H(gAZU\8ܧ}zy&j9R<:OHɽH gyx~t?op.$P&W " R.TSd ly|B" I>ةآ(G$@`UR,@".Y2GvX@`B, 8C L0ҿ_pH˕͗K3w!lBa)f "#HL 8?flŢko">!N_puk[Vh]3 Z zy8@P< %b0>3o~@zq@qanvRB1n#Dž)4\,XP"MyRD!ɕ2 w ONl~Xv@~- g42y@+͗\LD*A aD@ $<B AT:18 \p` Aa!:b""aH4 Q"rBj]H#-r9\@ 2G1Qu@Ơst4]k=Kut}c1fa\E`X&cX5V5cX7va$^lGXLXC%#W 1'"O%zxb:XF&!!%^'_H$ɒN !%2I IkHH-S>iL&m O:ňL $RJ5e?2BQͩ:ZImvP/S4u%͛Cˤ-Кigih/t ݃EЗkw Hb(k{/LӗT02goUX**|:V~TUsU?y TU^V}FUP թU6RwRPQ__c FHTc!2eXBrV,kMb[Lvv/{LSCsfffqƱ9ٜJ! {--?-jf~7zھbrup@,:m:u 6Qu>cy Gm7046l18c̐ckihhI'&g5x>fob4ekVyVV׬I\,mWlPW :˶vm))Sn1 9a%m;t;|rtuvlp4éĩWggs5KvSmnz˕ҵܭm=}M.]=AXq㝧/^v^Y^O&0m[{`:>=e>>z"=#~~~;yN`k5/ >B Yroc3g,Z0&L~oL̶Gli})*2.QStqt,֬Yg񏩌;jrvgjlRlc웸xEt$ =sl3Ttcܢ˞w|/%ҟ3gAMA|Q cHRMz%u0`:o_F.7IDATxyxUtI aIL@HXBP@Xb؂2:2:YQ^<*sՋSGLHXTKBHH'$$M:Iw;}~t [UWuWW}?SSէ`НW4(D` @V,U_uj@ xH@g3p@s͂  `(4 0fgp @1|@<׭{:_%T_FѲhp@CE `_GX.aԃyvu>"7Χh '˖-6UWۭ\L3xYS]Uj_"SC4b|;YxWҭ\¥&da|TWX_o\넑 @tu` ch&`q<^وn:thOhr}8GkpXٹ1-Kocd 7ޝte!55zG޿bnIH㶳 f5&x3c"P%w=>>1HJ 26Gx1K{:u̚:(R 'Sec%%'m2242> f 8 qCyy_۝lРی$C elw4ʱ x-8vB,euw㿋lZ]4cOM \rɵ蕗G@//;Gv㇍zbPЉJGc2lcl5q3]%jM]U C- u5]wKf +:JMB|Njd[vvvb?-I\О%̧&_*KFƘ(ȣm<.+*:؜9njx15|A/x]*񧧧X.ƌM'tHnLh %6|UpbaR}ۦƩ99BB"Hp,/oHc)5Pp` IT8z%驦ש9OH1HrcnjܜJ%zחOD E- vk'%U` |ݦ& `T߽YY]O㲱{&N!cK p6ȫt֞7MjS=pr\,g@c|KJJ=~{N1zmQZZbhhh@ss|$%%!55iiiHIIѨ x|ɕ~[f}Ey_wrX{ zC}Qҋ7аNQ~YY݋Bjrш dff"++ ɚvi⪷]_Bl8/q{_VGEnn.P]]{'$$ ''ӦMÈ#4/`eYc?oM}}#GGkaٳgi&l޼uuu}^za̙5k ێ#GZ2Lu/36kU}+dKBgߺu_zt̙3sP(Ĺ>TR" 8n j+={%Ծ wYY>3|~·z(5b4Wk#/2ƚi_Uu8ſqF|8w\<PWWٌOӽOhmu#.!՗Hqx;x^m#'Ơ|<3?fΞO _6UZ~"E,^Wʕ+V؈+Wb0NC" wZ|wVOw]~mۿzj;M'VvL@Ezr9^30xO}hK/tŪ}Gl6&ͦ)Bq}ľ L>dsd<ʯ}Y}<&%%Ֆ9K{(DFFO< #h7v`г5 ȟһ >kiwu' M5]oS q\x-*Y{15k4!́5kh:EWU}b gx-]xw7yIڵkj*M Z k׮@ ޱ<q _?u]uVX,>nݪ CV.O=9/S^SkU>|neok£U;СCx7P\\ - bѪvk'Sw_fH ' __SS0GZf͚?%%iiiHMM~bYHLLTcu5ӎރym-$5rmz%ƨ"|'صk_,dff"##FOƴZ(**Baa!݋2=ۮ]E> aۖuw͘+?qܷ<583»b$==cQk׮ҥKvʈ#0m4 !!TWW#//8z_8,[ S -lǏgYhHi>M4]tEEPmߑ#Gd Y0sLKTuuuؼy36mڄgi|r9R&lvE$Rׯ9A( 8WbDEw ֭Ν+V駟-~O?+VeR[mmm72+^s%Q֝]1W}شiGy=#== g}&kM0tP/!=>*;{|EA$95ǀp7D}n_ƙ3gdGvv6}Q7Nr|(((ěo4 4\1:dtaߵͬ6l O .~… 1}tqlذZ K>?oYl+מOd欬ۻ9ƍex'ѿ'uƍ~鑕5kllXxנ {PlǏCkkk͛e#11=X@B崴4A^~GLE^+_#77Wϟɓ'M|Y'lٲfYcxsyM-`vs1Zջzn߾%#G+K8<òM9x o߮( SlHĺ^4Ug6e[|PQtDDD,oݺUQtzL̞Շ y1>T{梨H̙3g*7Ϝ9s̑%"YR>+wƓymjOll95uP_fPod̮I> 5* 1Ov]Hve{8pb1{lY޿ߗP%։;N;xfԔ޽ܹS|srr✽999AUJw)b[dr4D}wn 򕊈̙319s,vBaa& o]dYV%7|v .yw}7M40m4}ݒk۱{nD Ia"0^P!vdGޖdY!3f]y̘111VPP*M7r;[3xJfM$V}߾}(//<;cǎ ;v,-//Ǿ}4$NnӍkV0S8mANػw,_9e(k 5ro;gN^>E`лƚ|Ox(eر~J'$Wk?hO,}xXNW<Ǐ4ѣG˶9rGI.EIo#T _\\,h9 XS=^n/A[*F'OJNӜt:E 5r˖(fjpƍ (>Z l#Fw\{fB!"(^4: ͵gϸ0ӧ%ok $(Fsy_9BF_QQSNI5WyͧNBEEPf23G5[޻oǀkKJJp8$˯_~5)<;huaxokb\Z'4jKKK%oذa֜DGGcذa~7@Fw5 @bDd'V ٳVKnHcW1ڋEu3|=kth3$ʤk`i 9}',J O?r;wN4oR&|9m- N~W3ABsG~v4)2de9Է |txQ3/ @xd 5 MHc*8N9*5oR 23G xdBoGLJ¶$ 4H0h $%%) :=^_1c CuJ;NL&KMM`м Jd\9  @ GwB]]@H_uuu9>ߵ+FI zf… 旜Lʗ,~W@hXd};㿆 bR8yRRRq/u* 2Ph=BR|=ړ/A(B5/fFt"'1rMpBoD=è B9/Fq:O4Pr,F !$D=##=TBt׉1 r,L}^+[Da4iy 69Ϣ9@N" By 5]6u HpmFZIԩSg$ҹSPmv6G  BaB ݠ N=T#` 8JAGMPpBsr[Hb#`mu㡒&%-4I=4A(]h@p\Ltqm8M\.'iM&&vMEM*T6V!)Z[ZB4 f@5*jPu٬`~eBS란Rms6â`r/o W զY@Pn'w+ދy4 d(pT 6+ h5d@T.Q@ b]MMUth 9A(hFTFP*C&~RHʓ'Of`n;ydwC8/.qAHL*&P!4r ^+:9O8JEOGu4#^Y: "x\X-"Ru4&Ps;# v+,<$0OPЛV! Y𚇾_0VH.ϗiO@*`P 9%Ǎ`D@`n|F)zDs 1.$ #t(1ڛ 9Y[( `k,F{ qe@-LԛPr:|T`-DP{e>3gj{tX? blDo_\"o ͭPeG\1? @b!&1k8,4׏> '$"a^4(WHڨ@п-'H3m_y:ZL~RXY?矯kՁ!/D\k<$.g Ti(.3}d7171WW[E!#u5b5vUM_hz7EDr}xs;El5m&3a3{" @MjHcf `,-9 "SZ»@H0ͪ( nhf^dM0t/trf1OTZr6TyfOE~kT71p5FqR@ۛبD&רlІL, JΜyqMΜ>f64`bhABӸl,}T}zG{c=EH0 y:R(n'ɽðy " C_٤i5_!BXLw=$Vub?clq3jW)fe$Y|sHiIXP?оf@h)/vwsAAX53G~= =P+*jbKUa@"NńIӫiTPffY93} ^k CkTIxq߼mfTKujC^޿Ǐ+2*k| !Y`<=@PGR2Ɩ@7x[lk ܃N"Tr%:5c5R"CbxMg cobK&>+L` Ŧpg}D{ 7}?$G&@P{(L~'&~7N! a]I)`b}KcS@-宨}g<7:E>|#;m@Ζl>f+ X]+**^YNA"H"{{e⪊ Sټ{~1&0޳ʘk?Bx-쫿K]2@֔pEd0H2jtv4Bh@\m8\ӒuO{XH){ Jb>F٩CEBJPn'Ν.%C.V/0>Ac<> @4ɃGGUu iQg:Q+j?GdgLPkδvG~cMކ#Fl|Jh])H2쯫rwg k=!w6|iC}DLN X t{h: !:ϋz2iI~pḗ ̗|?{ zZEHHw5lz"[2(8 E,E^}ӬAξ)%q1c55<}W1,"ɷe |i޹鲄_.6LoL'hԺKVHU:oC` IBM G\b!i#ךN{ϾoɸcK,;M|&>ian{5 ⶙5J(~'_2 %FW8K"!ܒWNX*]Y9}8J&WoT Q ,/U{e}{őwc'-a5`w'u:7ûYT2,;{\yӥvrPpYS]i{vvfuEm&?Ȕ2]ۿ0g>>+EZ5{r/Ong]Ԉz `Ƙ7%FJTsԑ>:(o_!\Y7nI ,^v>6V/}* -~Ql@2JkSc8D(szV9& 2yh p݆ 3D c!#ei~dW<.9򏍍19=w߁\Xg2% aaQn!mu7<`*O®mk/E}n'8=:% Ǯm7* kn*4 (PJ7s`RsȐTӟ^|Ɛ1rx=""BBBr;`n'sfkv_X,:r/oɒ ~%c̬K ;'M{0 642..йstHx1Dt!t!N݌yr9nikkk~8n8wdxnԂ6@D ty/: 0 3P&xnKANYTa/8AA|@"J+ǷT$dJ!Q)&BE" M섷W @ Ef \{wT$d_08c$Q\ dj$h0 @gE +Z"dZ"pbU[|_Pi{@݂ww7Sd@ @/Cdwh<߆? Yy@<9͢;1t @'N5T66Xt=:K^5~EZIENDB`Ext/Icons_04_CB/Finals/plock-grn.ico0000664000000000000000000006117610063245330016053 0ustar rootroot 00h ( 00 h^"00 %'  nM h^(0`pppppppwwwwwwwwwwwwwwwwwwwwwwwwwppppppppwwwwwwwwwwwwwwwwwppwpppppppp( @pppwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwpppppwwppp( pwwwwwwwwwwwwwppppwwpp(0`        '!%+45616884!9 9":$<$ ;%!=&%=)+<-O&P!P&Q(#A(&B+(@,)D-&I-(L/ R*"S,#T,$U.,G0-M3/M5&V0)V2)X2+Y4-Z6/\84T:1]9a-e. b-#d0$d1'f4(g5'j5)h6.c8,j90c:0e:3c<4d=5h>5l?)z:>]C=aC:gB=dD7j@5m@;hC;nD=nF1~AFFFQQQYYYChIDrLIuQGzPPXXz]fffyyy$9,?'>4C5E7G8GL=L:N,E-F.H/I1J3L4M5N7P9Q=U@N@OEQHSBPESFTIUKXMYT\BRCSFVMZIXL[N\Q]Q]BUFW@W@XBYD[F]H^H^YaU`UaWdZe\g^icmTcUdUeUg\iJ`LbMdOeQfUh\mShTi^pfpbpdqkuozp{iuctfvmyo{jyt~rUjWlYn[p]q`satdvbvdwj{eyg{h{hzi|l~xnπ}lj|ɉnЀpтr҄uцuԆwՈy֊{،}ٍڐčˏϕ̛Ցېܒޔ֚ޙڝX aYbW`Y Hyyxwwwwrrpc#ayyyxwwwwrrpseX Ŀyyyxwwswrwspea Tyyywwwwrrrrs# yyyywwwwrrsc* yyyww&G>yyyw2 RByyyⱛnmmmhhhfhffoyy)GŠ>y)QƊC)QȊC긞Ϯ||nnnmhh2E2E)E\)((((( i[[[[GHGDm^ȫG̀n2+ [ԉ8ڤ T \] [(PP  P :Ϡ _λJ a ҷX!׷b _رS Y` WbYa X( @         # #$%')'(,-566897$9 ;"<#<$ 5$!>&'6)AB C!D"E$F%H'R)X*"C( I($J+%K,&L.(N/-E1)N00L5+P2,P2.Q4&Y0([2*\4-^6._81Q74U:9W=!b. i/)n7.e90f:1g<5d>3h=5i? v29fA6j@8kB:lC=iE)y9/}??eFKDDD@YD@nHDmKJSMVnnn(:7F;I?M?N*B2K6O;SBNDQMY@W@XE\\dR`WeXg\iKaLbQeQfYlZm_qanfpksoxbsctWlXm^rdwn}eylpȋq҃r҄vцy֊ڏېېۓޕۖ,2,RWVTJGA?;::82X]E=664*%%$3:8a`( :9ea(!!!#I!!!::ge06K?;jg0!!!ZYVtrqpP `]ZYntrqoQ/ea`]R2-ntsqomkjgee[,2,(0` %F;;;F ;;; --- 3cVV 'F gwq҃oЁlj}h{fydwbu`s]q[pYnWlUjShQfOeMcKaI_G^E\CZBY@W>V ;;;:gBvԇsӅq҃oЁmj}h{fydwbu`s]r[pYnWlUjShQfOeMcKaI_G^E\CZAY@W>VV'!>&!>& =%=%<$<$;#;";":!V=T;S9R8P6Oޕݓܑڏ-N3        5m@`t^r\pFV           'j5@X>V=T;S9R8PޕݓܑdqVaT`S_Q]P\N[MYKXJVHUFTUebv`t^rUh>LV=U;S9Rޕݓ(D-4h>dxbv`tHX'f4D[BY@X>V=U;Sޕ)E.6i?gzexbvJY(g5F]D[BY@X?V=U*E.7j@i|gzexL[)h6H^F]D[BY@X?Vmy_j^i\g[fYeWdVbTaS_Q^P\^nk~i|gz^pFTESCQBP@O?M=L;K:I9H7GBUI`H^F]D[BY@X/M5                         -l9LbJ`H^F]D[BY,G0,j9MdLbJ`H^F]D[,G1-j9PeNcLbJ`H^F]ItP(@,'@+'?+&?*%>*%>)$=)$=(#=("<'"<'!<&!;% ;%:$:$:#9#9"8"8!8 7 7 7669GRgPeNdLbJ`H^cmFqMEpLDpKFvOאܒې}َ{،y֊wՈtԆr҄pтnπl~i|gzcv5l?0c:/c9.b8=KXmVkTiRgPeNdLbJ`PXrݔܒڐ}َ{،y֊wՈtԆr҄pтnπl~i|[l/e9ZoXmVkTiRgPeNdLbkuR[ߖݔܒې}َ{،y֊wՈtԆr҄pтnЀl~EQ@N\qZoXmVkTiRgPfNdѓ.L3ߖݔܒې}َ{،y֊wՈuԆr҄pтnπ(L/Ug_s\qZoXmVkTiRgPf) גߖݔܒې}َ{،y׊wՈuԆr҄k| bvau_s]qZoXmVkTiRgChIXaߖݔܒې}َ{،y׊wՈuԆMY+U3excwau_s\qZoXmVkTix2"ߖݔܒې}َ{،y׊vԇ5"N\g{eycwau_s]qZoXmVk%fpߖݔܒې~َ{،\ih{j|gzeycwau_s]qZoXmV].ޙߖޔܒې{Ջ2!;nDnЀlj}hzeycwau_s]qZoJvRߖޔܒGzP izpтnЀlj}g{eycwau_s]qZbdnߖ_jAtJuԆs҅pтnЁlj}h{eycwau_s&9)=aC}lj{Ȉ=dD,vчwՈuԆsӄpуnЁlj}h{fycwauϕ!  kz|،y׊wՉuԆsӅqуnЁlj}h{eycwč  iuې~ڎ|؍y׊wՉuԇsӅqуnЁlj}h{fyȏo{ޔܒې~ڎ|،z׋wՈuԇsӅqуoЁlj}dv̛ڝ>]C4T:}ˋߖޔܒې~ڏ|؍z׊w։uԇsӅqуoЁlUdXz]֚us}q|pzozΏߖޔܒې~ڏ|؍z׋w։uԇsӅqуoЁ4d=;;;  ߖޔܓې~ڏ|؍z׋wՉuԇsӅeu F+<-ߖޔܓۑ~ڏ|؍z׋wՉiy2F;;;  Xz]̛ߖޔܒۑ{ԋdq;hC  --- ;;; F;;;F( @ :777:\\:,LYcudw`t]qZoWlTiQfNdKaH_E\BZ@W=U;S8Q6O4M2K0I,D v2 #:-ònπj}gzdwat]rZoWlTiQfNdKaH_E\BZ@W=U;S8Q6O4M2K0I.H+E #777UauԆq҃nπk}gzdwat]rZoWlTiQfNdKaH_E\BZ@W=U;S8Q6O4M2K0I.H v2u΅x։uԆq҃ev'L.&L-%K,$J+"I*!I) H(G'F&F%E$D#D"C!B BAA i/4M2K0I,Eڏ{،x։uԆcsA6O4M2K0Iܒڏ{،x։k{"?'!>& =&=%<$<#;":!: 9 98776655!b.9Q6O4M2Kޕܒڏ{،l|)))(('')ZoWlJ\%%$$ $ # #X*;S9Q6O4Mޕܒڏl{^q[oJ\C =U;S9Q6OޕܒuɄ/R5.Q4-Q3+P2*O1)N0(N/'N/au^rRe!J) I(H'G&G%F$E#)n7@X=U;S9QޕtĂ  dwauQc        R)CZ@X>U;SuÃhzexRcD#F]CZ@X>UҎ?jG>iFk~h{]n._8-^6+]5*\4([2'Z1%Y03}AI_F]CZ@X{LjI'LbI_F]CZ}ȊG&OdLbI_F]ٗKwRIvQGuOFtNDsLBrKAqI?pH=oFQe1]91]91]9/;S6OޕJS>KYl@X;SMV1]91]91]9BN_q1]91]91]9F]@X?eF%LbF]ȋ0N56[=an\iWeR`;vG3?NRgLb.I3ݕېy֊r҄1]9ZmXmRg\dfpߖېvц  3ey_sXm  +ۖߖ@nHMYley_sks"&?++I0y֊sӅlfyox*@-%:)DmKۓېz׋sӅct:::@YDߖۑp(J.:::Ext/Icons_04_CB/Finals/plockbw.png0000664000000000000000000003717210063241544015634 0ustar rootrootPNG  IHDR\rf pHYs   MiCCPPhotoshop ICC profilexڝSwX>eVBl"#Ya@Ņ VHUĂ H(gAZU\8ܧ}zy&j9R<:OHɽH gyx~t?op.$P&W " R.TSd ly|B" I>ةآ(G$@`UR,@".Y2GvX@`B, 8C L0ҿ_pH˕͗K3w!lBa)f "#HL 8?flŢko">!N_puk[Vh]3 Z zy8@P< %b0>3o~@zq@qanvRB1n#Dž)4\,XP"MyRD!ɕ2 w ONl~Xv@~- g42y@+͗\LD*A aD@ $<B AT:18 \p` Aa!:b""aH4 Q"rBj]H#-r9\@ 2G1Qu@Ơst4]k=Kut}c1fa\E`X&cX5V5cX7va$^lGXLXC%#W 1'"O%zxb:XF&!!%^'_H$ɒN !%2I IkHH-S>iL&m O:ňL $RJ5e?2BQͩ:ZImvP/S4u%͛Cˤ-Кigih/t ݃EЗkw Hb(k{/LӗT02goUX**|:V~TUsU?y TU^V}FUP թU6RwRPQ__c FHTc!2eXBrV,kMb[Lvv/{LSCsfffqƱ9ٜJ! {--?-jf~7zھbrup@,:m:u 6Qu>cy Gm7046l18c̐ckihhI'&g5x>fob4ekVyVV׬I\,mWlPW :˶vm))Sn1 9a%m;t;|rtuvlp4éĩWggs5KvSmnz˕ҵܭm=}M.]=AXq㝧/^v^Y^O&0m[{`:>=e>>z"=#~~~;yN`k5/ >B Yroc3g,Z0&L~oL̶Gli})*2.QStqt,֬Yg񏩌;jrvgjlRlc웸xEt$ =sl3Ttcܢ˞w|/%ҟ3gAMA|Q cHRMz%u0`:o_F3IDATxw|TU?w27H! I$$C("]PH[UEJDTD:w)$ˤg'̜sur;Iu!33G/C@+PçJ>P(PB]`p'P@ .[! 7B>D @?[5d @9di(RB 8P0w `)c8 &5 sL!8 @5 ~j.D / `*fS5YP`RsRc` 0le2}3Bj1s-#FM|ݰAAJww73l9^R*P:hhkkEKK SQU]+Ҧ\$xʕ}IvA2K@"_` Q}$$87¶H;go1m͍fnΜټy{cnn9v ">M3  OD}lEsu SX]m;u2Q|.4*^"νU0B3=kWZKcѷbv1ʕOv!˄nl`خ`stMŤw1uDy*l@O2="q/otqqQoܸ~ֽݼyǃg95J#N\u&"1VJA@ `زTcuN^I#DXZ)Δ}bP8/+#mذF3Y4TcD3k*1VA,p7S0l ݻ6OehPWcKY_ `=cMZMNж47,yJ `X+?HVNgfhJىt&0kR ܞ0K[GeE.i*ũuqhqf =p?=}`v6>]DS}1>[T)OdX@1qu\vz.1'rwlY@#/0GYCN]biuIIfҟbX^e#˵sa030ltnÆ)Vn JpY?;vQ }V3N@>6c$6iij*PW|A h χz}ĈKzI+zܴ]O;<\VP"eG}3EEiT>D#(4i>EuRuNXX?S_0#>@1@{׮}$<6P}&HN+ ~UR^(0D)g⇫22Nx ^$DZbck{̝g /aћ|{FCMCu>{嗥8Zv Zao{noնWt&mlS2! 0֘rݫ4iI*$$Λ GxIt"n8. `˗Vk.SfKௌno8snj)z)>hgdܐ CgqS= 1) @WvY\/)uUq>0Gl*+@rnCaU8X~b{ qczR~:;1ۅeS0k׾I=nv*Թpv '_Q(ُF@TB0_'ߪuvG=M'07}!mn:[~\\\SܯtD3AYBS}?|dkKLw(ǖMDfl`ZVDiEKOmP!2< юmbbb0l0dB7\sWT; ~ GqqǦkltW\-[СCEkk+t:]x!* t///hBؠN6n!Tlyt7 `sC!&ӧOcHKKCiiYv?Fe˖aѴr@( bnA'/ ux @o!?Ol)M ---r 6l؀x\x fہBzz:jjj޽{CTtwpJ~V`V'.m|^QL^g g111LL:)J$z=#q:2@`gN4p@I/Ν;TZ@yy9qŅ9 2PEðw)?,[TJB||<㑑VkP^^lhZޞ-66Ws#+N`6_ 6BJm$_TTO>6mBNN/^+Tz=***6ё$N; [o7 1(bI]7nDmmm|[1<ӇR#:g01:AщDeNNnZ'tKJ|z5Zݾsۑ77754 :`Pk?׮6n,rϘvA^D_8!Wf  ѧl?Y^4_@+;H%=TM6|2֮]/^ڵk-V<wŔiU"Fvf_=㊊yf=zwtRRlق2zq-uuPg@ a"d i4$''c߾}]rhiiw}SNH3a5Hx EA>JBs{I0%%EP]]5kW_ư@$+]Nz+o tՕ&_Ő!Co߾ppp@CC T\v 555f)@---hii^'mḸ:)({Idڵk3bܸq3gBCCOOOڊ #==åKnMOU9OpM=(2|Euرcٚ5kXVV:^rlȐ!=V"J%>T%_+!Ф%[tvG\{hKDa0p@WFZZT"̎#F̼*$-}Æ l YYYo/ٳg VXx1^z%fǐBuE@P __ɞEqqs{'Nxq̙z&̎BuY@PHݣd"[#..f舅 "&&$uUn:*zN˓?>%-qqq&#7 vvvm***-T*1sLDFFR~tt4&MBAGuNZ[HVaJ%ۙ}b=ӧK]Xmz Y{IV᪪*6DFFWׯHG6cRwDDFFUӧlPlDL`SXZ- '''YݝE ( i%q9˾Lgkk+4 vWJw[L$yyVٮ H i YVA[Z$ 颛 ?]cF MuEYHumd3HW\\,٭(--%#̂jQH\Uuda{WWWvݼySkƪKGUj٨ hH/lC9tFFj ^^7ofRY oH~W~~>e@ W3n :AѲOKv~[6-HWQQ#G$0 .^(T7k+L+RnhZ$%% LsfYWJ& ZسgtII vMfI\($R`akk+[477cϞ=HHH&ڵ :/a6ԫDV@۷ ?'O`(//'#̆RU,S*ϾU 5>7| o jii֭[OEb[ x+ۙ)s> z0gΜ;#\̘1 W^ERRmۆk׮888v( 477@U($mee6PP lnnwN_J@u^ Q1m/zļMK~ҥKٶmإKXii)kkkE4 +**bΝc7ndcfDݍnOOOY%ux{{ޖ5,UPv0}-(- ` uup1>>>8q"_zuLII JJJ`>L0"nmЖ4V7E| 7 J$ &]ݑ޽{cȐ!=9bt1>}.EEcРAԓBtt45DĹ41j$}bɲqssäIIуa-jl޹K-"뭎 dz6J!SL+'N4V. ?JϵVVT0)}SPw?é1z8Ebt0yt<)K):)zԩ ^ !)tS,"'@ZڿS7}׋ }WE^C|Z.$4^dzgE B/..:w>EO]J)B1ڄ BwmPhVdH=Kw:BT4; :Z;^ЉT~:*LrrvQ޺IIE j`8sWt Zp5I-, Ǯ"n _̉=7~1UL AM(<( 9Aυ ޘȭŖ[Xz :oºy]gDpÊ415I;Â#7z2qX8XDM-6׶SU^x1;'L˞$R?tM{(إ^`/x Q;LxT]'ݧ@X+1`5Ɣ3e|޽ Zm})I#aRګ ͖KCgu=F$a$+񛶷VT&&>\mSF낅y4X3&/m+d!'WٓO_ ɲ _ۨf=XYzI)! )ɱ( W|[)ǫ_ձ7G)BBA Od3?Vm^h clLzd+ޔO`t% & }?YVXIT?coɨCqy R5k">ޤi(")&DQWPߐS-2Ɗ7L4i̊ԳzB:@Tr˴ r+$n~Ҥ  m]ă'-;~u&~e^*TF)YW_[~+3tЋ`/xʉCz}s5I<cLW_$ PIu^}^> ;}4uEIic{h-^V"]~ÎL);*lPՕ ҄6UL~}Ȁ!*?2yHaWlʽJZC(~W[#^6uX*]@::9w #6An%+ojw}0;}=V. GH,6vAud)w-~^D7?ԕ__mS_{fU%: KEcWϱ>JLˠEt<(O?Λy50|h 5J='2a&Ï[dɹv7_kJhT5s/εr/k3Tz?<tPV]#>?z;\Ne,Ԍg J1>{lF.6'm۸IkτNsmF`ƴ]ʮ_d>^ngP'w?4Bdg O>rޛ|C!!P8( TȻq _>y_ۚ'U>)cB<_YX~3E;3J)N  όyTL;yXE_~7gO "@h}Ϸ2ܻEƞc(d8x#IgUOƎPgLޙlԡ('g?DWa;/c,XܥO#M .Wq\C*\:x)ŔոK_2ƚ,\cCEX'ﮨCl#5\2u /?(\{ԥ(.?wuQU| kXF7k2l:e|[G=?M?Wp/g'\7y6%ȩk|UM~nzWZ;=o|; Ȇ[`1PIgW-?up~ޜ78ޖ5h,Ca<̤z?M E|fNu Y?:z@ vn^l]V[jRSj)޶e.u~ng`߈nX`ӷopܘ9FD 9V꟮ :աTU2t/k'%4Jr9xq|;c5=@vHl0Ӓ6l԰vCچ(<\.prm 0 -466zUK2oi.\jɾq"Iv_ ;K`X'JV}FHXfA! [w8HAD ] 0\БFA+pA 5!~DMB\ê4$p&5c0,p 3 $D@S2j2/x#:y=h>0 Sm\pO*2=i(-*yc{ n\8p`YXeð@3 G^+aHC@ uM0"YbIENDB`Ext/Icons_04_CB/Finals/plock.ico0000664000000000000000000006117610063242724015273 0ustar rootroot 00h ( 00 h^"00 %'  nM h^(0`pwwpwpxpp~p~pxp~p~~pp~~~pp~~~p~pp~~pp~p~p~pppxpwxwpppp??( @pwwpxxppp~p~~~ppppppppwwwwwwwppp~p~ppppwwpwwpp??( pwww~ppwpw~pwwwp~xwp~pwwwp(0`       +,+#""&1" .#3"3$8!!!!$$$-%#2&"3($:*$:,'0.-5.,50.;1.655<30><<N)W-M+ M, Q-!O6-R1%R4)M92G=:MA<zC/{E3{G5|K:BBBOIGREARHE_MFSMJWPMXQOTSRXUSjK@cPImmmtttF1H3H4Q>S:V>]>^>R@RAVEXG[LZEYD_Q]B_AaNaSbUdWfZi_h]k[m]aFcIaFhRu]k`pfvnrfxtxr}w}z}x}g|eiGlKhCy\lBnEoFpGqIsLtMvPxRzT|W}Y~p]̀ftǍxŐ}Ӕ`abdfikmpqtvyz|~ÑÔ͔ڜןŞ읁쟄ۡ¢åܦԩݬ襎䀹ﬕﮘﳞêʭ̴ر۵ֽؼ⶧뷥ṫļ¶°óijijŵŵǸɹʽʼ̾H< Dz{|{/m" F{P*'# d{{*odg1{K)h3e1uH5¾\f1H<C6 6\f13<n!G8O ee 7O qA! kkkbjjYbYYYYVVUTTTMMO;<EGľ4<*p(IEqE I**H< "*$".%"*'%0%!1*'=*#=,&1-+2.-20/>3/210444?62V,@)"@,%V/!E1)V0#V1$W4'X6*Y8-C95C;9A??Y;0Y<2Z>4p<+p>-A@?J@=Z@7VE?[B:[E>sA/j@1pA0tC2BBBDBBIDBZG@]TQ]WU^XV^ZYuSGk\W|d\bbbdddogdyolyqnzspztrF/G0M3O6W>[;]=\N\GbOcTj\t^u]qfxnyblJoNnImHpL_mCmEoGpGqIsLuMvPxRzT|W}Ylu~u]܇i~`abdfikmpqtvxz}~֚ß읁쟄ܡŧȦ复颉릎䀹ﬕﮘϭ޸ֿܼļźʿ±ijǷƵǸɹ˼̾P& &PP.@8.P)^l}xvtrrjXD*f}xvvrrpn\D`}xvvrrrnnV |}xvvrrrnn\D}}vvrrrnn\Dd}xvrrrnnV'}}xvvrppnP}vvvrrr\P3ľz]}xvvrrrN,}Z((irXPҕLc @grkP&"'b@hvv& H{ xv+ Sݽ" }v@T г }B JMGGG>><<775500B0 &#=Ļ&PFĻlPQ;Ļ_D̖ľ*PľyPDľ*ĻaDĻD Ļ eDDҡ'DDΔ3P&JTTK#PP& &P??(   ,(,5-!> 5 9!6)%1,+1,,210<30943965@*"@-&B62B95H>:g6&DCBUF@SLIigfhhh}ibumjD,S6U8^AdUk^`@gPnXnaujwq|toFoGrKpHsLtMuPxRzU}Y\чmp`abefjkmtvx~~읁֭䤍쥌朗䀹ﬕ⹪±ŵ˼̾   M*=972$ M 'HEC?9720#M,YVHEC?9722#Ma\TVJECA>823 NS&)% iVR;A 6h!]9 o/  = t"c_\XRJEB PtK.fdc_\YVJ+ xvtpmidca\YVMLxvtpmkdca^,M Lxvtpmkfc- MQvtpnOM  (0` %\\qqQ0%zF4T<^C\AQ8yB.P, \\\{1 P>x[_[}X{VySwQuOtLrJqIhFD.0\\\{-M4+t\jfca^[}Y{VyTwQvOtMrKqIpGoF\=K)͸-S8("{dspmjgda^\~Y{VzTxQvOtMsKqIpGnEmD\=6񁁁Sqqqn `Q~zwspmjgdb_\~Y|WzTxRvPuMsKqIpGnFmDmDF0 qqqnqqqn!sퟄ윁}zwtqnkheb_]~Z|WzUxRwPuNsLrJpGoFmDlB]=qqqnS.#ڜ읁~{xtqnkheb`]~Z|X{UySwPuNsLrJpHoFmDlCgB,S-!ۡ望읂~{xurolifc`]Z}X{UySwQvNtLrJqHoFnElCgB񸸸- Ôﭖ䀘잂|yurolifc`^[}X{VySwQuOtMrJqHoFnEmC^> \\\{ndﮗ䀘잃|yvsplifda^[}Y{VyTxQvOtMsKqIoGnEmCF1\\\{9/,ﮘﬔ잃윀}zvspmjgda^\~Y|WzTxRvPtMsKqIpGnEnF6􉉉ﯘﬔퟄ윀}zwtpmjgdb_\~Z|WzTxRwPuNsLqIpGnF]>PC?Ĵ°ﳞןŐ}͔襎ퟄ읁~zwtqnkheb_]~Z|WzUyRwPuNsLrJpHoFK*q¢ǸŴ±뷥rf2&"jK@Ӕ읁~{xuqnkheb`]Z}X{UySwQuNtLrJpH^@q3,*Ϳʻȸŵԩ3($ m]읂{xurolifc`][}X{VySwQuNtLrJqJ0wqͿ˼ٲ k[잂|yvrolifca^aFW-vOtMrKE0\ؼʽ?41 Ǎx힃윀|yvhR++S1%gdaaGO)xRvOtMkJ\ N80祝쟃윀}zaM2jgdcIO*zTxRvPuOVNKG=:J<7&ڝ쟄윁}bO1njheKN*|WzTxRvPP."ws -%#ṫǷcPI,|XzUySzD2ֽ;ʻǸ⶧ +Z}X{UT=˶ʭͿʼǸ+^[}XaFŽ~Ϳ۵+a^[bH β¶MA<+da^XB}zSLI,&$ i_k`j_h]g[eYdWbUaS_Q]O\M[KYIXGVFUDSBR@Q>ZEgdb{J9WSQ_MFﬕ晴ퟄ읁}zwtqnkheQ3( TNLذŴ±ﭕ朗ퟅ읁~{xtqnki\1., ʻǸŴ±ﭖ朗읂~{xuròe\OIG!Ϳ˼ȸŵòﭖ䀘잂|yurUD432TMK 930}w˼ȹƶòﮗ䀹잃|yw1"q˽ɹƶóﮗﬔ쟃윀}|fqRQP̽ɺƷijﬔퟄ읁M7/̾ɺǷĴ°ﬕ朗o<::̾ʻǷŴ±ﭖ朗8*%􉉉\\\{Ϳʻȸŵ±ﭖ䀘fY\\\{ Ϳ˼ȹŵòÑ -"""˼ȹƶòܦ!񸸸-S0//˽ɺƶijݬ.%"Sqqqn"""̽ɺǷĴŞ!qqqnqqqn ̾ʻǷtl qqqnS<;;å:2/񁁁S-RQQêPFC͸-\\\{433ļ|w3.,\\\{ WTS~{xWPN qq\\????( @ YYCCC%-U0#p>,p<+U. -CCC% WWW?(![F_\}XzUwQuNrJmHL2=!WWW %<)"xanjea]}YzUxQuNsKpHnE[;:%1 bS~xsojfb^~Y{VxRuOsKqHnFmDE. 껻1%  t잃~ytpkgb^~Z{VySvOsLqIoFmCZ:  %  }望쟄~zuplgc_[|WySvPtLqIoFmDZ: WWWpe䀘ퟄzvqlhd_[|WyTwPtMrJoGmDF/WWWCCC%=2.ﬔ윀{vrmid`\}XzTwQuMrJpGnE:CCC%ßܡ֚릎읁|wrniea\}XzUxQuNrKpH]=B84ɹŴu0%!\N颉읂}xsnjea]~Y{UxRuNsKpH="YͿɺ|d\E1)颉잂}xtokfb^W>V-V,nIsLN5YʿuSG잃~yu] :"gcsA/lJvOpL0,*?63.%" 复쟄t^!lgtC2oNySvP-\SPȦǷ~ |XzTU/"yolļ1*'̽Ƿ  \}Xp?.yqn źϭ a]pA0]WU*'%*$"k\WZG@[F?[E=[C;[B9Z@7Z?5Z=4Y<2Y;0Y9.Y8,X6*j@1faV3&1/.VE?°ﮗ잂~ytokf.IDB ޸ƶ±ﮘ朗쟃~yup܇iYogdJ@=ܼ˼Ƿò䀘ퟄzuaNYCAAֿ˽Ǹó䀹윀{?+$̽ȸijﬕkCCC%@>>̾ȹŴﭕ<+%CCC%WWWͿɺŵﭖi[WWW  ʻƶ±  % ʻƶ± %1 ˼Ƿwm  껻1%@?>ŧ>51% WWWCBBB:8WWW CCC%10/]YXztrzsp\VT1-,CCC%YY??(  @0 11 0 WWW>( gP`}YxQrKS6<WWW 988dU~tkb~ZxRsLoFD,976 WWWna䀘ulc[yStMoGE,WWW0@40䤍윀wme\zUuNpH<0֭6)%(p읂xof]^A`@U8 <30 쥌쟃чmg:!g6&uP 50/}ib⹪}X1521 H>:|t-#-"- -,,8!a1 umjUF@±朗~tj SLIwq˼ò䀹nX0BA@̾Ĵﬕ>+$0WWWͿŵk^WWW :::Ƿuj988 WWWBAA@73WWW 0 532521 0Ext/Icons_04_CB/Finals/plock-bw.png0000664000000000000000000002220210062626050015673 0ustar rootrootPNG  IHDR\rf pHYs   MiCCPPhotoshop ICC profilexڝSwX>eVBl"#Ya@Ņ VHUĂ H(gAZU\8ܧ}zy&j9R<:OHɽH gyx~t?op.$P&W " R.TSd ly|B" I>ةآ(G$@`UR,@".Y2GvX@`B, 8C L0ҿ_pH˕͗K3w!lBa)f "#HL 8?flŢko">!N_puk[Vh]3 Z zy8@P< %b0>3o~@zq@qanvRB1n#Dž)4\,XP"MyRD!ɕ2 w ONl~Xv@~- g42y@+͗\LD*A aD@ $<B AT:18 \p` Aa!:b""aH4 Q"rBj]H#-r9\@ 2G1Qu@Ơst4]k=Kut}c1fa\E`X&cX5V5cX7va$^lGXLXC%#W 1'"O%zxb:XF&!!%^'_H$ɒN !%2I IkHH-S>iL&m O:ňL $RJ5e?2BQͩ:ZImvP/S4u%͛Cˤ-Кigih/t ݃EЗkw Hb(k{/LӗT02goUX**|:V~TUsU?y TU^V}FUP թU6RwRPQ__c FHTc!2eXBrV,kMb[Lvv/{LSCsfffqƱ9ٜJ! {--?-jf~7zھbrup@,:m:u 6Qu>cy Gm7046l18c̐ckihhI'&g5x>fob4ekVyVV׬I\,mWlPW :˶vm))Sn1 9a%m;t;|rtuvlp4éĩWggs5KvSmnz˕ҵܭm=}M.]=AXq㝧/^v^Y^O&0m[{`:>=e>>z"=#~~~;yN`k5/ >B Yroc3g,Z0&L~oL̶Gli})*2.QStqt,֬Yg񏩌;jrvgjlRlc웸xEt$ =sl3Ttcܢ˞w|/%ҟ3gAMA|Q cHRMz%u0`:o_FIDATxyXUeduT}%'*>Y`iiSڢSYSN:Fiq4qI0SqHC+ * \?~#sݾ'}}/HBX$ICd ivH`q@N1P Iҳ N_j&I<ؿD-w.$Iz\=ؗD `%v$(lHpf@Dh"]%ONH аODJ0@@T"ztGip?KD8JH3DVѩqƫO|DV8U N~"  '?󆀆yCEW?' ^C (o4^_+o>F  =LJqa7M1Ȅ 5(vjk}+hx6xvxb޼'NhӦ 4Zb@\u p><[Wu~{1x n^pk$mWr8ldAcUm8@O6nDprkߣ O',)E[f k4>һ >w +'>9s@n 9_j*Ѱ ߁wPy]Q> G0B_ڳR0и*%>Aխm7v:U(:]VWpB;&'G O M{xn1I*l@7,o/FG>у |]{0?][x#4+o~N~Vp {d?xGnZ^{eoRu6 =6GYCɵDE.d~;q hJߕe 䡑jkBL;j0WdiǍH9sv~?o!"x>i^4Q !48ÏHf z>=B*qH!G6!$vBr@yCj)0=Dr5HaFЎDʓ-GwT0oʒenps{=cBTTTؽ{7ped2AWk4xꩧ0`"88y@´C\JfB,K/PѦM!G>$IC1BYFza0I N[&O5ExϿ[X=nݺe3ѩ_mhi3ɘ{U`0p)|oQSScӟsx70c tЁ(#sy6"`!ĆxL"!!A IrڟA 6eG/?= $m&j/^uqܹ/_m17 f̘#Gw)--ŪUSOoAmm-;B͛=!ٌ|̛70 qI̚5 W\Kn@nx駑p߯ ,7o%W?˰@2=!t";;!'mXl^z%vzkj[\ŗ̙m۶ o& ;{yyիAX{@ꫯpBPSS۷_FAAXt,wƍGv}OiӦ NA`[y zzIIIx뭷O?AL6 `cp ɄdL>l&L5cKNNF\\w1~x޽ E@_bԩw^l 1T׿/a} >|ӧOGnn.`߄orJ.hDJJ .]gϲAXht:_WFyy9`t:^{5?f?$I/()}|r&> òepifJҥ q-\x6@y-lݺHHHP1;v착ZcƌB !0 `0$^*/^,"""hs?/9du։8F 8P,_\>}Z\t;޼yS\pAڵKꋌD^\\\0fkN= r2SRR[x1&Nm?CU* yȑ#kKo>s3,glٲEZ-,Y!C8\;.XƍSk׮aŊq02yyy(..VS4t QQQCVU[nѣݯpP媽oOөm„ 2e*uݸq< `_RWdd$U;Onݺa„ e6tRdggs 3ZԩSGGu6 GLL*ueeezTTTROTT}~S\uqiUڵS/BCCUyO?U2.L&$%%D}Q;Uv*w|8yE0(,,t]vPZ@@ڶmnFddUUU0 z^w뽭M}F#t:S7oV.~!**}:t'@u9 ;(**Rc"..}3gddd8 ;\|uuun0tjoyf؁fCH7N(}YgϞNƝ~TɄ'O*~>8}t= ...;w.z!Et=F#l٢%~ݝ $!""֓Ldee)Օ^39{,.^pfB+ $IBBB PUU崯g4 w:t(:vni P %hZ⋊/h9ɓ'cذa2`PthZKw9tY:F#Yz֭[o777Etp#%%E[5 Ցo^W gT]]'N(v}U# ADDb!771%IhxqnGnlvu t&E< rb "9#Gr{F]]WI6ׯ_իW8"׍yҘ" 1@D "bD "1D "1@D "bq-F-HV}^"{D5~f|-l;FNNӽ`0`\5g<88Νe#::)ەۂ@D "bD "1@D "bD ")¡suu`uN4...N`pmysK0"bZΡ۶mZxxx8]Ԡ[n8y"F,Lд!R8 ڐ?|n^:%K9?GT{''CWT M%T^;D t@vhe+K#1!"R{li ‚!",n7 ^`S=}{p ɞ"Y;9T*GqeBkrxJwgN"ɈR?$WbC_F$' ?YdR Fw\ ̗si9i?@Cr>u ?#Aޱ7ryHQ4`5t4,PqtzNz_bM`,]EVӥ`/.V'tYG'vIfboڲ+>(w1ǥ;q=yܩE{>+7\^J/v!cB@Ӯ'{9;]s^Bm'jL ɅNd2[iW/}l.F:a{>}гpӪ??KyoS% B- HOl|>""õ(ru&Y,Xt?wF; ^ !#Jϣ(fø9Ԫ6Ixsx`;^j}ڄi ]48rnp)9{nJƔլ^BĢΡNhϖ!9 G8Ȧ6P_Uʲ+xx^vIjaa /xi鞀o,l{ou "ZtW`LCA&k!@ߒr V׵I xA]W4; =%4K d`^O9J4`-("( nZ2y{1"' `;C { pAа窦{[4,Db4g}K巧-4l422ȎEIv~cZ$h!28 BdZiteIENDB`Ext/Icons_04_CB/Finals/plock-blu.ico0000664000000000000000000006117610063243454016054 0ustar rootroot 00h ( 00 h^"00 %'  nM h^(0`pp~p~pppp~p~wwwwwwwwwwwwwp~~p~~~興p~~p~~~興p~pp~wwwwwwwwwwwwww~wwp~~~~~ppxp~p~ppx~pppp( @ppp~wwwwwwwwwwwwwwwwwwwww~wwwwwww~wwwwwwwwwwww~pppppwwp~pp( pwffffn~ww~p~ww~~wff`npppp~wpp(0`         " :$,!3 4%<%=/$H H H HE"I I%E&I&E*I(I+I,M-m)n-n/w'n0n2n4A,#E.!A,$F1$M2$N7)N8)W3![4"U;+Y:)n6 g8$n9"o;$o<&o>(|>%GB9\A1o@+oA,|@'~D+H/bL;lL8~M8|U>FFFQQQYYYpT@~U@}YBfffyyy/0034798=>!?BF,L3N6S9E"I&N,M*Q-Q0R0T1Y6Z;]:Z4a?b=CIIHJLNQRTT'_8\0U U!X#Z&])_,`6a-c0e2g4i5k9l9n<p=[C[A]@dKhLjRnRpVdDdCkJgEgBiGlKpO|]tSuRxV|[yfqGqFwMwSxT[{QsE|Or@tBwEyGzH|J~LejpDŽ_O^][SQTWZY]ȊeΉdԉaԐiĕrۛrcdaddcdeililntsspΡ}Ҥ|zuqtvx{|~ګֿ⯇峋řȜ͡ЫѦԩح۱N TOUMSOK|||zzyyu`, T2|||zzyyywtN|||zzyyywt T Q|||zyyyyw, ||||yyyy`7 X|yyyyv(V||zyyy(V|||zyy֓EEE@@@@@@;@;;;;;+;*******))a|||zzK(($((######h#^|||z4FqV|||4Fq[|||: bq ]|䬛rrrjjjhgggffff~|4G[6Gs\4Hs\ƥrnnnmmmjjii9  _5_6_R3333242$2$$$$$$$#######hRRLGFFFlũFom97 ѾPљ<ۣc ePJI Cū K TӽNB2UQOSMUOT N( @          " 05 0 0 1+1119%:)?(=80I I [ [ [!I!I#I%I'I(J*J,[#[%]&\'\(R-\+\,\.\0`*o,y,t5I8+\2 ]4"^7%^8&S<-[;)^:(^<+Z>-`4!t9"u=%^A0\F6wF.uF0uI2vK5vM7vO9vP;FFF}\F}_Immm12;6>$@&B(D*F-N.J1N5R9U=[>G%Q.^>GHHJLNPRU X#Z&])f>e:e9`,c0f3i6m:p=YA]EfJjLqWiIkHxY{\tTmBnDoBzNsAtAwEzH}L`jqtفWXY_PPTX^\ًbފ`ޔjڔl×tۛs؛tڝuj`dddhkhlorpppwstwx|{|۫묂츏ėřɞ̡Ϥҧҧԩ׬ٮٱ۱ݳݴNQ~wwvuussnmmkkihfUNwwvutssnmkkkihhdQwwvutssmnkkkihhU;93322020---***** Skhhe kkhh))))&&&&&&&Rkkkir6nkkkr*nnkk@@??9?9;2200---Tnnnm5tnnm-ttnnMLKKKHHGDDDD777autts4vuts0wvuuzzzy___^]]]ZZZZXXVbxwvu={&[wwvP@pwwō w@/Fcƞ@8 |`Ⱥ zEȎȎ Ƚ}POOQNQN(     $$ % 1 :> >%:>/">#:#:%?&;'>.#A K V @ ](`&E0$D4(N:,S6'Y7'Y7(U<-o@*fE2oO;zM5wU?}R:DDD]SEnnn;?=E)N5N2S4W9C H%L)Q.V4Z9U1ENRX#])c0i6p=^CaGrWcCkGqMvS|XsKo@wHxIwE~L~P^fkWXT\؟xfcdilklsty~z|ĘʞΨϤԩٮ*,*!VXQPCBA@?>=<,[\L:98765.-/=<b`1>=gb'$$$0M$$$$?>hgD3N @?ihE$$$4R$$$$A@ki& BAlkZ#%KJIH2;CBmlkgb`\$RPComlFSgb^XQPpomjeg)GYXQqpomT  ^\YXnqpomU)eb`\W,+nqpomlkihgb["*,*(0` %F;;;F ;;; ---  ~M8wSYTQO~L{JyGwEtBr@p=n;l9i6g4e2c/a-_+])['Y%W#V!TRQONLKI?w';;;FA,#^^\YVTQO~L{JyGwEtBr@p=n;l9i6g4e2c0a-_+])['Y%X#V!TRQONLKIHC:F cca^\YVTQO~L{JyGwEtBr@p=n;l9i6g4e2c0a-_+])['Y%X#V!T RQONLKJHC;;;T@ifca^\YVTQO~L{JyGwEuBr@p=n;l9i6g4e2c0a-_+])['Y%W#V!TRQONLKIHw'ψdkifca^\YVTQO~L{JyGwEtBr@p=n;k9i6g4e2c0a-_+])['Y%X#V!TRQONLKJ?snkifdaW3!0QONLKIsqnkifdM-/RQONLKvsqnkifM.0T RQONLxvsqnki]@oB-oA,o@+o?)o>(o='o<&o;$n:#n9"n8!n6 n5n4n3n2n1n0n/n.n-n-n,m+m*m)m(BV!T RQON{xvspnkN6I,I+I+I*I)I(I(I'I&I&I%Q0yGwEtB`6I!I I HIHHH H H H =X#V!TRQO}{xvsqnM0"~@'|JyGwEZ33Y%X#V!T RQ}{xvsqM1"~B(~M{JyG[54['Y%X#V!T R}{xvsY:)           G,O~M{J_88])['Y%X#V"T ~{xv[nMlLkJiHgFfDdCbAa?_=]!j7h4f2c0a._,N7)=!l9j7h4e2c0a.N8)?"n;l9j7h4e2c0ė•~[DF2%F1%F1$F0#F/"F/"F.!E. E- E,E+E+E*E)E)E(E'E'E&E%E%E$E#E#E"E!E!N,p>n;l9j7h5e2ƚė•|\}XA|W@|U>YAuvsqnligda_\YWSF,{@'{?&{=$R0wEuCr@p>nnn;l9ˠʞȜƚė•T:+~{yvsqnligda_[4"qF~M|JyHwEuCs@p>n<̠͢ʞȜƚʕ,! z~{yvtqnligd] $ QO~M|JyHwEuCs@p>Ϥ͢ˠʞȜƚʖpT@nR~{yvtqnligdDg8$TRO~M|JzHwEuCs@ѦϤ̠͢ʞȜƚʖĕr7'~{yvtqnli>&gBWURO~M|JyHwEuCӨѦϤ΢̠ʞȜƚʖ'_~{yvtqouR  YZWURO~M|JzHwEԩӨѦϤ̠͢ʞȜƚʖjR2$~{yvto:%L3_\ZWTRP~M|JzH֫ԩӨѦϤ̠͢ʞȜƚĘ ]E~{yv[A \b_\ZWURP~M|J׭֫ԩӨѦϤ̠͢ʞȜƚĘpV}^~{xVS9gda_\ZWURO~Mٯ׭֫ԩӨѦϤ̠͢ʞȜƚ=/$iL9ڜtܚqoM83 iigdb_\ZWUROڰٮ׭֫թӨѦϤ΢̠ʞȜƚګ% ԉaoligdb_\ZWURܱڰٮح֫ԪӨѦϤ΢̠ʞȜƚΡ} DŽ_tqoligdb_]ZWUܱܳڰٮح֫ԪӨѦϤ̠͢ʞȜƚҤ  ͋eyvtqoljgdb_]Z[ֿݳܱڰٮ׭֫ԩӨѦϤ΢̠ʞȜƚ峋bL;\A1t~{ywtqoljgdb_\xTyf޴ݳܱڰٮ׭֫ԪӨѦϤ΢̠ʞȜƚĘ⯇pmkihz~|yvtqoljgdb_~M9;;;Ы޴ݳܱڰٮ׭֫ԪӨѦϤ̠͢ʞȜƚʖ~{yvtqoligd_ FGB9ѫ޴ݳܱ۰ٮح֫ԪӨѦϤ΢̠ʞȜƚʖ~{yvtqoljdA,$F;;;yfֿ۳ܱڰٯح֫ԪӨѦϤ΢̠ʞȜƚʖ~|yvtsψeU@  --- ;;; F;;;F( @ :777:\\:9$iIYTP~LzHwEsAp=m:i6f3c0`,])Z&W#U RPNKH65 :9&d`\XTP~LzHwEsAp=m:i6f3c0`,])Z&X#U RPNKJG5 777tTgc`\XTP~LzIwEsAp=m:i6f3c0`,])Z&X#U RPNLJ6pkgdX\4"\2 \1\0\.\-\,\+\)\(\'[&[$[#["[![ [ 2PNLHsokgفW[ RPNLwsol_J,J+J*J)J(I'I&I%I$I#I"I!I III I I 1U RPN{wsoߋa11111103zHwEe90 0 0 0 0 00y,X#U RP{wsًb}LzIe:["Z&X#U!R{wj^<+^;)^:(^8&^7%^6#^4"`4!P~LoB]-],]+])](]']&;])Z&X#U!{ޔj     " TPmB    o,`-])Z&X#ڔlXTnD[&c0`-])Z&wvP;vO9vM7vK5uJ3uH1uF0wF.\XzNu>&u<%t:#t9!t7t5t4G%f3c0`-]*ۛs`*j7g3c0`-ڝu\)m:j7f3c0ė묂^F\DZBX@V>U$Q.p>m:j7f3ǛĘS<-fJwsplhd`\XI(N.wEtAp>m:j7ɞǛĘ^GZ>-{wsplhd`[ f>{IwEtAp>m:̡ʞǛĘj |{wtplhdkHP~M{IwEtBp>Ϥ̡ʞǛĘ xY{wtplh^9&R-TQ~M{IwEtBҧϤ̡ʞǛĘ\F6:*{wtp݊`^>XUQ~M{IwEԩҧϤ͡ʞǛĘ×tyZ{wt[;) ^\XTQ~M{I׬ԩҧϤ͡ʞǛĘI8+ ؛t{jL[>d`\YUQ~Mٮ׬ԩҧϤ͡ʞǛ۫  ^F`^A0?(khd`\YUQ۱ٮ׬ԪҧϤ͡ʞǛq +jplhd`\YUٱ۱ٮ׬ԪҧϤ͡ʞǛt ;)rxtplhd`\Zݳ۱ٮ׬ԩҧϤ͡ʞǛ츏qW}_I}]G}\F{\{xtplhd`jJ777=80ݴݳ۱ٮ׬ԪҧϤ͡ʞǛĘ{xtplhe9$:>80ٱ۱ٯ׬ԪҧϤ͡ʞǛĘ|xtpuU9&:\\:777:(  @:::Y7'WT~LwEp=i6c0])X#RNEV :::fcsKZ9V4Q.L)H%C ?;=NEskN5%% $ $ $ $$$,RN{szM5o@*o@*o@*E)o@o@*o@*o@*o@*X#R{^C* $) S4wH)))$])X#aGo@*o@*o@*W9~Po@*o@*o@*o@*c0])oO;&j7c0Ę؟xU<-fE2|XvSqMkGN2@ U1p>j7ʞĘN:, zsldo@*xIwEp>ϤʞĘrW^{ti >#T~MwEԩϤʞ /"~{}R:cC\U~MٮԩϤʞf%E0$S6'ld\UΨٮԩϤʞkD4(>.#wU?ytldX:::]SEΨٮԪϤʞĘ|tfY7(:::Ext/Icons_04_CB/Finals/Untitled.ico0000664000000000000000000005600610063304670015746 0ustar rootroot (n00 >h00 %N!  F hW( @??A??( y9(0`   %-'";#3$4&6>T/>H]L`M`>M:H9GESBOUcJVWcOZT^[cdi]az   ! "&$'+).*(":'#;#;51H=R:N>S@U9I1?6DM`Ob;HEQFRUaOZVaQ[V`W`\e\_y^a{eh]_qZ\m_armmmjjjeee\\\MMMMMMMMMMMMMB; GMMM= AJMM #$(*))((%HMM7!%')))))))))))))&NMM!$))))))))))))))))))'" IM@%)))))))))))))))))))))(EM()))))))))))))))))))))))))"EM))))))))))))).)))))))))$IM)))))))1)))))))))$ M)))))).)))))))K2)))))))))))))M)))))))0)))))))L))))))0)))))))))$FM))))))0))))))))))) M)))))'0)))))).)))))&M))))))60))))))):)))))!M/))))(60))))))))))))#CM)))))"$)))))))1))))(M))))))$))))))))))))M)))))(8$)))))))))))) M)))))%$))))))))))))M)))))"$))))))) ))))%M))))) 8$)))))))9))))%M))))) *)))))))))))%M)))))"*))))))) ))))%)))))M)))))"*)))))))4))))(?.))))(*)))))))>)))))#M)))))) -*))))))))))))M)))))'*)))))))>))))))))))))$*)))))))>)))))))))))))))))))*)))))3)))))))))))0>+*))))),5))))))))$>> ))))))).)))))))->>>>8$)))))))).)))))))*"$)))))))).)))))))))(%# %$'))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))5)))))))))))))))))))1)1))))))))))))))))))))))))????8x?~<8????( @  %-'";#3$4&6>T/>H]L`M`>M:H9GESBOUcJVWcOZT^[cdi]az   ! "&$'+).*(":'#;#;51H=R:N>S@U9I1?6DM`Ob;HEQFRUaOZVaQ[V`W`\e\_y^a{eh]_qZ\m_armmmjjjeee\\\MMMMMMMD=AGKDD- "%%%GMD+$)))))))'!HF()))))))))))))G6)))))))))))))))'J))))))))))))))))))EG)))))))41))))))! J.))))):))))))*GG)))))))3)))))))#J)))))3))))))))GJ)))))/0))))))))))"G.))))0)))))/:))))$7J))))*0))))).))))'G)))))%0))))). ))))J)))))"0))))).9))))G)))))0))))).))))J)))))%>0))))).))));G))))&,)))).))))D)))))!,))))).1))))*)))))&*))))).1))),6)))))))))).3))))D1)))))))).0))))))))))))8+&)))))5D))))))) !"$)))))),D)))))))))))))))))))))))))))))))))))))1)))))))))))))1))))))))):)))))????(   %-'";#3$4&6>T/>H]L`M`>M:H9GESBOUcJVWcOZT^[cdi]az   ! "&$'+).*(":'#;#;51H=R:N>S@U9I1?6DM`Ob;HEQFRUaOZVaQ[V`W`\e\_y^a{eh]_qZ\m_armmmjjjeee\\\JJGGJG0% =LJG'))))%GG)))$$))$K))),))#JG))$,))'CJ.)$,.$)G))$,).$)>G)),).$)))),.)G))).)))))$$"$)))))))))))))))ǁ!a(0` %"(-/.+% "6MdtzmYA+ .P 1HOHS6D-<'6D=JIR59[b>  *TNV>K"2GR'*Aj>EOX"2  "&)*..-))$ CO'*A^, %FLy.< $+.............' HRv=)Q[ &..................+ !-<&)?E(GS$-.....................) '37WE"GT)......................... !'37W= P]-.............P.@.p............&'&)?w. \h-.........`..0.........&-<bQY]!:........`. ........%FQE 8N........%p....... 27Wr$ [k.......0'.......-6DD ZdV.......p0'.........&37Xh BW.....+0'........... CO/`jQ.....+ @0'............''F Re..... 0'.............. >Do^ ":....)p0'.........@..... "ISnmz|..... !0`&.............)=J|%^o.....`&.........p.....6D,K^....)`&.........0..... /CW....$`&............. /..... !`&........8N....$,.....  `&........CW....$|%.....  `*........BW....$6Dn..... !0 `*........9O....$>K^.....$p `*........ ..... JTF .....) `*........kxf..... DJy/.....-@ `*........ap.....'g.@..... ! `*........9O....)DPA .....)p `*........cp͈..... "37U"......  *........AV.....9HA .0.....+*........(p.....'8=^......&*....... !-.....R^,.0.............*.....7K@ ...........' `*.....":?Fy|.........&0` -......Yf". ........ p@P&.......Te(.0........* ! &-.......Oa).0..........)$ "   $&+.........Pa%. ..........................]l.........................0 . .....................`. .................`.0.p..........P.????8x?~<8??( @  "#!.F^nvwseR;#6^EKzJT>K6D6D6DGRHP(+CsJ%  '%'Ck'.....'*.......016\T.E....2DN.P............06J....-OX$...........0`'.....EW7 .@.......- P@p '.....-D,0R_.......-%    !&.......U_....................\iϼ.................!:_m״.P..............BVYbX ..p............@.0.p......`. ? <x?(  @ *.+ FmnG %MTBQ0$ >KeVBl"#Ya@Ņ VHUĂ H(gAZU\8ܧ}zy&j9R<:OHɽH gyx~t?op.$P&W " R.TSd ly|B" I>ةآ(G$@`UR,@".Y2GvX@`B, 8C L0ҿ_pH˕͗K3w!lBa)f "#HL 8?flŢko">!N_puk[Vh]3 Z zy8@P< %b0>3o~@zq@qanvRB1n#Dž)4\,XP"MyRD!ɕ2 w ONl~Xv@~- g42y@+͗\LD*A aD@ $<B AT:18 \p` Aa!:b""aH4 Q"rBj]H#-r9\@ 2G1Qu@Ơst4]k=Kut}c1fa\E`X&cX5V5cX7va$^lGXLXC%#W 1'"O%zxb:XF&!!%^'_H$ɒN !%2I IkHH-S>iL&m O:ňL $RJ5e?2BQͩ:ZImvP/S4u%͛Cˤ-Кigih/t ݃EЗkw Hb(k{/LӗT02goUX**|:V~TUsU?y TU^V}FUP թU6RwRPQ__c FHTc!2eXBrV,kMb[Lvv/{LSCsfffqƱ9ٜJ! {--?-jf~7zھbrup@,:m:u 6Qu>cy Gm7046l18c̐ckihhI'&g5x>fob4ekVyVV׬I\,mWlPW :˶vm))Sn1 9a%m;t;|rtuvlp4éĩWggs5KvSmnz˕ҵܭm=}M.]=AXq㝧/^v^Y^O&0m[{`:>=e>>z"=#~~~;yN`k5/ >B Yroc3g,Z0&L~oL̶Gli})*2.QStqt,֬Yg񏩌;jrvgjlRlc웸xEt$ =sl3Ttcܢ˞w|/%ҟ3gAMA|Q cHRMz%u0`:o_F}]IDATx{eWU%<歪*;@^AyJ bJ۾~v ڟ~4OO!4`@A $@ʳ=s^s9w%sPgܺs^k9s swef8:'tMj3; |3_ vLo`f/r8|J.x }3; #w~ͯ}] M`7\0S>k~}^!=xͯ5E6٫4#k~ͯ_wx]?ZL5^9_`fϙF97]WN ȋ,<LZ?^I0b~ͯ5Ojn8z Z^U ?7OXo5 0k~A~h~ͯo?1Pt` Q<)O)9 [ڎ}`ߑpa ` ߧN~w?ܚ^Mnڿ}Zw=c=)!~O{_q1{>{7ܚ~p|~ۺ{uA|{/<} cΛqW^*܂_w2މU?K~v#C=Զe0xXmƅ6|ONd\ˢ@a(Fw,~v {+Mw4P4L6p!UcƵl 9?S<}8*C@'o'6n,OBLJ;ge@8B {֡a-8mY~Åxq+^2LGz߅?SN .,b"K|]8@<N֜е ýt‰?=a=2#Njf> ɏ짱Ei-M-A7 ־G l9i~MQ+c:HƱqx3; O^C!V(YF&B{OC֡Hݗ-LJE@d]tc;K?g\Q,e݁7G?qmAe}gJ_mݺ]NCN>Vpz2lvkx{}2tA%kA]`0n`-2Kv#R]۷e)|^ p>ԝ"K'4'bLD+RR)bN>`s 2,gҋ.CZ3v3 `Cn ?Y&(;/7x/:<AD$f/)7 Wk '" aCZAl-݆!CeNY͔o{͆H:6AȊ _0.l ʋm8)$}4_Y5RR{))>m:K…x >^k[(ċDa`'=[훎v/vAv]ϲw꣟IHdvuCƳߤmI6'H>]LXHr㵥)jV9oSCRIm΍& T Y߂j5g_?FC9 e0-`T!@gAAƢʆ_fpj^ueZ}UBh݆rk)XKM<AB)! f;tJNjXsϽ#¹G'+FR &}}Q)UP~L5o>>t§̗qVI劧CmP:~HmЗp! >D*FOcYç{~3G 6F4fڈ(ak^{2EMv<#$߯ s$g&&ng41Fn:i?>SXFP%("1-\OTk_G'+ 8QG5p,,_6lFO9w %yn9jHno)j5.;SHK -DuvJ9d }F0}o}kXBFxaA_K6L]&ueN`m<4,}x`P>c9mZxv 6œ,GEڡgp3z,lŋ<`QƒE1Ih@Xt!w RF\OK(؊3Bɡ@N:#օ4=L.vuymG.. q 1{ lt( GPŶNÃ9 781YHkS`S*hd;r h.8QŁf:#~$^cľ[KBc&O&n0--8Dj<QIP*|,bYɢ3އXg#,} x&4^\/| c/`qܳ|ʏ`8&,l(Ԩ3S)>Od02} :#bgZDw(92ShESi`Ec x/I0ǝ;BY$d'Ĭci@$̓N&Mʤ~)Z2Vv/dQ\z\ɋ/˵a#w*)/lݶR9qIαC)QU8UOIL5J{wa=_GOp3u7G $]с6ш'AehKc-B S,25NJ= +|t:^/Oo^~\g 1O" QoTOi_)՗h]5zB q2vu?k>X=;q.ĵ 6mނPYqYAs&!4X<]$b'P>h :F0JHj.6΅#qek6:1\ci3C7hf~І" T)FcZY_x$ @aT8S/ u 5rS ~Xܷh׽wނq> l>|g C+bifIKҡ$*\'Cܜ#+N5xmASr,,b K=t9Hr)gAS=`\r^\;lSZOT/pފ]܁ok=GO_{6l2l|o:i,N=I 6(P5 dP'}qjL 6Gƙ Gu"QL(.3*HDI3b+WRJ#YG3QU bH`!:ZK"ֺ]kB,/-Z^^W½w܂'aӐBȔq6>x.d)@T2wA 1n'ҤeST#A`O'HtfAHsez>?~;,??#oe=Y,!ДP˴^AȎEiP:X/8I-+P]+d1dٴTB4.0IS/؏SZY"1EY@ԾnFIץOg-_5_30V|C@Q"(~auH&ӿvҐ]))+ u7]dnhq 7~׊) ;Xt=@oU`q@d].XbEڑvnjnvTa}^OqE#LJY<.|ʼP/ڃ.ӭ!ɽ 82  <5˙PP6JWgm-fB;#?&.ڽ,.Zϭ7\뮀w: t<蘓u Xڿwv#kK{Kێ?x+st#tXZy cb:sVR l5jps3YS[Kw Yea&C :O7x" ИW_@N}BD8@50)X%56pn6l9hsptl&Ix裟y69w>Ϛ8qYOES0߲+PZt9#{0勃'-ys>!fCnBm7ڃ3N{L|u9 \FV)'p1oY| ێ?MPX-$H3SdlcO{/cXܷa#p璟!8SG`!axpڸwphEٺDh Vy-IJ@S3 @֦ *8(>{.7_c>'>Qx_G| &A$@h6r߃3\| wL(|}cN~$9C6e:980\{CBC Q| Ť2=9,#~\waz K7, 28 53}ͻv܂_[Ϳqӡx߇ſl~[l址&mhms\HFb=ލOMt,񧝍V'?Hl4!y?z͇m!G/pR2g+q㛸{;Nijl9X"Ŭ[qgߗWbM-7%rؘ\ԃTC;. 0 K#QNŐ p$7Jӊ 8㑔AΈ>u1QOy_æ͇k5W]#H'J/ja qzԳdz_;زUwr5>_žwfב!3)x(\ʊ;eI۠-X'ZAP ,֔EJ0;ꕹd1gLfDbRć? o?4t FvVCZ+ܓ !{s4\%܌MlÞb5Vڷ.\Oož{w)>x* u YD,W:dl+VQcWS33 hX`ɄHݦгK֒ O7 3(|2TԽ >>7l܄o_řyLt{)'hauO6[ayRa/_?z_W^yͤ4^HW>AS'AHMLSvH't0ʠ^`d:܃4D}A؏oJDX|뮼d}?|LR-~2s3n ~s_SU7-ʋwr = lקSߋx1*0AM۠䒽v%H4d4J{|' Mz̛ 4 Dxq>ۗtlيoyspƒbROj&@/)_V6䳞mb7vm*U91R2ۣMzHod 3PZYdm1ρZl7 Vr:Z*\m:l:"Ռ1~ c6\=;jg? L6_^Unux8R-. փ-Eo^>p@+mw) " 7,H:bB `%^OӅ>g{ϱoUYGc  ws4ߥ7qK@Cvu.6`-`O™6lZ[o@Bf8l)r嬘RR59|Edd5^K$'yL33 Wms8N~d8hh0i!Nc,7laN}ijpȖʽuu1z.1mdieT_O.;r`s:L2DY |tw"xcO1g^ѶW=`gWpWZum]#i Rm}@ cǕF-^ll ų^FpV-Rdw)Cѯ.mJmĬr0jw\%2#k0KPsj؁xSF$2~Wl&AH7܎/^;?GwJ=>JF3\(+D3yKUӆ(Q-ǝz.6z]w݄?!,/-q:dÜ,3Xҳcb\JYziNNi;#@Iώz#հ8$c aeˮUY 𜗾'ܦ+N#

:sƓo R[P8,Ì| G=oUޝʋހ}*?G7-e(l」5,ɧ#р2|T x%νi%AT?dφkpm_^EkcO<'aC @uXXy>:Te>Rg]EԀ[?a^vǰ'8>Ge鱦NUx%jۈRuC KnpF@ ў@;7դu贀<wZt96\F(S}ϝ [S#ӾqDF\Yi-:PҚ[g[yS9/pyrUw/]ύ§v俳v43ћp40BeIϐO1AG6Hlued/r+G{a~v;߈}bu~~ae:KJz1 H_º>PEm'>_tyga51< i֑֮,ƕDЅZkH V"Иki roIUAa)zA{g+T:{uW`wbݺ&KYc2Y F҇N?]Ntv(?xqIg=mU7];w0 h#MB AGސ]` `!.۰/ՈZl k!UcI0Q.EY 6< ˸:wLNgB AOg Gfwv{ת,6<~LQw>~9,Q|y.QʊVNs[_U,/i8ENbtZ7 ̥hv !Dm3Q Uii~,0haX;2f +~oqC#@5T}E׬H f Wi-|' Шc" ӟ1S.PA$h&CA+?^{z&L4tT\7Y ym_J2 >8u=lx~6<;/~wY PIέDCsU-9X Ԍ QHB9<[ׅ2XFd C0bTr R2[o}]y8!.UeE^EsT۵pnEfx$q)[N,{t [7`ӡGo{٪z} WLEDf΃LlAvl¥HXPִ"D%x$A.qG ,߇/|buϊ/#:GwZHL2KLV2?+*|N3$mbɔ >ظiˊ绿z5Ÿ('iFjW*jX(:Q؆Mx3t+~oqeo#/<+P+zl0ѵ=„=k`1%ז `d:5AZ7%n{vk?=Wz:>{vD쉵V7,?aF5rSw Yy 8oǞy;pmp"7>p:ⰆR3uR.'OA?TTwfl7RՍ'ꭎέS5̧N G Aܒژ#lQ p\Eu/ʣ͇m#Gq6fGbms Mv&m-i䡁%}}ga!ciߋ{PnxC^K#c`E`Őۃ}`E`FA#ɾ.DAMLd.U2dn4m鯭[1YW^f x94uFZNL Ak-]o#Q:*;M~ڏ?k;7^F(ԓQ/>KN!;Rl< =Oݘ5f#~\q?A' 4a(D*|!Cy&|؀eB0:F[*+ϲ\tw$g ʰU0X ^)`zԩv+~w7\WI) d"K~|BQ=ԱX$Y`B ]M⌁c`T7_iG h6w T睌&/|_~zE†8䳰a!cm<ԞbQI!BS1pe#-D[5Mw")GndM>\Eu qm* tSKpHUb1u;5X q"9+,>{ 3?{҃ˍ5DmD/&fRtaƮiT&Bv̰<,g%r:y^1V߷{EIg<O(V6ؒ罸Gumϧ%֋g8A8!Oģ+z[®;G?ʸiM e`'uE;< :=ҘhfFj>* H*%V#á[sOHU#"`ċNCbYtyN~w`JNOF O<|Vjn9MF)OCi>ㅢ!<(`}P8`l$}"MhR)t'W\sۋ B̪>@6]Ġi6(+rT Jʙ#ß*l|Ċ>;n w.d'l@Y b;!q=ۻ"祫/blʀ T/D4LsbfVV Tk"sBp1 mq3lP@b5]wmVtZ0q:ijoL=NgV'Lar4lʪ2pQR"/Z9 :!)&!-mO@AӵW+*ey ήڧKWt{q`j f58] WfSbˊ,m2=&a&h>p)![pKI~>(3EfS3.ky~?X OxLgj`f)ҁ QYcQ-y*R:];mE۹Oa;o R63lJ; F^m!S7Jؒ-hژK@ #ʁ6tVcC3F_F'z?lظ暺 $ju!C-fZ ; + N HP~Y!:ży:6rc#L2<~>ۮ '=ܶҶ[6OQ7eT7`HوkwMA1BcQTU@M_ MjҝLϘeT1iݽ @ 6iLJ;CdE- [1 EpSِUi?QO"Jw ё ړ:j{\WܹƄPYFZjIveylV]̍lGEYulm'Î:mE!ed*r$j: T9 6z/j'N@@)<zPhE#kQ ܃]ZF'?r x3Gm?3 gDv PԲsFِ9#֞&]WN<pbu%,ŌS8'h|թm𙖳4 f#XgA 5Yj%aQon#bJdu?S~[ B-l1<f KjY5^@X;z1poo-l܂ھ\ez8Ld0.SɋqRc44#FEPֆ) ^%8/@}w"au5A,߻b Ca!I*R!% 'ДlUL=R*Tfu]d8h/q37+ܬf&P(yƀmG M\g(e`DF}p֋t1cy(f 8| 0v̸[)Ae@cU`yۭMA]\wDstMr%:];nHGASSOuusR|f%k+MbKq5@2VvJtfl9vm7Yvz~+xfڣa!2-JihҒ.&]-ù͊a` O=Fu ׳ er)zCW,yJkFMt'cUKW lj됺Hf2 <łLjv@}zK_zf5uA8t81Mq`B7\wZOz&:"M-.cgMVЖrz:(&ÂP2ԺuZGx>=D}tV\Dw!`C V:(RWyj钪S$Fn <-u;; }]O-TCu  u^3JhwR@)k (O"nfI_c_3h3`<.]ƌLY=L\sQ4=V%ew_+H9 tqu#K&&r t|b7ZÿN)Q-:@M,>z}vMcAECKqYiڀN"!i">mp'L2i~ͯ*uLS?'c2tAHr\?@Θ8Zi3$L s).HUĚZ@]|*`Hc#Y* Ɨ 60>r7TodTiRzb%e'jH K, ldyz>U -,SC̯b@%ֲ$8*ujn`] zUi,^Zn>5Q%?$hAD6È-QmyEYN`5Z:N6fl%hc`UuSicGpP+JKϖ7y.]σ3l~nq谨,4pz聋>,اG\XFB mǺ+=Ɂ~ V7|,0\([${.|Uvwu * 䰋txҝױ$C#>7=e@N$BJT2cM]0_!yd~bȮ9(:ԬO7iG7p.b3d ƧÖ4S ݊U|BPD%Z~8U;PF61=3=>w}t6~ȃorFjhFw>-EYIyٺAbtqwy 7h*jhu6nƶDN9'Q'Wlܟl<"%6R>%DUƦbH[5ې'\J˞E [zXjEgOwPp$#_|A Vd藮 ۉ#_Ƣ듔\q]\}}O& X"ޥNʩf ^aQ}leP fd9b HWr4Ul8i8$=ӘdiiޏڅW8s1=9mZeɴ66 GLFH,TA6לg}@@uE-\OzԀpdr#HWo\aMA@F;,:OGU } ,@_ǞNl5p¤LVrw!6ab ,fjM־iZ%|VQ (eө4ew3(S#t0ˀl5Dkv[S+0&Iw]`pv-u2M%O %`ܸmC1eM*ru6<ᘃt_7k4qFZ+A(hM%z:TE8R8X.hbTkU*'ZȞ1dPNy?1x:m" >!w(3d_ p72p1hiX&f9tݸ{EqwWztc Uy}nE.zIu1F& =hPh]J <(u{\r: -SP)' H-8.LHI2[jUwzT%|l<_6[a$FjLD#J @&M~ beՃsa&tˋXذ a.\daG6`xRxLm6;ĸ葉Yx: y8 E^8/z`ͧ4E A" mx" \AAB-ILy]f9B;{Fb09jZps|BDAX8'-JcD@ dS.gIc Eऑ{50g^^GW˘jSVSK]L1a|[>nXԎ ԧi[ON)'aBA ,iհ'U4DRS$P"%Mi^ATE]%Nj(W7hO҂M0H'"7Rs!jώTQ,O Ʌ =$TP 0ʢ Iohhrd>6Лy`{^c΁FNc8c0\7[xM?ӥ#4܈) 4iGKۏ\2*Ƕ1xY)8!nɸBeb r?W3TZվ4 )']HbFTg6]xoDL"acB~ovK631BZ _sf:TDȬ4 ,`PöLPI`ۍB> Y=O&k6bf[c.Jór,}ZFhX,߃lM)J?ol.q̷9?y)l!{`%~o>gbæT{|ŝx+vI\~kamivffܤ2o^y2Xܻ@`B64;!2}b2] X^uWs6 W%Ղ Qkl*>0ݙIjY㴓1CU_6@graΉIRA +.T택I_;![~5ag?2 mN{ݐk`;dF$u,cwexnw V yz `L|`'ft-> 5f`dCVJA&ѰUεeAGE۴7ÃlSڲY`Tn]PL= ˦&!?*없T6 kЮɖjN+Xqoe{X0ݏZ{] 6$usMT+lC_+V +TƉzm_b)7JC[C] 쇀#ub2IR&yewDi ," ԕֺZՓU[8F1X9sjRX _)ǣ$E Ks&]ѴƵ=_7 skTCH3+uQY]Jx% 2zk\ OFA,QFVӠP8UC?E-\9hԃٜ]q gqܱKYAYz 'GRȈf($M0^x Ӄ"Yދ8 ĪAUEޒr6mp-$BN։=>Z`p A5zz=IVJw旤FꝏS{Ӭpop_9dK *M~Xh{^ X\H_ U=_C/&LBg n3pC=N-%-$knxd`m!x2laCzx{:Ԋ1ީ,<6,B,[Wi6FsU $K`˶gla,Ȣ+~:LBEHUGvs}_4>oR.>wު ߾X>/?v'a|aA=fpBˋ fXx,Sbe挤{a^8iEBXSAӕ ,+!oD=ݠL-nE !c1:Dx'9R[M%[נiW^qOw,t\f[c_)p4^>etOaNIJ b X+B&& A\(qXX]4,DJ6Iq_ORRL{],ʹ{gW4+_PQK{J4L6J"JƼ3_ _i!42`]؃CS!W)+M3"F ( j[gq uuٍ NIo^0jc]Pz݆ZGaiV̈́waDV#67>TvJ s4H09Þ^JC!S. HuI=ohZ˴3$ZOCZ(4k.Bއ 6t̺jKū--o@xR=V. qh:XX#6 WŮYxL~ܯ> Mayn䞿^e ҎSa*8E-<prui?Zz|\?7'l ;qΞ~T( 'c&u/+M=.!-rrJiؼ 8V XᖑlCvX=:[dzbfp;RkZ Sݭ5d< u+*5)f^?uKF(y\%%g3>,vf TʍT+# 5X_p@aAibNOA q>FXpў0r0iĎF$mo~c_Mi)3ϯU GqOt15Ἇ=x06(E4\1L|7TFƘ;̯N =9q[fc4 JC>YLJL&f!4(0n-@a)<̯.& )@Fʔi<<i)墭|=$z7 7kVik~b+fVe^lRA\ b;9{S$)AԁmLMe~e#BUtk d"|h#ý|'٤qo&S5׭_\ Ea~wûF`5ޓ@#kS( 膍 '6ĒW3~`_+DvXHC2\ːKU:zґ0a{N 2`~7Ԃu`5/3Kjz5MhPEzhQ *#OX@<{+cj @i M4fƉLZk,d~dO0Ә{q6z]6N`e*yQT3GmT ?7 o~8?h͘|ּ](>#< t®KMNDX峑tvv@7|ϯU LW/==hF  4Z0)&4tLÒf˸d4G.,,z7!Lx abtlXm,F:_+LoL `k;u [pcw~8 HBdyᝫyvj,`_gJB䢰L, T$ 9Zx.>sV9n5K|ׂ1\'ϯUm9p?yY*H8ҟ"Κ+YzZ}ȖɠϠ^IB.[hϺMׯ}k`!x@?=8L?hTt;!Нvqpxi˻֛= ԑ\&y<\VAh,^r.h,%n`э8,P*D0LD-~Ť孇ɠ^Eok_\}ǃt6ˌuI*Tw(!f0 1K1B[.4rw7&ju1YʼnnyY'2AЉ*6X}&esfUȨ5ܭΩTtŌBmŽ.'-\84;Kۘ.fpв^4dQA7>[obnˬOַi!w='-twX;g f7#VDžL4 Sh)o?TiƩ%,~OJs$7bz笤sbb4 o)č&Q̀ IsE3 SxG%P['~ -;t9]+>i5$nb4istVɪӹx֮Krf˱,"u1yAu/.nuMSi@B%^LdR2 g hk7q@]'ES]I; RXr _3Ֆ+.=)FL^oEj ;eZL͙a-iD3Z9N":,u(Ӡ?}%= ` qr,vnbcy8Y"ݔS!,(z՘ǰֺҮi Ss_\L6QiHZ{v[f ؂k뛴=te2sV`<s͊`Xs Z=}j ,Z8qq%QKbO,ٵL. q?i=M* (z?`le,jz{>pdX{ͭtæQ cyrBG[8Vi90zoWZ۵3TS H7K_h+>s9Lyq<ZN)M.R١N9ﲪvtXjH ns]/<^ږC)ڨ}tȽGKPX6;NlE3,n | p]Z=")S&K7 hTO.M_a>8wK~103n ;VF!jܥ& (Ec^݈)<]HR>*oPDžZB˩L2֦eVctBm}6p pbfѮ FY:oLcQkkXK6F а gFjoRܼ!5뚘f>B>D#E{F`Ĕ.K;Pt<\<4,Ɲ,"⣋~P7vlZ=&YxVwUWNC6(=$6j6n掝YllQʵ4.O{fsޏ.OՋT3I#K*H0o896f4L-i&3qxH}O݀@Sk裘ʠÚ(+Z2.4}J< {i s&_1.9S;"K6~/fx=qv翃}^0$]f$f QIy{7MRq6Nlc|uKK/'>rF$6Uj;i˹caAlcz-`>.fi#%lR%Qd0NYSq&F | jh#|3;txw/杴KN54$T31bTl~# ¾I ֵfY|Aw&xl 1*a^:08Ѳض31aiiY@C &Us`d}w,`4@|Y%ǝIRz3fLϐP)Fv@f?̘Lm5 ~}y| v v5pi/ի>,Ѭw`usҴLst`z%k c`!˂긎taqgNDwӨy "MGK>#Vr70&0mIH! LETdy>__b{kMh$x 0]O!`H,I}|_?Y. -)^ 9Guɂ-<\{wfF4;ٕ|@aW7O$/B0$ip[@-p69fœ xE+ϋ Fls(s -G`-zeG/Xk9CҤ,aޟ2F vНt[fwMnp^+]ihŊ[Zj3w^sayG"h6_2 Abo3B؈W<>66NbgV<8lYE-P^;Mn4bUfv;AQnۼ2M3> vF, >`Sw"u{|eoTLCb=_ƱωBNYc[( t#|Ƞ">:liMjx 3QaqSKʈ"\`*LI:- d]h}95`^K6M+7qkl6heE d%psad;q[|. 6W|S&Jkʅ&$Dau`D%;L D!W8$=O㬑 e;b2k#%d¬bfA^PԹINok%rk|тt f28Ιtgk 7YZ38e"4i> cĬS ]) Я 6"WSE,XxOxJo >C% Lr'w"u#B:`Д_kRZL>N3A۫. >BA @qY孹L\y@ضfڎr// WXYUf xv5._`/^ WW]uQYl;9!>̆)?%ؔ>1KMPe!gs $8׎>ōbڑO FڋA4"uأ4h Eʷ[7쟣jN"fm+'+ Q-r`$_Zz?6~/.gI^V}wa3{7?wn8>êFXЗ֟ur]g˻xF|{);QK) tn.\;{1ԥQlQgZ!Z5;ΌYC?{, ͖mw D&Dc"}޾|-N.Ʈ/G.[u`+Z"{gՍfO2RmS`SQUJ*Ŵ Vsހ)h\4t1׵NɘEW$P,`*p:d11 B%'DM@>GOYV?Q$|9>ݗ.x )sh;z33x}&6l9774BFuJQvZ0")U?עvƋVl';Q#mMƠC66mhaQ彳ȅE> RRLhFCSr ,5v$az{-nq'F-^/Gc~ͯޯ;dd]Wm~nk~ͯl%A`~ͯo_*<̯M0k~}l7̃_>$&5_`}xaBk~/\ Ͽ@]Ř_0GOc:nlg=`2JkX!=5]o~Oabk~d^J>h +0 Z+1|cF z 8;WvabF u*b"4rc}~L:/ޱg.[7<u^OtK OOIENDB`Ext/Icons_04_CB/Finals/key-bw.png0000664000000000000000000002355210062625430015365 0ustar rootrootPNG  IHDR\rf pHYs   MiCCPPhotoshop ICC profilexڝSwX>eVBl"#Ya@Ņ VHUĂ H(gAZU\8ܧ}zy&j9R<:OHɽH gyx~t?op.$P&W " R.TSd ly|B" I>ةآ(G$@`UR,@".Y2GvX@`B, 8C L0ҿ_pH˕͗K3w!lBa)f "#HL 8?flŢko">!N_puk[Vh]3 Z zy8@P< %b0>3o~@zq@qanvRB1n#Dž)4\,XP"MyRD!ɕ2 w ONl~Xv@~- g42y@+͗\LD*A aD@ $<B AT:18 \p` Aa!:b""aH4 Q"rBj]H#-r9\@ 2G1Qu@Ơst4]k=Kut}c1fa\E`X&cX5V5cX7va$^lGXLXC%#W 1'"O%zxb:XF&!!%^'_H$ɒN !%2I IkHH-S>iL&m O:ňL $RJ5e?2BQͩ:ZImvP/S4u%͛Cˤ-Кigih/t ݃EЗkw Hb(k{/LӗT02goUX**|:V~TUsU?y TU^V}FUP թU6RwRPQ__c FHTc!2eXBrV,kMb[Lvv/{LSCsfffqƱ9ٜJ! {--?-jf~7zھbrup@,:m:u 6Qu>cy Gm7046l18c̐ckihhI'&g5x>fob4ekVyVV׬I\,mWlPW :˶vm))Sn1 9a%m;t;|rtuvlp4éĩWggs5KvSmnz˕ҵܭm=}M.]=AXq㝧/^v^Y^O&0m[{`:>=e>>z"=#~~~;yN`k5/ >B Yroc3g,Z0&L~oL̶Gli})*2.QStqt,֬Yg񏩌;jrvgjlRlc웸xEt$ =sl3Ttcܢ˞w|/%ҟ3gAMA|Q cHRMz%u0`:o_FIDATx{PTW^H#[yFGh֚b)cffLj&UT;fglJSb3 1(htC@}<߯2{8s$I- DO 6A"l@* #!Pf Arl7xA vYDV0p /`.hҮx AVx @H6^Pb ^"]7G~OO'"ex šT$ԏR8Ο[D5$A.l"dª0`Ȧf_X%'Dv~";? q!t5@#`>lÿ  0[zj&bр[=]csOM:FV/T [D.1 e齄kh5ͽYkSxȊGǰ}H w8.l9tk0Ԣ j0ydKq--;_ڵ:lǿRN3}`Pk *<*Wv|APW%ӃmJC N+fc[d@i<]]Q~d[OpC<K<+ޫhn,At JWgg!md{A8D Μ]^f%"A;!|X"D Nb0{?&58?YW_}$#徇\\8 W; ~e0׋2A@D "bD "1@D "bD "1@D "bD "1@D "bԨX,0L0Ljh4h4j҂7no<E~~~ Axx8$$$ 22...PTE*9~=gX,hnnFkk+nܸ:hZ]]]bypIV 88111?>뛉ځؾ:Fr֢ZCCCX,X,$ipQ~EżypB,] [)1ΝQVV^[na``?'="򂷷7Ñ dee!$$-֠QUUSN MMMhoo@tt4Ґ41ՅFeee06\HOOիn:CV@F8}4PZZ.f$Q1k,XO>$ 777`bL}}}ӧN۷omeyxx 667nDNN;NСC())AGG]ߑ‚gy+V[2$r!Pww7N:<\xG 'N@kk+___f: > p;$a``eee0͛I iooLJ~R4444vd2駟F@@[%1сGb߾}t l6F$gH!ZƱcǰo>:MeXP[[<;v l9syyyuʨヒgbhh.\;#iQ!سg.^I;_{ &iZTdW_}ɓ'9@'f3{iZWNcc#}]TTT8b<$It8x X;***pAt:I \>ipp焦G444ٳhmmeE̙3hll łsΡ^0QRRrAaa!?dҥK<\ߏ|TTTL?e6QQQ|@mm-y|駨 ɄR|w}ł?$pʕ|Ѻp9h4 rD]]jkkP?P^^6<PSSJ &&h4ŋNA 9qX,|W~:'&qQVVƇ1/^wׇ t: rFŸ)._'OdФl[pF'I$ttt // q&s:6 ш @LL  ___L& BբnݲFߏWrE$AբΪ* !!!HKKCRRϟX fhnnFAuu5qU`'\|VFrr2֮]u!,, jj5"##,TUUɓ8wxB uuuVk׮ų>+V 88>>>Ftt4bbbph41:lh4V ,[ vBvv6Dq7= Aw^zrV ۋ&\Ϟ=;wDff:`l۶ 6m[ 1&KףfYb֭O("** b!d555)>,l޼YWm dlٲQQQl9 V+Az qqq)dff"++ *ҢL+ӱl2 {Xf z0Qmmmj5uo$bL`t.55}0Ņ-ݭ @777! @(`" x̘1CR bLtWWW̙3ʞ4QDHHק+"##6~~~M49m(=U؂0JEQD JFDNJ^[,meX000D Rlٌ|`|||:߹s͊?j,I:;;qM bLZV2Ν;hllD7o-7yfhhFy^f bLtt ů8 D+6`XjqܹsGQYY\@ppX !|7b!D+v 0Ak)́^GQQ0QQQ.$ :hhh۷o|-1&>>>h4ǏGgglRUU?hjjb!d!<<\Gvo޼CFqJeY,477ѣj0Y:ƣJJJ Q[[8cǎM9L7WT+qy̘1x'&$IAAA>!AVG I`gΜ`F{=/onݺα׃vмg9TGx7ܞ~#..N/"f3m&dobb"~ l5,Z زe jkk ~#0#)) sٳ///f(++C}}2J'JLLDuuC/z)u\WWWh4DGG<<><xT̜90 >>>HIIA`` O9^ (p={6222x1q$%%YmMpssCJJ 燥Kr;˧ d$''cvwԞ'&&:?b?>V\썓Zʕ+ǓA* O<fϞُ,QD\\/_*$~AVFk׮… y2y`ƌشiҸ0!#TlڴI`uK,ZPlذ/vK>_]߮\)))pssciiiXjS}/9# ?1G韝9s8˔~ ʥ=}OOO]8|0n߾=+k֬5kTmÆ vڔ bOvQQQxpM JMMs=HfBdd${!/ 222}vDEEMʉ?tŷQ'͛uin݊\C+`֬Yرc~L 6`\"d2ή&Ů]ti@HRaٲeصkbbbclH-ݽSwHKK /0m}_d v܉T@Sb϶6c'|]]]ؽ{7._ nѢEرc֭[PvZQ-A&GE^^._T .Ν;ˍ>js sa-[@߿NSIIIؾ};~iv~%B* UUUvpuuEJJ ~g?"ى?Cee%ŘHNNΝ;~z#\8d`@ii)>ttt8D@dff"77ۡ&c֬YXz5j5N'\Xlܸ999Xx17 ^Lh^Gaa!_fnN j5/_dgg#,,r 444ɓ(--Eyy]L!==ܹs!1҂JoVEGG?G@@l#44-֠q9?eee";Ȉ///x{{#44Xl` FAyy9.]+W@Ӎ%gX I9(."\]]sb…HOOGBBj5|}}J` $thii7PWWVvttt`0===___j# AAAƂ {F1llQLVo׮]V ~'Q燐#** HHH@BB"##RRnbTMc "1@D "bD "1@D "bD "1@D "bDd` "t ?" }1XD6`iɚ ^ YD67>W\aM@I@j!Z3FR %`w"+_YIeYo/Ok"+֑Oe)K9=M"|}gu@d e,F0V LBc:UkYCD R҄Y4?5pkHfCWbѺvQA9 rx^W"لOc}~4 *51 fɨ/X,8_Oޫ5"XZp$?_"GX4(gw 4DZRIx_#D'[MX{DS]v6Nbp@Gb"$?ko'w$_y?G(8}!@4/=\9˛Ōac]Uɒ$ <(v+Ś*v#"!ye{XZ)?5_Ia#QRشn "sAZ'2_pxܳw+$iA }45;Okp&M[CWbX."{(IRx^J~s#𗽯`p bkiX K̫yr.}$18!-cCe !#u4Z.ca %I?|T8`>펭' /8raYZѧ+^?ƚ$Iʡ[yHM@h`f 3t,+mf0zop:}3J**G`$IEK8 6Yj" w{ x+#}wW'p!@xDwf9IL0O6DN!k n "뻁-@C&XPGWr0Sqga"zB +jAu/Ao>{`Qנ~DT1H_x2o/F4\ֽ;8B{ vph"1s[.mVf@?_x;RB90_Y{E 퀦4I.h@IENDB`Ext/Icons_04_CB/keyhole-grn.ico0000664000000000000000000006117610062626434015176 0ustar rootroot 00h ( 00 h^"00 %'  nM h^(0`pp7wwwzszszsc:r62pzzwzs:sc`pwww8zzzw6:z3zr 0! #szzs x{w0:zsz0zr:szz60xxx':w6:p{z6w:zswsz:szs0 w7`x{w zszszzzr{w07:zsz0wwwwr7770:zzsxr7zw7pwzzwzz0xxw w777wz zz7pxw087w7xxwr87:{pwwr'zxw7wwzzpxxxwsszwx눣({{zww0zhrxx0xzzzpxxxzzwwxxxwx7{zx0z0xxxw7x0x>wp`r0zx8xxxr'w{w{hxxwww0wwx xwwpx%'xwwx0pxxwx(xwzr8xxxwvpp  pp( @pwzwzw7:s#pzzw:w:rrww#zrz2wzJs7z7:x{wzz7wx{h sw:sxzp:0zzsgw:zzwww7wx7zzxxwzzsz x:wx  x x7{zr{w{wzzxx(wxx'xzww x7x{zxxxxpxw xx 'xxzp(xxwrx p( pwzw:r'z'7 xzz0 sph wpzpxp{sr zz7xhp{x2rxw7 (0`         ! " ' "$+*--180":#?%!3$+<-H'P!&G,*@.#I*+N14O8.Y6,_61V87V<2\:'f43c<4d=8`?,=:gB>fE;hC;qE5|C;xG={IFFFQQQYYYDrLDOLuSNxUXz]fffyyy$9'>5HUyyytý¼3=yytýiny½%yý½ýWf½>U½?U½giý ý$2é h |k@¸h'0j/B ½ : ½C @½|4 ;A9C;B:( @           #+ %&*,-7<6"'6)J($E*$K,)M0-O30H4-X56W<8U=5[;(i50c: v2:\@8g@=qG<{HFFFmmm8F;972#@>;97 %#B@>;9,%#CB@><6'-,%#DCB@>;20-,%#GDCB? 20-,%IGDC 20-,JIGD720-LJIG5(9730FLJIG"!?>98)FLKIGDCB@>>4 (0` %F;;;F ;;; --- 3cVV 'F gwq҃oЁlj}h{fydwbu`s]q[pYnWlUjShQfOeMcKaI_G^E\CZBY@W>V ;;;:gBvԇsӅq҃oЁmj}h{fydwbu`s]rFV$$####" " " " " ! ! !,=VVVVV=T;S9Q8P6O5N3L2Kޕݓۑڏ}ٍz׋x։vՇtӅq҃oЁmπk~i{fz"  J`I`G^E\D[BY@W>VV=U;S9R8P6O5Nޕݓܑڏ}ٍz׋x։vՇtӅq҃oтmπk~KY5|COeMcKaI`G^F\D[BY@X>V=T;S9R8P6Oޕݓܑڏ}ٍ{׌x։vՇtӅr҃oЂmπew K_QgOeMcKbI`H^E\D[BY@X>V=T;S9R8Pޕݓܑڏ}ٍz׌x։vՇtӆr҄oтmπ:#+UjSiQgOeMcKbI`G^F\D[BY@X>V=U;S9Rޕݓܑڏ}ٍ{׋x֊vՈtӆr҄oс;qE,_6WlVkSiQgOeMcKbI`H^F]D[BY@X>V=U;Sޕݓܑڏ}َ{؋x֊vՈtӆr҄[iETZnXmVkTiQgOeMcKbI`H^F]D[BY@X?V=Uޕݓܑڏ}ٍ{؋x֊vՈtӆp΁ Zm\pZoXlVkTiQgOeMcKbJ`H^F]D[BY@X?Vޕݓܑڐ}َ{،y֊vՈtӆ+N1?%`t^r\pZnXmVkSiQgPeMcLbI`H^F]D[BY@Xޕݓܒڏ}َ{،y֊vՈLW;xGcv`t^r\pZoXmVkTiRgOeNcLbJ`H^F]D[BYߕݓܑۏ}َ{،y֊l|Xiexcv`t^r\qZnXmVkTiRgPeMdLbJ`H^F]D[ߕݓܒڐ}َ{،y֊- h{gzexcv`t^r\pZoXmVkTiRgPeNcLbJ`H^F]ߕݔܒې}َ{،;hC/Y7l~i|gzexcv`t^r\qZoXmVkTiRgPeNdLbJ`H^ߕݓܒې}َ^jN[nπl~i|gzexcvat^r\qZoXmVkTiRgPeNdLbJ`ߕݔܒjx1V82\:dtnπl~i|gzexcvat^s\pZoXmVkTiRgPeNdLbܓDrL GSnπl~i|gzexcwat^s\qZoXmVkTiRgPfNd>fEDOnπl~i|gzexcvat_s\qZoXmVkTiRgPfbl ]lnЀl~i|gzexcwau_s]qZoXmVkTiRg*&G,pтnЀl~i|hzexcwau_s\qZoXmVkTis~ hypтnЀl~j|g{eycwau_s]qZoXmVkV^Tar҄pтnЀlj|gzeycwau_s]qZoXmLuSISuԆs҄pтnЀlj}hzeycwau_s]qZoNxULVwՈuԆs҄pтnЀlj}g{eycwau_s]q^f]jy׊wՈuԆs҅pтnЁlj}h{eycwau_sȏ  w·|،y׊wՈuԆsӄpуnЁlj}h{fycwau*@.8`?ې~ڎ|،y׊wՉuԆsӅqуnЁlj}h{eycw xɆݒې~ڎ|؍y׊wՉuԇsӅqуnЁlj}h{fyck gsߖޔܒې~ڎ|،z׋wՈuԇsӅqуoЁlj}dv̛ox-p|ߖޔܒې~ڏ|؍z׊w։uԇsӅqуoЁlUdXz]ai4O80"!3$7VU;Sޕܒڏ|،x֊uԇr҄6"*[oXmUjQgNdKbI_F]CZ@X>Uޕܒڏ|؍x֊uԇ=qG0c:^r[oXmUjRgOdKbI_F]CZ@Xߕܒڐ|؍y֊`nM]au^r[pXmUjRgOdLbI_F]CZߕܓڐ|؍xՉ fyexbu^r[pXmUjRgOdLbI_F]ߕݓې|؍-O3$E*k~h{exbu^r[pXmUjRgOeLbI_ߕݓvʅ-O3)M0j{l~h{exbu^s[pXmUjRgOeLbdp  Zil~h{exbu^s[pXmUjRgOeyĆ   gwl~h{exbv_s[pXmUjRg6W<8g@oЁl~h{eybv_s[pXmUj  &r҄oЁli{eybv_s[pXm  vՇs҄oЁli|eybv_s[p y׊vՇs҄oсli|eybv_s0H45[;}ٍy׊vՇsӅoЂli|fybv{ qې}ٍy׊vՈsӅpтli|fy^f^iߖݓې}ٍz׋vՈsӅpтldv8U=$&:\@z†ߖݓې}َz׋vՈsӅpтMZ777'6)ߖݓۑ}َz׋vՈp΂-:'6)ߖݔۑxЈVc.:\\:777:(  @:::(I.bsdw]qWlQfKaE\@W;S6O2K*B::::n}q҃k}dw?L    (s8;S6O2K*Bڏx։q҃k}Xi;O@W;S6O2Kޕڏx։q҃k~  KaE\@W;S6Oޕڏx։r҄.X6#N+QgKbF\@X;Sޕڏx֊P]?MXmQgKbF]@Xߕڐs̃^q^rXmRgLbF]ߕ}׍'$j}ex^rXmRgLbۖ1!6"j|ex_sXmRg[cKXl~ey_sXmOyVBwLs҄ley_s{ivy׊sӅlfy`h [dߖېz׋sӅct:::@YDߖۑp(J.:::Ext/Icons_04_CB/plocko.ico0000664000000000000000000006117610062571030014230 0ustar rootroot 00h ( 00 h^"00 %'  nM h^(0`pwwpwspx8p{{yp{{yy{{x@A0p00x0 s{y;{{{9{{0@{@0;p31q51131){ps737ysq73[pxyxyssssss73s;111S1@C{{{!04x{x88{w{7p?p@0#1 {{p8{q{{00$ 0;{x p0{qx{00wq$0{8pA x@x01B7708p8s77p0@4p??( @pwwp8p3{pp`@9p?s738337p73s{ss9y{;qpsssq3s79p0sssssss7p8{p{?08{0qp 83A{x0!` c00p87s7sppg??( p7wwxpw11 q781!{H111q?qw{81!w{w8p3p(0`  "" "" ' #%*'6*03:!!!#&(%()-2655627<6:<1@ 6Y8Y=VD@YCYI^&IM.7 ,%63#,!-%)03:-71=5:>BGKOWYOBKZbOAFW_BFJPR\fiqv|iYN_RVZ^dkfhs{finbfjuv~nsxw{+(  (+,)J½J),XX())(ӘyjiiiRiuZyjjkkiiiiiRRRrZ{mttllkkkiiiiiiRRjޏvmvtttltkkkkiiiiRRRRu{{{vvmttltktkkkkiiiiiRRR(}{{{{vvvtttllllkkkiiiiiRiR(}}{{{{{vvvttttltkkkkiiiiiRiZ-Rii,-iiRx,*֒-iiii)bb^^]]]PPPvvvoMMLLLKKKKQkkiitדn{{B-jkkkkYn{B1tltkkyX좡qaAtktkjk+֣===<<<<<2;|f00///....Ottttlt+(*zG1vtttlt~)( WzS3vvvttttU 쯮@@@??=====g<22222///a{vvvvtt믯  B{{{wvvv믯>}}{{wwv>}{{{{ Wddddddbbbbq{}U (*㴴6 })(+跴 !$+! CC㸷:\Y#⸸ 95*H& ),⸸ &#,⸸8 \ﹹ⸱ \'6(幹  "(幹 "幹'幹TTT[幹⸸(湹(*)(,*W*,+( (+??( @ ### +# $&, '> *>*37;+06/46056444=D;Y7>E=t@YFY"DK;AE>EI$N] BtFtItMt+Yf7lw@OX[ZGCNAFJYVZghmqy~jMZTVZ^afmfu|oyw{,,,)--(,&qgSSZo&IZPPPOONNNSsIgWRRQPPPOONNNS&[XWWURRQPPPONNNNo&]][[XWWURRQPPPONNNqI_]][[XWWURRQPPPONNNN,ni_PNV,'kjiPPOs}vkk994933=XX500000>QPQY,yxxk][ URQQ,zyxx:::999@^]533321?UURRr*{zzy^` XWUUh).z{;;;:;::99999343A[XXW]-/"][[XZ-*<<<;;;;:::::999B^^][l*zzyyxxkk 9__^^],8 z{zyxxaEji__^,L Lz{zy7 fkjiim'~ #zwyvkkj',$ dC Dyyxv|,&u ~e zzzxxG JF b{{z&%  K&H c&'&'',+//+,,,??( ### % %&1+44801216=28=5;=7<=(K:B8D=F 4Y 6Y:Y>Y7>F8?FBYEY"DL:AF>DF!IY'NY DxHxMxRx1_h@EFhhh0j%j*qr&y${<KJyM,7 !.$')6-38=Q@JGLHgzQRT^WX[^^jmquafdacejnswz~% %jlxLLvkj%0wF8654=:8654K0j{D4r%n[H+)6@l% QM2*=8y ]S( ?>q a]BAt ba1 ]SMG 3DC{ %p}bVE]],IIPm%ed#a\&QMjiXZ]~fj%iY-.W|i%j$ppj% %(0` %\\qq #HQZkzkyGPZ #\\\{-27sq-27\\\{-EMUDLU͸-S4:?f6 ._38?񁁁Sqqqn z|5 &qv qqqnqqqn"$0 r!$qqqnS*/3F%#!  ,(-3S-"%/*(&$#! q!$񸸸- s1/-+)'&$"! W \\\{}6420.,*)'%$"  rv\\\{6;?>97"""#""#""#""#""#""#"#"" R 39?􉉉\><:"""#""#""#""#""#""#"#"" T0IQUDB@>"""#""#""#""#""#""#"#"" UvDLUqVGECA10.-,*)'&$,+*%xwvutrqpo!q057LJHGE """#""#""#+.-t"#""#"#""Yw-27|fPNLJH " " " #""#""#.20"v"#""#"#""Z0s\USQONLCYBYAY@Y@Y?Y>Y>Y>Y=Y354(:Y9Y8Y8Y7Y 6Y 6Y 6Y 5Yj\"#XVUSQO+l*k)j(j'h&g%f$e#d"c797.^]\[ZYYWV{! i #OWZv\ZXVTS " " " # " " # ""#7<:)}"#""#"#""`%#! =IRZwe_][ZXV # # # # # # # # # #:?>,#########b(&$#!$m{dba_][Y2s1r0q/p.o-n+m*l)k)iACA7#d"c!c a`__^\$+)(&$#!gedb`_]GYGYGYFYEYEYDYCYBYBYAYAY@Y?Y?Y>Y=Y=Y<;:875421/586531/3o}PYZrpnmkihY$ # #2o]\ZXVTRPOMKI'6 # #=V@><:8643PJSZ "#usqpnmkf)0# "!GUa_][YXVTRPNC # " #!Y{CA?=<:86{!#\wvtsqonl$JU#""(_b`_][YWUTR4~ # " #/{FECA?=;9\xwutsqoFWWW %6B=81.+)&#! 4;BCCC%Z@=###############=t,##### Bt,13ZXUR*l)j'i&g$e"d'u64g\[ZXWm#!q).3S\`_]ZW # # # # # #>Y<9 )>#####Ft(&#!NLV_ly}udb_\2s0r/p-n,m*k)j'h%g$e"d!ba_^"w-*(%7cq}mz}yifda # # # # # # # # # # #####Mt2/-*BCCC%WWW}G ##=DJ@*1# &Oc`^[WWW  ~EFWWW CCC%.33U_`o|}o|}U_`.23CCC%YY??(  @0 +17*07 0 WWW6=D{y4;DWWW 9::}@ .w99: WWW-'" gxWWW08?D=########5Y=Y;Y${r 5Y 4Y Dx6 ؾWQ###,&y###  /57a[FYEYEY*qEY=Y;YMx)$,17057je########3.,27 snMMx^YTJMx7=8 wj %Qc^<&1LH^0!!!$%"&&%'($)+%,.',-).3"/0-13,24-3333505706667868;2999;=8=>9>?<6@7@!9A$=D+Pe@G/@G0CI4FK:IM>KR<S^9Rf"Uh'Sc-Vj)Vf1Xg4Zj3\j;f{2aq;BBBGHBJNBKP@MPEPRKQTIUVTZ[Y^eOanCblJfqKhsNaeWin\kuTltXoxYqy]mmmov`u|cx}mttty}p|*m4r;{6~,n@uAxFvKzI{FsQ}Ww[Z|t/2559<<>UY]_ABFFHJMO[QUVY]djmtwyzcelasx|veijjm{ppqxxruwz~ƂȆɈʋˌ̎͒ƙĦǬЙҜȭԠӦ֤֥ҪةڭƷͲǼɻг԰շ۱ѻܲݵ߸߹P<KHHFK7<  MKHHK7+;;;994432210-",?LLKKV*) (uutsrnmk/VVMLKn5:{{ussrnTEVVUMM~5gf cxussr0X[ZVVV`' *~{{usol\[ZVu56 j~~{u;Nml\[kp5&y ~{jrnmlkgaO R; brrrm{_g&8 Ruurr~q&_ d~{u{v a~~_ &&v&g&he&g5+<<+555??(    #' "'13=5?,.&00/59,1113404608;19=1<>6::98A#9A$;C(=98743B;F'gT2T.LaV 1/ 48I.iaZ5074Z iea%# -87Rlge98TmhgHZVTO6=9^ .NlhcK\V:B?CJ.'nlh*)^W +QOaFFnlb" ST]DF.Fnld;;YagE.F'NmlliL'F..(0` %\\qq !QTJz~px}mPSH!\\\{24/yѻͲs13,\\\{-NPIܲӝҜڮKNC͸-S:<7߹̎hNFC?<>Syة7:1񁁁Sqqqn ֤pYUQMJFB?;852GȆv qqqnqqqn#$!Ʒ٬tea]YUQMJFC?<852/;ȅ "qqqnS/0-ʉrmiea]YUQMJFB?<852/~,HبԷ,.'S-#$"޷Ɓzvrniea]YUQNJFB?<852/~,~-ǃԷ "񸸸- ɽۯɇǂ~zvrmiea]YUQNJFC?<852/~,|*k \\\{͐ˋɇǃ~zvrmiea]YUQMJFC?<852/~,|*ǃv\\\{=>:њΔ͏          Pe/~,~-ب7:1􉉉ǾڮҜИΔ          Qf!2/~,HRTP֤ԠҜИ          Sg#52/~,ȅKNCqܳة֥ԠҜwspmifc_\Ykje[zIxFvCt@r=q:o7m4l1{6952/;q675ܱڭة֥ԡenjuJ         Uh'<952/Ȇ13,ݵܱڭة֥irnwM        Vj)?<952Hs\߹޵ܱڭةFK:EK9EJ7DJ6CI4BH3AH1@G0?F.>E-pvrX:B%9B$8A"7@!6@5?4>4>3=f{2C?<952ةͳ\##"߹޵ܱڭrz_qy]oxZnwXmvVkuSjtQhsNgrLeqJxzvc^k>]j<[i9Zh7Xg4Wf2Ve0Td.Sc,ux}m߹w~gv}et|cs{`rz^py\oxYmwWluTjtRɇǃncoFanC`mA_l?]k<\j:Zh8Yh6Wg3{FRNJGC@<ڮJOAJN?IM>HL=GL;FK:EJ8DJ7CI5BH4BH2@G0@G/?F->E,=D+޶ܲڭة֥ԡӝљϔ͐ˌwS^9rnjfb^ZV̏ !\JND"#԰޶ܲڮت֥աӝљϔ͐w[sQwsnjfb^Z߹ѻ\z~p ޶ܲڮة֥ԡӝљϔEL5n{wrnjfbqy888 RVI޶ܲڮت֥աӝ!.3"ǃ{wsojf֥24/q24/ !#æ޶ܲڮتץաltWblJɈǃ{wsnuqVVV|t aeW޶ܲڮتƙ&){ˌɈDŽ{wsڭNPI'($ !"޶ܲڮ^eOKR<Δ͐ˌɈDŽ{ʋ@@@y|q   570г޶z љϕ͐ˌɈDŽƂ:<7􉉉\\\{<>8 13,׷Ƨin\ jrXաӝљϕ͐ˌɈ߸\\\{ Ʒ,-)  %'! !KP@Ӧ֦բӝљϕ͑۰Ǹ -&&&,-)   KOAҪڮتצաӝқ#$!񸸸-S333ʹGHB  !"jo]ش޶ܲڮتצۯ/0-Sqqqn&&&xvǬ޶ܲݴɽ#$"qqqnqqqn qqqnS@@@Ǿ=>;񁁁S-VVVSTP͸-\\\{888675\\\{$$#Z[ZYZW##"qq\\????( @ YYCCC%./*UXNnrenrdTXL-/)CCC% WWW@A;ۿ=@7WWW %=>9͑oTPcƁ٬:<4%1 ٬sYSMHB=84Iˍy  껻1% õǃke_YSMHB=84/Eբ %  ĸݴxrke_YSNHB=84/~,z  WWWˋȅ~xrke_YSNHC=84/}+zyWWWCCC%?@=љΑȅ~xrke_YSNHC=84//~,բ:<4CCC%ǾۯӞИ       ;K4/EDEB٫֥Ӟ       =L94/ˍ=@7Yܱ٫֥lvVjtRhsNfqKcoGanCqLleaq;Wf2Ue/Sc+Qb(O`%cz,>94JY޷ܱ٫94٬221޷ܱrz^px[mwWkuSitPgrLwVxrgvD\j:Zh7Wg3Ve0Sd-i~5HC>9Ƃ-/)^_]߷?F.x).   CP#NIC>cTXM{{yw~gu|ds{aqy]oxYmvVjtRhsNfqKdoGbnD_l@]k=[i9Yh6pATNICPnrd{|zHT+ZTNIUnre__^|ozlxiv}et|brz^px[mwWkuTitPgrLepIboE`mB^k>vJ`ZTNpUXN332PTHMRCܲ٬֥ӟљΒˌŃ!boBlf`ZTΒ./*uzk&(!ڴܲ٬֥ԟљΒqYrlf`ZY߸ܲ٬֥ԟљdmNwyslftYFGF')$W[N߸ܲ٬֥Λ)-!AG1Ȇyslڭ@B;knd !߸ܲ٬{fdˌȆyDŽCCC%CCBо#$! AD;ۼ߸$'37)͖ΓˌȆƀ=>9CCC%WWW  ;>5|n(+# ԟљΓˌݴWWW  ori   y٬֦ԟњö  % 572  !AD;߸ܲ٬۱ĸ %1 껻1%BCBǿ?@=% WWWFGFDEBWWW CCC%332__^{|z{{y^_]231CCC%YY??(  @0 12,02, 0 WWW>?:ݹИΓخ;=5WWW ::9|YMC8Nӝz999 WWW޷reYNC8/yzWWW0AB?И     0ӝ;=50֥CI4@G0=E+UtI5?3=AP9N  ܱ   _yR   C9خ 665IM?FK:DI6r~ViuL;C(9A$HU*NCΓ02,676        ZNљ12, HU*۱֥љHU*^fZ޹ "֥ܲh#'}s}0DDC^`XMPE߼Ԭ59,ckNˌŀ>?:0WWW340AD;8;19=1˝љ߷WWW :::|Գ::9 WWWDDCAB?WWW 0676665  0Ext/Icons_04_CB/lockgreen.ico0000664000000000000000000006117610062522356014721 0ustar rootroot 00h ( 00 h^"00 %'  nM h^(0`pwwpwvpxhnvhv~7vxpw~wjfh犆zv~wfxxvvz~fpww~znzvhxxx  vv福~~vvnh pxpvggx`~vj~xvfxgvvzzpwvwggp~zvgfp0~wgpxx`hzwp~7gowwghh~w~w~vx與xx~wwwxxhfx xxx~~zxp wwwp(~~px燨 xp~w pw~p`xxp`xxppHx hphpxvgxvp`p%p??( @pwwpgwhwhggfhp~wfxx~zw~f`px~#%&zvh ~vvx`v~popvvwhxrvp莂gwgg興w~z~w~z~` w~vp`~x~xpp~zpg$ppxxzxox爆xp` hxxwwpp pgpvvppw??( pwwfxwxggnpvh`w vwp~xw(~o`wwxx 8pwwpp(0`        "#$&+4.5!! #$ %%#%%%./*/2(3:#49'01.6<*333461666897;=6::9=>:>I$>B4?@=O_(GN5HP4OY9PX<^l>BBBOVAV^CPSKSTOTWOUWPVWTXXW[\Z\\[\\\^jAmAitPknbmmmpvbttt|*~,x@}\~wx/2558<<>ABFFJMOP\QUVY]ocbwx~syecaseijjmr}rvwz}~ƒƂƄȇɈˋˌ̎̐ΔʡųИҜʮԠ֥اרկةڭĹ۰ܱ׾ܲݵ޸߹B2 2B$%D9JJ7D%{ʶ{$26űʜ52%ѼpYUURPR]ʜ% ̤t_]]WWUURPPLLW{Ѯtnk__]]WWUURPPLLFPȜ$Ŗrppnk__]]WWUURPLLLLFW̿ ձtwtppnk__]]WWUURRPLLKFFʸ 2ծwtuppnk__]]WWUURRPLLKFEt̝2ռwtu  RRLLLLFE{+ўyyuURRPLLKFF%Dԩyw>,UURRPLLKFW̜D9ŢyiGWUURRLLLLF5ةy ZWWUURRRLLKP̜$%ȩ.)]]YWUURRPLLK#$ؼH?_]]YUUURRPLLWfԱ[__]]YWUURRLLL̫Bʼnk__]]WWUURRRLB2=ż@1pnn__]]WWUURRO^72}sjppn_k_^]WWUURRRJttpppn__^]WWUURR̈ 40ywtppn_k_^]YVUUR̎gcwttpppn__^]YWUU̎ wwuppn_k_]]WWÜ }hlwttpppn__]]YYJ2=*4wwuppn_k_^]p92B-wuupppn__]BCbwttppn_k_Ѷ!wwtpppnu{$%wwtrnn$%ywwuptѝ =wtt5D3wԨD2ň+AaԀ2{Բ2 af % ز؄ 2ز+ 2=ڲ92%ں%D =}}= D%%B2  2D??( @  "*)/,1/0,04%34/332444=>85@6A9F9C :D#;E%DH9OW;Wa=BBBFFEWYPX[S[_SY[T]aT_`^bmHm}G`eSemS``_juPjsTbbbdddsvl||{}+~-vB{^}_~f/48=BHMRTWYY_d`kehklrrux~ƁƄDŽȅʋˌ͒ИӞԟ֥Ԩ֭٫٫٬ͳźǾ۱ܱܲ޶߸߹߿444)55)4_$^\ _$ ukSFDNg~j$ Y{SHDCBA@?>CkV veNNHHDCBA@?>=Awj $~UTRNNKHDCBA@?>>7dj$_[geUTS@>>=7dV_$kigeUS AA>>==w4wkkigeU#BA@?>=Bj4%rrkkigeJ9CBA@?>=k _wrrkkigdHDCBAA?>C\4~~wrrkkigHHDDBA@?>~4~~wrrkki:-NKHDDAA@?g+~~wrrkkfLNNKHFDBAAN'6~~wrrkk TSNNKHDCBAD56~~wrrk2,UTSNNKHDDBF54~~wrr<:eUTSNNKHDCS)~p"edTSNNKHDk4~.1dUTSNNKH4_~ geUTSNNT^%tigeUTSNw$4kigedTgu4%(/kkiged__pnnkig~Y_$W)(Xwwrnmku$ ~wr{v ]~[ $$ $_%a`%_4466+444??(     ! $8>):>.010784;=6:;:=@6?A;GT(AB>S]=`v-dx4h{<CDBEEE[eD[aNhhhoEzL/08CMRYkfprr~Ɓˋˌ͖ИӞգ֥٫٫ܱ߽ -1C;:@0-+E)#! "=*-,A)'5*-I:6) =3A;96! "0 KA?<:$#! @ KEA?;8&%#! : KHEA?<)'%#!; NJHEA)(%#C 4KJHB6)(51PKJH:65E--NKI2 /;:A+--PKJHEAAI,-4NKKK3- (0` %\\qq!"TVOx~wSVN!"\\\{461}35/\\\{-QRMĸةاNQI͸-S<=9źϕkOFC?<>Wǂ߷:<5񁁁Sqqqn ڬrYUQMJFB?;852J͐ qqqnqqqn$$"ݴuea]YUQMJFC?<852/=͐ų"#qqqnS01/ˌrmiea]YUQMJFB?<852/~,L޸./*S-$%#Ɓzvrniea]YUQNJFB?<852/~,-̎"#񸸸- ݴɇǂ~zvrmiea]YUQNJFC?<852/~,|*sų \\\{͐ˋɇǃ~zvr           ?<852/~,|*̎\\\{>?<њΔ͏ˋɇǃ~zv3:#+4C?<852/~,.޸:<5􉉉ۯҜИϔ͏ˋɇǃ~z^jAO_(FC?<852/~,LTUR֤ԠҜИΔ͐ˋɇǃ~ex@JFC?<852/~,͐NQIqݳة֥ԠҜИϔ͏ˋɇǃ} PNJFC?<952/=q786ܱڭة֥ԡҜИΔ̐ˋɇǃHP4>I$URNJFC?<952/͑35/ݵܱڭة֥ԠҜјϔ͐ˋɇ}\mAYURNJFC?<952K}\߹޵ܱڭة֥ԡҝИϔ͐ˋ  \^YVRNJGC?<952߸\$$#߹޵ܱڭة֥ԠҜИϔ͐ˋ49'.5fa]YVRNJGC?<95ǃ!"Z[Y߹޵ܱڭة֥ԡҜИϔ͐itP^l>jfa]ZURNJFC?<9WSVN߹޵ܱڭة֥ԡҝјϔ}cnjfb^ZVRNJGC@B4PX<Ąǃ{wrnjfb^ZVRlTVP$$$կ/2(GN5ȇǃ{wrnjfb^ZVϖ!"\pvbcɇǃ{wsnjfb^Z\6<*ˌɈDŽ{wrnjfbs998ʮ  ͐ˌɈDŽ{wsojfڭ461qϕ͐ˌɈǃ{wsnvĸqWWV׾љϕ͐ˌɈDŽ{wsݴQRM02,OVAӝљϕ͐ˌɈDŽ{ˍźAA@ աӝљϕ͐ˌɈDŽǂ<>9􉉉\\\{knboتצաӝљϕ͐ˌɈ\\\{ $&ܲڮ٪֦բӝљϕ͑ݵ -&&&wxݻ޶ܲڮتצաӝқ$$"񸸸-S333޶ܲڮتצ۰01/Sqqqn&&&޶ܲݴ$%#qqqnqqqn qqqnS@A@>?<񁁁S-WWVTUR͸-\\\{998786\\\{$$$[[[Z[Y$$#qq\\????( @ YYCCC%/1-Y[TsvmsvlX[S/0,CCC% WWWBC?@B<WWW %?@<źњtWRhʋ=>8%1 ݴvYSMHB=84Mј  껻1% Ǿȅke_YSMHB=84/H۱ %  ߹xrke_YSNHB=84/~,DŽ  WWWˋȅ~xrCM+;E%:D#9C 7B6A5@9F=84/}+DŽWWWCCC%AA?љΑˋȅ~x)/"*C>84/~-۱=>8CCC%ܱӞИ͒ˋȅ~Wa=IW&HC>84/HEFD٫֥ӞИΒˋȅdvBNHC>94/љ@B<Yܱ٫֥ӞИΒˋƄ YTNHC>94MY޷ܱ٫֥ӟИΒˋDL394332޷ܱ٫֥ӟИΒ{^m}Gf`ZTNHC>9ʋ/0,_`^߷ܱ٫֥ӟјklf`ZTNIC>iX[S||{޷ܱ٫֥ӟј04%,1xrlf`ZTNICRsvm||{߷ܲ٫֥ӟjsTbmHxrlf`ZTNIWsvm``_߷ܲ٫֥~f}_ȅyrlf`ZTNtY[T333߸֭DH9OW;Džyrlf`ZTњ/1-`eSjuPȅyrlf`ZY߿ ˌȆyslfwYGGGͳΒˌȆyslݵBC?љΓˌȆyȆźCCC%CCCWYPemSԟљΓˌȆƁ?@<CCC%WWW34/AD7ԨצԟљΓˌWWW  [_S]aT޷ܲ٬֦ԟњǾ  % ߸ܲ٬ܲ %1 껻1%CCCAA?% WWWGGGEFDWWW CCC%333``_||{||{_`^332CCC%YY??(  @0 340340 0 WWW@A=գӞ߽>@:WWW :::YMC8R٫9:9 WWWroEh{@:0֥ИˋS]=GT(NC9R ܱ֥ИkzLZNC9߽ 676ܱ֥͖  pfZNCӞ340776ܱ֥[eD[eDrfZNգ340[aN[eDrfZ ˌsŀ0DDD!љˌƀ@A=0WWW;=6=@6צљWWW :::::: WWWDDDBCAWWW 0776776 0Ext/Icons_04_CB/plockbw.ico0000664000000000000000000006117610062570634014413 0ustar rootroot 00h ( 00 h^"00 %'  nM h^(0`pxwpwwpxxppp@@p@wsw7twwsewpwwwwwwwwwxp@@@WwwwwwwxwwGwG4wwwwx p40$a'p!p04'@CspCOao P8q$%p0ppxBHpBGpxp0'pxpxqwwppp??( @pwwppwwxp pppwwwwwp@pwwwxxppx@Gpwwwwxppppxwwxpppppwp0pwppppp pwpwwpp??( wwpxwwpxwxwpwwwxxppwwxpwwp(0`  """#%&%&&)))01166679:899===>ABABBMMMUUUUWXVXXYYYY[\[\\^^^aaadddmmmqqqttt{{{}}}  +00+  %;CCCCCCCCCC;% 5CCCCCCCCCCCCCCCC55CCCCCCCCCCCCCCCCCCCC5%CCCCCCCCCCCCCCCCCCCCCCCC%6CCCCCCCCCCCCCCCCCCCCCCCCCC6 >CCCCCCCCCCCCCCCCCCCCCCCCCCCC> >CCCCCCCCCCCCCCCCCCCCCCCCCCCCCC>6CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC6%CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC%CCCCCC'CCCCCC5CCCCCC'CCCCCC5CCCCCCC'CCCCCCC5CCCCCCC3335333335ACC>533333533;CCCCCCC5 CCCCCCCC;CC.'CCCCCCCC %CCCCCCCC;CC.'CCCCCCCC%;CCCCCCCC>CC5-CCCCCCCC;CCCCCCCCC##########ACC9#########5CCCCCCCCCCCCCCCCCC 9CCCCCCCCCC5CCCCCCCCC;5CCCCCCCCCCCCCCCC5CCCCCCCCCC >CCCC+7CCCCCCCCCC&CCCCCCCCCA +>;"CCCCCCCCCC%7CCCCCCCCC7 ACCCCCCCCC7>CCCCCCCCC5ACCCCCCCCC> >CCCCCCCCC9ACCCCCCCCC> 7CCCCCCCCCC3%%%'>>BBBEGHGHHLLL]]]_aaddduuuyyy|}}  !!!!!!  !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! !!!!!!!!!! !!!!!!!!!!!! !!!!! !!!!!!! !!!!!!!!!!!!!!!!!!!! !!!!!!!! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! !!!!!!!!!!!!!!! !!!!!!!!!!!!!!!!!!! !!!!!!!!!!!! !!!!!!!!!!!! !!!!!! !!!!!!! !!!!!!!!!!!!!!!! !!!!!! !! !!!!!!!!!!!!! !!!!!!!!!!!!!!!!!!!!!!!! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!  !!!!!!  ??( ###%%%111444:::BBBEEELLLYYYhhhxxx                      (0` %\\qq!#$XZ[XZ[!#$\\\{578578\\\{-SUVSUV͸-S=?@?@"""""""""###""""""###""""""###""""""###""""""###""""""###"""###""""""?@􉉉\\\{BBB###""""""888~~~%%%###""""""\\\{ 000""""""###"""+++%%%""""""###"""^^^ -%%%000########################[[[$%%񸸸-S233MMM###""""""###"""'''}}}123Sqqqn%%%$%%qqqnqqqn qqqnS?@@>@@񁁁S-UVVTVV͸-\\\{788788\\\{#$$Z[[Z[[#$$qq\\????( @ YYCCC%133^``{|}{|}^``133CCC% WWWDFGDFGWWW %ABC@BC%1 껻1%  %   WWWWWWCCC%ABC@BCCCC%#############################################uuuEFG#############################################uuuDFGYY##################ZZZ>>>###############uuu233133_``##################ZZZ>>>###############uuu^``|}}{}}|}}#############################################uuu{}}_``_``233]]]###^^^+++###233###---######Y#########&&&YFGG,,,###ggg666###ZZZEFGwww###$$$######CCC%BCC(((###KKK---###BBBABCCCC%WWW######DDD111###&&&WWW  yyy###############%%%  % ;;;###%%%LLL %1 껻1%BCCACC% WWWFGGFGGWWW CCC%333```|}}|}}```233CCC%YY??(  @0 677677 0 WWWCDDCDDWWW :::::: WWWWWW0CDD#####################LLLCDD0ZZZZZZZZZZZZZZZxxx #########ZZZ######### 777ZZZZZZZZZZZZZZZZZZxxx677777########################677 ZZZZZZ %%%1110DDDhhhYYYDDDCDD0WWW888LLLBBBFFFWWW :::::: WWWDDDCDDWWW 0 777777 0Ext/KPDummyKey.pfx0000664000000000000000000000333410576764760013061 0ustar rootroot00 *H 0}0 *H 00 *H  00 *H  05D?*dI& |i&fKG;#!΀%R[m)ZwQoT>ybv[O$Rd3OWo7c4;תBvft87 5SG LLP4AiF2L[+ )$as(Q+Oݷ+hț[#~)[jgriL8V(C3=JpzĺV 3:|<`N8+؃8, tjؚyD5֙,X2ut_."h/^+ɳ)oAL̒*Yv3V윎,J3kgLp/s(AqPԼH^˪Ͳ;6L$ 8̒/Ya\J7zl0+/eϬ!!v,(7w&ٝ|mQZmI];8FVW.";> r'E gӟ.4{j<(C ҉v9&g>+9= 9}z7Dݗ]2>y%o,^9߸E69Rd_yYaļI6h>'3s=7haT<$t\1BOJuHsw3dMBjW"F~aؒz>um+yj8S!X*ZР#D!;*q^1-28=p'>[ɠ> !\8CY5qM~}dWBx~I`߃m@%wz'mBqlCd |~E~Q4nvwm0d΢pJ4\Z46`W|Uc Ut10;00+&cr{ 5FL~!4Sqn.CExt/XSL/0000775000000000000000000000000013024527232010764 5ustar rootrootExt/XSL/KDBX_Common.xsl0000664000000000000000000000656513222431152013563 0ustar rootroot
]]> ]]> ]]> ]]> KDBX Common

The KDBX_Common.xsl stylesheet is not supposed to be used directly.

Ext/XSL/KDBX_Tabular_HTML.xsl0000664000000000000000000000621713024520050014537 0ustar rootroot <xsl:if test="DatabaseName != ''"> <xsl:value-of select="DatabaseName" /> </xsl:if> <xsl:if test="DatabaseName = ''"> <xsl:text>Database</xsl:text> </xsl:if>

Title User Name Password URL Notes
 

]]>
Ext/XSL/KDBX_DetailsFull_HTML.xsl0000664000000000000000000000674413024515562015376 0ustar rootroot <xsl:if test="DatabaseName != ''"> <xsl:value-of select="DatabaseName" /> </xsl:if> <xsl:if test="DatabaseName = ''"> <xsl:text>Database</xsl:text> </xsl:if>
User Name: Password: URL: Notes: : Creation Time: Last Modification Time: Expires: Never expires
Ext/XSL/KDBX_PasswordsOnly_TXT.xsl0000664000000000000000000000162713024515566015727 0ustar rootroot Ext/XSL/KDBX_DetailsLight_HTML.xsl0000664000000000000000000000603213024515560015527 0ustar rootroot <xsl:if test="DatabaseName != ''"> <xsl:value-of select="DatabaseName" /> </xsl:if> <xsl:if test="DatabaseName = ''"> <xsl:text>Database</xsl:text> </xsl:if>
User Name: Password: URL: Notes: :
Ext/Resources/0000775000000000000000000000000012606740432012274 5ustar rootrootExt/Resources/LockOverlay32.png0000664000000000000000000000401311436206114015371 0ustar rootrootPNG  IHDR szzsRGBgAMA a cHRMz&u0`:pQ<tEXtSoftwarePaint.NET v3.5.5IdIDATXG p a5ŽB, *0U,B,[ T-%D@Sm1 LRҤj*[3b$${!y}T g|g)3O0Y2>MA^6?v3;gbsC~ag~i,feQ,< Qv@`f2 䯋͚`xL,|#7ܠMIӣw߭SiPX:f{٘B`[7N`o]}T碢|-iF)9YJJ֯W嫯̴iʺ>m<$45k$w{Zٱp)6VJInl>kl|^j(WbVz.$Sz CFyg8ݨ2TŜ9uڵRB•qXR1XTGO ٬ݷzqMq𡇤s%K_/6TS1}vu'Q6W͚_i}# 5x4c)͞]3DD'kW' pA2v| 4pƷF?t`qY*=O7{faa*^60t蠳b U,t\x~< S%T  U[Tܲ! 4n6G >+J_R|7\RΈE 7&MTx:UE5Ju-TՉ+ m`c'<>t}Wxo?ϲ[tvڍw3#(OQnRCt7k:uJGͦJx/!xo/hI|$S2xq7#Gz>lۦ5ԔC^-of ݹ~f̃!*[oA^XO*SM].Lγ|C.&T4Hr`/inY׽**f;|P'("{I-П2FAQҨn<T,E?KlfhBnT8uP(fR%S;w6<c1n$?l\6ݭ88cR?S2.ghBv )߿hrGV.zc:9a♠(沛/L 2Li`xd'P cǪq^xb%(z=9NUkvVQpNt\xFϋcbt|rWeT/f*N8DCHm&'*aQ^vW̏K勋ӎYvRg`-/GM3'Q%/2:Zy~Gfj̚5*b\ bB QvG߳1Wc1?d}qrYT}'RֵzT iZs*ߩ{ |wnu9u9pTM/Թ97ΒES\qyήGTR])Bٖa6{L2&N" 2"G1IaߍIENDB`Ext/Resources/LockOverlay16.png0000664000000000000000000000144411436204034015377 0ustar rootrootPNG  IHDRasRGBgAMA a cHRMz&u0`:pQ<tEXtSoftwarePaint.NET v3.5.5I}IDAT8OS[HTQ]wCԘ)>RA;Ͱ@S|a~"?%%G}Q b1&ab՞Q6,8:{ﳎ]Dz pH_ -`}7ǽoԭ@{nDEEhmzSrsy=<T*0$Hmͫ!!RWG\QZ9lF"?""w-4?^WU_DN]Ҧ RRQ޴&$GJ tJ,.&KJ kga!yy̅8S2 N~~(rߟkn}*90L!S^HLLM~LM=NEY^fE0'--|#τs xvEyRin䚄S d.'|7033r*# g9n'%ђNsL =˵i4<\F1}=1;3+M6b:;:ߨR[AADPb2ёAinh[`i v;e磚 mojEE>, Y_mÎIN;YEv[eoo8w}IENDB`Ext/KeePass.config.xml0000664000000000000000000000037412235417450013646 0ustar rootroot true Ext/KeePassMsi/0000775000000000000000000000000013214520260012315 5ustar rootrootExt/KeePassMsi/KeePassMsi.sln0000664000000000000000000000167313141612644015055 0ustar rootroot Microsoft Visual Studio Solution File, Format Version 12.00 # Visual Studio 15 VisualStudioVersion = 15.0.26430.16 MinimumVisualStudioVersion = 10.0.40219.1 Project("{54435603-DBB4-11D2-8724-00A0C9A8B90C}") = "KeePassMsi", "KeePassMsi.vdproj", "{C4135368-4A84-4924-B5CE-82B18FAADFD4}" EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Default = Debug|Default Release|Default = Release|Default EndGlobalSection GlobalSection(ProjectConfigurationPlatforms) = postSolution {C4135368-4A84-4924-B5CE-82B18FAADFD4}.Debug|Default.ActiveCfg = Debug {C4135368-4A84-4924-B5CE-82B18FAADFD4}.Debug|Default.Build.0 = Debug {C4135368-4A84-4924-B5CE-82B18FAADFD4}.Release|Default.ActiveCfg = Release {C4135368-4A84-4924-B5CE-82B18FAADFD4}.Release|Default.Build.0 = Release EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE EndGlobalSection EndGlobal Ext/KeePassMsi/KeePassMsi.vdproj0000664000000000000000000013735213225117416015571 0ustar rootroot"DeployProject" { "VSVersion" = "3:800" "ProjectType" = "8:{978C614F-708E-4E1A-B201-565925725DBA}" "IsWebType" = "8:FALSE" "ProjectName" = "8:KeePassMsi" "LanguageId" = "3:1033" "CodePage" = "3:1252" "UILanguageId" = "3:1033" "SccProjectName" = "8:" "SccLocalPath" = "8:" "SccAuxPath" = "8:" "SccProvider" = "8:" "Hierarchy" { "Entry" { "MsmKey" = "8:_092CBAA0A0914855A6FDE86CD482FD39" "OwnerKey" = "8:_UNDEFINED" "MsmSig" = "8:_UNDEFINED" } "Entry" { "MsmKey" = "8:_1FC6DBE255BB4666BC86F87988C881A0" "OwnerKey" = "8:_UNDEFINED" "MsmSig" = "8:_UNDEFINED" } "Entry" { "MsmKey" = "8:_22BA2527C1AC43E5B61F88AA217DF2E2" "OwnerKey" = "8:_UNDEFINED" "MsmSig" = "8:_UNDEFINED" } "Entry" { "MsmKey" = "8:_2A0C1DA9803A47F5842BC63F7CC0FEBC" "OwnerKey" = "8:_UNDEFINED" "MsmSig" = "8:_UNDEFINED" } "Entry" { "MsmKey" = "8:_442863E39B69D2D0EE0DFF0823AF5611" "OwnerKey" = "8:_8C05ADB649434D7892E36709EBDED4CC" "MsmSig" = "8:_UNDEFINED" } "Entry" { "MsmKey" = "8:_46CD3E3687454981A64BCF41FB207030" "OwnerKey" = "8:_UNDEFINED" "MsmSig" = "8:_UNDEFINED" } "Entry" { "MsmKey" = "8:_4F601F0D55964BDF9EF93A6D6B3FFD4F" "OwnerKey" = "8:_UNDEFINED" "MsmSig" = "8:_UNDEFINED" } "Entry" { "MsmKey" = "8:_71B4B6B66D7B48478B4C9A237064F77A" "OwnerKey" = "8:_UNDEFINED" "MsmSig" = "8:_UNDEFINED" } "Entry" { "MsmKey" = "8:_8C05ADB649434D7892E36709EBDED4CC" "OwnerKey" = "8:_UNDEFINED" "MsmSig" = "8:_UNDEFINED" } "Entry" { "MsmKey" = "8:_9473A3E101A1441894F0176A3A583551" "OwnerKey" = "8:_UNDEFINED" "MsmSig" = "8:_UNDEFINED" } "Entry" { "MsmKey" = "8:_9BCEB0D341714092A0374B47DA8238DD" "OwnerKey" = "8:_UNDEFINED" "MsmSig" = "8:_UNDEFINED" } "Entry" { "MsmKey" = "8:_A13624F7FFFD46FFA9EA3509BBB398FD" "OwnerKey" = "8:_UNDEFINED" "MsmSig" = "8:_UNDEFINED" } "Entry" { "MsmKey" = "8:_A2213A2E9D2B46D9ABB41BDE043EB6B1" "OwnerKey" = "8:_UNDEFINED" "MsmSig" = "8:_UNDEFINED" } "Entry" { "MsmKey" = "8:_B354F7D87A064AA0BBC71E3926639333" "OwnerKey" = "8:_UNDEFINED" "MsmSig" = "8:_UNDEFINED" } "Entry" { "MsmKey" = "8:_C34738027450488E935C153E9FD57296" "OwnerKey" = "8:_UNDEFINED" "MsmSig" = "8:_UNDEFINED" } "Entry" { "MsmKey" = "8:_C4F8814F844C43EE8C9F5B662182B11A" "OwnerKey" = "8:_UNDEFINED" "MsmSig" = "8:_UNDEFINED" } "Entry" { "MsmKey" = "8:_UNDEFINED" "OwnerKey" = "8:_8C05ADB649434D7892E36709EBDED4CC" "MsmSig" = "8:_UNDEFINED" } "Entry" { "MsmKey" = "8:_UNDEFINED" "OwnerKey" = "8:_442863E39B69D2D0EE0DFF0823AF5611" "MsmSig" = "8:_UNDEFINED" } "Entry" { "MsmKey" = "8:_UNDEFINED" "OwnerKey" = "8:_C4F8814F844C43EE8C9F5B662182B11A" "MsmSig" = "8:_UNDEFINED" } } "Configurations" { "Debug" { "DisplayName" = "8:Debug" "IsDebugOnly" = "11:TRUE" "IsReleaseOnly" = "11:FALSE" "OutputFilename" = "8:..\\..\\Build\\KeePassMsi\\Debug\\KeePass.msi" "PackageFilesAs" = "3:2" "PackageFileSize" = "3:-2147483648" "CabType" = "3:1" "Compression" = "3:3" "SignOutput" = "11:FALSE" "CertificateFile" = "8:" "PrivateKeyFile" = "8:" "TimeStampServer" = "8:" "InstallerBootstrapper" = "3:2" "BootstrapperCfg:{63ACBE69-63AA-4F98-B2B6-99F9E24495F2}" { "Enabled" = "11:FALSE" "PromptEnabled" = "11:TRUE" "PrerequisitesLocation" = "2:1" "Url" = "8:" "ComponentsUrl" = "8:" "Items" { } } } "Release" { "DisplayName" = "8:Release" "IsDebugOnly" = "11:FALSE" "IsReleaseOnly" = "11:TRUE" "OutputFilename" = "8:..\\..\\Build\\KeePassMsi\\Release\\KeePass.msi" "PackageFilesAs" = "3:2" "PackageFileSize" = "3:-2147483648" "CabType" = "3:1" "Compression" = "3:3" "SignOutput" = "11:FALSE" "CertificateFile" = "8:" "PrivateKeyFile" = "8:" "TimeStampServer" = "8:" "InstallerBootstrapper" = "3:2" "BootstrapperCfg:{63ACBE69-63AA-4F98-B2B6-99F9E24495F2}" { "Enabled" = "11:FALSE" "PromptEnabled" = "11:TRUE" "PrerequisitesLocation" = "2:1" "Url" = "8:" "ComponentsUrl" = "8:" "Items" { } } } } "Deployable" { "CustomAction" { } "DefaultFeature" { "Name" = "8:DefaultFeature" "Title" = "8:" "Description" = "8:" } "ExternalPersistence" { "LaunchCondition" { "{A06ECF26-33A3-4562-8140-9B0E340D4F24}:_B360A87AC4E743ADA53B9FFAAF1F5346" { "Name" = "8:.NET Framework" "Message" = "8:[VSDNETMSG]" "FrameworkVersion" = "8:ANY" "AllowLaterVersions" = "11:FALSE" "InstallUrl" = "8:http://go.microsoft.com/fwlink/?LinkId=76617" } } } "File" { "{1FB2D0AE-D3B9-43D4-B9DD-F88EC61E35DE}:_092CBAA0A0914855A6FDE86CD482FD39" { "SourcePath" = "8:..\\..\\Build\\KeePass_Distrib\\XSL\\KDBX_Tabular_HTML.xsl" "TargetName" = "8:KDBX_Tabular_HTML.xsl" "Tag" = "8:" "Folder" = "8:_76A04227854C4619BBADCC3E5C2829AE" "Condition" = "8:" "Transitive" = "11:FALSE" "Vital" = "11:TRUE" "ReadOnly" = "11:FALSE" "Hidden" = "11:FALSE" "System" = "11:FALSE" "Permanent" = "11:FALSE" "SharedLegacy" = "11:FALSE" "PackageAs" = "3:1" "Register" = "3:1" "Exclude" = "11:FALSE" "IsDependency" = "11:FALSE" "IsolateTo" = "8:" } "{1FB2D0AE-D3B9-43D4-B9DD-F88EC61E35DE}:_1FC6DBE255BB4666BC86F87988C881A0" { "SourcePath" = "8:..\\..\\Build\\KeePass_Distrib\\XSL\\KDBX_DetailsLight_HTML.xsl" "TargetName" = "8:KDBX_DetailsLight_HTML.xsl" "Tag" = "8:" "Folder" = "8:_76A04227854C4619BBADCC3E5C2829AE" "Condition" = "8:" "Transitive" = "11:FALSE" "Vital" = "11:TRUE" "ReadOnly" = "11:FALSE" "Hidden" = "11:FALSE" "System" = "11:FALSE" "Permanent" = "11:FALSE" "SharedLegacy" = "11:FALSE" "PackageAs" = "3:1" "Register" = "3:1" "Exclude" = "11:FALSE" "IsDependency" = "11:FALSE" "IsolateTo" = "8:" } "{1FB2D0AE-D3B9-43D4-B9DD-F88EC61E35DE}:_22BA2527C1AC43E5B61F88AA217DF2E2" { "SourcePath" = "8:..\\..\\Build\\KeePass_Distrib\\KeePassLibC32.dll" "TargetName" = "8:KeePassLibC32.dll" "Tag" = "8:" "Folder" = "8:_02F929C52C1D41D29CB593270C6D1DC6" "Condition" = "8:" "Transitive" = "11:FALSE" "Vital" = "11:TRUE" "ReadOnly" = "11:FALSE" "Hidden" = "11:FALSE" "System" = "11:FALSE" "Permanent" = "11:FALSE" "SharedLegacy" = "11:FALSE" "PackageAs" = "3:1" "Register" = "3:1" "Exclude" = "11:FALSE" "IsDependency" = "11:FALSE" "IsolateTo" = "8:" } "{1FB2D0AE-D3B9-43D4-B9DD-F88EC61E35DE}:_2A0C1DA9803A47F5842BC63F7CC0FEBC" { "SourcePath" = "8:..\\..\\Build\\KeePass_Distrib\\KeePass.chm" "TargetName" = "8:KeePass.chm" "Tag" = "8:" "Folder" = "8:_02F929C52C1D41D29CB593270C6D1DC6" "Condition" = "8:" "Transitive" = "11:FALSE" "Vital" = "11:TRUE" "ReadOnly" = "11:FALSE" "Hidden" = "11:FALSE" "System" = "11:FALSE" "Permanent" = "11:FALSE" "SharedLegacy" = "11:FALSE" "PackageAs" = "3:1" "Register" = "3:1" "Exclude" = "11:FALSE" "IsDependency" = "11:FALSE" "IsolateTo" = "8:" } "{9F6F8455-1EF1-4B85-886A-4223BCC8E7F7}:_442863E39B69D2D0EE0DFF0823AF5611" { "AssemblyRegister" = "3:1" "AssemblyIsInGAC" = "11:FALSE" "AssemblyAsmDisplayName" = "8:KeePass, Version=2.38.0.21288, Culture=neutral, PublicKeyToken=fed2ed7716aecf5c, processorArchitecture=MSIL" "ScatterAssemblies" { } "SourcePath" = "8:KeePass.EXE" "TargetName" = "8:" "Tag" = "8:" "Folder" = "8:_02F929C52C1D41D29CB593270C6D1DC6" "Condition" = "8:" "Transitive" = "11:FALSE" "Vital" = "11:TRUE" "ReadOnly" = "11:FALSE" "Hidden" = "11:FALSE" "System" = "11:FALSE" "Permanent" = "11:FALSE" "SharedLegacy" = "11:FALSE" "PackageAs" = "3:1" "Register" = "3:1" "Exclude" = "11:TRUE" "IsDependency" = "11:TRUE" "IsolateTo" = "8:" } "{1FB2D0AE-D3B9-43D4-B9DD-F88EC61E35DE}:_46CD3E3687454981A64BCF41FB207030" { "SourcePath" = "8:..\\..\\KeePass\\KeePass.ico" "TargetName" = "8:KeePassIcon.ico" "Tag" = "8:" "Folder" = "8:_02F929C52C1D41D29CB593270C6D1DC6" "Condition" = "8:" "Transitive" = "11:FALSE" "Vital" = "11:TRUE" "ReadOnly" = "11:FALSE" "Hidden" = "11:FALSE" "System" = "11:FALSE" "Permanent" = "11:FALSE" "SharedLegacy" = "11:FALSE" "PackageAs" = "3:1" "Register" = "3:1" "Exclude" = "11:FALSE" "IsDependency" = "11:FALSE" "IsolateTo" = "8:" } "{1FB2D0AE-D3B9-43D4-B9DD-F88EC61E35DE}:_4F601F0D55964BDF9EF93A6D6B3FFD4F" { "SourcePath" = "8:..\\..\\Build\\KeePass_Distrib\\XSL\\KDBX_DetailsFull_HTML.xsl" "TargetName" = "8:KDBX_DetailsFull_HTML.xsl" "Tag" = "8:" "Folder" = "8:_76A04227854C4619BBADCC3E5C2829AE" "Condition" = "8:" "Transitive" = "11:FALSE" "Vital" = "11:TRUE" "ReadOnly" = "11:FALSE" "Hidden" = "11:FALSE" "System" = "11:FALSE" "Permanent" = "11:FALSE" "SharedLegacy" = "11:FALSE" "PackageAs" = "3:1" "Register" = "3:1" "Exclude" = "11:FALSE" "IsDependency" = "11:FALSE" "IsolateTo" = "8:" } "{1FB2D0AE-D3B9-43D4-B9DD-F88EC61E35DE}:_71B4B6B66D7B48478B4C9A237064F77A" { "SourcePath" = "8:..\\..\\Build\\KeePass_Distrib\\KeePass.exe.config" "TargetName" = "8:KeePass.exe.config" "Tag" = "8:" "Folder" = "8:_02F929C52C1D41D29CB593270C6D1DC6" "Condition" = "8:" "Transitive" = "11:FALSE" "Vital" = "11:TRUE" "ReadOnly" = "11:FALSE" "Hidden" = "11:FALSE" "System" = "11:FALSE" "Permanent" = "11:FALSE" "SharedLegacy" = "11:FALSE" "PackageAs" = "3:1" "Register" = "3:1" "Exclude" = "11:FALSE" "IsDependency" = "11:FALSE" "IsolateTo" = "8:" } "{9F6F8455-1EF1-4B85-886A-4223BCC8E7F7}:_8C05ADB649434D7892E36709EBDED4CC" { "AssemblyRegister" = "3:1" "AssemblyIsInGAC" = "11:FALSE" "AssemblyAsmDisplayName" = "8:KeePass.XmlSerializers, Version=2.38.0.21288, Culture=neutral, PublicKeyToken=fed2ed7716aecf5c, processorArchitecture=MSIL" "ScatterAssemblies" { "_8C05ADB649434D7892E36709EBDED4CC" { "Name" = "8:KeePass.XmlSerializers.dll" "Attributes" = "3:512" } } "SourcePath" = "8:..\\..\\Build\\KeePass_Distrib\\KeePass.XmlSerializers.dll" "TargetName" = "8:" "Tag" = "8:" "Folder" = "8:_02F929C52C1D41D29CB593270C6D1DC6" "Condition" = "8:" "Transitive" = "11:FALSE" "Vital" = "11:TRUE" "ReadOnly" = "11:FALSE" "Hidden" = "11:FALSE" "System" = "11:FALSE" "Permanent" = "11:FALSE" "SharedLegacy" = "11:FALSE" "PackageAs" = "3:1" "Register" = "3:1" "Exclude" = "11:FALSE" "IsDependency" = "11:FALSE" "IsolateTo" = "8:" } "{1FB2D0AE-D3B9-43D4-B9DD-F88EC61E35DE}:_9473A3E101A1441894F0176A3A583551" { "SourcePath" = "8:..\\..\\Build\\KeePass_Distrib\\XSL\\KDBX_Common.xsl" "TargetName" = "8:KDBX_Common.xsl" "Tag" = "8:" "Folder" = "8:_76A04227854C4619BBADCC3E5C2829AE" "Condition" = "8:" "Transitive" = "11:FALSE" "Vital" = "11:TRUE" "ReadOnly" = "11:FALSE" "Hidden" = "11:FALSE" "System" = "11:FALSE" "Permanent" = "11:FALSE" "SharedLegacy" = "11:FALSE" "PackageAs" = "3:1" "Register" = "3:1" "Exclude" = "11:FALSE" "IsDependency" = "11:FALSE" "IsolateTo" = "8:" } "{1FB2D0AE-D3B9-43D4-B9DD-F88EC61E35DE}:_9BCEB0D341714092A0374B47DA8238DD" { "SourcePath" = "8:..\\..\\Build\\KeePass_Distrib\\KeePassLibC64.dll" "TargetName" = "8:KeePassLibC64.dll" "Tag" = "8:" "Folder" = "8:_02F929C52C1D41D29CB593270C6D1DC6" "Condition" = "8:" "Transitive" = "11:FALSE" "Vital" = "11:TRUE" "ReadOnly" = "11:FALSE" "Hidden" = "11:FALSE" "System" = "11:FALSE" "Permanent" = "11:FALSE" "SharedLegacy" = "11:FALSE" "PackageAs" = "3:1" "Register" = "3:1" "Exclude" = "11:FALSE" "IsDependency" = "11:FALSE" "IsolateTo" = "8:" } "{1FB2D0AE-D3B9-43D4-B9DD-F88EC61E35DE}:_A13624F7FFFD46FFA9EA3509BBB398FD" { "SourcePath" = "8:..\\..\\Build\\KeePass_Distrib\\KeePass.config.xml" "TargetName" = "8:KeePass.config.xml" "Tag" = "8:" "Folder" = "8:_02F929C52C1D41D29CB593270C6D1DC6" "Condition" = "8:" "Transitive" = "11:FALSE" "Vital" = "11:TRUE" "ReadOnly" = "11:FALSE" "Hidden" = "11:FALSE" "System" = "11:FALSE" "Permanent" = "11:FALSE" "SharedLegacy" = "11:FALSE" "PackageAs" = "3:1" "Register" = "3:1" "Exclude" = "11:FALSE" "IsDependency" = "11:FALSE" "IsolateTo" = "8:" } "{1FB2D0AE-D3B9-43D4-B9DD-F88EC61E35DE}:_A2213A2E9D2B46D9ABB41BDE043EB6B1" { "SourcePath" = "8:..\\..\\Build\\KeePass_Distrib\\XSL\\KDBX_PasswordsOnly_TXT.xsl" "TargetName" = "8:KDBX_PasswordsOnly_TXT.xsl" "Tag" = "8:" "Folder" = "8:_76A04227854C4619BBADCC3E5C2829AE" "Condition" = "8:" "Transitive" = "11:FALSE" "Vital" = "11:TRUE" "ReadOnly" = "11:FALSE" "Hidden" = "11:FALSE" "System" = "11:FALSE" "Permanent" = "11:FALSE" "SharedLegacy" = "11:FALSE" "PackageAs" = "3:1" "Register" = "3:1" "Exclude" = "11:FALSE" "IsDependency" = "11:FALSE" "IsolateTo" = "8:" } "{1FB2D0AE-D3B9-43D4-B9DD-F88EC61E35DE}:_B354F7D87A064AA0BBC71E3926639333" { "SourcePath" = "8:..\\..\\Build\\KeePass_Distrib\\ShInstUtil.exe" "TargetName" = "8:ShInstUtil.exe" "Tag" = "8:" "Folder" = "8:_02F929C52C1D41D29CB593270C6D1DC6" "Condition" = "8:" "Transitive" = "11:FALSE" "Vital" = "11:TRUE" "ReadOnly" = "11:FALSE" "Hidden" = "11:FALSE" "System" = "11:FALSE" "Permanent" = "11:FALSE" "SharedLegacy" = "11:FALSE" "PackageAs" = "3:1" "Register" = "3:1" "Exclude" = "11:FALSE" "IsDependency" = "11:FALSE" "IsolateTo" = "8:" } "{1FB2D0AE-D3B9-43D4-B9DD-F88EC61E35DE}:_C34738027450488E935C153E9FD57296" { "SourcePath" = "8:..\\..\\Build\\KeePass_Distrib\\License.txt" "TargetName" = "8:License.txt" "Tag" = "8:" "Folder" = "8:_02F929C52C1D41D29CB593270C6D1DC6" "Condition" = "8:" "Transitive" = "11:FALSE" "Vital" = "11:TRUE" "ReadOnly" = "11:FALSE" "Hidden" = "11:FALSE" "System" = "11:FALSE" "Permanent" = "11:FALSE" "SharedLegacy" = "11:FALSE" "PackageAs" = "3:1" "Register" = "3:1" "Exclude" = "11:FALSE" "IsDependency" = "11:FALSE" "IsolateTo" = "8:" } "{9F6F8455-1EF1-4B85-886A-4223BCC8E7F7}:_C4F8814F844C43EE8C9F5B662182B11A" { "AssemblyRegister" = "3:1" "AssemblyIsInGAC" = "11:FALSE" "AssemblyAsmDisplayName" = "8:KeePass, Version=2.38.0.21288, Culture=neutral, PublicKeyToken=fed2ed7716aecf5c, processorArchitecture=MSIL" "ScatterAssemblies" { "_C4F8814F844C43EE8C9F5B662182B11A" { "Name" = "8:KeePass.exe" "Attributes" = "3:512" } } "SourcePath" = "8:..\\..\\Build\\KeePass_Distrib\\KeePass.exe" "TargetName" = "8:" "Tag" = "8:" "Folder" = "8:_02F929C52C1D41D29CB593270C6D1DC6" "Condition" = "8:" "Transitive" = "11:FALSE" "Vital" = "11:TRUE" "ReadOnly" = "11:FALSE" "Hidden" = "11:FALSE" "System" = "11:FALSE" "Permanent" = "11:FALSE" "SharedLegacy" = "11:FALSE" "PackageAs" = "3:1" "Register" = "3:1" "Exclude" = "11:FALSE" "IsDependency" = "11:FALSE" "IsolateTo" = "8:" } } "FileType" { "{5EB83D71-FA18-4901-BE56-DE22E13CC478}:_7BABCD00223047B785A71DFBB11D9B48" { "Name" = "8:KeePass Database" "Description" = "8:" "Extensions" = "8:kdbx" "MIME" = "8:" "Icon" = "8:_46CD3E3687454981A64BCF41FB207030" "IconIndex" = "3:0" "Command" { "Command" = "8:_C4F8814F844C43EE8C9F5B662182B11A" } "Verbs" { "{95C0C507-CBF0-42B8-B119-07219E384A4A}:_33B042E70FCE442EB6C1AD610694DFD5" { "Command" = "8:&Open" "Verb" = "8:open" "Arguments" = "8:\"%1\"" "Order" = "3:0" } } } } "Folder" { "{3C67513D-01DD-4637-8A68-80971EB9504F}:_02F929C52C1D41D29CB593270C6D1DC6" { "DefaultLocation" = "8:[ProgramFilesFolder]KeePass2x" "Name" = "8:#1925" "AlwaysCreate" = "11:FALSE" "Condition" = "8:" "Transitive" = "11:FALSE" "Property" = "8:TARGETDIR" "Folders" { "{9EF0B969-E518-4E46-987F-47570745A589}:_650CFBE3ACEC49F281DA5C781D164F2B" { "Name" = "8:Languages" "AlwaysCreate" = "11:TRUE" "Condition" = "8:" "Transitive" = "11:FALSE" "Property" = "8:_A866B7F9250C42C49D83E0C115F4E016" "Folders" { } } "{9EF0B969-E518-4E46-987F-47570745A589}:_76A04227854C4619BBADCC3E5C2829AE" { "Name" = "8:XSL" "AlwaysCreate" = "11:FALSE" "Condition" = "8:" "Transitive" = "11:FALSE" "Property" = "8:_04DFBD4168EF4BFD8825BA692441B287" "Folders" { } } "{9EF0B969-E518-4E46-987F-47570745A589}:_F7FA774F4B0E4A3FB0F1FA4743CF06C8" { "Name" = "8:Plugins" "AlwaysCreate" = "11:TRUE" "Condition" = "8:" "Transitive" = "11:FALSE" "Property" = "8:_83A2FA647E5D4F68A9F210FC7878D245" "Folders" { } } } } "{1525181F-901A-416C-8A58-119130FE478E}:_8285FAA6D5774714AB190FF7FA5604FB" { "Name" = "8:#1919" "AlwaysCreate" = "11:FALSE" "Condition" = "8:" "Transitive" = "11:FALSE" "Property" = "8:ProgramMenuFolder" "Folders" { "{9EF0B969-E518-4E46-987F-47570745A589}:_C5518630440D4460BD3C92160ACB1712" { "Name" = "8:KeePass" "AlwaysCreate" = "11:FALSE" "Condition" = "8:" "Transitive" = "11:FALSE" "Property" = "8:_71CA578B76DC40C6A8B7FBD159CDBC1A" "Folders" { } } } } "{1525181F-901A-416C-8A58-119130FE478E}:_CD17966DB7404B60877D38C1EE806E5B" { "Name" = "8:#1916" "AlwaysCreate" = "11:FALSE" "Condition" = "8:" "Transitive" = "11:FALSE" "Property" = "8:DesktopFolder" "Folders" { } } } "LaunchCondition" { } "Locator" { } "MsiBootstrapper" { "LangId" = "3:1033" "RequiresElevation" = "11:FALSE" } "Product" { "Name" = "8:Microsoft Visual Studio" "ProductName" = "8:KeePass 2.38" "ProductCode" = "8:{E75B2CF0-38DA-4DFE-9462-9B6B8B7C30A5}" "PackageCode" = "8:{0479AFBF-1E00-48CA-BAC3-78BD8CD454D2}" "UpgradeCode" = "8:{F2F19898-4F86-4940-9BFA-426574CE03E1}" "AspNetVersion" = "8:4.0.30319.0" "RestartWWWService" = "11:FALSE" "RemovePreviousVersions" = "11:TRUE" "DetectNewerInstalledVersion" = "11:TRUE" "InstallAllUsers" = "11:TRUE" "ProductVersion" = "8:2.38.0" "Manufacturer" = "8:Dominik Reichl" "ARPHELPTELEPHONE" = "8:" "ARPHELPLINK" = "8:https://keepass.info/" "Title" = "8:KeePass Setup" "Subject" = "8:KeePass Password Safe" "ARPCONTACT" = "8:Dominik Reichl" "Keywords" = "8:" "ARPCOMMENTS" = "8:" "ARPURLINFOABOUT" = "8:https://keepass.info/" "ARPPRODUCTICON" = "8:_46CD3E3687454981A64BCF41FB207030" "ARPIconIndex" = "3:0" "SearchPath" = "8:" "UseSystemSearchPath" = "11:TRUE" "TargetPlatform" = "3:0" "PreBuildEvent" = "8:" "PostBuildEvent" = "8:" "RunPostBuildEvent" = "3:0" } "Registry" { "HKLM" { "Keys" { "{60EA8692-D2D5-43EB-80DC-7906BF13D6EF}:_C5EBC4EA7F4A4F02BD195E1047CD2D03" { "Name" = "8:Software" "Condition" = "8:" "AlwaysCreate" = "11:FALSE" "DeleteAtUninstall" = "11:FALSE" "Transitive" = "11:FALSE" "Keys" { "{60EA8692-D2D5-43EB-80DC-7906BF13D6EF}:_8408784FC07F4908A396060A977864FA" { "Name" = "8:[Manufacturer]" "Condition" = "8:" "AlwaysCreate" = "11:FALSE" "DeleteAtUninstall" = "11:FALSE" "Transitive" = "11:FALSE" "Keys" { } "Values" { } } } "Values" { } } } } "HKCU" { "Keys" { "{60EA8692-D2D5-43EB-80DC-7906BF13D6EF}:_262C9049A6B143369D448CE3C70D8EE5" { "Name" = "8:Software" "Condition" = "8:" "AlwaysCreate" = "11:FALSE" "DeleteAtUninstall" = "11:FALSE" "Transitive" = "11:FALSE" "Keys" { "{60EA8692-D2D5-43EB-80DC-7906BF13D6EF}:_22DFF8BEC1B745DF969ABE72FF0B968A" { "Name" = "8:[Manufacturer]" "Condition" = "8:" "AlwaysCreate" = "11:FALSE" "DeleteAtUninstall" = "11:FALSE" "Transitive" = "11:FALSE" "Keys" { } "Values" { } } } "Values" { } } } } "HKCR" { "Keys" { } } "HKU" { "Keys" { } } "HKPU" { "Keys" { } } } "Sequences" { } "Shortcut" { "{970C0BB2-C7D0-45D7-ABFA-7EC378858BC0}:_B9061F34EC304CA08E34DD695F741D2D" { "Name" = "8:KeePass User Manual" "Arguments" = "8:" "Description" = "8:" "ShowCmd" = "3:1" "IconIndex" = "3:0" "Transitive" = "11:FALSE" "Target" = "8:_2A0C1DA9803A47F5842BC63F7CC0FEBC" "Folder" = "8:_C5518630440D4460BD3C92160ACB1712" "WorkingFolder" = "8:_02F929C52C1D41D29CB593270C6D1DC6" "Icon" = "8:" "Feature" = "8:" } "{970C0BB2-C7D0-45D7-ABFA-7EC378858BC0}:_D4CD5274BA6C4E25937C7C422285FBCB" { "Name" = "8:KeePass" "Arguments" = "8:" "Description" = "8:" "ShowCmd" = "3:1" "IconIndex" = "3:0" "Transitive" = "11:FALSE" "Target" = "8:_C4F8814F844C43EE8C9F5B662182B11A" "Folder" = "8:_CD17966DB7404B60877D38C1EE806E5B" "WorkingFolder" = "8:_02F929C52C1D41D29CB593270C6D1DC6" "Icon" = "8:_46CD3E3687454981A64BCF41FB207030" "Feature" = "8:" } "{970C0BB2-C7D0-45D7-ABFA-7EC378858BC0}:_E64C38ED6AED4249B632955704092C33" { "Name" = "8:KeePass" "Arguments" = "8:" "Description" = "8:" "ShowCmd" = "3:1" "IconIndex" = "3:0" "Transitive" = "11:FALSE" "Target" = "8:_C4F8814F844C43EE8C9F5B662182B11A" "Folder" = "8:_C5518630440D4460BD3C92160ACB1712" "WorkingFolder" = "8:_02F929C52C1D41D29CB593270C6D1DC6" "Icon" = "8:_46CD3E3687454981A64BCF41FB207030" "Feature" = "8:" } } "UserInterface" { "{2479F3F5-0309-486D-8047-8187E2CE5BA0}:_0AEBAAEF47704E8B9A01C6CB1E62FDBD" { "UseDynamicProperties" = "11:FALSE" "IsDependency" = "11:FALSE" "SourcePath" = "8:\\VsdUserInterface.wim" } "{DF760B10-853B-4699-99F2-AFF7185B4A62}:_0CDFE41F4D01459286E7AFC52A7A9277" { "Name" = "8:#1900" "Sequence" = "3:1" "Attributes" = "3:1" "Dialogs" { "{688940B3-5CA9-4162-8DEE-2993FA9D8CBC}:_5861FDDB998C4FD1B1873B4342542B84" { "Sequence" = "3:200" "DisplayName" = "8:Installation Folder" "UseDynamicProperties" = "11:TRUE" "IsDependency" = "11:FALSE" "SourcePath" = "8:\\VsdFolderDlg.wid" "Properties" { "BannerBitmap" { "Name" = "8:BannerBitmap" "DisplayName" = "8:#1001" "Description" = "8:#1101" "Type" = "3:8" "ContextData" = "8:Bitmap" "Attributes" = "3:4" "Setting" = "3:1" "UsePlugInResources" = "11:TRUE" } "InstallAllUsersVisible" { "Name" = "8:InstallAllUsersVisible" "DisplayName" = "8:#1059" "Description" = "8:#1159" "Type" = "3:5" "ContextData" = "8:1;True=1;False=0" "Attributes" = "3:0" "Setting" = "3:0" "Value" = "3:1" "DefaultValue" = "3:1" "UsePlugInResources" = "11:TRUE" } } } "{688940B3-5CA9-4162-8DEE-2993FA9D8CBC}:_7FC84AF39FDF4EC4BC98AB5AA8A2C381" { "Sequence" = "3:100" "DisplayName" = "8:Welcome" "UseDynamicProperties" = "11:TRUE" "IsDependency" = "11:FALSE" "SourcePath" = "8:\\VsdWelcomeDlg.wid" "Properties" { "BannerBitmap" { "Name" = "8:BannerBitmap" "DisplayName" = "8:#1001" "Description" = "8:#1101" "Type" = "3:8" "ContextData" = "8:Bitmap" "Attributes" = "3:4" "Setting" = "3:1" "UsePlugInResources" = "11:TRUE" } "CopyrightWarning" { "Name" = "8:CopyrightWarning" "DisplayName" = "8:#1002" "Description" = "8:#1102" "Type" = "3:3" "ContextData" = "8:" "Attributes" = "3:0" "Setting" = "3:2" "Value" = "8:KeePass: Copyright (C) 2003-2018 Dominik Reichl. The software is distributed under the terms of the GNU General Public License version 2 or later." "DefaultValue" = "8:#1202" "UsePlugInResources" = "11:TRUE" } "Welcome" { "Name" = "8:Welcome" "DisplayName" = "8:#1003" "Description" = "8:#1103" "Type" = "3:3" "ContextData" = "8:" "Attributes" = "3:0" "Setting" = "3:1" "Value" = "8:#1203" "DefaultValue" = "8:#1203" "UsePlugInResources" = "11:TRUE" } } } "{688940B3-5CA9-4162-8DEE-2993FA9D8CBC}:_E3C24FFA9AD74248A8825644371FB17D" { "Sequence" = "3:300" "DisplayName" = "8:Confirm Installation" "UseDynamicProperties" = "11:TRUE" "IsDependency" = "11:FALSE" "SourcePath" = "8:\\VsdConfirmDlg.wid" "Properties" { "BannerBitmap" { "Name" = "8:BannerBitmap" "DisplayName" = "8:#1001" "Description" = "8:#1101" "Type" = "3:8" "ContextData" = "8:Bitmap" "Attributes" = "3:4" "Setting" = "3:1" "UsePlugInResources" = "11:TRUE" } } } } } "{DF760B10-853B-4699-99F2-AFF7185B4A62}:_1F185A5B22D443A8A99D2A777A370EF7" { "Name" = "8:#1902" "Sequence" = "3:1" "Attributes" = "3:3" "Dialogs" { "{688940B3-5CA9-4162-8DEE-2993FA9D8CBC}:_D035303469A14DEB8F3431B84D01CC88" { "Sequence" = "3:100" "DisplayName" = "8:Finished" "UseDynamicProperties" = "11:TRUE" "IsDependency" = "11:FALSE" "SourcePath" = "8:\\VsdFinishedDlg.wid" "Properties" { "BannerBitmap" { "Name" = "8:BannerBitmap" "DisplayName" = "8:#1001" "Description" = "8:#1101" "Type" = "3:8" "ContextData" = "8:Bitmap" "Attributes" = "3:4" "Setting" = "3:1" "UsePlugInResources" = "11:TRUE" } "UpdateText" { "Name" = "8:UpdateText" "DisplayName" = "8:#1058" "Description" = "8:#1158" "Type" = "3:15" "ContextData" = "8:" "Attributes" = "3:0" "Setting" = "3:1" "Value" = "8:#1258" "DefaultValue" = "8:#1258" "UsePlugInResources" = "11:TRUE" } } } } } "{DF760B10-853B-4699-99F2-AFF7185B4A62}:_5BB2AB842E494718822EA43B48741CFF" { "Name" = "8:#1900" "Sequence" = "3:2" "Attributes" = "3:1" "Dialogs" { "{688940B3-5CA9-4162-8DEE-2993FA9D8CBC}:_267559472A6540C0ABEB216DE61BC2ED" { "Sequence" = "3:100" "DisplayName" = "8:Welcome" "UseDynamicProperties" = "11:TRUE" "IsDependency" = "11:FALSE" "SourcePath" = "8:\\VsdAdminWelcomeDlg.wid" "Properties" { "BannerBitmap" { "Name" = "8:BannerBitmap" "DisplayName" = "8:#1001" "Description" = "8:#1101" "Type" = "3:8" "ContextData" = "8:Bitmap" "Attributes" = "3:4" "Setting" = "3:1" "UsePlugInResources" = "11:TRUE" } "CopyrightWarning" { "Name" = "8:CopyrightWarning" "DisplayName" = "8:#1002" "Description" = "8:#1102" "Type" = "3:3" "ContextData" = "8:" "Attributes" = "3:0" "Setting" = "3:2" "Value" = "8:KeePass: Copyright (C) 2003-2018 Dominik Reichl. The software is distributed under the terms of the GNU General Public License version 2 or later." "DefaultValue" = "8:#1202" "UsePlugInResources" = "11:TRUE" } "Welcome" { "Name" = "8:Welcome" "DisplayName" = "8:#1003" "Description" = "8:#1103" "Type" = "3:3" "ContextData" = "8:" "Attributes" = "3:0" "Setting" = "3:1" "Value" = "8:#1203" "DefaultValue" = "8:#1203" "UsePlugInResources" = "11:TRUE" } } } "{688940B3-5CA9-4162-8DEE-2993FA9D8CBC}:_60D4F895DECE471F8ED4CDF61AA25B54" { "Sequence" = "3:300" "DisplayName" = "8:Confirm Installation" "UseDynamicProperties" = "11:TRUE" "IsDependency" = "11:FALSE" "SourcePath" = "8:\\VsdAdminConfirmDlg.wid" "Properties" { "BannerBitmap" { "Name" = "8:BannerBitmap" "DisplayName" = "8:#1001" "Description" = "8:#1101" "Type" = "3:8" "ContextData" = "8:Bitmap" "Attributes" = "3:4" "Setting" = "3:1" "UsePlugInResources" = "11:TRUE" } } } "{688940B3-5CA9-4162-8DEE-2993FA9D8CBC}:_EDDAA1C6104A4A66917AC39A88839596" { "Sequence" = "3:200" "DisplayName" = "8:Installation Folder" "UseDynamicProperties" = "11:TRUE" "IsDependency" = "11:FALSE" "SourcePath" = "8:\\VsdAdminFolderDlg.wid" "Properties" { "BannerBitmap" { "Name" = "8:BannerBitmap" "DisplayName" = "8:#1001" "Description" = "8:#1101" "Type" = "3:8" "ContextData" = "8:Bitmap" "Attributes" = "3:4" "Setting" = "3:1" "UsePlugInResources" = "11:TRUE" } } } } } "{DF760B10-853B-4699-99F2-AFF7185B4A62}:_614D264D47264F6DBD8EB6EA348B4547" { "Name" = "8:#1901" "Sequence" = "3:1" "Attributes" = "3:2" "Dialogs" { "{688940B3-5CA9-4162-8DEE-2993FA9D8CBC}:_0F1ACBA89BC94B0C976878701159E964" { "Sequence" = "3:100" "DisplayName" = "8:Progress" "UseDynamicProperties" = "11:TRUE" "IsDependency" = "11:FALSE" "SourcePath" = "8:\\VsdProgressDlg.wid" "Properties" { "BannerBitmap" { "Name" = "8:BannerBitmap" "DisplayName" = "8:#1001" "Description" = "8:#1101" "Type" = "3:8" "ContextData" = "8:Bitmap" "Attributes" = "3:4" "Setting" = "3:1" "UsePlugInResources" = "11:TRUE" } "ShowProgress" { "Name" = "8:ShowProgress" "DisplayName" = "8:#1009" "Description" = "8:#1109" "Type" = "3:5" "ContextData" = "8:1;True=1;False=0" "Attributes" = "3:0" "Setting" = "3:0" "Value" = "3:1" "DefaultValue" = "3:1" "UsePlugInResources" = "11:TRUE" } } } } } "{DF760B10-853B-4699-99F2-AFF7185B4A62}:_7FB322B6256147D2948431F3FC326234" { "Name" = "8:#1901" "Sequence" = "3:2" "Attributes" = "3:2" "Dialogs" { "{688940B3-5CA9-4162-8DEE-2993FA9D8CBC}:_92F56F1C382B496EB552FC1054921EA6" { "Sequence" = "3:100" "DisplayName" = "8:Progress" "UseDynamicProperties" = "11:TRUE" "IsDependency" = "11:FALSE" "SourcePath" = "8:\\VsdAdminProgressDlg.wid" "Properties" { "BannerBitmap" { "Name" = "8:BannerBitmap" "DisplayName" = "8:#1001" "Description" = "8:#1101" "Type" = "3:8" "ContextData" = "8:Bitmap" "Attributes" = "3:4" "Setting" = "3:1" "UsePlugInResources" = "11:TRUE" } "ShowProgress" { "Name" = "8:ShowProgress" "DisplayName" = "8:#1009" "Description" = "8:#1109" "Type" = "3:5" "ContextData" = "8:1;True=1;False=0" "Attributes" = "3:0" "Setting" = "3:0" "Value" = "3:1" "DefaultValue" = "3:1" "UsePlugInResources" = "11:TRUE" } } } } } "{2479F3F5-0309-486D-8047-8187E2CE5BA0}:_8033517407B24C178237C0535336BD6A" { "UseDynamicProperties" = "11:FALSE" "IsDependency" = "11:FALSE" "SourcePath" = "8:\\VsdBasicDialogs.wim" } "{DF760B10-853B-4699-99F2-AFF7185B4A62}:_867192A49F194B79BD5113B27E970F8F" { "Name" = "8:#1902" "Sequence" = "3:2" "Attributes" = "3:3" "Dialogs" { "{688940B3-5CA9-4162-8DEE-2993FA9D8CBC}:_07EF6E21553142618A6718FD92103A1C" { "Sequence" = "3:100" "DisplayName" = "8:Finished" "UseDynamicProperties" = "11:TRUE" "IsDependency" = "11:FALSE" "SourcePath" = "8:\\VsdAdminFinishedDlg.wid" "Properties" { "BannerBitmap" { "Name" = "8:BannerBitmap" "DisplayName" = "8:#1001" "Description" = "8:#1101" "Type" = "3:8" "ContextData" = "8:Bitmap" "Attributes" = "3:4" "Setting" = "3:1" "UsePlugInResources" = "11:TRUE" } } } } } } "MergeModule" { } "ProjectOutput" { } } } Ext/Images_Client_16/0000775000000000000000000000000012666316542013342 5ustar rootrootExt/Images_Client_16/C00_Password.png0000664000000000000000000000166510132777112016252 0ustar rootrootPNG  IHDRagAMA7tEXtSoftwareAdobe ImageReadyqe<GIDATxblUgؙ1|&u1[V3e@, 8ߌ 1*?)YfPd2cY'V/ u4SFIfk|ee:;ÅG5ew+L~#3 fbd`ddڣ.GVp]|vn%@OA  wJx T&KQ? ?}uϟ eؘ կ É_ Dd%ąĄxZ0~e`$4ňH2}Ϸ+ o3=foG_?;[M hN6pedffP }``cfd)c.)D ̼| O/3([ , _2  8 >20|)0A ajfb`e``dhߠ 6SSAVFV!a@M|@ ivY031FX3? r "@q20t6d3q3Ͽxxx~l@SuGZɳkϗ ess? mdge` ߌNHvv"_?*`{޽k@+ x@1laSDDb50\ŀrz@@H`2@IENDB`Ext/Images_Client_16/C26_FileSave.png0000664000000000000000000000160210133443104016135 0ustar rootrootPNG  IHDRagAMA7tEXtSoftwareAdobe ImageReadyqe<IDATxb?Z\~11004@az{>r /_/ ğ?/ (AU'7[*xvkwѰA !ŪDZ?e>,q6cd``b;?# 7P7L@^>A.~baFF@El@H8L@ 8@`db2Clg`27P32102C ؘA 85yh.'T@Af?mF#P߿ /! _??3|_w3WY|v@À/$Z33;?0FX fc7 ˯ L _12 F~3L`3e`gf@Aߟ@ge0w_S&s}6@qr220Xjb_P4 Vq2pbPt67;#ODy^- 4j@A4   X Y3|AT/F &l| ٘0ewt30ДU>ad VHL؀ /6}3p]Fh"bFWp|afxo參 KC4>Sg%IENDB`Ext/Images_Client_16/C15_Scanner.png0000664000000000000000000000207610127240340016034 0ustar rootrootPNG  IHDRagAMA7tEXtSoftwareAdobe ImageReadyqe<IDATxbLJd2tgxp+b6c`ddd`aaex͋םVVVd#ej89tϟ_W`!X3;;÷o=TU\?|7_3())3yʕ z  f۷/1\tŋG ߿fx۷h i; @(r]r@S0TL$T޽}PUVahO@pq1 (\rߎ;  B _f3f07P ϯ- _h0/?޽ X@ß?~bd@qk^s޼x UY#\:Y @,7{iԙ 10`y3{d9Y-Td1s (~e4AXEJ;x910p0feaך6^CCSn IIv_ ``𖝉3+o&x{. 3WZrox3o?pի<>}:@1̜ lЏo?:e 9)庬WWl{?jDCWX_BB|„6 a @@Ƞ + Je a1 ?QSSo ;;g(`^w3XIENDB`Ext/Images_Client_16/C37_KPercentage.png0000664000000000000000000000212310125245344016637 0ustar rootrootPNG  IHDRagAMA7tEXtSoftwareAdobe ImageReadyqe<IDATxb?% L3i->}aSy_xqť# Ne2-PPNëצR(P -{c ~S/'xom Rq/>꿤K@@ X B%$3y tCahq &韉.6J_!×;GD̢lc̙ϰ} "b0p |uMwm6qd`aanb &2 I RL;W[g$Vd/_~3 v@]`4JX5T̚KNSA@R /3331Pk@ bc P}K_ 1H02 <{pA𕉙1K@ҽ `/؀wNȠ%*}_0\8 XXYΝ? [!Hl@A xʐu%I6'+ffx} @33r0 I Lg &(19@}ʠn3*>o51{ 7^VvvHx@1ć g b[ J 2J j"  l| < MOQL b@dbdf [ ?g #vya1 0WGDK!!ABA? /8*節  ?~gx L 8~{qi/J2Xf&$&?~ Nb  / ?329ˏʊ`|f>LCObs㻞$Xd"fb?@1R >IUIENDB`Ext/Images_Client_16/C33_Run.png0000664000000000000000000000173310133442666015222 0ustar rootrootPNG  IHDRagAMA7tEXtSoftwareAdobe ImageReadyqe<mIDATxb?% X@^^\\ ^b`g`a)/ 4%%}xy Ο9SߩL@} ̤2b`97+J  w @`%&a`g&ii)ni#f g~޼_0Ȳ>]5H/@ `/+Lll b>~a{~ e58-x3H/@]͛lpO_~0KF c޿cf_=P lk7=~m.R ώdxyw^"$>O 痟?3c9~zO ?al;##ׯ{oף?n^Fƛ_߼~%-_w t5# ތt԰IENDB`Ext/Images_Client_16/C45_Cancel.png0000664000000000000000000000215510133443252015635 0ustar rootrootPNG  IHDRagAMA7tEXtSoftwareAdobe ImageReadyqe<IDATxb,d /߿l1߿ w{QLLقG^gI&۷;w, @?/$;5O^__;?|8 @1bLL,BC ?+ly޽#/ $&@Ⴧ'l@7321H= _"ܸx42|)3KtP!@1۰_~}ׯ^beTb` )8P3#T3g.lѣE@v<< Ǐ^{YDx \ L@|ɓ gos…Ne m~g6ß?_yAo2 abb`Ǐ ߁;I !+PP6}:ˋ `_PeaP A ]YYl1]c#Ws?~}@w&669fAׯ^=`b&^jjK>}?HNjd`tO+8g323G #;oy?zx.{#?%ff?@_t y޾ j3NΟGpppPg &&&p @L?~}L&`x($ܷo[tߧ>;'0@Q ~1|@1}t/33e~?g^*Tf ^yV..O99(>~''oiK) NfE0A<=x̌' -H^IENDB`Ext/Images_Client_16/C22_ASCII.png0000664000000000000000000000106010130001224015247 0ustar rootrootPNG  IHDRagAMA7tEXtSoftwareAdobe ImageReadyqe<IDATxb:a### q޽[ZZ aǎ?_0+W?@,@@&D0 S}vKKK+׀ 3033 1K@BWWW%%%_~-0L͹s^xv@LA6W o޼[xl"{{{?Y16  ]9D;vӧ ,,,`9bB+ >@1 }t Ąl6/{ɓ Ϟ=G#@ pqq1{= @`6spp00@w `Fa@NIoddl ?@܉RRRi@yVPCX^| 2/IENDB`Ext/Images_Client_16/C42_KCMMemory.png0000664000000000000000000000162110131465526016253 0ustar rootrootPNG  IHDRagAMA7tEXtSoftwareAdobe ImageReadyqe<#IDATxbdpPb`0`򓁁 H3a`d%ĭr׃/ v~b`g| T y1ГQPSfc= sZ Y3~?lhiAAg/o>2ex{?w Iu#M ,3A3w ’&@a1;Ŧ$i` 蚿T+fy.9/5@cE} ARa7c lOJ0k 30s'+?t} v&yH`•AMі!S+e} ]7 A30*2 /}^bYp-;S ) G vc 5\o̤ޫǙYA{9V4 As"%b3 *?`G髨P1,I<wzZTIG(r'eU,ZIENDB`Ext/Images_Client_16/C40_Mail_Find.png0000664000000000000000000000216510133443544016272 0ustar rootrootPNG  IHDRagAMA7tEXtSoftwareAdobe ImageReadyqe<IDATxb Z_ LL 11|[[WG)ѣ;wh3FFV 4?Đ_~krprKE2:pʰϏN`` de 7/o;+k,$]Bs/>πd ???_B<#0_AFT!(Kie oߜmc`d F7uMS36u5w1ܺ?~^|2 kT10yA77W9<843#! 1" !̾/+&A00XH+1##6 GG;ĸYBL _fO| _~g3 df6V.2893##wǏ\/.6Vv& F iAAYwIqybaaeN?pq(/aN6o?A B@C?{ðmǞ߯lŻϯ?`cvݿ1r31|xpAAFEpI3zdE-~eA##MSEF'  c3 5A%%N: #庴ūCCw+)G98|ghk_yۇ8>?+?zu * x^`dd??S+0XX~01 C~39?[X@T 0r#333 &dr~r`yS{YIENDB`Ext/Images_Client_16/C67_Certificate.png0000664000000000000000000000103412666316414016705 0ustar rootrootPNG  IHDRaIDAT8ݒNTQP"/ DL5v`kg饳0K0ca q᜽P&~ei0 YI)cfFNLqR\ko K780%Fd$)U(eA:M bΉ%nN][hZ }"5 i4#G[{ DwTÊh!b8ʢQ4i6JRNԈ>gMbqw#~]DX|~('{BDY 3-`S׷~ȏp8&5f}&a 78u};55 !BY[I#~~ECV|P{ 5F&[39[`ü $2ɱO4Jf#&"$hY4X$DVKo;w*!U !e`dJ:W$2R2S"eIENDB`Ext/Images_Client_16/C20_Misc.png0000664000000000000000000000202110125245344015327 0ustar rootrootPNG  IHDRagAMA7tEXtSoftwareAdobe ImageReadyqe<IDATxb?% XJK; f100+rrR8e55i+;x~GbIŮ55dcc>~|]RA##T%a* rrꊞ*< L >ccc)w X~Ġ1p -FF`^GG6>>N70^ׯ&߿4$$$W mãG}:ADAZZAHt!!aǏoܸ| @A @3,[wihY\#'' 6`ݺ_ϟg & ر**2.]:=a߾ˁ1.!!Y ӇoY޽{k/_]AFFMCC_'$$AO߿c^F ,-YLÇ>b>u7o^~5+_JIIs XZZ)(H1/2,Z(@xx?VPPa`aaPY hjwA\\AJJ(W _5W qq `%++.Gϟ89ف)ܹ8q`ӧ˯_?,X0@\moQAQQ 8gP`FP͛gW^jy X@ĭ[WWp缼ڥrr߿bsP>0a2<{f2@0 ܹss %(qrr1̜9=z/F=ã  ,-mqssCX=;&cg+IENDB`Ext/Images_Client_16/C68_Smartphone.png0000664000000000000000000000075012505030564016577 0ustar rootrootPNG  IHDRabKGDIDAT8ˍnQ]{M1 Qy% A ~B׎?wb ɛ[^̙{t:=w? UPp8|yQ/U^6FEU(iNey*`}<{aT޽}Y>xc >Ɠ%FrdY_OS,ށ|%[b9 N "v%xs>`#"*z!p~:Rvw4JXU^\!A$šܽ -ZTn)"6M¢ ?NNpw w'^UZpIENDB`Ext/Images_Client_16/C12_IRKickFlash.png0000664000000000000000000000212410133443536016535 0ustar rootrootPNG  IHDRagAMA7tEXtSoftwareAdobe ImageReadyqe<IDATxb,,e`OF,,o?oas LL 30L/f""h0#+?Ϲ_q2P]/P H o P")h3)/k @I |Y ti'#9b:EdjߙEEO2Y333+߿? e|V -]߿}hq&@ :2 )7 K{/G4>@=*@]u4@A1 6 S t..UGG:GPfgZ|ޗOO5jǎܿ%<&vv;`,D @11}d6 Gf.. W/?.\$c#P ?@9`ذ311}db5@ӯݻr9`4``/vv6FPzc`Z &<P?ai o7 3 033?P(ï_>|x_ocecub?OA gf Lr;Lb$@L@[IY)\ @z 2@dsrq10|Lo~ tybR`~5>ΰaj!!9FFvS[S}B]^b`&[_~x'N0pj*)1( h3gyϫWL Xf: yo:)0|4ԁ)QA*Ṕj^@LHFƿ|a`&ه>|y`x lA jrjIENDB`Ext/Images_Client_16/C03_Server.png0000664000000000000000000000162210126474262015715 0ustar rootrootPNG  IHDRagAMA7tEXtSoftwareAdobe ImageReadyqe<$IDATxb?  ~f`g琕itrr av_>wG|!H@1 akkk##COO׮߿>}knnޙ0=€mlEUbo߾góg.cb`ddc`ff rs>};?~1| ee`cc)@Lps0~ϟ_ JJR ?fx5 3'ze|,,tqss6|  P `ddb7?|F! ?351P%\@5Wށm+T3#VNNv>>^p7߿l6 yxx=xp6?10{hWCh|oG@(y_ED~1~c`w}v1̟?Ƀځf] 2h!륳fkWW /_GBIEń^x&x҈׏VQg`akcg_888z ̴3nw013eՏZ& t U5>bgAD8C7} B wVZJ =::z _s~f`_/8Y˃W} )e=޿IENDB`Ext/Images_Client_16/C48_Folder.png0000664000000000000000000000062312666316326015702 0ustar rootrootPNG  IHDRaZIDAT8˥JAR;A++k`·k+FG0R 6B,lD b6dw~,l7 Xf|s,kKY&8`zXD= Q5i^Utz(@RI܎[p|rLuc ?Qh;hux1w`d2C +T"6r+Ԅu/tZ@Ou2y8} Ni*˟Nȃ92/av ĸq֋8$eW/ < 6uyU X=`uF{ a(`9f2(=7 }IENDB`Ext/Images_Client_16/C30_Konsole.png0000664000000000000000000000170010132777576016071 0ustar rootrootPNG  IHDRagAMA7tEXtSoftwareAdobe ImageReadyqe<RIDATxb >?101110221f`` #77'k7wo߾h X`H3.NNsS}^yYTbӌϞa`ecf; mA e/ï_?TXXp88@@DVl[B,$YkZE)HA f1'Dk R:xbaeae#gOjkkrsΞ=Pjd9bbaee=/;w2:۷ ?A ` YXAPP bef a`i <&fp 2@14}ܹ oN^f Ûv͐0qD... `C@119l@ׯ^2$3~h++Y0  `(2Սl/tgf{?͠f30 3 ;+Ï=z @6͚ @?@v@,@?00vI `1m4Y&`Hg` L ` $bafafdUSex7Pf?2|Ѐ_@0B8/@s3571a`,##RPr&=`3oPJe w0p;X([B,c!/0Lx/_`+@1Hڨ T@&@5A,Pc8; *zݨIENDB`Ext/Images_Client_16/C44_KNotes.png0000664000000000000000000000167210131463222015652 0ustar rootrootPNG  IHDRagAMA7tEXtSoftwareAdobe ImageReadyqe<LIDATxb?% ArC a"6 ql=?!oAG _6 k #8?  A 0K  9e~\o&C-?>}Ē \ \ 8210|gǦ^:n00؛1h00=1|P ?1|}GĒb+4AI;G_h?00c#ço o+ &^?@Eo~A5@[/@0ssg'0ۡ5bw ?Cb0 ??@K?9@gcʠiW&@ٌ@g7~z%@0cH 0 9ނr;ba`dF:o@{X~?fxqA@,"߀).([@d0 `F'_&~1oq𝾰@677SSS0vTt]J)R Lӌ׊" ˽k8I$P(MP*i2 (bx[b{w!?AExN !/f_R s!(_wk۶u]x cB@uNuvy|C8`AJ TJR}_;;;{:66AE\c! ~@RJBxj(4MyqqXi0 590DTRhywyrrJ&=::ba.Sm? 3R+an?lZv tɣZyvIENDB`Ext/Images_Client_16/C08_Socket.png0000664000000000000000000000223410126472642015704 0ustar rootrootPNG  IHDRagAMA7tEXtSoftwareAdobe ImageReadyqe<.IDATxbdp?ß l6Vz¦:|LLwvWݘ|_W@1 [!eog}0QK]#IY;@108gQoן+O~&ciA(]>65Z?  (IL~2]g0|x׷ >f8}y=àhr@A 7 ž /$' SC ϜaxCP+G 70bA BUP#;ED: k5?3A %(?;c<0]DKJXA[Sшhw By3p2py`p-C &'7Aǭ@;.  #!,lTH.A˵%'%!6ѫA߶))ŷ AիǺ* (    ]$}e`~.̚l }í 👑//C߫Wwo}T| ~g0Vq`i10\0(~ $ `ZlfIENDB`Ext/Images_Client_16/C60_KFM_Home.png0000664000000000000000000000204710133316700016027 0ustar rootrootPNG  IHDRagAMA7tEXtSoftwareAdobe ImageReadyqe<IDATxb?% Á0)'g`?̟3g` >νO&bc48ÿle`Ie Բf` @Ľ n\0| oc?#PǛ_|%xgr  f-6e.mfl"Vj J< ?c7 @/0mgav+ # _D? =&2I3Z10pr30?W?)6V̺g}?@LL?AQZ[E狟 _?× 1ff$#f5 ARP2   % #rA+  ? 70 :' $nɚo,fv4? o  2lMc`b(x @LN _ 7_x `/ 7 0Ҥy1ĉ>a`baB h+#+ VNw y3s00 ARM/mF1pbߟ|Y50y K.6Nq`6>pd"W`9 XvO.MtWfqQ0``2@<@\ d{(Ñ]{&8 %Y&ND$q3201:Y(E&}b`Ϡ)-ΖU᧯'  &Q1> ?7cqL OМ/ 6>@@ =:@hV?@C}}tC0߯ Jbl@EJ@ ^e4h~ " 4c_2o o\g|W@;A6',:̩ AaDD ej)&"{@ȴA#8ӓzh51QT)5u h K]7F`Xhs30q10 :+/K`#t@~.FH$%0`Ǜ/ "~1ۿ ^ Ӈ _`x R 01|*@LTO~g`eed!0Y<(~ý 3z7 ?= @,j@Wd`p4ca?Å7~|fPTexɧpOv ?>20<؂_^A֠,9+%0/ ΎQVLuo= (;0J\Pe4  wl<2IENDB`Ext/Images_Client_16/C27_NFS_Unmount.png0000664000000000000000000000177610127240424016632 0ustar rootrootPNG  IHDRagAMA7tEXtSoftwareAdobe ImageReadyqe<IDATxb Nb៣' XXfa|3C];/_ELLLOKKYXYؘ888޾;]޽{@,,J< ?~`LH63  & AAQ} b ,,@_ ?cbdR* NNn-..߿;Ab3 # 4@ XE5LL4~'fK l}gegPUUbaa EEYU--߁ v? r߿ /00ՕYxyLERRT ?BL(ـ.dv'':&@pq۷o@5Hd(b P??@1rqq-8@d *?7 oY˷& 4GnY>} ؿ@W0t>#Ï߿^x;_ F33 c'@_9% !O۷u vV?LLLll,?q^bdc,fd.W \%)um_^|o`hÇw,'O_ A LLI//-./4(4 R +nnix >~|rȱ>c?ט90ܻaČ7?{tD bi`& _|ѻw10Ȱ1 3<@W@ ',f k0#IENDB`Ext/Images_Client_16/C51_Decrypted.png0000664000000000000000000000171410133443170016367 0ustar rootrootPNG  IHDRagAMA7tEXtSoftwareAdobe ImageReadyqe<^IDATxb? 񝑛=@P^^I;;4ۗs9r 0QQХ6&_|3~^^,ii޿"ka ,`aiiY?â>pޝ}}+Xs988l@ %v[wlݻ.~ڝRXpLIQY]];ϟ? 3  az#4oJ><}5? b92|pOJZNUșNDx 0L,ٙ102q} qJ=@ ݮj`??S6aaca^Ơ]EIyn%lfH÷o | |ae` T!# 3J؀e7??1\r!ï Jxll0  ~20| =0F33y@緾30<h(01b0a`p#`! Xੁ+>\ 4MQ#N pِD @/@Ц_򚸁't:;#&HB QcX88!@o0!h;6 PfkBFTv' 6W8(JR.`6IENDB`Ext/Images_Client_16/C14_Laptop_Power.png0000664000000000000000000000163110133447040017054 0ustar rootrootPNG  IHDRagAMA7tEXtSoftwareAdobe ImageReadyqe<+IDATxb?% (AKLY x($Qw  l###2:?vAnA1yyE a}U>^?5\yu뎵.] @0?3xx8|< jgln<v ~}ax 20ĉ`b``fddc0M: Xph000EpWٶ, bb"`Hin s#@74>%{{?~`bbK9^ii13AX=i Ϗg}4 ïӧ00 1  `@}m2'O2&T$ tQ3Hx{3/ @~_ dAA @/4@1|*䷵e`WWg*&}; P\`L@ll \F ..>1z`5s1\ ¯͘ #+u g,0]-ׇA  E߿ ~ 450 YZ2up``d`  dO}}0ll ߁ 궕WWna ,DiF fJ03ܾvA=rr UU0002_k.`4D\Ey ߁y wA`Z`j dsrr2@;wo`L%kP43|?> ҀXFH6gyO0-|>IENDB`Ext/Images_Client_16/C05_Edu_Languages.png0000664000000000000000000000205410131211522017134 0ustar rootrootPNG  IHDRagAMA7tEXtSoftwareAdobe ImageReadyqe<IDATxbgvNo_~3| /~e8: R¢?}'w:ba^Z8ޜMuuIA"@X54[^Zy" X.>Բ*U#+VO ni¬BBMF@&D{rݧ_@, q O2Ife`'=sՏN|a )tVϽc?bR7e420beqy /Г˰gA   Ы ӌe ?ڧŭ#mg0ܸq;A} |bKCb t++û+6b+G < LL ?|goO \ L,\n@ſ ^3p0s1~g:~  s;>Q2ee` Z0aӗo v˟  F`J &( (çWnΚ''xn@12/.d^fU&V&Pcߟ_~Q`~bJIENDB`Ext/Images_Client_16/C53_Apply.png0000664000000000000000000000156310133445210015532 0ustar rootrootPNG  IHDRagAMA7tEXtSoftwareAdobe ImageReadyqe<IDATxb?% qp @~-:,\Nf6Z:xձ՘0ڏr$@;A]YjW+?"WE11vЛ_(sJ  % 3㜟좥б<ñ26_S'UNMǘF\|y]3b`@L|ܟ} VONk`X4uj$Ck >g=bzvL 1@+kF.u10ϕWeWjAH;8CK ۶\)A0dqIJ e"* avW:J"3]A0!3W0<S6.*#Y  A/"[/'0$M  YHC/Y~Uaga'.S&W3x ;?>93\˯\1 %0bb> GW1~Y y' @jF(ef`bdCmyLo, #Hiv0P!3#IENDB`Ext/Images_Client_16/C06_KCMDF.png0000664000000000000000000000170410131465512015271 0ustar rootrootPNG  IHDRagAMA7tEXtSoftwareAdobe ImageReadyqe<VIDATxb?% Ad+''Q {6  *dVAC ?JJ|B6'0tAǴD @YXQQHbvy s4%$X3;~]A}ڽO/PE 0~q0|xX88YN&?0\}PsL33'$Zs~FV ;ýw@_>s P]@ P0Ii CI20naLj@O0pOgd`ne:\ )"9#IENDB`Ext/Images_Client_16/C55_Thumbnail.png0000664000000000000000000000163210133442632016374 0ustar rootrootPNG  IHDRagAMA7tEXtSoftwareAdobe ImageReadyqe<,IDATxb?Cee]m!FF >H3a @1 .|6m@h)EGG3<{ߟ@iFF @# a`bUPcXlH pp;s*S# 2 @̌ g'/>fb 89X~j i 7/ ^00~o&1|(~+ +_u!Nf&|`` ?@< B\  *xdx/F~1|dfde``d # @A//vV71# ?%lXgGX'@11@)ˇ k'0 ̙_b lhnIENDB`Ext/Images_Client_16/C07_Kate.png0000664000000000000000000000211110126464500015323 0ustar rootrootPNG  IHDRagAMA7tEXtSoftwareAdobe ImageReadyqe<IDATxb?% X+˫Hg?+VƿYK6LE //1@bQdTg`d``ce`b _yVSmGϯ30dq33P @,?C' OaPUfB >UӳOK4}qҜ AS#@3=̔_` "]X&A5) " ْCXCk+ '~{i-nVظy^\p!XADj0P5bO}|7_ee~| "&-y  "JX0T@@N ӵ/>2+  ?o2|#q?۽Wz˪ @ WkWCo2<~ɂZ7#.e)_E0 @L, ?15 odXqÍ_V`aX|_OjH## 0 >=vы_~|g`ebc?bf>!IIMk/@,LLykי 30303;0csp02L 0Eꕿmaf D Y۳@.a>IENDB`Ext/Images_Client_16/C09_Identity.png0000664000000000000000000000155210133443056016243 0ustar rootrootPNG  IHDRagAMA7tEXtSoftwareAdobe ImageReadyqe<IDATxb?% (X{X]/)X302c dc`faL 1H/<}@,&rUU00|~  fׯ10111###23pqs1 ǫ+ ̬l _2}q÷X35202 1XYi3/@~g`zUZS@m `_b?3r00y*_2paݫ Š%by.~dxqv8= -?3 Pxpq 俁 ?|ῴ5g=j7?aAAAAAA?S1AUN@ocC@bÏoffx`qϥ a]NL/Fh 2Ͽ? ~c o?1gPs20[+1~e&(V`4?/??18b7?%!4u01 =t۱ceݻ/tտGeRUUgVRGЕ \ r^Kl@12hii11]***ŋww'$dbbd`c f q`ffw,,j/]tlmyxy 3g/ϝ;{1@ 0_){dee  n<;;wۻr0mg'C\\4͛7`ddzԦMk_|K@&{0<@5@G׭[񊕕 _"":? X7o^畐k/]|1>ym%GIENDB`Ext/Images_Client_16/C38_Samba_Unmount.png0000664000000000000000000000217010127240346017221 0ustar rootrootPNG  IHDRagAMA7tEXtSoftwareAdobe ImageReadyqe< IDATxb?C@tC7wff bݸ_󘘮[< 4٬j "8f8)P-\IZ6 e[i~6e{ɸ-C # Ȁ@WxYC/ :L .18wa,? V%{G ؾ]bRR!.!5Lҷ d £Π/ ;.dfP.Pi.d*()$Q^H3>yxUt3$p/ -(( 2 .`/y8&O13a0}`l%GD K3a| &&]"/7?qϾ3a7 o>`p9()wFFA>eeUVQ@BZAAIO?2&cPcgxwWOaASSU j+ˋ0(e30Zgx _߾a`vePb'377-@ =o?L cQaQef` ~101ps2h1 knn1| `1n6.b:?0` #2Fa`8tsruphq%އ:af )1.AF-v*ld FP^pv 7`_W%v^kbc~_vN~;~t#@ `=W"߿~Z3ppϠ-MIIǪ (:}I@!uk)Z9x9y^~zsO߿3Kq Y4uߟ7GIPH"_w/8Yu8٥؁?1Q/63<}3LeYkn'  |A/3\&"D '+M?2Sߘ&q=+';0Qr20p1???/^:??C##?:j @123['V)`Wp`x;?@Wgd``̔\̐u#ߓ~k9Y82 10s00r10('4?'˗r2k~=O7oI=}wz/` ;OcW H~.7*tfS'A]1    E8#P߿|'ʿc@!~狥IENDB`Ext/Images_Client_16/C47_KPackage.png0000664000000000000000000000172710132777546016143 0ustar rootrootPNG  IHDRagAMA7tEXtSoftwareAdobe ImageReadyqe<iIDATxb?_g?&,bU'qP|һ;$P-+]~@, @LD=L[kĘ toIo^}YeL\/X` A.mW3ȫ 0))2(30 30depwW|~Ll?q6@Y@Y3.. ܏ؘ1I22H(2pɋ10pr00|cXXgA@`/){3`P/*#_.1;2ég2(h0pD2ܿϰ j@l82'*0p!Ó;> ?e`~ŋ 1 `ضs  gbdQd06cxL9%g~c`Re`ba@   @`| Y`Tȳ _8ؘ~ QQ @L`LL L@Ȁ1aX?EĄ`22E L X { ?~g cd{_1B|tOwo~0I30qb%@͌h Ox 3*)3Ȫ03)/8} +d@`~λ71S5TQWae`gb`zR8)KJ0|̮%''-b odd?k×/ @`BBB[WNNAn.QPFHlY 0:vzRAIENDB`Ext/Images_Client_16/C23_Icons.png0000664000000000000000000000141510131260450015510 0ustar rootrootPNG  IHDRagAMA7tEXtSoftwareAdobe ImageReadyqe<IDATxb?% Xt>)kr񛁑hؿ CHd?g* w-їǛ 2be` T7! @>3P P~f)bM1zwY_ C 5gbd`؟&11|P o |+OYc`C9<@eN'0fe`'0p@CxPߠ XxDXd?! J0  L 0Tr02˓{-c2R@~bdlV`Z 4_߿` `"a`dQ,alf_ srZe IENDB`Ext/Images_Client_16/C49_Folder_Blue_Open.png0000664000000000000000000000112710133525322017614 0ustar rootrootPNG  IHDRagAMA7tEXtSoftwareAdobe ImageReadyqe<IDATxbd```bp7@ @8P ];@$=4N/F{ |܃ ^ d {l/ ?00p@={6\^" -3'go6x1s:Fw> u 8yB(0n~@y3)ds@#mcX;T#k? Wm c+_ 4Ȁ?r?C6520ċ5Ѐ M@h_ 2 nql5.BBDv7퇁@ i7b6F |t @۫ Ă]@@ `bC 0!A} XPP xThbCIENDB`Ext/Images_Client_16/C28_Message.png0000664000000000000000000000167110130000324016021 0ustar rootrootPNG  IHDRagAMA7tEXtSoftwareAdobe ImageReadyqe<KIDATxb:a### [ZZ aǎ?ϟ~O˗@!n(4iLⅠ;yTI=8k4ͦ#X@4+óV_YpN @qa&i`h1%?Rr @1 i:C˞?\|L< 0c{mf  3,9!AZB |0~cf`tAs)3 ߸>2 0~AEAy4Y^V ;. ?b`q"?_1<~ {$n֟Y9~gv ܿ%1\|3 _+ Y{70<~lyưzY~b`z`` ѿ 2 ~1 6/a8 w>p#s'n0&03|1ˏ A \ 3OLgxk/+; ,8"uBb0bMH~SssU}k0h"(?~bafff%_...x8lE@1 @,Νnaaod k0!R L ?@܉RRRi@ѳ8H Y^~ xwjzIENDB`Ext/Images_Client_16/C50_Folder_Tar.png0000664000000000000000000000154110133523764016472 0ustar rootrootPNG  IHDRagAMA7tEXtSoftwareAdobe ImageReadyqe<IDATxbd```bpcC@15@@y' b(fbFdd8;ݷ%2+Tx- W8GA؀W_d`Xx P P_1  /?A4hz /b`db`bafxE87P ,bge{0 Ǡll! >=;pc*×iq >C~Aڝ }+a !.`@y4 ؀_ ~cF&F.>aPw` j|U6Wp؀7 SAH0Z^}|^a~4o0!  h`h@00]TD\؀O@XY@ -c`zh~\~#bw !aHFAT>mZ&>?L?p: J.pg//#*r }pl+v@}Kx@2bP2 t2set`}tއ?T d;0 6^A" B (]@ ml ._iIENDB`Ext/Images_Client_16/C04_Klipper.png0000664000000000000000000000133312666316276016070 0ustar rootrootPNG  IHDRaIDAT8˥Mhy3$IW%V-XqV\<Mœz DYDî=qY+GU55h6|cf߃ԋxOSJ=2?t  <4S~]M$5oBf9]2yKvivbBА:("L?xl#t42x|X #Ta( l T"gv1_TE3Q6 Oǐa###ݧ)|7?~ gˠ'!*@@E߿?~koh훫'z/_@'- ߯~A Rgcjo,G+H %  Ѡ}Aq"+_c ҦrOKs1 gdt~1>2 ث@ͻA^ w~o|)7Ms'8`1M {NOa81uE bfdg,lAڇeu5Xĸظ1z- gn`8=wow$݃>@DO7?OXߨGv@e^#rR'V? ^ӛ]+r#@!+ 0Js.dbg 1El@ -kIENDB`Ext/Images_Client_16/C57_View_Text.png0000664000000000000000000000157710133443326016402 0ustar rootrootPNG  IHDRagAMA7tEXtSoftwareAdobe ImageReadyqe<IDATxbTUg20 4*ba(PD/?܏ l +7˻OӇ L 6DAX/׿ Z Z"`&E;/bH X021p2}v艳 Z fff _f8p ?: _?01pq`f ? L@c`bc (( E@_@aef/H/@ 3@-$$Ȁ \:?3#@:٣ bWP`Tgx=ŋ] !/uE EL  fp0} `W *+c V bb4 : ::`AJJ!**dy3(> L@޾zpc1qqyy9>0ܿPɊ]%4 XMafffxp!ÎM>|# E? &,(0BΏk~~w /L߾o{p X8y8gb-8B >VDf ?;8~3ˋ_m7`t )s?P`bd@1`IENDB`Ext/Images_Client_16/C17_CDROM_Unmount.png0000664000000000000000000000206610127240554017044 0ustar rootrootPNG  IHDRagAMA7tEXtSoftwareAdobe ImageReadyqe<IDATxb46^30|GH]COEEP>x'>|4C7.Fbb~~o 06^KJA@O_?޲[ۂxP#3@1gPSmGO|/`?~?uڥBB@|";mx޼e`_@K~: YX,,߾=q$КG8"F[NZ 00iүo_>zЀ=e`0wc5-a`` &5u@ i/@[mdGgc`q >з>g`bbvff e~Y~v/@:@&{? O8ޓf4?'[ \\ r\ i$$^38].@Lr6H306v6]5w|!a20@L`%+PRAiWp&NP(@A ߿y @LG>~'!@[ udd``bd7=ݳ׬:KBAQ1L(d2 A)]㇖jbӃ{wHI130| 0H0 @^>2Lj`rf8@L@U痲ac/_^`H*|À n&IENDB`Ext/Images_Client_16/C61_Services.png0000664000000000000000000000200610126474252016232 0ustar rootrootPNG  IHDRagAMA7tEXtSoftwareAdobe ImageReadyqe<IDATxb<+)OB{ ?|d`addy _z;= v_ @l&("'ϰ |3H3 3 a`b ҭ* 6d`padk>^DϿ |A| F&LߡmgcbX5䊿   I>Q M3fQ )-US5i{>8w xy @Lcÿ|`/n%YR_c}'n^/_2ص'wO|FN@w>w(3VW_vpr|bg`b̽^b\c&x0"7~@02 /Á20L @a7 6_cH <~kbՁbo@5Ï[ 0dTxrշ"b4xXKG 0#/(|a2 _eַ{30$%9P 00X[30KWGX{\/ ? N 34'P-7_?~c`Tb*(a#/3c`Rcb`b@rh*Tv5 4Ãg}n˕ R ƌ\  d&L @A !x?Ll0İH,KOs+($L @zjt+ô30CR&FEtRcb bn c`WecLN05cjNūIENDB`Ext/Images_Client_16/C11_Camera.png0000664000000000000000000000160610127241026015627 0ustar rootrootPNG  IHDRagAMA7tEXtSoftwareAdobe ImageReadyqe<IDATxb?% (A99ig :6 #ALL; .   ~|hIJJMVVA@YY?ɰO_2\zAGWAXZ&9b`cTAF;*B:)% ~̠`a'P6@/ b ,??@L @?~ d _3?p+ >*be``+FXR &&&ffV02ٳa ΀ @ 4%^r8ttL,~ 4 ubA<~00cpsuf.Nn?]r3@ 9 tçO_|gec'P)(Y?1&vvNK ` \` _y_h/0@Q )6rO~tvv/~1Lp@Wfx>ׯ~\??00`A ߿wF`3]L,̠Xc˿. FJ3@é "IENDB`Ext/Images_Client_16/C32_FSView.png0000664000000000000000000000162410133310424015601 0ustar rootrootPNG  IHDRagAMA7tEXtSoftwareAdobe ImageReadyqe<&IDATxb?% X@Dl:// ~@?f6ߟ>2Z@`- Du~ /P~T` <{/Fa/ ?|f`b }Ʈ$1ITxg_? YXDM`5y/?2(L ! @20.c`drGahAD*5vx)08.B)p*&YwWF|'~)@,/8?|Ó c/HO5?ß JPg^w@Y_`l_`d`7pGouJ @ 0"w?@w221$  `ÕgTD,<o3av@A ?^~O_e(P=P.o Sn)Ƴji! n~:VV _?3hà&+v Xԁ ߿}g|jz 88~G+%q6N. /{@^aa<|\j o|b`d``h '~3J3 =yh@11 i3×_~`n$ 1ax?Y)I-rO5EQs~_5Yf \< y2|gaWR>~$ @04G,WN)>ϟ1hj0(b0gg '/yAOF Ń^%#,ERoN(;n? ~bv*"!-痌FA2u52# L8G4+ '.sA-M ! 5@@(RF?4<8 #. 3102b77V^)-3g~~﷗ ?s0'#:E+AHbtyQ!!I;#ՈMB1 PJQ#0щSG/&7}`x{$=~֫W.0.@1+[\Nz7orSU@E(13oFF&0JtZ[;IENDB`Ext/Images_Client_16/C54_Signature.png0000664000000000000000000000142610133442656016420 0ustar rootrootPNG  IHDRagAMA7tEXtSoftwareAdobe ImageReadyqe<IDATxb?#c~8xSe&=8 @L\80;3?fVVOI^ H'@]-v]#QB~-Cw?={dg: p6{ӷ3_$*/{Q7$ >- ~Âofy-):&ff77~kb`@,&v~z]ˠ61p h/s3V@,0deE.Zy " ޔ3g @`߇g4/>Ѣ 14c8zFClP`g={F '7ál7vo(J5KX)3^0G2ay ĦX>8nC(a@p0LTW] ]kaXN A /Ow@ Lc .Аe rO`a N _ #0Ƙ@`M5C_03ϗ~0(:F r2NGBOMgx#Q |sjI3 WʪIENDB`Ext/Images_Client_16/C18_Display.png0000664000000000000000000000157010131206132016045 0ustar rootrootPNG  IHDRagAMA7tEXtSoftwareAdobe ImageReadyqe< IDATxb\hS#CC1?30g$ψB&&f?Yz+X0@ lFFe``aa͠@,wCs?$E}@7ß?@203ja7}>n8JLVV$4#|'%iNd7Ԏ@miMr3Bmq:1 e׻j5)?C:'`LtFZe2rlj R| <]ڒH%s&e2L\AZX.~Ri 4U4E~壼p8Դ u ԖQ^WZ/N}}IENDB`Ext/Images_Client_16/C46_Help.png0000664000000000000000000000224310133443074015341 0ustar rootrootPNG  IHDRagAMA7tEXtSoftwareAdobe ImageReadyqe<5IDATxbdНd`ft̑?û7_?2`[S(^ 00W gX_>xrק/rn3f9Y!>* ߾ex P b`daefQVz7o103AG  loIH>4[>* 8' %-A6AF0\:13$  [C1<<RA j+1% 3& kETZK^2h'# dx7'wU1w_0|, ?CDH Xx^~p 69!Fdggi, !0o#;< ,\lA1 ,cH _f`/wl2y/PO` L@@18˯ L 10^jZp#ÝG_3o`Pٯׯӗw}zpAZ 䀊~mao),LL!' :_ĸ2`à`J@~8߸y߯UA EF$ Z G?}3%~n5> !3FNFnƷd~oF5@12A2$?gf3(}׫7~x3caK̢ZtIENDB`Ext/Images_Client_16/C24_Connect_Established.png0000664000000000000000000000220310133443126020337 0ustar rootrootPNG  IHDRagAMA7tEXtSoftwareAdobe ImageReadyqe<IDATxba!Fٿ@۷`6' 1 2[F/;} *`jTߏ_>?CO~gAx8˯F/گ3"ԎڕTo?_|[P+G ߘ~g{ 7 _0|}xc93>ad'Χ^ $\ 44Q#SÅ12o GwALK ) Alw\bwh5 قˉ9?`\A  ·ryFsȌCb)q`f^]^^_L,,W>,ۿK/:`hΓ? }J@ ƺ/~3`Ѧ3#`A s#0MƐv˧ $_νE !07ڲwIENDB`Ext/Images_Client_16/C25_Folder_Mail.png0000664000000000000000000000151310133523340016615 0ustar rootrootPNG  IHDRagAMA7tEXtSoftwareAdobe ImageReadyqe<IDATxbd```bpcC@15@@y' b(fbFdd8;ݷ%2+Tx- W8GA؀W_d`Xx&Ml@ x E+g>38aK > OgXe@>C 3ȋ1Xi0\< } 3w ' obSfH 7dad/55&0<iT " @`^@{?0X23㌉_ ~ge61dq0Ha @L ͧ ρ~ưc G0}ab^rW.Nn`LwbxuÏ7`W$30%/7#W~&pr 10b0Ta8}:67F| ;vb(ra`̠4 d8 )HZd忴g|߾C/pE3XN% @ @ 3q%##󤬬?/ɩ} @X, :@Oƕ EHGIENDB`Ext/Images_Client_16/C52_Encrypted.png0000664000000000000000000000157610130001060016371 0ustar rootrootPNG  IHDRagAMA7tEXtSoftwareAdobe ImageReadyqe<IDATxb:a### [ZZ aǎ?ϟ~O˗ @2ի >|`afWA. ~fO.\[NNN30RH=%Ąl ++í;#/>Aw3\Vk0 ~p ?=aPUdx  =ack@, @Ƿo oex zNv37wO35-ga@e` _ kfbPg, ߿~#DFf~1o b0Π(};-O` Ƣ L8߀A  X@&߿ Ey.]ʠ@7+ 3  D+3 @7ÛXi@2m``򍉁@`/8F&dϭq T!8qQLA/0@A fffF399u$\q p7ߟ`R`e s}7TPF5ɹ篟 _͝(%%THY=C2#ׯ~@ⵊWșIENDB`Ext/Images_Client_16/C02_MessageBox_Warning.png0000664000000000000000000000165110133444024020161 0ustar rootrootPNG  IHDRagAMA7tEXtSoftwareAdobe ImageReadyqe<;IDATxb\΀g`P~@sb)ϤNŬQ'o: a`P27wtf3b33` 4 /0|%;;[W74 @(.``.ib,i` " -"Ơt4 @,,,i>| 20s0誨pH0Bm ɚI00143wu1bfP` P @L<gv3ܽv̌Q@;M@ x.& , ",#''ׯ jsy @㓕Pۏkˁ]%.. -- IX. ~2qsqt @1AQFEڋc*Z  !^e 2#P(  tV>L%&| C~?iII9@쟿32Qd=h@`+#/5{0/ ?c>u*Cco/o `%8のA zWb,V`fuïW?o\ F =޾ ?>~l YY q7K%^o/^0f1~g?@Mt #а 9\%N/@l@_Lhge~ ld"IZ Y IENDB`Ext/Images_Client_16/C13_KGPG_Key3.png0000664000000000000000000000166210125245344016073 0ustar rootrootPNG  IHDRagAMA7tEXtSoftwareAdobe ImageReadyqe<DIDATxb?% X@Dxx:b1r&o}n=n@ LHX7?)"wf&W|{| <,K{FGϸTb=ܲK 33#жYŰZ VAF````dbfx֍Xc{ 2030\\ 0 tΟ9'WWKÇ0o+}Dg8  6ǏWXX-DDxo  `ve{*p ={tOߏau&Ó'~h60>|22pp0{E&_suSH[ ~AZR-=4## bҿ?~z̹#n_`@1((H:s١Czvw 2|<<<˗o?}ԥ+t7o>}͛w,,/^g.(033 n_x7/f PJϛ7 _x[Gn G o LL nfPWW1-ZŒ _?`b/;#t&"Å ._>0Ǐ':tƻw4z?0 )MYIENDB`Ext/Images_Client_16/C31_FilePrint.png0000664000000000000000000000177410133443144016345 0ustar rootrootPNG  IHDRagAMA7tEXtSoftwareAdobe ImageReadyqe<IDATxbf߿3 rH12022h-[vo9vd4?b7Ǐ ||FFz< XgDj ;ffn&&^VVF3,ׯ@7b(i_0!4-?b9@ۛ/8,-5?_C\N>>x99@##KUi)q?~@%@#Q``ȱ_~  ]=߾0;ӯ l L@ bb\1QI\|wt?o&@EZX3 9~Ͽ~fd|`x-4y@()) 00˯ ' 3\p=?5}g``cPPV 1>}? s2{xFF( >bx _~ w>z!pgbPM_f7 ف.d 芟 .|e X~xúSY88XATw_(UMw ?=-//0'TyÇāa ##ۧwݹ7o^㊏OcRd* N`_ L JJ:DvΕZ@̊ 灌Wej&" gח\c ç ?02(+0zz:Ͼxzh@1z2𰥦$[ʈ3z_ ߿30nNNF)}9CWg*A!KK+-+"=@/W[JɢdECSrݏ?{ =~ l@fd`HJeABZ_0@,Ғa8|*7XYDD89~bdcHJdf10ܼ@18gZ9(3K00033q1gfaHUbPS 'g;vF(nemcŠ$`h Ơ)t;ï? Z ߾ a߾\>]_@@dD5$|f`ANAOADWF_@:h?FGs>~|(@1sr~3d:PwbF`1ߠ]/ L' ~t7^7W@H_10? N|p]&8x/`j`b '+V7@X~r0102ϰ<חDB4~2 0H m=x7w 49ɱn%ɠ _L B 3F33|[o> &[8}^21oFdX8Кȡ@O#g/v6+? $I3#.yp%71Xap4`8'@ ۏnҡX_| ?1}})"޻ ZO8a`x [} @yQifWzĠ|~֯}{5ë_'iBL :v39 ^z OaxT( \@@Ĉ;YXd ? a2\ Vjw*IENDB`Ext/Images_Client_16/C16_Mozilla_Firebird.png0000664000000000000000000000175210125245344017670 0ustar rootrootPNG  IHDRagAMA7tEXtSoftwareAdobe ImageReadyqe<|IDATxb?% X@###:G7;b/sqiNo}rOsd PO @ \ wa?^}_ #h.Pad>O?xw>G5\T.@LȚYi62? vo?2| c>s+@  ,–z3 0zmдk_0:xGQR+ P e3s< \3ppZ/ z7?xExy9tƿy`!wF ɺ?ޱ0l[pTe̴6uضtOy3(e30l'@L`o@1WMQTbbd?swMߘ \~'n \([j(۷, < _b`f - CHp'V100@ !s}?y_@`5m30Z\@OԴtWfbx"{ W^cgead tǏ?/,ɴ|nߞ@ʾ^yœ* k' ex=P#+ 0ce8z{f M^6:Ĵ ⌒ l ٞ0b<0ZQoN`/dž50| .KV!6.v&@x)inAw0d``c [> 1WeT5q%@1 )p[32> x׷ O11:1p 2' gdaxMIY0U8~Ÿ?)30L`Tff tMhC@033) (_e<ʸ0:2)wn^V.&`L?XTLmA5  :ss &3+A̸Qš_]6qGR'ÑSg_:v '^xt ÷ Ŀns|Ni`s1V¡+k@ ؁'@fga!+IENDB`Ext/Images_Client_16/C59_Package_Development.png0000664000000000000000000000173110130240702020341 0ustar rootrootPNG  IHDRagAMA7tEXtSoftwareAdobe ImageReadyqe<kIDATxbTWWgFFF2[RLLWUEMÇnߺ3n޸V,""fn66;J+mx}Tj`` 'Ol d@4GuuFf(sg=p__|]LLI߿;@z @[mm^`w> 7ñ#GW}=@ ( EEE91{;ÇO xn1~z!y޻5@_09))|yY 㕫.]緌VlmtUhy X@1'Z:<a?:Tt,}~wG  VV=w~3@Π?}}ʿg={z-&F$ 4Ub3P όZ?֚v2g@Uh/ ?+# ߾3E3>V1vQva&A2{7U;R S @lll DH317gos |gpg0ַT:~Vfz X0(11  g< _ %i~1pfP/˿_ Nc`cdj UbV`d.=eg8 |c 2i20j1}'>`cGQwXb`x'   ҆, 31{g0\yK?3 '{?z`  G fe`fG!^V^}pgd`b32 |(l 7L~ փL/#W>XYy8Medo0AAh*3Û^~5 pcx;ç/^ ,l b;e@20 '<:&}egxë/L /0|| ?Āח 6`͔څ\ L0o 3}%pób L|  Ͽ2ܽs  p^`ddcb/5w̓3pU pL, @?3}7rc}w[Azb ÷_,8lY?׷~9 =@ `*LwtIENDB`Ext/Images_Client_16/C39_History.png0000664000000000000000000000221610133443064016113 0ustar rootrootPNG  IHDRagAMA7tEXtSoftwareAdobe ImageReadyqe< IDATxA) F!%\%= f+`J/0o_?1_V 2r{ɓ[oˁ<@ ! @ʤ8Po_1XH3+,Ƿ~`з{ٛǟ02} foNII|,~3HJ3HJ1 2HI3003c`fG^F _@,,&]B,<վ3k12;;ХEDDd8s-w8(1>|ӧ/ LL 0 @W02q22J``bJA<G<% *"#**% J3A +/-55-"" !  ?#;?0daaG#u0ܖc02b+o~ ?@볠 77P,Qs#seexX;''. ? oo~ȩ a9 H!{ GO_cok&߁^q%̺pm%:0/=}+_h2{{ yx}7߿pןrVAj8-    _ /B|{ϰ&YVYi!/>1?6byMȁ!S  {Kf`Ҝl 8$XLD9gx\xzB 0D;|f֌&IENDB`Ext/Images_Client_16/C62_Tux.png0000664000000000000000000000117412505021266015231 0ustar rootrootPNG  IHDRabKGD1IDAT8ˍRMkQ=c&N&&F(ڢXB K@k[O!  +&BUTZXhd2uaRҘgss\7l{RJ4bk8h5BSSqpWBd7s%s=[ys7Ew4]x*RP(hFĭMa>!,g]58`5[e& `)+?&A0l/+/DDվޣ}v։(H͝6gJǡ\.G\gL$QZX,浶6!T1˲FEK`S``??1)LaBRԗy(NuJ)3#χv!׌`RJǢ,-= z7=^Ĉ9<(iWK0q~)ܖ-"!y6t=@4^T7v"jofq5mCێI ?;/:aIENDB`Ext/PublicKeys/0000775000000000000000000000000012606740432012374 5ustar rootrootExt/PublicKeys/KPScript.pk0000664000000000000000000000024010576770000014421 0ustar rootroot$$RSA1u}JRX+޿¡)7h Rv a;`H:+H=V-r.JU!r[I5ш??\fy:e,jn"]q 9r]|^];Zuencgt3#Ext/PublicKeys/SamplePlugin.pk0000664000000000000000000000024010576770032015327 0ustar rootroot$$RSA1E|s.9 28.GYvIVQD@dfQlS[DT˃WEb'*ga}wr &Z8v^^{Md7zv2bΗcS_wî:JvټExt/PublicKeys/KeePass.pk0000664000000000000000000000024010576767630014274 0ustar rootroot$$RSA1v[j}AbҀq0c(YWS\bO+7Z8.S:ASo5$BN\ew8C ~ m&pXo}܆~LKE\ܲN1Zd'{wӢFNExt/PublicKeys/KeePassLib.pk0000664000000000000000000000024010576767700014721 0ustar rootroot$$RSA1=dX/!,>U쥧 &ƽ,!l?9\[C;CH 2ī5J2lW^PEP<=?li(̧VEDZS&\5>{vq.rV Ext/PublicKeys/ArcFourCipher.pk0000664000000000000000000000024010576767514015436 0ustar rootroot$$RSA1o$չl~ӋsEc ~/7u2t3 ܥlBx`܍cZJ4J˫Pw4\C>x4"DZ~/Ext/PublicKeys/KeePassLibSD.pk0000664000000000000000000000024010576767744015160 0ustar rootroot$$RSA1::/N i*,~S2qߑ1P3~HO x&hzZeg 'JuBӶi &N:ᬳ!\C,0!̤*ߔX0C Ext/KeePass_NoVer.exe.config0000664000000000000000000000066613175413472014750 0ustar rootroot Ext/KeePass.exe.config0000664000000000000000000000137313225117314013623 0ustar rootroot Ext/Images_App_HighRes/0000775000000000000000000000000012706643204013740 5ustar rootrootExt/Images_App_HighRes/Nuvola/0000775000000000000000000000000012706643216015207 5ustar rootrootExt/Images_App_HighRes/Nuvola/B48x48_KGPG_Info.png0000664000000000000000000000643010125245344020375 0ustar rootrootPNG  IHDR00WgAMA7tEXtSoftwareAdobe ImageReadyqe< IDATxb?P0@`R\@To  ?T~~KU~ȑ#(bĂ:B,>KX'Y>a ـ?Xdaf / n^Z6///@x^" \n.@J]l@o\ ,"@ 1P Sz9hl P$9#<$!GtÇל ⿿Buo0hXh2<{̌$aKKKWHg"@pJAFZ X rÖn_3\޵AAGz_rm`dp``zрa 1Kpfƚ<{Ձ>r&+@ 9G7 6apPH3s1yy߿~:GmBR ö D^be+R邭IabAOjC  7kbI  k1]~ALN]AFOo VlJ*3| X'ρI_ 7&#&&X}XL~db߸l +0` }0jZDBh^@J BI Xp~`A#FH1_&voY%'%߰4 ؒ'!ebV `V O_Od`ta`0J0Bb_D__>| +Eq,;V1(F.F@=c[o5~`? Pa%!Ff3w.&0j#T @0$9[ wX R(avD}+όL _&fjGCLv|@篟H3Fh Rh (C? ?>7mr516u4A`σ?  zۚ[ȸ{HI JBf5(VxeI#3JQQ4bcD*ZQ.$@(coH6_zdCm LȄڪZklB rG/ԧzCWn3{3Bj`rz#PѝG!IKшDOBA^1@(Pbi㡍@^ ` C ) @fҩ d@#1bT^̍?zUSX5++ffLR#3bi"0Hr$@S ; hҠ#h&=TGiaP:9:X8ro b'D+0 laتo h90wV& LjF H%mQ l <l3(@Hb0_.Y=زaVP?(ւddfr$p1&v9 v<FcˣbzIZZ2232D5>BВzk xϷ5@}dyB RFz#<B›\ 90tFdx] +fը !5mhzL`% Rz艭! A ^3tFbx `5sg=@X=@Լ6Y#r/ÅSWq00D  -K6X#W?a =@C} @ *V?RIENDB`Ext/Images_App_HighRes/Nuvola/B48x48_Binary.png0000664000000000000000000000525010130001206020074 0ustar rootrootPNG  IHDR00WgAMA7tEXtSoftwareAdobe ImageReadyqe< :IDATxb?P8=@`dddptttP222}ˇ޾}{7o^ @,,6p)((0$  >)U@G OJG' @F;S2H$hTW})"RrIpwsnf Y{2րWk]wv>}F ˁBs!NZd`e y ~R@L$J &&&0-yA[alr0}< @/ _0IC 00&+!&?vB%+d ;gD0 lgRRDsNRJ8ŋ 3#`ɝs{fXQZCsCո7ƀڰ+Ur@  TLO!XF1ǁ'"?hfZ+WP 5 7|ޕ-D_ 3MKG1*%%%9 fA4 jjj23K@r WUUc`i9BZZALL yd8}h1 d``@D'M%ec^sCC;ZJlM9;Ĺcz't @!D/ڥl, EY@{'#?*f&!)c @Z+Q{R /\TUA8k->oNϼ;u9/hJ3Av G Xi qC/^-[L@惒 q_ɁɁb ?*[42H=@aMBQ3&2Y\D` ASRJR@6@G_ |z8l հVઙ%!Y Z< Ăt%#bW \GW - Q|} b!@q%L![U^ b1ZY>XӇ/p]6 dTق`HY>vҧxZK>~S˺[Z, wgyd͘536*4dxfJD79 m)a"1K7j@wDPl4!iA(NVwߌV"0 [/a.Bޛ~tl?PD41Đ Aul(3 ~Oо(pEx{ɓ' ׯ_7'@M`7ܾ8MhPA-X'''r%[7 "؜`mv<ɁW@ c J5=rLU elP B B)R[DyVDָUoYAa_WUM\^y]qs{_|.P\YY ɁB 9PȾ}A^^AII AB8P1^AjA,ATl]Yd@Q`qرcvuaKa 1% 6 aY8y 06L 9P̀y0fQZDC`2&Ɂ0Qd#Wk#Y3~C[  AG jPD?@/c6-Zz_ b0 ҁ,%+2ћ/b6b"&Ja@!B*rS4 6C\@r6/  NAةė'tWprBvCB:Qdf7lf67CajB%y%GUA}ȹZтGB[P &ys9T޻w%B}}}p(VVV7K@cMd yPj}Pqʕ /_$@LQyTKذ"( 5 ǂ j<󸊊  USDSr `Ű&aX JV-Vg`@kuZo޼7"AvFp%!b"vp]pG^uh@zjx%9P a^g:Ɂ . 3A@|@l&<2 Ɯ7nJ0 07\-l6DR" OFKXs }Ƚ2P3d X(FAjiiʡ4`cy֡%Îș z(r2 -ĐG@lА$LGoc[+݄L;[眐>d;eb0z?416Һ $r09?@ax{F`$ zQsY(2yAAkA &@ؖ:ii`&mӧU EC @ex /?|1P /20\`c`+"Ь$8W8<@(:C,0$-yyu4͵tLU10a:/'\ o߱1<{ ngqH ?xfh@@=Ș-(!6۞ATAUAL+ь?x<&g@[_Bh=7Ái&V%N$ M@SU~@ף/{( 90 ݠY#Pv=2Bz=" !}`[}iz6~!lGА!!!!!!0;'-IENDB`Ext/Images_App_HighRes/Nuvola/B48x48_Reload_Page.png0000664000000000000000000001013210133443444021026 0ustar rootrootPNG  IHDR00WgAMA7tEXtSoftwareAdobe ImageReadyqe<IDATxb? 0f32@5i@5&@\%&L} ?&3TӐ@m!dS:TD  PxG@$ZnJ xfdcаee9߿C@ՎZ@֘?tWmctNf`׈@X@'2o'88eaXSAO@$xbX9`U z@ X; 2 ӲN^8Tu Y`#0:]bH^#r 3`01UGxuR0,۽؄s##SP9B C bbdeab8\7к?C?_L gv1b|Ϟϰ`:$CϪ L*;QDԀx20@#Ci,52+3{$?O &/2Yę_P7Ai#7P\F#5/0Cc1'n2Cɠ TG@,8u fQ c󪇁pf`:QV #.cN- [F֋_V LwC`K3!7ΝkڅwPa\f fI pGM'b2~:`O&1E210|ݷ \$) ^qg@O E2W2 3N]: r*<|@,h! P~̵Ì 33/P%p)= Gdx#3!Ŀ) zJ xL}7Wh$If0T,*gW d́8wgT32FS/`@32LT .еiCn?~g`:A  Tc0 V V O?a8_>2 Cx<ãOwAlSdԬ& 2L&Hz XP3P90@@1 *Ф҆>`&0[>νGHP_*6cW'0iZ$C T0p|!qyE(! (~ڹA3\]HCB<  W^z=ɳE*p,0@eb~8{OHA LjHLl ߀P@ t5=H 숀`R@=@6(e`Z=`È1ojc.h;뇳D{߀t7H,W0۰s3/Tt#}@~v‡S .@Gu$:+; ^anwc(k`x%Czg÷_r{@P rQKqffXp' %0\w`' + XwаS!ʐXW΃(c3 X0:iax1Ï?Yu?1P@$ 3fK>'(dCas}O2v3ܻ{5@E% \,Xp(+g nar=C:?dž`a).uf!* ϡ`(` g 9;2Z%Trp9@ Z c`+!qٽeCG1;7CBw^.!_`kn|HKϯ 7g81aѮ- >ρ/Ǖl@n}C&ٗ^32LPP ,3o`S17cZ'Pݫ={[?_j <Ӂj'c1@D= yM:]Շ7 SjcUN_r7 ~+S81AzCL803f.R1r]sxڂ+40|0 X?`duȎv iJ0,[@_@+ ~DJwer87m*L`!›0> 1W3.79a12🴙2@3ʒ ,V=v-պ>=vQ ^`v`>5SQ_d3~<@Nt:,N )2l``Of@.=@OZף7o<ۯ@%bzdee[ZZ1|6/{ϟ?}8sҥw@( AyZ1Ϩq͔5u~Ç 7nЫ۷ozf/^p 3$gH<==UCBB/%%%rSO1ܾ}…oo߾y 3^p@% @Q5 jhhrRΠ nnϟp[n_~_y͉SNMjDHHH ,,D߿1}3w]޽;O?~珻߿cρ"@Q>7 gx0m jvUUUMm ,yX[[AOOW6_ :bt}yy1 djUb߿&&&L#5#@Y?6c@Ҡ;wn~ qU<娬 ߿ P1?R'0p0ա74!уW P=w7ՀA4AYE ,bؑ+8c` `P?G0Y`0@Go מ~gxO^|/8{QZ_)@O{3خbw?`*^{~)aSbdPgcfc7Ü.,+wiy:jj/7_0x ^bx? 12p0q1H r2(3Kp0\aS ~ XXdzG`Q}@\Tl(,؀ 8gmyqAI>ѷ~+177_2`~'3? ' ;?;/+70@퟿!Q[#<} *"/  $S`{S`{ DxCv<> O V?T/ `,7+WQ?%XQ/-`à* ) L;М~ $YX8^}/A Aۓ'?n  $88\|ZT@ hχ C]5X4եy|dPc: d8~!?<_PtB=?Qw`;@%cО?|woq-'>@P~~ 4 ( ,v`L/` L:l 5'Z5çS_x 1޻?_=l)@c؀2+7é9 e1yӛ/v`6 `Ԅlfax.͠,ʘ>P ,''+`4Xrd=T}0U]. @\ [^sǃq/WWbgr4P3!t<mp],nh,0/1"b?*7v..zõD ,DTe|ݠ@~}wpr9O@o`$b!qcP owbX88bP_Hi O0<yfd,.< /U؎N5Ɂi P~Hh ŝ6wf+dA_A߰8P="$,#7`iwkOaeee-7a%kBw_>pal(Sc/3ĕ00 eKa+]la3{>&~1]eW.,̇ `=)...~+4&Ocxќ۷|jǃCZ2{(d&lv@k;&91atUv A9i`m mGt`.BJz`;`ч V>޽+@!bׇo^4 ܹJoex!: V2vs@E %?p_/ sg3|aQWc I_e5l x' hЌ1.@积o} l1 t_,c< at!Wg?ԇ߾3xaf/?" sK`QM:!r1 j0y˟ 01?|vN>GP_ׯ5+6`ͅ 7t1{dPql" lmj`O`ɞKQճg~忐o@0>wml>gFf>/|@!ܞ=@thn,`\ Mn@U@?-`XTh ggx  8X9:/8PLs1;/1Sû3xtϡ}P1@??_V˝ml0 X{l"?t<#hT 30e*w0n` 10fal3 _3}z ,C`R`a`=,zXϮ1`{M.fN^`؏~}%rSdBwpeV .a@1`'z *2C 3M`xc>A~I̠P'#?A|g`{`,=l<, L X=x>ސ=А,.c?o/>&|9 P=ڃC};1XpFϷA{72Å3 -gX0pqS?hRc3gt1#,~}f`L=p+-i5U^XaN[c~ % T|wM< |0ma`x,.4`dx|t52N`/ 9ԌfS 8y <݁]vVA` , /]c*WfX{"e`fzLعga3` ꁟ0s_w!nl;>ij`,|8Oz2Po`72FQPN>X`bD"\ žOnegp=0#]Iѳ_h؞ۛ 1s3l{6^}Б߁ʚaD520%{t̸ GbF`Jcy ҋcbFȨ!Dѹ )ު rJ\ 6y9x8>/n p k3/OR`` H;l៨ αI&H=q#ïtO~}W_}k b~ t tpWh?A_H;T c I(Ą?e'{߻4L% ,ξ1@G?_^~g`~d3` đ?ZoPGDs(yb|;~ #6zn3<ïW L ? G1>@ q_+C#?8 X&BXZ݇/@, oH!zh80lX:*JIENDB`Ext/Images_App_HighRes/Nuvola/B48x48_Toggle_Log.png0000664000000000000000000000774510133714020020715 0ustar rootrootPNG  IHDR00WgAMA7tEXtSoftwareAdobe ImageReadyqe<wIDATxb?P8=@C4=@C 70刲8U 1 )nfíij+y|gP/J1 za9Y yrܲ/598D퀲M14``bO1HcI4gЖa`f*$xj8J7X1=g~t20ȖU1+!3`a](!ͤ͐iý& à* T-NȍDw0q-LrYj^c+Ɨ ^!,\r9 |@%@ѷv^ao`͋/A=u025.b[MŌ'2w72ب1De1ܸ/ *_te+J偘 D7pK)15bw }e1^Go2|!"A'G>}ĠiACуA[* Z?0 @@sTANJ2ÿ g ÝW_9tM{)[=W1'7l"0?MDD{xZ4+b-(tG^Gf&% pN6R"|[s~^CjVf-v.dE&ìDyf#cn?`}9ן~2q0<~TIʼ-O_2|b0Ud0Q`g+t0󏿁/0?~X1?x| dFLo'0~awpED;i:)70?`f{V`,|zן `}헟 v1 ^}Y $"1/  ukŧ P) P<ۆu_QeX&ưᢾ $" p@73 L., ,@Gl~c/P \|o  b" bx Nw_f8rob 6^xp9 ğ jM|_7F o0,{+#m`HK p `oX*AXcPz?cADX7 ofdo?2Ġ(ưgǭ_ V"s_?le @7%=`Д{pkV0E ALIX lP/00+.Vpy,MP4"& %n2~Xp1[ /2p ~gص9û#7o0vWa @'Tzީ \ 7^yqymJ3, p0 ـp0p3) ’UeԐV\ ."A5, + k402?3`-(s< #xVyzHn('WyVwc$lgxxTWv @ A`SXW00z:8{F; &S1\ùG[vbP[D1lmq:IJ62)}A۞aY31?`rd$akgo ?eq=Å??õǀg?P ~j3: @ĴF$MdV&oz!}LcJ_W2zk x~dxp%ɫ_ӟ3:gPfmVa@ۜf0NַUe=r"Cg Ͼ0HnfcxG</ ׿ }c8wٿs^}K7[sw14AE%X<@z""̳,2y}`pY / jNw^0?}O[phSh} mۼT4DJؑdqVِgjRASAUA]O Oa8~O~ax>ó7eShH?:=:/B w)IQq[73v헿^zՏ P@}M =W]JȘtg-7;>0_>@ PG( i| r<҅bh94M:;1 r<kC@fXi+!53R4=@C 2ƁEZIENDB`Ext/Images_App_HighRes/Nuvola/B48x48_Error.png0000664000000000000000000001057510131211552017757 0ustar rootrootPNG  IHDR00WgAMA7tEXtSoftwareAdobe ImageReadyqe<IDATxb?P8=@CFFFr55CLcׯo߁*!0G߿3qaϟR76= AdkiE20,UIo p>*D'{4/=w>d?jJc9::I@6߳Xx[!! sݻ>l*H'zY]#`cϟ?p 豮bepN?&>X>}O *"F=Z@ )-ϯ_2|ga65eaa+fb%_ fE7 z S_?y۷\N3p 6AhJׯ\bfplM'E~C^NS+м R " DD,0`a `djE9R#~ y~nnX݁Yg^2|z揸8~`Hos}&¼$ _ s䊊vuL?G.v@@yvbnhhtÆ&ϟ3? dc[@7@CU''#0Q>xCQ?q9CXX߿Ź@G LFf3rq1()1{A|EC-E30*t?BIBYX*UK|>0Z*+$;У6@O upq}bb@O.tWTdx`OLd'ß5^^OOXc&1=FLbA4&  @Kr *XX~qf;YYvv ɂ̥?F)ZEEE~7_VF%\FU""e/?@G3 1'fƄ(##'~5% ~ @(ϱ{~7!z4 d( LhMspHS=8OtKHg;7oH=* \lB+K8_f]6[@@_1p13H @x z|=bP޲ Q v0'33Th(o`xk^&2`ltINN;G $ǨƠL~ F`)-۷Xđ# -B/+!<В_P# 1Ce fPPVf8Tw`ct)c@$@0Бkw:5 V'7=t4@6+L+`W2ǫW-"_v؁"Ś_(_g’Am]]T#Z/+yBWw/1 &b! y݁i]ؽ yJ,Rutt%$$&{5P@c@[W xHko8*1P'`57,tuAMI/&~ef{_7212neMAM?副,@A22 Sܙ}@ጁ\==p:Xy`Qˠljsp0\ֲ_8o@lK:X@a4]]kv|OIAk?CDXXX0hKKK7ه k 20j_<&-"q<;JUC~gcg`L P TZYY1?rDٳ Q@@(͋v`a&}s<'W:20N-aۥO1JNёA[AA8)(y PDžj!r'Y! lϟvkwn|댜6m3 $-0c?z4jATs b Po6AEE.K9V셟?ƇoN?y XSف*Bv`Ϟes` @(_wTeerrQ8pj0ǁQ{?߼9u7Xȟ{[͛)ށzfX26H"9 G|y(P>tj Л Ls| ῡTÉ X:p߿_޼9wpN# K G` ,rA jr1hx#0=zׯ/&'(_()u*qs;f@O0Aɠo!!`yn!B @?+!! ;mmp+ x`f8 t<2|t^`s46 r;@ЀlRz~vB=pW\8pfgvaf'..bL^ X,y uA@둁cO^SJMhu`koJt'< *+k7n0g` wKwP~ ~r͛K~b;cהLQX_$4܁<>1+t4 jA|B?#tHA4@C;a b;x=Ă@ 53( b:tIENDB`Ext/Images_App_HighRes/Nuvola/B48x48_HTML.png0000664000000000000000000000646610130000760017432 0ustar rootrootPNG  IHDR00WgAMA7tEXtSoftwareAdobe ImageReadyqe< IDATxb?P8=@`dddptttP222}ˇ޾}{7o^ @,,6p)((0$  >)U@G OJG' @F;S2H$hTW})"RrIpwsnf Y{2րWk]wv>}F ˁBs!NZd`e y ~R@L$#6%ba0(^ f 1iX$)!A T9YJq1LAL\N@ h*0Cxex?Á_&~ XϿ$ X< yFG_1lLY/_?g͠ΰ+ŏ_?x %fx/f&Fc  ` >|ͰganIO x88xXؘ!Xb';` 0hgp'Â-Ɏf@1*30\v8? ; ?i@ gdb`̫ l _|e3ׯ߀;W^p ý)@]30wsW>1\" lJq[W)}n?~p `1ʗ LLL ܜ ? 7a ?dcPqd8r C?Pf[ bTp;g`db𓙓(k! l#ЃOXX I'T˷n?yp]?n3<{pû_889@~1'X0C0^c`p;O3Xw f`e`fcc`_߿2y>Ã'չ@=bs@0?G`p2gxp Ã$ uXL20([0\}a} t_pl00=& 20H3pr1 (W=-`i?z m!bbfxß`faxr.ó~KCSC`&z{0vfr2;"3ۥeDDxy~}]Z VdV6VVv^xx9xp @00|%$+& ,$``l23x gW``x%4åw8eq<<@D@y!nF`뒅'*XG?E/7Yy/1?0ԙ 7l-c@3gBjë "*👝OÉAX7`PY5*{BHAJQ(f`L0=*'% `cxd/?Vc":@zUINd#WK sO_q1Rô "u-ePßAKWAMM̞>| 8TD9}`???ï?Bl 8ce0WfP6'@S]3Dz@QA[E [@ nQbWV/P!< Po: ՠ t'öT\ * C@K]@ XV3`aP7?`,AIA3ıy HuA%Io ڪ \ @q@h(GفҼjAa \bư%!b!?)tI5'C Z _% DL 00 ձ |12 XHضѕe(0{UdL~~fpl>D` `? v\c*Cu*<Ÿ@DWd1 Вch ec.$~`X${?`+' O_aVb+n3PDT1==Bb*n=zp]s/0óŸ? @)JXK[OLE@$z@gPbPdآ7_~K VXJJ[f&4`A-D0@U3b:s0+2h0B=\/36гB? $]l bh "vƒ|y r e>bO p<"{I |5,)C0@xsԚtr_c 0)}}>_ ̈쬐9ɋnaly& Z3ap]<}ovhkpȿqZ])A Nm`ퟟn \'hKQCJZ0=K%t˳^9,]YD}c0҇KEhy)~mi 7ó ԿeΠx ҩ.3|83 0X7 2K3bP4g`6-~3#0蚲0~+iF9>Q]` K5g{GXY&(a`Ue2gb^eOf5d z ?l2m \E>B1(@@iZwiHzIgP#5g9[8 J w.bn6Ҁ_߀%7&`C L?3((30H( rO1w&vM 9y1g Dt=ݑ=ݫ^p3 :0Y8~uv5a{.PnE'8?;o@ h2d B| = ?L, >c[`Q ^V393?30;3Hp_)YNJC%/~ &|(&&GC0&XX?pП%bIX.s.u2~f~O1*J0/QePXk._]n 3$1CsD(1a?ԌJڟb`ȠR9(N]Á gc8qç +2D\˪>9)Ҧ`g \E%4π%C=INkLBRgE?Cy*` |gvrc(p.x#014G=pyl8+ž4:j0@b0h431 j .21\< ?i%/`qgI Ro1{2s`r4;U @8Y} ,kF6~i0bb8qZAa&o< ?ffDD/``LKdV%76'3_:er p%Nmkd v=^UY tPkAI 3>AWvFsXؘ0f6`F=nci]F?WD" `fK[np!K(b oz79f/7?=9!WT{]_]>2`b> `Jʟ_a/ 3bLؗNL1 ơ .MIENDB`Ext/Images_App_HighRes/Nuvola/B48x48_CompFile.png0000664000000000000000000000422310125245344020366 0ustar rootrootPNG  IHDR00WgAMA7tEXtSoftwareAdobe ImageReadyqe<%IDATxb?P0@1& ߿)G IRrOgݾ};<@31|߿ 1W{{)))d;ZIϟ? 3]h*glBϐPF8 @ < s "sIK)9#X=`B9DCY :JiəAJJ D!bEZJw@-cCj2zB-YqZ!8 :bW~ŗƉI6Ę@, %w?3ٽRA4Í3#Sd'ѱ@l!c`TM2DV+!p/* ƚ ?1|ݞB U{U+2B1@, 雁߿^0!d> $@v  G5|B1i Bœ@G:?` @Cx3i=b`{DUR &?_ ^pcL1@İtEgE_md>LN= & |ME [_db/+ +@01psq0\aْ If V0p=  & w XAcðpÕo&L gd8p:fFN׎?I!6R_`Q˷/ vjv K3N f螴A^Fԡ 3g1Y2| Xy!:;þ= L aX?b PU "4|A[aS` 6ix &B}OXeV')@`k; [r!mC: &jv" ߸>=3(1@LԊb"gs0@ !B`"X G#O Mt3K 7G5@ax˗/@xPi: [>{,((a؜0:c؜1:!c؜2cǎ||| g{ s\55PQQQf:u+89w'`,r;~,@tJ8g9贖J??Z @C} @Yj IENDB`Ext/Images_App_HighRes/Nuvola/B48x48_Configure.png0000664000000000000000000000552110133443174020613 0ustar rootrootPNG  IHDR00WgAMA7tEXtSoftwareAdobe ImageReadyqe< IDATxb?P8=@C4=@©j!:###7P= PP9-m6>@Ubbb"" BB" ,, ~dx޾}_3ⓀyO < aNN70--uAA~vff&1| nݒ8spÓ'w1r < };yaaAVV&O_| etzb-=@LDz??ssӦ- `O?3z(: hb—ly?k]PgcgX`bbd+;;3 ߿'€V &j`r߿0q -ao{ ¼,@0cABBϟ?1@1a)*UYY"|T`߿<_a{knp ř`{D,9H[:b 0<F@@YKK!<<Ƌm)~:@i߿mϞ= eb̌ m EZx 0_#qpb`7;py$?~'߿se'!P $6$$l@@)F% 1  ?=/ȴ0|ׯ߻wϟ`23,@1Lb" S@`0tR~\ڸ8w߾uP 7TEI`PBAfb@6 ;PTÂ<e?33H מ=d12S166Cs<$ׯ_ _~\ GP@# 6\{?7_|\`/P^9^RR^@<NJ?~ ={7di)rT^997KK'55M11q`;TB\x 3Ф[)S&3l޼ 9\L _xb@3= J3v+9 bcVܔ%5 Oa:u Æ +0n"`+CHـM+T166 %577}m`-֬Yr@x XHJo}>f M+cD;33Vě9PVV#ګW/ Yb@LT+n-ؽ{E2ܿX|#T< ,~8E,@1Qe`~҇ J>S=7 5@O,z" 'nJk]7o&O=&@#PQp-$PTTFPL H<0&WZpcΜx+\ }Fʨ: .'H6KND@=LNQ+V{ 'OނYaU~0ObX,cb<@4t, ́K~8g4pGx J:Xsp22$$dc6扳x񬫳fM&?(& ߿`xlK= ə?<@449X fk#%!.m- uu1L`g͚tcԉ$PL R" 12a``9PC#10\e @'ön -޾`, !?_ F[0 0R`*z6d -İ o9|@G/ uf=,~Hz9\  ga{/ |cЗ``Pc` _PHX؀ԗd0o`eOgİ9:񟿂Hz| XH!r񛿭O: bm`JU\^'B;clcfvae8aEAlx !;Ý Թ@?r@Yj9?}% 2.=qh7`dcPc,@`1p#`:xPg @2H b!Wxe&5(R]yic-I.00ll, /32|p<eܷ0~\ރkЎR*b"^ 0`Qx Mk?3HrkEU` _A雉A ʬ x.A߀O! @Ld6AK(o.kb(\KWmHP߁I:T΃+.xt<]FCU<#6\ɼߥ s1|V!̌AV@!I2m?VR@(+  Xc` @cf@i Fp'6:*g//3X˞HK=9 ǃɃb\A G\X2|# 3wky3?@ֶ|@ZHakq2p10L %, FH@uD.S8vp%Oo?FƋ3eȬonH*l]B" ʺFϯ@ֈ,FF f O .^y!UN w!L/p9 awMf>S[7eH.?l`P!n{ Jba} /fz@ r IƂ&`ǜ1HQ"7X_Ja Fp!r47(=O_0|=@;A{@B&+VXK [BHI+`[C:/=;|?,)$ΰ$c'p[?h}:ȕRX @Ġj [s~!KT!i{]`6ac#ƿ3sJ3|%X(CĠ%_i.0Â@w(#& 238X>1ew'`w2LX:0s 0K3 H?1< Eg"fa r[RX݁!l⼻ 3pc6H!;0Y@Hy @Gx J'X}ظCa5pB!X3/J`{LLTЬU: 8l Sw3`rJ2# o_Y -rDYcn ?'֞}\`^2l ^\S@=^> y@O,~7Cq}˷24`l, _>3a`]oSbF%TûxİG~19 ص @5ḑ@}lмqb l _}< ZeD $`1؎O5RZX@C~ h{  -,ez IENDB`Ext/Images_App_HighRes/Nuvola/B48x48_Laptop_Charge.png0000664000000000000000000001151710133447046021406 0ustar rootrootPNG  IHDR00WgAMA7tEXtSoftwareAdobe ImageReadyqe<IDATxb?P0@ yА@DFfŢl 2^9UJ 23x3%@Q÷?Z @,tK0zeat2ۻ 'hrߣ$?(|ˏ '.gxa0V#W`LӧOSgΜ~^f&~ffVfaf 畖dd$@Op 28;;00~@I8F%#`Z eJb8Y00'0̬lo|s?4UMEY\\TY__WPKKQMMAXX ߿ [/  "GACktDT=*I`Vh!󃙙++@ܾ}_Z@qKNUUww&w&VfGG.3~yA^Sh?i-\pϿfb } pz`c; ǃ#(/]ǎ:rXҶm't1|>AH,h炖>Q `# |_:Y cdeb?Ñ@E6?`e& +3#g X<Կ;CО=O4c̲fbSXX76`A Lv3^hd <CpPCt.00pyP{A5Wff@3~B?/~xm=w(5>IPEu  I`X -CH-Vve&fvFFff~) +z]HHBE^b_/kxX 3'Z0ʵ n| ADD[09112E H2J~A `q 8_>}|+K~7 5%~Ukk'3O2K:}_ YX,Q{u`KC)I0|8y܄on @߿gqki3k1r3pj\H9ISߪ _ dy̛]xOфAy}]c#N2|9:A@OVjE+1 ?o֛Oa2Ymdx1(@ ,5@u_Y403iœ ~Kr1|SdŒ7 ?fxîw7z{o` ;64P^`;\w<r(6A '2gVi/d!]aĠSm, J]o/yb?@=_̌ 2 Rr9XQ*+*Z> {.0%1# l1(v!f`4 zX:-hfpm֮Ns+̏'~h @OcTͫФ~'/ ``6#G>n[|ؑE`qfH*p7+0_e *u6!2 ֳ>Z LAR/=W/t~|SW0D4Pp~6?x`8 ` Xa~^>&n RL "L d[`zkXxebb08@XxXg!Qw8Óa -A/zfW ̰4q1ᙸ1߰ h, 13<{ 7e>R ?0Vxv Wdxh/9'QТ er=[}nGb#jǧ.^c\ MDd_'p~PJAAճ_ `|3c&1I dn%Me+ ׀h'LO2\; *  o p3I~Ŭ-k?(W+A#nywI-/  ?c:^c+,L;Kg3J 11| OWLD ?;'' ( R>U @c o|>@v6r&?pVsA] 1fȰ \uSY`ZAA؎2l9ˠXNk2u!/xAE z !-0#A*p2<I[ ?pZ[e-#8sg:~K13Lۙ?as3V5Ae9s O V< ~C.k`pcQg  1 :ç_tldV~_5,A! X+z adp'S)? B`^%1v#ÒN F *Z\;CT, 7`Aؠ5$P9&ޝ~5 Xz{>`ssf%/r2o`[ʏ?_ [l~KzdCK'02dx+A"/2K(2 IK^>P~yW 12=cV1p!%/+M/uht1 @˟g5LLw3fbdA<=^c o Cf&7X^ffcggvS=pr'Ǿ(p3 r02|NF~bt?0?2C^@,_wƿ3201:e+?Hfi o:u X&21Z߿_7{;; 4D>~zחIzOP4ҩva]}U@%f `π22yQ5=r2 00l;[_0q\D  P'q  Ηvl̗X /\cxwZVHS(@,hSGdVQJgz  =?Ϡ!M82Z/M 3A"uf6:5gߒ:STh̯*llnLϿE,H]b@3IJP;A*QŁ3S .tRF Α v9xޯz@43a@yJ$CKUǫ~Xd2B0$bk%hА@ y2"IENDB`Ext/Images_App_HighRes/Nuvola/B48x48_No.png0000664000000000000000000000576610125245344017261 0ustar rootrootPNG  IHDR00WgAMA7tEXtSoftwareAdobe ImageReadyqe< IDATxb?###5@?2b( .=#@1R@9@lD!] Gsrq1033p0jj203|5o/^0:s a;ȸ@'3D:^@MW9(LJALAHh06Ȟ_=c`x {bu.4yx0ݝ!ΎA?nb I9 ~̔ v0<@C@|i)  lC21< {Ob(>pxf'!fe`q0 C`rC&P,;;Û7 s`=f] Kvsrs'L OU}TXa66 FgQpO1X*<$O,ػ10{Xg,(莇^ eAz ɜKp0N0T~Ȱwn߆ GH O18q8d /0(c q/b P6 ȞҜX]\ `0,Ǽ87A@Xh^`Q R@ `aOc`@ [`db>002(CpB5@J!5mmHu218 J!.X7Coq1X*!'`l|x1C10qxb$'m @0(20| ia.3]oa!AOpk{.h%ɡ0 `t)#@LpGO>80goANL16`|a R@ XPBXbrV$ڷ7?oLt<0ss!`㑓` TB9`IB`PQ RSI 7[dST˅t&h! # qtB*P@=a`!@0ISWcԮB}b=@=@\/3<6E*1P } 4 of38YlիD8=p Gr $  .<>A 7l3>c  ==cP!<yV%/{ F/yᱤ$Q5,15}}Dx_@* `WAFoKKK2Nx(xҺ@(8̐( r|1,PE79'@u]$G;K  a`8+)`o TO3)7) '@Q~4` @1H@!6}ϘI)/ 2<^ P5,s%Dq#.!XDg 2`+4Ăd_"bL_'+A V4 @Z@8<O {;4^6vw| R扙Ձu  030Pf M£IfytgXl ș:L6!c b Iy[ |`=45#@QVBXA!d2A7 .8̬C< #VA#מV̀E//zJ؛X|7XG4 Fj.%1hf" !`!F~IENDB`Ext/Images_App_HighRes/Nuvola/B48x48_Folder.png0000664000000000000000000001126510126472472020114 0ustar rootrootPNG  IHDR00WgAMA7tEXtSoftwareAdobe ImageReadyqe<GIDATxb?P8=@,`_02R@___!^^~UUO]|o߾g={5=@,VV̜8K?Z]|…]vӧ>͛7g^/8 Q+50A˗ |ݻ}P\HJJ>c#((@1|1ܿի^?xp§Ov<{l'A yXȻ{\VW3ܹso~Kd+>r@z 00hZߺu _j֊ՊQ~~~`O@8XACCA_߀ի@SDKT__T\\./++ h2*1fihh$ ba& RoJLL /^d}GDqG3akxxxTTTwbM& &Ǐ ex0;;_֭zKP> TDcWYrFE_?4T?2xΚð=m)PgX#+++$$t`:H01] ,1;~7÷?0~_dKA0`033߀?O</Ì ~5sqJ p1CAMAAAZ֫? +D&o`8X 䉿h)rr3|Ё OϾ3\ǿ /2p2s@0;$>'Ñ_AS] o߾cpܻׯ_=@$+'V=!AAEc ?,Ul?R dP>ʠsÄ˕m7κ?1->.V. A.]ev)Av A.Ymv|VO߀477'ûo? 'lbx)N輧 , EZ2H0Jkw@~ (3f p 1~ebbTcP`eaz 2~{B Y7 0_~ Lv?y F0䉏_w?]g``pـ KQnYFl]&)>fnQ>6_ ?~ba`:_@Ǿ Вd_({89^/L0+A-دf$ˠ# =pqA0`z4$߽hPGArh2zU3@b h;'ë -@|z@|~7z$4a!aW`Z. 66\@ n.pIO'@j? ,o= z?@A<נ ̬Oן! #,!Ȍ`3?hCX:/D'4@$.*_~0&*`޽{wT3} rC@Z oɉX#;AXr#a Md bشbfan߼ׯπZ@i Ç?t<,!R;+;4% #~eo+waW?2b:ԨB9,Jk$)AJ><Z*>PI ŋG 732ȩebWW@1@,Ϗ;w_~Àj8i]XCԁg^A?d 3"%WX, ` `/n`2|{㣯~}+} Dkϧ^g va(%?~ %&pVC C4{NP0ëG, _|a`X7 ]y mJ E黷+-py ;GTXi6v@nR#h|Pbxw k|6`wǫu'\VI 0KG޼*BqZZhu&Ʉd>l+jg3^&1 AB{~], o?Ҙk4xO 娍/0z쮱5#ЧBx}v.^Àj?PKA? 0Hpgaddfـ@r$#4F`2H@!57Г4?r1z|N`2므A<@|.$/p[1#+/7+/' |'; YE2#4Gx?R>a&.yG ;ϗ}Σw51) z޳ᆱ)4 M1 9uH9Լ?G`cO`ă[v=c e_5 kSomHH:7{/.IP eU! 4  __X}b`؀59;0vX!=7>zC á/cc`c~s9#  TuۯPa2O\?N`wKlh|zp.i0g ػ غdLi壗 o~dШ˰C@O=/_]y 0'|h D `GbdĠ}P0" P@ `-00.{Мjpl ge9s 1cd|sˋ_?0ߞ}7_ go?6401B?R?倱FQ ov0 .^d#Ϡ0 S#/ *xŹg @zw^W'&`?;$GH;`-#3*@DŽc`8L.xq!,+CÚ \ <].p흛Z|B Tܙ l?0ÏMfH #BtP&)"B: IFzs_֮Oڋ.e`x?,_O6ʳ71W ߞߐ @c~~rQ&sFFAo.@ v`PXIkh6P+\0B/`C0~c Ŀ;/}w/~2L>}e3oO~{??C|Nu}@q.>9W9-F  L ,@w~xO#MEԨ̙o'þAW$ ol!k5G $;SƓGX?<0~/˿>3| C{_\ uQ G Fĸ \ 3HEH84 o,_'HT|pߡ5~r !@f)AҘA hQ -T9)q$>@Y xC4S62Z|IENDB`Ext/Images_App_HighRes/Nuvola/B48x48_Misc.png0000664000000000000000000001173310125245344017567 0ustar rootrootPNG  IHDR00WgAMA7tEXtSoftwareAdobe ImageReadyqe<mIDATxb?P8=@`022UdnR @fff%}hI+@u?dr;@R^ t_t@0VV?~301ԧsssqrr1|Ǐ@?o}Tz&'0}… &  ~D%~jBh ^C @2@~dx?}l8 J 0I22lݺA]]A\\lڵ z pz!00QtX'<Ï?!` PL(]S`  #0P1<ر w*~ N23dfV0prraY8=@X=7G]߿@v82 ÷o?cfs^߿Ih(b@Nj`ab [UUm;\%ùsDZz 0<`iN Àr<>Ao0d(1(**& Ǡv44?2FC6_~bオ&L@KDD\(tI ;`rvCdVʰoV3g@(vZ L:_|_3ps3 ^FpA`f 7@/9@P?SDDL`L;¦#[@2vyY( -@IXQ d`aay7 y)Ae9(&@1}8VV& -IIa`yCΝ[I?VG|2`bQQ%Y0(t i 8,i cAcgy$ ̠2 RR"d!,~2ʁ=L>po>O$Pmܸ!..aٲ`V?z#0jW80z^|P&e<'@qAgJJ `gETht:|8@*V@L=z5ϟ__z N> BB|`π 0 ~}!@Ev<第A |13 p DGgK`Z:r۷t/4LX0C֨{×/?޿ #=\,rr3-7 0+|nPXK(`*!7ÇSQQ!V3.V={p'OB\,ԁe3`ǂ r(!PH܃π!O ,~98!40ܿXpHLRׯ?;ի'@ۻvmj(>X@t}`a`-K\`|,yb`;136+PGٷn߾>zjz:::)H @,v]>>~pUJRD(̓<+2AL~Íޜ9slÇwO MayC`,@YYC DVpL| ,ٸ0<*0@۷oh_UU `k .P1 ]X`yFxMK/ g_,7 l{v`9>,ޭׯt ++ 6@ֆQQ i``*,,z@-PkX/jr0_6)~>nnNp X *@?~gxP/߻poo5S@E+(&~Lm(bX ;6VV.߾}5@/J 4A%PuAI2T|oAA>x3&mɅ޽[ )@$ 2@O;>OAuɻwo~6߿?[͜D-׵@v.P@78V@sӬH/AUU aE)t ..5G={ S>QQ`O!268XY|/^PV/߁IxlMV;TT4B|>VF߿Z΍@1  emP~a.0@ H?<@=7HR6 o߾= $@,ܴp@0O0\tٳP O@}F) 5=d/Ϟ:4Ǐ_@|| '`J`Y'&&1!7 ')]]99)`9O>| e>QQQ`~QK@;iVӃؠP;!5=@f~ X*~@,8wv2DD$|*ǏRMMcF~~~'Ea(&@Q-( 5mmp)٘U03v_{f|X'\{]@=`dd0EBB|"@2xAFF\" 0O@"2t͔B6/kA?8}"27?ނ%cB PzT{T3{d._>ɓǻ@#\@F #qU}>$}vV>Á% hPO P 9&}HFn"J1'`C4<( tQ`=|_$}}I@E,wBy}j{ 'ZN:"!I/~sP  < XA1 J0?w*``6@_ '\zb0M֤޾}woCYiRǰ.\J@e ѧNǠo౥g^[>6bp`w //>nYYy`[ܟ$`"T<r,ZA%H7q߾ Nz$x+_bOa;;ak ++8{X_3@c{%/}TP~@3^pXBG!qH;N 7`} 4G<o~eM۷o.y͛Wnݺ>{#`I_>z{w@mq#/^|ہ@,ffwԁd|v;wF,ټ!bb& P03<L P+/~-0_]arB{<LnK^W\'`ӛ4Wzd %%@e>l,g)((/' tݽ{G/ DY>>>w݄6@ 3DADD4ÊK p`6I51!~E |-0Fx=@ ,y= JVhRU@SP>4W%)-rUIENDB`Ext/Images_App_HighRes/Nuvola/B48x48_KGPG_Key2.png0000664000000000000000000001014710125245344020314 0ustar rootrootPNG  IHDR00WgAMA7tEXtSoftwareAdobe ImageReadyqe<IDATxb?P8=@C4=@C4=@C4=@`022€Be``>@ Puf gXl&gL Cz:vB:X>@1&=qe%qu# %1WO3<?|z=q>hw" ~{@ C'Cl Fbrj& Zf  r8``x }cxtÙͻMG#B AC7CJe +Dx10q30ʩ,Ï@90ag44õ+}xR3*^ @$Fn ~xP?/Ë 1Hs11|cPTx.%MttlA ĩAW|{9- Ó< N ?`xñ6AEĄAOAJ17gP *A}A0S ^I% PqbAQ T;/#˻v`dG>iyyHh Vc56O `yLN~313-@\F? V22!12 1\w@f/P?oX)\8 Û? z g+۷^7XXpys1|a0:Y ll a?@, bXgk7f\dx6`  *@pclER. 6 ||@Nj1pp3 0O2|g \\ /^>gXv%CaSw\`@ CA?v$@< cͼ==d$E-00 ҹ("LLL@ϰ222>|Ço@9KV0x{g~;#q@/āL`Pff&%`l 2}%ǰqW]k[2@/;9IǔYXAQV wzAAAh_~ ;;Co3ܾ!3#a /mc( NI Pgd% fFvH1@̉S r._b /L4e^Pjkl.+{0Ð&.p2;`*keP=xY~au H (ˮO`i# t  0_fPU'/_>0 !P31V-ӧo1,b1\p+y,PG dZO_2|ק=h ȟdA(k@2M\FFfa=dPV;ThFp=r00ࡎgl77'( _<@eس K>>e)Ӈ7 10~l~h?0"UX 81@`gp1ANNA]X99 Jɓ,b޼p߾}_7Z|~~g`vEpas/H jY+lB19 @@ ضQ: @FXAM Py+Ë A1`(?`E >uׁ]llS@20{0fނv@)uih#whhIƾBBB i`XX,y50~kmipjrzhûw9 Z_V̿hE3~2ܹs3"0t)쁨l l$?|xڦ-n:"99jaK؀$ 9qqa'ރ=p#GO2a#0Y[TPK/ WI8@HH2''0$z'~|4+ U 9`{׏`0<=ƍ;iP% JJO<6}{ 0<&浖!ЂآMq|?:ЁBBB޽ OEI O~2[R 0p2(*Jc䱷@O37n J7n\`8~|/ ol(sJ)d,z_sXzbπl/r^^C`w"DffnhFe0vu]=zuRJK,@°erp  pz@UQQ Lsq=j2: 4 >c`, ,NVȱ@;ITj=zmeʱ1Z( }l&`w^((^ %?`πx6H] w<|L~YY @"WPvY偎<}nzpLзo_}`( a`OAVVܴ˗Oiuu}>`cMHHWpR`_A CC eiiA`>w#>}̰rG@:@w~^ھ}%@${>4H\\~c_|0d@DEV(a##u>>>v`ls&Y^#= lc `-[k7 D݀!,U 0V€Mv7`iX6WݸX*=0y&$@427 $`g2aa 2(lܸX }ChА@ yА@ yА@ ym=oIENDB`Ext/Images_App_HighRes/Nuvola/B48x48_FTP.png0000664000000000000000000001310310126472420017314 0ustar rootrootPNG  IHDR00WgAMA7tEXtSoftwareAdobe ImageReadyqe<IDATxb?P8=@,p02o+: 3OQ@1Ͽ{@M 9p[ % x {%U_cyE5%X%e%88ـng`7^~O{omfo-G: 󀍊0K9Y\e44 ؕDX8Q ~0|dxp-k_3<|uG = bc@Xi`g񻒕:@CDފՎA.&1f/+ JB@o@ O O2s 7?`8w?cx @ " v:812gPfaab ж :;;0[e`zo@?٘aʟ 2y{ Gv~ P <`Ŵ+MF_A=9030g??0Kb`w/;@Wm618[Kw|ʞo\N 0raZRȩd#щ_Af '031303S?3 ×_ VKB @ # P O[NmgaS O[poP\ 0a^ҫ,`Տǐ7T(óW1_ T'8G+ QɠƉK\B>feaef; ;8~;{ ɰ klԕM;i w=E ? )W2pCf _`ppp0p;?'?rpR`$!6û/1 v lR&,Ü=~Up:ȥ@a7*}Q3yO62J77;;.`o8ǯ_ XB߁QĀjΐhpwGLt]\N Ls$0w՛C0s q1J 0psO_ Z:D;{2|/Z7 AҊ7!E/a۲ J& &" @ 7?W;DJrp}sᅢKq3򱀓1,a˧ >eePSVb&%fpav(/}x? ?~_@>(O73x30. XC@z@G[˛g s`8(fH%I_  w?dx%>~pedo?޾ q?v2L^7_2*3( 20x]*bA ?A1\/bxu*޿x`/` *,+&Pf6 3/y{xGx~e\{ 9Tw03<{a]  2;o vNZ eʰZ~ ؙ'h:0򈁋AU`p9?2p01>Peó_~/&f&͘papRbV`J}ϰIW/0|lAComy+ʮM@jj qipoo1{I&`~f |b8w9T8UإX1<ӟ70VѠaҿ1O{O3\yz֋ oC$&!ג^\&߬ B7Ş=( HZ#- ?vaKy߃=s6afQkׁ ¼Zy#z;` $'O@;aĠ*?0} 7yeŀ _GHd }+NQ`# }X /bxW㳞3ZPd&pAu€Tq8023 0!SWR@!`Kyc>AB@@01 ˰1õ ?^Mق 1e)&)] ' `8=O`n3A<*7XY+?6``T ?'3Jg Lg s1ǻ lL`} oO=A"I l <l&+#ó߁3kӁz{ҬvOr|| h"7P5+@!< JL G0 W3=UfHJL |`L z?pi+u6>FK_% ./eIA s@-6P5@,HdE3 S0-`ڿ 18ҿ!TP^ j /Nj&6+ߪơ40Ocexq;׻ gPPgPg`V<@py@2y3|A>P_Af/6A(_)/24[?&0hu'~2<_AUKA\H?Pr^?#0AC?P `ǣ%tPӀEȠM?+LVI]n@0<9Cwfn>i1Q>Vǟ07t?@!Ud|ۑ_ Ϭ[e l123H8=,bXc(;[#ᠼX6`alr1 121/^a<nyA[K,XPJ e 1i+*`MhQX" a&xgU`R`Vg`>'+' ߀g\xX32pK4*Š,¯WjS?'~c\BSP6N&!Qcx`;X}aXzd;>a8й9̋2B @XCy*2mI V ߁BC+VjAHo @ B31e`P[[ N`虽偏O 44A3?@6O(2(JLaV8w_?[~rO7zokv7\?d? ̠fqD+89z0pkh1Y3ZzuQ]偪a`hڸd5Cny9+aLѣGm8%p/ Uu{,(޴ d3D8,ٶEr;>p_GP[p[ys1Ix4Ձyؼ{v!%Fdʵ[H) `NE[(q 8זl܈,f,(CXPYIͷo?'0$ESTVMȑm5gC>YXOSzY jYVz: 4'L=q?S(uSDȄ0#!tաl #@#c .]$C!d 9" [u&h_Q$=ۥ@[]--8m$h)!#(!n CQ?P_=7n '@ܒ~t N\`$ B"g9K8W3GXv\. $Y:QM#a$8F!p/eXFma`jMC\e$YU-M!0MC1ժc,4y uh*\ l>wSu]qh -o=^ Ҙ\"|, 2@r7@ cxҭ<4݄l>ڔ6grÞef4|ɐ\X`LX*.hEsafs0gx+.x $?v0`Hct(6# HӁ_ /dd@葏x 61g[N&& a%% \BBab?2,8a߽{ H@>|l1 30`:i\pxڵ 3Ξ% I@aܹ 2ZZ  bB#;d[yx0<~aݻwTU,@!x_'߻p&,E)0o H%l.Xa32|,)urB1@(%73bH6|a`ݠh[AzA4>G;8X ̼`sg L{Q`µk[y 0QM1>^/^xi== ŋ ?Bs: Jj &jam&lr@3gnhk?;z qy 0syuyUgxy`a?ABa!  : pY@zTXW Zаcc[pCXq1q.00psc`@)$/k_pr=r4 ߾5y-l1@s$˻V*جURb`␛ꭏRP d!  OÃ8=Ǟ=c㚼W桗J ̦mB_[ V w00\ IH|wMif A9`Y=؎۵sfPT I*F::6R80I13`=0c{߾ɩf뗱w@6$ P=ǀTKLUȱr;@<."//),(^cs]`m *DLp+llw>1;QWea X3 QQX7R"y0U DDr'/\~(#3042\8p=F ..|Z͛-ǯ^uǗ~IZYcЏYY0?~RA7 V{||QW%%?2l:X0107oz-e;7=OIHh0  (!@̝|y難\[ lР6_ UbTA:PHۜLL6D"0I\?zCYٕ*` s تLJLLltP2 *b%$t*c@ԅ υ.|y͇O"ր  @C :1pclA:L 9@VRR^UA! 4bDŽ[Ym`??i vbb2 ~I*u0ੂƒ `O`.,Re S @T,]jAGplY`o/dT0D+P@^ ,6,%04(=KJ/de]]p* ,@m+NIX}@ .^,G4ή@  oC`6S p.TV`p,| F==>  p '#pAPS8w7IIpF[&@C!@(@D`ߚ)@ l +54@C:c{p @C%~qp\701}a耆jj{A Abr:P?SZ<-@WIENDB`Ext/Images_App_HighRes/Nuvola/B48x48_Package_Settings.png0000664000000000000000000001355210130241032022072 0ustar rootrootPNG  IHDR00WgAMA7tEXtSoftwareAdobe ImageReadyqe<IDATxb?P0@FFFτO>޲e-/ Jr'T7o={dwbfhSc֔G]VVV.{igJ<r80P܌ebXp˗/ >^F o`x5kJ31[ppК#GNOLL~TCgu?|?-/}:P@Q-艋˘jhBB ~4ra&O2 ׯeqm`z T ""W%% ik+3rpprmիw߿{틧O~ AYTTd䈈h.)) ݻ3-E%30ع:00M_>2ySλrb ЈgOqttvuk]vKg ¢ .f(Vc0g`: u1-'; GW19}w+@pwl`8xÆ =zN1(ͿŕwhDGGZ2sss1ݻX3>gc8#Cv2 \@0ġx,H1Ei{8~g̳bS3{NKYN+3*ãT cŰ XݵӇ@94nHLL \;;gpu~~/_?2څ 2 ǿ ̨ Rr.ϡ(Z30c@AKӄa 7ep3`r1Ξ89  T ,I X/ru65V̓] Ľ ߿axr{Cw1÷? K1Xb0 pßW~SWsF c`PV6`Xa#Ã[ \|1ro1ffb=yjyB X>/Z_߄7xF`˷ a1d$ɰOv ,Usy+k0\]5 0 I31dX 6Æ ^=``gO!5 o/ݼ@=93Z7É[732gW`z C3>w&;~ 70X[Y3\?v _0q30i2(*2lܴكC 6 Y=gbВ*"Cf'+VKFYg|T+. 5f 0ϟm3432!' (%T8,cf0yx r rJ +W`x"C|BCf9w=3_ ``WfHMgT6VY,+&ht78@174404662<#"uʹ ͸G6EsE00 d11dЗ+a  ,}Xe1 {1\y aJ A ,|J |o~~pK_~3(Iq]CA[C;o?^jK?ܷoϽ3gPdU" BLW8LE};l|grDw×[7yx>bxwÍWO,5;R\ \r xEAG׀﷧$Xi=) E?m O~7P[X w'3?_0(cTa`B " o?/= &?7~n iɭx"^8]a **<,~|]O2| ޾a'33H3|Xq_;dM, <a`aԐb`JN<$T Sw?`O˘OFy;>l9Zɠ ߁؃]?_ }l}gbd =A~r?3x/? ,Z!`+ۇֿg0O?/'|xi`#={22ç~<~)0gt4o^' R rBo~?,y)ƿ@w00&=2z)÷zpG᣾ O[/x;zl I蒸1ܻAH oeO ?p;ؤY+6a>>y` n8_T¤>w׳ ķ<j/ñ [~|:2A({[U2ȞU'`23)b)a lVWİcەϿ=wEA &/cܳ3?gg/4t9ÏۯIi;C[X΃ {wGrTZ܃6т}N6f&d[9KO>;А' @0S s ?+3 ҟW?9M/5#8E':dR BF끚pȴhfK @,͋oș  > ͼCk|b-@KN0 \#«IENDB`Ext/Images_App_HighRes/Nuvola/B48x48_FileQuickPrint.png0000664000000000000000000001174710133443136021570 0ustar rootrootPNG  IHDR00WgAMA7tEXtSoftwareAdobe ImageReadyqe<yIDATxb?P@dd&IdzHPĥ _|"FFƽ\|:@c?TB(@FF1LPu/#H@,dh&9 or@zaas2PNY <dbAX@I@ES204?d/3J  L,d $#GT` E+(g1,.`Pc? k%xaµ 1a5Nׯ>cef`gg`ff{LPF fje`<t#?Pcdg{ ߹8ɂa., A/ϟ~ *C@L|S?=2+,hgd|`0rav b`ta,Oj. &A @211 X  @)o3B <<`BL@ Qȫ3T y[ rN`8}Ciu9íE $9}`AnCB >3@C89111~cI8i13G:/ÿk?ˠ``nw $ J?>N1@1%ûw?ؑBSg8~dPF+4 (ñ UؙX@bl(߿tx`=2o@OgZ9!{u ’@Coh0Ջ 03XezҜϟ@>p@Uop7;6,C Amg,ɇ} zO21;XABvH2;OW0 Қ <@r//2tA|@Vt{|w$Od8_ cZF`R,^@[ n?lUVV6y%0F u$U1(BHv3B ).`l lf`a`PbaRRW c`YYYNc$x͝a+**,-- ,,| R kl`PS}(f"0H1'1@Af60 @޻w!11^ӧ2޽exݻw^zǏoǁ1}Ăl.KK.MMYnn66H n+##` ßd\UɇZ|Bz`aetPZFj+Ng`p+cT',=\k!'N yA?Ph+IŠoJ^^1:4 6?`t2|W`;#fwo3{e`1 .z b^Ȱ{7͉ ço$@&xAYYASS֞ѣGW:d@cXa97xW!0 ?eU`cgf̰kJ"  < "vBZ'G/Naa7ß_ ª ?0zAT3/_%`X?Ͱp2@%@@;'BNNpʃ}#4?aofGx"ƿ ?c0R "gx1e)%%L?qɁ#`t4,ã$v-#sC4}{ 6U 7}>h20s< Ye{JA< 0p0Z .\r@288ZkL?`t?bh0~ sleĀ7И2wf&&C^;0i3MXϿ 8b`:?P( σ:_ prr(@=`Ka5,o` qexoV`<G2d?Π2 ؘ 2]X /}c8#p=0Tـ9T/S@ \ B*K`h.aa!P`@,*" yAZky 4SMep-AaHE;'EPb v];͇ *⬠d t??(A^&!&+!66`fo?hL>~) %{ ?$K垗 _>b/Pcܬ ?Wg9_ԿG˯ ᄒ 1:/_ L ߾H2HH00"VV&zCE+01<;&,CģU *d=l0p:Li`X CC`b٠JҠT r_^o &Fb7o>s<; /' lpK'6` 01|pPT' Ϛ2pJ0dO- 72tugft<3 fx]،Lb+0~` EU?Aibb%'Pӷg9Dd~X? `4aW,F& ~e%E3K2gfH.` A8ío^߀/+uy[{`ccw&ŗ/?gzƁ90,zL&vN72k4rڗaaq%é J= %xXy `,y>p_h['Q31A  5 Av`FEBl%0-~ws铉Xnt0H6~ǟ 7O33b74d` o+2^6hb{@! n6#0VΜ9pi<69OBx?37fXq _& 9h#'' C*+]OX@Q Tu?{n``(lR^ua; o_ex)'-O;rLRׯ@| b~9%a> _QQ1p2ؚ!촨Z h )}_~pnga z_'dݻw?~ T20ֹ*5FpG bǰ> -B5@Qnii?A-ׯ&  oUc^ n˹sV^NBh(.'(oV >xa} )) K}}p2u1u!w L<,å |z#,)i &Jl'^Z޽讀息;wt0 !!'ޖ%< @ -X!t ?Med`hc/Ax qPڗ{p:Sɱc޽@=za &πe O.dʕ JJ`1H(Lbϵ |b g5:÷|k+6FȬ 9|fp3tc`Hy;@ys[NĄ(.No3',5yye8%cVXSpqT7BV "U 9=K6JAeCLaÆ?&_|~ ,d|0+ĂVeee[,aֿ|Ogc?Dt_\;PLLHاv<Es

There are many different methods to copy passwords stored in KeePass to other applications:


Info  Context-Sensitive Entry List

Depending on which field you double-click in the entry list (main window), different actions are performed:

  • Title field: open the entry editing dialog for this entry.
  • User Name field: copy user name to clipboard.
  • URL field: open (in browser) or copy the URL to clipboard (behavior configurable in the options).
  • Password field: copy password to the clipboard.
  • Notes field: notes are copied to the clipboard.
  • Attachment field: [1.x] copy to clipboard, [2.x] open in internal editor / viewer.
  • Other fields (like time and UUID fields): copy the contents of that field to the clipboard.

Info  Drag&Drop

You can drag&drop all fields of KeePass entries into other windows:

Drag&Drop Screenshot


Info  Auto-Type

Auto-Type is a powerful feature that sends simulated keypresses to other applications.

You can find more details about it here: Auto-Type documentation page.


Info  KeeForm and other Plugins

There are a lot of plugins available integrating KeePass directly with other applications. For example, KeeForm (for Internet Explorer and Mozilla Firefox) allows completely automatic filling of webforms.

You can find these integration plugins on the KeePass plugins page.

Docs/Chm/help/base/cmdline.html0000664000000000000000000002275713225117272015337 0ustar rootroot Command Line Options - KeePass
Command Line

Command Line Options


Command line options to automate KeePass tasks.

You can pass a file path in the command line in order to tell KeePass to open this file immediately after startup.

Switches can be either prefixed using a minus (-) or two minus characters (--). On Windows, a slash (/) is another alternative. The prefixes are equivalent; it doesn't matter which one you use.

Database file. The database file location is passed as argument. Only one database file is allowed. If the path contains a space, it must be enclosed in quotes (").

Password. Passwords can be passed using the -pw: option. In order to pass 'abc' as password, you would add the following argument to the command line: -pw:abc. Note that there must be no space between the ':' and the password. If your password contains a space, you must enclose it in quotes. For example: -pw:"my secret password".

Using the -pw: option is not recommended, because of security reasons (the operating system allows reading the command line options of other applications).

When passing the -pw-stdin option, KeePass reads the password from the StdIn stream.

Key file. For supplying the key file location, the -keyfile: switch exists. The same rules as above apply, just that you specify the key file location: -keyfile:D:\pwsafe.key. You also need to quote the value, if it contains a space, tab or other whitespace characters.

Pre-selection. In order to just pre-select a key file, use the -preselect: option. For example, if you lock your database with a password and a key file, but just want to type in the password (so, without selecting the key file manually), your command line would look like this:

KeePass.exe "C:\My Documents\MyDatabase.kdb" -preselect:C:\pwsafe.key

KeePass would then show a prompt for the password for the database, but in the key file list, the C:\pwsafe.key file is selected already. When using the -preselect: switch, KeePass by default activates the key file switch and sets the focus to the password edit window.

Note the difference! The -preselect: switch just pre-selects the key file for you and displays the login prompt. In contrast, the -keyfile: switch doesn't prompt you for the (maybe missing) password.

Other. The -minimize command line argument makes KeePass start up minimized.

The -auto-type command line argument makes other already opened KeePass instances perform a global auto-type.

Additionally, the -useraccount switch is supported. If specified, the current user account credentials will be used.

The -iocredfromrecent switch makes KeePass load file system credentials (not database key) from the most recently used files list. Alternatively, the file system credentials can be specified using the -iousername: and -iopassword: parameters. The optional -ioiscomplete switch tells KeePass that the path and file system credentials are complete (the 'Open URL' dialog will not be displayed then).

The -pw-enc: parameter is similar to -pw:, but it requires the password to be encrypted. Encrypted passwords can be generated using the {PASSWORD_ENC} placeholder.

The -entry-url-open option makes other already opened KeePass instances search for an entry and open its URL. The entry is identified by its UUID, which you can pass as -uuid: command line parameter.

Analogously to the -auto-type option, -auto-type-selected performs auto-type for the currently selected entry.

The path of the local configuration file can be changed using the -cfg-local: command line parameter.

The order of the arguments is arbitrary.


Text  Usage Examples

Open the database file 'C:\My Documents\MyDatabase.kdb' (KeePass will prompt you for the password and/or key file location):

KeePass.exe "C:\My Documents\MyDatabase.kdb"

If you got a database that is locked with a password 'abc', you could open it like this:

KeePass.exe "C:\My Documents\MyDatabaseWithPw.kdb" -pw:abc

If your USB stick always mounts to drive F: and you've locked your database with a key file on the USB stick, you could open your database as follows:

KeePass.exe "C:\My Documents\MyDatabaseWithFile.kdb" -keyfile:F:\pwsafe.key

If you've locked your database using a password and a key file, you can combine the two switches and open your database as follows:

KeePass.exe "C:\My Documents\MyDatabaseWithTwo.kdb" -pw:abc -keyfile:F:\pwsafe.key

You have locked your database using a password and a key file, but only want to have the key file pre-selected (i.e. you want to get prompted for the password), your command line would look like this:

KeePass.exe "C:\My Documents\MyDatabaseWithTwo.kdb" -preselect:F:\pwsafe.key

Text  Starting KeePass using a Batch File

Batch files can be used to start KeePass. Mostly you want to specify some of the parameters listed above. You can theoretically simply put the command line (i.e. application path and parameters) into the batch file, but this is not recommended as the command window will stay open until KeePass is closed. The following method is recommended instead:

START "" KeePass.exe ..\MyDb.kdb -pw:MySecretPw

This START command will run KeePass (which opens the ..\MyDb.kdb file using MySecretPw as password). KeePass is assumed to be in the same directory (working directory) as the batch file, otherwise you need to specify a different path.

START executes the given command line and immediately exits, i.e. it doesn't wait until the application is terminated. Consequently, the command window will disappear after KeePass has been started.

Please note the two quotes (") after the START command. These quotes are required if the application path contains quotes (in the example above, the quotes could also be removed). If you want to learn more about the START command syntax, type START /? into the command window.


Text  Closing/Locking KeePass using a Batch File

To close all currently running KeePass instances, call KeePass.exe with the '--exit-all' parameter:

KeePass.exe --exit-all

All KeePass windows will attempt to close. If a database has been modified, KeePass will ask you whether you want to save or not. If you wish to save in any case (i.e. a forced exit without any confirmation dialog), enable the 'Automatically save database on exit and workspace locking' option in 'Tools' → 'Options' → tab 'Advanced'.

The KeePass instance that has been created by the command above is not visible (i.e. it does not show a main window) and will immediately terminate after sending close requests to the other instances.

The --lock-all and --unlock-all command line options lock/unlock the workspaces of all other KeePass instances.

Docs/Chm/help/base/tans.html0000664000000000000000000000725413225117272014664 0ustar rootroot TAN Support - KeePass
Help

TAN Support


KeePass supports Transaction Authentication Numbers (TANs).

KeePass supports TANs, i.e. passwords that can be used only once. These special passwords are used by some banks: you need to confirm transactions using such TANs. This provides additional security, as a spy cannot perform transactions, even if he knows the password of your banking account.


Text  Using the TAN Wizard to add TANs

You can use the KeePass TAN Wizard to add several TANs at once to your database. Just open the TAN wizard dialog (menu Tools - TAN Wizard) and enter all your TANs. The formatting doesn't really matter, KeePass just uses all alphanumerical strings, i.e. characters like line breaks, tabs, spaces, dots, etc. are interpreted as separators.

The wizard will then generate several TAN entries from the data you entered into the dialog. Each TAN is a standard KeePass entry. The title of a TAN entry always is set to "<TAN>". This tells KeePass that the entry is a TAN entry. You cannot change the title, user name and URL of a TAN. But you can freely add notes to a TAN entry, if you wish.


Text  Using TANs

When you use the TAN (e.g. execute the "Copy Password" command on it), its expiration date will be set to the current time, which expires the entry. It will get a red X as icon. If you later want to know when you used a specific TAN, you can just have a look at its expiration date.

When copying a TAN to the clipboard, the database is marked as modified. You must save the file in order to remember the usage of a TAN.

If you accidently used a TAN without needing it, you can reset it (i.e. remove the red X and show it as valid TAN again). To do this, open the TAN entry (right-click it and choose 'Edit/View Entry...'). Here, uncheck the 'Expires' checkbox. Click [OK] to close the dialog.

Docs/Chm/help/base/keys.html0000664000000000000000000003142213225117272014664 0ustar rootroot Composite Master Key - KeePass
Help

Composite Master Key


This document details how KeePass locks its databases.

KeePass stores your passwords securely in an encrypted file (database). This database is locked with a master password, a key file and/or the current Windows account details. To open a database, all key sources (password, key file, ...) are required. Together, these key sources form the Composite Master Key.

KeePass does not support keys being used alternatively, i.e. it's not possible that you can open your database using a password or a key file. Either use a password, a key file, or both at once (both required), but not interchangeably.


Info  Master Passwords

If you use a master password, you only have to remember one password or passphrase (which should be good!) to open your database. KeePass features protection against brute-force and dictionary attacks on the master password, read the security information page for more about this.

If you forget this master password, all your other passwords in the database are lost, too. There isn't any backdoor or a key which can open all databases. There is no way of recovering your passwords.


Info  Key Files

You don't even have to remember a long, complicated master passphrase. The database can also be locked using a key file. A key file is basically a master password in a file. Key files are typically stronger than master passwords, because the key can be a lot more complicated; however it's also harder to keep them secret.

  • A key file can be used instead of a password, or in addition to a password (and the Windows user account in KeePass 2.x).
  • A key file can be any file you choose; although you should choose one with lots of random data.
  • A key file must not be modified, this will stop you opening the database. If you want to use a different key file, you can change the master key and use a new/different key file.
  • Key files must be backed up or you won't be able to open the database after a hard disk crash/re-build. It's just the same as forgetting the master password. There is no backdoor.

    Do not backup the key file to the same location as the database, use a different directory or disk. Test opening your database on another machine to confirm your backup works. For a detailed discussion on the difference between backing up the key file and the database, see the ABP FAQ.

Location. The point of a key file is that you have something to authenticate with (in contrast to master passwords, where you know something), for example a file on a USB stick. The key file content (i.e. the key data contained within the key file) needs to be kept secret. The point is not to keep the location of the key file secret – selecting a file out of thousands existing on your hard disk basically doesn't increase security at all, because it's very easy for malware/attackers to find out the correct file (for example by observing the last access times of files, the recently used files list of Windows, malware scanner logs, etc.). Trying to keep the key file location secret is security by obscurity, i.e. not really effective.

File Type and Existing Files. KeePass can generate key files for you, however you can also use any other, already existing file (like JPG image, DOC document, etc.).

In order to use an existing file as key file, click the 'Browse' button in the master key creation dialog.

Info  Windows User Account


KeePass can make the database dependent on the current Windows user account. If you enable this option, you can only open the database when you are logged in as the same Windows user when creating the database.

Warning Be very careful with using this option. If your Windows user account gets deleted, you won't be able to open your KeePass database anymore. Also, when using this option at home and your computer breaks (hard disk damaged), it is not enough to just create a new Windows account on the new installation with the same name and password; you need to copy the complete account (i.e. SID, ...). This is not a simple task, so if you don't know how to do this, it is highly recommended that you don't enable this option. Detailed instructions how to recover a Windows user account can be found here: Recover Windows User Account Credentials (a short technical tutorial can be found in a Microsoft TechNet article: How to recover a Vault corrupted by lost DPAPI keys).

You can change the password of the Windows user account freely; this does not affect the KeePass database. Note that changing the password (e.g. a user using the Control Panel or pressing Ctrl+Alt+Del and selecting 'Change Password') and resetting it to a new one (e.g. an administrator using a NET USER <User> <NewPassword> command) are two different things. After changing your password, you can still open your KeePass database. When resetting the password to a new one, access usually is not possible anymore (because the user's DPAPI keys are lost), but there are exceptions (for example when the user is in a domain, Windows can retrieve the user's DPAPI keys from a domain controller, or a home user can use a previously created Password Reset Disk). Details can be found in the MSDN article Windows Data Protection and in the support article How to troubleshoot the Data Protection API (DPAPI).

If you decide to use this option, it is highly recommended not to rely on it exclusively, but to additionally use one of the other two options (password or key file).

Protection using user accounts is unsupported on Windows 98 / ME.

Info  For Administrators: Specifying Minimum Properties of Master Keys

Administrators can specify a minimum length and/or the minimum estimated quality that master passwords must have in order to be accepted. You can tell KeePass to check these two minimum requirements by adding/editing appropriate definitions in the INI/XML configuration file.

The value of the Security/MasterPassword/MinimumLength node specifies the minimum master password length (in characters). For example, by setting it to 10, KeePass will only accept master passwords that consist of at least 10 characters.

The value of the Security/MasterPassword/MinimumQuality node specifies the minimum estimated quality (in bits) that master passwords must have. For example, by setting it to 80, only master passwords with an estimated quality of at least 80 bits will be accepted.

The Security/MasterKeyExpiryRec node can be set to an XSD date. If the master key has not been changed since the specified date, KeePass recommends to change it.

By specifying KeyCreationFlags and/or KeyPromptFlags (in the UI node), you can force states (enabled, disabled, checked, unchecked) of key source controls in the master key creation and prompt dialogs. These values can be bitwise combinations of one or more of the following flags:

Flag (Hex)Flag (Dec) Description
0x00 Don't force any states (default).
0x11 Enable password.
0x22 Enable key file.
0x44 Enable user account.
0x88 Enable 'hide password' button.
0x100256 Disable password.
0x200512 Disable key file.
0x4001024 Disable user account.
0x8002048 Disable 'hide password' button.
0x1000065536 Check password.
0x20000131072 Check key file.
0x40000262144 Check user account.
0x80000524288 Check 'hide password' option/button.
0x100000016777216 Uncheck password.
0x200000033554432 Uncheck key file.
0x400000067108864 Uncheck user account.
0x8000000134217728 Uncheck 'hide password' option/button.

The values of KeyCreationFlags and KeyPromptFlags must be specified in decimal notation.

For example, if you want to enforce using the user account option, you could check and disable the control (such that the user can't uncheck it anymore) by specifying 263168 as value (0x40000 + 0x400 = 0x40400 = 263168). Docs/Chm/help/base/faq_tech.html0000664000000000000000000007052613225117272015473 0ustar rootroot Technical FAQ - KeePass
Help

Technical FAQ


Frequently Asked Questions about the usage of KeePass.

Configuration: Installation / Integration: Security: Usage:

Info  I've saved my options, but when I reopen KeePass I get the old options. What's wrong?

KeePass supports two different locations for storing configuration information: the global configuration file in the KeePass directory and a local, user-dependent one in the user's private configuration folder. Most likely you do not have write access to your global configuration file.

For more details, see Cascading Configuration.


Info  Why doesn't KeePass 2.x run on my computer?

Symptoms: When trying to run KeePass 2.x on Windows ≤ XP, an error message like the following is displayed:
"A required .DLL file, MSCOREE.DLL, was not found" or
"The application failed to initialize properly (0xc0000135)".

Cause: KeePass 2.x requires Microsoft .NET Framework ≥ 2.0.

Resolution: Install Microsoft .NET Framework 2.0 or higher. It is available as a free download from the Microsoft website: Microsoft .NET Framework download. Alternatively, you can install it through Windows Update (the framework is an optional component).

KeePass 1.x does not require this framework.


Info  Why does KeePass 2.x crash when starting it from a network drive/share?

Symptoms: When trying to run KeePass 2.x from a network drive/share, you get an error message like the following:
"Application has generated an exception that could not be handled" or
"KeePass has encountered a problem and needs to close".

Cause: The strict default security policy by the Microsoft .NET Framework disallows running .NET applications from a network drive/share.

Recommended resolution: Copy/install KeePass 2.x onto a local hard disk, and run the copy.

Alternative, not recommended resolution: Configure the security policy to allow running .NET applications from network drives/shares. Ask your administrator to do this (administrative rights are required). If you have administrative rights and want to do it yourself, you can use the Code Access Security Policy Tool (Caspol.exe) that ships with the .NET framework (helpful instructions can be found here and here).


Info  Why does KeePass 2.x show a FIPS compliance error at startup?

Symptoms: When trying to run KeePass 2.x, you get an error message like the following:
"This implementation is not part of the Windows Platform FIPS validated cryptographic algorithms.".

Cause: KeePass uses the AES/Rijndael encryption and SHA-256 hashing algorithms, for which the Microsoft .NET Framework provides implementations. These implementations might not be FIPS compliant. If the local security policy of the system enforces the usage of FIPS compliant implementations, KeePass cannot run and shows an error message.

Resolution: Configure the local security policy of the system to allow FIPS non-compliant algorithm implementations. To do this, go to Control PanelAdministrative ToolsLocal Security Policy, open Local PoliciesSecurity Options, and change the option 'System cryptography: Use FIPS compliant algorithms for encryption, hashing, and signing' to 'Disabled'.

Alternative resolution: Download and run the following Windows registry file: FipsDisable.reg. By running this file (i.e. importing the modifications in this file into the registry), FIPS compliance enforcement is disabled.

Note: Currently only weaker cryptographic algorithms in the Microsoft .NET Framework are FIPS compliant. As security is the top priority for the KeePass project, an option to use these weaker FIPS compliant algorithms will not be added. Future .NET frameworks might have FIPS compliant implementations of the algorithms that KeePass requires.


Info  Why doesn't the CHM help file work?

Symptoms: When trying to open the KeePass CHM help file from a remote computer or shared network drive, it's not displayed correctly (navigation aborted, ...).

Solution: See Microsoft Security Bulletin MS05-026.


Info  Where can I find more application icons for Windows shortcuts?


Application icons are icons in Windows ICO format. They can be used in Windows shortcuts and/or as file association icons. The KeePass executable contains various application icons which can be used for these purposes.

Additional application icons are available from the "Ext/Icons_*" directories of the KeePass source code package. Most of them, shown at right, are slight variations of the main KeePass icon.

Even more, contributed icons (by users) can be found on the plugins page.

If you have multiple KeePass databases, you can use differently colored KeePass application icons in order to distinguish them.

These icons are not included in the binary distribution because this would make the application file too large.

Application Icons

Info  How can I add more client icons for password entries?


Client icons are the icons used for password entries and groups within KeePass. Each entry can be assigned its own icon.

You can import your own icons into KeePass databases. For this, click the 'Add...' button in the icon picker dialog.

Supported formats are BMP, EMF, GIF, ICO, JPEG, PNG, TIFF and WMF.
Application Icons

Info  Does KeePass support a mini mode?


A mini mode is not supported yet.

Info  Why doesn't KeePass lock after Auto-Type?


This does not apply to KeePass 2.x.

Info  Why doesn't Auto-Type work correctly on Polish systems?

On Polish systems, the default auto-type hot key Ctrl+Alt+A conflicts with a system command and is frequently used in typing. Therefore, auto-type is often executed accidentally.

The global auto-type hot key can be changed to a different key combination in the KeePass options (see Auto-Type for details).


Info  Why doesn't printing work in KeePass 1.x?

Symptoms: When trying to print a password list in KeePass 1.x, nothing happens after clicking OK in the 'Print Options' dialog.

Cause: KeePass 1.x uses the application associated with .html files to print the password list. If this application doesn't support the "print" shell verb (like Mozilla Firefox), nothing happens.

Resolution: Associate .html files with a different application that supports the "print" shell verb (like Internet Explorer).

Alternative Resolution / Workaround: Click 'File' → 'Print Preview' in KeePass 1.x and manually print the document in the application that just opened the file.


Info  Why does KeePass try to connect to the Internet?

KeePass has an option to automatically check for updates on each program start. In order to check for updates, KeePass downloads a small version information file and compares the available version with the installed version. No personal information is sent to the KeePass web server.

Automatic update checks are performed unintrusively in the background. A notification is only displayed when an update is available. Updates are not downloaded or installed automatically.

The option is disabled by default. You can enable/disable it in 'Tools' → 'Options' → tab 'Advanced'.


Info  Is Auto-Type keylogger-safe?

Is the Auto-Type feature resistant to keyloggers?

By default: no. The Auto-Type method in KeePass 2.x works the same as the one in 1.x and consequently is not keylogger-safe.

However, KeePass features an alternative method called Two-Channel Auto-Type Obfuscation (TCATO), which renders keyloggers completely useless. This is an opt-in feature (because it doesn't work with all windows) and must be enabled for entries manually. See the TCATO documentation for details.


Key  Can Auto-Type locate child controls?

No. Auto-Type only checks whether the title of the currently active top level window matches.

Browsers like Mozilla Firefox completely draw the window (all controls) themselves, without using standard Windows controls. Consequently it is technically impossible for KeePass to check whether an URL matches (methods like creating a screenshot and using optical character recognition are not reliable and secure). Also, it's impossible to check which child control currently has the focus. These problems can only be avoided by using browser integration plugins, i.e. not using auto-type at all.

The user must make sure that the focus is placed in the correct control before starting auto-type.


Info  Could you add the ... encryption algorithm to KeePass?


AES (Rijndael) and ChaCha20 are supported. There exist various plugins that provide support for additional encryption algorithms, including but not limited to Twofish, Serpent and GOST.

If you'd like to implement an algorithm, have a look at the ArcFourCipher sample plugin.

Info  Why doesn't KeePass lock while a sub-dialog is open?

KeePass has various options to lock its workspace automatically (after some time of inactivity, when the computer gets locked or the user is switched, when the computer gets suspended, etc.). However, the workspace is not locked automatically while a sub-dialog (like the 'Edit Entry' dialog) is open.

To understand why this behavior makes sense, it is first important to know what happens when the workspace gets locked. When locking, KeePass completely closes the database and only remembers several view parameters, like the last selected group, the top visible entry, selected entries, etc. From a security point of view, this achieves the best security possible: breaking a locked workspace is equal to breaking the database itself.

Now back to the original question. Let's assume a sub-dialog is open and one of the events occurs that should automatically lock the workspace. What should KeePass do now? In this situation, KeePass cannot ask the user what to do, and must make an automatic decision. There are several possibilities:

  • Do not save the database and lock.
    In this case, all unsaved data of the database would be lost. This not only applies to the data entered in the current dialog, but to all other entries and groups that have been modified previously.
  • Save the database and lock.
    In this case, possibly unwanted changes are saved. Often you open files, try something, having in mind that you can just close the file without saving the changes. KeePass has an option 'Automatically save database when KeePass closes or the workspace is locked'. If this option is enabled and no sub-dialog is open, it's clear what to do: try to save the database and if successful: lock the workspace. But what to do with the unsaved changes in the sub-dialog? Should it be saved automatically, taking away the possibility of pressing the 'Cancel' button?
  • Save to a temporary file and lock.
    This appears to be the best alternative at first glance, but there are several problems with it, too. First of all, saving to a temporary file could fail (for example, there could be too few free disk space, or some other program like a virus scanner could block it). Secondly, saving to a temporary file isn't uncritical from a security point of view. When having to choose a location, typically the user's temporary directory on the hard disk is chosen (because it likely has enough free space, required rights for access, etc.). KeePass databases could be leaked and accumulated there. It's not clear what should happen when the computer is being shutdown or crashes while being locked. When the database is opened the next time, should it use the database stored in the temporary directory instead? What should happen if the 'real' database has been modified in the meanwhile (a quite realistic situation if you're carrying your database on an USB stick)?

Obviously, none of these alternatives is satisfactory. Therefore, KeePass implements the following simple and easy to understand behavior:

KeePass doesn't lock while a sub-dialog is open.

This simple concept avoids the problems above. The user is responsible for the state of the program.

Note that opening a sub-dialog is typically only required for editing something; it is not required for using entries, as the main window provides various methods for this.

Locking when Windows locks. On Windows ≤ XP, the Windows service 'Terminal Services' should be enabled. If this service is disabled, locking KeePass when Windows locks might not work. This service isn't required on newer operating systems.


Info  Printing creates a temporary file. Will it be erased securely?

KeePass creates a temporary HTML file when printing password lists and showing print previews. This file is securely deleted when closing the database.

You must wait for the file being printed completely before closing KeePass (and close the print preview before closing KeePass), otherwise it could happen that the printing application blocks KeePass from deleting the file.

There is no way around the temporary file in the current printing system. If you want to write a plugin that directly sends the data to the printer, you can find a plugin development tutorial here: KeePass 2.x Plugin Development.


Info  Why the estimated quality of a password suddenly drops?

For estimating the quality/strength of a password, KeePass not only uses statistical methods (like checking which character ranges are used, repeating characters and differences), it also has a built-in list of common passwords and checks for patterns. When completing a common password or a repetition, the estimated quality can drop.

Details can be found on the Password Quality Estimation help page.


Info  How to store and work with large amounts of (formatted) text?


KeePass has a built-in editor that allows working conveniently with large amounts of (formatted) texts.

To add a large text to an entry, import the file as attachment (or click 'Attach' → 'Create Empty Attachment'). The built-in editor supports *.TXT (simple text) and *.RTF (formatted text) files.

In order to edit an attachment, right-click onto the entry in the main window, point on 'Attachments' and click 'YourFile.*'. Alternatively, if the text file is the only attachment, you can even open it by just double-clicking onto it in the main window (enable showing the attachment column in 'View' → 'Show Columns' → 'Attachments'). Alternatively, it's also possible to click the name of the attachment in the entry details view in the main window.

For TXT files, the built-in editor supports standard operations like cut, copy, paste, undo, word wrap, etc. For RTF files, additionally standard formatting commands are available: choosing the font, font size, bold, italic, underline, strikeout, text and background colors, align left / center / right, etc.
Editor screenshot


Info  Can an e-mail address field be added?

A few times it has been requested that a standard entry field for e-mail addresses is added (on the main tab page in the entry editing dialog). The short answer: an e-mail address field will not be added due to usability reasons. Now the long answer.

First of all, let's assume that most of the entries stored in KeePass contain information for logging in to websites. When you register an account for a website, you often have to specify a user name as well as an e-mail address. When you regularly log in later, you usually only need to provide either user name + password or e-mail + password (never user name + e-mail + password). Here the first part (which is either user name or e-mail) serves as identification: you tell the website who you are. The second part (password) provides authentication: you prove to the website that you're really the one who you claim to be.

There are various methods how KeePass can transfer data to other applications. All of these methods by default assume that the content of the user name field is used for identification. For example, the default auto-type sequence of an entry is {USERNAME}{TAB}{PASSWORD}{ENTER}, the default KeeForm configuration uses the user name, etc. Now on the one hand some websites require an e-mail address instead of a user name. On the other hand we want the default data transfer configuration to work for most websites (such that the work that the user has to put into the configuration is kept minimal and only needed for websites using special login forms).

The solution is simple: instead of interpreting the 'User Name' field strictly as a field containing a user name, users should rather interpret it as a field in which the data required for identification is stored. This data can consist of a user name, an e-mail address or something else (e.g. an account number for an online banking website). By handling it like this, the default data transfer configuration will work for most websites, i.e. zero amount of work needs to be put into the configuration. If you had to provide both a user name and an e-mail address at registration time, the other information (which isn't required on a regular basis) can be stored e.g. in the notes field or a custom string field of the KeePass entry.

Now assume a separate e-mail field would be added. When users store both a user name and an e-mail address, KeePass cannot know which of the two is required for identification. So, in order to setup data transfer for the entry, users would be forced to choose which of the two fields should be used.

So, adding an e-mail field would be a step back in usability, because it forces users to put additional time into data transfer configuration. The current system ('User Name' containing identification information, without a separate e-mail field) doesn't require this, and thus is the better solution.

For users that are willing to manually configure the data transfer for each entry, there are multiple ways to get a separate e-mail address field. After switching to the 'Advanced' tab in the entry editing dialog, an e-mail address field can be added as custom string. If the field should appear on the main tab page of the dialog, the KPEntryTemplates plugin can be used.

Docs/Chm/help/base/fieldrefs.html0000664000000000000000000001241713225117272015657 0ustar rootroot Field References - KeePass
Split

Field References


How to put references to data in fields of other entries.

Text  Introduction

KeePass can insert data stored in different entries into fields of an entry. This means that multiple entries can share a common field (user name, password, ...), and by changing the actual data entry, all other entries will also use the new value.

To create a field reference, you can either use the convenient field references wizard (in the entry editing window, click the 'Tools' button at the bottom left and select 'Insert Field Reference'), or insert the placeholder manually (see the syntax below).

Note that field references are intended for referencing data stored in different entries. If you want to insert data from the same/current entry, you should use local placeholders, like {TITLE} and {S:FieldName}; see Placeholders.


Text  Placeholder Syntax

The placeholder syntax for field references is the following:

{REF:<WantedField>@<SearchIn>:<Text>}

The WantedField and SearchIn parts need to be replaced by 1-letter codes identifying the field:

CodeField
TTitle
UUser name
PPassword
AURL
NNotes
IUUID
OOther custom strings (KeePass 2.x only)

The Text part is the search string, i.e. this text must occur in the specified field of an entry to match.

If multiple entries match the specified search criterion, the first entry will be used. To avoid ambiguity, entries can be identified by their UUIDs, which are unique. Example: {REF:P@I:46C9B1FFBD4ABC4BBB260C6190BAD20C} would insert the password of the entry having 46C9B1FFBD4ABC4BBB260C6190BAD20C as UUID.

Referencing fields of other entries only works with standard fields, not with custom user strings. If you want to reference a custom user string, you need to place a redirection in a standard field of the entry with the custom string, using {S:<Name>}, and reference the standard field.

Custom strings can locally (i.e. within an entry) be referenced using {S:<Name>}, see the page Placeholders for details.

You can use the O code to make KeePass search the database for custom string fields (to identify the referenced source entry), but O cannot be used to retrieve data from custom fields (i.e. the code can't be used as WantedField).

Text  Example

Let's assume you have two entries: one with title "Example Website" and one with "Example Forum", and you want to insert the user name of the website account into the URL of the forum entry. Within the forum entry's URL, you could reference the user name like this:
https://forum.example.com/?user={REF:U@T:Example Website}

Docs/Chm/help/base/integration.html0000664000000000000000000000641613225117272016241 0ustar rootroot Integration - KeePass
Help

Integration


How KeePass integrates into your operating system environment.

Info  Global Hot Key to Restore KeePass Window

To quickly switch back from an application to KeePass, you can use the global hot key that restores the KeePass main window.

If you have multiple instances of KeePass running, pressing the global hot key will restore the first instance that has been started.

The global hot key is Ctrl+Alt+K.

The hot key can freely be changed to a different key combination (or disabled) in the 'Options' dialog, tab page 'Integration'.

Info  Limit to Single Instance Option

If you enable the 'Limit to Single Instance' option, at most one KeePass instance can be running at a time. If you try to start a second KeePass instance, it is immediately terminated, and the first instance is brought to the foreground.

KeePass 2.x can open multiple databases in one instance/window (a tab bar appears, which allows you to conveniently switch between the databases).

When multiple databases are opened in one instance and you press the global auto-type hot key, auto-type searches in all opened databases for matching entries. Note that only exactly one KeePass instance can register the global hot key; so when you disable the single instance option and open databases in different instances, only the first instance searches for matching entries when global auto-type is invoked, not the others. Docs/Chm/help/base/configuration.html0000664000000000000000000002451713225117272016567 0ustar rootroot Configuration - KeePass
Configuration

Configuration


Details about how and where KeePass stores its configuration.

KeePass supports multiple locations for storing configuration information: the global configuration file in the KeePass application directory, a local user-dependent one in the user's private configuration folder, and an enforced configuration file in the KeePass application directory. The first one is called global, because everyone using this KeePass installation will write to the same configuration file (and possibly overwriting settings of other users). The second one is called local, because changes made to this configuration file only affect the current user.

Configuration files are stored in XML format.

ConfigurationLocationTypical File Path
Global Application Directory C:\Program Files (x86)\KeePass Password Safe 2\KeePass.config.xml
Global (Virtualized) Windows Vista/7/8/10 Virtual Store C:\Users\User Name\AppData\Local\VirtualStore\Program Files (x86)\KeePass Password Safe 2\KeePass.config.xml
Local User Application Data C:\Users\User Name\AppData\Roaming\KeePass\KeePass.config.xml
Enforced Application Directory C:\Program Files (x86)\KeePass Password Safe 2\KeePass.config.enforced.xml

On 32-bit systems, the name of the program files folder is 'Program Files' instead of 'Program Files (x86)'.


Text  Installation by Administrator, Usage by User

If you use the KeePass installer and install the program with administrator rights, the program directory will be write-protected when working as a normal/limited user. KeePass will use local configuration files, i.e. save and load the configuration from a file in your user directory.

Multiple users can use the locally installed KeePass. Configuration settings will not be shared and can be configured individually by each user.


Text  Portable Version

If you downloaded the portable version of KeePass (ZIP package), KeePass will try to store its configuration in the application directory. No configuration settings will be stored in the user directory (if the global configuration file is writable).


Text  Create Portable Version of Installed KeePass

If you are currently using a locally installed version of KeePass (installed by the KeePass installer) and want to create a portable version of it, first copy all files of KeePass to the portable device. Then get the configuration file from your user directory (application data, see above) and copy it over the configuration file on the portable device.


Text  For Network Administrators: Enforced Configuration

KeePass can be forced to load specific configuration settings. Enforced configuration settings are loaded from KeePass.enforced.ini (KeePass 1.x) and KeePass.config.enforced.xml (KeePass 2.x) files in the application directory (where KeePass.exe is stored).

Configuration items that are not present in the enforced configuration file are loaded normally from global/local configuration files.

Example (2.x). The following KeePass.config.enforced.xml file enforces the values/states of the settings 'Clipboard auto-clear time (seconds)', 'Lock workspace when minimizing main window' and 'Lock workspace when locking the computer or switching the user'. All other settings can be configured by the user.
<?xml version="1.0" encoding="utf-8"?>
<Configuration xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	xmlns:xsd="http://www.w3.org/2001/XMLSchema">
	<Security>
		<WorkspaceLocking>
			<LockOnWindowMinimize>true</LockOnWindowMinimize>
			<LockOnSessionSwitch>true</LockOnSessionSwitch>
		</WorkspaceLocking>
		<ClipboardClearAfterSeconds>20</ClipboardClearAfterSeconds>
	</Security>
</Configuration>
Enforced Options

UI disabled. KeePass 2.x disables most user interface items that are enforced. This can be seen in the screenshot for the example above: the enforced settings are drawn using gray text and clicking on them has no effect.

Security. Users must not have write access to the enforced configuration file (otherwise they could modify it, e.g. using a text editor).

Furthermore, this method only is effective as long as your users run the KeePass installation on the network drive. If they copy KeePass to their hard drives and run it from there, the options you set are not enforced (the local KeePass installation doesn't know anything of the enforced configuration file on the network drive in this case).

All data nodes (leaf nodes) are optional, however preceding non-leaf nodes with the same tag name in parent nodes of data leafs that you want to enforce are mandatory. For example, to enforce hiding user names and passwords using asterisks by default, the enforced configuration file would look like the following:
<?xml version="1.0" encoding="utf-8"?>
<Configuration xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	xmlns:xsd="http://www.w3.org/2001/XMLSchema">
	<MainWindow>
		<EntryListColumnCollection>
			<Column />
			<Column>
				<Type>UserName</Type>
				<HideWithAsterisks>true</HideWithAsterisks>
			</Column>
			<Column>
				<Type>Password</Type>
				<HideWithAsterisks>true</HideWithAsterisks>
			</Column>
		</EntryListColumnCollection>
	</MainWindow>
</Configuration>
In this example, the empty <Column /> non-leaf node (representing the title field) has the same tag name as the following sibling nodes ("Column"), and therefore is required.

Text  Technical Details

This section explains in detail how loading and saving the configuration works.

When KeePass starts up and finds both global and local configuration files, it must decide the order in which KeePass tries to get the configuration items. This is controlled by the (Kee)PreferUserConfiguration flag in the global configuration file. If it is not present, it defaults to false.

The flag is set to true in the global configuration file of the KeePass installer package. The portable ZIP package does not contain a configuration file, consequently the flag defaults to false.

Loading:
  • Try to get the configuration item from the enforced configuration file. If found, use this one.
  • If the PreferUserConfiguration flag is true, use the item from the local configuration file, otherwise use the one of the global one. If the global one doesn't exist or doesn't contain this item, use the default value.
Saving:
  • If the PreferUserConfiguration flag is true, try to store all configuration items into the local configuration file. If this fails, try to store them into the global configuration file. If this fails, report error.
  • If the PreferUserConfiguration flag is false, try to store all items into the global configuration file. If this fails try to store them into the local configuration file. If this fails, report error.
The path of the local configuration file can be changed using the '-cfg-local:' command line parameter. Docs/Chm/help/base/firststeps.html0000664000000000000000000001611113225117272016115 0ustar rootroot First Steps Tutorial - KeePass
Help

First Steps Tutorial


A short tutorial showing you the basic usage of KeePass.

This short tutorial will show you how to actually use KeePass. It describes only the basic usage, advanced features are covered on separate pages.


Creating a new database

The very first step is creating a new password database. KeePass will store all your passwords in such a database. To create one, click 'File - New...' in the main menu or click the leftmost toolbar button. A window will appear, which prompts you for a master password and/or key file. The database will be encrypted with the password you enter here. The password you enter here will be the only password you'll ever have to remember from on now. It should be long and built up of mixed characters. Keep in mind that when someone gets your database file and guesses the password, he could access all passwords you stored in the database.

For this tutorial, we'll just use a password, not a key file. Click into the password edit field and enter a password of your choice. The password edit control isn't limited in length, so feel free to even enter a whole sentence (just keep in mind that you'll need to remember it).

After clicking [OK], a second dialog appears. In this dialog you can configure some generic database properties. For now, just leave everything as it is and click [OK].

Now you see the main window. On the left, you see the entry groups. On the right, you see the actual password entries. The password entries are grouped together into the password groups you see on the left. So, depending on which group on the left you selected, it'll show you the entries in this group in the right view. KeePass has created a few default groups for you, but you're totally free to delete them and create your own ones.


Adding an entry

Time to store your very first password in the KeePass database! Right-click into the right password entry view and choose 'Add Entry...'. A window will pop up. In this window you can now edit your entry: enter some title for it, an username, an URL, the actual password, etc. If you don't need some of the fields, just leave them empty. When you're done, click [OK].

You'll see your new entry in the password list on the right now.


Using entries

You got the new entry in the password list now. What can you actually do with it now? Right-click onto the entry.

You have several options now. You can for example copy the username of the entry to the Windows clipboard. When you've copied it, you can post it into any other program of your choice. The same works for copying passwords.

Alternatively, you can drag&drop fields into other windows. To see an example of how this works, see this page: Drag&Dropping Fields.

KeePass can open the URL you specified. To do this, just click 'URL(s) - Open URL(s)' in the context menu. KeePass will start the default browser and open the specified URL.


Saving the database

It's time to save our database. Click onto the 'Save' toolbar button (looks like a disk; 3rd toolbar button). As you're saving the database the first time, you now have to specify a location where you want the database file to be stored.


More

That's it! You've made the first steps in using KeePass! You can now have a look at the more advanced features of KeePass.

Passwords and Key Files: In the tutorial above we've encrypted the database using a password. But KeePass also supports key files, i.e. you can lock your database using a file (which you can carry around on your USB stick for example). It even supports combining those two methods for maximum security.

TAN Entries: TAN entries are one-time passwords. Many banks are using TANs for better security. KeePass supports TAN entries, by making them expire automatically when using them.

Auto-Type: The auto-typing functionality is a very powerful feature. In the tutorial above you've copied the username and password of an entry to the clipboard. Wouldn't it be nice if KeePass would just type those strings for you into other windows? Wouldn't it be nice if you could define whole sequences of keypresses that KeePass should type for you? That's exactly what the Auto-Typing feature does: it sends simulated keypresses for you to other windows!

URL Field Capabilities: The URL field supports URLs of course. In the tutorial, you've learned that you can enter simple URLs into this field and KeePass will open the browser window for you. But the URL field can do more! It actually supports many different protocols (not just http) and supports executing Windows command lines through the cmd:// virtual protocol. The field also features a powerful substitution engine, replacing codes by other fields (username, password, ...) of this entry.

Command Line Capabilities: You can open .kdb files by passing the filename to the KeePass executable file. But did you know that you can also send the password for the database and key file location over the command line? You can also use the command line to pre-select a key file for you.

Plugins: KeePass features a powerful plugin architecture. If you miss some functionality, have a look at the plugins page to see if there are other people that have already written plugins for this. Many plugins exist to import/export data from/to other file formats.

Docs/Chm/help/base/index.html0000664000000000000000000001041113225117272015013 0ustar rootroot Help Center - KeePass
KeePass

KeePass Password Safe

OSI Certified

KeePass: Copyright © 2003-2018 Dominik Reichl. The program is OSI Certified Open Source Software. OSI Certified is a certification mark of the Open Source Initiative. For more information see the License page.

Screenshot

Introduction

Today you need to remember many passwords. You need a password for the Windows network logon, your e-mail account, your website's FTP password, online passwords (like website member account), etc. etc. etc. The list is endless. Also, you should use different passwords for each account. Because if you use only one password everywhere and someone gets this password you have a problem... A serious problem. He would have access to your e-mail account, website, etc. Unimaginable.

But who can remember all those passwords? Nobody, but KeePass can. KeePass is a free, open source, light-weight and easy-to-use password manager for Windows.

The program stores your passwords in a highly encrypted database. This database consists of only one file, so it can be easily transferred from one computer to another.

KeePass supports password groups, you can sort your passwords (for example into Windows, Internet, My Website, etc.). You can drag&drop passwords into other windows. The powerful auto-type feature will type user names and passwords for you into other windows. The program can export the database to various formats. It can also import data from various other formats (more than 35 different formats of other password managers, a generic CSV importer, ...).

Of course, you can also print the password list or current view. Using the context menu of the password list you can quickly copy password or user name to the Windows clipboard. Searching in password database is possible.

The program ships with a strong random password generator (you can define the possible output characters, length, generation rules, etc.).

The program features a plugin architecture. Other people can write plugins for KeePass, extending its functionality: support for even more data import/export formats, backup features, network features, etc. See the plugins page on the KeePass website for downloadable plugins and an introduction on how to write your own plugins.

And the best: it's free and you have full access to its source code!

KeePass is distributed under the GPL license. See the file 'License.txt' in the downloadable KeePass package for details.

This documentation applies to KeePass 2.x.

Docs/Chm/help/base/autourl.html0000664000000000000000000002615413225117272015412 0ustar rootroot URL Field Capabilities - KeePass
URL Field

URL Field Capabilities


The URL field supports various special protocols and placeholders.

URL Field Capabibilities: Usage Tips & Tricks:

Text  Standard Capabilities

The URL field can execute any valid URL for which a protocol handler is defined. On most systems at least the http://, https://, ftp:// and mailto: protocols are defined. KeePass supports all protocols that Windows supports.

For example, if you globally (i.e. using the Windows Explorer) register PuTTY for ssh:// URLs, KeePass will automatically use PuTTY for ssh:// URLs, too.


Terminal  Executing Command Lines

Instead of an URL, you can also execute command lines using the URL field. To tell KeePass that the line you entered is a command line, prefix it using cmd://. For example if you would like to execute Notepad, your URL could look like this:

cmd://C:\Windows\Notepad.exe C:\Test\MyTestFile.txt

The virtual cmd:// protocol also supports parameters for executable files, in contrast to the file:// protocol. This was the main reason why cmd:// was introduced; with file:// you aren't able to pass any parameters to started applications. Use the cmd:// protocol instead.

The paths for the cmd:// protocol don't need to be encoded. For example, you do not have to replace space characters by %20, as it is normally required for other URLs. KeePass just cuts away the cmd:// virtual protocol prefix and passes the remaining command line to the system.

If the file path contains spaces, you must enclose it in quotes (").

Environment Variables:
System environment variables are supported. The name of the variable must be enclosed in '%' characters. For example %TEMP% is replaced by the user's temporary path.

UNC Paths:
Windows-style UNC paths (starting with \\) are directly supported, i.e. do not need to be prefixed with cmd://.


Text  Placeholders

In the URL field, you can use several placeholders that will get automatically replaced when the URL is executed. For example:

https://www.example.com/default.php?user={USERNAME}&pass={PASSWORD}

For this entry, KeePass will replace {USERNAME} by the data of the username field and {PASSWORD} by the data in the password field when you execute the link.

For a complete list of supported placeholders, see the page Placeholders.

Also note that the special placeholders are supported, too. For example, the {APPDIR} placeholder is replaced by the application directory path of the currently running KeePass instance. It's the absolute path of the directory containing the KeePass executable, without a trailing backslash. If you would like to start a new KeePass instance, you could set the URL to:

cmd://"{APPDIR}\KeePass.exe"

To use different browsers for entries, you can use URLs like the following:
cmd://{INTERNETEXPLORER} "https://www.example.com/"
cmd://{FIREFOX} "https://www.example.com/"
cmd://{OPERA} "https://www.example.com/"
cmd://{GOOGLECHROME} "https://www.example.com/"
cmd://{SAFARI} "https://www.example.com/"
The browser placeholder will be replaced by the browser's executable path (if the browser is installed).


Text  Changing the URL Handler (URL Override)


The URL field behavior can be overridden individually for each entry using the field 'Override URL' (tab 'Properties' in the entry dialog). This allows you to execute a specific URL, while still using the URL field to (only) store data. When double-clicking the URL field of the entry in the main window, the specified command line (in the URL override field) will be run.

Using a different browser:
If your default browser is Firefox and you want to open a specific site with Internet Explorer, specify the following in the URL override field:

cmd://{INTERNETEXPLORER} "{URL}"

KeePass will open Internet Explorer and pass the data from the URL field as the parameter. This uses a placeholder to find Internet Explorer.

Globally changing the URL behavior:
If you want to change the default URL action for an URL scheme (e.g. http://, https:// or ftp://), you can define an URL scheme override in 'Tools' → 'Options' → tab 'Integration' → 'URL Overrides'. This for example allows to specify a browser as default for websites (in the dialog you can find several overrides for browsers like Internet Explorer, Mozilla Firefox, Opera and Google Chrome).

URL scheme overrides can also be used to define new protocols. For example, if you want to define a protocol kdbx:// that opens another KeePass database, specify the following as override for the kdbx scheme (on Windows):
cmd://"{APPDIR}\KeePass.exe" "{BASE:RMVSCM}" -pw-enc:"{PASSWORD_ENC}"
or on Unix-like systems (Mono):
cmd://mono "{APPDIR}/KeePass.exe" "{BASE:RMVSCM}" -pw-enc:"{PASSWORD_ENC}"
If an entry now has an URL looking like kdbx://PathToYourDatabase.kdbx and the master password for this database in the password field, double-clicking the URL of the entry in the main window opens the other database. The -pw-enc command line parameter and the {PASSWORD_ENC} placeholder allow passing the master password of the other database in encrypted form, i.e. process monitors and similar utilities aren't be able to read the master password.



Terminal  Starting RDP/TS Sessions

You can use the URL field of entries and the virtual cmd:// protocol to start remote desktop connections.

For this, enter the following in the URL field of an entry:

cmd://mstsc.exe

When you now double-click the URL field of the entry in the main window, a Windows remote desktop connection is initiated.

MSTSC is the Windows terminal server connection program (remote desktop connection). You can pass a path to an existing RDP file to the program to open it. For example, the following URL opens the specified RDP file:

cmd://mstsc.exe "C:\My Files\Connection.rdp"

MSTSC also supports several command line options:

  • /v:<Server[:Port]>
    Defines the terminal server to connect to.
  • /console
    Connects to the terminal session of the server.
  • /f
    Starts the client in full screen mode.
  • /w:<Width>
    Defines the width of the remote desktop screen.
  • /h:<Height>
    Defines the height of the remote desktop screen.
  • /edit
    Opens the specified RDP file for editing.
  • /migrate
    Migrates old connection files to new RDP files.

Terminal  Executing Built-In Shell Commands

The URL field can be used to start applications/documents and URLs. If you want to execute a built-in shell command, like COPY for example, this however doesn't work directly, because there is no COPY.EXE (in Windows 9x times there actually was one, but on all modern Windows operating systems these commands are built-in to the command line window).

In order to execute built-in shell commands, you need to pass them to the command line interpreter cmd.exe.

For the COPY command you would specify cmd.exe as executable file and /C COPY from to as arguments (where 'from' and 'to' are paths). The /C parameter tells cmd.exe to execute the command line that follows.

In the URL field, your URL would look like the following:
cmd://cmd.exe /C COPY from to
In other locations, like command lines in the trigger system, you can leave out the cmd:// URL prefix.

Docs/Chm/help/base/multiuser.html0000664000000000000000000001326113225117272015743 0ustar rootroot Multi-User - KeePass
Help

Multi-User


Details about multi-user features of KeePass.

People  General Information about Shared Databases

Both KeePass 1.x and 2.x allow multiple users working with one database, which is typically stored on a shared network drive or a file server.

All users use the same master password and/or key file to open the database. There are no per-group or per-entry access control lists (ACLs).

In order to restrict write access to the database file (i.e. only a select set of users may change the stored data), use file system access rights.


People  KeePass 1.x: Office-Style Locking


With KeePass 1.x, a database can be stored on a shared network drive and used by multiple users. When a user tries to open a database that is already opened by someone else, a prompt asks whether to open the database in read-only or normal mode (see image on the right).

By opening a database in normal mode, the current user takes ownership of the file (i.e. subsequent opening attempts will show the current user as owner).

KeePass 1.x does not provide synchronization, i.e. by saving the database you are saving your current data to disk. If another user has changed an entry in the meanwhile (i.e. since you loaded the database), these changes are overwritten.
KeePass 1.x Read-Only Prompt

If you want to use KeePass 1.x with a database on a shared network drive, it is recommended to let an administrator write to the database and let users only read it (ensure this using file system access rights). By using the -readonly command line switch, KeePass will automatically open a given database in read-only mode (i.e. not show the mode prompt). Users would open the database using a shortcut that contains this command line switch.

If there is no central administrator managing the database, users need to be careful to not overwrite each others changes.


People  KeePass 2.x: Synchronize or Overwrite


With KeePass 2.x, a database can be stored on a shared network drive and used by multiple users. When attempting to save, KeePass first checks whether the file on disk has been modified since it was loaded. If yes, KeePass asks whether to synchronize or overwrite the file (see image on the right).

By synchronizing, changes made by other users (file on disk) and changes made by the current user are merged. After the synchronization process has finished, the current user also sees the changes made by others (i.e. the data in the current KeePass instance is up-to-date).

If there is a conflict (multiple users edited the same entry), KeePass uses the latest version of the entry based on the last modification time.
KeePass 2.x Synchronize Prompt

Note: the synchronize prompt is only triggered by the 'Save' command, not by the 'Save As' command. When executing the 'Save As' command and manually selecting a file, this file will always be overwritten.

Docs/Chm/help/base/placeholders.html0000664000000000000000000007556013225117272016371 0ustar rootroot Placeholders - KeePass
Placeholder Icon

Placeholders


KeePass supports various placeholders.

In many places in KeePass (auto-type, URL field, triggers, ...), placeholders can be used.

Placeholders are case-insensitive.

KeePass uses the abbreviation "Spr" for "String placeholder replacement". An Spr-compiled field is a field where placeholders are replaced when performing an action with this field (like copying it to the clipboard, sending it using auto-type, etc.).

References in a field to (parts of) the field itself are unsupported. For example, the {URL:HOST} placeholder cannot be used in the URL field (but it can be used in the 'Override URL' field).


Placeholder  Entry Field Placeholders


PlaceholderField
{TITLE}Title
{USERNAME}User name
{URL}URL
{PASSWORD}Password
{NOTES}Notes

Custom strings can be referenced using {S:Name}. For example, if you have a custom string named "eMail", you can use the placeholder {S:eMail}.

PlaceholderIs Replaced By
{URL:RMVSCM}Entry URL without scheme name.
{URL:SCM}Scheme name of the entry URL.
{URL:HOST}Host component of the entry URL.
{URL:PORT}Port number of the entry URL.
{URL:PATH}Path component of the entry URL.
{URL:QUERY}Query information of the entry URL.
{URL:USERINFO}User information of the entry URL.
{URL:USERNAME}User name of the entry URL.
{URL:PASSWORD}Password of the entry URL.

An example can be found below.

Placeholder  Entry Field References

Fields of other entries can be inserted using Field References.


Placeholder  Paths and Date/Time Placeholders


PlaceholderIs Replaced By
{INTERNETEXPLORER}Path of Internet Explorer, if installed.
{FIREFOX}Path of Mozilla Firefox, if installed.
{OPERA}Path of Opera, if installed.
{GOOGLECHROME}Path of Google Chrome (or Chromium on Unix-like systems), if installed.
{SAFARI}Path of Safari, if installed.

Microsoft Edge. There exists no placeholder for Edge, because Edge is an app that cannot be started like a regular Windows application. In order to open an URL using Edge, prefix the URL with 'microsoft-edge:'. For example, in order to open the URL https://keepass.info/ using Edge, use the URL microsoft-edge:https://keepass.info/.


PlaceholderIs Replaced By
{APPDIR}KeePass application directory path.

PlaceholderIs Replaced By
{GROUP}Name of the entry's parent group.
{GROUP_PATH}Full group path of the entry.
{GROUP_NOTES}Notes of the entry's parent group.
{GROUP_SEL}Name of the group that is currently selected in the main window.
{GROUP_SEL_PATH}Full path of the group that is currently selected in the main window.
{GROUP_SEL_NOTES}Notes of the group that is currently selected in the main window.
{DB_PATH}Full path of the current database.
{DB_DIR}Directory of the current database.
{DB_NAME}File name (including extension) of the current database.
{DB_BASENAME}File name (excluding extension) of the current database.
{DB_EXT}File name extension of the current database.
{ENV_DIRSEP}Directory separator ('\' on Windows, '/' on Unix).
{ENV_PROGRAMFILES_X86}This is %ProgramFiles(x86)%, if it exists, otherwise %ProgramFiles%.

PlaceholderIs Replaced By
{DT_SIMPLE}Current local date/time as a simple, sortable string. For example, for 2012-07-25 17:05:34 the value is 20120725170534.
{DT_YEAR}Year component of the current local date/time.
{DT_MONTH}Month component of the current local date/time.
{DT_DAY}Day component of the current local date/time.
{DT_HOUR}Hour component of the current local date/time.
{DT_MINUTE}Minute component of the current local date/time.
{DT_SECOND}Seconds component of the current local date/time.
{DT_UTC_SIMPLE}Current UTC date/time as a simple, sortable string.
{DT_UTC_YEAR}Year component of the current UTC date/time.
{DT_UTC_MONTH}Month component of the current UTC date/time.
{DT_UTC_DAY}Day component of the current UTC date/time.
{DT_UTC_HOUR}Hour component of the current UTC date/time.
{DT_UTC_MINUTE}Minute component of the current UTC date/time.
{DT_UTC_SECOND}Seconds component of the current UTC date/time.


Placeholder  Environment Variables

System environment variables are supported. The name of the variable must be enclosed in '%' characters. For example %TEMP% is replaced by the user's temporary path.


Text  Text Transformations


PlaceholderAction
{T-REPLACE-RX:/Text/Search/Replace/} Searches the regular expression Search in Text and replaces all matches by Replace. See below.
{T-CONV:/Text/Type/} Convert Text to Type. See below.


{T-REPLACE-RX:/Text/Search/Replace/} – Replace Using Regular Expression:
This placeholder searches the regular expression Search in Text and replaces all matches by Replace.

All parameters are Spr-compiled, i.e. placeholders can be used within them.

The first character after the first ':' specifies the separator character. Any character except '}' can be used as separator character. It must not appear within the parameters. For example, {T-REPLACE-RX:/A/B/C/} and {T-REPLACE-RX:!A!B!C!} are equivalent. The last separator character (before the '}') is required.

Usage example. Let the user name field contain the e-mail address 'myname@example.com' and the URL field '{T-REPLACE-RX:!{USERNAME}!.*@(.*)!https://$1!}'. When running the URL field, KeePass opens 'https://example.com'.

{T-CONV:/Text/Type/} – Convert:
This placeholder converts Text to Type.

All parameters are Spr-compiled, i.e. placeholders can be used within them.

Supported types are:
  • Upper or U:
    Upper-case.
  • Lower or L:
    Lower-case.
    Example. Let the user name of an entry be 'Bob' and the URL 'https://example.com/?user={T-CONV:/{USERNAME}/L/}'. When running the URL, KeePass opens 'https://example.com/?user=bob'.
  • Base64:
    The Base64 encoding of the UTF-8 representation of the text.
  • Hex:
    The Hex encoding of the UTF-8 representation of the text.
  • Uri:
    The URI-escaped representation of the text.
  • Uri-Dec:
    The URI-unescaped representation of the text.
  • Raw:
    Spr-compiles Text without encoding the result for the current context.
    Example. Let the user name of an entry be '+'. The auto-type sequence '{USERNAME}a' results in the text '+a', whereas the auto-type sequence '{T-CONV:/{USERNAME}/Raw/}a' results in the text 'A' (because this placeholder inserts '+' into the auto-type sequence without encoding it, and '+a' means to press Shift+A, which results in the text 'A').


Placeholder  Other Placeholders


PlaceholderAction
{PICKCHARS}
{PICKCHARS:Fld:Opt}
Shows a dialog to pick certain characters from an entry string. See below.
{PICKFIELD}Shows a dialog to pick a field whose value will be inserted.
{NEWPASSWORD}
{NEWPASSWORD:/Profile/}
Generates a new password. See below.
{PASSWORD_ENC}Password in encrypted form. See below.
{HMACOTP}Generates a one-time password. See below.
{C:Comment}Comment; is removed.
{BASE}
{BASE:RMVSCM}
{BASE:SCM}
{BASE:HOST}
{BASE:PORT}
{BASE:PATH}
{BASE:QUERY}
{BASE:USERINFO}
{BASE:USERNAME}
{BASE:PASSWORD}
Within an URL override, each of these placeholders is replaced by the specified part of the string that is being overridden. See below.
{CMD:/CommandLine/Options/} Runs a command line. See below.


{PICKCHARS} – Picking Characters:
Character Picking Dialog The {PICKCHARS} placeholder shows a dialog, in which you can pick characters of an entry string (like the password) at certain positions.

{PICKCHARS} without any parameters lets you pick an arbitrary amount of characters from the password of the entry. A different entry string can be specified by appending a ':' and the name of the field; e.g. {PICKCHARS:UserName}. The names of the standard fields are Title, UserName (without a space), Password, URL and Notes. A custom entry string can be referenced by its name (without an S: prefix).

Additionally, the placeholder supports various (optional!) options. Options are appended after the field name, separated by a ':'. If you want to specify multiple options, separate them by a comma ','. Options are key-value pairs, separated by a '='. The following options are supported:
  • ID: Specifies an alphanumeric ID for the placeholder (see below).
  • C or Count: Specifies the number of characters to pick from the string. When enough characters have been picked, the dialog closes automatically (i.e. you don't need to manually click [OK] anymore).
  • Hide: If set to False, the picked characters in the dialog are shown as plain text by default, i.e. not hidden by asterisks. By default, KeePass uses the hiding setting of passwords in the main window.
  • Conv: Specifies how to convert the picked characters. When this parameter is omitted, no conversion is performed, i.e. the selected characters are auto-typed directly. The option supports the following values:
    • D: Convert the picked characters to down arrow keypresses; e.g. '2', 'c' and 'C' are converted to 2 down arrow keypresses.

      A fixed number of down arrow keypresses can be added by specifying them using the Conv-Offset option. For example, if you specify Conv=D, Conv-Offset=1, then '2', 'c' and 'C' are converted to 3 down arrow keypresses.

      By using the Conv-Fmt option, you can specify the layout of comboboxes. By default, KeePass assumes a combobox containing values from 0 to 9 or from A to Z. If the combobox contains values 0-9A-Z (i.e. first all ten digits, immediately followed by all characters from A to Z), specify Conv=D, Conv-Fmt=0A. Similarly, if it contains values A-Z0-9, specify Conv=D, Conv-Fmt=A0. If digits start with 1 instead of 0 (i.e. the 0 appears after the 9), use 1A and A1 instead of 0A and A0. If the combobox contains values 0-9A-Za-z (i.e. case-sensitive characters), specify 0Aa. All combinations of '0', 'A', 'a' and '?' are supported. If 'A' and 'a' are not specified both, characters are treated as case-insensitive. '?' skips a combobox item.
If you want to show the character picking dialog multiple times within one sequence, assign different IDs to the placeholders. If an ID is specified multiple times (or no ID is specified and the placeholders are the same), KeePass shows the character picking dialog once and reuses the picked characters in all following placeholders with the same ID.

Usage examples:

{USERNAME}{TAB}{PICKCHARS:Password:C=5}{ENTER}
First a dialog is shown in which the user can pick exactly 5 characters from the entry password. Afterwards KeePass types the user name into the target window, presses Tab, types the 5 picked characters and presses Enter.

ComboBox Form {S:Memorable}{TAB}{PICKCHARS:Password:ID=1, C=1, Conv=D, Conv-Offset=1}{TAB}{PICKCHARS:Password:ID=2, C=1, Conv=D, Conv-Offset=1}{TAB}{PICKCHARS:Password:ID=3, C=1, Conv=D, Conv-Offset=1}{ENTER}
First the character picking dialog is shown three times and each time the user can pick exactly one character from the entry password. Afterwards the auto-type process starts: KeePass types the contents of a custom entry string named "Memorable" into the target window. The focus is switched to the next control by pressing Tab, and the first previously picked character is converted to down arrow keypresses (with one additional keypress; e.g. a '1' is converted to two down arrow keypresses). This is repeated two more times with the other picked characters, and finally Enter is pressed.

Note this is not equivalent to picking three characters at once. If you'd use {S:Memorable}{TAB}{PICKCHARS:Password:C=3, Conv=D, Conv-Offset=1}, all the down arrow keypresses are sent to the same, currently active control.

In some browsers (e.g. Opera), setting the focus to a combobox can be slow. If you experience auto-type failures, consider slowing down the focus changes, e.g. by adding {DELAY 250} after each {TAB}, or slowing down the whole sequence, e.g. by prepending {DELAY=150}.

{NEWPASSWORD} and {NEWPASSWORD:/Profile/} – Generating New Passwords:
The {NEWPASSWORD} placeholder generates a new password for the current entry, based on the 'Automatically generated passwords for new entries' generator profile.

This placeholder is evaluated only once in an auto-type process, i.e. for a typical 'Old Password' - 'New Password' - 'Repeat New Password' dialog you can use {PASSWORD}{TAB}{NEWPASSWORD}{TAB}{NEWPASSWORD}{ENTER} as auto-type sequence.

In order to use a different password generator profile, use {NEWPASSWORD:/Profile/}, where Profile is the name of the profile. If the specified profile cannot be found, the 'Automatically generated passwords for new entries' profile is used.

When specifying '~' as name of the profile (i.e. when using the placeholder {NEWPASSWORD:/~/}), KeePass derives a profile from the current entry password. Not recommended, as the quality can decay.

{PASSWORD_ENC} – Encrypting Passwords:
The {PASSWORD_ENC} placeholder is replaced by the password of the current entry in encrypted form. The password is encrypted using credentials of the current Windows user. The encrypted password should not be stored and only works for the current user.

It is intended to be used in conjunction with the -pw-enc command line parameter (see the URL Field Capabilities page for an example how to define an URL to open an additional KeePass database). The placeholder cannot be used to transfer passwords to other applications (except KeePass), because the target applications don't know how to decrypt encrypted passwords generated by {PASSWORD_ENC}.

{HMACOTP} – Generating One-Time Passwords:
The {HMACOTP} placeholder generates a HMAC-based one-time password as specified in RFC 4226. The shared secret can be specified using one of the following entry string fields: HmacOtp-Secret (the UTF-8 representation of the value is the secret), HmacOtp-Secret-Hex (secret as hex string), HmacOtp-Secret-Base32 (secret as Base32 string) or HmacOtp-Secret-Base64 (secret as Base64 string). The counter is stored in decimal form in the HmacOtp-Counter field.

Usage example. Create a new entry, set its password to the {HMACOTP} placeholder, switch to the 'Advanced' tab, add a string named HmacOtp-Secret with value 12345678901234567890, and add a string named HmacOtp-Counter with value 0. When you now double-click onto the password cell of the entry in the entry list of the main window, an OTP is copied to the clipboard. When auto-typing, an OTP is sent as password. Each time you perform such an action, KeePass updates the counter value. With the secret key and counter values above, the following OTPs are generated: 755224, 287082, 359152, 969429, 338314, ... (more generated OTPs can be found in the example in RFC 4226).

{URL:...} and {BASE:...}:
The {URL:...} placeholder is replaced by the specified part of the current entry's URL; this typically is useful in an entry-specific URL override (defined on the 'Properties' tab of the entry dialog). The {BASE:...} placeholder is replaced by the specified part of the URL being overridden; this typically is useful in a global URL override (defined in 'Tools' → 'Options' → tab 'Integration' → button 'URL Overrides'), because there no entry context may be available.

Usage example. For the entry URL https://user:pw@keepass.info:80/path/example.php?q=e&s=t, the placeholders return the following values:

PlaceholderValue
{URL} https://user:pw@keepass.info:80/path/example.php?q=e&s=t
{URL:RMVSCM} user:pw@keepass.info:80/path/example.php?q=e&s=t
{URL:SCM} https
{URL:HOST} keepass.info
{URL:PORT} 80
{URL:PATH} /path/example.php
{URL:QUERY} ?q=e&s=t
{URL:USERINFO} user:pw
{URL:USERNAME} user
{URL:PASSWORD} pw

{BASE} supports exactly the same parts as {URL}.

{CMD:/CommandLine/Options/} – Running a command line:
The {CMD:/CommandLine/Options/} placeholder runs the specified command line.

A command line consists of a path to an executable file or a document and command line parameters. If the path contains spaces, it must be enclosed in quotes (").

The character after the first ':' specifies the separator character. It can be chosen freely (except '{' and '}'), but it must not occur in the command line or any of the options. For example, {CMD:/Notepad.exe/W=0/} and {CMD:!Notepad.exe!W=0!} are equivalent. The separator character at the end (before the '}') is mandatory.

An option is a key-value pair, separated by '='. Multiple options must be separated using commas ','.

Options:
  • M: Specifies the method for running/opening the executable/document.
    The default value is S.
    • S: Use the system shell (via ShellExecute). With this, executable files are executed and documents are opened using their associated applications. However, no standard input/output is supported.
    • C: Run an executable file (EXE or COM, via CreateProcess); documents are not supported. Standard input/output is supported.
  • O: Specifies what to do with the standard output of the executed application.
    The default value is 1.
    • 0: Ignore the standard output. The placeholder is replaced by an empty string.
    • 1: Replace the placeholder by the standard output.
  • W: Specifies whether to wait for the termination of the executed application.
    The default value is 1.
    • 0: Do not wait.
    • 1: Wait.
  • WS: Specifies the window style. Not all applications support this option.
    The default value is N.
    • N: Normal.
    • H: Hidden.
    • Min: Minimized.
    • Max: Maximized.
  • V: Specifies the verb (action to be performed), e.g. 'Open' or 'Print'. When using the verb 'RunAs', the application is executed with administrative rights (this may require a confirmation via the UAC dialog).
Usage examples:
  • {CMD:/Notepad.exe/W=0/}
    Runs Notepad and continues immediately.
  • {CMD:/PowerShell.exe -Command "(Get-FileHash '%SYSTEMROOT%\Win.ini' -Algorithm SHA256).Hash"/M=C,WS=H/}
    The placeholder is replaced by the SHA-256 hash of Windows' Win.ini file.
Docs/Chm/help/base/security.html0000664000000000000000000004676713225117272015602 0ustar rootroot Security - KeePass
Locked

Security


Detailed information on the security of KeePass.

Key  Database Encryption

KeePass database files are encrypted. KeePass encrypts the whole database, i.e. not only your passwords, but also your user names, URLs, notes, etc.

The following encryption algorithms are supported:

KeePass 1.x:

Algorithm Key Size Std. / Ref.
Advanced Encryption Standard (AES / Rijndael) 256 bits NIST FIPS 197
Twofish 256 bits Info

KeePass 2.x:

Algorithm Key Size Std. / Ref.
Advanced Encryption Standard (AES / Rijndael) 256 bits NIST FIPS 197
ChaCha20 256 bits RFC 7539
There exist various plugins that provide support for additional encryption algorithms, including but not limited to Twofish, Serpent and GOST.

These well-known and thoroughly analyzed algorithms are considered to be very secure. AES (Rijndael) became effective as a U.S. federal government standard and is approved by the National Security Agency (NSA) for top secret information. Twofish was one of the other four AES finalists. ChaCha20 is the successor of the Salsa20 algorithm (which is included in the eSTREAM portfolio).

The block ciphers are used in the Cipher Block Chaining (CBC) block cipher mode. In CBC mode, plaintext patterns are concealed.

An initialization vector (IV) is generated randomly each time a database is saved. Thus, multiple databases encrypted with the same master key (e.g. backups) are no problem.

Data authenticity and integrity:

The authenticity and integrity of the data is ensured using a HMAC-SHA-256 hash of the ciphertext (Encrypt-then-MAC scheme).


Key  Key Hashing and Key Derivation

SHA-256 is used for compressing the components of the composite master key (consisting of a password, a key file, a Windows user account key and/or a key provided by a plugin) to a 256-bit key K.

SHA-256 is a cryptographic hash function that is considered to be very secure. It has been standardized in NIST FIPS 180-4. The attack against SHA-1 discovered in 2005 does not affect the security of SHA-256.

In order to generate the key for the encryption algorithm, K is transformed using a key derivation function (with a random salt). This prevents precomputation of keys and makes dictionary and guessing attacks harder. For details, see the section 'Protection against Dictionary Attacks'.


Key  Protection against Dictionary Attacks

KeePass features a protection against dictionary and guessing attacks.

Such attacks cannot be prevented, but they can be made harder. For this, the key K derived from the user's composite master key (see above) is transformed using a key derivation function with a random salt. This prevents a precomputation of keys and adds a work factor that the user can make as large as desired to increase the computational effort of a dictionary or guessing attack.

The following key derivation functions are supported (they can be chosen and configured in the database settings dialog):

  • AES-KDF (KeePass 1.x and 2.x):
    This key derivation function is based on iterating AES.

    In the database settings dialog, users can change the number of iterations. The more iterations, the harder are dictionary and guessing attacks, but also database loading/saving takes more time (linearly).

    On Windows Vista and higher, KeePass can use Windows' CNG/BCrypt API for the key transformation, which is about 50% faster than the key transformation code built-in to KeePass.
  • Argon2 (KeePass 2.x only):
    Argon2 is the winner of the Password Hashing Competition. The main advantage of Argon2 over AES-KDF is that it provides a better resistance against GPU/ASIC attacks (due to being a memory-hard function).

    The number of iterations scales linearly with the required time. By increasing the memory parameter, GPU/ASIC attacks become harder (and the required time increases). The parallelism parameter can be used to specify how many threads should be used.

By clicking the '1 Second Delay' button in the database settings dialog, KeePass computes the number of iterations that results in a 1 second delay when loading/saving a database. Furthermore, KeePass 2.x has a button 'Test' that performs a key derivation with the specified parameters (which can be cancelled) and reports the required time.

The key derivation may require more or less time on other devices. If you are using KeePass or a port of it on other devices, make sure that all devices are fast enough (and have sufficient memory) to load the database with your parameters within an acceptable time.

KeePassX. In contrast to KeePass, the Linux port KeePassX only partially supports protection against dictionary and guessing attacks.


Binary  Random Number Generation

KeePass first creates an entropy pool using various entropy sources (including random numbers generated by the system cryptographic provider, current date/time and uptime, cursor position, operating system version, processor count, environment variables, process and memory statistics, current culture, a new random GUID, etc.).

The random bits for the high-level generation methods are generated using a cryptographically secure pseudo-random number generator (based on SHA-256/SHA-512 and ChaCha20) that is initialized using the entropy pool.


Application Protection  Process Memory Protection

While KeePass is running, sensitive data (like the hash of the master key and entry passwords) is stored encryptedly in process memory. This means that even if you would dump the KeePass process memory to disk, you could not find any sensitive data.

Furthermore, KeePass erases all security-critical memory when it is not needed anymore, i.e. it overwrites these memory areas before releasing them.

KeePass uses the Windows DPAPI for encrypting sensitive data in memory (via CryptProtectMemory / ProtectedMemory). With DPAPI, the key for the memory encryption is stored in a secure, non-swappable memory area managed by Windows. DPAPI is available on Windows 2000 and higher. KeePass 2.x always uses DPAPI when it is available; in KeePass 1.x, this can be disabled (in the advanced options; by default using DPAPI is enabled; if it is disabled, KeePass 1.x uses the ARC4 encryption algorithm with a random key; note that this is less secure than DPAPI, mainly not because ARC4 cryptographically is not that strong, but because the key for the memory encryption is also stored in swappable process memory; similarly, KeePass 2.x falls back to encrypting the process memory using ChaCha20, if DPAPI is unavailable). On Unix-like systems, KeePass 2.x uses ChaCha20, because Mono does not provide any effective memory protection method.

For some operations, KeePass must make sensitive data available unencryptedly in process memory. For example, in order to show a password in the standard list view control provided by Windows, KeePass must supply the cell content (the password) as unencrypted string (unless hiding using asterisks is enabled). Operations that result in unencrypted data in process memory include, but are not limited to: displaying data (not asterisks) in standard controls, searching data, and replacing placeholders (during auto-type, drag&drop, copying to clipboard, ...).


User Key  Enter Master Key on Secure Desktop (Protection against Keyloggers)

KeePass 2.x has an option (in 'Tools' → 'Options' → tab 'Security') to show the master key dialog on a different/secure desktop (supported on Windows 2000 and higher), similar to Windows' User Account Control (UAC). Almost no keylogger works on a secure desktop.

The option is turned off by default for compatibility reasons.

More information can be found on the Secure Desktop help page.

Note that auto-type can be secured against keyloggers, too, by using Two-Channel Auto-Type Obfuscation.

Note: KeePass was one of the first password managers that allow entering the master key on a different/secure desktop!


Application Protection  Locking the Workspace

When locking the workspace, KeePass closes the database file and only remembers its path.

This provides maximum security: unlocking the workspace is as hard as opening the database file the normal way. Also, it prevents data loss (the computer can crash while KeePass is locked, without doing any damage to the database).


Desktop  Viewing/Editing Attachments

KeePass 2.x has an internal viewer/editor for attachments. For details how to use it for working with texts, see 'How to store and work with large amounts of (formatted) text?'.

The internal viewer/editor works with the data in main memory. It does not extract/store the data onto disk.

When trying to open an attachment that the internal viewer/editor cannot handle (e.g. a PDF file), KeePass extracts the attachment to a (EFS-encrypted) temporary file and opens it using the default application associated with this file type. After finishing viewing/editing, the user can choose between importing or discarding any changes made to the temporary file. In any case, KeePass afterwards securely deletes the temporary file (including overwriting it).


Plugins  Plugins

A separate page exist about the security of plugins: Plugin Security.


Black Box  Self-Tests

Each time you start KeePass, the program performs a quick self-test to see whether the encryption and hash algorithms work correctly and pass their test vectors. If one of the algorithms does not pass its test vectors, KeePass shows a security exception dialog.


Terminal  Specialized Spyware

This section gives answers to questions like the following:

  • Would encrypting the configuration file increase security by preventing changes by a malicious program?
  • Would encrypting the application (executable file, eventually together with the configuration file) increase security by preventing changes by a malicious program?
  • Would an option to prevent plugins from being loaded increase security?
  • Would storing security options in the database (to override the settings of the KeePass instance) increase security?
  • Would locking the main window in such a way that only auto-type is allowed increase security?

The answer to all these questions is: no. Adding any of these features would not increase security.

All security features in KeePass protect against generic threats like keyloggers, clipboard monitors, password control monitors, etc. (and against non-runtime attacks on the database, memory dump analyzers, ...). However in all the questions above we are assuming that there is a spyware program running on the system that is specialized on attacking KeePass.

In this situation, the best security features will fail. This is law #1 of the Ten Immutable Laws of Security (Microsoft TechNet article; see also the Microsoft TechNet article Revisiting the 10 Immutable Laws of Security, Part 1):
"If a bad guy can persuade you to run his program on your computer, it's not your computer anymore".

For example, consider the following very simple spyware specialized for KeePass: an application that waits for KeePass to be started, then hides the started application and imitates KeePass itself. All interactions (like entering a password for decrypting the configuration, etc.) can be simulated. The only way to discover this spyware is to use a program that the spyware does not know about or cannot manipulate (secure desktop); in any case it cannot be KeePass.

For protecting your PC, we recommend using an anti-virus software. Use a proper firewall, only run software from trusted sources, do not open unknown e-mail attachments, etc.


Message  Security Issues

For a list of security issues, their status and clarifications, please see the page Security Issues.

Docs/Chm/help/base/pwgenerator.html0000664000000000000000000003300613225117272016246 0ustar rootroot Password Generator - KeePass
Security

Password Generator


Details about the built-in password generator of KeePass.


Help  Generation Based on Character Sets

This password generation method is the recommended way to generate random passwords. Other methods (pattern-based generation, ...) should only be used if passwords must follow special rules or fulfill certain conditions.

Generation based on a character set is very simple. You simply let KeePass know which characters can be used (e.g. upper-case letters, digits, ...) and KeePass will randomly pick characters out of the set.

Defining a Character Set:
The character set can be defined directly in the password generator window. For convenience, KeePass offers adding commonly used ranges of characters to the set. This is done by ticking the appropriate check box. Additionally to these predefined character ranges, you can specify characters manually: all characters that you enter in the 'Also include the following characters' text box will be directly added to the character set.

The characters that you enter in the 'Also include the following characters' text box are included in the character set from which the password generator randomly chooses characters from. This means that these additional characters are allowed to appear in the generated passwords, but they are not forced to. If you want to force that some characters appear in the generated passwords, you have to use the pattern-based generation.

Character Sets are Sets:
In mathematical terms, character sets are sets, not vectors. This means that characters cannot be added twice to the set. Either a character is in the set or it is not.

For example, if you enter 'AAAAB' into the additional characters box, this is exactly the same set as 'AB'. 'A' will not be 4 times as likely as 'B'! If you need to follow rules like 'character A is more likely than B', you must use pattern-based generation + permuting password characters.

KeePass will 'optimize' your character set by removing all duplicate characters. If you'd enter the character set 'AAAAB' into the additional characters box, close and reopen the password generator, it'll show the shorter character set 'AB'. Similarly, if you tick the Digits check box and enter '3' into the additional box, the '3' will be ignored because it is already included in the Digits character range.


Help  Generation Based on Patterns

The password generator can create passwords using patterns. A pattern is a string defining the layout of the new password. The following placeholders are supported:

Placeholder Type Character Set
a Lower-Case Alphanumeric abcdefghijklmnopqrstuvwxyz 0123456789
A Mixed-Case Alphanumeric ABCDEFGHIJKLMNOPQRSTUVWXYZ abcdefghijklmnopqrstuvwxyz 0123456789
U Upper-Case Alphanumeric ABCDEFGHIJKLMNOPQRSTUVWXYZ 0123456789
d Digit 0123456789
h Lower-Case Hex Character 0123456789 abcdef
H Upper-Case Hex Character 0123456789 ABCDEF
l Lower-Case Letter abcdefghijklmnopqrstuvwxyz
L Mixed-Case Letter ABCDEFGHIJKLMNOPQRSTUVWXYZ abcdefghijklmnopqrstuvwxyz
u Upper-Case Letter ABCDEFGHIJKLMNOPQRSTUVWXYZ
v Lower-Case Vowel aeiou
V Mixed-Case Vowel AEIOU aeiou
Z Upper-Case Vowel AEIOU
c Lower-Case Consonant bcdfghjklmnpqrstvwxyz
C Mixed-Case Consonant BCDFGHJKLMNPQRSTVWXYZ bcdfghjklmnpqrstvwxyz
z Upper-Case Consonant BCDFGHJKLMNPQRSTVWXYZ
p Punctuation ,.;:
b Bracket ()[]{}<>
s Printable 7-Bit Special Character !"#$%&'()*+,-./:;<=>?@[\]^_`{|}~
S Printable 7-Bit ASCII A-Z, a-z, 0-9, !"#$%&'()*+,-./:;<=>?@[\]^_`{|}~
x High ANSI Range [U+0080, U+00FF] except control and non-printable characters.
\ Escape (Fixed Char) Use following character as is.
{n} Escape (Repeat) Repeat the previous character n times.
[...] Custom Char Set Define a custom character set.

The \ placeholder is special: it's an escape character. The next character that follows the \ is written directly into the generated password. If you want a \ in your password at a specific place, you have to write \\.

Using the {n} code you can define how many times the previous placeholder should occur. The { } operator duplicates placeholders, not generated characters. Examples:
» d{4} is equivalent to dddd,
» dH{4}a is equivalent to dHHHHa and
» Hda{1}dH is equivalent to HdadH.

The [...] notation can be used to define a custom character set, from which the password generator will pick one character randomly. All characters between the '[' and ']' brackets follow the same rules as the placeholders above. The '^' character removes the next character from the character set. Examples:
» [dp] generates exactly 1 random character out of the set digits + punctuation,
» [d\m\@^3]{5} generates 5 characters out of the set "012456789m@",
» [u\_][u\_] generates 2 characters out of the set upper case + '_'.

More examples:

ddddd
Generates for example: 41922, 12733, 43960, 07660, 12390, 74680, ...

\H\e\x\:\ HHHHHH
Generates for example: 'Hex: 13567A', 'Hex: A6B99D', 'Hex: 02243C', ...

Common Password Patterns:

Name Pattern
Hex Key - 40-Bit h{10}
Hex Key - 128-Bit h{32}
Hex Key - 256-Bit h{64}
Random MAC Address HH\-HH\-HH\-HH\-HH\-HH


Help  Generating Passwords that Follow Rules

Below are a few examples how the pattern generation feature can be used to generate passwords that follow certain rules.

Important! For all of the following examples you must enable the 'Randomly permute characters of password' option!

Rule Pattern
Must consist of 2 upper case, 2 lower case characters and 2 digits uulldd
Must consist of 9 digits and 1 letter d{9}L
Must consist of 10 alphanumeric characters, where at least 1 is a letter and at least 1 is a digit LdA{8}
Must consist of 10 alphanumeric characters, where at least 2 are upper case and at least are 2 lower case characters uullA{6}
Must consist of 9 characters out of the set "ABCDEF" and an '@' symbol somewhere in it \@[\A\B\C\D\E\F]{9}


Help  Security-Reducing Options

The password generator supports several options like 'Each character must occur at most once', 'Exclude look-alike characters', and a field to explicitly specify characters that should not appear in generated passwords.

These options are reducing the security of generated passwords. You should only enable them if you are forced to follow such rules by the website/application, for which you are generating the password.

The options can be found in the 'Advanced' dialog / tab page.

Tab Control If you enable a security-reducing option, an exclamation mark (!)
is appended to the 'Advanced' tab.

Help  Creating and Using Password Generator Profiles

Password generator options (character set, length, pattern, ...) can be saved as password generator profiles.

Creating/Modifying a Profile:

  1. Open the Password Generator window.
  2. Specify all options of the new profile.
  3. Click the Save As Save as Profile button.
  4. Enter the name of the new profile, or select an existing profile name from the drop-down list to overwrite it. Close the dialog with OK.
  5. If you want to immediately create a password using the new profile, click OK/Accept. Otherwise click Cancel/Close (the profile is not lost; profile management is independent of password generation).

Using a Profile:

To use a profile, simply select it from the drop-down profiles list in the password generator window. All settings of this profile will be restored accordingly.


Help  Configuring Settings of Automatically Generated Passwords for New Entries

When you create a new entry, KeePass will automatically generate a random password for it. The properties of these generated passwords can be configured in the password generator dialog.

To configure, specify the options of your choice and overwrite the '(Automatically generated passwords for new entries)' profile (see section above).

Disabling Automatically Generated Passwords:
To disable automatically generated passwords for new entries, select 'Generate using character set' and specify 0 as password length. Overwrite the appropriate profile (see above).

Docs/Chm/help/base/disclaimer.html0000664000000000000000000003026513225117272016031 0ustar rootroot Disclaimer - KeePass
Help

Disclaimer


This disclaimer applies to the KeePass program, website and help pages.


Disclaimer

1. Content

The author reserves the right not to be responsible for the topicality, correctness, completeness or quality of the information provided. Liability claims regarding damage caused by the use of any information provided, including any kind of information which is incomplete or incorrect, will therefore be rejected.

All offers are not-binding and without obligation. Parts of the pages or the complete publication including all offers and information might be extended, changed or partly or completely deleted by the author without separate announcement.

2. Referrals and Links

The author is not responsible for any contents linked or referred to from his pages – unless he has full knowledge of illegal contents and would be able to prevent the visitors of his site from viewing those pages. If any damage occurs by the use of information presented there, only the author of the respective pages might be liable, not the one who has linked to these pages. Furthermore the author is not liable for any postings or messages published by users of discussion boards, guestbooks or mailinglists provided on his page.

3. Copyright

The author intended not to use any copyrighted material for the publication or, if not possible, to indicate the copyright of the respective object.

The copyright for any material created by the author is reserved. Any duplication or use of objects such as images, diagrams, sounds or texts in other electronic or printed publications is not permitted without the author's agreement.

4. Privacy Policy & Cookies

If the opportunity for the input of personal or business data (email addresses, name, addresses) is given, the input of these data takes place voluntarily. The use and payment of all offered services are permitted – if and so far technically possible and reasonable – without specification of any personal data or under specification of anonymized data or an alias. The use of published postal addresses, telephone or fax numbers and email addresses for marketing purposes is prohibited, offenders sending unwanted spam messages will be punished.

We use third-party advertising companies (Google) to serve ads when you visit our website. These companies may use information (not including your name, address, email address, or telephone number) about your visits to this and other websites in order to provide advertisements about goods and services of interest to you. If you would like more information about this practice and to know your choices about not having this information used by Google, click here.

We use cookies to personalise content and ads, to provide social media features and to analyse our traffic. We also share information about your use of our site with our social media, advertising and analytics partners.

By using our services, you agree to our use of cookies.

Details:

5. Legal Validity of this Disclaimer

This disclaimer is to be regarded as part of the internet publication which you were referred from. If sections or individual terms of this statement are not legal or correct, the content or validity of the other parts remain uninfluenced by this fact.



Haftungsausschluss

1. Inhalt des Onlineangebotes

Der Autor übernimmt keinerlei Gewähr für die Aktualität, Korrektheit, Vollständigkeit oder Qualität der bereitgestellten Informationen. Haftungsansprüche gegen den Autor, welche sich auf Schäden materieller oder ideeller Art beziehen, die durch die Nutzung oder Nichtnutzung der dargebotenen Informationen bzw. durch die Nutzung fehlerhafter und unvollständiger Informationen verursacht wurden, sind grundsätzlich ausgeschlossen, sofern seitens des Autors kein nachweislich vorsätzliches oder grob fahrlässiges Verschulden vorliegt.

Alle Angebote sind freibleibend und unverbindlich. Der Autor behält es sich ausdrücklich vor, Teile der Seiten oder das gesamte Angebot ohne gesonderte Ankündigung zu verändern, zu ergänzen, zu löschen oder die Veröffentlichung zeitweise oder endgültig einzustellen.

2. Verweise und Links

Bei direkten oder indirekten Verweisen auf fremde Webseiten ("Hyperlinks"), die außerhalb des Verantwortungsbereiches des Autors liegen, würde eine Haftungsverpflichtung ausschließlich in dem Fall in Kraft treten, in dem der Autor von den Inhalten Kenntnis hat und es ihm technisch möglich und zumutbar wäre, die Nutzung im Falle rechtswidriger Inhalte zu verhindern.

Der Autor erklärt hiermit ausdrücklich, dass zum Zeitpunkt der Linksetzung keine illegalen Inhalte auf den zu verlinkenden Seiten erkennbar waren. Auf die aktuelle und zukünftige Gestaltung, die Inhalte oder die Urheberschaft der verlinkten / verknüpften Seiten hat der Autor keinerlei Einfluss. Deshalb distanziert er sich hiermit ausdrücklich von allen Inhalten aller verlinkten / verknüpften Seiten, die nach der Linksetzung verändert wurden. Diese Feststellung gilt für alle innerhalb des eigenen Internetangebotes gesetzten Links und Verweise sowie für Fremdeinträge in vom Autor eingerichteten Gästebüchern, Diskussionsforen, Linkverzeichnissen, Mailinglisten und in allen anderen Formen von Datenbanken, auf deren Inhalt externe Schreibzugriffe möglich sind. Für illegale, fehlerhafte oder unvollständige Inhalte und insbesondere für Schäden, die aus der Nutzung oder Nichtnutzung solcherart dargebotener Informationen entstehen, haftet allein der Anbieter der Seite, auf welche verwiesen wurde, nicht derjenige, der über Links auf die jeweilige Veröffentlichung lediglich verweist.

3. Urheber- und Kennzeichenrecht

Der Autor ist bestrebt, in allen Publikationen die Urheberrechte der verwendeten Bilder, Grafiken, Tondokumente, Videosequenzen und Texte zu beachten, von ihm selbst erstellte Bilder, Grafiken, Tondokumente, Videosequenzen und Texte zu nutzen oder auf lizenzfreie Grafiken, Tondokumente, Videosequenzen und Texte zurückzugreifen.

Alle innerhalb des Internetangebotes genannten und ggf. durch Dritte geschützten Marken- und Warenzeichen unterliegen uneingeschränkt den Bestimmungen des jeweils gültigen Kennzeichenrechts und den Besitzrechten der jeweiligen eingetragenen Eigentümer. Allein aufgrund der bloßen Nennung ist nicht der Schluss zu ziehen, dass Markenzeichen nicht durch Rechte Dritter geschützt sind!

Das Copyright für veröffentlichte, vom Autor selbst erstellte Objekte bleibt allein beim Autor der Seiten. Eine Vervielfältigung oder Verwendung solcher Grafiken, Tondokumente, Videosequenzen und Texte in anderen elektronischen oder gedruckten Publikationen ist ohne ausdrückliche Zustimmung des Autors nicht gestattet.

4. Datenschutz & Cookies

Sofern innerhalb des Internetangebotes die Möglichkeit zur Eingabe persönlicher oder geschäftlicher Daten (Emailadressen, Namen, Anschriften) besteht, so erfolgt die Preisgabe dieser Daten seitens des Nutzers auf ausdrücklich freiwilliger Basis. Die Inanspruchnahme und Bezahlung aller angebotenen Dienste ist – soweit technisch möglich und zumutbar – auch ohne Angabe solcher Daten bzw. unter Angabe anonymisierter Daten oder eines Pseudonyms gestattet. Die Nutzung der im Rahmen des Impressums oder vergleichbarer Angaben veröffentlichten Kontaktdaten wie Postanschriften, Telefon- und Faxnummern sowie Emailadressen durch Dritte zur übersendung von nicht ausdrücklich angeforderten Informationen ist nicht gestattet. Rechtliche Schritte gegen die Versender von sogenannten Spam-Mails bei Verstössen gegen dieses Verbot sind ausdrücklich vorbehalten.

Wir greifen auf Drittanbieter (Google) zurück, um Anzeigen zu schalten, wenn Sie unsere Website besuchen. Diese Unternehmen nutzen möglicherweise Informationen (dies schließt nicht Ihren Namen, Ihre Adresse, E-Mail-Adresse oder Telefonnummer ein) zu Ihren Besuchen dieser und anderer Websites, damit Anzeigen zu Produkten und Diensten geschaltet werden können, die Sie interessieren. Falls Sie mehr über diese Methoden erfahren möchten oder wissen möchten, welche Möglichkeiten Sie haben, damit diese Informationen nicht von Google verwendet werden können, klicken Sie hier.

Wir verwenden Cookies, um Inhalte und Anzeigen zu personalisieren, Funktionen für soziale Medien anbieten zu können und die Zugriffe auf unsere Website zu analysieren. Außerdem geben wir Informationen zu Ihrer Nutzung unserer Website an unsere Partner für soziale Medien, Werbung und Analysen weiter.

Mit der Nutzung unserer Dienste erklären Sie sich damit einverstanden, dass wir Cookies verwenden.

Details:

5. Rechtswirksamkeit dieses Haftungsausschlusses

Dieser Haftungsausschluss ist als Teil des Internetangebotes zu betrachten, von dem aus auf diese Seite verwiesen wurde. Sofern Teile oder einzelne Formulierungen dieses Textes der geltenden Rechtslage nicht, nicht mehr oder nicht vollständig entsprechen sollten, bleiben die übrigen Teile des Dokumentes in ihrem Inhalt und ihrer Gültigkeit davon unberührt.

Docs/Chm/help/base/autotype.html0000664000000000000000000005735113225117272015574 0ustar rootroot Auto-Type - KeePass
Auto-Type Icon

Auto-Type


Powerful feature that sends simulated keypresses to other applications.

Text  Basic Auto-Type Information

KeePass features an "Auto-Type" functionality. This feature allows you to define a sequence of keypresses, which KeePass can automatically perform for you. The simulated keypresses can be sent to any other currently open window of your choice (browser windows, login dialogs, ...).

By default, the sent keystroke sequence is {USERNAME}{TAB}{PASSWORD}{ENTER}, i.e. it first types the user name of the selected entry, then presses the Tab key, then types the password of the entry and finally presses the Enter key.

For TAN entries, the default sequence is {PASSWORD}, i.e. it just types the TAN into the target window, without pressing Enter.

Auto-Type can be configured individually for each entry using the Auto-Type tab page on the entry dialog (select an entry → Edit Entry). On this page you can specify a default sequence and customize specific window/sequence associations.

Two-Channel Auto-Type Obfuscation is supported (making Auto-Type resistant against keyloggers).

Additionally, you can create customized window/sequence associations, which override the default sequence. You can specify different keystroke sequences for different windows for each entry. For example, imagine a webpage, to which you want to login, that has multiple pages where one can login. These pages could all look a bit different (on one you could additionally need to check some checkbox -- like often seen in forums). Here creating customized window/sequence associations solves the problems: you simply specify different auto-type sequences for each windows (identified by their window titles).

Invoking Auto-Type:
There are three different methods to invoke auto-type:

  • Invoke auto-type for an entry by using the context menu command Perform Auto-Type while the entry is selected.
  • Select the entry and press Ctrl+V (that's the menu shortcut for the context menu command above).
  • Using the system-wide auto-type hot key. KeePass will search all entries in the currently opened database for matching sequences.

All methods are explained in detail below.

Input Focus:
Note that auto-type starts typing into the control of the target window that has the input focus. Thus, for example for the default sequence you have to ensure that the input focus is set to the user name control of the target window before invoking auto-type using any of the above methods.

Rights:
For auto-type to work, KeePass must be running with the same or higher rights as the target application. Especially, if the target application is running with administrative rights, KeePass must be running with administrative rights, too.

Remote Desktops and Virtual Machines:
KeePass does not know the keyboard layout that has been selected in a remote desktop or virtual machine window. If you want to auto-type into such a window, you must ensure that the local and the remote/virtual system are using the same keyboard layout.


Text  Context Menu: 'Perform Auto-Type' Command

This method is the one that requires the least amount of configuration and is the simpler one, but it has the disadvantage that you need to select the entry in KeePass which you want to auto-type.

The method is simple: right-click on an entry of your currently opened database and click 'Perform Auto-Type' (or alternatively press the Ctrl+V shortcut for this command). The window that previously got the focus (i.e. the one in which you worked before switching to KeePass) will be brought to the foreground and KeePass auto-types into this window.

The sequence which is auto-typed depends on the window's title. If you didn't specify any custom window/sequence associations, the default sequence is sent. If you created associations, KeePass uses the sequence of the first matching association. If none of the associations match, the default sequence is used.


Text  Global Auto-Type Hot Key

This is the more powerful method, but it also requires a little bit more work/knowledge, before it can be used.

Simple Global Auto-Type Example:

  1. Create an entry in KeePass titled Notepad with values for user name and password.
  2. Start Notepad (under 'Programs' → 'Accessories').
  3. Press Ctrl+Alt+A within Notepad. The user name and password will be typed into Notepad.

The KeePass entry title Notepad is matched with the window title of Notepad and the default Auto-Type sequence is typed.

How It Works - Details:

KeePass registers a system-wide hot key for auto-type. The advantage of this hot key is that you don't need to switch to the KeePass window and select the entry. You simply press the hot key while having the target window open (i.e. the window which will receive the simulated keypresses).

By default, the global hot key is Ctrl+Alt+A (i.e. hold the Ctrl and Alt keys, press A and release all keys). You can change this hot key in the options dialog (main menu - 'Tools' - 'Options', tab 'Integration'): here, click into the textbox below "Global Auto-Type Hot Key Combination" and press the hot key that you wish to use. If the hot key is usable, it will appear in the textbox.

When you press the hot key, KeePass looks at the title of the currently opened window and searches the currently opened database for usable entries. If KeePass finds multiple entries that can be used, it displays a selection dialog. An entry is considered to be usable for the current window title when at least one of the following conditions is fulfilled:

  • The title of the entry is a substring of the currently active window title.
  • The entry has a window/sequence association, of which the window specifier matches the currently active window title.

The second condition has been mentioned already, but the first one is new. By using entry titles as filters for window titles, the configuration amount for auto-type is almost zero: you only need to make sure that the entry title is contained in the window title of the window into which you want the entry to be auto-typed. Of course, this is not always possible (for example, if a webpage has a very generic title like "Welcome"), here you need to use custom window/sequence associations.

Custom window/sequence associations can be specified on the 'Auto-Type' tab page of each entry.

The associations complement the KeePass entry title. Any associations specified will be used in addition to the KeePass entry title to determine a match.

Auto-Type window definitions, entry titles and URLs are Spr-compiled, i.e. placeholders, environment variables, field references, etc. can be used.


Text  Auto-Type Keystroke Sequences

An auto-type keystroke sequence is a one-line string that can contain placeholders and special key codes.

A complete list of all supported placeholders can be found on the page Placeholders. The special key codes can be found below.

Above you've seen already that the default auto-type is {USERNAME}{TAB}{PASSWORD}{ENTER}. Here, {USERNAME} and {PASSWORD} are placeholders: when auto-type is performed, these are replaced by the appropriate field values of the entry. {TAB} and {ENTER} are special key codes: these are replaced by the appropriate keypresses. Special key codes are the only way to specify special keys like Arrow-Down, Shift, Escape, etc.

Of course, keystroke sequences can also contain simple characters to be sent. For example, the following string is perfectly valid as keystroke sequence string:
{USERNAME}{TAB}Some text to be sent!{ENTER}.

Special key codes are case-insensitive.

Special Keys:
The following codes for special keys are supported:

Special KeyCode
Tab{TAB}
Enter{ENTER} or ~
Arrow Up{UP}
Arrow Down{DOWN}
Arrow Left{LEFT}
Arrow Right{RIGHT}
Insert{INSERT} or {INS}
Delete{DELETE} or {DEL}
Home{HOME}
End{END}
Page Up{PGUP}
Page Down{PGDN}
Space{SPACE}
Backspace{BACKSPACE}, {BS} or {BKSP}
Break{BREAK}
Caps-Lock{CAPSLOCK}
Escape{ESC}
Windows Key{WIN} (equ. to {LWIN})
Windows Key: left, right{LWIN}, {RWIN}
Apps / Menu{APPS}
Help{HELP}
Numlock{NUMLOCK}
Print Screen{PRTSC}
Scroll Lock{SCROLLLOCK}
F1 - F16{F1} - {F16}
Numeric Keypad +{ADD}
Numeric Keypad -{SUBTRACT}
Numeric Keypad *{MULTIPLY}
Numeric Keypad /{DIVIDE}
Numeric Keypad 0 to 9{NUMPAD0} to {NUMPAD9}
Shift+
Ctrl^
Alt%

Special KeyCode
+{+}
%{%}
^{^}
~{~}
(, ){(}, {)}
[, ]{[}, {]}
{, }{{}, {}}

Additionally, some special commands are supported:

Command SyntaxAction
{DELAY X}Delays X milliseconds.
{DELAY=X}Sets the default delay to X milliseconds for all following keypresses.
{CLEARFIELD}Clears the contents of the edit control that currently has the focus (only single-line edit controls).
{VKEY X}Sends the virtual key of value X.
{APPACTIVATE WindowTitle}Activates the window "WindowTitle".
{BEEP X Y}Beeps with a frequency of X hertz and a duration of Y milliseconds.

Command SyntaxAction
{VKEY-NX X}Sends the non-extended virtual key of value X. If possible, use {VKEY X} instead.
{VKEY-EX X}Sends the extended virtual key of value X. If possible, use {VKEY X} instead.

Keys and special keys (not placeholders or commands) can be repeated by appending a number within the code. For example, {TAB 5} presses the Tab key 5 times.

For details on how to send special keys for which no explicit special key codes exist, please see: How can auto-type send other special keys?.

Finally, some examples:

{TITLE}{TAB}{USERNAME}{TAB}{PASSWORD}{ENTER}
Types the entry's title, a Tab, the user name, a Tab, the password of the currently selected entry, and presses Enter.

{TAB}{PASSWORD}{ENTER}
Presses the Tab key, enters the entry's password and presses Enter.

{USERNAME}{TAB}^v{ENTER}
Types the user name, presses Tab, presses Ctrl+V (which pastes data from the Windows clipboard in most applications), and presses Enter.

Toggling Checkboxes:
Sometimes you find checkboxes on websites ("Stay logged in on this computer" for example). You can toggle these checkboxes by sending a space character (' ') when auto-typing. For example:
{USERNAME}{TAB}{PASSWORD}{TAB} {TAB}{ENTER}
If there is a webform with a user name field, password field and a checkbox, this sequence would enter the user name, the password and toggle the checkbox that follows the password control.

Pressing Non-Default Buttons:
Pressing non-default buttons works the same as toggling checkboxes: send a space character (' '). Note that this should only be used for non-default buttons; for default buttons, {ENTER} should be sent instead.

Higher ANSI Characters:
The auto-type function supports sending of higher ANSI characters in range 126-255. This means that you can send special characters like ©, @, etc. without any problems; you can write them directly into the keystroke sequence definition.


Text  Target Window Filters

When creating a custom window/sequence association, you need to tell KeePass how the matching window titles look like. Here, KeePass supports simple wildcards:

String with WildcardMeaning
STRINGMatches all window titles that are named exactly "STRING".
STRING*Matches all window titles that start with "STRING".
*STRINGMatches all window titles that end with "STRING".
*STRING*Matches all window titles that have "STRING" somewhere in the window title. This includes the string being directly at the start or at the end of the window title.

Wildcards may also appear in the middle of patterns. For example, *Windows*Explorer* would match Windows Internet Explorer.

Additionally, matching using regular expressions is supported. In order to tell KeePass that the pattern is a regular expression, enclose it in //. For example, //B.?g Window// would match Big Window, Bug Window and Bg Window.

By using wildcards, you can make your auto-type associations browser-independent. See the usage examples for more information.


Text  Change Default Auto-Type Sequence

The default auto-type sequence (i.e. the one which is used when you don't specify a custom one) is {USERNAME}{TAB}{PASSWORD}{ENTER}. KeePass allows you to change this default sequence. Normally you won't need to change it (use custom window/sequence definitions instead!), but it is quite useful when some other application is interfering with KeePass (for example a security software that always asks you for permission before allowing KeePass to auto-type).

By default, entries inherit the auto-type sequence of their containing group. Groups also inherit the auto-type sequence of their parent groups. There is only one top group (the first group contains all other groups). Consequently, if you change the auto-type sequence of this very first group, all other groups and their entries will use this sequence. Practically, this is a global override. To change it, right-click on the first group, choose 'Edit Group' and switch to the 'Auto-Type' tab.


Text  Usage Example

Now let's have a look at a real-world example: logging into a website. In this example, will we use the global auto-type hot key to fill out the login webpage. First open the test page, and afterwards create a new entry in KeePass with title Test Form and a user name and password of your choice.

Let's assume the global auto-type hot key is set to Ctrl+Alt+A (the default). KeePass is running in the background, you have opened your database and the workspace is unlocked.

When you now navigate to the test page and are being prompted for your user name and password, just click into the user name field and press Ctrl+Alt+A. KeePass enters the user name and password for you!

Why did this work? The window title of your browser window was "Test Form - KeePass - Internet Explorer" or "Test Form - KeePass - Mozilla Firefox", depending on the browser you are using. Because we gave the entry in KeePass the title Test Form, the entry title is contained in the window title, therefore KeePass uses this entry.

Here you see the huge advantages of auto-type: it not only doesn't require any additional browser software (the browser knows nothing of KeePass -- there are no helper browser plugins required), it is also browser-independent: the one entry that you created within KeePass works for Internet Explorer and Mozilla Firefox (and other browsers) without requiring any modifications or definitions.

When you would use window/sequence associations (instead of entry title matching), you can achieve the same browser-independent effect using wildcards: you could for example have used Test Form - KeePass - * as window filter. This filter matches both the Internet Explorer and the Firefox window.

Docs/Chm/help/base/license_lgpl.html0000664000000000000000000006724713225117272016367 0ustar rootroot LGPL License - KeePass
Help

LGPL License


GNU Lesser General Public License

		  GNU LESSER GENERAL PUBLIC LICENSE
		       Version 2.1, February 1999

 Copyright (C) 1991, 1999 Free Software Foundation, Inc.
     59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 Everyone is permitted to copy and distribute verbatim copies
 of this license document, but changing it is not allowed.

[This is the first released version of the Lesser GPL.  It also counts
 as the successor of the GNU Library Public License, version 2, hence
 the version number 2.1.]

			    Preamble

  The licenses for most software are designed to take away your
freedom to share and change it.  By contrast, the GNU General Public
Licenses are intended to guarantee your freedom to share and change
free software--to make sure the software is free for all its users.

  This license, the Lesser General Public License, applies to some
specially designated software packages--typically libraries--of the
Free Software Foundation and other authors who decide to use it.  You
can use it too, but we suggest you first think carefully about whether
this license or the ordinary General Public License is the better
strategy to use in any particular case, based on the explanations below.

  When we speak of free software, we are referring to freedom of use,
not price.  Our General Public Licenses are designed to make sure that
you have the freedom to distribute copies of free software (and charge
for this service if you wish); that you receive source code or can get
it if you want it; that you can change the software and use pieces of
it in new free programs; and that you are informed that you can do
these things.

  To protect your rights, we need to make restrictions that forbid
distributors to deny you these rights or to ask you to surrender these
rights.  These restrictions translate to certain responsibilities for
you if you distribute copies of the library or if you modify it.

  For example, if you distribute copies of the library, whether gratis
or for a fee, you must give the recipients all the rights that we gave
you.  You must make sure that they, too, receive or can get the source
code.  If you link other code with the library, you must provide
complete object files to the recipients, so that they can relink them
with the library after making changes to the library and recompiling
it.  And you must show them these terms so they know their rights.

  We protect your rights with a two-step method: (1) we copyright the
library, and (2) we offer you this license, which gives you legal
permission to copy, distribute and/or modify the library.

  To protect each distributor, we want to make it very clear that
there is no warranty for the free library.  Also, if the library is
modified by someone else and passed on, the recipients should know
that what they have is not the original version, so that the original
author's reputation will not be affected by problems that might be
introduced by others.

  Finally, software patents pose a constant threat to the existence of
any free program.  We wish to make sure that a company cannot
effectively restrict the users of a free program by obtaining a
restrictive license from a patent holder.  Therefore, we insist that
any patent license obtained for a version of the library must be
consistent with the full freedom of use specified in this license.

  Most GNU software, including some libraries, is covered by the
ordinary GNU General Public License.  This license, the GNU Lesser
General Public License, applies to certain designated libraries, and
is quite different from the ordinary General Public License.  We use
this license for certain libraries in order to permit linking those
libraries into non-free programs.

  When a program is linked with a library, whether statically or using
a shared library, the combination of the two is legally speaking a
combined work, a derivative of the original library.  The ordinary
General Public License therefore permits such linking only if the
entire combination fits its criteria of freedom.  The Lesser General
Public License permits more lax criteria for linking other code with
the library.

  We call this license the "Lesser" General Public License because it
does Less to protect the user's freedom than the ordinary General
Public License.  It also provides other free software developers Less
of an advantage over competing non-free programs.  These disadvantages
are the reason we use the ordinary General Public License for many
libraries.  However, the Lesser license provides advantages in certain
special circumstances.

  For example, on rare occasions, there may be a special need to
encourage the widest possible use of a certain library, so that it becomes
a de-facto standard.  To achieve this, non-free programs must be
allowed to use the library.  A more frequent case is that a free
library does the same job as widely used non-free libraries.  In this
case, there is little to gain by limiting the free library to free
software only, so we use the Lesser General Public License.

  In other cases, permission to use a particular library in non-free
programs enables a greater number of people to use a large body of
free software.  For example, permission to use the GNU C Library in
non-free programs enables many more people to use the whole GNU
operating system, as well as its variant, the GNU/Linux operating
system.

  Although the Lesser General Public License is Less protective of the
users' freedom, it does ensure that the user of a program that is
linked with the Library has the freedom and the wherewithal to run
that program using a modified version of the Library.

  The precise terms and conditions for copying, distribution and
modification follow.  Pay close attention to the difference between a
"work based on the library" and a "work that uses the library".  The
former contains code derived from the library, whereas the latter must
be combined with the library in order to run.

		  GNU LESSER GENERAL PUBLIC LICENSE
   TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION

  0. This License Agreement applies to any software library or other
program which contains a notice placed by the copyright holder or
other authorized party saying it may be distributed under the terms of
this Lesser General Public License (also called "this License").
Each licensee is addressed as "you".

  A "library" means a collection of software functions and/or data
prepared so as to be conveniently linked with application programs
(which use some of those functions and data) to form executables.

  The "Library", below, refers to any such software library or work
which has been distributed under these terms.  A "work based on the
Library" means either the Library or any derivative work under
copyright law: that is to say, a work containing the Library or a
portion of it, either verbatim or with modifications and/or translated
straightforwardly into another language.  (Hereinafter, translation is
included without limitation in the term "modification".)

  "Source code" for a work means the preferred form of the work for
making modifications to it.  For a library, complete source code means
all the source code for all modules it contains, plus any associated
interface definition files, plus the scripts used to control compilation
and installation of the library.

  Activities other than copying, distribution and modification are not
covered by this License; they are outside its scope.  The act of
running a program using the Library is not restricted, and output from
such a program is covered only if its contents constitute a work based
on the Library (independent of the use of the Library in a tool for
writing it).  Whether that is true depends on what the Library does
and what the program that uses the Library does.

  1. You may copy and distribute verbatim copies of the Library's
complete source code as you receive it, in any medium, provided that
you conspicuously and appropriately publish on each copy an
appropriate copyright notice and disclaimer of warranty; keep intact
all the notices that refer to this License and to the absence of any
warranty; and distribute a copy of this License along with the
Library.

  You may charge a fee for the physical act of transferring a copy,
and you may at your option offer warranty protection in exchange for a
fee.

  2. You may modify your copy or copies of the Library or any portion
of it, thus forming a work based on the Library, and copy and
distribute such modifications or work under the terms of Section 1
above, provided that you also meet all of these conditions:

    a) The modified work must itself be a software library.

    b) You must cause the files modified to carry prominent notices
    stating that you changed the files and the date of any change.

    c) You must cause the whole of the work to be licensed at no
    charge to all third parties under the terms of this License.

    d) If a facility in the modified Library refers to a function or a
    table of data to be supplied by an application program that uses
    the facility, other than as an argument passed when the facility
    is invoked, then you must make a good faith effort to ensure that,
    in the event an application does not supply such function or
    table, the facility still operates, and performs whatever part of
    its purpose remains meaningful.

    (For example, a function in a library to compute square roots has
    a purpose that is entirely well-defined independent of the
    application.  Therefore, Subsection 2d requires that any
    application-supplied function or table used by this function must
    be optional: if the application does not supply it, the square
    root function must still compute square roots.)

These requirements apply to the modified work as a whole.  If
identifiable sections of that work are not derived from the Library,
and can be reasonably considered independent and separate works in
themselves, then this License, and its terms, do not apply to those
sections when you distribute them as separate works.  But when you
distribute the same sections as part of a whole which is a work based
on the Library, the distribution of the whole must be on the terms of
this License, whose permissions for other licensees extend to the
entire whole, and thus to each and every part regardless of who wrote
it.

Thus, it is not the intent of this section to claim rights or contest
your rights to work written entirely by you; rather, the intent is to
exercise the right to control the distribution of derivative or
collective works based on the Library.

In addition, mere aggregation of another work not based on the Library
with the Library (or with a work based on the Library) on a volume of
a storage or distribution medium does not bring the other work under
the scope of this License.

  3. You may opt to apply the terms of the ordinary GNU General Public
License instead of this License to a given copy of the Library.  To do
this, you must alter all the notices that refer to this License, so
that they refer to the ordinary GNU General Public License, version 2,
instead of to this License.  (If a newer version than version 2 of the
ordinary GNU General Public License has appeared, then you can specify
that version instead if you wish.)  Do not make any other change in
these notices.

  Once this change is made in a given copy, it is irreversible for
that copy, so the ordinary GNU General Public License applies to all
subsequent copies and derivative works made from that copy.

  This option is useful when you wish to copy part of the code of
the Library into a program that is not a library.

  4. You may copy and distribute the Library (or a portion or
derivative of it, under Section 2) in object code or executable form
under the terms of Sections 1 and 2 above provided that you accompany
it with the complete corresponding machine-readable source code, which
must be distributed under the terms of Sections 1 and 2 above on a
medium customarily used for software interchange.

  If distribution of object code is made by offering access to copy
from a designated place, then offering equivalent access to copy the
source code from the same place satisfies the requirement to
distribute the source code, even though third parties are not
compelled to copy the source along with the object code.

  5. A program that contains no derivative of any portion of the
Library, but is designed to work with the Library by being compiled or
linked with it, is called a "work that uses the Library".  Such a
work, in isolation, is not a derivative work of the Library, and
therefore falls outside the scope of this License.

  However, linking a "work that uses the Library" with the Library
creates an executable that is a derivative of the Library (because it
contains portions of the Library), rather than a "work that uses the
library".  The executable is therefore covered by this License.
Section 6 states terms for distribution of such executables.

  When a "work that uses the Library" uses material from a header file
that is part of the Library, the object code for the work may be a
derivative work of the Library even though the source code is not.
Whether this is true is especially significant if the work can be
linked without the Library, or if the work is itself a library.  The
threshold for this to be true is not precisely defined by law.

  If such an object file uses only numerical parameters, data
structure layouts and accessors, and small macros and small inline
functions (ten lines or less in length), then the use of the object
file is unrestricted, regardless of whether it is legally a derivative
work.  (Executables containing this object code plus portions of the
Library will still fall under Section 6.)

  Otherwise, if the work is a derivative of the Library, you may
distribute the object code for the work under the terms of Section 6.
Any executables containing that work also fall under Section 6,
whether or not they are linked directly with the Library itself.

  6. As an exception to the Sections above, you may also combine or
link a "work that uses the Library" with the Library to produce a
work containing portions of the Library, and distribute that work
under terms of your choice, provided that the terms permit
modification of the work for the customer's own use and reverse
engineering for debugging such modifications.

  You must give prominent notice with each copy of the work that the
Library is used in it and that the Library and its use are covered by
this License.  You must supply a copy of this License.  If the work
during execution displays copyright notices, you must include the
copyright notice for the Library among them, as well as a reference
directing the user to the copy of this License.  Also, you must do one
of these things:

    a) Accompany the work with the complete corresponding
    machine-readable source code for the Library including whatever
    changes were used in the work (which must be distributed under
    Sections 1 and 2 above); and, if the work is an executable linked
    with the Library, with the complete machine-readable "work that
    uses the Library", as object code and/or source code, so that the
    user can modify the Library and then relink to produce a modified
    executable containing the modified Library.  (It is understood
    that the user who changes the contents of definitions files in the
    Library will not necessarily be able to recompile the application
    to use the modified definitions.)

    b) Use a suitable shared library mechanism for linking with the
    Library.  A suitable mechanism is one that (1) uses at run time a
    copy of the library already present on the user's computer system,
    rather than copying library functions into the executable, and (2)
    will operate properly with a modified version of the library, if
    the user installs one, as long as the modified version is
    interface-compatible with the version that the work was made with.

    c) Accompany the work with a written offer, valid for at
    least three years, to give the same user the materials
    specified in Subsection 6a, above, for a charge no more
    than the cost of performing this distribution.

    d) If distribution of the work is made by offering access to copy
    from a designated place, offer equivalent access to copy the above
    specified materials from the same place.

    e) Verify that the user has already received a copy of these
    materials or that you have already sent this user a copy.

  For an executable, the required form of the "work that uses the
Library" must include any data and utility programs needed for
reproducing the executable from it.  However, as a special exception,
the materials to be distributed need not include anything that is
normally distributed (in either source or binary form) with the major
components (compiler, kernel, and so on) of the operating system on
which the executable runs, unless that component itself accompanies
the executable.

  It may happen that this requirement contradicts the license
restrictions of other proprietary libraries that do not normally
accompany the operating system.  Such a contradiction means you cannot
use both them and the Library together in an executable that you
distribute.

  7. You may place library facilities that are a work based on the
Library side-by-side in a single library together with other library
facilities not covered by this License, and distribute such a combined
library, provided that the separate distribution of the work based on
the Library and of the other library facilities is otherwise
permitted, and provided that you do these two things:

    a) Accompany the combined library with a copy of the same work
    based on the Library, uncombined with any other library
    facilities.  This must be distributed under the terms of the
    Sections above.

    b) Give prominent notice with the combined library of the fact
    that part of it is a work based on the Library, and explaining
    where to find the accompanying uncombined form of the same work.

  8. You may not copy, modify, sublicense, link with, or distribute
the Library except as expressly provided under this License.  Any
attempt otherwise to copy, modify, sublicense, link with, or
distribute the Library is void, and will automatically terminate your
rights under this License.  However, parties who have received copies,
or rights, from you under this License will not have their licenses
terminated so long as such parties remain in full compliance.

  9. You are not required to accept this License, since you have not
signed it.  However, nothing else grants you permission to modify or
distribute the Library or its derivative works.  These actions are
prohibited by law if you do not accept this License.  Therefore, by
modifying or distributing the Library (or any work based on the
Library), you indicate your acceptance of this License to do so, and
all its terms and conditions for copying, distributing or modifying
the Library or works based on it.

  10. Each time you redistribute the Library (or any work based on the
Library), the recipient automatically receives a license from the
original licensor to copy, distribute, link with or modify the Library
subject to these terms and conditions.  You may not impose any further
restrictions on the recipients' exercise of the rights granted herein.
You are not responsible for enforcing compliance by third parties with
this License.

  11. If, as a consequence of a court judgment or allegation of patent
infringement or for any other reason (not limited to patent issues),
conditions are imposed on you (whether by court order, agreement or
otherwise) that contradict the conditions of this License, they do not
excuse you from the conditions of this License.  If you cannot
distribute so as to satisfy simultaneously your obligations under this
License and any other pertinent obligations, then as a consequence you
may not distribute the Library at all.  For example, if a patent
license would not permit royalty-free redistribution of the Library by
all those who receive copies directly or indirectly through you, then
the only way you could satisfy both it and this License would be to
refrain entirely from distribution of the Library.

If any portion of this section is held invalid or unenforceable under any
particular circumstance, the balance of the section is intended to apply,
and the section as a whole is intended to apply in other circumstances.

It is not the purpose of this section to induce you to infringe any
patents or other property right claims or to contest validity of any
such claims; this section has the sole purpose of protecting the
integrity of the free software distribution system which is
implemented by public license practices.  Many people have made
generous contributions to the wide range of software distributed
through that system in reliance on consistent application of that
system; it is up to the author/donor to decide if he or she is willing
to distribute software through any other system and a licensee cannot
impose that choice.

This section is intended to make thoroughly clear what is believed to
be a consequence of the rest of this License.

  12. If the distribution and/or use of the Library is restricted in
certain countries either by patents or by copyrighted interfaces, the
original copyright holder who places the Library under this License may add
an explicit geographical distribution limitation excluding those countries,
so that distribution is permitted only in or among countries not thus
excluded.  In such case, this License incorporates the limitation as if
written in the body of this License.

  13. The Free Software Foundation may publish revised and/or new
versions of the Lesser General Public License from time to time.
Such new versions will be similar in spirit to the present version,
but may differ in detail to address new problems or concerns.

Each version is given a distinguishing version number.  If the Library
specifies a version number of this License which applies to it and
"any later version", you have the option of following the terms and
conditions either of that version or of any later version published by
the Free Software Foundation.  If the Library does not specify a
license version number, you may choose any version ever published by
the Free Software Foundation.

  14. If you wish to incorporate parts of the Library into other free
programs whose distribution conditions are incompatible with these,
write to the author to ask for permission.  For software which is
copyrighted by the Free Software Foundation, write to the Free
Software Foundation; we sometimes make exceptions for this.  Our
decision will be guided by the two goals of preserving the free status
of all derivatives of our free software and of promoting the sharing
and reuse of software generally.

			    NO WARRANTY

  15. BECAUSE THE LIBRARY IS LICENSED FREE OF CHARGE, THERE IS NO
WARRANTY FOR THE LIBRARY, TO THE EXTENT PERMITTED BY APPLICABLE LAW.
EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR
OTHER PARTIES PROVIDE THE LIBRARY "AS IS" WITHOUT WARRANTY OF ANY
KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
PURPOSE.  THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE
LIBRARY IS WITH YOU.  SHOULD THE LIBRARY PROVE DEFECTIVE, YOU ASSUME
THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION.

  16. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN
WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY
AND/OR REDISTRIBUTE THE LIBRARY AS PERMITTED ABOVE, BE LIABLE TO YOU
FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR
CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE
LIBRARY (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING
RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A
FAILURE OF THE LIBRARY TO OPERATE WITH ANY OTHER SOFTWARE), EVEN IF
SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
DAMAGES.

		     END OF TERMS AND CONDITIONS

           How to Apply These Terms to Your New Libraries

  If you develop a new library, and you want it to be of the greatest
possible use to the public, we recommend making it free software that
everyone can redistribute and change.  You can do so by permitting
redistribution under these terms (or, alternatively, under the terms of the
ordinary General Public License).

  To apply these terms, attach the following notices to the library.  It is
safest to attach them to the start of each source file to most effectively
convey the exclusion of warranty; and each file should have at least the
"copyright" line and a pointer to where the full notice is found.

    <one line to give the library's name and a brief idea of what it does.>
    Copyright (C) <year>  <name of author>

    This library is free software; you can redistribute it and/or
    modify it under the terms of the GNU Lesser General Public
    License as published by the Free Software Foundation; either
    version 2.1 of the License, or (at your option) any later version.

    This library is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
    Lesser General Public License for more details.

    You should have received a copy of the GNU Lesser General Public
    License along with this library; if not, write to the Free Software
    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA

Also add information on how to contact you by electronic and paper mail.

You should also get your employer (if you work as a programmer) or your
school, if any, to sign a "copyright disclaimer" for the library, if
necessary.  Here is a sample; alter the names:

  Yoyodyne, Inc., hereby disclaims all copyright interest in the
  library `Frob' (a library for tweaking knobs) written by James Random Hacker.

  <signature of Ty Coon>, 1 April 1990
  Ty Coon, President of Vice

That's all there is to it!
Docs/Chm/help/base/importexport.html0000664000000000000000000004432213225117272016470 0ustar rootroot File Formats - KeePass
Help

Import / Export


KeePass supports importing/exporting data from/to various file formats.

KeePass 1.x supports importing data from CSV files (special form), CodeWallet, Password Safe, and Personal Vault.

KeePass 2.x supports importing data from CSV files (all), KeePass 1.x (KDB, XML and CSV), KeePass 2.x XML, 1Password Pro, 1PW, Alle meine Passworte, Any Password, CodeWallet, Dashlane, DataVault, DesktopKnox, Enpass, FlexWallet, Handy Safe, Handy Safe Pro, Kaspersky Password Manager, KeePassX, LastPass, Mozilla Bookmarks, mSecure, Network Password Manager, Norton Identity Safe, nPassword, PassKeeper, Passphrase Keeper, Password Agent, Password Depot, Password Exporter, Password Keeper, Password Memory, Password Prompter, Password Safe, Password Saver, Passwords Plus, Passwort.Tresor, Personal Vault, PINs, Revelation, RoboForm, SafeWallet, Security TXT, SplashID, Steganos Password Manager 2007, Sticky Password, TurboPasswords, VisKeeper, Whisper 32, ZDNet's Password Pro, and Spamex.com.

For both KeePass 1.x and 2.x, there are importer plugins available, which add more import capabilities/formats.


Unfortunately there isn't any standard password database format. Every password manager uses its own file format. Anyway, almost all support exporting to CSV or XML files. This sounds good at first glance, but CSV and XML files aren't specialized password database formats, they only specify a low-level layout of the stored data (for CSV: data fields are separated by commas; for XML: hierarchical form using tags). These formats do not specify the high-level arrangement of the data (for CSV: order/meaning of the fields; for XML: tag names and structure). Because of this, many users are confused when application #1 exports data to CSV/XML and application #2 can't read the CSV/XML file, although it claims that it can read those files.

This help page details the expected CSV and XML file formats. Knowing the formats which KeePass expects, you can reformat CSV and XML files exported by other password managers to match the KeePass formats. CSV files can be reformatted using e.g. LibreOffice Calc (see below). XML files can be reformatted using an XML editor.

KeePass can import many password database formats directly (see top of this page). Additionally, there are specialized KeePass Plugins available for importing more formats (like AnyPassword CSV, Oubliette files, PINs TXT, ZSafe files, and many more...). Using these plugins, you don't need to manually reformat the output of other password managers; you can directly import the exported files.

If no import plugin exists for importing data from your previous password manager, feel free to post a request for it in the KeePass Feature Requests Tracker and/or in the Open Discussion forum.


Text  File Format: CSV (KeePass 1.x)

KeePass imports and exports data from/to CSV files in the following format:

"Account","Login Name","Password","Web Site","Comments"

For a detailed example, download this file: ZIP Package FileSample_CSV.zip. This file is zipped only in order to ensure correct encoding (if not zipped, browsers or download managers could automatically convert the file to a different encoding). When importing a CSV file, it must not be zipped!

Important notes about the format:

  • The file must be encoded using UTF-8 (Unicode). Other encodings are not supported.
  • CSV files only support the following fields: title, user name, password, URL and notes. Other fields like last entry modification time, expiration time, icon, entry file attachments, etc. are not supported. If you want to transfer such information, you have to use a different format (like XML).
  • All fields must be enclosed in quotes ("). These quotes are mandatory, unquoted fields are not allowed.
  • Quotes (") in strings are encoded as \" (two characters). Backslashes (\) are encoded as \\.
  • Multiline comments are realized through normal line breaks. Encoding line breaks by \n is not supported.

Microsoft Excel by default does not enclose fields in quotes ("). It is recommended that you use LibreOffice Calc to create a correct CSV file (see below), or use the Generic CSV Importer of KeePass 2.x (import your CSV file into KeePass 2.x, then export the data to a KeePass 1.x KDB file), or fix the CSV file by manually adding the quotes using a text editor.

If you want to transfer data between KeePass 1.x databases, you must not change the default export options of KeePass. Do not export additional fields or uncheck any options, otherwise KeePass will not be able to re-import the CSV file, because it does not comply to the specification above any more.

Using LibreOffice Calc to create a CSV file:
LibreOffice Calc can be used to create CSV files that can be imported correctly into KeePass. Follow these steps:

  • Make sure you got 5 columns as described above.
  • Select everything, right-click and select 'Format Cells'. In the dialog, choose Text as category. Click [OK].
  • Go 'File' → 'Save As...', choose a location and the 'Text CSV' file type, and make sure that the check box 'Edit Filter Settings' is enabled. Click the 'Save' button.
  • Choose 'Unicode (UTF-8)' as character set. The field separator must be set to a comma. The text separator must be ". Make sure that the 'Quote all text cells' option is checked, and that the 'Fixed column width' option is not checked. Click [OK].

Text  File Format: XML (KeePass 1.x)

This section describes the KeePass 1.x XML format. Note that this format is different from the XML format used by KeePass 2.x (anyway, KeePass 2.x can import KeePass 1.x XML files).

You can download a detailed XML sample file here: ZIP Package FileSample_XML.zip. This file is zipped only in order to ensure correct encoding (if not zipped, browsers or download managers could automatically convert the file to a different encoding). When importing a XML file, it of course must not be zipped!

Important notes about the format:

  • The files must be encoded using UTF-8 (Unicode). Other encodings are not supported.
  • The following five entities must be encoded: < > & " '. They are encoded by &lt; &gt; &amp; &quot; &apos;.
  • The UUID is a hex-encoded 16-byte string (i.e. an 32 ANSI hex character string in the XML file). It is unique (also across multiple databases) and can be used to identify entries.
  • Dates/times are encoded in the standard date/time XML format (YYYY-MM-DDTHH:mm:ss): first the date in form YYYY-MM-DD, a 'T' character, and the time in form HH:mm:ss.

Text  Generic CSV Importer

KeePass 2.x features a generic CSV importer. This tool can import almost all CSV formats. The CSV files are loaded and you can manually specify the encoding / character set, assign columns to data fields, and specify how the low-level structure looks like (usage of quotes, etc.).

To start the generic CSV file importer, click 'File' → 'Import' and choose 'Generic CSV Importer'.

Generic CSV Importer

Details about the generic CSV importer (with descriptions of the options, examples, etc.) can be found on the Generic CSV Importer help page.


Text  How to Import CodeWallet TXT

CodeWallet is a password manager that supports different card types (fields). KeePass cannot know which of the CodeWallet fields correspond to the KeePass standard fields (title, user name, ...), because they don't have fixed names (language-dependent, user-customizable, ...). Therefore all fields from the CodeWallet file are imported into custom string fields of KeePass entries. After importing the file, you can move some of the strings to the correct standard fields (by clicking the 'Move' button on the second tab page of the entries dialog.


Text  How to Import PINs TXT

In order to successfully import a PINs TXT file, you need to do the following:

  • Switch PINs language to 'English'.
  • In PINs export dialog: Enable all fields.
  • In PINs export dialog: Set separator to 'tab'.
  • In PINs export dialog: Enable 'Quote texts'.

After exporting a TXT file using the settings above, import it using 'File → Import' in KeePass 2.x.


Text  How to Import Data from RoboForm

  1. Export your logins to a HTML file. To do this, open RoboForm's Passcard Editor ('Edit Passcards' or 'RoboForm Editor' in the Windows start menu) and in the editor's main menu go 'Passcard''Print List' (in newer versions you have to click the 'RoboForm' button and go 'Print List''Logins'). In the dialog that opens, click the 'Save' button. Choose a location and file name, and click 'Save'.
  2. Open your KeePass 2.x database file and go 'File''Import'. Choose 'RoboForm HTML' as format and select the HTML file you just exported, then click 'OK'.

Text  How to Import Data from Steganos Password Manager 2007

Warning! It is possible that the transfer fails and that KeePass accidently overwrites your existing passwords in Steganos Password Manager. Therefore backup your SEF file before starting the import! In any case you should restore your passwords by restoring the backup you just created after the import process! Even if you think KeePass hasn't changed anything, restore from the backup!

Unfortunately Steganos Password Manager (SPM) lacks any form of export functionality. As the SEF file format (in which the data is stored) is proprietary and no specification is available, KeePass needs to try to get all the data out of the windows of SPM.

The import process works as follows. First you start SPM and open your password database. The main password management window should be open (i.e. the one which lists your items in the middle of the screen, and got toolbar-like buttons at the top). Make sure that all your items are displayed in the list (select the correct filter in the combobox above the item list).

Now switch to KeePass 2.x and open your KeePass database. Go File → Import and choose Steganos Password Manager 2007. Click [OK]. Now read the rest before continuing.

After pressing the [Yes] button in the KeePass import confirmation dialog, you got 10 seconds to switch to the SPM window. Select the very first entry within the SPM window (but do not open it, just select it). This is important! The first entry must have the keyboard focus and must be selected.

When the 10 seconds are over, KeePass will start importing. You will see how KeePass opens the SPM items, copies the data, closes the item's window, select the next item, etc. Everything goes automatic now and you can just sit back and watch. Sometimes Windows playes a ding sound, this is normal.

Note that it can take quite some time to import your items. Do not do anything while KeePass is importing! One single mouse click or keypress can ruin the complete import process.

The last item will be scanned twice. When completed, KeePass will show a message "The import process has finished!".

It is possible that KeePass failed to import some items (mainly caused by SPM's unpredictable slow response times). It is highly recommended that you compare each of the entries.


Text  How to Import Data from PassKeeper 1.2

The import process works visually, exactly like the import method for Steganos Password Manager data. Please read all instructions in How to Import Data from Steganos Password Manager.


Text  How to Import 1PW and 1Password Pro CSV

KeePass can import CSV files exported by 1PW and 1Password Pro. When exporting the data, make sure:

  • Choose the tabulator (Tab) as field separator.
  • The option for enclosing fields in quotes must be enabled.
  • All fields must be exported, in the original order.
Docs/Chm/help/base/credits.html0000664000000000000000000006210313225117272015346 0ustar rootroot Acknowledgements - KeePass
Help

Acknowledgements / Credits


Thanks to various people for contributions and/or work.

At this place I want to thank a lot of people very much for their help, source code, suggestions and other contributions (in no particular order).


Info  Donation Acknowledgements

Developing high-quality applications takes much time and resources. Donations make it possible to keep up the current development standard. Therefore, thanks a lot to all who donated to the project.

More information about donations and a list of people who donated can be found here: KeePass Donations.


Info  Source Code Acknowledgements

KeePass uses some classes and libraries written by different people and given away for free. Here I want to thank them for writing these classes and libraries.

Author Class / Library
Szymon Stefanek C++ implementation of the AES/Rijndael encryption algorithm.
Niels Ferguson C implementation of the Twofish encryption algorithm.
Brian Gladman C implementation of the SHA-2 (256/384/512) hashing algorithms.
Alvaro Mendez MFC class for validating edit controls (CAMSEdit).
Brent Corkum MFC class for XP-style menu (BCMenu).
Davide Calabro MFC class for buttons with icons (CButtonST).
Zorglab, Chris Maunder, Alexander Bischofberger, James White, Descartes Systems Sciences Inc. MFC class for color pickers (CColourPickerXP).
Peter Mares MFC class for window side banners (CKCSideBannerWnd).
Chris Maunder MFC class for system tray icons (CSystemTray).
Hans Dietrich, Chris Maunder MFC class for hyperlinks in dialogs (XHyperLink).
Lallous Class for sending simulated keystrokes to other applications (CSendKeys).
PJ Naughter MFC classes for checking for single instance (CSingleInstance) and version information (CVersionInfo).
Bill Rubin Command line C++ classes.
Boost Developers Boost C++ libraries.
Silktide Cookie Consent JavaScript plugin.

Author Resource
Mark Burnett List of 10000 Top Passwords, which KeePass uses in its password quality estimation algorithm.


Info  Icon Acknowledgements

Thanks a lot to Christopher Bolin for creating the main KeePass icon (see top left on this page) and its variations. Many thanks to Victor Andreyenkov for refining the application icons.

Many thanks to David Vignoni for creating the nice 'Nuvola' icon theme. Most of the icons used in KeePass and on its website are icons of this theme. You can find the original images on the website of the author, and the license below.

Furthermore, thanks to the authors of the following icons that KeePass uses:


Info  Translation Acknowledgements

Thanks a lot to all people who created translations for KeePass.


Info  Plugin Acknowledgements

Many thanks to all people who wrote plugins for KeePass. Without you, KeePass would be a lot less powerful and useful!


Info  Tools Acknowledgements

Thanks to Jordan Russell for creating Inno Setup. This tool is used to create the KeePass installation program.

Thanks to Dimitri van Heesch for the Doxygen utility, which is used to compile the source code documentation.


Info  Hosting/Distribution Acknowledgements


Thanks to SourceForge.net for hosting the KeePass downloads / translations / plugins and for providing the project support platform (forums, feature requests / bug trackers, ...) for free.
Thanks to domain)FACTORY for hosting the KeePass website.
Thanks to datensysteme-lenk for hosting the German KeePass support forum in the past.


Info  Suggestions and Forum Support Acknowledgements

Thanks to all the people answering questions of others in the KeePass forums! A product is only as good as its support is, and I alone could never provide such an excellent individual help platform.

A few persons should be mentioned here, because of an extraordinary amount of suggestions (features, bug reports, ...) and helping others in the forums: Paul Tannard, Wellread1 and Michael Scheer.


Info  Special Acknowledgements

Thanks to Daniel Turini for suggesting "KeePass" as the name of the project.

An especially big thanks to Bill Rubin. He not only contributed a lot of source code to KeePass, he also had an enormous amount of feature and improvement suggestions, helped people in the KeePass forums, and wrote a KeePass plugin for backing up databases. He's also the reason why many of the sections in the KeePass Help are very precise, helpful, clear and easy to understand. In our countless hours long IM chats, we not only discussed much about the design of KeePass, Bill also told me a lot about C++ and other stuff. Thanks!


Info  Licenses of Components/Resources/etc.

Nuvola Icon Theme

Usage of the icons is allowed under the terms of the LGPL license (which you can find here: GNU Lesser General Public License), plus an addition.

TITLE:  NUVOLA ICON THEME for KDE 3.x
AUTHOR: David Vignoni | ICON KING
SITE:   http://www.icon-king.com
MAILING LIST: http://mail.icon-king.com/mailman/listinfo/nuvola_icon-king.com

Copyright (c)  2003-2004  David Vignoni.

This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation,
version 2.1 of the License.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with this library (see the the license.txt file); if not, write
to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston,
MA  02111-1307  USA
#######**** NOTE THIS ADD-ON ****#######
The GNU Lesser General Public License or LGPL is written for software libraries
in the first place. The LGPL has to be considered valid for this artwork
library too.
Nuvola icon theme for KDE 3.x is a special kind of software library, it is an
artwork library, it's elements can be used in a Graphical User Interface, or
GUI.
Source code, for this library means:
 - raster png image* .
The LGPL in some sections obliges you to make the files carry
notices. With images this is in some cases impossible or hardly usefull.
With this library a notice is placed at a prominent place in the directory
containing the elements. You may follow this practice.
The exception in section 6 of the GNU Lesser General Public License covers
the use of elements of this art library in a GUI.
dave [at] icon-king.com

Date:       15 october 2004
Version:    1.0

DESCRIPTION:

Icon theme for KDE 3.x.
Icons where designed using Adobe Illustrator, and then exported to PNG format.
Icons shadows and minor corrections were done using Adobe Photoshop.
Kiconedit was used to correct some 16x16 and 22x22 icons.

LICENSE

Released under GNU Lesser General Public License (LGPL)
Look at the license.txt file.

CONTACT

David Vignoni
e-mail :        david [at] icon-king.com
ICQ :           117761009
http:           http://www.icon-king.com

Boost

Boost Software License - Version 1.0 - August 17th, 2003

Permission is hereby granted, free of charge, to any person or organization
obtaining a copy of the software and accompanying documentation covered by
this license (the "Software") to use, reproduce, display, distribute,
execute, and transmit the Software, and to prepare derivative works of the
Software, and to permit third-parties to whom the Software is furnished to
do so, all subject to the following:

The copyright notices in the Software and this entire statement, including
the above license grant, this restriction and the following disclaimer,
must be included in all copies of the Software, in whole or in part, and
all derivative works of the Software, unless such copies or derivative
works are solely in the form of machine-executable object code generated by
a source language processor.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT
SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE
FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE,
ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
DEALINGS IN THE SOFTWARE.

Twofish Implementation

Fast, portable, and easy-to-use Twofish implementation,
Version 0.3.
Copyright (c) 2002 by Niels Ferguson.

The author hereby grants a perpetual license to everybody to
use this code for any purpose as long as the copyright message is included
in the source code of this or any derived work.

SHA-2 Implementation

Copyright (c) 2003, Dr Brian Gladman, Worcester, UK.   All rights reserved.

LICENSE TERMS

The free distribution and use of this software in both source and binary
form is allowed (with or without changes) provided that:

  1. distributions of this source code include the above copyright
     notice, this list of conditions and the following disclaimer;

  2. distributions in binary form include the above copyright
     notice, this list of conditions and the following disclaimer
     in the documentation and/or other associated materials;

  3. the copyright holder's name is not used to endorse products
     built using this software without specific written permission.

ALTERNATIVELY, provided that this notice is retained in full, this product
may be distributed under the terms of the GNU General Public License (GPL),
in which case the provisions of the GPL apply INSTEAD OF those given above.

DISCLAIMER

This software is provided 'as is' with no explicit or implied warranties
in respect of its properties, including, but not limited to, correctness
and/or fitness for purpose.
---------------------------------------------------------------------------
Issue 01/08/2005

CSendKeys

Copyright (c) 2004 lallous <lallousx86@yahoo.com>
All rights reserved.

Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions
are met:
1. Redistributions of source code must retain the above copyright
   notice, this list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright
   notice, this list of conditions and the following disclaimer in the
   documentation and/or other materials provided with the distribution.

THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
SUCH DAMAGE.

---------------------------------------

The Original SendKeys copyright info

SendKeys (sndkeys32.pas) routine for 32-bit Delphi.
Written by Ken Henderson
Copyright (c) 1995 Ken Henderson <khen@compuserve.com>

Command Line Classes

Copyright (c) 2006, Bill Rubin <rubin@contractor.net>
All rights reserved.

Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:

    * Redistributions of source code must retain the above copyright
      notice, this list of conditions and the following disclaimer.

    * Redistributions in binary form must reproduce the above copyright
      notice, this list of conditions and the following disclaimer in the
      documentation and/or other materials provided with the distribution.

    * Neither the name of Quality Object Software, Inc., nor the names of
      its contributors may be used to endorse or promote products derived
      from this software without specific prior written permission.

THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
POSSIBILITY OF SUCH DAMAGE.

Bouncy Castle Cryptographic C# API

The Bouncy Castle License
Copyright (c) 2000-2010 The Legion Of The Bouncy Castle
(http://www.bouncycastle.org)

Permission is hereby granted, free of charge, to any person obtaining a
copy of this software and associated documentation files (the "Software"),
to deal in the Software without restriction, including without limitation
the rights to use, copy, modify, merge, publish, distribute, sub license,
and/or sell copies of the Software, and to permit persons to whom the
Software is furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
DEALINGS IN THE SOFTWARE.

Cookie Consent

Copyright (c) 2015 Silktide Ltd

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.

Docs/Chm/help/base/faq.html0000664000000000000000000001466513225117272014472 0ustar rootroot Administrative FAQ - KeePass
Help

Administrative FAQ


Frequently Asked Questions about the project, licensing, ...

Info  How can I help you?

If you like KeePass and would like to help the developers in some way:

  • Donate
    This is the best way of helping, if you don't have that much time or experience in application development.
  • Make a translation
    If you have some free time, you could make a translation of KeePass (of course only if you're language isn't offered already).
  • Test new releases and report bugs
    KeePass is under constant development, new features get implemented, bugs get fixed. If you have some free time, you could test new releases thoroughly and report bugs. If you're a programmer, look through the sources to find bugs and maybe even submit fixes.
  • Spread the word
    If you like KeePass, tell all your friends how great KeePass is, publish articles about it, press it on CDs/DVDs, ship USB sticks preinstalled with it, submit it to software archives, talk in forums about it, etc.!

Info  May KeePass be used in a company?

Yes. KeePass is free software and you don't have to pay any fees. You may freely use KeePass under the terms of its license.

But of course, if you like KeePass, donations are always greatly appreciated.

You might be interested in this page: Customization (2.x).

Info  What about a centralized KeePass Internet server?

The idea on the first glance sounds simple and useful: there should be a centralized KeePass Internet server, on which all users can store their passwords. By having Internet connection, you'd have access to all your passwords.

Note that this idea is different from simply providing webspace. KeePass 2.x already supports storing databases on servers using HTTP/FTP. The point is having one server for all users.

When creating such a server, there are several difficulties:

  • A fairly complex synchronization and caching mechanism will be required. You won't want to transfer the complete database, otherwise the service will be unusable for everyone storing attachments, etc.

  • Directly related to the previous point: in order to do synchronization, the server needs to be able to read and understand databases, i.e. some dedicated KeePass server would need to be written. While the transport way could be secure HTTPS, the server certainly has some user data as plain text in memory for some time. One needs to be very careful here. What to do if the server gets compromised? The security implications would be horrible, if an attacker could read any user data.

  • How to avoid server compromises? If a normal Internet server is compromised, the security implications are minimal: in the worst case all user accounts and data for this website are lost. But with KeePass server, whole identities would be lost. An attacker couldn't only impersonate someone on this particular server, but on the complete Internet and real world, depending on what is stored in the databases.

    Therefore, banking-level security systems would be required for a KeePass server. Keeping PHP / ASP / Linux / Windows (or whatever will be used) up-to-date definitely is not enough here.

  • Basically you offer people webspace for their databases, therefore the service obviously will cost something. By charging people, they expect reliability and you need to make up-time guarantees. Therefore, at least 2 servers are required (by different hosters), which need to be synchronized.

Summary: a centralized Internet server currently is out of range. If someone wants to start a company providing such a service, feel free to use KeePass as base application (of course respect the Open Source terms).

But what can and probably will be done later is a local intranet KeePass server (for companies for example). Employees could log in to the company's password server and use it. But a centralized Internet server – no chance.

Docs/Chm/help/base/secedits.html0000664000000000000000000000412413225117272015513 0ustar rootroot Secure Edit Controls - KeePass
Help

Secure Edit Controls


KeePass supports security-enhanced edit controls.

KeePass was one of the first password managers featuring secure edit controls. The edit controls used in KeePass are resistant to password revealers and password control spies. Additionally, the entered passwords are protected against memory dumping attacks: the passwords aren't even visible in the process memory space of KeePass!

KeePass uses secure edit controls only when the hiding behind asterisks option is turned on! If you show the passwords in plaintext, they won't be protected (secure edit controls are just disabled then, replaced by standard Windows edit controls).

There are no selection limitations. Secure edit controls behave exactly like standard Windows edit controls. Docs/Chm/help/base/repair.html0000664000000000000000000001055213225117272015174 0ustar rootroot Repairing Databases - KeePass
Repair

Repairing Databases


KeePass can repair corrupted databases in some cases.

KeePass has quite some features to avoid database file corruption (transacted database writing, device buffer flushing, ...). However, data corruption can still be caused by other programs, the system or broken storage devices (note that KeePass by default is verifying the integrity of database files immediately after writing them, i.e. at this point of time, KeePass guarantees file integrity; however, KeePass of course can't do anything when the data becomes corrupted/unreadable at a later point of time).

In these cases, the database repair functionality might help you. Here, KeePass tries to read as much data as possible from the corrupted file.

Warning In repair mode, the integrity of the data is not checked (in order to rescue as much data as possible). When no integrity checks are performed, corrupted/malicious data might be incorporated into the database. Thus the repair functionality should only be used when there really is no other solution. If you use it, afterwards you should thoroughly check your whole database for corrupted/malicious data.

In order to use the repair functionality in KeePass 2.x, first create a new database file. Then, go 'File''Import' and import the corrupted database file, using 'KeePass KDBX (2.x) (Repair Mode)' as format.

Anyway, if you've lost the master key for the database, the repair functionality cannot help you. Also, if the header of the database (first few bytes) is corrupted, you're out of luck too: the repair functionality won't be able to restore any entries (because the header contains information required to decrypt the database).

The repair functionality should be seen as last hope. Regularly making backups of your databases is much better and has to be preferred. Backups have no cryptographic security implications. There are plugins that automate the backup process, see the KeePass plugins page.


Repair  File Header/Signature

If your database file has been deleted and you want to try recovering it using a tool that supports a file header/signature detection: below you can find the first bytes (in hex notation) with which all database files begin.

  • KeePass 1.x KDB File:
    03 D9 A2 9A 65 FB 4B B5
  • KeePass 2.x KDBX File:
    03 D9 A2 9A 67 FB 4B B5

The file header does not contain a field that specifies the length of the file. If the length cannot be determined from the file system, try to recover sufficiently much data (i.e. the database file data and maybe some subsequent, unnecessary data) and use the repair functionality above, which will simply ignore any subsequent data.

Docs/Chm/help/v2_dev/0000775000000000000000000000000013225117272013274 5ustar rootrootDocs/Chm/help/v2_dev/plg_index.html0000664000000000000000000006515213225117272016144 0ustar rootroot Plugin Development - KeePass
Settings

Plugin Development


How to develop plugins for KeePass 2.x.

This documentation applies to KeePass 2.x plugins. 2.x plugins are fundamentally different from 1.x plugins. 1.x plugins cannot be loaded by KeePass 2.x.


Info  Requirements

Before you can start developing a KeePass plugin, you need the following prerequisites:


Info  Step-by-Step Tutorial

Start your favorite IDE and create a new C# Class Library project (for the .NET Framework, not .NET Standard/Core). In this tutorial, the example plugin we're developing is called SamplePlugin. The first thing you need to do now is to add a reference to KeePass: go to the references dialog and select the KeePass.exe file (from the portable ZIP package). After you added the reference, the namespaces KeePass and KeePassLib should be available.

KeePass plugins all need to derive from a base KeePass plugin class (Plugin in the KeePass.Plugins namespace). By overriding methods of this class, you can customize the behavior of your plugin.

A minimal plugin looks like this:

using System;
using System.Collections.Generic;

using KeePass.Plugins;

namespace SamplePlugin
{
	public sealed class SamplePluginExt : Plugin
	{
		private IPluginHost m_host = null;

		public override bool Initialize(IPluginHost host)
		{
			m_host = host;
			return true;
		}
	}
}

You can find a fully documented and extended version of this simple plugin on the KeePass plugins web page.

This plugin does exactly nothing, but it shows some important conventions already, which must be followed by all plugins:

  • The namespace must be named like the DLL file without extension. Our DLL file is named SamplePlugin.dll, therefore the namespace must be called SamplePlugin.
  • The main plugin class (which KeePass will instantiate when it loads your plugin) must be called exactly the same as the namespace plus "Ext". In this case: "SamplePlugin" + "Ext" = "SamplePluginExt".
  • The main plugin class must be derived from the KeePass.Plugins.Plugin base class.

The Initialize function is the most important one and you probably will always override it. In this function, you get an interface to the KeePass internals: an IPluginHost interface reference. By using this interface, you can access the KeePass main menu, the currently opened database, etc. The Initialize function is called immediately after KeePass loads your plugin. All initialization should be done in this function (not in the constructor of your plugin class!). If you successfully initialized everything, you must return true. If you return false, KeePass will immediately unload your plugin.

A second function that you will need very often is the Terminate function:

public override void Terminate()
{
}

This function is called shortly before KeePass unloads your plugin. You cannot abort this process (it's just a notification and your last chance to clean up all used resources, etc.). Immediately after you return from this function, KeePass can unload your plugin. It is highly recommended to free all resources in this function (not in the destructor of your plugin class!).

We're almost done! We now need to tell KeePass that our file is a KeePass plugin. This is done by editing the Version Information Block of the file. Open the file version editing dialog (in Visual Studio 2005: right-click onto the project name - 'Properties' - button 'Assembly Information'). All fields can be assigned freely except the Product Name field (for more information see Plugin Conventions). This field must be set to "KeePass Plugin" (without the quotes).

That's it! Now try to compile your plugin and copy the resulting DLL file into the KeePass directory. If you start KeePass and go to the plugins dialog, you should see your plugin in the list of loaded plugins!


Info  Common Operations

Adding Menu Items:

Very often you want to add some menu items for your plugin. When clicked by the user, your plugin should get some notification. This can be done like follows. First of all you need to get a reference to the KeePass main menu or one of the special submenus (like Import, Tools, etc.). For this you can use the IPluginHost interface, which you received in the Initialize function. Then you can use standard tool strip operations to add a new menu item for your plugin. A very simple example, which adds a menu item to the Tools menu:

private ToolStripSeparator m_tsSeparator = null;
private ToolStripMenuItem m_tsmiMenuItem = null;

public override bool Initialize(IPluginHost host)
{
	m_host = host;

	// Get a reference to the 'Tools' menu item container
	ToolStripItemCollection tsMenu = m_host.MainWindow.ToolsMenu.DropDownItems;

	// Add a separator at the bottom
	m_tsSeparator = new ToolStripSeparator();
	tsMenu.Add(m_tsSeparator);

	// Add menu item 'Do Something'
	m_tsmiMenuItem = new ToolStripMenuItem();
	m_tsmiMenuItem.Text = "Do Something";
	m_tsmiMenuItem.Click += this.OnMenuDoSomething;
	tsMenu.Add(m_tsmiMenuItem);
}

public override void Terminate()
{
	// Remove all of our menu items
	ToolStripItemCollection tsMenu = m_host.MainWindow.ToolsMenu.DropDownItems;
	m_tsmiMenuItem.Click -= this.OnMenuDoSomething;
	tsMenu.Remove(m_tsmiMenuItem);
	tsMenu.Remove(m_tsSeparator);
}

private void OnMenuDoSomething(object sender, EventArgs e)
{
	// Called when the menu item is clicked
}

If you are working with tool strips, you of course have to add a reference to System.Windows.Forms of the .NET framework.

It is highly recommended that you unlink all event handlers and remove all menu items created by your plugin in the Terminate function (as shown in the example above). After the Terminate function has been called, everything should look like before loading your plugin.

In the example, we created a separator and one menu item. To this menu item an event handler for the Click event is attached. There's nothing special, this is all standard Windows.Forms code.

For examples of adding popup menus, see the SamplePlugin sample plugin (obtainable from the KeePass plugins page).


Adding Groups and Entries:

For this, see the sample plugin and the KeePassLib documentation.


Info  Plugin Conventions

File Version Information Block:

KeePass uses the file version information block to detect if a DLL file is a KeePass plugin and retrieves information from it to show in the plugins dialog. The fields are used as follows:

  • Title: Should contain the full name of the plugin.
  • Description: Should contain a short description (not more than 5 lines) of your plugin.
  • Company: Should contain the author name of the plugin.
  • Product Name: Must be set to "KeePass Plugin" (without the quotes).
  • Copyright: Not used by KeePass; freely assignable by the plugin.
  • Trademarks: Not used by KeePass; freely assignable by the plugin.
  • Assembly Version: Should be set to the version of your plugin.
  • File Version: Should be set to the version of your plugin. It is up to you how you are versioning your plugin builds, but it should be a scheme that allows version comparisons (by comparing the version components). Do not use asterisks for creating a version number at build time.
  • GUID: Not used by KeePass; freely assignable by the plugin.

Namespace and Class Naming:

The namespace must be named like the DLL file without extension. For example, if the DLL file is named SecretImporter.dll, you must call the namespace SecretImporter.

The plugin class must be named like the namespace plus "Ext". For the SecretImporter plugin, this would be SecretImporterExt.


Exchange  Update Checking

The update check of KeePass ≥ 2.18 can also check for plugin updates. Update check support is optional; plugins don't have to support update checks.

In order to support update checks, plugin developers need to do the following:

  • Provide version information file. When an end-user invokes an update check, KeePass downloads a version information file, which specifies the current version numbers of one or more plugins. Every plugin author hosts an own version information file. The format of the version information file is described in detail below.
  • Let KeePass know. In order to be able to check the plugin's version, KeePass must know where your version information file is located. To let KeePass know, override the UpdateUrl string property of your plugin class (the one derived from Plugin) to return the full, absolute URL of your version information file. This should be an https:// URL (for backward compatibility, KeePass also supports http:// and ftp://, but for security reasons https:// should be used).

Plugin developers have to update their version information file each time they release new versions of their plugins.

Version information file format.

  • The file is a simple text file. It must be encoded using UTF-8 without a byte order mark (KeePass ≥ 2.21 supports UTF-8 BOMs in version information files, however for compatibility with KeePass < 2.21 it is recommended not to use a BOM). All line endings are supported.
  • The first line of the file must start with a separator character of your choice. The separator character may be any character, but it must not appear within plugin names and versions. Suggested is ':'.
  • Each of the following lines specifies a plugin name and its currently available version, separated by the separator character that was specified in the header line.
  • As plugin name, the value of the 'Title' field in the version information block of the plugin must be specified. For managed plugins, this is the value specified using the AssemblyTitle assembly attribute.
  • As version number, the value of the file version in the version information block of the plugin must be specified. For managed plugins, this is the value specified using the AssemblyFileVersion assembly attribute. Trailing .0 may be removed (e.g. specify 1.3 instead of 1.3.0.0).
  • The file must end with a line containing only the separator character.
  • You may optionally compress your version information file using GZip (note this is not the same as Zip). The file name must then end with ".gz".

Example. Let's assume you're developing two plugins: MyPlugin1 (version 1.5) and MyPlugin2 (version 1.13.2.17). Then your version information file could look as follows:

:
MyPlugin1:1.5
MyPlugin2:1.13.2.17
:

If you've developed multiple plugins, it is recommended to create one version information file, list all your plugins in this file and specify the URL of the file in all your plugins. When KeePass checks for updates, it'll download your version information file only once. This reduces network traffic and is faster than downloading a version information file for every plugin separately.

Signing. Since KeePass 2.34, you can optionally digitally sign your version information file using RSA / SHA-512.

  • An RSA key pair can for instance be generated like the following:
    using(RSACryptoServiceProvider rsa = new RSACryptoServiceProvider(4096))
    {
    	rsa.PersistKeyInCsp = false;
    	Console.WriteLine("Private key: " + rsa.ToXmlString(true));
    	Console.WriteLine("Public key: " + rsa.ToXmlString(false));
    }
    All key lengths supported by RSACryptoServiceProvider are supported by KeePass (up to .NET 4.5 that is 384 to 16384 bits in 8 bit steps). We recommend at least 2048 bits; the main version information file (containing the KeePass version) uses 4096 bits.
  • In order to tell KeePass to accept a specific version information file only when it's verifiable with a specific public key, your plugin must call the UpdateCheckEx.SetFileSigKey method to associate the specified URL with the specified public key. The public key must be an XML string in the format as returned by the RSACryptoServiceProvider.ToXmlString method. Do not store the private key in your plugin, only the public key.
  • To sign an unsigned version information file, hash all trimmed non-empty lines between the header and the footer line using SHA-512, UTF-8 encoding, each line terminated by '\n' (not "\r\n"). Sign the hash using the private key (if you're using RSACryptoServiceProvider: load the private key using its FromXmlString method, then compute the signature using the SignData method). Encode the hash using Base64 and append it to the first line of the version information file.

Info  Can KeePass 2.x Plugins be written in Unmanaged C++?

Yes and no. You can write the complete logic of your plugin in unmanaged C++ (native Win32 APIs can be used). Anyway you must provide a managed interface to your plugin, i.e. you must export a managed class derived from the Plugin base class as described in the step-by-step tutorial.

Also, managed C++ will be required to modify the KeePass internals (i.e. entries, groups, main window, ...).

For an example how to use unmanaged APIs in a managed C++ plugin assembly, see the SamplePluginCpp sample plugin (obtainable from the KeePass plugins page).


Info  PLGX Files

PLGX is an optional plugin file format for KeePass ≥ 2.09. Instead of compiling your plugin to a DLL assembly, the plugin source code files can be packed into a PLGX file and KeePass will compile the plugin itself when loading it. The advantage of this approach is that plugins don't need to be recompiled by the plugin developers for each KeePass release anymore (as KeePass compiles the plugin itself, the generated plugin assembly references the current, correct KeePass assembly). Instead of shipping a plugin DLL assembly, you ship the PLGX.

For users, nothing changes. Instead of putting the plugin DLL assembly into the KeePass application directory, the PLGX file needs to be put there.

KeePass ≥ 2.14 also loads older plugin DLLs. However, an API within KeePass might have changed and .NET detects this when the plugin tries to call/access the method/class, not at loading time. This means that an incompatibility is detected relatively late and might crash KeePass. In contrast, when using the PLGX format, an incompatibility is detected immediately at loading time: if there is a problem, the compile process will just fail and KeePass can present an informative plugin incompatibility message to the user. Therefore, it is recommended that plugin developers create/ship PLGX files, not DLLs.

Creating PLGX files. PLGX files can be created from plugin sources by calling KeePass.exe with the --plgx-create command line option. If you additionally pass a path to the plugin sources directory (without terminating separator), KeePass will use this one; otherwise it'll show a folder browser dialog to allow you selecting the directory. If you want to pass the directory location using the command line, make sure that you're specifying a full, absolute path -- relative paths will not work.

In order to keep the size of the PLGX file small, it is recommended that you clean up the plugin sources directory before compiling the PLGX. Remove all unnecessary binary files (files in the bin and obj directory); especially, delete any plugin assembly DLL that you compiled yourself. Temporary files by the IDE (like .suo and .user files) can also be deleted.

PLGX features:

  • Extensible, object-oriented file format.
  • Compression support (data files are compressed using GZip).
  • .csproj support. KeePass retrieves all information required for compiling the plugin assembly from the .csproj file in the plugin sources.
  • Embedded resources support.
  • Referenced .NET assemblies support. References information is read from the .csproj file.
  • Referenced custom assemblies support. Third-party assemblies required by the plugin (references to DLLs) are supported, provided that the third-party assembly is located in the plugin source code directory (or any subdirectory of it).
  • ResX support. .resx files are automatically compiled to binary .resources files.
  • PLGX cache. PLGX files are compiled once and the generated assembly is stored in a cache. For all following KeePass starts, no compiling is required.
  • PLGX cache maintenance. The size of the PLGX cache can be seen in the KeePass plugins dialog. Here, the cache can also be marked to be cleared (it will be cleared when KeePass is started the next time). An option to automatically delete old files from the cache is supported and enabled by default.

PLGX limitations:

  • Currently only C# is supported (not Visual Basic or any other .NET language).
  • Linked resources (in different assemblies) are unsupported.
  • Dependencies on other projects are unsupported (reorganize your project to use custom assembly references instead).

Defining prerequisites. You can optionally specify a minimum KeePass version, a minimum installed .NET Framework, an operating system and the minimum size of a pointer (x86 vs. x64) using the --plgx-prereq-kp:, --plgx-prereq-net:, --plgx-prereq-os: and --plgx-prereq-ptr: command line options. If one of the plugin prerequisites isn't met, KeePass shows a detailed error message to the end-user (instead of a generic plugin incompatibility message). Build example:
KeePass.exe --plgx-create C:\YourPluginDir --plgx-prereq-kp:2.09 --plgx-prereq-net:3.5

Valid operating system values are Windows and Unix. When running on an unknown operating system, KeePass defaults to Windows. Pointer sizes (checking for x86 vs. x64) are specified in bytes; for example, to only allow running on x64, you specify --plgx-prereq-ptr:8.

Build commands. Optionally you can specify pre-build and post-build commands using --plgx-build-pre: and --plgx-build-post:. These commands are embedded in the PLGX file and executed when compiling the plugin on the end-user's system.

In the build commands, the placeholder {PLGX_TEMP_DIR} specifies the temporary directory (including a terminating separator), to which the files were extracted. In the post-build command, {PLGX_CACHE_DIR} is replaced by the cache directory of the plugin (including a terminating separator), into which the generated assembly was stored.

These build commands can for example be used to copy additional files into the cache directory. Example:
KeePass.exe --plgx-create C:\YourPluginDir --plgx-build-post:"cmd /c COPY """{PLGX_TEMP_DIR}MyFile.txt""" """{PLGX_CACHE_DIR}MyFile.txt""""

In order to specify a quote character on the command line, it has to be encoded using three quotes (this is Windows standard, see MSDN: SHELLEXECUTEINFO). So, the command line above will actually embed the post-build command cmd /c COPY "{PLGX_TEMP_DIR}MyFile.txt" "{PLGX_CACHE_DIR}MyFile.txt" into the PLGX, which is correct. It is highly recommended to surround paths including PLGX placeholders using quotes, otherwise the command will not run correctly if the path contains a space character (which happens very often).

If you need to run multiple commands, write them into a batch file and execute it (with cmd). If you need to perform more complex build tasks, write an own building executable and run it using the build commands (typically it is useful to pass the directory locations as arguments to your building executable), for example:
KeePass.exe --plgx-create C:\YourPluginDir --plgx-build-post:"{PLGX_TEMP_DIR}MyBuild.exe {PLGX_TEMP_DIR} {PLGX_CACHE_DIR}"

PLGX debugging. When the command line option --debug is passed and a PLGX plugin fails to compile, the output of all tried compilers is saved to a temporary file.

Docs/Chm/help/v2_dev/customize.html0000664000000000000000000001666313225117272016220 0ustar rootroot Customization (2.x) - KeePass
Computer

Customization (2.x)


KeePass 2.x features various options for network administrators to customize the program's appearance and behavior.

System  Preliminaries

Most options below are configured by directly editing the KeePass.config.xml configuration file. If you're planning to deploy a customized KeePass version, you should fully understand the KeePass configuration system, especially how to enforce some settings and leave others up to users.

Note that KeePass features a rich plugin framework. If there's no item in the XML file to configure what you're thinking about, you might want to write a plugin.


Key  Minimum Master Password Requirements

You can specify several properties that master passwords must have in order to be accepted (length, estimated quality, ...). See Specifying Minimum Master Password Properties.


Locked  Specifying UI Element States

The state (enabled, disabled, visible, hidden) of several user interface (UI) elements can be specified using the UIFlags value of the UI node in the configuration file. This can be a bitwise combination of one or more of the following flags:

Flag (Hex)Flag (Dec) Description
0x00 Don't force any states (default).
0x11 Disable 'Tools' → 'Options' menu item.
0x22 Disable 'Tools' → 'Plugins' menu item.
0x44 Disable 'Tools' → 'Triggers' menu item.
0x88 Disable controls to specify after how many days the master key should/must be changed.
0x1016 Hide password quality progress bars and information labels.
0x2032 Disable 'Help' → 'Check for Updates' menu item.
0x1000065536 Hide built-in profiles in the password generator context menu of the entry editing dialog.
0x20000131072 Show UI elements related to last access times.
Note: Databases are not marked as modified when a last access time changes. Thus, when only last access times are changed and the user closes the database (without saving manually first and without a save forced e.g. by a trigger or plugin), the changes to the last access times are lost.
0x40000262144 Do not display information dialogs when creating a new database.

The value of UIFlags must be specified in decimal notation.

For example, if you want to disable the 'Options' and 'Check for Updates' menu items, you'd specify 33 as value for the UIFlags node (0x1 + 0x20 = 1 + 32 = 33).


Key  More Options

  • Configuration/Defaults/WinFavsBaseFolderName:
    For the 'Windows Favorites' export: name of the root folder; the default value is 'KeePass'.
  • Configuration/Defaults/WinFavsFileNamePrefix:
    For the 'Windows Favorites' export: prefix for the title of every favorite; the default value is an empty string.
  • Configuration/Defaults/WinFavsFileNameSuffix:
    For the 'Windows Favorites' export: suffix for the title of every favorite; the default value is an empty string.
  • Configuration/Integration/AutoTypeInterKeyDelay:
    Specifies the default delay (in ms) between two keypresses sent by auto-type. The minimum is 1 ms. Note that very small delays may result in target applications not being able to process the keypresses correctly.
  • Configuration/Integration/AutoTypeAbortOnWindows:
    This node may contain one or more Window nodes that specify disallowed auto-type target windows (the value of each node must be a target window filter).

    For example, the following configuration disallows auto-typing into WordPad and LibreOffice Writer:

    <AutoTypeAbortOnWindows>
        <Window>* - WordPad</Window>
        <Window>* - LibreOffice Writer</Window>
    </AutoTypeAbortOnWindows>
  • Configuration/Security/MasterKeyTries:
    Specifies how often the master key dialog appears when entering incorrect master keys. The default value is 3.
  • Configuration/Application/ExpirySoonDays:
    Specifies the number of days within which entries are considered to expire "soon". The default value is 7.
Docs/Chm/help/v2_dev/scr_index.html0000664000000000000000000000540113225117272016140 0ustar rootroot Scripting Introduction - KeePass
Console

Scripting KeePass (2.x)


How to automate database operations in KeePass 2.x.

Prerequisites:

In order to automate KeePass, you need the KPScript plugin/extension. You can find the latest version of KPScript on the KeePass plugins web page. The KPScript.exe file needs to be copied into the directory where KeePass is installed (where the KeePass.exe file is).


There are two ways to automate KeePass: single command operations and KPS script files.

  • Single Command Operations: KPScript can be invoked using single commands. By passing the database location, its key, a command and eventually some parameters, simple operations like adding an entry can be performed. The syntax is very simple, no scripting knowledge is required. This method is ideal when you quickly want to do some small changes to the database. It is not recommended when you need to perform many operations, because for each command the database needs to be loaded from file, decrypted, modified, encrypted and written back to file.

  • KPS Script Files: These files are a lot more powerful than single command operations, but are also more complicated. You need to have heavy experience in C# programming and the KeePass 2.x internals. Within KPS files you can do everything that KeePass does.
Docs/Chm/help/v2_dev/scr_kps_index.html0000664000000000000000000000605413225117272017022 0ustar rootroot KPS Script Files - KeePass
Console

KPS Script Files


How to use KPS script files to automate KeePass 2.x.

KPS script files are a lot more powerful than single command operations, but are also more complicated. You need to have heavy experience in C# programming and the KeePass 2.x internals. Within KPS files you can do everything that KeePass does.

What are KPS files?

KPS files are C# files that are loaded, compiled and executed by the KPScript.exe program. Within the script file, you got full access to the KeePass internals.

The main differences to "normal" C# files are:

  • No need for using directives.
  • No need to add a reference to the KeePass assembly.
  • No need to write a wrapper class. Simply start with Main(). The complete script file is embedded in a static class.

Here's the famous Hello World program as KPS script:

public static void Main()
{
	MessageService.ShowInfo("Hello World!");
}

For the most important namespaces, KPScript automatically adds using directives at the start of the file before compiling it. MessageService for example is located in KeePassLib.Utility, but as it's included automatically by KPScript, you can use it directly.


Executing a KPS file:

To run a KPS file, you simply pass it to KPScript:

KPScript.exe C:\KeePass\MyScriptFile.kps

It is important that the file extension is .kps, otherwise KPScript won't recognize the file and will interpret it as database for single command operations.

Docs/Chm/help/v2_dev/scr_sc_index.html0000664000000000000000000004464213225117272016637 0ustar rootroot Single Command Operations - KeePass
Console

Single Command Operations


How to use KPScript with single command operations to perform simple database operations.

KPScript can be invoked using single commands. By passing the database location, its key, a command and eventually some parameters, simple operations like adding an entry can be performed. The syntax is very simple, no scripting knowledge is required. This method is ideal when you quickly want to do some small changes to the database. It is not recommended when you need to perform many operations, because for each command the database needs to be loaded from file, decrypted, modified, encrypted and written back to file.

Commands are specified by passing -c:COMMAND to KPScript, where COMMAND is the command to execute (see below for a list of available commands).

The database location is passed to KPScript by just passing it as a parameter, without any option prefix.


User Key  Master Key

The composite master key for the database can be given to KPScript using one of the following ways:

  • Command Line Parameters. Using the -pw:, -pw-enc:, -keyfile: and -useraccount parameters. For example, to pass "Secret" as password, you'd give KPScript the following parameter: -pw:Secret. If the password contains spaces or other special characters, it must be enclosed in quotes: -pw:"My Top Secret Password". For -pw-enc:, see the {PASSWORD_ENC} placeholder. The -keyfile: parameter can specify the key file location. If -useraccount is passed to KPScript, the user account credentials of the currently logged on user are used, otherwise not.

  • Entering interactively using the command line. If you pass -keyprompt to KPScript, it will prompt you for the key. You can enter the password, key file location and user account directly in the console window.

  • Entering interactively using graphical user interface. If you pass -guikeyprompt to KPScript, it will prompt you for the key using the standard key dialog of KeePass.

Console  Available Commands

Please note that commands are added incrementally based on user requests. If you are missing a command, please let the KeePass team know and it will be added to the next release of KPScript.

Currently, the following commands are available:



Command: ListGroups

This command lists all groups in a format that easily machine-readable. The output is not intended to be printed/used directly. Usage example:

KPScript -c:ListGroups "C:\KeePass\MyDb.kdbx" -pw:MyPassword
This will list all groups contained in the MyDb.kdbx database file.



Command: ListEntries

This command lists all entries in a format that easily machine-readable. The output is not intended to be printed/used directly. Usage example:

KPScript -c:ListEntries "C:\KeePass\MyDb.kdbx" -pw:MyPassword -keyfile:"C:\KeePass\MyDb.key"
Opens the MyDb.kdbx database using 'MyPassword' as password and the MyDb.key file as key file. It will output a list of all entries contained in the MyDb.kdbx database file.



Command: GetEntryString

Retrieves the value of an entry string field. The entry identification syntax is exactly the same as in the EditEntry command. Additional command line parameters:

  • -Field:NAME
    The field name can be specified using the '-Field' parameter. Supported field names are e.g. Title, UserName, Password, URL, Notes, etc.
  • -FailIfNotExists
    If you pass the option '-FailIfNotExists' and the specified field does not exist, the operation is aborted and an error is returned.
  • -FailIfNoEntry
    If you pass the option '-FailIfNoEntry' and no entry is found, KPScript terminates with an error.
  • -Spr
    Spr-compiles the value of the field, i.e. placeholders are replaced, field references are resolved, etc.

Usage example:

KPScript -c:GetEntryString "C:\KeePass\MyDb.kdbx" -pw:MyPassword -Field:UserName -ref-Title:"Demo Account"
Opens the MyDb.kdbx database using 'MyPassword' as password. It outputs the user names of all entries that have the title "Demo Account".



Command: AddEntry

This command adds an entry to the database. To specify the entry details, use the standard string field identifiers as parameter names and their values for the contents. Supported standard string fields are: Title, UserName, Password, URL, and Notes. Usage examples:

KPScript -c:AddEntry "C:\KeePass\MyDb.kdbx" -pw:MyPw -Title:"New entry title"

KPScript -c:AddEntry "C:\KeePass\MyDb.kdbx" -pw:MyPw -Title:SomeWebsite -UserName:Don -Password:pao5j3eg -URL:https://example.com/

Additional command line parameters:

  • -GroupName:NAME
    The -GroupName: parameter can be used to specify the group in which the entry is created. For searching, KPScript performs a pre-order traversal and uses the first matching group (the name is case-sensitive). If no group with the specified name is found, it will be created in the root group.
  • -GroupPath:PATH
    The full path of the group can be specified using the -GroupPath: parameter (use '/' as separator). If you do not specify a group name or path, the entry will be created in the root group.
  • -setx-Icon:ID
    Set the icon of the entry to the standard icon having index ID.
  • -setx-CustomIcon:ID
    Set the icon of the entry to the custom icon having index ID.

Example:

KPScript -c:AddEntry "C:\KeePass\MyDb.kdbx" -pw:MyPw -Title:"My Provider" -GroupName:"Internet Sites"



Command: EditEntry

This command edits existing entries.

Use one or more of the following parameters to identify the entries to be edited; all of the specified conditions must match:

  • -ref-FIELDNAME:FIELDVALUE
    The string field FIELDNAME must have the value FIELDVALUE.
    If the value is enclosed in '//', it is treated as a regular expression, which must occur in the entry field for the entry to match. For example, -ref-Title:"//Test\d\d//" matches every entry whose title contains 'Test' followed by at least two digits.
  • -refx-UUID:VALUE
    The UUID of the entry must be VALUE.
  • -refx-Tags:VALUE
    The entry must have the specified tags. Multiple tags can be separated using commas ','.
  • -refx-Expires:VALUE
    VALUE must be true or false. This parameter allows to specify whether the entry expires sometime (i.e. whether the 'Expires' checkbox is checked, independent of the expiry time).
  • -refx-Expired:VALUE
    VALUE must be true or false. This parameter allows to specify whether the entry has expired (i.e. whether the 'Expires' checkbox is checked and the expiry time is not in the future).
  • -refx-Group:VALUE
    The name of the parent group of the entry must be VALUE.
  • -refx-GroupPath:VALUE
    The full path of the parent group of the entry must be VALUE. Use '/' as group separator in the path.
  • -refx-All
    Matches all entries.

Use one or more of the following parameters to specify how the entry should be edited:

  • -set-FIELDNAME:FIELDVALUE
    Sets the string field FIELDNAME of the entry to the value FIELDVALUE.
  • -setx-Icon:ID
    Set the icon of the entry to the standard icon having index ID.
  • -setx-CustomIcon:ID
    Set the icon of the entry to the custom icon having index ID.
  • -setx-Expires:VALUE
    Sets whether the entry expires or not. VALUE must be either true or false.
  • -setx-ExpiryTime:VALUE
    Sets the expiry date/time of the entry.

Usage examples:

KPScript -c:EditEntry "C:\KeePass\MyDb.kdbx" -pw:MyPw -ref-Title:"Existing entry title" -set-UserName:"New user name"

KPScript -c:EditEntry "C:\KeePass\MyDb.kdbx" -pw:MyPw -ref-UserName:MyName -set-UserName:NewName -set-Password:"Top Secret"

If you additionally pass -CreateBackup, KPScript will first create backups of entries before modifying them.



Command: MoveEntry

This command moves one or more existing entries. The entry identification syntax is exactly the same as in the EditEntry command.

  • -GroupPath:PATH
    The target group can be specified using the -GroupPath: parameter. '/' must be used as separator (e.g. -GroupPath:Internet/eMail moves the specified entries to the subgroup 'eMail' of the subgroup 'Internet').
  • -GroupName:NAME
    The -GroupName: parameter can be used (see the AddEntry command for details).


Command: DeleteEntry

This command deletes one or more existing entries. The entry identification syntax is exactly the same as in the EditEntry command.



Command: DeleteAllEntries

This command deletes all entries (in all subgroups).



Command: Import

This command imports a file into the database.

  • -Format:NAME
    The format is specified by setting the "-Format" parameter (see names in the import dialog of KeePass).
  • -File:PATH
    The file to import to is specified using the "-File" parameter.
  • -MM:VALUE
    If the format supports UUIDs, the behavior for groups/entries that exist in both the current database and the import file can be specified using the optional "-MM" parameter. Possible values are "CreateNewUuids", "KeepExisting", "OverwriteExisting", "OverwriteIfNewer", and "Sync". By default, new UUIDs are created.
  • -imp_*:VALUE
    For encrypted import files, by default the master key of the target database is used. However, it is also possible to specify a different master key, using the usual master key command line parameters with the prefix '-imp_' (i.e. -imp_pw:, -imp_pw-enc:, -imp_keyfile:, -imp_useraccount, -imp_keyprompt, -imp_guikeyprompt).

Usage example:

KPScript -c:Import "C:\KeePass\MyDb.kdbx" -pw:MyPw -Format:"KeePass XML (2.x)" -File:SourceFile.xml



Command: Export

This command exports (parts of) the database.

  • -Format:NAME
    The format is specified by setting the "-Format" parameter (see names in the export dialog of KeePass).
  • -OutFile:PATH
    The file to export to is specified using the "-OutFile" parameter.
  • -GroupPath:PATH
    If a specific group should be exported (instead of the whole database), specify the group using the "-GroupPath" parameter (use '/' as separator).
  • -XslFile:PATH
    For the XSL transformation export module, the path of the XSL file can be passed using the "-XslFile" parameter.

Usage example:

KPScript -c:Export "C:\KeePass\MyDb.kdbx" -pw:MyPw -Format:"KeePass XML (2.x)" -OutFile:TargetFile.xml



Command: Sync

This command synchronizes the database with another one. The other database path has to be specified using the "-File" command line parameter. Usage example:

KPScript -c:Sync -guikeyprompt "C:\Path\A.kdbx" -File:"C:\Path\B.kdbx"



Command: ChangeMasterKey

This command changes the master key of the database. The new key values are specified using the standard options prefixed with 'new', i.e. -newpw:, -newkeyfile: and -newuseraccount (all are optional). Usage example:

KPScript -c:ChangeMasterKey "C:\KeePass\MyDb.kdbx" -pw:MyPw -newpw:MyNewPw



Command: DetachBins

This command saves all entry attachments (into the directory of the database) and removes them from the database. Usage example:

KPScript -c:DetachBins -guikeyprompt "C:\KeePass\MyDb.kdbx"



Command: GenPw

Generates passwords.

  • -count:NUMBER
    The number of passwords can be specified using the optional -count: parameter.
  • -profile:NAME
    A password generator profile can be specified using the optional -profile: parameter (the names of all available profiles can be found in the password generator dialog).

Usage examples:

KPScript -c:GenPw
Generates one password using the default generator profile.

KPScript -c:GenPw -count:5 -profile:"128-Bit Hex Key (built-in)"
Generates five 128-bit hex passwords (when no translation is used).



Command: EstimateQuality

Estimates the quality (in bits) of the password specified via the -text: parameter. Usage example:

KPScript -c:EstimateQuality -text:MyTopSecretPassword


Help  Console Character Encoding

If you observe garbled special characters in the output, please read the page Console Character Encoding.

Docs/Chm/help/v2/0000775000000000000000000000000013225117272012436 5ustar rootrootDocs/Chm/help/v2/sync.html0000664000000000000000000001663613225117272014314 0ustar rootroot Synchronization - KeePass
Synchronization

Synchronization


Merge changes made in multiple copies of a database.

Help  Introduction and Requirements

KeePass 2.x features a powerful, built-in synchronization mechanism. Changes made in multiple copies of a database file can be merged safely.

After synchronizing two files A and B, both A and B are up-to-date (i.e. KeePass saves the merged data to both locations when performing a synchronization).

Requirements.

  • If the files to be synchronized are accessible via a protocol that KeePass supports by default (e.g. files on a local hard disk or a network share, FTP, HTTP/WebDAV, ..., see the page Loading/Saving From/To URL for details), then no plugins/extensions are required.
  • If one of the files to be synchronized should be accessed via SCP, SFTP or FTPS, you need the IOProtocolExt plugin, which adds support for these protocols to KeePass.
  • If one of the files to be synchronized is stored in an online storage (like e.g. Amazon's S3, DigitalBucket, ...), you need an online storage provider plugin (e.g. KeeAnywhere, KeeCloud or KeePassSync). Note that you do not need a plugin in the other cases above (files on a local hard disk or network share, FTP, HTTP/WebDAV, SCP, SFTP, FTPS, ...).

Synchronization  Invoking a Synchronization

There are multiple ways how a synchronization can be invoked:

  • Manually. A synchronization can be started manually by navigating to 'File''Synchronize' and clicking 'Synchronize with File' or 'Synchronize with URL' (depending on whether the file to be synchronized with is stored on a local drive / network share or on a server accessible via an URL). If you've previously opened or synchronized with the target file, you can also simply point on 'Recent Files' (in the 'Synchronize' menu) and select the file. Manual synchronization is only possible when the currently opened database is a local file (files on a network share are here considered to be local files); when you've opened a file from a server using an URL, the 'Synchronize' menu is disabled.
  • Command 'Save'. When invoking the 'Save' command, KeePass checks whether the file on disk/server has been modified while you were editing it. If it has been modified, KeePass prompts whether you want to overwrite or synchronize with the file. Note this applies only to the 'Save' command, not the 'Save As' command. See the page Multi-User for details (section 'KeePass 2.x: Synchronize or Overwrite').
  • Triggers. In more complex situations you can use the synchronization trigger action. See the page Triggers for details.
  • Scripting. In order to perform a synchronization without opening KeePass, the synchronization command of KPScript can be used. See the KPScript help page Single Command Operations for details.

Synchronization  Technical Details

The synchronization algorithm is rather complex and it would take many pages to describe in detail how it's working. Developers interested in this can have a look into the KeePass source code. Here are the most important properties of the synchronization algorithm:

  • In order to decide which copy of an object is the latest one, KeePass mainly uses the last modification time of the object (which KeePass updates automatically each time the object is changed).
  • The synchronization is performed on entry level. This e.g. means that a combination of user name / password is always consistent (synchronization on field level will not be implemented, because combinations could become inconsistent with this).
  • In case of parallel updates and collisions, KeePass tries to store all information in an appropriate place. For example, when you have an entry E in a database A, make a copy B of A, change E in B, change E in A, and synchronize A and B, then E in A is treated as current and the changes made to E in B are stored as a history version of E (see tab 'History' in the entry dialog), i.e. the changes made in B aren't lost.

Synchronization  Advanced Synchronization Schemes

Docs/Chm/help/v2/dbsettings.html0000664000000000000000000001372113225117272015476 0ustar rootroot Database Settings - KeePass
Settings

Database Settings


Describes the various database options.

On the database settings dialog, you can configure various database-related settings.


Info  General

On this tab page you can specify general things like the name of the database and a description. Additionally, you can set various defaults like a default user name for new entries (created in this database).


Info  Security Options

On this page you can specify various settings related to encryption. Only change these settings if you really know what you are doing.

Encryption Algorithm:
You can choose the algorithm that is used to encrypt the database. All encryption algorithms offered by KeePass are well-known, secure algorithms, see Database Encryption.

Key Transformation:
See Protection against Dictionary Attacks.

KeePass has a button on this page to compute the number of key transformations that your computer can do in 1 second. If you for instance only want to wait 0.5 seconds, half the number resulted from the benchmark.


Info  Compression Options

KeePass databases can be compressed before being encrypted. Compression reduces the size of the database, but also slows down the database saving/loading process a bit.

It is recommended to use the GZip compression option. This algorithm is very fast (you won't notice any difference to saving the database without compression) and its compression rate is acceptable.

It is not recommended to save databases without compression.

On modern PCs, saving files with compression can actually be faster than saving without compression, because the compression process is performed by the CPU (which is very fast) and fewer data has to be transferred from/to the storage device. Especially when the device is slow (like saving to USB stick), compression can reduce the saving/loading time significantly.


Info  Templates

Templates are a great way to predefine often used user names or additional fields, or combinations of each.

  • A template is a normal KeePass entry with all required data already entered.
  • Templates must be kept in a single group.
  • Do not put real data entries in the template group.

First create a normal group in the main window and then set it as the templates group in 'File''Database Settings' → tab 'Templates'.

In order to create a new entry based on a template in the templates group, click the drop-down arrow of the 'Add Entry' toolbar button and choose the template to be used.

Docs/Chm/help/v2/translation.html0000664000000000000000000000671613225117272015674 0ustar rootroot Translations - KeePass
Language

Installing Translations


How to install translations of KeePass 2.x.

Language  Installing User Interface Translations

To install a user interface translation, follow these steps:

  1. Download the translation ZIP file from the Translations page and unpack it (to the current directory).
  2. In KeePass, click 'View' → 'Change Language' → button 'Open Folder'; KeePass now opens a folder called 'Languages'. Move the unpacked file(s) into the 'Languages' folder.
  3. Switch to KeePass, click 'View' → 'Change Language', and select your language. Restart KeePass.

Note. For moving the unpacked file(s) (in step 2), we recommend to use Windows Explorer. Other file managers may have problems with access rights.


Language  Additional Localized Content

For some languages (not for all) there is additional localized content available, like translated help files, tutorials, etc. All this content is available from the same page where the user interface translations are downloadable: Translations page.

If you'd like to create some translated content yourself, please first ask the KeePass team if the thing you're planning to create isn't in work already by someone else. If not, you'll make a lot of people very happy by creating translated content!

Docs/Chm/help/v2/version.html0000664000000000000000000000367613225117272015025 0ustar rootroot Compatibility - KeePass
System

Compatibility


Compatibility of KeePass editions.

KDBX files (created by KeePass 2.x) and KDB files (created by KeePass 1.x) are not compatible. KeePass 2.x supports a lot of features, which 1.x doesn't support, therefore these formats are incompatible.

But KeePass 2.x can import KDB files created by KeePass 1.x. For this, you first need to create a new database in KeePass 2.x and then import the 1.x database using 'File' → 'Import'.

By 'File' → 'Export', KeePass 2.x can also export data to 1.x KDB files. However note that not all 2.x fields are supported by 1.x (i.e. the export is lossy).

Docs/Chm/help/v2/plugins.html0000664000000000000000000001223613225117272015011 0ustar rootroot Plugins - KeePass
Plugin

KeePass Plugins


Installation, uninstallation and security of KeePass plugins.

Plugin  Introduction

KeePass features a plugin framework. Plugins can provide additional functionality, like support of more file formats for import/export, network functionalities, backup features, etc.


Info  Online Resources

Plugins can be found on the Plugins page.


Computer  Plugin Installation and Uninstallation

If there are no explicit instructions how to install the plugin, follow these steps:

  1. Download the plugin from the page above and unpack the ZIP file to a new folder.
  2. In KeePass, click 'Tools' → 'Plugins' → button 'Open Folder'; KeePass now opens a folder called 'Plugins'. Move the new folder (containing the plugin files) into the 'Plugins' folder.
  3. Restart KeePass in order to load the new plugin.

To uninstall a plugin, delete the plugin files.

Linux:
On some Linux systems, the mono-complete package may be required for plugins to work properly.


Locked  Security

What about the security of plugins? Can't malicious plugins 'inject' themselves into KeePass?

If plugins can register themselves (i.e. have write access to the KeePass directory), they could also just replace the whole 'KeePass.exe' file. It's a problem of file access rights, not the plugin system.

If you worry about this, install KeePass as administrator into the program files directory (which is the default, typically in a folder in 'C:\Program Files (x86)'). Afterwards, run KeePass and other applications only as normal user (without administrator privileges).

This solves the problem above. As the KeePass directory is write-protected for normal users, no other program can copy files into it. KeePass requires the plugins to be in the application directory. Therefore, plugins cannot inject themselves anymore.

If you use the portable package of KeePass or installed it into a different directory, you need to adjust the directory permissions yourself.


Computer  Plugin Cache

PLGX plugins are compiled and stored in a plugin cache directory on the user's system. This cache highly improves the startup performance of KeePass. Old files are normally deleted from the cache automatically (this can be disabled in the plugins dialog).

By default, the plugin cache is located in the user's application data directory. However, this can be overridden using the Application/PluginCachePath setting in the configuration file (this setting supports placeholders and environment variables). So, if you're for example using KeePass on a portable device and don't want the cache to be on the system, you could set the path to {APPDIR}\PluginCache.

Warning Do not relocate the plugin cache into the 'Plugins' folder of the KeePass application directory, because this can result in a severe performance degradation.

Docs/Chm/help/v2/guioptions.html0000664000000000000000000000426413225117272015532 0ustar rootroot GUI Options - KeePass
System

GUI Options


Explains various Graphical User Interface (GUI) options.

Info  Dialog Banner Styles

KeePass supports various different dialog banner styles. These styles are independent from the operating system and can freely be used on all systems.

WinXP Login:
WinXP Login Style

WinVista Black:
WinVista Style

KeePass Win32:
Old KeePass Win32 Style

Blue Carbon:
Blue Carbon Style

Docs/Chm/help/v2/entry.html0000664000000000000000000001110613225117272014464 0ustar rootroot Entry Dialog - KeePass
VCard Document

Entry Dialog


Explains options in the entry dialog.

In this dialog you can edit properties of new and existing entries.


Info  General

On this tab page you can specify the main information about the account. Apart from filling in standard information (user name, password, etc.), you can also assign an Expiry Time. When this date is reached, the entry is automatically marked as expired (using a red X icon in the main window and showing the entry information using a striked-out font). The entry is not deleted when it expires.

By default, KeePass generates a secure, random password for new entries. You can freely replace this generated password with an own one or invoke the password generator again (using the button on the right of the 'Repeat Password' field) to generate a password having different properties. For details (including information how to disable automatically generated passwords), see Password Generator.

A standard user name for new entries can be specified in the database settings dialog.


Info  Advanced

On this tab page you can assign custom strings and file attachments to the entry.

Custom Strings:
Each entry can have an arbitrary amount of custom strings. These strings can hold any information of your choice (for example additional e-mail addresses, passwords, more URLs, etc.). The strings will be stored encrypted in the database (like all other database content).

To use the value of a custom field, you can right-click on the entry and select 'Copy Custom String', which is much easier than highlighting the data in the entry view and copying.

File Attachments / Binaries:
You can attach files to entries. The files will be imported into the KeePass database and associated with the entry. When importing files, KeePass does not delete the original source file! You need to delete them yourself, if you wish. File attachments are stored encrypted in the database (like all other database content).


Info  Auto-Type

On this page you can configure the auto-type behaviour for this entry. For more information, see the Auto-Type help page.


Reload Document  History

Each entry has its own history. Each time you change an entry, KeePass automatically creates a backup copy of the current, non-modified entry before saving the new values. These backup copies are listed on the History tab page. You can delete backup copies if you are sure that you won't need them anymore, or you can restore any of the backup copies.

Docs/Chm/help/v2/index.html0000664000000000000000000000103313225117272014430 0ustar rootroot Redirection - KeePass Redirecting to KeePass Help Center...
Docs/Chm/help/v2/setup.html0000664000000000000000000004730113225117272014471 0ustar rootroot Setup - KeePass
System

Installation / Portability


KeePass 2.x installation, uninstallation, portability and updates.

Setup  General information

When downloading KeePass, you have the choice between 3 different packages:

  • KeePass-2.xx-Setup.exe: An installer program for Windows.
  • KeePass-2.xx.zip: A KeePass ZIP package (portable version).
  • KeePass-2.xx-Source.zip: The source code.

The installer and the portable version are described in detail below.

The source code package contains everything you need to compile KeePass. It includes the C#/C++ source code and header files, resource files, sources for building the installer, etc.

Updating KeePass:
When a new KeePass version has been released, you can update your existing KeePass installation, without losing any configuration settings. The steps are depending on which package you are using (installer or portable), see below.

Translations should also be updated when you install a new KeePass version. You can find the latest translation files here: KeePass Translations.


Setup  Installer program (KeePass-2.xx-Setup.exe file)

The KeePass development team provides an installer, which copies KeePass to your hard disk, creates shortcuts in the start menu and associates KDBX files with KeePass, if desired.

Additionally, KeePass is automatically configured to store its settings in the application data directory of the current user. This way multiple users can use one KeePass installation without overwriting each other's settings (each user has his own configuration file). The setup program must run with administrative rights, however KeePass runs fine without administrative rights once it is installed.

Installation:
To install KeePass, run the KeePass-2.xx-Setup.exe file and follow the wizard.

Updating:
Run the KeePass-2.xx-Setup.exe file. You do not need to uninstall the old version first. Your configuration options will not be lost.

Uninstallation:
In order to uninstall KeePass, run the uninstallation program, which is accessible by a shortcut in the start menu folder of KeePass, or in the program section of the system control panel. If you also want to remove your configuration settings, you need to delete the configuration file in the application data directory of your user profile, see Configuration.

Silent Installation:
The KeePass installer KeePass-2.xx-Setup.exe supports command line switches for silent installation, i.e. the program gets installed without asking the user for target directory or association options. The default settings of the installer are used.

The /SILENT command line switch performs a silent installation and shows a status dialog during the setup process. No questions will be asked though.

The /VERYSILENT command line switch performs a silent installation and does not show a status dialog during the setup process.

Destination Path:
The installer allows to choose the destination path to which KeePass is installed. However, when the installer detects an existing KeePass installation, it assumes that the user wants to perform an upgrade and thus doesn't display the destination path selection page; the old version will be overwritten by the new version. If you want to move an existing KeePass installation to a different path, first uninstall the old version; the installer of the new version will then display the destination path selection page again.

Options/Components:
The installation options/components are explained in detail here: What do the 2.x installation options/components mean in detail?.


Setup  Portable version (KeePass-2.xx.zip file)

The portable version can be carried around on portable devices (like USB sticks) and runs on any computer directly from the device, without any installation. It doesn't store anything on your system (in contrast to the setup package, see above). KeePass doesn't create any new registry keys and it doesn't create any configuration files in your Windows or application data directory of your user profile.

Make sure that KeePass has write access to its application directory. Otherwise, if it doesn't have, it'll attempt to store the configuration options (nothing security-relevant though) into the application data directory of the currently logged on user. For more about that, see this page: Configuration.

Installation:
KeePass does not need to be installed. Just download the ZIP package, unpack it with your favorite ZIP program and KeePass is ready to be used. Copy it to a location of your choice (for example onto your USB stick); no additional configuration or installation is needed.

Updating:
Download the latest portable package of KeePass, unpack it and copy all new files over the old ones. Your configuration settings will not be lost (the settings are stored in the KeePass.config.xml file, which won't be overwritten, because KeePass ZIP packages don't include a KeePass.config.xml file).

Uninstallation:
Simply delete the KeePass folder. This will leave no trace of KeePass on your system.


Setup  Running KeePass under Mono (Linux, Mac OS X, BSD, ...)

In addition to Windows, KeePass 2.x runs under Mono, i.e. Linux, Mac OS X, BSD, etc.

Links to all supported packages can be found on the Downloads page.

  • Debian/Ubuntu Linux:
    Install the keepass2 / KeePass 2.x for Debian/Ubuntu Linux package (e.g. using APT). A link to a page with more information about this package can be found on the downloads page.

  • Fedora Linux:
    Install the keepass package (from the Fedora repository; link on the downloads page).

  • OpenSUSE Linux:
    Install the keepass package (from the OpenSUSE Mono repository; link on the downloads page).

  • Gentoo Linux:
    Install the keepass package (from the Gentoo Linux repository; link on the downloads page).

  • Arch Linux:
    Install the keepass package (from the Arch Linux repository; link on the downloads page).

  • Mac OS X:
    Install the KeePass 2.x for Mac OS X package (link on the downloads page).

  • FreeBSD:
    Install the keepass package (from the FreeBSD ports tree or binary pkg repository; link on the downloads page).

  • Other Unix-like systems:
    In order to run KeePass, follow these steps:
    1. Install Mono ≥ 2.6 (older versions will not work and are not supported). Depending on your platform, the packages to install are called mono-stable, MonoFramework, mono-devel or mono-2.0-devel; see the Mono project page, if you are unsure which packages to install.
    2. On some platforms, the Windows Forms implementation (System.Windows.Forms) is offered as a separate package. KeePass requires this package; so if you see one, install it, too.
    3. On some platforms, the Runtime namespace (System.Runtime) is offered as a separate package. KeePass requires this package; so if you see one, install it, too.
    4. If you want to use auto-type on Linux / Mac OS X / BSD / etc., you additionally need the xdotool package.
    5. Download the portable version of KeePass (file KeePass-2.xx.zip) and unpack it in a location of your choice.
    6. When being in the KeePass directory, run the command line "mono KeePass.exe". Alternatively, right-click onto the KeePass.exe file, choose "Open with Other Application" and type in mono as custom command.

    For the last step you might want to create a shortcut or shell script file with this command line (use an absolute path to KeePass.exe, if the shortcut / shell script file is in a different location).

    Clipboard:
    On some systems, Mono's clipboard routines don't work properly. In this case, install the xsel and xdotool packages. If these are installed, KeePass uses them for clipboard operations.

    Global Auto-Type:
    In order to use global auto-type, you need to create an appropriate system-wide hot key. This only needs to be done manually once. KeePass performs global auto-type when it's invoked with the --auto-type command line option.

    Some examples how to create a system-wide hot key for global auto-type, for different operating systems:

    • KDE. On Linux systems with KDE, the hot key can be created in ComputerSystem SettingsShortcuts and Gestures: in this dialog, go EditNewGlobal ShortcutCommand/URL, specify the shortcut on the Trigger tab and enter
      mono /YourPathToKeePass/KeePass.exe --auto-type
      into the Command/URL field on the Action tab.
    • Ubuntu Linux ≥ 11.04 (Unity/GNOME). Open the dialog Keyboard Shortcuts in the system preferences, click the Add button, enter KeePass Auto-Type as name and
      mono /YourPathToKeePass/KeePass.exe --auto-type
      as command, then click [Apply]. Click on Disabled of the newly created item (such that the text 'New shortcut...' appears), press Ctrl+Alt+A, and close the dialog.
    • Ubuntu Linux ≤ 10.10 (GNOME).
      1. Press Alt-F2, enter gconf-editor and click [OK].
      2. Navigate to appsmetacitykeybinding_commands.
      3. Double-click one of the command_i items, enter
        mono /YourPathToKeePass/KeePass.exe --auto-type
        and click [OK].
      4. Click the global_keybindings node on the left.
      5. Double-click the appropriate run_command_i item (for example, when you've used command_5 in the previous steps, double-click run_command_5 now) and specify the hot key of your choice. For example, to use Ctrl+Alt+A as hot key, you'd enter <Control><Alt>a.

    Important: for global auto-type, the version of the xdotool package must be 2.20100818.3004 or higher! If your distribution only offers an older version, you can download and install the latest version of the package manually, see the xdotool website.

    Plugins:
    On some Linux systems, the mono-complete package may be required for plugins to work properly.


Setup  Running KeePass under Wine (Linux, Mac OS X, BSD, ...)

Although you can run KeePass 2.x more or less natively on Unix-like systems using Mono (see above), the user interface doesn't always look pretty. Some users therefore prefer running KeePass 2.x under Wine, which works fine, too.

In order to run KeePass 2.x under Wine, follow these steps:

  1. Make sure that Wine is installed. Typically the package to install is called wine.
  2. Make sure that .NET Framework 4.5 or higher is installed in Wine, see WineHQ AppDB: .NET Framework.
    For installing .NET Framework 4.5, winetricks can be used, see WineHQ AppDB: .NET Framework 4.5.
  3. Download the latest portable package of KeePass 2.x (ZIP file) and unpack it into some directory of your choice.
  4. Run wine KeePass.exe.

Theme. By default, Wine uses the classic Windows theme. If you prefer some other theme, you can install it in 'Applications' → 'Wine' → 'Configure Wine' → tab 'Desktop Integration'. Links to themes can for instance be found on Wikipedia: Windows XP visual styles.


Setup  Migrating from KeePass 1.x to 2.x

In order to migrate from KeePass 1.x to 2.x, follow these steps:

  1. Install KeePass 2.x.
    If you're using the installer, make sure that the component 'Native Support Library (KeePass 1.x)' is being installed (by default this component is enabled).
  2. Run KeePass 2.x and create a new KDBX database file (via 'File' → 'New').
  3. Import your old KDB database file into your new KDBX database file (via 'File' → 'Import', file format 'KeePass KDB (1.x)').

If everything works fine, you can delete your old KeePass 1.x installation. The old KDB database file also isn't required anymore, but you may want to keep it as a backup.

Docs/Chm/help/v2/ioconnect.html0000664000000000000000000000654013225117272015312 0ustar rootroot Loading/Saving From/To URL - KeePass
Browsing

Loading/Saving From/To URL


KeePass can load/save databases from/to URLs.

In this dialog you can specify an URL, from/to which data is read/written.

By default, KeePass supports FTP, HTTP and WebDAV, but additional protocols might be available on your system (if specific providers are installed).

The IOProtocolExt plugin adds support for SCP, SFTP and FTPS.

For an online storage (like e.g. Amazon's S3, DigitalBucket, ...), you need an online storage provider plugin (e.g. KeeAnywhere, KeeCloud or KeePassSync).


Server  Example: Using FTP Server

In order to load/save your database from/to an FTP server, you first need to upload the database file to the server manually. This only needs to be done once.

Then start KeePass and go 'File''Open''Open URL...'. Enter the full database path on the server and don't forget the ftp:// prefix! This prefix is required, otherwise KeePass doesn't know which protocol to use. Enter the FTP credentials and click [OK]. KeePass will download the file and open it.

KeePass can remember the FTP credentials, if you wish. You can choose between remembering everything (user name and password), partially (user name only) and not remembering the credentials at all.

When you press the 'Save' button, KeePass will automatically upload the new database file to the server (same location as before, i.e. overwriting the previous one).

Docs/Chm/help/v2/triggers.html0000664000000000000000000004114313225117272015155 0ustar rootroot Triggers - KeePass
Triggers

Triggers


Automate workflows using the trigger system.

Triggers  Trigger System Introduction

KeePass features a powerful event-condition-action trigger system. With this system, workflows can be automated. For example, you could define a trigger that automatically uploads your database to a backup server after saving the file locally.

A trigger starts to run when any of the specified events matches. When this happens, the conditions are checked. If all conditions are fulfilled, the actions of the trigger are performed. Actions are performed consecutively; if one action fails, typically the execution of the event is aborted (i.e. all following actions aren't performed).

A trigger must be both enabled and on in order to get executed. The enabled state is set by the user; a disabled trigger has no function. The on state is dependent on the state of the program. By enabling the 'Initially On' option, a trigger is on by default. If you enable the option 'Turn off after executing actions', the trigger will be off after running once. There are actions to turn triggers on and off, i.e. triggers can turn themselves and other triggers on and off, which allows to define a complex state-dependent system of triggers.

Most strings in the trigger system are Spr-compiled, i.e. placeholders, environment variables, etc. can be used.

IO Connection Properties. Most trigger actions having a file path/URL parameter only allow specifying the path/URL and possibly credentials (user name and password) for accessing the file; advanced connection properties (like timeout, user agent, passive mode, etc.) cannot be specified here. If advanced connection properties are required, open the file once (using 'File' → 'Open') with the desired connection properties. This will create an item in the 'Open Recent' file list (which remembers connection properties). When a trigger action is executed, KeePass loads the connection properties from the corresponding item (same path/URL) in the 'Open Recent' file list.


Triggers  Events

  • Application initialized:
    This event occurs when KeePass has finished initializing, but didn't perform any main window automations (like opening a default database) yet.
    • Parameters: None.

  • Application started and ready:
    This event occurs when KeePass has started up, performed main window automations (like opening a default database) and is ready for user actions.
    • Parameters: None.

  • Application exit:
    This event occurs when KeePass is about to exit. Databases have been closed already, but resources (like fonts, ...) are still valid.
    • Parameters: None.

  • Opened database file:
    This event occurs right after a database file has been opened successfully.
    • File/URL: An optional event filter. If a filter is specified (i.e. something is entered in 'File/URL - Filter'), the trigger is only evaluated, if the filter matches the actual database file path. For example, if you enter F:\ as filter string and specify 'Starts with' as comparison method, the trigger will only be evaluated, if the database (that has just been opened) path starts with F:\.

  • Saving database file:
    This event occurs right before a database file is saved.
    • Parameters: See 'Opened database file' event.

  • Saved database file:
    This event occurs right after a database file has been saved successfully.
    • Parameters: See 'Opened database file' event.

  • Closing database file (before saving):
    This event occurs right before a database file is closed. It occurs before KeePass saves the database automatically or asks the user whether to save unsaved changes.
    • Parameters: See 'Opened database file' event.

  • Closing database file (after saving):
    This event occurs right before a database file is closed. The database file already was saved automatically or unsaved changes were saved/discarded depending on the user's choice.
    • Parameters: See 'Opened database file' event.

  • Copied entry data to clipboard:
    This event occurs when entry data (user name, password, ...) is copied to the Windows clipboard.
    • Value: An optional value (copied data) filter.

  • User interface state updated:
    This event occurs when KeePass has finished updating the state of the user interface (menus, toolbar, ...). The user interface state is updated after most user actions, like adding / editing / deleting entries and groups, etc.
    • Parameters: None.

  • Custom toolbar button clicked:
    This event occurs when the user clicks a custom toolbar button. Custom toolbar buttons can be added using the 'Add custom toolbar button' trigger action.
    • ID: ID of the toolbar button that must have been clicked (see action).

Triggers  Conditions

  • Environment variable:
    • Name: Name of the environment variable to check. The name must not be enclosed in percent (%) characters.
    • Value: The value that the specified environment variable must have for the condition to be true.

  • String:
    • String: A string (KeePass Spr-compiles this, i.e. you can e.g. use placeholders).
    • Value: The value that the specified, evaluated string must have for the condition to be true.

  • File exists:
    • File: The file that must exist in order for the condition to be true.

  • Remote host is reachable (ping):
    • Host: Host to send the ping to.

  • Database has unsaved changes:
    Evaluates to true, if the specified database has unsaved changes.
    • Database: The database to check for unsaved changes.

Triggers  Actions

  • Execute command line / URL:
    The file/URL and arguments are parsed by the Spr engine before they are sent to the shell, i.e. generic and database-dependent placeholders can be used. If you want to use built-in shell commands, like COPY, please see: Executing Built-In Shell Commands.
    • File/URL: The string to be executed by the shell.
    • Arguments: Optional. If 'File/URL' points to an executable file, this string is sent to the executable as command line argument(s).
    • Wait for exit: If this option is checked, KeePass waits indefinitely for the started process to exit.
    • Window style: Specifies how the main window of the executed file/URL should be displayed. Not all applications respect this setting.
    • Verb: Specifies the action to be performed. An empty string means to use the default verb. Some applications support additional verbs (e.g. "Print" to print the specified document). When using the verb "RunAs", the application is executed with administrative rights (this may require a confirmation via the UAC dialog).

  • Change trigger on/off state:
    • Trigger name: Name of the target trigger whose on/off state should be changed. If this field is left empty, the target trigger is the current one.
    • New state: Specifies the new state of the target trigger.

  • Open database file:
    Open a KDBX database file (in a new tab). If the given database file is opened already, KeePass brings it to the foreground.
    • File/URL: Path of the database file to open. If it is an URL, the protocol (prefix) must be specified.
    • IO Connection - User Name / Password: Optional credentials that are used for connecting to the target file system (for example FTP account user name / password). These credentials are not used to decrypt the database.
    • Password / Key file / User account: Optional credentials that are used to decrypt the database file.

  • Save active database:
    Save the currently active database. This action always saves the database, even if there are no unsaved changes. To only save if there are unsaved changes, use the 'Active database has unsaved changes' trigger condition.
    • Parameters: None.

  • Synchronize active database with a file/URL:
    Synchronize the currently opened and active database with a file.
    • File/URL: Path of the database file to synchronize with. If it is an URL, the protocol (prefix) must be specified.
    • IO Connection - User Name / Password: Optional credentials that are used for connecting to the target file system (for example FTP account user name / password). These credentials are not used to decrypt the database.

  • Import into active database:
    Import a file into the currently opened and active database.
    • File/URL: Path of the source file to import. If it is an URL, the protocol (prefix) must be specified.
    • File format: Specifies the import format (see the import dialog for possible values).
    • Method: Specifies the behavior for groups/entries that exist in both the currently active database and the import file.
    • Password / Key file / User account: Optional credentials that are used to decrypt the import file, if required. If no credentials are specified, but the import file is encrypted, KeePass shows a key prompt dialog.

  • Export active database:
    Export the currently opened and active database to a file.
    • File/URL: Path of the target file to export to. If it is an URL, the protocol (prefix) must be specified.
    • File format: Specifies the export format (see the export dialog for possible values).
    • Filter - Group: Specifies the path of the group to export (optional; an empty string means the whole database). The path must start with the character used as separator, and the name of the root group of the database must not be specified. For example, to export a group 'B' that is a subgroup of the group 'A', specify /A/B as group path.
    • Filter - Tag: Export only the entries that have the specified tag (optional parameter).

  • Close active database:
    Close the currently active database.
    • Parameters: None.

  • Activate database (select tab):
    • File/URL: Path of the database to activate. This may be a substring of the actual database path. For example, specifying MyDatabase would match a database C:\Documents\KeePass\MyDatabase.kdbx.
    • Filter: Specifies the databases that are being considered. If 'Triggering' is selected and the 'File/URL' field is empty, the database that triggered the event is activated.

  • Wait:
    Wait for the specified amount of time.
    • Time span: Number of milliseconds to wait.

  • Show message box:
    Displays a message box.
    • Main instruction: First line of the message text (which is possibly displayed using a stronger font).
    • Text: Message text.
    • Icon: The icon that is displayed next to the message text.
    • Buttons: Specifies the available buttons.
    • Default button: The button that initially has the focus.
    • Action - Condition: Specifies the condition that must be fulfilled for the following action to be performed. For example, if 'Button OK/Yes' is selected, the action is only performed if the user clicks the 'OK' or 'Yes' button of the message box.
    • Action: The action to perform after showing the message box.
    • Action - Parameters: Parameters for the specified action. For example, if executing a command line / URL is specified as action, this field must contain the command line / URL.

  • Perform global auto-type:
    Execute global auto-type (like pressing the global auto-type hot key).
    • Parameters: None.

  • Perform auto-type with selected entry:
    Executes auto-type with the currently selected entry as context.
    • Sequence: The keystroke sequence to send. If this field is empty, the default sequence is used.

  • Show entries by tag:
    Search all entries having the specified tag and show them in the entry list of the main window.
    • Tag: Tag that the entries must have.

  • Add custom toolbar button:
    Add a custom button to the toolbar in the main window.
    • ID: ID of the toolbar button (see the event handler).
    • Name: Text that is shown on the toolbar button.
    • Description: Text that is shown in the tooltip of the button.

  • Remove custom toolbar button:
    Remove a custom button from the toolbar in the main window.
    • ID: ID of the toolbar button (see the event handler).

Triggers  Examples

See the Trigger Examples page.

Docs/Chm/help/v2/license.html0000664000000000000000000005171613225117272014760 0ustar rootroot License - KeePass
Text

KeePass 2.x License


License terms of KeePass 2.x.

KeePass: Copyright © 2003-2018 Dominik Reichl.

The program is distributed under the terms of the GNU General Public License version 2 or later.

For acknowledgements and licenses of components/resources/etc., see the Acknowledgements page.



GNU GENERAL PUBLIC LICENSE

Version 2, June 1991

Copyright (C) 1989, 1991 Free Software Foundation, Inc.  
51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA

Everyone is permitted to copy and distribute verbatim copies
of this license document, but changing it is not allowed.

Preamble

The licenses for most software are designed to take away your freedom to share and change it. By contrast, the GNU General Public License is intended to guarantee your freedom to share and change free software--to make sure the software is free for all its users. This General Public License applies to most of the Free Software Foundation's software and to any other program whose authors commit to using it. (Some other Free Software Foundation software is covered by the GNU Lesser General Public License instead.) You can apply it to your programs, too.

When we speak of free software, we are referring to freedom, not price. Our General Public Licenses are designed to make sure that you have the freedom to distribute copies of free software (and charge for this service if you wish), that you receive source code or can get it if you want it, that you can change the software or use pieces of it in new free programs; and that you know you can do these things.

To protect your rights, we need to make restrictions that forbid anyone to deny you these rights or to ask you to surrender the rights. These restrictions translate to certain responsibilities for you if you distribute copies of the software, or if you modify it.

For example, if you distribute copies of such a program, whether gratis or for a fee, you must give the recipients all the rights that you have. You must make sure that they, too, receive or can get the source code. And you must show them these terms so they know their rights.

We protect your rights with two steps: (1) copyright the software, and (2) offer you this license which gives you legal permission to copy, distribute and/or modify the software.

Also, for each author's protection and ours, we want to make certain that everyone understands that there is no warranty for this free software. If the software is modified by someone else and passed on, we want its recipients to know that what they have is not the original, so that any problems introduced by others will not reflect on the original authors' reputations.

Finally, any free program is threatened constantly by software patents. We wish to avoid the danger that redistributors of a free program will individually obtain patent licenses, in effect making the program proprietary. To prevent this, we have made it clear that any patent must be licensed for everyone's free use or not licensed at all.

The precise terms and conditions for copying, distribution and modification follow.

TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION

0. This License applies to any program or other work which contains a notice placed by the copyright holder saying it may be distributed under the terms of this General Public License. The "Program", below, refers to any such program or work, and a "work based on the Program" means either the Program or any derivative work under copyright law: that is to say, a work containing the Program or a portion of it, either verbatim or with modifications and/or translated into another language. (Hereinafter, translation is included without limitation in the term "modification".) Each licensee is addressed as "you".

Activities other than copying, distribution and modification are not covered by this License; they are outside its scope. The act of running the Program is not restricted, and the output from the Program is covered only if its contents constitute a work based on the Program (independent of having been made by running the Program). Whether that is true depends on what the Program does.

1. You may copy and distribute verbatim copies of the Program's source code as you receive it, in any medium, provided that you conspicuously and appropriately publish on each copy an appropriate copyright notice and disclaimer of warranty; keep intact all the notices that refer to this License and to the absence of any warranty; and give any other recipients of the Program a copy of this License along with the Program.

You may charge a fee for the physical act of transferring a copy, and you may at your option offer warranty protection in exchange for a fee.

2. You may modify your copy or copies of the Program or any portion of it, thus forming a work based on the Program, and copy and distribute such modifications or work under the terms of Section 1 above, provided that you also meet all of these conditions:

a) You must cause the modified files to carry prominent notices stating that you changed the files and the date of any change.
b) You must cause any work that you distribute or publish, that in whole or in part contains or is derived from the Program or any part thereof, to be licensed as a whole at no charge to all third parties under the terms of this License.
c) If the modified program normally reads commands interactively when run, you must cause it, when started running for such interactive use in the most ordinary way, to print or display an announcement including an appropriate copyright notice and a notice that there is no warranty (or else, saying that you provide a warranty) and that users may redistribute the program under these conditions, and telling the user how to view a copy of this License. (Exception: if the Program itself is interactive but does not normally print such an announcement, your work based on the Program is not required to print an announcement.)

These requirements apply to the modified work as a whole. If identifiable sections of that work are not derived from the Program, and can be reasonably considered independent and separate works in themselves, then this License, and its terms, do not apply to those sections when you distribute them as separate works. But when you distribute the same sections as part of a whole which is a work based on the Program, the distribution of the whole must be on the terms of this License, whose permissions for other licensees extend to the entire whole, and thus to each and every part regardless of who wrote it.

Thus, it is not the intent of this section to claim rights or contest your rights to work written entirely by you; rather, the intent is to exercise the right to control the distribution of derivative or collective works based on the Program.

In addition, mere aggregation of another work not based on the Program with the Program (or with a work based on the Program) on a volume of a storage or distribution medium does not bring the other work under the scope of this License.

3. You may copy and distribute the Program (or a work based on it, under Section 2) in object code or executable form under the terms of Sections 1 and 2 above provided that you also do one of the following:

a) Accompany it with the complete corresponding machine-readable source code, which must be distributed under the terms of Sections 1 and 2 above on a medium customarily used for software interchange; or,
b) Accompany it with a written offer, valid for at least three years, to give any third party, for a charge no more than your cost of physically performing source distribution, a complete machine-readable copy of the corresponding source code, to be distributed under the terms of Sections 1 and 2 above on a medium customarily used for software interchange; or,
c) Accompany it with the information you received as to the offer to distribute corresponding source code. (This alternative is allowed only for noncommercial distribution and only if you received the program in object code or executable form with such an offer, in accord with Subsection b above.)

The source code for a work means the preferred form of the work for making modifications to it. For an executable work, complete source code means all the source code for all modules it contains, plus any associated interface definition files, plus the scripts used to control compilation and installation of the executable. However, as a special exception, the source code distributed need not include anything that is normally distributed (in either source or binary form) with the major components (compiler, kernel, and so on) of the operating system on which the executable runs, unless that component itself accompanies the executable.

If distribution of executable or object code is made by offering access to copy from a designated place, then offering equivalent access to copy the source code from the same place counts as distribution of the source code, even though third parties are not compelled to copy the source along with the object code.

4. You may not copy, modify, sublicense, or distribute the Program except as expressly provided under this License. Any attempt otherwise to copy, modify, sublicense or distribute the Program is void, and will automatically terminate your rights under this License. However, parties who have received copies, or rights, from you under this License will not have their licenses terminated so long as such parties remain in full compliance.

5. You are not required to accept this License, since you have not signed it. However, nothing else grants you permission to modify or distribute the Program or its derivative works. These actions are prohibited by law if you do not accept this License. Therefore, by modifying or distributing the Program (or any work based on the Program), you indicate your acceptance of this License to do so, and all its terms and conditions for copying, distributing or modifying the Program or works based on it.

6. Each time you redistribute the Program (or any work based on the Program), the recipient automatically receives a license from the original licensor to copy, distribute or modify the Program subject to these terms and conditions. You may not impose any further restrictions on the recipients' exercise of the rights granted herein. You are not responsible for enforcing compliance by third parties to this License.

7. If, as a consequence of a court judgment or allegation of patent infringement or for any other reason (not limited to patent issues), conditions are imposed on you (whether by court order, agreement or otherwise) that contradict the conditions of this License, they do not excuse you from the conditions of this License. If you cannot distribute so as to satisfy simultaneously your obligations under this License and any other pertinent obligations, then as a consequence you may not distribute the Program at all. For example, if a patent license would not permit royalty-free redistribution of the Program by all those who receive copies directly or indirectly through you, then the only way you could satisfy both it and this License would be to refrain entirely from distribution of the Program.

If any portion of this section is held invalid or unenforceable under any particular circumstance, the balance of the section is intended to apply and the section as a whole is intended to apply in other circumstances.

It is not the purpose of this section to induce you to infringe any patents or other property right claims or to contest validity of any such claims; this section has the sole purpose of protecting the integrity of the free software distribution system, which is implemented by public license practices. Many people have made generous contributions to the wide range of software distributed through that system in reliance on consistent application of that system; it is up to the author/donor to decide if he or she is willing to distribute software through any other system and a licensee cannot impose that choice.

This section is intended to make thoroughly clear what is believed to be a consequence of the rest of this License.

8. If the distribution and/or use of the Program is restricted in certain countries either by patents or by copyrighted interfaces, the original copyright holder who places the Program under this License may add an explicit geographical distribution limitation excluding those countries, so that distribution is permitted only in or among countries not thus excluded. In such case, this License incorporates the limitation as if written in the body of this License.

9. The Free Software Foundation may publish revised and/or new versions of the General Public License from time to time. Such new versions will be similar in spirit to the present version, but may differ in detail to address new problems or concerns.

Each version is given a distinguishing version number. If the Program specifies a version number of this License which applies to it and "any later version", you have the option of following the terms and conditions either of that version or of any later version published by the Free Software Foundation. If the Program does not specify a version number of this License, you may choose any version ever published by the Free Software Foundation.

10. If you wish to incorporate parts of the Program into other free programs whose distribution conditions are different, write to the author to ask for permission. For software which is copyrighted by the Free Software Foundation, write to the Free Software Foundation; we sometimes make exceptions for this. Our decision will be guided by the two goals of preserving the free status of all derivatives of our free software and of promoting the sharing and reuse of software generally.

NO WARRANTY

11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION.

12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.

END OF TERMS AND CONDITIONS

How to Apply These Terms to Your New Programs

If you develop a new program, and you want it to be of the greatest possible use to the public, the best way to achieve this is to make it free software which everyone can redistribute and change under these terms.

To do so, attach the following notices to the program. It is safest to attach them to the start of each source file to most effectively convey the exclusion of warranty; and each file should have at least the "copyright" line and a pointer to where the full notice is found.

one line to give the program's name and an idea of what it does.
Copyright (C) yyyy  name of author

This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License
as published by the Free Software Foundation; either version 2
of the License, or (at your option) any later version.

This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
GNU General Public License for more details.

You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.

Also add information on how to contact you by electronic and paper mail.

If the program is interactive, make it output a short notice like this when it starts in an interactive mode:

Gnomovision version 69, Copyright (C) year name of author
Gnomovision comes with ABSOLUTELY NO WARRANTY; for details
type `show w'.  This is free software, and you are welcome
to redistribute it under certain conditions; type `show c' 
for details.

The hypothetical commands `show w' and `show c' should show the appropriate parts of the General Public License. Of course, the commands you use may be called something other than `show w' and `show c'; they could even be mouse-clicks or menu items--whatever suits your program.

You should also get your employer (if you work as a programmer) or your school, if any, to sign a "copyright disclaimer" for the program, if necessary. Here is a sample; alter the names:

Yoyodyne, Inc., hereby disclaims all copyright
interest in the program `Gnomovision'
(which makes passes at compilers) written 
by James Hacker.

signature of Ty Coon, 1 April 1989
Ty Coon, President of Vice

This General Public License does not permit incorporating your program into proprietary programs. If your program is a subroutine library, you may consider it more useful to permit linking proprietary applications with the library. If this is what you want to do, use the GNU Lesser General Public License instead of this License.


End GNU General Public License

Docs/Chm/help/v2/autotype_obfuscation.html0000664000000000000000000002551713225117272017604 0ustar rootroot Two-Channel Auto-Type Obfuscation - KeePass
Auto-Type Icon

Two-Channel Auto-Type Obfuscation


Description of the Two-Channel Auto-Type Obfuscation feature in KeePass 2.x.

Text  Introduction: What is Two-Channel Auto-Type Obfuscation?

The Auto-Type feature of KeePass is very powerful: it sends simulated keypresses to other applications. This works with all Windows applications and for the target applications it's not possible to distinguish between real keypresses and the ones simulated by Auto-Type. This at the same time is the main disadvantage of Auto-Type, because keyloggers can eavesdrop the simulated keys. That's where Two-Channel Auto-Type Obfuscation (TCATO) comes into play.

TCATO makes standard keyloggers useless. It uses the Windows clipboard to transfer parts of the auto-typed text into the target application. Keyloggers can see the Ctrl+V presses, but do not log the actual contents pasted from the clipboard.

Clipboard spies don't work either, because only parts of the sensitive information is transferred on this way.

Anyway, it's not perfectly secure (and unfortunately cannot be made by theory). None of the currently available keyloggers or clipboard spies can eavesdrop an obfuscated auto-type process, but it is theoretically possible to write a dedicated spy application that specializes on logging obfuscated auto-type.


Text  When can Two-Channel Auto-Type Obfuscation be used?

TCATO cannot be used with all windows. The target window(s) must support clipboard operations and navigation within edit controls using arrow keys. Additionally, the target user interface must not contain automation features like jumping focus when maximum length of a text box is reached (as seen in registration number dialogs for example).

Rules of thumb:

  • Can be used in:
    • Browsers.
    • Windows programs with standard text boxes.
  • Can not be used in:
    • Console-based applications (interactive terminals, ...).
    • Games.

Because it doesn't work with all windows, it's an opt-in feature for each entry. You have to enable it explicitly on the 'Auto-Type' tab page in the 'Edit Entry' dialog.


Text  How to enable / configure Two-Channel Auto-Type Obfuscation?

All you need to do is to tick the checkbox "Two-channel auto-type obfuscation" of an entry ('Auto-Type' tab of the entry editing window); KeePass will do the rest.


Text  Technical Overview

Instead of simply sending simulated keypresses to the target application (as normal auto-type does), obfuscated auto-type does the following:

  • Backup the current clipboard contents.
  • Intelligently split the text into parts.
  • For each part: check if the clipboard can be used.
    • If yes: Split it into two subparts (character-wise, like two flat intertwining combs). Copy/paste the first part, merge the rest by sending keypresses.
    • If no: Send it normally using simulated keypresses.
  • Restore previous clipboard contents.

These steps are described in detail below.


Text  Intelligently Splitting the Text

The text to be sent must first be split intelligently. Not all parts of the string can be sent using the clipboard: special key codes and key modifiers must be passed unchanged to the SendInput function. For an example, have a look at the following string:

mymail@myprovider.com{TAB}MyTopSecretPassword{TAB} {TAB}{ENTER}

This is an example of a typical string sent by KeePass to another application. First it types the user's email address, then a tab, then the password, a tab, toggles a checkbox, another tab and finally presses the enter key. This sequence can be split into the following parts:

mymail@myprovider.com
{TAB}
MyTopSecretPassword
{TAB}
' ' (space)
{TAB}
{ENTER}

For each line, it is checked if the clipboard can be used. If the line contains a '{', '}', '(', ')', '+', '^', '%' or whitespace (space), it can only be sent by the SendInput function directly. '+' for example presses the Shift key, it should not be copy/pasted as '+' character. Spaces can't be copy/pasted either, because they are usually used to toggle checkboxes.

In the example above, "mymail@myprovider.com" and "MyTopSecretPassword" can be sent using the clipboard.


Text  Splitting the Secrets

Let's transfer "mymail@myprovider.com" to the target application using TCATO.

First, the secret string "mymail@myprovider.com" is randomly split character-wise into two parts like two flat intertwining combs:

 y  il m   o  d  .c
m ma  @ ypr vi er  om

The first string "yilmod.c" is now copied to the clipboard. The string to be sent by the SendInput function is now assembled as follows:

  • Begin with pasting from the clipboard: ^v.
  • Press the left arrow key n times, with n = length of the clipboard string.
  • Send the remaining characters and press the right arrow key to skip the ones that were already pasted from the clipboard.

In our example above, the key sequence would be assembled to:

^v{LEFT 8}m{RIGHT}ma{RIGHT}{RIGHT}@{RIGHT}ypr{RIGHT}vi{RIGHT}er{RIGHT}{RIGHT}om

This will first paste the clipboard contents, go to its start and fill in the remaining characters, building up the original string "mymail@myprovider.com".

The time in which the first string part remains in the clipboard is minimal. It is copied to the clipboard, pasted into the target application and immediately cleared. This process usually takes only a few milliseconds at maximum.

More about secret string splitting:
In the above example, the string "mymail@myprovider.com" was split and sent. If the string would be split differently each time, a malicious application could reassemble the string by capturing multiple auto-types and combining them. In order to prevent this, KeePass initializes the random number generator for splitting based on a hash of the string. This means that each string is split differently, but the partitions of a string are uniquely determined. So, by invoking auto-type multiple times, an attacker cannot reassemble the original string, because he always captures the same half part.

Docs/Chm/help/v2/xml_replace.html0000664000000000000000000004127013225117272015623 0ustar rootroot XML Replace - KeePass
People

XML Replace


About the XML replacement functionality.

Help  General Information

XML Replace is a powerful feature that modifies a database by manipulating its XML representation.

KeePass creates a KDBX XML DOM of the current database in memory, performs the operation specified by the user (e.g. remove nodes or replace text), tries to load the modified XML, and merges the current database with the modified database.

Warning This is a feature for experts. Use with caution!

XML Replace can be invoked via 'Tools' → 'Database Tools' → 'XML Replace'.

A few links that might be helpful for working with XPath and regular expressions:

KeePass protects history entries; XML Replace cannot be used to modify these. Furthermore, any changes to database properties (database name/description, etc.) may be ignored.


Help  Usage Examples


Replace text in all entry titles and notes
Select nodes: //Entry/String[Key='Title' or Key='Notes']/Value
Action:Replace data
Data:Inner text
Find what:TheTextToFind
Replace with:TheReplacement
Within all entry titles and notes, this replaces all occurences of TheTextToFind by TheReplacement.

Replace all HTTP URLs by HTTPS URLs
Select nodes: //Entry/String[Key='URL']/Value
Action:Replace data
Data:Inner text
Find what:^http:
Replace with:https:
Regular expressions:Activated
Within all entry URL fields, this replaces all HTTP URLs by HTTPS URLs.

Replace group icons
Select nodes: //Group/IconID
Action:Replace data
Data:Inner text
Find what:^48$
Replace with:36
Regular expressions:Activated
This assigns the ZIP package icon to all groups that currently have a closed folder as icon.

All icon IDs can be found in the icon picker dialog.

Delete entry strings by name
Select nodes: //Entry/String[Key='TheName']
Action:Remove nodes
Removes all entry strings named TheName.

Delete entry attachments by name extension
Select nodes: //Entry/Binary[substring(Key, string-length(Key) - 3) = '.jpg']
Action:Remove nodes
Removes all entry attachments that have a name ending in '.jpg'.

The '3' in the node selection XPath expression is the length of '.jpg' - 1. If you'd e.g. want to search for attachments that have a name ending in '.abcde', you'd need to replace the '3' by '5'.

Reset background colors
Select nodes: //Entry/BackgroundColor
Action:Remove nodes
Sets the background color of all entries to the default (transparent/alternating).

Disable auto-type for entries with empty fields
Select nodes: //Entry/String[(Key='UserName' or Key='Password') and Value='']/../AutoType/Enabled
Action:Replace data
Data:Inner text
Find what:True
Replace with:False
Disables auto-type for all entries that have an empty user name field or an empty password field.

Convert {DELAY= to upper-case
Select nodes: //DefaultSequence | //KeystrokeSequence
Action:Replace data
Data:Inner text
Find what:{DELAY=
Replace with:{DELAY=
Converts all {DELAY= codes within auto-type sequence overrides and associations to upper-case (by default the case sensitivity option is turned off, thus the 'Find what' text matches all cases).

In KeePass 2.x, placeholders are case-insensitive. However, this XML Replace operation may be useful as preparation for the following example (which matches {DELAY= in a case-sensitive way).

Prepend {DELAY=50} to all sequences without a {DELAY=
Select nodes: (//DefaultSequence | //KeystrokeSequence)[not(contains(., '{DELAY=')) and (. != '')]
Action:Replace data
Data:Inner text
Find what:^(.*)$
Replace with:{DELAY=50}$1
Regular expressions:Activated
Prepends a {DELAY=50} to all auto-type sequence overrides and associations that do not contain any {DELAY= already and are not empty.

Note that the node selection is case-sensitive (independent of the data case sensitivity option), thus you need to ensure that all {DELAY= codes are upper-case before performing this operation. This can e.g. be done using the XML Replace operation mentioned above.

Change {DELAY= values
Select nodes: //DefaultSequence | //KeystrokeSequence
Action:Replace data
Data:Inner text
Find what:\{DELAY=[\d\s]*\}
Replace with:{DELAY=50}
Regular expressions:Activated
Sets the values of all {DELAY= codes within auto-type sequence overrides and associations to 50.

Remove {DELAY=x} from all sequences
Select nodes: //DefaultSequence | //KeystrokeSequence
Action:Replace data
Data:Inner text
Find what:\{DELAY=[\d\s]*\}
Replace with:(Leave empty)
Regular expressions:Activated
Removes all {DELAY=x} codes from all auto-type sequences.

Reset default sequences that contain {DELAY=
Select nodes: //DefaultSequence[contains(., '{DELAY=')]
Action:Remove nodes
If a sequence has been specified in the field 'Override default sequence' (in the entry dialog) and it contains {DELAY=, the sequence is reset, i.e. the option 'Inherit default auto-type sequence from group' is activated.

Add an auto-type association to all entries
Select nodes: //Entry/AutoType
Action:Replace data
Data:Outer XML
Find what:</AutoType>\Z
Replace with:<Association><Window>* - Notepad</Window><KeystrokeSequence>{PASSWORD}</KeystrokeSequence></Association></AutoType>
Regular expressions:Activated
Adds an auto-type association to all entries: the window title '* - Notepad' is associated with the sequence '{PASSWORD}'.

Copy entry URLs into title fields
Select nodes: //Entry
Action:Replace data
Data:Inner XML
Find what:(?s)(<Key>Title</Key>\s*)(<Value>.*?</Value>|<Value\s*/>)(.*?<Key>URL</Key>\s*)(<Value>.*?</Value>|<Value\s*/>)
Replace with:$1$4$3$4
Case-sensitive:Activated
Regular expressions:Activated
Copies the entry URL into the title field of the entry (overwriting any existing data in the title field).

Copy entry titles into empty user name fields
Select nodes: //Entry/String[Key='UserName' and Value='']/..
Action:Replace data
Data:Inner XML
Find what:(?s)(<Key>Title</Key>\s*?<Value>)(.*?)(</Value>.+?<Key>UserName</Key>\s*?)<Value />
Replace with:$1$2$3<Value>$2</Value>
Case-sensitive:Activated
Regular expressions:Activated
Copies the entry title into the user name field of the entry, if this field is empty.

Ensure first line is not empty
Select nodes: //Entry/String/Value
Action:Replace data
Data:Inner text
Find what:(?s)^(\r?\n)
Replace with:--$1
Regular expressions:Activated
For all multi-line fields, this inserts '--' into the first line of the field value, if this line is empty and the value has at least two lines. For example,



Sample data

is replaced by

--

Sample data
Docs/Chm/help/v2/policy.html0000664000000000000000000001133213225117272014623 0ustar rootroot Application Policy - KeePass
Settings

Application Policy


Details about the application policy system within KeePass.

Users  Help for Users

Application policy is a KeePass feature that enables administrators to prevent you from accidently compromising the security system of your company.

Operations like exporting entries to non-encrypted files or printing for example can be prevented effectively using the application policy.

If you are using KeePass at home, you can ignore the application policy (everything allowed anyway) or reduce your rights using the policy yourself, in order to avoid accidental leakage of sensitive information.

In order to prevent changing the policy after it has been specified, it is recommended to use an enforced configuration file.


Administrator  Help for Administrators

KeePass can be installed on a network drive and a policy can be enforced (like not permitting users to print the entry list).

The application policy enforcement is based on the mechanism how KeePass stores configuration settings. You first need to understand this method before you can continue creating a policy: Configuration.

A policy-enforcing KeePass installation looks like the following: the KeePass application files are stored on the network drive and all users are starting KeePass from this drive (i.e. they only have links to the executable on the network drive). By using an enforced configuration file on the network drive (remember that this file overrides all others), a policy can be enforced.

In order to create such an installation, follow these steps:

  1. Copy KeePass to a shared network drive that supports file access rights (like NTFS).
  2. Create an enforced configuration file that enforces the application policy settings that you wish.
  3. Adjust the file access rights: allow users only to read and execute all KeePass files, no write access.

Locked  Policy Security

Recall what the policy mechanism looks like: KeePass and the configuration file are stored on the network drive. If you grant your users free access to the Internet or allow them to insert CD-ROMs/DVDs/USB-sticks, nothing prevents a user to download a fresh copy of KeePass and run it. In this case the policy isn't enforced, as the downloaded KeePass doesn't know anything of the enforced configuration file on the network drive.

Policy enforcement therefore only is effective if your users really use the KeePass version installed on the network drive.

Docs/Chm/help/images/0000775000000000000000000000000013225117272013354 5ustar rootrootDocs/Chm/help/images/b64x64_dataexchange.png0000664000000000000000000000634513225117272017523 0ustar rootrootPNG  IHDR@@% tRNS/ IDATxZ{tUՙ+ɽ7M$#Hp&X -Cd!}Nj˱-c-T,Q; :`1Ԣg$77nr=q!&&q>}{ en䍎ɿ:t8WĬڕ+W~FЁ}@ 999[lYP`kb;U֚VZiӦcǎ 'X566.^"oB 8အǴo$IZlٞ={9Rc@ggg~~doL|0Z[['Bk3?̀|r΅Y6'9mX+q5P?|@\GC<\%xmGKP*>),$K0O hhYBo2Di"e،aIp!QCg%tL!Jm{9p_0$P.eeUބ1$!$Q EA-x!o;#Z8PzTV۹ʎ7Ѻ0-SJ&FSo3{'lf3E/l[~S9eٴ@EdCA+QɷN~|wdэIM3mTbJ ּFa{q:/57/\ۯ(A(A@0 _V8*k^˥7:HY.>"8sVӲghqme5yo,sݦ v4$A @A"SRdk<'~ʊ4DjVh+˴%oxh(@Nis'#}61Q~?ſ?#Z'F @5Αrr߬}uksg"!2!f8-pXqxm'~@`>r4n2TqJ|).K{Ι_$l}?G a-즣_;i@u_um/[Sso|C3˔O-+1B>GQ\ Y=8,(ͱخ9ql7l\oU>BkoX5 vیSS"$Sls1FgL;okkӶGPrn=*D >{P⯼útwj?qk<S% L\!ԃ=^d3>U{B?sC#0//>A.g=]^$OB!DȒPUpk<Ƈ@BCl%s!4Uxfß>5[yͷ(!mc0`19a`4<ݥꛫ5Ef<)3:`T @.]  @33]uw;'wX]E-EzD׃}`_OG7v v B:xL o Y*4 A@!0΅HWwW` -֡?~gB~ZLb8z99jxzV֩X|aY'8''_wO[Բb\Xmmn , D,- U~}{[RYnՅNr\E>t7KfJ~Tcm (!cVCZ̚雙/?>Hu ef ʼܼ@^Fn~f ;v8p:T Q,\ʁE ]d.]侹VZ\r"P 26@aUL/}?`1[g',vz\ө:UEA3 9Msܲ?{f˿]-vCBZz\؂ #0cg )mJq:'7,=FbzIC/<RUpE6 "%*Mը1s4Cx3,#<2bFlQY2B!d%` w4dr sYVLp{QX]A1';e3 Ske"]WY#Jwy{5 s.s4Eo7i fJ̊ٶ*Iy]Inxb5fiL P3c<ܵb >FcK[oW^0Ɇ>9OѧR&c1#ڿegߒ kvu!0 JQv3a ;f\r݂x%sœ͍:qcͺkg'~27Qp !! i8Pǡzуu_]VOVf8(+y{ϝ>ӒT5JJH&B ,3{wYXX PObȀn_vTm;Š6c!ZSKlMH4u?xH{wG,c'ߛ=oQIeB`ǩ8 2d%R-۶l0?i0,i)s˶+$s eSӜZzaJQƢ>B!B肧/0PSSnݺ 6&i&IҶ3iͯjvv1dɒ꺺m۶CRXӧo /_>mڴFT?ח< ,XPUUUSSSYU9zSN e8`CiVPPP^^> |+5z#8IENDB`Docs/Chm/help/images/b16x16_message.png0000664000000000000000000000167113225117272016522 0ustar rootrootPNG  IHDRagAMA7tEXtSoftwareAdobe ImageReadyqe<KIDATxb:a### [ZZ aǎ?ϟ~O˗@!n(4iLⅠ;yTI=8k4ͦ#X@4+óV_YpN @qa&i`h1%?Rr @1 i:C˞?\|L< 0c{mf  3,9!AZB |0~cf`tAs)3 ߸>2 0~AEAy4Y^V ;. ?b`q"?_1<~ {$n֟Y9~gv ܿ%1\|3 _+ Y{70<~lyưzY~b`z`` ѿ 2 ~1 6/a8 w>p#s'n0&03|1ˏ A \ 3OLgxk/+; ,8"uBb0bMH~SssU}k0h"(?~bafff%_...x8lE@1 @,Νnaaod k0!R L ?@܉RRRi@ѳ8H Y^~ xwjzIENDB`Docs/Chm/help/images/b64x64_vcard.png0000664000000000000000000000764313225117272016210 0ustar rootrootPNG  IHDR@@iqgAMA7tEXtSoftwareAdobe ImageReadyqe<5IDATxb?H8 ###vvv6w\@|Zơ9&&7@/u֜ׯ_  pS$'', 48ׯ_O{57d?841 ;Wّ @,B۷o(&FZG-06+++T̰fk>0uĄ-##%%2b=OH-"A~q@̏W߿<1OY l1/jb!) )@y/P3aM oa ~a`bf`f8_Sh,,@,4`dbĈf8i 70g>;G^> V#Ap`ʒ Ab"@1dџ?@XP~}| N ,B@1$301[1ˉ1:6ﯟZ[ bcnjhf78n b *cdh% B*@7A@;`O6q^ /_1|l6 3"gů_j)%p> "eLLHq+v x }6`@z+0~10AM7f&`X{@0|APOBL ll,RÏ,-u8 'X@ A D7*3ЬYC"ex3@sV HGGB}& Ehg"bq H)߄s>DoGd̚Q#mFW^0D  Ɔ0Pddc/`0+g`qT ~׏da?yy pdx8;ꔐ+?ŗ` X!%cf /Ϗ 23qͫ`O1c^?82s/c!.p7puD Lԃb R;H XH)1a^r, f(pmCepꅻ /]cPT/yc/fFay֭G ݻOf( Ae?w!!^pJ R0 Z OC?x)Eʯ?Npcx) 5 `gf3 '{ 2\ibe`lcFׯ?k..'m/Bӧ/ ,04 Kg"1ʀ?߿3}a 5n^| P[PA/× w_j**`ɂ  Jx?R 2 7Ȧ0"! R02\z ARS'.Oo21R d֐fp5(wnfp*b" , [؇tp{W-@$ C2Q gA(/ З/?20xڋ1#gsiV)q`p`ff8y7>ٳ`{DEjP^ȃ&,\0C CH;V 2 @0@$B 122|g`fl JIq3< xWvVfEii2(30r oX{[޼K@ f`@ !qq!`WUͰf<@,ĵa y1c+^f6> u_1[mW_3G/^1r=jŐjqqapz\Eš刖 r0@UfD ?;`~Z*$3,0o>FY12p O@~3h+13((gp "X9K l*(@QjlY_!@$ 1`OOFi ,@|F;0~>~co100p32 L=BL o?)`!X1! @Du8@/qe"2@MWpg`_}bՁy$ G{X]a3Ç'O>e66`+?'7#`$z_lKp} Ǐ_sAcW 7Ħ?h ~O=~2p r0l@`vYG1|pAr{Se`|بz9(pPA6"܄f ~ CY$$~.@a0IIQa3j*\e@=" X64Y!!Z#'&C?d(\101R ?0u PoCA$r3,@D@F=ǿ{d4<a|P,^]U7)x0CDl!@D99Yaǎ _aaVl/[|| 'Z1TUaغJ ZdP022S?DT!gwM3,A H#\@ H* L .]gG.-BͿ[#/ؼ;TÑ Ԃl($f@1P< Rb}(z &R - ޾}CyЦ)x xL>AeddY%-)ĘpmP'O< /7`jIPogj\QQ2Q`P r˝;w@v  p(Ӏ5/ 2vP @|%à i b5h 0y;V[\@?ih!ŜIJ@g0a ,IENDB`Docs/Chm/help/images/b16x16_kdmconfig.png0000664000000000000000000000221413225117272017031 0ustar rootrootPNG  IHDRagAMA7tEXtSoftwareAdobe ImageReadyqe<IDATxb?Vn y9jꌿ^߲f[Od=^A á >g8S N.??~*DoJeacd`vAW_ZM+]bf_y\`Qo fxf%l+ºA'Grd@|ADMP e_~30z{'_Z3=']6cƛ3^d@A6'(0%> Vk 5/9ޡ#~Ma Ν`be abcc5Ϻ}G A @COE 5 EEX(Pޚѯ ;303|>AfQ@ͬ@=b3bgA5'1Q zt5(:vA  )%' Gp6YKVB |d)å?XX3s113H 2(jJ3(122g4]ۿE?3|c)+ "6 l< _O ~d b Ʈ|m'Wu}``02S8~] XϾ?ZW> g:`/\hˌnY# $Qp-O/o= F[I38b#1z ܜ LL g+k7o{8hP~C ladfſקw0 IENDB`Docs/Chm/help/images/b16x16_package_system.png0000664000000000000000000000215113225117272020067 0ustar rootrootPNG  IHDRagAMA7tEXtSoftwareAdobe ImageReadyqe<IDATxbc߿50ggcb``fefgbffb6fFff^!3f^fP/bM?_=66Qˮ201c`+)'P8cby9܀_\zɏ8}+ Û94?_@Lez{m-I~- ֔f`Vd`Pbi>?I;[kFUEb׏o?攒cb@7 K)v3>}Ư_8 KHH3|&;?y.?e`x_ YwdPQ@1a`cf6`,exo_4:]!N5O>31hjjk200 fkt.'w1޽Ƞ'.+`#yJCy)nF?| A& arb>!޶~2rZGFPZMW 1<+0rH(m?Lׯ (A.`gf 6fcp$3[2y˰1soV}v޻gsՋcP?_s@yq%Nn" )o&27}jn AȖj-m/3'mʰ埇ϯ? \wn`fbgaÄ/ AWM9^X ~ ,%)@=<>HONP'(%߇a' eb: '778+Oqq񸡣_h69) 5 @  : ;  1.Pgee)1XXX`^IENDB`Docs/Chm/help/images/dlgbanner_win32.png0000664000000000000000000002423013225117272017041 0ustar rootrootPNG  IHDR<[ IDATx}yEV>'D@2 @Q@ D</CE@=» I!sȜ '9ݵ{gy _}WkE+:mk[wvi[:Y::򮐗(OPX9R@%DT9""""6 2Ć_̝iIs"0Ș! Q( kQuQΩ\cr9ۚn_,+#AV;uZ+G*3 UrV(=0(*'8 NU(bbVb13UA>H}0xN2ٳ32rKoZ}==ZQKl` 1#zzE#$`VU0YR+AU*P@P(T*Lb6:5J总B鳈“k6dXRREOB*p"""k8ЕfȕYe KUq.X"A)BIeAD $'*UOlA*"h5!7bDS2&ƘNn 4`v7:McqWSEPQ 4LQO (@LLB^"Ue6lvƭ UuTIA3QP N۩ #r20u5njg(þ p+TE.*2a0# Dx4(ډFxRHPi 0*RB`!΁Ωl=968 ,85斒-"c9}ѝvF*#"✊S%fkXu\[c>@D@""TWS*mkuNjebR?i pmq"1 b/p>4ASoy'2֓lNEP6@S{A 2e|DR K6ƲpEH -(%euxMS6i Ǒ٪PeRf 퓐~^ǍWv<{%75qUW:f̸?Jκ7k( ꢨ'X2dѣUҍ5-7]SIb\$IT"RlsXUISM(rQ (aka 3<H QjCUل:YÆ {]g\ED//٣ }ѯ <3\͌f2#ɵETQsme8푾NQ{DXNDvkw}^zӎ;jwO{RsȑG>v[P,m cb9boE"qQũw)A;up<ՏE(8n@11%JO{UALyʡY.bMP*3}j"Kk~¶?7kJ_L^u'_>!KYu9n;'.R%R&%VOQHĉE*H$*K@ 4H.`SL&( [\pt'" ysX8RD`&SSE'"ЈY ZL{Ν+y+OS67aG aE_=x/N>h g2S]\+9 $Lđs`@B!$%"Ě؏[EOyg\=Z`o!.R56ǔzWu""JL̆ W26f %5t;+ym\P]w$c7#cծy/u ={XjLkE&Є ח/W&um_S3R1Q)XG8of!1 &lOE Z%f"1s$."sUIWn Dbĩ"o(X 3Heo=( ]f_.ex&BC+h}_!ӧ3wJ[{ѢMin=iJ?#,قzT<|÷|績}u]ӐWl"p7,L._in$ ĉkYvp'F$*vb7y&"fUA"BJFӸBpL`8 Tq(F ! \Jz,vY &e\@\{\r'Ϟ5Ëv^c?SyԱxB]DcI VoGrո 3sEJE݉۫f#3RuZKq**!rl0IxHEĠ]myKh i|ўb5Tҁ)w^/Gm`Y">2y #BmEΚV}ҧ /u|5yK4>q)O3x㳓}!Yۉ5x }j9看:Pn '*Egb ) ֊I`y $^+;Ev*`bK@DQIR.x͆I[fS!@Q4R1 'ٝP;ݹO_C1`ll\v!;|̦lܹ_h|g]OWn\ulXнwFԡkhnkTfewY|F8@{ic\368`0#bM!s2)ڴ6L88OMT'6LXxi@=v_~C'2 DN 釩s1 4|';o65g[dQ۾m[?9b+V`l؂ 菟kFTv+{k##@HHZ D;  fD%(ﳶBY)0d"ȐO[7R4(*^gRu]۷/NB=VĢe!9}c~ێ=Mr#}Ss Vmūa3o–ZcfsuU n)'I֓2?K@v IV2q">B$b{4JD*.{q"ފX^ m}|%žw?)R2D!tT>$QR$޸vr6Ȏ?imӵ⽪~Yۖ| 7ÆZh= 7 >CϻCF9lNc6+7 XlW~_~o7ҔQi=^WkoG{H}Y;R7pm>5yiV1V8U'A&RKCk/uLR]p3WSε<5(NyBbO T䣵g+tDŐ/=Ͽ\}wiȈfye~?T)SC `0 ߹u}㿞Qg>_.ɉz</.E}=jP ~}]7O>CQTdk!w %FࢂHȑ %#6(':\LTى_ƒ1lrD) Ejxkk:”H\A\$NsHrֲ1)OH*rIR$CHAr9ct%ʣl^䷗]xE3Ǭ|u݋sxGɳwF`X&=rϏw>7~K/_9f02<6mͺq>g4Yi S |pUR%kONtD Xb֨aej-rZft@iV3d"pB!`q2Q;ֵFN̰i׻kJ!~}G1kp=i*];>@(R=[o7o^ >*`&cz3'|jhVzs{^i igF/^Ά8@~LjZ|zT%bO?J8 ׆;BQBVo(DΖ~hm=m`IjZ S?7C. ~/^ ek'׻eJ zWOqSg]x<գvQ_r'fLQ8d !:{lT)ـ)n#" 7 44-Z - %Ub LBy?XJ Ufeԯ7Zڿy'~N;/6l:įnF ܊G%򀠰Y?jy7\yu~xnڊ:n3zS/ީ X @s1 Bb]&E"$hCR ڭhWE-P=9 MqD@k L!h+Q{Q_4bNH 5 9`P`DVӧLᄐh[` kW|6ÂdJlǬ!]Zmv~;g-:~E,JMw*i)|{~_߄à@APO>͐5 8y~ϝo}|^uo܃o&kE=$Iizi̜١ jwx`/]* iTsƑVcXv4W\ZtM* J>NO//Ae9k1` >m*PG*$]Yo4n3j'whQǞ<lk'H}nFC>۷m;˟|xύߺʇ>zIpШ}cǒn:3mn" SUBIPcۋ4!vUBc]d3Q*aMRD=|ANA.IO#l`Bԩ zE7j[dR'%Kk&Ow L)_WԩᘋMS:u* #& [- ۏ-R_[&oӧ_&[U1c-\eDה}MrB,Й3/dY>oYa,-񆖩%i]״B+gZ<|b͜9asNy?U]%^@`FTQTFM\4iGˇr"ZE֒1dm&Yǂȩ*D`356i+jw[6MK?[^ivY0rЭ@5 @X]o5zhۀ~/7}>ߚwǍ$/{?Qe+~Ggm%j'7BgeR#car="P$'RE"",(Gd1dL1|Z 9HcM<5]ڝܱ?On= owfٕ>% @Tc3SFk_XΪ1ط!o>ag߼3g|ѳ.?+NJ %\@µqyMvYfN@yw$@y:2n_]Vd5k'WuEݥIHWJ|lKmvio*M.}Emb&5d*pNEvc}pI۝pd;rwv>yM7=?ۉU2oo}i>cpЉxI@. 'b疭5hؑ\97?8_ZNuwNIwn\ Vݳ0"dFnϵDIwIMzːTq"D"G*H ĆXQʾQF5%ӛq{C*HdnThROP"*'꜊slNw53o+|V~I>ŏ<{%7s7\-}˱aTa2*_tɳK{_z闞~_kWիuժi*MWeJ"a5SHwk:K;HwDԮȯ}e_ kMت(9qH4MH]ɵGUQu5AP(PBA QQ"ְ1lbۑ^ǭݴaC6uʌcO\xǫOMS񾓁C*`/źBas>r ^\%go]5svWv[Zn\ob7ֵvz=!qͪ_SIDATQdldRldrƊvҮf#,SHn5tiiהFDNhz6om~6 de xkՔF"5!l*:^~Y; 6$ ƒq T:/S7km߻$8Q4|Pp 2&~hpgwݩSqb ~6eSJvh;+m+_i7=~(`P@`&rcG;d]?>5S>qOݿ}Dz6 NSޤEJT"kF(zYRHP]5 :9\>2Q26֨1)@H0Vc3@ZJ{3j'[)qG5|~Wf`ud`}jͻkӽKxU;[(@d]"\,1l iɒ%uBd]I\ָ+b8Ωs "eψ&PUfMm- Mz&<;)SQ]>90t.]ƌ7>>Olv %-d%c01P Q$~S6iI_\i* 8U)af* &(Vđ1^ -f&%|O9zeKjVldK-3&cj`.`D$U! =&w%l˦*sC;"Bd {+a/LYɒtB~) iHCDla6J!Y{%z ӲػOD!E pA"Hɛ05BlgD5Db#0,Ɗe!h1I?L @H}`( !_8 lhcgQ`aPU"' ư>nMewdJ(|&$c `\\N$E+wZ̕԰5bFgĝ{$H ԙYXEND\`*Hc#x4+dXs)>vezKuY ^!%6lD790"l^*!B(8s*ޕ<|+?NvHAM\[E%́F09uPĉ'P ƃ&SH2:-+E؛m3LTEc/qzSJ3A"8$-RhLMsʗOI\Ւ#S!؃X8h*N7"ʣGd%+YJV?:歃,SIENDB`Docs/Chm/help/images/flageng_small.gif0000664000000000000000000000012613225117272016635 0ustar rootrootGIF89a , @/(*Hhܨc=II;Docs/Chm/help/images/flagger_small.gif0000664000000000000000000000012313225117272016636 0ustar rootrootGIF89a , @,H *\( Ç#0HqċjLXǂ1nIra@;Docs/Chm/help/images/b64x64_keyboard_layout.png0000664000000000000000000000657413225117272020310 0ustar rootrootPNG  IHDR@@% tRNS/ 1IDATxZYluν_,pB,vT-Mڴv"m (yCyJ@߂8yѦE]J;9R EJI>Y{0ײ(Qa3||~^}:799w‚ceJ]]ݐv:~{l8EǡI$r'>XGƏ_g,--J` F# A`msuW7档GGy$Io1ًcZODh>?۵{A$A0D"cHT ::X^^;q}+GU_yeszݣ#+S㓧O_=y}|c;(Q( C*"D` %*l( M{pĩSi{\xa\YIT66Fiʝw: ׅHxfwa6 av;;f^:8[qܲV@_$I%f!E@)cm}Qk(Z^wSv̇.3 C3bFD@DpA=f9@ oYt_g$z!-"|w1`-b!Y `ì!YEoC$pZ RLڢ5\ w څttR0h6aÈ!\F+x?(3 sg> (.كB J$"i0B z_RȁKǹ?n&j6Ʋ,`qOC=8<û 0" eHCyR.|+\MթGi)j CC9: =$q!?v5J L bJ@^'>K B3j'PN[ a,Z) ) ?_!>&hhn1 @v ID+U^XUkjSHq{u.w ﻯ^ye5'ݹz)3%1wZFXp둣=z#`A, 9\ձəֆ̞'Gkߞz$khWɺ鋳Ϟ3/Ԥ_Y E&@ 8Q+<{u+鞾@_&'5Ո c` F:Js}t_BȥN~*}p3PA@R"ԌzjBwg~X*lX):Zn ]֐F:4C{Nt H{~ܩL!mʹT9gS$$Ŗkreݙ~ _cI*%wWr0T8ފb'8MxґW,~ްv iu(K_l3N1JI!1@E^3MXt~YmeZ*P 8Mn+.7-k @f:8u0wY!"%S>M,jUdґqQ5m7]ߟw5_Չ"ϏB  ׎3ґv҃l s3׾lju" 2Fځq-&fgt7;/,M{xţCCkkΌ{RJ-Ny:y~{:d:Ro4OGx7 Ad c!%YK5 L!k-"}J$w~$H a!-Yeے>S[;$QjFpPHҲ1R}G~B֒wd!&|2_[_>59z +uH$%ixZguw/Jnq7Mm-}ݠnӗgggRT&U kIS̸7D Tm5"CC ##_yZuFrU*b808G ° u@[o߳qvNa~~ҥEQ?8[RI {*rÇ=0Lww'?y't!e˟{lP̢1ڽ{wPhȢHDZ.3a4Q[{BP.jf+P,9̳Mue2Okse K Q:j aƻ y*͇4m.]u*f6-䄒 IVĽmP0K*ñDetץ]t}gVe]60zc:kREEcѥp=o%XWLEpiu=nZH] j^(IDaz-ZlKjpAఀKE4MĻSB \Sz#hb*&9%"EE"% 8l$}=*l:?ť9}5T*$"3I._-2'34xԨ/ھs״!jSRd0\%\Ia8|6j^UC5q7?01ѝ5Ap$tz0vMIFWp-叺ܮŏ|[oY[NWEG&28nD1<Fgپsr8SpӏbNàTdT Bl%$iZ`Eڒ*AmRmVac^x޹mGMeE2-k2)T/d^=ꎽ; r[iDtkkՏz!'"r0ͧ]?_!oiWx2)gz.AIdaEQht!%7O^ g8}gR x;=\7w%;5M 3q#!#_ݩB)afٖsB܎[MȘ4CQaL%XXիٞsT9pB]4,\*,23r~*(jD{;9܏,EiqNRwe nM釭VRdTRReH\%܉d2906=,NN:j,3 v T|z(|vvpVUYé<2GwTL&g (.ph3죱%$p"hV$tMc7K||gzKreUbO;5I PnlEH^ ZX'ŜǍn$mSCl]& Xyzm\6l'IצMն G| ! pIb.syHx\~ǩu}id" {Kb Y[K&Ph?|㥎Gn\09{Mp(!vu@ 0?9@TI7gvrp`hJV'5wC/^z5/{`4ܮL#&\.\pSӺuZm v c 9حTla2#Ο8EVLIHnڵ=>O5Up1+ EeT8 W(EQ~Ksv-GFFX5 pAaV\1o~6%Wd" 3cq>QN$`(is9a$I]3_=}kK/5TLs,b h.B}*wn5::RA͕ݙ^=6l P η{TRt ?hj9C-Z@w-n:6?_Ԕ^tEMD&pjqiS'Uǽ镒&!i6cZ|\ܼuR2FEC!^fogoQ0At&\x^ Tp5+dCV@)L8/ ,sݘUHǵ~v$H:Tb?-&l]صSW&oLhԭBH$I~P)d Y AƠU[]u`ΫŞ[wa"fx\|I0 ]s5555o{"89_2YPNTt<~S6_8j pbl۸e6ֿn]es2r"@c%V@ }cPpLVV,xw27;2鲨#n{C(,nnn~;/ k>4L0PE)EeO~؍h&.J8\H$JZ|Ҁ)O&F+l E%IZe4M:ޞݯnoP5Lq ".W۸qÆ p7Μ>Y, v;MӫWp-9{~w~&kD9IENDB`Docs/Chm/help/images/appicons.png0000664000000000000000000004157713225117272015714 0ustar rootrootPNG  IHDRnNWtRNS/ IDATxwxW>\=Ii("($! 2&aۻv8\l ,xmɈDR΀Jf4O=3Q~VWUN5kUJL]TD޶̝O~r >JRPN?OfO_.QjJP(D"y=nOަ$qF+r0Ν0,_; (U+7~۷m(V]\@j# ŦM~ TZ`)ؼ#}Kp횵qĄP!r(a8r97&9T4HϬ)|?1u(C6~Y ~z}KJLJLL?k41HM"RJ 8!//;v4!!#?9~@F(JpQ:8)_>~Xo=oLHό98+?}qZN 2su_-gc8+;ums{zTI὞O0!g NR8YLzG; ظaÆU@D.d (C€2 JQ./7326nOeU]!g#1LH)pF8%* AnuKK\ףDe V9)<3 ~6SnS|bò3%,gF3j08n -w9~>rIʔOj{=kbbCC*aƐR EBPP*`xE^YNN/dXdܿo&&rAD * 93TdLdTHo/GuA~C8;:u Qސ+ɮxm{u}#*'{v#dfߛUn9\Yn-NRP7xII٧Nh4"E3&ٻg gA>..qTaʂi&MH<јrnE }قL61S""&N ca^ $%O8VzdFsn8?;r ȑM*)1jӬANն^ֿhƍ5pI:AsK+^6>?2@PZâHqh{msOn߶oSbL+rx--O/}4e~ubҌ{""coU~evtioWvT2F;J' ^Q{x@{,111=}eh0!H/X3ebnv [H{l`)gIW߰"'mG}&FǨ蹺5e>O9n2Yڳjb\p;Siw<{c!9~&\T*UJj fX((>xf?I,R$(RnDo5J*++w3䨄(ʄYwqyӂXZO-֒U[MZ[[{FJl-YmcsctZ|Nۛ?0@(<8c33oъsj"Nk-1`/A݅ H~ XqC,C/ .-=큷>`Y^vay'J,9}ԙ!늜ʳla4uT];n):_|uD>(u2\}k}#= YnipO5LXk }{.E%7a_LJ7Ӷ4B>o8/$$TJA:- 8l YhiИyĦkBʑ2S @YiQHH4$T2.GEN^Y$rݏ9%1ˋK%.uAζ?8Sep՘6CR/x!B],mGt^OM"D "H_!G1x-4rO%iZ'$N/K)bS0${voi<+r6lߤ/DNq*PskBŞT"eJ98*aV9,/Lis(h-0p 9X$\}[t#*`rz,>jvx <# N?tҾ$>?]%Wt+-W;st{fx .nAaJ9%~1XNJg"YjhT[7:~;`L-rCHC}DܨP(_/@0|PQt]WOnLtd/*> _|&NM$2k.rF8ȟ i+i96׶5!64W;֖Y˖h6dy˾hlڴGݚGV V唛=8\9sD N"cH90.#;79uVxdd<0oWf܇8yqD(qDAH9[>!'m;Ν8i+ ewGNSz=>߄(uu%e}A~t+d:8(6_q|C'Fk.Ej;CH@2#"̊s5٥0q.8+ofbDt)^sx`v,%cK/WRX,m^$2NiczMޞvAs!&_CX:?9#G}F  @)0۽\cS'(E*1)2B_P0-uD޶ֽ=7iDOOẉHu;wn:uB.ѣC'NqsvV  @՘1c@ղO:W_}o d{oѢE2u괉' 䩓Mpfѿラa(AxIӭl=|Gy *.(x0e$*ooP_?,-5L&nw"HkKKڊ>~ba7Ű/g TDbb"F/FnNGvl߱gϞE&&&x{{h6df~wbn^nWiT(9AGdQE)?KKҧ~i& S\\l4;6n8̺ ?x߆ FIg}jl?kvU*+LsD}qZ]+G9lj9Mv`-Q{{?m}'ӣK^zhd9@R85E38N=g]79nrdd/ Zڀ~Ævl$)ʀ~ʕ|,@AA7?칳}HtP9L>C]ٳgB333]\\ի<^:tJe/%y打nai`uhE򉇖Jߟ}$S)ENo\z?~P4D8M䖾hE*F?_Y:3"Abi3d[AĄe7Mc_okB͛2#'AƦӧ57XGk !-'_lkoDSΝBi횵}DWwP+B 9r͚5pƍ{NacXԎ bRA/ABNd;?%X[s-ı 7ު1 h2Z?L=5%@DphfO72+++***22Bv0m{h$n]iSs(nDhuQ##GDEee5ܥ^O?@bbbtt~vƎMIG333g&ϔl ㇏ ɓGN@11:nV.>a;6ltV2JOGDY]OE 'i(ix,"/]SW_~%q^29J6J0wOWJeg;8(!@DA~)nA\^OOO~ٳRn,X.]qkzz?l+AOD[6 zLj) SvbqvloAZJ*M[]y?ߓ[ 1۵vMjB[}.Mj$&Ȩ:)y JAIcd6Z]\FV;={GEWiii/]xL̙31vʕWfꭍ[MMM% rr1l9`Dd,eӵZ$۱Ah4j HR-IVڊuZ|>1u` RQ⢉)<00]ll xI]\}.O5U6ȡY:vOO%nWWJKK`̘1*UF%%%ݯibzeh\j##] W0.lHÃ*"ޮم %4* rޜ9 z"RDr2EۢBog~bW9a6 J,7R ޸qῲT P4v vQx}| O$_8YBIyv?w}wt&> IDATc׵zjI>,){z8{. ذAё!Q제3)29E.}8^jY0-0tDxYfZ[[| %ӌ9 '^Æ!W;&@Ev{* BJ-s sv9B!dJ'@!PA'xxKXMf~S\-^PP`lAhgצ-hN)K=:3VYު: 1AQJ}b=:?rrC%N RȬ3Hxp*("EzVv"*7{(}%s=7GDDԞ bsrNQ,y&]e]q ș%c𨮩DɐȉVkko?Wn8wfM& 'ZsH<<!%0N/)]r%\ڰЊ6B|*fo6)Zm{av^j 7fpuW[ho>)qkmi s،-Zm{G{`˖-j-?6njN*[6[3S?bd1"Em{D߉nQ-l<;@ӕ\ A 7nQ&U;y<}W֮̔28 @.C_'O [Jڸŋ(I~*~Hhʔ͛NGфX9_:[Uy~:gm͛iQt~7;NVՉF3ôtJ RCn|(Ak=*nS-ؼu۪G+FsϙNJ^nCՎ9 ΁s@t\(P4{rdoΜ)g?:tE> 7X&S9bDUC)P.WC*GXCN\VtwUl7_{G ĎK}donC ;sޝxLW6O߫"LOYF-5 FŽ ǹӬ%Ni?lb\ \yw'N7&Ao z-wt9; N2."ZϗqFq 'cnji^q>w,ht 捈3\SQ\] z(@2vԌbuƬ=.lfA"#rO+GEY] 55y꩕ drͶ& d2a˗~NoA[M9a}?ܜif;::U`ؼ{Wz]kVu6<{NΨŽ|$2n砊?K_HEj K1Rtt]ūJ~&ƃLe7?/{v>.VA^Ђ0IT}@);zOcС?~?h5lѪU]ߦkg544;RWwm}7o>xȯ1%>~';8ss2#u3Y6A3%BDFDFRDjK`;ߩ_R ښ_lQ#C#E%t`D(;_hhؽ)^w޽vof=mxR6{e6بQP]]WXXWAtៈ  ¢,7Cllѣ077?FF5:((j 56Yve~Z*UH*T"\kg]Ԕ];w4sQ&7 \k]%ufү+q֬Yކ"E$QlooڵkǬYi2DJ]--m"&En0quح;[f&LEl3rDvY'Wq'}۾\hS鿜)!)1KNDfгp 7I t˧N$Έsrr9"H97ry;㭜pƹ>'';99`Hr%RN(7Xi!5wHUx^#6vmձSgHk6 u%Z܀@ph!Ayc0~ڛ1&6$[#2e{Φm9nd2S㧎@*0'lw͔O114S (Tܒ]uLB #K4OȕA[X8grG结h2he ֭;6s[e2!,l_=6Nނ[0{փwo&&14(R` ;2vpa!׎"-ÐJW'YAA޲ųap!cb $9og}BJLxwE3pI>)bz#&N 'bc4(h2Op"׆e֓͛2"`<8$(~O$%&]pɓ11`p믽kw"wւR'/p 'Oi41"Eh&'=? % @d}#n| A~y fO_;{i)S%;?.lږ!C>MwIyD(q]amdJORSP4 s_gl|_QTTa4;?n|x`e`?dA6|6`6SRREF)Ɛ25" [fdX%ɔsdHw ;-! ">~}AUUZI ,g90vg dhz'Js` 8<$g,nԩfjn{Y!GJUXF?2+Ä2O+Ne_Wb||8hEj쥄#wd~ׯU=~0=PX29R?~6ԟU`0..3 0cno@A56n6"TV\ikk,) `U9>8'6iH@l`Jҋu쨘mԬd$@1lԄI*/d]'.C\Dh'OH&Dx*;zP2RS D2.c\\+BHdTXR -i}1%%P4s}ˈgyyI54;-lj|RctU;ʌ!giE T!`&Zd'G K|rN*vtXoL hW'ʮ^!J P#A^ 9 ?QYvvԄ&166EKf;ƌ WګYHBĨсNN*,-B+CSllTlFѲ:3k0"TAavҁoPBe"X%"kuY-Iwč_-{xB3 9p(ONT0_2; >HaϿá ];w~9kz3` 8Ɛ1 F- CNP/!as?k{O,q7~Q `Dˬ>ڹ͢nݗ CpQ(ix(q_|vaԲߎO9Ƒ1`|yOQͫ1S,~eݓ'`fD05!V>ZhX͑2}?pgR$8j@ SBp` ?Y֢Pi޶9vL̥ 6}g'ĝZ@4wA`B3 6lCϮ'>0fz0m`^ hB"y+)̭[&tuɚDfڀQ1sf]N3CA] 8:3Q6eiQG'bZ@?"%Y8Eڙ5ZN:CKj] skwElgn2I)tm/<@NʵO`a)uIaᒧeYIby96SfA:Q]] c~}oV8um(0ZamhQAcI#UP @Y{73 O|-74,@"l[}fb"??!wBĚ[J@$ ۻhI_g&'S[lyC&W A"H(5&!1t}%;ښl0$jЩ549xexƎ A1Hg 0yAm?Ek9p#ZoL E9(OϞEN(cP7GAAj $[{n͢.}[@@WOnm/{0W6BT"5a8k Cmx Řz};f-\G(Nv z$ݕjF,qηom&=BS(3r bܢ+VȔeVuqVO|?gDPqv >ȣbDNב_Vbez32ZZ >I.ۄI#-[6iġ֡"jڸeKVurp!6 ~ѳ)+gvԃM:8b߰ir CW^Zr ;6N-2O0K޳spr 8[NӬyTB\#(pС?̩`R81!%ˢBcY١D'tо$?2|ϭk߽@7`ExVo?{Yȶs`x ˄%>$ݲj?%HD_bkƋ#CP{.&-? !bW6O)s6^Iv)3j׃ispٮ@b³ˆ9Orܕ>4o2ZZV OĬ}N-NA^'>0vg֞Ci&Uxj7ߋ4OBO8q/6fZvH>}LwvTvYWC`Tyb^Υ3] >[P2۝u6fgS:@- wtX) p+1,L8w}f=Wr0$tSV&f'-]jUPY?Wܔ|{YD ~hsH`(9>>}U\M6en)*[\TjBF<jn*z\$?9$2j`)\TX[kR 5xpܪZ^T^Z@ {l?\ۗIENDB`Docs/Chm/help/images/dlgbanner_bluecarbon.png0000664000000000000000000002330613225117272020216 0ustar rootrootPNG  IHDR<[ IDATx}yUoܛ^C ! @ҭaVPQi9{>m_;tcm7F_}Ђ $2$B@ܛcWթ3sQ+{׮Nj^mذK. ŗJCPFd,ۈ@ jBDU!^E$lUDDң [fVG^S`V1d-CUP(g?z(ԋsPEZ"3v\rɥ*TUURIc&2C@,< @)Zn*UUUM1 8D"fS w U^@= sRNP[롶&⏪㱻);jK.N$|;q^bbf x-V) `@kQ@@!ᏸsP}1`6|z ec-j}:Đ S Uz1Dj '"b)9jK.xދPQUFdXjVQ\D1sk$x9Q)l-v jy%l@@0^Dmy/ȒHl<‘2Q;\rs%(A@2@gJ_ xOal J< @^EI%(άĢ=;G#kTZMĨF+xUP2s^;\rV{`3 95@ A]aAU*TTĄj`@P01Vy53!0&0"&D$ =Nuk4m7-_>?rpvL9 !^ H@L DgQeX Ӛ0Hi۫J`ԝQbRlR28UCX[1P$&$I-j'ū{Y +&\aAkCOO,9-w<'weSL\r9X]rexD`*r٪DT| @A4,jSԮ58IY uP_JJ>;(5Mad@Lle$u$v%jgu]Iʼn+&5GH/ē.|ƄYMمPt'oZ.9+&{z+kv-Ԇ2i2Zv@`r3 Ƒ%uI6Cl nیuv/Ay]-" !ˑA5uYW^q&m8ԇA {^-Yze3mܲAW^yK. ٱ*LD ؁$&U|е &@X戭9 j$YLJ ,ED`Bi$ʢƊa.0ˏ*:* /9hk3]M7|ӧ;c`?{=x y睫V!ՠv3gr92q>BFl%6BP"x$ީ*k1;U؈5JvV/~Gd;&ۭQ`6R勑E {`O^XGӻ;Lln!ƤV훿1> 7hָvU\*cV\Y>{HzT$\' L*`0Rjs /PPjlV6`,کWNJTY@DEy܀D-Ux'Fr"r2`gQ[U?;IA^m#W( ιufb>="Ƅx_y'>{n:˗/?pA۸vxr`W \7eDxJP5 c#䄌'hė %Pٖ#Qc[j&0$P a]˖ D8!͂j %df86y2!$h5Xݮy+}ysӏCGݍC ]nK/o׼&t]%zJ!;kĉmmmsF;N0d 6 Amĺv9ѵ51jZưPY Œ(lal8agP[@mU_՗H, 5x \ɘ?Ǟ LA:^yM;tU1aܯ>֓ᅽxv7{ٍ"}^h$NQȖ׶| OנAUI?\rcπ!0)g `[TC;u% ֠6l1٨1`ڱJsJKT,%!gv3W P!N2dFS2$! s;|,P@7&5o7_LPA-'.:gNny Ͼ^t O6_hakxj4.K.#I ibGd$=XlaHXQDLƆz,PdžRoBtB)+I\$u4 -R>jtX;V$+u`i㗙OZ~JV{6`M|[yW8'O%ׇ'_#/m?vӽ=;%G+\9qW4D̰gM\m#25&쳵FEZf`c"#FG8 BaQB8`a&jvF++8:8Tkpp%S(uiWt i,PJ]B pӶ}y37.mx5ܿiO/o=k?\r9 HY6d,%R֊R]1ē{?bq? u;];&``@9 e-^G$X%kc|ڃB%'D?f;`;羱p֙מFpYon1h_bɶyN|c?k'|מ:px~C;77CF_L,j2ԎlB ɧ 2IKI% aIEвv8!WBz()HPS:[2FIB&~|C@9Y_7i?=Go~Nxv-T޹m-Z:qz<:}!NG[ֹ dD1m1?)U'"VjY,E&- %U $YR3=Ϛ;R9 8 ۮnɫ&`O}ұl3tOځIR zE@P'zG |m@Ov%`:{`#$Qb*'*׆@j y#ή ]𬶃^* 2T̯FN(kY׎"9g?_2'@ġ@׎HD@7Pج]:Z}GmY|;c݋3^[PO>OQ (T.0@j auEc l l@vǠK*eY"EF&ux!H@R->$@ɸf:G#j?fW'|#>LFGĄ Q;((2 -KN\8M<߻}am_5w5}'*\j*Cal`r%FިM qX([*Z5"S*YS` 5DzT00Ptl†haӣ[~l1(o5ԡ{Zvr= qֲp='~k=75O\r9\- e!% 6|2D톜 58i % qT0SJ#NTb@$aXPDYϷL=tō͐&1:eEs|36sɔ ;/n/W{n=O4&r0A9V 0)1L5aB!xڢJ %B6(Aml` "/{ϔX3t6+$1D0j ٖ=@SFNB&<>q.Pq6}ffR[+ZwxpΜ _ՠV5Fr&[ʤʤ(D8Yq F7\fAIDUD$B,("6(26)k hȀ:$"SQpbCG%`QhK[yC49π&dH|7;bۍo{)'o6?z͎cOzu|׭zȰɖ-/Xp66jpߓlJ* %R"0a&2Z]Qgb,QEd-GQy2˨NHeиU*!04Mwp!}:Lݯ>n^`.t&؝~{m񕖳?8d3Zwk'lh7m{Ѣ+lѢ+r>"=c8m6v=#ڀ # Sf TȈ?#[3iB<+ U aY#ֲ 0FQ Rx!$(XU8n#o ߺť?w^W3C@/Лh}D`Љ5gOe=6nts.xu kYڪ%K UfCjѠla%t.U yMj/Eߴ۪1W ,mW5€Ԏ7m{wUnI-S%$mBqJiUؑc"l nm@F6,7W/p QeǨ]zO:m_rO)@'v@<+/y>۹?_baמ7̾_u };iepׯuٲk ²e>˖] e[6 Baݳn\)48cU jIӝeˮMBZX[m_U<;C2ț2;7j[>5NDG}:,2ez@BX 6YcBnTYk}ZSQ4r|(ja5Ь:v?l^v}8mz}-p0ePh <'=vaK:iބc4={S7މS^n|a*=+V\_fYo]A~UuGR;XDuRwUlpxU XwlCƒpKp-C +2a$i$1*5jsXR#!lJB߄㘒9Ș8`5jj;;NL LDspMoo}Kgtᩯ|Ӆ5ۦȫ?9+pہ`Wd߱cV0%ظeŒoEC90kɘNÄ6. # >^ɺǦԞv۸pydOT[Cl0 kkL7;a\N6~T4U Bv:r{@@g$ѣHW`("DX֤o☸<F!T` ce( cG͐3N׵mu,#)L({Uz&O>Zz1c> 8bҹ8icqǚ/o?8y=Ӟ_|hρ G}>^* %CEզ;ّ n/jKLp@N9F]wlCûVSpLx(ēdZb[=֨-qv$ BQmEdjNB"*1-Mr2(L9e6ԟ qN9phoQ_o|pg/>;ww@ppsۖ7Mh)g޼K,~TU7c`{--;_0eק\mDGV~x;#ܱx'|7lRD:&]C0aK4Mc G^-JZ];dYWf)3_lAA>P|ƒ,IT@S3fˀ%<-ضY^k_7}Qɧ5re Q%;oXՐ nJ((60RRtQ٢&aْI8ׯ'vU"s)+zuk(CmYs`ĉ;}ێwbiLhlisK.cl'D!Pa I^(ǰ{y=a\dAеC>W+`1"* S @sH,ɧʬ0/V߿5LzvbۢygOU.NZq-aa`h1]9.xRH`4s,ƐXҥ)T0z""^ER#ǐ87j7re;^ w޵=Ggv6cSB7lb "|Q=8*P&^# ~cT56dV#cctdDe~1WQ!*RNL/[b(:Ccf$+ػr4̥戏0\^?TI0s!!ğ`m8LҺൎL*I"D`F#& VBp1ب8*FB1p Da1^sLs2qv\,?we?h9Ni>i nJMy\r9TT ^M9*33dzP[HȈ5c$5bX2Ild53x ;OLDL`hX~ XreP%*q@psb{]đ9&CR3IQۓ0yO!1lLLl8,?8Ԏɜ4 A 5$ U 1)5Įryl./U=8>,P`_DN|l,"*A!odVC6HHJ5BΩJ{-`aBD:~P;_%\gJj{w1UB1^ےau(==aXR!Q5@dQ; Z&LDcH;q%NDPaaXPkK.GjK9Ӯx! Y<8eIE:j'LB$d!f@mM$TN&ʸFS`^J٘@.1]rr%\'j pCUSH 5D.y d0IRr≞x_$`k2iv4aB^}^CĆؤ%9jK.U5p&^za2])ṩQ j-Su; P@D!D(7Q``8#yB!Vv*GTHSxѰAHYf#yc:ALmp#·yS'?S*kS^t^;`4;3Q|7e7h8mwN*~x7Ñ|/!v>HXH~S۸ߗ<~Gi56·wdmuue؂2IENDB`Docs/Chm/help/images/b16x16_kcmdrkonqi.png0000664000000000000000000000216313225117272017235 0ustar rootrootPNG  IHDRagAMA7tEXtSoftwareAdobe ImageReadyqe<IDATxb3+k/??Ǐ?yݖ{N\q=j_  F7\sGGe^>>>1<񃁗Afbbpӧg\'Rb4QW]}wf]ׇx.|c``涎PR2O11-H?p@߿ 0""w_OaP0%{ ^9@>?QFr~bX\U@*Y\TTn߼L @1Mjgg I8'g(׷o > ȘSQ_32A0J /|Pw<<"@ˢAFBC)) !$x sH &;߿320\3J0:U?0^_\c0zHAAAYYoXǏ|r30ov̬?|a:5E (F Ǐ1q~ggg?b) Gf@9!A*fQ7]\o'.Nt' ?a`X @L};&",)i ]`鳲VJHc01ab|j<fsr+)*[A% \N00B4A'R1T::_{s nKfҏeZB e`^",NPпqqÅŀb ٠ɖenC!wN޻^pqrr(Ȱ>z~^ji FP cf(y,GyjIeYYF>0<|a^r?M@ˡ2Sb@:\ݎCЀW_z(0 iN@9IENDB`Docs/Chm/help/images/b16x16_kcmsystem.png0000664000000000000000000000165113225117272017113 0ustar rootrootPNG  IHDRagAMA7tEXtSoftwareAdobe ImageReadyqe<;IDATxb?% X@###VƙLbbE[}heeo$7aBO>DDW޽}77O\Sojj+r@4 )HyxJ2bB:,XNNvO6ӿ ϟy5n@MdIWjj*7qr÷o?XYY޾}uIWWݼg1겗U ̀ mh31`pq4x Ù37~gk`cdq í[> ؀|&&Pd_F^1|  LLL ̬ ۶m2/@ xNŔ)^|PWW{뗿=y( hC-[V驿 {@17440Ɔ=`bb5555eUsQ  62cdܽ{7nj ďA@`| 0MU077ɓWV\_6 @ˏΞU]F!!ׯ?0 Wի/z97@ `)ِ=Yo||拥Kwu9bn@ \66Ι_~pm\\܊_~9 {ķv  d@j8bPĿ]` ZZ dϐIENDB`Docs/Chm/help/images/b64x64_file_locked.png0000664000000000000000000001001213225117272017331 0ustar rootrootPNG  IHDR@@iqgAMA7tEXtSoftwareAdobe ImageReadyqe<IDATxb?H8 ###vvv6w\@|Zơ9&&7@/u֜ׯ_  pS$'', 48ׯ_O{57d?841 ;Wّ @,B۷o8?ƆY ) Ї?68@Crÿ@6# T̰fk>0u5##%%_ {?GGc jP@xytOG `ZlVfFy16_@)E G߿_3,> PGg@BPcC%ucL4b, i 0ِ @L@a# y$\4uOEN 0pd@<aFD3e.Ɍa[a ?U@1Hhlh` m  &bBK"'n™BT-!E?Jca_ %ǯ( +\Y 30x1|ȀhXRp@7BHm$=0yxsfdcd`afh9"L:RI R@161Q=(P@, >68 Z\  V0=< " A4ȳ,,, TAb`5 >zd@,h 0Oƍ ׯ_gx% Ƞ̠V+ u Ma,fbb'O2/;֭[GT % f JX۰a."06YDS[n1}X r1(**ժ0HJJ0<Ǐfr`ؽ{3ٳgLMM?B Hn\O8 ]4Q$P +þ}GǏ&}` H23ǽ 2b";X7p~+s0pp3`p8r$0} +L@ɿ@~?D?[| @m ?6^#'A1hk1pų *D\) X<|?@MzSyPL֠ÿ@r00jՋ00x27ii ?.e@_++ "ĖP/, !r30:3} B * L730=4$U00b<03W*qe"9 gK8C=@ Ɲ6lO&`uhifȐa<MHezDQSy@,@9NQ2lܶqvS9Ԃºf,@$M sQhI?RAO ?=Ɨ , U4b`?*CDTD#<A ?R``x_`GWH;w ZIXJDJH, 0E?/e_l10NXcv|Y F:.`bbd@] ~ΐ%(栿'@3=JJ lJp?++ l4?m良V&h*u@>'88@c# EF8°hܰAk&B=g`4 8G` i0'M,@1C{j h@ѪAf hb[BJc+CLv 4Vb!).sC'(&(-V\ 8 A` `$Y#LX7OB<*uNo> y?~"Pۇ47_CHn A8XI0a 8-gdB^[ҟԠb n \ZB(ALÄA=v&ݫЪRD4LfL F b"%B_W|{-\3h g nwƌ-"&adA3M hcc, zQFFf0UҢrg 郉Ӏ,}6h(h3r } pmKS ܹs߁@?lJmO`Wo}XaHmu@9A3ǁx/_L@; b:5h 0y;?+@|?G4@< -$ P ] TBIENDB`Docs/Chm/help/images/b16x16_password.png0000664000000000000000000000166513225117272016743 0ustar rootrootPNG  IHDRagAMA7tEXtSoftwareAdobe ImageReadyqe<GIDATxblUgؙ1|&u1[V3e@, 8ߌ 1*?)YfPd2cY'V/ u4SFIfk|ee:;ÅG5ew+L~#3 fbd`ddڣ.GVp]|vn%@OA  wJx T&KQ? ?}uϟ eؘ կ É_ Dd%ąĄxZ0~e`$4ňH2uE(mەJE)uccc&lIENDB`Docs/Chm/help/images/b64x64_blockdevice.png0000664000000000000000000001122613225117272017353 0ustar rootrootPNG  IHDR@@iqgAMA7tEXtSoftwareAdobe ImageReadyqe<(IDATxb?H0@4 F|Ј@#>h@ s** h> AuC}rX0C8IhU səyyw?j6r Q8hE)aO~~nnsNNo|0(C7PIhi4C ïP?Co6,^cuYwt}!'gHq+w*Yoj6GWW.G0=s20b`8DCUE 98$Āfbm- N30_aۉ˟n}{ ` q@ ĿQc^dvvv;+GG} ݻ bp  I" erawE~W l_h%0|[ݵݳo@$@?$dlSTufz ? piS/2\``8 i\QagkĠ/_$\nw 8|J/ad`pa_G/* b P`&\HQ3ٙR}xypC=lq/yP > ܬL ? XE`0 q7$B ?s&`@2zs?s% ȈASRFF>(ABI qPy9`l ?`É˗.20<L N##?pa? +,߳Gd`fH%~A 4w^`(}  -"@o*`{y1=\bAe?fm ).  hq` Y@dY`2e`|BMAZaǩ 3E'0VxiH@ ,A@|X, Ep RUidͰ`5OY0@J9n0D0X T?~_13؈3ae?~3x/mL% B@ u5 u8 .0,@glA J fS`U x+cb0d7!5-V+E Af(c >(0L49x|=C @_5p.B 0R?RG1Ug*Jp00\0e14d1a>J#"A!]e.';Sz|C<ZȽş䎬r@y6 ]B Z S-TŸn} 1ƈR37de{)/ 9^/450CGkƖ= 141a`H2e`dl.#RKQAxaA* gNar-z~1#:ao`xh@,hc7t@7V$ I<%.`1`{ 86"%,xlO%1}P[ W:4J Y @1\`;l3ragȰ21K,#AY*%8ep#/@<:,0|z5 C1("+ 0Dz ى :H0e gbL;7бPSR@w1,e:3s`_gBR O ?34=ð [@j3lTf`PP_ gdc4Ëwe<DԁaEFψ#l@|:C` DeLc-K 2a/ !D X 3#454b70 MAL8+Ps2 rdMXCiY5``#BK|&/A u`ypC_ 0b@2 Qu=QX>Ss A÷|y̠* (ĄY 30i7r@)9İtg_ d P<_b_ 6fh';3dzpi`,Ps,eefcå{'?I2HIK0033cLĀ;@ v>~~ !! <0p? |@x#Aݮ?JGP]RA^ܷ?Φ`]{9j? tۋ/=ifm+)u=q"?@큮&M<y`  ו`01d`ggfi|t ޻WK:glhc_ 4/cʅ/lXy l쐲(Q4w+W?`}7ljxu b2oزi#_+@~` 0^pN0/HXF  ʲ B?`I%t`V *Hbb"&-h! ?`) BcPi`h>.Cg @ X49wY4Mȉ̬nFv Fv<  {ngTF ./~9J_@MFA, wH@R/" *NA% Å~72K @[lAvh]` 8sp0|J0h@lgð IENDB`Docs/Chm/help/images/b16x16_kgpg.png0000664000000000000000000000124313225117272016021 0ustar rootrootPNG  IHDRh6tRNS/XIDATxڕOHSqǿgn6f3My(B/R  VK**R*R$5͍iss{{:4/|)&v"+ύ;/3Fw#rɰ̧Ovl엞+9_%)?Wwnm VǞ f4T"x nc]`"j=k #Сf|MbhԅR% M"LyEȭ@L%(otm&r+7OE.VTΦEw{yÅG/OtP^M{>:&Ѹ:(,'8٫з4׮ݗoI#C(wvquӜ3g[ոVI۲쩮Z;|N* 7*2ey/–C˄*n&4f%84 -#u Y/U^A,aK-G^&um~?NM[rˑ}w۱%Ȼ@RĢ -AQfXADĉX&Q:$J N`g/ΜycgNo{-G?~7h@iDmLgYbԎ㹮֨Ifl-v-$hU^yG#/\_~>v7}0(DbюBɅjb-If8%`_e`xIf3C03(+n`H(>svW| C=ٙ]R$ |Ω7G''uЮTz˞BTZ1KRDF=uG5qb,ae%nl:uz/_|?+J#;{ޛwMeI!\L7?~rdx㾞C{8i$Yuzrk'V[lͅ^j2f b&#la ࡿ~lӻロoAjDD@,Z)D|şk>'zD >_=vzl7]R޿a_@ދӵ e"!b$ Z E{~s?Pԋk^lxw1d"X,^>]_rO Z+O'|>['מxy{YD\ z=J 1YY& Sڵm=⩥>7ӿm'>{2Ù@XJ]}9kRcGz-ڎ_5n'3k,,QV䮃Jd,XRlNk7Әs}{72㯿qwo[#*_pD4 KG*ViW)(}"Q D\G.)L2:^.z3bvTn>jR+Č sͲ:cO\Cxco3v@o%cXZfљrgB`&DdNkd ٙ63Vڹ5N3BT20&"ڜX0[j ~̅;XX;C l0[dKXϭ%fJz|GkyJa8|v\kB"b[{ Yf:qLd(jGW^_~S@ww_RhXbefIB\>z'߿4>][O[.>zt ۷vԹ j#efQ, ƒ@N#g$ڱ&%Mk]glN4/NϬdûY[Gρ10 pB }[OҭeoruRl$`{o1כeqT$*JY@G[\*EeǨ`,0+"ݸ8;ogϝJ5~WZrp? ^\[ŗ,E3וmfkϟiЖUMF1y*TτY.WB܂S*Vv8ۘ_BepK?6S]4 : RPݝݥB::$A"bF YjVԶb+ %fb f"&f`v҂, xAUWřF[)rZF8 |-HF",l 1稑"Rێ3X`b+@RP^EIjAX6XD$C(͚H9T,9,A!ԥU.ERauzn x4v%$dvBZȠ!kԌOO:UIBllEuT7Y`X YYqruqfW0tr-q1,^&а҈%aT7.f0LQDVZk%F3>{mЀBjǙVQs\\4, 06vjb,ȒV9+kU,ETx’f *=vҶS纭b+t"AzB Bݛ}\uÞ9JLYJZ+}LҒ>PF4#aiQ"(l!kYZiLYs0FeV.$}nOAbvR1T1Pv zޑ\>ؚj#D(|@Ggn8wՙęi%Q´\UUX J1Ѩ㧩[T%P(@, 0 Ö?`[:_=x; +2S4F:Ae$kQj2D@aa\ V 0hh8]\C^'pQ<1,  6H$dPVaҏ[251k˹u%N2N(M~*0 (W 7"—l2ZFLno}3ޘڐIN^ob>ˏ]93m+a8IfԴ4I8(Ef6reWFH.AP z V anKJ ] XozT|/ϯs_)x(M6<ߩu;שּׁ%${sjGz]" %PK$KU.%[ЁF"u~tĥsgk5[C=^fRՌSkt&"2jTƉ\ `tKI|1B]Ďv>0 Ds]ZB1 T_B/PJ5Bn݅A.gFtVY;W/ln,.8P:ʛnD $Y"fFK\JfVBdC-o|/+_1+r Z5Sm#U!Ծe?l,ҡ9ҋ?p{͋=}~yͬ\iHȖ\]mZiՎfX`&N9Z;\?^OM^^7ATݷ-]vf~^X/FGN.PdNwCSVJ!jPDadΥy{_ȇGBzzo|7̥6uZ+8,@d%f@ Y6zczWw:s?w?xƿ-g.U?{b Q%۝.ŜϹax.j "d$&eȬ7a 6sܾofy駞:Z2F\F%XZbuGs.ό<4~vej67\\nUi%]U.z}`~PylWwܹGht-(ͬ1$Mu n|{_<2wtsIENDB`Docs/Chm/help/images/movepaper.gif0000664000000000000000000000205513225117272016043 0ustar rootrootGIF89alR \BDrD|4BLĦt2 ԂbdVD^d|jltFTZTlrtn*4&$FLTNLRTLNTD:!L|Wx||{Nc>|>N| 8PnOt4?>||  G!,GHjP@"+Y*CI3z$D a Ƥ0!K 1A1( ꂅ x JΣH*ݨ&4a(" J RNIR,ђ :E% NxHeD}iN^BU$(]zdM`RQ!!ꔁ>I@@ꅩ3JT| KYx ?x o6:qAĕ;UʬYh:( E +"{;Docs/Chm/help/images/options_enf.png0000664000000000000000000005061013225117272016407 0ustar rootrootPNG  IHDRƝ pHYs   IDATxwt\y/>gz`P̠77Q"EX--׊)%oe$^Ikgt-E.NAb/ H 픽{f0@,E 3s>a__ B"@)FO!K{ O;8{MBrҿB0&t@Q!,~c{`br, GXf wvQz,%fv@`! mLλ3OKٲPgFB! `7R1E,XE-ϜW@ B BHóOY *+Eu4-mY 1ADti!yv,3Ba !! QAT3Mj*.z-6[)WNe1&,0 Aanð,2 0YY"D$9Q@BL5"\jXDFĢ b>>r !"* CQi hQ~ӦVV3۾}ff_}vz)K+*JJKg6lhRT FXJl:HCCMEE\]9^àCPIJLCC5(IU*%B&\p8l( p8eD"'& bJAo<9nG4TEx2( XA9껃iR$)"L*N^mqfsS?dҡpd29׼sDB}FsajôwΎS 5n{v%BY%H675̺2i2 BLzٿotdpn=dNhCC^^76>0;Z.LN͔Sɔ-+RL:NXmin8k.8{6mjd==D2f] d2Q{mnnnÆ+]* VDQuͅeR ɤWUd,D S`s(Bx X 1!E.1Ά[_?5[믞ڹE=~(*Kf !6 7B/:}:ATσYiHC `? ݃qib0yQ#e%[@!& gȁUYW Oqܽ~BhbKgmkG`McU8d%_-s]R]Wm-^$4alk.&+":nCv @A3,Zt*hbB!%+tiBK7M)`*PEpS؟@znW< ڃXrT*YQ2Y}҉8#K{;njӥըXXy v(b-H\4܃!a*eƢlBoM Ld2?JD(d2 d2Ui-;v," .\luvliÄ g{^8lop8L!jF'mǵZmq܄wB-U&Bycr*RP6#gK?+olj4[nEaQd2 !NAb)Rǰp8Yy2!:ufÆ áV yOєĤL-4SSSKXr,g;U'‰0/^J$6mܪjWjo &cΫ>L3'6oQ*|T)H? )QkV6uekW=oU `b?֭[KKKs'H*++wA :)h+c$'s9422B=_.Jgffl6B:Td9N$H'7nHR>oxxs:rȑ#6mffjfffϞ=4͟ye*mbj|ZԴ+n:00w3ghX,f#H(R*Tj֭2WJby;|[ߺx׾X,t:[[[Z[[{{{~#|6$ʪ B(&lİ,98b Rx<޸qc$X,}}}O<my!uy(LX,644}^7SNI$"Ad}ggg:nrSO=ND"---6=A W1nollq\A .466VVV,;11aZ-KUUȈ^c8"$, ll8۞"7= Lo0Nr,rFA5w&E:DeҼ v`EELf6nXp$Tʥ GJaܣ89D"wE 1UWWE[;Py֍ںu=جuÝuk<|"9yB a ! x*ƨ*Z~iI\P k:= J$L<"Ykβ,Nh -c)Jenx(yד(RV@+WEj=#}sss%͖YOKm") .x<>ozzٯ>`9Ǔ% ˕AXTWt:=TܸEpz&CEyu(B r!w@ +v:oZA gϞݶmիW8!ax8{JRT2,ˆaLv o޼Bqŋ_|K.)T*P(BBh9JMLL$^>55544tA߾{6K\ eZNgEEhcc ~_|߾k??^^ t\b 8$*Wa N,ׯ+gtz1ԩS>w/XCCx }555cccuuuTuuuAry4 B---W^r\O=T0D)˗/B!>ؾ};B&uwwswUV[RR "HEE}[A?D"@_z /088x2K,%|}O:CV&J5,o,ғ;!z)gsod2cB;癙Ja$~;z=5jidd\V&RHJ DE%?]]P^6[q%eBh2W G**:9] Gb.1 6?,&fZ炏8O_J\&{h+K\qi $X,>o:]*Ѽw5H ?@nk! 3qG"@GGǒf姥f 뛟_*z)y?G>h\;H_}CCw4JjE1JwrF>dO XW?9ArshkO7S!FRcvY=p@GGR4H)qj裏}G}G?`08<<\^^VUUufQ)BlGJKKϝ;g28 n޼P(mfǎVСCh:>hnn㍍CCC%%%7oޤqHdvvv߾}ϟw8w;~tttaatnݺKHx1]kA@^s~3!]-[+T^홫5j9#booxee@MM H$t*yHDPD"~e9+))Q(Jrbb-K*ZXXh4Z}Uev2 xqDB&HvQ^^Dyy9yhh\:., *aH$aÆ@ JFapB(&L&3==:dR). Xr]GO_IS;{zK+Jah2F"[ZZl6lV(*$O ryy_XXؿQTDbxXm"`Xañ]P k BHD>? zH*n[2+P]"1R^W};:}<\^*r _P*EZDQR*)**2 IjQOb<_"m߱M&gCokiP"Ԩ@`0UPJ DQJNgrY"H;oJ4n[ӹ9OCp x BO@ azzZ)Q===g||0(wKt/f2w Dѩ)ABWy@:PL&\.?{,ƘeYL6<=j:ǏFBFxBWœW,_^^~Fc6#l8eY\NA3&q$^H$>jiqmmm8^XX(--t:QzZ-f3-0TXaF!zBv=\|Zs<5ɤZoם I`a!\^^yWo̥OBV8naa`ZV+"}[n!۷o_js߿?& vbFR"dVS0BN#WipGzsY,((q8|D2'n0Ja,:1REyVs5 _Dũp>&bYsKBh*%^gsvpj!-Ʉ=txj8(S3n__Dc^o&Ebq,H~H$d8W[53 4ʇ~wwwa^{m"\xhIo߮A!I%LifJF TJy4iR×Lsv! V]7LX&WhJ,fNWTjZPttt(/~o`hkk;y$˲/7,**Y{y d2\.z ht޽'OJrjj*Jt:z)w;vԀ5 ۶m;sl>uT}}㩨͛fppc<77'{^{h42 3444??o2(0{ȑ΅M6]rѣfbbd2qGsss͕Agy^!= K,c6zU"b!\|9L^rg9{,7N{>/FNٳg'&&.\xfff E&9z|t?~߿ѣ󝝝4!4;; s:'LԩSccc~Ç{711199yx;hs2QJeUUVV& O{ vd2eɷIp,ܳ딛 aqM(VSbcɥ5Y׽!SZBh(mh-kmqq1]"Ff]?jvvbP/,NS&t:Nǰ\.WՑHc,Hdr:C5 -KJZ'J$D"VZZZd]TT(.\36#/VNjLOOL@IbX,tD" JKK5^mddD"$ iMjLFRzZpkrrR"NMM)D"1>>ԔN/^}vE+uQrhE8o4M&3X,L&Zi V8eQKŠW3,C-M̌Bb4.H$"h W RV8Re6T*5%,H_iΪ(r\Raj4J2Lrvv4@VݫTS$XVZ]]:ݣĺ0H$]^VV4\n0n,%@nB~:40lkIa<-f:cB9 ?nEPк)`,W,O}D*'J$奂nW<̵Zt&eP{=~w4TJ%L&SXN.@&W [Q>ZdyV2hR0J! dxBjziYe2fZ,Z8ar4ۑRf3}t:K$Z&P.{&"!eY6lJW\)))F`d2y<L 80՗!dffFTR0 VVVs NV!qUTTDkS-*..v\J&$/hF>⻢x^ژVWT9zRRISPz^FH$MNND"AcimwZj)sC2N3f"8h4iZjNMMLP(Rl6-m4=BK`?a Vad*UjVY]2 BJ&+Va>?1`Nc\UU%ɖh4Tշ;KOWW ˲ d~խBk7r'z?}?kP m;>sҕ t]Nӎ,.J^-=N>:??(ϏE]QawuQNJT&J9 qꢆ)fq۫h6m488hwuҥ[^vm˖-׮];| >ػw/R?я$c=F'Ӧ.ZŴZimҪgwkmm !ptvvL_~; /?ݛ_~_t8.\(--/,,qFCMNj7T_WL& ?痱w,c64jU< Ǝ;;F$'Nkڵ뭷ު裏WÏ<{ ;;;/W_h4^ 0ι>N把 ;00S__4==cǎ~z痿U\\d~ݩSt:0cjj_pT*E88իW/޽>ݺu+u|_=}tII >211j1Jذa;CqϻĺȒI$ 嗎&=z_2glbnΝ;rykkؘD"IR4gƍ~zmvޝ.TTT$HnaVK{ۦN@ONNwΟ?sQ$GaY*_+@TVWWSw5]žb,k].]~vvv۶m:nC%ɞ={Ξ=kAڰa޽{c5)R޽{SB<3GL_zj?ݕ´sn+6f=_zHHW[GiŘᲲh, ,q^Vki^ }3IIr:/n+ c>'q} F'ڄp5W^~VױʶXlunO&Yʹ<ϯO۬T\咳tc+\cš@)T+2hT ƍcppZXlff!T]]M ]rOl޼y``@V{<j߸qcӦM݇Va,h4mmm/2B4𦥥ٳ0Lϟ'TUUz醆dd26ܹs:;;Kͽ 6l6F'NwHSSY^WTXp ~LAV+XtejvttN<F%Ν;}ݪsm۶󍎎>#G BW^[&˲*L&& Quww755d277HRxСC/_|^}gy& >s?7 8zYurd2?~|%L2 S\\|EBȹs(bn7-CVY.bNGC=zjR544tAm6z#7n855E7o|ƍ-[:uEEE۷o߽{wH`JZΚNj󡤧O?s'&&\.?~={b tz֭oAኳv}vvV޽0x|֭drnn1py檪*yWRnjⓏ*`4QOCVҥKmmmz>VᝨpW2XݷoLN t^qw`pVG ht:],N0ۅ{@(Z^=Ji\;N4^KN-vOt\s*dYV_QV~g#z/^|g{{{333/_~G3^wynܸ! ^zk׮nذ͛reJ۝djjj.\/|??hm144ONN'VFd2tO>G}k׮ .ݻܹsVof:zO>@mmmqq+W\.׆ Μ9Oxui粒@ kϞ=.]ڵkױcǪϜ9CuyLfۇW_3O$c1ԏ M"jqA@_͛h7(++ǎycǩ'qbbbzz:FGGm6OSq-_Wuuu`H+LOOG"~̙3sssÁ@J2 ^t?O2__:t護JR===(;vO^{^FEEEkkٟ |o{zzl6]s?a2|嗏9dsssx< ׮] +BGgʬluÑ^u B"BN777ZmccciiN9ҺVBi4PUUJeEEEII\.w:5J"IDAT;vUUU555 ;vlǎFsZ¦&Jo>ZM]e˖-4'; 8p P6oެV)ĵqFfX|>_[[ ݲe 0~llj*򙙙*qc=vFÑH$*++FcyyR_R@ h2J8eRLׁyG|w?͆U¼b(..l K#E"Z@(-,,|>όU;$g֖b_u`KߎMMɧ;?}>[wDn]V*r:###k9G"S|RL&355x +_[aDb+)铰 jzJAp֟sT*%BޕviNN:N$wqF:ufΜ9x̙3 !F7lebt:544hUzǏ[,X,F~'=䓡PuxxL&l6ۥKo:;;iiccАju\XO$,c6jU<y^žT*e.^ KKK7RTR|`4EQT(HɓNFcE ۿۋ/N^}o}[`ʕ+{^+)) pR###ׯ_okkkmm/~pʕSO,4800pĉ۷ܹ_un H&xx&>s'O6vhP(D<?N%Bsss(jllb*e2GhhhҗRrbTh4*"gyňF_ץRO555??st:>44TYY)C\OFh T'OKȎ9MNNlH$rE+477333'O8|0`||̙3'NtN6??OWnbۼysGGG4zE].WGGMHӄqoFCg^b\z[IVbqL }w[ZZ6l@HUzv]N>/|vooC._ZWWwC\*//ZVVz߸q'aϟG=RG퓓V9ܹ3%)g,e_iY7nܸ͛F{{;hii)-7?.p݅}lO mt~U_Zbk\J%ςR]wD(b,bwu?Mti|{ o.ߠX"WU#QfÅlOf/l2Ѭ7!B@%T ZlʇHiv贝9{H-E`wCڙs{0&Ru0%} z{{\299Y^^nـr9ΪO>Y,\0,@QTMMbQ(<ϗl6L;33c__J"?=j2Hݻw{zz[aa(`0ZV p8Zh4޼y`0Ax}dz!dL&S(~eYTY^^{*JV*pcv`+_RI|hR|>_{{F-++s744TWWg0?ݭP(zzz> 9'OdffqDz-((BAÇvwwWUUFݎ1'rt:(QRRT*E"PNNpYY=}4?~$Ix<gh4j\PP is:pXPy&++vvv644|AZ %j#%y^~)@;}u:]ggcǖ^xq_vmbbgΜx]qq1:t'Nd2Q^^v>|xƍҬ,ԤT*?~cNNM---fH`}}ϟ8ZYY)^~ 1ق(¹9peDJ`JYdǏڙ)BPcc#eff&Dt:*h\pV3ï`JW}P*dmW@ ;w.+5 E"QVWn)Xѹ\ɍ@F;2s4NE1Vh~q/.9A+lkk+DzljC}@ӧO/B cLOSܷ҅ ....vl.FAӴ\.ꌌ Z]] tE~mmm HAÂ*#w?77ɓ'{{{߾}RVVV~t:iX\\h4_|9{L~h).Z) A+Ԩ3"YPFfUTTX,1PY^^6L}}} 0 ZCCCpꚘ2Lkkk3 Z2 PR| FRԽs=zŋ/_dbGqܽ{={.ڝY˵* s\R @eeeVVVkkT*X,---AD\=@h<Ȳ,T nzj`sFF"0 q^d,˺¢"Z]PP 0zJx_TTDϟokkr ;\۷oB 83%%|)Ix^BST*VHt4[>"}*Zrz*"uķ3'-HHHȰqJ}}ĆP̶b'&۩<owDHǢ ' ӷ@WTC؊\ XvZ@U迿BgqL 0cB]76%>x;1,wV8_01&0!lϞxu 2룀 - †!U]? @$"IH)"IDDrqcc0q#'Mr6$1y>-ѭ B$ID," &N*c<DžqADҾl3s<*]bw a~DETDtlBmhm01yNدMz{$II^R² <C¶idx~u;7{KIENDB`Docs/Chm/help/images/b16x16_window_list.png0000664000000000000000000000162313225117272017435 0ustar rootrootPNG  IHDRagAMA7tEXtSoftwareAdobe ImageReadyqe<%IDATxb?% X"3V_~b7?Fr-6JJ?@,:Z4 H5𗁉7# iqy)qQc#_| X/7_ C@z?&f& 2d~OVEo Kbaaga0PbbCNab`x5nn>?|ڍ^b_d@? O_1H2kps0} X~ @A ?~3c7;ñ~ XcbD%#h4@ ||| * `|WoLp9?0@/6~]0X@6#0p@9  ]v[+~wnR6ލB`ll߁ _^f`` ?~1@ @Oc @A @,5!/` &@J8 1\FثtO`r: ڒ*aN >SP2hP70H(P 4/?3×@ ?_K 3* *pW)pԀ ~6V`X10@APRCCASۀ셛 o=dPg F~e)!6N65HٿAyfC$5夊\1IENDB`Docs/Chm/help/images/b16x16_konsole.png0000664000000000000000000000125213225117272016543 0ustar rootrootPNG  IHDRh6qIDATx5OHTaϽCF%(T H[C"(ȍAʭE JE"Q6Akttf|o}-Fυ{ˁÏ>y{3Q}'\^jimAecm[ZkF4C):@7$co0Je[*M$NRࣣrWWRX,zEQWk0 l0M"4*Ωɵ5?ja4ř\B0ȈybHS&lYHnnn8}]Yix   bbf,m{aa ..vK{=@c&Tb$ f@JCFa4pgx-f+ϫʲ &ӐB@C lAylll{{;Ugfn. Cd2$HSɂ4~~orRXVY9e4MZ-}$ $bbR\8vtx55 ^⚦`N48}? (u:|1p(Qt*RZ+(M@ >]3\*VT(hQ44t?* zIENDB`Docs/Chm/help/images/b16x16_chardevice.png0000664000000000000000000000177613225117272017201 0ustar rootrootPNG  IHDRagAMA7tEXtSoftwareAdobe ImageReadyqe<IDATxbLKK[wgg`|{:߽{ĸk׮l+V``fff`aaWOqqQ@[nJիW@?P_~ @@eN:[>>~vb<<< `AF~o߾]     g| >|`xж ?f;Ï?tttA/ph#HǏ4 @񕁑/F`h@HsA]pEw@ak?2Ҙ<211}@,A߿WaaaNNN7 bl`x{5 e96>p X@1vdee$%% W3:3 bnY"(@,@11]wNN....Ǐ3ܺuɑƭ; 0hlV7 /^W f`ihh 0pppg^32hk3 ;bu2!~ ׇk?˲eKR 荿L*?~djnnyIAЂ?X2|agX Xvܸq}P!4~q!W;v/220?KJNQA9jڠh_%D > \=ғVTWax012<}aú߽{ @0o߾.={[Ǐ3Z{׫&&`gd`eeJdbbՓ_J0{IWIENDB`Docs/Chm/help/images/b16x16_openterm.png0000664000000000000000000000163513225117272016727 0ustar rootrootPNG  IHDRagAMA7tEXtSoftwareAdobe ImageReadyqe</IDATxb?% XLLYIY@eBC!?x@,\... ߾f'33\FFF Ab;+ {7 ')Rv#( l( 3 O|u X@ >} (Šo/BF ,L 7d Ynk@_88N=p|I<7@7&&+1\j@53gEz X@ Rcd82l3O __|g1Ȓ/?332j3<<&)ß| ^ 0+;7'+8L@˟8N^> ` OB|W_1 ?Fz?P eHeaù[XX999X89YYAN?y,^psIWV0|gh`P/ ;?b ;?CE @ &Pg'"8;(; ß?r [g3L@;?p  ,α01˝~l߶@AiH5f lW @fg /f2IENDB`Docs/Chm/help/images/b64x64_kcmsystem.png0000664000000000000000000001535413225117272017126 0ustar rootrootPNG  IHDR@@iqgAMA7tEXtSoftwareAdobe ImageReadyqe<~IDATxb?H0@4 X9tg6uL(3|߿  }} @e'j_ _z|/_>KHȀ/`؋  @I=Ĵ0琤X_|RoG_#}07͛ _?g5kܴi9ŋ @t .?c6YTTXeJ oɉIZ z)0)<7> \zWѣGqAUU`s##S={ x@t)@I\Spt{%0%iE;;BY))aVVF.yyp` _~h 2 A2`6K3Ƃ߿ fee;d`` P377dvvnn~ ¼hY7XAY΁mD,3prgjV6o߾ihh(*J3b߿ Xgf`./ȃcx%ûwe, pP15bPS[4,yIb~8KzzcbTW)**<,]G^[wU'##AFFADWnz l3|Z*@;0jKN&`۷֬YS:QQq%%`'%oPx3R2iA~pc`Ub(#ҥ g^[w1ׯX@d"?09-)2,X0sP**ZcA#/sOk` 9991/lHP`<XU0HJ T_`q.H`غo~ X3XX829Av^)44t D!eOXS߿p7o^f'iMM]G`6rVPPfVf~~`n`-fo0 ̀+  Đm n!@U '6cGMKz~0UH/߁'Wu̱\B1ߕ+֟;w;O3 e`J`/"U %%S]@Eoš !+o՚ 0D-Q`_PA`G^1|?8Y1|.)) nR5?woZ|N޵k>>zr~Akyyq7& R`@@@D2?O{bhI(l ;)See g` gP@u&@TC/66 7cYԪ~x!8XENLq::&:q606Fii}gwsԔ$L t`c TjZZ:e ݻw;8@e(5P |1؎6̀YO $?_ziǣGw޾ O PH; Hy %whSJm#t2ZF""|}J`7_ WP.## R!$b%mPij}XqՕΓ'w!l &M;7ϟ?~gV Іj'8l t0Sg!,`] ++쏫A-6Pgԕ=rμ $.0߼ylex.0;(5@QH? ll=9'Y 4GUUbZڡSMMWNMMe6RB?~f @8g +WΆpe8/C H-`)cP*@%=ȃ?Ο 1PKA6fieb ˝;7\>p [PDDX0((HBJAWރ#P Ҟw?gdfV )/Of01Mhlk` sCcK9TX]}b8w:Ug!,`}|@5xW-P 1`yjS6EPի@` t9l \CX áu'e///WpGEL^@R0#2CR`b`d 0Ga#FH.A! J]em33%l~ |]Xhqε:&)C bBC/av0 #izKdcpA o߾zN_ wv$pa/#=F7R3М_,vhG`Jw=w?%4p_yOhNPJ`BX`?$@ P@ #@)  8fAmϟiP n|-فO0K{R /;B{\|a1PBq@bb2 4`^˫ o߂=&--Aܶ9  >Kw6 U}7o^&ǯ`ǃ<  < g`.r# AZ@98XUbgg?szkJ NYYSFF*u@` ]~3p4+ RjF߸qX[~ -- Ԁba$bRR Wp rh|>|h(ә3 B `I -R䔤AyT/0pcW aꆂ _5 #O{nSɳgj~ٳ **4B CF@ѣGπ?`o޼PS` tk p}h_PL, ÃW@O"uj, xx@5+Wm`Ma}}-?N> ̿' ,Y d0|V!-@n֍)U ظÝ;kFHJXɃ!#1,H(_|/sƥmn3nn^1%%Us]]c/ bbbL@򁫸?gw< .A/pwy>L9 WEtùp?Гw_?4!FF6k==킗Ie@a hL44$=)ayP0][~IP'vĝ;w>}dG'##xM\\ *@@YY/y#Pyikצ(++G5]_DpکΝ],,nzYpBf!!iPHadx6;`ջ@@w-w>d dGP ֯_^,\?- T6:S`uo:@U.#BBnܹxR/|*>>a 8{L/_ii@˳o`7 O@@tp?Ќ, N`7ca)OA 4` JGG0<X蜄A@yݻt;4""@$P2{h})WdTQUBVXq%?z t֗/_FOPv ˯ZqBA`7XyD 2IJꠖ++$uU>7nvv.7 ` PZ;0[QQm۷/nHHHX#03/_V 1` z|!g@y6&IF }<nR+, @vc *P}|(Z8(I[[;2IO> 2}SEE iH GaPxtpl hF/A-*v ^= @yVPP DD Z z}""6z{[lQ (՟*z}Pׯ<W 6(FAٍ1>&"<EB_~yġO]-+clllel# t,3NtQSS \={˗@hfXDLLO&+(Kij!fY1FxMXj HHq\kBoP̫)>0EMm@ꀦ-CP  ;_ )BXY겙1hi)L=@-:PA>}<L| ~ALpڴiEwbDSSPUU[ ԞFLa3 D$jJuMA)E@@4x .@e C<M;A`<~\P /^t rt@yD 帠-Ծ; E"`Z0pǏl;nlSܧZ53uʅG^m`,;H@Fr %[pV&@FsYԬ nZ&==M`/ 2S޽C.|ZR@RвÇw +s賰BY}rPdCiR(ˀ30ςt..L.d T߃FXX X[(**Ι3)$0{~ pO6޽;j=y\ @O<f6cpAAA>C (!<3C ?6gp+Y{ xǏ]7a _5J?|xϴw:`/qO={j }Ay`}&+*L|`BR<@ gAfAmХ/nӧρp>}'`; .o ch]@G_G 9aaa}_ߠy66|Ӑ,6pux奁)XZq1Xɠ@{.x@r=8 bVz^>X Zxׯ?;3|SP  5c\9_?طW}d@aA A@, ~}a^6{i2\޳a  fSC_Bs@OP ؀g8!2g-ow03,dcuC٫  /p30D&{aCIX 0׹22 0?YYr 230p00l<&jvDG20[Յ _dX>`byûL lߙa?@O @xD#Z0aㅿ | zsOA XBç 70nnVO_~1|şR ۟ .F; >WGt3N`-y&+2 W3Hsx^cR/C&{*$a w ?W@. dP@E= IENDB`Docs/Chm/help/images/b16x16_server.png0000664000000000000000000000162213225117272016400 0ustar rootrootPNG  IHDRagAMA7tEXtSoftwareAdobe ImageReadyqe<$IDATxb?  ~f`g琕itrr av_>wG|!H@1 akkk##COO׮߿>}knnޙ0=€mlEUbo߾góg.cb`ddc`ff rs>};?~1| ee`cc)@Lps0~ϟ_ JJR ?fx5 3'ze|,,tqss6|  P `ddb7?|F! ?351P%\@5Wށm+T3#VNNv>>^p7߿l6 yxx=xp6?10{hWCh|oG@(y_ED~1~c`w}v1̟?Ƀځf] 2h!륳fkWW /_GBIEń^x&x҈׏VQg`akcg_888z ̴3nw013eՏZ& t U5>bgAD8C7} B wVZJ =::z _s~f`_/8Y˃W} )e=޿IENDB`Docs/Chm/help/images/b64x64_kdmconfig.png0000664000000000000000000001652213225117272017046 0ustar rootrootPNG  IHDR@@iqgAMA7tEXtSoftwareAdobe ImageReadyqe<IDATxb?H0@Ăadd$ːz%߿ǝњ}|m[,Ĉ\~WRRef`'÷O>=/^xӏM=q#!":vNR[wv}g19%F6?`R~xpE0ܺqy ?HJϏ3Tt|J$@:~x/ ?4~3 vsɧOj~9Pwb!Eô`q?l4Swne`z#P h?__ L̬ Ʈ ,+iO@x>P@Dp1?бqQIe`&o`lpB<(H12C LŠ *#-[/eN*x1 !fTIl#i6W 4 Xo#(  Ũ%ԭԴTxJ@N _߽uU 0X)$= ,(@pX& _VNNu[[w6xchyIP Rbh b ߡL6 1a`dgflV@'ohR/m:7NZƐ%C(< abbs'O0ưao 379@`W+BN YP˺gߐP?@@R D`0231ˈ1h>TebϘfn%cg"&T ?#VuXoIp5͒?@|$6 n>^vnA!H?41 IeT @5@0H4230pr<0~CR_Pu858u5#7l:}vmK{V&@,󰳳1b\6~@@oF 㐘пp#Kn2(*m2'ȌR(P} ,XbOc067ɴ)  1hAC<G ZH_p`Cޭ aPT6bX0ENo,oYgav.%Og4^L@\@ ~ϯ!GAYWH@R@ ,q0)?g)%f~N&~`p`nXYTAA@A (!Ĭt(ӷ_w>~(9e0߂<,c @ {y6 Bu g;\&*L %҇fF^^ބ!7K~N0@4p[`?`IyD` V/80սx=Q7/6{` ~ U&g H#|ESAʂ+L7 y j ̰ɭ߾}zN=7sE0L_/`, ⿙mHh[(RK? p xώ\&63#2Php{_>0x a뿀W>2|׳7 R 4?*T))3@PSNAYN\XKS (%/g0t;ݻ'wa1/`=,@yO>00}!L,,H鿰@߿H^"XGFEGG̸<@9Omэ޻jԂb ?g?0|z?@=0 Bb <#ֿqHS/dgaf@? O(BQޕ :v bz`Ky'lL.}|ءbcx,%iHψ>liHC[@Og@4q (&66 qKD8:8٭)WdpR /0zAFÔ(Ъ\y0~cv^9cUL`gy5Kz*@ T+_Mb"߾Oqjsndý;L̓ l(dxn/80 @?4 7?^3|L ?Sbu#+ed<# ؓ`9C;dyoV_;FT24yeZ;20h*+bh5 L`:sAgFA` XHz~cobR j&콓^{ 3o>#CňVC14뀛yT?`[o?* *c;BUUgLdd`XxzC^ Énʠ!pkLc43%3*0+ ;lزfg%_`'?{ M~A5=dҤ/H{Xh7}ϿAy|]d^ H22u5T2*2xrmuSbef2\_ttmm%.c મ`7/؍~޺!*38z:*#:VXw`[?a8F`5_sߺ (o % Nj >e8 ;Ï_~{, @| (Ƞ!Ơ* TW<#=NgwvfPbePR`|Α`%e ab>H `amw/ jD0G N_}x廛@܅NEX#݀1 < | _|f`ada7+;/`A ? r S0cMbP1HqI33~ `fxkmeR;~A2 -pE-I-w /+x›Rx sJt8U0 P~[b q oNb\ 0 .@N v{ `30h#4N@)/S ++#oQ^Q/@02ge`0bGA=2>68Ł)X[5YLaO 3(0l)g 냴u=/ \o3|°]=៦os=;x Z"Jl: ~a6*sLlPCF?#(u? 2|~0{s5}DDx04333H<\}# %2B>_x+Dfz'˘3aز Cmwsi%\],"vN: Pk) .A>w?^2 4 0c)}&FH+/#x 8@Y78oW &0pchĠ ή "g1?uGIܹ4}f#? UMx10xcػCE!{cp՟t+l "B ߌFR_? g`e2|p<@Ag&2#rS[caw 'n0LaPb`sAQ! Pڽ  ?sX2{AI{^{3~10Æ^LAِUKw !=Ja ~e0Qf jyPۿ>?9^- Z,?dYCc 3< .l^X3u/-X@=[g2 &Xj&h`- 0O}axʜ \$ -M>P{bd`?(+,!?(<3x GEؕ '|bcq`8}=Kǯ/NŃ@O߾#x?4C>( o}p8 ën= +dܜMAU8 ,~nA`ac`e ?\% Iq@̀hH | J zn$%2jb7O??2p2? 8ـ)a̛72x![2p2pp0| 4 @31H h>!Nhb  OB 윬 -/`fJ Y8DuxǞ>wASؐ/YgRlo W/1;;3ɠ;d?$@3t )E_0<"(2yAXAN)wbv=4d G߿/ںH@,V34 r@tޑePc #rnV148 F3W_[:n~3cW a  X÷\ iP7`{qFhAQ! @J 23Vu8`3-@s.+a`ܓbL rڌ rzY/'#x3L q58@g+bE`JT@cLhe##r52e0|`Ps@Myr*óׇ|c,7+ '3'FA`Pre`'lHk#A?/}o o`+ rGp3@8-=h7~~i @SI^H]ήS3+gf>`6A kD}#(Z0# b/Z _Z?__}Dhb/tT3400|97hi-T PqO=3RuVcq4 <@IѺa/B"vn/4>C2@ 6(8#8߯/>5z~xhT“?TצCJYdX=|;:.J Djq$C7ꟷ,O.sr.9 xD&,_S@nq _|g8`éݽϏu·YDі?+wJZl: Z 1f1tM V G@3 S0\Yq[~s;_A~ zoblnpHIK)0H+3)3p 0r[ĕa'A^M }exu Ów^^~ly>@{A~ z,00r31Ef,%-/#-!l./>0ObÏ_//?202+iZl;<,g TuJ2>9]`IAP]y* ľ,4-dW`&_> o)~-@wWI7xDXڶ-`U,3;ԃm P6M@rgvNؑ:)H*\5!vHUOple|qw m,FYIENDB`Docs/Chm/help/images/b16x16_kblackbox.png0000664000000000000000000000152013225117272017027 0ustar rootrootPNG  IHDRagAMA7tEXtSoftwareAdobe ImageReadyqe<IDATxb?:`aaQ***---211Mbff`gbg1;999p{/,,tKFFB7 (񼼼+W?'O?|e`  F@<\D&2|L_xp gϾsNٳgسoe!Џύ `84 ;Vcb`d`x{fO`xP  g5h4M(=~U10B dn'Xl?ý@ϟɽ@ϟ{Ȟ} 0$49R#~e`gVVgRg3P` >gH7,G J@%4U/|Jdd$|9ðF^10ß/aepwǷ;AW+@~ LN?%y(oF?"| F fVj "\ O>dxr68G#S=1`?ǁ9u\71 &t $$6%_.1{ѷG 5? ex_@2| E @Q7jkh`l*l 6Z jɷO n`5&4-2F%0ܓU$ p550x@A;82<PσJ< <;ȊV_NSJQAWW\Aۗ.]b!2 ;vg1i1HG3ȳ(0ra ^O~3|:v Ϟ]dxT@r:>b s=r`1031K 1X0k1fÛ7o2}AK6əAINc`P=iÉL:$|ĽU}}İ~30bd8 غ`7j{! +C>ae .&BV1<,6<i1 }drs 櫛~Ͽ39F |B _֘Ƶ" ޽x@`,`6OLCi?Su6hy/> _d(c`TܽX!RNjaף kndXwy-÷/JeSA6#0@aļ< f 7bObx0/ LZ+1!)'Pg{2@YCkN@0,q"b '._btc`feePf`8z ǧ~v߁yxޫ1a(sd8o ."u`Ӳ>pB }x-20.e`GjD``8=᧌ .ä gyٞAv; bf,>1(q 0,rdpV0`dfx?EbSumQ~}w}cuVNvqdH{5fc,_aVx< )Nd8.q(1`^l3` Lƿ}`,bk 7L:p% q{25_zA?޾iM` &voO0D[R R@M2j<B aͩO T+!l~1U ;R(0(kh1yay$?ÎD? ețwl99 NF L@兙>efUd} _fn{8~2[b`L!OnsrAl"@Y]_<`̾/l < ~СV@'~ӿ2|4jcz ؙ)pB,j1#,(aagcWa`e]`ĘN\ !$Đ02*AMF1|_^t[P!Xs{oo@q~G >~Ap` $g̠ l220; _ed1X1p #^6]~gWo 3Ws3cp_oؙ!- ^!qSc`UvJ_ANBe p 4)3 ,yCGn0@-c]l(3g`Ghc(< PҒgz7-WScW ?ó~?U{2 2}a`Ed r +c$lv- L6p#FƐPeP ޹g`YREp#AH ؐATZԄV  Xbx{~W2( 0G}FD``01`Á37XXBc9=πj> `PWc| оMO)3@&tfh 0`U"@ 7<`x'm &`!A2؆ #vqsCjȀc㘁@1|<\ *0goNY 0qAFmfXy(IOѽ' %×{oALDhH7ٳn*`ÉlD/ ,U0o1{`I%#{ +B`v88z0Q=g0&u#7C;31tc$ _?2\yZWFy}1+1c0ohdD|Dx>~T3`?AlV!^`7o /fuån/<'0v?pS0|uٿ?p}1o`dD?uN+\N>ɰ$\Όh'o2ۻAU( Fy Xp򂂼 ?kp[l lZ lrz߿?nQvNf6}?fxO{,ï_^zpoY_Að2`bLcfh ˹X/bǪp[ᥨ_!Q4F?n3lٺaR=IXx0s3C _e8x1ë\`O3a` T81^`6g=ˇO^>y+>zo2R4݇ Hb8M>؎!gÕ$9i%cxDđᓀ2oP`c NbT>3|6pI+Ñ vpJ  j_? ddt/?cգ ,aGg dGGq"%5Ilfix9s& g D-^|ɰi$Gy@k:}°^1|d%qm&Y14\ 47d '޽x h`9Ow=BH~(9ԹAvrnƂ8C> :39U~2'X Z϶ ^2lb/$pMo2032daLbJrnfp#ׯcG]c|mdZ~@RJBo?n%V/>P`.F``70Jw_0|wW^1: >?4?_ ȝgXKi[&/Ý^> v aq;e&\ʰnO" xDf` /_K+3<=1@$'И~)mwr<`b0Ȱcf+yɄ_ ^1\:3n_ezOAS| e3.`cFzX}z>FW_^~{s64?ÒKa+ "w}? 3N1H8}-q Β ??0V+ R01|5o@ݵ7 gxJ_H(m\ (Y!Ƞ_FFXRFVW~1yKNNVp_ 6_A_`O O>aÇ{w HĤd;[1(8Mz¨5}e`SA.`z@y?:@{Յ exr&k K ٴD!!EKE9$ Q'~wP O@ @~ j-cN?iC' 4QΦE5 @'!`mP~@#}4@4  $IENDB`Docs/Chm/help/images/plockb_64.png0000664000000000000000000001027113225117272015646 0ustar rootrootPNG  IHDR@@iqbKGD pHYsIIw| YIDATx՛ytu?eaIHBX*GADvMu\Aqގu>Lk & IY7Ԓzy$:Իuw{.C"HR$&J#a`pj@i<A8qXGŴH4v;1p`Kbb" fN>EYY)%%AUpV/?P;u ,w /THWHWnvzTVe[-lnUeSv46ԙ*傅ʌpQ v{3(6m|e+}>!>iͪlhRe}_7eeMw儉S(p.ܹ//e}*|\W>'zd<~+z^YQu~|]v6hǎgB0b,,,dՌ?)5N|O/QDH\hBJT\hNBBBJ8M+={vǗpHq{>_~ =J1BS6˗?ɚ5k(((0>Ac#@Ux!55J*TU8 ӏ;ZgXy(6F#%JƍL|M&L03#5 dg U8+aWE1AǛYTWYn@^ӽ=磏6QXXh m~0|6ow_S_WCmư+54 3h P$( ȉ&qD9N;:҄HXiCifM#eF^uvB3!WbŌ~Zx\JAn/B¹̟;@Ok\vmZ</WUy9z&Ng|XUfSHIKhP۰)%@.ע`q|,\ȴ}~%=A;~8~Gl n}'_!vN N暱 -p5MU$L6/m|ʁ:24=nwkX|{CeAG +} EQřۇ|~qq-s;F3in- M32{o^"#+'"xcK•@l/a ~z&=L:Jf`"#We˖DxUHd7MCAUQ7s 3j ze‚7m95jAZ@Ho}q2u4j۷z"x|fN75e?'EƯ<) qSdk/*,ZdnEl9*+-,Ff>]/eO5V5-+UVfz,&LdG.7^4~/Nt0M%7CSs݊4y***k\|b  )oTT`g8@wSGҪ Tv0ݐ22xg%sa7-z{1$nO h7 F^ Y7yl65c:A"TKbWlQ- \i h%4ġz}o  OU:UAT7-kohVbGx_eJ8W230>LSeibʌm태޿:*P]ҷ&ܼ€abJoZQvf~CFt={D6k\l>2ihhΰcBJ>ifbbDͲEMbR_z׷#iNlBb@\hOxдkWj&zH[ cI\ː.2"oTBNCoNHhln< X_ ,Y8hH/v3$nnjot%M^-kO!ُ_Y/o䵕UPcymU|lc)HUz3gϘlJT;6SͼJP;EGjDB+n5WPj\:lQmWu J]ZL8% ^v+x۷jJG1)e!DR'"U)k?vlWj}w:^mK=1NCj(~]vHѷCnضyی@-QJ>޶IkkΉ XOreէSў+wPI"-+/ z M㓲‚F E{O7Q׶Yj`(L86j*&7"9~qG*Nq}3ٽsXoŚ <uG:t+ Ns?$N'ì۲&n正Y "7)=X50S7"t'g4Yi >35CL{+Nx%P#ڸzvD_ !?'V7@uma OHIwɶ?Ok|x}gl,D~NlG\|R5FF7#=.I5/yǸ{6#_=m~Y\rx>٧x/X I^gL4]=T7~NiM["L09\3>NWj沓`Hn,}{:̬Π`.Vv)ʊPˣMԻ,/Z'OŒGb+@s0?~mT$n4vJNVD %.o}=_ zZ:9]yzݜcM;2Ɖ8N9* n ШZ{^5.,|79&6=Spy\N;lvnZ߾aԳ;U)zRc)(ڲ+$/zf琐H|D47LŹS(/X 'K̠>)&WH}:^K2Ww W+/%Fމ6|?!((5IENDB`Docs/Chm/help/images/b64x64_kmultiple.png0000664000000000000000000000243113225117272017105 0ustar rootrootPNG  IHDR@@% tRNS/IDATxZMK#ING D%ԃK6s=F3 ^"H`v3 {8d4tЄt]] kNyjAG:GـzQ^u^1+ i/EZ,4͘A0rRlmme_e4|>???aOf`0(s)twwA0C7>eYFjhQڷ"cicOEQ:,d潉.q4,#z1d9GKp&>0\hCH!臲{)=#G7zq۽p8lE211J"/"y#TU$j5+Qfzϻ @ 6f"1A@J_/RWeY,]8rrb-ub譹SUATU B[F~@u]UUEQ;zG1gcusd<U[)= IJ=PVpϼ79;\t5?_a-5sBYzseϡ3 zY 3v5K#jLjr0ےLb'6V; *vYwp'vF.!g!B~mM ?C&{'@.KUge=Fiَv}4^O$WdTZ; @cccggg0RKb~uuH$.r36YUU=>>N$ˊ(Lj_*NNN1 tH$d. UU]ZZZYY4NBFz4f1ntXQ9$EvW?R p&Ԕh\eܙ_nr =]#s9Ֆg>DnphWj~蹰@80Q R72!I#B( zH$ryy4 d4Y]EnbP(DU/~vEqlnK߬/_FCQip8L|17w:S>AIg猌IENDB`Docs/Chm/help/images/b16x16_keyboard_layout.png0000664000000000000000000000127313225117272020271 0ustar rootrootPNG  IHDRh6tRNS/pIDATxmOq?+}oPHC1!DNqq0Wc!$ėHbB%&RP)-PЖ׻9g~! n Z>d|W-K7>~:&G=TZK%k0ߏalecW۹0\fvA3ϽߏO B|":y$!W6Y-ۋӍ빋?W_tmxl4X{*{+%PvTʫܧfyTd-ri6g=iU{ؼ1 n@'p@#ƙ جv!kmQ"p3x7,F#*30Zy}p(D" j:78 As$,Df"! ,0tN,fNED6_*ZMl `n8VI(b :=~mG=-ٷ?]V(b =IEȱzy09򰼜\_STpnDr1lffd""@DtZQAS~cIENDB`Docs/Chm/help/images/b16x16_rotate_cw.png0000664000000000000000000000150213225117272017056 0ustar rootrootPNG  IHDRagAMA7tEXtSoftwareAdobe ImageReadyqe<IDATxb?% X@c  /37ߏ3030$ J,Z~ŝ) /@,(9ۿ?ʂA._5kWu< F.`)-i'v =@A\߼4@yi)_?101 Tç? ͠)e \΁B" }e+ë'32 /+ 7N7! H 1} Va{'V]rg>a`a?@ O?~2c{38 (l_2010?@`@had@nP!HX lϯ y^3Hex $KR"@/Ġ 7\@iN|I ^O7D#S?3"(N"P$ 6z˖<- 20}!> `Yv IENDB`Docs/Chm/help/images/b16x16_help.png0000664000000000000000000000143313225117272016022 0ustar rootrootPNG  IHDRh6tRNS/IDATxEKl qmwmUUGH#HI8уGB$yTiVGWwٙ;C8ɋkS :ӿ{Q;PƩ `wKR ə#뜩SZ[j8z5;;[ he22Q)$SFЭmN?Xѳ6T-g6;2:eFEJT3CO^KgHhcGPtsR[tA1 kV!0F\>#wl5b\?% -4ڗ) f+ ׌~ܰC !S,{`/kDө]%ijBD;;͉Y (łBbN9hvo; q4A;?.=5,ǴuF*@eN#1~'`=aM'OO9uQ`T@,Shk(A(L:'CqǙ 0Sx.`gCv@o l(qD%LC¶*QlYw"jZ[E.ā&}ǟ:M̲`w[!53=+>Q#6=vε?%Sœg_}Q._ʺSl*_ھz[s7& @pS-;xG[(ȤZcIENDB`Docs/Chm/help/images/b64x64_usb.png0000664000000000000000000001112313225117272015666 0ustar rootrootPNG  IHDR@@iqgAMA7tEXtSoftwareAdobe ImageReadyqe<IDATxb?H0@4 F|Ј@#>h@4 X` FFF1?SfM oJNU|by8(3c^ǒ3_@20a` U O*1a:MA1an2|z /R ?`(#6(}O=g & ^ ¦ ϿgXraê=Gx9OS6J4qcpO?CO o$gU3ȉ6b6zM-)cȴw:sv J\ y^ b!`% ,9'?Y,i@Q? xK0g\S0C3CU68Ï O200!8@1KF>*nxI202eA^6PƔ- lg0bVa`ƿ/ ?c8q4P>ӳ 3֟f k 3Le`f} /b˿  ?e8y,éӏ?~1th' I Ub L0js0LK_á}~ix>230 1|_ ?20 ~w @@ uuR@(_f ʂsDZT3{g.ϟ1|l&{`C/ã? 4?Wc @,/0Ͱ7u 818X081̻˰{Mõw + ȩ??2|k@Y ~GR܀ǯ $@ 3)h #/[` OL`84P$0+CU$Ó?<%0[g`/GO0l}% y!߃6oZV3fLb`aˠΝ ?~&6f[n= 10PyXX82: -# >Ɵ Z Z ,bw=0e=;;O՞#ж>v@U?h' ɝ!K4` ?`EIAUݟ% ?,ax`V Hee# #f? BB \ >~f #?V*Gni ?ZT,ĝM G.e Xpu`x:<)nP00`3Ц*#1"Dأf} ? ``|'PTZ1<~|Zb.@LlldwdpW`dax1ÖKk>/ߒlq Bܮad *`l N< Z< |a FH?40 Hz1q?u5qok/3rt&$P?68m ?e8z* D S88d| LUMmRyQU^[3 'iF1|fI ;S48$Ù7^'F : bUqT9F Xs3)1D(V0ưR o3{ ^υ" b;LwwM rB,,||l &F *fXdgxlR a >=ax#;0bˠ*psoG+`gb`bb;3g&242 ?e6f6~uI= ndu`Q7?^1(*6SlPy@Pv.^9>?+Cekpwd(9sIM``y&\dd`&'.`XA ODx٫?$pq *~1|C`| o>1gx;ËB .?e~)T0 kx@1 Ifv`@?@K2cA[eCcܻH΀†3#t#66~L/oHX$E893rcxX2k:`l20@u ;ML~XҘ љ(En#@q53;; J8t}KrUnBߴ\:T>O}b6,d}HhgsA2 C 03!BN/-~;4j5*IG^-7Q D|g8o=y̠#AC `5Q^1`my? v z ^>bXg=/)3PK^ X3_?0hj2ZxS0X2k Woex#{`.swBcͿy|MK.w3X2JA2Ùn|{?!T3VS%7ngd58`- /f=L60*@X0Onp3y-NYË ^bДH\[ `y02J;h]„KYV&=̙g ĕ.c֖1\į) >`q#V☻%4ר7"//ݣ5U( Jd5#Qc@HSް QtXwV3D6e|N&8ǤmqTBnvB u~2|_7?=ӯN;rڌ%}Ż ~|bdЕ7`zսzp.00oM޽ ׯ?exrë _0K/&ûס}[P7ĂV0cXP룟o<>*,|= XvY; m߀v_y )#ud16`5k[oyڡ!|?eo^ )$-Û=@ c bRŀ|e8ÉG5s4~ۯO^~y/ǿr#@5DXeXY 1k#iw w ?Ï6]]pY?Xo2pz rr03?>=s%ÃOW@, ^@& |Cb h} e3Ƞéˠ̺_N\ZC-ASДͯg o/fxù~`( l1/ |fx{s9 $'=01BQ:pMaϼig[8d8US̍ "g~ɠl/n)kĮ1XR^~c"4If466s4I={MS} ) ͮʠ" " `' Ϯ( * /×_&,0|uIN00 5bvxcNN`ӛe1w-+ ~O]~+, l9U?-ɬ ǯ r~TA@ T@j1ےaMv2|AӌAE/9gc`bP 7 'h <X۶=lbIU~KXB3oeϿߡ kb : =ő% 篿{y[%}k h`^/ cqÿoMOY h0}qϙ@|s& qofxsQ;?0uQ`sɷ[ _܃dV4X.ͯxy9O|f5{g1\9ío7n~=m>&w& FTCYXTYs '(XR@5`SՠM]IhIzԭ}@z"5q3I,&h+I1, G)+Eh@4 F|Ј@#>h@؄*IENDB`Docs/Chm/help/images/rtfeditor.png0000664000000000000000000005110713225117272016070 0ustar rootrootPNG  IHDRM+c IDATx]wE~fv6 JXP" TrP0wz3;;@0bTx&$AdY`]vwvfN3;,;ӡ꩷z!"=ܳe˖zP" U0  =MpyZ+;@H⍘WPxTx L_wu!}ވcFcӔ^?xQ16tt (owD}#^xUv/d٢7s^k;t|7'uAWY)a0!b;-D2~qq9KA09gᯌ?6VbU΢o  Bf 3D1MfbA@AG:<ɬ~qPw\ƕbRZRF0…:? 8oГ%s[0Dc1sfY&*gb_w4-Q#]HX2\$'RdʜG #q:gQ>O9g L[YmcF6xem"vaEHp3Ƽ"[OTi$'j% 3P@(J( D<~W{V6n/ȑ.=2&ϥ=.Lڴ?}Ne-[Sadw<&Ǿb*"0D\E,,nzzd)B/ ay/:e S/P=n۾7W\_ئ~߸//npŪsgϚ|镑2D,nږRs._83aa(Zg}m4x.be֯]=թ2 Ȃ%֯[})'qg~ɬF[ZTѳ*2D4d%)$I[Bۗ`S7_s[_O8eڰF刌lss iMTH fk#KX75n",ѡXE!C9䭙hF`E߰eWqIv$eq9Âq8>ߊ޽3;MV@0x͘bLG> r^17zVCEƣ$-HYCgFFY?JXF_jFLB5(|\:8cqmu00$9Y<<VQI[`0wN`g앯TUYd ga_pm ֬Z~a~QUV{^c:?khIa[\핡N[+ ¦"ukq[o5J'5G~{?u[뼌y{T|~.?߭[#Iukehk+ dʃ(bj6?S~>=}zm 2,5΀_ZY3G_NiCխs<U6oͯ!'rxzv*k`GFF,`хcߴuWiivA\}8΁3ط8[\QRS0~҅a זeel*swkm[e/l*}̪оȧ},Ạp?#rcYT]sŔпGGߣcY3%{o 3˧C|QE[e<ԿKgXK${NKgq%J%6B[q52ѕ1+1MLrt |^-8{dzs<9OV9y\a99,'rsx^fCn huoBP 8t{| ry^氜 y9\ONyr<9|>ν* "z#1y9A?wz@ rއ̜0cٲ&L:wyx~aĈ7ܴ/^2#eN"p}_ 9zN?e 9w$TV)Ͽ06y˜[[洓OҲ>x^( ]ԁiWIcϯ 5_vu\y.AIi>Ic߼Boe}m~0G_SW*..A_]zO>v7h z&KԄT>xV[O=}{ۻwQ\Z W^6eJC ڷ᱆(gu?ׯ_SOΣ[>]W-BzѫMk UU XxȝSQS=P)62I(dr4DSdD@&%Cv27fP0΁12/ zD~RN`T5#s@AA>{yNǓalu o)*=l׋@SС"D&zĎ]q0aw~mkV-g3eˠdGR_ 9B匱}{ҋp/)-]ҧom?ٽ];i7o~m?}8yߜ3V|00/{SEN2qyp35ǎ'&O~-|T-wLz ^y Էl #ov$k~{d^ػgƬ^K䳕qT KiC']߶r d,uvlUu\Q8dRG QD/ ד6 x0^CѾ;qЗR:]>@UAQ& `BM;qIaWfYQys5_2eI'=ҫP{wb%%sε:?kQj@1J~.--C%)Nֻ%%ǻuy#5v_cxJ=vp3j3PsK>Or}|6eYrwn}5iSz_3,.ֽǙgHLHvҲEvqIDfX.}3,,[Lױ1 j3{# \zg fW$wqGPJ+)\Gn9,0vI'ZJH.єz'rN1P6Au PYoFUCӯX[PC[ xu-c%usöU~ܸ¶FB `1uf @fnܲViZf޻;rI'o޼sn_~뮿QF7ߘrɥ2b"|Mɹy~52R O҇ҨO>v>wD>xuWih)Px_Ռ/;~ߧߺ5tg_}&@MEEXS#z]ZK6mszsF[֛s׮O~}4 .jWR׮zX0EOk׬?}dտQi%eDx!)[0 -y>qJخTV/ }Ho}mK"xY [JESWb)BYU-cJ)\3#UP5ngv7T158gr[!諈lW !JsmPbV S q}/?ԋo A `|)W~#eK7mq"Lr߽x_~ȱ.uQ jC:wQE9^X=p|̸ T^u O??)*PQ*P8sUVypqE࿟{(KV cLޮ *MԦc*T*@տife_}ӫo?ÎTw6Jv?{^{~O!$@LJ~ͰS?֊vyQ`OPnW]=UQc'WC ؆V?X!K50!gwo埦˃,֫oHI|ʙFe+S%?ߐ7+Ϟ`W]wZp؉O=jH!5<"(p"a[SI-,8Y&&x(wڜE&wXsdhוb(J$r3Лq) -1 zߙZ˝3/lnEcEtk5yĞ<WUtNйH@M6gsmki9r|x]׭"a;E8n.bn3%VR&^;qf~vsOuýδxY_]}IO۹W(*6}?=< B[-Fm) GX,4Td']o%kX qMSc?btIA+tyYzљM,N1 agqǙtiƵ&ViTnd4V3F yyՐ],nhq`׹+:1Ҋ< Ѹ4)B֧vbuX3`q`1 VDm=P]`gU` C"2q4\ce3eZ IDAT[K-TH;;E9$ӂu#? odt;iT"YNȣ`R]f&l-V'"e?rdE Sj~f&H*,ieV`#3aiE(xDB!8s`-[ډ3~!C$k|.]Q{>Yc<(˞zo]h|ݰwz(/ět`Уs1/=A~(]bsc;Wuuu={ڴiӥK*B!q9>|@  TUUU=cA/9!€yM4f߾}]vurƙR5 E,Pɓǖyvyo˃?1Ǿ7Wpx(cmk~X[:Kc$tRYYrrG 3+;f=PJӛPsS%77733iعs'sO?t>}܂^OHU|XAEP(B1gW&6sG?|zx|l᦭{Vvؽ"R a=g`T"T7u]oÙʑ O޸7yx}nܸsaPUPPՎcݺ/woZs11offfN6lpGPM )TU)̆@ #jn$I\2+t; }PiYTUUyVZ-Y/ti$^Y Ukdc}أS1ddJUm@Gy3{({ h':iC(( ssi~֍73nB[fMVVV^^V6UR9缴tDBS";%3 Kܞc8 Rc( %Qg|wӦM_҅ G_r]{쑺y^^޽{닋׮];?صk'etSf%333-qƘY8hРVZ544ȇeddTTT:uJGm~}jjv+gyM= s}~}yAOV垕d*BEE0Dgp BDB6(XPpkKJ:a߾n996lwv$.;t^XXXXXPSG ,&uE˖-[l]GUUEQJKK98tPuu/(( 71u%wohh =gOO.IK+Xw7W[װnO~=*P Uk*" [puPǻ}BPU* B!P6`U;1Sץ1[ޛS]]ݵkW2 _ Gi)xI {\VV֯NN0Vvq"grGpsmݛ-=9YrJa@pXapeEC,rOBSJpx-qf?i p@ 41cgu~cyfA@8|zےP.ϏMq@ R ZHڐ% h#B@ 4WL Ok5M#=J*W4X8@FK 9߲ fO~6}i`E@x6W>ML!M_q3k1y晔UUVXͽ[Uj0'^q ~__jǎKk52m͏nfWg (+!'O?+` pȥ߿7~heݮsֻy_ih ]p˭nx;c֬Y۷8p`Bqk|N*`-qQ>|x&tIfFFY*k,}掻͛vZ}ʃmj_W+eC.c֬Yxuedd\~3gرciiiq{bxH!TÞY M,ƴ%J;_UBpVkS܄< ?p )E]Z6~ZbciXn޵~ێg]+ww³/'L`|o䆱Æ ={W^233۰z@7Wk;M@$n^O b*ޒ%K3Hρ(GRBbܒTt-7'pw'LOk ? }\ݻ3:3K&uk]ӷ{ Ntj zaXЦ0?wek?Ww4kٲ<.SUuƌv=???vҥO>qӞ}D Đ O:=GK^H1Q|>/ $)9͙ϿSN/^݆ݵjU _àUh-WEXSݦ#73^;7PPܹz`ܸP(T[[s~A{СJ7S8 D/Fv:H5j6w-O]k~sC P~orᓡ>|r&GV9s$>!nz|+sK[Wa۔U hS:QAC/Z8hz߿G!7ٹs]v޽}ݺus=i2gRk5e2+FKɓ`̘1IL[fffCC444DeEEvW0P^ܧ0Oច?Z٘Q 27mfڶžݻ!\xGwСC}Q^j +**@HmW@$ kw2&ҥK`ذaM(5riGqC] 5s yy2^z\D ,g}HRVVOj~665f/x%4זC "묶;+-;].󫢢}zVT41J ZmР~?33OSE!!B!5@Pm A%T!seu7,:t|))sqkf' ISC]ƶx#[)iB+nzZ{ƻ 3\ $_)xvU۶}ί6cO̚ڊOpOkgqUĞ=?W^5j\%D{Ԭ[ؽ"CA_ކ `H9)Z4@b̧wY>*/|ٳ ֺSti`J/;iAN52 9ƽ7mbFdw7wls"$ͪo|'{Ν;'L 9ْM<;;>@W9vѽwd UOz@ PAYCvܚ'\{HGp3ey2n}U[tٲ(>yFFAE 0R"!B" 4$J&뀡&la qiTT7>R  D73_Ƀ*x=d WnܺUe.|!&PO:򲉓&8Rݺuk֭/RٰoP~y@RgPG`HkPE8bl5H%^KcȐ!6}p 77}#(9a{]Z]-?wү5zˆᔻj}1gqvǏWvcǎ.]L<9+'\@r 4q3뛂t(fEK<}ߩYyNs_ǜ2oOe<>_cAcС/߿1c222w+?CH{ҁ@,4qy⿴jL 4hK]k*Hgq)nPlWzw{/'v.YR ~yL*'fZxhD I&^k8rąv3kjjx[&4G,(681vYg7gqo2A G{mIޢ#tKW_Q‘ ,m)4c A@8عs~&w`p@ '@@hp0Gf󖁤ps|iy>V+}I E.7mلV[73I|D8!=@ 1M1r>7fwq L0I.8KsqqFQuO7N ǽdp08uRw/8lkH:lcdf<3IDATyglO"?\D YBB8e/pBg*);~B\)gτ.&^^ 1payl 3ɤZL4DB3UR?O\6Au}: &xaJ|4k@80N1l|uAN ӄ1I:2@k2YO1tT 6';:rqs;,7t;sM1:gB1tB7U8@hJ=6 I!oH7"BsA+Zq@h$ni!}`I^%<HH@ ǒ818@ 4C)ЌA%Bs'qp@h֖8@ hKh{@ Ҋ''e@hQ ͛7=:-vA@ t={O<.cbt\{K:l@͜4s"wX֗F4%՘@{ԩShI+v/хlN&#de4ɤe$#nj6e~ dOI ~xdfKB04 7yD5jTuuQF5+erʑ\R^+Dsz=νތ~Pg`ٜIe)Ic!O:uѢEENoߞr<$.ؠ,sGJNj vύkD: ã9=é7sd,/0:/R7H( OsTMp&8e۽<&T>.vi:3׿^v#IDL9zpv?)qFI4>1I|roM熛8X^{ݨ.>Id%LcxHcr;۝袋\`;+ix!i uw =o.+JfDD^T旆~ -)4,ǽJ`?7Vq(><<ĉ KM  of᳔@ ;\wD\>@ 9[ĚЌ=,?u@̡9{vM?qFֲ$̬&Ꮠ{wKfOKHm՘Zmp2ˠXӛ`87<~DDifX R?RS'J)IeN[LhR{ֳ6l5w~&U4{ȗ{ <~L)^R97י ఋUhޟ,nL5töO!څ-ô[NT_ݍQwD5lf>b9Rj|hY Zr aY`zko׏a+˵+'r여4%q7 {A6Or?FPnB]r'䐨oexq)o2wf670`cj}ӎ[f_tÀ>UEAfEh4BhW|e!Uه(@ ұ=6F [ƕtrf'fFOI @ yN?M !AN![ٺ\ya0㼉]nL8x$ &D)@HnZ @h0 YdZ%\O mtfK B$qq89KlqG5kS@m{dPZemD Q @W4 IBBcvJY9|>yLʘx1NA ڒYMYSE+.gMڹd;CDƘ|sY8S#ƾ (%Nadb ޒsmNٚ1scdIxT3#M1t`w'5yTIkeD%Y QUUoT9B53ڀ0`?]{򵎥 g&l=\f;7Q׻ eU@wEhژY.K춼&;9s15g޽M@Dz{ݦkn<+>dߖQv=N!U}SUfV<4%?HoZeYFbf v|k BȲ>[}D4f (pXU? AeBәDT "lf&IENDB`Docs/Chm/help/images/b16x16_vcard.png0000664000000000000000000000157013225117272016173 0ustar rootrootPNG  IHDRagAMA7tEXtSoftwareAdobe ImageReadyqe< IDATxb:a### [ZZ aǎ?ׯ_ |yyC flrп6HBC r@8@*}&ffQL@C~ 0ͪ ! F۷?0ܸAL@Ma6@MLp?|Ǐ7 \\@c ߿eb``(劉  2ۯ@6"Й?0||tG c1aw |@ۿ3f /`(3|OOop=??~3|`Ȕ@16S#1|_ ~?+O07v!"~O72} Šp637q 8؁Fvx؀9s) 13ac|_}7aW VV @, ڊ3|45Ege!ϟ 2@$yl@󗁏Yl_pjI(0x++(,]@,@0Mgf%FhEЈ c&" e4&b9ww ߿da~D0H-03/bNJʳ-+gq~'Y$jIENDB`Docs/Chm/help/images/b16x16_desktop.png0000664000000000000000000000206513225117272016545 0ustar rootrootPNG  IHDRagAMA7tEXtSoftwareAdobe ImageReadyqe<IDATxA/  F9!M_fd栗YҸFC~0ycFNnb?_@WNB-ן"av? 52+,,ȖV]˄3& b Y3q- ~U ę`g2aő!mg)+l-觡ɰT)Okl'M8m@ @n0ȋT7tVbЖg`gr5þ />f8߾nj~@,BB"7؉e䔏f{ ?d`fʰk>i K=rV)m^|^ _31n۷ܸ L!C!Lψ}}]7&nbz[}naؕp~'9n+O?10e(t,+A0zB'0  ?179)"zןqE:X ~g&V_0( ^vf^/_2|p O^OA501P6!  0 㷆ǏI jɗvV=p9Ë O8=vbG  0.`0] va`JpƒE7:2xa >M/8=>~ݥ@MA Z l* r;6|/_?ߌ*wX != @ @6/+* {Ag5$42_$3-eaIENDB`Docs/Chm/help/images/b16x16_tar.png0000664000000000000000000000203213225117272015654 0ustar rootrootPNG  IHDRagAMA7tEXtSoftwareAdobe ImageReadyqe<IDATxAhQ "Y#*-ֹ A] \%06/>#5'Tc^߻ An !R'.$.  ۍwtǿzމL |`-=1)&F&vNq d``gfx{n7CHƼkL ߿20r2K300|KAD20<9 OOg` \" _30+3;PPZ/.00|{#P&~l 3 \@@Oc``d*| 9K10z  | ?@@x }=@M@63:hD# ̬@}&b7< @C??B B ÿ ?P\lP0P@] 5Gd 0^ `5oqBl@/0Ubacc+/PdĿp +V6 RFF&bdGTDW lf?@4Hs.; bqmb4吾G+&Т_2>7^1{a c @押 0+ 1ExJYyyaʝw?cXT< @ J \pdbPX2$Ey֊slcX 0&ݞxIENDB`Docs/Chm/help/images/b16x16_kmultiple.png0000664000000000000000000000074713225117272017107 0ustar rootrootPNG  IHDRh6tRNS/IDATx}0/¿`*يhH)GUHh m;LGHiHA iTc֚B03I)jjxJhc2s8~7x<]5884M;JU~GeY;oߒ$N_p}Jq^0 ðnNf|<@D)%jRD*n<,ˈ"1/O(N`1Ɣ=~̸!HcLRiZJ$I|z"ʲ,MSt<(z}23"JӴK)2n1F)ffx_Z)SJ) VG$8\fy>70u$庘mol6KdIENDB`Docs/Chm/help/images/dlgbanner_winxplogin.png0000664000000000000000000002740513225117272020304 0ustar rootrootPNG  IHDR<[ IDATx}w|sΝmr/2bJ# !ش` { MM30=@ !oK!*Ylɖ{ǽ3;+Yuwg̝g{sݏVP[B7of~5yol<6&5V뒍Ħot+-l\5iS[i[q{6x+CI#jRdR(P*$U*VĪVDDB0J 2}UQe&6LP` @oVPo'yfETCXQkCIІK,VoZhmn1vH!;}IerŧiBZRK`w5smrm8W&DI@*DXҢ^7'V-}(3YcMCǩ3:͵Ŋ @}G"#C?b}g?ߵKZ&}kHX6 DJE\DHVPeHr cPNT" Bm07U0 #F(OQ/4ډL"* !cH\pW]w+(bM*m4Z:UQimr\\;Z5]6Mo")A@¬& & TbNq*uӝuX2s̵)kheVS**INE &U\T9hv>XZtu+RQpw1VʦׂkQ+u* I,cTUZ6T WȊlm8R#]*BG3MDZP z13a2b݄m'.>BQbk{~Ѵ,zF`=Ns ]Z{a˶{ T>ےR01$X!e%0 EBVl EEFjITc&Exm@`R%b&A@leYI%9i;Na"O3YP4AC@$p~mt i4([Y?'\;ϗ>ዪWׂݤ{J* } *.ʩqLLklN\H 6!IP'{pm/{k*`ى6bDIժ%q ׆݌jLAy$ZaI'j#"*BJю(n=HUP$;?j=pD}cz~ z~Z jσ*5 !ċxد5,k!:zb)Tve*u"`IjԐW"V@T"XqA)NѬQ9i&0!N*[dEKu*LމP΄a'KuWNSHR݉7甧:az_,Aj0ό\9%uj s]: X:iM*3g%+81`/8KS" YD  Nޕk̷l=vK( &lTTa5RJ.LF@ dL`t-1dk&txhMduk;]\Zb3O:mY "̩Z0 3׿vQiu߽`} 5k'쎫i_Ryj8 \ۆjCVEZ!d-E>h.k2S+kpxZZHb#$ MnF4+F_ĵ9;T}[{ˏ70SvT O ^ŘoQMlmw5?ivrۃ3_tYN*o'c;XU7,S 17r6( 6>"BP8kA R%|ʖJ-ؑ}XRRG{&dX5L0u>;q 5W-yxC[{-wH]ՒEߵyُKZ_ .녪Uwo|qoxG{։s8ӯQ C=ohwv᠅z(Y,S%$FQV{l#*鼍TмWtQ%j T2_F I U@ALp"h$ZBkJDαNZb7=l~{}~wrCn`>Mw{ȥCWU)Y? Goޖ*"ϾV;a?T>enRv^]!P$`.Y yG(s[972b+ |(! 5NƵhHؔDř@V?_yczsp/yoO<,}?_sZw1n l54ȌwٶV`N@`2{|wؓڥ.쯈=OTht{z nBa_۵ʜ&;l!) d.kdܗ"6N;ʸeJqi dXʙR)ۜ* B &I\e4ff)1d Da%37 !NqӚeY*h>zs{Cm2UۮeK>7}郷vɷ \L>~95|ᡣ4TcE64ؿ?WrW[}xzmeׄ=gg^-Ie'ZեB%]^(7%%v ]2Ӓe0%C53ɧgqlͩxe`eXT[?~{:z6`[+Po~~~snx`[|è!%sښ>QdLPS(wqO%5n{xUþn"J>/KD; yaӰis.q<.m}i^\$pijf2NIz#H#FQJШ a_v뗟0?ܫ?ҫ0w.>K?"Fc0jza/^znیsZd#wwqToy(%XZwzˑq_-"y}qj ?/O}.1S3 X]ƣhH*2 p 'P" )D%6֫KtU"#": wһ*T aPTh'Fkz "RaA7?yDEŲ9s~|q9ޡGBWah`P{m.cU's&>}>O7lb,ZwsQWi,z_wdgRs ٞRͤ}Jbnr9|~fYsv'Xz̤Ҝȿ `[-i7SW1:5٪j,T;OlwHBPD#[Jmfnڱ+ LH +=[!QDf#WNq*zUHF'3/_5M}haWθ7_Uwέnk-6<ðz%kU' +VU7{l;Vᯟ9X u]?%gms2qjD0 htzR[WhE9yvknѭh;P9߶쭴S lEsiVMf765 y# ! (H%do϶U+ֺD U٤"ԷI:Dwnm%կx5ԳPlZl(VSi5MC0GQl$BƎ0z㓉H q ;.`f gqȑc-[fNw`|d3^=mH"~ZBe c$R P{M.ĤF1AAS f![Z| E F@Hhg>޼%pk8Q^m*{ybtʼn;턟Zm?j#-HiPMqUyN]G,ѺUXQO_.]4 nvͫwصҫK]ϵPKbɐ˩TbzTv{u56GgCM?&j36D`$+Gt4l?mr~p)L4NwJ2mmRVV.K/IJQZ|iԞ֫?|y73"\>nWҟ^qQ NgcA/7ަ 5+GxZ +G1rv!nb1Zm!J]A ȅVֈg'jS7-|= e@H] e hRNnG-TDJ3NG=־ A ;Y;of;AOW&%4ت>}N/h%'PR>Rt|wݰozOwuI5P/͇? dr;8T'v1.o2+ST$݀8n.b%ȋ dZe9*׎Y( %0 yr$<.Ŏ`'G~)츧ՠIRY2hؼU+Lul$DTUH )`%H!H44ĢCeO08խU3'v+ݤ+k'(umm<"/%6dE;dUӐQjDɻPlw1Mf$$3G57}{g5͘i~QoP҂4 UB AP Y76zr&~p^o1o*͟r[Љow&O*;XR xzTD1Db?N,:p 472nI_ڨZȉYHUx*2XBcE}u*զ3 3rجzBU puO,B^Q~V1Gc"\UW[;x}wNcz쏋iKȵTv~_ ` z4q6GA4-5b۹\\b\ ;T>]M,ډߨ WՠDѿ'VuLn7.lΓ߮dU%=/;sN'?aRVf'`W0=@X(C*s:.TYo+VSQ&5)#р%`5$p=w `i2xYN`E*`eC׏<6 VW^?|ew>cő'~Rx~)_J"4Lܻ$2>$ݤ2Z&88I5 kEgtVۯYJ  5LZO_eJ ædg՜D nϱ3L)1bX3?}|(Ug勜TqS/~yٽ3nΨG`$Dv4`zzplԫyקMSf^/F '컋 ʏϤӇ4]~{apfM%:bb-څ!U-/s>1l7kS\91Y[~Ўݗ{(u7\aw *뾃VLsMwy[v>NK[ฒٯ4Y7W}֓ʂjEw(uểIjgɂDtWH\>d`M\.0,)!jIB8Z81[줪ŵl6?pʻo/km5d :@-/u9w}˵M|EX˨>m/w6{I|e;\RCRyدXb9?̕fhd_GO,}IAs̤"ÿ)uE~QnIV9ps#Unr?4^Ni3Wg=t>v to~wn^ 0^p`|XS_u{Epm.>}WZqC.VqCLvYC\O={ۗTs<䙽j0G/nqR'9:]M7 |ggN])#L2) :{ڥ ES.^_1w]?<SyMϟrueͱhEW0`r +.Dp0{/5R޷dc0TH"*8 Ds,EQ.D@2CpF16%eB RK`u)8$V,PѺOEB ,[qo1O0l;P  X`m~{~ 鋒Ok=}>b|^2cYwt6^fz*tW✵~%{qpNK<;#>enS\u{*.>mȕU\qkl$p/|C/Kn*w{^|Cyڅ/z _db(IDAT=.v5ݞ_s\ȽOg]С-8s3,6eS&cn-gw Kw8r zeh> 7-PWۙqPpYx݉&q-/ QfDHd_^q1k ;Z#DD"V%DhW dH:\ ./v!1y| b;ޒ;/BŐπ%@O O;竷ԏMgO vu '~WH ܿNԾS% t}Q 2rtNpL8Qsm 60=F U&kD*iՇy'Ik HNk:-鴈S\Tl-2(n]$;pW,[ǣ߸?{{ڹl?v|s(0xX þo-YW?z+kuvƗ<.zƽI{9'G]<,n6m7e9 ɌZ )pfV7X-wGY ɝT}-k+poN{`̣zyDy^Ԏ;%9Ff#]Nvt/g_>"yj'NgȜZ0WOvu9o-v[a]}+$^( IF}"xR!9sB)#NlaBr Y'GxxlBf#Uq eǜ;ՔT%jYed;|kS^y[Q3.9?Q -QrӢA6^4w7λ  zUnnMŇؽ;A5^Q;v.|4VZx ٷ7Zx˨ ֪x*s㨪z !5LbcWֆdP.$jhscKA"(CSҡ1X }(ThhEBH@Hk{6̩6j~#V|[?y~$?X/՚a;nX:֬៷y~;hz׶ ؂̊kPWW~  wM8q &n9jdF"BbXjh$RUjJDƗDKg-R*[^&ϸ뭍6F Æb@E7߽鲲?ݶ_ꥋz QX; yӁRnn֑*S\*ĪR(= ļ]^ك6 0EI"H;9 * XUq0D cX8*C ReqU3JJ(ϕW52ǜpqJ`c!/ɗ}絥Ɛz1` +k}.0׫J7۩d赉TIea,,<\D"VSc DFffߍŴI3Gr(b$i%_ת,A 50F aI0]wfjI*Wt4T |_{o;ǧ]z lcpaśl?|'kL{E*; XRJD VEEu_[#ɵWaN8 j\[]5J*p H*CYly!KV!BQIjTG_\c^=, o,.)nR?n4Ǩ ʁX0t1&+Yؚ+TE6ވ|q&p2a*SM60p{,l4H!Ȥ$$ I$i%WXIUgz^;g|> UXRLԘ&R :^]^݆l;,[ZJ ȱȣ}H!`\k!"Į$*Q5d`umb%hDB<1@KqhWl*(:M:{+<ߨѥc7ަ}F2GIjM*~Rْή[J8A eR*"lҩS=k#ɵŐ5Ȩ @DcA ziېXYBh] `R W uŵXx'Gk.W<5L6':q]M-%quTTCJhX )2BoT0H/"|q8%!Xd)t}a!$!+3DGk"$V%+%Q"2rR.6H%(RRYOݤr&WӂvD%!a30NCS 7K/X@`#lL.2 t*d& )MV0 BJJ6n0Z`iRQ_ʢ*+F+V``&R8k"q_0 sz"8ƯmUa!Rcl`l`$N&Uu2GYzqw%Z3"fbbe* n*=t }unRYԤkwrsvN a%UuՊd5(Bo ,$ fa '.Ji{A$2Od{ Q+ ){M\h`Y3 ZtʵX;Tv=CIUJ%K4U+`3er= &/;? 0+)Q;`46D썸IO%bR_ cUl "6T!% 7}jv'c_w`.u,(ϕU7U-ԪL+|j[eA]"5rt?YKddJF%dI5t""`C]Ze'*RMZl25o+ćZ{ތ5oO x+OJh\l4YQ߬6jhm7B{6S<)>A9n8V]KPx6LXi֞k ;םxGc-lxԞ]B2&IENDB`Docs/Chm/help/images/b16x16_usbpendrive_unmount.png0000664000000000000000000000141113225117272021201 0ustar rootrootPNG  IHDRagAMA7tEXtSoftwareAdobe ImageReadyqe<IDATxb?% (Ē2ϟ f`dgx9Pq߿*i'()`/##+%"rK .*--Yg+#(iӜ"0߿@Ϳ4$ڬ =55u8. ( & p9_ Uoam-t6PÛ7߀^Ġ- #̰nui~>@ 7\{3335?^odeylPUU#@u6߿[ܬE54620|򛁍7??V.n.&1{odZ^baffdK3AAAZɣ ]kzi0 PjKKE?YY&/0Kp0HJ0ps30|kMY3۳w__VD7b>}'?߿lյ +7l5Ж W<}ΰb7oV @1Xhz֭;HJ=xpϷڀ@/)#''?(K|Eel`r>Sb@1R`G:GнIENDB`Docs/Chm/help/images/b16x16_warning.png0000664000000000000000000000165113225117272016541 0ustar rootrootPNG  IHDRagAMA7tEXtSoftwareAdobe ImageReadyqe<;IDATxb\΀g`P~@sb)ϤNŬQ'o: a`P27wtf3b33` 4 /0|%;;[W74 @(.``.ib,i` " -"Ơt4 @,,,i>| 20s0誨pH0Bm ɚI00143wu1bfP` P @L<gv3ܽv̌Q@;M@ x.& , ",#''ׯ jsy @㓕Pۏkˁ]%.. -- IX. ~2qsqt @1AQFEڋc*Z  !^e 2#P(  tV>L%&| C~?iII9@쟿32Qd=h@`+#/5{0/ ?c>u*Cco/o `%8のA zWb,V`fuïW?o\ F =޾ ?>~l YY q7K%^o/^0f1~g?@Mt #а 9\%N/@l@_Lhge~ ld"IZ Y IENDB`Docs/Chm/help/images/b64x64_binary.png0000664000000000000000000000716713225117272016376 0ustar rootrootPNG  IHDR@@iqgAMA7tEXtSoftwareAdobe ImageReadyqe< IDATxb?H0@`dddΦ L-C*vݾ֭[s^~ (bĖ@9GBBk vs0|޾}{ (  t cǎ//;bvd,۷@KKKBgc#E-z꣖Z`*fXf5PX_K:ZGFJJ ezZt1jEf L2ٯ5ǿb ybcXyj8@<@̆l@ Ft@T0!%0XCW,Ҝ`G.eP @7bPRecc;X y?)Lzafff oC2C@:X0(>C?M<A y.$wU6iL;=(Q@zcJ) Zkw? 1"sRJ(/RJ)H)!.gڤs"-5m_/@Lff{'N`9ݻ ϟg2e d Ǐ555N @I?{ٳ < 0;AD}͛ !!!*ҥK J P`3.\@q0C!## = X2333$>@8S2d)r ///XÇp= y` @a$C/@1Je1\-T|Y .abGcA`U(, 38Al7^[s@`$ et0,b.a>} ;sN{޻0(@5K)l^d u5_K1}N،s;4.DT 9 䀎GcxP!33\S ;UߠAlGGGd޽{%\P0| R``__\b?>þ})P  B,XR5''MY@y䦧 ** ((L(13' Ps{+b\@JC!9XϫJFpw!0m)aZ2>CHp x`^RA nz"=j )Ev%ןݽ kbl 7lU=1@jpWOGXdfnMѹgp AذaCActt4< QDAW:X @ @) @)dLY Ab! haBq5rMp"Y {чqe"*;??pb")?* @$ (q Df|@,XKa-BN>yyJ1l ^"6tiF2)8`kNʔHw_k9+"FPę( u#_ GP3_CbM`~+K{8y>)î*FsA/2`4jw֑Qxj7p1APF@s c[ukccc h1ȁ` bĐՂ8G Pl@  0L@0{vJgAIW`R (bĐ{= A+א=: )4pȅ:C`CAq?M9`aBd,@d DA"m*~% ᵘ4Sv ǧKEɩ&m7$UYfD@uQ9h2ބ8ZJPO9DWpkߪҳcr Ev})TZrrȟ֘U{y3Fl73Imb.,-Q;Fa(x3m@w+5.6=%XãM &{nX:{LR۫@`4ic "*$(& C^3XH1~Q#As 0> (@!! ,Y}M >za 'F'vu,eSknԱLٱ!e; / h%@ p7H3K*jyX Ȇ @X =̟f&Pˏ~9I1Tݾ}\πrsˁ µq HMWUU5Au41U`P r h h10~eо bAlgP @|%έ e@j@`bM /`$?sk:=40`FxIENDB`Docs/Chm/help/images/rtfeditor_small.png0000664000000000000000000001714313225117272017262 0ustar rootrootPNG  IHDRHK pHYs  IDATx}il\ǙW&dMR):iIHu<ٌ18'k#: k6&p2<-ز$QVͳynUdY%^WU_+245z/d:|A`&Ȝ{@0B2̈́VAFfl$d:-?[P-|uۦvvx\ (i&&&ԮŮ|n|2z"$}cjp-FhSBɾjFIFcYe̖a""%Y$t NDhMD4D ,92(V2/HoF!cYxeR^t5̹݈`#x <8[mˤT&MovCN3!4 [۹|*I+I 85iING~3(Ʉ,cs(1Y,6#A!ae%'BtYnCK=SNoh (# 3> rXP >L^2c!L3P4yotQFR?  Rԏ;>/u"(M(CD/Yt3zOǏ٢|`?9lj,6zRy|ɨu}W[z=Djk3ϱ X'J46{7<{`[[lk5ݷ_xu^o#z;;^nvO}"Sc}]XLu^ZY( Z3ȇj!}**Z [/mVVK!lNO˕l^E͔hf:$]kR`L :+>v}!o6q3.޻pC2ctwv*7o~ECޏ}h;v~~EǏN&qѸt2 Da'‘>K-Ddj÷6Xt:]mtWZ_ZQ1:8ݎ?qVga0u}Ӄ^q˯4_zh/(,ۭi B2rnj!2̖e PTXBX!V)h4o):g YU YR% QW"D4F &8yoքhK6Z&,kŋ`8//񒫤TV; ]=]Uoe8Z7M"WQchsKjÏ$*.q|y΂"WI*$%5S'&SJ6Gpj*-fC ˫?]`_yQ&Tr2bYsD(!BTEQ _ndE` 4% FQ(`L`2t%+@_wgO(7dE'H֊S~aXcFK\%DdIV FA(ky9$ rfy~YӲ 0 DZ JOF)fϜ\"txO}"ZRYքbF1@?i @Y 1 k&( Czapڵwee/hD"d,ttC+**r:.]tӦMoƲeNs~###!ݮjt2YCAhURY,QJ"YVk 4 &iI[& ! |?$蟊eBkddD <񄽪ReYeʾ IYy S"R˗/Ꞟ˥oo`Ϟ߲`Ҫ*B0떗GhN t*pNcJB+AxBH5 lk3l?`PEBz"ݘx"X,˱XFV˲1F-cEՔc$ 'D!.BB%wRh(EҢHcДw !uuKB?0RTxAN& b`0 0]\UVK6$I,TVV~m4.6iX%e0cB d,ñ,DcQd"@;v_}dd֑BDQLӄ_~wޡ |W^yerrRIinn>uԫŔDY?s))x2z6FH ==-<駝41H!cxR%`4uO$NEѵ xR%pRujy1eG1 C{^WH$&)LT<;::q܊+Xe&7YldbYvݺu4-6luE"_|g-)))ڒUV5662 ].^xW^VXUUUWW3@lX,F~?я+WK=آE 3UPcE K:-߻otoř DgݴÊ1849{b/\02I[z7o?1$.%23fseee~~~<jb&ibbʢ5kNx3ŴI*7|s,ˊx+xz)JcŔM%SFKpv"x~Fb,}YUUO8qg% HJevd9>*X N'q,7M uy>o!$ߙx2#_gdeAܹs-vn\UVV G?(S&4Z=z}UUOSSSO>d<V_[[Fz2{}m޼YG)Z׷x[_Hʷ}>W[,.c%?Iɕ&{⢆7L j1dZR]11E)ˏ7.[;YZ]A禿 ~c<{6N"CdHaIJZsVE ^ _jǫ[붾t|Oςw׀P "Ȍ | х%ΪUvh+~WZZlٲ#G,Ya;w;w.Noذbl`c`9}m uuu~]]]drNs޽nt D5^I*:ꨭYfFb03;11rJ:U 7oVL&jmVVVb2:Wi4B=5(qrL&͐H$dJ^^^yy9Cv%˲嚚j^( AoMFmmmo0Ɵ6_x,^f7cu漯[%/W ύ]p^b'Ntwwb1e[?3%kFEݭ\bq嶡gtt[* ܧJk۶p8Fjuuuo]^^n2d_vM|>>sF(((p:&clll`ܹsV5H8qbϞ=~IIɉ'U*U4UTl6;wp '?9s |gMMM=fcYMLL UV @CebSVT|0Hl۶ !DQϚ L׹ڵٳ.k555۶m[nZò,H$vy߶mqjpȲm6^Oc=vθ[V ] !X c,˲, =@ rP(dɒD"VTjl6 lEEEqq3gv{II$I[n@eIn`p8---V ÕdnD"~_VsdY޺u+d7nFJfvEQL&[6o<55CY,rt:] 0 vh4j4?444Kf$d\jR9Y(n憆/[Jy==ܣBEETWW?^EQ\ M{O6&fUGnxx hTp8N/]D" % ߟN&Eq(YQSMQ\ςkYLDbhhhbbDB&^qI^WVVqܯ~+^t:/\044x̙3 BFZv{$G"d2yA"C4M,yyy԰zP,zÇWVV2   H$p$TWiϧV[!$NɄsL׮ c$B<>8/t钡|q?0.\e!L&S32Y !rjX;wxt^^n"L&޽W6m*M%N^o!+Dח>}c^\\ /<䓉D G}q8]ָaZaZmOOz=B,LZ֞j afX5 $m߾=YF$ݞFY6!jFs̙ ͖NZfYՖ`Xzr3fIlzF$HɏPdZf# 8(ЍMIENDB`Docs/Chm/help/images/clienticons.gif0000664000000000000000000002617413225117272016367 0ustar rootrootGIF89ah#lƐ FN2֙NNGҰ PIJ5FK3h`gQ(hr*kIiO. OLh觐䊋giQ珬[4Gl l2OTiKo\ؐ78նvg F$#uwUKMPEg9qi٪ ne ɐHHMOq܇.puWi趺hjh Zk($_% m<\khhOvhhmNVUU.8wݙ-'TLKoFFKvvvwczSqugkȵ15V'sK.3D6nPh8n]q *c͹88 H./sg.i,F4fcY玓kV/L/cKܩn2.T34vi1h_kL7KJPp(: v08h4))lmNn 81YXXV>xl7OWykxZj .YP,wOӷwN טNڸڑPNٙ1xrw j5ytזk۲X/y0z4U0lz!2TZOzUXjZooQ8QYp0$e5;qّθT'UKYEZk,.%98[ .}K[1 9 #i4y9U9EdT^ڲG7 !l,hH*\ȰÇ#cBHR'5 Ӱ : TPA \@aQG .lpfazKxX,ƌG̛V1P3d:l!btRe S]*b,RB4c)?"D΋/4sfjyBz1lDٛoч` HiRd Cacf 39ţA3]`CB@ ʞ!+ř(.Q8Y'cdȏFA3$aL3QT g6L jR zaQG DF0G5Ў& "4CB3͘qC,aX=,Æ hh`XX X$y4xZg)ɸD4C _/0R#LPFDHdAB# -`C@|s  UpL[ sL()h8R-E/@vJR8cXԢƇ̤d!p  xP$I9;$:0!>'$#h5d,TŜg0'5<8P3 4VMA3LB<1a! ;БGE  !1h 9 4@j0\q b+d@ 7t:IGl/8!$1SCy3*mZ "0u)$ @hR1<' ń2}[, >1Zč 6сA,l2;hhep&Wi!#I0)l4װ"p 3A f4R@@BpL0>@ɐrC G.hy75< 5y$ٙ#p2Zlˍ:L+ʁw4А8㈂&lWSJFQ|;l`=a q, Ih4@L#`]0%\hJrׁTqlPB2!5,`c$ D#,0{p286#r0\b0c I.!f)Q/P *.|+b8JJ Y U&me@dq܄gDC6G *0$ @رwNQ|džkaUQnfc ՀƠH.WC$>$uY"O$"+9S*q)H(o*7x H3 5F f@J] k*T X8H @q!b ` Q. 8 XGD_&B}7!X"3GAU R R% P!Ԡh7،2 (FHaa#B PTP x(+` e H P!`O,N1 Y JAQ".QG" c }@R(tJIPX-aPClM?( d;[K@A؄wD48_܆*> MdCN5!0]t`ye,R!aC x%dAFH̩o|p6i B *P h+-`V# 9,aXB=^ Ȉ-Јc6e [5@f $yYtA|%֠9pE)41m9-"G7 4 Iuu:|F_WщDkDNCd*^X[D|5!G g^Bh"a tP" GMRԥ t`(t!H8c8@Bbl4`<uR\- 8Iar0a9ԡsDηCH4s|Pp\@k_&Hrp˽A PB@TYvAtx S3F!p@AsA b 6&MȘ!@l6""ѣNx<\x ϏR\`|GсfWtlP> o_q@UQQ=j!>pvR@O\)0ڐ1GlpW=҂%E7 ߠ-sR' w0[`GAlVW uuRPg RVYO `QpH P|p pv`y") k0P c h  B:0*`0Bp tdB^0p@J3` p+#/ /W LumP`+;!x?w`l >`-PH>jS0(>wF1#/HY`hA I r U@(igW PPuvVa_{xqgaёX@#eQ-Px5@ 0 Z}؈Bp`psЁ='pp~2e!;46Qh3Q_!ci7&с`Qׁ: a@7yV`%~@0θ/40J f ?P"UJ98TOXuprLF0` $R"e1敬wBbk3 @(5@k8aN@y@  #`%0p@.IMcPـV5P@ pP"6e.4g/0Ԅ~cwYW/`  p uBCu1-8{U5d%Z|5xFPW C5zVDl` PS⠞$وlp/'TI~@`}ci2>y6x&@d !Sjw-I N@p%o C垎Z ? pg GaJBT0M!@T!8F ,v&ِ 2Phek&Z 1^(Qy{-:ue  L 4r- ?1@႑jjU4j$EpT a%jMRUE0_bP HkV ĭ薯;; p&Cs0+کHb!!S 0 p=)˦4.2 !pv'2Uw݊;q:^0 01dz3WdS7E+*_*qP.GqJB`P;p8u%ku}Hr-V5'}  O[ntHЊYZشlwi`G@P30 ('~R*hk}$/ N2n -J#B tkxp0j. ,{ |:k`UM]d R^ j@JN=O[<*'/G!wp$-N;q QXP!yP r;yeǀhEH `NHCQwrQP Y@]#p w ( 8: @$Zy1Nrmz{26>瑓x [-WW6Gq`fP R3 ۰H0mV ! 4 2x<0wR prG`p20 =`zg`x`GNk+BB6M;;GpP 0| HYd N; e N˧;D`p4`#@ -~q# 0Ҧ0 !=6%@x@[W Clzp'LME e@%:pp-rVN ape` s :3j/06 HJؠ 0  + kP Y"&+`0. Lc4Ĥy OD/A0cf|y攌D tyE yQd 'S35:C. qҐ P_ 0 = n mp%;T|yf(+IHrp#>k=[y|NW* aiKx!%6μlB { c0ij@ ?0 ([{0oU=~ p ;uXy W'Tk^4jhy~ i!W(=`CS g]iMRGT @ JN(Mi m$. V=1pl\QzC=16JOS!^~Ѻ bH^eB4U& VG,.-x*XP %m8fY`.0GP Rg&.%%=PBj1smURP h 9 ~ Z@ g;kDPTx&d =G0('ȤwVM `rD@js"l ?  Jg k鑶 A@ z&fSY, DU$Ox,GP ߠ|4= t* 1 Q6yk_ǤDd]@*#P n>jm" opl634B py zPvv#T;hi oh ! e4-u ViDzM@Mɐ M ϖf O> TwTWaVԁdw}u0kTXZ00SʿPT c؏Z|o IǥH5x!p]5\cϝ-xi% )j3vb ^@[p#Щc56j |C1ZhA+f@ 4A0<@๴[J 金~&`% ) <%H'c(;£fh"$x)DƸ,8:e)<:*jHA 2 E 2 !,b@Zʂ%xL!t "0rXP:&8)Dh1ǂ+.%;k &(M%OFp)5/, !b)p0 Ѓ@tQOD$b/`Fa9h:(O9ğnLR=)E'r\*6  &+ jaG2x0 ^‹Ҁ\<#p 2H p@ m m!\raɲ^! .P-gOY2&)@ : `'zϨ!( _0f38D8c0D:òp'Ș!M\J脸a#^q#<ҀuC+Pjt5,$ PH;2tѥ TA:Var"睊U vwAR8CUT3Pb1d 13>%Nl &0թ58'%DkLTP;,FE,piyLb@a,JCBְB1"14Tc{ddҒf M6b:3,?;K X211^tM^[י ""\VAnrKP2y t}`\V*k,B ox;^׼뒂sބB fX/%p)ZZz BB1@|Q;̀ozхUºsZQka8  QK:gw9bTߺ ,1_XOr. YPkqg| P\lX0jp'/@na"aF#F|=&<4,`= PȈQ}ʲi ea"&-C'# D";p Hq>@u#:K^`a8`Y" 0HS,L}/( х΀;ڳ+Y3N'%~@@E@.lRCkݎv  `!x:@ͶQA J }pFlY\yR1,$}؃|(!K0W-z8A0A570`\8ac?wxZоJ5pR0NpA*P<6 +ɀ<;#5)Hh88:[s8 !xy'fXL鴮>ȃC4p8 Qфv5p0TtwpB ,x C, `|#,]![HîP2H[`sl ش-Yx! x4H (~Aȅ99ADPw(QxP`RP?+ ˅$ȐX1PE7虠J&瀜,X-8c3^IЛ`mF"x <<؀OhI<+HK,wԸOzNp )ic H)8q9D\t2'/ңCh8hP/ꜫx,'h8 p\LDĤ1-+JtwN؄zXP0JP؃\: tC?`2,4Ȇp(p\?cHK??`:*H(xYسhGI|PZ؁+0P[˻8mb(l,悠h70  M 2H48 MPm˷2'~kHOpѣb,QHdp M6l5$@*0@4VR0pAK\h,6,Ribȃ]*h/BΣڃcp 쀃0eHJ' #J:D$yP!,VO7:X{|W{UKUpg}eXmRCK0$Y^(.*#t`Y<8dPb%X=큉u@`#S#2jd2 x"%?؃PSdXbPR`0pg6 }XڣYe > ,*~;M`BPB8^xLS' jh7 .j Ȁ`cE:AxXXE[ݝI)Hڄ0ˮ 6L*[\ۆn臃x^ XffhE.t]*.h MPx] ޹=ݓ. X!6 *h|P ϘUŠ&Ё`ڸP@Q6+(Pj\0aٕX `\ӄo(`HNmڽ:)&Ņ(}Ѓn'`c6n, &0a5у˚\u:vڍ Z# ?[?(o8'0oH-s2Osؽ`0@?O"ȇVhD=pn(^*UXBI~hbaj+0i _fFJ800JkB)[cRx8014tv88`5V@X|6w@DX-)][؂ʔ`c6fgV1΃F v^:_M5@eW|v؂*KBb Epp[;M8z:9`a@TK=].~Faނ-`[ЁpXf=k4gƟ6> 9HGFÎV"*IM؄|FB5Pf-@S0SH{;sbFb2@n@k>لmh].Ze*Jc/ kŃΔ9fplqĞif |聝. \Koly>BNEX0z8MQ1L5hha@km.^*'`HLEH<0Y dŅFV w^7qpqή('K¦ Cg6lEЂ6m$M2nK@y[NhYx[8s[?/SelT2w111 i;-HoJnh''6(%_rbmbQ@`0MX'9hybP+oV/sP?[P:du#t!ٝvblCpgL;s dOk8=4* >H "4G*Ex 6Az_ :+؃#Px W%!6JЄYCW+f(ʊW6P/2,_E"6Z j=:yuءx`Ƀ')ZPyWF7?;Docs/Chm/help/images/b64x64_ktouch.png0000664000000000000000000000672113225117272016402 0ustar rootrootPNG  IHDR@@% tRNS/ IDATxZYl[gv>/VeB[-ˎ;3h(KSic_4A&}hgک14-hz/AdGe[ )w/},KxA >I߾9hǿ3O;BJTJQGgv,yh=D`)rlsJBuWfs6o%NLAdVƀ<UBW3_ƣ]G#v~07ttQ6{1,Sԭxv[H@Dc+j{a= ~ӯoK։`"G9je }7zO dģs玞ɥK$B!\I7}өOUwdHիj58]|Vİt)'RݵD0f>ů}9yPI1D33s_|xԔ1:; "7U>yZvV"5̂#``)X,B~G ]WyƀmGYC[x Pj?|o)dٷoZFUtc|?@k$(oMFkCj<&Fτ"(d JP"U*GZ6`&oWWt8po1a>㡭-8nSC",^ݸ}sթ)Z1 CCCϟ<0(BPh1s,;fˋeYDG`^3$H_pMIENDB`Docs/Chm/help/images/dragndrop.png0000664000000000000000000012073713225117272016054 0ustar rootrootPNG  IHDR=> IDATxw|eǿ̶lBM v'O{ pTHt$ gӳec°M$ |;J)  +t  `AA\йsд4:wV B<* Bmۮj/ױCA^lؾΞJaj29{w^ 1 r&/],\Hm#^9 wچE:4Ϣ LЅ [F.끐Ѩ+#t,D^;G[ L)@ l]eyz:v m(U`fH%yyv)SZMK۷m  W(W^,[Kҕ+ɲet2rLf͢!5:ڧ[Q*YY`9S6-fYٲ'Hhb4:kqB- Ri/6(Q$AW0WȑHln.rQAa\RSӢ~V1>+E˞)mV^ױtz2k9.%ii:y40#&֋CbBgi]TW=22W߮uGT0%6y03g]*FK/YyuF@httK, 3gnFy䊡o~Xni6{_6kuȕs{B/douOIv:9}=^{v,A`Q0dR sR)Vj #R ]Jn <I-Z%%Ҵ4&RSaR+mOGj*H62;%V)ٓr+Ms-tǏ篚>>>xǽ\bkn>=rn ~F$hb0hk%˖ѥKɶm@, …p!],XRI(5-T+#sIZZض `6:s&IK#j)IMU)YBD4;[̙0w.ʒӐlԹ+it4dgWJmǎ~RR`EnL) . fv}&oNk֬Ixtȝ$C(,(XĊO% &g]T#ee I?ܧgd9`mu`qw7(1Ö8 }vεǏٸqӞk32ʚ$x8?ќ|ǭ;Ѯ$P.>eg|ӟ=2Vy0x ]Nyy>I x%_q-;LN~~N~㞟4IтRo#s؏ݷKvZ{׎{;cZ]v͸`6<)t '**rŢlK]?=2ݼ%wMLIq, gd~,, ʍٯ8:1VɞJHdGA[I))OeΝOq΂-;N&%/(kHn@!eme)_85p,'WN8=#֟X xg<6b4#ٸlMe vR`4|=2RR[Z3˧N1pO\'At:fHNk?7Oji~,,_?=ဨeKVuSFzRv'NϗSd9j3CC}3hMWl}+-d5CQ$r쿛WTW'iӥ Rufgl#OM421?SAtjfgf>voh3o׌];cEcIզgd3pr]ywٸ[o٭_]{ߠA+rsGWOи32r-6[>CGƎ%I/SmWg$GEھ q;}tqƉ-wils@D<}t36r*AN w@_ L qԛ2n3*A XՍfL+щ@J/`=:k4mQ,nQpT0 3T!H15E5ۻ/beaM PTPJhPd ap AA` 3US&YFKԡ$Lˤş "cBEZU"RR U*J*R!=0Sڈ8>*A~PZ+ʀI׳cx@EJ)R J"P*PP= 5/a_ύ_ ?}p/xEBV@}P۫2 FPa 2@YJJ(22T$T@)a뮼?\9D_ycM?7/7V_[xh Hk Px @(B(-_wAxFUkgl\~1kZ[Drb0^I,9ۗ6k p,=bU[DyЙrY|\&/U\*4ZQ `b/KbE@՛>x:HR1aZ}տα]+ܵhOJw{џՋ$0(۫+#V*!@EP/~S,QD*ËVʪ(h F(y  XA vʭp r!#0sܢfف)rsOTT7av⊦˧N㺶`ɗ瀁GJ ¥W{9g䟞fG{Mܒݻe=}c$rCesEYHV m,q$!-ٸbC&-:-1Ϭ;zx/-uc鞊wv+~ A@ϕ%T@i8>}DCXPQUhhvnJ&E#|EEjmV5`mb?emZ h%6&^6"1 (q,٠N>`]Ǝ{8+{ddQ]ݻyyKv2)%ڔTG,(=:R3۷d;+&sg+>)Sk2KIs>vTںsf\/|pdd(ګs6nU0Mű{vm{DtƎ[{W~uUFL,>vyxhUӧ+A z[N`'gEnݡXӤ7&ݒ3osR OԒVg4<o0ڒ)-9o#!H'jYs+TgXKgnv.5)a2 0 H3Hu:be#RelD4j>(%2Z'Oԥ@ȇA32Lb󲳥Noc?z4l/8g g=xlR@*psNOggF䟶*m39Ҷ?홖%q 2Pûtuvm=z~iRr˰V~rO C{$L+˲U.Gc`ֵK+AAf dᚥfIh\*Rn6[Ūl\F(0T`(π MKFy@.g@`(PFAfo> 7)`;g"7WJyrɟ|,4:'@Բv6oԨGyCps.Cqig$H6?_8=4^3;3s Ҩ/e|Ƶ\4Į"zQзܠ ]._"o`8+ 63"vіl^.@ XxQ#FZpvfD0 PPPFnju-Yv5*@`@a[^B?lgSVRx|FLԱI%w-ٽk^v~cBBj5FHz~ҤǎJ3OFmoݺ|Tl|թn{wPE r2h- ZF*%BAFXvDVzlZ7jޝм;eޥ )/qj^P "5VF3ytVaɠ,+6Jy+rsm2egԍܻϜVM. a%MS}#99 ?WUgv3+u綞) `{e/ٽ+'tN~'xX{8IN֠]"8oUgɦIcS=>yߨvRu똤_W6CE [Nڕ;~DNH:%UJ&KшRҠV#*jѨ"o/N׆G˙+s kǩx DhtP_R+*[LxRho|^Wю37Q#13_n^鑣pcze5ݣHz٭|߾F6Sz8# ODo3.uR֭MLIY{gRgL6,OqQi4|,g?4HqJYOwSw8kDĊ܋7`HcIt&r33y{'LycA~JiF;i=?oUZEsHc~u 0Bj:V:#Tҥ(#> a€TcP% 2@ Dw,GZE CDS֮Y9=$:KŞ a#|^G_i&-}]6As] 6n0yo:%FNi @h&K"T J@׮7\GU6L>ՠʏm{ ![̙fͨ߷-qC^[Y2 R{~i!j cFJg(#5PF$li۽4bMf`${ǽ}_P ߣ z˄{E H!Tv %+J*ųTZfWcY|{v=Z32)s HR`" ԕG;,Qi*| 'BXJÂ"IELX @AwH,݁  H #bG{c뚊ˎ5=:  R䏎 ΖEքKt$j ANwHW-_ExXuKiwAʡC$04.A'}[S艹,K,M:>l˶o>( Av`vVF(ubi۽&k5+T0vbO@FiWQ\Bvl1ngGѾ~ǖUX| ywNQ(:(HT޶IvGm)bghkةAP BZc`B2W]v:F(`f. Ǵݜ\sTI;g]9HjzJ6  v .r$FRܶg[#~vz~G1{Q  i"1 >8{fO.(V'ζqt߄A:9fv(b\š%k|] ҁYf=}z>X͞33xR}A93 {d AA`cથ" Hky0I8KAA`:xLoI *(G׮^BA ]T0cuL˔" 1`PЬw6#[R('p4A ܷwEGΚ R*R@IK+(<_ЬO&M:8/E*2ԛ'=/yudzxnC&O2̹9OYQ='6hJe5;xr$ IDATG>C g$ULx{;^2flh=RQڵK!!9DE0#D+kΘ5 CL TMk*f? Jo')U1ĵ|ylFے7zƁ^%nJ2u b@E`jlEU]-fX_vn=5a4au1^[u~ů.c MsNъꯙ[{%E-:TZ75%޳KO9zͳ2J77͸$1E2 S^^>~D]wbaU9!%[l8ÐMEgFcFF6E`9+>7Y4ɻu Rz LM^xǻ3PVnP5Z /ZؐR.&<$E `&T\WTPun|s퇾:$ժ, A/ǃEVjtZzZ4hKa}7'vv Dm0ǻXNw;.LۤIM'WM|>?$jTF"ZxS=&c$|sAal5H\r!k TQ5v5\n5JoP*Hmx/џ~;r}tצvObtu^(ω!jLsplYXnꕨtgUiս!xBT0H   TЩ1S}hdm2d(!*U /n:P~?u\>qЀnEƼuycti5K- ku <ΡOW{X[X2`)7t`p8w^8}aC{$_U>dng1m{٩7SτypKUݪOBD RQh>ɔ)ybRb崡QQSJEQTTE'b5C` 5JR+V[5|?:If˝4Z{\"VV-1U4|c:*oA7 8j WBq} J) I8j1Cp7:FZSs_o.4YC1DRXB(pR(0[PEyiY /8e]IUua^ժ&vJ|g>3fd'pq˓ߟdn1m{ƣE;ս{%46F l-_VN aҵ>uyG6:㬖ꦲ ~Dey{,h ey_[0, R5 F4[AX0V ݶǚnj⭔R ՟}cowSPWdžZkJ4%T[Bj*ͼtO05 Ţjl܈oGb0vb+_(P ^zb?8P 0"֤ Vv֔Է-wG|#$Ņ̘sHxᐤF}wu5anMGN夯z,>=CطsЮ>]|AExz| _K\QX5Pq# ȴ^wLӪޚcE"G_(Rb05jC ,<@x4يف-,\;JaNS.1dhwd/K~ʛ }kzE@@E Wg[Oݐd-Ѫh rOf+ , 0sXXm$T>.3oruH6Й@,Lu*A_Yc8ӐW> фnVߥTE+ 5% o?g'yE;UEbZ6zX,_! L41cYgug0jk;%+6=j!$Q04JJJ*xPXhߎ1T .=A:?X`+yBs %}w<xr&޷ev59Q, O҉YKVȝ*E 5Y߿rDT9EBLf !"% !  loEҖ4sfppZCSo={6ԲcnZ~E ThBE>ZwoQF9eYV ]bŏ6rU|G"+@p<??fih]8(6j?X=3n[=xpKOߢ[ǮG- .֎3N^ꨮT`PIƲ{J+ԓf>yGkZkЅJ DyH1 ؍7̰W~ן}u+K=uxx*K<1JA PQ(C@EO&oC4 "o朼2<<"}+꘏^NR]y̠/2w,J= (-4.DI%u xw_aɣ[ּ"h|T0|gND?_{[;<ќ/ΩYst֔z"3~}P2 Нnض<:k ftVEԧf UԴQ3 +1w l5Vg6g趝0"JStL !{B&8* H;>EXV j@A5Qvcmŋ_L(UMeo+xW?_@aKaS=QT0i'(i4JʪhZ"X h?·i5ۧG?UkdcSAOE yed~_^%6)M2UGw畁0Z"W_ K(Fbb'CHHPQ^prR[,}D}au7\u-nnǎFQ*yz>/8)[Vִ?7PUr !d%56M :yM+LJ͎O5}^(ɝe]r,}{NPٵxԉ `2Cr_ՕFqOκrN]Rxfˏ!VC,2ohԘf|iS'-jz&cW?mVZ -/aϋ` +ꨎPKN&x`ܴCFa۶ Ƴ UvH1 u1 H'{ N*_ڜN8Fz}A}P34\츋Y:=1]yRU_orNle7®#4Zt_r?h'}uE牳G=A䋔/-ljTYzT%*OUut~"I6T&B"c(&ERDѱ69|ߞ/]ufmRJ_v0, ]]yΓιA{OçBQ1W5$,vYMu55& Kݬgf!b$O s>Bf8~xrrr@~8/B@*Iٙ djZ 'nTW^@ a CDkȇaQqVk<&j4ڴGv:yTsR#:oc'~k̈0UttXff:#WkzYWByCA5fY7_"QvȊBO)z*+OՁi`; S?:YiA.,(/..<ͷDeZ{FDՔVWWWV7Yy.,53a,JiC())kK'w bVqq+/pq\}f9Cۊi;WȁCƃTO*rv4]JgWϥPl7TVWU*+*mWEuu5 ułiU9 KNmS^ g\w3mPJxixѧ囚]I4}|ε+"Ͻ~<gTQچ;}= `ډ=m8'sP\"d,iVڒ CYV0{Xq(QEEQdS[-ViK.w?#KA[G]3j~y{u*gh;JT:*8|kPH|SBk]wyi%eihdsZrGUU%= z^R ?`(&lc")ŢbUn}w|E⪤5nܝgVu|TZN *vq!bՏq:7S8s"?| ;v`TZVKdUt7|@qqqdoN,eJv ]q\®ggp{U0(WǛy03gjI4ufӀ?q`6Zo{]tG$;jF+]]g!@Ug N?+z{q"S)rqNb i"&@d~m3ROWzϞ3ӇdgmnYFi כ~8ߥ6J0?=|o'8Td^%?~P $4 //]gZJՅꋊ9 {?#EY3V}_fuusfY}(> ޸vYHs!H 5C^vVjn6]w ={$Fc矯{'x6cDZNJJ-e_Р)Ǚ荫 aCee%-,s[` ƇHgfi-[9rbii\RbZB4uWG]Tem2eʨp5-d.^ hQ$%]/_2Mqq3TUe4Mu'i4jun5 |USdF7 HSn[V*"!d‸WPPPg/ AzAk=Ig/OQQy+BBCCB4kU- H6mSR{O|mVJI eBImɹ_O~`(j55x#Hg$::6OW*|vUdeβAhs6cĿVv ݿNǀ @5?|bZx#|0/m4??x4Xm>V Tm-- ksm}m# g " ȾxbGcWYq]O$\]0 1%D&FsF.),++||YxiTs\7yaܰ`za:?ۨt {w8~",<h\Imqq:2apz/lFF#u\NѶ;N$H[/zc0H;xBmm gmD1in2maח 'xeQuEL">y9gܑi HVmV-xsd=c0f`(!pʩp7[J6ue>zG7.6j'.V8dnxI~pvc0Hljg$]*Fl=Z ?Y:jVIފQGk㵛 ǎ]~ZQ51L!FejwץE_nirKul-9Kh׾o q= +tɷ,S H9TdmlltE6FE_g m#^mhvmP|bSݾ&ЮCEw):uFZkwq _*Xuq:oR6I+"WqY #<&K7Bg9q8O}iCk M/eO{ ,CL_~~LAeC!# H0q?;`0XXXQ]1XJ~)k)"-;BB\Q%ud ;k민ݮcKn=XAt+_dSmq7Ī7:(kD"bz{iշ?P|TW[-9V"}_ 1"nJkܻw˙P`m+^x쑛N Jݓ:v];>lŸi{'1e÷KlsѶ7uVY;`O<<Гz{U4Ki"u7u 2i9K>>C!Fg ejSC%zȄk/^W-#Whwizg91n@&z_6mڍ6[I zoQ0 s}:͎f\ݬXEm|^̻+w'?Kh@JTqi*`hC~{ſ<6"%ȹAFce U B&-oyu%oXyU ƙ, =+Zc X 4ϸ6v ~ȵvAjܯ C xȌ1"O,LP%.YGor&8cݨ۵손M\!&(YzlsQxjP|ВGr`_P?uvո.GBٍ:~)G#WxQ?3nq6s@A``d"=yCg9'11Xz3$\@f)>]+k>tEЅRxm[ٷ=]Ϯi9m|;ow84r5uSM޿7g?#p+Vdǯ4 8m3kv:5j  rR4Nm an[+obj*Vp)MmgV{'-{я W5GԄc+Soӂǧw}xl=mBo{-=P6m^oURY yE1uT6~N}< ^O}PWэHW0gWn{kٓtZ*}ؓe ]39KdT1 Z+,9lި;3eҐO܀׭'caJ+kx怄p_*(( PEbo[klmkU[[ڪ_zzBUTP9 HB]fs|dݙw6~wftZL$WHqǚ<8uT[S4$11I}M74O~O#v`w B`CR3f1׳u`0x\R(trCr>RC>*r㷠o+nlҁ=}=L4LCAxvFC#`ճgb/^{ͱ=&Nڸ\|k.pOd: r| y4r{ N\_6iTSǢ?M+q2A YLMa.0n8B I}V|0.X^^;`@g<8 m. |[CdKy ?tGHɟT&56gV\:_TS0gReA:=%Jӧjx4V7RX*lA@>ipĥP$؀n|;[̽Y[ rԆQzO=SӜ _*fMCB]m+B@@ %:*U7xqBu뎅 2Uԍ>V$p޽CR)-m]ʥY7>kX.;{gnRқǎ69xt(/p^qB:CfBeCYAcMA2iX?%F qp=Kp'A}=?& n0d3 "f|%iU+rࠤ+e}pm*_Ɗ׸v~s N c)zl_14y `;j{rvP? vnuNb`g@y4@xXZ>40WfHb }$ ^.1IL{>WdqqplA>⃃ 烷n:+z f'=ο%q30{]:mX[}o64%cIc9iAh9>;vpF~PP/1OQX>8 jP_7_7n,Ŷ!*+V Pgvdf&MIy "Bp$1$'Ki8Mz]%=jξ~X[|'~1=T8WQw_ҐۜxzbSe>#ZJRbO ^J<ؘoC%셰LP4cD qV =EBh^>ѫSO Juݼ}fYi""{}>o~dJ%?E)^\M'NĴY<`@TjJ:uA%R{ڷLR#?oɐoU1Z"?bOhCP_7nZ<Vd+,^QCm^fzk|Sg_ĐWgc]F,ch| Y`c ZٷSêodܻ%b113v짍-7Js~@UUb,Î3ץ\=)4K(lfW6odݝ߻ߐ<׋+cB7sgr Ω)'`v`@> 3õ 0K^(W,@C~Nm=Y8;l=O^mMf,ӸZڠAx}0:iłI7_ش)c $-QZ6~݀Ӯ sqS}6$V.RLFad2 1p|7hͷ-W)A}//̯C{FU*7뾕方[/~8 NS '-nt12 <>غuIshfL3aʁͶͽCWLNHUV{y;QӇv.ҎL"H& aMDOnյ2sx ;%@ްғ \Œ=`[`<&R`C8M˘k@1샹U@Α x] ~=yM]fBW).ur?*kom74T?Eq)Xm.\ƾs-ssn5l8s sY#f|0B\pry\.q\Hwc:]xFp1?tK^7JbGc Fok6c-s;f;jN(lSv`Wq^Q_U[W9V.rDss @(QVn[)]| 4 ,M6 Km^ f p8\`oSnvz;yclQ=P1 2P{b:K.jO*Ƚ'f6mv&ZYppxGRr ۷oTjwz[ےx,w#sZX BS2fbpx3Kw zhꃩ>.zpp8JZߣMoh}Eѿf;a)CP#JH\SOyV!^ye[Ìonx!8Ż!#$cY$`8˱/y:1F/_ ZE˟Wm{ujeƫ/F30c|& 0'mY=TD-E+6'-g ] IDATA/c>JӐ@!p@a,覯X Z#dgݟ0zxy"ڋ#j2~@-4H# X` O#YV\Q$-cMALlp*R84ۉsHx>»fH]Sɛ#~{3Fp\h$T6y og٬yWϝٟ[?>W2O7)h!/.Ӎazi/`bO! <>fb11I}6Zln)Z &E٤9c J%srsשeN8q@w"O02PŹ;.%l+  c7zAN36R(t;nW?g_q < t:D0pm;?zas!C.`I,` qX09|l5!'A60cz|=7PPaOb 7]* VK5\Ъ"z'Y(|n:{1wVʭV>UIpQkfUOA] 3}19S6vdm}Z,]nݺ5+BU+]EN>B( sVMS/zc4合nU *+|j=Wpg}hv0yzDD_P븞}}^,~8T{[4Ϗo>w8M ˗d:K0v蚱ui ōK7Loa<_Oc^&׆J61n~'A Vh ̳HƾYC>[\0cਜjg߾}`xVVYYQ]]A(1zh%Ҽ\Y7aHjM9cfK d.wgmN0wrȒ%oTce QjȦpݒL2rSPs` B`q_)p:v7ʿd|8H@!x=a 6|giR]2,-dC$ xM.v=}q7b0M[/ 0^+?yӄ+^ Da ꋅ겺{:Rܱ}/N:՚um'i޼i]2Og̵3e5wO[_0@ XC`"g?\Z-U^PwwS>W\^^:ª7]YF!'??j^REozx[vf;Fg:~4\$oԋ漷]LFvF@>gM|<<.(>WMILcƑVը+?3WGmMT+JuwrW8biqRNTWlthq5FceSM}ml'jxMa.˰΃!3A1|0v-DǃD~Ńyn/Fxol*x:S)3)<,;mݶ;1ǃ|0Ϻ?;UW]_reGg ^7Hݫ&?~^S 7zTR,,7iIgV_W6#BڭpXA ³&"{Bt|WJAǢ{5=W̨z*"pUd=P ik cT*ͪunn5|&ml7c`Z0r!.*ࠄ{Y3c玤=PG325䫗C_x{딙 i8[ˡ/OC՜9Y7{"cs2s)@q0862èmpF7bs4qqy= {t߽aaݭ갉y!뼗~)io2sᡅMЂSţzk0Zϊ{=71;b KtچS:s?&{]PąϤ[=fDN:і%3 RaXMɘ<[eE ;e쎏[Y!yЪS~w苵S~ZhȨb瞭t1{>ZwUx1)U%_%}?@{ݺuݻ _QaX6 8Mx4Iܣ߮XܽS5m\5O=?*©k&P fB٤ly2S?Ͳ6ۉgH n?&&fϒnojnёzB`=y)+9˫.}P>onzi9Y穌7n,E;mȹyf>%cwdfb8~$9L[O597pO4T^{ [jBcczEzeM )zu6l2(;G#b0䃱7Ahvsk_hϿ5RA1]h퐡ѥ59-33@c/džtW 7lL6^hd1izƤX'0:?b0sj_)<>Vu/uHs1w??x&~ko7lCיo`z(pzݷڱ)k?;DZgԱbdf0G[)\kڬڣV"JQ룗9[߯jyB7K-䖃C 8p9kؓ (@/<8|0"sz=buɻWƽ_?1?JNj/6/j*OծkmՖ0zn6W1ӝF X>H^=SJqв&1cH;Le.|S"AMYf'V!55Vܶ~ִ~nӫww+Uiܮ<8ĵ{WVWTѡu<_[q>g=Ǟb<|z&Xw|7l_?^7xOn[|kSmOѳˤq Km^ \f-X(c% 7ebhn0hj*TjV&͙ڊb>ebO>_K/.{җfҨ6$1vm&ݲVTҘ'E+[2{Yse1ang&iD"7 fItN LwE^I7+Ní݃XGQ05v0A<[5G3qCm- pFlXRY&~V[UUժږ+Jy cAd $W)VWWS_qi2Ɓu>._:t056l߾Q 94-{)Qa@l?qQ[`LƩXoO&23߽Z*V* *J5jV69~(G(őAnj~8O0pR߷_[` a.rbԨ1:u0 @'wwݼVH Zf1cfHH]`!̚EL{#w`o6-bN1a,eeh!?jT'K qry"Uܲ ‘S *(@!rvIqq-(ec Nۡ63cǎݸ=lȠ.PY)˕KT*9TUZB@h$=f1A6*#Åw̜H{SZ&, ֲRl?Q/6wF-Xo؎s=kPȽZfὼ٫!,n!i(..Պ Rejqh>F[36I3  wcƩ)ŴU6Sp3wɬy|pHe+DEE!6-DbqvnqY( <[[3)y ap9E#Q9h7zFaּ7?^8w?SY%ԏZ͛ <&&/ q\܆{Yi~i3sϦ 魹77F1 sppr9\.>FtD ƃC7[jhm2RSo8~U5 px{GFvqrrt\.8 ]]]̚yIHnH>c=yaPVжװ_e(IVJR&2(}0vF0GC\$ːVYY*HjGQ {-zi=q.[w͘Z]axaX"...nwǎZ8;A2ɩ5ZVjL3\$C Ҷm=JmE4" 1)4+b>:H$ryQknn?曍֯9zؑ[ֿ@@@` `,K?D" ]R [kOJ$u;w4i Gv3~ȳhjCɹD|ĉ#3fLYGz*:1hʭ+9E1>r5EERҾ<=6lؼ|;l^" [ٳ矯ѹKỠ̄iiMeI+mԃ Wrk"!9z4mvΝsxsXXN^tݩqD,<N{K`2q1fIP {O^wjmLN=}~Y]=#FDؚ@^hrqq?yeE}n^4]l BkV!L hZUOS"qqy];]a5Ԯ'EFٯUސnfUq#Gr\Q75Hqjou2++*vڧO6Ѳ}.ɉ.]O#?LN2f줰g&Xlŭ,no*)*mGA`Z>jah@W2ѪJQ_8ڵ;y#`{ u^RCrQ[S '0Lqw)q%tӍx?!ido朤$k CCR,^r\] k2/R~·B}|8i>w"iD"7 fIŋ}0BQx_g;vp@RU]0j~ D勿EwlWSt*K[T~lX\jHPrn,w7)/H >u8IJZrlt  Ќ_ֵڪ Vն^!WkI^"3U5X~}ڵQuŵw 6!z^+tAkY`ݼ zwLYKXxQ,}v8VY]]7#Gҕv8j:Q[c9mDanjѻi·=C.2a6J :-mk9bqhilbc)PKkQ~rrrb,oC}|D V6 H5ţ;<=H%KTxRXlND]lVM1f#[Ė釳o.Yʦ#t?.(TpqIDҥÇŹw32)jMMѣGuu OOo._%`,T/ AHKE+geY>7t;?}5&|$yoŁgiĐM)ZO'˗[ZO_X}1b̄|Z\4? ml|Y}FӋѦ#p-*W&YJ#Ko %q '-zo1!<1;gDҾNK*ƺ6"xP :1c%'Q5֭DZmZ tt.m+d"/&TV# ŏP(ՎeK< e20s*#rr랈krƄ0ZfR9lBw[,iDfj_Mc|bdP UP.p mB>F<m5s.I8$bZx^/lHM'&8 XglTB["~²7rJ^bk,FSĄ1ҥmD@ 1WE̾=#Sh6qoV;'NkMpdvzmcRa"B#e˰L|};/[f_Zgf#F<75 pIķJ\P~S8yzO;7ײٷ/ͼYH+9#m _{⃃ g^Ra9q[:lo"F) g/$_..^w)\AZDˤ4NҰ5oA%n`#dhCI$^AD*{n$43qDb"ԍЁL!&ֽX&檋,~c 3va};,_s,_{x`6߮kƢ-njA˫~PXsiK\R|7=KE#>ř+𓜻oR 9DGZ/ݐI`b<7شDh=/lR1cgJ-.Fr<0#Fi Al;wRbw-Cc\izřE 6"цᖼ%Ͱ]3""J`il,$5*j$bgr&O"CȐduA3FۧWUbŶ}c2G@v4 !Jyy0˗㞞aar# 5Y*(0 J߸0 OL$D]AvyvSϣOLH{zɆl{z➞ԚӧMJc.8bD5)D+9y2ym[o5}s{'.^D*))WGΡcu.<>1*,(GP/J;h`$#m:5LH[YvmDif/3} F퓯B!O,K6I5kQīhQ&2f,ү-fXܤKN"̈HSTfIkQl$O3h13""LnLXeׁpQP1c'b>&c6Rf"x^hӈuO-.1;{ñ';|Flriv0};6olaeq0ܹ͛ϝ%$>o};U>0|8Due$tc)uF 陙1gks²eXPPԬs/˭|:پn^^^.^.mݻyUU^3q/ZxpÜSK喃CCr0`\#ѫ':(@/<8|0"sz=;jޢ KnuZтn*tV[Rz-l^qcb@ķ[gGn\ ghsIcx~>q#sYsZE\kZ%NPX5C1:a7eSLot2@VT*TZD\׮3b̸}F;wFſҜGd#!>`(&OK s_6|pjmIyߎR+f\>qی3 !D:^PKG@`F钥Ո550-åRXeݰ7FÇ l% 0|8$&qL'QQؓSXB͛`) ̆ yw}#)~06y2ed-m@ԛZxN#5D;99@݆H:m?R.Z:}W;::P"gp䃏s${o5*Mcq0| :,w7nyN1. 'SsW>HH;3g"-! 4C`(b!jv2H ?Oij/e R^Rm| [o[/;-6ALdPYXÏ 13 xso={?zLǺC;dT%]>Co5$kah+6![kT-..ѣ3aqy<.\@PYY[YYyHhmrڒӧebA;^r:?69`x=x.`-)L~|Q`o ڲ5*Z}rrH!aOhMXri]ʥs$iS?{6=ZӉ-fLC .>lqXsJ 7`S'?H( jJj4ZFh Zժj@еk['LxȮM&ˎ7{G];\M2^̙uZڒ3g":--G,/x;Jʢ*-HOZjqii63o\P-#cAs܊dz֥\˰.Ν:w^9pкKy^fMJ;pxRZd/&$ ۳{,CGz "Lʪee.udJ妴u) ]T\}FԤg¶QS|Z ĒqM< f25i)NlcY|0&\)|?5vF%684i.4Z,R_JRVt:p8|P(trrvqqquu-ܤ@#i  j5ju@bv'iy@B|L;w堁&[AJ[;4*mkzҾ1L׃>_P7 9zDEセ@ne%Wy(QZ kOE} @XD %ȲČYhM X g H#m3)A 0k$⃃22?j52F2`Rk:Ōi` Hp 怡W!C0XD}ڙVr.cM<NrrH$\(#ΆmFk lre5u>>D)CեIFL QT5& ;45q-#qIW>!O7b"Zi PW$ 4Vh zKN_,{iU6LV{иIXYYr@"8;;wU>Q#Gˠuu`(Z\3g70_߰?'&ELm'&>iVH??|g >MDȮ0I4`JNG+2j}J?* =5aFHaB{az߾}9`dJ ,Yv5NX,=]Vt@ pxղG>)rzz*cq{ {[bE%-|OX|wט[@--#s+2qセKGn@{?D gЀԓ?=7)4D2l<"IJVfA+c1 Vit: aZFU+2é<|i_ɲ:upE@Pld V<^ KQwÕk֬߸MOHعwk7 [d|nݟ冯D1xJl[\X&셼ح}X_);`H¥JTVVڊg;l硔J?NsOkʆAPF =uquPas+:iV왍0E}n>z>= T1|{Ν];!5fI#|-[xL!jr-Oe"iAd8*6O़<GG a|pۜGaR{D$٠p22olY:~-2dl sedK[Ӑ tP$:J@NB{w]Mx]玘\Q>.ͥt;ׯa n=BdҢIZVZ!Z ؾ}w;<1:4zgS N7njA҅rx$w&֥̚O6"A5ʧJk#-f0zm\܁ w& e>0a!ĊU⭝Hk3Y友;0a"9ٱ=>/0YSoEt>o>9˳rcӦQlA"|[=d_1(Py P if'<>0/f[g"Gt:Vն^!Wkv^*3F=tLdejLW/>;ZQG#ݓx?/ΤEO _ GER5GsǟQF&_oyXd/hF$=wgu:G}*:+=5WEB.mX1CkА"Vcڧ;DZflF^~V#e[ h6c\Q-3Z*V* *J5jVcKQ%]ש/k4xuU@ =zu mgcX s35K~?_ ~ٝ2[h6:xFX[vƴ‡U<bc,&1:xs\pZcBg88fS7}:8ĕup)].dK*xרv9Ŭ7uگhVMd:gK9Y(un+p8W=ο3QI]14 b08:W*5\(H-BRqhnBm.--;p|ؑ;;EPoOi3&L>C h!4◣p`MX7t &G}h`0`:,0oh'\jIDATӧOؿ?/f{A{УGY}饗a"+l,nJcw^nkj1Lysbnπgs F@@hcShuZ\0q媵Z+ʲa6c)܅R?Reqhuر9q:t~aw|z'.ZTVV:ml)$o{8perE>!n/6|􏀀ƴF8ZhXfxJ*)yHDL"+msi()690LSc5%~E(@(qR՘*IENDB`Docs/Chm/help/images/b64x64_kgpg.png0000664000000000000000000001412513225117272016032 0ustar rootrootPNG  IHDR@@% tRNS/ IDATxzyt\՝wRJU*Ųl+llccV4f:Lgz&[Owr'N:NL$C&4;fc6U’,YTUmw?.9έw޹{PG>'{x)+@$\PT>G' Pu !Buu˯9Bcݧvdya ı \>/0BJB\<` ܻH&U,锔Ch BS+53 r汳*ƩYs?I;@ߡC Ohnpïa"= @p"A|__;{W^UԱw[=I@H [nid+_ A@ x 00߭}VbUtzM]aj( *'{zW c2*;.ToxԱl7lXD( (i8yӵWޮjg^j?|ا^|SvVQܴr*+鉏qY0A2sЯ.~ܣp( 0r0D>?{:׮@"R BepUaB混;NZW,Pdq]6c'flꁢPTD Kʖ\j73C ;XP@Fm_Fպm/y%7R4ʫ 4pX۪eqk5]ra` P@4(nPAR\BX,-%Knߨz.J>Y3ּP/C!`*=^kO:kkXx.kes^˻CB@͇JA!<99,L jӅWhE Swg 1޺mڴv6fA`VaF ,:heG'c,:: TAfؙJH`9(iUA͢fnB)<9x<@uk+ŋ >%㐑PnC "q܁_LJRJ!86\!œro@s[-,KrN9i(!2/zaԱmˠAJs2h\-)*GB@Y+3%e6ڡ! ǑB dn)% .S< Rr)ul9Vζ P***fO͆dP r%11/kIaŤ ohty5(L9x_ θ`Bp)8̶Mf63RVL0_$J QG{qH? 悓4}ើW:- IQ#eq.f )cڦc6m+k[YɳS%h[:gΧ3PP֦\y:F,\HS5y H0t*N8N.eNfz#MsBP3ɂ|9cԦEmq,js#O$zh}hUtv+zO>yzoR[g@ ?w`9O'i6/eTm<⋫oYVfBJA3(CmX6)d03Cݙʕ577_lWK3U.'ʌF9VyiMI Mʦv]{Xyvג#a%%g B0g1Q:uLFmN-#쎵l/͙3Z;nQVŏzȚ/!I:kF*&[>ֱڕ<{~cC眎DQ?@9\pƹ)ef͘řgFO8[~zcKpҟ˙ F0PS@"I)%B*Znڲkp宗>/x65Xw.xo~qd߼BѠι .8rN$D|q ~EsmGYBf.Ѐ|U]0b!BV9fNF_3.>b5]O?`(D38$d:rgP\'o~|7_/~᫮)/IH:4O6׹R,WFSQUxp6o\+ko =޴ټmۖ"KF:%}sWqMstƭUD9?xۭUMMweq1H!Ks= Yԕx~^J9:ujMA*PWtSi6VѦ ԕ6TB4N JvlodAK?:Sس}th>'AJP;I`Lֺ[vD6N6/L&#]]L+TP3Ky=59PE4ɖfyS.aqcɬ/_US= QZ,obҩ%%<pxrarX 렦JiM(-<&D\׍@f5nzT4Fpe*Wu`RXEºUUdtHFzfb|ee N 0R846,L !FbSI!>"R͜d"k)S.őQYqYCͮΜ9sQmߞ/~`%YqSg2â0&G:P$4{ɡK. mp,Pπa2gO(Waf[H>^OgYվUX fqb d"@U !'G x&3ȑ PLC,e{_Ls` @

t{ىh>/U\*p'd\(*A@)]=8=6֭]n]e>{;ko#P`;EMx3󮼲גTJ# B͕'2s.M||L85;mLf,<7Ǯo\8ձnٲe˗/&,$!<aޜ; U[v,.-~鍋qw䖟籣o/nܴi˖-7܇}xllllll|l,6>In²8'k4PU\>A ip *[lE 7B?G7o޴im;o]:10 0MӶmJ)^OEQUU4M\.@R[~}C\F"[ںuƍw~?crqs޽ҿag%^䮑?O&/Z9IENDB`Docs/Chm/help/images/b16x16_file_locked.png0000664000000000000000000000174713225117272017342 0ustar rootrootPNG  IHDRagAMA7tEXtSoftwareAdobe ImageReadyqe<yIDATxb:i? `Ȁ@FFFvC|ojj* ={v`q`3+ß"@߿ ߾eg0~{ X~enp+F_1b fO0J~cP@,F| 2 t133 aHݿ~ ,Ï_x @P _rJ c^[Ggș3"¼7#R+~e|PП??Μ=O.no__3ܼP? ] lb/t ߿~0eWf``/~1D2h* ï#\@,` 2/ 7e*yAhՀ6 b%'; JL \O l3 @@1fd􎁑OFY ɆNc[HM}Rl;(@z@I#0Çl L E?I7Di9ALr'S`4210Gʉ@:Ydx)˗> ҀjYX12Pa@Y^~ ˮb_IENDB`Docs/Chm/help/images/b16x16_ktouch.png0000664000000000000000000000126713225117272016374 0ustar rootrootPNG  IHDRh6tRNS/lIDATxuKOQ{:tVHK&!ݸp傕#Q11DML1l\`@A )]:L\,x$Iη:@=lP!#aOlNJ$OwVzf-_?L5UZ^BZtmlopӟ>V+Ug?,U*e`./WƯԔ}nq}-_siIENDB`Docs/Chm/help/images/dlgbanner_winvistablack.png0000664000000000000000000002363613225117272020751 0ustar rootrootPNG  IHDR<[ IDATx}yU:ݝ}# $D0DEdtuFGeFPQquf@5A*"$ $$$>T{ow^wSԩSU}z9" ( ,MSKSTAR'.ѤN@ >aFifffaUu"ֳ0z)Is" ,|CzZRs$:r" + 3Mi =$J5%" H^ @D e-W, MB* [i+9LgjyDB[(]Xawf iKk"H*J ȉCG<$BB@a 0 ރFVpp QQU(lӁb v ޛ0U#jVXa}7 >h*QT9eH׎̙lC"5 rBAEU3qN!i&$H07%,:d8^DmVC|O}O\!ז)y_iVXa=̧Q 5a&|)Xt9vH ("BU H(hA7f>"TbF3!ANHFHDm#fd*oql#!\ 득F{ԧ>qBD1uf bnn%%dz@AeT4'>j|j{zOMu #D |<37=͂-L/$ .Fl18Mὥ]Hx!$)-tc&D[ۉ@H轑.!@Q ( QK rmާQ0xSHe:gdዋ_Pa6hGM!*"Ԁx>qejKI.u$.T%Qh$yy :Im^%$H ."/ &.9bD0Ixj|qF.na>=I/Xn'|:uZC*!02ME1T "Q.2]F*#^481҉4cDm7O^莶u=r_/7—N*AbiShu#\SV? A A M 6l YTDD4bwqC% #&}$* !)1uTE2FG0^,Y٨p1/̂6 dDڝ\}_ûrґ1nCSgl =OMUh6$;FGUJQ"O3P"TDHLQqNNEe ZP\3)Mq kzD#{3S@s5 MS46s_/CyL w r>nn㿟W}aS!;CUoϵA np,J-$I8$F>&CLO'Y T#Uv{GPÛyL5 BFYC}9y"7/&8SL?X;X6\_f}o}S~.ԗzn Ϙ>w*_SXaFtN,BSiJ}BMTA~AZ7kq?4an9$z\_.qߌ鋇H_>cWrſ||M<(_n֭*׭ +l l^BQ'y>ՐwFz H<ebAh1ȭ% jG`l2c0XjD_==ڤ;1n{I&O; Ϲ~I_}&cS>a>x{։GN`K 7[>ay[v(_gG,`U:,\EB:' )%%(}Q> 69 ڥu,~A&TgkrP5SZcòњ6G}̼mCkvG~weά'S7}f6nTkz4waNtw [_w]3Nhơ77ٞϖWPP f>F TcUB\nk,' $TDt:>p,18PdR"H'b) /CmڄyeJK pYQ{`oٶec#])L¸GKcL{s~ݦxm{wxVqD5ݵ~Ã+zI`;f,ځfs‡헷]tDϭͧs֜-sذmmh–[7{͙Qn[?O~ێ}oi>Oւn_vaCܣZ0d)H3Ąz$eDQ@3e#Fʧ(F13^g6)QVp=j{X Kx8ڐ'jl{+t왭?u>Pi3_O^qR3,Nlt']WyW{sG|8rgz -M+5kw՛}{_ eg 3S]"IDBLK0($ @%✺:1DFͧf2K#ip9ƌMewUbCؿ|[N]zǵC?袆Oim.MM9p;ҟbNLNhZ!0tmu^/۵ vSzܶmm47T͂ F=uXAoe =cƨW͵C!7%DHGR.x݃kg%URKLȔ;?jƍ_nqSb\ َ&&u@+0kCU1![~qS}2qْ}Ϧ_?;1q÷WX@va ׎9|{뒻ՀQ\YYJBAv3MI<My' L̍m4?nv2g^uHۚg6nһs+?vU1czم6:-,R|(1LASqQ;FSK<;wŽ iVjw?Ybi,+F2vQl8s}e;#F@y㷻ojwԧ64n":&bە_jǗm~Ӌ\6:F3%ô!`b!h,X3U׎b>dՇi4f!8!HՂ la55&OK>?~rm']s26z$ǠLxc O IXk~v_@^l!f!9693vU/΃݇ߵCgs^*y:^s?>6˛ f{'c Po{^!UAm {5#feÖWUB,8Rüz"dXQ{Eq>Њ/M@sw >?}7;f,>{{~wo}϶-i yڷs}wk\G~tql7݇uvxH L!&8(D pehA\X! Y0 =!Y}5B@›OV6w1>YU\;XLOYhXv0h/.wVkצN?a!Xș>d;k#;g}X~zҥ+{rt[s0|eok=b>s֠kR[oIm1wX޸kޭ{{y?#[oTo#.$QCh. q8IIRFXfRbff1 qZViB#LC$= r>º>kv*0hl4hOwӘ&boznQs?x)l=h]S΁w~Nwփ GVqg^3/̗.KՕV5_.v[a9WX=WֲT&5^~z˗M׼j^F^~ݎRM/j8@ A68V$ڞ%)bDJ򪑈<IiBƒ) /b2Mia@m ;޶ࠇ_\mXy?"z 7{W` AL] t0KI7?񹗚qx_?k#uM:ҧ]j_]wW[O;[Wq}N;g-c9|nk=bU=gؽOp\]ڷN;a#=(|#!+j+*8׎ Xb1Č^WCa$ @X`o,Glqz/CFݍ:lК ƣnB 3xԻPRD!1%5io4z5Q@ /i#=}CV; iڵkᾮs|$>~Sly?Ǭ`uL8Kvnzx6^pq3f_y^__xuq ~?O:Uה_|ʪkjܚ/$Y{orߚsMGuc=[BAVƣ~zwjSp$ta u!qpATPYdQ2Z6(B@D>p"ИNI)S4fޛB1űk[V :c]m3fksڧ^}rl~g Ǟ ,^eQ g =r֛g GuLfr gΑ&mސ4fGs]`04v`6,8rA«XmYyЙl_r( '4 ʕSP$KB5n/Eߠd# PЙ;Q@C\,'ڞA*IȔ/PPkkflu=5h)1zhKٴiV}ASW_sq>3E`K =f?{b-zM@K%,Am^|jWb=Ig07UPЇ%"5@5-ǾQ>ܧ;fnӒ̞׮^,D^tޜ/7=W_f7Ua$j;!)U5KD eAm4d:Ӻ4uPK75Rg0T'MYcP!&:n,ypܥ>U[/yHV`fmӦ1{N)_m9uF*QaD*pL$a>RI΂|"s ^8_AB<:̓ !u!T@tjT5S1,enPj ;j[GZh37>lXl_֖W>jsO6i/FòRB3RR *JzVQ3 L,'i,NL՜$1>vEUJgIDZcvW,|n~H=;cs}:aOW͵FM* A.PP%ej&{OübK4%:1: I[{Eɧ"VH*%x !$xq;s\l{8x*vbOsWݶ߼bBFcC%pĘIjQxfF ElR,MB(T1Qx'P5l,Lj bm!23.P7=~Ҧ~x֎;4v֍.Aڅ6R"PЄ!5hPQ+֊HAm,v* sBNCRP3"P0xhƻ3L0 UP;@bY^ė) cvNfER֍Jîct]Xa#_B"Ty$8A3WNu \6 eR5oKmw"?Q'ć4Zh\K{} ]Xa߁IL\d"i&+i2CcDQ 4PQ(˶,U2dfi+S?:`DG^é6|7e UE%_5Ut^e~;`8;2a|746;4 :`+5d7e{}/Vmx;fDc|xHy\\w<'IENDB`Docs/Chm/help/images/b64x64_chardevice.png0000664000000000000000000001213213225117272017173 0ustar rootrootPNG  IHDR@@iqgAMA7tEXtSoftwareAdobe ImageReadyqe<IDATxb?H0@4 F| ###D78K,A16q|zŀ<S,ϟG/_$ Fj?~(**fee,-- Br?0(#!Y?BFo߾2\vƍ˯~@@ l@wkiie3((( L3

jBJy@,X򆱌 3338ųfd(.. {i ++p)AA>`x && ~&{5D (5  O< =zkkkPKb@>|ݻ ?f wlNR–u@),--I']< ݏ?fx(P `Db!A>|<JV"jzD0'P) ,lrmX[^=@aņZ-, _\@$gAOE j@m gGQJ#h`z?Jk2 `T<kY$C$  sAvE>l@= 3CfY ~N@1za\`` 8ɂa%8,SѠԃ͠Հ &9en341020|F0+h X>2ğ A9Tt w)^hj@iaC(<r4(@`BY@YVd01z06E%y?0^n`0S= .<0 Ϙa/?w8?ud`y1/Y Qc?a,a|Xl#F, >Ȟ{7Ò%K=N N(?`c+fA~ojί~-0owwiКc zg81<̠uuP6oR #\#aGN _|syCX(gd=Al`s30ꖂ%c'EU lVR b@b 2L @/#7r k ׯp * @A{°4 zz %e@]^&$=8\a&G y' P .Av), M-$`sX0p0xBn#,<(  w| =G%yX}y8>} , < 20< \a.v)y %g..b*h _/0]p \ amQ 0bՙ1Qąx=zL!?U%0Ssa} "W:fg - N@/O?2L뼿 硱7@1a#h…Ǝ'Fv(| ~|gpӎ׼#~~@@ssBjOw>0L뜿?c`8t A6/pv 1QEA #GNce022B<; !!p3`D0=HNA| _{0pk3񛁛|~ \! ~eh˼| @у@|  lСCn`*(+4GGOD] sqq3ܺuX3ˡxDr@ o'ÿwo>3l0dxMC/Mܬ\?g*}/ 02,+ K >]YWWϠ$ },e.<,JV7P  €j 2h\`/$g[/~eLQ1Sb\~s}7!:R0##ə XyG£0>$EGq6NN.xVBvdfdxƥgʟ 1e00\}X -Q:G-; π|`l{11P9CDeH GX< >|7P(+޽ "" N)o޼CG}x^Ͱ(Ït.N>v}=7{ߪ23k5VȞ \s:wОt r@BxuHsϞ=gz>}8 #wOrВ@p)/ z^ZWoXX"-C<"U<@`(0+O" N2\mt,/9+l8eR4| V_]x浢)gOjk;uZ\\ae߿='0)x @kl`PWWc077/*yB~1c?9#u hTo|f}'/_: X/biV谔*[<5US)++dfx0IgԀY.BEp` ;R ޾~N  " \10KK((h;;;2x{{2- "D9} -zen~k@ |ZA 046  X?pmpp楋_?:vO0` X **(KJʇ HU^VЂhii)<5sAMׯ_k/?~|ݻyXsڂ}mvoL&SfcdffVo@7>0ŋ'w#Po cZ4+ ~h hC T?&W>BKl@ kzք׿A+?77@14 Ј`>]W,^IENDB`Docs/Chm/help/images/b64x64_konsole.png0000664000000000000000000000671213225117272016557 0ustar rootrootPNG  IHDR@@% tRNS/ IDATxZ{չy"F r} #ׄ^ )ʣ1UQ&J] %1H@@J!KUV B*,, ,;;38}N8ݧ{zf1Qv{_7*Pa>9Ѿ=fM;|#"_DD $D>ԣ0KdxDz,"с fp.cƌikk2eJC6j7x񫮜tǮI7eTHAF/ nŞΊckV_DToK/ZK//}g3M3L58j|lѿ6;tn ||B tc]1>w }g_S&_㍽{o/G:? /0® {Qy2Ɓgڽ]]o鳄zqL'] J>} !#?}`ڴO3ovuU*"ԎЋ!RP(Z[[͠fY{%Dkl8N\>K$`۶q \ 8k?@<ƣ[▔B $A(RJ~eqժm۶m­~#Zn& q<϶m̓8bѲ,T*g)D$LfX~xvT:~DTFӬVIH !˲(N97Y.}\m[j_w"(R f\upG)5uBGΙ3ѣDdq\(ժ2 s@!H6dB@`^ȶm=Z7G馛 ,X`;w>oNٶe_@"0&`|)W,ar x!PaPJ9sZjҤIk'O9q `,wMB" 1(0 0[ȂZ s]sqٲe={lٲE 1~„3fyw!WcWz>6H  (,8oѢ}2bӏ=w_@5|Uۮ=4 JBD`ārQH*\ ˂#n:e~wo{,8N0N)V[u詚CkJdā P"7⦦H\q|Oϛk^=c.tJAB\u5bş^}N=n-pL?ŀi"I'Яt-^j)!IL.wy ̙;^9rAFH@l"#Dn$D(ڿf@bKKϻh]wҤIkz/79rd>~^f% Úx&gҊ(pHAB\ǮC6d2@BQ.7N\7vӟ엿5y s!$""46T.pæ5k6n̺uŻKN_R,Ɛw_yr9(k &rtڨ"3\Bo5gD5sR*+="454?V}?0DH]v0yN^RH G6NJ=mʔN55Q!/==^;v@.&WñPo(EHHi 1B .k%Ϛ>}G> Iwwڗ^kAKKMR5uu*OB )1"PR5 !y'ecݻ/hU Jݷl٦m۠Xb1^`*4LC)`}د# :sZ> Q$.)X)ZZ !2hnI)}U^93H{@@"#B*.HV*qng7) !q2Fu DDHJR2љE1Bj +_zF)ԑA+O[#e/bD+Ce\@SRHH q T)'Oꌭ)Y9c )-!(W0144&\ȦRC㹉|ʌ#8i1l+~`vuIju JiҭxQieQ8ƥRiB8BD_QkV[-gXU_K0E#amyuVhΕΘfE2 7UfLvp}qJD.(HR! ud@DgۦE~s%n53b@W AU_.5/9L&s =OԽis%UG?JO*eqS 1wTRzMNH&UV2Aܬs86Ӕ&#ףsӍ /U\,JgW~JL&sW|3wsnkž8tIENDB`Docs/Chm/help/images/b16x16_make_kdevelop.png0000664000000000000000000000171513225117272017703 0ustar rootrootPNG  IHDRagAMA7tEXtSoftwareAdobe ImageReadyqe<_IDATxbTUg20 4*ba(PD/?܏ l +7˻O 6D@L@ 1/P+3ׯʁ߯o@f`6?˿7c ߌL  | 0g//_0|p߅ ߟ={6@R_ATOY^7 ߽cbXYx X10 c(3bkc)*U~ Y``p018 `p 0= ,׮3toDZ 301ef JFɴ>7蝿aa`e{~3(L ,@w>2fgg ڸ?oUJlaA;b)KE}IENDB`Docs/Chm/help/images/b16x16_filesaveas.png0000664000000000000000000000176113225117272017220 0ustar rootrootPNG  IHDRagAMA7tEXtSoftwareAdobe ImageReadyqe<IDATxb?#c200@BL@VzIn؅\?w' X@Beڒ~Blj4?H^ < _=Z+&yS=>?  h; W/^`ng $ @`x33H ]/W?3X0>g`a W{0؀?h @?@1 fɻwƠ)DSe(tX}6^L LL c20|ə _TN0q)Eb7P;3$YAt̓s_2H)10< ù'u ĭx?U}e & Ŀ?_W1]ge`0W /41țx22F?F Ͼ0197ßO3Ch/݋of|,=^`0CR@]p?o~0~}Š '0\eaɑð~Ù,T^v_20( a(piGw9fjG[;X] oH0 ~0u)321(g2&10 Q s@A\o 30ea`ffx9gbc`bxt)LLg 3q20|_BIo |f_?dY~dc?X/@]pu̓\|wg>^Vg?!NYɗo ?aŻ߯9@g:|k㭏IENDB`Docs/Chm/help/images/b64x64_package_system.png0000664000000000000000000001721613225117272020105 0ustar rootrootPNG  IHDR@@iqgAMA7tEXtSoftwareAdobe ImageReadyqe< IDATxb?H0@X)c$.$Q}m@.!|]:; fCA|^ Ȱ{2 tph%I;Qzqjm*22)NlrqR0"p4ǶzY#kdl A+qL"$J5]a&@"POOGa[Jr\f36^T$Ƙ!}');b8@̙18>ù0 g p]sÇ_D fbb' %%]cYYY! $9$KqqFx=`.0E1F,s.>{{^X_@֠n6]4H)@G)^&++wӧ?^^.q9s[$!bcxX8B< h03B0ӠBV3ʇ O<ƠP+/߁ MNNqqI`$GNh & j5߁9?B$J!fFyfA4@4;0[@]3a~AU37>d gP2 0() 2a1 M = gF&Fh@P>H? ;`ͨl!,4ٳgАoU"@Q-;`B*@AYE+<ˀIfEeXv xP &@Iܠ#s{w1{ٳ Q҆VVPz^w ?7fė/?u=u̓yXJ@N `A1Z@1dzJtja l=z鳤߿s7@Q->~﷿~, 0@~B )IV;O-, U!rA b (V[`V|W`x q9jW&|Dψ| qVV lit6,Xap|Ɛ -#\~_~r9 v-_|~-C`5X]p3Cb)%xe+Οpbvūw ׯf{M`ҿ t PbEv3@P3!|珠*`gg6$=)OHu?cF P bo@1W#@jPc蓧Ν=pW?Wn ϟ?M߁!ׯ?)ؘe~z{`zB\@H, A@M쏟1(p01=dp{ La n=c{ #?|;@@)=`rSu@uUd~3 *Q·'`́;mC >UF'49H ѡ , Ngx GG/1p2HKqܼy4&@Q5޽C]ODD=A6`&"" ,60&A=A )\'jJ@'  IV, >>qlN=G1򏁃(0i28qo~&V`ky@T PNu`zk_`fePf8vXC:;X[V.dw~ebː`jp+0:}G5 ^2$0?`x.wl jIb J"@Oz[ 51 P7= .;1@%Cn0۳a 7Y0/× X(u҇Ǐ_vp k aEXAgzA) ; 1! lR Gcس Ágl O]~H?0 ,&&- ^Pc! ߿WP<=sbx mˣ7!gYAga6r0~;WF;29zWY7b r(ظ{W||< bb@CGP .l!1! ,8޾f 6n1 dF`=88c0!Aڝ7 c+, ?M?}'F@/:/ ,,<<ٽD~*@#45/V t$`z^}ʃML.^ð~-n3\pd`Rqfa L2pg !  hGPX@? RH31»̕xO&03pH39raρ g>r1d`gv:??ag> 2 r dY9hTPPCׯ5@*SE0"i00 BZ{6V6&`BV?|}>efؾ};[~cgf0 {ؚfd`ge& ~!\Rϟ? U?* ܼ%0x°_@ 締fS a gعs3ãGWu4u[dl_I`h?pWp.99y>| "cϿan l_Y5e ?޼b l$~27_)6Pb4w|ć}/~}۷>]vݻWA`Pz 553xɓ@?'+ `b86o1|bxm meegf-~f=<$0`x_|_ۧ߿:?sD ?LL4y=7/DC~|`vJ/3ԛk v'uYYu{xqϟ< y^{ͻ?Kߟa|А(:=D`eeWVfb&Qy9;2ڹBZAՃ; ?=f11c0pS ~**2H*A\$޽۾:ux߯_?/xݓhL\@T , &7o-nLcV  ~4?a.3N9cS`Làt.?߿= A?b<BDLDڎm zo^apaЉg/(-^`5Ç ewh?#;0deݓ09VKdjmr{Bc0UWdgd+@z@=`Š)k %L4@ ^p}-hrG DDǿ.V`w`PblypУ^] 2|v~/Ff`=ʠ L1z۷ jj 2jjϫ  GKY@ߠ|w |ʗ{nYf^t ;u)~v_|ذuH>`m6sb ÃAU 4c $hM 0#ci B'1IO?0|zqA?Wx)`?ݻw'pQ`g6l @![=n g+Eׯ0z/1_B<3&`|pSܞAٓA\# ܼ< R " \,D?'dD Xg‌2h`h+xIhnTxzٳG&M{ 3™XY?Qߟܐ  @6088_C?&v^01f +Х44J3}"BVfJ?/3|<7pQL B@-L llYbКC&OtÆE@S pNe^ g"b 4AyA|?03`约 @kih3Fh~;O@s3 7 R|obJZbV` Z4H/ PX+/7(A ݿ7$XoX~fp)f=22X.q,oeb8 T} woxIBP Z}^).)<(fY_ ~bQR3d ̾vÊ_zd# 22z1>ޗYk> x@%?!p`l`b8Ǐ~rX?4TQTVVSWWgPc{ 4s 켁1J`X*p;B=h=;#4yIdxx4TMutt$̘%o޼z (xA>}z$޿?~+ȏl=C%٘V23JYZ1fwd7X~O@)h2B0h4[Z. FJJX )ͷo_=c ßoЮB kXF\l/p= hL 33ձϾI'%c@^L@, ] ̓?vd-_zkq(f<,|5:/~12 Kpۗ~:T~/@W_<C Up@ 1ߔ"@ak 22jZ11 01`W~ Iנy~P (X Y)tsh0o< ZR@Ɉ @#}8@PߎO-IENDB`Docs/Chm/help/images/b16x16_binary.png0000664000000000000000000000150713225117272016360 0ustar rootrootPNG  IHDRagAMA7tEXtSoftwareAdobe ImageReadyqe<IDATxb:a߿ LLL  Ab lllR1aX?X{@%XQ3@U陹dDpww63'sl0 @1bll\#Vb&zfZ 3L"UÝfO1 rǏ60 {$r.'߿@jA@ -[| R6A -7@~<<< W KQ(l!!؂XHRݱ仫 \  c,l>d  pJx "03S.nfF}(3 V"@ MLL PL  9PX X@ ++ ,kkk@ @lk Vp @A 1H  z0Рh2f&sQFEHd !V6mcq%E1C6hwqk1$ Ǔ\+_H 9kޖޕ;P݈;1Q"hub+rs$H ¾kn@AH1>{w2Fbr@#hᥙS2\jh#%Hˇԯś7CS]-FDŽ<Ŏ,ia6dwOe3f3R x97+Հ 9ziM#NxaHUJ4hg٩ۄ5ϢA6C~AN`C@sx0KT+ήKE&wD%YeJF1 C:vK!KXi9HchV;[Lj Sr!r.A\pj mPT1!M:*|4RI[ᾔSsS"mh4JT񪘪!͘*uQ&D6JUq#TǛh^QbtMߌijZH]۪ͬmU82$Uz5cSc. @``@x3ƦrfzӸ{3G+szbg1pP\¼ j S9R{,DMGzbG"0~te:tޯ?g- FqF_230R!zzU39R*ےO+'o0D'fL}]{iGK}򉁵kD@ 8@@pb'W @" @ gΖ2\i#/Ճ?oPт ocNB0 }jZ\u8AzbsyOY6ڂ223 7\ƈOb}5VjT'V'3F3]]_2R B4ђ:n# vY6xd0]J֐,%P(!,K@  @Mp6.X+@L*d ۶|;^|7/5k475wEXTZ!BzYkeYF#t*$Gf]96OiA"L= ozP?w#/zxBp>{du@/91"վ">9E93kP-'SF1ZH1I e- 0Z%@-E (9>"p̂mS|BR1ֺDbve#[ zGY3T L؎)c;zB}QSaB&e52@h Hd[zeu$֊ &5G"= +![sJkTRvTek[߫~8 C[YJAK CRY2b'?7?V+:'ȏ4 B(""CJ41~)$"BLQ;@O݅T1_iCfAh jiWϜ$ tPʵFAh/L%< 5iY5S5w\&4F}JN{{GDO63k\(KCam5CSLz4` WILSSgMlWssN st6aDZC J5 ''mv>971|McèK,5 hE`V8C@還@ Luj=(-W̜|F5Dk&50iE`+V4.[n+ꆩMWnXbNزms}g&B("Ԁ4kt]jD RQf"AHD(%!`L02fB⭳|w'GNDoW(y?B:I7Rʞ9 ٦Ѥ6Ix{̀*'\zxWNKR8δtLnɵ˨ϮC1+ћ H[٠ḩ(F.Hl6Ͼ"8zd;# iW9'RT"̊z59szG#lMCǬкIH`,+~*&&F%ձ'M,Uw~VXxRgǀV#&$C3\vU{fZh%@,{}s\S%0'N=0 !b ZXLD QD, %@LP"M1 sEgڏ-zW<@sRh ܄~ jI(&, t>3 T )q8K.Wk^$Ξ5fXGZ1.T+;Z\ *"|Ⱓm(F "U̧jb, ]DqbO F 9<::S&!;wPG/'eDӬF pUI?1~dHU hᤨ W=tr\DX֎KeXQ}V#Pd2L}8 ձ?}M 񊕛~{ y9~?N??0 !@iB#mv^)%cѤB01@"I"$msV]dah2w#-5Q}꬀Bյ"%_tnʸ0Swcn?N ~Qv&P+ '(f$u55za<[#;^ubÃ8RV; uEj"3 3҂;Ak`\PLuiJ詉b;:KN9$ǂرaZ3ȜE!.Gxw$ elCEP@jsחtLwvCq[%d݄F/p!IIFZpG.<xwu ok[|q';𮿼[~wɜQb"Mb sm~F[rd jL3@?s bF CB<,dgZvmi⿐T%;rDQfF?$ }nzm )MǾ>d"{ߓ@8J}l ACɲ`tv^vdN\M2vs+Zgh#Tu1<1l@stT&p￁dx Mɡ`w q7M`ϡh3F`0^M"J݋\bp$ ? D7  E[lƼ a@ ։z7vZTWip~ʴY|7JE%>?oׯ])!\,7/Wywvӳ;"T~EPJ@ u@g]>!Y\?Gyt@O;,Pr=0F$zFM&UL%iŏu+sb7 n#v7UQ@*uV-KbYM !Dϼ~_odfܺ21!aB cLGI,uõƚC, Oxn*4тak7"Ia(eR0_+޿0߯g4wP1;nxiZfPL2\Ιldibݕ \sM]=Е2VxEz{w*S/ }cW?pO4?yK+fu}bcQ_jABDI@'3iB""թR:,y!r!͉^$C8-hMٟ7EsLG&Rdv/v~FVQxbH+FHPy9JI sg9-khq;8o"_{Y꽈E+Pb]bqLѲςOt5' >(@c <bHL Q 0a 5}i_:f˷^yo!B@ 0!1F/7Yqa~g~Ï5Hy΂ӧvƪ_5kT[pזD ط vt,Yнy?})quڕw7l _=/N\pډ N;uػoO٥7/8g(@w?8xvt;z㣏k@ly%n=o'W>v7YaN<9g/i}_8+~~N%_>D$%Ic($"8lgFXs :V#YZ*AA`&4&>Z,ޏÍj!$иh(r,`G?V'11vi(@#i*aiF ;DDɔU0QF9,ތQ 캔tv^tHG[ K &"<&Z"EIPN`x%@tO%pnVWMYG;dxȱ(7Kd/5bKEOnkmĩr Ji,!uBܑD@Ȑ3@PGm[já:{SO<2a)iRB(ap/~0KzG,0vԎ ǽ;+g13t/?KoNa_K`#=W؜n몯_y珟·o{'0vLs{>z~5lϖpHM ?)8F#&lBxlx dܩ&JX8q0%wh}@a#c,=,{[^9/G̙lHpL{4XT!AuA!{Edh(:Mዒcn _LZdTXIcrИl/S&bCY%f40jcVn^`Wa0bX@H@ %H` P  A!(61޼X/,]|_7U^Yͱz4<7^\E3#2O;g~o> 6eW5̸"Ajx3UF~b̭dbD?*EMkc,Q"P1 \*ߙR0ՅGWͻGĈ񛓖mxaٚw\w×]c)5BXF@&VyTw$X5T~%?^[O~@/Xiӎ>}Ͼ24048ăe2+pq?:s"&Q6B#7^0+4%3I %I"I,$Q$($%d(Ly}mvmU -.mU<xNH4BNj\MILoM'S*coV1$5nrN N^ W5x~0qϼÁutʌk;u" UeK^l8c=έ4-ћW]2cܼYS~{ulO!Le@v;ذ>[U0L0>8SZxӑgUz\]8q7WGwm)mg_ 'N=ǮO+`SY2 6.rhZG̞8fV&U1IDPP3kd(BS5㛇Z.⁣I),"96\W'LVe[1W kԫKZ_=Oϩj ^z׌ةkU-aC<>q0f>I_bv L>z%a %8qZOs9hr&*K90.o_= q≰u{cc~3>Dk t 贻)Ǘw4a+w}ds\ח|cWSoPXj] IDATw|vڥX !@[@f&DO@B%*r"ƫP:H {DRFڡVI(_(A" S73ʲ~y/TxWz3r 6ڰn! L:EcP]mAdWЄd&"bPr\0"k糵V Ek N.spc~kv,q3 KЍQ(<9RQL GEK?9keo OW(T5bQ)2kM6ϞP %[t긎Co] =o}gV PӠ ČYѪYr52x;ka >'\kb,YW:d24Z4eM bDwf?:5oZ5`td?fa}2ҧ!fl .b7֯z)46?#"n6qg_Ԍi) uwVVd'f݊ubSBb`pK 3!h3}i>#r=*B"0 /z+[ L~VG]Sgzb7PC?5FbEHA T((Dba𔙈)^ {)AhLD!SU f''^7:v# E}j,l|uk q_)7:^g(DtG7@D]5]dM㖪,cP㴏ńR;'rjؑ9*Qڨ%1r^`)tڍos>O6ԲasmP=TZ։znXOjjlBǟ#(Zngf[!Z%"(3)6ed*ˌ9 w.Ƨ00Pf\yTcr兟8U鳵:FёKXO7-^[vj5Pt6FZMvN l8Fx7j-^i&;r=1/V"}lr!!GUӕI#J4bl)BV晋BaDֺ$3B\zn/n[|M\zgM\? ~Z_$Ij-p_t0/˕w.9-R!)$KhMɍi bxP? M 'fNӱE=SQL+At@UmSz,pW ͧc,2A&TC!@@sQғ@,0Q̊`3&19L7/9^4tt6,LcvF 2 ]i, XKQ$Yѐt 3Fs†F>S_G X4,Z#tL~z ٥&P+1s"%:X,S4: Ē>=q{L {} lJF V򤈎&ft<b]\V4 7җjO]Fb{ʐz -1pnX1g<^g:Yܼ‘Pi9^K۸ݶ$f!]*&xгFj) e>\lbI H MNP]NK}bѢƤjzh))Ї@?42M*"^g b<QhمҒcU-g7FX۟6 DվZ.)&" )!Х:I)gR$2$IʆQy΢W윪ܽS(m4a(<\xхfJyƾ.A.K.97bjF QA dVá1*0ݸHep  XAD:4A*"$ŏѰ'xrr8%\rkTOd5 DbZ!z鐨)Pӗ01 "Jg`QT`"`f!\=KK>@`i Ji#pQs%\IF!"`"bQQBb"&mcvĔE" "@iT#KIչ'̦ b lT5FiS]ps%\r)T ᔎLBxe\a֔:)ӳƈ6AlX{V14DΈ Q-ƃ(0T8f8Crci.YLJS-)26!P#)˴/&+&hPmtxNht#%:$P7.ED$D!1;Xa q~ɵ\r%A[h)/ *N2 hƱƲ+ЇCՁ@S^|vՔ$ BiV*$SVrKctw]tdka.؊ W3"MeK]c%2ƙ֤($2."Qa }q֎a:1?~d} Lއ`X AzU%\ttǕ!j Ud[cK*NhtLY.9NE +L2C#c"KdYP:!Ht HǔP,HY.N<ŋټykW6멹ˁ*T:L'2%#t) dn_ a:nIrҢ ۨS]/Ң'F 0Sg]]IrHĘDVD̒H290iZw6E;DҜٳ-bꗗӳo׼ys.y챗Vg@K.*r"@d"B(QwpE`wJ0:2ĮZGcet*dDեHD*`U21MA'2vԲ`\IR_h1QVӲWڣڡ!S]h|xKKӴiׯxکϚ5!鲿uV[n_oFq=*5\r(" )f[Fm}Up=X;f)I"=OG8QʥvfNM(UbWgSڡW./ uli1KÏ] ;X3oڸ-'u\cc0<\il c)m:s֯ MMM7o`G}b(<[;P#=0\ry#jBL$# *`*E'@?2ep=N(QAV &XeEKh;0 Dcyj;;B[hY)Y׍u3Pi:@^{N;޽혣Ohhhش5 e U8sīg566yaCC-[7a^~KE\r%kUHTD"@ Q)rr^g`#úĄfQg(V-dfh9XЌEPXe%'.ޝ;wr-|c?sr-_I=iݲ'Mlj.䲟cy`D&XeSԜRJIҐ" f"P;V?>zN!{'Kt"gˢiL;tU2" 'u)I[L;{5?Hر#ut(P0ƍۻ{+0ԩ& ::&n(v%U: _nV}[Ϝ`]R ݆LiA"\B,IJ"): 1!ZDZUv ɐl 13n:$&J-že@DBU`;v?n\Z  P,657տ)J-*hkkyUV+q!'`7oWn%\P: U QK0`I;MV0 TfNl|TH4]7BZsrlUK౼K~C Eb&Gi+ wΞ5oٺQpMfPhA)T*2Sʶ֦$28g3g* B '쳯=8T] ?}㟿O_Ekqm5<&#\r;eE"D$I!ҭ\sTz0f۴ЫptD2iNBǐVcѱJff]MIuXrG9:u͛{ -K۷Oh'ڵl 'OPTj ðm#z蚈m:6l\;88(%!brsF_˿/Ԏ}v_g_,Νs% K*ʳSjEC;H HJ >1iGJf`%FF52!3nXEEU*!*tG16ਣXpNCCrlssSOώS'P* ^~yr޼FeB.}.* z{9sbh ֭!Qo(h7&Nnu,8Xa6>!U4,(aQ ke"Mceb OA]@!*?!p&fj*HI"0Hp㞫\c)NERn*6M25 IJuC8ąBb1PkӦM[|ECC0qb[))0 Xl83fϞknx9{'Mj P!ejզrY !V\CD>>=g= %\7L4S*Z6?}R*spRtњeYU*QpRdkh TR$PXSً47އ5me(s6h!Rg/t}ۼyN$•ҥ/#Bh7J?G9? B!(B@R"k71P,7mڲ|@r+e.R h_Ҁp`;yt(Ki QUb,ZQLiD91#j~p>rsf4Z l*bؿnnx24 ryvرcԩB-v{?̘1Rl5eD)y``6A DT*B( U*;<%\rcn@ !.lf4CYDRxGcXU˅CE% ~Tªh׾i3=nri}oR!sT.y$ZQ0<\j޴yĉSO?d*V֭5kV o߾cB\CC;w LX9D Cnl,rO?~9~qm{G5̵\rɥ&\E ^EOf\'Oa֤i59DbG'"~߸&F4 ! +[UXbt{t^m #PN8\i:aHAB@Oի7APS׮]U*9|][lnoook744\.B;0lkk2ebR3>}ƽup՟~"s%Q55a`U9j *Y N%>DL:3+Ȧ]$LIB,T $6ƚ-k)}w=3[ZJsPPQ/Ȍ;w,[f׮AJ)SfaeWnR.4]Μyn{C98XCY.o2 lnnټgBiIr%\=*ƙ LBժ)%Pwƙ=ӨK[|Cer7&{`rlOv"0%0ua ̙s dJ,B°v_|^ mm 2yba·̜9^;r65z/_60?gμIچ;?VzqIs%\!{F,CdUQ$c ȥ.p["C0]T2&,Z̪ohy ]D*+ ~rT4Nkt%H`{ a[[R P64@Dr۶/ag__(ܺm˚9cN>{ѢM퓦O?gq?tһ0Eo>3/D}߼s,%\?M$ޮ 4-j^21RKŵrVM܎1Z4l̠5 Achme+UC$I"U*_#CL \׬2n\Tjwoj*  @ ش~ÆRpbY{sҤI+˗?Y ŗ^5k`0~HՒK.W!T?Ȁ0´9vj$Y0Vt/!^FQ|D G^"Xh2%"O`bUT<)YH[b\f\DjOCŦB!TCC3'! AkƆT-֬]liӦr &{6,+\p-}woy\reEƐdAhkPGD~D,d,U8 @!wO6h@/u/!{dTpʪZ%:tyY3ph%V IDATAmqo7C.vFT" Áۻƍ_, px@DD8s)S=44l"7mٲ%bC6eT)᡾&onogC\--][ȢFcX]yJgc Ķz  9UC)T5t:1Hk[81C"%$qoIRQg;G x UGpߛJ"fT:4b PSϝ7Ν/,766ζ?k q Y, B$% bSKKSGغwpO5+:a{K|*φIQ' ֊L ]KGm&)($I d0Щ""*͌E @Cr*%R9UY 2t'_SnPJ)ehd@!!1PmݣL 9>X(3iEx`=}RsX p+vL6s R$H)訣 O>ueuԷŋ"ČDݽ [ >]z {\gߛ?o6ɔ)D` Bp(:^H"6?Ln*_*UU|l}(UVoڴ\?~ϛ7of T;wZjZ\nΞJ(y_ R ?p[.=onYgK~vϓ<$IfICsU';ulV{Au=S:ԈY շTzB &>~?l5* +,TJK0ZrsRu`_QIx`/a@@ Q/ GY$m')eҤ BnjQT\".go,H)73O2騣 T*APPc3t}ܤI0BP"bЪUB!xե6o(v}9_w/H}!9Qα3RNRgb{mpj/UT:ɗB=-ܩ*[|H=Ukڣ9ݧ/U֕I'wN[;COkl2 l$U ŏA_5Tr0q,uꈑR>9#زHd(Yez1z!;!ry+>˖-kmmU˗z--Jٷ'gh(6˹r% QRXl]MBQX8t^NG]mI !6J֚6IB$bU884r&9R[Ma7* 0yOn*n3s\Kӄ 'N:u-뺺wQ-/TytK. jp &fQ^Zu{\7nCdMZ L(lb` k1SB*&R)jx@b\ Oм~AƆ"Rի3?S*AVE\j K.+DDD6kI *O!@nޡZ٫egkI4bL * *l,tp9 G442a4~6q*Dk萢)51ϱr nKDŽWBn0 4R K~(x_w8KZ9nK.LStj1B(g"E@Q.:ѧ 2ؘtu;KA%hXb7 P:yLu8DG0s%\FF R }f]P6EթX9Щ1UBU h5+@Qic5% ADukGbT!ŘEK.󉄈M|)ԩ8BZd lI)t8(؝U& .҃Mtd,Y3<0n?! qpK.2jQŎ2Jl0XRm5c(OnGbxFTU>p%[( 1JCƔGK.K,`SȢNDq; 5 MHi!6| p0GÒa. 5aue_`-K.(WaS;0P']Qԣ b13,EC_*t\r%M _-XA1AČ_x9 v*&դ8Vs@.(0Ff#K ʕ/O Ss$~5 0;smb'nwwAq߫'(a4 _9W?ܺ^˹(~r׾wT}YL, ђF?/58q@kg~wg<woD8qPn>Wݠ3- CޱoL8(BK.I;cxWP!jR_s%\rR1ciNK.rPu!%\rWM`Ie\O%\r`Br"v'abra.K.?"| H$Z0Pu[σ~>M.A_"KFڡV174\r%7䲇BIXp~j,[g[6og 7jWVf}^˹2@[ȋ/x{՟7ϝ}߲8{ʔ)ܠ D_{eMCegol$ ˎrkS[~0IVo w3;Ɇ.zw\uUs=h~\rKہ/#%sO<0c3KCJ'|G-:nBc=PFp۶ nmF$p*!r-ןZjZ& &2l /ꫯ>i^Zױ># Y3K8~@Ú]wPpY1 Yg@εK."/JW|0F}/AɪK'ah Z(![U-:M] I*6\ 2'?~]/|'^Z:K&\Sه?wɂφYk#iC[Ȣ򦣎ڶ&̈́زjÛ[[v>CᐆC|I|]aR?#x۶mo!IBfhn9&מD{{OO;&ꞾM]wC%` M* n3VgdžBÎ;6lm֬Y_/;ޞ/ ^KU+OϘhd./:ugw~lCÌ3 >'qsÿu:_ryP~*rZ4=IqLj-3=wn8劏p흇֗7n#TZXd*o~*%jl( *a8vҵ;:9QKQ*u6f7'p|ӑta&F  4Iv̧6XZ(0q{{GR̵wm?#n׬I>][>s4 |K[gO>q1b9'Nvs٣ڡP"R"'pQ<%wO=~),AHYX6C 36]f͞`{,Y*%! s8@'Mn۶n4invBQ5\up((P!l$H(TBH`[.d>qĬYԹFE~]kzͯ\~T#ꣻEmtLS.]ﭭ;Nzs7͞;0);ߟSo o # bc4kdo<˽YI7č72f1wW{sEM$$^ŋ bDaakԩ'>u|w$7~|W\ĩGSW!TCA X\Ej /h+DScD"GrCel><=>ɓ'G&wr7651Ɔrw47(%3NMkj`*eٯcwuu1s},huer|ݦ ;/# >{l[hfNNo=d,,3]N:̶_-_|EsWrF{O$/ܹsM_Y*Iu|gig5ĉރa0 `HIO'V+wLJ_; *w /NtÜ, /}etttXa::: '&:tOСCK_"}["CC4UU^etm+vVgrDZ %^sJ B^x[/ӮjzUFNF)$ٷ*NžV0Rc >'Pe#EeoO_xf3GtI f0zgcW/[I ۷o߾BȾ},G=yJeTf3b>D1H yBt!c 9rU֙2I$g22u*:$N|#*IɕX:38e',]t`+Zﮃ3ȰF<73#>3%:'.ZqMa+}O"M C"Ѣ2J(ay?~_~Ϻu;9W^sf/ y=GXם p޽ ,B8 ?gHN<ʓHaaD'%D+f)u`W@"kr?eJω'MpAɒzO7U[ IDATMi7nȋet({4Ȝ|ss~WWW޽p¢38n9޿'\2ϦϕJEA,ʁm6sgMkd;::ӪA931 NtD7a0owݻwh;/|*ߪ,jh3#,5a0TU:54W!sn/gAW9J.g9eT$c$b7ej0fl b,ŋ WXNz&-b2Ɩ{Ǿ}xzܿ}ўq&,?yrccN=mZwtgQ^{xG lbwZABz(Xg!e\)_gS}]!M5\(%t{tRBȫec߻w¤4I9J b0Bt#0|1}DzW?=Vn`JIGO,Ĝ-{|擟I ˮ]HЃURun8zMss)'덍[xS9맞Ymƒ%Kb,"6:죿gE8n,˅UC&CRڔ+D%F /Ra=g}g^\dɒ%Kef2@c}vH1aZ|pQvG`,|>1JK_÷MPXP|{3 g[x |]5 -coMG.>;$@M!dN2LTF*bzTqHxl]1P!)!)Cj8eђWC= Ų a)59QB|тB)^Pa*^(lm9<:Z 3u8-juDv#PM }6im1^<=keCɖǞRxõhJm56B@hIm(:HB b_JM"a pz`bB+6Dg1N[}RQJal~A4 ,oPEYFCY쳥۟axi?ؽSLıd#8vU: %.wrZfc@H#O=^KBLB0t]>|zCJG˘WrY?=lok3fϛ3{^^["F Tΐ8 VKըj~h"gX w>|ƒ w>i:h>lZ#{K+O83T{zz7|wl=OHNmKGr$ꎍV5yH#D+Go2\fs: c=_Qs24+!a,70 #ΟUu<^B $IU~2h y0ޭBQXNY=}꥔0Et~f0YVWoUN_|0D-pI{yl Aо\(PxBaԒ̤x)~+j%[~uŘ5;-oY^bP()ݕbX ̱ \a<ģC-HZrHqS޳PjX؄|zh,e j]h/ٿB)t_xRIme U!}ƼI3-E69,,+5h7uv*_؅4%JœhKi֭]>( Tu0 p D$E3%3O}wd&厲yjS],D$$J=[cɆ;d60tq86_J$@hKS/yw`v{gE'5߻HӴɿ;_4+Z k"a"oh6nn~-I']??q2 >p[An%la=wmxAJ#Tr~9]F/*S1+br#GBtyw 5={niS[=\se ;>>> tu9Ѣkc`\8X{f{L0yx-`r !~-MF:m/Ke3gtiD~ӧv>׻.W%~byad$&s?W8o]OB$.!/MZcǂi&&N_n8(C-$׏9>ӻsWPJv|wj^:0 UU}5?Z`e^6rGDacojx - )ՋE&|iUu<^B $IU~d(K)!yа (X^~iH)QfkXvJXVdDREdYmun?ෞoM f[0,l`8>hxG0$'?Q,cq)P?l5;-oY^")I'h[0_f2"]k``NHoT ̒P% ̃[]hb)]QEr`W 4 bJq|ۅضi|ЪTU~&O\PX[n vuסm<3{n`]v]y啨.l!L gڥ7A{H]$ե4\'d:c>|U IeKZ|6ᜩvޏ$W*61$E9zh.M7#x~N3馟gUaS ~,&9I%T%v*@@^J|$I3fr)SDCOtLuOˏgǜ3~F[*sșxymY9,DbqRo9,} #.!dYRd))(,Kowԕot|es#~hEm~үwsKNˑ7w=_c~mͱ뜓OiyJl]Esgճ>Fg%x/C6:_82vSUUdMUUQǙ͎ ?8p=:#> s 5ymsɘ_;2I:̃xn5NaE#ҟycx;:M5)*˅9l6˿gΥq#~ɉxIZfcE1k,>:ՑU 3c]vڅ!o e|֡*Ȳ,˲$ISUUbxPrF(ϱ| HA:I"9Z\ 0\i&2_BBI߭f 2@#} ?!jYhCy켤g)kAvaⓥٌ},ɨiZ!#:o8փ8θ/L:V+'r.|kDRP4D"mwwA ʯu"V{L8 Ĺ뮻={^Pᢅ RY !t;/y.uIT0~ j'ERʽH X`q!YW%F 4"Vu9 uyAH0ExqӤ1>D VϤR\jJQC?0Υ% MأhMO CXFA,OK=Z@/! m~P rknZTyRP/H<7ae)PC @6Bԏ:dV}7iU 6~$lDKK-7R[xSpldxx[QMLvr% b5|cV@|)bG=Wze-BSC+l#>ROcKKkn\EDV1Ӛ0L6Wc{4K3 ? L&L槻eW?9[f!ԇRӻsWcyBtj^:??S;xy'~1fT|NH$D*`zh'ϬJ)%0IT%69bq-dc3bs f]$۞]s 9 >TCeH¶x0 L/ܯ(5배4y=65Wv3.`NWכPЭ|=/Nf2ZVcn*{~%Rwxx0S_$TѺ65&,Z;]Gwxt۫D?<02l\I:7OB$Lq*E. ukKswP tܯPAaWzzz7|wl=OHNmKGrĞVZ=e'Xf$lGu*B5Dlfa:8<<dL,#Dor$sm`+Z\`n&zuyW_jMSg{[K;=q;/iJC)U1:ݱ&mp^%P kŀ~衇nfƘ~dnG|>sܸfʔ)nAoQ___`V]wO|:qu˖l5:ۍ T1]!^'   ^QԱc9$RڭCCG F7uv7Zi*ӥ{~M Sb;g(*gT {^B)e1F*ت!'SsfIVE7v;qa63hokUEVUESÇ=vttz$QUQ4MQC{$I,)MUE%I԰7[}&6~=6օ,Eȶ1wcɌH5@&0lty<~a`&k90ҫ"g3Țd3(0J PBBNpy^B(ƹ/ѲH:P]dF0~I# *`jwd/uZC`M4'512z)%_C?M5)*˅9l6WҲc$D2;D %U"8stvh}LyT~TQdMUTEeYeIƟPj!6~wܱd/2VSZS_R%>D]T$mh >Ʀ4j>/TL-4P$UMXS+vSyl{:=/M$o$Q~e (aܻӜ,dTM4YVNr.>^AS_|ʗmZ][|oѪpP"C域H63-cK.4yqܸq I.Z hn NNTNBz!LT$'~) MPEx'9|g9jWr_!/Uu,Ɂ=j ]- |uיQxces&ϣ VEJ-QDS+xF(lT>u(I,K,e4ӻ,K~f[EG =@~f_wK3j[| GXJơW ,F)'ٌ**ٌZhAH6;/~@o;~{*U9Xn4yg8 + |غ $'B-K,:l_%x@>dv밸aihͨMTUUUY.̑fP"ֻ'OLA#WL~fG(=E2*]yP@K+0Y(*Ȳlz6UM;3~}4Z5d2vM( mB_ES*okj Ǯ4ij>/TL-4P$U 'nGWn *x:uWDJe͔Y^t3MuH)a$ٌ},ɨiZ!#Cc㨝#ќ{^+b镓P+o5G(z>0"UP ,x%DzPC L.Z I?7 By$Oz؄)R J.^o"nߓm|2?g둅:E9 $QUQ4MQ j19$I%E2B%IrL" v ΞfXX~ y'8ˉOP-HnrIy 9L5IEfTU5UfԂG BqG$W("^} :y'CU[]3_M\ )r6f4ESUUUe0Gf#9wqer( MTȽ0_OyN %1=9L:TEUYM@an&$=9]L$7fwn[X-ؤMS煊J* g /2j~~ppE60 &TܕfZгA+9D`&N6uwd2jVxvȈ,Ǚ s 4rۑK;5c1kG ᢅ v3)( {r&ζHqҔSӂ/1=TzVĴR{Z k1R ͍j  z!Cr".)+nԧ2źk'7u]7 Robg*w?9}v%ӧ6]~- 6[HǘVUndGmbm!!g<rwષ͘,2F'4Frj BӬP֡$іg_|D 0 5F4YYАmmifIUI>yǷ~W 8æM9wW:~: ՠ~`Lᴩ乗9cj ;>>> sO(?PG('E?S~tzv˿}3nN},>߿utqnjG*I3 #F"8/g)~CU*$v[ɡ{aOO]A)=Oީ-?x|0T56=G6b¤u4h˷< :r+j_/`lUuPB)_&IʡP'THCL?"Za L*{K)a"_uS`~vs~:.6"=s-2*}sև0T.ZT/rcLl Fܵ:b>hgRĝ=2ۥ `!`Y9 Xٛ=Po9 *0 03 (0`҄1_M }-u#n0|~$u/TL-4P$U -"Yo~Eh+hPV~aQ~&QDkUZٌ},ɨiZ!#e}'; 睟b(C)NJ6TEu"֘ș$_+ .q& RE "#gE| f3{H JխHDK"_8/QlL&m9lcJ(Tܵۮljn!P+_; &dC!$ե4:;EU5}k_Xv-?P֡w8PJUUΨ%.Ľ_X~1Ktx; 9:VYUM>3if: rh"ITUMSTE60:$I%E2B%IۣУiz̤_C9Uww%^ݹ˧_UuסU9T9QUET%Q -f=Dz'a<h wӽv:@L7}(xDs<[y0 èq99Q3VEdYU8L(ӑ9.Gs1ȱ"wcdnCe2 l?9\ryںhѢ}9TYSUQ̛/cLULoVs@I}mBHTB]Y3@nt]߱c-0cƌŋϘ1 /LY IEvTybj)$J"\R?h]kLd2 ?Dy,Su]ᇧNzy}٦꺞~X&Q5UӴ³CFdYE& #;w87s*~Ʃ@O"3jL!A)7m۶ VD +#.{IP/\ӘxQܽɰnCTz@eK-Ek4~~'?{ F3oK<;?ד jD.`7h aܸ/~񋭭Qcǎg?&.mg ^=yMٻԈuoϾ''oQO}SsO[!~97$o{p͔)#}C~FFFjCCC###a/d1az+o9@C"!޵0 mhjj{zzK]"{+KBjBB È7–Ǐz룙 t ZҜrU!ʻaC0So:>2Z[[;t#ȩ/…akkkwww> 2kʔ)Awwtƿ|9nv0GG]fͼyj}}}>hKKK%:_0B(~::cOJ%bOp+k9MPQ XbRؓ`od> c{7<1h H1]>a"[j%nJ;7 IZ5+b1v+/Zgss&M<KV,N;u:4@B6{?8čҡ5d҂Sɵ.TT9YZpjiczGy}F?S&V34RRBZ*3x/mюn;Ԇ8ZnCq͗؟ KetV['^q;h˖-gׯc0NۿfM1jG&D.-1xS--{:"Vیy$3UCL4eF>?xMMjP\lIyaT{$IENDB`Docs/Chm/help/images/b64x64_winprops.png0000664000000000000000000001061513225117272016763 0ustar rootrootPNG  IHDR@@iqgAMA7tEXtSoftwareAdobe ImageReadyqe<IDATxb?H0@4 F| 2H[ &<<1 9 Fj1iP173ç3vπ~@,sy3j1|? L18*ՁYDhB2b WWo+F27 ~@heSNH[be,IɁ0qOQ1e3"a'샹n%&Íͻ| L @| >|9ûOlj,01V43`"Nŧ~(8bv PkoF&?fbkCVzb0 R1?> e @,Y BbWlJ%Xe!Y?L/F(0loh6DZ01n5!AGY$1$bZ${0&-?&&H@@aMp '0|z `(mPښ S? 78+#Z^bA1r(*`p[__\ر$@`gedQc +3<K@gK_NP2aš#2~CKHRꉉ^H P Q 445a1Ab ^ b ž` zvU~f1^ݸsӤD)CCdIXGDr 1GaU- U -8pAg2|A92/Y$O?R?R[2ц2#͝;nl^..)99gQII6`=#PݶUnϠ LȞ%K<)?" 06~ 4 |²e ccccPb(*ׯ =b L _`< 3XARC&!Rv9``d@ J/~f};k~ om0g.g`/ ٿ7o2f?>0H߿ŀs!'0[Q >yXψ k;/;0殮YpkNv^~ eW76.N@v00 [c\`@,;Kd;;B?R!Q 0>+< T 0|+`RO}4<0T ph&w <KP FD   |OϜ%9KKx`A.SJ 06(;pm`zyjсR  1ۼ@zJdyH00<}L̈@b0YX\`t?u/~ ,+Ą L O<?p#ېTt _E?AbahD 0 53;+<5a<FCĄ ,ok .~֏0@e_Q?c1 WDk`?f2"gPA$(880&ϯ^A%300@|Pu HI?4@)WZE hM?yŒۘGI}p [;ԾS`2e Giȃ_y`M<3?`?hl 7GCֆu lЬҰ ?FЌ0I??wA?(>^cXN.P6طO@g +AZFFi(?F^?P V@‚2 깁b) WUB 5 (Bi,iapgϞ1pB @`U x#Y-A77# >c:Au0(VYتí /0ty 3 VVH/-Dae`cxvLMj h}@a  <`49a`;G`7_ׯ}O7pg Dר`㉋Aѡ Zѱ?7 \#dx

S֛kW~{)1) D(4 Ap<QVV `*!F%du,##QXս' Og8 @[QZZ?}?(JM^ 4tu6<xD4rr%f]F`_ _}c{<×8~g0B߾c<ρeK(G]c`#_TA6 E -E0(I'PXk|Vcxw;7D$$tMl9'Wv`7Po`ࠖQB# Hhԋeرd1СФ by: _Y?{`@;Wk[v1C`- OP ڽU 'pC xDҐG1uuNc@O GtAA@t>ה30[j^ &E r O`?CbA9Lu@aN#w>YY!`AL[GB( v?~>x kfQcz` ; @Dx\@bb`2kPT-G"@o`@`L# "!,J%@ߠR{^<:~]T6` yY! Yi?~1,K`==#b`ccf`d-5/@Xgt<~|P3,IRF“8gXŒ1bc2th~ޣ 2dHp 30U- #kXo,Ǿ1%p6 l<h栯F^Ѝ_d |D%Z?73*q{b‰"e?lC6၃6ف8T}~ d @s{yZ;"Fp#\O6;!t9dx0@afPie a`2V/C|%Ó5|  sBPM8XcdG= > ~ @dl*.**@3)=h8Ј7@#>h@E*IENDB`Docs/Chm/help/images/b64x64_kcmdrkonqi.png0000664000000000000000000001472613225117272017253 0ustar rootrootPNG  IHDR@@iqgAMA7tEXtSoftwareAdobe ImageReadyqe<hIDATxb?H0@4 X 222RՒ l20t2"( w}ګc`x KmO#ĈFb`h PH X4 ~`Ïȅ 00l[p zc[$`E 70//'40~ׯ o>fxã/|/Tqc`Q#j0.J$*#%Š,' <0S,077''0cA4c'0 0ӧ Ϟ1}90 n>dxϏ?g`a3g1@PDH-Op7q 7itJA)&[iE̛Z^Z Ӕ(HT,@ CP!+ʯw0(2Nm%)ueXq Mb\_^@\ΟJdt$%%!Mpz 0(c~f`p/0 &@Pjj҄X$^a`8wМS0\ׯϏ&S$H >C Ǵ=g20\ 돀۷<k1 ^6`gfe` 0U1A`x5м@50lXP%@d@cyPϟgxu`޽9'`RF7`~S@e` LA8\APM ye֗aPe`f-p|0`v}6ñ{@$q@1l箮@ox`1u ~`~qx`@ac T%Â4Ì ;EEPaj`N ? 50},c`H.7f ")Хe8ttXUU e$~#~wX>]  π ͳ#a `i 0mj^ ww`>1`h7Ђ@wfށځ7 -aqgP̃ (P?r7S0y#F<5H|?D֌ЀbI`bH܀AJB%{aT|=CPl! `b\vuP̟<30<_tG灅8_B==q[z!Ċd`dee @eP `,{kso9pa>P :/L0y-;w?| l,ʁp ?![ 4/2 ιB3g+C#H9\8g`A,n-( r{ݎ v/y+я9пt0,>@ `JX) l(<U >ac@|R@M`@ ꂂ /Č6[o>{ Z`t?z)R҃#槇>L_w.o*P?q`1k'`xI BDFLcfdډ ρP~PtX90mĀ|!; Z@읺~=Ãya+=A2,ۀmn_<{ 2Mw6@ln ` r@OZcn~I`?+Z<sИ'@ … &1bi(Qla5- b|&DҸ{X )G`ѣGh^`; 0R@1-ged%}v;0_?v@S/BB%<22 "cXg(ƈ( 5=0c`_'410(07jـ6KCVk5Im?2&1`>;(j}5FP88 l-2B g9 h)0Nؠr`*@ `Z֐/n߿ehLu}"p1%k'0%@4TVi#NX63.0'0 \ O~Вwn_z-`C=H [=K0ʑ9Hs^{@ @ws*0} nHC]#@ao0k#,9U/O ,G,X @̱Rx#0-= P* }e)7bT' ks! <\yH#>N@Ф`̃<(e2e[2@ t? `ؑ \& |LbHu:$ƫ)glhO)DJA` ;?@Z >G;C8_~4_ TPLC0*/( &`~=KVe`R-B@ A@<@Z1< X!y1ʫ ?, yD/>Gs"?7q _ê @=,@E47jh@jɁ2 x w:9JJJ !xÒ9LML6^ \FP A@E hl>_ϟۦ{^@ZAbQ?D u, }lym8 yUa/E@汳3- Q } Xpt@KyՠWWW'Xedq s/h" h0`h#`]?eG0F*Qks%/Udh K}*4^A ĕ@d  Aj &z%W tБ82/h'QZY;p ZvO ߓ~V`NahTHW^`B80C = `1bdd h `7 #L8r)8Fz)@GJ#4 -/w/ -klU? iׯM3=HБ[X~{9#00 :(^CM~~FP-LS0? @.'_JgPrb.^^p Uj бzz ς  2Y4x *_EM` d.4P pl`u4,DN`:xFx(i< JH rj]w`|= ]` YC-A(J-@8`,v<MiR`Q`EhnaM@yx f rv`s[Fa'`=5(/ z_,ozdjj B,,l ̐.S03b 3HRj[EEA-ԍO 7#  |"I`%ӧU urC tcAUP;4r @ 'IfXA>: 61w`{,e/P ¿? &e*O>׾EytZ۷oA=ي4K`\l 10R1õWnc=dMh ? 4eO}T*ؘL6_RhA500u/ٳ RKdf=qq ڸ9lT=? r70`-Ȃ[Ȍ hǺt gZX3B-|س?h/`en?}`1ͭd A(A`Hr=kC0܁5B7`[;= zɓ L`+iR:l & Ul]\8U{`r;ӿxPu2e˨1'QƜH5#_a[SMegt65e0-|J;ddldz Y~ b$ TƤh0::"B:҅ ϜaxK`a0X.~=50" N ?Zt%ꁂrr  B@߽saΝ ~~ZC{D!P!.Y0C[Ӓ"2>r)k oKr-*MhnB{u-ʨ09@3 ME4R@ ~;ׁ/ȴ{y_!gch @44m=1('6af#ؔhڄ}}p(uUP6+LHMPĪrd?H< @#~(@0@CyMCDIENDB`Docs/Chm/help/images/b64x64_doc.png0000664000000000000000000000270213225117272015645 0ustar rootrootPNG  IHDR@@% tRNS/wIDATxZKK+YH AAt΍ .ww+.U62s!Y(kgN[Swh|o_:>>>;;cFUUL&kkkAB?ytt4??J DrXۛ21W.777KVTZ__ݽ6*1ڧ*\_4xauo} ЋH$喖NOO///'9PTt3J7EBO?B0tZGR{m* 2!DjVVPȈ9.l~Lh !߿b1UU*`ecǭbz5 !*罪H6 -Jai/˲(!Ib9R1$`Te%YyhikB1FVHIրP1N&s6%Y !H1Q{痗,0cUUufaҞ:8qR[ZnuysO% Hi!,P cTT0ƉD"p׈k\BȲB(Jh`cICuE$IUU A&oIl[! ^{J%dΊQtP !Z c:`%sAj c9b*4jRFDBQcs J8>>!!@=SϖL&399I بNBIh|]@G纷!+ҮDGG/wv-Bh```yy3Q{*IRZEq[ЕhL¿#nӕEBHɜ JPA@6$9A"_JEJ{(R6ZլQ৐F**M_Ahӽ$y_XX@eY ^{tN,'4GW}3ss&F:8NI@kBcooo!T*7 ɮ( J3^(RlWb7!rFw`@XTB$SkYw%ik8ckёمP3cBWGpDz,Ƹ' {z鈩VQByAj/B6hn-d@,{yy1x骑QS+gXEYABa{{{gggttIܿJǏv-..nllؤQ`Yfӓ}ppprrڽB}}}SSS\P( `ǫWٵkhhhbb¤}}^&IENDB`Docs/Chm/KeePass.hhp0000664000000000000000000000274312321521402013207 0ustar rootroot[OPTIONS] Compatibility=1.1 or later Compiled file=KeePass.chm Contents file=KeePassContents.hhc Default topic=help\base\index.html Display compile progress=No Full-text search=Yes Language=0x409 Englisch (USA) Title=KeePass Password Safe Help [FILES] help\base\autotype.html help\base\autourl.html help\base\cmdline.html help\base\configuration.html help\base\credits.html help\base\disclaimer.html help\base\faq.html help\base\faq_tech.html help\base\fieldrefs.html help\base\firststeps.html help\base\importexport.html help\base\index.html help\base\integration.html help\base\keys.html help\base\license_lgpl.html help\base\multiuser.html help\base\placeholders.html help\base\pwgenerator.html help\base\repair.html help\base\secedits.html help\base\security.html help\base\tans.html help\base\usingpws.html help\v2\autotype_obfuscation.html help\v2\dbsettings.html help\v2\entry.html help\v2\guioptions.html help\v2\index.html help\v2\ioconnect.html help\v2\license.html help\v2\plugins.html help\v2\policy.html help\v2\setup.html help\v2\sync.html help\v2\translation.html help\v2\triggers.html help\v2\version.html help\v2\xml_replace.html help\v2_dev\customize.html help\v2_dev\plg_index.html help\v2_dev\scr_index.html help\v2_dev\scr_kps_index.html help\v2_dev\scr_sc_index.html images\grad_v_gw.gif images\back.gif images\grad_h_gw.gif images\grad_h_gw_186.gif images\grad_v_dlb.gif images\grad_v_dlb_tall_light.png [INFOTYPES] Docs/Chm/default.css0000664000000000000000000002444113225117272013322 0ustar rootroot/* Copyright (c) 2003-2018 Dominik Reichl. */ body, p, div, h1, h2, h3, h4, h5, h6, ol, ul, li, td, th, dd, dt, a, kbd kbd { font-family: Verdana, Arial, sans-serif; font-size: 9.75pt; font-weight: normal; color: #000000; } /* --------------------------------------------------------------------- */ body { background-color: #FFFFFF; background-image: url('./images/back.gif'); background-repeat: repeat; background-attachment: fixed; } p { margin-left: 0px; } ul { /* margin-left: 20px; list-style: disc; */ } h1 { font-size: 15.00pt; font-weight: bold; } h2 { font-size: 13.50pt; font-weight: bold; } h3 { font-size: 11.25pt; font-weight: bold; } h4 { font-size: 9.75pt; font-weight: bold; } h5 { font-size: 9.00pt; font-weight: bold; } h6 { font-size: 7.50pt; font-weight: normal; } hr { height: 1px; display: block; color: #000080; margin: 0px 0px 0px 0px; padding: 0px 0px 0px 0px; } pre { font-family: monospace; background-color: #E6E6E6; font-size: 8.25pt; overflow: auto; display: block; } kbd kbd { padding: 0px 4px 1px 4px; border: 1px solid #808080; border-collapse: collapse; -moz-border-radius: 2px; border-radius: 2px; box-shadow: 0.1em 0.15em 0.2em #C5C5C5; color: #000000; background-color: #EEEEEE; background-image: -webkit-linear-gradient(top, #EEEEEE, #FAFAFA, #EEEEEE); background-image: -moz-linear-gradient(top, #EEEEEE, #FAFAFA, #EEEEEE); background-image: -ms-linear-gradient(top, #EEEEEE, #FAFAFA, #EEEEEE); background-image: linear-gradient(to bottom, #EEEEEE, #FAFAFA, #EEEEEE); } /* --------------------------------------------------------------------- */ a:visited { text-decoration: none; color: #0000DD; } a:active { text-decoration: none; color: #6699FF; } a:link { text-decoration: none; color: #0000DD; } a:hover { text-decoration: underline; color: #6699FF; } /* --------------------------------------------------------------------- */ div.menubox { border: 1px solid #C5C5C5; display: block; margin: 0px 1px 0px 0px; padding: 0px 0px 0px 0px; background-color: #FFFFFF; } div.menubox div.menutitle { background-color: #C5C5C5; background: url('./images/grad_h_gw.gif') repeat-y; display: block; font-weight: bold; font-size: 7.50pt; padding: 1px 1px 1px 6px; vertical-align: middle; color: #005101; white-space: nowrap; } div.menubox div.menutitlewide { background-color: #C5C5C5; background: url('./images/grad_h_gw_186.gif') repeat-y; display: block; font-weight: bold; font-size: 7.50pt; padding: 1px 1px 1px 6px; vertical-align: middle; color: #005101; white-space: nowrap; } div.menubox a { display: block; padding: 1px 1px 1px 1px; border-collapse: collapse; text-decoration: none; font-size: 8.25pt; color: #000000; vertical-align: middle; } div.menubox a:visited, div.menubox a:active, div.menubox a:link { border: 1px solid #FFFFFF; } div.menubox a:hover { border: 1px solid #0A246A; -moz-border-radius: 2px; border-radius: 2px; background-color: #B6BDD2; background-image: -webkit-linear-gradient(top, #D9E5F9, #B8BED8); background-image: -moz-linear-gradient(top, #D9E5F9, #B8BED8); background-image: -ms-linear-gradient(top, #D9E5F9, #B8BED8); background-image: linear-gradient(to bottom, #D9E5F9, #B8BED8); } /* --------------------------------------------------------------------- */ table.laytable { width: 100%; border: 0px none; } table.tablebox, table.tablebox75 { background-color: #EEEEEE; margin: 0px 0px 0px 0px; padding: 0px 0px 0px 0px; border-left: 1px solid #AFB5CF; border-right: 0px none; border-top-width: 0px; border-bottom-width: 0px; border-collapse: collapse; } table.tablebox { width: 100%; } table.tablebox75 { width: 75%; margin-left: 12.5%; margin-right: 12.5%; } table.tablebox tr th, table.tablebox75 tr th { background-color: #EEEEEE; background: url('./images/grad_v_gw.gif') repeat-x top; font-weight: bold; border-bottom: 1px solid #AFB5CF; border-left: 0px none; border-right: 1px solid #AFB5CF; border-top: 1px solid #AFB5CF; padding: 2px 2px 2px 5px; empty-cells: show; white-space: nowrap; text-align: left; vertical-align: top; } table.tablebox tr td, table.tablebox75 tr td { background-color: #F0F0F0; font-weight: normal; border-bottom: 1px solid #AFB5CF; border-left: 0px none; border-right: 1px solid #AFB5CF; border-top: 0px none; padding: 5px 5px 5px 5px; empty-cells: show; text-align: left; vertical-align: top; } /* --------------------------------------------------------------------- */ img { border: 0px none; } img.singleimg { border: 0px none; vertical-align: middle; } /* --------------------------------------------------------------------- */ input.sansedit, textarea.fixededit { border: 1px solid #C5C5C5; padding-top: 1px; } input.sansedit:hover, input.sansedit:focus, textarea.fixededit:hover, textarea.fixededit:focus { border: 1px solid #000000; } input.sansedit { font-family: Verdana, Arial, sans-serif; font-size: 9.75pt; } textarea.fixededit { font-family: monospace; display: block; } /* --------------------------------------------------------------------- */ div.tooltipex { position: absolute; display: none; background-color: #FFFFE0; padding: 1px 1px 1px 1px; -moz-opacity: 0.9; opacity: 0.9; border: 1px solid #000000; } /* --------------------------------------------------------------------- */ div.specificbox { border: 1px solid #808080; -webkit-border-radius: 5px; -moz-border-radius: 5px; border-radius: 5px; display: block; background-color: #EEF0FF; padding-top: 1px; padding-left: 2px; padding-right: 2px; padding-bottom: 2px; } div.specificbox div.specifictitle { font-size: 7.50pt; font-weight: bold; border-left: 0px none; border-right: 0px none; border-bottom: thin dotted #808080; border-top: 0px none; text-align: left; margin-bottom: 3px; } /* --------------------------------------------------------------------- */ table.sectionsummary { width: 100%; border: thin solid #808080; -moz-box-shadow: 1px 1px 5px #808080; -webkit-box-shadow: 1px 1px 5px #808080; box-shadow: 1px 1px 5px #808080; background-color: #F0F8FF; margin: 0px 0px 0px 0px; padding: 0px 0px 0px 0px; } table.sectionsummary tr td { border: 0px; vertical-align: middle; font-size: 7.50pt; font-weight: normal; margin: 0px 0px 0px 0px; padding: 0px 0px 0px 0px; border-collapse: collapse; } table.sectionsummary tr td h1 { display: inline; font-size: 15.00pt; font-weight: normal; } /* --------------------------------------------------------------------- */ h2.sectiontitle { display: block; font-size: 9.75pt; font-weight: bold; color: #000000; background: url('./images/grad_v_dlb_tall_light.png') repeat-x top; border: 1px solid #AFB5CF; color: #005101; min-height: 14.25pt; vertical-align: middle; margin: 0px 0px 0px 0px; padding: 2px 0px 0px 6px; } /* --------------------------------------------------------------------- */ td.helptopheader { background-image: url('./help/images/b32x68_headerbg.png'); background-repeat: repeat-x; } /* --------------------------------------------------------------------- */ p.pagebreak { page-break-after: always; } /* --------------------------------------------------------------------- */ div.tipdiv { background-color: #FFFFE0; padding: 1px 1px 1px 1px; border: 1px solid #000000; } .box100 { -webkit-box-sizing: border-box; -moz-box-sizing: border-box; box-sizing: border-box; width: 100%; } .withspc > li + li { margin-top: 0.75em; } .codekw { color: #0000FF; } .codetp { color: #008888; } .codecm { color: #008800; } .codest { color: #880000; } /* --------------------------------------------------------------------- */ .il-m { background: transparent url('./images/il_main_v02.png') no-repeat; margin: 0px 0px 0px 0px; padding: 0px 0px 0px 0px; border: 0px none; overflow: hidden; display: inline-block; vertical-align: middle; } .spr-m-kp-h { background-position: -1px -1px; width: 75px; height: 75px; } .spr-m-home-mh { background-position: -78px -1px; width: 31px; height: 21px; } .spr-m-contact-mh { background-position: -78px -24px; width: 31px; height: 21px; } .spr-m-news-mh { background-position: -78px -47px; width: 31px; height: 21px; } .spr-m-scrsh-mh { background-position: -111px -1px; width: 31px; height: 21px; } .spr-m-dl-mh { background-position: -111px -24px; width: 31px; height: 21px; } .spr-m-lang-mh { background-position: -111px -47px; width: 31px; height: 21px; } .spr-m-ext-mh { background-position: -144px -1px; width: 31px; height: 21px; } .spr-m-write-mh { background-position: -144px -24px; width: 31px; height: 21px; } .spr-m-help-ml { background-position: -177px -1px; width: 31px; height: 18px; } .spr-m-info-ml { background-position: -177px -21px; width: 31px; height: 18px; } .spr-m-sec-ml { background-position: -177px -41px; width: 31px; height: 18px; } .spr-m-donate-ml { background-position: -177px -61px; width: 31px; height: 18px; } .spr-m-award-ml { background-position: -210px -1px; width: 31px; height: 18px; } .spr-m-links-ml { background-position: -210px -21px; width: 31px; height: 18px; } .spr-m-xmag-ml { background-position: -210px -41px; width: 31px; height: 18px; } .spr-m-osi-h { background-position: -1px -96px; width: 72px; height: 60px; } .spr-m-award-s { background-position: -1px -158px; width: 16px; height: 16px; } .spr-m-feed-s { background-position: -19px -158px; width: 16px; height: 16px; } .spr-m-w3valid-b { background-position: -1px -176px; width: 80px; height: 15px; } .spr-m-kp-b { background-position: -83px -176px; width: 80px; height: 15px; } /* --------------------------------------------------------------------- */ .cc_message, .cc_more_info, .cc_btn { font-family: Verdana, Arial, sans-serif !important; font-size: 13px !important; } .cc_message { color: #FFFFFF !important; } .cc_container { background-color: rgba(0, 0, 0, 0.92) !important; padding: 5px 5px 5px 10px !important; } Docs/Chm/images/0000775000000000000000000000000013225117272012424 5ustar rootrootDocs/Chm/images/grad_v_dlb_tall_light.png0000664000000000000000000000172413225117272017424 0ustar rootrootPNG  IHDRd)PLTEHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHdSGIDATxC o1Y IP]A r(ȱ r)ȵ (ȳ SA^ ]OAd-H$D"H$D"H$D"H$D"H$D"H$D"H$D"H$D"H$I6SkHIENDB`Docs/Chm/images/back.gif0000664000000000000000000000040713225117272014014 0ustar rootrootGIF89a@ ,@ @H*\ȰÇ#JHŋ3jȱǏ CIɓ(S\ɲ˗0cʜI͛8sɳϟ@ Jѣ(]ʴӧPJJիXjʵׯ`ÊKٳhӪ]˶۷pʝKݻx˷߿ L0+^̸ǐ"L˘3k̹ϠCMӨS^ͺװc˞M۸sͻ ǸDocs/Chm/images/grad_v_gw.gif0000664000000000000000000000067513225117272015062 0ustar rootrootGIF89ad,d@H*\ȰaB#JHŋ3jxǏ CIɓ(S$˗0cʜI͛3ɳϟ@ JhPH*]ʴӧPJԀիXjʵׯ`vU@ٳhӪ]˶۷kȝKݻx˷o^  LÈ+^|8ǐ#KL˘3WϠCMӣ ^ͺװc˞Mvsͻ ;ȓ+_μУ7_@سkνCOӫ_Ͼ}˟O?(h&X 6F(Vh;Docs/Chm/images/grad_h_gw.gif0000664000000000000000000000135413225117272015037 0ustar rootrootGIF89a , @`X8C"0@⁋hԘc A.9I Rt/!ȄfM 8%LعO @腣0(Ui PnUv뇯@; >(E9z )䂓(U6h惙4mFȩ焟@V(jRNJz֮^%[A 8-ƌq=~kI{[;ST1Ҥ>Lje[1 ,h^K["PMWAklpnļ[pWA8Z趦\^E`b\dQvei\gguxvHҁ*%ӂ65ӃBE؄M'߅Yه߆tEt]vvw!(1AیKWT՗W=bEDnTbHHޒ+6/FGgeT7^eW;eA)&d h&hdlMp$PtW%xZ'|j'z(ڠBڡFXҢ+5JLEOUj'acrrY@Docs/Chm/images/osi_certified_72x60.gif0000664000000000000000000000444313225117272016576 0ustar rootrootGIF89aH<O0_0?j?@j@ClCRxR]]``cciimmvvyyƵɺͿ DQTOZeQh`^Niafb^kQW nL"r !oac h%w#$t"V'y%Q+),*X\854174VP96;89631R!W "W!!T #W"#U"&[%%X$&X%-\,4c37c6=h<;e:FrEFnEHoGLtKJpIPuOW{V\[gfLU)|&,)1-/,0,0- \3/1.622/>9=9<8;7958441?;>:=9<8;7:6@::6potssrxwwv~}~~~}}}{{{yyywwwtttssspppnnnllljjjhhhbbb^^^[[[YYYSSSOOOMMMKKKHHHFFFEEECCC@@@>>>:::555222000+++((('''%%%"""!!! ,H<@E H*\ȰaPԨG>} iȇ"DqతCS(ȲeE eKEFʬ0S`#lsdB3 ͨBO丸 !MZN-BX6`A m r`&;V=o%/8wgwT%l9bΉ殚l| c˞M40 )&7j/OM|qp"mepU P.1!zBGWtL)Yq2tdVI2.$0쒂@Jl袊@K-s!J`? ⸢1#J]w M8ł:(ˠ35߈r<(̔# >();ָ' qZ4C 7̠Rq& h @vt3 rL(j!W0F$LD0K@ M`BlC`b'7ʒ"IA!pC9aG.%b"I IE"A#0Fgpk'DF'er*J2%iT6|*@3(2`܈K0 B :҈b ZA<TK41 $N534ҰC1J ML.TS >H3M=@`-p,r6<@ ALS /qbM4B)İ2Jzom1 @( -8,Wp(dpILB|Ru@0$!~tD~<2 N /(BZE@@`9 gP* \-, R4׳Ѣ %>R"r7sW|mH6Ql$h2HoLH z Vr,1dU.٠+ )vJ[Ҫ ( blE&'x$5@Ա&U)b> /zF'A&?P@&(j `+BK($DX-Ay!L7"}BE3!*+Zm@F*C 7$$b\@ E%VPh %pNP␹K&Bv8s(gjƲz,7!|#L! P@BA _b0=+B0Ƈb V 0LTB+"*_4ox1^ @_"7`qO+1 ."4MG6v s,uE>jqb@+$wة>Q4ሪ@ \BXh BElA^H;ֵ4G1DыY2ЍԈ=xQ { yd{4ߣ3=&Fx&ͭ&جD ֑$k\[zdz 7_éM7eR ~oj%!X;Docs/Chm/images/grad_v_dlb.gif0000664000000000000000000000100313225117272015170 0ustar rootrootGIF89adϰвҳӴԶַ׹ٺڻ۽ݾ޿,d@H*\ȰaB#JHŋ3jxǏ CIɓ(S$˗0cʜI͛3ɳϟ@ JhP H*]ʴӧPJTիXjʵׯ`v5@ٳhӪ]˶۷kȝKݻx˷o^ LÈ+^|Xǐ#KL˘3WϠCMӣ^ͺװc˞Mvsͻ ȓ+_μУ7?@سkνOӫ_Ͼ}˟O(h&X 6F(VhFv ($(,0(/V`8<@DiH&L6K;Docs/Chm/KeePassContents.hhc0000664000000000000000000001525712273660164014733 0ustar rootroot

ReadMe_PFX.txt0000664000000000000000000000063211156222774012201 0ustar rootrootAll projects contain dummy PFX files. These PFX files are NOT the ones with which the KeePass distributions are signed, these are kept secret. In order to unlock the private keys of the dummy PFX files, use: "123123" (without the quotes) Official KeePass distributions are signed with private keys. You can find the corresponding public keys in the Ext/PublicKeys directory. KeePassLib/0000775000000000000000000000000013225117636011546 5ustar rootrootKeePassLib/Delegates/0000775000000000000000000000000013224154300013427 5ustar rootrootKeePassLib/Delegates/Handlers.cs0000664000000000000000000000604613224154300015524 0ustar rootroot/* KeePass Password Safe - The Open-Source Password Manager Copyright (C) 2003-2018 Dominik Reichl This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ using System; namespace KeePassLib.Delegates { /// /// Function definition of a method that performs an action on a group. /// When traversing the internal tree, this function will be invoked /// for all visited groups. /// /// Currently visited group. /// You must return true if you want to continue the /// traversal. If you want to immediately stop the whole traversal, /// return false. public delegate bool GroupHandler(PwGroup pg); /// /// Function definition of a method that performs an action on an entry. /// When traversing the internal tree, this function will be invoked /// for all visited entries. /// /// Currently visited entry. /// You must return true if you want to continue the /// traversal. If you want to immediately stop the whole traversal, /// return false. public delegate bool EntryHandler(PwEntry pe); public delegate void VoidDelegate(); public delegate string StrPwEntryDelegate(string str, PwEntry pe); // Action<...> with 0 or >= 2 parameters has been introduced in .NET 3.5 public delegate void GAction(); public delegate void GAction(T o); public delegate void GAction(T1 o1, T2 o2); public delegate void GAction(T1 o1, T2 o2, T3 o3); public delegate void GAction(T1 o1, T2 o2, T3 o3, T4 o4); public delegate void GAction(T1 o1, T2 o2, T3 o3, T4 o4, T5 o5); public delegate void GAction(T1 o1, T2 o2, T3 o3, T4 o4, T5 o5, T6 o6); // Func<...> has been introduced in .NET 3.5 public delegate TResult GFunc(); public delegate TResult GFunc(T o); public delegate TResult GFunc(T1 o1, T2 o2); public delegate TResult GFunc(T1 o1, T2 o2, T3 o3); public delegate TResult GFunc(T1 o1, T2 o2, T3 o3, T4 o4); public delegate TResult GFunc(T1 o1, T2 o2, T3 o3, T4 o4, T5 o5); public delegate TResult GFunc(T1 o1, T2 o2, T3 o3, T4 o4, T5 o5, T6 o6); } KeePassLib/Collections/0000775000000000000000000000000013222430376014020 5ustar rootrootKeePassLib/Collections/ProtectedStringDictionary.cs0000664000000000000000000002313213222430376021516 0ustar rootroot/* KeePass Password Safe - The Open-Source Password Manager Copyright (C) 2003-2018 Dominik Reichl This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ using System; using System.Collections; using System.Collections.Generic; using System.Diagnostics; using System.Text; using KeePassLib.Interfaces; using KeePassLib.Security; using KeePassLib.Utility; #if KeePassLibSD using KeePassLibSD; #endif namespace KeePassLib.Collections { /// /// A list of ProtectedString objects (dictionary). /// public sealed class ProtectedStringDictionary : IDeepCloneable, IEnumerable> { private SortedDictionary m_vStrings = new SortedDictionary(); /// /// Get the number of strings in this entry. /// public uint UCount { get { return (uint)m_vStrings.Count; } } /// /// Construct a new list of protected strings. /// public ProtectedStringDictionary() { } IEnumerator IEnumerable.GetEnumerator() { return m_vStrings.GetEnumerator(); } public IEnumerator> GetEnumerator() { return m_vStrings.GetEnumerator(); } public void Clear() { m_vStrings.Clear(); } /// /// Clone the current ProtectedStringList object, including all /// stored protected strings. /// /// New ProtectedStringList object. public ProtectedStringDictionary CloneDeep() { ProtectedStringDictionary plNew = new ProtectedStringDictionary(); foreach(KeyValuePair kvpStr in m_vStrings) { // ProtectedString objects are immutable plNew.Set(kvpStr.Key, kvpStr.Value); } return plNew; } [Obsolete] public bool EqualsDictionary(ProtectedStringDictionary dict) { return EqualsDictionary(dict, PwCompareOptions.None, MemProtCmpMode.None); } [Obsolete] public bool EqualsDictionary(ProtectedStringDictionary dict, MemProtCmpMode mpCompare) { return EqualsDictionary(dict, PwCompareOptions.None, mpCompare); } public bool EqualsDictionary(ProtectedStringDictionary dict, PwCompareOptions pwOpt, MemProtCmpMode mpCompare) { if(dict == null) { Debug.Assert(false); return false; } bool bNeEqStd = ((pwOpt & PwCompareOptions.NullEmptyEquivStd) != PwCompareOptions.None); if(!bNeEqStd) { if(m_vStrings.Count != dict.m_vStrings.Count) return false; } foreach(KeyValuePair kvp in m_vStrings) { bool bStdField = PwDefs.IsStandardField(kvp.Key); ProtectedString ps = dict.Get(kvp.Key); if(bNeEqStd && (ps == null) && bStdField) ps = ProtectedString.Empty; if(ps == null) return false; if(mpCompare == MemProtCmpMode.Full) { if(ps.IsProtected != kvp.Value.IsProtected) return false; } else if(mpCompare == MemProtCmpMode.CustomOnly) { if(!bStdField && (ps.IsProtected != kvp.Value.IsProtected)) return false; } if(ps.ReadString() != kvp.Value.ReadString()) return false; } if(bNeEqStd) { foreach(KeyValuePair kvp in dict.m_vStrings) { ProtectedString ps = Get(kvp.Key); if(ps != null) continue; // Compared previously if(!PwDefs.IsStandardField(kvp.Key)) return false; if(!kvp.Value.IsEmpty) return false; } } return true; } /// /// Get one of the protected strings. /// /// String identifier. /// Protected string. If the string identified by /// cannot be found, the function /// returns null. /// Thrown if the input parameter /// is null. public ProtectedString Get(string strName) { Debug.Assert(strName != null); if(strName == null) throw new ArgumentNullException("strName"); ProtectedString ps; if(m_vStrings.TryGetValue(strName, out ps)) return ps; return null; } /// /// Get one of the protected strings. The return value is never null. /// If the requested string cannot be found, an empty protected string /// object is returned. /// /// String identifier. /// Returns a protected string object. If the standard string /// has not been set yet, the return value is an empty string (""). /// Thrown if the input /// parameter is null. public ProtectedString GetSafe(string strName) { Debug.Assert(strName != null); if(strName == null) throw new ArgumentNullException("strName"); ProtectedString ps; if(m_vStrings.TryGetValue(strName, out ps)) return ps; return ProtectedString.Empty; } /// /// Test if a named string exists. /// /// Name of the string to try. /// Returns true if the string exists, otherwise false. /// Thrown if /// is null. public bool Exists(string strName) { Debug.Assert(strName != null); if(strName == null) throw new ArgumentNullException("strName"); return m_vStrings.ContainsKey(strName); } /// /// Get one of the protected strings. If the string doesn't exist, the /// return value is an empty string (""). /// /// Name of the requested string. /// Requested string value or an empty string, if the named /// string doesn't exist. /// Thrown if the input /// parameter is null. public string ReadSafe(string strName) { Debug.Assert(strName != null); if(strName == null) throw new ArgumentNullException("strName"); ProtectedString ps; if(m_vStrings.TryGetValue(strName, out ps)) return ps.ReadString(); return string.Empty; } /// /// Get one of the entry strings. If the string doesn't exist, the /// return value is an empty string (""). If the string is /// in-memory protected, the return value is PwDefs.HiddenPassword. /// /// Name of the requested string. /// Returns the requested string in plain-text or /// PwDefs.HiddenPassword if the string cannot be found. /// Thrown if the input /// parameter is null. public string ReadSafeEx(string strName) { Debug.Assert(strName != null); if(strName == null) throw new ArgumentNullException("strName"); ProtectedString ps; if(m_vStrings.TryGetValue(strName, out ps)) { if(ps.IsProtected) return PwDefs.HiddenPassword; return ps.ReadString(); } return string.Empty; } /// /// Set a string. /// /// Identifier of the string field to modify. /// New value. This parameter must not be null. /// Thrown if one of the input /// parameters is null. public void Set(string strField, ProtectedString psNewValue) { Debug.Assert(strField != null); if(strField == null) throw new ArgumentNullException("strField"); Debug.Assert(psNewValue != null); if(psNewValue == null) throw new ArgumentNullException("psNewValue"); m_vStrings[strField] = psNewValue; } /// /// Delete a string. /// /// Name of the string field to delete. /// Returns true if the field has been successfully /// removed, otherwise the return value is false. /// Thrown if the input /// parameter is null. public bool Remove(string strField) { Debug.Assert(strField != null); if(strField == null) throw new ArgumentNullException("strField"); return m_vStrings.Remove(strField); } public List GetKeys() { return new List(m_vStrings.Keys); } public void EnableProtection(string strField, bool bProtect) { ProtectedString ps = Get(strField); if(ps == null) return; // Nothing to do, no assert if(ps.IsProtected != bProtect) { byte[] pbData = ps.ReadUtf8(); Set(strField, new ProtectedString(bProtect, pbData)); if(bProtect) MemUtil.ZeroByteArray(pbData); } } } } KeePassLib/Collections/PwObjectList.cs0000664000000000000000000002406613222430376016730 0ustar rootroot/* KeePass Password Safe - The Open-Source Password Manager Copyright (C) 2003-2018 Dominik Reichl This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ using System; using System.Collections; using System.Collections.Generic; using System.Diagnostics; using KeePassLib.Interfaces; namespace KeePassLib.Collections { /// /// List of objects that implement IDeepCloneable, /// and cannot be null. /// /// Type specifier. public sealed class PwObjectList : IEnumerable where T : class, IDeepCloneable { private List m_vObjects = new List(); /// /// Get number of objects in this list. /// public uint UCount { get { return (uint)m_vObjects.Count; } } /// /// Construct a new list of objects. /// public PwObjectList() { } IEnumerator IEnumerable.GetEnumerator() { return m_vObjects.GetEnumerator(); } public IEnumerator GetEnumerator() { return m_vObjects.GetEnumerator(); } public void Clear() { // Do not destroy contained objects! m_vObjects.Clear(); } /// /// Clone the current PwObjectList, including all /// stored objects (deep copy). /// /// New PwObjectList. public PwObjectList CloneDeep() { PwObjectList pl = new PwObjectList(); foreach(T po in m_vObjects) pl.Add(po.CloneDeep()); return pl; } public PwObjectList CloneShallow() { PwObjectList tNew = new PwObjectList(); foreach(T po in m_vObjects) tNew.Add(po); return tNew; } public List CloneShallowToList() { PwObjectList tNew = CloneShallow(); return tNew.m_vObjects; } /// /// Add an object to this list. /// /// Object to be added. /// Thrown if the input /// parameter is null. public void Add(T pwObject) { Debug.Assert(pwObject != null); if(pwObject == null) throw new ArgumentNullException("pwObject"); m_vObjects.Add(pwObject); } public void Add(PwObjectList vObjects) { Debug.Assert(vObjects != null); if(vObjects == null) throw new ArgumentNullException("vObjects"); foreach(T po in vObjects) { m_vObjects.Add(po); } } public void Add(List vObjects) { Debug.Assert(vObjects != null); if(vObjects == null) throw new ArgumentNullException("vObjects"); foreach(T po in vObjects) { m_vObjects.Add(po); } } public void Insert(uint uIndex, T pwObject) { Debug.Assert(pwObject != null); if(pwObject == null) throw new ArgumentNullException("pwObject"); m_vObjects.Insert((int)uIndex, pwObject); } /// /// Get an object of the list. /// /// Index of the object to get. Must be valid, otherwise an /// exception is thrown. /// Reference to an existing T object. Is never null. public T GetAt(uint uIndex) { Debug.Assert(uIndex < m_vObjects.Count); if(uIndex >= m_vObjects.Count) throw new ArgumentOutOfRangeException("uIndex"); return m_vObjects[(int)uIndex]; } public void SetAt(uint uIndex, T pwObject) { Debug.Assert(pwObject != null); if(pwObject == null) throw new ArgumentNullException("pwObject"); if(uIndex >= (uint)m_vObjects.Count) throw new ArgumentOutOfRangeException("uIndex"); m_vObjects[(int)uIndex] = pwObject; } /// /// Get a range of objects. /// /// Index of the first object to be /// returned (inclusive). /// Index of the last object to be /// returned (inclusive). /// public List GetRange(uint uStartIndexIncl, uint uEndIndexIncl) { if(uStartIndexIncl >= (uint)m_vObjects.Count) throw new ArgumentOutOfRangeException("uStartIndexIncl"); if(uEndIndexIncl >= (uint)m_vObjects.Count) throw new ArgumentOutOfRangeException("uEndIndexIncl"); if(uStartIndexIncl > uEndIndexIncl) throw new ArgumentException(); List list = new List((int)(uEndIndexIncl - uStartIndexIncl) + 1); for(uint u = uStartIndexIncl; u <= uEndIndexIncl; ++u) { list.Add(m_vObjects[(int)u]); } return list; } public int IndexOf(T pwReference) { Debug.Assert(pwReference != null); if(pwReference == null) throw new ArgumentNullException("pwReference"); return m_vObjects.IndexOf(pwReference); } /// /// Delete an object of this list. The object to be deleted is identified /// by a reference handle. /// /// Reference of the object to be deleted. /// Returns true if the object was deleted, false if /// the object wasn't found in this list. /// Thrown if the input /// parameter is null. public bool Remove(T pwReference) { Debug.Assert(pwReference != null); if(pwReference == null) throw new ArgumentNullException("pwReference"); return m_vObjects.Remove(pwReference); } public void RemoveAt(uint uIndex) { m_vObjects.RemoveAt((int)uIndex); } /// /// Move an object up or down. /// /// The object to be moved. /// Move one up. If false, move one down. public void MoveOne(T tObject, bool bUp) { Debug.Assert(tObject != null); if(tObject == null) throw new ArgumentNullException("tObject"); int nCount = m_vObjects.Count; if(nCount <= 1) return; int nIndex = m_vObjects.IndexOf(tObject); if(nIndex < 0) { Debug.Assert(false); return; } if(bUp && (nIndex > 0)) // No assert for top item { T tTemp = m_vObjects[nIndex - 1]; m_vObjects[nIndex - 1] = m_vObjects[nIndex]; m_vObjects[nIndex] = tTemp; } else if(!bUp && (nIndex != (nCount - 1))) // No assert for bottom item { T tTemp = m_vObjects[nIndex + 1]; m_vObjects[nIndex + 1] = m_vObjects[nIndex]; m_vObjects[nIndex] = tTemp; } } public void MoveOne(T[] vObjects, bool bUp) { Debug.Assert(vObjects != null); if(vObjects == null) throw new ArgumentNullException("vObjects"); List lIndices = new List(); foreach(T t in vObjects) { if(t == null) { Debug.Assert(false); continue; } int p = IndexOf(t); if(p >= 0) lIndices.Add(p); else { Debug.Assert(false); } } MoveOne(lIndices.ToArray(), bUp); } public void MoveOne(int[] vIndices, bool bUp) { Debug.Assert(vIndices != null); if(vIndices == null) throw new ArgumentNullException("vIndices"); int n = m_vObjects.Count; if(n <= 1) return; // No moving possible int m = vIndices.Length; if(m == 0) return; // Nothing to move int[] v = new int[m]; Array.Copy(vIndices, v, m); Array.Sort(v); if((bUp && (v[0] <= 0)) || (!bUp && (v[m - 1] >= (n - 1)))) return; // Moving as a block is not possible int iStart = (bUp ? 0 : (m - 1)); int iExcl = (bUp ? m : -1); int iStep = (bUp ? 1 : -1); for(int i = iStart; i != iExcl; i += iStep) { int p = v[i]; if((p < 0) || (p >= n)) { Debug.Assert(false); continue; } T t = m_vObjects[p]; if(bUp) { Debug.Assert(p > 0); m_vObjects.RemoveAt(p); m_vObjects.Insert(p - 1, t); } else // Down { Debug.Assert(p < (n - 1)); m_vObjects.RemoveAt(p); m_vObjects.Insert(p + 1, t); } } } /// /// Move some of the objects in this list to the top/bottom. /// /// List of objects to be moved. /// Move to top. If false, move to bottom. public void MoveTopBottom(T[] vObjects, bool bTop) { Debug.Assert(vObjects != null); if(vObjects == null) throw new ArgumentNullException("vObjects"); if(vObjects.Length == 0) return; int nCount = m_vObjects.Count; foreach(T t in vObjects) m_vObjects.Remove(t); if(bTop) { int nPos = 0; foreach(T t in vObjects) { m_vObjects.Insert(nPos, t); ++nPos; } } else // Move to bottom { foreach(T t in vObjects) m_vObjects.Add(t); } Debug.Assert(nCount == m_vObjects.Count); if(nCount != m_vObjects.Count) throw new ArgumentException("At least one of the T objects in the vObjects list doesn't exist!"); } public void Sort(IComparer tComparer) { if(tComparer == null) throw new ArgumentNullException("tComparer"); m_vObjects.Sort(tComparer); } public static PwObjectList FromArray(T[] tArray) { if(tArray == null) throw new ArgumentNullException("tArray"); PwObjectList l = new PwObjectList(); foreach(T t in tArray) { l.Add(t); } return l; } public static PwObjectList FromList(List tList) { if(tList == null) throw new ArgumentNullException("tList"); PwObjectList l = new PwObjectList(); l.Add(tList); return l; } } } KeePassLib/Collections/ProtectedBinaryDictionary.cs0000664000000000000000000001230113222430376021470 0ustar rootroot/* KeePass Password Safe - The Open-Source Password Manager Copyright (C) 2003-2018 Dominik Reichl This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ using System; using System.Collections; using System.Collections.Generic; using System.Text; using System.Diagnostics; using KeePassLib.Interfaces; using KeePassLib.Security; #if KeePassLibSD using KeePassLibSD; #endif namespace KeePassLib.Collections { /// /// A list of ProtectedBinary objects (dictionary). /// public sealed class ProtectedBinaryDictionary : IDeepCloneable, IEnumerable> { private SortedDictionary m_vBinaries = new SortedDictionary(); /// /// Get the number of binaries in this entry. /// public uint UCount { get { return (uint)m_vBinaries.Count; } } /// /// Construct a new list of protected binaries. /// public ProtectedBinaryDictionary() { } IEnumerator IEnumerable.GetEnumerator() { return m_vBinaries.GetEnumerator(); } public IEnumerator> GetEnumerator() { return m_vBinaries.GetEnumerator(); } public void Clear() { m_vBinaries.Clear(); } /// /// Clone the current ProtectedBinaryList object, including all /// stored protected strings. /// /// New ProtectedBinaryList object. public ProtectedBinaryDictionary CloneDeep() { ProtectedBinaryDictionary plNew = new ProtectedBinaryDictionary(); foreach(KeyValuePair kvpBin in m_vBinaries) { // ProtectedBinary objects are immutable plNew.Set(kvpBin.Key, kvpBin.Value); } return plNew; } public bool EqualsDictionary(ProtectedBinaryDictionary dict) { if(dict == null) { Debug.Assert(false); return false; } if(m_vBinaries.Count != dict.m_vBinaries.Count) return false; foreach(KeyValuePair kvp in m_vBinaries) { ProtectedBinary pb = dict.Get(kvp.Key); if(pb == null) return false; if(!pb.Equals(kvp.Value)) return false; } return true; } /// /// Get one of the stored binaries. /// /// Binary identifier. /// Protected binary. If the binary identified by /// cannot be found, the function /// returns null. /// Thrown if the input /// parameter is null. public ProtectedBinary Get(string strName) { Debug.Assert(strName != null); if(strName == null) throw new ArgumentNullException("strName"); ProtectedBinary pb; if(m_vBinaries.TryGetValue(strName, out pb)) return pb; return null; } /// /// Set a binary object. /// /// Identifier of the binary field to modify. /// New value. This parameter must not be null. /// Thrown if any of the input /// parameters is null. public void Set(string strField, ProtectedBinary pbNewValue) { Debug.Assert(strField != null); if(strField == null) throw new ArgumentNullException("strField"); Debug.Assert(pbNewValue != null); if(pbNewValue == null) throw new ArgumentNullException("pbNewValue"); m_vBinaries[strField] = pbNewValue; } /// /// Remove a binary object. /// /// Identifier of the binary field to remove. /// Returns true if the object has been successfully /// removed, otherwise false. /// Thrown if the input parameter /// is null. public bool Remove(string strField) { Debug.Assert(strField != null); if(strField == null) throw new ArgumentNullException("strField"); return m_vBinaries.Remove(strField); } public string KeysToString() { if(m_vBinaries.Count == 0) return string.Empty; StringBuilder sb = new StringBuilder(); foreach(KeyValuePair kvp in m_vBinaries) { if(sb.Length > 0) sb.Append(", "); sb.Append(kvp.Key); } return sb.ToString(); } } } KeePassLib/Collections/StringDictionaryEx.cs0000664000000000000000000000756313222430376020153 0ustar rootroot/* KeePass Password Safe - The Open-Source Password Manager Copyright (C) 2003-2018 Dominik Reichl This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ using System; using System.Collections; using System.Collections.Generic; using System.Text; using System.Diagnostics; using KeePassLib.Interfaces; #if KeePassLibSD using KeePassLibSD; #endif namespace KeePassLib.Collections { public sealed class StringDictionaryEx : IDeepCloneable, IEnumerable>, IEquatable { private SortedDictionary m_dict = new SortedDictionary(); public int Count { get { return m_dict.Count; } } public StringDictionaryEx() { } IEnumerator IEnumerable.GetEnumerator() { return m_dict.GetEnumerator(); } public IEnumerator> GetEnumerator() { return m_dict.GetEnumerator(); } public StringDictionaryEx CloneDeep() { StringDictionaryEx sdNew = new StringDictionaryEx(); foreach(KeyValuePair kvp in m_dict) sdNew.m_dict[kvp.Key] = kvp.Value; // Strings are immutable return sdNew; } public bool Equals(StringDictionaryEx sdOther) { if(sdOther == null) { Debug.Assert(false); return false; } if(m_dict.Count != sdOther.m_dict.Count) return false; foreach(KeyValuePair kvp in sdOther.m_dict) { string str = Get(kvp.Key); if((str == null) || (str != kvp.Value)) return false; } return true; } public string Get(string strName) { if(strName == null) { Debug.Assert(false); throw new ArgumentNullException("strName"); } string s; if(m_dict.TryGetValue(strName, out s)) return s; return null; } public bool Exists(string strName) { if(strName == null) { Debug.Assert(false); throw new ArgumentNullException("strName"); } return m_dict.ContainsKey(strName); } /// /// Set a string. /// /// Identifier of the string field to modify. /// New value. This parameter must not be null. /// Thrown if one of the input /// parameters is null. public void Set(string strField, string strNewValue) { if(strField == null) { Debug.Assert(false); throw new ArgumentNullException("strField"); } if(strNewValue == null) { Debug.Assert(false); throw new ArgumentNullException("strNewValue"); } m_dict[strField] = strNewValue; } /// /// Delete a string. /// /// Name of the string field to delete. /// Returns true, if the field has been successfully /// removed. Otherwise, the return value is false. /// Thrown if the input /// parameter is null. public bool Remove(string strField) { if(strField == null) { Debug.Assert(false); throw new ArgumentNullException("strField"); } return m_dict.Remove(strField); } } } KeePassLib/Collections/VariantDictionary.cs0000664000000000000000000002371713222430376020013 0ustar rootroot/* KeePass Password Safe - The Open-Source Password Manager Copyright (C) 2003-2018 Dominik Reichl This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ using System; using System.Collections.Generic; using System.Diagnostics; using System.IO; using System.Text; using KeePassLib.Resources; using KeePassLib.Utility; namespace KeePassLib.Collections { public class VariantDictionary : ICloneable { private const ushort VdVersion = 0x0100; private const ushort VdmCritical = 0xFF00; private const ushort VdmInfo = 0x00FF; private Dictionary m_d = new Dictionary(); private enum VdType : byte { None = 0, // Byte = 0x02, // UInt16 = 0x03, UInt32 = 0x04, UInt64 = 0x05, // Signed mask: 0x08 Bool = 0x08, // SByte = 0x0A, // Int16 = 0x0B, Int32 = 0x0C, Int64 = 0x0D, // Float = 0x10, // Double = 0x11, // Decimal = 0x12, // Char = 0x17, // 16-bit Unicode character String = 0x18, // Array mask: 0x40 ByteArray = 0x42 } public int Count { get { return m_d.Count; } } public VariantDictionary() { Debug.Assert((VdmCritical & VdmInfo) == ushort.MinValue); Debug.Assert((VdmCritical | VdmInfo) == ushort.MaxValue); } private bool Get(string strName, out T t) { t = default(T); if(string.IsNullOrEmpty(strName)) { Debug.Assert(false); return false; } object o; if(!m_d.TryGetValue(strName, out o)) return false; // No assert if(o == null) { Debug.Assert(false); return false; } if(o.GetType() != typeof(T)) { Debug.Assert(false); return false; } t = (T)o; return true; } private void SetStruct(string strName, T t) where T : struct { if(string.IsNullOrEmpty(strName)) { Debug.Assert(false); return; } #if DEBUG T tEx; Get(strName, out tEx); // Assert same type #endif m_d[strName] = t; } private void SetRef(string strName, T t) where T : class { if(string.IsNullOrEmpty(strName)) { Debug.Assert(false); return; } if(t == null) { Debug.Assert(false); return; } #if DEBUG T tEx; Get(strName, out tEx); // Assert same type #endif m_d[strName] = t; } public bool Remove(string strName) { if(string.IsNullOrEmpty(strName)) { Debug.Assert(false); return false; } return m_d.Remove(strName); } public void CopyTo(VariantDictionary d) { if(d == null) { Debug.Assert(false); return; } // Do not clear the target foreach(KeyValuePair kvp in m_d) { d.m_d[kvp.Key] = kvp.Value; } } public Type GetTypeOf(string strName) { if(string.IsNullOrEmpty(strName)) { Debug.Assert(false); return null; } object o; m_d.TryGetValue(strName, out o); if(o == null) return null; // No assert return o.GetType(); } public uint GetUInt32(string strName, uint uDefault) { uint u; if(Get(strName, out u)) return u; return uDefault; } public void SetUInt32(string strName, uint uValue) { SetStruct(strName, uValue); } public ulong GetUInt64(string strName, ulong uDefault) { ulong u; if(Get(strName, out u)) return u; return uDefault; } public void SetUInt64(string strName, ulong uValue) { SetStruct(strName, uValue); } public bool GetBool(string strName, bool bDefault) { bool b; if(Get(strName, out b)) return b; return bDefault; } public void SetBool(string strName, bool bValue) { SetStruct(strName, bValue); } public int GetInt32(string strName, int iDefault) { int i; if(Get(strName, out i)) return i; return iDefault; } public void SetInt32(string strName, int iValue) { SetStruct(strName, iValue); } public long GetInt64(string strName, long lDefault) { long l; if(Get(strName, out l)) return l; return lDefault; } public void SetInt64(string strName, long lValue) { SetStruct(strName, lValue); } public string GetString(string strName) { string str; Get(strName, out str); return str; } public void SetString(string strName, string strValue) { SetRef(strName, strValue); } public byte[] GetByteArray(string strName) { byte[] pb; Get(strName, out pb); return pb; } public void SetByteArray(string strName, byte[] pbValue) { SetRef(strName, pbValue); } /// /// Create a deep copy. /// public virtual object Clone() { VariantDictionary vdNew = new VariantDictionary(); foreach(KeyValuePair kvp in m_d) { object o = kvp.Value; if(o == null) { Debug.Assert(false); continue; } Type t = o.GetType(); if(t == typeof(byte[])) { byte[] p = (byte[])o; byte[] pNew = new byte[p.Length]; if(p.Length > 0) Array.Copy(p, pNew, p.Length); o = pNew; } vdNew.m_d[kvp.Key] = o; } return vdNew; } public static byte[] Serialize(VariantDictionary p) { if(p == null) { Debug.Assert(false); return null; } byte[] pbRet; using(MemoryStream ms = new MemoryStream()) { MemUtil.Write(ms, MemUtil.UInt16ToBytes(VdVersion)); foreach(KeyValuePair kvp in p.m_d) { string strName = kvp.Key; if(string.IsNullOrEmpty(strName)) { Debug.Assert(false); continue; } byte[] pbName = StrUtil.Utf8.GetBytes(strName); object o = kvp.Value; if(o == null) { Debug.Assert(false); continue; } Type t = o.GetType(); VdType vt = VdType.None; byte[] pbValue = null; if(t == typeof(uint)) { vt = VdType.UInt32; pbValue = MemUtil.UInt32ToBytes((uint)o); } else if(t == typeof(ulong)) { vt = VdType.UInt64; pbValue = MemUtil.UInt64ToBytes((ulong)o); } else if(t == typeof(bool)) { vt = VdType.Bool; pbValue = new byte[1]; pbValue[0] = ((bool)o ? (byte)1 : (byte)0); } else if(t == typeof(int)) { vt = VdType.Int32; pbValue = MemUtil.Int32ToBytes((int)o); } else if(t == typeof(long)) { vt = VdType.Int64; pbValue = MemUtil.Int64ToBytes((long)o); } else if(t == typeof(string)) { vt = VdType.String; pbValue = StrUtil.Utf8.GetBytes((string)o); } else if(t == typeof(byte[])) { vt = VdType.ByteArray; pbValue = (byte[])o; } else { Debug.Assert(false); continue; } // Unknown type ms.WriteByte((byte)vt); MemUtil.Write(ms, MemUtil.Int32ToBytes(pbName.Length)); MemUtil.Write(ms, pbName); MemUtil.Write(ms, MemUtil.Int32ToBytes(pbValue.Length)); MemUtil.Write(ms, pbValue); } ms.WriteByte((byte)VdType.None); pbRet = ms.ToArray(); } return pbRet; } public static VariantDictionary Deserialize(byte[] pb) { if(pb == null) { Debug.Assert(false); return null; } VariantDictionary d = new VariantDictionary(); using(MemoryStream ms = new MemoryStream(pb, false)) { ushort uVersion = MemUtil.BytesToUInt16(MemUtil.Read(ms, 2)); if((uVersion & VdmCritical) > (VdVersion & VdmCritical)) throw new FormatException(KLRes.FileNewVerReq); while(true) { int iType = ms.ReadByte(); if(iType < 0) throw new EndOfStreamException(KLRes.FileCorrupted); byte btType = (byte)iType; if(btType == (byte)VdType.None) break; int cbName = MemUtil.BytesToInt32(MemUtil.Read(ms, 4)); byte[] pbName = MemUtil.Read(ms, cbName); if(pbName.Length != cbName) throw new EndOfStreamException(KLRes.FileCorrupted); string strName = StrUtil.Utf8.GetString(pbName); int cbValue = MemUtil.BytesToInt32(MemUtil.Read(ms, 4)); byte[] pbValue = MemUtil.Read(ms, cbValue); if(pbValue.Length != cbValue) throw new EndOfStreamException(KLRes.FileCorrupted); switch(btType) { case (byte)VdType.UInt32: if(cbValue == 4) d.SetUInt32(strName, MemUtil.BytesToUInt32(pbValue)); else { Debug.Assert(false); } break; case (byte)VdType.UInt64: if(cbValue == 8) d.SetUInt64(strName, MemUtil.BytesToUInt64(pbValue)); else { Debug.Assert(false); } break; case (byte)VdType.Bool: if(cbValue == 1) d.SetBool(strName, (pbValue[0] != 0)); else { Debug.Assert(false); } break; case (byte)VdType.Int32: if(cbValue == 4) d.SetInt32(strName, MemUtil.BytesToInt32(pbValue)); else { Debug.Assert(false); } break; case (byte)VdType.Int64: if(cbValue == 8) d.SetInt64(strName, MemUtil.BytesToInt64(pbValue)); else { Debug.Assert(false); } break; case (byte)VdType.String: d.SetString(strName, StrUtil.Utf8.GetString(pbValue)); break; case (byte)VdType.ByteArray: d.SetByteArray(strName, pbValue); break; default: Debug.Assert(false); // Unknown type break; } } Debug.Assert(ms.ReadByte() < 0); } return d; } } } KeePassLib/Collections/ProtectedBinarySet.cs0000664000000000000000000000776513222430376020140 0ustar rootroot/* KeePass Password Safe - The Open-Source Password Manager Copyright (C) 2003-2018 Dominik Reichl This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ using System; using System.Collections; using System.Collections.Generic; using System.Diagnostics; using System.Text; using KeePassLib.Delegates; using KeePassLib.Security; namespace KeePassLib.Collections { internal sealed class ProtectedBinarySet : IEnumerable> { private Dictionary m_d = new Dictionary(); public ProtectedBinarySet() { } IEnumerator IEnumerable.GetEnumerator() { return m_d.GetEnumerator(); } public IEnumerator> GetEnumerator() { return m_d.GetEnumerator(); } public void Clear() { m_d.Clear(); } private int GetFreeID() { int i = m_d.Count; while(m_d.ContainsKey(i)) { ++i; } Debug.Assert(i == m_d.Count); // m_d.Count should be free return i; } public ProtectedBinary Get(int iID) { ProtectedBinary pb; if(m_d.TryGetValue(iID, out pb)) return pb; // Debug.Assert(false); // No assert return null; } public int Find(ProtectedBinary pb) { if(pb == null) { Debug.Assert(false); return -1; } // Fast search by reference foreach(KeyValuePair kvp in m_d) { if(object.ReferenceEquals(pb, kvp.Value)) { Debug.Assert(pb.Equals(kvp.Value)); return kvp.Key; } } // Slow search by content foreach(KeyValuePair kvp in m_d) { if(pb.Equals(kvp.Value)) return kvp.Key; } // Debug.Assert(false); // No assert return -1; } public void Set(int iID, ProtectedBinary pb) { if(iID < 0) { Debug.Assert(false); return; } if(pb == null) { Debug.Assert(false); return; } m_d[iID] = pb; } public void Add(ProtectedBinary pb) { if(pb == null) { Debug.Assert(false); return; } int i = Find(pb); if(i >= 0) return; // Exists already i = GetFreeID(); m_d[i] = pb; } public void AddFrom(ProtectedBinaryDictionary d) { if(d == null) { Debug.Assert(false); return; } foreach(KeyValuePair kvp in d) { Add(kvp.Value); } } public void AddFrom(PwGroup pg) { if(pg == null) { Debug.Assert(false); return; } EntryHandler eh = delegate(PwEntry pe) { if(pe == null) { Debug.Assert(false); return true; } AddFrom(pe.Binaries); foreach(PwEntry peHistory in pe.History) { if(peHistory == null) { Debug.Assert(false); continue; } AddFrom(peHistory.Binaries); } return true; }; pg.TraverseTree(TraversalMethod.PreOrder, null, eh); } public ProtectedBinary[] ToArray() { int n = m_d.Count; ProtectedBinary[] v = new ProtectedBinary[n]; foreach(KeyValuePair kvp in m_d) { if((kvp.Key < 0) || (kvp.Key >= n)) { Debug.Assert(false); throw new InvalidOperationException(); } v[kvp.Key] = kvp.Value; } for(int i = 0; i < n; ++i) { if(v[i] == null) { Debug.Assert(false); throw new InvalidOperationException(); } } return v; } } } KeePassLib/Collections/PwObjectPool.cs0000664000000000000000000001261313222430376016721 0ustar rootroot/* KeePass Password Safe - The Open-Source Password Manager Copyright (C) 2003-2018 Dominik Reichl This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ using System; using System.Collections; using System.Collections.Generic; using System.Diagnostics; using System.Text; using KeePassLib.Delegates; using KeePassLib.Interfaces; using KeePassLib.Utility; #if KeePassLibSD using KeePassLibSD; #endif namespace KeePassLib.Collections { public sealed class PwObjectPool { private SortedDictionary m_dict = new SortedDictionary(); public static PwObjectPool FromGroupRecursive(PwGroup pgRoot, bool bEntries) { if(pgRoot == null) throw new ArgumentNullException("pgRoot"); PwObjectPool p = new PwObjectPool(); if(!bEntries) p.m_dict[pgRoot.Uuid] = pgRoot; GroupHandler gh = delegate(PwGroup pg) { p.m_dict[pg.Uuid] = pg; return true; }; EntryHandler eh = delegate(PwEntry pe) { p.m_dict[pe.Uuid] = pe; return true; }; pgRoot.TraverseTree(TraversalMethod.PreOrder, bEntries ? null : gh, bEntries ? eh : null); return p; } public IStructureItem Get(PwUuid pwUuid) { IStructureItem pItem; m_dict.TryGetValue(pwUuid, out pItem); return pItem; } public bool ContainsOnlyType(Type t) { foreach(KeyValuePair kvp in m_dict) { if(kvp.Value.GetType() != t) return false; } return true; } } internal sealed class PwObjectPoolEx { private Dictionary m_dUuidToId = new Dictionary(); private Dictionary m_dIdToItem = new Dictionary(); private PwObjectPoolEx() { } public static PwObjectPoolEx FromGroup(PwGroup pg) { PwObjectPoolEx p = new PwObjectPoolEx(); if(pg == null) { Debug.Assert(false); return p; } ulong uFreeId = 2; // 0 = "not found", 1 is a hole p.m_dUuidToId[pg.Uuid] = uFreeId; p.m_dIdToItem[uFreeId] = pg; uFreeId += 2; // Make hole p.AddGroupRec(pg, ref uFreeId); return p; } private void AddGroupRec(PwGroup pg, ref ulong uFreeId) { if(pg == null) { Debug.Assert(false); return; } ulong uId = uFreeId; // Consecutive entries must have consecutive IDs foreach(PwEntry pe in pg.Entries) { Debug.Assert(!m_dUuidToId.ContainsKey(pe.Uuid)); Debug.Assert(!m_dIdToItem.ContainsValue(pe)); m_dUuidToId[pe.Uuid] = uId; m_dIdToItem[uId] = pe; ++uId; } ++uId; // Make hole // Consecutive groups must have consecutive IDs foreach(PwGroup pgSub in pg.Groups) { Debug.Assert(!m_dUuidToId.ContainsKey(pgSub.Uuid)); Debug.Assert(!m_dIdToItem.ContainsValue(pgSub)); m_dUuidToId[pgSub.Uuid] = uId; m_dIdToItem[uId] = pgSub; ++uId; } ++uId; // Make hole foreach(PwGroup pgSub in pg.Groups) { AddGroupRec(pgSub, ref uId); } uFreeId = uId; } public ulong GetIdByUuid(PwUuid pwUuid) { if(pwUuid == null) { Debug.Assert(false); return 0; } ulong uId; m_dUuidToId.TryGetValue(pwUuid, out uId); return uId; } public IStructureItem GetItemByUuid(PwUuid pwUuid) { if(pwUuid == null) { Debug.Assert(false); return null; } ulong uId; if(!m_dUuidToId.TryGetValue(pwUuid, out uId)) return null; Debug.Assert(uId != 0); return GetItemById(uId); } public IStructureItem GetItemById(ulong uId) { IStructureItem p; m_dIdToItem.TryGetValue(uId, out p); return p; } } internal sealed class PwObjectBlock : IEnumerable where T : class, ITimeLogger, IStructureItem, IDeepCloneable { private List m_l = new List(); public T PrimaryItem { get { return ((m_l.Count > 0) ? m_l[0] : null); } } private DateTime m_dtLocationChanged = TimeUtil.SafeMinValueUtc; public DateTime LocationChanged { get { return m_dtLocationChanged; } } private PwObjectPoolEx m_poolAssoc = null; public PwObjectPoolEx PoolAssoc { get { return m_poolAssoc; } } public PwObjectBlock() { } #if DEBUG public override string ToString() { return ("PwObjectBlock, Count = " + m_l.Count.ToString()); } #endif IEnumerator IEnumerable.GetEnumerator() { return m_l.GetEnumerator(); } public IEnumerator GetEnumerator() { return m_l.GetEnumerator(); } public void Add(T t, DateTime dtLoc, PwObjectPoolEx pool) { if(t == null) { Debug.Assert(false); return; } m_l.Add(t); if(dtLoc > m_dtLocationChanged) { m_dtLocationChanged = dtLoc; m_poolAssoc = pool; } } } } KeePassLib/Collections/AutoTypeConfig.cs0000664000000000000000000001471713222430376017261 0ustar rootroot/* KeePass Password Safe - The Open-Source Password Manager Copyright (C) 2003-2018 Dominik Reichl This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ using System; using System.Collections.Generic; using System.Diagnostics; using KeePassLib.Interfaces; namespace KeePassLib.Collections { [Flags] public enum AutoTypeObfuscationOptions { None = 0, UseClipboard = 1 } public sealed class AutoTypeAssociation : IEquatable, IDeepCloneable { private string m_strWindow = string.Empty; public string WindowName { get { return m_strWindow; } set { Debug.Assert(value != null); if(value == null) throw new ArgumentNullException("value"); m_strWindow = value; } } private string m_strSequence = string.Empty; public string Sequence { get { return m_strSequence; } set { Debug.Assert(value != null); if(value == null) throw new ArgumentNullException("value"); m_strSequence = value; } } public AutoTypeAssociation() { } public AutoTypeAssociation(string strWindow, string strSeq) { if(strWindow == null) throw new ArgumentNullException("strWindow"); if(strSeq == null) throw new ArgumentNullException("strSeq"); m_strWindow = strWindow; m_strSequence = strSeq; } public bool Equals(AutoTypeAssociation other) { if(other == null) return false; if(m_strWindow != other.m_strWindow) return false; if(m_strSequence != other.m_strSequence) return false; return true; } public AutoTypeAssociation CloneDeep() { return (AutoTypeAssociation)this.MemberwiseClone(); } } /// /// A list of auto-type associations. /// public sealed class AutoTypeConfig : IEquatable, IDeepCloneable { private bool m_bEnabled = true; private AutoTypeObfuscationOptions m_atooObfuscation = AutoTypeObfuscationOptions.None; private string m_strDefaultSequence = string.Empty; private List m_lWindowAssocs = new List(); /// /// Specify whether auto-type is enabled or not. /// public bool Enabled { get { return m_bEnabled; } set { m_bEnabled = value; } } /// /// Specify whether the typing should be obfuscated. /// public AutoTypeObfuscationOptions ObfuscationOptions { get { return m_atooObfuscation; } set { m_atooObfuscation = value; } } /// /// The default keystroke sequence that is auto-typed if /// no matching window is found in the Associations /// container. /// public string DefaultSequence { get { return m_strDefaultSequence; } set { Debug.Assert(value != null); if(value == null) throw new ArgumentNullException("value"); m_strDefaultSequence = value; } } /// /// Get all auto-type window/keystroke sequence pairs. /// public IEnumerable Associations { get { return m_lWindowAssocs; } } public int AssociationsCount { get { return m_lWindowAssocs.Count; } } /// /// Construct a new auto-type associations list. /// public AutoTypeConfig() { } /// /// Remove all associations. /// public void Clear() { m_lWindowAssocs.Clear(); } /// /// Clone the auto-type associations list. /// /// New, cloned object. public AutoTypeConfig CloneDeep() { AutoTypeConfig newCfg = new AutoTypeConfig(); newCfg.m_bEnabled = m_bEnabled; newCfg.m_atooObfuscation = m_atooObfuscation; newCfg.m_strDefaultSequence = m_strDefaultSequence; foreach(AutoTypeAssociation a in m_lWindowAssocs) newCfg.Add(a.CloneDeep()); return newCfg; } public bool Equals(AutoTypeConfig other) { if(other == null) { Debug.Assert(false); return false; } if(m_bEnabled != other.m_bEnabled) return false; if(m_atooObfuscation != other.m_atooObfuscation) return false; if(m_strDefaultSequence != other.m_strDefaultSequence) return false; if(m_lWindowAssocs.Count != other.m_lWindowAssocs.Count) return false; for(int i = 0; i < m_lWindowAssocs.Count; ++i) { if(!m_lWindowAssocs[i].Equals(other.m_lWindowAssocs[i])) return false; } return true; } public AutoTypeAssociation GetAt(int iIndex) { if((iIndex < 0) || (iIndex >= m_lWindowAssocs.Count)) throw new ArgumentOutOfRangeException("iIndex"); return m_lWindowAssocs[iIndex]; } public void Add(AutoTypeAssociation a) { if(a == null) { Debug.Assert(false); throw new ArgumentNullException("a"); } m_lWindowAssocs.Add(a); } public void Insert(int iIndex, AutoTypeAssociation a) { if((iIndex < 0) || (iIndex > m_lWindowAssocs.Count)) throw new ArgumentOutOfRangeException("iIndex"); if(a == null) { Debug.Assert(false); throw new ArgumentNullException("a"); } m_lWindowAssocs.Insert(iIndex, a); } public void RemoveAt(int iIndex) { if((iIndex < 0) || (iIndex >= m_lWindowAssocs.Count)) throw new ArgumentOutOfRangeException("iIndex"); m_lWindowAssocs.RemoveAt(iIndex); } // public void Sort() // { // m_lWindowAssocs.Sort(AutoTypeConfig.AssocCompareFn); // } // private static int AssocCompareFn(AutoTypeAssociation x, // AutoTypeAssociation y) // { // if(x == null) { Debug.Assert(false); return ((y == null) ? 0 : -1); } // if(y == null) { Debug.Assert(false); return 1; } // int cn = x.WindowName.CompareTo(y.WindowName); // if(cn != 0) return cn; // return x.Sequence.CompareTo(y.Sequence); // } } } KeePassLib/PwCustomIcon.cs0000664000000000000000000000714013222430400014451 0ustar rootroot/* KeePass Password Safe - The Open-Source Password Manager Copyright (C) 2003-2018 Dominik Reichl This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ using System; using System.Collections.Generic; using System.Diagnostics; #if !KeePassUAP using System.Drawing; #endif using KeePassLib.Utility; namespace KeePassLib { /// /// Custom icon. PwCustomIcon objects are immutable. /// public sealed class PwCustomIcon { private readonly PwUuid m_pwUuid; private readonly byte[] m_pbImageDataPng; private readonly Image m_imgOrg; private Dictionary m_dImageCache = new Dictionary(); // Recommended maximum sizes, not obligatory internal const int MaxWidth = 128; internal const int MaxHeight = 128; public PwUuid Uuid { get { return m_pwUuid; } } public byte[] ImageDataPng { get { return m_pbImageDataPng; } } [Obsolete("Use GetImage instead.")] public Image Image { #if (!KeePassLibSD && !KeePassUAP) get { return GetImage(16, 16); } // Backward compatibility #else get { return GetImage(); } // Backward compatibility #endif } public PwCustomIcon(PwUuid pwUuid, byte[] pbImageDataPng) { Debug.Assert(pwUuid != null); if(pwUuid == null) throw new ArgumentNullException("pwUuid"); Debug.Assert(!pwUuid.Equals(PwUuid.Zero)); if(pwUuid.Equals(PwUuid.Zero)) throw new ArgumentException("pwUuid == 0."); Debug.Assert(pbImageDataPng != null); if(pbImageDataPng == null) throw new ArgumentNullException("pbImageDataPng"); m_pwUuid = pwUuid; m_pbImageDataPng = pbImageDataPng; // MemoryStream ms = new MemoryStream(m_pbImageDataPng, false); // m_imgOrg = Image.FromStream(ms); // ms.Close(); try { m_imgOrg = GfxUtil.LoadImage(m_pbImageDataPng); } catch(Exception) { Debug.Assert(false); m_imgOrg = null; } if(m_imgOrg != null) m_dImageCache[GetID(m_imgOrg.Width, m_imgOrg.Height)] = m_imgOrg; } private static long GetID(int w, int h) { return (((long)w << 32) ^ (long)h); } /// /// Get the icon as an Image (original size). /// public Image GetImage() { return m_imgOrg; } #if (!KeePassLibSD && !KeePassUAP) /// /// Get the icon as an Image (with the specified size). /// /// Width of the returned image. /// Height of the returned image. public Image GetImage(int w, int h) { if(w < 0) { Debug.Assert(false); return m_imgOrg; } if(h < 0) { Debug.Assert(false); return m_imgOrg; } if(m_imgOrg == null) return null; long lID = GetID(w, h); Image img; if(m_dImageCache.TryGetValue(lID, out img)) return img; img = GfxUtil.ScaleImage(m_imgOrg, w, h, ScaleTransformFlags.UIIcon); m_dImageCache[lID] = img; return img; } #endif } } KeePassLib/Keys/0000775000000000000000000000000013222430400012441 5ustar rootrootKeePassLib/Keys/IUserKey.cs0000664000000000000000000000271213222430400014472 0ustar rootroot/* KeePass Password Safe - The Open-Source Password Manager Copyright (C) 2003-2018 Dominik Reichl This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ using System; using KeePassLib.Security; namespace KeePassLib.Keys { /// /// Interface to a user key, like a password, key file data, etc. /// public interface IUserKey { /// /// Get key data. Querying this property is fast (it returns a /// reference to a cached ProtectedBinary object). /// If no key data is available, null is returned. /// ProtectedBinary KeyData { get; } // /// // /// Clear the key and securely erase all security-critical information. // /// // void Clear(); } } KeePassLib/Keys/KeyValidatorPool.cs0000664000000000000000000000465113222430400016226 0ustar rootroot/* KeePass Password Safe - The Open-Source Password Manager Copyright (C) 2003-2018 Dominik Reichl This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ using System; using System.Collections; using System.Collections.Generic; using System.Text; using System.Diagnostics; using KeePassLib.Utility; namespace KeePassLib.Keys { public sealed class KeyValidatorPool : IEnumerable { private List m_vValidators = new List(); public int Count { get { return m_vValidators.Count; } } IEnumerator IEnumerable.GetEnumerator() { return m_vValidators.GetEnumerator(); } public IEnumerator GetEnumerator() { return m_vValidators.GetEnumerator(); } public void Add(KeyValidator v) { Debug.Assert(v != null); if(v == null) throw new ArgumentNullException("v"); m_vValidators.Add(v); } public bool Remove(KeyValidator v) { Debug.Assert(v != null); if(v == null) throw new ArgumentNullException("v"); return m_vValidators.Remove(v); } public string Validate(string strKey, KeyValidationType t) { Debug.Assert(strKey != null); if(strKey == null) throw new ArgumentNullException("strKey"); foreach(KeyValidator v in m_vValidators) { string strResult = v.Validate(strKey, t); if(strResult != null) return strResult; } return null; } public string Validate(byte[] pbKeyUtf8, KeyValidationType t) { Debug.Assert(pbKeyUtf8 != null); if(pbKeyUtf8 == null) throw new ArgumentNullException("pbKeyUtf8"); if(m_vValidators.Count == 0) return null; string strKey = StrUtil.Utf8.GetString(pbKeyUtf8, 0, pbKeyUtf8.Length); return Validate(strKey, t); } } } KeePassLib/Keys/KeyProviderPool.cs0000664000000000000000000000541213222430400016067 0ustar rootroot/* KeePass Password Safe - The Open-Source Password Manager Copyright (C) 2003-2018 Dominik Reichl This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ using System; using System.Collections; using System.Collections.Generic; using System.Text; using System.Diagnostics; namespace KeePassLib.Keys { public sealed class KeyProviderPool : IEnumerable { private List m_vProviders = new List(); public int Count { get { return m_vProviders.Count; } } IEnumerator IEnumerable.GetEnumerator() { return m_vProviders.GetEnumerator(); } public IEnumerator GetEnumerator() { return m_vProviders.GetEnumerator(); } public void Add(KeyProvider prov) { Debug.Assert(prov != null); if(prov == null) throw new ArgumentNullException("prov"); m_vProviders.Add(prov); } public bool Remove(KeyProvider prov) { Debug.Assert(prov != null); if(prov == null) throw new ArgumentNullException("prov"); return m_vProviders.Remove(prov); } public KeyProvider Get(string strProviderName) { if(strProviderName == null) throw new ArgumentNullException("strProviderName"); foreach(KeyProvider prov in m_vProviders) { if(prov.Name == strProviderName) return prov; } return null; } public bool IsKeyProvider(string strName) { Debug.Assert(strName != null); if(strName == null) throw new ArgumentNullException("strName"); foreach(KeyProvider prov in m_vProviders) { if(prov.Name == strName) return true; } return false; } internal byte[] GetKey(string strProviderName, KeyProviderQueryContext ctx, out bool bPerformHash) { Debug.Assert(strProviderName != null); if(strProviderName == null) throw new ArgumentNullException("strProviderName"); bPerformHash = true; foreach(KeyProvider prov in m_vProviders) { if(prov.Name == strProviderName) { bPerformHash = !prov.DirectKey; return prov.GetKey(ctx); } } Debug.Assert(false); return null; } } } KeePassLib/Keys/KeyValidator.cs0000664000000000000000000000314213222430400015366 0ustar rootroot/* KeePass Password Safe - The Open-Source Password Manager Copyright (C) 2003-2018 Dominik Reichl This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ using System; using System.Collections.Generic; using System.Text; namespace KeePassLib.Keys { public enum KeyValidationType { MasterPassword = 0 } public abstract class KeyValidator { /// /// Name of your key validator (should be unique). /// public abstract string Name { get; } /// /// Validate a key. /// /// Key to validate. /// Type of the validation to perform. /// Returns null, if the validation is successful. /// If there's a problem with the key, the returned string describes /// the problem. public abstract string Validate(string strKey, KeyValidationType t); } } KeePassLib/Keys/KcpPassword.cs0000664000000000000000000000527713222430400015243 0ustar rootroot/* KeePass Password Safe - The Open-Source Password Manager Copyright (C) 2003-2018 Dominik Reichl This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ using System; using System.Diagnostics; using System.Text; using KeePassLib.Cryptography; using KeePassLib.Security; using KeePassLib.Utility; namespace KeePassLib.Keys { /// /// Master password / passphrase as provided by the user. /// public sealed class KcpPassword : IUserKey { private ProtectedString m_psPassword; private ProtectedBinary m_pbKeyData; /// /// Get the password as protected string. /// public ProtectedString Password { get { return m_psPassword; } } /// /// Get key data. Querying this property is fast (it returns a /// reference to a cached ProtectedBinary object). /// If no key data is available, null is returned. /// public ProtectedBinary KeyData { get { return m_pbKeyData; } } public KcpPassword(byte[] pbPasswordUtf8) { SetKey(pbPasswordUtf8); } public KcpPassword(string strPassword) { SetKey(StrUtil.Utf8.GetBytes(strPassword)); } private void SetKey(byte[] pbPasswordUtf8) { Debug.Assert(pbPasswordUtf8 != null); if(pbPasswordUtf8 == null) throw new ArgumentNullException("pbPasswordUtf8"); #if (DEBUG && !KeePassLibSD) Debug.Assert(ValidatePassword(pbPasswordUtf8)); #endif byte[] pbRaw = CryptoUtil.HashSha256(pbPasswordUtf8); m_psPassword = new ProtectedString(true, pbPasswordUtf8); m_pbKeyData = new ProtectedBinary(true, pbRaw); } // public void Clear() // { // m_psPassword = null; // m_pbKeyData = null; // } #if (DEBUG && !KeePassLibSD) private static bool ValidatePassword(byte[] pb) { try { string str = StrUtil.Utf8.GetString(pb); return str.IsNormalized(NormalizationForm.FormC); } catch(Exception) { Debug.Assert(false); } return false; } #endif } } KeePassLib/Keys/KcpCustomKey.cs0000664000000000000000000000370513222430400015356 0ustar rootroot/* KeePass Password Safe - The Open-Source Password Manager Copyright (C) 2003-2018 Dominik Reichl This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ using System; using System.Collections.Generic; using System.Diagnostics; using System.Text; using KeePassLib.Cryptography; using KeePassLib.Security; namespace KeePassLib.Keys { public sealed class KcpCustomKey : IUserKey { private readonly string m_strName; private ProtectedBinary m_pbKey; /// /// Name of the provider that generated the custom key. /// public string Name { get { return m_strName; } } public ProtectedBinary KeyData { get { return m_pbKey; } } public KcpCustomKey(string strName, byte[] pbKeyData, bool bPerformHash) { Debug.Assert(strName != null); if(strName == null) throw new ArgumentNullException("strName"); Debug.Assert(pbKeyData != null); if(pbKeyData == null) throw new ArgumentNullException("pbKeyData"); m_strName = strName; if(bPerformHash) { byte[] pbRaw = CryptoUtil.HashSha256(pbKeyData); m_pbKey = new ProtectedBinary(true, pbRaw); } else m_pbKey = new ProtectedBinary(true, pbKeyData); } // public void Clear() // { // m_pbKey = null; // } } } KeePassLib/Keys/KeyProvider.cs0000664000000000000000000001024513222430400015235 0ustar rootroot/* KeePass Password Safe - The Open-Source Password Manager Copyright (C) 2003-2018 Dominik Reichl This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ using System; using System.Collections.Generic; using System.Text; using KeePassLib.Serialization; namespace KeePassLib.Keys { public sealed class KeyProviderQueryContext { private IOConnectionInfo m_ioInfo; public IOConnectionInfo DatabaseIOInfo { get { return m_ioInfo; } } public string DatabasePath { get { return m_ioInfo.Path; } } private bool m_bCreatingNewKey; public bool CreatingNewKey { get { return m_bCreatingNewKey; } } private bool m_bSecDesktop; public bool IsOnSecureDesktop { get { return m_bSecDesktop; } } public KeyProviderQueryContext(IOConnectionInfo ioInfo, bool bCreatingNewKey, bool bOnSecDesktop) { if(ioInfo == null) throw new ArgumentNullException("ioInfo"); m_ioInfo = ioInfo.CloneDeep(); m_bCreatingNewKey = bCreatingNewKey; m_bSecDesktop = bOnSecDesktop; } } public abstract class KeyProvider { /// /// Name of your key provider (should be unique). /// public abstract string Name { get; } /// /// Property indicating whether the provider is exclusive. /// If the provider is exclusive, KeePass doesn't allow other /// key sources (master password, Windows user account, ...) /// to be combined with the provider. /// Key providers typically should return false /// (to allow non-exclusive use), i.e. don't override this /// property. /// public virtual bool Exclusive { get { return false; } } /// /// Property that specifies whether the returned key data /// gets hashed by KeePass first or is written directly to /// the user key data stream. /// Standard key provider plugins should return false /// (i.e. don't overwrite this property). Returning true /// may cause severe security problems and is highly /// discouraged. /// public virtual bool DirectKey { get { return false; } } // public virtual PwIcon ImageIndex // { // get { return PwIcon.UserKey; } // } /// /// This property specifies whether the GetKey method might /// show a form or dialog. If there is any chance that the method shows /// one, this property must return true. Only if it's guaranteed /// that the GetKey method doesn't show any form or dialog, this /// property should return false. /// public virtual bool GetKeyMightShowGui { get { return true; } } /// /// This property specifies whether the key provider is compatible /// with the secure desktop mode. This almost never is the case, /// so you usually won't override this property. /// public virtual bool SecureDesktopCompatible { get { return false; } } public abstract byte[] GetKey(KeyProviderQueryContext ctx); } #if DEBUG public sealed class SampleKeyProvider : KeyProvider { public override string Name { get { return "Built-In Sample Key Provider"; } } // Do not just copy this to your own key provider class! See above. public override bool GetKeyMightShowGui { get { return false; } } public override byte[] GetKey(KeyProviderQueryContext ctx) { return new byte[]{ 2, 3, 5, 7, 11, 13 }; } } #endif } KeePassLib/Keys/KcpUserAccount.cs0000664000000000000000000001034013222430400015657 0ustar rootroot/* KeePass Password Safe - The Open-Source Password Manager Copyright (C) 2003-2018 Dominik Reichl This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ using System; using System.Diagnostics; using System.IO; using System.Security; #if !KeePassUAP using System.Security.Cryptography; #endif using KeePassLib.Cryptography; using KeePassLib.Resources; using KeePassLib.Security; using KeePassLib.Utility; namespace KeePassLib.Keys { /// /// A user key depending on the currently logged on Windows user account. /// public sealed class KcpUserAccount : IUserKey { private ProtectedBinary m_pbKeyData = null; // Constant initialization vector (unique for KeePass) private static readonly byte[] m_pbEntropy = new byte[] { 0xDE, 0x13, 0x5B, 0x5F, 0x18, 0xA3, 0x46, 0x70, 0xB2, 0x57, 0x24, 0x29, 0x69, 0x88, 0x98, 0xE6 }; private const string UserKeyFileName = "ProtectedUserKey.bin"; /// /// Get key data. Querying this property is fast (it returns a /// reference to a cached ProtectedBinary object). /// If no key data is available, null is returned. /// public ProtectedBinary KeyData { get { return m_pbKeyData; } } /// /// Construct a user account key. /// public KcpUserAccount() { // Test if ProtectedData is supported -- throws an exception // when running on an old system (Windows 98 / ME). byte[] pbDummyData = new byte[128]; ProtectedData.Protect(pbDummyData, m_pbEntropy, DataProtectionScope.CurrentUser); byte[] pbKey = LoadUserKey(false); if(pbKey == null) pbKey = CreateUserKey(); if(pbKey == null) // Should never happen { Debug.Assert(false); throw new SecurityException(KLRes.UserAccountKeyError); } m_pbKeyData = new ProtectedBinary(true, pbKey); MemUtil.ZeroByteArray(pbKey); } // public void Clear() // { // m_pbKeyData = null; // } private static string GetUserKeyFilePath(bool bCreate) { #if KeePassUAP string strUserDir = EnvironmentExt.AppDataRoamingFolderPath; #else string strUserDir = Environment.GetFolderPath( Environment.SpecialFolder.ApplicationData); #endif strUserDir = UrlUtil.EnsureTerminatingSeparator(strUserDir, false); strUserDir += PwDefs.ShortProductName; if(bCreate && !Directory.Exists(strUserDir)) Directory.CreateDirectory(strUserDir); strUserDir = UrlUtil.EnsureTerminatingSeparator(strUserDir, false); return (strUserDir + UserKeyFileName); } private static byte[] LoadUserKey(bool bThrow) { byte[] pbKey = null; #if !KeePassLibSD try { string strFilePath = GetUserKeyFilePath(false); byte[] pbProtectedKey = File.ReadAllBytes(strFilePath); pbKey = ProtectedData.Unprotect(pbProtectedKey, m_pbEntropy, DataProtectionScope.CurrentUser); } catch(Exception) { if(bThrow) throw; pbKey = null; } #endif return pbKey; } private static byte[] CreateUserKey() { #if KeePassLibSD return null; #else string strFilePath = GetUserKeyFilePath(true); byte[] pbRandomKey = CryptoRandom.Instance.GetRandomBytes(64); byte[] pbProtectedKey = ProtectedData.Protect(pbRandomKey, m_pbEntropy, DataProtectionScope.CurrentUser); File.WriteAllBytes(strFilePath, pbProtectedKey); byte[] pbKey = LoadUserKey(true); Debug.Assert(MemUtil.ArraysEqual(pbKey, pbRandomKey)); MemUtil.ZeroByteArray(pbRandomKey); return pbKey; #endif } } } KeePassLib/Keys/UserKeyType.cs0000664000000000000000000000200413222430400015215 0ustar rootroot/* KeePass Password Safe - The Open-Source Password Manager Copyright (C) 2003-2018 Dominik Reichl This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ using System; namespace KeePassLib.Keys { [Flags] public enum UserKeyType { None = 0, Other = 1, Password = 2, KeyFile = 4, UserAccount = 8 } } KeePassLib/Keys/KcpKeyFile.cs0000664000000000000000000002211613222430400014760 0ustar rootroot/* KeePass Password Safe - The Open-Source Password Manager Copyright (C) 2003-2018 Dominik Reichl This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ using System; using System.Diagnostics; using System.IO; using System.Security; using System.Text; using System.Xml; #if !KeePassUAP using System.Security.Cryptography; #endif using KeePassLib.Cryptography; using KeePassLib.Resources; using KeePassLib.Security; using KeePassLib.Serialization; using KeePassLib.Utility; namespace KeePassLib.Keys { /// /// Key files as provided by the user. /// public sealed class KcpKeyFile : IUserKey { private string m_strPath; private ProtectedBinary m_pbKeyData; /// /// Path to the key file. /// public string Path { get { return m_strPath; } } /// /// Get key data. Querying this property is fast (it returns a /// reference to a cached ProtectedBinary object). /// If no key data is available, null is returned. /// public ProtectedBinary KeyData { get { return m_pbKeyData; } } public KcpKeyFile(string strKeyFile) { Construct(IOConnectionInfo.FromPath(strKeyFile), false); } public KcpKeyFile(string strKeyFile, bool bThrowIfDbFile) { Construct(IOConnectionInfo.FromPath(strKeyFile), bThrowIfDbFile); } public KcpKeyFile(IOConnectionInfo iocKeyFile) { Construct(iocKeyFile, false); } public KcpKeyFile(IOConnectionInfo iocKeyFile, bool bThrowIfDbFile) { Construct(iocKeyFile, bThrowIfDbFile); } private void Construct(IOConnectionInfo iocFile, bool bThrowIfDbFile) { byte[] pbFileData = IOConnection.ReadFile(iocFile); if(pbFileData == null) throw new FileNotFoundException(); if(bThrowIfDbFile && (pbFileData.Length >= 8)) { uint uSig1 = MemUtil.BytesToUInt32(MemUtil.Mid(pbFileData, 0, 4)); uint uSig2 = MemUtil.BytesToUInt32(MemUtil.Mid(pbFileData, 4, 4)); if(((uSig1 == KdbxFile.FileSignature1) && (uSig2 == KdbxFile.FileSignature2)) || ((uSig1 == KdbxFile.FileSignaturePreRelease1) && (uSig2 == KdbxFile.FileSignaturePreRelease2)) || ((uSig1 == KdbxFile.FileSignatureOld1) && (uSig2 == KdbxFile.FileSignatureOld2))) #if KeePassLibSD throw new Exception(KLRes.KeyFileDbSel); #else throw new InvalidDataException(KLRes.KeyFileDbSel); #endif } byte[] pbKey = LoadXmlKeyFile(pbFileData); if(pbKey == null) pbKey = LoadKeyFile(pbFileData); if(pbKey == null) throw new InvalidOperationException(); m_strPath = iocFile.Path; m_pbKeyData = new ProtectedBinary(true, pbKey); MemUtil.ZeroByteArray(pbKey); } // public void Clear() // { // m_strPath = string.Empty; // m_pbKeyData = null; // } private static byte[] LoadKeyFile(byte[] pbFileData) { if(pbFileData == null) { Debug.Assert(false); return null; } int iLength = pbFileData.Length; byte[] pbKey = null; if(iLength == 32) pbKey = LoadBinaryKey32(pbFileData); else if(iLength == 64) pbKey = LoadHexKey32(pbFileData); if(pbKey == null) pbKey = CryptoUtil.HashSha256(pbFileData); return pbKey; } private static byte[] LoadBinaryKey32(byte[] pbFileData) { if(pbFileData == null) { Debug.Assert(false); return null; } if(pbFileData.Length != 32) { Debug.Assert(false); return null; } return pbFileData; } private static byte[] LoadHexKey32(byte[] pbFileData) { if(pbFileData == null) { Debug.Assert(false); return null; } if(pbFileData.Length != 64) { Debug.Assert(false); return null; } try { if(!StrUtil.IsHexString(pbFileData, true)) return null; string strHex = StrUtil.Utf8.GetString(pbFileData); byte[] pbKey = MemUtil.HexStringToByteArray(strHex); if((pbKey == null) || (pbKey.Length != 32)) { Debug.Assert(false); return null; } return pbKey; } catch(Exception) { Debug.Assert(false); } return null; } /// /// Create a new, random key-file. /// /// Path where the key-file should be saved to. /// If the file exists already, it will be overwritten. /// Additional entropy used to generate /// the random key. May be null (in this case only the KeePass-internal /// random number generator is used). /// Returns a FileSaveResult error code. public static void Create(string strFilePath, byte[] pbAdditionalEntropy) { byte[] pbKey32 = CryptoRandom.Instance.GetRandomBytes(32); if(pbKey32 == null) throw new SecurityException(); byte[] pbFinalKey32; if((pbAdditionalEntropy == null) || (pbAdditionalEntropy.Length == 0)) pbFinalKey32 = pbKey32; else { using(MemoryStream ms = new MemoryStream()) { MemUtil.Write(ms, pbAdditionalEntropy); MemUtil.Write(ms, pbKey32); pbFinalKey32 = CryptoUtil.HashSha256(ms.ToArray()); } } CreateXmlKeyFile(strFilePath, pbFinalKey32); } // ================================================================ // XML Key Files // ================================================================ // Sample XML file: // // // // 1.00 // // // ySFoKuCcJblw8ie6RkMBdVCnAf4EedSch7ItujK6bmI= // // private const string RootElementName = "KeyFile"; private const string MetaElementName = "Meta"; private const string VersionElementName = "Version"; private const string KeyElementName = "Key"; private const string KeyDataElementName = "Data"; private static byte[] LoadXmlKeyFile(byte[] pbFileData) { if(pbFileData == null) { Debug.Assert(false); return null; } MemoryStream ms = new MemoryStream(pbFileData, false); byte[] pbKeyData = null; try { XmlDocument doc = new XmlDocument(); doc.Load(ms); XmlElement el = doc.DocumentElement; if((el == null) || !el.Name.Equals(RootElementName)) return null; if(el.ChildNodes.Count < 2) return null; foreach(XmlNode xmlChild in el.ChildNodes) { if(xmlChild.Name.Equals(MetaElementName)) { } // Ignore Meta else if(xmlChild.Name == KeyElementName) { foreach(XmlNode xmlKeyChild in xmlChild.ChildNodes) { if(xmlKeyChild.Name == KeyDataElementName) { if(pbKeyData == null) pbKeyData = Convert.FromBase64String(xmlKeyChild.InnerText); } } } } } catch(Exception) { pbKeyData = null; } finally { ms.Close(); } return pbKeyData; } private static void CreateXmlKeyFile(string strFile, byte[] pbKeyData) { Debug.Assert(strFile != null); if(strFile == null) throw new ArgumentNullException("strFile"); Debug.Assert(pbKeyData != null); if(pbKeyData == null) throw new ArgumentNullException("pbKeyData"); IOConnectionInfo ioc = IOConnectionInfo.FromPath(strFile); Stream sOut = IOConnection.OpenWrite(ioc); #if KeePassUAP XmlWriterSettings xws = new XmlWriterSettings(); xws.Encoding = StrUtil.Utf8; xws.Indent = false; XmlWriter xtw = XmlWriter.Create(sOut, xws); #else XmlTextWriter xtw = new XmlTextWriter(sOut, StrUtil.Utf8); #endif xtw.WriteStartDocument(); xtw.WriteWhitespace("\r\n"); xtw.WriteStartElement(RootElementName); // KeyFile xtw.WriteWhitespace("\r\n\t"); xtw.WriteStartElement(MetaElementName); // Meta xtw.WriteWhitespace("\r\n\t\t"); xtw.WriteStartElement(VersionElementName); // Version xtw.WriteString("1.00"); xtw.WriteEndElement(); // End Version xtw.WriteWhitespace("\r\n\t"); xtw.WriteEndElement(); // End Meta xtw.WriteWhitespace("\r\n\t"); xtw.WriteStartElement(KeyElementName); // Key xtw.WriteWhitespace("\r\n\t\t"); xtw.WriteStartElement(KeyDataElementName); // Data xtw.WriteString(Convert.ToBase64String(pbKeyData)); xtw.WriteEndElement(); // End Data xtw.WriteWhitespace("\r\n\t"); xtw.WriteEndElement(); // End Key xtw.WriteWhitespace("\r\n"); xtw.WriteEndElement(); // RootElementName xtw.WriteWhitespace("\r\n"); xtw.WriteEndDocument(); // End KeyFile xtw.Close(); sOut.Close(); } } } KeePassLib/Keys/CompositeKey.cs0000664000000000000000000002016413222430400015406 0ustar rootroot/* KeePass Password Safe - The Open-Source Password Manager Copyright (C) 2003-2018 Dominik Reichl This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ using System; using System.Collections.Generic; using System.Diagnostics; using System.Text; using KeePassLib.Cryptography; using KeePassLib.Cryptography.KeyDerivation; using KeePassLib.Native; using KeePassLib.Resources; using KeePassLib.Security; using KeePassLib.Utility; namespace KeePassLib.Keys { /// /// Represents a key. A key can be build up using several user key data sources /// like a password, a key file, the currently logged on user credentials, /// the current computer ID, etc. /// public sealed class CompositeKey { private List m_vUserKeys = new List(); /// /// List of all user keys contained in the current composite key. /// public IEnumerable UserKeys { get { return m_vUserKeys; } } public uint UserKeyCount { get { return (uint)m_vUserKeys.Count; } } /// /// Construct a new, empty key object. /// public CompositeKey() { } // /// // /// Deconstructor, clears up the key. // /// // ~CompositeKey() // { // Clear(); // } // /// // /// Clears the key. This function also erases all previously stored // /// user key data objects. // /// // public void Clear() // { // foreach(IUserKey pKey in m_vUserKeys) // pKey.Clear(); // m_vUserKeys.Clear(); // } /// /// Add a user key. /// /// User key to add. public void AddUserKey(IUserKey pKey) { Debug.Assert(pKey != null); if(pKey == null) throw new ArgumentNullException("pKey"); m_vUserKeys.Add(pKey); } /// /// Remove a user key. /// /// User key to remove. /// Returns true if the key was removed successfully. public bool RemoveUserKey(IUserKey pKey) { Debug.Assert(pKey != null); if(pKey == null) throw new ArgumentNullException("pKey"); Debug.Assert(m_vUserKeys.IndexOf(pKey) >= 0); return m_vUserKeys.Remove(pKey); } /// /// Test whether the composite key contains a specific type of /// user keys (password, key file, ...). If at least one user /// key of that type is present, the function returns true. /// /// User key type. /// Returns true, if the composite key contains /// a user key of the specified type. public bool ContainsType(Type tUserKeyType) { Debug.Assert(tUserKeyType != null); if(tUserKeyType == null) throw new ArgumentNullException("tUserKeyType"); foreach(IUserKey pKey in m_vUserKeys) { if(pKey == null) { Debug.Assert(false); continue; } #if KeePassUAP if(pKey.GetType() == tUserKeyType) return true; #else if(tUserKeyType.IsInstanceOfType(pKey)) return true; #endif } return false; } /// /// Get the first user key of a specified type. /// /// Type of the user key to get. /// Returns the first user key of the specified type /// or null if no key of that type is found. public IUserKey GetUserKey(Type tUserKeyType) { Debug.Assert(tUserKeyType != null); if(tUserKeyType == null) throw new ArgumentNullException("tUserKeyType"); foreach(IUserKey pKey in m_vUserKeys) { if(pKey == null) { Debug.Assert(false); continue; } #if KeePassUAP if(pKey.GetType() == tUserKeyType) return pKey; #else if(tUserKeyType.IsInstanceOfType(pKey)) return pKey; #endif } return null; } /// /// Creates the composite key from the supplied user key sources (password, /// key file, user account, computer ID, etc.). /// private byte[] CreateRawCompositeKey32() { ValidateUserKeys(); // Concatenate user key data List lData = new List(); int cbData = 0; foreach(IUserKey pKey in m_vUserKeys) { ProtectedBinary b = pKey.KeyData; if(b != null) { byte[] pbKeyData = b.ReadData(); lData.Add(pbKeyData); cbData += pbKeyData.Length; } } byte[] pbAllData = new byte[cbData]; int p = 0; foreach(byte[] pbData in lData) { Array.Copy(pbData, 0, pbAllData, p, pbData.Length); p += pbData.Length; MemUtil.ZeroByteArray(pbData); } Debug.Assert(p == cbData); byte[] pbHash = CryptoUtil.HashSha256(pbAllData); MemUtil.ZeroByteArray(pbAllData); return pbHash; } public bool EqualsValue(CompositeKey ckOther) { if(ckOther == null) throw new ArgumentNullException("ckOther"); byte[] pbThis = CreateRawCompositeKey32(); byte[] pbOther = ckOther.CreateRawCompositeKey32(); bool bResult = MemUtil.ArraysEqual(pbThis, pbOther); MemUtil.ZeroByteArray(pbOther); MemUtil.ZeroByteArray(pbThis); return bResult; } [Obsolete] public ProtectedBinary GenerateKey32(byte[] pbKeySeed32, ulong uNumRounds) { Debug.Assert(pbKeySeed32 != null); if(pbKeySeed32 == null) throw new ArgumentNullException("pbKeySeed32"); Debug.Assert(pbKeySeed32.Length == 32); if(pbKeySeed32.Length != 32) throw new ArgumentException("pbKeySeed32"); AesKdf kdf = new AesKdf(); KdfParameters p = kdf.GetDefaultParameters(); p.SetUInt64(AesKdf.ParamRounds, uNumRounds); p.SetByteArray(AesKdf.ParamSeed, pbKeySeed32); return GenerateKey32(p); } /// /// Generate a 32-byte (256-bit) key from the composite key. /// public ProtectedBinary GenerateKey32(KdfParameters p) { if(p == null) { Debug.Assert(false); throw new ArgumentNullException("p"); } byte[] pbRaw32 = CreateRawCompositeKey32(); if((pbRaw32 == null) || (pbRaw32.Length != 32)) { Debug.Assert(false); return null; } KdfEngine kdf = KdfPool.Get(p.KdfUuid); if(kdf == null) // CryptographicExceptions are translated to "file corrupted" throw new Exception(KLRes.UnknownKdf + MessageService.NewParagraph + KLRes.FileNewVerOrPlgReq + MessageService.NewParagraph + "UUID: " + p.KdfUuid.ToHexString() + "."); byte[] pbTrf32 = kdf.Transform(pbRaw32, p); if(pbTrf32 == null) { Debug.Assert(false); return null; } if(pbTrf32.Length != 32) { Debug.Assert(false); pbTrf32 = CryptoUtil.HashSha256(pbTrf32); } ProtectedBinary pbRet = new ProtectedBinary(true, pbTrf32); MemUtil.ZeroByteArray(pbTrf32); MemUtil.ZeroByteArray(pbRaw32); return pbRet; } private void ValidateUserKeys() { int nAccounts = 0; foreach(IUserKey uKey in m_vUserKeys) { if(uKey is KcpUserAccount) ++nAccounts; } if(nAccounts >= 2) { Debug.Assert(false); throw new InvalidOperationException(); } } } public sealed class InvalidCompositeKeyException : Exception { public override string Message { get { return KLRes.InvalidCompositeKey + MessageService.NewParagraph + KLRes.InvalidCompositeKeyHint; } } /// /// Construct a new invalid composite key exception. /// public InvalidCompositeKeyException() { } } } KeePassLib/Translation/0000775000000000000000000000000013222430402014026 5ustar rootrootKeePassLib/Translation/KPStringTableItem.cs0000664000000000000000000000273313222430402017652 0ustar rootroot/* KeePass Password Safe - The Open-Source Password Manager Copyright (C) 2003-2018 Dominik Reichl This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ using System; using System.Collections.Generic; using System.Text; using System.Xml.Serialization; namespace KeePassLib.Translation { public sealed class KPStringTableItem { private string m_strName = string.Empty; public string Name { get { return m_strName; } set { m_strName = value; } } private string m_strValue = string.Empty; public string Value { get { return m_strValue; } set { m_strValue = value; } } private string m_strEnglish = string.Empty; [XmlIgnore] public string ValueEnglish { get { return m_strEnglish; } set { m_strEnglish = value; } } } } KeePassLib/Translation/KPFormCustomization.cs0000664000000000000000000000544513222430402020314 0ustar rootroot/* KeePass Password Safe - The Open-Source Password Manager Copyright (C) 2003-2018 Dominik Reichl This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ using System; using System.Collections.Generic; using System.Diagnostics; using System.Text; using System.Xml.Serialization; #if !KeePassUAP using System.Windows.Forms; #endif namespace KeePassLib.Translation { public sealed class KPFormCustomization { private string m_strFQName = string.Empty; /// /// The fully qualified name of the form. /// [XmlAttribute] public string FullName { get { return m_strFQName; } set { if(value == null) throw new ArgumentNullException("value"); m_strFQName = value; } } private KPControlCustomization m_ccWindow = new KPControlCustomization(); public KPControlCustomization Window { get { return m_ccWindow; } set { m_ccWindow = value; } } private List m_vControls = new List(); [XmlArray("ChildControls")] [XmlArrayItem("Control")] public List Controls { get { return m_vControls; } set { if(value == null) throw new ArgumentNullException("value"); m_vControls = value; } } #if (!KeePassLibSD && !KeePassUAP) private Form m_formEnglish = null; [XmlIgnore] public Form FormEnglish { get { return m_formEnglish; } set { m_formEnglish = value; } } public void ApplyTo(Form form) { Debug.Assert(form != null); if(form == null) throw new ArgumentNullException("form"); // Not supported by TrlUtil (preview form): // Debug.Assert(form.GetType().FullName == m_strFQName); m_ccWindow.ApplyTo(form); if(m_vControls.Count == 0) return; foreach(Control c in form.Controls) ApplyToControl(c); } private void ApplyToControl(Control c) { foreach(KPControlCustomization cc in m_vControls) { if(c.Name == cc.Name) { cc.ApplyTo(c); break; } } foreach(Control cSub in c.Controls) ApplyToControl(cSub); } #endif } } KeePassLib/Translation/KPStringTable.cs0000664000000000000000000000524213222430402017031 0ustar rootroot/* KeePass Password Safe - The Open-Source Password Manager Copyright (C) 2003-2018 Dominik Reichl This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ using System; using System.Collections.Generic; using System.Diagnostics; using System.Text; using System.Xml.Serialization; #if !KeePassUAP using System.Windows.Forms; #endif namespace KeePassLib.Translation { public sealed class KPStringTable { private string m_strName = string.Empty; [XmlAttribute] public string Name { get { return m_strName; } set { if(value == null) throw new ArgumentNullException("value"); m_strName = value; } } private List m_vItems = new List(); [XmlArrayItem("Data")] public List Strings { get { return m_vItems; } set { if(value == null) throw new ArgumentNullException("value"); m_vItems = value; } } public Dictionary ToDictionary() { Dictionary dict = new Dictionary(); foreach(KPStringTableItem kpstItem in m_vItems) { if(kpstItem.Value.Length > 0) dict[kpstItem.Name] = kpstItem.Value; } return dict; } #if (!KeePassLibSD && !KeePassUAP) public void ApplyTo(ToolStripItemCollection tsic) { if(tsic == null) throw new ArgumentNullException("tsic"); Dictionary dict = this.ToDictionary(); if(dict.Count == 0) return; this.ApplyTo(tsic, dict); } private void ApplyTo(ToolStripItemCollection tsic, Dictionary dict) { if(tsic == null) return; foreach(ToolStripItem tsi in tsic) { if(tsi.Text.Length == 0) continue; string strTrl; if(dict.TryGetValue(tsi.Name, out strTrl)) tsi.Text = strTrl; ToolStripMenuItem tsmi = tsi as ToolStripMenuItem; if((tsmi != null) && (tsmi.DropDownItems != null)) this.ApplyTo(tsmi.DropDownItems); } } #endif } } KeePassLib/Translation/KPControlCustomization.cs0000664000000000000000000002542413222430402021030 0ustar rootroot/* KeePass Password Safe - The Open-Source Password Manager Copyright (C) 2003-2018 Dominik Reichl This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ using System; using System.Collections.Generic; using System.ComponentModel; using System.Diagnostics; using System.Globalization; using System.Text; using System.Xml.Serialization; #if !KeePassUAP using System.Drawing; using System.Windows.Forms; #endif using KeePassLib.Cryptography; using KeePassLib.Utility; namespace KeePassLib.Translation { public sealed class KpccLayout { public enum LayoutParameterEx { X, Y, Width, Height } private const string m_strControlRelative = @"%c"; internal const NumberStyles m_nsParser = (NumberStyles.AllowLeadingSign | NumberStyles.AllowDecimalPoint); internal static readonly CultureInfo m_lclInv = CultureInfo.InvariantCulture; private string m_strPosX = string.Empty; [XmlAttribute] [DefaultValue("")] public string X { get { return m_strPosX; } set { if(value == null) throw new ArgumentNullException("value"); m_strPosX = value; } } private string m_strPosY = string.Empty; [XmlAttribute] [DefaultValue("")] public string Y { get { return m_strPosY; } set { if(value == null) throw new ArgumentNullException("value"); m_strPosY = value; } } private string m_strSizeW = string.Empty; [XmlAttribute] [DefaultValue("")] public string Width { get { return m_strSizeW; } set { if(value == null) throw new ArgumentNullException("value"); m_strSizeW = value; } } private string m_strSizeH = string.Empty; [XmlAttribute] [DefaultValue("")] public string Height { get { return m_strSizeH; } set { if(value == null) throw new ArgumentNullException("value"); m_strSizeH = value; } } public void SetControlRelativeValue(LayoutParameterEx lp, string strValue) { Debug.Assert(strValue != null); if(strValue == null) throw new ArgumentNullException("strValue"); if(strValue.Length > 0) strValue += m_strControlRelative; if(lp == LayoutParameterEx.X) m_strPosX = strValue; else if(lp == LayoutParameterEx.Y) m_strPosY = strValue; else if(lp == LayoutParameterEx.Width) m_strSizeW = strValue; else if(lp == LayoutParameterEx.Height) m_strSizeH = strValue; else { Debug.Assert(false); } } #if (!KeePassLibSD && !KeePassUAP) internal void ApplyTo(Control c) { Debug.Assert(c != null); if(c == null) return; int? v; v = GetModControlParameter(c, LayoutParameterEx.X, m_strPosX); if(v.HasValue) c.Left = v.Value; v = GetModControlParameter(c, LayoutParameterEx.Y, m_strPosY); if(v.HasValue) c.Top = v.Value; v = GetModControlParameter(c, LayoutParameterEx.Width, m_strSizeW); if(v.HasValue) c.Width = v.Value; v = GetModControlParameter(c, LayoutParameterEx.Height, m_strSizeH); if(v.HasValue) c.Height = v.Value; } private static int? GetModControlParameter(Control c, LayoutParameterEx p, string strModParam) { if(strModParam.Length == 0) return null; Debug.Assert(c.Left == c.Location.X); Debug.Assert(c.Top == c.Location.Y); Debug.Assert(c.Width == c.Size.Width); Debug.Assert(c.Height == c.Size.Height); int iPrev; if(p == LayoutParameterEx.X) iPrev = c.Left; else if(p == LayoutParameterEx.Y) iPrev = c.Top; else if(p == LayoutParameterEx.Width) iPrev = c.Width; else if(p == LayoutParameterEx.Height) iPrev = c.Height; else { Debug.Assert(false); return null; } double? dRel = ToControlRelativePercent(strModParam); if(dRel.HasValue) return (iPrev + (int)((dRel.Value * (double)iPrev) / 100.0)); Debug.Assert(false); return null; } public static double? ToControlRelativePercent(string strEncoded) { Debug.Assert(strEncoded != null); if(strEncoded == null) throw new ArgumentNullException("strEncoded"); if(strEncoded.Length == 0) return null; if(strEncoded.EndsWith(m_strControlRelative)) { string strValue = strEncoded.Substring(0, strEncoded.Length - m_strControlRelative.Length); if((strValue.Length == 1) && (strValue == "-")) strValue = "0"; double dRel; if(double.TryParse(strValue, m_nsParser, m_lclInv, out dRel)) { return dRel; } else { Debug.Assert(false); return null; } } Debug.Assert(false); return null; } #endif public static string ToControlRelativeString(string strEncoded) { Debug.Assert(strEncoded != null); if(strEncoded == null) throw new ArgumentNullException("strEncoded"); if(strEncoded.Length == 0) return string.Empty; if(strEncoded.EndsWith(m_strControlRelative)) return strEncoded.Substring(0, strEncoded.Length - m_strControlRelative.Length); Debug.Assert(false); return string.Empty; } } public sealed class KPControlCustomization : IComparable { private string m_strMemberName = string.Empty; /// /// Member variable name of the control to be translated. /// [XmlAttribute] public string Name { get { return m_strMemberName; } set { if(value == null) throw new ArgumentNullException("value"); m_strMemberName = value; } } private string m_strHash = string.Empty; [XmlAttribute] public string BaseHash { get { return m_strHash; } set { if(value == null) throw new ArgumentNullException("value"); m_strHash = value; } } private string m_strText = string.Empty; [DefaultValue("")] public string Text { get { return m_strText; } set { if(value == null) throw new ArgumentNullException("value"); m_strText = value; } } private string m_strEngText = string.Empty; [XmlIgnore] public string TextEnglish { get { return m_strEngText; } set { m_strEngText = value; } } private KpccLayout m_layout = new KpccLayout(); public KpccLayout Layout { get { return m_layout; } set { if(value == null) throw new ArgumentNullException("value"); m_layout = value; } } public int CompareTo(KPControlCustomization kpOther) { if(kpOther == null) { Debug.Assert(false); return 1; } return m_strMemberName.CompareTo(kpOther.Name); } #if (!KeePassLibSD && !KeePassUAP) private static readonly Type[] m_vTextControls = new Type[] { typeof(MenuStrip), typeof(PictureBox), typeof(ListView), typeof(TreeView), typeof(ToolStrip), typeof(WebBrowser), typeof(Panel), typeof(StatusStrip), typeof(ProgressBar), typeof(NumericUpDown), typeof(TabControl) }; public static bool ControlSupportsText(object oControl) { if(oControl == null) return false; Type t = oControl.GetType(); for(int i = 0; i < m_vTextControls.Length; ++i) { if(t == m_vTextControls[i]) return false; } return true; } // Name-unchecked (!) property application method internal void ApplyTo(Control c) { if((m_strText.Length > 0) && ControlSupportsText(c) && (c.Text.Length > 0)) { c.Text = m_strText; } m_layout.ApplyTo(c); } public static string HashControl(Control c) { if(c == null) { Debug.Assert(false); return string.Empty; } StringBuilder sb = new StringBuilder(); WriteCpiParam(sb, c.Text); if(c is Form) { WriteCpiParam(sb, c.ClientSize.Width.ToString(KpccLayout.m_lclInv)); WriteCpiParam(sb, c.ClientSize.Height.ToString(KpccLayout.m_lclInv)); } else // Normal control { WriteCpiParam(sb, c.Left.ToString(KpccLayout.m_lclInv)); WriteCpiParam(sb, c.Top.ToString(KpccLayout.m_lclInv)); WriteCpiParam(sb, c.Width.ToString(KpccLayout.m_lclInv)); WriteCpiParam(sb, c.Height.ToString(KpccLayout.m_lclInv)); WriteCpiParam(sb, c.Dock.ToString()); } WriteCpiParam(sb, c.Font.Name); WriteCpiParam(sb, c.Font.SizeInPoints.ToString(KpccLayout.m_lclInv)); WriteCpiParam(sb, c.Font.Bold ? "B" : "N"); WriteCpiParam(sb, c.Font.Italic ? "I" : "N"); WriteCpiParam(sb, c.Font.Underline ? "U" : "N"); WriteCpiParam(sb, c.Font.Strikeout ? "S" : "N"); WriteControlDependentParams(sb, c); byte[] pb = StrUtil.Utf8.GetBytes(sb.ToString()); byte[] pbSha = CryptoUtil.HashSha256(pb); // See also MatchHash return "v1:" + Convert.ToBase64String(pbSha, 0, 3, Base64FormattingOptions.None); } private static void WriteControlDependentParams(StringBuilder sb, Control c) { CheckBox cb = (c as CheckBox); RadioButton rb = (c as RadioButton); Button btn = (c as Button); Label l = (c as Label); LinkLabel ll = (c as LinkLabel); if(cb != null) { WriteCpiParam(sb, cb.AutoSize ? "A" : "F"); WriteCpiParam(sb, cb.TextAlign.ToString()); WriteCpiParam(sb, cb.TextImageRelation.ToString()); WriteCpiParam(sb, cb.Appearance.ToString()); WriteCpiParam(sb, cb.CheckAlign.ToString()); } else if(rb != null) { WriteCpiParam(sb, rb.AutoSize ? "A" : "F"); WriteCpiParam(sb, rb.TextAlign.ToString()); WriteCpiParam(sb, rb.TextImageRelation.ToString()); WriteCpiParam(sb, rb.Appearance.ToString()); WriteCpiParam(sb, rb.CheckAlign.ToString()); } else if(btn != null) { WriteCpiParam(sb, btn.AutoSize ? "A" : "F"); WriteCpiParam(sb, btn.TextAlign.ToString()); WriteCpiParam(sb, btn.TextImageRelation.ToString()); } else if(l != null) { WriteCpiParam(sb, l.AutoSize ? "A" : "F"); WriteCpiParam(sb, l.TextAlign.ToString()); } else if(ll != null) { WriteCpiParam(sb, ll.AutoSize ? "A" : "F"); WriteCpiParam(sb, ll.TextAlign.ToString()); } } private static void WriteCpiParam(StringBuilder sb, string strProp) { sb.Append('/'); sb.Append(strProp); } public bool MatchHash(string strHash) { if(strHash == null) throw new ArgumentNullException("strHash"); // Currently only v1: is supported, see HashControl return (m_strHash == strHash); } #endif } } KeePassLib/Translation/KPTranslation.cs0000664000000000000000000001760513222430402017117 0ustar rootroot/* KeePass Password Safe - The Open-Source Password Manager Copyright (C) 2003-2018 Dominik Reichl This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ using System; using System.Collections.Generic; using System.ComponentModel; using System.Diagnostics; using System.IO; using System.Text; using System.Xml; using System.Xml.Serialization; #if !KeePassUAP using System.Drawing; using System.Windows.Forms; #endif #if KeePassLibSD using ICSharpCode.SharpZipLib.GZip; #else using System.IO.Compression; #endif using KeePassLib.Interfaces; using KeePassLib.Utility; namespace KeePassLib.Translation { [XmlRoot("Translation")] public sealed class KPTranslation { public const string FileExtension = "lngx"; private KPTranslationProperties m_props = new KPTranslationProperties(); public KPTranslationProperties Properties { get { return m_props; } set { m_props = value; } } private List m_vStringTables = new List(); [XmlArrayItem("StringTable")] public List StringTables { get { return m_vStringTables; } set { if(value == null) throw new ArgumentNullException("value"); m_vStringTables = value; } } private List m_vForms = new List(); [XmlArrayItem("Form")] public List Forms { get { return m_vForms; } set { if(value == null) throw new ArgumentNullException("value"); m_vForms = value; } } private string m_strUnusedText = string.Empty; [DefaultValue("")] public string UnusedText { get { return m_strUnusedText; } set { if(value == null) throw new ArgumentNullException("value"); m_strUnusedText = value; } } public static void Save(KPTranslation kpTrl, string strFileName, IXmlSerializerEx xs) { using(FileStream fs = new FileStream(strFileName, FileMode.Create, FileAccess.Write, FileShare.None)) { Save(kpTrl, fs, xs); } } public static void Save(KPTranslation kpTrl, Stream sOut, IXmlSerializerEx xs) { if(xs == null) throw new ArgumentNullException("xs"); #if !KeePassLibSD GZipStream gz = new GZipStream(sOut, CompressionMode.Compress); #else GZipOutputStream gz = new GZipOutputStream(sOut); #endif XmlWriterSettings xws = new XmlWriterSettings(); xws.CheckCharacters = true; xws.Encoding = StrUtil.Utf8; xws.Indent = true; xws.IndentChars = "\t"; XmlWriter xw = XmlWriter.Create(gz, xws); xs.Serialize(xw, kpTrl); xw.Close(); gz.Close(); sOut.Close(); } public static KPTranslation Load(string strFile, IXmlSerializerEx xs) { KPTranslation kpTrl = null; using(FileStream fs = new FileStream(strFile, FileMode.Open, FileAccess.Read, FileShare.Read)) { kpTrl = Load(fs, xs); } return kpTrl; } public static KPTranslation Load(Stream s, IXmlSerializerEx xs) { if(xs == null) throw new ArgumentNullException("xs"); #if !KeePassLibSD GZipStream gz = new GZipStream(s, CompressionMode.Decompress); #else GZipInputStream gz = new GZipInputStream(s); #endif KPTranslation kpTrl = (xs.Deserialize(gz) as KPTranslation); gz.Close(); s.Close(); return kpTrl; } public Dictionary SafeGetStringTableDictionary( string strTableName) { foreach(KPStringTable kpst in m_vStringTables) { if(kpst.Name == strTableName) return kpst.ToDictionary(); } return new Dictionary(); } #if (!KeePassLibSD && !KeePassUAP) public void ApplyTo(Form form) { if(form == null) throw new ArgumentNullException("form"); if(m_props.RightToLeft) { try { form.RightToLeft = RightToLeft.Yes; form.RightToLeftLayout = true; } catch(Exception) { Debug.Assert(false); } } string strTypeName = form.GetType().FullName; foreach(KPFormCustomization kpfc in m_vForms) { if(kpfc.FullName == strTypeName) { kpfc.ApplyTo(form); break; } } if(m_props.RightToLeft) { try { RtlApplyToControls(form.Controls); } catch(Exception) { Debug.Assert(false); } } } private static void RtlApplyToControls(Control.ControlCollection cc) { foreach(Control c in cc) { if(c.Controls.Count > 0) RtlApplyToControls(c.Controls); if(c is DateTimePicker) ((DateTimePicker)c).RightToLeftLayout = true; else if(c is ListView) ((ListView)c).RightToLeftLayout = true; else if(c is MonthCalendar) ((MonthCalendar)c).RightToLeftLayout = true; else if(c is ProgressBar) ((ProgressBar)c).RightToLeftLayout = true; else if(c is TabControl) ((TabControl)c).RightToLeftLayout = true; else if(c is TrackBar) ((TrackBar)c).RightToLeftLayout = true; else if(c is TreeView) ((TreeView)c).RightToLeftLayout = true; // else if(c is ToolStrip) // RtlApplyToToolStripItems(((ToolStrip)c).Items); /* else if(c is Button) // Also see Label { Button btn = (c as Button); Image img = btn.Image; if(img != null) { Image imgNew = (Image)img.Clone(); imgNew.RotateFlip(RotateFlipType.RotateNoneFlipX); btn.Image = imgNew; } } else if(c is Label) // Also see Button { Label lbl = (c as Label); Image img = lbl.Image; if(img != null) { Image imgNew = (Image)img.Clone(); imgNew.RotateFlip(RotateFlipType.RotateNoneFlipX); lbl.Image = imgNew; } } */ if(IsRtlMoveChildsRequired(c)) RtlMoveChildControls(c); } } internal static bool IsRtlMoveChildsRequired(Control c) { if(c == null) { Debug.Assert(false); return false; } return ((c is GroupBox) || (c is Panel)); } private static void RtlMoveChildControls(Control cParent) { int nParentWidth = cParent.Size.Width; foreach(Control c in cParent.Controls) { DockStyle ds = c.Dock; if(ds == DockStyle.Left) c.Dock = DockStyle.Right; else if(ds == DockStyle.Right) c.Dock = DockStyle.Left; else { Point ptCur = c.Location; c.Location = new Point(nParentWidth - c.Size.Width - ptCur.X, ptCur.Y); } } } /* private static readonly string[] g_vRtlMirrorItemNames = new string[] { }; private static void RtlApplyToToolStripItems(ToolStripItemCollection tsic) { foreach(ToolStripItem tsi in tsic) { if(tsi == null) { Debug.Assert(false); continue; } if(Array.IndexOf(g_vRtlMirrorItemNames, tsi.Name) >= 0) tsi.RightToLeftAutoMirrorImage = true; ToolStripDropDownItem tsdd = (tsi as ToolStripDropDownItem); if(tsdd != null) RtlApplyToToolStripItems(tsdd.DropDownItems); } } */ public void ApplyTo(string strTableName, ToolStripItemCollection tsic) { if(tsic == null) throw new ArgumentNullException("tsic"); KPStringTable kpst = null; foreach(KPStringTable kpstEnum in m_vStringTables) { if(kpstEnum.Name == strTableName) { kpst = kpstEnum; break; } } if(kpst != null) kpst.ApplyTo(tsic); } #endif } } KeePassLib/Translation/KPTranslationProperties.cs0000664000000000000000000000527513222430402021174 0ustar rootroot/* KeePass Password Safe - The Open-Source Password Manager Copyright (C) 2003-2018 Dominik Reichl This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ using System; using System.Collections.Generic; using System.Text; namespace KeePassLib.Translation { public sealed class KPTranslationProperties { private string m_strApp = string.Empty; public string Application { get { return m_strApp; } set { m_strApp = value; } } private string m_strForVersion = string.Empty; public string ApplicationVersion { get { return m_strForVersion; } set { m_strForVersion = value; } } private string m_strNameEnglish = string.Empty; public string NameEnglish { get { return m_strNameEnglish; } set { m_strNameEnglish = value; } } private string m_strNameNative = string.Empty; public string NameNative { get { return m_strNameNative; } set { m_strNameNative = value; } } private string m_strIso6391Code = string.Empty; public string Iso6391Code { get { return m_strIso6391Code; } set { m_strIso6391Code = value; } } private bool m_bRtl = false; public bool RightToLeft { get { return m_bRtl; } set { m_bRtl = value; } } private string m_strAuthorName = string.Empty; public string AuthorName { get { return m_strAuthorName; } set { m_strAuthorName = value; } } private string m_strAuthorContact = string.Empty; public string AuthorContact { get { return m_strAuthorContact; } set { m_strAuthorContact = value; } } private string m_strGen = string.Empty; public string Generator { get { return m_strGen; } set { m_strGen = value; } } private string m_strUuid = string.Empty; public string FileUuid { get { return m_strUuid; } set { m_strUuid = value; } } private string m_strLastModified = string.Empty; public string LastModified { get { return m_strLastModified; } set { m_strLastModified = value; } } } } KeePassLib/PwUuid.cs0000664000000000000000000001272613222430402013304 0ustar rootroot/* KeePass Password Safe - The Open-Source Password Manager Copyright (C) 2003-2018 Dominik Reichl This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ using System; using System.Collections.Generic; using System.Xml; using System.Diagnostics; using KeePassLib.Utility; namespace KeePassLib { // [ImmutableObject(true)] /// /// Represents an UUID of a password entry or group. Once created, /// PwUuid objects aren't modifyable anymore (immutable). /// public sealed class PwUuid : IComparable, IEquatable { /// /// Standard size in bytes of a UUID. /// public const uint UuidSize = 16; /// /// Zero UUID (all bytes are zero). /// public static readonly PwUuid Zero = new PwUuid(false); private byte[] m_pbUuid = null; // Never null after constructor /// /// Get the 16 UUID bytes. /// public byte[] UuidBytes { get { return m_pbUuid; } } /// /// Construct a new UUID object. /// /// If this parameter is true, a new /// UUID is generated. If it is false, the UUID is initialized /// to zero. public PwUuid(bool bCreateNew) { if(bCreateNew) CreateNew(); else SetZero(); } /// /// Construct a new UUID object. /// /// Initial value of the PwUuid object. public PwUuid(byte[] uuidBytes) { SetValue(uuidBytes); } /// /// Create a new, random UUID. /// /// Returns true if a random UUID has been generated, /// otherwise it returns false. private void CreateNew() { Debug.Assert(m_pbUuid == null); // Only call from constructor while(true) { m_pbUuid = Guid.NewGuid().ToByteArray(); if((m_pbUuid == null) || (m_pbUuid.Length != (int)UuidSize)) { Debug.Assert(false); throw new InvalidOperationException(); } // Zero is a reserved value -- do not generate Zero if(!Equals(PwUuid.Zero)) break; Debug.Assert(false); } } private void SetValue(byte[] uuidBytes) { Debug.Assert((uuidBytes != null) && (uuidBytes.Length == (int)UuidSize)); if(uuidBytes == null) throw new ArgumentNullException("uuidBytes"); if(uuidBytes.Length != (int)UuidSize) throw new ArgumentException(); Debug.Assert(m_pbUuid == null); // Only call from constructor m_pbUuid = new byte[UuidSize]; Array.Copy(uuidBytes, m_pbUuid, (int)UuidSize); } private void SetZero() { Debug.Assert(m_pbUuid == null); // Only call from constructor m_pbUuid = new byte[UuidSize]; // Array.Clear(m_pbUuid, 0, (int)UuidSize); #if DEBUG List l = new List(m_pbUuid); Debug.Assert(l.TrueForAll(bt => (bt == 0))); #endif } [Obsolete] public bool EqualsValue(PwUuid uuid) { return Equals(uuid); } public override bool Equals(object obj) { return Equals(obj as PwUuid); } public bool Equals(PwUuid other) { if(other == null) { Debug.Assert(false); return false; } for(int i = 0; i < (int)UuidSize; ++i) { if(m_pbUuid[i] != other.m_pbUuid[i]) return false; } return true; } private int m_h = 0; public override int GetHashCode() { if(m_h == 0) m_h = (int)MemUtil.Hash32(m_pbUuid, 0, m_pbUuid.Length); return m_h; } public int CompareTo(PwUuid other) { if(other == null) { Debug.Assert(false); throw new ArgumentNullException("other"); } for(int i = 0; i < (int)UuidSize; ++i) { if(m_pbUuid[i] < other.m_pbUuid[i]) return -1; if(m_pbUuid[i] > other.m_pbUuid[i]) return 1; } return 0; } /// /// Convert the UUID to its string representation. /// /// String containing the UUID value. public string ToHexString() { return MemUtil.ByteArrayToHexString(m_pbUuid); } #if DEBUG public override string ToString() { return ToHexString(); } #endif } [Obsolete] public sealed class PwUuidComparable : IComparable { private byte[] m_pbUuid = new byte[PwUuid.UuidSize]; public PwUuidComparable(PwUuid pwUuid) { if(pwUuid == null) throw new ArgumentNullException("pwUuid"); Array.Copy(pwUuid.UuidBytes, m_pbUuid, (int)PwUuid.UuidSize); } public int CompareTo(PwUuidComparable other) { if(other == null) throw new ArgumentNullException("other"); for(int i = 0; i < (int)PwUuid.UuidSize; ++i) { if(m_pbUuid[i] < other.m_pbUuid[i]) return -1; if(m_pbUuid[i] > other.m_pbUuid[i]) return 1; } return 0; } } } KeePassLib/PwDefs.cs0000664000000000000000000003423013225116756013271 0ustar rootroot/* KeePass Password Safe - The Open-Source Password Manager Copyright (C) 2003-2018 Dominik Reichl This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ using System; using System.Collections.Generic; using System.ComponentModel; using System.Diagnostics; using System.Xml.Serialization; using KeePassLib.Delegates; using KeePassLib.Interfaces; using KeePassLib.Serialization; namespace KeePassLib { /// /// Contains KeePassLib-global definitions and enums. /// public static class PwDefs { /// /// The product name. /// public const string ProductName = "KeePass Password Safe"; /// /// A short, simple string representing the product name. The string /// should contain no spaces, directory separator characters, etc. /// public const string ShortProductName = "KeePass"; internal const string UnixName = "keepass2"; internal const string ResClass = "KeePass2"; // With initial capital /// /// Version, encoded as 32-bit unsigned integer. /// 2.00 = 0x02000000, 2.01 = 0x02000100, ..., 2.18 = 0x02010800. /// As of 2.19, the version is encoded component-wise per byte, /// e.g. 2.19 = 0x02130000. /// It is highly recommended to use FileVersion64 instead. /// public const uint Version32 = 0x02260000; /// /// Version, encoded as 64-bit unsigned integer /// (component-wise, 16 bits per component). /// public const ulong FileVersion64 = 0x0002002600000000UL; /// /// Version, encoded as string. /// public const string VersionString = "2.38"; public const string Copyright = @"Copyright © 2003-2018 Dominik Reichl"; /// /// Product website URL. Terminated by a forward slash. /// public const string HomepageUrl = "https://keepass.info/"; /// /// URL to the online translations page. /// public const string TranslationsUrl = "https://keepass.info/translations.html"; /// /// URL to the online plugins page. /// public const string PluginsUrl = "https://keepass.info/plugins.html"; /// /// Product donations URL. /// public const string DonationsUrl = "https://keepass.info/donate.html"; /// /// URL to the root path of the online KeePass help. Terminated by /// a forward slash. /// public const string HelpUrl = "https://keepass.info/help/"; /// /// URL to a TXT file (eventually compressed) that contains information /// about the latest KeePass version available on the website. /// public const string VersionUrl = "https://www.dominik-reichl.de/update/version2x.txt.gz"; /// /// A DateTime object that represents the time when the assembly /// was loaded. /// public static readonly DateTime DtDefaultNow = DateTime.UtcNow; /// /// Default number of master key encryption/transformation rounds /// (making dictionary attacks harder). /// public const ulong DefaultKeyEncryptionRounds = 60000; /// /// Default identifier string for the title field. Should not contain /// spaces, tabs or other whitespace. /// public const string TitleField = "Title"; /// /// Default identifier string for the user name field. Should not contain /// spaces, tabs or other whitespace. /// public const string UserNameField = "UserName"; /// /// Default identifier string for the password field. Should not contain /// spaces, tabs or other whitespace. /// public const string PasswordField = "Password"; /// /// Default identifier string for the URL field. Should not contain /// spaces, tabs or other whitespace. /// public const string UrlField = "URL"; /// /// Default identifier string for the notes field. Should not contain /// spaces, tabs or other whitespace. /// public const string NotesField = "Notes"; /// /// Default identifier string for the field which will contain TAN indices. /// public const string TanIndexField = UserNameField; /// /// Default title of an entry that is really a TAN entry. /// public const string TanTitle = @""; /// /// Prefix of a custom auto-type string field. /// public const string AutoTypeStringPrefix = "S:"; /// /// Default string representing a hidden password. /// public const string HiddenPassword = "********"; /// /// Default auto-type keystroke sequence. If no custom sequence is /// specified, this sequence is used. /// public const string DefaultAutoTypeSequence = @"{USERNAME}{TAB}{PASSWORD}{ENTER}"; /// /// Default auto-type keystroke sequence for TAN entries. If no custom /// sequence is specified, this sequence is used. /// public const string DefaultAutoTypeSequenceTan = @"{PASSWORD}"; /// /// Check if a name is a standard field name. /// /// Input field name. /// Returns true, if the field name is a standard /// field name (title, user name, password, ...), otherwise false. public static bool IsStandardField(string strFieldName) { Debug.Assert(strFieldName != null); if(strFieldName == null) return false; if(strFieldName.Equals(TitleField)) return true; if(strFieldName.Equals(UserNameField)) return true; if(strFieldName.Equals(PasswordField)) return true; if(strFieldName.Equals(UrlField)) return true; if(strFieldName.Equals(NotesField)) return true; return false; } public static List GetStandardFields() { List l = new List(); l.Add(TitleField); l.Add(UserNameField); l.Add(PasswordField); l.Add(UrlField); l.Add(NotesField); return l; } /// /// Check if an entry is a TAN. /// /// Password entry. /// Returns true if the entry is a TAN. public static bool IsTanEntry(PwEntry pe) { Debug.Assert(pe != null); if(pe == null) return false; return (pe.Strings.ReadSafe(PwDefs.TitleField) == TanTitle); } } // #pragma warning disable 1591 // Missing XML comments warning /// /// Search parameters for group and entry searches. /// public sealed class SearchParameters { private string m_strText = string.Empty; [DefaultValue("")] public string SearchString { get { return m_strText; } set { if(value == null) throw new ArgumentNullException("value"); m_strText = value; } } private bool m_bRegex = false; [DefaultValue(false)] public bool RegularExpression { get { return m_bRegex; } set { m_bRegex = value; } } private bool m_bSearchInTitles = true; [DefaultValue(true)] public bool SearchInTitles { get { return m_bSearchInTitles; } set { m_bSearchInTitles = value; } } private bool m_bSearchInUserNames = true; [DefaultValue(true)] public bool SearchInUserNames { get { return m_bSearchInUserNames; } set { m_bSearchInUserNames = value; } } private bool m_bSearchInPasswords = false; [DefaultValue(false)] public bool SearchInPasswords { get { return m_bSearchInPasswords; } set { m_bSearchInPasswords = value; } } private bool m_bSearchInUrls = true; [DefaultValue(true)] public bool SearchInUrls { get { return m_bSearchInUrls; } set { m_bSearchInUrls = value; } } private bool m_bSearchInNotes = true; [DefaultValue(true)] public bool SearchInNotes { get { return m_bSearchInNotes; } set { m_bSearchInNotes = value; } } private bool m_bSearchInOther = true; [DefaultValue(true)] public bool SearchInOther { get { return m_bSearchInOther; } set { m_bSearchInOther = value; } } private bool m_bSearchInStringNames = false; [DefaultValue(false)] public bool SearchInStringNames { get { return m_bSearchInStringNames; } set { m_bSearchInStringNames = value; } } private bool m_bSearchInTags = true; [DefaultValue(true)] public bool SearchInTags { get { return m_bSearchInTags; } set { m_bSearchInTags = value; } } private bool m_bSearchInUuids = false; [DefaultValue(false)] public bool SearchInUuids { get { return m_bSearchInUuids; } set { m_bSearchInUuids = value; } } private bool m_bSearchInGroupNames = false; [DefaultValue(false)] public bool SearchInGroupNames { get { return m_bSearchInGroupNames; } set { m_bSearchInGroupNames = value; } } #if KeePassUAP private StringComparison m_scType = StringComparison.OrdinalIgnoreCase; #else private StringComparison m_scType = StringComparison.InvariantCultureIgnoreCase; #endif /// /// String comparison type. Specifies the condition when the specified /// text matches a group/entry string. /// public StringComparison ComparisonMode { get { return m_scType; } set { m_scType = value; } } private bool m_bExcludeExpired = false; [DefaultValue(false)] public bool ExcludeExpired { get { return m_bExcludeExpired; } set { m_bExcludeExpired = value; } } private bool m_bRespectEntrySearchingDisabled = true; [DefaultValue(true)] public bool RespectEntrySearchingDisabled { get { return m_bRespectEntrySearchingDisabled; } set { m_bRespectEntrySearchingDisabled = value; } } private StrPwEntryDelegate m_fnDataTrf = null; [XmlIgnore] public StrPwEntryDelegate DataTransformationFn { get { return m_fnDataTrf; } set { m_fnDataTrf = value; } } private string m_strDataTrf = string.Empty; /// /// Only for serialization. /// [DefaultValue("")] public string DataTransformation { get { return m_strDataTrf; } set { if(value == null) throw new ArgumentNullException("value"); m_strDataTrf = value; } } [XmlIgnore] public static SearchParameters None { get { SearchParameters sp = new SearchParameters(); Debug.Assert(sp.m_strText.Length == 0); Debug.Assert(!sp.m_bRegex); sp.m_bSearchInTitles = false; sp.m_bSearchInUserNames = false; Debug.Assert(!sp.m_bSearchInPasswords); sp.m_bSearchInUrls = false; sp.m_bSearchInNotes = false; sp.m_bSearchInOther = false; Debug.Assert(!sp.m_bSearchInStringNames); sp.m_bSearchInTags = false; Debug.Assert(!sp.m_bSearchInUuids); Debug.Assert(!sp.m_bSearchInGroupNames); // Debug.Assert(sp.m_scType == StringComparison.InvariantCultureIgnoreCase); Debug.Assert(!sp.m_bExcludeExpired); Debug.Assert(sp.m_bRespectEntrySearchingDisabled); return sp; } } /// /// Construct a new search parameters object. /// public SearchParameters() { } public SearchParameters Clone() { return (SearchParameters)this.MemberwiseClone(); } } // #pragma warning restore 1591 // Missing XML comments warning // #pragma warning disable 1591 // Missing XML comments warning /// /// Memory protection configuration structure (for default fields). /// public sealed class MemoryProtectionConfig : IDeepCloneable { public bool ProtectTitle = false; public bool ProtectUserName = false; public bool ProtectPassword = true; public bool ProtectUrl = false; public bool ProtectNotes = false; // public bool AutoEnableVisualHiding = false; public MemoryProtectionConfig CloneDeep() { return (MemoryProtectionConfig)this.MemberwiseClone(); } public bool GetProtection(string strField) { if(strField == PwDefs.TitleField) return this.ProtectTitle; if(strField == PwDefs.UserNameField) return this.ProtectUserName; if(strField == PwDefs.PasswordField) return this.ProtectPassword; if(strField == PwDefs.UrlField) return this.ProtectUrl; if(strField == PwDefs.NotesField) return this.ProtectNotes; return false; } } // #pragma warning restore 1591 // Missing XML comments warning public sealed class ObjectTouchedEventArgs : EventArgs { private object m_o; public object Object { get { return m_o; } } private bool m_bModified; public bool Modified { get { return m_bModified; } } private bool m_bParentsTouched; public bool ParentsTouched { get { return m_bParentsTouched; } } public ObjectTouchedEventArgs(object o, bool bModified, bool bParentsTouched) { m_o = o; m_bModified = bModified; m_bParentsTouched = bParentsTouched; } } public sealed class IOAccessEventArgs : EventArgs { private IOConnectionInfo m_ioc; public IOConnectionInfo IOConnectionInfo { get { return m_ioc; } } private IOConnectionInfo m_ioc2; public IOConnectionInfo IOConnectionInfo2 { get { return m_ioc2; } } private IOAccessType m_t; public IOAccessType Type { get { return m_t; } } public IOAccessEventArgs(IOConnectionInfo ioc, IOConnectionInfo ioc2, IOAccessType t) { m_ioc = ioc; m_ioc2 = ioc2; m_t = t; } } } KeePassLib/Interfaces/0000775000000000000000000000000013222430400013611 5ustar rootrootKeePassLib/Interfaces/IStatusLogger.cs0000664000000000000000000000642713222430400016705 0ustar rootroot/* KeePass Password Safe - The Open-Source Password Manager Copyright (C) 2003-2018 Dominik Reichl This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ using System; using System.Collections.Generic; namespace KeePassLib.Interfaces { /// /// Status message types. /// public enum LogStatusType { /// /// Default type: simple information type. /// Info = 0, /// /// Warning message. /// Warning, /// /// Error message. /// Error, /// /// Additional information. Depends on lines above. /// AdditionalInfo } /// /// Status logging interface. /// public interface IStatusLogger { /// /// Function which needs to be called when logging is started. /// /// This string should roughly describe /// the operation, of which the status is logged. /// Specifies whether the /// operation is written to the log or not. void StartLogging(string strOperation, bool bWriteOperationToLog); /// /// Function which needs to be called when logging is ended /// (i.e. when no more messages will be logged and when the /// percent value won't change any more). /// void EndLogging(); /// /// Set the current progress in percent. /// /// Percent of work finished. /// Returns true if the caller should continue /// the current work. bool SetProgress(uint uPercent); /// /// Set the current status text. /// /// Status text. /// Type of the message. /// Returns true if the caller should continue /// the current work. bool SetText(string strNewText, LogStatusType lsType); /// /// Check if the user cancelled the current work. /// /// Returns true if the caller should continue /// the current work. bool ContinueWork(); } public sealed class NullStatusLogger : IStatusLogger { public void StartLogging(string strOperation, bool bWriteOperationToLog) { } public void EndLogging() { } public bool SetProgress(uint uPercent) { return true; } public bool SetText(string strNewText, LogStatusType lsType) { return true; } public bool ContinueWork() { return true; } } } KeePassLib/Interfaces/IUIOperations.cs0000664000000000000000000000253613222430400016640 0ustar rootroot/* KeePass Password Safe - The Open-Source Password Manager Copyright (C) 2003-2018 Dominik Reichl This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ using System; using System.Collections.Generic; using System.Text; namespace KeePassLib.Interfaces { public interface IUIOperations { /// /// Let the user interface save the current database. /// /// If true, the UI will not ask for /// whether to synchronize or overwrite, it'll simply overwrite the /// file. /// Returns true if the file has been saved. bool UIFileSave(bool bForceSave); } } KeePassLib/Interfaces/IDeepCloneable.cs0000664000000000000000000000237313222430400016740 0ustar rootroot/* KeePass Password Safe - The Open-Source Password Manager Copyright (C) 2003-2018 Dominik Reichl This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ using System; using System.Collections.Generic; namespace KeePassLib.Interfaces { /// /// Interface for objects that are deeply cloneable. /// /// Reference type. public interface IDeepCloneable where T : class { /// /// Deeply clone the object. /// /// Cloned object. T CloneDeep(); } } KeePassLib/Interfaces/IXmlSerializerEx.cs0000664000000000000000000000215513222430400017343 0ustar rootroot/* KeePass Password Safe - The Open-Source Password Manager Copyright (C) 2003-2018 Dominik Reichl This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ using System; using System.Collections.Generic; using System.Text; using System.IO; using System.Xml; namespace KeePassLib.Interfaces { public interface IXmlSerializerEx { void Serialize(XmlWriter xmlWriter, object o); object Deserialize(Stream s); } } KeePassLib/Interfaces/IStructureItem.cs0000664000000000000000000000207513222430400017074 0ustar rootroot/* KeePass Password Safe - The Open-Source Password Manager Copyright (C) 2003-2018 Dominik Reichl This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ using System; namespace KeePassLib.Interfaces { public interface IStructureItem : ITimeLogger // Provides LocationChanged { PwUuid Uuid { get; set; } PwGroup ParentGroup { get; } } } KeePassLib/Interfaces/ITimeLogger.cs0000664000000000000000000000525113222430400016312 0ustar rootroot/* KeePass Password Safe - The Open-Source Password Manager Copyright (C) 2003-2018 Dominik Reichl This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ using System; namespace KeePassLib.Interfaces { /// /// Interface for objects that support various times (creation time, last /// access time, last modification time and expiry time). Offers /// several helper functions (for example a function to touch the current /// object). /// public interface ITimeLogger { /// /// The date/time when the object was created. /// DateTime CreationTime { get; set; } /// /// The date/time when the object was last modified. /// DateTime LastModificationTime { get; set; } /// /// The date/time when the object was last accessed. /// DateTime LastAccessTime { get; set; } /// /// The date/time when the object expires. /// DateTime ExpiryTime { get; set; } /// /// Flag that determines if the object does expire. /// bool Expires { get; set; } /// /// Get or set the usage count of the object. To increase the usage /// count by one, use the Touch function. /// ulong UsageCount { get; set; } /// /// The date/time when the location of the object was last changed. /// DateTime LocationChanged { get; set; } /// /// Touch the object. This function updates the internal last access /// time. If the parameter is true, /// the last modification time gets updated, too. Each time you call /// Touch, the usage count of the object is increased by one. /// /// Update last modification time. void Touch(bool bModified); } } KeePassLib/PwDatabase.cs0000664000000000000000000016411213222430400014075 0ustar rootroot/* KeePass Password Safe - The Open-Source Password Manager Copyright (C) 2003-2018 Dominik Reichl This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ using System; using System.Collections.Generic; using System.Diagnostics; using System.IO; #if !KeePassUAP using System.Drawing; #endif using KeePassLib.Collections; using KeePassLib.Cryptography; using KeePassLib.Cryptography.Cipher; using KeePassLib.Cryptography.KeyDerivation; using KeePassLib.Delegates; using KeePassLib.Interfaces; using KeePassLib.Keys; using KeePassLib.Resources; using KeePassLib.Security; using KeePassLib.Serialization; using KeePassLib.Utility; namespace KeePassLib { /// /// The core password manager class. It contains a number of groups, which /// contain the actual entries. /// public sealed class PwDatabase { internal const int DefaultHistoryMaxItems = 10; // -1 = unlimited internal const long DefaultHistoryMaxSize = 6 * 1024 * 1024; // -1 = unlimited private static bool m_bPrimaryCreated = false; // Initializations: see Clear() private PwGroup m_pgRootGroup = null; private PwObjectList m_vDeletedObjects = new PwObjectList(); private PwUuid m_uuidDataCipher = StandardAesEngine.AesUuid; private PwCompressionAlgorithm m_caCompression = PwCompressionAlgorithm.GZip; // private ulong m_uKeyEncryptionRounds = PwDefs.DefaultKeyEncryptionRounds; private KdfParameters m_kdfParams = KdfPool.GetDefaultParameters(); private CompositeKey m_pwUserKey = null; private MemoryProtectionConfig m_memProtConfig = new MemoryProtectionConfig(); private List m_vCustomIcons = new List(); private bool m_bUINeedsIconUpdate = true; private DateTime m_dtSettingsChanged = PwDefs.DtDefaultNow; private string m_strName = string.Empty; private DateTime m_dtNameChanged = PwDefs.DtDefaultNow; private string m_strDesc = string.Empty; private DateTime m_dtDescChanged = PwDefs.DtDefaultNow; private string m_strDefaultUserName = string.Empty; private DateTime m_dtDefaultUserChanged = PwDefs.DtDefaultNow; private uint m_uMntncHistoryDays = 365; private Color m_clr = Color.Empty; private DateTime m_dtKeyLastChanged = PwDefs.DtDefaultNow; private long m_lKeyChangeRecDays = -1; private long m_lKeyChangeForceDays = -1; private bool m_bKeyChangeForceOnce = false; private IOConnectionInfo m_ioSource = new IOConnectionInfo(); private bool m_bDatabaseOpened = false; private bool m_bModified = false; private PwUuid m_pwLastSelectedGroup = PwUuid.Zero; private PwUuid m_pwLastTopVisibleGroup = PwUuid.Zero; private bool m_bUseRecycleBin = true; private PwUuid m_pwRecycleBin = PwUuid.Zero; private DateTime m_dtRecycleBinChanged = PwDefs.DtDefaultNow; private PwUuid m_pwEntryTemplatesGroup = PwUuid.Zero; private DateTime m_dtEntryTemplatesChanged = PwDefs.DtDefaultNow; private int m_nHistoryMaxItems = DefaultHistoryMaxItems; private long m_lHistoryMaxSize = DefaultHistoryMaxSize; // In bytes private StringDictionaryEx m_dCustomData = new StringDictionaryEx(); private VariantDictionary m_dPublicCustomData = new VariantDictionary(); private byte[] m_pbHashOfFileOnDisk = null; private byte[] m_pbHashOfLastIO = null; private bool m_bUseFileTransactions = false; private bool m_bUseFileLocks = false; private IStatusLogger m_slStatus = null; private static string m_strLocalizedAppName = string.Empty; // private const string StrBackupExtension = ".bak"; /// /// Get the root group that contains all groups and entries stored in the /// database. /// /// Root group. The return value is null, if no database /// has been opened. public PwGroup RootGroup { get { return m_pgRootGroup; } set { Debug.Assert(value != null); if(value == null) throw new ArgumentNullException("value"); m_pgRootGroup = value; } } /// /// IOConnection of the currently opened database file. /// Is never null. /// public IOConnectionInfo IOConnectionInfo { get { return m_ioSource; } } /// /// If this is true, a database is currently open. /// public bool IsOpen { get { return m_bDatabaseOpened; } } /// /// Modification flag. If true, the class has been modified and the /// user interface should prompt the user to save the changes before /// closing the database for example. /// public bool Modified { get { return m_bModified; } set { m_bModified = value; } } /// /// The user key used for database encryption. This key must be created /// and set before using any of the database load/save functions. /// public CompositeKey MasterKey { get { return m_pwUserKey; } set { Debug.Assert(value != null); if(value == null) throw new ArgumentNullException("value"); m_pwUserKey = value; } } public DateTime SettingsChanged { get { return m_dtSettingsChanged; } set { m_dtSettingsChanged = value; } } /// /// Name of the database. /// public string Name { get { return m_strName; } set { Debug.Assert(value != null); if(value != null) m_strName = value; } } public DateTime NameChanged { get { return m_dtNameChanged; } set { m_dtNameChanged = value; } } /// /// Database description. /// public string Description { get { return m_strDesc; } set { Debug.Assert(value != null); if(value != null) m_strDesc = value; } } public DateTime DescriptionChanged { get { return m_dtDescChanged; } set { m_dtDescChanged = value; } } /// /// Default user name used for new entries. /// public string DefaultUserName { get { return m_strDefaultUserName; } set { Debug.Assert(value != null); if(value != null) m_strDefaultUserName = value; } } public DateTime DefaultUserNameChanged { get { return m_dtDefaultUserChanged; } set { m_dtDefaultUserChanged = value; } } /// /// Number of days until history entries are being deleted /// in a database maintenance operation. /// public uint MaintenanceHistoryDays { get { return m_uMntncHistoryDays; } set { m_uMntncHistoryDays = value; } } public Color Color { get { return m_clr; } set { m_clr = value; } } public DateTime MasterKeyChanged { get { return m_dtKeyLastChanged; } set { m_dtKeyLastChanged = value; } } public long MasterKeyChangeRec { get { return m_lKeyChangeRecDays; } set { m_lKeyChangeRecDays = value; } } public long MasterKeyChangeForce { get { return m_lKeyChangeForceDays; } set { m_lKeyChangeForceDays = value; } } public bool MasterKeyChangeForceOnce { get { return m_bKeyChangeForceOnce; } set { m_bKeyChangeForceOnce = value; } } /// /// The encryption algorithm used to encrypt the data part of the database. /// public PwUuid DataCipherUuid { get { return m_uuidDataCipher; } set { Debug.Assert(value != null); if(value != null) m_uuidDataCipher = value; } } /// /// Compression algorithm used to encrypt the data part of the database. /// public PwCompressionAlgorithm Compression { get { return m_caCompression; } set { m_caCompression = value; } } // /// // /// Number of key transformation rounds (KDF parameter). // /// // public ulong KeyEncryptionRounds // { // get { return m_uKeyEncryptionRounds; } // set { m_uKeyEncryptionRounds = value; } // } public KdfParameters KdfParameters { get { return m_kdfParams; } set { if(value == null) throw new ArgumentNullException("value"); m_kdfParams = value; } } /// /// Memory protection configuration (for default fields). /// public MemoryProtectionConfig MemoryProtection { get { return m_memProtConfig; } set { Debug.Assert(value != null); if(value == null) throw new ArgumentNullException("value"); m_memProtConfig = value; } } /// /// Get a list of all deleted objects. /// public PwObjectList DeletedObjects { get { return m_vDeletedObjects; } } /// /// Get all custom icons stored in this database. /// public List CustomIcons { get { return m_vCustomIcons; } } /// /// This is a dirty-flag for the UI. It is used to indicate when an /// icon list update is required. /// public bool UINeedsIconUpdate { get { return m_bUINeedsIconUpdate; } set { m_bUINeedsIconUpdate = value; } } public PwUuid LastSelectedGroup { get { return m_pwLastSelectedGroup; } set { Debug.Assert(value != null); if(value == null) throw new ArgumentNullException("value"); m_pwLastSelectedGroup = value; } } public PwUuid LastTopVisibleGroup { get { return m_pwLastTopVisibleGroup; } set { Debug.Assert(value != null); if(value == null) throw new ArgumentNullException("value"); m_pwLastTopVisibleGroup = value; } } public bool RecycleBinEnabled { get { return m_bUseRecycleBin; } set { m_bUseRecycleBin = value; } } public PwUuid RecycleBinUuid { get { return m_pwRecycleBin; } set { Debug.Assert(value != null); if(value == null) throw new ArgumentNullException("value"); m_pwRecycleBin = value; } } public DateTime RecycleBinChanged { get { return m_dtRecycleBinChanged; } set { m_dtRecycleBinChanged = value; } } /// /// UUID of the group containing template entries. May be /// PwUuid.Zero, if no entry templates group has been specified. /// public PwUuid EntryTemplatesGroup { get { return m_pwEntryTemplatesGroup; } set { Debug.Assert(value != null); if(value == null) throw new ArgumentNullException("value"); m_pwEntryTemplatesGroup = value; } } public DateTime EntryTemplatesGroupChanged { get { return m_dtEntryTemplatesChanged; } set { m_dtEntryTemplatesChanged = value; } } public int HistoryMaxItems { get { return m_nHistoryMaxItems; } set { m_nHistoryMaxItems = value; } } public long HistoryMaxSize { get { return m_lHistoryMaxSize; } set { m_lHistoryMaxSize = value; } } /// /// Custom data container that can be used by plugins to store /// own data in KeePass databases. /// The data is stored in the encrypted part of encrypted /// database files. /// Use unique names for your items, e.g. "PluginName_ItemName". /// public StringDictionaryEx CustomData { get { return m_dCustomData; } internal set { if(value == null) { Debug.Assert(false); throw new ArgumentNullException("value"); } m_dCustomData = value; } } /// /// Custom data container that can be used by plugins to store /// own data in KeePass databases. /// The data is stored in the *unencrypted* part of database files, /// and it is not supported by all file formats (e.g. supported by KDBX, /// unsupported by XML). /// It is highly recommended to use CustomData instead, /// if possible. /// Use unique names for your items, e.g. "PluginName_ItemName". /// public VariantDictionary PublicCustomData { get { return m_dPublicCustomData; } internal set { if(value == null) { Debug.Assert(false); throw new ArgumentNullException("value"); } m_dPublicCustomData = value; } } /// /// Hash value of the primary file on disk (last read or last write). /// A call to SaveAs without making the saved file primary will /// not change this hash. May be null. /// public byte[] HashOfFileOnDisk { get { return m_pbHashOfFileOnDisk; } } public byte[] HashOfLastIO { get { return m_pbHashOfLastIO; } } public bool UseFileTransactions { get { return m_bUseFileTransactions; } set { m_bUseFileTransactions = value; } } public bool UseFileLocks { get { return m_bUseFileLocks; } set { m_bUseFileLocks = value; } } private string m_strDetachBins = null; /// /// Detach binaries when opening a file. If this isn't null, /// all binaries are saved to the specified path and are removed /// from the database. /// public string DetachBinaries { get { return m_strDetachBins; } set { m_strDetachBins = value; } } /// /// Localized application name. /// public static string LocalizedAppName { get { return m_strLocalizedAppName; } set { Debug.Assert(value != null); m_strLocalizedAppName = value; } } /// /// Constructs an empty password manager object. /// public PwDatabase() { if(m_bPrimaryCreated == false) m_bPrimaryCreated = true; Clear(); } private void Clear() { m_pgRootGroup = null; m_vDeletedObjects = new PwObjectList(); m_uuidDataCipher = StandardAesEngine.AesUuid; m_caCompression = PwCompressionAlgorithm.GZip; // m_uKeyEncryptionRounds = PwDefs.DefaultKeyEncryptionRounds; m_kdfParams = KdfPool.GetDefaultParameters(); m_pwUserKey = null; m_memProtConfig = new MemoryProtectionConfig(); m_vCustomIcons = new List(); m_bUINeedsIconUpdate = true; DateTime dtNow = DateTime.UtcNow; m_dtSettingsChanged = dtNow; m_strName = string.Empty; m_dtNameChanged = dtNow; m_strDesc = string.Empty; m_dtDescChanged = dtNow; m_strDefaultUserName = string.Empty; m_dtDefaultUserChanged = dtNow; m_uMntncHistoryDays = 365; m_clr = Color.Empty; m_dtKeyLastChanged = dtNow; m_lKeyChangeRecDays = -1; m_lKeyChangeForceDays = -1; m_bKeyChangeForceOnce = false; m_ioSource = new IOConnectionInfo(); m_bDatabaseOpened = false; m_bModified = false; m_pwLastSelectedGroup = PwUuid.Zero; m_pwLastTopVisibleGroup = PwUuid.Zero; m_bUseRecycleBin = true; m_pwRecycleBin = PwUuid.Zero; m_dtRecycleBinChanged = dtNow; m_pwEntryTemplatesGroup = PwUuid.Zero; m_dtEntryTemplatesChanged = dtNow; m_nHistoryMaxItems = DefaultHistoryMaxItems; m_lHistoryMaxSize = DefaultHistoryMaxSize; m_dCustomData = new StringDictionaryEx(); m_dPublicCustomData = new VariantDictionary(); m_pbHashOfFileOnDisk = null; m_pbHashOfLastIO = null; m_bUseFileTransactions = false; m_bUseFileLocks = false; } /// /// Initialize the class for managing a new database. Previously loaded /// data is deleted. /// /// IO connection of the new database. /// Key to open the database. public void New(IOConnectionInfo ioConnection, CompositeKey pwKey) { Debug.Assert(ioConnection != null); if(ioConnection == null) throw new ArgumentNullException("ioConnection"); Debug.Assert(pwKey != null); if(pwKey == null) throw new ArgumentNullException("pwKey"); Close(); m_ioSource = ioConnection; m_pwUserKey = pwKey; m_bDatabaseOpened = true; m_bModified = true; m_pgRootGroup = new PwGroup(true, true, UrlUtil.StripExtension(UrlUtil.GetFileName(ioConnection.Path)), PwIcon.FolderOpen); m_pgRootGroup.IsExpanded = true; } /// /// Open a database. The URL may point to any supported data source. /// /// IO connection to load the database from. /// Key used to open the specified database. /// Logger, which gets all status messages. public void Open(IOConnectionInfo ioSource, CompositeKey pwKey, IStatusLogger slLogger) { Debug.Assert(ioSource != null); if(ioSource == null) throw new ArgumentNullException("ioSource"); Debug.Assert(pwKey != null); if(pwKey == null) throw new ArgumentNullException("pwKey"); Close(); try { m_pgRootGroup = new PwGroup(true, true, UrlUtil.StripExtension( UrlUtil.GetFileName(ioSource.Path)), PwIcon.FolderOpen); m_pgRootGroup.IsExpanded = true; m_pwUserKey = pwKey; m_bModified = false; KdbxFile kdbx = new KdbxFile(this); kdbx.DetachBinaries = m_strDetachBins; Stream s = IOConnection.OpenRead(ioSource); kdbx.Load(s, KdbxFormat.Default, slLogger); s.Close(); m_pbHashOfLastIO = kdbx.HashOfFileOnDisk; m_pbHashOfFileOnDisk = kdbx.HashOfFileOnDisk; Debug.Assert(m_pbHashOfFileOnDisk != null); m_bDatabaseOpened = true; m_ioSource = ioSource; } catch(Exception) { Clear(); throw; } } /// /// Save the currently opened database. The file is written to the location /// it has been opened from. /// /// Logger that recieves status information. public void Save(IStatusLogger slLogger) { Debug.Assert(!HasDuplicateUuids()); FileLock fl = null; if(m_bUseFileLocks) fl = new FileLock(m_ioSource); try { FileTransactionEx ft = new FileTransactionEx(m_ioSource, m_bUseFileTransactions); Stream s = ft.OpenWrite(); KdbxFile kdb = new KdbxFile(this); kdb.Save(s, null, KdbxFormat.Default, slLogger); ft.CommitWrite(); m_pbHashOfLastIO = kdb.HashOfFileOnDisk; m_pbHashOfFileOnDisk = kdb.HashOfFileOnDisk; Debug.Assert(m_pbHashOfFileOnDisk != null); } finally { if(fl != null) fl.Dispose(); } m_bModified = false; } /// /// Save the currently opened database to a different location. If /// is true, the specified /// location is made the default location for future saves /// using SaveDatabase. /// /// New location to serialize the database to. /// If true, the new location is made the /// standard location for the database. If false, a copy of the currently /// opened database is saved to the specified location, but it isn't /// made the default location (i.e. no lock files will be moved for /// example). /// Logger that recieves status information. public void SaveAs(IOConnectionInfo ioConnection, bool bIsPrimaryNow, IStatusLogger slLogger) { Debug.Assert(ioConnection != null); if(ioConnection == null) throw new ArgumentNullException("ioConnection"); IOConnectionInfo ioCurrent = m_ioSource; // Remember current m_ioSource = ioConnection; byte[] pbHashCopy = m_pbHashOfFileOnDisk; try { this.Save(slLogger); } catch(Exception) { m_ioSource = ioCurrent; // Restore m_pbHashOfFileOnDisk = pbHashCopy; m_pbHashOfLastIO = null; throw; } if(!bIsPrimaryNow) { m_ioSource = ioCurrent; // Restore m_pbHashOfFileOnDisk = pbHashCopy; } } /// /// Closes the currently opened database. No confirmation message is shown /// before closing. Unsaved changes will be lost. /// public void Close() { Clear(); } public void MergeIn(PwDatabase pdSource, PwMergeMethod mm) { MergeIn(pdSource, mm, null); } public void MergeIn(PwDatabase pdSource, PwMergeMethod mm, IStatusLogger slStatus) { if(pdSource == null) throw new ArgumentNullException("pdSource"); if(mm == PwMergeMethod.CreateNewUuids) { pdSource.RootGroup.Uuid = new PwUuid(true); pdSource.RootGroup.CreateNewItemUuids(true, true, true); } // PwGroup pgOrgStructure = m_pgRootGroup.CloneStructure(); // PwGroup pgSrcStructure = pdSource.RootGroup.CloneStructure(); // Later in case 'if(mm == PwMergeMethod.Synchronize)': // PwObjectPoolEx ppOrg = PwObjectPoolEx.FromGroup(pgOrgStructure); // PwObjectPoolEx ppSrc = PwObjectPoolEx.FromGroup(pgSrcStructure); PwObjectPoolEx ppOrg = PwObjectPoolEx.FromGroup(m_pgRootGroup); PwObjectPoolEx ppSrc = PwObjectPoolEx.FromGroup(pdSource.RootGroup); GroupHandler ghSrc = delegate(PwGroup pg) { // if(pg == pdSource.m_pgRootGroup) return true; // Do not use ppOrg for finding the group, because new groups // might have been added (which are not in the pool, and the // pool should not be modified) PwGroup pgLocal = m_pgRootGroup.FindGroup(pg.Uuid, true); if(pgLocal == null) { PwGroup pgSourceParent = pg.ParentGroup; PwGroup pgLocalContainer; if(pgSourceParent == null) { // pg is the root group of pdSource, and no corresponding // local group was found; create the group within the // local root group Debug.Assert(pg == pdSource.m_pgRootGroup); pgLocalContainer = m_pgRootGroup; } else if(pgSourceParent == pdSource.m_pgRootGroup) pgLocalContainer = m_pgRootGroup; else pgLocalContainer = m_pgRootGroup.FindGroup(pgSourceParent.Uuid, true); Debug.Assert(pgLocalContainer != null); if(pgLocalContainer == null) pgLocalContainer = m_pgRootGroup; PwGroup pgNew = new PwGroup(false, false); pgNew.Uuid = pg.Uuid; pgNew.AssignProperties(pg, false, true); // pgLocalContainer.AddGroup(pgNew, true); InsertObjectAtBestPos(pgLocalContainer.Groups, pgNew, ppSrc); pgNew.ParentGroup = pgLocalContainer; } else // pgLocal != null { Debug.Assert(mm != PwMergeMethod.CreateNewUuids); if(mm == PwMergeMethod.OverwriteExisting) pgLocal.AssignProperties(pg, false, false); else if((mm == PwMergeMethod.OverwriteIfNewer) || (mm == PwMergeMethod.Synchronize)) { pgLocal.AssignProperties(pg, true, false); } // else if(mm == PwMergeMethod.KeepExisting) ... } return ((slStatus != null) ? slStatus.ContinueWork() : true); }; EntryHandler ehSrc = delegate(PwEntry pe) { // PwEntry peLocal = m_pgRootGroup.FindEntry(pe.Uuid, true); PwEntry peLocal = (ppOrg.GetItemByUuid(pe.Uuid) as PwEntry); Debug.Assert(object.ReferenceEquals(peLocal, m_pgRootGroup.FindEntry(pe.Uuid, true))); if(peLocal == null) { PwGroup pgSourceParent = pe.ParentGroup; PwGroup pgLocalContainer; if(pgSourceParent == pdSource.m_pgRootGroup) pgLocalContainer = m_pgRootGroup; else pgLocalContainer = m_pgRootGroup.FindGroup(pgSourceParent.Uuid, true); Debug.Assert(pgLocalContainer != null); if(pgLocalContainer == null) pgLocalContainer = m_pgRootGroup; PwEntry peNew = new PwEntry(false, false); peNew.Uuid = pe.Uuid; peNew.AssignProperties(pe, false, true, true); // pgLocalContainer.AddEntry(peNew, true); InsertObjectAtBestPos(pgLocalContainer.Entries, peNew, ppSrc); peNew.ParentGroup = pgLocalContainer; } else // peLocal != null { Debug.Assert(mm != PwMergeMethod.CreateNewUuids); const PwCompareOptions cmpOpt = (PwCompareOptions.IgnoreParentGroup | PwCompareOptions.IgnoreLastAccess | PwCompareOptions.IgnoreHistory | PwCompareOptions.NullEmptyEquivStd); bool bEquals = peLocal.EqualsEntry(pe, cmpOpt, MemProtCmpMode.None); bool bOrgBackup = !bEquals; if(mm != PwMergeMethod.OverwriteExisting) bOrgBackup &= (TimeUtil.CompareLastMod(pe, peLocal, true) > 0); bOrgBackup &= !pe.HasBackupOfData(peLocal, false, true); if(bOrgBackup) peLocal.CreateBackup(null); // Maintain at end bool bSrcBackup = !bEquals && (mm != PwMergeMethod.OverwriteExisting); bSrcBackup &= (TimeUtil.CompareLastMod(peLocal, pe, true) > 0); bSrcBackup &= !peLocal.HasBackupOfData(pe, false, true); if(bSrcBackup) pe.CreateBackup(null); // Maintain at end if(mm == PwMergeMethod.OverwriteExisting) peLocal.AssignProperties(pe, false, false, false); else if((mm == PwMergeMethod.OverwriteIfNewer) || (mm == PwMergeMethod.Synchronize)) { peLocal.AssignProperties(pe, true, false, false); } // else if(mm == PwMergeMethod.KeepExisting) ... MergeEntryHistory(peLocal, pe, mm); } return ((slStatus != null) ? slStatus.ContinueWork() : true); }; ghSrc(pdSource.RootGroup); if(!pdSource.RootGroup.TraverseTree(TraversalMethod.PreOrder, ghSrc, ehSrc)) throw new InvalidOperationException(); IStatusLogger slPrevStatus = m_slStatus; m_slStatus = slStatus; if(mm == PwMergeMethod.Synchronize) { RelocateGroups(ppOrg, ppSrc); RelocateEntries(ppOrg, ppSrc); ReorderObjects(m_pgRootGroup, ppOrg, ppSrc); // After all relocations and reorderings MergeInLocationChanged(m_pgRootGroup, ppOrg, ppSrc); ppOrg = null; // Pools are now invalid, because the location ppSrc = null; // changed times have been merged in // Delete *after* relocating, because relocating might // empty some groups that are marked for deletion (and // objects that weren't relocated yet might prevent the // deletion) Dictionary dOrgDel = CreateDeletedObjectsPool(); MergeInDeletionInfo(pdSource.m_vDeletedObjects, dOrgDel); ApplyDeletions(m_pgRootGroup, dOrgDel); // The list and the dictionary should be kept in sync Debug.Assert(m_vDeletedObjects.UCount == (uint)dOrgDel.Count); } // Must be called *after* merging groups, because group UUIDs // are required for recycle bin and entry template UUIDs MergeInDbProperties(pdSource, mm); MergeInCustomIcons(pdSource); MaintainBackups(); Debug.Assert(!HasDuplicateUuids()); m_slStatus = slPrevStatus; } private void MergeInCustomIcons(PwDatabase pdSource) { foreach(PwCustomIcon pwci in pdSource.CustomIcons) { if(GetCustomIconIndex(pwci.Uuid) >= 0) continue; m_vCustomIcons.Add(pwci); // PwCustomIcon is immutable m_bUINeedsIconUpdate = true; } } private Dictionary CreateDeletedObjectsPool() { Dictionary d = new Dictionary(); int n = (int)m_vDeletedObjects.UCount; for(int i = n - 1; i >= 0; --i) { PwDeletedObject pdo = m_vDeletedObjects.GetAt((uint)i); PwDeletedObject pdoEx; if(d.TryGetValue(pdo.Uuid, out pdoEx)) { Debug.Assert(false); // Found duplicate, which should not happen if(pdo.DeletionTime > pdoEx.DeletionTime) pdoEx.DeletionTime = pdo.DeletionTime; m_vDeletedObjects.RemoveAt((uint)i); } else d[pdo.Uuid] = pdo; } return d; } private void MergeInDeletionInfo(PwObjectList lSrc, Dictionary dOrgDel) { foreach(PwDeletedObject pdoSrc in lSrc) { PwDeletedObject pdoOrg; if(dOrgDel.TryGetValue(pdoSrc.Uuid, out pdoOrg)) // Update { Debug.Assert(pdoOrg.Uuid.Equals(pdoSrc.Uuid)); if(pdoSrc.DeletionTime > pdoOrg.DeletionTime) pdoOrg.DeletionTime = pdoSrc.DeletionTime; } else // Add { m_vDeletedObjects.Add(pdoSrc); dOrgDel[pdoSrc.Uuid] = pdoSrc; } } } private void ApplyDeletions(PwObjectList l, Predicate fCanDelete, Dictionary dOrgDel) where T : class, ITimeLogger, IStructureItem, IDeepCloneable { int n = (int)l.UCount; for(int i = n - 1; i >= 0; --i) { if((m_slStatus != null) && !m_slStatus.ContinueWork()) break; T t = l.GetAt((uint)i); PwDeletedObject pdo; if(dOrgDel.TryGetValue(t.Uuid, out pdo)) { Debug.Assert(t.Uuid.Equals(pdo.Uuid)); bool bDel = (TimeUtil.Compare(t.LastModificationTime, pdo.DeletionTime, true) < 0); bDel &= fCanDelete(t); if(bDel) l.RemoveAt((uint)i); else { // Prevent future deletion attempts; this also prevents // delayed deletions (emptying a group could cause a // group to be deleted, if the deletion was prevented // before due to the group not being empty) if(!m_vDeletedObjects.Remove(pdo)) { Debug.Assert(false); } if(!dOrgDel.Remove(pdo.Uuid)) { Debug.Assert(false); } } } } } private static bool SafeCanDeleteGroup(PwGroup pg) { if(pg == null) { Debug.Assert(false); return false; } if(pg.Groups.UCount > 0) return false; if(pg.Entries.UCount > 0) return false; return true; } private static bool SafeCanDeleteEntry(PwEntry pe) { if(pe == null) { Debug.Assert(false); return false; } return true; } // Apply deletions on all objects in the specified container // (but not the container itself), using post-order traversal // to avoid implicit deletions; // https://sourceforge.net/p/keepass/bugs/1499/ private void ApplyDeletions(PwGroup pgContainer, Dictionary dOrgDel) { foreach(PwGroup pg in pgContainer.Groups) // Post-order traversal { ApplyDeletions(pg, dOrgDel); } ApplyDeletions(pgContainer.Groups, PwDatabase.SafeCanDeleteGroup, dOrgDel); ApplyDeletions(pgContainer.Entries, PwDatabase.SafeCanDeleteEntry, dOrgDel); } private void RelocateGroups(PwObjectPoolEx ppOrg, PwObjectPoolEx ppSrc) { PwObjectList vGroups = m_pgRootGroup.GetGroups(true); foreach(PwGroup pg in vGroups) { if((m_slStatus != null) && !m_slStatus.ContinueWork()) break; // PwGroup pgOrg = pgOrgStructure.FindGroup(pg.Uuid, true); IStructureItem ptOrg = ppOrg.GetItemByUuid(pg.Uuid); if(ptOrg == null) continue; // PwGroup pgSrc = pgSrcStructure.FindGroup(pg.Uuid, true); IStructureItem ptSrc = ppSrc.GetItemByUuid(pg.Uuid); if(ptSrc == null) continue; PwGroup pgOrgParent = ptOrg.ParentGroup; // vGroups does not contain the root group, thus pgOrgParent // should not be null if(pgOrgParent == null) { Debug.Assert(false); continue; } PwGroup pgSrcParent = ptSrc.ParentGroup; // pgSrcParent may be null (for the source root group) if(pgSrcParent == null) continue; if(pgOrgParent.Uuid.Equals(pgSrcParent.Uuid)) { // pg.LocationChanged = ((ptSrc.LocationChanged > ptOrg.LocationChanged) ? // ptSrc.LocationChanged : ptOrg.LocationChanged); continue; } if(ptSrc.LocationChanged > ptOrg.LocationChanged) { PwGroup pgLocal = m_pgRootGroup.FindGroup(pgSrcParent.Uuid, true); if(pgLocal == null) { Debug.Assert(false); continue; } if(pgLocal.IsContainedIn(pg)) continue; pg.ParentGroup.Groups.Remove(pg); // pgLocal.AddGroup(pg, true); InsertObjectAtBestPos(pgLocal.Groups, pg, ppSrc); pg.ParentGroup = pgLocal; // pg.LocationChanged = ptSrc.LocationChanged; } else { Debug.Assert(pg.ParentGroup.Uuid.Equals(pgOrgParent.Uuid)); Debug.Assert(pg.LocationChanged == ptOrg.LocationChanged); } } Debug.Assert(m_pgRootGroup.GetGroups(true).UCount == vGroups.UCount); } private void RelocateEntries(PwObjectPoolEx ppOrg, PwObjectPoolEx ppSrc) { PwObjectList vEntries = m_pgRootGroup.GetEntries(true); foreach(PwEntry pe in vEntries) { if((m_slStatus != null) && !m_slStatus.ContinueWork()) break; // PwEntry peOrg = pgOrgStructure.FindEntry(pe.Uuid, true); IStructureItem ptOrg = ppOrg.GetItemByUuid(pe.Uuid); if(ptOrg == null) continue; // PwEntry peSrc = pgSrcStructure.FindEntry(pe.Uuid, true); IStructureItem ptSrc = ppSrc.GetItemByUuid(pe.Uuid); if(ptSrc == null) continue; PwGroup pgOrg = ptOrg.ParentGroup; PwGroup pgSrc = ptSrc.ParentGroup; if(pgOrg.Uuid.Equals(pgSrc.Uuid)) { // pe.LocationChanged = ((ptSrc.LocationChanged > ptOrg.LocationChanged) ? // ptSrc.LocationChanged : ptOrg.LocationChanged); continue; } if(ptSrc.LocationChanged > ptOrg.LocationChanged) { PwGroup pgLocal = m_pgRootGroup.FindGroup(pgSrc.Uuid, true); if(pgLocal == null) { Debug.Assert(false); continue; } pe.ParentGroup.Entries.Remove(pe); // pgLocal.AddEntry(pe, true); InsertObjectAtBestPos(pgLocal.Entries, pe, ppSrc); pe.ParentGroup = pgLocal; // pe.LocationChanged = ptSrc.LocationChanged; } else { Debug.Assert(pe.ParentGroup.Uuid.Equals(pgOrg.Uuid)); Debug.Assert(pe.LocationChanged == ptOrg.LocationChanged); } } Debug.Assert(m_pgRootGroup.GetEntries(true).UCount == vEntries.UCount); } private void ReorderObjects(PwGroup pg, PwObjectPoolEx ppOrg, PwObjectPoolEx ppSrc) { ReorderObjectList(pg.Groups, ppOrg, ppSrc); ReorderObjectList(pg.Entries, ppOrg, ppSrc); foreach(PwGroup pgSub in pg.Groups) { ReorderObjects(pgSub, ppOrg, ppSrc); } } private void ReorderObjectList(PwObjectList lItems, PwObjectPoolEx ppOrg, PwObjectPoolEx ppSrc) where T : class, ITimeLogger, IStructureItem, IDeepCloneable { List> lBlocks = PartitionConsec(lItems, ppOrg, ppSrc); if(lBlocks.Count <= 1) return; #if DEBUG PwObjectList lOrgItems = lItems.CloneShallow(); #endif Queue> qToDo = new Queue>(); qToDo.Enqueue(new KeyValuePair(0, lBlocks.Count - 1)); while(qToDo.Count > 0) { if((m_slStatus != null) && !m_slStatus.ContinueWork()) break; KeyValuePair kvp = qToDo.Dequeue(); if(kvp.Key >= kvp.Value) { Debug.Assert(false); continue; } PwObjectPoolEx pPool; int iPivot = FindLocationChangedPivot(lBlocks, kvp, out pPool); PwObjectBlock bPivot = lBlocks[iPivot]; T tPivotPrimary = bPivot.PrimaryItem; if(tPivotPrimary == null) { Debug.Assert(false); continue; } ulong idPivot = pPool.GetIdByUuid(tPivotPrimary.Uuid); if(idPivot == 0) { Debug.Assert(false); continue; } Queue> qBefore = new Queue>(); Queue> qAfter = new Queue>(); bool bBefore = true; for(int i = kvp.Key; i <= kvp.Value; ++i) { if(i == iPivot) { bBefore = false; continue; } PwObjectBlock b = lBlocks[i]; Debug.Assert(b.LocationChanged <= bPivot.LocationChanged); T t = b.PrimaryItem; if(t != null) { ulong idBPri = pPool.GetIdByUuid(t.Uuid); if(idBPri > 0) { if(idBPri < idPivot) qBefore.Enqueue(b); else qAfter.Enqueue(b); continue; } } else { Debug.Assert(false); } if(bBefore) qBefore.Enqueue(b); else qAfter.Enqueue(b); } int j = kvp.Key; while(qBefore.Count > 0) { lBlocks[j] = qBefore.Dequeue(); ++j; } int iNewPivot = j; lBlocks[j] = bPivot; ++j; while(qAfter.Count > 0) { lBlocks[j] = qAfter.Dequeue(); ++j; } Debug.Assert(j == (kvp.Value + 1)); if((iNewPivot - 1) > kvp.Key) qToDo.Enqueue(new KeyValuePair(kvp.Key, iNewPivot - 1)); if((iNewPivot + 1) < kvp.Value) qToDo.Enqueue(new KeyValuePair(iNewPivot + 1, kvp.Value)); } uint u = 0; foreach(PwObjectBlock b in lBlocks) { foreach(T t in b) { lItems.SetAt(u, t); ++u; } } Debug.Assert(u == lItems.UCount); #if DEBUG Debug.Assert(u == lOrgItems.UCount); foreach(T ptItem in lOrgItems) { Debug.Assert(lItems.IndexOf(ptItem) >= 0); } #endif } private static List> PartitionConsec(PwObjectList lItems, PwObjectPoolEx ppOrg, PwObjectPoolEx ppSrc) where T : class, ITimeLogger, IStructureItem, IDeepCloneable { List> lBlocks = new List>(); Dictionary dItemUuids = new Dictionary(); foreach(T t in lItems) { dItemUuids[t.Uuid] = true; } uint n = lItems.UCount; for(uint u = 0; u < n; ++u) { T t = lItems.GetAt(u); PwObjectBlock b = new PwObjectBlock(); DateTime dtLoc; PwObjectPoolEx pPool = GetBestPool(t, ppOrg, ppSrc, out dtLoc); b.Add(t, dtLoc, pPool); lBlocks.Add(b); ulong idOrg = ppOrg.GetIdByUuid(t.Uuid); ulong idSrc = ppSrc.GetIdByUuid(t.Uuid); if((idOrg == 0) || (idSrc == 0)) continue; for(uint x = u + 1; x < n; ++x) { T tNext = lItems.GetAt(x); ulong idOrgNext = idOrg + 1; while(true) { IStructureItem ptOrg = ppOrg.GetItemById(idOrgNext); if(ptOrg == null) { idOrgNext = 0; break; } if(ptOrg.Uuid.Equals(tNext.Uuid)) break; // Found it if(dItemUuids.ContainsKey(ptOrg.Uuid)) { idOrgNext = 0; break; } ++idOrgNext; } if(idOrgNext == 0) break; ulong idSrcNext = idSrc + 1; while(true) { IStructureItem ptSrc = ppSrc.GetItemById(idSrcNext); if(ptSrc == null) { idSrcNext = 0; break; } if(ptSrc.Uuid.Equals(tNext.Uuid)) break; // Found it if(dItemUuids.ContainsKey(ptSrc.Uuid)) { idSrcNext = 0; break; } ++idSrcNext; } if(idSrcNext == 0) break; pPool = GetBestPool(tNext, ppOrg, ppSrc, out dtLoc); b.Add(tNext, dtLoc, pPool); ++u; idOrg = idOrgNext; idSrc = idSrcNext; } } return lBlocks; } private static PwObjectPoolEx GetBestPool(T t, PwObjectPoolEx ppOrg, PwObjectPoolEx ppSrc, out DateTime dtLoc) where T : class, ITimeLogger, IStructureItem, IDeepCloneable { PwObjectPoolEx p = null; dtLoc = TimeUtil.SafeMinValueUtc; IStructureItem ptOrg = ppOrg.GetItemByUuid(t.Uuid); if(ptOrg != null) { dtLoc = ptOrg.LocationChanged; p = ppOrg; } IStructureItem ptSrc = ppSrc.GetItemByUuid(t.Uuid); if((ptSrc != null) && (ptSrc.LocationChanged > dtLoc)) { dtLoc = ptSrc.LocationChanged; p = ppSrc; } Debug.Assert(p != null); return p; } private static int FindLocationChangedPivot(List> lBlocks, KeyValuePair kvpRange, out PwObjectPoolEx pPool) where T : class, ITimeLogger, IStructureItem, IDeepCloneable { pPool = null; int iPosMax = kvpRange.Key; DateTime dtMax = TimeUtil.SafeMinValueUtc; for(int i = kvpRange.Key; i <= kvpRange.Value; ++i) { PwObjectBlock b = lBlocks[i]; if(b.LocationChanged > dtMax) { iPosMax = i; dtMax = b.LocationChanged; pPool = b.PoolAssoc; } } return iPosMax; } private static void MergeInLocationChanged(PwGroup pg, PwObjectPoolEx ppOrg, PwObjectPoolEx ppSrc) { GroupHandler gh = delegate(PwGroup pgSub) { DateTime dt; if(GetBestPool(pgSub, ppOrg, ppSrc, out dt) != null) pgSub.LocationChanged = dt; else { Debug.Assert(false); } return true; }; EntryHandler eh = delegate(PwEntry pe) { DateTime dt; if(GetBestPool(pe, ppOrg, ppSrc, out dt) != null) pe.LocationChanged = dt; else { Debug.Assert(false); } return true; }; gh(pg); pg.TraverseTree(TraversalMethod.PreOrder, gh, eh); } private static void InsertObjectAtBestPos(PwObjectList lItems, T tNew, PwObjectPoolEx ppSrc) where T : class, ITimeLogger, IStructureItem, IDeepCloneable { if(tNew == null) { Debug.Assert(false); return; } ulong idSrc = ppSrc.GetIdByUuid(tNew.Uuid); if(idSrc == 0) { Debug.Assert(false); lItems.Add(tNew); return; } const uint uIdOffset = 2; Dictionary dOrg = new Dictionary(); for(uint u = 0; u < lItems.UCount; ++u) dOrg[lItems.GetAt(u).Uuid] = uIdOffset + u; ulong idSrcNext = idSrc + 1; uint idOrgNext = 0; while(true) { IStructureItem pNext = ppSrc.GetItemById(idSrcNext); if(pNext == null) break; if(dOrg.TryGetValue(pNext.Uuid, out idOrgNext)) break; ++idSrcNext; } if(idOrgNext != 0) { lItems.Insert(idOrgNext - uIdOffset, tNew); return; } ulong idSrcPrev = idSrc - 1; uint idOrgPrev = 0; while(true) { IStructureItem pPrev = ppSrc.GetItemById(idSrcPrev); if(pPrev == null) break; if(dOrg.TryGetValue(pPrev.Uuid, out idOrgPrev)) break; --idSrcPrev; } if(idOrgPrev != 0) { lItems.Insert(idOrgPrev + 1 - uIdOffset, tNew); return; } lItems.Add(tNew); } private void MergeInDbProperties(PwDatabase pdSource, PwMergeMethod mm) { if(pdSource == null) { Debug.Assert(false); return; } if((mm == PwMergeMethod.KeepExisting) || (mm == PwMergeMethod.None)) return; bool bForce = (mm == PwMergeMethod.OverwriteExisting); bool bSourceNewer = (pdSource.m_dtSettingsChanged > m_dtSettingsChanged); if(bForce || bSourceNewer) { m_dtSettingsChanged = pdSource.m_dtSettingsChanged; m_clr = pdSource.m_clr; } if(bForce || (pdSource.m_dtNameChanged > m_dtNameChanged)) { m_strName = pdSource.m_strName; m_dtNameChanged = pdSource.m_dtNameChanged; } if(bForce || (pdSource.m_dtDescChanged > m_dtDescChanged)) { m_strDesc = pdSource.m_strDesc; m_dtDescChanged = pdSource.m_dtDescChanged; } if(bForce || (pdSource.m_dtDefaultUserChanged > m_dtDefaultUserChanged)) { m_strDefaultUserName = pdSource.m_strDefaultUserName; m_dtDefaultUserChanged = pdSource.m_dtDefaultUserChanged; } PwUuid pwPrefBin = m_pwRecycleBin, pwAltBin = pdSource.m_pwRecycleBin; if(bForce || (pdSource.m_dtRecycleBinChanged > m_dtRecycleBinChanged)) { pwPrefBin = pdSource.m_pwRecycleBin; pwAltBin = m_pwRecycleBin; m_bUseRecycleBin = pdSource.m_bUseRecycleBin; m_dtRecycleBinChanged = pdSource.m_dtRecycleBinChanged; } if(m_pgRootGroup.FindGroup(pwPrefBin, true) != null) m_pwRecycleBin = pwPrefBin; else if(m_pgRootGroup.FindGroup(pwAltBin, true) != null) m_pwRecycleBin = pwAltBin; else m_pwRecycleBin = PwUuid.Zero; // Debug.Assert(false); PwUuid pwPrefTmp = m_pwEntryTemplatesGroup, pwAltTmp = pdSource.m_pwEntryTemplatesGroup; if(bForce || (pdSource.m_dtEntryTemplatesChanged > m_dtEntryTemplatesChanged)) { pwPrefTmp = pdSource.m_pwEntryTemplatesGroup; pwAltTmp = m_pwEntryTemplatesGroup; m_dtEntryTemplatesChanged = pdSource.m_dtEntryTemplatesChanged; } if(m_pgRootGroup.FindGroup(pwPrefTmp, true) != null) m_pwEntryTemplatesGroup = pwPrefTmp; else if(m_pgRootGroup.FindGroup(pwAltTmp, true) != null) m_pwEntryTemplatesGroup = pwAltTmp; else m_pwEntryTemplatesGroup = PwUuid.Zero; // Debug.Assert(false); foreach(KeyValuePair kvp in pdSource.m_dCustomData) { if(bSourceNewer || !m_dCustomData.Exists(kvp.Key)) m_dCustomData.Set(kvp.Key, kvp.Value); } VariantDictionary vdLocal = m_dPublicCustomData; // Backup m_dPublicCustomData = (VariantDictionary)pdSource.m_dPublicCustomData.Clone(); if(!bSourceNewer) vdLocal.CopyTo(m_dPublicCustomData); // Merge } private void MergeEntryHistory(PwEntry pe, PwEntry peSource, PwMergeMethod mm) { if(!pe.Uuid.Equals(peSource.Uuid)) { Debug.Assert(false); return; } if(pe.History.UCount == peSource.History.UCount) { bool bEqual = true; for(uint uEnum = 0; uEnum < pe.History.UCount; ++uEnum) { if(pe.History.GetAt(uEnum).LastModificationTime != peSource.History.GetAt(uEnum).LastModificationTime) { bEqual = false; break; } } if(bEqual) return; } if((m_slStatus != null) && !m_slStatus.ContinueWork()) return; IDictionary dict = #if KeePassLibSD new SortedList(); #else new SortedDictionary(); #endif foreach(PwEntry peOrg in pe.History) { dict[peOrg.LastModificationTime] = peOrg; } foreach(PwEntry peSrc in peSource.History) { DateTime dt = peSrc.LastModificationTime; if(dict.ContainsKey(dt)) { if(mm == PwMergeMethod.OverwriteExisting) dict[dt] = peSrc.CloneDeep(); } else dict[dt] = peSrc.CloneDeep(); } pe.History.Clear(); foreach(KeyValuePair kvpCur in dict) { Debug.Assert(kvpCur.Value.Uuid.Equals(pe.Uuid)); Debug.Assert(kvpCur.Value.History.UCount == 0); pe.History.Add(kvpCur.Value); } } public bool MaintainBackups() { if(m_pgRootGroup == null) { Debug.Assert(false); return false; } bool bDeleted = false; EntryHandler eh = delegate(PwEntry pe) { if(pe.MaintainBackups(this)) bDeleted = true; return true; }; m_pgRootGroup.TraverseTree(TraversalMethod.PreOrder, null, eh); return bDeleted; } /* /// /// Synchronize current database with another one. /// /// Source file. public void Synchronize(string strFile) { PwDatabase pdSource = new PwDatabase(); IOConnectionInfo ioc = IOConnectionInfo.FromPath(strFile); pdSource.Open(ioc, m_pwUserKey, null); MergeIn(pdSource, PwMergeMethod.Synchronize); } */ /// /// Get the index of a custom icon. /// /// ID of the icon. /// Index of the icon. public int GetCustomIconIndex(PwUuid pwIconId) { for(int i = 0; i < m_vCustomIcons.Count; ++i) { PwCustomIcon pwci = m_vCustomIcons[i]; if(pwci.Uuid.Equals(pwIconId)) return i; } // Debug.Assert(false); // Do not assert return -1; } public int GetCustomIconIndex(byte[] pbPngData) { if(pbPngData == null) { Debug.Assert(false); return -1; } for(int i = 0; i < m_vCustomIcons.Count; ++i) { PwCustomIcon pwci = m_vCustomIcons[i]; byte[] pbEx = pwci.ImageDataPng; if(pbEx == null) { Debug.Assert(false); continue; } if(MemUtil.ArraysEqual(pbEx, pbPngData)) return i; } return -1; } #if KeePassUAP public Image GetCustomIcon(PwUuid pwIconId) { int nIndex = GetCustomIconIndex(pwIconId); if(nIndex >= 0) return m_vCustomIcons[nIndex].GetImage(); else { Debug.Assert(false); } return null; } #elif !KeePassLibSD [Obsolete("Additionally specify the size.")] public Image GetCustomIcon(PwUuid pwIconId) { return GetCustomIcon(pwIconId, 16, 16); // Backward compatibility } /// /// Get a custom icon. This method can return null, /// e.g. if no cached image of the icon is available. /// /// ID of the icon. /// Width of the returned image. If this is /// negative, the image is returned in its original size. /// Height of the returned image. If this is /// negative, the image is returned in its original size. public Image GetCustomIcon(PwUuid pwIconId, int w, int h) { int nIndex = GetCustomIconIndex(pwIconId); if(nIndex >= 0) { if((w >= 0) && (h >= 0)) return m_vCustomIcons[nIndex].GetImage(w, h); else return m_vCustomIcons[nIndex].GetImage(); // No assert } else { Debug.Assert(false); } return null; } #endif public bool DeleteCustomIcons(List vUuidsToDelete) { Debug.Assert(vUuidsToDelete != null); if(vUuidsToDelete == null) throw new ArgumentNullException("vUuidsToDelete"); if(vUuidsToDelete.Count <= 0) return true; GroupHandler gh = delegate(PwGroup pg) { PwUuid uuidThis = pg.CustomIconUuid; if(uuidThis.Equals(PwUuid.Zero)) return true; foreach(PwUuid uuidDelete in vUuidsToDelete) { if(uuidThis.Equals(uuidDelete)) { pg.CustomIconUuid = PwUuid.Zero; break; } } return true; }; EntryHandler eh = delegate(PwEntry pe) { RemoveCustomIconUuid(pe, vUuidsToDelete); return true; }; gh(m_pgRootGroup); if(!m_pgRootGroup.TraverseTree(TraversalMethod.PreOrder, gh, eh)) { Debug.Assert(false); return false; } foreach(PwUuid pwUuid in vUuidsToDelete) { int nIndex = GetCustomIconIndex(pwUuid); if(nIndex >= 0) m_vCustomIcons.RemoveAt(nIndex); } return true; } private static void RemoveCustomIconUuid(PwEntry pe, List vToDelete) { PwUuid uuidThis = pe.CustomIconUuid; if(uuidThis.Equals(PwUuid.Zero)) return; foreach(PwUuid uuidDelete in vToDelete) { if(uuidThis.Equals(uuidDelete)) { pe.CustomIconUuid = PwUuid.Zero; break; } } foreach(PwEntry peHistory in pe.History) RemoveCustomIconUuid(peHistory, vToDelete); } private int GetTotalObjectUuidCount() { uint uGroups, uEntries; m_pgRootGroup.GetCounts(true, out uGroups, out uEntries); uint uTotal = uGroups + uEntries + 1; // 1 for root group if(uTotal > 0x7FFFFFFFU) { Debug.Assert(false); return 0x7FFFFFFF; } return (int)uTotal; } internal bool HasDuplicateUuids() { int nTotal = GetTotalObjectUuidCount(); Dictionary d = new Dictionary(nTotal); bool bDupFound = false; GroupHandler gh = delegate(PwGroup pg) { PwUuid pu = pg.Uuid; if(d.ContainsKey(pu)) { bDupFound = true; return false; } d.Add(pu, null); Debug.Assert(d.ContainsKey(pu)); return true; }; EntryHandler eh = delegate(PwEntry pe) { PwUuid pu = pe.Uuid; if(d.ContainsKey(pu)) { bDupFound = true; return false; } d.Add(pu, null); Debug.Assert(d.ContainsKey(pu)); return true; }; gh(m_pgRootGroup); m_pgRootGroup.TraverseTree(TraversalMethod.PreOrder, gh, eh); Debug.Assert(bDupFound || (d.Count == nTotal)); return bDupFound; } internal void FixDuplicateUuids() { int nTotal = GetTotalObjectUuidCount(); Dictionary d = new Dictionary(nTotal); GroupHandler gh = delegate(PwGroup pg) { PwUuid pu = pg.Uuid; if(d.ContainsKey(pu)) { pu = new PwUuid(true); while(d.ContainsKey(pu)) { Debug.Assert(false); pu = new PwUuid(true); } pg.Uuid = pu; } d.Add(pu, null); return true; }; EntryHandler eh = delegate(PwEntry pe) { PwUuid pu = pe.Uuid; if(d.ContainsKey(pu)) { pu = new PwUuid(true); while(d.ContainsKey(pu)) { Debug.Assert(false); pu = new PwUuid(true); } pe.SetUuid(pu, true); } d.Add(pu, null); return true; }; gh(m_pgRootGroup); m_pgRootGroup.TraverseTree(TraversalMethod.PreOrder, gh, eh); Debug.Assert(d.Count == nTotal); Debug.Assert(!HasDuplicateUuids()); } /* public void CreateBackupFile(IStatusLogger sl) { if(sl != null) sl.SetText(KLRes.CreatingBackupFile, LogStatusType.Info); IOConnectionInfo iocBk = m_ioSource.CloneDeep(); iocBk.Path += StrBackupExtension; bool bMadeUnhidden = UrlUtil.UnhideFile(iocBk.Path); bool bFastCopySuccess = false; if(m_ioSource.IsLocalFile() && (m_ioSource.UserName.Length == 0) && (m_ioSource.Password.Length == 0)) { try { string strFile = m_ioSource.Path + StrBackupExtension; File.Copy(m_ioSource.Path, strFile, true); bFastCopySuccess = true; } catch(Exception) { Debug.Assert(false); } } if(bFastCopySuccess == false) { using(Stream sIn = IOConnection.OpenRead(m_ioSource)) { using(Stream sOut = IOConnection.OpenWrite(iocBk)) { MemUtil.CopyStream(sIn, sOut); sOut.Close(); } sIn.Close(); } } if(bMadeUnhidden) UrlUtil.HideFile(iocBk.Path, true); // Hide again } */ /* private static void RemoveData(PwGroup pg) { EntryHandler eh = delegate(PwEntry pe) { pe.AutoType.Clear(); pe.Binaries.Clear(); pe.History.Clear(); pe.Strings.Clear(); return true; }; pg.TraverseTree(TraversalMethod.PreOrder, null, eh); } */ public uint DeleteDuplicateEntries(IStatusLogger sl) { uint uDeleted = 0; PwGroup pgRecycleBin = null; if(m_bUseRecycleBin) pgRecycleBin = m_pgRootGroup.FindGroup(m_pwRecycleBin, true); DateTime dtNow = DateTime.UtcNow; PwObjectList l = m_pgRootGroup.GetEntries(true); int i = 0; while(true) { if(i >= ((int)l.UCount - 1)) break; if(sl != null) { long lCnt = (long)l.UCount, li = (long)i; long nArTotal = (lCnt * lCnt) / 2L; long nArCur = li * lCnt - ((li * li) / 2L); long nArPct = (nArCur * 100L) / nArTotal; if(nArPct < 0) nArPct = 0; if(nArPct > 100) nArPct = 100; if(!sl.SetProgress((uint)nArPct)) break; } PwEntry peA = l.GetAt((uint)i); for(uint j = (uint)i + 1; j < l.UCount; ++j) { PwEntry peB = l.GetAt(j); if(!DupEntriesEqual(peA, peB)) continue; bool bDeleteA = (TimeUtil.CompareLastMod(peA, peB, true) <= 0); if(pgRecycleBin != null) { bool bAInBin = peA.IsContainedIn(pgRecycleBin); bool bBInBin = peB.IsContainedIn(pgRecycleBin); if(bAInBin && !bBInBin) bDeleteA = true; else if(bBInBin && !bAInBin) bDeleteA = false; } if(bDeleteA) { peA.ParentGroup.Entries.Remove(peA); m_vDeletedObjects.Add(new PwDeletedObject(peA.Uuid, dtNow)); l.RemoveAt((uint)i); --i; } else { peB.ParentGroup.Entries.Remove(peB); m_vDeletedObjects.Add(new PwDeletedObject(peB.Uuid, dtNow)); l.RemoveAt(j); } ++uDeleted; break; } ++i; } return uDeleted; } private static List m_lStdFields = null; private static bool DupEntriesEqual(PwEntry a, PwEntry b) { if(m_lStdFields == null) m_lStdFields = PwDefs.GetStandardFields(); foreach(string strStdKey in m_lStdFields) { string strA = a.Strings.ReadSafe(strStdKey); string strB = b.Strings.ReadSafe(strStdKey); if(!strA.Equals(strB)) return false; } foreach(KeyValuePair kvpA in a.Strings) { if(PwDefs.IsStandardField(kvpA.Key)) continue; ProtectedString psB = b.Strings.Get(kvpA.Key); if(psB == null) return false; // Ignore protection setting, compare values only if(!kvpA.Value.ReadString().Equals(psB.ReadString())) return false; } foreach(KeyValuePair kvpB in b.Strings) { if(PwDefs.IsStandardField(kvpB.Key)) continue; ProtectedString psA = a.Strings.Get(kvpB.Key); if(psA == null) return false; // Must be equal by logic Debug.Assert(kvpB.Value.ReadString().Equals(psA.ReadString())); } if(a.Binaries.UCount != b.Binaries.UCount) return false; foreach(KeyValuePair kvpBin in a.Binaries) { ProtectedBinary pbB = b.Binaries.Get(kvpBin.Key); if(pbB == null) return false; // Ignore protection setting, compare values only byte[] pbDataA = kvpBin.Value.ReadData(); byte[] pbDataB = pbB.ReadData(); bool bBinEq = MemUtil.ArraysEqual(pbDataA, pbDataB); MemUtil.ZeroByteArray(pbDataA); MemUtil.ZeroByteArray(pbDataB); if(!bBinEq) return false; } return true; } public uint DeleteEmptyGroups() { uint uDeleted = 0; PwObjectList l = m_pgRootGroup.GetGroups(true); int iStart = (int)l.UCount - 1; for(int i = iStart; i >= 0; --i) { PwGroup pg = l.GetAt((uint)i); if((pg.Groups.UCount > 0) || (pg.Entries.UCount > 0)) continue; pg.ParentGroup.Groups.Remove(pg); m_vDeletedObjects.Add(new PwDeletedObject(pg.Uuid, DateTime.UtcNow)); ++uDeleted; } return uDeleted; } public uint DeleteUnusedCustomIcons() { List lToDelete = new List(); foreach(PwCustomIcon pwci in m_vCustomIcons) lToDelete.Add(pwci.Uuid); GroupHandler gh = delegate(PwGroup pg) { PwUuid pwUuid = pg.CustomIconUuid; if((pwUuid == null) || pwUuid.Equals(PwUuid.Zero)) return true; for(int i = 0; i < lToDelete.Count; ++i) { if(lToDelete[i].Equals(pwUuid)) { lToDelete.RemoveAt(i); break; } } return true; }; EntryHandler eh = delegate(PwEntry pe) { PwUuid pwUuid = pe.CustomIconUuid; if((pwUuid == null) || pwUuid.Equals(PwUuid.Zero)) return true; for(int i = 0; i < lToDelete.Count; ++i) { if(lToDelete[i].Equals(pwUuid)) { lToDelete.RemoveAt(i); break; } } return true; }; gh(m_pgRootGroup); m_pgRootGroup.TraverseTree(TraversalMethod.PreOrder, gh, eh); uint uDeleted = 0; foreach(PwUuid pwDel in lToDelete) { int nIndex = GetCustomIconIndex(pwDel); if(nIndex < 0) { Debug.Assert(false); continue; } m_vCustomIcons.RemoveAt(nIndex); ++uDeleted; } if(uDeleted > 0) m_bUINeedsIconUpdate = true; return uDeleted; } } } KeePassLib/Utility/0000775000000000000000000000000013222430402013173 5ustar rootrootKeePassLib/Utility/UrlUtil.cs0000664000000000000000000005540413222430402015132 0ustar rootroot/* KeePass Password Safe - The Open-Source Password Manager Copyright (C) 2003-2018 Dominik Reichl This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ using System; using System.Collections.Generic; using System.Diagnostics; using System.Globalization; using System.IO; using System.Text; using KeePassLib.Native; namespace KeePassLib.Utility { /// /// A class containing various static path utility helper methods (like /// stripping extension from a file, etc.). /// public static class UrlUtil { private static readonly char[] m_vDirSeps = new char[] { '\\', '/', UrlUtil.LocalDirSepChar }; private static readonly char[] m_vPathTrimCharsWs = new char[] { '\"', ' ', '\t', '\r', '\n' }; public static char LocalDirSepChar { get { return Path.DirectorySeparatorChar; } } /// /// Get the directory (path) of a file name. The returned string may be /// terminated by a directory separator character. Example: /// passing C:\\My Documents\\My File.kdb in /// and true to /// would produce this string: C:\\My Documents\\. /// /// Full path of a file. /// Append a terminating directory separator /// character to the returned path. /// If true, the returned path /// is guaranteed to be a valid directory path (for example X:\\ instead /// of X:, overriding ). /// This should only be set to true, if the returned path is directly /// passed to some directory API. /// Directory of the file. public static string GetFileDirectory(string strFile, bool bAppendTerminatingChar, bool bEnsureValidDirSpec) { Debug.Assert(strFile != null); if(strFile == null) throw new ArgumentNullException("strFile"); int nLastSep = strFile.LastIndexOfAny(m_vDirSeps); if(nLastSep < 0) return string.Empty; // No directory if(bEnsureValidDirSpec && (nLastSep == 2) && (strFile[1] == ':') && (strFile[2] == '\\')) // Length >= 3 and Windows root directory bAppendTerminatingChar = true; if(!bAppendTerminatingChar) return strFile.Substring(0, nLastSep); return EnsureTerminatingSeparator(strFile.Substring(0, nLastSep), (strFile[nLastSep] == '/')); } /// /// Gets the file name of the specified file (full path). Example: /// if is C:\\My Documents\\My File.kdb /// the returned string is My File.kdb. /// /// Full path of a file. /// File name of the specified file. The return value is /// an empty string ("") if the input parameter is null. public static string GetFileName(string strPath) { Debug.Assert(strPath != null); if(strPath == null) throw new ArgumentNullException("strPath"); int nLastSep = strPath.LastIndexOfAny(m_vDirSeps); if(nLastSep < 0) return strPath; if(nLastSep >= (strPath.Length - 1)) return string.Empty; return strPath.Substring(nLastSep + 1); } /// /// Strip the extension of a file. /// /// Full path of a file with extension. /// File name without extension. public static string StripExtension(string strPath) { Debug.Assert(strPath != null); if(strPath == null) throw new ArgumentNullException("strPath"); int nLastDirSep = strPath.LastIndexOfAny(m_vDirSeps); int nLastExtDot = strPath.LastIndexOf('.'); if(nLastExtDot <= nLastDirSep) return strPath; return strPath.Substring(0, nLastExtDot); } /// /// Get the extension of a file. /// /// Full path of a file with extension. /// Extension without prepending dot. public static string GetExtension(string strPath) { Debug.Assert(strPath != null); if(strPath == null) throw new ArgumentNullException("strPath"); int nLastDirSep = strPath.LastIndexOfAny(m_vDirSeps); int nLastExtDot = strPath.LastIndexOf('.'); if(nLastExtDot <= nLastDirSep) return string.Empty; if(nLastExtDot == (strPath.Length - 1)) return string.Empty; return strPath.Substring(nLastExtDot + 1); } /// /// Ensure that a path is terminated with a directory separator character. /// /// Input path. /// If true, a slash (/) is appended to /// the string if it's not terminated already. If false, the /// default system directory separator character is used. /// Path having a directory separator as last character. public static string EnsureTerminatingSeparator(string strPath, bool bUrl) { Debug.Assert(strPath != null); if(strPath == null) throw new ArgumentNullException("strPath"); int nLength = strPath.Length; if(nLength <= 0) return string.Empty; char chLast = strPath[nLength - 1]; for(int i = 0; i < m_vDirSeps.Length; ++i) { if(chLast == m_vDirSeps[i]) return strPath; } if(bUrl) return (strPath + '/'); return (strPath + UrlUtil.LocalDirSepChar); } /* /// /// File access mode enumeration. Used by the FileAccessible /// method. /// public enum FileAccessMode { /// /// Opening a file in read mode. The specified file must exist. /// Read = 0, /// /// Opening a file in create mode. If the file exists already, it /// will be overwritten. If it doesn't exist, it will be created. /// The return value is true, if data can be written to the /// file. /// Create } */ /* /// /// Test if a specified path is accessible, either in read or write mode. /// /// Path to test. /// Requested file access mode. /// Returns true if the specified path is accessible in /// the requested mode, otherwise the return value is false. public static bool FileAccessible(string strFilePath, FileAccessMode fMode) { Debug.Assert(strFilePath != null); if(strFilePath == null) throw new ArgumentNullException("strFilePath"); if(fMode == FileAccessMode.Read) { FileStream fs; try { fs = File.OpenRead(strFilePath); } catch(Exception) { return false; } if(fs == null) return false; fs.Close(); return true; } else if(fMode == FileAccessMode.Create) { FileStream fs; try { fs = File.Create(strFilePath); } catch(Exception) { return false; } if(fs == null) return false; fs.Close(); return true; } return false; } */ public static string GetQuotedAppPath(string strPath) { if(strPath == null) { Debug.Assert(false); return string.Empty; } // int nFirst = strPath.IndexOf('\"'); // int nSecond = strPath.IndexOf('\"', nFirst + 1); // if((nFirst >= 0) && (nSecond >= 0)) // return strPath.Substring(nFirst + 1, nSecond - nFirst - 1); // return strPath; string str = strPath.Trim(); if(str.Length <= 1) return str; if(str[0] != '\"') return str; int iSecond = str.IndexOf('\"', 1); if(iSecond <= 0) return str; return str.Substring(1, iSecond - 1); } public static string FileUrlToPath(string strUrl) { Debug.Assert(strUrl != null); if(strUrl == null) throw new ArgumentNullException("strUrl"); string str = strUrl; if(str.StartsWith(@"file:///", StrUtil.CaseIgnoreCmp)) str = str.Substring(8, str.Length - 8); str = str.Replace('/', UrlUtil.LocalDirSepChar); return str; } public static bool UnhideFile(string strFile) { #if KeePassLibSD return false; #else if(strFile == null) throw new ArgumentNullException("strFile"); try { FileAttributes fa = File.GetAttributes(strFile); if((long)(fa & FileAttributes.Hidden) == 0) return false; return HideFile(strFile, false); } catch(Exception) { } return false; #endif } public static bool HideFile(string strFile, bool bHide) { #if KeePassLibSD return false; #else if(strFile == null) throw new ArgumentNullException("strFile"); try { FileAttributes fa = File.GetAttributes(strFile); if(bHide) fa = ((fa & ~FileAttributes.Normal) | FileAttributes.Hidden); else // Unhide { fa &= ~FileAttributes.Hidden; if((long)fa == 0) fa = FileAttributes.Normal; } File.SetAttributes(strFile, fa); return true; } catch(Exception) { } return false; #endif } public static string MakeRelativePath(string strBaseFile, string strTargetFile) { if(strBaseFile == null) throw new ArgumentNullException("strBasePath"); if(strTargetFile == null) throw new ArgumentNullException("strTargetPath"); if(strBaseFile.Length == 0) return strTargetFile; if(strTargetFile.Length == 0) return string.Empty; // Test whether on different Windows drives if((strBaseFile.Length >= 3) && (strTargetFile.Length >= 3)) { if((strBaseFile[1] == ':') && (strTargetFile[1] == ':') && (strBaseFile[2] == '\\') && (strTargetFile[2] == '\\') && (strBaseFile[0] != strTargetFile[0])) return strTargetFile; } #if (!KeePassLibSD && !KeePassUAP) if(NativeLib.IsUnix()) { #endif bool bBaseUnc = IsUncPath(strBaseFile); bool bTargetUnc = IsUncPath(strTargetFile); if((!bBaseUnc && bTargetUnc) || (bBaseUnc && !bTargetUnc)) return strTargetFile; string strBase = GetShortestAbsolutePath(strBaseFile); string strTarget = GetShortestAbsolutePath(strTargetFile); string[] vBase = strBase.Split(m_vDirSeps); string[] vTarget = strTarget.Split(m_vDirSeps); int i = 0; while((i < (vBase.Length - 1)) && (i < (vTarget.Length - 1)) && (vBase[i] == vTarget[i])) { ++i; } StringBuilder sbRel = new StringBuilder(); for(int j = i; j < (vBase.Length - 1); ++j) { if(sbRel.Length > 0) sbRel.Append(UrlUtil.LocalDirSepChar); sbRel.Append(".."); } for(int k = i; k < vTarget.Length; ++k) { if(sbRel.Length > 0) sbRel.Append(UrlUtil.LocalDirSepChar); sbRel.Append(vTarget[k]); } return sbRel.ToString(); #if (!KeePassLibSD && !KeePassUAP) } try // Windows { const int nMaxPath = NativeMethods.MAX_PATH * 2; StringBuilder sb = new StringBuilder(nMaxPath + 2); if(NativeMethods.PathRelativePathTo(sb, strBaseFile, 0, strTargetFile, 0) == false) return strTargetFile; string str = sb.ToString(); while(str.StartsWith(".\\")) str = str.Substring(2, str.Length - 2); return str; } catch(Exception) { Debug.Assert(false); } return strTargetFile; #endif } public static string MakeAbsolutePath(string strBaseFile, string strTargetFile) { if(strBaseFile == null) throw new ArgumentNullException("strBasePath"); if(strTargetFile == null) throw new ArgumentNullException("strTargetPath"); if(strBaseFile.Length == 0) return strTargetFile; if(strTargetFile.Length == 0) return string.Empty; if(IsAbsolutePath(strTargetFile)) return strTargetFile; string strBaseDir = GetFileDirectory(strBaseFile, true, false); return GetShortestAbsolutePath(strBaseDir + strTargetFile); } public static bool IsAbsolutePath(string strPath) { if(strPath == null) throw new ArgumentNullException("strPath"); if(strPath.Length == 0) return false; if(IsUncPath(strPath)) return true; try { return Path.IsPathRooted(strPath); } catch(Exception) { Debug.Assert(false); } return true; } public static string GetShortestAbsolutePath(string strPath) { if(strPath == null) throw new ArgumentNullException("strPath"); if(strPath.Length == 0) return string.Empty; // Path.GetFullPath is incompatible with UNC paths traversing over // different server shares (which are created by PathRelativePathTo); // we need to build the absolute path on our own... if(IsUncPath(strPath)) { char chSep = strPath[0]; Debug.Assert(Array.IndexOf(m_vDirSeps, chSep) >= 0); List l = new List(); #if !KeePassLibSD string[] v = strPath.Split(m_vDirSeps, StringSplitOptions.None); #else string[] v = strPath.Split(m_vDirSeps); #endif Debug.Assert((v.Length >= 3) && (v[0].Length == 0) && (v[1].Length == 0)); foreach(string strPart in v) { if(strPart.Equals(".")) continue; else if(strPart.Equals("..")) { if(l.Count > 0) l.RemoveAt(l.Count - 1); else { Debug.Assert(false); } } else l.Add(strPart); // Do not ignore zero length parts } StringBuilder sb = new StringBuilder(); for(int i = 0; i < l.Count; ++i) { // Don't test length of sb, might be 0 due to initial UNC seps if(i > 0) sb.Append(chSep); sb.Append(l[i]); } return sb.ToString(); } string str; try { str = Path.GetFullPath(strPath); } catch(Exception) { Debug.Assert(false); return strPath; } Debug.Assert(str.IndexOf("\\..\\") < 0); foreach(char ch in m_vDirSeps) { string strSep = new string(ch, 1); str = str.Replace(strSep + "." + strSep, strSep); } return str; } public static int GetUrlLength(string strText, int nOffset) { if(strText == null) throw new ArgumentNullException("strText"); if(nOffset > strText.Length) throw new ArgumentException(); // Not >= (0 len) int iPosition = nOffset, nLength = 0, nStrLen = strText.Length; while(iPosition < nStrLen) { char ch = strText[iPosition]; ++iPosition; if((ch == ' ') || (ch == '\t') || (ch == '\r') || (ch == '\n')) break; ++nLength; } return nLength; } public static string RemoveScheme(string strUrl) { if(string.IsNullOrEmpty(strUrl)) return string.Empty; int nNetScheme = strUrl.IndexOf(@"://", StrUtil.CaseIgnoreCmp); int nShScheme = strUrl.IndexOf(@":/", StrUtil.CaseIgnoreCmp); int nSmpScheme = strUrl.IndexOf(@":", StrUtil.CaseIgnoreCmp); if((nNetScheme < 0) && (nShScheme < 0) && (nSmpScheme < 0)) return strUrl; // No scheme int nMin = Math.Min(Math.Min((nNetScheme >= 0) ? nNetScheme : int.MaxValue, (nShScheme >= 0) ? nShScheme : int.MaxValue), (nSmpScheme >= 0) ? nSmpScheme : int.MaxValue); if(nMin == nNetScheme) return strUrl.Substring(nMin + 3); if(nMin == nShScheme) return strUrl.Substring(nMin + 2); return strUrl.Substring(nMin + 1); } public static string ConvertSeparators(string strPath) { return ConvertSeparators(strPath, UrlUtil.LocalDirSepChar); } public static string ConvertSeparators(string strPath, char chSeparator) { if(string.IsNullOrEmpty(strPath)) return string.Empty; strPath = strPath.Replace('/', chSeparator); strPath = strPath.Replace('\\', chSeparator); return strPath; } public static bool IsUncPath(string strPath) { if(strPath == null) throw new ArgumentNullException("strPath"); return (strPath.StartsWith("\\\\") || strPath.StartsWith("//")); } public static string FilterFileName(string strName) { if(strName == null) { Debug.Assert(false); return string.Empty; } string str = strName; str = str.Replace('/', '-'); str = str.Replace('\\', '-'); str = str.Replace(":", string.Empty); str = str.Replace("*", string.Empty); str = str.Replace("?", string.Empty); str = str.Replace("\"", string.Empty); str = str.Replace(@"'", string.Empty); str = str.Replace('<', '('); str = str.Replace('>', ')'); str = str.Replace('|', '-'); return str; } /// /// Get the host component of an URL. /// This method is faster and more fault-tolerant than creating /// an Uri object and querying its Host /// property. /// /// /// For the input s://u:p@d.tld:p/p?q#f the return /// value is d.tld. /// public static string GetHost(string strUrl) { if(strUrl == null) { Debug.Assert(false); return string.Empty; } StringBuilder sb = new StringBuilder(); bool bInExtHost = false; for(int i = 0; i < strUrl.Length; ++i) { char ch = strUrl[i]; if(bInExtHost) { if(ch == '/') { if(sb.Length == 0) { } // Ignore leading '/'s else break; } else sb.Append(ch); } else // !bInExtHost { if(ch == ':') bInExtHost = true; } } string str = sb.ToString(); if(str.Length == 0) str = strUrl; // Remove the login part int nLoginLen = str.IndexOf('@'); if(nLoginLen >= 0) str = str.Substring(nLoginLen + 1); // Remove the port int iPort = str.LastIndexOf(':'); if(iPort >= 0) str = str.Substring(0, iPort); return str; } public static bool AssemblyEquals(string strExt, string strShort) { if((strExt == null) || (strShort == null)) { Debug.Assert(false); return false; } if(strExt.Equals(strShort, StrUtil.CaseIgnoreCmp) || strExt.StartsWith(strShort + ",", StrUtil.CaseIgnoreCmp)) return true; if(!strShort.EndsWith(".dll", StrUtil.CaseIgnoreCmp)) { if(strExt.Equals(strShort + ".dll", StrUtil.CaseIgnoreCmp) || strExt.StartsWith(strShort + ".dll,", StrUtil.CaseIgnoreCmp)) return true; } if(!strShort.EndsWith(".exe", StrUtil.CaseIgnoreCmp)) { if(strExt.Equals(strShort + ".exe", StrUtil.CaseIgnoreCmp) || strExt.StartsWith(strShort + ".exe,", StrUtil.CaseIgnoreCmp)) return true; } return false; } public static string GetTempPath() { string strDir; if(NativeLib.IsUnix()) strDir = NativeMethods.GetUserRuntimeDir(); #if KeePassUAP else strDir = Windows.Storage.ApplicationData.Current.TemporaryFolder.Path; #else else strDir = Path.GetTempPath(); #endif try { if(!Directory.Exists(strDir)) Directory.CreateDirectory(strDir); } catch(Exception) { Debug.Assert(false); } return strDir; } #if !KeePassLibSD // Structurally mostly equivalent to UrlUtil.GetFileInfos public static List GetFilePaths(string strDir, string strPattern, SearchOption opt) { List l = new List(); if(strDir == null) { Debug.Assert(false); return l; } if(strPattern == null) { Debug.Assert(false); return l; } string[] v = Directory.GetFiles(strDir, strPattern, opt); if(v == null) { Debug.Assert(false); return l; } // Only accept files with the correct extension; GetFiles may // return additional files, see GetFiles documentation string strExt = GetExtension(strPattern); if(!string.IsNullOrEmpty(strExt) && (strExt.IndexOf('*') < 0) && (strExt.IndexOf('?') < 0)) { strExt = "." + strExt; foreach(string strPathRaw in v) { if(strPathRaw == null) { Debug.Assert(false); continue; } string strPath = strPathRaw.Trim(m_vPathTrimCharsWs); if(strPath.Length == 0) { Debug.Assert(false); continue; } Debug.Assert(strPath == strPathRaw); if(strPath.EndsWith(strExt, StrUtil.CaseIgnoreCmp)) l.Add(strPathRaw); } } else l.AddRange(v); return l; } // Structurally mostly equivalent to UrlUtil.GetFilePaths public static List GetFileInfos(DirectoryInfo di, string strPattern, SearchOption opt) { List l = new List(); if(di == null) { Debug.Assert(false); return l; } if(strPattern == null) { Debug.Assert(false); return l; } FileInfo[] v = di.GetFiles(strPattern, opt); if(v == null) { Debug.Assert(false); return l; } // Only accept files with the correct extension; GetFiles may // return additional files, see GetFiles documentation string strExt = GetExtension(strPattern); if(!string.IsNullOrEmpty(strExt) && (strExt.IndexOf('*') < 0) && (strExt.IndexOf('?') < 0)) { strExt = "." + strExt; foreach(FileInfo fi in v) { if(fi == null) { Debug.Assert(false); continue; } string strPathRaw = fi.FullName; if(strPathRaw == null) { Debug.Assert(false); continue; } string strPath = strPathRaw.Trim(m_vPathTrimCharsWs); if(strPath.Length == 0) { Debug.Assert(false); continue; } Debug.Assert(strPath == strPathRaw); if(strPath.EndsWith(strExt, StrUtil.CaseIgnoreCmp)) l.Add(fi); } } else l.AddRange(v); return l; } #endif /// /// Expand shell variables in a string. /// [0] is the value of %1, etc. /// public static string ExpandShellVariables(string strText, string[] vParams) { if(strText == null) { Debug.Assert(false); return string.Empty; } if(vParams == null) { Debug.Assert(false); vParams = new string[0]; } string str = strText; NumberFormatInfo nfi = NumberFormatInfo.InvariantInfo; for(int i = 0; i <= 9; ++i) { string strPlh = "%" + i.ToString(nfi); string strValue = string.Empty; if((i > 0) && ((i - 1) < vParams.Length)) strValue = (vParams[i - 1] ?? string.Empty); str = str.Replace(strPlh, strValue); if(i == 1) { // %L is replaced by the long version of %1; e.g. // HKEY_CLASSES_ROOT\\IE.AssocFile.URL\\Shell\\Open\\Command str = str.Replace("%L", strValue); str = str.Replace("%l", strValue); } } if(str.IndexOf("%*") >= 0) { StringBuilder sb = new StringBuilder(); foreach(string strValue in vParams) { if(!string.IsNullOrEmpty(strValue)) { if(sb.Length > 0) sb.Append(' '); sb.Append(strValue); } } str = str.Replace("%*", sb.ToString()); } return str; } } } KeePassLib/Utility/TimeUtil.cs0000664000000000000000000003457313222430402015272 0ustar rootroot/* KeePass Password Safe - The Open-Source Password Manager Copyright (C) 2003-2018 Dominik Reichl This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ using System; using System.Collections.Generic; using System.Diagnostics; using System.Globalization; using System.Text; using KeePassLib.Interfaces; namespace KeePassLib.Utility { /// /// Contains various static time structure manipulation and conversion /// routines. /// public static class TimeUtil { /// /// Length of a compressed PW_TIME structure in bytes. /// public const int PwTimeLength = 7; public static readonly DateTime SafeMinValueUtc = new DateTime( DateTime.MinValue.Ticks + TimeSpan.TicksPerDay, DateTimeKind.Utc); public static readonly DateTime SafeMaxValueUtc = new DateTime( DateTime.MaxValue.Ticks - TimeSpan.TicksPerDay, DateTimeKind.Utc); #if !KeePassLibSD private static string m_strDtfStd = null; private static string m_strDtfDate = null; #endif // private static long m_lTicks2PowLess1s = 0; private static DateTime? m_odtUnixRoot = null; public static DateTime UnixRoot { get { if(m_odtUnixRoot.HasValue) return m_odtUnixRoot.Value; DateTime dtRoot = new DateTime(1970, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc); m_odtUnixRoot = dtRoot; return dtRoot; } } /// /// Pack a DateTime object into 5 bytes. Layout: 2 zero bits, /// year 12 bits, month 4 bits, day 5 bits, hour 5 bits, minute 6 /// bits, second 6 bits. /// [Obsolete] public static byte[] PackTime(DateTime dt) { dt = ToLocal(dt, true); byte[] pb = new byte[5]; // Pack time to 5 byte structure: // Byte bits: 11111111 22222222 33333333 44444444 55555555 // Contents : 00YYYYYY YYYYYYMM MMDDDDDH HHHHMMMM MMSSSSSS pb[0] = (byte)((dt.Year >> 6) & 0x3F); pb[1] = (byte)(((dt.Year & 0x3F) << 2) | ((dt.Month >> 2) & 0x03)); pb[2] = (byte)(((dt.Month & 0x03) << 6) | ((dt.Day & 0x1F) << 1) | ((dt.Hour >> 4) & 0x01)); pb[3] = (byte)(((dt.Hour & 0x0F) << 4) | ((dt.Minute >> 2) & 0x0F)); pb[4] = (byte)(((dt.Minute & 0x03) << 6) | (dt.Second & 0x3F)); return pb; } /// /// Unpack a packed time (5 bytes, packed by the PackTime /// member function) to a DateTime object. /// /// Packed time, 5 bytes. /// Unpacked DateTime object. [Obsolete] public static DateTime UnpackTime(byte[] pb) { Debug.Assert((pb != null) && (pb.Length == 5)); if(pb == null) throw new ArgumentNullException("pb"); if(pb.Length != 5) throw new ArgumentException(); int n1 = pb[0], n2 = pb[1], n3 = pb[2], n4 = pb[3], n5 = pb[4]; // Unpack 5 byte structure to date and time int nYear = (n1 << 6) | (n2 >> 2); int nMonth = ((n2 & 0x00000003) << 2) | (n3 >> 6); int nDay = (n3 >> 1) & 0x0000001F; int nHour = ((n3 & 0x00000001) << 4) | (n4 >> 4); int nMinute = ((n4 & 0x0000000F) << 2) | (n5 >> 6); int nSecond = n5 & 0x0000003F; return (new DateTime(nYear, nMonth, nDay, nHour, nMinute, nSecond, DateTimeKind.Local)).ToUniversalTime(); } /// /// Pack a DateTime object into 7 bytes (PW_TIME). /// /// Object to be encoded. /// Packed time, 7 bytes (PW_TIME). [Obsolete] public static byte[] PackPwTime(DateTime dt) { Debug.Assert(PwTimeLength == 7); dt = ToLocal(dt, true); byte[] pb = new byte[7]; pb[0] = (byte)(dt.Year & 0xFF); pb[1] = (byte)(dt.Year >> 8); pb[2] = (byte)dt.Month; pb[3] = (byte)dt.Day; pb[4] = (byte)dt.Hour; pb[5] = (byte)dt.Minute; pb[6] = (byte)dt.Second; return pb; } /// /// Unpack a packed time (7 bytes, PW_TIME) to a DateTime object. /// /// Packed time, 7 bytes. /// Unpacked DateTime object. [Obsolete] public static DateTime UnpackPwTime(byte[] pb) { Debug.Assert(PwTimeLength == 7); Debug.Assert(pb != null); if(pb == null) throw new ArgumentNullException("pb"); Debug.Assert(pb.Length == 7); if(pb.Length != 7) throw new ArgumentException(); return (new DateTime(((int)pb[1] << 8) | (int)pb[0], (int)pb[2], (int)pb[3], (int)pb[4], (int)pb[5], (int)pb[6], DateTimeKind.Local)).ToUniversalTime(); } /// /// Convert a DateTime object to a displayable string. /// /// DateTime object to convert to a string. /// String representing the specified DateTime object. public static string ToDisplayString(DateTime dt) { return ToLocal(dt, true).ToString(); } public static string ToDisplayStringDateOnly(DateTime dt) { return ToLocal(dt, true).ToString("d"); } public static DateTime FromDisplayString(string strDisplay) { DateTime dt; if(FromDisplayStringEx(strDisplay, out dt)) return dt; return DateTime.Now; } public static bool FromDisplayStringEx(string strDisplay, out DateTime dt) { #if KeePassLibSD try { dt = ToLocal(DateTime.Parse(strDisplay), true); return true; } catch(Exception) { } #else if(DateTime.TryParse(strDisplay, out dt)) { dt = ToLocal(dt, true); return true; } // For some custom formats specified using the Control Panel, // DateTime.ToString returns the correct string, but // DateTime.TryParse fails (e.g. for "//dd/MMM/yyyy"); // https://sourceforge.net/p/keepass/discussion/329221/thread/3a225b29/?limit=25&page=1#c6ae if((m_strDtfStd == null) || (m_strDtfDate == null)) { DateTime dtUni = new DateTime(2111, 3, 4, 5, 6, 7, DateTimeKind.Local); m_strDtfStd = DeriveCustomFormat(ToDisplayString(dtUni), dtUni); m_strDtfDate = DeriveCustomFormat(ToDisplayStringDateOnly(dtUni), dtUni); } const DateTimeStyles dts = DateTimeStyles.AllowWhiteSpaces; if(DateTime.TryParseExact(strDisplay, m_strDtfStd, null, dts, out dt)) { dt = ToLocal(dt, true); return true; } if(DateTime.TryParseExact(strDisplay, m_strDtfDate, null, dts, out dt)) { dt = ToLocal(dt, true); return true; } #endif Debug.Assert(false); return false; } #if !KeePassLibSD private static string DeriveCustomFormat(string strDT, DateTime dt) { string[] vPlh = new string[] { // Names, sorted by length "MMMM", "dddd", "MMM", "ddd", "gg", "g", // Numbers, the ones with prefix '0' first "yyyy", "yyy", "yy", "y", "MM", "M", "dd", "d", "HH", "hh", "H", "h", "mm", "m", "ss", "s", "tt", "t" }; List lValues = new List(); foreach(string strPlh in vPlh) { string strEval = strPlh; if(strEval.Length == 1) strEval = @"%" + strPlh; // Make custom lValues.Add(dt.ToString(strEval)); } StringBuilder sbAll = new StringBuilder(); sbAll.Append("dfFghHKmMstyz:/\"\'\\%"); sbAll.Append(strDT); foreach(string strVEnum in lValues) { sbAll.Append(strVEnum); } List lCodes = new List(); for(int i = 0; i < vPlh.Length; ++i) { char ch = StrUtil.GetUnusedChar(sbAll.ToString()); lCodes.Add(ch); sbAll.Append(ch); } string str = strDT; for(int i = 0; i < vPlh.Length; ++i) { string strValue = lValues[i]; if(string.IsNullOrEmpty(strValue)) continue; str = str.Replace(strValue, new string(lCodes[i], 1)); } StringBuilder sbFmt = new StringBuilder(); bool bInLiteral = false; foreach(char ch in str) { int iCode = lCodes.IndexOf(ch); // The escape character doesn't work correctly (e.g. // "dd\\.MM\\.yyyy\\ HH\\:mm\\:ss" doesn't work, but // "dd'.'MM'.'yyyy' 'HH':'mm':'ss" does); use '' instead // if(iCode >= 0) sbFmt.Append(vPlh[iCode]); // else // Literal // { // sbFmt.Append('\\'); // sbFmt.Append(ch); // } if(iCode >= 0) { if(bInLiteral) { sbFmt.Append('\''); bInLiteral = false; } sbFmt.Append(vPlh[iCode]); } else // Literal { if(!bInLiteral) { sbFmt.Append('\''); bInLiteral = true; } sbFmt.Append(ch); } } if(bInLiteral) sbFmt.Append('\''); return sbFmt.ToString(); } #endif public static string SerializeUtc(DateTime dt) { Debug.Assert(dt.Kind != DateTimeKind.Unspecified); string str = ToUtc(dt, false).ToString("s"); if(!str.EndsWith("Z")) str += "Z"; return str; } public static bool TryDeserializeUtc(string str, out DateTime dt) { if(str == null) throw new ArgumentNullException("str"); if(str.EndsWith("Z")) str = str.Substring(0, str.Length - 1); bool bResult = StrUtil.TryParseDateTime(str, out dt); if(bResult) dt = ToUtc(dt, true); return bResult; } public static double SerializeUnix(DateTime dt) { return (ToUtc(dt, false) - TimeUtil.UnixRoot).TotalSeconds; } public static DateTime ConvertUnixTime(double dtUnix) { try { return TimeUtil.UnixRoot.AddSeconds(dtUnix); } catch(Exception) { Debug.Assert(false); } return DateTime.UtcNow; } #if !KeePassLibSD [Obsolete] public static DateTime? ParseUSTextDate(string strDate) { return ParseUSTextDate(strDate, DateTimeKind.Unspecified); } private static string[] m_vUSMonths = null; /// /// Parse a US textual date string, like e.g. "January 02, 2012". /// public static DateTime? ParseUSTextDate(string strDate, DateTimeKind k) { if(strDate == null) { Debug.Assert(false); return null; } if(m_vUSMonths == null) m_vUSMonths = new string[] { "January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December" }; string str = strDate.Trim(); for(int i = 0; i < m_vUSMonths.Length; ++i) { if(str.StartsWith(m_vUSMonths[i], StrUtil.CaseIgnoreCmp)) { str = str.Substring(m_vUSMonths[i].Length); string[] v = str.Split(new char[] { ',', ';' }); if((v == null) || (v.Length != 2)) return null; string strDay = v[0].Trim().TrimStart('0'); int iDay, iYear; if(int.TryParse(strDay, out iDay) && int.TryParse(v[1].Trim(), out iYear)) return new DateTime(iYear, i + 1, iDay, 0, 0, 0, k); else { Debug.Assert(false); return null; } } } return null; } #endif private static readonly DateTime m_dtInvMin = new DateTime(2999, 12, 27, 23, 59, 59, DateTimeKind.Utc); private static readonly DateTime m_dtInvMax = new DateTime(2999, 12, 29, 23, 59, 59, DateTimeKind.Utc); public static int Compare(DateTime dtA, DateTime dtB, bool bUnkIsPast) { Debug.Assert(dtA.Kind == dtB.Kind); if(bUnkIsPast) { // 2999-12-28 23:59:59 in KeePass 1.x means 'unknown'; // expect time zone corruption (twice) // bool bInvA = ((dtA.Year == 2999) && (dtA.Month == 12) && // (dtA.Day >= 27) && (dtA.Day <= 29) && (dtA.Minute == 59) && // (dtA.Second == 59)); // bool bInvB = ((dtB.Year == 2999) && (dtB.Month == 12) && // (dtB.Day >= 27) && (dtB.Day <= 29) && (dtB.Minute == 59) && // (dtB.Second == 59)); // Faster due to internal implementation of DateTime: bool bInvA = ((dtA >= m_dtInvMin) && (dtA <= m_dtInvMax) && (dtA.Minute == 59) && (dtA.Second == 59)); bool bInvB = ((dtB >= m_dtInvMin) && (dtB <= m_dtInvMax) && (dtB.Minute == 59) && (dtB.Second == 59)); if(bInvA) return (bInvB ? 0 : -1); if(bInvB) return 1; } return dtA.CompareTo(dtB); } internal static int CompareLastMod(ITimeLogger tlA, ITimeLogger tlB, bool bUnkIsPast) { if(tlA == null) { Debug.Assert(false); return ((tlB == null) ? 0 : -1); } if(tlB == null) { Debug.Assert(false); return 1; } return Compare(tlA.LastModificationTime, tlB.LastModificationTime, bUnkIsPast); } public static DateTime ToUtc(DateTime dt, bool bUnspecifiedIsUtc) { DateTimeKind k = dt.Kind; if(k == DateTimeKind.Utc) return dt; if(k == DateTimeKind.Local) return dt.ToUniversalTime(); Debug.Assert(k == DateTimeKind.Unspecified); if(bUnspecifiedIsUtc) return new DateTime(dt.Ticks, DateTimeKind.Utc); return dt.ToUniversalTime(); // Unspecified = local } public static DateTime ToLocal(DateTime dt, bool bUnspecifiedIsLocal) { DateTimeKind k = dt.Kind; if(k == DateTimeKind.Local) return dt; if(k == DateTimeKind.Utc) return dt.ToLocalTime(); Debug.Assert(k == DateTimeKind.Unspecified); if(bUnspecifiedIsLocal) return new DateTime(dt.Ticks, DateTimeKind.Local); return dt.ToLocalTime(); // Unspecified = UTC } /* internal static DateTime RoundToMultOf2PowLess1s(DateTime dt) { long l2Pow = m_lTicks2PowLess1s; if(l2Pow == 0) { l2Pow = 1; while(true) { l2Pow <<= 1; if(l2Pow >= TimeSpan.TicksPerSecond) break; } l2Pow >>= 1; m_lTicks2PowLess1s = l2Pow; Debug.Assert(TimeSpan.TicksPerSecond == 10000000L); // .NET Debug.Assert(l2Pow == (1L << 23)); // .NET } long l = dt.Ticks; if((l % l2Pow) == 0L) return dt; // Round down to full second l /= TimeSpan.TicksPerSecond; l *= TimeSpan.TicksPerSecond; // Round up to multiple of l2Pow long l2PowM1 = l2Pow - 1L; l = (l + l2PowM1) & ~l2PowM1; DateTime dtRnd = new DateTime(l, dt.Kind); Debug.Assert((dtRnd.Ticks % l2Pow) == 0L); Debug.Assert(dtRnd.ToString("u") == dt.ToString("u")); return dtRnd; } */ } } KeePassLib/Utility/AppLogEx.cs0000664000000000000000000000544113222430402015205 0ustar rootroot/* KeePass Password Safe - The Open-Source Password Manager Copyright (C) 2003-2018 Dominik Reichl This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ using System; using System.Collections.Generic; using System.Diagnostics; using System.IO; using System.Text; #if !KeePassLibSD using System.IO.Compression; #endif namespace KeePassLib.Utility { /// /// Application-wide logging services. /// public static class AppLogEx { private static StreamWriter m_swOut = null; public static void Open(string strPrefix) { // Logging is not enabled in normal builds of KeePass! /* AppLogEx.Close(); Debug.Assert(strPrefix != null); if(strPrefix == null) strPrefix = "Log"; try { string strDirSep = string.Empty; strDirSep += UrlUtil.LocalDirSepChar; string strTemp = UrlUtil.GetTempPath(); if(!strTemp.EndsWith(strDirSep)) strTemp += strDirSep; string strPath = strTemp + strPrefix + "-"; Debug.Assert(strPath.IndexOf('/') < 0); DateTime dtNow = DateTime.UtcNow; string strTime = dtNow.ToString("s"); strTime = strTime.Replace('T', '-'); strTime = strTime.Replace(':', '-'); strPath += strTime + "-" + Environment.TickCount.ToString( NumberFormatInfo.InvariantInfo) + ".log.gz"; FileStream fsOut = new FileStream(strPath, FileMode.Create, FileAccess.Write, FileShare.None); GZipStream gz = new GZipStream(fsOut, CompressionMode.Compress); m_swOut = new StreamWriter(gz); AppLogEx.Log("Started logging on " + dtNow.ToString("s") + "."); } catch(Exception) { Debug.Assert(false); } */ } public static void Close() { if(m_swOut == null) return; m_swOut.Close(); m_swOut = null; } public static void Log(string strText) { if(m_swOut == null) return; if(strText == null) m_swOut.WriteLine(); else m_swOut.WriteLine(strText); } public static void Log(Exception ex) { if(m_swOut == null) return; if(ex == null) m_swOut.WriteLine(); else m_swOut.WriteLine(ex.ToString()); } } } KeePassLib/Utility/MonoWorkarounds.cs0000664000000000000000000004341313222430402016676 0ustar rootroot/* KeePass Password Safe - The Open-Source Password Manager Copyright (C) 2003-2018 Dominik Reichl This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ #if DEBUG // #define DEBUG_BREAKONFAIL #endif using System; using System.Collections.Generic; using System.ComponentModel; using System.Diagnostics; using System.IO; using System.Reflection; using System.Text; using System.Threading; using System.Xml; #if !KeePassUAP using System.Windows.Forms; #endif using KeePassLib.Native; namespace KeePassLib.Utility { public static class MonoWorkarounds { private const string AppXDoTool = "xdotool"; private static Dictionary g_dForceReq = new Dictionary(); private static Thread g_thFixClip = null; // private static Predicate g_fOwnWindow = null; #if DEBUG_BREAKONFAIL private static DebugBreakTraceListener g_tlBreak = null; #endif private static bool? g_bReq = null; public static bool IsRequired() { if(!g_bReq.HasValue) g_bReq = NativeLib.IsUnix(); return g_bReq.Value; } // 1219: // Mono prepends byte order mark (BOM) to StdIn. // https://sourceforge.net/p/keepass/bugs/1219/ // 1245: // Key events not raised while Alt is down, and nav keys out of order. // https://sourceforge.net/p/keepass/bugs/1245/ // 1254: // NumericUpDown bug: text is drawn below up/down buttons. // https://sourceforge.net/p/keepass/bugs/1254/ // 1354: // Finalizer of NotifyIcon throws on Unity. // See also 1574. // https://sourceforge.net/p/keepass/bugs/1354/ // 1358: // FileDialog crashes when ~/.recently-used is invalid. // https://sourceforge.net/p/keepass/bugs/1358/ // 1366: // Drawing bug when scrolling a RichTextBox. // https://sourceforge.net/p/keepass/bugs/1366/ // 1378: // Mono doesn't implement Microsoft.Win32.SystemEvents events. // https://sourceforge.net/p/keepass/bugs/1378/ // https://github.com/mono/mono/blob/master/mcs/class/System/Microsoft.Win32/SystemEvents.cs // 1418: // Minimizing a form while loading it doesn't work. // https://sourceforge.net/p/keepass/bugs/1418/ // 1468: // Use LibGCrypt for AES-KDF, because Mono's implementations // of RijndaelManaged and AesCryptoServiceProvider are slow. // https://sourceforge.net/p/keepass/bugs/1468/ // 1527: // Timer causes 100% CPU load. // https://sourceforge.net/p/keepass/bugs/1527/ // 1530: // Mono's clipboard functions don't work properly. // https://sourceforge.net/p/keepass/bugs/1530/ // 1574: // Finalizer of NotifyIcon throws on Mac OS X. // See also 1354. // https://sourceforge.net/p/keepass/bugs/1574/ // 1632: // RichTextBox rendering bug for bold/italic text. // https://sourceforge.net/p/keepass/bugs/1632/ // 1690: // Removing items from a list view doesn't work properly. // https://sourceforge.net/p/keepass/bugs/1690/ // 2139: // Shortcut keys are ignored. // https://sourceforge.net/p/keepass/feature-requests/2139/ // 2140: // Explicit control focusing is ignored. // https://sourceforge.net/p/keepass/feature-requests/2140/ // 5795: // Text in input field is incomplete. // https://bugzilla.xamarin.com/show_bug.cgi?id=5795 // https://sourceforge.net/p/keepass/discussion/329220/thread/d23dc88b/ // 10163: // WebRequest GetResponse call missing, breaks WebDAV due to no PUT. // https://bugzilla.xamarin.com/show_bug.cgi?id=10163 // https://sourceforge.net/p/keepass/bugs/1117/ // https://sourceforge.net/p/keepass/discussion/329221/thread/9422258c/ // https://github.com/mono/mono/commit/8e67b8c2fc7cb66bff7816ebf7c1039fb8cfc43b // https://bugzilla.xamarin.com/show_bug.cgi?id=1512 // https://sourceforge.net/p/keepass/patches/89/ // 12525: // PictureBox not rendered when bitmap height >= control height. // https://bugzilla.xamarin.com/show_bug.cgi?id=12525 // https://sourceforge.net/p/keepass/discussion/329220/thread/54f61e9a/ // 100001: // Control locations/sizes are invalid/unexpected. // [NoRef] // 373134: // Control.InvokeRequired doesn't always return the correct value. // https://bugzilla.novell.com/show_bug.cgi?id=373134 // 586901: // RichTextBox doesn't handle Unicode string correctly. // https://bugzilla.novell.com/show_bug.cgi?id=586901 // 620618: // ListView column headers not drawn. // https://bugzilla.novell.com/show_bug.cgi?id=620618 // 649266: // Calling Control.Hide doesn't remove the application from taskbar. // https://bugzilla.novell.com/show_bug.cgi?id=649266 // 686017: // Minimum sizes must be enforced. // https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=686017 // 801414: // Mono recreates the main window incorrectly. // https://bugs.launchpad.net/ubuntu/+source/keepass2/+bug/801414 // 891029: // Increase tab control height and don't use images on tabs. // https://sourceforge.net/projects/keepass/forums/forum/329221/topic/4519750 // https://bugs.launchpad.net/ubuntu/+source/keepass2/+bug/891029 // https://sourceforge.net/p/keepass/bugs/1256/ // https://sourceforge.net/p/keepass/bugs/1566/ // https://sourceforge.net/p/keepass/bugs/1634/ // 836428016: // ListView group header selection unsupported. // https://sourceforge.net/p/keepass/discussion/329221/thread/31dae0f0/ // 2449941153: // RichTextBox doesn't properly escape '}' when generating RTF data. // https://sourceforge.net/p/keepass/discussion/329221/thread/920722a1/ // 3471228285: // Mono requires command line arguments to be encoded differently. // https://sourceforge.net/p/keepass/discussion/329221/thread/cee6bd7d/ // 3574233558: // Problems with minimizing windows, no content rendered. // https://sourceforge.net/p/keepass/discussion/329220/thread/d50a79d6/ public static bool IsRequired(uint uBugID) { if(!MonoWorkarounds.IsRequired()) return false; bool bForce; if(g_dForceReq.TryGetValue(uBugID, out bForce)) return bForce; ulong v = NativeLib.MonoVersion; if(v != 0) { if(uBugID == 10163) return (v >= 0x0002000B00000000UL); // >= 2.11 } return true; } internal static void SetEnabled(string strIDs, bool bEnabled) { if(string.IsNullOrEmpty(strIDs)) return; string[] vIDs = strIDs.Split(new char[] { ',' }); foreach(string strID in vIDs) { if(string.IsNullOrEmpty(strID)) continue; uint uID; if(StrUtil.TryParseUInt(strID.Trim(), out uID)) g_dForceReq[uID] = bEnabled; } } internal static void Initialize() { Terminate(); // g_fOwnWindow = fOwnWindow; if(IsRequired(1530)) { try { ThreadStart ts = new ThreadStart(MonoWorkarounds.FixClipThread); g_thFixClip = new Thread(ts); g_thFixClip.Start(); } catch(Exception) { Debug.Assert(false); } } #if DEBUG_BREAKONFAIL if(IsRequired() && (g_tlBreak == null)) { g_tlBreak = new DebugBreakTraceListener(); Debug.Listeners.Add(g_tlBreak); } #endif } internal static void Terminate() { if(g_thFixClip != null) { try { g_thFixClip.Abort(); } catch(Exception) { Debug.Assert(false); } g_thFixClip = null; } } private static void FixClipThread() { try { #if !KeePassUAP const int msDelay = 250; string strTest = ClipboardU.GetText(); if(strTest == null) return; // No clipboard support // Without XDoTool, the workaround would be applied to // all applications, which may corrupt the clipboard // when it doesn't contain simple text only; // https://sourceforge.net/p/keepass/bugs/1603/#a113 strTest = (NativeLib.RunConsoleApp(AppXDoTool, "help") ?? string.Empty).Trim(); if(strTest.Length == 0) return; Thread.Sleep(msDelay); string strLast = null; while(true) { string str = ClipboardU.GetText(); if(str == null) { Debug.Assert(false); } else if(str != strLast) { if(NeedClipboardWorkaround()) ClipboardU.SetText(str, true); strLast = str; } Thread.Sleep(msDelay); } #endif } catch(ThreadAbortException) { try { Thread.ResetAbort(); } catch(Exception) { Debug.Assert(false); } } catch(Exception) { Debug.Assert(false); } finally { g_thFixClip = null; } } #if !KeePassUAP private static bool NeedClipboardWorkaround() { try { string strHandle = (NativeLib.RunConsoleApp(AppXDoTool, "getactivewindow") ?? string.Empty).Trim(); if(strHandle.Length == 0) { Debug.Assert(false); return false; } // IntPtr h = new IntPtr(long.Parse(strHandle)); long.Parse(strHandle); // Validate // Detection of own windows based on Form.Handle // comparisons doesn't work reliably (Mono's handles // are usually off by 1) // Predicate fOwnWindow = g_fOwnWindow; // if(fOwnWindow != null) // { // if(fOwnWindow(h)) return true; // } // else { Debug.Assert(false); } string strWmClass = (NativeLib.RunConsoleApp("xprop", "-id " + strHandle + " WM_CLASS") ?? string.Empty); if(strWmClass.IndexOf("\"" + PwDefs.ResClass + "\"", StrUtil.CaseIgnoreCmp) >= 0) return true; if(strWmClass.IndexOf("\"Remmina\"", StrUtil.CaseIgnoreCmp) >= 0) return true; } catch(ThreadAbortException) { throw; } catch(Exception) { Debug.Assert(false); } return false; } public static void ApplyTo(Form f) { if(!MonoWorkarounds.IsRequired()) return; if(f == null) { Debug.Assert(false); return; } #if !KeePassLibSD f.HandleCreated += MonoWorkarounds.OnFormHandleCreated; SetWmClass(f); ApplyToControlsRec(f.Controls, f, MonoWorkarounds.ApplyToControl); #endif } public static void Release(Form f) { if(!MonoWorkarounds.IsRequired()) return; if(f == null) { Debug.Assert(false); return; } #if !KeePassLibSD f.HandleCreated -= MonoWorkarounds.OnFormHandleCreated; ApplyToControlsRec(f.Controls, f, MonoWorkarounds.ReleaseControl); #endif } #if !KeePassLibSD private delegate void MwaControlHandler(Control c, Form fContext); private static void ApplyToControlsRec(Control.ControlCollection cc, Form fContext, MwaControlHandler fn) { if(cc == null) { Debug.Assert(false); return; } foreach(Control c in cc) { fn(c, fContext); ApplyToControlsRec(c.Controls, fContext, fn); } } private static void ApplyToControl(Control c, Form fContext) { Button btn = (c as Button); if(btn != null) ApplyToButton(btn, fContext); NumericUpDown nc = (c as NumericUpDown); if((nc != null) && MonoWorkarounds.IsRequired(1254)) { if(nc.TextAlign == HorizontalAlignment.Right) nc.TextAlign = HorizontalAlignment.Left; } } private sealed class MwaHandlerInfo { private readonly Delegate m_fnOrg; // May be null public Delegate FunctionOriginal { get { return m_fnOrg; } } private readonly Delegate m_fnOvr; public Delegate FunctionOverride { get { return m_fnOvr; } } private readonly DialogResult m_dr; public DialogResult Result { get { return m_dr; } } private readonly Form m_fContext; public Form FormContext { get { return m_fContext; } } public MwaHandlerInfo(Delegate fnOrg, Delegate fnOvr, DialogResult dr, Form fContext) { m_fnOrg = fnOrg; m_fnOvr = fnOvr; m_dr = dr; m_fContext = fContext; } } private static EventHandlerList GetEventHandlers(Component c, out object objClickEvent) { FieldInfo fi = typeof(Control).GetField("ClickEvent", // Mono BindingFlags.Static | BindingFlags.NonPublic); if(fi == null) fi = typeof(Control).GetField("EventClick", // .NET BindingFlags.Static | BindingFlags.NonPublic); if(fi == null) { Debug.Assert(false); objClickEvent = null; return null; } objClickEvent = fi.GetValue(null); if(objClickEvent == null) { Debug.Assert(false); return null; } PropertyInfo pi = typeof(Component).GetProperty("Events", BindingFlags.Instance | BindingFlags.NonPublic); return (pi.GetValue(c, null) as EventHandlerList); } private static Dictionary m_dictHandlers = new Dictionary(); private static void ApplyToButton(Button btn, Form fContext) { DialogResult dr = btn.DialogResult; if(dr == DialogResult.None) return; // No workaround required object objClickEvent; EventHandlerList ehl = GetEventHandlers(btn, out objClickEvent); if(ehl == null) { Debug.Assert(false); return; } Delegate fnClick = ehl[objClickEvent]; // May be null EventHandler fnOvr = new EventHandler(MonoWorkarounds.OnButtonClick); m_dictHandlers[btn] = new MwaHandlerInfo(fnClick, fnOvr, dr, fContext); btn.DialogResult = DialogResult.None; if(fnClick != null) ehl.RemoveHandler(objClickEvent, fnClick); ehl[objClickEvent] = fnOvr; } private static void ReleaseControl(Control c, Form fContext) { Button btn = (c as Button); if(btn != null) ReleaseButton(btn, fContext); } private static void ReleaseButton(Button btn, Form fContext) { MwaHandlerInfo hi; m_dictHandlers.TryGetValue(btn, out hi); if(hi == null) return; object objClickEvent; EventHandlerList ehl = GetEventHandlers(btn, out objClickEvent); if(ehl == null) { Debug.Assert(false); return; } ehl.RemoveHandler(objClickEvent, hi.FunctionOverride); if(hi.FunctionOriginal != null) ehl[objClickEvent] = hi.FunctionOriginal; btn.DialogResult = hi.Result; m_dictHandlers.Remove(btn); } private static void OnButtonClick(object sender, EventArgs e) { Button btn = (sender as Button); if(btn == null) { Debug.Assert(false); return; } MwaHandlerInfo hi; m_dictHandlers.TryGetValue(btn, out hi); if(hi == null) { Debug.Assert(false); return; } Form f = hi.FormContext; // Set current dialog result by setting the form's private // variable; the DialogResult property can't be used, // because it raises close events FieldInfo fiRes = typeof(Form).GetField("dialog_result", BindingFlags.Instance | BindingFlags.NonPublic); if(fiRes == null) { Debug.Assert(false); return; } if(f != null) fiRes.SetValue(f, hi.Result); if(hi.FunctionOriginal != null) hi.FunctionOriginal.Method.Invoke(hi.FunctionOriginal.Target, new object[] { btn, e }); // Raise close events, if the click event handler hasn't // reset the dialog result if((f != null) && (f.DialogResult == hi.Result)) f.DialogResult = hi.Result; // Raises close events } private static void SetWmClass(Form f) { NativeMethods.SetWmClass(f, PwDefs.UnixName, PwDefs.ResClass); } private static void OnFormHandleCreated(object sender, EventArgs e) { Form f = (sender as Form); if(f == null) { Debug.Assert(false); return; } if(!f.IsHandleCreated) return; // Prevent infinite loop SetWmClass(f); } /// /// Set the value of the private shown_raised member /// variable of a form. /// /// Previous shown_raised value. internal static bool ExchangeFormShownRaised(Form f, bool bNewValue) { if(f == null) { Debug.Assert(false); return true; } try { FieldInfo fi = typeof(Form).GetField("shown_raised", BindingFlags.Instance | BindingFlags.NonPublic); if(fi == null) { Debug.Assert(false); return true; } bool bPrevious = (bool)fi.GetValue(f); fi.SetValue(f, bNewValue); return bPrevious; } catch(Exception) { Debug.Assert(false); } return true; } #endif /// /// Ensure that the file ~/.recently-used is valid (in order to /// prevent Mono's FileDialog from crashing). /// internal static void EnsureRecentlyUsedValid() { if(!MonoWorkarounds.IsRequired(1358)) return; try { string strFile = Environment.GetFolderPath( Environment.SpecialFolder.Personal); strFile = UrlUtil.EnsureTerminatingSeparator(strFile, false); strFile += ".recently-used"; if(File.Exists(strFile)) { try { // Mono's WriteRecentlyUsedFiles method also loads the // XML file using XmlDocument XmlDocument xd = new XmlDocument(); xd.Load(strFile); } catch(Exception) // The XML file is invalid { File.Delete(strFile); } } } catch(Exception) { Debug.Assert(false); } } #endif // !KeePassUAP #if DEBUG_BREAKONFAIL private sealed class DebugBreakTraceListener : TraceListener { public override void Fail(string message) { Debugger.Break(); } public override void Fail(string message, string detailMessage) { Debugger.Break(); } public override void Write(string message) { } public override void WriteLine(string message) { } } #endif } } KeePassLib/Utility/MessageService.cs0000664000000000000000000003204413222430402016432 0ustar rootroot/* KeePass Password Safe - The Open-Source Password Manager Copyright (C) 2003-2018 Dominik Reichl This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ using System; using System.Collections.Generic; using System.Collections.Specialized; using System.Diagnostics; using System.Text; #if !KeePassUAP using System.Windows.Forms; #endif using KeePassLib.Resources; using KeePassLib.Serialization; namespace KeePassLib.Utility { public sealed class MessageServiceEventArgs : EventArgs { private string m_strTitle = string.Empty; private string m_strText = string.Empty; private MessageBoxButtons m_msgButtons = MessageBoxButtons.OK; private MessageBoxIcon m_msgIcon = MessageBoxIcon.None; public string Title { get { return m_strTitle; } } public string Text { get { return m_strText; } } public MessageBoxButtons Buttons { get { return m_msgButtons; } } public MessageBoxIcon Icon { get { return m_msgIcon; } } public MessageServiceEventArgs() { } public MessageServiceEventArgs(string strTitle, string strText, MessageBoxButtons msgButtons, MessageBoxIcon msgIcon) { m_strTitle = (strTitle ?? string.Empty); m_strText = (strText ?? string.Empty); m_msgButtons = msgButtons; m_msgIcon = msgIcon; } } public static class MessageService { private static volatile uint m_uCurrentMessageCount = 0; #if !KeePassLibSD private const MessageBoxIcon m_mbiInfo = MessageBoxIcon.Information; private const MessageBoxIcon m_mbiWarning = MessageBoxIcon.Warning; private const MessageBoxIcon m_mbiFatal = MessageBoxIcon.Error; private const MessageBoxOptions m_mboRtl = (MessageBoxOptions.RtlReading | MessageBoxOptions.RightAlign); #else private const MessageBoxIcon m_mbiInfo = MessageBoxIcon.Asterisk; private const MessageBoxIcon m_mbiWarning = MessageBoxIcon.Exclamation; private const MessageBoxIcon m_mbiFatal = MessageBoxIcon.Hand; #endif private const MessageBoxIcon m_mbiQuestion = MessageBoxIcon.Question; public static string NewLine { #if !KeePassLibSD get { return Environment.NewLine; } #else get { return "\r\n"; } #endif } public static string NewParagraph { #if !KeePassLibSD get { return Environment.NewLine + Environment.NewLine; } #else get { return "\r\n\r\n"; } #endif } public static uint CurrentMessageCount { get { return m_uCurrentMessageCount; } } #if !KeePassUAP public static event EventHandler MessageShowing; #endif private static string ObjectsToMessage(object[] vLines) { return ObjectsToMessage(vLines, false); } private static string ObjectsToMessage(object[] vLines, bool bFullExceptions) { if(vLines == null) return string.Empty; string strNewPara = MessageService.NewParagraph; StringBuilder sbText = new StringBuilder(); bool bSeparator = false; foreach(object obj in vLines) { if(obj == null) continue; string strAppend = null; Exception exObj = (obj as Exception); string strObj = (obj as string); #if !KeePassLibSD StringCollection scObj = (obj as StringCollection); #endif if(exObj != null) { if(bFullExceptions) strAppend = StrUtil.FormatException(exObj); else if((exObj.Message != null) && (exObj.Message.Length > 0)) strAppend = exObj.Message; } #if !KeePassLibSD else if(scObj != null) { StringBuilder sb = new StringBuilder(); foreach(string strCollLine in scObj) { if(sb.Length > 0) sb.AppendLine(); sb.Append(strCollLine.TrimEnd()); } strAppend = sb.ToString(); } #endif else if(strObj != null) strAppend = strObj; else strAppend = obj.ToString(); if(!string.IsNullOrEmpty(strAppend)) { if(bSeparator) sbText.Append(strNewPara); else bSeparator = true; sbText.Append(strAppend); } } return sbText.ToString(); } #if (!KeePassLibSD && !KeePassUAP) internal static Form GetTopForm() { FormCollection fc = Application.OpenForms; if((fc == null) || (fc.Count == 0)) return null; return fc[fc.Count - 1]; } #endif #if !KeePassUAP internal static DialogResult SafeShowMessageBox(string strText, string strTitle, MessageBoxButtons mb, MessageBoxIcon mi, MessageBoxDefaultButton mdb) { #if KeePassLibSD return MessageBox.Show(strText, strTitle, mb, mi, mdb); #else IWin32Window wnd = null; try { Form f = GetTopForm(); if((f != null) && f.InvokeRequired) return (DialogResult)f.Invoke(new SafeShowMessageBoxInternalDelegate( SafeShowMessageBoxInternal), f, strText, strTitle, mb, mi, mdb); else wnd = f; } catch(Exception) { Debug.Assert(false); } if(wnd == null) { if(StrUtil.RightToLeft) return MessageBox.Show(strText, strTitle, mb, mi, mdb, m_mboRtl); return MessageBox.Show(strText, strTitle, mb, mi, mdb); } try { if(StrUtil.RightToLeft) return MessageBox.Show(wnd, strText, strTitle, mb, mi, mdb, m_mboRtl); return MessageBox.Show(wnd, strText, strTitle, mb, mi, mdb); } catch(Exception) { Debug.Assert(false); } if(StrUtil.RightToLeft) return MessageBox.Show(strText, strTitle, mb, mi, mdb, m_mboRtl); return MessageBox.Show(strText, strTitle, mb, mi, mdb); #endif } #if !KeePassLibSD internal delegate DialogResult SafeShowMessageBoxInternalDelegate(IWin32Window iParent, string strText, string strTitle, MessageBoxButtons mb, MessageBoxIcon mi, MessageBoxDefaultButton mdb); internal static DialogResult SafeShowMessageBoxInternal(IWin32Window iParent, string strText, string strTitle, MessageBoxButtons mb, MessageBoxIcon mi, MessageBoxDefaultButton mdb) { if(StrUtil.RightToLeft) return MessageBox.Show(iParent, strText, strTitle, mb, mi, mdb, m_mboRtl); return MessageBox.Show(iParent, strText, strTitle, mb, mi, mdb); } #endif public static void ShowInfo(params object[] vLines) { ShowInfoEx(null, vLines); } public static void ShowInfoEx(string strTitle, params object[] vLines) { ++m_uCurrentMessageCount; strTitle = (strTitle ?? PwDefs.ShortProductName); string strText = ObjectsToMessage(vLines); if(MessageService.MessageShowing != null) MessageService.MessageShowing(null, new MessageServiceEventArgs( strTitle, strText, MessageBoxButtons.OK, m_mbiInfo)); SafeShowMessageBox(strText, strTitle, MessageBoxButtons.OK, m_mbiInfo, MessageBoxDefaultButton.Button1); --m_uCurrentMessageCount; } public static void ShowWarning(params object[] vLines) { ShowWarningPriv(vLines, false); } internal static void ShowWarningExcp(params object[] vLines) { ShowWarningPriv(vLines, true); } private static void ShowWarningPriv(object[] vLines, bool bFullExceptions) { ++m_uCurrentMessageCount; string strTitle = PwDefs.ShortProductName; string strText = ObjectsToMessage(vLines, bFullExceptions); if(MessageService.MessageShowing != null) MessageService.MessageShowing(null, new MessageServiceEventArgs( strTitle, strText, MessageBoxButtons.OK, m_mbiWarning)); SafeShowMessageBox(strText, strTitle, MessageBoxButtons.OK, m_mbiWarning, MessageBoxDefaultButton.Button1); --m_uCurrentMessageCount; } public static void ShowFatal(params object[] vLines) { ++m_uCurrentMessageCount; string strTitle = PwDefs.ShortProductName + " - " + KLRes.FatalError; string strText = KLRes.FatalErrorText + MessageService.NewParagraph + KLRes.ErrorInClipboard + MessageService.NewParagraph + // Please send it to the KeePass developers. // KLRes.ErrorFeedbackRequest + MessageService.NewParagraph + ObjectsToMessage(vLines); try { string strDetails = ObjectsToMessage(vLines, true); #if KeePassLibSD Clipboard.SetDataObject(strDetails); #else Clipboard.Clear(); Clipboard.SetText(strDetails); #endif } catch(Exception) { Debug.Assert(false); } if(MessageService.MessageShowing != null) MessageService.MessageShowing(null, new MessageServiceEventArgs( strTitle, strText, MessageBoxButtons.OK, m_mbiFatal)); SafeShowMessageBox(strText, strTitle, MessageBoxButtons.OK, m_mbiFatal, MessageBoxDefaultButton.Button1); --m_uCurrentMessageCount; } public static DialogResult Ask(string strText, string strTitle, MessageBoxButtons mbb) { ++m_uCurrentMessageCount; string strTextEx = (strText ?? string.Empty); string strTitleEx = (strTitle ?? PwDefs.ShortProductName); if(MessageService.MessageShowing != null) MessageService.MessageShowing(null, new MessageServiceEventArgs( strTitleEx, strTextEx, mbb, m_mbiQuestion)); DialogResult dr = SafeShowMessageBox(strTextEx, strTitleEx, mbb, m_mbiQuestion, MessageBoxDefaultButton.Button1); --m_uCurrentMessageCount; return dr; } public static bool AskYesNo(string strText, string strTitle, bool bDefaultToYes, MessageBoxIcon mbi) { ++m_uCurrentMessageCount; string strTextEx = (strText ?? string.Empty); string strTitleEx = (strTitle ?? PwDefs.ShortProductName); if(MessageService.MessageShowing != null) MessageService.MessageShowing(null, new MessageServiceEventArgs( strTitleEx, strTextEx, MessageBoxButtons.YesNo, mbi)); DialogResult dr = SafeShowMessageBox(strTextEx, strTitleEx, MessageBoxButtons.YesNo, mbi, bDefaultToYes ? MessageBoxDefaultButton.Button1 : MessageBoxDefaultButton.Button2); --m_uCurrentMessageCount; return (dr == DialogResult.Yes); } public static bool AskYesNo(string strText, string strTitle, bool bDefaultToYes) { return AskYesNo(strText, strTitle, bDefaultToYes, m_mbiQuestion); } public static bool AskYesNo(string strText, string strTitle) { return AskYesNo(strText, strTitle, true, m_mbiQuestion); } public static bool AskYesNo(string strText) { return AskYesNo(strText, null, true, m_mbiQuestion); } public static void ShowLoadWarning(string strFilePath, Exception ex) { ShowLoadWarning(strFilePath, ex, false); } public static void ShowLoadWarning(string strFilePath, Exception ex, bool bFullException) { ShowWarning(GetLoadWarningMessage(strFilePath, ex, bFullException)); } public static void ShowLoadWarning(IOConnectionInfo ioConnection, Exception ex) { if(ioConnection != null) ShowLoadWarning(ioConnection.GetDisplayName(), ex, false); else ShowWarning(ex); } public static void ShowSaveWarning(string strFilePath, Exception ex, bool bCorruptionWarning) { FileLockException fl = (ex as FileLockException); if(fl != null) { ShowWarning(fl.Message); return; } string str = GetSaveWarningMessage(strFilePath, ex, bCorruptionWarning); ShowWarning(str); } public static void ShowSaveWarning(IOConnectionInfo ioConnection, Exception ex, bool bCorruptionWarning) { if(ioConnection != null) ShowSaveWarning(ioConnection.GetDisplayName(), ex, bCorruptionWarning); else ShowWarning(ex); } #endif // !KeePassUAP internal static string GetLoadWarningMessage(string strFilePath, Exception ex, bool bFullException) { string str = string.Empty; if(!string.IsNullOrEmpty(strFilePath)) str += strFilePath + MessageService.NewParagraph; str += KLRes.FileLoadFailed; if((ex != null) && !string.IsNullOrEmpty(ex.Message)) { str += MessageService.NewParagraph; if(!bFullException) str += ex.Message; else str += ObjectsToMessage(new object[] { ex }, true); } return str; } internal static string GetSaveWarningMessage(string strFilePath, Exception ex, bool bCorruptionWarning) { string str = string.Empty; if(!string.IsNullOrEmpty(strFilePath)) str += strFilePath + MessageService.NewParagraph; str += KLRes.FileSaveFailed; if((ex != null) && !string.IsNullOrEmpty(ex.Message)) str += MessageService.NewParagraph + ex.Message; if(bCorruptionWarning) str += MessageService.NewParagraph + KLRes.FileSaveCorruptionWarning; return str; } public static void ExternalIncrementMessageCount() { ++m_uCurrentMessageCount; } public static void ExternalDecrementMessageCount() { --m_uCurrentMessageCount; } } } KeePassLib/Utility/StrUtil.cs0000664000000000000000000013623013222430402015135 0ustar rootroot/* KeePass Password Safe - The Open-Source Password Manager Copyright (C) 2003-2018 Dominik Reichl This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ using System; using System.Collections; using System.Collections.Generic; using System.Diagnostics; using System.Globalization; using System.IO; using System.Text; using System.Text.RegularExpressions; #if !KeePassUAP using System.Drawing; using System.Security.Cryptography; #endif using KeePassLib.Collections; using KeePassLib.Cryptography.PasswordGenerator; using KeePassLib.Native; using KeePassLib.Security; namespace KeePassLib.Utility { /// /// Character stream class. /// public sealed class CharStream { private string m_strString = string.Empty; private int m_nPos = 0; public CharStream(string str) { Debug.Assert(str != null); if(str == null) throw new ArgumentNullException("str"); m_strString = str; } public void Seek(SeekOrigin org, int nSeek) { if(org == SeekOrigin.Begin) m_nPos = nSeek; else if(org == SeekOrigin.Current) m_nPos += nSeek; else if(org == SeekOrigin.End) m_nPos = m_strString.Length + nSeek; } public char ReadChar() { if(m_nPos < 0) return char.MinValue; if(m_nPos >= m_strString.Length) return char.MinValue; char chRet = m_strString[m_nPos]; ++m_nPos; return chRet; } public char ReadChar(bool bSkipWhiteSpace) { if(bSkipWhiteSpace == false) return ReadChar(); while(true) { char ch = ReadChar(); if((ch != ' ') && (ch != '\t') && (ch != '\r') && (ch != '\n')) return ch; } } public char PeekChar() { if(m_nPos < 0) return char.MinValue; if(m_nPos >= m_strString.Length) return char.MinValue; return m_strString[m_nPos]; } public char PeekChar(bool bSkipWhiteSpace) { if(bSkipWhiteSpace == false) return PeekChar(); int iIndex = m_nPos; while(true) { if(iIndex < 0) return char.MinValue; if(iIndex >= m_strString.Length) return char.MinValue; char ch = m_strString[iIndex]; if((ch != ' ') && (ch != '\t') && (ch != '\r') && (ch != '\n')) return ch; ++iIndex; } } } public enum StrEncodingType { Unknown = 0, Default, Ascii, Utf7, Utf8, Utf16LE, Utf16BE, Utf32LE, Utf32BE } public sealed class StrEncodingInfo { private readonly StrEncodingType m_type; public StrEncodingType Type { get { return m_type; } } private readonly string m_strName; public string Name { get { return m_strName; } } private readonly Encoding m_enc; public Encoding Encoding { get { return m_enc; } } private readonly uint m_cbCodePoint; /// /// Size of a character in bytes. /// public uint CodePointSize { get { return m_cbCodePoint; } } private readonly byte[] m_vSig; /// /// Start signature of the text (byte order mark). /// May be null or empty, if no signature is known. /// public byte[] StartSignature { get { return m_vSig; } } public StrEncodingInfo(StrEncodingType t, string strName, Encoding enc, uint cbCodePoint, byte[] vStartSig) { if(strName == null) throw new ArgumentNullException("strName"); if(enc == null) throw new ArgumentNullException("enc"); if(cbCodePoint <= 0) throw new ArgumentOutOfRangeException("cbCodePoint"); m_type = t; m_strName = strName; m_enc = enc; m_cbCodePoint = cbCodePoint; m_vSig = vStartSig; } } /// /// A class containing various string helper methods. /// public static class StrUtil { public const StringComparison CaseIgnoreCmp = StringComparison.OrdinalIgnoreCase; public static StringComparer CaseIgnoreComparer { get { return StringComparer.OrdinalIgnoreCase; } } private static bool m_bRtl = false; public static bool RightToLeft { get { return m_bRtl; } set { m_bRtl = value; } } private static UTF8Encoding m_encUtf8 = null; public static UTF8Encoding Utf8 { get { if(m_encUtf8 == null) m_encUtf8 = new UTF8Encoding(false, false); return m_encUtf8; } } private static List m_lEncs = null; public static IEnumerable Encodings { get { if(m_lEncs != null) return m_lEncs; List l = new List(); l.Add(new StrEncodingInfo(StrEncodingType.Default, #if KeePassUAP "Unicode (UTF-8)", StrUtil.Utf8, 1, new byte[] { 0xEF, 0xBB, 0xBF })); #else #if !KeePassLibSD Encoding.Default.EncodingName, #else Encoding.Default.WebName, #endif Encoding.Default, (uint)Encoding.Default.GetBytes("a").Length, null)); #endif l.Add(new StrEncodingInfo(StrEncodingType.Ascii, "ASCII", Encoding.ASCII, 1, null)); l.Add(new StrEncodingInfo(StrEncodingType.Utf7, "Unicode (UTF-7)", Encoding.UTF7, 1, null)); l.Add(new StrEncodingInfo(StrEncodingType.Utf8, "Unicode (UTF-8)", StrUtil.Utf8, 1, new byte[] { 0xEF, 0xBB, 0xBF })); l.Add(new StrEncodingInfo(StrEncodingType.Utf16LE, "Unicode (UTF-16 LE)", new UnicodeEncoding(false, false), 2, new byte[] { 0xFF, 0xFE })); l.Add(new StrEncodingInfo(StrEncodingType.Utf16BE, "Unicode (UTF-16 BE)", new UnicodeEncoding(true, false), 2, new byte[] { 0xFE, 0xFF })); #if !KeePassLibSD l.Add(new StrEncodingInfo(StrEncodingType.Utf32LE, "Unicode (UTF-32 LE)", new UTF32Encoding(false, false), 4, new byte[] { 0xFF, 0xFE, 0x0, 0x0 })); l.Add(new StrEncodingInfo(StrEncodingType.Utf32BE, "Unicode (UTF-32 BE)", new UTF32Encoding(true, false), 4, new byte[] { 0x0, 0x0, 0xFE, 0xFF })); #endif m_lEncs = l; return l; } } // public static string RtfPar // { // // get { return (m_bRtl ? "\\rtlpar " : "\\par "); } // get { return "\\par "; } // } // /// // /// Convert a string into a valid RTF string. // /// // /// Any string. // /// RTF-encoded string. // public static string MakeRtfString(string str) // { // Debug.Assert(str != null); if(str == null) throw new ArgumentNullException("str"); // str = str.Replace("\\", "\\\\"); // str = str.Replace("\r", string.Empty); // str = str.Replace("{", "\\{"); // str = str.Replace("}", "\\}"); // str = str.Replace("\n", StrUtil.RtfPar); // StringBuilder sbEncoded = new StringBuilder(); // for(int i = 0; i < str.Length; ++i) // { // char ch = str[i]; // if((int)ch >= 256) // sbEncoded.Append(StrUtil.RtfEncodeChar(ch)); // else sbEncoded.Append(ch); // } // return sbEncoded.ToString(); // } public static string RtfEncodeChar(char ch) { // Unicode character values must be encoded using // 16-bit numbers (decimal); Unicode values greater // than 32767 must be expressed as negative numbers short sh = (short)ch; return ("\\u" + sh.ToString(NumberFormatInfo.InvariantInfo) + "?"); } /// /// Convert a string to a HTML sequence representing that string. /// /// String to convert. /// String, HTML-encoded. public static string StringToHtml(string str) { return StringToHtml(str, false); } internal static string StringToHtml(string str, bool bNbsp) { Debug.Assert(str != null); if(str == null) throw new ArgumentNullException("str"); str = str.Replace(@"&", @"&"); // Must be first str = str.Replace(@"<", @"<"); str = str.Replace(@">", @">"); str = str.Replace("\"", @"""); str = str.Replace("\'", @"'"); if(bNbsp) str = str.Replace(" ", @" "); // Before
str = NormalizeNewLines(str, false); str = str.Replace("\n", @"
" + MessageService.NewLine); return str; } public static string XmlToString(string str) { Debug.Assert(str != null); if(str == null) throw new ArgumentNullException("str"); str = str.Replace(@"&", @"&"); str = str.Replace(@"<", @"<"); str = str.Replace(@">", @">"); str = str.Replace(@""", "\""); str = str.Replace(@"'", "\'"); return str; } public static string ReplaceCaseInsensitive(string strString, string strFind, string strNew) { Debug.Assert(strString != null); if(strString == null) return strString; Debug.Assert(strFind != null); if(strFind == null) return strString; Debug.Assert(strNew != null); if(strNew == null) return strString; string str = strString; int nPos = 0; while(nPos < str.Length) { nPos = str.IndexOf(strFind, nPos, StringComparison.OrdinalIgnoreCase); if(nPos < 0) break; str = str.Remove(nPos, strFind.Length); str = str.Insert(nPos, strNew); nPos += strNew.Length; } return str; } /// /// Split up a command line into application and argument. /// /// Command line to split. /// Application path. /// Arguments. public static void SplitCommandLine(string strCmdLine, out string strApp, out string strArgs) { Debug.Assert(strCmdLine != null); if(strCmdLine == null) throw new ArgumentNullException("strCmdLine"); string str = strCmdLine.Trim(); strApp = null; strArgs = null; if(str.StartsWith("\"")) { int nSecond = str.IndexOf('\"', 1); if(nSecond >= 1) { strApp = str.Substring(1, nSecond - 1).Trim(); strArgs = str.Remove(0, nSecond + 1).Trim(); } } if(strApp == null) { int nSpace = str.IndexOf(' '); if(nSpace >= 0) { strApp = str.Substring(0, nSpace); strArgs = str.Remove(0, nSpace).Trim(); } else strApp = strCmdLine; } if(strApp == null) strApp = string.Empty; if(strArgs == null) strArgs = string.Empty; } // /// // /// Initialize an RTF document based on given font face and size. // /// // /// StringBuilder to put the generated RTF into. // /// Face name of the font to use. // /// Size of the font to use. // public static void InitRtf(StringBuilder sb, string strFontFace, float fFontSize) // { // Debug.Assert(sb != null); if(sb == null) throw new ArgumentNullException("sb"); // Debug.Assert(strFontFace != null); if(strFontFace == null) throw new ArgumentNullException("strFontFace"); // sb.Append("{\\rtf1"); // if(m_bRtl) sb.Append("\\fbidis"); // sb.Append("\\ansi\\ansicpg"); // sb.Append(Encoding.Default.CodePage); // sb.Append("\\deff0{\\fonttbl{\\f0\\fswiss MS Sans Serif;}{\\f1\\froman\\fcharset2 Symbol;}{\\f2\\fswiss "); // sb.Append(strFontFace); // sb.Append(";}{\\f3\\fswiss Arial;}}"); // sb.Append("{\\colortbl\\red0\\green0\\blue0;}"); // if(m_bRtl) sb.Append("\\rtldoc"); // sb.Append("\\deflang1031\\pard\\plain\\f2\\cf0 "); // sb.Append("\\fs"); // sb.Append((int)(fFontSize * 2)); // if(m_bRtl) sb.Append("\\rtlpar\\qr\\rtlch "); // } // /// // /// Convert a simple HTML string to an RTF string. // /// // /// Input HTML string. // /// RTF string representing the HTML input string. // public static string SimpleHtmlToRtf(string strHtmlString) // { // StringBuilder sb = new StringBuilder(); // StrUtil.InitRtf(sb, "Microsoft Sans Serif", 8.25f); // sb.Append(" "); // string str = MakeRtfString(strHtmlString); // str = str.Replace("", "\\b "); // str = str.Replace("", "\\b0 "); // str = str.Replace("", "\\i "); // str = str.Replace("", "\\i0 "); // str = str.Replace("", "\\ul "); // str = str.Replace("", "\\ul0 "); // str = str.Replace("
", StrUtil.RtfPar); // sb.Append(str); // return sb.ToString(); // } /// /// Convert a Color to a HTML color identifier string. /// /// Color to convert. /// If this is true, an empty string /// is returned if the color is transparent. /// HTML color identifier string. public static string ColorToUnnamedHtml(Color color, bool bEmptyIfTransparent) { if(bEmptyIfTransparent && (color.A != 255)) return string.Empty; StringBuilder sb = new StringBuilder(); byte bt; sb.Append('#'); bt = (byte)(color.R >> 4); if(bt < 10) sb.Append((char)('0' + bt)); else sb.Append((char)('A' - 10 + bt)); bt = (byte)(color.R & 0x0F); if(bt < 10) sb.Append((char)('0' + bt)); else sb.Append((char)('A' - 10 + bt)); bt = (byte)(color.G >> 4); if(bt < 10) sb.Append((char)('0' + bt)); else sb.Append((char)('A' - 10 + bt)); bt = (byte)(color.G & 0x0F); if(bt < 10) sb.Append((char)('0' + bt)); else sb.Append((char)('A' - 10 + bt)); bt = (byte)(color.B >> 4); if(bt < 10) sb.Append((char)('0' + bt)); else sb.Append((char)('A' - 10 + bt)); bt = (byte)(color.B & 0x0F); if(bt < 10) sb.Append((char)('0' + bt)); else sb.Append((char)('A' - 10 + bt)); return sb.ToString(); } /// /// Format an exception and convert it to a string. /// /// Exception to convert/format. /// String representing the exception. public static string FormatException(Exception excp) { string strText = string.Empty; if(excp.Message != null) strText += excp.Message + MessageService.NewLine; #if !KeePassLibSD if(excp.Source != null) strText += excp.Source + MessageService.NewLine; #endif if(excp.StackTrace != null) strText += excp.StackTrace + MessageService.NewLine; #if !KeePassLibSD #if !KeePassUAP if(excp.TargetSite != null) strText += excp.TargetSite.ToString() + MessageService.NewLine; #endif if(excp.Data != null) { strText += MessageService.NewLine; foreach(DictionaryEntry de in excp.Data) strText += @"'" + de.Key + @"' -> '" + de.Value + @"'" + MessageService.NewLine; } #endif if(excp.InnerException != null) { strText += MessageService.NewLine + "Inner:" + MessageService.NewLine; if(excp.InnerException.Message != null) strText += excp.InnerException.Message + MessageService.NewLine; #if !KeePassLibSD if(excp.InnerException.Source != null) strText += excp.InnerException.Source + MessageService.NewLine; #endif if(excp.InnerException.StackTrace != null) strText += excp.InnerException.StackTrace + MessageService.NewLine; #if !KeePassLibSD #if !KeePassUAP if(excp.InnerException.TargetSite != null) strText += excp.InnerException.TargetSite.ToString(); #endif if(excp.InnerException.Data != null) { strText += MessageService.NewLine; foreach(DictionaryEntry de in excp.InnerException.Data) strText += @"'" + de.Key + @"' -> '" + de.Value + @"'" + MessageService.NewLine; } #endif } return strText; } public static bool TryParseUShort(string str, out ushort u) { #if !KeePassLibSD return ushort.TryParse(str, out u); #else try { u = ushort.Parse(str); return true; } catch(Exception) { u = 0; return false; } #endif } public static bool TryParseInt(string str, out int n) { #if !KeePassLibSD return int.TryParse(str, out n); #else try { n = int.Parse(str); return true; } catch(Exception) { n = 0; } return false; #endif } public static bool TryParseIntInvariant(string str, out int n) { #if !KeePassLibSD return int.TryParse(str, NumberStyles.Integer, NumberFormatInfo.InvariantInfo, out n); #else try { n = int.Parse(str, NumberStyles.Integer, NumberFormatInfo.InvariantInfo); return true; } catch(Exception) { n = 0; } return false; #endif } public static bool TryParseUInt(string str, out uint u) { #if !KeePassLibSD return uint.TryParse(str, out u); #else try { u = uint.Parse(str); return true; } catch(Exception) { u = 0; } return false; #endif } public static bool TryParseUIntInvariant(string str, out uint u) { #if !KeePassLibSD return uint.TryParse(str, NumberStyles.Integer, NumberFormatInfo.InvariantInfo, out u); #else try { u = uint.Parse(str, NumberStyles.Integer, NumberFormatInfo.InvariantInfo); return true; } catch(Exception) { u = 0; } return false; #endif } public static bool TryParseLong(string str, out long n) { #if !KeePassLibSD return long.TryParse(str, out n); #else try { n = long.Parse(str); return true; } catch(Exception) { n = 0; } return false; #endif } public static bool TryParseLongInvariant(string str, out long n) { #if !KeePassLibSD return long.TryParse(str, NumberStyles.Integer, NumberFormatInfo.InvariantInfo, out n); #else try { n = long.Parse(str, NumberStyles.Integer, NumberFormatInfo.InvariantInfo); return true; } catch(Exception) { n = 0; } return false; #endif } public static bool TryParseULong(string str, out ulong u) { #if !KeePassLibSD return ulong.TryParse(str, out u); #else try { u = ulong.Parse(str); return true; } catch(Exception) { u = 0; } return false; #endif } public static bool TryParseULongInvariant(string str, out ulong u) { #if !KeePassLibSD return ulong.TryParse(str, NumberStyles.Integer, NumberFormatInfo.InvariantInfo, out u); #else try { u = ulong.Parse(str, NumberStyles.Integer, NumberFormatInfo.InvariantInfo); return true; } catch(Exception) { u = 0; } return false; #endif } public static bool TryParseDateTime(string str, out DateTime dt) { #if !KeePassLibSD return DateTime.TryParse(str, out dt); #else try { dt = DateTime.Parse(str); return true; } catch(Exception) { dt = DateTime.UtcNow; } return false; #endif } public static string CompactString3Dots(string strText, int nMaxChars) { Debug.Assert(strText != null); if(strText == null) throw new ArgumentNullException("strText"); Debug.Assert(nMaxChars >= 0); if(nMaxChars < 0) throw new ArgumentOutOfRangeException("nMaxChars"); if(nMaxChars == 0) return string.Empty; if(strText.Length <= nMaxChars) return strText; if(nMaxChars <= 3) return strText.Substring(0, nMaxChars); return strText.Substring(0, nMaxChars - 3) + "..."; } public static string GetStringBetween(string strText, int nStartIndex, string strStart, string strEnd) { int nTemp; return GetStringBetween(strText, nStartIndex, strStart, strEnd, out nTemp); } public static string GetStringBetween(string strText, int nStartIndex, string strStart, string strEnd, out int nInnerStartIndex) { if(strText == null) throw new ArgumentNullException("strText"); if(strStart == null) throw new ArgumentNullException("strStart"); if(strEnd == null) throw new ArgumentNullException("strEnd"); nInnerStartIndex = -1; int nIndex = strText.IndexOf(strStart, nStartIndex); if(nIndex < 0) return string.Empty; nIndex += strStart.Length; int nEndIndex = strText.IndexOf(strEnd, nIndex); if(nEndIndex < 0) return string.Empty; nInnerStartIndex = nIndex; return strText.Substring(nIndex, nEndIndex - nIndex); } /// /// Removes all characters that are not valid XML characters, /// according to https://www.w3.org/TR/xml/#charsets . /// /// Source text. /// Text containing only valid XML characters. public static string SafeXmlString(string strText) { Debug.Assert(strText != null); // No throw if(string.IsNullOrEmpty(strText)) return strText; int nLength = strText.Length; StringBuilder sb = new StringBuilder(nLength); for(int i = 0; i < nLength; ++i) { char ch = strText[i]; if(((ch >= '\u0020') && (ch <= '\uD7FF')) || (ch == '\u0009') || (ch == '\u000A') || (ch == '\u000D') || ((ch >= '\uE000') && (ch <= '\uFFFD'))) sb.Append(ch); else if((ch >= '\uD800') && (ch <= '\uDBFF')) // High surrogate { if((i + 1) < nLength) { char chLow = strText[i + 1]; if((chLow >= '\uDC00') && (chLow <= '\uDFFF')) // Low sur. { sb.Append(ch); sb.Append(chLow); ++i; } else { Debug.Assert(false); } // Low sur. invalid } else { Debug.Assert(false); } // Low sur. missing } Debug.Assert((ch < '\uDC00') || (ch > '\uDFFF')); // Lonely low sur. } return sb.ToString(); } /* private static Regex g_rxNaturalSplit = null; public static int CompareNaturally(string strX, string strY) { Debug.Assert(strX != null); if(strX == null) throw new ArgumentNullException("strX"); Debug.Assert(strY != null); if(strY == null) throw new ArgumentNullException("strY"); if(NativeMethods.SupportsStrCmpNaturally) return NativeMethods.StrCmpNaturally(strX, strY); if(g_rxNaturalSplit == null) g_rxNaturalSplit = new Regex(@"([0-9]+)", RegexOptions.Compiled); string[] vPartsX = g_rxNaturalSplit.Split(strX); string[] vPartsY = g_rxNaturalSplit.Split(strY); int n = Math.Min(vPartsX.Length, vPartsY.Length); for(int i = 0; i < n; ++i) { string strPartX = vPartsX[i], strPartY = vPartsY[i]; int iPartCompare; #if KeePassLibSD try { ulong uX = ulong.Parse(strPartX); ulong uY = ulong.Parse(strPartY); iPartCompare = uX.CompareTo(uY); } catch(Exception) { iPartCompare = string.Compare(strPartX, strPartY, true); } #else ulong uX, uY; if(ulong.TryParse(strPartX, out uX) && ulong.TryParse(strPartY, out uY)) iPartCompare = uX.CompareTo(uY); else iPartCompare = string.Compare(strPartX, strPartY, true); #endif if(iPartCompare != 0) return iPartCompare; } if(vPartsX.Length == vPartsY.Length) return 0; if(vPartsX.Length < vPartsY.Length) return -1; return 1; } */ public static int CompareNaturally(string strX, string strY) { Debug.Assert(strX != null); if(strX == null) throw new ArgumentNullException("strX"); Debug.Assert(strY != null); if(strY == null) throw new ArgumentNullException("strY"); if(NativeMethods.SupportsStrCmpNaturally) return NativeMethods.StrCmpNaturally(strX, strY); int cX = strX.Length; int cY = strY.Length; if(cX == 0) return ((cY == 0) ? 0 : -1); if(cY == 0) return 1; char chFirstX = strX[0]; char chFirstY = strY[0]; bool bExpNum = ((chFirstX >= '0') && (chFirstX <= '9')); bool bExpNumY = ((chFirstY >= '0') && (chFirstY <= '9')); if(bExpNum != bExpNumY) return string.Compare(strX, strY, true); int pX = 0; int pY = 0; while((pX < cX) && (pY < cY)) { Debug.Assert(((strX[pX] >= '0') && (strX[pX] <= '9')) == bExpNum); Debug.Assert(((strY[pY] >= '0') && (strY[pY] <= '9')) == bExpNum); int pExclX = pX + 1; while(pExclX < cX) { char ch = strX[pExclX]; bool bChNum = ((ch >= '0') && (ch <= '9')); if(bChNum != bExpNum) break; ++pExclX; } int pExclY = pY + 1; while(pExclY < cY) { char ch = strY[pExclY]; bool bChNum = ((ch >= '0') && (ch <= '9')); if(bChNum != bExpNum) break; ++pExclY; } string strPartX = strX.Substring(pX, pExclX - pX); string strPartY = strY.Substring(pY, pExclY - pY); bool bStrCmp = true; if(bExpNum) { // 2^64 - 1 = 18446744073709551615 has length 20 if((strPartX.Length <= 19) && (strPartY.Length <= 19)) { ulong uX, uY; if(ulong.TryParse(strPartX, out uX) && ulong.TryParse(strPartY, out uY)) { if(uX < uY) return -1; if(uX > uY) return 1; bStrCmp = false; } else { Debug.Assert(false); } } else { double dX, dY; if(double.TryParse(strPartX, out dX) && double.TryParse(strPartY, out dY)) { if(dX < dY) return -1; if(dX > dY) return 1; bStrCmp = false; } else { Debug.Assert(false); } } } if(bStrCmp) { int c = string.Compare(strPartX, strPartY, true); if(c != 0) return c; } bExpNum = !bExpNum; pX = pExclX; pY = pExclY; } if(pX >= cX) { Debug.Assert(pX == cX); if(pY >= cY) { Debug.Assert(pY == cY); return 0; } return -1; } Debug.Assert(pY == cY); return 1; } public static string RemoveAccelerator(string strMenuText) { if(strMenuText == null) throw new ArgumentNullException("strMenuText"); string str = strMenuText; for(char ch = 'A'; ch <= 'Z'; ++ch) { string strEnhAcc = @"(&" + ch.ToString() + @")"; if(str.IndexOf(strEnhAcc) >= 0) { str = str.Replace(@" " + strEnhAcc, string.Empty); str = str.Replace(strEnhAcc, string.Empty); } } str = str.Replace(@"&", string.Empty); return str; } public static string AddAccelerator(string strMenuText, List lAvailKeys) { if(strMenuText == null) { Debug.Assert(false); return null; } if(lAvailKeys == null) { Debug.Assert(false); return strMenuText; } int xa = -1, xs = 0; for(int i = 0; i < strMenuText.Length; ++i) { char ch = strMenuText[i]; #if KeePassLibSD char chUpper = char.ToUpper(ch); #else char chUpper = char.ToUpperInvariant(ch); #endif xa = lAvailKeys.IndexOf(chUpper); if(xa >= 0) { xs = i; break; } #if KeePassLibSD char chLower = char.ToLower(ch); #else char chLower = char.ToLowerInvariant(ch); #endif xa = lAvailKeys.IndexOf(chLower); if(xa >= 0) { xs = i; break; } } if(xa < 0) return strMenuText; lAvailKeys.RemoveAt(xa); return strMenuText.Insert(xs, @"&"); } public static string EncodeMenuText(string strText) { if(strText == null) throw new ArgumentNullException("strText"); return strText.Replace(@"&", @"&&"); } public static string EncodeToolTipText(string strText) { if(strText == null) throw new ArgumentNullException("strText"); return strText.Replace(@"&", @"&&&"); } public static bool IsHexString(string str, bool bStrict) { if(str == null) throw new ArgumentNullException("str"); foreach(char ch in str) { if((ch >= '0') && (ch <= '9')) continue; if((ch >= 'a') && (ch <= 'f')) continue; if((ch >= 'A') && (ch <= 'F')) continue; if(bStrict) return false; if((ch == ' ') || (ch == '\t') || (ch == '\r') || (ch == '\n')) continue; return false; } return true; } public static bool IsHexString(byte[] pbUtf8, bool bStrict) { if(pbUtf8 == null) throw new ArgumentNullException("pbUtf8"); for(int i = 0; i < pbUtf8.Length; ++i) { byte bt = pbUtf8[i]; if((bt >= (byte)'0') && (bt <= (byte)'9')) continue; if((bt >= (byte)'a') && (bt <= (byte)'f')) continue; if((bt >= (byte)'A') && (bt <= (byte)'F')) continue; if(bStrict) return false; if((bt == (byte)' ') || (bt == (byte)'\t') || (bt == (byte)'\r') || (bt == (byte)'\n')) continue; return false; } return true; } #if !KeePassLibSD private static readonly char[] m_vPatternPartsSep = new char[] { '*' }; public static bool SimplePatternMatch(string strPattern, string strText, StringComparison sc) { if(strPattern == null) throw new ArgumentNullException("strPattern"); if(strText == null) throw new ArgumentNullException("strText"); if(strPattern.IndexOf('*') < 0) return strText.Equals(strPattern, sc); string[] vPatternParts = strPattern.Split(m_vPatternPartsSep, StringSplitOptions.RemoveEmptyEntries); if(vPatternParts == null) { Debug.Assert(false); return true; } if(vPatternParts.Length == 0) return true; if(strText.Length == 0) return false; if(!strPattern.StartsWith(@"*") && !strText.StartsWith(vPatternParts[0], sc)) { return false; } if(!strPattern.EndsWith(@"*") && !strText.EndsWith(vPatternParts[ vPatternParts.Length - 1], sc)) { return false; } int iOffset = 0; for(int i = 0; i < vPatternParts.Length; ++i) { string strPart = vPatternParts[i]; int iFound = strText.IndexOf(strPart, iOffset, sc); if(iFound < iOffset) return false; iOffset = iFound + strPart.Length; if(iOffset == strText.Length) return (i == (vPatternParts.Length - 1)); } return true; } #endif // !KeePassLibSD public static bool StringToBool(string str) { if(string.IsNullOrEmpty(str)) return false; // No assert string s = str.Trim().ToLower(); if(s == "true") return true; if(s == "yes") return true; if(s == "1") return true; if(s == "enabled") return true; if(s == "checked") return true; return false; } public static bool? StringToBoolEx(string str) { if(string.IsNullOrEmpty(str)) return null; string s = str.Trim().ToLower(); if(s == "true") return true; if(s == "false") return false; return null; } public static string BoolToString(bool bValue) { return (bValue ? "true" : "false"); } public static string BoolToStringEx(bool? bValue) { if(bValue.HasValue) return BoolToString(bValue.Value); return "null"; } /// /// Normalize new line characters in a string. Input strings may /// contain mixed new line character sequences from all commonly /// used operating systems (i.e. \r\n from Windows, \n from Unix /// and \r from Mac OS. /// /// String with mixed new line characters. /// If true, new line characters /// are normalized for Windows (\r\n); if false, new line /// characters are normalized for Unix (\n). /// String with normalized new line characters. public static string NormalizeNewLines(string str, bool bWindows) { if(string.IsNullOrEmpty(str)) return str; str = str.Replace("\r\n", "\n"); str = str.Replace("\r", "\n"); if(bWindows) str = str.Replace("\n", "\r\n"); return str; } private static char[] m_vNewLineChars = null; public static void NormalizeNewLines(ProtectedStringDictionary dict, bool bWindows) { if(dict == null) { Debug.Assert(false); return; } if(m_vNewLineChars == null) m_vNewLineChars = new char[]{ '\r', '\n' }; List vKeys = dict.GetKeys(); foreach(string strKey in vKeys) { ProtectedString ps = dict.Get(strKey); if(ps == null) { Debug.Assert(false); continue; } string strValue = ps.ReadString(); if(strValue.IndexOfAny(m_vNewLineChars) < 0) continue; dict.Set(strKey, new ProtectedString(ps.IsProtected, NormalizeNewLines(strValue, bWindows))); } } public static string GetNewLineSeq(string str) { if(str == null) { Debug.Assert(false); return MessageService.NewLine; } int n = str.Length, nLf = 0, nCr = 0, nCrLf = 0; char chLast = char.MinValue; for(int i = 0; i < n; ++i) { char ch = str[i]; if(ch == '\r') ++nCr; else if(ch == '\n') { ++nLf; if(chLast == '\r') ++nCrLf; } chLast = ch; } nCr -= nCrLf; nLf -= nCrLf; int nMax = Math.Max(nCrLf, Math.Max(nCr, nLf)); if(nMax == 0) return MessageService.NewLine; if(nCrLf == nMax) return "\r\n"; return ((nLf == nMax) ? "\n" : "\r"); } public static string AlphaNumericOnly(string str) { if(string.IsNullOrEmpty(str)) return str; StringBuilder sb = new StringBuilder(); for(int i = 0; i < str.Length; ++i) { char ch = str[i]; if(((ch >= 'a') && (ch <= 'z')) || ((ch >= 'A') && (ch <= 'Z')) || ((ch >= '0') && (ch <= '9'))) sb.Append(ch); } return sb.ToString(); } public static string FormatDataSize(ulong uBytes) { const ulong uKB = 1024; const ulong uMB = uKB * uKB; const ulong uGB = uMB * uKB; const ulong uTB = uGB * uKB; if(uBytes == 0) return "0 KB"; if(uBytes <= uKB) return "1 KB"; if(uBytes <= uMB) return (((uBytes - 1UL) / uKB) + 1UL).ToString() + " KB"; if(uBytes <= uGB) return (((uBytes - 1UL) / uMB) + 1UL).ToString() + " MB"; if(uBytes <= uTB) return (((uBytes - 1UL) / uGB) + 1UL).ToString() + " GB"; return (((uBytes - 1UL)/ uTB) + 1UL).ToString() + " TB"; } public static string FormatDataSizeKB(ulong uBytes) { const ulong uKB = 1024; if(uBytes == 0) return "0 KB"; if(uBytes <= uKB) return "1 KB"; return (((uBytes - 1UL) / uKB) + 1UL).ToString() + " KB"; } private static readonly char[] m_vVersionSep = new char[]{ '.', ',' }; public static ulong ParseVersion(string strVersion) { if(strVersion == null) { Debug.Assert(false); return 0; } string[] vVer = strVersion.Split(m_vVersionSep); if((vVer == null) || (vVer.Length == 0)) { Debug.Assert(false); return 0; } ushort uPart; StrUtil.TryParseUShort(vVer[0].Trim(), out uPart); ulong uVer = ((ulong)uPart << 48); if(vVer.Length >= 2) { StrUtil.TryParseUShort(vVer[1].Trim(), out uPart); uVer |= ((ulong)uPart << 32); } if(vVer.Length >= 3) { StrUtil.TryParseUShort(vVer[2].Trim(), out uPart); uVer |= ((ulong)uPart << 16); } if(vVer.Length >= 4) { StrUtil.TryParseUShort(vVer[3].Trim(), out uPart); uVer |= (ulong)uPart; } return uVer; } public static string VersionToString(ulong uVersion) { return VersionToString(uVersion, 1U); } [Obsolete] public static string VersionToString(ulong uVersion, bool bEnsureAtLeastTwoComp) { return VersionToString(uVersion, (bEnsureAtLeastTwoComp ? 2U : 1U)); } public static string VersionToString(ulong uVersion, uint uMinComp) { StringBuilder sb = new StringBuilder(); uint uComp = 0; for(int i = 0; i < 4; ++i) { if(uVersion == 0UL) break; ushort us = (ushort)(uVersion >> 48); if(sb.Length > 0) sb.Append('.'); sb.Append(us.ToString(NumberFormatInfo.InvariantInfo)); ++uComp; uVersion <<= 16; } while(uComp < uMinComp) { if(sb.Length > 0) sb.Append('.'); sb.Append('0'); ++uComp; } return sb.ToString(); } private static readonly byte[] m_pbOptEnt = { 0xA5, 0x74, 0x2E, 0xEC }; public static string EncryptString(string strPlainText) { if(string.IsNullOrEmpty(strPlainText)) return string.Empty; try { byte[] pbPlain = StrUtil.Utf8.GetBytes(strPlainText); byte[] pbEnc = ProtectedData.Protect(pbPlain, m_pbOptEnt, DataProtectionScope.CurrentUser); #if (!KeePassLibSD && !KeePassUAP) return Convert.ToBase64String(pbEnc, Base64FormattingOptions.None); #else return Convert.ToBase64String(pbEnc); #endif } catch(Exception) { Debug.Assert(false); } return strPlainText; } public static string DecryptString(string strCipherText) { if(string.IsNullOrEmpty(strCipherText)) return string.Empty; try { byte[] pbEnc = Convert.FromBase64String(strCipherText); byte[] pbPlain = ProtectedData.Unprotect(pbEnc, m_pbOptEnt, DataProtectionScope.CurrentUser); return StrUtil.Utf8.GetString(pbPlain, 0, pbPlain.Length); } catch(Exception) { Debug.Assert(false); } return strCipherText; } public static string SerializeIntArray(int[] vNumbers) { if(vNumbers == null) throw new ArgumentNullException("vNumbers"); StringBuilder sb = new StringBuilder(); for(int i = 0; i < vNumbers.Length; ++i) { if(i > 0) sb.Append(' '); sb.Append(vNumbers[i].ToString(NumberFormatInfo.InvariantInfo)); } return sb.ToString(); } public static int[] DeserializeIntArray(string strSerialized) { if(strSerialized == null) throw new ArgumentNullException("strSerialized"); if(strSerialized.Length == 0) return new int[0]; string[] vParts = strSerialized.Split(' '); int[] v = new int[vParts.Length]; for(int i = 0; i < vParts.Length; ++i) { int n; if(!TryParseIntInvariant(vParts[i], out n)) { Debug.Assert(false); } v[i] = n; } return v; } private static readonly char[] m_vTagSep = new char[] { ',', ';', ':' }; public static string TagsToString(List vTags, bool bForDisplay) { if(vTags == null) throw new ArgumentNullException("vTags"); StringBuilder sb = new StringBuilder(); bool bFirst = true; foreach(string strTag in vTags) { if(string.IsNullOrEmpty(strTag)) { Debug.Assert(false); continue; } Debug.Assert(strTag.IndexOfAny(m_vTagSep) < 0); if(!bFirst) { if(bForDisplay) sb.Append(", "); else sb.Append(';'); } sb.Append(strTag); bFirst = false; } return sb.ToString(); } public static List StringToTags(string strTags) { if(strTags == null) throw new ArgumentNullException("strTags"); List lTags = new List(); if(strTags.Length == 0) return lTags; string[] vTags = strTags.Split(m_vTagSep); foreach(string strTag in vTags) { string strFlt = strTag.Trim(); if(strFlt.Length > 0) lTags.Add(strFlt); } return lTags; } public static string Obfuscate(string strPlain) { if(strPlain == null) { Debug.Assert(false); return string.Empty; } if(strPlain.Length == 0) return string.Empty; byte[] pb = StrUtil.Utf8.GetBytes(strPlain); Array.Reverse(pb); for(int i = 0; i < pb.Length; ++i) pb[i] = (byte)(pb[i] ^ 0x65); #if (!KeePassLibSD && !KeePassUAP) return Convert.ToBase64String(pb, Base64FormattingOptions.None); #else return Convert.ToBase64String(pb); #endif } public static string Deobfuscate(string strObf) { if(strObf == null) { Debug.Assert(false); return string.Empty; } if(strObf.Length == 0) return string.Empty; try { byte[] pb = Convert.FromBase64String(strObf); for(int i = 0; i < pb.Length; ++i) pb[i] = (byte)(pb[i] ^ 0x65); Array.Reverse(pb); return StrUtil.Utf8.GetString(pb, 0, pb.Length); } catch(Exception) { Debug.Assert(false); } return string.Empty; } /// /// Split a string and include the separators in the splitted array. /// /// String to split. /// Separators. /// Specifies whether separators are /// matched case-sensitively or not. /// Splitted string including separators. public static List SplitWithSep(string str, string[] vSeps, bool bCaseSensitive) { if(str == null) throw new ArgumentNullException("str"); if(vSeps == null) throw new ArgumentNullException("vSeps"); List v = new List(); while(true) { int minIndex = int.MaxValue, minSep = -1; for(int i = 0; i < vSeps.Length; ++i) { string strSep = vSeps[i]; if(string.IsNullOrEmpty(strSep)) { Debug.Assert(false); continue; } int iIndex = (bCaseSensitive ? str.IndexOf(strSep) : str.IndexOf(strSep, StrUtil.CaseIgnoreCmp)); if((iIndex >= 0) && (iIndex < minIndex)) { minIndex = iIndex; minSep = i; } } if(minIndex == int.MaxValue) break; v.Add(str.Substring(0, minIndex)); v.Add(vSeps[minSep]); str = str.Substring(minIndex + vSeps[minSep].Length); } v.Add(str); return v; } public static string MultiToSingleLine(string strMulti) { if(strMulti == null) { Debug.Assert(false); return string.Empty; } if(strMulti.Length == 0) return string.Empty; string str = strMulti; str = str.Replace("\r\n", " "); str = str.Replace("\r", " "); str = str.Replace("\n", " "); return str; } public static List SplitSearchTerms(string strSearch) { List l = new List(); if(strSearch == null) { Debug.Assert(false); return l; } StringBuilder sbTerm = new StringBuilder(); bool bQuoted = false; for(int i = 0; i < strSearch.Length; ++i) { char ch = strSearch[i]; if(((ch == ' ') || (ch == '\t') || (ch == '\r') || (ch == '\n')) && !bQuoted) { if(sbTerm.Length > 0) l.Add(sbTerm.ToString()); sbTerm.Remove(0, sbTerm.Length); } else if(ch == '\"') bQuoted = !bQuoted; else sbTerm.Append(ch); } if(sbTerm.Length > 0) l.Add(sbTerm.ToString()); return l; } public static int CompareLengthGt(string x, string y) { if(x.Length == y.Length) return 0; return ((x.Length > y.Length) ? -1 : 1); } public static bool IsDataUri(string strUri) { return IsDataUri(strUri, null); } public static bool IsDataUri(string strUri, string strReqMimeType) { if(strUri == null) { Debug.Assert(false); return false; } // strReqMimeType may be null const string strPrefix = "data:"; if(!strUri.StartsWith(strPrefix, StrUtil.CaseIgnoreCmp)) return false; int iC = strUri.IndexOf(','); if(iC < 0) return false; if(!string.IsNullOrEmpty(strReqMimeType)) { int iS = strUri.IndexOf(';', 0, iC); int iTerm = ((iS >= 0) ? iS : iC); string strMime = strUri.Substring(strPrefix.Length, iTerm - strPrefix.Length); if(!strMime.Equals(strReqMimeType, StrUtil.CaseIgnoreCmp)) return false; } return true; } /// /// Create a data URI (according to RFC 2397). /// /// Data to encode. /// Optional MIME type. If null, /// an appropriate type is used. /// Data URI. public static string DataToDataUri(byte[] pbData, string strMimeType) { if(pbData == null) throw new ArgumentNullException("pbData"); if(strMimeType == null) strMimeType = "application/octet-stream"; #if (!KeePassLibSD && !KeePassUAP) return ("data:" + strMimeType + ";base64," + Convert.ToBase64String( pbData, Base64FormattingOptions.None)); #else return ("data:" + strMimeType + ";base64," + Convert.ToBase64String( pbData)); #endif } /// /// Convert a data URI (according to RFC 2397) to binary data. /// /// Data URI to decode. /// Decoded binary data. public static byte[] DataUriToData(string strDataUri) { if(strDataUri == null) throw new ArgumentNullException("strDataUri"); if(!strDataUri.StartsWith("data:", StrUtil.CaseIgnoreCmp)) return null; int iSep = strDataUri.IndexOf(','); if(iSep < 0) return null; string strDesc = strDataUri.Substring(5, iSep - 5); bool bBase64 = strDesc.EndsWith(";base64", StrUtil.CaseIgnoreCmp); string strData = strDataUri.Substring(iSep + 1); if(bBase64) return Convert.FromBase64String(strData); MemoryStream ms = new MemoryStream(); Encoding enc = Encoding.ASCII; string[] v = strData.Split('%'); byte[] pb = enc.GetBytes(v[0]); ms.Write(pb, 0, pb.Length); for(int i = 1; i < v.Length; ++i) { ms.WriteByte(Convert.ToByte(v[i].Substring(0, 2), 16)); pb = enc.GetBytes(v[i].Substring(2)); ms.Write(pb, 0, pb.Length); } pb = ms.ToArray(); ms.Close(); return pb; } /// /// Remove placeholders from a string (wrapped in '{' and '}'). /// This doesn't remove environment variables (wrapped in '%'). /// public static string RemovePlaceholders(string str) { if(str == null) { Debug.Assert(false); return string.Empty; } while(true) { int iPlhStart = str.IndexOf('{'); if(iPlhStart < 0) break; int iPlhEnd = str.IndexOf('}', iPlhStart); // '{' might be at end if(iPlhEnd < 0) break; str = (str.Substring(0, iPlhStart) + str.Substring(iPlhEnd + 1)); } return str; } public static StrEncodingInfo GetEncoding(StrEncodingType t) { foreach(StrEncodingInfo sei in StrUtil.Encodings) { if(sei.Type == t) return sei; } return null; } public static StrEncodingInfo GetEncoding(string strName) { foreach(StrEncodingInfo sei in StrUtil.Encodings) { if(sei.Name == strName) return sei; } return null; } private static string[] m_vPrefSepChars = null; /// /// Find a character that does not occur within a given text. /// public static char GetUnusedChar(string strText) { if(strText == null) { Debug.Assert(false); return '@'; } if(m_vPrefSepChars == null) m_vPrefSepChars = new string[5] { "@!$%#/\\:;,.*-_?", PwCharSet.UpperCase, PwCharSet.LowerCase, PwCharSet.Digits, PwCharSet.PrintableAsciiSpecial }; for(int i = 0; i < m_vPrefSepChars.Length; ++i) { foreach(char ch in m_vPrefSepChars[i]) { if(strText.IndexOf(ch) < 0) return ch; } } for(char ch = '\u00C0'; ch < char.MaxValue; ++ch) { if(strText.IndexOf(ch) < 0) return ch; } return char.MinValue; } public static char ByteToSafeChar(byte bt) { const char chDefault = '.'; // 00-1F are C0 control chars if(bt < 0x20) return chDefault; // 20-7F are basic Latin; 7F is DEL if(bt < 0x7F) return (char)bt; // 80-9F are C1 control chars if(bt < 0xA0) return chDefault; // A0-FF are Latin-1 supplement; AD is soft hyphen if(bt == 0xAD) return '-'; return (char)bt; } public static int Count(string str, string strNeedle) { if(str == null) { Debug.Assert(false); return 0; } if(string.IsNullOrEmpty(strNeedle)) { Debug.Assert(false); return 0; } int iOffset = 0, iCount = 0; while(iOffset < str.Length) { int p = str.IndexOf(strNeedle, iOffset); if(p < 0) break; ++iCount; iOffset = p + 1; } return iCount; } internal static string ReplaceNulls(string str) { if(str == null) { Debug.Assert(false); return null; } if(str.IndexOf('\0') < 0) return str; // Replacing null characters by spaces is the // behavior of Notepad (on Windows 10) return str.Replace('\0', ' '); } } } KeePassLib/Utility/GfxUtil.cs0000664000000000000000000002637013222430402015114 0ustar rootroot/* KeePass Password Safe - The Open-Source Password Manager Copyright (C) 2003-2018 Dominik Reichl This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ using System; using System.Collections.Generic; using System.Diagnostics; using System.IO; using System.Text; #if !KeePassUAP using System.Drawing; using System.Drawing.Drawing2D; using System.Drawing.Imaging; #endif namespace KeePassLib.Utility { public static class GfxUtil { #if (!KeePassLibSD && !KeePassUAP) private sealed class GfxImage { public byte[] Data; public int Width; public int Height; public GfxImage(byte[] pbData, int w, int h) { this.Data = pbData; this.Width = w; this.Height = h; } #if DEBUG // For debugger display public override string ToString() { return (this.Width.ToString() + "x" + this.Height.ToString()); } #endif } #endif #if KeePassUAP public static Image LoadImage(byte[] pb) { if(pb == null) throw new ArgumentNullException("pb"); MemoryStream ms = new MemoryStream(pb, false); try { return Image.FromStream(ms); } finally { ms.Close(); } } #else public static Image LoadImage(byte[] pb) { if(pb == null) throw new ArgumentNullException("pb"); #if !KeePassLibSD // First try to load the data as ICO and afterwards as // normal image, because trying to load an ICO using // the normal image loading methods can result in a // low resolution image try { Image imgIco = ExtractBestImageFromIco(pb); if(imgIco != null) return imgIco; } catch(Exception) { Debug.Assert(false); } #endif MemoryStream ms = new MemoryStream(pb, false); try { return LoadImagePriv(ms); } finally { ms.Close(); } } private static Image LoadImagePriv(Stream s) { // Image.FromStream wants the stream to be open during // the whole lifetime of the image; as we can't guarantee // this, we make a copy of the image Image imgSrc = null; try { #if !KeePassLibSD imgSrc = Image.FromStream(s); Bitmap bmp = new Bitmap(imgSrc.Width, imgSrc.Height, PixelFormat.Format32bppArgb); try { bmp.SetResolution(imgSrc.HorizontalResolution, imgSrc.VerticalResolution); Debug.Assert(bmp.Size == imgSrc.Size); } catch(Exception) { Debug.Assert(false); } #else imgSrc = new Bitmap(s); Bitmap bmp = new Bitmap(imgSrc.Width, imgSrc.Height); #endif using(Graphics g = Graphics.FromImage(bmp)) { g.Clear(Color.Transparent); #if !KeePassLibSD g.DrawImageUnscaled(imgSrc, 0, 0); #else g.DrawImage(imgSrc, 0, 0); #endif } return bmp; } finally { if(imgSrc != null) imgSrc.Dispose(); } } #if !KeePassLibSD private static Image ExtractBestImageFromIco(byte[] pb) { List l = UnpackIco(pb); if((l == null) || (l.Count == 0)) return null; long qMax = 0; foreach(GfxImage gi in l) { if(gi.Width == 0) gi.Width = 256; if(gi.Height == 0) gi.Height = 256; qMax = Math.Max(qMax, (long)gi.Width * (long)gi.Height); } byte[] pbHdrPng = new byte[] { 0x89, 0x50, 0x4E, 0x47, 0x0D, 0x0A, 0x1A, 0x0A }; byte[] pbHdrJpeg = new byte[] { 0xFF, 0xD8, 0xFF }; Image imgBest = null; int bppBest = -1; foreach(GfxImage gi in l) { if(((long)gi.Width * (long)gi.Height) < qMax) continue; byte[] pbImg = gi.Data; Image img = null; try { if((pbImg.Length > pbHdrPng.Length) && MemUtil.ArraysEqual(pbHdrPng, MemUtil.Mid(pbImg, 0, pbHdrPng.Length))) img = GfxUtil.LoadImage(pbImg); else if((pbImg.Length > pbHdrJpeg.Length) && MemUtil.ArraysEqual(pbHdrJpeg, MemUtil.Mid(pbImg, 0, pbHdrJpeg.Length))) img = GfxUtil.LoadImage(pbImg); else { using(MemoryStream ms = new MemoryStream(pb, false)) { using(Icon ico = new Icon(ms, gi.Width, gi.Height)) { img = ico.ToBitmap(); } } } } catch(Exception) { Debug.Assert(false); } if(img == null) continue; if((img.Width < gi.Width) || (img.Height < gi.Height)) { Debug.Assert(false); img.Dispose(); continue; } int bpp = GetBitsPerPixel(img.PixelFormat); if(bpp > bppBest) { if(imgBest != null) imgBest.Dispose(); imgBest = img; bppBest = bpp; } else img.Dispose(); } return imgBest; } private static List UnpackIco(byte[] pb) { if(pb == null) { Debug.Assert(false); return null; } const int SizeICONDIR = 6; const int SizeICONDIRENTRY = 16; if(pb.Length < SizeICONDIR) return null; if(MemUtil.BytesToUInt16(pb, 0) != 0) return null; // Reserved, 0 if(MemUtil.BytesToUInt16(pb, 2) != 1) return null; // ICO type, 1 int n = MemUtil.BytesToUInt16(pb, 4); if(n < 0) { Debug.Assert(false); return null; } int cbDir = SizeICONDIR + (n * SizeICONDIRENTRY); if(pb.Length < cbDir) return null; List l = new List(); int iOffset = SizeICONDIR; for(int i = 0; i < n; ++i) { int w = pb[iOffset]; int h = pb[iOffset + 1]; if((w < 0) || (h < 0)) { Debug.Assert(false); return null; } int cb = MemUtil.BytesToInt32(pb, iOffset + 8); if(cb <= 0) return null; // Data must have header (even BMP) int p = MemUtil.BytesToInt32(pb, iOffset + 12); if(p < cbDir) return null; if((p + cb) > pb.Length) return null; try { byte[] pbImage = MemUtil.Mid(pb, p, cb); GfxImage img = new GfxImage(pbImage, w, h); l.Add(img); } catch(Exception) { Debug.Assert(false); return null; } iOffset += SizeICONDIRENTRY; } return l; } private static int GetBitsPerPixel(PixelFormat f) { int bpp = 0; switch(f) { case PixelFormat.Format1bppIndexed: bpp = 1; break; case PixelFormat.Format4bppIndexed: bpp = 4; break; case PixelFormat.Format8bppIndexed: bpp = 8; break; case PixelFormat.Format16bppArgb1555: case PixelFormat.Format16bppGrayScale: case PixelFormat.Format16bppRgb555: case PixelFormat.Format16bppRgb565: bpp = 16; break; case PixelFormat.Format24bppRgb: bpp = 24; break; case PixelFormat.Format32bppArgb: case PixelFormat.Format32bppPArgb: case PixelFormat.Format32bppRgb: bpp = 32; break; case PixelFormat.Format48bppRgb: bpp = 48; break; case PixelFormat.Format64bppArgb: case PixelFormat.Format64bppPArgb: bpp = 64; break; default: Debug.Assert(false); break; } return bpp; } public static Image ScaleImage(Image img, int w, int h) { return ScaleImage(img, w, h, ScaleTransformFlags.None); } /// /// Resize an image. /// /// Image to resize. /// Width of the returned image. /// Height of the returned image. /// Flags to customize scaling behavior. /// Resized image. This object is always different /// from (i.e. they can be /// disposed separately). public static Image ScaleImage(Image img, int w, int h, ScaleTransformFlags f) { if(img == null) throw new ArgumentNullException("img"); if(w < 0) throw new ArgumentOutOfRangeException("w"); if(h < 0) throw new ArgumentOutOfRangeException("h"); bool bUIIcon = ((f & ScaleTransformFlags.UIIcon) != ScaleTransformFlags.None); // We must return a Bitmap object for UIUtil.CreateScaledImage Bitmap bmp = new Bitmap(w, h, PixelFormat.Format32bppArgb); using(Graphics g = Graphics.FromImage(bmp)) { g.Clear(Color.Transparent); g.SmoothingMode = SmoothingMode.HighQuality; g.CompositingQuality = CompositingQuality.HighQuality; int wSrc = img.Width; int hSrc = img.Height; InterpolationMode im = InterpolationMode.HighQualityBicubic; if((wSrc > 0) && (hSrc > 0)) { if(bUIIcon && ((w % wSrc) == 0) && ((h % hSrc) == 0)) im = InterpolationMode.NearestNeighbor; // else if((w < wSrc) && (h < hSrc)) // im = InterpolationMode.HighQualityBilinear; } else { Debug.Assert(false); } g.InterpolationMode = im; RectangleF rSource = new RectangleF(0.0f, 0.0f, wSrc, hSrc); RectangleF rDest = new RectangleF(0.0f, 0.0f, w, h); AdjustScaleRects(ref rSource, ref rDest); g.DrawImage(img, rDest, rSource, GraphicsUnit.Pixel); } return bmp; } internal static void AdjustScaleRects(ref RectangleF rSource, ref RectangleF rDest) { // When enlarging images, apply a -0.5 offset to avoid // the scaled image being cropped on the top/left side; // when shrinking images, do not apply a -0.5 offset, // otherwise the image is cropped on the bottom/right // side; this applies to all interpolation modes if(rDest.Width > rSource.Width) rSource.X = rSource.X - 0.5f; if(rDest.Height > rSource.Height) rSource.Y = rSource.Y - 0.5f; // When shrinking, apply a +0.5 offset, such that the // scaled image is less cropped on the bottom/right side if(rDest.Width < rSource.Width) rSource.X = rSource.X + 0.5f; if(rDest.Height < rSource.Height) rSource.Y = rSource.Y + 0.5f; } #if DEBUG public static Image ScaleTest(Image[] vIcons) { Bitmap bmp = new Bitmap(1024, vIcons.Length * (256 + 12), PixelFormat.Format32bppArgb); using(Graphics g = Graphics.FromImage(bmp)) { g.Clear(Color.White); int[] v = new int[] { 16, 24, 32, 48, 64, 128, 256 }; int x; int y = 8; foreach(Image imgIcon in vIcons) { if(imgIcon == null) { Debug.Assert(false); continue; } x = 128; foreach(int q in v) { using(Image img = ScaleImage(imgIcon, q, q, ScaleTransformFlags.UIIcon)) { g.DrawImageUnscaled(img, x, y); } x += q + 8; } y += v[v.Length - 1] + 8; } } return bmp; } #endif // DEBUG #endif // !KeePassLibSD #endif // KeePassUAP internal static string ImageToDataUri(Image img) { if(img == null) { Debug.Assert(false); return string.Empty; } byte[] pb = null; using(MemoryStream ms = new MemoryStream()) { img.Save(ms, ImageFormat.Png); pb = ms.ToArray(); } return StrUtil.DataToDataUri(pb, "image/png"); } } } KeePassLib/Utility/MemUtil.cs0000664000000000000000000006104413222430402015103 0ustar rootroot/* KeePass Password Safe - The Open-Source Password Manager Copyright (C) 2003-2018 Dominik Reichl This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ using System; using System.Collections.Generic; using System.Diagnostics; using System.IO; using System.Runtime.CompilerServices; using System.Text; #if KeePassLibSD using KeePassLibSD; #else using System.IO.Compression; #endif namespace KeePassLib.Utility { /// /// Contains static buffer manipulation and string conversion routines. /// public static class MemUtil { internal static readonly byte[] EmptyByteArray = new byte[0]; internal static readonly ArrayHelperEx ArrayHelperExOfChar = new ArrayHelperEx(); private static readonly uint[] m_vSBox = new uint[256] { 0xCD2FACB3, 0xE78A7F5C, 0x6F0803FC, 0xBCF6E230, 0x3A321712, 0x06403DB1, 0xD2F84B95, 0xDF22A6E4, 0x07CE9E5B, 0x31788A0C, 0xF683F6F4, 0xEA061F49, 0xFA5C2ACA, 0x4B9E494E, 0xB0AB25BA, 0x767731FC, 0x261893A7, 0x2B09F2CE, 0x046261E4, 0x41367B4B, 0x18A7F225, 0x8F923C0E, 0x5EF3A325, 0x28D0435E, 0x84C22919, 0xED66873C, 0x8CEDE444, 0x7FC47C24, 0xFCFC6BA3, 0x676F928D, 0xB4147187, 0xD8FB126E, 0x7D798D17, 0xFF82E424, 0x1712FA5B, 0xABB09DD5, 0x8156BA63, 0x84E4D969, 0xC937FB9A, 0x2F1E5BFC, 0x178ECA11, 0x0E71CD5F, 0x52AAC6F4, 0x71EEFC8F, 0x7090D749, 0x21CACA31, 0x92996378, 0x0939A8A8, 0xE9EE1934, 0xD2718616, 0xF2500543, 0xB911873C, 0xD3CB3EEC, 0x2BA0DBEB, 0xB42D0A27, 0xECE67C0F, 0x302925F0, 0x6114F839, 0xD39E6307, 0xE28970D6, 0xEB982F99, 0x941B4CDF, 0xC540E550, 0x8124FC45, 0x98B025C7, 0xE2BF90EA, 0x4F57C976, 0xCF546FE4, 0x59566DC8, 0xE3F4360D, 0xF5F9D231, 0xD6180B22, 0xB54E088A, 0xB5DFE6A6, 0x3637A36F, 0x056E9284, 0xAFF8FBC5, 0x19E01648, 0x8611F043, 0xDAE44337, 0xF61B6A1C, 0x257ACD9E, 0xDD35F507, 0xEF05CAFA, 0x05EB4A83, 0xFC25CA92, 0x0A4728E6, 0x9CF150EF, 0xAEEF67DE, 0xA9472337, 0x57C81EFE, 0x3E5E009F, 0x02CB03BB, 0x2BA85674, 0xF21DC251, 0x78C34A34, 0xABB1F5BF, 0xB95A2FBD, 0x1FB47777, 0x9A96E8AC, 0x5D2D2838, 0x55AAC92A, 0x99EE324E, 0x10F6214B, 0x58ABDFB1, 0x2008794D, 0xBEC880F0, 0xE75E5341, 0x88015C34, 0x352D8FBF, 0x622B7F6C, 0xF5C59EA2, 0x1F759D8E, 0xADE56159, 0xCC7B4C25, 0x5B8BC48C, 0xB6BD15AF, 0x3C5B5110, 0xE74A7C3D, 0xEE613161, 0x156A1C67, 0x72C06817, 0xEA0A6F69, 0x4CECF993, 0xCA9D554C, 0x8E20361F, 0x42D396B9, 0x595DE578, 0x749D7955, 0xFD1BA5FD, 0x81FC160E, 0xDB97E28C, 0x7CF148F7, 0x0B0B3CF5, 0x534DE605, 0x46421066, 0xD4B68DD1, 0x9E479CE6, 0xAE667A9D, 0xBC082082, 0xB06DD6EF, 0x20F0F23F, 0xB99E1551, 0xF47A2E3A, 0x71DA50C6, 0x67B65779, 0x2A8CB376, 0x1EA71EEE, 0x29ABCD50, 0xB6EB0C6B, 0x23C10511, 0x6F3F2144, 0x6AF23012, 0xF696BD9E, 0xB94099D8, 0xAD5A9C81, 0x7A0794FA, 0x7EDF59D6, 0x1E72E574, 0x8561913C, 0x4E4D568F, 0xEECB9928, 0x9C124D2E, 0x0848B82C, 0xF1CA395F, 0x9DAF43DC, 0xF77EC323, 0x394E9B59, 0x7E200946, 0x8B811D68, 0x16DA3305, 0xAB8DE2C3, 0xE6C53B64, 0x98C2D321, 0x88A97D81, 0xA7106419, 0x8E52F7BF, 0x8ED262AF, 0x7CCA974E, 0xF0933241, 0x040DD437, 0xE143B3D4, 0x3019F56F, 0xB741521D, 0xF1745362, 0x4C435F9F, 0xB4214D0D, 0x0B0C348B, 0x5051D189, 0x4C30447E, 0x7393D722, 0x95CEDD0B, 0xDD994E80, 0xC3D22ED9, 0x739CD900, 0x131EB9C4, 0xEF1062B2, 0x4F0DE436, 0x52920073, 0x9A7F3D80, 0x896E7B1B, 0x2C8BBE5A, 0xBD304F8A, 0xA993E22C, 0x134C41A0, 0xFA989E00, 0x39CE9726, 0xFB89FCCF, 0xE8FBAC97, 0xD4063FFC, 0x935A2B5A, 0x44C8EE83, 0xCB2BC7B6, 0x02989E92, 0x75478BEA, 0x144378D0, 0xD853C087, 0x8897A34E, 0xDD23629D, 0xBDE2A2A2, 0x581D8ECC, 0x5DA8AEE8, 0xFF8AAFD0, 0xBA2BCF6E, 0x4BD98DAC, 0xF2EDB9E4, 0xFA2DC868, 0x47E84661, 0xECEB1C7D, 0x41705CA4, 0x5982E4D4, 0xEB5204A1, 0xD196CAFB, 0x6414804D, 0x3ABD4B46, 0x8B494C26, 0xB432D52B, 0x39C5356B, 0x6EC80BF7, 0x71BE5483, 0xCEC4A509, 0xE9411D61, 0x52F341E5, 0xD2E6197B, 0x4F02826C, 0xA9E48838, 0xD1F8F247, 0xE4957FB3, 0x586CCA99, 0x9A8B6A5B, 0x4998FBEA, 0xF762BE4C, 0x90DFE33C, 0x9731511E, 0x88C6A82F, 0xDD65A4D4 }; /// /// Convert a hexadecimal string to a byte array. The input string must be /// even (i.e. its length is a multiple of 2). /// /// String containing hexadecimal characters. /// Returns a byte array. Returns null if the string parameter /// was null or is an uneven string (i.e. if its length isn't a /// multiple of 2). /// Thrown if /// is null. public static byte[] HexStringToByteArray(string strHex) { if(strHex == null) { Debug.Assert(false); throw new ArgumentNullException("strHex"); } int nStrLen = strHex.Length; if((nStrLen & 1) != 0) { Debug.Assert(false); return null; } byte[] pb = new byte[nStrLen / 2]; byte bt; char ch; for(int i = 0; i < nStrLen; i += 2) { ch = strHex[i]; if((ch >= '0') && (ch <= '9')) bt = (byte)(ch - '0'); else if((ch >= 'a') && (ch <= 'f')) bt = (byte)(ch - 'a' + 10); else if((ch >= 'A') && (ch <= 'F')) bt = (byte)(ch - 'A' + 10); else { Debug.Assert(false); bt = 0; } bt <<= 4; ch = strHex[i + 1]; if((ch >= '0') && (ch <= '9')) bt += (byte)(ch - '0'); else if((ch >= 'a') && (ch <= 'f')) bt += (byte)(ch - 'a' + 10); else if((ch >= 'A') && (ch <= 'F')) bt += (byte)(ch - 'A' + 10); else { Debug.Assert(false); } pb[i >> 1] = bt; } return pb; } /// /// Convert a byte array to a hexadecimal string. /// /// Input byte array. /// Returns the hexadecimal string representing the byte /// array. Returns null, if the input byte array was null. Returns /// an empty string, if the input byte array has length 0. public static string ByteArrayToHexString(byte[] pbArray) { if(pbArray == null) return null; int nLen = pbArray.Length; if(nLen == 0) return string.Empty; StringBuilder sb = new StringBuilder(); byte bt, btHigh, btLow; for(int i = 0; i < nLen; ++i) { bt = pbArray[i]; btHigh = bt; btHigh >>= 4; btLow = (byte)(bt & 0x0F); if(btHigh >= 10) sb.Append((char)('A' + btHigh - 10)); else sb.Append((char)('0' + btHigh)); if(btLow >= 10) sb.Append((char)('A' + btLow - 10)); else sb.Append((char)('0' + btLow)); } return sb.ToString(); } /// /// Decode Base32 strings according to RFC 4648. /// public static byte[] ParseBase32(string str) { if((str == null) || ((str.Length % 8) != 0)) { Debug.Assert(false); return null; } ulong uMaxBits = (ulong)str.Length * 5UL; List l = new List((int)(uMaxBits / 8UL) + 1); Debug.Assert(l.Count == 0); for(int i = 0; i < str.Length; i += 8) { ulong u = 0; int nBits = 0; for(int j = 0; j < 8; ++j) { char ch = str[i + j]; if(ch == '=') break; ulong uValue; if((ch >= 'A') && (ch <= 'Z')) uValue = (ulong)(ch - 'A'); else if((ch >= 'a') && (ch <= 'z')) uValue = (ulong)(ch - 'a'); else if((ch >= '2') && (ch <= '7')) uValue = (ulong)(ch - '2') + 26UL; else { Debug.Assert(false); return null; } u <<= 5; u += uValue; nBits += 5; } int nBitsTooMany = (nBits % 8); u >>= nBitsTooMany; nBits -= nBitsTooMany; Debug.Assert((nBits % 8) == 0); int idxNewBytes = l.Count; while(nBits > 0) { l.Add((byte)(u & 0xFF)); u >>= 8; nBits -= 8; } l.Reverse(idxNewBytes, l.Count - idxNewBytes); } return l.ToArray(); } /// /// Set all bytes in a byte array to zero. /// /// Input array. All bytes of this array /// will be set to zero. #if KeePassLibSD [MethodImpl(MethodImplOptions.NoInlining)] #else [MethodImpl(MethodImplOptions.NoOptimization | MethodImplOptions.NoInlining)] #endif public static void ZeroByteArray(byte[] pbArray) { Debug.Assert(pbArray != null); if(pbArray == null) throw new ArgumentNullException("pbArray"); Array.Clear(pbArray, 0, pbArray.Length); } /// /// Set all elements of an array to the default value. /// /// Input array. #if KeePassLibSD [MethodImpl(MethodImplOptions.NoInlining)] #else [MethodImpl(MethodImplOptions.NoOptimization | MethodImplOptions.NoInlining)] #endif public static void ZeroArray(T[] v) { if(v == null) { Debug.Assert(false); throw new ArgumentNullException("v"); } Array.Clear(v, 0, v.Length); } /// /// Convert 2 bytes to a 16-bit unsigned integer (little-endian). /// public static ushort BytesToUInt16(byte[] pb) { Debug.Assert((pb != null) && (pb.Length == 2)); if(pb == null) throw new ArgumentNullException("pb"); if(pb.Length != 2) throw new ArgumentOutOfRangeException("pb"); return (ushort)((ushort)pb[0] | ((ushort)pb[1] << 8)); } /// /// Convert 2 bytes to a 16-bit unsigned integer (little-endian). /// public static ushort BytesToUInt16(byte[] pb, int iOffset) { if(pb == null) { Debug.Assert(false); throw new ArgumentNullException("pb"); } if((iOffset < 0) || ((iOffset + 1) >= pb.Length)) { Debug.Assert(false); throw new ArgumentOutOfRangeException("iOffset"); } return (ushort)((ushort)pb[iOffset] | ((ushort)pb[iOffset + 1] << 8)); } /// /// Convert 4 bytes to a 32-bit unsigned integer (little-endian). /// public static uint BytesToUInt32(byte[] pb) { Debug.Assert((pb != null) && (pb.Length == 4)); if(pb == null) throw new ArgumentNullException("pb"); if(pb.Length != 4) throw new ArgumentOutOfRangeException("pb"); return ((uint)pb[0] | ((uint)pb[1] << 8) | ((uint)pb[2] << 16) | ((uint)pb[3] << 24)); } /// /// Convert 4 bytes to a 32-bit unsigned integer (little-endian). /// public static uint BytesToUInt32(byte[] pb, int iOffset) { if(pb == null) { Debug.Assert(false); throw new ArgumentNullException("pb"); } if((iOffset < 0) || ((iOffset + 3) >= pb.Length)) { Debug.Assert(false); throw new ArgumentOutOfRangeException("iOffset"); } return ((uint)pb[iOffset] | ((uint)pb[iOffset + 1] << 8) | ((uint)pb[iOffset + 2] << 16) | ((uint)pb[iOffset + 3] << 24)); } /// /// Convert 8 bytes to a 64-bit unsigned integer (little-endian). /// public static ulong BytesToUInt64(byte[] pb) { Debug.Assert((pb != null) && (pb.Length == 8)); if(pb == null) throw new ArgumentNullException("pb"); if(pb.Length != 8) throw new ArgumentOutOfRangeException("pb"); return ((ulong)pb[0] | ((ulong)pb[1] << 8) | ((ulong)pb[2] << 16) | ((ulong)pb[3] << 24) | ((ulong)pb[4] << 32) | ((ulong)pb[5] << 40) | ((ulong)pb[6] << 48) | ((ulong)pb[7] << 56)); } /// /// Convert 8 bytes to a 64-bit unsigned integer (little-endian). /// public static ulong BytesToUInt64(byte[] pb, int iOffset) { if(pb == null) { Debug.Assert(false); throw new ArgumentNullException("pb"); } if((iOffset < 0) || ((iOffset + 7) >= pb.Length)) { Debug.Assert(false); throw new ArgumentOutOfRangeException("iOffset"); } // if(BitConverter.IsLittleEndian) // return BitConverter.ToUInt64(pb, iOffset); return ((ulong)pb[iOffset] | ((ulong)pb[iOffset + 1] << 8) | ((ulong)pb[iOffset + 2] << 16) | ((ulong)pb[iOffset + 3] << 24) | ((ulong)pb[iOffset + 4] << 32) | ((ulong)pb[iOffset + 5] << 40) | ((ulong)pb[iOffset + 6] << 48) | ((ulong)pb[iOffset + 7] << 56)); } public static int BytesToInt32(byte[] pb) { return (int)BytesToUInt32(pb); } public static int BytesToInt32(byte[] pb, int iOffset) { return (int)BytesToUInt32(pb, iOffset); } public static long BytesToInt64(byte[] pb) { return (long)BytesToUInt64(pb); } public static long BytesToInt64(byte[] pb, int iOffset) { return (long)BytesToUInt64(pb, iOffset); } /// /// Convert a 16-bit unsigned integer to 2 bytes (little-endian). /// public static byte[] UInt16ToBytes(ushort uValue) { byte[] pb = new byte[2]; unchecked { pb[0] = (byte)uValue; pb[1] = (byte)(uValue >> 8); } return pb; } /// /// Convert a 32-bit unsigned integer to 4 bytes (little-endian). /// public static byte[] UInt32ToBytes(uint uValue) { byte[] pb = new byte[4]; unchecked { pb[0] = (byte)uValue; pb[1] = (byte)(uValue >> 8); pb[2] = (byte)(uValue >> 16); pb[3] = (byte)(uValue >> 24); } return pb; } /// /// Convert a 32-bit unsigned integer to 4 bytes (little-endian). /// public static void UInt32ToBytesEx(uint uValue, byte[] pb, int iOffset) { if(pb == null) { Debug.Assert(false); throw new ArgumentNullException("pb"); } if((iOffset < 0) || ((iOffset + 3) >= pb.Length)) { Debug.Assert(false); throw new ArgumentOutOfRangeException("iOffset"); } unchecked { pb[iOffset] = (byte)uValue; pb[iOffset + 1] = (byte)(uValue >> 8); pb[iOffset + 2] = (byte)(uValue >> 16); pb[iOffset + 3] = (byte)(uValue >> 24); } } /// /// Convert a 64-bit unsigned integer to 8 bytes (little-endian). /// public static byte[] UInt64ToBytes(ulong uValue) { byte[] pb = new byte[8]; unchecked { pb[0] = (byte)uValue; pb[1] = (byte)(uValue >> 8); pb[2] = (byte)(uValue >> 16); pb[3] = (byte)(uValue >> 24); pb[4] = (byte)(uValue >> 32); pb[5] = (byte)(uValue >> 40); pb[6] = (byte)(uValue >> 48); pb[7] = (byte)(uValue >> 56); } return pb; } /// /// Convert a 64-bit unsigned integer to 8 bytes (little-endian). /// public static void UInt64ToBytesEx(ulong uValue, byte[] pb, int iOffset) { if(pb == null) { Debug.Assert(false); throw new ArgumentNullException("pb"); } if((iOffset < 0) || ((iOffset + 7) >= pb.Length)) { Debug.Assert(false); throw new ArgumentOutOfRangeException("iOffset"); } unchecked { pb[iOffset] = (byte)uValue; pb[iOffset + 1] = (byte)(uValue >> 8); pb[iOffset + 2] = (byte)(uValue >> 16); pb[iOffset + 3] = (byte)(uValue >> 24); pb[iOffset + 4] = (byte)(uValue >> 32); pb[iOffset + 5] = (byte)(uValue >> 40); pb[iOffset + 6] = (byte)(uValue >> 48); pb[iOffset + 7] = (byte)(uValue >> 56); } } public static byte[] Int32ToBytes(int iValue) { return UInt32ToBytes((uint)iValue); } public static byte[] Int64ToBytes(long lValue) { return UInt64ToBytes((ulong)lValue); } public static uint RotateLeft32(uint u, int nBits) { return ((u << nBits) | (u >> (32 - nBits))); } public static uint RotateRight32(uint u, int nBits) { return ((u >> nBits) | (u << (32 - nBits))); } public static ulong RotateLeft64(ulong u, int nBits) { return ((u << nBits) | (u >> (64 - nBits))); } public static ulong RotateRight64(ulong u, int nBits) { return ((u >> nBits) | (u << (64 - nBits))); } public static bool ArraysEqual(byte[] x, byte[] y) { // Return false if one of them is null (not comparable)! if((x == null) || (y == null)) { Debug.Assert(false); return false; } if(x.Length != y.Length) return false; for(int i = 0; i < x.Length; ++i) { if(x[i] != y[i]) return false; } return true; } public static void XorArray(byte[] pbSource, int iSourceOffset, byte[] pbBuffer, int iBufferOffset, int cb) { if(pbSource == null) throw new ArgumentNullException("pbSource"); if(iSourceOffset < 0) throw new ArgumentOutOfRangeException("iSourceOffset"); if(pbBuffer == null) throw new ArgumentNullException("pbBuffer"); if(iBufferOffset < 0) throw new ArgumentOutOfRangeException("iBufferOffset"); if(cb < 0) throw new ArgumentOutOfRangeException("cb"); if(iSourceOffset > (pbSource.Length - cb)) throw new ArgumentOutOfRangeException("cb"); if(iBufferOffset > (pbBuffer.Length - cb)) throw new ArgumentOutOfRangeException("cb"); for(int i = 0; i < cb; ++i) pbBuffer[iBufferOffset + i] ^= pbSource[iSourceOffset + i]; } /// /// Fast hash that can be used e.g. for hash tables. /// The algorithm might change in the future; do not store /// the hashes for later use. /// public static uint Hash32(byte[] v, int iStart, int iLength) { uint u = 0x326F637B; if(v == null) { Debug.Assert(false); return u; } if(iStart < 0) { Debug.Assert(false); return u; } if(iLength < 0) { Debug.Assert(false); return u; } int m = iStart + iLength; if(m > v.Length) { Debug.Assert(false); return u; } for(int i = iStart; i < m; ++i) { u ^= m_vSBox[v[i]]; u *= 3; } return u; } public static void CopyStream(Stream sSource, Stream sTarget) { Debug.Assert((sSource != null) && (sTarget != null)); if(sSource == null) throw new ArgumentNullException("sSource"); if(sTarget == null) throw new ArgumentNullException("sTarget"); const int nBufSize = 4096; byte[] pbBuf = new byte[nBufSize]; while(true) { int nRead = sSource.Read(pbBuf, 0, nBufSize); if(nRead == 0) break; sTarget.Write(pbBuf, 0, nRead); } // Do not close any of the streams } public static byte[] Read(Stream s, int nCount) { if(s == null) throw new ArgumentNullException("s"); if(nCount < 0) throw new ArgumentOutOfRangeException("nCount"); byte[] pb = new byte[nCount]; int iOffset = 0; while(nCount > 0) { int iRead = s.Read(pb, iOffset, nCount); if(iRead == 0) break; iOffset += iRead; nCount -= iRead; } if(iOffset != pb.Length) { byte[] pbPart = new byte[iOffset]; Array.Copy(pb, pbPart, iOffset); return pbPart; } return pb; } public static void Write(Stream s, byte[] pbData) { if(s == null) { Debug.Assert(false); return; } if(pbData == null) { Debug.Assert(false); return; } Debug.Assert(pbData.Length >= 0); if(pbData.Length > 0) s.Write(pbData, 0, pbData.Length); } public static byte[] Compress(byte[] pbData) { if(pbData == null) throw new ArgumentNullException("pbData"); if(pbData.Length == 0) return pbData; byte[] pbCompressed; using(MemoryStream msSource = new MemoryStream(pbData, false)) { using(MemoryStream msCompressed = new MemoryStream()) { using(GZipStream gz = new GZipStream(msCompressed, CompressionMode.Compress)) { MemUtil.CopyStream(msSource, gz); } pbCompressed = msCompressed.ToArray(); } } return pbCompressed; } public static byte[] Decompress(byte[] pbCompressed) { if(pbCompressed == null) throw new ArgumentNullException("pbCompressed"); if(pbCompressed.Length == 0) return pbCompressed; byte[] pbData; using(MemoryStream msData = new MemoryStream()) { using(MemoryStream msCompressed = new MemoryStream(pbCompressed, false)) { using(GZipStream gz = new GZipStream(msCompressed, CompressionMode.Decompress)) { MemUtil.CopyStream(gz, msData); } } pbData = msData.ToArray(); } return pbData; } public static int IndexOf(T[] vHaystack, T[] vNeedle) where T : IEquatable { if(vHaystack == null) throw new ArgumentNullException("vHaystack"); if(vNeedle == null) throw new ArgumentNullException("vNeedle"); if(vNeedle.Length == 0) return 0; for(int i = 0; i <= (vHaystack.Length - vNeedle.Length); ++i) { bool bFound = true; for(int m = 0; m < vNeedle.Length; ++m) { if(!vHaystack[i + m].Equals(vNeedle[m])) { bFound = false; break; } } if(bFound) return i; } return -1; } public static T[] Mid(T[] v, int iOffset, int iLength) { if(v == null) throw new ArgumentNullException("v"); if(iOffset < 0) throw new ArgumentOutOfRangeException("iOffset"); if(iLength < 0) throw new ArgumentOutOfRangeException("iLength"); if((iOffset + iLength) > v.Length) throw new ArgumentException(); T[] r = new T[iLength]; Array.Copy(v, iOffset, r, 0, iLength); return r; } public static IEnumerable Union(IEnumerable a, IEnumerable b, IEqualityComparer cmp) { if(a == null) throw new ArgumentNullException("a"); if(b == null) throw new ArgumentNullException("b"); Dictionary d = ((cmp != null) ? (new Dictionary(cmp)) : (new Dictionary())); foreach(T ta in a) { if(d.ContainsKey(ta)) continue; // Prevent duplicates d[ta] = true; yield return ta; } foreach(T tb in b) { if(d.ContainsKey(tb)) continue; // Prevent duplicates d[tb] = true; yield return tb; } yield break; } public static IEnumerable Intersect(IEnumerable a, IEnumerable b, IEqualityComparer cmp) { if(a == null) throw new ArgumentNullException("a"); if(b == null) throw new ArgumentNullException("b"); Dictionary d = ((cmp != null) ? (new Dictionary(cmp)) : (new Dictionary())); foreach(T tb in b) { d[tb] = true; } foreach(T ta in a) { if(d.Remove(ta)) // Prevent duplicates yield return ta; } yield break; } public static IEnumerable Except(IEnumerable a, IEnumerable b, IEqualityComparer cmp) { if(a == null) throw new ArgumentNullException("a"); if(b == null) throw new ArgumentNullException("b"); Dictionary d = ((cmp != null) ? (new Dictionary(cmp)) : (new Dictionary())); foreach(T tb in b) { d[tb] = true; } foreach(T ta in a) { if(d.ContainsKey(ta)) continue; d[ta] = true; // Prevent duplicates yield return ta; } yield break; } } internal sealed class ArrayHelperEx : IEqualityComparer, IComparer where T : IEquatable, IComparable { public int GetHashCode(T[] obj) { if(obj == null) throw new ArgumentNullException("obj"); uint h = 0xC17962B7U; unchecked { int n = obj.Length; for(int i = 0; i < n; ++i) { h += (uint)obj[i].GetHashCode(); h = MemUtil.RotateLeft32(h * 0x5FC34C67U, 13); } } return (int)h; } /* internal ulong GetHashCodeEx(T[] obj) { if(obj == null) throw new ArgumentNullException("obj"); ulong h = 0x207CAC8E509A3FC9UL; unchecked { int n = obj.Length; for(int i = 0; i < n; ++i) { h += (uint)obj[i].GetHashCode(); h = MemUtil.RotateLeft64(h * 0x54724D3EA2860CBBUL, 29); } } return h; } */ public bool Equals(T[] x, T[] y) { if(object.ReferenceEquals(x, y)) return true; if((x == null) || (y == null)) return false; int n = x.Length; if(n != y.Length) return false; for(int i = 0; i < n; ++i) { if(!x[i].Equals(y[i])) return false; } return true; } public int Compare(T[] x, T[] y) { if(object.ReferenceEquals(x, y)) return 0; if(x == null) return -1; if(y == null) return 1; int n = x.Length, m = y.Length; if(n != m) return ((n < m) ? -1 : 1); for(int i = 0; i < n; ++i) { T tX = x[i], tY = y[i]; if(!tX.Equals(tY)) return tX.CompareTo(tY); } return 0; } } } KeePassLib/Resources/0000775000000000000000000000000013222750172013513 5ustar rootrootKeePassLib/Resources/KLRes.Generated.cs0000664000000000000000000004413313222750172016724 0ustar rootroot// This is a generated file! // Do not edit manually, changes will be overwritten. using System; using System.Collections.Generic; namespace KeePassLib.Resources { /// /// A strongly-typed resource class, for looking up localized strings, etc. /// public static class KLRes { private static string TryGetEx(Dictionary dictNew, string strName, string strDefault) { string strTemp; if(dictNew.TryGetValue(strName, out strTemp)) return strTemp; return strDefault; } public static void SetTranslatedStrings(Dictionary dictNew) { if(dictNew == null) throw new ArgumentNullException("dictNew"); m_strCryptoStreamFailed = TryGetEx(dictNew, "CryptoStreamFailed", m_strCryptoStreamFailed); m_strEncDataTooLarge = TryGetEx(dictNew, "EncDataTooLarge", m_strEncDataTooLarge); m_strErrorInClipboard = TryGetEx(dictNew, "ErrorInClipboard", m_strErrorInClipboard); m_strExpect100Continue = TryGetEx(dictNew, "Expect100Continue", m_strExpect100Continue); m_strFatalError = TryGetEx(dictNew, "FatalError", m_strFatalError); m_strFatalErrorText = TryGetEx(dictNew, "FatalErrorText", m_strFatalErrorText); m_strFileCorrupted = TryGetEx(dictNew, "FileCorrupted", m_strFileCorrupted); m_strFileHeaderCorrupted = TryGetEx(dictNew, "FileHeaderCorrupted", m_strFileHeaderCorrupted); m_strFileIncomplete = TryGetEx(dictNew, "FileIncomplete", m_strFileIncomplete); m_strFileIncompleteExpc = TryGetEx(dictNew, "FileIncompleteExpc", m_strFileIncompleteExpc); m_strFileLoadFailed = TryGetEx(dictNew, "FileLoadFailed", m_strFileLoadFailed); m_strFileLockedWrite = TryGetEx(dictNew, "FileLockedWrite", m_strFileLockedWrite); m_strFileNewVerOrPlgReq = TryGetEx(dictNew, "FileNewVerOrPlgReq", m_strFileNewVerOrPlgReq); m_strFileNewVerReq = TryGetEx(dictNew, "FileNewVerReq", m_strFileNewVerReq); m_strFileSaveCorruptionWarning = TryGetEx(dictNew, "FileSaveCorruptionWarning", m_strFileSaveCorruptionWarning); m_strFileSaveFailed = TryGetEx(dictNew, "FileSaveFailed", m_strFileSaveFailed); m_strFileSigInvalid = TryGetEx(dictNew, "FileSigInvalid", m_strFileSigInvalid); m_strFileUnknownCipher = TryGetEx(dictNew, "FileUnknownCipher", m_strFileUnknownCipher); m_strFileUnknownCompression = TryGetEx(dictNew, "FileUnknownCompression", m_strFileUnknownCompression); m_strFileVersionUnsupported = TryGetEx(dictNew, "FileVersionUnsupported", m_strFileVersionUnsupported); m_strFinalKeyCreationFailed = TryGetEx(dictNew, "FinalKeyCreationFailed", m_strFinalKeyCreationFailed); m_strFrameworkNotImplExcp = TryGetEx(dictNew, "FrameworkNotImplExcp", m_strFrameworkNotImplExcp); m_strGeneral = TryGetEx(dictNew, "General", m_strGeneral); m_strInvalidCompositeKey = TryGetEx(dictNew, "InvalidCompositeKey", m_strInvalidCompositeKey); m_strInvalidCompositeKeyHint = TryGetEx(dictNew, "InvalidCompositeKeyHint", m_strInvalidCompositeKeyHint); m_strInvalidDataWhileDecoding = TryGetEx(dictNew, "InvalidDataWhileDecoding", m_strInvalidDataWhileDecoding); m_strKeePass1xHint = TryGetEx(dictNew, "KeePass1xHint", m_strKeePass1xHint); m_strKeyBits = TryGetEx(dictNew, "KeyBits", m_strKeyBits); m_strKeyFileDbSel = TryGetEx(dictNew, "KeyFileDbSel", m_strKeyFileDbSel); m_strMasterSeedLengthInvalid = TryGetEx(dictNew, "MasterSeedLengthInvalid", m_strMasterSeedLengthInvalid); m_strOldFormat = TryGetEx(dictNew, "OldFormat", m_strOldFormat); m_strPassive = TryGetEx(dictNew, "Passive", m_strPassive); m_strPreAuth = TryGetEx(dictNew, "PreAuth", m_strPreAuth); m_strTimeout = TryGetEx(dictNew, "Timeout", m_strTimeout); m_strTryAgainSecs = TryGetEx(dictNew, "TryAgainSecs", m_strTryAgainSecs); m_strUnknownHeaderId = TryGetEx(dictNew, "UnknownHeaderId", m_strUnknownHeaderId); m_strUnknownKdf = TryGetEx(dictNew, "UnknownKdf", m_strUnknownKdf); m_strUserAccountKeyError = TryGetEx(dictNew, "UserAccountKeyError", m_strUserAccountKeyError); m_strUserAgent = TryGetEx(dictNew, "UserAgent", m_strUserAgent); } private static readonly string[] m_vKeyNames = { "CryptoStreamFailed", "EncDataTooLarge", "ErrorInClipboard", "Expect100Continue", "FatalError", "FatalErrorText", "FileCorrupted", "FileHeaderCorrupted", "FileIncomplete", "FileIncompleteExpc", "FileLoadFailed", "FileLockedWrite", "FileNewVerOrPlgReq", "FileNewVerReq", "FileSaveCorruptionWarning", "FileSaveFailed", "FileSigInvalid", "FileUnknownCipher", "FileUnknownCompression", "FileVersionUnsupported", "FinalKeyCreationFailed", "FrameworkNotImplExcp", "General", "InvalidCompositeKey", "InvalidCompositeKeyHint", "InvalidDataWhileDecoding", "KeePass1xHint", "KeyBits", "KeyFileDbSel", "MasterSeedLengthInvalid", "OldFormat", "Passive", "PreAuth", "Timeout", "TryAgainSecs", "UnknownHeaderId", "UnknownKdf", "UserAccountKeyError", "UserAgent" }; public static string[] GetKeyNames() { return m_vKeyNames; } private static string m_strCryptoStreamFailed = @"Failed to initialize encryption/decryption stream!"; /// /// Look up a localized string similar to /// 'Failed to initialize encryption/decryption stream!'. /// public static string CryptoStreamFailed { get { return m_strCryptoStreamFailed; } } private static string m_strEncDataTooLarge = @"The data is too large to be encrypted/decrypted securely using {PARAM}."; /// /// Look up a localized string similar to /// 'The data is too large to be encrypted/decrypted securely using {PARAM}.'. /// public static string EncDataTooLarge { get { return m_strEncDataTooLarge; } } private static string m_strErrorInClipboard = @"An extended error report has been copied to the clipboard."; /// /// Look up a localized string similar to /// 'An extended error report has been copied to the clipboard.'. /// public static string ErrorInClipboard { get { return m_strErrorInClipboard; } } private static string m_strExpect100Continue = @"Expect 100-Continue responses"; /// /// Look up a localized string similar to /// 'Expect 100-Continue responses'. /// public static string Expect100Continue { get { return m_strExpect100Continue; } } private static string m_strFatalError = @"Fatal Error"; /// /// Look up a localized string similar to /// 'Fatal Error'. /// public static string FatalError { get { return m_strFatalError; } } private static string m_strFatalErrorText = @"A fatal error has occurred!"; /// /// Look up a localized string similar to /// 'A fatal error has occurred!'. /// public static string FatalErrorText { get { return m_strFatalErrorText; } } private static string m_strFileCorrupted = @"The file is corrupted."; /// /// Look up a localized string similar to /// 'The file is corrupted.'. /// public static string FileCorrupted { get { return m_strFileCorrupted; } } private static string m_strFileHeaderCorrupted = @"The file header is corrupted."; /// /// Look up a localized string similar to /// 'The file header is corrupted.'. /// public static string FileHeaderCorrupted { get { return m_strFileHeaderCorrupted; } } private static string m_strFileIncomplete = @"Data is missing at the end of the file, i.e. the file is incomplete."; /// /// Look up a localized string similar to /// 'Data is missing at the end of the file, i.e. the file is incomplete.'. /// public static string FileIncomplete { get { return m_strFileIncomplete; } } private static string m_strFileIncompleteExpc = @"Less data than expected could be read from the file."; /// /// Look up a localized string similar to /// 'Less data than expected could be read from the file.'. /// public static string FileIncompleteExpc { get { return m_strFileIncompleteExpc; } } private static string m_strFileLoadFailed = @"Failed to load the specified file!"; /// /// Look up a localized string similar to /// 'Failed to load the specified file!'. /// public static string FileLoadFailed { get { return m_strFileLoadFailed; } } private static string m_strFileLockedWrite = @"The file is locked, because the following user is currently writing to it:"; /// /// Look up a localized string similar to /// 'The file is locked, because the following user is currently writing to it:'. /// public static string FileLockedWrite { get { return m_strFileLockedWrite; } } private static string m_strFileNewVerOrPlgReq = @"A newer KeePass version or a plugin is required to open this file."; /// /// Look up a localized string similar to /// 'A newer KeePass version or a plugin is required to open this file.'. /// public static string FileNewVerOrPlgReq { get { return m_strFileNewVerOrPlgReq; } } private static string m_strFileNewVerReq = @"A newer KeePass version is required to open this file."; /// /// Look up a localized string similar to /// 'A newer KeePass version is required to open this file.'. /// public static string FileNewVerReq { get { return m_strFileNewVerReq; } } private static string m_strFileSaveCorruptionWarning = @"The target file might be corrupted. Please try saving again. If that fails, save the database to a different location."; /// /// Look up a localized string similar to /// 'The target file might be corrupted. Please try saving again. If that fails, save the database to a different location.'. /// public static string FileSaveCorruptionWarning { get { return m_strFileSaveCorruptionWarning; } } private static string m_strFileSaveFailed = @"Failed to save the current database to the specified location!"; /// /// Look up a localized string similar to /// 'Failed to save the current database to the specified location!'. /// public static string FileSaveFailed { get { return m_strFileSaveFailed; } } private static string m_strFileSigInvalid = @"The file signature is invalid. Either the file isn't a KeePass database file at all or it is corrupted."; /// /// Look up a localized string similar to /// 'The file signature is invalid. Either the file isn't a KeePass database file at all or it is corrupted.'. /// public static string FileSigInvalid { get { return m_strFileSigInvalid; } } private static string m_strFileUnknownCipher = @"The file is encrypted using an unknown encryption algorithm!"; /// /// Look up a localized string similar to /// 'The file is encrypted using an unknown encryption algorithm!'. /// public static string FileUnknownCipher { get { return m_strFileUnknownCipher; } } private static string m_strFileUnknownCompression = @"The file is compressed using an unknown compression algorithm!"; /// /// Look up a localized string similar to /// 'The file is compressed using an unknown compression algorithm!'. /// public static string FileUnknownCompression { get { return m_strFileUnknownCompression; } } private static string m_strFileVersionUnsupported = @"The file version is unsupported."; /// /// Look up a localized string similar to /// 'The file version is unsupported.'. /// public static string FileVersionUnsupported { get { return m_strFileVersionUnsupported; } } private static string m_strFinalKeyCreationFailed = @"Failed to create the final encryption/decryption key!"; /// /// Look up a localized string similar to /// 'Failed to create the final encryption/decryption key!'. /// public static string FinalKeyCreationFailed { get { return m_strFinalKeyCreationFailed; } } private static string m_strFrameworkNotImplExcp = @"The .NET framework/runtime under which KeePass is currently running does not support this operation."; /// /// Look up a localized string similar to /// 'The .NET framework/runtime under which KeePass is currently running does not support this operation.'. /// public static string FrameworkNotImplExcp { get { return m_strFrameworkNotImplExcp; } } private static string m_strGeneral = @"General"; /// /// Look up a localized string similar to /// 'General'. /// public static string General { get { return m_strGeneral; } } private static string m_strInvalidCompositeKey = @"The composite key is invalid!"; /// /// Look up a localized string similar to /// 'The composite key is invalid!'. /// public static string InvalidCompositeKey { get { return m_strInvalidCompositeKey; } } private static string m_strInvalidCompositeKeyHint = @"Make sure the composite key is correct and try again."; /// /// Look up a localized string similar to /// 'Make sure the composite key is correct and try again.'. /// public static string InvalidCompositeKeyHint { get { return m_strInvalidCompositeKeyHint; } } private static string m_strInvalidDataWhileDecoding = @"Found invalid data while decoding."; /// /// Look up a localized string similar to /// 'Found invalid data while decoding.'. /// public static string InvalidDataWhileDecoding { get { return m_strInvalidDataWhileDecoding; } } private static string m_strKeePass1xHint = @"In order to import KeePass 1.x KDB files, create a new 2.x database file and click 'File' -> 'Import' in the main menu. In the import dialog, choose 'KeePass KDB (1.x)' as file format."; /// /// Look up a localized string similar to /// 'In order to import KeePass 1.x KDB files, create a new 2.x database file and click 'File' -> 'Import' in the main menu. In the import dialog, choose 'KeePass KDB (1.x)' as file format.'. /// public static string KeePass1xHint { get { return m_strKeePass1xHint; } } private static string m_strKeyBits = @"{PARAM}-bit key"; /// /// Look up a localized string similar to /// '{PARAM}-bit key'. /// public static string KeyBits { get { return m_strKeyBits; } } private static string m_strKeyFileDbSel = @"Database files cannot be used as key files."; /// /// Look up a localized string similar to /// 'Database files cannot be used as key files.'. /// public static string KeyFileDbSel { get { return m_strKeyFileDbSel; } } private static string m_strMasterSeedLengthInvalid = @"The length of the master key seed is invalid!"; /// /// Look up a localized string similar to /// 'The length of the master key seed is invalid!'. /// public static string MasterSeedLengthInvalid { get { return m_strMasterSeedLengthInvalid; } } private static string m_strOldFormat = @"The selected file appears to be an old format"; /// /// Look up a localized string similar to /// 'The selected file appears to be an old format'. /// public static string OldFormat { get { return m_strOldFormat; } } private static string m_strPassive = @"Passive"; /// /// Look up a localized string similar to /// 'Passive'. /// public static string Passive { get { return m_strPassive; } } private static string m_strPreAuth = @"Pre-authenticate"; /// /// Look up a localized string similar to /// 'Pre-authenticate'. /// public static string PreAuth { get { return m_strPreAuth; } } private static string m_strTimeout = @"Timeout"; /// /// Look up a localized string similar to /// 'Timeout'. /// public static string Timeout { get { return m_strTimeout; } } private static string m_strTryAgainSecs = @"Please try it again in a few seconds."; /// /// Look up a localized string similar to /// 'Please try it again in a few seconds.'. /// public static string TryAgainSecs { get { return m_strTryAgainSecs; } } private static string m_strUnknownHeaderId = @"Unknown header ID!"; /// /// Look up a localized string similar to /// 'Unknown header ID!'. /// public static string UnknownHeaderId { get { return m_strUnknownHeaderId; } } private static string m_strUnknownKdf = @"Unknown key derivation function!"; /// /// Look up a localized string similar to /// 'Unknown key derivation function!'. /// public static string UnknownKdf { get { return m_strUnknownKdf; } } private static string m_strUserAccountKeyError = @"The operating system did not grant KeePass read/write access to the user profile folder, where the protected user key is stored."; /// /// Look up a localized string similar to /// 'The operating system did not grant KeePass read/write access to the user profile folder, where the protected user key is stored.'. /// public static string UserAccountKeyError { get { return m_strUserAccountKeyError; } } private static string m_strUserAgent = @"User agent"; /// /// Look up a localized string similar to /// 'User agent'. /// public static string UserAgent { get { return m_strUserAgent; } } } } KeePassLib/Resources/KSRes.Generated.cs0000664000000000000000000000216313222750172016730 0ustar rootroot// This is a generated file! // Do not edit manually, changes will be overwritten. using System; using System.Collections.Generic; namespace KeePassLib.Resources { /// /// A strongly-typed resource class, for looking up localized strings, etc. /// public static class KSRes { private static string TryGetEx(Dictionary dictNew, string strName, string strDefault) { string strTemp; if(dictNew.TryGetValue(strName, out strTemp)) return strTemp; return strDefault; } public static void SetTranslatedStrings(Dictionary dictNew) { if(dictNew == null) throw new ArgumentNullException("dictNew"); m_strTest = TryGetEx(dictNew, "Test", m_strTest); } private static readonly string[] m_vKeyNames = { "Test" }; public static string[] GetKeyNames() { return m_vKeyNames; } private static string m_strTest = @"Test"; /// /// Look up a localized string similar to /// 'Test'. /// public static string Test { get { return m_strTest; } } } } KeePassLib/KeePassLib.csproj0000664000000000000000000002046313166621174014760 0ustar rootroot Debug AnyCPU 9.0.30729 2.0 {53573E4E-33CB-4FDB-8698-C95F5E40E7F3} Library Properties KeePassLib KeePassLib true KeePassLib.pfx 2.0 true full false ..\Build\KeePassLib\Debug\ DEBUG;TRACE prompt 4 ..\Build\KeePassLib\Debug\KeePassLib.xml 1591 pdbonly true ..\Build\KeePassLib\Release\ TRACE prompt 4 ..\Build\KeePassLib\Release\KeePassLib.xml 1591 Component KeePassLib/Security/0000775000000000000000000000000013222430402013337 5ustar rootrootKeePassLib/Security/ProtectedString.cs0000664000000000000000000002447713222430402017024 0ustar rootroot/* KeePass Password Safe - The Open-Source Password Manager Copyright (C) 2003-2018 Dominik Reichl This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ using System; using System.Diagnostics; using System.Text; using KeePassLib.Cryptography; using KeePassLib.Utility; #if KeePassLibSD using KeePassLibSD; #endif // SecureString objects are limited to 65536 characters, don't use namespace KeePassLib.Security { /// /// Represents an in-memory encrypted string. /// ProtectedString objects are immutable and thread-safe. /// #if (DEBUG && !KeePassLibSD) [DebuggerDisplay(@"{ReadString()}")] #endif public sealed class ProtectedString { // Exactly one of the following will be non-null private ProtectedBinary m_pbUtf8 = null; private string m_strPlainText = null; private bool m_bIsProtected; private static readonly ProtectedString m_psEmpty = new ProtectedString(); public static ProtectedString Empty { get { return m_psEmpty; } } /// /// A flag specifying whether the ProtectedString object /// has turned on memory protection or not. /// public bool IsProtected { get { return m_bIsProtected; } } public bool IsEmpty { get { ProtectedBinary pBin = m_pbUtf8; // Local ref for thread-safety if(pBin != null) return (pBin.Length == 0); Debug.Assert(m_strPlainText != null); return (m_strPlainText.Length == 0); } } private int m_nCachedLength = -1; public int Length { get { if(m_nCachedLength >= 0) return m_nCachedLength; ProtectedBinary pBin = m_pbUtf8; // Local ref for thread-safety if(pBin != null) { byte[] pbPlain = pBin.ReadData(); m_nCachedLength = StrUtil.Utf8.GetCharCount(pbPlain); MemUtil.ZeroByteArray(pbPlain); } else { Debug.Assert(m_strPlainText != null); m_nCachedLength = m_strPlainText.Length; } return m_nCachedLength; } } /// /// Construct a new protected string object. Protection is /// disabled. /// public ProtectedString() { Init(false, string.Empty); } /// /// Construct a new protected string. The string is initialized /// to the value supplied in the parameters. /// /// If this parameter is true, /// the string will be protected in memory (encrypted). If it /// is false, the string will be stored as plain-text. /// The initial string value. public ProtectedString(bool bEnableProtection, string strValue) { Init(bEnableProtection, strValue); } /// /// Construct a new protected string. The string is initialized /// to the value supplied in the parameters (UTF-8 encoded string). /// /// If this parameter is true, /// the string will be protected in memory (encrypted). If it /// is false, the string will be stored as plain-text. /// The initial string value, encoded as /// UTF-8 byte array. This parameter won't be modified; the caller /// is responsible for clearing it. public ProtectedString(bool bEnableProtection, byte[] vUtf8Value) { Init(bEnableProtection, vUtf8Value); } /// /// Construct a new protected string. The string is initialized /// to the value passed in the XorredBuffer object. /// /// Enable protection or not. /// XorredBuffer object containing the /// string in UTF-8 representation. The UTF-8 string must not /// be null-terminated. public ProtectedString(bool bEnableProtection, XorredBuffer xbProtected) { Debug.Assert(xbProtected != null); if(xbProtected == null) throw new ArgumentNullException("xbProtected"); byte[] pb = xbProtected.ReadPlainText(); Init(bEnableProtection, pb); if(bEnableProtection) MemUtil.ZeroByteArray(pb); } private void Init(bool bEnableProtection, string str) { if(str == null) throw new ArgumentNullException("str"); m_bIsProtected = bEnableProtection; // The string already is in memory and immutable, // protection would be useless m_strPlainText = str; } private void Init(bool bEnableProtection, byte[] pbUtf8) { if(pbUtf8 == null) throw new ArgumentNullException("pbUtf8"); m_bIsProtected = bEnableProtection; if(bEnableProtection) m_pbUtf8 = new ProtectedBinary(true, pbUtf8); else m_strPlainText = StrUtil.Utf8.GetString(pbUtf8, 0, pbUtf8.Length); } /// /// Convert the protected string to a normal string object. /// Be careful with this function, the returned string object /// isn't protected anymore and stored in plain-text in the /// process memory. /// /// Plain-text string. Is never null. public string ReadString() { if(m_strPlainText != null) return m_strPlainText; byte[] pb = ReadUtf8(); string str = ((pb.Length == 0) ? string.Empty : StrUtil.Utf8.GetString(pb, 0, pb.Length)); // No need to clear pb // As the text is now visible in process memory anyway, // there's no need to protect it anymore m_strPlainText = str; m_pbUtf8 = null; // Thread-safe order return str; } /// /// Read out the string and return a byte array that contains the /// string encoded using UTF-8. The returned string is not protected /// anymore! /// /// Plain-text UTF-8 byte array. public byte[] ReadUtf8() { ProtectedBinary pBin = m_pbUtf8; // Local ref for thread-safety if(pBin != null) return pBin.ReadData(); return StrUtil.Utf8.GetBytes(m_strPlainText); } /// /// Read the protected string and return it protected with a sequence /// of bytes generated by a random stream. /// /// Random number source. /// Protected string. public byte[] ReadXorredString(CryptoRandomStream crsRandomSource) { Debug.Assert(crsRandomSource != null); if(crsRandomSource == null) throw new ArgumentNullException("crsRandomSource"); byte[] pbData = ReadUtf8(); uint uLen = (uint)pbData.Length; byte[] randomPad = crsRandomSource.GetRandomBytes(uLen); Debug.Assert(randomPad.Length == pbData.Length); for(uint i = 0; i < uLen; ++i) pbData[i] ^= randomPad[i]; return pbData; } public ProtectedString WithProtection(bool bProtect) { if(bProtect == m_bIsProtected) return this; byte[] pb = ReadUtf8(); ProtectedString ps = new ProtectedString(bProtect, pb); if(bProtect) MemUtil.ZeroByteArray(pb); return ps; } public ProtectedString Insert(int iStart, string strInsert) { if(iStart < 0) throw new ArgumentOutOfRangeException("iStart"); if(strInsert == null) throw new ArgumentNullException("strInsert"); if(strInsert.Length == 0) return this; // Only operate directly with strings when m_bIsProtected is // false, not in the case of non-null m_strPlainText, because // the operation creates a new sequence in memory if(!m_bIsProtected) return new ProtectedString(false, ReadString().Insert( iStart, strInsert)); UTF8Encoding utf8 = StrUtil.Utf8; byte[] pb = ReadUtf8(); char[] v = utf8.GetChars(pb); char[] vNew; try { if(iStart > v.Length) throw new ArgumentOutOfRangeException("iStart"); char[] vIns = strInsert.ToCharArray(); vNew = new char[v.Length + vIns.Length]; Array.Copy(v, 0, vNew, 0, iStart); Array.Copy(vIns, 0, vNew, iStart, vIns.Length); Array.Copy(v, iStart, vNew, iStart + vIns.Length, v.Length - iStart); } finally { MemUtil.ZeroArray(v); MemUtil.ZeroByteArray(pb); } byte[] pbNew = utf8.GetBytes(vNew); ProtectedString ps = new ProtectedString(m_bIsProtected, pbNew); Debug.Assert(utf8.GetString(pbNew, 0, pbNew.Length) == ReadString().Insert(iStart, strInsert)); MemUtil.ZeroArray(vNew); MemUtil.ZeroByteArray(pbNew); return ps; } public ProtectedString Remove(int iStart, int nCount) { if(iStart < 0) throw new ArgumentOutOfRangeException("iStart"); if(nCount < 0) throw new ArgumentOutOfRangeException("nCount"); if(nCount == 0) return this; // Only operate directly with strings when m_bIsProtected is // false, not in the case of non-null m_strPlainText, because // the operation creates a new sequence in memory if(!m_bIsProtected) return new ProtectedString(false, ReadString().Remove( iStart, nCount)); UTF8Encoding utf8 = StrUtil.Utf8; byte[] pb = ReadUtf8(); char[] v = utf8.GetChars(pb); char[] vNew; try { if((iStart + nCount) > v.Length) throw new ArgumentException("iStart + nCount"); vNew = new char[v.Length - nCount]; Array.Copy(v, 0, vNew, 0, iStart); Array.Copy(v, iStart + nCount, vNew, iStart, v.Length - (iStart + nCount)); } finally { MemUtil.ZeroArray(v); MemUtil.ZeroByteArray(pb); } byte[] pbNew = utf8.GetBytes(vNew); ProtectedString ps = new ProtectedString(m_bIsProtected, pbNew); Debug.Assert(utf8.GetString(pbNew, 0, pbNew.Length) == ReadString().Remove(iStart, nCount)); MemUtil.ZeroArray(vNew); MemUtil.ZeroByteArray(pbNew); return ps; } } } KeePassLib/Security/XorredBuffer.cs0000664000000000000000000000764013222430402016272 0ustar rootroot/* KeePass Password Safe - The Open-Source Password Manager Copyright (C) 2003-2018 Dominik Reichl This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ using System; using System.Diagnostics; namespace KeePassLib.Security { /// /// Represents an object that is encrypted using a XOR pad until /// it is read. XorredBuffer objects are immutable and /// thread-safe. /// public sealed class XorredBuffer { private byte[] m_pbData; // Never null private byte[] m_pbXorPad; // Always valid for m_pbData /// /// Length of the protected data in bytes. /// public uint Length { get { return (uint)m_pbData.Length; } } /// /// Construct a new XOR-protected object using a protected byte array /// and a XOR pad that decrypts the protected data. The /// byte array must have the same size /// as the byte array. /// The XorredBuffer object takes ownership of the two byte /// arrays, i.e. the caller must not use or modify them afterwards. /// /// Protected data (XOR pad applied). /// XOR pad that can be used to decrypt the /// parameter. /// Thrown if one of the input /// parameters is null. /// Thrown if the byte arrays are /// of different size. public XorredBuffer(byte[] pbProtectedData, byte[] pbXorPad) { if(pbProtectedData == null) { Debug.Assert(false); throw new ArgumentNullException("pbProtectedData"); } if(pbXorPad == null) { Debug.Assert(false); throw new ArgumentNullException("pbXorPad"); } Debug.Assert(pbProtectedData.Length == pbXorPad.Length); if(pbProtectedData.Length != pbXorPad.Length) throw new ArgumentException(); m_pbData = pbProtectedData; m_pbXorPad = pbXorPad; } /// /// Get a copy of the plain-text. The caller is responsible /// for clearing the byte array safely after using it. /// /// Unprotected plain-text byte array. public byte[] ReadPlainText() { byte[] pbPlain = new byte[m_pbData.Length]; for(int i = 0; i < pbPlain.Length; ++i) pbPlain[i] = (byte)(m_pbData[i] ^ m_pbXorPad[i]); return pbPlain; } /* public bool EqualsValue(XorredBuffer xb) { if(xb == null) { Debug.Assert(false); throw new ArgumentNullException("xb"); } if(xb.m_pbData.Length != m_pbData.Length) return false; for(int i = 0; i < m_pbData.Length; ++i) { byte bt1 = (byte)(m_pbData[i] ^ m_pbXorPad[i]); byte bt2 = (byte)(xb.m_pbData[i] ^ xb.m_pbXorPad[i]); if(bt1 != bt2) return false; } return true; } public bool EqualsValue(byte[] pb) { if(pb == null) { Debug.Assert(false); throw new ArgumentNullException("pb"); } if(pb.Length != m_pbData.Length) return false; for(int i = 0; i < m_pbData.Length; ++i) { if((byte)(m_pbData[i] ^ m_pbXorPad[i]) != pb[i]) return false; } return true; } */ } } KeePassLib/Security/ProtectedBinary.cs0000664000000000000000000002726613222430402017001 0ustar rootroot/* KeePass Password Safe - The Open-Source Password Manager Copyright (C) 2003-2018 Dominik Reichl This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ using System; using System.Diagnostics; using System.Threading; #if !KeePassUAP using System.Security.Cryptography; #endif using KeePassLib.Cryptography; using KeePassLib.Cryptography.Cipher; using KeePassLib.Native; using KeePassLib.Utility; #if KeePassLibSD using KeePassLibSD; #endif namespace KeePassLib.Security { [Flags] public enum PbCryptFlags { None = 0, Encrypt = 1, Decrypt = 2 } public delegate void PbCryptDelegate(byte[] pbData, PbCryptFlags cf, long lID); /// /// Represents a protected binary, i.e. a byte array that is encrypted /// in memory. A ProtectedBinary object is immutable and /// thread-safe. /// public sealed class ProtectedBinary : IEquatable { private const int BlockSize = 16; private static PbCryptDelegate g_fExtCrypt = null; /// /// A plugin can provide a custom memory protection method /// by assigning a non-null delegate to this property. /// public static PbCryptDelegate ExtCrypt { get { return g_fExtCrypt; } set { g_fExtCrypt = value; } } // Local copy of the delegate that was used for encryption, // in order to allow correct decryption even when the global // delegate changes private PbCryptDelegate m_fExtCrypt = null; private enum PbMemProt { None = 0, ProtectedMemory, ChaCha20, ExtCrypt } // ProtectedMemory is supported only on Windows 2000 SP3 and higher #if !KeePassLibSD private static bool? g_obProtectedMemorySupported = null; #endif private static bool ProtectedMemorySupported { get { #if KeePassLibSD return false; #else bool? ob = g_obProtectedMemorySupported; if(ob.HasValue) return ob.Value; // Mono does not implement any encryption for ProtectedMemory; // https://sourceforge.net/p/keepass/feature-requests/1907/ if(NativeLib.IsUnix()) { g_obProtectedMemorySupported = false; return false; } ob = false; try // Test whether ProtectedMemory is supported { // BlockSize * 3 in order to test encryption for multiple // blocks, but not introduce a power of 2 as factor byte[] pb = new byte[ProtectedBinary.BlockSize * 3]; for(int i = 0; i < pb.Length; ++i) pb[i] = (byte)i; ProtectedMemory.Protect(pb, MemoryProtectionScope.SameProcess); for(int i = 0; i < pb.Length; ++i) { if(pb[i] != (byte)i) { ob = true; break; } } } catch(Exception) { } // Windows 98 / ME g_obProtectedMemorySupported = ob; return ob.Value; #endif } } private static long g_lCurID = 0; private long m_lID; private byte[] m_pbData; // Never null // The real length of the data; this value can be different from // m_pbData.Length, as the length of m_pbData always is a multiple // of BlockSize (required for ProtectedMemory) private uint m_uDataLen; private bool m_bProtected; // Protection requested by the caller private PbMemProt m_mp = PbMemProt.None; // Actual protection private readonly object m_objSync = new object(); private static byte[] g_pbKey32 = null; /// /// A flag specifying whether the ProtectedBinary object has /// turned on memory protection or not. /// public bool IsProtected { get { return m_bProtected; } } /// /// Length of the stored data. /// public uint Length { get { return m_uDataLen; } } /// /// Construct a new, empty protected binary data object. /// Protection is disabled. /// public ProtectedBinary() { Init(false, MemUtil.EmptyByteArray, 0, 0); } /// /// Construct a new protected binary data object. /// /// If this paremeter is true, /// the data will be encrypted in memory. If it is false, the /// data is stored in plain-text in the process memory. /// Value of the protected object. /// The input parameter is not modified and /// ProtectedBinary doesn't take ownership of the data, /// i.e. the caller is responsible for clearing it. public ProtectedBinary(bool bEnableProtection, byte[] pbData) { if(pbData == null) throw new ArgumentNullException("pbData"); Init(bEnableProtection, pbData, 0, pbData.Length); } /// /// Construct a new protected binary data object. /// /// If this paremeter is true, /// the data will be encrypted in memory. If it is false, the /// data is stored in plain-text in the process memory. /// Value of the protected object. /// The input parameter is not modified and /// ProtectedBinary doesn't take ownership of the data, /// i.e. the caller is responsible for clearing it. /// Offset for . /// Size for . public ProtectedBinary(bool bEnableProtection, byte[] pbData, int iOffset, int cbSize) { Init(bEnableProtection, pbData, iOffset, cbSize); } /// /// Construct a new protected binary data object. Copy the data from /// a XorredBuffer object. /// /// Enable protection or not. /// XorredBuffer object used to /// initialize the ProtectedBinary object. public ProtectedBinary(bool bEnableProtection, XorredBuffer xbProtected) { Debug.Assert(xbProtected != null); if(xbProtected == null) throw new ArgumentNullException("xbProtected"); byte[] pb = xbProtected.ReadPlainText(); Init(bEnableProtection, pb, 0, pb.Length); if(bEnableProtection) MemUtil.ZeroByteArray(pb); } private void Init(bool bEnableProtection, byte[] pbData, int iOffset, int cbSize) { if(pbData == null) throw new ArgumentNullException("pbData"); if(iOffset < 0) throw new ArgumentOutOfRangeException("iOffset"); if(cbSize < 0) throw new ArgumentOutOfRangeException("cbSize"); if(iOffset > (pbData.Length - cbSize)) throw new ArgumentOutOfRangeException("cbSize"); #if KeePassLibSD m_lID = ++g_lCurID; #else m_lID = Interlocked.Increment(ref g_lCurID); #endif m_bProtected = bEnableProtection; m_uDataLen = (uint)cbSize; const int bs = ProtectedBinary.BlockSize; int nBlocks = cbSize / bs; if((nBlocks * bs) < cbSize) ++nBlocks; Debug.Assert((nBlocks * bs) >= cbSize); m_pbData = new byte[nBlocks * bs]; Array.Copy(pbData, iOffset, m_pbData, 0, cbSize); Encrypt(); } private void Encrypt() { Debug.Assert(m_mp == PbMemProt.None); // Nothing to do if caller didn't request protection if(!m_bProtected) return; // ProtectedMemory.Protect throws for data size == 0 if(m_pbData.Length == 0) return; PbCryptDelegate f = g_fExtCrypt; if(f != null) { f(m_pbData, PbCryptFlags.Encrypt, m_lID); m_fExtCrypt = f; m_mp = PbMemProt.ExtCrypt; return; } if(ProtectedBinary.ProtectedMemorySupported) { ProtectedMemory.Protect(m_pbData, MemoryProtectionScope.SameProcess); m_mp = PbMemProt.ProtectedMemory; return; } byte[] pbKey32 = g_pbKey32; if(pbKey32 == null) { pbKey32 = CryptoRandom.Instance.GetRandomBytes(32); byte[] pbUpd = Interlocked.Exchange(ref g_pbKey32, pbKey32); if(pbUpd != null) pbKey32 = pbUpd; } byte[] pbIV = new byte[12]; MemUtil.UInt64ToBytesEx((ulong)m_lID, pbIV, 4); using(ChaCha20Cipher c = new ChaCha20Cipher(pbKey32, pbIV, true)) { c.Encrypt(m_pbData, 0, m_pbData.Length); } m_mp = PbMemProt.ChaCha20; } private void Decrypt() { if(m_pbData.Length == 0) return; if(m_mp == PbMemProt.ProtectedMemory) ProtectedMemory.Unprotect(m_pbData, MemoryProtectionScope.SameProcess); else if(m_mp == PbMemProt.ChaCha20) { byte[] pbIV = new byte[12]; MemUtil.UInt64ToBytesEx((ulong)m_lID, pbIV, 4); using(ChaCha20Cipher c = new ChaCha20Cipher(g_pbKey32, pbIV, true)) { c.Decrypt(m_pbData, 0, m_pbData.Length); } } else if(m_mp == PbMemProt.ExtCrypt) m_fExtCrypt(m_pbData, PbCryptFlags.Decrypt, m_lID); else { Debug.Assert(m_mp == PbMemProt.None); } m_mp = PbMemProt.None; } /// /// Get a copy of the protected data as a byte array. /// Please note that the returned byte array is not protected and /// can therefore been read by any other application. /// Make sure that your clear it properly after usage. /// /// Unprotected byte array. This is always a copy of the internal /// protected data and can therefore be cleared safely. public byte[] ReadData() { if(m_uDataLen == 0) return MemUtil.EmptyByteArray; byte[] pbReturn = new byte[m_uDataLen]; lock(m_objSync) { Decrypt(); Array.Copy(m_pbData, pbReturn, (int)m_uDataLen); Encrypt(); } return pbReturn; } /// /// Read the protected data and return it protected with a sequence /// of bytes generated by a random stream. /// /// Random number source. public byte[] ReadXorredData(CryptoRandomStream crsRandomSource) { Debug.Assert(crsRandomSource != null); if(crsRandomSource == null) throw new ArgumentNullException("crsRandomSource"); byte[] pbData = ReadData(); uint uLen = (uint)pbData.Length; byte[] randomPad = crsRandomSource.GetRandomBytes(uLen); Debug.Assert(randomPad.Length == pbData.Length); for(uint i = 0; i < uLen; ++i) pbData[i] ^= randomPad[i]; return pbData; } private int? m_hash = null; public override int GetHashCode() { if(m_hash.HasValue) return m_hash.Value; int h = (m_bProtected ? 0x7B11D289 : 0); byte[] pb = ReadData(); unchecked { for(int i = 0; i < pb.Length; ++i) h = (h << 3) + h + (int)pb[i]; } MemUtil.ZeroByteArray(pb); m_hash = h; return h; } public override bool Equals(object obj) { return Equals(obj as ProtectedBinary); } public bool Equals(ProtectedBinary other) { if(other == null) return false; // No assert if(m_bProtected != other.m_bProtected) return false; if(m_uDataLen != other.m_uDataLen) return false; byte[] pbL = ReadData(); byte[] pbR = other.ReadData(); bool bEq = MemUtil.ArraysEqual(pbL, pbR); MemUtil.ZeroByteArray(pbL); MemUtil.ZeroByteArray(pbR); #if DEBUG if(bEq) { Debug.Assert(GetHashCode() == other.GetHashCode()); } #endif return bEq; } } } KeePassLib/PwGroup.cs0000664000000000000000000013632413222430402013473 0ustar rootroot/* KeePass Password Safe - The Open-Source Password Manager Copyright (C) 2003-2018 Dominik Reichl This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ using System; using System.Collections.Generic; using System.Diagnostics; using System.Text.RegularExpressions; using KeePassLib.Collections; using KeePassLib.Delegates; using KeePassLib.Interfaces; using KeePassLib.Security; using KeePassLib.Utility; namespace KeePassLib { /// /// A group containing several password entries. /// public sealed class PwGroup : ITimeLogger, IStructureItem, IDeepCloneable { public const bool DefaultAutoTypeEnabled = true; public const bool DefaultSearchingEnabled = true; private PwObjectList m_listGroups = new PwObjectList(); private PwObjectList m_listEntries = new PwObjectList(); private PwGroup m_pParentGroup = null; private DateTime m_tParentGroupLastMod = PwDefs.DtDefaultNow; private PwUuid m_uuid = PwUuid.Zero; private string m_strName = string.Empty; private string m_strNotes = string.Empty; private PwIcon m_pwIcon = PwIcon.Folder; private PwUuid m_pwCustomIconID = PwUuid.Zero; private DateTime m_tCreation = PwDefs.DtDefaultNow; private DateTime m_tLastMod = PwDefs.DtDefaultNow; private DateTime m_tLastAccess = PwDefs.DtDefaultNow; private DateTime m_tExpire = PwDefs.DtDefaultNow; private bool m_bExpires = false; private ulong m_uUsageCount = 0; private bool m_bIsExpanded = true; private bool m_bVirtual = false; private string m_strDefaultAutoTypeSequence = string.Empty; private bool? m_bEnableAutoType = null; private bool? m_bEnableSearching = null; private PwUuid m_pwLastTopVisibleEntry = PwUuid.Zero; private StringDictionaryEx m_dCustomData = new StringDictionaryEx(); /// /// UUID of this group. /// public PwUuid Uuid { get { return m_uuid; } set { Debug.Assert(value != null); if(value == null) throw new ArgumentNullException("value"); m_uuid = value; } } /// /// The name of this group. Cannot be null. /// public string Name { get { return m_strName; } set { Debug.Assert(value != null); if(value == null) throw new ArgumentNullException("value"); m_strName = value; } } /// /// Comments about this group. Cannot be null. /// public string Notes { get { return m_strNotes; } set { Debug.Assert(value != null); if(value == null) throw new ArgumentNullException("value"); m_strNotes = value; } } /// /// Icon of the group. /// public PwIcon IconId { get { return m_pwIcon; } set { m_pwIcon = value; } } /// /// Get the custom icon ID. This value is 0, if no custom icon is /// being used (i.e. the icon specified by the IconID property /// should be displayed). /// public PwUuid CustomIconUuid { get { return m_pwCustomIconID; } set { Debug.Assert(value != null); if(value == null) throw new ArgumentNullException("value"); m_pwCustomIconID = value; } } /// /// Reference to the group to which this group belongs. May be null. /// public PwGroup ParentGroup { get { return m_pParentGroup; } // Plugins: use PwGroup.AddGroup instead. internal set { Debug.Assert(value != this); m_pParentGroup = value; } } /// /// The date/time when the location of the object was last changed. /// public DateTime LocationChanged { get { return m_tParentGroupLastMod; } set { m_tParentGroupLastMod = value; } } /// /// A flag that specifies if the group is shown as expanded or /// collapsed in the user interface. /// public bool IsExpanded { get { return m_bIsExpanded; } set { m_bIsExpanded = value; } } /// /// The date/time when this group was created. /// public DateTime CreationTime { get { return m_tCreation; } set { m_tCreation = value; } } /// /// The date/time when this group was last modified. /// public DateTime LastModificationTime { get { return m_tLastMod; } set { m_tLastMod = value; } } /// /// The date/time when this group was last accessed (read). /// public DateTime LastAccessTime { get { return m_tLastAccess; } set { m_tLastAccess = value; } } /// /// The date/time when this group expires. /// public DateTime ExpiryTime { get { return m_tExpire; } set { m_tExpire = value; } } /// /// Flag that determines if the group expires. /// public bool Expires { get { return m_bExpires; } set { m_bExpires = value; } } /// /// Get or set the usage count of the group. To increase the usage /// count by one, use the Touch function. /// public ulong UsageCount { get { return m_uUsageCount; } set { m_uUsageCount = value; } } /// /// Get a list of subgroups in this group. /// public PwObjectList Groups { get { return m_listGroups; } } /// /// Get a list of entries in this group. /// public PwObjectList Entries { get { return m_listEntries; } } /// /// A flag specifying whether this group is virtual or not. Virtual /// groups can contain links to entries stored in other groups. /// Note that this flag has to be interpreted and set by the calling /// code; it won't prevent you from accessing and modifying the list /// of entries in this group in any way. /// public bool IsVirtual { get { return m_bVirtual; } set { m_bVirtual = value; } } /// /// Default auto-type keystroke sequence for all entries in /// this group. This property can be an empty string, which /// means that the value should be inherited from the parent. /// public string DefaultAutoTypeSequence { get { return m_strDefaultAutoTypeSequence; } set { Debug.Assert(value != null); if(value == null) throw new ArgumentNullException("value"); m_strDefaultAutoTypeSequence = value; } } public bool? EnableAutoType { get { return m_bEnableAutoType; } set { m_bEnableAutoType = value; } } public bool? EnableSearching { get { return m_bEnableSearching; } set { m_bEnableSearching = value; } } public PwUuid LastTopVisibleEntry { get { return m_pwLastTopVisibleEntry; } set { Debug.Assert(value != null); if(value == null) throw new ArgumentNullException("value"); m_pwLastTopVisibleEntry = value; } } /// /// Custom data container that can be used by plugins to store /// own data in KeePass groups. /// The data is stored in the encrypted part of encrypted /// database files. /// Use unique names for your items, e.g. "PluginName_ItemName". /// public StringDictionaryEx CustomData { get { return m_dCustomData; } internal set { if(value == null) { Debug.Assert(false); throw new ArgumentNullException("value"); } m_dCustomData = value; } } public static EventHandler GroupTouched; public EventHandler Touched; /// /// Construct a new, empty group. /// public PwGroup() { } /// /// Construct a new, empty group. /// /// Create a new UUID for this group. /// Set creation, last access and last modification times to the current time. public PwGroup(bool bCreateNewUuid, bool bSetTimes) { if(bCreateNewUuid) m_uuid = new PwUuid(true); if(bSetTimes) { DateTime dtNow = DateTime.UtcNow; m_tCreation = dtNow; m_tLastMod = dtNow; m_tLastAccess = dtNow; m_tParentGroupLastMod = dtNow; } } /// /// Construct a new group. /// /// Create a new UUID for this group. /// Set creation, last access and last modification times to the current time. /// Name of the new group. /// Icon of the new group. public PwGroup(bool bCreateNewUuid, bool bSetTimes, string strName, PwIcon pwIcon) { if(bCreateNewUuid) m_uuid = new PwUuid(true); if(bSetTimes) { DateTime dtNow = DateTime.UtcNow; m_tCreation = dtNow; m_tLastMod = dtNow; m_tLastAccess = dtNow; m_tParentGroupLastMod = dtNow; } if(strName != null) m_strName = strName; m_pwIcon = pwIcon; } #if DEBUG // For display in debugger public override string ToString() { return (@"PwGroup '" + m_strName + @"'"); } #endif /// /// Deeply clone the current group. The returned group will be an exact /// value copy of the current object (including UUID, etc.). /// /// Exact value copy of the current PwGroup object. public PwGroup CloneDeep() { PwGroup pg = new PwGroup(false, false); pg.m_uuid = m_uuid; // PwUuid is immutable pg.m_listGroups = m_listGroups.CloneDeep(); pg.m_listEntries = m_listEntries.CloneDeep(); pg.m_pParentGroup = m_pParentGroup; pg.m_tParentGroupLastMod = m_tParentGroupLastMod; pg.m_strName = m_strName; pg.m_strNotes = m_strNotes; pg.m_pwIcon = m_pwIcon; pg.m_pwCustomIconID = m_pwCustomIconID; pg.m_tCreation = m_tCreation; pg.m_tLastMod = m_tLastMod; pg.m_tLastAccess = m_tLastAccess; pg.m_tExpire = m_tExpire; pg.m_bExpires = m_bExpires; pg.m_uUsageCount = m_uUsageCount; pg.m_bIsExpanded = m_bIsExpanded; pg.m_bVirtual = m_bVirtual; pg.m_strDefaultAutoTypeSequence = m_strDefaultAutoTypeSequence; pg.m_bEnableAutoType = m_bEnableAutoType; pg.m_bEnableSearching = m_bEnableSearching; pg.m_pwLastTopVisibleEntry = m_pwLastTopVisibleEntry; pg.m_dCustomData = m_dCustomData.CloneDeep(); return pg; } public PwGroup CloneStructure() { PwGroup pg = new PwGroup(false, false); pg.m_uuid = m_uuid; // PwUuid is immutable pg.m_tParentGroupLastMod = m_tParentGroupLastMod; // Do not assign m_pParentGroup foreach(PwGroup pgSub in m_listGroups) pg.AddGroup(pgSub.CloneStructure(), true); foreach(PwEntry peSub in m_listEntries) pg.AddEntry(peSub.CloneStructure(), true); return pg; } public bool EqualsGroup(PwGroup pg, PwCompareOptions pwOpt, MemProtCmpMode mpCmpStr) { if(pg == null) { Debug.Assert(false); return false; } bool bIgnoreLastAccess = ((pwOpt & PwCompareOptions.IgnoreLastAccess) != PwCompareOptions.None); bool bIgnoreLastMod = ((pwOpt & PwCompareOptions.IgnoreLastMod) != PwCompareOptions.None); if(!m_uuid.Equals(pg.m_uuid)) return false; if((pwOpt & PwCompareOptions.IgnoreParentGroup) == PwCompareOptions.None) { if(m_pParentGroup != pg.m_pParentGroup) return false; if(!bIgnoreLastMod && (m_tParentGroupLastMod != pg.m_tParentGroupLastMod)) return false; } if(m_strName != pg.m_strName) return false; if(m_strNotes != pg.m_strNotes) return false; if(m_pwIcon != pg.m_pwIcon) return false; if(!m_pwCustomIconID.Equals(pg.m_pwCustomIconID)) return false; if(m_tCreation != pg.m_tCreation) return false; if(!bIgnoreLastMod && (m_tLastMod != pg.m_tLastMod)) return false; if(!bIgnoreLastAccess && (m_tLastAccess != pg.m_tLastAccess)) return false; if(m_tExpire != pg.m_tExpire) return false; if(m_bExpires != pg.m_bExpires) return false; if(!bIgnoreLastAccess && (m_uUsageCount != pg.m_uUsageCount)) return false; // if(m_bIsExpanded != pg.m_bIsExpanded) return false; if(m_strDefaultAutoTypeSequence != pg.m_strDefaultAutoTypeSequence) return false; if(m_bEnableAutoType.HasValue != pg.m_bEnableAutoType.HasValue) return false; if(m_bEnableAutoType.HasValue) { if(m_bEnableAutoType.Value != pg.m_bEnableAutoType.Value) return false; } if(m_bEnableSearching.HasValue != pg.m_bEnableSearching.HasValue) return false; if(m_bEnableSearching.HasValue) { if(m_bEnableSearching.Value != pg.m_bEnableSearching.Value) return false; } if(!m_pwLastTopVisibleEntry.Equals(pg.m_pwLastTopVisibleEntry)) return false; if(!m_dCustomData.Equals(pg.m_dCustomData)) return false; if((pwOpt & PwCompareOptions.PropertiesOnly) == PwCompareOptions.None) { if(m_listEntries.UCount != pg.m_listEntries.UCount) return false; for(uint u = 0; u < m_listEntries.UCount; ++u) { PwEntry peA = m_listEntries.GetAt(u); PwEntry peB = pg.m_listEntries.GetAt(u); if(!peA.EqualsEntry(peB, pwOpt, mpCmpStr)) return false; } if(m_listGroups.UCount != pg.m_listGroups.UCount) return false; for(uint u = 0; u < m_listGroups.UCount; ++u) { PwGroup pgA = m_listGroups.GetAt(u); PwGroup pgB = pg.m_listGroups.GetAt(u); if(!pgA.EqualsGroup(pgB, pwOpt, mpCmpStr)) return false; } } return true; } /// /// Assign properties to the current group based on a template group. /// /// Template group. Must not be null. /// Only set the properties of the template group /// if it is newer than the current one. /// If true, the /// LocationChanged property is copied, otherwise not. public void AssignProperties(PwGroup pgTemplate, bool bOnlyIfNewer, bool bAssignLocationChanged) { Debug.Assert(pgTemplate != null); if(pgTemplate == null) throw new ArgumentNullException("pgTemplate"); if(bOnlyIfNewer && (TimeUtil.Compare(pgTemplate.m_tLastMod, m_tLastMod, true) < 0)) return; // Template UUID should be the same as the current one Debug.Assert(m_uuid.Equals(pgTemplate.m_uuid)); m_uuid = pgTemplate.m_uuid; if(bAssignLocationChanged) m_tParentGroupLastMod = pgTemplate.m_tParentGroupLastMod; m_strName = pgTemplate.m_strName; m_strNotes = pgTemplate.m_strNotes; m_pwIcon = pgTemplate.m_pwIcon; m_pwCustomIconID = pgTemplate.m_pwCustomIconID; m_tCreation = pgTemplate.m_tCreation; m_tLastMod = pgTemplate.m_tLastMod; m_tLastAccess = pgTemplate.m_tLastAccess; m_tExpire = pgTemplate.m_tExpire; m_bExpires = pgTemplate.m_bExpires; m_uUsageCount = pgTemplate.m_uUsageCount; m_strDefaultAutoTypeSequence = pgTemplate.m_strDefaultAutoTypeSequence; m_bEnableAutoType = pgTemplate.m_bEnableAutoType; m_bEnableSearching = pgTemplate.m_bEnableSearching; m_pwLastTopVisibleEntry = pgTemplate.m_pwLastTopVisibleEntry; m_dCustomData = pgTemplate.m_dCustomData.CloneDeep(); } /// /// Touch the group. This function updates the internal last access /// time. If the parameter is true, /// the last modification time gets updated, too. /// /// Modify last modification time. public void Touch(bool bModified) { Touch(bModified, true); } /// /// Touch the group. This function updates the internal last access /// time. If the parameter is true, /// the last modification time gets updated, too. /// /// Modify last modification time. /// If true, all parent objects /// get touched, too. public void Touch(bool bModified, bool bTouchParents) { m_tLastAccess = DateTime.UtcNow; ++m_uUsageCount; if(bModified) m_tLastMod = m_tLastAccess; if(this.Touched != null) this.Touched(this, new ObjectTouchedEventArgs(this, bModified, bTouchParents)); if(PwGroup.GroupTouched != null) PwGroup.GroupTouched(this, new ObjectTouchedEventArgs(this, bModified, bTouchParents)); if(bTouchParents && (m_pParentGroup != null)) m_pParentGroup.Touch(bModified, true); } /// /// Get number of groups and entries in the current group. This function /// can also traverse through all subgroups and accumulate their counts /// (recursive mode). /// /// If this parameter is true, all /// subgroups and entries in subgroups will be counted and added to /// the returned value. If it is false, only the number of /// subgroups and entries of the current group is returned. /// Number of subgroups. /// Number of entries. public void GetCounts(bool bRecursive, out uint uNumGroups, out uint uNumEntries) { if(bRecursive) { uint uTotalGroups = m_listGroups.UCount; uint uTotalEntries = m_listEntries.UCount; uint uSubGroupCount, uSubEntryCount; foreach(PwGroup pg in m_listGroups) { pg.GetCounts(true, out uSubGroupCount, out uSubEntryCount); uTotalGroups += uSubGroupCount; uTotalEntries += uSubEntryCount; } uNumGroups = uTotalGroups; uNumEntries = uTotalEntries; } else // !bRecursive { uNumGroups = m_listGroups.UCount; uNumEntries = m_listEntries.UCount; } } public uint GetEntriesCount(bool bRecursive) { uint uGroups, uEntries; GetCounts(bRecursive, out uGroups, out uEntries); return uEntries; } /// /// Traverse the group/entry tree in the current group. Various traversal /// methods are available. /// /// Specifies the traversal method. /// Function that performs an action on /// the currently visited group (see GroupHandler for more). /// This parameter may be null, in this case the tree is traversed but /// you don't get notifications for each visited group. /// Function that performs an action on /// the currently visited entry (see EntryHandler for more). /// This parameter may be null. /// Returns true if all entries and groups have been /// traversed. If the traversal has been canceled by one of the two /// handlers, the return value is false. public bool TraverseTree(TraversalMethod tm, GroupHandler groupHandler, EntryHandler entryHandler) { bool bRet = false; switch(tm) { case TraversalMethod.None: bRet = true; break; case TraversalMethod.PreOrder: bRet = PreOrderTraverseTree(groupHandler, entryHandler); break; default: Debug.Assert(false); break; } return bRet; } private bool PreOrderTraverseTree(GroupHandler groupHandler, EntryHandler entryHandler) { if(entryHandler != null) { foreach(PwEntry pe in m_listEntries) { if(!entryHandler(pe)) return false; } } foreach(PwGroup pg in m_listGroups) { if(groupHandler != null) { if(!groupHandler(pg)) return false; } if(!pg.PreOrderTraverseTree(groupHandler, entryHandler)) return false; } return true; } /// /// Pack all groups into one flat linked list of references (recursively). /// /// Flat list of all groups. public LinkedList GetFlatGroupList() { LinkedList list = new LinkedList(); foreach(PwGroup pg in m_listGroups) { list.AddLast(pg); if(pg.Groups.UCount != 0) LinearizeGroupRecursive(list, pg, 1); } return list; } private void LinearizeGroupRecursive(LinkedList list, PwGroup pg, ushort uLevel) { Debug.Assert(pg != null); if(pg == null) return; foreach(PwGroup pwg in pg.Groups) { list.AddLast(pwg); if(pwg.Groups.UCount != 0) LinearizeGroupRecursive(list, pwg, (ushort)(uLevel + 1)); } } /// /// Pack all entries into one flat linked list of references. Temporary /// group IDs are assigned automatically. /// /// A flat group list created by /// GetFlatGroupList. /// Flat list of all entries. public static LinkedList GetFlatEntryList(LinkedList flatGroupList) { Debug.Assert(flatGroupList != null); if(flatGroupList == null) return null; LinkedList list = new LinkedList(); foreach(PwGroup pg in flatGroupList) { foreach(PwEntry pe in pg.Entries) list.AddLast(pe); } return list; } /// /// Enable protection of a specific string field type. /// /// Name of the string field to protect or unprotect. /// Enable protection or not. /// Returns true, if the operation completed successfully, /// otherwise false. public bool EnableStringFieldProtection(string strFieldName, bool bEnable) { Debug.Assert(strFieldName != null); EntryHandler eh = delegate(PwEntry pe) { // Enable protection of current string pe.Strings.EnableProtection(strFieldName, bEnable); // Do the same for all history items foreach(PwEntry peHistory in pe.History) { peHistory.Strings.EnableProtection(strFieldName, bEnable); } return true; }; return PreOrderTraverseTree(null, eh); } /// /// Search this group and all subgroups for entries. /// /// Specifies the search parameters. /// Entry list in which the search results /// will be stored. public void SearchEntries(SearchParameters sp, PwObjectList lResults) { SearchEntries(sp, lResults, null); } /// /// Search this group and all subgroups for entries. /// /// Specifies the search parameters. /// Entry list in which the search results /// will be stored. /// Optional status reporting object. public void SearchEntries(SearchParameters sp, PwObjectList lResults, IStatusLogger slStatus) { if(sp == null) { Debug.Assert(false); return; } if(lResults == null) { Debug.Assert(false); return; } PwObjectList lCand = GetEntries(true); DateTime dtNow = DateTime.UtcNow; PwObjectList l = new PwObjectList(); foreach(PwEntry pe in lCand) { if(sp.RespectEntrySearchingDisabled && !pe.GetSearchingEnabled()) continue; if(sp.ExcludeExpired && pe.Expires && (pe.ExpiryTime <= dtNow)) continue; l.Add(pe); } lCand = l; List lTerms; if(sp.RegularExpression) { lTerms = new List(); lTerms.Add((sp.SearchString ?? string.Empty).Trim()); } else lTerms = StrUtil.SplitSearchTerms(sp.SearchString); // Search longer strings first (for improved performance) lTerms.Sort(StrUtil.CompareLengthGt); ulong uPrcEntries = 0, uTotalEntries = lCand.UCount; SearchParameters spSub = sp.Clone(); for(int iTerm = 0; iTerm < lTerms.Count; ++iTerm) { // Update counters for a better state guess if(slStatus != null) { ulong uRemRounds = (ulong)(lTerms.Count - iTerm); uTotalEntries = uPrcEntries + (uRemRounds * lCand.UCount); } spSub.SearchString = lTerms[iTerm]; // No trim // spSub.RespectEntrySearchingDisabled = false; // Ignored by sub // spSub.ExcludeExpired = false; // Ignored by sub bool bNegate = false; if(spSub.SearchString.StartsWith(@"-") && (spSub.SearchString.Length >= 2)) { spSub.SearchString = spSub.SearchString.Substring(1); bNegate = true; } l = new PwObjectList(); if(!SearchEntriesSingle(lCand, spSub, l, slStatus, ref uPrcEntries, uTotalEntries)) { lCand.Clear(); break; } if(bNegate) { PwObjectList lRem = new PwObjectList(); foreach(PwEntry pe in lCand) { if(l.IndexOf(pe) < 0) lRem.Add(pe); } lCand = lRem; } else lCand = l; } Debug.Assert(lResults.UCount == 0); lResults.Clear(); lResults.Add(lCand); } private static bool SearchEntriesSingle(PwObjectList lSource, SearchParameters sp, PwObjectList lResults, IStatusLogger slStatus, ref ulong uPrcEntries, ulong uTotalEntries) { if(lSource == null) { Debug.Assert(false); return true; } if(sp == null) { Debug.Assert(false); return true; } if(lResults == null) { Debug.Assert(false); return true; } Debug.Assert(lResults.UCount == 0); bool bTitle = sp.SearchInTitles; bool bUserName = sp.SearchInUserNames; bool bPassword = sp.SearchInPasswords; bool bUrl = sp.SearchInUrls; bool bNotes = sp.SearchInNotes; bool bOther = sp.SearchInOther; bool bStringName = sp.SearchInStringNames; bool bTags = sp.SearchInTags; bool bUuids = sp.SearchInUuids; bool bGroupName = sp.SearchInGroupNames; // bool bExcludeExpired = sp.ExcludeExpired; // bool bRespectEntrySearchingDisabled = sp.RespectEntrySearchingDisabled; Regex rx = null; if(sp.RegularExpression) { RegexOptions ro = RegexOptions.None; // RegexOptions.Compiled if((sp.ComparisonMode == StringComparison.CurrentCultureIgnoreCase) || #if !KeePassUAP (sp.ComparisonMode == StringComparison.InvariantCultureIgnoreCase) || #endif (sp.ComparisonMode == StringComparison.OrdinalIgnoreCase)) { ro |= RegexOptions.IgnoreCase; } rx = new Regex(sp.SearchString, ro); } ulong uLocalPrcEntries = uPrcEntries; if(sp.SearchString.Length == 0) lResults.Add(lSource); else { foreach(PwEntry pe in lSource) { if(slStatus != null) { if(!slStatus.SetProgress((uint)((uLocalPrcEntries * 100UL) / uTotalEntries))) return false; ++uLocalPrcEntries; } // if(bRespectEntrySearchingDisabled && !pe.GetSearchingEnabled()) // continue; // if(bExcludeExpired && pe.Expires && (pe.ExpiryTime <= dtNow)) // continue; uint uInitialResults = lResults.UCount; foreach(KeyValuePair kvp in pe.Strings) { string strKey = kvp.Key; if(strKey == PwDefs.TitleField) { if(bTitle) SearchEvalAdd(sp, kvp.Value.ReadString(), rx, pe, lResults); } else if(strKey == PwDefs.UserNameField) { if(bUserName) SearchEvalAdd(sp, kvp.Value.ReadString(), rx, pe, lResults); } else if(strKey == PwDefs.PasswordField) { if(bPassword) SearchEvalAdd(sp, kvp.Value.ReadString(), rx, pe, lResults); } else if(strKey == PwDefs.UrlField) { if(bUrl) SearchEvalAdd(sp, kvp.Value.ReadString(), rx, pe, lResults); } else if(strKey == PwDefs.NotesField) { if(bNotes) SearchEvalAdd(sp, kvp.Value.ReadString(), rx, pe, lResults); } else if(bOther) SearchEvalAdd(sp, kvp.Value.ReadString(), rx, pe, lResults); // An entry can match only once => break if we have added it if(lResults.UCount != uInitialResults) break; } if(bStringName) { foreach(KeyValuePair kvp in pe.Strings) { if(lResults.UCount != uInitialResults) break; SearchEvalAdd(sp, kvp.Key, rx, pe, lResults); } } if(bTags) { foreach(string strTag in pe.Tags) { if(lResults.UCount != uInitialResults) break; SearchEvalAdd(sp, strTag, rx, pe, lResults); } } if(bUuids && (lResults.UCount == uInitialResults)) SearchEvalAdd(sp, pe.Uuid.ToHexString(), rx, pe, lResults); if(bGroupName && (lResults.UCount == uInitialResults) && (pe.ParentGroup != null)) SearchEvalAdd(sp, pe.ParentGroup.Name, rx, pe, lResults); } } uPrcEntries = uLocalPrcEntries; return true; } private static void SearchEvalAdd(SearchParameters sp, string strData, Regex rx, PwEntry pe, PwObjectList lResults) { if(sp == null) { Debug.Assert(false); return; } if(strData == null) { Debug.Assert(false); return; } if(pe == null) { Debug.Assert(false); return; } if(lResults == null) { Debug.Assert(false); return; } bool bMatch; if(rx == null) bMatch = (strData.IndexOf(sp.SearchString, sp.ComparisonMode) >= 0); else bMatch = rx.IsMatch(strData); if(!bMatch && (sp.DataTransformationFn != null)) { string strCmp = sp.DataTransformationFn(strData, pe); if(!object.ReferenceEquals(strCmp, strData)) { if(rx == null) bMatch = (strCmp.IndexOf(sp.SearchString, sp.ComparisonMode) >= 0); else bMatch = rx.IsMatch(strCmp); } } if(bMatch) lResults.Add(pe); } public List BuildEntryTagsList() { return BuildEntryTagsList(false); } public List BuildEntryTagsList(bool bSort) { List vTags = new List(); EntryHandler eh = delegate(PwEntry pe) { foreach(string strTag in pe.Tags) { bool bFound = false; for(int i = 0; i < vTags.Count; ++i) { if(vTags[i].Equals(strTag, StrUtil.CaseIgnoreCmp)) { bFound = true; break; } } if(!bFound) vTags.Add(strTag); } return true; }; TraverseTree(TraversalMethod.PreOrder, null, eh); if(bSort) vTags.Sort(StrUtil.CaseIgnoreComparer); return vTags; } #if !KeePassLibSD public IDictionary BuildEntryTagsDict(bool bSort) { IDictionary d; if(!bSort) d = new Dictionary(StrUtil.CaseIgnoreComparer); else d = new SortedDictionary(StrUtil.CaseIgnoreComparer); EntryHandler eh = delegate(PwEntry pe) { foreach(string strTag in pe.Tags) { uint u; if(d.TryGetValue(strTag, out u)) d[strTag] = u + 1; else d[strTag] = 1; } return true; }; TraverseTree(TraversalMethod.PreOrder, null, eh); return d; } #endif public void FindEntriesByTag(string strTag, PwObjectList listStorage, bool bSearchRecursive) { if(strTag == null) throw new ArgumentNullException("strTag"); if(strTag.Length == 0) return; foreach(PwEntry pe in m_listEntries) { foreach(string strEntryTag in pe.Tags) { if(strEntryTag.Equals(strTag, StrUtil.CaseIgnoreCmp)) { listStorage.Add(pe); break; } } } if(bSearchRecursive) { foreach(PwGroup pg in m_listGroups) pg.FindEntriesByTag(strTag, listStorage, true); } } /// /// Find a group. /// /// UUID identifying the group the caller is looking for. /// If true, the search is recursive. /// Returns reference to found group, otherwise null. public PwGroup FindGroup(PwUuid uuid, bool bSearchRecursive) { // Do not assert on PwUuid.Zero if(m_uuid.Equals(uuid)) return this; if(bSearchRecursive) { PwGroup pgRec; foreach(PwGroup pg in m_listGroups) { pgRec = pg.FindGroup(uuid, true); if(pgRec != null) return pgRec; } } else // Not recursive { foreach(PwGroup pg in m_listGroups) { if(pg.m_uuid.Equals(uuid)) return pg; } } return null; } /// /// Find an object. /// /// UUID of the object to find. /// Specifies whether to search recursively. /// If null, groups and entries are /// searched. If true, only entries are searched. If false, /// only groups are searched. /// Reference to the object, if found. Otherwise null. public IStructureItem FindObject(PwUuid uuid, bool bRecursive, bool? bEntries) { if(bEntries.HasValue) { if(bEntries.Value) return FindEntry(uuid, bRecursive); else return FindGroup(uuid, bRecursive); } PwGroup pg = FindGroup(uuid, bRecursive); if(pg != null) return pg; return FindEntry(uuid, bRecursive); } /// /// Try to find a subgroup and create it, if it doesn't exist yet. /// /// Name of the subgroup. /// If the group isn't found: create it. /// Returns a reference to the requested group or null if /// it doesn't exist and shouldn't be created. public PwGroup FindCreateGroup(string strName, bool bCreateIfNotFound) { Debug.Assert(strName != null); if(strName == null) throw new ArgumentNullException("strName"); foreach(PwGroup pg in m_listGroups) { if(pg.Name == strName) return pg; } if(!bCreateIfNotFound) return null; PwGroup pgNew = new PwGroup(true, true, strName, PwIcon.Folder); AddGroup(pgNew, true); return pgNew; } /// /// Find an entry. /// /// UUID identifying the entry the caller is looking for. /// If true, the search is recursive. /// Returns reference to found entry, otherwise null. public PwEntry FindEntry(PwUuid uuid, bool bSearchRecursive) { foreach(PwEntry pe in m_listEntries) { if(pe.Uuid.Equals(uuid)) return pe; } if(bSearchRecursive) { PwEntry peSub; foreach(PwGroup pg in m_listGroups) { peSub = pg.FindEntry(uuid, true); if(peSub != null) return peSub; } } return null; } /// /// Get the full path of a group. /// /// Full path of the group. public string GetFullPath() { return GetFullPath(".", false); } /// /// Get the full path of a group. /// /// String that separates the group /// names. /// Specifies whether the returned /// path starts with the topmost group. /// Full path of the group. public string GetFullPath(string strSeparator, bool bIncludeTopMostGroup) { Debug.Assert(strSeparator != null); if(strSeparator == null) throw new ArgumentNullException("strSeparator"); string strPath = m_strName; PwGroup pg = m_pParentGroup; while(pg != null) { if((!bIncludeTopMostGroup) && (pg.m_pParentGroup == null)) break; strPath = pg.Name + strSeparator + strPath; pg = pg.m_pParentGroup; } return strPath; } /// /// Assign new UUIDs to groups and entries. /// /// Create new UUIDs for subgroups. /// Create new UUIDs for entries. /// Recursive tree traversal. public void CreateNewItemUuids(bool bNewGroups, bool bNewEntries, bool bRecursive) { if(bNewGroups) { foreach(PwGroup pg in m_listGroups) pg.Uuid = new PwUuid(true); } if(bNewEntries) { foreach(PwEntry pe in m_listEntries) pe.SetUuid(new PwUuid(true), true); } if(bRecursive) { foreach(PwGroup pg in m_listGroups) pg.CreateNewItemUuids(bNewGroups, bNewEntries, true); } } public void TakeOwnership(bool bTakeSubGroups, bool bTakeEntries, bool bRecursive) { if(bTakeSubGroups) { foreach(PwGroup pg in m_listGroups) pg.ParentGroup = this; } if(bTakeEntries) { foreach(PwEntry pe in m_listEntries) pe.ParentGroup = this; } if(bRecursive) { foreach(PwGroup pg in m_listGroups) pg.TakeOwnership(bTakeSubGroups, bTakeEntries, true); } } #if !KeePassLibSD /// /// Find/create a subtree of groups. /// /// Tree string. /// Separators that delimit groups in the /// strTree parameter. public PwGroup FindCreateSubTree(string strTree, char[] vSeparators) { return FindCreateSubTree(strTree, vSeparators, true); } public PwGroup FindCreateSubTree(string strTree, char[] vSeparators, bool bAllowCreate) { if(vSeparators == null) { Debug.Assert(false); vSeparators = new char[0]; } string[] v = new string[vSeparators.Length]; for(int i = 0; i < vSeparators.Length; ++i) v[i] = new string(vSeparators[i], 1); return FindCreateSubTree(strTree, v, bAllowCreate); } public PwGroup FindCreateSubTree(string strTree, string[] vSeparators, bool bAllowCreate) { Debug.Assert(strTree != null); if(strTree == null) return this; if(strTree.Length == 0) return this; string[] vGroups = strTree.Split(vSeparators, StringSplitOptions.None); if((vGroups == null) || (vGroups.Length == 0)) return this; PwGroup pgContainer = this; for(int nGroup = 0; nGroup < vGroups.Length; ++nGroup) { if(string.IsNullOrEmpty(vGroups[nGroup])) continue; bool bFound = false; foreach(PwGroup pg in pgContainer.Groups) { if(pg.Name == vGroups[nGroup]) { pgContainer = pg; bFound = true; break; } } if(!bFound) { if(!bAllowCreate) return null; PwGroup pg = new PwGroup(true, true, vGroups[nGroup], PwIcon.Folder); pgContainer.AddGroup(pg, true); pgContainer = pg; } } return pgContainer; } #endif /// /// Get the level of the group (i.e. the number of parent groups). /// /// Number of parent groups. public uint GetLevel() { PwGroup pg = m_pParentGroup; uint uLevel = 0; while(pg != null) { pg = pg.ParentGroup; ++uLevel; } return uLevel; } public string GetAutoTypeSequenceInherited() { if(m_strDefaultAutoTypeSequence.Length > 0) return m_strDefaultAutoTypeSequence; if(m_pParentGroup != null) return m_pParentGroup.GetAutoTypeSequenceInherited(); return string.Empty; } public bool GetAutoTypeEnabledInherited() { if(m_bEnableAutoType.HasValue) return m_bEnableAutoType.Value; if(m_pParentGroup != null) return m_pParentGroup.GetAutoTypeEnabledInherited(); return DefaultAutoTypeEnabled; } public bool GetSearchingEnabledInherited() { if(m_bEnableSearching.HasValue) return m_bEnableSearching.Value; if(m_pParentGroup != null) return m_pParentGroup.GetSearchingEnabledInherited(); return DefaultSearchingEnabled; } /// /// Get a list of subgroups (not including this one). /// /// If true, subgroups are added /// recursively, i.e. all child groups are returned, too. /// List of subgroups. If is /// true, it is guaranteed that subsubgroups appear after /// subgroups. public PwObjectList GetGroups(bool bRecursive) { if(bRecursive == false) return m_listGroups; PwObjectList list = m_listGroups.CloneShallow(); foreach(PwGroup pgSub in m_listGroups) { list.Add(pgSub.GetGroups(true)); } return list; } public PwObjectList GetEntries(bool bIncludeSubGroupEntries) { PwObjectList l = new PwObjectList(); GroupHandler gh = delegate(PwGroup pg) { l.Add(pg.Entries); return true; }; gh(this); if(bIncludeSubGroupEntries) PreOrderTraverseTree(gh, null); Debug.Assert(l.UCount == GetEntriesCount(bIncludeSubGroupEntries)); return l; } /// /// Get objects contained in this group. /// /// Specifies whether to search recursively. /// If null, the returned list contains /// groups and entries. If true, the returned list contains only /// entries. If false, the returned list contains only groups. /// List of objects. public List GetObjects(bool bRecursive, bool? bEntries) { List list = new List(); if(!bEntries.HasValue || !bEntries.Value) { PwObjectList lGroups = GetGroups(bRecursive); foreach(PwGroup pg in lGroups) list.Add(pg); } if(!bEntries.HasValue || bEntries.Value) { PwObjectList lEntries = GetEntries(bRecursive); foreach(PwEntry pe in lEntries) list.Add(pe); } return list; } public bool IsContainedIn(PwGroup pgContainer) { PwGroup pgCur = m_pParentGroup; while(pgCur != null) { if(pgCur == pgContainer) return true; pgCur = pgCur.m_pParentGroup; } return false; } /// /// Add a subgroup to this group. /// /// Group to be added. Must not be null. /// If this parameter is true, the /// parent group reference of the subgroup will be set to the current /// group (i.e. the current group takes ownership of the subgroup). public void AddGroup(PwGroup subGroup, bool bTakeOwnership) { AddGroup(subGroup, bTakeOwnership, false); } /// /// Add a subgroup to this group. /// /// Group to be added. Must not be null. /// If this parameter is true, the /// parent group reference of the subgroup will be set to the current /// group (i.e. the current group takes ownership of the subgroup). /// If true, the /// LocationChanged property of the subgroup is updated. public void AddGroup(PwGroup subGroup, bool bTakeOwnership, bool bUpdateLocationChangedOfSub) { if(subGroup == null) throw new ArgumentNullException("subGroup"); m_listGroups.Add(subGroup); if(bTakeOwnership) subGroup.m_pParentGroup = this; if(bUpdateLocationChangedOfSub) subGroup.LocationChanged = DateTime.UtcNow; } /// /// Add an entry to this group. /// /// Entry to be added. Must not be null. /// If this parameter is true, the /// parent group reference of the entry will be set to the current /// group (i.e. the current group takes ownership of the entry). public void AddEntry(PwEntry pe, bool bTakeOwnership) { AddEntry(pe, bTakeOwnership, false); } /// /// Add an entry to this group. /// /// Entry to be added. Must not be null. /// If this parameter is true, the /// parent group reference of the entry will be set to the current /// group (i.e. the current group takes ownership of the entry). /// If true, the /// LocationChanged property of the entry is updated. public void AddEntry(PwEntry pe, bool bTakeOwnership, bool bUpdateLocationChangedOfEntry) { if(pe == null) throw new ArgumentNullException("pe"); m_listEntries.Add(pe); // Do not remove the entry from its previous parent group, // only assign it to the new one if(bTakeOwnership) pe.ParentGroup = this; if(bUpdateLocationChangedOfEntry) pe.LocationChanged = DateTime.UtcNow; } public void SortSubGroups(bool bRecursive) { m_listGroups.Sort(new PwGroupComparer()); if(bRecursive) { foreach(PwGroup pgSub in m_listGroups) pgSub.SortSubGroups(true); } } public void DeleteAllObjects(PwDatabase pdContext) { DateTime dtNow = DateTime.UtcNow; foreach(PwEntry pe in m_listEntries) { PwDeletedObject pdo = new PwDeletedObject(pe.Uuid, dtNow); pdContext.DeletedObjects.Add(pdo); } m_listEntries.Clear(); foreach(PwGroup pg in m_listGroups) { pg.DeleteAllObjects(pdContext); PwDeletedObject pdo = new PwDeletedObject(pg.Uuid, dtNow); pdContext.DeletedObjects.Add(pdo); } m_listGroups.Clear(); } internal List GetTopSearchSkippedGroups() { List l = new List(); if(!GetSearchingEnabledInherited()) l.Add(this); else GetTopSearchSkippedGroupsRec(l); return l; } private void GetTopSearchSkippedGroupsRec(List l) { if(m_bEnableSearching.HasValue && !m_bEnableSearching.Value) { l.Add(this); return; } else { Debug.Assert(GetSearchingEnabledInherited()); } foreach(PwGroup pgSub in m_listGroups) pgSub.GetTopSearchSkippedGroupsRec(l); } public void SetCreatedNow(bool bRecursive) { DateTime dt = DateTime.UtcNow; m_tCreation = dt; m_tLastAccess = dt; if(!bRecursive) return; GroupHandler gh = delegate(PwGroup pg) { pg.m_tCreation = dt; pg.m_tLastAccess = dt; return true; }; EntryHandler eh = delegate(PwEntry pe) { pe.CreationTime = dt; pe.LastAccessTime = dt; return true; }; TraverseTree(TraversalMethod.PreOrder, gh, eh); } public PwGroup Duplicate() { PwGroup pg = CloneDeep(); pg.Uuid = new PwUuid(true); pg.CreateNewItemUuids(true, true, true); pg.SetCreatedNow(true); pg.TakeOwnership(true, true, true); return pg; } } public sealed class PwGroupComparer : IComparer { public PwGroupComparer() { } public int Compare(PwGroup a, PwGroup b) { return StrUtil.CompareNaturally(a.Name, b.Name); } } } KeePassLib/Native/0000775000000000000000000000000013222430400012754 5ustar rootrootKeePassLib/Native/NativeMethods.Unix.cs0000664000000000000000000001550113222430400017001 0ustar rootroot/* KeePass Password Safe - The Open-Source Password Manager Copyright (C) 2003-2018 Dominik Reichl This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ using System; using System.Collections.Generic; using System.Diagnostics; using System.Reflection; using System.Runtime.InteropServices; using System.Text; #if !KeePassUAP using System.Windows.Forms; #endif namespace KeePassLib.Native { internal static partial class NativeMethods { #if (!KeePassLibSD && !KeePassUAP) [StructLayout(LayoutKind.Sequential)] private struct XClassHint { public IntPtr res_name; public IntPtr res_class; } [DllImport("libX11")] private static extern int XSetClassHint(IntPtr display, IntPtr window, IntPtr class_hints); private static Type m_tXplatUIX11 = null; private static Type GetXplatUIX11Type(bool bThrowOnError) { if(m_tXplatUIX11 == null) { // CheckState is in System.Windows.Forms string strTypeCS = typeof(CheckState).AssemblyQualifiedName; string strTypeX11 = strTypeCS.Replace("CheckState", "XplatUIX11"); m_tXplatUIX11 = Type.GetType(strTypeX11, bThrowOnError, true); } return m_tXplatUIX11; } private static Type m_tHwnd = null; private static Type GetHwndType(bool bThrowOnError) { if(m_tHwnd == null) { // CheckState is in System.Windows.Forms string strTypeCS = typeof(CheckState).AssemblyQualifiedName; string strTypeHwnd = strTypeCS.Replace("CheckState", "Hwnd"); m_tHwnd = Type.GetType(strTypeHwnd, bThrowOnError, true); } return m_tHwnd; } internal static void SetWmClass(Form f, string strName, string strClass) { if(f == null) { Debug.Assert(false); return; } // The following crashes under Mac OS X (SIGSEGV in native code, // not just an exception), thus skip it when we're on Mac OS X; // https://sourceforge.net/projects/keepass/forums/forum/329221/topic/5860588 if(NativeLib.GetPlatformID() == PlatformID.MacOSX) return; try { Type tXplatUIX11 = GetXplatUIX11Type(true); FieldInfo fiDisplayHandle = tXplatUIX11.GetField("DisplayHandle", BindingFlags.NonPublic | BindingFlags.Static); IntPtr hDisplay = (IntPtr)fiDisplayHandle.GetValue(null); Type tHwnd = GetHwndType(true); MethodInfo miObjectFromHandle = tHwnd.GetMethod("ObjectFromHandle", BindingFlags.Public | BindingFlags.Static); object oHwnd = miObjectFromHandle.Invoke(null, new object[] { f.Handle }); FieldInfo fiWholeWindow = tHwnd.GetField("whole_window", BindingFlags.NonPublic | BindingFlags.Instance); IntPtr hWindow = (IntPtr)fiWholeWindow.GetValue(oHwnd); XClassHint xch = new XClassHint(); xch.res_name = Marshal.StringToCoTaskMemAnsi(strName ?? string.Empty); xch.res_class = Marshal.StringToCoTaskMemAnsi(strClass ?? string.Empty); IntPtr pXch = Marshal.AllocCoTaskMem(Marshal.SizeOf(xch)); Marshal.StructureToPtr(xch, pXch, false); XSetClassHint(hDisplay, hWindow, pXch); Marshal.FreeCoTaskMem(pXch); Marshal.FreeCoTaskMem(xch.res_name); Marshal.FreeCoTaskMem(xch.res_class); } catch(Exception) { Debug.Assert(false); } } #endif // ============================================================= // LibGCrypt 1.8.1 private const string LibGCrypt = "libgcrypt.so.20"; internal const int GCRY_CIPHER_AES256 = 9; internal const int GCRY_CIPHER_MODE_ECB = 1; [DllImport(LibGCrypt)] internal static extern IntPtr gcry_check_version(IntPtr lpReqVersion); [DllImport(LibGCrypt)] internal static extern uint gcry_cipher_open(ref IntPtr ph, int nAlgo, int nMode, uint uFlags); [DllImport(LibGCrypt)] internal static extern void gcry_cipher_close(IntPtr h); [DllImport(LibGCrypt)] internal static extern uint gcry_cipher_setkey(IntPtr h, IntPtr pbKey, IntPtr cbKey); // cbKey is size_t [DllImport(LibGCrypt)] internal static extern uint gcry_cipher_encrypt(IntPtr h, IntPtr pbOut, IntPtr cbOut, IntPtr pbIn, IntPtr cbIn); // cb* are size_t /* internal static IntPtr Utf8ZFromString(string str) { byte[] pb = StrUtil.Utf8.GetBytes(str ?? string.Empty); IntPtr p = Marshal.AllocCoTaskMem(pb.Length + 1); if(p != IntPtr.Zero) { Marshal.Copy(pb, 0, p, pb.Length); Marshal.WriteByte(p, pb.Length, 0); } else { Debug.Assert(false); } return p; } internal static string Utf8ZToString(IntPtr p) { if(p == IntPtr.Zero) { Debug.Assert(false); return null; } List l = new List(); for(int i = 0; i < int.MaxValue; ++i) { byte bt = Marshal.ReadByte(p, i); if(bt == 0) break; l.Add(bt); } return StrUtil.Utf8.GetString(l.ToArray()); } internal static void Utf8ZFree(IntPtr p) { if(p != IntPtr.Zero) Marshal.FreeCoTaskMem(p); } */ /* // ============================================================= // LibGLib 2 private const string LibGLib = "libglib-2.0.so.0"; internal const int G_FALSE = 0; // https://developer.gnome.org/glib/stable/glib-Memory-Allocation.html [DllImport(LibGLib)] internal static extern void g_free(IntPtr pMem); // pMem may be null // ============================================================= // LibGTK 3 (3.22.11 / 3.22.24) private const string LibGtk = "libgtk-3.so.0"; internal static readonly IntPtr GDK_SELECTION_PRIMARY = new IntPtr(1); internal static readonly IntPtr GDK_SELECTION_CLIPBOARD = new IntPtr(69); [DllImport(LibGtk)] internal static extern int gtk_init_check(IntPtr pArgc, IntPtr pArgv); [DllImport(LibGtk)] // The returned handle is owned by GTK and must not be freed internal static extern IntPtr gtk_clipboard_get(IntPtr pSelection); [DllImport(LibGtk)] internal static extern void gtk_clipboard_clear(IntPtr hClipboard); [DllImport(LibGtk)] internal static extern IntPtr gtk_clipboard_wait_for_text(IntPtr hClipboard); [DllImport(LibGtk)] internal static extern void gtk_clipboard_set_text(IntPtr hClipboard, IntPtr lpText, int cbLen); [DllImport(LibGtk)] internal static extern void gtk_clipboard_store(IntPtr hClipboard); */ } } KeePassLib/Native/NativeLib.cs0000664000000000000000000003121213222430400015157 0ustar rootroot/* KeePass Password Safe - The Open-Source Password Manager Copyright (C) 2003-2018 Dominik Reichl This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ using System; using System.Collections.Generic; using System.Diagnostics; using System.Reflection; using System.Runtime.InteropServices; using System.Text; using System.Text.RegularExpressions; #if !KeePassUAP using System.IO; using System.Threading; using System.Windows.Forms; #endif using KeePassLib.Utility; namespace KeePassLib.Native { /// /// Interface to native library (library containing fast versions of /// several cryptographic functions). /// public static class NativeLib { private static bool m_bAllowNative = true; /// /// If this property is set to true, the native library is used. /// If it is false, all calls to functions in this class will fail. /// public static bool AllowNative { get { return m_bAllowNative; } set { m_bAllowNative = value; } } private static int? g_oiPointerSize = null; /// /// Size of a native pointer (in bytes). /// public static int PointerSize { get { if(!g_oiPointerSize.HasValue) #if KeePassUAP g_oiPointerSize = Marshal.SizeOf(); #else g_oiPointerSize = Marshal.SizeOf(typeof(IntPtr)); #endif return g_oiPointerSize.Value; } } private static ulong? m_ouMonoVersion = null; public static ulong MonoVersion { get { if(m_ouMonoVersion.HasValue) return m_ouMonoVersion.Value; ulong uVersion = 0; try { Type t = Type.GetType("Mono.Runtime"); if(t != null) { MethodInfo mi = t.GetMethod("GetDisplayName", BindingFlags.NonPublic | BindingFlags.Static); if(mi != null) { string strName = (mi.Invoke(null, null) as string); if(!string.IsNullOrEmpty(strName)) { Match m = Regex.Match(strName, "\\d+(\\.\\d+)+"); if(m.Success) uVersion = StrUtil.ParseVersion(m.Value); else { Debug.Assert(false); } } else { Debug.Assert(false); } } else { Debug.Assert(false); } } } catch(Exception) { Debug.Assert(false); } m_ouMonoVersion = uVersion; return uVersion; } } /// /// Determine if the native library is installed. /// /// Returns true, if the native library is installed. public static bool IsLibraryInstalled() { byte[] pDummy0 = new byte[32]; byte[] pDummy1 = new byte[32]; // Save the native state bool bCachedNativeState = m_bAllowNative; // Temporarily allow native functions and try to load the library m_bAllowNative = true; bool bResult = TransformKey256(pDummy0, pDummy1, 16); // Pop native state and return result m_bAllowNative = bCachedNativeState; return bResult; } private static bool? m_bIsUnix = null; public static bool IsUnix() { if(m_bIsUnix.HasValue) return m_bIsUnix.Value; PlatformID p = GetPlatformID(); // Mono defines Unix as 128 in early .NET versions #if !KeePassLibSD m_bIsUnix = ((p == PlatformID.Unix) || (p == PlatformID.MacOSX) || ((int)p == 128)); #else m_bIsUnix = (((int)p == 4) || ((int)p == 6) || ((int)p == 128)); #endif return m_bIsUnix.Value; } private static PlatformID? m_platID = null; public static PlatformID GetPlatformID() { if(m_platID.HasValue) return m_platID.Value; #if KeePassUAP m_platID = EnvironmentExt.OSVersion.Platform; #else m_platID = Environment.OSVersion.Platform; #endif #if (!KeePassLibSD && !KeePassUAP) // Mono returns PlatformID.Unix on Mac OS X, workaround this if(m_platID.Value == PlatformID.Unix) { if((RunConsoleApp("uname", null) ?? string.Empty).Trim().Equals( "Darwin", StrUtil.CaseIgnoreCmp)) m_platID = PlatformID.MacOSX; } #endif return m_platID.Value; } private static DesktopType? m_tDesktop = null; public static DesktopType GetDesktopType() { if(!m_tDesktop.HasValue) { DesktopType t = DesktopType.None; if(!IsUnix()) t = DesktopType.Windows; else { try { string strXdg = (Environment.GetEnvironmentVariable( "XDG_CURRENT_DESKTOP") ?? string.Empty).Trim(); string strGdm = (Environment.GetEnvironmentVariable( "GDMSESSION") ?? string.Empty).Trim(); StringComparison sc = StrUtil.CaseIgnoreCmp; if(strXdg.Equals("Unity", sc)) t = DesktopType.Unity; else if(strXdg.Equals("LXDE", sc)) t = DesktopType.Lxde; else if(strXdg.Equals("XFCE", sc)) t = DesktopType.Xfce; else if(strXdg.Equals("MATE", sc)) t = DesktopType.Mate; else if(strXdg.Equals("X-Cinnamon", sc)) t = DesktopType.Cinnamon; else if(strXdg.Equals("Pantheon", sc)) // Elementary OS t = DesktopType.Pantheon; else if(strXdg.Equals("KDE", sc) || // Mint 16 strGdm.Equals("kde-plasma", sc)) // Ubuntu 12.04 t = DesktopType.Kde; else if(strXdg.Equals("GNOME", sc)) { if(strGdm.Equals("cinnamon", sc)) // Mint 13 t = DesktopType.Cinnamon; else t = DesktopType.Gnome; } } catch(Exception) { Debug.Assert(false); } } m_tDesktop = t; } return m_tDesktop.Value; } #if (!KeePassLibSD && !KeePassUAP) public static string RunConsoleApp(string strAppPath, string strParams) { return RunConsoleApp(strAppPath, strParams, null); } public static string RunConsoleApp(string strAppPath, string strParams, string strStdInput) { return RunConsoleApp(strAppPath, strParams, strStdInput, (AppRunFlags.GetStdOutput | AppRunFlags.WaitForExit)); } private delegate string RunProcessDelegate(); public static string RunConsoleApp(string strAppPath, string strParams, string strStdInput, AppRunFlags f) { if(strAppPath == null) throw new ArgumentNullException("strAppPath"); if(strAppPath.Length == 0) throw new ArgumentException("strAppPath"); bool bStdOut = ((f & AppRunFlags.GetStdOutput) != AppRunFlags.None); RunProcessDelegate fnRun = delegate() { try { ProcessStartInfo psi = new ProcessStartInfo(); psi.CreateNoWindow = true; psi.FileName = strAppPath; psi.WindowStyle = ProcessWindowStyle.Hidden; psi.UseShellExecute = false; psi.RedirectStandardOutput = bStdOut; if(strStdInput != null) psi.RedirectStandardInput = true; if(!string.IsNullOrEmpty(strParams)) psi.Arguments = strParams; Process p = Process.Start(psi); if(strStdInput != null) { EnsureNoBom(p.StandardInput); p.StandardInput.Write(strStdInput); p.StandardInput.Close(); } string strOutput = string.Empty; if(bStdOut) strOutput = p.StandardOutput.ReadToEnd(); if((f & AppRunFlags.WaitForExit) != AppRunFlags.None) p.WaitForExit(); else if((f & AppRunFlags.GCKeepAlive) != AppRunFlags.None) { Thread th = new Thread(delegate() { try { p.WaitForExit(); } catch(Exception) { Debug.Assert(false); } }); th.Start(); } return strOutput; } #if DEBUG catch(Exception ex) { Debug.Assert(ex is ThreadAbortException); } #else catch(Exception) { } #endif return null; }; if((f & AppRunFlags.DoEvents) != AppRunFlags.None) { List
lDisabledForms = new List(); if((f & AppRunFlags.DisableForms) != AppRunFlags.None) { foreach(Form form in Application.OpenForms) { if(!form.Enabled) continue; lDisabledForms.Add(form); form.Enabled = false; } } IAsyncResult ar = fnRun.BeginInvoke(null, null); while(!ar.AsyncWaitHandle.WaitOne(0)) { Application.DoEvents(); Thread.Sleep(2); } string strRet = fnRun.EndInvoke(ar); for(int i = lDisabledForms.Count - 1; i >= 0; --i) lDisabledForms[i].Enabled = true; return strRet; } return fnRun(); } private static void EnsureNoBom(StreamWriter sw) { if(sw == null) { Debug.Assert(false); return; } if(!MonoWorkarounds.IsRequired(1219)) return; try { Encoding enc = sw.Encoding; if(enc == null) { Debug.Assert(false); return; } byte[] pbBom = enc.GetPreamble(); if((pbBom == null) || (pbBom.Length == 0)) return; // For Mono >= 4.0 (using Microsoft's reference source) try { FieldInfo fi = typeof(StreamWriter).GetField("haveWrittenPreamble", BindingFlags.Instance | BindingFlags.NonPublic); if(fi != null) { fi.SetValue(sw, true); return; } } catch(Exception) { Debug.Assert(false); } // For Mono < 4.0 FieldInfo fiPD = typeof(StreamWriter).GetField("preamble_done", BindingFlags.Instance | BindingFlags.NonPublic); if(fiPD != null) fiPD.SetValue(sw, true); else { Debug.Assert(false); } } catch(Exception) { Debug.Assert(false); } } #endif /// /// Transform a key. /// /// Source and destination buffer. /// Key to use in the transformation. /// Number of transformation rounds. /// Returns true, if the key was transformed successfully. public static bool TransformKey256(byte[] pBuf256, byte[] pKey256, ulong uRounds) { #if KeePassUAP return false; #else if(!m_bAllowNative) return false; KeyValuePair kvp = PrepareArrays256(pBuf256, pKey256); bool bResult = false; try { bResult = NativeMethods.TransformKey(kvp.Key, kvp.Value, uRounds); } catch(Exception) { bResult = false; } if(bResult) GetBuffers256(kvp, pBuf256, pKey256); FreeArrays(kvp); return bResult; #endif } /// /// Benchmark key transformation. /// /// Number of milliseconds to perform the benchmark. /// Number of transformations done. /// Returns true, if the benchmark was successful. public static bool TransformKeyBenchmark256(uint uTimeMs, out ulong puRounds) { puRounds = 0; #if KeePassUAP return false; #else if(!m_bAllowNative) return false; try { puRounds = NativeMethods.TransformKeyBenchmark(uTimeMs); } catch(Exception) { return false; } return true; #endif } private static KeyValuePair PrepareArrays256(byte[] pBuf256, byte[] pKey256) { Debug.Assert((pBuf256 != null) && (pBuf256.Length == 32)); if(pBuf256 == null) throw new ArgumentNullException("pBuf256"); if(pBuf256.Length != 32) throw new ArgumentException(); Debug.Assert((pKey256 != null) && (pKey256.Length == 32)); if(pKey256 == null) throw new ArgumentNullException("pKey256"); if(pKey256.Length != 32) throw new ArgumentException(); IntPtr hBuf = Marshal.AllocHGlobal(pBuf256.Length); Marshal.Copy(pBuf256, 0, hBuf, pBuf256.Length); IntPtr hKey = Marshal.AllocHGlobal(pKey256.Length); Marshal.Copy(pKey256, 0, hKey, pKey256.Length); return new KeyValuePair(hBuf, hKey); } private static void GetBuffers256(KeyValuePair kvpSource, byte[] pbDestBuf, byte[] pbDestKey) { if(kvpSource.Key != IntPtr.Zero) Marshal.Copy(kvpSource.Key, pbDestBuf, 0, pbDestBuf.Length); if(kvpSource.Value != IntPtr.Zero) Marshal.Copy(kvpSource.Value, pbDestKey, 0, pbDestKey.Length); } private static void FreeArrays(KeyValuePair kvpPointers) { if(kvpPointers.Key != IntPtr.Zero) Marshal.FreeHGlobal(kvpPointers.Key); if(kvpPointers.Value != IntPtr.Zero) Marshal.FreeHGlobal(kvpPointers.Value); } } } KeePassLib/Native/ClipboardU.cs0000664000000000000000000001216713222430400015336 0ustar rootroot/* KeePass Password Safe - The Open-Source Password Manager Copyright (C) 2003-2018 Dominik Reichl This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ using System; using System.Collections.Generic; using System.Diagnostics; using System.Reflection; using System.Text; namespace KeePassLib.Native { internal static class ClipboardU { private const string XSel = "xsel"; private const string XSelV = "--version"; private const string XSelR = "--output --clipboard"; private const string XSelC = "--clear --clipboard"; private const string XSelW = "--input --clipboard"; private const string XSelND = " --nodetach"; private const AppRunFlags XSelWF = AppRunFlags.WaitForExit; private static bool? g_obXSel = null; public static string GetText() { // System.Windows.Forms.Clipboard doesn't work properly, // see Mono workaround 1530 // string str = GtkGetText(); // if(str != null) return str; return XSelGetText(); } public static bool SetText(string strText, bool bMayBlock) { string str = (strText ?? string.Empty); // System.Windows.Forms.Clipboard doesn't work properly, // see Mono workaround 1530 // if(GtkSetText(str)) return true; return XSelSetText(str, bMayBlock); } // ============================================================= // LibGTK // Even though GTK+ 3 appears to be loaded already, performing a // P/Invoke of LibGTK's gtk_init_check function terminates the // process (!) with the following error message: // "Gtk-ERROR **: GTK+ 2.x symbols detected. Using GTK+ 2.x and // GTK+ 3 in the same process is not supported". /* private static bool GtkInit() { try { // GTK requires GLib; // the following throws if and only if GLib is unavailable NativeMethods.g_free(IntPtr.Zero); if(NativeMethods.gtk_init_check(IntPtr.Zero, IntPtr.Zero) != NativeMethods.G_FALSE) return true; Debug.Assert(false); } catch(Exception) { Debug.Assert(false); } return false; } private static string GtkGetText() { IntPtr lpText = IntPtr.Zero; try { if(GtkInit()) { IntPtr h = NativeMethods.gtk_clipboard_get( NativeMethods.GDK_SELECTION_CLIPBOARD); if(h != IntPtr.Zero) { lpText = NativeMethods.gtk_clipboard_wait_for_text(h); if(lpText != IntPtr.Zero) return NativeMethods.Utf8ZToString(lpText); } } } catch(Exception) { Debug.Assert(false); } finally { try { NativeMethods.g_free(lpText); } catch(Exception) { Debug.Assert(false); } } return null; } private static bool GtkSetText(string str) { IntPtr lpText = IntPtr.Zero; try { if(GtkInit()) { lpText = NativeMethods.Utf8ZFromString(str ?? string.Empty); if(lpText == IntPtr.Zero) { Debug.Assert(false); return false; } bool b = false; for(int i = 0; i < 2; ++i) { IntPtr h = NativeMethods.gtk_clipboard_get((i == 0) ? NativeMethods.GDK_SELECTION_PRIMARY : NativeMethods.GDK_SELECTION_CLIPBOARD); if(h != IntPtr.Zero) { NativeMethods.gtk_clipboard_clear(h); NativeMethods.gtk_clipboard_set_text(h, lpText, -1); NativeMethods.gtk_clipboard_store(h); b = true; } } return b; } } catch(Exception) { Debug.Assert(false); } finally { NativeMethods.Utf8ZFree(lpText); } return false; } */ // ============================================================= // XSel private static bool XSelInit() { if(g_obXSel.HasValue) return g_obXSel.Value; string strTest = NativeLib.RunConsoleApp(XSel, XSelV); bool b = (strTest != null); g_obXSel = b; return b; } private static string XSelGetText() { if(!XSelInit()) return null; return NativeLib.RunConsoleApp(XSel, XSelR); } private static bool XSelSetText(string str, bool bMayBlock) { if(!XSelInit()) return false; string strOpt = (bMayBlock ? XSelND : string.Empty); // xsel with an empty input can hang, thus use --clear if(str.Length == 0) return (NativeLib.RunConsoleApp(XSel, XSelC + strOpt, null, XSelWF) != null); // Use --nodetach to prevent clipboard corruption; // https://sourceforge.net/p/keepass/bugs/1603/ return (NativeLib.RunConsoleApp(XSel, XSelW + strOpt, str, XSelWF) != null); } } } KeePassLib/Native/NativeMethods.cs0000664000000000000000000001463513222430400016066 0ustar rootroot/* KeePass Password Safe - The Open-Source Password Manager Copyright (C) 2003-2018 Dominik Reichl This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ using System; using System.Diagnostics; using System.IO; using System.Runtime.InteropServices; using System.Text; using KeePassLib.Utility; namespace KeePassLib.Native { internal static partial class NativeMethods { internal const int MAX_PATH = 260; // internal const uint TF_SFT_SHOWNORMAL = 0x00000001; // internal const uint TF_SFT_HIDDEN = 0x00000008; /* [DllImport("KeePassNtv32.dll", EntryPoint = "TransformKey")] [return: MarshalAs(UnmanagedType.Bool)] private static extern bool TransformKey32(IntPtr pBuf256, IntPtr pKey256, UInt64 uRounds); [DllImport("KeePassNtv64.dll", EntryPoint = "TransformKey")] [return: MarshalAs(UnmanagedType.Bool)] private static extern bool TransformKey64(IntPtr pBuf256, IntPtr pKey256, UInt64 uRounds); internal static bool TransformKey(IntPtr pBuf256, IntPtr pKey256, UInt64 uRounds) { if(Marshal.SizeOf(typeof(IntPtr)) == 8) return TransformKey64(pBuf256, pKey256, uRounds); else return TransformKey32(pBuf256, pKey256, uRounds); } [DllImport("KeePassNtv32.dll", EntryPoint = "TransformKeyTimed")] [return: MarshalAs(UnmanagedType.Bool)] private static extern bool TransformKeyTimed32(IntPtr pBuf256, IntPtr pKey256, ref UInt64 puRounds, UInt32 uSeconds); [DllImport("KeePassNtv64.dll", EntryPoint = "TransformKeyTimed")] [return: MarshalAs(UnmanagedType.Bool)] private static extern bool TransformKeyTimed64(IntPtr pBuf256, IntPtr pKey256, ref UInt64 puRounds, UInt32 uSeconds); internal static bool TransformKeyTimed(IntPtr pBuf256, IntPtr pKey256, ref UInt64 puRounds, UInt32 uSeconds) { if(Marshal.SizeOf(typeof(IntPtr)) == 8) return TransformKeyTimed64(pBuf256, pKey256, ref puRounds, uSeconds); else return TransformKeyTimed32(pBuf256, pKey256, ref puRounds, uSeconds); } */ #if !KeePassUAP [DllImport("KeePassLibC32.dll", EntryPoint = "TransformKey256")] [return: MarshalAs(UnmanagedType.Bool)] private static extern bool TransformKey32(IntPtr pBuf256, IntPtr pKey256, UInt64 uRounds); [DllImport("KeePassLibC64.dll", EntryPoint = "TransformKey256")] [return: MarshalAs(UnmanagedType.Bool)] private static extern bool TransformKey64(IntPtr pBuf256, IntPtr pKey256, UInt64 uRounds); internal static bool TransformKey(IntPtr pBuf256, IntPtr pKey256, UInt64 uRounds) { if(NativeLib.PointerSize == 8) return TransformKey64(pBuf256, pKey256, uRounds); else return TransformKey32(pBuf256, pKey256, uRounds); } [DllImport("KeePassLibC32.dll", EntryPoint = "TransformKeyBenchmark256")] private static extern UInt64 TransformKeyBenchmark32(UInt32 uTimeMs); [DllImport("KeePassLibC64.dll", EntryPoint = "TransformKeyBenchmark256")] private static extern UInt64 TransformKeyBenchmark64(UInt32 uTimeMs); internal static UInt64 TransformKeyBenchmark(UInt32 uTimeMs) { if(NativeLib.PointerSize == 8) return TransformKeyBenchmark64(uTimeMs); return TransformKeyBenchmark32(uTimeMs); } #endif /* [DllImport("KeePassLibC32.dll", EntryPoint = "TF_ShowLangBar")] [return: MarshalAs(UnmanagedType.Bool)] private static extern bool TF_ShowLangBar32(UInt32 dwFlags); [DllImport("KeePassLibC64.dll", EntryPoint = "TF_ShowLangBar")] [return: MarshalAs(UnmanagedType.Bool)] private static extern bool TF_ShowLangBar64(UInt32 dwFlags); internal static bool TfShowLangBar(uint dwFlags) { if(Marshal.SizeOf(typeof(IntPtr)) == 8) return TF_ShowLangBar64(dwFlags); return TF_ShowLangBar32(dwFlags); } */ #if (!KeePassLibSD && !KeePassUAP) [DllImport("ShlWApi.dll", CharSet = CharSet.Auto)] [return: MarshalAs(UnmanagedType.Bool)] internal static extern bool PathRelativePathTo([Out] StringBuilder pszPath, [In] string pszFrom, uint dwAttrFrom, [In] string pszTo, uint dwAttrTo); [DllImport("ShlWApi.dll", CharSet = CharSet.Unicode, ExactSpelling = true)] private static extern int StrCmpLogicalW(string x, string y); private static bool? m_obSupportsLogicalCmp = null; private static void TestNaturalComparisonsSupport() { try { StrCmpLogicalW("0", "0"); // Throws exception if unsupported m_obSupportsLogicalCmp = true; } catch(Exception) { m_obSupportsLogicalCmp = false; } } #endif internal static bool SupportsStrCmpNaturally { get { #if (!KeePassLibSD && !KeePassUAP) if(!m_obSupportsLogicalCmp.HasValue) TestNaturalComparisonsSupport(); return m_obSupportsLogicalCmp.Value; #else return false; #endif } } internal static int StrCmpNaturally(string x, string y) { #if (!KeePassLibSD && !KeePassUAP) if(!NativeMethods.SupportsStrCmpNaturally) { Debug.Assert(false); return string.Compare(x, y, true); } return StrCmpLogicalW(x, y); #else Debug.Assert(false); return string.Compare(x, y, true); #endif } internal static string GetUserRuntimeDir() { #if KeePassLibSD return Path.GetTempPath(); #else #if KeePassUAP string strRtDir = EnvironmentExt.AppDataLocalFolderPath; #else string strRtDir = Environment.GetEnvironmentVariable("XDG_RUNTIME_DIR"); if(string.IsNullOrEmpty(strRtDir)) strRtDir = Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData); if(string.IsNullOrEmpty(strRtDir)) { Debug.Assert(false); return Path.GetTempPath(); // Not UrlUtil (otherwise cyclic) } #endif strRtDir = UrlUtil.EnsureTerminatingSeparator(strRtDir, false); strRtDir += PwDefs.ShortProductName; return strRtDir; #endif } } } KeePassLib/Cryptography/0000775000000000000000000000000013222430400014221 5ustar rootrootKeePassLib/Cryptography/QualityEstimation.cs0000664000000000000000000005247613222430400020253 0ustar rootroot/* KeePass Password Safe - The Open-Source Password Manager Copyright (C) 2003-2018 Dominik Reichl This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ using System; using System.Collections.Generic; using System.Diagnostics; using System.Text; using KeePassLib.Cryptography.PasswordGenerator; using KeePassLib.Utility; namespace KeePassLib.Cryptography { /// /// A class that offers static functions to estimate the quality of /// passwords. /// public static class QualityEstimation { private static class PatternID { public const char LowerAlpha = 'L'; public const char UpperAlpha = 'U'; public const char Digit = 'D'; public const char Special = 'S'; public const char High = 'H'; public const char Other = 'X'; public const char Dictionary = 'W'; public const char Repetition = 'R'; public const char Number = 'N'; public const char DiffSeq = 'C'; public const string All = "LUDSHXWRNC"; } // private static class CharDistrib // { // public static readonly ulong[] LowerAlpha = new ulong[26] { // 884, 211, 262, 249, 722, 98, 172, 234, 556, 124, 201, 447, 321, // 483, 518, 167, 18, 458, 416, 344, 231, 105, 80, 48, 238, 76 // }; // public static readonly ulong[] UpperAlpha = new ulong[26] { // 605, 188, 209, 200, 460, 81, 130, 163, 357, 122, 144, 332, 260, // 317, 330, 132, 18, 320, 315, 250, 137, 76, 60, 36, 161, 54 // }; // public static readonly ulong[] Digit = new ulong[10] { // 574, 673, 524, 377, 339, 336, 312, 310, 357, 386 // }; // } private sealed class QeCharType { private readonly char m_chTypeID; public char TypeID { get { return m_chTypeID; } } private readonly string m_strAlph; public string Alphabet { get { return m_strAlph; } } private readonly int m_nChars; public int CharCount { get { return m_nChars; } } private readonly char m_chFirst; private readonly char m_chLast; private readonly double m_dblCharSize; public double CharSize { get { return m_dblCharSize; } } public QeCharType(char chTypeID, string strAlphabet, bool bIsConsecutive) { if(strAlphabet == null) throw new ArgumentNullException(); if(strAlphabet.Length == 0) throw new ArgumentException(); m_chTypeID = chTypeID; m_strAlph = strAlphabet; m_nChars = m_strAlph.Length; m_chFirst = (bIsConsecutive ? m_strAlph[0] : char.MinValue); m_chLast = (bIsConsecutive ? m_strAlph[m_nChars - 1] : char.MinValue); m_dblCharSize = Log2(m_nChars); Debug.Assert(((int)(m_chLast - m_chFirst) == (m_nChars - 1)) || !bIsConsecutive); } public QeCharType(char chTypeID, int nChars) // Catch-none set { if(nChars <= 0) throw new ArgumentOutOfRangeException(); m_chTypeID = chTypeID; m_strAlph = string.Empty; m_nChars = nChars; m_chFirst = char.MinValue; m_chLast = char.MinValue; m_dblCharSize = Log2(m_nChars); } public bool Contains(char ch) { if(m_chLast != char.MinValue) return ((ch >= m_chFirst) && (ch <= m_chLast)); Debug.Assert(m_strAlph.Length > 0); // Don't call for catch-none set return (m_strAlph.IndexOf(ch) >= 0); } } private sealed class EntropyEncoder { private readonly string m_strAlph; private Dictionary m_dHisto = new Dictionary(); private readonly ulong m_uBaseWeight; private readonly ulong m_uCharWeight; private readonly ulong m_uOccExclThreshold; public EntropyEncoder(string strAlphabet, ulong uBaseWeight, ulong uCharWeight, ulong uOccExclThreshold) { if(strAlphabet == null) throw new ArgumentNullException(); if(strAlphabet.Length == 0) throw new ArgumentException(); m_strAlph = strAlphabet; m_uBaseWeight = uBaseWeight; m_uCharWeight = uCharWeight; m_uOccExclThreshold = uOccExclThreshold; #if DEBUG Dictionary d = new Dictionary(); foreach(char ch in m_strAlph) { d[ch] = true; } Debug.Assert(d.Count == m_strAlph.Length); // No duplicates #endif } public void Reset() { m_dHisto.Clear(); } public void Write(char ch) { Debug.Assert(m_strAlph.IndexOf(ch) >= 0); ulong uOcc; m_dHisto.TryGetValue(ch, out uOcc); Debug.Assert(m_dHisto.ContainsKey(ch) || (uOcc == 0)); m_dHisto[ch] = uOcc + 1; } public double GetOutputSize() { ulong uTotalWeight = m_uBaseWeight * (ulong)m_strAlph.Length; foreach(ulong u in m_dHisto.Values) { Debug.Assert(u >= 1); if(u > m_uOccExclThreshold) uTotalWeight += (u - m_uOccExclThreshold) * m_uCharWeight; } double dSize = 0.0, dTotalWeight = (double)uTotalWeight; foreach(ulong u in m_dHisto.Values) { ulong uWeight = m_uBaseWeight; if(u > m_uOccExclThreshold) uWeight += (u - m_uOccExclThreshold) * m_uCharWeight; dSize -= (double)u * Log2((double)uWeight / dTotalWeight); } return dSize; } } private sealed class MultiEntropyEncoder { private Dictionary m_dEncs = new Dictionary(); public MultiEntropyEncoder() { } public void AddEncoder(char chTypeID, EntropyEncoder ec) { if(ec == null) { Debug.Assert(false); return; } Debug.Assert(!m_dEncs.ContainsKey(chTypeID)); m_dEncs[chTypeID] = ec; } public void Reset() { foreach(EntropyEncoder ec in m_dEncs.Values) { ec.Reset(); } } public bool Write(char chTypeID, char chData) { EntropyEncoder ec; if(!m_dEncs.TryGetValue(chTypeID, out ec)) return false; ec.Write(chData); return true; } public double GetOutputSize() { double d = 0.0; foreach(EntropyEncoder ec in m_dEncs.Values) { d += ec.GetOutputSize(); } return d; } } private sealed class QePatternInstance { private readonly int m_iPos; public int Position { get { return m_iPos; } } private readonly int m_nLen; public int Length { get { return m_nLen; } } private readonly char m_chPatternID; public char PatternID { get { return m_chPatternID; } } private readonly double m_dblCost; public double Cost { get { return m_dblCost; } } private readonly QeCharType m_ctSingle; public QeCharType SingleCharType { get { return m_ctSingle; } } public QePatternInstance(int iPosition, int nLength, char chPatternID, double dblCost) { m_iPos = iPosition; m_nLen = nLength; m_chPatternID = chPatternID; m_dblCost = dblCost; m_ctSingle = null; } public QePatternInstance(int iPosition, int nLength, QeCharType ctSingle) { m_iPos = iPosition; m_nLen = nLength; m_chPatternID = ctSingle.TypeID; m_dblCost = ctSingle.CharSize; m_ctSingle = ctSingle; } } private sealed class QePathState { public readonly int Position; public readonly List Path; public QePathState(int iPosition, List lPath) { this.Position = iPosition; this.Path = lPath; } } private static readonly object m_objSyncInit = new object(); private static List m_lCharTypes = null; private static void EnsureInitialized() { lock(m_objSyncInit) { if(m_lCharTypes == null) { string strSpecial = PwCharSet.PrintableAsciiSpecial; if(strSpecial.IndexOf(' ') >= 0) { Debug.Assert(false); } else strSpecial = strSpecial + " "; int nSp = strSpecial.Length; int nHi = PwCharSet.HighAnsiChars.Length; m_lCharTypes = new List(); m_lCharTypes.Add(new QeCharType(PatternID.LowerAlpha, PwCharSet.LowerCase, true)); m_lCharTypes.Add(new QeCharType(PatternID.UpperAlpha, PwCharSet.UpperCase, true)); m_lCharTypes.Add(new QeCharType(PatternID.Digit, PwCharSet.Digits, true)); m_lCharTypes.Add(new QeCharType(PatternID.Special, strSpecial, false)); m_lCharTypes.Add(new QeCharType(PatternID.High, PwCharSet.HighAnsiChars, false)); m_lCharTypes.Add(new QeCharType(PatternID.Other, 0x10000 - (2 * 26) - 10 - nSp - nHi)); } } } /// /// Estimate the quality of a password. /// /// Password to check. /// Estimated bit-strength of the password. public static uint EstimatePasswordBits(char[] vPassword) { if(vPassword == null) { Debug.Assert(false); return 0; } if(vPassword.Length == 0) return 0; EnsureInitialized(); int n = vPassword.Length; List[] vPatterns = new List[n]; for(int i = 0; i < n; ++i) { vPatterns[i] = new List(); QePatternInstance piChar = new QePatternInstance(i, 1, GetCharType(vPassword[i])); vPatterns[i].Add(piChar); } FindRepetitions(vPassword, vPatterns); FindNumbers(vPassword, vPatterns); FindDiffSeqs(vPassword, vPatterns); FindPopularPasswords(vPassword, vPatterns); // Encoders must not be static, because the entropy estimation // may run concurrently in multiple threads and the encoders are // not read-only EntropyEncoder ecPattern = new EntropyEncoder(PatternID.All, 0, 1, 0); MultiEntropyEncoder mcData = new MultiEntropyEncoder(); for(int i = 0; i < (m_lCharTypes.Count - 1); ++i) { // Let m be the alphabet size. In order to ensure that two same // characters cost at least as much as a single character, for // the probability p and weight w of the character it must hold: // -log(1/m) >= -2*log(p) // <=> log(1/m) <= log(p^2) <=> 1/m <= p^2 <=> p >= sqrt(1/m); // sqrt(1/m) = (1+w)/(m+w) // <=> m+w = (1+w)*sqrt(m) <=> m+w = sqrt(m) + w*sqrt(m) // <=> w*(1-sqrt(m)) = sqrt(m) - m <=> w = (sqrt(m)-m)/(1-sqrt(m)) // <=> w = (sqrt(m)-m)*(1+sqrt(m))/(1-m) // <=> w = (sqrt(m)-m+m-m*sqrt(m))/(1-m) <=> w = sqrt(m) ulong uw = (ulong)Math.Sqrt((double)m_lCharTypes[i].CharCount); mcData.AddEncoder(m_lCharTypes[i].TypeID, new EntropyEncoder( m_lCharTypes[i].Alphabet, 1, uw, 1)); } double dblMinCost = (double)int.MaxValue; int tStart = Environment.TickCount; Stack sRec = new Stack(); sRec.Push(new QePathState(0, new List())); while(sRec.Count > 0) { int tDiff = Environment.TickCount - tStart; if(tDiff > 500) break; QePathState s = sRec.Pop(); if(s.Position >= n) { Debug.Assert(s.Position == n); double dblCost = ComputePathCost(s.Path, vPassword, ecPattern, mcData); if(dblCost < dblMinCost) dblMinCost = dblCost; } else { List lSubs = vPatterns[s.Position]; for(int i = lSubs.Count - 1; i >= 0; --i) { QePatternInstance pi = lSubs[i]; Debug.Assert(pi.Position == s.Position); Debug.Assert(pi.Length >= 1); List lNewPath = new List(s.Path.Count + 1); lNewPath.AddRange(s.Path); lNewPath.Add(pi); Debug.Assert(lNewPath.Capacity == (s.Path.Count + 1)); QePathState sNew = new QePathState(s.Position + pi.Length, lNewPath); sRec.Push(sNew); } } } return (uint)Math.Ceiling(dblMinCost); } /// /// Estimate the quality of a password. /// /// Password to check, UTF-8 encoded. /// Estimated bit-strength of the password. public static uint EstimatePasswordBits(byte[] pbUnprotectedUtf8) { if(pbUnprotectedUtf8 == null) { Debug.Assert(false); return 0; } char[] vChars = StrUtil.Utf8.GetChars(pbUnprotectedUtf8); uint uResult = EstimatePasswordBits(vChars); MemUtil.ZeroArray(vChars); return uResult; } private static QeCharType GetCharType(char ch) { int nTypes = m_lCharTypes.Count; Debug.Assert((nTypes > 0) && (m_lCharTypes[nTypes - 1].CharCount > 256)); for(int i = 0; i < (nTypes - 1); ++i) { if(m_lCharTypes[i].Contains(ch)) return m_lCharTypes[i]; } return m_lCharTypes[nTypes - 1]; } private static double ComputePathCost(List l, char[] vPassword, EntropyEncoder ecPattern, MultiEntropyEncoder mcData) { ecPattern.Reset(); for(int i = 0; i < l.Count; ++i) ecPattern.Write(l[i].PatternID); double dblPatternCost = ecPattern.GetOutputSize(); mcData.Reset(); double dblDataCost = 0.0; foreach(QePatternInstance pi in l) { QeCharType tChar = pi.SingleCharType; if(tChar != null) { char ch = vPassword[pi.Position]; if(!mcData.Write(tChar.TypeID, ch)) dblDataCost += pi.Cost; } else dblDataCost += pi.Cost; } dblDataCost += mcData.GetOutputSize(); return (dblPatternCost + dblDataCost); } private static void FindPopularPasswords(char[] vPassword, List[] vPatterns) { int n = vPassword.Length; char[] vLower = new char[n]; char[] vLeet = new char[n]; for(int i = 0; i < n; ++i) { char ch = vPassword[i]; vLower[i] = char.ToLower(ch); vLeet[i] = char.ToLower(DecodeLeetChar(ch)); } char chErased = default(char); // The value that Array.Clear uses Debug.Assert(chErased == char.MinValue); int nMaxLen = Math.Min(n, PopularPasswords.MaxLength); for(int nSubLen = nMaxLen; nSubLen >= 3; --nSubLen) { if(!PopularPasswords.ContainsLength(nSubLen)) continue; char[] vSub = new char[nSubLen]; for(int i = 0; i <= (n - nSubLen); ++i) { if(Array.IndexOf(vLower, chErased, i, nSubLen) >= 0) continue; Array.Copy(vLower, i, vSub, 0, nSubLen); if(!EvalAddPopularPasswordPattern(vPatterns, vPassword, i, vSub, 0.0)) { Array.Copy(vLeet, i, vSub, 0, nSubLen); if(EvalAddPopularPasswordPattern(vPatterns, vPassword, i, vSub, 1.5)) { Array.Clear(vLower, i, nSubLen); // Not vLeet Debug.Assert(vLower[i] == chErased); } } else { Array.Clear(vLower, i, nSubLen); Debug.Assert(vLower[i] == chErased); } } MemUtil.ZeroArray(vSub); } MemUtil.ZeroArray(vLower); MemUtil.ZeroArray(vLeet); } private static bool EvalAddPopularPasswordPattern(List[] vPatterns, char[] vPassword, int i, char[] vSub, double dblCostPerMod) { ulong uDictSize; if(!PopularPasswords.IsPopularPassword(vSub, out uDictSize)) return false; int n = vSub.Length; int d = HammingDist(vSub, 0, vPassword, i, n); double dblCost = Log2((double)uDictSize); // dblCost += log2(n binom d) int k = Math.Min(d, n - d); for(int j = n; j > (n - k); --j) dblCost += Log2(j); for(int j = k; j >= 2; --j) dblCost -= Log2(j); dblCost += dblCostPerMod * (double)d; vPatterns[i].Add(new QePatternInstance(i, n, PatternID.Dictionary, dblCost)); return true; } private static char DecodeLeetChar(char chLeet) { if((chLeet >= '\u00C0') && (chLeet <= '\u00C6')) return 'a'; if((chLeet >= '\u00C8') && (chLeet <= '\u00CB')) return 'e'; if((chLeet >= '\u00CC') && (chLeet <= '\u00CF')) return 'i'; if((chLeet >= '\u00D2') && (chLeet <= '\u00D6')) return 'o'; if((chLeet >= '\u00D9') && (chLeet <= '\u00DC')) return 'u'; if((chLeet >= '\u00E0') && (chLeet <= '\u00E6')) return 'a'; if((chLeet >= '\u00E8') && (chLeet <= '\u00EB')) return 'e'; if((chLeet >= '\u00EC') && (chLeet <= '\u00EF')) return 'i'; if((chLeet >= '\u00F2') && (chLeet <= '\u00F6')) return 'o'; if((chLeet >= '\u00F9') && (chLeet <= '\u00FC')) return 'u'; char ch; switch(chLeet) { case '4': case '@': case '?': case '^': case '\u00AA': ch = 'a'; break; case '8': case '\u00DF': ch = 'b'; break; case '(': case '{': case '[': case '<': case '\u00A2': case '\u00A9': case '\u00C7': case '\u00E7': ch = 'c'; break; case '\u00D0': case '\u00F0': ch = 'd'; break; case '3': case '\u20AC': case '&': case '\u00A3': ch = 'e'; break; case '6': case '9': ch = 'g'; break; case '#': ch = 'h'; break; case '1': case '!': case '|': case '\u00A1': case '\u00A6': ch = 'i'; break; case '\u00D1': case '\u00F1': ch = 'n'; break; case '0': case '*': case '\u00A4': // Currency case '\u00B0': // Degree case '\u00D8': case '\u00F8': ch = 'o'; break; case '\u00AE': ch = 'r'; break; case '$': case '5': case '\u00A7': ch = 's'; break; case '+': case '7': ch = 't'; break; case '\u00B5': ch = 'u'; break; case '%': case '\u00D7': ch = 'x'; break; case '\u00A5': case '\u00DD': case '\u00FD': case '\u00FF': ch = 'y'; break; case '2': ch = 'z'; break; default: ch = chLeet; break; } return ch; } private static int HammingDist(char[] v1, int iOffset1, char[] v2, int iOffset2, int nLength) { int nDist = 0; for(int i = 0; i < nLength; ++i) { if(v1[iOffset1 + i] != v2[iOffset2 + i]) ++nDist; } return nDist; } private static void FindRepetitions(char[] vPassword, List[] vPatterns) { int n = vPassword.Length; char[] v = new char[n]; Array.Copy(vPassword, v, n); char chErased = char.MaxValue; for(int m = (n / 2); m >= 3; --m) { for(int x1 = 0; x1 <= (n - (2 * m)); ++x1) { bool bFoundRep = false; for(int x2 = (x1 + m); x2 <= (n - m); ++x2) { if(PartsEqual(v, x1, x2, m)) { double dblCost = Log2(x1 + 1) + Log2(m); vPatterns[x2].Add(new QePatternInstance(x2, m, PatternID.Repetition, dblCost)); ErasePart(v, x2, m, ref chErased); bFoundRep = true; } } if(bFoundRep) ErasePart(v, x1, m, ref chErased); } } MemUtil.ZeroArray(v); } private static bool PartsEqual(char[] v, int x1, int x2, int nLength) { for(int i = 0; i < nLength; ++i) { if(v[x1 + i] != v[x2 + i]) return false; } return true; } private static void ErasePart(char[] v, int i, int n, ref char chErased) { for(int j = 0; j < n; ++j) { v[i + j] = chErased; --chErased; } } private static void FindNumbers(char[] vPassword, List[] vPatterns) { int n = vPassword.Length; StringBuilder sb = new StringBuilder(); for(int i = 0; i < n; ++i) { char ch = vPassword[i]; if((ch >= '0') && (ch <= '9')) sb.Append(ch); else { AddNumberPattern(vPatterns, sb, i - sb.Length); sb.Remove(0, sb.Length); } } AddNumberPattern(vPatterns, sb, n - sb.Length); } private static void AddNumberPattern(List[] vPatterns, StringBuilder sb, int i) { if(sb.Length <= 2) return; string strNumber = sb.ToString(); int nZeros = 0; for(int j = 0; j < strNumber.Length; ++j) { if(strNumber[j] != '0') break; ++nZeros; } double dblCost = Log2(nZeros + 1); if(nZeros < strNumber.Length) { string strNonZero = strNumber.Substring(nZeros); #if KeePassLibSD try { dblCost += Log2(double.Parse(strNonZero)); } catch(Exception) { Debug.Assert(false); return; } #else double d; if(double.TryParse(strNonZero, out d)) dblCost += Log2(d); else { Debug.Assert(false); return; } #endif } vPatterns[i].Add(new QePatternInstance(i, strNumber.Length, PatternID.Number, dblCost)); } private static void FindDiffSeqs(char[] vPassword, List[] vPatterns) { int n = vPassword.Length; int d = int.MaxValue, p = 0; for(int i = 1; i <= n; ++i) { int dCur = ((i == n) ? int.MinValue : ((int)vPassword[i] - (int)vPassword[i - 1])); if(dCur != d) { if((i - p) >= 3) // At least 3 chars involved { QeCharType ct = GetCharType(vPassword[p]); double dblCost = ct.CharSize + Log2(i - p - 1); vPatterns[p].Add(new QePatternInstance(p, i - p, PatternID.DiffSeq, dblCost)); } d = dCur; p = i - 1; } } } private static double Log2(double dblValue) { #if KeePassLibSD return (Math.Log(dblValue) / Math.Log(2.0)); #else return Math.Log(dblValue, 2.0); #endif } } } KeePassLib/Cryptography/PopularPasswords.cs0000664000000000000000000000702213222430400020101 0ustar rootroot/* KeePass Password Safe - The Open-Source Password Manager Copyright (C) 2003-2018 Dominik Reichl This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ using System; using System.Collections.Generic; using System.Diagnostics; using System.Text; using KeePassLib.Utility; namespace KeePassLib.Cryptography { public static class PopularPasswords { private static Dictionary> m_dicts = new Dictionary>(); internal static int MaxLength { get { Debug.Assert(m_dicts.Count > 0); // Should be initialized int iMaxLen = 0; foreach(int iLen in m_dicts.Keys) { if(iLen > iMaxLen) iMaxLen = iLen; } return iMaxLen; } } internal static bool ContainsLength(int nLength) { Dictionary dDummy; return m_dicts.TryGetValue(nLength, out dDummy); } public static bool IsPopularPassword(char[] vPassword) { ulong uDummy; return IsPopularPassword(vPassword, out uDummy); } public static bool IsPopularPassword(char[] vPassword, out ulong uDictSize) { if(vPassword == null) throw new ArgumentNullException("vPassword"); if(vPassword.Length == 0) { uDictSize = 0; return false; } #if DEBUG Array.ForEach(vPassword, ch => Debug.Assert(ch == char.ToLower(ch))); #endif try { return IsPopularPasswordPriv(vPassword, out uDictSize); } catch(Exception) { Debug.Assert(false); } uDictSize = 0; return false; } private static bool IsPopularPasswordPriv(char[] vPassword, out ulong uDictSize) { Debug.Assert(m_dicts.Count > 0); // Should be initialized with data Dictionary d; if(!m_dicts.TryGetValue(vPassword.Length, out d)) { uDictSize = 0; return false; } uDictSize = (ulong)d.Count; return d.ContainsKey(vPassword); } public static void Add(byte[] pbData, bool bGZipped) { try { if(bGZipped) pbData = MemUtil.Decompress(pbData); string strData = StrUtil.Utf8.GetString(pbData, 0, pbData.Length); if(string.IsNullOrEmpty(strData)) { Debug.Assert(false); return; } StringBuilder sb = new StringBuilder(); for(int i = 0; i <= strData.Length; ++i) { char ch = ((i == strData.Length) ? ' ' : strData[i]); if(char.IsWhiteSpace(ch)) { int cc = sb.Length; if(cc > 0) { char[] vWord = new char[cc]; sb.CopyTo(0, vWord, 0, cc); Dictionary d; if(!m_dicts.TryGetValue(cc, out d)) { d = new Dictionary(MemUtil.ArrayHelperExOfChar); m_dicts[cc] = d; } d[vWord] = true; sb.Remove(0, cc); } } else sb.Append(char.ToLower(ch)); } } catch(Exception) { Debug.Assert(false); } } } } KeePassLib/Cryptography/CryptoUtil.cs0000664000000000000000000001110113222430400016660 0ustar rootroot/* KeePass Password Safe - The Open-Source Password Manager Copyright (C) 2003-2018 Dominik Reichl This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ using System; using System.Collections.Generic; using System.Diagnostics; using System.Reflection; using System.Text; #if !KeePassUAP using System.Security.Cryptography; #endif using KeePassLib.Native; using KeePassLib.Utility; namespace KeePassLib.Cryptography { public static class CryptoUtil { public static byte[] HashSha256(byte[] pbData) { if(pbData == null) throw new ArgumentNullException("pbData"); return HashSha256(pbData, 0, pbData.Length); } public static byte[] HashSha256(byte[] pbData, int iOffset, int cbCount) { if(pbData == null) throw new ArgumentNullException("pbData"); #if DEBUG byte[] pbCopy = new byte[pbData.Length]; Array.Copy(pbData, pbCopy, pbData.Length); #endif byte[] pbHash; using(SHA256Managed h = new SHA256Managed()) { pbHash = h.ComputeHash(pbData, iOffset, cbCount); } #if DEBUG // Ensure the data has not been modified Debug.Assert(MemUtil.ArraysEqual(pbData, pbCopy)); Debug.Assert((pbHash != null) && (pbHash.Length == 32)); byte[] pbZero = new byte[32]; Debug.Assert(!MemUtil.ArraysEqual(pbHash, pbZero)); #endif return pbHash; } /// /// Create a cryptographic key of length /// (in bytes) from . /// public static byte[] ResizeKey(byte[] pbIn, int iInOffset, int cbIn, int cbOut) { if(pbIn == null) throw new ArgumentNullException("pbIn"); if(cbOut < 0) throw new ArgumentOutOfRangeException("cbOut"); if(cbOut == 0) return MemUtil.EmptyByteArray; byte[] pbHash; if(cbOut <= 32) pbHash = HashSha256(pbIn, iInOffset, cbIn); else { using(SHA512Managed h = new SHA512Managed()) { pbHash = h.ComputeHash(pbIn, iInOffset, cbIn); } } if(cbOut == pbHash.Length) return pbHash; byte[] pbRet = new byte[cbOut]; if(cbOut < pbHash.Length) Array.Copy(pbHash, pbRet, cbOut); else { int iPos = 0; ulong r = 0; while(iPos < cbOut) { Debug.Assert(pbHash.Length == 64); using(HMACSHA256 h = new HMACSHA256(pbHash)) { byte[] pbR = MemUtil.UInt64ToBytes(r); byte[] pbPart = h.ComputeHash(pbR); int cbCopy = Math.Min(cbOut - iPos, pbPart.Length); Debug.Assert(cbCopy > 0); Array.Copy(pbPart, 0, pbRet, iPos, cbCopy); iPos += cbCopy; ++r; MemUtil.ZeroByteArray(pbPart); } } Debug.Assert(iPos == cbOut); } #if DEBUG byte[] pbZero = new byte[pbHash.Length]; Debug.Assert(!MemUtil.ArraysEqual(pbHash, pbZero)); #endif MemUtil.ZeroByteArray(pbHash); return pbRet; } private static bool? g_obAesCsp = null; internal static SymmetricAlgorithm CreateAes() { if(g_obAesCsp.HasValue) return (g_obAesCsp.Value ? CreateAesCsp() : new RijndaelManaged()); SymmetricAlgorithm a = CreateAesCsp(); g_obAesCsp = (a != null); return (a ?? new RijndaelManaged()); } private static SymmetricAlgorithm CreateAesCsp() { try { // On Windows, the CSP implementation is only minimally // faster (and for key derivations it's not used anyway, // as KeePass uses a native implementation based on // CNG/BCrypt, which is much faster) if(!NativeLib.IsUnix()) return null; string strFqn = Assembly.CreateQualifiedName( "System.Core, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089", "System.Security.Cryptography.AesCryptoServiceProvider"); Type t = Type.GetType(strFqn); if(t == null) return null; return (Activator.CreateInstance(t) as SymmetricAlgorithm); } catch(Exception) { Debug.Assert(false); } return null; } } } KeePassLib/Cryptography/HashingStreamEx.cs0000664000000000000000000001066013222430400017605 0ustar rootroot/* KeePass Password Safe - The Open-Source Password Manager Copyright (C) 2003-2018 Dominik Reichl This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ using System; using System.Collections.Generic; using System.Diagnostics; using System.IO; using System.Text; #if !KeePassUAP using System.Security.Cryptography; #endif using KeePassLib.Utility; namespace KeePassLib.Cryptography { public sealed class HashingStreamEx : Stream { private readonly Stream m_sBaseStream; private readonly bool m_bWriting; private HashAlgorithm m_hash; private byte[] m_pbFinalHash = null; public byte[] Hash { get { return m_pbFinalHash; } } public override bool CanRead { get { return !m_bWriting; } } public override bool CanSeek { get { return false; } } public override bool CanWrite { get { return m_bWriting; } } public override long Length { get { return m_sBaseStream.Length; } } public override long Position { get { return m_sBaseStream.Position; } set { Debug.Assert(false); throw new NotSupportedException(); } } public HashingStreamEx(Stream sBaseStream, bool bWriting, HashAlgorithm hashAlgorithm) { if(sBaseStream == null) throw new ArgumentNullException("sBaseStream"); m_sBaseStream = sBaseStream; m_bWriting = bWriting; #if !KeePassLibSD m_hash = (hashAlgorithm ?? new SHA256Managed()); #else // KeePassLibSD m_hash = null; try { m_hash = HashAlgorithm.Create("SHA256"); } catch(Exception) { } try { if(m_hash == null) m_hash = HashAlgorithm.Create(); } catch(Exception) { } #endif if(m_hash == null) { Debug.Assert(false); return; } // Validate hash algorithm if(!m_hash.CanReuseTransform || !m_hash.CanTransformMultipleBlocks) { Debug.Assert(false); m_hash = null; } } protected override void Dispose(bool disposing) { if(disposing) { if(m_hash != null) { try { m_hash.TransformFinalBlock(MemUtil.EmptyByteArray, 0, 0); m_pbFinalHash = m_hash.Hash; } catch(Exception) { Debug.Assert(false); } m_hash = null; } m_sBaseStream.Close(); } base.Dispose(disposing); } public override void Flush() { m_sBaseStream.Flush(); } public override long Seek(long lOffset, SeekOrigin soOrigin) { throw new NotSupportedException(); } public override void SetLength(long lValue) { throw new NotSupportedException(); } public override int Read(byte[] pbBuffer, int nOffset, int nCount) { if(m_bWriting) throw new InvalidOperationException(); int nRead = m_sBaseStream.Read(pbBuffer, nOffset, nCount); int nPartialRead = nRead; while((nRead < nCount) && (nPartialRead != 0)) { nPartialRead = m_sBaseStream.Read(pbBuffer, nOffset + nRead, nCount - nRead); nRead += nPartialRead; } #if DEBUG byte[] pbOrg = new byte[pbBuffer.Length]; Array.Copy(pbBuffer, pbOrg, pbBuffer.Length); #endif if((m_hash != null) && (nRead > 0)) m_hash.TransformBlock(pbBuffer, nOffset, nRead, pbBuffer, nOffset); #if DEBUG Debug.Assert(MemUtil.ArraysEqual(pbBuffer, pbOrg)); #endif return nRead; } public override void Write(byte[] pbBuffer, int nOffset, int nCount) { if(!m_bWriting) throw new InvalidOperationException(); #if DEBUG byte[] pbOrg = new byte[pbBuffer.Length]; Array.Copy(pbBuffer, pbOrg, pbBuffer.Length); #endif if((m_hash != null) && (nCount > 0)) m_hash.TransformBlock(pbBuffer, nOffset, nCount, pbBuffer, nOffset); #if DEBUG Debug.Assert(MemUtil.ArraysEqual(pbBuffer, pbOrg)); #endif m_sBaseStream.Write(pbBuffer, nOffset, nCount); } } } KeePassLib/Cryptography/HmacOtp.cs0000664000000000000000000000556313222430400016114 0ustar rootroot/* KeePass Password Safe - The Open-Source Password Manager Copyright (C) 2003-2018 Dominik Reichl This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ using System; using System.Collections.Generic; using System.Globalization; using System.Text; #if !KeePassUAP using System.Security.Cryptography; #endif using KeePassLib.Utility; #if !KeePassLibSD namespace KeePassLib.Cryptography { /// /// Generate HMAC-based one-time passwords as specified in RFC 4226. /// public static class HmacOtp { private static readonly uint[] vDigitsPower = new uint[]{ 1, 10, 100, 1000, 10000, 100000, 1000000, 10000000, 100000000 }; public static string Generate(byte[] pbSecret, ulong uFactor, uint uCodeDigits, bool bAddChecksum, int iTruncationOffset) { byte[] pbText = MemUtil.UInt64ToBytes(uFactor); Array.Reverse(pbText); // To big-endian HMACSHA1 hsha1 = new HMACSHA1(pbSecret); byte[] pbHash = hsha1.ComputeHash(pbText); uint uOffset = (uint)(pbHash[pbHash.Length - 1] & 0xF); if((iTruncationOffset >= 0) && (iTruncationOffset < (pbHash.Length - 4))) uOffset = (uint)iTruncationOffset; uint uBinary = (uint)(((pbHash[uOffset] & 0x7F) << 24) | ((pbHash[uOffset + 1] & 0xFF) << 16) | ((pbHash[uOffset + 2] & 0xFF) << 8) | (pbHash[uOffset + 3] & 0xFF)); uint uOtp = (uBinary % vDigitsPower[uCodeDigits]); if(bAddChecksum) uOtp = ((uOtp * 10) + CalculateChecksum(uOtp, uCodeDigits)); uint uDigits = (bAddChecksum ? (uCodeDigits + 1) : uCodeDigits); return uOtp.ToString(NumberFormatInfo.InvariantInfo).PadLeft( (int)uDigits, '0'); } private static readonly uint[] vDoubleDigits = new uint[]{ 0, 2, 4, 6, 8, 1, 3, 5, 7, 9 }; private static uint CalculateChecksum(uint uNum, uint uDigits) { bool bDoubleDigit = true; uint uTotal = 0; while(0 < uDigits--) { uint uDigit = (uNum % 10); uNum /= 10; if(bDoubleDigit) uDigit = vDoubleDigits[uDigit]; uTotal += uDigit; bDoubleDigit = !bDoubleDigit; } uint uResult = (uTotal % 10); if(uResult != 0) uResult = 10 - uResult; return uResult; } } } #endif KeePassLib/Cryptography/KeyDerivation/0000775000000000000000000000000013222430400016776 5ustar rootrootKeePassLib/Cryptography/KeyDerivation/AesKdf.cs0000664000000000000000000001743113222430400020470 0ustar rootroot/* KeePass Password Safe - The Open-Source Password Manager Copyright (C) 2003-2018 Dominik Reichl This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ using System; using System.Collections.Generic; using System.Diagnostics; using System.Text; #if KeePassUAP using Org.BouncyCastle.Crypto; using Org.BouncyCastle.Crypto.Engines; using Org.BouncyCastle.Crypto.Parameters; #else using System.Security.Cryptography; #endif using KeePassLib.Cryptography; using KeePassLib.Native; using KeePassLib.Utility; namespace KeePassLib.Cryptography.KeyDerivation { public sealed partial class AesKdf : KdfEngine { private static readonly PwUuid g_uuid = new PwUuid(new byte[] { 0xC9, 0xD9, 0xF3, 0x9A, 0x62, 0x8A, 0x44, 0x60, 0xBF, 0x74, 0x0D, 0x08, 0xC1, 0x8A, 0x4F, 0xEA }); public const string ParamRounds = "R"; // UInt64 public const string ParamSeed = "S"; // Byte[32] private const ulong BenchStep = 3001; public override PwUuid Uuid { get { return g_uuid; } } public override string Name { get { return "AES-KDF"; } } public AesKdf() { } public override KdfParameters GetDefaultParameters() { KdfParameters p = base.GetDefaultParameters(); p.SetUInt64(ParamRounds, PwDefs.DefaultKeyEncryptionRounds); return p; } public override void Randomize(KdfParameters p) { if(p == null) { Debug.Assert(false); return; } Debug.Assert(g_uuid.Equals(p.KdfUuid)); byte[] pbSeed = CryptoRandom.Instance.GetRandomBytes(32); p.SetByteArray(ParamSeed, pbSeed); } public override byte[] Transform(byte[] pbMsg, KdfParameters p) { if(pbMsg == null) throw new ArgumentNullException("pbMsg"); if(p == null) throw new ArgumentNullException("p"); Type tRounds = p.GetTypeOf(ParamRounds); if(tRounds == null) throw new ArgumentNullException("p.Rounds"); if(tRounds != typeof(ulong)) throw new ArgumentOutOfRangeException("p.Rounds"); ulong uRounds = p.GetUInt64(ParamRounds, 0); byte[] pbSeed = p.GetByteArray(ParamSeed); if(pbSeed == null) throw new ArgumentNullException("p.Seed"); if(pbMsg.Length != 32) { Debug.Assert(false); pbMsg = CryptoUtil.HashSha256(pbMsg); } if(pbSeed.Length != 32) { Debug.Assert(false); pbSeed = CryptoUtil.HashSha256(pbSeed); } return TransformKey(pbMsg, pbSeed, uRounds); } private static byte[] TransformKey(byte[] pbOriginalKey32, byte[] pbKeySeed32, ulong uNumRounds) { Debug.Assert((pbOriginalKey32 != null) && (pbOriginalKey32.Length == 32)); if(pbOriginalKey32 == null) throw new ArgumentNullException("pbOriginalKey32"); if(pbOriginalKey32.Length != 32) throw new ArgumentException(); Debug.Assert((pbKeySeed32 != null) && (pbKeySeed32.Length == 32)); if(pbKeySeed32 == null) throw new ArgumentNullException("pbKeySeed32"); if(pbKeySeed32.Length != 32) throw new ArgumentException(); byte[] pbNewKey = new byte[32]; Array.Copy(pbOriginalKey32, pbNewKey, pbNewKey.Length); try { // Try to use the native library first if(NativeLib.TransformKey256(pbNewKey, pbKeySeed32, uNumRounds)) return CryptoUtil.HashSha256(pbNewKey); if(TransformKeyGCrypt(pbNewKey, pbKeySeed32, uNumRounds)) return CryptoUtil.HashSha256(pbNewKey); if(TransformKeyManaged(pbNewKey, pbKeySeed32, uNumRounds)) return CryptoUtil.HashSha256(pbNewKey); } finally { MemUtil.ZeroByteArray(pbNewKey); } return null; } internal static bool TransformKeyManaged(byte[] pbNewKey32, byte[] pbKeySeed32, ulong uNumRounds) { #if KeePassUAP KeyParameter kp = new KeyParameter(pbKeySeed32); AesEngine aes = new AesEngine(); aes.Init(true, kp); for(ulong i = 0; i < uNumRounds; ++i) { aes.ProcessBlock(pbNewKey32, 0, pbNewKey32, 0); aes.ProcessBlock(pbNewKey32, 16, pbNewKey32, 16); } #else byte[] pbIV = new byte[16]; Array.Clear(pbIV, 0, pbIV.Length); SymmetricAlgorithm a = CryptoUtil.CreateAes(); if(a.BlockSize != 128) // AES block size { Debug.Assert(false); a.BlockSize = 128; } a.IV = pbIV; a.Mode = CipherMode.ECB; a.KeySize = 256; a.Key = pbKeySeed32; ICryptoTransform iCrypt = a.CreateEncryptor(); // !iCrypt.CanReuseTransform -- doesn't work with Mono if((iCrypt == null) || (iCrypt.InputBlockSize != 16) || (iCrypt.OutputBlockSize != 16)) { Debug.Assert(false, "Invalid ICryptoTransform."); Debug.Assert((iCrypt.InputBlockSize == 16), "Invalid input block size!"); Debug.Assert((iCrypt.OutputBlockSize == 16), "Invalid output block size!"); return false; } for(ulong i = 0; i < uNumRounds; ++i) { iCrypt.TransformBlock(pbNewKey32, 0, 16, pbNewKey32, 0); iCrypt.TransformBlock(pbNewKey32, 16, 16, pbNewKey32, 16); } #endif return true; } public override KdfParameters GetBestParameters(uint uMilliseconds) { KdfParameters p = GetDefaultParameters(); ulong uRounds; // Try native method if(NativeLib.TransformKeyBenchmark256(uMilliseconds, out uRounds)) { p.SetUInt64(ParamRounds, uRounds); return p; } if(TransformKeyBenchmarkGCrypt(uMilliseconds, out uRounds)) { p.SetUInt64(ParamRounds, uRounds); return p; } byte[] pbKey = new byte[32]; byte[] pbNewKey = new byte[32]; for(int i = 0; i < pbKey.Length; ++i) { pbKey[i] = (byte)i; pbNewKey[i] = (byte)i; } #if KeePassUAP KeyParameter kp = new KeyParameter(pbKey); AesEngine aes = new AesEngine(); aes.Init(true, kp); #else byte[] pbIV = new byte[16]; Array.Clear(pbIV, 0, pbIV.Length); SymmetricAlgorithm a = CryptoUtil.CreateAes(); if(a.BlockSize != 128) // AES block size { Debug.Assert(false); a.BlockSize = 128; } a.IV = pbIV; a.Mode = CipherMode.ECB; a.KeySize = 256; a.Key = pbKey; ICryptoTransform iCrypt = a.CreateEncryptor(); // !iCrypt.CanReuseTransform -- doesn't work with Mono if((iCrypt == null) || (iCrypt.InputBlockSize != 16) || (iCrypt.OutputBlockSize != 16)) { Debug.Assert(false, "Invalid ICryptoTransform."); Debug.Assert(iCrypt.InputBlockSize == 16, "Invalid input block size!"); Debug.Assert(iCrypt.OutputBlockSize == 16, "Invalid output block size!"); p.SetUInt64(ParamRounds, PwDefs.DefaultKeyEncryptionRounds); return p; } #endif uRounds = 0; int tStart = Environment.TickCount; while(true) { for(ulong j = 0; j < BenchStep; ++j) { #if KeePassUAP aes.ProcessBlock(pbNewKey, 0, pbNewKey, 0); aes.ProcessBlock(pbNewKey, 16, pbNewKey, 16); #else iCrypt.TransformBlock(pbNewKey, 0, 16, pbNewKey, 0); iCrypt.TransformBlock(pbNewKey, 16, 16, pbNewKey, 16); #endif } uRounds += BenchStep; if(uRounds < BenchStep) // Overflow check { uRounds = ulong.MaxValue; break; } uint tElapsed = (uint)(Environment.TickCount - tStart); if(tElapsed > uMilliseconds) break; } p.SetUInt64(ParamRounds, uRounds); return p; } } } KeePassLib/Cryptography/KeyDerivation/KdfEngine.cs0000664000000000000000000000732513222430400021166 0ustar rootroot/* KeePass Password Safe - The Open-Source Password Manager Copyright (C) 2003-2018 Dominik Reichl This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ using System; using System.Collections.Generic; using System.Diagnostics; using System.Text; namespace KeePassLib.Cryptography.KeyDerivation { public abstract class KdfEngine { public abstract PwUuid Uuid { get; } public abstract string Name { get; } public virtual KdfParameters GetDefaultParameters() { return new KdfParameters(this.Uuid); } /// /// Generate random seeds and store them in . /// public virtual void Randomize(KdfParameters p) { Debug.Assert(p != null); Debug.Assert(p.KdfUuid.Equals(this.Uuid)); } public abstract byte[] Transform(byte[] pbMsg, KdfParameters p); public virtual KdfParameters GetBestParameters(uint uMilliseconds) { throw new NotImplementedException(); } protected void MaximizeParamUInt64(KdfParameters p, string strName, ulong uMin, ulong uMax, uint uMilliseconds, bool bInterpSearch) { if(p == null) { Debug.Assert(false); return; } if(string.IsNullOrEmpty(strName)) { Debug.Assert(false); return; } if(uMin > uMax) { Debug.Assert(false); return; } if(uMax > (ulong.MaxValue >> 1)) { Debug.Assert(false); uMax = ulong.MaxValue >> 1; if(uMin > uMax) { p.SetUInt64(strName, uMin); return; } } byte[] pbMsg = new byte[32]; for(int i = 0; i < pbMsg.Length; ++i) pbMsg[i] = (byte)i; ulong uLow = uMin; ulong uHigh = uMin + 1UL; long tLow = 0; long tHigh = 0; long tTarget = (long)uMilliseconds; // Determine range while(uHigh <= uMax) { p.SetUInt64(strName, uHigh); // GC.Collect(); Stopwatch sw = Stopwatch.StartNew(); Transform(pbMsg, p); sw.Stop(); tHigh = sw.ElapsedMilliseconds; if(tHigh > tTarget) break; uLow = uHigh; tLow = tHigh; uHigh <<= 1; } if(uHigh > uMax) { uHigh = uMax; tHigh = 0; } if(uLow > uHigh) uLow = uHigh; // Skips to end // Find optimal number of iterations while((uHigh - uLow) >= 2UL) { ulong u = (uHigh + uLow) >> 1; // Binary search // Interpolation search, if possible if(bInterpSearch && (tLow > 0) && (tHigh > tTarget) && (tLow <= tTarget)) { u = uLow + (((uHigh - uLow) * (ulong)(tTarget - tLow)) / (ulong)(tHigh - tLow)); if((u >= uLow) && (u <= uHigh)) { u = Math.Max(u, uLow + 1UL); u = Math.Min(u, uHigh - 1UL); } else { Debug.Assert(false); u = (uHigh + uLow) >> 1; } } p.SetUInt64(strName, u); // GC.Collect(); Stopwatch sw = Stopwatch.StartNew(); Transform(pbMsg, p); sw.Stop(); long t = sw.ElapsedMilliseconds; if(t == tTarget) { uLow = u; break; } else if(t > tTarget) { uHigh = u; tHigh = t; } else { uLow = u; tLow = t; } } p.SetUInt64(strName, uLow); } } } KeePassLib/Cryptography/KeyDerivation/KdfPool.cs0000664000000000000000000000450113222430400020663 0ustar rootroot/* KeePass Password Safe - The Open-Source Password Manager Copyright (C) 2003-2018 Dominik Reichl This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ using System; using System.Collections.Generic; using System.Diagnostics; using System.Text; using KeePassLib.Utility; namespace KeePassLib.Cryptography.KeyDerivation { public static class KdfPool { private static List g_l = new List(); public static IEnumerable Engines { get { EnsureInitialized(); return g_l; } } private static void EnsureInitialized() { if(g_l.Count > 0) return; g_l.Add(new AesKdf()); g_l.Add(new Argon2Kdf()); } internal static KdfParameters GetDefaultParameters() { EnsureInitialized(); return g_l[0].GetDefaultParameters(); } public static KdfEngine Get(PwUuid pu) { if(pu == null) { Debug.Assert(false); return null; } EnsureInitialized(); foreach(KdfEngine kdf in g_l) { if(pu.Equals(kdf.Uuid)) return kdf; } return null; } public static KdfEngine Get(string strName) { if(string.IsNullOrEmpty(strName)) { Debug.Assert(false); return null; } EnsureInitialized(); foreach(KdfEngine kdf in g_l) { if(strName.Equals(kdf.Name, StrUtil.CaseIgnoreCmp)) return kdf; } return null; } public static void Add(KdfEngine kdf) { if(kdf == null) { Debug.Assert(false); return; } EnsureInitialized(); if(Get(kdf.Uuid) != null) { Debug.Assert(false); return; } if(Get(kdf.Name) != null) { Debug.Assert(false); return; } g_l.Add(kdf); } } } KeePassLib/Cryptography/KeyDerivation/AesKdf.GCrypt.cs0000664000000000000000000002507713222430400021704 0ustar rootroot/* KeePass Password Safe - The Open-Source Password Manager Copyright (C) 2003-2018 Dominik Reichl This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ using System; using System.Collections.Generic; using System.Diagnostics; using System.Runtime.InteropServices; using System.Text; using System.Threading; using KeePassLib.Native; using KeePassLib.Utility; namespace KeePassLib.Cryptography.KeyDerivation { public sealed partial class AesKdf : KdfEngine { private static bool TransformKeyGCrypt(byte[] pbData32, byte[] pbSeed32, ulong uRounds) { byte[] pbNewData32 = null; try { if(GCryptInitLib()) { pbNewData32 = new byte[32]; Array.Copy(pbData32, pbNewData32, 32); if(TransformKeyGCryptPriv(pbNewData32, pbSeed32, uRounds)) { Array.Copy(pbNewData32, pbData32, 32); return true; } } } catch(Exception) { } finally { if(pbNewData32 != null) MemUtil.ZeroByteArray(pbNewData32); } return false; } private static bool TransformKeyBenchmarkGCrypt(uint uTimeMs, out ulong uRounds) { uRounds = 0; try { if(GCryptInitLib()) return TransformKeyBenchmarkGCryptPriv(uTimeMs, ref uRounds); } catch(Exception) { } return false; } private static bool GCryptInitLib() { Debug.Assert(Marshal.SizeOf(typeof(int)) == 4); // Also on 64-bit systems Debug.Assert(Marshal.SizeOf(typeof(uint)) == 4); if(!NativeLib.IsUnix()) return false; // Independent of workaround state if(!MonoWorkarounds.IsRequired(1468)) return false; // Can be turned off // gcry_check_version initializes the library; // throws when LibGCrypt is not available NativeMethods.gcry_check_version(IntPtr.Zero); return true; } // ============================================================= // Multi-threaded implementation // For some reason, the following multi-threaded implementation // is slower than the single-threaded implementation below // (threading overhead by Mono? LibGCrypt threading issues?) /* private sealed class GCryptTransformInfo : IDisposable { public IntPtr Data16; public IntPtr Seed32; public ulong Rounds; public uint TimeMs; public bool Success = false; public GCryptTransformInfo(byte[] pbData32, int iDataOffset, byte[] pbSeed32, ulong uRounds, uint uTimeMs) { this.Data16 = Marshal.AllocCoTaskMem(16); Marshal.Copy(pbData32, iDataOffset, this.Data16, 16); this.Seed32 = Marshal.AllocCoTaskMem(32); Marshal.Copy(pbSeed32, 0, this.Seed32, 32); this.Rounds = uRounds; this.TimeMs = uTimeMs; } public void Dispose() { if(this.Data16 != IntPtr.Zero) { Marshal.WriteInt64(this.Data16, 0); Marshal.WriteInt64(this.Data16, 8, 0); Marshal.FreeCoTaskMem(this.Data16); this.Data16 = IntPtr.Zero; } if(this.Seed32 != IntPtr.Zero) { Marshal.FreeCoTaskMem(this.Seed32); this.Seed32 = IntPtr.Zero; } } } private static GCryptTransformInfo[] GCryptRun(byte[] pbData32, byte[] pbSeed32, ulong uRounds, uint uTimeMs, ParameterizedThreadStart fL, ParameterizedThreadStart fR) { GCryptTransformInfo tiL = new GCryptTransformInfo(pbData32, 0, pbSeed32, uRounds, uTimeMs); GCryptTransformInfo tiR = new GCryptTransformInfo(pbData32, 16, pbSeed32, uRounds, uTimeMs); Thread th = new Thread(fL); th.Start(tiL); fR(tiR); th.Join(); Marshal.Copy(tiL.Data16, pbData32, 0, 16); Marshal.Copy(tiR.Data16, pbData32, 16, 16); tiL.Dispose(); tiR.Dispose(); if(tiL.Success && tiR.Success) return new GCryptTransformInfo[2] { tiL, tiR }; return null; } private static bool TransformKeyGCryptPriv(byte[] pbData32, byte[] pbSeed32, ulong uRounds) { return (GCryptRun(pbData32, pbSeed32, uRounds, 0, new ParameterizedThreadStart(AesKdf.GCryptTransformTh), new ParameterizedThreadStart(AesKdf.GCryptTransformTh)) != null); } private static bool GCryptInitCipher(ref IntPtr h, GCryptTransformInfo ti) { NativeMethods.gcry_cipher_open(ref h, NativeMethods.GCRY_CIPHER_AES256, NativeMethods.GCRY_CIPHER_MODE_ECB, 0); if(h == IntPtr.Zero) { Debug.Assert(false); return false; } IntPtr n32 = new IntPtr(32); if(NativeMethods.gcry_cipher_setkey(h, ti.Seed32, n32) != 0) { Debug.Assert(false); return false; } return true; } private static void GCryptTransformTh(object o) { IntPtr h = IntPtr.Zero; try { GCryptTransformInfo ti = (o as GCryptTransformInfo); if(ti == null) { Debug.Assert(false); return; } if(!GCryptInitCipher(ref h, ti)) return; IntPtr n16 = new IntPtr(16); for(ulong u = 0; u < ti.Rounds; ++u) { if(NativeMethods.gcry_cipher_encrypt(h, ti.Data16, n16, IntPtr.Zero, IntPtr.Zero) != 0) { Debug.Assert(false); return; } } ti.Success = true; } catch(Exception) { Debug.Assert(false); } finally { try { if(h != IntPtr.Zero) NativeMethods.gcry_cipher_close(h); } catch(Exception) { Debug.Assert(false); } } } private static bool TransformKeyBenchmarkGCryptPriv(uint uTimeMs, ref ulong uRounds) { GCryptTransformInfo[] v = GCryptRun(new byte[32], new byte[32], 0, uTimeMs, new ParameterizedThreadStart(AesKdf.GCryptBenchmarkTh), new ParameterizedThreadStart(AesKdf.GCryptBenchmarkTh)); if(v != null) { ulong uL = Math.Min(v[0].Rounds, ulong.MaxValue >> 1); ulong uR = Math.Min(v[1].Rounds, ulong.MaxValue >> 1); uRounds = (uL + uR) / 2; return true; } return false; } private static void GCryptBenchmarkTh(object o) { IntPtr h = IntPtr.Zero; try { GCryptTransformInfo ti = (o as GCryptTransformInfo); if(ti == null) { Debug.Assert(false); return; } if(!GCryptInitCipher(ref h, ti)) return; ulong r = 0; IntPtr n16 = new IntPtr(16); int tStart = Environment.TickCount; while(true) { for(ulong j = 0; j < BenchStep; ++j) { if(NativeMethods.gcry_cipher_encrypt(h, ti.Data16, n16, IntPtr.Zero, IntPtr.Zero) != 0) { Debug.Assert(false); return; } } r += BenchStep; if(r < BenchStep) // Overflow check { r = ulong.MaxValue; break; } uint tElapsed = (uint)(Environment.TickCount - tStart); if(tElapsed > ti.TimeMs) break; } ti.Rounds = r; ti.Success = true; } catch(Exception) { Debug.Assert(false); } finally { try { if(h != IntPtr.Zero) NativeMethods.gcry_cipher_close(h); } catch(Exception) { Debug.Assert(false); } } } */ // ============================================================= // Single-threaded implementation private static bool GCryptInitCipher(ref IntPtr h, IntPtr pSeed32) { NativeMethods.gcry_cipher_open(ref h, NativeMethods.GCRY_CIPHER_AES256, NativeMethods.GCRY_CIPHER_MODE_ECB, 0); if(h == IntPtr.Zero) { Debug.Assert(false); return false; } IntPtr n32 = new IntPtr(32); if(NativeMethods.gcry_cipher_setkey(h, pSeed32, n32) != 0) { Debug.Assert(false); return false; } return true; } private static bool GCryptBegin(byte[] pbData32, byte[] pbSeed32, ref IntPtr h, ref IntPtr pData32, ref IntPtr pSeed32) { pData32 = Marshal.AllocCoTaskMem(32); pSeed32 = Marshal.AllocCoTaskMem(32); Marshal.Copy(pbData32, 0, pData32, 32); Marshal.Copy(pbSeed32, 0, pSeed32, 32); return GCryptInitCipher(ref h, pSeed32); } private static void GCryptEnd(IntPtr h, IntPtr pData32, IntPtr pSeed32) { NativeMethods.gcry_cipher_close(h); Marshal.WriteInt64(pData32, 0); Marshal.WriteInt64(pData32, 8, 0); Marshal.WriteInt64(pData32, 16, 0); Marshal.WriteInt64(pData32, 24, 0); Marshal.FreeCoTaskMem(pData32); Marshal.FreeCoTaskMem(pSeed32); } private static bool TransformKeyGCryptPriv(byte[] pbData32, byte[] pbSeed32, ulong uRounds) { IntPtr h = IntPtr.Zero, pData32 = IntPtr.Zero, pSeed32 = IntPtr.Zero; if(!GCryptBegin(pbData32, pbSeed32, ref h, ref pData32, ref pSeed32)) return false; try { IntPtr n32 = new IntPtr(32); for(ulong i = 0; i < uRounds; ++i) { if(NativeMethods.gcry_cipher_encrypt(h, pData32, n32, IntPtr.Zero, IntPtr.Zero) != 0) { Debug.Assert(false); return false; } } Marshal.Copy(pData32, pbData32, 0, 32); return true; } catch(Exception) { Debug.Assert(false); } finally { GCryptEnd(h, pData32, pSeed32); } return false; } private static bool TransformKeyBenchmarkGCryptPriv(uint uTimeMs, ref ulong uRounds) { byte[] pbData32 = new byte[32]; byte[] pbSeed32 = new byte[32]; IntPtr h = IntPtr.Zero, pData32 = IntPtr.Zero, pSeed32 = IntPtr.Zero; if(!GCryptBegin(pbData32, pbSeed32, ref h, ref pData32, ref pSeed32)) return false; uint uMaxMs = uTimeMs; ulong uDiv = 1; if(uMaxMs <= (uint.MaxValue >> 1)) { uMaxMs *= 2U; uDiv = 2; } try { ulong r = 0; IntPtr n32 = new IntPtr(32); int tStart = Environment.TickCount; while(true) { for(ulong j = 0; j < BenchStep; ++j) { if(NativeMethods.gcry_cipher_encrypt(h, pData32, n32, IntPtr.Zero, IntPtr.Zero) != 0) { Debug.Assert(false); return false; } } r += BenchStep; if(r < BenchStep) // Overflow check { r = ulong.MaxValue; break; } uint tElapsed = (uint)(Environment.TickCount - tStart); if(tElapsed > uMaxMs) break; } uRounds = r / uDiv; return true; } catch(Exception) { Debug.Assert(false); } finally { GCryptEnd(h, pData32, pSeed32); } return false; } } } KeePassLib/Cryptography/KeyDerivation/Argon2Kdf.Core.cs0000664000000000000000000004432113222430400021775 0ustar rootroot/* KeePass Password Safe - The Open-Source Password Manager Copyright (C) 2003-2018 Dominik Reichl This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ // This implementation is based on the official reference C // implementation by Daniel Dinu and Dmitry Khovratovich (CC0 1.0). // Relative iterations (* = B2ROUND_ARRAYS \\ G_INLINED): // * | false true // ------+----------- // false | 8885 9618 // true | 9009 9636 #define ARGON2_B2ROUND_ARRAYS #define ARGON2_G_INLINED using System; using System.Collections.Generic; using System.Diagnostics; using System.Runtime.InteropServices; using System.Text; using System.Threading; using KeePassLib.Cryptography.Hash; using KeePassLib.Utility; namespace KeePassLib.Cryptography.KeyDerivation { public sealed partial class Argon2Kdf : KdfEngine { private const ulong NbBlockSize = 1024; private const ulong NbBlockSizeInQW = NbBlockSize / 8UL; private const ulong NbSyncPoints = 4; private const int NbPreHashDigestLength = 64; private const int NbPreHashSeedLength = NbPreHashDigestLength + 8; #if ARGON2_B2ROUND_ARRAYS private static int[][] g_vFBCols = null; private static int[][] g_vFBRows = null; #endif private sealed class Argon2Ctx { public uint Version = 0; public ulong Lanes = 0; public ulong TCost = 0; public ulong MCost = 0; public ulong MemoryBlocks = 0; public ulong SegmentLength = 0; public ulong LaneLength = 0; public ulong[] Mem = null; } private sealed class Argon2ThreadInfo { public Argon2Ctx Context = null; public ManualResetEvent Finished = new ManualResetEvent(false); public ulong Pass = 0; public ulong Lane = 0; public ulong Slice = 0; public ulong Index = 0; public void Release() { if(this.Finished != null) { this.Finished.Close(); this.Finished = null; } else { Debug.Assert(false); } } } private static byte[] Argon2d(byte[] pbMsg, byte[] pbSalt, uint uParallel, ulong uMem, ulong uIt, int cbOut, uint uVersion, byte[] pbSecretKey, byte[] pbAssocData) { pbSecretKey = (pbSecretKey ?? MemUtil.EmptyByteArray); pbAssocData = (pbAssocData ?? MemUtil.EmptyByteArray); #if ARGON2_B2ROUND_ARRAYS InitB2RoundIndexArrays(); #endif Argon2Ctx ctx = new Argon2Ctx(); ctx.Version = uVersion; ctx.Lanes = uParallel; ctx.TCost = uIt; ctx.MCost = uMem / NbBlockSize; ctx.MemoryBlocks = Math.Max(ctx.MCost, 2UL * NbSyncPoints * ctx.Lanes); ctx.SegmentLength = ctx.MemoryBlocks / (ctx.Lanes * NbSyncPoints); ctx.MemoryBlocks = ctx.SegmentLength * ctx.Lanes * NbSyncPoints; ctx.LaneLength = ctx.SegmentLength * NbSyncPoints; Debug.Assert(NbBlockSize == (NbBlockSizeInQW * #if KeePassUAP (ulong)Marshal.SizeOf() #else (ulong)Marshal.SizeOf(typeof(ulong)) #endif )); ctx.Mem = new ulong[ctx.MemoryBlocks * NbBlockSizeInQW]; Blake2b h = new Blake2b(); // Initial hash Debug.Assert(h.HashSize == (NbPreHashDigestLength * 8)); byte[] pbBuf = new byte[4]; MemUtil.UInt32ToBytesEx(uParallel, pbBuf, 0); h.TransformBlock(pbBuf, 0, pbBuf.Length, pbBuf, 0); MemUtil.UInt32ToBytesEx((uint)cbOut, pbBuf, 0); h.TransformBlock(pbBuf, 0, pbBuf.Length, pbBuf, 0); MemUtil.UInt32ToBytesEx((uint)ctx.MCost, pbBuf, 0); h.TransformBlock(pbBuf, 0, pbBuf.Length, pbBuf, 0); MemUtil.UInt32ToBytesEx((uint)uIt, pbBuf, 0); h.TransformBlock(pbBuf, 0, pbBuf.Length, pbBuf, 0); MemUtil.UInt32ToBytesEx(uVersion, pbBuf, 0); h.TransformBlock(pbBuf, 0, pbBuf.Length, pbBuf, 0); MemUtil.UInt32ToBytesEx(0, pbBuf, 0); // Argon2d type = 0 h.TransformBlock(pbBuf, 0, pbBuf.Length, pbBuf, 0); MemUtil.UInt32ToBytesEx((uint)pbMsg.Length, pbBuf, 0); h.TransformBlock(pbBuf, 0, pbBuf.Length, pbBuf, 0); h.TransformBlock(pbMsg, 0, pbMsg.Length, pbMsg, 0); MemUtil.UInt32ToBytesEx((uint)pbSalt.Length, pbBuf, 0); h.TransformBlock(pbBuf, 0, pbBuf.Length, pbBuf, 0); h.TransformBlock(pbSalt, 0, pbSalt.Length, pbSalt, 0); MemUtil.UInt32ToBytesEx((uint)pbSecretKey.Length, pbBuf, 0); h.TransformBlock(pbBuf, 0, pbBuf.Length, pbBuf, 0); h.TransformBlock(pbSecretKey, 0, pbSecretKey.Length, pbSecretKey, 0); MemUtil.UInt32ToBytesEx((uint)pbAssocData.Length, pbBuf, 0); h.TransformBlock(pbBuf, 0, pbBuf.Length, pbBuf, 0); h.TransformBlock(pbAssocData, 0, pbAssocData.Length, pbAssocData, 0); h.TransformFinalBlock(MemUtil.EmptyByteArray, 0, 0); byte[] pbH0 = h.Hash; Debug.Assert(pbH0.Length == 64); byte[] pbBlockHash = new byte[NbPreHashSeedLength]; Array.Copy(pbH0, pbBlockHash, pbH0.Length); MemUtil.ZeroByteArray(pbH0); FillFirstBlocks(ctx, pbBlockHash, h); MemUtil.ZeroByteArray(pbBlockHash); FillMemoryBlocks(ctx); byte[] pbOut = FinalHash(ctx, cbOut, h); h.Clear(); MemUtil.ZeroArray(ctx.Mem); return pbOut; } private static void LoadBlock(ulong[] pqDst, ulong uDstOffset, byte[] pbIn) { // for(ulong i = 0; i < NbBlockSizeInQW; ++i) // pqDst[uDstOffset + i] = MemUtil.BytesToUInt64(pbIn, (int)(i << 3)); Debug.Assert((uDstOffset + NbBlockSizeInQW - 1UL) <= (ulong)int.MaxValue); int iDstOffset = (int)uDstOffset; for(int i = 0; i < (int)NbBlockSizeInQW; ++i) pqDst[iDstOffset + i] = MemUtil.BytesToUInt64(pbIn, i << 3); } private static void StoreBlock(byte[] pbDst, ulong[] pqSrc) { for(int i = 0; i < (int)NbBlockSizeInQW; ++i) MemUtil.UInt64ToBytesEx(pqSrc[i], pbDst, i << 3); } private static void CopyBlock(ulong[] vDst, ulong uDstOffset, ulong[] vSrc, ulong uSrcOffset) { // for(ulong i = 0; i < NbBlockSizeInQW; ++i) // vDst[uDstOffset + i] = vSrc[uSrcOffset + i]; // Debug.Assert((uDstOffset + NbBlockSizeInQW - 1UL) <= (ulong)int.MaxValue); // Debug.Assert((uSrcOffset + NbBlockSizeInQW - 1UL) <= (ulong)int.MaxValue); // int iDstOffset = (int)uDstOffset; // int iSrcOffset = (int)uSrcOffset; // for(int i = 0; i < (int)NbBlockSizeInQW; ++i) // vDst[iDstOffset + i] = vSrc[iSrcOffset + i]; #if KeePassUAP Array.Copy(vSrc, (int)uSrcOffset, vDst, (int)uDstOffset, (int)NbBlockSizeInQW); #else Array.Copy(vSrc, (long)uSrcOffset, vDst, (long)uDstOffset, (long)NbBlockSizeInQW); #endif } private static void XorBlock(ulong[] vDst, ulong uDstOffset, ulong[] vSrc, ulong uSrcOffset) { // for(ulong i = 0; i < NbBlockSizeInQW; ++i) // vDst[uDstOffset + i] ^= vSrc[uSrcOffset + i]; Debug.Assert((uDstOffset + NbBlockSizeInQW - 1UL) <= (ulong)int.MaxValue); Debug.Assert((uSrcOffset + NbBlockSizeInQW - 1UL) <= (ulong)int.MaxValue); int iDstOffset = (int)uDstOffset; int iSrcOffset = (int)uSrcOffset; for(int i = 0; i < (int)NbBlockSizeInQW; ++i) vDst[iDstOffset + i] ^= vSrc[iSrcOffset + i]; } private static void Blake2bLong(byte[] pbOut, int cbOut, byte[] pbIn, int cbIn, Blake2b h) { Debug.Assert((h != null) && (h.HashSize == (64 * 8))); byte[] pbOutLen = new byte[4]; MemUtil.UInt32ToBytesEx((uint)cbOut, pbOutLen, 0); if(cbOut <= 64) { Blake2b hOut = ((cbOut == 64) ? h : new Blake2b(cbOut)); if(cbOut == 64) hOut.Initialize(); hOut.TransformBlock(pbOutLen, 0, pbOutLen.Length, pbOutLen, 0); hOut.TransformBlock(pbIn, 0, cbIn, pbIn, 0); hOut.TransformFinalBlock(MemUtil.EmptyByteArray, 0, 0); Array.Copy(hOut.Hash, pbOut, cbOut); if(cbOut < 64) hOut.Clear(); return; } h.Initialize(); h.TransformBlock(pbOutLen, 0, pbOutLen.Length, pbOutLen, 0); h.TransformBlock(pbIn, 0, cbIn, pbIn, 0); h.TransformFinalBlock(MemUtil.EmptyByteArray, 0, 0); byte[] pbOutBuffer = new byte[64]; Array.Copy(h.Hash, pbOutBuffer, pbOutBuffer.Length); int ibOut = 64 / 2; Array.Copy(pbOutBuffer, pbOut, ibOut); int cbToProduce = cbOut - ibOut; h.Initialize(); while(cbToProduce > 64) { byte[] pbHash = h.ComputeHash(pbOutBuffer); Array.Copy(pbHash, pbOutBuffer, 64); Array.Copy(pbHash, 0, pbOut, ibOut, 64 / 2); ibOut += 64 / 2; cbToProduce -= 64 / 2; MemUtil.ZeroByteArray(pbHash); } using(Blake2b hOut = new Blake2b(cbToProduce)) { byte[] pbHash = hOut.ComputeHash(pbOutBuffer); Array.Copy(pbHash, 0, pbOut, ibOut, cbToProduce); MemUtil.ZeroByteArray(pbHash); } MemUtil.ZeroByteArray(pbOutBuffer); } #if !ARGON2_G_INLINED private static ulong BlaMka(ulong x, ulong y) { ulong xy = (x & 0xFFFFFFFFUL) * (y & 0xFFFFFFFFUL); return (x + y + (xy << 1)); } private static void G(ulong[] v, int a, int b, int c, int d) { ulong va = v[a], vb = v[b], vc = v[c], vd = v[d]; va = BlaMka(va, vb); vd = MemUtil.RotateRight64(vd ^ va, 32); vc = BlaMka(vc, vd); vb = MemUtil.RotateRight64(vb ^ vc, 24); va = BlaMka(va, vb); vd = MemUtil.RotateRight64(vd ^ va, 16); vc = BlaMka(vc, vd); vb = MemUtil.RotateRight64(vb ^ vc, 63); v[a] = va; v[b] = vb; v[c] = vc; v[d] = vd; } #else private static void G(ulong[] v, int a, int b, int c, int d) { ulong va = v[a], vb = v[b], vc = v[c], vd = v[d]; ulong xy = (va & 0xFFFFFFFFUL) * (vb & 0xFFFFFFFFUL); va += vb + (xy << 1); vd = MemUtil.RotateRight64(vd ^ va, 32); xy = (vc & 0xFFFFFFFFUL) * (vd & 0xFFFFFFFFUL); vc += vd + (xy << 1); vb = MemUtil.RotateRight64(vb ^ vc, 24); xy = (va & 0xFFFFFFFFUL) * (vb & 0xFFFFFFFFUL); va += vb + (xy << 1); vd = MemUtil.RotateRight64(vd ^ va, 16); xy = (vc & 0xFFFFFFFFUL) * (vd & 0xFFFFFFFFUL); vc += vd + (xy << 1); vb = MemUtil.RotateRight64(vb ^ vc, 63); v[a] = va; v[b] = vb; v[c] = vc; v[d] = vd; } #endif #if ARGON2_B2ROUND_ARRAYS private static void Blake2RoundNoMsg(ulong[] pbR, int[] v) { G(pbR, v[0], v[4], v[8], v[12]); G(pbR, v[1], v[5], v[9], v[13]); G(pbR, v[2], v[6], v[10], v[14]); G(pbR, v[3], v[7], v[11], v[15]); G(pbR, v[0], v[5], v[10], v[15]); G(pbR, v[1], v[6], v[11], v[12]); G(pbR, v[2], v[7], v[8], v[13]); G(pbR, v[3], v[4], v[9], v[14]); } #else private static void Blake2RoundNoMsgCols16i(ulong[] pbR, int i) { G(pbR, i, i + 4, i + 8, i + 12); G(pbR, i + 1, i + 5, i + 9, i + 13); G(pbR, i + 2, i + 6, i + 10, i + 14); G(pbR, i + 3, i + 7, i + 11, i + 15); G(pbR, i, i + 5, i + 10, i + 15); G(pbR, i + 1, i + 6, i + 11, i + 12); G(pbR, i + 2, i + 7, i + 8, i + 13); G(pbR, i + 3, i + 4, i + 9, i + 14); } private static void Blake2RoundNoMsgRows2i(ulong[] pbR, int i) { G(pbR, i, i + 32, i + 64, i + 96); G(pbR, i + 1, i + 33, i + 65, i + 97); G(pbR, i + 16, i + 48, i + 80, i + 112); G(pbR, i + 17, i + 49, i + 81, i + 113); G(pbR, i, i + 33, i + 80, i + 113); G(pbR, i + 1, i + 48, i + 81, i + 96); G(pbR, i + 16, i + 49, i + 64, i + 97); G(pbR, i + 17, i + 32, i + 65, i + 112); } #endif private static void FillFirstBlocks(Argon2Ctx ctx, byte[] pbBlockHash, Blake2b h) { byte[] pbBlock = new byte[NbBlockSize]; for(ulong l = 0; l < ctx.Lanes; ++l) { MemUtil.UInt32ToBytesEx(0, pbBlockHash, NbPreHashDigestLength); MemUtil.UInt32ToBytesEx((uint)l, pbBlockHash, NbPreHashDigestLength + 4); Blake2bLong(pbBlock, (int)NbBlockSize, pbBlockHash, NbPreHashSeedLength, h); LoadBlock(ctx.Mem, l * ctx.LaneLength * NbBlockSizeInQW, pbBlock); MemUtil.UInt32ToBytesEx(1, pbBlockHash, NbPreHashDigestLength); Blake2bLong(pbBlock, (int)NbBlockSize, pbBlockHash, NbPreHashSeedLength, h); LoadBlock(ctx.Mem, (l * ctx.LaneLength + 1UL) * NbBlockSizeInQW, pbBlock); } MemUtil.ZeroByteArray(pbBlock); } private static ulong IndexAlpha(Argon2Ctx ctx, Argon2ThreadInfo ti, uint uPseudoRand, bool bSameLane) { ulong uRefAreaSize; if(ti.Pass == 0) { if(ti.Slice == 0) { Debug.Assert(ti.Index > 0); uRefAreaSize = ti.Index - 1UL; } else { if(bSameLane) uRefAreaSize = ti.Slice * ctx.SegmentLength + ti.Index - 1UL; else uRefAreaSize = ti.Slice * ctx.SegmentLength - ((ti.Index == 0UL) ? 1UL : 0UL); } } else { if(bSameLane) uRefAreaSize = ctx.LaneLength - ctx.SegmentLength + ti.Index - 1UL; else uRefAreaSize = ctx.LaneLength - ctx.SegmentLength - ((ti.Index == 0) ? 1UL : 0UL); } Debug.Assert(uRefAreaSize <= (ulong)uint.MaxValue); ulong uRelPos = uPseudoRand; uRelPos = (uRelPos * uRelPos) >> 32; uRelPos = uRefAreaSize - 1UL - ((uRefAreaSize * uRelPos) >> 32); ulong uStart = 0; if(ti.Pass != 0) uStart = (((ti.Slice + 1UL) == NbSyncPoints) ? 0UL : ((ti.Slice + 1UL) * ctx.SegmentLength)); Debug.Assert(uStart <= (ulong)uint.MaxValue); Debug.Assert(ctx.LaneLength <= (ulong)uint.MaxValue); return ((uStart + uRelPos) % ctx.LaneLength); } private static void FillMemoryBlocks(Argon2Ctx ctx) { int np = (int)ctx.Lanes; Argon2ThreadInfo[] v = new Argon2ThreadInfo[np]; for(ulong r = 0; r < ctx.TCost; ++r) { for(ulong s = 0; s < NbSyncPoints; ++s) { for(int l = 0; l < np; ++l) { Argon2ThreadInfo ti = new Argon2ThreadInfo(); ti.Context = ctx; ti.Pass = r; ti.Lane = (ulong)l; ti.Slice = s; if(!ThreadPool.QueueUserWorkItem(FillSegmentThr, ti)) { Debug.Assert(false); throw new OutOfMemoryException(); } v[l] = ti; } for(int l = 0; l < np; ++l) { v[l].Finished.WaitOne(); v[l].Release(); } } } } private static void FillSegmentThr(object o) { Argon2ThreadInfo ti = (o as Argon2ThreadInfo); if(ti == null) { Debug.Assert(false); return; } try { Argon2Ctx ctx = ti.Context; if(ctx == null) { Debug.Assert(false); return; } Debug.Assert(ctx.Version >= MinVersion); bool bCanXor = (ctx.Version >= 0x13U); ulong uStart = 0; if((ti.Pass == 0) && (ti.Slice == 0)) uStart = 2; ulong uCur = (ti.Lane * ctx.LaneLength) + (ti.Slice * ctx.SegmentLength) + uStart; ulong uPrev = (((uCur % ctx.LaneLength) == 0) ? (uCur + ctx.LaneLength - 1UL) : (uCur - 1UL)); ulong[] pbR = new ulong[NbBlockSizeInQW]; ulong[] pbTmp = new ulong[NbBlockSizeInQW]; for(ulong i = uStart; i < ctx.SegmentLength; ++i) { if((uCur % ctx.LaneLength) == 1) uPrev = uCur - 1UL; ulong uPseudoRand = ctx.Mem[uPrev * NbBlockSizeInQW]; ulong uRefLane = (uPseudoRand >> 32) % ctx.Lanes; if((ti.Pass == 0) && (ti.Slice == 0)) uRefLane = ti.Lane; ti.Index = i; ulong uRefIndex = IndexAlpha(ctx, ti, (uint)uPseudoRand, (uRefLane == ti.Lane)); ulong uRefBlockIndex = (ctx.LaneLength * uRefLane + uRefIndex) * NbBlockSizeInQW; ulong uCurBlockIndex = uCur * NbBlockSizeInQW; FillBlock(ctx.Mem, uPrev * NbBlockSizeInQW, uRefBlockIndex, uCurBlockIndex, ((ti.Pass != 0) && bCanXor), pbR, pbTmp); ++uCur; ++uPrev; } MemUtil.ZeroArray(pbR); MemUtil.ZeroArray(pbTmp); } catch(Exception) { Debug.Assert(false); } try { ti.Finished.Set(); } catch(Exception) { Debug.Assert(false); } } #if ARGON2_B2ROUND_ARRAYS private static void InitB2RoundIndexArrays() { int[][] vCols = g_vFBCols; if(vCols == null) { vCols = new int[8][]; Debug.Assert(vCols.Length == 8); int e = 0; for(int i = 0; i < 8; ++i) { vCols[i] = new int[16]; for(int j = 0; j < 16; ++j) { vCols[i][j] = e; ++e; } } g_vFBCols = vCols; } int[][] vRows = g_vFBRows; if(vRows == null) { vRows = new int[8][]; for(int i = 0; i < 8; ++i) { vRows[i] = new int[16]; for(int j = 0; j < 16; ++j) { int jh = j / 2; vRows[i][j] = (2 * i) + (16 * jh) + (j & 1); } } g_vFBRows = vRows; } } #endif private static void FillBlock(ulong[] pMem, ulong uPrev, ulong uRef, ulong uNext, bool bXor, ulong[] pbR, ulong[] pbTmp) { CopyBlock(pbR, 0, pMem, uRef); XorBlock(pbR, 0, pMem, uPrev); CopyBlock(pbTmp, 0, pbR, 0); if(bXor) XorBlock(pbTmp, 0, pMem, uNext); #if ARGON2_B2ROUND_ARRAYS int[][] vCols = g_vFBCols; int[][] vRows = g_vFBRows; for(int i = 0; i < 8; ++i) Blake2RoundNoMsg(pbR, vCols[i]); for(int i = 0; i < 8; ++i) Blake2RoundNoMsg(pbR, vRows[i]); #else for(int i = 0; i < (8 * 16); i += 16) Blake2RoundNoMsgCols16i(pbR, i); for(int i = 0; i < (8 * 2); i += 2) Blake2RoundNoMsgRows2i(pbR, i); #endif CopyBlock(pMem, uNext, pbTmp, 0); XorBlock(pMem, uNext, pbR, 0); } private static byte[] FinalHash(Argon2Ctx ctx, int cbOut, Blake2b h) { ulong[] pqBlockHash = new ulong[NbBlockSizeInQW]; CopyBlock(pqBlockHash, 0, ctx.Mem, (ctx.LaneLength - 1UL) * NbBlockSizeInQW); for(ulong l = 1; l < ctx.Lanes; ++l) XorBlock(pqBlockHash, 0, ctx.Mem, (l * ctx.LaneLength + ctx.LaneLength - 1UL) * NbBlockSizeInQW); byte[] pbBlockHashBytes = new byte[NbBlockSize]; StoreBlock(pbBlockHashBytes, pqBlockHash); byte[] pbOut = new byte[cbOut]; Blake2bLong(pbOut, cbOut, pbBlockHashBytes, (int)NbBlockSize, h); MemUtil.ZeroArray(pqBlockHash); MemUtil.ZeroByteArray(pbBlockHashBytes); return pbOut; } } } KeePassLib/Cryptography/KeyDerivation/KdfParameters.cs0000664000000000000000000000423613222430400022062 0ustar rootroot/* KeePass Password Safe - The Open-Source Password Manager Copyright (C) 2003-2018 Dominik Reichl This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ using System; using System.Collections.Generic; using System.Diagnostics; using System.IO; using System.Text; using KeePassLib.Collections; using KeePassLib.Utility; namespace KeePassLib.Cryptography.KeyDerivation { public sealed class KdfParameters : VariantDictionary { private const string ParamUuid = @"$UUID"; private readonly PwUuid m_puKdf; public PwUuid KdfUuid { get { return m_puKdf; } } public KdfParameters(PwUuid puKdf) { if(puKdf == null) throw new ArgumentNullException("puKdf"); m_puKdf = puKdf; SetByteArray(ParamUuid, puKdf.UuidBytes); } /// /// Unsupported. /// public override object Clone() { throw new NotSupportedException(); } public static byte[] SerializeExt(KdfParameters p) { return VariantDictionary.Serialize(p); } public static KdfParameters DeserializeExt(byte[] pb) { VariantDictionary d = VariantDictionary.Deserialize(pb); if(d == null) { Debug.Assert(false); return null; } byte[] pbUuid = d.GetByteArray(ParamUuid); if((pbUuid == null) || (pbUuid.Length != (int)PwUuid.UuidSize)) { Debug.Assert(false); return null; } PwUuid pu = new PwUuid(pbUuid); KdfParameters p = new KdfParameters(pu); d.CopyTo(p); return p; } } } KeePassLib/Cryptography/KeyDerivation/Argon2Kdf.cs0000664000000000000000000001126213222430400021104 0ustar rootroot/* KeePass Password Safe - The Open-Source Password Manager Copyright (C) 2003-2018 Dominik Reichl This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ using System; using System.Collections.Generic; using System.Diagnostics; using System.Text; namespace KeePassLib.Cryptography.KeyDerivation { public sealed partial class Argon2Kdf : KdfEngine { private static readonly PwUuid g_uuid = new PwUuid(new byte[] { 0xEF, 0x63, 0x6D, 0xDF, 0x8C, 0x29, 0x44, 0x4B, 0x91, 0xF7, 0xA9, 0xA4, 0x03, 0xE3, 0x0A, 0x0C }); public const string ParamSalt = "S"; // Byte[] public const string ParamParallelism = "P"; // UInt32 public const string ParamMemory = "M"; // UInt64 public const string ParamIterations = "I"; // UInt64 public const string ParamVersion = "V"; // UInt32 public const string ParamSecretKey = "K"; // Byte[] public const string ParamAssocData = "A"; // Byte[] private const uint MinVersion = 0x10; private const uint MaxVersion = 0x13; private const int MinSalt = 8; private const int MaxSalt = int.MaxValue; // .NET limit; 2^32 - 1 in spec internal const ulong MinIterations = 1; internal const ulong MaxIterations = uint.MaxValue; internal const ulong MinMemory = 1024 * 8; // For parallelism = 1 // internal const ulong MaxMemory = (ulong)uint.MaxValue * 1024UL; // Spec internal const ulong MaxMemory = int.MaxValue; // .NET limit internal const uint MinParallelism = 1; internal const uint MaxParallelism = (1 << 24) - 1; internal const ulong DefaultIterations = 2; internal const ulong DefaultMemory = 1024 * 1024; // 1 MB internal const uint DefaultParallelism = 2; public override PwUuid Uuid { get { return g_uuid; } } public override string Name { get { return "Argon2"; } } public Argon2Kdf() { } public override KdfParameters GetDefaultParameters() { KdfParameters p = base.GetDefaultParameters(); p.SetUInt32(ParamVersion, MaxVersion); p.SetUInt64(ParamIterations, DefaultIterations); p.SetUInt64(ParamMemory, DefaultMemory); p.SetUInt32(ParamParallelism, DefaultParallelism); return p; } public override void Randomize(KdfParameters p) { if(p == null) { Debug.Assert(false); return; } Debug.Assert(g_uuid.Equals(p.KdfUuid)); byte[] pb = CryptoRandom.Instance.GetRandomBytes(32); p.SetByteArray(ParamSalt, pb); } public override byte[] Transform(byte[] pbMsg, KdfParameters p) { if(pbMsg == null) throw new ArgumentNullException("pbMsg"); if(p == null) throw new ArgumentNullException("p"); byte[] pbSalt = p.GetByteArray(ParamSalt); if(pbSalt == null) throw new ArgumentNullException("p.Salt"); if((pbSalt.Length < MinSalt) || (pbSalt.Length > MaxSalt)) throw new ArgumentOutOfRangeException("p.Salt"); uint uPar = p.GetUInt32(ParamParallelism, 0); if((uPar < MinParallelism) || (uPar > MaxParallelism)) throw new ArgumentOutOfRangeException("p.Parallelism"); ulong uMem = p.GetUInt64(ParamMemory, 0); if((uMem < MinMemory) || (uMem > MaxMemory)) throw new ArgumentOutOfRangeException("p.Memory"); ulong uIt = p.GetUInt64(ParamIterations, 0); if((uIt < MinIterations) || (uIt > MaxIterations)) throw new ArgumentOutOfRangeException("p.Iterations"); uint v = p.GetUInt32(ParamVersion, 0); if((v < MinVersion) || (v > MaxVersion)) throw new ArgumentOutOfRangeException("p.Version"); byte[] pbSecretKey = p.GetByteArray(ParamSecretKey); byte[] pbAssocData = p.GetByteArray(ParamAssocData); byte[] pbRet = Argon2d(pbMsg, pbSalt, uPar, uMem, uIt, 32, v, pbSecretKey, pbAssocData); if(uMem > (100UL * 1024UL * 1024UL)) GC.Collect(); return pbRet; } public override KdfParameters GetBestParameters(uint uMilliseconds) { KdfParameters p = GetDefaultParameters(); Randomize(p); MaximizeParamUInt64(p, ParamIterations, MinIterations, MaxIterations, uMilliseconds, true); return p; } } } KeePassLib/Cryptography/CryptoRandom.cs0000664000000000000000000002447013222430400017200 0ustar rootroot/* KeePass Password Safe - The Open-Source Password Manager Copyright (C) 2003-2018 Dominik Reichl This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ using System; using System.Collections; using System.Collections.Generic; using System.Diagnostics; using System.Globalization; using System.IO; #if !KeePassUAP using System.Drawing; using System.Security.Cryptography; using System.Windows.Forms; #endif using KeePassLib.Native; using KeePassLib.Utility; namespace KeePassLib.Cryptography { /// /// Cryptographically secure pseudo-random number generator. /// The returned values are unpredictable and cannot be reproduced. /// CryptoRandom is a singleton class. /// public sealed class CryptoRandom { private byte[] m_pbEntropyPool = new byte[64]; private ulong m_uCounter; private RNGCryptoServiceProvider m_rng = new RNGCryptoServiceProvider(); private ulong m_uGeneratedBytesCount = 0; private static readonly object g_oSyncRoot = new object(); private readonly object m_oSyncRoot = new object(); private static CryptoRandom g_pInstance = null; public static CryptoRandom Instance { get { CryptoRandom cr; lock(g_oSyncRoot) { cr = g_pInstance; if(cr == null) { cr = new CryptoRandom(); g_pInstance = cr; } } return cr; } } /// /// Get the number of random bytes that this instance generated so far. /// Note that this number can be higher than the number of random bytes /// actually requested using the GetRandomBytes method. /// public ulong GeneratedBytesCount { get { ulong u; lock(m_oSyncRoot) { u = m_uGeneratedBytesCount; } return u; } } /// /// Event that is triggered whenever the internal GenerateRandom256 /// method is called to generate random bytes. /// public event EventHandler GenerateRandom256Pre; private CryptoRandom() { // Random rWeak = new Random(); // Based on tick count // byte[] pb = new byte[8]; // rWeak.NextBytes(pb); // m_uCounter = MemUtil.BytesToUInt64(pb); m_uCounter = (ulong)DateTime.UtcNow.ToBinary(); AddEntropy(GetSystemData()); AddEntropy(GetCspData()); } /// /// Update the internal seed of the random number generator based /// on entropy data. /// This method is thread-safe. /// /// Entropy bytes. public void AddEntropy(byte[] pbEntropy) { if(pbEntropy == null) { Debug.Assert(false); return; } if(pbEntropy.Length == 0) { Debug.Assert(false); return; } byte[] pbNewData = pbEntropy; if(pbEntropy.Length > 64) { #if KeePassLibSD using(SHA256Managed shaNew = new SHA256Managed()) #else using(SHA512Managed shaNew = new SHA512Managed()) #endif { pbNewData = shaNew.ComputeHash(pbEntropy); } } lock(m_oSyncRoot) { int cbPool = m_pbEntropyPool.Length; int cbNew = pbNewData.Length; byte[] pbCmp = new byte[cbPool + cbNew]; Array.Copy(m_pbEntropyPool, pbCmp, cbPool); Array.Copy(pbNewData, 0, pbCmp, cbPool, cbNew); MemUtil.ZeroByteArray(m_pbEntropyPool); #if KeePassLibSD using(SHA256Managed shaPool = new SHA256Managed()) #else using(SHA512Managed shaPool = new SHA512Managed()) #endif { m_pbEntropyPool = shaPool.ComputeHash(pbCmp); } MemUtil.ZeroByteArray(pbCmp); } } private static byte[] GetSystemData() { MemoryStream ms = new MemoryStream(); byte[] pb; pb = MemUtil.Int32ToBytes(Environment.TickCount); MemUtil.Write(ms, pb); pb = MemUtil.Int64ToBytes(DateTime.UtcNow.ToBinary()); MemUtil.Write(ms, pb); #if !KeePassLibSD // In try-catch for systems without GUI; // https://sourceforge.net/p/keepass/discussion/329221/thread/20335b73/ try { Point pt = Cursor.Position; pb = MemUtil.Int32ToBytes(pt.X); MemUtil.Write(ms, pb); pb = MemUtil.Int32ToBytes(pt.Y); MemUtil.Write(ms, pb); } catch(Exception) { } #endif pb = MemUtil.UInt32ToBytes((uint)NativeLib.GetPlatformID()); MemUtil.Write(ms, pb); try { #if KeePassUAP string strOS = EnvironmentExt.OSVersion.VersionString; #else string strOS = Environment.OSVersion.VersionString; #endif AddStrHash(ms, strOS); pb = MemUtil.Int32ToBytes(Environment.ProcessorCount); MemUtil.Write(ms, pb); #if !KeePassUAP AddStrHash(ms, Environment.CommandLine); pb = MemUtil.Int64ToBytes(Environment.WorkingSet); MemUtil.Write(ms, pb); #endif } catch(Exception) { Debug.Assert(false); } try { foreach(DictionaryEntry de in Environment.GetEnvironmentVariables()) { AddStrHash(ms, (de.Key as string)); AddStrHash(ms, (de.Value as string)); } } catch(Exception) { Debug.Assert(false); } #if KeePassUAP pb = DiagnosticsExt.GetProcessEntropy(); MemUtil.Write(ms, pb); #elif !KeePassLibSD Process p = null; try { p = Process.GetCurrentProcess(); pb = MemUtil.Int64ToBytes(p.Handle.ToInt64()); MemUtil.Write(ms, pb); pb = MemUtil.Int32ToBytes(p.HandleCount); MemUtil.Write(ms, pb); pb = MemUtil.Int32ToBytes(p.Id); MemUtil.Write(ms, pb); pb = MemUtil.Int64ToBytes(p.NonpagedSystemMemorySize64); MemUtil.Write(ms, pb); pb = MemUtil.Int64ToBytes(p.PagedMemorySize64); MemUtil.Write(ms, pb); pb = MemUtil.Int64ToBytes(p.PagedSystemMemorySize64); MemUtil.Write(ms, pb); pb = MemUtil.Int64ToBytes(p.PeakPagedMemorySize64); MemUtil.Write(ms, pb); pb = MemUtil.Int64ToBytes(p.PeakVirtualMemorySize64); MemUtil.Write(ms, pb); pb = MemUtil.Int64ToBytes(p.PeakWorkingSet64); MemUtil.Write(ms, pb); pb = MemUtil.Int64ToBytes(p.PrivateMemorySize64); MemUtil.Write(ms, pb); pb = MemUtil.Int64ToBytes(p.StartTime.ToBinary()); MemUtil.Write(ms, pb); pb = MemUtil.Int64ToBytes(p.VirtualMemorySize64); MemUtil.Write(ms, pb); pb = MemUtil.Int64ToBytes(p.WorkingSet64); MemUtil.Write(ms, pb); // Not supported in Mono 1.2.6: // pb = MemUtil.UInt32ToBytes((uint)p.SessionId); // MemUtil.Write(ms, pb); } catch(Exception) { Debug.Assert(NativeLib.IsUnix()); } finally { try { if(p != null) p.Dispose(); } catch(Exception) { Debug.Assert(false); } } #endif try { CultureInfo ci = CultureInfo.CurrentCulture; if(ci != null) { pb = MemUtil.Int32ToBytes(ci.GetHashCode()); MemUtil.Write(ms, pb); } else { Debug.Assert(false); } } catch(Exception) { Debug.Assert(false); } pb = Guid.NewGuid().ToByteArray(); MemUtil.Write(ms, pb); byte[] pbAll = ms.ToArray(); ms.Close(); return pbAll; } private static void AddStrHash(Stream s, string str) { if(s == null) { Debug.Assert(false); return; } if(string.IsNullOrEmpty(str)) return; byte[] pbUtf8 = StrUtil.Utf8.GetBytes(str); byte[] pbHash = CryptoUtil.HashSha256(pbUtf8); MemUtil.Write(s, pbHash); } private byte[] GetCspData() { byte[] pbCspRandom = new byte[32]; m_rng.GetBytes(pbCspRandom); return pbCspRandom; } private byte[] GenerateRandom256() { if(this.GenerateRandom256Pre != null) this.GenerateRandom256Pre(this, EventArgs.Empty); byte[] pbCmp; lock(m_oSyncRoot) { m_uCounter += 0x74D8B29E4D38E161UL; // Prime number byte[] pbCounter = MemUtil.UInt64ToBytes(m_uCounter); byte[] pbCspRandom = GetCspData(); int cbPool = m_pbEntropyPool.Length; int cbCtr = pbCounter.Length; int cbCsp = pbCspRandom.Length; pbCmp = new byte[cbPool + cbCtr + cbCsp]; Array.Copy(m_pbEntropyPool, pbCmp, cbPool); Array.Copy(pbCounter, 0, pbCmp, cbPool, cbCtr); Array.Copy(pbCspRandom, 0, pbCmp, cbPool + cbCtr, cbCsp); MemUtil.ZeroByteArray(pbCspRandom); m_uGeneratedBytesCount += 32; } byte[] pbRet = CryptoUtil.HashSha256(pbCmp); MemUtil.ZeroByteArray(pbCmp); return pbRet; } /// /// Get a number of cryptographically strong random bytes. /// This method is thread-safe. /// /// Number of requested random bytes. /// A byte array consisting of /// random bytes. public byte[] GetRandomBytes(uint uRequestedBytes) { if(uRequestedBytes == 0) return MemUtil.EmptyByteArray; if(uRequestedBytes > (uint)int.MaxValue) { Debug.Assert(false); throw new ArgumentOutOfRangeException("uRequestedBytes"); } int cbRem = (int)uRequestedBytes; byte[] pbRes = new byte[cbRem]; int iPos = 0; while(cbRem != 0) { byte[] pbRandom256 = GenerateRandom256(); Debug.Assert(pbRandom256.Length == 32); int cbCopy = Math.Min(cbRem, pbRandom256.Length); Array.Copy(pbRandom256, 0, pbRes, iPos, cbCopy); MemUtil.ZeroByteArray(pbRandom256); iPos += cbCopy; cbRem -= cbCopy; } Debug.Assert(iPos == pbRes.Length); return pbRes; } private static int g_iWeakSeed = 0; public static Random NewWeakRandom() { long s64 = DateTime.UtcNow.ToBinary(); int s32 = (int)((s64 >> 32) ^ s64); lock(g_oSyncRoot) { unchecked { g_iWeakSeed += 0x78A8C4B7; // Prime number s32 ^= g_iWeakSeed; } } // Prevent overflow in the Random constructor of .NET 2.0 if(s32 == int.MinValue) s32 = int.MaxValue; return new Random(s32); } } } KeePassLib/Cryptography/Cipher/0000775000000000000000000000000013222430400015433 5ustar rootrootKeePassLib/Cryptography/Cipher/ChaCha20Cipher.cs0000664000000000000000000002042113222430376020401 0ustar rootroot/* KeePass Password Safe - The Open-Source Password Manager Copyright (C) 2003-2018 Dominik Reichl This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ using System; using System.Collections.Generic; using System.Diagnostics; using System.IO; using KeePassLib.Resources; using KeePassLib.Utility; namespace KeePassLib.Cryptography.Cipher { /// /// Implementation of the ChaCha20 cipher with a 96-bit nonce, /// as specified in RFC 7539. /// https://tools.ietf.org/html/rfc7539 /// public sealed class ChaCha20Cipher : CtrBlockCipher { private uint[] m_s = new uint[16]; // State private uint[] m_x = new uint[16]; // Working buffer private bool m_bLargeCounter; // See constructor documentation private static readonly uint[] g_sigma = new uint[4] { 0x61707865, 0x3320646E, 0x79622D32, 0x6B206574 }; private const string StrNameRfc = "ChaCha20 (RFC 7539)"; public override int BlockSize { get { return 64; } } public ChaCha20Cipher(byte[] pbKey32, byte[] pbIV12) : this(pbKey32, pbIV12, false) { } /// /// Constructor. /// /// Key (32 bytes). /// Nonce (12 bytes). /// If false, the RFC 7539 version /// of ChaCha20 is used. In this case, only 256 GB of data can be /// encrypted securely (because the block counter is a 32-bit variable); /// an attempt to encrypt more data throws an exception. /// If is true, the 32-bit /// counter overflows to another 32-bit variable (i.e. the counter /// effectively is a 64-bit variable), like in the original ChaCha20 /// specification by D. J. Bernstein (which has a 64-bit counter and a /// 64-bit nonce). To be compatible with this version, the 64-bit nonce /// must be stored in the last 8 bytes of /// and the first 4 bytes must be 0. /// If the IV was generated randomly, a 12-byte IV and a large counter /// can be used to securely encrypt more than 256 GB of data (but note /// this is incompatible with RFC 7539 and the original specification). public ChaCha20Cipher(byte[] pbKey32, byte[] pbIV12, bool bLargeCounter) : base() { if(pbKey32 == null) throw new ArgumentNullException("pbKey32"); if(pbKey32.Length != 32) throw new ArgumentOutOfRangeException("pbKey32"); if(pbIV12 == null) throw new ArgumentNullException("pbIV12"); if(pbIV12.Length != 12) throw new ArgumentOutOfRangeException("pbIV12"); m_bLargeCounter = bLargeCounter; // Key setup m_s[4] = MemUtil.BytesToUInt32(pbKey32, 0); m_s[5] = MemUtil.BytesToUInt32(pbKey32, 4); m_s[6] = MemUtil.BytesToUInt32(pbKey32, 8); m_s[7] = MemUtil.BytesToUInt32(pbKey32, 12); m_s[8] = MemUtil.BytesToUInt32(pbKey32, 16); m_s[9] = MemUtil.BytesToUInt32(pbKey32, 20); m_s[10] = MemUtil.BytesToUInt32(pbKey32, 24); m_s[11] = MemUtil.BytesToUInt32(pbKey32, 28); m_s[0] = g_sigma[0]; m_s[1] = g_sigma[1]; m_s[2] = g_sigma[2]; m_s[3] = g_sigma[3]; // IV setup m_s[12] = 0; // Counter m_s[13] = MemUtil.BytesToUInt32(pbIV12, 0); m_s[14] = MemUtil.BytesToUInt32(pbIV12, 4); m_s[15] = MemUtil.BytesToUInt32(pbIV12, 8); } protected override void Dispose(bool bDisposing) { if(bDisposing) { MemUtil.ZeroArray(m_s); MemUtil.ZeroArray(m_x); } base.Dispose(bDisposing); } protected override void NextBlock(byte[] pBlock) { if(pBlock == null) throw new ArgumentNullException("pBlock"); if(pBlock.Length != 64) throw new ArgumentOutOfRangeException("pBlock"); // x is a local alias for the working buffer; with this, // the compiler/runtime might remove some checks uint[] x = m_x; if(x == null) throw new InvalidOperationException(); if(x.Length < 16) throw new InvalidOperationException(); uint[] s = m_s; if(s == null) throw new InvalidOperationException(); if(s.Length < 16) throw new InvalidOperationException(); Array.Copy(s, x, 16); unchecked { // 10 * 8 quarter rounds = 20 rounds for(int i = 0; i < 10; ++i) { // Column quarter rounds x[ 0] += x[ 4]; x[12] = MemUtil.RotateLeft32(x[12] ^ x[ 0], 16); x[ 8] += x[12]; x[ 4] = MemUtil.RotateLeft32(x[ 4] ^ x[ 8], 12); x[ 0] += x[ 4]; x[12] = MemUtil.RotateLeft32(x[12] ^ x[ 0], 8); x[ 8] += x[12]; x[ 4] = MemUtil.RotateLeft32(x[ 4] ^ x[ 8], 7); x[ 1] += x[ 5]; x[13] = MemUtil.RotateLeft32(x[13] ^ x[ 1], 16); x[ 9] += x[13]; x[ 5] = MemUtil.RotateLeft32(x[ 5] ^ x[ 9], 12); x[ 1] += x[ 5]; x[13] = MemUtil.RotateLeft32(x[13] ^ x[ 1], 8); x[ 9] += x[13]; x[ 5] = MemUtil.RotateLeft32(x[ 5] ^ x[ 9], 7); x[ 2] += x[ 6]; x[14] = MemUtil.RotateLeft32(x[14] ^ x[ 2], 16); x[10] += x[14]; x[ 6] = MemUtil.RotateLeft32(x[ 6] ^ x[10], 12); x[ 2] += x[ 6]; x[14] = MemUtil.RotateLeft32(x[14] ^ x[ 2], 8); x[10] += x[14]; x[ 6] = MemUtil.RotateLeft32(x[ 6] ^ x[10], 7); x[ 3] += x[ 7]; x[15] = MemUtil.RotateLeft32(x[15] ^ x[ 3], 16); x[11] += x[15]; x[ 7] = MemUtil.RotateLeft32(x[ 7] ^ x[11], 12); x[ 3] += x[ 7]; x[15] = MemUtil.RotateLeft32(x[15] ^ x[ 3], 8); x[11] += x[15]; x[ 7] = MemUtil.RotateLeft32(x[ 7] ^ x[11], 7); // Diagonal quarter rounds x[ 0] += x[ 5]; x[15] = MemUtil.RotateLeft32(x[15] ^ x[ 0], 16); x[10] += x[15]; x[ 5] = MemUtil.RotateLeft32(x[ 5] ^ x[10], 12); x[ 0] += x[ 5]; x[15] = MemUtil.RotateLeft32(x[15] ^ x[ 0], 8); x[10] += x[15]; x[ 5] = MemUtil.RotateLeft32(x[ 5] ^ x[10], 7); x[ 1] += x[ 6]; x[12] = MemUtil.RotateLeft32(x[12] ^ x[ 1], 16); x[11] += x[12]; x[ 6] = MemUtil.RotateLeft32(x[ 6] ^ x[11], 12); x[ 1] += x[ 6]; x[12] = MemUtil.RotateLeft32(x[12] ^ x[ 1], 8); x[11] += x[12]; x[ 6] = MemUtil.RotateLeft32(x[ 6] ^ x[11], 7); x[ 2] += x[ 7]; x[13] = MemUtil.RotateLeft32(x[13] ^ x[ 2], 16); x[ 8] += x[13]; x[ 7] = MemUtil.RotateLeft32(x[ 7] ^ x[ 8], 12); x[ 2] += x[ 7]; x[13] = MemUtil.RotateLeft32(x[13] ^ x[ 2], 8); x[ 8] += x[13]; x[ 7] = MemUtil.RotateLeft32(x[ 7] ^ x[ 8], 7); x[ 3] += x[ 4]; x[14] = MemUtil.RotateLeft32(x[14] ^ x[ 3], 16); x[ 9] += x[14]; x[ 4] = MemUtil.RotateLeft32(x[ 4] ^ x[ 9], 12); x[ 3] += x[ 4]; x[14] = MemUtil.RotateLeft32(x[14] ^ x[ 3], 8); x[ 9] += x[14]; x[ 4] = MemUtil.RotateLeft32(x[ 4] ^ x[ 9], 7); } for(int i = 0; i < 16; ++i) x[i] += s[i]; for(int i = 0; i < 16; ++i) { int i4 = i << 2; uint xi = x[i]; pBlock[i4] = (byte)xi; pBlock[i4 + 1] = (byte)(xi >> 8); pBlock[i4 + 2] = (byte)(xi >> 16); pBlock[i4 + 3] = (byte)(xi >> 24); } ++s[12]; if(s[12] == 0) { if(!m_bLargeCounter) throw new InvalidOperationException( KLRes.EncDataTooLarge.Replace(@"{PARAM}", StrNameRfc)); ++s[13]; // Increment high half of large counter } } } public long Seek(long lOffset, SeekOrigin so) { if(so != SeekOrigin.Begin) throw new NotSupportedException(); if((lOffset < 0) || ((lOffset & 63) != 0) || ((lOffset >> 6) > (long)uint.MaxValue)) throw new ArgumentOutOfRangeException("lOffset"); m_s[12] = (uint)(lOffset >> 6); InvalidateBlock(); return lOffset; } } } KeePassLib/Cryptography/Cipher/StandardAesEngine.cs0000664000000000000000000001120213222430400021275 0ustar rootroot/* KeePass Password Safe - The Open-Source Password Manager Copyright (C) 2003-2018 Dominik Reichl This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ using System; using System.Collections.Generic; using System.Text; using System.IO; using System.Security; using System.Diagnostics; #if !KeePassUAP using System.Security.Cryptography; #endif using KeePassLib.Resources; namespace KeePassLib.Cryptography.Cipher { /// /// Standard AES cipher implementation. /// public sealed class StandardAesEngine : ICipherEngine { #if !KeePassUAP private const CipherMode m_rCipherMode = CipherMode.CBC; private const PaddingMode m_rCipherPadding = PaddingMode.PKCS7; #endif private static PwUuid g_uuidAes = null; /// /// UUID of the cipher engine. This ID uniquely identifies the /// AES engine. Must not be used by other ciphers. /// public static PwUuid AesUuid { get { PwUuid pu = g_uuidAes; if(pu == null) { pu = new PwUuid(new byte[] { 0x31, 0xC1, 0xF2, 0xE6, 0xBF, 0x71, 0x43, 0x50, 0xBE, 0x58, 0x05, 0x21, 0x6A, 0xFC, 0x5A, 0xFF }); g_uuidAes = pu; } return pu; } } /// /// Get the UUID of this cipher engine as PwUuid object. /// public PwUuid CipherUuid { get { return StandardAesEngine.AesUuid; } } /// /// Get a displayable name describing this cipher engine. /// public string DisplayName { get { return ("AES/Rijndael (" + KLRes.KeyBits.Replace(@"{PARAM}", "256") + ", FIPS 197)"); } } private static void ValidateArguments(Stream stream, bool bEncrypt, byte[] pbKey, byte[] pbIV) { Debug.Assert(stream != null); if(stream == null) throw new ArgumentNullException("stream"); Debug.Assert(pbKey != null); if(pbKey == null) throw new ArgumentNullException("pbKey"); Debug.Assert(pbKey.Length == 32); if(pbKey.Length != 32) throw new ArgumentException("Key must be 256 bits wide!"); Debug.Assert(pbIV != null); if(pbIV == null) throw new ArgumentNullException("pbIV"); Debug.Assert(pbIV.Length == 16); if(pbIV.Length != 16) throw new ArgumentException("Initialization vector must be 128 bits wide!"); if(bEncrypt) { Debug.Assert(stream.CanWrite); if(!stream.CanWrite) throw new ArgumentException("Stream must be writable!"); } else // Decrypt { Debug.Assert(stream.CanRead); if(!stream.CanRead) throw new ArgumentException("Encrypted stream must be readable!"); } } private static Stream CreateStream(Stream s, bool bEncrypt, byte[] pbKey, byte[] pbIV) { StandardAesEngine.ValidateArguments(s, bEncrypt, pbKey, pbIV); byte[] pbLocalIV = new byte[16]; Array.Copy(pbIV, pbLocalIV, 16); byte[] pbLocalKey = new byte[32]; Array.Copy(pbKey, pbLocalKey, 32); #if KeePassUAP return StandardAesEngineExt.CreateStream(s, bEncrypt, pbLocalKey, pbLocalIV); #else SymmetricAlgorithm a = CryptoUtil.CreateAes(); if(a.BlockSize != 128) // AES block size { Debug.Assert(false); a.BlockSize = 128; } a.IV = pbLocalIV; a.KeySize = 256; a.Key = pbLocalKey; a.Mode = m_rCipherMode; a.Padding = m_rCipherPadding; ICryptoTransform iTransform = (bEncrypt ? a.CreateEncryptor() : a.CreateDecryptor()); Debug.Assert(iTransform != null); if(iTransform == null) throw new SecurityException("Unable to create AES transform!"); return new CryptoStream(s, iTransform, bEncrypt ? CryptoStreamMode.Write : CryptoStreamMode.Read); #endif } public Stream EncryptStream(Stream sPlainText, byte[] pbKey, byte[] pbIV) { return StandardAesEngine.CreateStream(sPlainText, true, pbKey, pbIV); } public Stream DecryptStream(Stream sEncrypted, byte[] pbKey, byte[] pbIV) { return StandardAesEngine.CreateStream(sEncrypted, false, pbKey, pbIV); } } } KeePassLib/Cryptography/Cipher/ChaCha20Engine.cs0000664000000000000000000001034313222430376020376 0ustar rootroot/* KeePass Password Safe - The Open-Source Password Manager Copyright (C) 2003-2018 Dominik Reichl This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ using System; using System.Collections.Generic; using System.Diagnostics; using System.IO; using System.Text; using KeePassLib.Resources; namespace KeePassLib.Cryptography.Cipher { public sealed class ChaCha20Engine : ICipherEngine2 { private PwUuid m_uuid = new PwUuid(new byte[] { 0xD6, 0x03, 0x8A, 0x2B, 0x8B, 0x6F, 0x4C, 0xB5, 0xA5, 0x24, 0x33, 0x9A, 0x31, 0xDB, 0xB5, 0x9A }); public PwUuid CipherUuid { get { return m_uuid; } } public string DisplayName { get { return ("ChaCha20 (" + KLRes.KeyBits.Replace(@"{PARAM}", "256") + ", RFC 7539)"); } } public int KeyLength { get { return 32; } } public int IVLength { get { return 12; } // 96 bits } public Stream EncryptStream(Stream sPlainText, byte[] pbKey, byte[] pbIV) { return new ChaCha20Stream(sPlainText, true, pbKey, pbIV); } public Stream DecryptStream(Stream sEncrypted, byte[] pbKey, byte[] pbIV) { return new ChaCha20Stream(sEncrypted, false, pbKey, pbIV); } } internal sealed class ChaCha20Stream : Stream { private Stream m_sBase; private readonly bool m_bWriting; private ChaCha20Cipher m_c; private byte[] m_pbBuffer = null; public override bool CanRead { get { return !m_bWriting; } } public override bool CanSeek { get { return false; } } public override bool CanWrite { get { return m_bWriting; } } public override long Length { get { Debug.Assert(false); throw new NotSupportedException(); } } public override long Position { get { Debug.Assert(false); throw new NotSupportedException(); } set { Debug.Assert(false); throw new NotSupportedException(); } } public ChaCha20Stream(Stream sBase, bool bWriting, byte[] pbKey32, byte[] pbIV12) { if(sBase == null) throw new ArgumentNullException("sBase"); m_sBase = sBase; m_bWriting = bWriting; m_c = new ChaCha20Cipher(pbKey32, pbIV12); } protected override void Dispose(bool bDisposing) { if(bDisposing) { if(m_sBase != null) { m_c.Dispose(); m_c = null; m_sBase.Close(); m_sBase = null; } m_pbBuffer = null; } base.Dispose(bDisposing); } public override void Flush() { Debug.Assert(m_sBase != null); if(m_bWriting && (m_sBase != null)) m_sBase.Flush(); } public override long Seek(long lOffset, SeekOrigin soOrigin) { Debug.Assert(false); throw new NotImplementedException(); } public override void SetLength(long lValue) { Debug.Assert(false); throw new NotImplementedException(); } public override int Read(byte[] pbBuffer, int iOffset, int nCount) { if(m_bWriting) throw new InvalidOperationException(); int cbRead = m_sBase.Read(pbBuffer, iOffset, nCount); m_c.Decrypt(pbBuffer, iOffset, cbRead); return cbRead; } public override void Write(byte[] pbBuffer, int iOffset, int nCount) { if(nCount < 0) throw new ArgumentOutOfRangeException("nCount"); if(nCount == 0) return; if(!m_bWriting) throw new InvalidOperationException(); if((m_pbBuffer == null) || (m_pbBuffer.Length < nCount)) m_pbBuffer = new byte[nCount]; Array.Copy(pbBuffer, iOffset, m_pbBuffer, 0, nCount); m_c.Encrypt(m_pbBuffer, 0, nCount); m_sBase.Write(m_pbBuffer, 0, nCount); } } } KeePassLib/Cryptography/Cipher/ICipherEngine.cs0000664000000000000000000000510013222430376020443 0ustar rootroot/* KeePass Password Safe - The Open-Source Password Manager Copyright (C) 2003-2018 Dominik Reichl This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ using System; using System.IO; namespace KeePassLib.Cryptography.Cipher { /// /// Interface of an encryption/decryption class. /// public interface ICipherEngine { /// /// UUID of the engine. If you want to write an engine/plugin, /// please contact the KeePass team to obtain a new UUID. /// PwUuid CipherUuid { get; } /// /// String displayed in the list of available encryption/decryption /// engines in the GUI. /// string DisplayName { get; } /// /// Encrypt a stream. /// /// Stream to read the plain-text from. /// Key to use. /// Initialization vector. /// Stream, from which the encrypted data can be read. Stream EncryptStream(Stream sPlainText, byte[] pbKey, byte[] pbIV); /// /// Decrypt a stream. /// /// Stream to read the encrypted data from. /// Key to use. /// Initialization vector. /// Stream, from which the decrypted data can be read. Stream DecryptStream(Stream sEncrypted, byte[] pbKey, byte[] pbIV); } public interface ICipherEngine2 : ICipherEngine { /// /// Length of an encryption key in bytes. /// The base ICipherEngine assumes 32. /// int KeyLength { get; } /// /// Length of the initialization vector in bytes. /// The base ICipherEngine assumes 16. /// int IVLength { get; } } } KeePassLib/Cryptography/Cipher/CtrBlockCipher.cs0000664000000000000000000000533413222430376020641 0ustar rootroot/* KeePass Password Safe - The Open-Source Password Manager Copyright (C) 2003-2018 Dominik Reichl This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ using System; using System.Collections.Generic; using System.Diagnostics; using System.Text; using KeePassLib.Utility; namespace KeePassLib.Cryptography.Cipher { public abstract class CtrBlockCipher : IDisposable { private bool m_bDisposed = false; private byte[] m_pBlock; private int m_iBlockPos; public abstract int BlockSize { get; } public CtrBlockCipher() { int cb = this.BlockSize; if(cb <= 0) throw new InvalidOperationException("this.BlockSize"); m_pBlock = new byte[cb]; m_iBlockPos = cb; } public void Dispose() { Dispose(true); GC.SuppressFinalize(this); } protected virtual void Dispose(bool bDisposing) { if(bDisposing) { MemUtil.ZeroByteArray(m_pBlock); m_iBlockPos = m_pBlock.Length; m_bDisposed = true; } } protected void InvalidateBlock() { m_iBlockPos = m_pBlock.Length; } protected abstract void NextBlock(byte[] pBlock); public void Encrypt(byte[] m, int iOffset, int cb) { if(m_bDisposed) throw new ObjectDisposedException(null); if(m == null) throw new ArgumentNullException("m"); if(iOffset < 0) throw new ArgumentOutOfRangeException("iOffset"); if(cb < 0) throw new ArgumentOutOfRangeException("cb"); if(iOffset > (m.Length - cb)) throw new ArgumentOutOfRangeException("cb"); int cbBlock = m_pBlock.Length; while(cb > 0) { Debug.Assert(m_iBlockPos <= cbBlock); if(m_iBlockPos == cbBlock) { NextBlock(m_pBlock); m_iBlockPos = 0; } int cbCopy = Math.Min(cbBlock - m_iBlockPos, cb); Debug.Assert(cbCopy > 0); MemUtil.XorArray(m_pBlock, m_iBlockPos, m, iOffset, cbCopy); m_iBlockPos += cbCopy; iOffset += cbCopy; cb -= cbCopy; } } public void Decrypt(byte[] m, int iOffset, int cb) { Encrypt(m, iOffset, cb); } } } KeePassLib/Cryptography/Cipher/CipherPool.cs0000664000000000000000000001137013222430376020044 0ustar rootroot/* KeePass Password Safe - The Open-Source Password Manager Copyright (C) 2003-2018 Dominik Reichl This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ using System; using System.Collections.Generic; using System.Text; using System.IO; using System.Diagnostics; namespace KeePassLib.Cryptography.Cipher { /// /// Pool of encryption/decryption algorithms (ciphers). /// public sealed class CipherPool { private List m_vCiphers = new List(); private static CipherPool m_poolGlobal = null; /// /// Reference to the global cipher pool. /// public static CipherPool GlobalPool { get { CipherPool cp = m_poolGlobal; if(cp == null) { cp = new CipherPool(); cp.AddCipher(new StandardAesEngine()); cp.AddCipher(new ChaCha20Engine()); m_poolGlobal = cp; } return cp; } } /// /// Remove all cipher engines from the current pool. /// public void Clear() { m_vCiphers.Clear(); } /// /// Add a cipher engine to the pool. /// /// Cipher engine to add. Must not be null. public void AddCipher(ICipherEngine csEngine) { Debug.Assert(csEngine != null); if(csEngine == null) throw new ArgumentNullException("csEngine"); // Return if a cipher with that ID is registered already. for(int i = 0; i < m_vCiphers.Count; ++i) if(m_vCiphers[i].CipherUuid.Equals(csEngine.CipherUuid)) return; m_vCiphers.Add(csEngine); } /// /// Get a cipher identified by its UUID. /// /// UUID of the cipher to return. /// Reference to the requested cipher. If the cipher is /// not found, null is returned. public ICipherEngine GetCipher(PwUuid uuidCipher) { foreach(ICipherEngine iEngine in m_vCiphers) { if(iEngine.CipherUuid.Equals(uuidCipher)) return iEngine; } return null; } /// /// Get the index of a cipher. This index is temporary and should /// not be stored or used to identify a cipher. /// /// UUID of the cipher. /// Index of the requested cipher. Returns -1 if /// the specified cipher is not found. public int GetCipherIndex(PwUuid uuidCipher) { for(int i = 0; i < m_vCiphers.Count; ++i) { if(m_vCiphers[i].CipherUuid.Equals(uuidCipher)) return i; } Debug.Assert(false); return -1; } /// /// Get the index of a cipher. This index is temporary and should /// not be stored or used to identify a cipher. /// /// Name of the cipher. Note that /// multiple ciphers can have the same name. In this case, the /// first matching cipher is returned. /// Cipher with the specified name or -1 if /// no cipher with that name is found. public int GetCipherIndex(string strDisplayName) { for(int i = 0; i < m_vCiphers.Count; ++i) if(m_vCiphers[i].DisplayName == strDisplayName) return i; Debug.Assert(false); return -1; } /// /// Get the number of cipher engines in this pool. /// public int EngineCount { get { return m_vCiphers.Count; } } /// /// Get the cipher engine at the specified position. Throws /// an exception if the index is invalid. You can use this /// to iterate over all ciphers, but do not use it to /// identify ciphers. /// /// Index of the requested cipher engine. /// Reference to the cipher engine at the specified /// position. public ICipherEngine this[int nIndex] { get { if((nIndex < 0) || (nIndex >= m_vCiphers.Count)) throw new ArgumentOutOfRangeException("nIndex"); return m_vCiphers[nIndex]; } } } } KeePassLib/Cryptography/Cipher/Salsa20Cipher.cs0000664000000000000000000001273713222430376020350 0ustar rootroot/* KeePass Password Safe - The Open-Source Password Manager Copyright (C) 2003-2018 Dominik Reichl This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ // Implementation of the Salsa20 cipher, based on the eSTREAM // submission by D. J. Bernstein. using System; using System.Collections.Generic; using System.Diagnostics; using KeePassLib.Utility; namespace KeePassLib.Cryptography.Cipher { public sealed class Salsa20Cipher : CtrBlockCipher { private uint[] m_s = new uint[16]; // State private uint[] m_x = new uint[16]; // Working buffer private static readonly uint[] g_sigma = new uint[4] { 0x61707865, 0x3320646E, 0x79622D32, 0x6B206574 }; public override int BlockSize { get { return 64; } } public Salsa20Cipher(byte[] pbKey32, byte[] pbIV8) : base() { if(pbKey32 == null) throw new ArgumentNullException("pbKey32"); if(pbKey32.Length != 32) throw new ArgumentOutOfRangeException("pbKey32"); if(pbIV8 == null) throw new ArgumentNullException("pbIV8"); if(pbIV8.Length != 8) throw new ArgumentOutOfRangeException("pbIV8"); // Key setup m_s[1] = MemUtil.BytesToUInt32(pbKey32, 0); m_s[2] = MemUtil.BytesToUInt32(pbKey32, 4); m_s[3] = MemUtil.BytesToUInt32(pbKey32, 8); m_s[4] = MemUtil.BytesToUInt32(pbKey32, 12); m_s[11] = MemUtil.BytesToUInt32(pbKey32, 16); m_s[12] = MemUtil.BytesToUInt32(pbKey32, 20); m_s[13] = MemUtil.BytesToUInt32(pbKey32, 24); m_s[14] = MemUtil.BytesToUInt32(pbKey32, 28); m_s[0] = g_sigma[0]; m_s[5] = g_sigma[1]; m_s[10] = g_sigma[2]; m_s[15] = g_sigma[3]; // IV setup m_s[6] = MemUtil.BytesToUInt32(pbIV8, 0); m_s[7] = MemUtil.BytesToUInt32(pbIV8, 4); m_s[8] = 0; // Counter, low m_s[9] = 0; // Counter, high } protected override void Dispose(bool bDisposing) { if(bDisposing) { MemUtil.ZeroArray(m_s); MemUtil.ZeroArray(m_x); } base.Dispose(bDisposing); } protected override void NextBlock(byte[] pBlock) { if(pBlock == null) throw new ArgumentNullException("pBlock"); if(pBlock.Length != 64) throw new ArgumentOutOfRangeException("pBlock"); // x is a local alias for the working buffer; with this, // the compiler/runtime might remove some checks uint[] x = m_x; if(x == null) throw new InvalidOperationException(); if(x.Length < 16) throw new InvalidOperationException(); uint[] s = m_s; if(s == null) throw new InvalidOperationException(); if(s.Length < 16) throw new InvalidOperationException(); Array.Copy(s, x, 16); unchecked { // 10 * 8 quarter rounds = 20 rounds for(int i = 0; i < 10; ++i) { x[ 4] ^= MemUtil.RotateLeft32(x[ 0] + x[12], 7); x[ 8] ^= MemUtil.RotateLeft32(x[ 4] + x[ 0], 9); x[12] ^= MemUtil.RotateLeft32(x[ 8] + x[ 4], 13); x[ 0] ^= MemUtil.RotateLeft32(x[12] + x[ 8], 18); x[ 9] ^= MemUtil.RotateLeft32(x[ 5] + x[ 1], 7); x[13] ^= MemUtil.RotateLeft32(x[ 9] + x[ 5], 9); x[ 1] ^= MemUtil.RotateLeft32(x[13] + x[ 9], 13); x[ 5] ^= MemUtil.RotateLeft32(x[ 1] + x[13], 18); x[14] ^= MemUtil.RotateLeft32(x[10] + x[ 6], 7); x[ 2] ^= MemUtil.RotateLeft32(x[14] + x[10], 9); x[ 6] ^= MemUtil.RotateLeft32(x[ 2] + x[14], 13); x[10] ^= MemUtil.RotateLeft32(x[ 6] + x[ 2], 18); x[ 3] ^= MemUtil.RotateLeft32(x[15] + x[11], 7); x[ 7] ^= MemUtil.RotateLeft32(x[ 3] + x[15], 9); x[11] ^= MemUtil.RotateLeft32(x[ 7] + x[ 3], 13); x[15] ^= MemUtil.RotateLeft32(x[11] + x[ 7], 18); x[ 1] ^= MemUtil.RotateLeft32(x[ 0] + x[ 3], 7); x[ 2] ^= MemUtil.RotateLeft32(x[ 1] + x[ 0], 9); x[ 3] ^= MemUtil.RotateLeft32(x[ 2] + x[ 1], 13); x[ 0] ^= MemUtil.RotateLeft32(x[ 3] + x[ 2], 18); x[ 6] ^= MemUtil.RotateLeft32(x[ 5] + x[ 4], 7); x[ 7] ^= MemUtil.RotateLeft32(x[ 6] + x[ 5], 9); x[ 4] ^= MemUtil.RotateLeft32(x[ 7] + x[ 6], 13); x[ 5] ^= MemUtil.RotateLeft32(x[ 4] + x[ 7], 18); x[11] ^= MemUtil.RotateLeft32(x[10] + x[ 9], 7); x[ 8] ^= MemUtil.RotateLeft32(x[11] + x[10], 9); x[ 9] ^= MemUtil.RotateLeft32(x[ 8] + x[11], 13); x[10] ^= MemUtil.RotateLeft32(x[ 9] + x[ 8], 18); x[12] ^= MemUtil.RotateLeft32(x[15] + x[14], 7); x[13] ^= MemUtil.RotateLeft32(x[12] + x[15], 9); x[14] ^= MemUtil.RotateLeft32(x[13] + x[12], 13); x[15] ^= MemUtil.RotateLeft32(x[14] + x[13], 18); } for(int i = 0; i < 16; ++i) x[i] += s[i]; for(int i = 0; i < 16; ++i) { int i4 = i << 2; uint xi = x[i]; pBlock[i4] = (byte)xi; pBlock[i4 + 1] = (byte)(xi >> 8); pBlock[i4 + 2] = (byte)(xi >> 16); pBlock[i4 + 3] = (byte)(xi >> 24); } ++s[8]; if(s[8] == 0) ++s[9]; } } } } KeePassLib/Cryptography/Hash/0000775000000000000000000000000013222430400015104 5ustar rootrootKeePassLib/Cryptography/Hash/Blake2b.cs0000664000000000000000000001521313222430400016677 0ustar rootroot/* KeePass Password Safe - The Open-Source Password Manager Copyright (C) 2003-2018 Dominik Reichl This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ // This implementation is based on the official reference C // implementation by Samuel Neves (CC0 1.0 Universal). using System; using System.Collections.Generic; using System.Diagnostics; using System.Text; #if !KeePassUAP using System.Security.Cryptography; #endif using KeePassLib.Utility; namespace KeePassLib.Cryptography.Hash { public sealed class Blake2b : HashAlgorithm { private const int NbRounds = 12; private const int NbBlockBytes = 128; private const int NbMaxOutBytes = 64; private static readonly ulong[] g_vIV = new ulong[8] { 0x6A09E667F3BCC908UL, 0xBB67AE8584CAA73BUL, 0x3C6EF372FE94F82BUL, 0xA54FF53A5F1D36F1UL, 0x510E527FADE682D1UL, 0x9B05688C2B3E6C1FUL, 0x1F83D9ABFB41BD6BUL, 0x5BE0CD19137E2179UL }; private static readonly int[] g_vSigma = new int[NbRounds * 16] { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 14, 10, 4, 8, 9, 15, 13, 6, 1, 12, 0, 2, 11, 7, 5, 3, 11, 8, 12, 0, 5, 2, 15, 13, 10, 14, 3, 6, 7, 1, 9, 4, 7, 9, 3, 1, 13, 12, 11, 14, 2, 6, 5, 10, 4, 0, 15, 8, 9, 0, 5, 7, 2, 4, 10, 15, 14, 1, 11, 12, 6, 8, 3, 13, 2, 12, 6, 10, 0, 11, 8, 3, 4, 13, 7, 5, 15, 14, 1, 9, 12, 5, 1, 15, 14, 13, 4, 10, 0, 7, 6, 3, 9, 2, 8, 11, 13, 11, 7, 14, 12, 1, 3, 9, 5, 0, 15, 4, 8, 6, 2, 10, 6, 15, 14, 9, 11, 3, 0, 8, 12, 2, 13, 7, 1, 4, 10, 5, 10, 2, 8, 4, 7, 6, 1, 5, 15, 11, 9, 14, 3, 12, 13, 0, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 14, 10, 4, 8, 9, 15, 13, 6, 1, 12, 0, 2, 11, 7, 5, 3 }; private readonly int m_cbHashLength; private ulong[] m_h = new ulong[8]; private ulong[] m_t = new ulong[2]; private ulong[] m_f = new ulong[2]; private byte[] m_buf = new byte[NbBlockBytes]; private int m_cbBuf = 0; private ulong[] m_m = new ulong[16]; private ulong[] m_v = new ulong[16]; public Blake2b() { m_cbHashLength = NbMaxOutBytes; this.HashSizeValue = NbMaxOutBytes * 8; // Bits Initialize(); } public Blake2b(int cbHashLength) { if((cbHashLength < 0) || (cbHashLength > NbMaxOutBytes)) throw new ArgumentOutOfRangeException("cbHashLength"); m_cbHashLength = cbHashLength; this.HashSizeValue = cbHashLength * 8; // Bits Initialize(); } public override void Initialize() { Debug.Assert(m_h.Length == g_vIV.Length); Array.Copy(g_vIV, m_h, m_h.Length); // Fan-out = 1, depth = 1 m_h[0] ^= 0x0000000001010000UL ^ (ulong)m_cbHashLength; Array.Clear(m_t, 0, m_t.Length); Array.Clear(m_f, 0, m_f.Length); Array.Clear(m_buf, 0, m_buf.Length); m_cbBuf = 0; Array.Clear(m_m, 0, m_m.Length); Array.Clear(m_v, 0, m_v.Length); } private static void G(ulong[] v, ulong[] m, int r16, int i, int a, int b, int c, int d) { int p = r16 + i; v[a] += v[b] + m[g_vSigma[p]]; v[d] = MemUtil.RotateRight64(v[d] ^ v[a], 32); v[c] += v[d]; v[b] = MemUtil.RotateRight64(v[b] ^ v[c], 24); v[a] += v[b] + m[g_vSigma[p + 1]]; v[d] = MemUtil.RotateRight64(v[d] ^ v[a], 16); v[c] += v[d]; v[b] = MemUtil.RotateRight64(v[b] ^ v[c], 63); } private void Compress(byte[] pb, int iOffset) { ulong[] v = m_v; ulong[] m = m_m; ulong[] h = m_h; for(int i = 0; i < 16; ++i) m[i] = MemUtil.BytesToUInt64(pb, iOffset + (i << 3)); Array.Copy(h, v, 8); v[8] = g_vIV[0]; v[9] = g_vIV[1]; v[10] = g_vIV[2]; v[11] = g_vIV[3]; v[12] = g_vIV[4] ^ m_t[0]; v[13] = g_vIV[5] ^ m_t[1]; v[14] = g_vIV[6] ^ m_f[0]; v[15] = g_vIV[7] ^ m_f[1]; for(int r = 0; r < NbRounds; ++r) { int r16 = r << 4; G(v, m, r16, 0, 0, 4, 8, 12); G(v, m, r16, 2, 1, 5, 9, 13); G(v, m, r16, 4, 2, 6, 10, 14); G(v, m, r16, 6, 3, 7, 11, 15); G(v, m, r16, 8, 0, 5, 10, 15); G(v, m, r16, 10, 1, 6, 11, 12); G(v, m, r16, 12, 2, 7, 8, 13); G(v, m, r16, 14, 3, 4, 9, 14); } for(int i = 0; i < 8; ++i) h[i] ^= v[i] ^ v[i + 8]; } private void IncrementCounter(ulong cb) { m_t[0] += cb; if(m_t[0] < cb) ++m_t[1]; } protected override void HashCore(byte[] array, int ibStart, int cbSize) { Debug.Assert(m_f[0] == 0); if((m_cbBuf + cbSize) > NbBlockBytes) // Not '>=' (buffer must not be empty) { int cbFill = NbBlockBytes - m_cbBuf; if(cbFill > 0) Array.Copy(array, ibStart, m_buf, m_cbBuf, cbFill); IncrementCounter((ulong)NbBlockBytes); Compress(m_buf, 0); m_cbBuf = 0; cbSize -= cbFill; ibStart += cbFill; while(cbSize > NbBlockBytes) // Not '>=' (buffer must not be empty) { IncrementCounter((ulong)NbBlockBytes); Compress(array, ibStart); cbSize -= NbBlockBytes; ibStart += NbBlockBytes; } } if(cbSize > 0) { Debug.Assert((m_cbBuf + cbSize) <= NbBlockBytes); Array.Copy(array, ibStart, m_buf, m_cbBuf, cbSize); m_cbBuf += cbSize; } } protected override byte[] HashFinal() { if(m_f[0] != 0) { Debug.Assert(false); throw new InvalidOperationException(); } Debug.Assert(((m_t[1] == 0) && (m_t[0] == 0)) || (m_cbBuf > 0)); // Buffer must not be empty for last block processing m_f[0] = ulong.MaxValue; // Indicate last block int cbFill = NbBlockBytes - m_cbBuf; if(cbFill > 0) Array.Clear(m_buf, m_cbBuf, cbFill); IncrementCounter((ulong)m_cbBuf); Compress(m_buf, 0); byte[] pbHash = new byte[NbMaxOutBytes]; for(int i = 0; i < m_h.Length; ++i) MemUtil.UInt64ToBytesEx(m_h[i], pbHash, i << 3); if(m_cbHashLength == NbMaxOutBytes) return pbHash; Debug.Assert(m_cbHashLength < NbMaxOutBytes); byte[] pbShort = new byte[m_cbHashLength]; if(m_cbHashLength > 0) Array.Copy(pbHash, pbShort, m_cbHashLength); MemUtil.ZeroByteArray(pbHash); return pbShort; } } } KeePassLib/Cryptography/CryptoRandomStream.cs0000664000000000000000000001602113222430400020345 0ustar rootroot/* KeePass Password Safe - The Open-Source Password Manager Copyright (C) 2003-2018 Dominik Reichl This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ using System; using System.Diagnostics; #if !KeePassUAP using System.Security.Cryptography; #endif using KeePassLib.Cryptography.Cipher; using KeePassLib.Utility; namespace KeePassLib.Cryptography { /// /// Algorithms supported by CryptoRandomStream. /// public enum CrsAlgorithm { /// /// Not supported. /// Null = 0, /// /// A variant of the ARCFour algorithm (RC4 incompatible). /// Insecure; for backward compatibility only. /// ArcFourVariant = 1, /// /// Salsa20 stream cipher algorithm. /// Salsa20 = 2, /// /// ChaCha20 stream cipher algorithm. /// ChaCha20 = 3, Count = 4 } /// /// A random stream class. The class is initialized using random /// bytes provided by the caller. The produced stream has random /// properties, but for the same seed always the same stream /// is produced, i.e. this class can be used as stream cipher. /// public sealed class CryptoRandomStream : IDisposable { private readonly CrsAlgorithm m_crsAlgorithm; private bool m_bDisposed = false; private byte[] m_pbState = null; private byte m_i = 0; private byte m_j = 0; private Salsa20Cipher m_salsa20 = null; private ChaCha20Cipher m_chacha20 = null; /// /// Construct a new cryptographically secure random stream object. /// /// Algorithm to use. /// Initialization key. Must not be null and /// must contain at least 1 byte. public CryptoRandomStream(CrsAlgorithm a, byte[] pbKey) { if(pbKey == null) { Debug.Assert(false); throw new ArgumentNullException("pbKey"); } int cbKey = pbKey.Length; if(cbKey <= 0) { Debug.Assert(false); // Need at least one byte throw new ArgumentOutOfRangeException("pbKey"); } m_crsAlgorithm = a; if(a == CrsAlgorithm.ChaCha20) { byte[] pbKey32 = new byte[32]; byte[] pbIV12 = new byte[12]; using(SHA512Managed h = new SHA512Managed()) { byte[] pbHash = h.ComputeHash(pbKey); Array.Copy(pbHash, pbKey32, 32); Array.Copy(pbHash, 32, pbIV12, 0, 12); MemUtil.ZeroByteArray(pbHash); } m_chacha20 = new ChaCha20Cipher(pbKey32, pbIV12, true); } else if(a == CrsAlgorithm.Salsa20) { byte[] pbKey32 = CryptoUtil.HashSha256(pbKey); byte[] pbIV8 = new byte[8] { 0xE8, 0x30, 0x09, 0x4B, 0x97, 0x20, 0x5D, 0x2A }; // Unique constant m_salsa20 = new Salsa20Cipher(pbKey32, pbIV8); } else if(a == CrsAlgorithm.ArcFourVariant) { // Fill the state linearly m_pbState = new byte[256]; for(int w = 0; w < 256; ++w) m_pbState[w] = (byte)w; unchecked { byte j = 0, t; int inxKey = 0; for(int w = 0; w < 256; ++w) // Key setup { j += (byte)(m_pbState[w] + pbKey[inxKey]); t = m_pbState[0]; // Swap entries m_pbState[0] = m_pbState[j]; m_pbState[j] = t; ++inxKey; if(inxKey >= cbKey) inxKey = 0; } } GetRandomBytes(512); // Increases security, see cryptanalysis } else // Unknown algorithm { Debug.Assert(false); throw new ArgumentOutOfRangeException("a"); } } public void Dispose() { Dispose(true); GC.SuppressFinalize(this); } private void Dispose(bool disposing) { if(disposing) { if(m_crsAlgorithm == CrsAlgorithm.ChaCha20) m_chacha20.Dispose(); else if(m_crsAlgorithm == CrsAlgorithm.Salsa20) m_salsa20.Dispose(); else if(m_crsAlgorithm == CrsAlgorithm.ArcFourVariant) { MemUtil.ZeroByteArray(m_pbState); m_i = 0; m_j = 0; } else { Debug.Assert(false); } m_bDisposed = true; } } /// /// Get random bytes. /// /// Number of random bytes to retrieve. /// Returns random bytes. public byte[] GetRandomBytes(uint uRequestedCount) { if(m_bDisposed) throw new ObjectDisposedException(null); if(uRequestedCount == 0) return MemUtil.EmptyByteArray; if(uRequestedCount > (uint)int.MaxValue) throw new ArgumentOutOfRangeException("uRequestedCount"); int cb = (int)uRequestedCount; byte[] pbRet = new byte[cb]; if(m_crsAlgorithm == CrsAlgorithm.ChaCha20) m_chacha20.Encrypt(pbRet, 0, cb); else if(m_crsAlgorithm == CrsAlgorithm.Salsa20) m_salsa20.Encrypt(pbRet, 0, cb); else if(m_crsAlgorithm == CrsAlgorithm.ArcFourVariant) { unchecked { for(int w = 0; w < cb; ++w) { ++m_i; m_j += m_pbState[m_i]; byte t = m_pbState[m_i]; // Swap entries m_pbState[m_i] = m_pbState[m_j]; m_pbState[m_j] = t; t = (byte)(m_pbState[m_i] + m_pbState[m_j]); pbRet[w] = m_pbState[t]; } } } else { Debug.Assert(false); } return pbRet; } public ulong GetRandomUInt64() { byte[] pb = GetRandomBytes(8); return MemUtil.BytesToUInt64(pb); } #if CRSBENCHMARK public static string Benchmark() { int nRounds = 2000000; string str = "ArcFour small: " + BenchTime(CrsAlgorithm.ArcFourVariant, nRounds, 16).ToString() + "\r\n"; str += "ArcFour big: " + BenchTime(CrsAlgorithm.ArcFourVariant, 32, 2 * 1024 * 1024).ToString() + "\r\n"; str += "Salsa20 small: " + BenchTime(CrsAlgorithm.Salsa20, nRounds, 16).ToString() + "\r\n"; str += "Salsa20 big: " + BenchTime(CrsAlgorithm.Salsa20, 32, 2 * 1024 * 1024).ToString(); return str; } private static int BenchTime(CrsAlgorithm cra, int nRounds, int nDataSize) { byte[] pbKey = new byte[4] { 0x00, 0x01, 0x02, 0x03 }; int nStart = Environment.TickCount; for(int i = 0; i < nRounds; ++i) { using(CryptoRandomStream c = new CryptoRandomStream(cra, pbKey)) { c.GetRandomBytes((uint)nDataSize); } } int nEnd = Environment.TickCount; return (nEnd - nStart); } #endif } } KeePassLib/Cryptography/SelfTest.cs0000664000000000000000000011463513222430400016313 0ustar rootroot/* KeePass Password Safe - The Open-Source Password Manager Copyright (C) 2003-2018 Dominik Reichl This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ using System; using System.Collections.Generic; using System.Diagnostics; using System.Globalization; using System.IO; using System.Security; using System.Text; #if KeePassUAP using Org.BouncyCastle.Crypto; using Org.BouncyCastle.Crypto.Engines; using Org.BouncyCastle.Crypto.Parameters; #else using System.Security.Cryptography; #endif using KeePassLib.Cryptography.Cipher; using KeePassLib.Cryptography.Hash; using KeePassLib.Cryptography.KeyDerivation; using KeePassLib.Keys; using KeePassLib.Native; using KeePassLib.Resources; using KeePassLib.Security; using KeePassLib.Utility; #if (KeePassUAP && KeePassLibSD) #error KeePassUAP and KeePassLibSD are mutually exclusive. #endif namespace KeePassLib.Cryptography { /// /// Class containing self-test methods. /// public static class SelfTest { /// /// Perform a self-test. /// public static void Perform() { Random r = CryptoRandom.NewWeakRandom(); TestFipsComplianceProblems(); // Must be the first test TestAes(); TestSalsa20(r); TestChaCha20(r); TestBlake2b(r); TestArgon2(); TestHmac(); TestKeyTransform(r); TestNativeKeyTransform(r); TestHmacOtp(); TestProtectedObjects(r); TestMemUtil(r); TestStrUtil(); TestUrlUtil(); Debug.Assert((int)PwIcon.World == 1); Debug.Assert((int)PwIcon.Warning == 2); Debug.Assert((int)PwIcon.BlackBerry == 68); #if KeePassUAP SelfTestEx.Perform(); #endif } internal static void TestFipsComplianceProblems() { #if !KeePassUAP try { using(RijndaelManaged r = new RijndaelManaged()) { } } catch(Exception exAes) { throw new SecurityException("AES/Rijndael: " + exAes.Message); } #endif try { using(SHA256Managed h = new SHA256Managed()) { } } catch(Exception exSha256) { throw new SecurityException("SHA-256: " + exSha256.Message); } } private static void TestAes() { // Test vector (official ECB test vector #356) byte[] pbIV = new byte[16]; byte[] pbTestKey = new byte[32]; byte[] pbTestData = new byte[16]; byte[] pbReferenceCT = new byte[16] { 0x75, 0xD1, 0x1B, 0x0E, 0x3A, 0x68, 0xC4, 0x22, 0x3D, 0x88, 0xDB, 0xF0, 0x17, 0x97, 0x7D, 0xD7 }; int i; for(i = 0; i < 16; ++i) pbIV[i] = 0; for(i = 0; i < 32; ++i) pbTestKey[i] = 0; for(i = 0; i < 16; ++i) pbTestData[i] = 0; pbTestData[0] = 0x04; #if KeePassUAP AesEngine r = new AesEngine(); r.Init(true, new KeyParameter(pbTestKey)); if(r.GetBlockSize() != pbTestData.Length) throw new SecurityException("AES (BC)"); r.ProcessBlock(pbTestData, 0, pbTestData, 0); #else SymmetricAlgorithm a = CryptoUtil.CreateAes(); if(a.BlockSize != 128) // AES block size { Debug.Assert(false); a.BlockSize = 128; } a.IV = pbIV; a.KeySize = 256; a.Key = pbTestKey; a.Mode = CipherMode.ECB; ICryptoTransform iCrypt = a.CreateEncryptor(); iCrypt.TransformBlock(pbTestData, 0, 16, pbTestData, 0); #endif if(!MemUtil.ArraysEqual(pbTestData, pbReferenceCT)) throw new SecurityException("AES"); } private static void TestSalsa20(Random r) { #if DEBUG // Test values from official set 6, vector 3 byte[] pbKey = new byte[32] { 0x0F, 0x62, 0xB5, 0x08, 0x5B, 0xAE, 0x01, 0x54, 0xA7, 0xFA, 0x4D, 0xA0, 0xF3, 0x46, 0x99, 0xEC, 0x3F, 0x92, 0xE5, 0x38, 0x8B, 0xDE, 0x31, 0x84, 0xD7, 0x2A, 0x7D, 0xD0, 0x23, 0x76, 0xC9, 0x1C }; byte[] pbIV = new byte[8] { 0x28, 0x8F, 0xF6, 0x5D, 0xC4, 0x2B, 0x92, 0xF9 }; byte[] pbExpected = new byte[16] { 0x5E, 0x5E, 0x71, 0xF9, 0x01, 0x99, 0x34, 0x03, 0x04, 0xAB, 0xB2, 0x2A, 0x37, 0xB6, 0x62, 0x5B }; byte[] pb = new byte[16]; Salsa20Cipher c = new Salsa20Cipher(pbKey, pbIV); c.Encrypt(pb, 0, pb.Length); if(!MemUtil.ArraysEqual(pb, pbExpected)) throw new SecurityException("Salsa20-1"); // Extended test byte[] pbExpected2 = new byte[16] { 0xAB, 0xF3, 0x9A, 0x21, 0x0E, 0xEE, 0x89, 0x59, 0x8B, 0x71, 0x33, 0x37, 0x70, 0x56, 0xC2, 0xFE }; byte[] pbExpected3 = new byte[16] { 0x1B, 0xA8, 0x9D, 0xBD, 0x3F, 0x98, 0x83, 0x97, 0x28, 0xF5, 0x67, 0x91, 0xD5, 0xB7, 0xCE, 0x23 }; int nPos = Salsa20ToPos(c, r, pb.Length, 65536); Array.Clear(pb, 0, pb.Length); c.Encrypt(pb, 0, pb.Length); if(!MemUtil.ArraysEqual(pb, pbExpected2)) throw new SecurityException("Salsa20-2"); nPos = Salsa20ToPos(c, r, nPos + pb.Length, 131008); Array.Clear(pb, 0, pb.Length); c.Encrypt(pb, 0, pb.Length); if(!MemUtil.ArraysEqual(pb, pbExpected3)) throw new SecurityException("Salsa20-3"); Dictionary d = new Dictionary(); const int nRounds = 100; for(int i = 0; i < nRounds; ++i) { byte[] z = new byte[32]; c = new Salsa20Cipher(z, MemUtil.Int64ToBytes(i)); c.Encrypt(z, 0, z.Length); d[MemUtil.ByteArrayToHexString(z)] = true; } if(d.Count != nRounds) throw new SecurityException("Salsa20-4"); #endif } #if DEBUG private static int Salsa20ToPos(Salsa20Cipher c, Random r, int nPos, int nTargetPos) { byte[] pb = new byte[512]; while(nPos < nTargetPos) { int x = r.Next(1, 513); int nGen = Math.Min(nTargetPos - nPos, x); c.Encrypt(pb, 0, nGen); nPos += nGen; } return nTargetPos; } #endif private static void TestChaCha20(Random r) { // ====================================================== // Test vector from RFC 7539, section 2.3.2 byte[] pbKey = new byte[32]; for(int i = 0; i < 32; ++i) pbKey[i] = (byte)i; byte[] pbIV = new byte[12]; pbIV[3] = 0x09; pbIV[7] = 0x4A; byte[] pbExpc = new byte[64] { 0x10, 0xF1, 0xE7, 0xE4, 0xD1, 0x3B, 0x59, 0x15, 0x50, 0x0F, 0xDD, 0x1F, 0xA3, 0x20, 0x71, 0xC4, 0xC7, 0xD1, 0xF4, 0xC7, 0x33, 0xC0, 0x68, 0x03, 0x04, 0x22, 0xAA, 0x9A, 0xC3, 0xD4, 0x6C, 0x4E, 0xD2, 0x82, 0x64, 0x46, 0x07, 0x9F, 0xAA, 0x09, 0x14, 0xC2, 0xD7, 0x05, 0xD9, 0x8B, 0x02, 0xA2, 0xB5, 0x12, 0x9C, 0xD1, 0xDE, 0x16, 0x4E, 0xB9, 0xCB, 0xD0, 0x83, 0xE8, 0xA2, 0x50, 0x3C, 0x4E }; byte[] pb = new byte[64]; using(ChaCha20Cipher c = new ChaCha20Cipher(pbKey, pbIV)) { c.Seek(64, SeekOrigin.Begin); // Skip first block c.Encrypt(pb, 0, pb.Length); if(!MemUtil.ArraysEqual(pb, pbExpc)) throw new SecurityException("ChaCha20-1"); } #if DEBUG // ====================================================== // Test vector from RFC 7539, section 2.4.2 pbIV[3] = 0; pb = StrUtil.Utf8.GetBytes("Ladies and Gentlemen of the clas" + @"s of '99: If I could offer you only one tip for " + @"the future, sunscreen would be it."); pbExpc = new byte[] { 0x6E, 0x2E, 0x35, 0x9A, 0x25, 0x68, 0xF9, 0x80, 0x41, 0xBA, 0x07, 0x28, 0xDD, 0x0D, 0x69, 0x81, 0xE9, 0x7E, 0x7A, 0xEC, 0x1D, 0x43, 0x60, 0xC2, 0x0A, 0x27, 0xAF, 0xCC, 0xFD, 0x9F, 0xAE, 0x0B, 0xF9, 0x1B, 0x65, 0xC5, 0x52, 0x47, 0x33, 0xAB, 0x8F, 0x59, 0x3D, 0xAB, 0xCD, 0x62, 0xB3, 0x57, 0x16, 0x39, 0xD6, 0x24, 0xE6, 0x51, 0x52, 0xAB, 0x8F, 0x53, 0x0C, 0x35, 0x9F, 0x08, 0x61, 0xD8, 0x07, 0xCA, 0x0D, 0xBF, 0x50, 0x0D, 0x6A, 0x61, 0x56, 0xA3, 0x8E, 0x08, 0x8A, 0x22, 0xB6, 0x5E, 0x52, 0xBC, 0x51, 0x4D, 0x16, 0xCC, 0xF8, 0x06, 0x81, 0x8C, 0xE9, 0x1A, 0xB7, 0x79, 0x37, 0x36, 0x5A, 0xF9, 0x0B, 0xBF, 0x74, 0xA3, 0x5B, 0xE6, 0xB4, 0x0B, 0x8E, 0xED, 0xF2, 0x78, 0x5E, 0x42, 0x87, 0x4D }; byte[] pb64 = new byte[64]; using(ChaCha20Cipher c = new ChaCha20Cipher(pbKey, pbIV)) { c.Encrypt(pb64, 0, pb64.Length); // Skip first block c.Encrypt(pb, 0, pb.Length); if(!MemUtil.ArraysEqual(pb, pbExpc)) throw new SecurityException("ChaCha20-2"); } // ====================================================== // Test vector from RFC 7539, appendix A.2 #2 Array.Clear(pbKey, 0, pbKey.Length); pbKey[31] = 1; Array.Clear(pbIV, 0, pbIV.Length); pbIV[11] = 2; pb = StrUtil.Utf8.GetBytes("Any submission to the IETF inten" + "ded by the Contributor for publication as all or" + " part of an IETF Internet-Draft or RFC and any s" + "tatement made within the context of an IETF acti" + "vity is considered an \"IETF Contribution\". Such " + "statements include oral statements in IETF sessi" + "ons, as well as written and electronic communica" + "tions made at any time or place, which are addressed to"); pbExpc = MemUtil.HexStringToByteArray( "A3FBF07DF3FA2FDE4F376CA23E82737041605D9F4F4F57BD8CFF2C1D4B7955EC" + "2A97948BD3722915C8F3D337F7D370050E9E96D647B7C39F56E031CA5EB6250D" + "4042E02785ECECFA4B4BB5E8EAD0440E20B6E8DB09D881A7C6132F420E527950" + "42BDFA7773D8A9051447B3291CE1411C680465552AA6C405B7764D5E87BEA85A" + "D00F8449ED8F72D0D662AB052691CA66424BC86D2DF80EA41F43ABF937D3259D" + "C4B2D0DFB48A6C9139DDD7F76966E928E635553BA76C5C879D7B35D49EB2E62B" + "0871CDAC638939E25E8A1E0EF9D5280FA8CA328B351C3C765989CBCF3DAA8B6C" + "CC3AAF9F3979C92B3720FC88DC95ED84A1BE059C6499B9FDA236E7E818B04B0B" + "C39C1E876B193BFE5569753F88128CC08AAA9B63D1A16F80EF2554D7189C411F" + "5869CA52C5B83FA36FF216B9C1D30062BEBCFD2DC5BCE0911934FDA79A86F6E6" + "98CED759C3FF9B6477338F3DA4F9CD8514EA9982CCAFB341B2384DD902F3D1AB" + "7AC61DD29C6F21BA5B862F3730E37CFDC4FD806C22F221"); using(MemoryStream msEnc = new MemoryStream()) { using(ChaCha20Stream c = new ChaCha20Stream(msEnc, true, pbKey, pbIV)) { r.NextBytes(pb64); c.Write(pb64, 0, pb64.Length); // Skip first block int p = 0; while(p < pb.Length) { int cb = r.Next(1, pb.Length - p + 1); c.Write(pb, p, cb); p += cb; } Debug.Assert(p == pb.Length); } byte[] pbEnc0 = msEnc.ToArray(); byte[] pbEnc = MemUtil.Mid(pbEnc0, 64, pbEnc0.Length - 64); if(!MemUtil.ArraysEqual(pbEnc, pbExpc)) throw new SecurityException("ChaCha20-3"); using(MemoryStream msCT = new MemoryStream(pbEnc0, false)) { using(ChaCha20Stream cDec = new ChaCha20Stream(msCT, false, pbKey, pbIV)) { byte[] pbPT = MemUtil.Read(cDec, pbEnc0.Length); if(cDec.ReadByte() >= 0) throw new SecurityException("ChaCha20-4"); if(!MemUtil.ArraysEqual(MemUtil.Mid(pbPT, 0, 64), pb64)) throw new SecurityException("ChaCha20-5"); if(!MemUtil.ArraysEqual(MemUtil.Mid(pbPT, 64, pbEnc.Length), pb)) throw new SecurityException("ChaCha20-6"); } } } // ====================================================== // Test vector TC8 from RFC draft by J. Strombergson: // https://tools.ietf.org/html/draft-strombergson-chacha-test-vectors-01 pbKey = new byte[32] { 0xC4, 0x6E, 0xC1, 0xB1, 0x8C, 0xE8, 0xA8, 0x78, 0x72, 0x5A, 0x37, 0xE7, 0x80, 0xDF, 0xB7, 0x35, 0x1F, 0x68, 0xED, 0x2E, 0x19, 0x4C, 0x79, 0xFB, 0xC6, 0xAE, 0xBE, 0xE1, 0xA6, 0x67, 0x97, 0x5D }; // The first 4 bytes are set to zero and a large counter // is used; this makes the RFC 7539 version of ChaCha20 // compatible with the original specification by // D. J. Bernstein. pbIV = new byte[12] { 0x00, 0x00, 0x00, 0x00, 0x1A, 0xDA, 0x31, 0xD5, 0xCF, 0x68, 0x82, 0x21 }; pb = new byte[128]; pbExpc = new byte[128] { 0xF6, 0x3A, 0x89, 0xB7, 0x5C, 0x22, 0x71, 0xF9, 0x36, 0x88, 0x16, 0x54, 0x2B, 0xA5, 0x2F, 0x06, 0xED, 0x49, 0x24, 0x17, 0x92, 0x30, 0x2B, 0x00, 0xB5, 0xE8, 0xF8, 0x0A, 0xE9, 0xA4, 0x73, 0xAF, 0xC2, 0x5B, 0x21, 0x8F, 0x51, 0x9A, 0xF0, 0xFD, 0xD4, 0x06, 0x36, 0x2E, 0x8D, 0x69, 0xDE, 0x7F, 0x54, 0xC6, 0x04, 0xA6, 0xE0, 0x0F, 0x35, 0x3F, 0x11, 0x0F, 0x77, 0x1B, 0xDC, 0xA8, 0xAB, 0x92, 0xE5, 0xFB, 0xC3, 0x4E, 0x60, 0xA1, 0xD9, 0xA9, 0xDB, 0x17, 0x34, 0x5B, 0x0A, 0x40, 0x27, 0x36, 0x85, 0x3B, 0xF9, 0x10, 0xB0, 0x60, 0xBD, 0xF1, 0xF8, 0x97, 0xB6, 0x29, 0x0F, 0x01, 0xD1, 0x38, 0xAE, 0x2C, 0x4C, 0x90, 0x22, 0x5B, 0xA9, 0xEA, 0x14, 0xD5, 0x18, 0xF5, 0x59, 0x29, 0xDE, 0xA0, 0x98, 0xCA, 0x7A, 0x6C, 0xCF, 0xE6, 0x12, 0x27, 0x05, 0x3C, 0x84, 0xE4, 0x9A, 0x4A, 0x33, 0x32 }; using(ChaCha20Cipher c = new ChaCha20Cipher(pbKey, pbIV, true)) { c.Decrypt(pb, 0, pb.Length); if(!MemUtil.ArraysEqual(pb, pbExpc)) throw new SecurityException("ChaCha20-7"); } #endif } private static void TestBlake2b(Random r) { #if DEBUG Blake2b h = new Blake2b(); // ====================================================== // From https://tools.ietf.org/html/rfc7693 byte[] pbData = StrUtil.Utf8.GetBytes("abc"); byte[] pbExpc = new byte[64] { 0xBA, 0x80, 0xA5, 0x3F, 0x98, 0x1C, 0x4D, 0x0D, 0x6A, 0x27, 0x97, 0xB6, 0x9F, 0x12, 0xF6, 0xE9, 0x4C, 0x21, 0x2F, 0x14, 0x68, 0x5A, 0xC4, 0xB7, 0x4B, 0x12, 0xBB, 0x6F, 0xDB, 0xFF, 0xA2, 0xD1, 0x7D, 0x87, 0xC5, 0x39, 0x2A, 0xAB, 0x79, 0x2D, 0xC2, 0x52, 0xD5, 0xDE, 0x45, 0x33, 0xCC, 0x95, 0x18, 0xD3, 0x8A, 0xA8, 0xDB, 0xF1, 0x92, 0x5A, 0xB9, 0x23, 0x86, 0xED, 0xD4, 0x00, 0x99, 0x23 }; byte[] pbC = h.ComputeHash(pbData); if(!MemUtil.ArraysEqual(pbC, pbExpc)) throw new SecurityException("Blake2b-1"); // ====================================================== // Computed using the official b2sum tool pbExpc = new byte[64] { 0x78, 0x6A, 0x02, 0xF7, 0x42, 0x01, 0x59, 0x03, 0xC6, 0xC6, 0xFD, 0x85, 0x25, 0x52, 0xD2, 0x72, 0x91, 0x2F, 0x47, 0x40, 0xE1, 0x58, 0x47, 0x61, 0x8A, 0x86, 0xE2, 0x17, 0xF7, 0x1F, 0x54, 0x19, 0xD2, 0x5E, 0x10, 0x31, 0xAF, 0xEE, 0x58, 0x53, 0x13, 0x89, 0x64, 0x44, 0x93, 0x4E, 0xB0, 0x4B, 0x90, 0x3A, 0x68, 0x5B, 0x14, 0x48, 0xB7, 0x55, 0xD5, 0x6F, 0x70, 0x1A, 0xFE, 0x9B, 0xE2, 0xCE }; pbC = h.ComputeHash(MemUtil.EmptyByteArray); if(!MemUtil.ArraysEqual(pbC, pbExpc)) throw new SecurityException("Blake2b-2"); // ====================================================== // Computed using the official b2sum tool string strS = "ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789.:,;_-\r\n"; StringBuilder sb = new StringBuilder(); for(int i = 0; i < 1000; ++i) sb.Append(strS); pbData = StrUtil.Utf8.GetBytes(sb.ToString()); pbExpc = new byte[64] { 0x59, 0x69, 0x8D, 0x3B, 0x83, 0xF4, 0x02, 0x4E, 0xD8, 0x99, 0x26, 0x0E, 0xF4, 0xE5, 0x9F, 0x20, 0xDC, 0x31, 0xEE, 0x5B, 0x45, 0xEA, 0xBB, 0xFC, 0x1C, 0x0A, 0x8E, 0xED, 0xAA, 0x7A, 0xFF, 0x50, 0x82, 0xA5, 0x8F, 0xBC, 0x4A, 0x46, 0xFC, 0xC5, 0xEF, 0x44, 0x4E, 0x89, 0x80, 0x7D, 0x3F, 0x1C, 0xC1, 0x94, 0x45, 0xBB, 0xC0, 0x2C, 0x95, 0xAA, 0x3F, 0x08, 0x8A, 0x93, 0xF8, 0x75, 0x91, 0xB0 }; int p = 0; while(p < pbData.Length) { int cb = r.Next(1, pbData.Length - p + 1); h.TransformBlock(pbData, p, cb, pbData, p); p += cb; } Debug.Assert(p == pbData.Length); h.TransformFinalBlock(MemUtil.EmptyByteArray, 0, 0); if(!MemUtil.ArraysEqual(h.Hash, pbExpc)) throw new SecurityException("Blake2b-3"); h.Clear(); #endif } private static void TestArgon2() { #if DEBUG Argon2Kdf kdf = new Argon2Kdf(); // ====================================================== // From the official Argon2 1.3 reference code package // (test vector for Argon2d 1.3); also on // https://tools.ietf.org/html/draft-irtf-cfrg-argon2-00 KdfParameters p = kdf.GetDefaultParameters(); kdf.Randomize(p); Debug.Assert(p.GetUInt32(Argon2Kdf.ParamVersion, 0) == 0x13U); byte[] pbMsg = new byte[32]; for(int i = 0; i < pbMsg.Length; ++i) pbMsg[i] = 1; p.SetUInt64(Argon2Kdf.ParamMemory, 32 * 1024); p.SetUInt64(Argon2Kdf.ParamIterations, 3); p.SetUInt32(Argon2Kdf.ParamParallelism, 4); byte[] pbSalt = new byte[16]; for(int i = 0; i < pbSalt.Length; ++i) pbSalt[i] = 2; p.SetByteArray(Argon2Kdf.ParamSalt, pbSalt); byte[] pbKey = new byte[8]; for(int i = 0; i < pbKey.Length; ++i) pbKey[i] = 3; p.SetByteArray(Argon2Kdf.ParamSecretKey, pbKey); byte[] pbAssoc = new byte[12]; for(int i = 0; i < pbAssoc.Length; ++i) pbAssoc[i] = 4; p.SetByteArray(Argon2Kdf.ParamAssocData, pbAssoc); byte[] pbExpc = new byte[32] { 0x51, 0x2B, 0x39, 0x1B, 0x6F, 0x11, 0x62, 0x97, 0x53, 0x71, 0xD3, 0x09, 0x19, 0x73, 0x42, 0x94, 0xF8, 0x68, 0xE3, 0xBE, 0x39, 0x84, 0xF3, 0xC1, 0xA1, 0x3A, 0x4D, 0xB9, 0xFA, 0xBE, 0x4A, 0xCB }; byte[] pb = kdf.Transform(pbMsg, p); if(!MemUtil.ArraysEqual(pb, pbExpc)) throw new SecurityException("Argon2-1"); // ====================================================== // From the official Argon2 1.3 reference code package // (test vector for Argon2d 1.0) p.SetUInt32(Argon2Kdf.ParamVersion, 0x10); pbExpc = new byte[32] { 0x96, 0xA9, 0xD4, 0xE5, 0xA1, 0x73, 0x40, 0x92, 0xC8, 0x5E, 0x29, 0xF4, 0x10, 0xA4, 0x59, 0x14, 0xA5, 0xDD, 0x1F, 0x5C, 0xBF, 0x08, 0xB2, 0x67, 0x0D, 0xA6, 0x8A, 0x02, 0x85, 0xAB, 0xF3, 0x2B }; pb = kdf.Transform(pbMsg, p); if(!MemUtil.ArraysEqual(pb, pbExpc)) throw new SecurityException("Argon2-2"); // ====================================================== // From the official 'phc-winner-argon2-20151206.zip' // (test vector for Argon2d 1.0) p.SetUInt64(Argon2Kdf.ParamMemory, 16 * 1024); pbExpc = new byte[32] { 0x57, 0xB0, 0x61, 0x3B, 0xFD, 0xD4, 0x13, 0x1A, 0x0C, 0x34, 0x88, 0x34, 0xC6, 0x72, 0x9C, 0x2C, 0x72, 0x29, 0x92, 0x1E, 0x6B, 0xBA, 0x37, 0x66, 0x5D, 0x97, 0x8C, 0x4F, 0xE7, 0x17, 0x5E, 0xD2 }; pb = kdf.Transform(pbMsg, p); if(!MemUtil.ArraysEqual(pb, pbExpc)) throw new SecurityException("Argon2-3"); #if SELFTEST_ARGON2_LONG // ====================================================== // Computed using the official 'argon2' application // (test vectors for Argon2d 1.3) p = kdf.GetDefaultParameters(); pbMsg = StrUtil.Utf8.GetBytes("ABC1234"); p.SetUInt64(Argon2Kdf.ParamMemory, (1 << 11) * 1024); // 2 MB p.SetUInt64(Argon2Kdf.ParamIterations, 2); p.SetUInt32(Argon2Kdf.ParamParallelism, 2); pbSalt = StrUtil.Utf8.GetBytes("somesalt"); p.SetByteArray(Argon2Kdf.ParamSalt, pbSalt); pbExpc = new byte[32] { 0x29, 0xCB, 0xD3, 0xA1, 0x93, 0x76, 0xF7, 0xA2, 0xFC, 0xDF, 0xB0, 0x68, 0xAC, 0x0B, 0x99, 0xBA, 0x40, 0xAC, 0x09, 0x01, 0x73, 0x42, 0xCE, 0xF1, 0x29, 0xCC, 0xA1, 0x4F, 0xE1, 0xC1, 0xB7, 0xA3 }; pb = kdf.Transform(pbMsg, p); if(!MemUtil.ArraysEqual(pb, pbExpc)) throw new SecurityException("Argon2-4"); p.SetUInt64(Argon2Kdf.ParamMemory, (1 << 10) * 1024); // 1 MB p.SetUInt64(Argon2Kdf.ParamIterations, 3); pbExpc = new byte[32] { 0x7A, 0xBE, 0x1C, 0x1C, 0x8D, 0x7F, 0xD6, 0xDC, 0x7C, 0x94, 0x06, 0x3E, 0xD8, 0xBC, 0xD8, 0x1C, 0x2F, 0x87, 0x84, 0x99, 0x12, 0x83, 0xFE, 0x76, 0x00, 0x64, 0xC4, 0x58, 0xA4, 0xDA, 0x35, 0x70 }; pb = kdf.Transform(pbMsg, p); if(!MemUtil.ArraysEqual(pb, pbExpc)) throw new SecurityException("Argon2-5"); #if SELFTEST_ARGON2_LONGER p.SetUInt64(Argon2Kdf.ParamMemory, (1 << 20) * 1024); // 1 GB p.SetUInt64(Argon2Kdf.ParamIterations, 2); p.SetUInt32(Argon2Kdf.ParamParallelism, 3); pbExpc = new byte[32] { 0xE6, 0xE7, 0xCB, 0xF5, 0x5A, 0x06, 0x93, 0x05, 0x32, 0xBA, 0x86, 0xC6, 0x1F, 0x45, 0x17, 0x99, 0x65, 0x41, 0x77, 0xF9, 0x30, 0x55, 0x9A, 0xE8, 0x3D, 0x21, 0x48, 0xC6, 0x2D, 0x0C, 0x49, 0x11 }; pb = kdf.Transform(pbMsg, p); if(!MemUtil.ArraysEqual(pb, pbExpc)) throw new SecurityException("Argon2-6"); #endif // SELFTEST_ARGON2_LONGER #endif // SELFTEST_ARGON2_LONG #endif // DEBUG } private static void TestHmac() { #if DEBUG // Test vectors from RFC 4231 byte[] pbKey = new byte[20]; for(int i = 0; i < pbKey.Length; ++i) pbKey[i] = 0x0B; byte[] pbMsg = StrUtil.Utf8.GetBytes("Hi There"); byte[] pbExpc = new byte[32] { 0xB0, 0x34, 0x4C, 0x61, 0xD8, 0xDB, 0x38, 0x53, 0x5C, 0xA8, 0xAF, 0xCE, 0xAF, 0x0B, 0xF1, 0x2B, 0x88, 0x1D, 0xC2, 0x00, 0xC9, 0x83, 0x3D, 0xA7, 0x26, 0xE9, 0x37, 0x6C, 0x2E, 0x32, 0xCF, 0xF7 }; HmacEval(pbKey, pbMsg, pbExpc, "1"); pbKey = new byte[131]; for(int i = 0; i < pbKey.Length; ++i) pbKey[i] = 0xAA; pbMsg = StrUtil.Utf8.GetBytes( "This is a test using a larger than block-size key and " + "a larger than block-size data. The key needs to be " + "hashed before being used by the HMAC algorithm."); pbExpc = new byte[32] { 0x9B, 0x09, 0xFF, 0xA7, 0x1B, 0x94, 0x2F, 0xCB, 0x27, 0x63, 0x5F, 0xBC, 0xD5, 0xB0, 0xE9, 0x44, 0xBF, 0xDC, 0x63, 0x64, 0x4F, 0x07, 0x13, 0x93, 0x8A, 0x7F, 0x51, 0x53, 0x5C, 0x3A, 0x35, 0xE2 }; HmacEval(pbKey, pbMsg, pbExpc, "2"); #endif } #if DEBUG private static void HmacEval(byte[] pbKey, byte[] pbMsg, byte[] pbExpc, string strID) { using(HMACSHA256 h = new HMACSHA256(pbKey)) { h.TransformBlock(pbMsg, 0, pbMsg.Length, pbMsg, 0); h.TransformFinalBlock(MemUtil.EmptyByteArray, 0, 0); byte[] pbHash = h.Hash; if(!MemUtil.ArraysEqual(pbHash, pbExpc)) throw new SecurityException("HMAC-SHA-256-" + strID); // Reuse the object h.Initialize(); h.TransformBlock(pbMsg, 0, pbMsg.Length, pbMsg, 0); h.TransformFinalBlock(MemUtil.EmptyByteArray, 0, 0); pbHash = h.Hash; if(!MemUtil.ArraysEqual(pbHash, pbExpc)) throw new SecurityException("HMAC-SHA-256-" + strID + "-R"); } } #endif private static void TestKeyTransform(Random r) { #if DEBUG // Up to KeePass 2.34, the OtpKeyProv plugin used the public // CompositeKey.TransformKeyManaged method (and a finalizing // SHA-256 computation), which became an internal method of // the AesKdf class in KeePass 2.35, thus OtpKeyProv now // uses the AesKdf class; here we ensure that the results // are the same byte[] pbKey = new byte[32]; r.NextBytes(pbKey); byte[] pbSeed = new byte[32]; r.NextBytes(pbSeed); ulong uRounds = (ulong)r.Next(1, 0x7FFF); byte[] pbMan = new byte[pbKey.Length]; Array.Copy(pbKey, pbMan, pbKey.Length); if(!AesKdf.TransformKeyManaged(pbMan, pbSeed, uRounds)) throw new SecurityException("AES-KDF-1"); pbMan = CryptoUtil.HashSha256(pbMan); AesKdf kdf = new AesKdf(); KdfParameters p = kdf.GetDefaultParameters(); p.SetUInt64(AesKdf.ParamRounds, uRounds); p.SetByteArray(AesKdf.ParamSeed, pbSeed); byte[] pbKdf = kdf.Transform(pbKey, p); if(!MemUtil.ArraysEqual(pbMan, pbKdf)) throw new SecurityException("AES-KDF-2"); #endif } private static void TestNativeKeyTransform(Random r) { #if DEBUG byte[] pbOrgKey = CryptoRandom.Instance.GetRandomBytes(32); byte[] pbSeed = CryptoRandom.Instance.GetRandomBytes(32); ulong uRounds = (ulong)r.Next(1, 0x3FFF); byte[] pbManaged = new byte[32]; Array.Copy(pbOrgKey, pbManaged, 32); if(!AesKdf.TransformKeyManaged(pbManaged, pbSeed, uRounds)) throw new SecurityException("AES-KDF-1"); byte[] pbNative = new byte[32]; Array.Copy(pbOrgKey, pbNative, 32); if(!NativeLib.TransformKey256(pbNative, pbSeed, uRounds)) return; // Native library not available ("success") if(!MemUtil.ArraysEqual(pbManaged, pbNative)) throw new SecurityException("AES-KDF-2"); #endif } private static void TestMemUtil(Random r) { #if DEBUG byte[] pb = CryptoRandom.Instance.GetRandomBytes((uint)r.Next( 0, 0x2FFFF)); byte[] pbCompressed = MemUtil.Compress(pb); if(!MemUtil.ArraysEqual(MemUtil.Decompress(pbCompressed), pb)) throw new InvalidOperationException("GZip"); Encoding enc = StrUtil.Utf8; pb = enc.GetBytes("012345678901234567890a"); byte[] pbN = enc.GetBytes("9012"); if(MemUtil.IndexOf(pb, pbN) != 9) throw new InvalidOperationException("MemUtil-1"); pbN = enc.GetBytes("01234567890123"); if(MemUtil.IndexOf(pb, pbN) != 0) throw new InvalidOperationException("MemUtil-2"); pbN = enc.GetBytes("a"); if(MemUtil.IndexOf(pb, pbN) != 21) throw new InvalidOperationException("MemUtil-3"); pbN = enc.GetBytes("0a"); if(MemUtil.IndexOf(pb, pbN) != 20) throw new InvalidOperationException("MemUtil-4"); pbN = enc.GetBytes("1"); if(MemUtil.IndexOf(pb, pbN) != 1) throw new InvalidOperationException("MemUtil-5"); pbN = enc.GetBytes("b"); if(MemUtil.IndexOf(pb, pbN) >= 0) throw new InvalidOperationException("MemUtil-6"); pbN = enc.GetBytes("012b"); if(MemUtil.IndexOf(pb, pbN) >= 0) throw new InvalidOperationException("MemUtil-7"); byte[] pbRes = MemUtil.ParseBase32("MY======"); byte[] pbExp = Encoding.ASCII.GetBytes("f"); if(!MemUtil.ArraysEqual(pbRes, pbExp)) throw new Exception("Base32-1"); pbRes = MemUtil.ParseBase32("MZXQ===="); pbExp = Encoding.ASCII.GetBytes("fo"); if(!MemUtil.ArraysEqual(pbRes, pbExp)) throw new Exception("Base32-2"); pbRes = MemUtil.ParseBase32("MZXW6==="); pbExp = Encoding.ASCII.GetBytes("foo"); if(!MemUtil.ArraysEqual(pbRes, pbExp)) throw new Exception("Base32-3"); pbRes = MemUtil.ParseBase32("MZXW6YQ="); pbExp = Encoding.ASCII.GetBytes("foob"); if(!MemUtil.ArraysEqual(pbRes, pbExp)) throw new Exception("Base32-4"); pbRes = MemUtil.ParseBase32("MZXW6YTB"); pbExp = Encoding.ASCII.GetBytes("fooba"); if(!MemUtil.ArraysEqual(pbRes, pbExp)) throw new Exception("Base32-5"); pbRes = MemUtil.ParseBase32("MZXW6YTBOI======"); pbExp = Encoding.ASCII.GetBytes("foobar"); if(!MemUtil.ArraysEqual(pbRes, pbExp)) throw new Exception("Base32-6"); pbRes = MemUtil.ParseBase32("JNSXSIDQOJXXM2LEMVZCAYTBONSWIIDPNYQG63TFFV2GS3LFEBYGC43TO5XXEZDTFY======"); pbExp = Encoding.ASCII.GetBytes("Key provider based on one-time passwords."); if(!MemUtil.ArraysEqual(pbRes, pbExp)) throw new Exception("Base32-7"); int i = 0 - 0x10203040; pbRes = MemUtil.Int32ToBytes(i); if(MemUtil.ByteArrayToHexString(pbRes) != "C0CFDFEF") throw new Exception("MemUtil-8"); // Must be little-endian if(MemUtil.BytesToUInt32(pbRes) != (uint)i) throw new Exception("MemUtil-9"); if(MemUtil.BytesToInt32(pbRes) != i) throw new Exception("MemUtil-10"); ArrayHelperEx ah = MemUtil.ArrayHelperExOfChar; for(int j = 0; j < 30; ++j) { string strA = r.Next(30).ToString(); string strB = r.Next(30).ToString(); char[] vA = strA.ToCharArray(); char[] vB = strB.ToCharArray(); if(ah.Equals(vA, vB) != string.Equals(strA, strB)) throw new Exception("MemUtil-11"); if((vA.Length == vB.Length) && (Math.Sign(ah.Compare(vA, vB)) != Math.Sign(string.CompareOrdinal(strA, strB)))) throw new Exception("MemUtil-12"); } #endif } private static void TestHmacOtp() { #if (DEBUG && !KeePassLibSD) byte[] pbSecret = StrUtil.Utf8.GetBytes("12345678901234567890"); string[] vExp = new string[]{ "755224", "287082", "359152", "969429", "338314", "254676", "287922", "162583", "399871", "520489" }; for(int i = 0; i < vExp.Length; ++i) { if(HmacOtp.Generate(pbSecret, (ulong)i, 6, false, -1) != vExp[i]) throw new InvalidOperationException("HmacOtp"); } #endif } private static void TestProtectedObjects(Random r) { #if DEBUG Encoding enc = StrUtil.Utf8; byte[] pbData = enc.GetBytes("Test Test Test Test"); ProtectedBinary pb = new ProtectedBinary(true, pbData); if(!pb.IsProtected) throw new SecurityException("ProtectedBinary-1"); byte[] pbDec = pb.ReadData(); if(!MemUtil.ArraysEqual(pbData, pbDec)) throw new SecurityException("ProtectedBinary-2"); if(!pb.IsProtected) throw new SecurityException("ProtectedBinary-3"); byte[] pbData2 = enc.GetBytes("Test Test Test Test"); byte[] pbData3 = enc.GetBytes("Test Test Test Test Test"); ProtectedBinary pb2 = new ProtectedBinary(true, pbData2); ProtectedBinary pb3 = new ProtectedBinary(true, pbData3); if(!pb.Equals(pb2)) throw new SecurityException("ProtectedBinary-4"); if(pb.Equals(pb3)) throw new SecurityException("ProtectedBinary-5"); if(pb2.Equals(pb3)) throw new SecurityException("ProtectedBinary-6"); if(pb.GetHashCode() != pb2.GetHashCode()) throw new SecurityException("ProtectedBinary-7"); if(!((object)pb).Equals((object)pb2)) throw new SecurityException("ProtectedBinary-8"); if(((object)pb).Equals((object)pb3)) throw new SecurityException("ProtectedBinary-9"); if(((object)pb2).Equals((object)pb3)) throw new SecurityException("ProtectedBinary-10"); ProtectedString ps = new ProtectedString(); if(ps.Length != 0) throw new SecurityException("ProtectedString-1"); if(!ps.IsEmpty) throw new SecurityException("ProtectedString-2"); if(ps.ReadString().Length != 0) throw new SecurityException("ProtectedString-3"); ps = new ProtectedString(true, "Test"); ProtectedString ps2 = new ProtectedString(true, enc.GetBytes("Test")); if(ps.IsEmpty) throw new SecurityException("ProtectedString-4"); pbData = ps.ReadUtf8(); pbData2 = ps2.ReadUtf8(); if(!MemUtil.ArraysEqual(pbData, pbData2)) throw new SecurityException("ProtectedString-5"); if(pbData.Length != 4) throw new SecurityException("ProtectedString-6"); if(ps.ReadString() != ps2.ReadString()) throw new SecurityException("ProtectedString-7"); pbData = ps.ReadUtf8(); pbData2 = ps2.ReadUtf8(); if(!MemUtil.ArraysEqual(pbData, pbData2)) throw new SecurityException("ProtectedString-8"); if(!ps.IsProtected) throw new SecurityException("ProtectedString-9"); if(!ps2.IsProtected) throw new SecurityException("ProtectedString-10"); string str = string.Empty; ps = new ProtectedString(); for(int i = 0; i < 100; ++i) { bool bProt = ((r.Next() % 4) != 0); ps = ps.WithProtection(bProt); int x = r.Next(str.Length + 1); int c = r.Next(20); char ch = (char)r.Next(1, 256); string strIns = new string(ch, c); str = str.Insert(x, strIns); ps = ps.Insert(x, strIns); if(ps.IsProtected != bProt) throw new SecurityException("ProtectedString-11"); if(ps.ReadString() != str) throw new SecurityException("ProtectedString-12"); ps = ps.WithProtection(bProt); x = r.Next(str.Length); c = r.Next(str.Length - x + 1); str = str.Remove(x, c); ps = ps.Remove(x, c); if(ps.IsProtected != bProt) throw new SecurityException("ProtectedString-13"); if(ps.ReadString() != str) throw new SecurityException("ProtectedString-14"); } #endif } private static void TestStrUtil() { #if DEBUG string[] vSeps = new string[]{ "ax", "b", "c" }; const string str1 = "axbqrstcdeax"; List v1 = StrUtil.SplitWithSep(str1, vSeps, true); if(v1.Count != 9) throw new InvalidOperationException("StrUtil-1"); if(v1[0].Length > 0) throw new InvalidOperationException("StrUtil-2"); if(!v1[1].Equals("ax")) throw new InvalidOperationException("StrUtil-3"); if(v1[2].Length > 0) throw new InvalidOperationException("StrUtil-4"); if(!v1[3].Equals("b")) throw new InvalidOperationException("StrUtil-5"); if(!v1[4].Equals("qrst")) throw new InvalidOperationException("StrUtil-6"); if(!v1[5].Equals("c")) throw new InvalidOperationException("StrUtil-7"); if(!v1[6].Equals("de")) throw new InvalidOperationException("StrUtil-8"); if(!v1[7].Equals("ax")) throw new InvalidOperationException("StrUtil-9"); if(v1[8].Length > 0) throw new InvalidOperationException("StrUtil-10"); const string str2 = "12ab56"; List v2 = StrUtil.SplitWithSep(str2, new string[]{ "AB" }, false); if(v2.Count != 3) throw new InvalidOperationException("StrUtil-11"); if(!v2[0].Equals("12")) throw new InvalidOperationException("StrUtil-12"); if(!v2[1].Equals("AB")) throw new InvalidOperationException("StrUtil-13"); if(!v2[2].Equals("56")) throw new InvalidOperationException("StrUtil-14"); List v3 = StrUtil.SplitWithSep("pqrs", vSeps, false); if(v3.Count != 1) throw new InvalidOperationException("StrUtil-15"); if(!v3[0].Equals("pqrs")) throw new InvalidOperationException("StrUtil-16"); if(StrUtil.VersionToString(0x000F000E000D000CUL) != "15.14.13.12") throw new InvalidOperationException("StrUtil-V1"); if(StrUtil.VersionToString(0x00FF000E00010000UL) != "255.14.1") throw new InvalidOperationException("StrUtil-V2"); if(StrUtil.VersionToString(0x000F00FF00000000UL) != "15.255") throw new InvalidOperationException("StrUtil-V3"); if(StrUtil.VersionToString(0x00FF000000000000UL) != "255") throw new InvalidOperationException("StrUtil-V4"); if(StrUtil.VersionToString(0x00FF000000000000UL, 2) != "255.0") throw new InvalidOperationException("StrUtil-V5"); if(StrUtil.VersionToString(0x0000000000070000UL) != "0.0.7") throw new InvalidOperationException("StrUtil-V6"); if(StrUtil.VersionToString(0x0000000000000000UL) != "0") throw new InvalidOperationException("StrUtil-V7"); if(StrUtil.VersionToString(0x00000000FFFF0000UL, 4) != "0.0.65535.0") throw new InvalidOperationException("StrUtil-V8"); if(StrUtil.VersionToString(0x0000000000000000UL, 4) != "0.0.0.0") throw new InvalidOperationException("StrUtil-V9"); if(StrUtil.RtfEncodeChar('\u0000') != "\\u0?") throw new InvalidOperationException("StrUtil-Rtf1"); if(StrUtil.RtfEncodeChar('\u7FFF') != "\\u32767?") throw new InvalidOperationException("StrUtil-Rtf2"); if(StrUtil.RtfEncodeChar('\u8000') != "\\u-32768?") throw new InvalidOperationException("StrUtil-Rtf3"); if(StrUtil.RtfEncodeChar('\uFFFF') != "\\u-1?") throw new InvalidOperationException("StrUtil-Rtf4"); if(!StrUtil.StringToBool(Boolean.TrueString)) throw new InvalidOperationException("StrUtil-Bool1"); if(StrUtil.StringToBool(Boolean.FalseString)) throw new InvalidOperationException("StrUtil-Bool2"); if(StrUtil.Count("Abracadabra", "a") != 4) throw new InvalidOperationException("StrUtil-Count1"); if(StrUtil.Count("Bla", "U") != 0) throw new InvalidOperationException("StrUtil-Count2"); if(StrUtil.Count("AAAAA", "AA") != 4) throw new InvalidOperationException("StrUtil-Count3"); const string sU = "data:mytype;base64,"; if(!StrUtil.IsDataUri(sU)) throw new InvalidOperationException("StrUtil-DataUri1"); if(!StrUtil.IsDataUri(sU, "mytype")) throw new InvalidOperationException("StrUtil-DataUri2"); if(StrUtil.IsDataUri(sU, "notmytype")) throw new InvalidOperationException("StrUtil-DataUri3"); uint u = 0x7FFFFFFFU; if(u.ToString(NumberFormatInfo.InvariantInfo) != "2147483647") throw new InvalidOperationException("StrUtil-Inv1"); if(uint.MaxValue.ToString(NumberFormatInfo.InvariantInfo) != "4294967295") throw new InvalidOperationException("StrUtil-Inv2"); if(long.MinValue.ToString(NumberFormatInfo.InvariantInfo) != "-9223372036854775808") throw new InvalidOperationException("StrUtil-Inv3"); if(short.MinValue.ToString(NumberFormatInfo.InvariantInfo) != "-32768") throw new InvalidOperationException("StrUtil-Inv4"); if(!string.Equals("abcd", "aBcd", StrUtil.CaseIgnoreCmp)) throw new InvalidOperationException("StrUtil-Case1"); if(string.Equals(@"ab", StrUtil.CaseIgnoreCmp)) throw new InvalidOperationException("StrUtil-Case2"); #endif } private static void TestUrlUtil() { #if DEBUG #if !KeePassUAP Debug.Assert(Uri.UriSchemeHttp.Equals("http", StrUtil.CaseIgnoreCmp)); Debug.Assert(Uri.UriSchemeHttps.Equals("https", StrUtil.CaseIgnoreCmp)); #endif if(UrlUtil.GetHost(@"scheme://domain:port/path?query_string#fragment_id") != "domain") throw new InvalidOperationException("UrlUtil-H1"); if(UrlUtil.GetHost(@"https://example.org:443") != "example.org") throw new InvalidOperationException("UrlUtil-H2"); if(UrlUtil.GetHost(@"mailto:bob@example.com") != "example.com") throw new InvalidOperationException("UrlUtil-H3"); if(UrlUtil.GetHost(@"ftp://asmith@ftp.example.org") != "ftp.example.org") throw new InvalidOperationException("UrlUtil-H4"); if(UrlUtil.GetHost(@"scheme://username:password@domain:port/path?query_string#fragment_id") != "domain") throw new InvalidOperationException("UrlUtil-H5"); if(UrlUtil.GetHost(@"bob@example.com") != "example.com") throw new InvalidOperationException("UrlUtil-H6"); if(UrlUtil.GetHost(@"s://u:p@d.tld:p/p?q#f") != "d.tld") throw new InvalidOperationException("UrlUtil-H7"); if(NativeLib.IsUnix()) return; string strBase = "\\\\HOMESERVER\\Apps\\KeePass\\KeePass.exe"; string strDoc = "\\\\HOMESERVER\\Documents\\KeePass\\NewDatabase.kdbx"; string strRel = "..\\..\\Documents\\KeePass\\NewDatabase.kdbx"; string str = UrlUtil.MakeRelativePath(strBase, strDoc); if(!str.Equals(strRel)) throw new InvalidOperationException("UrlUtil-R1"); str = UrlUtil.MakeAbsolutePath(strBase, strRel); if(!str.Equals(strDoc)) throw new InvalidOperationException("UrlUtil-R2"); str = UrlUtil.GetQuotedAppPath(" \"Test\" \"%1\" "); if(str != "Test") throw new InvalidOperationException("UrlUtil-Q1"); str = UrlUtil.GetQuotedAppPath("C:\\Program Files\\Test.exe"); if(str != "C:\\Program Files\\Test.exe") throw new InvalidOperationException("UrlUtil-Q2"); str = UrlUtil.GetQuotedAppPath("Reg.exe \"Test\" \"Test 2\""); if(str != "Reg.exe \"Test\" \"Test 2\"") throw new InvalidOperationException("UrlUtil-Q3"); #endif } } } KeePassLib/Cryptography/PasswordGenerator/0000775000000000000000000000000013222430400017672 5ustar rootrootKeePassLib/Cryptography/PasswordGenerator/PwProfile.cs0000664000000000000000000001640413222430400022135 0ustar rootroot/* KeePass Password Safe - The Open-Source Password Manager Copyright (C) 2003-2018 Dominik Reichl This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ using System; using System.Collections.Generic; using System.Text; using System.Xml.Serialization; using System.ComponentModel; using System.Diagnostics; using KeePassLib.Interfaces; using KeePassLib.Security; using KeePassLib.Utility; namespace KeePassLib.Cryptography.PasswordGenerator { /// /// Type of the password generator. Different types like generators /// based on given patterns, based on character sets, etc. are /// available. /// public enum PasswordGeneratorType { /// /// Generator based on character spaces/sets, i.e. groups /// of characters like lower-case, upper-case or numeric characters. /// CharSet = 0, /// /// Password generation based on a pattern. The user has provided /// a pattern, which describes how the generated password has to /// look like. /// Pattern = 1, Custom = 2 } public sealed class PwProfile : IDeepCloneable { private string m_strName = string.Empty; [DefaultValue("")] public string Name { get { return m_strName; } set { m_strName = value; } } private PasswordGeneratorType m_type = PasswordGeneratorType.CharSet; public PasswordGeneratorType GeneratorType { get { return m_type; } set { m_type = value; } } private bool m_bUserEntropy = false; [DefaultValue(false)] public bool CollectUserEntropy { get { return m_bUserEntropy; } set { m_bUserEntropy = value; } } private uint m_uLength = 20; public uint Length { get { return m_uLength; } set { m_uLength = value; } } private PwCharSet m_pwCharSet = new PwCharSet(PwCharSet.UpperCase + PwCharSet.LowerCase + PwCharSet.Digits); [XmlIgnore] public PwCharSet CharSet { get { return m_pwCharSet; } set { if(value == null) throw new ArgumentNullException("value"); m_pwCharSet = value; } } private string m_strCharSetRanges = string.Empty; [DefaultValue("")] public string CharSetRanges { get { this.UpdateCharSet(true); return m_strCharSetRanges; } set { if(value == null) throw new ArgumentNullException("value"); m_strCharSetRanges = value; this.UpdateCharSet(false); } } private string m_strCharSetAdditional = string.Empty; [DefaultValue("")] public string CharSetAdditional { get { this.UpdateCharSet(true); return m_strCharSetAdditional; } set { if(value == null) throw new ArgumentNullException("value"); m_strCharSetAdditional = value; this.UpdateCharSet(false); } } private string m_strPattern = string.Empty; [DefaultValue("")] public string Pattern { get { return m_strPattern; } set { m_strPattern = value; } } private bool m_bPatternPermute = false; [DefaultValue(false)] public bool PatternPermutePassword { get { return m_bPatternPermute; } set { m_bPatternPermute = value; } } private bool m_bNoLookAlike = false; [DefaultValue(false)] public bool ExcludeLookAlike { get { return m_bNoLookAlike; } set { m_bNoLookAlike = value; } } private bool m_bNoRepeat = false; [DefaultValue(false)] public bool NoRepeatingCharacters { get { return m_bNoRepeat; } set { m_bNoRepeat = value; } } private string m_strExclude = string.Empty; [DefaultValue("")] public string ExcludeCharacters { get { return m_strExclude; } set { if(value == null) throw new ArgumentNullException("value"); m_strExclude = value; } } private string m_strCustomID = string.Empty; [DefaultValue("")] public string CustomAlgorithmUuid { get { return m_strCustomID; } set { if(value == null) throw new ArgumentNullException("value"); m_strCustomID = value; } } private string m_strCustomOpt = string.Empty; [DefaultValue("")] public string CustomAlgorithmOptions { get { return m_strCustomOpt; } set { if(value == null) throw new ArgumentNullException("value"); m_strCustomOpt = value; } } public PwProfile() { } public PwProfile CloneDeep() { PwProfile p = new PwProfile(); p.m_strName = m_strName; p.m_type = m_type; p.m_bUserEntropy = m_bUserEntropy; p.m_uLength = m_uLength; p.m_pwCharSet = new PwCharSet(m_pwCharSet.ToString()); p.m_strCharSetRanges = m_strCharSetRanges; p.m_strCharSetAdditional = m_strCharSetAdditional; p.m_strPattern = m_strPattern; p.m_bPatternPermute = m_bPatternPermute; p.m_bNoLookAlike = m_bNoLookAlike; p.m_bNoRepeat = m_bNoRepeat; p.m_strExclude = m_strExclude; p.m_strCustomID = m_strCustomID; p.m_strCustomOpt = m_strCustomOpt; return p; } private void UpdateCharSet(bool bSetXml) { if(bSetXml) { PwCharSet pcs = new PwCharSet(m_pwCharSet.ToString()); m_strCharSetRanges = pcs.PackAndRemoveCharRanges(); m_strCharSetAdditional = pcs.ToString(); } else { PwCharSet pcs = new PwCharSet(m_strCharSetAdditional); pcs.UnpackCharRanges(m_strCharSetRanges); m_pwCharSet = pcs; } } public static PwProfile DeriveFromPassword(ProtectedString psPassword) { PwProfile pp = new PwProfile(); Debug.Assert(psPassword != null); if(psPassword == null) return pp; byte[] pbUtf8 = psPassword.ReadUtf8(); char[] vChars = StrUtil.Utf8.GetChars(pbUtf8); pp.GeneratorType = PasswordGeneratorType.CharSet; pp.Length = (uint)vChars.Length; PwCharSet pcs = pp.CharSet; pcs.Clear(); foreach(char ch in vChars) { if((ch >= 'A') && (ch <= 'Z')) pcs.Add(PwCharSet.UpperCase); else if((ch >= 'a') && (ch <= 'z')) pcs.Add(PwCharSet.LowerCase); else if((ch >= '0') && (ch <= '9')) pcs.Add(PwCharSet.Digits); else if(PwCharSet.SpecialChars.IndexOf(ch) >= 0) pcs.Add(PwCharSet.SpecialChars); else if(ch == ' ') pcs.Add(' '); else if(ch == '-') pcs.Add('-'); else if(ch == '_') pcs.Add('_'); else if(PwCharSet.Brackets.IndexOf(ch) >= 0) pcs.Add(PwCharSet.Brackets); else if(PwCharSet.HighAnsiChars.IndexOf(ch) >= 0) pcs.Add(PwCharSet.HighAnsiChars); else pcs.Add(ch); } MemUtil.ZeroArray(vChars); MemUtil.ZeroByteArray(pbUtf8); return pp; } public bool HasSecurityReducingOption() { return (m_bNoLookAlike || m_bNoRepeat || (m_strExclude.Length > 0)); } } } KeePassLib/Cryptography/PasswordGenerator/PwCharSet.cs0000664000000000000000000002357613222430400022076 0ustar rootroot/* KeePass Password Safe - The Open-Source Password Manager Copyright (C) 2003-2018 Dominik Reichl This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ using System; using System.Collections.Generic; using System.Text; using System.Diagnostics; namespace KeePassLib.Cryptography.PasswordGenerator { public sealed class PwCharSet { public const string UpperCase = "ABCDEFGHIJKLMNOPQRSTUVWXYZ"; public const string LowerCase = "abcdefghijklmnopqrstuvwxyz"; public const string Digits = "0123456789"; public const string UpperConsonants = "BCDFGHJKLMNPQRSTVWXYZ"; public const string LowerConsonants = "bcdfghjklmnpqrstvwxyz"; public const string UpperVowels = "AEIOU"; public const string LowerVowels = "aeiou"; public const string Punctuation = @",.;:"; public const string Brackets = @"[]{}()<>"; public const string PrintableAsciiSpecial = "!\"#$%&'()*+,-./:;<=>?@[\\]^_`{|}~"; public const string UpperHex = "0123456789ABCDEF"; public const string LowerHex = "0123456789abcdef"; public const string Invalid = "\t\r\n"; public const string LookAlike = @"O0l1I|"; internal const string MenuAccels = PwCharSet.LowerCase + PwCharSet.Digits; private const int CharTabSize = (0x10000 / 8); private List m_vChars = new List(); private byte[] m_vTab = new byte[CharTabSize]; private static string m_strHighAnsi = null; public static string HighAnsiChars { get { if(m_strHighAnsi == null) { new PwCharSet(); } // Create string Debug.Assert(m_strHighAnsi != null); return m_strHighAnsi; } } private static string m_strSpecial = null; public static string SpecialChars { get { if(m_strSpecial == null) { new PwCharSet(); } // Create string Debug.Assert(m_strSpecial != null); return m_strSpecial; } } /// /// Create a new, empty character set collection object. /// public PwCharSet() { Initialize(true); } public PwCharSet(string strCharSet) { Initialize(true); Add(strCharSet); } private PwCharSet(bool bFullInitialize) { Initialize(bFullInitialize); } private void Initialize(bool bFullInitialize) { Clear(); if(!bFullInitialize) return; if(m_strHighAnsi == null) { StringBuilder sbHighAnsi = new StringBuilder(); // [U+0080, U+009F] are C1 control characters, // U+00A0 is non-breaking space for(char ch = '\u00A1'; ch <= '\u00AC'; ++ch) sbHighAnsi.Append(ch); // U+00AD is soft hyphen (format character) for(char ch = '\u00AE'; ch < '\u00FF'; ++ch) sbHighAnsi.Append(ch); sbHighAnsi.Append('\u00FF'); m_strHighAnsi = sbHighAnsi.ToString(); } if(m_strSpecial == null) { PwCharSet pcs = new PwCharSet(false); pcs.AddRange('!', '/'); pcs.AddRange(':', '@'); pcs.AddRange('[', '`'); pcs.Add(@"|~"); pcs.Remove(@"-_ "); pcs.Remove(PwCharSet.Brackets); m_strSpecial = pcs.ToString(); } } /// /// Number of characters in this set. /// public uint Size { get { return (uint)m_vChars.Count; } } /// /// Get a character of the set using an index. /// /// Index of the character to get. /// Character at the specified position. If the index is invalid, /// an ArgumentOutOfRangeException is thrown. public char this[uint uPos] { get { if(uPos >= (uint)m_vChars.Count) throw new ArgumentOutOfRangeException("uPos"); return m_vChars[(int)uPos]; } } /// /// Remove all characters from this set. /// public void Clear() { m_vChars.Clear(); Array.Clear(m_vTab, 0, m_vTab.Length); } public bool Contains(char ch) { return (((m_vTab[ch / 8] >> (ch % 8)) & 1) != char.MinValue); } public bool Contains(string strCharacters) { Debug.Assert(strCharacters != null); if(strCharacters == null) throw new ArgumentNullException("strCharacters"); foreach(char ch in strCharacters) { if(!Contains(ch)) return false; } return true; } /// /// Add characters to the set. /// /// Character to add. public void Add(char ch) { if(ch == char.MinValue) { Debug.Assert(false); return; } if(!Contains(ch)) { m_vChars.Add(ch); m_vTab[ch / 8] |= (byte)(1 << (ch % 8)); } } /// /// Add characters to the set. /// /// String containing characters to add. public void Add(string strCharSet) { Debug.Assert(strCharSet != null); if(strCharSet == null) throw new ArgumentNullException("strCharSet"); m_vChars.Capacity = m_vChars.Count + strCharSet.Length; foreach(char ch in strCharSet) Add(ch); } public void Add(string strCharSet1, string strCharSet2) { Add(strCharSet1); Add(strCharSet2); } public void Add(string strCharSet1, string strCharSet2, string strCharSet3) { Add(strCharSet1); Add(strCharSet2); Add(strCharSet3); } public void AddRange(char chMin, char chMax) { m_vChars.Capacity = m_vChars.Count + (chMax - chMin) + 1; for(char ch = chMin; ch < chMax; ++ch) Add(ch); Add(chMax); } public bool AddCharSet(char chCharSetIdentifier) { bool bResult = true; switch(chCharSetIdentifier) { case 'a': Add(PwCharSet.LowerCase, PwCharSet.Digits); break; case 'A': Add(PwCharSet.LowerCase, PwCharSet.UpperCase, PwCharSet.Digits); break; case 'U': Add(PwCharSet.UpperCase, PwCharSet.Digits); break; case 'c': Add(PwCharSet.LowerConsonants); break; case 'C': Add(PwCharSet.LowerConsonants, PwCharSet.UpperConsonants); break; case 'z': Add(PwCharSet.UpperConsonants); break; case 'd': Add(PwCharSet.Digits); break; // Digit case 'h': Add(PwCharSet.LowerHex); break; case 'H': Add(PwCharSet.UpperHex); break; case 'l': Add(PwCharSet.LowerCase); break; case 'L': Add(PwCharSet.LowerCase, PwCharSet.UpperCase); break; case 'u': Add(PwCharSet.UpperCase); break; case 'p': Add(PwCharSet.Punctuation); break; case 'b': Add(PwCharSet.Brackets); break; case 's': Add(PwCharSet.PrintableAsciiSpecial); break; case 'S': Add(PwCharSet.UpperCase, PwCharSet.LowerCase); Add(PwCharSet.Digits, PwCharSet.PrintableAsciiSpecial); break; case 'v': Add(PwCharSet.LowerVowels); break; case 'V': Add(PwCharSet.LowerVowels, PwCharSet.UpperVowels); break; case 'Z': Add(PwCharSet.UpperVowels); break; case 'x': Add(m_strHighAnsi); break; default: bResult = false; break; } return bResult; } public bool Remove(char ch) { m_vTab[ch / 8] &= (byte)(~(1 << (ch % 8))); return m_vChars.Remove(ch); } public bool Remove(string strCharacters) { Debug.Assert(strCharacters != null); if(strCharacters == null) throw new ArgumentNullException("strCharacters"); bool bResult = true; foreach(char ch in strCharacters) { if(!Remove(ch)) bResult = false; } return bResult; } public bool RemoveIfAllExist(string strCharacters) { Debug.Assert(strCharacters != null); if(strCharacters == null) throw new ArgumentNullException("strCharacters"); if(!Contains(strCharacters)) return false; return Remove(strCharacters); } /// /// Convert the character set to a string containing all its characters. /// /// String containing all character set characters. public override string ToString() { StringBuilder sb = new StringBuilder(); foreach(char ch in m_vChars) sb.Append(ch); return sb.ToString(); } public string PackAndRemoveCharRanges() { StringBuilder sb = new StringBuilder(); sb.Append(RemoveIfAllExist(PwCharSet.UpperCase) ? 'U' : '_'); sb.Append(RemoveIfAllExist(PwCharSet.LowerCase) ? 'L' : '_'); sb.Append(RemoveIfAllExist(PwCharSet.Digits) ? 'D' : '_'); sb.Append(RemoveIfAllExist(m_strSpecial) ? 'S' : '_'); sb.Append(RemoveIfAllExist(PwCharSet.Punctuation) ? 'P' : '_'); sb.Append(RemoveIfAllExist(@"-") ? 'm' : '_'); sb.Append(RemoveIfAllExist(@"_") ? 'u' : '_'); sb.Append(RemoveIfAllExist(@" ") ? 's' : '_'); sb.Append(RemoveIfAllExist(PwCharSet.Brackets) ? 'B' : '_'); sb.Append(RemoveIfAllExist(m_strHighAnsi) ? 'H' : '_'); return sb.ToString(); } public void UnpackCharRanges(string strRanges) { if(strRanges == null) { Debug.Assert(false); return; } if(strRanges.Length < 10) { Debug.Assert(false); return; } if(strRanges[0] != '_') Add(PwCharSet.UpperCase); if(strRanges[1] != '_') Add(PwCharSet.LowerCase); if(strRanges[2] != '_') Add(PwCharSet.Digits); if(strRanges[3] != '_') Add(m_strSpecial); if(strRanges[4] != '_') Add(PwCharSet.Punctuation); if(strRanges[5] != '_') Add('-'); if(strRanges[6] != '_') Add('_'); if(strRanges[7] != '_') Add(' '); if(strRanges[8] != '_') Add(PwCharSet.Brackets); if(strRanges[9] != '_') Add(m_strHighAnsi); } } } KeePassLib/Cryptography/PasswordGenerator/CharSetBasedGenerator.cs0000664000000000000000000000400613222430400024360 0ustar rootroot/* KeePass Password Safe - The Open-Source Password Manager Copyright (C) 2003-2018 Dominik Reichl This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ using System; using System.Collections.Generic; using System.Text; using System.Diagnostics; using KeePassLib.Security; using KeePassLib.Utility; namespace KeePassLib.Cryptography.PasswordGenerator { internal static class CharSetBasedGenerator { internal static PwgError Generate(out ProtectedString psOut, PwProfile pwProfile, CryptoRandomStream crsRandomSource) { psOut = ProtectedString.Empty; if(pwProfile.Length == 0) return PwgError.Success; PwCharSet pcs = new PwCharSet(pwProfile.CharSet.ToString()); char[] vGenerated = new char[pwProfile.Length]; PwGenerator.PrepareCharSet(pcs, pwProfile); for(int nIndex = 0; nIndex < (int)pwProfile.Length; ++nIndex) { char ch = PwGenerator.GenerateCharacter(pwProfile, pcs, crsRandomSource); if(ch == char.MinValue) { MemUtil.ZeroArray(vGenerated); return PwgError.TooFewCharacters; } vGenerated[nIndex] = ch; } byte[] pbUtf8 = StrUtil.Utf8.GetBytes(vGenerated); psOut = new ProtectedString(true, pbUtf8); MemUtil.ZeroByteArray(pbUtf8); MemUtil.ZeroArray(vGenerated); return PwgError.Success; } } } KeePassLib/Cryptography/PasswordGenerator/PatternBasedGenerator.cs0000664000000000000000000001133613222430400024450 0ustar rootroot/* KeePass Password Safe - The Open-Source Password Manager Copyright (C) 2003-2018 Dominik Reichl This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ using System; using System.Collections.Generic; using System.Text; using System.Diagnostics; using KeePassLib.Security; using KeePassLib.Utility; namespace KeePassLib.Cryptography.PasswordGenerator { internal static class PatternBasedGenerator { internal static PwgError Generate(out ProtectedString psOut, PwProfile pwProfile, CryptoRandomStream crsRandomSource) { psOut = ProtectedString.Empty; LinkedList vGenerated = new LinkedList(); PwCharSet pcsCurrent = new PwCharSet(); PwCharSet pcsCustom = new PwCharSet(); PwCharSet pcsUsed = new PwCharSet(); bool bInCharSetDef = false; string strPattern = ExpandPattern(pwProfile.Pattern); if(strPattern.Length == 0) return PwgError.Success; CharStream csStream = new CharStream(strPattern); char ch = csStream.ReadChar(); while(ch != char.MinValue) { pcsCurrent.Clear(); bool bGenerateChar = false; if(ch == '\\') { ch = csStream.ReadChar(); if(ch == char.MinValue) // Backslash at the end { vGenerated.AddLast('\\'); break; } if(bInCharSetDef) pcsCustom.Add(ch); else { vGenerated.AddLast(ch); pcsUsed.Add(ch); } } else if(ch == '^') { ch = csStream.ReadChar(); if(ch == char.MinValue) // ^ at the end { vGenerated.AddLast('^'); break; } if(bInCharSetDef) pcsCustom.Remove(ch); } else if(ch == '[') { pcsCustom.Clear(); bInCharSetDef = true; } else if(ch == ']') { pcsCurrent.Add(pcsCustom.ToString()); bInCharSetDef = false; bGenerateChar = true; } else if(bInCharSetDef) { if(pcsCustom.AddCharSet(ch) == false) pcsCustom.Add(ch); } else if(pcsCurrent.AddCharSet(ch) == false) { vGenerated.AddLast(ch); pcsUsed.Add(ch); } else bGenerateChar = true; if(bGenerateChar) { PwGenerator.PrepareCharSet(pcsCurrent, pwProfile); if(pwProfile.NoRepeatingCharacters) pcsCurrent.Remove(pcsUsed.ToString()); char chGen = PwGenerator.GenerateCharacter(pwProfile, pcsCurrent, crsRandomSource); if(chGen == char.MinValue) return PwgError.TooFewCharacters; vGenerated.AddLast(chGen); pcsUsed.Add(chGen); } ch = csStream.ReadChar(); } if(vGenerated.Count == 0) return PwgError.Success; char[] vArray = new char[vGenerated.Count]; vGenerated.CopyTo(vArray, 0); if(pwProfile.PatternPermutePassword) PwGenerator.ShufflePassword(vArray, crsRandomSource); byte[] pbUtf8 = StrUtil.Utf8.GetBytes(vArray); psOut = new ProtectedString(true, pbUtf8); MemUtil.ZeroByteArray(pbUtf8); MemUtil.ZeroArray(vArray); vGenerated.Clear(); return PwgError.Success; } private static string ExpandPattern(string strPattern) { Debug.Assert(strPattern != null); if(strPattern == null) return string.Empty; string str = strPattern; while(true) { int nOpen = FindFirstUnescapedChar(str, '{'); int nClose = FindFirstUnescapedChar(str, '}'); if((nOpen >= 0) && (nOpen < nClose)) { string strCount = str.Substring(nOpen + 1, nClose - nOpen - 1); str = str.Remove(nOpen, nClose - nOpen + 1); uint uRepeat; if(StrUtil.TryParseUInt(strCount, out uRepeat) && (nOpen >= 1)) { if(uRepeat == 0) str = str.Remove(nOpen - 1, 1); else str = str.Insert(nOpen, new string(str[nOpen - 1], (int)uRepeat - 1)); } } else break; } return str; } private static int FindFirstUnescapedChar(string str, char ch) { for(int i = 0; i < str.Length; ++i) { char chCur = str[i]; if(chCur == '\\') ++i; // Next is escaped, skip it else if(chCur == ch) return i; } return -1; } } } KeePassLib/Cryptography/PasswordGenerator/CustomPwGenerator.cs0000664000000000000000000000424113222430400023652 0ustar rootroot/* KeePass Password Safe - The Open-Source Password Manager Copyright (C) 2003-2018 Dominik Reichl This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ using System; using System.Collections.Generic; using System.Text; using KeePassLib; using KeePassLib.Security; namespace KeePassLib.Cryptography.PasswordGenerator { public abstract class CustomPwGenerator { /// /// Each custom password generation algorithm must have /// its own unique UUID. /// public abstract PwUuid Uuid { get; } /// /// Displayable name of the password generation algorithm. /// public abstract string Name { get; } public virtual bool SupportsOptions { get { return false; } } /// /// Password generation function. /// /// Password generation options chosen /// by the user. This may be null, if the default /// options should be used. /// Source that the algorithm /// can use to generate random numbers. /// Generated password or null in case /// of failure. If returning null, the caller assumes /// that an error message has already been shown to the user. public abstract ProtectedString Generate(PwProfile prf, CryptoRandomStream crsRandomSource); public virtual string GetOptions(string strCurrentOptions) { return string.Empty; } } } KeePassLib/Cryptography/PasswordGenerator/CustomPwGeneratorPool.cs0000664000000000000000000000530013222430400024501 0ustar rootroot/* KeePass Password Safe - The Open-Source Password Manager Copyright (C) 2003-2018 Dominik Reichl This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ using System; using System.Collections; using System.Collections.Generic; using System.Text; namespace KeePassLib.Cryptography.PasswordGenerator { public sealed class CustomPwGeneratorPool : IEnumerable { private List m_vGens = new List(); public int Count { get { return m_vGens.Count; } } public CustomPwGeneratorPool() { } IEnumerator IEnumerable.GetEnumerator() { return m_vGens.GetEnumerator(); } public IEnumerator GetEnumerator() { return m_vGens.GetEnumerator(); } public void Add(CustomPwGenerator pwg) { if(pwg == null) throw new ArgumentNullException("pwg"); PwUuid uuid = pwg.Uuid; if(uuid == null) throw new ArgumentException(); int nIndex = FindIndex(uuid); if(nIndex >= 0) m_vGens[nIndex] = pwg; // Replace else m_vGens.Add(pwg); } public CustomPwGenerator Find(PwUuid uuid) { if(uuid == null) throw new ArgumentNullException("uuid"); foreach(CustomPwGenerator pwg in m_vGens) { if(uuid.Equals(pwg.Uuid)) return pwg; } return null; } public CustomPwGenerator Find(string strName) { if(strName == null) throw new ArgumentNullException("strName"); foreach(CustomPwGenerator pwg in m_vGens) { if(pwg.Name == strName) return pwg; } return null; } private int FindIndex(PwUuid uuid) { if(uuid == null) throw new ArgumentNullException("uuid"); for(int i = 0; i < m_vGens.Count; ++i) { if(uuid.Equals(m_vGens[i].Uuid)) return i; } return -1; } public bool Remove(PwUuid uuid) { if(uuid == null) throw new ArgumentNullException("uuid"); int nIndex = FindIndex(uuid); if(nIndex < 0) return false; m_vGens.RemoveAt(nIndex); return true; } } } KeePassLib/Cryptography/PasswordGenerator/PwGenerator.cs0000664000000000000000000001226413222430400022463 0ustar rootroot/* KeePass Password Safe - The Open-Source Password Manager Copyright (C) 2003-2018 Dominik Reichl This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ using System; using System.Collections.Generic; using System.Diagnostics; using System.Text; #if !KeePassUAP using System.Security.Cryptography; #endif using KeePassLib.Security; using KeePassLib.Utility; namespace KeePassLib.Cryptography.PasswordGenerator { public enum PwgError { Success = 0, Unknown = 1, TooFewCharacters = 2, UnknownAlgorithm = 3 } /// /// Utility functions for generating random passwords. /// public static class PwGenerator { public static PwgError Generate(out ProtectedString psOut, PwProfile pwProfile, byte[] pbUserEntropy, CustomPwGeneratorPool pwAlgorithmPool) { Debug.Assert(pwProfile != null); if(pwProfile == null) throw new ArgumentNullException("pwProfile"); PwgError e = PwgError.Unknown; CryptoRandomStream crs = null; byte[] pbKey = null; try { crs = CreateRandomStream(pbUserEntropy, out pbKey); if(pwProfile.GeneratorType == PasswordGeneratorType.CharSet) e = CharSetBasedGenerator.Generate(out psOut, pwProfile, crs); else if(pwProfile.GeneratorType == PasswordGeneratorType.Pattern) e = PatternBasedGenerator.Generate(out psOut, pwProfile, crs); else if(pwProfile.GeneratorType == PasswordGeneratorType.Custom) e = GenerateCustom(out psOut, pwProfile, crs, pwAlgorithmPool); else { Debug.Assert(false); psOut = ProtectedString.Empty; } } finally { if(crs != null) crs.Dispose(); if(pbKey != null) MemUtil.ZeroByteArray(pbKey); } return e; } private static CryptoRandomStream CreateRandomStream(byte[] pbAdditionalEntropy, out byte[] pbKey) { pbKey = CryptoRandom.Instance.GetRandomBytes(128); // Mix in additional entropy Debug.Assert(pbKey.Length >= 64); if((pbAdditionalEntropy != null) && (pbAdditionalEntropy.Length > 0)) { using(SHA512Managed h = new SHA512Managed()) { byte[] pbHash = h.ComputeHash(pbAdditionalEntropy); MemUtil.XorArray(pbHash, 0, pbKey, 0, pbHash.Length); } } return new CryptoRandomStream(CrsAlgorithm.ChaCha20, pbKey); } internal static char GenerateCharacter(PwProfile pwProfile, PwCharSet pwCharSet, CryptoRandomStream crsRandomSource) { if(pwCharSet.Size == 0) return char.MinValue; ulong uIndex = crsRandomSource.GetRandomUInt64(); uIndex %= (ulong)pwCharSet.Size; char ch = pwCharSet[(uint)uIndex]; if(pwProfile.NoRepeatingCharacters) pwCharSet.Remove(ch); return ch; } internal static void PrepareCharSet(PwCharSet pwCharSet, PwProfile pwProfile) { pwCharSet.Remove(PwCharSet.Invalid); if(pwProfile.ExcludeLookAlike) pwCharSet.Remove(PwCharSet.LookAlike); if(pwProfile.ExcludeCharacters.Length > 0) pwCharSet.Remove(pwProfile.ExcludeCharacters); } internal static void ShufflePassword(char[] pPassword, CryptoRandomStream crsRandomSource) { Debug.Assert(pPassword != null); if(pPassword == null) return; Debug.Assert(crsRandomSource != null); if(crsRandomSource == null) return; if(pPassword.Length <= 1) return; // Nothing to shuffle for(int nSelect = 0; nSelect < pPassword.Length; ++nSelect) { ulong uRandomIndex = crsRandomSource.GetRandomUInt64(); uRandomIndex %= (ulong)(pPassword.Length - nSelect); char chTemp = pPassword[nSelect]; pPassword[nSelect] = pPassword[nSelect + (int)uRandomIndex]; pPassword[nSelect + (int)uRandomIndex] = chTemp; } } private static PwgError GenerateCustom(out ProtectedString psOut, PwProfile pwProfile, CryptoRandomStream crs, CustomPwGeneratorPool pwAlgorithmPool) { psOut = ProtectedString.Empty; Debug.Assert(pwProfile.GeneratorType == PasswordGeneratorType.Custom); if(pwAlgorithmPool == null) return PwgError.UnknownAlgorithm; string strID = pwProfile.CustomAlgorithmUuid; if(string.IsNullOrEmpty(strID)) { Debug.Assert(false); return PwgError.UnknownAlgorithm; } byte[] pbUuid = Convert.FromBase64String(strID); PwUuid uuid = new PwUuid(pbUuid); CustomPwGenerator pwg = pwAlgorithmPool.Find(uuid); if(pwg == null) { Debug.Assert(false); return PwgError.UnknownAlgorithm; } ProtectedString pwd = pwg.Generate(pwProfile.CloneDeep(), crs); if(pwd == null) return PwgError.Unknown; psOut = pwd; return PwgError.Success; } } } KeePassLib/PwEntry.cs0000664000000000000000000006720413222430402013500 0ustar rootroot/* KeePass Password Safe - The Open-Source Password Manager Copyright (C) 2003-2018 Dominik Reichl This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ using System; using System.Collections.Generic; using System.Diagnostics; #if !KeePassUAP using System.Drawing; #endif using KeePassLib.Collections; using KeePassLib.Interfaces; using KeePassLib.Security; using KeePassLib.Utility; namespace KeePassLib { /// /// A class representing a password entry. A password entry consists of several /// fields like title, user name, password, etc. Each password entry has a /// unique ID (UUID). /// public sealed class PwEntry : ITimeLogger, IStructureItem, IDeepCloneable { private PwUuid m_uuid = PwUuid.Zero; private PwGroup m_pParentGroup = null; private DateTime m_tParentGroupLastMod = PwDefs.DtDefaultNow; private ProtectedStringDictionary m_listStrings = new ProtectedStringDictionary(); private ProtectedBinaryDictionary m_listBinaries = new ProtectedBinaryDictionary(); private AutoTypeConfig m_listAutoType = new AutoTypeConfig(); private PwObjectList m_listHistory = new PwObjectList(); private PwIcon m_pwIcon = PwIcon.Key; private PwUuid m_pwCustomIconID = PwUuid.Zero; private Color m_clrForeground = Color.Empty; private Color m_clrBackground = Color.Empty; private DateTime m_tCreation = PwDefs.DtDefaultNow; private DateTime m_tLastMod = PwDefs.DtDefaultNow; private DateTime m_tLastAccess = PwDefs.DtDefaultNow; private DateTime m_tExpire = PwDefs.DtDefaultNow; private bool m_bExpires = false; private ulong m_uUsageCount = 0; private string m_strOverrideUrl = string.Empty; private List m_vTags = new List(); private StringDictionaryEx m_dCustomData = new StringDictionaryEx(); /// /// UUID of this entry. /// public PwUuid Uuid { get { return m_uuid; } set { Debug.Assert(value != null); if(value == null) throw new ArgumentNullException("value"); m_uuid = value; } } /// /// Reference to a group which contains the current entry. /// public PwGroup ParentGroup { get { return m_pParentGroup; } // Plugins: use PwGroup.AddEntry instead. internal set { m_pParentGroup = value; } } /// /// The date/time when the location of the object was last changed. /// public DateTime LocationChanged { get { return m_tParentGroupLastMod; } set { m_tParentGroupLastMod = value; } } /// /// Get or set all entry strings. /// public ProtectedStringDictionary Strings { get { return m_listStrings; } set { Debug.Assert(value != null); if(value == null) throw new ArgumentNullException("value"); m_listStrings = value; } } /// /// Get or set all entry binaries. /// public ProtectedBinaryDictionary Binaries { get { return m_listBinaries; } set { Debug.Assert(value != null); if(value == null) throw new ArgumentNullException("value"); m_listBinaries = value; } } /// /// Get or set all auto-type window/keystroke sequence associations. /// public AutoTypeConfig AutoType { get { return m_listAutoType; } set { Debug.Assert(value != null); if(value == null) throw new ArgumentNullException("value"); m_listAutoType = value; } } /// /// Get all previous versions of this entry (backups). /// public PwObjectList History { get { return m_listHistory; } set { Debug.Assert(value != null); if(value == null) throw new ArgumentNullException("value"); m_listHistory = value; } } /// /// Image ID specifying the icon that will be used for this entry. /// public PwIcon IconId { get { return m_pwIcon; } set { m_pwIcon = value; } } /// /// Get the custom icon ID. This value is 0, if no custom icon is /// being used (i.e. the icon specified by the IconID property /// should be displayed). /// public PwUuid CustomIconUuid { get { return m_pwCustomIconID; } set { Debug.Assert(value != null); if(value == null) throw new ArgumentNullException("value"); m_pwCustomIconID = value; } } /// /// Get or set the foreground color of this entry. /// public Color ForegroundColor { get { return m_clrForeground; } set { m_clrForeground = value; } } /// /// Get or set the background color of this entry. /// public Color BackgroundColor { get { return m_clrBackground; } set { m_clrBackground = value; } } /// /// The date/time when this entry was created. /// public DateTime CreationTime { get { return m_tCreation; } set { m_tCreation = value; } } /// /// The date/time when this entry was last modified. /// public DateTime LastModificationTime { get { return m_tLastMod; } set { m_tLastMod = value; } } /// /// The date/time when this entry was last accessed (read). /// public DateTime LastAccessTime { get { return m_tLastAccess; } set { m_tLastAccess = value; } } /// /// The date/time when this entry expires. Use the Expires property /// to specify if the entry does actually expire or not. /// public DateTime ExpiryTime { get { return m_tExpire; } set { m_tExpire = value; } } /// /// Specifies whether the entry expires or not. /// public bool Expires { get { return m_bExpires; } set { m_bExpires = value; } } /// /// Get or set the usage count of the entry. To increase the usage /// count by one, use the Touch function. /// public ulong UsageCount { get { return m_uUsageCount; } set { m_uUsageCount = value; } } /// /// Entry-specific override URL. If this string is non-empty, /// public string OverrideUrl { get { return m_strOverrideUrl; } set { if(value == null) throw new ArgumentNullException("value"); m_strOverrideUrl = value; } } /// /// List of tags associated with this entry. /// public List Tags { get { return m_vTags; } set { if(value == null) throw new ArgumentNullException("value"); m_vTags = value; } } /// /// Custom data container that can be used by plugins to store /// own data in KeePass entries. /// The data is stored in the encrypted part of encrypted /// database files. /// Use unique names for your items, e.g. "PluginName_ItemName". /// public StringDictionaryEx CustomData { get { return m_dCustomData; } internal set { if(value == null) { Debug.Assert(false); throw new ArgumentNullException("value"); } m_dCustomData = value; } } public static EventHandler EntryTouched; public EventHandler Touched; /// /// Construct a new, empty password entry. Member variables will be initialized /// to their default values. /// /// If true, a new UUID will be created /// for this entry. If false, the UUID is zero and you must set it /// manually later. /// If true, the creation, last modification /// and last access times will be set to the current system time. public PwEntry(bool bCreateNewUuid, bool bSetTimes) { if(bCreateNewUuid) m_uuid = new PwUuid(true); if(bSetTimes) { DateTime dtNow = DateTime.UtcNow; m_tCreation = dtNow; m_tLastMod = dtNow; m_tLastAccess = dtNow; m_tParentGroupLastMod = dtNow; } } /// /// Construct a new, empty password entry. Member variables will be initialized /// to their default values. /// /// Reference to the containing group, this /// parameter may be null and set later manually. /// If true, a new UUID will be created /// for this entry. If false, the UUID is zero and you must set it /// manually later. /// If true, the creation, last modification /// and last access times will be set to the current system time. [Obsolete("Use a different constructor. To add an entry to a group, use AddEntry of PwGroup.")] public PwEntry(PwGroup pwParentGroup, bool bCreateNewUuid, bool bSetTimes) { m_pParentGroup = pwParentGroup; if(bCreateNewUuid) m_uuid = new PwUuid(true); if(bSetTimes) { DateTime dtNow = DateTime.UtcNow; m_tCreation = dtNow; m_tLastMod = dtNow; m_tLastAccess = dtNow; m_tParentGroupLastMod = dtNow; } } #if DEBUG // For display in debugger public override string ToString() { return (@"PwEntry '" + m_listStrings.ReadSafe(PwDefs.TitleField) + @"'"); } #endif /// /// Clone the current entry. The returned entry is an exact value copy /// of the current entry (including UUID and parent group reference). /// All mutable members are cloned. /// /// Exact value clone. All references to mutable values changed. public PwEntry CloneDeep() { PwEntry peNew = new PwEntry(false, false); peNew.m_uuid = m_uuid; // PwUuid is immutable peNew.m_pParentGroup = m_pParentGroup; peNew.m_tParentGroupLastMod = m_tParentGroupLastMod; peNew.m_listStrings = m_listStrings.CloneDeep(); peNew.m_listBinaries = m_listBinaries.CloneDeep(); peNew.m_listAutoType = m_listAutoType.CloneDeep(); peNew.m_listHistory = m_listHistory.CloneDeep(); peNew.m_pwIcon = m_pwIcon; peNew.m_pwCustomIconID = m_pwCustomIconID; peNew.m_clrForeground = m_clrForeground; peNew.m_clrBackground = m_clrBackground; peNew.m_tCreation = m_tCreation; peNew.m_tLastMod = m_tLastMod; peNew.m_tLastAccess = m_tLastAccess; peNew.m_tExpire = m_tExpire; peNew.m_bExpires = m_bExpires; peNew.m_uUsageCount = m_uUsageCount; peNew.m_strOverrideUrl = m_strOverrideUrl; peNew.m_vTags = new List(m_vTags); peNew.m_dCustomData = m_dCustomData.CloneDeep(); return peNew; } public PwEntry CloneStructure() { PwEntry peNew = new PwEntry(false, false); peNew.m_uuid = m_uuid; // PwUuid is immutable peNew.m_tParentGroupLastMod = m_tParentGroupLastMod; // Do not assign m_pParentGroup return peNew; } private static PwCompareOptions BuildCmpOpt(bool bIgnoreParentGroup, bool bIgnoreLastMod, bool bIgnoreLastAccess, bool bIgnoreHistory, bool bIgnoreThisLastBackup) { PwCompareOptions pwOpt = PwCompareOptions.None; if(bIgnoreParentGroup) pwOpt |= PwCompareOptions.IgnoreParentGroup; if(bIgnoreLastMod) pwOpt |= PwCompareOptions.IgnoreLastMod; if(bIgnoreLastAccess) pwOpt |= PwCompareOptions.IgnoreLastAccess; if(bIgnoreHistory) pwOpt |= PwCompareOptions.IgnoreHistory; if(bIgnoreThisLastBackup) pwOpt |= PwCompareOptions.IgnoreLastBackup; return pwOpt; } [Obsolete] public bool EqualsEntry(PwEntry pe, bool bIgnoreParentGroup, bool bIgnoreLastMod, bool bIgnoreLastAccess, bool bIgnoreHistory, bool bIgnoreThisLastBackup) { return EqualsEntry(pe, BuildCmpOpt(bIgnoreParentGroup, bIgnoreLastMod, bIgnoreLastAccess, bIgnoreHistory, bIgnoreThisLastBackup), MemProtCmpMode.None); } [Obsolete] public bool EqualsEntry(PwEntry pe, bool bIgnoreParentGroup, bool bIgnoreLastMod, bool bIgnoreLastAccess, bool bIgnoreHistory, bool bIgnoreThisLastBackup, MemProtCmpMode mpCmpStr) { return EqualsEntry(pe, BuildCmpOpt(bIgnoreParentGroup, bIgnoreLastMod, bIgnoreLastAccess, bIgnoreHistory, bIgnoreThisLastBackup), mpCmpStr); } public bool EqualsEntry(PwEntry pe, PwCompareOptions pwOpt, MemProtCmpMode mpCmpStr) { if(pe == null) { Debug.Assert(false); return false; } bool bNeEqStd = ((pwOpt & PwCompareOptions.NullEmptyEquivStd) != PwCompareOptions.None); bool bIgnoreLastAccess = ((pwOpt & PwCompareOptions.IgnoreLastAccess) != PwCompareOptions.None); bool bIgnoreLastMod = ((pwOpt & PwCompareOptions.IgnoreLastMod) != PwCompareOptions.None); if(!m_uuid.Equals(pe.m_uuid)) return false; if((pwOpt & PwCompareOptions.IgnoreParentGroup) == PwCompareOptions.None) { if(m_pParentGroup != pe.m_pParentGroup) return false; if(!bIgnoreLastMod && (m_tParentGroupLastMod != pe.m_tParentGroupLastMod)) return false; } if(!m_listStrings.EqualsDictionary(pe.m_listStrings, pwOpt, mpCmpStr)) return false; if(!m_listBinaries.EqualsDictionary(pe.m_listBinaries)) return false; if(!m_listAutoType.Equals(pe.m_listAutoType)) return false; if((pwOpt & PwCompareOptions.IgnoreHistory) == PwCompareOptions.None) { bool bIgnoreLastBackup = ((pwOpt & PwCompareOptions.IgnoreLastBackup) != PwCompareOptions.None); if(!bIgnoreLastBackup && (m_listHistory.UCount != pe.m_listHistory.UCount)) return false; if(bIgnoreLastBackup && (m_listHistory.UCount == 0)) { Debug.Assert(false); return false; } if(bIgnoreLastBackup && ((m_listHistory.UCount - 1) != pe.m_listHistory.UCount)) return false; PwCompareOptions cmpSub = PwCompareOptions.IgnoreParentGroup; if(bNeEqStd) cmpSub |= PwCompareOptions.NullEmptyEquivStd; if(bIgnoreLastMod) cmpSub |= PwCompareOptions.IgnoreLastMod; if(bIgnoreLastAccess) cmpSub |= PwCompareOptions.IgnoreLastAccess; for(uint uHist = 0; uHist < pe.m_listHistory.UCount; ++uHist) { if(!m_listHistory.GetAt(uHist).EqualsEntry(pe.m_listHistory.GetAt( uHist), cmpSub, MemProtCmpMode.None)) return false; } } if(m_pwIcon != pe.m_pwIcon) return false; if(!m_pwCustomIconID.Equals(pe.m_pwCustomIconID)) return false; if(m_clrForeground != pe.m_clrForeground) return false; if(m_clrBackground != pe.m_clrBackground) return false; if(m_tCreation != pe.m_tCreation) return false; if(!bIgnoreLastMod && (m_tLastMod != pe.m_tLastMod)) return false; if(!bIgnoreLastAccess && (m_tLastAccess != pe.m_tLastAccess)) return false; if(m_tExpire != pe.m_tExpire) return false; if(m_bExpires != pe.m_bExpires) return false; if(!bIgnoreLastAccess && (m_uUsageCount != pe.m_uUsageCount)) return false; if(m_strOverrideUrl != pe.m_strOverrideUrl) return false; if(m_vTags.Count != pe.m_vTags.Count) return false; for(int iTag = 0; iTag < m_vTags.Count; ++iTag) { if(m_vTags[iTag] != pe.m_vTags[iTag]) return false; } if(!m_dCustomData.Equals(pe.m_dCustomData)) return false; return true; } /// /// Assign properties to the current entry based on a template entry. /// /// Template entry. Must not be null. /// Only set the properties of the template entry /// if it is newer than the current one. /// If true, the history will be /// copied, too. /// If true, the /// LocationChanged property is copied, otherwise not. public void AssignProperties(PwEntry peTemplate, bool bOnlyIfNewer, bool bIncludeHistory, bool bAssignLocationChanged) { if(peTemplate == null) { Debug.Assert(false); throw new ArgumentNullException("peTemplate"); } if(bOnlyIfNewer && (TimeUtil.Compare(peTemplate.m_tLastMod, m_tLastMod, true) < 0)) return; // Template UUID should be the same as the current one Debug.Assert(m_uuid.Equals(peTemplate.m_uuid)); m_uuid = peTemplate.m_uuid; if(bAssignLocationChanged) m_tParentGroupLastMod = peTemplate.m_tParentGroupLastMod; m_listStrings = peTemplate.m_listStrings.CloneDeep(); m_listBinaries = peTemplate.m_listBinaries.CloneDeep(); m_listAutoType = peTemplate.m_listAutoType.CloneDeep(); if(bIncludeHistory) m_listHistory = peTemplate.m_listHistory.CloneDeep(); m_pwIcon = peTemplate.m_pwIcon; m_pwCustomIconID = peTemplate.m_pwCustomIconID; // Immutable m_clrForeground = peTemplate.m_clrForeground; m_clrBackground = peTemplate.m_clrBackground; m_tCreation = peTemplate.m_tCreation; m_tLastMod = peTemplate.m_tLastMod; m_tLastAccess = peTemplate.m_tLastAccess; m_tExpire = peTemplate.m_tExpire; m_bExpires = peTemplate.m_bExpires; m_uUsageCount = peTemplate.m_uUsageCount; m_strOverrideUrl = peTemplate.m_strOverrideUrl; m_vTags = new List(peTemplate.m_vTags); m_dCustomData = peTemplate.m_dCustomData.CloneDeep(); } /// /// Touch the entry. This function updates the internal last access /// time. If the parameter is true, /// the last modification time gets updated, too. /// /// Modify last modification time. public void Touch(bool bModified) { Touch(bModified, true); } /// /// Touch the entry. This function updates the internal last access /// time. If the parameter is true, /// the last modification time gets updated, too. /// /// Modify last modification time. /// If true, all parent objects /// get touched, too. public void Touch(bool bModified, bool bTouchParents) { m_tLastAccess = DateTime.UtcNow; ++m_uUsageCount; if(bModified) m_tLastMod = m_tLastAccess; if(this.Touched != null) this.Touched(this, new ObjectTouchedEventArgs(this, bModified, bTouchParents)); if(PwEntry.EntryTouched != null) PwEntry.EntryTouched(this, new ObjectTouchedEventArgs(this, bModified, bTouchParents)); if(bTouchParents && (m_pParentGroup != null)) m_pParentGroup.Touch(bModified, true); } /// /// Create a backup of this entry. The backup item doesn't contain any /// history items. /// [Obsolete] public void CreateBackup() { CreateBackup(null); } /// /// Create a backup of this entry. The backup item doesn't contain any /// history items. /// If this parameter isn't null, /// the history list is maintained automatically (i.e. old backups are /// deleted if there are too many or the history size is too large). /// This parameter may be null (no maintenance then). /// public void CreateBackup(PwDatabase pwHistMntcSettings) { PwEntry peCopy = CloneDeep(); peCopy.History = new PwObjectList(); // Remove history m_listHistory.Add(peCopy); // Must be added at end, see EqualsEntry if(pwHistMntcSettings != null) MaintainBackups(pwHistMntcSettings); } /// /// Restore an entry snapshot from backups. /// /// Index of the backup item, to which /// should be reverted. [Obsolete] public void RestoreFromBackup(uint uBackupIndex) { RestoreFromBackup(uBackupIndex, null); } /// /// Restore an entry snapshot from backups. /// /// Index of the backup item, to which /// should be reverted. /// If this parameter isn't null, /// the history list is maintained automatically (i.e. old backups are /// deleted if there are too many or the history size is too large). /// This parameter may be null (no maintenance then). public void RestoreFromBackup(uint uBackupIndex, PwDatabase pwHistMntcSettings) { Debug.Assert(uBackupIndex < m_listHistory.UCount); if(uBackupIndex >= m_listHistory.UCount) throw new ArgumentOutOfRangeException("uBackupIndex"); PwEntry pe = m_listHistory.GetAt(uBackupIndex); Debug.Assert(pe != null); if(pe == null) throw new InvalidOperationException(); CreateBackup(pwHistMntcSettings); // Backup current data before restoring AssignProperties(pe, false, false, false); } public bool HasBackupOfData(PwEntry peData, bool bIgnoreLastMod, bool bIgnoreLastAccess) { if(peData == null) { Debug.Assert(false); return false; } PwCompareOptions cmpOpt = (PwCompareOptions.IgnoreParentGroup | PwCompareOptions.IgnoreHistory | PwCompareOptions.NullEmptyEquivStd); if(bIgnoreLastMod) cmpOpt |= PwCompareOptions.IgnoreLastMod; if(bIgnoreLastAccess) cmpOpt |= PwCompareOptions.IgnoreLastAccess; foreach(PwEntry pe in m_listHistory) { if(pe.EqualsEntry(peData, cmpOpt, MemProtCmpMode.None)) return true; } return false; } /// /// Delete old history items if there are too many or the history /// size is too large. /// If one or more history items have been deleted, true /// is returned. Otherwise false. /// public bool MaintainBackups(PwDatabase pwSettings) { if(pwSettings == null) { Debug.Assert(false); return false; } bool bDeleted = false; int nMaxItems = pwSettings.HistoryMaxItems; if(nMaxItems >= 0) { while(m_listHistory.UCount > (uint)nMaxItems) { RemoveOldestBackup(); bDeleted = true; } } long lMaxSize = pwSettings.HistoryMaxSize; if(lMaxSize >= 0) { while(true) { ulong uHistSize = 0; foreach(PwEntry pe in m_listHistory) { uHistSize += pe.GetSize(); } if(uHistSize > (ulong)lMaxSize) { RemoveOldestBackup(); bDeleted = true; } else break; } } return bDeleted; } private void RemoveOldestBackup() { DateTime dtMin = TimeUtil.SafeMaxValueUtc; uint idxRemove = uint.MaxValue; for(uint u = 0; u < m_listHistory.UCount; ++u) { PwEntry pe = m_listHistory.GetAt(u); if(TimeUtil.Compare(pe.LastModificationTime, dtMin, true) < 0) { idxRemove = u; dtMin = pe.LastModificationTime; } } if(idxRemove != uint.MaxValue) m_listHistory.RemoveAt(idxRemove); } public bool GetAutoTypeEnabled() { if(!m_listAutoType.Enabled) return false; if(m_pParentGroup != null) return m_pParentGroup.GetAutoTypeEnabledInherited(); return PwGroup.DefaultAutoTypeEnabled; } public string GetAutoTypeSequence() { string strSeq = m_listAutoType.DefaultSequence; PwGroup pg = m_pParentGroup; while(pg != null) { if(strSeq.Length != 0) break; strSeq = pg.DefaultAutoTypeSequence; pg = pg.ParentGroup; } if(strSeq.Length != 0) return strSeq; if(PwDefs.IsTanEntry(this)) return PwDefs.DefaultAutoTypeSequenceTan; return PwDefs.DefaultAutoTypeSequence; } public bool GetSearchingEnabled() { if(m_pParentGroup != null) return m_pParentGroup.GetSearchingEnabledInherited(); return PwGroup.DefaultSearchingEnabled; } /// /// Approximate the total size of this entry in bytes (including /// strings, binaries and history entries). /// /// Size in bytes. public ulong GetSize() { ulong uSize = 128; // Approx fixed length data foreach(KeyValuePair kvpStr in m_listStrings) { uSize += (ulong)kvpStr.Key.Length; uSize += (ulong)kvpStr.Value.Length; } foreach(KeyValuePair kvpBin in m_listBinaries) { uSize += (ulong)kvpBin.Key.Length; uSize += kvpBin.Value.Length; } uSize += (ulong)m_listAutoType.DefaultSequence.Length; foreach(AutoTypeAssociation a in m_listAutoType.Associations) { uSize += (ulong)a.WindowName.Length; uSize += (ulong)a.Sequence.Length; } foreach(PwEntry peHistory in m_listHistory) uSize += peHistory.GetSize(); uSize += (ulong)m_strOverrideUrl.Length; foreach(string strTag in m_vTags) uSize += (ulong)strTag.Length; foreach(KeyValuePair kvp in m_dCustomData) uSize += (ulong)kvp.Key.Length + (ulong)kvp.Value.Length; return uSize; } public bool HasTag(string strTag) { if(string.IsNullOrEmpty(strTag)) { Debug.Assert(false); return false; } for(int i = 0; i < m_vTags.Count; ++i) { if(m_vTags[i].Equals(strTag, StrUtil.CaseIgnoreCmp)) return true; } return false; } public bool AddTag(string strTag) { if(string.IsNullOrEmpty(strTag)) { Debug.Assert(false); return false; } for(int i = 0; i < m_vTags.Count; ++i) { if(m_vTags[i].Equals(strTag, StrUtil.CaseIgnoreCmp)) return false; } m_vTags.Add(strTag); return true; } public bool RemoveTag(string strTag) { if(string.IsNullOrEmpty(strTag)) { Debug.Assert(false); return false; } for(int i = 0; i < m_vTags.Count; ++i) { if(m_vTags[i].Equals(strTag, StrUtil.CaseIgnoreCmp)) { m_vTags.RemoveAt(i); return true; } } return false; } public bool IsContainedIn(PwGroup pgContainer) { PwGroup pgCur = m_pParentGroup; while(pgCur != null) { if(pgCur == pgContainer) return true; pgCur = pgCur.ParentGroup; } return false; } public void SetUuid(PwUuid pwNewUuid, bool bAlsoChangeHistoryUuids) { this.Uuid = pwNewUuid; if(bAlsoChangeHistoryUuids) { foreach(PwEntry peHist in m_listHistory) { peHist.Uuid = pwNewUuid; } } } public void SetCreatedNow() { DateTime dt = DateTime.UtcNow; m_tCreation = dt; m_tLastAccess = dt; } public PwEntry Duplicate() { PwEntry pe = CloneDeep(); pe.SetUuid(new PwUuid(true), true); pe.SetCreatedNow(); return pe; } } public sealed class PwEntryComparer : IComparer { private string m_strFieldName; private bool m_bCaseInsensitive; private bool m_bCompareNaturally; public PwEntryComparer(string strFieldName, bool bCaseInsensitive, bool bCompareNaturally) { if(strFieldName == null) throw new ArgumentNullException("strFieldName"); m_strFieldName = strFieldName; m_bCaseInsensitive = bCaseInsensitive; m_bCompareNaturally = bCompareNaturally; } public int Compare(PwEntry a, PwEntry b) { string strA = a.Strings.ReadSafe(m_strFieldName); string strB = b.Strings.ReadSafe(m_strFieldName); if(m_bCompareNaturally) return StrUtil.CompareNaturally(strA, strB); return string.Compare(strA, strB, m_bCaseInsensitive); } } } KeePassLib/KeePassLib.pfx0000664000000000000000000000333410576764760014266 0ustar rootroot00 *H 0}0 *H 00 *H  00 *H  05D?*dI& |i&fKG;#!΀%R[m)ZwQoT>ybv[O$Rd3OWo7c4;תBvft87 5SG LLP4AiF2L[+ )$as(Q+Oݷ+hț[#~)[jgriL8V(C3=JpzĺV 3:|<`N8+؃8, tjؚyD5֙,X2ut_."h/^+ɳ)oAL̒*Yv3V윎,J3kgLp/s(AqPԼH^˪Ͳ;6L$ 8̒/Ya\J7zl0+/eϬ!!v,(7w&ٝ|mQZmI];8FVW.";> r'E gӟ.4{j<(C ҉v9&g>+9= 9}z7Dݗ]2>y%o,^9߸E69Rd_yYaļI6h>'3s=7haT<$t\1BOJuHsw3dMBjW"F~aؒz>um+yj8S!X*ZР#D!;*q^1-28=p'>[ɠ> !\8CY5qM~}dWBx~I`߃m@%wz'mBqlCd |~E~Q4nvwm0d΢pJ4\Z46`W|Uc Ut10;00+&cr{ 5FL~!4Sqn.CKeePassLib/Serialization/0000775000000000000000000000000013223475706014366 5ustar rootrootKeePassLib/Serialization/FileLock.cs0000664000000000000000000001624213222430402016371 0ustar rootroot/* KeePass Password Safe - The Open-Source Password Manager Copyright (C) 2003-2018 Dominik Reichl This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ using System; using System.Collections.Generic; using System.Diagnostics; using System.IO; using System.Text; using System.Threading; using KeePassLib.Cryptography; using KeePassLib.Resources; using KeePassLib.Utility; namespace KeePassLib.Serialization { public sealed class FileLockException : Exception { private readonly string m_strMsg; public override string Message { get { return m_strMsg; } } public FileLockException(string strBaseFile, string strUser) { StringBuilder sb = new StringBuilder(); if(!string.IsNullOrEmpty(strBaseFile)) { sb.Append(strBaseFile); sb.Append(MessageService.NewParagraph); } sb.Append(KLRes.FileLockedWrite); sb.Append(MessageService.NewLine); if(!string.IsNullOrEmpty(strUser)) sb.Append(strUser); else sb.Append("?"); sb.Append(MessageService.NewParagraph); sb.Append(KLRes.TryAgainSecs); m_strMsg = sb.ToString(); } } public sealed class FileLock : IDisposable { private const string LockFileExt = ".lock"; private const string LockFileHeader = "KeePass Lock File"; private IOConnectionInfo m_iocLockFile; private sealed class LockFileInfo { public readonly string ID; public readonly DateTime Time; public readonly string UserName; public readonly string Machine; public readonly string Domain; private LockFileInfo(string strID, string strTime, string strUserName, string strMachine, string strDomain) { this.ID = (strID ?? string.Empty).Trim(); DateTime dt; if(TimeUtil.TryDeserializeUtc(strTime.Trim(), out dt)) this.Time = dt; else { Debug.Assert(false); this.Time = DateTime.UtcNow; } this.UserName = (strUserName ?? string.Empty).Trim(); this.Machine = (strMachine ?? string.Empty).Trim(); this.Domain = (strDomain ?? string.Empty).Trim(); if(this.Domain.Equals(this.Machine, StrUtil.CaseIgnoreCmp)) this.Domain = string.Empty; } public string GetOwner() { StringBuilder sb = new StringBuilder(); sb.Append((this.UserName.Length > 0) ? this.UserName : "?"); bool bMachine = (this.Machine.Length > 0); bool bDomain = (this.Domain.Length > 0); if(bMachine || bDomain) { sb.Append(" ("); sb.Append(this.Machine); if(bMachine && bDomain) sb.Append(" @ "); sb.Append(this.Domain); sb.Append(")"); } return sb.ToString(); } public static LockFileInfo Load(IOConnectionInfo iocLockFile) { Stream s = null; try { s = IOConnection.OpenRead(iocLockFile); if(s == null) return null; StreamReader sr = new StreamReader(s, StrUtil.Utf8); string str = sr.ReadToEnd(); sr.Close(); if(str == null) { Debug.Assert(false); return null; } str = StrUtil.NormalizeNewLines(str, false); string[] v = str.Split('\n'); if((v == null) || (v.Length < 6)) { Debug.Assert(false); return null; } if(!v[0].StartsWith(LockFileHeader)) { Debug.Assert(false); return null; } return new LockFileInfo(v[1], v[2], v[3], v[4], v[5]); } catch(FileNotFoundException) { } catch(Exception) { Debug.Assert(false); } finally { if(s != null) s.Close(); } return null; } // Throws on error public static LockFileInfo Create(IOConnectionInfo iocLockFile) { LockFileInfo lfi; Stream s = null; try { byte[] pbID = CryptoRandom.Instance.GetRandomBytes(16); string strTime = TimeUtil.SerializeUtc(DateTime.UtcNow); lfi = new LockFileInfo(Convert.ToBase64String(pbID), strTime, #if KeePassUAP EnvironmentExt.UserName, EnvironmentExt.MachineName, EnvironmentExt.UserDomainName); #elif KeePassLibSD string.Empty, string.Empty, string.Empty); #else Environment.UserName, Environment.MachineName, Environment.UserDomainName); #endif StringBuilder sb = new StringBuilder(); #if !KeePassLibSD sb.AppendLine(LockFileHeader); sb.AppendLine(lfi.ID); sb.AppendLine(strTime); sb.AppendLine(lfi.UserName); sb.AppendLine(lfi.Machine); sb.AppendLine(lfi.Domain); #else sb.Append(LockFileHeader + MessageService.NewLine); sb.Append(lfi.ID + MessageService.NewLine); sb.Append(strTime + MessageService.NewLine); sb.Append(lfi.UserName + MessageService.NewLine); sb.Append(lfi.Machine + MessageService.NewLine); sb.Append(lfi.Domain + MessageService.NewLine); #endif byte[] pbFile = StrUtil.Utf8.GetBytes(sb.ToString()); s = IOConnection.OpenWrite(iocLockFile); if(s == null) throw new IOException(iocLockFile.GetDisplayName()); s.Write(pbFile, 0, pbFile.Length); } finally { if(s != null) s.Close(); } return lfi; } } 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); } ~FileLock() { Dispose(false); } public void Dispose() { Dispose(true); GC.SuppressFinalize(this); } private void Dispose(bool bDisposing) { if(m_iocLockFile == null) return; bool bFileDeleted = false; for(int r = 0; r < 5; ++r) { // if(!OwnLockFile()) { bFileDeleted = true; break; } try { IOConnection.DeleteFile(m_iocLockFile); bFileDeleted = true; } catch(Exception) { Debug.Assert(false); } if(bFileDeleted) break; if(bDisposing) Thread.Sleep(50); } // if(bDisposing && !bFileDeleted) // IOConnection.DeleteFile(m_iocLockFile); // Possibly with exception m_iocLockFile = null; } // private bool OwnLockFile() // { // if(m_iocLockFile == null) { Debug.Assert(false); return false; } // if(m_strLockID == null) { Debug.Assert(false); return false; } // LockFileInfo lfi = LockFileInfo.Load(m_iocLockFile); // if(lfi == null) return false; // return m_strLockID.Equals(lfi.ID); // } } } KeePassLib/Serialization/BinaryReaderEx.cs0000664000000000000000000000477613222430402017556 0ustar rootroot/* KeePass Password Safe - The Open-Source Password Manager Copyright (C) 2003-2018 Dominik Reichl This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ using System; using System.Collections.Generic; using System.IO; using System.Text; using KeePassLib.Utility; namespace KeePassLib.Serialization { public sealed class BinaryReaderEx { private Stream m_s; // private Encoding m_enc; // See constructor private string m_strReadExcp; // May be null public string ReadExceptionText { get { return m_strReadExcp; } set { m_strReadExcp = value; } } private Stream m_sCopyTo = null; /// /// If this property is set to a non-null stream, all data that /// is read from the input stream is automatically written to /// the copy stream (before returning the read data). /// public Stream CopyDataTo { get { return m_sCopyTo; } set { m_sCopyTo = value; } } public BinaryReaderEx(Stream input, Encoding encoding, string strReadExceptionText) { if(input == null) throw new ArgumentNullException("input"); m_s = input; // m_enc = encoding; // Not used yet m_strReadExcp = strReadExceptionText; } public byte[] ReadBytes(int nCount) { try { byte[] pb = MemUtil.Read(m_s, nCount); if((pb == null) || (pb.Length != nCount)) { if(!string.IsNullOrEmpty(m_strReadExcp)) throw new EndOfStreamException(m_strReadExcp); else throw new EndOfStreamException(); } if(m_sCopyTo != null) m_sCopyTo.Write(pb, 0, pb.Length); return pb; } catch(Exception) { if(!string.IsNullOrEmpty(m_strReadExcp)) throw new IOException(m_strReadExcp); else throw; } } public byte ReadByte() { byte[] pb = ReadBytes(1); return pb[0]; } } } KeePassLib/Serialization/KdbxFile.Write.cs0000664000000000000000000010101013222430402017446 0ustar rootroot/* KeePass Password Safe - The Open-Source Password Manager Copyright (C) 2003-2018 Dominik Reichl This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ using System; using System.Collections.Generic; using System.Diagnostics; using System.Globalization; using System.IO; using System.Security; using System.Text; using System.Xml; #if !KeePassUAP using System.Drawing; using System.Security.Cryptography; #endif #if KeePassLibSD using KeePassLibSD; #else using System.IO.Compression; #endif using KeePassLib.Collections; using KeePassLib.Cryptography; using KeePassLib.Cryptography.Cipher; using KeePassLib.Cryptography.KeyDerivation; using KeePassLib.Delegates; using KeePassLib.Interfaces; using KeePassLib.Keys; using KeePassLib.Resources; using KeePassLib.Security; using KeePassLib.Utility; namespace KeePassLib.Serialization { /// /// Serialization to KeePass KDBX files. /// public sealed partial class KdbxFile { // public void Save(string strFile, PwGroup pgDataSource, KdbxFormat fmt, // IStatusLogger slLogger) // { // bool bMadeUnhidden = UrlUtil.UnhideFile(strFile); // // IOConnectionInfo ioc = IOConnectionInfo.FromPath(strFile); // this.Save(IOConnection.OpenWrite(ioc), pgDataSource, format, slLogger); // // if(bMadeUnhidden) UrlUtil.HideFile(strFile, true); // Hide again // } /// /// Save the contents of the current PwDatabase to a KDBX file. /// /// Stream to write the KDBX file into. /// Group containing all groups and /// entries to write. If null, the complete database will /// be written. /// Format of the file to create. /// Logger that recieves status information. public void Save(Stream sSaveTo, PwGroup pgDataSource, KdbxFormat fmt, IStatusLogger slLogger) { Debug.Assert(sSaveTo != null); if(sSaveTo == null) throw new ArgumentNullException("sSaveTo"); if(m_bUsedOnce) throw new InvalidOperationException("Do not reuse KdbxFile objects!"); m_bUsedOnce = true; m_format = fmt; m_slLogger = slLogger; PwGroup pgRoot = (pgDataSource ?? m_pwDatabase.RootGroup); UTF8Encoding encNoBom = StrUtil.Utf8; CryptoRandom cr = CryptoRandom.Instance; byte[] pbCipherKey = null; byte[] pbHmacKey64 = null; m_pbsBinaries.Clear(); m_pbsBinaries.AddFrom(pgRoot); List lStreams = new List(); lStreams.Add(sSaveTo); HashingStreamEx sHashing = new HashingStreamEx(sSaveTo, true, null); lStreams.Add(sHashing); try { m_uFileVersion = GetMinKdbxVersion(); int cbEncKey, cbEncIV; ICipherEngine iCipher = GetCipher(out cbEncKey, out cbEncIV); m_pbMasterSeed = cr.GetRandomBytes(32); m_pbEncryptionIV = cr.GetRandomBytes((uint)cbEncIV); // m_pbTransformSeed = cr.GetRandomBytes(32); PwUuid puKdf = m_pwDatabase.KdfParameters.KdfUuid; KdfEngine kdf = KdfPool.Get(puKdf); if(kdf == null) throw new Exception(KLRes.UnknownKdf + MessageService.NewParagraph + // KLRes.FileNewVerOrPlgReq + MessageService.NewParagraph + "UUID: " + puKdf.ToHexString() + "."); kdf.Randomize(m_pwDatabase.KdfParameters); if(m_format == KdbxFormat.Default) { if(m_uFileVersion < FileVersion32_4) { m_craInnerRandomStream = CrsAlgorithm.Salsa20; m_pbInnerRandomStreamKey = cr.GetRandomBytes(32); } else // KDBX >= 4 { m_craInnerRandomStream = CrsAlgorithm.ChaCha20; m_pbInnerRandomStreamKey = cr.GetRandomBytes(64); } m_randomStream = new CryptoRandomStream(m_craInnerRandomStream, m_pbInnerRandomStreamKey); } if(m_uFileVersion < FileVersion32_4) m_pbStreamStartBytes = cr.GetRandomBytes(32); Stream sXml; if(m_format == KdbxFormat.Default) { byte[] pbHeader = GenerateHeader(); m_pbHashOfHeader = CryptoUtil.HashSha256(pbHeader); MemUtil.Write(sHashing, pbHeader); sHashing.Flush(); ComputeKeys(out pbCipherKey, cbEncKey, out pbHmacKey64); Stream sPlain; if(m_uFileVersion < FileVersion32_4) { Stream sEncrypted = EncryptStream(sHashing, iCipher, pbCipherKey, cbEncIV, true); if((sEncrypted == null) || (sEncrypted == sHashing)) throw new SecurityException(KLRes.CryptoStreamFailed); lStreams.Add(sEncrypted); MemUtil.Write(sEncrypted, m_pbStreamStartBytes); sPlain = new HashedBlockStream(sEncrypted, true); } else // KDBX >= 4 { // For integrity checking (without knowing the master key) MemUtil.Write(sHashing, m_pbHashOfHeader); byte[] pbHeaderHmac = ComputeHeaderHmac(pbHeader, pbHmacKey64); MemUtil.Write(sHashing, pbHeaderHmac); Stream sBlocks = new HmacBlockStream(sHashing, true, true, pbHmacKey64); lStreams.Add(sBlocks); sPlain = EncryptStream(sBlocks, iCipher, pbCipherKey, cbEncIV, true); if((sPlain == null) || (sPlain == sBlocks)) throw new SecurityException(KLRes.CryptoStreamFailed); } lStreams.Add(sPlain); if(m_pwDatabase.Compression == PwCompressionAlgorithm.GZip) { sXml = new GZipStream(sPlain, CompressionMode.Compress); lStreams.Add(sXml); } else sXml = sPlain; if(m_uFileVersion >= FileVersion32_4) WriteInnerHeader(sXml); // Binary header before XML } else if(m_format == KdbxFormat.PlainXml) sXml = sHashing; else { Debug.Assert(false); throw new ArgumentOutOfRangeException("fmt"); } #if KeePassUAP XmlWriterSettings xws = new XmlWriterSettings(); xws.Encoding = encNoBom; xws.Indent = true; xws.IndentChars = "\t"; xws.NewLineOnAttributes = false; XmlWriter xw = XmlWriter.Create(sXml, xws); #else XmlTextWriter xw = new XmlTextWriter(sXml, encNoBom); xw.Formatting = Formatting.Indented; xw.IndentChar = '\t'; xw.Indentation = 1; #endif m_xmlWriter = xw; WriteDocument(pgRoot); m_xmlWriter.Flush(); m_xmlWriter.Close(); } finally { if(pbCipherKey != null) MemUtil.ZeroByteArray(pbCipherKey); if(pbHmacKey64 != null) MemUtil.ZeroByteArray(pbHmacKey64); CommonCleanUpWrite(lStreams, sHashing); } } private void CommonCleanUpWrite(List lStreams, HashingStreamEx sHashing) { CloseStreams(lStreams); Debug.Assert(lStreams.Contains(sHashing)); // sHashing must be closed m_pbHashOfFileOnDisk = sHashing.Hash; Debug.Assert(m_pbHashOfFileOnDisk != null); CleanUpInnerRandomStream(); m_xmlWriter = null; m_pbHashOfHeader = null; } private byte[] GenerateHeader() { byte[] pbHeader; using(MemoryStream ms = new MemoryStream()) { MemUtil.Write(ms, MemUtil.UInt32ToBytes(FileSignature1)); MemUtil.Write(ms, MemUtil.UInt32ToBytes(FileSignature2)); MemUtil.Write(ms, MemUtil.UInt32ToBytes(m_uFileVersion)); WriteHeaderField(ms, KdbxHeaderFieldID.CipherID, m_pwDatabase.DataCipherUuid.UuidBytes); int nCprID = (int)m_pwDatabase.Compression; WriteHeaderField(ms, KdbxHeaderFieldID.CompressionFlags, MemUtil.UInt32ToBytes((uint)nCprID)); WriteHeaderField(ms, KdbxHeaderFieldID.MasterSeed, m_pbMasterSeed); if(m_uFileVersion < FileVersion32_4) { Debug.Assert(m_pwDatabase.KdfParameters.KdfUuid.Equals( (new AesKdf()).Uuid)); WriteHeaderField(ms, KdbxHeaderFieldID.TransformSeed, m_pwDatabase.KdfParameters.GetByteArray(AesKdf.ParamSeed)); WriteHeaderField(ms, KdbxHeaderFieldID.TransformRounds, MemUtil.UInt64ToBytes(m_pwDatabase.KdfParameters.GetUInt64( AesKdf.ParamRounds, PwDefs.DefaultKeyEncryptionRounds))); } else WriteHeaderField(ms, KdbxHeaderFieldID.KdfParameters, KdfParameters.SerializeExt(m_pwDatabase.KdfParameters)); if(m_pbEncryptionIV.Length > 0) WriteHeaderField(ms, KdbxHeaderFieldID.EncryptionIV, m_pbEncryptionIV); if(m_uFileVersion < FileVersion32_4) { WriteHeaderField(ms, KdbxHeaderFieldID.InnerRandomStreamKey, m_pbInnerRandomStreamKey); WriteHeaderField(ms, KdbxHeaderFieldID.StreamStartBytes, m_pbStreamStartBytes); int nIrsID = (int)m_craInnerRandomStream; WriteHeaderField(ms, KdbxHeaderFieldID.InnerRandomStreamID, MemUtil.Int32ToBytes(nIrsID)); } // Write public custom data only when there is at least one item, // because KDBX 3.1 didn't support this field yet if(m_pwDatabase.PublicCustomData.Count > 0) WriteHeaderField(ms, KdbxHeaderFieldID.PublicCustomData, VariantDictionary.Serialize(m_pwDatabase.PublicCustomData)); WriteHeaderField(ms, KdbxHeaderFieldID.EndOfHeader, new byte[] { (byte)'\r', (byte)'\n', (byte)'\r', (byte)'\n' }); pbHeader = ms.ToArray(); } return pbHeader; } private void WriteHeaderField(Stream s, KdbxHeaderFieldID kdbID, byte[] pbData) { s.WriteByte((byte)kdbID); byte[] pb = (pbData ?? MemUtil.EmptyByteArray); int cb = pb.Length; if(cb < 0) { Debug.Assert(false); throw new OutOfMemoryException(); } Debug.Assert(m_uFileVersion > 0); if(m_uFileVersion < FileVersion32_4) { if(cb > (int)ushort.MaxValue) { Debug.Assert(false); throw new ArgumentOutOfRangeException("pbData"); } MemUtil.Write(s, MemUtil.UInt16ToBytes((ushort)cb)); } else MemUtil.Write(s, MemUtil.Int32ToBytes(cb)); MemUtil.Write(s, pb); } private void WriteInnerHeader(Stream s) { int nIrsID = (int)m_craInnerRandomStream; WriteInnerHeaderField(s, KdbxInnerHeaderFieldID.InnerRandomStreamID, MemUtil.Int32ToBytes(nIrsID), null); WriteInnerHeaderField(s, KdbxInnerHeaderFieldID.InnerRandomStreamKey, m_pbInnerRandomStreamKey, null); ProtectedBinary[] vBin = m_pbsBinaries.ToArray(); for(int i = 0; i < vBin.Length; ++i) { ProtectedBinary pb = vBin[i]; if(pb == null) throw new InvalidOperationException(); KdbxBinaryFlags f = KdbxBinaryFlags.None; if(pb.IsProtected) f |= KdbxBinaryFlags.Protected; byte[] pbFlags = new byte[1] { (byte)f }; byte[] pbData = pb.ReadData(); WriteInnerHeaderField(s, KdbxInnerHeaderFieldID.Binary, pbFlags, pbData); if(pb.IsProtected) MemUtil.ZeroByteArray(pbData); } WriteInnerHeaderField(s, KdbxInnerHeaderFieldID.EndOfHeader, null, null); } private void WriteInnerHeaderField(Stream s, KdbxInnerHeaderFieldID kdbID, byte[] pbData1, byte[] pbData2) { s.WriteByte((byte)kdbID); byte[] pb1 = (pbData1 ?? MemUtil.EmptyByteArray); byte[] pb2 = (pbData2 ?? MemUtil.EmptyByteArray); int cb = pb1.Length + pb2.Length; if(cb < 0) { Debug.Assert(false); throw new OutOfMemoryException(); } MemUtil.Write(s, MemUtil.Int32ToBytes(cb)); MemUtil.Write(s, pb1); MemUtil.Write(s, pb2); } private void WriteDocument(PwGroup pgRoot) { Debug.Assert(m_xmlWriter != null); if(m_xmlWriter == null) throw new InvalidOperationException(); uint uNumGroups, uNumEntries, uCurEntry = 0; pgRoot.GetCounts(true, out uNumGroups, out uNumEntries); m_xmlWriter.WriteStartDocument(true); m_xmlWriter.WriteStartElement(ElemDocNode); WriteMeta(); m_xmlWriter.WriteStartElement(ElemRoot); StartGroup(pgRoot); Stack groupStack = new Stack(); groupStack.Push(pgRoot); GroupHandler gh = delegate(PwGroup pg) { Debug.Assert(pg != null); if(pg == null) throw new ArgumentNullException("pg"); while(true) { if(pg.ParentGroup == groupStack.Peek()) { groupStack.Push(pg); StartGroup(pg); break; } else { groupStack.Pop(); if(groupStack.Count <= 0) return false; EndGroup(); } } return true; }; EntryHandler eh = delegate(PwEntry pe) { Debug.Assert(pe != null); WriteEntry(pe, false); ++uCurEntry; if(m_slLogger != null) if(!m_slLogger.SetProgress((100 * uCurEntry) / uNumEntries)) return false; return true; }; if(!pgRoot.TraverseTree(TraversalMethod.PreOrder, gh, eh)) throw new InvalidOperationException(); while(groupStack.Count > 1) { m_xmlWriter.WriteEndElement(); groupStack.Pop(); } EndGroup(); WriteList(ElemDeletedObjects, m_pwDatabase.DeletedObjects); m_xmlWriter.WriteEndElement(); // Root m_xmlWriter.WriteEndElement(); // ElemDocNode m_xmlWriter.WriteEndDocument(); } private void WriteMeta() { m_xmlWriter.WriteStartElement(ElemMeta); WriteObject(ElemGenerator, PwDatabase.LocalizedAppName, false); if((m_pbHashOfHeader != null) && (m_uFileVersion < FileVersion32_4)) WriteObject(ElemHeaderHash, Convert.ToBase64String( m_pbHashOfHeader), false); if(m_uFileVersion >= FileVersion32_4) WriteObject(ElemSettingsChanged, m_pwDatabase.SettingsChanged); WriteObject(ElemDbName, m_pwDatabase.Name, true); WriteObject(ElemDbNameChanged, m_pwDatabase.NameChanged); WriteObject(ElemDbDesc, m_pwDatabase.Description, true); WriteObject(ElemDbDescChanged, m_pwDatabase.DescriptionChanged); WriteObject(ElemDbDefaultUser, m_pwDatabase.DefaultUserName, true); WriteObject(ElemDbDefaultUserChanged, m_pwDatabase.DefaultUserNameChanged); WriteObject(ElemDbMntncHistoryDays, m_pwDatabase.MaintenanceHistoryDays); WriteObject(ElemDbColor, StrUtil.ColorToUnnamedHtml(m_pwDatabase.Color, true), false); WriteObject(ElemDbKeyChanged, m_pwDatabase.MasterKeyChanged); WriteObject(ElemDbKeyChangeRec, m_pwDatabase.MasterKeyChangeRec); WriteObject(ElemDbKeyChangeForce, m_pwDatabase.MasterKeyChangeForce); if(m_pwDatabase.MasterKeyChangeForceOnce) WriteObject(ElemDbKeyChangeForceOnce, true); WriteList(ElemMemoryProt, m_pwDatabase.MemoryProtection); WriteCustomIconList(); WriteObject(ElemRecycleBinEnabled, m_pwDatabase.RecycleBinEnabled); WriteObject(ElemRecycleBinUuid, m_pwDatabase.RecycleBinUuid); WriteObject(ElemRecycleBinChanged, m_pwDatabase.RecycleBinChanged); WriteObject(ElemEntryTemplatesGroup, m_pwDatabase.EntryTemplatesGroup); WriteObject(ElemEntryTemplatesGroupChanged, m_pwDatabase.EntryTemplatesGroupChanged); WriteObject(ElemHistoryMaxItems, m_pwDatabase.HistoryMaxItems); WriteObject(ElemHistoryMaxSize, m_pwDatabase.HistoryMaxSize); WriteObject(ElemLastSelectedGroup, m_pwDatabase.LastSelectedGroup); WriteObject(ElemLastTopVisibleGroup, m_pwDatabase.LastTopVisibleGroup); if((m_format != KdbxFormat.Default) || (m_uFileVersion < FileVersion32_4)) WriteBinPool(); WriteList(ElemCustomData, m_pwDatabase.CustomData); m_xmlWriter.WriteEndElement(); } private void StartGroup(PwGroup pg) { m_xmlWriter.WriteStartElement(ElemGroup); WriteObject(ElemUuid, pg.Uuid); WriteObject(ElemName, pg.Name, true); WriteObject(ElemNotes, pg.Notes, true); WriteObject(ElemIcon, (int)pg.IconId); if(!pg.CustomIconUuid.Equals(PwUuid.Zero)) WriteObject(ElemCustomIconID, pg.CustomIconUuid); WriteList(ElemTimes, pg); WriteObject(ElemIsExpanded, pg.IsExpanded); WriteObject(ElemGroupDefaultAutoTypeSeq, pg.DefaultAutoTypeSequence, true); WriteObject(ElemEnableAutoType, StrUtil.BoolToStringEx(pg.EnableAutoType), false); WriteObject(ElemEnableSearching, StrUtil.BoolToStringEx(pg.EnableSearching), false); WriteObject(ElemLastTopVisibleEntry, pg.LastTopVisibleEntry); if(pg.CustomData.Count > 0) WriteList(ElemCustomData, pg.CustomData); } private void EndGroup() { m_xmlWriter.WriteEndElement(); // Close group element } private void WriteEntry(PwEntry pe, bool bIsHistory) { Debug.Assert(pe != null); if(pe == null) throw new ArgumentNullException("pe"); m_xmlWriter.WriteStartElement(ElemEntry); WriteObject(ElemUuid, pe.Uuid); WriteObject(ElemIcon, (int)pe.IconId); if(!pe.CustomIconUuid.Equals(PwUuid.Zero)) WriteObject(ElemCustomIconID, pe.CustomIconUuid); WriteObject(ElemFgColor, StrUtil.ColorToUnnamedHtml(pe.ForegroundColor, true), false); WriteObject(ElemBgColor, StrUtil.ColorToUnnamedHtml(pe.BackgroundColor, true), false); WriteObject(ElemOverrideUrl, pe.OverrideUrl, true); WriteObject(ElemTags, StrUtil.TagsToString(pe.Tags, false), true); WriteList(ElemTimes, pe); WriteList(pe.Strings, true); WriteList(pe.Binaries); WriteList(ElemAutoType, pe.AutoType); if(pe.CustomData.Count > 0) WriteList(ElemCustomData, pe.CustomData); if(!bIsHistory) WriteList(ElemHistory, pe.History, true); else { Debug.Assert(pe.History.UCount == 0); } m_xmlWriter.WriteEndElement(); } private void WriteList(ProtectedStringDictionary dictStrings, bool bEntryStrings) { Debug.Assert(dictStrings != null); if(dictStrings == null) throw new ArgumentNullException("dictStrings"); foreach(KeyValuePair kvp in dictStrings) WriteObject(kvp.Key, kvp.Value, bEntryStrings); } private void WriteList(ProtectedBinaryDictionary dictBinaries) { Debug.Assert(dictBinaries != null); if(dictBinaries == null) throw new ArgumentNullException("dictBinaries"); foreach(KeyValuePair kvp in dictBinaries) WriteObject(kvp.Key, kvp.Value, true); } private void WriteList(string name, AutoTypeConfig cfgAutoType) { Debug.Assert(name != null); Debug.Assert(cfgAutoType != null); if(cfgAutoType == null) throw new ArgumentNullException("cfgAutoType"); m_xmlWriter.WriteStartElement(name); WriteObject(ElemAutoTypeEnabled, cfgAutoType.Enabled); WriteObject(ElemAutoTypeObfuscation, (int)cfgAutoType.ObfuscationOptions); if(cfgAutoType.DefaultSequence.Length > 0) WriteObject(ElemAutoTypeDefaultSeq, cfgAutoType.DefaultSequence, true); foreach(AutoTypeAssociation a in cfgAutoType.Associations) WriteObject(ElemAutoTypeItem, ElemWindow, ElemKeystrokeSequence, new KeyValuePair(a.WindowName, a.Sequence)); m_xmlWriter.WriteEndElement(); } private void WriteList(string name, ITimeLogger times) { Debug.Assert(name != null); Debug.Assert(times != null); if(times == null) throw new ArgumentNullException("times"); m_xmlWriter.WriteStartElement(name); WriteObject(ElemCreationTime, times.CreationTime); WriteObject(ElemLastModTime, times.LastModificationTime); WriteObject(ElemLastAccessTime, times.LastAccessTime); WriteObject(ElemExpiryTime, times.ExpiryTime); WriteObject(ElemExpires, times.Expires); WriteObject(ElemUsageCount, times.UsageCount); WriteObject(ElemLocationChanged, times.LocationChanged); m_xmlWriter.WriteEndElement(); // Name } private void WriteList(string name, PwObjectList value, bool bIsHistory) { Debug.Assert(name != null); Debug.Assert(value != null); if(value == null) throw new ArgumentNullException("value"); m_xmlWriter.WriteStartElement(name); foreach(PwEntry pe in value) WriteEntry(pe, bIsHistory); m_xmlWriter.WriteEndElement(); } private void WriteList(string name, PwObjectList value) { Debug.Assert(name != null); Debug.Assert(value != null); if(value == null) throw new ArgumentNullException("value"); m_xmlWriter.WriteStartElement(name); foreach(PwDeletedObject pdo in value) WriteObject(ElemDeletedObject, pdo); m_xmlWriter.WriteEndElement(); } private void WriteList(string name, MemoryProtectionConfig value) { Debug.Assert(name != null); Debug.Assert(value != null); m_xmlWriter.WriteStartElement(name); WriteObject(ElemProtTitle, value.ProtectTitle); WriteObject(ElemProtUserName, value.ProtectUserName); WriteObject(ElemProtPassword, value.ProtectPassword); WriteObject(ElemProtUrl, value.ProtectUrl); WriteObject(ElemProtNotes, value.ProtectNotes); // WriteObject(ElemProtAutoHide, value.AutoEnableVisualHiding); m_xmlWriter.WriteEndElement(); } private void WriteList(string name, StringDictionaryEx value) { Debug.Assert(name != null); Debug.Assert(value != null); if(value == null) throw new ArgumentNullException("value"); m_xmlWriter.WriteStartElement(name); foreach(KeyValuePair kvp in value) WriteObject(ElemStringDictExItem, ElemKey, ElemValue, kvp); m_xmlWriter.WriteEndElement(); } private void WriteCustomIconList() { if(m_pwDatabase.CustomIcons.Count == 0) return; m_xmlWriter.WriteStartElement(ElemCustomIcons); foreach(PwCustomIcon pwci in m_pwDatabase.CustomIcons) { m_xmlWriter.WriteStartElement(ElemCustomIconItem); WriteObject(ElemCustomIconItemID, pwci.Uuid); string strData = Convert.ToBase64String(pwci.ImageDataPng); WriteObject(ElemCustomIconItemData, strData, false); m_xmlWriter.WriteEndElement(); } m_xmlWriter.WriteEndElement(); } private void WriteObject(string name, string value, bool bFilterValueXmlChars) { Debug.Assert(name != null); Debug.Assert(value != null); m_xmlWriter.WriteStartElement(name); if(bFilterValueXmlChars) m_xmlWriter.WriteString(StrUtil.SafeXmlString(value)); else m_xmlWriter.WriteString(value); m_xmlWriter.WriteEndElement(); } private void WriteObject(string name, bool value) { Debug.Assert(name != null); WriteObject(name, value ? ValTrue : ValFalse, false); } private void WriteObject(string name, PwUuid value) { Debug.Assert(name != null); Debug.Assert(value != null); if(value == null) throw new ArgumentNullException("value"); WriteObject(name, Convert.ToBase64String(value.UuidBytes), false); } private void WriteObject(string name, int value) { Debug.Assert(name != null); m_xmlWriter.WriteStartElement(name); m_xmlWriter.WriteString(value.ToString(NumberFormatInfo.InvariantInfo)); m_xmlWriter.WriteEndElement(); } private void WriteObject(string name, uint value) { Debug.Assert(name != null); m_xmlWriter.WriteStartElement(name); m_xmlWriter.WriteString(value.ToString(NumberFormatInfo.InvariantInfo)); m_xmlWriter.WriteEndElement(); } private void WriteObject(string name, long value) { Debug.Assert(name != null); m_xmlWriter.WriteStartElement(name); m_xmlWriter.WriteString(value.ToString(NumberFormatInfo.InvariantInfo)); m_xmlWriter.WriteEndElement(); } private void WriteObject(string name, ulong value) { Debug.Assert(name != null); m_xmlWriter.WriteStartElement(name); m_xmlWriter.WriteString(value.ToString(NumberFormatInfo.InvariantInfo)); m_xmlWriter.WriteEndElement(); } private void WriteObject(string name, DateTime value) { Debug.Assert(name != null); Debug.Assert(value.Kind == DateTimeKind.Utc); // Cf. ReadTime if((m_format == KdbxFormat.Default) && (m_uFileVersion >= FileVersion32_4)) { DateTime dt = TimeUtil.ToUtc(value, false); // DateTime dtBase = new DateTime(2000, 1, 1, 0, 0, 0, DateTimeKind.Utc); // dt -= new TimeSpan(dtBase.Ticks); // WriteObject(name, dt.ToBinary()); // dt = TimeUtil.RoundToMultOf2PowLess1s(dt); // long lBin = dt.ToBinary(); long lSec = dt.Ticks / TimeSpan.TicksPerSecond; // WriteObject(name, lSec); byte[] pb = MemUtil.Int64ToBytes(lSec); WriteObject(name, Convert.ToBase64String(pb), false); } else WriteObject(name, TimeUtil.SerializeUtc(value), false); } private void WriteObject(string name, string strKeyName, string strValueName, KeyValuePair kvp) { m_xmlWriter.WriteStartElement(name); m_xmlWriter.WriteStartElement(strKeyName); m_xmlWriter.WriteString(StrUtil.SafeXmlString(kvp.Key)); m_xmlWriter.WriteEndElement(); m_xmlWriter.WriteStartElement(strValueName); m_xmlWriter.WriteString(StrUtil.SafeXmlString(kvp.Value)); m_xmlWriter.WriteEndElement(); m_xmlWriter.WriteEndElement(); } private void WriteObject(string name, ProtectedString value, bool bIsEntryString) { Debug.Assert(name != null); Debug.Assert(value != null); if(value == null) throw new ArgumentNullException("value"); m_xmlWriter.WriteStartElement(ElemString); m_xmlWriter.WriteStartElement(ElemKey); m_xmlWriter.WriteString(StrUtil.SafeXmlString(name)); m_xmlWriter.WriteEndElement(); m_xmlWriter.WriteStartElement(ElemValue); bool bProtected = value.IsProtected; if(bIsEntryString) { // Adjust memory protection setting (which might be different // from the database default, e.g. due to an import which // didn't specify the correct setting) if(name == PwDefs.TitleField) bProtected = m_pwDatabase.MemoryProtection.ProtectTitle; else if(name == PwDefs.UserNameField) bProtected = m_pwDatabase.MemoryProtection.ProtectUserName; else if(name == PwDefs.PasswordField) bProtected = m_pwDatabase.MemoryProtection.ProtectPassword; else if(name == PwDefs.UrlField) bProtected = m_pwDatabase.MemoryProtection.ProtectUrl; else if(name == PwDefs.NotesField) bProtected = m_pwDatabase.MemoryProtection.ProtectNotes; } if(bProtected && (m_format == KdbxFormat.Default)) { m_xmlWriter.WriteAttributeString(AttrProtected, ValTrue); byte[] pbEncoded = value.ReadXorredString(m_randomStream); if(pbEncoded.Length > 0) m_xmlWriter.WriteBase64(pbEncoded, 0, pbEncoded.Length); } else { string strValue = value.ReadString(); // If names should be localized, we need to apply the language-dependent // string transformation here. By default, language-dependent conversions // should be applied, otherwise characters could be rendered incorrectly // (code page problems). if(m_bLocalizedNames) { StringBuilder sb = new StringBuilder(); foreach(char ch in strValue) { char chMapped = ch; // Symbols and surrogates must be moved into the correct code // page area if(char.IsSymbol(ch) || char.IsSurrogate(ch)) { System.Globalization.UnicodeCategory cat = CharUnicodeInfo.GetUnicodeCategory(ch); // Map character to correct position in code page chMapped = (char)((int)cat * 32 + ch); } else if(char.IsControl(ch)) { if(ch >= 256) // Control character in high ANSI code page { // Some of the control characters map to corresponding ones // in the low ANSI range (up to 255) when calling // ToLower on them with invariant culture (see // http://lists.ximian.com/pipermail/mono-patches/2002-February/086106.html ) #if !KeePassLibSD chMapped = char.ToLowerInvariant(ch); #else chMapped = char.ToLower(ch); #endif } } sb.Append(chMapped); } strValue = sb.ToString(); // Correct string for current code page } if((m_format == KdbxFormat.PlainXml) && bProtected) m_xmlWriter.WriteAttributeString(AttrProtectedInMemPlainXml, ValTrue); m_xmlWriter.WriteString(StrUtil.SafeXmlString(strValue)); } m_xmlWriter.WriteEndElement(); // ElemValue m_xmlWriter.WriteEndElement(); // ElemString } private void WriteObject(string name, ProtectedBinary value, bool bAllowRef) { Debug.Assert(name != null); Debug.Assert(value != null); if(value == null) throw new ArgumentNullException("value"); m_xmlWriter.WriteStartElement(ElemBinary); m_xmlWriter.WriteStartElement(ElemKey); m_xmlWriter.WriteString(StrUtil.SafeXmlString(name)); m_xmlWriter.WriteEndElement(); m_xmlWriter.WriteStartElement(ElemValue); string strRef = null; if(bAllowRef) { int iRef = m_pbsBinaries.Find(value); if(iRef >= 0) strRef = iRef.ToString(NumberFormatInfo.InvariantInfo); else { Debug.Assert(false); } } if(strRef != null) m_xmlWriter.WriteAttributeString(AttrRef, strRef); else SubWriteValue(value); m_xmlWriter.WriteEndElement(); // ElemValue m_xmlWriter.WriteEndElement(); // ElemBinary } private void SubWriteValue(ProtectedBinary value) { if(value.IsProtected && (m_format == KdbxFormat.Default)) { m_xmlWriter.WriteAttributeString(AttrProtected, ValTrue); byte[] pbEncoded = value.ReadXorredData(m_randomStream); if(pbEncoded.Length > 0) m_xmlWriter.WriteBase64(pbEncoded, 0, pbEncoded.Length); } else { if(m_pwDatabase.Compression != PwCompressionAlgorithm.None) { m_xmlWriter.WriteAttributeString(AttrCompressed, ValTrue); byte[] pbRaw = value.ReadData(); byte[] pbCmp = MemUtil.Compress(pbRaw); m_xmlWriter.WriteBase64(pbCmp, 0, pbCmp.Length); if(value.IsProtected) { MemUtil.ZeroByteArray(pbRaw); MemUtil.ZeroByteArray(pbCmp); } } else { byte[] pbRaw = value.ReadData(); m_xmlWriter.WriteBase64(pbRaw, 0, pbRaw.Length); if(value.IsProtected) MemUtil.ZeroByteArray(pbRaw); } } } private void WriteObject(string name, PwDeletedObject value) { Debug.Assert(name != null); Debug.Assert(value != null); if(value == null) throw new ArgumentNullException("value"); m_xmlWriter.WriteStartElement(name); WriteObject(ElemUuid, value.Uuid); WriteObject(ElemDeletionTime, value.DeletionTime); m_xmlWriter.WriteEndElement(); } private void WriteBinPool() { m_xmlWriter.WriteStartElement(ElemBinaries); ProtectedBinary[] v = m_pbsBinaries.ToArray(); for(int i = 0; i < v.Length; ++i) { m_xmlWriter.WriteStartElement(ElemBinary); m_xmlWriter.WriteAttributeString(AttrId, i.ToString(NumberFormatInfo.InvariantInfo)); SubWriteValue(v[i]); m_xmlWriter.WriteEndElement(); } m_xmlWriter.WriteEndElement(); } [Obsolete] public static bool WriteEntries(Stream msOutput, PwEntry[] vEntries) { return WriteEntries(msOutput, null, vEntries); } public static bool WriteEntries(Stream msOutput, PwDatabase pdContext, PwEntry[] vEntries) { if(msOutput == null) { Debug.Assert(false); return false; } // pdContext may be null if(vEntries == null) { Debug.Assert(false); return false; } /* KdbxFile f = new KdbxFile(pwDatabase); f.m_format = KdbxFormat.PlainXml; XmlTextWriter xtw = null; try { xtw = new XmlTextWriter(msOutput, StrUtil.Utf8); } catch(Exception) { Debug.Assert(false); return false; } if(xtw == null) { Debug.Assert(false); return false; } f.m_xmlWriter = xtw; xtw.Formatting = Formatting.Indented; xtw.IndentChar = '\t'; xtw.Indentation = 1; xtw.WriteStartDocument(true); xtw.WriteStartElement(ElemRoot); foreach(PwEntry pe in vEntries) f.WriteEntry(pe, false); xtw.WriteEndElement(); xtw.WriteEndDocument(); xtw.Flush(); xtw.Close(); return true; */ PwDatabase pd = new PwDatabase(); pd.New(new IOConnectionInfo(), new CompositeKey()); PwGroup pg = pd.RootGroup; if(pg == null) { Debug.Assert(false); return false; } foreach(PwEntry pe in vEntries) { PwUuid pu = pe.CustomIconUuid; if(!pu.Equals(PwUuid.Zero) && (pd.GetCustomIconIndex(pu) < 0)) { int i = -1; if(pdContext != null) i = pdContext.GetCustomIconIndex(pu); if(i >= 0) { PwCustomIcon ci = pdContext.CustomIcons[i]; pd.CustomIcons.Add(ci); } else { Debug.Assert(pdContext == null); } } PwEntry peCopy = pe.CloneDeep(); pg.AddEntry(peCopy, true); } KdbxFile f = new KdbxFile(pd); f.Save(msOutput, null, KdbxFormat.PlainXml, null); return true; } } } KeePassLib/Serialization/OldFormatException.cs0000664000000000000000000000350613222430402020446 0ustar rootroot/* KeePass Password Safe - The Open-Source Password Manager Copyright (C) 2003-2018 Dominik Reichl This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ using System; using System.Collections.Generic; using System.Text; using KeePassLib.Resources; using KeePassLib.Utility; namespace KeePassLib.Serialization { public sealed class OldFormatException : Exception { private string m_strFormat = string.Empty; private OldFormatType m_type = OldFormatType.Unknown; public enum OldFormatType { Unknown = 0, KeePass1x = 1 } public override string Message { get { string str = KLRes.OldFormat + ((m_strFormat.Length > 0) ? (@" (" + m_strFormat + @")") : string.Empty) + "."; if(m_type == OldFormatType.KeePass1x) str += MessageService.NewParagraph + KLRes.KeePass1xHint; return str; } } public OldFormatException(string strFormatName) { if(strFormatName != null) m_strFormat = strFormatName; } public OldFormatException(string strFormatName, OldFormatType t) { if(strFormatName != null) m_strFormat = strFormatName; m_type = t; } } } KeePassLib/Serialization/HashedBlockStream.cs0000664000000000000000000001715313222430402020226 0ustar rootroot/* KeePass Password Safe - The Open-Source Password Manager Copyright (C) 2003-2018 Dominik Reichl This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ using System; using System.Diagnostics; using System.IO; using System.Text; using KeePassLib.Cryptography; using KeePassLib.Native; using KeePassLib.Utility; #if KeePassLibSD using KeePassLibSD; #endif namespace KeePassLib.Serialization { public sealed class HashedBlockStream : Stream { private const int NbDefaultBufferSize = 1024 * 1024; // 1 MB private Stream m_sBaseStream; private bool m_bWriting; private bool m_bVerify; private bool m_bEos = false; private BinaryReader m_brInput; private BinaryWriter m_bwOutput; private byte[] m_pbBuffer; private int m_nBufferPos = 0; private uint m_uBlockIndex = 0; public override bool CanRead { get { return !m_bWriting; } } public override bool CanSeek { get { return false; } } public override bool CanWrite { get { return m_bWriting; } } public override long Length { get { Debug.Assert(false); throw new NotSupportedException(); } } public override long Position { get { Debug.Assert(false); throw new NotSupportedException(); } set { Debug.Assert(false); throw new NotSupportedException(); } } public HashedBlockStream(Stream sBaseStream, bool bWriting) { Initialize(sBaseStream, bWriting, 0, true); } public HashedBlockStream(Stream sBaseStream, bool bWriting, int nBufferSize) { Initialize(sBaseStream, bWriting, nBufferSize, true); } public HashedBlockStream(Stream sBaseStream, bool bWriting, int nBufferSize, bool bVerify) { Initialize(sBaseStream, bWriting, nBufferSize, bVerify); } private void Initialize(Stream sBaseStream, bool bWriting, int nBufferSize, bool bVerify) { if(sBaseStream == null) throw new ArgumentNullException("sBaseStream"); if(nBufferSize < 0) throw new ArgumentOutOfRangeException("nBufferSize"); if(nBufferSize == 0) nBufferSize = NbDefaultBufferSize; m_sBaseStream = sBaseStream; m_bWriting = bWriting; m_bVerify = bVerify; UTF8Encoding utf8 = StrUtil.Utf8; if(!m_bWriting) // Reading mode { if(!m_sBaseStream.CanRead) throw new InvalidOperationException(); m_brInput = new BinaryReader(sBaseStream, utf8); m_pbBuffer = MemUtil.EmptyByteArray; } else // Writing mode { if(!m_sBaseStream.CanWrite) throw new InvalidOperationException(); m_bwOutput = new BinaryWriter(sBaseStream, utf8); m_pbBuffer = new byte[nBufferSize]; } } protected override void Dispose(bool disposing) { if(disposing && (m_sBaseStream != null)) { if(!m_bWriting) // Reading mode { m_brInput.Close(); m_brInput = null; } else // Writing mode { if(m_nBufferPos == 0) // No data left in buffer WriteHashedBlock(); // Write terminating block else { WriteHashedBlock(); // Write remaining buffered data WriteHashedBlock(); // Write terminating block } Flush(); m_bwOutput.Close(); m_bwOutput = null; } m_sBaseStream.Close(); m_sBaseStream = null; } base.Dispose(disposing); } public override void Flush() { if(m_bWriting) m_bwOutput.Flush(); } public override long Seek(long lOffset, SeekOrigin soOrigin) { throw new NotSupportedException(); } public override void SetLength(long lValue) { throw new NotSupportedException(); } public override int Read(byte[] pbBuffer, int nOffset, int nCount) { if(m_bWriting) throw new InvalidOperationException(); int nRemaining = nCount; while(nRemaining > 0) { if(m_nBufferPos == m_pbBuffer.Length) { if(ReadHashedBlock() == false) return (nCount - nRemaining); // Bytes actually read } int nCopy = Math.Min(m_pbBuffer.Length - m_nBufferPos, nRemaining); Array.Copy(m_pbBuffer, m_nBufferPos, pbBuffer, nOffset, nCopy); nOffset += nCopy; m_nBufferPos += nCopy; nRemaining -= nCopy; } return nCount; } private bool ReadHashedBlock() { if(m_bEos) return false; // End of stream reached already m_nBufferPos = 0; if(m_brInput.ReadUInt32() != m_uBlockIndex) throw new InvalidDataException(); ++m_uBlockIndex; byte[] pbStoredHash = m_brInput.ReadBytes(32); if((pbStoredHash == null) || (pbStoredHash.Length != 32)) throw new InvalidDataException(); int nBufferSize = 0; try { nBufferSize = m_brInput.ReadInt32(); } catch(NullReferenceException) // Mono bug workaround (LaunchPad 783268) { if(!NativeLib.IsUnix()) throw; } if(nBufferSize < 0) throw new InvalidDataException(); if(nBufferSize == 0) { for(int iHash = 0; iHash < 32; ++iHash) { if(pbStoredHash[iHash] != 0) throw new InvalidDataException(); } m_bEos = true; m_pbBuffer = MemUtil.EmptyByteArray; return false; } m_pbBuffer = m_brInput.ReadBytes(nBufferSize); if((m_pbBuffer == null) || ((m_pbBuffer.Length != nBufferSize) && m_bVerify)) throw new InvalidDataException(); if(m_bVerify) { byte[] pbComputedHash = CryptoUtil.HashSha256(m_pbBuffer); if((pbComputedHash == null) || (pbComputedHash.Length != 32)) throw new InvalidOperationException(); if(!MemUtil.ArraysEqual(pbStoredHash, pbComputedHash)) throw new InvalidDataException(); } return true; } public override void Write(byte[] pbBuffer, int nOffset, int nCount) { if(!m_bWriting) throw new InvalidOperationException(); while(nCount > 0) { if(m_nBufferPos == m_pbBuffer.Length) WriteHashedBlock(); int nCopy = Math.Min(m_pbBuffer.Length - m_nBufferPos, nCount); Array.Copy(pbBuffer, nOffset, m_pbBuffer, m_nBufferPos, nCopy); nOffset += nCopy; m_nBufferPos += nCopy; nCount -= nCopy; } } private void WriteHashedBlock() { m_bwOutput.Write(m_uBlockIndex); ++m_uBlockIndex; if(m_nBufferPos > 0) { byte[] pbHash = CryptoUtil.HashSha256(m_pbBuffer, 0, m_nBufferPos); // For KeePassLibSD: // SHA256Managed sha256 = new SHA256Managed(); // byte[] pbHash; // if(m_nBufferPos == m_pbBuffer.Length) // pbHash = sha256.ComputeHash(m_pbBuffer); // else // { // byte[] pbData = new byte[m_nBufferPos]; // Array.Copy(m_pbBuffer, 0, pbData, 0, m_nBufferPos); // pbHash = sha256.ComputeHash(pbData); // } m_bwOutput.Write(pbHash); } else { m_bwOutput.Write((ulong)0); // Zero hash m_bwOutput.Write((ulong)0); m_bwOutput.Write((ulong)0); m_bwOutput.Write((ulong)0); } m_bwOutput.Write(m_nBufferPos); if(m_nBufferPos > 0) m_bwOutput.Write(m_pbBuffer, 0, m_nBufferPos); m_nBufferPos = 0; } } } KeePassLib/Serialization/IocProperties.cs0000664000000000000000000001170113222430402017463 0ustar rootroot/* KeePass Password Safe - The Open-Source Password Manager Copyright (C) 2003-2018 Dominik Reichl This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ using System; using System.Collections.Generic; using System.Diagnostics; using System.Globalization; using System.Text; using System.Xml; using KeePassLib.Interfaces; using KeePassLib.Utility; using StrDict = System.Collections.Generic.Dictionary; namespace KeePassLib.Serialization { public interface IHasIocProperties { IocProperties IOConnectionProperties { get; set; } } public sealed class IocProperties : IDeepCloneable { private StrDict m_dict = new StrDict(); public IocProperties() { } public IocProperties CloneDeep() { IocProperties p = new IocProperties(); p.m_dict = new StrDict(m_dict); return p; } public string Get(string strKey) { if(string.IsNullOrEmpty(strKey)) return null; foreach(KeyValuePair kvp in m_dict) { if(kvp.Key.Equals(strKey, StrUtil.CaseIgnoreCmp)) return kvp.Value; } return null; } public void Set(string strKey, string strValue) { if(string.IsNullOrEmpty(strKey)) { Debug.Assert(false); return; } foreach(KeyValuePair kvp in m_dict) { if(kvp.Key.Equals(strKey, StrUtil.CaseIgnoreCmp)) { if(string.IsNullOrEmpty(strValue)) m_dict.Remove(kvp.Key); else m_dict[kvp.Key] = strValue; return; } } if(!string.IsNullOrEmpty(strValue)) m_dict[strKey] = strValue; } public bool? GetBool(string strKey) { string str = Get(strKey); if(string.IsNullOrEmpty(str)) return null; return StrUtil.StringToBool(str); } public void SetBool(string strKey, bool? ob) { if(ob.HasValue) Set(strKey, (ob.Value ? "1" : "0")); else Set(strKey, null); } public long? GetLong(string strKey) { string str = Get(strKey); if(string.IsNullOrEmpty(str)) return null; long l; if(StrUtil.TryParseLongInvariant(str, out l)) return l; Debug.Assert(false); return null; } public void SetLong(string strKey, long? ol) { if(ol.HasValue) Set(strKey, ol.Value.ToString(NumberFormatInfo.InvariantInfo)); else Set(strKey, null); } public string Serialize() { if(m_dict.Count == 0) return string.Empty; StringBuilder sbAll = new StringBuilder(); foreach(KeyValuePair kvp in m_dict) { sbAll.Append(kvp.Key); sbAll.Append(kvp.Value); } string strAll = sbAll.ToString(); char chSepOuter = ';'; if(strAll.IndexOf(chSepOuter) >= 0) chSepOuter = StrUtil.GetUnusedChar(strAll); strAll += chSepOuter; char chSepInner = '='; if(strAll.IndexOf(chSepInner) >= 0) chSepInner = StrUtil.GetUnusedChar(strAll); StringBuilder sb = new StringBuilder(); sb.Append(chSepOuter); sb.Append(chSepInner); foreach(KeyValuePair kvp in m_dict) { sb.Append(chSepOuter); sb.Append(kvp.Key); sb.Append(chSepInner); sb.Append(kvp.Value); } return sb.ToString(); } public static IocProperties Deserialize(string strSerialized) { IocProperties p = new IocProperties(); if(string.IsNullOrEmpty(strSerialized)) return p; // No assert char chSepOuter = strSerialized[0]; string[] v = strSerialized.Substring(1).Split(new char[] { chSepOuter }); if((v == null) || (v.Length < 2)) { Debug.Assert(false); return p; } string strMeta = v[0]; if(string.IsNullOrEmpty(strMeta)) { Debug.Assert(false); return p; } char chSepInner = strMeta[0]; char[] vSepInner = new char[] { chSepInner }; for(int i = 1; i < v.Length; ++i) { string strProp = v[i]; if(string.IsNullOrEmpty(strProp)) { Debug.Assert(false); continue; } string[] vProp = strProp.Split(vSepInner); if((vProp == null) || (vProp.Length < 2)) { Debug.Assert(false); continue; } Debug.Assert(vProp.Length == 2); p.Set(vProp[0], vProp[1]); } return p; } public void CopyTo(IocProperties p) { if(p == null) { Debug.Assert(false); return; } foreach(KeyValuePair kvp in m_dict) { p.m_dict[kvp.Key] = kvp.Value; } } } } KeePassLib/Serialization/KdbxFile.Read.Streamed.cs0000664000000000000000000007766513222430402021026 0ustar rootroot/* KeePass Password Safe - The Open-Source Password Manager Copyright (C) 2003-2018 Dominik Reichl This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ using System; using System.Collections.Generic; using System.Diagnostics; using System.IO; using System.Text; using System.Xml; #if !KeePassUAP using System.Drawing; #endif using KeePassLib; using KeePassLib.Collections; using KeePassLib.Interfaces; using KeePassLib.Resources; using KeePassLib.Security; using KeePassLib.Utility; namespace KeePassLib.Serialization { /// /// Serialization to KeePass KDBX files. /// public sealed partial class KdbxFile { private enum KdbContext { Null, KeePassFile, Meta, Root, MemoryProtection, CustomIcons, CustomIcon, Binaries, CustomData, CustomDataItem, RootDeletedObjects, DeletedObject, Group, GroupTimes, GroupCustomData, GroupCustomDataItem, Entry, EntryTimes, EntryString, EntryBinary, EntryAutoType, EntryAutoTypeItem, EntryHistory, EntryCustomData, EntryCustomDataItem } private bool m_bReadNextNode = true; private Stack m_ctxGroups = new Stack(); private PwGroup m_ctxGroup = null; private PwEntry m_ctxEntry = null; private string m_ctxStringName = null; private ProtectedString m_ctxStringValue = null; private string m_ctxBinaryName = null; private ProtectedBinary m_ctxBinaryValue = null; private string m_ctxATName = null; private string m_ctxATSeq = null; private bool m_bEntryInHistory = false; private PwEntry m_ctxHistoryBase = null; private PwDeletedObject m_ctxDeletedObject = null; private PwUuid m_uuidCustomIconID = PwUuid.Zero; private byte[] m_pbCustomIconData = null; private string m_strCustomDataKey = null; private string m_strCustomDataValue = null; private string m_strGroupCustomDataKey = null; private string m_strGroupCustomDataValue = null; private string m_strEntryCustomDataKey = null; private string m_strEntryCustomDataValue = null; private void ReadXmlStreamed(Stream sXml, Stream sParent) { ReadDocumentStreamed(CreateXmlReader(sXml), sParent); } internal static XmlReaderSettings CreateStdXmlReaderSettings() { XmlReaderSettings xrs = new XmlReaderSettings(); xrs.CloseInput = true; xrs.IgnoreComments = true; xrs.IgnoreProcessingInstructions = true; xrs.IgnoreWhitespace = true; #if KeePassUAP xrs.DtdProcessing = DtdProcessing.Prohibit; #else #if !KeePassLibSD // Also see PrepMonoDev.sh script xrs.ProhibitDtd = true; // Obsolete in .NET 4, but still there // xrs.DtdProcessing = DtdProcessing.Prohibit; // .NET 4 only #endif xrs.ValidationType = ValidationType.None; #endif return xrs; } private static XmlReader CreateXmlReader(Stream readerStream) { XmlReaderSettings xrs = CreateStdXmlReaderSettings(); return XmlReader.Create(readerStream, xrs); } private void ReadDocumentStreamed(XmlReader xr, Stream sParentStream) { Debug.Assert(xr != null); if(xr == null) throw new ArgumentNullException("xr"); m_ctxGroups.Clear(); KdbContext ctx = KdbContext.Null; uint uTagCounter = 0; bool bSupportsStatus = (m_slLogger != null); long lStreamLength = 1; try { sParentStream.Position.ToString(); // Test Position support lStreamLength = sParentStream.Length; } catch(Exception) { bSupportsStatus = false; } if(lStreamLength <= 0) { Debug.Assert(false); lStreamLength = 1; } m_bReadNextNode = true; while(true) { if(m_bReadNextNode) { if(!xr.Read()) break; } else m_bReadNextNode = true; switch(xr.NodeType) { case XmlNodeType.Element: ctx = ReadXmlElement(ctx, xr); break; case XmlNodeType.EndElement: ctx = EndXmlElement(ctx, xr); break; case XmlNodeType.XmlDeclaration: break; // Ignore default: Debug.Assert(false); break; } ++uTagCounter; if(((uTagCounter % 256) == 0) && bSupportsStatus) { Debug.Assert(lStreamLength == sParentStream.Length); uint uPct = (uint)((sParentStream.Position * 100) / lStreamLength); // Clip percent value in case the stream reports incorrect // position/length values (M120413) if(uPct > 100) { Debug.Assert(false); uPct = 100; } m_slLogger.SetProgress(uPct); } } Debug.Assert(ctx == KdbContext.Null); if(ctx != KdbContext.Null) throw new FormatException(); Debug.Assert(m_ctxGroups.Count == 0); if(m_ctxGroups.Count != 0) throw new FormatException(); } private KdbContext ReadXmlElement(KdbContext ctx, XmlReader xr) { Debug.Assert(xr.NodeType == XmlNodeType.Element); switch(ctx) { case KdbContext.Null: if(xr.Name == ElemDocNode) return SwitchContext(ctx, KdbContext.KeePassFile, xr); else ReadUnknown(xr); break; case KdbContext.KeePassFile: if(xr.Name == ElemMeta) return SwitchContext(ctx, KdbContext.Meta, xr); else if(xr.Name == ElemRoot) return SwitchContext(ctx, KdbContext.Root, xr); else ReadUnknown(xr); break; case KdbContext.Meta: if(xr.Name == ElemGenerator) ReadString(xr); // Ignore else if(xr.Name == ElemHeaderHash) { // The header hash is typically only stored in // KDBX <= 3.1 files, not in KDBX >= 4 files // (here, the header is verified via a HMAC), // but we also support it for KDBX >= 4 files // (i.e. if it's present, we check it) string strHash = ReadString(xr); if(!string.IsNullOrEmpty(strHash) && (m_pbHashOfHeader != null) && !m_bRepairMode) { Debug.Assert(m_uFileVersion < FileVersion32_4); byte[] pbHash = Convert.FromBase64String(strHash); if(!MemUtil.ArraysEqual(pbHash, m_pbHashOfHeader)) throw new InvalidDataException(KLRes.FileCorrupted); } } else if(xr.Name == ElemSettingsChanged) m_pwDatabase.SettingsChanged = ReadTime(xr); else if(xr.Name == ElemDbName) m_pwDatabase.Name = ReadString(xr); else if(xr.Name == ElemDbNameChanged) m_pwDatabase.NameChanged = ReadTime(xr); else if(xr.Name == ElemDbDesc) m_pwDatabase.Description = ReadString(xr); else if(xr.Name == ElemDbDescChanged) m_pwDatabase.DescriptionChanged = ReadTime(xr); else if(xr.Name == ElemDbDefaultUser) m_pwDatabase.DefaultUserName = ReadString(xr); else if(xr.Name == ElemDbDefaultUserChanged) m_pwDatabase.DefaultUserNameChanged = ReadTime(xr); else if(xr.Name == ElemDbMntncHistoryDays) m_pwDatabase.MaintenanceHistoryDays = ReadUInt(xr, 365); else if(xr.Name == ElemDbColor) { string strColor = ReadString(xr); if(!string.IsNullOrEmpty(strColor)) m_pwDatabase.Color = ColorTranslator.FromHtml(strColor); } else if(xr.Name == ElemDbKeyChanged) m_pwDatabase.MasterKeyChanged = ReadTime(xr); else if(xr.Name == ElemDbKeyChangeRec) m_pwDatabase.MasterKeyChangeRec = ReadLong(xr, -1); else if(xr.Name == ElemDbKeyChangeForce) m_pwDatabase.MasterKeyChangeForce = ReadLong(xr, -1); else if(xr.Name == ElemDbKeyChangeForceOnce) m_pwDatabase.MasterKeyChangeForceOnce = ReadBool(xr, false); else if(xr.Name == ElemMemoryProt) return SwitchContext(ctx, KdbContext.MemoryProtection, xr); else if(xr.Name == ElemCustomIcons) return SwitchContext(ctx, KdbContext.CustomIcons, xr); else if(xr.Name == ElemRecycleBinEnabled) m_pwDatabase.RecycleBinEnabled = ReadBool(xr, true); else if(xr.Name == ElemRecycleBinUuid) m_pwDatabase.RecycleBinUuid = ReadUuid(xr); else if(xr.Name == ElemRecycleBinChanged) m_pwDatabase.RecycleBinChanged = ReadTime(xr); else if(xr.Name == ElemEntryTemplatesGroup) m_pwDatabase.EntryTemplatesGroup = ReadUuid(xr); else if(xr.Name == ElemEntryTemplatesGroupChanged) m_pwDatabase.EntryTemplatesGroupChanged = ReadTime(xr); else if(xr.Name == ElemHistoryMaxItems) m_pwDatabase.HistoryMaxItems = ReadInt(xr, -1); else if(xr.Name == ElemHistoryMaxSize) m_pwDatabase.HistoryMaxSize = ReadLong(xr, -1); else if(xr.Name == ElemLastSelectedGroup) m_pwDatabase.LastSelectedGroup = ReadUuid(xr); else if(xr.Name == ElemLastTopVisibleGroup) m_pwDatabase.LastTopVisibleGroup = ReadUuid(xr); else if(xr.Name == ElemBinaries) return SwitchContext(ctx, KdbContext.Binaries, xr); else if(xr.Name == ElemCustomData) return SwitchContext(ctx, KdbContext.CustomData, xr); else ReadUnknown(xr); break; case KdbContext.MemoryProtection: if(xr.Name == ElemProtTitle) m_pwDatabase.MemoryProtection.ProtectTitle = ReadBool(xr, false); else if(xr.Name == ElemProtUserName) m_pwDatabase.MemoryProtection.ProtectUserName = ReadBool(xr, false); else if(xr.Name == ElemProtPassword) m_pwDatabase.MemoryProtection.ProtectPassword = ReadBool(xr, true); else if(xr.Name == ElemProtUrl) m_pwDatabase.MemoryProtection.ProtectUrl = ReadBool(xr, false); else if(xr.Name == ElemProtNotes) m_pwDatabase.MemoryProtection.ProtectNotes = ReadBool(xr, false); // else if(xr.Name == ElemProtAutoHide) // m_pwDatabase.MemoryProtection.AutoEnableVisualHiding = ReadBool(xr, true); else ReadUnknown(xr); break; case KdbContext.CustomIcons: if(xr.Name == ElemCustomIconItem) return SwitchContext(ctx, KdbContext.CustomIcon, xr); else ReadUnknown(xr); break; case KdbContext.CustomIcon: if(xr.Name == ElemCustomIconItemID) m_uuidCustomIconID = ReadUuid(xr); else if(xr.Name == ElemCustomIconItemData) { string strData = ReadString(xr); if(!string.IsNullOrEmpty(strData)) m_pbCustomIconData = Convert.FromBase64String(strData); else { Debug.Assert(false); } } else ReadUnknown(xr); break; case KdbContext.Binaries: if(xr.Name == ElemBinary) { if(xr.MoveToAttribute(AttrId)) { string strKey = xr.Value; ProtectedBinary pbData = ReadProtectedBinary(xr); int iKey; if(!StrUtil.TryParseIntInvariant(strKey, out iKey)) throw new FormatException(); if(iKey < 0) throw new FormatException(); Debug.Assert(m_pbsBinaries.Get(iKey) == null); Debug.Assert(m_pbsBinaries.Find(pbData) < 0); m_pbsBinaries.Set(iKey, pbData); } else ReadUnknown(xr); } else ReadUnknown(xr); break; case KdbContext.CustomData: if(xr.Name == ElemStringDictExItem) return SwitchContext(ctx, KdbContext.CustomDataItem, xr); else ReadUnknown(xr); break; case KdbContext.CustomDataItem: if(xr.Name == ElemKey) m_strCustomDataKey = ReadString(xr); else if(xr.Name == ElemValue) m_strCustomDataValue = ReadString(xr); else ReadUnknown(xr); break; case KdbContext.Root: if(xr.Name == ElemGroup) { Debug.Assert(m_ctxGroups.Count == 0); if(m_ctxGroups.Count != 0) throw new FormatException(); m_pwDatabase.RootGroup = new PwGroup(false, false); m_ctxGroups.Push(m_pwDatabase.RootGroup); m_ctxGroup = m_ctxGroups.Peek(); return SwitchContext(ctx, KdbContext.Group, xr); } else if(xr.Name == ElemDeletedObjects) return SwitchContext(ctx, KdbContext.RootDeletedObjects, xr); else ReadUnknown(xr); break; case KdbContext.Group: if(xr.Name == ElemUuid) m_ctxGroup.Uuid = ReadUuid(xr); else if(xr.Name == ElemName) m_ctxGroup.Name = ReadString(xr); else if(xr.Name == ElemNotes) m_ctxGroup.Notes = ReadString(xr); else if(xr.Name == ElemIcon) m_ctxGroup.IconId = ReadIconId(xr, PwIcon.Folder); else if(xr.Name == ElemCustomIconID) m_ctxGroup.CustomIconUuid = ReadUuid(xr); else if(xr.Name == ElemTimes) return SwitchContext(ctx, KdbContext.GroupTimes, xr); else if(xr.Name == ElemIsExpanded) m_ctxGroup.IsExpanded = ReadBool(xr, true); else if(xr.Name == ElemGroupDefaultAutoTypeSeq) m_ctxGroup.DefaultAutoTypeSequence = ReadString(xr); else if(xr.Name == ElemEnableAutoType) m_ctxGroup.EnableAutoType = StrUtil.StringToBoolEx(ReadString(xr)); else if(xr.Name == ElemEnableSearching) m_ctxGroup.EnableSearching = StrUtil.StringToBoolEx(ReadString(xr)); else if(xr.Name == ElemLastTopVisibleEntry) m_ctxGroup.LastTopVisibleEntry = ReadUuid(xr); else if(xr.Name == ElemCustomData) return SwitchContext(ctx, KdbContext.GroupCustomData, xr); else if(xr.Name == ElemGroup) { m_ctxGroup = new PwGroup(false, false); m_ctxGroups.Peek().AddGroup(m_ctxGroup, true); m_ctxGroups.Push(m_ctxGroup); return SwitchContext(ctx, KdbContext.Group, xr); } else if(xr.Name == ElemEntry) { m_ctxEntry = new PwEntry(false, false); m_ctxGroup.AddEntry(m_ctxEntry, true); m_bEntryInHistory = false; return SwitchContext(ctx, KdbContext.Entry, xr); } else ReadUnknown(xr); break; case KdbContext.GroupCustomData: if(xr.Name == ElemStringDictExItem) return SwitchContext(ctx, KdbContext.GroupCustomDataItem, xr); else ReadUnknown(xr); break; case KdbContext.GroupCustomDataItem: if(xr.Name == ElemKey) m_strGroupCustomDataKey = ReadString(xr); else if(xr.Name == ElemValue) m_strGroupCustomDataValue = ReadString(xr); else ReadUnknown(xr); break; case KdbContext.Entry: if(xr.Name == ElemUuid) m_ctxEntry.Uuid = ReadUuid(xr); else if(xr.Name == ElemIcon) m_ctxEntry.IconId = ReadIconId(xr, PwIcon.Key); else if(xr.Name == ElemCustomIconID) m_ctxEntry.CustomIconUuid = ReadUuid(xr); else if(xr.Name == ElemFgColor) { string strColor = ReadString(xr); if(!string.IsNullOrEmpty(strColor)) m_ctxEntry.ForegroundColor = ColorTranslator.FromHtml(strColor); } else if(xr.Name == ElemBgColor) { string strColor = ReadString(xr); if(!string.IsNullOrEmpty(strColor)) m_ctxEntry.BackgroundColor = ColorTranslator.FromHtml(strColor); } else if(xr.Name == ElemOverrideUrl) m_ctxEntry.OverrideUrl = ReadString(xr); else if(xr.Name == ElemTags) m_ctxEntry.Tags = StrUtil.StringToTags(ReadString(xr)); else if(xr.Name == ElemTimes) return SwitchContext(ctx, KdbContext.EntryTimes, xr); else if(xr.Name == ElemString) return SwitchContext(ctx, KdbContext.EntryString, xr); else if(xr.Name == ElemBinary) return SwitchContext(ctx, KdbContext.EntryBinary, xr); else if(xr.Name == ElemAutoType) return SwitchContext(ctx, KdbContext.EntryAutoType, xr); else if(xr.Name == ElemCustomData) return SwitchContext(ctx, KdbContext.EntryCustomData, xr); else if(xr.Name == ElemHistory) { Debug.Assert(m_bEntryInHistory == false); if(m_bEntryInHistory == false) { m_ctxHistoryBase = m_ctxEntry; return SwitchContext(ctx, KdbContext.EntryHistory, xr); } else ReadUnknown(xr); } else ReadUnknown(xr); break; case KdbContext.GroupTimes: case KdbContext.EntryTimes: ITimeLogger tl = ((ctx == KdbContext.GroupTimes) ? (ITimeLogger)m_ctxGroup : (ITimeLogger)m_ctxEntry); Debug.Assert(tl != null); if(xr.Name == ElemCreationTime) tl.CreationTime = ReadTime(xr); else if(xr.Name == ElemLastModTime) tl.LastModificationTime = ReadTime(xr); else if(xr.Name == ElemLastAccessTime) tl.LastAccessTime = ReadTime(xr); else if(xr.Name == ElemExpiryTime) tl.ExpiryTime = ReadTime(xr); else if(xr.Name == ElemExpires) tl.Expires = ReadBool(xr, false); else if(xr.Name == ElemUsageCount) tl.UsageCount = ReadULong(xr, 0); else if(xr.Name == ElemLocationChanged) tl.LocationChanged = ReadTime(xr); else ReadUnknown(xr); break; case KdbContext.EntryString: if(xr.Name == ElemKey) m_ctxStringName = ReadString(xr); else if(xr.Name == ElemValue) m_ctxStringValue = ReadProtectedString(xr); else ReadUnknown(xr); break; case KdbContext.EntryBinary: if(xr.Name == ElemKey) m_ctxBinaryName = ReadString(xr); else if(xr.Name == ElemValue) m_ctxBinaryValue = ReadProtectedBinary(xr); else ReadUnknown(xr); break; case KdbContext.EntryAutoType: if(xr.Name == ElemAutoTypeEnabled) m_ctxEntry.AutoType.Enabled = ReadBool(xr, true); else if(xr.Name == ElemAutoTypeObfuscation) m_ctxEntry.AutoType.ObfuscationOptions = (AutoTypeObfuscationOptions)ReadInt(xr, 0); else if(xr.Name == ElemAutoTypeDefaultSeq) m_ctxEntry.AutoType.DefaultSequence = ReadString(xr); else if(xr.Name == ElemAutoTypeItem) return SwitchContext(ctx, KdbContext.EntryAutoTypeItem, xr); else ReadUnknown(xr); break; case KdbContext.EntryAutoTypeItem: if(xr.Name == ElemWindow) m_ctxATName = ReadString(xr); else if(xr.Name == ElemKeystrokeSequence) m_ctxATSeq = ReadString(xr); else ReadUnknown(xr); break; case KdbContext.EntryCustomData: if(xr.Name == ElemStringDictExItem) return SwitchContext(ctx, KdbContext.EntryCustomDataItem, xr); else ReadUnknown(xr); break; case KdbContext.EntryCustomDataItem: if(xr.Name == ElemKey) m_strEntryCustomDataKey = ReadString(xr); else if(xr.Name == ElemValue) m_strEntryCustomDataValue = ReadString(xr); else ReadUnknown(xr); break; case KdbContext.EntryHistory: if(xr.Name == ElemEntry) { m_ctxEntry = new PwEntry(false, false); m_ctxHistoryBase.History.Add(m_ctxEntry); m_bEntryInHistory = true; return SwitchContext(ctx, KdbContext.Entry, xr); } else ReadUnknown(xr); break; case KdbContext.RootDeletedObjects: if(xr.Name == ElemDeletedObject) { m_ctxDeletedObject = new PwDeletedObject(); m_pwDatabase.DeletedObjects.Add(m_ctxDeletedObject); return SwitchContext(ctx, KdbContext.DeletedObject, xr); } else ReadUnknown(xr); break; case KdbContext.DeletedObject: if(xr.Name == ElemUuid) m_ctxDeletedObject.Uuid = ReadUuid(xr); else if(xr.Name == ElemDeletionTime) m_ctxDeletedObject.DeletionTime = ReadTime(xr); else ReadUnknown(xr); break; default: ReadUnknown(xr); break; } return ctx; } private KdbContext EndXmlElement(KdbContext ctx, XmlReader xr) { Debug.Assert(xr.NodeType == XmlNodeType.EndElement); if((ctx == KdbContext.KeePassFile) && (xr.Name == ElemDocNode)) return KdbContext.Null; else if((ctx == KdbContext.Meta) && (xr.Name == ElemMeta)) return KdbContext.KeePassFile; else if((ctx == KdbContext.Root) && (xr.Name == ElemRoot)) return KdbContext.KeePassFile; else if((ctx == KdbContext.MemoryProtection) && (xr.Name == ElemMemoryProt)) return KdbContext.Meta; else if((ctx == KdbContext.CustomIcons) && (xr.Name == ElemCustomIcons)) return KdbContext.Meta; else if((ctx == KdbContext.CustomIcon) && (xr.Name == ElemCustomIconItem)) { if(!m_uuidCustomIconID.Equals(PwUuid.Zero) && (m_pbCustomIconData != null)) m_pwDatabase.CustomIcons.Add(new PwCustomIcon( m_uuidCustomIconID, m_pbCustomIconData)); else { Debug.Assert(false); } m_uuidCustomIconID = PwUuid.Zero; m_pbCustomIconData = null; return KdbContext.CustomIcons; } else if((ctx == KdbContext.Binaries) && (xr.Name == ElemBinaries)) return KdbContext.Meta; else if((ctx == KdbContext.CustomData) && (xr.Name == ElemCustomData)) return KdbContext.Meta; else if((ctx == KdbContext.CustomDataItem) && (xr.Name == ElemStringDictExItem)) { if((m_strCustomDataKey != null) && (m_strCustomDataValue != null)) m_pwDatabase.CustomData.Set(m_strCustomDataKey, m_strCustomDataValue); else { Debug.Assert(false); } m_strCustomDataKey = null; m_strCustomDataValue = null; return KdbContext.CustomData; } else if((ctx == KdbContext.Group) && (xr.Name == ElemGroup)) { if(PwUuid.Zero.Equals(m_ctxGroup.Uuid)) m_ctxGroup.Uuid = new PwUuid(true); // No assert (import) m_ctxGroups.Pop(); if(m_ctxGroups.Count == 0) { m_ctxGroup = null; return KdbContext.Root; } else { m_ctxGroup = m_ctxGroups.Peek(); return KdbContext.Group; } } else if((ctx == KdbContext.GroupTimes) && (xr.Name == ElemTimes)) return KdbContext.Group; else if((ctx == KdbContext.GroupCustomData) && (xr.Name == ElemCustomData)) return KdbContext.Group; else if((ctx == KdbContext.GroupCustomDataItem) && (xr.Name == ElemStringDictExItem)) { if((m_strGroupCustomDataKey != null) && (m_strGroupCustomDataValue != null)) m_ctxGroup.CustomData.Set(m_strGroupCustomDataKey, m_strGroupCustomDataValue); else { Debug.Assert(false); } m_strGroupCustomDataKey = null; m_strGroupCustomDataValue = null; return KdbContext.GroupCustomData; } else if((ctx == KdbContext.Entry) && (xr.Name == ElemEntry)) { // Create new UUID if absent if(PwUuid.Zero.Equals(m_ctxEntry.Uuid)) m_ctxEntry.Uuid = new PwUuid(true); // No assert (import) if(m_bEntryInHistory) { m_ctxEntry = m_ctxHistoryBase; return KdbContext.EntryHistory; } return KdbContext.Group; } else if((ctx == KdbContext.EntryTimes) && (xr.Name == ElemTimes)) return KdbContext.Entry; else if((ctx == KdbContext.EntryString) && (xr.Name == ElemString)) { m_ctxEntry.Strings.Set(m_ctxStringName, m_ctxStringValue); m_ctxStringName = null; m_ctxStringValue = null; return KdbContext.Entry; } else if((ctx == KdbContext.EntryBinary) && (xr.Name == ElemBinary)) { if(string.IsNullOrEmpty(m_strDetachBins)) m_ctxEntry.Binaries.Set(m_ctxBinaryName, m_ctxBinaryValue); else { SaveBinary(m_ctxBinaryName, m_ctxBinaryValue, m_strDetachBins); m_ctxBinaryValue = null; GC.Collect(); } m_ctxBinaryName = null; m_ctxBinaryValue = null; return KdbContext.Entry; } else if((ctx == KdbContext.EntryAutoType) && (xr.Name == ElemAutoType)) return KdbContext.Entry; else if((ctx == KdbContext.EntryAutoTypeItem) && (xr.Name == ElemAutoTypeItem)) { AutoTypeAssociation atAssoc = new AutoTypeAssociation(m_ctxATName, m_ctxATSeq); m_ctxEntry.AutoType.Add(atAssoc); m_ctxATName = null; m_ctxATSeq = null; return KdbContext.EntryAutoType; } else if((ctx == KdbContext.EntryCustomData) && (xr.Name == ElemCustomData)) return KdbContext.Entry; else if((ctx == KdbContext.EntryCustomDataItem) && (xr.Name == ElemStringDictExItem)) { if((m_strEntryCustomDataKey != null) && (m_strEntryCustomDataValue != null)) m_ctxEntry.CustomData.Set(m_strEntryCustomDataKey, m_strEntryCustomDataValue); else { Debug.Assert(false); } m_strEntryCustomDataKey = null; m_strEntryCustomDataValue = null; return KdbContext.EntryCustomData; } else if((ctx == KdbContext.EntryHistory) && (xr.Name == ElemHistory)) { m_bEntryInHistory = false; return KdbContext.Entry; } else if((ctx == KdbContext.RootDeletedObjects) && (xr.Name == ElemDeletedObjects)) return KdbContext.Root; else if((ctx == KdbContext.DeletedObject) && (xr.Name == ElemDeletedObject)) { m_ctxDeletedObject = null; return KdbContext.RootDeletedObjects; } else { Debug.Assert(false); throw new FormatException(); } } private string ReadString(XmlReader xr) { XorredBuffer xb = ProcessNode(xr); if(xb != null) { byte[] pb = xb.ReadPlainText(); if(pb.Length == 0) return string.Empty; return StrUtil.Utf8.GetString(pb, 0, pb.Length); } m_bReadNextNode = false; // ReadElementString skips end tag return xr.ReadElementString(); } private string ReadStringRaw(XmlReader xr) { m_bReadNextNode = false; // ReadElementString skips end tag return xr.ReadElementString(); } private byte[] ReadBase64(XmlReader xr, bool bRaw) { // if(bRaw) return ReadBase64RawInChunks(xr); string str = (bRaw ? ReadStringRaw(xr) : ReadString(xr)); if(string.IsNullOrEmpty(str)) return MemUtil.EmptyByteArray; return Convert.FromBase64String(str); } /* private byte[] m_pbBase64ReadBuf = new byte[1024 * 1024 * 3]; private byte[] ReadBase64RawInChunks(XmlReader xr) { xr.MoveToContent(); List lParts = new List(); byte[] pbBuf = m_pbBase64ReadBuf; while(true) { int cb = xr.ReadElementContentAsBase64(pbBuf, 0, pbBuf.Length); if(cb == 0) break; byte[] pb = new byte[cb]; Array.Copy(pbBuf, 0, pb, 0, cb); lParts.Add(pb); // No break when cb < pbBuf.Length, because ReadElementContentAsBase64 // moves to the next XML node only when returning 0 } m_bReadNextNode = false; if(lParts.Count == 0) return MemUtil.EmptyByteArray; if(lParts.Count == 1) return lParts[0]; long cbRes = 0; for(int i = 0; i < lParts.Count; ++i) cbRes += lParts[i].Length; byte[] pbRes = new byte[cbRes]; int cbCur = 0; for(int i = 0; i < lParts.Count; ++i) { Array.Copy(lParts[i], 0, pbRes, cbCur, lParts[i].Length); cbCur += lParts[i].Length; } return pbRes; } */ private bool ReadBool(XmlReader xr, bool bDefault) { string str = ReadString(xr); if(str == ValTrue) return true; else if(str == ValFalse) return false; Debug.Assert(false); return bDefault; } private PwUuid ReadUuid(XmlReader xr) { byte[] pb = ReadBase64(xr, false); if(pb.Length == 0) return PwUuid.Zero; return new PwUuid(pb); } private int ReadInt(XmlReader xr, int nDefault) { string str = ReadString(xr); int n; if(StrUtil.TryParseIntInvariant(str, out n)) return n; // Backward compatibility if(StrUtil.TryParseInt(str, out n)) return n; Debug.Assert(false); return nDefault; } private uint ReadUInt(XmlReader xr, uint uDefault) { string str = ReadString(xr); uint u; if(StrUtil.TryParseUIntInvariant(str, out u)) return u; // Backward compatibility if(StrUtil.TryParseUInt(str, out u)) return u; Debug.Assert(false); return uDefault; } private long ReadLong(XmlReader xr, long lDefault) { string str = ReadString(xr); long l; if(StrUtil.TryParseLongInvariant(str, out l)) return l; // Backward compatibility if(StrUtil.TryParseLong(str, out l)) return l; Debug.Assert(false); return lDefault; } private ulong ReadULong(XmlReader xr, ulong uDefault) { string str = ReadString(xr); ulong u; if(StrUtil.TryParseULongInvariant(str, out u)) return u; // Backward compatibility if(StrUtil.TryParseULong(str, out u)) return u; Debug.Assert(false); return uDefault; } private DateTime ReadTime(XmlReader xr) { // Cf. WriteObject(string, DateTime) if((m_format == KdbxFormat.Default) && (m_uFileVersion >= FileVersion32_4)) { // long l = ReadLong(xr, -1); // if(l != -1) return DateTime.FromBinary(l); byte[] pb = ReadBase64(xr, false); if(pb.Length != 8) { Debug.Assert(false); byte[] pb8 = new byte[8]; Array.Copy(pb, pb8, Math.Min(pb.Length, 8)); // Little-endian pb = pb8; } long lSec = MemUtil.BytesToInt64(pb); return new DateTime(lSec * TimeSpan.TicksPerSecond, DateTimeKind.Utc); } else { string str = ReadString(xr); DateTime dt; if(TimeUtil.TryDeserializeUtc(str, out dt)) return dt; } Debug.Assert(false); return m_dtNow; } private PwIcon ReadIconId(XmlReader xr, PwIcon icDefault) { int i = ReadInt(xr, (int)icDefault); if((i >= 0) && (i < (int)PwIcon.Count)) return (PwIcon)i; Debug.Assert(false); return icDefault; } private ProtectedString ReadProtectedString(XmlReader xr) { XorredBuffer xb = ProcessNode(xr); if(xb != null) return new ProtectedString(true, xb); bool bProtect = false; if(m_format == KdbxFormat.PlainXml) { if(xr.MoveToAttribute(AttrProtectedInMemPlainXml)) { string strProtect = xr.Value; bProtect = ((strProtect != null) && (strProtect == ValTrue)); } } ProtectedString ps = new ProtectedString(bProtect, ReadString(xr)); return ps; } private ProtectedBinary ReadProtectedBinary(XmlReader xr) { if(xr.MoveToAttribute(AttrRef)) { string strRef = xr.Value; if(!string.IsNullOrEmpty(strRef)) { int iRef; if(StrUtil.TryParseIntInvariant(strRef, out iRef)) { ProtectedBinary pb = m_pbsBinaries.Get(iRef); if(pb != null) { // https://sourceforge.net/p/keepass/feature-requests/2023/ xr.MoveToElement(); #if DEBUG string strInner = ReadStringRaw(xr); Debug.Assert(string.IsNullOrEmpty(strInner)); #else ReadStringRaw(xr); #endif return pb; } else { Debug.Assert(false); } } else { Debug.Assert(false); } } else { Debug.Assert(false); } } bool bCompressed = false; if(xr.MoveToAttribute(AttrCompressed)) bCompressed = (xr.Value == ValTrue); XorredBuffer xb = ProcessNode(xr); if(xb != null) { Debug.Assert(!bCompressed); // See SubWriteValue(ProtectedBinary value) return new ProtectedBinary(true, xb); } byte[] pbData = ReadBase64(xr, true); if(pbData.Length == 0) return new ProtectedBinary(); if(bCompressed) pbData = MemUtil.Decompress(pbData); return new ProtectedBinary(false, pbData); } private void ReadUnknown(XmlReader xr) { Debug.Assert(false); // Unknown node! if(xr.IsEmptyElement) return; string strUnknownName = xr.Name; ProcessNode(xr); while(xr.Read()) { if(xr.NodeType == XmlNodeType.EndElement) break; if(xr.NodeType != XmlNodeType.Element) continue; ReadUnknown(xr); } Debug.Assert(xr.Name == strUnknownName); } private XorredBuffer ProcessNode(XmlReader xr) { // Debug.Assert(xr.NodeType == XmlNodeType.Element); XorredBuffer xb = null; if(xr.HasAttributes) { if(xr.MoveToAttribute(AttrProtected)) { if(xr.Value == ValTrue) { xr.MoveToElement(); byte[] pbEncrypted = ReadBase64(xr, true); byte[] pbPad = m_randomStream.GetRandomBytes((uint)pbEncrypted.Length); xb = new XorredBuffer(pbEncrypted, pbPad); } } } return xb; } private static KdbContext SwitchContext(KdbContext ctxCurrent, KdbContext ctxNew, XmlReader xr) { if(xr.IsEmptyElement) return ctxCurrent; return ctxNew; } } } KeePassLib/Serialization/IOConnection.cs0000664000000000000000000005574313222430402017241 0ustar rootroot/* KeePass Password Safe - The Open-Source Password Manager Copyright (C) 2003-2018 Dominik Reichl This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ using System; using System.Collections.Generic; using System.Diagnostics; using System.IO; using System.Net; using System.Reflection; using System.Text; #if (!KeePassLibSD && !KeePassUAP) using System.Net.Cache; using System.Net.Security; #endif #if !KeePassUAP using System.Security.Cryptography.X509Certificates; #endif using KeePassLib.Native; using KeePassLib.Utility; namespace KeePassLib.Serialization { #if !KeePassLibSD internal sealed class IOWebClient : WebClient { private IOConnectionInfo m_ioc; public IOWebClient(IOConnectionInfo ioc) : base() { m_ioc = ioc; } protected override WebRequest GetWebRequest(Uri address) { WebRequest request = base.GetWebRequest(address); IOConnection.ConfigureWebRequest(request, m_ioc); return request; } } #endif internal abstract class WrapperStream : Stream { private readonly Stream m_s; protected Stream BaseStream { get { return m_s; } } public override bool CanRead { get { return m_s.CanRead; } } public override bool CanSeek { get { return m_s.CanSeek; } } public override bool CanTimeout { get { return m_s.CanTimeout; } } public override bool CanWrite { get { return m_s.CanWrite; } } public override long Length { get { return m_s.Length; } } public override long Position { get { return m_s.Position; } set { m_s.Position = value; } } public override int ReadTimeout { get { return m_s.ReadTimeout; } set { m_s.ReadTimeout = value; } } public override int WriteTimeout { get { return m_s.WriteTimeout; } set { m_s.WriteTimeout = value; } } public WrapperStream(Stream sBase) : base() { if(sBase == null) throw new ArgumentNullException("sBase"); m_s = sBase; } #if !KeePassUAP public override IAsyncResult BeginRead(byte[] buffer, int offset, int count, AsyncCallback callback, object state) { return m_s.BeginRead(buffer, offset, count, callback, state); } public override IAsyncResult BeginWrite(byte[] buffer, int offset, int count, AsyncCallback callback, object state) { return BeginWrite(buffer, offset, count, callback, state); } #endif protected override void Dispose(bool disposing) { if(disposing) m_s.Dispose(); base.Dispose(disposing); } #if !KeePassUAP public override int EndRead(IAsyncResult asyncResult) { return m_s.EndRead(asyncResult); } public override void EndWrite(IAsyncResult asyncResult) { m_s.EndWrite(asyncResult); } #endif public override void Flush() { m_s.Flush(); } public override int Read(byte[] buffer, int offset, int count) { return m_s.Read(buffer, offset, count); } public override int ReadByte() { return m_s.ReadByte(); } public override long Seek(long offset, SeekOrigin origin) { return m_s.Seek(offset, origin); } public override void SetLength(long value) { m_s.SetLength(value); } public override void Write(byte[] buffer, int offset, int count) { m_s.Write(buffer, offset, count); } public override void WriteByte(byte value) { m_s.WriteByte(value); } } internal sealed class IocStream : WrapperStream { private readonly bool m_bWrite; // Initially opened for writing private bool m_bDisposed = false; public IocStream(Stream sBase) : base(sBase) { m_bWrite = sBase.CanWrite; } protected override void Dispose(bool disposing) { base.Dispose(disposing); if(disposing && MonoWorkarounds.IsRequired(10163) && m_bWrite && !m_bDisposed) { try { Stream s = this.BaseStream; Type t = s.GetType(); if(t.Name == "WebConnectionStream") { PropertyInfo pi = t.GetProperty("Request", BindingFlags.Instance | BindingFlags.NonPublic); if(pi != null) { WebRequest wr = (pi.GetValue(s, null) as WebRequest); if(wr != null) IOConnection.DisposeResponse(wr.GetResponse(), false); else { Debug.Assert(false); } } else { Debug.Assert(false); } } } catch(Exception) { Debug.Assert(false); } } m_bDisposed = true; } public static Stream WrapIfRequired(Stream s) { if(s == null) { Debug.Assert(false); return null; } if(MonoWorkarounds.IsRequired(10163) && s.CanWrite) return new IocStream(s); return s; } } public static class IOConnection { #if !KeePassLibSD private static ProxyServerType m_pstProxyType = ProxyServerType.System; private static string m_strProxyAddr = string.Empty; private static string m_strProxyPort = string.Empty; private static ProxyAuthType m_patProxyAuthType = ProxyAuthType.Auto; private static string m_strProxyUserName = string.Empty; private static string m_strProxyPassword = string.Empty; #if !KeePassUAP private static bool? m_obDefaultExpect100Continue = null; private static bool m_bSslCertsAcceptInvalid = false; internal static bool SslCertsAcceptInvalid { // get { return m_bSslCertsAcceptInvalid; } set { m_bSslCertsAcceptInvalid = value; } } #endif #endif // Web request methods public const string WrmDeleteFile = "DELETEFILE"; public const string WrmMoveFile = "MOVEFILE"; // Web request headers public const string WrhMoveFileTo = "MoveFileTo"; public static event EventHandler IOAccessPre; #if !KeePassLibSD #if !KeePassUAP // Allow self-signed certificates, expired certificates, etc. private static bool AcceptCertificate(object sender, X509Certificate certificate, X509Chain chain, SslPolicyErrors sslPolicyErrors) { return true; } #endif internal static void SetProxy(ProxyServerType pst, string strAddr, string strPort, ProxyAuthType pat, string strUserName, string strPassword) { m_pstProxyType = pst; m_strProxyAddr = (strAddr ?? string.Empty); m_strProxyPort = (strPort ?? string.Empty); m_patProxyAuthType = pat; m_strProxyUserName = (strUserName ?? string.Empty); m_strProxyPassword = (strPassword ?? string.Empty); } internal static void ConfigureWebRequest(WebRequest request, IOConnectionInfo ioc) { if(request == null) { Debug.Assert(false); return; } // No throw IocProperties p = ((ioc != null) ? ioc.Properties : null); if(p == null) { Debug.Assert(false); p = new IocProperties(); } IHasIocProperties ihpReq = (request as IHasIocProperties); if(ihpReq != null) { IocProperties pEx = ihpReq.IOConnectionProperties; if(pEx != null) p.CopyTo(pEx); else ihpReq.IOConnectionProperties = p.CloneDeep(); } if(IsHttpWebRequest(request)) { // WebDAV support #if !KeePassUAP request.PreAuthenticate = true; // Also auth GET #endif if(string.Equals(request.Method, WebRequestMethods.Http.Post, StrUtil.CaseIgnoreCmp)) request.Method = WebRequestMethods.Http.Put; #if !KeePassUAP HttpWebRequest hwr = (request as HttpWebRequest); if(hwr != null) { string strUA = p.Get(IocKnownProperties.UserAgent); if(!string.IsNullOrEmpty(strUA)) hwr.UserAgent = strUA; } else { Debug.Assert(false); } #endif } #if !KeePassUAP else if(IsFtpWebRequest(request)) { FtpWebRequest fwr = (request as FtpWebRequest); if(fwr != null) { bool? obPassive = p.GetBool(IocKnownProperties.Passive); if(obPassive.HasValue) fwr.UsePassive = obPassive.Value; } else { Debug.Assert(false); } } #endif #if !KeePassUAP // Not implemented and ignored in Mono < 2.10 try { request.CachePolicy = new RequestCachePolicy(RequestCacheLevel.NoCacheNoStore); } catch(NotImplementedException) { } catch(Exception) { Debug.Assert(false); } #endif try { IWebProxy prx; if(GetWebProxy(out prx)) request.Proxy = prx; } catch(Exception) { Debug.Assert(false); } #if !KeePassUAP long? olTimeout = p.GetLong(IocKnownProperties.Timeout); if(olTimeout.HasValue && (olTimeout.Value >= 0)) request.Timeout = (int)Math.Min(olTimeout.Value, (long)int.MaxValue); bool? ob = p.GetBool(IocKnownProperties.PreAuth); if(ob.HasValue) request.PreAuthenticate = ob.Value; #endif } internal static void ConfigureWebClient(WebClient wc) { #if !KeePassUAP // Not implemented and ignored in Mono < 2.10 try { wc.CachePolicy = new RequestCachePolicy(RequestCacheLevel.NoCacheNoStore); } catch(NotImplementedException) { } catch(Exception) { Debug.Assert(false); } #endif try { IWebProxy prx; if(GetWebProxy(out prx)) wc.Proxy = prx; } catch(Exception) { Debug.Assert(false); } } private static bool GetWebProxy(out IWebProxy prx) { bool b = GetWebProxyServer(out prx); if(b) AssignCredentials(prx); return b; } private static bool GetWebProxyServer(out IWebProxy prx) { prx = null; if(m_pstProxyType == ProxyServerType.None) return true; // Use null proxy if(m_pstProxyType == ProxyServerType.Manual) { try { if(m_strProxyAddr.Length == 0) { // First try default (from config), then system prx = WebRequest.DefaultWebProxy; #if !KeePassUAP if(prx == null) prx = WebRequest.GetSystemWebProxy(); #endif } else if(m_strProxyPort.Length > 0) prx = new WebProxy(m_strProxyAddr, int.Parse(m_strProxyPort)); else prx = new WebProxy(m_strProxyAddr); return (prx != null); } #if KeePassUAP catch(Exception) { Debug.Assert(false); } #else catch(Exception ex) { string strInfo = m_strProxyAddr; if(m_strProxyPort.Length > 0) strInfo += ":" + m_strProxyPort; MessageService.ShowWarning(strInfo, ex.Message); } #endif return false; // Use default } Debug.Assert(m_pstProxyType == ProxyServerType.System); try { // First try system, then default (from config) #if !KeePassUAP prx = WebRequest.GetSystemWebProxy(); #endif if(prx == null) prx = WebRequest.DefaultWebProxy; return (prx != null); } catch(Exception) { Debug.Assert(false); } return false; } private static void AssignCredentials(IWebProxy prx) { if(prx == null) return; // No assert string strUserName = m_strProxyUserName; string strPassword = m_strProxyPassword; ProxyAuthType pat = m_patProxyAuthType; if(pat == ProxyAuthType.Auto) { if((strUserName.Length > 0) || (strPassword.Length > 0)) pat = ProxyAuthType.Manual; else pat = ProxyAuthType.Default; } try { if(pat == ProxyAuthType.None) prx.Credentials = null; else if(pat == ProxyAuthType.Default) prx.Credentials = CredentialCache.DefaultCredentials; else if(pat == ProxyAuthType.Manual) { if((strUserName.Length > 0) || (strPassword.Length > 0)) prx.Credentials = new NetworkCredential( strUserName, strPassword); } else { Debug.Assert(false); } } catch(Exception) { Debug.Assert(false); } } private static void PrepareWebAccess(IOConnectionInfo ioc) { #if !KeePassUAP IocProperties p = ((ioc != null) ? ioc.Properties : null); if(p == null) { Debug.Assert(false); p = new IocProperties(); } try { if(m_bSslCertsAcceptInvalid) ServicePointManager.ServerCertificateValidationCallback = IOConnection.AcceptCertificate; else ServicePointManager.ServerCertificateValidationCallback = null; } catch(Exception) { Debug.Assert(false); } try { SecurityProtocolType spt = (SecurityProtocolType.Ssl3 | SecurityProtocolType.Tls); // The flags Tls11 and Tls12 in SecurityProtocolType have been // introduced in .NET 4.5 and must not be set when running under // older .NET versions (otherwise an exception is thrown) Type tSpt = typeof(SecurityProtocolType); string[] vSpt = Enum.GetNames(tSpt); foreach(string strSpt in vSpt) { if(strSpt.Equals("Tls11", StrUtil.CaseIgnoreCmp)) spt |= (SecurityProtocolType)Enum.Parse(tSpt, "Tls11", true); else if(strSpt.Equals("Tls12", StrUtil.CaseIgnoreCmp)) spt |= (SecurityProtocolType)Enum.Parse(tSpt, "Tls12", true); } ServicePointManager.SecurityProtocol = spt; } catch(Exception) { Debug.Assert(false); } try { bool bCurCont = ServicePointManager.Expect100Continue; if(!m_obDefaultExpect100Continue.HasValue) { Debug.Assert(bCurCont); // Default should be true m_obDefaultExpect100Continue = bCurCont; } bool bNewCont = m_obDefaultExpect100Continue.Value; bool? ob = p.GetBool(IocKnownProperties.Expect100Continue); if(ob.HasValue) bNewCont = ob.Value; if(bNewCont != bCurCont) ServicePointManager.Expect100Continue = bNewCont; } catch(Exception) { Debug.Assert(false); } #endif } private static IOWebClient CreateWebClient(IOConnectionInfo ioc) { PrepareWebAccess(ioc); IOWebClient wc = new IOWebClient(ioc); ConfigureWebClient(wc); if((ioc.UserName.Length > 0) || (ioc.Password.Length > 0)) wc.Credentials = new NetworkCredential(ioc.UserName, ioc.Password); else if(NativeLib.IsUnix()) // Mono requires credentials wc.Credentials = new NetworkCredential("anonymous", string.Empty); return wc; } private static WebRequest CreateWebRequest(IOConnectionInfo ioc) { PrepareWebAccess(ioc); WebRequest req = WebRequest.Create(ioc.Path); ConfigureWebRequest(req, ioc); if((ioc.UserName.Length > 0) || (ioc.Password.Length > 0)) req.Credentials = new NetworkCredential(ioc.UserName, ioc.Password); else if(NativeLib.IsUnix()) // Mono requires credentials req.Credentials = new NetworkCredential("anonymous", string.Empty); return req; } public static Stream OpenRead(IOConnectionInfo ioc) { RaiseIOAccessPreEvent(ioc, IOAccessType.Read); if(StrUtil.IsDataUri(ioc.Path)) { byte[] pbData = StrUtil.DataUriToData(ioc.Path); if(pbData != null) return new MemoryStream(pbData, false); } if(ioc.IsLocalFile()) return OpenReadLocal(ioc); return IocStream.WrapIfRequired(CreateWebClient(ioc).OpenRead( new Uri(ioc.Path))); } #else public static Stream OpenRead(IOConnectionInfo ioc) { RaiseIOAccessPreEvent(ioc, IOAccessType.Read); return OpenReadLocal(ioc); } #endif private static Stream OpenReadLocal(IOConnectionInfo ioc) { return new FileStream(ioc.Path, FileMode.Open, FileAccess.Read, FileShare.Read); } #if !KeePassLibSD public static Stream OpenWrite(IOConnectionInfo ioc) { if(ioc == null) { Debug.Assert(false); return null; } RaiseIOAccessPreEvent(ioc, IOAccessType.Write); if(ioc.IsLocalFile()) return OpenWriteLocal(ioc); Uri uri = new Uri(ioc.Path); Stream s; // Mono does not set HttpWebRequest.Method to POST for writes, // so one needs to set the method to PUT explicitly if(NativeLib.IsUnix() && IsHttpWebRequest(uri)) s = CreateWebClient(ioc).OpenWrite(uri, WebRequestMethods.Http.Put); else s = CreateWebClient(ioc).OpenWrite(uri); return IocStream.WrapIfRequired(s); } #else public static Stream OpenWrite(IOConnectionInfo ioc) { RaiseIOAccessPreEvent(ioc, IOAccessType.Write); return OpenWriteLocal(ioc); } #endif private static Stream OpenWriteLocal(IOConnectionInfo ioc) { return new FileStream(ioc.Path, FileMode.Create, FileAccess.Write, FileShare.None); } public static bool FileExists(IOConnectionInfo ioc) { return FileExists(ioc, false); } public static bool FileExists(IOConnectionInfo ioc, bool bThrowErrors) { if(ioc == null) { Debug.Assert(false); return false; } RaiseIOAccessPreEvent(ioc, IOAccessType.Exists); if(ioc.IsLocalFile()) return File.Exists(ioc.Path); #if !KeePassLibSD if(ioc.Path.StartsWith("ftp://", StrUtil.CaseIgnoreCmp)) { bool b = SendCommand(ioc, WebRequestMethods.Ftp.GetDateTimestamp); if(!b && bThrowErrors) throw new InvalidOperationException(); return b; } #endif try { Stream s = OpenRead(ioc); if(s == null) throw new FileNotFoundException(); try { s.ReadByte(); } catch(Exception) { } // We didn't download the file completely; close may throw // an exception -- that's okay try { s.Close(); } catch(Exception) { } } catch(Exception) { if(bThrowErrors) throw; return false; } return true; } public static void DeleteFile(IOConnectionInfo ioc) { RaiseIOAccessPreEvent(ioc, IOAccessType.Delete); if(ioc.IsLocalFile()) { File.Delete(ioc.Path); return; } #if !KeePassLibSD WebRequest req = CreateWebRequest(ioc); if(req != null) { if(IsHttpWebRequest(req)) req.Method = "DELETE"; else if(IsFtpWebRequest(req)) req.Method = WebRequestMethods.Ftp.DeleteFile; else if(IsFileWebRequest(req)) { File.Delete(UrlUtil.FileUrlToPath(ioc.Path)); return; } else req.Method = WrmDeleteFile; DisposeResponse(req.GetResponse(), true); } #endif } /// /// Rename/move a file. For local file system and WebDAV, the /// specified file is moved, i.e. the file destination can be /// in a different directory/path. In contrast, for FTP the /// file is renamed, i.e. its destination must be in the same /// directory/path. /// /// Source file path. /// Target file path. public static void RenameFile(IOConnectionInfo iocFrom, IOConnectionInfo iocTo) { RaiseIOAccessPreEvent(iocFrom, iocTo, IOAccessType.Move); if(iocFrom.IsLocalFile()) { File.Move(iocFrom.Path, iocTo.Path); return; } #if !KeePassLibSD WebRequest req = CreateWebRequest(iocFrom); if(req != null) { if(IsHttpWebRequest(req)) { #if KeePassUAP throw new NotSupportedException(); #else req.Method = "MOVE"; req.Headers.Set("Destination", iocTo.Path); // Full URL supported #endif } else if(IsFtpWebRequest(req)) { #if KeePassUAP throw new NotSupportedException(); #else req.Method = WebRequestMethods.Ftp.Rename; string strTo = UrlUtil.GetFileName(iocTo.Path); // We're affected by .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 // Prepending "./", "%2E/" or "Dummy/../" doesn't work. ((FtpWebRequest)req).RenameTo = strTo; #endif } else if(IsFileWebRequest(req)) { File.Move(UrlUtil.FileUrlToPath(iocFrom.Path), UrlUtil.FileUrlToPath(iocTo.Path)); return; } else { #if KeePassUAP throw new NotSupportedException(); #else req.Method = WrmMoveFile; req.Headers.Set(WrhMoveFileTo, iocTo.Path); #endif } #if !KeePassUAP // Unreachable code DisposeResponse(req.GetResponse(), true); #endif } #endif // using(Stream sIn = IOConnection.OpenRead(iocFrom)) // { // using(Stream sOut = IOConnection.OpenWrite(iocTo)) // { // MemUtil.CopyStream(sIn, sOut); // sOut.Close(); // } // // sIn.Close(); // } // DeleteFile(iocFrom); } #if !KeePassLibSD private static bool SendCommand(IOConnectionInfo ioc, string strMethod) { try { WebRequest req = CreateWebRequest(ioc); req.Method = strMethod; DisposeResponse(req.GetResponse(), true); } catch(Exception) { return false; } return true; } #endif internal static void DisposeResponse(WebResponse wr, bool bGetStream) { if(wr == null) return; try { if(bGetStream) { Stream s = wr.GetResponseStream(); if(s != null) s.Close(); } } catch(Exception) { Debug.Assert(false); } try { wr.Close(); } catch(Exception) { Debug.Assert(false); } } public static byte[] ReadFile(IOConnectionInfo ioc) { Stream sIn = null; MemoryStream ms = null; try { sIn = IOConnection.OpenRead(ioc); if(sIn == null) return null; ms = new MemoryStream(); MemUtil.CopyStream(sIn, ms); return ms.ToArray(); } catch(Exception) { } finally { if(sIn != null) sIn.Close(); if(ms != null) ms.Close(); } return null; } private static void RaiseIOAccessPreEvent(IOConnectionInfo ioc, IOAccessType t) { RaiseIOAccessPreEvent(ioc, null, t); } 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); } } private static bool IsHttpWebRequest(Uri uri) { if(uri == null) { Debug.Assert(false); return false; } string sch = uri.Scheme; if(sch == null) { Debug.Assert(false); return false; } return (sch.Equals("http", StrUtil.CaseIgnoreCmp) || // Uri.UriSchemeHttp sch.Equals("https", StrUtil.CaseIgnoreCmp)); // Uri.UriSchemeHttps } internal static bool IsHttpWebRequest(WebRequest wr) { if(wr == null) { Debug.Assert(false); return false; } #if KeePassUAP return IsHttpWebRequest(wr.RequestUri); #else return (wr is HttpWebRequest); #endif } internal static bool IsFtpWebRequest(WebRequest wr) { if(wr == null) { Debug.Assert(false); return false; } #if KeePassUAP return string.Equals(wr.RequestUri.Scheme, "ftp", StrUtil.CaseIgnoreCmp); #else return (wr is FtpWebRequest); #endif } private static bool IsFileWebRequest(WebRequest wr) { if(wr == null) { Debug.Assert(false); return false; } #if KeePassUAP return string.Equals(wr.RequestUri.Scheme, "file", StrUtil.CaseIgnoreCmp); #else return (wr is FileWebRequest); #endif } } } KeePassLib/Serialization/HmacBlockStream.cs0000664000000000000000000002126413222430402017700 0ustar rootroot/* KeePass Password Safe - The Open-Source Password Manager Copyright (C) 2003-2018 Dominik Reichl This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ using System; using System.Collections.Generic; using System.Diagnostics; using System.IO; using System.Text; #if !KeePassUAP using System.Security.Cryptography; #endif using KeePassLib.Resources; using KeePassLib.Utility; namespace KeePassLib.Serialization { public sealed class HmacBlockStream : Stream { private const int NbDefaultBufferSize = 1024 * 1024; // 1 MB private Stream m_sBase; private readonly bool m_bWriting; private readonly bool m_bVerify; private byte[] m_pbKey; private bool m_bEos = false; private byte[] m_pbBuffer; private int m_iBufferPos = 0; private ulong m_uBlockIndex = 0; public override bool CanRead { get { return !m_bWriting; } } public override bool CanSeek { get { return false; } } public override bool CanWrite { get { return m_bWriting; } } public override long Length { get { Debug.Assert(false); throw new NotSupportedException(); } } public override long Position { get { Debug.Assert(false); throw new NotSupportedException(); } set { Debug.Assert(false); throw new NotSupportedException(); } } public HmacBlockStream(Stream sBase, bool bWriting, bool bVerify, byte[] pbKey) { if(sBase == null) throw new ArgumentNullException("sBase"); if(pbKey == null) throw new ArgumentNullException("pbKey"); m_sBase = sBase; m_bWriting = bWriting; m_bVerify = bVerify; m_pbKey = pbKey; if(!m_bWriting) // Reading mode { if(!m_sBase.CanRead) throw new InvalidOperationException(); m_pbBuffer = MemUtil.EmptyByteArray; } else // Writing mode { if(!m_sBase.CanWrite) throw new InvalidOperationException(); m_pbBuffer = new byte[NbDefaultBufferSize]; } } protected override void Dispose(bool disposing) { if(disposing && (m_sBase != null)) { if(m_bWriting) { if(m_iBufferPos == 0) // No data left in buffer WriteSafeBlock(); // Write terminating block else { WriteSafeBlock(); // Write remaining buffered data WriteSafeBlock(); // Write terminating block } Flush(); } m_sBase.Close(); m_sBase = null; } base.Dispose(disposing); } public override void Flush() { Debug.Assert(m_sBase != null); // Object should not be disposed if(m_bWriting && (m_sBase != null)) m_sBase.Flush(); } public override long Seek(long lOffset, SeekOrigin soOrigin) { Debug.Assert(false); throw new NotSupportedException(); } public override void SetLength(long lValue) { Debug.Assert(false); throw new NotSupportedException(); } internal static byte[] GetHmacKey64(byte[] pbKey, ulong uBlockIndex) { if(pbKey == null) throw new ArgumentNullException("pbKey"); Debug.Assert(pbKey.Length == 64); // We are computing the HMAC using SHA-256, whose internal // block size is 512 bits; thus create a key that is 512 // bits long (using SHA-512) byte[] pbBlockKey; using(SHA512Managed h = new SHA512Managed()) { byte[] pbIndex = MemUtil.UInt64ToBytes(uBlockIndex); h.TransformBlock(pbIndex, 0, pbIndex.Length, pbIndex, 0); h.TransformBlock(pbKey, 0, pbKey.Length, pbKey, 0); h.TransformFinalBlock(MemUtil.EmptyByteArray, 0, 0); pbBlockKey = h.Hash; } #if DEBUG byte[] pbZero = new byte[64]; Debug.Assert((pbBlockKey.Length == 64) && !MemUtil.ArraysEqual( pbBlockKey, pbZero)); // Ensure we own pbBlockKey #endif return pbBlockKey; } public override int Read(byte[] pbBuffer, int iOffset, int nCount) { if(m_bWriting) throw new InvalidOperationException(); int nRemaining = nCount; while(nRemaining > 0) { if(m_iBufferPos == m_pbBuffer.Length) { if(!ReadSafeBlock()) return (nCount - nRemaining); // Bytes actually read } int nCopy = Math.Min(m_pbBuffer.Length - m_iBufferPos, nRemaining); Debug.Assert(nCopy > 0); Array.Copy(m_pbBuffer, m_iBufferPos, pbBuffer, iOffset, nCopy); iOffset += nCopy; m_iBufferPos += nCopy; nRemaining -= nCopy; } return nCount; } private bool ReadSafeBlock() { if(m_bEos) return false; // End of stream reached already byte[] pbStoredHmac = MemUtil.Read(m_sBase, 32); if((pbStoredHmac == null) || (pbStoredHmac.Length != 32)) throw new EndOfStreamException(KLRes.FileCorrupted + " " + KLRes.FileIncomplete); // Block index is implicit: it's used in the HMAC computation, // but does not need to be stored // byte[] pbBlockIndex = MemUtil.Read(m_sBase, 8); // if((pbBlockIndex == null) || (pbBlockIndex.Length != 8)) // throw new EndOfStreamException(); // ulong uBlockIndex = MemUtil.BytesToUInt64(pbBlockIndex); // if((uBlockIndex != m_uBlockIndex) && m_bVerify) // throw new InvalidDataException(); byte[] pbBlockIndex = MemUtil.UInt64ToBytes(m_uBlockIndex); byte[] pbBlockSize = MemUtil.Read(m_sBase, 4); if((pbBlockSize == null) || (pbBlockSize.Length != 4)) throw new EndOfStreamException(KLRes.FileCorrupted + " " + KLRes.FileIncomplete); int nBlockSize = MemUtil.BytesToInt32(pbBlockSize); if(nBlockSize < 0) throw new InvalidDataException(KLRes.FileCorrupted); m_iBufferPos = 0; m_pbBuffer = MemUtil.Read(m_sBase, nBlockSize); if((m_pbBuffer == null) || ((m_pbBuffer.Length != nBlockSize) && m_bVerify)) throw new EndOfStreamException(KLRes.FileCorrupted + " " + KLRes.FileIncompleteExpc); if(m_bVerify) { byte[] pbCmpHmac; byte[] pbBlockKey = GetHmacKey64(m_pbKey, m_uBlockIndex); using(HMACSHA256 h = new HMACSHA256(pbBlockKey)) { h.TransformBlock(pbBlockIndex, 0, pbBlockIndex.Length, pbBlockIndex, 0); h.TransformBlock(pbBlockSize, 0, pbBlockSize.Length, pbBlockSize, 0); if(m_pbBuffer.Length > 0) h.TransformBlock(m_pbBuffer, 0, m_pbBuffer.Length, m_pbBuffer, 0); h.TransformFinalBlock(MemUtil.EmptyByteArray, 0, 0); pbCmpHmac = h.Hash; } MemUtil.ZeroByteArray(pbBlockKey); if(!MemUtil.ArraysEqual(pbCmpHmac, pbStoredHmac)) throw new InvalidDataException(KLRes.FileCorrupted); } ++m_uBlockIndex; if(nBlockSize == 0) { m_bEos = true; return false; // No further data available } return true; } public override void Write(byte[] pbBuffer, int iOffset, int nCount) { if(!m_bWriting) throw new InvalidOperationException(); while(nCount > 0) { if(m_iBufferPos == m_pbBuffer.Length) WriteSafeBlock(); int nCopy = Math.Min(m_pbBuffer.Length - m_iBufferPos, nCount); Debug.Assert(nCopy > 0); Array.Copy(pbBuffer, iOffset, m_pbBuffer, m_iBufferPos, nCopy); iOffset += nCopy; m_iBufferPos += nCopy; nCount -= nCopy; } } private void WriteSafeBlock() { byte[] pbBlockIndex = MemUtil.UInt64ToBytes(m_uBlockIndex); int cbBlockSize = m_iBufferPos; byte[] pbBlockSize = MemUtil.Int32ToBytes(cbBlockSize); byte[] pbBlockHmac; byte[] pbBlockKey = GetHmacKey64(m_pbKey, m_uBlockIndex); using(HMACSHA256 h = new HMACSHA256(pbBlockKey)) { h.TransformBlock(pbBlockIndex, 0, pbBlockIndex.Length, pbBlockIndex, 0); h.TransformBlock(pbBlockSize, 0, pbBlockSize.Length, pbBlockSize, 0); if(cbBlockSize > 0) h.TransformBlock(m_pbBuffer, 0, cbBlockSize, m_pbBuffer, 0); h.TransformFinalBlock(MemUtil.EmptyByteArray, 0, 0); pbBlockHmac = h.Hash; } MemUtil.ZeroByteArray(pbBlockKey); MemUtil.Write(m_sBase, pbBlockHmac); // MemUtil.Write(m_sBase, pbBlockIndex); // Implicit MemUtil.Write(m_sBase, pbBlockSize); if(cbBlockSize > 0) m_sBase.Write(m_pbBuffer, 0, cbBlockSize); ++m_uBlockIndex; m_iBufferPos = 0; } } } KeePassLib/Serialization/FileTransactionEx.cs0000664000000000000000000001400713222430402020260 0ustar rootroot/* KeePass Password Safe - The Open-Source Password Manager Copyright (C) 2003-2018 Dominik Reichl This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ using System; using System.Collections.Generic; using System.Diagnostics; using System.IO; using System.Text; #if (!KeePassLibSD && !KeePassUAP) using System.Security.AccessControl; #endif using KeePassLib.Native; using KeePassLib.Resources; using KeePassLib.Utility; namespace KeePassLib.Serialization { public sealed class FileTransactionEx { private bool m_bTransacted; private IOConnectionInfo m_iocBase; private IOConnectionInfo m_iocTemp; private bool m_bMadeUnhidden = false; private const string StrTempSuffix = ".tmp"; private static Dictionary g_dEnabled = new Dictionary(StrUtil.CaseIgnoreComparer); private static bool g_bExtraSafe = false; internal static bool ExtraSafe { get { return g_bExtraSafe; } set { g_bExtraSafe = value; } } public FileTransactionEx(IOConnectionInfo iocBaseFile) { Initialize(iocBaseFile, true); } public FileTransactionEx(IOConnectionInfo iocBaseFile, bool bTransacted) { Initialize(iocBaseFile, bTransacted); } 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 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 Stream OpenWrite() { if(!m_bTransacted) m_bMadeUnhidden = UrlUtil.UnhideFile(m_iocTemp.Path); else // m_bTransacted { try { IOConnection.DeleteFile(m_iocTemp); } catch(Exception) { } } return IOConnection.OpenWrite(m_iocTemp); } public void CommitWrite() { if(m_bTransacted) CommitWriteTransaction(); else // !m_bTransacted { if(m_bMadeUnhidden) UrlUtil.HideFile(m_iocTemp.Path, true); // Hide again } } private void CommitWriteTransaction() { bool bMadeUnhidden = UrlUtil.UnhideFile(m_iocBase.Path); #if (!KeePassLibSD && !KeePassUAP) FileSecurity bkSecurity = null; bool bEfsEncrypted = false; #endif if(g_bExtraSafe) { if(!IOConnection.FileExists(m_iocTemp)) throw new FileNotFoundException(m_iocTemp.Path + MessageService.NewLine + KLRes.FileSaveFailed); } if(IOConnection.FileExists(m_iocBase)) { #if !KeePassLibSD if(m_iocBase.IsLocalFile()) { try { #if !KeePassUAP FileAttributes faBase = File.GetAttributes(m_iocBase.Path); bEfsEncrypted = ((long)(faBase & FileAttributes.Encrypted) != 0); #endif DateTime tCreation = File.GetCreationTimeUtc(m_iocBase.Path); File.SetCreationTimeUtc(m_iocTemp.Path, tCreation); #if !KeePassUAP // May throw with Mono bkSecurity = File.GetAccessControl(m_iocBase.Path); #endif } catch(Exception) { Debug.Assert(NativeLib.IsUnix()); } } #endif IOConnection.DeleteFile(m_iocBase); } IOConnection.RenameFile(m_iocTemp, m_iocBase); #if (!KeePassLibSD && !KeePassUAP) if(m_iocBase.IsLocalFile()) { try { if(bEfsEncrypted) { try { File.Encrypt(m_iocBase.Path); } catch(Exception) { Debug.Assert(false); } } if(bkSecurity != null) File.SetAccessControl(m_iocBase.Path, bkSecurity); } catch(Exception) { Debug.Assert(false); } } #endif if(bMadeUnhidden) UrlUtil.HideFile(m_iocBase.Path, true); // Hide again } // For plugins public static void Configure(string strPrefix, bool? obTransacted) { if(string.IsNullOrEmpty(strPrefix)) { Debug.Assert(false); return; } if(obTransacted.HasValue) g_dEnabled[strPrefix] = obTransacted.Value; else g_dEnabled.Remove(strPrefix); } } } KeePassLib/Serialization/KdbxFile.cs0000664000000000000000000004410413223475706016410 0ustar rootroot/* KeePass Password Safe - The Open-Source Password Manager Copyright (C) 2003-2018 Dominik Reichl This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ using System; using System.Collections.Generic; using System.Diagnostics; using System.Globalization; using System.IO; using System.Security; using System.Text; using System.Xml; #if !KeePassUAP using System.Security.Cryptography; #endif using KeePassLib.Collections; using KeePassLib.Cryptography; using KeePassLib.Cryptography.Cipher; using KeePassLib.Cryptography.KeyDerivation; using KeePassLib.Delegates; using KeePassLib.Interfaces; using KeePassLib.Resources; using KeePassLib.Security; using KeePassLib.Utility; namespace KeePassLib.Serialization { /// /// The KdbxFile class supports saving the data to various /// formats. /// public enum KdbxFormat { /// /// The default, encrypted file format. /// Default = 0, /// /// Use this flag when exporting data to a plain-text XML file. /// PlainXml } /// /// Serialization to KeePass KDBX files. /// public sealed partial class KdbxFile { /// /// File identifier, first 32-bit value. /// internal const uint FileSignature1 = 0x9AA2D903; /// /// File identifier, second 32-bit value. /// internal const uint FileSignature2 = 0xB54BFB67; /// /// File version of files saved by the current KdbxFile class. /// KeePass 2.07 has version 1.01, 2.08 has 1.02, 2.09 has 2.00, /// 2.10 has 2.02, 2.11 has 2.04, 2.15 has 3.00, 2.20 has 3.01. /// The first 2 bytes are critical (i.e. loading will fail, if the /// file version is too high), the last 2 bytes are informational. /// private const uint FileVersion32 = 0x00040000; internal const uint FileVersion32_4 = 0x00040000; // First of 4.x series internal const uint FileVersion32_3 = 0x00030001; // Old format 3.1 private const uint FileVersionCriticalMask = 0xFFFF0000; // KeePass 1.x signature internal const uint FileSignatureOld1 = 0x9AA2D903; internal const uint FileSignatureOld2 = 0xB54BFB65; // KeePass 2.x pre-release (alpha and beta) signature internal const uint FileSignaturePreRelease1 = 0x9AA2D903; internal const uint FileSignaturePreRelease2 = 0xB54BFB66; private const string ElemDocNode = "KeePassFile"; private const string ElemMeta = "Meta"; private const string ElemRoot = "Root"; private const string ElemGroup = "Group"; private const string ElemEntry = "Entry"; private const string ElemGenerator = "Generator"; private const string ElemHeaderHash = "HeaderHash"; private const string ElemSettingsChanged = "SettingsChanged"; private const string ElemDbName = "DatabaseName"; private const string ElemDbNameChanged = "DatabaseNameChanged"; private const string ElemDbDesc = "DatabaseDescription"; private const string ElemDbDescChanged = "DatabaseDescriptionChanged"; private const string ElemDbDefaultUser = "DefaultUserName"; private const string ElemDbDefaultUserChanged = "DefaultUserNameChanged"; private const string ElemDbMntncHistoryDays = "MaintenanceHistoryDays"; private const string ElemDbColor = "Color"; private const string ElemDbKeyChanged = "MasterKeyChanged"; private const string ElemDbKeyChangeRec = "MasterKeyChangeRec"; private const string ElemDbKeyChangeForce = "MasterKeyChangeForce"; private const string ElemDbKeyChangeForceOnce = "MasterKeyChangeForceOnce"; private const string ElemRecycleBinEnabled = "RecycleBinEnabled"; private const string ElemRecycleBinUuid = "RecycleBinUUID"; private const string ElemRecycleBinChanged = "RecycleBinChanged"; private const string ElemEntryTemplatesGroup = "EntryTemplatesGroup"; private const string ElemEntryTemplatesGroupChanged = "EntryTemplatesGroupChanged"; private const string ElemHistoryMaxItems = "HistoryMaxItems"; private const string ElemHistoryMaxSize = "HistoryMaxSize"; private const string ElemLastSelectedGroup = "LastSelectedGroup"; private const string ElemLastTopVisibleGroup = "LastTopVisibleGroup"; private const string ElemMemoryProt = "MemoryProtection"; private const string ElemProtTitle = "ProtectTitle"; private const string ElemProtUserName = "ProtectUserName"; private const string ElemProtPassword = "ProtectPassword"; private const string ElemProtUrl = "ProtectURL"; private const string ElemProtNotes = "ProtectNotes"; // private const string ElemProtAutoHide = "AutoEnableVisualHiding"; private const string ElemCustomIcons = "CustomIcons"; private const string ElemCustomIconItem = "Icon"; private const string ElemCustomIconItemID = "UUID"; private const string ElemCustomIconItemData = "Data"; private const string ElemAutoType = "AutoType"; private const string ElemHistory = "History"; private const string ElemName = "Name"; private const string ElemNotes = "Notes"; private const string ElemUuid = "UUID"; private const string ElemIcon = "IconID"; private const string ElemCustomIconID = "CustomIconUUID"; private const string ElemFgColor = "ForegroundColor"; private const string ElemBgColor = "BackgroundColor"; private const string ElemOverrideUrl = "OverrideURL"; private const string ElemTimes = "Times"; private const string ElemTags = "Tags"; private const string ElemCreationTime = "CreationTime"; private const string ElemLastModTime = "LastModificationTime"; private const string ElemLastAccessTime = "LastAccessTime"; private const string ElemExpiryTime = "ExpiryTime"; private const string ElemExpires = "Expires"; private const string ElemUsageCount = "UsageCount"; private const string ElemLocationChanged = "LocationChanged"; private const string ElemGroupDefaultAutoTypeSeq = "DefaultAutoTypeSequence"; private const string ElemEnableAutoType = "EnableAutoType"; private const string ElemEnableSearching = "EnableSearching"; private const string ElemString = "String"; private const string ElemBinary = "Binary"; private const string ElemKey = "Key"; private const string ElemValue = "Value"; private const string ElemAutoTypeEnabled = "Enabled"; private const string ElemAutoTypeObfuscation = "DataTransferObfuscation"; private const string ElemAutoTypeDefaultSeq = "DefaultSequence"; private const string ElemAutoTypeItem = "Association"; private const string ElemWindow = "Window"; private const string ElemKeystrokeSequence = "KeystrokeSequence"; private const string ElemBinaries = "Binaries"; private const string AttrId = "ID"; private const string AttrRef = "Ref"; private const string AttrProtected = "Protected"; private const string AttrProtectedInMemPlainXml = "ProtectInMemory"; private const string AttrCompressed = "Compressed"; private const string ElemIsExpanded = "IsExpanded"; private const string ElemLastTopVisibleEntry = "LastTopVisibleEntry"; private const string ElemDeletedObjects = "DeletedObjects"; private const string ElemDeletedObject = "DeletedObject"; private const string ElemDeletionTime = "DeletionTime"; private const string ValFalse = "False"; private const string ValTrue = "True"; private const string ElemCustomData = "CustomData"; private const string ElemStringDictExItem = "Item"; private PwDatabase m_pwDatabase; // Not null, see constructor private bool m_bUsedOnce = false; private XmlWriter m_xmlWriter = null; private CryptoRandomStream m_randomStream = null; private KdbxFormat m_format = KdbxFormat.Default; private IStatusLogger m_slLogger = null; private uint m_uFileVersion = 0; private byte[] m_pbMasterSeed = null; // private byte[] m_pbTransformSeed = null; private byte[] m_pbEncryptionIV = null; private byte[] m_pbStreamStartBytes = null; // ArcFourVariant only for backward compatibility; KeePass defaults // to a more secure algorithm when *writing* databases private CrsAlgorithm m_craInnerRandomStream = CrsAlgorithm.ArcFourVariant; private byte[] m_pbInnerRandomStreamKey = null; private ProtectedBinarySet m_pbsBinaries = new ProtectedBinarySet(); private byte[] m_pbHashOfHeader = null; private byte[] m_pbHashOfFileOnDisk = null; private readonly DateTime m_dtNow = DateTime.UtcNow; // Cache current time private const uint NeutralLanguageOffset = 0x100000; // 2^20, see 32-bit Unicode specs private const uint NeutralLanguageIDSec = 0x7DC5C; // See 32-bit Unicode specs private const uint NeutralLanguageID = NeutralLanguageOffset + NeutralLanguageIDSec; private static bool m_bLocalizedNames = false; private enum KdbxHeaderFieldID : byte { EndOfHeader = 0, Comment = 1, CipherID = 2, CompressionFlags = 3, MasterSeed = 4, TransformSeed = 5, // KDBX 3.1, for backward compatibility only TransformRounds = 6, // KDBX 3.1, for backward compatibility only EncryptionIV = 7, InnerRandomStreamKey = 8, // KDBX 3.1, for backward compatibility only StreamStartBytes = 9, // KDBX 3.1, for backward compatibility only InnerRandomStreamID = 10, // KDBX 3.1, for backward compatibility only KdfParameters = 11, // KDBX 4, superseding Transform* PublicCustomData = 12 // KDBX 4 } // Inner header in KDBX >= 4 files private enum KdbxInnerHeaderFieldID : byte { EndOfHeader = 0, InnerRandomStreamID = 1, // Supersedes KdbxHeaderFieldID.InnerRandomStreamID InnerRandomStreamKey = 2, // Supersedes KdbxHeaderFieldID.InnerRandomStreamKey Binary = 3 } [Flags] private enum KdbxBinaryFlags : byte { None = 0, Protected = 1 } public byte[] HashOfFileOnDisk { get { return m_pbHashOfFileOnDisk; } } private bool m_bRepairMode = false; public bool RepairMode { get { return m_bRepairMode; } set { m_bRepairMode = value; } } private uint m_uForceVersion = 0; internal uint ForceVersion { get { return m_uForceVersion; } set { m_uForceVersion = value; } } private string m_strDetachBins = null; /// /// Detach binaries when opening a file. If this isn't null, /// all binaries are saved to the specified path and are removed /// from the database. /// public string DetachBinaries { get { return m_strDetachBins; } set { m_strDetachBins = value; } } /// /// Default constructor. /// /// The PwDatabase instance that the /// class will load file data into or use to create a KDBX file. public KdbxFile(PwDatabase pwDataStore) { Debug.Assert(pwDataStore != null); if(pwDataStore == null) throw new ArgumentNullException("pwDataStore"); m_pwDatabase = pwDataStore; } /// /// Call this once to determine the current localization settings. /// public static void DetermineLanguageId() { // Test if localized names should be used. If localized names are used, // the m_bLocalizedNames value must be set to true. By default, localized // names should be used! (Otherwise characters could be corrupted // because of different code pages). unchecked { uint uTest = 0; foreach(char ch in PwDatabase.LocalizedAppName) uTest = uTest * 5 + ch; m_bLocalizedNames = (uTest != NeutralLanguageID); } } private uint GetMinKdbxVersion() { if(m_uForceVersion != 0) return m_uForceVersion; // See also KeePassKdb2x3.Export (KDBX 3.1 export module) AesKdf kdfAes = new AesKdf(); if(!kdfAes.Uuid.Equals(m_pwDatabase.KdfParameters.KdfUuid)) return FileVersion32; if(m_pwDatabase.PublicCustomData.Count > 0) return FileVersion32; bool bCustomData = false; GroupHandler gh = delegate(PwGroup pg) { if(pg == null) { Debug.Assert(false); return true; } if(pg.CustomData.Count > 0) { bCustomData = true; return false; } return true; }; EntryHandler eh = delegate(PwEntry pe) { if(pe == null) { Debug.Assert(false); return true; } if(pe.CustomData.Count > 0) { bCustomData = true; return false; } return true; }; gh(m_pwDatabase.RootGroup); m_pwDatabase.RootGroup.TraverseTree(TraversalMethod.PreOrder, gh, eh); if(bCustomData) return FileVersion32; return FileVersion32_3; // KDBX 3.1 is sufficient } private void ComputeKeys(out byte[] pbCipherKey, int cbCipherKey, out byte[] pbHmacKey64) { byte[] pbCmp = new byte[32 + 32 + 1]; try { Debug.Assert(m_pbMasterSeed != null); if(m_pbMasterSeed == null) throw new ArgumentNullException("m_pbMasterSeed"); Debug.Assert(m_pbMasterSeed.Length == 32); if(m_pbMasterSeed.Length != 32) throw new FormatException(KLRes.MasterSeedLengthInvalid); Array.Copy(m_pbMasterSeed, 0, pbCmp, 0, 32); Debug.Assert(m_pwDatabase != null); Debug.Assert(m_pwDatabase.MasterKey != null); ProtectedBinary pbinUser = m_pwDatabase.MasterKey.GenerateKey32( m_pwDatabase.KdfParameters); Debug.Assert(pbinUser != null); if(pbinUser == null) throw new SecurityException(KLRes.InvalidCompositeKey); byte[] pUserKey32 = pbinUser.ReadData(); if((pUserKey32 == null) || (pUserKey32.Length != 32)) throw new SecurityException(KLRes.InvalidCompositeKey); Array.Copy(pUserKey32, 0, pbCmp, 32, 32); MemUtil.ZeroByteArray(pUserKey32); pbCipherKey = CryptoUtil.ResizeKey(pbCmp, 0, 64, cbCipherKey); pbCmp[64] = 1; using(SHA512Managed h = new SHA512Managed()) { pbHmacKey64 = h.ComputeHash(pbCmp); } } finally { MemUtil.ZeroByteArray(pbCmp); } } private ICipherEngine GetCipher(out int cbEncKey, out int cbEncIV) { PwUuid pu = m_pwDatabase.DataCipherUuid; ICipherEngine iCipher = CipherPool.GlobalPool.GetCipher(pu); if(iCipher == null) // CryptographicExceptions are translated to "file corrupted" throw new Exception(KLRes.FileUnknownCipher + MessageService.NewParagraph + KLRes.FileNewVerOrPlgReq + MessageService.NewParagraph + "UUID: " + pu.ToHexString() + "."); ICipherEngine2 iCipher2 = (iCipher as ICipherEngine2); if(iCipher2 != null) { cbEncKey = iCipher2.KeyLength; if(cbEncKey < 0) throw new InvalidOperationException("EncKey.Length"); cbEncIV = iCipher2.IVLength; if(cbEncIV < 0) throw new InvalidOperationException("EncIV.Length"); } else { cbEncKey = 32; cbEncIV = 16; } return iCipher; } private Stream EncryptStream(Stream s, ICipherEngine iCipher, byte[] pbKey, int cbIV, bool bEncrypt) { byte[] pbIV = (m_pbEncryptionIV ?? MemUtil.EmptyByteArray); if(pbIV.Length != cbIV) { Debug.Assert(false); throw new Exception(KLRes.FileCorrupted); } if(bEncrypt) return iCipher.EncryptStream(s, pbKey, pbIV); return iCipher.DecryptStream(s, pbKey, pbIV); } private byte[] ComputeHeaderHmac(byte[] pbHeader, byte[] pbKey) { byte[] pbHeaderHmac; byte[] pbBlockKey = HmacBlockStream.GetHmacKey64( pbKey, ulong.MaxValue); using(HMACSHA256 h = new HMACSHA256(pbBlockKey)) { pbHeaderHmac = h.ComputeHash(pbHeader); } MemUtil.ZeroByteArray(pbBlockKey); return pbHeaderHmac; } private void CloseStreams(List lStreams) { if(lStreams == null) { Debug.Assert(false); return; } // Typically, closing a stream also closes its base // stream; however, there may be streams that do not // do this (e.g. some cipher plugin), thus for safety // we close all streams manually, from the innermost // to the outermost for(int i = lStreams.Count - 1; i >= 0; --i) { // Check for duplicates Debug.Assert((lStreams.IndexOf(lStreams[i]) == i) && (lStreams.LastIndexOf(lStreams[i]) == i)); try { lStreams[i].Close(); } // Unnecessary exception from CryptoStream with // RijndaelManagedTransform when a stream hasn't been // read completely (e.g. incorrect master key) catch(CryptographicException) { } catch(Exception) { Debug.Assert(false); } } // Do not clear the list } private void CleanUpInnerRandomStream() { if(m_randomStream != null) m_randomStream.Dispose(); if(m_pbInnerRandomStreamKey != null) MemUtil.ZeroByteArray(m_pbInnerRandomStreamKey); } private static void SaveBinary(string strName, ProtectedBinary pb, string strSaveDir) { if(pb == null) { Debug.Assert(false); return; } if(string.IsNullOrEmpty(strName)) strName = "File.bin"; string strPath; int iTry = 1; do { strPath = UrlUtil.EnsureTerminatingSeparator(strSaveDir, false); string strExt = UrlUtil.GetExtension(strName); string strDesc = UrlUtil.StripExtension(strName); strPath += strDesc; if(iTry > 1) strPath += " (" + iTry.ToString(NumberFormatInfo.InvariantInfo) + ")"; if(!string.IsNullOrEmpty(strExt)) strPath += "." + strExt; ++iTry; } while(File.Exists(strPath)); #if !KeePassLibSD byte[] pbData = pb.ReadData(); File.WriteAllBytes(strPath, pbData); MemUtil.ZeroByteArray(pbData); #else FileStream fs = new FileStream(strPath, FileMode.Create, FileAccess.Write, FileShare.None); byte[] pbData = pb.ReadData(); fs.Write(pbData, 0, pbData.Length); fs.Close(); #endif } } } KeePassLib/Serialization/IocPropertyInfo.cs0000664000000000000000000000477713222430402020006 0ustar rootroot/* KeePass Password Safe - The Open-Source Password Manager Copyright (C) 2003-2018 Dominik Reichl This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ using System; using System.Collections.Generic; using System.Diagnostics; using System.Text; using KeePassLib.Utility; namespace KeePassLib.Serialization { public sealed class IocPropertyInfo { private readonly string m_strName; public string Name { get { return m_strName; } } private readonly Type m_t; public Type Type { get { return m_t; } } private string m_strDisplayName; public string DisplayName { get { return m_strDisplayName; } set { if(value == null) throw new ArgumentNullException("value"); m_strDisplayName = value; } } private List m_lProtocols = new List(); public IEnumerable Protocols { get { return m_lProtocols; } } public IocPropertyInfo(string strName, Type t, string strDisplayName, string[] vProtocols) { if(strName == null) throw new ArgumentNullException("strName"); if(t == null) throw new ArgumentNullException("t"); if(strDisplayName == null) throw new ArgumentNullException("strDisplayName"); m_strName = strName; m_t = t; m_strDisplayName = strDisplayName; AddProtocols(vProtocols); } public void AddProtocols(string[] v) { if(v == null) { Debug.Assert(false); return; } foreach(string strProtocol in v) { if(strProtocol == null) continue; string str = strProtocol.Trim(); if(str.Length == 0) continue; bool bFound = false; foreach(string strEx in m_lProtocols) { if(strEx.Equals(str, StrUtil.CaseIgnoreCmp)) { bFound = true; break; } } if(!bFound) m_lProtocols.Add(str); } } } } KeePassLib/Serialization/IOConnectionInfo.cs0000664000000000000000000002215513222430402020044 0ustar rootroot/* KeePass Password Safe - The Open-Source Password Manager Copyright (C) 2003-2018 Dominik Reichl This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ using System; using System.Collections.Generic; using System.ComponentModel; using System.Diagnostics; using System.IO; using System.Text; using System.Xml.Serialization; using KeePassLib.Interfaces; using KeePassLib.Utility; namespace KeePassLib.Serialization { public enum IOCredSaveMode { /// /// Do not remember user name or password. /// NoSave = 0, /// /// Remember the user name only, not the password. /// UserNameOnly, /// /// Save both user name and password. /// SaveCred } public enum IOCredProtMode { None = 0, Obf } /* public enum IOFileFormatHint { None = 0, Deprecated } */ public sealed class IOConnectionInfo : IDeepCloneable { // private IOFileFormatHint m_ioHint = IOFileFormatHint.None; private string m_strUrl = string.Empty; public string Path { get { return m_strUrl; } set { Debug.Assert(value != null); if(value == null) throw new ArgumentNullException("value"); m_strUrl = value; } } private string m_strUser = string.Empty; [DefaultValue("")] public string UserName { get { return m_strUser; } set { Debug.Assert(value != null); if(value == null) throw new ArgumentNullException("value"); m_strUser = value; } } private string m_strPassword = string.Empty; [DefaultValue("")] public string Password { get { return m_strPassword; } set { Debug.Assert(value != null); if(value == null) throw new ArgumentNullException("value"); m_strPassword = value; } } private IOCredProtMode m_ioCredProtMode = IOCredProtMode.None; public IOCredProtMode CredProtMode { get { return m_ioCredProtMode; } set { m_ioCredProtMode = value; } } private IOCredSaveMode m_ioCredSaveMode = IOCredSaveMode.NoSave; public IOCredSaveMode CredSaveMode { get { return m_ioCredSaveMode; } set { m_ioCredSaveMode = value; } } private bool m_bComplete = false; [XmlIgnore] public bool IsComplete // Credentials etc. fully specified { get { return m_bComplete; } set { m_bComplete = value; } } /* public IOFileFormatHint FileFormatHint { get { return m_ioHint; } set { m_ioHint = value; } } */ private IocProperties m_props = new IocProperties(); [XmlIgnore] public IocProperties Properties { get { return m_props; } set { if(value == null) throw new ArgumentNullException("value"); m_props = value; } } /// /// For serialization only; use Properties in code. /// [DefaultValue("")] public string PropertiesEx { get { return m_props.Serialize(); } set { if(value == null) throw new ArgumentNullException("value"); IocProperties p = IocProperties.Deserialize(value); Debug.Assert(p != null); m_props = (p ?? new IocProperties()); } } public IOConnectionInfo CloneDeep() { IOConnectionInfo ioc = (IOConnectionInfo)this.MemberwiseClone(); ioc.m_props = m_props.CloneDeep(); return ioc; } #if DEBUG // For debugger display only public override string ToString() { return GetDisplayName(); } #endif /* /// /// Serialize the current connection info to a string. Credentials /// are serialized based on the CredSaveMode property. /// /// Input object to be serialized. /// Serialized object as string. public static string SerializeToString(IOConnectionInfo iocToCompile) { Debug.Assert(iocToCompile != null); if(iocToCompile == null) throw new ArgumentNullException("iocToCompile"); string strUrl = iocToCompile.Path; string strUser = TransformUnreadable(iocToCompile.UserName, true); string strPassword = TransformUnreadable(iocToCompile.Password, true); string strAll = strUrl + strUser + strPassword + "CUN"; char chSep = StrUtil.GetUnusedChar(strAll); if(chSep == char.MinValue) throw new FormatException(); StringBuilder sb = new StringBuilder(); sb.Append(chSep); sb.Append(strUrl); sb.Append(chSep); if(iocToCompile.CredSaveMode == IOCredSaveMode.SaveCred) { sb.Append('C'); sb.Append(chSep); sb.Append(strUser); sb.Append(chSep); sb.Append(strPassword); } else if(iocToCompile.CredSaveMode == IOCredSaveMode.UserNameOnly) { sb.Append('U'); sb.Append(chSep); sb.Append(strUser); sb.Append(chSep); } else // Don't remember credentials { sb.Append('N'); sb.Append(chSep); sb.Append(chSep); } return sb.ToString(); } public static IOConnectionInfo UnserializeFromString(string strToDecompile) { Debug.Assert(strToDecompile != null); if(strToDecompile == null) throw new ArgumentNullException("strToDecompile"); if(strToDecompile.Length <= 1) throw new ArgumentException(); char chSep = strToDecompile[0]; string[] vParts = strToDecompile.Substring(1, strToDecompile.Length - 1).Split(new char[]{ chSep }); if(vParts.Length < 4) throw new ArgumentException(); IOConnectionInfo s = new IOConnectionInfo(); s.Path = vParts[0]; if(vParts[1] == "C") s.CredSaveMode = IOCredSaveMode.SaveCred; else if(vParts[1] == "U") s.CredSaveMode = IOCredSaveMode.UserNameOnly; else s.CredSaveMode = IOCredSaveMode.NoSave; s.UserName = TransformUnreadable(vParts[2], false); s.Password = TransformUnreadable(vParts[3], false); return s; } */ /* /// /// Very simple string protection. Doesn't really encrypt the input /// string, only encodes it that it's not readable on the first glance. /// /// The string to encode/decode. /// If true, the string will be encoded, /// otherwise it'll be decoded. /// Encoded/decoded string. private static string TransformUnreadable(string strToEncode, bool bEncode) { Debug.Assert(strToEncode != null); if(strToEncode == null) throw new ArgumentNullException("strToEncode"); if(bEncode) { byte[] pbUtf8 = StrUtil.Utf8.GetBytes(strToEncode); unchecked { for(int iPos = 0; iPos < pbUtf8.Length; ++iPos) pbUtf8[iPos] += (byte)(iPos * 11); } return Convert.ToBase64String(pbUtf8); } else // Decode { byte[] pbBase = Convert.FromBase64String(strToEncode); unchecked { for(int iPos = 0; iPos < pbBase.Length; ++iPos) pbBase[iPos] -= (byte)(iPos * 11); } return StrUtil.Utf8.GetString(pbBase, 0, pbBase.Length); } } */ public string GetDisplayName() { string str = m_strUrl; if(m_strUser.Length > 0) str += (" (" + m_strUser + ")"); return str; } public bool IsEmpty() { return (m_strUrl.Length == 0); } public static IOConnectionInfo FromPath(string strPath) { IOConnectionInfo ioc = new IOConnectionInfo(); ioc.Path = strPath; ioc.CredSaveMode = IOCredSaveMode.NoSave; return ioc; } public bool CanProbablyAccess() { if(IsLocalFile()) return File.Exists(m_strUrl); return true; } public bool IsLocalFile() { // Not just ":/", see e.g. AppConfigEx.ChangePathRelAbs return (m_strUrl.IndexOf("://") < 0); } public void ClearCredentials(bool bDependingOnRememberMode) { if((bDependingOnRememberMode == false) || (m_ioCredSaveMode == IOCredSaveMode.NoSave)) { m_strUser = string.Empty; } if((bDependingOnRememberMode == false) || (m_ioCredSaveMode == IOCredSaveMode.NoSave) || (m_ioCredSaveMode == IOCredSaveMode.UserNameOnly)) { m_strPassword = string.Empty; } } public void Obfuscate(bool bObf) { if(bObf && (m_ioCredProtMode == IOCredProtMode.None)) { m_strPassword = StrUtil.Obfuscate(m_strPassword); m_ioCredProtMode = IOCredProtMode.Obf; } else if(!bObf && (m_ioCredProtMode == IOCredProtMode.Obf)) { m_strPassword = StrUtil.Deobfuscate(m_strPassword); m_ioCredProtMode = IOCredProtMode.None; } } } } KeePassLib/Serialization/KdbxFile.Read.cs0000664000000000000000000004342013222430402017241 0ustar rootroot/* KeePass Password Safe - The Open-Source Password Manager Copyright (C) 2003-2018 Dominik Reichl This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ // #define KDBX_BENCHMARK using System; using System.Collections.Generic; using System.Diagnostics; using System.IO; using System.Security; using System.Text; using System.Xml; #if !KeePassUAP using System.Security.Cryptography; #endif #if !KeePassLibSD using System.IO.Compression; #else using KeePassLibSD; #endif using KeePassLib.Collections; using KeePassLib.Cryptography; using KeePassLib.Cryptography.Cipher; using KeePassLib.Cryptography.KeyDerivation; using KeePassLib.Interfaces; using KeePassLib.Keys; using KeePassLib.Resources; using KeePassLib.Security; using KeePassLib.Utility; namespace KeePassLib.Serialization { /// /// Serialization to KeePass KDBX files. /// public sealed partial class KdbxFile { /// /// Load a KDBX file. /// /// File to load. /// Format. /// Status logger (optional). public void Load(string strFilePath, KdbxFormat fmt, IStatusLogger slLogger) { IOConnectionInfo ioc = IOConnectionInfo.FromPath(strFilePath); Load(IOConnection.OpenRead(ioc), fmt, slLogger); } /// /// Load a KDBX file from a stream. /// /// Stream to read the data from. Must contain /// a KDBX stream. /// Format. /// Status logger (optional). public void Load(Stream sSource, KdbxFormat fmt, IStatusLogger slLogger) { Debug.Assert(sSource != null); if(sSource == null) throw new ArgumentNullException("sSource"); if(m_bUsedOnce) throw new InvalidOperationException("Do not reuse KdbxFile objects!"); m_bUsedOnce = true; #if KDBX_BENCHMARK Stopwatch swTime = Stopwatch.StartNew(); #endif m_format = fmt; m_slLogger = slLogger; m_pbsBinaries.Clear(); UTF8Encoding encNoBom = StrUtil.Utf8; byte[] pbCipherKey = null; byte[] pbHmacKey64 = null; List lStreams = new List(); lStreams.Add(sSource); HashingStreamEx sHashing = new HashingStreamEx(sSource, false, null); lStreams.Add(sHashing); try { Stream sXml; if(fmt == KdbxFormat.Default) { BinaryReaderEx br = new BinaryReaderEx(sHashing, encNoBom, KLRes.FileCorrupted); byte[] pbHeader = LoadHeader(br); m_pbHashOfHeader = CryptoUtil.HashSha256(pbHeader); int cbEncKey, cbEncIV; ICipherEngine iCipher = GetCipher(out cbEncKey, out cbEncIV); ComputeKeys(out pbCipherKey, cbEncKey, out pbHmacKey64); string strIncomplete = KLRes.FileHeaderCorrupted + " " + KLRes.FileIncomplete; Stream sPlain; if(m_uFileVersion < FileVersion32_4) { Stream sDecrypted = EncryptStream(sHashing, iCipher, pbCipherKey, cbEncIV, false); if((sDecrypted == null) || (sDecrypted == sHashing)) throw new SecurityException(KLRes.CryptoStreamFailed); lStreams.Add(sDecrypted); BinaryReaderEx brDecrypted = new BinaryReaderEx(sDecrypted, encNoBom, strIncomplete); byte[] pbStoredStartBytes = brDecrypted.ReadBytes(32); if((m_pbStreamStartBytes == null) || (m_pbStreamStartBytes.Length != 32)) throw new EndOfStreamException(strIncomplete); if(!MemUtil.ArraysEqual(pbStoredStartBytes, m_pbStreamStartBytes)) throw new InvalidCompositeKeyException(); sPlain = new HashedBlockStream(sDecrypted, false, 0, !m_bRepairMode); } else // KDBX >= 4 { byte[] pbStoredHash = MemUtil.Read(sHashing, 32); if((pbStoredHash == null) || (pbStoredHash.Length != 32)) throw new EndOfStreamException(strIncomplete); if(!MemUtil.ArraysEqual(m_pbHashOfHeader, pbStoredHash)) throw new InvalidDataException(KLRes.FileHeaderCorrupted); byte[] pbHeaderHmac = ComputeHeaderHmac(pbHeader, pbHmacKey64); byte[] pbStoredHmac = MemUtil.Read(sHashing, 32); if((pbStoredHmac == null) || (pbStoredHmac.Length != 32)) throw new EndOfStreamException(strIncomplete); if(!MemUtil.ArraysEqual(pbHeaderHmac, pbStoredHmac)) throw new InvalidCompositeKeyException(); HmacBlockStream sBlocks = new HmacBlockStream(sHashing, false, !m_bRepairMode, pbHmacKey64); lStreams.Add(sBlocks); sPlain = EncryptStream(sBlocks, iCipher, pbCipherKey, cbEncIV, false); if((sPlain == null) || (sPlain == sBlocks)) throw new SecurityException(KLRes.CryptoStreamFailed); } lStreams.Add(sPlain); if(m_pwDatabase.Compression == PwCompressionAlgorithm.GZip) { sXml = new GZipStream(sPlain, CompressionMode.Decompress); lStreams.Add(sXml); } else sXml = sPlain; if(m_uFileVersion >= FileVersion32_4) LoadInnerHeader(sXml); // Binary header before XML } else if(fmt == KdbxFormat.PlainXml) sXml = sHashing; else { Debug.Assert(false); throw new ArgumentOutOfRangeException("fmt"); } if(fmt == KdbxFormat.Default) { if(m_pbInnerRandomStreamKey == null) { Debug.Assert(false); throw new SecurityException("Invalid inner random stream key!"); } m_randomStream = new CryptoRandomStream(m_craInnerRandomStream, m_pbInnerRandomStreamKey); } #if KeePassDebug_WriteXml // FileStream fsOut = new FileStream("Raw.xml", FileMode.Create, // FileAccess.Write, FileShare.None); // try // { // while(true) // { // int b = sXml.ReadByte(); // if(b == -1) break; // fsOut.WriteByte((byte)b); // } // } // catch(Exception) { } // fsOut.Close(); #endif ReadXmlStreamed(sXml, sHashing); // ReadXmlDom(sXml); } catch(CryptographicException) // Thrown on invalid padding { throw new CryptographicException(KLRes.FileCorrupted); } finally { if(pbCipherKey != null) MemUtil.ZeroByteArray(pbCipherKey); if(pbHmacKey64 != null) MemUtil.ZeroByteArray(pbHmacKey64); CommonCleanUpRead(lStreams, sHashing); } #if KDBX_BENCHMARK swTime.Stop(); MessageService.ShowInfo("Loading KDBX took " + swTime.ElapsedMilliseconds.ToString() + " ms."); #endif } private void CommonCleanUpRead(List lStreams, HashingStreamEx sHashing) { CloseStreams(lStreams); Debug.Assert(lStreams.Contains(sHashing)); // sHashing must be closed m_pbHashOfFileOnDisk = sHashing.Hash; Debug.Assert(m_pbHashOfFileOnDisk != null); CleanUpInnerRandomStream(); // Reset memory protection settings (to always use reasonable // defaults) m_pwDatabase.MemoryProtection = new MemoryProtectionConfig(); // Remove old backups (this call is required here in order to apply // the default history maintenance settings for people upgrading from // KeePass <= 2.14 to >= 2.15; also it ensures history integrity in // case a different application has created the KDBX file and ignored // the history maintenance settings) m_pwDatabase.MaintainBackups(); // Don't mark database as modified // Expand the root group, such that in case the user accidently // collapses the root group he can simply reopen the database PwGroup pgRoot = m_pwDatabase.RootGroup; if(pgRoot != null) pgRoot.IsExpanded = true; else { Debug.Assert(false); } m_pbHashOfHeader = null; } private byte[] LoadHeader(BinaryReaderEx br) { string strPrevExcpText = br.ReadExceptionText; br.ReadExceptionText = KLRes.FileHeaderCorrupted + " " + KLRes.FileIncompleteExpc; MemoryStream msHeader = new MemoryStream(); Debug.Assert(br.CopyDataTo == null); br.CopyDataTo = msHeader; byte[] pbSig1 = br.ReadBytes(4); uint uSig1 = MemUtil.BytesToUInt32(pbSig1); byte[] pbSig2 = br.ReadBytes(4); uint uSig2 = MemUtil.BytesToUInt32(pbSig2); if((uSig1 == FileSignatureOld1) && (uSig2 == FileSignatureOld2)) throw new OldFormatException(PwDefs.ShortProductName + @" 1.x", OldFormatException.OldFormatType.KeePass1x); if((uSig1 == FileSignature1) && (uSig2 == FileSignature2)) { } else if((uSig1 == FileSignaturePreRelease1) && (uSig2 == FileSignaturePreRelease2)) { } else throw new FormatException(KLRes.FileSigInvalid); byte[] pb = br.ReadBytes(4); uint uVersion = MemUtil.BytesToUInt32(pb); if((uVersion & FileVersionCriticalMask) > (FileVersion32 & FileVersionCriticalMask)) throw new FormatException(KLRes.FileVersionUnsupported + MessageService.NewParagraph + KLRes.FileNewVerReq); m_uFileVersion = uVersion; while(true) { if(!ReadHeaderField(br)) break; } br.CopyDataTo = null; byte[] pbHeader = msHeader.ToArray(); msHeader.Close(); br.ReadExceptionText = strPrevExcpText; return pbHeader; } private bool ReadHeaderField(BinaryReaderEx brSource) { Debug.Assert(brSource != null); if(brSource == null) throw new ArgumentNullException("brSource"); byte btFieldID = brSource.ReadByte(); int cbSize; Debug.Assert(m_uFileVersion > 0); if(m_uFileVersion < FileVersion32_4) cbSize = (int)MemUtil.BytesToUInt16(brSource.ReadBytes(2)); else cbSize = MemUtil.BytesToInt32(brSource.ReadBytes(4)); if(cbSize < 0) throw new FormatException(KLRes.FileCorrupted); byte[] pbData = MemUtil.EmptyByteArray; if(cbSize > 0) pbData = brSource.ReadBytes(cbSize); bool bResult = true; KdbxHeaderFieldID kdbID = (KdbxHeaderFieldID)btFieldID; switch(kdbID) { case KdbxHeaderFieldID.EndOfHeader: bResult = false; // Returning false indicates end of header break; case KdbxHeaderFieldID.CipherID: SetCipher(pbData); break; case KdbxHeaderFieldID.CompressionFlags: SetCompressionFlags(pbData); break; case KdbxHeaderFieldID.MasterSeed: m_pbMasterSeed = pbData; CryptoRandom.Instance.AddEntropy(pbData); break; // Obsolete; for backward compatibility only case KdbxHeaderFieldID.TransformSeed: Debug.Assert(m_uFileVersion < FileVersion32_4); AesKdf kdfS = new AesKdf(); if(!m_pwDatabase.KdfParameters.KdfUuid.Equals(kdfS.Uuid)) m_pwDatabase.KdfParameters = kdfS.GetDefaultParameters(); // m_pbTransformSeed = pbData; m_pwDatabase.KdfParameters.SetByteArray(AesKdf.ParamSeed, pbData); CryptoRandom.Instance.AddEntropy(pbData); break; // Obsolete; for backward compatibility only case KdbxHeaderFieldID.TransformRounds: Debug.Assert(m_uFileVersion < FileVersion32_4); AesKdf kdfR = new AesKdf(); if(!m_pwDatabase.KdfParameters.KdfUuid.Equals(kdfR.Uuid)) m_pwDatabase.KdfParameters = kdfR.GetDefaultParameters(); // m_pwDatabase.KeyEncryptionRounds = MemUtil.BytesToUInt64(pbData); m_pwDatabase.KdfParameters.SetUInt64(AesKdf.ParamRounds, MemUtil.BytesToUInt64(pbData)); break; case KdbxHeaderFieldID.EncryptionIV: m_pbEncryptionIV = pbData; break; case KdbxHeaderFieldID.InnerRandomStreamKey: Debug.Assert(m_uFileVersion < FileVersion32_4); Debug.Assert(m_pbInnerRandomStreamKey == null); m_pbInnerRandomStreamKey = pbData; CryptoRandom.Instance.AddEntropy(pbData); break; case KdbxHeaderFieldID.StreamStartBytes: Debug.Assert(m_uFileVersion < FileVersion32_4); m_pbStreamStartBytes = pbData; break; case KdbxHeaderFieldID.InnerRandomStreamID: Debug.Assert(m_uFileVersion < FileVersion32_4); SetInnerRandomStreamID(pbData); break; case KdbxHeaderFieldID.KdfParameters: m_pwDatabase.KdfParameters = KdfParameters.DeserializeExt(pbData); break; case KdbxHeaderFieldID.PublicCustomData: Debug.Assert(m_pwDatabase.PublicCustomData.Count == 0); m_pwDatabase.PublicCustomData = VariantDictionary.Deserialize(pbData); break; default: Debug.Assert(false); if(m_slLogger != null) m_slLogger.SetText(KLRes.UnknownHeaderId + @": " + kdbID.ToString() + "!", LogStatusType.Warning); break; } return bResult; } private void LoadInnerHeader(Stream s) { BinaryReaderEx br = new BinaryReaderEx(s, StrUtil.Utf8, KLRes.FileCorrupted + " " + KLRes.FileIncompleteExpc); while(true) { if(!ReadInnerHeaderField(br)) break; } } private bool ReadInnerHeaderField(BinaryReaderEx br) { Debug.Assert(br != null); if(br == null) throw new ArgumentNullException("br"); byte btFieldID = br.ReadByte(); int cbSize = MemUtil.BytesToInt32(br.ReadBytes(4)); if(cbSize < 0) throw new FormatException(KLRes.FileCorrupted); byte[] pbData = MemUtil.EmptyByteArray; if(cbSize > 0) pbData = br.ReadBytes(cbSize); bool bResult = true; KdbxInnerHeaderFieldID kdbID = (KdbxInnerHeaderFieldID)btFieldID; switch(kdbID) { case KdbxInnerHeaderFieldID.EndOfHeader: bResult = false; // Returning false indicates end of header break; case KdbxInnerHeaderFieldID.InnerRandomStreamID: SetInnerRandomStreamID(pbData); break; case KdbxInnerHeaderFieldID.InnerRandomStreamKey: Debug.Assert(m_pbInnerRandomStreamKey == null); m_pbInnerRandomStreamKey = pbData; CryptoRandom.Instance.AddEntropy(pbData); break; case KdbxInnerHeaderFieldID.Binary: if(pbData.Length < 1) throw new FormatException(); KdbxBinaryFlags f = (KdbxBinaryFlags)pbData[0]; bool bProt = ((f & KdbxBinaryFlags.Protected) != KdbxBinaryFlags.None); ProtectedBinary pb = new ProtectedBinary(bProt, pbData, 1, pbData.Length - 1); m_pbsBinaries.Add(pb); if(bProt) MemUtil.ZeroByteArray(pbData); break; default: Debug.Assert(false); break; } return bResult; } private void SetCipher(byte[] pbID) { if((pbID == null) || (pbID.Length != (int)PwUuid.UuidSize)) throw new FormatException(KLRes.FileUnknownCipher); m_pwDatabase.DataCipherUuid = new PwUuid(pbID); } private void SetCompressionFlags(byte[] pbFlags) { int nID = (int)MemUtil.BytesToUInt32(pbFlags); if((nID < 0) || (nID >= (int)PwCompressionAlgorithm.Count)) throw new FormatException(KLRes.FileUnknownCompression); m_pwDatabase.Compression = (PwCompressionAlgorithm)nID; } private void SetInnerRandomStreamID(byte[] pbID) { uint uID = MemUtil.BytesToUInt32(pbID); if(uID >= (uint)CrsAlgorithm.Count) throw new FormatException(KLRes.FileUnknownCipher); m_craInnerRandomStream = (CrsAlgorithm)uID; } [Obsolete] public static List ReadEntries(Stream msData) { return ReadEntries(msData, null, false); } [Obsolete] public static List ReadEntries(PwDatabase pdContext, Stream msData) { return ReadEntries(msData, pdContext, true); } /// /// Read entries from a stream. /// /// Input stream to read the entries from. /// Context database (e.g. for storing icons). /// If true, custom icons required by /// the loaded entries are copied to the context database. /// Loaded entries. public static List ReadEntries(Stream msData, PwDatabase pdContext, bool bCopyIcons) { List lEntries = new List(); if(msData == null) { Debug.Assert(false); return lEntries; } // pdContext may be null /* KdbxFile f = new KdbxFile(pwDatabase); f.m_format = KdbxFormat.PlainXml; XmlDocument doc = new XmlDocument(); doc.Load(msData); XmlElement el = doc.DocumentElement; if(el.Name != ElemRoot) throw new FormatException(); List vEntries = new List(); foreach(XmlNode xmlChild in el.ChildNodes) { if(xmlChild.Name == ElemEntry) { PwEntry pe = f.ReadEntry(xmlChild); pe.Uuid = new PwUuid(true); foreach(PwEntry peHistory in pe.History) peHistory.Uuid = pe.Uuid; vEntries.Add(pe); } else { Debug.Assert(false); } } return vEntries; */ PwDatabase pd = new PwDatabase(); pd.New(new IOConnectionInfo(), new CompositeKey()); KdbxFile f = new KdbxFile(pd); f.Load(msData, KdbxFormat.PlainXml, null); foreach(PwEntry pe in pd.RootGroup.Entries) { pe.SetUuid(new PwUuid(true), true); lEntries.Add(pe); if(bCopyIcons && (pdContext != null)) { PwUuid pu = pe.CustomIconUuid; if(!pu.Equals(PwUuid.Zero)) { int iSrc = pd.GetCustomIconIndex(pu); int iDst = pdContext.GetCustomIconIndex(pu); if(iSrc < 0) { Debug.Assert(false); } else if(iDst < 0) { pdContext.CustomIcons.Add(pd.CustomIcons[iSrc]); pdContext.Modified = true; pdContext.UINeedsIconUpdate = true; } } } } return lEntries; } } } KeePassLib/Serialization/IocPropertyInfoPool.cs0000664000000000000000000000752613222430402020633 0ustar rootroot/* KeePass Password Safe - The Open-Source Password Manager Copyright (C) 2003-2018 Dominik Reichl This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ using System; using System.Collections.Generic; using System.Diagnostics; using System.Text; using KeePassLib.Resources; using KeePassLib.Utility; namespace KeePassLib.Serialization { public static class IocKnownProtocols { public const string Http = "HTTP"; public const string Https = "HTTPS"; public const string WebDav = "WebDAV"; public const string Ftp = "FTP"; } public static class IocKnownProperties { public const string Timeout = "Timeout"; public const string PreAuth = "PreAuth"; public const string UserAgent = "UserAgent"; public const string Expect100Continue = "Expect100Continue"; public const string Passive = "Passive"; } public static class IocPropertyInfoPool { private static List m_l = null; public static IEnumerable PropertyInfos { get { EnsureInitialized(); return m_l; } } private static void EnsureInitialized() { if(m_l != null) return; string strGen = KLRes.General; string strHttp = IocKnownProtocols.Http; string strHttps = IocKnownProtocols.Https; string strWebDav = IocKnownProtocols.WebDav; string strFtp = IocKnownProtocols.Ftp; string[] vGen = new string[] { strGen }; string[] vHttp = new string[] { strHttp, strHttps, strWebDav }; string[] vFtp = new string[] { strFtp }; List l = new List(); l.Add(new IocPropertyInfo(IocKnownProperties.Timeout, typeof(long), KLRes.Timeout + " [ms]", vGen)); l.Add(new IocPropertyInfo(IocKnownProperties.PreAuth, typeof(bool), KLRes.PreAuth, vGen)); l.Add(new IocPropertyInfo(IocKnownProperties.UserAgent, typeof(string), KLRes.UserAgent, vHttp)); l.Add(new IocPropertyInfo(IocKnownProperties.Expect100Continue, typeof(bool), KLRes.Expect100Continue, vHttp)); l.Add(new IocPropertyInfo(IocKnownProperties.Passive, typeof(bool), KLRes.Passive, vFtp)); // l.Add(new IocPropertyInfo("Test", typeof(bool), // "Long long long long long long long long long long long long long long long long long long long long", // new string[] { "Proto 1/9", "Proto 2/9", "Proto 3/9", "Proto 4/9", "Proto 5/9", // "Proto 6/9", "Proto 7/9", "Proto 8/9", "Proto 9/9" })); m_l = l; } public static IocPropertyInfo Get(string strName) { if(string.IsNullOrEmpty(strName)) { Debug.Assert(false); return null; } EnsureInitialized(); foreach(IocPropertyInfo pi in m_l) { if(pi.Name.Equals(strName, StrUtil.CaseIgnoreCmp)) return pi; } return null; } public static bool Add(IocPropertyInfo pi) { if(pi == null) { Debug.Assert(false); return false; } // Name must be non-empty string strName = pi.Name; if(string.IsNullOrEmpty(strName)) { Debug.Assert(false); return false; } IocPropertyInfo piEx = Get(strName); // Ensures initialized if(piEx != null) { Debug.Assert(false); return false; } // Exists already m_l.Add(pi); return true; } } } KeePassLib/PwDeletedObject.cs0000664000000000000000000000451513222430402015070 0ustar rootroot/* KeePass Password Safe - The Open-Source Password Manager Copyright (C) 2003-2018 Dominik Reichl This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ using System; using System.Collections.Generic; using System.Diagnostics; using KeePassLib.Interfaces; namespace KeePassLib { /// /// Represents an object that has been deleted. /// public sealed class PwDeletedObject : IDeepCloneable { private PwUuid m_uuid = PwUuid.Zero; /// /// UUID of the entry that has been deleted. /// public PwUuid Uuid { get { return m_uuid; } set { if(value == null) throw new ArgumentNullException("value"); m_uuid = value; } } private DateTime m_dtDeletionTime = PwDefs.DtDefaultNow; /// /// The date/time when the entry has been deleted. /// public DateTime DeletionTime { get { return m_dtDeletionTime; } set { m_dtDeletionTime = value; } } /// /// Construct a new PwDeletedObject object. /// public PwDeletedObject() { } public PwDeletedObject(PwUuid uuid, DateTime dtDeletionTime) { if(uuid == null) throw new ArgumentNullException("uuid"); m_uuid = uuid; m_dtDeletionTime = dtDeletionTime; } /// /// Clone the object. /// /// Value copy of the current object. public PwDeletedObject CloneDeep() { PwDeletedObject pdo = new PwDeletedObject(); pdo.m_uuid = m_uuid; // PwUuid objects are immutable pdo.m_dtDeletionTime = m_dtDeletionTime; return pdo; } } } KeePassLib/PwEnums.cs0000664000000000000000000001441413222430402013461 0ustar rootroot/* KeePass Password Safe - The Open-Source Password Manager Copyright (C) 2003-2018 Dominik Reichl This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ using System; namespace KeePassLib { /// /// Compression algorithm specifiers. /// public enum PwCompressionAlgorithm { /// /// No compression. /// None = 0, /// /// GZip compression. /// GZip = 1, /// /// Virtual field: currently known number of algorithms. Should not be used /// by plugins or libraries -- it's used internally only. /// Count = 2 } /// /// Tree traversal methods. /// public enum TraversalMethod { /// /// Don't traverse the tree. /// None = 0, /// /// Traverse the tree in pre-order mode, i.e. first visit all items /// in the current node, then visit all subnodes. /// PreOrder = 1 } /// /// Methods for merging password databases/entries. /// public enum PwMergeMethod { // Do not change the explicitly assigned values, otherwise // serialization (e.g. of Ecas triggers) breaks None = 0, OverwriteExisting = 1, KeepExisting = 2, OverwriteIfNewer = 3, CreateNewUuids = 4, Synchronize = 5 } /// /// Icon identifiers for groups and password entries. /// public enum PwIcon { Key = 0, World, Warning, NetworkServer, MarkedDirectory, UserCommunication, Parts, Notepad, WorldSocket, Identity, PaperReady, Digicam, IRCommunication, MultiKeys, Energy, Scanner, WorldStar, CDRom, Monitor, EMail, Configuration, ClipboardReady, PaperNew, Screen, EnergyCareful, EMailBox, Disk, Drive, PaperQ, TerminalEncrypted, Console, Printer, ProgramIcons, Run, Settings, WorldComputer, Archive, Homebanking, DriveWindows, Clock, EMailSearch, PaperFlag, Memory, TrashBin, Note, Expired, Info, Package, Folder, FolderOpen, FolderPackage, LockOpen, PaperLocked, Checked, Pen, Thumbnail, Book, List, UserKey, Tool, Home, Star, Tux, Feather, Apple, Wiki, Money, Certificate, BlackBerry, /// /// Virtual identifier -- represents the number of icons. /// Count } public enum ProxyServerType { None = 0, System = 1, Manual = 2 } public enum ProxyAuthType { None = 0, /// /// Use default user credentials (provided by the system). /// Default = 1, Manual = 2, /// /// Default or Manual, depending on whether /// manual credentials are available. /// This type exists for supporting upgrading from KeePass /// 2.28 to 2.29; the user cannot select this type. /// Auto = 3 } /// /// Comparison modes for in-memory protected objects. /// public enum MemProtCmpMode { /// /// Ignore the in-memory protection states. /// None = 0, /// /// Ignore the in-memory protection states of standard /// objects; do compare in-memory protection states of /// custom objects. /// CustomOnly, /// /// Compare in-memory protection states. /// Full } [Flags] public enum PwCompareOptions { None = 0x0, /// /// Empty standard string fields are considered to be the /// same as non-existing standard string fields. /// This doesn't affect custom string comparisons. /// NullEmptyEquivStd = 0x1, IgnoreParentGroup = 0x2, IgnoreLastAccess = 0x4, IgnoreLastMod = 0x8, IgnoreHistory = 0x10, IgnoreLastBackup = 0x20, // For groups: PropertiesOnly = 0x40, IgnoreTimes = (IgnoreLastAccess | IgnoreLastMod) } public enum IOAccessType { None = 0, /// /// The IO connection is being opened for reading. /// Read = 1, /// /// The IO connection is being opened for writing. /// Write = 2, /// /// The IO connection is being opened for testing /// whether a file/object exists. /// Exists = 3, /// /// The IO connection is being opened for deleting a file/object. /// Delete = 4, /// /// The IO connection is being opened for renaming/moving a file/object. /// Move = 5 } // public enum PwLogicalOp // { // None = 0, // Or = 1, // And = 2, // NOr = 3, // NAnd = 4 // } [Flags] public enum AppRunFlags { None = 0, GetStdOutput = 1, WaitForExit = 2, // https://sourceforge.net/p/keepass/patches/84/ /// /// This flag prevents any handles being garbage-collected /// before the started process has terminated, without /// blocking the current thread. /// GCKeepAlive = 4, // https://sourceforge.net/p/keepass/patches/85/ DoEvents = 8, DisableForms = 16 } [Flags] public enum ScaleTransformFlags { None = 0, /// /// UIIcon indicates that the returned image is going /// to be displayed as icon in the UI and that it is not /// subject to future changes in size. /// UIIcon = 1 } public enum DesktopType { None = 0, Windows, Gnome, Kde, Unity, Lxde, Xfce, Mate, Cinnamon, Pantheon } } KeePassLib/Properties/0000775000000000000000000000000013222747410013676 5ustar rootrootKeePassLib/Properties/AssemblyInfo.cs0000664000000000000000000000313413225116762016624 0ustar rootroot/* KeePass Password Safe - The Open-Source Password Manager Copyright (C) 2003-2018 Dominik Reichl This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.InteropServices; // General assembly properties [assembly: AssemblyTitle("KeePassLib")] [assembly: AssemblyDescription("KeePass Password Management Library")] [assembly: AssemblyConfiguration("")] [assembly: AssemblyCompany("Dominik Reichl")] [assembly: AssemblyProduct("KeePassLib")] [assembly: AssemblyCopyright("Copyright © 2003-2018 Dominik Reichl")] [assembly: AssemblyTrademark("")] [assembly: AssemblyCulture("")] // COM settings [assembly: ComVisible(false)] // Assembly GUID [assembly: Guid("395f6eec-a1e0-4438-aa82-b75099348134")] // Assembly version information [assembly: AssemblyVersion("2.38.0.*")] [assembly: AssemblyFileVersion("2.38.0.0")] Build/0000775000000000000000000000000013225117636010623 5ustar rootrootBuild/KeePassLib_Distrib/0000775000000000000000000000000013225117316014260 5ustar rootrootBuild/KeePassLib_Distrib/KeePassLib.xml0000664000000000000000000045761213225117030016774 0ustar rootroot KeePassLib A class containing various static path utility helper methods (like stripping extension from a file, etc.). Get the directory (path) of a file name. The returned string may be terminated by a directory separator character. Example: passing C:\\My Documents\\My File.kdb in and true to would produce this string: C:\\My Documents\\. Full path of a file. Append a terminating directory separator character to the returned path. If true, the returned path is guaranteed to be a valid directory path (for example X:\\ instead of X:, overriding ). This should only be set to true, if the returned path is directly passed to some directory API. Directory of the file. Gets the file name of the specified file (full path). Example: if is C:\\My Documents\\My File.kdb the returned string is My File.kdb. Full path of a file. File name of the specified file. The return value is an empty string ("") if the input parameter is null. Strip the extension of a file. Full path of a file with extension. File name without extension. Get the extension of a file. Full path of a file with extension. Extension without prepending dot. Ensure that a path is terminated with a directory separator character. Input path. If true, a slash (/) is appended to the string if it's not terminated already. If false, the default system directory separator character is used. Path having a directory separator as last character. Get the host component of an URL. This method is faster and more fault-tolerant than creating an Uri object and querying its Host property. For the input s://u:p@d.tld:p/p?q#f the return value is d.tld. Expand shell variables in a string. [0] is the value of %1, etc. The fully qualified name of the form. Serialization to KeePass KDBX files. Serialization to KeePass KDBX files. Serialization to KeePass KDBX files. Serialization to KeePass KDBX files. File identifier, first 32-bit value. File identifier, second 32-bit value. File version of files saved by the current KdbxFile class. KeePass 2.07 has version 1.01, 2.08 has 1.02, 2.09 has 2.00, 2.10 has 2.02, 2.11 has 2.04, 2.15 has 3.00, 2.20 has 3.01. The first 2 bytes are critical (i.e. loading will fail, if the file version is too high), the last 2 bytes are informational. Load a KDBX file. File to load. Format. Status logger (optional). Load a KDBX file from a stream. Stream to read the data from. Must contain a KDBX stream. Format. Status logger (optional). Read entries from a stream. Input stream to read the entries from. Context database (e.g. for storing icons). If true, custom icons required by the loaded entries are copied to the context database. Loaded entries. Save the contents of the current PwDatabase to a KDBX file. Stream to write the KDBX file into. Group containing all groups and entries to write. If null, the complete database will be written. Format of the file to create. Logger that recieves status information. Default constructor. The PwDatabase instance that the class will load file data into or use to create a KDBX file. Call this once to determine the current localization settings. Detach binaries when opening a file. If this isn't null, all binaries are saved to the specified path and are removed from the database. Contains KeePassLib-global definitions and enums. The product name. A short, simple string representing the product name. The string should contain no spaces, directory separator characters, etc. Version, encoded as 32-bit unsigned integer. 2.00 = 0x02000000, 2.01 = 0x02000100, ..., 2.18 = 0x02010800. As of 2.19, the version is encoded component-wise per byte, e.g. 2.19 = 0x02130000. It is highly recommended to use FileVersion64 instead. Version, encoded as 64-bit unsigned integer (component-wise, 16 bits per component). Version, encoded as string. Product website URL. Terminated by a forward slash. URL to the online translations page. URL to the online plugins page. Product donations URL. URL to the root path of the online KeePass help. Terminated by a forward slash. URL to a TXT file (eventually compressed) that contains information about the latest KeePass version available on the website. Default number of master key encryption/transformation rounds (making dictionary attacks harder). Default identifier string for the title field. Should not contain spaces, tabs or other whitespace. Default identifier string for the user name field. Should not contain spaces, tabs or other whitespace. Default identifier string for the password field. Should not contain spaces, tabs or other whitespace. Default identifier string for the URL field. Should not contain spaces, tabs or other whitespace. Default identifier string for the notes field. Should not contain spaces, tabs or other whitespace. Default identifier string for the field which will contain TAN indices. Default title of an entry that is really a TAN entry. Prefix of a custom auto-type string field. Default string representing a hidden password. Default auto-type keystroke sequence. If no custom sequence is specified, this sequence is used. Default auto-type keystroke sequence for TAN entries. If no custom sequence is specified, this sequence is used. A DateTime object that represents the time when the assembly was loaded. Check if a name is a standard field name. Input field name. Returns true, if the field name is a standard field name (title, user name, password, ...), otherwise false. Check if an entry is a TAN. Password entry. Returns true if the entry is a TAN. Search parameters for group and entry searches. Construct a new search parameters object. String comparison type. Specifies the condition when the specified text matches a group/entry string. Only for serialization. Memory protection configuration structure (for default fields). Interface for objects that are deeply cloneable. Reference type. Deeply clone the object. Cloned object. Validate a key. Key to validate. Type of the validation to perform. Returns null, if the validation is successful. If there's a problem with the key, the returned string describes the problem. Name of your key validator (should be unique). Generate HMAC-based one-time passwords as specified in RFC 4226. A list of ProtectedString objects (dictionary). Construct a new list of protected strings. Clone the current ProtectedStringList object, including all stored protected strings. New ProtectedStringList object. Get one of the protected strings. String identifier. Protected string. If the string identified by cannot be found, the function returns null. Thrown if the input parameter is null. Get one of the protected strings. The return value is never null. If the requested string cannot be found, an empty protected string object is returned. String identifier. Returns a protected string object. If the standard string has not been set yet, the return value is an empty string (""). Thrown if the input parameter is null. Test if a named string exists. Name of the string to try. Returns true if the string exists, otherwise false. Thrown if is null. Get one of the protected strings. If the string doesn't exist, the return value is an empty string (""). Name of the requested string. Requested string value or an empty string, if the named string doesn't exist. Thrown if the input parameter is null. Get one of the entry strings. If the string doesn't exist, the return value is an empty string (""). If the string is in-memory protected, the return value is PwDefs.HiddenPassword. Name of the requested string. Returns the requested string in plain-text or PwDefs.HiddenPassword if the string cannot be found. Thrown if the input parameter is null. Set a string. Identifier of the string field to modify. New value. This parameter must not be null. Thrown if one of the input parameters is null. Delete a string. Name of the string field to delete. Returns true if the field has been successfully removed, otherwise the return value is false. Thrown if the input parameter is null. Get the number of strings in this entry. A strongly-typed resource class, for looking up localized strings, etc. Look up a localized string similar to 'Failed to initialize encryption/decryption stream!'. Look up a localized string similar to 'The data is too large to be encrypted/decrypted securely using {PARAM}.'. Look up a localized string similar to 'An extended error report has been copied to the clipboard.'. Look up a localized string similar to 'Expect 100-Continue responses'. Look up a localized string similar to 'Fatal Error'. Look up a localized string similar to 'A fatal error has occurred!'. Look up a localized string similar to 'The file is corrupted.'. Look up a localized string similar to 'The file header is corrupted.'. Look up a localized string similar to 'Data is missing at the end of the file, i.e. the file is incomplete.'. Look up a localized string similar to 'Less data than expected could be read from the file.'. Look up a localized string similar to 'Failed to load the specified file!'. Look up a localized string similar to 'The file is locked, because the following user is currently writing to it:'. Look up a localized string similar to 'A newer KeePass version or a plugin is required to open this file.'. Look up a localized string similar to 'A newer KeePass version is required to open this file.'. Look up a localized string similar to 'The target file might be corrupted. Please try saving again. If that fails, save the database to a different location.'. Look up a localized string similar to 'Failed to save the current database to the specified location!'. Look up a localized string similar to 'The file signature is invalid. Either the file isn't a KeePass database file at all or it is corrupted.'. Look up a localized string similar to 'The file is encrypted using an unknown encryption algorithm!'. Look up a localized string similar to 'The file is compressed using an unknown compression algorithm!'. Look up a localized string similar to 'The file version is unsupported.'. Look up a localized string similar to 'Failed to create the final encryption/decryption key!'. Look up a localized string similar to 'The .NET framework/runtime under which KeePass is currently running does not support this operation.'. Look up a localized string similar to 'General'. Look up a localized string similar to 'The composite key is invalid!'. Look up a localized string similar to 'Make sure the composite key is correct and try again.'. Look up a localized string similar to 'Found invalid data while decoding.'. Look up a localized string similar to 'In order to import KeePass 1.x KDB files, create a new 2.x database file and click 'File' -> 'Import' in the main menu. In the import dialog, choose 'KeePass KDB (1.x)' as file format.'. Look up a localized string similar to '{PARAM}-bit key'. Look up a localized string similar to 'Database files cannot be used as key files.'. Look up a localized string similar to 'The length of the master key seed is invalid!'. Look up a localized string similar to 'The selected file appears to be an old format'. Look up a localized string similar to 'Passive'. Look up a localized string similar to 'Pre-authenticate'. Look up a localized string similar to 'Timeout'. Look up a localized string similar to 'Please try it again in a few seconds.'. Look up a localized string similar to 'Unknown header ID!'. Look up a localized string similar to 'Unknown key derivation function!'. Look up a localized string similar to 'The operating system did not grant KeePass read/write access to the user profile folder, where the protected user key is stored.'. Look up a localized string similar to 'User agent'. Algorithms supported by CryptoRandomStream. Not supported. A variant of the ARCFour algorithm (RC4 incompatible). Insecure; for backward compatibility only. Salsa20 stream cipher algorithm. ChaCha20 stream cipher algorithm. A random stream class. The class is initialized using random bytes provided by the caller. The produced stream has random properties, but for the same seed always the same stream is produced, i.e. this class can be used as stream cipher. Construct a new cryptographically secure random stream object. Algorithm to use. Initialization key. Must not be null and must contain at least 1 byte. Get random bytes. Number of random bytes to retrieve. Returns random bytes. Character stream class. Size of a character in bytes. Start signature of the text (byte order mark). May be null or empty, if no signature is known. A class containing various string helper methods. Convert a string to a HTML sequence representing that string. String to convert. String, HTML-encoded. Split up a command line into application and argument. Command line to split. Application path. Arguments. Convert a Color to a HTML color identifier string. Color to convert. If this is true, an empty string is returned if the color is transparent. HTML color identifier string. Format an exception and convert it to a string. Exception to convert/format. String representing the exception. Removes all characters that are not valid XML characters, according to https://www.w3.org/TR/xml/#charsets . Source text. Text containing only valid XML characters. Normalize new line characters in a string. Input strings may contain mixed new line character sequences from all commonly used operating systems (i.e. \r\n from Windows, \n from Unix and \r from Mac OS. String with mixed new line characters. If true, new line characters are normalized for Windows (\r\n); if false, new line characters are normalized for Unix (\n). String with normalized new line characters. Split a string and include the separators in the splitted array. String to split. Separators. Specifies whether separators are matched case-sensitively or not. Splitted string including separators. Create a data URI (according to RFC 2397). Data to encode. Optional MIME type. If null, an appropriate type is used. Data URI. Convert a data URI (according to RFC 2397) to binary data. Data URI to decode. Decoded binary data. Remove placeholders from a string (wrapped in '{' and '}'). This doesn't remove environment variables (wrapped in '%'). Find a character that does not occur within a given text. Generate random seeds and store them in . Set the value of the private shown_raised member variable of a form. Previous shown_raised value. Ensure that the file ~/.recently-used is valid (in order to prevent Mono's FileDialog from crashing). Member variable name of the control to be translated. Represents an object that is encrypted using a XOR pad until it is read. XorredBuffer objects are immutable and thread-safe. Construct a new XOR-protected object using a protected byte array and a XOR pad that decrypts the protected data. The byte array must have the same size as the byte array. The XorredBuffer object takes ownership of the two byte arrays, i.e. the caller must not use or modify them afterwards. Protected data (XOR pad applied). XOR pad that can be used to decrypt the parameter. Thrown if one of the input parameters is null. Thrown if the byte arrays are of different size. Get a copy of the plain-text. The caller is responsible for clearing the byte array safely after using it. Unprotected plain-text byte array. Length of the protected data in bytes. Set a string. Identifier of the string field to modify. New value. This parameter must not be null. Thrown if one of the input parameters is null. Delete a string. Name of the string field to delete. Returns true, if the field has been successfully removed. Otherwise, the return value is false. Thrown if the input parameter is null. Contains various static time structure manipulation and conversion routines. Length of a compressed PW_TIME structure in bytes. Pack a DateTime object into 5 bytes. Layout: 2 zero bits, year 12 bits, month 4 bits, day 5 bits, hour 5 bits, minute 6 bits, second 6 bits. Unpack a packed time (5 bytes, packed by the PackTime member function) to a DateTime object. Packed time, 5 bytes. Unpacked DateTime object. Pack a DateTime object into 7 bytes (PW_TIME). Object to be encoded. Packed time, 7 bytes (PW_TIME). Unpack a packed time (7 bytes, PW_TIME) to a DateTime object. Packed time, 7 bytes. Unpacked DateTime object. Convert a DateTime object to a displayable string. DateTime object to convert to a string. String representing the specified DateTime object. Parse a US textual date string, like e.g. "January 02, 2012". Do not remember user name or password. Remember the user name only, not the password. Save both user name and password. For serialization only; use Properties in code. Status message types. Default type: simple information type. Warning message. Error message. Additional information. Depends on lines above. Status logging interface. Function which needs to be called when logging is started. This string should roughly describe the operation, of which the status is logged. Specifies whether the operation is written to the log or not. Function which needs to be called when logging is ended (i.e. when no more messages will be logged and when the percent value won't change any more). Set the current progress in percent. Percent of work finished. Returns true if the caller should continue the current work. Set the current status text. Status text. Type of the message. Returns true if the caller should continue the current work. Check if the user cancelled the current work. Returns true if the caller should continue the current work. Interface for objects that support various times (creation time, last access time, last modification time and expiry time). Offers several helper functions (for example a function to touch the current object). Touch the object. This function updates the internal last access time. If the parameter is true, the last modification time gets updated, too. Each time you call Touch, the usage count of the object is increased by one. Update last modification time. The date/time when the object was created. The date/time when the object was last modified. The date/time when the object was last accessed. The date/time when the object expires. Flag that determines if the object does expire. Get or set the usage count of the object. To increase the usage count by one, use the Touch function. The date/time when the location of the object was last changed. Standard AES cipher implementation. Interface of an encryption/decryption class. Encrypt a stream. Stream to read the plain-text from. Key to use. Initialization vector. Stream, from which the encrypted data can be read. Decrypt a stream. Stream to read the encrypted data from. Key to use. Initialization vector. Stream, from which the decrypted data can be read. UUID of the engine. If you want to write an engine/plugin, please contact the KeePass team to obtain a new UUID. String displayed in the list of available encryption/decryption engines in the GUI. UUID of the cipher engine. This ID uniquely identifies the AES engine. Must not be used by other ciphers. Get the UUID of this cipher engine as PwUuid object. Get a displayable name describing this cipher engine. Interface to a user key, like a password, key file data, etc. Get key data. Querying this property is fast (it returns a reference to a cached ProtectedBinary object). If no key data is available, null is returned. Let the user interface save the current database. If true, the UI will not ask for whether to synchronize or overwrite, it'll simply overwrite the file. Returns true if the file has been saved. Create a new, empty character set collection object. Remove all characters from this set. Add characters to the set. Character to add. Add characters to the set. String containing characters to add. Convert the character set to a string containing all its characters. String containing all character set characters. Number of characters in this set. Get a character of the set using an index. Index of the character to get. Character at the specified position. If the index is invalid, an ArgumentOutOfRangeException is thrown. Create a cryptographic key of length (in bytes) from . Utility functions for generating random passwords. Rename/move a file. For local file system and WebDAV, the specified file is moved, i.e. the file destination can be in a different directory/path. In contrast, for FTP the file is renamed, i.e. its destination must be in the same directory/path. Source file path. Target file path. Password generation function. Password generation options chosen by the user. This may be null, if the default options should be used. Source that the algorithm can use to generate random numbers. Generated password or null in case of failure. If returning null, the caller assumes that an error message has already been shown to the user. Each custom password generation algorithm must have its own unique UUID. Displayable name of the password generation algorithm. A list of auto-type associations. Construct a new auto-type associations list. Remove all associations. Clone the auto-type associations list. New, cloned object. Specify whether auto-type is enabled or not. Specify whether the typing should be obfuscated. The default keystroke sequence that is auto-typed if no matching window is found in the Associations container. Get all auto-type window/keystroke sequence pairs. Name of your key provider (should be unique). Property indicating whether the provider is exclusive. If the provider is exclusive, KeePass doesn't allow other key sources (master password, Windows user account, ...) to be combined with the provider. Key providers typically should return false (to allow non-exclusive use), i.e. don't override this property. Property that specifies whether the returned key data gets hashed by KeePass first or is written directly to the user key data stream. Standard key provider plugins should return false (i.e. don't overwrite this property). Returning true may cause severe security problems and is highly discouraged. This property specifies whether the GetKey method might show a form or dialog. If there is any chance that the method shows one, this property must return true. Only if it's guaranteed that the GetKey method doesn't show any form or dialog, this property should return false. This property specifies whether the key provider is compatible with the secure desktop mode. This almost never is the case, so you usually won't override this property. Implementation of the ChaCha20 cipher with a 96-bit nonce, as specified in RFC 7539. https://tools.ietf.org/html/rfc7539 Constructor. Key (32 bytes). Nonce (12 bytes). If false, the RFC 7539 version of ChaCha20 is used. In this case, only 256 GB of data can be encrypted securely (because the block counter is a 32-bit variable); an attempt to encrypt more data throws an exception. If is true, the 32-bit counter overflows to another 32-bit variable (i.e. the counter effectively is a 64-bit variable), like in the original ChaCha20 specification by D. J. Bernstein (which has a 64-bit counter and a 64-bit nonce). To be compatible with this version, the 64-bit nonce must be stored in the last 8 bytes of and the first 4 bytes must be 0. If the IV was generated randomly, a 12-byte IV and a large counter can be used to securely encrypt more than 256 GB of data (but note this is incompatible with RFC 7539 and the original specification). List of objects that implement IDeepCloneable, and cannot be null. Type specifier. Construct a new list of objects. Clone the current PwObjectList, including all stored objects (deep copy). New PwObjectList. Add an object to this list. Object to be added. Thrown if the input parameter is null. Get an object of the list. Index of the object to get. Must be valid, otherwise an exception is thrown. Reference to an existing T object. Is never null. Get a range of objects. Index of the first object to be returned (inclusive). Index of the last object to be returned (inclusive). Delete an object of this list. The object to be deleted is identified by a reference handle. Reference of the object to be deleted. Returns true if the object was deleted, false if the object wasn't found in this list. Thrown if the input parameter is null. Move an object up or down. The object to be moved. Move one up. If false, move one down. Move some of the objects in this list to the top/bottom. List of objects to be moved. Move to top. If false, move to bottom. Get number of objects in this list. Type of the password generator. Different types like generators based on given patterns, based on character sets, etc. are available. Generator based on character spaces/sets, i.e. groups of characters like lower-case, upper-case or numeric characters. Password generation based on a pattern. The user has provided a pattern, which describes how the generated password has to look like. Cryptographically secure pseudo-random number generator. The returned values are unpredictable and cannot be reproduced. CryptoRandom is a singleton class. Update the internal seed of the random number generator based on entropy data. This method is thread-safe. Entropy bytes. Get a number of cryptographically strong random bytes. This method is thread-safe. Number of requested random bytes. A byte array consisting of random bytes. Get the number of random bytes that this instance generated so far. Note that this number can be higher than the number of random bytes actually requested using the GetRandomBytes method. Event that is triggered whenever the internal GenerateRandom256 method is called to generate random bytes. Interface to native library (library containing fast versions of several cryptographic functions). Determine if the native library is installed. Returns true, if the native library is installed. Transform a key. Source and destination buffer. Key to use in the transformation. Number of transformation rounds. Returns true, if the key was transformed successfully. Benchmark key transformation. Number of milliseconds to perform the benchmark. Number of transformations done. Returns true, if the benchmark was successful. If this property is set to true, the native library is used. If it is false, all calls to functions in this class will fail. Size of a native pointer (in bytes). Resize an image. Image to resize. Width of the returned image. Height of the returned image. Flags to customize scaling behavior. Resized image. This object is always different from (i.e. they can be disposed separately). Contains static buffer manipulation and string conversion routines. Convert a hexadecimal string to a byte array. The input string must be even (i.e. its length is a multiple of 2). String containing hexadecimal characters. Returns a byte array. Returns null if the string parameter was null or is an uneven string (i.e. if its length isn't a multiple of 2). Thrown if is null. Convert a byte array to a hexadecimal string. Input byte array. Returns the hexadecimal string representing the byte array. Returns null, if the input byte array was null. Returns an empty string, if the input byte array has length 0. Decode Base32 strings according to RFC 4648. Set all bytes in a byte array to zero. Input array. All bytes of this array will be set to zero. Set all elements of an array to the default value. Input array. Convert 2 bytes to a 16-bit unsigned integer (little-endian). Convert 2 bytes to a 16-bit unsigned integer (little-endian). Convert 4 bytes to a 32-bit unsigned integer (little-endian). Convert 4 bytes to a 32-bit unsigned integer (little-endian). Convert 8 bytes to a 64-bit unsigned integer (little-endian). Convert 8 bytes to a 64-bit unsigned integer (little-endian). Convert a 16-bit unsigned integer to 2 bytes (little-endian). Convert a 32-bit unsigned integer to 4 bytes (little-endian). Convert a 32-bit unsigned integer to 4 bytes (little-endian). Convert a 64-bit unsigned integer to 8 bytes (little-endian). Convert a 64-bit unsigned integer to 8 bytes (little-endian). Fast hash that can be used e.g. for hash tables. The algorithm might change in the future; do not store the hashes for later use. A user key depending on the currently logged on Windows user account. Construct a user account key. Get key data. Querying this property is fast (it returns a reference to a cached ProtectedBinary object). If no key data is available, null is returned. Function definition of a method that performs an action on a group. When traversing the internal tree, this function will be invoked for all visited groups. Currently visited group. You must return true if you want to continue the traversal. If you want to immediately stop the whole traversal, return false. Function definition of a method that performs an action on an entry. When traversing the internal tree, this function will be invoked for all visited entries. Currently visited entry. You must return true if you want to continue the traversal. If you want to immediately stop the whole traversal, return false. Pool of encryption/decryption algorithms (ciphers). Remove all cipher engines from the current pool. Add a cipher engine to the pool. Cipher engine to add. Must not be null. Get a cipher identified by its UUID. UUID of the cipher to return. Reference to the requested cipher. If the cipher is not found, null is returned. Get the index of a cipher. This index is temporary and should not be stored or used to identify a cipher. UUID of the cipher. Index of the requested cipher. Returns -1 if the specified cipher is not found. Get the index of a cipher. This index is temporary and should not be stored or used to identify a cipher. Name of the cipher. Note that multiple ciphers can have the same name. In this case, the first matching cipher is returned. Cipher with the specified name or -1 if no cipher with that name is found. Reference to the global cipher pool. Get the number of cipher engines in this pool. Get the cipher engine at the specified position. Throws an exception if the index is invalid. You can use this to iterate over all ciphers, but do not use it to identify ciphers. Index of the requested cipher engine. Reference to the cipher engine at the specified position. The core password manager class. It contains a number of groups, which contain the actual entries. Constructs an empty password manager object. Initialize the class for managing a new database. Previously loaded data is deleted. IO connection of the new database. Key to open the database. Open a database. The URL may point to any supported data source. IO connection to load the database from. Key used to open the specified database. Logger, which gets all status messages. Save the currently opened database. The file is written to the location it has been opened from. Logger that recieves status information. Save the currently opened database to a different location. If is true, the specified location is made the default location for future saves using SaveDatabase. New location to serialize the database to. If true, the new location is made the standard location for the database. If false, a copy of the currently opened database is saved to the specified location, but it isn't made the default location (i.e. no lock files will be moved for example). Logger that recieves status information. Closes the currently opened database. No confirmation message is shown before closing. Unsaved changes will be lost. Get the index of a custom icon. ID of the icon. Index of the icon. Get a custom icon. This method can return null, e.g. if no cached image of the icon is available. ID of the icon. Width of the returned image. If this is negative, the image is returned in its original size. Height of the returned image. If this is negative, the image is returned in its original size. Get the root group that contains all groups and entries stored in the database. Root group. The return value is null, if no database has been opened. IOConnection of the currently opened database file. Is never null. If this is true, a database is currently open. Modification flag. If true, the class has been modified and the user interface should prompt the user to save the changes before closing the database for example. The user key used for database encryption. This key must be created and set before using any of the database load/save functions. Name of the database. Database description. Default user name used for new entries. Number of days until history entries are being deleted in a database maintenance operation. The encryption algorithm used to encrypt the data part of the database. Compression algorithm used to encrypt the data part of the database. Memory protection configuration (for default fields). Get a list of all deleted objects. Get all custom icons stored in this database. This is a dirty-flag for the UI. It is used to indicate when an icon list update is required. UUID of the group containing template entries. May be PwUuid.Zero, if no entry templates group has been specified. Custom data container that can be used by plugins to store own data in KeePass databases. The data is stored in the encrypted part of encrypted database files. Use unique names for your items, e.g. "PluginName_ItemName". Custom data container that can be used by plugins to store own data in KeePass databases. The data is stored in the *unencrypted* part of database files, and it is not supported by all file formats (e.g. supported by KDBX, unsupported by XML). It is highly recommended to use CustomData instead, if possible. Use unique names for your items, e.g. "PluginName_ItemName". Hash value of the primary file on disk (last read or last write). A call to SaveAs without making the saved file primary will not change this hash. May be null. Detach binaries when opening a file. If this isn't null, all binaries are saved to the specified path and are removed from the database. Localized application name. Create a deep copy. Unsupported. Length of an encryption key in bytes. The base ICipherEngine assumes 32. Length of the initialization vector in bytes. The base ICipherEngine assumes 16. Represents a key. A key can be build up using several user key data sources like a password, a key file, the currently logged on user credentials, the current computer ID, etc. Construct a new, empty key object. Add a user key. User key to add. Remove a user key. User key to remove. Returns true if the key was removed successfully. Test whether the composite key contains a specific type of user keys (password, key file, ...). If at least one user key of that type is present, the function returns true. User key type. Returns true, if the composite key contains a user key of the specified type. Get the first user key of a specified type. Type of the user key to get. Returns the first user key of the specified type or null if no key of that type is found. Creates the composite key from the supplied user key sources (password, key file, user account, computer ID, etc.). Generate a 32-byte (256-bit) key from the composite key. List of all user keys contained in the current composite key. Construct a new invalid composite key exception. A group containing several password entries. Construct a new, empty group. Construct a new, empty group. Create a new UUID for this group. Set creation, last access and last modification times to the current time. Construct a new group. Create a new UUID for this group. Set creation, last access and last modification times to the current time. Name of the new group. Icon of the new group. Deeply clone the current group. The returned group will be an exact value copy of the current object (including UUID, etc.). Exact value copy of the current PwGroup object. Assign properties to the current group based on a template group. Template group. Must not be null. Only set the properties of the template group if it is newer than the current one. If true, the LocationChanged property is copied, otherwise not. Touch the group. This function updates the internal last access time. If the parameter is true, the last modification time gets updated, too. Modify last modification time. Touch the group. This function updates the internal last access time. If the parameter is true, the last modification time gets updated, too. Modify last modification time. If true, all parent objects get touched, too. Get number of groups and entries in the current group. This function can also traverse through all subgroups and accumulate their counts (recursive mode). If this parameter is true, all subgroups and entries in subgroups will be counted and added to the returned value. If it is false, only the number of subgroups and entries of the current group is returned. Number of subgroups. Number of entries. Traverse the group/entry tree in the current group. Various traversal methods are available. Specifies the traversal method. Function that performs an action on the currently visited group (see GroupHandler for more). This parameter may be null, in this case the tree is traversed but you don't get notifications for each visited group. Function that performs an action on the currently visited entry (see EntryHandler for more). This parameter may be null. Returns true if all entries and groups have been traversed. If the traversal has been canceled by one of the two handlers, the return value is false. Pack all groups into one flat linked list of references (recursively). Flat list of all groups. Pack all entries into one flat linked list of references. Temporary group IDs are assigned automatically. A flat group list created by GetFlatGroupList. Flat list of all entries. Enable protection of a specific string field type. Name of the string field to protect or unprotect. Enable protection or not. Returns true, if the operation completed successfully, otherwise false. Search this group and all subgroups for entries. Specifies the search parameters. Entry list in which the search results will be stored. Search this group and all subgroups for entries. Specifies the search parameters. Entry list in which the search results will be stored. Optional status reporting object. Find a group. UUID identifying the group the caller is looking for. If true, the search is recursive. Returns reference to found group, otherwise null. Find an object. UUID of the object to find. Specifies whether to search recursively. If null, groups and entries are searched. If true, only entries are searched. If false, only groups are searched. Reference to the object, if found. Otherwise null. Try to find a subgroup and create it, if it doesn't exist yet. Name of the subgroup. If the group isn't found: create it. Returns a reference to the requested group or null if it doesn't exist and shouldn't be created. Find an entry. UUID identifying the entry the caller is looking for. If true, the search is recursive. Returns reference to found entry, otherwise null. Get the full path of a group. Full path of the group. Get the full path of a group. String that separates the group names. Specifies whether the returned path starts with the topmost group. Full path of the group. Assign new UUIDs to groups and entries. Create new UUIDs for subgroups. Create new UUIDs for entries. Recursive tree traversal. Find/create a subtree of groups. Tree string. Separators that delimit groups in the strTree parameter. Get the level of the group (i.e. the number of parent groups). Number of parent groups. Get a list of subgroups (not including this one). If true, subgroups are added recursively, i.e. all child groups are returned, too. List of subgroups. If is true, it is guaranteed that subsubgroups appear after subgroups. Get objects contained in this group. Specifies whether to search recursively. If null, the returned list contains groups and entries. If true, the returned list contains only entries. If false, the returned list contains only groups. List of objects. Add a subgroup to this group. Group to be added. Must not be null. If this parameter is true, the parent group reference of the subgroup will be set to the current group (i.e. the current group takes ownership of the subgroup). Add a subgroup to this group. Group to be added. Must not be null. If this parameter is true, the parent group reference of the subgroup will be set to the current group (i.e. the current group takes ownership of the subgroup). If true, the LocationChanged property of the subgroup is updated. Add an entry to this group. Entry to be added. Must not be null. If this parameter is true, the parent group reference of the entry will be set to the current group (i.e. the current group takes ownership of the entry). Add an entry to this group. Entry to be added. Must not be null. If this parameter is true, the parent group reference of the entry will be set to the current group (i.e. the current group takes ownership of the entry). If true, the LocationChanged property of the entry is updated. UUID of this group. The name of this group. Cannot be null. Comments about this group. Cannot be null. Icon of the group. Get the custom icon ID. This value is 0, if no custom icon is being used (i.e. the icon specified by the IconID property should be displayed). Reference to the group to which this group belongs. May be null. The date/time when the location of the object was last changed. A flag that specifies if the group is shown as expanded or collapsed in the user interface. The date/time when this group was created. The date/time when this group was last modified. The date/time when this group was last accessed (read). The date/time when this group expires. Flag that determines if the group expires. Get or set the usage count of the group. To increase the usage count by one, use the Touch function. Get a list of subgroups in this group. Get a list of entries in this group. A flag specifying whether this group is virtual or not. Virtual groups can contain links to entries stored in other groups. Note that this flag has to be interpreted and set by the calling code; it won't prevent you from accessing and modifying the list of entries in this group in any way. Default auto-type keystroke sequence for all entries in this group. This property can be an empty string, which means that the value should be inherited from the parent. Custom data container that can be used by plugins to store own data in KeePass groups. The data is stored in the encrypted part of encrypted database files. Use unique names for your items, e.g. "PluginName_ItemName". A strongly-typed resource class, for looking up localized strings, etc. Look up a localized string similar to 'Test'. Custom icon. PwCustomIcon objects are immutable. Get the icon as an Image (original size). Get the icon as an Image (with the specified size). Width of the returned image. Height of the returned image. A class that offers static functions to estimate the quality of passwords. Estimate the quality of a password. Password to check. Estimated bit-strength of the password. Estimate the quality of a password. Password to check, UTF-8 encoded. Estimated bit-strength of the password. The KdbxFile class supports saving the data to various formats. The default, encrypted file format. Use this flag when exporting data to a plain-text XML file. If this property is set to a non-null stream, all data that is read from the input stream is automatically written to the copy stream (before returning the read data). Represents an UUID of a password entry or group. Once created, PwUuid objects aren't modifyable anymore (immutable). Standard size in bytes of a UUID. Zero UUID (all bytes are zero). Construct a new UUID object. If this parameter is true, a new UUID is generated. If it is false, the UUID is initialized to zero. Construct a new UUID object. Initial value of the PwUuid object. Create a new, random UUID. Returns true if a random UUID has been generated, otherwise it returns false. Convert the UUID to its string representation. String containing the UUID value. Get the 16 UUID bytes. Name of the provider that generated the custom key. Compression algorithm specifiers. No compression. GZip compression. Virtual field: currently known number of algorithms. Should not be used by plugins or libraries -- it's used internally only. Tree traversal methods. Don't traverse the tree. Traverse the tree in pre-order mode, i.e. first visit all items in the current node, then visit all subnodes. Methods for merging password databases/entries. Icon identifiers for groups and password entries. Virtual identifier -- represents the number of icons. Use default user credentials (provided by the system). Default or Manual, depending on whether manual credentials are available. This type exists for supporting upgrading from KeePass 2.28 to 2.29; the user cannot select this type. Comparison modes for in-memory protected objects. Ignore the in-memory protection states. Ignore the in-memory protection states of standard objects; do compare in-memory protection states of custom objects. Compare in-memory protection states. Empty standard string fields are considered to be the same as non-existing standard string fields. This doesn't affect custom string comparisons. The IO connection is being opened for reading. The IO connection is being opened for writing. The IO connection is being opened for testing whether a file/object exists. The IO connection is being opened for deleting a file/object. The IO connection is being opened for renaming/moving a file/object. This flag prevents any handles being garbage-collected before the started process has terminated, without blocking the current thread. UIIcon indicates that the returned image is going to be displayed as icon in the UI and that it is not subject to future changes in size. A class representing a password entry. A password entry consists of several fields like title, user name, password, etc. Each password entry has a unique ID (UUID). Construct a new, empty password entry. Member variables will be initialized to their default values. If true, a new UUID will be created for this entry. If false, the UUID is zero and you must set it manually later. If true, the creation, last modification and last access times will be set to the current system time. Construct a new, empty password entry. Member variables will be initialized to their default values. Reference to the containing group, this parameter may be null and set later manually. If true, a new UUID will be created for this entry. If false, the UUID is zero and you must set it manually later. If true, the creation, last modification and last access times will be set to the current system time. Clone the current entry. The returned entry is an exact value copy of the current entry (including UUID and parent group reference). All mutable members are cloned. Exact value clone. All references to mutable values changed. Assign properties to the current entry based on a template entry. Template entry. Must not be null. Only set the properties of the template entry if it is newer than the current one. If true, the history will be copied, too. If true, the LocationChanged property is copied, otherwise not. Touch the entry. This function updates the internal last access time. If the parameter is true, the last modification time gets updated, too. Modify last modification time. Touch the entry. This function updates the internal last access time. If the parameter is true, the last modification time gets updated, too. Modify last modification time. If true, all parent objects get touched, too. Create a backup of this entry. The backup item doesn't contain any history items. Create a backup of this entry. The backup item doesn't contain any history items. If this parameter isn't null, the history list is maintained automatically (i.e. old backups are deleted if there are too many or the history size is too large). This parameter may be null (no maintenance then). Restore an entry snapshot from backups. Index of the backup item, to which should be reverted. Restore an entry snapshot from backups. Index of the backup item, to which should be reverted. If this parameter isn't null, the history list is maintained automatically (i.e. old backups are deleted if there are too many or the history size is too large). This parameter may be null (no maintenance then). Delete old history items if there are too many or the history size is too large. If one or more history items have been deleted, true is returned. Otherwise false. Approximate the total size of this entry in bytes (including strings, binaries and history entries). Size in bytes. UUID of this entry. Reference to a group which contains the current entry. The date/time when the location of the object was last changed. Get or set all entry strings. Get or set all entry binaries. Get or set all auto-type window/keystroke sequence associations. Get all previous versions of this entry (backups). Image ID specifying the icon that will be used for this entry. Get the custom icon ID. This value is 0, if no custom icon is being used (i.e. the icon specified by the IconID property should be displayed). Get or set the foreground color of this entry. Get or set the background color of this entry. The date/time when this entry was created. The date/time when this entry was last modified. The date/time when this entry was last accessed (read). The date/time when this entry expires. Use the Expires property to specify if the entry does actually expire or not. Specifies whether the entry expires or not. Get or set the usage count of the entry. To increase the usage count by one, use the Touch function. Entry-specific override URL. If this string is non-empty, List of tags associated with this entry. Custom data container that can be used by plugins to store own data in KeePass entries. The data is stored in the encrypted part of encrypted database files. Use unique names for your items, e.g. "PluginName_ItemName". Represents an in-memory encrypted string. ProtectedString objects are immutable and thread-safe. Construct a new protected string object. Protection is disabled. Construct a new protected string. The string is initialized to the value supplied in the parameters. If this parameter is true, the string will be protected in memory (encrypted). If it is false, the string will be stored as plain-text. The initial string value. Construct a new protected string. The string is initialized to the value supplied in the parameters (UTF-8 encoded string). If this parameter is true, the string will be protected in memory (encrypted). If it is false, the string will be stored as plain-text. The initial string value, encoded as UTF-8 byte array. This parameter won't be modified; the caller is responsible for clearing it. Construct a new protected string. The string is initialized to the value passed in the XorredBuffer object. Enable protection or not. XorredBuffer object containing the string in UTF-8 representation. The UTF-8 string must not be null-terminated. Convert the protected string to a normal string object. Be careful with this function, the returned string object isn't protected anymore and stored in plain-text in the process memory. Plain-text string. Is never null. Read out the string and return a byte array that contains the string encoded using UTF-8. The returned string is not protected anymore! Plain-text UTF-8 byte array. Read the protected string and return it protected with a sequence of bytes generated by a random stream. Random number source. Protected string. A flag specifying whether the ProtectedString object has turned on memory protection or not. Represents a protected binary, i.e. a byte array that is encrypted in memory. A ProtectedBinary object is immutable and thread-safe. Construct a new, empty protected binary data object. Protection is disabled. Construct a new protected binary data object. If this paremeter is true, the data will be encrypted in memory. If it is false, the data is stored in plain-text in the process memory. Value of the protected object. The input parameter is not modified and ProtectedBinary doesn't take ownership of the data, i.e. the caller is responsible for clearing it. Construct a new protected binary data object. If this paremeter is true, the data will be encrypted in memory. If it is false, the data is stored in plain-text in the process memory. Value of the protected object. The input parameter is not modified and ProtectedBinary doesn't take ownership of the data, i.e. the caller is responsible for clearing it. Offset for . Size for . Construct a new protected binary data object. Copy the data from a XorredBuffer object. Enable protection or not. XorredBuffer object used to initialize the ProtectedBinary object. Get a copy of the protected data as a byte array. Please note that the returned byte array is not protected and can therefore been read by any other application. Make sure that your clear it properly after usage. Unprotected byte array. This is always a copy of the internal protected data and can therefore be cleared safely. Read the protected data and return it protected with a sequence of bytes generated by a random stream. Random number source. A plugin can provide a custom memory protection method by assigning a non-null delegate to this property. A flag specifying whether the ProtectedBinary object has turned on memory protection or not. Length of the stored data. Class containing self-test methods. Perform a self-test. Application-wide logging services. Represents an object that has been deleted. Construct a new PwDeletedObject object. Clone the object. Value copy of the current object. UUID of the entry that has been deleted. The date/time when the entry has been deleted. Master password / passphrase as provided by the user. Get the password as protected string. Get key data. Querying this property is fast (it returns a reference to a cached ProtectedBinary object). If no key data is available, null is returned. Key files as provided by the user. Create a new, random key-file. Path where the key-file should be saved to. If the file exists already, it will be overwritten. Additional entropy used to generate the random key. May be null (in this case only the KeePass-internal random number generator is used). Returns a FileSaveResult error code. Path to the key file. Get key data. Querying this property is fast (it returns a reference to a cached ProtectedBinary object). If no key data is available, null is returned. A list of ProtectedBinary objects (dictionary). Construct a new list of protected binaries. Clone the current ProtectedBinaryList object, including all stored protected strings. New ProtectedBinaryList object. Get one of the stored binaries. Binary identifier. Protected binary. If the binary identified by cannot be found, the function returns null. Thrown if the input parameter is null. Set a binary object. Identifier of the binary field to modify. New value. This parameter must not be null. Thrown if any of the input parameters is null. Remove a binary object. Identifier of the binary field to remove. Returns true if the object has been successfully removed, otherwise false. Thrown if the input parameter is null. Get the number of binaries in this entry. Build/PrepMonoDev.sh0000664000000000000000000000342413156213236013354 0ustar rootroot#!/bin/sh kpBuild="$(pwd)" kpRoot="${kpBuild}/.." # Mono's resource compiler/linker doesn't support ICO files # containing high resolution images (in PNG format) kpIco="${kpRoot}/Ext/Icons_15_VA/LowResIcons/KeePass_LR.ico" kpIcoG="${kpRoot}/Ext/Icons_15_VA/LowResIcons/KeePass_LR_G.ico" kpIcoR="${kpRoot}/Ext/Icons_15_VA/LowResIcons/KeePass_LR_R.ico" kpIcoY="${kpRoot}/Ext/Icons_15_VA/LowResIcons/KeePass_LR_Y.ico" fnPrepSolution() { cd "${kpRoot}" local kpSln="KeePass.sln" # Update solution format to 11 (this targets Mono 4 rather than 3.5) sed -i 's!Format Version 10\.00!Format Version 11\.00!g' "${kpSln}" } fnPrepKeePass() { cd "${kpRoot}/KeePass" local kpCsProj="KeePass.csproj" sed -i 's! ToolsVersion="3\.5"!!g' "${kpCsProj}" sed -i 's!true!false!g' "${kpCsProj}" sed -i '/sgen\.exe/d' "${kpCsProj}" cp -f "${kpIco}" KeePass.ico cp -f "${kpIco}" Resources/Icons/KeePass.ico cp -f "${kpIcoG}" Resources/Icons/KeePass_G.ico cp -f "${kpIcoR}" Resources/Icons/KeePass_R.ico cp -f "${kpIcoY}" Resources/Icons/KeePass_Y.ico } fnPrepKeePassLib() { cd "${kpRoot}/KeePassLib" local kpCsProj="KeePassLib.csproj" local kpKdbxRS="Serialization/KdbxFile.Read.Streamed.cs" sed -i 's! ToolsVersion="3\.5"!!g' "${kpCsProj}" sed -i 's!true!false!g' "${kpCsProj}" sed -i -E 's!(xrs\.ProhibitDtd = true;)!// \1!g' "${kpKdbxRS}" sed -i -E 's!// (xrs\.DtdProcessing = DtdProcessing\.Prohibit;)!\1!g' "${kpKdbxRS}" } fnPrepTrlUtil() { cd "${kpRoot}/Translation/TrlUtil" local kpCsProj="TrlUtil.csproj" sed -i 's! ToolsVersion="3\.5"!!g' "${kpCsProj}" cp -f "${kpIco}" Resources/KeePass.ico } fnPrepSolution fnPrepKeePass fnPrepKeePassLib fnPrepTrlUtil cd "${kpBuild}" Build/Clean.bat0000664000000000000000000000407013222754410012330 0ustar rootrootRMDIR /S /Q KeePass RMDIR /S /Q KeePass_Distrib RMDIR /S /Q KeePassLib RMDIR /S /Q KeePassLibDoc REM RMDIR /S /Q KeePassLibSD REM RMDIR /S /Q KeePassNtv RMDIR /S /Q ShInstUtil RMDIR /S /Q ..\Ext\Output RMDIR /S /Q ..\KeePass\obj DEL ..\KeePass\KeePass.csproj.user RMDIR /S /Q ..\KeePassLib\obj DEL ..\KeePassLib\KeePassLib.csproj.user REM RMDIR /S /Q ..\KeePassLibSD\obj REM DEL ..\KeePassLibSD\KeePassLibSD.csproj.user REM RMDIR /S /Q ..\ShInstUtil\obj REM DEL ..\ShInstUtil\ShInstUtil.csproj.user DEL ..\ShInstUtil\ShInstUtil.aps DEL ..\ShInstUtil\ShInstUtil.ncb DEL /A:H ..\ShInstUtil\ShInstUtil.suo DEL /Q ..\ShInstUtil\*.user DEL /A:H ..\KeePass.suo DEL ..\KeePass.ncb REM DEL /Q ..\KeePassNtv\*.aps REM DEL /Q ..\KeePassNtv\*.user RMDIR /S /Q ArcFourCipher RMDIR /S /Q ..\Plugins\ArcFourCipher\obj DEL ..\Plugins\ArcFourCipher\ArcFourCipher.csproj.user DEL /A:H ..\Plugins\ArcFourCipher\ArcFourCipher.suo RMDIR /S /Q KPScript RMDIR /S /Q ..\Plugins\KPScript\obj DEL ..\Plugins\KPScript\KPScript.csproj.user DEL /A:H ..\Plugins\KPScript\KPScript.suo RMDIR /S /Q SamplePlugin RMDIR /S /Q ..\Plugins\SamplePlugin\obj DEL ..\Plugins\SamplePlugin\SamplePlugin.csproj.user DEL /A:H ..\Plugins\SamplePlugin\SamplePlugin.suo RMDIR /S /Q ..\Plugins\SamplePluginCpp\Build DEL /Q ..\Plugins\SamplePluginCpp\*.aps DEL /Q ..\Plugins\SamplePluginCpp\*.user DEL /Q ..\Plugins\SamplePluginCpp\*.ncb DEL /A:H ..\Plugins\SamplePluginCpp\SamplePluginCpp.suo RMDIR /S /Q ..\Translation\TrlUtil\Build RMDIR /S /Q ..\Translation\TrlUtil\obj DEL ..\Translation\KeePass.config.xml DEL ..\Translation\KeePass.exe DEL ..\Translation\KeePass.exe.config DEL ..\Translation\KeePass.pdb DEL ..\Translation\KeePass.XmlSerializers.dll DEL ..\Translation\TrlUtil.exe DEL ..\Translation\TrlUtil.exe.config DEL ..\Translation\TrlUtil.pdb DEL ..\Translation\TrlUtil.vshost.exe DEL ..\Translation\TrlUtil.vshost.exe.manifest DEL /A:H ..\Ext\KeePassMsi\KeePassMsi.suo RMDIR /S /Q ..\Ext\KeePassMsi\.vs RMDIR /S /Q KeePassMsi RMDIR /S /Q KPScript CLSKeePass.sln0000664000000000000000000001007712610400266011631 0ustar rootrootMicrosoft Visual Studio Solution File, Format Version 10.00 # Visual Studio 2008 Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "KeePassLib", "KeePassLib\KeePassLib.csproj", "{53573E4E-33CB-4FDB-8698-C95F5E40E7F3}" EndProject Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "KeePass", "KeePass\KeePass.csproj", "{10938016-DEE2-4A25-9A5A-8FD3444379CA}" EndProject Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "TrlUtil", "Translation\TrlUtil\TrlUtil.csproj", "{B7E890E7-BF50-4450-9A52-C105BD98651C}" EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Any CPU = Debug|Any CPU Debug|Mixed Platforms = Debug|Mixed Platforms Debug|Win32 = Debug|Win32 Debug|x64 = Debug|x64 Release|Any CPU = Release|Any CPU Release|Mixed Platforms = Release|Mixed Platforms Release|Win32 = Release|Win32 Release|x64 = Release|x64 EndGlobalSection GlobalSection(ProjectConfigurationPlatforms) = postSolution {53573E4E-33CB-4FDB-8698-C95F5E40E7F3}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {53573E4E-33CB-4FDB-8698-C95F5E40E7F3}.Debug|Any CPU.Build.0 = Debug|Any CPU {53573E4E-33CB-4FDB-8698-C95F5E40E7F3}.Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU {53573E4E-33CB-4FDB-8698-C95F5E40E7F3}.Debug|Mixed Platforms.Build.0 = Debug|Any CPU {53573E4E-33CB-4FDB-8698-C95F5E40E7F3}.Debug|Win32.ActiveCfg = Debug|Any CPU {53573E4E-33CB-4FDB-8698-C95F5E40E7F3}.Debug|x64.ActiveCfg = Debug|Any CPU {53573E4E-33CB-4FDB-8698-C95F5E40E7F3}.Release|Any CPU.ActiveCfg = Release|Any CPU {53573E4E-33CB-4FDB-8698-C95F5E40E7F3}.Release|Any CPU.Build.0 = Release|Any CPU {53573E4E-33CB-4FDB-8698-C95F5E40E7F3}.Release|Mixed Platforms.ActiveCfg = Release|Any CPU {53573E4E-33CB-4FDB-8698-C95F5E40E7F3}.Release|Mixed Platforms.Build.0 = Release|Any CPU {53573E4E-33CB-4FDB-8698-C95F5E40E7F3}.Release|Win32.ActiveCfg = Release|Any CPU {53573E4E-33CB-4FDB-8698-C95F5E40E7F3}.Release|x64.ActiveCfg = Release|Any CPU {10938016-DEE2-4A25-9A5A-8FD3444379CA}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {10938016-DEE2-4A25-9A5A-8FD3444379CA}.Debug|Any CPU.Build.0 = Debug|Any CPU {10938016-DEE2-4A25-9A5A-8FD3444379CA}.Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU {10938016-DEE2-4A25-9A5A-8FD3444379CA}.Debug|Mixed Platforms.Build.0 = Debug|Any CPU {10938016-DEE2-4A25-9A5A-8FD3444379CA}.Debug|Win32.ActiveCfg = Debug|Any CPU {10938016-DEE2-4A25-9A5A-8FD3444379CA}.Debug|x64.ActiveCfg = Debug|Any CPU {10938016-DEE2-4A25-9A5A-8FD3444379CA}.Release|Any CPU.ActiveCfg = Release|Any CPU {10938016-DEE2-4A25-9A5A-8FD3444379CA}.Release|Any CPU.Build.0 = Release|Any CPU {10938016-DEE2-4A25-9A5A-8FD3444379CA}.Release|Mixed Platforms.ActiveCfg = Release|Any CPU {10938016-DEE2-4A25-9A5A-8FD3444379CA}.Release|Mixed Platforms.Build.0 = Release|Any CPU {10938016-DEE2-4A25-9A5A-8FD3444379CA}.Release|Win32.ActiveCfg = Release|Any CPU {10938016-DEE2-4A25-9A5A-8FD3444379CA}.Release|x64.ActiveCfg = Release|Any CPU {B7E890E7-BF50-4450-9A52-C105BD98651C}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {B7E890E7-BF50-4450-9A52-C105BD98651C}.Debug|Any CPU.Build.0 = Debug|Any CPU {B7E890E7-BF50-4450-9A52-C105BD98651C}.Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU {B7E890E7-BF50-4450-9A52-C105BD98651C}.Debug|Mixed Platforms.Build.0 = Debug|Any CPU {B7E890E7-BF50-4450-9A52-C105BD98651C}.Debug|Win32.ActiveCfg = Debug|Any CPU {B7E890E7-BF50-4450-9A52-C105BD98651C}.Debug|x64.ActiveCfg = Debug|Any CPU {B7E890E7-BF50-4450-9A52-C105BD98651C}.Release|Any CPU.ActiveCfg = Release|Any CPU {B7E890E7-BF50-4450-9A52-C105BD98651C}.Release|Any CPU.Build.0 = Release|Any CPU {B7E890E7-BF50-4450-9A52-C105BD98651C}.Release|Mixed Platforms.ActiveCfg = Release|Any CPU {B7E890E7-BF50-4450-9A52-C105BD98651C}.Release|Mixed Platforms.Build.0 = Release|Any CPU {B7E890E7-BF50-4450-9A52-C105BD98651C}.Release|Win32.ActiveCfg = Release|Any CPU {B7E890E7-BF50-4450-9A52-C105BD98651C}.Release|x64.ActiveCfg = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE EndGlobalSection EndGlobal KeePass/0000775000000000000000000000000013225117636011117 5ustar rootrootKeePass/App/0000775000000000000000000000000013222430402011621 5ustar rootrootKeePass/App/AppPolicy.cs0000664000000000000000000002512313222430402014053 0ustar rootroot/* KeePass Password Safe - The Open-Source Password Manager Copyright (C) 2003-2018 Dominik Reichl This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ using System; using System.Collections.Generic; using System.Windows.Forms; using System.ComponentModel; using System.Diagnostics; using KeePass.Resources; using KeePassLib; using KeePassLib.Utility; namespace KeePass.App { /// /// Application policy IDs. /// public enum AppPolicyId { Plugins = 0, Export, ExportNoKey, // Don't require the current key to be repeated Import, Print, PrintNoKey, // Don't require the current key to be repeated NewFile, SaveFile, AutoType, AutoTypeWithoutContext, CopyToClipboard, CopyWholeEntries, DragDrop, UnhidePasswords, ChangeMasterKey, ChangeMasterKeyNoKey, // Don't require the current key to be repeated EditTriggers } /// /// Application policy flags. /// public sealed class AppPolicyFlags { private bool m_bPlugins = true; [DefaultValue(true)] public bool Plugins { get { return m_bPlugins; } set { m_bPlugins = value; } } private bool m_bExport = true; [DefaultValue(true)] public bool Export { get { return m_bExport;} set { m_bExport = value;} } private bool m_bExportNoKey = true; [DefaultValue(true)] public bool ExportNoKey { get { return m_bExportNoKey; } set { m_bExportNoKey = value; } } private bool m_bImport = true; [DefaultValue(true)] public bool Import { get { return m_bImport; } set { m_bImport = value; } } private bool m_bPrint = true; [DefaultValue(true)] public bool Print { get { return m_bPrint; } set { m_bPrint = value; } } private bool m_bPrintNoKey = true; [DefaultValue(true)] public bool PrintNoKey { get { return m_bPrintNoKey; } set { m_bPrintNoKey = value; } } private bool m_bNewFile = true; [DefaultValue(true)] public bool NewFile { get { return m_bNewFile; } set { m_bNewFile = value; } } private bool m_bSave = true; [DefaultValue(true)] public bool SaveFile { get { return m_bSave; } set { m_bSave = value; } } private bool m_bAutoType = true; [DefaultValue(true)] public bool AutoType { get { return m_bAutoType; } set { m_bAutoType = value; } } private bool m_bAutoTypeWithoutContext = true; [DefaultValue(true)] public bool AutoTypeWithoutContext { get { return m_bAutoTypeWithoutContext; } set { m_bAutoTypeWithoutContext = value; } } private bool m_bClipboard = true; [DefaultValue(true)] public bool CopyToClipboard { get { return m_bClipboard; } set { m_bClipboard = value; } } private bool m_bCopyWholeEntries = true; [DefaultValue(true)] public bool CopyWholeEntries { get { return m_bCopyWholeEntries; } set { m_bCopyWholeEntries = value; } } private bool m_bDragDrop = true; [DefaultValue(true)] public bool DragDrop { get { return m_bDragDrop; } set { m_bDragDrop = value; } } private bool m_bUnhidePasswords = true; [DefaultValue(true)] public bool UnhidePasswords { get { return m_bUnhidePasswords; } set { m_bUnhidePasswords = value; } } private bool m_bChangeMasterKey = true; [DefaultValue(true)] public bool ChangeMasterKey { get { return m_bChangeMasterKey; } set { m_bChangeMasterKey = value; } } private bool m_bChangeMasterKeyNoKey = true; [DefaultValue(true)] public bool ChangeMasterKeyNoKey { get { return m_bChangeMasterKeyNoKey; } set { m_bChangeMasterKeyNoKey = value; } } private bool m_bTriggersEdit = true; [DefaultValue(true)] public bool EditTriggers { get { return m_bTriggersEdit; } set { m_bTriggersEdit = value; } } public AppPolicyFlags CloneDeep() { return (AppPolicyFlags)this.MemberwiseClone(); } } /// /// Application policy settings. /// public static class AppPolicy { private static AppPolicyFlags m_apfCurrent = new AppPolicyFlags(); // private static AppPolicyFlags m_apfNew = new AppPolicyFlags(); public static AppPolicyFlags Current { get { return m_apfCurrent; } set { if(value == null) throw new ArgumentNullException("value"); m_apfCurrent = value; } } /* public static AppPolicyFlags New { get { return m_apfNew; } set { if(value == null) throw new ArgumentNullException("value"); m_apfNew = value; } } */ private static string PolicyToString(AppPolicyId flag, bool bPrefix) { string str = (bPrefix ? "* " : string.Empty); str += KPRes.Feature + ": "; switch(flag) { case AppPolicyId.Plugins: str += KPRes.Plugins; break; case AppPolicyId.Export: str += KPRes.Export; break; case AppPolicyId.ExportNoKey: str += KPRes.Export + " - " + KPRes.NoKeyRepeat; break; case AppPolicyId.Import: str += KPRes.Import; break; case AppPolicyId.Print: str += KPRes.Print; break; case AppPolicyId.PrintNoKey: str += KPRes.Print + " - " + KPRes.NoKeyRepeat; break; case AppPolicyId.NewFile: str += KPRes.NewDatabase; break; case AppPolicyId.SaveFile: str += KPRes.SaveDatabase; break; case AppPolicyId.AutoType: str += KPRes.AutoType; break; case AppPolicyId.AutoTypeWithoutContext: str += KPRes.AutoType + " - " + KPRes.WithoutContext; break; case AppPolicyId.CopyToClipboard: str += KPRes.Clipboard; break; case AppPolicyId.CopyWholeEntries: str += KPRes.CopyWholeEntries; break; case AppPolicyId.DragDrop: str += KPRes.DragDrop; break; case AppPolicyId.UnhidePasswords: str += KPRes.UnhidePasswords; break; case AppPolicyId.ChangeMasterKey: str += KPRes.ChangeMasterKey; break; case AppPolicyId.ChangeMasterKeyNoKey: str += KPRes.ChangeMasterKey + " - " + KPRes.NoKeyRepeat; break; case AppPolicyId.EditTriggers: str += KPRes.TriggersEdit; break; default: Debug.Assert(false); str += KPRes.Unknown + "."; break; } str += MessageService.NewLine; if(bPrefix) str += "* "; str += KPRes.Description + ": "; switch(flag) { case AppPolicyId.Plugins: str += KPRes.PolicyPluginsDesc; break; case AppPolicyId.Export: str += KPRes.PolicyExportDesc2; break; case AppPolicyId.ExportNoKey: str += KPRes.PolicyExportNoKeyDesc; break; case AppPolicyId.Import: str += KPRes.PolicyImportDesc; break; case AppPolicyId.Print: str += KPRes.PolicyPrintDesc; break; case AppPolicyId.PrintNoKey: str += KPRes.PolicyPrintNoKeyDesc; break; case AppPolicyId.NewFile: str += KPRes.PolicyNewDatabaseDesc; break; case AppPolicyId.SaveFile: str += KPRes.PolicySaveDatabaseDesc; break; case AppPolicyId.AutoType: str += KPRes.PolicyAutoTypeDesc; break; case AppPolicyId.AutoTypeWithoutContext: str += KPRes.PolicyAutoTypeWithoutContextDesc; break; case AppPolicyId.CopyToClipboard: str += KPRes.PolicyClipboardDesc; break; case AppPolicyId.CopyWholeEntries: str += KPRes.PolicyCopyWholeEntriesDesc; break; case AppPolicyId.DragDrop: str += KPRes.PolicyDragDropDesc; break; case AppPolicyId.UnhidePasswords: str += KPRes.UnhidePasswordsDesc; break; case AppPolicyId.ChangeMasterKey: str += KPRes.PolicyChangeMasterKey; break; case AppPolicyId.ChangeMasterKeyNoKey: str += KPRes.PolicyChangeMasterKeyNoKeyDesc; break; case AppPolicyId.EditTriggers: str += KPRes.PolicyTriggersEditDesc; break; default: Debug.Assert(false); str += KPRes.Unknown + "."; break; } return str; } public static string RequiredPolicyMessage(AppPolicyId flag) { string str = KPRes.PolicyDisallowed + MessageService.NewParagraph; str += KPRes.PolicyRequiredFlag + ":" + MessageService.NewLine; str += PolicyToString(flag, true); return str; } public static bool Try(AppPolicyId flag) { bool bAllowed = true; switch(flag) { case AppPolicyId.Plugins: bAllowed = m_apfCurrent.Plugins; break; case AppPolicyId.Export: bAllowed = m_apfCurrent.Export; break; case AppPolicyId.ExportNoKey: bAllowed = m_apfCurrent.ExportNoKey; break; case AppPolicyId.Import: bAllowed = m_apfCurrent.Import; break; case AppPolicyId.Print: bAllowed = m_apfCurrent.Print; break; case AppPolicyId.PrintNoKey: bAllowed = m_apfCurrent.PrintNoKey; break; case AppPolicyId.NewFile: bAllowed = m_apfCurrent.NewFile; break; case AppPolicyId.SaveFile: bAllowed = m_apfCurrent.SaveFile; break; case AppPolicyId.AutoType: bAllowed = m_apfCurrent.AutoType; break; case AppPolicyId.AutoTypeWithoutContext: bAllowed = m_apfCurrent.AutoTypeWithoutContext; break; case AppPolicyId.CopyToClipboard: bAllowed = m_apfCurrent.CopyToClipboard; break; case AppPolicyId.CopyWholeEntries: bAllowed = m_apfCurrent.CopyWholeEntries; break; case AppPolicyId.DragDrop: bAllowed = m_apfCurrent.DragDrop; break; case AppPolicyId.UnhidePasswords: bAllowed = m_apfCurrent.UnhidePasswords; break; case AppPolicyId.ChangeMasterKey: bAllowed = m_apfCurrent.ChangeMasterKey; break; case AppPolicyId.ChangeMasterKeyNoKey: bAllowed = m_apfCurrent.ChangeMasterKeyNoKey; break; case AppPolicyId.EditTriggers: bAllowed = m_apfCurrent.EditTriggers; break; default: Debug.Assert(false); break; } if(bAllowed == false) { string strMsg = RequiredPolicyMessage(flag); MessageService.ShowWarning(strMsg); } return bAllowed; } } } KeePass/App/AppHelp.cs0000664000000000000000000001177213222430402013511 0ustar rootroot/* KeePass Password Safe - The Open-Source Password Manager Copyright (C) 2003-2018 Dominik Reichl This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ using System; using System.IO; using System.Diagnostics; using System.Threading; using KeePass.Util; using KeePassLib; using KeePassLib.Utility; namespace KeePass.App { public enum AppHelpSource { Local, Online } /// /// Application help provider. Starts an external application that /// shows help on a specified topic. /// public static class AppHelp { private static string m_strLocalHelpFile = null; /// /// Get/set the path of the local help file. /// public static string LocalHelpFile { get { return m_strLocalHelpFile; } set { m_strLocalHelpFile = value; } } public static bool LocalHelpAvailable { get { if(m_strLocalHelpFile == null) return false; try { return File.Exists(m_strLocalHelpFile); } catch(Exception) { } return false; } } public static AppHelpSource PreferredHelpSource { get { return ((Program.Config.Application.HelpUseLocal) ? AppHelpSource.Local : AppHelpSource.Online); } set { Program.Config.Application.HelpUseLocal = (value == AppHelpSource.Local); } } /// /// Show a help page. /// /// Topic name. May be null. /// Section name. May be null. Must not start /// with the '#' character. public static void ShowHelp(string strTopic, string strSection) { AppHelp.ShowHelp(strTopic, strSection, false); } /// /// Show a help page. /// /// Topic name. May be null. /// Section name. May be null. Must not start /// with the '#' character. /// Specify if the local help file should be /// preferred. If no local help file is available, the online help /// system will be used, independent of the bPreferLocal flag. public static void ShowHelp(string strTopic, string strSection, bool bPreferLocal) { if(AppHelp.LocalHelpAvailable) { if(bPreferLocal || (AppHelp.PreferredHelpSource == AppHelpSource.Local)) AppHelp.ShowHelpLocal(strTopic, strSection); else AppHelp.ShowHelpOnline(strTopic, strSection); } else AppHelp.ShowHelpOnline(strTopic, strSection); } private static void ShowHelpLocal(string strTopic, string strSection) { Debug.Assert(m_strLocalHelpFile != null); // Unblock CHM file for proper display of help contents WinUtil.RemoveZoneIdentifier(m_strLocalHelpFile); string strCmd = "\"ms-its:" + m_strLocalHelpFile; if(strTopic != null) strCmd += @"::/help/" + strTopic + ".html"; if(strSection != null) { Debug.Assert(strTopic != null); // Topic must be present for section strCmd += @"#" + strSection; } strCmd += "\""; try { Process.Start(WinUtil.LocateSystemApp("hh.exe"), strCmd); } catch(Exception exStart) { MessageService.ShowWarning(@"hh.exe " + strCmd, exStart); } } private static void ShowHelpOnline(string strTopic, string strSection) { string strCmd = PwDefs.HelpUrl; if(strTopic != null) strCmd += strTopic + ".html"; if(strSection != null) { Debug.Assert(strTopic != null); // Topic must be present for section strCmd += @"#" + strSection; } try { ParameterizedThreadStart pts = new ParameterizedThreadStart(AppHelp.RunCommandAsync); Thread th = new Thread(pts); // Local, but thread will continue to run anyway th.Start(strCmd); } catch(Exception exThread) { MessageService.ShowWarning(strCmd, exThread); } } private static void RunCommandAsync(object pData) { Debug.Assert(pData != null); if(pData == null) throw new ArgumentNullException("pData"); string strCommand = (pData as string); Debug.Assert(strCommand != null); if(strCommand == null) throw new ArgumentException(); try { Process.Start(strCommand); } catch(Exception exStart) { MessageService.ShowWarning(strCommand, exStart); } } } } KeePass/App/AppIcons.cs0000664000000000000000000001042413222430402013665 0ustar rootroot/* KeePass Password Safe - The Open-Source Password Manager Copyright (C) 2003-2018 Dominik Reichl This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ using System; using System.Collections.Generic; using System.Diagnostics; using System.Drawing; using System.Globalization; using System.Text; using KeePass.UI; namespace KeePass.App { public enum AppIconType { None = 0, Main, QuadNormal, QuadLocked } public static class AppIcons { private static readonly Color[] g_vColors = new Color[] { // Default should be first Color.Blue, Color.Red, Color.Lime, Color.Yellow // Color.Green.G == 128, Color.Lime.G == 255 }; internal static Color[] Colors { get { return g_vColors; } } private static Dictionary g_dCache = new Dictionary(); private static readonly object g_oCacheSync = new object(); public static Icon Default { get { return Get(AppIconType.Main, Size.Empty, g_vColors[0]); } } public static Icon Get(AppIconType t, Size sz, Color clr) { int w = Math.Min(Math.Max(sz.Width, 0), 256); int h = Math.Min(Math.Max(sz.Height, 0), 256); if((w == 0) || (h == 0)) { Size szDef = UIUtil.GetIconSize(); w = szDef.Width; h = szDef.Height; } Color c = RoundColor(clr); NumberFormatInfo nf = NumberFormatInfo.InvariantInfo; string strID = ((long)t).ToString(nf) + ":" + w.ToString(nf) + ":" + h.ToString(nf) + ":" + c.ToArgb().ToString(nf); Icon ico = null; lock(g_oCacheSync) { if(g_dCache.TryGetValue(strID, out ico)) return ico; } if(t == AppIconType.Main) { if(c == Color.Red) ico = Properties.Resources.KeePass_R; else if(c == Color.Lime) ico = Properties.Resources.KeePass_G; else if(c == Color.Yellow) ico = Properties.Resources.KeePass_Y; else { Debug.Assert(c == Color.Blue); ico = Properties.Resources.KeePass; } } else if(t == AppIconType.QuadNormal) { if(c == Color.Red) ico = Properties.Resources.QuadNormal_R; else if(c == Color.Lime) ico = Properties.Resources.QuadNormal_G; else if(c == Color.Yellow) ico = Properties.Resources.QuadNormal_Y; else { Debug.Assert(c == Color.Blue); ico = Properties.Resources.QuadNormal; } } else if(t == AppIconType.QuadLocked) { Debug.Assert(c == Color.Blue); ico = Properties.Resources.QuadLocked; } else { Debug.Assert(false); } Icon icoSc = null; if(ico != null) icoSc = new Icon(ico, w, h); // Preserves icon data else { Debug.Assert(false); } lock(g_oCacheSync) { g_dCache[strID] = icoSc; } return icoSc; } private static int ColorDist(Color c1, Color c2) { int dR = (int)c1.R - (int)c2.R; int dG = (int)c1.G - (int)c2.G; int dB = (int)c1.B - (int)c2.B; return ((dR * dR) + (dG * dG) + (dB * dB)); } /// /// Round to the nearest supported color. /// public static Color RoundColor(Color clr) { int c = clr.ToArgb(); // Color name is irrelevant for(int i = 0; i < g_vColors.Length; ++i) { if(g_vColors[i].ToArgb() == c) return g_vColors[i]; // With name } if((clr.R == clr.B) && (clr.G == clr.B)) return g_vColors[0]; // Gray => default int iColor = 0; int dMin = int.MaxValue; for(int i = 0; i < g_vColors.Length; ++i) { int d = ColorDist(clr, g_vColors[i]); if(d < dMin) { iColor = i; dMin = d; } } return g_vColors[iColor]; } } } KeePass/App/AppDefs.cs0000664000000000000000000002663213222430402013503 0ustar rootroot/* KeePass Password Safe - The Open-Source Password Manager Copyright (C) 2003-2018 Dominik Reichl This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ using System; using System.Collections.Generic; using System.Drawing; using System.Windows.Forms; using KeePass.UI; using KeePass.Resources; using KeePassLib; using KeePassLib.Utility; namespace KeePass.App { public static class AppDefs { public static readonly Color ColorControlNormal = SystemColors.Window; public static readonly Color ColorControlDisabled = SystemColors.Control; public static readonly Color ColorEditError = Color.FromArgb(255, 192, 192); public static readonly Color ColorQualityLow = Color.FromArgb(255, 128, 0); public static readonly Color ColorQualityHigh = Color.FromArgb(0, 255, 0); public const string LanguagesDir = "Languages"; public const string PluginsDir = "Plugins"; public const string PluginProductName = "KeePass Plugin"; public const string XslFilesDir = "XSL"; public const string XslFileHtmlFull = "KDBX_DetailsFull_HTML.xsl"; public const string XslFileHtmlLight = "KDBX_DetailsLight_HTML.xsl"; public const string XslFileHtmlTabular = "KDBX_Tabular_HTML.xsl"; public static class FileNames { public const string Program = "KeePass.exe"; public const string XmlSerializers = "KeePass.XmlSerializers.dll"; public const string NativeLib32 = "KeePassLibC32.dll"; public const string NativeLib64 = "KeePassLibC64.dll"; public const string ShInstUtil = "ShInstUtil.exe"; } // public const string MruNameValueSplitter = @"/::/"; /// /// Hot key IDs (used in WM_HOTKEY window messages). /// public static class GlobalHotKeyId { public const int AutoType = 195; public const int AutoTypeSelected = 196; public const int ShowWindow = 226; public const int EntryMenu = 227; internal const int TempRegTest = 225; } public static class HelpTopics { public const string Acknowledgements = "base/credits"; public const string License = "v2/license"; public const string DatabaseSettings = "v2/dbsettings"; public const string DbSettingsGeneral = "general"; public const string DbSettingsSecurity = "security"; // public const string DbSettingsProtection = "protection"; public const string DbSettingsCompression = "compression"; public const string AutoType = "base/autotype"; public const string AutoTypeObfuscation = "v2/autotype_obfuscation"; public const string AutoTypeWindowFilters = "autowindows"; public const string Entry = "v2/entry"; public const string EntryGeneral = "general"; public const string EntryStrings = "advanced"; public const string EntryAutoType = "autotype"; public const string EntryHistory = "history"; public const string KeySources = "base/keys"; public const string KeySourcesKeyFile = "keyfiles"; public const string KeySourcesUserAccount = "winuser"; public const string PwGenerator = "base/pwgenerator"; public const string IOConnections = "v2/ioconnect"; public const string UrlField = "base/autourl"; public const string CommandLine = "base/cmdline"; public const string FieldRefs = "base/fieldrefs"; public const string ImportExport = "base/importexport"; public const string ImportExportGenericCsv = "genericcsv"; public const string ImportExportSteganos = "imp_steganos"; public const string ImportExportPassKeeper = "imp_passkeeper"; public const string AppPolicy = "v2/policy"; public const string Triggers = "v2/triggers"; public const string TriggersEvents = "events"; public const string TriggersConditions = "conditions"; public const string TriggersActions = "actions"; public const string Setup = "v2/setup"; public const string SetupMono = "mono"; // public const string FaqTech = "base/faq_tech"; // public const string FaqTechMemProt = "memprot"; public const string XmlReplace = "v2/xml_replace"; } public static class CommandLineOptions { public const string Password = "pw"; public const string KeyFile = "keyfile"; public const string UserAccount = "useraccount"; public const string PasswordEncrypted = "pw-enc"; public const string PasswordStdIn = "pw-stdin"; public const string PreSelect = "preselect"; public const string IoCredUserName = "iousername"; public const string IoCredPassword = "iopassword"; public const string IoCredFromRecent = "iocredfromrecent"; public const string IoCredIsComplete = "ioiscomplete"; // User-friendly Pascal-case (shown in UAC dialog) public const string FileExtRegister = "RegisterFileExt"; public const string FileExtUnregister = "UnregisterFileExt"; public const string PreLoad = "preload"; // public const string PreLoadRegister = "registerpreload"; // public const string PreLoadUnregister = "unregisterpreload"; public const string ExitAll = "exit-all"; public const string Minimize = "minimize"; public const string AutoType = "auto-type"; public const string AutoTypeSelected = "auto-type-selected"; public const string OpenEntryUrl = "entry-url-open"; public const string LockAll = "lock-all"; public const string UnlockAll = "unlock-all"; public const string IpcEvent = "e"; public const string Uuid = "uuid"; public const string Help = @"?"; public const string HelpLong = "help"; public const string WorkaroundDisable = "wa-disable"; public const string ConfigPathLocal = "cfg-local"; public const string ConfigSetUrlOverride = "set-urloverride"; public const string ConfigClearUrlOverride = "clear-urloverride"; public const string ConfigGetUrlOverride = "get-urloverride"; public const string ConfigSetLanguageFile = "set-languagefile"; public const string PlgxCreate = "plgx-create"; public const string PlgxCreateInfo = "plgx-create-info"; public const string PlgxPrereqKP = "plgx-prereq-kp"; public const string PlgxPrereqNet = "plgx-prereq-net"; public const string PlgxPrereqOS = "plgx-prereq-os"; public const string PlgxPrereqPtr = "plgx-prereq-ptr"; public const string PlgxBuildPre = "plgx-build-pre"; public const string PlgxBuildPost = "plgx-build-post"; public const string Debug = "debug"; public const string DebugThrowException = "debug-throwexcp"; // public const string SavePluginCompileRes = "saveplgxcr"; // Now: Debug public const string ShowAssemblyInfo = "showasminfo"; public const string MakeXmlSerializerEx = "makexmlserializerex"; public const string MakeXspFile = "makexspfile"; #if DEBUG public const string TestGfx = "testgfx"; #endif public const string Version = "version"; // For Unix // #if (DEBUG && !KeePassLibSD) // public const string MakePopularPasswordTable = "makepopularpasswordtable"; // #endif } public static class FileExtension { public const string FileExt = "kdbx"; public const string ExtId = "kdbxfile"; public const string KeyFile = "key"; } public const string AutoRunName = "KeePass Password Safe 2"; public const string PreLoadName = "KeePass 2 PreLoad"; public const string MutexName = "KeePassAppMutex"; public const string MutexNameGlobal = "KeePassAppMutexEx"; // public const string ScriptExtension = "kps"; public const int InvalidWindowValue = -16381; public static class NamedEntryColor { public static readonly Color LightRed = Color.FromArgb(255, 204, 204); public static readonly Color LightGreen = Color.FromArgb(204, 255, 204); public static readonly Color LightBlue = Color.FromArgb(153, 204, 255); public static readonly Color LightYellow = Color.FromArgb(255, 255, 153); } public static class FileDialogContext { // Values must not contain '@' public const string Database = "Database"; public const string Sync = "Sync"; public const string KeyFile = "KeyFile"; public const string Import = "Import"; public const string Export = "Export"; public const string Attachments = "Attachments"; public const string Xsl = "Xsl"; } public const string DefaultTrlAuthor = "Dominik Reichl"; public const string DefaultTrlContact = "https://www.dominik-reichl.de/"; // public const string LanguageInfoFileName = "LanguageInfo.xml"; internal const string Rsa4096PublicKeyXml = @"9Oa8Bb9if4rSYBxczLVQ3Yyae95dWQrNJ1FlqS7DoF" + @"RF80tD2hq84vxDE8slVeSHs68KMFnJhPsXFD6nM9oTRBaUlU/alnRTUU+X/cUXbr" + @"mhYN9DkJhM0OcWk5Vsl9Qxl613sA+hqIwmPc+el/fCM/1vP6JkHo/JTJ2OxQvDKN" + @"4cC55pHYMZt+HX6AhemsPe7ejTG7l9nN5tHGmD+GrlwuxBTddzFBARmoknFzDPWd" + @"QHddjuK1mXDs6lWeu73ODlSLSHMc5n0R2xMwGHN4eaiIMGzEbt0lv1aMWz+Iy1H3" + @"XgFgWGDHX9kx8yefmfcgFIK4Y/xHU5EyGAV68ZHPatv6i4pT4ZuecIb5GSoFzVXq" + @"8BZjbe+zDI+Wr1u8jLcBH0mySTWkF2gooQLvE1vgZXP1blsA7UFZSVFzYjBt36HQ" + @"SJLpQ9AjjB5MKpMSlvdb5SnvjzREiFVLoBsY7KH2TMz+IG1Rh3OZTGwjQKXkgRVj" + @"5XrEMTFRmT1zo2BHWhx8vrY6agVzqsCVqxYRbjeAhgOi6hLDMHSNAVuNg6ZHOKS8" + @"6x6kmBcBhGJriwY017H3Oxuhfz33ehRFX/C05egCvmR2TAXbqm+CUgrq1bZ96T/y" + @"s+O5uvKpe7H+EZuWb655Y9WuQSby+q0Vqqny7T6Z2NbEnI8nYHg5ZZP+TijSxeH0" + @"8=AQAB"; public const string ColumnIdnGroup = "Group"; public const string ColumnIdnCreationTime = "CreationTime"; public const string ColumnIdnLastModificationTime = "LastModificationTime"; public const string ColumnIdnLastAccessTime = "LastAccessTime"; public const string ColumnIdnExpiryTime = "ExpiryTime"; public const string ColumnIdnUuid = "UUID"; public const string ColumnIdnAttachment = "Attachment"; public static string GetEntryField(PwEntry pe, string strFieldId) { if(pe == null) throw new ArgumentNullException("pe"); if(strFieldId == null) throw new ArgumentNullException("strFieldId"); if(strFieldId == AppDefs.ColumnIdnGroup) return ((pe.ParentGroup != null) ? pe.ParentGroup.Name : string.Empty); else if(strFieldId == AppDefs.ColumnIdnCreationTime) return TimeUtil.ToDisplayString(pe.CreationTime); else if(strFieldId == AppDefs.ColumnIdnLastModificationTime) return TimeUtil.ToDisplayString(pe.LastModificationTime); else if(strFieldId == AppDefs.ColumnIdnLastAccessTime) return TimeUtil.ToDisplayString(pe.LastAccessTime); else if(strFieldId == AppDefs.ColumnIdnExpiryTime) { if(!pe.Expires) return KPRes.NeverExpires; return TimeUtil.ToDisplayString(pe.ExpiryTime); } else if(strFieldId == AppDefs.ColumnIdnUuid) return pe.Uuid.ToHexString(); else if(strFieldId == AppDefs.ColumnIdnAttachment) return pe.Binaries.UCount.ToString(); return pe.Strings.ReadSafe(strFieldId); } } } KeePass/App/Configuration/0000775000000000000000000000000013224666720014450 5ustar rootrootKeePass/App/Configuration/AceIntegration.cs0000664000000000000000000003621313222430402017660 0ustar rootroot/* KeePass Password Safe - The Open-Source Password Manager Copyright (C) 2003-2018 Dominik Reichl This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ using System; using System.Collections.Generic; using System.Text; using System.Windows.Forms; using System.Xml.Serialization; using System.ComponentModel; using System.Diagnostics; using KeePassLib; using KeePassLib.Interfaces; using KeePassLib.Utility; namespace KeePass.App.Configuration { public sealed class AceIntegration { private ulong m_hkAutoType = (ulong)(Keys.Control | Keys.Alt | Keys.A); public ulong HotKeyGlobalAutoType { get { return m_hkAutoType; } set { m_hkAutoType = value; } } private ulong m_hkAutoTypeSel = (ulong)Keys.None; public ulong HotKeySelectedAutoType { get { return m_hkAutoTypeSel; } set { m_hkAutoTypeSel = value; } } private ulong m_hkShowWindow = (ulong)(Keys.Control | Keys.Alt | Keys.K); public ulong HotKeyShowWindow { get { return m_hkShowWindow; } set { m_hkShowWindow = value; } } private ulong m_hkEntryMenu = (ulong)Keys.None; public ulong HotKeyEntryMenu { get { return m_hkEntryMenu; } set { m_hkEntryMenu = value; } } private bool m_bCheckHotKeys = true; [DefaultValue(true)] public bool CheckHotKeys { get { return m_bCheckHotKeys; } set { m_bCheckHotKeys = value; } } private string m_strUrlOverride = string.Empty; [DefaultValue("")] public string UrlOverride { get { return m_strUrlOverride; } set { if(value == null) throw new ArgumentNullException("value"); m_strUrlOverride = value; } } private AceUrlSchemeOverrides m_vSchemeOverrides = new AceUrlSchemeOverrides(); public AceUrlSchemeOverrides UrlSchemeOverrides { get { return m_vSchemeOverrides; } set { if(value == null) throw new ArgumentNullException("value"); m_vSchemeOverrides = value; } } private bool m_bSearchKeyFiles = true; [DefaultValue(true)] public bool SearchKeyFiles { get { return m_bSearchKeyFiles; } set { m_bSearchKeyFiles = value; } } private bool m_bSearchKeyFilesOnRemovable = false; [DefaultValue(false)] public bool SearchKeyFilesOnRemovableMedia { get { return m_bSearchKeyFilesOnRemovable; } set { m_bSearchKeyFilesOnRemovable = value; } } private bool m_bSingleInstance = true; [DefaultValue(true)] public bool LimitToSingleInstance { get { return m_bSingleInstance; } set { m_bSingleInstance = value; } } private bool m_bMatchByTitle = true; [DefaultValue(true)] public bool AutoTypeMatchByTitle { get { return m_bMatchByTitle; } set { m_bMatchByTitle = value; } } private bool m_bMatchByUrlInTitle = false; [DefaultValue(false)] public bool AutoTypeMatchByUrlInTitle { get { return m_bMatchByUrlInTitle; } set { m_bMatchByUrlInTitle = value; } } private bool m_bMatchByUrlHostInTitle = false; [DefaultValue(false)] public bool AutoTypeMatchByUrlHostInTitle { get { return m_bMatchByUrlHostInTitle; } set { m_bMatchByUrlHostInTitle = value; } } private bool m_bMatchByTagInTitle = false; [DefaultValue(false)] public bool AutoTypeMatchByTagInTitle { get { return m_bMatchByTagInTitle; } set { m_bMatchByTagInTitle = value; } } private bool m_bExpiredCanMatch = false; [DefaultValue(false)] public bool AutoTypeExpiredCanMatch { get { return m_bExpiredCanMatch; } set { m_bExpiredCanMatch = value; } } private bool m_bAutoTypeAlwaysShowSelDlg = false; [DefaultValue(false)] public bool AutoTypeAlwaysShowSelDialog { get { return m_bAutoTypeAlwaysShowSelDlg; } set { m_bAutoTypeAlwaysShowSelDlg = value; } } private bool m_bPrependInitSeqIE = true; [DefaultValue(true)] public bool AutoTypePrependInitSequenceForIE { get { return m_bPrependInitSeqIE; } set { m_bPrependInitSeqIE = value; } } private bool m_bSpecialReleaseAlt = true; [DefaultValue(true)] public bool AutoTypeReleaseAltWithKeyPress { get { return m_bSpecialReleaseAlt; } set { m_bSpecialReleaseAlt = value; } } private bool m_bAdjustKeybLayout = true; [DefaultValue(true)] public bool AutoTypeAdjustKeyboardLayout { get { return m_bAdjustKeybLayout; } set { m_bAdjustKeybLayout = value; } } private bool m_bAllowInterleaved = false; [DefaultValue(false)] public bool AutoTypeAllowInterleaved { get { return m_bAllowInterleaved; } set { m_bAllowInterleaved = value; } } private bool m_bCancelOnWindowChange = false; [DefaultValue(false)] public bool AutoTypeCancelOnWindowChange { get { return m_bCancelOnWindowChange; } set { m_bCancelOnWindowChange = value; } } private bool m_bCancelOnTitleChange = false; [DefaultValue(false)] public bool AutoTypeCancelOnTitleChange { get { return m_bCancelOnTitleChange; } set { m_bCancelOnTitleChange = value; } } private int m_iInterKeyDelay = -1; [DefaultValue(-1)] public int AutoTypeInterKeyDelay { get { return m_iInterKeyDelay; } set { m_iInterKeyDelay = value; } } private List m_lAbortWindows = new List(); [XmlArrayItem("Window")] public List AutoTypeAbortOnWindows { get { return m_lAbortWindows; } set { if(value == null) throw new ArgumentNullException("value"); m_lAbortWindows = value; } } private ProxyServerType m_pstProxyType = ProxyServerType.System; public ProxyServerType ProxyType { get { return m_pstProxyType; } set { m_pstProxyType = value; } } private string m_strProxyAddr = string.Empty; [DefaultValue("")] public string ProxyAddress { get { return m_strProxyAddr; } set { if(value == null) throw new ArgumentNullException("value"); m_strProxyAddr = value; } } private string m_strProxyPort = string.Empty; [DefaultValue("")] public string ProxyPort { get { return m_strProxyPort; } set { if(value == null) throw new ArgumentNullException("value"); m_strProxyPort = value; } } private ProxyAuthType m_pstProxyAuthType = ProxyAuthType.Auto; public ProxyAuthType ProxyAuthType { get { return m_pstProxyAuthType; } set { m_pstProxyAuthType = value; } } private string m_strProxyUser = string.Empty; [DefaultValue("")] public string ProxyUserName { get { return m_strProxyUser; } set { if(value == null) throw new ArgumentNullException("value"); m_strProxyUser = value; } } private string m_strProxyPassword = string.Empty; [DefaultValue("")] public string ProxyPassword { get { return m_strProxyPassword; } set { if(value == null) throw new ArgumentNullException("value"); m_strProxyPassword = value; } } public AceIntegration() { } } public sealed class AceUrlSchemeOverrides : IDeepCloneable { private List m_lBuiltInOverrides = new List(); [XmlIgnore] public List BuiltInOverrides { get { return m_lBuiltInOverrides; } set { if(value == null) throw new ArgumentNullException("value"); m_lBuiltInOverrides = value; } } public ulong BuiltInOverridesEnabled { get { return GetEnabledBuiltInOverrides(); } set { SetEnabledBuiltInOverrides(value); } } private List m_lCustomOverrides = new List(); [XmlArrayItem("Override")] public List CustomOverrides { get { return m_lCustomOverrides; } set { if(value == null) throw new ArgumentNullException("value"); m_lCustomOverrides = value; } } public AceUrlSchemeOverrides() { MakeBuiltInList(); } private void MakeBuiltInList() { m_lBuiltInOverrides.Clear(); m_lBuiltInOverrides.Add(new AceUrlSchemeOverride(true, "ssh", @"cmd://PuTTY.exe -ssh {USERNAME}@{BASE:RMVSCM}", 0x1)); m_lBuiltInOverrides.Add(new AceUrlSchemeOverride(false, "http", "cmd://{INTERNETEXPLORER} \"{BASE}\"", 0x2)); m_lBuiltInOverrides.Add(new AceUrlSchemeOverride(false, "https", "cmd://{INTERNETEXPLORER} \"{BASE}\"", 0x4)); m_lBuiltInOverrides.Add(new AceUrlSchemeOverride(false, "http", "cmd://{INTERNETEXPLORER} -private \"{BASE}\"", 0x10000)); m_lBuiltInOverrides.Add(new AceUrlSchemeOverride(false, "https", "cmd://{INTERNETEXPLORER} -private \"{BASE}\"", 0x20000)); m_lBuiltInOverrides.Add(new AceUrlSchemeOverride(false, "http", "microsoft-edge:{BASE}", 0x4000)); m_lBuiltInOverrides.Add(new AceUrlSchemeOverride(false, "https", "microsoft-edge:{BASE}", 0x8000)); m_lBuiltInOverrides.Add(new AceUrlSchemeOverride(false, "http", "cmd://{FIREFOX} \"{BASE}\"", 0x8)); m_lBuiltInOverrides.Add(new AceUrlSchemeOverride(false, "https", "cmd://{FIREFOX} \"{BASE}\"", 0x10)); m_lBuiltInOverrides.Add(new AceUrlSchemeOverride(false, "http", "cmd://{FIREFOX} -private-window \"{BASE}\"", 0x100000)); m_lBuiltInOverrides.Add(new AceUrlSchemeOverride(false, "https", "cmd://{FIREFOX} -private-window \"{BASE}\"", 0x200000)); m_lBuiltInOverrides.Add(new AceUrlSchemeOverride(false, "chrome", "cmd://{FIREFOX} -chrome \"{BASE}\"", 0x20)); m_lBuiltInOverrides.Add(new AceUrlSchemeOverride(false, "http", "cmd://{GOOGLECHROME} \"{BASE}\"", 0x100)); m_lBuiltInOverrides.Add(new AceUrlSchemeOverride(false, "https", "cmd://{GOOGLECHROME} \"{BASE}\"", 0x200)); m_lBuiltInOverrides.Add(new AceUrlSchemeOverride(false, "http", "cmd://{GOOGLECHROME} --incognito \"{BASE}\"", 0x40000)); m_lBuiltInOverrides.Add(new AceUrlSchemeOverride(false, "https", "cmd://{GOOGLECHROME} --incognito \"{BASE}\"", 0x80000)); m_lBuiltInOverrides.Add(new AceUrlSchemeOverride(false, "http", "cmd://{OPERA} \"{BASE}\"", 0x40)); m_lBuiltInOverrides.Add(new AceUrlSchemeOverride(false, "https", "cmd://{OPERA} \"{BASE}\"", 0x80)); m_lBuiltInOverrides.Add(new AceUrlSchemeOverride(false, "http", "cmd://{OPERA} --private \"{BASE}\"", 0x400000)); m_lBuiltInOverrides.Add(new AceUrlSchemeOverride(false, "https", "cmd://{OPERA} --private \"{BASE}\"", 0x800000)); m_lBuiltInOverrides.Add(new AceUrlSchemeOverride(false, "http", "cmd://{SAFARI} \"{BASE}\"", 0x400)); m_lBuiltInOverrides.Add(new AceUrlSchemeOverride(false, "https", "cmd://{SAFARI} \"{BASE}\"", 0x800)); m_lBuiltInOverrides.Add(new AceUrlSchemeOverride(false, "kdbx", "cmd://\"{APPDIR}\\KeePass.exe\" \"{BASE:RMVSCM}\" -pw-enc:\"{PASSWORD_ENC}\"", 0x1000)); m_lBuiltInOverrides.Add(new AceUrlSchemeOverride(false, "kdbx", "cmd://mono \"{APPDIR}/KeePass.exe\" \"{BASE:RMVSCM}\" -pw-enc:\"{PASSWORD_ENC}\"", 0x2000)); // Free: 0x1000000 #if DEBUG ulong u = 0; foreach(AceUrlSchemeOverride o in m_lBuiltInOverrides) { Debug.Assert(o.IsBuiltIn); ulong f = o.BuiltInFlagID; Debug.Assert((f != 0) && ((f & (f - 1)) == 0)); // Check power of 2 u += f; } Debug.Assert(u == ((1UL << m_lBuiltInOverrides.Count) - 1UL)); #endif } public string GetOverrideForUrl(string strUrl) { if(string.IsNullOrEmpty(strUrl)) return null; for(int i = 0; i < 2; ++i) { List l = ((i == 0) ? m_lBuiltInOverrides : m_lCustomOverrides); foreach(AceUrlSchemeOverride ovr in l) { if(!ovr.Enabled) continue; if(strUrl.StartsWith(ovr.Scheme + ":", StrUtil.CaseIgnoreCmp)) return ovr.UrlOverride; } } return null; } public AceUrlSchemeOverrides CloneDeep() { AceUrlSchemeOverrides ovr = new AceUrlSchemeOverrides(); CopyTo(ovr); return ovr; } public void CopyTo(AceUrlSchemeOverrides ovrTarget) { ovrTarget.m_lBuiltInOverrides.Clear(); foreach(AceUrlSchemeOverride shB in m_lBuiltInOverrides) { ovrTarget.m_lBuiltInOverrides.Add(shB.CloneDeep()); } ovrTarget.m_lCustomOverrides.Clear(); foreach(AceUrlSchemeOverride shC in m_lCustomOverrides) { ovrTarget.m_lCustomOverrides.Add(shC.CloneDeep()); } } public ulong GetEnabledBuiltInOverrides() { ulong u = 0; for(int i = 0; i < m_lBuiltInOverrides.Count; ++i) { if(m_lBuiltInOverrides[i].Enabled) u |= m_lBuiltInOverrides[i].BuiltInFlagID; } return u; } public void SetEnabledBuiltInOverrides(ulong uFlags) { for(int i = 0; i < m_lBuiltInOverrides.Count; ++i) m_lBuiltInOverrides[i].Enabled = ((uFlags & m_lBuiltInOverrides[i].BuiltInFlagID) != 0UL); } } public sealed class AceUrlSchemeOverride : IDeepCloneable { private bool m_bEnabled = true; public bool Enabled { get { return m_bEnabled; } set { m_bEnabled = value; } } private string m_strScheme = string.Empty; public string Scheme { get { return m_strScheme; } set { if(value == null) throw new ArgumentNullException("value"); m_strScheme = value; } } private string m_strOvr = string.Empty; public string UrlOverride { get { return m_strOvr; } set { if(value == null) throw new ArgumentNullException("value"); m_strOvr = value; } } private ulong m_uBuiltInFlagID = 0; [XmlIgnore] internal ulong BuiltInFlagID { get { return m_uBuiltInFlagID; } } [XmlIgnore] public bool IsBuiltIn { get { return (m_uBuiltInFlagID != 0UL); } } public AceUrlSchemeOverride() { } public AceUrlSchemeOverride(bool bEnable, string strScheme, string strUrlOverride) { Init(bEnable, strScheme, strUrlOverride, 0); } internal AceUrlSchemeOverride(bool bEnable, string strScheme, string strUrlOverride, ulong uBuiltInFlagID) { Init(bEnable, strScheme, strUrlOverride, uBuiltInFlagID); } private void Init(bool bEnable, string strScheme, string strUrlOverride, ulong uBuiltInFlagID) { if(strScheme == null) throw new ArgumentNullException("strScheme"); if(strUrlOverride == null) throw new ArgumentNullException("strUrlOverride"); m_bEnabled = bEnable; m_strScheme = strScheme; m_strOvr = strUrlOverride; m_uBuiltInFlagID = uBuiltInFlagID; } public AceUrlSchemeOverride CloneDeep() { return new AceUrlSchemeOverride(m_bEnabled, m_strScheme, m_strOvr, m_uBuiltInFlagID); } } } KeePass/App/Configuration/AcePasswordGenerator.cs0000664000000000000000000000370013222430402021041 0ustar rootroot/* KeePass Password Safe - The Open-Source Password Manager Copyright (C) 2003-2018 Dominik Reichl This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ using System; using System.Collections.Generic; using System.Text; using System.Xml.Serialization; using KeePassLib.Cryptography.PasswordGenerator; namespace KeePass.App.Configuration { public sealed class AcePasswordGenerator { public AcePasswordGenerator() { } private PwProfile m_pwgoAutoProfile = new PwProfile(); public PwProfile AutoGeneratedPasswordsProfile { get { return m_pwgoAutoProfile; } set { if(value == null) throw new ArgumentNullException("value"); m_pwgoAutoProfile = value; } } private PwProfile m_pwgoLastProfile = new PwProfile(); public PwProfile LastUsedProfile { get { return m_pwgoLastProfile; } set { if(value == null) throw new ArgumentNullException("value"); m_pwgoLastProfile = value; } } private List m_vUserProfiles = new List(); [XmlArrayItem("Profile")] public List UserProfiles { get { return m_vUserProfiles; } set { if(value == null) throw new ArgumentNullException("value"); m_vUserProfiles = value; } } } } KeePass/App/Configuration/AceToolBar.cs0000664000000000000000000000230313222430404016732 0ustar rootroot/* KeePass Password Safe - The Open-Source Password Manager Copyright (C) 2003-2018 Dominik Reichl This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ using System; using System.Collections.Generic; using System.Text; using System.ComponentModel; namespace KeePass.App.Configuration { public sealed class AceToolBar { public AceToolBar() { } private bool m_bShow = true; [DefaultValue(true)] public bool Show { get { return m_bShow; } set { m_bShow = value; } } } } KeePass/App/Configuration/AceUI.cs0000664000000000000000000002504113222430404015711 0ustar rootroot/* KeePass Password Safe - The Open-Source Password Manager Copyright (C) 2003-2018 Dominik Reichl This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ using System; using System.Collections.Generic; using System.Text; using System.Drawing; using System.ComponentModel; using System.Diagnostics; using KeePass.UI; namespace KeePass.App.Configuration { [Flags] public enum AceKeyUIFlags : ulong { None = 0, EnablePassword = 0x1, EnableKeyFile = 0x2, EnableUserAccount = 0x4, EnableHidePassword = 0x8, DisablePassword = 0x100, DisableKeyFile = 0x200, DisableUserAccount = 0x400, DisableHidePassword = 0x800, CheckPassword = 0x10000, CheckKeyFile = 0x20000, CheckUserAccount = 0x40000, CheckHidePassword = 0x80000, UncheckPassword = 0x1000000, UncheckKeyFile = 0x2000000, UncheckUserAccount = 0x4000000, UncheckHidePassword = 0x8000000 } [Flags] public enum AceUIFlags : ulong { None = 0, DisableOptions = 0x1, DisablePlugins = 0x2, DisableTriggers = 0x4, DisableKeyChangeDays = 0x8, HidePwQuality = 0x10, DisableUpdateCheck = 0x20, HideBuiltInPwGenPrfInEntryDlg = 0x10000, ShowLastAccessTime = 0x20000, HideNewDbInfoDialogs = 0x40000 } [Flags] public enum AceAutoTypeCtxFlags : long { None = 0, ColTitle = 0x1, ColUserName = 0x2, ColPassword = 0x4, ColUrl = 0x8, ColNotes = 0x10, ColSequence = 0x20, ColSequenceComments = 0x40, Default = (ColTitle | ColUserName | ColUrl | ColSequence) } public sealed class AceUI { public AceUI() { } private AceTrayIcon m_tray = new AceTrayIcon(); public AceTrayIcon TrayIcon { get { return m_tray; } set { if(value == null) throw new ArgumentNullException("value"); m_tray = value; } } private AceHiding m_uiHiding = new AceHiding(); public AceHiding Hiding { get { return m_uiHiding; } set { if(value == null) throw new ArgumentNullException("value"); m_uiHiding = value; } } private bool m_bRepeatPwOnlyWhenHidden = true; [DefaultValue(true)] public bool RepeatPasswordOnlyWhenHidden { get { return m_bRepeatPwOnlyWhenHidden; } set { m_bRepeatPwOnlyWhenHidden = value; } } private AceFont m_font = new AceFont(); public AceFont StandardFont { get { return m_font; } set { if(value == null) throw new ArgumentNullException("value"); m_font = value; } } private AceFont m_fontPasswords = new AceFont(true); public AceFont PasswordFont { get { return m_fontPasswords; } set { if(value == null) throw new ArgumentNullException("value"); m_fontPasswords = value; } } private bool m_bForceSysFont = true; [DefaultValue(true)] public bool ForceSystemFontUnix { get { return m_bForceSysFont; } set { m_bForceSysFont = value; } } private BannerStyle m_bannerStyle = BannerStyle.WinVistaBlack; public BannerStyle BannerStyle { get { return m_bannerStyle; } set { m_bannerStyle = value; } } private bool m_bShowImportStatusDlg = true; [DefaultValue(true)] public bool ShowImportStatusDialog { get { return m_bShowImportStatusDlg; } set { m_bShowImportStatusDlg = value; } } private bool m_bShowDbMntncResDlg = true; [DefaultValue(true)] public bool ShowDbMntncResultsDialog { get { return m_bShowDbMntncResDlg; } set { m_bShowDbMntncResDlg = value; } } private bool m_bShowRecycleDlg = true; [DefaultValue(true)] public bool ShowRecycleConfirmDialog { get { return m_bShowRecycleDlg; } set { m_bShowRecycleDlg = value; } } private bool m_bShowEmSheetDlg = true; [DefaultValue(true)] public bool ShowEmSheetDialog { get { return m_bShowEmSheetDlg; } set { m_bShowEmSheetDlg = value; } } // private bool m_bUseCustomTsRenderer = true; // [DefaultValue(true)] // public bool UseCustomToolStripRenderer // { // get { return m_bUseCustomTsRenderer; } // set { m_bUseCustomTsRenderer = value; } // } private string m_strToolStripRenderer = string.Empty; [DefaultValue("")] public string ToolStripRenderer { get { return m_strToolStripRenderer; } set { if(value == null) throw new ArgumentNullException("value"); m_strToolStripRenderer = value; } } private bool m_bOptScreenReader = false; [DefaultValue(false)] public bool OptimizeForScreenReader { get { return m_bOptScreenReader; } set { m_bOptScreenReader = value; } } private string m_strDataViewerRect = string.Empty; [DefaultValue("")] public string DataViewerRect { get { return m_strDataViewerRect; } set { if(value == null) throw new ArgumentNullException("value"); m_strDataViewerRect = value; } } private string m_strDataEditorRect = string.Empty; [DefaultValue("")] public string DataEditorRect { get { return m_strDataEditorRect; } set { if(value == null) throw new ArgumentNullException("value"); m_strDataEditorRect = value; } } private AceFont m_deFont = new AceFont(); public AceFont DataEditorFont { get { return m_deFont; } set { if(value == null) throw new ArgumentNullException("value"); m_deFont = value; } } private bool m_bDeWordWrap = true; [DefaultValue(true)] public bool DataEditorWordWrap { get { return m_bDeWordWrap; } set { m_bDeWordWrap = value; } } private string m_strCharPickerRect = string.Empty; [DefaultValue("")] public string CharPickerRect { get { return m_strCharPickerRect; } set { if(value == null) throw new ArgumentNullException("value"); m_strCharPickerRect = value; } } private string m_strAutoTypeCtxRect = string.Empty; [DefaultValue("")] public string AutoTypeCtxRect { get { return m_strAutoTypeCtxRect; } set { if(value == null) throw new ArgumentNullException("value"); m_strAutoTypeCtxRect = value; } } private long m_lAutoTypeCtxFlags = (long)AceAutoTypeCtxFlags.Default; [DefaultValue((long)AceAutoTypeCtxFlags.Default)] public long AutoTypeCtxFlags { get { return m_lAutoTypeCtxFlags; } set { m_lAutoTypeCtxFlags = value; } } private string m_strAutoTypeCtxColWidths = string.Empty; [DefaultValue("")] public string AutoTypeCtxColumnWidths { get { return m_strAutoTypeCtxColWidths; } set { if(value == null) throw new ArgumentNullException("value"); m_strAutoTypeCtxColWidths = value; } } private ulong m_uUIFlags = (ulong)AceUIFlags.None; public ulong UIFlags { get { return m_uUIFlags; } set { m_uUIFlags = value; } } private ulong m_uKeyCreationFlags = (ulong)AceKeyUIFlags.None; public ulong KeyCreationFlags { get { return m_uKeyCreationFlags; } set { m_uKeyCreationFlags = value; } } private ulong m_uKeyPromptFlags = (ulong)AceKeyUIFlags.None; public ulong KeyPromptFlags { get { return m_uKeyPromptFlags; } set { m_uKeyPromptFlags = value; } } // private bool m_bEditCancelConfirmation = true; // public bool EntryEditCancelConfirmation // { // get { return m_bEditCancelConfirmation; } // set { m_bEditCancelConfirmation = value; } // } private bool m_bAdvATCmds = false; [DefaultValue(false)] public bool ShowAdvAutoTypeCommands { get { return m_bAdvATCmds; } set { m_bAdvATCmds = value; } } private bool m_bSecDeskSound = true; [DefaultValue(true)] public bool SecureDesktopPlaySound { get { return m_bSecDeskSound; } set { m_bSecDeskSound = value; } } } public sealed class AceHiding { public AceHiding() { } private bool m_bSepHiding = false; [DefaultValue(false)] public bool SeparateHidingSettings { get { return m_bSepHiding; } set { m_bSepHiding = value; } } private bool m_bHideInEntryDialog = true; [DefaultValue(true)] public bool HideInEntryWindow { get { return m_bHideInEntryDialog; } set { m_bHideInEntryDialog = value; } } private bool m_bUnhideBtnAlsoUnhidesSec = false; [DefaultValue(false)] public bool UnhideButtonAlsoUnhidesSource { get { return m_bUnhideBtnAlsoUnhidesSec; } set { m_bUnhideBtnAlsoUnhidesSec = value; } } } public sealed class AceFont { private Font m_fCached = null; private bool m_bCacheValid = false; private string m_strFamily = "Microsoft Sans Serif"; public string Family { get { return m_strFamily; } set { if(value == null) throw new ArgumentNullException("value"); m_strFamily = value; m_bCacheValid = false; } } private float m_fSize = 8.25f; public float Size { get { return m_fSize; } set { m_fSize = value; m_bCacheValid = false; } } private GraphicsUnit m_gu = GraphicsUnit.Point; public GraphicsUnit GraphicsUnit { get { return m_gu; } set { m_gu = value; m_bCacheValid = false; } } private FontStyle m_fStyle = FontStyle.Regular; public FontStyle Style { get { return m_fStyle; } set { m_fStyle = value; m_bCacheValid = false; } } private bool m_bOverrideUIDefault = false; public bool OverrideUIDefault { get { return m_bOverrideUIDefault; } set { m_bOverrideUIDefault = value; } } public AceFont() { } public AceFont(Font f) { if(f == null) throw new ArgumentNullException("f"); this.Family = f.FontFamily.Name; m_fSize = f.Size; m_fStyle = f.Style; m_gu = f.Unit; } public AceFont(bool bMonospace) { if(bMonospace) m_strFamily = "Courier New"; } public Font ToFont() { if(m_bCacheValid) return m_fCached; m_fCached = FontUtil.CreateFont(m_strFamily, m_fSize, m_fStyle, m_gu); m_bCacheValid = true; return m_fCached; } } } KeePass/App/Configuration/AppConfigEx.cs0000664000000000000000000004024313224666720017145 0ustar rootroot/* KeePass Password Safe - The Open-Source Password Manager Copyright (C) 2003-2018 Dominik Reichl This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ using System; using System.Collections.Generic; using System.ComponentModel; using System.Diagnostics; using System.Drawing; using System.Reflection; using System.Text; using System.Windows.Forms; using System.Xml; using System.Xml.Serialization; using KeePass.UI; using KeePass.Util; using KeePass.Util.XmlSerialization; using KeePassLib.Delegates; using KeePassLib.Native; using KeePassLib.Serialization; using KeePassLib.Utility; namespace KeePass.App.Configuration { [XmlType(TypeName = "Configuration")] public sealed class AppConfigEx { public AppConfigEx() { } private AceMeta m_meta = null; public AceMeta Meta { get { if(m_meta == null) m_meta = new AceMeta(); return m_meta; } set { if(value == null) throw new ArgumentNullException("value"); m_meta = value; } } private AceApplication m_aceApp = null; public AceApplication Application { get { if(m_aceApp == null) m_aceApp = new AceApplication(); return m_aceApp; } set { if(value == null) throw new ArgumentNullException("value"); m_aceApp = value; } } private AceLogging m_aceLogging = null; public AceLogging Logging { get { if(m_aceLogging == null) m_aceLogging = new AceLogging(); return m_aceLogging; } set { if(value == null) throw new ArgumentNullException("value"); m_aceLogging = value; } } private AceMainWindow m_uiMainWindow = null; public AceMainWindow MainWindow { get { if(m_uiMainWindow == null) m_uiMainWindow = new AceMainWindow(); return m_uiMainWindow; } set { if(value == null) throw new ArgumentNullException("value"); m_uiMainWindow = value; } } private AceUI m_aceUI = null; public AceUI UI { get { if(m_aceUI == null) m_aceUI = new AceUI(); return m_aceUI; } set { if(value == null) throw new ArgumentNullException("value"); m_aceUI = value; } } private AceSecurity m_sec = null; public AceSecurity Security { get { if(m_sec == null) m_sec = new AceSecurity(); return m_sec; } set { if(value == null) throw new ArgumentNullException("value"); m_sec = value; } } private AceNative m_native = null; public AceNative Native { get { if(m_native == null) m_native = new AceNative(); return m_native; } set { if(value == null) throw new ArgumentNullException("value"); m_native = value; } } private AcePasswordGenerator m_pwGen = null; public AcePasswordGenerator PasswordGenerator { get { if(m_pwGen == null) m_pwGen = new AcePasswordGenerator(); return m_pwGen; } set { if(value == null) throw new ArgumentNullException("value"); m_pwGen = value; } } private AceDefaults m_def = null; public AceDefaults Defaults { get { if(m_def == null) m_def = new AceDefaults(); return m_def; } set { if(value == null) throw new ArgumentNullException("value"); m_def = value; } } private AceIntegration m_int = null; public AceIntegration Integration { get { if(m_int == null) m_int = new AceIntegration(); return m_int; } set { if(value == null) throw new ArgumentNullException("value"); m_int = value; } } private AceCustomConfig m_cc = null; [XmlIgnore] public AceCustomConfig CustomConfig { get { if(m_cc == null) m_cc = new AceCustomConfig(); return m_cc; } set { if(value == null) throw new ArgumentNullException("value"); m_cc = value; } } [XmlArray("Custom")] [XmlArrayItem("Item")] public AceKvp[] CustomSerialized { get { return this.CustomConfig.Serialize(); // m_cc might be null } set { if(value == null) throw new ArgumentNullException("value"); this.CustomConfig.Deserialize(value); // m_cc might be null } } /// /// Prepare for saving the configuration to disk. None of the /// modifications in this method need to be rolled back /// (for rollback, use OnSavePre / OnSavePost). /// private void PrepareSave() { AceMeta aceMeta = this.Meta; // m_meta might be null AceApplication aceApp = this.Application; // m_aceApp might be null AceDefaults aceDef = this.Defaults; // m_def might be null aceMeta.OmitItemsWithDefaultValues = true; aceMeta.DpiFactorX = DpiUtil.FactorX; // For new (not loaded) cfgs. aceMeta.DpiFactorY = DpiUtil.FactorY; aceApp.LastUsedFile.ClearCredentials(true); foreach(IOConnectionInfo iocMru in aceApp.MostRecentlyUsed.Items) iocMru.ClearCredentials(true); if(aceDef.RememberKeySources == false) aceDef.KeySources.Clear(); aceApp.TriggerSystem = Program.TriggerSystem; SearchUtil.PrepareForSerialize(aceDef.SearchParameters); } internal void OnLoad() { AceMainWindow aceMainWindow = this.MainWindow; // m_uiMainWindow might be null AceDefaults aceDef = this.Defaults; // m_def might be null // aceInt.UrlSchemeOverrides.SetDefaultsIfEmpty(); ObfuscateCred(false); ChangePathsRelAbs(true); // Remove invalid columns List vColumns = aceMainWindow.EntryListColumns; int i = 0; while(i < vColumns.Count) { if(((int)vColumns[i].Type < 0) || ((int)vColumns[i].Type >= (int)AceColumnType.Count)) vColumns.RemoveAt(i); else ++i; } SearchUtil.FinishDeserialize(aceDef.SearchParameters); DpiScale(); if(NativeLib.IsUnix()) { this.Security.MasterKeyOnSecureDesktop = false; AceIntegration aceInt = this.Integration; aceInt.HotKeyGlobalAutoType = (ulong)Keys.None; aceInt.HotKeySelectedAutoType = (ulong)Keys.None; aceInt.HotKeyShowWindow = (ulong)Keys.None; } if(MonoWorkarounds.IsRequired(1378)) { AceWorkspaceLocking aceWL = this.Security.WorkspaceLocking; aceWL.LockOnSessionSwitch = false; aceWL.LockOnSuspend = false; aceWL.LockOnRemoteControlChange = false; } if(MonoWorkarounds.IsRequired(1418)) { aceMainWindow.MinimizeAfterOpeningDatabase = false; this.Application.Start.MinimizedAndLocked = false; } } internal void OnSavePre() { PrepareSave(); ChangePathsRelAbs(false); ObfuscateCred(true); } internal void OnSavePost() { ObfuscateCred(false); ChangePathsRelAbs(true); } private void ChangePathsRelAbs(bool bMakeAbsolute) { AceApplication aceApp = this.Application; // m_aceApp might be null AceDefaults aceDef = this.Defaults; // m_def might be null ChangePathRelAbs(aceApp.LastUsedFile, bMakeAbsolute); foreach(IOConnectionInfo iocMru in aceApp.MostRecentlyUsed.Items) ChangePathRelAbs(iocMru, bMakeAbsolute); List lWDKeys = aceApp.GetWorkingDirectoryContexts(); foreach(string strWDKey in lWDKeys) aceApp.SetWorkingDirectory(strWDKey, ChangePathRelAbsStr( aceApp.GetWorkingDirectory(strWDKey), bMakeAbsolute)); foreach(AceKeyAssoc kfp in aceDef.KeySources) { kfp.DatabasePath = ChangePathRelAbsStr(kfp.DatabasePath, bMakeAbsolute); kfp.KeyFilePath = ChangePathRelAbsStr(kfp.KeyFilePath, bMakeAbsolute); } } private static void ChangePathRelAbs(IOConnectionInfo ioc, bool bMakeAbsolute) { if(ioc == null) { Debug.Assert(false); return; } if(!ioc.IsLocalFile()) return; // Update path separators for current system if(!UrlUtil.IsUncPath(ioc.Path)) ioc.Path = UrlUtil.ConvertSeparators(ioc.Path); string strBase = WinUtil.GetExecutable(); bool bIsAbs = UrlUtil.IsAbsolutePath(ioc.Path); if(bMakeAbsolute && !bIsAbs) ioc.Path = UrlUtil.MakeAbsolutePath(strBase, ioc.Path); else if(!bMakeAbsolute && bIsAbs) ioc.Path = UrlUtil.MakeRelativePath(strBase, ioc.Path); } private static string ChangePathRelAbsStr(string strPath, bool bMakeAbsolute) { if(strPath == null) { Debug.Assert(false); return string.Empty; } if(strPath.Length == 0) return strPath; IOConnectionInfo ioc = IOConnectionInfo.FromPath(strPath); ChangePathRelAbs(ioc, bMakeAbsolute); return ioc.Path; } private void ObfuscateCred(bool bObf) { AceApplication aceApp = this.Application; // m_aceApp might be null AceIntegration aceInt = this.Integration; // m_int might be null if(aceApp.LastUsedFile == null) { Debug.Assert(false); } else aceApp.LastUsedFile.Obfuscate(bObf); foreach(IOConnectionInfo iocMru in aceApp.MostRecentlyUsed.Items) { if(iocMru == null) { Debug.Assert(false); } else iocMru.Obfuscate(bObf); } if(bObf) aceInt.ProxyUserName = StrUtil.Obfuscate(aceInt.ProxyUserName); else aceInt.ProxyUserName = StrUtil.Deobfuscate(aceInt.ProxyUserName); if(bObf) aceInt.ProxyPassword = StrUtil.Obfuscate(aceInt.ProxyPassword); else aceInt.ProxyPassword = StrUtil.Deobfuscate(aceInt.ProxyPassword); } private void DpiScale() { AceMeta aceMeta = this.Meta; // m_meta might be null double dCfgX = aceMeta.DpiFactorX, dCfgY = aceMeta.DpiFactorY; double dScrX = DpiUtil.FactorX, dScrY = DpiUtil.FactorY; if((dScrX == dCfgX) && (dScrY == dCfgY)) return; // When this method returns, all positions and sizes are in pixels // for the current screen DPI aceMeta.DpiFactorX = dScrX; aceMeta.DpiFactorY = dScrY; // Backward compatibility; configuration files created by KeePass // 2.37 and earlier do not contain DpiFactor* values, they default // to 0.0 and all positions and sizes are in pixels for the current // screen DPI; so, do not perform any DPI scaling in this case if((dCfgX == 0.0) || (dCfgY == 0.0)) return; double sX = dScrX / dCfgX, sY = dScrY / dCfgY; GFunc fX = delegate(int x) { return (int)Math.Round((double)x * sX); }; GFunc fY = delegate(int y) { return (int)Math.Round((double)y * sY); }; GFunc fWsr = delegate(string strRect) { return UIUtil.ScaleWindowScreenRect(strRect, sX, sY); }; GFunc fVX = delegate(string strArray) { if(string.IsNullOrEmpty(strArray)) return strArray; try { int[] v = StrUtil.DeserializeIntArray(strArray); if(v == null) { Debug.Assert(false); return strArray; } for(int i = 0; i < v.Length; ++i) v[i] = (int)Math.Round((double)v[i] * sX); return StrUtil.SerializeIntArray(v); } catch(Exception) { Debug.Assert(false); } return strArray; }; GAction fFont = delegate(AceFont f) { if(f == null) { Debug.Assert(false); return; } if(f.GraphicsUnit == GraphicsUnit.Pixel) f.Size = (float)(f.Size * sY); }; AceMainWindow mw = this.MainWindow; AceUI ui = this.UI; if(mw.X != AppDefs.InvalidWindowValue) mw.X = fX(mw.X); if(mw.Y != AppDefs.InvalidWindowValue) mw.Y = fY(mw.Y); if(mw.Width != AppDefs.InvalidWindowValue) mw.Width = fX(mw.Width); if(mw.Height != AppDefs.InvalidWindowValue) mw.Height = fY(mw.Height); foreach(AceColumn c in mw.EntryListColumns) { if(c.Width >= 0) c.Width = fX(c.Width); } ui.DataViewerRect = fWsr(ui.DataViewerRect); ui.DataEditorRect = fWsr(ui.DataEditorRect); ui.CharPickerRect = fWsr(ui.CharPickerRect); ui.AutoTypeCtxRect = fWsr(ui.AutoTypeCtxRect); ui.AutoTypeCtxColumnWidths = fVX(ui.AutoTypeCtxColumnWidths); fFont(ui.StandardFont); fFont(ui.PasswordFont); fFont(ui.DataEditorFont); } private static Dictionary m_dictXmlPathCache = new Dictionary(); public static bool IsOptionEnforced(object pContainer, PropertyInfo pi) { if(pContainer == null) { Debug.Assert(false); return false; } if(pi == null) { Debug.Assert(false); return false; } XmlDocument xdEnforced = AppConfigSerializer.EnforcedConfigXml; if(xdEnforced == null) return false; string strObjPath; if(!m_dictXmlPathCache.TryGetValue(pContainer, out strObjPath)) { strObjPath = XmlUtil.GetObjectXmlPath(Program.Config, pContainer); if(string.IsNullOrEmpty(strObjPath)) { Debug.Assert(false); return false; } m_dictXmlPathCache[pContainer] = strObjPath; } string strProp = XmlSerializerEx.GetXmlName(pi); if(string.IsNullOrEmpty(strProp)) { Debug.Assert(false); return false; } string strPre = strObjPath; if(!strPre.EndsWith("/")) strPre += "/"; string strXPath = strPre + strProp; XmlNode xn = xdEnforced.SelectSingleNode(strXPath); return (xn != null); } public static bool IsOptionEnforced(object pContainer, string strPropertyName) { if(pContainer == null) { Debug.Assert(false); return false; } if(string.IsNullOrEmpty(strPropertyName)) { Debug.Assert(false); return false; } // To improve performance (avoid type queries), check here, too XmlDocument xdEnforced = AppConfigSerializer.EnforcedConfigXml; if(xdEnforced == null) return false; Type tContainer = pContainer.GetType(); PropertyInfo pi = tContainer.GetProperty(strPropertyName); return IsOptionEnforced(pContainer, pi); } public static void ClearXmlPathCache() { m_dictXmlPathCache.Clear(); } public void Apply(AceApplyFlags f) { AceApplication aceApp = this.Application; // m_aceApp might be null AceSecurity aceSec = this.Security; // m_sec might be null AceIntegration aceInt = this.Integration; // m_int might be null if((f & AceApplyFlags.Proxy) != AceApplyFlags.None) IOConnection.SetProxy(aceInt.ProxyType, aceInt.ProxyAddress, aceInt.ProxyPort, aceInt.ProxyAuthType, aceInt.ProxyUserName, aceInt.ProxyPassword); if((f & AceApplyFlags.Ssl) != AceApplyFlags.None) IOConnection.SslCertsAcceptInvalid = aceSec.SslCertsAcceptInvalid; if((f & AceApplyFlags.FileTransactions) != AceApplyFlags.None) FileTransactionEx.ExtraSafe = aceApp.FileTxExtra; } } [Flags] public enum AceApplyFlags { None = 0, Proxy = 0x1, Ssl = 0x2, FileTransactions = 0x4, All = 0x7FFF } public sealed class AceMeta { public AceMeta() { } private bool m_bPrefLocalCfg = false; public bool PreferUserConfiguration { get { return m_bPrefLocalCfg; } set { m_bPrefLocalCfg = value; } } // private bool m_bIsEnforced = false; // [XmlIgnore] // public bool IsEnforcedConfiguration // { // get { return m_bIsEnforced; } // set { m_bIsEnforced = value; } // } private bool m_bOmitDefaultValues = true; // Informational property only (like an XML comment); // currently doesn't have any effect (the XmlSerializer // always omits default values, independent of this // property) public bool OmitItemsWithDefaultValues { get { return m_bOmitDefaultValues; } set { m_bOmitDefaultValues = value; } } private double m_dDpiFactorX = 0.0; // See AppConfigEx.DpiScale() [DefaultValue(0.0)] public double DpiFactorX { get { return m_dDpiFactorX; } set { m_dDpiFactorX = value; } } private double m_dDpiFactorY = 0.0; // See AppConfigEx.DpiScale() [DefaultValue(0.0)] public double DpiFactorY { get { return m_dDpiFactorY; } set { m_dDpiFactorY = value; } } } } KeePass/App/Configuration/AceSecurity.cs0000664000000000000000000001351213222430402017201 0ustar rootroot/* KeePass Password Safe - The Open-Source Password Manager Copyright (C) 2003-2018 Dominik Reichl This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ using System; using System.Collections.Generic; using System.Text; using System.ComponentModel; namespace KeePass.App.Configuration { public sealed class AceSecurity { public AceSecurity() { } private AceWorkspaceLocking m_wsl = new AceWorkspaceLocking(); public AceWorkspaceLocking WorkspaceLocking { get { return m_wsl; } set { if(value == null) throw new ArgumentNullException("value"); m_wsl = value; } } private AppPolicyFlags m_appPolicy = new AppPolicyFlags(); public AppPolicyFlags Policy { get { return m_appPolicy; } set { if(value == null) throw new ArgumentNullException("value"); m_appPolicy = value; } } private AceMasterPassword m_mp = new AceMasterPassword(); public AceMasterPassword MasterPassword { get { return m_mp; } set { if(value == null) throw new ArgumentNullException("value"); m_mp = value; } } private int m_nMasterKeyTries = 3; [DefaultValue(3)] public int MasterKeyTries { get { return m_nMasterKeyTries; } set { m_nMasterKeyTries = value; } } private bool m_bSecureDesktop = false; [DefaultValue(false)] public bool MasterKeyOnSecureDesktop { get { return m_bSecureDesktop; } set { m_bSecureDesktop = value; } } private string m_strMasterKeyExpiryRec = string.Empty; [DefaultValue("")] public string MasterKeyExpiryRec { get { return m_strMasterKeyExpiryRec; } set { if(value == null) throw new ArgumentNullException("value"); m_strMasterKeyExpiryRec = value; } } private bool m_bClipClearOnExit = true; [DefaultValue(true)] public bool ClipboardClearOnExit { get { return m_bClipClearOnExit; } set { m_bClipClearOnExit = value; } } private int m_nClipClearSeconds = 12; [DefaultValue(12)] public int ClipboardClearAfterSeconds { get { return m_nClipClearSeconds; } set { m_nClipClearSeconds = value; } } // Disabled by default, because Office's clipboard tools // crash with the Clipboard Viewer Ignore format // (when it is set using OleSetClipboard) private bool m_bUseClipboardViewerIgnoreFmt = false; [DefaultValue(false)] public bool UseClipboardViewerIgnoreFormat { get { return m_bUseClipboardViewerIgnoreFmt; } set { m_bUseClipboardViewerIgnoreFmt = value; } } private bool m_bClearKeyCmdLineOpt = true; [DefaultValue(true)] public bool ClearKeyCommandLineParams { get { return m_bClearKeyCmdLineOpt; } set { m_bClearKeyCmdLineOpt = value; } } private bool m_bSslCertsAcceptInvalid = false; [DefaultValue(false)] public bool SslCertsAcceptInvalid { get { return m_bSslCertsAcceptInvalid; } set { m_bSslCertsAcceptInvalid = value; } } } public sealed class AceWorkspaceLocking { public AceWorkspaceLocking() { } private bool m_bOnMinimize = false; [DefaultValue(false)] public bool LockOnWindowMinimize { get { return m_bOnMinimize; } set { m_bOnMinimize = value; } } private bool m_bOnMinimizeToTray = false; [DefaultValue(false)] public bool LockOnWindowMinimizeToTray { get { return m_bOnMinimizeToTray; } set { m_bOnMinimizeToTray = value; } } private bool m_bOnSessionSwitch = false; [DefaultValue(false)] public bool LockOnSessionSwitch { get { return m_bOnSessionSwitch; } set { m_bOnSessionSwitch = value; } } private bool m_bOnSuspend = false; [DefaultValue(false)] public bool LockOnSuspend { get { return m_bOnSuspend; } set { m_bOnSuspend = value; } } private bool m_bOnRemoteControlChange = false; [DefaultValue(false)] public bool LockOnRemoteControlChange { get { return m_bOnRemoteControlChange; } set { m_bOnRemoteControlChange = value; } } private uint m_uLockAfterTime = 0; public uint LockAfterTime { get { return m_uLockAfterTime; } set { m_uLockAfterTime = value; } } private uint m_uLockAfterGlobalTime = 0; public uint LockAfterGlobalTime { get { return m_uLockAfterGlobalTime; } set { m_uLockAfterGlobalTime = value; } } private bool m_bExitInsteadOfLockingAfterTime = false; [DefaultValue(false)] public bool ExitInsteadOfLockingAfterTime { get { return m_bExitInsteadOfLockingAfterTime; } set { m_bExitInsteadOfLockingAfterTime = value; } } private bool m_bAlwaysExitInsteadOfLocking = false; [DefaultValue(false)] public bool AlwaysExitInsteadOfLocking { get { return m_bAlwaysExitInsteadOfLocking; } set { m_bAlwaysExitInsteadOfLocking = value; } } } public sealed class AceMasterPassword { public AceMasterPassword() { } private uint m_uMinLength = 0; public uint MinimumLength { get { return m_uMinLength; } set { m_uMinLength = value; } } private uint m_uMinQuality = 0; public uint MinimumQuality { get { return m_uMinQuality; } set { m_uMinQuality = value; } } } } KeePass/App/Configuration/AceTrayIcon.cs0000664000000000000000000000313113222430404017120 0ustar rootroot/* KeePass Password Safe - The Open-Source Password Manager Copyright (C) 2003-2018 Dominik Reichl This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ using System; using System.Collections.Generic; using System.Text; using System.ComponentModel; namespace KeePass.App.Configuration { public sealed class AceTrayIcon { public AceTrayIcon() { } private bool m_bOnlyIfTrayed = false; [DefaultValue(false)] public bool ShowOnlyIfTrayed { get { return m_bOnlyIfTrayed; } set { m_bOnlyIfTrayed = value; } } private bool m_bGrayIcon = false; [DefaultValue(false)] public bool GrayIcon { get { return m_bGrayIcon; } set { m_bGrayIcon = value; } } private bool m_bSingleClickDefault = false; [DefaultValue(false)] public bool SingleClickDefault { get { return m_bSingleClickDefault; } set { m_bSingleClickDefault = value; } } } } KeePass/App/Configuration/AceApplication.cs0000664000000000000000000002652713222430402017647 0ustar rootroot/* KeePass Password Safe - The Open-Source Password Manager Copyright (C) 2003-2018 Dominik Reichl This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ using System; using System.Collections.Generic; using System.ComponentModel; using System.Diagnostics; using System.Text; using System.Xml.Serialization; using KeePass.Ecas; using KeePass.Util; using KeePassLib.Serialization; using KeePassLib.Utility; namespace KeePass.App.Configuration { public sealed class AceApplication { public AceApplication() { } private string m_strLanguageFile = string.Empty; // = English [DefaultValue("")] public string LanguageFile { get { return m_strLanguageFile; } set { if(value == null) throw new ArgumentNullException("value"); m_strLanguageFile = value; } } private bool m_bHelpUseLocal = false; [DefaultValue(false)] public bool HelpUseLocal { get { return m_bHelpUseLocal; } set { m_bHelpUseLocal = value; } } // Serialize DateTime with TimeUtil private string m_strLastUpdChk = string.Empty; [DefaultValue("")] public string LastUpdateCheck { get { return m_strLastUpdChk; } set { if(value == null) throw new ArgumentNullException("value"); m_strLastUpdChk = value; } } private IOConnectionInfo m_ioLastDb = null; public IOConnectionInfo LastUsedFile { get { if(m_ioLastDb == null) m_ioLastDb = new IOConnectionInfo(); return m_ioLastDb; } set { if(value == null) throw new ArgumentNullException("value"); m_ioLastDb = value; } } private AceMru m_mru = null; public AceMru MostRecentlyUsed { get { if(m_mru == null) m_mru = new AceMru(); return m_mru; } set { if(value == null) throw new ArgumentNullException("value"); m_mru = value; } } private bool m_bRememberWorkDirs = true; [DefaultValue(true)] public bool RememberWorkingDirectories { get { return m_bRememberWorkDirs; } set { m_bRememberWorkDirs = value; } } private Dictionary m_dictWorkingDirs = new Dictionary(); /// /// For serialization only; use the *WorkingDirectory /// methods instead. /// [XmlArray("WorkingDirectories")] [XmlArrayItem("Item")] public string[] WorkingDirectoriesSerialized { get { return SerializeWorkingDirectories(); } set { if(value == null) throw new ArgumentNullException("value"); DeserializeWorkingDirectories(value); } } private AceStartUp m_su = null; public AceStartUp Start { get { if(m_su == null) m_su = new AceStartUp(); return m_su; } set { if(value == null) throw new ArgumentNullException("value"); m_su = value; } } private AceOpenDb m_fo = null; public AceOpenDb FileOpening { get { if(m_fo == null) m_fo = new AceOpenDb(); return m_fo; } set { if(value == null) throw new ArgumentNullException("value"); m_fo = value; } } private bool m_bVerifyFile = true; [DefaultValue(true)] public bool VerifyWrittenFileAfterSaving { get { return m_bVerifyFile; } set { m_bVerifyFile = value; } } private bool m_bTransactedWrites = true; [DefaultValue(true)] public bool UseTransactedFileWrites { get { return m_bTransactedWrites; } set { m_bTransactedWrites = value; } } private bool m_bFileTxExtra = false; [DefaultValue(false)] public bool FileTxExtra { get { return m_bFileTxExtra; } set { m_bFileTxExtra = value; } } private bool m_bFileLocks = false; [DefaultValue(false)] public bool UseFileLocks { get { return m_bFileLocks; } set { m_bFileLocks = value; } } private bool m_bSaveForceSync = false; [DefaultValue(false)] public bool SaveForceSync { get { return m_bSaveForceSync; } set { m_bSaveForceSync = value; } } private AceCloseDb m_fc = new AceCloseDb(); public AceCloseDb FileClosing { get { return m_fc; } set { if(value == null) throw new ArgumentNullException("value"); m_fc = value; } } private EcasTriggerSystem m_triggers = new EcasTriggerSystem(); public EcasTriggerSystem TriggerSystem { get { return m_triggers; } set { if(value == null) throw new ArgumentNullException("value"); m_triggers = value; } } private string m_strPluginCachePath = string.Empty; [DefaultValue("")] public string PluginCachePath { get { return m_strPluginCachePath; } set { if(value == null) throw new ArgumentNullException("value"); m_strPluginCachePath = value; } } private int m_iExpirySoonDays = 7; [DefaultValue(7)] public int ExpirySoonDays { get { return m_iExpirySoonDays; } set { m_iExpirySoonDays = value; } } internal static string GetLanguagesDir(AceDir d, bool bTermSep) { string str; if(d == AceDir.App) str = UrlUtil.GetFileDirectory(WinUtil.GetExecutable(), true, false) + AppDefs.LanguagesDir; else if(d == AceDir.User) str = UrlUtil.EnsureTerminatingSeparator( AppConfigSerializer.AppDataDirectory, false) + AppDefs.LanguagesDir; else { Debug.Assert(false); return string.Empty; } if(bTermSep) str = UrlUtil.EnsureTerminatingSeparator(str, false); return str; } private const string LngPrefixUser = "UL::"; internal string GetLanguageFilePath() { string str = m_strLanguageFile; if(str.Length == 0) return string.Empty; string strDir, strName; if(str.StartsWith(LngPrefixUser, StrUtil.CaseIgnoreCmp)) { strDir = GetLanguagesDir(AceDir.User, true); strName = str.Substring(LngPrefixUser.Length); } else { strDir = GetLanguagesDir(AceDir.App, true); strName = str; } // File name must not contain a directory separator // (language files must be directly in the directory, // not any subdirectory of it or somewhere else) if(UrlUtil.GetFileName(strName) != strName) { Debug.Assert(false); return string.Empty; } return (strDir + strName); } internal void SetLanguageFilePath(string strPath) { m_strLanguageFile = string.Empty; if(string.IsNullOrEmpty(strPath)) return; string str = GetLanguagesDir(AceDir.App, true); if(strPath.StartsWith(str, StrUtil.CaseIgnoreCmp)) { m_strLanguageFile = strPath.Substring(str.Length); return; } str = GetLanguagesDir(AceDir.User, true); if(strPath.StartsWith(str, StrUtil.CaseIgnoreCmp)) { m_strLanguageFile = LngPrefixUser + strPath.Substring(str.Length); return; } Debug.Assert(false); } public string GetWorkingDirectory(string strContext) { // strContext may be null if(!m_bRememberWorkDirs) return null; string str; m_dictWorkingDirs.TryGetValue(strContext ?? string.Empty, out str); return str; } public void SetWorkingDirectory(string strContext, string strDir) { // Both parameters may be null // if(!m_bRememberWorkDirs) return; if(string.IsNullOrEmpty(strContext)) return; m_dictWorkingDirs[strContext] = (strDir ?? string.Empty); } internal List GetWorkingDirectoryContexts() { if(!m_bRememberWorkDirs) return new List(); return new List(m_dictWorkingDirs.Keys); } private string[] SerializeWorkingDirectories() { if(!m_bRememberWorkDirs) return new string[0]; List l = new List(); foreach(KeyValuePair kvp in m_dictWorkingDirs) l.Add(kvp.Key + @"@" + kvp.Value); return l.ToArray(); } private void DeserializeWorkingDirectories(string[] v) { // Do not check m_bRememberWorkDirs, because it might not // have been deserialized yet m_dictWorkingDirs.Clear(); foreach(string str in v) { if(str == null) { Debug.Assert(false); continue; } int iSep = str.IndexOf('@'); if(iSep <= 0) { Debug.Assert(false); continue; } m_dictWorkingDirs[str.Substring(0, iSep)] = str.Substring(iSep + 1); } } } internal enum AceDir { App = 0, User } public sealed class AceStartUp { public AceStartUp() { } private bool m_bOpenLastDb = true; [DefaultValue(true)] public bool OpenLastFile { get { return m_bOpenLastDb; } set { m_bOpenLastDb = value; } } private bool m_bCheckForUpdate = false; // [DefaultValue(false)] // Avoid user confusion with 'Configured' setting public bool CheckForUpdate { get { return m_bCheckForUpdate; } set { m_bCheckForUpdate = value; } } private bool m_bCheckForUpdateCfg = false; [DefaultValue(false)] public bool CheckForUpdateConfigured { get { return m_bCheckForUpdateCfg; } set { m_bCheckForUpdateCfg = value; } } private bool m_bMinimizedAndLocked = false; [DefaultValue(false)] public bool MinimizedAndLocked { get { return m_bMinimizedAndLocked; } set { m_bMinimizedAndLocked = value; } } private bool m_bPlgDeleteOld = true; [DefaultValue(true)] public bool PluginCacheDeleteOld { get { return m_bPlgDeleteOld; } set { m_bPlgDeleteOld = value; } } private bool m_bClearPlgCache = false; [DefaultValue(false)] public bool PluginCacheClearOnce { get { return m_bClearPlgCache; } set { m_bClearPlgCache = value; } } } public sealed class AceOpenDb { public AceOpenDb() { } private bool m_bShowExpiredEntries = false; [DefaultValue(false)] public bool ShowExpiredEntries { get { return m_bShowExpiredEntries; } set { m_bShowExpiredEntries = value; } } private bool m_bShowSoonToExpireEntries = false; [DefaultValue(false)] public bool ShowSoonToExpireEntries { get { return m_bShowSoonToExpireEntries; } set { m_bShowSoonToExpireEntries = value; } } } public sealed class AceCloseDb { public AceCloseDb() { } private bool m_bAutoSave = false; [DefaultValue(false)] public bool AutoSave { get { return m_bAutoSave; } set { m_bAutoSave = value; } } } public sealed class AceMru { public const uint DefaultMaxItemCount = 12; public AceMru() { } private uint m_uMaxItems = DefaultMaxItemCount; public uint MaxItemCount { get { return m_uMaxItems; } set { m_uMaxItems = value; } } private List m_vItems = new List(); [XmlArrayItem("ConnectionInfo")] public List Items { get { return m_vItems; } set { m_vItems = value; } } } } KeePass/App/Configuration/AceCustomConfig.cs0000664000000000000000000001405413222430402017774 0ustar rootroot/* KeePass Password Safe - The Open-Source Password Manager Copyright (C) 2003-2018 Dominik Reichl This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ using System; using System.Collections.Generic; using System.Text; using System.Xml.Serialization; using System.Globalization; using KeePassLib.Utility; namespace KeePass.App.Configuration { public sealed class AceKvp { private string m_strKey = null; public string Key { get { return m_strKey; } set { m_strKey = value; } } private string m_strValue = null; public string Value { get { return m_strValue; } set { m_strValue = value; } } public AceKvp() { } public AceKvp(string strKey, string strValue) { m_strKey = strKey; m_strValue = strValue; } } public sealed class AceCustomConfig { private Dictionary m_vItems = new Dictionary(); public AceCustomConfig() { } internal AceKvp[] Serialize() { List v = new List(); foreach(KeyValuePair kvp in m_vItems) v.Add(new AceKvp(kvp.Key, kvp.Value)); return v.ToArray(); } internal void Deserialize(AceKvp[] v) { if(v == null) throw new ArgumentNullException("v"); m_vItems.Clear(); foreach(AceKvp kvp in v) m_vItems[kvp.Key] = kvp.Value; } /// /// Set a configuration item's value. /// /// ID of the configuration item. This identifier /// should consist only of English characters (a-z, A-Z, 0-9, '.', /// ',', '-', '_') and should be unique -- for example (without quotes): /// "PluginName.YourConfigGroupName.ItemName". Use upper camel /// case as naming convention. /// New value of the configuration item. public void SetString(string strID, string strValue) { if(strID == null) throw new ArgumentNullException("strID"); if(strID.Length == 0) throw new ArgumentException(); if(strValue == null) m_vItems.Remove(strID); else m_vItems[strID] = strValue; } /// /// Set a configuration item's value. /// /// ID of the configuration item. This identifier /// should consist only of English characters (a-z, A-Z, 0-9, '.', /// ',', '-', '_') and should be unique -- for example (without quotes): /// "PluginName.YourConfigGroupName.ItemName". Use upper camel /// case as naming convention. /// New value of the configuration item. public void SetBool(string strID, bool bValue) { SetString(strID, StrUtil.BoolToString(bValue)); } /// /// Set a configuration item's value. /// /// ID of the configuration item. This identifier /// should consist only of English characters (a-z, A-Z, 0-9, '.', /// ',', '-', '_') and should be unique -- for example (without quotes): /// "PluginName.YourConfigGroupName.ItemName". Use upper camel /// case as naming convention. /// New value of the configuration item. public void SetLong(string strID, long lValue) { SetString(strID, lValue.ToString(NumberFormatInfo.InvariantInfo)); } /// /// Set a configuration item's value. /// /// ID of the configuration item. This identifier /// should consist only of English characters (a-z, A-Z, 0-9, '.', /// ',', '-', '_') and should be unique -- for example (without quotes): /// "PluginName.YourConfigGroupName.ItemName". Use upper camel /// case as naming convention. /// New value of the configuration item. public void SetULong(string strID, ulong uValue) { SetString(strID, uValue.ToString(NumberFormatInfo.InvariantInfo)); } public string GetString(string strID) { return GetString(strID, null); } /// /// Get the current value of a custom configuration string. /// /// ID of the configuration item. /// Default value that is returned if /// the specified configuration does not exist. /// Value of the configuration item. public string GetString(string strID, string strDefault) { if(strID == null) throw new ArgumentNullException("strID"); if(strID.Length == 0) throw new ArgumentException(); string strValue; if(m_vItems.TryGetValue(strID, out strValue)) return strValue; return strDefault; } public bool GetBool(string strID, bool bDefault) { string strValue = GetString(strID, null); if(string.IsNullOrEmpty(strValue)) return bDefault; return StrUtil.StringToBool(strValue); } public long GetLong(string strID, long lDefault) { string strValue = GetString(strID, null); if(string.IsNullOrEmpty(strValue)) return lDefault; long lValue; if(StrUtil.TryParseLongInvariant(strValue, out lValue)) return lValue; return lDefault; } public ulong GetULong(string strID, ulong uDefault) { string strValue = GetString(strID, null); if(string.IsNullOrEmpty(strValue)) return uDefault; ulong uValue; if(StrUtil.TryParseULongInvariant(strValue, out uValue)) return uValue; return uDefault; } } } KeePass/App/Configuration/AceNative.cs0000664000000000000000000000236313222430402016622 0ustar rootroot/* KeePass Password Safe - The Open-Source Password Manager Copyright (C) 2003-2018 Dominik Reichl This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ using System; using System.Collections.Generic; using System.Text; using System.ComponentModel; namespace KeePass.App.Configuration { public sealed class AceNative { public AceNative() { } private bool m_bNativeKeyTrans = true; [DefaultValue(true)] public bool NativeKeyTransformations { get { return m_bNativeKeyTrans; } set { m_bNativeKeyTrans = value; } } } } KeePass/App/Configuration/AceDefaults.cs0000664000000000000000000001741513222430402017147 0ustar rootroot/* KeePass Password Safe - The Open-Source Password Manager Copyright (C) 2003-2018 Dominik Reichl This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ using System; using System.Collections.Generic; using System.Text; using System.Xml.Serialization; using System.ComponentModel; using KeePass.Util; using KeePassLib; using KeePassLib.Keys; using KeePassLib.Serialization; using KeePassLib.Utility; namespace KeePass.App.Configuration { public sealed class AceKeyAssoc { private string m_strDb = string.Empty; public string DatabasePath { get { return m_strDb; } set { if(value == null) throw new ArgumentNullException("value"); m_strDb = value; } } private bool m_bPassword = false; [DefaultValue(false)] public bool Password { get { return m_bPassword; } set { m_bPassword = value; } } private string m_strKey = string.Empty; [DefaultValue("")] public string KeyFilePath { get { return m_strKey; } set { if(value == null) throw new ArgumentNullException("value"); m_strKey = value; } } private string m_strProv = string.Empty; [DefaultValue("")] public string KeyProvider { get { return m_strProv; } set { if(value == null) throw new ArgumentNullException("value"); m_strProv = value; } } private bool m_bUserAcc = false; [DefaultValue(false)] public bool UserAccount { get { return m_bUserAcc; } set { m_bUserAcc = value; } } public AceKeyAssoc() { } } public sealed class AceDefaults { public AceDefaults() { } private int m_nNewEntryExpireDays = -1; [DefaultValue(-1)] public int NewEntryExpiresInDays { get { return m_nNewEntryExpireDays; } set { m_nNewEntryExpireDays = value; } } private uint m_uDefaultOptionsTab = 0; public uint OptionsTabIndex { get { return m_uDefaultOptionsTab; } set { m_uDefaultOptionsTab = value; } } private const string DefaultTanChars = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789-"; private string m_strTanChars = DefaultTanChars; [DefaultValue(DefaultTanChars)] public string TanCharacters { get { return m_strTanChars; } set { if(value == null) throw new ArgumentNullException("value"); m_strTanChars = value; } } private bool m_bExpireTansOnUse = true; [DefaultValue(true)] public bool TanExpiresOnUse { get { return m_bExpireTansOnUse; } set { m_bExpireTansOnUse = value; } } private SearchParameters m_searchParams = new SearchParameters(); public SearchParameters SearchParameters { get { return m_searchParams; } set { if(value == null) throw new ArgumentNullException("value"); m_searchParams = value; } } private string m_strDbSaveAsPath = string.Empty; [DefaultValue("")] public string FileSaveAsDirectory { get { return m_strDbSaveAsPath; } set { if(value == null) throw new ArgumentNullException("value"); m_strDbSaveAsPath = value; } } private bool m_bRememberKeySources = true; [DefaultValue(true)] public bool RememberKeySources { get { return m_bRememberKeySources; } set { m_bRememberKeySources = value; } } private List m_vKeySources = new List(); [XmlArrayItem("Association")] public List KeySources { get { return m_vKeySources; } set { if(value == null) throw new ArgumentNullException("value"); m_vKeySources = value; } } private string m_strCustomColors = string.Empty; [DefaultValue("")] public string CustomColors { get { return m_strCustomColors; } set { if(value == null) throw new ArgumentNullException("value"); m_strCustomColors = value; } } private string m_strWinFavsBaseName = string.Empty; [DefaultValue("")] public string WinFavsBaseFolderName { get { return m_strWinFavsBaseName; } set { if(value == null) throw new ArgumentNullException("value"); m_strWinFavsBaseName = value; } } private string m_strWinFavsFilePrefix = string.Empty; [DefaultValue("")] public string WinFavsFileNamePrefix { get { return m_strWinFavsFilePrefix; } set { if(value == null) throw new ArgumentNullException("value"); m_strWinFavsFilePrefix = value; } } private string m_strWinFavsFileSuffix = string.Empty; [DefaultValue("")] public string WinFavsFileNameSuffix { get { return m_strWinFavsFileSuffix; } set { if(value == null) throw new ArgumentNullException("value"); m_strWinFavsFileSuffix = value; } } private bool m_bCollapseRecycleBin = false; [DefaultValue(false)] public bool RecycleBinCollapse { get { return m_bCollapseRecycleBin; } set { m_bCollapseRecycleBin = value; } } private static string GetKeyAssocID(IOConnectionInfo iocDb) { if(iocDb == null) throw new ArgumentNullException("iocDb"); string strDb = iocDb.Path; if((strDb.Length > 0) && iocDb.IsLocalFile() && !UrlUtil.IsAbsolutePath(strDb)) strDb = UrlUtil.MakeAbsolutePath(WinUtil.GetExecutable(), strDb); return strDb; } private int GetKeyAssocIndex(string strID) { for(int i = 0; i < m_vKeySources.Count; ++i) { if(strID.Equals(m_vKeySources[i].DatabasePath, StrUtil.CaseIgnoreCmp)) return i; } return -1; } public void SetKeySources(IOConnectionInfo iocDb, CompositeKey cmpKey) { string strID = GetKeyAssocID(iocDb); int idx = GetKeyAssocIndex(strID); if((cmpKey == null) || !m_bRememberKeySources) { if(idx >= 0) m_vKeySources.RemoveAt(idx); return; } AceKeyAssoc a = new AceKeyAssoc(); a.DatabasePath = strID; IUserKey kcpPassword = cmpKey.GetUserKey(typeof(KcpPassword)); a.Password = (kcpPassword != null); IUserKey kcpFile = cmpKey.GetUserKey(typeof(KcpKeyFile)); if(kcpFile != null) { string strKeyFile = ((KcpKeyFile)kcpFile).Path; if(!string.IsNullOrEmpty(strKeyFile) && !StrUtil.IsDataUri(strKeyFile)) { if(!UrlUtil.IsAbsolutePath(strKeyFile)) strKeyFile = UrlUtil.MakeAbsolutePath(WinUtil.GetExecutable(), strKeyFile); a.KeyFilePath = strKeyFile; } } IUserKey kcpCustom = cmpKey.GetUserKey(typeof(KcpCustomKey)); if(kcpCustom != null) a.KeyProvider = ((KcpCustomKey)kcpCustom).Name; IUserKey kcpUser = cmpKey.GetUserKey(typeof(KcpUserAccount)); a.UserAccount = (kcpUser != null); bool bAtLeastOne = (a.Password || (a.KeyFilePath.Length > 0) || (a.KeyProvider.Length > 0) || a.UserAccount); if(bAtLeastOne) { if(idx >= 0) m_vKeySources[idx] = a; else m_vKeySources.Add(a); } else if(idx >= 0) m_vKeySources.RemoveAt(idx); } public AceKeyAssoc GetKeySources(IOConnectionInfo iocDb) { string strID = GetKeyAssocID(iocDb); int idx = GetKeyAssocIndex(strID); if(!m_bRememberKeySources) return null; if(idx >= 0) return m_vKeySources[idx]; return null; } } } KeePass/App/Configuration/AppConfigSerializer.cs0000664000000000000000000002611513224146256020701 0ustar rootroot/* KeePass Password Safe - The Open-Source Password Manager Copyright (C) 2003-2018 Dominik Reichl This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ using System; using System.Collections.Generic; using System.Diagnostics; using System.IO; using System.Reflection; using System.Text; using System.Xml; using KeePass.Resources; using KeePass.Util; using KeePass.Util.XmlSerialization; using KeePassLib; using KeePassLib.Serialization; using KeePassLib.Utility; namespace KeePass.App.Configuration { public static class AppConfigSerializer { private static string m_strBaseName = null; // Null prop allowed private static string m_strCreateDir = null; private static string m_strCreateDirLocal = null; private static string m_strEnforcedConfigFile = null; private static string m_strGlobalConfigFile = null; private static string m_strUserConfigFile = null; public static string AppDataDirectory { get { AppConfigSerializer.GetConfigPaths(); return m_strCreateDir; } } public static string LocalAppDataDirectory { get { AppConfigSerializer.GetConfigPaths(); return m_strCreateDirLocal; } } /// /// Get/set the base name for the configuration. If this property is /// null, the class constructs names based on the current /// assembly and the product name. /// public static string BaseName { get { return m_strBaseName; } set { m_strBaseName = value; m_strCreateDir = null; m_strCreateDirLocal = null; m_strEnforcedConfigFile = null; // Invalidate paths m_strGlobalConfigFile = null; m_strUserConfigFile = null; } } private static XmlDocument m_xdEnforced = null; public static XmlDocument EnforcedConfigXml { get { return m_xdEnforced; } } private static void GetConfigPaths() { if(m_strGlobalConfigFile == null) { Assembly asm = Assembly.GetExecutingAssembly(); Debug.Assert(asm != null); if(asm == null) return; #if !KeePassLibSD string strFile = null; try { strFile = asm.Location; } catch(Exception) { } if(string.IsNullOrEmpty(strFile)) strFile = UrlUtil.FileUrlToPath(asm.GetName().CodeBase); #else string strFile = UrlUtil.FileUrlToPath(asm.GetName().CodeBase); #endif Debug.Assert(strFile != null); if(strFile == null) return; if(string.IsNullOrEmpty(m_strBaseName)) { // Remove assembly extension if(strFile.EndsWith(".exe", StrUtil.CaseIgnoreCmp)) strFile = strFile.Substring(0, strFile.Length - 4); else if(strFile.EndsWith(".dll", StrUtil.CaseIgnoreCmp)) strFile = strFile.Substring(0, strFile.Length - 4); } else // Base name != null strFile = UrlUtil.GetFileDirectory(strFile, true, false) + m_strBaseName; m_strGlobalConfigFile = strFile + ".config.xml"; m_strEnforcedConfigFile = strFile + ".config.enforced.xml"; } if(m_strUserConfigFile == null) { string strBaseDirName = PwDefs.ShortProductName; if((m_strBaseName != null) && (m_strBaseName.Length > 0)) strBaseDirName = m_strBaseName; string strUserDir; try { strUserDir = Environment.GetFolderPath( Environment.SpecialFolder.ApplicationData); } catch(Exception) { strUserDir = UrlUtil.GetFileDirectory(UrlUtil.FileUrlToPath( Assembly.GetExecutingAssembly().GetName().CodeBase), true, false); } strUserDir = UrlUtil.EnsureTerminatingSeparator(strUserDir, false); string strUserDirLocal; try { strUserDirLocal = Environment.GetFolderPath( Environment.SpecialFolder.LocalApplicationData); } catch(Exception) { strUserDirLocal = strUserDir; } strUserDirLocal = UrlUtil.EnsureTerminatingSeparator(strUserDirLocal, false); m_strCreateDir = strUserDir + strBaseDirName; m_strCreateDirLocal = strUserDirLocal + strBaseDirName; m_strUserConfigFile = m_strCreateDir + Path.DirectorySeparatorChar + strBaseDirName + ".config.xml"; } string strLocalOvr = Program.CommandLineArgs[ AppDefs.CommandLineOptions.ConfigPathLocal]; if(!string.IsNullOrEmpty(strLocalOvr)) { string strWD = UrlUtil.EnsureTerminatingSeparator( WinUtil.GetWorkingDirectory(), false); m_strUserConfigFile = UrlUtil.MakeAbsolutePath(strWD + "Sentinel.txt", strLocalOvr); } Debug.Assert(!string.IsNullOrEmpty(m_strCreateDir)); } private static void EnsureAppDataDirAvailable() { if(string.IsNullOrEmpty(m_strCreateDir)) { Debug.Assert(false); return; } try { if(Directory.Exists(m_strCreateDir) == false) Directory.CreateDirectory(m_strCreateDir); } catch(Exception) { Debug.Assert(false); } } private static XmlDocument LoadEnforcedConfigFile() { #if DEBUG Stopwatch sw = Stopwatch.StartNew(); #endif m_xdEnforced = null; try { // Performance optimization if(!File.Exists(m_strEnforcedConfigFile)) return null; XmlDocument xmlDoc = new XmlDocument(); xmlDoc.Load(m_strEnforcedConfigFile); m_xdEnforced = xmlDoc; return xmlDoc; } catch(Exception) { Debug.Assert(false); } #if DEBUG finally { sw.Stop(); } #endif return null; } private static AppConfigEx LoadConfigFileEx(string strFilePath, XmlDocument xdEnforced) { if(string.IsNullOrEmpty(strFilePath)) return null; AppConfigEx tConfig = null; XmlSerializerEx xmlSerial = new XmlSerializerEx(typeof(AppConfigEx)); if(xdEnforced == null) { FileStream fs = null; try { fs = new FileStream(strFilePath, FileMode.Open, FileAccess.Read, FileShare.Read); tConfig = (AppConfigEx)xmlSerial.Deserialize(fs); } catch(Exception) { } // Do not assert if(fs != null) { fs.Close(); fs = null; } } else // Enforced configuration { try { XmlDocument xd = new XmlDocument(); xd.Load(strFilePath); XmlUtil.MergeNodes(xd, xd.DocumentElement, xdEnforced.DocumentElement); MemoryStream msAsm = new MemoryStream(); xd.Save(msAsm); MemoryStream msRead = new MemoryStream(msAsm.ToArray(), false); tConfig = (AppConfigEx)xmlSerial.Deserialize(msRead); msRead.Close(); msAsm.Close(); } catch(FileNotFoundException) { } catch(Exception) { Debug.Assert(false); } } if(tConfig != null) tConfig.OnLoad(); return tConfig; } public static AppConfigEx Load() { AppConfigSerializer.GetConfigPaths(); // AppConfigEx cfgEnf = LoadConfigFileEx(m_strEnforcedConfigFile); // if(cfgEnf != null) // { // cfgEnf.Meta.IsEnforcedConfiguration = true; // return cfgEnf; // } XmlDocument xdEnforced = LoadEnforcedConfigFile(); AppConfigEx cfgGlobal = LoadConfigFileEx(m_strGlobalConfigFile, xdEnforced); AppConfigEx cfgUser = LoadConfigFileEx(m_strUserConfigFile, xdEnforced); if((cfgGlobal == null) && (cfgUser == null)) { if(xdEnforced != null) { XmlSerializerEx xmlSerial = new XmlSerializerEx(typeof(AppConfigEx)); try { MemoryStream msEnf = new MemoryStream(); xdEnforced.Save(msEnf); MemoryStream msRead = new MemoryStream(msEnf.ToArray(), false); AppConfigEx cfgEnf = (AppConfigEx)xmlSerial.Deserialize(msRead); cfgEnf.OnLoad(); msRead.Close(); msEnf.Close(); return cfgEnf; } catch(Exception) { Debug.Assert(false); } } AppConfigEx cfgNew = new AppConfigEx(); cfgNew.OnLoad(); // Create defaults return cfgNew; } else if((cfgGlobal != null) && (cfgUser == null)) return cfgGlobal; else if((cfgGlobal == null) && (cfgUser != null)) return cfgUser; cfgUser.Meta.PreferUserConfiguration = cfgGlobal.Meta.PreferUserConfiguration; return (cfgGlobal.Meta.PreferUserConfiguration ? cfgUser : cfgGlobal); } private static bool SaveConfigFileEx(AppConfigEx tConfig, string strFilePath, bool bRemoveConfigPref) { tConfig.OnSavePre(); XmlSerializerEx xmlSerial = new XmlSerializerEx(typeof(AppConfigEx)); bool bResult = true; // FileStream fs = null; IOConnectionInfo iocPath = IOConnectionInfo.FromPath(strFilePath); FileTransactionEx fts = new FileTransactionEx(iocPath, true); Stream fs = null; // Temporarily remove user file preference (restore after saving) bool bConfigPref = tConfig.Meta.PreferUserConfiguration; if(bRemoveConfigPref) tConfig.Meta.PreferUserConfiguration = false; XmlWriterSettings xws = new XmlWriterSettings(); xws.Encoding = StrUtil.Utf8; xws.Indent = true; xws.IndentChars = "\t"; try { // fs = new FileStream(strFilePath, FileMode.Create, // FileAccess.Write, FileShare.None); fs = fts.OpenWrite(); if(fs == null) throw new InvalidOperationException(); XmlWriter xw = XmlWriter.Create(fs, xws); xmlSerial.Serialize(xw, tConfig); xw.Close(); } catch(Exception) { bResult = false; } // Do not assert if(fs != null) { fs.Close(); fs = null; } if(bResult) { try { fts.CommitWrite(); } catch(Exception) { Debug.Assert(false); } } if(bRemoveConfigPref) tConfig.Meta.PreferUserConfiguration = bConfigPref; tConfig.OnSavePost(); return bResult; } public static bool Save(AppConfigEx tConfig) { Debug.Assert(tConfig != null); if(tConfig == null) throw new ArgumentNullException("tConfig"); AppConfigSerializer.GetConfigPaths(); bool bPreferUser = false; XmlDocument xdEnforced = LoadEnforcedConfigFile(); AppConfigEx cfgGlobal = LoadConfigFileEx(m_strGlobalConfigFile, xdEnforced); if((cfgGlobal != null) && cfgGlobal.Meta.PreferUserConfiguration) bPreferUser = true; if(bPreferUser) { EnsureAppDataDirAvailable(); if(SaveConfigFileEx(tConfig, m_strUserConfigFile, true)) return true; if(SaveConfigFileEx(tConfig, m_strGlobalConfigFile, false)) return true; } else // Don't prefer user -- use global first { if(SaveConfigFileEx(tConfig, m_strGlobalConfigFile, false)) return true; EnsureAppDataDirAvailable(); if(SaveConfigFileEx(tConfig, m_strUserConfigFile, true)) return true; } #if !KeePassLibSD if(Program.MainForm != null) Program.MainForm.SetStatusEx(KPRes.ConfigSaveFailed); #endif return false; } } } KeePass/App/Configuration/AceMainWindow.cs0000664000000000000000000003770213222430402017455 0ustar rootroot/* KeePass Password Safe - The Open-Source Password Manager Copyright (C) 2003-2018 Dominik Reichl This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ using System; using System.Collections.Generic; using System.ComponentModel; using System.Diagnostics; using System.Drawing; using System.Text; using System.Windows.Forms; using System.Xml.Serialization; using KeePass.Resources; using KeePass.UI; using KeePassLib; using KeePassLib.Security; namespace KeePass.App.Configuration { public enum AceMainWindowLayout { Default = 0, SideBySide = 1 } [Flags] public enum AceListGrouping { Auto = 0, On = 1, Off = 2, // Additional flags: use value > Primary Primary = 0x0F // Auto/On/Off are primary states } public sealed class AceMainWindow { public AceMainWindow() { } private int m_posX = AppDefs.InvalidWindowValue; public int X { get { return m_posX; } set { m_posX = value; } } private int m_posY = AppDefs.InvalidWindowValue; public int Y { get { return m_posY; } set { m_posY = value; } } private int m_sizeW = AppDefs.InvalidWindowValue; public int Width { get { return m_sizeW; } set { m_sizeW = value; } } private int m_sizeH = AppDefs.InvalidWindowValue; public int Height { get { return m_sizeH; } set { m_sizeH = value; } } private bool m_bMax = false; [DefaultValue(false)] public bool Maximized { get { return m_bMax; } set { m_bMax = value; } } private double m_dSplitterHorz = double.Epsilon; public double SplitterHorizontalFrac { get { return m_dSplitterHorz; } set { m_dSplitterHorz = value; } } private double m_dSplitterVert = double.Epsilon; public double SplitterVerticalFrac { get { return m_dSplitterVert; } set { m_dSplitterVert = value; } } private AceMainWindowLayout m_layout = AceMainWindowLayout.Default; public AceMainWindowLayout Layout { get { return m_layout; } set { m_layout = value; } } private bool m_bTop = false; [DefaultValue(false)] public bool AlwaysOnTop { get { return m_bTop; } set { m_bTop = value; } } private bool m_bCloseMin = false; [DefaultValue(false)] public bool CloseButtonMinimizesWindow { get { return m_bCloseMin; } set { m_bCloseMin = value; } } private bool m_bEscMin = false; [DefaultValue(false)] public bool EscMinimizesToTray { get { return m_bEscMin; } set { m_bEscMin = value; } } private bool m_bMinToTray = false; [DefaultValue(false)] public bool MinimizeToTray { get { return m_bMinToTray; } set { m_bMinToTray = value; } } private bool m_bFullPath = false; [DefaultValue(false)] public bool ShowFullPathInTitle { get { return m_bFullPath; } set { m_bFullPath = value; } } private bool m_bDropToBackAfterCopy = false; [DefaultValue(false)] public bool DropToBackAfterClipboardCopy { get { return m_bDropToBackAfterCopy; } set { m_bDropToBackAfterCopy = value; } } private bool m_bMinAfterCopy = false; [DefaultValue(false)] public bool MinimizeAfterClipboardCopy { get { return m_bMinAfterCopy; } set { m_bMinAfterCopy = value; } } private bool m_bMinAfterLocking = true; [DefaultValue(true)] public bool MinimizeAfterLocking { get { return m_bMinAfterLocking; } set { m_bMinAfterLocking = value; } } private bool m_bMinAfterOpeningDb = false; [DefaultValue(false)] public bool MinimizeAfterOpeningDatabase { get { return m_bMinAfterOpeningDb; } set { m_bMinAfterOpeningDb = value; } } private bool m_bQuickFindSearchInPasswords = false; [DefaultValue(false)] public bool QuickFindSearchInPasswords { get { return m_bQuickFindSearchInPasswords; } set { m_bQuickFindSearchInPasswords = value; } } private bool m_bQuickFindExcludeExpired = false; [DefaultValue(false)] public bool QuickFindExcludeExpired { get { return m_bQuickFindExcludeExpired; } set { m_bQuickFindExcludeExpired = value; } } private bool m_bQuickFindDerefData = false; [DefaultValue(false)] public bool QuickFindDerefData { get { return m_bQuickFindDerefData; } set { m_bQuickFindDerefData = value; } } private bool m_bFocusResAfterQuickFind = false; [DefaultValue(false)] public bool FocusResultsAfterQuickFind { get { return m_bFocusResAfterQuickFind; } set { m_bFocusResAfterQuickFind = value; } } private bool m_bFocusQuickFindOnRestore = false; /// /// Focus the quick search box when restoring the main /// window. Here 'restoring' actually means unminimizing, /// i.e. restoring or maximizing the window. /// [DefaultValue(false)] public bool FocusQuickFindOnRestore { get { return m_bFocusQuickFindOnRestore; } set { m_bFocusQuickFindOnRestore = value; } } private bool m_bFocusQuickFindOnUntray = false; [DefaultValue(false)] public bool FocusQuickFindOnUntray { get { return m_bFocusQuickFindOnUntray; } set { m_bFocusQuickFindOnUntray = value; } } private bool m_bCopyUrls = false; [DefaultValue(false)] public bool CopyUrlsInsteadOfOpening { get { return m_bCopyUrls; } set { m_bCopyUrls = value; } } private bool m_bEntrySelGroupSel = true; [DefaultValue(true)] public bool EntrySelGroupSel { get { return m_bEntrySelGroupSel; } set { m_bEntrySelGroupSel = value; } } private bool m_bDisableSaveIfNotModified = false; /// /// Disable 'Save' button (instead of graying it out) if the database /// hasn't been modified. /// [DefaultValue(false)] public bool DisableSaveIfNotModified { get { return m_bDisableSaveIfNotModified; } set { m_bDisableSaveIfNotModified = value; } } private bool m_bHideCloseDbTb = true; [DefaultValue(true)] public bool HideCloseDatabaseButton { get { return m_bHideCloseDbTb; } set { m_bHideCloseDbTb = value; } } private AceToolBar m_tb = new AceToolBar(); public AceToolBar ToolBar { get { return m_tb; } set { if(value == null) throw new ArgumentNullException("value"); m_tb = value; } } private AceEntryView m_ev = new AceEntryView(); public AceEntryView EntryView { get { return m_ev; } set { if(value == null) throw new ArgumentNullException("value"); m_ev = value; } } private AceTanView m_tan = new AceTanView(); public AceTanView TanView { get { return m_tan; } set { if(value == null) throw new ArgumentNullException("value"); m_tan = value; } } private List m_aceColumns = new List(); [XmlArray("EntryListColumnCollection")] public List EntryListColumns { get { return m_aceColumns; } set { if(value == null) throw new ArgumentNullException("value"); m_aceColumns = value; } } private string m_strDisplayIndices = string.Empty; [DefaultValue("")] public string EntryListColumnDisplayOrder { get { return m_strDisplayIndices; } set { if(value == null) throw new ArgumentNullException("value"); m_strDisplayIndices = value; } } private bool m_bAutoResizeColumns = false; [DefaultValue(false)] public bool EntryListAutoResizeColumns { get { return m_bAutoResizeColumns; } set { m_bAutoResizeColumns = value; } } private bool m_bAlternatingBgColor = true; [DefaultValue(true)] public bool EntryListAlternatingBgColors { get { return m_bAlternatingBgColor; } set { m_bAlternatingBgColor = value; } } private int m_argbAltBgColor = 0; [DefaultValue(0)] public int EntryListAlternatingBgColor { get { return m_argbAltBgColor; } set { m_argbAltBgColor = value; } } private bool m_bResolveFieldRefs = false; [DefaultValue(false)] public bool EntryListShowDerefData { get { return m_bResolveFieldRefs; } set { m_bResolveFieldRefs = value; } } private bool m_bResolveFieldRefsAsync = false; [DefaultValue(false)] public bool EntryListShowDerefDataAsync { get { return m_bResolveFieldRefsAsync; } set { m_bResolveFieldRefsAsync = value; } } private bool m_bDerefDataWithRefs = true; [DefaultValue(true)] public bool EntryListShowDerefDataAndRefs { get { return m_bDerefDataWithRefs; } set { m_bDerefDataWithRefs = value; } } // private bool m_bGridLines = false; // public bool ShowGridLines // { // get { return m_bGridLines; } // set { m_bGridLines = value; } // } private ListSorter m_pListSorter = null; public ListSorter ListSorting { get { if(m_pListSorter == null) m_pListSorter = new ListSorter(); return m_pListSorter; } set { if(value == null) throw new ArgumentNullException("value"); m_pListSorter = value; } } private int m_iLgMain = (int)AceListGrouping.Auto; [DefaultValue(0)] public int ListGrouping // AceListGrouping { get { return m_iLgMain; } set { m_iLgMain = value; } } private bool m_bShowEntriesOfSubGroups = false; [DefaultValue(false)] public bool ShowEntriesOfSubGroups { get { return m_bShowEntriesOfSubGroups; } set { m_bShowEntriesOfSubGroups = value; } } public AceColumn FindColumn(AceColumnType t) { foreach(AceColumn c in m_aceColumns) { if(c.Type == t) return c; } return null; } public bool IsColumnHidden(AceColumnType t) { return IsColumnHidden(t, (t == AceColumnType.Password)); } public bool IsColumnHidden(AceColumnType t, bool bDefault) { foreach(AceColumn c in m_aceColumns) { if(c.Type == t) return c.HideWithAsterisks; } return bDefault; } public bool ShouldHideCustomString(string strCustomName, ProtectedString psValue) { foreach(AceColumn c in m_aceColumns) { if((c.Type == AceColumnType.CustomString) && (c.CustomName == strCustomName)) return c.HideWithAsterisks; } if(psValue != null) return psValue.IsProtected; return false; } } public sealed class AceEntryView { public AceEntryView() { } private bool m_bShow = true; [DefaultValue(true)] public bool Show { get { return m_bShow; } set { m_bShow = value; } } // private bool m_bHideProtectedCustomStrings = true; // [DefaultValue(true)] // public bool HideProtectedCustomStrings // { // get { return m_bHideProtectedCustomStrings; } // set { m_bHideProtectedCustomStrings = value; } // } } public sealed class AceTanView { public AceTanView() { } private bool m_bSimple = true; [DefaultValue(true)] public bool UseSimpleView { get { return m_bSimple; } set { m_bSimple = value; } } private bool m_bIndices = true; [DefaultValue(true)] public bool ShowIndices { get { return m_bIndices; } set { m_bIndices = value; } } } public enum AceColumnType { Title = 0, UserName, Password, Url, Notes, CreationTime, LastModificationTime, LastAccessTime, ExpiryTime, Uuid, Attachment, CustomString, PluginExt, // Column data provided by a plugin OverrideUrl, Tags, ExpiryTimeDateOnly, Size, HistoryCount, AttachmentCount, LastPasswordModTime, Count // Virtual identifier representing the number of types } [XmlType(TypeName = "Column")] public sealed class AceColumn { private AceColumnType m_type = AceColumnType.Count; public AceColumnType Type { get { return m_type; } set { if(((int)value >= 0) && ((int)value < (int)AceColumnType.Count)) m_type = value; else { Debug.Assert(false); } } } private string m_strCustomName = string.Empty; [DefaultValue("")] public string CustomName { get { return m_strCustomName; } set { if(value == null) throw new ArgumentNullException("value"); m_strCustomName = value; } } private int m_nWidth = -1; public int Width { get { return m_nWidth; } set { m_nWidth = value; } } private bool m_bHide = false; [DefaultValue(false)] public bool HideWithAsterisks { get { return m_bHide; } set { m_bHide = value; } } public AceColumn() { } public AceColumn(AceColumnType t) { m_type = t; } public AceColumn(AceColumnType t, string strCustomName, bool bHide, int nWidth) { m_type = t; m_strCustomName = strCustomName; m_bHide = bHide; m_nWidth = nWidth; } public string GetDisplayName() { string str = string.Empty; switch(m_type) { case AceColumnType.Title: str = KPRes.Title; break; case AceColumnType.UserName: str = KPRes.UserName; break; case AceColumnType.Password: str = KPRes.Password; break; case AceColumnType.Url: str = KPRes.Url; break; case AceColumnType.Notes: str = KPRes.Notes; break; case AceColumnType.CreationTime: str = KPRes.CreationTime; break; case AceColumnType.LastModificationTime: str = KPRes.LastModificationTime; break; case AceColumnType.LastAccessTime: str = KPRes.LastAccessTime; break; case AceColumnType.ExpiryTime: str = KPRes.ExpiryTime; break; case AceColumnType.Uuid: str = KPRes.Uuid; break; case AceColumnType.Attachment: str = KPRes.Attachments; break; case AceColumnType.CustomString: str = m_strCustomName; break; case AceColumnType.PluginExt: str = m_strCustomName; break; case AceColumnType.OverrideUrl: str = KPRes.UrlOverride; break; case AceColumnType.Tags: str = KPRes.Tags; break; case AceColumnType.ExpiryTimeDateOnly: str = KPRes.ExpiryTimeDateOnly; break; case AceColumnType.Size: str = KPRes.Size; break; case AceColumnType.HistoryCount: str = KPRes.History + " (" + KPRes.Count + ")"; break; case AceColumnType.AttachmentCount: str = KPRes.Attachments + " (" + KPRes.Count + ")"; break; case AceColumnType.LastPasswordModTime: str = KPRes.LastModTimePwHist; break; default: Debug.Assert(false); break; }; return str; } public int SafeGetWidth(int nDefaultWidth) { if(m_nWidth >= 0) return m_nWidth; return nDefaultWidth; } public static bool IsTimeColumn(AceColumnType t) { return ((t == AceColumnType.CreationTime) || (t == AceColumnType.LastModificationTime) || (t == AceColumnType.LastAccessTime) || (t == AceColumnType.ExpiryTime) || (t == AceColumnType.ExpiryTimeDateOnly) || (t == AceColumnType.LastPasswordModTime)); /* bool bTime = false; switch(t) { case AceColumnType.CreationTime: case AceColumnType.LastModificationTime: case AceColumnType.LastAccessTime: case AceColumnType.ExpiryTime: case AceColumnType.ExpiryTimeDateOnly: case AceColumnType.LastPasswordModTime: bTime = true; break; default: break; } return bTime; */ } public static HorizontalAlignment GetTextAlign(AceColumnType t) { if((t == AceColumnType.Size) || (t == AceColumnType.HistoryCount) || (t == AceColumnType.AttachmentCount)) return HorizontalAlignment.Right; return HorizontalAlignment.Left; } } } KeePass/App/Configuration/AceLogging.cs0000664000000000000000000000232113222430402016754 0ustar rootroot/* KeePass Password Safe - The Open-Source Password Manager Copyright (C) 2003-2018 Dominik Reichl This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ using System; using System.Collections.Generic; using System.Text; using System.ComponentModel; namespace KeePass.App.Configuration { public sealed class AceLogging { public AceLogging() { } private bool m_bEnabled = false; [DefaultValue(false)] public bool Enabled { get { return m_bEnabled; } set { m_bEnabled = value; } } } } KeePass/KeePass.pfx0000664000000000000000000000333410576764760013210 0ustar rootroot00 *H 0}0 *H 00 *H  00 *H  05D?*dI& |i&fKG;#!΀%R[m)ZwQoT>ybv[O$Rd3OWo7c4;תBvft87 5SG LLP4AiF2L[+ )$as(Q+Oݷ+hț[#~)[jgriL8V(C3=JpzĺV 3:|<`N8+؃8, tjؚyD5֙,X2ut_."h/^+ɳ)oAL̒*Yv3V윎,J3kgLp/s(AqPԼH^˪Ͳ;6L$ 8̒/Ya\J7zl0+/eϬ!!v,(7w&ٝ|mQZmI];8FVW.";> r'E gӟ.4{j<(C ҉v9&g>+9= 9}z7Dݗ]2>y%o,^9߸E69Rd_yYaļI6h>'3s=7haT<$t\1BOJuHsw3dMBjW"F~aؒz>um+yj8S!X*ZР#D!;*q^1-28=p'>[ɠ> !\8CY5qM~}dWBx~I`߃m@%wz'mBqlCd |~E~Q4nvwm0d΢pJ4\Z46`W|Uc Ut10;00+&cr{ 5FL~!4Sqn.CKeePass/UI/0000775000000000000000000000000013224374410011426 5ustar rootrootKeePass/UI/VistaTaskDialog.cs0000664000000000000000000003220213222430416015002 0ustar rootroot/* KeePass Password Safe - The Open-Source Password Manager Copyright (C) 2003-2018 Dominik Reichl This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ using System; using System.Collections.Generic; using System.Collections.ObjectModel; using System.Text; using System.Runtime.InteropServices; using System.Windows.Forms; using System.Diagnostics; using System.Drawing; using KeePass.Native; using KeePass.Resources; using KeePassLib.Utility; namespace KeePass.UI { [Flags] public enum VtdFlags { None = 0, EnableHyperlinks = 0x0001, UseHIconMain = 0x0002, UseHIconFooter = 0x0004, AllowDialogCancellation = 0x0008, UseCommandLinks = 0x0010, UseCommandLinksNoIcon = 0x0020, ExpandFooterArea = 0x0040, ExpandedByDefault = 0x0080, VerificationFlagChecked = 0x0100, ShowProgressBar = 0x0200, ShowMarqueeProgressBar = 0x0400, CallbackTimer = 0x0800, PositionRelativeToWindow = 0x1000, RtlLayout = 0x2000, NoDefaultRadioButton = 0x4000 } [Flags] public enum VtdCommonButtonFlags { None = 0, OkButton = 0x0001, // Return value: IDOK = DialogResult.OK YesButton = 0x0002, // Return value: IDYES NoButton = 0x0004, // Return value: IDNO CancelButton = 0x0008, // Return value: IDCANCEL RetryButton = 0x0010, // Return value: IDRETRY CloseButton = 0x0020 // Return value: IDCLOSE } public enum VtdIcon { None = 0, Warning = 0xFFFF, Error = 0xFFFE, Information = 0xFFFD, Shield = 0xFFFC } public enum VtdCustomIcon { None = 0, Question = 1 } /* internal enum VtdMsg { Created = 0, Navigated = 1, ButtonClicked = 2, HyperlinkClicked = 3, Timer = 4, Destroyed = 5, RadioButtonClicked = 6, DialogConstructed = 7, VerificationClicked = 8, Help = 9, ExpandoButtonClicked = 10 } */ // Pack = 4 required for 64-bit compatibility [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Auto, Pack = 4)] internal struct VtdButton { public int ID; [MarshalAs(UnmanagedType.LPWStr)] public string Text; public VtdButton(bool bConstruct) { Debug.Assert(bConstruct); this.ID = (int)DialogResult.Cancel; this.Text = string.Empty; } } // Pack = 4 required for 64-bit compatibility [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Auto, Pack = 4)] internal struct VtdConfig { public uint cbSize; public IntPtr hwndParent; public IntPtr hInstance; [MarshalAs(UnmanagedType.U4)] public VtdFlags dwFlags; [MarshalAs(UnmanagedType.U4)] public VtdCommonButtonFlags dwCommonButtons; [MarshalAs(UnmanagedType.LPWStr)] public string pszWindowTitle; public IntPtr hMainIcon; [MarshalAs(UnmanagedType.LPWStr)] public string pszMainInstruction; [MarshalAs(UnmanagedType.LPWStr)] public string pszContent; public uint cButtons; public IntPtr pButtons; public int nDefaultButton; public uint cRadioButtons; public IntPtr pRadioButtons; public int nDefaultRadioButton; [MarshalAs(UnmanagedType.LPWStr)] public string pszVerificationText; [MarshalAs(UnmanagedType.LPWStr)] public string pszExpandedInformation; [MarshalAs(UnmanagedType.LPWStr)] public string pszExpandedControlText; [MarshalAs(UnmanagedType.LPWStr)] public string pszCollapsedControlText; public IntPtr hFooterIcon; [MarshalAs(UnmanagedType.LPWStr)] public string pszFooter; public TaskDialogCallbackProc pfCallback; public IntPtr lpCallbackData; public uint cxWidth; public VtdConfig(bool bConstruct) { Debug.Assert(bConstruct); cbSize = (uint)Marshal.SizeOf(typeof(VtdConfig)); hwndParent = IntPtr.Zero; hInstance = IntPtr.Zero; dwFlags = VtdFlags.None; if(Program.Translation.Properties.RightToLeft) dwFlags |= VtdFlags.RtlLayout; dwCommonButtons = VtdCommonButtonFlags.None; pszWindowTitle = null; hMainIcon = IntPtr.Zero; pszMainInstruction = string.Empty; pszContent = string.Empty; cButtons = 0; pButtons = IntPtr.Zero; nDefaultButton = 0; cRadioButtons = 0; pRadioButtons = IntPtr.Zero; nDefaultRadioButton = 0; pszVerificationText = null; pszExpandedInformation = null; pszExpandedControlText = null; pszCollapsedControlText = null; hFooterIcon = IntPtr.Zero; pszFooter = null; pfCallback = null; lpCallbackData = IntPtr.Zero; cxWidth = 0; } } internal delegate int TaskDialogCallbackProc(IntPtr hwnd, uint uNotification, UIntPtr wParam, IntPtr lParam, IntPtr lpRefData); public sealed class VistaTaskDialog { private const int VtdConfigSize32 = 96; private const int VtdConfigSize64 = 160; private VtdConfig m_cfg = new VtdConfig(true); private int m_iResult = (int)DialogResult.Cancel; private bool m_bVerification = false; private List m_vButtons = new List(); // private IntPtr m_hWnd = IntPtr.Zero; public string WindowTitle { get { return m_cfg.pszWindowTitle; } set { m_cfg.pszWindowTitle = value; } } public string MainInstruction { get { return m_cfg.pszMainInstruction; } set { m_cfg.pszMainInstruction = value; } } internal ReadOnlyCollection Buttons { get { return m_vButtons.AsReadOnly(); } } public string Content { get { return m_cfg.pszContent; } set { m_cfg.pszContent = value; } } public bool CommandLinks { get { return ((m_cfg.dwFlags & VtdFlags.UseCommandLinks) != VtdFlags.None); } set { if(value) m_cfg.dwFlags |= VtdFlags.UseCommandLinks; else m_cfg.dwFlags &= ~VtdFlags.UseCommandLinks; } } public int DefaultButtonID { get { return m_cfg.nDefaultButton; } set { m_cfg.nDefaultButton = value; } } public string ExpandedInformation { get { return m_cfg.pszExpandedInformation; } set { m_cfg.pszExpandedInformation = value; } } public bool ExpandedByDefault { get { return ((m_cfg.dwFlags & VtdFlags.ExpandedByDefault) != VtdFlags.None); } set { if(value) m_cfg.dwFlags |= VtdFlags.ExpandedByDefault; else m_cfg.dwFlags &= ~VtdFlags.ExpandedByDefault; } } public string FooterText { get { return m_cfg.pszFooter; } set { m_cfg.pszFooter = value; } } public string VerificationText { get { return m_cfg.pszVerificationText; } set { m_cfg.pszVerificationText = value; } } public int Result { get { return m_iResult; } } public bool ResultVerificationChecked { get { return m_bVerification; } } public VistaTaskDialog() { } public void AddButton(int iResult, string strCommand, string strDescription) { if(strCommand == null) throw new ArgumentNullException("strCommand"); VtdButton btn = new VtdButton(true); if(strDescription == null) btn.Text = strCommand; else btn.Text = strCommand + "\n" + strDescription; btn.ID = iResult; m_vButtons.Add(btn); } public void SetIcon(VtdIcon vtdIcon) { m_cfg.dwFlags &= ~VtdFlags.UseHIconMain; m_cfg.hMainIcon = new IntPtr((int)vtdIcon); } public void SetIcon(VtdCustomIcon vtdIcon) { if(vtdIcon == VtdCustomIcon.Question) this.SetIcon(SystemIcons.Question.Handle); } public void SetIcon(IntPtr hIcon) { m_cfg.dwFlags |= VtdFlags.UseHIconMain; m_cfg.hMainIcon = hIcon; } public void SetFooterIcon(VtdIcon vtdIcon) { m_cfg.dwFlags &= ~VtdFlags.UseHIconFooter; m_cfg.hFooterIcon = new IntPtr((int)vtdIcon); } private void ButtonsToPtr() { if(m_vButtons.Count == 0) { m_cfg.pButtons = IntPtr.Zero; return; } int nConfigSize = Marshal.SizeOf(typeof(VtdButton)); m_cfg.pButtons = Marshal.AllocHGlobal(m_vButtons.Count * nConfigSize); m_cfg.cButtons = (uint)m_vButtons.Count; for(int i = 0; i < m_vButtons.Count; ++i) { long l = m_cfg.pButtons.ToInt64() + (i * nConfigSize); Marshal.StructureToPtr(m_vButtons[i], new IntPtr(l), false); } } private void FreeButtonsPtr() { if(m_cfg.pButtons == IntPtr.Zero) return; int nConfigSize = Marshal.SizeOf(typeof(VtdButton)); for(int i = 0; i < m_vButtons.Count; ++i) { long l = m_cfg.pButtons.ToInt64() + (i * nConfigSize); Marshal.DestroyStructure(new IntPtr(l), typeof(VtdButton)); } Marshal.FreeHGlobal(m_cfg.pButtons); m_cfg.pButtons = IntPtr.Zero; m_cfg.cButtons = 0; } public bool ShowDialog() { return ShowDialog(null); } public bool ShowDialog(Form fParent) { MessageService.ExternalIncrementMessageCount(); Form f = fParent; if(f == null) f = MessageService.GetTopForm(); if(f == null) f = GlobalWindowManager.TopWindow; #if DEBUG if(GlobalWindowManager.TopWindow != null) { Debug.Assert(f == GlobalWindowManager.TopWindow); } if(Program.MainForm != null) // Skip check for TrlUtil { Debug.Assert(f == MessageService.GetTopForm()); } #endif bool bResult; if((f == null) || !f.InvokeRequired) bResult = InternalShowDialog(f); else bResult = (bool)f.Invoke(new InternalShowDialogDelegate( this.InternalShowDialog), f); MessageService.ExternalDecrementMessageCount(); return bResult; } private delegate bool InternalShowDialogDelegate(Form fParent); private bool InternalShowDialog(Form fParent) { if(IntPtr.Size == 4) { Debug.Assert(Marshal.SizeOf(typeof(VtdConfig)) == VtdConfigSize32); } else if(IntPtr.Size == 8) { Debug.Assert(Marshal.SizeOf(typeof(VtdConfig)) == VtdConfigSize64); } else { Debug.Assert(false); } m_cfg.cbSize = (uint)Marshal.SizeOf(typeof(VtdConfig)); if(fParent == null) m_cfg.hwndParent = IntPtr.Zero; else { try { m_cfg.hwndParent = fParent.Handle; } catch(Exception) { Debug.Assert(false); m_cfg.hwndParent = IntPtr.Zero; } } bool bExp = (m_cfg.pszExpandedInformation != null); m_cfg.pszExpandedControlText = (bExp ? KPRes.Details : null); m_cfg.pszCollapsedControlText = (bExp ? KPRes.Details : null); int pnButton = 0, pnRadioButton = 0; bool bVerification = false; try { ButtonsToPtr(); } catch(Exception) { Debug.Assert(false); return false; } // m_cfg.pfCallback = this.OnTaskDialogCallback; try { using(EnableThemingInScope etis = new EnableThemingInScope(true)) { if(NativeMethods.TaskDialogIndirect(ref m_cfg, out pnButton, out pnRadioButton, out bVerification) != 0) throw new NotSupportedException(); } } catch(Exception) { return false; } finally { try { // m_cfg.pfCallback = null; FreeButtonsPtr(); } catch(Exception) { Debug.Assert(false); } } m_iResult = pnButton; m_bVerification = bVerification; return true; } /* private int OnTaskDialogCallback(IntPtr hwnd, uint uNotification, UIntPtr wParam, IntPtr lParam, IntPtr lpRefData) { if((uNotification == (uint)VtdMsg.Created) || (uNotification == (uint)VtdMsg.DialogConstructed)) UpdateHWnd(hwnd); else if(uNotification == (uint)VtdMsg.Destroyed) UpdateHWnd(IntPtr.Zero); return 0; } private void UpdateHWnd(IntPtr hWnd) { if(hWnd != m_hWnd) { } // Unregister m_hWnd // Register hWnd m_hWnd = hWnd; } */ public static bool ShowMessageBox(string strContent, string strMainInstruction, string strWindowTitle, VtdIcon vtdIcon, Form fParent) { return (ShowMessageBoxEx(strContent, strMainInstruction, strWindowTitle, vtdIcon, fParent, null, 0, null, 0) >= 0); } public static int ShowMessageBoxEx(string strContent, string strMainInstruction, string strWindowTitle, VtdIcon vtdIcon, Form fParent, string strButton1, int iResult1, string strButton2, int iResult2) { VistaTaskDialog vtd = new VistaTaskDialog(); vtd.CommandLinks = false; if(strContent != null) vtd.Content = strContent; if(strMainInstruction != null) vtd.MainInstruction = strMainInstruction; if(strWindowTitle != null) vtd.WindowTitle = strWindowTitle; vtd.SetIcon(vtdIcon); bool bCustomButton = false; if(!string.IsNullOrEmpty(strButton1)) { vtd.AddButton(iResult1, strButton1, null); bCustomButton = true; } if(!string.IsNullOrEmpty(strButton2)) { vtd.AddButton(iResult2, strButton2, null); bCustomButton = true; } if(!vtd.ShowDialog(fParent)) return -1; return (bCustomButton ? vtd.Result : 0); } } } KeePass/UI/BackgroundForm.cs0000664000000000000000000000304213222430412014650 0ustar rootroot/* KeePass Password Safe - The Open-Source Password Manager Copyright (C) 2003-2018 Dominik Reichl This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ using System; using System.Collections.Generic; using System.Text; using System.Windows.Forms; using System.Drawing; using System.Diagnostics; namespace KeePass.UI { public sealed class BackgroundForm : Form { public BackgroundForm(Bitmap bmpBackground, Screen sc) { Screen s = (sc ?? Screen.PrimaryScreen); this.ShowIcon = false; this.ShowInTaskbar = false; this.FormBorderStyle = FormBorderStyle.None; this.StartPosition = FormStartPosition.Manual; this.Location = s.Bounds.Location; this.Size = s.Bounds.Size; this.DoubleBuffered = true; this.BackColor = Color.Black; if(bmpBackground != null) this.BackgroundImage = bmpBackground; } } } KeePass/UI/CustomContextMenuStripEx.cs0000664000000000000000000000352413222430414016737 0ustar rootroot/* KeePass Password Safe - The Open-Source Password Manager Copyright (C) 2003-2018 Dominik Reichl This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ using System; using System.Collections.Generic; using System.ComponentModel; using System.Diagnostics; using System.Drawing; using System.Text; using System.Windows.Forms; namespace KeePass.UI { public sealed class CustomContextMenuStripEx : ContextMenuStrip { public CustomContextMenuStripEx() : base() { UIUtil.Configure(this); } // Used e.g. by the designer public CustomContextMenuStripEx(IContainer container) : base(container) { UIUtil.Configure(this); } public void ShowEx(Control cParent) { if(cParent == null) Show(Cursor.Position); else { int dx = 0; if(cParent.RightToLeft == RightToLeft.Yes) { this.RightToLeft = RightToLeft.Yes; dx = cParent.Width; } Show(cParent, dx, cParent.Height); } } // protected override void OnItemClicked(ToolStripItemClickedEventArgs e) // { // if(UIUtil.HasClickedSeparator(e)) return; // Ignore the click // base.OnItemClicked(e); // } } } KeePass/UI/ProtectedDialog.cs0000664000000000000000000002720113222430414015023 0ustar rootroot/* KeePass Password Safe - The Open-Source Password Manager Copyright (C) 2003-2018 Dominik Reichl This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ using System; using System.Collections.Generic; using System.Text; using System.Windows.Forms; using System.Diagnostics; using System.Threading; using System.Drawing; using KeePass.Native; using KeePass.Resources; using KeePass.Util; using KeePassLib; using KeePassLib.Cryptography; using KeePassLib.Utility; // using KpLibNativeMethods = KeePassLib.Native.NativeMethods; namespace KeePass.UI { public delegate Form UIFormConstructor(object objParam); public delegate object UIFormResultBuilder(Form f); public sealed class ProtectedDialog { private UIFormConstructor m_fnConstruct; private UIFormResultBuilder m_fnResultBuilder; private enum SecureThreadState { None = 0, ShowingDialog, Terminated } private sealed class SecureThreadInfo { public List BackgroundBitmaps = new List(); public IntPtr ThreadDesktop = IntPtr.Zero; public object FormConstructParam = null; public DialogResult DialogResult = DialogResult.None; public object ResultObject = null; public SecureThreadState State = SecureThreadState.None; } public ProtectedDialog(UIFormConstructor fnConstruct, UIFormResultBuilder fnResultBuilder) { if(fnConstruct == null) { Debug.Assert(false); throw new ArgumentNullException("fnConstruct"); } if(fnResultBuilder == null) { Debug.Assert(false); throw new ArgumentNullException("fnResultBuilder"); } m_fnConstruct = fnConstruct; m_fnResultBuilder = fnResultBuilder; } 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), Base64FormattingOptions.None); strName = strName.Replace(@"+", string.Empty); strName = strName.Replace(@"/", string.Empty); strName = strName.Replace(@"=", string.Empty); 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; } private static void ProcessMessagesEx() { Application.DoEvents(); Thread.Sleep(5); Application.DoEvents(); } private void SecureDialogThread(object oParam) { SecureThreadInfo stp = (oParam as SecureThreadInfo); if(stp == null) { Debug.Assert(false); return; } List lBackForms = new List(); BackgroundForm formBackPrimary = null; // bool bLangBar = false; try { if(!NativeMethods.SetThreadDesktop(stp.ThreadDesktop)) { Debug.Assert(false); return; } ProcessMessagesEx(); // Test whether we're really on the secure desktop if(NativeMethods.GetThreadDesktop(NativeMethods.GetCurrentThreadId()) != stp.ThreadDesktop) { Debug.Assert(false); return; } // Disabling IME is not required anymore; we terminate // CtfMon.exe child processes manually // try { NativeMethods.ImmDisableIME(0); } // Always false on 2000/XP // catch(Exception) { Debug.Assert(!WinUtil.IsAtLeastWindows2000); } ProcessMessagesEx(); Screen[] vScreens = Screen.AllScreens; Screen scPrimary = Screen.PrimaryScreen; Debug.Assert(vScreens.Length == stp.BackgroundBitmaps.Count); int sMin = Math.Min(vScreens.Length, stp.BackgroundBitmaps.Count); for(int i = sMin - 1; i >= 0; --i) { Bitmap bmpBack = stp.BackgroundBitmaps[i]; if(bmpBack == null) continue; Debug.Assert(bmpBack.Size == vScreens[i].Bounds.Size); BackgroundForm formBack = new BackgroundForm(bmpBack, vScreens[i]); lBackForms.Add(formBack); if(vScreens[i].Equals(scPrimary)) formBackPrimary = formBack; formBack.Show(); } if(formBackPrimary == null) { Debug.Assert(false); if(lBackForms.Count > 0) formBackPrimary = lBackForms[lBackForms.Count - 1]; } ProcessMessagesEx(); if(!NativeMethods.SwitchDesktop(stp.ThreadDesktop)) { Debug.Assert(false); } ProcessMessagesEx(); Form f = m_fnConstruct(stp.FormConstructParam); if(f == null) { Debug.Assert(false); return; } if(Program.Config.UI.SecureDesktopPlaySound) UIUtil.PlayUacSound(); // bLangBar = ShowLangBar(true); lock(stp) { stp.State = SecureThreadState.ShowingDialog; } stp.DialogResult = f.ShowDialog(formBackPrimary); stp.ResultObject = m_fnResultBuilder(f); UIUtil.DestroyForm(f); } catch(Exception) { Debug.Assert(false); } finally { // if(bLangBar) ShowLangBar(false); foreach(BackgroundForm formBack in lBackForms) { try { formBack.Close(); UIUtil.DestroyForm(formBack); } catch(Exception) { Debug.Assert(false); } } lock(stp) { stp.State = SecureThreadState.Terminated; } } } /* private static bool ShowLangBar(bool bShow) { try { return KpLibNativeMethods.TfShowLangBar(bShow ? KpLibNativeMethods.TF_SFT_SHOWNORMAL : KpLibNativeMethods.TF_SFT_HIDDEN); } catch(Exception) { } return false; } */ private static void HandleUnexpectedDesktopSwitch(IntPtr pOrgDesktop, IntPtr pNewDesktop, SecureThreadInfo stp) { NativeMethods.SwitchDesktop(pOrgDesktop); NativeMethods.SetThreadDesktop(pOrgDesktop); ProcessMessagesEx(); // Do not use MessageService.ShowWarning, because // it uses the top form's thread MessageService.ExternalIncrementMessageCount(); NativeMethods.MessageBoxFlags mbf = (NativeMethods.MessageBoxFlags.MB_ICONWARNING | NativeMethods.MessageBoxFlags.MB_TASKMODAL | NativeMethods.MessageBoxFlags.MB_SETFOREGROUND | NativeMethods.MessageBoxFlags.MB_TOPMOST); if(StrUtil.RightToLeft) mbf |= (NativeMethods.MessageBoxFlags.MB_RTLREADING | NativeMethods.MessageBoxFlags.MB_RIGHT); NativeMethods.MessageBox(IntPtr.Zero, KPRes.SecDeskOtherSwitched + MessageService.NewParagraph + KPRes.SecDeskSwitchBack, PwDefs.ShortProductName, mbf); MessageService.ExternalDecrementMessageCount(); SecureThreadState st; lock(stp) { st = stp.State; } if(st != SecureThreadState.Terminated) { NativeMethods.SwitchDesktop(pNewDesktop); ProcessMessagesEx(); } } /* private static void BlockPrintScreen(Form f, bool bBlock) { if(f == null) { Debug.Assert(false); return; } try { if(bBlock) { NativeMethods.RegisterHotKey(f.Handle, NativeMethods.IDHOT_SNAPDESKTOP, 0, NativeMethods.VK_SNAPSHOT); NativeMethods.RegisterHotKey(f.Handle, NativeMethods.IDHOT_SNAPWINDOW, NativeMethods.MOD_ALT, NativeMethods.VK_SNAPSHOT); } else { NativeMethods.UnregisterHotKey(f.Handle, NativeMethods.IDHOT_SNAPWINDOW); NativeMethods.UnregisterHotKey(f.Handle, NativeMethods.IDHOT_SNAPDESKTOP); } } catch(Exception) { Debug.Assert(false); } } */ } } KeePass/UI/NotifyIconEx.cs0000664000000000000000000001053713222430414014334 0ustar rootroot/* KeePass Password Safe - The Open-Source Password Manager Copyright (C) 2003-2018 Dominik Reichl This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ using System; using System.Collections.Generic; using System.ComponentModel; using System.Diagnostics; using System.Drawing; using System.Text; using System.Windows.Forms; using KeePass; using KeePassLib; using KeePassLib.Native; using KeePassLib.Utility; namespace KeePass.UI { /// /// Exception-safe NotifyIcon wrapper class (workaround /// for exceptions thrown when running KeePass under Mono on /// Mac OS X). /// public sealed class NotifyIconEx { private NotifyIcon m_ntf = null; private Icon m_ico = null; // Property value private Icon m_icoShell = null; // Private copy public NotifyIcon NotifyIcon { get { return m_ntf; } } public ContextMenuStrip ContextMenuStrip { get { try { if(m_ntf != null) return m_ntf.ContextMenuStrip; } catch(Exception) { Debug.Assert(false); } return null; } set { try { if(m_ntf != null) m_ntf.ContextMenuStrip = value; } catch(Exception) { Debug.Assert(false); } } } public bool Visible { get { try { if(m_ntf != null) return m_ntf.Visible; } catch(Exception) { Debug.Assert(false); } return false; } set { try { if(m_ntf != null) m_ntf.Visible = value; } catch(Exception) { Debug.Assert(false); } } } public Icon Icon { get { return m_ico; } set { if(value == m_ico) return; // Avoid small icon recreation m_ico = value; RefreshShellIcon(); } } public string Text { get { try { if(m_ntf != null) return m_ntf.Text; } catch(Exception) { Debug.Assert(false); } return string.Empty; } set { try { if(m_ntf != null) m_ntf.Text = value; } catch(Exception) { Debug.Assert(false); } } } public NotifyIconEx(IContainer container) { try { bool bNtf = true; if(NativeLib.GetPlatformID() == PlatformID.MacOSX) bNtf = !MonoWorkarounds.IsRequired(1574); else { DesktopType t = NativeLib.GetDesktopType(); if((t == DesktopType.Unity) || (t == DesktopType.Pantheon)) bNtf = !MonoWorkarounds.IsRequired(1354); } if(bNtf) m_ntf = new NotifyIcon(container); } catch(Exception) { Debug.Assert(false); } } public void SetHandlers(EventHandler ehClick, EventHandler ehDoubleClick, MouseEventHandler ehMouseDown) { if(m_ntf == null) return; try { if(ehClick != null) m_ntf.Click += ehClick; if(ehDoubleClick != null) m_ntf.DoubleClick += ehDoubleClick; if(ehMouseDown != null) m_ntf.MouseDown += ehMouseDown; } catch(Exception) { Debug.Assert(false); } } internal void RefreshShellIcon() { if(m_ntf == null) return; try { Icon icoToDispose = m_icoShell; try { if(m_ico != null) { Size sz = UIUtil.GetSmallIconSize(); if(Program.Config.UI.TrayIcon.GrayIcon) { using(Bitmap bmpOrg = UIUtil.IconToBitmap(m_ico, sz.Width, sz.Height)) { using(Bitmap bmpGray = UIUtil.CreateGrayImage( bmpOrg)) { m_icoShell = UIUtil.BitmapToIcon(bmpGray); } } } else m_icoShell = new Icon(m_ico, sz); m_ntf.Icon = m_icoShell; } else m_ntf.Icon = null; } catch(Exception) { Debug.Assert(false); m_ntf.Icon = m_ico; } if(icoToDispose != null) icoToDispose.Dispose(); } catch(Exception) { Debug.Assert(false); } } } } KeePass/UI/StatusUtil.cs0000664000000000000000000000661413222430414014100 0ustar rootroot/* KeePass Password Safe - The Open-Source Password Manager Copyright (C) 2003-2018 Dominik Reichl This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ using System; using System.Collections.Generic; using System.Text; using System.Windows.Forms; using System.Diagnostics; using KeePass.Forms; using KeePass.Native; using KeePassLib; using KeePassLib.Interfaces; namespace KeePass.UI { public static class StatusUtil { private sealed class StatusProgressFormWrapper : IStatusLogger { private StatusProgressForm m_dlg; public StatusProgressForm Form { get { return m_dlg; } } public StatusProgressFormWrapper(Form fParent, string strTitle, bool bCanCancel, bool bMarqueeProgress) { m_dlg = new StatusProgressForm(); m_dlg.InitEx(strTitle, bCanCancel, bMarqueeProgress, fParent); if(fParent != null) m_dlg.Show(fParent); else m_dlg.Show(); } public void StartLogging(string strOperation, bool bWriteOperationToLog) { if(m_dlg == null) { Debug.Assert(false); return; } m_dlg.StartLogging(strOperation, false); } public void EndLogging() { if(m_dlg == null) { Debug.Assert(false); return; } m_dlg.EndLogging(); m_dlg.Close(); UIUtil.DestroyForm(m_dlg); m_dlg = null; } public bool SetProgress(uint uPercent) { if(m_dlg == null) { Debug.Assert(false); return true; } return m_dlg.SetProgress(uPercent); } public bool SetText(string strNewText, LogStatusType lsType) { if(m_dlg == null) { Debug.Assert(false); return true; } return m_dlg.SetText(strNewText, lsType); } public bool ContinueWork() { if(m_dlg == null) { Debug.Assert(false); return true; } return m_dlg.ContinueWork(); } } public static IStatusLogger CreateStatusDialog(Form fParent, out Form fOptDialog, string strTitle, string strOp, bool bCanCancel, bool bMarqueeProgress) { if(string.IsNullOrEmpty(strTitle)) strTitle = PwDefs.ShortProductName; if(strOp == null) strOp = string.Empty; IStatusLogger sl; // if(NativeProgressDialog.IsSupported) // { // ProgDlgFlags fl = (ProgDlgFlags.AutoTime | ProgDlgFlags.NoMinimize); // if(!bCanCancel) fl |= ProgDlgFlags.NoCancel; // if(bMarqueeProgress) fl |= ProgDlgFlags.MarqueeProgress; // sl = new NativeProgressDialog((fParent != null) ? fParent.Handle : // IntPtr.Zero, fl); // fOptDialog = null; // } // else // { StatusProgressFormWrapper w = new StatusProgressFormWrapper(fParent, strTitle, bCanCancel, bMarqueeProgress); sl = w; fOptDialog = w.Form; // } sl.StartLogging(strOp, false); return sl; } } } KeePass/UI/ColumnProviderPool.cs0000664000000000000000000000707013222430414015556 0ustar rootroot/* KeePass Password Safe - The Open-Source Password Manager Copyright (C) 2003-2018 Dominik Reichl This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ using System; using System.Collections; using System.Collections.Generic; using System.Text; using System.Windows.Forms; using System.Diagnostics; using KeePassLib; namespace KeePass.UI { public sealed class ColumnProviderPool : IEnumerable { private List m_vProviders = new List(); public int Count { get { return m_vProviders.Count; } } IEnumerator IEnumerable.GetEnumerator() { return m_vProviders.GetEnumerator(); } public IEnumerator GetEnumerator() { return m_vProviders.GetEnumerator(); } public void Add(ColumnProvider prov) { Debug.Assert(prov != null); if(prov == null) throw new ArgumentNullException("prov"); m_vProviders.Add(prov); } public bool Remove(ColumnProvider prov) { Debug.Assert(prov != null); if(prov == null) throw new ArgumentNullException("prov"); return m_vProviders.Remove(prov); } public string[] GetColumnNames() { List v = new List(); foreach(ColumnProvider prov in m_vProviders) { foreach(string strColumn in prov.ColumnNames) { if(!v.Contains(strColumn)) v.Add(strColumn); } } return v.ToArray(); } public HorizontalAlignment GetTextAlign(string strColumnName) { if(strColumnName == null) throw new ArgumentNullException("strColumnName"); foreach(ColumnProvider prov in m_vProviders) { if(Array.IndexOf(prov.ColumnNames, strColumnName) >= 0) return prov.TextAlign; } return HorizontalAlignment.Left; } public string GetCellData(string strColumnName, PwEntry pe) { if(strColumnName == null) throw new ArgumentNullException("strColumnName"); if(pe == null) throw new ArgumentNullException("pe"); foreach(ColumnProvider prov in m_vProviders) { if(Array.IndexOf(prov.ColumnNames, strColumnName) >= 0) return prov.GetCellData(strColumnName, pe); } return string.Empty; } public bool SupportsCellAction(string strColumnName) { if(strColumnName == null) throw new ArgumentNullException("strColumnName"); foreach(ColumnProvider prov in m_vProviders) { if(Array.IndexOf(prov.ColumnNames, strColumnName) >= 0) return prov.SupportsCellAction(strColumnName); } return false; } public void PerformCellAction(string strColumnName, PwEntry pe) { if(strColumnName == null) throw new ArgumentNullException("strColumnName"); foreach(ColumnProvider prov in m_vProviders) { if(Array.IndexOf(prov.ColumnNames, strColumnName) >= 0) { prov.PerformCellAction(strColumnName, pe); break; } } } } } KeePass/UI/CustomToolStripEx.cs0000664000000000000000000000512713222430414015404 0ustar rootroot/* KeePass Password Safe - The Open-Source Password Manager Copyright (C) 2003-2018 Dominik Reichl This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ using System; using System.Collections.Generic; using System.Text; using System.Drawing; using System.Windows.Forms; using System.Diagnostics; using KeePass.Native; using KeePass.Util; namespace KeePass.UI { public sealed class CustomToolStripEx : ToolStrip { private CriticalSectionEx m_csSizeAuto = new CriticalSectionEx(); private int m_iLockedHeight = 0; public CustomToolStripEx() : base() { // ThemeToolStripRenderer.AttachTo(this); UIUtil.Configure(this); } #if DEBUG ~CustomToolStripEx() { if(m_csSizeAuto.TryEnter()) m_csSizeAuto.Exit(); else { Debug.Assert(false); } // Should have been unlocked } #endif protected override void WndProc(ref Message m) { base.WndProc(ref m); // Enable 'click through' behavior if((m.Msg == NativeMethods.WM_MOUSEACTIVATE) && (m.Result == (IntPtr)NativeMethods.MA_ACTIVATEANDEAT)) { m.Result = (IntPtr)NativeMethods.MA_ACTIVATE; } } public void LockHeight(bool bLock) { Debug.Assert(this.Height > 0); m_iLockedHeight = (bLock ? this.Height : 0); } protected override void OnSizeChanged(EventArgs e) { if(m_csSizeAuto.TryEnter()) { try { Size sz = this.Size; // Ignore zero-size events (which can occur e.g. when // the ToolStrip is being hidden) if((sz.Width > 0) && (sz.Height > 0)) { if((m_iLockedHeight > 0) && (sz.Height != m_iLockedHeight)) { base.OnSizeChanged(e); this.Height = m_iLockedHeight; Debug.Assert(this.Size.Height == m_iLockedHeight); return; } } } catch(Exception) { Debug.Assert(false); } finally { m_csSizeAuto.Exit(); } } base.OnSizeChanged(e); } } } KeePass/UI/OpenWithMenu.cs0000664000000000000000000002723213222430414014340 0ustar rootroot/* KeePass Password Safe - The Open-Source Password Manager Copyright (C) 2003-2018 Dominik Reichl This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ using System; using System.Collections.Generic; using System.Text; using System.Windows.Forms; using System.Drawing; using System.Drawing.Drawing2D; using System.Drawing.Imaging; using System.IO; using System.Diagnostics; using Microsoft.Win32; using KeePass.Resources; using KeePass.Util; using KeePassLib; using KeePassLib.Native; using KeePassLib.Utility; namespace KeePass.UI { internal enum OwFilePathType { /// /// Path to an executable file that is invoked with /// the target URI as command line parameter. /// Executable = 0, /// /// Shell path (e.g. URI) in which a placeholder is /// replaced by the target URI. /// ShellExpand } internal sealed class OpenWithItem { private string m_strPath; public string FilePath { get { return m_strPath; } } private OwFilePathType m_tPath; public OwFilePathType FilePathType { get { return m_tPath; } } private string m_strMenuText; // public string MenuText { get { return m_strMenuText; } } private Image m_imgIcon; public Image Image { get { return m_imgIcon; } } private ToolStripMenuItem m_tsmi; public ToolStripMenuItem MenuItem { get { return m_tsmi; } } public OpenWithItem(string strFilePath, OwFilePathType tPath, string strMenuText, Image imgIcon, DynamicMenu dynMenu) { m_strPath = strFilePath; m_tPath = tPath; m_strMenuText = strMenuText; m_imgIcon = imgIcon; m_tsmi = dynMenu.AddItem(m_strMenuText, m_imgIcon, this); try { m_tsmi.ToolTipText = m_strPath; } catch(Exception) { } // Too long? } } public sealed class OpenWithMenu { private ToolStripDropDownItem m_tsmiHost; private DynamicMenu m_dynMenu; private List m_lOpenWith = null; private const string PlhTargetUri = @"{OW_URI}"; public OpenWithMenu(ToolStripDropDownItem tsmiHost) { if(tsmiHost == null) { Debug.Assert(false); return; } m_tsmiHost = tsmiHost; m_dynMenu = new DynamicMenu(m_tsmiHost); m_dynMenu.MenuClick += this.OnOpenUrl; m_tsmiHost.DropDownOpening += this.OnMenuOpening; } ~OpenWithMenu() { try { Destroy(); } catch(Exception) { Debug.Assert(false); } } public void Destroy() { if(m_dynMenu != null) { m_dynMenu.Clear(); m_dynMenu.MenuClick -= this.OnOpenUrl; m_dynMenu = null; m_tsmiHost.DropDownOpening -= this.OnMenuOpening; m_tsmiHost = null; // After the menu has been destroyed: ReleaseOpenWithList(); // Release icons, ... } } private void OnMenuOpening(object sender, EventArgs e) { if(m_dynMenu == null) { Debug.Assert(false); return; } if(m_lOpenWith == null) CreateOpenWithList(); PwEntry[] v = Program.MainForm.GetSelectedEntries(); if(v == null) v = new PwEntry[0]; bool bCanOpenWith = true; uint uValidUrls = 0; foreach(PwEntry pe in v) { string strUrl = pe.Strings.ReadSafe(PwDefs.UrlField); if(string.IsNullOrEmpty(strUrl)) continue; ++uValidUrls; bCanOpenWith &= !WinUtil.IsCommandLineUrl(strUrl); } if((v.Length == 0) || (uValidUrls == 0)) bCanOpenWith = false; foreach(OpenWithItem it in m_lOpenWith) it.MenuItem.Enabled = bCanOpenWith; } private void CreateOpenWithList() { ReleaseOpenWithList(); m_dynMenu.Clear(); m_dynMenu.AddSeparator(); m_lOpenWith = new List(); FindAppsByKnown(); FindAppsByRegistry(); if(m_lOpenWith.Count == 0) m_dynMenu.Clear(); // Remove separator } private void ReleaseOpenWithList() { if(m_lOpenWith == null) return; foreach(OpenWithItem it in m_lOpenWith) { if(it.Image != null) it.Image.Dispose(); } m_lOpenWith = null; } private void OnOpenUrl(object sender, DynamicMenuEventArgs e) { if(e == null) { Debug.Assert(false); return; } OpenWithItem it = (e.Tag as OpenWithItem); if(it == null) { Debug.Assert(false); return; } string strApp = it.FilePath; PwEntry[] v = Program.MainForm.GetSelectedEntries(); if(v == null) { Debug.Assert(false); return; } foreach(PwEntry pe in v) { string strUrl = pe.Strings.ReadSafe(PwDefs.UrlField); if(string.IsNullOrEmpty(strUrl)) continue; if(it.FilePathType == OwFilePathType.Executable) WinUtil.OpenUrlWithApp(strUrl, pe, strApp); else if(it.FilePathType == OwFilePathType.ShellExpand) { string str = strApp.Replace(PlhTargetUri, strUrl); WinUtil.OpenUrl(str, pe, false); } else { Debug.Assert(false); } } } private bool AddAppByFile(string strAppCmdLine, string strName) { if(string.IsNullOrEmpty(strAppCmdLine)) return false; // No assert string strPath = UrlUtil.GetShortestAbsolutePath( UrlUtil.GetQuotedAppPath(strAppCmdLine).Trim()); if(strPath.Length == 0) { Debug.Assert(false); return false; } foreach(OpenWithItem it in m_lOpenWith) { if(it.FilePath.Equals(strPath, StrUtil.CaseIgnoreCmp)) return false; // Already have an item for this } // Filter non-existing/legacy applications try { if(!File.Exists(strPath)) return false; } catch(Exception) { Debug.Assert(false); return false; } if(string.IsNullOrEmpty(strName)) strName = UrlUtil.StripExtension(UrlUtil.GetFileName(strPath)); Image img = UIUtil.GetFileIcon(strPath, DpiUtil.ScaleIntX(16), DpiUtil.ScaleIntY(16)); string strMenuText = KPRes.OpenWith.Replace(@"{PARAM}", strName); OpenWithItem owi = new OpenWithItem(strPath, OwFilePathType.Executable, strMenuText, img, m_dynMenu); m_lOpenWith.Add(owi); return true; } private void AddAppByShellExpand(string strShell, string strName, string strIconExe) { if(string.IsNullOrEmpty(strShell)) return; if(string.IsNullOrEmpty(strName)) strName = strShell; Image img = null; if(!string.IsNullOrEmpty(strIconExe)) img = UIUtil.GetFileIcon(strIconExe, DpiUtil.ScaleIntX(16), DpiUtil.ScaleIntY(16)); string strMenuText = KPRes.OpenWith.Replace(@"{PARAM}", strName); OpenWithItem owi = new OpenWithItem(strShell, OwFilePathType.ShellExpand, strMenuText, img, m_dynMenu); m_lOpenWith.Add(owi); } private void FindAppsByKnown() { string strIE = AppLocator.InternetExplorerPath; if(AddAppByFile(strIE, @"&Internet Explorer")) { // https://msdn.microsoft.com/en-us/library/hh826025.aspx AddAppByShellExpand("cmd://\"" + strIE + "\" -private \"" + PlhTargetUri + "\"", "Internet Explorer (" + KPRes.Private + ")", strIE); } if(AppLocator.EdgeProtocolSupported) AddAppByShellExpand("microsoft-edge:" + PlhTargetUri, @"&Edge", AppLocator.EdgePath); string strFF = AppLocator.FirefoxPath; if(AddAppByFile(strFF, @"&Firefox")) { // The command line options -private and -private-window work // correctly with Firefox 49.0.1 (before, they did not); // https://developer.mozilla.org/en-US/docs/Mozilla/Command_Line_Options // https://bugzilla.mozilla.org/show_bug.cgi?id=856839 // https://bugzilla.mozilla.org/show_bug.cgi?id=829180 AddAppByShellExpand("cmd://\"" + strFF + "\" -private-window \"" + PlhTargetUri + "\"", "Firefox (" + KPRes.Private + ")", strFF); } string strCh = AppLocator.ChromePath; if(AddAppByFile(strCh, @"&Google Chrome")) { // https://www.chromium.org/developers/how-tos/run-chromium-with-flags // https://peter.sh/experiments/chromium-command-line-switches/ AddAppByShellExpand("cmd://\"" + strCh + "\" --incognito \"" + PlhTargetUri + "\"", "Google Chrome (" + KPRes.Private + ")", strCh); } string strOp = AppLocator.OperaPath; if(AddAppByFile(strOp, @"O&pera")) { // Doesn't work with Opera 34.0.2036.25: // AddAppByShellExpand("cmd://\"" + strOp + "\" -newprivatetab \"" + // PlhTargetUri + "\"", "Opera (" + KPRes.Private + ")", strOp); // Doesn't work with Opera 36.0.2130.65: // AddAppByShellExpand("cmd://\"" + strOp + "\" --incognito \"" + // PlhTargetUri + "\"", "Opera (" + KPRes.Private + ")", strOp); // Works with Opera 40.0.2308.81: AddAppByShellExpand("cmd://\"" + strOp + "\" --private \"" + PlhTargetUri + "\"", "Opera (" + KPRes.Private + ")", strOp); } AddAppByFile(AppLocator.SafariPath, @"&Safari"); if(NativeLib.IsUnix()) { AddAppByFile(AppLocator.FindAppUnix("epiphany-browser"), @"&Epiphany"); AddAppByFile(AppLocator.FindAppUnix("galeon"), @"Ga&leon"); AddAppByFile(AppLocator.FindAppUnix("konqueror"), @"&Konqueror"); AddAppByFile(AppLocator.FindAppUnix("rekonq"), @"&Rekonq"); AddAppByFile(AppLocator.FindAppUnix("arora"), @"&Arora"); AddAppByFile(AppLocator.FindAppUnix("midori"), @"&Midori"); AddAppByFile(AppLocator.FindAppUnix("Dooble"), @"&Dooble"); // Upper-case } } private void FindAppsByRegistry() { const string strSmiDef = "SOFTWARE\\Clients\\StartMenuInternet"; const string strSmiWow = "SOFTWARE\\Wow6432Node\\Clients\\StartMenuInternet"; // https://msdn.microsoft.com/en-us/library/windows/desktop/dd203067.aspx try { FindAppsByRegistryPriv(Registry.CurrentUser, strSmiDef); } catch(Exception) { Debug.Assert(NativeLib.IsUnix()); } try { FindAppsByRegistryPriv(Registry.CurrentUser, strSmiWow); } catch(Exception) { Debug.Assert(NativeLib.IsUnix()); } try { FindAppsByRegistryPriv(Registry.LocalMachine, strSmiDef); } catch(Exception) { Debug.Assert(NativeLib.IsUnix()); } try { FindAppsByRegistryPriv(Registry.LocalMachine, strSmiWow); } catch(Exception) { Debug.Assert(NativeLib.IsUnix()); } } private void FindAppsByRegistryPriv(RegistryKey kBase, string strRootSubKey) { RegistryKey kRoot = kBase.OpenSubKey(strRootSubKey, false); if(kRoot == null) return; // No assert, key might not exist string[] vAppSubKeys = kRoot.GetSubKeyNames(); foreach(string strAppSubKey in vAppSubKeys) { RegistryKey kApp = kRoot.OpenSubKey(strAppSubKey, false); string strName = (kApp.GetValue(string.Empty) as string); string strAltName = null; RegistryKey kCmd = kApp.OpenSubKey("shell\\open\\command", false); if(kCmd == null) { kApp.Close(); continue; } // No assert (XP) string strCmdLine = (kCmd.GetValue(string.Empty) as string); kCmd.Close(); RegistryKey kCaps = kApp.OpenSubKey("Capabilities", false); if(kCaps != null) { strAltName = (kCaps.GetValue("ApplicationName") as string); kCaps.Close(); } kApp.Close(); string strDisplayName = string.Empty; if(strName != null) strDisplayName = strName; if((strAltName != null) && (strAltName.Length <= strDisplayName.Length)) strDisplayName = strAltName; AddAppByFile(strCmdLine, strDisplayName); } kRoot.Close(); } } } KeePass/UI/DwmUtil.cs0000664000000000000000000001612113222430414013336 0ustar rootroot/* KeePass Password Safe - The Open-Source Password Manager Copyright (C) 2003-2018 Dominik Reichl This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ using System; using System.Collections.Generic; using System.Text; using System.Runtime.InteropServices; using System.Drawing; using System.Drawing.Drawing2D; using System.Drawing.Imaging; using System.Windows.Forms; using System.Diagnostics; using KeePass.App; using KeePass.Forms; using KeePass.Native; using KeePass.Util; using KeePassLib.Utility; namespace KeePass.UI { public static class DwmUtil { private const uint DWMWA_FORCE_ICONIC_REPRESENTATION = 7; // private const uint DWMWA_FLIP3D_POLICY = 8; private const uint DWMWA_HAS_ICONIC_BITMAP = 10; // private const uint DWMWA_DISALLOW_PEEK = 11; private const uint DWM_SIT_DISPLAYFRAME = 1; public const int WM_DWMSENDICONICTHUMBNAIL = 0x0323; public const int WM_DWMSENDICONICLIVEPREVIEWBITMAP = 0x0326; // private const int DWMFLIP3D_DEFAULT = 0; // private const int DWMFLIP3D_EXCLUDEBELOW = 1; // [DllImport("DwmApi.dll")] // private static extern Int32 DwmExtendFrameIntoClientArea(IntPtr hWnd, // ref MARGINS pMarInset); // [DllImport("DwmApi.dll")] // private static extern Int32 DwmIsCompositionEnabled(ref Int32 pfEnabled); [DllImport("DwmApi.dll")] private static extern int DwmInvalidateIconicBitmaps(IntPtr hWnd); [DllImport("DwmApi.dll", EntryPoint = "DwmSetWindowAttribute")] private static extern int DwmSetWindowAttributeInt(IntPtr hWnd, uint dwAttribute, [In] ref int pvAttribute, uint cbAttribute); [DllImport("DwmApi.dll")] private static extern int DwmSetIconicThumbnail(IntPtr hWnd, IntPtr hBmp, uint dwSITFlags); [DllImport("DwmApi.dll")] private static extern int DwmSetIconicLivePreviewBitmap(IntPtr hWnd, IntPtr hBmp, IntPtr pptClient, uint dwSITFlags); internal static void EnableWindowPeekPreview(MainForm mf) { if(mf == null) { Debug.Assert(false); return; } FormWindowState ws = mf.WindowState; bool bPeek = ((ws == FormWindowState.Normal) || (ws == FormWindowState.Maximized) || !mf.IsFileLocked(null)); EnableWindowPeekPreview(mf, bPeek); } public static void EnableWindowPeekPreview(Form f, bool bEnable) { try { // Static iconic bitmaps only supported by Windows >= 7 if(!WinUtil.IsAtLeastWindows7) return; IntPtr h = f.Handle; if(h == IntPtr.Zero) { Debug.Assert(false); return; } int s = (bEnable ? 0 : 1); // DwmSetWindowAttributeInt(h, DWMWA_DISALLOW_PEEK, ref iNoPeek, 4); // int iFlip3D = (bEnable ? DWMFLIP3D_DEFAULT : // DWMFLIP3D_EXCLUDEBELOW); // DwmSetWindowAttributeInt(h, DWMWA_FLIP3D_POLICY, ref iFlip3D, 4); DwmSetWindowAttributeInt(h, DWMWA_HAS_ICONIC_BITMAP, ref s, 4); DwmSetWindowAttributeInt(h, DWMWA_FORCE_ICONIC_REPRESENTATION, ref s, 4); DwmInvalidateIconicBitmaps(h); } catch(Exception) { Debug.Assert(false); } } public static void SetIconicThumbnail(Form f, Icon ico, ref Message m) { int iInfo = (int)m.LParam.ToInt64(); Size sz = new Size((iInfo >> 16) & 0xFFFF, iInfo & 0xFFFF); SetIconicBitmap(f, ico, sz, true); m.Result = IntPtr.Zero; } public static void SetIconicPreview(Form f, Icon ico, ref Message m) { if(f == null) { Debug.Assert(false); return; } Size sz = new Size(0, 0); MainForm mf = (f as MainForm); if(mf != null) sz = mf.LastClientSize; if((sz.Width <= 0) || (sz.Height <= 0)) sz = f.ClientSize; SetIconicBitmap(f, ico, sz, false); m.Result = IntPtr.Zero; } private static void SetIconicBitmap(Form f, Icon ico, Size sz, bool bThumbnail) { Image img = null; Bitmap bmp = null; IntPtr hBmp = IntPtr.Zero; try { IntPtr hWnd = f.Handle; if(hWnd == IntPtr.Zero) { Debug.Assert(false); return; } img = UIUtil.ExtractVistaIcon(ico); if(img == null) img = ico.ToBitmap(); if(img == null) { Debug.Assert(false); return; } int sw = sz.Width, sh = sz.Height; if(sw <= 0) { Debug.Assert(false); sw = 200; } // Default Windows 7 if(sh <= 0) { Debug.Assert(false); sh = 109; } // Default Windows 7 int iImgW = Math.Min(img.Width, 128); int iImgH = Math.Min(img.Height, 128); int iImgWMax = (sw * 4) / 6; int iImgHMax = (sh * 4) / 6; if(iImgW > iImgWMax) { float fRatio = (float)iImgWMax / (float)iImgW; iImgW = iImgWMax; iImgH = (int)((float)iImgH * fRatio); } if(iImgH > iImgHMax) { float fRatio = (float)iImgHMax / (float)iImgH; iImgW = (int)((float)iImgW * fRatio); iImgH = iImgHMax; } if((iImgW <= 0) || (iImgH <= 0)) { Debug.Assert(false); return; } if(iImgW > sw) { Debug.Assert(false); iImgW = sw; } if(iImgH > sh) { Debug.Assert(false); iImgH = sh; } int iImgX = (sw - iImgW) / 2; int iImgY = (sh - iImgH) / 2; // 32-bit color depth required by API bmp = new Bitmap(sw, sh, PixelFormat.Format32bppArgb); using(Graphics g = Graphics.FromImage(bmp)) { Color clr = AppDefs.ColorControlDisabled; g.Clear(clr); using(LinearGradientBrush br = new LinearGradientBrush( new Point(0, 0), new Point(sw, sh), UIUtil.LightenColor( clr, 0.25), UIUtil.DarkenColor(clr, 0.25))) { g.FillRectangle(br, 0, 0, sw, sh); } // *After* drawing the gradient (otherwise border bug) g.InterpolationMode = InterpolationMode.HighQualityBicubic; g.SmoothingMode = SmoothingMode.HighQuality; RectangleF rSource = new RectangleF(0.0f, 0.0f, img.Width, img.Height); RectangleF rDest = new RectangleF(iImgX, iImgY, iImgW, iImgH); GfxUtil.AdjustScaleRects(ref rSource, ref rDest); // g.DrawImage(img, iImgX, iImgY, iImgW, iImgH); g.DrawImage(img, rDest, rSource, GraphicsUnit.Pixel); } hBmp = bmp.GetHbitmap(); if(bThumbnail) DwmSetIconicThumbnail(hWnd, hBmp, DWM_SIT_DISPLAYFRAME); else DwmSetIconicLivePreviewBitmap(hWnd, hBmp, IntPtr.Zero, DWM_SIT_DISPLAYFRAME); } catch(Exception) { Debug.Assert(!WinUtil.IsAtLeastWindows7); } finally { if(hBmp != IntPtr.Zero) { try { NativeMethods.DeleteObject(hBmp); } catch(Exception) { Debug.Assert(false); } } if(bmp != null) bmp.Dispose(); if(img != null) img.Dispose(); } } } } KeePass/UI/IGwmWindow.cs0000664000000000000000000000202413222430414014001 0ustar rootroot/* KeePass Password Safe - The Open-Source Password Manager Copyright (C) 2003-2018 Dominik Reichl This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ using System; using System.Collections.Generic; using System.Text; namespace KeePass.UI { public interface IGwmWindow { bool CanCloseWithoutDataLoss { get; } } } KeePass/UI/FileDialogsEx.cs0000664000000000000000000002265113222430414014435 0ustar rootroot/* KeePass Password Safe - The Open-Source Password Manager Copyright (C) 2003-2018 Dominik Reichl This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ using System; using System.Collections.Generic; using System.Diagnostics; using System.IO; using System.Text; using System.Windows.Forms; using KeePass.Resources; using KeePass.Util; using KeePassLib; using KeePassLib.Utility; namespace KeePass.UI { public enum FileSaveOrigin { Closing = 0, Locking = 1, Exiting = 2 } public static class FileDialogsEx { public static DialogResult ShowFileSaveQuestion(string strFile, FileSaveOrigin fsOrigin) { bool bFile = ((strFile != null) && (strFile.Length > 0)); if(WinUtil.IsAtLeastWindowsVista) { VistaTaskDialog dlg = new VistaTaskDialog(); string strText = KPRes.DatabaseModifiedNoDot; if(bFile) strText += ":\r\n" + strFile; else strText += "."; dlg.CommandLinks = true; dlg.WindowTitle = PwDefs.ShortProductName; dlg.Content = strText; dlg.SetIcon(VtdCustomIcon.Question); bool bShowCheckBox = true; if(fsOrigin == FileSaveOrigin.Locking) { dlg.MainInstruction = KPRes.FileSaveQLocking; dlg.AddButton((int)DialogResult.Yes, KPRes.SaveCmd, KPRes.FileSaveQOpYesLocking); dlg.AddButton((int)DialogResult.No, KPRes.DiscardChangesCmd, KPRes.FileSaveQOpNoLocking); dlg.AddButton((int)DialogResult.Cancel, KPRes.Cancel, KPRes.FileSaveQOpCancel + " " + KPRes.FileSaveQOpCancelLocking); } else if(fsOrigin == FileSaveOrigin.Exiting) { dlg.MainInstruction = KPRes.FileSaveQExiting; dlg.AddButton((int)DialogResult.Yes, KPRes.SaveCmd, KPRes.FileSaveQOpYesExiting); dlg.AddButton((int)DialogResult.No, KPRes.DiscardChangesCmd, KPRes.FileSaveQOpNoExiting); dlg.AddButton((int)DialogResult.Cancel, KPRes.Cancel, KPRes.FileSaveQOpCancel + " " + KPRes.FileSaveQOpCancelExiting); } else { dlg.MainInstruction = KPRes.FileSaveQClosing; dlg.AddButton((int)DialogResult.Yes, KPRes.SaveCmd, KPRes.FileSaveQOpYesClosing); dlg.AddButton((int)DialogResult.No, KPRes.DiscardChangesCmd, KPRes.FileSaveQOpNoClosing); dlg.AddButton((int)DialogResult.Cancel, KPRes.Cancel, KPRes.FileSaveQOpCancel + " " + KPRes.FileSaveQOpCancelClosing); bShowCheckBox = false; } if(Program.Config.Application.FileClosing.AutoSave) bShowCheckBox = false; if(bShowCheckBox) dlg.VerificationText = KPRes.AutoSaveAtExit; if(dlg.ShowDialog()) { if(bShowCheckBox && (dlg.Result == (int)DialogResult.Yes)) Program.Config.Application.FileClosing.AutoSave = dlg.ResultVerificationChecked; return (DialogResult)dlg.Result; } } string strMessage = (bFile ? (strFile + MessageService.NewParagraph) : string.Empty); strMessage += KPRes.DatabaseModifiedNoDot + "." + MessageService.NewParagraph + KPRes.SaveBeforeCloseQuestion; return MessageService.Ask(strMessage, KPRes.SaveBeforeCloseTitle, MessageBoxButtons.YesNoCancel); } public static bool ShowNewDatabaseIntro(Form fParent) { StringBuilder sb = new StringBuilder(); sb.AppendLine(KPRes.DatabaseFileIntro); sb.AppendLine(); sb.AppendLine(KPRes.DatabaseFileRem); sb.AppendLine(); sb.AppendLine(KPRes.BackupDatabase); string str = sb.ToString(); int r = VistaTaskDialog.ShowMessageBoxEx(str, KPRes.NewDatabase, PwDefs.ShortProductName, VtdIcon.Information, fParent, KPRes.Ok, (int)DialogResult.OK, KPRes.Cancel, (int)DialogResult.Cancel); if(r >= 0) return (r == (int)DialogResult.OK); MessageService.ShowInfo(str); return true; } internal static bool CheckAttachmentSize(long lSize, string strOp) { // https://sourceforge.net/p/keepass/discussion/329221/thread/42ddc71a/ const long cbMax = 512 * 1024 * 1024; if(lSize > cbMax) { MessageService.ShowWarning(strOp, KPRes.FileTooLarge + " " + KPRes.MaxAttachmentSize.Replace(@"{PARAM}", StrUtil.FormatDataSize((ulong)cbMax))); return false; } return true; } internal static bool CheckAttachmentSize(string strPath, string strOp) { FileInfo fi = new FileInfo(strPath); return CheckAttachmentSize(fi.Length, strOp); } } public abstract class FileDialogEx { private readonly bool m_bSaveMode; private readonly string m_strContext; public abstract FileDialog FileDialog { get; } public string DefaultExt { get { return this.FileDialog.DefaultExt; } set { this.FileDialog.DefaultExt = value; } } public string FileName { get { return this.FileDialog.FileName; } set { this.FileDialog.FileName = value; } } public string[] FileNames { get { return this.FileDialog.FileNames; } } public string Filter { get { return this.FileDialog.Filter; } set { this.FileDialog.Filter = value; } } public int FilterIndex { get { return this.FileDialog.FilterIndex; } set { this.FileDialog.FilterIndex = value; } } private string m_strInitialDirectoryOvr = null; public string InitialDirectory { get { return m_strInitialDirectoryOvr; } set { m_strInitialDirectoryOvr = value; } } public string Title { get { return this.FileDialog.Title; } set { this.FileDialog.Title = value; } } protected FileDialogEx(bool bSaveMode, string strContext) { m_bSaveMode = bSaveMode; m_strContext = strContext; // May be null } public DialogResult ShowDialog() { string strPrevWorkDir = PreShowDialog(); DialogResult dr = this.FileDialog.ShowDialog(); PostShowDialog(strPrevWorkDir, dr); return dr; } public DialogResult ShowDialog(IWin32Window owner) { string strPrevWorkDir = PreShowDialog(); DialogResult dr = this.FileDialog.ShowDialog(owner); PostShowDialog(strPrevWorkDir, dr); return dr; } private string PreShowDialog() { MonoWorkarounds.EnsureRecentlyUsedValid(); string strPrevWorkDir = WinUtil.GetWorkingDirectory(); string strNew = Program.Config.Application.GetWorkingDirectory(m_strContext); if(!string.IsNullOrEmpty(m_strInitialDirectoryOvr)) strNew = m_strInitialDirectoryOvr; WinUtil.SetWorkingDirectory(strNew); // Always, even when no context try { string strWD = WinUtil.GetWorkingDirectory(); this.FileDialog.InitialDirectory = strWD; } catch(Exception) { Debug.Assert(false); } return strPrevWorkDir; } private void PostShowDialog(string strPrevWorkDir, DialogResult dr) { string strCur = null; // Modern file dialogs (on Windows >= Vista) do not change the // working directory (in contrast to Windows <= XP), thus we // derive the working directory from the first file try { if(dr == DialogResult.OK) { string strFile = null; if(m_bSaveMode) strFile = this.FileDialog.FileName; else if(this.FileDialog.FileNames.Length > 0) strFile = this.FileDialog.FileNames[0]; if(!string.IsNullOrEmpty(strFile)) strCur = UrlUtil.GetFileDirectory(strFile, false, true); } } catch(Exception) { Debug.Assert(false); } if(!string.IsNullOrEmpty(strCur)) Program.Config.Application.SetWorkingDirectory(m_strContext, strCur); WinUtil.SetWorkingDirectory(strPrevWorkDir); } } public sealed class OpenFileDialogEx : FileDialogEx { private OpenFileDialog m_dlg = new OpenFileDialog(); public override FileDialog FileDialog { get { return m_dlg; } } public bool Multiselect { get { return m_dlg.Multiselect; } set { m_dlg.Multiselect = value; } } public OpenFileDialogEx(string strContext) : base(false, strContext) { m_dlg.CheckFileExists = true; m_dlg.CheckPathExists = true; m_dlg.DereferenceLinks = true; m_dlg.ReadOnlyChecked = false; m_dlg.ShowHelp = false; m_dlg.ShowReadOnly = false; // m_dlg.SupportMultiDottedExtensions = false; // Default m_dlg.ValidateNames = true; m_dlg.RestoreDirectory = false; // Want new working directory } } public sealed class SaveFileDialogEx : FileDialogEx { private SaveFileDialog m_dlg = new SaveFileDialog(); public override FileDialog FileDialog { get { return m_dlg; } } public SaveFileDialogEx(string strContext) : base(true, strContext) { m_dlg.AddExtension = true; m_dlg.CheckFileExists = false; m_dlg.CheckPathExists = true; m_dlg.CreatePrompt = false; m_dlg.DereferenceLinks = true; m_dlg.OverwritePrompt = true; m_dlg.ShowHelp = false; // m_dlg.SupportMultiDottedExtensions = false; // Default m_dlg.ValidateNames = true; m_dlg.RestoreDirectory = false; // Want new working directory } } } KeePass/UI/UIUtil.cs0000664000000000000000000027547613224167342013161 0ustar rootroot/* KeePass Password Safe - The Open-Source Password Manager Copyright (C) 2003-2018 Dominik Reichl This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ using System; using System.Collections.Generic; using System.Diagnostics; using System.Drawing; using System.Drawing.Drawing2D; using System.Drawing.Imaging; using System.IO; using System.Media; using System.Runtime.InteropServices; using System.Text; using System.Text.RegularExpressions; using System.Threading; using System.Windows.Forms; using System.Windows.Forms.VisualStyles; using Microsoft.Win32; using KeePass.App; using KeePass.App.Configuration; using KeePass.Native; using KeePass.Resources; using KeePass.UI.ToolStripRendering; using KeePass.Util; using KeePass.Util.Spr; using KeePassLib; using KeePassLib.Collections; using KeePassLib.Delegates; using KeePassLib.Interfaces; using KeePassLib.Utility; using NativeLib = KeePassLib.Native.NativeLib; namespace KeePass.UI { public sealed class UIScrollInfo { private readonly int m_dx; public int ScrollX { get { return m_dx; } } private readonly int m_dy; public int ScrollY { get { return m_dy; } } private readonly int m_idxTop; public int TopIndex { get { return m_idxTop; } } public UIScrollInfo(int iScrollX, int iScrollY, int iTopIndex) { m_dx = iScrollX; m_dy = iScrollY; m_idxTop = iTopIndex; } } public static class UIUtil { private const int FwsNormal = 0; private const int FwsMaximized = 2; // Compatible with FormWindowState private static bool m_bVistaStyleLists = false; public static bool VistaStyleListsSupported { get { return m_bVistaStyleLists; } } public static bool IsDarkTheme { get { return !IsDarkColor(SystemColors.ControlText); } } public static bool IsHighContrast { get { try { return SystemInformation.HighContrast; } catch(Exception) { Debug.Assert(false); } return false; } } public static void Initialize(bool bReinitialize) { // bReinitialize is currently not used, but not removed // for plugin backward compatibility string strUuid = Program.Config.UI.ToolStripRenderer; ToolStripRenderer tsr = TsrPool.GetBestRenderer(strUuid); if(tsr == null) { Debug.Assert(false); tsr = new ToolStripProfessionalRenderer(); } ToolStripManager.Renderer = tsr; m_bVistaStyleLists = (WinUtil.IsAtLeastWindowsVista && (Environment.Version.Major >= 2)); } internal static NativeMethods.CHARFORMAT2 RtfGetCharFormat(RichTextBox rtb) { NativeMethods.CHARFORMAT2 cf = new NativeMethods.CHARFORMAT2(); cf.cbSize = (uint)Marshal.SizeOf(cf); if(NativeLib.IsUnix()) return cf; IntPtr pCF = IntPtr.Zero; try { pCF = Marshal.AllocCoTaskMem(Marshal.SizeOf(cf)); Marshal.StructureToPtr(cf, pCF, false); IntPtr wParam = (IntPtr)NativeMethods.SCF_SELECTION; NativeMethods.SendMessage(rtb.Handle, NativeMethods.EM_GETCHARFORMAT, wParam, pCF); cf = (NativeMethods.CHARFORMAT2)Marshal.PtrToStructure(pCF, typeof(NativeMethods.CHARFORMAT2)); } catch(Exception) { Debug.Assert(NativeLib.IsUnix()); } finally { if(pCF != IntPtr.Zero) Marshal.FreeCoTaskMem(pCF); } return cf; } internal static void RtfSetCharFormat(RichTextBox rtb, NativeMethods.CHARFORMAT2 cf) { if(NativeLib.IsUnix()) return; if(cf.cbSize != (uint)Marshal.SizeOf(cf)) { Debug.Assert(false); cf.cbSize = (uint)Marshal.SizeOf(cf); } IntPtr pCF = IntPtr.Zero; try { pCF = Marshal.AllocCoTaskMem(Marshal.SizeOf(cf)); Marshal.StructureToPtr(cf, pCF, false); IntPtr wParam = (IntPtr)NativeMethods.SCF_SELECTION; NativeMethods.SendMessage(rtb.Handle, NativeMethods.EM_SETCHARFORMAT, wParam, pCF); } catch(Exception) { Debug.Assert(NativeLib.IsUnix()); } finally { if(pCF != IntPtr.Zero) Marshal.FreeCoTaskMem(pCF); } } public static void RtfSetSelectionLink(RichTextBox rtb) { NativeMethods.CHARFORMAT2 cf = new NativeMethods.CHARFORMAT2(); cf.cbSize = (uint)Marshal.SizeOf(cf); cf.dwMask = NativeMethods.CFM_LINK; cf.dwEffects = NativeMethods.CFE_LINK; RtfSetCharFormat(rtb, cf); } public static bool RtfIsFirstCharLink(RichTextBox rtb) { NativeMethods.CHARFORMAT2 cf = RtfGetCharFormat(rtb); return ((cf.dwEffects & NativeMethods.CFE_LINK) != 0); } public static void RtfLinkifyExtUrls(RichTextBox richTextBox, bool bResetSelection) { const string strProto = "cmd://"; try { string strText = richTextBox.Text; int nOffset = 0; while(nOffset < strText.Length) { int nStart = strText.IndexOf(strProto, nOffset, StrUtil.CaseIgnoreCmp); if(nStart < 0) break; richTextBox.Select(nStart, UrlUtil.GetUrlLength(strText, nStart)); RtfSetSelectionLink(richTextBox); nOffset = nStart + 1; } if(bResetSelection) richTextBox.Select(0, 0); } catch(Exception) { Debug.Assert(false); } } public static void RtfLinkifyText(RichTextBox rtb, string strLinkText, bool bResetTempSelection) { if(rtb == null) throw new ArgumentNullException("rtb"); if(string.IsNullOrEmpty(strLinkText)) return; // No assert try { string strText = rtb.Text; int nStart = strText.IndexOf(strLinkText); if(nStart >= 0) { rtb.Select(nStart, strLinkText.Length); RtfSetSelectionLink(rtb); if(bResetTempSelection) rtb.Select(0, 0); } } catch(Exception) { Debug.Assert(false); } } public static void RtfLinkifyReferences(RichTextBox rtb, bool bResetTempSelection) { try { string str = rtb.Text; int iOffset = 0; while(true) { int iStart = str.IndexOf(SprEngine.StrRefStart, iOffset, StrUtil.CaseIgnoreCmp); if(iStart < 0) break; int iEnd = str.IndexOf(SprEngine.StrRefEnd, iStart + 1, StrUtil.CaseIgnoreCmp); if(iEnd <= iStart) break; string strRef = str.Substring(iStart, iEnd - iStart + 1); RtfLinkifyText(rtb, strRef, bResetTempSelection); iOffset = iStart + 1; } } catch(Exception) { Debug.Assert(false); } } internal static void RtfSetFontSize(RichTextBox rtb, float fSizeInPt) { NativeMethods.CHARFORMAT2 cf = new NativeMethods.CHARFORMAT2(); cf.cbSize = (uint)Marshal.SizeOf(cf); cf.dwMask = NativeMethods.CFM_SIZE; cf.yHeight = (int)(fSizeInPt * 20.0f); RtfSetCharFormat(rtb, cf); } [Obsolete("Use GfxUtil.LoadImage instead.")] public static Image LoadImage(byte[] pb) { return GfxUtil.LoadImage(pb); } public static Image CreateColorBitmap24(int nWidth, int nHeight, Color color) { Bitmap bmp = new Bitmap(nWidth, nHeight, PixelFormat.Format24bppRgb); using(Graphics g = Graphics.FromImage(bmp)) { g.Clear(color); // g.DrawRectangle(Pens.Black, 0, 0, nWidth - 1, nHeight - 1); } return bmp; } public static Image CreateColorBitmap24(Button btnTarget, Color clr) { if(btnTarget == null) { Debug.Assert(false); return null; } Rectangle rect = btnTarget.ClientRectangle; return CreateColorBitmap24(rect.Width - 8, rect.Height - 8, clr); } public static ImageList BuildImageListUnscaled(List lImages, int nWidth, int nHeight) { ImageList imgList = new ImageList(); imgList.ImageSize = new Size(nWidth, nHeight); imgList.ColorDepth = ColorDepth.Depth32Bit; if((lImages != null) && (lImages.Count > 0)) imgList.Images.AddRange(lImages.ToArray()); return imgList; } public static ImageList BuildImageList(List vImages, int nWidth, int nHeight) { ImageList imgList = new ImageList(); imgList.ImageSize = new Size(nWidth, nHeight); imgList.ColorDepth = ColorDepth.Depth32Bit; List lImages = BuildImageListEx(vImages, nWidth, nHeight); if((lImages != null) && (lImages.Count > 0)) imgList.Images.AddRange(lImages.ToArray()); return imgList; } public static List BuildImageListEx(List vImages, int nWidth, int nHeight) { List lImages = new List(); foreach(PwCustomIcon pwci in vImages) { Image img = pwci.GetImage(nWidth, nHeight); if(img == null) { Debug.Assert(false); img = UIUtil.CreateColorBitmap24(nWidth, nHeight, Color.White); } if((img.Width != nWidth) || (img.Height != nHeight)) { Debug.Assert(false); img = new Bitmap(img, new Size(nWidth, nHeight)); } lImages.Add(img); } return lImages; } public static ImageList ConvertImageList24(List vImages, int nWidth, int nHeight, Color clrBack) { ImageList ilNew = new ImageList(); ilNew.ImageSize = new Size(nWidth, nHeight); ilNew.ColorDepth = ColorDepth.Depth24Bit; List vNewImages = new List(); foreach(Image img in vImages) { Bitmap bmpNew = new Bitmap(nWidth, nHeight, PixelFormat.Format24bppRgb); using(Graphics g = Graphics.FromImage(bmpNew)) { g.Clear(clrBack); if((img.Width == nWidth) && (img.Height == nHeight)) g.DrawImageUnscaled(img, 0, 0); else { g.InterpolationMode = InterpolationMode.High; g.DrawImage(img, 0, 0, nWidth, nHeight); } } vNewImages.Add(bmpNew); } ilNew.Images.AddRange(vNewImages.ToArray()); return ilNew; } public static ImageList CloneImageList(ImageList ilSource, bool bCloneImages) { Debug.Assert(ilSource != null); if(ilSource == null) throw new ArgumentNullException("ilSource"); ImageList ilNew = new ImageList(); ilNew.ColorDepth = ilSource.ColorDepth; ilNew.ImageSize = ilSource.ImageSize; foreach(Image img in ilSource.Images) { if(bCloneImages) ilNew.Images.Add(new Bitmap(img)); else ilNew.Images.Add(img); } return ilNew; } public static bool DrawAnimatedRects(Rectangle rectFrom, Rectangle rectTo) { bool bResult; try { NativeMethods.RECT rnFrom = new NativeMethods.RECT(rectFrom); NativeMethods.RECT rnTo = new NativeMethods.RECT(rectTo); bResult = NativeMethods.DrawAnimatedRects(IntPtr.Zero, NativeMethods.IDANI_CAPTION, ref rnFrom, ref rnTo); } catch(Exception) { Debug.Assert(false); bResult = false; } return bResult; } private static void SetCueBanner(IntPtr hWnd, string strText) { Debug.Assert(strText != null); if(strText == null) throw new ArgumentNullException("strText"); IntPtr pText = IntPtr.Zero; try { pText = Marshal.StringToHGlobalUni(strText); NativeMethods.SendMessage(hWnd, NativeMethods.EM_SETCUEBANNER, IntPtr.Zero, pText); } catch(Exception) { Debug.Assert(NativeLib.IsUnix()); } finally { if(pText != IntPtr.Zero) Marshal.FreeHGlobal(pText); } } public static void SetCueBanner(TextBox tb, string strText) { SetCueBanner(tb.Handle, strText); } public static void SetCueBanner(ToolStripTextBox tb, string strText) { SetCueBanner(tb.TextBox, strText); } public static void SetCueBanner(ToolStripComboBox tb, string strText) { try { NativeMethods.COMBOBOXINFO cbi = new NativeMethods.COMBOBOXINFO(); cbi.cbSize = Marshal.SizeOf(cbi); NativeMethods.GetComboBoxInfo(tb.ComboBox.Handle, ref cbi); SetCueBanner(cbi.hwndEdit, strText); } catch(Exception) { Debug.Assert(NativeLib.IsUnix()); } } public static Bitmap CreateScreenshot() { return CreateScreenshot(null); } public static Bitmap CreateScreenshot(Screen sc) { try { Screen s = (sc ?? Screen.PrimaryScreen); Bitmap bmp = new Bitmap(s.Bounds.Width, s.Bounds.Height); using(Graphics g = Graphics.FromImage(bmp)) { g.CopyFromScreen(s.Bounds.Location, new Point(0, 0), s.Bounds.Size); } return bmp; } catch(Exception) { } // Throws on Cocoa and Quartz return null; } public static void DimImage(Image bmp) { if(bmp == null) { Debug.Assert(false); return; } using(Brush b = new SolidBrush(Color.FromArgb(192, Color.Black))) { using(Graphics g = Graphics.FromImage(bmp)) { g.FillRectangle(b, 0, 0, bmp.Width, bmp.Height); } } } public static void PrepareStandardMultilineControl(RichTextBox rtb, bool bSimpleTextOnly, bool bCtrlEnterAccepts) { Debug.Assert(rtb != null); if(rtb == null) throw new ArgumentNullException("rtb"); try { int nStyle = NativeMethods.GetWindowStyle(rtb.Handle); if((nStyle & NativeMethods.ES_WANTRETURN) == 0) { NativeMethods.SetWindowLong(rtb.Handle, NativeMethods.GWL_STYLE, nStyle | NativeMethods.ES_WANTRETURN); Debug.Assert((NativeMethods.GetWindowStyle(rtb.Handle) & NativeMethods.ES_WANTRETURN) != 0); } } catch(Exception) { } CustomRichTextBoxEx crtb = (rtb as CustomRichTextBoxEx); if(crtb != null) { crtb.SimpleTextOnly = bSimpleTextOnly; crtb.CtrlEnterAccepts = bCtrlEnterAccepts; } else { Debug.Assert(!bSimpleTextOnly && !bCtrlEnterAccepts); } } public static void SetMultilineText(TextBox tb, string str) { if(tb == null) { Debug.Assert(false); return; } if(str == null) str = string.Empty; if(!NativeLib.IsUnix()) str = StrUtil.NormalizeNewLines(str, true); tb.Text = str; } /// /// Fill a ListView with password entries. /// /// ListView to fill. /// Entries. /// Columns of the ListView. The first /// parameter of the key-value pair is the internal string field name, /// and the second one the text displayed in the column header. public static void CreateEntryList(ListView lv, IEnumerable vEntries, List> vColumns, ImageList ilIcons) { if(lv == null) throw new ArgumentNullException("lv"); if(vEntries == null) throw new ArgumentNullException("vEntries"); if(vColumns == null) throw new ArgumentNullException("vColumns"); if(vColumns.Count == 0) throw new ArgumentException(); // ilIcons may be null lv.BeginUpdate(); lv.Items.Clear(); lv.Columns.Clear(); lv.ShowGroups = true; lv.SmallImageList = ilIcons; foreach(KeyValuePair kvp in vColumns) { lv.Columns.Add(kvp.Value); } DocumentManagerEx dm = Program.MainForm.DocumentManager; ListViewGroup lvg = new ListViewGroup(Guid.NewGuid().ToString()); DateTime dtNow = DateTime.UtcNow; bool bFirstEntry = true; foreach(PwEntry pe in vEntries) { if(pe == null) { Debug.Assert(false); continue; } if(pe.ParentGroup != null) { string strGroup = pe.ParentGroup.GetFullPath(" - ", false); if(strGroup != lvg.Header) { lvg = new ListViewGroup(strGroup, HorizontalAlignment.Left); lv.Groups.Add(lvg); } } ListViewItem lvi = new ListViewItem(AppDefs.GetEntryField(pe, vColumns[0].Key)); if(ilIcons != null) { if(pe.Expires && (pe.ExpiryTime <= dtNow)) lvi.ImageIndex = (int)PwIcon.Expired; else if(pe.CustomIconUuid == PwUuid.Zero) lvi.ImageIndex = (int)pe.IconId; else { lvi.ImageIndex = (int)pe.IconId; foreach(PwDocument ds in dm.Documents) { int nInx = ds.Database.GetCustomIconIndex(pe.CustomIconUuid); if(nInx > -1) { ilIcons.Images.Add(new Bitmap(DpiUtil.GetIcon( ds.Database, pe.CustomIconUuid))); lvi.ImageIndex = ilIcons.Images.Count - 1; break; } } } } for(int iCol = 1; iCol < vColumns.Count; ++iCol) lvi.SubItems.Add(AppDefs.GetEntryField(pe, vColumns[iCol].Key)); if(!pe.ForegroundColor.IsEmpty) lvi.ForeColor = pe.ForegroundColor; if(!pe.BackgroundColor.IsEmpty) lvi.BackColor = pe.BackgroundColor; lvi.Tag = pe; lv.Items.Add(lvi); lvg.Items.Add(lvi); if(bFirstEntry) { UIUtil.SetFocusedItem(lv, lvi, true); bFirstEntry = false; } } int nColWidth = (lv.ClientRectangle.Width - GetVScrollBarWidth()) / vColumns.Count; foreach(ColumnHeader ch in lv.Columns) { ch.Width = nColWidth; } lv.EndUpdate(); } /// /// Fill a ListView with password entries. /// public static void CreateEntryList(ListView lv, List lCtxs, AceAutoTypeCtxFlags f, ImageList ilIcons) { if(lv == null) throw new ArgumentNullException("lv"); if(lCtxs == null) throw new ArgumentNullException("lCtxs"); lv.BeginUpdate(); lv.Items.Clear(); lv.Columns.Clear(); lv.ShowGroups = true; lv.SmallImageList = ilIcons; Debug.Assert((f & AceAutoTypeCtxFlags.ColTitle) != AceAutoTypeCtxFlags.None); f |= AceAutoTypeCtxFlags.ColTitle; // Enforce title lv.Columns.Add(KPRes.Title); if((f & AceAutoTypeCtxFlags.ColUserName) != AceAutoTypeCtxFlags.None) lv.Columns.Add(KPRes.UserName); if((f & AceAutoTypeCtxFlags.ColPassword) != AceAutoTypeCtxFlags.None) lv.Columns.Add(KPRes.Password); if((f & AceAutoTypeCtxFlags.ColUrl) != AceAutoTypeCtxFlags.None) lv.Columns.Add(KPRes.Url); if((f & AceAutoTypeCtxFlags.ColNotes) != AceAutoTypeCtxFlags.None) lv.Columns.Add(KPRes.Notes); if((f & AceAutoTypeCtxFlags.ColSequenceComments) != AceAutoTypeCtxFlags.None) lv.Columns.Add(KPRes.Sequence + " - " + KPRes.Comments); if((f & AceAutoTypeCtxFlags.ColSequence) != AceAutoTypeCtxFlags.None) lv.Columns.Add(KPRes.Sequence); ListViewGroup lvg = new ListViewGroup(Guid.NewGuid().ToString()); DateTime dtNow = DateTime.UtcNow; Regex rxSeqCmt = null; bool bFirstEntry = true; foreach(AutoTypeCtx ctx in lCtxs) { if(ctx == null) { Debug.Assert(false); continue; } PwEntry pe = ctx.Entry; if(pe == null) { Debug.Assert(false); continue; } PwDatabase pd = ctx.Database; if(pd == null) { Debug.Assert(false); continue; } if(pe.ParentGroup != null) { string strGroup = pe.ParentGroup.GetFullPath(" - ", true); if(strGroup != lvg.Header) { lvg = new ListViewGroup(strGroup, HorizontalAlignment.Left); lv.Groups.Add(lvg); } } SprContext sprCtx = new SprContext(pe, pd, SprCompileFlags.Deref); sprCtx.ForcePlainTextPasswords = false; ListViewItem lvi = new ListViewItem(SprEngine.Compile( pe.Strings.ReadSafe(PwDefs.TitleField), sprCtx)); if(pe.Expires && (pe.ExpiryTime <= dtNow)) lvi.ImageIndex = (int)PwIcon.Expired; else if(pe.CustomIconUuid == PwUuid.Zero) lvi.ImageIndex = (int)pe.IconId; else { int nInx = pd.GetCustomIconIndex(pe.CustomIconUuid); if(nInx > -1) { ilIcons.Images.Add(new Bitmap(DpiUtil.GetIcon( pd, pe.CustomIconUuid))); lvi.ImageIndex = ilIcons.Images.Count - 1; } else { Debug.Assert(false); lvi.ImageIndex = (int)pe.IconId; } } if((f & AceAutoTypeCtxFlags.ColUserName) != AceAutoTypeCtxFlags.None) lvi.SubItems.Add(SprEngine.Compile(pe.Strings.ReadSafe( PwDefs.UserNameField), sprCtx)); if((f & AceAutoTypeCtxFlags.ColPassword) != AceAutoTypeCtxFlags.None) lvi.SubItems.Add(SprEngine.Compile(pe.Strings.ReadSafe( PwDefs.PasswordField), sprCtx)); if((f & AceAutoTypeCtxFlags.ColUrl) != AceAutoTypeCtxFlags.None) lvi.SubItems.Add(SprEngine.Compile(pe.Strings.ReadSafe( PwDefs.UrlField), sprCtx)); if((f & AceAutoTypeCtxFlags.ColNotes) != AceAutoTypeCtxFlags.None) lvi.SubItems.Add(StrUtil.MultiToSingleLine(SprEngine.Compile( pe.Strings.ReadSafe(PwDefs.NotesField), sprCtx))); if((f & AceAutoTypeCtxFlags.ColSequenceComments) != AceAutoTypeCtxFlags.None) { if(rxSeqCmt == null) rxSeqCmt = new Regex("\\{[Cc]:[^\\}]*\\}"); string strSeqCmt = string.Empty, strImpSeqCmt = string.Empty; foreach(Match m in rxSeqCmt.Matches(ctx.Sequence)) { string strPart = m.Value; if(strPart == null) { Debug.Assert(false); continue; } if(strPart.Length < 4) { Debug.Assert(false); continue; } strPart = strPart.Substring(3, strPart.Length - 4).Trim(); bool bImp = strPart.StartsWith("!"); // Important comment if(bImp) strPart = strPart.Substring(1); if(strPart.Length == 0) continue; if(bImp) { if(strImpSeqCmt.Length > 0) strImpSeqCmt += " - "; strImpSeqCmt += strPart; } else { if(strSeqCmt.Length > 0) strSeqCmt += " - "; strSeqCmt += strPart; } } lvi.SubItems.Add((strImpSeqCmt.Length > 0) ? strImpSeqCmt : strSeqCmt); } if((f & AceAutoTypeCtxFlags.ColSequence) != AceAutoTypeCtxFlags.None) lvi.SubItems.Add(ctx.Sequence); Debug.Assert(lvi.SubItems.Count == lv.Columns.Count); if(!pe.ForegroundColor.IsEmpty) lvi.ForeColor = pe.ForegroundColor; if(!pe.BackgroundColor.IsEmpty) lvi.BackColor = pe.BackgroundColor; lvi.Tag = ctx; lv.Items.Add(lvi); lvg.Items.Add(lvi); if(bFirstEntry) { UIUtil.SetFocusedItem(lv, lvi, true); bFirstEntry = false; } } lv.EndUpdate(); // Resize columns *after* EndUpdate, otherwise sizing problem // caused by the scrollbar UIUtil.ResizeColumns(lv, true); } public static int GetVScrollBarWidth() { try { return SystemInformation.VerticalScrollBarWidth; } catch(Exception) { Debug.Assert(false); } return 18; // Default theme on Windows Vista } /// /// Create a file type filter specification string. /// /// Default extension(s), without leading /// dot. Multiple extensions must be separated by a '|' (e.g. /// "html|htm", having the same description "HTML Files"). public static string CreateFileTypeFilter(string strExtension, string strDescription, bool bIncludeAllFiles) { StringBuilder sb = new StringBuilder(); if(!string.IsNullOrEmpty(strExtension) && !string.IsNullOrEmpty( strDescription)) { // str += strDescription + @" (*." + strExtension + // @")|*." + strExtension; string[] vExts = strExtension.Split(new char[]{ '|' }, StringSplitOptions.RemoveEmptyEntries); if(vExts.Length > 0) { sb.Append(strDescription); sb.Append(@" (*."); for(int i = 0; i < vExts.Length; ++i) { if(i > 0) sb.Append(@", *."); sb.Append(vExts[i]); } sb.Append(@")|*."); for(int i = 0; i < vExts.Length; ++i) { if(i > 0) sb.Append(@";*."); sb.Append(vExts[i]); } } } if(bIncludeAllFiles) { if(sb.Length > 0) sb.Append(@"|"); sb.Append(KPRes.AllFiles); sb.Append(@" (*.*)|*.*"); } return sb.ToString(); } public static string GetPrimaryFileTypeExt(string strExtensions) { if(strExtensions == null) { Debug.Assert(false); return string.Empty; } int i = strExtensions.IndexOf('|'); if(i >= 0) return strExtensions.Substring(0, i); return strExtensions; // Single extension } [Obsolete("Use the overload with the strContext parameter.")] public static OpenFileDialog CreateOpenFileDialog(string strTitle, string strFilter, int iFilterIndex, string strDefaultExt, bool bMultiSelect, bool bRestoreDirectory) { return (OpenFileDialog)(CreateOpenFileDialog(strTitle, strFilter, iFilterIndex, strDefaultExt, bMultiSelect, string.Empty).FileDialog); } public static OpenFileDialogEx CreateOpenFileDialog(string strTitle, string strFilter, int iFilterIndex, string strDefaultExt, bool bMultiSelect, string strContext) { OpenFileDialogEx ofd = new OpenFileDialogEx(strContext); if(!string.IsNullOrEmpty(strDefaultExt)) ofd.DefaultExt = strDefaultExt; if(!string.IsNullOrEmpty(strFilter)) { ofd.Filter = strFilter; if(iFilterIndex > 0) ofd.FilterIndex = iFilterIndex; } ofd.Multiselect = bMultiSelect; if(!string.IsNullOrEmpty(strTitle)) ofd.Title = strTitle; return ofd; } [Obsolete("Use the overload with the strContext parameter.")] public static SaveFileDialog CreateSaveFileDialog(string strTitle, string strSuggestedFileName, string strFilter, int iFilterIndex, string strDefaultExt, bool bRestoreDirectory) { return (SaveFileDialog)(CreateSaveFileDialog(strTitle, strSuggestedFileName, strFilter, iFilterIndex, strDefaultExt, string.Empty).FileDialog); } [Obsolete("Use the overload with the strContext parameter.")] public static SaveFileDialog CreateSaveFileDialog(string strTitle, string strSuggestedFileName, string strFilter, int iFilterIndex, string strDefaultExt, bool bRestoreDirectory, bool bIsDatabaseFile) { return (SaveFileDialog)(CreateSaveFileDialog(strTitle, strSuggestedFileName, strFilter, iFilterIndex, strDefaultExt, (bIsDatabaseFile ? AppDefs.FileDialogContext.Database : string.Empty)).FileDialog); } public static SaveFileDialogEx CreateSaveFileDialog(string strTitle, string strSuggestedFileName, string strFilter, int iFilterIndex, string strDefaultExt, string strContext) { SaveFileDialogEx sfd = new SaveFileDialogEx(strContext); if(!string.IsNullOrEmpty(strDefaultExt)) sfd.DefaultExt = strDefaultExt; if(!string.IsNullOrEmpty(strSuggestedFileName)) sfd.FileName = strSuggestedFileName; if(!string.IsNullOrEmpty(strFilter)) { sfd.Filter = strFilter; if(iFilterIndex > 0) sfd.FilterIndex = iFilterIndex; } if(!string.IsNullOrEmpty(strTitle)) sfd.Title = strTitle; if(strContext != null) { if((strContext == AppDefs.FileDialogContext.Database) && (Program.Config.Defaults.FileSaveAsDirectory.Length > 0)) sfd.InitialDirectory = Program.Config.Defaults.FileSaveAsDirectory; } return sfd; } public static FolderBrowserDialog CreateFolderBrowserDialog(string strDescription) { FolderBrowserDialog fbd = new FolderBrowserDialog(); if((strDescription != null) && (strDescription.Length > 0)) fbd.Description = strDescription; fbd.ShowNewFolderButton = true; return fbd; } private static ColorDialog CreateColorDialog(Color clrDefault) { ColorDialog dlg = new ColorDialog(); dlg.AllowFullOpen = true; dlg.AnyColor = true; if(!clrDefault.IsEmpty) dlg.Color = clrDefault; dlg.FullOpen = true; dlg.ShowHelp = false; // dlg.SolidColorOnly = false; try { string strColors = Program.Config.Defaults.CustomColors; if(!string.IsNullOrEmpty(strColors)) { int[] vColors = StrUtil.DeserializeIntArray(strColors); if((vColors != null) && (vColors.Length > 0)) dlg.CustomColors = vColors; } } catch(Exception) { Debug.Assert(false); } return dlg; } private static void SaveCustomColors(ColorDialog dlg) { if(dlg == null) { Debug.Assert(false); return; } try { int[] vColors = dlg.CustomColors; if((vColors == null) || (vColors.Length == 0)) Program.Config.Defaults.CustomColors = string.Empty; else Program.Config.Defaults.CustomColors = StrUtil.SerializeIntArray(vColors); } catch(Exception) { Debug.Assert(false); } } public static Color? ShowColorDialog(Color clrDefault) { ColorDialog dlg = CreateColorDialog(clrDefault); GlobalWindowManager.AddDialog(dlg); DialogResult dr = dlg.ShowDialog(); GlobalWindowManager.RemoveDialog(dlg); SaveCustomColors(dlg); Color? clrResult = null; if(dr == DialogResult.OK) clrResult = dlg.Color; dlg.Dispose(); return clrResult; } public static FontDialog CreateFontDialog(bool bEffects) { FontDialog dlg = new FontDialog(); dlg.FontMustExist = true; dlg.ShowEffects = bEffects; return dlg; } public static void SetGroupNodeToolTip(TreeNode tn, PwGroup pg) { if((tn == null) || (pg == null)) { Debug.Assert(false); return; } string str = GetPwGroupToolTip(pg); if(str == null) return; try { tn.ToolTipText = str; } catch(Exception) { Debug.Assert(false); } } public static string GetPwGroupToolTip(PwGroup pg) { if(pg == null) { Debug.Assert(false); return null; } StringBuilder sb = new StringBuilder(); sb.Append(pg.Name); string strNotes = pg.Notes.Trim(); if(strNotes.Length > 0) { sb.Append(MessageService.NewParagraph); sb.Append(strNotes); } else return null; // uint uSubGroups, uEntries; // pg.GetCounts(true, out uSubGroups, out uEntries); // sb.Append(MessageService.NewParagraph); // sb.Append(KPRes.Subgroups); sb.Append(": "); sb.Append(uSubGroups); // sb.Append(MessageService.NewLine); // sb.Append(KPRes.Entries); sb.Append(": "); sb.Append(uEntries); return sb.ToString(); } // public static string GetPwGroupToolTipTN(TreeNode tn) // { // if(tn == null) { Debug.Assert(false); return null; } // PwGroup pg = (tn.Tag as PwGroup); // if(pg == null) { Debug.Assert(false); return null; } // return GetPwGroupToolTip(pg); // } public static Color LightenColor(Color clrBase, double dblFactor) { if((dblFactor <= 0.0) || (dblFactor > 1.0)) return clrBase; unchecked { byte r = (byte)((double)(255 - clrBase.R) * dblFactor + clrBase.R); byte g = (byte)((double)(255 - clrBase.G) * dblFactor + clrBase.G); byte b = (byte)((double)(255 - clrBase.B) * dblFactor + clrBase.B); return Color.FromArgb((int)r, (int)g, (int)b); } } public static Color DarkenColor(Color clrBase, double dblFactor) { if((dblFactor <= 0.0) || (dblFactor > 1.0)) return clrBase; unchecked { byte r = (byte)((double)clrBase.R - ((double)clrBase.R * dblFactor)); byte g = (byte)((double)clrBase.G - ((double)clrBase.G * dblFactor)); byte b = (byte)((double)clrBase.B - ((double)clrBase.B * dblFactor)); return Color.FromArgb((int)r, (int)g, (int)b); } } public static void MoveSelectedItemsInternalOne(ListView lv, PwObjectList v, bool bUp) where T : class, IDeepCloneable { if(lv == null) throw new ArgumentNullException("lv"); if(v == null) throw new ArgumentNullException("v"); if(lv.Items.Count != (int)v.UCount) throw new ArgumentException(); ListView.SelectedListViewItemCollection lvsic = lv.SelectedItems; if(lvsic.Count == 0) return; int nStart = (bUp ? 0 : (lvsic.Count - 1)); int nEnd = (bUp ? lvsic.Count : -1); int iStep = (bUp ? 1 : -1); for(int i = nStart; i != nEnd; i += iStep) v.MoveOne((lvsic[i].Tag as T), bUp); } public static void DeleteSelectedItems(ListView lv, PwObjectList vInternalList) where T : class, IDeepCloneable { if(lv == null) throw new ArgumentNullException("lv"); if(vInternalList == null) throw new ArgumentNullException("vInternalList"); ListView.SelectedIndexCollection lvsc = lv.SelectedIndices; int n = lvsc.Count; // Getting Count sends a message if(n == 0) return; // LVSIC: one access by index requires O(n) time, thus copy // all to an array (which requires O(1) for each element) int[] v = new int[n]; lvsc.CopyTo(v, 0); for(int i = 0; i < n; ++i) { int nIndex = v[n - i - 1]; if(vInternalList.Remove(lv.Items[nIndex].Tag as T)) lv.Items.RemoveAt(nIndex); else { Debug.Assert(false); } } } public static object[] GetSelectedItemTags(ListView lv) { if(lv == null) throw new ArgumentNullException("lv"); ListView.SelectedListViewItemCollection lvsc = lv.SelectedItems; if(lvsc == null) { Debug.Assert(false); return new object[0]; } int n = lvsc.Count; // Getting Count sends a message object[] p = new object[n]; int i = 0; // LVSLVIC: one access by index requires O(n) time, thus use // enumerator instead (which requires O(1) for each element) foreach(ListViewItem lvi in lvsc) { if(i >= n) { Debug.Assert(false); break; } p[i] = lvi.Tag; ++i; } Debug.Assert(i == n); return p; } public static void SelectItems(ListView lv, object[] vItemTags) { if(lv == null) throw new ArgumentNullException("lv"); if(vItemTags == null) throw new ArgumentNullException("vItemTags"); for(int i = 0; i < lv.Items.Count; ++i) { if(Array.IndexOf(vItemTags, lv.Items[i].Tag) >= 0) lv.Items[i].Selected = true; } } public static void SetWebBrowserDocument(WebBrowser wb, string strDocumentText) { string strContent = (strDocumentText ?? string.Empty); wb.AllowNavigation = true; wb.DocumentText = strContent; // Wait for document being loaded for(int i = 0; i < 50; ++i) { if(wb.DocumentText == strContent) break; Thread.Sleep(20); Application.DoEvents(); } } public static string GetWebBrowserDocument(WebBrowser wb) { return wb.DocumentText; } public static void SetExplorerTheme(IntPtr hWnd) { if(hWnd == IntPtr.Zero) { Debug.Assert(false); return; } try { NativeMethods.SetWindowTheme(hWnd, "explorer", null); } catch(Exception) { } // Not supported on older operating systems } public static void SetExplorerTheme(Control c, bool bUseListFont) { if(c == null) { Debug.Assert(false); return; } SetExplorerTheme(c.Handle); if(bUseListFont) { if(UISystemFonts.ListFont != null) c.Font = UISystemFonts.ListFont; } } public static void SetShield(Button btn, bool bSetShield) { if(btn == null) throw new ArgumentNullException("btn"); try { if(btn.FlatStyle != FlatStyle.System) { Debug.Assert(false); btn.FlatStyle = FlatStyle.System; } IntPtr h = btn.Handle; if(h == IntPtr.Zero) { Debug.Assert(false); return; } NativeMethods.SendMessage(h, NativeMethods.BCM_SETSHIELD, IntPtr.Zero, (IntPtr)(bSetShield ? 1 : 0)); } catch(Exception) { Debug.Assert(false); } } public static void Configure(ToolStrip ts) { if(ts == null) { Debug.Assert(false); return; } if(Program.DesignMode) return; // if(Program.Translation.Properties.RightToLeft) // ts.RightToLeft = RightToLeft.Yes; DpiUtil.Configure(ts); } // internal static void ConfigureToolStripItem(ToolStripItem ts) // { // if(ts == null) { Debug.Assert(false); return; } // if(Program.DesignMode) return; // // Disable separators such that clicking on them // // does not close the menu // ToolStripSeparator tsSep = (ts as ToolStripSeparator); // if(tsSep != null) tsSep.Enabled = false; // } public static void ConfigureTbButton(ToolStripItem tb, string strText, string strTooltip) { ConfigureTbButton(tb, strText, strTooltip, null); } private static char[] m_vTbTrim = null; public static void ConfigureTbButton(ToolStripItem tb, string strText, string strTooltip, ToolStripMenuItem tsmiEquiv) { if(strText != null) tb.Text = strText; if(m_vTbTrim == null) m_vTbTrim = new char[] { ' ', '\t', '\r', '\n', '.', '\u2026' }; string strTip = (strTooltip ?? strText); if(strTip == null) return; strTip = StrUtil.RemoveAccelerator(strTip); strTip = strTip.Trim(m_vTbTrim); if((tsmiEquiv != null) && (strTip.Length > 0)) { string strShortcut = tsmiEquiv.ShortcutKeyDisplayString; if(!string.IsNullOrEmpty(strShortcut)) strTip += " (" + strShortcut + ")"; } tb.ToolTipText = strTip; } public static void ConfigureToolTip(ToolTip tt) { if(tt == null) { Debug.Assert(false); return; } try { tt.AutoPopDelay = 32000; tt.InitialDelay = 250; tt.ReshowDelay = 50; Debug.Assert(tt.AutoPopDelay == 32000); } catch(Exception) { Debug.Assert(false); } } public static void CreateGroupList(PwGroup pgContainer, ComboBox cmb, Dictionary outCreatedItems, PwUuid uuidToSelect, out int iSelectIndex) { iSelectIndex = -1; if(pgContainer == null) { Debug.Assert(false); return; } if(cmb == null) { Debug.Assert(false); return; } // Do not clear the combobox! int iSelectInner = -1; GroupHandler gh = delegate(PwGroup pg) { string str = new string(' ', Math.Abs(8 * ((int)pg.GetLevel() - 1))); str += pg.Name; if((uuidToSelect != null) && pg.Uuid.Equals(uuidToSelect)) iSelectInner = cmb.Items.Count; if(outCreatedItems != null) outCreatedItems[cmb.Items.Count] = pg.Uuid; cmb.Items.Add(str); return true; }; pgContainer.TraverseTree(TraversalMethod.PreOrder, gh, null); iSelectIndex = iSelectInner; } public static void MakeInheritableBoolComboBox(ComboBox cmb, bool? bSelect, bool bInheritedState) { if(cmb == null) { Debug.Assert(false); return; } cmb.Items.Clear(); cmb.Items.Add(KPRes.InheritSettingFromParent + " (" + (bInheritedState ? KPRes.Enabled : KPRes.Disabled) + ")"); cmb.Items.Add(KPRes.Enabled); cmb.Items.Add(KPRes.Disabled); if(bSelect.HasValue) cmb.SelectedIndex = (bSelect.Value ? 1 : 2); else cmb.SelectedIndex = 0; } public static bool? GetInheritableBoolComboBoxValue(ComboBox cmb) { if(cmb == null) { Debug.Assert(false); return null; } if(cmb.SelectedIndex == 1) return true; if(cmb.SelectedIndex == 2) return false; return null; } public static void SetEnabled(Control c, bool bEnabled) { if(c == null) { Debug.Assert(false); return; } if(c.Enabled != bEnabled) c.Enabled = bEnabled; } internal static void SetEnabledFast(bool bEnabled, params ToolStripItem[] v) { if(v == null) { Debug.Assert(false); return; } foreach(ToolStripItem c in v) { if(c == null) { Debug.Assert(false); continue; } c.Enabled = bEnabled; } } public static void SetChecked(CheckBox cb, bool bChecked) { if(cb == null) { Debug.Assert(false); return; } if(cb.Checked != bChecked) cb.Checked = bChecked; } private static Bitmap GetGlyphBitmap(MenuGlyph mg, Color clrFG) { try { Size sz = new Size(DpiUtil.ScaleIntX(16), DpiUtil.ScaleIntY(16)); Bitmap bmp = new Bitmap(sz.Width, sz.Height, PixelFormat.Format32bppArgb); using(Graphics g = Graphics.FromImage(bmp)) { g.Clear(Color.Transparent); ControlPaint.DrawMenuGlyph(g, new Rectangle(Point.Empty, sz), mg, clrFG, Color.Transparent); } return bmp; } catch(Exception) { Debug.Assert(false); } return null; } private static Bitmap g_bmpCheck = null; private static Bitmap g_bmpCheckLight = null; private static Bitmap g_bmpTrans = null; public static void SetChecked(ToolStripMenuItem tsmi, bool bChecked) { if(tsmi == null) { Debug.Assert(false); return; } string strIDCheck = "guid:5EAEA440-02AA-4E62-B57E-724A6F89B1EE"; string strIDTrans = "guid:38DDF11D-F101-468A-A006-9810A95F34F4"; // The image references may change, thus use the Tag instead; // https://sourceforge.net/p/keepass/discussion/329220/thread/e1950e60/ bool bSetImage = false; Image imgCur = tsmi.Image; if(imgCur == null) bSetImage = true; else { string strID = (imgCur.Tag as string); if(strID == null) { } // Unknown image, don't overwrite else if((strID == strIDCheck) || (strID == strIDTrans)) bSetImage = true; } if(bSetImage) { Image img = null; if(bChecked) { if(g_bmpCheck == null) { g_bmpCheck = new Bitmap(Properties.Resources.B16x16_MenuCheck); g_bmpCheck.Tag = strIDCheck; } img = g_bmpCheck; Color clrFG = tsmi.ForeColor; if(!clrFG.IsEmpty && (ColorToGrayscale(clrFG).R >= 128)) { if(g_bmpCheckLight == null) { g_bmpCheckLight = GetGlyphBitmap(MenuGlyph.Checkmark, Color.White); // Not clrFG, for consistency if(g_bmpCheckLight != null) { Debug.Assert(g_bmpCheckLight.Tag == null); g_bmpCheckLight.Tag = strIDCheck; } } if(g_bmpCheckLight != null) img = g_bmpCheckLight; } else { Debug.Assert(g_bmpCheckLight == null); } // Always or never } else { if(g_bmpTrans == null) { g_bmpTrans = new Bitmap(Properties.Resources.B16x16_Transparent); g_bmpTrans.Tag = strIDTrans; } // Assign transparent image instead of null in order to // prevent incorrect menu item heights img = g_bmpTrans; } tsmi.Image = img; } tsmi.Checked = bChecked; } private static Bitmap g_bmpRadioLight = null; public static void SetRadioChecked(ToolStripMenuItem tsmi, bool bChecked) { if(tsmi == null) { Debug.Assert(false); return; } Debug.Assert(!tsmi.CheckOnClick); // Potential to break image if(bChecked) { Image imgCheck = Properties.Resources.B16x16_MenuRadio; Color clrFG = tsmi.ForeColor; if(!clrFG.IsEmpty && (ColorToGrayscale(clrFG).R >= 128)) { if(g_bmpRadioLight == null) g_bmpRadioLight = GetGlyphBitmap(MenuGlyph.Bullet, Color.White); // Not clrFG, for consistency if(g_bmpRadioLight != null) imgCheck = g_bmpRadioLight; } else { Debug.Assert(g_bmpRadioLight == null); } // Always or never tsmi.Image = imgCheck; tsmi.CheckState = CheckState.Checked; } else { // Transparent: see SetChecked method tsmi.Image = Properties.Resources.B16x16_Transparent; tsmi.CheckState = CheckState.Unchecked; } } public static void ResizeColumns(ListView lv, bool bBlockUIUpdate) { ResizeColumns(lv, null, bBlockUIUpdate); } public static void ResizeColumns(ListView lv, int[] vRelWidths, bool bBlockUIUpdate) { if(lv == null) { Debug.Assert(false); return; } // vRelWidths may be null List lCurWidths = new List(); foreach(ColumnHeader ch in lv.Columns) { lCurWidths.Add(ch.Width); } int n = lCurWidths.Count; if(n == 0) return; int[] vRels = new int[n]; int nRelSum = 0; for(int i = 0; i < n; ++i) { if((vRelWidths != null) && (i < vRelWidths.Length)) { if(vRelWidths[i] >= 0) vRels[i] = vRelWidths[i]; else { Debug.Assert(false); vRels[i] = 0; } } else vRels[i] = 1; // Unit width 1 is default nRelSum += vRels[i]; } if(nRelSum == 0) { Debug.Assert(false); return; } int w = lv.ClientSize.Width - 1; if(w <= 0) { Debug.Assert(false); return; } // The client width might include the width of a vertical // scrollbar or not (unreliable; for example the scrollbar // width is not subtracted during a Form.Load even though // a scrollbar is required); try to detect this situation int cwScroll = UIUtil.GetVScrollBarWidth(); if((lv.Width - w) < cwScroll) // Scrollbar not already subtracted { int nItems = lv.Items.Count; if(nItems > 0) { #if DEBUG foreach(ListViewItem lvi in lv.Items) { Debug.Assert(lvi.Bounds.Height == lv.Items[0].Bounds.Height); } #endif if((((long)nItems * (long)lv.Items[0].Bounds.Height) > (long)lv.ClientSize.Height) && (w > cwScroll)) w -= cwScroll; } } double dx = (double)w / (double)nRelSum; int[] vNewWidths = new int[n]; int iFirstVisible = -1, wSum = 0; for(int i = 0; i < n; ++i) { int cw = (int)Math.Floor(dx * (double)vRels[i]); vNewWidths[i] = cw; wSum += cw; if((iFirstVisible < 0) && (cw > 0)) iFirstVisible = i; } if((iFirstVisible >= 0) && (wSum < w)) vNewWidths[iFirstVisible] += (w - wSum); if(bBlockUIUpdate) lv.BeginUpdate(); int iCol = 0; foreach(ColumnHeader ch in lv.Columns) { if(iCol >= n) { Debug.Assert(false); break; } if(vNewWidths[iCol] != lCurWidths[iCol]) ch.Width = vNewWidths[iCol]; ++iCol; } Debug.Assert(iCol == n); if(bBlockUIUpdate) lv.EndUpdate(); } public static bool ColorsEqual(Color c1, Color c2) { // return ((c1.R == c2.R) && (c1.G == c2.G) && (c1.B == c2.B) && // (c1.A == c2.A)); return (c1.ToArgb() == c2.ToArgb()); } public static Color GetAlternateColor(Color clrBase) { if(ColorsEqual(clrBase, Color.White)) return Color.FromArgb(238, 238, 255); float b = clrBase.GetBrightness(); if(b >= 0.5) return UIUtil.DarkenColor(clrBase, 0.1); return UIUtil.LightenColor(clrBase, 0.25); } public static Color GetAlternateColorEx(Color clrBase) { int c = Program.Config.MainWindow.EntryListAlternatingBgColor; if(c != 0) return Color.FromArgb(c); return GetAlternateColor(clrBase); } public static void SetAlternatingBgColors(ListView lv, Color clrAlternate, bool bAlternate) { if(lv == null) throw new ArgumentNullException("lv"); Color clrBg = lv.BackColor; if(!UIUtil.GetGroupsEnabled(lv) || !bAlternate) { for(int i = 0; i < lv.Items.Count; ++i) { ListViewItem lvi = lv.Items[i]; Debug.Assert(lvi.Index == i); Debug.Assert(lvi.UseItemStyleForSubItems); if(!bAlternate) { if(ColorsEqual(lvi.BackColor, clrAlternate)) lvi.BackColor = clrBg; } else if(((i & 1) == 0) && ColorsEqual(lvi.BackColor, clrAlternate)) lvi.BackColor = clrBg; else if(((i & 1) == 1) && ColorsEqual(lvi.BackColor, clrBg)) lvi.BackColor = clrAlternate; } } else // Groups && alternating { foreach(ListViewGroup lvg in lv.Groups) { // Within the group the items are not in display order, // but the order can be derived from the item indices List lItems = new List(); foreach(ListViewItem lviEnum in lvg.Items) lItems.Add(lviEnum); lItems.Sort(UIUtil.LviCompareByIndex); for(int i = 0; i < lItems.Count; ++i) { ListViewItem lvi = lItems[i]; Debug.Assert(lvi.UseItemStyleForSubItems); if(((i & 1) == 0) && ColorsEqual(lvi.BackColor, clrAlternate)) lvi.BackColor = clrBg; else if(((i & 1) == 1) && ColorsEqual(lvi.BackColor, clrBg)) lvi.BackColor = clrAlternate; } } } } private static int LviCompareByIndex(ListViewItem a, ListViewItem b) { return a.Index.CompareTo(b.Index); } public static bool SetSortIcon(ListView lv, int iColumn, SortOrder so) { if(lv == null) { Debug.Assert(false); return false; } if(NativeLib.IsUnix()) return false; try { IntPtr hHeader = NativeMethods.SendMessage(lv.Handle, NativeMethods.LVM_GETHEADER, IntPtr.Zero, IntPtr.Zero); bool bUnicode = (WinUtil.IsWindows2000 || WinUtil.IsWindowsXP || WinUtil.IsAtLeastWindowsVista); int nGetMsg = (bUnicode ? NativeMethods.HDM_GETITEMW : NativeMethods.HDM_GETITEMA); int nSetMsg = (bUnicode ? NativeMethods.HDM_SETITEMW : NativeMethods.HDM_SETITEMA); for(int i = 0; i < lv.Columns.Count; ++i) { IntPtr pColIndex = new IntPtr(i); NativeMethods.HDITEM hdItem = new NativeMethods.HDITEM(); hdItem.mask = NativeMethods.HDI_FORMAT; if(NativeMethods.SendMessageHDItem(hHeader, nGetMsg, pColIndex, ref hdItem) == IntPtr.Zero) { Debug.Assert(false); } if((i != iColumn) || (so == SortOrder.None)) hdItem.fmt &= (~NativeMethods.HDF_SORTUP & ~NativeMethods.HDF_SORTDOWN); else { if(so == SortOrder.Ascending) { hdItem.fmt &= ~NativeMethods.HDF_SORTDOWN; hdItem.fmt |= NativeMethods.HDF_SORTUP; } else // SortOrder.Descending { hdItem.fmt &= ~NativeMethods.HDF_SORTUP; hdItem.fmt |= NativeMethods.HDF_SORTDOWN; } } Debug.Assert(hdItem.mask == NativeMethods.HDI_FORMAT); if(NativeMethods.SendMessageHDItem(hHeader, nSetMsg, pColIndex, ref hdItem) == IntPtr.Zero) { Debug.Assert(false); } } } catch(Exception) { Debug.Assert(false); return false; } return true; } public static void SetDisplayIndices(ListView lv, int[] v) { // Display indices must be assigned in an ordered way (with // respect to the display indices, not the column indices), // otherwise .NET's automatic adjustments result in // different display indices; // https://sourceforge.net/p/keepass/discussion/329221/thread/5e00cffe/ if(lv == null) { Debug.Assert(false); return; } if(v == null) { Debug.Assert(false); return; } int nCols = lv.Columns.Count; int nMin = Math.Min(nCols, v.Length); SortedDictionary d = new SortedDictionary(); for(int i = 0; i < nMin; ++i) { int nIdx = v[i]; if((nIdx >= 0) && (nIdx < nCols)) d[nIdx] = i; } foreach(KeyValuePair kvp in d) lv.Columns[kvp.Value].DisplayIndex = kvp.Key; #if DEBUG int[] vNew = new int[nMin]; for(int i = 0; i < nMin; ++i) vNew[i] = lv.Columns[i].DisplayIndex; Debug.Assert(StrUtil.SerializeIntArray(vNew) == StrUtil.SerializeIntArray(MemUtil.Mid(v, 0, nMin))); #endif } public static Color ColorToGrayscale(Color clr) { int l = (int)((0.3f * clr.R) + (0.59f * clr.G) + (0.11f * clr.B)); if(l >= 256) l = 255; return Color.FromArgb(l, l, l); } public static Color ColorTowards(Color clr, Color clrBase, double dblFactor) { int l = (int)((0.3f * clrBase.R) + (0.59f * clrBase.G) + (0.11f * clrBase.B)); if(l < 128) return DarkenColor(clr, dblFactor); return LightenColor(clr, dblFactor); } public static Color ColorTowardsGrayscale(Color clr, Color clrBase, double dblFactor) { return ColorToGrayscale(ColorTowards(clr, clrBase, dblFactor)); } public static bool IsDarkColor(Color clr) { Color clrLvl = ColorToGrayscale(clr); return (clrLvl.R < 128); } public static Color ColorMiddle(Color clrA, Color clrB) { return Color.FromArgb(((int)clrA.A + (int)clrB.A) / 2, ((int)clrA.R + (int)clrB.R) / 2, ((int)clrA.G + (int)clrB.G) / 2, ((int)clrA.B + (int)clrB.B) / 2); } public static GraphicsPath CreateRoundedRectangle(int x, int y, int dx, int dy, int r) { try { GraphicsPath gp = new GraphicsPath(); gp.AddLine(x + r, y, x + dx - (r * 2), y); gp.AddArc(x + dx - (r * 2), y, r * 2, r * 2, 270.0f, 90.0f); gp.AddLine(x + dx, y + r, x + dx, y + dy - (r * 2)); gp.AddArc(x + dx - (r * 2), y + dy - (r * 2), r * 2, r * 2, 0.0f, 90.0f); gp.AddLine(x + dx - (r * 2), y + dy, x + r, y + dy); gp.AddArc(x, y + dy - (r * 2), r * 2, r * 2, 90.0f, 90.0f); gp.AddLine(x, y + dy - (r * 2), x, y + r); gp.AddArc(x, y, r * 2, r * 2, 180.0f, 90.0f); gp.CloseFigure(); return gp; } catch(Exception) { Debug.Assert(false); } return null; } public static Control GetActiveControl(ContainerControl cc) { if(cc == null) { Debug.Assert(false); return null; } try { Control c = cc.ActiveControl; if(c == cc) return c; ContainerControl ccSub = (c as ContainerControl); if(ccSub != null) return GetActiveControl(ccSub); else return c; } catch(Exception) { Debug.Assert(false); } return null; } public static void ApplyKeyUIFlags(ulong aceUIFlags, CheckBox cbPassword, CheckBox cbKeyFile, CheckBox cbUserAccount, CheckBox cbHidePassword) { if((aceUIFlags & (ulong)AceKeyUIFlags.EnablePassword) != 0) UIUtil.SetEnabled(cbPassword, true); if((aceUIFlags & (ulong)AceKeyUIFlags.EnableKeyFile) != 0) UIUtil.SetEnabled(cbKeyFile, true); if((aceUIFlags & (ulong)AceKeyUIFlags.EnableUserAccount) != 0) UIUtil.SetEnabled(cbUserAccount, true); if((aceUIFlags & (ulong)AceKeyUIFlags.EnableHidePassword) != 0) UIUtil.SetEnabled(cbHidePassword, true); if((aceUIFlags & (ulong)AceKeyUIFlags.CheckPassword) != 0) UIUtil.SetChecked(cbPassword, true); if((aceUIFlags & (ulong)AceKeyUIFlags.CheckKeyFile) != 0) UIUtil.SetChecked(cbKeyFile, true); if((aceUIFlags & (ulong)AceKeyUIFlags.CheckUserAccount) != 0) UIUtil.SetChecked(cbUserAccount, true); if((aceUIFlags & (ulong)AceKeyUIFlags.CheckHidePassword) != 0) UIUtil.SetChecked(cbHidePassword, true); if((aceUIFlags & (ulong)AceKeyUIFlags.UncheckPassword) != 0) UIUtil.SetChecked(cbPassword, false); if((aceUIFlags & (ulong)AceKeyUIFlags.UncheckKeyFile) != 0) UIUtil.SetChecked(cbKeyFile, false); if((aceUIFlags & (ulong)AceKeyUIFlags.UncheckUserAccount) != 0) UIUtil.SetChecked(cbUserAccount, false); if((aceUIFlags & (ulong)AceKeyUIFlags.UncheckHidePassword) != 0) UIUtil.SetChecked(cbHidePassword, false); if((aceUIFlags & (ulong)AceKeyUIFlags.DisablePassword) != 0) UIUtil.SetEnabled(cbPassword, false); if((aceUIFlags & (ulong)AceKeyUIFlags.DisableKeyFile) != 0) UIUtil.SetEnabled(cbKeyFile, false); if((aceUIFlags & (ulong)AceKeyUIFlags.DisableUserAccount) != 0) UIUtil.SetEnabled(cbUserAccount, false); if((aceUIFlags & (ulong)AceKeyUIFlags.DisableHidePassword) != 0) UIUtil.SetEnabled(cbHidePassword, false); } public static bool GetGroupsEnabled(ListView lv) { if(lv == null) { Debug.Assert(false); return false; } // Corresponds almost with the internal GroupsEnabled property return (lv.ShowGroups && (lv.Groups.Count > 0) && !lv.VirtualMode); } public static int GetMaxVisibleItemCount(ListView lv) { if(lv == null) { Debug.Assert(false); return 0; } int hClient = lv.ClientSize.Height; int hHeader = NativeMethods.GetHeaderHeight(lv); if(hHeader > 0) { if(((lv.Height - hClient) < hHeader) && (hClient > hHeader)) hClient -= hHeader; } int dy = lv.Items[0].Bounds.Height; if(dy <= 1) { Debug.Assert(false); dy = DpiUtil.ScaleIntY(16) + 1; } return (hClient / dy); } public static int GetTopVisibleItem(ListView lv) { if(lv == null) { Debug.Assert(false); return -1; } // The returned value must be an existing index or -1 int nRes = -1; try { if(lv.Items.Count == 0) return nRes; ListViewItem lvi = null; if(!UIUtil.GetGroupsEnabled(lv)) lvi = lv.TopItem; else { // In grouped mode, the TopItem property does not work; // https://connect.microsoft.com/VisualStudio/feedback/details/642188/listview-control-bug-topitem-property-doesnt-work-with-groups // https://msdn.microsoft.com/en-us/library/windows/desktop/bb761087.aspx int dyHeader = NativeMethods.GetHeaderHeight(lv); int yMin = int.MaxValue; foreach(ListViewItem lviEnum in lv.Items) { int yEnum = Math.Abs(lviEnum.Position.Y - dyHeader); if(yEnum < yMin) { yMin = yEnum; lvi = lviEnum; } } } if(lvi != null) nRes = lvi.Index; } catch(Exception) { Debug.Assert(false); } return nRes; } public static void SetTopVisibleItem(ListView lv, int iIndex) { SetTopVisibleItem(lv, iIndex, false); } public static void SetTopVisibleItem(ListView lv, int iIndex, bool bEnsureSelectedVisible) { if(lv == null) { Debug.Assert(false); return; } if(iIndex < 0) return; // No assert int n = lv.Items.Count; if(n <= 0) return; if(iIndex >= n) iIndex = n - 1; // No assert int iOrgTop = GetTopVisibleItem(lv); lv.BeginUpdate(); // Might reduce flicker if(iIndex != iOrgTop) // Prevent unnecessary flicker { // Setting lv.TopItem doesn't work properly // lv.EnsureVisible(n - 1); // if(iIndex != (n - 1)) lv.EnsureVisible(iIndex); #if DEBUG foreach(ListViewItem lvi in lv.Items) { Debug.Assert(lvi.Bounds.Height == lv.Items[0].Bounds.Height); } #endif if(iIndex < iOrgTop) lv.EnsureVisible(iIndex); else { int nVisItems = GetMaxVisibleItemCount(lv); int iNewLast = nVisItems + iIndex - 1; if(iNewLast < 0) { Debug.Assert(false); iNewLast = 0; } iNewLast = Math.Min(iNewLast, n - 1); lv.EnsureVisible(iNewLast); int iNewTop = GetTopVisibleItem(lv); if(iNewTop > iIndex) // Scrolled too far { Debug.Assert(false); lv.EnsureVisible(iIndex); // Scroll back } else if(iNewTop == iIndex) { } // Perfect else { Debug.Assert(iNewLast == (n - 1)); } // int hItem = lv.Items[0].Bounds.Height; // if(hItem <= 0) { Debug.Assert(false); hItem = DpiUtil.ScaleIntY(16) + 1; } // int hToScroll = (iIndex - iOrgTop) * hItem; // NativeMethods.Scroll(lv, 0, hToScroll); // int iNewTop = GetTopVisibleItem(lv); // if(iNewTop > iIndex) // Scrolled too far // { // Debug.Assert(false); // lv.EnsureVisible(iIndex); // Scroll back // } // else if(iNewTop == iIndex) { } // Perfect // else // { // lv.EnsureVisible(n - 1); // if(iIndex != (n - 1)) lv.EnsureVisible(iIndex); // } } } if(bEnsureSelectedVisible) { ListView.SelectedIndexCollection lvsic = lv.SelectedIndices; int nSel = lvsic.Count; if(nSel > 0) { int[] vSel = new int[nSel]; lvsic.CopyTo(vSel, 0); lv.EnsureVisible(vSel[nSel - 1]); if(nSel >= 2) lv.EnsureVisible(vSel[0]); } } lv.EndUpdate(); } public static UIScrollInfo GetScrollInfo(ListView lv, bool bForRestoreOnly) { if(lv == null) { Debug.Assert(false); return null; } int scrY = NativeMethods.GetScrollPosY(lv.Handle); int idxTop = GetTopVisibleItem(lv); // Fix index-based scroll position if((scrY == idxTop) && (idxTop > 0)) { // Groups imply pixel position Debug.Assert(!UIUtil.GetGroupsEnabled(lv)); if(!bForRestoreOnly) { int hSum = 0; foreach(ListViewItem lvi in lv.Items) { if(scrY <= 0) break; int hItem = lvi.Bounds.Height; if(hItem > 1) hSum += hItem; else { Debug.Assert(false); } --scrY; } scrY = hSum; } else scrY = 0; // Pixels not required for restoration } return new UIScrollInfo(0, scrY, idxTop); } public static void Scroll(ListView lv, UIScrollInfo s, bool bEnsureSelectedVisible) { if(lv == null) { Debug.Assert(false); return; } if(s == null) { Debug.Assert(false); return; } if(UIUtil.GetGroupsEnabled(lv) && !NativeLib.IsUnix()) { // Only works correctly when groups are present // (lv.ShowGroups is not sufficient) NativeMethods.Scroll(lv, s.ScrollX, s.ScrollY); if(bEnsureSelectedVisible) { Debug.Assert(false); // Unsupported mode combination SetTopVisibleItem(lv, GetTopVisibleItem(lv), true); } } else SetTopVisibleItem(lv, s.TopIndex, bEnsureSelectedVisible); } /// /// Test whether a screen area is at least partially visible. /// /// Area to test. /// Returns true, if the area is at least partially /// visible. Otherwise, false is returned. public static bool IsScreenAreaVisible(Rectangle rect) { try { foreach(Screen scr in Screen.AllScreens) { Rectangle scrBounds = scr.Bounds; if((rect.Left > scrBounds.Right) || (rect.Right < scrBounds.Left) || (rect.Top > scrBounds.Bottom) || (rect.Bottom < scrBounds.Top)) { } else return true; } } catch(Exception) { Debug.Assert(false); return true; } return false; } public static void EnsureInsideScreen(Form f) { if(f == null) { Debug.Assert(false); return; } try { if(!f.Visible) return; // No assert if(f.WindowState != FormWindowState.Normal) return; int x = f.Location.X; int y = f.Location.Y; int w = f.Size.Width; int h = f.Size.Height; Debug.Assert((x != -32000) && (x != -64000)); Debug.Assert(x != AppDefs.InvalidWindowValue); Debug.Assert((y != -32000) && (y != -64000)); Debug.Assert(y != AppDefs.InvalidWindowValue); Debug.Assert(w != AppDefs.InvalidWindowValue); Debug.Assert(h != AppDefs.InvalidWindowValue); Rectangle rect = new Rectangle(x, y, w, h); if(IsScreenAreaVisible(rect)) return; Screen scr = Screen.PrimaryScreen; Rectangle rectScr = scr.Bounds; BoundsSpecified bs = BoundsSpecified.Location; if((w > rectScr.Width) || (h > rectScr.Height)) { w = Math.Min(w, rectScr.Width); h = Math.Min(h, rectScr.Height); bs |= BoundsSpecified.Size; } x = rectScr.X + ((rectScr.Width - w) / 2); y = rectScr.Y + ((rectScr.Height - h) / 2); f.SetBounds(x, y, w, h, bs); } catch(Exception) { Debug.Assert(false); } } public static string GetWindowScreenRect(Form f) { if(f == null) { Debug.Assert(false); return string.Empty; } List l = new List(); Point pt = f.Location; l.Add(pt.X); l.Add(pt.Y); FormBorderStyle s = f.FormBorderStyle; if((s == FormBorderStyle.Sizable) || (s == FormBorderStyle.SizableToolWindow)) { Size sz = f.Size; l.Add(sz.Width); l.Add(sz.Height); if(f.WindowState == FormWindowState.Maximized) l.Add(FwsMaximized); } return StrUtil.SerializeIntArray(l.ToArray()); } public static void SetWindowScreenRect(Form f, string strRect) { if((f == null) || (strRect == null)) { Debug.Assert(false); return; } try { // Backward compatibility (", " as separator) Debug.Assert(StrUtil.SerializeIntArray(new int[] { 12, 34, 56 }) == "12 34 56"); // Should not use ',' string str = strRect.Replace(",", string.Empty); if(str.Length == 0) return; // No assert int[] v = StrUtil.DeserializeIntArray(str); if((v == null) || (v.Length < 2)) { Debug.Assert(false); return; } FormBorderStyle s = f.FormBorderStyle; bool bSizable = ((s == FormBorderStyle.Sizable) || (s == FormBorderStyle.SizableToolWindow)); int ws = ((v.Length <= 4) ? FwsNormal : v[4]); if(ws == FwsMaximized) { if(bSizable && f.MaximizeBox) f.WindowState = FormWindowState.Maximized; else { Debug.Assert(false); } return; // Ignore the saved size; restore to default } else if(ws != FwsNormal) { Debug.Assert(false); return; } bool bSize = ((v.Length >= 4) && (v[2] > 0) && (v[3] > 0) && bSizable); Rectangle rect = new Rectangle(); rect.X = v[0]; rect.Y = v[1]; if(bSize) rect.Size = new Size(v[2], v[3]); else rect.Size = f.Size; if(UIUtil.IsScreenAreaVisible(rect)) { f.Location = rect.Location; if(bSize) f.Size = rect.Size; } } catch(Exception) { Debug.Assert(false); } } public static string SetWindowScreenRectEx(Form f, string strRect) { SetWindowScreenRect(f, strRect); return GetWindowScreenRect(f); } internal static string ScaleWindowScreenRect(string strRect, double sX, double sY) { if(string.IsNullOrEmpty(strRect)) return strRect; try { string str = strRect.Replace(",", string.Empty); // Backward compat. int[] v = StrUtil.DeserializeIntArray(str); if((v == null) || (v.Length < 2)) { Debug.Assert(false); return strRect; } v[0] = (int)Math.Round((double)v[0] * sX); // X v[1] = (int)Math.Round((double)v[1] * sY); // Y if(v.Length >= 4) { v[2] = (int)Math.Round((double)v[2] * sX); // Width v[3] = (int)Math.Round((double)v[3] * sY); // Height } return StrUtil.SerializeIntArray(v); } catch(Exception) { Debug.Assert(false); } return strRect; } public static string GetColumnWidths(ListView lv) { if(lv == null) { Debug.Assert(false); return string.Empty; } int n = lv.Columns.Count; int[] vSizes = new int[n]; for(int i = 0; i < n; ++i) vSizes[i] = lv.Columns[i].Width; return StrUtil.SerializeIntArray(vSizes); } public static void SetColumnWidths(ListView lv, string strSizes) { if(string.IsNullOrEmpty(strSizes)) return; // No assert int[] vSizes = StrUtil.DeserializeIntArray(strSizes); int n = lv.Columns.Count; Debug.Assert(n == vSizes.Length); for(int i = 0; i < Math.Min(n, vSizes.Length); ++i) lv.Columns[i].Width = vSizes[i]; } public static Image SetButtonImage(Button btn, Image img, bool b16To15) { if(btn == null) { Debug.Assert(false); return null; } if(img == null) { Debug.Assert(false); return null; } Image imgNew = img; if(b16To15 && (btn.Height == 23) && (imgNew.Height == 16)) imgNew = GfxUtil.ScaleImage(imgNew, imgNew.Width, 15, ScaleTransformFlags.UIIcon); // if(btn.RightToLeft == RightToLeft.Yes) // { // // Dispose scaled image only // Image imgToDispose = ((imgNew != img) ? imgNew : null); // imgNew = (Image)imgNew.Clone(); // imgNew.RotateFlip(RotateFlipType.RotateNoneFlipX); // if(imgToDispose != null) imgToDispose.Dispose(); // } btn.Image = imgNew; return imgNew; } public static void OverwriteButtonImage(Button btn, ref Image imgCur, Image imgNew) { if(btn == null) { Debug.Assert(false); return; } // imgNew may be null Debug.Assert(object.ReferenceEquals(btn.Image, imgCur)); Image imgPrev = imgCur; btn.Image = imgNew; imgCur = imgNew; if(imgPrev != null) imgPrev.Dispose(); } public static void DisposeButtonImage(Button btn, ref Image imgCur) { if(btn == null) { Debug.Assert(false); return; } Debug.Assert(object.ReferenceEquals(btn.Image, imgCur)); if(imgCur != null) { btn.Image = null; imgCur.Dispose(); imgCur = null; } } internal static void OverwriteIfNotEqual(ref Image imgCur, Image imgNew) { if(object.ReferenceEquals(imgCur, imgNew)) return; if(imgCur != null) imgCur.Dispose(); imgCur = imgNew; } public static void EnableAutoCompletion(ComboBox cb, bool bAlsoAutoAppend) { if(cb == null) { Debug.Assert(false); return; } Debug.Assert(cb.DropDownStyle != ComboBoxStyle.DropDownList); cb.AutoCompleteMode = (bAlsoAutoAppend ? AutoCompleteMode.SuggestAppend : AutoCompleteMode.Suggest); cb.AutoCompleteSource = AutoCompleteSource.ListItems; } public static void EnableAutoCompletion(ToolStripComboBox cb, bool bAlsoAutoAppend) { if(cb == null) { Debug.Assert(false); return; } Debug.Assert(cb.DropDownStyle != ComboBoxStyle.DropDownList); cb.AutoCompleteMode = (bAlsoAutoAppend ? AutoCompleteMode.SuggestAppend : AutoCompleteMode.Suggest); cb.AutoCompleteSource = AutoCompleteSource.ListItems; } public static void SetFocus(Control c, Form fParent) { if(c == null) { Debug.Assert(false); return; } // fParent may be null try { if(fParent != null) fParent.ActiveControl = c; } catch(Exception) { Debug.Assert(false); } try { if(c.CanSelect) c.Select(); if(c.CanFocus) c.Focus(); } catch(Exception) { Debug.Assert(false); } } public static void ResetFocus(Control c, Form fParent) { if(c == null) { Debug.Assert(false); return; } // fParent may be null try { Control cPre = null; if(fParent != null) cPre = fParent.ActiveControl; bool bStdSetFocus = true; if(c == cPre) { // Special reset for password text boxes that // can show a Caps Lock balloon tip; // https://sourceforge.net/p/keepass/feature-requests/1905/ TextBox tb = (c as TextBox); if((tb != null) && !NativeLib.IsUnix()) { IntPtr h = tb.Handle; bool bCapsLock = ((NativeMethods.GetKeyState( NativeMethods.VK_CAPITAL) & 1) != 0); if((h != IntPtr.Zero) && tb.UseSystemPasswordChar && !tb.ReadOnly && bCapsLock) { NativeMethods.SendMessage(h, NativeMethods.WM_KILLFOCUS, IntPtr.Zero, IntPtr.Zero); NativeMethods.SendMessage(h, NativeMethods.WM_SETFOCUS, IntPtr.Zero, IntPtr.Zero); bStdSetFocus = false; } } } if(bStdSetFocus) UIUtil.SetFocus(c, fParent); } catch(Exception) { Debug.Assert(false); } } /// /// Show a modal dialog and destroy it afterwards. /// /// Form to show and destroy. /// Result from ShowDialog. public static DialogResult ShowDialogAndDestroy(Form f) { if(f == null) { Debug.Assert(false); return DialogResult.None; } DialogResult dr = f.ShowDialog(); UIUtil.DestroyForm(f); return dr; } /// /// Show a modal dialog. If the result isn't the specified value, the /// dialog is disposed and true is returned. Otherwise, false /// is returned (without disposing the dialog!). /// /// Dialog to show. /// Comparison value. /// See description. public static bool ShowDialogNotValue(Form f, DialogResult drNotValue) { if(f == null) { Debug.Assert(false); return true; } if(f.ShowDialog() != drNotValue) { UIUtil.DestroyForm(f); return true; } return false; } public static void DestroyForm(Form f) { if(f == null) { Debug.Assert(false); return; } try { // f.Close(); // Don't trigger closing events f.Dispose(); } catch(Exception) { Debug.Assert(false); } } public static Image ExtractVistaIcon(Icon ico) { if(ico == null) { Debug.Assert(false); return null; } MemoryStream ms = new MemoryStream(); try { ico.Save(ms); byte[] pb = ms.ToArray(); return GfxUtil.LoadImage(pb); // Extracts best image from ICO } catch { Debug.Assert(false); } finally { ms.Close(); } return null; } public static void ColorToHsv(Color clr, out float fHue, out float fSaturation, out float fValue) { int nMax = Math.Max(clr.R, Math.Max(clr.G, clr.B)); int nMin = Math.Min(clr.R, Math.Min(clr.G, clr.B)); fHue = clr.GetHue(); // In degrees fSaturation = ((nMax == 0) ? 0.0f : (1.0f - ((float)nMin / nMax))); fValue = (float)nMax / 255.0f; } public static Color ColorFromHsv(float fHue, float fSaturation, float fValue) { float d = fHue / 60; float fl = (float)Math.Floor(d); float f = d - fl; fValue *= 255.0f; int v = (int)fValue; int p = (int)(fValue * (1.0f - fSaturation)); int q = (int)(fValue * (1.0f - (fSaturation * f))); int t = (int)(fValue * (1.0f - (fSaturation * (1.0f - f)))); try { int hi = (int)fl % 6; if(hi == 0) return Color.FromArgb(255, v, t, p); if(hi == 1) return Color.FromArgb(255, q, v, p); if(hi == 2) return Color.FromArgb(255, p, v, t); if(hi == 3) return Color.FromArgb(255, p, q, v); if(hi == 4) return Color.FromArgb(255, t, p, v); return Color.FromArgb(255, v, p, q); } catch(Exception) { Debug.Assert(false); } return Color.Transparent; } public static Bitmap IconToBitmap(Icon ico, int w, int h) { if(ico == null) { Debug.Assert(false); return null; } if(w < 0) w = ico.Width; if(h < 0) h = ico.Height; Bitmap bmp = new Bitmap(w, h, PixelFormat.Format32bppArgb); using(Icon icoBest = new Icon(ico, w, h)) { using(Graphics g = Graphics.FromImage(bmp)) { g.Clear(Color.Transparent); g.InterpolationMode = InterpolationMode.HighQualityBicubic; g.SmoothingMode = SmoothingMode.HighQuality; g.DrawIcon(icoBest, new Rectangle(0, 0, w, h)); } } return bmp; } public static Icon BitmapToIcon(Bitmap bmp) { if(bmp == null) { Debug.Assert(false); return null; } Icon ico = null; IntPtr hIcon = IntPtr.Zero; try { hIcon = bmp.GetHicon(); using(Icon icoNoOwn = Icon.FromHandle(hIcon)) { ico = (Icon)icoNoOwn.Clone(); } } catch(Exception) { Debug.Assert(false); } finally { if(hIcon != IntPtr.Zero) { try { NativeMethods.DestroyIcon(hIcon); } catch(Exception) { Debug.Assert(NativeLib.IsUnix()); } } } return ico; } /* public static Icon CreateColorizedIcon(Icon icoBase, Color clr, int qSize) { if(icoBase == null) { Debug.Assert(false); return null; } if(qSize <= 0) qSize = 48; // Large shell icon size Bitmap bmp = null; try { bmp = new Bitmap(qSize, qSize, PixelFormat.Format32bppArgb); using(Graphics g = Graphics.FromImage(bmp)) { g.Clear(Color.Transparent); g.InterpolationMode = InterpolationMode.HighQualityBicubic; g.SmoothingMode = SmoothingMode.HighQuality; bool bDrawDefault = true; if((qSize != 16) && (qSize != 32)) { Image imgIco = ExtractVistaIcon(icoBase); if(imgIco != null) { // g.DrawImage(imgIco, 0, 0, bmp.Width, bmp.Height); using(Image imgSc = GfxUtil.ScaleImage(imgIco, bmp.Width, bmp.Height, ScaleTransformFlags.UIIcon)) { g.DrawImageUnscaled(imgSc, 0, 0); } imgIco.Dispose(); bDrawDefault = false; } } if(bDrawDefault) { Icon icoSc = null; try { icoSc = new Icon(icoBase, bmp.Width, bmp.Height); g.DrawIcon(icoSc, new Rectangle(0, 0, bmp.Width, bmp.Height)); } catch(Exception) { Debug.Assert(false); g.DrawIcon(icoBase, new Rectangle(0, 0, bmp.Width, bmp.Height)); } finally { if(icoSc != null) icoSc.Dispose(); } } // IntPtr hdc = g.GetHdc(); // NativeMethods.DrawIconEx(hdc, 0, 0, icoBase.Handle, bmp.Width, // bmp.Height, 0, IntPtr.Zero, NativeMethods.DI_NORMAL); // g.ReleaseHdc(hdc); } BitmapData bd = bmp.LockBits(new Rectangle(0, 0, bmp.Width, bmp.Height), ImageLockMode.ReadWrite, PixelFormat.Format32bppArgb); int nBytes = Math.Abs(bd.Stride * bmp.Height); byte[] pbArgb = new byte[nBytes]; Marshal.Copy(bd.Scan0, pbArgb, 0, nBytes); float fHue, fSaturation, fValue; ColorToHsv(clr, out fHue, out fSaturation, out fValue); for(int i = 0; i < nBytes; i += 4) { if(pbArgb[i + 3] == 0) continue; // Transparent if((pbArgb[i] == pbArgb[i + 1]) && (pbArgb[i] == pbArgb[i + 2])) continue; // Gray Color clrPixel = Color.FromArgb((int)pbArgb[i + 2], (int)pbArgb[i + 1], (int)pbArgb[i]); // BGRA float h, s, v; ColorToHsv(clrPixel, out h, out s, out v); Color clrNew = ColorFromHsv(fHue, s, v); pbArgb[i] = clrNew.B; pbArgb[i + 1] = clrNew.G; pbArgb[i + 2] = clrNew.R; } Marshal.Copy(pbArgb, 0, bd.Scan0, nBytes); bmp.UnlockBits(bd); return BitmapToIcon(bmp); } catch(Exception) { Debug.Assert(false); } finally { if(bmp != null) bmp.Dispose(); } return (Icon)icoBase.Clone(); } */ private static Bitmap CloneWithColorMatrix(Image img, ColorMatrix cm) { if(img == null) { Debug.Assert(false); return null; } if(cm == null) { Debug.Assert(false); return null; } try { int w = img.Width, h = img.Height; Bitmap bmp = new Bitmap(w, h, PixelFormat.Format32bppArgb); using(Graphics g = Graphics.FromImage(bmp)) { g.Clear(Color.Transparent); g.InterpolationMode = InterpolationMode.NearestNeighbor; g.SmoothingMode = SmoothingMode.None; ImageAttributes a = new ImageAttributes(); a.SetColorMatrix(cm); g.DrawImage(img, new Rectangle(0, 0, w, h), 0, 0, w, h, GraphicsUnit.Pixel, a); } return bmp; } catch(Exception) { Debug.Assert(false); } return null; } public static Bitmap InvertImage(Image img) { ColorMatrix cm = new ColorMatrix(new float[][] { new float[] { -1, 0, 0, 0, 0 }, new float[] { 0, -1, 0, 0, 0 }, new float[] { 0, 0, -1, 0, 0 }, new float[] { 0, 0, 0, 1, 0 }, new float[] { 1, 1, 1, 0, 1 } }); return CloneWithColorMatrix(img, cm); } public static Bitmap CreateGrayImage(Image img) { ColorMatrix cm = new ColorMatrix(new float[][] { new float[] { 0.30f, 0.30f, 0.30f, 0, 0 }, new float[] { 0.59f, 0.59f, 0.59f, 0, 0 }, new float[] { 0.11f, 0.11f, 0.11f, 0, 0 }, new float[] { 0, 0, 0, 1, 0 }, new float[] { 0, 0, 0, 0, 1 } }); return CloneWithColorMatrix(img, cm); } public static Image CreateTabColorImage(Color clr, TabControl cTab) { if(cTab == null) { Debug.Assert(false); return null; } int qSize = cTab.ItemSize.Height - 3; if(MonoWorkarounds.IsRequired()) qSize -= 1; if(qSize < 4) { Debug.Assert(false); return null; } const int dyTrans = 3; int yCenter = (qSize - dyTrans) / 2 + dyTrans; Rectangle rectTop = new Rectangle(0, dyTrans, qSize, yCenter - dyTrans); Rectangle rectBottom = new Rectangle(0, yCenter, qSize, qSize - yCenter); Color clrLight = UIUtil.LightenColor(clr, 0.5); Color clrDark = UIUtil.DarkenColor(clr, 0.1); Bitmap bmp = new Bitmap(qSize, qSize, PixelFormat.Format32bppArgb); using(Graphics g = Graphics.FromImage(bmp)) { g.Clear(Color.Transparent); using(LinearGradientBrush brLight = new LinearGradientBrush( rectTop, clrLight, clr, LinearGradientMode.Vertical)) { g.FillRectangle(brLight, rectTop); } using(LinearGradientBrush brDark = new LinearGradientBrush( rectBottom, clr, clrDark, LinearGradientMode.Vertical)) { g.FillRectangle(brDark, rectBottom); } } return bmp; } public static bool PlayUacSound() { try { string strRoot = "HKEY_CURRENT_USER\\AppEvents\\Schemes\\Apps\\.Default\\WindowsUAC\\"; string strWav = (Registry.GetValue(strRoot + ".Current", string.Empty, string.Empty) as string); if(string.IsNullOrEmpty(strWav)) strWav = (Registry.GetValue(strRoot + ".Default", string.Empty, string.Empty) as string); if(string.IsNullOrEmpty(strWav)) strWav = @"%SystemRoot%\Media\Windows User Account Control.wav"; strWav = SprEngine.Compile(strWav, null); if(!File.Exists(strWav)) throw new FileNotFoundException(); NativeMethods.PlaySound(strWav, IntPtr.Zero, NativeMethods.SND_FILENAME | NativeMethods.SND_ASYNC | NativeMethods.SND_NODEFAULT); return true; } catch(Exception) { } Debug.Assert(NativeLib.IsUnix() || !WinUtil.IsAtLeastWindowsVista); // Do not play a standard sound here return false; } public static Image GetWindowImage(IntPtr hWnd, bool bPrefSmall) { try { IntPtr hIcon; if(bPrefSmall) { hIcon = NativeMethods.SendMessage(hWnd, NativeMethods.WM_GETICON, new IntPtr(NativeMethods.ICON_SMALL2), IntPtr.Zero); if(hIcon != IntPtr.Zero) return Icon.FromHandle(hIcon).ToBitmap(); } hIcon = NativeMethods.SendMessage(hWnd, NativeMethods.WM_GETICON, new IntPtr(bPrefSmall ? NativeMethods.ICON_SMALL : NativeMethods.ICON_BIG), IntPtr.Zero); if(hIcon != IntPtr.Zero) return Icon.FromHandle(hIcon).ToBitmap(); hIcon = NativeMethods.GetClassLongPtr(hWnd, bPrefSmall ? NativeMethods.GCLP_HICONSM : NativeMethods.GCLP_HICON); if(hIcon != IntPtr.Zero) return Icon.FromHandle(hIcon).ToBitmap(); hIcon = NativeMethods.SendMessage(hWnd, NativeMethods.WM_GETICON, new IntPtr(bPrefSmall ? NativeMethods.ICON_BIG : NativeMethods.ICON_SMALL), IntPtr.Zero); if(hIcon != IntPtr.Zero) return Icon.FromHandle(hIcon).ToBitmap(); hIcon = NativeMethods.GetClassLongPtr(hWnd, bPrefSmall ? NativeMethods.GCLP_HICON : NativeMethods.GCLP_HICONSM); if(hIcon != IntPtr.Zero) return Icon.FromHandle(hIcon).ToBitmap(); if(!bPrefSmall) { hIcon = NativeMethods.SendMessage(hWnd, NativeMethods.WM_GETICON, new IntPtr(NativeMethods.ICON_SMALL2), IntPtr.Zero); if(hIcon != IntPtr.Zero) return Icon.FromHandle(hIcon).ToBitmap(); } } catch(Exception) { Debug.Assert(false); } return null; } /// /// Set the state of a window. This is a workaround for /// https://sourceforge.net/projects/keepass/forums/forum/329221/topic/4610118 /// public static void SetWindowState(Form f, FormWindowState fws) { if(f == null) { Debug.Assert(false); return; } f.WindowState = fws; // If the window state change / resize handler changes // the window state again, the property gets out of sync // with the real state. Therefore, we now make sure that // the property is synchronized with the actual window // state. try { // Get the value that .NET currently caches; note // this isn't necessarily the real window state // due to the bug FormWindowState fwsCached = f.WindowState; IntPtr hWnd = f.Handle; if(hWnd == IntPtr.Zero) { Debug.Assert(false); return; } // Get the real state using Windows API functions bool bIsRealMin = NativeMethods.IsIconic(hWnd); bool bIsRealMax = NativeMethods.IsZoomed(hWnd); FormWindowState? fwsFix = null; if(bIsRealMin && (fwsCached != FormWindowState.Minimized)) fwsFix = FormWindowState.Minimized; else if(bIsRealMax && (fwsCached != FormWindowState.Maximized) && !bIsRealMin) fwsFix = FormWindowState.Maximized; else if(!bIsRealMin && !bIsRealMax && (fwsCached != FormWindowState.Normal)) fwsFix = FormWindowState.Normal; if(fwsFix.HasValue) { // If the window is invisible, no state // change / resize handlers are called bool bVisible = f.Visible; if(bVisible) f.Visible = false; f.WindowState = fwsFix.Value; if(bVisible) f.Visible = true; } } catch(Exception) { Debug.Assert(NativeLib.IsUnix()); } } private static KeysConverter m_convKeys = null; public static string GetKeysName(Keys k) { if(m_convKeys == null) m_convKeys = new KeysConverter(); return m_convKeys.ConvertToString(k); } /// /// Assign shortcut keys to a menu item. This method uses /// custom-translated display strings. /// public static void AssignShortcut(ToolStripMenuItem tsmi, Keys k) { if(tsmi == null) { Debug.Assert(false); return; } tsmi.ShortcutKeys = k; string str = string.Empty; if((k & Keys.Control) != Keys.None) str += KPRes.KeyboardKeyCtrl + "+"; if((k & Keys.Alt) != Keys.None) str += KPRes.KeyboardKeyAlt + "+"; if((k & Keys.Shift) != Keys.None) str += KPRes.KeyboardKeyShift + "+"; str += GetKeysName(k & Keys.KeyCode); tsmi.ShortcutKeyDisplayString = str; } public static void SetFocusedItem(ListView lv, ListViewItem lvi, bool bAlsoSelect) { if((lv == null) || (lvi == null)) { Debug.Assert(false); return; } if(bAlsoSelect) lvi.Selected = true; try { lv.FocusedItem = lvi; } // .NET catch(Exception) { try { lvi.Focused = true; } // Mono catch(Exception) { Debug.Assert(false); } } } public static Image CreateDropDownImage(Image imgBase) { if(imgBase == null) { Debug.Assert(false); return null; } // Height of the arrow without the glow effect // int hArrow = (int)Math.Ceiling((double)DpiUtil.ScaleIntY(20) / 8.0); // int hArrow = (int)Math.Ceiling((double)DpiUtil.ScaleIntY(28) / 8.0); int hArrow = DpiUtil.ScaleIntY(3); int dx = imgBase.Width, dy = imgBase.Height; if((dx < ((hArrow * 2) + 2)) || (dy < (hArrow + 2))) return new Bitmap(imgBase); bool bRtl = Program.Translation.Properties.RightToLeft; bool bStdClr = !UIUtil.IsDarkTheme; Bitmap bmp = new Bitmap(dx, dy, PixelFormat.Format32bppArgb); using(Graphics g = Graphics.FromImage(bmp)) { g.Clear(Color.Transparent); g.DrawImageUnscaled(imgBase, 0, 0); // Pen penDark = Pens.Black; // g.DrawLine(penDark, dx - 5, dy - 3, dx - 1, dy - 3); // g.DrawLine(penDark, dx - 4, dy - 2, dx - 2, dy - 2); // // g.DrawLine(penDark, dx - 7, dy - 4, dx - 1, dy - 4); // // g.DrawLine(penDark, dx - 6, dy - 3, dx - 2, dy - 3); // // g.DrawLine(penDark, dx - 5, dy - 2, dx - 3, dy - 2); // using(Pen penLight = new Pen(Color.FromArgb( // 160, 255, 255, 255), 1.0f)) // { // g.DrawLine(penLight, dx - 5, dy - 4, dx - 1, dy - 4); // g.DrawLine(penLight, dx - 6, dy - 3, dx - 4, dy - 1); // g.DrawLine(penLight, dx - 2, dy - 1, dx - 1, dy - 2); // // g.DrawLine(penLight, dx - 7, dy - 5, dx - 1, dy - 5); // // g.DrawLine(penLight, dx - 8, dy - 4, dx - 5, dy - 1); // // g.DrawLine(penLight, dx - 3, dy - 1, dx - 1, dy - 3); // } g.SmoothingMode = SmoothingMode.None; if(bRtl) { g.ScaleTransform(-1, 1); g.TranslateTransform(-dx + 1, 0); } Pen penDark = (bStdClr ? Pens.Black : Pens.White); for(int i = 1; i < hArrow; ++i) g.DrawLine(penDark, dx - hArrow - i, dy - 1 - i, dx - hArrow + i, dy - 1 - i); int c = (bStdClr ? 255 : 0); using(Pen penLight = new Pen(Color.FromArgb(160, c, c, c), 1.0f)) { g.DrawLine(penLight, dx - (hArrow * 2) + 1, dy - hArrow - 1, dx - 1, dy - hArrow - 1); g.DrawLine(penLight, dx - (hArrow * 2), dy - hArrow, dx - hArrow - 1, dy - 1); g.DrawLine(penLight, dx - hArrow + 1, dy - 1, dx - 1, dy - hArrow + 1); } } // bmp.SetPixel(dx - 3, dy - 1, Color.Black); // // bmp.SetPixel(dx - 4, dy - 1, Color.Black); bmp.SetPixel((bRtl ? (hArrow - 1) : (dx - hArrow)), dy - 1, (bStdClr ? Color.Black : Color.White)); return bmp; } [Obsolete("Use GfxUtil.ScaleImage instead.")] public static Bitmap CreateScaledImage(Image img, int w, int h) { if(img == null) { Debug.Assert(false); return null; } Bitmap bmp = (GfxUtil.ScaleImage(img, w, h) as Bitmap); Debug.Assert(bmp != null); return bmp; } /* public static T DgvGetComboBoxValue(DataGridViewComboBoxCell c, List> lItems) { if((c == null) || (lItems == null)) { Debug.Assert(false); return default(T); } string strValue = ((c.Value as string) ?? string.Empty); foreach(KeyValuePair kvp in lItems) { if(kvp.Value == strValue) return kvp.Key; } Debug.Assert(false); return default(T); } public static void DgvSetComboBoxValue(DataGridViewComboBoxCell c, T tValue, List> lItems) { if((c == null) || (lItems == null)) { Debug.Assert(false); return; } foreach(KeyValuePair kvp in lItems) { if(kvp.Key.Equals(tValue)) { c.Value = kvp.Value; return; } } Debug.Assert(false); } public static bool GetChecked(DataGridViewCheckBoxCell c) { if(c == null) { Debug.Assert(false); return false; } object o = c.Value; if(o == null) { Debug.Assert(false); return false; } return StrUtil.StringToBool(o.ToString()); } public static void SetChecked(DataGridViewCheckBoxCell c, bool bChecked) { if(c == null) { Debug.Assert(false); return; } c.Value = bChecked; } */ public static Image GetFileIcon(string strFilePath, int w, int h) { Image img = null; try { Icon ico = Icon.ExtractAssociatedIcon(strFilePath); if(ico == null) return null; img = new Bitmap(w, h, PixelFormat.Format32bppArgb); using(Graphics g = Graphics.FromImage(img)) { g.Clear(Color.Transparent); g.InterpolationMode = InterpolationMode.HighQualityBicubic; g.SmoothingMode = SmoothingMode.HighQuality; g.DrawIcon(ico, new Rectangle(0, 0, img.Width, img.Height)); } ico.Dispose(); } catch(Exception) { Debug.Assert(NativeLib.IsUnix()); } return img; } public static void SetHandled(KeyEventArgs e, bool bHandled) { if(e == null) { Debug.Assert(false); return; } e.Handled = bHandled; e.SuppressKeyPress = bHandled; } public static bool HandleCommonKeyEvent(KeyEventArgs e, bool bDown, Control cCtx) { if(e == null) { Debug.Assert(false); return false; } if(cCtx == null) { Debug.Assert(false); return false; } // On Windows, all of the following is already supported by .NET if(!NativeLib.IsUnix()) return false; bool bS = e.Shift; bool bC = e.Control; bool bA = e.Alt; Keys k = e.KeyCode; bool bMac = (NativeLib.GetPlatformID() == PlatformID.MacOSX); if(((k == Keys.Apps) && !bA) || // Shift and Control irrelevant ((k == Keys.F10) && bS && !bA) || // Control irrelevant (bMac && (k == Keys.D5) && bC && bA) || (bMac && (k == Keys.NumPad5) && bC)) { bool bOp = bDown; if(k == Keys.Apps) bOp = !bDown; if(bOp) { ContextMenu cm = cCtx.ContextMenu; ContextMenuStrip cms = cCtx.ContextMenuStrip; if(cms != null) cms.Show(Cursor.Position); else if(cm != null) { Point pt = cCtx.PointToClient(Cursor.Position); cm.Show(cCtx, pt); } } UIUtil.SetHandled(e, true); return true; } return false; } public static Size GetIconSize() { #if DEBUG if(!NativeLib.IsUnix()) { Debug.Assert(SystemInformation.IconSize.Width == DpiUtil.ScaleIntX(32)); Debug.Assert(SystemInformation.IconSize.Height == DpiUtil.ScaleIntY(32)); } #endif try { return SystemInformation.IconSize; } catch(Exception) { Debug.Assert(NativeLib.IsUnix()); } return new Size(DpiUtil.ScaleIntX(32), DpiUtil.ScaleIntY(32)); } public static Size GetSmallIconSize() { #if DEBUG if(!NativeLib.IsUnix()) { Debug.Assert(SystemInformation.SmallIconSize.Width == DpiUtil.ScaleIntX(16)); Debug.Assert(SystemInformation.SmallIconSize.Height == DpiUtil.ScaleIntY(16)); } #endif // Throws under Mono 4.2.1 on Mac OS X; // https://sourceforge.net/p/keepass/discussion/329221/thread/7c096cfc/ try { return SystemInformation.SmallIconSize; } catch(Exception) { Debug.Assert(NativeLib.IsUnix()); } return new Size(DpiUtil.ScaleIntX(16), DpiUtil.ScaleIntY(16)); } /* internal static bool HasClickedSeparator(ToolStripItemClickedEventArgs e) { if(e == null) { Debug.Assert(false); return false; } ToolStripSeparator ts = (e.ClickedItem as ToolStripSeparator); if(ts == null) return false; Debug.Assert(!(e.ClickedItem is ToolStripMenuItem)); return true; } */ public static void RemoveBannerIfNecessary(Form f) { if(f == null) { Debug.Assert(false); return; } try { Screen s = Screen.FromControl(f); if(s == null) { Debug.Assert(false); return; } int hForm = f.Height; if(s.WorkingArea.Height >= hForm) return; PictureBox pbBanner = null; foreach(Control c in f.Controls) { if(c == null) { Debug.Assert(false); continue; } #if DEBUG if(c.Name == "m_bannerImage") { Debug.Assert(c is PictureBox); Debug.Assert(c.Dock == DockStyle.Top); Debug.Assert(c.Visible); } #endif PictureBox pb = (c as PictureBox); if(pb != null) { if(pb.Dock != DockStyle.Top) continue; // Check whether there are multiple picture // boxes that could be the dialog banner if(pbBanner != null) { Debug.Assert(false); return; } pbBanner = pb; // No break } } if(pbBanner == null) return; // No assert Debug.Assert(pbBanner.Name == "m_bannerImage"); int dy = pbBanner.Height; if((dy <= 0) || (dy >= hForm)) { Debug.Assert(false); return; } f.SuspendLayout(); try { pbBanner.Visible = false; foreach(Control c in f.Controls) { if(c == null) { Debug.Assert(false); } else if(c != pbBanner) { Point pt = c.Location; c.Location = new Point(pt.X, pt.Y - dy); } } f.Height = hForm - dy; } catch(Exception) { Debug.Assert(false); } finally { f.ResumeLayout(); } } catch(Exception) { Debug.Assert(false); } } internal static void StrDictListInit(ListView lv) { if(lv == null) { Debug.Assert(false); return; } int w = (lv.ClientSize.Width - GetVScrollBarWidth()) / 2; lv.Columns.Add(KPRes.Name, w); lv.Columns.Add(KPRes.Value, w); } internal static void StrDictListUpdate(ListView lv, StringDictionaryEx sd) { if((lv == null) || (sd == null)) { Debug.Assert(false); return; } UIScrollInfo si = GetScrollInfo(lv, true); lv.BeginUpdate(); lv.Items.Clear(); foreach(KeyValuePair kvp in sd) { if(kvp.Key == null) { Debug.Assert(false); continue; } string strValue = StrUtil.MultiToSingleLine(StrUtil.CompactString3Dots( kvp.Value ?? string.Empty, 1024)); ListViewItem lvi = lv.Items.Add(kvp.Key); lvi.SubItems.Add(strValue); } Scroll(lv, si, true); lv.EndUpdate(); } internal static void StrDictListDeleteSel(ListView lv, StringDictionaryEx sd) { if((lv == null) || (sd == null)) { Debug.Assert(false); return; } ListView.SelectedListViewItemCollection lvsic = lv.SelectedItems; if((lvsic == null) || (lvsic.Count <= 0)) return; foreach(ListViewItem lvi in lvsic) { if(lvi == null) { Debug.Assert(false); continue; } string strName = lvi.Text; if(strName == null) { Debug.Assert(false); continue; } if(!sd.Remove(strName)) { Debug.Assert(false); } } StrDictListUpdate(lv, sd); } public static void SetText(Control c, string strText) { if(c == null) { Debug.Assert(false); return; } if(strText == null) { Debug.Assert(false); strText = string.Empty; } using(RtlAwareResizeScope r = new RtlAwareResizeScope(c)) { c.Text = strText; } } internal static int GetEntryIconIndex(PwDatabase pd, PwEntry pe, DateTime dtNow) { if(pe == null) { Debug.Assert(false); return (int)PwIcon.Key; } if(pe.Expires && (pe.ExpiryTime <= dtNow)) return (int)PwIcon.Expired; if(pe.CustomIconUuid == PwUuid.Zero) return (int)pe.IconId; int i = -1; if(pd != null) i = pd.GetCustomIconIndex(pe.CustomIconUuid); else { Debug.Assert(false); } if(i >= 0) return ((int)PwIcon.Count + i); Debug.Assert(false); return (int)pe.IconId; } internal static void SetView(ListView lv, View v) { if(lv == null) { Debug.Assert(false); return; } if(lv.View != v) lv.View = v; } } } KeePass/UI/SplitButtonEx.cs0000664000000000000000000000560013222430414014535 0ustar rootroot/* KeePass Password Safe - The Open-Source Password Manager Copyright (C) 2003-2018 Dominik Reichl This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ using System; using System.Collections.Generic; using System.Text; using System.Drawing; using System.Windows.Forms; using System.ComponentModel; using System.Diagnostics; using KeePass.Native; using KeePass.Util; namespace KeePass.UI { public sealed class SplitButtonEx : Button { private const int BS_SPLITBUTTON = 0x0000000C; // private const int BS_LEFTTEXT = 0x00000020; // private const int BS_RIGHT = 0x00000200; private const uint BCN_FIRST = unchecked((uint)(-1250)); private const uint BCN_DROPDOWN = (BCN_FIRST + 0x0002); private readonly bool m_bSupported; private CustomContextMenuStripEx m_ctx = null; [Browsable(false)] [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] public CustomContextMenuStripEx SplitDropDownMenu { get { return m_ctx; } set { m_ctx = value; } } [Browsable(false)] [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] protected override CreateParams CreateParams { get { CreateParams cp = base.CreateParams; if(m_bSupported) { int fAdd = BS_SPLITBUTTON; // if(this.RightToLeft == RightToLeft.Yes) // fAdd |= (BS_LEFTTEXT | BS_RIGHT); cp.Style |= fAdd; } return cp; } } public SplitButtonEx() : base() { m_bSupported = (WinUtil.IsAtLeastWindowsVista && !KeePassLib.Native.NativeLib.IsUnix() && !Program.DesignMode); if(m_bSupported) { this.FlatStyle = FlatStyle.System; } } protected override void WndProc(ref Message m) { if((m.Msg == NativeMethods.WM_NOTIFY_REFLECT) && m_bSupported) { try { NativeMethods.NMHDR nm = (NativeMethods.NMHDR)m.GetLParam( typeof(NativeMethods.NMHDR)); if(nm.code == BCN_DROPDOWN) { if(m_ctx != null) { m_ctx.ShowEx(this); return; // We handled it } else { Debug.Assert(false); } } } catch(Exception) { Debug.Assert(false); } } base.WndProc(ref m); } } } KeePass/UI/DpiUtil.cs0000664000000000000000000001744013224374410013335 0ustar rootroot/* KeePass Password Safe - The Open-Source Password Manager Copyright (C) 2003-2018 Dominik Reichl This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ using System; using System.Collections.Generic; using System.Collections.Specialized; using System.Diagnostics; using System.Drawing; using System.Drawing.Drawing2D; using System.Drawing.Imaging; using System.IO; using System.Reflection; using System.Text; using System.Windows.Forms; using KeePass.Native; using KeePass.Util; using KeePassLib; using KeePassLib.Utility; using NativeLib = KeePassLib.Native.NativeLib; namespace KeePass.UI { public static class DpiUtil { private const int StdDpi = 96; private static bool m_bInitialized = false; private static int m_nDpiX = StdDpi; private static int m_nDpiY = StdDpi; private static double m_dScaleX = 1.0; public static double FactorX { get { EnsureInitialized(); return m_dScaleX; } } private static double m_dScaleY = 1.0; public static double FactorY { get { EnsureInitialized(); return m_dScaleY; } } public static bool ScalingRequired { get { if(Program.DesignMode) return false; EnsureInitialized(); return ((m_nDpiX != StdDpi) || (m_nDpiY != StdDpi)); } } private static void EnsureInitialized() { if(m_bInitialized) return; if(NativeLib.IsUnix()) { m_bInitialized = true; return; } try { IntPtr hDC = NativeMethods.GetDC(IntPtr.Zero); if(hDC != IntPtr.Zero) { m_nDpiX = NativeMethods.GetDeviceCaps(hDC, NativeMethods.LOGPIXELSX); m_nDpiY = NativeMethods.GetDeviceCaps(hDC, NativeMethods.LOGPIXELSY); if((m_nDpiX <= 0) || (m_nDpiY <= 0)) { Debug.Assert(false); m_nDpiX = StdDpi; m_nDpiY = StdDpi; } if(NativeMethods.ReleaseDC(IntPtr.Zero, hDC) != 1) { Debug.Assert(false); } } else { Debug.Assert(false); } } catch(Exception) { Debug.Assert(false); } m_dScaleX = (double)m_nDpiX / (double)StdDpi; m_dScaleY = (double)m_nDpiY / (double)StdDpi; m_bInitialized = true; } public static void ConfigureProcess() { Debug.Assert(!m_bInitialized); // Configure process before use if(NativeLib.IsUnix()) return; // try // { // ConfigurationManager.AppSettings.Set( // "EnableWindowsFormsHighDpiAutoResizing", "true"); // } // catch(Exception) { Debug.Assert(false); } #if DEBUG // Ensure that the .config file enables high DPI features string strExeConfig = WinUtil.GetExecutable() + ".config"; if(File.Exists(strExeConfig)) { string strCM = "System.Configuration.ConfigurationManager, "; strCM += "System.Configuration, Version="; strCM += Environment.Version.Major.ToString() + ".0.0.0, "; strCM += "Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a"; Type tCM = Type.GetType(strCM, false); if(tCM != null) { PropertyInfo pi = tCM.GetProperty("AppSettings", (BindingFlags.Public | BindingFlags.Static)); if(pi != null) { NameValueCollection nvc = (pi.GetValue(null, null) as NameValueCollection); if(nvc != null) { Debug.Assert(string.Equals(nvc.Get( "EnableWindowsFormsHighDpiAutoResizing"), "true", StrUtil.CaseIgnoreCmp)); } else { Debug.Assert(false); } } else { Debug.Assert(false); } } else { Debug.Assert(false); } // Assembly should be loaded } #endif try { // SetProcessDPIAware is obsolete; use // SetProcessDpiAwareness on Windows 10 and higher if(WinUtil.IsAtLeastWindows10) // 8.1 partially { if(NativeMethods.SetProcessDpiAwareness( NativeMethods.ProcessDpiAwareness.SystemAware) < 0) { Debug.Assert(false); } } else if(WinUtil.IsAtLeastWindowsVista) { if(!NativeMethods.SetProcessDPIAware()) { Debug.Assert(false); } } } catch(Exception) { Debug.Assert(false); } } internal static void Configure(ToolStrip ts) { if(ts == null) { Debug.Assert(false); return; } if(!DpiUtil.ScalingRequired) return; Size sz = ts.ImageScalingSize; if((sz.Width == 16) && (sz.Height == 16)) { sz.Width = ScaleIntX(16); sz.Height = ScaleIntY(16); ts.ImageScalingSize = sz; } else { Debug.Assert(((sz.Width == ScaleIntX(16)) && (sz.Height == ScaleIntY(16))), sz.ToString()); } } public static int ScaleIntX(int i) { EnsureInitialized(); return (int)Math.Round((double)i * m_dScaleX); } public static int ScaleIntY(int i) { EnsureInitialized(); return (int)Math.Round((double)i * m_dScaleY); } public static Image ScaleImage(Image img, bool bForceNewObject) { if(img == null) { Debug.Assert(false); return null; } // EnsureInitialized(); // Done by ScaleIntX int w = img.Width; int h = img.Height; int sw = ScaleIntX(w); int sh = ScaleIntY(h); if((w == sw) && (h == sh) && !bForceNewObject) return img; return GfxUtil.ScaleImage(img, sw, sh, ScaleTransformFlags.UIIcon); } internal static void ScaleToolStripItems(ToolStripItem[] vItems, int[] vWidths) { if(vItems == null) { Debug.Assert(false); return; } if(vWidths == null) { Debug.Assert(false); return; } if(vItems.Length != vWidths.Length) { Debug.Assert(false); return; } for(int i = 0; i < vItems.Length; ++i) { ToolStripItem tsi = vItems[i]; if(tsi == null) { Debug.Assert(false); continue; } int nWidth = vWidths[i]; int nWidthScaled = ScaleIntX(nWidth); Debug.Assert(nWidth >= 0); if(nWidth == nWidthScaled) { Debug.Assert(tsi.Width == nWidth); continue; } try { int w = tsi.Width; // .NET scales some ToolStripItems, some not Debug.Assert(((w == nWidth) || (w == nWidthScaled)), tsi.Name + ": w = " + w.ToString()); if(Math.Abs(w - nWidth) < Math.Abs(w - nWidthScaled)) tsi.Width = nWidthScaled; } catch(Exception) { Debug.Assert(false); } } } internal static Image GetIcon(PwDatabase pd, PwUuid pwUuid) { if(pd == null) { Debug.Assert(false); return null; } if(pwUuid == null) { Debug.Assert(false); return null; } int w = ScaleIntX(16); int h = ScaleIntY(16); return pd.GetCustomIcon(pwUuid, w, h); } [Conditional("DEBUG")] internal static void AssertUIImage(Image img) { #if DEBUG if(img == null) { Debug.Assert(false); return; } EnsureInitialized(); try { // Windows XP scales images based on the DPI resolution // specified in the image file; thus ensure that the // image file does not specify a DPI resolution; // https://sourceforge.net/p/keepass/bugs/1487/ int d = (int)Math.Round(img.HorizontalResolution); Debug.Assert((d == 0) || (d == m_nDpiX)); d = (int)Math.Round(img.VerticalResolution); Debug.Assert((d == 0) || (d == m_nDpiY)); } catch(Exception) { Debug.Assert(false); } #endif } } } KeePass/UI/RichTextBuilder.cs0000664000000000000000000001673313222430414015023 0ustar rootroot/* KeePass Password Safe - The Open-Source Password Manager Copyright (C) 2003-2018 Dominik Reichl This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ using System; using System.Collections.Generic; using System.Diagnostics; using System.Drawing; using System.Text; using System.Text.RegularExpressions; using System.Windows.Forms; using KeePassLib.Utility; namespace KeePass.UI { public sealed class RichTextBuilder { private StringBuilder m_sb = new StringBuilder(); private static List m_vTags = null; private sealed class RtfbTag { public string IdCode { get; private set; } public string RtfCode { get; private set; } public bool StartTag { get; private set; } public FontStyle Style { get; private set; } public RtfbTag(string strId, string strRtf, bool bStartTag, FontStyle fs) { if(string.IsNullOrEmpty(strId)) strId = GenerateRandomIdCode(); this.IdCode = strId; this.RtfCode = strRtf; this.StartTag = bStartTag; this.Style = fs; } internal static string GenerateRandomIdCode() { StringBuilder sb = new StringBuilder(15); // 1 + 12 + 2 Random r = Program.GlobalRandom; // On Hebrew systems, IDs starting with digits break // the RTF generation; for safety, we do not use // digits at all sb.Append((char)('A' + r.Next(26))); for(int i = 0; i < 12; ++i) { int n = r.Next(52); // 62 if(n < 26) sb.Append((char)('A' + n)); // else if(n < 52) else sb.Append((char)('a' + (n - 26))); // else sb.Append((char)('0' + (n - 52))); } return sb.ToString(); } #if DEBUG // For debugger display public override string ToString() { return (this.IdCode + " => " + (this.RtfCode ?? string.Empty)); } #endif } private Font m_fDefault = null; public Font DefaultFont { get { return m_fDefault; } set { m_fDefault = value; } } public RichTextBuilder() { EnsureInitializedStatic(); } private static void EnsureInitializedStatic() { if(m_vTags != null) return; // When running under Mono, replace bold and italic text // by underlined text, which is rendered correctly (in // contrast to bold and italic text) string strOvrS = null, strOvrE = null; if(MonoWorkarounds.IsRequired(1632)) { strOvrS = "\\ul "; strOvrE = "\\ul0 "; } List l = new List(); l.Add(new RtfbTag(null, (strOvrS ?? "\\b "), true, FontStyle.Bold)); l.Add(new RtfbTag(null, (strOvrE ?? "\\b0 "), false, FontStyle.Bold)); l.Add(new RtfbTag(null, (strOvrS ?? "\\i "), true, FontStyle.Italic)); l.Add(new RtfbTag(null, (strOvrE ?? "\\i0 "), false, FontStyle.Italic)); l.Add(new RtfbTag(null, "\\ul ", true, FontStyle.Underline)); l.Add(new RtfbTag(null, "\\ul0 ", false, FontStyle.Underline)); l.Add(new RtfbTag(null, "\\strike ", true, FontStyle.Strikeout)); l.Add(new RtfbTag(null, "\\strike0 ", false, FontStyle.Strikeout)); m_vTags = l; } public static KeyValuePair GetStyleIdCodes(FontStyle fs) { string strL = null, strR = null; foreach(RtfbTag rTag in m_vTags) { if(rTag.Style == fs) { if(rTag.StartTag) strL = rTag.IdCode; else strR = rTag.IdCode; } } return new KeyValuePair(strL, strR); } public void Append(string str) { m_sb.Append(str); } public void AppendLine() { m_sb.AppendLine(); } public void AppendLine(string str) { m_sb.AppendLine(str); } public void Append(string str, FontStyle fs) { Append(str, fs, null, null, null, null); } public void Append(string str, FontStyle fs, string strOuterPrefix, string strInnerPrefix, string strInnerSuffix, string strOuterSuffix) { KeyValuePair kvpTags = GetStyleIdCodes(fs); if(!string.IsNullOrEmpty(strOuterPrefix)) m_sb.Append(strOuterPrefix); if(!string.IsNullOrEmpty(kvpTags.Key)) m_sb.Append(kvpTags.Key); if(!string.IsNullOrEmpty(strInnerPrefix)) m_sb.Append(strInnerPrefix); m_sb.Append(str); if(!string.IsNullOrEmpty(strInnerSuffix)) m_sb.Append(strInnerSuffix); if(!string.IsNullOrEmpty(kvpTags.Value)) m_sb.Append(kvpTags.Value); if(!string.IsNullOrEmpty(strOuterSuffix)) m_sb.Append(strOuterSuffix); } public void AppendLine(string str, FontStyle fs, string strOuterPrefix, string strInnerPrefix, string strInnerSuffix, string strOuterSuffix) { Append(str, fs, strOuterPrefix, strInnerPrefix, strInnerSuffix, strOuterSuffix); m_sb.AppendLine(); } public void AppendLine(string str, FontStyle fs) { Append(str, fs); m_sb.AppendLine(); } private static RichTextBox CreateOpRtb(RichTextBox rtbUI) { RichTextBox rtbOp = new RichTextBox(); rtbOp.Visible = false; rtbOp.DetectUrls = false; rtbOp.HideSelection = true; rtbOp.Multiline = true; rtbOp.WordWrap = false; // rtbOp.BorderStyle = rtbUI.BorderStyle; // rtbOp.ScrollBars = rtbUI.ScrollBars; rtbOp.Size = rtbUI.Size; if(rtbUI.RightToLeft == RightToLeft.Yes) { rtbOp.RightToLeft = RightToLeft.Yes; // rtbOp.SelectionAlignment = HorizontalAlignment.Right; } return rtbOp; } public void Build(RichTextBox rtb) { Build(rtb, false); } internal void Build(RichTextBox rtb, bool bBracesBalanced) { if(rtb == null) throw new ArgumentNullException("rtb"); RichTextBox rtbOp = CreateOpRtb(rtb); string strText = m_sb.ToString(); Dictionary dEnc = new Dictionary(); if(MonoWorkarounds.IsRequired(586901)) { StringBuilder sbEnc = new StringBuilder(); for(int i = 0; i < strText.Length; ++i) { char ch = strText[i]; if((int)ch <= 255) sbEnc.Append(ch); else { string strCharEnc; if(!dEnc.TryGetValue(ch, out strCharEnc)) { strCharEnc = RtfbTag.GenerateRandomIdCode(); dEnc[ch] = strCharEnc; } sbEnc.Append(strCharEnc); } } strText = sbEnc.ToString(); } rtbOp.Text = strText; Debug.Assert(rtbOp.Text == strText); // Test committed if(m_fDefault != null) { rtbOp.SelectAll(); rtbOp.SelectionFont = m_fDefault; } string strRtf = rtbOp.Rtf; rtbOp.Dispose(); foreach(KeyValuePair kvpEnc in dEnc) { strRtf = strRtf.Replace(kvpEnc.Value, StrUtil.RtfEncodeChar(kvpEnc.Key)); } foreach(RtfbTag rTag in m_vTags) { strRtf = strRtf.Replace(rTag.IdCode, rTag.RtfCode); } if(bBracesBalanced && MonoWorkarounds.IsRequired(2449941153U)) strRtf = Regex.Replace(strRtf, @"(\\)(\{[\u0020-\u005B\u005D-z\w\s]*?)(\})", "$1$2$1$3"); rtb.Rtf = strRtf; } } } KeePass/UI/StatusBarLogger.cs0000664000000000000000000000605113222430414015022 0ustar rootroot/* KeePass Password Safe - The Open-Source Password Manager Copyright (C) 2003-2018 Dominik Reichl This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ using System; using System.Collections.Generic; using System.Diagnostics; using System.Text; using System.Windows.Forms; using KeePassLib.Interfaces; namespace KeePass.UI { public sealed class StatusBarLogger : IStatusLogger { private ToolStripStatusLabel m_sbText = null; private ToolStripProgressBar m_pbProgress = null; private bool m_bStartedLogging = false; private bool m_bEndedLogging = false; private uint m_uLastPercent = 0; ~StatusBarLogger() { Debug.Assert(m_bEndedLogging); try { if(!m_bEndedLogging) EndLogging(); } catch(Exception) { Debug.Assert(false); } } public void SetControls(ToolStripStatusLabel sbText, ToolStripProgressBar pbProgress) { m_sbText = sbText; m_pbProgress = pbProgress; if(m_pbProgress != null) { if(m_pbProgress.Minimum != 0) m_pbProgress.Minimum = 0; if(m_pbProgress.Maximum != 100) m_pbProgress.Maximum = 100; } } public void StartLogging(string strOperation, bool bWriteOperationToLog) { Debug.Assert(!m_bStartedLogging && !m_bEndedLogging); m_pbProgress.Value = 0; m_uLastPercent = 0; m_pbProgress.Visible = true; m_bStartedLogging = true; this.SetText(strOperation, LogStatusType.Info); } public void EndLogging() { Debug.Assert(m_bStartedLogging && !m_bEndedLogging); if(m_pbProgress != null) { m_pbProgress.Visible = false; m_pbProgress.Value = 100; } m_uLastPercent = 100; m_bEndedLogging = true; } public bool SetProgress(uint uPercent) { Debug.Assert(m_bStartedLogging && !m_bEndedLogging); if((m_pbProgress != null) && (uPercent != m_uLastPercent)) { m_pbProgress.Value = (int)uPercent; m_uLastPercent = uPercent; Application.DoEvents(); } return true; } public bool SetText(string strNewText, LogStatusType lsType) { Debug.Assert(m_bStartedLogging && !m_bEndedLogging); if((m_sbText != null) && (lsType == LogStatusType.Info)) { m_sbText.Text = strNewText; Application.DoEvents(); } return true; } public bool ContinueWork() { Debug.Assert(m_bStartedLogging && !m_bEndedLogging); return true; } } } KeePass/UI/OnDemandStatusDialog.cs0000664000000000000000000001237413222430414015770 0ustar rootroot/* KeePass Password Safe - The Open-Source Password Manager Copyright (C) 2003-2018 Dominik Reichl This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ using System; using System.Collections.Generic; using System.Text; using System.Diagnostics; using System.Threading; using System.Windows.Forms; using KeePass.Forms; using KeePassLib.Interfaces; namespace KeePass.UI { public sealed class OnDemandStatusDialog : IStatusLogger { private readonly bool m_bUseThread; private readonly Form m_fOwner; private Thread m_th = null; private StatusProgressForm m_dlgModal = null; private readonly object m_objSync = new object(); private const uint InitialProgress = 0; private const string InitialStatus = null; private volatile string m_strTitle = null; private volatile bool m_bTerminate = false; private volatile uint m_uProgress = InitialProgress; private volatile string m_strProgress = InitialStatus; public OnDemandStatusDialog(bool bUseThread, Form fOwner) { m_bUseThread = bUseThread; m_fOwner = fOwner; } public void StartLogging(string strOperation, bool bWriteOperationToLog) { m_strTitle = strOperation; } public void EndLogging() { lock(m_objSync) { m_bTerminate = true; } m_th = null; if(m_dlgModal != null) { DestroyStatusDialog(m_dlgModal); m_dlgModal = null; } } public bool SetProgress(uint uPercent) { lock(m_objSync) { m_uProgress = uPercent; } return ((m_dlgModal != null) ? m_dlgModal.SetProgress(uPercent) : true); } public bool SetText(string strNewText, LogStatusType lsType) { if(strNewText == null) return true; if(lsType != LogStatusType.Info) return true; if(m_bUseThread && (m_th == null)) { ThreadStart ts = new ThreadStart(this.GuiThread); m_th = new Thread(ts); m_th.Start(); } if(!m_bUseThread && (m_dlgModal == null)) m_dlgModal = ConstructStatusDialog(); lock(m_objSync) { m_strProgress = strNewText; } return ((m_dlgModal != null) ? m_dlgModal.SetText(strNewText, lsType) : true); } public bool ContinueWork() { return ((m_dlgModal != null) ? m_dlgModal.ContinueWork() : true); } private void GuiThread() { uint uProgress = InitialProgress; string strProgress = InitialStatus; StatusProgressForm dlg = null; while(true) { lock(m_objSync) { if(m_bTerminate) break; if(m_uProgress != uProgress) { uProgress = m_uProgress; if(dlg != null) dlg.SetProgress(uProgress); } if(m_strProgress != strProgress) { strProgress = m_strProgress; if(dlg == null) dlg = ConstructStatusDialog(); dlg.SetText(strProgress, LogStatusType.Info); } } Application.DoEvents(); } DestroyStatusDialog(dlg); } private StatusProgressForm ConstructStatusDialog() { StatusProgressForm dlg = StatusProgressForm.ConstructEx( m_strTitle, false, true, (m_bUseThread ? null : m_fOwner), null); dlg.SetProgress(m_uProgress); MainForm mfOwner = ((m_fOwner != null) ? (m_fOwner as MainForm) : null); if((m_bUseThread == false) && (mfOwner != null)) { // mfOwner.RedirectActivationPush(dlg); mfOwner.UIBlockInteraction(true); } return dlg; } private void DestroyStatusDialog(StatusProgressForm dlg) { if(dlg != null) { MainForm mfOwner = ((m_fOwner != null) ? (m_fOwner as MainForm) : null); if((m_bUseThread == false) && (mfOwner != null)) { // mfOwner.RedirectActivationPop(); mfOwner.UIBlockInteraction(false); } StatusProgressForm.DestroyEx(dlg); // Conflict with 3116455 // if(mfOwner != null) mfOwner.Activate(); // Prevent disappearing } } } public sealed class UIBlockerStatusLogger : IStatusLogger { private MainForm m_mf; public UIBlockerStatusLogger(Form fParent) { m_mf = (fParent as MainForm); } public void StartLogging(string strOperation, bool bWriteOperationToLog) { if(m_mf != null) m_mf.UIBlockInteraction(true); } public void EndLogging() { if(m_mf != null) m_mf.UIBlockInteraction(false); } public bool SetProgress(uint uPercent) { return true; } public bool SetText(string strNewText, LogStatusType lsType) { if(m_mf != null) { if(!string.IsNullOrEmpty(strNewText)) { m_mf.SetStatusEx(strNewText); Application.DoEvents(); } } return true; } public bool ContinueWork() { return true; } } } KeePass/UI/TabControlEx.cs0000664000000000000000000000321213222430414014312 0ustar rootroot/* KeePass Password Safe - The Open-Source Password Manager Copyright (C) 2003-2018 Dominik Reichl This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ /* using System; using System.Collections.Generic; using System.Text; using System.Windows.Forms; using System.Drawing; namespace KeePass.UI { public sealed class TabControlEx : TabControl { private Font m_fBold = null; public TabControlEx() : base() { m_fBold = FontUtil.CreateFont(this.Font, FontStyle.Bold); this.DrawMode = TabDrawMode.OwnerDrawFixed; } protected override void Dispose(bool disposing) { base.Dispose(disposing); if(disposing) m_fBold.Dispose(); } protected override void OnDrawItem(DrawItemEventArgs e) { DrawItemEventArgs ev = e; if(this.SelectedIndex == e.Index) ev = new DrawItemEventArgs(e.Graphics, m_fBold, e.Bounds, e.Index, e.State); e.DrawBackground(); base.OnDrawItem(ev); } } } */ KeePass/UI/CustomMessageFilterEx.cs0000664000000000000000000000402213222430414016170 0ustar rootroot/* KeePass Password Safe - The Open-Source Password Manager Copyright (C) 2003-2018 Dominik Reichl This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ using System; using System.Collections.Generic; using System.Text; using System.Windows.Forms; using KeePass.Native; using KeePass.Util; namespace KeePass.UI { internal sealed class CustomMessageFilterEx : IMessageFilter { public bool PreFilterMessage(ref Message m) { if((m.Msg == NativeMethods.WM_KEYDOWN) || (m.Msg == NativeMethods.WM_LBUTTONDOWN) || (m.Msg == NativeMethods.WM_RBUTTONDOWN) || (m.Msg == NativeMethods.WM_MBUTTONDOWN)) { Program.NotifyUserActivity(); } // Workaround for .NET 4.6 overflow bug in InputLanguage.Culture // (handle casted to Int32 without the 'unchecked' keyword); // https://sourceforge.net/p/keepass/bugs/1598/ // https://stackoverflow.com/questions/25619831/arithmetic-operation-resulted-in-an-overflow-in-inputlanguagechangingeventargs // https://referencesource.microsoft.com/#System.Windows.Forms/winforms/Managed/System/WinForms/InputLanguage.cs if(m.Msg == NativeMethods.WM_INPUTLANGCHANGEREQUEST) { long l = m.LParam.ToInt64(); if((l < (long)int.MinValue) || (l > (long)int.MaxValue)) return true; // Ignore it (better than an exception) } return false; } } } KeePass/UI/ListViewSortMenu.cs0000664000000000000000000001454313222430414015222 0ustar rootroot/* KeePass Password Safe - The Open-Source Password Manager Copyright (C) 2003-2018 Dominik Reichl This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ using System; using System.Collections; using System.Collections.Generic; using System.Text; using System.Windows.Forms; using System.Diagnostics; using KeePass.Resources; using KeePassLib.Utility; namespace KeePass.UI { public delegate void SortCommandHandler(bool bEnableSorting, int nColumn, SortOrder? soForce, bool bUpdateEntryList); public sealed class ListViewSortMenu { private ToolStripMenuItem m_tsmiMenu; private ListView m_lv; private SortCommandHandler m_h; private int m_iCurSortColumn = -1; private bool m_bCurSortAsc = true; private ToolStripMenuItem m_tsmiInitDummy = null; private ToolStripMenuItem m_tsmiNoSort = null; private ToolStripSeparator m_tssSep0 = null; private List m_vColumns = null; private ToolStripSeparator m_tssSep1 = null; private ToolStripMenuItem m_tsmiAsc = null; private ToolStripMenuItem m_tsmiDesc = null; public ListViewSortMenu(ToolStripMenuItem tsmiContainer, ListView lvTarget, SortCommandHandler h) { if(tsmiContainer == null) throw new ArgumentNullException("tsmiContainer"); if(lvTarget == null) throw new ArgumentNullException("lvTarget"); if(h == null) throw new ArgumentNullException("h"); m_tsmiMenu = tsmiContainer; m_lv = lvTarget; m_h = h; m_tsmiInitDummy = new ToolStripMenuItem(KPRes.NoSort); m_tsmiMenu.DropDownItems.Add(m_tsmiInitDummy); m_tsmiMenu.DropDownOpening += this.UpdateMenu; } #if DEBUG ~ListViewSortMenu() { Debug.Assert(m_tsmiMenu == null); // Release should have been called } #endif public void Release() { if(m_tsmiMenu != null) { DeleteMenuItems(); m_tsmiMenu.DropDownOpening -= this.UpdateMenu; m_tsmiMenu = null; m_lv = null; m_h = null; } } private void DeleteMenuItems() { if(m_tsmiInitDummy != null) { m_tsmiMenu.DropDownItems.Remove(m_tsmiInitDummy); m_tsmiInitDummy = null; } if(m_tsmiNoSort == null) return; m_tsmiNoSort.Click -= this.OnNoSort; foreach(ToolStripMenuItem tsmiCol in m_vColumns) tsmiCol.Click -= this.OnSortColumn; m_tsmiAsc.Click -= this.OnSortAscDesc; m_tsmiDesc.Click -= this.OnSortAscDesc; m_tsmiMenu.DropDownItems.Clear(); m_tsmiNoSort = null; m_tssSep0 = null; m_vColumns = null; m_tssSep1 = null; m_tsmiAsc = null; m_tsmiDesc = null; } private void UpdateMenu(object sender, EventArgs e) { if(m_lv == null) { Debug.Assert(false); return; } DeleteMenuItems(); IComparer icSorter = m_lv.ListViewItemSorter; ListSorter ls = ((icSorter != null) ? (icSorter as ListSorter) : null); if(ls != null) { m_iCurSortColumn = ls.Column; m_bCurSortAsc = (ls.Order != SortOrder.Descending); if((ls.Order == SortOrder.None) || (m_iCurSortColumn >= m_lv.Columns.Count)) m_iCurSortColumn = -1; } else m_iCurSortColumn = -1; m_tsmiNoSort = new ToolStripMenuItem(KPRes.NoSort); if(m_iCurSortColumn < 0) UIUtil.SetRadioChecked(m_tsmiNoSort, true); m_tsmiNoSort.Click += this.OnNoSort; m_tsmiMenu.DropDownItems.Add(m_tsmiNoSort); m_tssSep0 = new ToolStripSeparator(); m_tsmiMenu.DropDownItems.Add(m_tssSep0); m_vColumns = new List(); foreach(ColumnHeader ch in m_lv.Columns) { string strText = (ch.Text ?? string.Empty); strText = StrUtil.EncodeMenuText(strText); ToolStripMenuItem tsmi = new ToolStripMenuItem(strText); if(ch.Index == m_iCurSortColumn) UIUtil.SetRadioChecked(tsmi, true); tsmi.Click += this.OnSortColumn; m_vColumns.Add(tsmi); m_tsmiMenu.DropDownItems.Add(tsmi); } m_tssSep1 = new ToolStripSeparator(); m_tsmiMenu.DropDownItems.Add(m_tssSep1); m_tsmiAsc = new ToolStripMenuItem(KPRes.Ascending); if((m_iCurSortColumn >= 0) && m_bCurSortAsc) UIUtil.SetRadioChecked(m_tsmiAsc, true); m_tsmiAsc.Click += this.OnSortAscDesc; if(m_iCurSortColumn < 0) m_tsmiAsc.Enabled = false; m_tsmiMenu.DropDownItems.Add(m_tsmiAsc); m_tsmiDesc = new ToolStripMenuItem(KPRes.Descending); if((m_iCurSortColumn >= 0) && !m_bCurSortAsc) UIUtil.SetRadioChecked(m_tsmiDesc, true); m_tsmiDesc.Click += this.OnSortAscDesc; if(m_iCurSortColumn < 0) m_tsmiDesc.Enabled = false; m_tsmiMenu.DropDownItems.Add(m_tsmiDesc); } private void OnNoSort(object sender, EventArgs e) { if(m_h == null) { Debug.Assert(false); return; } m_h(false, 0, null, true); } private void OnSortColumn(object sender, EventArgs e) { if(m_h == null) { Debug.Assert(false); return; } ToolStripMenuItem tsmi = (sender as ToolStripMenuItem); if(tsmi == null) { Debug.Assert(false); return; } for(int i = 0; i < m_vColumns.Count; ++i) { if(m_vColumns[i] == tsmi) { bool bAsc = m_bCurSortAsc; if(i == m_iCurSortColumn) bAsc = !bAsc; // Toggle m_h(true, i, bAsc ? SortOrder.Ascending : SortOrder.Descending, true); break; } } } private void OnSortAscDesc(object sender, EventArgs e) { if(m_h == null) { Debug.Assert(false); return; } if(m_iCurSortColumn < 0) { Debug.Assert(false); return; } ToolStripMenuItem tsmi = (sender as ToolStripMenuItem); if(tsmi == null) { Debug.Assert(false); return; } if((tsmi == m_tsmiAsc) && !m_bCurSortAsc) m_h(true, m_iCurSortColumn, SortOrder.Ascending, true); else if((tsmi == m_tsmiDesc) && m_bCurSortAsc) m_h(true, m_iCurSortColumn, SortOrder.Descending, true); } } } KeePass/UI/ColorMenuItem.cs0000664000000000000000000000443413222430412014475 0ustar rootroot/* KeePass Password Safe - The Open-Source Password Manager Copyright (C) 2003-2018 Dominik Reichl This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ using System; using System.Collections.Generic; using System.Text; using System.Windows.Forms; using System.Drawing; using System.Diagnostics; namespace KeePass.UI { public sealed class ColorMenuItem : MenuItem { private Color m_clr; private int m_qSize; public Color Color { get { return m_clr; } } public ColorMenuItem(Color clr, int qSize) : base() { m_clr = clr; m_qSize = qSize; Debug.Assert(this.CanRaiseEvents); this.ShowShortcut = false; this.OwnerDraw = true; } protected override void OnDrawItem(DrawItemEventArgs e) { // base.OnDrawItem(e); Graphics g = e.Graphics; Rectangle rectBounds = e.Bounds; Rectangle rectFill = new Rectangle(rectBounds.Left + 2, rectBounds.Top + 2, rectBounds.Width - 4, rectBounds.Height - 4); bool bFocused = (((e.State & DrawItemState.Focus) != DrawItemState.None) || ((e.State & DrawItemState.Selected) != DrawItemState.None)); // e.DrawBackground(); // e.DrawFocusRectangle(); using(SolidBrush sbBack = new SolidBrush(bFocused ? SystemColors.Highlight : SystemColors.Menu)) { g.FillRectangle(sbBack, rectBounds); } using(SolidBrush sb = new SolidBrush(m_clr)) { g.FillRectangle(sb, rectFill); } } protected override void OnMeasureItem(MeasureItemEventArgs e) { // base.OnMeasureItem(e); e.ItemWidth = m_qSize; e.ItemHeight = m_qSize; } } } KeePass/UI/ShowWarningsLogger.cs0000664000000000000000000001317513222430414015550 0ustar rootroot/* KeePass Password Safe - The Open-Source Password Manager Copyright (C) 2003-2018 Dominik Reichl This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ using System; using System.Collections.Generic; using System.Text; using System.Windows.Forms; using System.Diagnostics; using KeePass.Forms; using KeePassLib; using KeePassLib.Interfaces; namespace KeePass.UI { /// /// This logger displays the current status in a status bar. /// As soon as a warning or error is logged, a dialog is opened /// and all consecutive log lines are sent to both loggers /// (status bar and dialog). /// public sealed class ShowWarningsLogger : IStatusLogger { private StatusBarLogger m_sbDefault = null; private StatusLoggerForm m_slForm = null; private Form m_fTaskbarWindow = null; private bool m_bStartedLogging = false; private bool m_bEndedLogging = false; private List> m_vCachedMessages = new List>(); [Obsolete] public ShowWarningsLogger(StatusBarLogger sbDefault) { m_sbDefault = sbDefault; } public ShowWarningsLogger(StatusBarLogger sbDefault, Form fTaskbarWindow) { m_sbDefault = sbDefault; m_fTaskbarWindow = fTaskbarWindow; } ~ShowWarningsLogger() { Debug.Assert(m_bEndedLogging); try { if(!m_bEndedLogging) EndLogging(); } catch(Exception) { Debug.Assert(false); } } public void StartLogging(string strOperation, bool bWriteOperationToLog) { Debug.Assert(!m_bStartedLogging && !m_bEndedLogging); if(m_sbDefault != null) m_sbDefault.StartLogging(strOperation, bWriteOperationToLog); if(m_slForm != null) m_slForm.StartLogging(strOperation, bWriteOperationToLog); if(m_fTaskbarWindow != null) { TaskbarList.SetProgressValue(m_fTaskbarWindow, 0, 100); TaskbarList.SetProgressState(m_fTaskbarWindow, TbpFlag.Normal); } m_bStartedLogging = true; if(bWriteOperationToLog) m_vCachedMessages.Add(new KeyValuePair( LogStatusType.Info, strOperation)); } public void EndLogging() { Debug.Assert(m_bStartedLogging && !m_bEndedLogging); if(m_sbDefault != null) m_sbDefault.EndLogging(); if(m_slForm != null) m_slForm.EndLogging(); if(m_fTaskbarWindow != null) TaskbarList.SetProgressState(m_fTaskbarWindow, TbpFlag.NoProgress); m_bEndedLogging = true; } /// /// Set the current progress in percent. /// /// Percent of work finished. /// Returns true if the caller should continue /// the current work. public bool SetProgress(uint uPercent) { Debug.Assert(m_bStartedLogging && !m_bEndedLogging); bool b = true; if(m_sbDefault != null) { if(!m_sbDefault.SetProgress(uPercent)) b = false; } if(m_slForm != null) { if(!m_slForm.SetProgress(uPercent)) b = false; } if(m_fTaskbarWindow != null) TaskbarList.SetProgressValue(m_fTaskbarWindow, uPercent, 100); return b; } /// /// Set the current status text. /// /// Status text. /// Type of the message. /// Returns true if the caller should continue /// the current work. public bool SetText(string strNewText, LogStatusType lsType) { Debug.Assert(m_bStartedLogging && !m_bEndedLogging); if((m_slForm == null) && ((lsType == LogStatusType.Warning) || (lsType == LogStatusType.Error))) { m_slForm = new StatusLoggerForm(); m_slForm.InitEx(false); m_slForm.Show(); m_slForm.BringToFront(); bool bLoggingStarted = false; foreach(KeyValuePair kvp in m_vCachedMessages) { if(!bLoggingStarted) { m_slForm.StartLogging(kvp.Value, true); bLoggingStarted = true; } else m_slForm.SetText(kvp.Value, kvp.Key); } Debug.Assert(bLoggingStarted); m_vCachedMessages.Clear(); } bool b = true; if(m_sbDefault != null) { if(!m_sbDefault.SetText(strNewText, lsType)) b = false; } if(m_slForm != null) { if(!m_slForm.SetText(strNewText, lsType)) b = false; } if(m_slForm == null) m_vCachedMessages.Add(new KeyValuePair( lsType, strNewText)); return b; } /// /// Check if the user cancelled the current work. /// /// Returns true if the caller should continue /// the current work. public bool ContinueWork() { Debug.Assert(m_bStartedLogging && !m_bEndedLogging); bool b = true; if(m_slForm != null) { if(!m_slForm.ContinueWork()) b = false; } if(m_sbDefault != null) { if(!m_sbDefault.ContinueWork()) b = false; } return b; } } } KeePass/UI/BannerFactory.cs0000664000000000000000000003212713222430412014510 0ustar rootroot/* KeePass Password Safe - The Open-Source Password Manager Copyright (C) 2003-2018 Dominik Reichl This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ using System; using System.Collections.Generic; using System.Diagnostics; using System.Drawing; using System.Drawing.Drawing2D; using System.Drawing.Imaging; using System.Windows.Forms; using KeePass.App; using KeePass.Util; using KeePassLib.Utility; namespace KeePass.UI { public enum BannerStyle { Default = 0, WinXPLogin = 1, WinVistaBlack = 2, KeePassWin32 = 3, BlueCarbon = 4 } public sealed class BfBannerInfo { public int Width { get; private set; } public int Height { get; private set; } public BannerStyle Style { get; private set; } public Image Icon { get; private set; } public string TitleText { get; private set; } public string InfoText { get; private set; } public BfBannerInfo(int nWidth, int nHeight, BannerStyle bs, Image imgIcon, string strTitle, string strLine) { this.Width = nWidth; this.Height = nHeight; this.Style = bs; this.Icon = imgIcon; this.TitleText = strTitle; this.InfoText = strLine; } } public delegate Image BfBannerGenerator(BfBannerInfo bannerInfo); public static class BannerFactory { private const int StdHeight = 60; // Standard height for 96 DPI private const int StdIconDim = 48; private static Dictionary m_vImageCache = new Dictionary(); private const int MaxCachedImages = 32; private static BfBannerGenerator m_pCustomGen = null; public static BfBannerGenerator CustomGenerator { get { return m_pCustomGen; } set { m_pCustomGen = value; } } public static Image CreateBanner(int nWidth, int nHeight, BannerStyle bs, Image imgIcon, string strTitle, string strLine) { return CreateBanner(nWidth, nHeight, bs, imgIcon, strTitle, strLine, false); } public static Image CreateBanner(int nWidth, int nHeight, BannerStyle bs, Image imgIcon, string strTitle, string strLine, bool bNoCache) { // imgIcon may be null Debug.Assert(strTitle != null); if(strTitle == null) throw new ArgumentNullException("strTitle"); Debug.Assert(strLine != null); if(strLine == null) throw new ArgumentNullException("strLine"); Debug.Assert((nHeight == StdHeight) || DpiUtil.ScalingRequired || UISystemFonts.OverrideUIFont); if(MonoWorkarounds.IsRequired(12525) && (nHeight > 0)) --nHeight; string strImageID = nWidth.ToString() + "x" + nHeight.ToString() + ":"; if(strTitle != null) strImageID += strTitle; strImageID += ":"; if(strLine != null) strImageID += strLine; if(bs == BannerStyle.Default) bs = Program.Config.UI.BannerStyle; if(bs == BannerStyle.Default) { Debug.Assert(false); bs = BannerStyle.WinVistaBlack; } strImageID += ":" + ((uint)bs).ToString(); // Try getting the banner from the banner cache Image img = null; if(!bNoCache && m_vImageCache.TryGetValue(strImageID, out img)) return img; if(m_pCustomGen != null) img = m_pCustomGen(new BfBannerInfo(nWidth, nHeight, bs, imgIcon, strTitle, strLine)); const float fHorz = 0.90f; const float fVert = 90.0f; if(img == null) { img = new Bitmap(nWidth, nHeight, PixelFormat.Format24bppRgb); Graphics g = Graphics.FromImage(img); Color clrStart = Color.White; Color clrEnd = Color.LightBlue; float fAngle = fHorz; if(bs == BannerStyle.BlueCarbon) { fAngle = fVert; g.Clear(Color.Black); // Area from 3/8 to 1/2 height clrStart = Color.LightGray; clrEnd = Color.Black; Rectangle rect = new Rectangle(0, 0, nWidth, (nHeight * 3) / 8); using(LinearGradientBrush brCarbonT = new LinearGradientBrush( rect, clrStart, clrEnd, fAngle, true)) { g.FillRectangle(brCarbonT, rect); } // clrStart = Color.FromArgb(0, 0, 32); clrStart = Color.FromArgb(0, 0, 28); // clrEnd = Color.FromArgb(192, 192, 255); clrEnd = Color.FromArgb(155, 155, 214); // rect = new Rectangle(0, nHeight / 2, nWidth, (nHeight * 5) / 8); int hMid = nHeight / 2; rect = new Rectangle(0, hMid - 1, nWidth, nHeight - hMid); using(LinearGradientBrush brCarbonB = new LinearGradientBrush( rect, clrStart, clrEnd, fAngle, true)) { g.FillRectangle(brCarbonB, rect); } // Workaround gradient drawing bug (e.g. occuring on // Windows 8.1 with 150% DPI) using(Pen pen = new Pen(Color.Black)) { g.DrawLine(pen, 0, hMid - 1, nWidth - 1, hMid - 1); } } else { if(bs == BannerStyle.WinXPLogin) { clrStart = Color.FromArgb(200, 208, 248); clrEnd = Color.FromArgb(40, 64, 216); } else if(bs == BannerStyle.WinVistaBlack) { clrStart = Color.FromArgb(151, 154, 173); clrEnd = Color.FromArgb(27, 27, 37); fAngle = fVert; } else if(bs == BannerStyle.KeePassWin32) { clrStart = Color.FromArgb(235, 235, 255); clrEnd = Color.FromArgb(192, 192, 255); } Rectangle rect = new Rectangle(0, 0, nWidth, nHeight); using(LinearGradientBrush brBack = new LinearGradientBrush( rect, clrStart, clrEnd, fAngle, true)) { g.FillRectangle(brBack, rect); } } bool bRtl = Program.Translation.Properties.RightToLeft; // Matrix mxTrfOrg = g.Transform; // if(bRtl) // { // g.TranslateTransform(nWidth, 0.0f); // g.ScaleTransform(-1.0f, 1.0f); // } int xIcon = DpiScaleInt(10, nHeight); int wIconScaled = StdIconDim; int hIconScaled = StdIconDim; if(imgIcon != null) { float fIconRel = (float)imgIcon.Width / (float)imgIcon.Height; wIconScaled = (int)Math.Round(DpiScaleFloat(fIconRel * (float)StdIconDim, nHeight)); hIconScaled = DpiScaleInt(StdIconDim, nHeight); int xIconR = (bRtl ? (nWidth - xIcon - wIconScaled) : xIcon); int yIconR = (nHeight - hIconScaled) / 2; if(hIconScaled == imgIcon.Height) g.DrawImageUnscaled(imgIcon, xIconR, yIconR); else g.DrawImage(imgIcon, xIconR, yIconR, wIconScaled, hIconScaled); ColorMatrix cm = new ColorMatrix(); cm.Matrix33 = 0.1f; ImageAttributes ia = new ImageAttributes(); ia.SetColorMatrix(cm); int w = wIconScaled * 3, h = hIconScaled * 3; int x = (bRtl ? xIcon : (nWidth - w - xIcon)); int y = (nHeight - h) / 2; Rectangle rectDest = new Rectangle(x, y, w, h); g.DrawImage(imgIcon, rectDest, 0, 0, imgIcon.Width, imgIcon.Height, GraphicsUnit.Pixel, ia); } if((bs == BannerStyle.WinXPLogin) || (bs == BannerStyle.WinVistaBlack) || (bs == BannerStyle.BlueCarbon)) { int sh = DpiUtil.ScaleIntY(20) / 10; // Force floor Rectangle rect = new Rectangle(0, nHeight - sh, 0, sh); rect.Width = nWidth / 2 + 1; rect.X = nWidth / 2; clrStart = Color.FromArgb(248, 136, 24); clrEnd = Color.White; using(LinearGradientBrush brushOrangeWhite = new LinearGradientBrush( rect, clrStart, clrEnd, fHorz, true)) { g.FillRectangle(brushOrangeWhite, rect); } rect.Width = nWidth / 2 + 1; rect.X = 0; clrStart = Color.White; clrEnd = Color.FromArgb(248, 136, 24); using(LinearGradientBrush brushWhiteOrange = new LinearGradientBrush( rect, clrStart, clrEnd, fHorz, true)) { g.FillRectangle(brushWhiteOrange, rect); } } else if(bs == BannerStyle.KeePassWin32) { int sh = DpiUtil.ScaleIntY(10) / 10; // Force floor // Black separator line using(Pen penBlack = new Pen(Color.Black)) { for(int i = 0; i < sh; ++i) g.DrawLine(penBlack, 0, nHeight - i - 1, nWidth - 1, nHeight - i - 1); } } // if(bRtl) g.Transform = mxTrfOrg; // Brush brush; Color clrText; if(bs == BannerStyle.KeePassWin32) { // brush = Brushes.Black; clrText = Color.Black; } else { // brush = Brushes.White; clrText = Color.White; } // float fx = 2 * xIcon, fy = 9.0f; int tx = 2 * xIcon, ty = DpiScaleInt(9, nHeight); if(imgIcon != null) tx += wIconScaled; // fx // TextFormatFlags tff = (TextFormatFlags.PreserveGraphicsClipping | // TextFormatFlags.NoPrefix); // if(bRtl) tff |= TextFormatFlags.RightToLeft; float fFontSize = DpiScaleFloat((12.0f * 96.0f) / g.DpiY, nHeight); Font font = FontUtil.CreateFont(FontFamily.GenericSansSerif, fFontSize, FontStyle.Bold); int txT = (!bRtl ? tx : (nWidth - tx)); // - TextRenderer.MeasureText(g, strTitle, font).Width)); // g.DrawString(strTitle, font, brush, fx, fy); BannerFactory.DrawText(g, strTitle, txT, ty, font, clrText, bRtl); font.Dispose(); tx += xIcon; // fx ty += xIcon * 2 + 2; // fy float fFontSizeSm = DpiScaleFloat((9.0f * 96.0f) / g.DpiY, nHeight); Font fontSmall = FontUtil.CreateFont(FontFamily.GenericSansSerif, fFontSizeSm, FontStyle.Regular); int txL = (!bRtl ? tx : (nWidth - tx)); // - TextRenderer.MeasureText(g, strLine, fontSmall).Width)); // g.DrawString(strLine, fontSmall, brush, fx, fy); BannerFactory.DrawText(g, strLine, txL, ty, fontSmall, clrText, bRtl); fontSmall.Dispose(); g.Dispose(); } if(!bNoCache) { while(m_vImageCache.Count >= MaxCachedImages) { foreach(string strKey in m_vImageCache.Keys) { m_vImageCache.Remove(strKey); break; // Remove first item only } } // Save in cache m_vImageCache[strImageID] = img; } return img; } private static void DrawText(Graphics g, string strText, int x, int y, Font font, Color clrForeground, bool bRtl) { // With ClearType on, text drawn using Graphics.DrawString // looks better than TextRenderer.DrawText; // https://sourceforge.net/p/keepass/discussion/329220/thread/06ef4466/ /* // On Windows 2000 the DrawText method taking a Point doesn't // work by design, see MSDN: // https://msdn.microsoft.com/en-us/library/ms160657.aspx if(WinUtil.IsWindows2000) TextRenderer.DrawText(g, strText, font, new Rectangle(pt.X, pt.Y, nWidth - pt.X - 1, nHeight - pt.Y - 1), clrForeground, tff); else TextRenderer.DrawText(g, strText, font, pt, clrForeground, tff); */ using(SolidBrush br = new SolidBrush(clrForeground)) { StringFormatFlags sff = (StringFormatFlags.FitBlackBox | StringFormatFlags.NoClip); if(bRtl) sff |= StringFormatFlags.DirectionRightToLeft; using(StringFormat sf = new StringFormat(sff)) { g.DrawString(strText, font, br, x, y, sf); } } } private static int DpiScaleInt(int x, int nBaseHeight) { return (int)Math.Round((double)(x * nBaseHeight) / (double)StdHeight); } private static float DpiScaleFloat(float x, int nBaseHeight) { return ((x * (float)nBaseHeight) / (float)StdHeight); } public static void CreateBannerEx(Form f, PictureBox picBox, Image imgIcon, string strTitle, string strLine) { CreateBannerEx(f, picBox, imgIcon, strTitle, strLine, false); } public static void CreateBannerEx(Form f, PictureBox picBox, Image imgIcon, string strTitle, string strLine, bool bNoCache) { if(picBox == null) { Debug.Assert(false); return; } try { picBox.Image = CreateBanner(picBox.Width, picBox.Height, BannerStyle.Default, imgIcon, strTitle, strLine, bNoCache); } catch(Exception) { Debug.Assert(false); } } /// /// Update/create a dialog banner. This method is intended for /// updating banners in resizable dialogs. The created banner /// images bypass the cache of the factory and are disposed /// when the dialog is resized (i.e. the caller shouldn't do /// anything with the banner images). /// public static void UpdateBanner(Form f, PictureBox picBox, Image imgIcon, string strTitle, string strLine, ref int nOldWidth) { int nWidth = picBox.Width; if(nWidth != nOldWidth) { Image imgPrev = null; if(nOldWidth >= 0) imgPrev = picBox.Image; BannerFactory.CreateBannerEx(f, picBox, imgIcon, strTitle, strLine, true); if(imgPrev != null) imgPrev.Dispose(); // Release old banner nOldWidth = nWidth; } } } } KeePass/UI/DocumentManagerEx.cs0000664000000000000000000001617313222430414015326 0ustar rootroot/* KeePass Password Safe - The Open-Source Password Manager Copyright (C) 2003-2018 Dominik Reichl This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ using System; using System.Collections.Generic; using System.Text; using System.Windows.Forms; using System.Diagnostics; using KeePass.App.Configuration; using KeePassLib; using KeePassLib.Delegates; using KeePassLib.Serialization; namespace KeePass.UI { public sealed class DocumentManagerEx { private List m_vDocs = new List(); private PwDocument m_dsActive = new PwDocument(); public event EventHandler ActiveDocumentSelected; public DocumentManagerEx() { Debug.Assert((m_vDocs != null) && (m_dsActive != null)); m_vDocs.Add(m_dsActive); } public PwDocument ActiveDocument { get { return m_dsActive; } set { if(value == null) { Debug.Assert(false); throw new ArgumentNullException("value"); } for(int i = 0; i < m_vDocs.Count; ++i) { if(m_vDocs[i] == value) { m_dsActive = value; NotifyActiveDocumentSelected(); return; } } throw new ArgumentException(); } } public PwDatabase ActiveDatabase { get { return m_dsActive.Database; } set { if(value == null) { Debug.Assert(false); throw new ArgumentNullException("value"); } for(int i = 0; i < m_vDocs.Count; ++i) { if(m_vDocs[i].Database == value) { m_dsActive = m_vDocs[i]; NotifyActiveDocumentSelected(); return; } } throw new ArgumentException(); } } public uint DocumentCount { get { return (uint)m_vDocs.Count; } } public List Documents { get { return m_vDocs; } } public PwDocument CreateNewDocument(bool bMakeActive) { PwDocument ds = new PwDocument(); if((m_vDocs.Count == 1) && (!m_vDocs[0].Database.IsOpen) && (m_vDocs[0].LockedIoc.Path.Length == 0)) { m_vDocs.RemoveAt(0); m_dsActive = ds; } m_vDocs.Add(ds); if(bMakeActive) m_dsActive = ds; NotifyActiveDocumentSelected(); return ds; } public void CloseDatabase(PwDatabase pwDatabase) { int iFoundPos = -1; for(int i = 0; i < m_vDocs.Count; ++i) { if(m_vDocs[i].Database == pwDatabase) { iFoundPos = i; break; } } if(iFoundPos < 0) { Debug.Assert(false); return; } bool bClosingActive = (m_vDocs[iFoundPos] == m_dsActive); m_vDocs.RemoveAt(iFoundPos); if(m_vDocs.Count == 0) m_vDocs.Add(new PwDocument()); if(bClosingActive) { int iNewActive = Math.Min(iFoundPos, m_vDocs.Count - 1); m_dsActive = m_vDocs[iNewActive]; NotifyActiveDocumentSelected(); } else { Debug.Assert(m_vDocs.Contains(m_dsActive)); } } public List GetOpenDatabases() { List list = new List(); foreach(PwDocument ds in m_vDocs) { if(ds.Database.IsOpen) list.Add(ds.Database); } return list; } internal List GetDocuments(int iMoveActive) { List lDocs = new List(m_vDocs); if(iMoveActive != 0) { for(int i = 0; i < lDocs.Count; ++i) { if(lDocs[i] == m_dsActive) { lDocs.RemoveAt(i); if(iMoveActive < 0) lDocs.Insert(0, m_dsActive); else lDocs.Add(m_dsActive); break; } } } return lDocs; } private void NotifyActiveDocumentSelected() { RememberActiveDocument(); if(this.ActiveDocumentSelected != null) this.ActiveDocumentSelected(null, EventArgs.Empty); } internal void RememberActiveDocument() { if(m_dsActive == null) { Debug.Assert(false); return; } if(m_dsActive.LockedIoc != null) SetLastUsedFile(m_dsActive.LockedIoc); if(m_dsActive.Database != null) SetLastUsedFile(m_dsActive.Database.IOConnectionInfo); } 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(); } public PwDocument FindDocument(PwDatabase pwDatabase) { if(pwDatabase == null) throw new ArgumentNullException("pwDatabase"); foreach(PwDocument ds in m_vDocs) { if(ds.Database == pwDatabase) return ds; } return null; } /// /// Search for an entry in all opened databases. The /// entry is identified by its reference (not its UUID). /// /// Entry to search for. /// Database containing the entry. public PwDatabase FindContainerOf(PwEntry peObj) { if(peObj == null) return null; // No assert PwGroup pg = peObj.ParentGroup; if(pg != null) { while(pg.ParentGroup != null) { pg = pg.ParentGroup; } foreach(PwDocument ds in m_vDocs) { PwDatabase pd = ds.Database; if((pd == null) || !pd.IsOpen) continue; if(object.ReferenceEquals(pd.RootGroup, pg)) return pd; } Debug.Assert(false); } return SlowFindContainerOf(peObj); } private PwDatabase SlowFindContainerOf(PwEntry peObj) { PwDatabase pdRet = null; foreach(PwDocument ds in m_vDocs) { PwDatabase pd = ds.Database; if((pd == null) || !pd.IsOpen) continue; EntryHandler eh = delegate(PwEntry pe) { if(object.ReferenceEquals(pe, peObj)) { pdRet = pd; return false; // Stop traversal } return true; }; pd.RootGroup.TraverseTree(TraversalMethod.PreOrder, null, eh); if(pdRet != null) return pdRet; } return null; } public PwDatabase SafeFindContainerOf(PwEntry peObj) { // peObj may be null return (FindContainerOf(peObj) ?? m_dsActive.Database); } } public sealed class PwDocument { private PwDatabase m_pwDb = new PwDatabase(); private IOConnectionInfo m_ioLockedIoc = new IOConnectionInfo(); public PwDatabase Database { get { return m_pwDb; } } public IOConnectionInfo LockedIoc { get { return m_ioLockedIoc; } set { Debug.Assert(value != null); if(value == null) throw new ArgumentNullException("value"); m_ioLockedIoc = value; } } } } KeePass/UI/MruList.cs0000664000000000000000000002362413222430414013356 0ustar rootroot/* KeePass Password Safe - The Open-Source Password Manager Copyright (C) 2003-2018 Dominik Reichl This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ using System; using System.Collections.Generic; using System.Text; using System.Windows.Forms; using System.Drawing; using System.Globalization; using System.Diagnostics; using KeePass.Resources; using KeePassLib; using KeePassLib.Serialization; using KeePassLib.Utility; namespace KeePass.UI { /// /// MRU handler interface. An MRU handler must support executing an MRU /// item and clearing the MRU list. /// public interface IMruExecuteHandler { /// /// Function that is called when an MRU item is executed (i.e. when /// the user has clicked the menu item). /// void OnMruExecute(string strDisplayName, object oTag, ToolStripMenuItem tsmiParent); /// /// Function to clear the MRU (for example all menu items must be /// removed from the menu). /// void OnMruClear(); } public sealed class MruList { private List> m_vItems = new List>(); private IMruExecuteHandler m_handler = null; private List m_lContainers = new List(); private ToolStripMenuItem m_tsmiClear = null; private List m_lMruMenuItems = new List(); private enum MruMenuItemType { None = 0, Item, Clear } // private Font m_fItalic = null; private uint m_uMaxItemCount = 0; public uint MaxItemCount { get { return m_uMaxItemCount; } set { m_uMaxItemCount = value; } } private bool m_bMarkOpened = false; public bool MarkOpened { get { return m_bMarkOpened; } set { m_bMarkOpened = value; } } public uint ItemCount { get { return (uint)m_vItems.Count; } } public bool IsValid { get { return (m_handler != null); } } public MruList() { } public void Initialize(IMruExecuteHandler handler, params ToolStripMenuItem[] vContainers) { Release(); Debug.Assert(handler != null); // No throw m_handler = handler; if(vContainers != null) { foreach(ToolStripMenuItem tsmi in vContainers) { if(tsmi != null) { m_lContainers.Add(tsmi); tsmi.DropDownOpening += this.OnDropDownOpening; } } } } public void Release() { ReleaseMenuItems(); foreach(ToolStripMenuItem tsmi in m_lContainers) { tsmi.DropDownOpening -= this.OnDropDownOpening; } m_lContainers.Clear(); m_handler = null; } private void ReleaseMenuItems() { if(m_tsmiClear != null) { m_tsmiClear.Click -= this.ClearHandler; m_tsmiClear = null; } foreach(ToolStripMenuItem tsmi in m_lMruMenuItems) { tsmi.Click -= this.ClickHandler; } m_lMruMenuItems.Clear(); } public void Clear() { m_vItems.Clear(); } [Obsolete] public void AddItem(string strDisplayName, object oTag, bool bUpdateMenu) { AddItem(strDisplayName, oTag); } public void AddItem(string strDisplayName, object oTag) { Debug.Assert(strDisplayName != null); if(strDisplayName == null) throw new ArgumentNullException("strDisplayName"); // oTag may be null bool bExists = false; foreach(KeyValuePair kvp in m_vItems) { Debug.Assert(kvp.Key != null); if(kvp.Key.Equals(strDisplayName, StrUtil.CaseIgnoreCmp)) { bExists = true; break; } } if(bExists) MoveItemToTop(strDisplayName, oTag); else { m_vItems.Insert(0, new KeyValuePair( strDisplayName, oTag)); if(m_vItems.Count > m_uMaxItemCount) m_vItems.RemoveAt(m_vItems.Count - 1); } // if(bUpdateMenu) UpdateMenu(); } private void MoveItemToTop(string strName, object oNewTag) { for(int i = 0; i < m_vItems.Count; ++i) { if(m_vItems[i].Key.Equals(strName, StrUtil.CaseIgnoreCmp)) { KeyValuePair t = new KeyValuePair(strName, oNewTag); m_vItems.RemoveAt(i); m_vItems.Insert(0, t); return; } } Debug.Assert(false); } [Obsolete] public void UpdateMenu() { } private void UpdateMenu(object oContainer) { ToolStripMenuItem tsmiContainer = (oContainer as ToolStripMenuItem); if(tsmiContainer == null) { Debug.Assert(false); return; } if(!m_lContainers.Contains(tsmiContainer)) { Debug.Assert(false); return; } tsmiContainer.DropDown.SuspendLayout(); // Verify that the popup arrow has been drawn (i.e. items existed) Debug.Assert(tsmiContainer.DropDownItems.Count > 0); ReleaseMenuItems(); tsmiContainer.DropDownItems.Clear(); uint uAccessKey = 1, uNull = 0; if(m_vItems.Count > 0) { foreach(KeyValuePair kvp in m_vItems) { AddMenuItem(tsmiContainer, MruMenuItemType.Item, StrUtil.EncodeMenuText(kvp.Key), null, kvp.Value, true, ref uAccessKey); } tsmiContainer.DropDownItems.Add(new ToolStripSeparator()); AddMenuItem(tsmiContainer, MruMenuItemType.Clear, KPRes.ClearMru, Properties.Resources.B16x16_EditDelete, null, true, ref uNull); } else { AddMenuItem(tsmiContainer, MruMenuItemType.None, "(" + KPRes.Empty + ")", null, null, false, ref uNull); } tsmiContainer.DropDown.ResumeLayout(true); } private void AddMenuItem(ToolStripMenuItem tsmiParent, MruMenuItemType t, string strText, Image img, object oTag, bool bEnabled, ref uint uAccessKey) { ToolStripMenuItem tsmi = CreateMenuItem(t, strText, img, oTag, bEnabled, uAccessKey); tsmiParent.DropDownItems.Add(tsmi); if(t == MruMenuItemType.Item) m_lMruMenuItems.Add(tsmi); else if(t == MruMenuItemType.Clear) { Debug.Assert(m_tsmiClear == null); m_tsmiClear = tsmi; } if(uAccessKey != 0) ++uAccessKey; } private ToolStripMenuItem CreateMenuItem(MruMenuItemType t, string strText, Image img, object oTag, bool bEnabled, uint uAccessKey) { string strItem = strText; if(uAccessKey >= 1) { NumberFormatInfo nfi = NumberFormatInfo.InvariantInfo; if(uAccessKey < 10) strItem = @"&" + uAccessKey.ToString(nfi) + " " + strItem; else if(uAccessKey == 10) strItem = @"1&0 " + strItem; else strItem = uAccessKey.ToString(nfi) + " " + strItem; } ToolStripMenuItem tsmi = new ToolStripMenuItem(strItem); if(img != null) tsmi.Image = img; if(oTag != null) tsmi.Tag = oTag; IOConnectionInfo ioc = (oTag as IOConnectionInfo); if(m_bMarkOpened && (ioc != null) && (Program.MainForm != null)) { foreach(PwDatabase pd in Program.MainForm.DocumentManager.GetOpenDatabases()) { if(pd.IOConnectionInfo.GetDisplayName().Equals( ioc.GetDisplayName(), StrUtil.CaseIgnoreCmp)) { // if(m_fItalic == null) // { // Font f = tsi.Font; // if(f != null) // m_fItalic = FontUtil.CreateFont(f, FontStyle.Italic); // else { Debug.Assert(false); } // } // if(m_fItalic != null) tsmi.Font = m_fItalic; // 153, 51, 153 tsmi.ForeColor = Color.FromArgb(64, 64, 255); tsmi.Text += " [" + KPRes.Opened + "]"; break; } } } if(t == MruMenuItemType.Item) tsmi.Click += this.ClickHandler; else if(t == MruMenuItemType.Clear) tsmi.Click += this.ClearHandler; // t == MruMenuItemType.None needs no handler if(!bEnabled) tsmi.Enabled = false; return tsmi; } public KeyValuePair GetItem(uint uIndex) { Debug.Assert(uIndex < (uint)m_vItems.Count); if(uIndex >= (uint)m_vItems.Count) throw new ArgumentException(); return m_vItems[(int)uIndex]; } public bool RemoveItem(string strDisplayName) { Debug.Assert(strDisplayName != null); if(strDisplayName == null) throw new ArgumentNullException("strDisplayName"); for(int i = 0; i < m_vItems.Count; ++i) { KeyValuePair kvp = m_vItems[i]; if(kvp.Key.Equals(strDisplayName, StrUtil.CaseIgnoreCmp)) { m_vItems.RemoveAt(i); return true; } } return false; } private void ClickHandler(object sender, EventArgs args) { ToolStripMenuItem tsmi = (sender as ToolStripMenuItem); if(tsmi == null) { Debug.Assert(false); return; } Debug.Assert(m_lMruMenuItems.Contains(tsmi)); ToolStripMenuItem tsmiParent = (tsmi.OwnerItem as ToolStripMenuItem); if(tsmiParent == null) { Debug.Assert(false); return; } if(!m_lContainers.Contains(tsmiParent)) { Debug.Assert(false); return; } if(m_handler == null) { Debug.Assert(false); return; } string strName = tsmi.Text; object oTag = tsmi.Tag; m_handler.OnMruExecute(strName, oTag, tsmiParent); // MoveItemToTop(strName); } private void ClearHandler(object sender, EventArgs e) { if(m_handler != null) m_handler.OnMruClear(); else { Debug.Assert(false); } } private void OnDropDownOpening(object sender, EventArgs e) { UpdateMenu(sender); } } } KeePass/UI/KeyboardControl.cs0000664000000000000000000001011013222430414015042 0ustar rootroot/* KeePass Password Safe - The Open-Source Password Manager Copyright (C) 2003-2018 Dominik Reichl This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ /* using System; using System.Collections.Generic; using System.Text; using System.Windows.Forms; using System.Drawing; using System.Diagnostics; namespace KeePass.UI { public sealed class KblButton { public string Text = null; public string Command = null; public Rectangle Position = Rectangle.Empty; public KblButton() { } public KblButton(string strText, string strCommand) { this.Text = strText; this.Command = strCommand; } } public sealed class KbcLayout { public List> Rows = new List>(); public static KbcLayout Default { get { KbcLayout l = new KbcLayout(); List r = new List(); r.Add(new KblButton("1", null)); r.Add(new KblButton("2", null)); r.Add(new KblButton("3", null)); r.Add(new KblButton("4", null)); r.Add(new KblButton("5", null)); r.Add(new KblButton("6", null)); r.Add(new KblButton("7", null)); r.Add(new KblButton("8", null)); r.Add(new KblButton("9", null)); r.Add(new KblButton("0", null)); l.Rows.Add(r); return l; } } } public sealed class KeyboardControl : Control { private KbcLayout m_l = null; private int m_iLayoutW = -1, m_iLayoutH = -1; private CustomToolStripRendererEx m_renderer = new CustomToolStripRendererEx(); public void InitEx(KbcLayout l) { m_l = l; } private void ComputeLayoutEx() { if(m_l == null) { Debug.Assert(false); return; } int w = this.ClientSize.Width, h = this.ClientSize.Height; int nRows = m_l.Rows.Count; float fBtnH = (float)h / (float)(nRows + 1); float fBtnHSkip = ((float)h - (fBtnH * (float)nRows)) / (float)(nRows + 1); float y = 0.0f; for(int iy = 0; iy < nRows; ++iy) { y += fBtnHSkip; int nColumns = m_l.Rows[iy].Count; float fBtnW = (float)w / (nColumns + 1); float fBtnWSkip = ((float)w - (fBtnW * (float)nColumns)) / (float)(nColumns + 1); float x = 0.0f; for(int ix = 0; ix < nColumns; ++ix) { x += fBtnWSkip; m_l.Rows[iy][ix].Position = new Rectangle((int)(x + 0.00001f), (int)(y + 0.00001f), (int)fBtnW, (int)fBtnH); } } } protected override void OnPaint(PaintEventArgs e) { base.OnPaint(e); // Required if(m_l == null) return; Size szCli = this.ClientSize; if((m_iLayoutW != szCli.Width) || (m_iLayoutH != szCli.Height)) ComputeLayoutEx(); Graphics g = e.Graphics; Rectangle rectClip = e.ClipRectangle; foreach(List vRow in m_l.Rows) { foreach(KblButton btn in vRow) { if(btn.Position.IntersectsWith(rectClip)) DrawButtonEx(btn, g); } } } private void DrawButtonEx(KblButton btn, Graphics g) { string strText = ((btn.Text ?? btn.Command) ?? string.Empty); ToolStripItemRenderEventArgs e = new ToolStripItemRenderEventArgs(g, new ToolStripButton(strText)); m_renderer.DrawMenuItemBackground(e); } protected override void OnPaintBackground(PaintEventArgs pevent) { using(SolidBrush brush = new SolidBrush(SystemColors.Control)) { pevent.Graphics.FillRectangle(brush, pevent.ClipRectangle); } } } } */ KeePass/UI/DynamicMenu.cs0000664000000000000000000000737713222430414014177 0ustar rootroot/* KeePass Password Safe - The Open-Source Password Manager Copyright (C) 2003-2018 Dominik Reichl This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ using System; using System.Collections.Generic; using System.Text; using System.Windows.Forms; using System.Drawing; using System.Diagnostics; namespace KeePass.UI { public sealed class DynamicMenuEventArgs : EventArgs { private string m_strItemName = string.Empty; private object m_objTag = null; public string ItemName { get { return m_strItemName; } } public object Tag { get { return m_objTag; } } public DynamicMenuEventArgs(string strItemName, object objTag) { Debug.Assert(strItemName != null); if(strItemName == null) throw new ArgumentNullException("strItemName"); m_strItemName = strItemName; m_objTag = objTag; } } public sealed class DynamicMenu { private ToolStripItemCollection m_tsicHost; private List m_vMenuItems = new List(); public event EventHandler MenuClick; // Constructor required by plugins public DynamicMenu(ToolStripDropDownItem tsmiHost) { Debug.Assert(tsmiHost != null); if(tsmiHost == null) throw new ArgumentNullException("tsmiHost"); m_tsicHost = tsmiHost.DropDownItems; } public DynamicMenu(ToolStripItemCollection tsicHost) { Debug.Assert(tsicHost != null); if(tsicHost == null) throw new ArgumentNullException("tsicHost"); m_tsicHost = tsicHost; } ~DynamicMenu() { try { Clear(); } // Throws under Mono catch(Exception) { Debug.Assert(false); } } public void Clear() { for(int i = 0; i < m_vMenuItems.Count; ++i) { ToolStripItem tsi = m_vMenuItems[m_vMenuItems.Count - i - 1]; if(tsi is ToolStripMenuItem) tsi.Click -= this.OnMenuClick; m_tsicHost.Remove(tsi); } m_vMenuItems.Clear(); } public ToolStripMenuItem AddItem(string strItemText, Image imgSmallIcon) { return AddItem(strItemText, imgSmallIcon, null); } public ToolStripMenuItem AddItem(string strItemText, Image imgSmallIcon, object objTag) { Debug.Assert(strItemText != null); if(strItemText == null) throw new ArgumentNullException("strItemText"); ToolStripMenuItem tsmi = new ToolStripMenuItem(strItemText); tsmi.Click += this.OnMenuClick; tsmi.Tag = objTag; if(imgSmallIcon != null) tsmi.Image = imgSmallIcon; m_tsicHost.Add(tsmi); m_vMenuItems.Add(tsmi); return tsmi; } public void AddSeparator() { ToolStripSeparator sep = new ToolStripSeparator(); m_tsicHost.Add(sep); m_vMenuItems.Add(sep); } private void OnMenuClick(object sender, EventArgs e) { ToolStripItem tsi = (sender as ToolStripItem); Debug.Assert(tsi != null); if(tsi == null) return; string strText = tsi.Text; Debug.Assert(strText != null); if(strText == null) return; DynamicMenuEventArgs args = new DynamicMenuEventArgs(strText, tsi.Tag); if(this.MenuClick != null) this.MenuClick(sender, args); } } } KeePass/UI/TaskbarList.cs0000664000000000000000000001131613222430414014175 0ustar rootroot/* KeePass Password Safe - The Open-Source Password Manager Copyright (C) 2003-2018 Dominik Reichl This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ using System; using System.Collections.Generic; using System.Text; using System.Runtime.InteropServices; using System.Diagnostics; using System.Windows.Forms; using System.Drawing; // using KeePass.Native; namespace KeePass.UI { public static class TaskbarList { private static bool m_bInitialized = false; private static ITaskbarList3 m_tbList = null; private static bool EnsureInitialized() { if(m_bInitialized) return (m_tbList != null); try { m_tbList = (ITaskbarList3)(new CTaskbarList()); m_tbList.HrInit(); } catch(Exception) { m_tbList = null; } m_bInitialized = true; return (m_tbList != null); } public static void SetProgressValue(Form fWindow, UInt64 ullCompleted, UInt64 ullTotal) { if(!EnsureInitialized()) return; try { m_tbList.SetProgressValue(fWindow.Handle, ullCompleted, ullTotal); } catch(Exception) { Debug.Assert(false); } } public static void SetProgressState(Form fWindow, TbpFlag tbpFlags) { if(!EnsureInitialized()) return; try { m_tbList.SetProgressState(fWindow.Handle, tbpFlags); } catch(Exception) { Debug.Assert(false); } } public static void SetOverlayIcon(Form fWindow, Icon iconOverlay, string strDescription) { if(!EnsureInitialized()) return; try { m_tbList.SetOverlayIcon(fWindow.Handle, ((iconOverlay == null) ? IntPtr.Zero : iconOverlay.Handle), strDescription); } catch(Exception) { Debug.Assert(false); } } /* public static void SetThumbnailClip(IntPtr hWnd, Rectangle? rect) { if(!EnsureInitialized()) return; try { if(!rect.HasValue) m_tbList.SetThumbnailClip(hWnd, IntPtr.Zero); else { NativeMethods.RECT rc = new NativeMethods.RECT(rect.Value); IntPtr prc = Marshal.AllocCoTaskMem(Marshal.SizeOf( typeof(NativeMethods.RECT))); Marshal.StructureToPtr(rc, prc, false); m_tbList.SetThumbnailClip(hWnd, prc); Marshal.DestroyStructure(prc, typeof(NativeMethods.RECT)); Marshal.FreeCoTaskMem(prc); } } catch(Exception) { Debug.Assert(false); } } */ } // States are mutually exclusive, see MSDN public enum TbpFlag { NoProgress = 0x0, Indeterminate = 0x1, Normal = 0x2, Error = 0x4, Paused = 0x8 } internal enum TbatFlag { None = 0x0, UseMdiThumbnail = 0x1, UseMdiLivePreview = 0x2 } [ComImport] [Guid("EA1AFB91-9E28-4B86-90E9-9E9F8A5EEFAF")] // [Guid("C43DC798-95D1-4BEA-9030-BB99E2983A1A")] // 4 [InterfaceType(ComInterfaceType.InterfaceIsIUnknown)] internal interface ITaskbarList3 { // ITaskbarList void HrInit(); void AddTab(IntPtr hwnd); void DeleteTab(IntPtr hwnd); void ActivateTab(IntPtr hwnd); void SetActiveAlt(IntPtr hwnd); // ITaskbarList2 void MarkFullscreenWindow(IntPtr hwnd, [MarshalAs(UnmanagedType.Bool)] bool fFullscreen); // ITaskbarList3 void SetProgressValue(IntPtr hwnd, UInt64 ullCompleted, UInt64 ullTotal); void SetProgressState(IntPtr hwnd, TbpFlag tbpFlags); void RegisterTab(IntPtr hwndTab, IntPtr hwndMDI); void UnregisterTab(IntPtr hwndTab); void SetTabOrder(IntPtr hwndTab, IntPtr hwndInsertBefore); void SetTabActive(IntPtr hwndTab, IntPtr hwndMDI, TbatFlag tbatFlags); void ThumbBarAddButtons(IntPtr hwnd, uint cButtons, IntPtr pButtons); void ThumbBarUpdateButtons(IntPtr hwnd, uint cButtons, IntPtr pButtons); void ThumbBarSetImageList(IntPtr hwnd, IntPtr himl); void SetOverlayIcon(IntPtr hwnd, IntPtr hIcon, [MarshalAs(UnmanagedType.LPWStr)] string pszDescription); void SetThumbnailTooltip(IntPtr hwnd, [MarshalAs(UnmanagedType.LPWStr)] string pszTip); void SetThumbnailClip(IntPtr hwnd, IntPtr prcClip); } [ComImport] [Guid("56FDF344-FD6D-11D0-958A-006097C9A090")] [ClassInterface(ClassInterfaceType.None)] internal class CTaskbarList { } } KeePass/UI/AsyncPwListUpdate.cs0000664000000000000000000001566513222430412015346 0ustar rootroot/* KeePass Password Safe - The Open-Source Password Manager Copyright (C) 2003-2018 Dominik Reichl This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ using System; using System.Collections.Generic; using System.Text; using System.Windows.Forms; using System.Threading; using System.Diagnostics; using KeePass.Forms; using KeePass.Util.Spr; using KeePassLib; namespace KeePass.UI { public sealed class PwListItem { private static long m_idNext = 1; private readonly PwEntry m_pe; public PwEntry Entry { get { return m_pe; } } private readonly long m_id; public long ListViewItemID { get { return m_id; } } public PwListItem(PwEntry pe) { if(pe == null) throw new ArgumentNullException("pe"); m_pe = pe; m_id = m_idNext; unchecked { ++m_idNext; } } } public delegate string PwTextUpdateDelegate(string strText, PwListItem li); public sealed class AsyncPwListUpdate { private readonly ListView m_lv; private readonly object m_objListEditSync = new object(); public object ListEditSyncObject { get { return m_objListEditSync; } } private Dictionary m_dValidIDs = new Dictionary(); private readonly object m_objValidIDsSync = new object(); private sealed class LviUpdInfo { public ListView ListView { get; set; } public long UpdateID { get; set; } public string Text { get; set; } public PwListItem ListItem { get; set; } public int IndexHint { get; set; } public int SubItem { get; set; } public PwTextUpdateDelegate Function { get; set; } public object ListEditSyncObject { get; set; } public object ValidIDsSyncObject { get; set; } public Dictionary ValidIDs { get; set; } } public AsyncPwListUpdate(ListView lv) { if(lv == null) throw new ArgumentNullException("lv"); m_lv = lv; } public void Queue(string strText, PwListItem li, int iIndexHint, int iSubItem, PwTextUpdateDelegate f) { if(strText == null) { Debug.Assert(false); return; } if(li == null) { Debug.Assert(false); return; } if(iSubItem < 0) { Debug.Assert(false); return; } if(f == null) { Debug.Assert(false); return; } LviUpdInfo state = new LviUpdInfo(); state.ListView = m_lv; state.UpdateID = unchecked((li.ListViewItemID << 6) + iSubItem); state.Text = strText; state.ListItem = li; state.IndexHint = ((iIndexHint >= 0) ? iIndexHint : 0); state.SubItem = iSubItem; state.Function = f; state.ListEditSyncObject = m_objListEditSync; state.ValidIDsSyncObject = m_objValidIDsSync; state.ValidIDs = m_dValidIDs; lock(m_objValidIDsSync) { Debug.Assert(!m_dValidIDs.ContainsKey(state.UpdateID)); m_dValidIDs[state.UpdateID] = true; } try { if(!ThreadPool.QueueUserWorkItem(new WaitCallback(UpdateItemFn), state)) throw new InvalidOperationException(); } catch(Exception) { Debug.Assert(false); lock(m_objValidIDsSync) { m_dValidIDs.Remove(state.UpdateID); } } } /// /// Cancel all pending updates. This method is asynchronous, /// i.e. it returns immediately and the number of queued /// updates will decrease continually. /// public void CancelPendingUpdatesAsync() { lock(m_objValidIDsSync) { List vKeys = new List(m_dValidIDs.Keys); foreach(long lKey in vKeys) { m_dValidIDs[lKey] = false; } } } public void WaitAll() { while(true) { lock(m_objValidIDsSync) { if(m_dValidIDs.Count == 0) break; } Thread.Sleep(4); Application.DoEvents(); } } private static void UpdateItemFn(object state) { LviUpdInfo lui = (state as LviUpdInfo); if(lui == null) { Debug.Assert(false); return; } try // Avoid cross-thread exceptions { bool bWork; lock(lui.ValidIDsSyncObject) { if(!lui.ValidIDs.TryGetValue(lui.UpdateID, out bWork)) { Debug.Assert(false); return; } } if(bWork) { string strNew = lui.Function(lui.Text, lui.ListItem); if(strNew == null) { Debug.Assert(false); return; } if(strNew == lui.Text) return; // if(lui.ListView.InvokeRequired) lui.ListView.Invoke(new SetItemTextDelegate( SetItemText), new object[] { strNew, lui }); // else SetItemText(strNew, lui); } } catch(Exception) { Debug.Assert(false); } finally { try // Avoid cross-thread exceptions { lock(lui.ValidIDsSyncObject) { if(!lui.ValidIDs.Remove(lui.UpdateID)) { Debug.Assert(false); } } } catch(Exception) { Debug.Assert(false); } } } private delegate void SetItemTextDelegate(string strText, LviUpdInfo lui); private static void SetItemText(string strText, LviUpdInfo lui) { try // Avoid cross-thread exceptions { long lTargetID = lui.ListItem.ListViewItemID; int iIndexHint = lui.IndexHint; lock(lui.ListEditSyncObject) { ListView.ListViewItemCollection lvic = lui.ListView.Items; int nCount = lvic.Count; // for(int i = 0; i < nCount; ++i) for(int i = nCount; i > 0; --i) { int j = ((iIndexHint + i) % nCount); ListViewItem lvi = lvic[j]; PwListItem li = (lvi.Tag as PwListItem); if(li == null) { Debug.Assert(false); continue; } if(li.ListViewItemID != lTargetID) continue; lvi.SubItems[lui.SubItem].Text = strText; break; } } } catch(Exception) { Debug.Assert(false); } } internal static string SprCompileFn(string strText, PwListItem li) { string strCmp = null; while(strCmp == null) { try { strCmp = SprEngine.Compile(strText, MainForm.GetEntryListSprContext( li.Entry, Program.MainForm.DocumentManager.SafeFindContainerOf( li.Entry))); } catch(InvalidOperationException) { } // Probably collection changed catch(NullReferenceException) { } // Objects disposed already catch(Exception) { Debug.Assert(false); } } if(strCmp == strText) return strText; return (Program.Config.MainWindow.EntryListShowDerefDataAndRefs ? (strCmp + " - " + strText) : strCmp); } } } KeePass/UI/ListSorter.cs0000664000000000000000000000704413222430414014067 0ustar rootroot/* KeePass Password Safe - The Open-Source Password Manager Copyright (C) 2003-2018 Dominik Reichl This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ using System; using System.Collections; using System.Windows.Forms; using System.ComponentModel; using System.Diagnostics; using KeePass.Resources; using KeePassLib.Utility; namespace KeePass.UI { public sealed class ListSorter : IComparer { // Cached version of a string representing infinity private readonly string m_strNeverExpires; private int m_nColumn = -1; [DefaultValue(-1)] public int Column { get { return m_nColumn; } /// Only provided for XML serialization, do not use set { m_nColumn = value; } } private SortOrder m_oSort = SortOrder.Ascending; public SortOrder Order { get { return m_oSort; } /// Only provided for XML serialization, do not use set { m_oSort = value; } } private bool m_bCompareNaturally = true; [DefaultValue(true)] public bool CompareNaturally { get { return m_bCompareNaturally; } /// Only provided for XML serialization, do not use set { m_bCompareNaturally = value; } } private bool m_bCompareTimes = false; [DefaultValue(false)] public bool CompareTimes { get { return m_bCompareTimes; } /// Only provided for XML serialization, do not use set { m_bCompareTimes = value; } } public ListSorter() { m_strNeverExpires = KPRes.NeverExpires; } public ListSorter(int nColumn, SortOrder sortOrder, bool bCompareNaturally, bool bCompareTimes) { m_strNeverExpires = KPRes.NeverExpires; m_nColumn = nColumn; Debug.Assert(sortOrder != SortOrder.None); if(sortOrder != SortOrder.None) m_oSort = sortOrder; m_bCompareNaturally = bCompareNaturally; m_bCompareTimes = bCompareTimes; } public int Compare(object x, object y) { bool bSwap = (m_oSort != SortOrder.Ascending); ListViewItem lviX = (bSwap ? (ListViewItem)y : (ListViewItem)x); ListViewItem lviY = (bSwap ? (ListViewItem)x : (ListViewItem)y); string strL, strR; Debug.Assert(lviX.SubItems.Count == lviY.SubItems.Count); if((m_nColumn <= 0) || (lviX.SubItems.Count <= m_nColumn) || (lviY.SubItems.Count <= m_nColumn)) { strL = lviX.Text; strR = lviY.Text; } else { strL = lviX.SubItems[m_nColumn].Text; strR = lviY.SubItems[m_nColumn].Text; } if(m_bCompareTimes) { if((strL == m_strNeverExpires) || (strR == m_strNeverExpires)) return strL.CompareTo(strR); DateTime dtL = TimeUtil.FromDisplayString(strL); DateTime dtR = TimeUtil.FromDisplayString(strR); Debug.Assert(dtL.Kind == dtR.Kind); return dtL.CompareTo(dtR); } if(m_bCompareNaturally) return StrUtil.CompareNaturally(strL, strR); return string.Compare(strL, strR, true); } } } KeePass/UI/CheckedLVItemDXList.cs0000664000000000000000000002057013222430412015451 0ustar rootroot/* KeePass Password Safe - The Open-Source Password Manager Copyright (C) 2003-2018 Dominik Reichl This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ using System; using System.Collections.Generic; using System.Text; using System.Windows.Forms; using System.Drawing; using System.Reflection; using System.Diagnostics; using KeePass.App; using KeePass.App.Configuration; using KeePass.Util; using KeePassLib.Utility; namespace KeePass.UI { public enum CheckItemLinkType { None = 0, CheckedChecked, UncheckedUnchecked, CheckedUnchecked, UncheckedChecked } public sealed class CheckedLVItemDXList { private ListView m_lv; private List m_lItems = new List(); private List m_lLinks = new List(); private bool m_bUseEnforcedConfig; private sealed class ClviInfo { private object m_o; // Never null public object Object { get { return m_o; } } // private string m_strPropName; // Never null // public string PropertyName { get { return m_strPropName; } } private PropertyInfo m_pi; // Never null public PropertyInfo PropertyInfo { get { return m_pi; } } private ListViewItem m_lvi; // Never null public ListViewItem ListViewItem { get { return m_lvi; } } public bool PropertyValue { get { return (bool)m_pi.GetValue(m_o, null); } set { m_pi.SetValue(m_o, value, null); } } private bool m_bReadOnly = false; public bool ReadOnly { get { return m_bReadOnly; } set { m_bReadOnly = value; } } public ClviInfo(object pContainer, string strPropertyName, ListViewItem lvi) { if(pContainer == null) throw new ArgumentNullException("pContainer"); if(strPropertyName == null) throw new ArgumentNullException("strPropertyName"); if(strPropertyName.Length == 0) throw new ArgumentException("strPropertyName"); // if(lvi == null) throw new ArgumentNullException("lvi"); m_o = pContainer; // m_strPropName = strPropertyName; m_lvi = lvi; Type t = pContainer.GetType(); m_pi = t.GetProperty(strPropertyName); if((m_pi == null) || (m_pi.PropertyType != typeof(bool)) || !m_pi.CanRead || !m_pi.CanWrite) throw new ArgumentException("strPropertyName"); } } private sealed class CheckItemLink { private ListViewItem m_lvSource; public ListViewItem Source { get { return m_lvSource; } } private ListViewItem m_lvTarget; public ListViewItem Target { get { return m_lvTarget; } } private CheckItemLinkType m_t; public CheckItemLinkType Type { get { return m_t; } } public CheckItemLink(ListViewItem lviSource, ListViewItem lviTarget, CheckItemLinkType cilType) { m_lvSource = lviSource; m_lvTarget = lviTarget; m_t = cilType; } } [Obsolete] public CheckedLVItemDXList(ListView lv) { Construct(lv, false); } public CheckedLVItemDXList(ListView lv, bool bUseEnforcedConfig) { Construct(lv, bUseEnforcedConfig); } private void Construct(ListView lv, bool bUseEnforcedConfig) { if(lv == null) throw new ArgumentNullException("lv"); m_lv = lv; m_bUseEnforcedConfig = bUseEnforcedConfig; m_lv.ItemChecked += this.OnItemCheckedChanged; } #if DEBUG ~CheckedLVItemDXList() { Debug.Assert(m_lv == null); // Release should have been called } #endif public void Release() { if(m_lv == null) { Debug.Assert(false); return; } m_lItems.Clear(); m_lLinks.Clear(); m_lv.ItemChecked -= this.OnItemCheckedChanged; m_lv = null; } public void UpdateData(bool bGuiToInternals) { if(m_lv == null) { Debug.Assert(false); return; } Color clr = SystemColors.ControlText; float fH, fS, fV; UIUtil.ColorToHsv(clr, out fH, out fS, out fV); if(fV >= 0.5f) // Text color is rather light clr = UIUtil.ColorFromHsv(fH, 0.0f, 0.40f); else // Text color is rather dark clr = UIUtil.ColorFromHsv(fH, 0.0f, 0.60f); foreach(ClviInfo clvi in m_lItems) { ListViewItem lvi = clvi.ListViewItem; Debug.Assert(lvi.Index >= 0); Debug.Assert(m_lv.Items.IndexOf(lvi) >= 0); if(bGuiToInternals) { bool bChecked = lvi.Checked; clvi.PropertyValue = bChecked; } else // Internals to GUI { bool bValue = clvi.PropertyValue; lvi.Checked = bValue; if(clvi.ReadOnly) lvi.ForeColor = clr; } } } public ListViewItem CreateItem(object pContainer, string strPropertyName, ListViewGroup lvgContainer, string strDisplayString) { return CreateItem(pContainer, strPropertyName, lvgContainer, strDisplayString, null); } public ListViewItem CreateItem(object pContainer, string strPropertyName, ListViewGroup lvgContainer, string strDisplayString, bool? obReadOnly) { if(pContainer == null) throw new ArgumentNullException("pContainer"); if(strPropertyName == null) throw new ArgumentNullException("strPropertyName"); if(strPropertyName.Length == 0) throw new ArgumentException("strPropertyName"); if(strDisplayString == null) throw new ArgumentNullException("strDisplayString"); if(m_lv == null) { Debug.Assert(false); return null; } ListViewItem lvi = new ListViewItem(strDisplayString); ClviInfo clvi = new ClviInfo(pContainer, strPropertyName, lvi); if(obReadOnly.HasValue) clvi.ReadOnly = obReadOnly.Value; else DetermineReadOnlyState(clvi); if(lvgContainer != null) { lvi.Group = lvgContainer; Debug.Assert(lvgContainer.Items.IndexOf(lvi) >= 0); Debug.Assert(m_lv.Groups.IndexOf(lvgContainer) >= 0); } m_lv.Items.Add(lvi); m_lItems.Add(clvi); return lvi; } public void AddLink(ListViewItem lviSource, ListViewItem lviTarget, CheckItemLinkType t) { if(lviSource == null) { Debug.Assert(false); return; } if(lviTarget == null) { Debug.Assert(false); return; } if(m_lv == null) { Debug.Assert(false); return; } Debug.Assert(GetItem(lviSource) != null); Debug.Assert(GetItem(lviTarget) != null); m_lLinks.Add(new CheckItemLink(lviSource, lviTarget, t)); } private ClviInfo GetItem(ListViewItem lvi) { if(lvi == null) { Debug.Assert(false); return null; } foreach(ClviInfo clvi in m_lItems) { if(clvi.ListViewItem == lvi) return clvi; } return null; } private void OnItemCheckedChanged(object sender, ItemCheckedEventArgs e) { ListViewItem lvi = e.Item; if(lvi == null) { Debug.Assert(false); return; } bool bChecked = lvi.Checked; ClviInfo clvi = GetItem(lvi); if(clvi != null) { if(clvi.ReadOnly && (bChecked != clvi.PropertyValue)) { lvi.Checked = clvi.PropertyValue; return; } } foreach(CheckItemLink cl in m_lLinks) { if(cl.Source == lvi) { if(cl.Target.Index < 0) continue; if((cl.Type == CheckItemLinkType.CheckedChecked) && bChecked && !cl.Target.Checked) cl.Target.Checked = true; else if((cl.Type == CheckItemLinkType.UncheckedUnchecked) && !bChecked && cl.Target.Checked) cl.Target.Checked = false; else if((cl.Type == CheckItemLinkType.CheckedUnchecked) && bChecked && cl.Target.Checked) cl.Target.Checked = false; else if((cl.Type == CheckItemLinkType.UncheckedChecked) && !bChecked && !cl.Target.Checked) cl.Target.Checked = true; } } } private void DetermineReadOnlyState(ClviInfo clvi) { if(clvi == null) { Debug.Assert(false); return; } if(!m_bUseEnforcedConfig) clvi.ReadOnly = false; else clvi.ReadOnly = AppConfigEx.IsOptionEnforced(clvi.Object, clvi.PropertyInfo); } } } KeePass/UI/ListViewStateEx.cs0000664000000000000000000000327613222430414015024 0ustar rootroot/* KeePass Password Safe - The Open-Source Password Manager Copyright (C) 2003-2018 Dominik Reichl This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ using System; using System.Collections.Generic; using System.Text; using System.Windows.Forms; namespace KeePass.UI { internal sealed class ListViewStateEx { public readonly int[] ColumnWidths; public ListViewStateEx(ListView lv) { if(lv == null) throw new ArgumentNullException("lv"); this.ColumnWidths = new int[lv.Columns.Count]; for(int iColumn = 0; iColumn < lv.Columns.Count; ++iColumn) this.ColumnWidths[iColumn] = lv.Columns[iColumn].Width; } public bool CompareTo(ListView lv) { if(lv == null) throw new ArgumentNullException("lv"); if(lv.Columns.Count != this.ColumnWidths.Length) return false; for(int iColumn = 0; iColumn < this.ColumnWidths.Length; ++iColumn) { if(lv.Columns[iColumn].Width != this.ColumnWidths[iColumn]) return false; } return true; } } } KeePass/UI/GlobalWindowManager.cs0000664000000000000000000002150213222430414015633 0ustar rootroot/* KeePass Password Safe - The Open-Source Password Manager Copyright (C) 2003-2018 Dominik Reichl This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ using System; using System.Collections.Generic; using System.Text; using System.Diagnostics; using System.Windows.Forms; using System.Drawing; using KeePass.App; using KeePass.Forms; using KeePassLib.Native; using KeePassLib.Utility; namespace KeePass.UI { public sealed class GwmWindowEventArgs : EventArgs { private Form m_form; public Form Form { get { return m_form; } } private IGwmWindow m_gwmWindow; public IGwmWindow GwmWindow { get { return m_gwmWindow; } } public GwmWindowEventArgs(Form form, IGwmWindow gwmWindow) { m_form = form; m_gwmWindow = gwmWindow; } } public static class GlobalWindowManager { private static List> g_vWindows = new List>(); private static List g_vDialogs = new List(); private static readonly object g_oSyncRoot = new object(); public static uint WindowCount { get { uint u; lock(g_oSyncRoot) { u = ((uint)(g_vWindows.Count + g_vDialogs.Count) + MessageService.CurrentMessageCount); } return u; } } public static bool CanCloseAllWindows { get { lock(g_oSyncRoot) { if(g_vDialogs.Count > 0) return false; if(MessageService.CurrentMessageCount > 0) return false; foreach(KeyValuePair kvp in g_vWindows) { if(kvp.Value == null) return false; else if(!kvp.Value.CanCloseWithoutDataLoss) return false; } } return true; } } public static Form TopWindow { get { lock(g_oSyncRoot) { int n = g_vWindows.Count; if(n > 0) return g_vWindows[n - 1].Key; } return null; } } public static event EventHandler WindowAdded; public static event EventHandler WindowRemoved; public static void AddWindow(Form form) { AddWindow(form, null); } public static void AddWindow(Form form, IGwmWindow wnd) { Debug.Assert(form != null); if(form == null) throw new ArgumentNullException("form"); KeyValuePair kvp = new KeyValuePair( form, wnd); lock(g_oSyncRoot) { Debug.Assert(g_vWindows.IndexOf(kvp) < 0); g_vWindows.Add(kvp); } // The control box must be enabled, otherwise DPI scaling // doesn't work due to a .NET bug: // https://connect.microsoft.com/VisualStudio/feedback/details/694242/difference-dpi-let-the-button-cannot-appear-completely-while-remove-the-controlbox-for-the-form // https://social.msdn.microsoft.com/Forums/en-US/winforms/thread/67407313-8cb2-42b4-afb9-8be816f0a601/ Debug.Assert(form.ControlBox); form.TopMost = Program.Config.MainWindow.AlwaysOnTop; // Form formParent = form.ParentForm; // if(formParent != null) form.TopMost = formParent.TopMost; // else { Debug.Assert(false); } // form.Font = new System.Drawing.Font(System.Drawing.SystemFonts.MessageBoxFont.Name, 12.0f); CustomizeForm(form); MonoWorkarounds.ApplyTo(form); if(GlobalWindowManager.WindowAdded != null) GlobalWindowManager.WindowAdded(null, new GwmWindowEventArgs( form, wnd)); } public static void AddDialog(CommonDialog dlg) { Debug.Assert(dlg != null); if(dlg == null) throw new ArgumentNullException("dlg"); lock(g_oSyncRoot) { g_vDialogs.Add(dlg); } } public static void RemoveWindow(Form form) { Debug.Assert(form != null); if(form == null) throw new ArgumentNullException("form"); lock(g_oSyncRoot) { for(int i = 0; i < g_vWindows.Count; ++i) { if(g_vWindows[i].Key == form) { if(GlobalWindowManager.WindowRemoved != null) GlobalWindowManager.WindowRemoved(null, new GwmWindowEventArgs( form, g_vWindows[i].Value)); MonoWorkarounds.Release(form); #if DEBUG DebugClose(form); #endif g_vWindows.RemoveAt(i); return; } } } Debug.Assert(false); // Window not found } public static void RemoveDialog(CommonDialog dlg) { Debug.Assert(dlg != null); if(dlg == null) throw new ArgumentNullException("dlg"); lock(g_oSyncRoot) { Debug.Assert(g_vDialogs.IndexOf(dlg) >= 0); g_vDialogs.Remove(dlg); } } public static void CloseAllWindows() { Debug.Assert(GlobalWindowManager.CanCloseAllWindows); KeyValuePair[] vWindows; lock(g_oSyncRoot) { vWindows = g_vWindows.ToArray(); } Array.Reverse(vWindows); // Close windows in reverse order foreach(KeyValuePair kvp in vWindows) { if(kvp.Value == null) continue; else if(kvp.Value.CanCloseWithoutDataLoss) { if(kvp.Key.InvokeRequired) kvp.Key.Invoke(new CloseFormDelegate( GlobalWindowManager.CloseForm), kvp.Key); else CloseForm(kvp.Key); Application.DoEvents(); } } } private delegate void CloseFormDelegate(Form f); private static void CloseForm(Form f) { try { f.DialogResult = DialogResult.Cancel; f.Close(); } catch(Exception) { Debug.Assert(false); } } public static bool HasWindow(IntPtr hWindow) { lock(g_oSyncRoot) { foreach(KeyValuePair kvp in g_vWindows) { if(kvp.Key.Handle == hWindow) return true; } } return false; } /* internal static bool HasWindowMW(IntPtr hWindow) { if(HasWindow(hWindow)) return true; MainForm mf = Program.MainForm; if((mf != null) && (mf.Handle == hWindow)) return true; return false; } */ internal static bool ActivateTopWindow() { try { Form f = GlobalWindowManager.TopWindow; if(f == null) return false; f.Activate(); return true; } catch(Exception) { Debug.Assert(false); } return false; } public static void CustomizeForm(Form f) { CustomizeControl(f); try { const string strForms = "KeePass.Forms."; Debug.Assert(typeof(PwEntryForm).FullName.StartsWith(strForms)); if(f.GetType().FullName.StartsWith(strForms) && (f.FormBorderStyle == FormBorderStyle.FixedDialog)) UIUtil.RemoveBannerIfNecessary(f); } catch(Exception) { Debug.Assert(false); } } public static void CustomizeControl(Control c) { if(UISystemFonts.OverrideUIFont) { Font font = UISystemFonts.DefaultFont; if(font != null) CustomizeFont(c, font); } } private static void CustomizeFont(Control c, Font font) { if((c is Form) || (c is ToolStrip) || (c is ContextMenuStrip)) c.Font = font; foreach(Control cSub in c.Controls) CustomizeFont(cSub, font); if(c.ContextMenuStrip != null) CustomizeFont(c.ContextMenuStrip, font); } #if DEBUG private static void DebugClose(Control c) { if(c == null) { Debug.Assert(false); return; } List lInv = new List(); lInv.Add(Program.MainForm.ClientIcons); ListView lv = (c as ListView); if(lv != null) { // Image list properties must be set to null manually // when closing, otherwise we get a memory leak // (because the image list holds event handlers to // the list) Debug.Assert(!lInv.Contains(lv.LargeImageList)); Debug.Assert(!lInv.Contains(lv.SmallImageList)); } TreeView tv = (c as TreeView); if(tv != null) { Debug.Assert(!lInv.Contains(tv.ImageList)); // See above } TabControl tc = (c as TabControl); if(tc != null) { Debug.Assert(!lInv.Contains(tc.ImageList)); // See above } ToolStrip ts = (c as ToolStrip); if(ts != null) { Debug.Assert(!lInv.Contains(ts.ImageList)); // See above } Button btn = (c as Button); if(btn != null) { Debug.Assert(!lInv.Contains(btn.ImageList)); // See above } foreach(Control cc in c.Controls) DebugClose(cc); } #endif } } KeePass/UI/SecureEdit.cs0000664000000000000000000002652213222430414014013 0ustar rootroot/* KeePass Password Safe - The Open-Source Password Manager Copyright (C) 2003-2018 Dominik Reichl This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ using System; using System.Diagnostics; using System.Runtime.InteropServices; using System.Security; using System.Text; using System.Threading; using System.Windows.Forms; using KeePassLib.Security; using KeePassLib.Utility; namespace KeePass.UI { /// /// Secure edit control class. Supports storing passwords in an encrypted /// form in the process memory. /// public sealed class SecureEdit { private static char? m_ochPasswordChar = null; internal static char PasswordChar { get { if(m_ochPasswordChar.HasValue) return m_ochPasswordChar.Value; // On Windows 98 / ME, an ANSI character must be used as // password char m_ochPasswordChar = ((Environment.OSVersion.Platform == PlatformID.Win32Windows) ? '\u00D7' : '\u25CF'); return m_ochPasswordChar.Value; } } private TextBox m_tbPassword = null; private EventHandler m_evTextChanged = null; private static readonly ProtectedString g_psEmpty = new ProtectedString( true, new byte[0]); // With ProtectedString.Empty no incremental protection (Remove/Insert) private ProtectedString m_psText = g_psEmpty; private bool m_bBlockTextChanged = false; private bool m_bFirstGotFocus = true; private bool m_bSecureDesktop = false; public bool SecureDesktopMode { get { return m_bSecureDesktop; } set { m_bSecureDesktop = value; } } public uint TextLength { get { return (uint)m_psText.Length; } } /// /// Construct a new SecureEdit object. You must call the /// Attach member function to associate the secure edit control /// with a text box. /// public SecureEdit() { } ~SecureEdit() { try { Detach(); } catch(Exception) { Debug.Assert(false); } } /// /// Associate the current secure edit object with a text box. /// /// Text box to link to. /// Initial protection flag. public void Attach(TextBox tbPasswordBox, EventHandler evTextChanged, bool bHidePassword) { Debug.Assert(tbPasswordBox != null); if(tbPasswordBox == null) throw new ArgumentNullException("tbPasswordBox"); Detach(); m_tbPassword = tbPasswordBox; m_evTextChanged = evTextChanged; // Initialize to zero-length string m_tbPassword.Text = string.Empty; Debug.Assert(m_tbPassword.SelectionStart == 0); Debug.Assert(m_tbPassword.SelectionLength == 0); m_psText = g_psEmpty; EnableProtection(bHidePassword); if(m_evTextChanged != null) m_evTextChanged(m_tbPassword, EventArgs.Empty); if(!m_bSecureDesktop) m_tbPassword.AllowDrop = true; // Register event handler m_tbPassword.TextChanged += this.OnPasswordTextChanged; m_tbPassword.GotFocus += this.OnGotFocus; if(!m_bSecureDesktop) { m_tbPassword.DragEnter += this.OnDragCheck; m_tbPassword.DragOver += this.OnDragCheck; m_tbPassword.DragDrop += this.OnDragDrop; } } /// /// Remove the current association. You should call this before the /// text box is destroyed. /// public void Detach() { if(m_tbPassword != null) { m_tbPassword.TextChanged -= this.OnPasswordTextChanged; m_tbPassword.GotFocus -= this.OnGotFocus; if(!m_bSecureDesktop) { m_tbPassword.DragEnter -= this.OnDragCheck; m_tbPassword.DragOver -= this.OnDragCheck; m_tbPassword.DragDrop -= this.OnDragDrop; } m_tbPassword = null; } } public void EnableProtection(bool bEnable) { if(m_tbPassword == null) { Debug.Assert(false); return; } if(!MonoWorkarounds.IsRequired(5795)) { if(bEnable) FontUtil.AssignDefault(m_tbPassword); else { FontUtil.SetDefaultFont(m_tbPassword); FontUtil.AssignDefaultMono(m_tbPassword, true); } } if(m_tbPassword.UseSystemPasswordChar == bEnable) return; m_tbPassword.UseSystemPasswordChar = bEnable; ShowCurrentPassword(-1, -1); } private void OnPasswordTextChanged(object sender, EventArgs e) { if(m_tbPassword == null) { Debug.Assert(false); return; } if(m_bBlockTextChanged) return; int nSelPos = m_tbPassword.SelectionStart; int nSelLen = m_tbPassword.SelectionLength; if(!m_tbPassword.UseSystemPasswordChar) { RemoveInsert(0, 0, m_tbPassword.Text); ShowCurrentPassword(nSelPos, nSelLen); return; } string strText = m_tbPassword.Text; int inxLeft = -1, inxRight = 0; StringBuilder sbNewPart = new StringBuilder(); char chPasswordChar = SecureEdit.PasswordChar; for(int i = 0; i < strText.Length; ++i) { if(strText[i] != chPasswordChar) { if(inxLeft == -1) inxLeft = i; inxRight = i; sbNewPart.Append(strText[i]); } } if(inxLeft < 0) RemoveInsert(nSelPos, strText.Length - nSelPos, string.Empty); else RemoveInsert(inxLeft, strText.Length - inxRight - 1, sbNewPart.ToString()); ShowCurrentPassword(nSelPos, nSelLen); // Check for m_tbPassword being null from on now; the // control might be disposed already (by the user handler // triggered by the ShowCurrentPassword call) if(m_tbPassword != null) m_tbPassword.ClearUndo(); // Would need special undo buffer } private void ShowCurrentPassword(int nSelStart, int nSelLength) { if(m_tbPassword == null) { Debug.Assert(false); return; } if(nSelStart < 0) nSelStart = m_tbPassword.SelectionStart; if(nSelLength < 0) nSelLength = m_tbPassword.SelectionLength; m_bBlockTextChanged = true; if(!m_tbPassword.UseSystemPasswordChar) m_tbPassword.Text = GetAsString(); else m_tbPassword.Text = new string(SecureEdit.PasswordChar, m_psText.Length); m_bBlockTextChanged = false; int nNewTextLen = m_tbPassword.TextLength; if(nSelStart < 0) { Debug.Assert(false); nSelStart = 0; } if(nSelStart > nNewTextLen) nSelStart = nNewTextLen; // Behind last char if(nSelLength < 0) { Debug.Assert(false); nSelLength = 0; } if((nSelStart + nSelLength) > nNewTextLen) nSelLength = nNewTextLen - nSelStart; m_tbPassword.SelectionStart = nSelStart; m_tbPassword.SelectionLength = nSelLength; if(m_evTextChanged != null) m_evTextChanged(m_tbPassword, EventArgs.Empty); } public byte[] ToUtf8() { // Debug.Assert(sizeof(char) == 2); // if(m_secString != null) // { // char[] vChars = new char[m_secString.Length]; // IntPtr p = Marshal.SecureStringToGlobalAllocUnicode(m_secString); // for(int i = 0; i < m_secString.Length; ++i) // vChars[i] = (char)Marshal.ReadInt16(p, i * 2); // Marshal.ZeroFreeGlobalAllocUnicode(p); // byte[] pb = StrUtil.Utf8.GetBytes(vChars); // MemUtil.ZeroArray(vChars); // return pb; // } // else return StrUtil.Utf8.GetBytes(m_strAlternativeSecString); return m_psText.ReadUtf8(); } private string GetAsString() { // if(m_secString != null) // { // IntPtr p = Marshal.SecureStringToGlobalAllocUnicode(m_secString); // string str = Marshal.PtrToStringUni(p); // Marshal.ZeroFreeGlobalAllocUnicode(p); // return str; // } // else return m_strAlternativeSecString; return m_psText.ReadString(); } private void RemoveInsert(int nLeftRem, int nRightRem, string strInsert) { Debug.Assert(nLeftRem >= 0); // if(m_secString != null) // { // while(m_secString.Length > (nLeftRem + nRightRem)) // m_secString.RemoveAt(nLeftRem); // for(int i = 0; i < strInsert.Length; ++i) // m_secString.InsertAt(nLeftRem + i, strInsert[i]); // } // else // { // StringBuilder sb = new StringBuilder(m_strAlternativeSecString); // while(sb.Length > (nLeftRem + nRightRem)) // sb.Remove(nLeftRem, 1); // sb.Insert(nLeftRem, strInsert); // m_strAlternativeSecString = sb.ToString(); // } try { int cr = m_psText.Length - (nLeftRem + nRightRem); if(cr >= 0) m_psText = m_psText.Remove(nLeftRem, cr); else { Debug.Assert(false); } Debug.Assert(m_psText.Length == (nLeftRem + nRightRem)); } catch(Exception) { Debug.Assert(false); } try { m_psText = m_psText.Insert(nLeftRem, strInsert); } catch(Exception) { Debug.Assert(false); } } public bool ContentsEqualTo(SecureEdit secOther) { Debug.Assert(secOther != null); if(secOther == null) return false; byte[] pbThis = ToUtf8(); byte[] pbOther = secOther.ToUtf8(); bool bEqual = MemUtil.ArraysEqual(pbThis, pbOther); MemUtil.ZeroByteArray(pbThis); MemUtil.ZeroByteArray(pbOther); return bEqual; } public void SetPassword(byte[] pbUtf8) { Debug.Assert(pbUtf8 != null); if(pbUtf8 == null) throw new ArgumentNullException("pbUtf8"); // if(m_secString != null) // { // m_secString.Clear(); // char[] vChars = StrUtil.Utf8.GetChars(pbUtf8); // for(int i = 0; i < vChars.Length; ++i) // { // m_secString.AppendChar(vChars[i]); // vChars[i] = char.MinValue; // } // } // else m_strAlternativeSecString = StrUtil.Utf8.GetString(pbUtf8); m_psText = new ProtectedString(true, pbUtf8); ShowCurrentPassword(0, 0); } private void OnGotFocus(object sender, EventArgs e) { if(m_tbPassword == null) { Debug.Assert(false); return; } if(m_bFirstGotFocus) { m_bFirstGotFocus = false; // OnGotFocus is not called when the box initially has the // focus; the user can select characters without triggering // OnGotFocus, thus we select all characters only if the // selection is in its original state (0, 0), otherwise // e.g. the selection restoration when hiding/unhiding does // not work the first time (because after restoring the // selection, we would override it here by selecting all) if((m_tbPassword.SelectionStart <= 0) && (m_tbPassword.SelectionLength <= 0)) m_tbPassword.SelectAll(); } } private void OnDragCheck(object sender, DragEventArgs e) { if(e.Data.GetDataPresent(typeof(string))) e.Effect = DragDropEffects.Copy; else e.Effect = DragDropEffects.None; } private void OnDragDrop(object sender, DragEventArgs e) { if(e.Data.GetDataPresent(typeof(string))) { string strData = (e.Data.GetData(typeof(string)) as string); if(strData == null) { Debug.Assert(false); return; } if(m_tbPassword != null) m_tbPassword.Paste(strData); } } } } KeePass/UI/EnableThemingInScope.cs0000664000000000000000000000752613222430414015745 0ustar rootroot/* KeePass Password Safe - The Open-Source Password Manager Copyright (C) 2003-2018 Dominik Reichl This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ using System; using System.Collections.Generic; using System.Text; using System.IO; using System.Runtime.InteropServices; using System.Security; using System.Security.Permissions; using System.Windows.Forms; using System.Diagnostics; using KeePass.Native; using KeePass.Util; namespace KeePass.UI { // Code derived from https://support.microsoft.com/kb/830033/ public sealed class EnableThemingInScope : IDisposable { private UIntPtr? m_nuCookie = null; private static readonly object m_oSync = new object(); private static IntPtr? m_nhCtx = null; public EnableThemingInScope(bool bEnable) { if(!bEnable) return; if(KeePassLib.Native.NativeLib.IsUnix()) return; try { if(OSFeature.Feature.IsPresent(OSFeature.Themes)) { if(EnsureActCtxCreated()) { UIntPtr u = UIntPtr.Zero; if(NativeMethods.ActivateActCtx(m_nhCtx.Value, ref u)) m_nuCookie = u; else { Debug.Assert(false); } } else { Debug.Assert(false); } } } catch(Exception) { Debug.Assert(false); } } ~EnableThemingInScope() { Debug.Assert(!m_nuCookie.HasValue); Dispose(false); } public void Dispose() { Dispose(true); GC.SuppressFinalize(this); } private void Dispose(bool bDisposing) { if(!m_nuCookie.HasValue) return; try { if(NativeMethods.DeactivateActCtx(0, m_nuCookie.Value)) m_nuCookie = null; else { Debug.Assert(false); } } catch(Exception) { Debug.Assert(false); } } public static void StaticDispose() { if(!m_nhCtx.HasValue) return; try { NativeMethods.ReleaseActCtx(m_nhCtx.Value); m_nhCtx = null; } catch(Exception) { Debug.Assert(false); } } private static bool EnsureActCtxCreated() { lock(m_oSync) { if(m_nhCtx.HasValue) return true; string strAsmLoc; FileIOPermission p = new FileIOPermission(PermissionState.None); p.AllFiles = FileIOPermissionAccess.PathDiscovery; p.Assert(); try { strAsmLoc = typeof(object).Assembly.Location; } finally { CodeAccessPermission.RevertAssert(); } if(string.IsNullOrEmpty(strAsmLoc)) { Debug.Assert(false); return false; } string strInstDir = Path.GetDirectoryName(strAsmLoc); string strMfLoc = Path.Combine(strInstDir, "XPThemes.manifest"); NativeMethods.ACTCTX ctx = new NativeMethods.ACTCTX(); ctx.cbSize = (uint)Marshal.SizeOf(typeof(NativeMethods.ACTCTX)); Debug.Assert(((IntPtr.Size == 4) && (ctx.cbSize == NativeMethods.ACTCTXSize32)) || ((IntPtr.Size == 8) && (ctx.cbSize == NativeMethods.ACTCTXSize64))); ctx.lpSource = strMfLoc; ctx.lpAssemblyDirectory = strInstDir; ctx.dwFlags = NativeMethods.ACTCTX_FLAG_ASSEMBLY_DIRECTORY_VALID; m_nhCtx = NativeMethods.CreateActCtx(ref ctx); if(NativeMethods.IsInvalidHandleValue(m_nhCtx.Value)) { Debug.Assert(false); m_nhCtx = null; return false; } } return true; } } } KeePass/UI/UISystemFonts.cs0000664000000000000000000001332113222430414014504 0ustar rootroot/* KeePass Password Safe - The Open-Source Password Manager Copyright (C) 2003-2018 Dominik Reichl This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ using System; using System.Collections.Generic; using System.Diagnostics; using System.Drawing; using System.IO; using System.Text; using System.Xml; using KeePass.Util; using KeePassLib.Native; using KeePassLib.Utility; namespace KeePass.UI { public static class UISystemFonts { private static bool m_bInitialized = false; private static Font m_fontUI = null; public static Font DefaultFont { get { EnsureInitialized(); return m_fontUI; } } private static Font m_fontList = null; public static Font ListFont { get { EnsureInitialized(); return m_fontList; } } internal static bool OverrideUIFont { get { return (NativeLib.IsUnix() && Program.Config.UI.ForceSystemFontUnix); } } private static void EnsureInitialized() { if(m_bInitialized) return; if(NativeLib.IsUnix()) { try { UnixLoadFonts(); } catch(Exception) { Debug.Assert(false); } } if(m_fontUI == null) m_fontUI = SystemFonts.DefaultFont; if(m_fontList == null) { if(UIUtil.VistaStyleListsSupported) { string str1 = SystemFonts.IconTitleFont.ToString(); string str2 = SystemFonts.StatusFont.ToString(); if(str1 == str2) m_fontList = SystemFonts.StatusFont; else m_fontList = m_fontUI; } else m_fontList = m_fontUI; } m_bInitialized = true; } private static void UnixLoadFonts() { // string strSession = Environment.GetEnvironmentVariable("DESKTOP_SESSION"); // "Default", "KDE", "Gnome", "Ubuntu", ... // string strKde = Environment.GetEnvironmentVariable("KDE_FULL_SESSION"); string strHome = Environment.GetFolderPath(Environment.SpecialFolder.Personal); if(string.IsNullOrEmpty(strHome)) { Debug.Assert(false); return; } strHome = UrlUtil.EnsureTerminatingSeparator(strHome, false); KdeLoadFonts(strHome); if(m_fontUI == null) GnomeLoadFonts(strHome); if(m_fontUI == null) UbuntuLoadFonts(); } private static void KdeLoadFonts(string strHome) { string strKdeConfig = strHome + ".kde/share/config/kdeglobals"; if(!File.Exists(strKdeConfig)) { strKdeConfig = strHome + ".kde4/share/config/kdeglobals"; if(!File.Exists(strKdeConfig)) { strKdeConfig = strHome + ".kde3/share/config/kdeglobals"; if(!File.Exists(strKdeConfig)) return; } } IniFile ini = IniFile.Read(strKdeConfig, Encoding.UTF8); string strFont = ini.Get("General", "font"); if(string.IsNullOrEmpty(strFont)) { Debug.Assert(false); return; } m_fontUI = KdeCreateFont(strFont); } private static Font KdeCreateFont(string strDef) { string[] v = strDef.Split(new char[] { ',' }); if((v == null) || (v.Length < 6)) { Debug.Assert(false); return null; } for(int i = 0; i < v.Length; ++i) v[i] = v[i].Trim(); float fSize; if(!float.TryParse(v[1], out fSize)) { Debug.Assert(false); return null; } FontStyle fs = FontStyle.Regular; if(v[4] == "75") fs |= FontStyle.Bold; if((v[5] == "1") || (v[5] == "2")) fs |= FontStyle.Italic; return FontUtil.CreateFont(v[0], fSize, fs); } private static void GnomeLoadFonts(string strHome) { string strConfig = strHome + @".gconf/desktop/gnome/interface/%gconf.xml"; if(!File.Exists(strConfig)) return; XmlDocument doc = new XmlDocument(); doc.Load(strConfig); foreach(XmlNode xn in doc.DocumentElement.ChildNodes) { if(string.Equals(xn.Name, "entry") && string.Equals(xn.Attributes.GetNamedItem("name").Value, "font_name")) { m_fontUI = GnomeCreateFont(xn.FirstChild.InnerText); break; } } } private static Font GnomeCreateFont(string strDef) { int iSep = strDef.LastIndexOf(' '); if(iSep < 0) { Debug.Assert(false); return null; } string strName = strDef.Substring(0, iSep); float fSize = float.Parse(strDef.Substring(iSep + 1)); FontStyle fs = FontStyle.Regular; // Name can end with "Bold", "Italic", "Bold Italic", ... if(strName.EndsWith(" Oblique", StrUtil.CaseIgnoreCmp)) // Gnome { fs |= FontStyle.Italic; strName = strName.Substring(0, strName.Length - 8); } if(strName.EndsWith(" Italic", StrUtil.CaseIgnoreCmp)) // Ubuntu { fs |= FontStyle.Italic; strName = strName.Substring(0, strName.Length - 7); } if(strName.EndsWith(" Bold", StrUtil.CaseIgnoreCmp)) { fs |= FontStyle.Bold; strName = strName.Substring(0, strName.Length - 5); } return FontUtil.CreateFont(strName, fSize, fs); } private static void UbuntuLoadFonts() { string strDef = NativeLib.RunConsoleApp("gsettings", "get org.gnome.desktop.interface font-name"); if(strDef == null) return; strDef = strDef.Trim(new char[] { ' ', '\t', '\r', '\n', '\'', '\"' }); if(strDef.Length == 0) return; m_fontUI = GnomeCreateFont(strDef); } } } KeePass/UI/ListViewGroupingMenu.cs0000664000000000000000000001105213222430414016055 0ustar rootroot/* KeePass Password Safe - The Open-Source Password Manager Copyright (C) 2003-2018 Dominik Reichl This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ using System; using System.Collections.Generic; using System.Text; using System.Windows.Forms; using System.Diagnostics; using KeePass.App.Configuration; using KeePass.Forms; using KeePass.Resources; using KeePass.Util; using KeePassLib; using KeePassLib.Collections; namespace KeePass.UI { public sealed class ListViewGroupingMenu { private ToolStripMenuItem m_tsmiMenu; private MainForm m_mf; private Dictionary m_dItems = new Dictionary(); public ListViewGroupingMenu(ToolStripMenuItem tsmiContainer, MainForm mf) { if(tsmiContainer == null) throw new ArgumentNullException("tsmiContainer"); if(mf == null) throw new ArgumentNullException("mf"); m_tsmiMenu = tsmiContainer; m_mf = mf; ToolStripMenuItem tsmi = new ToolStripMenuItem(KPRes.On); tsmi.Click += this.OnGroupOn; m_dItems[AceListGrouping.On] = tsmi; m_tsmiMenu.DropDownItems.Add(tsmi); tsmi = new ToolStripMenuItem(KPRes.Auto + " (" + KPRes.RecommendedCmd + ")"); tsmi.Click += this.OnGroupAuto; m_dItems[AceListGrouping.Auto] = tsmi; m_tsmiMenu.DropDownItems.Add(tsmi); tsmi = new ToolStripMenuItem(KPRes.Off); tsmi.Click += this.OnGroupOff; m_dItems[AceListGrouping.Off] = tsmi; m_tsmiMenu.DropDownItems.Add(tsmi); UpdateUI(); } #if DEBUG ~ListViewGroupingMenu() { Debug.Assert(m_tsmiMenu == null); // Release should have been called } #endif public void Release() { if(m_tsmiMenu != null) { m_dItems[AceListGrouping.On].Click -= this.OnGroupOn; m_dItems[AceListGrouping.Auto].Click -= this.OnGroupAuto; m_dItems[AceListGrouping.Off].Click -= this.OnGroupOff; m_dItems.Clear(); m_tsmiMenu.DropDownItems.Clear(); m_tsmiMenu = null; m_mf = null; } } private void UpdateUI() { int lgp = (Program.Config.MainWindow.ListGrouping & (int)AceListGrouping.Primary); foreach(KeyValuePair kvp in m_dItems) { Debug.Assert(((int)kvp.Key & ~(int)AceListGrouping.Primary) == 0); UIUtil.SetRadioChecked(kvp.Value, ((int)kvp.Key == lgp)); } } private void SetGrouping(AceListGrouping lgPrimary) { Debug.Assert(((int)lgPrimary & ~(int)AceListGrouping.Primary) == 0); if((int)lgPrimary == (Program.Config.MainWindow.ListGrouping & (int)AceListGrouping.Primary)) return; Program.Config.MainWindow.ListGrouping &= ~(int)AceListGrouping.Primary; Program.Config.MainWindow.ListGrouping |= (int)lgPrimary; Debug.Assert((Program.Config.MainWindow.ListGrouping & (int)AceListGrouping.Primary) == (int)lgPrimary); UpdateUI(); if(m_mf == null) { Debug.Assert(false); return; } PwDatabase pd = m_mf.ActiveDatabase; PwGroup pg = m_mf.GetCurrentEntries(); if((pd == null) || !pd.IsOpen || (pg == null)) return; // No assert PwObjectList pwl = pg.GetEntries(true); if((pwl.UCount > 0) && EntryUtil.EntriesHaveSameParent(pwl)) m_mf.UpdateUI(false, null, true, pwl.GetAt(0).ParentGroup, true, null, false); else { EntryUtil.ReorderEntriesAsInDatabase(pwl, pd); // Requires open DB pg = new PwGroup(true, true); pg.IsVirtual = true; foreach(PwEntry pe in pwl) pg.AddEntry(pe, false); m_mf.UpdateUI(false, null, false, null, true, pg, false); } } private void OnGroupOn(object sender, EventArgs e) { SetGrouping(AceListGrouping.On); } private void OnGroupAuto(object sender, EventArgs e) { SetGrouping(AceListGrouping.Auto); } private void OnGroupOff(object sender, EventArgs e) { SetGrouping(AceListGrouping.Off); } } } KeePass/UI/PromptedTextBox.cs0000664000000000000000000000376213222430414015070 0ustar rootroot/* KeePass Password Safe - The Open-Source Password Manager Copyright (C) 2003-2018 Dominik Reichl This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ using System; using System.Collections.Generic; using System.Text; using System.Windows.Forms; using System.ComponentModel; using System.Drawing; namespace KeePass.UI { public sealed class PromptedTextBox : TextBox { private const int WM_PAINT = 0x000F; private string m_strPrompt = string.Empty; [DefaultValue("")] public string PromptText { get { return m_strPrompt; } set { if(value == null) throw new ArgumentNullException("value"); m_strPrompt = value; this.Invalidate(); } } protected override void WndProc(ref Message m) { base.WndProc(ref m); if((m.Msg == WM_PAINT) && !this.Focused && (this.Text.Length == 0) && (m_strPrompt.Length > 0)) { TextFormatFlags tff = (TextFormatFlags.EndEllipsis | TextFormatFlags.NoPrefix | TextFormatFlags.Left | TextFormatFlags.Top | TextFormatFlags.NoPadding); using(Graphics g = this.CreateGraphics()) { Rectangle rect = this.ClientRectangle; rect.Offset(1, 1); TextRenderer.DrawText(g, m_strPrompt, this.Font, rect, SystemColors.GrayText, this.BackColor, tff); } } } } } KeePass/UI/CustomContextMenuEx.cs0000664000000000000000000000273713222430414015722 0ustar rootroot/* KeePass Password Safe - The Open-Source Password Manager Copyright (C) 2003-2018 Dominik Reichl This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ using System; using System.Collections.Generic; using System.Diagnostics; using System.Drawing; using System.Text; using System.Windows.Forms; namespace KeePass.UI { public sealed class CustomContextMenuEx : ContextMenu { public CustomContextMenuEx() : base() { } public void ShowEx(Control cParent) { if(cParent == null) { Debug.Assert(false); return; } if(cParent.RightToLeft == RightToLeft.Yes) { this.RightToLeft = RightToLeft.Yes; Show(cParent, new Point(cParent.Width, cParent.Height), LeftRightAlignment.Left); } else Show(cParent, new Point(0, cParent.Height)); } } } KeePass/UI/FontUtil.cs0000664000000000000000000001314413222430414013517 0ustar rootroot/* KeePass Password Safe - The Open-Source Password Manager Copyright (C) 2003-2018 Dominik Reichl This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ using System; using System.Collections.Generic; using System.Text; using System.Drawing; using System.Windows.Forms; using System.Diagnostics; namespace KeePass.UI { public static class FontUtil { public static Font CreateFont(string strFamily, float fEmSize, FontStyle fs) { return CreateFont(strFamily, fEmSize, fs, GraphicsUnit.Point); } public static Font CreateFont(string strFamily, float fEmSize, FontStyle fs, GraphicsUnit gu) { try { return new Font(strFamily, fEmSize, fs, gu); } catch(Exception) { Debug.Assert(false); } // Style unsupported? return new Font(strFamily, fEmSize, gu); // Regular style } public static Font CreateFont(FontFamily ff, float fEmSize, FontStyle fs) { try { return new Font(ff, fEmSize, fs); } catch(Exception) { Debug.Assert(false); } // Style unsupported? return new Font(ff, fEmSize); } public static Font CreateFont(Font fBase, FontStyle fs) { try { return new Font(fBase, fs); } catch(Exception) { Debug.Assert(false); } // Style unsupported? return new Font(fBase, fBase.Style); // Clone } private static void Assign(Control c, Font f) { if(c == null) { Debug.Assert(false); return; } if(f == null) { Debug.Assert(false); return; } try { using(RtlAwareResizeScope r = new RtlAwareResizeScope(c)) { c.Font = f; } } catch(Exception) { Debug.Assert(false); } } private static Font m_fontDefault = null; /// /// Get the default UI font. This might be null! /// public static Font DefaultFont { get { return m_fontDefault; } } public static void SetDefaultFont(Control c) { if(c == null) { Debug.Assert(false); return; } // Allow specifying the default font once only if(m_fontDefault == null) m_fontDefault = c.Font; } public static void AssignDefault(Control c) { Assign(c, m_fontDefault); } private static Font m_fontBold = null; public static void AssignDefaultBold(Control c) { if(c == null) { Debug.Assert(false); return; } if(m_fontBold == null) { try { m_fontBold = new Font(c.Font, FontStyle.Bold); } catch(Exception) { Debug.Assert(false); m_fontBold = c.Font; } } Assign(c, m_fontBold); } private static Font m_fontItalic = null; public static void AssignDefaultItalic(Control c) { if(c == null) { Debug.Assert(false); return; } if(m_fontItalic == null) { try { m_fontItalic = new Font(c.Font, FontStyle.Italic); } catch(Exception) { Debug.Assert(false); m_fontItalic = c.Font; } } Assign(c, m_fontItalic); } private static Font m_fontMono = null; /// /// Get the default UI monospace font. This might be null! /// public static Font MonoFont { get { return m_fontMono; } } public static void AssignDefaultMono(Control c, bool bIsPasswordBox) { if(c == null) { Debug.Assert(false); return; } if(m_fontMono == null) { try { m_fontMono = new Font(FontFamily.GenericMonospace, c.Font.SizeInPoints); Debug.Assert(c.Font.Height == m_fontMono.Height); } catch(Exception) { Debug.Assert(false); m_fontMono = c.Font; } } if(bIsPasswordBox && Program.Config.UI.PasswordFont.OverrideUIDefault) Assign(c, Program.Config.UI.PasswordFont.ToFont()); else Assign(c, m_fontMono); } /* private const string FontPartsSeparator = @"/:/"; public static Font FontIDToFont(string strFontID) { Debug.Assert(strFontID != null); if(strFontID == null) return null; string[] vParts = strFontID.Split(new string[] { FontPartsSeparator }, StringSplitOptions.None); if((vParts == null) || (vParts.Length != 6)) return null; float fSize; if(!float.TryParse(vParts[1], out fSize)) { Debug.Assert(false); return null; } FontStyle fs = FontStyle.Regular; if(vParts[2] == "1") fs |= FontStyle.Bold; if(vParts[3] == "1") fs |= FontStyle.Italic; if(vParts[4] == "1") fs |= FontStyle.Underline; if(vParts[5] == "1") fs |= FontStyle.Strikeout; return FontUtil.CreateFont(vParts[0], fSize, fs); } public static string FontToFontID(Font f) { Debug.Assert(f != null); if(f == null) return string.Empty; StringBuilder sb = new StringBuilder(); sb.Append(f.Name); sb.Append(FontPartsSeparator); sb.Append(f.SizeInPoints.ToString()); sb.Append(FontPartsSeparator); sb.Append(f.Bold ? "1" : "0"); sb.Append(FontPartsSeparator); sb.Append(f.Italic ? "1" : "0"); sb.Append(FontPartsSeparator); sb.Append(f.Underline ? "1" : "0"); sb.Append(FontPartsSeparator); sb.Append(f.Strikeout ? "1" : "0"); return sb.ToString(); } */ } } KeePass/UI/ColumnProvider.cs0000664000000000000000000000405213222430414014721 0ustar rootroot/* KeePass Password Safe - The Open-Source Password Manager Copyright (C) 2003-2018 Dominik Reichl This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ using System; using System.Collections.Generic; using System.Text; using System.Windows.Forms; using KeePassLib; namespace KeePass.UI { public abstract class ColumnProvider { /// /// Names of all provided columns. /// Querying this property should be fast, i.e. it's recommended that /// you cache the returned string array. /// public abstract string[] ColumnNames { get; } public virtual HorizontalAlignment TextAlign { get { return HorizontalAlignment.Left; } } public abstract string GetCellData(string strColumnName, PwEntry pe); public virtual bool SupportsCellAction(string strColumnName) { return false; } /// /// KeePass calls this method when a user double-clicks onto a cell /// of a column provided by the plugin. /// This method is only called, if the provider returns true /// in the SupportsCellAction method for the specified column. /// /// Name of the active column. /// Entry to which the active cell belongs. public virtual void PerformCellAction(string strColumnName, PwEntry pe) { } } } KeePass/UI/ImageComboBoxEx.cs0000664000000000000000000000767113222430414014733 0ustar rootroot/* KeePass Password Safe - The Open-Source Password Manager Copyright (C) 2003-2018 Dominik Reichl This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ using System; using System.Collections.Generic; using System.Text; using System.ComponentModel; using System.Windows.Forms; using System.Drawing; using System.Drawing.Drawing2D; using System.Diagnostics; using KeePassLib.Native; namespace KeePass.UI { public sealed class ImageComboBoxEx : ComboBox { private List m_vImages = null; [Browsable(false)] [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] public List OrderedImageList { get { return m_vImages; } set { m_vImages = value; } // Null allowed } public ImageComboBoxEx() : base() { if(Program.DesignMode) return; if(NativeLib.IsUnix()) return; Debug.Assert(this.DrawMode == DrawMode.Normal); this.DrawMode = DrawMode.OwnerDrawVariable; this.DropDownHeight = GetStdItemHeight(null) * 12 + 2; this.MaxDropDownItems = 12; Debug.Assert(!this.Sorted); } private int GetStdItemHeight(Graphics g) { if(g == null) return Math.Max(18, TextRenderer.MeasureText("Wg", this.Font).Height); return Math.Max(18, TextRenderer.MeasureText(g, "Wg", this.Font).Height); } protected override void OnMeasureItem(MeasureItemEventArgs e) { base.OnMeasureItem(e); e.ItemHeight = GetStdItemHeight(e.Graphics); } protected override void OnDrawItem(DrawItemEventArgs e) { Color clrBack = e.BackColor, clrFore = e.ForeColor; if((e.State & DrawItemState.Selected) != DrawItemState.None) { clrBack = SystemColors.Highlight; clrFore = SystemColors.HighlightText; } int nIdx = e.Index; Rectangle rectClip = e.Bounds; int dImg = rectClip.Height - 2; bool bRtl = Program.Translation.Properties.RightToLeft; Graphics g = e.Graphics; SolidBrush brBack = new SolidBrush(clrBack); g.FillRectangle(brBack, rectClip); Rectangle rectImg = new Rectangle(bRtl ? (rectClip.Right - dImg - 1) : (rectClip.Left + 1), rectClip.Top + 1, dImg, dImg); if((m_vImages != null) && (nIdx >= 0) && (nIdx < m_vImages.Count) && (m_vImages[nIdx] != null)) { g.InterpolationMode = InterpolationMode.HighQualityBicubic; g.SmoothingMode = SmoothingMode.HighQuality; g.DrawImage(m_vImages[nIdx], rectImg); } Rectangle rectText = new Rectangle(bRtl ? (rectClip.Left + 1) : (rectClip.Left + dImg + 2 + 1), rectClip.Top + 1, rectClip.Width - dImg - 5, rectClip.Height - 2); TextFormatFlags tff = (TextFormatFlags.PreserveGraphicsClipping | TextFormatFlags.EndEllipsis | TextFormatFlags.NoPrefix | TextFormatFlags.SingleLine | TextFormatFlags.VerticalCenter); if(bRtl) tff |= (TextFormatFlags.RightToLeft | TextFormatFlags.Right); string strText = string.Empty; if((nIdx >= 0) && (nIdx < this.Items.Count)) strText = ((this.Items[nIdx] as string) ?? string.Empty); TextRenderer.DrawText(g, strText, e.Font, rectText, clrFore, clrBack, tff); if(((e.State & DrawItemState.Focus) != DrawItemState.None) && ((e.State & DrawItemState.NoFocusRect) == DrawItemState.None)) e.DrawFocusRectangle(); brBack.Dispose(); } } } KeePass/UI/CustomListViewEx.cs0000664000000000000000000001207313222430414015211 0ustar rootroot/* KeePass Password Safe - The Open-Source Password Manager Copyright (C) 2003-2018 Dominik Reichl This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ using System; using System.Collections.Generic; using System.Text; using System.Windows.Forms; using System.Threading; using System.Diagnostics; using KeePass.Native; using KeePassLib.Utility; namespace KeePass.UI { public sealed class CustomListViewEx : ListView { public CustomListViewEx() : base() { try { this.DoubleBuffered = true; } catch(Exception) { Debug.Assert(false); } } /* private Color m_clrPrev = Color.Black; private Point m_ptLast = new Point(-1, -1); protected override void OnMouseHover(EventArgs e) { if((m_ptLast.X >= 0) && (m_ptLast.X < this.Columns.Count) && (m_ptLast.Y >= 0) && (m_ptLast.Y < this.Items.Count)) { this.Items[m_ptLast.Y].SubItems[m_ptLast.X].ForeColor = m_clrPrev; } ListViewHitTestInfo lh = this.HitTest(this.PointToClient(Cursor.Position)); if((lh.Item != null) && (lh.SubItem != null)) { m_ptLast = new Point(lh.Item.SubItems.IndexOf(lh.SubItem), lh.Item.Index); m_clrPrev = lh.SubItem.ForeColor; lh.SubItem.ForeColor = Color.LightBlue; } base.OnMouseHover(e); } */ /* protected override void OnKeyUp(KeyEventArgs e) { base.OnKeyUp(e); UnfocusGroupInSingleMode(); } private void UnfocusGroupInSingleMode() { try { if(!WinUtil.IsAtLeastWindowsVista) return; if(KeePassLib.Native.NativeLib.IsUnix()) return; if(!this.ShowGroups) return; if(this.MultiSelect) return; const uint m = (NativeMethods.LVGS_FOCUSED | NativeMethods.LVGS_SELECTED); uint uGroups = (uint)this.Groups.Count; for(uint u = 0; u < uGroups; ++u) { int iGroupID; if(NativeMethods.GetGroupStateByIndex(this, u, m, out iGroupID) == m) { NativeMethods.SetGroupState(this, iGroupID, m, NativeMethods.LVGS_SELECTED); return; } } } catch(Exception) { Debug.Assert(false); } } */ protected override void OnKeyDown(KeyEventArgs e) { if(UIUtil.HandleCommonKeyEvent(e, true, this)) return; try { if(SkipGroupHeaderIfRequired(e)) return; } catch(Exception) { Debug.Assert(false); } base.OnKeyDown(e); } protected override void OnKeyUp(KeyEventArgs e) { if(UIUtil.HandleCommonKeyEvent(e, false, this)) return; base.OnKeyUp(e); } private bool SkipGroupHeaderIfRequired(KeyEventArgs e) { if(!UIUtil.GetGroupsEnabled(this)) return false; if(this.MultiSelect) return false; if(MonoWorkarounds.IsRequired(836428016)) return false; ListViewItem lvi = this.FocusedItem; if(lvi != null) { ListViewGroup g = lvi.Group; ListViewItem lviChangeTo = null; if((e.KeyCode == Keys.Up) && IsFirstLastItemInGroup(g, lvi, true)) lviChangeTo = (GetNextLvi(g, true) ?? lvi); // '??' for top item else if((e.KeyCode == Keys.Down) && IsFirstLastItemInGroup(g, lvi, false)) lviChangeTo = (GetNextLvi(g, false) ?? lvi); // '??' for bottom item if(lviChangeTo != null) { foreach(ListViewItem lviEnum in this.Items) lviEnum.Selected = false; EnsureVisible(lviChangeTo.Index); UIUtil.SetFocusedItem(this, lviChangeTo, true); UIUtil.SetHandled(e, true); return true; } } return false; } private static bool IsFirstLastItemInGroup(ListViewGroup g, ListViewItem lvi, bool bFirst) { if(g == null) { Debug.Assert(false); return false; } ListViewItemCollection c = g.Items; if(c.Count == 0) { Debug.Assert(false); return false; } return (bFirst ? (c[0] == lvi) : (c[c.Count - 1] == lvi)); } private ListViewItem GetNextLvi(ListViewGroup gBaseExcl, bool bUp) { if(gBaseExcl == null) { Debug.Assert(false); return null; } int i = this.Groups.IndexOf(gBaseExcl); if(i < 0) { Debug.Assert(false); return null; } if(bUp) { --i; while(i >= 0) { ListViewGroup g = this.Groups[i]; if(g.Items.Count > 0) return g.Items[g.Items.Count - 1]; --i; } } else // Down { ++i; int nGroups = this.Groups.Count; while(i < nGroups) { ListViewGroup g = this.Groups[i]; if(g.Items.Count > 0) return g.Items[0]; ++i; } } return null; } } } KeePass/UI/QualityProgressBar.cs0000664000000000000000000001622313222430414015556 0ustar rootroot/* KeePass Password Safe - The Open-Source Password Manager Copyright (C) 2003-2018 Dominik Reichl This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ using System; using System.Collections.Generic; using System.ComponentModel; using System.Diagnostics; using System.Drawing; using System.Drawing.Drawing2D; using System.Text; using System.Windows.Forms; using System.Windows.Forms.VisualStyles; using KeePass.App; using KeePass.Util; using KeePassLib.Native; namespace KeePass.UI { public sealed class QualityProgressBar : Control { public QualityProgressBar() : base() { this.DoubleBuffered = true; } private int m_nMinimum = 0; [DefaultValue(0)] public int Minimum { get { return m_nMinimum; } set { m_nMinimum = value; this.Invalidate(); } } private int m_nMaximum = 100; [DefaultValue(100)] public int Maximum { get { return m_nMaximum; } set { m_nMaximum = value; this.Invalidate(); } } private int m_nPosition = 0; [DefaultValue(0)] public int Value { get { return m_nPosition; } set { m_nPosition = value; this.Invalidate(); } } private ProgressBarStyle m_pbsStyle = ProgressBarStyle.Continuous; [Browsable(false)] [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] public ProgressBarStyle Style { get { return m_pbsStyle; } set { m_pbsStyle = value; this.Invalidate(); } } private string m_strText = string.Empty; [DefaultValue("")] public string ProgressText { get { return m_strText; } set { m_strText = value; this.Invalidate(); } } protected override void OnPaint(PaintEventArgs e) { try { PaintPriv(e); } catch(Exception) { Debug.Assert(false); } } private void PaintPriv(PaintEventArgs e) { Graphics g = e.Graphics; if(g == null) { base.OnPaint(e); return; } int nNormPos = m_nPosition - m_nMinimum; int nNormMax = m_nMaximum - m_nMinimum; if(nNormMax <= 0) { Debug.Assert(false); nNormMax = 100; } if(nNormPos < 0) { Debug.Assert(false); nNormPos = 0; } if(nNormPos > nNormMax) { Debug.Assert(false); nNormPos = nNormMax; } Rectangle rectClient = this.ClientRectangle; Rectangle rectDraw; VisualStyleElement vse = VisualStyleElement.ProgressBar.Bar.Normal; if(VisualStyleRenderer.IsSupported && VisualStyleRenderer.IsElementDefined(vse)) { VisualStyleRenderer vsr = new VisualStyleRenderer(vse); if(vsr.IsBackgroundPartiallyTransparent()) vsr.DrawParentBackground(g, rectClient, this); vsr.DrawBackground(g, rectClient); rectDraw = vsr.GetBackgroundContentRectangle(g, rectClient); } else { g.FillRectangle(SystemBrushes.Control, rectClient); Pen penGray = SystemPens.ControlDark; Pen penWhite = SystemPens.ControlLight; g.DrawLine(penGray, 0, 0, rectClient.Width - 1, 0); g.DrawLine(penGray, 0, 0, 0, rectClient.Height - 1); g.DrawLine(penWhite, rectClient.Width - 1, 0, rectClient.Width - 1, rectClient.Height - 1); g.DrawLine(penWhite, 0, rectClient.Height - 1, rectClient.Width - 1, rectClient.Height - 1); rectDraw = new Rectangle(rectClient.X + 1, rectClient.Y + 1, rectClient.Width - 2, rectClient.Height - 2); } int nDrawWidth = (int)((float)rectDraw.Width * (float)nNormPos / (float)nNormMax); Color clrStart = AppDefs.ColorQualityLow; Color clrEnd = AppDefs.ColorQualityHigh; if(!this.Enabled) { clrStart = UIUtil.ColorToGrayscale(SystemColors.ControlDark); clrEnd = UIUtil.ColorToGrayscale(SystemColors.ControlLight); } bool bRtl = (this.RightToLeft == RightToLeft.Yes); if(bRtl) { Color clrTemp = clrStart; clrStart = clrEnd; clrEnd = clrTemp; } // Workaround for Windows <= XP Rectangle rectGrad = new Rectangle(rectDraw.X, rectDraw.Y, rectDraw.Width, rectDraw.Height); if(!WinUtil.IsAtLeastWindowsVista && !NativeLib.IsUnix()) rectGrad.Inflate(1, 0); using(LinearGradientBrush brush = new LinearGradientBrush(rectGrad, clrStart, clrEnd, LinearGradientMode.Horizontal)) { g.FillRectangle(brush, (bRtl ? (rectDraw.Width - nDrawWidth + 1) : rectDraw.Left), rectDraw.Top, nDrawWidth, rectDraw.Height); } PaintText(g, rectDraw); } private void PaintText(Graphics g, Rectangle rectDraw) { if(string.IsNullOrEmpty(m_strText)) return; Font f = (FontUtil.DefaultFont ?? this.Font); Color clrFG = UIUtil.ColorToGrayscale(this.ForeColor); Color clrBG = Color.FromArgb(clrFG.ToArgb() ^ 0x20FFFFFF); // Instead of an ellipse, Mono draws a circle, which looks ugly if(!NativeLib.IsUnix()) { int dx = rectDraw.X; int dy = rectDraw.Y; int dw = rectDraw.Width; int dh = rectDraw.Height; Rectangle rectGlow = rectDraw; rectGlow.Width = TextRenderer.MeasureText(g, m_strText, f).Width; rectGlow.X = ((dw - rectGlow.Width) / 2) + dx; rectGlow.Inflate(rectGlow.Width / 2, rectGlow.Height / 2); using(GraphicsPath gpGlow = new GraphicsPath()) { gpGlow.AddEllipse(rectGlow); using(PathGradientBrush pgbGlow = new PathGradientBrush(gpGlow)) { pgbGlow.CenterPoint = new PointF((dw / 2.0f) + dx, (dh / 2.0f) + dy); pgbGlow.CenterColor = clrBG; pgbGlow.SurroundColors = new Color[] { Color.Transparent }; Region rgOrgClip = g.Clip; g.SetClip(rectDraw); g.FillPath(pgbGlow, gpGlow); g.Clip = rgOrgClip; } } } // With ClearType on, text drawn using Graphics.DrawString // looks better than TextRenderer.DrawText; // https://sourceforge.net/p/keepass/discussion/329220/thread/06ef4466/ // TextFormatFlags tff = (TextFormatFlags.HorizontalCenter | TextFormatFlags.SingleLine | // TextFormatFlags.VerticalCenter); // TextRenderer.DrawText(g, m_strText, f, rectDraw, clrFG, tff); using(SolidBrush br = new SolidBrush(clrFG)) { StringFormatFlags sff = (StringFormatFlags.FitBlackBox | StringFormatFlags.NoClip); using(StringFormat sf = new StringFormat(sff)) { sf.Alignment = StringAlignment.Center; sf.LineAlignment = StringAlignment.Center; RectangleF rf = new RectangleF(rectDraw.X, rectDraw.Y, rectDraw.Width, rectDraw.Height); g.DrawString(m_strText, f, br, rf, sf); } } } protected override void OnPaintBackground(PaintEventArgs pEvent) { // base.OnPaintBackground(pevent); } } } KeePass/UI/CustomRichTextBoxEx.cs0000664000000000000000000003626413222430414015656 0ustar rootroot/* KeePass Password Safe - The Open-Source Password Manager Copyright (C) 2003-2018 Dominik Reichl This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ using System; using System.Collections.Generic; using System.Text; using System.Windows.Forms; using System.ComponentModel; using System.Drawing; using System.Diagnostics; using KeePass.Util; using KeePassLib.Native; using KeePassLib.Utility; namespace KeePass.UI { public sealed class CustomRichTextBoxEx : RichTextBox { private static bool? m_bForceRedrawOnScroll = null; private bool m_bSimpleTextOnly = false; [Browsable(false)] [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] [DefaultValue(false)] public bool SimpleTextOnly { get { return m_bSimpleTextOnly; } set { m_bSimpleTextOnly = value; } } private bool m_bCtrlEnterAccepts = false; [Browsable(false)] [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] [DefaultValue(false)] public bool CtrlEnterAccepts { get { return m_bCtrlEnterAccepts; } set { m_bCtrlEnterAccepts = value; } } public CustomRichTextBoxEx() : base() { // We cannot use EnableAutoDragDrop, because moving some text // using drag&drop can remove the selected text from the box // (even when read-only is enabled!), which is usually not a // good behavior in the case of KeePass; // reproducible e.g. with LibreOffice Writer, not WordPad // this.EnableAutoDragDrop = true; // this.AllowDrop = true; // The following is intended to set a default value; // see also OnHandleCreated this.AutoWordSelection = false; } private CriticalSectionEx m_csAutoProps = new CriticalSectionEx(); protected override void OnHandleCreated(EventArgs e) { base.OnHandleCreated(e); // The following operations should not recreate the handle if(m_csAutoProps.TryEnter()) { // Workaround for .NET bug: // AutoWordSelection remembers the value of the property // correctly, but incorrectly sends a message as follows: // SendMessage(EM_SETOPTIONS, value ? ECOOP_OR : ECOOP_XOR, // ECO_AUTOWORDSELECTION); // So, when setting AutoWordSelection to false, the control // style is toggled instead of turned off (the internal value // is updated correctly) bool bAutoWord = this.AutoWordSelection; // Internal, no message if(!bAutoWord) // Only 'false' needs workaround { // Ensure control style is on (currently we're in a // random state, as it could be set to false multiple // times; e.g. base.OnHandleCreated does the following: // 'this.AutoWordSelection = this.AutoWordSelection;') this.AutoWordSelection = true; // Toggle control style to false this.AutoWordSelection = false; } m_csAutoProps.Exit(); } else { Debug.Assert(false); } } private static bool IsPasteCommand(KeyEventArgs e) { if(e == null) { Debug.Assert(false); return false; } // Also check for modifier keys being up; // https://sourceforge.net/p/keepass/bugs/1185/ if((e.KeyCode == Keys.V) && e.Control && !e.Alt) // e.Shift arb. return true; if((e.KeyCode == Keys.Insert) && e.Shift && !e.Alt) // e.Control arb. return true; return false; } protected override void OnKeyDown(KeyEventArgs e) { if(UIUtil.HandleCommonKeyEvent(e, true, this)) return; if(m_bSimpleTextOnly && IsPasteCommand(e)) { UIUtil.SetHandled(e, true); PasteAcceptable(); return; } if(m_bCtrlEnterAccepts && e.Control && ((e.KeyCode == Keys.Return) || (e.KeyCode == Keys.Enter))) { UIUtil.SetHandled(e, true); Debug.Assert(this.Multiline); Control p = this; Form f; while(true) { f = (p as Form); if(f != null) break; Control pParent = p.Parent; if((pParent == null) || (pParent == p)) break; p = pParent; } if(f != null) { IButtonControl btn = f.AcceptButton; if(btn != null) btn.PerformClick(); else { Debug.Assert(false); } } else { Debug.Assert(false); } return; } if(HandleAltX(e, true)) return; base.OnKeyDown(e); } protected override void OnKeyUp(KeyEventArgs e) { if(UIUtil.HandleCommonKeyEvent(e, false, this)) return; if(m_bSimpleTextOnly && IsPasteCommand(e)) { UIUtil.SetHandled(e, true); return; } if(m_bCtrlEnterAccepts && e.Control && ((e.KeyCode == Keys.Return) || (e.KeyCode == Keys.Enter))) { UIUtil.SetHandled(e, true); return; } if(HandleAltX(e, false)) return; base.OnKeyUp(e); } public void PasteAcceptable() { try { if(!m_bSimpleTextOnly) Paste(); else if(ClipboardUtil.ContainsData(DataFormats.UnicodeText)) Paste(DataFormats.GetFormat(DataFormats.UnicodeText)); else if(ClipboardUtil.ContainsData(DataFormats.Text)) Paste(DataFormats.GetFormat(DataFormats.Text)); } catch(Exception) { Debug.Assert(false); } } // https://www.fileformat.info/tip/microsoft/enter_unicode.htm // https://sourceforge.net/p/keepass/feature-requests/2180/ private bool HandleAltX(KeyEventArgs e, bool bDown) { // Rich text boxes of Windows already support Alt+X if(!NativeLib.IsUnix()) return false; if(!e.Control && e.Alt && (e.KeyCode == Keys.X)) { } else return false; UIUtil.SetHandled(e, true); if(!bDown) return true; try { string strSel = (this.SelectedText ?? string.Empty); int iSel = this.SelectionStart; Debug.Assert(this.SelectionLength == strSel.Length); if(e.Shift) // Character -> code { string strChar = strSel; if(strSel.Length >= 2) // Work with leftmost character { if(char.IsSurrogatePair(strSel, 0)) strChar = strSel.Substring(0, 2); else strChar = strSel.Substring(0, 1); } else if(strSel.Length == 0) // Work with char. to the left { int p = iSel - 1; string strText = this.Text; if((p < 0) || (p >= strText.Length)) return true; char ch = strText[p]; if(!char.IsSurrogate(ch)) strChar = new string(ch, 1); else if(p >= 1) { if(char.IsSurrogatePair(strText, p - 1)) strChar = strText.Substring(p - 1, 2); } } else // strSel.Length == 1 { if(char.IsSurrogate(strSel[0])) { Debug.Assert(false); // Half surrogate return true; } } if(strChar.Length == 0) { Debug.Assert(false); return true; } int uc = char.ConvertToUtf32(strChar, 0); string strRep = Convert.ToString(uc, 16).ToUpperInvariant(); if(strSel.Length >= 2) this.Select(iSel, strChar.Length); else if(strSel.Length == 0) { this.Select(iSel - strChar.Length, strChar.Length); iSel -= strChar.Length; } this.SelectedText = strRep; this.Select(iSel, strRep.Length); } else // Code -> character { const uint ucMax = 0x10FFFF; // Max. using surrogates const int ccHexMax = 6; // See e.g. WordPad string strHex = strSel; if(strSel.Length == 0) { int p = iSel - 1; string strText = this.Text; while((p >= 0) && (p < strText.Length)) { char ch = strText[p]; if(((ch >= '0') && (ch <= '9')) || ((ch >= 'a') && (ch <= 'f')) || ((ch >= 'A') && (ch <= 'F'))) { strHex = (new string(ch, 1)) + strHex; if(strHex.Length == ccHexMax) break; } else break; --p; } } if((strHex.Length == 0) || !StrUtil.IsHexString(strHex, true)) return true; string strHexTr = strHex.TrimStart('0'); if(strHexTr.Length > ccHexMax) return true; uint uc = Convert.ToUInt32(strHexTr, 16); if(uc > ucMax) return true; string strRep = char.ConvertFromUtf32((int)uc); if(string.IsNullOrEmpty(strRep)) { Debug.Assert(false); return true; } if(char.IsControl(strRep, 0) && (strRep[0] != '\t')) return true; if(strSel.Length == 0) this.Select(iSel - strHex.Length, strHex.Length); this.SelectedText = strRep; } } catch(Exception) { Debug.Assert(false); } return true; } // ////////////////////////////////////////////////////////////////// // Drag&Drop Source Support /* private Rectangle m_rectDragBox = Rectangle.Empty; private bool m_bCurDragSource = false; protected override void OnMouseDown(MouseEventArgs e) { base.OnMouseDown(e); if(((e.Button & MouseButtons.Left) == MouseButtons.Left) && (this.SelectionLength > 0)) { Size szDrag = SystemInformation.DragSize; m_rectDragBox = new Rectangle(new Point(e.X - (szDrag.Width / 2), e.Y - (szDrag.Height / 2)), szDrag); } } protected override void OnMouseUp(MouseEventArgs mevent) { m_rectDragBox = Rectangle.Empty; base.OnMouseUp(mevent); } protected override void OnMouseMove(MouseEventArgs e) { if(m_bCurDragSource) { base.OnMouseMove(e); return; } if(((e.Button & MouseButtons.Left) == MouseButtons.Left) && !m_rectDragBox.IsEmpty) { if(!m_rectDragBox.Contains(e.X, e.Y)) { m_rectDragBox = Rectangle.Empty; string strText = this.SelectedText; // int iSelStart = this.SelectionStart; // int iSelLen = this.SelectionLength; if(!string.IsNullOrEmpty(strText)) { m_bCurDragSource = true; DoDragDrop(strText, (DragDropEffects.Move | DragDropEffects.Copy | DragDropEffects.Scroll)); m_bCurDragSource = false; // Select(iSelStart, iSelLen); return; } else { Debug.Assert(false); } } } base.OnMouseMove(e); } */ // ////////////////////////////////////////////////////////////////// // Drag&Drop Target Support /* private static bool ObjectHasText(DragEventArgs e) { if(e == null) { Debug.Assert(false); return false; } IDataObject ido = e.Data; if(ido == null) { Debug.Assert(false); return false; } return (ido.GetDataPresent(DataFormats.Text) || ido.GetDataPresent(DataFormats.UnicodeText)); } private bool IsDropAcceptable(DragEventArgs e) { if(e == null) { Debug.Assert(false); return false; } if(this.ReadOnly) return false; // Currently, in-control drag&drop is unsupported if(m_bCurDragSource) return false; return ObjectHasText(e); } private bool CustomizeDropEffect(DragEventArgs e) { if(e == null) { Debug.Assert(false); return false; } if(!IsDropAcceptable(e)) { e.Effect = DragDropEffects.None; return true; } return false; } protected override void OnDragEnter(DragEventArgs drgevent) { base.OnDragEnter(drgevent); CustomizeDropEffect(drgevent); } protected override void OnDragOver(DragEventArgs drgevent) { base.OnDragOver(drgevent); CustomizeDropEffect(drgevent); } protected override void OnDragDrop(DragEventArgs drgevent) { if(drgevent == null) { Debug.Assert(false); return; } if(!IsDropAcceptable(drgevent)) { drgevent.Effect = DragDropEffects.None; return; } if(m_bSimpleTextOnly) { IDataObject d = drgevent.Data; string str = null; if(d.GetDataPresent(DataFormats.UnicodeText)) str = (d.GetData(DataFormats.UnicodeText) as string); if((str == null) && d.GetDataPresent(DataFormats.Text)) str = (d.GetData(DataFormats.Text) as string); if(str == null) { Debug.Assert(false); drgevent.Effect = DragDropEffects.None; return; } Point pt = new Point(drgevent.X, drgevent.Y); pt = PointToClient(pt); drgevent.Effect = DragDropEffects.None; int pIns = GetCharIndexFromPosition(pt); InsertTextAt(str, pIns); } else base.OnDragDrop(drgevent); } private void InsertTextAt(string str, int pIns) { if(string.IsNullOrEmpty(str)) return; string strText = this.Text; if((pIns < 0) || (pIns > strText.Length)) { Debug.Assert(false); return; } this.Text = strText.Insert(pIns, str); Select(pIns + str.Length, 0); // Data was inserted, not moved ScrollToCaret(); } */ // ////////////////////////////////////////////////////////////////// // Simple Selection Support // The following selection code is not required, because // AutoWordSelection can be used with a workaround // private int? m_oiMouseSelStart = null; /* protected override void OnMouseDown(MouseEventArgs e) { base.OnMouseDown(e); if(((e.Button & MouseButtons.Left) != MouseButtons.None) && (this.SelectionLength == 0)) m_oiMouseSelStart = this.SelectionStart; } protected override void OnMouseMove(MouseEventArgs e) { if(UpdateSelectionEx(e)) return; base.OnMouseMove(e); } protected override void OnMouseUp(MouseEventArgs mevent) { if((mevent.Button & MouseButtons.Left) != MouseButtons.None) m_oiMouseSelStart = null; base.OnMouseUp(mevent); } private bool UpdateSelectionEx(MouseEventArgs e) { if(!m_oiMouseSelStart.HasValue) return false; if((e.Button & MouseButtons.Left) == MouseButtons.None) return false; try { int iSelS = m_oiMouseSelStart.Value; int iSelE = Math.Max(GetCharIndexFromPosition(e.Location), 0); if(iSelE == (this.TextLength - 1)) { Font f = this.SelectionFont; if(f == null) { Select(iSelE, 1); f = (this.SelectionFont ?? this.Font); } // Measuring a single character is imprecise (padding, ...) Size szLastChar = TextRenderer.MeasureText(new string( this.Text[iSelE], 20), f); int wLastChar = szLastChar.Width / 20; Point ptLastChar = GetPositionFromCharIndex(iSelE); if(e.X >= (ptLastChar.X + (wLastChar / 2))) ++iSelE; } if(iSelS <= iSelE) Select(iSelS, iSelE - iSelS); else Select(iSelE, iSelS - iSelE); } catch(Exception) { Debug.Assert(false); return false; } return true; } */ protected override void OnHScroll(EventArgs e) { base.OnHScroll(e); MonoRedrawOnScroll(); } protected override void OnVScroll(EventArgs e) { base.OnVScroll(e); MonoRedrawOnScroll(); } private void MonoRedrawOnScroll() { if(!m_bForceRedrawOnScroll.HasValue) m_bForceRedrawOnScroll = MonoWorkarounds.IsRequired(1366); if(m_bForceRedrawOnScroll.Value) Invalidate(); } } } KeePass/UI/RichTextBoxContextMenu.cs0000664000000000000000000001562313222430414016354 0ustar rootroot/* KeePass Password Safe - The Open-Source Password Manager Copyright (C) 2003-2018 Dominik Reichl This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ using System; using System.Collections.Generic; using System.Windows.Forms; using System.Diagnostics; using KeePass.Resources; using KeePass.Util; namespace KeePass.UI { public sealed class RichTextBoxContextMenu { private RichTextBox m_rtb = null; private Form m_form = null; private CustomContextMenuStripEx m_ctx = null; private ToolStripItem[] m_vMenuItems = new ToolStripItem[(int)RtbCtxCommands.Count]; private string m_strCurLink = string.Empty; private enum RtbCtxCommands { Undo = 0, Cut, Copy, Paste, Delete, CopyLink, CopyAll, SelectAll, Count } public RichTextBoxContextMenu() { } ~RichTextBoxContextMenu() { try { Detach(); } catch(Exception) { Debug.Assert(false); } } [Obsolete] public void Attach(RichTextBox rtb) { Attach(rtb, null); } public void Attach(RichTextBox rtb, Form fParent) { Detach(); m_rtb = rtb; m_form = fParent; m_ctx = CreateContextMenu(); m_ctx.Opening += this.OnMenuOpening; GlobalWindowManager.CustomizeControl(m_ctx); m_rtb.ContextMenuStrip = m_ctx; } public void Detach() { if(m_rtb != null) { m_rtb.ContextMenuStrip = null; m_ctx.Opening -= this.OnMenuOpening; m_ctx = null; for(int i = 0; i < (int)RtbCtxCommands.Count; ++i) m_vMenuItems[i] = null; m_rtb = null; m_form = null; } } private CustomContextMenuStripEx CreateContextMenu() { CustomContextMenuStripEx ctx = new CustomContextMenuStripEx(); int iPos = -1; ToolStripItem tsiUndo = ctx.Items.Add(KPRes.Undo, Properties.Resources.B16x16_Undo, this.OnUndoCommand); tsiUndo.RightToLeftAutoMirrorImage = true; m_vMenuItems[++iPos] = tsiUndo; ctx.Items.Add(new ToolStripSeparator()); m_vMenuItems[++iPos] = ctx.Items.Add(KPRes.Cut, Properties.Resources.B16x16_Cut, this.OnCutCommand); m_vMenuItems[++iPos] = ctx.Items.Add(KPRes.Copy, Properties.Resources.B16x16_EditCopy, this.OnCopyCommand); m_vMenuItems[++iPos] = ctx.Items.Add(KPRes.Paste, Properties.Resources.B16x16_EditPaste, this.OnPasteCommand); m_vMenuItems[++iPos] = ctx.Items.Add(KPRes.Delete, Properties.Resources.B16x16_EditDelete, this.OnDeleteCommand); ctx.Items.Add(new ToolStripSeparator()); ToolStripItem tsiLink = ctx.Items.Add(KPRes.CopyLink, Properties.Resources.B16x16_EditCopyLink, this.OnCopyLinkCommand); tsiLink.RightToLeftAutoMirrorImage = true; m_vMenuItems[++iPos] = tsiLink; m_vMenuItems[++iPos] = ctx.Items.Add(KPRes.CopyAll, Properties.Resources.B16x16_EditShred, this.OnCopyAllCommand); m_vMenuItems[++iPos] = ctx.Items.Add(KPRes.SelectAll, Properties.Resources.B16x16_Edit, this.OnSelectAllCommand); Debug.Assert(iPos == ((int)RtbCtxCommands.Count - 1)); return ctx; } private void OnMenuOpening(object sender, EventArgs e) { bool bHasText = (m_rtb.TextLength > 0); bool bHasSel = (m_rtb.SelectionLength > 0); if(m_rtb.ReadOnly) { m_vMenuItems[(int)RtbCtxCommands.Undo].Enabled = false; m_vMenuItems[(int)RtbCtxCommands.Cut].Enabled = false; m_vMenuItems[(int)RtbCtxCommands.Paste].Enabled = false; m_vMenuItems[(int)RtbCtxCommands.Delete].Enabled = false; } else // Editable { m_vMenuItems[(int)RtbCtxCommands.Undo].Enabled = m_rtb.CanUndo; m_vMenuItems[(int)RtbCtxCommands.Cut].Enabled = bHasSel; m_vMenuItems[(int)RtbCtxCommands.Paste].Enabled = true; // Optimistic m_vMenuItems[(int)RtbCtxCommands.Delete].Enabled = bHasSel; } m_vMenuItems[(int)RtbCtxCommands.Copy].Enabled = bHasSel; m_vMenuItems[(int)RtbCtxCommands.CopyAll].Enabled = bHasText; m_vMenuItems[(int)RtbCtxCommands.SelectAll].Enabled = bHasText; m_strCurLink = GetLinkBelowMouse(); m_vMenuItems[(int)RtbCtxCommands.CopyLink].Enabled = (m_strCurLink.Length > 0); } private string GetLinkBelowMouse() { // Save selection int iSelStart = m_rtb.SelectionStart, iSelLength = m_rtb.SelectionLength; string strLink = string.Empty; try { int p = m_rtb.GetCharIndexFromPosition(m_rtb.PointToClient( Cursor.Position)); m_rtb.Select(p, 1); if(UIUtil.RtfIsFirstCharLink(m_rtb)) { int l = p; while((l - 1) >= 0) { m_rtb.Select(l - 1, 1); if(!UIUtil.RtfIsFirstCharLink(m_rtb)) break; --l; } int r = p, n = m_rtb.TextLength; while((r + 1) < n) { m_rtb.Select(r + 1, 1); if(!UIUtil.RtfIsFirstCharLink(m_rtb)) break; ++r; } strLink = m_rtb.Text.Substring(l, r - l + 1); } } catch(Exception) { Debug.Assert(false); } m_rtb.Select(iSelStart, iSelLength); // Restore selection return strLink; } private void OnUndoCommand(object sender, EventArgs e) { m_rtb.Undo(); } private void OnCutCommand(object sender, EventArgs e) { m_rtb.Cut(); } private void OnCopyCommand(object sender, EventArgs e) { m_rtb.Copy(); } private void OnPasteCommand(object sender, EventArgs e) { CustomRichTextBoxEx crtb = (m_rtb as CustomRichTextBoxEx); if(crtb != null) crtb.PasteAcceptable(); else m_rtb.Paste(); } private void OnDeleteCommand(object sender, EventArgs e) { int nStart = m_rtb.SelectionStart, nLength = m_rtb.SelectionLength; if((nStart < 0) || (nLength <= 0)) return; string strText = m_rtb.Text; strText = strText.Remove(nStart, nLength); m_rtb.Text = strText; m_rtb.Select(nStart, 0); } private void OnCopyLinkCommand(object sender, EventArgs e) { ClipboardUtil.Copy(m_strCurLink, false, false, null, null, (m_form != null) ? m_form.Handle : IntPtr.Zero); } private void OnCopyAllCommand(object sender, EventArgs e) { int nStart = m_rtb.SelectionStart, nLength = m_rtb.SelectionLength; m_rtb.SelectAll(); m_rtb.Copy(); m_rtb.Select(nStart, nLength); } private void OnSelectAllCommand(object sender, EventArgs e) { m_rtb.SelectAll(); } } } KeePass/UI/CustomSplitContainerEx.cs0000664000000000000000000001241513222430414016401 0ustar rootroot/* KeePass Password Safe - The Open-Source Password Manager Copyright (C) 2003-2018 Dominik Reichl This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ using System; using System.Collections.Generic; using System.Text; using System.ComponentModel; using System.Windows.Forms; using System.Reflection; using System.Diagnostics; using KeePassLib.Native; namespace KeePass.UI { public sealed class CustomSplitContainerEx : SplitContainer { private ControlCollection m_ccControls = null; private Control m_cDefault = null; private Control m_cFocused = null; private Control m_cLastKnown = null; [Browsable(false)] [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] public double SplitterDistanceFrac { get { bool bVert = (this.Orientation == Orientation.Vertical); int m = (bVert ? this.Width : this.Height); if(m <= 0) { Debug.Assert(false); return 0.0; } int d = this.SplitterDistance; if(d < 0) { Debug.Assert(false); return 0.0; } if(d == 0) return 0.0; // Avoid fExact infinity double f = (double)d / (double)m; try { FieldInfo fi = GetRatioField(bVert); if(fi != null) { double fExact = (double)fi.GetValue(this); if(fExact > double.Epsilon) { fExact = 1.0 / fExact; // Test whether fExact makes sense and if so, // use it instead of f; 1/m as boundary is // slightly too strict if(Math.Abs(fExact - f) <= (1.5 / (double)m)) return fExact; else { Debug.Assert(false); } } else { Debug.Assert(false); } } else { Debug.Assert(false); } } catch(Exception) { Debug.Assert(false); } return f; } set { if((value < 0.0) || (value > 1.0)) { Debug.Assert(false); return; } bool bVert = (this.Orientation == Orientation.Vertical); int m = (bVert ? this.Width : this.Height); if(m <= 0) { Debug.Assert(false); return; } int d = (int)Math.Round(value * (double)m); if(d < 0) { Debug.Assert(false); d = 0; } if(d > m) { Debug.Assert(false); d = m; } this.SplitterDistance = d; if(d == 0) return; // Avoid infinity / division by zero // If the position was auto-adjusted (e.g. due to // minimum size constraints), skip the rest if(this.SplitterDistance != d) return; try { FieldInfo fi = GetRatioField(bVert); if(fi != null) { double fEst = (double)fi.GetValue(this); if(fEst <= double.Epsilon) { Debug.Assert(false); return; } fEst = 1.0 / fEst; // m/d -> d/m // Test whether fEst makes sense and if so, // overwrite it with the exact value; // we must test for 1.5/m, not 1/m, because .NET // uses Math.Floor and we use Math.Round if(Math.Abs(fEst - value) <= (1.5 / (double)m)) fi.SetValue(this, 1.0 / value); // d/m -> m/d else { Debug.Assert(false); } } else { Debug.Assert(false); } } catch(Exception) { Debug.Assert(false); } } } public CustomSplitContainerEx() : base() { } public void InitEx(ControlCollection cc, Control cDefault) { m_ccControls = cc; m_cDefault = m_cLastKnown = cDefault; } private static Control FindInputFocus(ControlCollection cc) { if(cc == null) { Debug.Assert(false); return null; } foreach(Control c in cc) { if(c.Focused) return c; else if(c.ContainsFocus) return FindInputFocus(c.Controls); } return null; } protected override void OnMouseDown(MouseEventArgs e) { m_cFocused = FindInputFocus(m_ccControls); if(m_cFocused == null) m_cFocused = m_cDefault; if(m_cFocused != null) m_cLastKnown = m_cFocused; base.OnMouseDown(e); } protected override void OnMouseUp(MouseEventArgs e) { base.OnMouseUp(e); if(m_cFocused != null) { UIUtil.SetFocus(m_cFocused, null); m_cFocused = null; } else { Debug.Assert(false); } } protected override void OnEnter(EventArgs e) { base.OnEnter(e); if(this.Focused && (m_cFocused == null)) { if(m_cLastKnown != null) UIUtil.SetFocus(m_cLastKnown, null); else if(m_cDefault != null) UIUtil.SetFocus(m_cDefault, null); } } private static FieldInfo GetRatioField(bool bVert) { // Both .NET and Mono store 'max/pos', not 'pos/max' return typeof(SplitContainer).GetField( (NativeLib.IsUnix() ? "fixed_none_ratio" : (bVert ? "ratioWidth" : "ratioHeight")), (BindingFlags.Instance | BindingFlags.NonPublic)); } } } KeePass/UI/PwInputControlGroup.cs0000664000000000000000000003760513222430414015747 0ustar rootroot/* KeePass Password Safe - The Open-Source Password Manager Copyright (C) 2003-2018 Dominik Reichl This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ using System; using System.Collections.Generic; using System.Diagnostics; using System.Drawing; using System.Text; using System.Threading; using System.Windows.Forms; using KeePass.App; using KeePass.App.Configuration; using KeePass.Forms; using KeePass.Resources; using KeePass.Util.Spr; using KeePassLib; using KeePassLib.Cryptography; using KeePassLib.Utility; namespace KeePass.UI { public sealed class PwInputControlGroup { private TextBox m_tbPassword = null; private CheckBox m_cbHide = null; private Label m_lblRepeat = null; private TextBox m_tbRepeat = null; private Label m_lblQualityPrompt = null; private QualityProgressBar m_pbQuality = null; private Label m_lblQualityInfo = null; private ToolTip m_ttHint = null; private Form m_fParent = null; private SecureEdit m_secPassword = null; private SecureEdit m_secRepeat = null; private bool m_bInitializing = false; private uint m_uPrgmCheck = 0; private bool m_bEnabled = true; public bool Enabled { get { return m_bEnabled; } set { if(value != m_bEnabled) { m_bEnabled = value; UpdateUI(); } } } private bool m_bSprVar = false; public bool IsSprVariant { get { return m_bSprVar; } set { m_bSprVar = value; } } public uint PasswordLength { get { if(m_secPassword == null) { Debug.Assert(false); return 0; } return m_secPassword.TextLength; } } private bool AutoRepeat { get { if(!Program.Config.UI.RepeatPasswordOnlyWhenHidden) return false; if(m_cbHide == null) { Debug.Assert(false); return false; } return !m_cbHide.Checked; } } private PwDatabase m_ctxDatabase = null; public PwDatabase ContextDatabase { get { return m_ctxDatabase; } set { m_ctxDatabase = value; } } private PwEntry m_ctxEntry = null; public PwEntry ContextEntry { get { return m_ctxEntry; } set { m_ctxEntry = value; } } public PwInputControlGroup() { } #if DEBUG ~PwInputControlGroup() { Debug.Assert(m_tbPassword == null); // Owner should call Release() Debug.Assert(m_uBlockUIUpdate == 0); Debug.Assert(m_lUqiTasks.Count == 0); } #endif public void Attach(TextBox tbPassword, CheckBox cbHide, Label lblRepeat, TextBox tbRepeat, Label lblQualityPrompt, QualityProgressBar pbQuality, Label lblQualityInfo, ToolTip ttHint, Form fParent, bool bInitialHide, bool bSecureDesktopMode) { if(tbPassword == null) throw new ArgumentNullException("tbPassword"); if(cbHide == null) throw new ArgumentNullException("cbHide"); if(lblRepeat == null) throw new ArgumentNullException("lblRepeat"); if(tbRepeat == null) throw new ArgumentNullException("tbRepeat"); if(lblQualityPrompt == null) throw new ArgumentNullException("lblQualityPrompt"); if(pbQuality == null) throw new ArgumentNullException("pbQuality"); if(lblQualityInfo == null) throw new ArgumentNullException("lblQualityInfo"); // ttHint may be null if(fParent == null) throw new ArgumentNullException("fParent"); Release(); m_bInitializing = true; m_tbPassword = tbPassword; m_cbHide = cbHide; m_lblRepeat = lblRepeat; m_tbRepeat = tbRepeat; m_lblQualityPrompt = lblQualityPrompt; m_pbQuality = pbQuality; m_lblQualityInfo = lblQualityInfo; m_ttHint = ttHint; m_fParent = fParent; m_secPassword = new SecureEdit(); m_secPassword.SecureDesktopMode = bSecureDesktopMode; m_secPassword.Attach(m_tbPassword, this.OnPasswordTextChanged, bInitialHide); m_secRepeat = new SecureEdit(); m_secRepeat.SecureDesktopMode = bSecureDesktopMode; m_secRepeat.Attach(m_tbRepeat, this.OnRepeatTextChanged, bInitialHide); ConfigureHideButton(m_cbHide, m_ttHint); m_cbHide.Checked = bInitialHide; m_cbHide.CheckedChanged += this.OnHideCheckedChanged; Debug.Assert(m_pbQuality.Minimum == 0); Debug.Assert(m_pbQuality.Maximum == 100); m_bInitializing = false; UpdateUI(); } public void Release() { Debug.Assert(!m_bInitializing); if(m_tbPassword == null) return; m_secPassword.Detach(); m_secRepeat.Detach(); m_cbHide.CheckedChanged -= this.OnHideCheckedChanged; m_tbPassword = null; m_cbHide = null; m_lblRepeat = null; m_tbRepeat = null; m_lblQualityPrompt = null; m_pbQuality = null; m_lblQualityInfo = null; m_ttHint = null; m_fParent = null; m_secPassword = null; m_secRepeat = null; } private uint m_uBlockUIUpdate = 0; private void UpdateUI() { if((m_uBlockUIUpdate > 0) || m_bInitializing) return; ++m_uBlockUIUpdate; ulong uFlags = 0; if(m_fParent is KeyCreationForm) uFlags = Program.Config.UI.KeyCreationFlags; byte[] pbUtf8 = m_secPassword.ToUtf8(); char[] v = StrUtil.Utf8.GetChars(pbUtf8); #if DEBUG byte[] pbTest = StrUtil.Utf8.GetBytes(v); Debug.Assert(MemUtil.ArraysEqual(pbUtf8, pbTest)); MemUtil.ZeroByteArray(pbTest); #endif m_tbPassword.Enabled = m_bEnabled; m_cbHide.Enabled = (m_bEnabled && ((uFlags & (ulong)AceKeyUIFlags.DisableHidePassword) == 0)); if((uFlags & (ulong)AceKeyUIFlags.CheckHidePassword) != 0) { ++m_uPrgmCheck; m_cbHide.Checked = true; --m_uPrgmCheck; } if((uFlags & (ulong)AceKeyUIFlags.UncheckHidePassword) != 0) { ++m_uPrgmCheck; m_cbHide.Checked = false; --m_uPrgmCheck; } bool bAutoRepeat = this.AutoRepeat; if(bAutoRepeat && (m_secRepeat.TextLength > 0)) m_secRepeat.SetPassword(MemUtil.EmptyByteArray); byte[] pbRepeat = m_secRepeat.ToUtf8(); if(!MemUtil.ArraysEqual(pbUtf8, pbRepeat) && !bAutoRepeat) m_tbRepeat.BackColor = AppDefs.ColorEditError; else m_tbRepeat.ResetBackColor(); bool bRepeatEnable = (m_bEnabled && !bAutoRepeat); m_lblRepeat.Enabled = bRepeatEnable; m_tbRepeat.Enabled = bRepeatEnable; bool bQuality = m_bEnabled; if(m_bSprVar && bQuality) { if(SprEngine.MightChange(v)) // Perf. opt. { // {S:...} and {REF:...} may reference the entry that // is currently being edited and SprEngine will not see // the current data entered in the dialog; thus we // disable quality estimation for all strings containing // one of these placeholders string str = new string(v); if((str.IndexOf(@"{S:", StrUtil.CaseIgnoreCmp) >= 0) || (str.IndexOf(@"{REF:", StrUtil.CaseIgnoreCmp) >= 0)) bQuality = false; else { SprContext ctx = new SprContext(m_ctxEntry, m_ctxDatabase, SprCompileFlags.NonActive, false, false); string strCmp = SprEngine.Compile(str, ctx); if(strCmp != str) bQuality = false; } } #if DEBUG else { string str = new string(v); SprContext ctx = new SprContext(m_ctxEntry, m_ctxDatabase, SprCompileFlags.NonActive, false, false); string strCmp = SprEngine.Compile(str, ctx); Debug.Assert(strCmp == str); } #endif } m_lblQualityPrompt.Enabled = bQuality; m_pbQuality.Enabled = bQuality; m_lblQualityInfo.Enabled = bQuality; if((Program.Config.UI.UIFlags & (ulong)AceUIFlags.HidePwQuality) != 0) { m_lblQualityPrompt.Visible = false; m_pbQuality.Visible = false; m_lblQualityInfo.Visible = false; } else if(bQuality || !m_bSprVar) UpdateQualityInfo(v); else UqiShowQuality(0, 0); MemUtil.ZeroByteArray(pbUtf8); MemUtil.ZeroByteArray(pbRepeat); MemUtil.ZeroArray(v); --m_uBlockUIUpdate; } private void OnPasswordTextChanged(object sender, EventArgs e) { UpdateUI(); } private void OnRepeatTextChanged(object sender, EventArgs e) { UpdateUI(); } private void OnHideCheckedChanged(object sender, EventArgs e) { if(m_bInitializing) return; bool bHide = m_cbHide.Checked; if(!bHide && (m_uPrgmCheck == 0)) { if(!AppPolicy.Try(AppPolicyId.UnhidePasswords)) { ++m_uPrgmCheck; m_cbHide.Checked = true; --m_uPrgmCheck; return; } } m_secPassword.EnableProtection(bHide); m_secRepeat.EnableProtection(bHide); bool bWasAutoRepeat = Program.Config.UI.RepeatPasswordOnlyWhenHidden; if(bHide && (m_uPrgmCheck == 0) && bWasAutoRepeat) { ++m_uBlockUIUpdate; byte[] pb = GetPasswordUtf8(); m_secRepeat.SetPassword(pb); MemUtil.ZeroByteArray(pb); --m_uBlockUIUpdate; } UpdateUI(); if(m_uPrgmCheck == 0) UIUtil.SetFocus(m_tbPassword, m_fParent); } public void SetPassword(byte[] pbUtf8, bool bSetRepeatPw) { if(pbUtf8 == null) { Debug.Assert(false); return; } ++m_uBlockUIUpdate; m_secPassword.SetPassword(pbUtf8); if(bSetRepeatPw && !this.AutoRepeat) m_secRepeat.SetPassword(pbUtf8); --m_uBlockUIUpdate; UpdateUI(); } public void SetPasswords(string strPassword, string strRepeat) { byte[] pbP = ((strPassword != null) ? StrUtil.Utf8.GetBytes( strPassword) : null); byte[] pbR = ((strRepeat != null) ? StrUtil.Utf8.GetBytes( strRepeat) : null); SetPasswords(pbP, pbR); } public void SetPasswords(byte[] pbPasswordUtf8, byte[] pbRepeatUtf8) { ++m_uBlockUIUpdate; if(pbPasswordUtf8 != null) m_secPassword.SetPassword(pbPasswordUtf8); if((pbRepeatUtf8 != null) && !this.AutoRepeat) m_secRepeat.SetPassword(pbRepeatUtf8); --m_uBlockUIUpdate; UpdateUI(); } public string GetPassword() { return StrUtil.Utf8.GetString(m_secPassword.ToUtf8()); } public byte[] GetPasswordUtf8() { return m_secPassword.ToUtf8(); } public string GetRepeat() { if(this.AutoRepeat) return GetPassword(); return StrUtil.Utf8.GetString(m_secRepeat.ToUtf8()); } public byte[] GetRepeatUtf8() { if(this.AutoRepeat) return GetPasswordUtf8(); return m_secRepeat.ToUtf8(); } public bool ValidateData(bool bUIOnError) { if(this.AutoRepeat) return true; if(m_secPassword.ContentsEqualTo(m_secRepeat)) return true; if(bUIOnError) { if(!VistaTaskDialog.ShowMessageBox(KPRes.PasswordRepeatFailed, KPRes.ValidationFailed, PwDefs.ShortProductName, VtdIcon.Warning, m_fParent)) MessageService.ShowWarning(KPRes.PasswordRepeatFailed); } return false; } private static string GetUqiTaskID(char[] v) { byte[] pb = StrUtil.Utf8.GetBytes(v); byte[] pbHash = CryptoUtil.HashSha256(pb); MemUtil.ZeroByteArray(pb); return Convert.ToBase64String(pbHash); } private List m_lUqiTasks = new List(); private readonly object m_oUqiTasksSync = new object(); private void UpdateQualityInfo(char[] v) { if(v == null) { Debug.Assert(false); return; } int nTasks; lock(m_oUqiTasksSync) { string strTask = GetUqiTaskID(v); if(m_lUqiTasks.Contains(strTask)) return; nTasks = m_lUqiTasks.Count; m_lUqiTasks.Add(strTask); } char[] vForTh = new char[v.Length]; // Will be cleared by thread Array.Copy(v, vForTh, v.Length); int nPoolWorkers, nPoolCompletions; ThreadPool.GetAvailableThreads(out nPoolWorkers, out nPoolCompletions); if((nTasks <= 3) && (nPoolWorkers >= 2)) ThreadPool.QueueUserWorkItem(new WaitCallback( this.UpdateQualityInfoTh), vForTh); else { ParameterizedThreadStart pts = new ParameterizedThreadStart( this.UpdateQualityInfoTh); Thread th = new Thread(pts); th.Start(vForTh); } } private void UpdateQualityInfoTh(object oPassword) { char[] v = (oPassword as char[]); if(v == null) { Debug.Assert(false); return; } char[] vNew = null; try { Debug.Assert(m_tbPassword.InvokeRequired); uint uBits = QualityEstimation.EstimatePasswordBits(v); TextBox tb = m_tbPassword; if(tb == null) return; // Control disposed in the meanwhile // Test whether the password has changed in the meanwhile vNew = (tb.Invoke(new UqiGetPasswordDelegate( this.UqiGetPassword)) as char[]); if(!MemUtil.ArrayHelperExOfChar.Equals(v, vNew)) return; tb.Invoke(new UqiShowQualityDelegate(this.UqiShowQuality), uBits, (uint)v.Length); } catch(Exception) { Debug.Assert(false); } finally { string strTask = GetUqiTaskID(v); lock(m_oUqiTasksSync) { m_lUqiTasks.Remove(strTask); } MemUtil.ZeroArray(v); if(vNew != null) MemUtil.ZeroArray(vNew); } } private delegate char[] UqiGetPasswordDelegate(); private char[] UqiGetPassword() { byte[] pb = null; try { pb = m_secPassword.ToUtf8(); return StrUtil.Utf8.GetChars(pb); } catch(Exception) { Debug.Assert(false); } finally { if(pb != null) MemUtil.ZeroByteArray(pb); } return null; } private delegate void UqiShowQualityDelegate(uint uBits, uint uLength); private void UqiShowQuality(uint uBits, uint uLength) { try { bool bUnknown = (m_bSprVar && !m_pbQuality.Enabled); string strBits = (bUnknown ? "?" : uBits.ToString()) + " " + KPRes.BitsStc; m_pbQuality.ProgressText = (bUnknown ? string.Empty : strBits); int iPos = (int)((100 * uBits) / (256 / 2)); if(iPos < 0) iPos = 0; else if(iPos > 100) iPos = 100; m_pbQuality.Value = iPos; string strLength = (bUnknown ? "?" : uLength.ToString()); string strInfo = strLength + " " + KPRes.CharsAbbr; if(Program.Config.UI.OptimizeForScreenReader) strInfo = strBits + ", " + strInfo; UIUtil.SetText(m_lblQualityInfo, strInfo); if(m_ttHint != null) m_ttHint.SetToolTip(m_lblQualityInfo, KPRes.PasswordLength + ": " + strLength + " " + KPRes.CharsStc); } catch(Exception) { Debug.Assert(false); } } private static Bitmap g_bmpLightDots = null; internal static void ConfigureHideButton(CheckBox cb, ToolTip tt) { if(cb == null) { Debug.Assert(false); return; } Debug.Assert(!cb.AutoSize); Debug.Assert(cb.Appearance == Appearance.Button); Debug.Assert(cb.Image == null); Debug.Assert(cb.Text == "***"); Debug.Assert(cb.TextAlign == ContentAlignment.MiddleCenter); Debug.Assert(cb.TextImageRelation == TextImageRelation.Overlay); Debug.Assert(cb.UseVisualStyleBackColor); Debug.Assert((cb.Width == 32) || DpiUtil.ScalingRequired || MonoWorkarounds.IsRequired(100001)); Debug.Assert((cb.Height == 23) || DpiUtil.ScalingRequired || MonoWorkarounds.IsRequired(100001)); // Too much spacing between the dots when using the default font // cb.Text = new string(SecureEdit.PasswordChar, 3); cb.Text = string.Empty; Image img = Properties.Resources.B19x07_3BlackDots; if(UIUtil.IsDarkTheme) { if(g_bmpLightDots == null) g_bmpLightDots = UIUtil.InvertImage(img); if(g_bmpLightDots != null) img = g_bmpLightDots; } else { Debug.Assert(g_bmpLightDots == null); } // Always or never cb.Image = img; Debug.Assert(cb.ImageAlign == ContentAlignment.MiddleCenter); if(tt != null) tt.SetToolTip(cb, KPRes.TogglePasswordAsterisks); } } } KeePass/UI/CustomMenuStripEx.cs0000664000000000000000000000355713222430414015400 0ustar rootroot/* KeePass Password Safe - The Open-Source Password Manager Copyright (C) 2003-2018 Dominik Reichl This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ using System; using System.Collections.Generic; using System.Text; using System.Windows.Forms; using KeePass.Native; namespace KeePass.UI { public sealed class CustomMenuStripEx : MenuStrip { public CustomMenuStripEx() : base() { // ThemeToolStripRenderer.AttachTo(this); UIUtil.Configure(this); } protected override void WndProc(ref Message m) { base.WndProc(ref m); // Enable 'click through' behavior if((m.Msg == NativeMethods.WM_MOUSEACTIVATE) && (m.Result == (IntPtr)NativeMethods.MA_ACTIVATEANDEAT)) { m.Result = (IntPtr)NativeMethods.MA_ACTIVATE; } } // protected override void OnItemClicked(ToolStripItemClickedEventArgs e) // { // if(UIUtil.HasClickedSeparator(e)) return; // Ignore the click // base.OnItemClicked(e); // } // protected override void OnMouseUp(MouseEventArgs mea) // { // ToolStripSeparator s = (GetItemAt(mea.X, mea.Y) as ToolStripSeparator); // if(s != null) return; // base.OnMouseUp(mea); // } } } KeePass/UI/RtlAwareResizeScope.cs0000664000000000000000000000476713222430414015663 0ustar rootroot/* KeePass Password Safe - The Open-Source Password Manager Copyright (C) 2003-2018 Dominik Reichl This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ using System; using System.Collections.Generic; using System.Diagnostics; using System.Drawing; using System.Text; using System.Windows.Forms; using KeePassLib.Translation; namespace KeePass.UI { public sealed class RtlAwareResizeScope : IDisposable { private List m_lControls = new List(); private List m_lOrgX = new List(); private List m_lOrgW = new List(); public RtlAwareResizeScope(params Control[] v) { if(v != null) { foreach(Control c in v) { if(c == null) { Debug.Assert(false); continue; } try { if((c.RightToLeft == RightToLeft.Yes) && KPTranslation.IsRtlMoveChildsRequired(c.Parent)) { int x = c.Location.X; int w = c.Width; m_lControls.Add(c); m_lOrgX.Add(x); m_lOrgW.Add(w); } } catch(Exception) { Debug.Assert(false); } } } else { Debug.Assert(false); } } public void Dispose() { Dispose(true); GC.SuppressFinalize(this); } private void Dispose(bool bDisposing) { if(!bDisposing) { Debug.Assert(false); return; } for(int i = 0; i < m_lControls.Count; ++i) { try { Control c = m_lControls[i]; int xOrg = m_lOrgX[i]; int wOrg = m_lOrgW[i]; Point ptNew = c.Location; int wNew = c.Width; Debug.Assert(c.RightToLeft == RightToLeft.Yes); if((wNew != wOrg) && (ptNew.X == xOrg)) c.Location = new Point(xOrg + wOrg - wNew, ptNew.Y); } catch(Exception) { Debug.Assert(false); } } m_lControls.Clear(); m_lOrgX.Clear(); m_lOrgW.Clear(); } } } KeePass/UI/ExpiryControlGroup.cs0000664000000000000000000000623413222430414015613 0ustar rootroot/* KeePass Password Safe - The Open-Source Password Manager Copyright (C) 2003-2018 Dominik Reichl This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ using System; using System.Collections.Generic; using System.Text; using System.Windows.Forms; using System.Globalization; using System.Diagnostics; using KeePassLib; using KeePassLib.Utility; namespace KeePass.UI { public sealed class ExpiryControlGroup { private CheckBox m_cb = null; private DateTimePicker m_dtp = null; public bool Checked { get { if(m_cb == null) { Debug.Assert(false); return false; } return m_cb.Checked; } set { UIUtil.SetChecked(m_cb, value); } } public DateTime Value { get { if(m_dtp == null) { Debug.Assert(false); return DateTime.UtcNow; } // Force validation/update of incomplete edit // (workaround for KPB 3505269) if(m_dtp.Focused && m_dtp.Visible) { m_dtp.Visible = false; m_dtp.Visible = true; } return TimeUtil.ToUtc(m_dtp.Value, false); } set { if(m_dtp == null) { Debug.Assert(false); return; } m_dtp.Value = TimeUtil.ToLocal(value, true); } } public ExpiryControlGroup() { } #if DEBUG ~ExpiryControlGroup() { Debug.Assert(m_cb == null); // Owner should call Release() } #endif public void Attach(CheckBox cb, DateTimePicker dtp) { if(cb == null) throw new ArgumentNullException("cb"); if(dtp == null) throw new ArgumentNullException("dtp"); m_cb = cb; m_dtp = dtp; // m_dtp.ShowUpDown = true; m_dtp.CustomFormat = DateTimeFormatInfo.CurrentInfo.ShortDatePattern + " " + DateTimeFormatInfo.CurrentInfo.LongTimePattern; m_dtp.ValueChanged += this.OnExpiryValueChanged; // Also handle key press event (workaround for KPB 3505269) m_dtp.KeyPress += this.OnExpiryKeyPress; } public void Release() { if(m_cb == null) return; m_dtp.ValueChanged -= this.OnExpiryValueChanged; m_dtp.KeyPress -= this.OnExpiryKeyPress; m_cb = null; m_dtp = null; } private void UpdateUI(bool? pbSetCheck) { if(pbSetCheck.HasValue) UIUtil.SetChecked(m_cb, pbSetCheck.Value); UIUtil.SetEnabled(m_dtp, m_cb.Enabled); } private void OnExpiryValueChanged(object sender, EventArgs e) { UpdateUI(true); } private void OnExpiryKeyPress(object sender, KeyPressEventArgs e) { if(char.IsDigit(e.KeyChar)) UpdateUI(true); } } } KeePass/UI/ToolStripRendering/0000775000000000000000000000000013222430414015216 5ustar rootrootKeePass/UI/ToolStripRendering/SystemTsr.cs0000664000000000000000000003042013222430414017521 0ustar rootroot/* KeePass Password Safe - The Open-Source Password Manager Copyright (C) 2003-2018 Dominik Reichl This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ using System; using System.Collections.Generic; using System.Diagnostics; using System.Drawing; using System.Drawing.Drawing2D; using System.Text; using System.Windows.Forms; using KeePass.Resources; using KeePassLib; namespace KeePass.UI.ToolStripRendering { internal sealed class SystemTsrFactory : TsrFactory { private PwUuid m_uuid = new PwUuid(new byte[] { 0x6B, 0xCD, 0x45, 0xFA, 0xA1, 0x3F, 0x71, 0xEC, 0x7B, 0x5E, 0x97, 0x38, 0x8D, 0xB1, 0xCB, 0x09 }); public override PwUuid Uuid { get { return m_uuid; } } public override string Name { get { return (KPRes.System + " - " + KPRes.ClassicAdj); } } public override ToolStripRenderer CreateInstance() { return new SystemTsr(); } } // Checkboxes are rendered incorrectly /* internal sealed class SystemTsrFactory : TsrFactory { private PwUuid m_uuid = new PwUuid(new byte[] { 0x03, 0xF8, 0x67, 0xAB, 0x21, 0x96, 0x43, 0xED, 0xA5, 0xFE, 0x9E, 0x43, 0x4A, 0x35, 0x89, 0xAA }); public override PwUuid Uuid { get { return m_uuid; } } public override string Name { get { return (KPRes.System + " - " + KPRes.ClassicAdj); } } public override ToolStripRenderer CreateInstance() { return new ToolStripSystemRenderer(); } } */ internal sealed class SystemTsr : ProExtTsr { private sealed class SystemTsrColorTable : ProfessionalColorTable { private Color m_clrItemActiveBack = SystemColors.Control; private Color m_clrItemActiveBorder = SystemColors.ControlDarkDark; private Color m_clrItemSelBack = SystemColors.Control; private Color m_clrItemSelBorder = SystemColors.ControlDark; private Color m_clrBarBack = SystemColors.MenuBar; private Color m_clrMenuBack = SystemColors.Menu; private Color m_clrImageBack = SystemColors.Menu; private Color m_clrSubItemSelBack = SystemColors.MenuHighlight; private Color m_clrSubItemSelBorder = SystemColors.MenuHighlight; public override Color ButtonCheckedGradientBegin { get { return m_clrItemActiveBack; } } public override Color ButtonCheckedGradientEnd { get { return m_clrItemActiveBack; } } public override Color ButtonCheckedGradientMiddle { get { return m_clrItemActiveBack; } } public override Color ButtonCheckedHighlight { get { return m_clrItemActiveBack; } // Untested } public override Color ButtonCheckedHighlightBorder { get { return m_clrItemActiveBorder; } // Untested } public override Color ButtonPressedBorder { get { return m_clrItemActiveBorder; } } public override Color ButtonPressedGradientBegin { get { return m_clrItemActiveBack; } } public override Color ButtonPressedGradientEnd { get { return m_clrItemActiveBack; } } public override Color ButtonPressedGradientMiddle { get { return m_clrItemActiveBack; } } public override Color ButtonPressedHighlight { get { return m_clrItemActiveBack; } // Untested } public override Color ButtonPressedHighlightBorder { get { return m_clrItemActiveBorder; } // Untested } public override Color ButtonSelectedBorder { get { return m_clrItemSelBorder; } } public override Color ButtonSelectedGradientBegin { get { return m_clrItemSelBack; } } public override Color ButtonSelectedGradientEnd { get { return m_clrItemSelBack; } } public override Color ButtonSelectedGradientMiddle { get { return m_clrItemSelBack; } } public override Color ButtonSelectedHighlight { get { return m_clrItemSelBack; } // Untested } public override Color ButtonSelectedHighlightBorder { get { return m_clrItemSelBorder; } } public override Color CheckBackground { get { return m_clrMenuBack; } } public override Color CheckPressedBackground { get { return m_clrMenuBack; } } public override Color CheckSelectedBackground { get { return m_clrMenuBack; } } public override Color GripDark { get { return SystemColors.ControlDark; } } public override Color GripLight { get { return SystemColors.ControlLight; } } public override Color ImageMarginGradientBegin { get { return m_clrImageBack; } } public override Color ImageMarginGradientEnd { get { return m_clrImageBack; } } public override Color ImageMarginGradientMiddle { get { return m_clrImageBack; } } public override Color ImageMarginRevealedGradientBegin { get { return m_clrImageBack; } } public override Color ImageMarginRevealedGradientEnd { get { return m_clrImageBack; } } public override Color ImageMarginRevealedGradientMiddle { get { return m_clrImageBack; } } public override Color MenuBorder { get { return SystemColors.ActiveBorder; } } public override Color MenuItemBorder { get { return m_clrSubItemSelBorder; } } public override Color MenuItemSelected { get { return m_clrSubItemSelBack; } } public override Color MenuItemPressedGradientBegin { // Used by pressed root menu items and inactive drop-down // arrow buttons in toolbar comboboxes (?!) get { return m_clrMenuBack; } } public override Color MenuItemPressedGradientEnd { get { return m_clrItemActiveBack; } } public override Color MenuItemPressedGradientMiddle { get { return m_clrItemActiveBack; } } public override Color MenuItemSelectedGradientBegin { get { return m_clrItemSelBack; } } public override Color MenuItemSelectedGradientEnd { get { return m_clrItemSelBack; } } public override Color MenuStripGradientBegin { get { return m_clrBarBack; } } public override Color MenuStripGradientEnd { get { return m_clrBarBack; } } public override Color OverflowButtonGradientBegin { get { return SystemColors.ControlLight; } } public override Color OverflowButtonGradientEnd { get { return SystemColors.ControlDark; } } public override Color OverflowButtonGradientMiddle { get { return SystemColors.Control; } } public override Color RaftingContainerGradientBegin { get { return m_clrMenuBack; } // Untested } public override Color RaftingContainerGradientEnd { get { return m_clrMenuBack; } // Untested } public override Color SeparatorDark { // SeparatorDark is used for both the menu and the toolbar get { return SystemColors.ControlDark; } } public override Color SeparatorLight { get { return m_clrBarBack; } } public override Color StatusStripGradientBegin { get { return m_clrMenuBack; } } public override Color StatusStripGradientEnd { get { return m_clrMenuBack; } } public override Color ToolStripBorder { get { return m_clrMenuBack; } } public override Color ToolStripContentPanelGradientBegin { get { return m_clrMenuBack; } // Untested } public override Color ToolStripContentPanelGradientEnd { get { return m_clrMenuBack; } // Untested } public override Color ToolStripDropDownBackground { get { return m_clrMenuBack; } } public override Color ToolStripGradientBegin { get { return m_clrBarBack; } } public override Color ToolStripGradientEnd { get { return m_clrBarBack; } } public override Color ToolStripGradientMiddle { get { return m_clrBarBack; } } public override Color ToolStripPanelGradientBegin { get { return m_clrBarBack; } // Untested } public override Color ToolStripPanelGradientEnd { get { return m_clrBarBack; } // Untested } } protected override bool EnsureTextContrast { get { return false; } // Prevent color override by base class } public SystemTsr() : base(new SystemTsrColorTable()) { } protected override void OnRenderItemText(ToolStripItemTextRenderEventArgs e) { if(e != null) { ToolStripItem tsi = e.Item; if(tsi != null) { bool bDropDown = (tsi.OwnerItem != null); bool bCtxMenu = (tsi.Owner is ContextMenuStrip); Color clr = tsi.ForeColor; if(!tsi.Enabled && !tsi.Selected) { if(!UIUtil.IsHighContrast) { // Draw light "shadow" Rectangle r = e.TextRectangle; int dx = DpiUtil.ScaleIntX(128) / 128; // Force floor int dy = DpiUtil.ScaleIntY(128) / 128; // Force floor r.Offset(dx, dy); TextRenderer.DrawText(e.Graphics, e.Text, e.TextFont, r, SystemColors.HighlightText, e.TextFormat); } clr = SystemColors.GrayText; } else if(tsi.Selected && (bDropDown || bCtxMenu)) clr = SystemColors.HighlightText; else if(clr.ToArgb() == Control.DefaultForeColor.ToArgb()) clr = SystemColors.MenuText; else { bool bDarkBack = this.IsDarkStyle; bool bDarkText = UIUtil.IsDarkColor(clr); if((bDarkBack && bDarkText) || (!bDarkBack && !bDarkText)) { Debug.Assert(false); clr = SystemColors.MenuText; } } e.TextColor = clr; } } else { Debug.Assert(false); } base.OnRenderItemText(e); } protected override void OnRenderMenuItemBackground(ToolStripItemRenderEventArgs e) { ToolStripItem tsi = ((e != null) ? e.Item : null); bool bCtxItem = ((tsi != null) ? (tsi.Owner is ContextMenuStrip) : false); if((tsi != null) && (bCtxItem || (tsi.OwnerItem != null)) && tsi.Selected && !tsi.Enabled) { Rectangle rect = tsi.ContentRectangle; rect.Offset(0, -1); rect.Height += 1; Color clrBack = this.ColorTable.MenuItemSelected; Color clrBorder = clrBack; SolidBrush br = new SolidBrush(clrBack); Pen p = new Pen(clrBorder); Graphics g = e.Graphics; if(g != null) { g.FillRectangle(br, rect); g.DrawRectangle(p, rect); } else { Debug.Assert(false); } p.Dispose(); br.Dispose(); } /* else if((tsi != null) && !bCtxItem && (tsi.OwnerItem == null) && (tsi.Selected || tsi.Pressed)) { Rectangle rect = tsi.ContentRectangle; rect.Offset(0, -1); rect.Height += 1; // ButtonState bs = (tsi.Pressed ? ButtonState.Pushed : ButtonState.Normal); // if(!tsi.Enabled) bs = ButtonState.Inactive; // ControlPaint.DrawButton(e.Graphics, rect, bs); DrawButton(e.Graphics, rect, tsi.Pressed); } */ else base.OnRenderMenuItemBackground(e); } /* private static void DrawButton(Graphics g, Rectangle r, bool bPressed) { using(SolidBrush brBack = new SolidBrush(SystemColors.Control)) { g.FillRectangle(brBack, r); } Color clrTL = (bPressed ? SystemColors.ButtonShadow : SystemColors.ButtonHighlight); Color clrBR = (bPressed ? SystemColors.ButtonHighlight : SystemColors.ButtonShadow); int x1 = r.Left + 2, y1 = r.Top; int x2 = r.Right - 3, y2 = r.Bottom; using(Pen pTL = new Pen(clrTL)) { g.DrawLine(pTL, x1, y1, x2, y1); g.DrawLine(pTL, x1, y1, x1, y2); } using(Pen pBR = new Pen(clrBR)) { g.DrawLine(pBR, x1, y2, x2, y2); g.DrawLine(pBR, x2, y1, x2, y2); } } */ } } KeePass/UI/ToolStripRendering/KeePassTsr.cs0000664000000000000000000001322413222430414017573 0ustar rootroot/* KeePass Password Safe - The Open-Source Password Manager Copyright (C) 2003-2018 Dominik Reichl This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ using System; using System.Collections.Generic; using System.Diagnostics; using System.Drawing; using System.Drawing.Drawing2D; using System.Text; using System.Windows.Forms; using KeePass.Resources; using KeePassLib; using KeePassLib.Utility; namespace KeePass.UI.ToolStripRendering { internal sealed class KeePassTsrFactory : TsrFactory { private PwUuid m_uuid = new PwUuid(new byte[] { 0x05, 0x0A, 0x57, 0xF0, 0x7B, 0xBC, 0x34, 0xAF, 0x5B, 0x8F, 0xA1, 0x31, 0xDB, 0xBF, 0x2B, 0xEC }); public override PwUuid Uuid { get { return m_uuid; } } public override string Name { get { return (PwDefs.ShortProductName + " - " + KPRes.Gradient); } } public override bool IsSupported() { // bool bVisualStyles = true; // try { bVisualStyles = VisualStyleRenderer.IsSupported; } // catch(Exception) { Debug.Assert(false); bVisualStyles = false; } // Various drawing bugs under Mono (gradients too light, incorrect // painting of popup menus, paint method not invoked for disabled // items, ...) bool bMono = MonoWorkarounds.IsRequired(); return (!UIUtil.IsHighContrast && !bMono); } public override ToolStripRenderer CreateInstance() { return new KeePassTsr(); } } internal sealed class KeePassTsr : ProExtTsr { private sealed class KeePassTsrColorTable : ProfessionalColorTable { private const double m_dblLight = 0.75; private const double m_dblDark = 0.05; internal static Color StartGradient(Color clr) { return UIUtil.LightenColor(clr, m_dblLight); } internal static Color EndGradient(Color clr) { return UIUtil.DarkenColor(clr, m_dblDark); } public override Color ButtonPressedGradientBegin { get { return StartGradient(this.ButtonPressedGradientMiddle); } } public override Color ButtonPressedGradientEnd { get { return EndGradient(this.ButtonPressedGradientMiddle); } } public override Color ButtonSelectedGradientBegin { get { return StartGradient(this.ButtonSelectedGradientMiddle); } } public override Color ButtonSelectedGradientEnd { get { return EndGradient(this.ButtonSelectedGradientMiddle); } } public override Color ImageMarginGradientBegin { get { return StartGradient(this.ImageMarginGradientMiddle); } } public override Color ImageMarginGradientEnd { get { return EndGradient(this.ImageMarginGradientMiddle); } } /* public override Color MenuItemPressedGradientBegin { get { return StartGradient(this.MenuItemPressedGradientMiddle); } } public override Color MenuItemPressedGradientEnd { get { return EndGradient(this.MenuItemPressedGradientMiddle); } } */ public override Color MenuItemSelectedGradientBegin { get { return StartGradient(this.MenuItemSelected); } } public override Color MenuItemSelectedGradientEnd { get { return EndGradient(this.MenuItemSelected); } } } public KeePassTsr() : base(new KeePassTsrColorTable()) { } protected override void OnRenderMenuItemBackground(ToolStripItemRenderEventArgs e) { ToolStripItem tsi = ((e != null) ? e.Item : null); if((tsi != null) && ((tsi.Owner is ContextMenuStrip) || (tsi.OwnerItem != null)) && tsi.Selected) { Rectangle rect = tsi.ContentRectangle; rect.Offset(0, -1); rect.Height += 1; Color clrStart = KeePassTsrColorTable.StartGradient(this.ColorTable.MenuItemSelected); Color clrEnd = KeePassTsrColorTable.EndGradient(this.ColorTable.MenuItemSelected); Color clrBorder = this.ColorTable.MenuItemBorder; if(!tsi.Enabled) { Color clrBase = this.ColorTable.MenuStripGradientEnd; clrStart = UIUtil.ColorTowardsGrayscale(clrStart, clrBase, 0.5); clrEnd = UIUtil.ColorTowardsGrayscale(clrEnd, clrBase, 0.2); clrBorder = UIUtil.ColorTowardsGrayscale(clrBorder, clrBase, 0.2); } Graphics g = e.Graphics; if(g != null) { LinearGradientBrush br = new LinearGradientBrush(rect, clrStart, clrEnd, LinearGradientMode.Vertical); Pen p = new Pen(clrBorder); SmoothingMode smOrg = g.SmoothingMode; g.SmoothingMode = SmoothingMode.HighQuality; GraphicsPath gp = UIUtil.CreateRoundedRectangle(rect.X, rect.Y, rect.Width, rect.Height, DpiUtil.ScaleIntY(2)); if(gp != null) { g.FillPath(br, gp); g.DrawPath(p, gp); gp.Dispose(); } else // Shouldn't ever happen... { Debug.Assert(false); g.FillRectangle(br, rect); g.DrawRectangle(p, rect); } g.SmoothingMode = smOrg; p.Dispose(); br.Dispose(); return; } else { Debug.Assert(false); } } base.OnRenderMenuItemBackground(e); } } } KeePass/UI/ToolStripRendering/VisualStyleTsr.cs0000664000000000000000000001667513222430414020541 0ustar rootroot/* KeePass Password Safe - The Open-Source Password Manager Copyright (C) 2003-2018 Dominik Reichl This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ /* using System; using System.Collections.Generic; using System.Text; using System.Windows.Forms; using System.Windows.Forms.VisualStyles; using System.Drawing; using System.Diagnostics; // Parts and States: // https://msdn.microsoft.com/en-us/library/bb773210.aspx // How to Implement a Custom ToolStripRenderer: // https://msdn.microsoft.com/en-us/library/ms229720.aspx namespace KeePass.UI.ToolStripRendering { public sealed class VisualStyleTsr : ProExtTsr { private const string VsClassMenu = "MENU"; private const string VsClassToolBar = "TOOLBAR"; private const string VsClassReBar = "REBAR"; private enum VsMenuPart : int { MenuItemTmSchema = 1, MenuDropDownTmSchema = 2, MenuBarItemTmSchema = 3, MenuBarDropDownTmSchema = 4, ChevronTmSchema = 5, SeparatorTmSchema = 6, BarBackground = 7, BarItem = 8, PopupBackground = 9, PopupBorders = 10, PopupCheck = 11, PopupCheckBackground = 12, PopupGutter = 13, PopupItem = 14, PopupSeparator = 15, PopupSubMenu = 16, SystemClose = 17, SystemMaximize = 18, SystemMinimize = 19, SystemRestore = 20 } private enum VsMenuState : int { Default = 0, MbActive = 1, MbInactive = 2, MbiNormal = 1, MbiHot = 2, MbiPushed = 3, MbiDisabled = 4, MbiDisabledHot = 5, MbiDisabledPushed = 6, McCheckMarkNormal = 1, McCheckMarkDisabled = 2, McBulletNormal = 3, McBulletDisabled = 4, McbDisabled = 1, McbNormal = 2, McbBitmap = 3, MpiNormal = 1, MpiHot = 2, MpiDisabled = 3, MpiDisabledHot = 4, MsmNormal = 1, MsmDisabled = 2 }; private enum VsReBarPart : int { Gripper = 1, GripperVert = 2, Band = 3, Chevron = 4, ChevronVert = 5, Background = 6, Splitter = 7, SplitterVert = 8 } private VisualStyleRenderer m_r = null; private bool IsSupported { get { return (m_r != null); } } public VisualStyleTsr() : base() { try { if(VisualStyleRenderer.IsSupported) m_r = new VisualStyleRenderer(VsClassMenu, (int)VsMenuPart.BarBackground, (int)VsMenuState.MbActive); } catch(Exception) { } } private void DrawBackgroundEx(Graphics g, Rectangle rect, Control c, bool bCanPaintParent) { if(bCanPaintParent && m_r.IsBackgroundPartiallyTransparent() && (c != null)) m_r.DrawParentBackground(g, rect, c); m_r.DrawBackground(g, rect); #if DEBUG Color clr = Color.Red; string str = Environment.StackTrace; if(str.IndexOf("OnRenderMenuItemBackground") >= 0) clr = Color.Green; if(str.IndexOf("OnRenderToolStripBackground") >= 0) clr = Color.Blue; if(str.IndexOf("OnRenderToolStripBorder") >= 0) clr = Color.Pink; using(SolidBrush br = new SolidBrush(clr)) { using(Pen p = new Pen(UIUtil.LightenColor(clr, 0.5))) { g.FillRectangle(br, rect); g.DrawRectangle(p, rect); } } #endif } private void ConfigureForItem(ToolStripItem tsi) { bool bEnabled = tsi.Enabled; bool bPressed = tsi.Pressed; bool bHot = tsi.Selected; string c = VsClassMenu; if(tsi.IsOnDropDown) { const int p = (int)VsMenuPart.PopupItem; if(bEnabled) m_r.SetParameters(c, p, (int)(bHot ? VsMenuState.MpiHot : VsMenuState.MpiNormal)); else m_r.SetParameters(c, p, (int)(bHot ? VsMenuState.MpiDisabledHot : VsMenuState.MpiDisabled)); } else { const int p = (int)VsMenuPart.BarItem; if(tsi.Pressed) m_r.SetParameters(c, p, (int)(bEnabled ? VsMenuState.MbiPushed : VsMenuState.MbiDisabledPushed)); else if(bEnabled) m_r.SetParameters(c, p, (int)(bHot ? VsMenuState.MbiHot : VsMenuState.MbiNormal)); else m_r.SetParameters(c, p, (int)(bHot ? VsMenuState.MbiDisabledHot : VsMenuState.MbiDisabled)); } } private delegate bool TsrBoolDelegate(); private delegate void TsrFuncDelegate(T e); private void RenderOrBase(T e, TsrBoolDelegate f, TsrFuncDelegate fBase) { bool bBase = true; try { if(this.IsSupported) bBase = !f(); } catch(Exception) { Debug.Assert(false); } if(bBase) fBase(e); } private Rectangle GetBackgroundRect(Graphics g, ToolStripItem tsi) { if(!tsi.IsOnDropDown) return new Rectangle(0, 0, tsi.Width, tsi.Height - 1); Rectangle rect = new Rectangle(Point.Empty, tsi.Size); Size szBorder = GetPopupBorderSize(g); rect.Inflate(-szBorder.Width, 0); rect.X += 1; rect.Width -= 1; return rect; } private Size GetPopupBorderSize(Graphics g) { Size sz = m_r.GetPartSize(g, ThemeSizeType.Minimum); if(sz.Width < 1) { Debug.Assert(false); sz.Width = 1; } if(sz.Height < 1) { Debug.Assert(false); sz.Height = 1; } return sz; } protected override void OnRenderMenuItemBackground(ToolStripItemRenderEventArgs e) { TsrBoolDelegate f = delegate() { ConfigureForItem(e.Item); DrawBackgroundEx(e.Graphics, GetBackgroundRect(e.Graphics, e.Item), e.ToolStrip, false); return true; }; RenderOrBase(e, f, base.OnRenderMenuItemBackground); } protected override void OnRenderToolStripBackground(ToolStripRenderEventArgs e) { TsrBoolDelegate f = delegate() { Debug.Assert(e.AffectedBounds == e.ToolStrip.ClientRectangle); VisualStyleElement vse = VisualStyleElement.CreateElement(VsClassMenu, (int)VsMenuPart.BarBackground, (int)VsMenuState.MbInactive); if(!VisualStyleRenderer.IsElementDefined(vse)) vse = VisualStyleElement.CreateElement(VsClassMenu, (int)VsMenuPart.BarBackground, 0); m_r.SetParameters(vse); DrawBackgroundEx(e.Graphics, e.ToolStrip.ClientRectangle, e.ToolStrip, true); return true; }; RenderOrBase(e, f, base.OnRenderToolStripBackground); } protected override void OnRenderToolStripBorder(ToolStripRenderEventArgs e) { TsrBoolDelegate f = delegate() { Debug.Assert(e.AffectedBounds == e.ToolStrip.ClientRectangle); m_r.SetParameters(VsClassMenu, (int)VsMenuPart.PopupBorders, 0); Graphics g = e.Graphics; Rectangle rectClient = e.ToolStrip.ClientRectangle; Rectangle rect = rectClient; Size szBorder = GetPopupBorderSize(e.Graphics); rect.Inflate(-szBorder.Width, -szBorder.Height); Region rgOrgClip = g.Clip.Clone(); g.ExcludeClip(rect); DrawBackgroundEx(g, rectClient, e.ToolStrip, false); g.Clip = rgOrgClip; return true; }; RenderOrBase(e, f, base.OnRenderToolStripBorder); } } } */ KeePass/UI/ToolStripRendering/TsrFactory.cs0000664000000000000000000000237113222430414017650 0ustar rootroot/* KeePass Password Safe - The Open-Source Password Manager Copyright (C) 2003-2018 Dominik Reichl This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ using System; using System.Collections.Generic; using System.Text; using System.Windows.Forms; using KeePassLib; namespace KeePass.UI.ToolStripRendering { public abstract class TsrFactory { public abstract PwUuid Uuid { get; } public abstract string Name { get; } public virtual bool IsSupported() { return true; } public abstract ToolStripRenderer CreateInstance(); } } KeePass/UI/ToolStripRendering/Win81Tsr.cs0000664000000000000000000002256313222430414017154 0ustar rootroot/* KeePass Password Safe - The Open-Source Password Manager Copyright (C) 2003-2018 Dominik Reichl This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ using System; using System.Collections.Generic; using System.Diagnostics; using System.Drawing; using System.Drawing.Drawing2D; using System.Text; using System.Windows.Forms; using KeePassLib; namespace KeePass.UI.ToolStripRendering { internal sealed class Win81TsrFactory : TsrFactory { private PwUuid m_uuid = new PwUuid(new byte[] { 0xEF, 0x5B, 0x4B, 0xE8, 0x49, 0xD1, 0x5E, 0x71, 0x65, 0xE0, 0x26, 0x3B, 0x03, 0xBD, 0x8C, 0x3B }); public override PwUuid Uuid { get { return m_uuid; } } public override string Name { get { return "Windows 8.1"; } } public override bool IsSupported() { return !UIUtil.IsHighContrast; } public override ToolStripRenderer CreateInstance() { return new Win81Tsr(); } } internal sealed class Win81Tsr : ProExtTsr { private sealed class Win81TsrColorTable : ProfessionalColorTable { private Color m_clrItemActiveBack = Color.FromArgb(184, 216, 249); private Color m_clrItemActiveBorder = Color.FromArgb(98, 163, 229); private Color m_clrItemSelBack = Color.FromArgb(213, 231, 248); private Color m_clrItemSelBorder = Color.FromArgb(122, 177, 232); private Color m_clrBarBack = Color.FromArgb(245, 246, 247); private Color m_clrMenuBack = Color.FromArgb(240, 240, 240); private Color m_clrImageBack = Color.FromArgb(240, 240, 240); private Color m_clrSubItemSelBack = Color.FromArgb(209, 226, 242); private Color m_clrSubItemSelBorder = Color.FromArgb(120, 174, 229); public override Color ButtonCheckedGradientBegin { get { return m_clrItemActiveBack; } } public override Color ButtonCheckedGradientEnd { get { return m_clrItemActiveBack; } } public override Color ButtonCheckedGradientMiddle { get { return m_clrItemActiveBack; } } public override Color ButtonCheckedHighlight { get { return m_clrItemActiveBack; } // Untested } public override Color ButtonCheckedHighlightBorder { get { return m_clrItemActiveBorder; } // Untested } public override Color ButtonPressedBorder { get { return m_clrItemActiveBorder; } } public override Color ButtonPressedGradientBegin { get { return m_clrItemActiveBack; } } public override Color ButtonPressedGradientEnd { get { return m_clrItemActiveBack; } } public override Color ButtonPressedGradientMiddle { get { return m_clrItemActiveBack; } } public override Color ButtonPressedHighlight { get { return m_clrItemActiveBack; } // Untested } public override Color ButtonPressedHighlightBorder { get { return m_clrItemActiveBorder; } // Untested } public override Color ButtonSelectedBorder { get { return m_clrItemSelBorder; } } public override Color ButtonSelectedGradientBegin { get { return m_clrItemSelBack; } } public override Color ButtonSelectedGradientEnd { get { return m_clrItemSelBack; } } public override Color ButtonSelectedGradientMiddle { get { return m_clrItemSelBack; } } public override Color ButtonSelectedHighlight { get { return m_clrItemSelBack; } // Untested } public override Color ButtonSelectedHighlightBorder { get { return m_clrItemSelBorder; } } public override Color CheckBackground { get { return Color.FromArgb(192, 221, 235); } } public override Color CheckPressedBackground { get { return Color.FromArgb(168, 210, 236); } } public override Color CheckSelectedBackground { get { return Color.FromArgb(168, 210, 236); } } public override Color GripDark { get { return Color.FromArgb(187, 188, 189); } } public override Color GripLight { get { return Color.FromArgb(252, 252, 253); } } public override Color ImageMarginGradientBegin { get { return m_clrImageBack; } } public override Color ImageMarginGradientEnd { get { return m_clrImageBack; } } public override Color ImageMarginGradientMiddle { get { return m_clrImageBack; } } public override Color ImageMarginRevealedGradientBegin { get { return m_clrImageBack; } } public override Color ImageMarginRevealedGradientEnd { get { return m_clrImageBack; } } public override Color ImageMarginRevealedGradientMiddle { get { return m_clrImageBack; } } public override Color MenuBorder { get { return Color.FromArgb(151, 151, 151); } } public override Color MenuItemBorder { get { return m_clrSubItemSelBorder; } } public override Color MenuItemSelected { get { return m_clrSubItemSelBack; } } public override Color MenuItemPressedGradientBegin { // Used by pressed root menu items and inactive drop-down // arrow buttons in toolbar comboboxes (?!) get { return m_clrItemActiveBack; } } public override Color MenuItemPressedGradientEnd { get { return m_clrItemActiveBack; } } public override Color MenuItemPressedGradientMiddle { get { return m_clrItemActiveBack; } } public override Color MenuItemSelectedGradientBegin { get { return m_clrItemSelBack; } } public override Color MenuItemSelectedGradientEnd { get { return m_clrItemSelBack; } } public override Color MenuStripGradientBegin { get { return m_clrBarBack; } } public override Color MenuStripGradientEnd { get { return m_clrBarBack; } } public override Color OverflowButtonGradientBegin { get { return Color.FromArgb(245, 245, 245); } } public override Color OverflowButtonGradientEnd { get { return Color.FromArgb(229, 229, 229); } } public override Color OverflowButtonGradientMiddle { get { return Color.FromArgb(237, 237, 237); } } public override Color RaftingContainerGradientBegin { get { return m_clrMenuBack; } // Untested } public override Color RaftingContainerGradientEnd { get { return m_clrMenuBack; } // Untested } public override Color SeparatorDark { // Menu separators are (215, 215, 215), // toolbar separators are (135, 135, 136); // SeparatorDark is used for both the menu and the toolbar get { return Color.FromArgb(175, 175, 175); } } public override Color SeparatorLight { get { return Color.FromArgb(248, 249, 249); } } public override Color StatusStripGradientBegin { get { return m_clrMenuBack; } } public override Color StatusStripGradientEnd { get { return m_clrMenuBack; } } public override Color ToolStripBorder { get { return m_clrMenuBack; } } public override Color ToolStripContentPanelGradientBegin { get { return m_clrMenuBack; } // Untested } public override Color ToolStripContentPanelGradientEnd { get { return m_clrMenuBack; } // Untested } public override Color ToolStripDropDownBackground { get { return m_clrMenuBack; } } public override Color ToolStripGradientBegin { get { return m_clrBarBack; } } public override Color ToolStripGradientEnd { get { return m_clrBarBack; } } public override Color ToolStripGradientMiddle { get { return m_clrBarBack; } } public override Color ToolStripPanelGradientBegin { get { return m_clrBarBack; } // Untested } public override Color ToolStripPanelGradientEnd { get { return m_clrBarBack; } // Untested } } public Win81Tsr() : base(new Win81TsrColorTable()) { } protected override void OnRenderMenuItemBackground(ToolStripItemRenderEventArgs e) { ToolStripItem tsi = ((e != null) ? e.Item : null); if((tsi != null) && ((tsi.Owner is ContextMenuStrip) || (tsi.OwnerItem != null)) && tsi.Selected && !tsi.Enabled) { Rectangle rect = tsi.ContentRectangle; rect.Offset(0, -1); rect.Height += 1; Color clrBack = Color.FromArgb(225, 225, 225); Color clrBorder = Color.FromArgb(174, 174, 174); SolidBrush br = new SolidBrush(clrBack); Pen p = new Pen(clrBorder); Graphics g = e.Graphics; if(g != null) { g.FillRectangle(br, rect); g.DrawRectangle(p, rect); } else { Debug.Assert(false); } p.Dispose(); br.Dispose(); } else base.OnRenderMenuItemBackground(e); } } } KeePass/UI/ToolStripRendering/ProExtTsr.cs0000664000000000000000000002037013222430414017461 0ustar rootroot/* KeePass Password Safe - The Open-Source Password Manager Copyright (C) 2003-2018 Dominik Reichl This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ using System; using System.Collections.Generic; using System.Diagnostics; using System.Drawing; using System.Text; using System.Windows.Forms; using KeePass.Resources; using KeePassLib; using KeePassLib.Native; using KeePassLib.Utility; namespace KeePass.UI.ToolStripRendering { internal sealed class ProExtTsrFactory : TsrFactory { private PwUuid m_uuid = new PwUuid(new byte[] { 0x21, 0xED, 0x54, 0x1A, 0xE2, 0xEB, 0xCB, 0x0C, 0x57, 0x18, 0x41, 0x32, 0x70, 0xD8, 0xE0, 0xE9 }); public override PwUuid Uuid { get { return m_uuid; } } public override string Name { get { return (".NET/Office - " + KPRes.Professional); } } public override ToolStripRenderer CreateInstance() { return new ProExtTsr(); } } public class ProExtTsr : ToolStripProfessionalRenderer { private bool m_bCustomColorTable = false; protected bool IsDarkStyle { get { ProfessionalColorTable ct = this.ColorTable; if(ct == null) { Debug.Assert(false); return false; } return UIUtil.IsDarkColor(ct.ToolStripDropDownBackground); } } protected virtual bool EnsureTextContrast { get { return true; } } public ProExtTsr() : base() { } public ProExtTsr(ProfessionalColorTable ct) : base(ct) { m_bCustomColorTable = true; } protected override void OnRenderButtonBackground(ToolStripItemRenderEventArgs e) { base.OnRenderButtonBackground(e); // .NET incorrectly draws the border using // this.ColorTable.ButtonSelectedBorder even when the button // is pressed; thus in this case we draw it again using the // correct color ToolStripItem tsi = ((e != null) ? e.Item : null); if((tsi != null) && tsi.Pressed && !NativeLib.IsUnix()) { using(Pen p = new Pen(this.ColorTable.ButtonPressedBorder)) { e.Graphics.DrawRectangle(p, 0, 0, tsi.Width - 1, tsi.Height - 1); } } } protected override void OnRenderItemCheck(ToolStripItemImageRenderEventArgs e) { if(MonoWorkarounds.IsRequired()) { base.OnRenderItemCheck(e); return; } Image imgToDispose = null; try { Graphics g = e.Graphics; Image imgOrg = e.Image; Rectangle rOrg = e.ImageRectangle; ToolStripItem tsi = e.Item; Image img = imgOrg; Rectangle r = rOrg; Debug.Assert(r.Width == r.Height); Debug.Assert(DpiUtil.ScalingRequired || (r.Size == ((img != null) ? img.Size : new Size(3, 5)))); // Override the .NET checkmark bitmap ToolStripMenuItem tsmi = (tsi as ToolStripMenuItem); if((tsmi != null) && tsmi.Checked && (tsmi.Image == null)) img = Properties.Resources.B16x16_MenuCheck; if(tsi != null) { Rectangle rContent = tsi.ContentRectangle; Debug.Assert(rContent.Contains(r) || DpiUtil.ScalingRequired); r.Intersect(rContent); if(r.Height < r.Width) r.Width = r.Height; } else { Debug.Assert(false); } if((img != null) && (r.Size != img.Size)) { img = GfxUtil.ScaleImage(img, r.Width, r.Height, ScaleTransformFlags.UIIcon); imgToDispose = img; } if((img != imgOrg) || (r != rOrg)) { ToolStripItemImageRenderEventArgs eNew = new ToolStripItemImageRenderEventArgs(g, tsi, img, r); base.OnRenderItemCheck(eNew); return; } /* ToolStripMenuItem tsmi = (tsi as ToolStripMenuItem); if((tsmi != null) && tsmi.Checked && (r.Width > 0) && (r.Height > 0) && (img != null) && ((img.Width != r.Width) || (img.Height != r.Height))) { Rectangle rContent = tsmi.ContentRectangle; r.Intersect(rContent); if(r.Height < r.Width) r.Width = r.Height; ProfessionalColorTable ct = this.ColorTable; Color clrBorder = ct.ButtonSelectedBorder; Color clrBG = ct.CheckBackground; if(tsmi.Selected) clrBG = ct.CheckSelectedBackground; if(tsmi.Pressed) clrBG = ct.CheckPressedBackground; Color clrFG = ((UIUtil.ColorToGrayscale(clrBG).R >= 128) ? Color.Black : Color.White); using(SolidBrush sb = new SolidBrush(clrBG)) { g.FillRectangle(sb, r); } using(Pen p = new Pen(clrBorder)) { g.DrawRectangle(p, r.X, r.Y, r.Width - 1, r.Height - 1); } ControlPaint.DrawMenuGlyph(g, r, MenuGlyph.Checkmark, clrFG, Color.Transparent); // if((img.Width == r.Width) && (img.Height == r.Height)) // g.DrawImage(img, r); // else // { // Image imgScaled = GfxUtil.ScaleImage(img, // r.Width, r.Height, ScaleTransformFlags.UIIcon); // g.DrawImage(imgScaled, r); // imgScaled.Dispose(); // } return; } */ /* if((img != null) && (r.Width > 0) && (r.Height > 0) && ((img.Width != r.Width) || (img.Height != r.Height)) && (tsi != null)) { // This should only happen on high DPI Debug.Assert(DpiUtil.ScalingRequired); Image imgScaled = GfxUtil.ScaleImage(img, r.Width, r.Height, ScaleTransformFlags.UIIcon); // Image imgScaled = new Bitmap(r.Width, r.Height, // PixelFormat.Format32bppArgb); // using(Graphics gScaled = Graphics.FromImage(imgScaled)) // { // gScaled.Clear(Color.Transparent); // Color clrFG = ((UIUtil.ColorToGrayscale( // this.ColorTable.CheckBackground).R >= 128) ? // Color.FromArgb(18, 24, 163) : Color.White); // Rectangle rGlyph = new Rectangle(0, 0, r.Width, r.Height); // // rGlyph.Inflate(-r.Width / 12, -r.Height / 12); // ControlPaint.DrawMenuGlyph(gScaled, rGlyph, // MenuGlyph.Bullet, clrFG, Color.Transparent); // } ToolStripItemImageRenderEventArgs eMod = new ToolStripItemImageRenderEventArgs(g, e.Item, imgScaled, r); base.OnRenderItemCheck(eMod); imgScaled.Dispose(); return; } */ } catch(Exception) { Debug.Assert(false); } finally { if(imgToDispose != null) imgToDispose.Dispose(); } base.OnRenderItemCheck(e); // Not in 'finally', see 'eNew' } protected override void OnRenderItemText(ToolStripItemTextRenderEventArgs e) { if(e != null) { ToolStripItem tsi = e.Item; // In high contrast mode, various colors of the default // color table are incorrect, thus check m_bCustomColorTable if((tsi != null) && this.EnsureTextContrast && m_bCustomColorTable) { bool bDarkBack = this.IsDarkStyle; if(tsi.Selected || tsi.Pressed) { if((tsi.Owner is ContextMenuStrip) || (tsi.OwnerItem != null)) bDarkBack = UIUtil.IsDarkColor(this.ColorTable.MenuItemSelected); else // Top menu item { if(tsi.Pressed) bDarkBack = UIUtil.IsDarkColor( this.ColorTable.MenuItemPressedGradientMiddle); else bDarkBack = UIUtil.IsDarkColor(UIUtil.ColorMiddle( this.ColorTable.MenuItemSelectedGradientBegin, this.ColorTable.MenuItemSelectedGradientEnd)); } } // e.TextColor might be incorrect, thus use tsi.ForeColor bool bDarkText = UIUtil.IsDarkColor(tsi.ForeColor); if(bDarkBack && bDarkText) { Debug.Assert(false); e.TextColor = Color.White; } else if(!bDarkBack && !bDarkText) { Debug.Assert(false); e.TextColor = Color.Black; } } } else { Debug.Assert(false); } base.OnRenderItemText(e); } } } KeePass/UI/ToolStripRendering/TsrPool.cs0000664000000000000000000001073613222430414017156 0ustar rootroot/* KeePass Password Safe - The Open-Source Password Manager Copyright (C) 2003-2018 Dominik Reichl This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ using System; using System.Collections.Generic; using System.Diagnostics; using System.Text; using System.Windows.Forms; using KeePass.Util; using KeePassLib; using KeePassLib.Native; namespace KeePass.UI.ToolStripRendering { public static class TsrPool { private static List g_lFacs = null; private static int g_nStdFac = 0; internal static List Factories { get { EnsureFactories(); return g_lFacs; } } private static void EnsureFactories() { if(g_lFacs != null) return; TsrFactory fKP = new KeePassTsrFactory(); TsrFactory f81 = new Win81TsrFactory(); TsrFactory f10 = new Win10TsrFactory(); TsrFactory fP = new ProExtTsrFactory(); TsrFactory fS; try { fS = new SystemTsrFactory(); } catch(Exception) { Debug.Assert(false); fS = fP; } // https://sourceforge.net/p/keepass/discussion/329220/thread/fab85f1d/ // https://keepass.info/help/kb/tsrstyles_survey.html TsrFactory[] vPref; if(WinUtil.IsAtLeastWindows10) vPref = new TsrFactory[] { f10, f81, fKP, fP, fS }; else if(WinUtil.IsAtLeastWindows8) vPref = new TsrFactory[] { f81, f10, fKP, fP, fS }; else if(NativeLib.IsUnix()) vPref = new TsrFactory[] { f81, f10, fKP, fP, fS }; else // Older Windows systems vPref = new TsrFactory[] { fKP, f10, f81, fP, fS }; List l = new List(vPref); #if DEBUG for(int i = 0; i < l.Count; ++i) { TsrFactory f1 = l[i]; if(f1 == null) { Debug.Assert(false); continue; } if(f1.Uuid == null) { Debug.Assert(false); continue; } for(int j = i + 1; j < l.Count; ++j) { TsrFactory f2 = l[j]; if(f2 == null) { Debug.Assert(false); continue; } if(f2.Uuid == null) { Debug.Assert(false); continue; } Debug.Assert(!f1.Uuid.Equals(f2.Uuid)); } } #endif g_lFacs = l; g_nStdFac = l.Count; } private static TsrFactory GetFactory(PwUuid u) { if(u == null) { Debug.Assert(false); return null; } foreach(TsrFactory f in TsrPool.Factories) { if(u.Equals(f.Uuid)) return f; } return null; } public static bool AddFactory(TsrFactory f) { if(f == null) { Debug.Assert(false); return false; } TsrFactory fEx = GetFactory(f.Uuid); if(fEx != null) return false; // Exists already TsrPool.Factories.Add(f); return true; } public static bool RemoveFactory(PwUuid u) { if(u == null) { Debug.Assert(false); return false; } List l = TsrPool.Factories; int cInitial = l.Count; for(int i = l.Count - 1; i >= g_nStdFac; --i) { if(u.Equals(l[i].Uuid)) l.RemoveAt(i); } return (l.Count != cInitial); } internal static ToolStripRenderer GetBestRenderer(string strUuid) { PwUuid u = PwUuid.Zero; try { if(!string.IsNullOrEmpty(strUuid)) u = new PwUuid(Convert.FromBase64String(strUuid)); } catch(Exception) { Debug.Assert(false); } return GetBestRenderer(u); } internal static ToolStripRenderer GetBestRenderer(PwUuid u) { TsrFactory fPref = null; if((u == null) || PwUuid.Zero.Equals(u)) { } else fPref = GetFactory(u); List lPref = new List(); if(fPref != null) lPref.Add(fPref); lPref.AddRange(TsrPool.Factories); foreach(TsrFactory fCand in lPref) { if((fCand != null) && fCand.IsSupported()) { try { ToolStripRenderer tsr = fCand.CreateInstance(); if(tsr != null) return tsr; } catch(Exception) { Debug.Assert(false); } } } return null; } } } KeePass/UI/ToolStripRendering/Win10Tsr.cs0000664000000000000000000002266413222430414017146 0ustar rootroot/* KeePass Password Safe - The Open-Source Password Manager Copyright (C) 2003-2018 Dominik Reichl This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ using System; using System.Collections.Generic; using System.Diagnostics; using System.Drawing; using System.Drawing.Drawing2D; using System.Text; using System.Windows.Forms; using KeePassLib; namespace KeePass.UI.ToolStripRendering { internal sealed class Win10TsrFactory : TsrFactory { private PwUuid m_uuid = new PwUuid(new byte[] { 0x39, 0xE5, 0x05, 0x04, 0xB6, 0x56, 0x14, 0xE7, 0x4F, 0x13, 0x68, 0x51, 0x85, 0xB3, 0x87, 0xC6 }); public override PwUuid Uuid { get { return m_uuid; } } public override string Name { get { return "Windows 10"; } // Version 1511 } public override bool IsSupported() { return !UIUtil.IsHighContrast; } public override ToolStripRenderer CreateInstance() { return new Win10Tsr(); } } internal sealed class Win10Tsr : ProExtTsr { private sealed class Win10TsrColorTable : ProfessionalColorTable { private Color m_clrItemActiveBack = Color.FromArgb(204, 232, 255); private Color m_clrItemActiveBorder = Color.FromArgb(153, 209, 255); private Color m_clrItemSelBack = Color.FromArgb(229, 243, 255); private Color m_clrItemSelBorder = Color.FromArgb(204, 232, 255); private Color m_clrBarBack = Color.FromArgb(255, 255, 255); private Color m_clrMenuBack = Color.FromArgb(242, 242, 242); private Color m_clrImageBack = Color.FromArgb(240, 240, 240); private Color m_clrSubItemSelBack = Color.FromArgb(145, 201, 247); private Color m_clrSubItemSelBorder = Color.FromArgb(145, 201, 247); public override Color ButtonCheckedGradientBegin { get { return m_clrItemActiveBack; } } public override Color ButtonCheckedGradientEnd { get { return m_clrItemActiveBack; } } public override Color ButtonCheckedGradientMiddle { get { return m_clrItemActiveBack; } } public override Color ButtonCheckedHighlight { get { return m_clrItemActiveBack; } // Untested } public override Color ButtonCheckedHighlightBorder { get { return m_clrItemActiveBorder; } // Untested } public override Color ButtonPressedBorder { get { return m_clrItemActiveBorder; } } public override Color ButtonPressedGradientBegin { get { return m_clrItemActiveBack; } } public override Color ButtonPressedGradientEnd { get { return m_clrItemActiveBack; } } public override Color ButtonPressedGradientMiddle { get { return m_clrItemActiveBack; } } public override Color ButtonPressedHighlight { get { return m_clrItemActiveBack; } // Untested } public override Color ButtonPressedHighlightBorder { get { return m_clrItemActiveBorder; } // Untested } public override Color ButtonSelectedBorder { get { return m_clrItemSelBorder; } } public override Color ButtonSelectedGradientBegin { get { return m_clrItemSelBack; } } public override Color ButtonSelectedGradientEnd { get { return m_clrItemSelBack; } } public override Color ButtonSelectedGradientMiddle { get { return m_clrItemSelBack; } } public override Color ButtonSelectedHighlight { get { return m_clrItemSelBack; } // Untested } public override Color ButtonSelectedHighlightBorder { get { return m_clrItemSelBorder; } } public override Color CheckBackground { get { return Color.FromArgb(144, 200, 246); } } public override Color CheckPressedBackground { get { return Color.FromArgb(86, 176, 250); } } public override Color CheckSelectedBackground { get { return Color.FromArgb(86, 176, 250); } } public override Color GripDark { get { return Color.FromArgb(195, 195, 195); } } public override Color GripLight { get { return Color.FromArgb(228, 228, 228); } } public override Color ImageMarginGradientBegin { get { return m_clrImageBack; } } public override Color ImageMarginGradientEnd { get { return m_clrImageBack; } } public override Color ImageMarginGradientMiddle { get { return m_clrImageBack; } } public override Color ImageMarginRevealedGradientBegin { get { return m_clrImageBack; } } public override Color ImageMarginRevealedGradientEnd { get { return m_clrImageBack; } } public override Color ImageMarginRevealedGradientMiddle { get { return m_clrImageBack; } } public override Color MenuBorder { get { return Color.FromArgb(204, 204, 204); } } public override Color MenuItemBorder { get { return m_clrSubItemSelBorder; } } public override Color MenuItemSelected { get { return m_clrSubItemSelBack; } } public override Color MenuItemPressedGradientBegin { // Used by pressed root menu items and inactive drop-down // arrow buttons in toolbar comboboxes (?!) get { return m_clrItemActiveBack; } } public override Color MenuItemPressedGradientEnd { get { return m_clrItemActiveBack; } } public override Color MenuItemPressedGradientMiddle { get { return m_clrItemActiveBack; } } public override Color MenuItemSelectedGradientBegin { get { return m_clrItemSelBack; } } public override Color MenuItemSelectedGradientEnd { get { return m_clrItemSelBack; } } public override Color MenuStripGradientBegin { get { return m_clrBarBack; } } public override Color MenuStripGradientEnd { get { return m_clrBarBack; } } public override Color OverflowButtonGradientBegin { get { return Color.FromArgb(245, 245, 245); } } public override Color OverflowButtonGradientEnd { get { return Color.FromArgb(229, 229, 229); } } public override Color OverflowButtonGradientMiddle { get { return Color.FromArgb(237, 237, 237); } } public override Color RaftingContainerGradientBegin { get { return m_clrMenuBack; } // Untested } public override Color RaftingContainerGradientEnd { get { return m_clrMenuBack; } // Untested } public override Color SeparatorDark { // Menu separators are (215, 215, 215), // toolbar separators are (140, 140, 140); // SeparatorDark is used for both the menu and the toolbar get { return Color.FromArgb(177, 177, 177); } } public override Color SeparatorLight { get { return m_clrBarBack; } } public override Color StatusStripGradientBegin { get { return m_clrMenuBack; } } public override Color StatusStripGradientEnd { get { return m_clrMenuBack; } } public override Color ToolStripBorder { get { return m_clrMenuBack; } } public override Color ToolStripContentPanelGradientBegin { get { return m_clrMenuBack; } // Untested } public override Color ToolStripContentPanelGradientEnd { get { return m_clrMenuBack; } // Untested } public override Color ToolStripDropDownBackground { get { return m_clrMenuBack; } } public override Color ToolStripGradientBegin { get { return m_clrBarBack; } } public override Color ToolStripGradientEnd { get { return m_clrBarBack; } } public override Color ToolStripGradientMiddle { get { return m_clrBarBack; } } public override Color ToolStripPanelGradientBegin { get { return m_clrBarBack; } // Untested } public override Color ToolStripPanelGradientEnd { get { return m_clrBarBack; } // Untested } } public Win10Tsr() : base(new Win10TsrColorTable()) { } protected override void OnRenderMenuItemBackground(ToolStripItemRenderEventArgs e) { ToolStripItem tsi = ((e != null) ? e.Item : null); if((tsi != null) && ((tsi.Owner is ContextMenuStrip) || (tsi.OwnerItem != null)) && tsi.Selected && !tsi.Enabled) { Rectangle rect = tsi.ContentRectangle; rect.Offset(0, -1); rect.Height += 1; // In image area (228, 228, 228), in text area (230, 230, 230) Color clrBack = Color.FromArgb(229, 229, 229); Color clrBorder = Color.FromArgb(229, 229, 229); SolidBrush br = new SolidBrush(clrBack); Pen p = new Pen(clrBorder); Graphics g = e.Graphics; if(g != null) { g.FillRectangle(br, rect); g.DrawRectangle(p, rect); } else { Debug.Assert(false); } p.Dispose(); br.Dispose(); } else base.OnRenderMenuItemBackground(e); } } } KeePass/UI/HotKeyControlEx.cs0000664000000000000000000002023513222430414015013 0ustar rootroot/* KeePass Password Safe - The Open-Source Password Manager Copyright (C) 2003-2018 Dominik Reichl This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ // This control is based on the following article: // https://www.codeproject.com/useritems/hotkeycontrol.asp using System; using System.Collections.Generic; using System.Text; using System.Windows.Forms; using System.ComponentModel; using System.Diagnostics; using KeePass.Resources; namespace KeePass.UI { public sealed class HotKeyControlEx : TextBox { private Keys m_kHotKey = Keys.None; private Keys m_kModifiers = Keys.None; private static List m_vNeedNonShiftModifier = new List(); private static List m_vNeedNonAltGrModifier = new List(); private ContextMenu m_ctxNone = new ContextMenu(); [Browsable(false)] [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] public Keys HotKey { get { return m_kHotKey; } set { m_kHotKey = value; } } [Browsable(false)] [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] public Keys HotKeyModifiers { get { return m_kModifiers; } set { m_kModifiers = value; } } private bool m_bNoRightModKeys = false; [DefaultValue(false)] public bool NoRightModKeys { get { return m_bNoRightModKeys; } set { m_bNoRightModKeys = value; } } private string m_strTextNone = KPRes.None; [Browsable(false)] [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] public string TextNone { get { return m_strTextNone; } set { if(value == null) throw new ArgumentNullException("value"); m_strTextNone = value; } } [Browsable(false)] [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] public override ContextMenu ContextMenu { get { return m_ctxNone; } set { base.ContextMenu = m_ctxNone; } } // Hot key control is single-line [Browsable(false)] [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] public override bool Multiline { get { return base.Multiline; } set { base.Multiline = false; } } public HotKeyControlEx() { this.ContextMenu = m_ctxNone; // No context menu available this.Text = m_strTextNone; this.KeyPress += new KeyPressEventHandler(this.OnKeyPressEx); this.KeyUp += new KeyEventHandler(this.OnKeyUpEx); this.KeyDown += new KeyEventHandler(this.OnKeyDownEx); if(m_vNeedNonShiftModifier.Count == 0) PopulateModifierLists(); } private static void PopulateModifierLists() { for(Keys k = Keys.D0; k <= Keys.Z; ++k) m_vNeedNonShiftModifier.Add(k); for(Keys k = Keys.NumPad0; k <= Keys.NumPad9; ++k) m_vNeedNonShiftModifier.Add(k); for(Keys k = Keys.Oem1; k <= Keys.OemBackslash; ++k) m_vNeedNonShiftModifier.Add(k); for(Keys k = Keys.Space; k <= Keys.Home; ++k) m_vNeedNonShiftModifier.Add(k); m_vNeedNonShiftModifier.Add(Keys.Insert); m_vNeedNonShiftModifier.Add(Keys.Help); m_vNeedNonShiftModifier.Add(Keys.Multiply); m_vNeedNonShiftModifier.Add(Keys.Add); m_vNeedNonShiftModifier.Add(Keys.Subtract); m_vNeedNonShiftModifier.Add(Keys.Divide); m_vNeedNonShiftModifier.Add(Keys.Decimal); m_vNeedNonShiftModifier.Add(Keys.Return); m_vNeedNonShiftModifier.Add(Keys.Escape); m_vNeedNonShiftModifier.Add(Keys.NumLock); m_vNeedNonShiftModifier.Add(Keys.Scroll); m_vNeedNonShiftModifier.Add(Keys.Pause); for(Keys k = Keys.D0; k <= Keys.D9; ++k) m_vNeedNonAltGrModifier.Add(k); } public new void Clear() { m_kHotKey = Keys.None; m_kModifiers = Keys.None; } private void OnKeyDownEx(object sender, KeyEventArgs e) { if((e.KeyCode == Keys.Back) || (e.KeyCode == Keys.Delete)) ResetHotKey(); else { m_kHotKey = e.KeyCode; m_kModifiers = e.Modifiers; RenderHotKey(); } } private void OnKeyUpEx(object sender, KeyEventArgs e) { if((m_kHotKey == Keys.None) && (Control.ModifierKeys == Keys.None)) ResetHotKey(); } private void OnKeyPressEx(object sender, KeyPressEventArgs e) { e.Handled = true; } protected override bool ProcessCmdKey(ref Message msg, Keys keyData) { if((keyData == Keys.Delete) || (keyData == (Keys.Control | Keys.Delete))) { ResetHotKey(); return true; } if(keyData == (Keys.Shift | Keys.Insert)) // Paste command return true; // Not allowed if((keyData & Keys.KeyCode) == Keys.F12) return true; // Reserved for debugger, see MSDN return base.ProcessCmdKey(ref msg, keyData); } private void ResetHotKey() { m_kHotKey = Keys.None; m_kModifiers = Keys.None; RenderHotKey(); } public void ResetIfModifierOnly() { if((m_kHotKey == Keys.None) && (m_kModifiers != Keys.None)) ResetHotKey(); } public void RenderHotKey() { if(m_kHotKey == Keys.None) { this.Text = m_strTextNone; return; } if((m_kHotKey == Keys.LWin) || (m_kHotKey == Keys.RWin)) { ResetHotKey(); return; } if(((m_kModifiers == Keys.Shift) || (m_kModifiers == Keys.None)) && m_vNeedNonShiftModifier.Contains(m_kHotKey)) { if(m_kModifiers == Keys.None) { if(m_vNeedNonAltGrModifier.Contains(m_kHotKey) == false) m_kModifiers = (Keys.Alt | Keys.Control); else m_kModifiers = (Keys.Alt | Keys.Shift); } else { m_kHotKey = Keys.None; this.Text = ModifiersToString(m_kModifiers) + " + " + KPRes.InvalidKey; return; } } if((m_kModifiers == (Keys.Alt | Keys.Control)) && m_vNeedNonAltGrModifier.Contains(m_kHotKey)) { m_kHotKey = Keys.None; this.Text = ModifiersToString(m_kModifiers) + " + " + KPRes.InvalidKey; return; } if(m_kModifiers == Keys.None) { if(m_kHotKey == Keys.None) { this.Text = m_strTextNone; return; } else { this.Text = m_kHotKey.ToString(); return; } } if((m_kHotKey == Keys.Menu) || (m_kHotKey == Keys.ShiftKey) || (m_kHotKey == Keys.ControlKey)) { m_kHotKey = Keys.None; } this.Text = ModifiersToString(m_kModifiers) + " + " + m_kHotKey.ToString(); } private string ModifiersToString(Keys kModifiers) { string str = string.Empty; if((kModifiers & Keys.Shift) != Keys.None) str = (m_bNoRightModKeys ? KPRes.KeyboardKeyShiftLeft : KPRes.KeyboardKeyShift); if((kModifiers & Keys.Control) != Keys.None) { if(str.Length > 0) str += ", "; str += (m_bNoRightModKeys ? KPRes.KeyboardKeyCtrlLeft : KPRes.KeyboardKeyCtrl); } if((kModifiers & Keys.Alt) != Keys.None) { if(str.Length > 0) str += ", "; str += KPRes.KeyboardKeyAlt; } return str; } [Obsolete] public static HotKeyControlEx ReplaceTextBox(Control cContainer, TextBox tb) { return ReplaceTextBox(cContainer, tb, false); } public static HotKeyControlEx ReplaceTextBox(Control cContainer, TextBox tb, bool bNoRightModKeys) { Debug.Assert(tb != null); if(tb == null) throw new ArgumentNullException("tb"); tb.Enabled = false; tb.Visible = false; cContainer.Controls.Remove(tb); HotKeyControlEx hk = new HotKeyControlEx(); hk.Location = tb.Location; hk.Size = tb.Size; hk.NoRightModKeys = bNoRightModKeys; cContainer.Controls.Add(hk); cContainer.PerformLayout(); return hk; } } } KeePass/UI/CustomTreeViewEx.cs0000664000000000000000000001446213222430414015201 0ustar rootroot/* KeePass Password Safe - The Open-Source Password Manager Copyright (C) 2003-2018 Dominik Reichl This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ using System; using System.Collections.Generic; using System.Text; using System.Windows.Forms; using System.Diagnostics; using KeePass.Native; using KeePass.Util; using NativeLib = KeePassLib.Native.NativeLib; namespace KeePass.UI { // public delegate string QueryToolTipDelegate(TreeNode tn); public sealed class CustomTreeViewEx : TreeView { // private TreeNode m_tnReadyForLabelEdit = null; // private QueryToolTipDelegate m_fnQueryToolTip = null; // /// // /// This handler will be used to dynamically query tooltip // /// texts for tree nodes. // /// // public QueryToolTipDelegate QueryToolTip // { // get { return m_fnQueryToolTip; } // set { m_fnQueryToolTip = value; } // } public CustomTreeViewEx() : base() { // Enable default double buffering (must be combined with // TVS_EX_DOUBLEBUFFER, see OnHandleCreated) try { this.DoubleBuffered = true; } catch(Exception) { Debug.Assert(!WinUtil.IsAtLeastWindowsVista); } // try // { // IntPtr hWnd = this.Handle; // if((hWnd != IntPtr.Zero) && (this.ItemHeight == 16)) // { // int nStyle = NativeMethods.GetWindowStyle(hWnd); // nStyle |= (int)NativeMethods.TVS_NONEVENHEIGHT; // NativeMethods.SetWindowLong(hWnd, NativeMethods.GWL_STYLE, nStyle); // this.ItemHeight = 17; // } // } // catch(Exception) { } // this.ItemHeight = 18; // try // { // IntPtr hWnd = this.Handle; // if((hWnd != IntPtr.Zero) && UIUtil.VistaStyleListsSupported) // { // int nStyle = NativeMethods.GetWindowStyle(hWnd); // nStyle |= (int)NativeMethods.TVS_FULLROWSELECT; // NativeMethods.SetWindowLong(hWnd, NativeMethods.GWL_STYLE, nStyle); // nStyle = NativeMethods.GetWindowLong(hWnd, NativeMethods.GWL_EXSTYLE); // nStyle |= (int)NativeMethods.TVS_EX_FADEINOUTEXPANDOS; // NativeMethods.SetWindowLong(hWnd, NativeMethods.GWL_EXSTYLE, nStyle); // } // } // catch(Exception) { } } // protected override void WndProc(ref Message m) // { // if(m.Msg == NativeMethods.WM_NOTIFY) // { // NativeMethods.NMHDR nm = (NativeMethods.NMHDR)m.GetLParam( // typeof(NativeMethods.NMHDR)); // if((nm.code == NativeMethods.TTN_NEEDTEXTA) || // (nm.code == NativeMethods.TTN_NEEDTEXTW)) // DynamicAssignNodeToolTip(); // } // base.WndProc(ref m); // } // private void DynamicAssignNodeToolTip() // { // if(m_fnQueryToolTip == null) return; // TreeViewHitTestInfo hti = HitTest(PointToClient(Cursor.Position)); // if(hti == null) { Debug.Assert(false); return; } // TreeNode tn = hti.Node; // if(tn == null) return; // tn.ToolTipText = (m_fnQueryToolTip(tn) ?? string.Empty); // } /* protected override void OnAfterSelect(TreeViewEventArgs e) { base.OnAfterSelect(e); if(!this.Focused) m_tnReadyForLabelEdit = null; else m_tnReadyForLabelEdit = this.SelectedNode; } protected override void OnLeave(EventArgs e) { m_tnReadyForLabelEdit = null; base.OnLeave(e); } protected override void OnBeforeLabelEdit(NodeLabelEditEventArgs e) { if(e != null) { if((m_tnReadyForLabelEdit == null) || (e.Node != m_tnReadyForLabelEdit)) { e.CancelEdit = true; return; } } else { Debug.Assert(false); } base.OnBeforeLabelEdit(e); // Call BeforeLabelEdit event } */ protected override void OnHandleCreated(EventArgs e) { base.OnHandleCreated(e); try { if(this.DoubleBuffered && !NativeLib.IsUnix()) { IntPtr p = new IntPtr((int)NativeMethods.TVS_EX_DOUBLEBUFFER); NativeMethods.SendMessage(this.Handle, NativeMethods.TVM_SETEXTENDEDSTYLE, p, p); } else { Debug.Assert(!WinUtil.IsAtLeastWindowsVista); } } catch(Exception) { Debug.Assert(false); } // Display tooltips for a longer time; // https://sourceforge.net/p/keepass/feature-requests/2038/ try { if(this.ShowNodeToolTips && !NativeLib.IsUnix()) { IntPtr hTip = NativeMethods.SendMessage(this.Handle, NativeMethods.TVM_GETTOOLTIPS, IntPtr.Zero, IntPtr.Zero); if(hTip != IntPtr.Zero) { // Apparently the maximum value is 2^15 - 1 = 32767 // (signed short maximum); any larger values result // in truncated values or are ignored IntPtr pTime = new IntPtr((int)short.MaxValue - 3); NativeMethods.SendMessage(hTip, NativeMethods.TTM_SETDELAYTIME, new IntPtr(NativeMethods.TTDT_AUTOPOP), pTime); Debug.Assert(NativeMethods.SendMessage(hTip, NativeMethods.TTM_GETDELAYTIME, new IntPtr( NativeMethods.TTDT_AUTOPOP), IntPtr.Zero) == pTime); } else { Debug.Assert(false); } } } catch(Exception) { Debug.Assert(false); } } /* protected override CreateParams CreateParams { get { CreateParams cp = base.CreateParams; cp.ExStyle |= NativeMethods.WS_EX_COMPOSITED; return cp; } } */ /* protected override void WndProc(ref Message m) { if(m.Msg == NativeMethods.WM_ERASEBKGND) { m.Result = IntPtr.Zero; return; } base.WndProc(ref m); } */ protected override void OnKeyDown(KeyEventArgs e) { if(UIUtil.HandleCommonKeyEvent(e, true, this)) return; base.OnKeyDown(e); } protected override void OnKeyUp(KeyEventArgs e) { if(UIUtil.HandleCommonKeyEvent(e, false, this)) return; base.OnKeyUp(e); } } } KeePass/DataExchange/0000775000000000000000000000000013222430406013421 5ustar rootrootKeePass/DataExchange/PwExportInfo.cs0000664000000000000000000000476113222430406016364 0ustar rootroot/* KeePass Password Safe - The Open-Source Password Manager Copyright (C) 2003-2018 Dominik Reichl This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ using System; using System.Collections.Generic; using System.Text; using KeePassLib; namespace KeePass.DataExchange { public sealed class PwExportInfo { private PwGroup m_pg; /// /// This group contains all entries and subgroups that should /// be exported. Is never null. /// public PwGroup DataGroup { get { return m_pg; } } private PwDatabase m_pd; /// /// Optional context database reference. May be null. /// public PwDatabase ContextDatabase { get { return m_pd; } } private bool m_bExpDel = true; /// /// Indicates whether deleted objects should be exported, if /// the data format supports it. /// public bool ExportDeletedObjects { get { return m_bExpDel; } } private Dictionary m_dictParams = new Dictionary(); public Dictionary Parameters { get { return m_dictParams; } } public PwExportInfo(PwGroup pgDataSource, PwDatabase pwContextInfo) { ConstructEx(pgDataSource, pwContextInfo, null); } public PwExportInfo(PwGroup pgDataSource, PwDatabase pwContextInfo, bool bExportDeleted) { ConstructEx(pgDataSource, pwContextInfo, bExportDeleted); } private void ConstructEx(PwGroup pgDataSource, PwDatabase pwContextInfo, bool? bExportDeleted) { if(pgDataSource == null) throw new ArgumentNullException("pgDataSource"); // pwContextInfo may be null m_pg = pgDataSource; m_pd = pwContextInfo; if(bExportDeleted.HasValue) m_bExpDel = bExportDeleted.Value; } } } KeePass/DataExchange/CsvStreamReaderEx.cs0000664000000000000000000001225613222430404017303 0ustar rootroot/* KeePass Password Safe - The Open-Source Password Manager Copyright (C) 2003-2018 Dominik Reichl This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ using System; using System.Collections.Generic; using System.Text; using System.IO; using System.Diagnostics; using KeePassLib.Utility; namespace KeePass.DataExchange { public sealed class CsvOptions { private char m_chFieldSep = ','; public char FieldSeparator { get { return m_chFieldSep; } set { m_chFieldSep = value; } } private char m_chRecSep = '\n'; public char RecordSeparator { get { return m_chRecSep; } set { m_chRecSep = value; } } private char m_chTextQual = '\"'; public char TextQualifier { get { return m_chTextQual; } set { m_chTextQual = value; } } private bool m_bBackEscape = true; public bool BackslashIsEscape { get { return m_bBackEscape; } set { m_bBackEscape = value; } } private bool m_bTrimFields = true; public bool TrimFields { get { return m_bTrimFields; } set { m_bTrimFields = value; } } private string m_strNewLineSeq = "\r\n"; public string NewLineSequence { get { return m_strNewLineSeq; } set { if(value == null) throw new ArgumentNullException("value"); m_strNewLineSeq = value; } } } public sealed class CsvStreamReaderEx { private CharStream m_sChars; private CsvOptions m_opt; public CsvStreamReaderEx(string strData) { Init(strData, null); } public CsvStreamReaderEx(string strData, CsvOptions opt) { Init(strData, opt); } private void Init(string strData, CsvOptions opt) { if(strData == null) throw new ArgumentNullException("strData"); m_opt = (opt ?? new CsvOptions()); string strInput = strData; // Normalize to Unix "\n" right now; the new lines are // converted back in the AddField method strInput = StrUtil.NormalizeNewLines(strInput, false); strInput = strInput.Trim(new char[] { (char)0 }); m_sChars = new CharStream(strInput); } public string[] ReadLine() { char chFirst = m_sChars.PeekChar(); if(chFirst == char.MinValue) return null; List v = new List(); StringBuilder sb = new StringBuilder(); bool bInText = false; char chFS = m_opt.FieldSeparator, chRS = m_opt.RecordSeparator; char chTQ = m_opt.TextQualifier; while(true) { char ch = m_sChars.ReadChar(); if(ch == char.MinValue) break; Debug.Assert(ch != '\r'); // Was normalized to Unix "\n" if((ch == '\\') && m_opt.BackslashIsEscape) { char chEsc = m_sChars.ReadChar(); if(chEsc == char.MinValue) break; if(chEsc == 'n') sb.Append('\n'); else if(chEsc == 'r') sb.Append('\r'); else if(chEsc == 't') sb.Append('\t'); else if(chEsc == 'u') { char chNum1 = m_sChars.ReadChar(); char chNum2 = m_sChars.ReadChar(); char chNum3 = m_sChars.ReadChar(); char chNum4 = m_sChars.ReadChar(); if(chNum4 != char.MinValue) // Implies the others { StringBuilder sbNum = new StringBuilder(); sbNum.Append(chNum3); // Little-endian sbNum.Append(chNum4); sbNum.Append(chNum1); sbNum.Append(chNum2); byte[] pbNum = MemUtil.HexStringToByteArray(sbNum.ToString()); ushort usNum = MemUtil.BytesToUInt16(pbNum); sb.Append((char)usNum); } } else sb.Append(chEsc); } else if(ch == chTQ) { if(!bInText) bInText = true; else // bInText { char chNext = m_sChars.PeekChar(); if(chNext == chTQ) { m_sChars.ReadChar(); sb.Append(chTQ); } else bInText = false; } } else if((ch == chRS) && !bInText) break; else if(bInText) sb.Append(ch); else if(ch == chFS) { AddField(v, sb.ToString()); if(sb.Length > 0) sb.Remove(0, sb.Length); } else sb.Append(ch); } // Debug.Assert(!bInText); AddField(v, sb.ToString()); return v.ToArray(); } private void AddField(List v, string strField) { // Escape characters might have been used to insert // new lines that might not conform to Unix "\n" strField = StrUtil.NormalizeNewLines(strField, false); // Transform to final form of new lines strField = strField.Replace("\n", m_opt.NewLineSequence); if(m_opt.TrimFields) strField = strField.Trim(); v.Add(strField); } } } KeePass/DataExchange/GxiImporter.cs0000664000000000000000000002731613222430406016232 0ustar rootroot/* KeePass Password Safe - The Open-Source Password Manager Copyright (C) 2003-2018 Dominik Reichl This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ using System; using System.Collections.Generic; using System.Text; using System.Xml; using System.Xml.XPath; using System.IO; using System.Diagnostics; using KeePass.Resources; using KeePass.Util; using KeePassLib; using KeePassLib.Interfaces; using KeePassLib.Security; using KeePassLib.Utility; namespace KeePass.DataExchange { public static class GxiImporter { private sealed class GxiContext // Immutable { private PwDatabase m_pd; public PwDatabase Database { get { return m_pd; } } private PwGroup m_pg; public PwGroup Group { get { return m_pg; } } private PwEntry m_pe; public PwEntry Entry { get { return m_pe; } } private Dictionary m_dStringKeyRepl; public Dictionary StringKeyRepl { get { return m_dStringKeyRepl; } } private Dictionary m_dStringValueRepl; public Dictionary StringValueRepl { get { return m_dStringValueRepl; } } private Dictionary m_dStringKeyRepl2; public Dictionary StringKeyRepl2 { get { return m_dStringKeyRepl2; } } private Dictionary m_dStringValueRepl2; public Dictionary StringValueRepl2 { get { return m_dStringValueRepl2; } } private Dictionary m_dBinaryKeyRepl; public Dictionary BinaryKeyRepl { get { return m_dBinaryKeyRepl; } } public GxiContext(GxiProfile p, PwDatabase pd, PwGroup pg, PwEntry pe) { m_pd = pd; m_pg = pg; m_pe = pe; m_dStringKeyRepl = GxiImporter.ParseRepl(p.StringKeyRepl); m_dStringValueRepl = GxiImporter.ParseRepl(p.StringValueRepl); m_dStringKeyRepl2 = GxiImporter.ParseRepl(p.StringKeyRepl2); m_dStringValueRepl2 = GxiImporter.ParseRepl(p.StringValueRepl2); m_dBinaryKeyRepl = GxiImporter.ParseRepl(p.BinaryKeyRepl); } public GxiContext ModifyWith(PwGroup pg) { GxiContext c = (GxiContext)MemberwiseClone(); Debug.Assert(object.ReferenceEquals(c.m_dStringKeyRepl, m_dStringKeyRepl)); c.m_pg = pg; return c; } public GxiContext ModifyWith(PwEntry pe) { GxiContext c = (GxiContext)MemberwiseClone(); Debug.Assert(object.ReferenceEquals(c.m_dStringKeyRepl, m_dStringKeyRepl)); c.m_pe = pe; return c; } } private delegate void ImportObjectDelegate(XPathNavigator xpRoot, GxiProfile p, GxiContext c); public static void Import(PwGroup pgStorage, Stream s, GxiProfile p, PwDatabase pdContext, IStatusLogger sl) { if(pgStorage == null) throw new ArgumentNullException("pgStorage"); if(s == null) throw new ArgumentNullException("s"); if(p == null) throw new ArgumentNullException("p"); if(pdContext == null) throw new ArgumentNullException("pdContext"); // sl may be null // Import into virtual group first, in order to realize // an all-or-nothing import PwGroup pgVirt = new PwGroup(true, true); try { ImportPriv(pgVirt, s, p, pdContext, sl); } finally { s.Close(); } foreach(PwGroup pg in pgVirt.Groups) pgStorage.AddGroup(pg, true); foreach(PwEntry pe in pgVirt.Entries) pgStorage.AddEntry(pe, true); } private static void ImportPriv(PwGroup pgStorage, Stream s, GxiProfile p, PwDatabase pdContext, IStatusLogger sl) { StrEncodingInfo sei = StrUtil.GetEncoding(p.Encoding); StreamReader srRaw; if((sei != null) && (sei.Encoding != null)) srRaw = new StreamReader(s, sei.Encoding, true); else srRaw = new StreamReader(s, true); string strDoc = srRaw.ReadToEnd(); srRaw.Close(); strDoc = Preprocess(strDoc, p); StringReader srDoc = new StringReader(strDoc); XPathDocument xd = new XPathDocument(srDoc); GxiContext c = new GxiContext(p, pdContext, pgStorage, null); XPathNavigator xpDoc = xd.CreateNavigator(); ImportObject(xpDoc, p, p.RootXPath, "/*", GxiImporter.ImportRoot, c); srDoc.Close(); } private static string Preprocess(string strDoc, GxiProfile p) { string str = strDoc; if(str == null) { Debug.Assert(false); return string.Empty; } if(p.RemoveInvalidChars) str = StrUtil.SafeXmlString(str); if(p.DecodeHtmlEntities) str = XmlUtil.DecodeHtmlEntities(str); return str; } private static XPathNodeIterator QueryNodes(XPathNavigator xpBase, string strXPath, string strAltXPath) { if(xpBase == null) { Debug.Assert(false); return null; } string strX = (string.IsNullOrEmpty(strXPath) ? strAltXPath : strXPath); if(string.IsNullOrEmpty(strX)) return null; return xpBase.Select(strX); } private static string QueryValue(XPathNavigator xpBase, string strXPath, bool bQueryName) { if(xpBase == null) { Debug.Assert(false); return null; } if(string.IsNullOrEmpty(strXPath)) return null; XPathNavigator xp = xpBase.SelectSingleNode(strXPath); if(xp == null) return null; return (bQueryName ? xp.Name : xp.Value); } private static string QueryValueSafe(XPathNavigator xpBase, string strXPath) { return (QueryValue(xpBase, strXPath, false) ?? string.Empty); } // private static string QueryValueSafe(XPathNavigator xpBase, string strXPath, // bool bQueryName) // { // return (QueryValue(xpBase, strXPath, bQueryName) ?? string.Empty); // } private static void ImportObject(XPathNavigator xpBase, GxiProfile p, string strXPath, string strAltXPath, ImportObjectDelegate f, GxiContext c) { if(f == null) { Debug.Assert(false); return; } XPathNodeIterator xi = QueryNodes(xpBase, strXPath, strAltXPath); if(xi == null) return; // No assert foreach(XPathNavigator xp in xi) { f(xp, p, c); } } private static void ImportRoot(XPathNavigator xpBase, GxiProfile p, GxiContext c) { ImportObject(xpBase, p, p.GroupXPath, null, GxiImporter.ImportGroup, c); if(p.EntriesInRoot) ImportObject(xpBase, p, p.EntryXPath, null, GxiImporter.ImportEntry, c); } private static void ImportGroup(XPathNavigator xpBase, GxiProfile p, GxiContext c) { PwGroup pg = new PwGroup(true, true); c.Group.AddGroup(pg, true); GxiContext cSub = c.ModifyWith(pg); pg.Name = QueryValueSafe(xpBase, p.GroupNameXPath); if(pg.Name.Length == 0) pg.Name = KPRes.Group; if(p.GroupsInGroup) ImportObject(xpBase, p, p.GroupXPath, null, GxiImporter.ImportGroup, cSub); if(p.EntriesInGroup) ImportObject(xpBase, p, p.EntryXPath, null, GxiImporter.ImportEntry, cSub); } private static void ImportEntry(XPathNavigator xpBase, GxiProfile p, GxiContext c) { PwEntry pe = new PwEntry(true, true); PwGroup pg = c.Group; // Not the database root group string strGroupPath = QueryValueSafe(xpBase, p.EntryGroupXPath); string strGroupPath2 = QueryValueSafe(xpBase, p.EntryGroupXPath2); if((strGroupPath.Length > 0) && (strGroupPath2.Length > 0)) { Debug.Assert(p.EntryGroupSep.Length > 0); strGroupPath = strGroupPath + p.EntryGroupSep + strGroupPath2; } if(strGroupPath.Length > 0) { if(p.EntryGroupSep.Length == 0) pg = pg.FindCreateGroup(strGroupPath, true); else pg = pg.FindCreateSubTree(strGroupPath, new string[1]{ p.EntryGroupSep }, true); } pg.AddEntry(pe, true); GxiContext cSub = c.ModifyWith(pe); ImportObject(xpBase, p, p.StringKvpXPath, null, GxiImporter.ImportStringKvp, cSub); ImportObject(xpBase, p, p.StringKvpXPath2, null, GxiImporter.ImportStringKvp2, cSub); ImportObject(xpBase, p, p.BinaryKvpXPath, null, GxiImporter.ImportBinaryKvp, cSub); } private static void ImportStringKvp(XPathNavigator xpBase, GxiProfile p, GxiContext c) { ImportStringKvpEx(xpBase, p, c, true); } private static void ImportStringKvp2(XPathNavigator xpBase, GxiProfile p, GxiContext c) { ImportStringKvpEx(xpBase, p, c, false); } private static void ImportStringKvpEx(XPathNavigator xpBase, GxiProfile p, GxiContext c, bool bFirst) { string strKey = QueryValue(xpBase, (bFirst ? p.StringKeyXPath : p.StringKeyXPath2), (bFirst ? p.StringKeyUseName : p.StringKeyUseName2)); if(string.IsNullOrEmpty(strKey)) return; strKey = ApplyRepl(strKey, (bFirst ? c.StringKeyRepl : c.StringKeyRepl2)); if(strKey.Length == 0) return; if(p.StringKeyToStd) { string strMapped = ImportUtil.MapNameToStandardField(strKey, p.StringKeyToStdFuzzy); if(!string.IsNullOrEmpty(strMapped)) strKey = strMapped; } string strValue = QueryValueSafe(xpBase, (bFirst ? p.StringValueXPath : p.StringValueXPath2)); strValue = ApplyRepl(strValue, (bFirst ? c.StringValueRepl : c.StringValueRepl2)); ImportUtil.AppendToField(c.Entry, strKey, strValue, c.Database); } private static void ImportBinaryKvp(XPathNavigator xpBase, GxiProfile p, GxiContext c) { string strKey = QueryValue(xpBase, p.BinaryKeyXPath, p.BinaryKeyUseName); if(string.IsNullOrEmpty(strKey)) return; strKey = ApplyRepl(strKey, c.BinaryKeyRepl); if(strKey.Length == 0) return; string strValue = QueryValueSafe(xpBase, p.BinaryValueXPath); byte[] pbValue = null; if(p.BinaryValueEncoding == GxiBinaryEncoding.Base64) pbValue = Convert.FromBase64String(strValue); else if(p.BinaryValueEncoding == GxiBinaryEncoding.Hex) pbValue = MemUtil.HexStringToByteArray(strValue); else { Debug.Assert(false); } if(pbValue == null) return; c.Entry.Binaries.Set(strKey, new ProtectedBinary(false, pbValue)); } internal static Dictionary ParseRepl(string str) { Dictionary d = new Dictionary(); if(str == null) { Debug.Assert(false); return d; } CharStream cs = new CharStream(str + ",,"); StringBuilder sb = new StringBuilder(); string strKey = string.Empty; bool bValue = false; while(true) { char ch = cs.ReadChar(); if(ch == char.MinValue) break; if(ch == ',') { if(!bValue) { strKey = sb.ToString(); sb.Remove(0, sb.Length); } if(strKey.Length > 0) d[strKey] = sb.ToString(); sb.Remove(0, sb.Length); bValue = false; } else if(ch == '>') { strKey = sb.ToString(); sb.Remove(0, sb.Length); bValue = true; } else if(ch == '\\') { char chSub = cs.ReadChar(); if(chSub == 'n') sb.Append('\n'); else if(chSub == 'r') sb.Append('\r'); else if(chSub == 't') sb.Append('\t'); else sb.Append(chSub); } else sb.Append(ch); } return d; } private static string ApplyRepl(string str, Dictionary dRepl) { if(str == null) { Debug.Assert(false); return string.Empty; } if(dRepl == null) { Debug.Assert(false); return str; } string strOut; if(dRepl.TryGetValue(str, out strOut)) return strOut; return str; } } } KeePass/DataExchange/KdbFile.cs0000664000000000000000000006200513222430406015253 0ustar rootroot/* KeePass Password Safe - The Open-Source Password Manager Copyright (C) 2003-2018 Dominik Reichl This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ using System; using System.Collections.Generic; using System.Diagnostics; using System.Globalization; using System.Runtime.InteropServices; using System.Text; using KeePass.Resources; using KeePassLib; using KeePassLib.Collections; using KeePassLib.Cryptography.KeyDerivation; using KeePassLib.Delegates; using KeePassLib.Interfaces; using KeePassLib.Keys; using KeePassLib.Resources; using KeePassLib.Security; using KeePassLib.Utility; namespace KeePass.DataExchange { /// /// Serialization to KeePass KDB files. /// public sealed class KdbFile { private PwDatabase m_pwDatabase; private IStatusLogger m_slLogger; private const string KdbPrefix = "KDB: "; private const string AutoTypePrefix = "Auto-Type"; private const string AutoTypeWindowPrefix = "Auto-Type-Window"; private const string UrlOverridePrefix = "Url-Override:"; public static bool IsLibraryInstalled() { Exception ex; return IsLibraryInstalled(out ex); } public static bool IsLibraryInstalled(out Exception ex) { try { KdbManager mgr = new KdbManager(); mgr.Dispose(); } catch(Exception exMgr) { ex = exMgr; return false; } ex = null; return true; } /// /// Default constructor. /// /// The PwDatabase instance that the class /// will load file data into or use to create a KDB file. Must not be null. /// Thrown if the database /// reference is null. public KdbFile(PwDatabase pwDataStore, IStatusLogger slLogger) { Debug.Assert(pwDataStore != null); if(pwDataStore == null) throw new ArgumentNullException("pwDataStore"); m_pwDatabase = pwDataStore; m_slLogger = slLogger; } private static KdbErrorCode SetDatabaseKey(KdbManager mgr, CompositeKey pwKey) { KdbErrorCode e; bool bPassword = pwKey.ContainsType(typeof(KcpPassword)); bool bKeyFile = pwKey.ContainsType(typeof(KcpKeyFile)); string strPassword = (bPassword ? (pwKey.GetUserKey( typeof(KcpPassword)) as KcpPassword).Password.ReadString() : string.Empty); string strKeyFile = (bKeyFile ? (pwKey.GetUserKey( typeof(KcpKeyFile)) as KcpKeyFile).Path : string.Empty); if(bPassword && bKeyFile) e = mgr.SetMasterKey(strKeyFile, true, strPassword, IntPtr.Zero, false); else if(bPassword && !bKeyFile) e = mgr.SetMasterKey(strPassword, false, null, IntPtr.Zero, false); else if(!bPassword && bKeyFile) e = mgr.SetMasterKey(strKeyFile, true, null, IntPtr.Zero, false); else if(pwKey.ContainsType(typeof(KcpUserAccount))) throw new Exception(KPRes.KdbWUA); else throw new Exception(KLRes.InvalidCompositeKey); return e; } /// /// Loads a KDB file and stores all loaded entries in the current /// PwDatabase instance. /// /// Relative or absolute path to the file to open. public void Load(string strFilePath) { Debug.Assert(strFilePath != null); if(strFilePath == null) throw new ArgumentNullException("strFilePath"); using(KdbManager mgr = new KdbManager()) { KdbErrorCode e; e = KdbFile.SetDatabaseKey(mgr, m_pwDatabase.MasterKey); if(e != KdbErrorCode.Success) throw new Exception(KLRes.InvalidCompositeKey); e = mgr.OpenDatabase(strFilePath, IntPtr.Zero); if(e != KdbErrorCode.Success) throw new Exception(KLRes.FileLoadFailed); // Copy properties m_pwDatabase.KdfParameters = (new AesKdf()).GetDefaultParameters(); m_pwDatabase.KdfParameters.SetUInt64(AesKdf.ParamRounds, mgr.KeyTransformationRounds); // Read groups and entries Dictionary dictGroups = ReadGroups(mgr); ReadEntries(mgr, dictGroups); } } private Dictionary ReadGroups(KdbManager mgr) { uint uGroupCount = mgr.GroupCount; Dictionary dictGroups = new Dictionary(); Stack vGroupStack = new Stack(); vGroupStack.Push(m_pwDatabase.RootGroup); DateTime dtNeverExpire = KdbManager.GetNeverExpireTime(); for(uint uGroup = 0; uGroup < uGroupCount; ++uGroup) { KdbGroup g = mgr.GetGroup(uGroup); PwGroup pg = new PwGroup(true, false); pg.Name = g.Name; pg.IconId = (g.ImageId < (uint)PwIcon.Count) ? (PwIcon)g.ImageId : PwIcon.Folder; pg.CreationTime = g.CreationTime.ToDateTime(); pg.LastModificationTime = g.LastModificationTime.ToDateTime(); pg.LastAccessTime = g.LastAccessTime.ToDateTime(); pg.ExpiryTime = g.ExpirationTime.ToDateTime(); pg.Expires = (pg.ExpiryTime != dtNeverExpire); pg.IsExpanded = ((g.Flags & (uint)KdbGroupFlags.Expanded) != 0); while(g.Level < (vGroupStack.Count - 1)) vGroupStack.Pop(); vGroupStack.Peek().AddGroup(pg, true); dictGroups[g.GroupId] = pg; if(g.Level == (uint)(vGroupStack.Count - 1)) vGroupStack.Push(pg); } return dictGroups; } private void ReadEntries(KdbManager mgr, Dictionary dictGroups) { DateTime dtNeverExpire = KdbManager.GetNeverExpireTime(); uint uEntryCount = mgr.EntryCount; for(uint uEntry = 0; uEntry < uEntryCount; ++uEntry) { KdbEntry e = mgr.GetEntry(uEntry); PwGroup pgContainer; if(!dictGroups.TryGetValue(e.GroupId, out pgContainer)) { Debug.Assert(false); continue; } PwEntry pe = new PwEntry(false, false); pe.SetUuid(new PwUuid(e.Uuid.ToByteArray()), false); pgContainer.AddEntry(pe, true, true); pe.IconId = (e.ImageId < (uint)PwIcon.Count) ? (PwIcon)e.ImageId : PwIcon.Key; pe.Strings.Set(PwDefs.TitleField, new ProtectedString( m_pwDatabase.MemoryProtection.ProtectTitle, e.Title)); pe.Strings.Set(PwDefs.UserNameField, new ProtectedString( m_pwDatabase.MemoryProtection.ProtectUserName, e.UserName)); pe.Strings.Set(PwDefs.PasswordField, new ProtectedString( m_pwDatabase.MemoryProtection.ProtectPassword, e.Password)); pe.Strings.Set(PwDefs.UrlField, new ProtectedString( m_pwDatabase.MemoryProtection.ProtectUrl, e.Url)); string strNotes = e.Additional; ImportAutoType(ref strNotes, pe); ImportUrlOverride(ref strNotes, pe); pe.Strings.Set(PwDefs.NotesField, new ProtectedString( m_pwDatabase.MemoryProtection.ProtectNotes, strNotes)); pe.CreationTime = e.CreationTime.ToDateTime(); pe.LastModificationTime = e.LastModificationTime.ToDateTime(); pe.LastAccessTime = e.LastAccessTime.ToDateTime(); pe.ExpiryTime = e.ExpirationTime.ToDateTime(); pe.Expires = (pe.ExpiryTime != dtNeverExpire); if((e.BinaryDataLength > 0) && (e.BinaryData != IntPtr.Zero)) { byte[] pbData = KdbManager.ReadBinary(e.BinaryData, e.BinaryDataLength); Debug.Assert(pbData.Length == e.BinaryDataLength); string strDesc = e.BinaryDescription; if(string.IsNullOrEmpty(strDesc)) strDesc = "Attachment"; pe.Binaries.Set(strDesc, new ProtectedBinary(false, pbData)); } if(m_slLogger != null) { if(!m_slLogger.SetProgress((100 * uEntry) / uEntryCount)) throw new Exception(KPRes.Cancel); } } } /// /// Save the contents of the current PwDatabase to a KDB file. /// /// Location to save the KDB file to. public void Save(string strSaveToFile, PwGroup pgDataSource) { Debug.Assert(strSaveToFile != null); if(strSaveToFile == null) throw new ArgumentNullException("strSaveToFile"); using(KdbManager mgr = new KdbManager()) { KdbErrorCode e = KdbFile.SetDatabaseKey(mgr, m_pwDatabase.MasterKey); if(e != KdbErrorCode.Success) { Debug.Assert(false); throw new Exception(KLRes.InvalidCompositeKey); } if(m_slLogger != null) { if(m_pwDatabase.MasterKey.ContainsType(typeof(KcpUserAccount))) m_slLogger.SetText(KPRes.KdbWUA, LogStatusType.Warning); if(m_pwDatabase.Name.Length != 0) m_slLogger.SetText(KdbPrefix + KPRes.FormatNoDatabaseName, LogStatusType.Warning); if(m_pwDatabase.Description.Length != 0) m_slLogger.SetText(KdbPrefix + KPRes.FormatNoDatabaseDesc, LogStatusType.Warning); } // Set properties AesKdf kdf = new AesKdf(); if(!kdf.Uuid.Equals(m_pwDatabase.KdfParameters.KdfUuid)) mgr.KeyTransformationRounds = (uint)PwDefs.DefaultKeyEncryptionRounds; else { ulong uRounds = m_pwDatabase.KdfParameters.GetUInt64( AesKdf.ParamRounds, PwDefs.DefaultKeyEncryptionRounds); uRounds = Math.Min(uRounds, 0xFFFFFFFEUL); mgr.KeyTransformationRounds = (uint)uRounds; } PwGroup pgRoot = (pgDataSource ?? m_pwDatabase.RootGroup); // Write groups and entries Dictionary dictGroups = WriteGroups(mgr, pgRoot); WriteEntries(mgr, dictGroups, pgRoot); e = mgr.SaveDatabase(strSaveToFile); if(e != KdbErrorCode.Success) throw new Exception(KLRes.FileSaveFailed); } } private static Dictionary WriteGroups(KdbManager mgr, PwGroup pgRoot) { Dictionary dictGroups = new Dictionary(); uint uGroupIndex = 1; DateTime dtNeverExpire = KdbManager.GetNeverExpireTime(); GroupHandler gh = delegate(PwGroup pg) { WriteGroup(pg, pgRoot, ref uGroupIndex, dictGroups, dtNeverExpire, mgr, false); return true; }; pgRoot.TraverseTree(TraversalMethod.PreOrder, gh, null); Debug.Assert(dictGroups.Count == (int)(uGroupIndex - 1)); EnsureParentGroupsExported(pgRoot, ref uGroupIndex, dictGroups, dtNeverExpire, mgr); return dictGroups; } private static void WriteGroup(PwGroup pg, PwGroup pgRoot, ref uint uGroupIndex, Dictionary dictGroups, DateTime dtNeverExpire, KdbManager mgr, bool bForceLevel0) { if(pg == pgRoot) return; KdbGroup grp = new KdbGroup(); grp.GroupId = uGroupIndex; dictGroups[pg] = grp.GroupId; grp.ImageId = (uint)pg.IconId; grp.Name = pg.Name; grp.CreationTime.Set(pg.CreationTime); grp.LastModificationTime.Set(pg.LastModificationTime); grp.LastAccessTime.Set(pg.LastAccessTime); if(pg.Expires) grp.ExpirationTime.Set(pg.ExpiryTime); else grp.ExpirationTime.Set(dtNeverExpire); grp.Level = (bForceLevel0 ? (ushort)0 : (ushort)(pg.GetLevel() - 1)); if(pg.IsExpanded) grp.Flags |= (uint)KdbGroupFlags.Expanded; if(!mgr.AddGroup(ref grp)) { Debug.Assert(false); throw new InvalidOperationException(); } ++uGroupIndex; } private static void EnsureParentGroupsExported(PwGroup pgRoot, ref uint uGroupIndex, Dictionary dictGroups, DateTime dtNeverExpires, KdbManager mgr) { bool bHasAtLeastOneGroup = (dictGroups.Count > 0); uint uLocalIndex = uGroupIndex; // Local copy, can't use ref in delegate EntryHandler eh = delegate(PwEntry pe) { PwGroup pg = pe.ParentGroup; if(pg == null) { Debug.Assert(false); return true; } if(bHasAtLeastOneGroup && (pg == pgRoot)) return true; if(dictGroups.ContainsKey(pg)) return true; WriteGroup(pg, pgRoot, ref uLocalIndex, dictGroups, dtNeverExpires, mgr, true); return true; }; pgRoot.TraverseTree(TraversalMethod.PreOrder, null, eh); uGroupIndex = uLocalIndex; } private void WriteEntries(KdbManager mgr, Dictionary dictGroups, PwGroup pgRoot) { bool bWarnedOnce = false; uint uGroupCount, uEntryCount, uEntriesSaved = 0; pgRoot.GetCounts(true, out uGroupCount, out uEntryCount); DateTime dtNeverExpire = KdbManager.GetNeverExpireTime(); EntryHandler eh = delegate(PwEntry pe) { KdbEntry e = new KdbEntry(); e.Uuid.Set(pe.Uuid.UuidBytes); if(pe.ParentGroup != pgRoot) e.GroupId = dictGroups[pe.ParentGroup]; else { e.GroupId = 1; if((m_slLogger != null) && !bWarnedOnce) { m_slLogger.SetText(KdbPrefix + KPRes.FormatNoRootEntries, LogStatusType.Warning); bWarnedOnce = true; } if(dictGroups.Count == 0) throw new Exception(KPRes.FormatNoSubGroupsInRoot); } e.ImageId = (uint)pe.IconId; e.Title = pe.Strings.ReadSafe(PwDefs.TitleField); e.UserName = pe.Strings.ReadSafe(PwDefs.UserNameField); e.Password = pe.Strings.ReadSafe(PwDefs.PasswordField); e.Url = pe.Strings.ReadSafe(PwDefs.UrlField); string strNotes = pe.Strings.ReadSafe(PwDefs.NotesField); ExportCustomStrings(pe, ref strNotes); ExportAutoType(pe, ref strNotes); ExportUrlOverride(pe, ref strNotes); e.Additional = strNotes; e.PasswordLength = (uint)e.Password.Length; Debug.Assert(TimeUtil.PwTimeLength == 7); e.CreationTime.Set(pe.CreationTime); e.LastModificationTime.Set(pe.LastModificationTime); e.LastAccessTime.Set(pe.LastAccessTime); if(pe.Expires) e.ExpirationTime.Set(pe.ExpiryTime); else e.ExpirationTime.Set(dtNeverExpire); IntPtr hBinaryData = IntPtr.Zero; if(pe.Binaries.UCount >= 1) { foreach(KeyValuePair kvp in pe.Binaries) { e.BinaryDescription = kvp.Key; byte[] pbAttached = kvp.Value.ReadData(); e.BinaryDataLength = (uint)pbAttached.Length; if(e.BinaryDataLength > 0) { hBinaryData = Marshal.AllocHGlobal((int)e.BinaryDataLength); Marshal.Copy(pbAttached, 0, hBinaryData, (int)e.BinaryDataLength); e.BinaryData = hBinaryData; } break; } if((pe.Binaries.UCount > 1) && (m_slLogger != null)) m_slLogger.SetText(KdbPrefix + KPRes.FormatOnlyOneAttachment + "\r\n\r\n" + KPRes.Entry + ":\r\n" + KPRes.Title + ": " + e.Title + "\r\n" + KPRes.UserName + ": " + e.UserName, LogStatusType.Warning); } bool bResult = mgr.AddEntry(ref e); Marshal.FreeHGlobal(hBinaryData); hBinaryData = IntPtr.Zero; if(!bResult) { Debug.Assert(false); throw new InvalidOperationException(); } ++uEntriesSaved; if(m_slLogger != null) if(!m_slLogger.SetProgress((100 * uEntriesSaved) / uEntryCount)) return false; return true; }; if(!pgRoot.TraverseTree(TraversalMethod.PreOrder, null, eh)) throw new InvalidOperationException(); } /* private static void ImportAutoType(ref string strNotes, PwEntry peStorage) { string str = strNotes; char[] vTrim = new char[]{ '\r', '\n', '\t', ' ' }; int nFirstAutoType = str.IndexOf(AutoTypePrefix, StringComparison.OrdinalIgnoreCase); if(nFirstAutoType < 0) nFirstAutoType = int.MaxValue; int nFirstAutoTypeWindow = str.IndexOf(AutoTypeWindowPrefix, StringComparison.OrdinalIgnoreCase); if((nFirstAutoTypeWindow >= 0) && (nFirstAutoTypeWindow < nFirstAutoType)) { int nWindowEnd = str.IndexOf('\n', nFirstAutoTypeWindow); if(nWindowEnd < 0) nWindowEnd = str.Length - 1; string strWindow = str.Substring(nFirstAutoTypeWindow + AutoTypeWindowPrefix.Length, nWindowEnd - nFirstAutoTypeWindow - AutoTypeWindowPrefix.Length + 1); strWindow = strWindow.Trim(vTrim); str = str.Remove(nFirstAutoTypeWindow, nWindowEnd - nFirstAutoTypeWindow + 1); peStorage.AutoType.Set(strWindow, string.Empty); } while(true) { int nAutoTypeStart = str.IndexOf(AutoTypePrefix, 0, StringComparison.OrdinalIgnoreCase); if(nAutoTypeStart < 0) break; int nAutoTypeEnd = str.IndexOf('\n', nAutoTypeStart); if(nAutoTypeEnd < 0) nAutoTypeEnd = str.Length - 1; string strAutoType = str.Substring(nAutoTypeStart + AutoTypePrefix.Length, nAutoTypeEnd - nAutoTypeStart - AutoTypePrefix.Length + 1); strAutoType = strAutoType.Trim(vTrim); str = str.Remove(nAutoTypeStart, nAutoTypeEnd - nAutoTypeStart + 1); int nWindowStart = str.IndexOf(AutoTypeWindowPrefix, 0, StringComparison.OrdinalIgnoreCase); if((nWindowStart < 0) || (nWindowStart >= nAutoTypeStart)) { peStorage.AutoType.DefaultSequence = strAutoType; continue; } int nWindowEnd = str.IndexOf('\n', nWindowStart); if(nWindowEnd < 0) nWindowEnd = str.Length - 1; string strWindow = str.Substring(nWindowStart + AutoTypeWindowPrefix.Length, nWindowEnd - nWindowStart - AutoTypeWindowPrefix.Length + 1); strWindow = strWindow.Trim(vTrim); str = str.Remove(nWindowStart, nWindowEnd - nWindowStart + 1); peStorage.AutoType.Set(strWindow, strAutoType); } strNotes = str; } */ private static void ImportAutoType(ref string strNotes, PwEntry peStorage) { if(string.IsNullOrEmpty(strNotes)) return; string str = strNotes.Replace("\r", string.Empty); string[] vLines = str.Split('\n'); string strOvr = FindPrefixedLine(vLines, AutoTypePrefix + ":"); if((strOvr != null) && (strOvr.Length > (AutoTypePrefix.Length + 1))) { strOvr = strOvr.Substring(AutoTypePrefix.Length + 1).Trim(); peStorage.AutoType.DefaultSequence = ConvertAutoTypeSequence( strOvr, true); } StringBuilder sb = new StringBuilder(); foreach(string strLine in vLines) { bool bProcessed = false; for(int iIdx = 0; iIdx < 32; ++iIdx) { string s = ((iIdx == 0) ? string.Empty : ("-" + iIdx.ToString(NumberFormatInfo.InvariantInfo))); string strWndPrefix = (AutoTypeWindowPrefix + s + ":"); string strSeqPrefix = (AutoTypePrefix + s + ":"); if(strLine.StartsWith(strWndPrefix, StrUtil.CaseIgnoreCmp) && (strLine.Length > strWndPrefix.Length)) { string strWindow = strLine.Substring(strWndPrefix.Length).Trim(); string strSeq = FindPrefixedLine(vLines, strSeqPrefix); if((strSeq != null) && (strSeq.Length > strSeqPrefix.Length)) peStorage.AutoType.Add(new AutoTypeAssociation( strWindow, ConvertAutoTypeSequence(strSeq.Substring( strSeqPrefix.Length), true))); else // Window, but no sequence peStorage.AutoType.Add(new AutoTypeAssociation( strWindow, string.Empty)); bProcessed = true; break; } else if(strLine.StartsWith(strSeqPrefix, StrUtil.CaseIgnoreCmp)) { bProcessed = true; break; } } if(bProcessed == false) { sb.Append(strLine); sb.Append(MessageService.NewLine); } } strNotes = sb.ToString(); // peStorage.AutoType.Sort(); } private static string FindPrefixedLine(string[] vLines, string strPrefix) { foreach(string str in vLines) { if(str.StartsWith(strPrefix, StrUtil.CaseIgnoreCmp)) return str; } return null; } private static Dictionary m_dSeq1xTo2x = null; private static Dictionary m_dSeq1xTo2xBiDir = null; private static string ConvertAutoTypeSequence(string strSeq, bool b1xTo2x) { if(string.IsNullOrEmpty(strSeq)) return string.Empty; if(m_dSeq1xTo2x == null) { m_dSeq1xTo2x = new Dictionary(); m_dSeq1xTo2xBiDir = new Dictionary(); // m_dSeq1xTo2x[@"{SPACE}"] = " "; // m_dSeq1xTo2x[@"{CLEARFIELD}"] = @"{HOME}+({END}){DEL}"; m_dSeq1xTo2xBiDir[@"{AT}"] = @"@"; m_dSeq1xTo2xBiDir[@"{PLUS}"] = @"{+}"; m_dSeq1xTo2xBiDir[@"{PERCENT}"] = @"{%}"; m_dSeq1xTo2xBiDir[@"{CARET}"] = @"{^}"; m_dSeq1xTo2xBiDir[@"{TILDE}"] = @"{~}"; m_dSeq1xTo2xBiDir[@"{LEFTBRACE}"] = @"{{}"; m_dSeq1xTo2xBiDir[@"{RIGHTBRACE}"] = @"{}}"; m_dSeq1xTo2xBiDir[@"{LEFTPAREN}"] = @"{(}"; m_dSeq1xTo2xBiDir[@"{RIGHTPAREN}"] = @"{)}"; m_dSeq1xTo2xBiDir[@"(+{END})"] = @"+({END})"; } string str = strSeq.Trim(); if(b1xTo2x) { foreach(KeyValuePair kvp in m_dSeq1xTo2x) str = StrUtil.ReplaceCaseInsensitive(str, kvp.Key, kvp.Value); } foreach(KeyValuePair kvp in m_dSeq1xTo2xBiDir) { if(b1xTo2x) str = StrUtil.ReplaceCaseInsensitive(str, kvp.Key, kvp.Value); else str = StrUtil.ReplaceCaseInsensitive(str, kvp.Value, kvp.Key); } if(!b1xTo2x) str = CapitalizePlaceholders(str); return str; } private static string CapitalizePlaceholders(string strSeq) { string str = strSeq; int iOffset = 0; while(true) { int iStart = str.IndexOf('{', iOffset); if(iStart < 0) break; int iEnd = str.IndexOf('}', iStart); if(iEnd < 0) break; // No assert (user data) string strPlaceholder = str.Substring(iStart, iEnd - iStart + 1); if(!strPlaceholder.StartsWith("{S:", StrUtil.CaseIgnoreCmp)) str = str.Replace(strPlaceholder, strPlaceholder.ToUpper()); iOffset = iStart + 1; } return str; } private static void ExportCustomStrings(PwEntry peSource, ref string strNotes) { bool bSep = false; foreach(KeyValuePair kvp in peSource.Strings) { if(PwDefs.IsStandardField(kvp.Key)) continue; if(!bSep) { if(strNotes.Length > 0) strNotes += MessageService.NewParagraph; bSep = true; } strNotes += kvp.Key + ": " + kvp.Value.ReadString() + MessageService.NewLine; } } private static void ExportAutoType(PwEntry peSource, ref string strNotes) { StringBuilder sbAppend = new StringBuilder(); bool bSeparator = false; uint uIndex = 0; if((peSource.AutoType.DefaultSequence.Length > 0) && (peSource.AutoType.AssociationsCount == 0)) // Avoid broken indices { if(strNotes.Length > 0) sbAppend.Append(MessageService.NewParagraph); sbAppend.Append(AutoTypePrefix); sbAppend.Append(@": "); sbAppend.Append(ConvertAutoTypeSeqExp(peSource.AutoType.DefaultSequence, peSource)); sbAppend.Append(MessageService.NewLine); bSeparator = true; ++uIndex; } foreach(AutoTypeAssociation a in peSource.AutoType.Associations) { if(bSeparator == false) { if(strNotes.Length > 0) sbAppend.Append(MessageService.NewParagraph); bSeparator = true; } string strSuffix = ((uIndex > 0) ? ("-" + uIndex.ToString( NumberFormatInfo.InvariantInfo)) : string.Empty); sbAppend.Append(AutoTypePrefix + strSuffix); sbAppend.Append(@": "); sbAppend.Append(ConvertAutoTypeSeqExp(a.Sequence, peSource)); sbAppend.Append(MessageService.NewLine); sbAppend.Append(AutoTypeWindowPrefix + strSuffix); sbAppend.Append(@": "); sbAppend.Append(a.WindowName); sbAppend.Append(MessageService.NewLine); ++uIndex; } strNotes = strNotes.TrimEnd(new char[]{ '\r', '\n', '\t', ' ' }); strNotes += sbAppend.ToString(); } private static string ConvertAutoTypeSeqExp(string strSeq, PwEntry pe) { string strExp = strSeq; if(string.IsNullOrEmpty(strExp)) strExp = pe.GetAutoTypeSequence(); return ConvertAutoTypeSequence(strExp, false); } private static void ImportUrlOverride(ref string strNotes, PwEntry peStorage) { string str = strNotes; char[] vTrim = new char[] { '\r', '\n', '\t', ' ' }; int nUrlStart = str.IndexOf(UrlOverridePrefix, 0, StringComparison.OrdinalIgnoreCase); if(nUrlStart < 0) return; int nUrlEnd = str.IndexOf('\n', nUrlStart); if(nUrlEnd < 0) nUrlEnd = str.Length - 1; string strUrl = str.Substring(nUrlStart + UrlOverridePrefix.Length, nUrlEnd - nUrlStart - UrlOverridePrefix.Length + 1); strUrl = strUrl.Trim(vTrim); peStorage.OverrideUrl = strUrl; str = str.Remove(nUrlStart, nUrlEnd - nUrlStart + 1); strNotes = str; } private static void ExportUrlOverride(PwEntry peSource, ref string strNotes) { if(peSource.OverrideUrl.Length > 0) { StringBuilder sbAppend = new StringBuilder(); sbAppend.Append(MessageService.NewParagraph); sbAppend.Append(UrlOverridePrefix); sbAppend.Append(@" "); sbAppend.Append(peSource.OverrideUrl); sbAppend.Append(MessageService.NewLine); strNotes = strNotes.TrimEnd(new char[] { '\r', '\n', '\t', ' ' }); strNotes += sbAppend.ToString(); } } } } KeePass/DataExchange/GxiProfile.cs0000664000000000000000000002216313222430406016024 0ustar rootroot/* KeePass Password Safe - The Open-Source Password Manager Copyright (C) 2003-2018 Dominik Reichl This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ using System; using System.Collections.Generic; using System.Text; using System.Xml.Serialization; using System.ComponentModel; using System.Diagnostics; using KeePassLib.Utility; namespace KeePass.DataExchange { public enum GxiBinaryEncoding { Base64 = 0, Hex, Count // Virtual } public sealed class GxiProfile { private StrEncodingType m_tEnc = StrEncodingType.Unknown; public StrEncodingType Encoding { get { return m_tEnc; } set { m_tEnc = value; } } private bool m_bRemoveInvChars = true; [DefaultValue(true)] public bool RemoveInvalidChars { get { return m_bRemoveInvChars; } set { m_bRemoveInvChars = value; } } private bool m_bDecodeHtmlEnt = true; [DefaultValue(true)] public bool DecodeHtmlEntities { get { return m_bDecodeHtmlEnt; } set { m_bDecodeHtmlEnt = value; } } private string m_strRootXPath = string.Empty; [DefaultValue("")] public string RootXPath { get { return m_strRootXPath; } set { if(value == null) throw new ArgumentNullException("value"); m_strRootXPath = value; } } private string m_strGroupXPath = string.Empty; [DefaultValue("")] public string GroupXPath { get { return m_strGroupXPath; } set { if(value == null) throw new ArgumentNullException("value"); m_strGroupXPath = value; } } private string m_strGroupNameXPath = string.Empty; [DefaultValue("")] public string GroupNameXPath { get { return m_strGroupNameXPath; } set { if(value == null) throw new ArgumentNullException("value"); m_strGroupNameXPath = value; } } private string m_strEntryXPath = string.Empty; [DefaultValue("")] public string EntryXPath { get { return m_strEntryXPath; } set { if(value == null) throw new ArgumentNullException("value"); m_strEntryXPath = value; } } private string m_strStringKvpXPath = string.Empty; [DefaultValue("")] public string StringKvpXPath { get { return m_strStringKvpXPath; } set { if(value == null) throw new ArgumentNullException("value"); m_strStringKvpXPath = value; } } private string m_strStringKeyXPath = string.Empty; [DefaultValue("")] public string StringKeyXPath { get { return m_strStringKeyXPath; } set { if(value == null) throw new ArgumentNullException("value"); m_strStringKeyXPath = value; } } private bool m_bStringKeyUseName = false; [DefaultValue(false)] public bool StringKeyUseName { get { return m_bStringKeyUseName; } set { m_bStringKeyUseName = value; } } private string m_strStringKeyRepl = string.Empty; [DefaultValue("")] public string StringKeyRepl { get { return m_strStringKeyRepl; } set { if(value == null) throw new ArgumentNullException("value"); m_strStringKeyRepl = value; } } private string m_strStringValueXPath = string.Empty; [DefaultValue("")] public string StringValueXPath { get { return m_strStringValueXPath; } set { if(value == null) throw new ArgumentNullException("value"); m_strStringValueXPath = value; } } private string m_strStringValueRepl = string.Empty; [DefaultValue("")] public string StringValueRepl { get { return m_strStringValueRepl; } set { if(value == null) throw new ArgumentNullException("value"); m_strStringValueRepl = value; } } private string m_strStringKvpXPath2 = string.Empty; [DefaultValue("")] public string StringKvpXPath2 { get { return m_strStringKvpXPath2; } set { if(value == null) throw new ArgumentNullException("value"); m_strStringKvpXPath2 = value; } } private string m_strStringKeyXPath2 = string.Empty; [DefaultValue("")] public string StringKeyXPath2 { get { return m_strStringKeyXPath2; } set { if(value == null) throw new ArgumentNullException("value"); m_strStringKeyXPath2 = value; } } private bool m_bStringKeyUseName2 = false; [DefaultValue(false)] public bool StringKeyUseName2 { get { return m_bStringKeyUseName2; } set { m_bStringKeyUseName2 = value; } } private string m_strStringKeyRepl2 = string.Empty; [DefaultValue("")] public string StringKeyRepl2 { get { return m_strStringKeyRepl2; } set { if(value == null) throw new ArgumentNullException("value"); m_strStringKeyRepl2 = value; } } private string m_strStringValueXPath2 = string.Empty; [DefaultValue("")] public string StringValueXPath2 { get { return m_strStringValueXPath2; } set { if(value == null) throw new ArgumentNullException("value"); m_strStringValueXPath2 = value; } } private string m_strStringValueRepl2 = string.Empty; [DefaultValue("")] public string StringValueRepl2 { get { return m_strStringValueRepl2; } set { if(value == null) throw new ArgumentNullException("value"); m_strStringValueRepl2 = value; } } private string m_strBinaryKvpXPath = string.Empty; [DefaultValue("")] public string BinaryKvpXPath { get { return m_strBinaryKvpXPath; } set { if(value == null) throw new ArgumentNullException("value"); m_strBinaryKvpXPath = value; } } private string m_strBinaryKeyXPath = string.Empty; [DefaultValue("")] public string BinaryKeyXPath { get { return m_strBinaryKeyXPath; } set { if(value == null) throw new ArgumentNullException("value"); m_strBinaryKeyXPath = value; } } private bool m_bBinaryKeyUseName = false; [DefaultValue(false)] public bool BinaryKeyUseName { get { return m_bBinaryKeyUseName; } set { m_bBinaryKeyUseName = value; } } private string m_strBinaryKeyRepl = string.Empty; [DefaultValue("")] public string BinaryKeyRepl { get { return m_strBinaryKeyRepl; } set { if(value == null) throw new ArgumentNullException("value"); m_strBinaryKeyRepl = value; } } private string m_strBinaryValueXPath = string.Empty; [DefaultValue("")] public string BinaryValueXPath { get { return m_strBinaryValueXPath; } set { if(value == null) throw new ArgumentNullException("value"); m_strBinaryValueXPath = value; } } private GxiBinaryEncoding m_beBinValue = GxiBinaryEncoding.Base64; public GxiBinaryEncoding BinaryValueEncoding { get { return m_beBinValue; } set { m_beBinValue = value; } } private string m_strEntryGroupXPath = string.Empty; [DefaultValue("")] public string EntryGroupXPath { get { return m_strEntryGroupXPath; } set { if(value == null) throw new ArgumentNullException("value"); m_strEntryGroupXPath = value; } } private string m_strEntryGroupXPath2 = string.Empty; [DefaultValue("")] public string EntryGroupXPath2 { get { return m_strEntryGroupXPath2; } set { if(value == null) throw new ArgumentNullException("value"); m_strEntryGroupXPath2 = value; } } private string m_strEntryGroupSep = string.Empty; [DefaultValue("")] public string EntryGroupSep { get { return m_strEntryGroupSep; } set { if(value == null) throw new ArgumentNullException("value"); m_strEntryGroupSep = value; } } private bool m_bEntriesInRoot = true; [DefaultValue(true)] public bool EntriesInRoot { get { return m_bEntriesInRoot; } set { m_bEntriesInRoot = value; } } private bool m_bEntriesInGroup = true; [DefaultValue(true)] public bool EntriesInGroup { get { return m_bEntriesInGroup; } set { m_bEntriesInGroup = value; } } private bool m_bGroupsInGroup = true; [DefaultValue(true)] public bool GroupsInGroup { get { return m_bGroupsInGroup; } set { m_bGroupsInGroup = value; } } private bool m_bStringKeyToStd = true; [DefaultValue(true)] public bool StringKeyToStd { get { return m_bStringKeyToStd; } set { m_bStringKeyToStd = value; } } private bool m_bStringKeyToStdFuzzy = false; [DefaultValue(false)] public bool StringKeyToStdFuzzy { get { return m_bStringKeyToStdFuzzy; } set { m_bStringKeyToStdFuzzy = value; } } } } KeePass/DataExchange/Json.cs0000664000000000000000000001577713222430406014702 0ustar rootroot/* KeePass Password Safe - The Open-Source Password Manager Copyright (C) 2003-2018 Dominik Reichl This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ using System; using System.Collections.Generic; using System.Text; using System.Globalization; using System.Diagnostics; using KeePassLib.Utility; using KeePassLib.Resources; namespace KeePass.DataExchange { public sealed class JsonFormatException : Exception { public override string Message { get { return KLRes.InvalidDataWhileDecoding; } } public JsonFormatException() { Debug.Assert(false); } } public sealed class JsonObject { private Dictionary m_dict = new Dictionary(); public Dictionary Items { get { return m_dict; } } public JsonObject(CharStream csDataSource) { if(csDataSource == null) throw new ArgumentNullException("csDataSource"); char chInit = csDataSource.ReadChar(true); if(chInit != '{') throw new JsonFormatException(); while(true) { string strName = (new JsonString(csDataSource)).Value; char chSeparator = csDataSource.ReadChar(true); if(chSeparator != ':') throw new JsonFormatException(); JsonValue jValue = new JsonValue(csDataSource); m_dict[strName] = jValue; char chNext = csDataSource.PeekChar(true); if(chNext == '}') break; else if(chNext == ',') csDataSource.ReadChar(true); else throw new JsonFormatException(); } char chTerminator = csDataSource.ReadChar(true); if(chTerminator != '}') throw new JsonFormatException(); } } public sealed class JsonArray { private JsonValue[] m_values; public JsonValue[] Values { get { return m_values; } } public JsonArray(JsonValue[] vValues) { if(vValues == null) throw new ArgumentNullException("vValues"); m_values = vValues; } public JsonArray(CharStream csDataSource) { if(csDataSource == null) throw new ArgumentNullException("csDataSource"); char chInit = csDataSource.ReadChar(true); if(chInit != '[') throw new JsonFormatException(); List lValues = new List(); while(true) { char chNext = csDataSource.PeekChar(true); if(chNext == ']') break; lValues.Add(new JsonValue(csDataSource)); chNext = csDataSource.PeekChar(true); if(chNext == ',') csDataSource.ReadChar(true); } char chTerminator = csDataSource.ReadChar(true); if(chTerminator != ']') throw new JsonFormatException(); m_values = lValues.ToArray(); } } public sealed class JsonValue { private object m_value; public object Value { get { return m_value; } } public JsonValue(CharStream csDataSource) { if(csDataSource == null) throw new ArgumentNullException("csDataSource"); char chNext = csDataSource.PeekChar(true); if(chNext == '\"') m_value = (new JsonString(csDataSource)).Value; else if(chNext == '{') m_value = new JsonObject(csDataSource); else if(chNext == '[') m_value = new JsonArray(csDataSource); else if(chNext == 't') { for(int i = 0; i < 4; ++i) csDataSource.ReadChar(true); m_value = true; } else if(chNext == 'f') { for(int i = 0; i < 5; ++i) csDataSource.ReadChar(true); m_value = false; } else if(chNext == 'n') { for(int i = 0; i < 4; ++i) csDataSource.ReadChar(true); m_value = null; } else m_value = new JsonNumber(csDataSource); } public override string ToString() { if(m_value != null) return m_value.ToString(); return string.Empty; } } public sealed class JsonString { private string m_str; public string Value { get { return m_str; } } public JsonString(string strValue) { if(strValue == null) throw new ArgumentNullException("strValue"); m_str = strValue; } public JsonString(CharStream csDataSource) { if(csDataSource == null) throw new ArgumentNullException("csDataSource"); char chInit = csDataSource.ReadChar(true); if(chInit != '\"') throw new JsonFormatException(); StringBuilder sb = new StringBuilder(); while(true) { char ch = csDataSource.ReadChar(); if(ch == char.MinValue) throw new JsonFormatException(); if(ch == '\"') break; // End of string else if(ch == '\\') { char chNext = csDataSource.ReadChar(); if(chNext == char.MinValue) throw new JsonFormatException(); if((chNext == 'b') || (chNext == 'f')) { } // Ignore else if(chNext == 'r') sb.Append('\r'); else if(chNext == 'n') sb.Append('\n'); else if(chNext == 't') sb.Append('\t'); else if(chNext == 'u') { char ch1 = csDataSource.ReadChar(); char ch2 = csDataSource.ReadChar(); char ch3 = csDataSource.ReadChar(); char ch4 = csDataSource.ReadChar(); if(ch4 == char.MinValue) throw new JsonFormatException(); byte[] pbUni = MemUtil.HexStringToByteArray(new string( new char[] { ch1, ch2, ch3, ch4 })); if((pbUni != null) && (pbUni.Length == 2)) sb.Append((char)(((ushort)pbUni[0] << 8) | (ushort)pbUni[1])); else throw new JsonFormatException(); } else sb.Append(chNext); } else sb.Append(ch); } m_str = sb.ToString(); } public override string ToString() { return m_str; } } public sealed class JsonNumber { private double m_value; public double Value { get { return m_value; } } public JsonNumber(CharStream csDataSource) { if(csDataSource == null) throw new ArgumentNullException("csDataSource"); StringBuilder sb = new StringBuilder(); while(true) { char ch = csDataSource.PeekChar(true); if(((ch >= '0') && (ch <= '9')) || (ch == 'e') || (ch == 'E') || (ch == '+') || (ch == '-') || (ch == '.')) { csDataSource.ReadChar(true); sb.Append(ch); } else break; } const NumberStyles ns = (NumberStyles.Integer | NumberStyles.AllowDecimalPoint | NumberStyles.AllowThousands | NumberStyles.AllowExponent); if(!double.TryParse(sb.ToString(), ns, NumberFormatInfo.InvariantInfo, out m_value)) { Debug.Assert(false); } } public override string ToString() { return m_value.ToString(NumberFormatInfo.InvariantInfo); } } } KeePass/DataExchange/CsvStreamReader.cs0000664000000000000000000000667313222430404017014 0ustar rootroot/* KeePass Password Safe - The Open-Source Password Manager Copyright (C) 2003-2018 Dominik Reichl This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ using System; using System.Collections.Generic; using System.Text; using System.IO; using System.Diagnostics; using KeePassLib.Utility; namespace KeePass.DataExchange { public sealed class CsvStreamReader { private CharStream m_sChars; private readonly bool m_bAllowUnquoted; [Obsolete] public CsvStreamReader(string strData) { m_sChars = new CharStream(strData); m_bAllowUnquoted = false; } public CsvStreamReader(string strData, bool bAllowUnquoted) { m_sChars = new CharStream(strData); m_bAllowUnquoted = bAllowUnquoted; } public string[] ReadLine() { return (m_bAllowUnquoted ? ReadLineUnquoted() : ReadLineQuoted()); } private string[] ReadLineQuoted() { if(m_sChars.PeekChar() == char.MinValue) return null; List v = new List(); StringBuilder sb = new StringBuilder(); bool bInField = false; while(true) { char ch = m_sChars.ReadChar(); if(ch == char.MinValue) break; if((ch == '\"') && !bInField) bInField = true; else if((ch == '\"') && bInField) { if(m_sChars.PeekChar() == '\"') { m_sChars.ReadChar(); sb.Append('\"'); } else { v.Add(sb.ToString()); if(sb.Length > 0) sb.Remove(0, sb.Length); bInField = false; } } else if(((ch == '\r') || (ch == '\n')) && !bInField) break; else if(bInField) sb.Append(ch); } Debug.Assert(!bInField); Debug.Assert(sb.Length == 0); if(sb.Length > 0) v.Add(sb.ToString()); return v.ToArray(); } private string[] ReadLineUnquoted() { char chFirst = m_sChars.PeekChar(); if(chFirst == char.MinValue) return null; if((chFirst == '\r') || (chFirst == '\n')) { m_sChars.ReadChar(); // Advance return new string[0]; } List v = new List(); StringBuilder sb = new StringBuilder(); bool bInField = false; while(true) { char ch = m_sChars.ReadChar(); if(ch == char.MinValue) break; if((ch == '\"') && !bInField) bInField = true; else if((ch == '\"') && bInField) { if(m_sChars.PeekChar() == '\"') { m_sChars.ReadChar(); sb.Append('\"'); } else bInField = false; } else if(((ch == '\r') || (ch == '\n')) && !bInField) break; else if(bInField) sb.Append(ch); else if(ch == ',') { v.Add(sb.ToString()); if(sb.Length > 0) sb.Remove(0, sb.Length); } else sb.Append(ch); } Debug.Assert(!bInField); v.Add(sb.ToString()); return v.ToArray(); } } } KeePass/DataExchange/KdbManager.cs0000664000000000000000000011444713222430406015756 0ustar rootroot/* KeePass Password Safe - The Open-Source Password Manager Copyright (C) 2003-2018 Dominik Reichl This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ #if PocketPC || Smartphone || WindowsCE #undef KDB_ANSI #else // If compiling for the ANSI version of KeePassLibC, define KDB_ANSI. // If compiling for the Unicode version of KeePassLibC, do not define KDB_ANSI. #define KDB_ANSI #endif using System; using System.Diagnostics; using System.Runtime.InteropServices; using System.Text; using KeePassLib.Utility; namespace KeePass.DataExchange { /// /// Structure containing information about a password group. This structure /// doesn't contain any information about the entries stored in this group. /// #if PocketPC || Smartphone || WindowsCE [StructLayout(LayoutKind.Sequential)] #else [StructLayout(LayoutKind.Sequential, Pack = 1)] #endif public struct KdbGroup { /// /// The GroupID of the group. /// [MarshalAs(UnmanagedType.U4)] public UInt32 GroupId; /// /// The ImageID of the group. /// [MarshalAs(UnmanagedType.U4)] public UInt32 ImageId; /// /// The Name of the group. /// #if KDB_ANSI [MarshalAs(UnmanagedType.LPStr)] public string Name; #else [MarshalAs(UnmanagedType.LPWStr)] public string Name; #endif /// /// The creation time of the group. /// public KdbTime CreationTime; /// /// The last modification time of the group. /// public KdbTime LastModificationTime; /// /// The last access time of the group. /// public KdbTime LastAccessTime; /// /// The expiry time of the group. /// public KdbTime ExpirationTime; /// /// Indentation level of the group. /// [MarshalAs(UnmanagedType.U2)] public UInt16 Level; #if VPF_ALIGN /// /// Dummy entry for alignment purposes. /// [MarshalAs(UnmanagedType.U2)] public UInt16 Dummy; #endif /// /// Flags of the group (see KdbGroupFlags). /// [MarshalAs(UnmanagedType.U4)] public UInt32 Flags; } /// /// Password group flags. /// [Flags] public enum KdbGroupFlags { /// /// No special flags. /// None = 0, /// /// The group is expanded. /// Expanded = 1 } /// /// Structure containing information about a password entry. /// #if PocketPC || Smartphone || WindowsCE [StructLayout(LayoutKind.Sequential)] #else [StructLayout(LayoutKind.Sequential, Pack = 1)] #endif public struct KdbEntry { /// /// The UUID of the entry. /// public KdbUuid Uuid; /// /// The group ID of the enty. /// [MarshalAs(UnmanagedType.U4)] public UInt32 GroupId; /// /// The image ID of the entry. /// [MarshalAs(UnmanagedType.U4)] public UInt32 ImageId; #if KDB_ANSI /// /// The title of the entry. /// [MarshalAs(UnmanagedType.LPStr)] public string Title; /// /// The URL of the entry. /// [MarshalAs(UnmanagedType.LPStr)] public string Url; /// /// The user name of the entry. /// [MarshalAs(UnmanagedType.LPStr)] public string UserName; /// /// The password length of the entry. /// [MarshalAs(UnmanagedType.U4)] public UInt32 PasswordLength; /// /// The password of the entry. /// [MarshalAs(UnmanagedType.LPStr)] public string Password; /// /// The notes field of the entry. /// [MarshalAs(UnmanagedType.LPStr)] public string Additional; #else /// /// The title of the entry. /// [MarshalAs(UnmanagedType.LPWStr)] public string Title; /// /// The URL of the entry. /// [MarshalAs(UnmanagedType.LPWStr)] public string Url; /// /// The user name of the entry. /// [MarshalAs(UnmanagedType.LPWStr)] public string UserName; /// /// The password length of the entry. /// [MarshalAs(UnmanagedType.U4)] public UInt32 PasswordLength; /// /// The password of the entry. /// [MarshalAs(UnmanagedType.LPWStr)] public string Password; /// /// The notes field of the entry. /// [MarshalAs(UnmanagedType.LPWStr)] public string Additional; #endif /// /// The creation time of the entry. /// public KdbTime CreationTime; /// /// The last modification time of the entry. /// public KdbTime LastModificationTime; /// /// The last access time of the entry. /// public KdbTime LastAccessTime; /// /// The expiration time of the entry. /// public KdbTime ExpirationTime; /// /// The description of the binary attachment. /// #if KDB_ANSI [MarshalAs(UnmanagedType.LPStr)] public string BinaryDescription; #else [MarshalAs(UnmanagedType.LPWStr)] public string BinaryDescription; #endif /// /// The attachment of the entry. /// public IntPtr BinaryData; /// /// The length of the attachment. /// [MarshalAs(UnmanagedType.U4)] public UInt32 BinaryDataLength; } /// /// Structure containing UUID bytes (16 bytes). /// #if PocketPC || Smartphone || WindowsCE [StructLayout(LayoutKind.Sequential)] #else [StructLayout(LayoutKind.Sequential, Pack = 1)] #endif public struct KdbUuid { public Byte V0; public Byte V1; public Byte V2; public Byte V3; public Byte V4; public Byte V5; public Byte V6; public Byte V7; public Byte V8; public Byte V9; public Byte VA; public Byte VB; public Byte VC; public Byte VD; public Byte VE; public Byte VF; /// /// Convert UUID to a byte array of length 16. /// /// Byte array (16 bytes). public byte[] ToByteArray() { return new byte[]{ this.V0, this.V1, this.V2, this.V3, this.V4, this.V5, this.V6, this.V7, this.V8, this.V9, this.VA, this.VB, this.VC, this.VD, this.VE, this.VF }; } /// /// Set the UUID using an array of 16 bytes. /// /// Bytes to set the UUID to. public void Set(byte[] pb) { Debug.Assert((pb != null) && (pb.Length == 16)); if(pb == null) throw new ArgumentNullException("pb"); if(pb.Length != 16) throw new ArgumentException(); this.V0 = pb[0]; this.V1 = pb[1]; this.V2 = pb[2]; this.V3 = pb[3]; this.V4 = pb[4]; this.V5 = pb[5]; this.V6 = pb[6]; this.V7 = pb[7]; this.V8 = pb[8]; this.V9 = pb[9]; this.VA = pb[10]; this.VB = pb[11]; this.VC = pb[12]; this.VD = pb[13]; this.VE = pb[14]; this.VF = pb[15]; } } /// /// Structure containing time information in a compact, but still easily /// accessible form. /// #if PocketPC || Smartphone || WindowsCE [StructLayout(LayoutKind.Sequential)] #else [StructLayout(LayoutKind.Sequential, Pack = 1)] #endif public struct KdbTime { [MarshalAs(UnmanagedType.U2)] public UInt16 Year; [MarshalAs(UnmanagedType.U1)] public Byte Month; [MarshalAs(UnmanagedType.U1)] public Byte Day; [MarshalAs(UnmanagedType.U1)] public Byte Hour; [MarshalAs(UnmanagedType.U1)] public Byte Minute; [MarshalAs(UnmanagedType.U1)] public Byte Second; #if VPF_ALIGN /// /// Dummy entry for alignment purposes. /// [MarshalAs(UnmanagedType.U1)] public Byte Dummy; #endif /// /// Construct a KdbTime with initial values. /// /// Year. /// Month. /// Day. /// Hour. /// Minute. /// Second. public KdbTime(UInt16 uYear, Byte uMonth, Byte uDay, Byte uHour, Byte uMinute, Byte uSecond) { this.Year = uYear; this.Month = uMonth; this.Day = uDay; this.Hour = uHour; this.Minute = uMinute; this.Second = uSecond; #if VPF_ALIGN this.Dummy = 0; #endif } /// /// Convert the current KdbTime object to a DateTime object. /// public DateTime ToDateTime() { if((this.Year == 0) || (this.Month == 0) || (this.Day == 0)) return DateTime.UtcNow; // https://sourceforge.net/p/keepass/discussion/329221/thread/07599afd/ try { int dy = (int)this.Year; if(dy > 2999) { Debug.Assert(false); dy = 2999; } int dm = (int)this.Month; if(dm > 12) { Debug.Assert(false); dm = 12; } int dd = (int)this.Day; if(dd > 31) { Debug.Assert(false); dd = 28; } // Day might not exist in month int th = (int)this.Hour; if(th > 23) { Debug.Assert(false); th = 23; } int tm = (int)this.Minute; if(tm > 59) { Debug.Assert(false); tm = 59; } int ts = (int)this.Second; if(ts > 59) { Debug.Assert(false); ts = 59; } return (new DateTime(dy, dm, dd, th, tm, ts, DateTimeKind.Local)).ToUniversalTime(); } catch(Exception) { Debug.Assert(false); } return DateTime.UtcNow; } /// /// Copy data from a DateTime object to the current KdbTime object. /// /// Data source. public void Set(DateTime dt) { DateTime dtLocal = TimeUtil.ToLocal(dt, true); this.Year = (UInt16)dtLocal.Year; this.Month = (Byte)dtLocal.Month; this.Day = (Byte)dtLocal.Day; this.Hour = (Byte)dtLocal.Hour; this.Minute = (Byte)dtLocal.Minute; this.Second = (Byte)dtLocal.Second; } /// /// A KdbTime element that is used to indicate the never expire time. /// public static readonly KdbTime NeverExpireTime = new KdbTime(2999, 12, 28, 23, 59, 59); } /// /// Error codes for various functions (OpenDatabase, etc.). /// public enum KdbErrorCode { /// /// Unknown error occurred. /// Unknown = 0, /// /// Successful function call. /// Success, /// /// Invalid parameters were given. /// InvalidParam, /// /// Not enough memory to perform requested operation. /// NotEnoughMemory, /// /// Invalid key was supplied. /// InvalidKey, /// /// The file could not be read. /// NoFileAccessRead, /// /// The file could not be written. /// NoFileAccessWrite, /// /// A file read error occurred. /// FileErrorRead, /// /// A file write error occurred. /// FileErrorWrite, /// /// Invalid random source was given. /// InvalidRandomSource, /// /// Invalid file structure was detected. /// InvalidFileStructure, /// /// Cryptographic error occurred. /// CryptoError, /// /// Invalid file size was given/detected. /// InvalidFileSize, /// /// Invalid file signature was detected. /// InvalidFileSignature, /// /// Invalid file header was detected. /// InvalidFileHeader, /// /// The keyfile could not be read. /// NoFileAccessReadKey } /// /// Manager class for KDB files. It can load/save databases, add/change/delete /// groups and entries, check for KeePassLibC library existence and version, etc. /// public sealed class KdbManager : IDisposable { private const string DllFile32 = "KeePassLibC32.dll"; private const string DllFile64 = "KeePassLibC64.dll"; private static readonly bool m_bX64 = (Marshal.SizeOf(typeof(IntPtr)) == 8); #if KDB_ANSI private const CharSet DllCharSet = CharSet.Ansi; #else private const CharSet DllCharSet = CharSet.Unicode; #endif private static bool m_bFirstInstance = true; private IntPtr m_pManager = IntPtr.Zero; [DllImport(DllFile32, EntryPoint = "GetKeePassVersion")] private static extern UInt32 GetKeePassVersion32(); [DllImport(DllFile64, EntryPoint = "GetKeePassVersion")] private static extern UInt32 GetKeePassVersion64(); /// /// Get the KeePass version, which the KeePassLibC library supports. /// public static UInt32 KeePassVersion { get { if(m_bX64) return GetKeePassVersion64(); else return GetKeePassVersion32(); } } [DllImport(DllFile32, CharSet = DllCharSet, EntryPoint = "GetKeePassVersionString")] private static extern IntPtr GetKeePassVersionString32(); [DllImport(DllFile64, CharSet = DllCharSet, EntryPoint = "GetKeePassVersionString")] private static extern IntPtr GetKeePassVersionString64(); /// /// Get the KeePass version, which the KeePassLibC library supports /// (the version is returned as a displayable string, if you need to /// compare versions: use the KeePassVersion property). /// public static string KeePassVersionString { #if KDB_ANSI get { if(m_bX64) return Marshal.PtrToStringAnsi(GetKeePassVersionString64()); else return Marshal.PtrToStringAnsi(GetKeePassVersionString32()); } #else get { if(m_bX64) return Marshal.PtrToStringUni(GetKeePassVersionString64()); else return Marshal.PtrToStringUni(GetKeePassVersionString32()); } #endif } [DllImport(DllFile32, EntryPoint = "GetLibraryBuild")] private static extern UInt32 GetLibraryBuild32(); [DllImport(DllFile64, EntryPoint = "GetLibraryBuild")] private static extern UInt32 GetLibraryBuild64(); /// /// Get the library build version. This version has nothing to do with /// the supported KeePass version (see KeePassVersion property). /// public static UInt32 LibraryBuild { get { if(m_bX64) return GetLibraryBuild64(); else return GetLibraryBuild32(); } } [DllImport(DllFile32, EntryPoint = "GetNumberOfEntries")] private static extern UInt32 GetNumberOfEntries32(IntPtr pMgr); [DllImport(DllFile64, EntryPoint = "GetNumberOfEntries")] private static extern UInt32 GetNumberOfEntries64(IntPtr pMgr); /// /// Get the number of entries in this manager instance. /// public UInt32 EntryCount { get { if(m_bX64) return GetNumberOfEntries64(m_pManager); else return GetNumberOfEntries32(m_pManager); } } [DllImport(DllFile32, EntryPoint = "GetNumberOfGroups")] private static extern UInt32 GetNumberOfGroups32(IntPtr pMgr); [DllImport(DllFile64, EntryPoint = "GetNumberOfGroups")] private static extern UInt32 GetNumberOfGroups64(IntPtr pMgr); /// /// Get the number of groups in this manager instance. /// public UInt32 GroupCount { get { if(m_bX64) return GetNumberOfGroups64(m_pManager); else return GetNumberOfGroups32(m_pManager); } } [DllImport(DllFile32, EntryPoint = "GetKeyEncRounds")] private static extern UInt32 GetKeyEncRounds32(IntPtr pMgr); [DllImport(DllFile64, EntryPoint = "GetKeyEncRounds")] private static extern UInt32 GetKeyEncRounds64(IntPtr pMgr); [DllImport(DllFile32, EntryPoint = "SetKeyEncRounds")] private static extern void SetKeyEncRounds32(IntPtr pMgr, UInt32 dwRounds); [DllImport(DllFile64, EntryPoint = "SetKeyEncRounds")] private static extern void SetKeyEncRounds64(IntPtr pMgr, UInt32 dwRounds); /// /// Get or set the number of key transformation rounds (in order to /// make key-searching attacks harder). /// public UInt32 KeyTransformationRounds { get { if(m_bX64) return GetKeyEncRounds64(m_pManager); else return GetKeyEncRounds32(m_pManager); } set { if(m_bX64) SetKeyEncRounds64(m_pManager, value); else SetKeyEncRounds32(m_pManager, value); } } [DllImport(DllFile32, EntryPoint = "InitManager")] private static extern void InitManager32(out IntPtr ppMgr, [MarshalAs(UnmanagedType.Bool)] bool bFirstInstance); [DllImport(DllFile64, EntryPoint = "InitManager")] private static extern void InitManager64(out IntPtr ppMgr, [MarshalAs(UnmanagedType.Bool)] bool bFirstInstance); [DllImport(DllFile32, EntryPoint = "NewDatabase")] private static extern void NewDatabase32(IntPtr pMgr); [DllImport(DllFile64, EntryPoint = "NewDatabase")] private static extern void NewDatabase64(IntPtr pMgr); /// /// Construct a new KDB manager instance. /// public KdbManager() { if(!m_bX64) // Only check 32-bit structures { #if VPF_ALIGN bool bAligned = true; #else bool bAligned = false; #endif // Static structure layout assertions int nExpectedSize = (bAligned ? 52 : 46); KdbGroup g = new KdbGroup(); Debug.Assert(Marshal.SizeOf(g) == nExpectedSize); if(Marshal.SizeOf(g) != nExpectedSize) throw new FormatException("SizeOf(KdbGroup) invalid!"); nExpectedSize = (bAligned ? 92 : 88); KdbEntry e = new KdbEntry(); Debug.Assert(Marshal.SizeOf(e) == nExpectedSize); if(Marshal.SizeOf(e) != nExpectedSize) throw new FormatException("SizeOf(KdbEntry) invalid!"); KdbUuid u = new KdbUuid(); Debug.Assert(Marshal.SizeOf(u) == 16); if(Marshal.SizeOf(u) != 16) throw new FormatException("SizeOf(KdbUuid) invalid!"); nExpectedSize = (bAligned ? 8 : 7); KdbTime t = new KdbTime(); Debug.Assert(Marshal.SizeOf(t) == nExpectedSize); if(Marshal.SizeOf(t) != nExpectedSize) throw new FormatException("SizeOf(KdbTime) invalid!"); } if(m_bX64) KdbManager.InitManager64(out m_pManager, m_bFirstInstance); else KdbManager.InitManager32(out m_pManager, m_bFirstInstance); m_bFirstInstance = false; if(m_pManager == IntPtr.Zero) throw new InvalidOperationException("Failed to initialize manager! DLL installed?"); if(m_bX64) KdbManager.NewDatabase64(m_pManager); else KdbManager.NewDatabase32(m_pManager); } ~KdbManager() { Dispose(false); } public void Dispose() { Dispose(true); GC.SuppressFinalize(this); } [DllImport(DllFile32, EntryPoint = "DeleteManager")] private static extern void DeleteManager32(IntPtr pMgr); [DllImport(DllFile64, EntryPoint = "DeleteManager")] private static extern void DeleteManager64(IntPtr pMgr); private void Dispose(bool bDisposing) { if(m_pManager != IntPtr.Zero) { try { if(m_bX64) KdbManager.DeleteManager64(m_pManager); else KdbManager.DeleteManager32(m_pManager); } catch(Exception) { Debug.Assert(false); } m_pManager = IntPtr.Zero; } } [Obsolete] public void Unload() { Dispose(true); } [DllImport(DllFile32, CharSet = DllCharSet, EntryPoint = "SetMasterKey")] private static extern Int32 SetMasterKey32(IntPtr pMgr, string pszMasterKey, [MarshalAs(UnmanagedType.Bool)] bool bDiskDrive, string pszSecondKey, IntPtr pARI, [MarshalAs(UnmanagedType.Bool)] bool bOverwrite); [DllImport(DllFile64, CharSet = DllCharSet, EntryPoint = "SetMasterKey")] private static extern Int32 SetMasterKey64(IntPtr pMgr, string pszMasterKey, [MarshalAs(UnmanagedType.Bool)] bool bDiskDrive, string pszSecondKey, IntPtr pARI, [MarshalAs(UnmanagedType.Bool)] bool bOverwrite); /// /// Set the master key, which will be used when you call the /// OpenDatabase or SaveDatabase functions. /// /// Master password or path to key file. Must not be null. /// Indicates if a key file is used. /// Path to the key file when both master password /// and key file are used. /// Random source interface. Set this to IntPtr.Zero /// if you want to open a KDB file normally. If you want to create a key file, /// pARI must point to a CNewRandomInterface (see KeePass 1.x /// source code). /// Indicates if the target file should be overwritten when /// creating a new key file. /// Error code (see KdbErrorCode). public KdbErrorCode SetMasterKey(string strMasterKey, bool bDiskDrive, string strSecondKey, IntPtr pARI, bool bOverwrite) { Debug.Assert(strMasterKey != null); if(strMasterKey == null) throw new ArgumentNullException("strMasterKey"); if(m_bX64) return (KdbErrorCode)KdbManager.SetMasterKey64(m_pManager, strMasterKey, bDiskDrive, strSecondKey, pARI, bOverwrite); else return (KdbErrorCode)KdbManager.SetMasterKey32(m_pManager, strMasterKey, bDiskDrive, strSecondKey, pARI, bOverwrite); } [DllImport(DllFile32, CharSet = DllCharSet, EntryPoint = "GetNumberOfItemsInGroup")] private static extern UInt32 GetNumberOfItemsInGroup32(IntPtr pMgr, string pszGroup); [DllImport(DllFile64, CharSet = DllCharSet, EntryPoint = "GetNumberOfItemsInGroup")] private static extern UInt32 GetNumberOfItemsInGroup64(IntPtr pMgr, string pszGroup); /// /// Get the number of entries in a group. /// /// Group name, which identifies the group. Note /// that multiple groups can have the same name, in this case you'll need to /// use the other counting function which uses group IDs. /// Number of entries in the specified group. public UInt32 GetNumberOfEntriesInGroup(string strGroupName) { Debug.Assert(strGroupName != null); if(strGroupName == null) throw new ArgumentNullException("strGroupName"); if(m_bX64) return KdbManager.GetNumberOfItemsInGroup64(m_pManager, strGroupName); else return KdbManager.GetNumberOfItemsInGroup32(m_pManager, strGroupName); } [DllImport(DllFile32, EntryPoint = "GetNumberOfItemsInGroupN")] private static extern UInt32 GetNumberOfItemsInGroupN32(IntPtr pMgr, UInt32 idGroup); [DllImport(DllFile64, EntryPoint = "GetNumberOfItemsInGroupN")] private static extern UInt32 GetNumberOfItemsInGroupN64(IntPtr pMgr, UInt32 idGroup); /// /// Get the number of entries in a group. /// /// Group ID. /// Number of entries in the specified group. public UInt32 GetNumberOfEntriesInGroup(UInt32 uGroupId) { Debug.Assert((uGroupId != 0) && (uGroupId != UInt32.MaxValue)); if((uGroupId == 0) || (uGroupId == UInt32.MaxValue)) throw new ArgumentException("Invalid group ID!"); if(m_bX64) return KdbManager.GetNumberOfItemsInGroupN64(m_pManager, uGroupId); else return KdbManager.GetNumberOfItemsInGroupN32(m_pManager, uGroupId); } [DllImport(DllFile32, EntryPoint = "LockEntryPassword")] private static extern IntPtr LockEntryPassword32(IntPtr pMgr, IntPtr pEntry); [DllImport(DllFile64, EntryPoint = "LockEntryPassword")] private static extern IntPtr LockEntryPassword64(IntPtr pMgr, IntPtr pEntry); [DllImport(DllFile32, EntryPoint = "UnlockEntryPassword")] private static extern IntPtr UnlockEntryPassword32(IntPtr pMgr, IntPtr pEntry); [DllImport(DllFile64, EntryPoint = "UnlockEntryPassword")] private static extern IntPtr UnlockEntryPassword64(IntPtr pMgr, IntPtr pEntry); [DllImport(DllFile32, EntryPoint = "GetEntry")] private static extern IntPtr GetEntry32(IntPtr pMgr, UInt32 dwIndex); [DllImport(DllFile64, EntryPoint = "GetEntry")] private static extern IntPtr GetEntry64(IntPtr pMgr, UInt32 dwIndex); /// /// Get an entry. /// /// Index of the entry. This index must be valid, otherwise /// an ArgumentOutOfRangeException is thrown. /// The requested entry. Note that any modifications to this /// structure won't affect the internal data structures of the manager. public KdbEntry GetEntry(uint uIndex) { Debug.Assert(uIndex < this.EntryCount); IntPtr p; if(m_bX64) p = KdbManager.GetEntry64(m_pManager, uIndex); else p = KdbManager.GetEntry32(m_pManager, uIndex); if(p == IntPtr.Zero) throw new ArgumentOutOfRangeException("uIndex"); if(m_bX64) KdbManager.UnlockEntryPassword64(m_pManager, p); else KdbManager.UnlockEntryPassword32(m_pManager, p); KdbEntry kdbEntry = (KdbEntry)Marshal.PtrToStructure(p, typeof(KdbEntry)); if(m_bX64) KdbManager.LockEntryPassword64(m_pManager, p); else KdbManager.LockEntryPassword32(m_pManager, p); return kdbEntry; } [DllImport(DllFile32, EntryPoint = "GetEntryByGroup")] private static extern IntPtr GetEntryByGroup32(IntPtr pMgr, UInt32 idGroup, UInt32 dwIndex); [DllImport(DllFile64, EntryPoint = "GetEntryByGroup")] private static extern IntPtr GetEntryByGroup64(IntPtr pMgr, UInt32 idGroup, UInt32 dwIndex); /// /// Get an entry in a specific group. /// /// Index of the entry in the group. This index must /// be valid, otherwise an ArgumentOutOfRangeException is thrown. /// ID of the group containing the entry. /// The requested entry. Note that any modifications to this /// structure won't affect the internal data structures of the manager. public KdbEntry GetEntryByGroup(UInt32 uGroupId, UInt32 uIndex) { Debug.Assert((uGroupId != 0) && (uGroupId != UInt32.MaxValue)); if((uGroupId == 0) || (uGroupId == UInt32.MaxValue)) throw new ArgumentException("Invalid group ID!"); Debug.Assert(uIndex < this.EntryCount); IntPtr p; if(m_bX64) p = GetEntryByGroup64(m_pManager, uGroupId, uIndex); else p = GetEntryByGroup32(m_pManager, uGroupId, uIndex); if(p == IntPtr.Zero) throw new ArgumentOutOfRangeException(); if(m_bX64) KdbManager.UnlockEntryPassword64(m_pManager, p); else KdbManager.UnlockEntryPassword32(m_pManager, p); KdbEntry kdbEntry = (KdbEntry)Marshal.PtrToStructure(p, typeof(KdbEntry)); if(m_bX64) KdbManager.LockEntryPassword64(m_pManager, p); else KdbManager.LockEntryPassword32(m_pManager, p); return kdbEntry; } [DllImport(DllFile32, EntryPoint = "GetGroup")] private static extern IntPtr GetGroup32(IntPtr pMgr, UInt32 dwIndex); [DllImport(DllFile64, EntryPoint = "GetGroup")] private static extern IntPtr GetGroup64(IntPtr pMgr, UInt32 dwIndex); /// /// Get a group. /// /// Index of the group. Must be valid, otherwise an /// ArgumentOutOfRangeException is thrown. /// Group structure. public KdbGroup GetGroup(UInt32 uIndex) { Debug.Assert(uIndex < this.GroupCount); IntPtr p; if(m_bX64) p = KdbManager.GetGroup64(m_pManager, uIndex); else p = KdbManager.GetGroup32(m_pManager, uIndex); if(p == IntPtr.Zero) throw new ArgumentOutOfRangeException("uIndex"); return (KdbGroup)Marshal.PtrToStructure(p, typeof(KdbGroup)); } [DllImport(DllFile32, EntryPoint = "GetGroupById")] private static extern IntPtr GetGroupById32(IntPtr pMgr, UInt32 idGroup); [DllImport(DllFile64, EntryPoint = "GetGroupById")] private static extern IntPtr GetGroupById64(IntPtr pMgr, UInt32 idGroup); /// /// Get a group via the GroupID. /// /// ID of the group. /// Group structure. public KdbGroup GetGroupById(UInt32 uGroupId) { Debug.Assert((uGroupId != 0) && (uGroupId != UInt32.MaxValue)); if((uGroupId == 0) || (uGroupId == UInt32.MaxValue)) throw new ArgumentException("Invalid group ID!"); IntPtr p; if(m_bX64) p = KdbManager.GetGroupById64(m_pManager, uGroupId); else p = KdbManager.GetGroupById32(m_pManager, uGroupId); if(p == IntPtr.Zero) throw new ArgumentOutOfRangeException("uGroupId"); return (KdbGroup)Marshal.PtrToStructure(p, typeof(KdbGroup)); } [DllImport(DllFile32, EntryPoint = "GetGroupByIdN")] private static extern UInt32 GetGroupByIdN32(IntPtr pMgr, UInt32 idGroup); [DllImport(DllFile64, EntryPoint = "GetGroupByIdN")] private static extern UInt32 GetGroupByIdN64(IntPtr pMgr, UInt32 idGroup); /// /// Get the group index via the GroupID. /// /// ID of the group. /// Group index. public UInt32 GetGroupByIdN(UInt32 uGroupId) { Debug.Assert((uGroupId != 0) && (uGroupId != UInt32.MaxValue)); if((uGroupId == 0) || (uGroupId == UInt32.MaxValue)) throw new ArgumentException("Invalid group ID!"); if(m_bX64) return KdbManager.GetGroupByIdN64(m_pManager, uGroupId); else return KdbManager.GetGroupByIdN32(m_pManager, uGroupId); } [DllImport(DllFile32, CharSet = DllCharSet, EntryPoint = "OpenDatabase")] private static extern Int32 OpenDatabase32(IntPtr pMgr, string pszFile, IntPtr pRepair); [DllImport(DllFile64, CharSet = DllCharSet, EntryPoint = "OpenDatabase")] private static extern Int32 OpenDatabase64(IntPtr pMgr, string pszFile, IntPtr pRepair); /// /// Open a KDB database. /// /// File path of the database. /// Pointer to a repair information structure. If /// you want to open a Kdb file normally, set this parameter to /// IntPtr.Zero. /// Error code (see KdbErrorCode). public KdbErrorCode OpenDatabase(string strFile, IntPtr pRepairInfo) { Debug.Assert(strFile != null); if(strFile == null) throw new ArgumentNullException("strFile"); if(m_bX64) return (KdbErrorCode)KdbManager.OpenDatabase64(m_pManager, strFile, pRepairInfo); else return (KdbErrorCode)KdbManager.OpenDatabase32(m_pManager, strFile, pRepairInfo); } [DllImport(DllFile32, CharSet = DllCharSet, EntryPoint = "SaveDatabase")] private static extern Int32 SaveDatabase32(IntPtr pMgr, string pszFile); [DllImport(DllFile64, CharSet = DllCharSet, EntryPoint = "SaveDatabase")] private static extern Int32 SaveDatabase64(IntPtr pMgr, string pszFile); /// /// Save the current contents of the manager to a KDB file on disk. /// /// File to create. /// Error code (see KdbErrorCode). public KdbErrorCode SaveDatabase(string strFile) { Debug.Assert(strFile != null); if(strFile == null) throw new ArgumentNullException("strFile"); if(m_bX64) return (KdbErrorCode)KdbManager.SaveDatabase64(m_pManager, strFile); else return (KdbErrorCode)KdbManager.SaveDatabase32(m_pManager, strFile); } /// /// Close current database and create a new and empty one. /// public void NewDatabase() { if(m_bX64) KdbManager.NewDatabase64(m_pManager); else KdbManager.NewDatabase32(m_pManager); } /// /// Get the date/time object representing the 'Never Expires' status. /// /// DateTime object. public static DateTime GetNeverExpireTime() { return KdbTime.NeverExpireTime.ToDateTime(); } [DllImport(DllFile32, CharSet = DllCharSet, EntryPoint = "AddGroup")] [return: MarshalAs(UnmanagedType.Bool)] private static extern bool AddGroup32(IntPtr pMgr, ref KdbGroup pTemplate); [DllImport(DllFile64, CharSet = DllCharSet, EntryPoint = "AddGroup")] [return: MarshalAs(UnmanagedType.Bool)] private static extern bool AddGroup64(IntPtr pMgr, ref KdbGroup pTemplate); /// /// Add a new password group. /// /// Template containing new group information. /// Returns true if the group was created successfully. public bool AddGroup(ref KdbGroup pNewGroup) { if(m_bX64) return KdbManager.AddGroup64(m_pManager, ref pNewGroup); else return KdbManager.AddGroup32(m_pManager, ref pNewGroup); } [DllImport(DllFile32, CharSet = DllCharSet, EntryPoint = "SetGroup")] [return: MarshalAs(UnmanagedType.Bool)] private static extern bool SetGroup32(IntPtr pMgr, UInt32 dwIndex, ref KdbGroup pTemplate); [DllImport(DllFile64, CharSet = DllCharSet, EntryPoint = "SetGroup")] [return: MarshalAs(UnmanagedType.Bool)] private static extern bool SetGroup64(IntPtr pMgr, UInt32 dwIndex, ref KdbGroup pTemplate); /// /// Set/change a password group. /// /// Index of the group to be changed. /// Template containing new group information. /// Returns true if the group was created successfully. public bool SetGroup(UInt32 uIndex, ref KdbGroup pNewGroup) { Debug.Assert(uIndex < this.GroupCount); if(m_bX64) return KdbManager.SetGroup64(m_pManager, uIndex, ref pNewGroup); else return KdbManager.SetGroup32(m_pManager, uIndex, ref pNewGroup); } [DllImport(DllFile32, EntryPoint = "DeleteGroupById")] [return: MarshalAs(UnmanagedType.Bool)] private static extern bool DeleteGroupById32(IntPtr pMgr, UInt32 uGroupId); [DllImport(DllFile64, EntryPoint = "DeleteGroupById")] [return: MarshalAs(UnmanagedType.Bool)] private static extern bool DeleteGroupById64(IntPtr pMgr, UInt32 uGroupId); /// /// Delete a password group. /// /// ID of the group to be deleted. /// If the group has been deleted, the return value is true. public bool DeleteGroupByID(UInt32 uGroupID) { Debug.Assert((uGroupID != 0) && (uGroupID != UInt32.MaxValue)); if((uGroupID == 0) || (uGroupID == UInt32.MaxValue)) throw new ArgumentException("Invalid group ID!"); if(m_bX64) return KdbManager.DeleteGroupById64(m_pManager, uGroupID); else return KdbManager.DeleteGroupById32(m_pManager, uGroupID); } [DllImport(DllFile32, CharSet = DllCharSet, EntryPoint = "AddEntry")] [return: MarshalAs(UnmanagedType.Bool)] private static extern bool AddEntry32(IntPtr pMgr, ref KdbEntry pTemplate); [DllImport(DllFile64, CharSet = DllCharSet, EntryPoint = "AddEntry")] [return: MarshalAs(UnmanagedType.Bool)] private static extern bool AddEntry64(IntPtr pMgr, ref KdbEntry pTemplate); /// /// Add a new password entry. /// /// Template containing new entry information. /// Returns true if the entry was created successfully. public bool AddEntry(ref KdbEntry peNew) { if(m_bX64) return KdbManager.AddEntry64(m_pManager, ref peNew); else return KdbManager.AddEntry32(m_pManager, ref peNew); } [DllImport(DllFile32, CharSet = DllCharSet, EntryPoint = "SetEntry")] [return: MarshalAs(UnmanagedType.Bool)] private static extern bool SetEntry32(IntPtr pMgr, UInt32 dwIndex, ref KdbEntry pTemplate); [DllImport(DllFile64, CharSet = DllCharSet, EntryPoint = "SetEntry")] [return: MarshalAs(UnmanagedType.Bool)] private static extern bool SetEntry64(IntPtr pMgr, UInt32 dwIndex, ref KdbEntry pTemplate); /// /// Set/change a password entry. /// /// Index of the entry to be changed. /// Template containing new entry information. /// Returns true if the entry was created successfully. public bool SetEntry(UInt32 uIndex, ref KdbEntry peNew) { Debug.Assert(uIndex < this.EntryCount); if(m_bX64) return KdbManager.SetEntry64(m_pManager, uIndex, ref peNew); else return KdbManager.SetEntry32(m_pManager, uIndex, ref peNew); } [DllImport(DllFile32, EntryPoint = "DeleteEntry")] [return: MarshalAs(UnmanagedType.Bool)] private static extern bool DeleteEntry32(IntPtr pMgr, UInt32 dwIndex); [DllImport(DllFile64, EntryPoint = "DeleteEntry")] [return: MarshalAs(UnmanagedType.Bool)] private static extern bool DeleteEntry64(IntPtr pMgr, UInt32 dwIndex); /// /// Delete a password entry. /// /// Index of the entry. /// If the entry has been deleted, the return value is true. public bool DeleteEntry(UInt32 uIndex) { Debug.Assert(uIndex < this.EntryCount); if(m_bX64) return KdbManager.DeleteEntry64(m_pManager, uIndex); else return KdbManager.DeleteEntry32(m_pManager, uIndex); } /// /// Helper function to extract file attachments. /// /// Native memory pointer (as stored in the /// BinaryData member of KdbEntry. /// Size in bytes of the memory block. /// Managed byte array. public static byte[] ReadBinary(IntPtr pMemory, uint uSize) { Debug.Assert(pMemory != IntPtr.Zero); if(pMemory == IntPtr.Zero) throw new ArgumentNullException("pMemory"); byte[] pb = new byte[uSize]; if(uSize == 0) return pb; Marshal.Copy(pMemory, pb, 0, (int)uSize); return pb; } } } KeePass/DataExchange/ImportUtil.cs0000664000000000000000000004720713222430406016072 0ustar rootroot/* KeePass Password Safe - The Open-Source Password Manager Copyright (C) 2003-2018 Dominik Reichl This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ using System; using System.Collections.Generic; using System.Text; using System.IO; using System.Windows.Forms; using System.Diagnostics; using System.Xml; using System.Threading; using KeePass.App; using KeePass.DataExchange.Formats; using KeePass.Forms; using KeePass.Native; using KeePass.Resources; using KeePass.UI; using KeePass.Util; using KeePassLib; using KeePassLib.Interfaces; using KeePassLib.Keys; using KeePassLib.Resources; using KeePassLib.Security; using KeePassLib.Serialization; using KeePassLib.Utility; namespace KeePass.DataExchange { public static class ImportUtil { public static bool? Import(PwDatabase pwStorage, out bool bAppendedToRootOnly, Form fParent) { bAppendedToRootOnly = false; if(pwStorage == null) throw new ArgumentNullException("pwStorage"); if(!pwStorage.IsOpen) return null; if(!AppPolicy.Try(AppPolicyId.Import)) return null; ExchangeDataForm dlgFmt = new ExchangeDataForm(); dlgFmt.InitEx(false, pwStorage, pwStorage.RootGroup); if(UIUtil.ShowDialogNotValue(dlgFmt, DialogResult.OK)) return null; Debug.Assert(dlgFmt.ResultFormat != null); if(dlgFmt.ResultFormat == null) { MessageService.ShowWarning(KPRes.ImportFailed); UIUtil.DestroyForm(dlgFmt); return false; } bAppendedToRootOnly = dlgFmt.ResultFormat.ImportAppendsToRootGroupOnly; FileFormatProvider ffp = dlgFmt.ResultFormat; List lConnections = new List(); foreach(string strSelFile in dlgFmt.ResultFiles) lConnections.Add(IOConnectionInfo.FromPath(strSelFile)); UIUtil.DestroyForm(dlgFmt); return Import(pwStorage, ffp, lConnections.ToArray(), false, null, false, fParent); } public static bool? Import(PwDatabase pwDatabase, FileFormatProvider fmtImp, IOConnectionInfo[] vConnections, bool bSynchronize, IUIOperations uiOps, bool bForceSave, Form fParent) { if(pwDatabase == null) throw new ArgumentNullException("pwDatabase"); if(!pwDatabase.IsOpen) return null; if(fmtImp == null) throw new ArgumentNullException("fmtImp"); if(vConnections == null) throw new ArgumentNullException("vConnections"); if(!AppPolicy.Try(AppPolicyId.Import)) return false; if(!fmtImp.TryBeginImport()) return false; bool bUseTempDb = (fmtImp.SupportsUuids || fmtImp.RequiresKey); bool bAllSuccess = true; // if(bSynchronize) { Debug.Assert(vFiles.Length == 1); } IStatusLogger dlgStatus; if(Program.Config.UI.ShowImportStatusDialog) dlgStatus = new OnDemandStatusDialog(false, fParent); else dlgStatus = new UIBlockerStatusLogger(fParent); dlgStatus.StartLogging(PwDefs.ShortProductName + " - " + (bSynchronize ? KPRes.Synchronizing : KPRes.ImportingStatusMsg), false); dlgStatus.SetText(bSynchronize ? KPRes.Synchronizing : KPRes.ImportingStatusMsg, LogStatusType.Info); if(vConnections.Length == 0) { try { fmtImp.Import(pwDatabase, null, dlgStatus); } catch(Exception exSingular) { if((exSingular.Message != null) && (exSingular.Message.Length > 0)) { // slf.SetText(exSingular.Message, LogStatusType.Warning); MessageService.ShowWarning(exSingular); } } dlgStatus.EndLogging(); return true; } foreach(IOConnectionInfo iocIn in vConnections) { Stream s = null; try { s = IOConnection.OpenRead(iocIn); } catch(Exception exFile) { MessageService.ShowWarning(iocIn.GetDisplayName(), exFile); bAllSuccess = false; continue; } if(s == null) { Debug.Assert(false); bAllSuccess = false; continue; } PwDatabase pwImp; if(bUseTempDb) { pwImp = new PwDatabase(); pwImp.New(new IOConnectionInfo(), pwDatabase.MasterKey); pwImp.MemoryProtection = pwDatabase.MemoryProtection.CloneDeep(); } else pwImp = pwDatabase; if(fmtImp.RequiresKey && !bSynchronize) { KeyPromptForm kpf = new KeyPromptForm(); kpf.InitEx(iocIn, false, true); if(UIUtil.ShowDialogNotValue(kpf, DialogResult.OK)) { s.Close(); continue; } pwImp.MasterKey = kpf.CompositeKey; UIUtil.DestroyForm(kpf); } else if(bSynchronize) pwImp.MasterKey = pwDatabase.MasterKey; dlgStatus.SetText((bSynchronize ? KPRes.Synchronizing : KPRes.ImportingStatusMsg) + " (" + iocIn.GetDisplayName() + ")", LogStatusType.Info); try { fmtImp.Import(pwImp, s, dlgStatus); } catch(Exception excpFmt) { string strMsgEx = excpFmt.Message; if(bSynchronize && (excpFmt is InvalidCompositeKeyException)) strMsgEx = KLRes.InvalidCompositeKey + MessageService.NewParagraph + KPRes.SynchronizingHint; MessageService.ShowWarning(strMsgEx); s.Close(); bAllSuccess = false; continue; } s.Close(); if(bUseTempDb) { PwMergeMethod mm; if(!fmtImp.SupportsUuids) mm = PwMergeMethod.CreateNewUuids; else if(bSynchronize) mm = PwMergeMethod.Synchronize; else { ImportMethodForm imf = new ImportMethodForm(); if(UIUtil.ShowDialogNotValue(imf, DialogResult.OK)) continue; mm = imf.MergeMethod; UIUtil.DestroyForm(imf); } try { pwDatabase.MergeIn(pwImp, mm, dlgStatus); } catch(Exception exMerge) { MessageService.ShowWarning(iocIn.GetDisplayName(), KPRes.ImportFailed, exMerge); bAllSuccess = false; continue; } } } if(bSynchronize && bAllSuccess) { Debug.Assert(uiOps != null); if(uiOps == null) throw new ArgumentNullException("uiOps"); dlgStatus.SetText(KPRes.Synchronizing + " (" + KPRes.SavingDatabase + ")", LogStatusType.Info); MainForm mf = Program.MainForm; // Null for KPScript if(mf != null) { try { mf.DocumentManager.ActiveDatabase = pwDatabase; } catch(Exception) { Debug.Assert(false); } } if(uiOps.UIFileSave(bForceSave)) { foreach(IOConnectionInfo ioc in vConnections) { try { // dlgStatus.SetText(KPRes.Synchronizing + " (" + // KPRes.SavingDatabase + " " + ioc.GetDisplayName() + // ")", LogStatusType.Info); string strSource = pwDatabase.IOConnectionInfo.Path; if(!string.Equals(ioc.Path, strSource, StrUtil.CaseIgnoreCmp)) { bool bSaveAs = true; if(pwDatabase.IOConnectionInfo.IsLocalFile() && ioc.IsLocalFile()) { // Do not try to copy an encrypted file; // https://sourceforge.net/p/keepass/discussion/329220/thread/9c9eb989/ // https://msdn.microsoft.com/en-us/library/windows/desktop/aa363851.aspx if((long)(File.GetAttributes(strSource) & FileAttributes.Encrypted) == 0) { File.Copy(strSource, ioc.Path, true); bSaveAs = false; } } if(bSaveAs) pwDatabase.SaveAs(ioc, false, null); } // else { } // No assert (sync on save) if(mf != null) mf.FileMruList.AddItem(ioc.GetDisplayName(), ioc.CloneDeep()); } catch(Exception exSync) { MessageService.ShowWarning(KPRes.SyncFailed, pwDatabase.IOConnectionInfo.GetDisplayName() + MessageService.NewLine + ioc.GetDisplayName(), exSync); bAllSuccess = false; continue; } } } else { MessageService.ShowWarning(KPRes.SyncFailed, pwDatabase.IOConnectionInfo.GetDisplayName()); bAllSuccess = false; } } dlgStatus.EndLogging(); return bAllSuccess; } public static bool? Import(PwDatabase pd, FileFormatProvider fmtImp, IOConnectionInfo iocImp, PwMergeMethod mm, CompositeKey cmpKey) { if(pd == null) { Debug.Assert(false); return false; } if(fmtImp == null) { Debug.Assert(false); return false; } if(iocImp == null) { Debug.Assert(false); return false; } if(cmpKey == null) cmpKey = new CompositeKey(); if(!AppPolicy.Try(AppPolicyId.Import)) return false; if(!fmtImp.TryBeginImport()) return false; PwDatabase pdImp = new PwDatabase(); pdImp.New(new IOConnectionInfo(), cmpKey); pdImp.MemoryProtection = pd.MemoryProtection.CloneDeep(); Stream s = IOConnection.OpenRead(iocImp); if(s == null) throw new FileNotFoundException(iocImp.GetDisplayName() + MessageService.NewLine + KPRes.FileNotFoundError); try { fmtImp.Import(pdImp, s, null); } finally { s.Close(); } pd.MergeIn(pdImp, mm); return true; } public static bool? Synchronize(PwDatabase pwStorage, IUIOperations uiOps, bool bOpenFromUrl, Form fParent) { if(pwStorage == null) throw new ArgumentNullException("pwStorage"); if(!pwStorage.IsOpen) return null; if(!AppPolicy.Try(AppPolicyId.Import)) return null; List vConnections = new List(); if(bOpenFromUrl == false) { OpenFileDialogEx ofd = UIUtil.CreateOpenFileDialog(KPRes.Synchronize, UIUtil.CreateFileTypeFilter(AppDefs.FileExtension.FileExt, KPRes.KdbxFiles, true), 1, null, true, AppDefs.FileDialogContext.Sync); if(ofd.ShowDialog() != DialogResult.OK) return null; foreach(string strSelFile in ofd.FileNames) vConnections.Add(IOConnectionInfo.FromPath(strSelFile)); } else // Open URL { IOConnectionForm iocf = new IOConnectionForm(); iocf.InitEx(false, null, true, true); if(UIUtil.ShowDialogNotValue(iocf, DialogResult.OK)) return null; vConnections.Add(iocf.IOConnectionInfo); UIUtil.DestroyForm(iocf); } return Import(pwStorage, new KeePassKdb2x(), vConnections.ToArray(), true, uiOps, false, fParent); } public static bool? Synchronize(PwDatabase pwStorage, IUIOperations uiOps, IOConnectionInfo iocSyncWith, bool bForceSave, Form fParent) { if(pwStorage == null) throw new ArgumentNullException("pwStorage"); if(!pwStorage.IsOpen) return null; // No assert or throw if(iocSyncWith == null) throw new ArgumentNullException("iocSyncWith"); if(!AppPolicy.Try(AppPolicyId.Import)) return null; List vConnections = new List(); vConnections.Add(iocSyncWith); return Import(pwStorage, new KeePassKdb2x(), vConnections.ToArray(), true, uiOps, bForceSave, fParent); } public static int CountQuotes(string str, int posMax) { int i = 0, n = 0; while(true) { i = str.IndexOf('\"', i); if(i < 0) return n; ++i; if(i > posMax) return n; ++n; } } public static List SplitCsvLine(string strLine, string strDelimiter) { List list = new List(); int nOffset = 0; while(true) { int i = strLine.IndexOf(strDelimiter, nOffset); if(i < 0) break; int nQuotes = CountQuotes(strLine, i); if((nQuotes & 1) == 0) { list.Add(strLine.Substring(0, i)); strLine = strLine.Remove(0, i + strDelimiter.Length); nOffset = 0; } else { nOffset = i + strDelimiter.Length; if(nOffset >= strLine.Length) break; } } list.Add(strLine); return list; } public static bool SetStatus(IStatusLogger slLogger, uint uPercent) { if(slLogger != null) return slLogger.SetProgress(uPercent); return true; } private static readonly string[] m_vTitles = { "title", "system", "account", "entry", "item", "itemname", "item name", "subject", "service", "servicename", "service name", "head", "heading", "card", "product", "provider", "bank", "type", // Non-English names "seite" }; private static readonly string[] m_vUserNames = { "user", "name", "user name", "username", "login name", "email", "e-mail", "id", "userid", "user id", "login", "form_loginname", "wpname", "mail", "loginid", "login id", "log", "uin", "first name", "last name", "card#", "account #", "member", "member #", // Non-English names "nom", "benutzername" }; private static readonly string[] m_vPasswords = { "password", "pass word", "passphrase", "pass phrase", "pass", "code", "code word", "codeword", "secret", "secret word", "key", "keyword", "key word", "keyphrase", "key phrase", "form_pw", "wppassword", "pin", "pwd", "pw", "pword", "p", "serial", "serial#", "license key", "reg #", // Non-English names "passwort", "kennwort" }; private static readonly string[] m_vUrls = { "url", "hyper link", "hyperlink", "link", "host", "hostname", "host name", "server", "address", "hyper ref", "href", "web", "website", "web site", "site", "web-site", // Non-English names "ort", "adresse", "webseite" }; private static readonly string[] m_vNotes = { "note", "notes", "comment", "comments", "memo", "description", "free form", "freeform", "free text", "freetext", "free", // Non-English names "kommentar" }; private static readonly string[] m_vSubstrTitles = { "title", "system", "account", "entry", "item", "subject", "service", "head" }; private static readonly string[] m_vSubstrUserNames = { "user", "name", "id", "login", "mail" }; private static readonly string[] m_vSubstrPasswords = { "pass", "code", "secret", "key", "pw", "pin" }; private static readonly string[] m_vSubstrUrls = { "url", "link", "host", "address", "hyper ref", "href", "web", "site" }; private static readonly string[] m_vSubstrNotes = { "note", "comment", "memo", "description", "free" }; public static string MapNameToStandardField(string strName, bool bAllowFuzzy) { Debug.Assert(strName != null); if(strName == null) throw new ArgumentNullException("strName"); string strFind = strName.ToLower(); if(Array.IndexOf(m_vTitles, strFind) >= 0) return PwDefs.TitleField; if(Array.IndexOf(m_vUserNames, strFind) >= 0) return PwDefs.UserNameField; if(Array.IndexOf(m_vPasswords, strFind) >= 0) return PwDefs.PasswordField; if(Array.IndexOf(m_vUrls, strFind) >= 0) return PwDefs.UrlField; if(Array.IndexOf(m_vNotes, strFind) >= 0) return PwDefs.NotesField; return (bAllowFuzzy ? MapNameSubstringToStandardField(strName) : string.Empty); } private static string MapNameSubstringToStandardField(string strName) { Debug.Assert(strName != null); if(strName == null) throw new ArgumentNullException("strName"); string strFind = strName.ToLower(); // Check for passwords first, then user names ('vb_login_password') foreach(string strPassword in m_vSubstrPasswords) { if(strFind.Contains(strPassword)) return PwDefs.PasswordField; } foreach(string strUserName in m_vSubstrUserNames) { if(strFind.Contains(strUserName)) return PwDefs.UserNameField; } foreach(string strTitle in m_vSubstrTitles) { if(strFind.Contains(strTitle)) return PwDefs.TitleField; } foreach(string strUrl in m_vSubstrUrls) { if(strFind.Contains(strUrl)) return PwDefs.UrlField; } foreach(string strNotes in m_vSubstrNotes) { if(strFind.Contains(strNotes)) return PwDefs.NotesField; } return string.Empty; } public static void AppendToField(PwEntry pe, string strName, string strValue, PwDatabase pdContext) { AppendToField(pe, strName, strValue, pdContext, null, false); } public static void AppendToField(PwEntry pe, string strName, string strValue, PwDatabase pdContext, string strSeparator, bool bOnlyIfNotDup) { // Default separator must be single-line compatible if(strSeparator == null) strSeparator = ", "; bool bProtect = ((pdContext == null) ? false : pdContext.MemoryProtection.GetProtection(strName)); ProtectedString ps = pe.Strings.Get(strName); string strPrev = ((ps != null) ? ps.ReadString() : null); if(ps != null) bProtect = ps.IsProtected; strValue = (strValue ?? string.Empty); if(string.IsNullOrEmpty(strPrev)) pe.Strings.Set(strName, new ProtectedString(bProtect, strValue)); else if(strValue.Length > 0) { bool bAppend = true; if(bOnlyIfNotDup) bAppend &= (strPrev != strValue); if(bAppend) pe.Strings.Set(strName, new ProtectedString(bProtect, strPrev + strSeparator + strValue)); } } public static bool EntryEquals(PwEntry pe1, PwEntry pe2) { if(pe1.ParentGroup == null) return false; if(pe2.ParentGroup == null) return false; if(pe1.ParentGroup.Name != pe2.ParentGroup.Name) return false; if(pe1.Strings.ReadSafe(PwDefs.TitleField) != pe2.Strings.ReadSafe(PwDefs.TitleField)) { return false; } if(pe1.Strings.ReadSafe(PwDefs.UserNameField) != pe2.Strings.ReadSafe(PwDefs.UserNameField)) { return false; } if(pe1.Strings.ReadSafe(PwDefs.PasswordField) != pe2.Strings.ReadSafe(PwDefs.PasswordField)) { return false; } if(pe1.Strings.ReadSafe(PwDefs.UrlField) != pe2.Strings.ReadSafe(PwDefs.UrlField)) { return false; } if(pe1.Strings.ReadSafe(PwDefs.NotesField) != pe2.Strings.ReadSafe(PwDefs.NotesField)) { return false; } return true; } internal static string GuiSendRetrieve(string strSendPrefix) { if(strSendPrefix.Length > 0) GuiSendKeysPrc(strSendPrefix); return GuiRetrieveDataField(); } private static string GuiRetrieveDataField() { ClipboardUtil.Clear(); Application.DoEvents(); GuiSendKeysPrc(@"^c"); try { if(ClipboardUtil.ContainsText()) return ClipboardUtil.GetText(); } catch(Exception) { Debug.Assert(false); } // Opened by other process return string.Empty; } internal static void GuiSendKeysPrc(string strSend) { if(strSend.Length > 0) SendInputEx.SendKeysWait(strSend, false); Application.DoEvents(); Thread.Sleep(100); Application.DoEvents(); } internal static void GuiSendWaitWindowChange(string strSend) { IntPtr ptrCur = NativeMethods.GetForegroundWindowHandle(); ImportUtil.GuiSendKeysPrc(strSend); int nRound = 0; while(true) { Application.DoEvents(); IntPtr ptr = NativeMethods.GetForegroundWindowHandle(); if(ptr != ptrCur) break; ++nRound; if(nRound > 1000) throw new InvalidOperationException(); Thread.Sleep(50); } Thread.Sleep(100); Application.DoEvents(); } internal static string FixUrl(string strUrl) { strUrl = strUrl.Trim(); if((strUrl.Length > 0) && (strUrl.IndexOf(':') < 0) && (strUrl.IndexOf('@') < 0)) { string strNew = ("http://" + strUrl.ToLower()); if(strUrl.IndexOf('/') < 0) strNew += "/"; return strNew; } return strUrl; } } } KeePass/DataExchange/Formats/0000775000000000000000000000000013222430406015034 5ustar rootrootKeePass/DataExchange/Formats/FlexWalletXml17.cs0000664000000000000000000001403713222430404020266 0ustar rootroot/* KeePass Password Safe - The Open-Source Password Manager Copyright (C) 2003-2018 Dominik Reichl This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ using System; using System.Collections.Generic; using System.Text; using System.Xml; using System.IO; using System.Diagnostics; using System.Drawing; using KeePass.Resources; using KeePass.Util; using KeePassLib; using KeePassLib.Interfaces; using KeePassLib.Security; using KeePassLib.Utility; namespace KeePass.DataExchange.Formats { // 1.7 internal sealed class FlexWalletXml17 : FileFormatProvider { public override bool SupportsImport { get { return true; } } public override bool SupportsExport { get { return false; } } public override string FormatName { get { return "FlexWallet XML"; } } public override string DefaultExtension { get { return "xml"; } } public override string ApplicationGroup { get { return KPRes.PasswordManagers; } } public override Image SmallIcon { get { return KeePass.Properties.Resources.B16x16_Imp_FlexWallet; } } private const string ElemRoot = "FlexWallet"; // In 1.7 the node names are Pascal-cased and in 2006 they are // lower-cased. Therefore, compare them case-insensitively. private const string ElemCategory = "Category"; private const string ElemEntry = "Card"; private const string ElemField = "Field"; private const string ElemNotes = "Notes"; private const string AttribData = "Description"; // 1.7 private const string AttribName = "name"; // 2006 public override void Import(PwDatabase pwStorage, Stream sInput, IStatusLogger slLogger) { StreamReader sr = new StreamReader(sInput, Encoding.Default); string strDoc = sr.ReadToEnd(); sr.Close(); ImportFileString(strDoc, pwStorage); } private static void ImportFileString(string strXmlDoc, PwDatabase pwStorage) { XmlDocument doc = new XmlDocument(); doc.LoadXml(strXmlDoc); XmlElement xmlRoot = doc.DocumentElement; Debug.Assert(xmlRoot.Name == ElemRoot); foreach(XmlNode xmlChild in xmlRoot.ChildNodes) { if(xmlChild.Name.Equals(ElemCategory, StrUtil.CaseIgnoreCmp)) ImportCategory(xmlChild, pwStorage.RootGroup, pwStorage); else { Debug.Assert(false); } } } private static void ImportCategory(XmlNode xmlNode, PwGroup pgContainer, PwDatabase pwStorage) { string strName = ReadNameAttrib(xmlNode); if(string.IsNullOrEmpty(strName)) strName = KPRes.Group; PwGroup pg = new PwGroup(true, true, strName, PwIcon.Folder); pgContainer.AddGroup(pg, true); foreach(XmlNode xmlChild in xmlNode.ChildNodes) { if(xmlChild.Name.Equals(ElemEntry, StrUtil.CaseIgnoreCmp)) ImportEntry(xmlChild, pg, pwStorage); else if(xmlChild.Name.Equals(ElemCategory, StrUtil.CaseIgnoreCmp)) ImportCategory(xmlChild, pg, pwStorage); else { Debug.Assert(false); } } } private static void ImportEntry(XmlNode xmlNode, PwGroup pg, PwDatabase pwStorage) { PwEntry pe = new PwEntry(true, true); string strTitle = ReadNameAttrib(xmlNode); if(!string.IsNullOrEmpty(strTitle)) pe.Strings.Set(PwDefs.TitleField, new ProtectedString( pwStorage.MemoryProtection.ProtectTitle, strTitle)); foreach(XmlNode xmlChild in xmlNode) { if(xmlChild.Name.Equals(ElemField, StrUtil.CaseIgnoreCmp)) { string strName = ReadNameAttrib(xmlChild); if(string.IsNullOrEmpty(strName)) continue; string strValue = XmlUtil.SafeInnerText(xmlChild); string strKpName = ImportUtil.MapNameToStandardField(strName, true); if(string.IsNullOrEmpty(strKpName)) strKpName = strName; ImportUtil.AppendToField(pe, strKpName, strValue, pwStorage); } else if(xmlChild.Name.Equals(ElemNotes, StrUtil.CaseIgnoreCmp)) ImportUtil.AppendToField(pe, PwDefs.NotesField, XmlUtil.SafeInnerText(xmlChild), pwStorage); else { Debug.Assert(false); } } // RenameFields(pe); pg.AddEntry(pe, true); } private static string ReadNameAttrib(XmlNode xmlNode) { if(xmlNode == null) { Debug.Assert(false); return string.Empty; } try { if(xmlNode.Attributes.GetNamedItem(AttribData) != null) // 1.7 return (xmlNode.Attributes[AttribData].Value ?? string.Empty); if(xmlNode.Attributes.GetNamedItem(AttribName) != null) // 2006 return (xmlNode.Attributes[AttribName].Value ?? string.Empty); Debug.Assert(false); } catch(Exception) { Debug.Assert(false); } return string.Empty; } /* private static void RenameFields(PwEntry pe) { string[] vMap = new string[] { "Acct #", PwDefs.UserNameField, "Subject", PwDefs.UserNameField, "Location", PwDefs.UserNameField, "Combination", PwDefs.PasswordField, "Username", PwDefs.UserNameField, "Website", PwDefs.UrlField, "Serial #", PwDefs.PasswordField, "Product ID", PwDefs.UserNameField }; Debug.Assert((vMap.Length % 2) == 0); for(int i = 0; i < vMap.Length; i += 2) { string strFrom = vMap[i], strTo = vMap[i + 1]; if(pe.Strings.ReadSafe(strTo).Length > 0) continue; string strData = pe.Strings.ReadSafe(strFrom); if(strData.Length > 0) { pe.Strings.Set(strTo, new ProtectedString(false, strData)); if(pe.Strings.Remove(strFrom) == false) { Debug.Assert(false); } } } } */ } } KeePass/DataExchange/Formats/Spamex20070328.cs0000664000000000000000000002204013222430406017444 0ustar rootroot/* KeePass Password Safe - The Open-Source Password Manager Copyright (C) 2003-2018 Dominik Reichl This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ using System; using System.Collections.Generic; using System.Text; using System.IO; using System.Windows.Forms; using System.Drawing; using System.Net; using System.Net.Security; using System.Security.Cryptography.X509Certificates; using KeePass.Forms; using KeePass.Resources; using KeePass.UI; using KeePass.Util; using KeePassLib; using KeePassLib.Interfaces; using KeePassLib.Resources; using KeePassLib.Security; using KeePassLib.Utility; namespace KeePass.DataExchange.Formats { // Originally written on 2007-03-28, updated on 2012-04-15 internal sealed class Spamex20070328 : FileFormatProvider { public override bool SupportsImport { get { return true; } } public override bool SupportsExport { get { return false; } } public override string FormatName { get { return "Spamex.com"; } } public override string ApplicationGroup { get { return KPRes.WebSites; } } public override bool ImportAppendsToRootGroupOnly { get { return true; } } public override bool RequiresFile { get { return false; } } public override Image SmallIcon { get { return KeePass.Properties.Resources.B16x16_WWW; } } private const string UrlDomain = "www.spamex.com"; private const string UrlBase = "https://www.spamex.com"; private const string UrlLoginPage = "https://www.spamex.com/tool/"; private const string UrlIndexPage = "https://www.spamex.com/tool/listaliases.cfm"; private const string UrlIndexAliasLink = ""; private const string StrTabLinkUrl = "/tool/listaliases.cfm"; public override void Import(PwDatabase pwStorage, Stream sInput, IStatusLogger slLogger) { slLogger.SetText("> Spamex.com...", LogStatusType.Info); SingleLineEditForm dlgUser = new SingleLineEditForm(); dlgUser.InitEx("Spamex.com", KPRes.WebSiteLogin + " - " + KPRes.UserName, KPRes.UserNamePrompt, KeePass.Properties.Resources.B48x48_WWW, string.Empty, null); if(UIUtil.ShowDialogNotValue(dlgUser, DialogResult.OK)) return; string strUser = dlgUser.ResultString; UIUtil.DestroyForm(dlgUser); SingleLineEditForm dlgPassword = new SingleLineEditForm(); dlgPassword.InitEx("Spamex.com", KPRes.WebSiteLogin + " - " + KPRes.Password, KPRes.PasswordPrompt, KeePass.Properties.Resources.B48x48_WWW, string.Empty, null); if(UIUtil.ShowDialogNotValue(dlgPassword, DialogResult.OK)) return; string strPassword = dlgPassword.ResultString; UIUtil.DestroyForm(dlgPassword); RemoteCertificateValidationCallback pPrevCertCb = ServicePointManager.ServerCertificateValidationCallback; ServicePointManager.ServerCertificateValidationCallback = delegate(object sender, X509Certificate certificate, X509Chain chain, SslPolicyErrors sslPolicyErrors) { return true; }; try { slLogger.SetText(KPRes.ImportingStatusMsg, LogStatusType.Info); string strPostData = @"toollogin=&MetaDomain=&LoginEmail=" + strUser + @"&LoginPassword=" + strPassword + @"&Remember=1"; List> vCookies; string strMain = NetUtil.WebPageLogin(new Uri(UrlLoginPage), strPostData, out vCookies); if(strMain.IndexOf("Welcome " + strUser + "") < 0) { MessageService.ShowWarning(KPRes.InvalidUserPassword); return; } string strIndexPage = NetUtil.WebPageGetWithCookies(new Uri(UrlIndexPage), vCookies, UrlDomain); ImportIndex(pwStorage, strIndexPage, vCookies, slLogger); int nOffset = 0; List vSubPages = new List(); while(true) { string strLink = StrUtil.GetStringBetween(strIndexPage, nOffset, StrTabLinksStart, StrTabLinksEnd, out nOffset); ++nOffset; if(strLink.Length == 0) break; if(!strLink.StartsWith(StrTabLinkUrl)) continue; if(vSubPages.IndexOf(strLink) >= 0) continue; vSubPages.Add(strLink); string strSubPage = NetUtil.WebPageGetWithCookies(new Uri( UrlBase + strLink), vCookies, UrlDomain); ImportIndex(pwStorage, strSubPage, vCookies, slLogger); } } finally { ServicePointManager.ServerCertificateValidationCallback = pPrevCertCb; } } private static void ImportIndex(PwDatabase pwStorage, string strIndexPage, List> vCookies, IStatusLogger slf) { int nOffset = 0; while(true) { int nStart = strIndexPage.IndexOf(UrlIndexAliasLink, nOffset); if(nStart < 0) break; nStart += UrlIndexAliasLink.Length; StringBuilder sbCode = new StringBuilder(); while(true) { if(strIndexPage[nStart] == '\"') break; sbCode.Append(strIndexPage[nStart]); ++nStart; } ImportAccount(pwStorage, sbCode.ToString(), vCookies, slf); nOffset = nStart + 1; } } private static void ImportAccount(PwDatabase pwStorage, string strID, List> vCookies, IStatusLogger slf) { string strPage = NetUtil.WebPageGetWithCookies(new Uri( UrlAccountPage + strID), vCookies, UrlDomain); PwEntry pe = new PwEntry(true, true); pwStorage.RootGroup.AddEntry(pe, true); string str; string strTitle = StrUtil.GetStringBetween(strPage, 0, "Subject : ", ""); if(strTitle.StartsWith("")) strTitle = strTitle.Substring(3, strTitle.Length - 3); pe.Strings.Set(PwDefs.TitleField, new ProtectedString( pwStorage.MemoryProtection.ProtectTitle, strTitle)); string strUser = StrUtil.GetStringBetween(strPage, 0, "Site Username : ", ""); if(strUser.StartsWith("")) strUser = strUser.Substring(3, strUser.Length - 3); pe.Strings.Set(PwDefs.UserNameField, new ProtectedString( pwStorage.MemoryProtection.ProtectUserName, strUser)); str = StrUtil.GetStringBetween(strPage, 0, "Site Password : ", ""); if(str.StartsWith("")) str = str.Substring(3, str.Length - 3); pe.Strings.Set(PwDefs.PasswordField, new ProtectedString( pwStorage.MemoryProtection.ProtectPassword, str)); str = StrUtil.GetStringBetween(strPage, 0, "Site Domain : ", ""); if(str.StartsWith("")) str = str.Substring(3, str.Length - 3); pe.Strings.Set(PwDefs.UrlField, new ProtectedString( pwStorage.MemoryProtection.ProtectUrl, str)); str = StrUtil.GetStringBetween(strPage, 0, "Notes : ", ""); if(str.StartsWith("")) str = str.Substring(3, str.Length - 3); pe.Strings.Set(PwDefs.NotesField, new ProtectedString( pwStorage.MemoryProtection.ProtectNotes, str)); str = StrUtil.GetStringBetween(strPage, 0, "Address: ", ""); if(str.StartsWith("")) str = str.Substring(3, str.Length - 3); pe.Strings.Set("Address", new ProtectedString(false, str)); str = StrUtil.GetStringBetween(strPage, 0, "Forwards to: ", ""); if(str.StartsWith("")) str = str.Substring(3, str.Length - 3); pe.Strings.Set("Forward To", new ProtectedString(false, str)); str = StrUtil.GetStringBetween(strPage, 0, "Reply-To Messages: ", ""); if(str.StartsWith("")) str = str.Substring(3, str.Length - 3); pe.Strings.Set("Reply-To Messages", new ProtectedString(false, str)); str = StrUtil.GetStringBetween(strPage, 0, "Allow Reply From: ", ""); if(str.StartsWith("")) str = str.Substring(3, str.Length - 3); pe.Strings.Set("Allow Reply From", new ProtectedString(false, str)); str = StrUtil.GetStringBetween(strPage, 0, "Filter Mode: ", ""); if(str.StartsWith("")) str = str.Substring(3, str.Length - 3); pe.Strings.Set("Filter Mode", new ProtectedString(false, str)); str = StrUtil.GetStringBetween(strPage, 0, "Created: ", ""); if(str.StartsWith("")) str = str.Substring(3, str.Length - 3); pe.Strings.Set("Created", new ProtectedString(false, str)); slf.SetText(strTitle + " - " + strUser + " (" + strID + ")", LogStatusType.Info); if(!slf.ContinueWork()) throw new InvalidOperationException(string.Empty); } } } KeePass/DataExchange/Formats/PinsTxt450.cs0000664000000000000000000001023113222430404017220 0ustar rootroot/* KeePass Password Safe - The Open-Source Password Manager Copyright (C) 2003-2018 Dominik Reichl This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ using System; using System.Collections.Generic; using System.Diagnostics; using System.Drawing; using System.IO; using System.Text; using System.Windows.Forms; using KeePass.Resources; using KeePassLib; using KeePassLib.Interfaces; using KeePassLib.Security; using KeePassLib.Utility; namespace KeePass.DataExchange.Formats { // 4.50 internal sealed class PinsTxt450 : FileFormatProvider { private const string FirstLine = "\"Category\"\t\"System\"\t\"User\"\t" + "\"Password\"\t\"URL/Comments\"\t\"Custom\"\t\"Start date\"\t\"Expires\"\t" + "\"More info\""; private const string FieldSeparator = "\"\t\""; public override bool SupportsImport { get { return true; } } public override bool SupportsExport { get { return false; } } public override string FormatName { get { return "PINs TXT"; } } public override string DefaultExtension { get { return "txt"; } } public override string ApplicationGroup { get { return KPRes.PasswordManagers; } } public override Image SmallIcon { get { return KeePass.Properties.Resources.B16x16_Imp_PINs; } } public override void Import(PwDatabase pwStorage, Stream sInput, IStatusLogger slLogger) { StreamReader sr = new StreamReader(sInput, Encoding.Default); string strData = sr.ReadToEnd(); sr.Close(); string[] vLines = strData.Split(new char[]{ '\r', '\n' }); bool bFirst = true; foreach(string strLine in vLines) { if(bFirst) { if(strLine != FirstLine) throw new FormatException("Format error. First line is invalid. Read the documentation."); bFirst = false; } else if(strLine.Length > 5) ImportLine(strLine, pwStorage); } } private static void ImportLine(string strLine, PwDatabase pwStorage) { string[] vParts = strLine.Split(new string[] { FieldSeparator }, StringSplitOptions.None); Debug.Assert(vParts.Length == 9); if(vParts.Length != 9) throw new FormatException("Line:\r\n" + strLine); vParts[0] = vParts[0].Remove(0, 1); vParts[8] = vParts[8].Substring(0, vParts[8].Length - 1); vParts[8] = vParts[8].Replace("||", "\r\n"); PwGroup pg = pwStorage.RootGroup.FindCreateGroup(vParts[0], true); PwEntry pe = new PwEntry(true, true); pg.AddEntry(pe, true); pe.Strings.Set(PwDefs.TitleField, new ProtectedString( pwStorage.MemoryProtection.ProtectTitle, vParts[1])); pe.Strings.Set(PwDefs.UserNameField, new ProtectedString( pwStorage.MemoryProtection.ProtectUserName, vParts[2])); pe.Strings.Set(PwDefs.PasswordField, new ProtectedString( pwStorage.MemoryProtection.ProtectPassword, vParts[3])); pe.Strings.Set(PwDefs.UrlField, new ProtectedString( pwStorage.MemoryProtection.ProtectUrl, vParts[4])); if(vParts[5].Length > 0) pe.Strings.Set("Custom", new ProtectedString(false, vParts[5])); DateTime dt; if((vParts[6].Length > 0) && DateTime.TryParse(vParts[6], out dt)) pe.CreationTime = pe.LastModificationTime = pe.LastAccessTime = TimeUtil.ToUtc(dt, false); if((vParts[7].Length > 0) && DateTime.TryParse(vParts[7], out dt)) { pe.ExpiryTime = TimeUtil.ToUtc(dt, false); pe.Expires = true; } pe.Strings.Set(PwDefs.NotesField, new ProtectedString( pwStorage.MemoryProtection.ProtectNotes, vParts[8])); } } } KeePass/DataExchange/Formats/DataVaultCsv47.cs0000664000000000000000000000640613222430404020103 0ustar rootroot/* KeePass Password Safe - The Open-Source Password Manager Copyright (C) 2003-2018 Dominik Reichl This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ using System; using System.Collections.Generic; using System.Text; using System.IO; using System.Diagnostics; using System.Globalization; using System.Drawing; using KeePass.Resources; using KeePassLib; using KeePassLib.Interfaces; using KeePassLib.Security; namespace KeePass.DataExchange.Formats { // 4.7.35 internal sealed class DataVaultCsv47 : FileFormatProvider { public override bool SupportsImport { get { return true; } } public override bool SupportsExport { get { return false; } } public override string FormatName { get { return "DataVault CSV"; } } public override string DefaultExtension { get { return "csv"; } } public override string ApplicationGroup { get { return KPRes.PasswordManagers; } } public override bool ImportAppendsToRootGroupOnly { get { return true; } } public override Image SmallIcon { get { return KeePass.Properties.Resources.B16x16_Imp_DataVault; } } public override void Import(PwDatabase pwStorage, Stream sInput, IStatusLogger slLogger) { StreamReader sr = new StreamReader(sInput, Encoding.Default); string strData = sr.ReadToEnd(); sr.Close(); // Fix broken newlines strData = strData.Replace("\r\r\n", "\r\n"); CsvStreamReader csv = new CsvStreamReader(strData, false); while(true) { string[] v = csv.ReadLine(); if(v == null) break; if(v.Length == 0) continue; PwEntry pe = new PwEntry(true, true); pwStorage.RootGroup.AddEntry(pe, true); pe.Strings.Set(PwDefs.TitleField, new ProtectedString( pwStorage.MemoryProtection.ProtectTitle, v[0])); int p = 1; while((p + 1) < v.Length) { string strMapped = ImportUtil.MapNameToStandardField(v[p], true); string strKey = (string.IsNullOrEmpty(strMapped) ? v[p] : strMapped); string strValue = v[p + 1]; p += 2; if((strKey.Length == 0) && (strValue.Length == 0)) continue; AppendToString(pe, strKey, strValue); } if((p < v.Length) && !string.IsNullOrEmpty(v[p])) AppendToString(pe, PwDefs.NotesField, v[p]); } } private static void AppendToString(PwEntry pe, string strKey, string strValue) { if(pe.Strings.ReadSafe(strKey).Length > 0) { pe.Strings.Set(strKey, new ProtectedString(false, pe.Strings.ReadSafe(strKey) + ", " + strValue)); } else pe.Strings.Set(strKey, new ProtectedString(false, strValue)); } } } KeePass/DataExchange/Formats/MozillaBookmarksJson100.cs0000664000000000000000000001675613222430404021733 0ustar rootroot/* KeePass Password Safe - The Open-Source Password Manager Copyright (C) 2003-2018 Dominik Reichl This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ using System; using System.Collections.Generic; using System.Text; using System.IO; using System.Diagnostics; using System.Drawing; using KeePass.Resources; using KeePassLib; using KeePassLib.Interfaces; using KeePassLib.Security; using KeePassLib.Utility; namespace KeePass.DataExchange.Formats { // 1.00 internal sealed class MozillaBookmarksJson100 : FileFormatProvider { public override bool SupportsImport { get { return true; } } public override bool SupportsExport { get { return false; } } public override string FormatName { get { return "Mozilla Bookmarks JSON"; } } public override string DefaultExtension { get { return "json"; } } public override string ApplicationGroup { get { return KPRes.Browser; } } private const string m_strGroup = "children"; public override Image SmallIcon { get { return KeePass.Properties.Resources.B16x16_ASCII; } } public override void Import(PwDatabase pwStorage, Stream sInput, IStatusLogger slLogger) { StreamReader sr = new StreamReader(sInput, StrUtil.Utf8); string strContent = sr.ReadToEnd(); sr.Close(); if(string.IsNullOrEmpty(strContent)) return; CharStream cs = new CharStream(strContent); Dictionary> dTags = new Dictionary>(); List lCreatedEntries = new List(); JsonObject jRoot = new JsonObject(cs); AddObject(pwStorage.RootGroup, jRoot, pwStorage, false, dTags, lCreatedEntries); Debug.Assert(cs.PeekChar(true) == char.MinValue); // Assign tags foreach(PwEntry pe in lCreatedEntries) { string strUri = pe.Strings.ReadSafe(PwDefs.UrlField); if(strUri.Length == 0) continue; foreach(KeyValuePair> kvp in dTags) { foreach(string strTagUri in kvp.Value) { if(strUri.Equals(strTagUri, StrUtil.CaseIgnoreCmp)) pe.AddTag(kvp.Key); } } } } private static void AddObject(PwGroup pgStorage, JsonObject jObject, PwDatabase pwContext, bool bCreateSubGroups, Dictionary> dTags, List lCreatedEntries) { JsonValue jvRoot; jObject.Items.TryGetValue("root", out jvRoot); string strRoot = (((jvRoot != null) ? jvRoot.ToString() : null) ?? string.Empty); if(strRoot.Equals("tagsFolder", StrUtil.CaseIgnoreCmp)) { ImportTags(jObject, dTags); return; } if(jObject.Items.ContainsKey(m_strGroup)) { JsonArray jArray = (jObject.Items[m_strGroup].Value as JsonArray); if(jArray == null) { Debug.Assert(false); return; } PwGroup pgNew; if(bCreateSubGroups) { pgNew = new PwGroup(true, true); pgStorage.AddGroup(pgNew, true); if(jObject.Items.ContainsKey("title")) pgNew.Name = ((jObject.Items["title"].Value != null) ? jObject.Items["title"].Value.ToString() : string.Empty); } else pgNew = pgStorage; foreach(JsonValue jValue in jArray.Values) { JsonObject objSub = (jValue.Value as JsonObject); if(objSub != null) AddObject(pgNew, objSub, pwContext, true, dTags, lCreatedEntries); else { Debug.Assert(false); } } return; } PwEntry pe = new PwEntry(true, true); SetString(pe, "Index", false, jObject, "index"); SetString(pe, PwDefs.TitleField, pwContext.MemoryProtection.ProtectTitle, jObject, "title"); SetString(pe, "ID", false, jObject, "id"); SetString(pe, PwDefs.UrlField, pwContext.MemoryProtection.ProtectUrl, jObject, "uri"); SetString(pe, "CharSet", false, jObject, "charset"); if(jObject.Items.ContainsKey("annos")) { JsonArray vAnnos = (jObject.Items["annos"].Value as JsonArray); if(vAnnos != null) { foreach(JsonValue jv in vAnnos.Values) { if(jv == null) { Debug.Assert(false); continue; } JsonObject jo = (jv.Value as JsonObject); if(jo == null) { Debug.Assert(false); continue; } JsonValue jvAnnoName, jvAnnoValue; jo.Items.TryGetValue("name", out jvAnnoName); jo.Items.TryGetValue("value", out jvAnnoValue); if((jvAnnoName == null) || (jvAnnoValue == null)) continue; string strAnnoName = jvAnnoName.ToString(); string strAnnoValue = jvAnnoValue.ToString(); if((strAnnoName == null) || (strAnnoValue == null)) continue; if(strAnnoName == "bookmarkProperties/description") pe.Strings.Set(PwDefs.NotesField, new ProtectedString( pwContext.MemoryProtection.ProtectNotes, strAnnoValue)); } } } if((pe.Strings.ReadSafe(PwDefs.TitleField).Length > 0) || (pe.Strings.ReadSafe(PwDefs.UrlField).Length > 0)) { pgStorage.AddEntry(pe, true); lCreatedEntries.Add(pe); } } private static void SetString(PwEntry pe, string strEntryKey, bool bProtect, JsonObject jObject, string strObjectKey) { if(!jObject.Items.ContainsKey(strObjectKey)) return; object obj = jObject.Items[strObjectKey].Value; if(obj == null) return; pe.Strings.Set(strEntryKey, new ProtectedString(bProtect, obj.ToString())); } private static void ImportTags(JsonObject jTagsRoot, Dictionary> dTags) { try { JsonValue jTags = jTagsRoot.Items["children"]; if(jTags == null) { Debug.Assert(false); return; } JsonArray arTags = (jTags.Value as JsonArray); if(arTags == null) { Debug.Assert(false); return; } foreach(JsonValue jvTag in arTags.Values) { JsonObject jTag = (jvTag.Value as JsonObject); if(jTag == null) { Debug.Assert(false); continue; } JsonValue jvName = jTag.Items["title"]; if(jvName == null) { Debug.Assert(false); continue; } string strName = jvName.ToString(); if(string.IsNullOrEmpty(strName)) { Debug.Assert(false); continue; } List lUris; dTags.TryGetValue(strName, out lUris); if(lUris == null) { lUris = new List(); dTags[strName] = lUris; } JsonValue jvUrls = jTag.Items["children"]; if(jvUrls == null) { Debug.Assert(false); continue; } JsonArray arUrls = (jvUrls.Value as JsonArray); if(arUrls == null) { Debug.Assert(false); continue; } foreach(JsonValue jvPlace in arUrls.Values) { JsonObject jUrl = (jvPlace.Value as JsonObject); if(jUrl == null) { Debug.Assert(false); continue; } JsonValue jvUri = jUrl.Items["uri"]; if(jvUri == null) { Debug.Assert(false); continue; } string strUri = jvUri.ToString(); if(!string.IsNullOrEmpty(strUri)) lUris.Add(strUri); } } } catch(Exception) { Debug.Assert(false); } } } } KeePass/DataExchange/Formats/RevelationXml04.cs0000664000000000000000000001432413222430406020324 0ustar rootroot/* KeePass Password Safe - The Open-Source Password Manager Copyright (C) 2003-2018 Dominik Reichl This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ using System; using System.Collections.Generic; using System.Text; using System.Diagnostics; using System.Drawing; using System.IO; using System.Xml; using KeePass.Resources; using KeePass.Util; using KeePassLib; using KeePassLib.Interfaces; using KeePassLib.Utility; using KeePassLib.Security; namespace KeePass.DataExchange.Formats { internal sealed class RevelationXml04 : FileFormatProvider { public override bool SupportsImport { get { return true; } } public override bool SupportsExport { get { return false; } } public override string FormatName { get { return "Revelation XML"; } } public override string DefaultExtension { get { return "xml"; } } public override string ApplicationGroup { get { return KPRes.PasswordManagers; } } public override Image SmallIcon { get { return KeePass.Properties.Resources.B16x16_Imp_Revelation; } } public override void Import(PwDatabase pwStorage, Stream sInput, IStatusLogger slLogger) { StreamReader sr = new StreamReader(sInput, Encoding.UTF8); string strDoc = sr.ReadToEnd(); sr.Close(); XmlDocument doc = new XmlDocument(); doc.LoadXml(strDoc); ProcessEntries(pwStorage, pwStorage.RootGroup, doc.DocumentElement.ChildNodes); } private static void ProcessEntries(PwDatabase pd, PwGroup pgParent, XmlNodeList xlNodes) { foreach(XmlNode xmlChild in xlNodes) { if(xmlChild.Name == "entry") { XmlNode xnType = xmlChild.Attributes.GetNamedItem("type"); if(xnType == null) { Debug.Assert(false); } else { if(xnType.Value == "folder") ImportGroup(pd, pgParent, xmlChild); else ImportEntry(pd, pgParent, xmlChild); } } } } private static void ImportGroup(PwDatabase pd, PwGroup pgParent, XmlNode xmlNode) { PwGroup pg = new PwGroup(true, true); foreach(XmlNode xmlChild in xmlNode.ChildNodes) { if(xmlChild.Name == "name") pg.Name = XmlUtil.SafeInnerText(xmlChild); else if(xmlChild.Name == "description") pg.Notes = XmlUtil.SafeInnerText(xmlChild); else if(xmlChild.Name == "entry") { } else if(xmlChild.Name == "updated") pg.LastModificationTime = ImportTime(xmlChild); else { Debug.Assert(false); } } pgParent.AddGroup(pg, true); ProcessEntries(pd, pg, xmlNode.ChildNodes); } private static void ImportEntry(PwDatabase pd, PwGroup pgParent, XmlNode xmlNode) { PwEntry pe = new PwEntry(true, true); pgParent.AddEntry(pe, true); foreach(XmlNode xmlChild in xmlNode.ChildNodes) { if(xmlChild.Name == "name") pe.Strings.Set(PwDefs.TitleField, new ProtectedString( pd.MemoryProtection.ProtectTitle, XmlUtil.SafeInnerText(xmlChild))); else if(xmlChild.Name == "description") pe.Strings.Set(PwDefs.NotesField, new ProtectedString( pd.MemoryProtection.ProtectNotes, XmlUtil.SafeInnerText(xmlChild))); else if(xmlChild.Name == "updated") pe.LastModificationTime = ImportTime(xmlChild); else if(xmlChild.Name == "field") { XmlNode xnName = xmlChild.Attributes.GetNamedItem("id"); if(xnName == null) { Debug.Assert(false); } else { KeyValuePair kvp = MapFieldName(xnName.Value, pd); pe.Strings.Set(kvp.Key, new ProtectedString(kvp.Value, XmlUtil.SafeInnerText(xmlChild))); } } else { Debug.Assert(false); } } } private static KeyValuePair MapFieldName(string strFieldName, PwDatabase pdContext) { switch(strFieldName) { case "creditcard-cardnumber": case "generic-username": case "generic-location": case "phone-phonenumber": return new KeyValuePair(PwDefs.UserNameField, pdContext.MemoryProtection.ProtectUserName); case "generic-code": case "generic-password": case "generic-pin": return new KeyValuePair(PwDefs.PasswordField, pdContext.MemoryProtection.ProtectPassword); case "generic-hostname": case "generic-url": return new KeyValuePair(PwDefs.UrlField, pdContext.MemoryProtection.ProtectUrl); case "creditcard-cardtype": return new KeyValuePair("Card Type", false); case "creditcard-expirydate": return new KeyValuePair(KPRes.ExpiryTime, false); case "creditcard-ccv": return new KeyValuePair("CCV Number", false); case "generic-certificate": return new KeyValuePair("Certificate", false); case "generic-keyfile": return new KeyValuePair("Key File", false); case "generic-database": return new KeyValuePair(KPRes.Database, false); case "generic-email": return new KeyValuePair(KPRes.EMail, false); case "generic-port": return new KeyValuePair("Port", false); case "generic-domain": return new KeyValuePair("Domain", false); default: Debug.Assert(false); break; } return new KeyValuePair(strFieldName, false); } private static DateTime ImportTime(XmlNode xn) { string str = XmlUtil.SafeInnerText(xn); double dtUnix; if(!double.TryParse(str, out dtUnix)) { Debug.Assert(false); } else return TimeUtil.ConvertUnixTime(dtUnix); return DateTime.UtcNow; } } } KeePass/DataExchange/Formats/SplashIdCsv402.cs0000664000000000000000000002502113222430406017774 0ustar rootroot/* KeePass Password Safe - The Open-Source Password Manager Copyright (C) 2003-2018 Dominik Reichl This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ using System; using System.Collections.Generic; using System.Text; using System.Drawing; using System.IO; using System.Diagnostics; using KeePass.Resources; using KeePassLib; using KeePassLib.Interfaces; using KeePassLib.Security; using KeePassLib.Utility; namespace KeePass.DataExchange.Formats { // 3.4-5.3+, types from web 2016-12 (version 8.1.1.925) internal sealed class SplashIdCsv402 : FileFormatProvider { public override bool SupportsImport { get { return true; } } public override bool SupportsExport { get { return false; } } public override string FormatName { get { return "SplashID CSV"; } } public override string DefaultExtension { get { return "csv"; } } public override string ApplicationGroup { get { return KPRes.PasswordManagers; } } public override bool ImportAppendsToRootGroupOnly { get { return false; } } public override Image SmallIcon { get { return KeePass.Properties.Resources.B16x16_Imp_SplashID; } } private const string StrHeader = "SplashID Export File"; private static SplashIdMapping[] m_vMappings = null; private static SplashIdMapping[] SplashIdMappings { get { if(m_vMappings != null) return m_vMappings; m_vMappings = new SplashIdMapping[] { new SplashIdMapping("Addresses", PwIcon.UserCommunication, new string[] { PwDefs.TitleField, // Name PwDefs.NotesField, // Address PwDefs.NotesField, // Address 2 PwDefs.NotesField, // City PwDefs.NotesField, // State PwDefs.NotesField, // Zip Code PwDefs.NotesField, // Country PwDefs.UserNameField, // Email PwDefs.NotesField }), // Phone new SplashIdMapping("Bank Accounts", PwIcon.Homebanking, new string[] { PwDefs.TitleField, PwDefs.UserNameField, PwDefs.PasswordField, "Name", "Branch", "Phone #" }), new SplashIdMapping("Bank Accts", PwIcon.Homebanking, new string[] { PwDefs.TitleField, PwDefs.UserNameField, PwDefs.PasswordField, "Name", "Branch", "Phone #" }), new SplashIdMapping("Birthdays", PwIcon.UserCommunication, new string[] { PwDefs.TitleField, PwDefs.UserNameField }), new SplashIdMapping("Calling Cards", PwIcon.UserKey, new string[] { PwDefs.TitleField, PwDefs.UserNameField, PwDefs.PasswordField }), new SplashIdMapping("Clothes Size", PwIcon.UserCommunication, new string[] { PwDefs.TitleField, "Shirt Size", "Pant Size", "Shoe Size", "Dress Size", "Ring Size" }), new SplashIdMapping("Combinations", PwIcon.Key, new string[] { PwDefs.TitleField, PwDefs.PasswordField }), new SplashIdMapping("Credit Cards", PwIcon.Money, new string[] { PwDefs.TitleField, PwDefs.UserNameField, "Expiry Date", "Name", PwDefs.PasswordField, "Bank" }), new SplashIdMapping("Email Accounts", PwIcon.EMail, new string[] { PwDefs.TitleField, PwDefs.UserNameField, PwDefs.PasswordField, "POP3 Host", "SMTP Host" }), new SplashIdMapping("Email Accts", PwIcon.EMail, new string[] { PwDefs.TitleField, PwDefs.UserNameField, PwDefs.PasswordField, "POP3 Host", "SMTP Host" }), new SplashIdMapping("Emergency Info", PwIcon.UserCommunication, new string[] { PwDefs.TitleField, PwDefs.UserNameField }), new SplashIdMapping("Files", PwIcon.PaperNew, new string[] { PwDefs.TitleField, PwDefs.NotesField, PwDefs.UserNameField, "Date" }), new SplashIdMapping("Frequent Flyer", PwIcon.PaperQ, new string[] { PwDefs.TitleField, PwDefs.UserNameField, "Name", "Date" }), new SplashIdMapping("Identification", PwIcon.UserKey, new string[] { PwDefs.TitleField, PwDefs.PasswordField, PwDefs.UserNameField, "Date" }), new SplashIdMapping("Insurance", PwIcon.ClipboardReady, new string[] { PwDefs.TitleField, PwDefs.PasswordField, PwDefs.UserNameField, "Insured", "Date", "Phone #" }), new SplashIdMapping("Memberships", PwIcon.UserKey, new string[] { PwDefs.TitleField, PwDefs.PasswordField, PwDefs.UserNameField, "Date" }), new SplashIdMapping("Phone Numbers", PwIcon.UserCommunication, new string[] { PwDefs.TitleField, PwDefs.UserNameField }), new SplashIdMapping("Prescriptions", PwIcon.ClipboardReady, new string[] { PwDefs.TitleField, PwDefs.PasswordField, PwDefs.UserNameField, "Doctor", "Pharmacy", "Phone #" }), new SplashIdMapping("Serial Numbers", PwIcon.Key, new string[] { PwDefs.TitleField, PwDefs.PasswordField, "Date", "Reseller" }), new SplashIdMapping("Servers", PwIcon.NetworkServer, new string[] { PwDefs.TitleField, PwDefs.UserNameField, PwDefs.PasswordField, PwDefs.UrlField }), new SplashIdMapping("Vehicle Info", PwIcon.PaperReady, new string[] { PwDefs.TitleField, PwDefs.UserNameField, PwDefs.PasswordField, "Insurance", "Year" }), new SplashIdMapping("Vehicles", PwIcon.PaperReady, new string[] { PwDefs.TitleField, PwDefs.UserNameField, PwDefs.PasswordField, "Insurance", "Year" }), new SplashIdMapping("Voice Mail", PwIcon.IRCommunication, new string[] { PwDefs.TitleField, PwDefs.UserNameField, PwDefs.PasswordField }), new SplashIdMapping("Web Logins", PwIcon.Key, new string[] { PwDefs.TitleField, PwDefs.UserNameField, PwDefs.PasswordField, PwDefs.UrlField }) }; return m_vMappings; } } public override void Import(PwDatabase pwStorage, Stream sInput, IStatusLogger slLogger) { StreamReader sr = new StreamReader(sInput, Encoding.Default, true); string strData = sr.ReadToEnd(); sr.Close(); CsvOptions o = new CsvOptions(); o.BackslashIsEscape = false; CsvStreamReaderEx csv = new CsvStreamReaderEx(strData, o); SortedDictionary dictGroups = new SortedDictionary(); while(true) { string[] vLine = csv.ReadLine(); if(vLine == null) break; if(vLine.Length == 0) continue; if(vLine.Length == 1) { Debug.Assert(vLine[0] == StrHeader); continue; } // Support old version 3.4 if(vLine.Length == 9) { string[] v = new string[13]; for(int i = 0; i < 7; ++i) v[i] = vLine[i]; for(int i = 7; i < 11; ++i) v[i] = string.Empty; v[11] = vLine[7]; v[12] = vLine[8]; vLine = v; } if(vLine.Length == 13) ProcessCsvLine(vLine, pwStorage, dictGroups); else { Debug.Assert(false); } } } private static void ProcessCsvLine(string[] vLine, PwDatabase pwStorage, SortedDictionary dictGroups) { string strType = ParseCsvWord(vLine[0]); string strGroupName = ParseCsvWord(vLine[12]); // + " - " + strType; if(strGroupName.Length == 0) strGroupName = strType; SplashIdMapping mp = null; foreach(SplashIdMapping mpFind in SplashIdCsv402.SplashIdMappings) { if(mpFind.TypeName == strType) { mp = mpFind; break; } } PwIcon pwIcon = ((mp != null) ? mp.Icon : PwIcon.Key); PwGroup pg = null; if(dictGroups.ContainsKey(strGroupName)) pg = dictGroups[strGroupName]; else { // PwIcon pwGroupIcon = ((pwIcon == PwIcon.Key) ? // PwIcon.FolderOpen : pwIcon); // pg = new PwGroup(true, true, strGroupName, pwGroupIcon); pg = new PwGroup(true, true); pg.Name = strGroupName; pwStorage.RootGroup.AddGroup(pg, true); dictGroups[strGroupName] = pg; } PwEntry pe = new PwEntry(true, true); pg.AddEntry(pe, true); pe.IconId = pwIcon; List vTags = StrUtil.StringToTags(strType); foreach(string strTag in vTags) { pe.AddTag(strTag); } for(int iField = 0; iField < 9; ++iField) { string strData = ParseCsvWord(vLine[iField + 1]); if(strData.Length == 0) continue; string strLookup = ((mp != null) ? mp.FieldNames[iField] : null); string strField = (strLookup ?? ("Field " + (iField + 1).ToString())); string strSep = ((strField != PwDefs.NotesField) ? ", " : "\r\n"); ImportUtil.AppendToField(pe, strField, strData, pwStorage, strSep, false); } ImportUtil.AppendToField(pe, PwDefs.NotesField, ParseCsvWord(vLine[11]), pwStorage, "\r\n", false); DateTime? odt = TimeUtil.ParseUSTextDate(ParseCsvWord(vLine[10]), DateTimeKind.Local); if(odt.HasValue) { DateTime dt = TimeUtil.ToUtc(odt.Value, false); pe.LastAccessTime = dt; pe.LastModificationTime = dt; } } private static string ParseCsvWord(string strWord) { if(strWord == null) { Debug.Assert(false); return string.Empty; } string str = strWord; str = str.Replace('\u000B', '\n'); // 0x0B = new line str = StrUtil.NormalizeNewLines(str, true); return str; } private sealed class SplashIdMapping { private readonly string m_strTypeName; public string TypeName { get { return m_strTypeName; } } private readonly PwIcon m_pwIcon; public PwIcon Icon { get { return m_pwIcon; } } private string[] m_vFieldNames = new string[9]; public string[] FieldNames { get { return m_vFieldNames; } } public SplashIdMapping(string strTypeName, PwIcon pwIcon, string[] vFieldNames) { Debug.Assert(strTypeName != null); if(strTypeName == null) throw new ArgumentNullException("strTypeName"); Debug.Assert(vFieldNames != null); if(vFieldNames == null) throw new ArgumentNullException("vFieldNames"); m_strTypeName = strTypeName; m_pwIcon = pwIcon; int nMin = Math.Min(m_vFieldNames.Length, vFieldNames.Length); for(int i = 0; i < nMin; ++i) m_vFieldNames[i] = vFieldNames[i]; } } } } KeePass/DataExchange/Formats/KeePassXml2x.cs0000664000000000000000000000500013222430404017642 0ustar rootroot/* KeePass Password Safe - The Open-Source Password Manager Copyright (C) 2003-2018 Dominik Reichl This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ using System; using System.Collections.Generic; using System.Text; using System.Drawing; using System.IO; using KeePass.Resources; using KeePassLib; using KeePassLib.Collections; using KeePassLib.Interfaces; using KeePassLib.Serialization; namespace KeePass.DataExchange.Formats { internal sealed class KeePassXml2x : FileFormatProvider { public override bool SupportsImport { get { return true; } } public override bool SupportsExport { get { return true; } } public override string FormatName { get { return "KeePass XML (2.x)"; } } public override string DefaultExtension { get { return "xml"; } } public override string ApplicationGroup { get { return PwDefs.ShortProductName; } } public override bool SupportsUuids { get { return true; } } public override Image SmallIcon { get { return KeePass.Properties.Resources.B16x16_Binary; } } public override void Import(PwDatabase pwStorage, Stream sInput, IStatusLogger slLogger) { KdbxFile kdbx = new KdbxFile(pwStorage); kdbx.Load(sInput, KdbxFormat.PlainXml, slLogger); } public override bool Export(PwExportInfo pwExportInfo, Stream sOutput, IStatusLogger slLogger) { PwDatabase pd = (pwExportInfo.ContextDatabase ?? new PwDatabase()); PwObjectList vDel = null; if(!pwExportInfo.ExportDeletedObjects) { vDel = pd.DeletedObjects.CloneShallow(); pd.DeletedObjects.Clear(); } KdbxFile kdb = new KdbxFile(pd); kdb.Save(sOutput, pwExportInfo.DataGroup, KdbxFormat.PlainXml, slLogger); // Restore deleted objects list if(vDel != null) pd.DeletedObjects.Add(vDel); return true; } } } KeePass/DataExchange/Formats/SecurityTxt12.cs0000664000000000000000000000716013222430406020041 0ustar rootroot/* KeePass Password Safe - The Open-Source Password Manager Copyright (C) 2003-2018 Dominik Reichl This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ using System; using System.Collections.Generic; using System.Text; using System.IO; using System.Diagnostics; using System.Drawing; using KeePass.Resources; using KeePassLib; using KeePassLib.Interfaces; using KeePassLib.Security; namespace KeePass.DataExchange.Formats { // 1.2 internal sealed class SecurityTxt12 : FileFormatProvider { public override bool SupportsImport { get { return true; } } public override bool SupportsExport { get { return false; } } public override string FormatName { get { return "Security TXT"; } } public override string DefaultExtension { get { return "txt"; } } public override string ApplicationGroup { get { return KPRes.PasswordManagers; } } public override Image SmallIcon { get { return KeePass.Properties.Resources.B16x16_Imp_Security; } } internal sealed class SecLine { public string Text = string.Empty; public List SubLines = new List(); } public override void Import(PwDatabase pwStorage, Stream sInput, IStatusLogger slLogger) { StreamReader sr = new StreamReader(sInput, Encoding.Default); Stack vGroups = new Stack(); SecLine secRoot = new SecLine(); vGroups.Push(secRoot); char[] vTrim = new char[]{ '\t', '\n', '\r', ' ' }; while(true) { string str = sr.ReadLine(); if(str == null) break; if(str.Length == 0) continue; SecLine line = new SecLine(); line.Text = str.Trim(vTrim); int nTabs = CountTabs(str); if(nTabs == vGroups.Count) { vGroups.Peek().SubLines.Add(line); vGroups.Push(line); } else { while(nTabs < (vGroups.Count - 1)) vGroups.Pop(); vGroups.Peek().SubLines.Add(line); vGroups.Push(line); } } AddSecLine(pwStorage.RootGroup, secRoot, true, pwStorage); sr.Close(); } private static int CountTabs(string str) { Debug.Assert(str != null); if(str == null) return 0; int nTabs = 0; for(int i = 0; i < str.Length; ++i) { if(str[i] != '\t') break; ++nTabs; } return nTabs; } private void AddSecLine(PwGroup pgContainer, SecLine line, bool bIsContainer, PwDatabase pwParent) { if(!bIsContainer) { if(line.SubLines.Count > 0) { PwGroup pg = new PwGroup(true, true); pg.Name = line.Text; pgContainer.AddGroup(pg, true); pgContainer = pg; } else { PwEntry pe = new PwEntry(true, true); pgContainer.AddEntry(pe, true); pe.Strings.Set(PwDefs.TitleField, new ProtectedString( pwParent.MemoryProtection.ProtectTitle, line.Text)); } } foreach(SecLine subLine in line.SubLines) AddSecLine(pgContainer, subLine, false, pwParent); } } } KeePass/DataExchange/Formats/NetworkPwMgrCsv4.cs0000664000000000000000000000774413222430404020543 0ustar rootroot/* KeePass Password Safe - The Open-Source Password Manager Copyright (C) 2003-2018 Dominik Reichl This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ using System; using System.Collections.Generic; using System.Text; using System.IO; using System.Drawing; using System.Diagnostics; using KeePass.Resources; using KeePassLib; using KeePassLib.Interfaces; using KeePassLib.Security; namespace KeePass.DataExchange.Formats { // 4.0+ internal sealed class NetworkPwMgrCsv4 : FileFormatProvider { public override bool SupportsImport { get { return true; } } public override bool SupportsExport { get { return false; } } public override string FormatName { get { return "Network Password Manager CSV"; } } public override string DefaultExtension { get { return "csv"; } } public override string ApplicationGroup { get { return KPRes.PasswordManagers; } } public override Image SmallIcon { get { return KeePass.Properties.Resources.B16x16_Imp_NetworkPwMgr; } } public override void Import(PwDatabase pwStorage, Stream sInput, IStatusLogger slLogger) { StreamReader sr = new StreamReader(sInput, Encoding.Default); string strData = sr.ReadToEnd(); sr.Close(); CsvOptions opt = new CsvOptions(); opt.BackslashIsEscape = false; opt.TextQualifier = char.MaxValue; // No text qualifier CsvStreamReaderEx csv = new CsvStreamReaderEx(strData, opt); PwGroup pg = pwStorage.RootGroup; char[] vGroupSplit = new char[] { '\\' }; while(true) { string[] v = csv.ReadLine(); if(v == null) break; if(v.Length < 1) continue; for(int i = 0; i < v.Length; ++i) v[i] = ParseString(v[i]); if(v[0].StartsWith("\\")) // Group { string strGroup = v[0].Trim(vGroupSplit); // Also from end if(strGroup.Length > 0) { pg = pwStorage.RootGroup.FindCreateSubTree(strGroup, vGroupSplit); if(v.Length >= 6) pg.Notes = v[5].Trim(); if((v.Length >= 5) && (v[4].Trim().Length > 0)) { if(pg.Notes.Length > 0) pg.Notes += Environment.NewLine + Environment.NewLine; pg.Notes += v[4].Trim(); } } } else // Entry { PwEntry pe = new PwEntry(true, true); pg.AddEntry(pe, true); List l = new List(v); while(l.Count < 8) { Debug.Assert(false); l.Add(string.Empty); } ImportUtil.AppendToField(pe, PwDefs.TitleField, l[0], pwStorage); ImportUtil.AppendToField(pe, PwDefs.UserNameField, l[1], pwStorage); ImportUtil.AppendToField(pe, PwDefs.PasswordField, l[2], pwStorage); ImportUtil.AppendToField(pe, PwDefs.UrlField, l[3], pwStorage); ImportUtil.AppendToField(pe, PwDefs.NotesField, l[4], pwStorage); if(l[5].Length > 0) ImportUtil.AppendToField(pe, "Custom 1", l[5], pwStorage); if(l[6].Length > 0) ImportUtil.AppendToField(pe, "Custom 2", l[6], pwStorage); if(l[7].Length > 0) ImportUtil.AppendToField(pe, "Custom 3", l[7], pwStorage); } } } private static string ParseString(string str) { if(str == null) { Debug.Assert(false); return string.Empty; } str = str.Replace(@"#44", ","); str = str.Replace(@"#13", Environment.NewLine); return str; } } } KeePass/DataExchange/Formats/PwPrompterDat12.cs0000664000000000000000000001207213222430404020276 0ustar rootroot/* KeePass Password Safe - The Open-Source Password Manager Copyright (C) 2003-2018 Dominik Reichl This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ using System; using System.Collections.Generic; using System.Text; using System.IO; using System.Windows.Forms; using System.Drawing; using System.Diagnostics; using KeePass.Forms; using KeePass.Resources; using KeePass.UI; using KeePassLib; using KeePassLib.Interfaces; using KeePassLib.Resources; using KeePassLib.Security; namespace KeePass.DataExchange.Formats { internal sealed class PwPrompterDat12 : FileFormatProvider { public override bool SupportsImport { get { return true; } } public override bool SupportsExport { get { return false; } } public override string FormatName { get { return "Password Prompter DAT"; } } public override string DefaultExtension { get { return "dat"; } } public override string ApplicationGroup { get { return KPRes.PasswordManagers; } } public override bool ImportAppendsToRootGroupOnly { get { return true; } } public override Image SmallIcon { get { return Properties.Resources.B16x16_Imp_PwPrompter; } } public override void Import(PwDatabase pwStorage, Stream sInput, IStatusLogger slLogger) { SingleLineEditForm dlg = new SingleLineEditForm(); dlg.InitEx(KPRes.Password, KPRes.Import + ": " + this.FormatName, KPRes.PasswordPrompt, Properties.Resources.B48x48_KGPG_Key2, string.Empty, null); if(UIUtil.ShowDialogNotValue(dlg, DialogResult.OK)) return; string strPassword = dlg.ResultString; UIUtil.DestroyForm(dlg); byte[] pbPassword = Encoding.Default.GetBytes(strPassword); BinaryReader br = new BinaryReader(sInput, Encoding.Default); ushort usFileVersion = br.ReadUInt16(); if(usFileVersion != 0x0100) throw new Exception(KLRes.FileVersionUnsupported); uint uEntries = br.ReadUInt32(); uint uKeySize = br.ReadUInt32(); Debug.Assert(uKeySize == 50); // It's a constant byte btKeyArrayLen = br.ReadByte(); byte[] pbKey = br.ReadBytes(btKeyArrayLen); byte btValidArrayLen = br.ReadByte(); byte[] pbValid = br.ReadBytes(btValidArrayLen); if(pbPassword.Length > 0) { MangleSetKey(pbPassword); MangleDecode(pbKey); } MangleSetKey(pbKey); MangleDecode(pbValid); string strValid = Encoding.Default.GetString(pbValid); if(strValid != "aacaaaadaaeabaacyuioqaqqaaaaaertaaajkadaadaaxywqea") throw new Exception(KLRes.InvalidCompositeKey); for(uint uEntry = 0; uEntry < uEntries; ++uEntry) { PwEntry pe = new PwEntry(true, true); pwStorage.RootGroup.AddEntry(pe, true); pe.Strings.Set(PwDefs.TitleField, new ProtectedString( pwStorage.MemoryProtection.ProtectTitle, ReadString(br))); pe.Strings.Set(PwDefs.UserNameField, new ProtectedString( pwStorage.MemoryProtection.ProtectUserName, ReadString(br))); pe.Strings.Set(PwDefs.PasswordField, new ProtectedString( pwStorage.MemoryProtection.ProtectPassword, ReadString(br))); pe.Strings.Set("Hint", new ProtectedString(false, ReadString(br))); pe.Strings.Set(PwDefs.NotesField, new ProtectedString( pwStorage.MemoryProtection.ProtectNotes, ReadString(br))); pe.Strings.Set(PwDefs.UrlField, new ProtectedString( pwStorage.MemoryProtection.ProtectUrl, ReadString(br))); } br.Close(); sInput.Close(); } private string ReadString(BinaryReader br) { byte btLen = br.ReadByte(); byte[] pbData = br.ReadBytes(btLen); MangleDecode(pbData); return Encoding.Default.GetString(pbData); } byte[] m_pbMangleKey = null; private void MangleSetKey(byte[] pbKey) { if(pbKey == null) { Debug.Assert(false); return; } m_pbMangleKey = new byte[pbKey.Length]; Array.Copy(pbKey, m_pbMangleKey, pbKey.Length); } private void MangleDecode(byte[] pbData) { if(m_pbMangleKey == null) { Debug.Assert(false); return; } int nKeyIndex = 0, nIndex = 0, nRemLen = pbData.Length; bool bUp = true; while(nRemLen > 0) { if(nKeyIndex > (m_pbMangleKey.Length - 1)) { nKeyIndex = m_pbMangleKey.Length - 1; bUp = false; } else if(nKeyIndex < 0) { nKeyIndex = 0; bUp = true; } pbData[nIndex] ^= m_pbMangleKey[nKeyIndex]; nKeyIndex += (bUp ? 1 : -1); ++nIndex; --nRemLen; } } } } KeePass/DataExchange/Formats/OnePwProCsv599.cs0000664000000000000000000001532513222430404020023 0ustar rootroot/* KeePass Password Safe - The Open-Source Password Manager Copyright (C) 2003-2018 Dominik Reichl This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ using System; using System.Collections.Generic; using System.Diagnostics; using System.Drawing; using System.Globalization; using System.IO; using System.Text; using KeePass.Resources; using KeePassLib; using KeePassLib.Interfaces; using KeePassLib.Security; using KeePassLib.Utility; namespace KeePass.DataExchange.Formats { // 1PW 6.15-7.05+ and its predecessor 1Password Pro 5.99, // not 1Password (which is an entirely different product) internal sealed class OnePwProCsv599 : FileFormatProvider { public override bool SupportsImport { get { return true; } } public override bool SupportsExport { get { return false; } } public override string FormatName { get { return @"1PW & 1Password Pro CSV"; } } public override string DefaultExtension { get { return "csv"; } } public override string ApplicationGroup { get { return KPRes.PasswordManagers; } } public override bool ImportAppendsToRootGroupOnly { get { return false; } } public override Image SmallIcon { get { return KeePass.Properties.Resources.B16x16_Imp_OnePwPro; } } public override void Import(PwDatabase pwStorage, Stream sInput, IStatusLogger slLogger) { StreamReader sr = new StreamReader(sInput, Encoding.Default, true); string strData = sr.ReadToEnd(); sr.Close(); string[] vLines = strData.Split(new char[] { '\r', '\n' }, StringSplitOptions.RemoveEmptyEntries); Dictionary dictGroups = new Dictionary(); foreach(string strLine in vLines) { ProcessCsvLine(strLine, pwStorage, dictGroups); } } private static void ProcessCsvLine(string strLine, PwDatabase pwStorage, Dictionary dictGroups) { if(strLine == "\"Bezeichnung\"\t\"User/ID\"\t\"1.Passwort\"\t\"Url/Programm\"\t\"Geändert am\"\t\"Bemerkung\"\t\"2.Passwort\"\t\"Läuft ab\"\t\"Kategorie\"\t\"Eigene Felder\"") return; string str = strLine; if(str.StartsWith("\"") && str.EndsWith("\"")) str = str.Substring(1, str.Length - 2); else { Debug.Assert(false); } string[] list = str.Split(new string[]{ "\"\t\"" }, StringSplitOptions.None); int iOffset; if(list.Length == 11) iOffset = 0; // 1Password Pro 5.99 else if(list.Length == 10) iOffset = -1; // 1PW 6.15 else if(list.Length > 11) iOffset = 0; // Unknown extension else return; string strGroup = list[9 + iOffset]; PwGroup pg; if(dictGroups.ContainsKey(strGroup)) pg = dictGroups[strGroup]; else { pg = new PwGroup(true, true, strGroup, PwIcon.Folder); pwStorage.RootGroup.AddGroup(pg, true); dictGroups[strGroup] = pg; } PwEntry pe = new PwEntry(true, true); pg.AddEntry(pe, true); pe.Strings.Set(PwDefs.TitleField, new ProtectedString( pwStorage.MemoryProtection.ProtectTitle, ParseCsvWord(list[1 + iOffset]))); pe.Strings.Set(PwDefs.UserNameField, new ProtectedString( pwStorage.MemoryProtection.ProtectUserName, ParseCsvWord(list[2 + iOffset]))); pe.Strings.Set(PwDefs.PasswordField, new ProtectedString( pwStorage.MemoryProtection.ProtectPassword, ParseCsvWord(list[3 + iOffset]))); pe.Strings.Set(PwDefs.UrlField, new ProtectedString( pwStorage.MemoryProtection.ProtectUrl, ParseCsvWord(list[4 + iOffset]))); pe.Strings.Set(PwDefs.NotesField, new ProtectedString( pwStorage.MemoryProtection.ProtectNotes, ParseCsvWord(list[6 + iOffset]))); pe.Strings.Set(PwDefs.PasswordField + " 2", new ProtectedString( pwStorage.MemoryProtection.ProtectPassword, ParseCsvWord(list[7 + iOffset]))); // 1Password Pro only: // Debug.Assert(list[9] == list[0]); // Very mysterious format... DateTime dt; if(ParseDateTime(list[5 + iOffset], out dt)) { pe.CreationTime = pe.LastAccessTime = pe.LastModificationTime = dt; } else { Debug.Assert(false); } if(ParseDateTime(list[8 + iOffset], out dt)) { pe.Expires = true; pe.ExpiryTime = dt; } AddCustomFields(pe, list[10 + iOffset]); } private static string ParseCsvWord(string strWord) { string str = strWord; str = str.Replace("\\r", string.Empty); str = str.Replace("\\n", "\r\n"); return str; } private static bool ParseDateTime(string str, out DateTime dt) { dt = DateTime.MinValue; if(string.IsNullOrEmpty(str)) return false; if(str.Trim().Equals("nie", StrUtil.CaseIgnoreCmp)) return false; if(str.Trim().Equals("never", StrUtil.CaseIgnoreCmp)) return false; if(str.Trim().Equals("morgen", StrUtil.CaseIgnoreCmp)) { dt = DateTime.UtcNow.AddDays(1.0); return true; } string[] list = str.Split(new char[] { '.', '\r', '\n', ' ', '\t', '-', ':' }, StringSplitOptions.RemoveEmptyEntries); try { if(list.Length == 6) dt = (new DateTime(int.Parse(list[2]), int.Parse(list[1]), int.Parse(list[0]), int.Parse(list[3]), int.Parse(list[4]), int.Parse(list[5]), DateTimeKind.Local)).ToUniversalTime(); else if(list.Length == 3) dt = (new DateTime(int.Parse(list[2]), int.Parse(list[1]), int.Parse(list[0]), 0, 0, 0, DateTimeKind.Local)).ToUniversalTime(); else { Debug.Assert(false); return false; } } catch(Exception) { Debug.Assert(false); return false; } return true; } private static void AddCustomFields(PwEntry pe, string strCustom) { string[] vItems = strCustom.Split(new string[] { @"|~#~|" }, StringSplitOptions.RemoveEmptyEntries); foreach(string strItem in vItems) { string[] vData = strItem.Split(new char[] { '|' }, StringSplitOptions.None); if(vData.Length >= 3) { string strValue = vData[2]; for(int i = 3; i < vData.Length; ++i) strValue += @"|" + vData[i]; pe.Strings.Set(vData[1], new ProtectedString(false, strValue)); } else { Debug.Assert(false); } } } } } KeePass/DataExchange/Formats/PwMemory2008Xml104.cs0000664000000000000000000001016513222430404020363 0ustar rootroot/* KeePass Password Safe - The Open-Source Password Manager Copyright (C) 2003-2018 Dominik Reichl This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ using System; using System.Collections.Generic; using System.Text; using System.Drawing; using System.IO; using System.Xml; using System.Xml.Serialization; using KeePass.Resources; using KeePassLib; using KeePassLib.Interfaces; using KeePassLib.Security; using KeePassLib.Utility; namespace KeePass.DataExchange.Formats { // 1.0.4 internal sealed class PwMemory2008Xml104 : FileFormatProvider { public override bool SupportsImport { get { return true; } } public override bool SupportsExport { get { return false; } } public override string FormatName { get { return "Password Memory 2008 XML"; } } public override string DefaultExtension { get { return "xml"; } } public override string ApplicationGroup { get { return KPRes.PasswordManagers; } } public override Image SmallIcon { get { return KeePass.Properties.Resources.B16x16_Imp_PwMem2008; } } public override void Import(PwDatabase pwStorage, Stream sInput, IStatusLogger slLogger) { string str = Preprocess(sInput); MemoryStream ms = new MemoryStream(StrUtil.Utf8.GetBytes(str), false); XmlSerializer xs = new XmlSerializer(typeof(PwMem2008XmlFile_Priv)); PwMem2008XmlFile_Priv f = (PwMem2008XmlFile_Priv)xs.Deserialize(ms); ms.Close(); if((f == null) || (f.Cells == null)) return; Dictionary vGroups = new Dictionary(); for(int iLine = 2; iLine < f.Cells.Length; ++iLine) { string[] vCells = f.Cells[iLine]; if((vCells == null) || (vCells.Length != 6)) continue; if((vCells[1] == null) || (vCells[2] == null) || (vCells[3] == null) || (vCells[4] == null)) continue; string strGroup = vCells[4]; PwGroup pg; if(strGroup == ".") pg = pwStorage.RootGroup; else if(vGroups.ContainsKey(strGroup)) pg = vGroups[strGroup]; else { pg = new PwGroup(true, true); pg.Name = strGroup; pwStorage.RootGroup.AddGroup(pg, true); vGroups[strGroup] = pg; } PwEntry pe = new PwEntry(true, true); pg.AddEntry(pe, true); if(vCells[1] != ".") pe.Strings.Set(PwDefs.TitleField, new ProtectedString( pwStorage.MemoryProtection.ProtectTitle, vCells[1])); if(vCells[2] != ".") pe.Strings.Set(PwDefs.UserNameField, new ProtectedString( pwStorage.MemoryProtection.ProtectUserName, vCells[2])); if(vCells[3] != ".") pe.Strings.Set(PwDefs.PasswordField, new ProtectedString( pwStorage.MemoryProtection.ProtectPassword, vCells[3])); } } private static string Preprocess(Stream sInput) { StreamReader sr = new StreamReader(sInput, Encoding.UTF8); string str = sr.ReadToEnd(); sr.Close(); const string strStartTag = " This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ using System; using System.Collections.Generic; using System.Text; using System.Xml; using System.IO; using System.Drawing; using System.Drawing.Imaging; using System.Globalization; using System.Diagnostics; using KeePass.Resources; using KeePass.UI; using KeePass.Util; using KeePassLib; using KeePassLib.Cryptography; using KeePassLib.Interfaces; using KeePassLib.Security; using KeePassLib.Utility; namespace KeePass.DataExchange.Formats { // 1.00 internal sealed class MozillaBookmarksHtml100 : FileFormatProvider { public override bool SupportsImport { get { return true; } } public override bool SupportsExport { get { return true; } } public override string FormatName { get { return "Mozilla Bookmarks HTML"; } } public override string DefaultExtension { get { return @"html|htm"; } } public override string ApplicationGroup { get { return KPRes.Browser; } } // public override bool ImportAppendsToRootGroupOnly { get { return false; } } public override Image SmallIcon { get { return KeePass.Properties.Resources.B16x16_ASCII; } } // ////////////////////////////////////////////////////////////////// // Import public override void Import(PwDatabase pwStorage, Stream sInput, IStatusLogger slLogger) { StreamReader sr = new StreamReader(sInput, Encoding.UTF8); string strContent = sr.ReadToEnd(); sr.Close(); if(strContent.IndexOf(@"") < 0) throw new FormatException("Invalid DOCTYPE!"); strContent = strContent.Replace(@"", string.Empty); strContent = strContent.Replace(@"
", string.Empty); strContent = strContent.Replace(@"

", string.Empty); // strContent = strContent.Replace(@"

", string.Empty); // strContent = strContent.Replace(@"
", string.Empty); // strContent = strContent.Replace(@"
", string.Empty); strContent = strContent.Replace(@"
", string.Empty); // int nOffset = strContent.IndexOf('&'); // while(nOffset >= 0) // { // string str4 = strContent.Substring(nOffset, 4); // string str5 = strContent.Substring(nOffset, 5); // string str6 = strContent.Substring(nOffset, 6); // if((str6 != @" ") && (str5 != @"&") && (str4 != @"<") && // (str4 != @">") && (str5 != @"'") && (str6 != @""")) // { // strContent = strContent.Remove(nOffset, 1); // strContent = strContent.Insert(nOffset, @"&"); // } // else nOffset = strContent.IndexOf('&', nOffset + 1); // } string[] vPreserve = new string[] { @" ", @"&", @"<", @">", @"'", @""" }; Dictionary dPreserve = new Dictionary(); CryptoRandom cr = CryptoRandom.Instance; foreach(string strPreserve in vPreserve) { string strCode = Convert.ToBase64String(cr.GetRandomBytes(16)); Debug.Assert(strCode.IndexOf('&') < 0); dPreserve[strPreserve] = strCode; strContent = strContent.Replace(strPreserve, strCode); } strContent = strContent.Replace(@"&", @"&"); foreach(KeyValuePair kvpPreserve in dPreserve) { strContent = strContent.Replace(kvpPreserve.Value, kvpPreserve.Key); } // Terminate
s int iDD = -1; while(true) { iDD = strContent.IndexOf(@"
", iDD + 1); if(iDD < 0) break; int iNextTag = strContent.IndexOf('<', iDD + 1); if(iNextTag <= 0) { Debug.Assert(false); break; } strContent = strContent.Insert(iNextTag, @"
"); } strContent = "" + strContent + ""; byte[] pbFixedData = StrUtil.Utf8.GetBytes(strContent); MemoryStream msFixed = new MemoryStream(pbFixedData, false); XmlDocument xmlDoc = new XmlDocument(); xmlDoc.Load(msFixed); msFixed.Close(); XmlNode xmlRoot = xmlDoc.DocumentElement; foreach(XmlNode xmlChild in xmlRoot) { if(xmlChild.Name == "META") ImportMeta(xmlChild, pwStorage); } } private static void ImportMeta(XmlNode xmlNode, PwDatabase pwStorage) { foreach(XmlNode xmlChild in xmlNode) { if(xmlChild.Name == "DL") ImportGroup(xmlChild, pwStorage, pwStorage.RootGroup); else if(xmlChild.Name == "TITLE") { } else if(xmlChild.Name == "H1") { } else { Debug.Assert(false); } } } private static void ImportGroup(XmlNode xmlNode, PwDatabase pwStorage, PwGroup pg) { PwGroup pgSub = pg; PwEntry pe = null; foreach(XmlNode xmlChild in xmlNode) { if(xmlChild.Name == "A") { pe = new PwEntry(true, true); pg.AddEntry(pe, true); pe.Strings.Set(PwDefs.TitleField, new ProtectedString( pwStorage.MemoryProtection.ProtectTitle, XmlUtil.SafeInnerText(xmlChild))); XmlNode xnUrl = xmlChild.Attributes.GetNamedItem("HREF"); if((xnUrl != null) && (xnUrl.Value != null)) pe.Strings.Set(PwDefs.UrlField, new ProtectedString( pwStorage.MemoryProtection.ProtectUrl, xnUrl.Value)); else { Debug.Assert(false); } // pe.Strings.Set("RDF_ID", new ProtectedString( // false, xmlChild.Attributes.GetNamedItem("ID").Value)); ImportIcon(xmlChild, pe, pwStorage); XmlNode xnTags = xmlChild.Attributes.GetNamedItem("TAGS"); if((xnTags != null) && (xnTags.Value != null)) { string[] vTags = xnTags.Value.Split(','); foreach(string strTag in vTags) { if(string.IsNullOrEmpty(strTag)) continue; pe.AddTag(strTag); } } } else if(xmlChild.Name == "DD") { if(pe != null) ImportUtil.AppendToField(pe, PwDefs.NotesField, XmlUtil.SafeInnerText(xmlChild).Trim(), pwStorage, "\r\n", false); else { Debug.Assert(false); } } else if(xmlChild.Name == "H3") { string strGroup = XmlUtil.SafeInnerText(xmlChild); if(strGroup.Length == 0) { Debug.Assert(false); pgSub = pg; } else { pgSub = new PwGroup(true, true, strGroup, PwIcon.Folder); pg.AddGroup(pgSub, true); } } else if(xmlChild.Name == "DL") ImportGroup(xmlChild, pwStorage, pgSub); else { Debug.Assert(false); } } } private static void ImportIcon(XmlNode xn, PwEntry pe, PwDatabase pd) { XmlNode xnIcon = xn.Attributes.GetNamedItem("ICON"); if(xnIcon == null) return; string strIcon = xnIcon.Value; if(!StrUtil.IsDataUri(strIcon)) { Debug.Assert(false); return; } try { byte[] pbImage = StrUtil.DataUriToData(strIcon); if((pbImage == null) || (pbImage.Length == 0)) { Debug.Assert(false); return; } Image img = GfxUtil.LoadImage(pbImage); if(img == null) { Debug.Assert(false); return; } byte[] pbPng; int wMax = PwCustomIcon.MaxWidth; int hMax = PwCustomIcon.MaxHeight; if((img.Width <= wMax) && (img.Height <= hMax)) { using(MemoryStream msPng = new MemoryStream()) { img.Save(msPng, ImageFormat.Png); pbPng = msPng.ToArray(); } } else { using(Image imgSc = GfxUtil.ScaleImage(img, wMax, hMax)) { using(MemoryStream msPng = new MemoryStream()) { imgSc.Save(msPng, ImageFormat.Png); pbPng = msPng.ToArray(); } } } img.Dispose(); PwUuid pwUuid = null; int iEx = pd.GetCustomIconIndex(pbPng); if(iEx >= 0) pwUuid = pd.CustomIcons[iEx].Uuid; else { pwUuid = new PwUuid(true); pd.CustomIcons.Add(new PwCustomIcon(pwUuid, pbPng)); pd.UINeedsIconUpdate = true; pd.Modified = true; } pe.CustomIconUuid = pwUuid; } catch(Exception) { Debug.Assert(false); } } // ////////////////////////////////////////////////////////////////// // Export public override bool Export(PwExportInfo pwExportInfo, Stream sOutput, IStatusLogger slLogger) { StringBuilder sb = new StringBuilder(); sb.AppendLine(""); sb.AppendLine(""); sb.AppendLine(""); sb.AppendLine("Bookmarks"); sb.AppendLine("

Bookmarks

"); sb.AppendLine(); sb.AppendLine("

"); ExportGroup(sb, pwExportInfo.DataGroup, 1, pwExportInfo.ContextDatabase); sb.AppendLine("

"); string strData = sb.ToString(); strData = StrUtil.NormalizeNewLines(strData, false); byte[] pbData = StrUtil.Utf8.GetBytes(strData); sOutput.Write(pbData, 0, pbData.Length); sOutput.Close(); return true; } private static void ExportGroup(StringBuilder sb, PwGroup pg, uint uIndent, PwDatabase pd) { ExportData(sb, uIndent, "
", pg.Name, true, "", true); ExportData(sb, uIndent, "

", null, false, null, true); foreach(PwGroup pgSub in pg.Groups) { ExportGroup(sb, pgSub, uIndent + 1, pd); } #if DEBUG List l = new List(); l.Add("Tag 1"); l.Add("Tag 2"); Debug.Assert(StrUtil.TagsToString(l, false) == "Tag 1;Tag 2"); #endif foreach(PwEntry pe in pg.Entries) { string strUrl = pe.Strings.ReadSafe(PwDefs.UrlField); if(strUrl.Length == 0) continue; // Encode only when really required; '&' does not need // to be encoded bool bEncUrl = (strUrl.IndexOfAny(new char[] { '\"', '<', '>' }) >= 0); ExportData(sb, uIndent + 1, "

0) { string strTags = StrUtil.TagsToString(pe.Tags, false); strTags = strTags.Replace(';', ','); // Without space ExportData(sb, 0, " TAGS=\"", strTags, true, "\"", false); } string strTitle = pe.Strings.ReadSafe(PwDefs.TitleField); if(strTitle.Length == 0) strTitle = strUrl; ExportData(sb, 0, ">", strTitle, true, "", true); string strNotes = pe.Strings.ReadSafe(PwDefs.NotesField); if(strNotes.Length > 0) ExportData(sb, uIndent + 1, "
", strNotes, true, null, true); } ExportData(sb, uIndent, "

", null, false, null, true); } private static void ExportData(StringBuilder sb, uint uIndent, string strRawPrefix, string strData, bool bEncodeData, string strRawSuffix, bool bNewLine) { if(uIndent > 0) sb.Append(new string(' ', 4 * (int)uIndent)); if(strRawPrefix != null) sb.Append(strRawPrefix); if(strData != null) { if(bEncodeData) { // Apply HTML encodings except '\n' -> "
" const string strNewLine = "899A13DDD6BA4B24BA2CA6C756E7B936"; string str = StrUtil.NormalizeNewLines(strData, false); str = str.Replace("\n", strNewLine); str = StrUtil.StringToHtml(str); str = str.Replace(strNewLine, "\n"); sb.Append(str); } else sb.Append(strData); } if(strRawSuffix != null) sb.Append(strRawSuffix); if(bNewLine) sb.AppendLine(); } private static void ExportTimes(StringBuilder sb, ITimeLogger tl) { if(tl == null) { Debug.Assert(false); return; } try { long t = (long)TimeUtil.SerializeUnix(tl.CreationTime); ExportData(sb, 0, " ADD_DATE=\"", t.ToString( NumberFormatInfo.InvariantInfo), false, "\"", false); t = (long)TimeUtil.SerializeUnix(tl.LastModificationTime); ExportData(sb, 0, " LAST_MODIFIED=\"", t.ToString( NumberFormatInfo.InvariantInfo), false, "\"", false); } catch(Exception) { Debug.Assert(false); } } } } KeePass/DataExchange/Formats/GenericCsv.cs0000664000000000000000000000426113222430404017414 0ustar rootroot/* KeePass Password Safe - The Open-Source Password Manager Copyright (C) 2003-2018 Dominik Reichl This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ using System; using System.Collections.Generic; using System.Text; using System.IO; using System.Drawing; using KeePass.Forms; using KeePass.Resources; using KeePass.UI; using KeePassLib; using KeePassLib.Interfaces; using KeePassLib.Utility; namespace KeePass.DataExchange.Formats { internal sealed class GenericCsv : FileFormatProvider { public override bool SupportsImport { get { return true; } } public override bool SupportsExport { get { return false; } } public override string FormatName { get { return KPRes.CsvTextFile; } } public override string DisplayName { get { return KPRes.GenericCsvImporter; } } public override string DefaultExtension { get { return @"*"; } } public override string ApplicationGroup { get { return KPRes.General; } } public override bool ImportAppendsToRootGroupOnly { get { return false; } } public override Image SmallIcon { get { return KeePass.Properties.Resources.B16x16_ASCII; } } public override void Import(PwDatabase pwStorage, Stream sInput, IStatusLogger slLogger) { MemoryStream ms = new MemoryStream(); MemUtil.CopyStream(sInput, ms); byte[] pbData = ms.ToArray(); ms.Close(); sInput.Close(); CsvImportForm dlg = new CsvImportForm(); dlg.InitEx(pwStorage, pbData); UIUtil.ShowDialogAndDestroy(dlg); } } } KeePass/DataExchange/Formats/StickyPwXml50.cs0000664000000000000000000001223413222430406017770 0ustar rootroot/* KeePass Password Safe - The Open-Source Password Manager Copyright (C) 2003-2018 Dominik Reichl This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ using System; using System.Collections.Generic; using System.Text; using System.Xml; using System.Xml.XPath; using System.IO; using System.Drawing; using System.Diagnostics; using KeePass.Resources; using KeePass.UI; using KeePass.Util; using KeePassLib; using KeePassLib.Interfaces; using KeePassLib.Security; using KeePassLib.Utility; namespace KeePass.DataExchange.Formats { // KasperskyPwMgrXml50 derives from this // 5.0.4.232-8.0.7.78+ internal class StickyPwXml50 : FileFormatProvider { public override bool SupportsImport { get { return true; } } public override bool SupportsExport { get { return false; } } public override string FormatName { get { return "Sticky Password XML"; } } public override string DefaultExtension { get { return "xml"; } } public override string ApplicationGroup { get { return KPRes.PasswordManagers; } } public override bool ImportAppendsToRootGroupOnly { get { return true; } } public override Image SmallIcon { get { return KeePass.Properties.Resources.B16x16_Imp_StickyPw; } } public override void Import(PwDatabase pwStorage, Stream sInput, IStatusLogger slLogger) { XPathDocument xpDoc = new XPathDocument(sInput); XPathNavigator xpNav = xpDoc.CreateNavigator(); ImportLogins(xpNav, pwStorage); ImportMemos(xpNav, pwStorage); } private static void ImportLogins(XPathNavigator xpNav, PwDatabase pd) { XPathNodeIterator it = xpNav.Select("/root/Database/Logins/Login"); while(it.MoveNext()) { PwEntry pe = new PwEntry(true, true); pd.RootGroup.AddEntry(pe, true); XPathNavigator xpLogin = it.Current; pe.Strings.Set(PwDefs.UserNameField, new ProtectedString( pd.MemoryProtection.ProtectUserName, xpLogin.GetAttribute("Name", string.Empty))); pe.Strings.Set(PwDefs.PasswordField, new ProtectedString( pd.MemoryProtection.ProtectPassword, xpLogin.GetAttribute("Password", string.Empty))); SetTimes(pe, xpLogin); string strID = xpLogin.GetAttribute("ID", string.Empty); if(string.IsNullOrEmpty(strID)) continue; XPathNavigator xpAccLogin = xpNav.SelectSingleNode( @"/root/Database/Accounts/Account/LoginLinks/Login[@SourceLoginID='" + strID + @"']/../.."); if(xpAccLogin == null) { Debug.Assert(false); } else { Debug.Assert(xpAccLogin.Name == "Account"); pe.Strings.Set(PwDefs.TitleField, new ProtectedString( pd.MemoryProtection.ProtectTitle, xpAccLogin.GetAttribute("Name", string.Empty))); pe.Strings.Set(PwDefs.UrlField, new ProtectedString( pd.MemoryProtection.ProtectUrl, xpAccLogin.GetAttribute("Link", string.Empty))); string strNotes = xpAccLogin.GetAttribute("Comments", string.Empty); strNotes = strNotes.Replace("/n", Environment.NewLine); pe.Strings.Set(PwDefs.NotesField, new ProtectedString( pd.MemoryProtection.ProtectNotes, strNotes)); } } } private static void ImportMemos(XPathNavigator xpNav, PwDatabase pd) { XPathNodeIterator it = xpNav.Select("/root/Database/SecureMemos/SecureMemo"); while(it.MoveNext()) { PwEntry pe = new PwEntry(true, true); pd.RootGroup.AddEntry(pe, true); pe.IconId = PwIcon.PaperNew; XPathNavigator xpMemo = it.Current; pe.Strings.Set(PwDefs.TitleField, new ProtectedString( pd.MemoryProtection.ProtectTitle, xpMemo.GetAttribute("Name", string.Empty))); SetTimes(pe, xpMemo); try { string strMemoHex = xpMemo.Value; byte[] pbMemo = MemUtil.HexStringToByteArray(strMemoHex); string strMemoRtf = Encoding.Unicode.GetString(pbMemo); pe.Binaries.Set(KPRes.Notes + ".rtf", new ProtectedBinary( false, StrUtil.Utf8.GetBytes(strMemoRtf))); } catch(Exception) { Debug.Assert(false); } } } private static void SetTimes(PwEntry pe, XPathNavigator xpNode) { DateTime dt; string strTime = (xpNode.GetAttribute("CreatedDate", string.Empty)); if(DateTime.TryParse(strTime, out dt)) pe.CreationTime = TimeUtil.ToUtc(dt, true); else { Debug.Assert(false); } strTime = (xpNode.GetAttribute("ModifiedDate", string.Empty)); if(DateTime.TryParse(strTime, out dt)) pe.LastModificationTime = TimeUtil.ToUtc(dt, true); else { Debug.Assert(false); } } } } KeePass/DataExchange/Formats/CodeWalletTxt605.cs0000664000000000000000000000710213222430404020337 0ustar rootroot/* KeePass Password Safe - The Open-Source Password Manager Copyright (C) 2003-2018 Dominik Reichl This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ using System; using System.Collections.Generic; using System.Text; using System.IO; using System.Windows.Forms; using System.Diagnostics; using System.Drawing; using KeePass.Resources; using KeePassLib; using KeePassLib.Interfaces; using KeePassLib.Security; using KeePassLib.Utility; namespace KeePass.DataExchange.Formats { // 6.05-6.62+ internal sealed class CodeWalletTxt605 : FileFormatProvider { private const string FieldSeparator = "*---------------------------------------------------"; public override bool SupportsImport { get { return true; } } public override bool SupportsExport { get { return false; } } public override string FormatName { get { return "CodeWallet TXT"; } } public override string DefaultExtension { get { return "txt"; } } public override string ApplicationGroup { get { return KPRes.PasswordManagers; } } public override bool ImportAppendsToRootGroupOnly { get { return true; } } public override Image SmallIcon { get { return KeePass.Properties.Resources.B16x16_Imp_CWallet; } } public override void Import(PwDatabase pwStorage, Stream sInput, IStatusLogger slLogger) { StreamReader sr = new StreamReader(sInput, Encoding.Unicode); string strData = sr.ReadToEnd(); sr.Close(); string[] vLines = strData.Split(new char[]{ '\r', '\n' }); bool bDoImport = false; PwEntry pe = new PwEntry(true, true); bool bInnerSep = false; bool bEmptyEntry = true; string strLastIndexedItem = string.Empty; string strLastLine = string.Empty; foreach(string strLine in vLines) { if(strLine.Length == 0) continue; if(strLine == FieldSeparator) { bInnerSep = !bInnerSep; if(bInnerSep && !bEmptyEntry) { pwStorage.RootGroup.AddEntry(pe, true); pe = new PwEntry(true, true); bEmptyEntry = true; } else if(!bInnerSep) pe.Strings.Set(PwDefs.TitleField, new ProtectedString( pwStorage.MemoryProtection.ProtectTitle, strLastLine)); bDoImport = true; } else if(bDoImport) { int nIDLen = strLine.IndexOf(": "); if(nIDLen > 0) { string strIndex = strLine.Substring(0, nIDLen); if(PwDefs.IsStandardField(strIndex)) strIndex = Guid.NewGuid().ToString(); pe.Strings.Set(strIndex, new ProtectedString( false, strLine.Remove(0, nIDLen + 2))); strLastIndexedItem = strIndex; } else if(!bEmptyEntry) { pe.Strings.Set(strLastIndexedItem, new ProtectedString( false, pe.Strings.ReadSafe(strLastIndexedItem) + MessageService.NewParagraph + strLine)); } bEmptyEntry = false; } strLastLine = strLine; } } } } KeePass/DataExchange/Formats/DashlaneCsv2.cs0000664000000000000000000001305313222430404017640 0ustar rootroot/* KeePass Password Safe - The Open-Source Password Manager Copyright (C) 2003-2018 Dominik Reichl This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ using System; using System.Collections.Generic; using System.Diagnostics; using System.Drawing; using System.IO; using System.Text; using System.Text.RegularExpressions; using KeePass.Resources; using KeePassLib; using KeePassLib.Interfaces; using KeePassLib.Native; using KeePassLib.Utility; namespace KeePass.DataExchange.Formats { // 2.3.2-5.0.1+ internal sealed class DashlaneCsv2 : FileFormatProvider { public override bool SupportsImport { get { return true; } } public override bool SupportsExport { get { return false; } } public override string FormatName { get { return "Dashlane CSV"; } } public override string DefaultExtension { get { return "csv"; } } public override string ApplicationGroup { get { return KPRes.PasswordManagers; } } public override bool ImportAppendsToRootGroupOnly { get { return true; } } public override Image SmallIcon { get { return KeePass.Properties.Resources.B16x16_Imp_Dashlane; } } public override void Import(PwDatabase pwStorage, Stream sInput, IStatusLogger slLogger) { StreamReader sr = new StreamReader(sInput, StrUtil.Utf8, true); string str = sr.ReadToEnd(); sr.Close(); // All fields are enclosed in '"', however '"' in data is // not encoded (broken format) str = str.Trim(); str = StrUtil.NormalizeNewLines(str, false); // To Unix char chFieldSep = StrUtil.GetUnusedChar(str); str = str.Replace("\",\"", new string(chFieldSep, 1)); char chRecSep = StrUtil.GetUnusedChar(str); str = str.Replace("\"\n\"", new string(chRecSep, 1)); if(str.StartsWith("\"") && str.EndsWith("\"") && (str.Length >= 2)) str = str.Substring(1, str.Length - 2); else { Debug.Assert(false); } if(!NativeLib.IsUnix()) str = StrUtil.NormalizeNewLines(str, true); CsvOptions opt = new CsvOptions(); opt.BackslashIsEscape = false; opt.FieldSeparator = chFieldSep; opt.RecordSeparator = chRecSep; opt.TextQualifier = char.MinValue; CsvStreamReaderEx csr = new CsvStreamReaderEx(str, opt); while(true) { string[] vLine = csr.ReadLine(); if(vLine == null) break; AddEntry(vLine, pwStorage); } } private static Regex m_rxIsDate = null; private static Regex m_rxIsGuid = null; private static void AddEntry(string[] vLine, PwDatabase pd) { int n = vLine.Length; if(n == 0) return; PwEntry pe = new PwEntry(true, true); pd.RootGroup.AddEntry(pe, true); string[] vFields = null; if(n == 2) vFields = new string[2] { PwDefs.TitleField, PwDefs.UrlField }; else if(n == 3) vFields = new string[3] { PwDefs.TitleField, PwDefs.UrlField, PwDefs.UserNameField }; else if(n == 4) { if((vLine[2].Length == 0) && (vLine[3].Length == 0)) vFields = new string[4] { PwDefs.TitleField, PwDefs.UserNameField, PwDefs.NotesField, PwDefs.NotesField }; else vFields = new string[4] { PwDefs.TitleField, PwDefs.NotesField, PwDefs.UserNameField, PwDefs.NotesField }; } else if(n == 5) vFields = new string[5] { PwDefs.TitleField, PwDefs.UrlField, PwDefs.UserNameField, PwDefs.PasswordField, PwDefs.NotesField }; else if(n == 6) vFields = new string[6] { PwDefs.TitleField, PwDefs.UrlField, PwDefs.UserNameField, PwDefs.UserNameField, PwDefs.PasswordField, PwDefs.NotesField }; else if(n == 7) vFields = new string[7] { PwDefs.TitleField, PwDefs.UserNameField, PwDefs.NotesField, PwDefs.NotesField, PwDefs.NotesField, PwDefs.NotesField, PwDefs.NotesField }; if(m_rxIsDate == null) { m_rxIsDate = new Regex(@"^\d{4}-\d+-\d+$"); m_rxIsGuid = new Regex( @"^\{[0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{12}\}$"); } if((vLine[0].Length == 0) && (n >= 2) && m_rxIsDate.IsMatch(vLine[1])) { vFields = null; vLine[0] = KPRes.Id; for(int i = 1; i < n; ++i) { string strPart = vLine[i]; if(strPart.Equals("NO_TYPE", StrUtil.CaseIgnoreCmp) || m_rxIsGuid.IsMatch(strPart)) vLine[i] = string.Empty; } } for(int i = 0; i < n; ++i) { string str = vLine[i]; if(str.Length == 0) continue; if(str.Equals("dashlaneappcredential", StrUtil.CaseIgnoreCmp)) continue; string strField = ((vFields != null) ? vFields[i] : null); if(strField == null) { if(i == 0) strField = PwDefs.TitleField; else strField = PwDefs.NotesField; } if((strField == PwDefs.UrlField) && (str.IndexOf('.') >= 0)) str = ImportUtil.FixUrl(str); ImportUtil.AppendToField(pe, strField, str, pd, ((strField == PwDefs.NotesField) ? MessageService.NewLine : ", "), false); } } } } KeePass/DataExchange/Formats/PwAgentXml234.cs0000664000000000000000000001313013222430404017636 0ustar rootroot/* KeePass Password Safe - The Open-Source Password Manager Copyright (C) 2003-2018 Dominik Reichl This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ using System; using System.Collections.Generic; using System.Text; using System.Xml; using System.IO; using System.Diagnostics; using System.Drawing; using KeePass.Resources; using KeePass.Util; using KeePassLib; using KeePassLib.Interfaces; using KeePassLib.Security; using KeePassLib.Utility; namespace KeePass.DataExchange.Formats { // 2.3.4-2.6.2+ internal sealed class PwAgentXml234 : FileFormatProvider { private const string ElemGroup = "group"; private const string ElemGroupName = "name"; private const string ElemEntry = "entry"; private const string ElemEntryName = "name"; private const string ElemEntryType = "type"; private const string ElemEntryUser = "account"; private const string ElemEntryPassword = "password"; private const string ElemEntryURL = "link"; private const string ElemEntryNotes = "note"; private const string ElemEntryCreationTime = "date_added"; private const string ElemEntryLastModTime = "date_modified"; private const string ElemEntryExpireTime = "date_expire"; public override bool SupportsImport { get { return true; } } public override bool SupportsExport { get { return false; } } public override string FormatName { get { return "Password Agent XML"; } } public override string DefaultExtension { get { return "xml"; } } public override string ApplicationGroup { get { return KPRes.PasswordManagers; } } public override Image SmallIcon { get { return KeePass.Properties.Resources.B16x16_Imp_PwAgent; } } public override void Import(PwDatabase pwStorage, Stream sInput, IStatusLogger slLogger) { StreamReader sr = new StreamReader(sInput, Encoding.Default); XmlDocument xmlDoc = new XmlDocument(); xmlDoc.Load(sr); sr.Close(); sInput.Close(); XmlNode xmlRoot = xmlDoc.DocumentElement; foreach(XmlNode xmlChild in xmlRoot.ChildNodes) { if(xmlChild.Name == ElemGroup) ReadGroup(xmlChild, pwStorage.RootGroup, pwStorage); else { Debug.Assert(false); } } } private static void ReadGroup(XmlNode xmlNode, PwGroup pgParent, PwDatabase pwStorage) { PwGroup pg = new PwGroup(true, true); pgParent.AddGroup(pg, true); foreach(XmlNode xmlChild in xmlNode) { if(xmlChild.Name == ElemGroupName) pg.Name = XmlUtil.SafeInnerText(xmlChild); else if(xmlChild.Name == ElemGroup) ReadGroup(xmlChild, pg, pwStorage); else if(xmlChild.Name == ElemEntry) ReadEntry(xmlChild, pg, pwStorage); else { Debug.Assert(false); } } } private static void ReadEntry(XmlNode xmlNode, PwGroup pgParent, PwDatabase pwStorage) { PwEntry pe = new PwEntry(true, true); pgParent.AddEntry(pe, true); DateTime dt; foreach(XmlNode xmlChild in xmlNode) { if(xmlChild.Name == ElemEntryName) pe.Strings.Set(PwDefs.TitleField, new ProtectedString( pwStorage.MemoryProtection.ProtectTitle, XmlUtil.SafeInnerText(xmlChild))); else if(xmlChild.Name == ElemEntryType) pe.IconId = ((XmlUtil.SafeInnerText(xmlChild) != "1") ? PwIcon.Key : PwIcon.PaperNew); else if(xmlChild.Name == ElemEntryUser) pe.Strings.Set(PwDefs.UserNameField, new ProtectedString( pwStorage.MemoryProtection.ProtectUserName, XmlUtil.SafeInnerText(xmlChild))); else if(xmlChild.Name == ElemEntryPassword) pe.Strings.Set(PwDefs.PasswordField, new ProtectedString( pwStorage.MemoryProtection.ProtectPassword, XmlUtil.SafeInnerText(xmlChild))); else if(xmlChild.Name == ElemEntryURL) pe.Strings.Set(PwDefs.UrlField, new ProtectedString( pwStorage.MemoryProtection.ProtectUrl, XmlUtil.SafeInnerText(xmlChild))); else if(xmlChild.Name == ElemEntryNotes) pe.Strings.Set(PwDefs.NotesField, new ProtectedString( pwStorage.MemoryProtection.ProtectNotes, XmlUtil.SafeInnerText(xmlChild))); else if(xmlChild.Name == ElemEntryCreationTime) { if(ParseDate(xmlChild, out dt)) pe.CreationTime = dt; } else if(xmlChild.Name == ElemEntryLastModTime) { if(ParseDate(xmlChild, out dt)) pe.LastModificationTime = dt; } else if(xmlChild.Name == ElemEntryExpireTime) { if(ParseDate(xmlChild, out dt)) { pe.ExpiryTime = dt; pe.Expires = true; } } else { Debug.Assert(false); } } } private static bool ParseDate(XmlNode xn, out DateTime dtOut) { string strDate = XmlUtil.SafeInnerText(xn); if(strDate.Length == 0) { dtOut = DateTime.UtcNow; return false; } if(DateTime.TryParse(strDate, out dtOut)) { dtOut = TimeUtil.ToUtc(dtOut, false); return true; } Debug.Assert(false); dtOut = DateTime.UtcNow; return false; } } } KeePass/DataExchange/Formats/KeePassKdb2xRepair.cs0000664000000000000000000001042713222430404020756 0ustar rootroot/* KeePass Password Safe - The Open-Source Password Manager Copyright (C) 2003-2018 Dominik Reichl This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ using System; using System.Collections.Generic; using System.Text; using System.Drawing; using System.IO; using System.Windows.Forms; using KeePass.App; using KeePass.Native; using KeePass.Resources; using KeePass.UI; using KeePassLib; using KeePassLib.Interfaces; using KeePassLib.Serialization; using KeePassLib.Utility; namespace KeePass.DataExchange.Formats { internal sealed class KeePassKdb2xRepair : FileFormatProvider { public override bool SupportsImport { get { return true; } } public override bool SupportsExport { get { return false; } } public override string FormatName { get { return "KeePass KDBX (2.x) (" + KPRes.RepairMode + ")"; } } public override string DefaultExtension { get { return AppDefs.FileExtension.FileExt; } } public override string ApplicationGroup { get { return PwDefs.ShortProductName; } } public override bool SupportsUuids { get { return true; } } public override bool RequiresKey { get { return true; } } public override Image SmallIcon { get { return KeePass.Properties.Resources.B16x16_KeePass; } } public override bool TryBeginImport() { string strTitle = KPRes.Warning + "!"; string strMsg = KPRes.RepairModeInt + MessageService.NewParagraph + KPRes.RepairModeUse + MessageService.NewParagraph + KPRes.RepairModeQ; int iYes = (int)DialogResult.Yes; int iNo = (int)DialogResult.No; int r = VistaTaskDialog.ShowMessageBoxEx(strMsg, strTitle, PwDefs.ShortProductName, VtdIcon.Warning, null, KPRes.YesCmd, iYes, KPRes.NoCmd, iNo); if(r < 0) r = (MessageService.AskYesNo(strTitle + MessageService.NewParagraph + strMsg, PwDefs.ShortProductName, false, MessageBoxIcon.Warning) ? iYes : iNo); return ((r == iYes) || (r == (int)DialogResult.OK)); } public override void Import(PwDatabase pwStorage, Stream sInput, IStatusLogger slLogger) { KdbxFile kdbx = new KdbxFile(pwStorage); // CappedByteStream s = new CappedByteStream(sInput, 64); kdbx.RepairMode = true; try { kdbx.Load(sInput, KdbxFormat.Default, slLogger); } catch(Exception) { } } /* private sealed class CappedByteStream : Stream { private Stream m_sBase; private int m_nMaxRead; public override bool CanRead { get { return m_sBase.CanRead; } } public override bool CanSeek { get { return m_sBase.CanSeek; } } public override bool CanWrite { get { return m_sBase.CanWrite; } } public override long Length { get { return m_sBase.Length; } } public override long Position { get { return m_sBase.Position; } set { m_sBase.Position = value; } } public CappedByteStream(Stream sBase, int nMaxRead) { if(sBase == null) throw new ArgumentNullException("sBase"); if(nMaxRead <= 0) throw new ArgumentException(); m_sBase = sBase; m_nMaxRead = nMaxRead; } public override void Flush() { m_sBase.Flush(); } public override int Read(byte[] buffer, int offset, int count) { if(count > m_nMaxRead) count = m_nMaxRead; return m_sBase.Read(buffer, offset, count); } public override long Seek(long offset, SeekOrigin origin) { return m_sBase.Seek(offset, origin); } public override void SetLength(long value) { m_sBase.SetLength(value); } public override void Write(byte[] buffer, int offset, int count) { m_sBase.Write(buffer, offset, count); } } */ } } KeePass/DataExchange/Formats/LastPassCsv2.cs0000664000000000000000000001224013222430404017650 0ustar rootroot/* KeePass Password Safe - The Open-Source Password Manager Copyright (C) 2003-2018 Dominik Reichl This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ using System; using System.Collections.Generic; using System.Text; using System.IO; using System.Drawing; using System.Diagnostics; using KeePass.Resources; using KeePassLib; using KeePassLib.Interfaces; using KeePassLib.Utility; namespace KeePass.DataExchange.Formats { // 2.0.2-4.1.35+ internal sealed class LastPassCsv2 : FileFormatProvider { public override bool SupportsImport { get { return true; } } public override bool SupportsExport { get { return false; } } public override string FormatName { get { return "LastPass CSV"; } } public override string DefaultExtension { get { return "csv"; } } public override string ApplicationGroup { get { return KPRes.PasswordManagers; } } public override bool ImportAppendsToRootGroupOnly { get { return false; } } public override Image SmallIcon { get { return KeePass.Properties.Resources.B16x16_Imp_LastPass; } } public override void Import(PwDatabase pwStorage, Stream sInput, IStatusLogger slLogger) { StreamReader sr = new StreamReader(sInput, StrUtil.Utf8, true); string strData = sr.ReadToEnd(); sr.Close(); // The Chrome extension of LastPass 4.1.35 encodes some // special characters as XML entities; the web version and // the Firefox extension do not do this strData = strData.Replace(@"<", @"<"); strData = strData.Replace(@">", @">"); strData = strData.Replace(@"&", @"&"); CsvOptions opt = new CsvOptions(); opt.BackslashIsEscape = false; CsvStreamReaderEx csr = new CsvStreamReaderEx(strData, opt); while(true) { string[] vLine = csr.ReadLine(); if(vLine == null) break; AddEntry(vLine, pwStorage); } } private static void AddEntry(string[] vLine, PwDatabase pd) { Debug.Assert((vLine.Length == 0) || (vLine.Length == 7)); if(vLine.Length < 5) return; // Skip header line if((vLine[1] == "username") && (vLine[2] == "password") && (vLine[3] == "extra") && (vLine[4] == "name")) return; PwEntry pe = new PwEntry(true, true); PwGroup pg = pd.RootGroup; if(vLine.Length >= 6) { string strGroup = vLine[5]; if(strGroup.Length > 0) pg = pg.FindCreateSubTree(strGroup, new string[1]{ "\\" }, true); } pg.AddEntry(pe, true); ImportUtil.AppendToField(pe, PwDefs.TitleField, vLine[4], pd); ImportUtil.AppendToField(pe, PwDefs.UserNameField, vLine[1], pd); ImportUtil.AppendToField(pe, PwDefs.PasswordField, vLine[2], pd); string strNotes = vLine[3]; bool bIsSecNote = vLine[0].Equals("http://sn", StrUtil.CaseIgnoreCmp); if(bIsSecNote) { if(strNotes.StartsWith("NoteType:", StrUtil.CaseIgnoreCmp)) AddNoteFields(pe, strNotes, pd); else ImportUtil.AppendToField(pe, PwDefs.NotesField, strNotes, pd); } else // Standard entry, no secure note { ImportUtil.AppendToField(pe, PwDefs.UrlField, vLine[0], pd); Debug.Assert(!strNotes.StartsWith("NoteType:")); ImportUtil.AppendToField(pe, PwDefs.NotesField, strNotes, pd); } if(vLine.Length >= 7) { if(StrUtil.StringToBool(vLine[6])) pe.AddTag("Favorite"); } } private static void AddNoteFields(PwEntry pe, string strNotes, PwDatabase pd) { string strData = StrUtil.NormalizeNewLines(strNotes, false); string[] vLines = strData.Split('\n'); string strFieldName = PwDefs.NotesField; bool bNotesFound = false; foreach(string strLine in vLines) { int iFieldLen = strLine.IndexOf(':'); int iDataOffset = 0; if((iFieldLen > 0) && !bNotesFound) { string strRaw = strLine.Substring(0, iFieldLen).Trim(); string strField = ImportUtil.MapNameToStandardField(strRaw, false); if(string.IsNullOrEmpty(strField)) strField = strRaw; if(strField.Length > 0) { strFieldName = strField; iDataOffset = iFieldLen + 1; bNotesFound |= (strRaw == "Notes"); // Not PwDefs.NotesField } } bool bSingle = ((strFieldName == PwDefs.TitleField) || (strFieldName == PwDefs.UserNameField) || (strFieldName == PwDefs.PasswordField) || (strFieldName == PwDefs.UrlField)); string strSep = (bSingle ? ", " : "\r\n"); ImportUtil.AppendToField(pe, strFieldName, strLine.Substring( iDataOffset), pd, strSep, bSingle); } } } } KeePass/DataExchange/Formats/KeePassKdb1x.cs0000664000000000000000000000674213222430404017617 0ustar rootroot/* KeePass Password Safe - The Open-Source Password Manager Copyright (C) 2003-2018 Dominik Reichl This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ using System; using System.Collections.Generic; using System.Text; using System.Drawing; using System.Windows.Forms; using System.IO; using KeePass.Resources; using KeePassLib; using KeePassLib.Interfaces; using KeePassLib.Native; using KeePassLib.Utility; namespace KeePass.DataExchange.Formats { internal sealed class KeePassKdb1x : FileFormatProvider { public override bool SupportsImport { get { return true; } } public override bool SupportsExport { get { return true; } } public override string FormatName { get { return "KeePass KDB (1.x)"; } } public override string DefaultExtension { get { return "kdb"; } } public override string ApplicationGroup { get { return PwDefs.ShortProductName; } } public override bool SupportsUuids { get { return true; } } public override bool RequiresKey { get { return true; } } public override Image SmallIcon { get { return KeePass.Properties.Resources.B16x16_KeePass; } } public override bool TryBeginImport() { if(NativeLib.IsUnix()) { MessageService.ShowWarning(KPRes.KeePassLibCNotWindows, KPRes.KeePassLibCNotWindowsHint); return false; } Exception exLib; if(!KdbFile.IsLibraryInstalled(out exLib)) { MessageService.ShowWarning(KPRes.KeePassLibCNotFound, KPRes.KdbKeePassLibC, exLib); return false; } return true; } public override bool TryBeginExport() { return TryBeginImport(); } public override void Import(PwDatabase pwStorage, Stream sInput, IStatusLogger slLogger) { string strTempFile = Program.TempFilesPool.GetTempFileName(); BinaryReader br = new BinaryReader(sInput); byte[] pb = br.ReadBytes((int)sInput.Length); br.Close(); File.WriteAllBytes(strTempFile, pb); KdbFile kdb = new KdbFile(pwStorage, slLogger); kdb.Load(strTempFile); Program.TempFilesPool.Delete(strTempFile); } public override bool Export(PwExportInfo pwExportInfo, Stream sOutput, IStatusLogger slLogger) { PwDatabase pd = (pwExportInfo.ContextDatabase ?? new PwDatabase()); string strTempFile = Program.TempFilesPool.GetTempFileName(false); try { KdbFile kdb = new KdbFile(pd, slLogger); kdb.Save(strTempFile, pwExportInfo.DataGroup); byte[] pbKdb = File.ReadAllBytes(strTempFile); sOutput.Write(pbKdb, 0, pbKdb.Length); MemUtil.ZeroByteArray(pbKdb); } catch(Exception exKdb) { if(slLogger != null) slLogger.SetText(exKdb.Message, LogStatusType.Error); return false; } finally { Program.TempFilesPool.Delete(strTempFile); } return true; } } } KeePass/DataExchange/Formats/PwsPlusCsv1007.cs0000664000000000000000000000773713222430406020002 0ustar rootroot/* KeePass Password Safe - The Open-Source Password Manager Copyright (C) 2003-2018 Dominik Reichl This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ using System; using System.Collections.Generic; using System.Text; using System.Drawing; using System.IO; using System.Diagnostics; using KeePass.Resources; using KeePassLib; using KeePassLib.Interfaces; using KeePassLib.Security; using KeePassLib.Utility; namespace KeePass.DataExchange.Formats { internal sealed class PwsPlusCsv1007 : FileFormatProvider { public override bool SupportsImport { get { return true; } } public override bool SupportsExport { get { return false; } } public override string FormatName { get { return "Passwords Plus CSV"; } } public override string DefaultExtension { get { return "csv"; } } public override string ApplicationGroup { get { return KPRes.PasswordManagers; } } public override Image SmallIcon { get { return KeePass.Properties.Resources.B16x16_Imp_PwsPlus; } } public override void Import(PwDatabase pwStorage, Stream sInput, IStatusLogger slLogger) { StreamReader sr = new StreamReader(sInput, Encoding.Default); string strData = sr.ReadToEnd(); sr.Close(); CsvStreamReader csv = new CsvStreamReader(strData, true); Dictionary dictGroups = new Dictionary(); while(true) { string[] vLine = csv.ReadLine(); if(vLine == null) break; if(vLine.Length == 0) continue; // Skip empty line if(vLine.Length == 5) continue; // Skip header line if(vLine.Length != 34) { Debug.Assert(false); continue; } string strType = vLine[0].Trim(); if(strType.Equals("Is Template", StrUtil.CaseIgnoreCmp)) continue; if(strType.Equals("1")) continue; // Skip template string strGroup = vLine[2].Trim(); PwGroup pg; if(strGroup.Length == 0) pg = pwStorage.RootGroup; else { if(dictGroups.ContainsKey(strGroup)) pg = dictGroups[strGroup]; else { pg = new PwGroup(true, true, strGroup, PwIcon.Folder); pwStorage.RootGroup.AddGroup(pg, true); dictGroups[strGroup] = pg; } } PwEntry pe = new PwEntry(true, true); pg.AddEntry(pe, true); string strTitle = vLine[1].Trim(); if(strTitle.Length > 0) ImportUtil.AppendToField(pe, PwDefs.TitleField, strTitle, pwStorage); for(int i = 0; i < 10; ++i) { string strKey = vLine[(i * 3) + 3].Trim(); string strValue = vLine[(i * 3) + 4].Trim(); if((strKey.Length == 0) || (strValue.Length == 0)) continue; string strMapped = ImportUtil.MapNameToStandardField(strKey, true); if(string.IsNullOrEmpty(strMapped)) strMapped = strKey; ImportUtil.AppendToField(pe, strMapped, strValue, pwStorage); } string strNotesPre = pe.Strings.ReadSafe(PwDefs.NotesField); string strNotes = vLine[33].Trim(); if(strNotes.Length > 0) { if(strNotesPre.Length == 0) ImportUtil.AppendToField(pe, PwDefs.NotesField, strNotes, pwStorage); else pe.Strings.Set(PwDefs.NotesField, new ProtectedString( ((pwStorage == null) ? false : pwStorage.MemoryProtection.ProtectNotes), strNotesPre + Environment.NewLine + Environment.NewLine + strNotes)); } } } } } KeePass/DataExchange/Formats/ZdnPwProTxt314.cs0000664000000000000000000001260513222430406020042 0ustar rootroot/* KeePass Password Safe - The Open-Source Password Manager Copyright (C) 2003-2018 Dominik Reichl This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ using System; using System.Collections.Generic; using System.Text; using System.Drawing; using System.IO; using System.Diagnostics; using KeePass.Resources; using KeePassLib; using KeePassLib.Interfaces; using KeePassLib.Security; using KeePassLib.Utility; namespace KeePass.DataExchange.Formats { // 3.1.4 internal sealed class ZdnPwProTxt314 : FileFormatProvider { public override bool SupportsImport { get { return true; } } public override bool SupportsExport { get { return false; } } public override string FormatName { get { return "ZDNet's Password Pro TXT"; } } public override string DefaultExtension { get { return "txt"; } } public override string ApplicationGroup { get { return KPRes.PasswordManagers; } } public override bool ImportAppendsToRootGroupOnly { get { return true; } } public override Image SmallIcon { get { return KeePass.Properties.Resources.B16x16_Imp_ZdnPwPro; } } private const string StrFieldUser = "User Name: "; private const string StrFieldPw = "Password: "; private const string StrFieldUrl = "Shortcut: "; private const string StrFieldExpires = "Expires: "; private const string StrFieldType = "Type: "; private const string StrFieldNotes = "Comments: "; public override void Import(PwDatabase pwStorage, Stream sInput, IStatusLogger slLogger) { StreamReader sr = new StreamReader(sInput, Encoding.Default); string strData = sr.ReadToEnd(); sr.Close(); strData = strData.Replace("\r", string.Empty); string[] vLines = strData.Split(new char[] { '\n' }); if(vLines.Length >= 1) { Debug.Assert(vLines[0].StartsWith("Contents of: ")); vLines[0] = string.Empty; // Trigger 'new entry' below } Dictionary dItems = new Dictionary(); bool bInNotes = false; DateTime? dtExpire = null; for(int i = 0; i < vLines.Length; ++i) { string strLine = vLines[i]; if((i + 2) < vLines.Length) { string strSep = new string('-', vLines[i + 1].Length); if((strLine.Length == 0) && (vLines[i + 2] == strSep) && (strSep.Length > 0)) { AddEntry(pwStorage.RootGroup, dItems, ref bInNotes, ref dtExpire); dItems.Clear(); dItems[PwDefs.TitleField] = vLines[i + 1]; i += 2; continue; } } if(bInNotes) { if(dItems.ContainsKey(PwDefs.NotesField)) dItems[PwDefs.NotesField] += MessageService.NewLine + strLine; else dItems[PwDefs.NotesField] = strLine; } else if(strLine.StartsWith(StrFieldUser)) AddField(dItems, PwDefs.UserNameField, strLine.Substring( StrFieldUser.Length)); else if(strLine.StartsWith(StrFieldPw)) AddField(dItems, PwDefs.PasswordField, strLine.Substring( StrFieldPw.Length)); else if(strLine.StartsWith(StrFieldUrl)) AddField(dItems, PwDefs.UrlField, strLine.Substring( StrFieldUrl.Length)); else if(strLine.StartsWith(StrFieldType)) AddField(dItems, "Type", strLine.Substring(StrFieldType.Length)); else if(strLine.StartsWith(StrFieldExpires)) { string strExp = strLine.Substring(StrFieldExpires.Length); DateTime dtExp; if(DateTime.TryParse(strExp, out dtExp)) dtExpire = TimeUtil.ToUtc(dtExp, false); else { Debug.Assert(false); } } else if(strLine.StartsWith(StrFieldNotes)) { AddField(dItems, PwDefs.NotesField, strLine.Substring( StrFieldNotes.Length)); bInNotes = true; } else { Debug.Assert(false); } } AddEntry(pwStorage.RootGroup, dItems, ref bInNotes, ref dtExpire); Debug.Assert(!dtExpire.HasValue); } private static void AddField(Dictionary dItems, string strKey, string strValue) { if(!dItems.ContainsKey(strKey)) { dItems[strKey] = strValue; return; } string strPreValue = dItems[strKey]; if((strPreValue.Length > 0) && (strValue.Length > 0)) strPreValue += ", "; dItems[strKey] = strPreValue + strValue; } private static void AddEntry(PwGroup pg, Dictionary dItems, ref bool bInNotes, ref DateTime? dtExpire) { if(dItems.Count > 0) { PwEntry pe = new PwEntry(true, true); pg.AddEntry(pe, true); foreach(KeyValuePair kvp in dItems) pe.Strings.Set(kvp.Key, new ProtectedString(false, kvp.Value)); if(dtExpire.HasValue) { pe.Expires = true; pe.ExpiryTime = dtExpire.Value; } } bInNotes = false; dtExpire = null; } } } KeePass/DataExchange/Formats/NPasswordNpw102.cs0000664000000000000000000001765113222430404020223 0ustar rootroot/* KeePass Password Safe - The Open-Source Password Manager Copyright (C) 2003-2018 Dominik Reichl This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ using System; using System.Collections.Generic; using System.Diagnostics; using System.Drawing; using System.IO; using System.Text; using System.Xml; using KeePass.Resources; using KeePass.Util; using KeePassLib; using KeePassLib.Interfaces; using KeePassLib.Resources; using KeePassLib.Security; using KeePassLib.Utility; namespace KeePass.DataExchange.Formats { // 1.0.2.41 internal sealed class NPasswordNpw102 : FileFormatProvider { private const string ElemGroup = "folder"; private const string ElemEntry = "record"; private const string ElemEntryUser = "login"; private const string ElemEntryPassword = "pass"; private const string ElemEntryPassword2 = "additional"; private const string ElemEntryUrl = "link"; private const string ElemEntryNotes = "comments"; private const string ElemEntryExpires = "expires"; private const string ElemEntryExpiryTime = "expire_date"; private const string ElemEntryUnsupp0 = "data"; private const string ElemEntryUnsupp1 = "script"; private const string ElemAutoType = "macro"; private const string ElemAutoTypePlh = "item"; private const string ElemTags = "keywords"; private const string ElemUnsupp0 = "settings"; private const string Password2Key = PwDefs.PasswordField + " 2"; private static Dictionary m_dAutoTypeConv = null; public override bool SupportsImport { get { return true; } } public override bool SupportsExport { get { return false; } } public override string FormatName { get { return "nPassword NPW"; } } public override string DefaultExtension { get { return "npw"; } } public override string ApplicationGroup { get { return KPRes.PasswordManagers; } } public override Image SmallIcon { get { return KeePass.Properties.Resources.B16x16_Imp_NPassword; } } public override void Import(PwDatabase pwStorage, Stream sInput, IStatusLogger slLogger) { if(m_dAutoTypeConv == null) { Dictionary d = new Dictionary(); d[@"{login}"] = @"{USERNAME}"; d[@"{password}"] = @"{PASSWORD}"; d[@"{additional key}"] = @"{S:" + Password2Key + @"}"; d[@"{url}"] = @"{URL}"; d[@"{memo}"] = @"{NOTES}"; d[@"[tab]"] = @"{TAB}"; d[@"[enter]"] = @"{ENTER}"; m_dAutoTypeConv = d; } MemoryStream ms = new MemoryStream(); MemUtil.CopyStream(sInput, ms); byte[] pbData = ms.ToArray(); ms.Close(); string strFmt = KLRes.FileLoadFailed + MessageService.NewParagraph + KPRes.NoEncNoCompress; // The file must start with " 0) { if(pg.Name.Length > 0) pg.Name += " "; pg.Name += strValue; } } else if(xmlChild.Name == ElemGroup) ReadGroup(xmlChild, pg, pwStorage); else if(xmlChild.Name == ElemEntry) ReadEntry(xmlChild, pg, pwStorage); else if(xmlChild.Name == ElemTags) { } else { Debug.Assert(false); } } } private static void ReadEntry(XmlNode xmlNode, PwGroup pgParent, PwDatabase pwStorage) { PwEntry pe = new PwEntry(true, true); pgParent.AddEntry(pe, true); DateTime? odtExpiry = null; foreach(XmlNode xmlChild in xmlNode) { string strValue = XmlUtil.SafeInnerText(xmlChild); if(xmlChild.NodeType == XmlNodeType.Text) ImportUtil.AppendToField(pe, PwDefs.TitleField, (xmlChild.Value ?? string.Empty).Trim(), pwStorage, " ", false); else if(xmlChild.Name == ElemEntryUser) pe.Strings.Set(PwDefs.UserNameField, new ProtectedString( pwStorage.MemoryProtection.ProtectUserName, strValue)); else if(xmlChild.Name == ElemEntryPassword) pe.Strings.Set(PwDefs.PasswordField, new ProtectedString( pwStorage.MemoryProtection.ProtectPassword, strValue)); else if(xmlChild.Name == ElemEntryPassword2) { if(strValue.Length > 0) // Prevent empty item pe.Strings.Set(Password2Key, new ProtectedString( pwStorage.MemoryProtection.ProtectPassword, strValue)); } else if(xmlChild.Name == ElemEntryUrl) pe.Strings.Set(PwDefs.UrlField, new ProtectedString( pwStorage.MemoryProtection.ProtectUrl, strValue)); else if(xmlChild.Name == ElemEntryNotes) pe.Strings.Set(PwDefs.NotesField, new ProtectedString( pwStorage.MemoryProtection.ProtectNotes, strValue)); else if(xmlChild.Name == ElemTags) { string strTags = strValue.Replace(' ', ';'); List vTags = StrUtil.StringToTags(strTags); foreach(string strTag in vTags) { pe.AddTag(strTag); } } else if(xmlChild.Name == ElemEntryExpires) pe.Expires = StrUtil.StringToBool(strValue); else if(xmlChild.Name == ElemEntryExpiryTime) { DateTime dt; if(TimeUtil.FromDisplayStringEx(strValue, out dt)) odtExpiry = TimeUtil.ToUtc(dt, false); else { Debug.Assert(false); } } else if(xmlChild.Name == ElemAutoType) ReadAutoType(xmlChild, pe); else if(xmlChild.Name == ElemEntryUnsupp0) { } else if(xmlChild.Name == ElemEntryUnsupp1) { } else { Debug.Assert(false); } } if(odtExpiry.HasValue) pe.ExpiryTime = odtExpiry.Value; else pe.Expires = false; } private static void ReadAutoType(XmlNode xmlNode, PwEntry pe) { string strSeq = string.Empty; foreach(XmlNode xmlChild in xmlNode) { if(xmlChild.Name == ElemAutoTypePlh) { string strValue = XmlUtil.SafeInnerText(xmlChild); string strConv = null; foreach(KeyValuePair kvp in m_dAutoTypeConv) { if(kvp.Key.Equals(strValue, StrUtil.CaseIgnoreCmp)) { strConv = kvp.Value; break; } } if(strConv != null) strSeq += strConv; else { Debug.Assert(false); strSeq += strValue; } } else { Debug.Assert(false); } } pe.AutoType.DefaultSequence = strSeq; } } } KeePass/DataExchange/Formats/KeePassCsv1x.cs0000664000000000000000000001343313222430404017645 0ustar rootroot/* KeePass Password Safe - The Open-Source Password Manager Copyright (C) 2003-2018 Dominik Reichl This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ using System; using System.Collections.Generic; using System.Text; using System.Diagnostics; using System.Drawing; using System.IO; using KeePassLib; using KeePassLib.Delegates; using KeePassLib.Interfaces; using KeePassLib.Security; using KeePassLib.Utility; namespace KeePass.DataExchange.Formats { internal sealed class KeePassCsv1x : FileFormatProvider { public override bool SupportsImport { get { return false; } } public override bool SupportsExport { get { return true; } } public override string FormatName { get { return "KeePass CSV (1.x)"; } } public override string DefaultExtension { get { return "csv"; } } public override string ApplicationGroup { get { return PwDefs.ShortProductName; } } // public override bool ImportAppendsToRootGroupOnly { get { return true; } } public override Image SmallIcon { get { return KeePass.Properties.Resources.B16x16_KeePass; } } /* public override void Import(PwDatabase pwStorage, Stream sInput, IStatusLogger slLogger) { StreamReader sr = new StreamReader(sInput, Encoding.UTF8); string strFileContents = sr.ReadToEnd(); sr.Close(); CharStream csSource = new CharStream(strFileContents); while(true) { if(ReadEntry(pwStorage, csSource) == false) break; } } private static bool ReadEntry(PwDatabase pwStorage, CharStream csSource) { PwEntry pe = new PwEntry(true, true); string strTitle = ReadCsvField(csSource); if(strTitle == null) return false; // No entry available string strUser = ReadCsvField(csSource); if(strUser == null) throw new InvalidDataException(); string strPassword = ReadCsvField(csSource); if(strPassword == null) throw new InvalidDataException(); string strUrl = ReadCsvField(csSource); if(strUrl == null) throw new InvalidDataException(); string strNotes = ReadCsvField(csSource); if(strNotes == null) throw new InvalidDataException(); if((strTitle == "Account") && (strUser == "Login Name") && (strPassword == "Password") && (strUrl == "Web Site") && (strNotes == "Comments")) { return true; // Ignore header entry } pe.Strings.Set(PwDefs.TitleField, new ProtectedString( pwStorage.MemoryProtection.ProtectTitle, strTitle)); pe.Strings.Set(PwDefs.UserNameField, new ProtectedString( pwStorage.MemoryProtection.ProtectUserName, strUser)); pe.Strings.Set(PwDefs.PasswordField, new ProtectedString( pwStorage.MemoryProtection.ProtectPassword, strPassword)); pe.Strings.Set(PwDefs.UrlField, new ProtectedString( pwStorage.MemoryProtection.ProtectUrl, strUrl)); pe.Strings.Set(PwDefs.NotesField, new ProtectedString( pwStorage.MemoryProtection.ProtectNotes, strNotes)); pwStorage.RootGroup.AddEntry(pe, true); return true; } private static string ReadCsvField(CharStream csSource) { StringBuilder sb = new StringBuilder(); bool bInField = false; while(true) { char ch = csSource.ReadChar(); if(ch == char.MinValue) return null; if((ch == '\"') && !bInField) bInField = true; else if((ch == '\"') && bInField) break; else if(ch == '\\') { char chSub = csSource.ReadChar(); if(chSub == char.MinValue) throw new InvalidDataException(); sb.Append(chSub); } else if(bInField) sb.Append(ch); } return sb.ToString(); } */ public override bool Export(PwExportInfo pwExportInfo, Stream sOutput, IStatusLogger slLogger) { PwGroup pg = (pwExportInfo.DataGroup ?? ((pwExportInfo.ContextDatabase != null) ? pwExportInfo.ContextDatabase.RootGroup : null)); StreamWriter sw = new StreamWriter(sOutput, StrUtil.Utf8); sw.Write("\"Account\",\"Login Name\",\"Password\",\"Web Site\",\"Comments\"\r\n"); EntryHandler eh = delegate(PwEntry pe) { WriteCsvEntry(sw, pe); return true; }; if(pg != null) pg.TraverseTree(TraversalMethod.PreOrder, null, eh); sw.Close(); return true; } private static void WriteCsvEntry(StreamWriter sw, PwEntry pe) { if(sw == null) { Debug.Assert(false); return; } if(pe == null) { Debug.Assert(false); return; } const string strSep = "\",\""; sw.Write("\""); WriteCsvString(sw, pe.Strings.ReadSafe(PwDefs.TitleField), strSep); WriteCsvString(sw, pe.Strings.ReadSafe(PwDefs.UserNameField), strSep); WriteCsvString(sw, pe.Strings.ReadSafe(PwDefs.PasswordField), strSep); WriteCsvString(sw, pe.Strings.ReadSafe(PwDefs.UrlField), strSep); WriteCsvString(sw, pe.Strings.ReadSafe(PwDefs.NotesField), "\"\r\n"); } private static void WriteCsvString(StreamWriter sw, string strText, string strAppend) { string str = strText; if(!string.IsNullOrEmpty(str)) { str = str.Replace("\\", "\\\\"); str = str.Replace("\"", "\\\""); sw.Write(str); } if(!string.IsNullOrEmpty(strAppend)) sw.Write(strAppend); } } } KeePass/DataExchange/Formats/PassKeeper12.cs0000664000000000000000000000757113222430404017600 0ustar rootroot/* KeePass Password Safe - The Open-Source Password Manager Copyright (C) 2003-2018 Dominik Reichl This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ using System; using System.Collections.Generic; using System.Text; using System.Windows.Forms; using System.IO; using System.Drawing; using System.Threading; using KeePass.App; using KeePass.Native; using KeePass.Resources; using KeePass.Util; using KeePassLib; using KeePassLib.Interfaces; using KeePassLib.Security; using KeePassLib.Utility; namespace KeePass.DataExchange.Formats { // 1.2 internal sealed class PassKeeper12 : FileFormatProvider { public override bool SupportsImport { get { return true; } } public override bool SupportsExport { get { return false; } } public override string FormatName { get { return "PassKeeper"; } } public override string ApplicationGroup { get { return KPRes.PasswordManagers; } } public override bool RequiresFile { get { return false; } } public override bool ImportAppendsToRootGroupOnly { get { return true; } } public override Image SmallIcon { get { return KeePass.Properties.Resources.B16x16_Imp_PassKeeper; } } public override void Import(PwDatabase pwStorage, Stream sInput, IStatusLogger slLogger) { if(MessageService.AskYesNo(KPRes.ImportMustRead + MessageService.NewParagraph + KPRes.ImportMustReadQuestion) == false) { AppHelp.ShowHelp(AppDefs.HelpTopics.ImportExport, AppDefs.HelpTopics.ImportExportPassKeeper); return; } PwEntry pePrev = new PwEntry(true, true); for(int i = 0; i < 20; ++i) { Thread.Sleep(500); Application.DoEvents(); } try { while(true) { PwEntry pe = ImportEntry(pwStorage); if(ImportUtil.EntryEquals(pe, pePrev)) { if(pe.ParentGroup != null) // Remove duplicate pe.ParentGroup.Entries.Remove(pe); break; } ImportUtil.GuiSendKeysPrc(@"{DOWN}"); pePrev = pe; } MessageService.ShowInfo(KPRes.ImportFinished); } catch(Exception exImp) { MessageService.ShowWarning(exImp); } } private static PwEntry ImportEntry(PwDatabase pwDb) { ImportUtil.GuiSendWaitWindowChange(@"{ENTER}"); Thread.Sleep(250); ImportUtil.GuiSendKeysPrc(string.Empty); // Process messages string strTitle = ImportUtil.GuiSendRetrieve(string.Empty); string strUserName = ImportUtil.GuiSendRetrieve(@"{TAB}"); string strPassword = ImportUtil.GuiSendRetrieve(@"{TAB}"); string strNotes = ImportUtil.GuiSendRetrieve(@"{TAB}"); ImportUtil.GuiSendWaitWindowChange(@"{ESC}"); PwGroup pg = pwDb.RootGroup; PwEntry pe = new PwEntry(true, true); pg.AddEntry(pe, true); pe.Strings.Set(PwDefs.TitleField, new ProtectedString( pwDb.MemoryProtection.ProtectTitle, strTitle)); pe.Strings.Set(PwDefs.UserNameField, new ProtectedString( pwDb.MemoryProtection.ProtectUserName, strUserName)); pe.Strings.Set(PwDefs.PasswordField, new ProtectedString( pwDb.MemoryProtection.ProtectPassword, strPassword)); pe.Strings.Set(PwDefs.NotesField, new ProtectedString( pwDb.MemoryProtection.ProtectNotes, strNotes)); return pe; } } } KeePass/DataExchange/Formats/KeePassKdb2x.cs0000664000000000000000000001121413222430404017606 0ustar rootroot/* KeePass Password Safe - The Open-Source Password Manager Copyright (C) 2003-2018 Dominik Reichl This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ using System; using System.Collections.Generic; using System.Diagnostics; using System.Text; using System.Drawing; using System.IO; using KeePass.App; using KeePass.Resources; using KeePassLib; using KeePassLib.Collections; using KeePassLib.Cryptography.KeyDerivation; using KeePassLib.Delegates; using KeePassLib.Interfaces; using KeePassLib.Serialization; namespace KeePass.DataExchange.Formats { internal class KeePassKdb2x : FileFormatProvider { public override bool SupportsImport { get { return true; } } public override bool SupportsExport { get { return true; } } public override string FormatName { get { return "KeePass KDBX (2.x)"; } } public override string DefaultExtension { get { return AppDefs.FileExtension.FileExt; } } public override string ApplicationGroup { get { return PwDefs.ShortProductName; } } public override bool SupportsUuids { get { return true; } } public override bool RequiresKey { get { return true; } } public override Image SmallIcon { get { return KeePass.Properties.Resources.B16x16_KeePass; } } public override void Import(PwDatabase pwStorage, Stream sInput, IStatusLogger slLogger) { KdbxFile kdbx = new KdbxFile(pwStorage); kdbx.Load(sInput, KdbxFormat.Default, slLogger); } public override bool Export(PwExportInfo pwExportInfo, Stream sOutput, IStatusLogger slLogger) { KdbxFile kdbx = new KdbxFile(pwExportInfo.ContextDatabase); kdbx.Save(sOutput, pwExportInfo.DataGroup, KdbxFormat.Default, slLogger); return true; } } // KDBX 3.1 export module internal sealed class KeePassKdb2x3 : KeePassKdb2x { // Only list base class as import module public override bool SupportsImport { get { return false; } } public override string FormatName { get { return ("KeePass KDBX (2.34, " + KPRes.OldFormat + ")"); } } public override bool Export(PwExportInfo pwExportInfo, Stream sOutput, IStatusLogger slLogger) { PwDatabase pd = pwExportInfo.ContextDatabase; PwGroup pgRoot = pwExportInfo.DataGroup; // Remove everything that requires KDBX 4 or higher; // see also KdbxFile.GetMinKdbxVersion KdfParameters pKdf = pd.KdfParameters; AesKdf kdfAes = new AesKdf(); if(!kdfAes.Uuid.Equals(pKdf.KdfUuid)) pd.KdfParameters = kdfAes.GetDefaultParameters(); VariantDictionary vdPublic = pd.PublicCustomData; pd.PublicCustomData = new VariantDictionary(); List lCustomGK = new List(); List lCustomGV = new List(); List lCustomEK = new List(); List lCustomEV = new List(); GroupHandler gh = delegate(PwGroup pg) { if(pg == null) { Debug.Assert(false); return true; } if(pg.CustomData.Count > 0) { lCustomGK.Add(pg); lCustomGV.Add(pg.CustomData); pg.CustomData = new StringDictionaryEx(); } return true; }; EntryHandler eh = delegate(PwEntry pe) { if(pe == null) { Debug.Assert(false); return true; } if(pe.CustomData.Count > 0) { lCustomEK.Add(pe); lCustomEV.Add(pe.CustomData); pe.CustomData = new StringDictionaryEx(); } return true; }; gh(pgRoot); pgRoot.TraverseTree(TraversalMethod.PreOrder, gh, eh); try { KdbxFile kdbx = new KdbxFile(pd); kdbx.ForceVersion = KdbxFile.FileVersion32_3; kdbx.Save(sOutput, pgRoot, KdbxFormat.Default, slLogger); } finally { // Restore pd.KdfParameters = pKdf; pd.PublicCustomData = vdPublic; for(int i = 0; i < lCustomGK.Count; ++i) lCustomGK[i].CustomData = lCustomGV[i]; for(int i = 0; i < lCustomEK.Count; ++i) lCustomEK[i].CustomData = lCustomEV[i]; } return true; } } } KeePass/DataExchange/Formats/KeePassXml1x.cs0000664000000000000000000001631613222430404017655 0ustar rootroot/* KeePass Password Safe - The Open-Source Password Manager Copyright (C) 2003-2018 Dominik Reichl This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ using System; using System.Collections.Generic; using System.Text; using System.Drawing; using System.IO; using System.Xml; using System.Xml.Serialization; using System.Diagnostics; using KeePass.Resources; using KeePass.Util; using KeePassLib; using KeePassLib.Collections; using KeePassLib.Interfaces; using KeePassLib.Security; using KeePassLib.Serialization; using KeePassLib.Utility; namespace KeePass.DataExchange.Formats { internal sealed class KeePassXml1x : FileFormatProvider { public override bool SupportsImport { get { return true; } } public override bool SupportsExport { get { return false; } } public override string FormatName { get { return "KeePass XML (1.x)"; } } public override string DefaultExtension { get { return "xml"; } } public override string ApplicationGroup { get { return PwDefs.ShortProductName; } } public override bool SupportsUuids { get { return true; } } public override Image SmallIcon { get { return KeePass.Properties.Resources.B16x16_Binary; } } private const string ElemRoot = "pwlist"; private const string ElemEntry = "pwentry"; private const string ElemGroup = "group"; private const string ElemTitle = "title"; private const string ElemUserName = "username"; private const string ElemUrl = "url"; private const string ElemPassword = "password"; private const string ElemNotes = "notes"; private const string ElemUuid = "uuid"; private const string ElemImage = "image"; private const string ElemCreationTime = "creationtime"; private const string ElemLastModTime = "lastmodtime"; private const string ElemLastAccessTime = "lastaccesstime"; private const string ElemExpiryTime = "expiretime"; private const string ElemAttachDesc = "attachdesc"; private const string ElemAttachment = "attachment"; private const string AttribGroupTree = "tree"; private const string AttribExpires = "expires"; public override void Import(PwDatabase pwStorage, Stream sInput, IStatusLogger slLogger) { XmlDocument xmlDoc = new XmlDocument(); xmlDoc.Load(sInput); XmlNode xmlRoot = xmlDoc.DocumentElement; Debug.Assert(xmlRoot.Name == ElemRoot); int nNodeCount = xmlRoot.ChildNodes.Count; for(int i = 0; i < nNodeCount; ++i) { XmlNode xmlChild = xmlRoot.ChildNodes[i]; if(xmlChild.Name == ElemEntry) ReadEntry(xmlChild, pwStorage); else { Debug.Assert(false); } if(slLogger != null) slLogger.SetProgress((uint)(((i + 1) * 100) / nNodeCount)); } } private static void ReadEntry(XmlNode xmlNode, PwDatabase pwStorage) { PwEntry pe = new PwEntry(true, true); PwGroup pg = pwStorage.RootGroup; string strAttachDesc = null, strAttachment = null; foreach(XmlNode xmlChild in xmlNode) { if(xmlChild.Name == ElemGroup) { string strPreTree = null; try { XmlNode xmlTree = xmlChild.Attributes.GetNamedItem(AttribGroupTree); strPreTree = xmlTree.Value; } catch(Exception) { } string strLast = XmlUtil.SafeInnerText(xmlChild); string strGroup = ((!string.IsNullOrEmpty(strPreTree)) ? strPreTree + "\\" + strLast : strLast); pg = pwStorage.RootGroup.FindCreateSubTree(strGroup, new string[1]{ "\\" }, true); } else if(xmlChild.Name == ElemTitle) pe.Strings.Set(PwDefs.TitleField, new ProtectedString( pwStorage.MemoryProtection.ProtectTitle, XmlUtil.SafeInnerText(xmlChild))); else if(xmlChild.Name == ElemUserName) pe.Strings.Set(PwDefs.UserNameField, new ProtectedString( pwStorage.MemoryProtection.ProtectUserName, XmlUtil.SafeInnerText(xmlChild))); else if(xmlChild.Name == ElemUrl) pe.Strings.Set(PwDefs.UrlField, new ProtectedString( pwStorage.MemoryProtection.ProtectUrl, XmlUtil.SafeInnerText(xmlChild))); else if(xmlChild.Name == ElemPassword) pe.Strings.Set(PwDefs.PasswordField, new ProtectedString( pwStorage.MemoryProtection.ProtectPassword, XmlUtil.SafeInnerText(xmlChild))); else if(xmlChild.Name == ElemNotes) pe.Strings.Set(PwDefs.NotesField, new ProtectedString( pwStorage.MemoryProtection.ProtectNotes, XmlUtil.SafeInnerText(xmlChild))); else if(xmlChild.Name == ElemUuid) pe.SetUuid(new PwUuid(MemUtil.HexStringToByteArray( XmlUtil.SafeInnerText(xmlChild))), false); else if(xmlChild.Name == ElemImage) { int nImage; if(int.TryParse(XmlUtil.SafeInnerText(xmlChild), out nImage)) { if((nImage >= 0) && (nImage < (int)PwIcon.Count)) pe.IconId = (PwIcon)nImage; else { Debug.Assert(false); } } else { Debug.Assert(false); } } else if(xmlChild.Name == ElemCreationTime) pe.CreationTime = ParseTime(XmlUtil.SafeInnerText(xmlChild)); else if(xmlChild.Name == ElemLastModTime) pe.LastModificationTime = ParseTime(XmlUtil.SafeInnerText(xmlChild)); else if(xmlChild.Name == ElemLastAccessTime) pe.LastAccessTime = ParseTime(XmlUtil.SafeInnerText(xmlChild)); else if(xmlChild.Name == ElemExpiryTime) { try { XmlNode xmlExpires = xmlChild.Attributes.GetNamedItem(AttribExpires); if(StrUtil.StringToBool(xmlExpires.Value)) { pe.Expires = true; pe.ExpiryTime = ParseTime(XmlUtil.SafeInnerText(xmlChild)); } else { Debug.Assert(ParseTime(XmlUtil.SafeInnerText(xmlChild)).Year == 2999); } } catch(Exception) { Debug.Assert(false); } } else if(xmlChild.Name == ElemAttachDesc) strAttachDesc = XmlUtil.SafeInnerText(xmlChild); else if(xmlChild.Name == ElemAttachment) strAttachment = XmlUtil.SafeInnerText(xmlChild); else { Debug.Assert(false); } } if(!string.IsNullOrEmpty(strAttachDesc) && (strAttachment != null)) { byte[] pbData = Convert.FromBase64String(strAttachment); ProtectedBinary pb = new ProtectedBinary(false, pbData); pe.Binaries.Set(strAttachDesc, pb); } pg.AddEntry(pe, true); } private static DateTime ParseTime(string str) { if(string.IsNullOrEmpty(str)) { Debug.Assert(false); return DateTime.UtcNow; } if(str == "0000-00-00T00:00:00") return DateTime.UtcNow; DateTime dt; if(DateTime.TryParse(str, out dt)) return TimeUtil.ToUtc(dt, false); Debug.Assert(false); return DateTime.UtcNow; } } } KeePass/DataExchange/Formats/VisKeeperTxt3.cs0000664000000000000000000001062413222430406020046 0ustar rootroot/* KeePass Password Safe - The Open-Source Password Manager Copyright (C) 2003-2018 Dominik Reichl This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ using System; using System.Collections.Generic; using System.Text; using System.IO; using System.Drawing; using System.Diagnostics; using KeePass.Resources; using KeePassLib; using KeePassLib.Interfaces; using KeePassLib.Utility; using KeePassLib.Security; namespace KeePass.DataExchange.Formats { // 3.3.0+ internal sealed class VisKeeperTxt3 : FileFormatProvider { public override bool SupportsImport { get { return true; } } public override bool SupportsExport { get { return false; } } public override string FormatName { get { return "VisKeeper TXT"; } } public override string DefaultExtension { get { return "txt"; } } public override string ApplicationGroup { get { return KPRes.PasswordManagers; } } public override Image SmallIcon { get { return KeePass.Properties.Resources.B16x16_Imp_VisKeeper; } } public override void Import(PwDatabase pwStorage, Stream sInput, IStatusLogger slLogger) { StreamReader sr = new StreamReader(sInput, Encoding.Default, true); string strData = sr.ReadToEnd(); sr.Close(); strData = StrUtil.NormalizeNewLines(strData, false); const string strInitGroup = "\n\nOrdner:"; const string strInitTemplate = "\n\nVorlage:"; const string strInitEntry = "\n\nEintrag:"; const string strInitNote = "\n\nNotiz:"; string[] vSeps = new string[] { strInitGroup, strInitTemplate, strInitEntry, strInitNote }; List lData = StrUtil.SplitWithSep(strData, vSeps, true); Debug.Assert((lData.Count & 1) == 1); PwGroup pgRoot = pwStorage.RootGroup; PwGroup pgTemplates = new PwGroup(true, true, "Vorlagen", PwIcon.MarkedDirectory); pgRoot.AddGroup(pgTemplates, true); for(int i = 1; (i + 1) < lData.Count; i += 2) { string strInit = lData[i]; string strPart = lData[i + 1]; if(strInit == strInitGroup) { } else if(strInit == strInitTemplate) ImportEntry(strPart, pgTemplates, pwStorage, false); else if(strInit == strInitEntry) ImportEntry(strPart, pgRoot, pwStorage, false); else if(strInit == strInitNote) ImportEntry(strPart, pgRoot, pwStorage, true); else { Debug.Assert(false); } } } private static void ImportEntry(string strData, PwGroup pg, PwDatabase pd, bool bForceNotes) { PwEntry pe = new PwEntry(true, true); pg.AddEntry(pe, true); string[] v = strData.Split('\n'); if(v.Length == 0) { Debug.Assert(false); return; } ImportUtil.AppendToField(pe, PwDefs.TitleField, v[0].Trim(), pd); int n = v.Length; for(int j = n - 1; j >= 0; --j) { if(v[j].Length > 0) break; --n; } bool bInNotes = bForceNotes; for(int i = 1; i < n; ++i) { string str = v[i]; int iSep = str.IndexOf(':'); if(iSep <= 0) bInNotes = true; if(bInNotes) { if(str.Length == 0) ImportUtil.AppendToField(pe, PwDefs.NotesField, Environment.NewLine, pd, string.Empty, false); else ImportUtil.AppendToField(pe, PwDefs.NotesField, str, pd, Environment.NewLine, false); } else { string strRawKey = str.Substring(0, iSep); string strValue = str.Substring(iSep + 1).Trim(); string strKey = ImportUtil.MapNameToStandardField(strRawKey, false); if(string.IsNullOrEmpty(strKey)) strKey = strRawKey; bool bMultiLine = ((strKey == PwDefs.NotesField) || !PwDefs.IsStandardField(strKey)); ImportUtil.AppendToField(pe, strKey, strValue, pd, (bMultiLine ? Environment.NewLine : ", "), false); } } } } } KeePass/DataExchange/Formats/SteganosPwManager2007.cs0000664000000000000000000001076213222430406021267 0ustar rootroot/* KeePass Password Safe - The Open-Source Password Manager Copyright (C) 2003-2018 Dominik Reichl This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ using System; using System.Collections.Generic; using System.Text; using System.Windows.Forms; using System.IO; using System.Drawing; using System.Threading; using KeePass.App; using KeePass.Native; using KeePass.Resources; using KeePass.Util; using KeePassLib; using KeePassLib.Interfaces; using KeePassLib.Security; using KeePassLib.Utility; namespace KeePass.DataExchange.Formats { internal sealed class SteganosPwManager2007 : FileFormatProvider { public override bool SupportsImport { get { return true; } } public override bool SupportsExport { get { return false; } } public override string FormatName { get { return "Steganos Password Manager 2007"; } } public override string ApplicationGroup { get { return KPRes.PasswordManagers; } } public override bool RequiresFile { get { return false; } } public override Image SmallIcon { get { return KeePass.Properties.Resources.B16x16_Imp_Steganos; } } public override void Import(PwDatabase pwStorage, Stream sInput, IStatusLogger slLogger) { if(MessageService.AskYesNo(KPRes.ImportMustRead + MessageService.NewParagraph + KPRes.ImportMustReadQuestion) == false) { AppHelp.ShowHelp(AppDefs.HelpTopics.ImportExport, AppDefs.HelpTopics.ImportExportSteganos); return; } PwEntry pePrev = new PwEntry(true, true); for(int i = 0; i < 20; ++i) { Thread.Sleep(500); Application.DoEvents(); } try { while(true) { PwEntry pe = ImportEntry(pwStorage); if(ImportUtil.EntryEquals(pe, pePrev)) { if(pe.ParentGroup != null) // Remove duplicate pe.ParentGroup.Entries.Remove(pe); break; } ImportUtil.GuiSendKeysPrc(@"{DOWN}"); pePrev = pe; } MessageService.ShowInfo(KPRes.ImportFinished); } catch(Exception exImp) { MessageService.ShowWarning(exImp); } } private static PwEntry ImportEntry(PwDatabase pwDb) { ImportUtil.GuiSendWaitWindowChange(@"{ENTER}"); Thread.Sleep(1000); ImportUtil.GuiSendKeysPrc(string.Empty); // Process messages string strTitle = ImportUtil.GuiSendRetrieve(string.Empty); string strGroup = ImportUtil.GuiSendRetrieve(@"{TAB}"); string strUserName = ImportUtil.GuiSendRetrieve(@"{TAB}"); ImportUtil.GuiSendKeysPrc(@"{TAB}{TAB}"); ImportUtil.GuiSendKeysPrc(@" "); ImportUtil.GuiSendKeysPrc(@"+({TAB})"); string strPassword = ImportUtil.GuiSendRetrieve(string.Empty); ImportUtil.GuiSendKeysPrc(@"{TAB} "); string strNotes = ImportUtil.GuiSendRetrieve(@"{TAB}{TAB}"); string strUrl = ImportUtil.GuiSendRetrieve(@"{TAB}"); string strUrl2 = ImportUtil.GuiSendRetrieve(@"{TAB}"); ImportUtil.GuiSendWaitWindowChange(@"{ESC}"); if(strGroup.Length == 0) strGroup = "Steganos"; PwGroup pg = pwDb.RootGroup.FindCreateGroup(strGroup, true); PwEntry pe = new PwEntry(true, true); pg.AddEntry(pe, true); pe.Strings.Set(PwDefs.TitleField, new ProtectedString( pwDb.MemoryProtection.ProtectTitle, strTitle)); pe.Strings.Set(PwDefs.UserNameField, new ProtectedString( pwDb.MemoryProtection.ProtectUserName, strUserName)); pe.Strings.Set(PwDefs.PasswordField, new ProtectedString( pwDb.MemoryProtection.ProtectPassword, strPassword)); pe.Strings.Set(PwDefs.NotesField, new ProtectedString( pwDb.MemoryProtection.ProtectNotes, strNotes)); if(strUrl.Length > 0) pe.Strings.Set(PwDefs.UrlField, new ProtectedString( pwDb.MemoryProtection.ProtectUrl, strUrl)); else pe.Strings.Set(PwDefs.UrlField, new ProtectedString( pwDb.MemoryProtection.ProtectUrl, strUrl2)); return pe; } } } KeePass/DataExchange/Formats/PwTresorXml100.cs0000664000000000000000000001051413222430406020053 0ustar rootroot/* KeePass Password Safe - The Open-Source Password Manager Copyright (C) 2003-2018 Dominik Reichl This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ using System; using System.Collections.Generic; using System.Text; using System.Xml; using System.Drawing; using System.IO; using System.Diagnostics; using KeePass.Resources; using KeePass.Util; using KeePassLib; using KeePassLib.Interfaces; using KeePassLib.Security; namespace KeePass.DataExchange.Formats { // 1.0.2001.157 internal sealed class PwTresorXml100 : FileFormatProvider { private const string ElemGroup = "Group"; private const string ElemGroupName = "groupname"; private const string ElemEntry = "PassItem"; private const string ElemEntryName = "itemname"; private const string ElemEntryUser = "username"; private const string ElemEntryPassword = "password"; private const string ElemEntryURL = "url"; private const string ElemEntryNotes = "description"; public override bool SupportsImport { get { return true; } } public override bool SupportsExport { get { return false; } } public override string FormatName { get { return "Passwort.Tresor XML"; } } public override string DefaultExtension { get { return "xml"; } } public override string ApplicationGroup { get { return KPRes.PasswordManagers; } } public override Image SmallIcon { get { return KeePass.Properties.Resources.B16x16_Imp_PwTresor; } } public override void Import(PwDatabase pwStorage, Stream sInput, IStatusLogger slLogger) { StreamReader sr = new StreamReader(sInput, Encoding.Default); XmlDocument xmlDoc = new XmlDocument(); xmlDoc.Load(sr); XmlNode xmlRoot = xmlDoc.DocumentElement; foreach(XmlNode xmlChild in xmlRoot.ChildNodes) { if(xmlChild.Name == ElemGroup) ReadGroup(xmlChild, pwStorage.RootGroup, pwStorage); else { Debug.Assert(false); } } } private static void ReadGroup(XmlNode xmlNode, PwGroup pgParent, PwDatabase pwStorage) { PwGroup pg = new PwGroup(true, true); pgParent.AddGroup(pg, true); foreach(XmlNode xmlChild in xmlNode) { if(xmlChild.Name == ElemGroupName) pg.Name = XmlUtil.SafeInnerText(xmlChild); else if(xmlChild.Name == ElemGroup) ReadGroup(xmlChild, pg, pwStorage); else if(xmlChild.Name == ElemEntry) ReadEntry(xmlChild, pg, pwStorage); else { Debug.Assert(false); } } } private static void ReadEntry(XmlNode xmlNode, PwGroup pgParent, PwDatabase pwStorage) { PwEntry pe = new PwEntry(true, true); pgParent.AddEntry(pe, true); foreach(XmlNode xmlChild in xmlNode) { if(xmlChild.Name == ElemEntryName) pe.Strings.Set(PwDefs.TitleField, new ProtectedString( pwStorage.MemoryProtection.ProtectTitle, XmlUtil.SafeInnerText(xmlChild))); else if(xmlChild.Name == ElemEntryUser) pe.Strings.Set(PwDefs.UserNameField, new ProtectedString( pwStorage.MemoryProtection.ProtectUserName, XmlUtil.SafeInnerText(xmlChild))); else if(xmlChild.Name == ElemEntryPassword) pe.Strings.Set(PwDefs.PasswordField, new ProtectedString( pwStorage.MemoryProtection.ProtectPassword, XmlUtil.SafeInnerText(xmlChild))); else if(xmlChild.Name == ElemEntryURL) pe.Strings.Set(PwDefs.UrlField, new ProtectedString( pwStorage.MemoryProtection.ProtectUrl, XmlUtil.SafeInnerText(xmlChild))); else if(xmlChild.Name == ElemEntryNotes) pe.Strings.Set(PwDefs.NotesField, new ProtectedString( pwStorage.MemoryProtection.ProtectNotes, XmlUtil.SafeInnerText(xmlChild))); else { Debug.Assert(false); } } } } } KeePass/DataExchange/Formats/TurboPwsCsv5.cs0000664000000000000000000000772513222430406017724 0ustar rootroot/* KeePass Password Safe - The Open-Source Password Manager Copyright (C) 2003-2018 Dominik Reichl This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ using System; using System.Collections.Generic; using System.Text; using System.IO; using System.Diagnostics; using System.Globalization; using System.Drawing; using KeePass.Resources; using KeePassLib; using KeePassLib.Interfaces; using KeePassLib.Security; namespace KeePass.DataExchange.Formats { // 5.0.1+ internal sealed class TurboPwsCsv5 : FileFormatProvider { public override bool SupportsImport { get { return true; } } public override bool SupportsExport { get { return false; } } public override string FormatName { get { return "TurboPasswords CSV"; } } public override string DefaultExtension { get { return "csv"; } } public override string ApplicationGroup { get { return KPRes.PasswordManagers; } } public override Image SmallIcon { get { return Properties.Resources.B16x16_Imp_TurboPws; } } public override void Import(PwDatabase pwStorage, Stream sInput, IStatusLogger slLogger) { StreamReader sr = new StreamReader(sInput, Encoding.Default); string strData = sr.ReadToEnd(); sr.Close(); sInput.Close(); Dictionary dGroups = new Dictionary(); dGroups[string.Empty] = pwStorage.RootGroup; CsvOptions opt = new CsvOptions(); opt.BackslashIsEscape = false; CsvStreamReaderEx csv = new CsvStreamReaderEx(strData, opt); while(true) { string[] v = csv.ReadLine(); if(v == null) break; if(v.Length == 0) continue; if(v[0].StartsWith("TurboPasswords CSV Export File")) continue; if(v.Length < 24) { Debug.Assert(false); continue; } if((v[0] == "Category") && (v[1] == "Type")) continue; PwEntry pe = new PwEntry(true, true); PwGroup pg; string strGroup = v[0]; if(!dGroups.TryGetValue(strGroup, out pg)) { pg = new PwGroup(true, true, strGroup, PwIcon.Folder); dGroups[string.Empty].AddGroup(pg, true); dGroups[strGroup] = pg; } pg.AddEntry(pe, true); string strType = v[1]; for(int f = 0; f < 6; ++f) { string strKey = v[2 + (2 * f)]; string strValue = v[2 + (2 * f) + 1]; if(strKey.Length == 0) strKey = PwDefs.NotesField; if(strValue.Length == 0) continue; if(strKey == "Description") strKey = PwDefs.TitleField; else if(((strType == "Contact") || (strType == "Personal Info")) && (strKey == "Name")) strKey = PwDefs.TitleField; else if(((strType == "Membership") || (strType == "Insurance")) && (strKey == "Company")) strKey = PwDefs.TitleField; else if(strKey == "SSN") strKey = PwDefs.UserNameField; else { string strMapped = ImportUtil.MapNameToStandardField(strKey, false); if(!string.IsNullOrEmpty(strMapped)) strKey = strMapped; } ImportUtil.AppendToField(pe, strKey, strValue, pwStorage, ((strKey == PwDefs.NotesField) ? "\r\n" : ", "), false); } ImportUtil.AppendToField(pe, PwDefs.NotesField, v[20], pwStorage, "\r\n\r\n", false); if(v[21].Length > 0) ImportUtil.AppendToField(pe, "Login URL", v[21], pwStorage, null, true); } } } } KeePass/DataExchange/Formats/HandySafeTxt512.cs0000664000000000000000000001070513222430404020156 0ustar rootroot/* KeePass Password Safe - The Open-Source Password Manager Copyright (C) 2003-2018 Dominik Reichl This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ using System; using System.Collections.Generic; using System.Text; using System.Drawing; using System.IO; using System.Diagnostics; using KeePass.Resources; using KeePassLib; using KeePassLib.Interfaces; using KeePassLib.Security; using KeePassLib.Utility; namespace KeePass.DataExchange.Formats { // 5.12 internal sealed class HandySafeTxt512 : FileFormatProvider { public override bool SupportsImport { get { return true; } } public override bool SupportsExport { get { return false; } } public override string FormatName { get { return "Handy Safe TXT"; } } public override string DefaultExtension { get { return "txt"; } } public override string ApplicationGroup { get { return KPRes.PasswordManagers; } } public override Image SmallIcon { get { return KeePass.Properties.Resources.B16x16_Imp_HandySafe; } } private const string StrGroupStart = "[Category: "; private const string StrGroupEnd = "]"; private const string StrEntryStart = "[Card, "; private const string StrEntryEnd = "]"; private const string StrNotesBegin = "Note:"; private const string StrFieldSplit = ": "; public override void Import(PwDatabase pwStorage, Stream sInput, IStatusLogger slLogger) { StreamReader sr = new StreamReader(sInput, Encoding.Default); string strData = sr.ReadToEnd(); sr.Close(); strData = strData.Replace("\r", string.Empty); string[] vLines = strData.Split(new char[] { '\n' }); PwGroup pg = pwStorage.RootGroup; Dictionary dItems = new Dictionary(); bool bInNotes = false; foreach(string strLine in vLines) { if(strLine.StartsWith(StrGroupStart) && strLine.EndsWith(StrGroupEnd)) { AddEntry(pg, dItems, ref bInNotes); dItems.Clear(); pg = new PwGroup(true, true); pg.Name = strLine.Substring(StrGroupStart.Length, strLine.Length - StrGroupStart.Length - StrGroupEnd.Length); pwStorage.RootGroup.AddGroup(pg, true); } else if(strLine.StartsWith(StrEntryStart) && strLine.EndsWith(StrEntryEnd)) { AddEntry(pg, dItems, ref bInNotes); dItems.Clear(); } else if(strLine == StrNotesBegin) bInNotes = true; else if(bInNotes) { if(dItems.ContainsKey(PwDefs.NotesField)) dItems[PwDefs.NotesField] += MessageService.NewLine + strLine; else dItems[PwDefs.NotesField] = strLine; } else { int nSplitPos = strLine.IndexOf(StrFieldSplit); if(nSplitPos < 0) { Debug.Assert(false); } else { AddField(dItems, strLine.Substring(0, nSplitPos), strLine.Substring(nSplitPos + StrFieldSplit.Length)); } } } AddEntry(pg, dItems, ref bInNotes); } private static void AddField(Dictionary dItems, string strKey, string strValue) { string strKeyTrl = ImportUtil.MapNameToStandardField(strKey, true); if(string.IsNullOrEmpty(strKeyTrl)) strKeyTrl = strKey; if(!dItems.ContainsKey(strKeyTrl)) { dItems[strKeyTrl] = strValue; return; } string strPreValue = dItems[strKeyTrl]; if((strPreValue.Length > 0) && (strValue.Length > 0)) strPreValue += ", "; dItems[strKeyTrl] = strPreValue + strValue; } private static void AddEntry(PwGroup pg, Dictionary dItems, ref bool bInNotes) { if(dItems.Count == 0) return; PwEntry pe = new PwEntry(true, true); pg.AddEntry(pe, true); foreach(KeyValuePair kvp in dItems) pe.Strings.Set(kvp.Key, new ProtectedString(false, kvp.Value)); bInNotes = false; } } } KeePass/DataExchange/Formats/Whisper32Csv116.cs0000664000000000000000000001156713222430406020067 0ustar rootroot/* KeePass Password Safe - The Open-Source Password Manager Copyright (C) 2003-2018 Dominik Reichl This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ using System; using System.Collections.Generic; using System.Text; using System.IO; using System.Drawing; using System.Diagnostics; using KeePass.Resources; using KeePassLib; using KeePassLib.Interfaces; using KeePassLib.Security; using KeePassLib.Utility; namespace KeePass.DataExchange.Formats { // 1.16 internal sealed class Whisper32Csv116 : FileFormatProvider { public override bool SupportsImport { get { return true; } } public override bool SupportsExport { get { return false; } } public override string FormatName { get { return "Whisper 32 CSV"; } } public override string DefaultExtension { get { return "csv"; } } public override string ApplicationGroup { get { return KPRes.PasswordManagers; } } public override bool ImportAppendsToRootGroupOnly { get { return true; } } public override Image SmallIcon { get { return KeePass.Properties.Resources.B16x16_Imp_Whisper32; } } public override void Import(PwDatabase pwStorage, Stream sInput, IStatusLogger slLogger) { StreamReader sr = new StreamReader(sInput, Encoding.Default); string strDocument = sr.ReadToEnd(); sr.Close(); PwGroup pg = pwStorage.RootGroup; CharStream cs = new CharStream(strDocument); string[] vFields = new string[7]; char[] vDateFieldSplitter = new char[]{ '/' }; char[] vDateZeroTrim = new char[]{ '0' }; bool bFirst = true; while(true) { bool bSubZero = false; for(int iField = 0; iField < vFields.Length; ++iField) { vFields[iField] = ReadCsvField(cs); if((iField > 0) && (vFields[iField] == null)) bSubZero = true; } if(vFields[0] == null) break; // Import successful else if(bSubZero) throw new FormatException(); if(bFirst) { bFirst = false; // Check first line once only if((vFields[0] != "ServiceName") || (vFields[1] != "UserName") || (vFields[2] != "Password") || (vFields[3] != "Memo") || (vFields[4] != "Expire") || (vFields[5] != "StartDate") || (vFields[6] != "DaysToLive")) { Debug.Assert(false); throw new FormatException(); } else continue; } PwEntry pe = new PwEntry(true, true); pg.AddEntry(pe, true); pe.Strings.Set(PwDefs.TitleField, new ProtectedString( pwStorage.MemoryProtection.ProtectTitle, vFields[0])); pe.Strings.Set(PwDefs.UserNameField, new ProtectedString( pwStorage.MemoryProtection.ProtectUserName, vFields[1])); pe.Strings.Set(PwDefs.PasswordField, new ProtectedString( pwStorage.MemoryProtection.ProtectPassword, vFields[2])); pe.Strings.Set(PwDefs.NotesField, new ProtectedString( pwStorage.MemoryProtection.ProtectNotes, vFields[3])); pe.Expires = (vFields[4] == "true"); try { string[] vDateParts = vFields[5].Split(vDateFieldSplitter); DateTime dt = (new DateTime( int.Parse(vDateParts[2].TrimStart(vDateZeroTrim)), int.Parse(vDateParts[0].TrimStart(vDateZeroTrim)), int.Parse(vDateParts[1].TrimStart(vDateZeroTrim)), 0, 0, 0, DateTimeKind.Local)).ToUniversalTime(); pe.LastModificationTime = dt; pe.LastAccessTime = dt; pe.ExpiryTime = dt.AddDays(double.Parse(vFields[6])); } catch(Exception) { Debug.Assert(false); } pe.Strings.Set("Days To Live", new ProtectedString(false, vFields[6])); } } private static string ReadCsvField(CharStream cs) { StringBuilder sbValue = new StringBuilder(); char ch; while(true) { ch = cs.ReadChar(); if(ch == char.MinValue) return null; else if(ch == '\"') break; } while(true) { ch = cs.ReadChar(); if(ch == char.MinValue) return null; else if(ch == '\r') continue; else if(ch == '\"') { char chSucc = cs.ReadChar(); if(chSucc == '\"') sbValue.Append('\"'); else break; } else if(ch == '\n') sbValue.Append(MessageService.NewLine); else sbValue.Append(ch); } return sbValue.ToString(); } } } KeePass/DataExchange/Formats/PVaultTxt14.cs0000664000000000000000000001065213222430404017445 0ustar rootroot/* KeePass Password Safe - The Open-Source Password Manager Copyright (C) 2003-2018 Dominik Reichl This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ using System; using System.Collections.Generic; using System.Text; using System.IO; using System.Drawing; using KeePass.Resources; using KeePassLib; using KeePassLib.Interfaces; using KeePassLib.Security; namespace KeePass.DataExchange.Formats { // 1.4 internal sealed class PVaultTxt14 : FileFormatProvider { private const string InitGroup = "************"; private const string InitNewEntry = "----------------------"; private const string InitTitle = "Account: "; private const string InitUser = "User Name: "; private const string InitPassword = "Password: "; private const string InitURL = "Hyperlink: "; private const string InitEMail = "Email: "; private const string InitNotes = "Comments: "; private const string ContinueNotes = " "; public override bool SupportsImport { get { return true; } } public override bool SupportsExport { get { return false; } } public override string FormatName { get { return "Personal Vault TXT"; } } public override string DefaultExtension { get { return "txt"; } } public override string ApplicationGroup { get { return KPRes.PasswordManagers; } } public override Image SmallIcon { get { return KeePass.Properties.Resources.B16x16_Imp_PVault; } } public override void Import(PwDatabase pwStorage, Stream sInput, IStatusLogger slLogger) { StreamReader sr = new StreamReader(sInput, Encoding.Default); string strData = sr.ReadToEnd(); sr.Close(); string[] vLines = strData.Split(new char[]{ '\r', '\n' }); PwGroup pg = pwStorage.RootGroup; PwEntry pe = new PwEntry(true, true); foreach(string strLine in vLines) { if(strLine.StartsWith(InitGroup)) { string strGroup = strLine.Remove(0, InitGroup.Length); if(strGroup.Length > InitGroup.Length) strGroup = strGroup.Substring(0, strGroup.Length - InitGroup.Length); pg = pwStorage.RootGroup.FindCreateGroup(strGroup, true); pe = new PwEntry(true, true); pg.AddEntry(pe, true); } else if(strLine.StartsWith(InitNewEntry)) { pe = new PwEntry(true, true); pg.AddEntry(pe, true); } else if(strLine.StartsWith(InitTitle)) pe.Strings.Set(PwDefs.TitleField, new ProtectedString( pwStorage.MemoryProtection.ProtectTitle, strLine.Remove(0, InitTitle.Length))); else if(strLine.StartsWith(InitUser)) pe.Strings.Set(PwDefs.UserNameField, new ProtectedString( pwStorage.MemoryProtection.ProtectUserName, strLine.Remove(0, InitUser.Length))); else if(strLine.StartsWith(InitPassword)) pe.Strings.Set(PwDefs.PasswordField, new ProtectedString( pwStorage.MemoryProtection.ProtectPassword, strLine.Remove(0, InitPassword.Length))); else if(strLine.StartsWith(InitURL)) pe.Strings.Set(PwDefs.UrlField, new ProtectedString( pwStorage.MemoryProtection.ProtectUrl, strLine.Remove(0, InitURL.Length))); else if(strLine.StartsWith(InitEMail)) pe.Strings.Set("E-Mail", new ProtectedString( false, strLine.Remove(0, InitEMail.Length))); else if(strLine.StartsWith(InitNotes)) pe.Strings.Set(PwDefs.NotesField, new ProtectedString( pwStorage.MemoryProtection.ProtectNotes, strLine.Remove(0, InitNotes.Length))); else if(strLine.StartsWith(ContinueNotes)) pe.Strings.Set(PwDefs.NotesField, new ProtectedString( pwStorage.MemoryProtection.ProtectNotes, pe.Strings.ReadSafe(PwDefs.NotesField) + "\r\n" + strLine.Remove(0, ContinueNotes.Length))); } } } } KeePass/DataExchange/Formats/PwKeeperCsv70.cs0000664000000000000000000000702013222430404017725 0ustar rootroot/* KeePass Password Safe - The Open-Source Password Manager Copyright (C) 2003-2018 Dominik Reichl This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ using System; using System.Collections.Generic; using System.Text; using System.IO; using System.Diagnostics; using System.Globalization; using System.Drawing; using KeePass.Resources; using KeePassLib; using KeePassLib.Interfaces; using KeePassLib.Security; namespace KeePass.DataExchange.Formats { // 7.0 internal sealed class PwKeeperCsv70 : FileFormatProvider { public override bool SupportsImport { get { return true; } } public override bool SupportsExport { get { return false; } } public override string FormatName { get { return "Password Keeper CSV"; } } public override string DefaultExtension { get { return "csv"; } } public override string ApplicationGroup { get { return KPRes.PasswordManagers; } } public override bool ImportAppendsToRootGroupOnly { get { return true; } } public override Image SmallIcon { get { return KeePass.Properties.Resources.B16x16_Imp_Whisper32; } } public override void Import(PwDatabase pwStorage, Stream sInput, IStatusLogger slLogger) { StreamReader sr = new StreamReader(sInput, Encoding.Default); string strData = sr.ReadToEnd(); sr.Close(); string[] vLines = strData.Split(new char[] { '\r', '\n' }); foreach(string strLine in vLines) { if(strLine.Length > 5) ProcessCsvLine(strLine, pwStorage); } } private static void ProcessCsvLine(string strLine, PwDatabase pwStorage) { List list = ImportUtil.SplitCsvLine(strLine, ","); Debug.Assert(list.Count == 5); PwEntry pe = new PwEntry(true, true); pwStorage.RootGroup.AddEntry(pe, true); if(list.Count == 5) { pe.Strings.Set(PwDefs.TitleField, new ProtectedString( pwStorage.MemoryProtection.ProtectTitle, ProcessCsvWord(list[0]))); pe.Strings.Set(PwDefs.UserNameField, new ProtectedString( pwStorage.MemoryProtection.ProtectUserName, ProcessCsvWord(list[1]))); pe.Strings.Set(PwDefs.PasswordField, new ProtectedString( pwStorage.MemoryProtection.ProtectPassword, ProcessCsvWord(list[2]))); pe.Strings.Set(PwDefs.UrlField, new ProtectedString( pwStorage.MemoryProtection.ProtectUrl, ProcessCsvWord(list[3]))); pe.Strings.Set(PwDefs.NotesField, new ProtectedString( pwStorage.MemoryProtection.ProtectNotes, ProcessCsvWord(list[4]))); } else throw new FormatException("Invalid field count!"); } private static string ProcessCsvWord(string strWord) { if(strWord == null) return string.Empty; if(strWord.Length < 2) return strWord; if(strWord.StartsWith("\"") && strWord.EndsWith("\"")) return strWord.Substring(1, strWord.Length - 2); return strWord; } } } KeePass/DataExchange/Formats/PwSafeXml302.cs0000664000000000000000000002772313222430406017471 0ustar rootroot/* KeePass Password Safe - The Open-Source Password Manager Copyright (C) 2003-2018 Dominik Reichl This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ using System; using System.Collections.Generic; using System.Text; using System.IO; using System.Xml; using System.Diagnostics; using System.Drawing; using KeePass.Resources; using KeePass.Util; using KeePassLib; using KeePassLib.Interfaces; using KeePassLib.Security; using KeePassLib.Utility; namespace KeePass.DataExchange.Formats { // 3.02-3.30+ internal sealed class PwSafeXml302 : FileFormatProvider { private const string AttribLineBreak = "delimiter"; private const string ElemEntry = "entry"; private const string ElemGroup = "group"; private const string ElemTitle = "title"; private const string ElemUserName = "username"; private const string ElemPassword = "password"; private const string ElemURL = "url"; private const string ElemNotes = "notes"; private const string ElemEMail = "email"; private const string ElemAutoType = "autotype"; private const string ElemRunCommand = "runcommand"; private const string ElemCreationTime = "ctime"; private const string ElemLastAccessTime = "atime"; private const string ElemExpireTime = "ltime"; private const string ElemLastModTime = "pmtime"; private const string ElemRecordModTime = "rmtime"; private const string ElemCreationTimeX = "ctimex"; private const string ElemLastAccessTimeX = "atimex"; private const string ElemExpireTimeX = "xtimex"; // Yes, inconsistent private const string ElemLastModTimeX = "pmtimex"; private const string ElemRecordModTimeX = "rmtimex"; private const string ElemEntryHistory = "pwhistory"; private const string ElemEntryHistoryContainer = "history_entries"; private const string ElemEntryHistoryItem = "history_entry"; private const string ElemEntryHistoryItemTime = "changed"; private const string ElemEntryHistoryItemTimeX = "changedx"; private const string ElemEntryHistoryItemPassword = "oldpassword"; private const string ElemTimePartDate = "date"; private const string ElemTimePartTime = "time"; private const string XPathUseDefaultUser = "Preferences/UseDefaultUser"; private const string XPathDefaultUser = "Preferences/DefaultUsername"; public override bool SupportsImport { get { return true; } } public override bool SupportsExport { get { return false; } } public override string FormatName { get { return "Password Safe XML"; } } public override string DefaultExtension { get { return "xml"; } } public override string ApplicationGroup { get { return KPRes.PasswordManagers; } } public override Image SmallIcon { get { return KeePass.Properties.Resources.B16x16_Imp_PwSafe; } } private sealed class DatePasswordPair { public DateTime Time = DateTime.UtcNow; public string Password = string.Empty; } public override void Import(PwDatabase pwStorage, Stream sInput, IStatusLogger slLogger) { MemoryStream ms = new MemoryStream(); MemUtil.CopyStream(sInput, ms); byte[] pbData = ms.ToArray(); ms.Close(); try { string strData = StrUtil.Utf8.GetString(pbData); if(strData.StartsWith("", StrUtil.CaseIgnoreCmp) && (strData.IndexOf( "WhatSaved=\"Password Safe V3.29\"", StrUtil.CaseIgnoreCmp) >= 0)) { // Fix broken XML exported by Password Safe 3.29; // this has been fixed in 3.30 strData = strData.Replace(" 0) pwStorage.DefaultUserNameChanged = DateTime.UtcNow; } } } ms.Close(); } private static void ImportEntry(XmlNode xmlNode, PwDatabase pwStorage, string strLineBreak) { Debug.Assert(xmlNode != null); if(xmlNode == null) return; PwEntry pe = new PwEntry(true, true); string strGroupName = string.Empty; List listHistory = null; foreach(XmlNode xmlChild in xmlNode.ChildNodes) { if(xmlChild.Name == ElemGroup) strGroupName = XmlUtil.SafeInnerText(xmlChild); else if(xmlChild.Name == ElemTitle) pe.Strings.Set(PwDefs.TitleField, new ProtectedString(pwStorage.MemoryProtection.ProtectTitle, XmlUtil.SafeInnerText(xmlChild))); else if(xmlChild.Name == ElemUserName) pe.Strings.Set(PwDefs.UserNameField, new ProtectedString(pwStorage.MemoryProtection.ProtectUserName, XmlUtil.SafeInnerText(xmlChild))); else if(xmlChild.Name == ElemPassword) pe.Strings.Set(PwDefs.PasswordField, new ProtectedString(pwStorage.MemoryProtection.ProtectPassword, XmlUtil.SafeInnerText(xmlChild))); else if(xmlChild.Name == ElemURL) pe.Strings.Set(PwDefs.UrlField, new ProtectedString(pwStorage.MemoryProtection.ProtectUrl, XmlUtil.SafeInnerText(xmlChild))); else if(xmlChild.Name == ElemNotes) pe.Strings.Set(PwDefs.NotesField, new ProtectedString(pwStorage.MemoryProtection.ProtectNotes, XmlUtil.SafeInnerText(xmlChild, strLineBreak))); else if(xmlChild.Name == ElemEMail) pe.Strings.Set("E-Mail", new ProtectedString(false, XmlUtil.SafeInnerText(xmlChild))); else if(xmlChild.Name == ElemCreationTime) pe.CreationTime = ReadDateTime(xmlChild); else if(xmlChild.Name == ElemLastAccessTime) pe.LastAccessTime = ReadDateTime(xmlChild); else if(xmlChild.Name == ElemExpireTime) { pe.ExpiryTime = ReadDateTime(xmlChild); pe.Expires = true; } else if(xmlChild.Name == ElemLastModTime) // = last mod pe.LastModificationTime = ReadDateTime(xmlChild); else if(xmlChild.Name == ElemRecordModTime) // = last mod pe.LastModificationTime = ReadDateTime(xmlChild); else if(xmlChild.Name == ElemCreationTimeX) pe.CreationTime = ReadDateTimeX(xmlChild); else if(xmlChild.Name == ElemLastAccessTimeX) pe.LastAccessTime = ReadDateTimeX(xmlChild); else if(xmlChild.Name == ElemExpireTimeX) { pe.ExpiryTime = ReadDateTimeX(xmlChild); pe.Expires = true; } else if(xmlChild.Name == ElemLastModTimeX) // = last mod pe.LastModificationTime = ReadDateTimeX(xmlChild); else if(xmlChild.Name == ElemRecordModTimeX) // = last mod pe.LastModificationTime = ReadDateTimeX(xmlChild); else if(xmlChild.Name == ElemAutoType) pe.AutoType.DefaultSequence = XmlUtil.SafeInnerText(xmlChild); else if(xmlChild.Name == ElemRunCommand) pe.OverrideUrl = XmlUtil.SafeInnerText(xmlChild); else if(xmlChild.Name == ElemEntryHistory) listHistory = ReadEntryHistory(xmlChild); } if(listHistory != null) { string strPassword = pe.Strings.ReadSafe(PwDefs.PasswordField); DateTime dtLastMod = pe.LastModificationTime; foreach(DatePasswordPair dpp in listHistory) { pe.Strings.Set(PwDefs.PasswordField, new ProtectedString( pwStorage.MemoryProtection.ProtectPassword, dpp.Password)); pe.LastModificationTime = dpp.Time; pe.CreateBackup(null); } // Maintain backups manually now (backups from the imported file // might have been out of order) pe.MaintainBackups(pwStorage); pe.Strings.Set(PwDefs.PasswordField, new ProtectedString( pwStorage.MemoryProtection.ProtectPassword, strPassword)); pe.LastModificationTime = dtLastMod; } PwGroup pgContainer = pwStorage.RootGroup; if(strGroupName.Length != 0) pgContainer = pwStorage.RootGroup.FindCreateSubTree(strGroupName, new string[1]{ "." }, true); pgContainer.AddEntry(pe, true); pgContainer.IsExpanded = true; } private static DateTime ReadDateTime(XmlNode xmlNode) { Debug.Assert(xmlNode != null); if(xmlNode == null) return DateTime.UtcNow; int[] vTimeParts = new int[6]; DateTime dtTemp; foreach(XmlNode xmlChild in xmlNode.ChildNodes) { if(xmlChild.Name == ElemTimePartDate) { if(DateTime.TryParse(XmlUtil.SafeInnerText(xmlChild), out dtTemp)) { vTimeParts[0] = dtTemp.Year; vTimeParts[1] = dtTemp.Month; vTimeParts[2] = dtTemp.Day; } } else if(xmlChild.Name == ElemTimePartTime) { if(DateTime.TryParse(XmlUtil.SafeInnerText(xmlChild), out dtTemp)) { vTimeParts[3] = dtTemp.Hour; vTimeParts[4] = dtTemp.Minute; vTimeParts[5] = dtTemp.Second; } } else { Debug.Assert(false); } } return (new DateTime(vTimeParts[0], vTimeParts[1], vTimeParts[2], vTimeParts[3], vTimeParts[4], vTimeParts[5], DateTimeKind.Local)).ToUniversalTime(); } private static DateTime ReadDateTimeX(XmlNode xmlNode) { string strDate = XmlUtil.SafeInnerText(xmlNode); DateTime dt; if(StrUtil.TryParseDateTime(strDate, out dt)) return TimeUtil.ToUtc(dt, false); Debug.Assert(false); return DateTime.UtcNow; } private static List ReadEntryHistory(XmlNode xmlNode) { List list = null; foreach(XmlNode xmlChild in xmlNode) { if(xmlChild.Name == ElemEntryHistoryContainer) list = ReadEntryHistoryContainer(xmlChild); } return list; } private static List ReadEntryHistoryContainer(XmlNode xmlNode) { List list = new List(); foreach(XmlNode xmlChild in xmlNode) { if(xmlChild.Name == ElemEntryHistoryItem) list.Add(ReadEntryHistoryItem(xmlChild)); } return list; } private static DatePasswordPair ReadEntryHistoryItem(XmlNode xmlNode) { DatePasswordPair dpp = new DatePasswordPair(); foreach(XmlNode xmlChild in xmlNode) { if(xmlChild.Name == ElemEntryHistoryItemTime) dpp.Time = ReadDateTime(xmlChild); else if(xmlChild.Name == ElemEntryHistoryItemTimeX) dpp.Time = ReadDateTimeX(xmlChild); else if(xmlChild.Name == ElemEntryHistoryItemPassword) dpp.Password = XmlUtil.SafeInnerText(xmlChild); } return dpp; } } } KeePass/DataExchange/Formats/NortonIdSafeCsv2013.cs0000664000000000000000000000566513222430404020712 0ustar rootroot/* KeePass Password Safe - The Open-Source Password Manager Copyright (C) 2003-2018 Dominik Reichl This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ using System; using System.Collections.Generic; using System.Text; using System.IO; using System.Diagnostics; using System.Globalization; using System.Drawing; using KeePass.Resources; using KeePassLib; using KeePassLib.Interfaces; using KeePassLib.Security; using KeePassLib.Utility; namespace KeePass.DataExchange.Formats { // 2013.4.0.10 internal sealed class NortonIdSafeCsv2013 : FileFormatProvider { public override bool SupportsImport { get { return true; } } public override bool SupportsExport { get { return false; } } public override string FormatName { get { return "Norton Identity Safe CSV"; } } public override string DefaultExtension { get { return "csv"; } } public override string ApplicationGroup { get { return KPRes.PasswordManagers; } } public override Image SmallIcon { get { return KeePass.Properties.Resources.B16x16_Imp_NortonIdSafe; } } public override void Import(PwDatabase pwStorage, Stream sInput, IStatusLogger slLogger) { StreamReader sr = new StreamReader(sInput, Encoding.Unicode, true); string strData = sr.ReadToEnd(); sr.Close(); CsvOptions opt = new CsvOptions(); opt.BackslashIsEscape = false; CsvStreamReaderEx csv = new CsvStreamReaderEx(strData, opt); while(true) { string[] v = csv.ReadLine(); if(v == null) break; if(v.Length < 5) continue; if(v[0].Equals("url", StrUtil.CaseIgnoreCmp) && v[1].Equals("username", StrUtil.CaseIgnoreCmp) && v[2].Equals("password", StrUtil.CaseIgnoreCmp)) continue; // Header PwGroup pg = pwStorage.RootGroup; string strGroup = v[4]; if(!string.IsNullOrEmpty(strGroup)) pg = pg.FindCreateGroup(strGroup, true); PwEntry pe = new PwEntry(true, true); pg.AddEntry(pe, true); ImportUtil.AppendToField(pe, PwDefs.UrlField, v[0], pwStorage); ImportUtil.AppendToField(pe, PwDefs.UserNameField, v[1], pwStorage); ImportUtil.AppendToField(pe, PwDefs.PasswordField, v[2], pwStorage); ImportUtil.AppendToField(pe, PwDefs.TitleField, v[3], pwStorage); } } } } KeePass/DataExchange/Formats/DesktopKnoxXml32.cs0000664000000000000000000000716013222430404020464 0ustar rootroot/* KeePass Password Safe - The Open-Source Password Manager Copyright (C) 2003-2018 Dominik Reichl This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ using System; using System.Collections.Generic; using System.Diagnostics; using System.Drawing; using System.IO; using System.Text; using System.Xml; using KeePass.Resources; using KeePass.Util; using KeePassLib; using KeePassLib.Interfaces; using KeePassLib.Security; using KeePassLib.Utility; namespace KeePass.DataExchange.Formats { // 3.2+ internal sealed class DesktopKnoxXml32 : FileFormatProvider { private const string ElemRoot = "SafeCatalog"; private const string ElemEntry = "SafeElement"; private const string ElemCategory = "Category"; private const string ElemTitle = "Title"; private const string ElemNotes = "Content"; public override bool SupportsImport { get { return true; } } public override bool SupportsExport { get { return false; } } public override string FormatName { get { return "DesktopKnox XML"; } } public override string DefaultExtension { get { return "xml"; } } public override string ApplicationGroup { get { return KPRes.PasswordManagers; } } public override Image SmallIcon { get { return KeePass.Properties.Resources.B16x16_Imp_DesktopKnox; } } public override void Import(PwDatabase pwStorage, Stream sInput, IStatusLogger slLogger) { StreamReader sr = new StreamReader(sInput, StrUtil.Utf8); string strDoc = sr.ReadToEnd(); sr.Close(); XmlDocument doc = new XmlDocument(); doc.LoadXml(strDoc); XmlElement xmlRoot = doc.DocumentElement; Debug.Assert(xmlRoot.Name == ElemRoot); Dictionary dictGroups = new Dictionary(); dictGroups[string.Empty] = pwStorage.RootGroup; foreach(XmlNode xmlChild in xmlRoot.ChildNodes) { if(xmlChild.Name == ElemEntry) ImportEntry(xmlChild, pwStorage, dictGroups); else { Debug.Assert(false); } } } private static void ImportEntry(XmlNode xmlNode, PwDatabase pwStorage, Dictionary dGroups) { PwEntry pe = new PwEntry(true, true); string strGroup = string.Empty; foreach(XmlNode xmlChild in xmlNode) { string strInner = XmlUtil.SafeInnerText(xmlChild); if(xmlChild.Name == ElemCategory) strGroup = strInner; else if(xmlChild.Name == ElemTitle) pe.Strings.Set(PwDefs.TitleField, new ProtectedString( pwStorage.MemoryProtection.ProtectTitle, strInner)); else if(xmlChild.Name == ElemNotes) pe.Strings.Set(PwDefs.NotesField, new ProtectedString( pwStorage.MemoryProtection.ProtectNotes, strInner)); } PwGroup pg; dGroups.TryGetValue(strGroup, out pg); if(pg == null) { pg = new PwGroup(true, true); pg.Name = strGroup; dGroups[string.Empty].AddGroup(pg, true); dGroups[strGroup] = pg; } pg.AddEntry(pe, true); } } } KeePass/DataExchange/Formats/WinFavorites10.cs0000664000000000000000000002351113222430406020146 0ustar rootroot/* KeePass Password Safe - The Open-Source Password Manager Copyright (C) 2003-2018 Dominik Reichl This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ using System; using System.Collections.Generic; using System.Text; using System.IO; using System.Drawing; using System.Threading; using System.Diagnostics; using KeePass.Native; using KeePass.Resources; using KeePass.Util; using KeePass.Util.Spr; using KeePassLib; using KeePassLib.Interfaces; using KeePassLib.Utility; using NativeLib = KeePassLib.Native.NativeLib; namespace KeePass.DataExchange.Formats { internal sealed class WinFavorites10 : FileFormatProvider { private readonly bool m_bInRoot; private const string IniTypeKey = "Type"; private const string IniTypeValue = "WinFav-Export 1.0"; private const string LnkDescSuffix = (@" [" + PwDefs.ShortProductName + @"]"); public override bool SupportsImport { get { return false; } } public override bool SupportsExport { get { return true; } } public override string FormatName { get { return (KPRes.WindowsFavorites + " (" + (m_bInRoot ? KPRes.RootDirectory : (KPRes.Folder + @" '" + GetFolderName(true, null, null) + @"'")) + ")"); } } public override bool RequiresFile { get { return false; } } public override string ApplicationGroup { get { return KPRes.General; } } public override Image SmallIcon { get { return Properties.Resources.B16x16_WinFavs; } } public WinFavorites10(bool bInRoot) : base() { m_bInRoot = bInRoot; } private static string GetFolderName(bool bForceRoot, PwExportInfo pwExportInfo, PwGroup pg) { string strBaseName = UrlUtil.FilterFileName(string.IsNullOrEmpty( Program.Config.Defaults.WinFavsBaseFolderName) ? PwDefs.ShortProductName : Program.Config.Defaults.WinFavsBaseFolderName); if(bForceRoot || (pwExportInfo == null) || (pg == null)) return strBaseName; string strGroup = UrlUtil.FilterFileName(pg.Name); string strRootName = strBaseName; if(strGroup.Length > 0) strRootName += (" - " + strGroup); if(pwExportInfo.ContextDatabase != null) { if(pg == pwExportInfo.ContextDatabase.RootGroup) strRootName = strBaseName; } return strRootName; } public override bool Export(PwExportInfo pwExportInfo, Stream sOutput, IStatusLogger slLogger) { PwGroup pg = pwExportInfo.DataGroup; if(pg == null) { Debug.Assert(false); return true; } string strFavsRoot = Environment.GetFolderPath( Environment.SpecialFolder.Favorites); if(string.IsNullOrEmpty(strFavsRoot)) return false; uint uTotalGroups, uTotalEntries, uEntriesProcessed = 0; pwExportInfo.DataGroup.GetCounts(true, out uTotalGroups, out uTotalEntries); if(!m_bInRoot) // In folder { string strRootName = GetFolderName(false, pwExportInfo, pg); string strFavsSub = UrlUtil.EnsureTerminatingSeparator( strFavsRoot, false) + strRootName; if(Directory.Exists(strFavsSub)) { Directory.Delete(strFavsSub, true); WaitForDirCommit(strFavsSub, false); } ExportGroup(pwExportInfo.DataGroup, strFavsSub, slLogger, uTotalEntries, ref uEntriesProcessed, pwExportInfo); } else // In root { DeletePreviousExport(strFavsRoot, slLogger); ExportGroup(pwExportInfo.DataGroup, strFavsRoot, slLogger, uTotalEntries, ref uEntriesProcessed, pwExportInfo); } Debug.Assert(uEntriesProcessed == uTotalEntries); return true; } private static void ExportGroup(PwGroup pg, string strDir, IStatusLogger slLogger, uint uTotalEntries, ref uint uEntriesProcessed, PwExportInfo pxi) { foreach(PwEntry pe in pg.Entries) { ExportEntry(pe, strDir, pxi); ++uEntriesProcessed; if(slLogger != null) slLogger.SetProgress(((uEntriesProcessed * 50U) / uTotalEntries) + 50U); } foreach(PwGroup pgSub in pg.Groups) { string strGroup = UrlUtil.FilterFileName(pgSub.Name); string strSub = (UrlUtil.EnsureTerminatingSeparator(strDir, false) + (!string.IsNullOrEmpty(strGroup) ? strGroup : KPRes.Group)); ExportGroup(pgSub, strSub, slLogger, uTotalEntries, ref uEntriesProcessed, pxi); } } private static void ExportEntry(PwEntry pe, string strDir, PwExportInfo pxi) { PwDatabase pd = ((pxi != null) ? pxi.ContextDatabase : null); SprContext ctx = new SprContext(pe, pd, SprCompileFlags.NonActive, false, false); KeyValuePair? okvpCmd = null; string strUrl = SprEngine.Compile(pe.Strings.ReadSafe(PwDefs.UrlField), ctx); if(WinUtil.IsCommandLineUrl(strUrl)) { strUrl = WinUtil.GetCommandLineFromUrl(strUrl); if(!NativeLib.IsUnix()) // LNKs only supported on Windows { string strApp, strArgs; StrUtil.SplitCommandLine(strUrl, out strApp, out strArgs); if(!string.IsNullOrEmpty(strApp)) okvpCmd = new KeyValuePair(strApp, strArgs); } } if(string.IsNullOrEmpty(strUrl)) return; bool bLnk = okvpCmd.HasValue; string strTitleCmp = SprEngine.Compile(pe.Strings.ReadSafe(PwDefs.TitleField), ctx); if(string.IsNullOrEmpty(strTitleCmp)) strTitleCmp = KPRes.Entry; string strTitle = Program.Config.Defaults.WinFavsFileNamePrefix + strTitleCmp; string strSuffix = Program.Config.Defaults.WinFavsFileNameSuffix + (bLnk ? ".lnk" : ".url"); strSuffix = UrlUtil.FilterFileName(strSuffix); string strFileBase = (UrlUtil.EnsureTerminatingSeparator(strDir, false) + UrlUtil.FilterFileName(strTitle)); string strFile = strFileBase + strSuffix; int iFind = 2; while(File.Exists(strFile)) { strFile = strFileBase + " (" + iFind.ToString() + ")" + strSuffix; ++iFind; } if(!Directory.Exists(strDir)) { try { Directory.CreateDirectory(strDir); } catch(Exception exDir) { throw new Exception(strDir + MessageService.NewParagraph + exDir.Message); } WaitForDirCommit(strDir, true); } try { if(bLnk) { int ccMaxDesc = NativeMethods.INFOTIPSIZE - 1 - LnkDescSuffix.Length; string strDesc = StrUtil.CompactString3Dots(strUrl, ccMaxDesc) + LnkDescSuffix; ShellLinkEx sl = new ShellLinkEx(okvpCmd.Value.Key, okvpCmd.Value.Value, strDesc); sl.Save(strFile); } else { StringBuilder sb = new StringBuilder(); sb.AppendLine(@"[InternetShortcut]"); sb.AppendLine(@"URL=" + strUrl); // No additional line break sb.AppendLine(@"[" + PwDefs.ShortProductName + @"]"); sb.AppendLine(IniTypeKey + @"=" + IniTypeValue); // Terminating line break is important File.WriteAllText(strFile, sb.ToString(), Encoding.Default); } } catch(Exception exWrite) { throw new Exception(strFile + MessageService.NewParagraph + exWrite.Message); } } private static void WaitForDirCommit(string strDir, bool bRequireExists) { for(int i = 0; i < 20; ++i) { bool bExists = Directory.Exists(strDir); if(bExists && bRequireExists) return; if(!bExists && !bRequireExists) return; Thread.Sleep(50); } } private static void DeletePreviousExport(string strDir, IStatusLogger slLogger) { List vDirsToDelete = new List(); try { List lUrlFiles = UrlUtil.GetFilePaths(strDir, "*.url", SearchOption.AllDirectories); List lLnkFiles = UrlUtil.GetFilePaths(strDir, "*.lnk", SearchOption.AllDirectories); List lFiles = new List(); lFiles.AddRange(lUrlFiles); lFiles.AddRange(lLnkFiles); for(int iFile = 0; iFile < lFiles.Count; ++iFile) { string strFile = lFiles[iFile]; try { bool bDelete = false; if(strFile.EndsWith(".url", StrUtil.CaseIgnoreCmp)) { IniFile ini = IniFile.Read(strFile, Encoding.Default); string strType = ini.Get(PwDefs.ShortProductName, IniTypeKey); bDelete = ((strType != null) && (strType == IniTypeValue)); } else if(strFile.EndsWith(".lnk", StrUtil.CaseIgnoreCmp)) { ShellLinkEx sl = ShellLinkEx.Load(strFile); if(sl != null) bDelete = ((sl.Description != null) && sl.Description.EndsWith(LnkDescSuffix)); } else { Debug.Assert(false); } if(bDelete) { File.Delete(strFile); string strCont = UrlUtil.GetFileDirectory(strFile, false, true); if(vDirsToDelete.IndexOf(strCont) < 0) vDirsToDelete.Add(strCont); } } catch(Exception) { Debug.Assert(false); } if(slLogger != null) slLogger.SetProgress(((uint)iFile * 50U) / (uint)lFiles.Count); } bool bDeleted = true; while(bDeleted) { bDeleted = false; for(int i = (vDirsToDelete.Count - 1); i >= 0; --i) { try { Directory.Delete(vDirsToDelete[i], false); WaitForDirCommit(vDirsToDelete[i], false); vDirsToDelete.RemoveAt(i); bDeleted = true; } catch(Exception) { } // E.g. not empty } } } catch(Exception) { Debug.Assert(false); } } } } KeePass/DataExchange/Formats/KasperskyPwMgrXml50.cs0000664000000000000000000000305513222430404021143 0ustar rootroot/* KeePass Password Safe - The Open-Source Password Manager Copyright (C) 2003-2018 Dominik Reichl This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ using System; using System.Collections.Generic; using System.Text; using System.IO; using System.Drawing; using System.Diagnostics; using KeePass.Resources; using KeePassLib; using KeePassLib.Interfaces; namespace KeePass.DataExchange.Formats { // Sticky Password is basically the same password manager as // Kaspersky Password Manager, and the exported XML files // are exactly the same. // 5.0.0.148-5.0.0.183+ internal sealed class KasperskyPwMgrXml50 : StickyPwXml50 { public override string FormatName { get { return "Kaspersky Password Manager XML"; } } public override Image SmallIcon { get { return KeePass.Properties.Resources.B16x16_Imp_KasperskyPwMgr; } } } } KeePass/DataExchange/Formats/AnyPwCsv144.cs0000664000000000000000000001012313222430404017321 0ustar rootroot/* KeePass Password Safe - The Open-Source Password Manager Copyright (C) 2003-2018 Dominik Reichl This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ using System; using System.Collections.Generic; using System.Diagnostics; using System.Drawing; using System.Globalization; using System.IO; using System.Text; using KeePass.Resources; using KeePassLib; using KeePassLib.Interfaces; using KeePassLib.Security; using KeePassLib.Utility; namespace KeePass.DataExchange.Formats { // 1.44 & Pro 1.07 internal sealed class AnyPwCsv144 : FileFormatProvider { public override bool SupportsImport { get { return true; } } public override bool SupportsExport { get { return false; } } public override string FormatName { get { return "Any Password CSV"; } } public override string DefaultExtension { get { return "csv"; } } public override string ApplicationGroup { get { return KPRes.PasswordManagers; } } public override bool ImportAppendsToRootGroupOnly { get { return true; } } public override Image SmallIcon { get { return KeePass.Properties.Resources.B16x16_Imp_AnyPw; } } public override void Import(PwDatabase pwStorage, Stream sInput, IStatusLogger slLogger) { StreamReader sr = new StreamReader(sInput, Encoding.Default); string strData = sr.ReadToEnd(); sr.Close(); string[] vLines = strData.Split(new char[]{ '\r', '\n' }, StringSplitOptions.RemoveEmptyEntries); foreach(string strLine in vLines) { if(strLine.Length > 5) ProcessCsvLine(strLine, pwStorage); } } private static void ProcessCsvLine(string strLine, PwDatabase pwStorage) { List list = ImportUtil.SplitCsvLine(strLine, ","); Debug.Assert((list.Count == 6) || (list.Count == 7)); if(list.Count < 6) return; bool bIsPro = (list.Count >= 7); // Std exports 6 fields only PwEntry pe = new PwEntry(true, true); pwStorage.RootGroup.AddEntry(pe, true); pe.Strings.Set(PwDefs.TitleField, new ProtectedString( pwStorage.MemoryProtection.ProtectTitle, ParseCsvWord(list[0], false))); pe.Strings.Set(PwDefs.UserNameField, new ProtectedString( pwStorage.MemoryProtection.ProtectUserName, ParseCsvWord(list[1], false))); pe.Strings.Set(PwDefs.PasswordField, new ProtectedString( pwStorage.MemoryProtection.ProtectPassword, ParseCsvWord(list[2], false))); pe.Strings.Set(PwDefs.UrlField, new ProtectedString( pwStorage.MemoryProtection.ProtectUrl, ParseCsvWord(list[3], false))); int p = 3; if(bIsPro) pe.Strings.Set(KPRes.Custom, new ProtectedString(false, ParseCsvWord(list[++p], false))); pe.Strings.Set(PwDefs.NotesField, new ProtectedString( pwStorage.MemoryProtection.ProtectNotes, ParseCsvWord(list[++p], true))); DateTime dt; if(DateTime.TryParse(ParseCsvWord(list[++p], false), out dt)) pe.CreationTime = pe.LastAccessTime = pe.LastModificationTime = TimeUtil.ToUtc(dt, false); else { Debug.Assert(false); } } private static string ParseCsvWord(string strWord, bool bFixCodes) { string str = strWord.Trim(); if((str.Length >= 2) && str.StartsWith("\"") && str.EndsWith("\"")) str = str.Substring(1, str.Length - 2); str = str.Replace("\"\"", "\""); if(bFixCodes) { str = str.Replace("<13>", string.Empty); str = str.Replace("<10>", "\r\n"); } return str; } } } KeePass/DataExchange/Formats/KeePassHtml2x.cs0000664000000000000000000000462513222430404020022 0ustar rootroot/* KeePass Password Safe - The Open-Source Password Manager Copyright (C) 2003-2018 Dominik Reichl This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ using System; using System.Collections.Generic; using System.Text; using System.Drawing; using System.IO; using System.Windows.Forms; using KeePass.Forms; using KeePass.Resources; using KeePass.UI; using KeePassLib; using KeePassLib.Interfaces; using KeePassLib.Utility; namespace KeePass.DataExchange.Formats { internal sealed class KeePassHtml2x : FileFormatProvider { public override bool SupportsImport { get { return false; } } public override bool SupportsExport { get { return true; } } public override string FormatName { get { return KPRes.CustomizableHtml; } } public override string DefaultExtension { get { return @"html|htm"; } } public override string ApplicationGroup { get { return KPRes.General; } } public override Image SmallIcon { get { return KeePass.Properties.Resources.B16x16_HTML; } } public override bool Export(PwExportInfo pwExportInfo, Stream sOutput, IStatusLogger slLogger) { ImageList il = null; MainForm mf = Program.MainForm; if((mf != null) && (mf.ActiveDatabase == pwExportInfo.ContextDatabase)) il = mf.ClientIcons; PrintForm dlg = new PrintForm(); dlg.InitEx(pwExportInfo.DataGroup, pwExportInfo.ContextDatabase, il, false, -1); bool bResult = false; try { if(dlg.ShowDialog() == DialogResult.OK) { byte[] pb = StrUtil.Utf8.GetBytes(dlg.GeneratedHtml); sOutput.Write(pb, 0, pb.Length); sOutput.Close(); bResult = true; } } finally { UIUtil.DestroyForm(dlg); } return bResult; } } } KeePass/DataExchange/Formats/PwSaverXml412.cs0000664000000000000000000001530013222430406017661 0ustar rootroot/* KeePass Password Safe - The Open-Source Password Manager Copyright (C) 2003-2018 Dominik Reichl This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ using System; using System.Collections.Generic; using System.Diagnostics; using System.Drawing; using System.IO; using System.Text; using System.Xml; using KeePass.Resources; using KeePass.Util; using KeePassLib; using KeePassLib.Interfaces; using KeePassLib.Utility; namespace KeePass.DataExchange.Formats { // 4.1.2+ internal sealed class PwSaverXml412 : FileFormatProvider { private const string ElemRoot = "ROOT"; private const string ElemGroup = "FOLDER"; private const string ElemRecycleBin = "GARBAGE"; private const string ElemEntry = "RECORD"; private const string ElemName = "NAME"; private const string ElemIcon = "ICON"; private const string ElemFields = "FIELDS"; private const string ElemField = "FIELD"; private const string ElemID = "ID"; private const string ElemType = "TYPE"; private const string ElemValue = "VALUE"; public override bool SupportsImport { get { return true; } } public override bool SupportsExport { get { return false; } } public override string FormatName { get { return "Password Saver XML"; } } public override string DefaultExtension { get { return "xml"; } } public override string ApplicationGroup { get { return KPRes.PasswordManagers; } } public override Image SmallIcon { get { return KeePass.Properties.Resources.B16x16_Imp_PwSaver; } } public override void Import(PwDatabase pwStorage, Stream sInput, IStatusLogger slLogger) { StreamReader sr = new StreamReader(sInput, StrUtil.Utf8); string strDoc = sr.ReadToEnd(); sr.Close(); XmlDocument doc = new XmlDocument(); doc.LoadXml(strDoc); XmlElement xmlRoot = doc.DocumentElement; Debug.Assert(xmlRoot.Name == ElemRoot); PwGroup pgRoot = pwStorage.RootGroup; foreach(XmlNode xmlChild in xmlRoot.ChildNodes) { if(xmlChild.Name == ElemGroup) ImportGroup(xmlChild, pgRoot, pwStorage, false); else if(xmlChild.Name == ElemRecycleBin) ImportGroup(xmlChild, pgRoot, pwStorage, true); else if(xmlChild.Name == ElemEntry) ImportEntry(xmlChild, pgRoot, pwStorage); else { Debug.Assert(false); } } } private static void ImportGroup(XmlNode xn, PwGroup pgParent, PwDatabase pd, bool bIsRecycleBin) { PwGroup pg; if(!bIsRecycleBin) { pg = new PwGroup(true, true); pgParent.AddGroup(pg, true); } else { pg = pd.RootGroup.FindGroup(pd.RecycleBinUuid, true); if(pg == null) { pg = new PwGroup(true, true, KPRes.RecycleBin, PwIcon.TrashBin); pgParent.AddGroup(pg, true); pd.RecycleBinUuid = pg.Uuid; pd.RecycleBinChanged = DateTime.UtcNow; } } foreach(XmlNode xmlChild in xn.ChildNodes) { if(xmlChild.Name == ElemName) pg.Name = XmlUtil.SafeInnerText(xmlChild); else if(xmlChild.Name == ElemIcon) pg.IconId = GetIcon(XmlUtil.SafeInnerText(xmlChild)); else if(xmlChild.Name == ElemGroup) ImportGroup(xmlChild, pg, pd, false); else if(xmlChild.Name == ElemEntry) ImportEntry(xmlChild, pg, pd); else { Debug.Assert(false); } } } private static void ImportEntry(XmlNode xn, PwGroup pgParent, PwDatabase pd) { PwEntry pe = new PwEntry(true, true); pgParent.AddEntry(pe, true); foreach(XmlNode xmlChild in xn.ChildNodes) { if(xmlChild.Name == ElemName) ImportUtil.AppendToField(pe, PwDefs.TitleField, XmlUtil.SafeInnerText(xmlChild), pd); else if(xmlChild.Name == ElemIcon) pe.IconId = GetIcon(XmlUtil.SafeInnerText(xmlChild)); else if(xmlChild.Name == ElemFields) ImportFields(xmlChild, pe, pd); else { Debug.Assert(false); } } } private static void ImportFields(XmlNode xn, PwEntry pe, PwDatabase pd) { foreach(XmlNode xmlChild in xn.ChildNodes) { if(xmlChild.Name == ElemField) ImportField(xmlChild, pe, pd); else { Debug.Assert(false); } } } private static void ImportField(XmlNode xn, PwEntry pe, PwDatabase pd) { string strName = null; string strValue = null; foreach(XmlNode xmlChild in xn.ChildNodes) { if(xmlChild.Name == ElemID) { } else if(xmlChild.Name == ElemName) strName = XmlUtil.SafeInnerText(xmlChild); else if(xmlChild.Name == ElemType) { } else if(xmlChild.Name == ElemValue) strValue = XmlUtil.SafeInnerText(xmlChild); else { Debug.Assert(false); } } if(!string.IsNullOrEmpty(strName) && !string.IsNullOrEmpty(strValue)) { string strF = ImportUtil.MapNameToStandardField(strName, true); if((strName == "Control Panel") || (strName == "Webmail Interface")) strF = PwDefs.UrlField; else if(strName == "FTP Address") strF = strName; else if(strName == "FTP Username") strF = "FTP User Name"; else if(strName == "FTP Password") strF = strName; if(string.IsNullOrEmpty(strF)) strF = strName; ImportUtil.AppendToField(pe, strF, strValue, pd, ((strF == PwDefs.NotesField) ? MessageService.NewLine : ", "), true); } } private static PwIcon GetIcon(string strName) { if(string.IsNullOrEmpty(strName)) { Debug.Assert(false); return PwIcon.Key; } string str = strName.ToUpperInvariant(); if(str == "FOLDER") return PwIcon.Folder; if(str == "RECORD") return PwIcon.Key; if(str == "WEBSITE.ICO") return PwIcon.Home; if(str == "HOSTING.ICO") return PwIcon.NetworkServer; if(str == "DIALUP.ICO") return PwIcon.WorldSocket; if(str == "SHOPING.ICO") return PwIcon.ClipboardReady; // Sic if(str == "AUCTION.ICO") return PwIcon.Tool; if(str == "MESSENGER.ICO") return PwIcon.UserCommunication; if(str == "SOFTWARE_SERIALS.ICO") return PwIcon.CDRom; if(str == "CREDITCARD.ICO") return PwIcon.Identity; if(str == "MAILBOX.ICO") return PwIcon.EMailBox; Debug.Assert(false); return PwIcon.Key; } } } KeePass/DataExchange/Formats/KeePassXXml041.cs0000664000000000000000000001662713222430404017766 0ustar rootroot/* KeePass Password Safe - The Open-Source Password Manager Copyright (C) 2003-2018 Dominik Reichl This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ using System; using System.Collections.Generic; using System.Text; using System.Drawing; using System.IO; using System.Xml; using System.Xml.Serialization; using System.Diagnostics; using KeePass.Resources; using KeePass.Util; using KeePassLib; using KeePassLib.Collections; using KeePassLib.Interfaces; using KeePassLib.Security; using KeePassLib.Serialization; using KeePassLib.Utility; namespace KeePass.DataExchange.Formats { // 0.4.1 internal sealed class KeePassXXml041 : FileFormatProvider { public override bool SupportsImport { get { return true; } } public override bool SupportsExport { get { return false; } } public override string FormatName { get { return "KeePassX XML"; } } public override string DefaultExtension { get { return "xml"; } } public override string ApplicationGroup { get { return KPRes.PasswordManagers; } } public override bool SupportsUuids { get { return false; } } public override Image SmallIcon { get { return KeePass.Properties.Resources.B16x16_Imp_KeePassX; } } private const string ElemRoot = "database"; private const string ElemGroup = "group"; private const string ElemTitle = "title"; private const string ElemIcon = "icon"; private const string ElemEntry = "entry"; private const string ElemUserName = "username"; private const string ElemUrl = "url"; private const string ElemPassword = "password"; private const string ElemNotes = "comment"; private const string ElemCreationTime = "creation"; private const string ElemLastModTime = "lastmod"; private const string ElemLastAccessTime = "lastaccess"; private const string ElemExpiryTime = "expire"; private const string ElemAttachDesc = "bindesc"; private const string ElemAttachment = "bin"; private const string ValueNever = "Never"; public override void Import(PwDatabase pwStorage, Stream sInput, IStatusLogger slLogger) { XmlDocument xmlDoc = new XmlDocument(); xmlDoc.Load(sInput); XmlNode xmlRoot = xmlDoc.DocumentElement; Debug.Assert(xmlRoot.Name == ElemRoot); Stack vGroups = new Stack(); vGroups.Push(pwStorage.RootGroup); int nNodeCount = xmlRoot.ChildNodes.Count; for(int i = 0; i < nNodeCount; ++i) { XmlNode xmlChild = xmlRoot.ChildNodes[i]; if(xmlChild.Name == ElemGroup) ReadGroup(xmlChild, vGroups, pwStorage); else { Debug.Assert(false); } if(slLogger != null) slLogger.SetProgress((uint)(((i + 1) * 100) / nNodeCount)); } } private static PwIcon ReadIcon(XmlNode xmlChild, PwIcon pwDefault) { int nIcon; if(StrUtil.TryParseInt(XmlUtil.SafeInnerText(xmlChild), out nIcon)) { if((nIcon >= 0) && (nIcon < (int)PwIcon.Count)) return (PwIcon)nIcon; } else { Debug.Assert(false); } return pwDefault; } private static void ReadGroup(XmlNode xmlNode, Stack vGroups, PwDatabase pwStorage) { if(vGroups.Count == 0) { Debug.Assert(false); return; } PwGroup pgParent = vGroups.Peek(); PwGroup pg = new PwGroup(true, true); pgParent.AddGroup(pg, true); vGroups.Push(pg); foreach(XmlNode xmlChild in xmlNode) { if(xmlChild.Name == ElemTitle) pg.Name = XmlUtil.SafeInnerText(xmlChild); else if(xmlChild.Name == ElemIcon) pg.IconId = ReadIcon(xmlChild, pg.IconId); else if(xmlChild.Name == ElemGroup) ReadGroup(xmlChild, vGroups, pwStorage); else if(xmlChild.Name == ElemEntry) ReadEntry(xmlChild, pg, pwStorage); else { Debug.Assert(false); } } vGroups.Pop(); } private static void ReadEntry(XmlNode xmlNode, PwGroup pgParent, PwDatabase pwStorage) { PwEntry pe = new PwEntry(true, true); pgParent.AddEntry(pe, true); string strAttachDesc = null, strAttachment = null; foreach(XmlNode xmlChild in xmlNode) { if(xmlChild.Name == ElemTitle) pe.Strings.Set(PwDefs.TitleField, new ProtectedString( pwStorage.MemoryProtection.ProtectTitle, XmlUtil.SafeInnerText(xmlChild))); else if(xmlChild.Name == ElemUserName) pe.Strings.Set(PwDefs.UserNameField, new ProtectedString( pwStorage.MemoryProtection.ProtectUserName, XmlUtil.SafeInnerText(xmlChild))); else if(xmlChild.Name == ElemUrl) pe.Strings.Set(PwDefs.UrlField, new ProtectedString( pwStorage.MemoryProtection.ProtectUrl, XmlUtil.SafeInnerText(xmlChild))); else if(xmlChild.Name == ElemPassword) pe.Strings.Set(PwDefs.PasswordField, new ProtectedString( pwStorage.MemoryProtection.ProtectPassword, XmlUtil.SafeInnerText(xmlChild))); else if(xmlChild.Name == ElemNotes) pe.Strings.Set(PwDefs.NotesField, new ProtectedString( pwStorage.MemoryProtection.ProtectNotes, FilterSpecial(XmlUtil.SafeInnerXml(xmlChild)))); else if(xmlChild.Name == ElemIcon) pe.IconId = ReadIcon(xmlChild, pe.IconId); else if(xmlChild.Name == ElemCreationTime) pe.CreationTime = ParseTime(XmlUtil.SafeInnerText(xmlChild)); else if(xmlChild.Name == ElemLastModTime) pe.LastModificationTime = ParseTime(XmlUtil.SafeInnerText(xmlChild)); else if(xmlChild.Name == ElemLastAccessTime) pe.LastAccessTime = ParseTime(XmlUtil.SafeInnerText(xmlChild)); else if(xmlChild.Name == ElemExpiryTime) { string strDate = XmlUtil.SafeInnerText(xmlChild); pe.Expires = (strDate != ValueNever); if(pe.Expires) pe.ExpiryTime = ParseTime(strDate); } else if(xmlChild.Name == ElemAttachDesc) strAttachDesc = XmlUtil.SafeInnerText(xmlChild); else if(xmlChild.Name == ElemAttachment) strAttachment = XmlUtil.SafeInnerText(xmlChild); else { Debug.Assert(false); } } if(!string.IsNullOrEmpty(strAttachDesc) && (strAttachment != null)) { byte[] pbData = Convert.FromBase64String(strAttachment); ProtectedBinary pb = new ProtectedBinary(false, pbData); pe.Binaries.Set(strAttachDesc, pb); } } private static DateTime ParseTime(string str) { if(string.IsNullOrEmpty(str)) { Debug.Assert(false); return DateTime.UtcNow; } if(str == "0000-00-00T00:00:00") return DateTime.UtcNow; DateTime dt; if(DateTime.TryParse(str, out dt)) return TimeUtil.ToUtc(dt, false); Debug.Assert(false); return DateTime.UtcNow; } private static string FilterSpecial(string strData) { string str = strData; str = str.Replace(@"
", MessageService.NewLine); str = str.Replace(@"
", MessageService.NewLine); str = StrUtil.XmlToString(str); return str; } } } KeePass/DataExchange/Formats/MSecureCsv355.cs0000664000000000000000000002337213222430404017644 0ustar rootroot/* KeePass Password Safe - The Open-Source Password Manager Copyright (C) 2003-2018 Dominik Reichl This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ using System; using System.Collections.Generic; using System.Diagnostics; using System.Drawing; using System.IO; using System.Text; using KeePass.Resources; using KeePassLib; using KeePassLib.Interfaces; using KeePassLib.Utility; namespace KeePass.DataExchange.Formats { // 3.5.5+ internal sealed class MSecureCsv355 : FileFormatProvider { public override bool SupportsImport { get { return true; } } public override bool SupportsExport { get { return false; } } public override string FormatName { get { return "mSecure CSV"; } } public override string DefaultExtension { get { return "csv"; } } public override string ApplicationGroup { get { return KPRes.PasswordManagers; } } public override bool ImportAppendsToRootGroupOnly { get { return false; } } public override Image SmallIcon { get { return KeePass.Properties.Resources.B16x16_Imp_MSecure; } } public override void Import(PwDatabase pwStorage, Stream sInput, IStatusLogger slLogger) { StreamReader sr = new StreamReader(sInput, Encoding.Default, true); string str = sr.ReadToEnd(); sr.Close(); CsvOptions opt = new CsvOptions(); // Backslashes are not escaped, even though "\\n" is used // to encode new-line characters opt.BackslashIsEscape = false; opt.FieldSeparator = ';'; CsvStreamReaderEx csr = new CsvStreamReaderEx(str, opt); Dictionary dGroups = new Dictionary(); while(true) { string[] vLine = csr.ReadLine(); if(vLine == null) break; AddEntry(vLine, pwStorage, dGroups); } } private static void AddEntry(string[] vLine, PwDatabase pd, Dictionary dGroups) { if(vLine.Length < 2) return; string strGroup = vLine[0]; PwGroup pg; if(string.IsNullOrEmpty(strGroup)) pg = pd.RootGroup; else { if(!dGroups.TryGetValue(strGroup, out pg)) { pg = new PwGroup(true, true); pg.Name = strGroup; pd.RootGroup.AddGroup(pg, true); dGroups[strGroup] = pg; } } PwEntry pe = new PwEntry(true, true); pg.AddEntry(pe, true); MsAppend(pe, PwDefs.TitleField, vLine, 2, pd); MsAppend(pe, PwDefs.NotesField, vLine, 3, pd); string strType = vLine[1]; int i = 3; DateTime dt; switch(strType) { case "Bank Accounts": MsAppend(pe, PwDefs.UserNameField, vLine, ++i, pd); MsAppend(pe, PwDefs.PasswordField, vLine, ++i, pd); MsAppend(pe, "Name", vLine, ++i, pd); MsAppend(pe, "Branch", vLine, ++i, pd); MsAppend(pe, "Phone No.", vLine, ++i, pd); pe.IconId = PwIcon.Money; break; case "Birthdays": MsAppend(pe, PwDefs.UserNameField, vLine, ++i, pd); pe.IconId = PwIcon.UserCommunication; break; case "Calling Cards": case "Social Security": case "Voice Mail": MsAppend(pe, PwDefs.UserNameField, vLine, ++i, pd); MsAppend(pe, PwDefs.PasswordField, vLine, ++i, pd); pe.IconId = PwIcon.UserKey; break; case "Clothes Size": MsAppend(pe, "Shirt Size", vLine, ++i, pd); MsAppend(pe, "Pant Size", vLine, ++i, pd); MsAppend(pe, "Shoe Size", vLine, ++i, pd); MsAppend(pe, "Dress Size", vLine, ++i, pd); break; case "Combinations": MsAppend(pe, PwDefs.PasswordField, vLine, ++i, pd); break; case "Credit Cards": MsAppend(pe, PwDefs.UserNameField, vLine, ++i, pd); ++i; if((vLine.Length > i) && StrUtil.TryParseDateTime( vLine[i], out dt)) { pe.Expires = true; pe.ExpiryTime = TimeUtil.ToUtc(dt, false); } else MsAppend(pe, "Expiration", vLine, i, pd); MsAppend(pe, "Name", vLine, ++i, pd); MsAppend(pe, PwDefs.PasswordField, vLine, ++i, pd); MsAppend(pe, "Bank", vLine, ++i, pd); MsAppend(pe, "Security Code", vLine, ++i, pd); pe.IconId = PwIcon.Money; break; case "Email Accounts": MsAppend(pe, PwDefs.UserNameField, vLine, ++i, pd); MsAppend(pe, PwDefs.PasswordField, vLine, ++i, pd); MsAppend(pe, "POP3 Host", vLine, ++i, pd); MsAppend(pe, "SMTP Host", vLine, ++i, pd); pe.IconId = PwIcon.EMail; break; case "Frequent Flyer": MsAppend(pe, "Number", vLine, ++i, pd); MsAppend(pe, PwDefs.UrlField, vLine, ++i, pd); MsAppend(pe, PwDefs.UserNameField, vLine, ++i, pd); MsAppend(pe, PwDefs.PasswordField, vLine, ++i, pd); MsAppend(pe, "Mileage", vLine, ++i, pd); break; case "Identity": ++i; MsAppend(pe, PwDefs.UserNameField, vLine, i + 1, pd); // Last name MsAppend(pe, PwDefs.UserNameField, vLine, i, pd); // First name ++i; MsAppend(pe, "Nick Name", vLine, ++i, pd); MsAppend(pe, "Company", vLine, ++i, pd); MsAppend(pe, PwDefs.UserNameField, vLine, ++i, pd); MsAppend(pe, "Address", vLine, ++i, pd); MsAppend(pe, "Address 2", vLine, ++i, pd); MsAppend(pe, "City", vLine, ++i, pd); MsAppend(pe, "State", vLine, ++i, pd); MsAppend(pe, "Country", vLine, ++i, pd); MsAppend(pe, "Zip", vLine, ++i, pd); MsAppend(pe, "Home Phone", vLine, ++i, pd); MsAppend(pe, "Office Phone", vLine, ++i, pd); MsAppend(pe, "Mobile Phone", vLine, ++i, pd); MsAppend(pe, "E-Mail", vLine, ++i, pd); MsAppend(pe, "E-Mail 2", vLine, ++i, pd); MsAppend(pe, "Skype", vLine, ++i, pd); MsAppend(pe, PwDefs.UrlField, vLine, ++i, pd); pe.IconId = PwIcon.UserCommunication; break; case "Insurance": MsAppend(pe, PwDefs.UserNameField, vLine, ++i, pd); MsAppend(pe, "Group No.", vLine, ++i, pd); MsAppend(pe, "Insured", vLine, ++i, pd); MsAppend(pe, "Date", vLine, ++i, pd); MsAppend(pe, "Phone No.", vLine, ++i, pd); pe.IconId = PwIcon.Certificate; break; case "Memberships": MsAppend(pe, PwDefs.PasswordField, vLine, ++i, pd); MsAppend(pe, PwDefs.UserNameField, vLine, ++i, pd); MsAppend(pe, "Date", vLine, ++i, pd); pe.IconId = PwIcon.UserKey; break; case "Note": pe.IconId = PwIcon.Notepad; break; case "Passport": MsAppend(pe, PwDefs.UserNameField, vLine, ++i, pd); MsAppend(pe, PwDefs.PasswordField, vLine, ++i, pd); MsAppend(pe, "Type", vLine, ++i, pd); MsAppend(pe, "Issuing Country", vLine, ++i, pd); MsAppend(pe, "Issuing Authority", vLine, ++i, pd); MsAppend(pe, "Nationality", vLine, ++i, pd); ++i; if((vLine.Length > i) && StrUtil.TryParseDateTime( vLine[i], out dt)) { pe.Expires = true; pe.ExpiryTime = TimeUtil.ToUtc(dt, false); } else MsAppend(pe, "Expiration", vLine, i, pd); MsAppend(pe, "Place of Birth", vLine, ++i, pd); pe.IconId = PwIcon.Certificate; break; case "Prescriptions": MsAppend(pe, "RX Number", vLine, ++i, pd); MsAppend(pe, PwDefs.UserNameField, vLine, ++i, pd); MsAppend(pe, "Doctor", vLine, ++i, pd); MsAppend(pe, "Pharmacy", vLine, ++i, pd); MsAppend(pe, "Phone No.", vLine, ++i, pd); break; case "Registration Codes": MsAppend(pe, PwDefs.UserNameField, vLine, ++i, pd); MsAppend(pe, "Date", vLine, ++i, pd); pe.IconId = PwIcon.UserKey; break; case "Unassigned": MsAppend(pe, "Field 1", vLine, ++i, pd); MsAppend(pe, "Field 2", vLine, ++i, pd); MsAppend(pe, "Field 3", vLine, ++i, pd); MsAppend(pe, "Field 4", vLine, ++i, pd); MsAppend(pe, "Field 5", vLine, ++i, pd); MsAppend(pe, "Field 6", vLine, ++i, pd); break; case "Vehicle Info": MsAppend(pe, PwDefs.UserNameField, vLine, ++i, pd); MsAppend(pe, PwDefs.PasswordField, vLine, ++i, pd); MsAppend(pe, "Date Purchased", vLine, ++i, pd); MsAppend(pe, "Tire Size", vLine, ++i, pd); break; case "Web Logins": MsAppend(pe, PwDefs.UrlField, vLine, ++i, pd); MsAppend(pe, PwDefs.UserNameField, vLine, ++i, pd); MsAppend(pe, PwDefs.PasswordField, vLine, ++i, pd); break; default: Debug.Assert(false); break; } Debug.Assert((i + 1) == vLine.Length); } private static void MsAppend(PwEntry pe, string strFieldName, string[] vLine, int iIndex, PwDatabase pdContext) { if(iIndex >= vLine.Length) { Debug.Assert(false); return; } string strValue = vLine[iIndex]; if(string.IsNullOrEmpty(strValue)) return; strValue = strValue.Replace("\\r\\n", "\\n"); strValue = strValue.Replace("\\r", "\\n"); if(PwDefs.IsStandardField(strFieldName) && (strFieldName != PwDefs.NotesField)) { while(strValue.EndsWith("\\n")) { strValue = strValue.Substring(0, strValue.Length - 2); } strValue = strValue.Replace("\\n", ", "); } else strValue = strValue.Replace("\\n", MessageService.NewLine); ImportUtil.AppendToField(pe, strFieldName, strValue, pdContext); } } } KeePass/DataExchange/Formats/PwDepotXml26.cs0000664000000000000000000002624613222430404017606 0ustar rootroot/* KeePass Password Safe - The Open-Source Password Manager Copyright (C) 2003-2018 Dominik Reichl This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ using System; using System.Collections.Generic; using System.Text; using System.Xml; using System.IO; using System.Drawing; using System.Globalization; using System.Diagnostics; using KeePass.Resources; using KeePass.Util; using KeePassLib; using KeePassLib.Interfaces; using KeePassLib.Security; using KeePassLib.Utility; namespace KeePass.DataExchange.Formats { // 2.6 - 5.3.0+ internal sealed class PwDepotXml26 : FileFormatProvider { private const string ElemHeader = "HEADER"; private const string ElemContainer = "PASSWORDS"; private const string ElemGroup = "GROUP"; private const string AttribGroupName = "NAME"; private const string ElemEntry = "ITEM"; private const string ElemEntryName = "DESCRIPTION"; private const string ElemEntryUser = "USERNAME"; private const string ElemEntryPassword = "PASSWORD"; private const string ElemEntryURL = "URL"; private const string ElemEntryNotes = "COMMENT"; private const string ElemEntryLastModTime = "LASTMODIFIED"; private const string ElemEntryExpireTime = "EXPIRYDATE"; private const string ElemEntryCreatedTime = "CREATED"; private const string ElemEntryLastAccTime = "LASTACCESSED"; private const string ElemEntryUsageCount = "USAGECOUNT"; private const string ElemEntryAutoType = "TEMPLATE"; private const string ElemEntryCustom = "CUSTOMFIELDS"; private static readonly string[] ElemEntryUnsupportedItems = new string[]{ "TYPE", "IMPORTANCE", "IMAGECUSTOM", "PARAMSTR", "CATEGORY", "CUSTOMBROWSER", "AUTOCOMPLETEMETHOD", "WEBFORMDATA", "TANS", "FINGERPRINT" }; private const string ElemImageIndex = "IMAGEINDEX"; private const string ElemCustomField = "FIELD"; private const string ElemCustomFieldName = "NAME"; private const string ElemCustomFieldValue = "VALUE"; private const string AttribFormat = "FMT"; private const string FieldInfoText = "IDS_InformationText"; public override bool SupportsImport { get { return true; } } public override bool SupportsExport { get { return false; } } public override string FormatName { get { return "Password Depot XML"; } } public override string DefaultExtension { get { return "xml"; } } public override string ApplicationGroup { get { return KPRes.PasswordManagers; } } public override Image SmallIcon { get { return KeePass.Properties.Resources.B16x16_Imp_PwDepot; } } public override void Import(PwDatabase pwStorage, Stream sInput, IStatusLogger slLogger) { StreamReader sr = new StreamReader(sInput, StrUtil.Utf8); string strData = sr.ReadToEnd(); sr.Close(); // Remove vertical tabulators strData = strData.Replace("\u000B", string.Empty); XmlDocument xmlDoc = new XmlDocument(); xmlDoc.LoadXml(strData); XmlNode xmlRoot = xmlDoc.DocumentElement; foreach(XmlNode xmlChild in xmlRoot.ChildNodes) { if(xmlChild.Name == ElemHeader) { } // Unsupported else if(xmlChild.Name == ElemContainer) ReadContainer(xmlChild, pwStorage); else { Debug.Assert(false); } } } private static void ReadContainer(XmlNode xmlNode, PwDatabase pwStorage) { foreach(XmlNode xmlChild in xmlNode.ChildNodes) { if(xmlChild.Name == ElemGroup) ReadGroup(xmlChild, pwStorage.RootGroup, pwStorage); else { Debug.Assert(false); } } } private static void ReadGroup(XmlNode xmlNode, PwGroup pgParent, PwDatabase pwStorage) { PwGroup pg = new PwGroup(true, true); pgParent.AddGroup(pg, true); try { XmlAttributeCollection xac = xmlNode.Attributes; pg.Name = xac.GetNamedItem(AttribGroupName).Value; } catch(Exception) { } foreach(XmlNode xmlChild in xmlNode) { if(xmlChild.Name == ElemGroup) ReadGroup(xmlChild, pg, pwStorage); else if(xmlChild.Name == ElemEntry) ReadEntry(xmlChild, pg, pwStorage); else { Debug.Assert(false); } } } private static void ReadEntry(XmlNode xmlNode, PwGroup pgParent, PwDatabase pwStorage) { PwEntry pe = new PwEntry(true, true); pgParent.AddEntry(pe, true); DateTime? ndt; foreach(XmlNode xmlChild in xmlNode) { if(xmlChild.Name == ElemEntryName) pe.Strings.Set(PwDefs.TitleField, new ProtectedString( pwStorage.MemoryProtection.ProtectTitle, XmlUtil.SafeInnerText(xmlChild))); else if(xmlChild.Name == ElemEntryUser) pe.Strings.Set(PwDefs.UserNameField, new ProtectedString( pwStorage.MemoryProtection.ProtectUserName, XmlUtil.SafeInnerText(xmlChild))); else if(xmlChild.Name == ElemEntryPassword) pe.Strings.Set(PwDefs.PasswordField, new ProtectedString( pwStorage.MemoryProtection.ProtectPassword, XmlUtil.SafeInnerText(xmlChild))); else if(xmlChild.Name == ElemEntryURL) pe.Strings.Set(PwDefs.UrlField, new ProtectedString( pwStorage.MemoryProtection.ProtectUrl, XmlUtil.SafeInnerText(xmlChild))); else if(xmlChild.Name == ElemEntryNotes) pe.Strings.Set(PwDefs.NotesField, new ProtectedString( pwStorage.MemoryProtection.ProtectNotes, XmlUtil.SafeInnerText(xmlChild))); else if(xmlChild.Name == ElemEntryLastModTime) { ndt = ReadTime(xmlChild); if(ndt.HasValue) pe.LastModificationTime = ndt.Value; } else if(xmlChild.Name == ElemEntryExpireTime) { ndt = ReadTime(xmlChild); if(ndt.HasValue) { pe.ExpiryTime = ndt.Value; pe.Expires = true; } } else if(xmlChild.Name == ElemEntryCreatedTime) { ndt = ReadTime(xmlChild); if(ndt.HasValue) pe.CreationTime = ndt.Value; } else if(xmlChild.Name == ElemEntryLastAccTime) { ndt = ReadTime(xmlChild); if(ndt.HasValue) pe.LastAccessTime = ndt.Value; } else if(xmlChild.Name == ElemEntryUsageCount) { ulong uUsageCount; if(ulong.TryParse(XmlUtil.SafeInnerText(xmlChild), out uUsageCount)) pe.UsageCount = uUsageCount; } else if(xmlChild.Name == ElemEntryAutoType) pe.AutoType.DefaultSequence = MapAutoType( XmlUtil.SafeInnerText(xmlChild)); else if(xmlChild.Name == ElemEntryCustom) ReadCustomContainer(xmlChild, pe); else if(xmlChild.Name == ElemImageIndex) pe.IconId = MapIcon(XmlUtil.SafeInnerText(xmlChild), true); else if(Array.IndexOf(ElemEntryUnsupportedItems, xmlChild.Name) >= 0) { } else { Debug.Assert(false, xmlChild.Name); } } string strInfoText = pe.Strings.ReadSafe(FieldInfoText); if((pe.Strings.ReadSafe(PwDefs.NotesField).Length == 0) && (strInfoText.Length > 0)) { pe.Strings.Remove(FieldInfoText); pe.Strings.Set(PwDefs.NotesField, new ProtectedString( pwStorage.MemoryProtection.ProtectNotes, strInfoText)); } } private static void ReadCustomContainer(XmlNode xmlNode, PwEntry pe) { foreach(XmlNode xmlChild in xmlNode) { if(xmlChild.Name == ElemCustomField) ReadCustomField(xmlChild, pe); else { Debug.Assert(false); } } } private static void ReadCustomField(XmlNode xmlNode, PwEntry pe) { string strName = string.Empty, strValue = string.Empty; foreach(XmlNode xmlChild in xmlNode) { if(xmlChild.Name == ElemCustomFieldName) strName = XmlUtil.SafeInnerText(xmlChild); else if(xmlChild.Name == ElemCustomFieldValue) strValue = XmlUtil.SafeInnerText(xmlChild); // else { } // Field 'VISIBLE' } if((strName.Length == 0) || PwDefs.IsStandardField(strName)) pe.Strings.Set(Guid.NewGuid().ToString(), new ProtectedString(false, strValue)); else pe.Strings.Set(strName, new ProtectedString(false, strValue)); } private static PwIcon MapIcon(string strIconId, bool bEntryIcon) { PwIcon ico = (bEntryIcon ? PwIcon.Key : PwIcon.Folder); int idIcon; if(!int.TryParse(strIconId, out idIcon)) return ico; ++idIcon; // In the icon picker dialog, all indices are + 1 switch(idIcon) { case 1: ico = PwIcon.Key; break; case 4: ico = PwIcon.Folder; break; case 5: ico = PwIcon.LockOpen; break; case 15: ico = PwIcon.EMail; break; case 16: ico = PwIcon.EMail; break; case 17: ico = PwIcon.ProgramIcons; break; case 18: ico = PwIcon.ProgramIcons; break; case 21: ico = PwIcon.World; break; case 22: ico = PwIcon.World; break; case 25: ico = PwIcon.Money; break; case 26: ico = PwIcon.Money; break; case 27: ico = PwIcon.Star; break; case 28: ico = PwIcon.Star; break; case 47: ico = PwIcon.FolderOpen; break; case 48: ico = PwIcon.TrashBin; break; case 49: ico = PwIcon.TrashBin; break; default: break; }; return ico; } private static string MapAutoType(string str) { str = str.Replace('<', '{'); str = str.Replace('>', '}'); str = StrUtil.ReplaceCaseInsensitive(str, @"{USER}", @"{" + PwDefs.UserNameField.ToUpper() + @"}"); str = StrUtil.ReplaceCaseInsensitive(str, @"{PASS}", @"{" + PwDefs.PasswordField.ToUpper() + @"}"); str = StrUtil.ReplaceCaseInsensitive(str, @"{CLEAR}", @"{HOME}+({END}){DEL}"); str = StrUtil.ReplaceCaseInsensitive(str, @"{ARROW_LEFT}", @"{LEFT}"); str = StrUtil.ReplaceCaseInsensitive(str, @"{ARROW_UP}", @"{UP}"); str = StrUtil.ReplaceCaseInsensitive(str, @"{ARROW_RIGHT}", @"{RIGHT}"); str = StrUtil.ReplaceCaseInsensitive(str, @"{ARROW_DOWN}", @"{DOWN}"); if(str.Equals(PwDefs.DefaultAutoTypeSequence, StrUtil.CaseIgnoreCmp)) return string.Empty; return str; } private static DateTime? ReadTime(XmlNode xmlNode) { DateTime? ndt = ReadTimeRaw(xmlNode); if(!ndt.HasValue) return null; if(ndt.Value.Year < 1950) return null; return ndt.Value; } private static DateTime? ReadTimeRaw(XmlNode xmlNode) { string strTime = XmlUtil.SafeInnerText(xmlNode); string strFormat = null; try { XmlAttributeCollection xac = xmlNode.Attributes; strFormat = xac.GetNamedItem(AttribFormat).Value; } catch(Exception) { } DateTime dt; if(!string.IsNullOrEmpty(strFormat)) { strFormat = strFormat.Replace("mm", "MM"); if(DateTime.TryParseExact(strTime, strFormat, null, DateTimeStyles.AssumeLocal, out dt)) return TimeUtil.ToUtc(dt, false); } if(DateTime.TryParse(strTime, out dt)) return TimeUtil.ToUtc(dt, false); return null; } } } KeePass/DataExchange/Formats/EnpassTxt5.cs0000664000000000000000000000774613222430404017415 0ustar rootroot/* KeePass Password Safe - The Open-Source Password Manager Copyright (C) 2003-2018 Dominik Reichl This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ using System; using System.Collections.Generic; using System.Diagnostics; using System.Drawing; using System.IO; using System.Text; using KeePass.Resources; using KeePassLib; using KeePassLib.Interfaces; using KeePassLib.Security; using KeePassLib.Utility; namespace KeePass.DataExchange.Formats { // 5.3.0.1+ internal sealed class EnpassTxt5 : FileFormatProvider { public override bool SupportsImport { get { return true; } } public override bool SupportsExport { get { return false; } } public override string FormatName { get { return "Enpass TXT"; } } public override string DefaultExtension { get { return "txt"; } } public override string ApplicationGroup { get { return KPRes.PasswordManagers; } } public override bool ImportAppendsToRootGroupOnly { get { return true; } } public override Image SmallIcon { get { return KeePass.Properties.Resources.B16x16_Imp_Enpass; } } public override void Import(PwDatabase pwStorage, Stream sInput, IStatusLogger slLogger) { StreamReader sr = new StreamReader(sInput, StrUtil.Utf8, true); string strData = sr.ReadToEnd(); sr.Close(); const string strKvpSep = " : "; PwGroup pg = pwStorage.RootGroup; strData = StrUtil.NormalizeNewLines(strData, false); strData += ("\n\nTitle" + strKvpSep); string[] vLines = strData.Split('\n'); bool bLastWasEmpty = true; string strName = PwDefs.TitleField; PwEntry pe = null; string strNotes = string.Empty; // Do not trim spaces, because these are part of the // key-value separator char[] vTrimLine = new char[] { '\t', '\r', '\n' }; foreach(string strLine in vLines) { if(strLine == null) { Debug.Assert(false); continue; } string str = strLine.Trim(vTrimLine); string strValue = str; int iKvpSep = str.IndexOf(strKvpSep); if(iKvpSep >= 0) { string strOrgName = str.Substring(0, iKvpSep).Trim(); strValue = str.Substring(iKvpSep + strKvpSep.Length).Trim(); // If an entry doesn't have any notes, the next entry // may start without an empty line; in this case we // detect the new entry by the field name "Title" // (which apparently is not translated by Enpass) if(bLastWasEmpty || (strOrgName == "Title")) { if(pe != null) { strNotes = strNotes.Trim(); pe.Strings.Set(PwDefs.NotesField, new ProtectedString( pwStorage.MemoryProtection.ProtectNotes, strNotes)); strNotes = string.Empty; pg.AddEntry(pe, true); } pe = new PwEntry(true, true); } strName = ImportUtil.MapNameToStandardField(strOrgName, true); if(string.IsNullOrEmpty(strName)) { strName = strOrgName; if(string.IsNullOrEmpty(strName)) { Debug.Assert(false); strName = PwDefs.NotesField; } } } if(strName == PwDefs.NotesField) { if(strNotes.Length > 0) strNotes += MessageService.NewLine; strNotes += strValue; } else ImportUtil.AppendToField(pe, strName, strValue, pwStorage); bLastWasEmpty = (str.Length == 0); } } } } KeePass/DataExchange/Formats/SafeWalletXml3.cs0000664000000000000000000001465713222430406020173 0ustar rootroot/* KeePass Password Safe - The Open-Source Password Manager Copyright (C) 2003-2018 Dominik Reichl This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ using System; using System.Collections.Generic; using System.Text; using System.Xml; using System.IO; using System.Drawing; using System.Diagnostics; using KeePass.Resources; using KeePass.Util; using KeePassLib; using KeePassLib.Interfaces; namespace KeePass.DataExchange.Formats { // 2.4.1.2-3.0.7.2022+ internal sealed class SafeWalletXml3 : FileFormatProvider { private static readonly string[] ElemsVault = new string[] { "T37" // 3.0.5 }; private static readonly string[] ElemsGroup = new string[] { "Folder", // 2.4.1.2 "T3", // 3.0.5 "T21" // 3.0.7, special group for web entries }; private static readonly string[] ElemsEntry = new string[] { "Card", // 3.0.4 "T4" // 3.0.5 }; private static readonly string[] ElemsProps = new string[] { "Property", // 3.0.4 "T257", "T258", "T259", "T263", "T264", "T265", // 3.0.5 "T266", "T267" // 3.0.5 }; private static readonly string[] ElemsWebEntry = new string[] { "T22" // 3.0.7 }; private const string AttribCaption = "Caption"; private const string AttribWebUrl = "URL"; private const string AttribWebUserName = "Username"; private const string AttribWebPassword = "Password"; public override bool SupportsImport { get { return true; } } public override bool SupportsExport { get { return false; } } public override string FormatName { get { return "SafeWallet XML"; } } public override string DefaultExtension { get { return "xml"; } } public override string ApplicationGroup { get { return KPRes.PasswordManagers; } } public override bool ImportAppendsToRootGroupOnly { get { return false; } } public override Image SmallIcon { get { return KeePass.Properties.Resources.B16x16_Imp_SafeWallet; } } public override void Import(PwDatabase pwStorage, Stream sInput, IStatusLogger slLogger) { StreamReader sr = new StreamReader(sInput, Encoding.Unicode); string strDoc = sr.ReadToEnd(); sr.Close(); XmlDocument xd = new XmlDocument(); xd.LoadXml(strDoc); XmlNode xnRoot = xd.DocumentElement; Debug.Assert(xnRoot.Name == "SafeWallet"); foreach(XmlNode xn in xnRoot.ChildNodes) { if(Array.IndexOf(ElemsGroup, xn.Name) >= 0) AddGroup(xn, pwStorage.RootGroup, pwStorage); // 2.4.1.2 else if(Array.IndexOf(ElemsEntry, xn.Name) >= 0) AddEntry(xn, pwStorage.RootGroup, pwStorage); // 3.0.4 else if(Array.IndexOf(ElemsVault, xn.Name) >= 0) ImportVault(xn, pwStorage); // 3.0.5 } } private static void AddEntry(XmlNode xnEntry, PwGroup pg, PwDatabase pd) { PwEntry pe = new PwEntry(true, true); pg.AddEntry(pe, true); XmlNode xnTitle = xnEntry.Attributes.GetNamedItem(AttribCaption); string strTitle = ((xnTitle != null) ? xnTitle.Value : string.Empty); ImportUtil.AppendToField(pe, PwDefs.TitleField, strTitle ?? string.Empty, pd); foreach(XmlNode xn in xnEntry.ChildNodes) { if(Array.IndexOf(ElemsProps, xn.Name) >= 0) { XmlNode xnField = xn.Attributes.GetNamedItem(AttribCaption); string strField = ((xnField != null) ? xnField.Value : null); if(string.IsNullOrEmpty(strField)) { Debug.Assert(false); } else { string strMap = ImportUtil.MapNameToStandardField(strField, false); if(string.IsNullOrEmpty(strMap)) strMap = strField; ImportUtil.AppendToField(pe, strMap, XmlUtil.SafeInnerText(xn), pd); } } else { Debug.Assert(false); } // Unknown node } } private static void AddWebEntry(XmlNode xnEntry, PwGroup pg, PwDatabase pd) { PwEntry pe = new PwEntry(true, true); pg.AddEntry(pe, true); XmlNode xn = xnEntry.Attributes.GetNamedItem(AttribCaption); string str = ((xn != null) ? xn.Value : string.Empty); ImportUtil.AppendToField(pe, PwDefs.TitleField, str ?? string.Empty, pd); xn = xnEntry.Attributes.GetNamedItem(AttribWebUrl); str = ((xn != null) ? xn.Value : string.Empty); ImportUtil.AppendToField(pe, PwDefs.UrlField, str ?? string.Empty, pd); xn = xnEntry.Attributes.GetNamedItem(AttribWebUserName); str = ((xn != null) ? xn.Value : string.Empty); ImportUtil.AppendToField(pe, PwDefs.UserNameField, str ?? string.Empty, pd); xn = xnEntry.Attributes.GetNamedItem(AttribWebPassword); str = ((xn != null) ? xn.Value : string.Empty); ImportUtil.AppendToField(pe, PwDefs.PasswordField, str ?? string.Empty, pd); } private static void ImportVault(XmlNode xnVault, PwDatabase pd) { foreach(XmlNode xn in xnVault.ChildNodes) { if(Array.IndexOf(ElemsGroup, xn.Name) >= 0) AddGroup(xn, pd.RootGroup, pd); else if(Array.IndexOf(ElemsEntry, xn.Name) >= 0) AddEntry(xn, pd.RootGroup, pd); else { Debug.Assert(false); } // Unknown node } } private static void AddGroup(XmlNode xnGrp, PwGroup pgParent, PwDatabase pd) { XmlNode xnName = xnGrp.Attributes.GetNamedItem(AttribCaption); string strName = ((xnName != null) ? xnName.Value : null); if(string.IsNullOrEmpty(strName)) { Debug.Assert(false); strName = KPRes.Group; } PwGroup pg = new PwGroup(true, true); pg.Name = strName; pgParent.AddGroup(pg, true); foreach(XmlNode xn in xnGrp) { if(Array.IndexOf(ElemsGroup, xn.Name) >= 0) AddGroup(xn, pg, pd); else if(Array.IndexOf(ElemsEntry, xn.Name) >= 0) AddEntry(xn, pg, pd); else if(Array.IndexOf(ElemsWebEntry, xn.Name) >= 0) AddWebEntry(xn, pg, pd); else { Debug.Assert(false); } // Unknown node } } } } KeePass/DataExchange/Formats/PwExporterXml105.cs0000664000000000000000000001362013222430404020411 0ustar rootroot/* KeePass Password Safe - The Open-Source Password Manager Copyright (C) 2003-2018 Dominik Reichl This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ using System; using System.Collections.Generic; using System.Diagnostics; using System.Drawing; using System.IO; using System.Text; using System.Xml; using System.Xml.Serialization; using KeePass.Resources; using KeePassLib; using KeePassLib.Interfaces; using KeePassLib.Security; using KeePassLib.Utility; namespace KeePass.DataExchange.Formats { // 1.0.5-1.3.4+ internal sealed class PwExporterXml105 : FileFormatProvider { public override bool SupportsImport { get { return true; } } public override bool SupportsExport { get { return false; } } public override string FormatName { get { return "Password Exporter XML"; } } public override string DefaultExtension { get { return "xml"; } } public override string ApplicationGroup { get { return KPRes.Browser; } } public override bool ImportAppendsToRootGroupOnly { get { return true; } } public override Image SmallIcon { get { return KeePass.Properties.Resources.B16x16_HTML; } } private const string ElemRoot = "xml"; private const string ElemEntries = "entries"; private const string ElemEntry = "entry"; private const string AttrUser = "user"; private const string AttrPassword = "password"; private const string AttrURL = "host"; private const string AttrUserFieldName = "userFieldName"; private const string AttrPasswordFieldName = "passFieldName"; private const string DbUserFieldName = "FieldID_UserName"; private const string DbPasswordFieldName = "FieldID_Password"; public override void Import(PwDatabase pwStorage, Stream sInput, IStatusLogger slLogger) { StreamReader sr = new StreamReader(sInput, Encoding.Default); string strDoc = sr.ReadToEnd(); sr.Close(); // Fix '<' characters, for version 1.0.5 int nIndex = strDoc.IndexOf('<'); while(nIndex >= 0) { int nAttrib = strDoc.LastIndexOf("=\"", nIndex); int nElem = strDoc.LastIndexOf('>', nIndex); if(nAttrib > nElem) { strDoc = strDoc.Remove(nIndex, 1); strDoc = strDoc.Insert(nIndex, @"<"); } nIndex = strDoc.IndexOf('<', nIndex + 1); } // Fix '>' characters, for version 1.0.5 nIndex = strDoc.IndexOf('>'); while(nIndex >= 0) { char chPrev = strDoc[nIndex - 1]; string strPrev4 = strDoc.Substring(nIndex - 3, 4); if((chPrev != '/') && (chPrev != '\"') && (strPrev4 != @"xml>") && (strPrev4 != @"ies>")) { strDoc = strDoc.Remove(nIndex, 1); strDoc = strDoc.Insert(nIndex, @">"); } nIndex = strDoc.IndexOf('>', nIndex + 1); } MemoryStream ms = new MemoryStream(StrUtil.Utf8.GetBytes(strDoc), false); XmlDocument xmlDoc = new XmlDocument(); xmlDoc.Load(ms); ms.Close(); XmlNode xmlRoot = xmlDoc.DocumentElement; if(xmlRoot.Name != ElemRoot) throw new FormatException("Invalid root element!"); foreach(XmlNode xmlChild in xmlRoot.ChildNodes) { if(xmlChild.Name == ElemEntries) ImportEntries(xmlChild, pwStorage); else { Debug.Assert(false); } } } private static void ImportEntries(XmlNode xmlNode, PwDatabase pwStorage) { foreach(XmlNode xmlChild in xmlNode) { if(xmlChild.Name == ElemEntry) ImportEntry(xmlChild, pwStorage); else { Debug.Assert(false); } } } private static void ImportEntry(XmlNode xmlNode, PwDatabase pwStorage) { PwEntry pe = new PwEntry(true, true); pwStorage.RootGroup.AddEntry(pe, true); XmlAttributeCollection col = xmlNode.Attributes; if(col == null) return; XmlNode xmlAttrib; xmlAttrib = col.GetNamedItem(AttrUser); if(xmlAttrib != null) pe.Strings.Set(PwDefs.UserNameField, new ProtectedString( pwStorage.MemoryProtection.ProtectUserName, PctDecode(xmlAttrib.Value))); else { Debug.Assert(false); } xmlAttrib = col.GetNamedItem(AttrPassword); if(xmlAttrib != null) pe.Strings.Set(PwDefs.PasswordField, new ProtectedString( pwStorage.MemoryProtection.ProtectPassword, PctDecode(xmlAttrib.Value))); else { Debug.Assert(false); } xmlAttrib = col.GetNamedItem(AttrURL); if(xmlAttrib != null) pe.Strings.Set(PwDefs.UrlField, new ProtectedString( pwStorage.MemoryProtection.ProtectUrl, PctDecode(xmlAttrib.Value))); else { Debug.Assert(false); } xmlAttrib = col.GetNamedItem(AttrUserFieldName); if(xmlAttrib != null) pe.Strings.Set(DbUserFieldName, new ProtectedString( false, PctDecode(xmlAttrib.Value))); else { Debug.Assert(false); } xmlAttrib = col.GetNamedItem(AttrPasswordFieldName); if(xmlAttrib != null) pe.Strings.Set(DbPasswordFieldName, new ProtectedString( false, PctDecode(xmlAttrib.Value))); else { Debug.Assert(false); } } // For version 1.3.4 private static string PctDecode(string strText) { if(string.IsNullOrEmpty(strText)) return string.Empty; string str = strText; str = str.Replace("%3C", "<"); str = str.Replace("%3E", ">"); str = str.Replace("%22", "\""); str = str.Replace("%26", "&"); str = str.Replace("%25", "%"); // Must be last return str; } } } KeePass/DataExchange/Formats/XslTransform2x.cs0000664000000000000000000001001213222430406020271 0ustar rootroot/* KeePass Password Safe - The Open-Source Password Manager Copyright (C) 2003-2018 Dominik Reichl This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ using System; using System.Collections.Generic; using System.Text; using System.IO; using System.Xml; using System.Xml.Xsl; using System.Windows.Forms; using System.Diagnostics; using System.Drawing; using KeePass.App; using KeePass.Resources; using KeePass.UI; using KeePassLib; using KeePassLib.Interfaces; using KeePassLib.Serialization; using KeePassLib.Utility; namespace KeePass.DataExchange.Formats { internal sealed class XslTransform2x : FileFormatProvider { private const string ParamXslFile = "XslFile"; public override bool SupportsImport { get { return false; } } public override bool SupportsExport { get { return true; } } public override string FormatName { get { return KPRes.XslExporter; } } public override string ApplicationGroup { get { return KPRes.General; } } public override Image SmallIcon { get { return KeePass.Properties.Resources.B16x16_CompFile; } } public override bool Export(PwExportInfo pwExportInfo, Stream sOutput, IStatusLogger slLogger) { string strXslFile; pwExportInfo.Parameters.TryGetValue(ParamXslFile, out strXslFile); if(string.IsNullOrEmpty(strXslFile)) { strXslFile = UIGetXslFile(); if(string.IsNullOrEmpty(strXslFile)) return false; } return ExportEx(pwExportInfo, sOutput, slLogger, strXslFile); } private static string UIGetXslFile() { string strFilter = UIUtil.CreateFileTypeFilter("xsl", KPRes.XslFileType, true); OpenFileDialogEx dlgXsl = UIUtil.CreateOpenFileDialog(KPRes.XslSelectFile, strFilter, 1, "xsl", false, AppDefs.FileDialogContext.Xsl); if(dlgXsl.ShowDialog() != DialogResult.OK) return null; return dlgXsl.FileName; } private bool ExportEx(PwExportInfo pwExportInfo, Stream sOutput, IStatusLogger slLogger, string strXslFile) { XslCompiledTransform xsl = new XslCompiledTransform(); try { xsl.Load(strXslFile); } catch(Exception exXsl) { throw new NotSupportedException(strXslFile + MessageService.NewParagraph + KPRes.NoXslFile + MessageService.NewParagraph + exXsl.Message); } byte[] pbData; using(MemoryStream ms = new MemoryStream()) { PwDatabase pd = (pwExportInfo.ContextDatabase ?? new PwDatabase()); KdbxFile f = new KdbxFile(pd); f.Save(ms, pwExportInfo.DataGroup, KdbxFormat.PlainXml, slLogger); pbData = ms.ToArray(); } if(pbData == null) throw new OutOfMemoryException(); XmlWriterSettings xws = xsl.OutputSettings; if(xws == null) { xws = new XmlWriterSettings(); xws.CheckCharacters = false; xws.ConformanceLevel = ConformanceLevel.Auto; xws.Encoding = StrUtil.Utf8; // xws.Indent = false; xws.IndentChars = "\t"; xws.NewLineChars = MessageService.NewLine; xws.NewLineHandling = NewLineHandling.None; xws.OmitXmlDeclaration = true; } using(MemoryStream msIn = new MemoryStream(pbData, false)) { using(XmlReader xrIn = XmlReader.Create(msIn)) { using(XmlWriter xwOut = XmlWriter.Create(sOutput, xws)) { xsl.Transform(xrIn, xwOut); } } } MemUtil.ZeroByteArray(pbData); return true; } } } KeePass/DataExchange/Formats/PpKeeperHtml270.cs0000664000000000000000000001552713222430404020164 0ustar rootroot/* KeePass Password Safe - The Open-Source Password Manager Copyright (C) 2003-2018 Dominik Reichl This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ using System; using System.Collections.Generic; using System.Text; using System.Text.RegularExpressions; using System.Drawing; using System.IO; using System.Diagnostics; using KeePass.Resources; using KeePassLib; using KeePassLib.Interfaces; using KeePassLib.Security; using KeePassLib.Utility; namespace KeePass.DataExchange.Formats { // 2.50, 2.60 and 2.70 internal sealed class PpKeeperHtml270 : FileFormatProvider { public override bool SupportsImport { get { return true; } } public override bool SupportsExport { get { return false; } } public override string FormatName { get { return "Passphrase Keeper HTML"; } } public override string DefaultExtension { get { return @"html|htm"; } } public override string ApplicationGroup { get { return KPRes.PasswordManagers; } } public override bool ImportAppendsToRootGroupOnly { get { return true; } } public override Image SmallIcon { // Passphrase Keeper uses the same standard XP keys icon // as Whisper 32 get { return KeePass.Properties.Resources.B16x16_Imp_Whisper32; } } private const string m_strStartTd = ""; private const string m_strEndTd = @""; private const string m_strModifiedField = @"{0530D298-F983-454C-B5A3-BFB0775844D1}"; private const string m_strModifiedHdrStart = "Modified"; public override void Import(PwDatabase pwStorage, Stream sInput, IStatusLogger slLogger) { StreamReader sr = new StreamReader(sInput, Encoding.Default); string strData = sr.ReadToEnd(); sr.Close(); // Normalize 2.70 files strData = strData.Replace("", m_strStartTd); strData = strData.Replace("", m_strStartTd); strData = strData.Replace("", m_strStartTd); strData = strData.Replace("", m_strStartTd); strData = strData.Replace("", m_strStartTd); strData = strData.Replace("", m_strStartTd); // Additionally support old versions string[] vRepl = new string[5] { // 2.60 "", // 2.50 and 2.60 "", "", "", "" }; foreach(string strRepl in vRepl) { strData = Regex.Replace(strData, strRepl, m_strStartTd); } strData = strData.Replace("\r\n", m_strEndTd + "\r\n"); int nOffset = 0; PwEntry peHeader; if(!ReadEntry(out peHeader, strData, ref nOffset, pwStorage)) { Debug.Assert(false); return; } while((nOffset >= 0) && (nOffset < strData.Length)) { PwEntry pe; if(!ReadEntry(out pe, strData, ref nOffset, pwStorage)) { Debug.Assert(false); break; } if(pe == null) break; pwStorage.RootGroup.AddEntry(pe, true); } } private static bool ReadEntry(out PwEntry pe, string strData, ref int nOffset, PwDatabase pd) { pe = new PwEntry(true, true); if(!ReadString(strData, ref nOffset, m_strStartTd, m_strEndTd, pe, null, false)) { pe = null; return true; } if(!ReadString(strData, ref nOffset, m_strStartTd, m_strEndTd, pe, PwDefs.TitleField, pd.MemoryProtection.ProtectTitle)) return false; if(!ReadString(strData, ref nOffset, m_strStartTd, m_strEndTd, pe, PwDefs.UserNameField, pd.MemoryProtection.ProtectUserName)) return false; if(!ReadString(strData, ref nOffset, m_strStartTd, m_strEndTd, pe, PwDefs.PasswordField, pd.MemoryProtection.ProtectPassword)) return false; if(!ReadString(strData, ref nOffset, m_strStartTd, m_strEndTd, pe, PwDefs.UrlField, pd.MemoryProtection.ProtectUrl)) return false; if(!ReadString(strData, ref nOffset, m_strStartTd, m_strEndTd, pe, PwDefs.NotesField, pd.MemoryProtection.ProtectNotes)) return false; if(!ReadString(strData, ref nOffset, m_strStartTd, m_strEndTd, pe, m_strModifiedField, false)) return false; return true; } private static bool ReadString(string strData, ref int nOffset, string strStart, string strEnd, PwEntry pe, string strFieldName, bool bProtect) { nOffset = strData.IndexOf(strStart, nOffset); if(nOffset < 0) return false; string strRawValue = StrUtil.GetStringBetween(strData, nOffset, strStart, strEnd); string strValue = strRawValue.Trim(); if(strValue == @"
") strValue = string.Empty; strValue = strValue.Replace("\r", string.Empty); strValue = strValue.Replace("\n", string.Empty); strValue = strValue.Replace(@"
", MessageService.NewLine); if((strFieldName != null) && (strFieldName == m_strModifiedField)) { DateTime dt = ReadModified(strValue); pe.CreationTime = dt; pe.LastModificationTime = dt; } else if(strFieldName != null) pe.Strings.Set(strFieldName, new ProtectedString(bProtect, strValue)); nOffset += strStart.Length + strRawValue.Length + strEnd.Length; return true; } private static DateTime ReadModified(string strValue) { if(strValue == null) { Debug.Assert(false); return DateTime.UtcNow; } if(strValue.StartsWith(m_strModifiedHdrStart)) return DateTime.UtcNow; string[] vParts = strValue.Split(new char[] { ' ', ':', '/' }, StringSplitOptions.RemoveEmptyEntries); if(vParts.Length != 6) { Debug.Assert(false); return DateTime.UtcNow; } try { return (new DateTime(int.Parse(vParts[2]), int.Parse(vParts[0]), int.Parse(vParts[1]), int.Parse(vParts[3]), int.Parse(vParts[4]), int.Parse(vParts[5]), DateTimeKind.Local)).ToUniversalTime(); } catch(Exception) { Debug.Assert(false); } return DateTime.UtcNow; } } } KeePass/DataExchange/Formats/RoboFormHtml69.cs0000664000000000000000000001530213222430406020115 0ustar rootroot/* KeePass Password Safe - The Open-Source Password Manager Copyright (C) 2003-2018 Dominik Reichl This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ using System; using System.Collections.Generic; using System.Diagnostics; using System.Drawing; using System.IO; using System.Text; using System.Windows.Forms; using KeePass.Resources; using KeePass.UI; using KeePass.Util; using KeePassLib; using KeePassLib.Interfaces; using KeePassLib.Security; using KeePassLib.Utility; namespace KeePass.DataExchange.Formats { // 6.9.82-8.4.3.4+ internal sealed class RoboFormHtml69 : FileFormatProvider { public override bool SupportsImport { get { return true; } } public override bool SupportsExport { get { return false; } } public override string FormatName { get { return "RoboForm HTML (Logins/PassCards)"; } } public override string DefaultExtension { get { return @"html|htm"; } } public override string ApplicationGroup { get { return KPRes.PasswordManagers; } } public override Image SmallIcon { get { return KeePass.Properties.Resources.B16x16_Imp_RoboForm; } } public override void Import(PwDatabase pwStorage, Stream sInput, IStatusLogger slLogger) { StreamReader sr = new StreamReader(sInput, Encoding.Unicode, true); string strData = sr.ReadToEnd(); sr.Close(); strData = strData.Replace(@"", string.Empty); strData = strData.Replace(@"­", string.Empty); using(WebBrowser wb = new WebBrowser()) { wb.Visible = false; wb.ScriptErrorsSuppressed = true; UIUtil.SetWebBrowserDocument(wb, strData); ImportPriv(pwStorage, wb.Document.Body); } } private static string ParseTitle(string strTitle, PwDatabase pd, out PwGroup pg) { pg = pd.RootGroup; // In 7.9.5.9 '/' is used; in earlier versions '\\' char[] vSeps = new char[] { '/', '\\' }; int iLastSep = strTitle.LastIndexOfAny(vSeps); if(iLastSep >= 0) { string strTree = strTitle.Substring(0, iLastSep); pg = pd.RootGroup.FindCreateSubTree(strTree, vSeps, true); return strTitle.Substring(iLastSep + 1); } return strTitle; } private static string MapKey(string strKey) { string s = ImportUtil.MapNameToStandardField(strKey, true); if(string.IsNullOrEmpty(s)) return strKey; if((s == PwDefs.TitleField) || (s == PwDefs.UrlField)) return strKey; return s; } private static List GetElements(HtmlElement hRoot, string strTagName, string strAttribName, string strAttribValue) { List l = new List(); if(hRoot == null) { Debug.Assert(false); return l; } if(string.IsNullOrEmpty(strTagName)) { Debug.Assert(false); return l; } foreach(HtmlElement hEl in hRoot.GetElementsByTagName(strTagName)) { if(!string.IsNullOrEmpty(strAttribName) && (strAttribValue != null)) { string strValue = XmlUtil.SafeAttribute(hEl, strAttribName); if(!strValue.Equals(strAttribValue, StrUtil.CaseIgnoreCmp)) continue; } l.Add(hEl); } return l; } private static void ImportPriv(PwDatabase pd, HtmlElement hBody) { #if DEBUG bool bHasSpanCaptions = (GetElements(hBody, "SPAN", "class", "caption").Count > 0); #endif foreach(HtmlElement hTable in hBody.GetElementsByTagName("TABLE")) { Debug.Assert(XmlUtil.SafeAttribute(hTable, "width") == "100%"); string strRules = XmlUtil.SafeAttribute(hTable, "rules"); string strFrame = XmlUtil.SafeAttribute(hTable, "frame"); if(strRules.Equals("cols", StrUtil.CaseIgnoreCmp) && strFrame.Equals("void", StrUtil.CaseIgnoreCmp)) continue; PwEntry pe = new PwEntry(true, true); PwGroup pg = null; bool bNotesHeaderFound = false; foreach(HtmlElement hTr in hTable.GetElementsByTagName("TR")) { // 7.9.1.1+ List lCaption = GetElements(hTr, "SPAN", "class", "caption"); if(lCaption.Count == 0) lCaption = GetElements(hTr, "DIV", "class", "caption"); if(lCaption.Count > 0) { string strTitle = ParseTitle(XmlUtil.SafeInnerText( lCaption[0]), pd, out pg); ImportUtil.AppendToField(pe, PwDefs.TitleField, strTitle, pd); continue; // Data is in next TR } // 7.9.1.1+ if(hTr.GetElementsByTagName("TABLE").Count > 0) continue; HtmlElementCollection lTd = hTr.GetElementsByTagName("TD"); if(lTd.Count == 1) { HtmlElement e = lTd[0]; string strText = XmlUtil.SafeInnerText(e); string strClass = XmlUtil.SafeAttribute(e, "class"); if(strClass.Equals("caption", StrUtil.CaseIgnoreCmp)) { Debug.Assert(pg == null); strText = ParseTitle(strText, pd, out pg); ImportUtil.AppendToField(pe, PwDefs.TitleField, strText, pd); } else if(strClass.Equals("subcaption", StrUtil.CaseIgnoreCmp)) ImportUtil.AppendToField(pe, PwDefs.UrlField, ImportUtil.FixUrl(strText), pd); else if(strClass.Equals("field", StrUtil.CaseIgnoreCmp)) { // 7.9.2.5+ if(strText.EndsWith(":") && !bNotesHeaderFound) bNotesHeaderFound = true; else ImportUtil.AppendToField(pe, PwDefs.NotesField, strText.Trim(), pd, MessageService.NewLine, false); } else { Debug.Assert(false); } } else if((lTd.Count == 2) || (lTd.Count == 3)) { string strKey = XmlUtil.SafeInnerText(lTd[0]); string strValue = XmlUtil.SafeInnerText(lTd[lTd.Count - 1]); if(lTd.Count == 3) { Debug.Assert(string.IsNullOrEmpty(lTd[1].InnerText)); } if(strKey.EndsWith(":")) // 7.9.1.1+ strKey = strKey.Substring(0, strKey.Length - 1); if(strKey.Length > 0) ImportUtil.AppendToField(pe, MapKey(strKey), strValue, pd); else { Debug.Assert(false); } } else { Debug.Assert(false); } } if(pg != null) pg.AddEntry(pe, true); #if DEBUG else { Debug.Assert(bHasSpanCaptions); } #endif } } } } KeePass/DataExchange/Formats/HandySafeProXml12.cs0000664000000000000000000001037613222430404020537 0ustar rootroot/* KeePass Password Safe - The Open-Source Password Manager Copyright (C) 2003-2018 Dominik Reichl This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ using System; using System.Collections.Generic; using System.Text; using System.Drawing; using System.IO; using System.Diagnostics; using System.Xml.Serialization; using KeePass.Resources; using KeePassLib; using KeePassLib.Interfaces; using KeePassLib.Security; using KeePassLib.Utility; namespace KeePass.DataExchange.Formats { [XmlRoot("HandySafe")] public sealed class HspFolder { [XmlAttribute("name")] public string Name { get; set; } [XmlElement("Folder")] public HspFolder[] Folders { get; set; } [XmlElement("Card")] public HspCard[] Cards { get; set; } } public sealed class HspCard { [XmlAttribute("name")] public string Name { get; set; } [XmlElement("Field")] public HspField[] Fields { get; set; } public string Note { get; set; } } public sealed class HspField { [XmlAttribute("name")] public string Name { get; set; } [XmlText] public string Value { get; set; } } // 1.2 internal sealed class HandySafeProXml12 : FileFormatProvider { public override bool SupportsImport { get { return true; } } public override bool SupportsExport { get { return false; } } public override string FormatName { get { return "Handy Safe Pro XML"; } } public override string DefaultExtension { get { return "xml"; } } public override string ApplicationGroup { get { return KPRes.PasswordManagers; } } public override Image SmallIcon { get { return KeePass.Properties.Resources.B16x16_Imp_HandySafePro; } } public override void Import(PwDatabase pwStorage, Stream sInput, IStatusLogger slLogger) { XmlSerializer xs = new XmlSerializer(typeof(HspFolder)); HspFolder hspRoot = (HspFolder)xs.Deserialize(sInput); AddFolder(pwStorage.RootGroup, hspRoot, false); } private static void AddFolder(PwGroup pgParent, HspFolder hspFolder, bool bNewGroup) { if(hspFolder == null) { Debug.Assert(false); return; } PwGroup pg; if(bNewGroup) { pg = new PwGroup(true, true); pgParent.AddGroup(pg, true); if(!string.IsNullOrEmpty(hspFolder.Name)) pg.Name = hspFolder.Name; } else pg = pgParent; if(hspFolder.Folders != null) { foreach(HspFolder fld in hspFolder.Folders) AddFolder(pg, fld, true); } if(hspFolder.Cards != null) { foreach(HspCard crd in hspFolder.Cards) AddCard(pg, crd); } } private static void AddCard(PwGroup pgParent, HspCard hspCard) { if(hspCard == null) { Debug.Assert(false); return; } PwEntry pe = new PwEntry(true, true); pgParent.AddEntry(pe, true); if(!string.IsNullOrEmpty(hspCard.Name)) pe.Strings.Set(PwDefs.TitleField, new ProtectedString(false, hspCard.Name)); if(!string.IsNullOrEmpty(hspCard.Note)) pe.Strings.Set(PwDefs.NotesField, new ProtectedString(false, hspCard.Note)); if(hspCard.Fields == null) return; foreach(HspField fld in hspCard.Fields) { if(fld == null) { Debug.Assert(false); continue; } if(string.IsNullOrEmpty(fld.Name) || string.IsNullOrEmpty(fld.Value)) continue; string strKey = ImportUtil.MapNameToStandardField(fld.Name, true); if(string.IsNullOrEmpty(strKey)) strKey = fld.Name; string strValue = pe.Strings.ReadSafe(strKey); if(strValue.Length > 0) strValue += ", "; strValue += fld.Value; pe.Strings.Set(strKey, new ProtectedString(false, strValue)); } } } } KeePass/DataExchange/Formats/AmpXml250.cs0000664000000000000000000001531613222430404017014 0ustar rootroot/* KeePass Password Safe - The Open-Source Password Manager Copyright (C) 2003-2018 Dominik Reichl This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ using System; using System.Collections.Generic; using System.Diagnostics; using System.Drawing; using System.IO; using System.Text; using System.Xml; using KeePass.Resources; using KeePass.Util; using KeePassLib; using KeePassLib.Interfaces; using KeePassLib.Security; using KeePassLib.Utility; namespace KeePass.DataExchange.Formats { // 2.50-3.21+ internal sealed class AmpXml250 : FileFormatProvider { private const string ElemRoot = "AmP_FILE"; private const string ElemInfo = "INFO"; private const string ElemData = "DATA"; private const string ElemCategory = "Kategorie"; private const string ElemTitle = "Bezeichnung"; private const string ElemUserName = "Benutzername"; private const string ElemPassword1 = "Passwort1"; private const string ElemPassword2 = "Passwort2"; private const string ElemExpiry = "Ablaufdatum"; private const string ElemUrl = "URL_Programm"; private const string ElemNotes = "Kommentar"; private const string ElemCustom = "Benutzerdefinierte_Felder"; private const string ElemCustomName = "name"; private const string ElemCustomValue = "wert"; private const string ValueNoData = "n/a"; private const string ValueNone = "keins"; private const string ValueNever = "nie"; public override bool SupportsImport { get { return true; } } public override bool SupportsExport { get { return false; } } public override string FormatName { get { return "Alle meine Passworte XML"; } } public override string DefaultExtension { get { return "xml"; } } public override string ApplicationGroup { get { return KPRes.PasswordManagers; } } public override Image SmallIcon { get { return Properties.Resources.B16x16_Imp_AmP; } } public override void Import(PwDatabase pwStorage, Stream sInput, IStatusLogger slLogger) { StreamReader sr = new StreamReader(sInput, Encoding.Default); string strDoc = sr.ReadToEnd(); sr.Close(); strDoc = XmlUtil.DecodeHtmlEntities(strDoc); ImportFileString(strDoc, pwStorage, slLogger); } private static void ImportFileString(string strXmlDoc, PwDatabase pwStorage, IStatusLogger slLogger) { XmlDocument doc = new XmlDocument(); doc.LoadXml(strXmlDoc); XmlElement xmlRoot = doc.DocumentElement; Debug.Assert(xmlRoot.Name == ElemRoot); foreach(XmlNode xmlChild in xmlRoot.ChildNodes) { if(xmlChild.Name == ElemData) LoadDataNode(xmlChild, pwStorage, slLogger); else if(xmlChild.Name == ElemInfo) { } else { Debug.Assert(false); } } } private static void LoadDataNode(XmlNode xmlNode, PwDatabase pwStorage, IStatusLogger slLogger) { uint uCat = 0, uCount = (uint)xmlNode.ChildNodes.Count; foreach(XmlNode xmlCategory in xmlNode.ChildNodes) { LoadCategoryNode(xmlCategory, pwStorage); ++uCat; ImportUtil.SetStatus(slLogger, (uCat * 100) / uCount); } } private static void LoadCategoryNode(XmlNode xmlNode, PwDatabase pwStorage) { PwGroup pg = new PwGroup(true, true, xmlNode.Name, PwIcon.Folder); pwStorage.RootGroup.AddGroup(pg, true); PwEntry pe = new PwEntry(true, true); foreach(XmlNode xmlChild in xmlNode) { string strInner = XmlUtil.SafeInnerText(xmlChild); if(strInner == ValueNoData) strInner = string.Empty; if(xmlChild.Name == ElemCategory) { // strInner may contain special characters, thus // update the group name now pg.Name = strInner; } else if(xmlChild.Name == ElemTitle) { AddEntryIfValid(pg, ref pe); Debug.Assert(strInner.Length > 0); pe.Strings.Set(PwDefs.TitleField, new ProtectedString( pwStorage.MemoryProtection.ProtectTitle, strInner)); } else if(xmlChild.Name == ElemUserName) pe.Strings.Set(PwDefs.UserNameField, new ProtectedString( pwStorage.MemoryProtection.ProtectUserName, strInner)); else if(xmlChild.Name == ElemPassword1) pe.Strings.Set(PwDefs.PasswordField, new ProtectedString( pwStorage.MemoryProtection.ProtectPassword, strInner)); else if(xmlChild.Name == ElemPassword2) { if((strInner.Length > 0) && (strInner != ValueNone)) pe.Strings.Set(PwDefs.PasswordField + @" 2", new ProtectedString( pwStorage.MemoryProtection.ProtectPassword, strInner)); } else if(xmlChild.Name == ElemExpiry) { if((strInner.Length > 0) && (strInner != ValueNever)) { try { DateTime dt = DateTime.Parse(strInner); pe.ExpiryTime = TimeUtil.ToUtc(dt, false); pe.Expires = true; } catch(Exception) { Debug.Assert(false); } } } else if(xmlChild.Name == ElemUrl) pe.Strings.Set(PwDefs.UrlField, new ProtectedString( pwStorage.MemoryProtection.ProtectUrl, strInner)); else if(xmlChild.Name == ElemNotes) pe.Strings.Set(PwDefs.NotesField, new ProtectedString( pwStorage.MemoryProtection.ProtectNotes, strInner)); else if(xmlChild.Name == ElemCustom) LoadCustomFields(xmlChild, pe, pwStorage); else { Debug.Assert(false); } } AddEntryIfValid(pg, ref pe); } private static void AddEntryIfValid(PwGroup pgContainer, ref PwEntry pe) { try { if(pe == null) return; if(pe.Strings.ReadSafe(PwDefs.TitleField).Length == 0) return; pgContainer.AddEntry(pe, true); } finally { pe = new PwEntry(true, true); } } private static void LoadCustomFields(XmlNode xmlNode, PwEntry pe, PwDatabase pwStorage) { string strKey = string.Empty; foreach(XmlNode xn in xmlNode.ChildNodes) { if(xn.Name == ElemCustomName) strKey = XmlUtil.SafeInnerText(xn); else if(xn.Name == ElemCustomValue) { if(strKey.Length == 0) { Debug.Assert(false); continue; } ImportUtil.AppendToField(pe, strKey, XmlUtil.SafeInnerText(xn), pwStorage); } } } } } KeePass/DataExchange/FileFormatPool.cs0000664000000000000000000001467013222430404016640 0ustar rootroot/* KeePass Password Safe - The Open-Source Password Manager Copyright (C) 2003-2018 Dominik Reichl This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ using System; using System.Collections; using System.Collections.Generic; using System.Diagnostics; using System.Text; using KeePass.DataExchange.Formats; using KeePassLib.Utility; namespace KeePass.DataExchange { public sealed class FileFormatPool : IEnumerable { private List m_vFormats = null; public IEnumerable Importers { get { EnsurePoolInitialized(); List v = new List(); foreach(FileFormatProvider prov in m_vFormats) { if(prov.SupportsImport) v.Add(prov); } return v; } } public IEnumerable Exporters { get { EnsurePoolInitialized(); List v = new List(); foreach(FileFormatProvider prov in m_vFormats) { if(prov.SupportsExport) v.Add(prov); } return v; } } public int Count { get { EnsurePoolInitialized(); return m_vFormats.Count; } } public FileFormatPool() { } IEnumerator IEnumerable.GetEnumerator() { EnsurePoolInitialized(); return m_vFormats.GetEnumerator(); } public IEnumerator GetEnumerator() { EnsurePoolInitialized(); return m_vFormats.GetEnumerator(); } private void EnsurePoolInitialized() { if(m_vFormats != null) return; InitializePool(); } private void InitializePool() { Debug.Assert(m_vFormats == null); m_vFormats = new List(); m_vFormats.Add(new KeePassCsv1x()); m_vFormats.Add(new KeePassKdb1x()); m_vFormats.Add(new KeePassKdb2x()); m_vFormats.Add(new KeePassKdb2xRepair()); m_vFormats.Add(new KeePassKdb2x3()); m_vFormats.Add(new KeePassXml1x()); m_vFormats.Add(new KeePassXml2x()); m_vFormats.Add(new GenericCsv()); m_vFormats.Add(new KeePassHtml2x()); m_vFormats.Add(new XslTransform2x()); m_vFormats.Add(new WinFavorites10(false)); m_vFormats.Add(new WinFavorites10(true)); m_vFormats.Add(new OnePwProCsv599()); m_vFormats.Add(new AmpXml250()); m_vFormats.Add(new AnyPwCsv144()); m_vFormats.Add(new CodeWalletTxt605()); m_vFormats.Add(new DashlaneCsv2()); m_vFormats.Add(new DataVaultCsv47()); m_vFormats.Add(new DesktopKnoxXml32()); m_vFormats.Add(new EnpassTxt5()); m_vFormats.Add(new FlexWalletXml17()); m_vFormats.Add(new HandySafeTxt512()); m_vFormats.Add(new HandySafeProXml12()); m_vFormats.Add(new KasperskyPwMgrXml50()); m_vFormats.Add(new KeePassXXml041()); m_vFormats.Add(new LastPassCsv2()); m_vFormats.Add(new MSecureCsv355()); m_vFormats.Add(new NetworkPwMgrCsv4()); m_vFormats.Add(new NortonIdSafeCsv2013()); m_vFormats.Add(new NPasswordNpw102()); m_vFormats.Add(new PassKeeper12()); m_vFormats.Add(new PpKeeperHtml270()); m_vFormats.Add(new PwAgentXml234()); m_vFormats.Add(new PwDepotXml26()); m_vFormats.Add(new PwKeeperCsv70()); m_vFormats.Add(new PwMemory2008Xml104()); m_vFormats.Add(new PwPrompterDat12()); m_vFormats.Add(new PwSafeXml302()); m_vFormats.Add(new PwSaverXml412()); m_vFormats.Add(new PwsPlusCsv1007()); m_vFormats.Add(new PwTresorXml100()); m_vFormats.Add(new PVaultTxt14()); m_vFormats.Add(new PinsTxt450()); m_vFormats.Add(new RevelationXml04()); m_vFormats.Add(new RoboFormHtml69()); m_vFormats.Add(new SafeWalletXml3()); m_vFormats.Add(new SecurityTxt12()); m_vFormats.Add(new SplashIdCsv402()); m_vFormats.Add(new SteganosPwManager2007()); m_vFormats.Add(new StickyPwXml50()); m_vFormats.Add(new TurboPwsCsv5()); m_vFormats.Add(new VisKeeperTxt3()); m_vFormats.Add(new Whisper32Csv116()); m_vFormats.Add(new ZdnPwProTxt314()); m_vFormats.Add(new MozillaBookmarksHtml100()); m_vFormats.Add(new MozillaBookmarksJson100()); m_vFormats.Add(new PwExporterXml105()); m_vFormats.Add(new Spamex20070328()); #if DEBUG // Ensure name uniqueness for(int i = 0; i < m_vFormats.Count; ++i) { FileFormatProvider pi = m_vFormats[i]; for(int j = i + 1; j < m_vFormats.Count; ++j) { FileFormatProvider pj = m_vFormats[j]; Debug.Assert(!string.Equals(pi.FormatName, pj.FormatName, StrUtil.CaseIgnoreCmp)); Debug.Assert(!string.Equals(pi.FormatName, pj.DisplayName, StrUtil.CaseIgnoreCmp)); Debug.Assert(!string.Equals(pi.DisplayName, pj.FormatName, StrUtil.CaseIgnoreCmp)); Debug.Assert(!string.Equals(pi.DisplayName, pj.DisplayName, StrUtil.CaseIgnoreCmp)); } } #endif } public void Add(FileFormatProvider prov) { Debug.Assert(prov != null); if(prov == null) throw new ArgumentNullException("prov"); EnsurePoolInitialized(); m_vFormats.Add(prov); } public bool Remove(FileFormatProvider prov) { Debug.Assert(prov != null); if(prov == null) throw new ArgumentNullException("prov"); EnsurePoolInitialized(); return m_vFormats.Remove(prov); } public FileFormatProvider Find(string strFormatName) { if(strFormatName == null) return null; EnsurePoolInitialized(); // Format and display names may differ (e.g. the Generic // CSV Importer has a different format name) foreach(FileFormatProvider f in m_vFormats) { if(string.Equals(strFormatName, f.DisplayName, StrUtil.CaseIgnoreCmp)) return f; } foreach(FileFormatProvider f in m_vFormats) { if(string.Equals(strFormatName, f.FormatName, StrUtil.CaseIgnoreCmp)) return f; } return null; } } } KeePass/DataExchange/ExportUtil.cs0000664000000000000000000001050013222430404016061 0ustar rootroot/* KeePass Password Safe - The Open-Source Password Manager Copyright (C) 2003-2018 Dominik Reichl This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ using System; using System.Collections.Generic; using System.Text; using System.Windows.Forms; using System.Diagnostics; using System.IO; using KeePass.App; using KeePass.Forms; using KeePass.UI; using KeePassLib; using KeePassLib.Interfaces; using KeePassLib.Serialization; using KeePassLib.Utility; namespace KeePass.DataExchange { public static class ExportUtil { public static bool Export(PwExportInfo pwExportInfo, IStatusLogger slLogger) { if(pwExportInfo == null) throw new ArgumentNullException("pwExportInfo"); if(pwExportInfo.DataGroup == null) throw new ArgumentException(); if(!AppPolicy.Try(AppPolicyId.Export)) return false; ExchangeDataForm dlg = new ExchangeDataForm(); dlg.InitEx(true, pwExportInfo.ContextDatabase, pwExportInfo.DataGroup); bool bResult = false; if(dlg.ShowDialog() == DialogResult.OK) { FileFormatProvider ffp = dlg.ResultFormat; if(ffp == null) { Debug.Assert(false); goto ExpZRet; } if(ffp.RequiresFile) { if(dlg.ResultFiles.Length != 1) { Debug.Assert(false); goto ExpZRet; } if(dlg.ResultFiles[0] == null) { Debug.Assert(false); goto ExpZRet; } if(dlg.ResultFiles[0].Length == 0) { Debug.Assert(false); goto ExpZRet; } } Application.DoEvents(); // Redraw parent window IOConnectionInfo iocOutput = (ffp.RequiresFile ? IOConnectionInfo.FromPath( dlg.ResultFiles[0]) : null); try { bResult = Export(pwExportInfo, dlg.ResultFormat, iocOutput, slLogger); } catch(Exception ex) { MessageService.ShowWarning(ex); } } ExpZRet: UIUtil.DestroyForm(dlg); return bResult; } public static bool Export(PwExportInfo pwExportInfo, string strFormatName, IOConnectionInfo iocOutput) { if(strFormatName == null) throw new ArgumentNullException("strFormatName"); // iocOutput may be null FileFormatProvider prov = Program.FileFormatPool.Find(strFormatName); if(prov == null) return false; NullStatusLogger slLogger = new NullStatusLogger(); return Export(pwExportInfo, prov, iocOutput, slLogger); } public static bool Export(PwExportInfo pwExportInfo, FileFormatProvider fileFormat, IOConnectionInfo iocOutput, IStatusLogger slLogger) { if(pwExportInfo == null) throw new ArgumentNullException("pwExportInfo"); if(pwExportInfo.DataGroup == null) throw new ArgumentException(); if(fileFormat == null) throw new ArgumentNullException("fileFormat"); if(fileFormat.RequiresFile && (iocOutput == null)) throw new ArgumentNullException("iocOutput"); if(!AppPolicy.Try(AppPolicyId.Export)) return false; if(!fileFormat.SupportsExport) return false; if(!fileFormat.TryBeginExport()) return false; // bool bExistedAlready = File.Exists(strOutputFile); bool bExistedAlready = (fileFormat.RequiresFile ? IOConnection.FileExists( iocOutput) : false); // FileStream fsOut = new FileStream(strOutputFile, FileMode.Create, // FileAccess.Write, FileShare.None); Stream sOut = (fileFormat.RequiresFile ? IOConnection.OpenWrite( iocOutput) : null); bool bResult = false; try { bResult = fileFormat.Export(pwExportInfo, sOut, slLogger); } catch(Exception ex) { MessageService.ShowWarning(ex); } if(sOut != null) sOut.Close(); if(fileFormat.RequiresFile && (bResult == false) && (bExistedAlready == false)) { try { IOConnection.DeleteFile(iocOutput); } catch(Exception) { } } return bResult; } } } KeePass/DataExchange/FileFormatProvider.cs0000664000000000000000000001227013222430404017513 0ustar rootroot/* KeePass Password Safe - The Open-Source Password Manager Copyright (C) 2003-2018 Dominik Reichl This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ using System; using System.Collections.Generic; using System.IO; using System.Drawing; using KeePass.Resources; using KeePassLib; using KeePassLib.Interfaces; namespace KeePass.DataExchange { public abstract class FileFormatProvider { public abstract bool SupportsImport { get; } public abstract bool SupportsExport { get; } public abstract string FormatName { get; } public virtual string DisplayName { get { return this.FormatName; } } ///

/// Default file name extension, without leading dot. /// If there are multiple default/equivalent extensions /// (like e.g. "html" and "htm"), specify all of them /// separated by a '|' (e.g. "html|htm"). /// public virtual string DefaultExtension { get { return string.Empty; } } /// /// Type of the original application using this format (like /// password manager / KPRes.PasswordManagers, /// web site / KPRes.WebSites, /// browser / KPRes.Browser, etc. /// public virtual string ApplicationGroup { get { return KPRes.General; } } public virtual Image SmallIcon { get { return KeePass.Properties.Resources.B16x16_Folder_Inbox; } } public virtual bool RequiresFile { get { return true; } } public virtual bool SupportsUuids { get { return false; } } public virtual bool RequiresKey { get { return false; } } /// /// This property specifies if entries are only appended to the /// end of the root group. This is true for example if the /// file format doesn't support groups (i.e. no hierarchy). /// public virtual bool ImportAppendsToRootGroupOnly { get { return false; } } /// /// If the importer is implemented as a profile for the generic /// XML importer, return the profile using this property (in /// this case the Import method must not be overridden!). /// internal virtual GxiProfile XmlProfile { get { return null; } } /// /// Called before the Import method is invoked. /// /// Returns true, if the Import method /// can be invoked. If it returns false, something has /// failed and the import process should be aborted. public virtual bool TryBeginImport() { return true; } /// /// Called before the Export method is invoked. /// /// Returns true, if the Export method /// can be invoked. If it returns false, something has /// failed and the export process should be aborted. public virtual bool TryBeginExport() { return true; } /// /// Import a stream into a database. Throws an exception if an error /// occurs. Do not call the base class method when overriding it. /// /// Data storage into which the data will be imported. /// Input stream to read the data from. /// Status logger. May be null. public virtual void Import(PwDatabase pwStorage, Stream sInput, IStatusLogger slLogger) { GxiProfile p = this.XmlProfile; if(p != null) { if(pwStorage == null) throw new ArgumentNullException("pwStorage"); GxiImporter.Import(pwStorage.RootGroup, sInput, p, pwStorage, slLogger); return; } throw new NotSupportedException(); } /// /// Export data into a stream. Throws an exception if an error /// occurs (like writing to stream fails, etc.). Returns true, /// if the export was successful. /// /// Contains the data source and detailed /// information about which entries should be exported. /// Output stream to write the data to. /// Status logger. May be null. /// Returns false, if the user has aborted the export /// process (like clicking Cancel in an additional export settings /// dialog). public virtual bool Export(PwExportInfo pwExportInfo, Stream sOutput, IStatusLogger slLogger) { throw new NotSupportedException(); } } } KeePass/Plugins/0000775000000000000000000000000013222430412012523 5ustar rootrootKeePass/Plugins/PlgxCsprojLoader.cs0000664000000000000000000001305513222430412016300 0ustar rootroot/* KeePass Password Safe - The Open-Source Password Manager Copyright (C) 2003-2018 Dominik Reichl This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ using System; using System.Collections.Generic; using System.Text; using System.Xml; using System.CodeDom.Compiler; using System.Diagnostics; using System.IO; using KeePass.Resources; using KeePassLib; using KeePassLib.Resources; using KeePassLib.Utility; namespace KeePass.Plugins { public static class PlgxCsprojLoader { private const string XnnProject = "Project"; private const string XnnPropertyGroup = "PropertyGroup"; private const string XnnItemGroup = "ItemGroup"; private const string XnnAssemblyName = "AssemblyName"; private const string XnnEmbeddedRes = "EmbeddedResource"; private const string XnnInclude = "Include"; private const string XnnReference = "Reference"; private const string XnnCompile = "Compile"; private const string XnnHintPath = "HintPath"; private const string XnnImport = "Import"; public static void LoadDefault(string strDirPath, PlgxPluginInfo plgxOutInfo) { if(plgxOutInfo == null) throw new ArgumentNullException("plgxOutInfo"); List lCsproj = UrlUtil.GetFilePaths(strDirPath, "*.csproj", SearchOption.AllDirectories); if(lCsproj.Count == 1) { plgxOutInfo.ProjectType = PlgxProjectType.CSharp; PlgxCsprojLoader.Load(lCsproj[0], plgxOutInfo); return; } // List lVbproj = UrlUtil.GetFilePaths(strDirPath, "*.vbproj", // SearchOption.AllDirectories); // if(lVbproj.Count == 1) // { // plgxOutInfo.ProjectType = PlgxProjectType.VisualBasic; // PlgxCsprojLoader.Load(lVbproj[0], plgxOutInfo); // return; // } throw new InvalidOperationException(KPRes.CsprojCountError); } private static void Load(string strFilePath, PlgxPluginInfo plgxOutInfo) { if(strFilePath == null) throw new ArgumentNullException("strFilePath"); plgxOutInfo.CsprojFilePath = strFilePath; XmlDocument doc = new XmlDocument(); doc.Load(strFilePath); ReadProject(doc.DocumentElement, plgxOutInfo); } private static void ReadProject(XmlNode xn, PlgxPluginInfo plgx) { if(xn.Name != XnnProject) throw new Exception(KLRes.FileCorrupted); foreach(XmlNode xnChild in xn.ChildNodes) { if(xnChild.Name == XnnPropertyGroup) ReadPropertyGroup(xnChild, plgx); else if(xnChild.Name == XnnItemGroup) ReadItemGroup(xnChild, plgx); } } private static void ReadPropertyGroup(XmlNode xn, PlgxPluginInfo plgx) { foreach(XmlNode xnChild in xn.ChildNodes) { if(xnChild.Name == XnnAssemblyName) plgx.BaseFileName = xnChild.InnerText; } } private static void ReadItemGroup(XmlNode xn, PlgxPluginInfo plgx) { foreach(XmlNode xnChild in xn.ChildNodes) { if(xnChild.Name == XnnEmbeddedRes) ReadEmbeddedRes(xnChild, plgx); else if(xnChild.Name == XnnReference) ReadReference(xnChild, plgx); else if(xnChild.Name == XnnCompile) ReadCompile(xnChild, plgx); else if(xnChild.Name == XnnImport) ReadImport(xnChild, plgx); } } private static void ReadEmbeddedRes(XmlNode xn, PlgxPluginInfo plgx) { XmlNode xnInc = xn.Attributes.GetNamedItem(XnnInclude); if((xnInc == null) || string.IsNullOrEmpty(xnInc.Value)) { Debug.Assert(false); return; } string strResSrc = plgx.GetAbsPath(xnInc.Value); // Converts separators plgx.EmbeddedResourceSources.Add(strResSrc); } private static void ReadReference(XmlNode xn, PlgxPluginInfo plgx) { XmlNode xnInc = xn.Attributes.GetNamedItem(XnnInclude); if((xnInc == null) || string.IsNullOrEmpty(xnInc.Value)) { Debug.Assert(false); return; } string str = xnInc.Value; if(UrlUtil.AssemblyEquals(str, PwDefs.ShortProductName)) return; // Ignore KeePass references foreach(XmlNode xnSub in xn.ChildNodes) { if(xnSub.Name == XnnHintPath) { plgx.IncludedReferencedAssemblies.Add( UrlUtil.ConvertSeparators(xnSub.InnerText, '/')); return; } } if(!str.EndsWith(".dll", StrUtil.CaseIgnoreCmp)) str += ".dll"; plgx.CompilerParameters.ReferencedAssemblies.Add(str); } private static void ReadCompile(XmlNode xn, PlgxPluginInfo plgx) { XmlNode xnInc = xn.Attributes.GetNamedItem(XnnInclude); if((xnInc == null) || string.IsNullOrEmpty(xnInc.Value)) { Debug.Assert(false); return; } plgx.SourceFiles.Add(plgx.GetAbsPath(xnInc.Value)); // Converts separators } private static void ReadImport(XmlNode xn, PlgxPluginInfo plgx) { if(plgx.ProjectType != PlgxProjectType.VisualBasic) { Debug.Assert(false); return; } XmlNode xnInc = xn.Attributes.GetNamedItem(XnnInclude); if((xnInc == null) || string.IsNullOrEmpty(xnInc.Value)) { Debug.Assert(false); return; } plgx.VbImports.Add(UrlUtil.ConvertSeparators(xnInc.Value)); } } } KeePass/Plugins/PluginInfo.cs0000664000000000000000000000566513222430412015140 0ustar rootroot/* KeePass Password Safe - The Open-Source Password Manager Copyright (C) 2003-2018 Dominik Reichl This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ using System; using System.Collections.Generic; using System.Text; using System.IO; using System.Diagnostics; using KeePass.App; using KeePassLib; using KeePassLib.Utility; namespace KeePass.Plugins { internal sealed class PluginInfo { private readonly string m_strFilePath; private readonly string m_strDisplayFilePath; // May be null private Plugin m_pluginInterface = null; private readonly string m_strFileVersion; private readonly string m_strName; private readonly string m_strDescription; private readonly string m_strAuthor; public string FilePath { get { return m_strFilePath; } } public string DisplayFilePath { get { return (m_strDisplayFilePath ?? m_strFilePath); } } public Plugin Interface { get { return m_pluginInterface; } set { m_pluginInterface = value; } } public string FileVersion { get { return m_strFileVersion; } } public string Name { get { return m_strName; } } public string Description { get { return m_strDescription; } } public string Author { get { return m_strAuthor; } } public PluginInfo(string strFilePath, FileVersionInfo fvi, string strDisplayFilePath) { Debug.Assert(strFilePath != null); if(strFilePath == null) throw new ArgumentNullException("strFilePath"); Debug.Assert(fvi != null); if(fvi == null) throw new ArgumentNullException("fvi"); // strDisplayFilePath may be null m_strFilePath = strFilePath; m_strDisplayFilePath = strDisplayFilePath; m_strFileVersion = (fvi.FileVersion ?? string.Empty).Trim(); string strName = (fvi.FileDescription ?? string.Empty).Trim(); m_strDescription = (fvi.Comments ?? string.Empty).Trim(); m_strAuthor = (fvi.CompanyName ?? string.Empty).Trim(); // Workaround for Mono not storing the AssemblyTitle in // the file version information block when compiling an // assembly (PLGX plugin) if(strName.Length == 0) strName = UrlUtil.StripExtension(UrlUtil.GetFileName( strFilePath)); m_strName = strName; } } } KeePass/Plugins/PlgxPlugin.cs0000664000000000000000000006177113222430412015157 0ustar rootroot/* KeePass Password Safe - The Open-Source Password Manager Copyright (C) 2003-2018 Dominik Reichl This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ using System; using System.Collections; using System.Collections.Generic; using System.Text; using System.IO; using System.IO.Compression; using System.Diagnostics; using System.Windows.Forms; using System.CodeDom; using System.CodeDom.Compiler; using System.Resources; using System.Security.Cryptography; using Microsoft.CSharp; // using Microsoft.VisualBasic; using KeePass.App; using KeePass.Forms; using KeePass.Resources; using KeePass.UI; using KeePass.Util; using KeePass.Util.Spr; using KeePassLib; using KeePassLib.Interfaces; using KeePassLib.Native; using KeePassLib.Resources; using KeePassLib.Utility; namespace KeePass.Plugins { public sealed class PlgxException : Exception { private string m_strMsg; public override string Message { get { return m_strMsg; } } public PlgxException(string strMessage) { if(strMessage == null) throw new ArgumentNullException("strMessage"); m_strMsg = strMessage; } } public static class PlgxPlugin { public const string PlgxExtension = "plgx"; private const uint PlgxSignature1 = 0x65D90719; private const uint PlgxSignature2 = 0x3DDD0503; private const uint PlgxVersion = 0x00010000; private const uint PlgxVersionMask = 0xFFFF0000; private const ushort PlgxEOF = 0; private const ushort PlgxFileUuid = 1; private const ushort PlgxBaseFileName = 2; private const ushort PlgxBeginContent = 3; private const ushort PlgxFile = 4; private const ushort PlgxEndContent = 5; private const ushort PlgxCreationTime = 6; private const ushort PlgxGeneratorName = 7; private const ushort PlgxGeneratorVersion = 8; private const ushort PlgxPrereqKP = 9; // KeePass version private const ushort PlgxPrereqNet = 10; // .NET Framework version private const ushort PlgxPrereqOS = 11; // Operating system private const ushort PlgxPrereqPtr = 12; // Pointer size private const ushort PlgxBuildPre = 13; private const ushort PlgxBuildPost = 14; private const ushort PlgxfEOF = 0; private const ushort PlgxfPath = 1; private const ushort PlgxfData = 2; public static void Load(string strFilePath, IStatusLogger slStatus) { try { LoadPriv(strFilePath, slStatus, true, true, true, null); } catch(PlgxException exPlgx) { MessageService.ShowWarning(strFilePath + MessageService.NewParagraph + KPRes.PluginLoadFailed + MessageService.NewParagraph + exPlgx.Message); } catch(Exception exLoad) { PluginManager.ShowLoadError(strFilePath, exLoad, slStatus); } } public static void CreateInfoFile(string strPlgxPath) { FileStream fsOut = null; TextWriter twLog = null; try { fsOut = new FileStream(strPlgxPath + ".txt", FileMode.Create, FileAccess.Write, FileShare.None); twLog = new StreamWriter(fsOut, new UTF8Encoding(false)); NullStatusLogger sl = new NullStatusLogger(); LoadPriv(strPlgxPath, sl, false, false, false, twLog); } catch(Exception ex) { MessageService.ShowWarning(strPlgxPath, ex); } finally { if(twLog != null) twLog.Close(); if(fsOut != null) fsOut.Close(); } } private static void LoadPriv(string strFilePath, IStatusLogger slStatus, bool bAllowCached, bool bAllowCompile, bool bAllowLoad, TextWriter twLog) { if(strFilePath == null) { Debug.Assert(false); return; } FileInfo fi = new FileInfo(strFilePath); if(fi.Length < 12) return; // Ignore file, don't throw FileStream fs = new FileStream(strFilePath, FileMode.Open, FileAccess.Read, FileShare.Read); BinaryReader br = new BinaryReader(fs); PlgxPluginInfo plgx = new PlgxPluginInfo(true, bAllowCached, bAllowCompile); plgx.LogStream = twLog; string strPluginPath = null; try { strPluginPath = ReadFile(br, plgx, slStatus); } finally { br.Close(); fs.Close(); } if(!string.IsNullOrEmpty(strPluginPath) && bAllowLoad) Program.MainForm.PluginManager.LoadPlugin(strPluginPath, plgx.BaseFileName, strFilePath, false); } private static string ReadFile(BinaryReader br, PlgxPluginInfo plgx, IStatusLogger slStatus) { uint uSig1 = br.ReadUInt32(); uint uSig2 = br.ReadUInt32(); uint uVersion = br.ReadUInt32(); if((uSig1 != PlgxSignature1) || (uSig2 != PlgxSignature2)) return null; // Ignore file, don't throw if((uVersion & PlgxVersionMask) > (PlgxVersion & PlgxVersionMask)) throw new PlgxException(KLRes.FileVersionUnsupported); string strPluginPath = null; string strTmpRoot = null; bool? bContent = null; string strBuildPre = null, strBuildPost = null; while(true) { KeyValuePair kvp = ReadObject(br); if(kvp.Key == PlgxEOF) break; else if(kvp.Key == PlgxFileUuid) plgx.FileUuid = new PwUuid(kvp.Value); else if(kvp.Key == PlgxBaseFileName) plgx.BaseFileName = StrUtil.Utf8.GetString(kvp.Value); else if(kvp.Key == PlgxCreationTime) { } // Ignore else if(kvp.Key == PlgxGeneratorName) { } else if(kvp.Key == PlgxGeneratorVersion) { } else if(kvp.Key == PlgxPrereqKP) { ulong uReq = MemUtil.BytesToUInt64(kvp.Value); if(uReq > PwDefs.FileVersion64) throw new PlgxException(KLRes.FileNewVerReq); } else if(kvp.Key == PlgxPrereqNet) { ulong uReq = MemUtil.BytesToUInt64(kvp.Value); ulong uInst = WinUtil.GetMaxNetFrameworkVersion(); if((uInst != 0) && (uReq > uInst)) throw new PlgxException(KPRes.NewerNetRequired); } else if(kvp.Key == PlgxPrereqOS) { string strOS = "," + WinUtil.GetOSStr() + ","; string strReq = "," + StrUtil.Utf8.GetString(kvp.Value) + ","; if(strReq.IndexOf(strOS, StrUtil.CaseIgnoreCmp) < 0) throw new PlgxException(KPRes.PluginOperatingSystemUnsupported); } else if(kvp.Key == PlgxPrereqPtr) { uint uReq = MemUtil.BytesToUInt32(kvp.Value); if(uReq > (uint)IntPtr.Size) throw new PlgxException(KPRes.PluginOperatingSystemUnsupported); } else if(kvp.Key == PlgxBuildPre) strBuildPre = StrUtil.Utf8.GetString(kvp.Value); else if(kvp.Key == PlgxBuildPost) strBuildPost = StrUtil.Utf8.GetString(kvp.Value); else if(kvp.Key == PlgxBeginContent) { if(bContent.HasValue) throw new PlgxException(KLRes.FileCorrupted); string strCached = PlgxCache.GetCacheFile(plgx, true, false); if(!string.IsNullOrEmpty(strCached) && plgx.AllowCached) { strPluginPath = strCached; break; } if(slStatus != null) slStatus.SetText(KPRes.PluginsCompilingAndLoading, LogStatusType.Info); bContent = true; if(plgx.LogStream != null) plgx.LogStream.WriteLine("Content:"); } else if(kvp.Key == PlgxFile) { if(!bContent.HasValue || !bContent.Value) throw new PlgxException(KLRes.FileCorrupted); if(strTmpRoot == null) strTmpRoot = CreateTempDirectory(); ExtractFile(kvp.Value, strTmpRoot, plgx); } else if(kvp.Key == PlgxEndContent) { if(!bContent.HasValue || !bContent.Value) throw new PlgxException(KLRes.FileCorrupted); bContent = false; } else { Debug.Assert(false); } } if((strPluginPath == null) && plgx.AllowCompile) strPluginPath = Compile(strTmpRoot, plgx, strBuildPre, strBuildPost); return strPluginPath; } private static string CreateTempDirectory() { string strTmpRoot = UrlUtil.GetTempPath(); strTmpRoot = UrlUtil.EnsureTerminatingSeparator(strTmpRoot, false); strTmpRoot += (new PwUuid(true)).ToHexString(); Directory.CreateDirectory(strTmpRoot); Program.TempFilesPool.AddDirectory(strTmpRoot, true); return strTmpRoot; } private static KeyValuePair ReadObject(BinaryReader br) { try { ushort uType = br.ReadUInt16(); uint uLength = br.ReadUInt32(); byte[] pbData = ((uLength > 0) ? br.ReadBytes((int)uLength) : null); return new KeyValuePair(uType, pbData); } catch(Exception) { throw new PlgxException(KLRes.FileCorrupted); } } private static void WriteObject(BinaryWriter bw, ushort uType, byte[] pbData) { bw.Write(uType); bw.Write((uint)((pbData != null) ? pbData.Length : 0)); if((pbData != null) && (pbData.Length > 0)) bw.Write(pbData); } private static void ExtractFile(byte[] pbData, string strTmpRoot, PlgxPluginInfo plgx) { MemoryStream ms = new MemoryStream(pbData, false); BinaryReader br = new BinaryReader(ms); string strPath = null; byte[] pbContent = null; while(true) { KeyValuePair kvp = ReadObject(br); if(kvp.Key == PlgxfEOF) break; else if(kvp.Key == PlgxfPath) strPath = StrUtil.Utf8.GetString(kvp.Value); else if(kvp.Key == PlgxfData) pbContent = kvp.Value; else { Debug.Assert(false); } } br.Close(); ms.Close(); if(!string.IsNullOrEmpty(strPath) && (pbContent != null)) { string strTmpFile = UrlUtil.EnsureTerminatingSeparator(strTmpRoot, false) + UrlUtil.ConvertSeparators(strPath); string strTmpDir = UrlUtil.GetFileDirectory(strTmpFile, false, true); if(!Directory.Exists(strTmpDir)) Directory.CreateDirectory(strTmpDir); byte[] pbDecompressed = MemUtil.Decompress(pbContent); File.WriteAllBytes(strTmpFile, pbDecompressed); // Although the temporary directory will be deleted recursively // anyway, add the extracted file here manually, in order to // minimize left-over files in case the recursive deletion fails // due to locked / in-use files Program.TempFilesPool.Add(strTmpFile); if(plgx.LogStream != null) { MD5CryptoServiceProvider md5 = new MD5CryptoServiceProvider(); byte[] pbMD5 = md5.ComputeHash(pbDecompressed); plgx.LogStream.Write(MemUtil.ByteArrayToHexString(pbMD5)); plgx.LogStream.WriteLine(" " + strPath); } } else { Debug.Assert(false); } } private static void AddFile(BinaryWriter bw, string strRootDir, string strSourceFile) { if(strSourceFile.EndsWith(".suo", StrUtil.CaseIgnoreCmp)) return; MemoryStream msFile = new MemoryStream(); BinaryWriter bwFile = new BinaryWriter(msFile); strRootDir = UrlUtil.EnsureTerminatingSeparator(strRootDir, false); string strRel = UrlUtil.ConvertSeparators(UrlUtil.MakeRelativePath( strRootDir + "Sentinel.txt", strSourceFile), '/'); WriteObject(bwFile, PlgxfPath, StrUtil.Utf8.GetBytes(strRel)); byte[] pbData = (File.ReadAllBytes(strSourceFile) ?? MemUtil.EmptyByteArray); if(pbData.LongLength >= (long)(int.MaxValue / 2)) // Max 1 GB throw new OutOfMemoryException(); byte[] pbCompressed = MemUtil.Compress(pbData); WriteObject(bwFile, PlgxfData, pbCompressed); WriteObject(bwFile, PlgxfEOF, null); WriteObject(bw, PlgxFile, msFile.ToArray()); bwFile.Close(); msFile.Close(); if(!MemUtil.ArraysEqual(MemUtil.Decompress(pbCompressed), pbData)) throw new InvalidOperationException(); } public static void CreateFromCommandLine() { try { string strDir = Program.CommandLineArgs.FileName; if(string.IsNullOrEmpty(strDir)) { FolderBrowserDialog dlg = UIUtil.CreateFolderBrowserDialog(KPRes.Plugin); if(dlg.ShowDialog() != DialogResult.OK) { dlg.Dispose(); return; } strDir = dlg.SelectedPath; dlg.Dispose(); } CreateFromDirectory(strDir); } catch(Exception ex) { MessageService.ShowWarning(ex); } } private static void CreateFromDirectory(string strDirPath) { string strPlgx = strDirPath + "." + PlgxExtension; PlgxPluginInfo plgx = new PlgxPluginInfo(false, true, true); PlgxCsprojLoader.LoadDefault(strDirPath, plgx); FileStream fs = new FileStream(strPlgx, FileMode.Create, FileAccess.Write, FileShare.None); BinaryWriter bw = new BinaryWriter(fs); bw.Write(PlgxSignature1); bw.Write(PlgxSignature2); bw.Write(PlgxVersion); WriteObject(bw, PlgxFileUuid, (new PwUuid(true)).UuidBytes); WriteObject(bw, PlgxBaseFileName, StrUtil.Utf8.GetBytes( plgx.BaseFileName)); WriteObject(bw, PlgxCreationTime, StrUtil.Utf8.GetBytes( TimeUtil.SerializeUtc(DateTime.UtcNow))); WriteObject(bw, PlgxGeneratorName, StrUtil.Utf8.GetBytes( PwDefs.ShortProductName)); WriteObject(bw, PlgxGeneratorVersion, MemUtil.UInt64ToBytes( PwDefs.FileVersion64)); string strKP = Program.CommandLineArgs[AppDefs.CommandLineOptions.PlgxPrereqKP]; if(!string.IsNullOrEmpty(strKP)) { ulong uKP = StrUtil.ParseVersion(strKP); if(uKP != 0) WriteObject(bw, PlgxPrereqKP, MemUtil.UInt64ToBytes(uKP)); } string strNet = Program.CommandLineArgs[AppDefs.CommandLineOptions.PlgxPrereqNet]; if(!string.IsNullOrEmpty(strNet)) { ulong uNet = StrUtil.ParseVersion(strNet); if(uNet != 0) WriteObject(bw, PlgxPrereqNet, MemUtil.UInt64ToBytes(uNet)); } string strOS = Program.CommandLineArgs[AppDefs.CommandLineOptions.PlgxPrereqOS]; if(!string.IsNullOrEmpty(strOS)) WriteObject(bw, PlgxPrereqOS, StrUtil.Utf8.GetBytes(strOS)); string strPtr = Program.CommandLineArgs[AppDefs.CommandLineOptions.PlgxPrereqPtr]; if(!string.IsNullOrEmpty(strPtr)) { uint uPtr; if(uint.TryParse(strPtr, out uPtr)) WriteObject(bw, PlgxPrereqPtr, MemUtil.UInt32ToBytes(uPtr)); } string strBuildPre = Program.CommandLineArgs[AppDefs.CommandLineOptions.PlgxBuildPre]; if(!string.IsNullOrEmpty(strBuildPre)) WriteObject(bw, PlgxBuildPre, StrUtil.Utf8.GetBytes(strBuildPre)); string strBuildPost = Program.CommandLineArgs[AppDefs.CommandLineOptions.PlgxBuildPost]; if(!string.IsNullOrEmpty(strBuildPost)) WriteObject(bw, PlgxBuildPost, StrUtil.Utf8.GetBytes(strBuildPost)); WriteObject(bw, PlgxBeginContent, null); RecursiveFileAdd(bw, strDirPath, new DirectoryInfo(strDirPath)); WriteObject(bw, PlgxEndContent, null); WriteObject(bw, PlgxEOF, null); bw.Close(); fs.Close(); // Test loading not possible, because MainForm not available // PlgxPlugin.Load(strPlgx); } private static void RecursiveFileAdd(BinaryWriter bw, string strRootDir, DirectoryInfo di) { if(di.Name.Equals(".svn", StrUtil.CaseIgnoreCmp)) return; // Skip SVN foreach(FileInfo fi in di.GetFiles()) { if((fi.Name == ".") || (fi.Name == "..")) continue; AddFile(bw, strRootDir, fi.FullName); } foreach(DirectoryInfo diSub in di.GetDirectories()) RecursiveFileAdd(bw, strRootDir, diSub); } private static string Compile(string strTmpRoot, PlgxPluginInfo plgx, string strBuildPre, string strBuildPost) { if(strTmpRoot == null) { Debug.Assert(false); return null; } RunBuildCommand(strBuildPre, UrlUtil.EnsureTerminatingSeparator( strTmpRoot, false), null); PlgxCsprojLoader.LoadDefault(strTmpRoot, plgx); List vCustomRefs = new List(); foreach(string strIncRefAsm in plgx.IncludedReferencedAssemblies) { string strSrcAsm = plgx.GetAbsPath(UrlUtil.ConvertSeparators( strIncRefAsm)); string strCached = PlgxCache.AddCacheFile(strSrcAsm, plgx); if(string.IsNullOrEmpty(strCached)) throw new InvalidOperationException(); vCustomRefs.Add(strCached); } CompilerParameters cp = plgx.CompilerParameters; cp.OutputAssembly = UrlUtil.EnsureTerminatingSeparator(strTmpRoot, false) + UrlUtil.GetFileName(PlgxCache.GetCacheFile(plgx, false, false)); cp.GenerateExecutable = false; cp.GenerateInMemory = false; cp.IncludeDebugInformation = false; cp.TreatWarningsAsErrors = false; cp.ReferencedAssemblies.Add(WinUtil.GetExecutable()); foreach(string strCustomRef in vCustomRefs) cp.ReferencedAssemblies.Add(strCustomRef); CompileEmbeddedRes(plgx); PrepareSourceFiles(plgx); string[] vCompilers; Version vClr = Environment.Version; int iClrMajor = vClr.Major, iClrMinor = vClr.Minor; if((iClrMajor >= 5) || ((iClrMajor == 4) && (iClrMinor >= 5))) { vCompilers = new string[] { null, "v4.5", "v4", // Suggested in CodeDomProvider.CreateProvider doc "v4.0", // Suggested in community content of the above "v4.0.30319", // Deduced from file system "v3.5" }; } else if(iClrMajor == 4) // 4.0 { vCompilers = new string[] { null, "v4", // Suggested in CodeDomProvider.CreateProvider doc "v4.0", // Suggested in community content of the above "v4.0.30319", // Deduced from file system "v4.5", "v3.5" }; } else // <= 3.5 { vCompilers = new string[] { null, "v3.5", "v4", // Suggested in CodeDomProvider.CreateProvider doc "v4.0", // Suggested in community content of the above "v4.0.30319", // Deduced from file system "v4.5" }; } CompilerResults cr = null; StringBuilder sbCompilerLog = new StringBuilder(); bool bCompiled = false; for(int iCmp = 0; iCmp < vCompilers.Length; ++iCmp) { if(CompileAssembly(plgx, out cr, vCompilers[iCmp])) { bCompiled = true; break; } if(cr != null) AppendCompilerResults(sbCompilerLog, vCompilers[iCmp], cr); } if(!bCompiled) { if(Program.CommandLineArgs[AppDefs.CommandLineOptions.Debug] != null) SaveCompilerResults(plgx, sbCompilerLog); throw new InvalidOperationException(); } Program.TempFilesPool.Add(cr.PathToAssembly); Debug.Assert(cr.PathToAssembly == cp.OutputAssembly); string strCacheAsm = PlgxCache.AddCacheAssembly(cr.PathToAssembly, plgx); RunBuildCommand(strBuildPost, UrlUtil.EnsureTerminatingSeparator( strTmpRoot, false), UrlUtil.GetFileDirectory(strCacheAsm, true, false)); return strCacheAsm; } private static bool CompileAssembly(PlgxPluginInfo plgx, out CompilerResults cr, string strCompilerVersion) { cr = null; const string StrCoreRef = "System.Core"; const string StrCoreDll = "System.Core.dll"; bool bHasCore = false, bCoreAdded = false; foreach(string strAsm in plgx.CompilerParameters.ReferencedAssemblies) { if(UrlUtil.AssemblyEquals(strAsm, StrCoreRef)) { bHasCore = true; break; } } if((strCompilerVersion != null) && strCompilerVersion.StartsWith( "v", StrUtil.CaseIgnoreCmp)) { ulong v = StrUtil.ParseVersion(strCompilerVersion.Substring(1)); if(!bHasCore && (v >= 0x0003000500000000UL)) { plgx.CompilerParameters.ReferencedAssemblies.Add(StrCoreDll); bCoreAdded = true; } } bool bResult = false; try { Dictionary dictOpt = new Dictionary(); if(!string.IsNullOrEmpty(strCompilerVersion)) dictOpt.Add("CompilerVersion", strCompilerVersion); // Windows 98 only supports the parameterless constructor; // check must be separate from the instantiation method if(WinUtil.IsWindows9x) dictOpt.Clear(); CodeDomProvider cdp = null; if(plgx.ProjectType == PlgxProjectType.CSharp) cdp = ((dictOpt.Count == 0) ? new CSharpCodeProvider() : CreateCscProvider(dictOpt)); // else if(plgx.ProjectType == PlgxProjectType.VisualBasic) // cdp = ((dictOpt.Count == 0) ? new VBCodeProvider() : // new VBCodeProvider(dictOpt)); else throw new InvalidOperationException(); cr = cdp.CompileAssemblyFromFile(plgx.CompilerParameters, plgx.SourceFiles.ToArray()); bResult = ((cr.Errors == null) || !cr.Errors.HasErrors); } catch(Exception) { } if(bCoreAdded) plgx.CompilerParameters.ReferencedAssemblies.Remove(StrCoreDll); return bResult; } private static void AppendCompilerResults(StringBuilder sb, string strCompiler, CompilerResults cr) { if((sb == null) || (cr == null)) { Debug.Assert(false); return; } // strCompiler may be null if(sb.Length > 0) { sb.AppendLine(); sb.AppendLine(); sb.AppendLine(); } sb.AppendLine(new string('=', 78)); sb.AppendLine(@"Compiler '" + (strCompiler ?? "null") + @"':"); sb.AppendLine(); foreach(string str in cr.Output) { if(str == null) { Debug.Assert(false); continue; } sb.AppendLine(str.Trim()); } } private static void SaveCompilerResults(PlgxPluginInfo plgx, StringBuilder sb) { string strFile = Path.GetTempFileName(); File.WriteAllText(strFile, sb.ToString(), StrUtil.Utf8); MessageService.ShowWarning(plgx.BaseFileName, "Compilation failed. Compiler results have been saved to:" + Environment.NewLine + strFile); } // Windows 98 only supports the parameterless constructor, therefore // the instantiation of the one with parameters must be in a separate // method; check must be separate from the instantiation method private static CodeDomProvider CreateCscProvider(IDictionary iOpts) { return new CSharpCodeProvider(iOpts); } private static void CompileEmbeddedRes(PlgxPluginInfo plgx) { foreach(string strResSrc in plgx.EmbeddedResourceSources) { string strResFileName = plgx.BaseFileName + "." + UrlUtil.ConvertSeparators( UrlUtil.MakeRelativePath(plgx.CsprojFilePath, strResSrc), '.'); string strResFile = UrlUtil.GetFileDirectory(plgx.CsprojFilePath, true, true) + strResFileName; if(strResSrc.EndsWith(".resx", StrUtil.CaseIgnoreCmp)) { PrepareResXFile(strResSrc); string strRsrc = UrlUtil.StripExtension(strResFile) + ".resources"; ResXResourceReader r = new ResXResourceReader(strResSrc); ResourceWriter w = new ResourceWriter(strRsrc); r.BasePath = UrlUtil.GetFileDirectory(strResSrc, false, true); foreach(DictionaryEntry de in r) w.AddResource((string)de.Key, de.Value); w.Generate(); w.Close(); r.Close(); if(File.Exists(strRsrc)) { plgx.CompilerParameters.EmbeddedResources.Add(strRsrc); Program.TempFilesPool.Add(strRsrc); } } else { File.Copy(strResSrc, strResFile, true); plgx.CompilerParameters.EmbeddedResources.Add(strResFile); } } } private static void PrepareResXFile(string strFilePath) { if(!NativeLib.IsUnix()) return; string[] v = File.ReadAllLines(strFilePath, Encoding.UTF8); // Fix directory separators in ResX file; // Mono's ResXResourceReader doesn't convert them for(int i = 0; i < (v.Length - 1); ++i) { if((v[i].IndexOf(@"= 0) && (v[i].IndexOf( @"System.Resources.ResXFileRef") >= 0) && (v[i + 1].IndexOf( @"") >= 0)) { v[i + 1] = UrlUtil.ConvertSeparators(v[i + 1]); } } File.WriteAllLines(strFilePath, v, new UTF8Encoding(false)); } private static void PrepareSourceFiles(PlgxPluginInfo plgx) { if(plgx.ProjectType != PlgxProjectType.VisualBasic) return; string strImports = string.Empty; foreach(string strImport in plgx.VbImports) strImports += "Imports " + strImport + "\r\n"; if(strImports.Length == 0) return; foreach(string strFile in plgx.SourceFiles) { if(!strFile.EndsWith(".vb", StrUtil.CaseIgnoreCmp)) continue; string strData = File.ReadAllText(strFile); File.WriteAllText(strFile, strImports + strData); } } private static void RunBuildCommand(string strCmd, string strTmpDir, string strCacheDir) { if(string.IsNullOrEmpty(strCmd)) return; // No assert string str = strCmd; if(strTmpDir != null) str = StrUtil.ReplaceCaseInsensitive(str, @"{PLGX_TEMP_DIR}", strTmpDir); if(strCacheDir != null) str = StrUtil.ReplaceCaseInsensitive(str, @"{PLGX_CACHE_DIR}", strCacheDir); // str = UrlUtil.ConvertSeparators(str); str = SprEngine.Compile(str, null); string strApp, strArgs; StrUtil.SplitCommandLine(str, out strApp, out strArgs); try { if((strArgs != null) && (strArgs.Length > 0)) Process.Start(strApp, strArgs); else Process.Start(strApp); } catch(Exception exRun) { if(Program.CommandLineArgs[AppDefs.CommandLineOptions.Debug] != null) throw new PlgxException(exRun.Message); throw; } } } } KeePass/Plugins/PluginManager.cs0000664000000000000000000002244313222430412015610 0ustar rootroot/* KeePass Password Safe - The Open-Source Password Manager Copyright (C) 2003-2018 Dominik Reichl This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ using System; using System.Collections; using System.Collections.Generic; using System.Diagnostics; using System.IO; using System.Reflection; using System.Runtime.Remoting; using System.Text; using System.Windows.Forms; using KeePass.App; using KeePass.App.Configuration; using KeePass.Resources; using KeePass.Plugins; using KeePass.UI; using KeePass.Util; using KeePassLib; using KeePassLib.Interfaces; using KeePassLib.Native; using KeePassLib.Utility; namespace KeePass.Plugins { internal sealed class PluginManager : IEnumerable { private List m_vPlugins = new List(); private IPluginHost m_host = null; private static string g_strUserDir = string.Empty; internal static string UserDirectory { get { return g_strUserDir; } } public void Initialize(IPluginHost host) { Debug.Assert(host != null); m_host = host; } IEnumerator IEnumerable.GetEnumerator() { return m_vPlugins.GetEnumerator(); } public IEnumerator GetEnumerator() { return m_vPlugins.GetEnumerator(); } internal void LoadAllPlugins() { string[] vExclNames = new string[] { AppDefs.FileNames.Program, AppDefs.FileNames.XmlSerializers, AppDefs.FileNames.NativeLib32, AppDefs.FileNames.NativeLib64, AppDefs.FileNames.ShInstUtil }; string strAppDir = UrlUtil.GetFileDirectory(WinUtil.GetExecutable(), false, true); LoadAllPlugins(strAppDir, SearchOption.TopDirectoryOnly, vExclNames); g_strUserDir = strAppDir; // Preliminary, see below if(WinUtil.IsAppX) { string str = UrlUtil.EnsureTerminatingSeparator( AppConfigSerializer.AppDataDirectory, false) + AppDefs.PluginsDir; LoadAllPlugins(str, SearchOption.AllDirectories, vExclNames); g_strUserDir = str; } else if(!NativeLib.IsUnix()) { string str = UrlUtil.EnsureTerminatingSeparator(strAppDir, false) + AppDefs.PluginsDir; LoadAllPlugins(str, SearchOption.AllDirectories, vExclNames); g_strUserDir = str; } else // Unix { try { DirectoryInfo diPlgRoot = new DirectoryInfo(strAppDir); foreach(DirectoryInfo diSub in diPlgRoot.GetDirectories()) { if(diSub == null) { Debug.Assert(false); continue; } if(string.Equals(diSub.Name, AppDefs.PluginsDir, StrUtil.CaseIgnoreCmp)) { LoadAllPlugins(diSub.FullName, SearchOption.AllDirectories, vExclNames); g_strUserDir = diSub.FullName; } } } catch(Exception) { Debug.Assert(false); } } } public void LoadAllPlugins(string strDirectory, SearchOption so, string[] vExclNames) { Debug.Assert(m_host != null); try { string strPath = strDirectory; if(!Directory.Exists(strPath)) return; // No assert DirectoryInfo di = new DirectoryInfo(strPath); List lFiles = UrlUtil.GetFileInfos(di, "*.dll", so); FilterList(lFiles, vExclNames); LoadPlugins(lFiles, null, null, true); lFiles = UrlUtil.GetFileInfos(di, "*.exe", so); FilterList(lFiles, vExclNames); LoadPlugins(lFiles, null, null, true); lFiles = UrlUtil.GetFileInfos(di, "*." + PlgxPlugin.PlgxExtension, so); FilterList(lFiles, vExclNames); if(lFiles.Count > 0) { OnDemandStatusDialog dlgStatus = new OnDemandStatusDialog(true, null); dlgStatus.StartLogging(PwDefs.ShortProductName, false); foreach(FileInfo fi in lFiles) PlgxPlugin.Load(fi.FullName, dlgStatus); dlgStatus.EndLogging(); } } catch(Exception) { Debug.Assert(false); } // Path access violation } public void LoadPlugin(string strFilePath, string strTypeName, string strDisplayFilePath, bool bSkipCacheFile) { if(strFilePath == null) throw new ArgumentNullException("strFilePath"); List l = new List(); l.Add(new FileInfo(strFilePath)); LoadPlugins(l, strTypeName, strDisplayFilePath, bSkipCacheFile); } private void LoadPlugins(List lFiles, string strTypeName, string strDisplayFilePath, bool bSkipCacheFiles) { string strCacheRoot = PlgxCache.GetCacheRoot(); foreach(FileInfo fi in lFiles) { if(bSkipCacheFiles && fi.FullName.StartsWith(strCacheRoot, StrUtil.CaseIgnoreCmp)) continue; FileVersionInfo fvi = null; try { fvi = FileVersionInfo.GetVersionInfo(fi.FullName); if((fvi == null) || (fvi.ProductName == null) || (fvi.ProductName != AppDefs.PluginProductName)) { continue; } } catch(Exception) { continue; } Exception exShowStd = null; try { PluginInfo pi = new PluginInfo(fi.FullName, fvi, strDisplayFilePath); pi.Interface = CreatePluginInstance(pi.FilePath, strTypeName); if(!pi.Interface.Initialize(m_host)) continue; // Fail without error m_vPlugins.Add(pi); } catch(BadImageFormatException exBif) { if(Is1xPlugin(fi.FullName)) MessageService.ShowWarning(KPRes.PluginIncompatible + MessageService.NewLine + fi.FullName + MessageService.NewParagraph + KPRes.Plugin1x + MessageService.NewParagraph + KPRes.Plugin1xHint); else exShowStd = exBif; } catch(Exception exLoad) { if(Program.CommandLineArgs[AppDefs.CommandLineOptions.Debug] != null) MessageService.ShowWarningExcp(fi.FullName, exLoad); else exShowStd = exLoad; } if(exShowStd != null) ShowLoadError(fi.FullName, exShowStd, null); } } internal static void ShowLoadError(string strPath, Exception ex, IStatusLogger slStatus) { if(string.IsNullOrEmpty(strPath)) { Debug.Assert(false); return; } if(slStatus != null) slStatus.SetText(KPRes.PluginLoadFailed, LogStatusType.Info); bool bShowExcp = (Program.CommandLineArgs[ AppDefs.CommandLineOptions.Debug] != null); string strMsg = KPRes.PluginIncompatible + MessageService.NewLine + strPath + MessageService.NewParagraph + KPRes.PluginUpdateHint; string strExcp = ((ex != null) ? StrUtil.FormatException(ex).Trim() : null); VistaTaskDialog vtd = new VistaTaskDialog(); vtd.Content = strMsg; vtd.ExpandedByDefault = ((strExcp != null) && bShowExcp); vtd.ExpandedInformation = strExcp; vtd.WindowTitle = PwDefs.ShortProductName; vtd.SetIcon(VtdIcon.Warning); if(!vtd.ShowDialog()) { if(!bShowExcp) MessageService.ShowWarning(strMsg); else MessageService.ShowWarningExcp(strPath, ex); } } public void UnloadAllPlugins() { foreach(PluginInfo plugin in m_vPlugins) { Debug.Assert(plugin.Interface != null); if(plugin.Interface != null) { try { plugin.Interface.Terminate(); } catch(Exception) { Debug.Assert(false); } } } m_vPlugins.Clear(); } private static Plugin CreatePluginInstance(string strFilePath, string strTypeName) { Debug.Assert(strFilePath != null); if(strFilePath == null) throw new ArgumentNullException("strFilePath"); string strType; if(string.IsNullOrEmpty(strTypeName)) { strType = UrlUtil.GetFileName(strFilePath); strType = UrlUtil.StripExtension(strType) + "." + UrlUtil.StripExtension(strType) + "Ext"; } else strType = strTypeName + "." + strTypeName + "Ext"; ObjectHandle oh = Activator.CreateInstanceFrom(strFilePath, strType); Plugin plugin = (oh.Unwrap() as Plugin); if(plugin == null) throw new FileLoadException(); return plugin; } private static bool Is1xPlugin(string strFile) { try { byte[] pbFile = File.ReadAllBytes(strFile); byte[] pbSig = StrUtil.Utf8.GetBytes("KpCreateInstance"); string strData = MemUtil.ByteArrayToHexString(pbFile); string strSig = MemUtil.ByteArrayToHexString(pbSig); return (strData.IndexOf(strSig) >= 0); } catch(Exception) { Debug.Assert(false); } return false; } private static void FilterList(List l, string[] vExclNames) { if((l == null) || (vExclNames == null)) { Debug.Assert(false); return; } for(int i = l.Count - 1; i >= 0; --i) { string strName = UrlUtil.GetFileName(l[i].FullName); foreach(string strExcl in vExclNames) { if(string.IsNullOrEmpty(strExcl)) { Debug.Assert(false); continue; } if(string.Equals(strName, strExcl, StrUtil.CaseIgnoreCmp)) { l.RemoveAt(i); break; } } } } } } KeePass/Plugins/Plugin.cs0000664000000000000000000000507613222430412014320 0ustar rootroot/* KeePass Password Safe - The Open-Source Password Manager Copyright (C) 2003-2018 Dominik Reichl This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ using System; using System.Collections.Generic; using System.Text; using System.Diagnostics; using System.Drawing; namespace KeePass.Plugins { /// /// KeePass plugin base class. All KeePass plugins must derive from /// this class. /// public abstract class Plugin { /// /// The Initialize function is called by KeePass when /// you should initialize your plugin (create menu items, etc.). /// /// Plugin host interface. By using this /// interface, you can access the KeePass main window and the /// currently opened database. /// You must return true in order to signal /// successful initialization. If you return false, /// KeePass unloads your plugin (without calling the /// Terminate function of your plugin). public virtual bool Initialize(IPluginHost host) { return (host != null); } /// /// The Terminate function is called by KeePass when /// you should free all resources, close open files/streams, /// etc. It is also recommended that you remove all your /// plugin menu items from the KeePass menu. /// public virtual void Terminate() { } /// /// Get a handle to a 16x16 icon representing the plugin. /// This icon is shown in the plugin management window of /// KeePass for example. /// public virtual Image SmallIcon { get { return null; } } /// /// URL of a version information file. See /// https://keepass.info/help/v2_dev/plg_index.html#upd /// public virtual string UpdateUrl { get { return null; } } } } KeePass/Plugins/PlgxCache.cs0000664000000000000000000002013013222430412014704 0ustar rootroot/* KeePass Password Safe - The Open-Source Password Manager Copyright (C) 2003-2018 Dominik Reichl This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ using System; using System.Collections.Generic; using System.Diagnostics; using System.IO; using System.Reflection; using System.Text; using System.Threading; using KeePass.App.Configuration; using KeePass.Util.Spr; using KeePassLib; using KeePassLib.Cryptography; using KeePassLib.Native; using KeePassLib.Utility; namespace KeePass.Plugins { public static class PlgxCache { private const string CacheDirName = "PluginCache"; private static string m_strAppEnvID = null; private static string GetAppEnvID() { if(m_strAppEnvID != null) return m_strAppEnvID; StringBuilder sb = new StringBuilder(); Assembly asm = null; AssemblyName asmName = null; try { asm = Assembly.GetExecutingAssembly(); asmName = asm.GetName(); } catch(Exception) { Debug.Assert(false); } try { sb.Append(asmName.Version.ToString(4)); } catch(Exception) { Debug.Assert(false); sb.Append(PwDefs.VersionString); } #if DEBUG sb.Append("d"); #endif sb.Append(",PK="); try { byte[] pk = asmName.GetPublicKeyToken(); sb.Append(Convert.ToBase64String(pk, Base64FormattingOptions.None)); } catch(Exception) { Debug.Assert(false); sb.Append('?'); } sb.Append(",CLR="); sb.Append(Environment.Version.ToString(4)); sb.Append(",Ptr="); sb.Append(IntPtr.Size.ToString()); sb.Append(",OS="); PlatformID p = NativeLib.GetPlatformID(); if((p == PlatformID.Win32NT) || (p == PlatformID.Win32S) || (p == PlatformID.Win32Windows)) sb.Append("Win"); else if(p == PlatformID.WinCE) sb.Append("WinCE"); else if(p == PlatformID.Xbox) sb.Append("Xbox"); else if(p == PlatformID.Unix) sb.Append("Unix"); else if(p == PlatformID.MacOSX) sb.Append("MacOSX"); else sb.Append('?'); m_strAppEnvID = sb.ToString(); return m_strAppEnvID; } public static string GetCacheRoot() { if(Program.Config.Application.PluginCachePath.Length > 0) { string strRoot = SprEngine.Compile(Program.Config.Application.PluginCachePath, null); if(!string.IsNullOrEmpty(strRoot)) { if(strRoot.EndsWith(new string(Path.DirectorySeparatorChar, 1))) strRoot = strRoot.Substring(0, strRoot.Length - 1); return strRoot; } } string strDataDir = AppConfigSerializer.LocalAppDataDirectory; // try // { // DirectoryInfo diAppData = new DirectoryInfo(strDataDir); // DirectoryInfo diRoot = diAppData.Root; // DriveInfo di = new DriveInfo(diRoot.FullName); // if(di.DriveType == DriveType.Network) // { // strDataDir = UrlUtil.EnsureTerminatingSeparator( // UrlUtil.GetTempPath(), false); // strDataDir = strDataDir.Substring(0, strDataDir.Length - 1); // } // } // catch(Exception) { Debug.Assert(false); } return (strDataDir + Path.DirectorySeparatorChar + CacheDirName); } 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()); byte[] pbHash = CryptoUtil.HashSha256(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; } 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.SetLastAccessTimeUtc(strPath, DateTime.UtcNow); } catch(Exception) { } // Might be locked by other KeePass instance } if(!bMustExist || bExists) return strPath; return null; } public static string AddCacheAssembly(string strAssemblyPath, PlgxPluginInfo plgx) { if(string.IsNullOrEmpty(strAssemblyPath)) { Debug.Assert(false); return null; } string strNewFile = GetCacheFile(plgx, false, true); File.Copy(strAssemblyPath, strNewFile, true); return strNewFile; } public static string AddCacheFile(string strNormalFile, PlgxPluginInfo plgx) { if(string.IsNullOrEmpty(strNormalFile)) { Debug.Assert(false); return null; } string strNewFile = UrlUtil.EnsureTerminatingSeparator(GetCacheDirectory( plgx, true), false) + UrlUtil.GetFileName(strNormalFile); File.Copy(strNormalFile, strNewFile, true); return strNewFile; } public static ulong GetUsedCacheSize() { string strRoot = GetCacheRoot(); if(!Directory.Exists(strRoot)) return 0; DirectoryInfo di = new DirectoryInfo(strRoot); List lFiles = UrlUtil.GetFileInfos(di, "*", SearchOption.AllDirectories); ulong uSize = 0; foreach(FileInfo fi in lFiles) { uSize += (ulong)fi.Length; } return uSize; } public static void Clear() { try { string strRoot = GetCacheRoot(); if(!Directory.Exists(strRoot)) return; Directory.Delete(strRoot, true); } catch(Exception) { Debug.Assert(false); } } public static void DeleteOldFilesAsync() { ThreadPool.QueueUserWorkItem(new WaitCallback(PlgxCache.DeleteOldFilesSafe)); } private static void DeleteOldFilesSafe(object stateInfo) { try { DeleteOldFilesFunc(); } catch(Exception) { Debug.Assert(false); } } private static void DeleteOldFilesFunc() { string strRoot = GetCacheRoot(); if(!Directory.Exists(strRoot)) return; DirectoryInfo di = new DirectoryInfo(strRoot); foreach(DirectoryInfo diSub in di.GetDirectories("*", SearchOption.TopDirectoryOnly)) { try { if(ContainsOnlyOldFiles(diSub)) Directory.Delete(diSub.FullName, true); } catch(Exception) { Debug.Assert(false); } } } private static bool ContainsOnlyOldFiles(DirectoryInfo di) { if((di.Name == ".") || (di.Name == "..")) return false; List lFiles = UrlUtil.GetFileInfos(di, "*.dll", SearchOption.TopDirectoryOnly); DateTime dtNow = DateTime.UtcNow; foreach(FileInfo fi in lFiles) { if((dtNow - fi.LastAccessTimeUtc).TotalDays < 62.0) return false; } return true; } } } KeePass/Plugins/IPluginHost.cs0000664000000000000000000000446113222430412015264 0ustar rootroot/* KeePass Password Safe - The Open-Source Password Manager Copyright (C) 2003-2018 Dominik Reichl This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ using System; using System.Collections.Generic; using System.Text; using System.Drawing; using System.Resources; using System.Diagnostics; using KeePass.App.Configuration; using KeePass.DataExchange; using KeePass.Ecas; using KeePass.Forms; using KeePass.UI; using KeePass.Util; using KeePassLib; using KeePassLib.Cryptography.Cipher; using KeePassLib.Cryptography.PasswordGenerator; using KeePassLib.Keys; namespace KeePass.Plugins { public interface IPluginHost { /// /// Reference to the KeePass main window. /// MainForm MainWindow { get; } /// /// Reference to the currently opened database. /// PwDatabase Database { get; } /// /// Reference to the command line arguments. /// CommandLineArgs CommandLineArgs { get; } AceCustomConfig CustomConfig { get; } /// /// Reference to the global cipher pool. When implementing /// an encryption algorithm, use this pool to register it. /// CipherPool CipherPool { get; } KeyProviderPool KeyProviderPool { get; } KeyValidatorPool KeyValidatorPool { get; } FileFormatPool FileFormatPool { get; } TempFilesPool TempFilesPool { get; } EcasPool EcasPool { get; } EcasTriggerSystem TriggerSystem { get; } CustomPwGeneratorPool PwGeneratorPool { get; } ColumnProviderPool ColumnProviderPool { get; } ResourceManager Resources { get; } } } KeePass/Plugins/PlgxPluginInfo.cs0000664000000000000000000000774313222430412015772 0ustar rootroot/* KeePass Password Safe - The Open-Source Password Manager Copyright (C) 2003-2018 Dominik Reichl This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ using System; using System.Collections.Generic; using System.Text; using System.Diagnostics; using System.CodeDom; using System.CodeDom.Compiler; using System.IO; using KeePass.Resources; using KeePassLib; using KeePassLib.Utility; namespace KeePass.Plugins { public enum PlgxProjectType { CSharp, VisualBasic } public sealed class PlgxPluginInfo { public bool Compiling { get; set; } public bool AllowCached { get; set; } public bool AllowCompile { get; set; } private TextWriter m_twLog = null; public TextWriter LogStream { get { return m_twLog; } set { m_twLog = value; } } private PlgxProjectType m_pt = PlgxProjectType.CSharp; public PlgxProjectType ProjectType { get { return m_pt; } set { m_pt = value; } } private PwUuid m_uuid = PwUuid.Zero; public PwUuid FileUuid { get { return m_uuid; } set { if(value == null) throw new ArgumentNullException("value"); m_uuid = value; } } private string m_strBaseFileName = string.Empty; public string BaseFileName { get { return m_strBaseFileName; } set { if(value == null) throw new ArgumentNullException("value"); m_strBaseFileName = value; } } private string m_strCsproj = string.Empty; public string CsprojFilePath { get { return m_strCsproj; } set { if(value == null) throw new ArgumentNullException("value"); m_strCsproj = value; } } private CompilerParameters m_cp = new CompilerParameters(); public CompilerParameters CompilerParameters { get { return m_cp; } set { if(value == null) throw new ArgumentNullException("value"); m_cp = value; } } private List m_vFiles = new List(); public List SourceFiles { get { return m_vFiles; } set { if(value == null) throw new ArgumentNullException("value"); m_vFiles = value; } } private List m_vIncRefAsms = new List(); public List IncludedReferencedAssemblies { get { return m_vIncRefAsms; } set { if(value == null) throw new ArgumentNullException("value"); m_vIncRefAsms = value; } } private List m_vEmbeddedRes = new List(); public List EmbeddedResourceSources { get { return m_vEmbeddedRes; } set { if(value == null) throw new ArgumentNullException("value"); m_vEmbeddedRes = value; } } private List m_vVbImports = new List(); public List VbImports { get { return m_vVbImports; } set { if(value == null) throw new ArgumentNullException("value"); m_vVbImports = value; } } public PlgxPluginInfo(bool bCompiling, bool bAllowCached, bool bAllowCompile) { this.Compiling = bCompiling; this.AllowCached = bAllowCached; this.AllowCompile = bAllowCompile; } public string GetAbsPath(string strRelPath) { Debug.Assert(!string.IsNullOrEmpty(this.CsprojFilePath)); return UrlUtil.MakeAbsolutePath(this.CsprojFilePath, UrlUtil.ConvertSeparators(strRelPath)); } } } KeePass/Plugins/DefaultPluginHost.cs0000664000000000000000000000607213222430412016460 0ustar rootroot/* KeePass Password Safe - The Open-Source Password Manager Copyright (C) 2003-2018 Dominik Reichl This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ using System; using System.Collections.Generic; using System.Resources; using System.Diagnostics; using KeePass.App.Configuration; using KeePass.DataExchange; using KeePass.Ecas; using KeePass.Forms; using KeePass.UI; using KeePass.Util; using KeePassLib; using KeePassLib.Cryptography.Cipher; using KeePassLib.Cryptography.PasswordGenerator; using KeePassLib.Keys; using KeePassLib.Security; namespace KeePass.Plugins { internal sealed class DefaultPluginHost : IPluginHost { private MainForm m_form = null; private CommandLineArgs m_cmdLineArgs = null; private CipherPool m_cipherPool = null; public DefaultPluginHost() { } public void Initialize(MainForm form, CommandLineArgs cmdLineArgs, CipherPool cipherPool) { Debug.Assert(form != null); Debug.Assert(cmdLineArgs != null); Debug.Assert(cipherPool != null); m_form = form; m_cmdLineArgs = cmdLineArgs; m_cipherPool = cipherPool; } public MainForm MainWindow { get { return m_form; } } public PwDatabase Database { get { return m_form.ActiveDatabase; } } public CommandLineArgs CommandLineArgs { get { return m_cmdLineArgs; } } public AceCustomConfig CustomConfig { get { return Program.Config.CustomConfig; } } public CipherPool CipherPool { get { return m_cipherPool; } } public KeyProviderPool KeyProviderPool { get { return Program.KeyProviderPool; } } public KeyValidatorPool KeyValidatorPool { get { return Program.KeyValidatorPool; } } public FileFormatPool FileFormatPool { get { return Program.FileFormatPool; } } public TempFilesPool TempFilesPool { get { return Program.TempFilesPool; } } public EcasPool EcasPool { get { return Program.EcasPool; } } public EcasTriggerSystem TriggerSystem { get { return Program.TriggerSystem; } } public CustomPwGeneratorPool PwGeneratorPool { get { return Program.PwGeneratorPool; } } public ColumnProviderPool ColumnProviderPool { get { return Program.ColumnProviderPool; } } public ResourceManager Resources { get { return Properties.Resources.ResourceManager; } } } } KeePass/Util/0000775000000000000000000000000013224154300012020 5ustar rootrootKeePass/Util/ChildProcessesSnapshot.cs0000664000000000000000000001235613222430416017013 0ustar rootroot/* KeePass Password Safe - The Open-Source Password Manager Copyright (C) 2003-2018 Dominik Reichl This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ using System; using System.Collections.Generic; using System.Text; using System.Runtime.InteropServices; using System.Threading; using System.Diagnostics; using KeePass.Native; using KeePass.Util; using KeePassLib.Utility; namespace KeePass.Util { public sealed class ChildProcessesSnapshot { private readonly string m_strChildExeName; // May be null private readonly List m_lPids; public ChildProcessesSnapshot(string strChildExeName) { m_strChildExeName = (string.IsNullOrEmpty(strChildExeName) ? string.Empty : GetExeName(strChildExeName)); m_lPids = GetChildPids(); } private List GetChildPids() { List lPids = new List(); if(KeePassLib.Native.NativeLib.IsUnix()) return lPids; try { uint pidThis = (uint)Process.GetCurrentProcess().Id; uint uEntrySize = (uint)Marshal.SizeOf(typeof( NativeMethods.PROCESSENTRY32)); if(WinUtil.IsAtLeastWindows2000) // Unicode { int p = Marshal.SizeOf(typeof(IntPtr)); if(p == 4) { Debug.Assert(uEntrySize == NativeMethods.PROCESSENTRY32SizeUni32); } else if(p == 8) { Debug.Assert(uEntrySize == NativeMethods.PROCESSENTRY32SizeUni64); } } IntPtr hSnap = NativeMethods.CreateToolhelp32Snapshot( NativeMethods.ToolHelpFlags.SnapProcess, 0); if(NativeMethods.IsInvalidHandleValue(hSnap)) { Debug.Assert(false); return lPids; } for(int i = 0; i < int.MaxValue; ++i) { NativeMethods.PROCESSENTRY32 pe = new NativeMethods.PROCESSENTRY32(); pe.dwSize = uEntrySize; bool b; if(i == 0) b = NativeMethods.Process32First(hSnap, ref pe); else b = NativeMethods.Process32Next(hSnap, ref pe); if(!b) break; if(pe.th32ProcessID == pidThis) continue; if(pe.th32ParentProcessID != pidThis) continue; if(!string.IsNullOrEmpty(m_strChildExeName)) { if(pe.szExeFile == null) { Debug.Assert(false); continue; } string str = GetExeName(pe.szExeFile); if(!str.Equals(m_strChildExeName, StrUtil.CaseIgnoreCmp)) continue; } lPids.Add(pe.th32ProcessID); } if(!NativeMethods.CloseHandle(hSnap)) { Debug.Assert(false); } } catch(Exception) { Debug.Assert(false); } return lPids; } private static char[] m_vTrimChars = null; private static string GetExeName(string strPath) { if(strPath == null) { Debug.Assert(false); return string.Empty; } if(m_vTrimChars == null) m_vTrimChars = new char[] { '\r', '\n', ' ', '\t', '\"', '\'' }; string str = strPath.Trim(m_vTrimChars); str = UrlUtil.GetFileName(str); return str; } public void TerminateNewChildsAsync(int nDelayMs) { List lPids = GetChildPids(); foreach(uint uPid in lPids) { if(m_lPids.IndexOf(uPid) < 0) { CpsTermInfo ti = new CpsTermInfo(uPid, m_strChildExeName, nDelayMs); ParameterizedThreadStart pts = new ParameterizedThreadStart( ChildProcessesSnapshot.DelayedTerminatePid); Thread th = new Thread(pts); th.Start(ti); } } } private sealed class CpsTermInfo { private readonly uint m_uPid; public uint ProcessId { get { return m_uPid; } } private readonly string m_strExeName; public string ExeName { get { return m_strExeName; } } private readonly int m_nDelayMs; public int Delay { get { return m_nDelayMs; } } public CpsTermInfo(uint uPid, string strExeName, int nDelayMs) { m_uPid = uPid; m_strExeName = strExeName; m_nDelayMs = nDelayMs; } } private static void DelayedTerminatePid(object oTermInfo) { try { CpsTermInfo ti = (oTermInfo as CpsTermInfo); if(ti == null) { Debug.Assert(false); return; } if(ti.Delay > 0) Thread.Sleep(ti.Delay); Process p = Process.GetProcessById((int)ti.ProcessId); if(p == null) { Debug.Assert(false); return; } // Verify that likely it's indeed the correct process if(!string.IsNullOrEmpty(ti.ExeName)) { string str = GetExeName(p.MainModule.FileName); if(!str.Equals(ti.ExeName, StrUtil.CaseIgnoreCmp)) { Debug.Assert(false); return; } } p.Kill(); p.Close(); } catch(ArgumentException) { } // Not running catch(Exception) { Debug.Assert(false); } } } } KeePass/Util/EmergencySheet.cs0000664000000000000000000003307713224154300015270 0ustar rootroot/* KeePass Password Safe - The Open-Source Password Manager Copyright (C) 2003-2018 Dominik Reichl This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ using System; using System.Collections.Generic; using System.Diagnostics; using System.IO; using System.Text; using System.Windows.Forms; using KeePass.App; using KeePass.Resources; using KeePass.UI; using KeePass.Util.Archive; using KeePassLib; using KeePassLib.Delegates; using KeePassLib.Keys; using KeePassLib.Serialization; using KeePassLib.Utility; namespace KeePass.Util { public static class EmergencySheet { public static void AskCreate(PwDatabase pd) { if((pd == null) || !pd.IsOpen) { Debug.Assert(false); return; } if(!Program.Config.UI.ShowEmSheetDialog) return; string str = KPRes.EmergencySheetInfo + MessageService.NewParagraph + KPRes.EmergencySheetRec + MessageService.NewParagraph + KPRes.EmergencySheetQ; VistaTaskDialog dlg = new VistaTaskDialog(); dlg.CommandLinks = true; dlg.Content = str; dlg.DefaultButtonID = (int)DialogResult.OK; dlg.MainInstruction = KPRes.EmergencySheet; dlg.WindowTitle = PwDefs.ShortProductName; dlg.AddButton((int)DialogResult.OK, KPRes.Print, KPRes.EmergencySheetPrintInfo); dlg.AddButton((int)DialogResult.Cancel, KPRes.Skip, null); dlg.SetIcon(VtdCustomIcon.Question); bool b; if(dlg.ShowDialog()) b = (dlg.Result == (int)DialogResult.OK); else b = MessageService.AskYesNo(str); if(b) Print(pd); } public static void Print(PwDatabase pd) { if((pd == null) || !pd.IsOpen) { Debug.Assert(false); return; } try { string strName = UrlUtil.StripExtension(UrlUtil.GetFileName( pd.IOConnectionInfo.Path)); if(strName.Length == 0) strName = KPRes.Database; string strHtml = GenerateHtml(pd, strName); PrintUtil.PrintHtml(strHtml); } catch(Exception ex) { MessageService.ShowWarning(ex); } } private static string GenerateHtml(PwDatabase pd, string strName) { GFunc h = new GFunc(StrUtil.StringToHtml); GFunc ne = delegate(string str) { if(string.IsNullOrEmpty(str)) return " "; return str; }; StringBuilder sb = new StringBuilder(); bool bRtl = Program.Translation.Properties.RightToLeft; sb.AppendLine(""); sb.Append(""); sb.AppendLine(""); sb.AppendLine(""); sb.Append(""); sb.Append(h(strName + " - " + KPRes.EmergencySheet)); sb.AppendLine(""); sb.AppendLine(""); sb.AppendLine(""); sb.AppendLine(""); sb.AppendLine(""); sb.AppendLine(""); ImageArchive ia = new ImageArchive(); ia.Load(Properties.Resources.Images_App_HighRes); sb.AppendLine(""); sb.AppendLine(""); sb.AppendLine(""); sb.AppendLine(""); sb.AppendLine("
"); sb.AppendLine("\"""); sb.AppendLine("

" + h(PwDefs.ShortProductName) + "

"); sb.AppendLine("

" + h(KPRes.EmergencySheet) + "

"); sb.AppendLine("
"); sb.AppendLine("\""
"); sb.AppendLine("

" + h( TimeUtil.ToDisplayStringDateOnly(DateTime.Now)) + "

"); const string strFillInit = "
"; const string strFillEnd = "
"; string strFillSym = "\"✍\""; string strFill = strFillInit + ne(string.Empty) + // "" + "" + strFillSym + strFillEnd; IOConnectionInfo ioc = pd.IOConnectionInfo; sb.AppendLine("

" + h(KPRes.DatabaseFile) + ":

"); sb.AppendLine(strFillInit + ne(h(ioc.Path)) + strFillEnd); // if(pd.Name.Length > 0) // sb.AppendLine("

" + h(KPRes.Name) + ": " + // h(pd.Name) + "

"); // if(pd.Description.Length > 0) // sb.AppendLine("

" + h(KPRes.Description) + ": " + // h(pd.Description)); sb.AppendLine("

" + h(KPRes.BackupDatabase) + " " + h(KPRes.BackupLocation) + "

"); sb.AppendLine(strFill); CompositeKey ck = pd.MasterKey; if(ck.UserKeyCount > 0) { sb.AppendLine("
"); sb.AppendLine("

" + h(KPRes.MasterKey) + "

"); sb.AppendLine("

" + h(KPRes.MasterKeyComponents) + "

"); sb.AppendLine("
    "); 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("
  • " + h(KPRes.MasterPassword) + ":

    "); sb.AppendLine(strFill + "
  • "); } else if(kf != null) { sb.AppendLine("
  • " + h(KPRes.KeyFile) + ":

    "); sb.AppendLine(strFillInit + ne(h(kf.Path)) + strFillEnd); sb.AppendLine("

    " + h(KPRes.BackupFile) + " " + h(KPRes.BackupLocation) + "

    "); sb.AppendLine(strFill); sb.AppendLine("
  • "); } else if(a != null) { sb.AppendLine("
  • " + h(KPRes.WindowsUserAccount) + ":

    "); 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("

    " + h(KPRes.WindowsUserAccountBackup) + " " + h(KPRes.BackupLocation) + "

    "); sb.AppendLine(strFill + "
  • "); } else if(c != null) { sb.AppendLine("
  • " + h(KPRes.KeyProvider) + ":

    "); sb.AppendLine(strFillInit + ne(h(c.Name)) + strFillEnd); sb.AppendLine("
  • "); } else { Debug.Assert(false); sb.AppendLine("
  • " + h(KPRes.Unknown) + ".

  • "); } } sb.AppendLine("
"); } sb.AppendLine("
"); sb.AppendLine("

" + h(KPRes.InstrAndGenInfo) + "

"); sb.AppendLine("
    "); sb.AppendLine("
  • " + h(KPRes.EmergencySheetInfo) + "
  • "); // sb.AppendLine(""); // sb.AppendLine(""); // sb.AppendLine(""); sb.AppendLine("
  • " + h(KPRes.DataLoss) + "
  • "); sb.AppendLine("
  • " + h(KPRes.LatestVersionWeb) + ": " + h(PwDefs.HomepageUrl) + ".
  • "); sb.AppendLine("
"); sb.AppendLine(""); return sb.ToString(); } } } KeePass/Util/SearchUtil.cs0000664000000000000000000000401113222430416014411 0ustar rootroot/* KeePass Password Safe - The Open-Source Password Manager Copyright (C) 2003-2018 Dominik Reichl This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ using System; using System.Collections.Generic; using System.Text; using System.Diagnostics; using KeePass.Util.Spr; using KeePassLib; namespace KeePass.Util { public static class SearchUtil { internal const string StrTrfDeref = "Deref"; internal static void PrepareForSerialize(SearchParameters sp) { if(sp == null) { Debug.Assert(false); return; } sp.DataTransformation = GetTransformation(sp); } internal static void FinishDeserialize(SearchParameters sp) { if(sp == null) { Debug.Assert(false); return; } SetTransformation(sp, sp.DataTransformation); } internal static string GetTransformation(SearchParameters spIn) { if(spIn == null) { Debug.Assert(false); return string.Empty; } if(spIn.DataTransformationFn == null) return string.Empty; return StrTrfDeref; } internal static void SetTransformation(SearchParameters spOut, string strTrf) { if(spOut == null) { Debug.Assert(false); return; } if(strTrf == null) { Debug.Assert(false); return; } if(strTrf == StrTrfDeref) spOut.DataTransformationFn = SprEngine.DerefFn; else spOut.DataTransformationFn = null; } } } KeePass/Util/IniFile.cs0000664000000000000000000000512513222430416013674 0ustar rootroot/* KeePass Password Safe - The Open-Source Password Manager Copyright (C) 2003-2018 Dominik Reichl This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ using System; using System.Collections.Generic; using System.Text; using System.IO; using System.Diagnostics; using StrDict = System.Collections.Generic.SortedDictionary; namespace KeePass.Util { public sealed class IniFile { private SortedDictionary m_vSections = new SortedDictionary(); public IniFile() { } public static IniFile Read(string strFile, Encoding enc) { StreamReader sr = null; IniFile ini = new IniFile(); try { sr = new StreamReader(strFile, enc); string strSection = string.Empty; while(true) { string str = sr.ReadLine(); if(str == null) break; // End of stream str = str.Trim(); if(str.Length == 0) continue; if(str.StartsWith("[") && str.EndsWith("]")) strSection = str.Substring(1, str.Length - 2); else { int iSep = str.IndexOf('='); if(iSep < 0) { Debug.Assert(false); } else { string strKey = str.Substring(0, iSep); string strValue = str.Substring(iSep + 1); if(!ini.m_vSections.ContainsKey(strSection)) ini.m_vSections.Add(strSection, new StrDict()); ini.m_vSections[strSection][strKey] = strValue; } } } } finally { if(sr != null) sr.Close(); } return ini; } public string Get(string strSection, string strKey) { if(strSection == null) throw new ArgumentNullException("strSection"); if(strKey == null) throw new ArgumentNullException("strKey"); StrDict dict; if(!m_vSections.TryGetValue(strSection, out dict)) return null; string strValue; if(!dict.TryGetValue(strKey, out strValue)) return null; return strValue; } } } KeePass/Util/PwGeneratorUtil.cs0000664000000000000000000001230713222430416015450 0ustar rootroot/* KeePass Password Safe - The Open-Source Password Manager Copyright (C) 2003-2018 Dominik Reichl This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ using System; using System.Collections.Generic; using System.Diagnostics; using System.Text; using KeePass.Resources; #if !KeePassUAP using KeePass.Util.Spr; #endif using KeePassLib; using KeePassLib.Cryptography.PasswordGenerator; using KeePassLib.Security; using KeePassLib.Utility; namespace KeePass.Util { public static class PwGeneratorUtil { private static string m_strBuiltInSuffix = null; internal static string BuiltInSuffix { get { if(m_strBuiltInSuffix == null) m_strBuiltInSuffix = " (" + KPRes.BuiltIn + ")"; return m_strBuiltInSuffix; } } private static List m_lBuiltIn = null; public static List BuiltInProfiles { get { if(m_lBuiltIn == null) AllocStandardProfiles(); return m_lBuiltIn; } } private static void AllocStandardProfiles() { m_lBuiltIn = new List(); AddStdPattern(KPRes.RandomMacAddress, @"HH\-HH\-HH\-HH\-HH\-HH"); string strHex = KPRes.HexKeyEx; AddStdPattern(strHex.Replace(@"{PARAM}", "40"), @"h{10}"); AddStdPattern(strHex.Replace(@"{PARAM}", "128"), @"h{32}"); AddStdPattern(strHex.Replace(@"{PARAM}", "256"), @"h{64}"); } private static void AddStdPattern(string strName, string strPattern) { PwProfile p = new PwProfile(); p.Name = strName + PwGeneratorUtil.BuiltInSuffix; p.CollectUserEntropy = false; p.GeneratorType = PasswordGeneratorType.Pattern; p.Pattern = strPattern; m_lBuiltIn.Add(p); } /// /// Get a list of all password generator profiles (built-in /// and user-defined ones). /// public static List GetAllProfiles(bool bSort) { List lUser = Program.Config.PasswordGenerator.UserProfiles; // Sort it in the configuration file if(bSort) lUser.Sort(PwGeneratorUtil.CompareProfilesByName); // Remove old built-in profiles by KeePass <= 2.17 for(int i = lUser.Count - 1; i >= 0; --i) { if(IsBuiltInProfile(lUser[i].Name)) lUser.RemoveAt(i); } List l = new List(); l.AddRange(PwGeneratorUtil.BuiltInProfiles); l.AddRange(lUser); if(bSort) l.Sort(PwGeneratorUtil.CompareProfilesByName); return l; } public static bool IsBuiltInProfile(string strName) { if(strName == null) { Debug.Assert(false); return false; } string strWithSuffix = strName + PwGeneratorUtil.BuiltInSuffix; foreach(PwProfile p in PwGeneratorUtil.BuiltInProfiles) { if(p.Name.Equals(strName, StrUtil.CaseIgnoreCmp) || p.Name.Equals(strWithSuffix, StrUtil.CaseIgnoreCmp)) return true; } return false; } public static int CompareProfilesByName(PwProfile a, PwProfile b) { if(a == b) return 0; if(a == null) { Debug.Assert(false); return -1; } if(b == null) { Debug.Assert(false); return 1; } return StrUtil.CompareNaturally(a.Name, b.Name); } #if !KeePassUAP internal static ProtectedString GenerateAcceptable(PwProfile prf, byte[] pbUserEntropy, PwEntry peOptCtx, PwDatabase pdOptCtx) { bool b = false; return GenerateAcceptable(prf, pbUserEntropy, peOptCtx, pdOptCtx, ref b); } internal static ProtectedString GenerateAcceptable(PwProfile prf, byte[] pbUserEntropy, PwEntry peOptCtx, PwDatabase pdOptCtx, ref bool bAcceptAlways) { ProtectedString ps = ProtectedString.Empty; SprContext ctx = new SprContext(peOptCtx, pdOptCtx, SprCompileFlags.NonActive, false, false); bool bAcceptable = false; while(!bAcceptable) { bAcceptable = true; PwGenerator.Generate(out ps, prf, pbUserEntropy, Program.PwGeneratorPool); if(ps == null) { Debug.Assert(false); ps = ProtectedString.Empty; } if(bAcceptAlways) { } else { string str = ps.ReadString(); string strCmp = SprEngine.Compile(str, ctx); if(str != strCmp) { if(prf.GeneratorType == PasswordGeneratorType.CharSet) bAcceptable = false; // Silently try again else { string strText = str + MessageService.NewParagraph + KPRes.GenPwSprVariant + MessageService.NewParagraph + KPRes.GenPwAccept; if(!MessageService.AskYesNo(strText, null, false)) bAcceptable = false; else bAcceptAlways = true; } } } } return ps; } #endif } } KeePass/Util/SendInputEx.cs0000664000000000000000000003541513222430416014570 0ustar rootroot/* KeePass Password Safe - The Open-Source Password Manager Copyright (C) 2003-2018 Dominik Reichl This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ using System; using System.Collections.Generic; using System.Diagnostics; using System.Media; using System.Text; using System.Threading; using System.Windows.Forms; using KeePass.Native; using KeePass.Resources; using KeePass.Util.SendInputExt; using KeePassLib.Utility; namespace KeePass.Util { internal enum SiEventType { None = 0, Key, KeyModifier, Char, Delay, SetDefaultDelay, ClipboardCopy, AppActivate, Beep } internal sealed class SiEvent { public SiEventType Type = SiEventType.None; public int VKey = 0; public bool? ExtendedKey = null; public Keys KeyModifier = Keys.None; public char Char = char.MinValue; public bool? Down = null; public uint Delay = 0; public string Text = null; #if DEBUG // For debugger display public override string ToString() { string str = Enum.GetName(typeof(SiEventType), this.Type); string strSub = null; switch(this.Type) { case SiEventType.Key: strSub = this.VKey.ToString() + " " + this.ExtendedKey.ToString() + " " + this.Down.ToString(); break; case SiEventType.KeyModifier: strSub = this.KeyModifier.ToString() + " " + this.Down.ToString(); break; case SiEventType.Char: strSub = this.Char.ToString() + " " + this.Down.ToString(); break; case SiEventType.Delay: case SiEventType.SetDefaultDelay: strSub = this.Delay.ToString(); break; case SiEventType.ClipboardCopy: case SiEventType.AppActivate: case SiEventType.Beep: strSub = this.Text; break; default: break; } if(!string.IsNullOrEmpty(strSub)) return (str + ": " + strSub); return str; } #endif } public static class SendInputEx { private static CriticalSectionEx g_csSending = new CriticalSectionEx(); private static int m_nCurSending = 0; public static bool IsSending { get { return (m_nCurSending != 0); } } public static void SendKeysWait(string strKeys, bool bObfuscate) { if(strKeys == null) { Debug.Assert(false); return; } List l = Parse(strKeys); if(l.Count == 0) return; if(bObfuscate) SiObf.Obfuscate(l); FixEventSeq(l); bool bUnix = KeePassLib.Native.NativeLib.IsUnix(); ISiEngine si; if(bUnix) si = new SiEngineUnix(); else si = new SiEngineWin(); bool bInter = Program.Config.Integration.AutoTypeAllowInterleaved; if(!bInter) { if(!g_csSending.TryEnter()) return; } Interlocked.Increment(ref m_nCurSending); try { si.Init(); Send(si, l); } finally { try { si.Release(); } catch(Exception) { Debug.Assert(false); } Interlocked.Decrement(ref m_nCurSending); if(!bInter) g_csSending.Exit(); } } private static List Parse(string strSequence) { CharStream cs = new CharStream(strSequence); List l = new List(); string strError = KPRes.AutoTypeSequenceInvalid; Keys kCurKbMods = Keys.None; List lMods = new List(); lMods.Add(Keys.None); while(true) { char ch = cs.ReadChar(); if(ch == char.MinValue) break; if((ch == '+') || (ch == '^') || (ch == '%')) { if(lMods.Count == 0) { Debug.Assert(false); break; } else if(ch == '+') lMods[lMods.Count - 1] |= Keys.Shift; else if(ch == '^') lMods[lMods.Count - 1] |= Keys.Control; else if(ch == '%') lMods[lMods.Count - 1] |= Keys.Alt; else { Debug.Assert(false); } continue; } else if(ch == '(') { lMods.Add(Keys.None); continue; } else if(ch == ')') { if(lMods.Count >= 2) { lMods.RemoveAt(lMods.Count - 1); lMods[lMods.Count - 1] = Keys.None; } else throw new FormatException(strError); continue; } Keys kEffMods = Keys.None; foreach(Keys k in lMods) kEffMods |= k; EnsureKeyModifiers(kEffMods, ref kCurKbMods, l); if(ch == '{') { List lSub = ParseSpecial(cs); if(lSub == null) throw new FormatException(strError); l.AddRange(lSub); } else if(ch == '}') throw new FormatException(strError); else if(ch == '~') { SiEvent si = new SiEvent(); si.Type = SiEventType.Key; si.VKey = (int)Keys.Enter; l.Add(si); } else { SiEvent si = new SiEvent(); si.Type = SiEventType.Char; si.Char = ch; l.Add(si); } lMods[lMods.Count - 1] = Keys.None; } EnsureKeyModifiers(Keys.None, ref kCurKbMods, l); return l; } private static void EnsureKeyModifiers(Keys kReqMods, ref Keys kCurKbMods, List l) { if(kReqMods == kCurKbMods) return; if((kReqMods & Keys.Shift) != (kCurKbMods & Keys.Shift)) { SiEvent si = new SiEvent(); si.Type = SiEventType.KeyModifier; si.KeyModifier = Keys.Shift; si.Down = ((kReqMods & Keys.Shift) != Keys.None); l.Add(si); } if((kReqMods & Keys.Control) != (kCurKbMods & Keys.Control)) { SiEvent si = new SiEvent(); si.Type = SiEventType.KeyModifier; si.KeyModifier = Keys.Control; si.Down = ((kReqMods & Keys.Control) != Keys.None); l.Add(si); } if((kReqMods & Keys.Alt) != (kCurKbMods & Keys.Alt)) { SiEvent si = new SiEvent(); si.Type = SiEventType.KeyModifier; si.KeyModifier = Keys.Alt; si.Down = ((kReqMods & Keys.Alt) != Keys.None); l.Add(si); } kCurKbMods = kReqMods; } private static List ParseSpecial(CharStream cs) { // Skip leading white space while(true) { char ch = cs.PeekChar(); if(ch == char.MinValue) { Debug.Assert(false); return null; } if(!char.IsWhiteSpace(ch)) break; cs.ReadChar(); } // First char is *always* part of the name (support for "{{}", etc.) char chFirst = cs.ReadChar(); if(chFirst == char.MinValue) { Debug.Assert(false); return null; } int iPart = 0; StringBuilder sbName = new StringBuilder(), sbParams = new StringBuilder(); sbName.Append(chFirst); while(true) { char ch = cs.ReadChar(); if(ch == char.MinValue) { Debug.Assert(false); return null; } if(ch == '}') break; if(iPart == 0) { if(char.IsWhiteSpace(ch)) ++iPart; else sbName.Append(ch); } else sbParams.Append(ch); } string strName = sbName.ToString(); string strParams = sbParams.ToString().Trim(); uint? ouParam = null; if(strParams.Length > 0) { uint uParamTry; if(uint.TryParse(strParams, out uParamTry)) ouParam = uParamTry; } List l = new List(); if(strName.Equals("DELAY", StrUtil.CaseIgnoreCmp)) { if(!ouParam.HasValue) { Debug.Assert(false); return null; } SiEvent si = new SiEvent(); si.Type = SiEventType.Delay; si.Delay = ouParam.Value; l.Add(si); return l; } if(strName.StartsWith("DELAY=", StrUtil.CaseIgnoreCmp)) { SiEvent si = new SiEvent(); si.Type = SiEventType.SetDefaultDelay; string strDelay = strName.Substring(6).Trim(); uint uDelay; if(uint.TryParse(strDelay, out uDelay)) si.Delay = uDelay; else { Debug.Assert(false); return null; } l.Add(si); return l; } if(strName.Equals("VKEY", StrUtil.CaseIgnoreCmp) || strName.Equals("VKEY-NX", StrUtil.CaseIgnoreCmp) || strName.Equals("VKEY-EX", StrUtil.CaseIgnoreCmp)) { if(!ouParam.HasValue) { Debug.Assert(false); return null; } SiEvent si = new SiEvent(); si.Type = SiEventType.Key; si.VKey = (int)ouParam.Value; if(strName.EndsWith("-NX", StrUtil.CaseIgnoreCmp)) si.ExtendedKey = false; else if(strName.EndsWith("-EX", StrUtil.CaseIgnoreCmp)) si.ExtendedKey = true; l.Add(si); return l; } if(strName.Equals("APPACTIVATE", StrUtil.CaseIgnoreCmp)) { SiEvent si = new SiEvent(); si.Type = SiEventType.AppActivate; si.Text = strParams; l.Add(si); return l; } if(strName.Equals("BEEP", StrUtil.CaseIgnoreCmp)) { SiEvent si = new SiEvent(); si.Type = SiEventType.Beep; si.Text = strParams; l.Add(si); return l; } SiCode siCode = SiCodes.Get(strName); SiEvent siTmpl = new SiEvent(); if(siCode != null) { siTmpl.Type = SiEventType.Key; siTmpl.VKey = siCode.VKey; siTmpl.ExtendedKey = siCode.ExtKey; } else if(strName.Length == 1) { siTmpl.Type = SiEventType.Char; siTmpl.Char = strName[0]; } else { throw new FormatException(KPRes.AutoTypeUnknownPlaceholder + MessageService.NewLine + @"{" + strName + @"}"); } uint uRepeat = 1; if(ouParam.HasValue) uRepeat = ouParam.Value; for(uint u = 0; u < uRepeat; ++u) { SiEvent si = new SiEvent(); si.Type = siTmpl.Type; si.VKey = siTmpl.VKey; si.ExtendedKey = siTmpl.ExtendedKey; si.Char = siTmpl.Char; l.Add(si); } return l; } private static void FixEventSeq(List l) { // Convert chars to keys // Keys kMod = Keys.None; for(int i = 0; i < l.Count; ++i) { SiEvent si = l[i]; SiEventType t = si.Type; // if(t == SiEventType.KeyModifier) // { // if(!si.Down.HasValue) { Debug.Assert(false); continue; } // if(si.Down.Value) // { // Debug.Assert((kMod & si.KeyModifier) == Keys.None); // kMod |= si.KeyModifier; // } // else // { // Debug.Assert((kMod & si.KeyModifier) == si.KeyModifier); // kMod &= ~si.KeyModifier; // } // } if(t == SiEventType.Char) { // bool bLightConv = (kMod == Keys.None); int iVKey = SiCodes.CharToVKey(si.Char, true); if(iVKey > 0) { si.Type = SiEventType.Key; si.VKey = iVKey; } } } } private static void Send(ISiEngine siEngine, List l) { bool bHasClipOp = l.Exists(SendInputEx.IsClipboardOp); ClipboardEventChainBlocker cev = null; ClipboardContents cnt = null; if(bHasClipOp) { cev = new ClipboardEventChainBlocker(); cnt = new ClipboardContents(true, true); } try { SendPriv(siEngine, l); } finally { if(bHasClipOp) { ClipboardUtil.Clear(); cnt.SetData(); cev.Dispose(); } } } private static bool IsClipboardOp(SiEvent si) { if(si == null) { Debug.Assert(false); return false; } return (si.Type == SiEventType.ClipboardCopy); } private static void SendPriv(ISiEngine siEngine, List l) { // For 2000 alphanumeric characters: // * KeePass 1.26: 0:31 min // * KeePass 2.24: 1:58 min // * New engine of KeePass 2.25 with default delay DD: // * DD = 1: 0:31 min // * DD = 31: 1:03 min // * DD = 32: 1:34 min // * DD = 33: 1:34 min // * DD = 43: 1:34 min // * DD = 46: 1:34 min // * DD = 47: 2:05 min // * DD = 49: 2:05 min // * DD = 59: 2:05 min uint uDefaultDelay = 33; // Slice boundary + 1 // Induced by SiEngineWin.TrySendCharByKeypresses uDefaultDelay += 2; int iDefOvr = Program.Config.Integration.AutoTypeInterKeyDelay; if(iDefOvr >= 0) { if(iDefOvr == 0) iDefOvr = 1; // 1 ms is minimum uDefaultDelay = (uint)iDefOvr; } bool bFirstInput = true; foreach(SiEvent si in l) { // Also delay key modifiers, as a workaround for applications // with broken time-dependent message processing; // https://sourceforge.net/p/keepass/bugs/1213/ if((si.Type == SiEventType.Key) || (si.Type == SiEventType.Char) || (si.Type == SiEventType.KeyModifier)) { if(!bFirstInput) siEngine.Delay(uDefaultDelay); bFirstInput = false; } switch(si.Type) { case SiEventType.Key: siEngine.SendKey(si.VKey, si.ExtendedKey, si.Down); break; case SiEventType.KeyModifier: if(si.Down.HasValue) siEngine.SetKeyModifier(si.KeyModifier, si.Down.Value); else { Debug.Assert(false); } break; case SiEventType.Char: siEngine.SendChar(si.Char, si.Down); break; case SiEventType.Delay: siEngine.Delay(si.Delay); break; case SiEventType.SetDefaultDelay: uDefaultDelay = si.Delay; break; case SiEventType.ClipboardCopy: if(!string.IsNullOrEmpty(si.Text)) ClipboardUtil.Copy(si.Text, false, false, null, null, IntPtr.Zero); else if(si.Text != null) ClipboardUtil.Clear(); break; case SiEventType.AppActivate: AppActivate(si); break; case SiEventType.Beep: Beep(si); break; default: Debug.Assert(false); break; } // Extra delay after tabs if(((si.Type == SiEventType.Key) && (si.VKey == (int)Keys.Tab)) || ((si.Type == SiEventType.Char) && (si.Char == '\t'))) { if(uDefaultDelay < 100) siEngine.Delay(uDefaultDelay); } } } private static void AppActivate(SiEvent si) { try { if(string.IsNullOrEmpty(si.Text)) return; IntPtr h = NativeMethods.FindWindow(si.Text); if(h != IntPtr.Zero) NativeMethods.EnsureForegroundWindow(h); } catch(Exception) { Debug.Assert(false); } } private static void Beep(SiEvent si) { try { string str = si.Text; if(string.IsNullOrEmpty(str)) { SystemSounds.Beep.Play(); return; } string[] v = str.Split(new char[] { ' ', '\t' }, StringSplitOptions.RemoveEmptyEntries); int f = 800, d = 200; // Defaults of Console.Beep() if(v.Length >= 1) int.TryParse(v[0], out f); if(v.Length >= 2) int.TryParse(v[1], out d); f = Math.Min(Math.Max(f, 37), 32767); if(d <= 0) return; Console.Beep(f, d); // Throws on a server } catch(Exception) { Debug.Assert(false); } } } } KeePass/Util/GlobalMutexPool.cs0000664000000000000000000001375313222430416015440 0ustar rootroot/* KeePass Password Safe - The Open-Source Password Manager Copyright (C) 2003-2018 Dominik Reichl This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ using System; using System.Collections.Generic; using System.Text; using System.Threading; using System.IO; using System.Security.Cryptography; using System.Diagnostics; using KeePassLib.Native; using KeePassLib.Utility; namespace KeePass.Util { /// /// Low performance, system-wide mutex objects pool. /// public static class GlobalMutexPool { private static List> m_vMutexesWin = new List>(); private static List> m_vMutexesUnix = new List>(); private static int m_iLastRefresh = 0; private const double GmpMutexValidSecs = 190.0; private const int GmpMutexRefreshMs = 60 * 1000; private static readonly byte[] GmpOptEnt = { 0x08, 0xA6, 0x5E, 0x40 }; public static bool CreateMutex(string strName, bool bInitiallyOwned) { if(!NativeLib.IsUnix()) // Windows return CreateMutexWin(strName, bInitiallyOwned); return CreateMutexUnix(strName, bInitiallyOwned); } private static bool CreateMutexWin(string strName, bool bInitiallyOwned) { try { bool bCreatedNew; Mutex m = new Mutex(bInitiallyOwned, strName, out bCreatedNew); if(bCreatedNew) { m_vMutexesWin.Add(new KeyValuePair(strName, m)); return true; } } catch(Exception) { } return false; } private static bool CreateMutexUnix(string strName, bool bInitiallyOwned) { string strPath = GetMutexPath(strName); try { if(File.Exists(strPath)) { byte[] pbEnc = File.ReadAllBytes(strPath); byte[] pb = ProtectedData.Unprotect(pbEnc, GmpOptEnt, DataProtectionScope.CurrentUser); if(pb.Length == 12) { long lTime = MemUtil.BytesToInt64(pb, 0); DateTime dt = DateTime.FromBinary(lTime); if((DateTime.UtcNow - dt).TotalSeconds < GmpMutexValidSecs) { int pid = MemUtil.BytesToInt32(pb, 8); try { Process.GetProcessById(pid); // Throws if process is not running return false; // Actively owned by other process } catch(Exception) { } } // Release the old mutex since process is not running ReleaseMutexUnix(strName); } else { Debug.Assert(false); } } } catch(Exception) { Debug.Assert(false); } try { WriteMutexFilePriv(strPath); } catch(Exception) { Debug.Assert(false); } m_vMutexesUnix.Add(new KeyValuePair(strName, strPath)); return true; } private static void WriteMutexFilePriv(string strPath) { byte[] pb = new byte[12]; MemUtil.Int64ToBytes(DateTime.UtcNow.ToBinary()).CopyTo(pb, 0); MemUtil.Int32ToBytes(Process.GetCurrentProcess().Id).CopyTo(pb, 8); byte[] pbEnc = ProtectedData.Protect(pb, GmpOptEnt, DataProtectionScope.CurrentUser); File.WriteAllBytes(strPath, pbEnc); } public static bool ReleaseMutex(string strName) { if(!NativeLib.IsUnix()) // Windows return ReleaseMutexWin(strName); return ReleaseMutexUnix(strName); } private static bool ReleaseMutexWin(string strName) { for(int i = 0; i < m_vMutexesWin.Count; ++i) { if(m_vMutexesWin[i].Key.Equals(strName, StrUtil.CaseIgnoreCmp)) { try { m_vMutexesWin[i].Value.ReleaseMutex(); } catch(Exception) { Debug.Assert(false); } try { m_vMutexesWin[i].Value.Close(); } catch(Exception) { Debug.Assert(false); } m_vMutexesWin.RemoveAt(i); return true; } } return false; } private static bool ReleaseMutexUnix(string strName) { for(int i = 0; i < m_vMutexesUnix.Count; ++i) { if(m_vMutexesUnix[i].Key.Equals(strName, StrUtil.CaseIgnoreCmp)) { for(int r = 0; r < 12; ++r) { try { if(!File.Exists(m_vMutexesUnix[i].Value)) break; File.Delete(m_vMutexesUnix[i].Value); break; } catch(Exception) { } Thread.Sleep(10); } m_vMutexesUnix.RemoveAt(i); return true; } } return false; } public static void ReleaseAll() { if(!NativeLib.IsUnix()) // Windows { for(int i = m_vMutexesWin.Count - 1; i >= 0; --i) ReleaseMutexWin(m_vMutexesWin[i].Key); } else { for(int i = m_vMutexesUnix.Count - 1; i >= 0; --i) ReleaseMutexUnix(m_vMutexesUnix[i].Key); } } public static void Refresh() { if(!NativeLib.IsUnix()) return; // Windows, no refresh required // Unix int iTicksDiff = (Environment.TickCount - m_iLastRefresh); if(iTicksDiff >= GmpMutexRefreshMs) { m_iLastRefresh = Environment.TickCount; for(int i = 0; i < m_vMutexesUnix.Count; ++i) { try { WriteMutexFilePriv(m_vMutexesUnix[i].Value); } catch(Exception) { Debug.Assert(false); } } } } private static string GetMutexPath(string strName) { string strDir = UrlUtil.EnsureTerminatingSeparator( UrlUtil.GetTempPath(), false); return (strDir + IpcUtilEx.IpcMsgFilePreID + IpcBroadcast.GetUserID() + "-Mutex-" + strName + ".tmp"); } } } KeePass/Util/XmlUtil.cs0000664000000000000000000003112413222430420013744 0ustar rootroot/* KeePass Password Safe - The Open-Source Password Manager Copyright (C) 2003-2018 Dominik Reichl This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ using System; using System.Collections.Generic; using System.Text; using System.Xml; using System.Xml.Serialization; using System.Reflection; using System.Windows.Forms; using System.Diagnostics; using KeePass.Util.XmlSerialization; using KeePassLib.Utility; namespace KeePass.Util { public static partial class XmlUtil { public static string SafeInnerText(XmlNode xmlNode) { Debug.Assert(xmlNode != null); if(xmlNode == null) return string.Empty; return (xmlNode.InnerText ?? string.Empty); } public static string SafeInnerText(XmlNode xmlNode, string strNewLineCode) { if(string.IsNullOrEmpty(strNewLineCode)) return SafeInnerText(xmlNode); string strInner = SafeInnerText(xmlNode); return strInner.Replace(strNewLineCode, "\r\n"); } public static string SafeInnerXml(XmlNode xmlNode) { Debug.Assert(xmlNode != null); if(xmlNode == null) return string.Empty; return (xmlNode.InnerXml ?? string.Empty); } public static string SafeInnerText(HtmlElement htmlNode) { Debug.Assert(htmlNode != null); if(htmlNode == null) return string.Empty; return (htmlNode.InnerText ?? string.Empty); } public static string SafeAttribute(HtmlElement htmlNode, string strName) { if(htmlNode == null) { Debug.Assert(false); return string.Empty; } if(string.IsNullOrEmpty(strName)) { Debug.Assert(false); return string.Empty; } string strValue = (htmlNode.GetAttribute(strName) ?? string.Empty); // https://msdn.microsoft.com/en-us/library/ie/ms536429.aspx if((strValue.Length == 0) && strName.Equals("class", StrUtil.CaseIgnoreCmp)) strValue = (htmlNode.GetAttribute("className") ?? string.Empty); return strValue; } private static Dictionary m_dHtmlEntities = null; /// /// Decode common HTML entities except the XML ones (<, >, etc.). /// /// String to decode. /// String without non-standard entities. public static string DecodeHtmlEntities(string strXml) { if(strXml == null) { Debug.Assert(false); return string.Empty; } if(m_dHtmlEntities == null) { Dictionary d = new Dictionary(); d["nbsp"] = '\u00A0'; d["iexcl"] = '\u00A1'; d["cent"] = '\u00A2'; d["pound"] = '\u00A3'; d["curren"] = '\u00A4'; d["yen"] = '\u00A5'; d["brvbar"] = '\u00A6'; d["sect"] = '\u00A7'; d["uml"] = '\u00A8'; d["copy"] = '\u00A9'; d["ordf"] = '\u00AA'; d["laquo"] = '\u00AB'; d["not"] = '\u00AC'; d["shy"] = '\u00AD'; d["reg"] = '\u00AE'; d["macr"] = '\u00AF'; d["deg"] = '\u00B0'; d["plusmn"] = '\u00B1'; d["sup2"] = '\u00B2'; d["sup3"] = '\u00B3'; d["acute"] = '\u00B4'; d["micro"] = '\u00B5'; d["para"] = '\u00B6'; d["middot"] = '\u00B7'; d["cedil"] = '\u00B8'; d["sup1"] = '\u00B9'; d["ordm"] = '\u00BA'; d["raquo"] = '\u00BB'; d["frac14"] = '\u00BC'; d["frac12"] = '\u00BD'; d["frac34"] = '\u00BE'; d["iquest"] = '\u00BF'; d["Agrave"] = '\u00C0'; d["Aacute"] = '\u00C1'; d["Acirc"] = '\u00C2'; d["Atilde"] = '\u00C3'; d["Auml"] = '\u00C4'; d["Aring"] = '\u00C5'; d["AElig"] = '\u00C6'; d["Ccedil"] = '\u00C7'; d["Egrave"] = '\u00C8'; d["Eacute"] = '\u00C9'; d["Ecirc"] = '\u00CA'; d["Euml"] = '\u00CB'; d["Igrave"] = '\u00CC'; d["Iacute"] = '\u00CD'; d["Icirc"] = '\u00CE'; d["Iuml"] = '\u00CF'; d["ETH"] = '\u00D0'; d["Ntilde"] = '\u00D1'; d["Ograve"] = '\u00D2'; d["Oacute"] = '\u00D3'; d["Ocirc"] = '\u00D4'; d["Otilde"] = '\u00D5'; d["Ouml"] = '\u00D6'; d["times"] = '\u00D7'; d["Oslash"] = '\u00D8'; d["Ugrave"] = '\u00D9'; d["Uacute"] = '\u00DA'; d["Ucirc"] = '\u00DB'; d["Uuml"] = '\u00DC'; d["Yacute"] = '\u00DD'; d["THORN"] = '\u00DE'; d["szlig"] = '\u00DF'; d["agrave"] = '\u00E0'; d["aacute"] = '\u00E1'; d["acirc"] = '\u00E2'; d["atilde"] = '\u00E3'; d["auml"] = '\u00E4'; d["aring"] = '\u00E5'; d["aelig"] = '\u00E6'; d["ccedil"] = '\u00E7'; d["egrave"] = '\u00E8'; d["eacute"] = '\u00E9'; d["ecirc"] = '\u00EA'; d["euml"] = '\u00EB'; d["igrave"] = '\u00EC'; d["iacute"] = '\u00ED'; d["icirc"] = '\u00EE'; d["iuml"] = '\u00EF'; d["eth"] = '\u00F0'; d["ntilde"] = '\u00F1'; d["ograve"] = '\u00F2'; d["oacute"] = '\u00F3'; d["ocirc"] = '\u00F4'; d["otilde"] = '\u00F5'; d["ouml"] = '\u00F6'; d["divide"] = '\u00F7'; d["oslash"] = '\u00F8'; d["ugrave"] = '\u00F9'; d["uacute"] = '\u00FA'; d["ucirc"] = '\u00FB'; d["uuml"] = '\u00FC'; d["yacute"] = '\u00FD'; d["thorn"] = '\u00FE'; d["yuml"] = '\u00FF'; Debug.Assert(d.Count == (0xFF - 0xA0 + 1)); d["circ"] = '\u02C6'; d["tilde"] = '\u02DC'; d["euro"] = '\u20AC'; m_dHtmlEntities = d; #if DEBUG Dictionary dChars = new Dictionary(); foreach(KeyValuePair kvp in d) { Debug.Assert((kvp.Key.IndexOf('&') < 0) && (kvp.Key.IndexOf(';') < 0)); dChars[kvp.Value] = true; } Debug.Assert(dChars.Count == d.Count); // Injective Debug.Assert(DecodeHtmlEntities("€ A êZ; B ©") == "\u20AC A êZ; B \u00A9"); Debug.Assert(DecodeHtmlEntities(@"<>&'"") == "<>&'""); // Do not decode XML entities Debug.Assert(DecodeHtmlEntities(@"") == "\u20AC"); #endif } StringBuilder sb = new StringBuilder(); List lParts = SplitByCData(strXml); foreach(string str in lParts) { if(str.StartsWith(@" iOffset) sb.Append(str, iOffset, pAmp - iOffset); int pTerm = str.IndexOf(';', pAmp); if(pTerm < 0) { Debug.Assert(false); // At least one entity not terminated sb.Append(str, pAmp, str.Length - pAmp); break; } string strEntity = str.Substring(pAmp + 1, pTerm - pAmp - 1); char ch; if(m_dHtmlEntities.TryGetValue(strEntity, out ch)) sb.Append(ch); else sb.Append(str, pAmp, pTerm - pAmp + 1); iOffset = pTerm + 1; } } return sb.ToString(); } public static List SplitByCData(string str) { List l = new List(); if(str == null) { Debug.Assert(false); return l; } int iOffset = 0; while(iOffset < str.Length) { int pStart = str.IndexOf(@" iOffset) l.Add(str.Substring(iOffset, pStart - iOffset)); const string strTerm = @"]]>"; int pTerm = str.IndexOf(strTerm, pStart); if(pTerm < 0) { Debug.Assert(false); // At least one CDATA not terminated l.Add(str.Substring(pStart, str.Length - pStart)); break; } l.Add(str.Substring(pStart, pTerm - pStart + strTerm.Length)); iOffset = pTerm + strTerm.Length; } Debug.Assert(l.IndexOf(string.Empty) < 0); return l; } public static int GetMultiChildIndex(XmlNodeList xlList, XmlNode xnFind) { if(xlList == null) throw new ArgumentNullException("xlList"); if(xnFind == null) throw new ArgumentNullException("xnFind"); string strChildName = xnFind.Name; int nChildIndex = 0; for(int i = 0; i < xlList.Count; ++i) { if(xlList[i] == xnFind) return nChildIndex; else if(xlList[i].Name == strChildName) ++nChildIndex; } return -1; } public static XmlNode FindMultiChild(XmlNodeList xlList, string strChildName, int nMultiChildIndex) { if(xlList == null) throw new ArgumentNullException("xlList"); if(strChildName == null) throw new ArgumentNullException("strChildName"); int nChildIndex = 0; for(int i = 0; i < xlList.Count; ++i) { if(xlList[i].Name == strChildName) { if(nChildIndex == nMultiChildIndex) return xlList[i]; else ++nChildIndex; } } return null; } public static void MergeNodes(XmlDocument xd, XmlNode xn, XmlNode xnOverride) { if(xd == null) throw new ArgumentNullException("xd"); if(xn == null) throw new ArgumentNullException("xn"); if(xnOverride == null) throw new ArgumentNullException("xnOverride"); Debug.Assert(xn.Name == xnOverride.Name); foreach(XmlNode xnOvrChild in xnOverride.ChildNodes) { if(xnOvrChild.NodeType == XmlNodeType.Comment) continue; Debug.Assert(xnOvrChild.NodeType == XmlNodeType.Element); int nOvrIndex = GetMultiChildIndex(xnOverride.ChildNodes, xnOvrChild); if(nOvrIndex < 0) { Debug.Assert(false); continue; } XmlNode xnRep = FindMultiChild(xn.ChildNodes, xnOvrChild.Name, nOvrIndex); bool bHasSub = (XmlUtil.SafeInnerXml(xnOvrChild).IndexOf('>') >= 0); if(xnRep == null) { if(xnOvrChild.NodeType != XmlNodeType.Element) { Debug.Assert(false); continue; } XmlNode xnNew = xd.CreateElement(xnOvrChild.Name); xn.AppendChild(xnNew); if(!bHasSub) xnNew.InnerText = XmlUtil.SafeInnerText(xnOvrChild); else MergeNodes(xd, xnNew, xnOvrChild); } else if(bHasSub) MergeNodes(xd, xnRep, xnOvrChild); else xnRep.InnerText = XmlUtil.SafeInnerText(xnOvrChild); } } private sealed class XuopContainer { private object m_o; public object Object { get { return m_o; } } public XuopContainer(object o) { m_o = o; } } private const string GoxpSep = "/"; public static string GetObjectXmlPath(object oContainer, object oNeedle) { if(oContainer == null) { Debug.Assert(false); return null; } XuopContainer c = new XuopContainer(oContainer); string strXPath = GetObjectXmlPathRec(c, typeof(XuopContainer), oNeedle, string.Empty); if(string.IsNullOrEmpty(strXPath)) return strXPath; if(!strXPath.StartsWith("/Object")) { Debug.Assert(false); return null; } strXPath = strXPath.Substring(7); Type tRoot = oContainer.GetType(); string strRoot = XmlSerializerEx.GetXmlName(tRoot); return (GoxpSep + strRoot + strXPath); } private static string GetObjectXmlPathRec(object oContainer, Type tContainer, object oNeedle, string strCurPath) { if(oContainer == null) { Debug.Assert(false); return null; } if(oNeedle == null) { Debug.Assert(false); return null; } Debug.Assert(oContainer.GetType() == tContainer); PropertyInfo[] vProps = tContainer.GetProperties(); foreach(PropertyInfo pi in vProps) { if((pi == null) || !pi.CanRead) continue; object[] vPropAttribs = pi.GetCustomAttributes(true); if(XmlSerializerEx.GetAttribute( vPropAttribs) != null) continue; object oSub = pi.GetValue(oContainer, null); if(oSub == null) continue; string strPropName = XmlSerializerEx.GetXmlName(pi); string strSubPath = strCurPath + GoxpSep + strPropName; if(oSub == oNeedle) return strSubPath; Type tSub = oSub.GetType(); string strPrimarySubType; string strPropTypeCS = XmlSerializerEx.GetFullTypeNameCS(tSub, out strPrimarySubType); if(XmlSerializerEx.TypeIsArray(strPropTypeCS) || XmlSerializerEx.TypeIsList(strPropTypeCS)) continue; if(strPropTypeCS.StartsWith("System.")) continue; string strSubFound = GetObjectXmlPathRec(oSub, tSub, oNeedle, strSubPath); if(strSubFound != null) return strSubFound; } return null; } } } KeePass/Util/AppLocator.cs0000664000000000000000000003074613222430416014430 0ustar rootroot/* KeePass Password Safe - The Open-Source Password Manager Copyright (C) 2003-2018 Dominik Reichl This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ using System; using System.Collections; using System.Collections.Generic; using System.Text; using System.IO; using System.Diagnostics; using Microsoft.Win32; using KeePass.Util.Spr; using KeePassLib.Native; using KeePassLib.Security; using KeePassLib.Utility; namespace KeePass.Util { public static class AppLocator { private const int BrwIE = 0; private const int BrwFirefox = 1; private const int BrwOpera = 2; private const int BrwChrome = 3; private const int BrwSafari = 4; private const int BrwEdge = 5; private static Dictionary m_dictPaths = new Dictionary(); public static string InternetExplorerPath { get { return GetPath(BrwIE, FindInternetExplorer); } } public static string FirefoxPath { get { return GetPath(BrwFirefox, FindFirefox); } } public static string OperaPath { get { return GetPath(BrwOpera, FindOpera); } } public static string ChromePath { get { return GetPath(BrwChrome, FindChrome); } } public static string SafariPath { get { return GetPath(BrwSafari, FindSafari); } } /// /// Edge executable cannot be run normally. /// public static string EdgePath { get { return GetPath(BrwEdge, FindEdge); } } private static bool? m_obEdgeProtocol = null; public static bool EdgeProtocolSupported { get { if(m_obEdgeProtocol.HasValue) return m_obEdgeProtocol.Value; bool b = false; RegistryKey rk = null; try { rk = Registry.ClassesRoot.OpenSubKey( "microsoft-edge", false); if(rk != null) b = (rk.GetValue("URL Protocol") != null); } catch(Exception) { Debug.Assert(NativeLib.IsUnix()); } finally { if(rk != null) rk.Close(); } m_obEdgeProtocol = b; return b; } } private delegate string FindAppDelegate(); private static string GetPath(int iBrwID, FindAppDelegate f) { string strPath; if(m_dictPaths.TryGetValue(iBrwID, out strPath)) return strPath; try { strPath = f(); if((strPath != null) && (strPath.Length == 0)) strPath = null; } catch(Exception) { strPath = null; } m_dictPaths[iBrwID] = strPath; return strPath; } public static string FillPlaceholders(string strText, SprContext ctx) { string str = strText; str = AppLocator.ReplacePath(str, @"{INTERNETEXPLORER}", AppLocator.InternetExplorerPath, ctx); str = AppLocator.ReplacePath(str, @"{FIREFOX}", AppLocator.FirefoxPath, ctx); str = AppLocator.ReplacePath(str, @"{OPERA}", AppLocator.OperaPath, ctx); str = AppLocator.ReplacePath(str, @"{GOOGLECHROME}", AppLocator.ChromePath, ctx); str = AppLocator.ReplacePath(str, @"{SAFARI}", AppLocator.SafariPath, ctx); // Edge executable cannot be run normally return str; } private static string ReplacePath(string str, string strPlaceholder, string strFill, SprContext ctx) { if(str == null) { Debug.Assert(false); return string.Empty; } if(strPlaceholder == null) { Debug.Assert(false); return str; } if(strPlaceholder.Length == 0) { Debug.Assert(false); return str; } if(strFill == null) return str; // No assert string strRep; if((ctx != null) && ctx.EncodeForCommandLine) strRep = "\"" + SprEngine.TransformContent(strFill, ctx) + "\""; else strRep = SprEngine.TransformContent("\"" + strFill + "\"", ctx); return StrUtil.ReplaceCaseInsensitive(str, strPlaceholder, strRep); } private static string FindInternetExplorer() { const string strIEDef = "SOFTWARE\\Clients\\StartMenuInternet\\IEXPLORE.EXE\\shell\\open\\command"; const string strIEWow = "SOFTWARE\\Wow6432Node\\Clients\\StartMenuInternet\\IEXPLORE.EXE\\shell\\open\\command"; for(int i = 0; i < 6; ++i) { RegistryKey k = null; // https://msdn.microsoft.com/en-us/library/windows/desktop/dd203067.aspx if(i == 0) k = Registry.CurrentUser.OpenSubKey(strIEDef, false); else if(i == 1) k = Registry.CurrentUser.OpenSubKey(strIEWow, false); else if(i == 2) k = Registry.LocalMachine.OpenSubKey(strIEDef, false); else if(i == 3) k = Registry.LocalMachine.OpenSubKey(strIEWow, false); else if(i == 4) k = Registry.ClassesRoot.OpenSubKey( "IE.AssocFile.HTM\\shell\\open\\command", false); else k = Registry.ClassesRoot.OpenSubKey( "Applications\\iexplore.exe\\shell\\open\\command", false); if(k == null) continue; string str = (k.GetValue(string.Empty) as string); k.Close(); if(str == null) continue; str = UrlUtil.GetQuotedAppPath(str).Trim(); if(str.Length == 0) continue; // https://sourceforge.net/p/keepass/discussion/329221/thread/6b292ede/ if(str.StartsWith("iexplore.exe", StrUtil.CaseIgnoreCmp)) continue; return str; } return null; } private static string FindFirefox() { if(NativeLib.IsUnix()) return FindAppUnix("firefox"); try { string strPath = FindFirefoxWin(false); if(!string.IsNullOrEmpty(strPath)) return strPath; } catch(Exception) { } return FindFirefoxWin(true); } private static string FindFirefoxWin(bool bWowNode) { RegistryKey kFirefox = Registry.LocalMachine.OpenSubKey(bWowNode ? "SOFTWARE\\Wow6432Node\\Mozilla\\Mozilla Firefox" : "SOFTWARE\\Mozilla\\Mozilla Firefox", false); if(kFirefox == null) return null; string strCurVer = (kFirefox.GetValue("CurrentVersion") as string); if(string.IsNullOrEmpty(strCurVer)) { // The ESR version stores the 'CurrentVersion' value under // 'Mozilla Firefox ESR', but the version-specific info // under 'Mozilla Firefox\\' (without 'ESR') RegistryKey kESR = Registry.LocalMachine.OpenSubKey(bWowNode ? "SOFTWARE\\Wow6432Node\\Mozilla\\Mozilla Firefox ESR" : "SOFTWARE\\Mozilla\\Mozilla Firefox ESR", false); if(kESR != null) { strCurVer = (kESR.GetValue("CurrentVersion") as string); kESR.Close(); } if(string.IsNullOrEmpty(strCurVer)) { kFirefox.Close(); return null; } } RegistryKey kMain = kFirefox.OpenSubKey(strCurVer + "\\Main", false); if(kMain == null) { Debug.Assert(false); kFirefox.Close(); return null; } string strPath = (kMain.GetValue("PathToExe") as string); if(!string.IsNullOrEmpty(strPath)) { strPath = strPath.Trim(); strPath = UrlUtil.GetQuotedAppPath(strPath).Trim(); } else { Debug.Assert(false); } kMain.Close(); kFirefox.Close(); return strPath; } private static string FindOpera() { if(NativeLib.IsUnix()) return FindAppUnix("opera"); // Old Opera versions const string strOp12 = "SOFTWARE\\Clients\\StartMenuInternet\\Opera\\shell\\open\\command"; // Opera >= 20.0.1387.77 const string strOp20 = "SOFTWARE\\Clients\\StartMenuInternet\\OperaStable\\shell\\open\\command"; for(int i = 0; i < 5; ++i) { RegistryKey k = null; // https://msdn.microsoft.com/en-us/library/windows/desktop/dd203067.aspx if(i == 0) k = Registry.CurrentUser.OpenSubKey(strOp20, false); else if(i == 1) k = Registry.CurrentUser.OpenSubKey(strOp12, false); else if(i == 2) k = Registry.LocalMachine.OpenSubKey(strOp20, false); else if(i == 3) k = Registry.LocalMachine.OpenSubKey(strOp12, false); else // Old Opera versions k = Registry.ClassesRoot.OpenSubKey( "Opera.HTML\\shell\\open\\command", false); if(k == null) continue; string strPath = (k.GetValue(string.Empty) as string); if(!string.IsNullOrEmpty(strPath)) strPath = UrlUtil.GetQuotedAppPath(strPath).Trim(); else { Debug.Assert(false); } k.Close(); if(!string.IsNullOrEmpty(strPath)) return strPath; } return null; } private static string FindChrome() { if(NativeLib.IsUnix()) { string str = FindAppUnix("google-chrome"); if(!string.IsNullOrEmpty(str)) return str; return FindAppUnix("chromium-browser"); } string strPath = FindChromeNew(); if(string.IsNullOrEmpty(strPath)) strPath = FindChromeOld(); return strPath; } // HKEY_CLASSES_ROOT\\ChromeHTML[.ID]\\shell\\open\\command private static string FindChromeNew() { RegistryKey kHtml = Registry.ClassesRoot.OpenSubKey("ChromeHTML", false); if(kHtml == null) // New versions append an ID { string[] vKeys = Registry.ClassesRoot.GetSubKeyNames(); foreach(string strEnum in vKeys) { if(strEnum.StartsWith("ChromeHTML.", StrUtil.CaseIgnoreCmp)) { kHtml = Registry.ClassesRoot.OpenSubKey(strEnum, false); break; } } if(kHtml == null) return null; } RegistryKey kCommand = kHtml.OpenSubKey("shell\\open\\command", false); if(kCommand == null) { Debug.Assert(false); kHtml.Close(); return null; } string strPath = (kCommand.GetValue(string.Empty) as string); if(!string.IsNullOrEmpty(strPath)) { strPath = strPath.Trim(); strPath = UrlUtil.GetQuotedAppPath(strPath).Trim(); } else { Debug.Assert(false); } kCommand.Close(); kHtml.Close(); return strPath; } // HKEY_CLASSES_ROOT\\Applications\\chrome.exe\\shell\\open\\command private static string FindChromeOld() { RegistryKey kCommand = Registry.ClassesRoot.OpenSubKey( "Applications\\chrome.exe\\shell\\open\\command", false); if(kCommand == null) return null; string strPath = (kCommand.GetValue(string.Empty) as string); if(!string.IsNullOrEmpty(strPath)) { strPath = strPath.Trim(); strPath = UrlUtil.GetQuotedAppPath(strPath).Trim(); } else { Debug.Assert(false); } kCommand.Close(); return strPath; } // HKEY_LOCAL_MACHINE\\SOFTWARE\\Apple Computer, Inc.\\Safari\\BrowserExe private static string FindSafari() { RegistryKey kSafari = Registry.LocalMachine.OpenSubKey( "SOFTWARE\\Apple Computer, Inc.\\Safari", false); if(kSafari == null) return null; string strPath = (kSafari.GetValue("BrowserExe") as string); if(!string.IsNullOrEmpty(strPath)) { strPath = strPath.Trim(); strPath = UrlUtil.GetQuotedAppPath(strPath).Trim(); } else { Debug.Assert(false); } kSafari.Close(); return strPath; } private static string FindEdge() { string strSys = Environment.SystemDirectory.TrimEnd( UrlUtil.LocalDirSepChar); if(strSys.EndsWith("32")) strSys = strSys.Substring(0, strSys.Length - 2); strSys += "Apps"; if(!Directory.Exists(strSys)) return null; string[] vEdgeDirs = Directory.GetDirectories(strSys, "Microsoft.MicrosoftEdge*", SearchOption.TopDirectoryOnly); if(vEdgeDirs == null) { Debug.Assert(false); return null; } foreach(string strEdgeDir in vEdgeDirs) { string strExe = UrlUtil.EnsureTerminatingSeparator( strEdgeDir, false) + "MicrosoftEdge.exe"; if(File.Exists(strExe)) return strExe; } return null; } public static string FindAppUnix(string strApp) { string strArgPrefix = "-b "; if(NativeLib.GetPlatformID() == PlatformID.MacOSX) strArgPrefix = string.Empty; // FR 3535696 string str = NativeLib.RunConsoleApp("whereis", strArgPrefix + strApp); if(str == null) return null; str = str.Trim(); int iPrefix = str.IndexOf(':'); if(iPrefix >= 0) str = str.Substring(iPrefix + 1).Trim(); int iSep = str.IndexOfAny(new char[]{ ' ', '\t', '\r', '\n' }); if(iSep >= 0) str = str.Substring(0, iSep); return ((str.Length > 0) ? str : null); } } } KeePass/Util/BinaryDataClassifier.cs0000664000000000000000000001252113222430416016376 0ustar rootroot/* KeePass Password Safe - The Open-Source Password Manager Copyright (C) 2003-2018 Dominik Reichl This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ using System; using System.Collections.Generic; using System.Text; using System.Diagnostics; using System.Drawing; using System.IO; using KeePass.Resources; using KeePassLib.Utility; namespace KeePass.Util { public enum BinaryDataClass { Unknown = 0, Text, RichText, Image, WebDocument } public static class BinaryDataClassifier { private static readonly string[] m_vTextExtensions = new string[] { "txt", "csv", "c", "cpp", "h", "hpp", "css", "js", "bat", "ps1" }; private static readonly string[] m_vRichTextExtensions = new string[] { "rtf" }; private static readonly string[] m_vImageExtensions = new string[] { "bmp", "emf", "exif", "gif", "ico", "jpeg", "jpe", "jpg", "png", "tiff", "tif", "wmf" }; private static readonly string[] m_vWebExtensions = new string[] { "htm", "html" // The following types can be displayed by Internet Explorer, // but not by the WebBrowser control // "mht", "xml", "xslt" }; public static BinaryDataClass ClassifyUrl(string strUrl) { Debug.Assert(strUrl != null); if(strUrl == null) throw new ArgumentNullException("strUrl"); string str = strUrl.Trim().ToLower(); foreach(string strTextExt in m_vTextExtensions) { if(str.EndsWith("." + strTextExt)) return BinaryDataClass.Text; } foreach(string strRichTextExt in m_vRichTextExtensions) { if(str.EndsWith("." + strRichTextExt)) return BinaryDataClass.RichText; } foreach(string strImageExt in m_vImageExtensions) { if(str.EndsWith("." + strImageExt)) return BinaryDataClass.Image; } foreach(string strWebExt in m_vWebExtensions) { if(str.EndsWith("." + strWebExt)) return BinaryDataClass.WebDocument; } return BinaryDataClass.Unknown; } public static BinaryDataClass ClassifyData(byte[] pbData) { Debug.Assert(pbData != null); if(pbData == null) throw new ArgumentNullException("pbData"); try { Image img = GfxUtil.LoadImage(pbData); if(img != null) { img.Dispose(); return BinaryDataClass.Image; } } catch(Exception) { } return BinaryDataClass.Unknown; } public static BinaryDataClass Classify(string strUrl, byte[] pbData) { BinaryDataClass bdc = ClassifyUrl(strUrl); if(bdc != BinaryDataClass.Unknown) return bdc; return ClassifyData(pbData); } public static StrEncodingInfo GetStringEncoding(byte[] pbData, out uint uStartOffset) { Debug.Assert(pbData != null); if(pbData == null) throw new ArgumentNullException("pbData"); uStartOffset = 0; List lEncs = new List(StrUtil.Encodings); lEncs.Sort(BinaryDataClassifier.CompareBySigLengthRev); foreach(StrEncodingInfo sei in lEncs) { byte[] pbSig = sei.StartSignature; if((pbSig == null) || (pbSig.Length == 0)) continue; if(pbSig.Length > pbData.Length) continue; byte[] pbStart = MemUtil.Mid(pbData, 0, pbSig.Length); if(MemUtil.ArraysEqual(pbStart, pbSig)) { uStartOffset = (uint)pbSig.Length; return sei; } } if((pbData.Length % 4) == 0) { byte[] z3 = new byte[] { 0, 0, 0 }; int i = MemUtil.IndexOf(pbData, z3); if((i >= 0) && (i < (pbData.Length - 4))) // Ignore last zero char { if((i % 4) == 0) return StrUtil.GetEncoding(StrEncodingType.Utf32BE); if((i % 4) == 1) return StrUtil.GetEncoding(StrEncodingType.Utf32LE); // Don't assume UTF-32 for other offsets } } if((pbData.Length % 2) == 0) { int i = Array.IndexOf(pbData, 0); if((i >= 0) && (i < (pbData.Length - 2))) // Ignore last zero char { if((i % 2) == 0) return StrUtil.GetEncoding(StrEncodingType.Utf16BE); return StrUtil.GetEncoding(StrEncodingType.Utf16LE); } } try { UTF8Encoding utf8Throw = new UTF8Encoding(false, true); utf8Throw.GetString(pbData); return StrUtil.GetEncoding(StrEncodingType.Utf8); } catch(Exception) { } return StrUtil.GetEncoding(StrEncodingType.Default); } private static int CompareBySigLengthRev(StrEncodingInfo a, StrEncodingInfo b) { Debug.Assert((a != null) && (b != null)); int na = 0, nb = 0; if((a != null) && (a.StartSignature != null)) na = a.StartSignature.Length; if((b != null) && (b.StartSignature != null)) nb = b.StartSignature.Length; return -(na.CompareTo(nb)); } } } KeePass/Util/ClipboardUtil.Unix.cs0000664000000000000000000001353013222430416016033 0ustar rootroot/* KeePass Password Safe - The Open-Source Password Manager Copyright (C) 2003-2018 Dominik Reichl This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ using System; using System.Collections.Generic; using System.Text; using System.Windows.Forms; using System.Reflection; using System.Diagnostics; using KeePassLib; using KeePassLib.Native; namespace KeePass.Util { public static partial class ClipboardUtil { // https://sourceforge.net/p/keepass/patches/84/ // https://sourceforge.net/p/keepass/patches/85/ private const AppRunFlags XSelFlags = (AppRunFlags.GetStdOutput | AppRunFlags.GCKeepAlive | AppRunFlags.DoEvents | AppRunFlags.DisableForms); private static string GetStringM() { // string strGtk = GtkGetString(); // if(strGtk != null) return strGtk; return (NativeLib.RunConsoleApp("pbpaste", "-pboard general") ?? string.Empty); } private static void SetStringM(string str) { // if(GtkSetString(str)) return; NativeLib.RunConsoleApp("pbcopy", "-pboard general", str); } private static string GetStringU() { // string strGtk = GtkGetString(); // if(strGtk != null) return strGtk; // string str = NativeLib.RunConsoleApp("xclip", // "-out -selection clipboard"); // if(str != null) return str; string str = NativeLib.RunConsoleApp("xsel", "--output --clipboard", null, XSelFlags); if(str != null) return str; if(Clipboard.ContainsText()) return (Clipboard.GetText() ?? string.Empty); return string.Empty; } private static void SetStringU(string str) { // if(GtkSetString(str)) return; // string r = NativeLib.RunConsoleApp("xclip", // "-in -selection clipboard", str); // if(r != null) return; if(string.IsNullOrEmpty(str)) { // xsel with an empty input can hang, thus use --clear if(NativeLib.RunConsoleApp("xsel", "--clear --primary", null, XSelFlags) != null) { NativeLib.RunConsoleApp("xsel", "--clear --clipboard", null, XSelFlags); return; } try { Clipboard.Clear(); } catch(Exception) { Debug.Assert(false); } return; } // xsel does not support --primary and --clipboard together if(NativeLib.RunConsoleApp("xsel", "--input --primary", str, XSelFlags) != null) { NativeLib.RunConsoleApp("xsel", "--input --clipboard", str, XSelFlags); return; } try { Clipboard.SetText(str); } catch(Exception) { Debug.Assert(false); } } /* private static bool GtkGetClipboard(out Type t, out object o) { t = null; o = null; try { Assembly asmGdk = KeePass.Native.NativeMethods.LoadAssembly( "gdk-sharp", "gdk-sharp.dll"); if(asmGdk == null) return false; Assembly asmGtk = KeePass.Native.NativeMethods.LoadAssembly( "gtk-sharp", "gtk-sharp.dll"); if(asmGtk == null) return false; if(!KeePass.Native.NativeMethods.GtkEnsureInit()) return false; Type tAtom = asmGdk.GetType("Gdk.Atom", true); MethodInfo miAtomIntern = tAtom.GetMethod("Intern", BindingFlags.Public | BindingFlags.Static); if(miAtomIntern == null) { Debug.Assert(false); return false; } object oAtomClip = miAtomIntern.Invoke(null, new object[] { "CLIPBOARD", false }); if(oAtomClip == null) { Debug.Assert(false); return false; } t = asmGtk.GetType("Gtk.Clipboard", true); MethodInfo miClipboardGet = t.GetMethod("Get", BindingFlags.Public | BindingFlags.Static); if(miClipboardGet == null) { Debug.Assert(false); return false; } o = miClipboardGet.Invoke(null, new object[] { oAtomClip }); if(o == null) { Debug.Assert(false); return false; } return true; } catch(Exception) { Debug.Assert(false); } return false; } private static string GtkGetString() { Type t; object o; if(!GtkGetClipboard(out t, out o)) return null; try { MethodInfo miTest = t.GetMethod("WaitIsTextAvailable", BindingFlags.Public | BindingFlags.Instance); if(miTest == null) { Debug.Assert(false); return null; } bool bText = (bool)miTest.Invoke(o, null); if(!bText) return string.Empty; MethodInfo miGet = t.GetMethod("WaitForText", BindingFlags.Public | BindingFlags.Instance); if(miGet == null) { Debug.Assert(false); return null; } return (miGet.Invoke(o, null) as string); } catch(Exception) { Debug.Assert(false); } return null; } private static bool GtkSetString(string str) { Type t; object o; if(!GtkGetClipboard(out t, out o)) return false; try { MethodInfo miClear = t.GetMethod("Clear", BindingFlags.Public | BindingFlags.Instance); miClear.Invoke(o, null); PropertyInfo piText = t.GetProperty("Text", BindingFlags.Public | BindingFlags.Instance); piText.SetValue(o, (str ?? string.Empty), null); // Prevent deadlock when pasting in own window MethodInfo miStore = t.GetMethod("Store", BindingFlags.Public | BindingFlags.Instance); miStore.Invoke(o, null); return true; } catch(Exception) { Debug.Assert(false); } return false; } */ } } KeePass/Util/CriticalSectionEx.cs0000664000000000000000000000422113222430416015725 0ustar rootroot/* KeePass Password Safe - The Open-Source Password Manager Copyright (C) 2003-2018 Dominik Reichl This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ using System; using System.Collections.Generic; using System.Diagnostics; using System.Text; using System.Threading; namespace KeePass.Util { /// /// Mechanism to synchronize access to an object. /// In addition to a usual critical section (which locks an object /// to a single thread), CriticalSectionEx also prevents /// subsequent accesses from the same thread. /// public sealed class CriticalSectionEx { private int m_iLock = 0; #if (DEBUG && !KeePassUAP) private int m_iThreadId = -1; #endif public CriticalSectionEx() { } #if DEBUG ~CriticalSectionEx() { // The object should be unlocked when the lock is disposed Debug.Assert(Interlocked.CompareExchange(ref m_iLock, 0, 2) == 0); } #endif public bool TryEnter() { bool b = (Interlocked.Exchange(ref m_iLock, 1) == 0); #if (DEBUG && !KeePassUAP) if(b) m_iThreadId = Thread.CurrentThread.ManagedThreadId; #endif return b; } public void Exit() { if(Interlocked.Exchange(ref m_iLock, 0) != 1) { Debug.Assert(false); } #if (DEBUG && !KeePassUAP) else { // Lock should be released by the original thread Debug.Assert(Thread.CurrentThread.ManagedThreadId == m_iThreadId); m_iThreadId = -1; } #endif } } } KeePass/Util/WinUtil.cs0000664000000000000000000005311513222430416013752 0ustar rootroot/* KeePass Password Safe - The Open-Source Password Manager Copyright (C) 2003-2018 Dominik Reichl This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ using System; using System.Collections.Generic; using System.ComponentModel; using System.Diagnostics; using System.Drawing; using System.IO; using System.Reflection; using System.Runtime.InteropServices; using System.Security.Cryptography; using System.Text; using System.Text.RegularExpressions; using System.Windows.Forms; using Microsoft.Win32; using KeePass.App; using KeePass.Native; using KeePass.Resources; using KeePass.Util.Spr; using KeePassLib; using KeePassLib.Serialization; using KeePassLib.Utility; using NativeLib = KeePassLib.Native.NativeLib; namespace KeePass.Util { public static class WinUtil { private static bool m_bIsWindows9x = false; private static bool m_bIsWindows2000 = false; private static bool m_bIsWindowsXP = false; private static bool m_bIsAtLeastWindows2000 = false; private static bool m_bIsAtLeastWindowsVista = false; private static bool m_bIsAtLeastWindows7 = false; private static bool m_bIsAtLeastWindows8 = false; private static bool m_bIsAtLeastWindows10 = false; private static bool m_bIsAppX = false; private static string m_strExePath = null; private static ulong m_uFrameworkVersion = 0; public static bool IsWindows9x { get { return m_bIsWindows9x; } } public static bool IsWindows2000 { get { return m_bIsWindows2000; } } public static bool IsWindowsXP { get { return m_bIsWindowsXP; } } public static bool IsAtLeastWindows2000 { get { return m_bIsAtLeastWindows2000; } } public static bool IsAtLeastWindowsVista { get { return m_bIsAtLeastWindowsVista; } } public static bool IsAtLeastWindows7 { get { return m_bIsAtLeastWindows7; } } public static bool IsAtLeastWindows8 { get { return m_bIsAtLeastWindows8; } } public static bool IsAtLeastWindows10 { get { return m_bIsAtLeastWindows10; } } public static bool IsAppX { get { return m_bIsAppX; } } static WinUtil() { OperatingSystem os = Environment.OSVersion; Version v = os.Version; m_bIsWindows9x = (os.Platform == PlatformID.Win32Windows); m_bIsWindows2000 = ((v.Major == 5) && (v.Minor == 0)); m_bIsWindowsXP = ((v.Major == 5) && (v.Minor == 1)); m_bIsAtLeastWindows2000 = (v.Major >= 5); m_bIsAtLeastWindowsVista = (v.Major >= 6); m_bIsAtLeastWindows7 = ((v.Major >= 7) || ((v.Major == 6) && (v.Minor >= 1))); m_bIsAtLeastWindows8 = ((v.Major >= 7) || ((v.Major == 6) && (v.Minor >= 2))); // Environment.OSVersion is reliable only up to version 6.2; // https://msdn.microsoft.com/library/windows/desktop/ms724832.aspx RegistryKey rk = null; try { rk = Registry.LocalMachine.OpenSubKey( "SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion", false); if(rk != null) { string str = rk.GetValue("CurrentMajorVersionNumber", string.Empty).ToString(); uint u; if(uint.TryParse(str, out u)) m_bIsAtLeastWindows10 = (u >= 10); else { Debug.Assert(string.IsNullOrEmpty(str)); } } else { Debug.Assert(NativeLib.IsUnix()); } } catch(Exception) { Debug.Assert(NativeLib.IsUnix()); } finally { if(rk != null) rk.Close(); } try { string strDir = UrlUtil.GetFileDirectory(GetExecutable(), false, false); if(strDir.IndexOf("\\WindowsApps\\", StrUtil.CaseIgnoreCmp) >= 0) { Regex rx = new Regex("\\\\WindowsApps\\\\.*?_\\d+(\\.\\d+)*_", RegexOptions.IgnoreCase); m_bIsAppX = rx.IsMatch(strDir); } else { Debug.Assert(!m_bIsAppX); } // No AppX by default } catch(Exception) { Debug.Assert(false); } } public static void OpenEntryUrl(PwEntry pe) { Debug.Assert(pe != null); if(pe == null) throw new ArgumentNullException("pe"); string strUrl = pe.Strings.ReadSafe(PwDefs.UrlField); if(pe.OverrideUrl.Length > 0) WinUtil.OpenUrl(pe.OverrideUrl, pe, true, strUrl); else { string strOverride = Program.Config.Integration.UrlOverride; if(strOverride.Length > 0) WinUtil.OpenUrl(strOverride, pe, true, strUrl); else WinUtil.OpenUrl(strUrl, pe, true); } } public static void OpenUrl(string strUrlToOpen, PwEntry peDataSource) { OpenUrl(strUrlToOpen, peDataSource, true, null); } public static void OpenUrl(string strUrlToOpen, PwEntry peDataSource, bool bAllowOverride) { OpenUrl(strUrlToOpen, peDataSource, bAllowOverride, null); } public static void OpenUrl(string strUrlToOpen, PwEntry peDataSource, bool bAllowOverride, string strBaseRaw) { // If URL is null, return, do not throw exception. Debug.Assert(strUrlToOpen != null); if(strUrlToOpen == null) return; string strPrevWorkDir = WinUtil.GetWorkingDirectory(); string strThisExe = WinUtil.GetExecutable(); string strExeDir = UrlUtil.GetFileDirectory(strThisExe, false, true); WinUtil.SetWorkingDirectory(strExeDir); string strUrlFlt = strUrlToOpen; strUrlFlt = strUrlFlt.TrimStart(new char[]{ ' ', '\t', '\r', '\n' }); PwDatabase pwDatabase = null; try { pwDatabase = Program.MainForm.DocumentManager.SafeFindContainerOf( peDataSource); } catch(Exception) { Debug.Assert(false); } bool bEncCmd = WinUtil.IsCommandLineUrl(strUrlFlt); SprContext ctx = new SprContext(peDataSource, pwDatabase, SprCompileFlags.All, false, bEncCmd); ctx.Base = strBaseRaw; ctx.BaseIsEncoded = false; string strUrl = SprEngine.Compile(strUrlFlt, ctx); string strOvr = Program.Config.Integration.UrlSchemeOverrides.GetOverrideForUrl( strUrl); if(!bAllowOverride) strOvr = null; if(strOvr != null) { bool bEncCmdOvr = WinUtil.IsCommandLineUrl(strOvr); SprContext ctxOvr = new SprContext(peDataSource, pwDatabase, SprCompileFlags.All, false, bEncCmdOvr); ctxOvr.Base = strUrl; ctxOvr.BaseIsEncoded = bEncCmd; strUrl = SprEngine.Compile(strOvr, ctxOvr); } if(WinUtil.IsCommandLineUrl(strUrl)) { string strApp, strArgs; StrUtil.SplitCommandLine(WinUtil.GetCommandLineFromUrl(strUrl), out strApp, out strArgs); try { if((strArgs != null) && (strArgs.Length > 0)) Process.Start(strApp, strArgs); else Process.Start(strApp); } catch(Win32Exception) { StartWithoutShellExecute(strApp, strArgs); } catch(Exception exCmd) { string strInf = KPRes.FileOrUrl + ": " + strApp; if((strArgs != null) && (strArgs.Length > 0)) strInf += MessageService.NewParagraph + KPRes.Arguments + ": " + strArgs; MessageService.ShowWarning(strInf, exCmd); } } else // Standard URL { try { Process.Start(strUrl); } catch(Exception exUrl) { MessageService.ShowWarning(strUrl, exUrl); } } // Restore previous working directory WinUtil.SetWorkingDirectory(strPrevWorkDir); // SprEngine.Compile might have modified the database Program.MainForm.UpdateUI(false, null, false, null, false, null, false); } public static void OpenUrlWithApp(string strUrlToOpen, PwEntry peDataSource, string strAppPath) { if(string.IsNullOrEmpty(strUrlToOpen)) return; if(string.IsNullOrEmpty(strAppPath)) return; char[] vPathTrim = new char[]{ ' ', '\t', '\r', '\n', '\"', '\'' }; string strUrl = strUrlToOpen.Trim(vPathTrim); if(strUrl.Length == 0) { Debug.Assert(false); return; } string strApp = strAppPath.Trim(vPathTrim); if(strApp.Length == 0) { Debug.Assert(false); return; } string str = "cmd://\"" + strApp + "\" \"" + strUrl + "\""; OpenUrl(str, peDataSource, false); } private static void StartWithoutShellExecute(string strApp, string strArgs) { try { ProcessStartInfo psi = new ProcessStartInfo(); psi.FileName = strApp; if((strArgs != null) && (strArgs.Length > 0)) psi.Arguments = strArgs; psi.UseShellExecute = false; Process.Start(psi); } catch(Exception exCmd) { string strInf = KPRes.FileOrUrl + ": " + strApp; if((strArgs != null) && (strArgs.Length > 0)) strInf += MessageService.NewParagraph + KPRes.Arguments + ": " + strArgs; MessageService.ShowWarning(strInf, exCmd); } } public static void Restart() { try { Process.Start(WinUtil.GetExecutable()); } catch(Exception exRestart) { MessageService.ShowWarning(exRestart); } } public static string GetExecutable() { if(m_strExePath != null) return m_strExePath; try { m_strExePath = Assembly.GetExecutingAssembly().Location; } catch(Exception) { } if(string.IsNullOrEmpty(m_strExePath)) { m_strExePath = Assembly.GetExecutingAssembly().GetName().CodeBase; m_strExePath = UrlUtil.FileUrlToPath(m_strExePath); } return m_strExePath; } /// /// Shorten a path. /// /// Path to make shorter. /// Maximum number of characters in the returned string. /// Shortened path. public static string CompactPath(string strPath, int nMaxChars) { Debug.Assert(strPath != null); if(strPath == null) throw new ArgumentNullException("strPath"); Debug.Assert(nMaxChars >= 0); if(nMaxChars < 0) throw new ArgumentOutOfRangeException("nMaxChars"); if(nMaxChars == 0) return string.Empty; if(strPath.Length <= nMaxChars) return strPath; try { StringBuilder sb = new StringBuilder(strPath.Length * 2 + 4); if(NativeMethods.PathCompactPathEx(sb, strPath, (uint)nMaxChars, 0) == false) return StrUtil.CompactString3Dots(strPath, nMaxChars); Debug.Assert(sb.Length <= nMaxChars); if((sb.Length <= nMaxChars) && (sb.Length != 0)) return sb.ToString(); else return StrUtil.CompactString3Dots(strPath, nMaxChars); } catch(Exception) { Debug.Assert(false); } return StrUtil.CompactString3Dots(strPath, nMaxChars); } public static bool FlushStorageBuffers(char chDriveLetter, bool bOnlyIfRemovable) { string strDriveLetter = new string(chDriveLetter, 1); bool bResult = true; try { if(bOnlyIfRemovable) { DriveInfo di = new DriveInfo(strDriveLetter); if(di.DriveType != DriveType.Removable) return true; } string strDevice = "\\\\.\\" + strDriveLetter + ":"; IntPtr hDevice = NativeMethods.CreateFile(strDevice, NativeMethods.EFileAccess.GenericRead | NativeMethods.EFileAccess.GenericWrite, NativeMethods.EFileShare.Read | NativeMethods.EFileShare.Write, IntPtr.Zero, NativeMethods.ECreationDisposition.OpenExisting, 0, IntPtr.Zero); if(NativeMethods.IsInvalidHandleValue(hDevice)) { Debug.Assert(false); return false; } string strDir = FreeDriveIfCurrent(chDriveLetter); uint dwDummy; if(NativeMethods.DeviceIoControl(hDevice, NativeMethods.FSCTL_LOCK_VOLUME, IntPtr.Zero, 0, IntPtr.Zero, 0, out dwDummy, IntPtr.Zero) != false) { if(NativeMethods.DeviceIoControl(hDevice, NativeMethods.FSCTL_UNLOCK_VOLUME, IntPtr.Zero, 0, IntPtr.Zero, 0, out dwDummy, IntPtr.Zero) == false) { Debug.Assert(false); } } else bResult = false; if(strDir.Length > 0) WinUtil.SetWorkingDirectory(strDir); if(!NativeMethods.CloseHandle(hDevice)) { Debug.Assert(false); } } catch(Exception) { Debug.Assert(false); return false; } return bResult; } public static bool FlushStorageBuffers(string strFileOnStorage, bool bOnlyIfRemovable) { if(strFileOnStorage == null) { Debug.Assert(false); return false; } if(strFileOnStorage.Length < 3) return false; if(strFileOnStorage[1] != ':') return false; if(strFileOnStorage[2] != '\\') return false; return FlushStorageBuffers(char.ToUpper(strFileOnStorage[0]), bOnlyIfRemovable); } private static string FreeDriveIfCurrent(char chDriveLetter) { try { string strCur = WinUtil.GetWorkingDirectory(); if((strCur == null) || (strCur.Length < 3)) return string.Empty; if(strCur[1] != ':') return string.Empty; if(strCur[2] != '\\') return string.Empty; char chPar = char.ToUpper(chDriveLetter); char chCur = char.ToUpper(strCur[0]); if(chPar != chCur) return string.Empty; string strTemp = UrlUtil.GetTempPath(); WinUtil.SetWorkingDirectory(strTemp); return strCur; } catch(Exception) { Debug.Assert(false); } return string.Empty; } private static readonly string[] m_vIE7Windows = new string[] { "Windows Internet Explorer", "Maxthon" }; public static bool IsInternetExplorer7Window(string strWindowTitle) { if(strWindowTitle == null) return false; // No assert or throw if(strWindowTitle.Length == 0) return false; // No assert or throw foreach(string str in m_vIE7Windows) { if(strWindowTitle.IndexOf(str) >= 0) return true; } return false; } public static byte[] HashFile(IOConnectionInfo iocFile) { if(iocFile == null) { Debug.Assert(false); return null; } // Assert only Stream sIn; try { sIn = IOConnection.OpenRead(iocFile); if(sIn == null) throw new FileNotFoundException(); } catch(Exception) { return null; } byte[] pbHash; try { using(SHA256Managed sha256 = new SHA256Managed()) { pbHash = sha256.ComputeHash(sIn); } } catch(Exception) { Debug.Assert(false); sIn.Close(); return null; } sIn.Close(); return pbHash; } // See GetCommandLineFromUrl when editing this method public static bool IsCommandLineUrl(string strUrl) { if(strUrl == null) { Debug.Assert(false); return false; } string strLower = strUrl.ToLower(); if(strLower.StartsWith("cmd://")) return true; if(strLower.StartsWith("\\\\")) return true; // UNC path support return false; } // See IsCommandLineUrl when editing this method public static string GetCommandLineFromUrl(string strUrl) { if(strUrl == null) { Debug.Assert(false); return string.Empty; } string strLower = strUrl.ToLower(); if(strLower.StartsWith("cmd://")) return strUrl.Remove(0, 6); if(strLower.StartsWith("\\\\")) return strUrl; // UNC path support return strUrl; } public static bool RunElevated(string strExe, string strArgs, bool bShowMessageIfFailed) { if(strExe == null) throw new ArgumentNullException("strExe"); try { ProcessStartInfo psi = new ProcessStartInfo(); if(strArgs != null) psi.Arguments = strArgs; psi.FileName = strExe; psi.UseShellExecute = true; psi.WindowStyle = ProcessWindowStyle.Normal; // Elevate on Windows Vista and higher if(WinUtil.IsAtLeastWindowsVista) psi.Verb = "runas"; Process.Start(psi); } catch(Exception ex) { if(bShowMessageIfFailed) MessageService.ShowWarning(ex); return false; } return true; } public static ulong GetMaxNetFrameworkVersion() { if(m_uFrameworkVersion != 0) return m_uFrameworkVersion; try { m_uFrameworkVersion = GetMaxNetVersionPriv(); } catch(Exception) { Debug.Assert(false); } if(m_uFrameworkVersion == 0) { Version v = Environment.Version; if(v.Major > 0) m_uFrameworkVersion |= (uint)v.Major; m_uFrameworkVersion <<= 16; if(v.Minor > 0) m_uFrameworkVersion |= (uint)v.Minor; m_uFrameworkVersion <<= 16; if(v.Build > 0) m_uFrameworkVersion |= (uint)v.Build; m_uFrameworkVersion <<= 16; if(v.Revision > 0) m_uFrameworkVersion |= (uint)v.Revision; } return m_uFrameworkVersion; } private static ulong GetMaxNetVersionPriv() { RegistryKey kNdp = Registry.LocalMachine.OpenSubKey( "SOFTWARE\\Microsoft\\NET Framework Setup\\NDP", false); if(kNdp == null) { Debug.Assert(false); return 0; } ulong uMaxVer = 0; string[] vInNdp = kNdp.GetSubKeyNames(); foreach(string strInNdp in vInNdp) { if(strInNdp == null) { Debug.Assert(false); continue; } if(!strInNdp.StartsWith("v", StrUtil.CaseIgnoreCmp)) continue; RegistryKey kVer = kNdp.OpenSubKey(strInNdp, false); if(kVer != null) { UpdateNetVersionFromRegKey(kVer, ref uMaxVer); string[] vProfiles = kVer.GetSubKeyNames(); foreach(string strProfile in vProfiles) { if(string.IsNullOrEmpty(strProfile)) { Debug.Assert(false); continue; } RegistryKey kPro = kVer.OpenSubKey(strProfile, false); UpdateNetVersionFromRegKey(kPro, ref uMaxVer); if(kPro != null) kPro.Close(); } kVer.Close(); } else { Debug.Assert(false); } } kNdp.Close(); return uMaxVer; } private static void UpdateNetVersionFromRegKey(RegistryKey k, ref ulong uMaxVer) { if(k == null) { Debug.Assert(false); return; } try { // https://msdn.microsoft.com/en-us/library/hh925568.aspx string strInstall = k.GetValue("Install", string.Empty).ToString(); if((strInstall.Length > 0) && (strInstall != "1")) return; string strVer = k.GetValue("Version", string.Empty).ToString(); if(strVer.Length > 0) { ulong uVer = StrUtil.ParseVersion(strVer); if(uVer > uMaxVer) uMaxVer = uVer; } } catch(Exception) { Debug.Assert(false); } } /* private static ulong GetMaxNetVersionPriv() { string strSysRoot = Environment.GetEnvironmentVariable("SystemRoot"); string strFrameworks = UrlUtil.EnsureTerminatingSeparator(strSysRoot, false) + "Microsoft.NET" + Path.DirectorySeparatorChar + "Framework"; if(!Directory.Exists(strFrameworks)) { Debug.Assert(false); return 0; } ulong uFrameworkVersion = 0; DirectoryInfo diFrameworks = new DirectoryInfo(strFrameworks); foreach(DirectoryInfo di in diFrameworks.GetDirectories("v*", SearchOption.TopDirectoryOnly)) { string strVer = di.Name.TrimStart('v', 'V'); ulong uVer = StrUtil.ParseVersion(strVer); if(uVer > uFrameworkVersion) uFrameworkVersion = uVer; } return uFrameworkVersion; } */ public static string GetOSStr() { if(NativeLib.IsUnix()) return "Unix"; return "Windows"; } public static void RemoveZoneIdentifier(string strFilePath) { // No throw if(string.IsNullOrEmpty(strFilePath)) { Debug.Assert(false); return; } try { string strZoneId = strFilePath + ":Zone.Identifier"; if(NativeMethods.FileExists(strZoneId)) NativeMethods.DeleteFile(strZoneId); } catch(Exception) { Debug.Assert(NativeLib.IsUnix()); } } [Obsolete] public static string RunConsoleApp(string strAppPath, string strParams) { return NativeLib.RunConsoleApp(strAppPath, strParams); } public static string LocateSystemApp(string strExeName) { if(strExeName == null) { Debug.Assert(false); return string.Empty; } if(strExeName.Length == 0) return strExeName; if(NativeLib.IsUnix()) return strExeName; try { string str = null; for(int i = 0; i < 3; ++i) { if(i == 0) str = Environment.GetFolderPath( Environment.SpecialFolder.System); else if(i == 1) str = Environment.GetEnvironmentVariable("WinDir"); else if(i == 2) str = Environment.GetEnvironmentVariable("SystemRoot"); if(!string.IsNullOrEmpty(str)) { str = UrlUtil.EnsureTerminatingSeparator(str, false); str += strExeName; if(File.Exists(str)) return str; } } } catch(Exception) { Debug.Assert(false); } return strExeName; } public static string GetHomeDirectory() { string str = null; try { str = Environment.GetFolderPath(Environment.SpecialFolder.Personal); } catch(Exception) { Debug.Assert(false); } if(string.IsNullOrEmpty(str)) { try { str = Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments); } catch(Exception) { Debug.Assert(false); } } if(string.IsNullOrEmpty(str)) { Debug.Assert(false); return string.Empty; } return str; } public static string GetWorkingDirectory() { string strWorkDir = null; try { strWorkDir = Directory.GetCurrentDirectory(); } catch(Exception) { Debug.Assert(false); } return (!string.IsNullOrEmpty(strWorkDir) ? strWorkDir : GetHomeDirectory()); } public static void SetWorkingDirectory(string strWorkDir) { string str = strWorkDir; // May be null if(!string.IsNullOrEmpty(str)) { try { if(!Directory.Exists(str)) str = null; } catch(Exception) { Debug.Assert(false); str = null; } } if(string.IsNullOrEmpty(str)) str = GetHomeDirectory(); // Not app dir try { Directory.SetCurrentDirectory(str); } catch(Exception) { Debug.Assert(false); } } } } KeePass/Util/CancellableOperationEventArgs.cs0000664000000000000000000000317413222430416020244 0ustar rootroot/* KeePass Password Safe - The Open-Source Password Manager Copyright (C) 2003-2018 Dominik Reichl This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ using System; namespace KeePass.Util { /// /// Structure for a cancellable event. /// The difference between this class and the .NET CancelEventArgs /// class is that in CancellableOperationEventArgs once the /// Cancel property has been set to true, it remains /// true, even when trying to set it to false afterwards; /// this allows passing an instance to multiple recipients and cancel /// if at least one of them wants to (the others can't reset the vote). /// public class CancellableOperationEventArgs : EventArgs { private bool m_bCancel = false; public CancellableOperationEventArgs() { } public bool Cancel { get { return m_bCancel; } set { m_bCancel |= value; } } } } KeePass/Util/CustomResourceManager.cs0000664000000000000000000001272313222430416016634 0ustar rootroot/* KeePass Password Safe - The Open-Source Password Manager Copyright (C) 2003-2018 Dominik Reichl This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ using System; using System.Collections.Generic; using System.Collections.ObjectModel; using System.Text; using System.Globalization; using System.Resources; using System.Drawing; using System.Reflection; using System.Diagnostics; using KeePass.UI; using KeePass.Util.Archive; using KeePassLib; using KeePassLib.Utility; namespace KeePass.Util { public sealed class CrmEventArgs : EventArgs { private readonly string m_strName; public string Name { get { return m_strName; } } private readonly CultureInfo m_ci; public CultureInfo CultureInfo { get { return m_ci; } } private object m_obj; public object Object { get { return m_obj; } set { m_obj = value; } } public CrmEventArgs(string strName, CultureInfo ci, object o) { if(strName == null) throw new ArgumentNullException("strName"); m_strName = strName; m_ci = ci; m_obj = o; } } public sealed class CustomResourceManager : ResourceManager { private static List m_lInsts = new List(); public static ReadOnlyCollection Instances { get { return m_lInsts.AsReadOnly(); } } public event EventHandler GetObjectPre; private readonly ResourceManager m_rm; public ResourceManager BaseResourceManager { get { return m_rm; } } private Dictionary m_dOverrides = new Dictionary(); private ImageArchive m_iaAppHighRes = new ImageArchive(); public CustomResourceManager(ResourceManager rmBase) { if(rmBase == null) throw new ArgumentNullException("rmBase"); m_rm = rmBase; if(m_lInsts.Count < 1000) m_lInsts.Add(this); else { Debug.Assert(false); } try { m_iaAppHighRes.Load(Properties.Resources.Images_App_HighRes); } catch(Exception) { Debug.Assert(false); } } public override object GetObject(string name) { return GetObject(name, null); } public override object GetObject(string name, CultureInfo culture) { if(name == null) throw new ArgumentNullException("name"); if(this.GetObjectPre != null) { CrmEventArgs e = new CrmEventArgs(name, culture, null); this.GetObjectPre(this, e); if(e.Object != null) return e.Object; } object oOvr; if(m_dOverrides.TryGetValue(name, out oOvr)) return oOvr; object o = m_rm.GetObject(name, culture); if(o == null) { Debug.Assert(false); return null; } try { Image img = (o as Image); if(img != null) { Debug.Assert(!(o is Icon)); Image imgOvr = m_iaAppHighRes.GetForObject(name); if(imgOvr != null) { int wOvr = imgOvr.Width; int hOvr = imgOvr.Height; int wBase = img.Width; int hBase = img.Height; int wReq = DpiUtil.ScaleIntX(wBase); int hReq = DpiUtil.ScaleIntY(hBase); if((wBase > wOvr) || (hBase > hOvr)) { Debug.Assert(false); // Base has higher resolution imgOvr = img; wOvr = wBase; hOvr = hBase; } if((wReq != wOvr) || (hReq != hOvr)) imgOvr = GfxUtil.ScaleImage(imgOvr, wReq, hReq, ScaleTransformFlags.UIIcon); } else imgOvr = DpiUtil.ScaleImage(img, false); m_dOverrides[name] = imgOvr; return imgOvr; } } catch(Exception) { Debug.Assert(false); } return o; } public override string GetString(string name) { return m_rm.GetString(name); } public override string GetString(string name, CultureInfo culture) { return m_rm.GetString(name, culture); } public static void Override(Type tResClass) { try { OverridePriv(tResClass); } catch(Exception) { Debug.Assert(false); } } private static void OverridePriv(Type tResClass) { if(tResClass == null) { Debug.Assert(false); return; } if(Program.DesignMode) return; if(!DpiUtil.ScalingRequired) return; // Ensure ResourceManager instance PropertyInfo pi = tResClass.GetProperty("ResourceManager", (BindingFlags.NonPublic | BindingFlags.Static)); if(pi == null) { Debug.Assert(false); return; } pi.GetValue(null, null); FieldInfo fi = tResClass.GetField("resourceMan", (BindingFlags.NonPublic | BindingFlags.Static)); if(fi == null) { Debug.Assert(false); return; } ResourceManager rm = (fi.GetValue(null) as ResourceManager); if(rm == null) { Debug.Assert(false); return; } Debug.Assert(!(rm is CustomResourceManager)); // Override only once CustomResourceManager crm = new CustomResourceManager(rm); fi.SetValue(null, crm); } } } KeePass/Util/PrintUtil.cs0000664000000000000000000001101013222430416014275 0ustar rootroot/* KeePass Password Safe - The Open-Source Password Manager Copyright (C) 2003-2018 Dominik Reichl This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ using System; using System.Collections.Generic; using System.Diagnostics; using System.IO; using System.Text; using System.Windows.Forms; using Microsoft.Win32; using KeePass.UI; using KeePassLib.Native; using KeePassLib.Utility; namespace KeePass.Util { public static class PrintUtil { public static void PrintHtml(string strHtml) { if(string.IsNullOrEmpty(strHtml)) { Debug.Assert(false); return; } try { if(!PrintHtmlShell(strHtml)) { if(!PrintHtmlWB(strHtml)) PrintHtmlExec(strHtml); } } catch(Exception ex) { MessageService.ShowWarning(ex); } } private static bool PrintHtmlShell(string strHtml) { if(NativeLib.IsUnix()) return false; RegistryKey k = null; try { k = Registry.ClassesRoot.OpenSubKey( "htmlfile\\shell\\print\\command", false); if(k == null) { Debug.Assert(false); return false; } string str = (k.GetValue(string.Empty) as string); if(string.IsNullOrEmpty(str)) { Debug.Assert(false); return false; } str = FixPrintCommandLine(str); string strPath = Program.TempFilesPool.GetTempFileName("html"); string strOrg = str; str = UrlUtil.ExpandShellVariables(str, new string[] { strPath }); if(str == strOrg) { Debug.Assert(false); return false; } File.WriteAllText(strPath, strHtml, StrUtil.Utf8); WinUtil.OpenUrl("cmd://" + str, null, false); return true; } catch(Exception) { Debug.Assert(false); } finally { if(k != null) k.Close(); } return false; } private static string FixPrintCommandLine(string strCmd) { string str = strCmd; // Workaround for Microsoft Office breaking the 'Print' shell verb; // https://sourceforge.net/p/keepass/bugs/1675/ // https://support.microsoft.com/en-us/help/274527/cannot-print-file-with--htm-extension-from-windows-explorer-by-right-c if(str.IndexOf("\\msohtmed.exe", StrUtil.CaseIgnoreCmp) >= 0) { string strSys = UrlUtil.EnsureTerminatingSeparator( Environment.SystemDirectory, false); str = "\"" + strSys + "rundll32.exe\" \"" + strSys + "mshtml.dll\",PrintHTML \"%1\""; } return str; } private static bool PrintHtmlWB(string strHtml) { // Mono's WebBrowser implementation doesn't support printing if(NativeLib.IsUnix()) return false; try { // Printing and disposing immediately seems to be supported; // https://docs.microsoft.com/en-us/dotnet/framework/winforms/controls/how-to-print-with-a-webbrowser-control using(WebBrowser wb = new WebBrowser()) { wb.AllowWebBrowserDrop = false; wb.IsWebBrowserContextMenuEnabled = false; wb.ScriptErrorsSuppressed = true; wb.WebBrowserShortcutsEnabled = false; UIUtil.SetWebBrowserDocument(wb, strHtml); wb.ShowPrintDialog(); } Program.TempFilesPool.AddWebBrowserPrintContent(); return true; } catch(Exception) { Debug.Assert(false); } return false; } private static void PrintHtmlExec(string strHtml) { string strPath = Program.TempFilesPool.GetTempFileName("html"); File.WriteAllText(strPath, strHtml, StrUtil.Utf8); ProcessStartInfo psi = new ProcessStartInfo(); psi.FileName = strPath; psi.UseShellExecute = true; // Try to use the 'Print' verb; if it's not available, the // default verb is used (to just display the file) string[] v = (psi.Verbs ?? new string[0]); foreach(string strVerb in v) { if(strVerb == null) { Debug.Assert(false); continue; } if(strVerb.Equals("Print", StrUtil.CaseIgnoreCmp)) { psi.Verb = strVerb; break; } } Process.Start(psi); } } } KeePass/Util/ClipboardEventChainBlocker.cs0000664000000000000000000000506213222430416017523 0ustar rootroot/* KeePass Password Safe - The Open-Source Password Manager Copyright (C) 2003-2018 Dominik Reichl This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ using System; using System.Collections.Generic; using System.Text; using System.Windows.Forms; using System.Runtime.InteropServices; using System.Diagnostics; using KeePass.Native; using NativeLib = KeePassLib.Native.NativeLib; namespace KeePass.Util { public sealed class ClipboardEventChainBlocker : IDisposable { private ClipboardBlockerForm m_form = null; private IntPtr m_hChain = IntPtr.Zero; public ClipboardEventChainBlocker() { if(NativeLib.IsUnix()) return; // Unsupported m_form = new ClipboardBlockerForm(); try { m_hChain = NativeMethods.SetClipboardViewer(m_form.Handle); } catch(Exception) { Debug.Assert(false); } } ~ClipboardEventChainBlocker() { Dispose(false); } public void Dispose() { Dispose(true); GC.SuppressFinalize(this); } private void Dispose(bool bDisposing) { if(bDisposing && (m_form != null)) { try { // Ignore return value (no assert); see documentation // of ChangeClipboardChain NativeMethods.ChangeClipboardChain(m_form.Handle, m_hChain); } catch(Exception) { Debug.Assert(false); } m_form.Dispose(); m_form = null; } m_hChain = IntPtr.Zero; } [Obsolete] public void Release() { Dispose(true); } private sealed class ClipboardBlockerForm : Form { public ClipboardBlockerForm() : base() { this.Visible = false; this.ShowInTaskbar = false; this.ShowIcon = false; } public override bool PreProcessMessage(ref Message msg) { if(msg.Msg == NativeMethods.WM_DRAWCLIPBOARD) return true; // Block message return base.PreProcessMessage(ref msg); } } } } KeePass/Util/XmlSerialization/0000775000000000000000000000000013222430420015314 5ustar rootrootKeePass/Util/XmlSerialization/XmlSerializerEx.Gen.cs0000664000000000000000000026174413224757466021510 0ustar rootroot// This is a generated file! // Do not edit manually, changes will be overwritten. using System; using System.Collections.Generic; using System.Xml; using System.Diagnostics; using KeePassLib.Interfaces; namespace KeePass.Util.XmlSerialization { public sealed partial class XmlSerializerEx : IXmlSerializerEx { private static char[] m_vEnumSeps = new char[] { ' ', '\t', '\r', '\n', '|', ',', ';', ':' }; private static KeePass.App.Configuration.AppConfigEx ReadAppConfigEx(XmlReader xr) { KeePass.App.Configuration.AppConfigEx o = new KeePass.App.Configuration.AppConfigEx(); if(SkipEmptyElement(xr)) return o; Debug.Assert(xr.NodeType == XmlNodeType.Element); xr.ReadStartElement(); xr.MoveToContent(); while(true) { XmlNodeType nt = xr.NodeType; if((nt == XmlNodeType.EndElement) || (nt == XmlNodeType.None)) break; if(nt != XmlNodeType.Element) { Debug.Assert(false); continue; } switch(xr.LocalName) { case "Meta": o.Meta = ReadAceMeta(xr); break; case "Application": o.Application = ReadAceApplication(xr); break; case "Logging": o.Logging = ReadAceLogging(xr); break; case "MainWindow": o.MainWindow = ReadAceMainWindow(xr); break; case "UI": o.UI = ReadAceUI(xr); break; case "Security": o.Security = ReadAceSecurity(xr); break; case "Native": o.Native = ReadAceNative(xr); break; case "PasswordGenerator": o.PasswordGenerator = ReadAcePasswordGenerator(xr); break; case "Defaults": o.Defaults = ReadAceDefaults(xr); break; case "Integration": o.Integration = ReadAceIntegration(xr); break; case "Custom": o.CustomSerialized = ReadArrayOfAceKvp(xr); break; default: Debug.Assert(false); xr.Skip(); break; } xr.MoveToContent(); } Debug.Assert(xr.NodeType == XmlNodeType.EndElement); xr.ReadEndElement(); return o; } private static KeePassLib.Translation.KPTranslation ReadKPTranslation(XmlReader xr) { KeePassLib.Translation.KPTranslation o = new KeePassLib.Translation.KPTranslation(); if(SkipEmptyElement(xr)) return o; Debug.Assert(xr.NodeType == XmlNodeType.Element); xr.ReadStartElement(); xr.MoveToContent(); while(true) { XmlNodeType nt = xr.NodeType; if((nt == XmlNodeType.EndElement) || (nt == XmlNodeType.None)) break; if(nt != XmlNodeType.Element) { Debug.Assert(false); continue; } switch(xr.LocalName) { case "Properties": o.Properties = ReadKPTranslationProperties(xr); break; case "StringTables": o.StringTables = ReadListOfKPStringTable(xr); break; case "Forms": o.Forms = ReadListOfKPFormCustomization(xr); break; case "UnusedText": o.UnusedText = ReadString(xr); break; default: Debug.Assert(false); xr.Skip(); break; } xr.MoveToContent(); } Debug.Assert(xr.NodeType == XmlNodeType.EndElement); xr.ReadEndElement(); return o; } private static KeePass.App.Configuration.AceMeta ReadAceMeta(XmlReader xr) { KeePass.App.Configuration.AceMeta o = new KeePass.App.Configuration.AceMeta(); if(SkipEmptyElement(xr)) return o; Debug.Assert(xr.NodeType == XmlNodeType.Element); xr.ReadStartElement(); xr.MoveToContent(); while(true) { XmlNodeType nt = xr.NodeType; if((nt == XmlNodeType.EndElement) || (nt == XmlNodeType.None)) break; if(nt != XmlNodeType.Element) { Debug.Assert(false); continue; } switch(xr.LocalName) { case "PreferUserConfiguration": o.PreferUserConfiguration = ReadBoolean(xr); break; case "OmitItemsWithDefaultValues": o.OmitItemsWithDefaultValues = ReadBoolean(xr); break; case "DpiFactorX": o.DpiFactorX = ReadDouble(xr); break; case "DpiFactorY": o.DpiFactorY = ReadDouble(xr); break; default: Debug.Assert(false); xr.Skip(); break; } xr.MoveToContent(); } Debug.Assert(xr.NodeType == XmlNodeType.EndElement); xr.ReadEndElement(); return o; } private static KeePass.App.Configuration.AceApplication ReadAceApplication(XmlReader xr) { KeePass.App.Configuration.AceApplication o = new KeePass.App.Configuration.AceApplication(); if(SkipEmptyElement(xr)) return o; Debug.Assert(xr.NodeType == XmlNodeType.Element); xr.ReadStartElement(); xr.MoveToContent(); while(true) { XmlNodeType nt = xr.NodeType; if((nt == XmlNodeType.EndElement) || (nt == XmlNodeType.None)) break; if(nt != XmlNodeType.Element) { Debug.Assert(false); continue; } switch(xr.LocalName) { case "LanguageFile": o.LanguageFile = ReadString(xr); break; case "HelpUseLocal": o.HelpUseLocal = ReadBoolean(xr); break; case "LastUpdateCheck": o.LastUpdateCheck = ReadString(xr); break; case "LastUsedFile": o.LastUsedFile = ReadIOConnectionInfo(xr); break; case "MostRecentlyUsed": o.MostRecentlyUsed = ReadAceMru(xr); break; case "RememberWorkingDirectories": o.RememberWorkingDirectories = ReadBoolean(xr); break; case "WorkingDirectories": o.WorkingDirectoriesSerialized = ReadArrayOfString(xr); break; case "Start": o.Start = ReadAceStartUp(xr); break; case "FileOpening": o.FileOpening = ReadAceOpenDb(xr); break; case "VerifyWrittenFileAfterSaving": o.VerifyWrittenFileAfterSaving = ReadBoolean(xr); break; case "UseTransactedFileWrites": o.UseTransactedFileWrites = ReadBoolean(xr); break; case "FileTxExtra": o.FileTxExtra = ReadBoolean(xr); break; case "UseFileLocks": o.UseFileLocks = ReadBoolean(xr); break; case "SaveForceSync": o.SaveForceSync = ReadBoolean(xr); break; case "FileClosing": o.FileClosing = ReadAceCloseDb(xr); break; case "TriggerSystem": o.TriggerSystem = ReadEcasTriggerSystem(xr); break; case "PluginCachePath": o.PluginCachePath = ReadString(xr); break; case "ExpirySoonDays": o.ExpirySoonDays = ReadInt32(xr); break; default: Debug.Assert(false); xr.Skip(); break; } xr.MoveToContent(); } Debug.Assert(xr.NodeType == XmlNodeType.EndElement); xr.ReadEndElement(); return o; } private static KeePass.App.Configuration.AceLogging ReadAceLogging(XmlReader xr) { KeePass.App.Configuration.AceLogging o = new KeePass.App.Configuration.AceLogging(); if(SkipEmptyElement(xr)) return o; Debug.Assert(xr.NodeType == XmlNodeType.Element); xr.ReadStartElement(); xr.MoveToContent(); while(true) { XmlNodeType nt = xr.NodeType; if((nt == XmlNodeType.EndElement) || (nt == XmlNodeType.None)) break; if(nt != XmlNodeType.Element) { Debug.Assert(false); continue; } switch(xr.LocalName) { case "Enabled": o.Enabled = ReadBoolean(xr); break; default: Debug.Assert(false); xr.Skip(); break; } xr.MoveToContent(); } Debug.Assert(xr.NodeType == XmlNodeType.EndElement); xr.ReadEndElement(); return o; } private static KeePass.App.Configuration.AceMainWindow ReadAceMainWindow(XmlReader xr) { KeePass.App.Configuration.AceMainWindow o = new KeePass.App.Configuration.AceMainWindow(); if(SkipEmptyElement(xr)) return o; Debug.Assert(xr.NodeType == XmlNodeType.Element); xr.ReadStartElement(); xr.MoveToContent(); while(true) { XmlNodeType nt = xr.NodeType; if((nt == XmlNodeType.EndElement) || (nt == XmlNodeType.None)) break; if(nt != XmlNodeType.Element) { Debug.Assert(false); continue; } switch(xr.LocalName) { case "X": o.X = ReadInt32(xr); break; case "Y": o.Y = ReadInt32(xr); break; case "Width": o.Width = ReadInt32(xr); break; case "Height": o.Height = ReadInt32(xr); break; case "Maximized": o.Maximized = ReadBoolean(xr); break; case "SplitterHorizontalFrac": o.SplitterHorizontalFrac = ReadDouble(xr); break; case "SplitterVerticalFrac": o.SplitterVerticalFrac = ReadDouble(xr); break; case "Layout": o.Layout = ReadAceMainWindowLayout(xr); break; case "AlwaysOnTop": o.AlwaysOnTop = ReadBoolean(xr); break; case "CloseButtonMinimizesWindow": o.CloseButtonMinimizesWindow = ReadBoolean(xr); break; case "EscMinimizesToTray": o.EscMinimizesToTray = ReadBoolean(xr); break; case "MinimizeToTray": o.MinimizeToTray = ReadBoolean(xr); break; case "ShowFullPathInTitle": o.ShowFullPathInTitle = ReadBoolean(xr); break; case "DropToBackAfterClipboardCopy": o.DropToBackAfterClipboardCopy = ReadBoolean(xr); break; case "MinimizeAfterClipboardCopy": o.MinimizeAfterClipboardCopy = ReadBoolean(xr); break; case "MinimizeAfterLocking": o.MinimizeAfterLocking = ReadBoolean(xr); break; case "MinimizeAfterOpeningDatabase": o.MinimizeAfterOpeningDatabase = ReadBoolean(xr); break; case "QuickFindSearchInPasswords": o.QuickFindSearchInPasswords = ReadBoolean(xr); break; case "QuickFindExcludeExpired": o.QuickFindExcludeExpired = ReadBoolean(xr); break; case "QuickFindDerefData": o.QuickFindDerefData = ReadBoolean(xr); break; case "FocusResultsAfterQuickFind": o.FocusResultsAfterQuickFind = ReadBoolean(xr); break; case "FocusQuickFindOnRestore": o.FocusQuickFindOnRestore = ReadBoolean(xr); break; case "FocusQuickFindOnUntray": o.FocusQuickFindOnUntray = ReadBoolean(xr); break; case "CopyUrlsInsteadOfOpening": o.CopyUrlsInsteadOfOpening = ReadBoolean(xr); break; case "EntrySelGroupSel": o.EntrySelGroupSel = ReadBoolean(xr); break; case "DisableSaveIfNotModified": o.DisableSaveIfNotModified = ReadBoolean(xr); break; case "HideCloseDatabaseButton": o.HideCloseDatabaseButton = ReadBoolean(xr); break; case "ToolBar": o.ToolBar = ReadAceToolBar(xr); break; case "EntryView": o.EntryView = ReadAceEntryView(xr); break; case "TanView": o.TanView = ReadAceTanView(xr); break; case "EntryListColumnCollection": o.EntryListColumns = ReadListOfAceColumn(xr); break; case "EntryListColumnDisplayOrder": o.EntryListColumnDisplayOrder = ReadString(xr); break; case "EntryListAutoResizeColumns": o.EntryListAutoResizeColumns = ReadBoolean(xr); break; case "EntryListAlternatingBgColors": o.EntryListAlternatingBgColors = ReadBoolean(xr); break; case "EntryListAlternatingBgColor": o.EntryListAlternatingBgColor = ReadInt32(xr); break; case "EntryListShowDerefData": o.EntryListShowDerefData = ReadBoolean(xr); break; case "EntryListShowDerefDataAsync": o.EntryListShowDerefDataAsync = ReadBoolean(xr); break; case "EntryListShowDerefDataAndRefs": o.EntryListShowDerefDataAndRefs = ReadBoolean(xr); break; case "ListSorting": o.ListSorting = ReadListSorter(xr); break; case "ListGrouping": o.ListGrouping = ReadInt32(xr); break; case "ShowEntriesOfSubGroups": o.ShowEntriesOfSubGroups = ReadBoolean(xr); break; default: Debug.Assert(false); xr.Skip(); break; } xr.MoveToContent(); } Debug.Assert(xr.NodeType == XmlNodeType.EndElement); xr.ReadEndElement(); return o; } private static KeePass.App.Configuration.AceUI ReadAceUI(XmlReader xr) { KeePass.App.Configuration.AceUI o = new KeePass.App.Configuration.AceUI(); if(SkipEmptyElement(xr)) return o; Debug.Assert(xr.NodeType == XmlNodeType.Element); xr.ReadStartElement(); xr.MoveToContent(); while(true) { XmlNodeType nt = xr.NodeType; if((nt == XmlNodeType.EndElement) || (nt == XmlNodeType.None)) break; if(nt != XmlNodeType.Element) { Debug.Assert(false); continue; } switch(xr.LocalName) { case "TrayIcon": o.TrayIcon = ReadAceTrayIcon(xr); break; case "Hiding": o.Hiding = ReadAceHiding(xr); break; case "RepeatPasswordOnlyWhenHidden": o.RepeatPasswordOnlyWhenHidden = ReadBoolean(xr); break; case "StandardFont": o.StandardFont = ReadAceFont(xr); break; case "PasswordFont": o.PasswordFont = ReadAceFont(xr); break; case "ForceSystemFontUnix": o.ForceSystemFontUnix = ReadBoolean(xr); break; case "BannerStyle": o.BannerStyle = ReadBannerStyle(xr); break; case "ShowImportStatusDialog": o.ShowImportStatusDialog = ReadBoolean(xr); break; case "ShowDbMntncResultsDialog": o.ShowDbMntncResultsDialog = ReadBoolean(xr); break; case "ShowRecycleConfirmDialog": o.ShowRecycleConfirmDialog = ReadBoolean(xr); break; case "ShowEmSheetDialog": o.ShowEmSheetDialog = ReadBoolean(xr); break; case "ToolStripRenderer": o.ToolStripRenderer = ReadString(xr); break; case "OptimizeForScreenReader": o.OptimizeForScreenReader = ReadBoolean(xr); break; case "DataViewerRect": o.DataViewerRect = ReadString(xr); break; case "DataEditorRect": o.DataEditorRect = ReadString(xr); break; case "DataEditorFont": o.DataEditorFont = ReadAceFont(xr); break; case "DataEditorWordWrap": o.DataEditorWordWrap = ReadBoolean(xr); break; case "CharPickerRect": o.CharPickerRect = ReadString(xr); break; case "AutoTypeCtxRect": o.AutoTypeCtxRect = ReadString(xr); break; case "AutoTypeCtxFlags": o.AutoTypeCtxFlags = ReadInt64(xr); break; case "AutoTypeCtxColumnWidths": o.AutoTypeCtxColumnWidths = ReadString(xr); break; case "UIFlags": o.UIFlags = ReadUInt64(xr); break; case "KeyCreationFlags": o.KeyCreationFlags = ReadUInt64(xr); break; case "KeyPromptFlags": o.KeyPromptFlags = ReadUInt64(xr); break; case "ShowAdvAutoTypeCommands": o.ShowAdvAutoTypeCommands = ReadBoolean(xr); break; case "SecureDesktopPlaySound": o.SecureDesktopPlaySound = ReadBoolean(xr); break; default: Debug.Assert(false); xr.Skip(); break; } xr.MoveToContent(); } Debug.Assert(xr.NodeType == XmlNodeType.EndElement); xr.ReadEndElement(); return o; } private static KeePass.App.Configuration.AceSecurity ReadAceSecurity(XmlReader xr) { KeePass.App.Configuration.AceSecurity o = new KeePass.App.Configuration.AceSecurity(); if(SkipEmptyElement(xr)) return o; Debug.Assert(xr.NodeType == XmlNodeType.Element); xr.ReadStartElement(); xr.MoveToContent(); while(true) { XmlNodeType nt = xr.NodeType; if((nt == XmlNodeType.EndElement) || (nt == XmlNodeType.None)) break; if(nt != XmlNodeType.Element) { Debug.Assert(false); continue; } switch(xr.LocalName) { case "WorkspaceLocking": o.WorkspaceLocking = ReadAceWorkspaceLocking(xr); break; case "Policy": o.Policy = ReadAppPolicyFlags(xr); break; case "MasterPassword": o.MasterPassword = ReadAceMasterPassword(xr); break; case "MasterKeyTries": o.MasterKeyTries = ReadInt32(xr); break; case "MasterKeyOnSecureDesktop": o.MasterKeyOnSecureDesktop = ReadBoolean(xr); break; case "MasterKeyExpiryRec": o.MasterKeyExpiryRec = ReadString(xr); break; case "ClipboardClearOnExit": o.ClipboardClearOnExit = ReadBoolean(xr); break; case "ClipboardClearAfterSeconds": o.ClipboardClearAfterSeconds = ReadInt32(xr); break; case "UseClipboardViewerIgnoreFormat": o.UseClipboardViewerIgnoreFormat = ReadBoolean(xr); break; case "ClearKeyCommandLineParams": o.ClearKeyCommandLineParams = ReadBoolean(xr); break; case "SslCertsAcceptInvalid": o.SslCertsAcceptInvalid = ReadBoolean(xr); break; default: Debug.Assert(false); xr.Skip(); break; } xr.MoveToContent(); } Debug.Assert(xr.NodeType == XmlNodeType.EndElement); xr.ReadEndElement(); return o; } private static KeePass.App.Configuration.AceNative ReadAceNative(XmlReader xr) { KeePass.App.Configuration.AceNative o = new KeePass.App.Configuration.AceNative(); if(SkipEmptyElement(xr)) return o; Debug.Assert(xr.NodeType == XmlNodeType.Element); xr.ReadStartElement(); xr.MoveToContent(); while(true) { XmlNodeType nt = xr.NodeType; if((nt == XmlNodeType.EndElement) || (nt == XmlNodeType.None)) break; if(nt != XmlNodeType.Element) { Debug.Assert(false); continue; } switch(xr.LocalName) { case "NativeKeyTransformations": o.NativeKeyTransformations = ReadBoolean(xr); break; default: Debug.Assert(false); xr.Skip(); break; } xr.MoveToContent(); } Debug.Assert(xr.NodeType == XmlNodeType.EndElement); xr.ReadEndElement(); return o; } private static KeePass.App.Configuration.AcePasswordGenerator ReadAcePasswordGenerator(XmlReader xr) { KeePass.App.Configuration.AcePasswordGenerator o = new KeePass.App.Configuration.AcePasswordGenerator(); if(SkipEmptyElement(xr)) return o; Debug.Assert(xr.NodeType == XmlNodeType.Element); xr.ReadStartElement(); xr.MoveToContent(); while(true) { XmlNodeType nt = xr.NodeType; if((nt == XmlNodeType.EndElement) || (nt == XmlNodeType.None)) break; if(nt != XmlNodeType.Element) { Debug.Assert(false); continue; } switch(xr.LocalName) { case "AutoGeneratedPasswordsProfile": o.AutoGeneratedPasswordsProfile = ReadPwProfile(xr); break; case "LastUsedProfile": o.LastUsedProfile = ReadPwProfile(xr); break; case "UserProfiles": o.UserProfiles = ReadListOfPwProfile(xr); break; default: Debug.Assert(false); xr.Skip(); break; } xr.MoveToContent(); } Debug.Assert(xr.NodeType == XmlNodeType.EndElement); xr.ReadEndElement(); return o; } private static KeePass.App.Configuration.AceDefaults ReadAceDefaults(XmlReader xr) { KeePass.App.Configuration.AceDefaults o = new KeePass.App.Configuration.AceDefaults(); if(SkipEmptyElement(xr)) return o; Debug.Assert(xr.NodeType == XmlNodeType.Element); xr.ReadStartElement(); xr.MoveToContent(); while(true) { XmlNodeType nt = xr.NodeType; if((nt == XmlNodeType.EndElement) || (nt == XmlNodeType.None)) break; if(nt != XmlNodeType.Element) { Debug.Assert(false); continue; } switch(xr.LocalName) { case "NewEntryExpiresInDays": o.NewEntryExpiresInDays = ReadInt32(xr); break; case "OptionsTabIndex": o.OptionsTabIndex = ReadUInt32(xr); break; case "TanCharacters": o.TanCharacters = ReadString(xr); break; case "TanExpiresOnUse": o.TanExpiresOnUse = ReadBoolean(xr); break; case "SearchParameters": o.SearchParameters = ReadSearchParameters(xr); break; case "FileSaveAsDirectory": o.FileSaveAsDirectory = ReadString(xr); break; case "RememberKeySources": o.RememberKeySources = ReadBoolean(xr); break; case "KeySources": o.KeySources = ReadListOfAceKeyAssoc(xr); break; case "CustomColors": o.CustomColors = ReadString(xr); break; case "WinFavsBaseFolderName": o.WinFavsBaseFolderName = ReadString(xr); break; case "WinFavsFileNamePrefix": o.WinFavsFileNamePrefix = ReadString(xr); break; case "WinFavsFileNameSuffix": o.WinFavsFileNameSuffix = ReadString(xr); break; case "RecycleBinCollapse": o.RecycleBinCollapse = ReadBoolean(xr); break; default: Debug.Assert(false); xr.Skip(); break; } xr.MoveToContent(); } Debug.Assert(xr.NodeType == XmlNodeType.EndElement); xr.ReadEndElement(); return o; } private static KeePass.App.Configuration.AceIntegration ReadAceIntegration(XmlReader xr) { KeePass.App.Configuration.AceIntegration o = new KeePass.App.Configuration.AceIntegration(); if(SkipEmptyElement(xr)) return o; Debug.Assert(xr.NodeType == XmlNodeType.Element); xr.ReadStartElement(); xr.MoveToContent(); while(true) { XmlNodeType nt = xr.NodeType; if((nt == XmlNodeType.EndElement) || (nt == XmlNodeType.None)) break; if(nt != XmlNodeType.Element) { Debug.Assert(false); continue; } switch(xr.LocalName) { case "HotKeyGlobalAutoType": o.HotKeyGlobalAutoType = ReadUInt64(xr); break; case "HotKeySelectedAutoType": o.HotKeySelectedAutoType = ReadUInt64(xr); break; case "HotKeyShowWindow": o.HotKeyShowWindow = ReadUInt64(xr); break; case "HotKeyEntryMenu": o.HotKeyEntryMenu = ReadUInt64(xr); break; case "CheckHotKeys": o.CheckHotKeys = ReadBoolean(xr); break; case "UrlOverride": o.UrlOverride = ReadString(xr); break; case "UrlSchemeOverrides": o.UrlSchemeOverrides = ReadAceUrlSchemeOverrides(xr); break; case "SearchKeyFiles": o.SearchKeyFiles = ReadBoolean(xr); break; case "SearchKeyFilesOnRemovableMedia": o.SearchKeyFilesOnRemovableMedia = ReadBoolean(xr); break; case "LimitToSingleInstance": o.LimitToSingleInstance = ReadBoolean(xr); break; case "AutoTypeMatchByTitle": o.AutoTypeMatchByTitle = ReadBoolean(xr); break; case "AutoTypeMatchByUrlInTitle": o.AutoTypeMatchByUrlInTitle = ReadBoolean(xr); break; case "AutoTypeMatchByUrlHostInTitle": o.AutoTypeMatchByUrlHostInTitle = ReadBoolean(xr); break; case "AutoTypeMatchByTagInTitle": o.AutoTypeMatchByTagInTitle = ReadBoolean(xr); break; case "AutoTypeExpiredCanMatch": o.AutoTypeExpiredCanMatch = ReadBoolean(xr); break; case "AutoTypeAlwaysShowSelDialog": o.AutoTypeAlwaysShowSelDialog = ReadBoolean(xr); break; case "AutoTypePrependInitSequenceForIE": o.AutoTypePrependInitSequenceForIE = ReadBoolean(xr); break; case "AutoTypeReleaseAltWithKeyPress": o.AutoTypeReleaseAltWithKeyPress = ReadBoolean(xr); break; case "AutoTypeAdjustKeyboardLayout": o.AutoTypeAdjustKeyboardLayout = ReadBoolean(xr); break; case "AutoTypeAllowInterleaved": o.AutoTypeAllowInterleaved = ReadBoolean(xr); break; case "AutoTypeCancelOnWindowChange": o.AutoTypeCancelOnWindowChange = ReadBoolean(xr); break; case "AutoTypeCancelOnTitleChange": o.AutoTypeCancelOnTitleChange = ReadBoolean(xr); break; case "AutoTypeInterKeyDelay": o.AutoTypeInterKeyDelay = ReadInt32(xr); break; case "AutoTypeAbortOnWindows": o.AutoTypeAbortOnWindows = ReadListOfString(xr); break; case "ProxyType": o.ProxyType = ReadProxyServerType(xr); break; case "ProxyAddress": o.ProxyAddress = ReadString(xr); break; case "ProxyPort": o.ProxyPort = ReadString(xr); break; case "ProxyAuthType": o.ProxyAuthType = ReadProxyAuthType(xr); break; case "ProxyUserName": o.ProxyUserName = ReadString(xr); break; case "ProxyPassword": o.ProxyPassword = ReadString(xr); break; default: Debug.Assert(false); xr.Skip(); break; } xr.MoveToContent(); } Debug.Assert(xr.NodeType == XmlNodeType.EndElement); xr.ReadEndElement(); return o; } private static KeePass.App.Configuration.AceKvp[] ReadArrayOfAceKvp(XmlReader xr) { List l = new List(); if(SkipEmptyElement(xr)) return l.ToArray(); Debug.Assert(xr.NodeType == XmlNodeType.Element); xr.ReadStartElement(); xr.MoveToContent(); while(true) { XmlNodeType nt = xr.NodeType; if((nt == XmlNodeType.EndElement) || (nt == XmlNodeType.None)) break; if(nt != XmlNodeType.Element) { Debug.Assert(false); continue; } KeePass.App.Configuration.AceKvp oElem = ReadAceKvp(xr); l.Add(oElem); xr.MoveToContent(); } Debug.Assert(xr.NodeType == XmlNodeType.EndElement); xr.ReadEndElement(); return l.ToArray(); } private static KeePassLib.Translation.KPTranslationProperties ReadKPTranslationProperties(XmlReader xr) { KeePassLib.Translation.KPTranslationProperties o = new KeePassLib.Translation.KPTranslationProperties(); if(SkipEmptyElement(xr)) return o; Debug.Assert(xr.NodeType == XmlNodeType.Element); xr.ReadStartElement(); xr.MoveToContent(); while(true) { XmlNodeType nt = xr.NodeType; if((nt == XmlNodeType.EndElement) || (nt == XmlNodeType.None)) break; if(nt != XmlNodeType.Element) { Debug.Assert(false); continue; } switch(xr.LocalName) { case "Application": o.Application = ReadString(xr); break; case "ApplicationVersion": o.ApplicationVersion = ReadString(xr); break; case "NameEnglish": o.NameEnglish = ReadString(xr); break; case "NameNative": o.NameNative = ReadString(xr); break; case "Iso6391Code": o.Iso6391Code = ReadString(xr); break; case "RightToLeft": o.RightToLeft = ReadBoolean(xr); break; case "AuthorName": o.AuthorName = ReadString(xr); break; case "AuthorContact": o.AuthorContact = ReadString(xr); break; case "Generator": o.Generator = ReadString(xr); break; case "FileUuid": o.FileUuid = ReadString(xr); break; case "LastModified": o.LastModified = ReadString(xr); break; default: Debug.Assert(false); xr.Skip(); break; } xr.MoveToContent(); } Debug.Assert(xr.NodeType == XmlNodeType.EndElement); xr.ReadEndElement(); return o; } private static System.Collections.Generic.List ReadListOfKPStringTable(XmlReader xr) { System.Collections.Generic.List o = new System.Collections.Generic.List(); if(SkipEmptyElement(xr)) return o; Debug.Assert(xr.NodeType == XmlNodeType.Element); xr.ReadStartElement(); xr.MoveToContent(); while(true) { XmlNodeType nt = xr.NodeType; if((nt == XmlNodeType.EndElement) || (nt == XmlNodeType.None)) break; if(nt != XmlNodeType.Element) { Debug.Assert(false); continue; } KeePassLib.Translation.KPStringTable oElem = ReadKPStringTable(xr); o.Add(oElem); xr.MoveToContent(); } Debug.Assert(xr.NodeType == XmlNodeType.EndElement); xr.ReadEndElement(); return o; } private static System.Collections.Generic.List ReadListOfKPFormCustomization(XmlReader xr) { System.Collections.Generic.List o = new System.Collections.Generic.List(); if(SkipEmptyElement(xr)) return o; Debug.Assert(xr.NodeType == XmlNodeType.Element); xr.ReadStartElement(); xr.MoveToContent(); while(true) { XmlNodeType nt = xr.NodeType; if((nt == XmlNodeType.EndElement) || (nt == XmlNodeType.None)) break; if(nt != XmlNodeType.Element) { Debug.Assert(false); continue; } KeePassLib.Translation.KPFormCustomization oElem = ReadKPFormCustomization(xr); o.Add(oElem); xr.MoveToContent(); } Debug.Assert(xr.NodeType == XmlNodeType.EndElement); xr.ReadEndElement(); return o; } private static System.String ReadString(XmlReader xr) { return xr.ReadElementString(); } private static System.Boolean ReadBoolean(XmlReader xr) { string strValue = xr.ReadElementString(); return XmlConvert.ToBoolean(strValue); } private static System.Double ReadDouble(XmlReader xr) { string strValue = xr.ReadElementString(); return XmlConvert.ToDouble(strValue); } private static KeePassLib.Serialization.IOConnectionInfo ReadIOConnectionInfo(XmlReader xr) { KeePassLib.Serialization.IOConnectionInfo o = new KeePassLib.Serialization.IOConnectionInfo(); if(SkipEmptyElement(xr)) return o; Debug.Assert(xr.NodeType == XmlNodeType.Element); xr.ReadStartElement(); xr.MoveToContent(); while(true) { XmlNodeType nt = xr.NodeType; if((nt == XmlNodeType.EndElement) || (nt == XmlNodeType.None)) break; if(nt != XmlNodeType.Element) { Debug.Assert(false); continue; } switch(xr.LocalName) { case "Path": o.Path = ReadString(xr); break; case "UserName": o.UserName = ReadString(xr); break; case "Password": o.Password = ReadString(xr); break; case "CredProtMode": o.CredProtMode = ReadIOCredProtMode(xr); break; case "CredSaveMode": o.CredSaveMode = ReadIOCredSaveMode(xr); break; case "PropertiesEx": o.PropertiesEx = ReadString(xr); break; default: Debug.Assert(false); xr.Skip(); break; } xr.MoveToContent(); } Debug.Assert(xr.NodeType == XmlNodeType.EndElement); xr.ReadEndElement(); return o; } private static KeePass.App.Configuration.AceMru ReadAceMru(XmlReader xr) { KeePass.App.Configuration.AceMru o = new KeePass.App.Configuration.AceMru(); if(SkipEmptyElement(xr)) return o; Debug.Assert(xr.NodeType == XmlNodeType.Element); xr.ReadStartElement(); xr.MoveToContent(); while(true) { XmlNodeType nt = xr.NodeType; if((nt == XmlNodeType.EndElement) || (nt == XmlNodeType.None)) break; if(nt != XmlNodeType.Element) { Debug.Assert(false); continue; } switch(xr.LocalName) { case "MaxItemCount": o.MaxItemCount = ReadUInt32(xr); break; case "Items": o.Items = ReadListOfIOConnectionInfo(xr); break; default: Debug.Assert(false); xr.Skip(); break; } xr.MoveToContent(); } Debug.Assert(xr.NodeType == XmlNodeType.EndElement); xr.ReadEndElement(); return o; } private static System.String[] ReadArrayOfString(XmlReader xr) { List l = new List(); if(SkipEmptyElement(xr)) return l.ToArray(); Debug.Assert(xr.NodeType == XmlNodeType.Element); xr.ReadStartElement(); xr.MoveToContent(); while(true) { XmlNodeType nt = xr.NodeType; if((nt == XmlNodeType.EndElement) || (nt == XmlNodeType.None)) break; if(nt != XmlNodeType.Element) { Debug.Assert(false); continue; } System.String oElem = ReadString(xr); l.Add(oElem); xr.MoveToContent(); } Debug.Assert(xr.NodeType == XmlNodeType.EndElement); xr.ReadEndElement(); return l.ToArray(); } private static KeePass.App.Configuration.AceStartUp ReadAceStartUp(XmlReader xr) { KeePass.App.Configuration.AceStartUp o = new KeePass.App.Configuration.AceStartUp(); if(SkipEmptyElement(xr)) return o; Debug.Assert(xr.NodeType == XmlNodeType.Element); xr.ReadStartElement(); xr.MoveToContent(); while(true) { XmlNodeType nt = xr.NodeType; if((nt == XmlNodeType.EndElement) || (nt == XmlNodeType.None)) break; if(nt != XmlNodeType.Element) { Debug.Assert(false); continue; } switch(xr.LocalName) { case "OpenLastFile": o.OpenLastFile = ReadBoolean(xr); break; case "CheckForUpdate": o.CheckForUpdate = ReadBoolean(xr); break; case "CheckForUpdateConfigured": o.CheckForUpdateConfigured = ReadBoolean(xr); break; case "MinimizedAndLocked": o.MinimizedAndLocked = ReadBoolean(xr); break; case "PluginCacheDeleteOld": o.PluginCacheDeleteOld = ReadBoolean(xr); break; case "PluginCacheClearOnce": o.PluginCacheClearOnce = ReadBoolean(xr); break; default: Debug.Assert(false); xr.Skip(); break; } xr.MoveToContent(); } Debug.Assert(xr.NodeType == XmlNodeType.EndElement); xr.ReadEndElement(); return o; } private static KeePass.App.Configuration.AceOpenDb ReadAceOpenDb(XmlReader xr) { KeePass.App.Configuration.AceOpenDb o = new KeePass.App.Configuration.AceOpenDb(); if(SkipEmptyElement(xr)) return o; Debug.Assert(xr.NodeType == XmlNodeType.Element); xr.ReadStartElement(); xr.MoveToContent(); while(true) { XmlNodeType nt = xr.NodeType; if((nt == XmlNodeType.EndElement) || (nt == XmlNodeType.None)) break; if(nt != XmlNodeType.Element) { Debug.Assert(false); continue; } switch(xr.LocalName) { case "ShowExpiredEntries": o.ShowExpiredEntries = ReadBoolean(xr); break; case "ShowSoonToExpireEntries": o.ShowSoonToExpireEntries = ReadBoolean(xr); break; default: Debug.Assert(false); xr.Skip(); break; } xr.MoveToContent(); } Debug.Assert(xr.NodeType == XmlNodeType.EndElement); xr.ReadEndElement(); return o; } private static KeePass.App.Configuration.AceCloseDb ReadAceCloseDb(XmlReader xr) { KeePass.App.Configuration.AceCloseDb o = new KeePass.App.Configuration.AceCloseDb(); if(SkipEmptyElement(xr)) return o; Debug.Assert(xr.NodeType == XmlNodeType.Element); xr.ReadStartElement(); xr.MoveToContent(); while(true) { XmlNodeType nt = xr.NodeType; if((nt == XmlNodeType.EndElement) || (nt == XmlNodeType.None)) break; if(nt != XmlNodeType.Element) { Debug.Assert(false); continue; } switch(xr.LocalName) { case "AutoSave": o.AutoSave = ReadBoolean(xr); break; default: Debug.Assert(false); xr.Skip(); break; } xr.MoveToContent(); } Debug.Assert(xr.NodeType == XmlNodeType.EndElement); xr.ReadEndElement(); return o; } private static KeePass.Ecas.EcasTriggerSystem ReadEcasTriggerSystem(XmlReader xr) { KeePass.Ecas.EcasTriggerSystem o = new KeePass.Ecas.EcasTriggerSystem(); if(SkipEmptyElement(xr)) return o; Debug.Assert(xr.NodeType == XmlNodeType.Element); xr.ReadStartElement(); xr.MoveToContent(); while(true) { XmlNodeType nt = xr.NodeType; if((nt == XmlNodeType.EndElement) || (nt == XmlNodeType.None)) break; if(nt != XmlNodeType.Element) { Debug.Assert(false); continue; } switch(xr.LocalName) { case "Enabled": o.Enabled = ReadBoolean(xr); break; case "Triggers": o.TriggerArrayForSerialization = ReadArrayOfEcasTrigger(xr); break; default: Debug.Assert(false); xr.Skip(); break; } xr.MoveToContent(); } Debug.Assert(xr.NodeType == XmlNodeType.EndElement); xr.ReadEndElement(); return o; } private static System.Int32 ReadInt32(XmlReader xr) { string strValue = xr.ReadElementString(); return XmlConvert.ToInt32(strValue); } private static Dictionary m_dictAceMainWindowLayout = null; private static KeePass.App.Configuration.AceMainWindowLayout ReadAceMainWindowLayout(XmlReader xr) { if(m_dictAceMainWindowLayout == null) { m_dictAceMainWindowLayout = new Dictionary(); m_dictAceMainWindowLayout["Default"] = KeePass.App.Configuration.AceMainWindowLayout.Default; m_dictAceMainWindowLayout["SideBySide"] = KeePass.App.Configuration.AceMainWindowLayout.SideBySide; } string strValue = xr.ReadElementString(); KeePass.App.Configuration.AceMainWindowLayout eResult; if(!m_dictAceMainWindowLayout.TryGetValue(strValue, out eResult)) { Debug.Assert(false); } return eResult; } private static KeePass.App.Configuration.AceToolBar ReadAceToolBar(XmlReader xr) { KeePass.App.Configuration.AceToolBar o = new KeePass.App.Configuration.AceToolBar(); if(SkipEmptyElement(xr)) return o; Debug.Assert(xr.NodeType == XmlNodeType.Element); xr.ReadStartElement(); xr.MoveToContent(); while(true) { XmlNodeType nt = xr.NodeType; if((nt == XmlNodeType.EndElement) || (nt == XmlNodeType.None)) break; if(nt != XmlNodeType.Element) { Debug.Assert(false); continue; } switch(xr.LocalName) { case "Show": o.Show = ReadBoolean(xr); break; default: Debug.Assert(false); xr.Skip(); break; } xr.MoveToContent(); } Debug.Assert(xr.NodeType == XmlNodeType.EndElement); xr.ReadEndElement(); return o; } private static KeePass.App.Configuration.AceEntryView ReadAceEntryView(XmlReader xr) { KeePass.App.Configuration.AceEntryView o = new KeePass.App.Configuration.AceEntryView(); if(SkipEmptyElement(xr)) return o; Debug.Assert(xr.NodeType == XmlNodeType.Element); xr.ReadStartElement(); xr.MoveToContent(); while(true) { XmlNodeType nt = xr.NodeType; if((nt == XmlNodeType.EndElement) || (nt == XmlNodeType.None)) break; if(nt != XmlNodeType.Element) { Debug.Assert(false); continue; } switch(xr.LocalName) { case "Show": o.Show = ReadBoolean(xr); break; default: Debug.Assert(false); xr.Skip(); break; } xr.MoveToContent(); } Debug.Assert(xr.NodeType == XmlNodeType.EndElement); xr.ReadEndElement(); return o; } private static KeePass.App.Configuration.AceTanView ReadAceTanView(XmlReader xr) { KeePass.App.Configuration.AceTanView o = new KeePass.App.Configuration.AceTanView(); if(SkipEmptyElement(xr)) return o; Debug.Assert(xr.NodeType == XmlNodeType.Element); xr.ReadStartElement(); xr.MoveToContent(); while(true) { XmlNodeType nt = xr.NodeType; if((nt == XmlNodeType.EndElement) || (nt == XmlNodeType.None)) break; if(nt != XmlNodeType.Element) { Debug.Assert(false); continue; } switch(xr.LocalName) { case "UseSimpleView": o.UseSimpleView = ReadBoolean(xr); break; case "ShowIndices": o.ShowIndices = ReadBoolean(xr); break; default: Debug.Assert(false); xr.Skip(); break; } xr.MoveToContent(); } Debug.Assert(xr.NodeType == XmlNodeType.EndElement); xr.ReadEndElement(); return o; } private static System.Collections.Generic.List ReadListOfAceColumn(XmlReader xr) { System.Collections.Generic.List o = new System.Collections.Generic.List(); if(SkipEmptyElement(xr)) return o; Debug.Assert(xr.NodeType == XmlNodeType.Element); xr.ReadStartElement(); xr.MoveToContent(); while(true) { XmlNodeType nt = xr.NodeType; if((nt == XmlNodeType.EndElement) || (nt == XmlNodeType.None)) break; if(nt != XmlNodeType.Element) { Debug.Assert(false); continue; } KeePass.App.Configuration.AceColumn oElem = ReadAceColumn(xr); o.Add(oElem); xr.MoveToContent(); } Debug.Assert(xr.NodeType == XmlNodeType.EndElement); xr.ReadEndElement(); return o; } private static KeePass.UI.ListSorter ReadListSorter(XmlReader xr) { KeePass.UI.ListSorter o = new KeePass.UI.ListSorter(); if(SkipEmptyElement(xr)) return o; Debug.Assert(xr.NodeType == XmlNodeType.Element); xr.ReadStartElement(); xr.MoveToContent(); while(true) { XmlNodeType nt = xr.NodeType; if((nt == XmlNodeType.EndElement) || (nt == XmlNodeType.None)) break; if(nt != XmlNodeType.Element) { Debug.Assert(false); continue; } switch(xr.LocalName) { case "Column": o.Column = ReadInt32(xr); break; case "Order": o.Order = ReadSortOrder(xr); break; case "CompareNaturally": o.CompareNaturally = ReadBoolean(xr); break; case "CompareTimes": o.CompareTimes = ReadBoolean(xr); break; default: Debug.Assert(false); xr.Skip(); break; } xr.MoveToContent(); } Debug.Assert(xr.NodeType == XmlNodeType.EndElement); xr.ReadEndElement(); return o; } private static KeePass.App.Configuration.AceTrayIcon ReadAceTrayIcon(XmlReader xr) { KeePass.App.Configuration.AceTrayIcon o = new KeePass.App.Configuration.AceTrayIcon(); if(SkipEmptyElement(xr)) return o; Debug.Assert(xr.NodeType == XmlNodeType.Element); xr.ReadStartElement(); xr.MoveToContent(); while(true) { XmlNodeType nt = xr.NodeType; if((nt == XmlNodeType.EndElement) || (nt == XmlNodeType.None)) break; if(nt != XmlNodeType.Element) { Debug.Assert(false); continue; } switch(xr.LocalName) { case "ShowOnlyIfTrayed": o.ShowOnlyIfTrayed = ReadBoolean(xr); break; case "GrayIcon": o.GrayIcon = ReadBoolean(xr); break; case "SingleClickDefault": o.SingleClickDefault = ReadBoolean(xr); break; default: Debug.Assert(false); xr.Skip(); break; } xr.MoveToContent(); } Debug.Assert(xr.NodeType == XmlNodeType.EndElement); xr.ReadEndElement(); return o; } private static KeePass.App.Configuration.AceHiding ReadAceHiding(XmlReader xr) { KeePass.App.Configuration.AceHiding o = new KeePass.App.Configuration.AceHiding(); if(SkipEmptyElement(xr)) return o; Debug.Assert(xr.NodeType == XmlNodeType.Element); xr.ReadStartElement(); xr.MoveToContent(); while(true) { XmlNodeType nt = xr.NodeType; if((nt == XmlNodeType.EndElement) || (nt == XmlNodeType.None)) break; if(nt != XmlNodeType.Element) { Debug.Assert(false); continue; } switch(xr.LocalName) { case "SeparateHidingSettings": o.SeparateHidingSettings = ReadBoolean(xr); break; case "HideInEntryWindow": o.HideInEntryWindow = ReadBoolean(xr); break; case "UnhideButtonAlsoUnhidesSource": o.UnhideButtonAlsoUnhidesSource = ReadBoolean(xr); break; default: Debug.Assert(false); xr.Skip(); break; } xr.MoveToContent(); } Debug.Assert(xr.NodeType == XmlNodeType.EndElement); xr.ReadEndElement(); return o; } private static KeePass.App.Configuration.AceFont ReadAceFont(XmlReader xr) { KeePass.App.Configuration.AceFont o = new KeePass.App.Configuration.AceFont(); if(SkipEmptyElement(xr)) return o; Debug.Assert(xr.NodeType == XmlNodeType.Element); xr.ReadStartElement(); xr.MoveToContent(); while(true) { XmlNodeType nt = xr.NodeType; if((nt == XmlNodeType.EndElement) || (nt == XmlNodeType.None)) break; if(nt != XmlNodeType.Element) { Debug.Assert(false); continue; } switch(xr.LocalName) { case "Family": o.Family = ReadString(xr); break; case "Size": o.Size = ReadSingle(xr); break; case "GraphicsUnit": o.GraphicsUnit = ReadGraphicsUnit(xr); break; case "Style": o.Style = ReadFontStyle(xr); break; case "OverrideUIDefault": o.OverrideUIDefault = ReadBoolean(xr); break; default: Debug.Assert(false); xr.Skip(); break; } xr.MoveToContent(); } Debug.Assert(xr.NodeType == XmlNodeType.EndElement); xr.ReadEndElement(); return o; } private static Dictionary m_dictBannerStyle = null; private static KeePass.UI.BannerStyle ReadBannerStyle(XmlReader xr) { if(m_dictBannerStyle == null) { m_dictBannerStyle = new Dictionary(); m_dictBannerStyle["Default"] = KeePass.UI.BannerStyle.Default; m_dictBannerStyle["WinXPLogin"] = KeePass.UI.BannerStyle.WinXPLogin; m_dictBannerStyle["WinVistaBlack"] = KeePass.UI.BannerStyle.WinVistaBlack; m_dictBannerStyle["KeePassWin32"] = KeePass.UI.BannerStyle.KeePassWin32; m_dictBannerStyle["BlueCarbon"] = KeePass.UI.BannerStyle.BlueCarbon; } string strValue = xr.ReadElementString(); KeePass.UI.BannerStyle eResult; if(!m_dictBannerStyle.TryGetValue(strValue, out eResult)) { Debug.Assert(false); } return eResult; } private static System.Int64 ReadInt64(XmlReader xr) { string strValue = xr.ReadElementString(); return XmlConvert.ToInt64(strValue); } private static System.UInt64 ReadUInt64(XmlReader xr) { string strValue = xr.ReadElementString(); return XmlConvert.ToUInt64(strValue); } private static KeePass.App.Configuration.AceWorkspaceLocking ReadAceWorkspaceLocking(XmlReader xr) { KeePass.App.Configuration.AceWorkspaceLocking o = new KeePass.App.Configuration.AceWorkspaceLocking(); if(SkipEmptyElement(xr)) return o; Debug.Assert(xr.NodeType == XmlNodeType.Element); xr.ReadStartElement(); xr.MoveToContent(); while(true) { XmlNodeType nt = xr.NodeType; if((nt == XmlNodeType.EndElement) || (nt == XmlNodeType.None)) break; if(nt != XmlNodeType.Element) { Debug.Assert(false); continue; } switch(xr.LocalName) { case "LockOnWindowMinimize": o.LockOnWindowMinimize = ReadBoolean(xr); break; case "LockOnWindowMinimizeToTray": o.LockOnWindowMinimizeToTray = ReadBoolean(xr); break; case "LockOnSessionSwitch": o.LockOnSessionSwitch = ReadBoolean(xr); break; case "LockOnSuspend": o.LockOnSuspend = ReadBoolean(xr); break; case "LockOnRemoteControlChange": o.LockOnRemoteControlChange = ReadBoolean(xr); break; case "LockAfterTime": o.LockAfterTime = ReadUInt32(xr); break; case "LockAfterGlobalTime": o.LockAfterGlobalTime = ReadUInt32(xr); break; case "ExitInsteadOfLockingAfterTime": o.ExitInsteadOfLockingAfterTime = ReadBoolean(xr); break; case "AlwaysExitInsteadOfLocking": o.AlwaysExitInsteadOfLocking = ReadBoolean(xr); break; default: Debug.Assert(false); xr.Skip(); break; } xr.MoveToContent(); } Debug.Assert(xr.NodeType == XmlNodeType.EndElement); xr.ReadEndElement(); return o; } private static KeePass.App.AppPolicyFlags ReadAppPolicyFlags(XmlReader xr) { KeePass.App.AppPolicyFlags o = new KeePass.App.AppPolicyFlags(); if(SkipEmptyElement(xr)) return o; Debug.Assert(xr.NodeType == XmlNodeType.Element); xr.ReadStartElement(); xr.MoveToContent(); while(true) { XmlNodeType nt = xr.NodeType; if((nt == XmlNodeType.EndElement) || (nt == XmlNodeType.None)) break; if(nt != XmlNodeType.Element) { Debug.Assert(false); continue; } switch(xr.LocalName) { case "Plugins": o.Plugins = ReadBoolean(xr); break; case "Export": o.Export = ReadBoolean(xr); break; case "ExportNoKey": o.ExportNoKey = ReadBoolean(xr); break; case "Import": o.Import = ReadBoolean(xr); break; case "Print": o.Print = ReadBoolean(xr); break; case "PrintNoKey": o.PrintNoKey = ReadBoolean(xr); break; case "NewFile": o.NewFile = ReadBoolean(xr); break; case "SaveFile": o.SaveFile = ReadBoolean(xr); break; case "AutoType": o.AutoType = ReadBoolean(xr); break; case "AutoTypeWithoutContext": o.AutoTypeWithoutContext = ReadBoolean(xr); break; case "CopyToClipboard": o.CopyToClipboard = ReadBoolean(xr); break; case "CopyWholeEntries": o.CopyWholeEntries = ReadBoolean(xr); break; case "DragDrop": o.DragDrop = ReadBoolean(xr); break; case "UnhidePasswords": o.UnhidePasswords = ReadBoolean(xr); break; case "ChangeMasterKey": o.ChangeMasterKey = ReadBoolean(xr); break; case "ChangeMasterKeyNoKey": o.ChangeMasterKeyNoKey = ReadBoolean(xr); break; case "EditTriggers": o.EditTriggers = ReadBoolean(xr); break; default: Debug.Assert(false); xr.Skip(); break; } xr.MoveToContent(); } Debug.Assert(xr.NodeType == XmlNodeType.EndElement); xr.ReadEndElement(); return o; } private static KeePass.App.Configuration.AceMasterPassword ReadAceMasterPassword(XmlReader xr) { KeePass.App.Configuration.AceMasterPassword o = new KeePass.App.Configuration.AceMasterPassword(); if(SkipEmptyElement(xr)) return o; Debug.Assert(xr.NodeType == XmlNodeType.Element); xr.ReadStartElement(); xr.MoveToContent(); while(true) { XmlNodeType nt = xr.NodeType; if((nt == XmlNodeType.EndElement) || (nt == XmlNodeType.None)) break; if(nt != XmlNodeType.Element) { Debug.Assert(false); continue; } switch(xr.LocalName) { case "MinimumLength": o.MinimumLength = ReadUInt32(xr); break; case "MinimumQuality": o.MinimumQuality = ReadUInt32(xr); break; default: Debug.Assert(false); xr.Skip(); break; } xr.MoveToContent(); } Debug.Assert(xr.NodeType == XmlNodeType.EndElement); xr.ReadEndElement(); return o; } private static KeePassLib.Cryptography.PasswordGenerator.PwProfile ReadPwProfile(XmlReader xr) { KeePassLib.Cryptography.PasswordGenerator.PwProfile o = new KeePassLib.Cryptography.PasswordGenerator.PwProfile(); if(SkipEmptyElement(xr)) return o; Debug.Assert(xr.NodeType == XmlNodeType.Element); xr.ReadStartElement(); xr.MoveToContent(); while(true) { XmlNodeType nt = xr.NodeType; if((nt == XmlNodeType.EndElement) || (nt == XmlNodeType.None)) break; if(nt != XmlNodeType.Element) { Debug.Assert(false); continue; } switch(xr.LocalName) { case "Name": o.Name = ReadString(xr); break; case "GeneratorType": o.GeneratorType = ReadPasswordGeneratorType(xr); break; case "CollectUserEntropy": o.CollectUserEntropy = ReadBoolean(xr); break; case "Length": o.Length = ReadUInt32(xr); break; case "CharSetRanges": o.CharSetRanges = ReadString(xr); break; case "CharSetAdditional": o.CharSetAdditional = ReadString(xr); break; case "Pattern": o.Pattern = ReadString(xr); break; case "PatternPermutePassword": o.PatternPermutePassword = ReadBoolean(xr); break; case "ExcludeLookAlike": o.ExcludeLookAlike = ReadBoolean(xr); break; case "NoRepeatingCharacters": o.NoRepeatingCharacters = ReadBoolean(xr); break; case "ExcludeCharacters": o.ExcludeCharacters = ReadString(xr); break; case "CustomAlgorithmUuid": o.CustomAlgorithmUuid = ReadString(xr); break; case "CustomAlgorithmOptions": o.CustomAlgorithmOptions = ReadString(xr); break; default: Debug.Assert(false); xr.Skip(); break; } xr.MoveToContent(); } Debug.Assert(xr.NodeType == XmlNodeType.EndElement); xr.ReadEndElement(); return o; } private static System.Collections.Generic.List ReadListOfPwProfile(XmlReader xr) { System.Collections.Generic.List o = new System.Collections.Generic.List(); if(SkipEmptyElement(xr)) return o; Debug.Assert(xr.NodeType == XmlNodeType.Element); xr.ReadStartElement(); xr.MoveToContent(); while(true) { XmlNodeType nt = xr.NodeType; if((nt == XmlNodeType.EndElement) || (nt == XmlNodeType.None)) break; if(nt != XmlNodeType.Element) { Debug.Assert(false); continue; } KeePassLib.Cryptography.PasswordGenerator.PwProfile oElem = ReadPwProfile(xr); o.Add(oElem); xr.MoveToContent(); } Debug.Assert(xr.NodeType == XmlNodeType.EndElement); xr.ReadEndElement(); return o; } private static System.UInt32 ReadUInt32(XmlReader xr) { string strValue = xr.ReadElementString(); return XmlConvert.ToUInt32(strValue); } private static KeePassLib.SearchParameters ReadSearchParameters(XmlReader xr) { KeePassLib.SearchParameters o = new KeePassLib.SearchParameters(); if(SkipEmptyElement(xr)) return o; Debug.Assert(xr.NodeType == XmlNodeType.Element); xr.ReadStartElement(); xr.MoveToContent(); while(true) { XmlNodeType nt = xr.NodeType; if((nt == XmlNodeType.EndElement) || (nt == XmlNodeType.None)) break; if(nt != XmlNodeType.Element) { Debug.Assert(false); continue; } switch(xr.LocalName) { case "SearchString": o.SearchString = ReadString(xr); break; case "RegularExpression": o.RegularExpression = ReadBoolean(xr); break; case "SearchInTitles": o.SearchInTitles = ReadBoolean(xr); break; case "SearchInUserNames": o.SearchInUserNames = ReadBoolean(xr); break; case "SearchInPasswords": o.SearchInPasswords = ReadBoolean(xr); break; case "SearchInUrls": o.SearchInUrls = ReadBoolean(xr); break; case "SearchInNotes": o.SearchInNotes = ReadBoolean(xr); break; case "SearchInOther": o.SearchInOther = ReadBoolean(xr); break; case "SearchInStringNames": o.SearchInStringNames = ReadBoolean(xr); break; case "SearchInTags": o.SearchInTags = ReadBoolean(xr); break; case "SearchInUuids": o.SearchInUuids = ReadBoolean(xr); break; case "SearchInGroupNames": o.SearchInGroupNames = ReadBoolean(xr); break; case "ComparisonMode": o.ComparisonMode = ReadStringComparison(xr); break; case "ExcludeExpired": o.ExcludeExpired = ReadBoolean(xr); break; case "RespectEntrySearchingDisabled": o.RespectEntrySearchingDisabled = ReadBoolean(xr); break; case "DataTransformation": o.DataTransformation = ReadString(xr); break; default: Debug.Assert(false); xr.Skip(); break; } xr.MoveToContent(); } Debug.Assert(xr.NodeType == XmlNodeType.EndElement); xr.ReadEndElement(); return o; } private static System.Collections.Generic.List ReadListOfAceKeyAssoc(XmlReader xr) { System.Collections.Generic.List o = new System.Collections.Generic.List(); if(SkipEmptyElement(xr)) return o; Debug.Assert(xr.NodeType == XmlNodeType.Element); xr.ReadStartElement(); xr.MoveToContent(); while(true) { XmlNodeType nt = xr.NodeType; if((nt == XmlNodeType.EndElement) || (nt == XmlNodeType.None)) break; if(nt != XmlNodeType.Element) { Debug.Assert(false); continue; } KeePass.App.Configuration.AceKeyAssoc oElem = ReadAceKeyAssoc(xr); o.Add(oElem); xr.MoveToContent(); } Debug.Assert(xr.NodeType == XmlNodeType.EndElement); xr.ReadEndElement(); return o; } private static KeePass.App.Configuration.AceUrlSchemeOverrides ReadAceUrlSchemeOverrides(XmlReader xr) { KeePass.App.Configuration.AceUrlSchemeOverrides o = new KeePass.App.Configuration.AceUrlSchemeOverrides(); if(SkipEmptyElement(xr)) return o; Debug.Assert(xr.NodeType == XmlNodeType.Element); xr.ReadStartElement(); xr.MoveToContent(); while(true) { XmlNodeType nt = xr.NodeType; if((nt == XmlNodeType.EndElement) || (nt == XmlNodeType.None)) break; if(nt != XmlNodeType.Element) { Debug.Assert(false); continue; } switch(xr.LocalName) { case "BuiltInOverridesEnabled": o.BuiltInOverridesEnabled = ReadUInt64(xr); break; case "CustomOverrides": o.CustomOverrides = ReadListOfAceUrlSchemeOverride(xr); break; default: Debug.Assert(false); xr.Skip(); break; } xr.MoveToContent(); } Debug.Assert(xr.NodeType == XmlNodeType.EndElement); xr.ReadEndElement(); return o; } private static System.Collections.Generic.List ReadListOfString(XmlReader xr) { System.Collections.Generic.List o = new System.Collections.Generic.List(); if(SkipEmptyElement(xr)) return o; Debug.Assert(xr.NodeType == XmlNodeType.Element); xr.ReadStartElement(); xr.MoveToContent(); while(true) { XmlNodeType nt = xr.NodeType; if((nt == XmlNodeType.EndElement) || (nt == XmlNodeType.None)) break; if(nt != XmlNodeType.Element) { Debug.Assert(false); continue; } System.String oElem = ReadString(xr); o.Add(oElem); xr.MoveToContent(); } Debug.Assert(xr.NodeType == XmlNodeType.EndElement); xr.ReadEndElement(); return o; } private static Dictionary m_dictProxyServerType = null; private static KeePassLib.ProxyServerType ReadProxyServerType(XmlReader xr) { if(m_dictProxyServerType == null) { m_dictProxyServerType = new Dictionary(); m_dictProxyServerType["None"] = KeePassLib.ProxyServerType.None; m_dictProxyServerType["System"] = KeePassLib.ProxyServerType.System; m_dictProxyServerType["Manual"] = KeePassLib.ProxyServerType.Manual; } string strValue = xr.ReadElementString(); KeePassLib.ProxyServerType eResult; if(!m_dictProxyServerType.TryGetValue(strValue, out eResult)) { Debug.Assert(false); } return eResult; } private static Dictionary m_dictProxyAuthType = null; private static KeePassLib.ProxyAuthType ReadProxyAuthType(XmlReader xr) { if(m_dictProxyAuthType == null) { m_dictProxyAuthType = new Dictionary(); m_dictProxyAuthType["None"] = KeePassLib.ProxyAuthType.None; m_dictProxyAuthType["Default"] = KeePassLib.ProxyAuthType.Default; m_dictProxyAuthType["Manual"] = KeePassLib.ProxyAuthType.Manual; m_dictProxyAuthType["Auto"] = KeePassLib.ProxyAuthType.Auto; } string strValue = xr.ReadElementString(); KeePassLib.ProxyAuthType eResult; if(!m_dictProxyAuthType.TryGetValue(strValue, out eResult)) { Debug.Assert(false); } return eResult; } private static KeePass.App.Configuration.AceKvp ReadAceKvp(XmlReader xr) { KeePass.App.Configuration.AceKvp o = new KeePass.App.Configuration.AceKvp(); if(SkipEmptyElement(xr)) return o; Debug.Assert(xr.NodeType == XmlNodeType.Element); xr.ReadStartElement(); xr.MoveToContent(); while(true) { XmlNodeType nt = xr.NodeType; if((nt == XmlNodeType.EndElement) || (nt == XmlNodeType.None)) break; if(nt != XmlNodeType.Element) { Debug.Assert(false); continue; } switch(xr.LocalName) { case "Key": o.Key = ReadString(xr); break; case "Value": o.Value = ReadString(xr); break; default: Debug.Assert(false); xr.Skip(); break; } xr.MoveToContent(); } Debug.Assert(xr.NodeType == XmlNodeType.EndElement); xr.ReadEndElement(); return o; } private static KeePassLib.Translation.KPStringTable ReadKPStringTable(XmlReader xr) { KeePassLib.Translation.KPStringTable o = new KeePassLib.Translation.KPStringTable(); while(xr.MoveToNextAttribute()) { switch(xr.LocalName) { case "Name": o.Name = xr.Value; break; default: Debug.Assert(false); break; } } if(SkipEmptyElement(xr)) return o; Debug.Assert(xr.NodeType == XmlNodeType.Element); xr.ReadStartElement(); xr.MoveToContent(); while(true) { XmlNodeType nt = xr.NodeType; if((nt == XmlNodeType.EndElement) || (nt == XmlNodeType.None)) break; if(nt != XmlNodeType.Element) { Debug.Assert(false); continue; } switch(xr.LocalName) { case "Strings": o.Strings = ReadListOfKPStringTableItem(xr); break; default: Debug.Assert(false); xr.Skip(); break; } xr.MoveToContent(); } Debug.Assert(xr.NodeType == XmlNodeType.EndElement); xr.ReadEndElement(); return o; } private static KeePassLib.Translation.KPFormCustomization ReadKPFormCustomization(XmlReader xr) { KeePassLib.Translation.KPFormCustomization o = new KeePassLib.Translation.KPFormCustomization(); while(xr.MoveToNextAttribute()) { switch(xr.LocalName) { case "FullName": o.FullName = xr.Value; break; default: Debug.Assert(false); break; } } if(SkipEmptyElement(xr)) return o; Debug.Assert(xr.NodeType == XmlNodeType.Element); xr.ReadStartElement(); xr.MoveToContent(); while(true) { XmlNodeType nt = xr.NodeType; if((nt == XmlNodeType.EndElement) || (nt == XmlNodeType.None)) break; if(nt != XmlNodeType.Element) { Debug.Assert(false); continue; } switch(xr.LocalName) { case "Window": o.Window = ReadKPControlCustomization(xr); break; case "ChildControls": o.Controls = ReadListOfKPControlCustomization(xr); break; default: Debug.Assert(false); xr.Skip(); break; } xr.MoveToContent(); } Debug.Assert(xr.NodeType == XmlNodeType.EndElement); xr.ReadEndElement(); return o; } private static Dictionary m_dictIOCredProtMode = null; private static KeePassLib.Serialization.IOCredProtMode ReadIOCredProtMode(XmlReader xr) { if(m_dictIOCredProtMode == null) { m_dictIOCredProtMode = new Dictionary(); m_dictIOCredProtMode["None"] = KeePassLib.Serialization.IOCredProtMode.None; m_dictIOCredProtMode["Obf"] = KeePassLib.Serialization.IOCredProtMode.Obf; } string strValue = xr.ReadElementString(); KeePassLib.Serialization.IOCredProtMode eResult; if(!m_dictIOCredProtMode.TryGetValue(strValue, out eResult)) { Debug.Assert(false); } return eResult; } private static Dictionary m_dictIOCredSaveMode = null; private static KeePassLib.Serialization.IOCredSaveMode ReadIOCredSaveMode(XmlReader xr) { if(m_dictIOCredSaveMode == null) { m_dictIOCredSaveMode = new Dictionary(); m_dictIOCredSaveMode["NoSave"] = KeePassLib.Serialization.IOCredSaveMode.NoSave; m_dictIOCredSaveMode["UserNameOnly"] = KeePassLib.Serialization.IOCredSaveMode.UserNameOnly; m_dictIOCredSaveMode["SaveCred"] = KeePassLib.Serialization.IOCredSaveMode.SaveCred; } string strValue = xr.ReadElementString(); KeePassLib.Serialization.IOCredSaveMode eResult; if(!m_dictIOCredSaveMode.TryGetValue(strValue, out eResult)) { Debug.Assert(false); } return eResult; } private static System.Collections.Generic.List ReadListOfIOConnectionInfo(XmlReader xr) { System.Collections.Generic.List o = new System.Collections.Generic.List(); if(SkipEmptyElement(xr)) return o; Debug.Assert(xr.NodeType == XmlNodeType.Element); xr.ReadStartElement(); xr.MoveToContent(); while(true) { XmlNodeType nt = xr.NodeType; if((nt == XmlNodeType.EndElement) || (nt == XmlNodeType.None)) break; if(nt != XmlNodeType.Element) { Debug.Assert(false); continue; } KeePassLib.Serialization.IOConnectionInfo oElem = ReadIOConnectionInfo(xr); o.Add(oElem); xr.MoveToContent(); } Debug.Assert(xr.NodeType == XmlNodeType.EndElement); xr.ReadEndElement(); return o; } private static KeePass.Ecas.EcasTrigger[] ReadArrayOfEcasTrigger(XmlReader xr) { List l = new List(); if(SkipEmptyElement(xr)) return l.ToArray(); Debug.Assert(xr.NodeType == XmlNodeType.Element); xr.ReadStartElement(); xr.MoveToContent(); while(true) { XmlNodeType nt = xr.NodeType; if((nt == XmlNodeType.EndElement) || (nt == XmlNodeType.None)) break; if(nt != XmlNodeType.Element) { Debug.Assert(false); continue; } KeePass.Ecas.EcasTrigger oElem = ReadEcasTrigger(xr); l.Add(oElem); xr.MoveToContent(); } Debug.Assert(xr.NodeType == XmlNodeType.EndElement); xr.ReadEndElement(); return l.ToArray(); } private static KeePass.App.Configuration.AceColumn ReadAceColumn(XmlReader xr) { KeePass.App.Configuration.AceColumn o = new KeePass.App.Configuration.AceColumn(); if(SkipEmptyElement(xr)) return o; Debug.Assert(xr.NodeType == XmlNodeType.Element); xr.ReadStartElement(); xr.MoveToContent(); while(true) { XmlNodeType nt = xr.NodeType; if((nt == XmlNodeType.EndElement) || (nt == XmlNodeType.None)) break; if(nt != XmlNodeType.Element) { Debug.Assert(false); continue; } switch(xr.LocalName) { case "Type": o.Type = ReadAceColumnType(xr); break; case "CustomName": o.CustomName = ReadString(xr); break; case "Width": o.Width = ReadInt32(xr); break; case "HideWithAsterisks": o.HideWithAsterisks = ReadBoolean(xr); break; default: Debug.Assert(false); xr.Skip(); break; } xr.MoveToContent(); } Debug.Assert(xr.NodeType == XmlNodeType.EndElement); xr.ReadEndElement(); return o; } private static Dictionary m_dictSortOrder = null; private static System.Windows.Forms.SortOrder ReadSortOrder(XmlReader xr) { if(m_dictSortOrder == null) { m_dictSortOrder = new Dictionary(); m_dictSortOrder["None"] = System.Windows.Forms.SortOrder.None; m_dictSortOrder["Ascending"] = System.Windows.Forms.SortOrder.Ascending; m_dictSortOrder["Descending"] = System.Windows.Forms.SortOrder.Descending; } string strValue = xr.ReadElementString(); System.Windows.Forms.SortOrder eResult; if(!m_dictSortOrder.TryGetValue(strValue, out eResult)) { Debug.Assert(false); } return eResult; } private static System.Single ReadSingle(XmlReader xr) { string strValue = xr.ReadElementString(); return XmlConvert.ToSingle(strValue); } private static Dictionary m_dictGraphicsUnit = null; private static System.Drawing.GraphicsUnit ReadGraphicsUnit(XmlReader xr) { if(m_dictGraphicsUnit == null) { m_dictGraphicsUnit = new Dictionary(); m_dictGraphicsUnit["World"] = System.Drawing.GraphicsUnit.World; m_dictGraphicsUnit["Display"] = System.Drawing.GraphicsUnit.Display; m_dictGraphicsUnit["Pixel"] = System.Drawing.GraphicsUnit.Pixel; m_dictGraphicsUnit["Point"] = System.Drawing.GraphicsUnit.Point; m_dictGraphicsUnit["Inch"] = System.Drawing.GraphicsUnit.Inch; m_dictGraphicsUnit["Document"] = System.Drawing.GraphicsUnit.Document; m_dictGraphicsUnit["Millimeter"] = System.Drawing.GraphicsUnit.Millimeter; } string strValue = xr.ReadElementString(); System.Drawing.GraphicsUnit eResult; if(!m_dictGraphicsUnit.TryGetValue(strValue, out eResult)) { Debug.Assert(false); } return eResult; } private static Dictionary m_dictFontStyle = null; private static System.Drawing.FontStyle ReadFontStyle(XmlReader xr) { if(m_dictFontStyle == null) { m_dictFontStyle = new Dictionary(); m_dictFontStyle["Regular"] = System.Drawing.FontStyle.Regular; m_dictFontStyle["Bold"] = System.Drawing.FontStyle.Bold; m_dictFontStyle["Italic"] = System.Drawing.FontStyle.Italic; m_dictFontStyle["Underline"] = System.Drawing.FontStyle.Underline; m_dictFontStyle["Strikeout"] = System.Drawing.FontStyle.Strikeout; } string strValue = xr.ReadElementString(); System.Drawing.FontStyle eResult = (System.Drawing.FontStyle)0; string[] vValues = strValue.Split(m_vEnumSeps, StringSplitOptions.RemoveEmptyEntries); foreach(string strPart in vValues) { System.Drawing.FontStyle ePart; if(m_dictFontStyle.TryGetValue(strPart, out ePart)) eResult |= ePart; else { Debug.Assert(false); } } return eResult; } private static Dictionary m_dictPasswordGeneratorType = null; private static KeePassLib.Cryptography.PasswordGenerator.PasswordGeneratorType ReadPasswordGeneratorType(XmlReader xr) { if(m_dictPasswordGeneratorType == null) { m_dictPasswordGeneratorType = new Dictionary(); m_dictPasswordGeneratorType["CharSet"] = KeePassLib.Cryptography.PasswordGenerator.PasswordGeneratorType.CharSet; m_dictPasswordGeneratorType["Pattern"] = KeePassLib.Cryptography.PasswordGenerator.PasswordGeneratorType.Pattern; m_dictPasswordGeneratorType["Custom"] = KeePassLib.Cryptography.PasswordGenerator.PasswordGeneratorType.Custom; } string strValue = xr.ReadElementString(); KeePassLib.Cryptography.PasswordGenerator.PasswordGeneratorType eResult; if(!m_dictPasswordGeneratorType.TryGetValue(strValue, out eResult)) { Debug.Assert(false); } return eResult; } private static Dictionary m_dictStringComparison = null; private static System.StringComparison ReadStringComparison(XmlReader xr) { if(m_dictStringComparison == null) { m_dictStringComparison = new Dictionary(); m_dictStringComparison["CurrentCulture"] = System.StringComparison.CurrentCulture; m_dictStringComparison["CurrentCultureIgnoreCase"] = System.StringComparison.CurrentCultureIgnoreCase; m_dictStringComparison["InvariantCulture"] = System.StringComparison.InvariantCulture; m_dictStringComparison["InvariantCultureIgnoreCase"] = System.StringComparison.InvariantCultureIgnoreCase; m_dictStringComparison["Ordinal"] = System.StringComparison.Ordinal; m_dictStringComparison["OrdinalIgnoreCase"] = System.StringComparison.OrdinalIgnoreCase; } string strValue = xr.ReadElementString(); System.StringComparison eResult; if(!m_dictStringComparison.TryGetValue(strValue, out eResult)) { Debug.Assert(false); } return eResult; } private static KeePass.App.Configuration.AceKeyAssoc ReadAceKeyAssoc(XmlReader xr) { KeePass.App.Configuration.AceKeyAssoc o = new KeePass.App.Configuration.AceKeyAssoc(); if(SkipEmptyElement(xr)) return o; Debug.Assert(xr.NodeType == XmlNodeType.Element); xr.ReadStartElement(); xr.MoveToContent(); while(true) { XmlNodeType nt = xr.NodeType; if((nt == XmlNodeType.EndElement) || (nt == XmlNodeType.None)) break; if(nt != XmlNodeType.Element) { Debug.Assert(false); continue; } switch(xr.LocalName) { case "DatabasePath": o.DatabasePath = ReadString(xr); break; case "Password": o.Password = ReadBoolean(xr); break; case "KeyFilePath": o.KeyFilePath = ReadString(xr); break; case "KeyProvider": o.KeyProvider = ReadString(xr); break; case "UserAccount": o.UserAccount = ReadBoolean(xr); break; default: Debug.Assert(false); xr.Skip(); break; } xr.MoveToContent(); } Debug.Assert(xr.NodeType == XmlNodeType.EndElement); xr.ReadEndElement(); return o; } private static System.Collections.Generic.List ReadListOfAceUrlSchemeOverride(XmlReader xr) { System.Collections.Generic.List o = new System.Collections.Generic.List(); if(SkipEmptyElement(xr)) return o; Debug.Assert(xr.NodeType == XmlNodeType.Element); xr.ReadStartElement(); xr.MoveToContent(); while(true) { XmlNodeType nt = xr.NodeType; if((nt == XmlNodeType.EndElement) || (nt == XmlNodeType.None)) break; if(nt != XmlNodeType.Element) { Debug.Assert(false); continue; } KeePass.App.Configuration.AceUrlSchemeOverride oElem = ReadAceUrlSchemeOverride(xr); o.Add(oElem); xr.MoveToContent(); } Debug.Assert(xr.NodeType == XmlNodeType.EndElement); xr.ReadEndElement(); return o; } private static System.Collections.Generic.List ReadListOfKPStringTableItem(XmlReader xr) { System.Collections.Generic.List o = new System.Collections.Generic.List(); if(SkipEmptyElement(xr)) return o; Debug.Assert(xr.NodeType == XmlNodeType.Element); xr.ReadStartElement(); xr.MoveToContent(); while(true) { XmlNodeType nt = xr.NodeType; if((nt == XmlNodeType.EndElement) || (nt == XmlNodeType.None)) break; if(nt != XmlNodeType.Element) { Debug.Assert(false); continue; } KeePassLib.Translation.KPStringTableItem oElem = ReadKPStringTableItem(xr); o.Add(oElem); xr.MoveToContent(); } Debug.Assert(xr.NodeType == XmlNodeType.EndElement); xr.ReadEndElement(); return o; } private static KeePassLib.Translation.KPControlCustomization ReadKPControlCustomization(XmlReader xr) { KeePassLib.Translation.KPControlCustomization o = new KeePassLib.Translation.KPControlCustomization(); while(xr.MoveToNextAttribute()) { switch(xr.LocalName) { case "Name": o.Name = xr.Value; break; case "BaseHash": o.BaseHash = xr.Value; break; default: Debug.Assert(false); break; } } if(SkipEmptyElement(xr)) return o; Debug.Assert(xr.NodeType == XmlNodeType.Element); xr.ReadStartElement(); xr.MoveToContent(); while(true) { XmlNodeType nt = xr.NodeType; if((nt == XmlNodeType.EndElement) || (nt == XmlNodeType.None)) break; if(nt != XmlNodeType.Element) { Debug.Assert(false); continue; } switch(xr.LocalName) { case "Text": o.Text = ReadString(xr); break; case "Layout": o.Layout = ReadKpccLayout(xr); break; default: Debug.Assert(false); xr.Skip(); break; } xr.MoveToContent(); } Debug.Assert(xr.NodeType == XmlNodeType.EndElement); xr.ReadEndElement(); return o; } private static System.Collections.Generic.List ReadListOfKPControlCustomization(XmlReader xr) { System.Collections.Generic.List o = new System.Collections.Generic.List(); if(SkipEmptyElement(xr)) return o; Debug.Assert(xr.NodeType == XmlNodeType.Element); xr.ReadStartElement(); xr.MoveToContent(); while(true) { XmlNodeType nt = xr.NodeType; if((nt == XmlNodeType.EndElement) || (nt == XmlNodeType.None)) break; if(nt != XmlNodeType.Element) { Debug.Assert(false); continue; } KeePassLib.Translation.KPControlCustomization oElem = ReadKPControlCustomization(xr); o.Add(oElem); xr.MoveToContent(); } Debug.Assert(xr.NodeType == XmlNodeType.EndElement); xr.ReadEndElement(); return o; } private static KeePass.Ecas.EcasTrigger ReadEcasTrigger(XmlReader xr) { KeePass.Ecas.EcasTrigger o = new KeePass.Ecas.EcasTrigger(); if(SkipEmptyElement(xr)) return o; Debug.Assert(xr.NodeType == XmlNodeType.Element); xr.ReadStartElement(); xr.MoveToContent(); while(true) { XmlNodeType nt = xr.NodeType; if((nt == XmlNodeType.EndElement) || (nt == XmlNodeType.None)) break; if(nt != XmlNodeType.Element) { Debug.Assert(false); continue; } switch(xr.LocalName) { case "Guid": o.UuidString = ReadString(xr); break; case "Name": o.Name = ReadString(xr); break; case "Comments": o.Comments = ReadString(xr); break; case "Enabled": o.Enabled = ReadBoolean(xr); break; case "InitiallyOn": o.InitiallyOn = ReadBoolean(xr); break; case "TurnOffAfterAction": o.TurnOffAfterAction = ReadBoolean(xr); break; case "Events": o.EventArrayForSerialization = ReadArrayOfEcasEvent(xr); break; case "Conditions": o.ConditionsArrayForSerialization = ReadArrayOfEcasCondition(xr); break; case "Actions": o.ActionArrayForSerialization = ReadArrayOfEcasAction(xr); break; default: Debug.Assert(false); xr.Skip(); break; } xr.MoveToContent(); } Debug.Assert(xr.NodeType == XmlNodeType.EndElement); xr.ReadEndElement(); return o; } private static Dictionary m_dictAceColumnType = null; private static KeePass.App.Configuration.AceColumnType ReadAceColumnType(XmlReader xr) { if(m_dictAceColumnType == null) { m_dictAceColumnType = new Dictionary(); m_dictAceColumnType["Title"] = KeePass.App.Configuration.AceColumnType.Title; m_dictAceColumnType["UserName"] = KeePass.App.Configuration.AceColumnType.UserName; m_dictAceColumnType["Password"] = KeePass.App.Configuration.AceColumnType.Password; m_dictAceColumnType["Url"] = KeePass.App.Configuration.AceColumnType.Url; m_dictAceColumnType["Notes"] = KeePass.App.Configuration.AceColumnType.Notes; m_dictAceColumnType["CreationTime"] = KeePass.App.Configuration.AceColumnType.CreationTime; m_dictAceColumnType["LastModificationTime"] = KeePass.App.Configuration.AceColumnType.LastModificationTime; m_dictAceColumnType["LastAccessTime"] = KeePass.App.Configuration.AceColumnType.LastAccessTime; m_dictAceColumnType["ExpiryTime"] = KeePass.App.Configuration.AceColumnType.ExpiryTime; m_dictAceColumnType["Uuid"] = KeePass.App.Configuration.AceColumnType.Uuid; m_dictAceColumnType["Attachment"] = KeePass.App.Configuration.AceColumnType.Attachment; m_dictAceColumnType["CustomString"] = KeePass.App.Configuration.AceColumnType.CustomString; m_dictAceColumnType["PluginExt"] = KeePass.App.Configuration.AceColumnType.PluginExt; m_dictAceColumnType["OverrideUrl"] = KeePass.App.Configuration.AceColumnType.OverrideUrl; m_dictAceColumnType["Tags"] = KeePass.App.Configuration.AceColumnType.Tags; m_dictAceColumnType["ExpiryTimeDateOnly"] = KeePass.App.Configuration.AceColumnType.ExpiryTimeDateOnly; m_dictAceColumnType["Size"] = KeePass.App.Configuration.AceColumnType.Size; m_dictAceColumnType["HistoryCount"] = KeePass.App.Configuration.AceColumnType.HistoryCount; m_dictAceColumnType["AttachmentCount"] = KeePass.App.Configuration.AceColumnType.AttachmentCount; m_dictAceColumnType["LastPasswordModTime"] = KeePass.App.Configuration.AceColumnType.LastPasswordModTime; m_dictAceColumnType["Count"] = KeePass.App.Configuration.AceColumnType.Count; } string strValue = xr.ReadElementString(); KeePass.App.Configuration.AceColumnType eResult; if(!m_dictAceColumnType.TryGetValue(strValue, out eResult)) { Debug.Assert(false); } return eResult; } private static KeePass.App.Configuration.AceUrlSchemeOverride ReadAceUrlSchemeOverride(XmlReader xr) { KeePass.App.Configuration.AceUrlSchemeOverride o = new KeePass.App.Configuration.AceUrlSchemeOverride(); if(SkipEmptyElement(xr)) return o; Debug.Assert(xr.NodeType == XmlNodeType.Element); xr.ReadStartElement(); xr.MoveToContent(); while(true) { XmlNodeType nt = xr.NodeType; if((nt == XmlNodeType.EndElement) || (nt == XmlNodeType.None)) break; if(nt != XmlNodeType.Element) { Debug.Assert(false); continue; } switch(xr.LocalName) { case "Enabled": o.Enabled = ReadBoolean(xr); break; case "Scheme": o.Scheme = ReadString(xr); break; case "UrlOverride": o.UrlOverride = ReadString(xr); break; default: Debug.Assert(false); xr.Skip(); break; } xr.MoveToContent(); } Debug.Assert(xr.NodeType == XmlNodeType.EndElement); xr.ReadEndElement(); return o; } private static KeePassLib.Translation.KPStringTableItem ReadKPStringTableItem(XmlReader xr) { KeePassLib.Translation.KPStringTableItem o = new KeePassLib.Translation.KPStringTableItem(); if(SkipEmptyElement(xr)) return o; Debug.Assert(xr.NodeType == XmlNodeType.Element); xr.ReadStartElement(); xr.MoveToContent(); while(true) { XmlNodeType nt = xr.NodeType; if((nt == XmlNodeType.EndElement) || (nt == XmlNodeType.None)) break; if(nt != XmlNodeType.Element) { Debug.Assert(false); continue; } switch(xr.LocalName) { case "Name": o.Name = ReadString(xr); break; case "Value": o.Value = ReadString(xr); break; default: Debug.Assert(false); xr.Skip(); break; } xr.MoveToContent(); } Debug.Assert(xr.NodeType == XmlNodeType.EndElement); xr.ReadEndElement(); return o; } private static KeePassLib.Translation.KpccLayout ReadKpccLayout(XmlReader xr) { KeePassLib.Translation.KpccLayout o = new KeePassLib.Translation.KpccLayout(); while(xr.MoveToNextAttribute()) { switch(xr.LocalName) { case "X": o.X = xr.Value; break; case "Y": o.Y = xr.Value; break; case "Width": o.Width = xr.Value; break; case "Height": o.Height = xr.Value; break; default: Debug.Assert(false); break; } } if(SkipEmptyElement(xr)) return o; Debug.Assert(xr.NodeType == XmlNodeType.Element); xr.ReadStartElement(); xr.MoveToContent(); while(true) { XmlNodeType nt = xr.NodeType; if((nt == XmlNodeType.EndElement) || (nt == XmlNodeType.None)) break; if(nt != XmlNodeType.Element) { Debug.Assert(false); continue; } Debug.Assert(false); xr.Skip(); xr.MoveToContent(); } Debug.Assert(xr.NodeType == XmlNodeType.EndElement); xr.ReadEndElement(); return o; } private static KeePass.Ecas.EcasEvent[] ReadArrayOfEcasEvent(XmlReader xr) { List l = new List(); if(SkipEmptyElement(xr)) return l.ToArray(); Debug.Assert(xr.NodeType == XmlNodeType.Element); xr.ReadStartElement(); xr.MoveToContent(); while(true) { XmlNodeType nt = xr.NodeType; if((nt == XmlNodeType.EndElement) || (nt == XmlNodeType.None)) break; if(nt != XmlNodeType.Element) { Debug.Assert(false); continue; } KeePass.Ecas.EcasEvent oElem = ReadEcasEvent(xr); l.Add(oElem); xr.MoveToContent(); } Debug.Assert(xr.NodeType == XmlNodeType.EndElement); xr.ReadEndElement(); return l.ToArray(); } private static KeePass.Ecas.EcasCondition[] ReadArrayOfEcasCondition(XmlReader xr) { List l = new List(); if(SkipEmptyElement(xr)) return l.ToArray(); Debug.Assert(xr.NodeType == XmlNodeType.Element); xr.ReadStartElement(); xr.MoveToContent(); while(true) { XmlNodeType nt = xr.NodeType; if((nt == XmlNodeType.EndElement) || (nt == XmlNodeType.None)) break; if(nt != XmlNodeType.Element) { Debug.Assert(false); continue; } KeePass.Ecas.EcasCondition oElem = ReadEcasCondition(xr); l.Add(oElem); xr.MoveToContent(); } Debug.Assert(xr.NodeType == XmlNodeType.EndElement); xr.ReadEndElement(); return l.ToArray(); } private static KeePass.Ecas.EcasAction[] ReadArrayOfEcasAction(XmlReader xr) { List l = new List(); if(SkipEmptyElement(xr)) return l.ToArray(); Debug.Assert(xr.NodeType == XmlNodeType.Element); xr.ReadStartElement(); xr.MoveToContent(); while(true) { XmlNodeType nt = xr.NodeType; if((nt == XmlNodeType.EndElement) || (nt == XmlNodeType.None)) break; if(nt != XmlNodeType.Element) { Debug.Assert(false); continue; } KeePass.Ecas.EcasAction oElem = ReadEcasAction(xr); l.Add(oElem); xr.MoveToContent(); } Debug.Assert(xr.NodeType == XmlNodeType.EndElement); xr.ReadEndElement(); return l.ToArray(); } private static KeePass.Ecas.EcasEvent ReadEcasEvent(XmlReader xr) { KeePass.Ecas.EcasEvent o = new KeePass.Ecas.EcasEvent(); if(SkipEmptyElement(xr)) return o; Debug.Assert(xr.NodeType == XmlNodeType.Element); xr.ReadStartElement(); xr.MoveToContent(); while(true) { XmlNodeType nt = xr.NodeType; if((nt == XmlNodeType.EndElement) || (nt == XmlNodeType.None)) break; if(nt != XmlNodeType.Element) { Debug.Assert(false); continue; } switch(xr.LocalName) { case "TypeGuid": o.TypeString = ReadString(xr); break; case "Parameters": o.Parameters = ReadListOfString(xr); break; default: Debug.Assert(false); xr.Skip(); break; } xr.MoveToContent(); } Debug.Assert(xr.NodeType == XmlNodeType.EndElement); xr.ReadEndElement(); return o; } private static KeePass.Ecas.EcasCondition ReadEcasCondition(XmlReader xr) { KeePass.Ecas.EcasCondition o = new KeePass.Ecas.EcasCondition(); if(SkipEmptyElement(xr)) return o; Debug.Assert(xr.NodeType == XmlNodeType.Element); xr.ReadStartElement(); xr.MoveToContent(); while(true) { XmlNodeType nt = xr.NodeType; if((nt == XmlNodeType.EndElement) || (nt == XmlNodeType.None)) break; if(nt != XmlNodeType.Element) { Debug.Assert(false); continue; } switch(xr.LocalName) { case "TypeGuid": o.TypeString = ReadString(xr); break; case "Parameters": o.Parameters = ReadListOfString(xr); break; case "Negate": o.Negate = ReadBoolean(xr); break; default: Debug.Assert(false); xr.Skip(); break; } xr.MoveToContent(); } Debug.Assert(xr.NodeType == XmlNodeType.EndElement); xr.ReadEndElement(); return o; } private static KeePass.Ecas.EcasAction ReadEcasAction(XmlReader xr) { KeePass.Ecas.EcasAction o = new KeePass.Ecas.EcasAction(); if(SkipEmptyElement(xr)) return o; Debug.Assert(xr.NodeType == XmlNodeType.Element); xr.ReadStartElement(); xr.MoveToContent(); while(true) { XmlNodeType nt = xr.NodeType; if((nt == XmlNodeType.EndElement) || (nt == XmlNodeType.None)) break; if(nt != XmlNodeType.Element) { Debug.Assert(false); continue; } switch(xr.LocalName) { case "TypeGuid": o.TypeString = ReadString(xr); break; case "Parameters": o.Parameters = ReadListOfString(xr); break; default: Debug.Assert(false); xr.Skip(); break; } xr.MoveToContent(); } Debug.Assert(xr.NodeType == XmlNodeType.EndElement); xr.ReadEndElement(); return o; } } } KeePass/Util/XmlSerialization/XmlSerializerEx.cs0000664000000000000000000004357513222430416020755 0ustar rootroot/* KeePass Password Safe - The Open-Source Password Manager Copyright (C) 2003-2018 Dominik Reichl This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ using System; using System.Collections.Generic; using System.Text; using System.IO; using System.Xml; using System.Xml.Serialization; using System.Reflection; using System.Diagnostics; using KeePass.App.Configuration; using KeePassLib.Interfaces; using KeePassLib.Serialization; using KeePassLib.Translation; using KeePassLib.Utility; namespace KeePass.Util.XmlSerialization { public sealed partial class XmlSerializerEx : IXmlSerializerEx { private readonly Type m_t; public XmlSerializerEx(Type t) { m_t = t; } // AppConfigEx with KeePass.XmlSerializers.dll: 811 ms // AppConfigEx with own deserializer: 312 ms /* public object Deserialize(Stream s) { int tStart = Environment.TickCount; object o = Deserialize_(s); MessageService.ShowInfo(Environment.TickCount - tStart); return o; } */ public object Deserialize(Stream s) { object oResult = null; if((m_t == typeof(AppConfigEx)) || (m_t == typeof(KPTranslation))) { XmlReaderSettings xrs = KdbxFile.CreateStdXmlReaderSettings(); XmlReader xr = XmlReader.Create(s, xrs); string strRootName = GetXmlName(m_t); bool bRootFound = SkipToRoot(xr, strRootName); if(!bRootFound) { Debug.Assert(false); } else if(m_t == typeof(AppConfigEx)) oResult = ReadAppConfigEx(xr); else if(m_t == typeof(KPTranslation)) oResult = ReadKPTranslation(xr); else { Debug.Assert(false); } // See top-level 'if' xr.Close(); } if(oResult != null) return oResult; XmlSerializer xs = new XmlSerializer(m_t); return xs.Deserialize(s); } private static bool SkipToRoot(XmlReader xr, string strRootName) { xr.Read(); // Initialize reader bool bRootFound = false; while(true) { if((xr.NodeType == XmlNodeType.Document) || (xr.NodeType == XmlNodeType.DocumentFragment) || (xr.NodeType == XmlNodeType.Element)) { if(xr.Name == strRootName) { bRootFound = true; break; } xr.Skip(); } else if(!xr.Read()) { Debug.Assert(false); break; } } return bRootFound; } public void Serialize(XmlWriter xmlWriter, object o) { XmlSerializer xs = new XmlSerializer(m_t); xs.Serialize(xmlWriter, o); } internal static T GetAttribute(object[] vAttribs) where T : Attribute { if(vAttribs == null) { Debug.Assert(false); return null; } foreach(object o in vAttribs) { if(o == null) { Debug.Assert(false); continue; } if(o.GetType() == typeof(T)) return (o as T); } return null; } internal static string GetXmlName(MemberInfo mi) { object[] vAttribs = mi.GetCustomAttributes(true); string strXmlName = mi.Name; XmlTypeAttribute xmlType = GetAttribute(vAttribs); if(xmlType != null) strXmlName = xmlType.TypeName; XmlRootAttribute xmlRoot = GetAttribute(vAttribs); if(xmlRoot != null) strXmlName = xmlRoot.ElementName; XmlArrayAttribute xmlArray = GetAttribute(vAttribs); if(xmlArray != null) strXmlName = xmlArray.ElementName; XmlElementAttribute xmlElement = GetAttribute(vAttribs); if(xmlElement != null) strXmlName = xmlElement.ElementName; return strXmlName; } private sealed class XmlsTypeInfo { public bool HasInfo { get { return (m_strReadCode.Length > 0); } } private readonly Type m_t; public Type Type { get { return m_t; } } private readonly string m_strReadCode; public string ReadCode { get { return m_strReadCode; } } // private readonly string m_strWriteCode; // public string WriteCode { get { return m_strWriteCode; } } public XmlsTypeInfo(Type t) { m_t = t; m_strReadCode = string.Empty; // m_strWriteCode = string.Empty; } public XmlsTypeInfo(Type t, string strReadCode, string strWriteCode) { m_t = t; m_strReadCode = (strReadCode ?? string.Empty); // m_strWriteCode = (strWriteCode ?? string.Empty); } } internal static void GenerateSerializers(CommandLineArgs cl) { StringBuilder sb = new StringBuilder(); int t = 0; AppendLine(sb, "// This is a generated file!", ref t); AppendLine(sb, "// Do not edit manually, changes will be overwritten.", ref t); AppendLine(sb); AppendLine(sb, "using System;", ref t); AppendLine(sb, "using System.Collections.Generic;", ref t); AppendLine(sb, "using System.Xml;", ref t); AppendLine(sb, "using System.Diagnostics;", ref t); AppendLine(sb); AppendLine(sb, "using KeePassLib.Interfaces;", ref t); AppendLine(sb); AppendLine(sb, "namespace KeePass.Util.XmlSerialization", ref t); AppendLine(sb, "{", ref t, 0, 1); AppendLine(sb, "public sealed partial class XmlSerializerEx : IXmlSerializerEx", ref t); AppendLine(sb, "{", ref t, 0, 1); AppendLine(sb, "private static char[] m_vEnumSeps = new char[] {", ref t, 0, 1); AppendLine(sb, "' ', '\\t', '\\r', '\\n', '|', ',', ';', ':'", ref t); AppendLine(sb, "};", ref t, -1, 0); Dictionary d = new Dictionary(); d[typeof(AppConfigEx).FullName] = new XmlsTypeInfo(typeof(AppConfigEx)); d[typeof(KPTranslation).FullName] = new XmlsTypeInfo(typeof(KPTranslation)); bool bTypeCreated = true; while(bTypeCreated) { bTypeCreated = false; foreach(KeyValuePair kvp in d) { if(!kvp.Value.HasInfo) { d[kvp.Key] = GenerateSerializer(kvp.Value.Type, d, t); bTypeCreated = true; break; // Iterator might be invalid } } } foreach(KeyValuePair kvp in d) { AppendLine(sb); sb.Append(kvp.Value.ReadCode); } AppendLine(sb, "}", ref t, -1, 0); AppendLine(sb, "}", ref t, -1, 0); Debug.Assert(t == 0); string strFileData = StrUtil.NormalizeNewLines(sb.ToString(), true); string strFile = cl["out"]; if(!string.IsNullOrEmpty(strFile)) { strFile = UrlUtil.MakeAbsolutePath(WinUtil.GetExecutable(), strFile); File.WriteAllText(strFile, strFileData, StrUtil.Utf8); MessageService.ShowInfo("Saved XmlSerializerEx to:", strFile); } } private static bool IsXmlConvertibleType(Type t) { return ((t == typeof(Boolean)) || (t == typeof(Byte)) || (t == typeof(Char)) || (t == typeof(DateTime)) || (t == typeof(DateTimeOffset)) || (t == typeof(Decimal)) || (t == typeof(Double)) || (t == typeof(Guid)) || (t == typeof(Int16)) || (t == typeof(Int32)) || (t == typeof(Int64)) || (t == typeof(SByte)) || (t == typeof(Single)) || (t == typeof(TimeSpan)) || (t == typeof(UInt16)) || (t == typeof(UInt32)) || (t == typeof(UInt64))); } private static void Append(StringBuilder sb, string strAppend, ref int iIndent, int iIndentChangePre, int iIndentChangePost) { iIndent += iIndentChangePre; Debug.Assert(iIndent >= 0); sb.Append(new string('\t', Math.Max(iIndent, 0))); sb.Append(strAppend); iIndent += iIndentChangePost; } private static void AppendLine(StringBuilder sb) { sb.AppendLine(); } private static void AppendLine(StringBuilder sb, string strAppend, ref int iIndent) { AppendLine(sb, strAppend, ref iIndent, 0, 0); } private static void AppendLine(StringBuilder sb, string strAppend, ref int iIndent, int iIndentChangePre, int iIndentChangePost) { Append(sb, strAppend + MessageService.NewLine, ref iIndent, iIndentChangePre, iIndentChangePost); } internal static string GetFullTypeNameCS(Type t, out string strPrimarySubType) { string str = t.FullName; if(str.StartsWith(@"System.Collections.Generic.List`1")) { int iElemTypeOffset = str.IndexOf("[["); int iElemTypeEnd = str.IndexOfAny(new char[] { ',', ' ', '\t', '\r', '\n', ';', ':', ']' }, iElemTypeOffset); strPrimarySubType = str.Substring(iElemTypeOffset + 2, iElemTypeEnd - iElemTypeOffset - 2); str = "System.Collections.Generic.List<" + strPrimarySubType + ">"; } else if(str.EndsWith("[]")) strPrimarySubType = str.Substring(0, str.Length - 2); else strPrimarySubType = null; return str; } internal static string GetTypeDesc(string strFullTypeNameCS) { string str = strFullTypeNameCS; int iBackOffset = str.IndexOf('<'); if(iBackOffset < 0) iBackOffset = str.Length - 1; int i = str.LastIndexOf('.', iBackOffset); if(i >= 0) str = str.Substring(i + 1); if(str.StartsWith("List<")) { string strSubType = str.Substring(5, str.Length - 6); return "ListOf" + GetTypeDesc(strSubType); } if(str.EndsWith("[]")) { string strSubType = str.Substring(0, str.Length - 2); return "ArrayOf" + GetTypeDesc(strSubType); } Debug.Assert(str.IndexOfAny(new char[] { '<', '>', '[', ']', '`', ':', ' ', '\t', '\r', '\n' }) < 0); return str; } internal static bool TypeIsList(string strTypeFullCS) { return strTypeFullCS.StartsWith("System.Collections.Generic.List<"); } internal static bool TypeIsArray(string strTypeFullCS) { return strTypeFullCS.EndsWith("[]"); } private static XmlsTypeInfo GenerateSerializer(Type t, Dictionary dTypes, int iIndent) { StringBuilder sbr = new StringBuilder(); StringBuilder sbw = new StringBuilder(); string strSubTypeFull; string strTypeFull = GetFullTypeNameCS(t, out strSubTypeFull); string strTypeDesc = GetTypeDesc(strTypeFull); string strSubTypeDesc = null; if(strSubTypeFull != null) strSubTypeDesc = GetTypeDesc(strSubTypeFull); bool bIsList = TypeIsList(strTypeFull); bool bIsArray = TypeIsArray(strTypeFull); int ir = iIndent; if(t.IsEnum) AppendLine(sbr, "private static Dictionary m_dict" + strTypeDesc + " = null;", ref ir); AppendLine(sbr, "private static " + strTypeFull + " Read" + strTypeDesc + "(XmlReader xr" + // ((bIsList || bIsArray) ? ", string strItemName" : string.Empty) + ")", ref ir); AppendLine(sbr, "{", ref ir, 0, 1); if(t == typeof(string)) { AppendLine(sbr, "return xr.ReadElementString();", ref ir); } else if(IsXmlConvertibleType(t)) { AppendLine(sbr, "string strValue = xr.ReadElementString();", ref ir); AppendLine(sbr, "return XmlConvert.To" + strTypeDesc + "(strValue);", ref ir); } else if(t.IsEnum) { AppendLine(sbr, "if(m_dict" + strTypeDesc + " == null)", ref ir); AppendLine(sbr, "{", ref ir, 0, 1); AppendLine(sbr, "m_dict" + strTypeDesc + " = new Dictionary();", ref ir); string[] vEnumNames = Enum.GetNames(t); foreach(string strEnumName in vEnumNames) { AppendLine(sbr, "m_dict" + strTypeDesc + "[\"" + strEnumName + "\"] = " + strTypeFull + "." + strEnumName + ";", ref ir); } AppendLine(sbr, "}", ref ir, -1, 0); AppendLine(sbr); AppendLine(sbr, "string strValue = xr.ReadElementString();", ref ir); // AppendLine(sbr, "return Enum.Parse(typeof(" + strTypeFull + "), strValue);", ref ir); object[] vAttribs = t.GetCustomAttributes(true); if(GetAttribute(vAttribs) != null) { AppendLine(sbr, strTypeFull + " eResult = (" + strTypeFull + ")0;", ref ir); AppendLine(sbr, "string[] vValues = strValue.Split(m_vEnumSeps, StringSplitOptions.RemoveEmptyEntries);", ref ir); AppendLine(sbr, "foreach(string strPart in vValues)", ref ir); AppendLine(sbr, "{", ref ir, 0, 1); AppendLine(sbr, strTypeFull + " ePart;", ref ir); AppendLine(sbr, "if(m_dict" + strTypeDesc + ".TryGetValue(strPart, out ePart))", ref ir); AppendLine(sbr, "eResult |= ePart;", ref ir, 1, -1); AppendLine(sbr, "else { Debug.Assert(false); }", ref ir); AppendLine(sbr, "}", ref ir, -1, 0); } else { AppendLine(sbr, strTypeFull + " eResult;", ref ir); AppendLine(sbr, "if(!m_dict" + strTypeDesc + ".TryGetValue(strValue, out eResult))", ref ir); AppendLine(sbr, "{ Debug.Assert(false); }", ref ir, 1, -1); } AppendLine(sbr, "return eResult;", ref ir); } else { if(!bIsArray) AppendLine(sbr, strTypeFull + " o = new " + strTypeFull + "();", ref ir); else AppendLine(sbr, "List<" + strSubTypeFull + "> l = new List<" + strSubTypeFull + ">();", ref ir); AppendLine(sbr); byte[] pbInsAttribs = new byte[16]; Program.GlobalRandom.NextBytes(pbInsAttribs); string strInsAttribs = Convert.ToBase64String(pbInsAttribs, Base64FormattingOptions.None); sbr.Append(strInsAttribs); StringBuilder sbAttribs = new StringBuilder(); AppendLine(sbr, "if(SkipEmptyElement(xr)) return " + (bIsArray ? "l.ToArray();" : "o;"), ref ir); AppendLine(sbr); AppendLine(sbr, "Debug.Assert(xr.NodeType == XmlNodeType.Element);", ref ir); AppendLine(sbr, "xr.ReadStartElement();", ref ir); AppendLine(sbr, "xr.MoveToContent();", ref ir); AppendLine(sbr); AppendLine(sbr, "while(true)", ref ir); AppendLine(sbr, "{", ref ir, 0, 1); AppendLine(sbr, "XmlNodeType nt = xr.NodeType;", ref ir); AppendLine(sbr, "if((nt == XmlNodeType.EndElement) || (nt == XmlNodeType.None)) break;", ref ir); AppendLine(sbr, "if(nt != XmlNodeType.Element) { Debug.Assert(false); continue; }", ref ir); AppendLine(sbr); if(bIsList || bIsArray) { AppendLine(sbr, strSubTypeFull + " oElem = Read" + strSubTypeDesc + "(xr);", ref ir); AppendLine(sbr, (bIsArray ? "l" : "o") + ".Add(oElem);", ref ir); if(!dTypes.ContainsKey(strSubTypeFull)) dTypes[strSubTypeFull] = new XmlsTypeInfo(Type.GetType(strSubTypeFull)); } else { StringBuilder sbs = new StringBuilder(); uint uElements = 0; AppendLine(sbs, "switch(xr.LocalName)", ref ir); AppendLine(sbs, "{", ref ir, 0, 1); PropertyInfo[] vProps = t.GetProperties(); foreach(PropertyInfo pi in vProps) { object[] vAttribs = pi.GetCustomAttributes(true); if(GetAttribute(vAttribs) != null) continue; if(!pi.CanRead || !pi.CanWrite) { Debug.Assert(false); continue; } Type tProp = pi.PropertyType; string strPropSubTypeFull; string strPropTypeFull = GetFullTypeNameCS(tProp, out strPropSubTypeFull); string strPropTypeDesc = GetTypeDesc(strPropTypeFull); string strXmlName = GetXmlName(pi); if(!dTypes.ContainsKey(strPropTypeFull)) dTypes[strPropTypeFull] = new XmlsTypeInfo(tProp); if(GetAttribute(vAttribs) == null) { AppendLine(sbs, "case \"" + strXmlName + "\":", ref ir, 0, 1); AppendLine(sbs, "o." + pi.Name + " = Read" + strPropTypeDesc + "(xr);", ref ir); AppendLine(sbs, "break;", ref ir, 0, -1); ++uElements; } else { Debug.Assert(tProp == typeof(string)); AppendLine(sbAttribs, "case \"" + strXmlName + "\":", ref ir, 0, 1); AppendLine(sbAttribs, "o." + pi.Name + " = xr.Value;", ref ir); AppendLine(sbAttribs, "break;", ref ir, 0, -1); } } AppendLine(sbs, "default:", ref ir, 0, 1); AppendLine(sbs, "Debug.Assert(false);", ref ir); AppendLine(sbs, "xr.Skip();", ref ir); AppendLine(sbs, "break;", ref ir, 0, -1); AppendLine(sbs, "}", ref ir, -1, 0); // switch if(uElements > 0) sbr.Append(sbs.ToString()); else { AppendLine(sbr, "Debug.Assert(false);", ref ir); AppendLine(sbr, "xr.Skip();", ref ir); } } AppendLine(sbr); AppendLine(sbr, "xr.MoveToContent();", ref ir); AppendLine(sbr, "}", ref ir, -1, 0); AppendLine(sbr); AppendLine(sbr, "Debug.Assert(xr.NodeType == XmlNodeType.EndElement);", ref ir); AppendLine(sbr, "xr.ReadEndElement();", ref ir); AppendLine(sbr, (bIsArray ? "return l.ToArray();" : "return o;"), ref ir); if(sbAttribs.Length == 0) sbr.Replace(strInsAttribs, string.Empty); else { StringBuilder sba = new StringBuilder(); AppendLine(sba, "while(xr.MoveToNextAttribute())", ref ir); AppendLine(sba, "{", ref ir, 0, 1); AppendLine(sba, "switch(xr.LocalName)", ref ir); AppendLine(sba, "{", ref ir, 0, 1); sba.Append(sbAttribs.ToString()); AppendLine(sba, "default:", ref ir, 0, 1); AppendLine(sba, "Debug.Assert(false);", ref ir); AppendLine(sba, "break;", ref ir, 0, -1); AppendLine(sba, "}", ref ir, -1, 0); // switch AppendLine(sba, "}", ref ir, -1, 0); // while sba.AppendLine(); sbr.Replace(strInsAttribs, sba.ToString()); } } AppendLine(sbr, "}", ref ir, -1, 0); Debug.Assert(ir == iIndent); XmlsTypeInfo xti = new XmlsTypeInfo(t, sbr.ToString(), sbw.ToString()); return xti; } private static bool SkipEmptyElement(XmlReader xr) { xr.MoveToElement(); if(xr.IsEmptyElement) { xr.Skip(); return true; } return false; } } } KeePass/Util/TextSimilarity.cs0000664000000000000000000000466513222430416015360 0ustar rootroot/* KeePass Password Safe - The Open-Source Password Manager Copyright (C) 2003-2018 Dominik Reichl This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ using System; using System.Collections.Generic; using System.Diagnostics; using System.Text; namespace KeePass.Util { public static class TextSimilarity { public static int LevenshteinDistance(string s, string t) { if(s == null) { Debug.Assert(false); throw new ArgumentNullException("s"); } if(t == null) { Debug.Assert(false); throw new ArgumentNullException("t"); } int m = s.Length, n = t.Length; if(m <= 0) return n; if(n <= 0) return m; int[,] d = new int[m + 1, n + 1]; for(int k = 0; k <= m; ++k) d[k, 0] = k; for(int l = 1; l <= n; ++l) d[0, l] = l; for(int i = 1; i <= m; ++i) { char s_i = s[i - 1]; for(int j = 1; j <= n; ++j) { int dSubst = ((s_i == t[j - 1]) ? 0 : 1); // Insertion, deletion and substitution d[i, j] = Math.Min(d[i, j - 1] + 1, Math.Min( d[i - 1, j] + 1, d[i - 1, j - 1] + dSubst)); } } return d[m, n]; } /* internal static void Test() { string[] v = new string[] { "Y00000000Y", "Y00001111Y", "Y11110000Y", "Y11111111Y", "YZZZZZZZAY", "YZZZZZZZBY" }; int n = v.Length; float[,] mx = new float[n, n]; for(int i = 0; i < n; ++i) { for(int j = i; j < n; ++j) { float f = (float)LevenshteinDistance(v[i], v[j]) / (float)Math.Max(v[i].Length, v[j].Length); float p = (1.0f - f) * 100.0f; mx[i, j] = p; mx[j, i] = p; } } float[] s = new float[n]; for(int i = 0; i < n; ++i) { for(int j = 0; j < n; ++j) s[i] += mx[i, j]; s[i] /= n; } } */ } } KeePass/Util/ClipboardUtil.cs0000664000000000000000000004141413222430416015113 0ustar rootroot/* KeePass Password Safe - The Open-Source Password Manager Copyright (C) 2003-2018 Dominik Reichl This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ using System; using System.Collections.Generic; using System.Collections.Specialized; using System.Diagnostics; using System.Drawing; using System.Drawing.Imaging; using System.IO; using System.Text; using System.Threading; using System.Windows.Forms; using KeePass.App; using KeePass.Ecas; using KeePass.Forms; using KeePass.Native; using KeePass.UI; using KeePass.Util; using KeePass.Util.Spr; using KeePassLib; using KeePassLib.Cryptography; using KeePassLib.Security; using KeePassLib.Utility; using NativeLib = KeePassLib.Native.NativeLib; namespace KeePass.Util { public static partial class ClipboardUtil { private static byte[] m_pbDataHash32 = null; private static string m_strFormat = null; private static bool m_bEncoded = false; private static CriticalSectionEx g_csClearing = new CriticalSectionEx(); private const string ClipboardIgnoreFormatName = "Clipboard Viewer Ignore"; [Obsolete] public static bool Copy(string strToCopy, bool bIsEntryInfo, PwEntry peEntryInfo, PwDatabase pwReferenceSource) { return Copy(strToCopy, true, bIsEntryInfo, peEntryInfo, pwReferenceSource, IntPtr.Zero); } [Obsolete] public static bool Copy(ProtectedString psToCopy, bool bIsEntryInfo, PwEntry peEntryInfo, PwDatabase pwReferenceSource) { if(psToCopy == null) throw new ArgumentNullException("psToCopy"); return Copy(psToCopy.ReadString(), true, bIsEntryInfo, peEntryInfo, pwReferenceSource, IntPtr.Zero); } public static bool Copy(string strToCopy, bool bSprCompile, bool bIsEntryInfo, PwEntry peEntryInfo, PwDatabase pwReferenceSource, IntPtr hOwner) { if(strToCopy == null) throw new ArgumentNullException("strToCopy"); if(bIsEntryInfo && !AppPolicy.Try(AppPolicyId.CopyToClipboard)) return false; string strData = (bSprCompile ? SprEngine.Compile(strToCopy, new SprContext(peEntryInfo, pwReferenceSource, SprCompileFlags.All)) : strToCopy); try { if(!NativeLib.IsUnix()) // Windows { if(!OpenW(hOwner, true)) throw new InvalidOperationException(); bool bFailed = false; if(!AttachIgnoreFormatW()) bFailed = true; if(!SetDataW(null, strData, null)) bFailed = true; CloseW(); if(bFailed) return false; } else if(NativeLib.GetPlatformID() == PlatformID.MacOSX) SetStringM(strData); else if(NativeLib.IsUnix()) SetStringU(strData); // else // Managed // { // Clear(); // DataObject doData = CreateProtectedDataObject(strData); // Clipboard.SetDataObject(doData); // } } catch(Exception) { Debug.Assert(false); return false; } m_strFormat = null; byte[] pbUtf8 = StrUtil.Utf8.GetBytes(strData); m_pbDataHash32 = CryptoUtil.HashSha256(pbUtf8); RaiseCopyEvent(bIsEntryInfo, strData); if(peEntryInfo != null) peEntryInfo.Touch(false); // SprEngine.Compile might have modified the database MainForm mf = Program.MainForm; if((mf != null) && bSprCompile) { mf.RefreshEntriesList(); mf.UpdateUI(false, null, false, null, false, null, false); } return true; } [Obsolete] public static bool Copy(byte[] pbToCopy, string strFormat, bool bIsEntryInfo) { return Copy(pbToCopy, strFormat, false, bIsEntryInfo, IntPtr.Zero); } public static bool Copy(byte[] pbToCopy, string strFormat, bool bEncode, bool bIsEntryInfo, IntPtr hOwner) { Debug.Assert(pbToCopy != null); if(pbToCopy == null) throw new ArgumentNullException("pbToCopy"); if(bIsEntryInfo && !AppPolicy.Try(AppPolicyId.CopyToClipboard)) return false; string strEnc = null; try { if(bEncode || NativeLib.IsUnix()) strEnc = StrUtil.DataToDataUri(pbToCopy, ClipFmtToMimeType(strFormat)); if(!NativeLib.IsUnix()) // Windows { if(!OpenW(hOwner, true)) throw new InvalidOperationException(); uint uFormat = NativeMethods.RegisterClipboardFormat(strFormat); bool bFailed = false; if(!AttachIgnoreFormatW()) bFailed = true; if(!bEncode) { if(!SetDataW(uFormat, pbToCopy)) bFailed = true; } else // Encode { if(!SetDataW(uFormat, strEnc, false)) bFailed = true; } CloseW(); if(bFailed) return false; } else if(NativeLib.GetPlatformID() == PlatformID.MacOSX) SetStringM(strEnc); else if(NativeLib.IsUnix()) SetStringU(strEnc); // else // Managed, no encoding // { // Clear(); // DataObject doData = CreateProtectedDataObject(strFormat, pbToCopy); // Clipboard.SetDataObject(doData); // } } catch(Exception) { Debug.Assert(false); return false; } m_strFormat = strFormat; m_bEncoded = (strEnc != null); // if(strEnc != null) // m_pbDataHash32 = CryptoUtil.HashSha256(StrUtil.Utf8.GetBytes(strEnc)); // else m_pbDataHash32 = CryptoUtil.HashSha256(pbToCopy); RaiseCopyEvent(bIsEntryInfo, string.Empty); return true; } public static byte[] GetEncodedData(string strFormat, IntPtr hOwner) { try { if(!NativeLib.IsUnix()) // Windows { if(!OpenW(hOwner, false)) throw new InvalidOperationException(); string str = GetStringW(strFormat, false); CloseW(); if(str == null) return null; if(str.Length == 0) return MemUtil.EmptyByteArray; return StrUtil.DataUriToData(str); } else if(NativeLib.GetPlatformID() == PlatformID.MacOSX) return StrUtil.DataUriToData(GetStringM()); else if(NativeLib.IsUnix()) return StrUtil.DataUriToData(GetStringU()); // else // Managed, no encoding // { // return GetData(strFormat); // } } catch(Exception) { Debug.Assert(false); } return null; } public static bool CopyAndMinimize(string strToCopy, bool bIsEntryInfo, Form formContext, PwEntry peEntryInfo, PwDatabase pwReferenceSource) { return CopyAndMinimize(new ProtectedString(false, strToCopy), bIsEntryInfo, formContext, peEntryInfo, pwReferenceSource); } public static bool CopyAndMinimize(ProtectedString psToCopy, bool bIsEntryInfo, Form formContext, PwEntry peEntryInfo, PwDatabase pwReferenceSource) { if(psToCopy == null) throw new ArgumentNullException("psToCopy"); IntPtr hOwner = ((formContext != null) ? formContext.Handle : IntPtr.Zero); if(Copy(psToCopy.ReadString(), true, bIsEntryInfo, peEntryInfo, pwReferenceSource, hOwner)) { if(formContext != null) { if(Program.Config.MainWindow.DropToBackAfterClipboardCopy) NativeMethods.LoseFocus(formContext); if(Program.Config.MainWindow.MinimizeAfterClipboardCopy) UIUtil.SetWindowState(formContext, FormWindowState.Minimized); } return true; } return false; } private static void RaiseCopyEvent(bool bIsEntryInfo, string strDesc) { if(bIsEntryInfo == false) return; Program.TriggerSystem.RaiseEvent(EcasEventIDs.CopiedEntryInfo, EcasProperty.Text, strDesc); } /// /// Safely clear the clipboard. The clipboard clearing method of the /// .NET framework sets the clipboard to an empty DataObject when /// invoking the clearing method -- this might cause incompatibilities /// with other applications. Therefore, the Clear method of /// ClipboardUtil first tries to clear the clipboard using /// native Windows functions (which *really* clear the clipboard). /// public static void Clear() { // Ensure that there's no infinite recursion if(!g_csClearing.TryEnter()) { Debug.Assert(false); return; } // In some situations (e.g. when running in a VM, when using // a clipboard extension utility, ...) the clipboard cannot // be cleared; for this case we first overwrite the clipboard // with a non-sensitive text try { Copy("--", false, false, null, null, IntPtr.Zero); } catch(Exception) { Debug.Assert(false); } bool bNativeSuccess = false; try { if(!NativeLib.IsUnix()) // Windows { if(OpenW(IntPtr.Zero, true)) // Clears the clipboard { CloseW(); bNativeSuccess = true; } } else if(NativeLib.GetPlatformID() == PlatformID.MacOSX) { SetStringM(string.Empty); bNativeSuccess = true; } else if(NativeLib.IsUnix()) { SetStringU(string.Empty); bNativeSuccess = true; } } catch(Exception) { Debug.Assert(false); } g_csClearing.Exit(); if(bNativeSuccess) return; try { Clipboard.Clear(); } // Fallback to .NET framework method catch(Exception) { Debug.Assert(false); } } public static void ClearIfOwner() { // Handle-based detection doesn't work well, because a control // or dialog that stored the data may not exist anymore and // thus GetClipboardOwner returns null /* bool bOwnHandle = false; try { if(!NativeLib.IsUnix()) { IntPtr h = NativeMethods.GetClipboardOwner(); if(h != IntPtr.Zero) { MainForm mf = Program.MainForm; if(((mf != null) && (h == mf.Handle)) || GlobalWindowManager.HasWindow(h)) bOwnHandle = true; } } } catch(Exception) { Debug.Assert(false); } */ // If we didn't copy anything or cleared it already: do nothing if(m_pbDataHash32 == null) return; if(m_pbDataHash32.Length != 32) { Debug.Assert(false); return; } byte[] pbHash = HashClipboard(); // Hash current contents if(pbHash == null) return; // Unknown data (i.e. no KeePass data) if(pbHash.Length != 32) { Debug.Assert(false); return; } if(!MemUtil.ArraysEqual(m_pbDataHash32, pbHash)) return; m_pbDataHash32 = null; m_strFormat = null; Clear(); } private static byte[] HashClipboard() { try { if(m_strFormat != null) { if(ContainsData(m_strFormat)) { byte[] pbData; if(m_bEncoded) pbData = GetEncodedData(m_strFormat, IntPtr.Zero); else pbData = GetData(m_strFormat); if(pbData == null) { Debug.Assert(false); return null; } return CryptoUtil.HashSha256(pbData); } } else if(NativeLib.GetPlatformID() == PlatformID.MacOSX) { string strData = GetStringM(); byte[] pbUtf8 = StrUtil.Utf8.GetBytes(strData); return CryptoUtil.HashSha256(pbUtf8); } else if(NativeLib.IsUnix()) { string strData = GetStringU(); byte[] pbUtf8 = StrUtil.Utf8.GetBytes(strData); return CryptoUtil.HashSha256(pbUtf8); } else if(Clipboard.ContainsText()) { string strData = Clipboard.GetText(); byte[] pbUtf8 = StrUtil.Utf8.GetBytes(strData); return CryptoUtil.HashSha256(pbUtf8); } } catch(Exception) { Debug.Assert(false); } return null; } public static byte[] ComputeHash() { try // This works always or never { bool bOpened = OpenW(IntPtr.Zero, false); // The following seems to work even without opening the // clipboard, but opening maybe is safer uint u = NativeMethods.GetClipboardSequenceNumber(); if(bOpened) CloseW(); if(u == 0) throw new UnauthorizedAccessException(); return CryptoUtil.HashSha256(MemUtil.UInt32ToBytes(u)); } catch(Exception) { Debug.Assert(false); } if(NativeLib.GetPlatformID() == PlatformID.MacOSX) { string str = GetStringM(); byte[] pbText = StrUtil.Utf8.GetBytes("pb" + str); return CryptoUtil.HashSha256(pbText); } if(NativeLib.IsUnix()) { string str = GetStringU(); byte[] pbText = StrUtil.Utf8.GetBytes("pb" + str); return CryptoUtil.HashSha256(pbText); } try { MemoryStream ms = new MemoryStream(); byte[] pbPre = StrUtil.Utf8.GetBytes("pb"); ms.Write(pbPre, 0, pbPre.Length); // Prevent empty buffer if(Clipboard.ContainsAudio()) { Stream sAudio = Clipboard.GetAudioStream(); MemUtil.CopyStream(sAudio, ms); sAudio.Close(); } if(Clipboard.ContainsFileDropList()) { StringCollection sc = Clipboard.GetFileDropList(); foreach(string str in sc) { byte[] pbStr = StrUtil.Utf8.GetBytes(str); ms.Write(pbStr, 0, pbStr.Length); } } if(Clipboard.ContainsImage()) { using(Image img = Clipboard.GetImage()) { MemoryStream msImage = new MemoryStream(); img.Save(msImage, ImageFormat.Bmp); byte[] pbImg = msImage.ToArray(); ms.Write(pbImg, 0, pbImg.Length); msImage.Close(); } } if(Clipboard.ContainsText()) { string str = Clipboard.GetText(); byte[] pbText = StrUtil.Utf8.GetBytes(str); ms.Write(pbText, 0, pbText.Length); } byte[] pbData = ms.ToArray(); byte[] pbHash = CryptoUtil.HashSha256(pbData); ms.Close(); return pbHash; } catch(Exception) { Debug.Assert(false); } return null; } /* private static DataObject CreateProtectedDataObject(string strText) { DataObject d = new DataObject(); AttachIgnoreFormat(d); Debug.Assert(strText != null); if(strText == null) return d; if(strText.Length > 0) d.SetText(strText); return d; } private static DataObject CreateProtectedDataObject(string strFormat, byte[] pbData) { DataObject d = new DataObject(); AttachIgnoreFormat(d); Debug.Assert(strFormat != null); if(strFormat == null) return d; Debug.Assert(pbData != null); if(pbData == null) return d; if(pbData.Length > 0) d.SetData(strFormat, pbData); return d; } private static void AttachIgnoreFormat(DataObject doData) { Debug.Assert(doData != null); if(doData == null) return; if(!Program.Config.Security.UseClipboardViewerIgnoreFormat) return; if(NativeLib.IsUnix()) return; // Not supported on Unix try { doData.SetData(ClipboardIgnoreFormatName, false, PwDefs.ProductName); } catch(Exception) { Debug.Assert(false); } } */ public static bool ContainsText() { if(!NativeLib.IsUnix()) return Clipboard.ContainsText(); return true; } public static bool ContainsData(string strFormat) { if(!NativeLib.IsUnix()) return Clipboard.ContainsData(strFormat); if(string.IsNullOrEmpty(strFormat)) { Debug.Assert(false); return false; } if((strFormat == DataFormats.CommaSeparatedValue) || (strFormat == DataFormats.Html) || (strFormat == DataFormats.OemText) || (strFormat == DataFormats.Rtf) || (strFormat == DataFormats.Text) || (strFormat == DataFormats.UnicodeText)) return ContainsText(); string strData = GetText(); return StrUtil.IsDataUri(strData, ClipFmtToMimeType(strFormat)); } public static string GetText() { if(!NativeLib.IsUnix()) // Windows return Clipboard.GetText(); if(NativeLib.GetPlatformID() == PlatformID.MacOSX) return GetStringM(); if(NativeLib.IsUnix()) return GetStringU(); Debug.Assert(false); return Clipboard.GetText(); } private static string ClipFmtToMimeType(string strClipFmt) { if(strClipFmt == null) { Debug.Assert(false); return "application/octet-stream"; } StringBuilder sb = new StringBuilder(); for(int i = 0; i < strClipFmt.Length; ++i) { char ch = strClipFmt[i]; if(((ch >= 'A') && (ch <= 'Z')) || ((ch >= 'a') && (ch <= 'z')) || ((ch >= '0') && (ch <= '9'))) sb.Append(ch); else { Debug.Assert(false); } } if(sb.Length == 0) return "application/octet-stream"; return ("application/vnd." + PwDefs.ShortProductName + "." + sb.ToString()); } public static byte[] GetData(string strFormat) { try { object o = Clipboard.GetData(strFormat); if(o == null) return null; byte[] pb = (o as byte[]); if(pb != null) return pb; MemoryStream ms = (o as MemoryStream); if(ms != null) return ms.ToArray(); } catch(Exception) { Debug.Assert(false); } return null; } } } KeePass/Util/ShellUtil.cs0000664000000000000000000001270713222430416014266 0ustar rootroot/* KeePass Password Safe - The Open-Source Password Manager Copyright (C) 2003-2018 Dominik Reichl This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ using System; using System.Collections.Generic; using System.Text; using System.Windows.Forms; using System.Diagnostics; using KeePass.Native; using KeePass.Resources; using KeePassLib; using KeePassLib.Utility; using Microsoft.Win32; namespace KeePass.Util { public static class ShellUtil { public static void RegisterExtension(string strFileExt, string strExtId, string strFullExtName, string strAppPath, string strAppName, bool bShowSuccessMessage) { try { RegistryKey kClassesRoot = Registry.ClassesRoot; try { kClassesRoot.CreateSubKey("." + strFileExt); } catch(Exception) { } RegistryKey kFileExt = kClassesRoot.OpenSubKey("." + strFileExt, true); kFileExt.SetValue(string.Empty, strExtId, RegistryValueKind.String); kFileExt.Close(); try { kClassesRoot.CreateSubKey(strExtId); } catch(Exception) { } RegistryKey kExtInfo = kClassesRoot.OpenSubKey(strExtId, true); kExtInfo.SetValue(string.Empty, strFullExtName, RegistryValueKind.String); try { kExtInfo.CreateSubKey("DefaultIcon"); } catch(Exception) { } RegistryKey kIcon = kExtInfo.OpenSubKey("DefaultIcon", true); if(strAppPath.IndexOfAny(new char[]{ ' ', '\t' }) < 0) kIcon.SetValue(string.Empty, strAppPath + ",0", RegistryValueKind.String); else kIcon.SetValue(string.Empty, "\"" + strAppPath + "\",0", RegistryValueKind.String); kIcon.Close(); try { kExtInfo.CreateSubKey("shell"); } catch(Exception) { } RegistryKey kShell = kExtInfo.OpenSubKey("shell", true); try { kShell.CreateSubKey("open"); } catch(Exception) { } RegistryKey kShellOpen = kShell.OpenSubKey("open", true); kShellOpen.SetValue(string.Empty, @"&Open with " + strAppName, RegistryValueKind.String); try { kShellOpen.CreateSubKey("command"); } catch(Exception) { } RegistryKey kShellCommand = kShellOpen.OpenSubKey("command", true); kShellCommand.SetValue(string.Empty, "\"" + strAppPath + "\" \"%1\"", RegistryValueKind.String); kShellCommand.Close(); kShellOpen.Close(); kShell.Close(); kExtInfo.Close(); ShChangeNotify(); if(bShowSuccessMessage) MessageService.ShowInfo(KPRes.FileExtInstallSuccess); } catch(Exception) { MessageService.ShowWarning(KPRes.FileExtInstallFailed); } } public static void UnregisterExtension(string strFileExt, string strExtId) { try { RegistryKey kClassesRoot = Registry.ClassesRoot; kClassesRoot.DeleteSubKeyTree("." + strFileExt); kClassesRoot.DeleteSubKeyTree(strExtId); ShChangeNotify(); } catch(Exception) { } } private static void ShChangeNotify() { try { NativeMethods.SHChangeNotify(NativeMethods.SHCNE_ASSOCCHANGED, NativeMethods.SHCNF_IDLIST, IntPtr.Zero, IntPtr.Zero); } catch(Exception) { Debug.Assert(false); } } private const string AutoRunKey = "Software\\Microsoft\\Windows\\CurrentVersion\\Run"; public static void SetStartWithWindows(string strAppName, string strAppPath, bool bAutoStart) { try { if(bAutoStart) Registry.SetValue("HKEY_CURRENT_USER\\" + AutoRunKey, strAppName, strAppPath, RegistryValueKind.String); else { RegistryKey kRun = Registry.CurrentUser.OpenSubKey(AutoRunKey, true); kRun.DeleteValue(strAppName); kRun.Close(); } } catch(Exception) { Debug.Assert(false); } } public static bool GetStartWithWindows(string strAppName) { try { string strNotFound = Guid.NewGuid().ToString(); string strResult = (Registry.GetValue("HKEY_CURRENT_USER\\" + AutoRunKey, strAppName, strNotFound) as string); if((strResult != null) && (strResult != strNotFound) && (strResult.Length > 0)) { return true; } } catch(Exception) { Debug.Assert(false); } return false; } /* private const string PreLoadKey = "Software\\Microsoft\\Windows\\CurrentVersion\\Run"; public static void RegisterPreLoad(string strAppName, string strAppPath, string strCmdLineOptions, bool bPreLoad) { try { if(bPreLoad) { string strValue = strAppPath; if(!string.IsNullOrEmpty(strCmdLineOptions)) strValue += " " + strCmdLineOptions; Registry.SetValue("HKEY_LOCAL_MACHINE\\" + PreLoadKey, strAppName, strValue, RegistryValueKind.String); } else { RegistryKey kRun = Registry.LocalMachine.OpenSubKey(PreLoadKey, true); kRun.DeleteValue(strAppName); kRun.Close(); } } catch(Exception) { Debug.Assert(false); } } */ } } KeePass/Util/IpcBroadcast.Fsw.cs0000664000000000000000000001621313222430416015451 0ustar rootroot/* KeePass Password Safe - The Open-Source Password Manager Copyright (C) 2003-2018 Dominik Reichl This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ using System; using System.Collections.Generic; using System.Text; using System.IO; using System.Threading; using System.Security.Cryptography; using System.Diagnostics; using KeePassLib.Cryptography; using KeePassLib.Utility; namespace KeePass.Util { public static partial class IpcBroadcast { private static string m_strMsgFilePath = null; private static string m_strMsgFileName = null; private static FileSystemWatcher m_fsw = null; private static CriticalSectionEx m_csProcess = new CriticalSectionEx(); private static List m_vProcessedMsgs = new List(); private const double IpcMsgValidSecs = 4.0; private const int IpcComRetryCount = 30; private const int IpcComRetryDelay = 10; private const ulong IpcFileSig = 0x038248CB851D7A7CUL; private static readonly byte[] IpcOptEnt = { 0xC7, 0x97, 0x39, 0x74 }; private static void FswEnsurePaths() { if(m_strMsgFilePath != null) return; string strDir = UrlUtil.EnsureTerminatingSeparator( UrlUtil.GetTempPath(), false); m_strMsgFileName = IpcUtilEx.IpcMsgFilePreID + GetUserID() + IpcUtilEx.IpcMsgFilePostID; m_strMsgFilePath = strDir + m_strMsgFileName; } private static void FswSend(Program.AppMessage msg, int lParam) { FswEnsurePaths(); IpcMessage ipcMsg = new IpcMessage(); byte[] pbID = CryptoRandom.Instance.GetRandomBytes(8); ipcMsg.ID = MemUtil.BytesToUInt64(pbID); ipcMsg.Time = DateTime.UtcNow.ToBinary(); ipcMsg.Message = msg; ipcMsg.LParam = lParam; // Send just to others, not to own m_vProcessedMsgs.Add(ipcMsg); for(int r = 0; r < IpcComRetryCount; ++r) { try { List l = ReadMessagesPriv(); CleanOldMessages(l); l.Add(ipcMsg); MemoryStream ms = new MemoryStream(); BinaryWriter bw = new BinaryWriter(ms); bw.Write(IpcFileSig); bw.Write((uint)l.Count); for(int j = 0; j < l.Count; ++j) IpcMessage.Serialize(bw, l[j]); byte[] pbPlain = ms.ToArray(); bw.Close(); ms.Close(); byte[] pbFile = ProtectedData.Protect(pbPlain, IpcOptEnt, DataProtectionScope.CurrentUser); FileStream fsWrite = new FileStream(m_strMsgFilePath, FileMode.Create, FileAccess.Write, FileShare.None); fsWrite.Write(pbFile, 0, pbFile.Length); fsWrite.Close(); break; } catch(Exception) { } Thread.Sleep(IpcComRetryDelay); } CleanOldMessages(m_vProcessedMsgs); } private static void FswStartServer() { FswEnsurePaths(); try { m_fsw = new FileSystemWatcher(UrlUtil.GetTempPath(), m_strMsgFileName); } catch(Exception) { Debug.Assert(false); return; } // Access denied m_fsw.IncludeSubdirectories = false; m_fsw.NotifyFilter = (NotifyFilters.CreationTime | NotifyFilters.LastWrite); m_fsw.Created += OnCreated; m_fsw.Changed += OnChanged; m_fsw.EnableRaisingEvents = true; } private static void FswStopServer() { if(m_fsw != null) { m_fsw.EnableRaisingEvents = false; m_fsw.Changed -= OnChanged; m_fsw.Created -= OnCreated; m_fsw.Dispose(); m_fsw = null; } } private static void OnCreated(object sender, FileSystemEventArgs e) { ProcessIpcMessage(e); } private static void OnChanged(object sender, FileSystemEventArgs e) { ProcessIpcMessage(e); } private static void ProcessIpcMessage(FileSystemEventArgs e) { if((e == null) || (e.FullPath == null) || !m_strMsgFilePath.Equals( e.FullPath, StrUtil.CaseIgnoreCmp)) { Debug.Assert(false); return; } if(!m_csProcess.TryEnter()) return; for(int r = 0; r < IpcComRetryCount; ++r) { try { ProcessIpcMessagesPriv(); break; } catch(Exception) { } Thread.Sleep(IpcComRetryDelay); } CleanOldMessages(m_vProcessedMsgs); m_csProcess.Exit(); } private static void ProcessIpcMessagesPriv() { List l = ReadMessagesPriv(); CleanOldMessages(l); foreach(IpcMessage msg in l) { bool bProcessed = false; foreach(IpcMessage ipcMsg in m_vProcessedMsgs) { if(ipcMsg.ID == msg.ID) { bProcessed = true; break; } } if(bProcessed) continue; m_vProcessedMsgs.Add(msg); Program.MainForm.Invoke(new CallPrivDelegate(CallPriv), (int)msg.Message, msg.LParam); } } public delegate void CallPrivDelegate(int msg, int lParam); private static void CallPriv(int msg, int lParam) { Program.MainForm.ProcessAppMessage(new IntPtr(msg), new IntPtr(lParam)); } private static List ReadMessagesPriv() { List l = new List(); if(!File.Exists(m_strMsgFilePath)) return l; byte[] pbEnc = File.ReadAllBytes(m_strMsgFilePath); byte[] pb = ProtectedData.Unprotect(pbEnc, IpcOptEnt, DataProtectionScope.CurrentUser); MemoryStream ms = new MemoryStream(pb, false); BinaryReader br = new BinaryReader(ms); ulong uSig = br.ReadUInt64(); if(uSig != IpcFileSig) { Debug.Assert(false); return l; } uint uMessages = br.ReadUInt32(); for(uint u = 0; u < uMessages; ++u) l.Add(IpcMessage.Deserialize(br)); br.Close(); ms.Close(); return l; } private static void CleanOldMessages(List l) { DateTime dtNow = DateTime.UtcNow; for(int i = l.Count - 1; i >= 0; --i) { DateTime dtEvent = DateTime.FromBinary(l[i].Time); if((dtNow - dtEvent).TotalSeconds > IpcMsgValidSecs) l.RemoveAt(i); } } private sealed class IpcMessage { public ulong ID; public long Time; public Program.AppMessage Message; public int LParam; public static void Serialize(BinaryWriter bw, IpcMessage msg) { if((bw == null) || (msg == null)) { Debug.Assert(false); return; } bw.Write(msg.ID); bw.Write(msg.Time); bw.Write((int)msg.Message); bw.Write(msg.LParam); } public static IpcMessage Deserialize(BinaryReader br) { if(br == null) { Debug.Assert(false); return null; } IpcMessage msg = new IpcMessage(); msg.ID = br.ReadUInt64(); msg.Time = br.ReadInt64(); msg.Message = (Program.AppMessage)br.ReadInt32(); msg.LParam = br.ReadInt32(); return msg; } } } } KeePass/Util/IpcBroadcast.cs0000664000000000000000000001135113222430416014711 0ustar rootroot/* KeePass Password Safe - The Open-Source Password Manager Copyright (C) 2003-2018 Dominik Reichl This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ using System; using System.Collections.Generic; using System.Text; // using System.Runtime.Remoting; // using System.Runtime.Remoting.Channels; // using System.Runtime.Remoting.Channels.Ipc; using System.Security.Cryptography; using KeePass.Native; using KeePassLib.Utility; namespace KeePass.Util { public static partial class IpcBroadcast { // private static IpcServerChannel m_chServer = null; // private static IpcClientChannel m_chClient = null; // private const string IpcServerPortName = "KeePassBroadcastPort"; // private const string IpcObjectName = "KeePassBroadcastSingleton"; public static void Send(Program.AppMessage msg, int lParam, bool bWaitWithTimeout) { if(!KeePassLib.Native.NativeLib.IsUnix()) // Windows { if(bWaitWithTimeout) { IntPtr pResult = new IntPtr(0); NativeMethods.SendMessageTimeout((IntPtr)NativeMethods.HWND_BROADCAST, Program.ApplicationMessage, (IntPtr)msg, (IntPtr)lParam, NativeMethods.SMTO_ABORTIFHUNG, 5000, ref pResult); } else NativeMethods.PostMessage((IntPtr)NativeMethods.HWND_BROADCAST, Program.ApplicationMessage, (IntPtr)msg, (IntPtr)lParam); } else // Unix { // if(m_chClient == null) // { // m_chClient = new IpcClientChannel(); // ChannelServices.RegisterChannel(m_chClient, false); // } // try // { // IpcBroadcastSingleton ipc = (Activator.GetObject(typeof( // IpcBroadcastSingleton), "ipc://" + GetPortName() + "/" + // IpcObjectName) as IpcBroadcastSingleton); // if(ipc != null) ipc.Call((int)msg, lParam); // } // catch(Exception) { } // Server might not exist FswSend(msg, lParam); } } // private static string GetPortName() // { // return (IpcServerPortName + "-" + GetUserID()); // } private static string m_strUserID = null; internal static string GetUserID() { if(m_strUserID != null) return m_strUserID; string strID = (Environment.UserName ?? string.Empty) + @" @ " + (Environment.MachineName ?? string.Empty); byte[] pbID = StrUtil.Utf8.GetBytes(strID); SHA1Managed sha1 = new SHA1Managed(); byte[] pbHash = sha1.ComputeHash(pbID); string strShort = Convert.ToBase64String(pbHash, Base64FormattingOptions.None); strShort = strShort.Replace(@"+", string.Empty); strShort = strShort.Replace(@"/", string.Empty); if(strShort.Length > 8) strShort = strShort.Substring(0, 8); m_strUserID = strShort; return strShort; } public static void StartServer() { StopServer(); if(!KeePassLib.Native.NativeLib.IsUnix()) return; // Windows // IDictionary dOpt = new Hashtable(); // dOpt["portName"] = GetPortName(); // dOpt["exclusiveAddressUse"] = false; // dOpt["secure"] = false; // m_chServer = new IpcServerChannel(dOpt, null); // ChannelServices.RegisterChannel(m_chServer, false); // RemotingConfiguration.RegisterWellKnownServiceType(typeof( // IpcBroadcastSingleton), IpcObjectName, // WellKnownObjectMode.SingleCall); FswStartServer(); } public static void StopServer() { if(!KeePassLib.Native.NativeLib.IsUnix()) return; // Windows // if(m_chClient != null) // { // ChannelServices.UnregisterChannel(m_chClient); // m_chClient = null; // } // if(m_chServer != null) // { // ChannelServices.UnregisterChannel(m_chServer); // m_chServer = null; // } FswStopServer(); } } // public sealed class IpcBroadcastSingleton : MarshalByRefObject // { // public void Call(int msg, int lParam) // { // Program.MainForm.Invoke(new CallPrivDelegate(CallPriv), msg, lParam); // } // public delegate void CallPrivDelegate(int msg, int lParam); // private void CallPriv(int msg, int lParam) // { // Program.MainForm.ProcessAppMessage(new IntPtr(msg), new IntPtr(lParam)); // } // } } KeePass/Util/AutoTypeCtx.cs0000664000000000000000000000674613222430416014620 0ustar rootroot/* KeePass Password Safe - The Open-Source Password Manager Copyright (C) 2003-2018 Dominik Reichl This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ using System; using System.Collections.Generic; using System.Text; using System.Diagnostics; using KeePass.Util.Spr; using KeePassLib; namespace KeePass.Util { /// /// Auto-type candidate context. /// public sealed class AutoTypeCtx { private string m_strSeq = string.Empty; public string Sequence { get { return m_strSeq; } set { if(value == null) throw new ArgumentNullException("value"); m_strSeq = value; } } private PwEntry m_pe = null; public PwEntry Entry { get { return m_pe; } set { m_pe = value; } } private PwDatabase m_pd = null; public PwDatabase Database { get { return m_pd; } set { m_pd = value; } } public AutoTypeCtx() { } public AutoTypeCtx(string strSequence, PwEntry pe, PwDatabase pd) { if(strSequence == null) throw new ArgumentNullException("strSequence"); m_strSeq = strSequence; m_pe = pe; m_pd = pd; } public AutoTypeCtx Clone() { return (AutoTypeCtx)this.MemberwiseClone(); } } public sealed class SequenceQueriesEventArgs : EventArgs { private readonly int m_iEventID; public int EventID { get { return m_iEventID; } } private readonly IntPtr m_h; public IntPtr TargetWindowHandle { get { return m_h; } } private readonly string m_strWnd; public string TargetWindowTitle { get { return m_strWnd; } } public SequenceQueriesEventArgs(int iEventID, IntPtr hWnd, string strWnd) { m_iEventID = iEventID; m_h = hWnd; m_strWnd = strWnd; } } public sealed class SequenceQueryEventArgs : EventArgs { private readonly int m_iEventID; public int EventID { get { return m_iEventID; } } private readonly IntPtr m_h; public IntPtr TargetWindowHandle { get { return m_h; } } private readonly string m_strWnd; public string TargetWindowTitle { get { return m_strWnd; } } private readonly PwEntry m_pe; public PwEntry Entry { get { return m_pe; } } private readonly PwDatabase m_pd; public PwDatabase Database { get { return m_pd; } } private List m_lSeqs = new List(); internal IEnumerable Sequences { get { return m_lSeqs; } } public SequenceQueryEventArgs(int iEventID, IntPtr hWnd, string strWnd, PwEntry pe, PwDatabase pd) { m_iEventID = iEventID; m_h = hWnd; m_strWnd = strWnd; m_pe = pe; m_pd = pd; } public void AddSequence(string strSeq) { if(strSeq == null) { Debug.Assert(false); return; } m_lSeqs.Add(strSeq); } } } KeePass/Util/Archive/0000775000000000000000000000000013222430416013404 5ustar rootrootKeePass/Util/Archive/ImageArchive.cs0000664000000000000000000001060613222430416016262 0ustar rootroot/* KeePass Password Safe - The Open-Source Password Manager Copyright (C) 2003-2018 Dominik Reichl This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ using System; using System.Collections.Generic; using System.Text; using System.Drawing; using System.Diagnostics; using KeePass.UI; using KeePassLib; using KeePassLib.Utility; namespace KeePass.Util.Archive { internal sealed class ImageArchive { private Dictionary m_dItems = new Dictionary(); private sealed class ImageArchiveItem { private readonly string m_strName; public string Name { get { return m_strName; } } private byte[] m_pbData; public byte[] Data { get { return m_pbData; } } private Image m_imgOrg = null; public Image Image { get { if(m_imgOrg != null) return m_imgOrg; try { Image img = GfxUtil.LoadImage(m_pbData); DpiUtil.AssertUIImage(img); m_imgOrg = img; return img; } catch(Exception) { Debug.Assert(false); } return null; } } public ImageArchiveItem(string strName, byte[] pbData) { if(strName == null) throw new ArgumentNullException("strName"); if(pbData == null) throw new ArgumentNullException("pbData"); m_strName = strName; m_pbData = pbData; } } public ImageArchive() { } public void Load(byte[] pbXspFile) { XspArchive a = new XspArchive(); a.Load(pbXspFile); foreach(KeyValuePair kvp in a.Items) { string str = GetID(kvp.Key); ImageArchiveItem it = new ImageArchiveItem(kvp.Key, kvp.Value); Debug.Assert(!m_dItems.ContainsKey(str)); m_dItems[str] = it; } } private static string GetID(string strFileName) { if(strFileName == null) { Debug.Assert(false); return string.Empty; } string str = strFileName; if(str.Length == 0) return string.Empty; char chFirst = str[0]; if((chFirst == 'B') || (chFirst == 'b')) { int pL = str.IndexOf('_'); int pR = str.LastIndexOf('.'); if((pL >= 0) && (pR > pL)) str = str.Substring(pL + 1, pR - pL - 1); else if(pL >= 0) str = str.Substring(pL + 1); } else str = UrlUtil.StripExtension(str); return str.ToLowerInvariant(); } public Image GetForObject(string strObjectName) { if(strObjectName == null) { Debug.Assert(false); return null; } string str = GetID(strObjectName); ImageArchiveItem it; if(!m_dItems.TryGetValue(str, out it)) return null; if(it == null) { Debug.Assert(false); return null; } return it.Image; } public List GetImages(int w, int h, bool bSortByName) { if(w < 0) { Debug.Assert(false); return null; } if(h < 0) { Debug.Assert(false); return null; } List lItems = new List( m_dItems.Values); if(bSortByName) lItems.Sort(ImageArchive.CompareByName); List l = new List(lItems.Count); foreach(ImageArchiveItem it in lItems) { Image img = it.Image; if(img == null) { Debug.Assert(false); img = UIUtil.CreateColorBitmap24(w, h, Color.White); } if((img.Width == w) && (img.Height == h)) l.Add(img); else l.Add(GfxUtil.ScaleImage(img, w, h, ScaleTransformFlags.UIIcon)); } Debug.Assert(l.Count == lItems.Count); return l; } private static int CompareByName(ImageArchiveItem a, ImageArchiveItem b) { if(a == null) { Debug.Assert(false); return -1; } if(b == null) { Debug.Assert(false); return 1; } return string.Compare(a.Name, b.Name, StrUtil.CaseIgnoreCmp); } } } KeePass/Util/Archive/XspArchive.cs0000664000000000000000000000772113222430416016016 0ustar rootroot/* KeePass Password Safe - The Open-Source Password Manager Copyright (C) 2003-2018 Dominik Reichl This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ using System; using System.Collections.Generic; using System.Text; using System.IO; using System.Diagnostics; using KeePassLib.Utility; namespace KeePass.Util.Archive { internal sealed class XspArchive { private const ulong g_uSig = 0x562CBA7C4F9AF297UL; private const ushort g_uVer = 1; private Dictionary m_dItems = new Dictionary(); public IDictionary Items { get { return m_dItems; } } public XspArchive() { } internal static void CreateFile(string strXspFile, string strSourceDir) { try { string strExe = WinUtil.GetExecutable(); string strFile = UrlUtil.MakeAbsolutePath(strExe, strXspFile); string strDir = UrlUtil.EnsureTerminatingSeparator( strSourceDir, false); strDir = strDir.Substring(0, strDir.Length - 1); strDir = UrlUtil.EnsureTerminatingSeparator( UrlUtil.MakeAbsolutePath(strExe, strDir), false); CreateFilePriv(strFile, strDir); } catch(Exception ex) { MessageService.ShowWarningExcp(ex); } } private static void CreateFilePriv(string strFile, string strSourceDir) { FileStream fsOut = new FileStream(strFile, FileMode.Create, FileAccess.Write, FileShare.None); BinaryWriter bwOut = new BinaryWriter(fsOut); try { bwOut.Write(g_uSig); bwOut.Write(g_uVer); string[] vFiles = Directory.GetFiles(strSourceDir, "*.*", SearchOption.AllDirectories); foreach(string str in vFiles) { if(string.IsNullOrEmpty(str)) { Debug.Assert(false); continue; } if(str.EndsWith("\"")) { Debug.Assert(false); continue; } if(str.EndsWith(".")) { Debug.Assert(false); continue; } byte[] pbData = File.ReadAllBytes(str); if(pbData.LongLength > int.MaxValue) throw new OutOfMemoryException(); int cbData = pbData.Length; string strName = UrlUtil.GetFileName(str); byte[] pbName = StrUtil.Utf8.GetBytes(strName); if(pbName.LongLength > int.MaxValue) throw new OutOfMemoryException(); int cbName = pbName.Length; bwOut.Write(cbName); bwOut.Write(pbName); bwOut.Write(cbData); bwOut.Write(pbData); } const int iTerm = 0; bwOut.Write(iTerm); } finally { bwOut.Close(); fsOut.Close(); } } public void Load(byte[] pbFile) { if(pbFile == null) throw new ArgumentNullException("pbFile"); MemoryStream ms = new MemoryStream(pbFile, false); BinaryReader br = new BinaryReader(ms); try { ulong uSig = br.ReadUInt64(); if(uSig != g_uSig) throw new FormatException(); ushort uVer = br.ReadUInt16(); if(uVer > g_uVer) throw new FormatException(); while(true) { int cbName = br.ReadInt32(); if(cbName == 0) break; byte[] pbName = br.ReadBytes(cbName); string strName = StrUtil.Utf8.GetString(pbName); int cbData = br.ReadInt32(); byte[] pbData = br.ReadBytes(cbData); Debug.Assert(!m_dItems.ContainsKey(strName)); m_dItems[strName] = pbData; } } finally { br.Close(); ms.Close(); } } } } KeePass/Util/SessionLockNotifier.cs0000664000000000000000000000752613222430416016320 0ustar rootroot/* KeePass Password Safe - The Open-Source Password Manager Copyright (C) 2003-2018 Dominik Reichl This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ using System; using System.Collections.Generic; using System.Text; using System.Windows.Forms; using System.Diagnostics; using Microsoft.Win32; namespace KeePass.Util { public enum SessionLockReason { Unknown = 0, Ending = 1, Lock = 2, Suspend = 3, RemoteControlChange = 4, UserSwitch = 5 } public sealed class SessionLockEventArgs : EventArgs { private SessionLockReason m_r; public SessionLockReason Reason { get { return m_r; } } public SessionLockEventArgs(SessionLockReason r) { m_r = r; } } public sealed class SessionLockNotifier { private bool m_bEventsRegistered = false; private EventHandler m_evHandler = null; public SessionLockNotifier() { } #if DEBUG ~SessionLockNotifier() { Debug.Assert(m_bEventsRegistered == false); } #endif public void Install(EventHandler ev) { this.Uninstall(); try { SystemEvents.SessionEnding += this.OnSessionEnding; SystemEvents.SessionSwitch += this.OnSessionSwitch; SystemEvents.PowerModeChanged += this.OnPowerModeChanged; } catch(Exception) { Debug.Assert(WinUtil.IsWindows2000); } // 2000 always throws m_evHandler = ev; m_bEventsRegistered = true; } public void Uninstall() { if(m_bEventsRegistered) { // Unregister event handlers (in the same order as registering, // in case one of them throws) try { SystemEvents.SessionEnding -= this.OnSessionEnding; SystemEvents.SessionSwitch -= this.OnSessionSwitch; SystemEvents.PowerModeChanged -= this.OnPowerModeChanged; } catch(Exception) { Debug.Assert(WinUtil.IsWindows2000); } // 2000 always throws m_evHandler = null; m_bEventsRegistered = false; } } private void OnSessionEnding(object sender, SessionEndingEventArgs e) { if(m_evHandler != null) m_evHandler(sender, new SessionLockEventArgs(SessionLockReason.Ending)); } private void OnSessionSwitch(object sender, SessionSwitchEventArgs e) { if(m_evHandler != null) { SessionLockReason r = SessionLockReason.Unknown; if(e.Reason == SessionSwitchReason.SessionLock) r = SessionLockReason.Lock; else if(e.Reason == SessionSwitchReason.SessionLogoff) r = SessionLockReason.Ending; else if(e.Reason == SessionSwitchReason.ConsoleDisconnect) r = SessionLockReason.UserSwitch; else if((e.Reason == SessionSwitchReason.SessionRemoteControl) || (e.Reason == SessionSwitchReason.RemoteConnect) || (e.Reason == SessionSwitchReason.RemoteDisconnect)) r = SessionLockReason.RemoteControlChange; if(r != SessionLockReason.Unknown) m_evHandler(sender, new SessionLockEventArgs(r)); } } private void OnPowerModeChanged(object sender, PowerModeChangedEventArgs e) { if((m_evHandler != null) && (e.Mode == PowerModes.Suspend)) m_evHandler(sender, new SessionLockEventArgs(SessionLockReason.Suspend)); } } } KeePass/Util/ClipboardContents.cs0000664000000000000000000000534013222430416015771 0ustar rootroot/* KeePass Password Safe - The Open-Source Password Manager Copyright (C) 2003-2018 Dominik Reichl This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ using System; using System.Collections.Generic; using System.Text; using System.Windows.Forms; using System.Diagnostics; namespace KeePass.Util { public sealed class ClipboardContents { private string m_strText = null; private List> m_vContents = null; public ClipboardContents(bool bGetFromCurrent, bool bSimpleOnly) { if(bGetFromCurrent) GetData(bSimpleOnly); } /// /// Create a backup of the current clipboard contents. /// /// Create a simplified backup. /// The advanced mode might crash in conjunction with /// applications that use clipboard tricks like delay /// rendering. public void GetData(bool bSimpleOnly) { try { GetDataPriv(bSimpleOnly); } catch(Exception) { Debug.Assert(false); } } private void GetDataPriv(bool bSimpleOnly) { if(bSimpleOnly) { if(ClipboardUtil.ContainsText()) m_strText = ClipboardUtil.GetText(); } else // Advanced backup { m_vContents = new List>(); IDataObject idoClip = Clipboard.GetDataObject(); foreach(string strFormat in idoClip.GetFormats()) { KeyValuePair kvp = new KeyValuePair(strFormat, idoClip.GetData(strFormat)); m_vContents.Add(kvp); } } } public void SetData() { try { SetDataPriv(); } catch(Exception) { Debug.Assert(false); } } private void SetDataPriv() { if(m_strText != null) ClipboardUtil.Copy(m_strText, false, false, null, null, IntPtr.Zero); else if(m_vContents != null) { DataObject dObj = new DataObject(); foreach(KeyValuePair kvp in m_vContents) dObj.SetData(kvp.Key, kvp.Value); ClipboardUtil.Clear(); Clipboard.SetDataObject(dObj); } } } } KeePass/Util/CommandLineArgs.cs0000664000000000000000000001173313222430416015362 0ustar rootroot/* KeePass Password Safe - The Open-Source Password Manager Copyright (C) 2003-2018 Dominik Reichl This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ using System; using System.Collections.Generic; using System.Text; using System.Diagnostics; using System.IO; using System.Xml.Serialization; using KeePassLib.Native; namespace KeePass.Util { public sealed class CommandLineArgs { private List m_vFileNames = new List(); private SortedDictionary m_vParams = new SortedDictionary(); /// /// Get the primary file name. /// public string FileName { get { if(m_vFileNames.Count < 1) return null; return m_vFileNames[0]; } } /// /// All file names. /// public IEnumerable FileNames { get { return m_vFileNames; } } public IEnumerable> Parameters { get { return m_vParams; } } public CommandLineArgs(string[] vArgs) { if(vArgs == null) return; // No throw foreach(string str in vArgs) { if((str == null) || (str.Length < 1)) continue; KeyValuePair kvp = GetParameter(str); if(kvp.Key.Length == 0) m_vFileNames.Add(kvp.Value); else m_vParams[kvp.Key] = kvp.Value; } } /// /// Get the value of a command line parameter. Returns null /// if no key-value pair with the specified key exists. /// public string this[string strKey] { get { if(string.IsNullOrEmpty(strKey)) return this.FileName; else { string strValue; if(m_vParams.TryGetValue(strKey.ToLower(), out strValue)) return strValue; } return null; } } internal static KeyValuePair GetParameter(string strCompiled) { string str = strCompiled; if(str.StartsWith("--")) str = str.Remove(0, 2); else if(str.StartsWith("-")) str = str.Remove(0, 1); else if(str.StartsWith("/") && !NativeLib.IsUnix()) str = str.Remove(0, 1); else return new KeyValuePair(string.Empty, str); int posDbl = str.IndexOf(':'); int posEq = str.IndexOf('='); if((posDbl < 0) && (posEq < 0)) return new KeyValuePair(str.ToLower(), string.Empty); int posMin = Math.Min(posDbl, posEq); if(posMin < 0) posMin = ((posDbl < 0) ? posEq : posDbl); if(posMin <= 0) return new KeyValuePair(str.ToLower(), string.Empty); string strKey = str.Substring(0, posMin).ToLower(); string strValue = str.Remove(0, posMin + 1); return new KeyValuePair(strKey, strValue); } public bool Remove(string strParamName) { if(strParamName == null) { Debug.Assert(false); return false; } string strKey = strParamName.ToLower(); if(m_vParams.ContainsKey(strKey)) { if(m_vParams.Remove(strKey)) return true; else { Debug.Assert(false); } } return false; // No assert when not found } public static string SafeSerialize(string[] args) { if(args == null) throw new ArgumentNullException("args"); MemoryStream ms = new MemoryStream(); XmlSerializer xml = new XmlSerializer(typeof(string[])); xml.Serialize(ms, args); string strSerialized = Convert.ToBase64String(ms.ToArray(), Base64FormattingOptions.None); ms.Close(); return strSerialized; } public static string[] SafeDeserialize(string str) { if(str == null) throw new ArgumentNullException("str"); byte[] pb = Convert.FromBase64String(str); MemoryStream ms = new MemoryStream(pb, false); XmlSerializer xml = new XmlSerializer(typeof(string[])); try { return (string[])xml.Deserialize(ms); } catch(Exception) { Debug.Assert(false); } finally { ms.Close(); } return null; } internal void CopyFrom(CommandLineArgs args) { if(args == null) throw new ArgumentNullException("args"); m_vFileNames.Clear(); foreach(string strFile in args.FileNames) { m_vFileNames.Add(strFile); } m_vParams.Clear(); foreach(KeyValuePair kvp in args.Parameters) { if(!string.IsNullOrEmpty(kvp.Key)) m_vParams[kvp.Key] = kvp.Value; } } } } KeePass/Util/EntryUtil.cs0000664000000000000000000011165013222430416014315 0ustar rootroot/* KeePass Password Safe - The Open-Source Password Manager Copyright (C) 2003-2018 Dominik Reichl This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ using System; using System.Collections.Generic; using System.Diagnostics; using System.Drawing; using System.IO; using System.IO.Compression; using System.Security.Cryptography; using System.Text; using System.Windows.Forms; using KeePass.App; using KeePass.Forms; using KeePass.Resources; using KeePass.UI; using KeePass.Util.Spr; using KeePassLib; using KeePassLib.Collections; using KeePassLib.Cryptography; using KeePassLib.Cryptography.PasswordGenerator; using KeePassLib.Delegates; using KeePassLib.Interfaces; using KeePassLib.Security; using KeePassLib.Serialization; using KeePassLib.Utility; namespace KeePass.Util { internal delegate List EntryReportDelegate(PwDatabase pd, IStatusLogger sl, out Action fInit); /// /// This class contains various static functions for entry operations. /// public static class EntryUtil { /// /// Save all attachments of an array of entries to a directory. /// /// Array of entries whose attachments are extracted and saved. /// Directory in which the attachments are stored. public static void SaveEntryAttachments(PwEntry[] vEntries, string strBasePath) { Debug.Assert(vEntries != null); if(vEntries == null) return; Debug.Assert(strBasePath != null); if(strBasePath == null) return; string strPath = UrlUtil.EnsureTerminatingSeparator(strBasePath, false); bool bCancel = false; foreach(PwEntry pe in vEntries) { foreach(KeyValuePair kvp in pe.Binaries) { string strFile = strPath + kvp.Key; if(File.Exists(strFile)) { string strMsg = KPRes.FileExistsAlready + MessageService.NewLine; strMsg += strFile + MessageService.NewParagraph; strMsg += KPRes.OverwriteExistingFileQuestion; DialogResult dr = MessageService.Ask(strMsg, null, MessageBoxButtons.YesNoCancel); if(dr == DialogResult.Cancel) { bCancel = true; break; } else if(dr == DialogResult.Yes) { try { File.Delete(strFile); } catch(Exception exDel) { MessageService.ShowWarning(strFile, exDel); continue; } } else continue; // DialogResult.No } byte[] pbData = kvp.Value.ReadData(); try { File.WriteAllBytes(strFile, pbData); } catch(Exception exWrite) { MessageService.ShowWarning(strFile, exWrite); } MemUtil.ZeroByteArray(pbData); } if(bCancel) break; } } // Old format name (<= 2.14): "KeePassEntriesCF", // old format name (<= 2.22): "KeePassEntriesCX" public const string ClipFormatEntries = "KeePassEntries"; private static byte[] AdditionalEntropy = { 0xF8, 0x03, 0xFA, 0x51, 0x87, 0x18, 0x49, 0x5D }; [Obsolete] public static void CopyEntriesToClipboard(PwDatabase pwDatabase, PwEntry[] vEntries) { CopyEntriesToClipboard(pwDatabase, vEntries, IntPtr.Zero); } public static void CopyEntriesToClipboard(PwDatabase pwDatabase, PwEntry[] vEntries, IntPtr hOwner) { using(MemoryStream ms = new MemoryStream()) { using(GZipStream gz = new GZipStream(ms, CompressionMode.Compress)) { KdbxFile.WriteEntries(gz, pwDatabase, vEntries); byte[] pbFinal; if(WinUtil.IsWindows9x) pbFinal = ms.ToArray(); else pbFinal = ProtectedData.Protect(ms.ToArray(), AdditionalEntropy, DataProtectionScope.CurrentUser); ClipboardUtil.Copy(pbFinal, ClipFormatEntries, true, true, hOwner); } } } public static void PasteEntriesFromClipboard(PwDatabase pwDatabase, PwGroup pgStorage) { try { PasteEntriesFromClipboardPriv(pwDatabase, pgStorage); } catch(Exception) { Debug.Assert(false); } } private static void PasteEntriesFromClipboardPriv(PwDatabase pwDatabase, PwGroup pgStorage) { if(!ClipboardUtil.ContainsData(ClipFormatEntries)) return; byte[] pbEnc = ClipboardUtil.GetEncodedData(ClipFormatEntries, IntPtr.Zero); if(pbEnc == null) { Debug.Assert(false); return; } byte[] pbPlain; if(WinUtil.IsWindows9x) pbPlain = pbEnc; else pbPlain = ProtectedData.Unprotect(pbEnc, AdditionalEntropy, DataProtectionScope.CurrentUser); using(MemoryStream ms = new MemoryStream(pbPlain, false)) { using(GZipStream gz = new GZipStream(ms, CompressionMode.Decompress)) { List vEntries = KdbxFile.ReadEntries(gz, pwDatabase, true); // Adjust protection settings and add entries foreach(PwEntry pe in vEntries) { pe.Strings.EnableProtection(PwDefs.TitleField, pwDatabase.MemoryProtection.ProtectTitle); pe.Strings.EnableProtection(PwDefs.UserNameField, pwDatabase.MemoryProtection.ProtectUserName); pe.Strings.EnableProtection(PwDefs.PasswordField, pwDatabase.MemoryProtection.ProtectPassword); pe.Strings.EnableProtection(PwDefs.UrlField, pwDatabase.MemoryProtection.ProtectUrl); pe.Strings.EnableProtection(PwDefs.NotesField, pwDatabase.MemoryProtection.ProtectNotes); pe.SetCreatedNow(); pgStorage.AddEntry(pe, true, true); } } } } [Obsolete] public static string FillPlaceholders(string strText, SprContext ctx) { return FillPlaceholders(strText, ctx, 0); } public static string FillPlaceholders(string strText, SprContext ctx, uint uRecursionLevel) { if((ctx == null) || (ctx.Entry == null)) return strText; string str = strText; if((ctx.Flags & SprCompileFlags.NewPassword) != SprCompileFlags.None) str = ReplaceNewPasswordPlaceholder(str, ctx, uRecursionLevel); if((ctx.Flags & SprCompileFlags.HmacOtp) != SprCompileFlags.None) str = ReplaceHmacOtpPlaceholder(str, ctx); if((ctx.Flags & SprCompileFlags.PickChars) != SprCompileFlags.None) str = ReplacePickField(str, ctx); return str; } private static string ReplaceNewPasswordPlaceholder(string strText, SprContext ctx, uint uRecursionLevel) { PwEntry pe = ctx.Entry; PwDatabase pd = ctx.Database; if((pe == null) || (pd == null)) return strText; string str = strText; const string strNewPwStart = @"{NEWPASSWORD"; if(str.IndexOf(strNewPwStart, StrUtil.CaseIgnoreCmp) < 0) return str; string strGen = null; int iStart; List lParams; while(SprEngine.ParseAndRemovePlhWithParams(ref str, ctx, uRecursionLevel, strNewPwStart + ":", out iStart, out lParams, true)) { if(strGen == null) strGen = GeneratePassword((((lParams != null) && (lParams.Count > 0)) ? lParams[0] : string.Empty), ctx); string strIns = SprEngine.TransformContent(strGen, ctx); str = str.Insert(iStart, strIns); } const string strNewPwPlh = strNewPwStart + @"}"; if(str.IndexOf(strNewPwPlh, StrUtil.CaseIgnoreCmp) >= 0) { if(strGen == null) strGen = GeneratePassword(null, ctx); string strIns = SprEngine.TransformContent(strGen, ctx); str = StrUtil.ReplaceCaseInsensitive(str, strNewPwPlh, strIns); } if(strGen != null) { pe.CreateBackup(pd); ProtectedString psGen = new ProtectedString( pd.MemoryProtection.ProtectPassword, strGen); pe.Strings.Set(PwDefs.PasswordField, psGen); pe.Touch(true, false); pd.Modified = true; } else { Debug.Assert(false); } return str; } private static string GeneratePassword(string strProfile, SprContext ctx) { PwProfile prf = Program.Config.PasswordGenerator.AutoGeneratedPasswordsProfile; if(!string.IsNullOrEmpty(strProfile)) { if(strProfile == @"~") prf = PwProfile.DeriveFromPassword(ctx.Entry.Strings.GetSafe( PwDefs.PasswordField)); else { List lPrf = PwGeneratorUtil.GetAllProfiles(false); foreach(PwProfile p in lPrf) { if(strProfile.Equals(p.Name, StrUtil.CaseIgnoreCmp)) { prf = p; break; } } } } PwEntry peCtx = ((ctx != null) ? ctx.Entry : null); PwDatabase pdCtx = ((ctx != null) ? ctx.Database : null); ProtectedString ps = PwGeneratorUtil.GenerateAcceptable( prf, null, peCtx, pdCtx); return ps.ReadString(); } private static string ReplaceHmacOtpPlaceholder(string strText, SprContext ctx) { PwEntry pe = ctx.Entry; PwDatabase pd = ctx.Database; if((pe == null) || (pd == null)) return strText; string str = strText; const string strHmacOtpPlh = @"{HMACOTP}"; if(str.IndexOf(strHmacOtpPlh, StrUtil.CaseIgnoreCmp) >= 0) { const string strKeyFieldUtf8 = "HmacOtp-Secret"; const string strKeyFieldHex = "HmacOtp-Secret-Hex"; const string strKeyFieldBase32 = "HmacOtp-Secret-Base32"; const string strKeyFieldBase64 = "HmacOtp-Secret-Base64"; const string strCounterField = "HmacOtp-Counter"; byte[] pbSecret = null; try { string strKey = pe.Strings.ReadSafe(strKeyFieldUtf8); if(strKey.Length > 0) pbSecret = StrUtil.Utf8.GetBytes(strKey); if(pbSecret == null) { strKey = pe.Strings.ReadSafe(strKeyFieldHex); if(strKey.Length > 0) pbSecret = MemUtil.HexStringToByteArray(strKey); } if(pbSecret == null) { strKey = pe.Strings.ReadSafe(strKeyFieldBase32); if(strKey.Length > 0) pbSecret = MemUtil.ParseBase32(strKey); } if(pbSecret == null) { strKey = pe.Strings.ReadSafe(strKeyFieldBase64); if(strKey.Length > 0) pbSecret = Convert.FromBase64String(strKey); } } catch(Exception) { Debug.Assert(false); } if(pbSecret == null) pbSecret = MemUtil.EmptyByteArray; string strCounter = pe.Strings.ReadSafe(strCounterField); ulong uCounter; ulong.TryParse(strCounter, out uCounter); string strValue = HmacOtp.Generate(pbSecret, uCounter, 6, false, -1); pe.Strings.Set(strCounterField, new ProtectedString(false, (uCounter + 1).ToString())); pe.Touch(true, false); pd.Modified = true; str = StrUtil.ReplaceCaseInsensitive(str, strHmacOtpPlh, strValue); } return str; } private static string ReplacePickField(string strText, SprContext ctx) { string str = strText; PwEntry pe = ((ctx != null) ? ctx.Entry : null); PwDatabase pd = ((ctx != null) ? ctx.Database : null); while(true) { const string strPlh = @"{PICKFIELD}"; int p = str.IndexOf(strPlh, StrUtil.CaseIgnoreCmp); if(p < 0) break; string strRep = string.Empty; List l = new List(); string strGroup; if(pe != null) { strGroup = KPRes.Entry + " - " + KPRes.StandardFields; Debug.Assert(PwDefs.GetStandardFields().Count == 5); l.Add(new FpField(KPRes.Title, pe.Strings.GetSafe(PwDefs.TitleField), strGroup)); l.Add(new FpField(KPRes.UserName, pe.Strings.GetSafe(PwDefs.UserNameField), strGroup)); l.Add(new FpField(KPRes.Password, pe.Strings.GetSafe(PwDefs.PasswordField), strGroup)); l.Add(new FpField(KPRes.Url, pe.Strings.GetSafe(PwDefs.UrlField), strGroup)); l.Add(new FpField(KPRes.Notes, pe.Strings.GetSafe(PwDefs.NotesField), strGroup)); strGroup = KPRes.Entry + " - " + KPRes.CustomFields; foreach(KeyValuePair kvp in pe.Strings) { if(PwDefs.IsStandardField(kvp.Key)) continue; l.Add(new FpField(kvp.Key, kvp.Value, strGroup)); } PwGroup pg = pe.ParentGroup; if(pg != null) { strGroup = KPRes.Group; l.Add(new FpField(KPRes.Name, new ProtectedString( false, pg.Name), strGroup)); if(pg.Notes.Length > 0) l.Add(new FpField(KPRes.Notes, new ProtectedString( false, pg.Notes), strGroup)); } } if(pd != null) { strGroup = KPRes.Database; if(pd.Name.Length > 0) l.Add(new FpField(KPRes.Name, new ProtectedString( false, pd.Name), strGroup)); l.Add(new FpField(KPRes.FileOrUrl, new ProtectedString( false, pd.IOConnectionInfo.Path), strGroup)); } FpField fpf = FieldPickerForm.ShowAndRestore(KPRes.PickField, KPRes.PickFieldDesc, l); if(fpf != null) strRep = fpf.Value.ReadString(); strRep = SprEngine.Compile(strRep, ctx.WithoutContentTransformations()); strRep = SprEngine.TransformContent(strRep, ctx); str = str.Remove(p, strPlh.Length); str = str.Insert(p, strRep); } return str; } public static bool EntriesHaveSameParent(PwObjectList v) { if(v == null) { Debug.Assert(false); return true; } if(v.UCount == 0) return true; PwGroup pg = v.GetAt(0).ParentGroup; foreach(PwEntry pe in v) { if(pe.ParentGroup != pg) return false; } return true; } public static void ReorderEntriesAsInDatabase(PwObjectList v, PwDatabase pd) { if((v == null) || (pd == null)) { Debug.Assert(false); return; } if(pd.RootGroup == null) { Debug.Assert(false); return; } // DB must be open PwObjectList vRem = v.CloneShallow(); v.Clear(); EntryHandler eh = delegate(PwEntry pe) { int p = vRem.IndexOf(pe); if(p >= 0) { v.Add(pe); vRem.RemoveAt((uint)p); } return true; }; pd.RootGroup.TraverseTree(TraversalMethod.PreOrder, null, eh); foreach(PwEntry peRem in vRem) v.Add(peRem); // Entries not found } [Obsolete] public static void ExpireTanEntry(PwEntry pe) { ExpireTanEntryIfOption(pe, null); } [Obsolete] public static bool ExpireTanEntryIfOption(PwEntry pe) { return ExpireTanEntryIfOption(pe, null); } /// /// Test whether an entry is a TAN entry and if so, expire it, provided /// that the option for expiring TANs on use is enabled. /// /// Entry. /// If the entry has been modified, the return value is /// true, otherwise false. public static bool ExpireTanEntryIfOption(PwEntry pe, PwDatabase pdContext) { if(pe == null) throw new ArgumentNullException("pe"); // pdContext may be null if(!PwDefs.IsTanEntry(pe)) return false; // No assert if(Program.Config.Defaults.TanExpiresOnUse) { pe.ExpiryTime = DateTime.UtcNow; pe.Expires = true; pe.Touch(true); if(pdContext != null) pdContext.Modified = true; return true; } return false; } public static string CreateSummaryList(PwGroup pgItems, bool bStartWithNewPar) { List l = pgItems.GetEntries(true).CloneShallowToList(); string str = CreateSummaryList(pgItems, l.ToArray()); if((str.Length == 0) || !bStartWithNewPar) return str; return (MessageService.NewParagraph + str); } public static string CreateSummaryList(PwGroup pgSubGroups, PwEntry[] vEntries) { int nMaxEntries = 10; string strSummary = string.Empty; if(pgSubGroups != null) { PwObjectList vGroups = pgSubGroups.GetGroups(true); if(vGroups.UCount > 0) { StringBuilder sbGroups = new StringBuilder(); sbGroups.Append("- "); uint uToList = Math.Min(3U, vGroups.UCount); for(uint u = 0; u < uToList; ++u) { if(sbGroups.Length > 2) sbGroups.Append(", "); sbGroups.Append(vGroups.GetAt(u).Name); } if(uToList < vGroups.UCount) sbGroups.Append(", ..."); strSummary += sbGroups.ToString(); // New line below nMaxEntries -= 2; } } int nSummaryShow = Math.Min(nMaxEntries, vEntries.Length); if(nSummaryShow == (vEntries.Length - 1)) --nSummaryShow; // Plural msg for(int iSumEnum = 0; iSumEnum < nSummaryShow; ++iSumEnum) { if(strSummary.Length > 0) strSummary += MessageService.NewLine; PwEntry pe = vEntries[iSumEnum]; strSummary += ("- " + StrUtil.CompactString3Dots( pe.Strings.ReadSafe(PwDefs.TitleField), 39)); if(PwDefs.IsTanEntry(pe)) { string strTanIdx = pe.Strings.ReadSafe(PwDefs.UserNameField); if(!string.IsNullOrEmpty(strTanIdx)) strSummary += (@" (#" + strTanIdx + @")"); } } if(nSummaryShow != vEntries.Length) strSummary += (MessageService.NewLine + "- " + KPRes.MoreEntries.Replace(@"{PARAM}", (vEntries.Length - nSummaryShow).ToString())); return strSummary; } private static int CompareLastMod(PwEntry x, PwEntry y) { if(x == null) { Debug.Assert(false); return ((y == null) ? 0 : -1); } if(y == null) { Debug.Assert(false); return 1; } return x.LastModificationTime.CompareTo(y.LastModificationTime); } public static DateTime GetLastPasswordModTime(PwEntry pe) { if(pe == null) { Debug.Assert(false); return TimeUtil.ToUtc(DateTime.Today, false); } List l = new List(pe.History); l.Sort(EntryUtil.CompareLastMod); DateTime dt = pe.LastModificationTime; byte[] pbC = pe.Strings.GetSafe(PwDefs.PasswordField).ReadUtf8(); for(int i = l.Count - 1; i >= 0; --i) { PwEntry peH = l[i]; byte[] pbH = peH.Strings.GetSafe(PwDefs.PasswordField).ReadUtf8(); bool bSame = MemUtil.ArraysEqual(pbH, pbC); MemUtil.ZeroByteArray(pbH); if(!bSame) break; dt = peH.LastModificationTime; } MemUtil.ZeroByteArray(pbC); return dt; } private static int CompareListSizeDesc(List x, List y) { if(x == null) { Debug.Assert(false); return ((y == null) ? 0 : -1); } if(y == null) { Debug.Assert(false); return 1; } return y.Count.CompareTo(x.Count); // Descending } internal static List FindDuplicatePasswords(PwDatabase pd, IStatusLogger sl, out Action fInit) { fInit = delegate(ListView lv) { int w = lv.ClientSize.Width - UIUtil.GetVScrollBarWidth(); int wf = w / 4; int di = Math.Min(UIUtil.GetSmallIconSize().Width, wf); lv.Columns.Add(KPRes.Title, wf + di); lv.Columns.Add(KPRes.UserName, wf); lv.Columns.Add(KPRes.Password, wf); lv.Columns.Add(KPRes.Group, wf - di); UIUtil.SetDisplayIndices(lv, new int[] { 1, 2, 3, 0 }); }; List> lDups = FindDuplicatePasswordsEx(pd, sl); if(lDups == null) return null; List lResults = new List(); DateTime dtNow = DateTime.UtcNow; foreach(List l in lDups) { PwGroup pg = new PwGroup(true, true); pg.IsVirtual = true; ListViewGroup lvg = new ListViewGroup(KPRes.DuplicatePasswordsGroup); lvg.Tag = pg; lResults.Add(lvg); foreach(PwEntry pe in l) { pg.AddEntry(pe, false, false); string strGroup = string.Empty; if(pe.ParentGroup != null) strGroup = pe.ParentGroup.GetFullPath(" - ", false); ListViewItem lvi = new ListViewItem(pe.Strings.ReadSafe( PwDefs.TitleField)); lvi.SubItems.Add(pe.Strings.ReadSafe(PwDefs.UserNameField)); lvi.SubItems.Add(pe.Strings.ReadSafe(PwDefs.PasswordField)); lvi.SubItems.Add(strGroup); lvi.ImageIndex = UIUtil.GetEntryIconIndex(pd, pe, dtNow); lvi.Tag = pe; lResults.Add(lvi); } } return lResults; } private static List> FindDuplicatePasswordsEx(PwDatabase pd, IStatusLogger sl) { if((pd == null) || !pd.IsOpen) { Debug.Assert(false); return null; } PwGroup pg = pd.RootGroup; if(pg == null) { Debug.Assert(false); return null; } uint uEntries = pg.GetEntriesCount(true); uint uEntriesDone = 0; Dictionary> d = new Dictionary>(); EntryHandler eh = delegate(PwEntry pe) { if((sl != null) && (uEntries != 0)) { uint u = (uEntriesDone * 100) / uEntries; if(!sl.SetProgress(u)) return false; ++uEntriesDone; } if(!pe.GetSearchingEnabled()) return true; SprContext ctx = new SprContext(pe, pd, SprCompileFlags.NonActive); string str = SprEngine.Compile(pe.Strings.ReadSafe( PwDefs.PasswordField), ctx); if(str.Length != 0) { List l; if(d.TryGetValue(str, out l)) l.Add(pe); else { l = new List(); l.Add(pe); d[str] = l; } } return true; }; if(!pg.TraverseTree(TraversalMethod.PreOrder, null, eh)) return null; List> lRes = new List>(); foreach(List l in d.Values) { if(l.Count <= 1) continue; lRes.Add(l); } lRes.Sort(EntryUtil.CompareListSizeDesc); return lRes; } private sealed class EuSimilarPasswords { public readonly PwEntry EntryA; public readonly PwEntry EntryB; public readonly float Similarity; public EuSimilarPasswords(PwEntry peA, PwEntry peB, float fSimilarity) { if(peA == null) throw new ArgumentNullException("peA"); if(peB == null) throw new ArgumentNullException("peB"); this.EntryA = peA; this.EntryB = peB; this.Similarity = fSimilarity; } } internal static List FindSimilarPasswordsP(PwDatabase pd, IStatusLogger sl, out Action fInit) { fInit = delegate(ListView lv) { int w = lv.ClientSize.Width - UIUtil.GetVScrollBarWidth(); int wf = w / 4; int di = Math.Min(UIUtil.GetSmallIconSize().Width, wf); lv.Columns.Add(KPRes.Title, wf + di); lv.Columns.Add(KPRes.UserName, wf); lv.Columns.Add(KPRes.Password, wf); lv.Columns.Add(KPRes.Group, wf - di); UIUtil.SetDisplayIndices(lv, new int[] { 1, 2, 3, 0 }); }; List l = FindSimilarPasswordsPEx(pd, sl); if(l == null) return null; List lResults = new List(); DateTime dtNow = DateTime.UtcNow; foreach(EuSimilarPasswords sp in l) { PwGroup pg = new PwGroup(true, true); pg.IsVirtual = true; float fSim = sp.Similarity * 100.0f; string strLvg = KPRes.SimilarPasswordsGroup.Replace( @"{PARAM}", fSim.ToString("F02") + @"%"); ListViewGroup lvg = new ListViewGroup(strLvg); lvg.Tag = pg; lResults.Add(lvg); for(int i = 0; i < 2; ++i) { PwEntry pe = ((i == 0) ? sp.EntryA : sp.EntryB); pg.AddEntry(pe, false, false); string strGroup = string.Empty; if(pe.ParentGroup != null) strGroup = pe.ParentGroup.GetFullPath(" - ", false); ListViewItem lvi = new ListViewItem(pe.Strings.ReadSafe( PwDefs.TitleField)); lvi.SubItems.Add(pe.Strings.ReadSafe(PwDefs.UserNameField)); lvi.SubItems.Add(pe.Strings.ReadSafe(PwDefs.PasswordField)); lvi.SubItems.Add(strGroup); lvi.ImageIndex = UIUtil.GetEntryIconIndex(pd, pe, dtNow); lvi.Tag = pe; lResults.Add(lvi); } } return lResults; } private static bool GetEntryPasswords(PwGroup pg, PwDatabase pd, IStatusLogger sl, uint uPrePct, List lEntries, List lPasswords) { uint uEntries = pg.GetEntriesCount(true); uint uEntriesDone = 0; EntryHandler eh = delegate(PwEntry pe) { if((sl != null) && (uEntries != 0)) { uint u = (uEntriesDone * uPrePct) / uEntries; if(!sl.SetProgress(u)) return false; ++uEntriesDone; } if(!pe.GetSearchingEnabled()) return true; SprContext ctx = new SprContext(pe, pd, SprCompileFlags.NonActive); string str = SprEngine.Compile(pe.Strings.ReadSafe( PwDefs.PasswordField), ctx); if(str.Length != 0) { lEntries.Add(pe); lPasswords.Add(str); } return true; }; return pg.TraverseTree(TraversalMethod.PreOrder, null, eh); } private static List FindSimilarPasswordsPEx( PwDatabase pd, IStatusLogger sl) { if((pd == null) || !pd.IsOpen) { Debug.Assert(false); return null; } PwGroup pg = pd.RootGroup; if(pg == null) { Debug.Assert(false); return null; } const uint uPrePct = 33; const long cPostPct = 67; List lEntries = new List(); List lPasswords = new List(); if(!GetEntryPasswords(pg, pd, sl, uPrePct, lEntries, lPasswords)) return null; Debug.Assert(TextSimilarity.LevenshteinDistance("Columns", "Comments") == 4); Debug.Assert(TextSimilarity.LevenshteinDistance("File/URL", "Field Value") == 8); int n = lEntries.Count; long cTotal = ((long)n * (long)(n - 1)) / 2L; long cDone = 0; List l = new List(); for(int i = 0; i < (n - 1); ++i) { string strA = lPasswords[i]; Debug.Assert(strA.Length != 0); for(int j = i + 1; j < n; ++j) { string strB = lPasswords[j]; if(strA != strB) l.Add(new EuSimilarPasswords(lEntries[i], lEntries[j], 1.0f - ((float)TextSimilarity.LevenshteinDistance(strA, strB) / (float)Math.Max(strA.Length, strB.Length)))); if(sl != null) { ++cDone; uint u = uPrePct + (uint)((cDone * cPostPct) / cTotal); if(!sl.SetProgress(u)) return null; } } } Debug.Assert((cDone == cTotal) || (sl == null)); Comparison fCmp = delegate(EuSimilarPasswords x, EuSimilarPasswords y) { return y.Similarity.CompareTo(x.Similarity); // Descending }; l.Sort(fCmp); int ciMax = Math.Max(n / 2, 20); if(l.Count > ciMax) l.RemoveRange(ciMax, l.Count - ciMax); return l; } /* private const int FspcShowItemsPerCluster = 7; internal static List FindSimilarPasswordsC(PwDatabase pd, IStatusLogger sl, out Action fInit) { fInit = delegate(ListView lv) { int w = lv.ClientSize.Width - UIUtil.GetVScrollBarWidth(); int wf = w / 5; int di = Math.Min(UIUtil.GetSmallIconSize().Width, wf); lv.Columns.Add(KPRes.Title, wf + di); lv.Columns.Add(KPRes.UserName, wf); lv.Columns.Add(KPRes.Password, wf); lv.Columns.Add(KPRes.Group, wf - di); lv.Columns.Add(KPRes.Similarity, wf, HorizontalAlignment.Right); UIUtil.SetDisplayIndices(lv, new int[] { 1, 2, 3, 0, 4 }); }; List> l = FindSimilarPasswordsCEx(pd, sl); if(l == null) return null; List lResults = new List(); DateTime dtNow = DateTime.UtcNow; foreach(List lSp in l) { PwGroup pg = new PwGroup(true, true); pg.IsVirtual = true; ListViewGroup lvg = new ListViewGroup(KPRes.SimilarPasswordsGroupSh); lvg.Tag = pg; lResults.Add(lvg); for(int i = 0; i < lSp.Count; ++i) { EuSimilarPasswords sp = lSp[i]; PwEntry pe = sp.EntryB; pg.AddEntry(pe, false, false); // The group contains all cluster entries (such that they // are displayed in the main window when clicking an entry), // but the report dialog only shows the first few entries if(i >= FspcShowItemsPerCluster) continue; string strGroup = string.Empty; if(pe.ParentGroup != null) strGroup = pe.ParentGroup.GetFullPath(" - ", false); ListViewItem lvi = new ListViewItem(pe.Strings.ReadSafe( PwDefs.TitleField)); lvi.SubItems.Add(pe.Strings.ReadSafe(PwDefs.UserNameField)); lvi.SubItems.Add(pe.Strings.ReadSafe(PwDefs.PasswordField)); lvi.SubItems.Add(strGroup); string strSim = KPRes.ClusterCenter; if(i > 0) strSim = (sp.Similarity * 100.0f).ToString("F02") + @"%"; else { Debug.Assert(sp.Similarity == float.MaxValue); } lvi.SubItems.Add(strSim); lvi.ImageIndex = UIUtil.GetEntryIconIndex(pd, pe, dtNow); lvi.Tag = pe; lResults.Add(lvi); } } return lResults; } */ internal static List FindSimilarPasswordsC(PwDatabase pd, IStatusLogger sl, out Action fInit) { fInit = delegate(ListView lv) { int wm = 4; int w = lv.ClientSize.Width - UIUtil.GetVScrollBarWidth() - (3 * wm); int wf = w / 12; int wl = w / 4; int wr = w - (3 * wl + 3 * wf); int di = Math.Min(UIUtil.GetSmallIconSize().Width, wf); lv.Columns.Add(KPRes.Title, wl + di + wr); lv.Columns.Add(KPRes.UserName, wl - di); lv.Columns.Add(KPRes.Password, wl); lv.Columns.Add("> 90%", wf + wm, HorizontalAlignment.Right); lv.Columns.Add("> 70%", wf + wm, HorizontalAlignment.Right); lv.Columns.Add("> 50%", wf + wm, HorizontalAlignment.Right); }; List> l = FindSimilarPasswordsCEx(pd, sl); if(l == null) return null; List lResults = new List(); DateTime dtNow = DateTime.UtcNow; float[] vSimBounds = new float[] { 0.9f, 0.7f, 0.5f }; int[] vSimCounts = new int[3]; foreach(List lSp in l) { PwGroup pg = new PwGroup(true, true); pg.IsVirtual = true; PwEntry pe = lSp[0].EntryA; // Cluster center pg.AddEntry(pe, false, false); ListViewItem lvi = new ListViewItem(pe.Strings.ReadSafe( PwDefs.TitleField)); lvi.SubItems.Add(pe.Strings.ReadSafe(PwDefs.UserNameField)); lvi.SubItems.Add(pe.Strings.ReadSafe(PwDefs.PasswordField)); Array.Clear(vSimCounts, 0, vSimCounts.Length); for(int i = 1; i < lSp.Count; ++i) { EuSimilarPasswords sp = lSp[i]; pg.AddEntry(sp.EntryB, false, false); for(int j = 0; j < vSimCounts.Length; ++j) { if(sp.Similarity > vSimBounds[j]) ++vSimCounts[j]; } } for(int i = 0; i < vSimCounts.Length; ++i) lvi.SubItems.Add(vSimCounts[i].ToString()); lvi.ImageIndex = UIUtil.GetEntryIconIndex(pd, pe, dtNow); lvi.Tag = pg; lResults.Add(lvi); } return lResults; } private static List> FindSimilarPasswordsCEx( PwDatabase pd, IStatusLogger sl) { if((pd == null) || !pd.IsOpen) { Debug.Assert(false); return null; } PwGroup pg = pd.RootGroup; if(pg == null) { Debug.Assert(false); return null; } const uint uPrePct = 33; const long cPostPct = 67; List lEntries = new List(); List lPasswords = new List(); if(!GetEntryPasswords(pg, pd, sl, uPrePct, lEntries, lPasswords)) return null; int n = lEntries.Count; long cTotal = ((long)n * (long)(n - 1)) / 2L; long cDone = 0; float[,] mxSim = new float[n, n]; for(int i = 0; i < (n - 1); ++i) { string strA = lPasswords[i]; Debug.Assert(strA.Length != 0); for(int j = i + 1; j < n; ++j) { string strB = lPasswords[j]; float s = 0.0f; if(strA != strB) s = 1.0f - ((float)TextSimilarity.LevenshteinDistance(strA, strB) / (float)Math.Max(strA.Length, strB.Length)); mxSim[i, j] = s; mxSim[j, i] = s; if(sl != null) { ++cDone; uint u = uPrePct + (uint)((cDone * cPostPct) / cTotal); if(!sl.SetProgress(u)) return null; } } } Debug.Assert((cDone == cTotal) || (sl == null)); float[] vXSums = new float[n]; for(int i = 0; i < (n - 1); ++i) { for(int j = i + 1; j < n; ++j) { float s = mxSim[i, j]; if(s != 1.0f) { float x = s / (1.0f - s); vXSums[i] += x; vXSums[j] += x; } else { Debug.Assert(false); } } } List> lXSums = new List>(); for(int i = 0; i < n; ++i) lXSums.Add(new KeyValuePair(i, vXSums[i])); Comparison> fCmpS = delegate(KeyValuePair x, KeyValuePair y) { return y.Value.CompareTo(x.Value); // Descending }; lXSums.Sort(fCmpS); Comparison fCmpE = delegate(EuSimilarPasswords x, EuSimilarPasswords y) { return y.Similarity.CompareTo(x.Similarity); // Descending }; List> l = new List>(); // int cgMax = Math.Min(Math.Max(n / FspcShowItemsPerCluster, 20), n); int cgMax = Math.Min(Math.Max(n / 2, 20), n); for(int i = 0; i < cgMax; ++i) { int p = lXSums[i].Key; PwEntry pe = lEntries[p]; List lSim = new List(); lSim.Add(new EuSimilarPasswords(pe, pe, float.MaxValue)); for(int j = 0; j < n; ++j) { float s = mxSim[p, j]; Debug.Assert((j != p) || (s == 0.0f)); if(s > 0.5f) lSim.Add(new EuSimilarPasswords(pe, lEntries[j], s)); } if(lSim.Count >= 2) { lSim.Sort(fCmpE); l.Add(lSim); } } return l; } internal static List CreatePwQualityList(PwDatabase pd, IStatusLogger sl, out Action fInit) { fInit = delegate(ListView lv) { int w = lv.ClientSize.Width - UIUtil.GetVScrollBarWidth(); int wf = (int)(((long)w * 5L) / 23L); int wq = w - (wf * 4); int di = Math.Min(UIUtil.GetSmallIconSize().Width, wf); lv.Columns.Add(KPRes.Title, wf + di); lv.Columns.Add(KPRes.UserName, wf); lv.Columns.Add(KPRes.Password, wf); lv.Columns.Add(KPRes.Group, wf - di); lv.Columns.Add(KPRes.Quality, wq, HorizontalAlignment.Right); UIUtil.SetDisplayIndices(lv, new int[] { 1, 2, 3, 0, 4 }); }; List> l = CreatePwQualityListEx(pd, sl); if(l == null) return null; List lResults = new List(); DateTime dtNow = DateTime.UtcNow; Color clrL = UIUtil.ColorTowards(AppDefs.ColorQualityLow, AppDefs.ColorControlNormal, 0.5); Color clrH = UIUtil.ColorTowards(AppDefs.ColorQualityHigh, AppDefs.ColorControlNormal, 0.5); int rL = clrL.R, gL = clrL.G, bL = clrL.B; float rSp = (int)clrH.R - rL; float gSp = (int)clrH.G - gL; float bSp = (int)clrH.B - bL; foreach(KeyValuePair kvp in l) { PwEntry pe = kvp.Key; string strGroup = string.Empty; if(pe.ParentGroup != null) strGroup = pe.ParentGroup.GetFullPath(" - ", false); ListViewItem lvi = new ListViewItem(pe.Strings.ReadSafe( PwDefs.TitleField)); lvi.UseItemStyleForSubItems = false; lvi.SubItems.Add(pe.Strings.ReadSafe(PwDefs.UserNameField)); lvi.SubItems.Add(pe.Strings.ReadSafe(PwDefs.PasswordField)); lvi.SubItems.Add(strGroup); ulong q = (kvp.Value >> 32); ListViewItem.ListViewSubItem lvsi = lvi.SubItems.Add( q.ToString() + " " + KPRes.BitsStc); try { float fQ = (float)Math.Min(q, 128UL) / 128.0f; lvsi.BackColor = Color.FromArgb(rL + (int)(fQ * rSp), gL + (int)(fQ * gSp), bL + (int)(fQ * bSp)); } catch(Exception) { Debug.Assert(false); } lvi.ImageIndex = UIUtil.GetEntryIconIndex(pd, pe, dtNow); lvi.Tag = pe; lResults.Add(lvi); } return lResults; } private static List> CreatePwQualityListEx( PwDatabase pd, IStatusLogger sl) { if((pd == null) || !pd.IsOpen) { Debug.Assert(false); return null; } PwGroup pg = pd.RootGroup; if(pg == null) { Debug.Assert(false); return null; } uint uEntries = pg.GetEntriesCount(true); uint uEntriesDone = 0; List> l = new List>(); EntryHandler eh = delegate(PwEntry pe) { if((sl != null) && (uEntries != 0)) { uint u = (uEntriesDone * 100) / uEntries; if(!sl.SetProgress(u)) return false; } ++uEntriesDone; // Also used for sorting, see below if(!pe.GetSearchingEnabled()) return true; SprContext ctx = new SprContext(pe, pd, SprCompileFlags.NonActive); string str = SprEngine.Compile(pe.Strings.ReadSafe( PwDefs.PasswordField), ctx); if(str.Length != 0) { uint q = QualityEstimation.EstimatePasswordBits(str.ToCharArray()); l.Add(new KeyValuePair(pe, ((ulong)q << 32) | (ulong)uEntriesDone)); } return true; }; if(!pg.TraverseTree(TraversalMethod.PreOrder, null, eh)) return null; Comparison> fCompare = delegate( KeyValuePair x, KeyValuePair y) { return x.Value.CompareTo(y.Value); }; l.Sort(fCompare); return l; } } } KeePass/Util/SendInputExt/0000775000000000000000000000000013222430416014415 5ustar rootrootKeePass/Util/SendInputExt/SiEngineUnix.cs0000664000000000000000000000636513222430416017323 0ustar rootroot/* KeePass Password Safe - The Open-Source Password Manager Copyright (C) 2003-2018 Dominik Reichl This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ using System; using System.Collections.Generic; using System.Text; using System.Windows.Forms; using System.Globalization; using System.Diagnostics; using KeePass.Native; namespace KeePass.Util.SendInputExt { internal sealed class SiEngineUnix : SiEngineStd { public override void Init() { base.Init(); ReleaseModifiers(); } // public override void Release() // { // base.Release(); // } public override void SendKeyImpl(int iVKey, bool? bExtKey, bool? bDown) { SiCode si = SiCodes.Get(iVKey, bExtKey); if(si == null) { char ch = SiCodes.VKeyToChar(iVKey); if(ch != char.MinValue) SendCharImpl(ch, bDown); return; } string strXKeySym = si.XKeySym; if(string.IsNullOrEmpty(strXKeySym)) { Debug.Assert(false); return; } string strVerb = "key"; if(bDown.HasValue) strVerb = (bDown.Value ? "keydown" : "keyup"); RunXDoTool(strVerb, strXKeySym); } public override void SetKeyModifierImpl(Keys kMod, bool bDown) { string strVerb = (bDown ? "keydown" : "keyup"); if((kMod & Keys.Shift) != Keys.None) RunXDoTool(strVerb, "shift"); if((kMod & Keys.Control) != Keys.None) RunXDoTool(strVerb, "ctrl"); if((kMod & Keys.Alt) != Keys.None) RunXDoTool(strVerb, "alt"); } public override void SendCharImpl(char ch, bool? bDown) { string strVerb = "key"; if(bDown.HasValue) strVerb = (bDown.Value ? "keydown" : "keyup"); RunXDoTool(strVerb, SiCodes.CharToXKeySym(ch)); } private static void ReleaseModifiers() { // '--clearmodifiers' clears the modifiers only for the // current command and restores them afterwards, i.e. // it does not permanently clear the modifiers // str += " --clearmodifiers"; // Both left and right modifier keys must be released; // releasing only one does not necessarily clear the // modifier state string[] vMods = new string[] { "Shift_L", "Shift_R", "Control_L", "Control_R", "Alt_L", "Alt_R", "Super_L", "Super_R", "Meta_L", "Meta_R" }; foreach(string strMod in vMods) RunXDoTool("keyup", strMod); } private static void RunXDoTool(string strVerb, string strParam) { if(string.IsNullOrEmpty(strVerb)) { Debug.Assert(false); return; } string str = strVerb; if(!string.IsNullOrEmpty(strParam)) str += " " + strParam; NativeMethods.RunXDoTool(str); } } } KeePass/Util/SendInputExt/SiEngineStd.cs0000664000000000000000000001134413222430416017123 0ustar rootroot/* KeePass Password Safe - The Open-Source Password Manager Copyright (C) 2003-2018 Dominik Reichl This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ using System; using System.Collections.Generic; using System.Diagnostics; using System.Security; using System.Text; using System.Threading; using System.Windows.Forms; using KeePass.Native; using KeePass.Resources; using KeePassLib.Utility; namespace KeePass.Util.SendInputExt { public abstract class SiEngineStd : ISiEngine { public IntPtr TargetHWnd = IntPtr.Zero; public string TargetWindowTitle = string.Empty; public bool Cancelled = false; private Stopwatch m_swLastEvent = new Stopwatch(); #if DEBUG private List m_lDelaysRec = new List(); #endif public virtual void Init() { try { Debug.Assert(!m_swLastEvent.IsRunning); IntPtr hWndTarget; string strTargetTitle; NativeMethods.GetForegroundWindowInfo(out hWndTarget, out strTargetTitle, false); this.TargetHWnd = hWndTarget; this.TargetWindowTitle = (strTargetTitle ?? string.Empty); } catch(Exception) { Debug.Assert(false); } } public virtual void Release() { m_swLastEvent.Stop(); } public abstract void SendKeyImpl(int iVKey, bool? bExtKey, bool? bDown); public abstract void SetKeyModifierImpl(Keys kMod, bool bDown); public abstract void SendCharImpl(char ch, bool? bDown); private bool PreSendEvent() { // Update event time *before* actually performing the event m_swLastEvent.Reset(); m_swLastEvent.Start(); return ValidateState(); } public void SendKey(int iVKey, bool? bExtKey, bool? bDown) { if(!PreSendEvent()) return; SendKeyImpl(iVKey, bExtKey, bDown); Application.DoEvents(); } public void SetKeyModifier(Keys kMod, bool bDown) { if(!PreSendEvent()) return; SetKeyModifierImpl(kMod, bDown); Application.DoEvents(); } public void SendChar(char ch, bool? bDown) { if(!PreSendEvent()) return; SendCharImpl(ch, bDown); Application.DoEvents(); } public virtual void Delay(uint uMs) { if(this.Cancelled) return; if(!m_swLastEvent.IsRunning) { Thread.Sleep((int)uMs); m_swLastEvent.Reset(); m_swLastEvent.Start(); return; } m_swLastEvent.Stop(); long lAlreadyDelayed = m_swLastEvent.ElapsedMilliseconds; long lRemDelay = (long)uMs - lAlreadyDelayed; if(lRemDelay >= 0) Thread.Sleep((int)lRemDelay); #if DEBUG m_lDelaysRec.Add(lAlreadyDelayed); #endif m_swLastEvent.Reset(); m_swLastEvent.Start(); } private bool ValidateState() { if(this.Cancelled) return false; List lAbortWindows = Program.Config.Integration.AutoTypeAbortOnWindows; bool bChkWndCh = Program.Config.Integration.AutoTypeCancelOnWindowChange; bool bChkTitleCh = Program.Config.Integration.AutoTypeCancelOnTitleChange; bool bChkTitleFx = (lAbortWindows.Count != 0); if(bChkWndCh || bChkTitleCh || bChkTitleFx) { IntPtr h = IntPtr.Zero; string strTitle = null; bool bHasInfo = true; try { NativeMethods.GetForegroundWindowInfo(out h, out strTitle, false); } catch(Exception) { Debug.Assert(false); bHasInfo = false; } if(strTitle == null) strTitle = string.Empty; if(bHasInfo) { if(bChkWndCh && (h != this.TargetHWnd)) { this.Cancelled = true; return false; } if(bChkTitleCh && (strTitle != this.TargetWindowTitle)) { this.Cancelled = true; return false; } if(bChkTitleFx) { foreach(string strWnd in lAbortWindows) { if(string.IsNullOrEmpty(strWnd)) continue; if(AutoType.MatchWindows(strWnd, strTitle)) { this.Cancelled = true; throw new SecurityException(KPRes.AutoTypeAbortedOnWindow + MessageService.NewParagraph + KPRes.TargetWindow + @": '" + strTitle + @"'."); } } } } } return true; } } } KeePass/Util/SendInputExt/SiEngineWin.cs0000664000000000000000000006363413222430416017137 0ustar rootroot/* KeePass Password Safe - The Open-Source Password Manager Copyright (C) 2003-2018 Dominik Reichl This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ using System; using System.Collections.Generic; using System.Text; using System.Windows.Forms; using System.Runtime.InteropServices; using System.Threading; using System.Diagnostics; using KeePass.Native; using KeePassLib.Utility; namespace KeePass.Util.SendInputExt { internal sealed class SiEngineWin : SiEngineStd { private static Dictionary g_dProcessSendMethods = new Dictionary(); private IntPtr m_hklOriginal = IntPtr.Zero; private IntPtr m_hklCurrent = IntPtr.Zero; private bool m_bInputBlocked = false; private SiSendMethod? m_osmEnforced = null; private Dictionary m_dWindowInfos = new Dictionary(); private SiWindowInfo m_swiCurrent = new SiWindowInfo(IntPtr.Zero); // private bool m_bThreadInputAttached = false; private Keys m_kModCur = Keys.None; private static readonly int[] g_vToggleKeys = new int[] { NativeMethods.VK_CAPITAL // Caps Lock }; public override void Init() { base.Init(); try { InitProcessSendMethods(); InitForEnv(); // Do not use SendKeys.Flush here, use Application.DoEvents // instead; SendKeys.Flush might run into an infinite loop here // if a previous auto-type process failed with throwing an // exception (SendKeys.Flush is waiting in a loop for an internal // queue being empty, however the queue is never processed) Application.DoEvents(); // if(m_uThisThreadID != m_uTargetThreadID) // { // m_bThreadInputAttached = NativeMethods.AttachThreadInput( // m_uThisThreadID, m_uTargetThreadID, true); // Debug.Assert(m_bThreadInputAttached); // } // else { Debug.Assert(false); } m_bInputBlocked = NativeMethods.BlockInput(true); uint? tLastInput = NativeMethods.GetLastInputTime(); if(tLastInput.HasValue) { int iDiff = Environment.TickCount - (int)tLastInput.Value; Debug.Assert(iDiff >= 0); if(iDiff == 0) { // Enforce delay after pressing the global auto-type // hot key, as a workaround for applications // with broken time-dependent message processing; // https://sourceforge.net/p/keepass/bugs/1213/ Thread.Sleep(1); Application.DoEvents(); } } PrepareSend(); if(ReleaseModifiers(true) > 0) { // Enforce delay between releasing modifiers and sending // the actual sequence, as a workaround for applications // with broken time-dependent message processing; // https://sourceforge.net/p/keepass/bugs/1213/ Thread.Sleep(1); Application.DoEvents(); } } catch(Exception) { Debug.Assert(false); } } public override void Release() { try { PrepareSend(); // For releasing modifiers if(m_bInputBlocked) { NativeMethods.BlockInput(false); // Unblock m_bInputBlocked = false; } Debug.Assert(m_kModCur == Keys.None); // Do not restore original modifier keys here, otherwise // modifier keys are restored even when the user released // them while KeePass is auto-typing if(ReleaseModifiers(false) != 0) { Debug.Assert(false); } // if(m_bThreadInputAttached) // NativeMethods.AttachThreadInput(m_uThisThreadID, // m_uTargetThreadID, false); // Detach Debug.Assert(NativeMethods.GetKeyboardLayout(0) == m_hklCurrent); if((m_hklCurrent != m_hklOriginal) && (m_hklOriginal != IntPtr.Zero)) { if(NativeMethods.ActivateKeyboardLayout(m_hklOriginal, 0) != m_hklCurrent) { Debug.Assert(false); } m_hklCurrent = m_hklOriginal; } Application.DoEvents(); } catch(Exception) { Debug.Assert(false); } base.Release(); } public override void SendKeyImpl(int iVKey, bool? bExtKey, bool? bDown) { PrepareSend(); // Disable IME (only required for sending VKeys, not for chars); // https://sourceforge.net/p/keepass/discussion/329221/thread/5da4bd14/ // using(SiImeBlocker sib = new SiImeBlocker(hWnd)) if(bDown.HasValue) { SendVKeyNative(iVKey, bExtKey, bDown.Value); return; } SendVKeyNative(iVKey, bExtKey, true); SendVKeyNative(iVKey, bExtKey, false); } public override void SetKeyModifierImpl(Keys kMod, bool bDown) { SetKeyModifierImplEx(kMod, bDown, false); } private void SetKeyModifierImplEx(Keys kMod, bool bDown, bool bRAlt) { PrepareSend(); if((kMod & Keys.Shift) != Keys.None) SendVKeyNative((int)Keys.ShiftKey, null, bDown); if((kMod & Keys.Control) != Keys.None) SendVKeyNative((int)Keys.ControlKey, null, bDown); if((kMod & Keys.Alt) != Keys.None) { int vk = (int)(bRAlt ? Keys.RMenu : Keys.Menu); SendVKeyNative(vk, null, bDown); } if(bDown) m_kModCur |= kMod; else m_kModCur &= ~kMod; } public override void SendCharImpl(char ch, bool? bDown) { PrepareSend(); if(TrySendCharByKeypresses(ch, bDown)) return; if(bDown.HasValue) { SendCharNative(ch, bDown.Value); return; } SendCharNative(ch, true); SendCharNative(ch, false); } private static void InitProcessSendMethods() { Dictionary d = g_dProcessSendMethods; if(d.Count > 0) return; // Init once is sufficient string[] vEnfUni = new string[] { "PuTTY", "KiTTY", "KiTTY_Portable", "KiTTY_NoTrans", "KiTTY_NoHyperlink", "KiTTY_NoCompress", "PuTTYjp", // "mRemoteNG", // No effect // "PuTTYNG", // No effect // SuperPuTTY spawns PuTTY processes whose windows are // displayed embedded in the SuperPuTTY window (without // window borders), thus the definition "PuTTY" also // fixes SuperPuTTY; no "SuperPuTTY" required // "SuperPuTTY", "MinTTY" // Cygwin window "~" }; foreach(string strEnfUni in vEnfUni) { d[strEnfUni] = SiSendMethod.UnicodePacket; } string[] vEnfKey = new string[] { "MSTSC", // Remote Desktop Connection client "VirtualBox", // VirtualBox does not support VK_PACKET "VpxClient" // VMware vSphere client }; foreach(string strEnfKey in vEnfKey) { d[strEnfKey] = SiSendMethod.KeyEvent; } } private void InitForEnv() { #if DEBUG Stopwatch sw = Stopwatch.StartNew(); #endif try { m_hklCurrent = NativeMethods.GetKeyboardLayout(0); m_hklOriginal = m_hklCurrent; Debug.Assert(m_hklOriginal != IntPtr.Zero); Process[] vProcesses = Process.GetProcesses(); foreach(Process p in vProcesses) { if(p == null) { Debug.Assert(false); continue; } try { string strName = GetProcessName(p); // If the Neo keyboard layout is being used, we must // send Unicode characters; keypresses are converted // and thus do not lead to the expected result if(ProcessNameMatches(strName, "Neo20")) { FileVersionInfo fvi = p.MainModule.FileVersionInfo; if(((fvi.ProductName ?? string.Empty).Trim().Length == 0) && ((fvi.FileDescription ?? string.Empty).Trim().Length == 0)) m_osmEnforced = SiSendMethod.UnicodePacket; else { Debug.Assert(false); } } else if(ProcessNameMatches(strName, "KbdNeo_Ahk")) m_osmEnforced = SiSendMethod.UnicodePacket; } catch(Exception) { Debug.Assert(false); } try { p.Dispose(); } catch(Exception) { Debug.Assert(false); } } } catch(Exception) { Debug.Assert(false); } #if DEBUG sw.Stop(); Debug.Assert(sw.ElapsedMilliseconds < 100); #endif } private bool SendVKeyNative(int vKey, bool? bExtKey, bool bDown) { bool bRes = false; if(IntPtr.Size == 4) bRes = SendVKeyNative32(vKey, bExtKey, null, bDown); else if(IntPtr.Size == 8) bRes = SendVKeyNative64(vKey, bExtKey, null, bDown); else { Debug.Assert(false); } // The following does not hold when sending keypresses to // key state-consuming windows (e.g. VM windows) // if(bDown && (vKey != NativeMethods.VK_CAPITAL)) // { // Debug.Assert(IsKeyActive(vKey)); // } return bRes; } private bool SendCharNative(char ch, bool bDown) { if(IntPtr.Size == 4) return SendVKeyNative32(0, null, ch, bDown); else if(IntPtr.Size == 8) return SendVKeyNative64(0, null, ch, bDown); else { Debug.Assert(false); } return false; } private bool SendVKeyNative32(int vKey, bool? bExtKey, char? optUnicodeChar, bool bDown) { NativeMethods.INPUT32[] pInput = new NativeMethods.INPUT32[1]; pInput[0].Type = NativeMethods.INPUT_KEYBOARD; if(optUnicodeChar.HasValue && WinUtil.IsAtLeastWindows2000) { pInput[0].KeyboardInput.VirtualKeyCode = 0; pInput[0].KeyboardInput.ScanCode = (ushort)optUnicodeChar.Value; pInput[0].KeyboardInput.Flags = ((bDown ? 0 : NativeMethods.KEYEVENTF_KEYUP) | NativeMethods.KEYEVENTF_UNICODE); } else { IntPtr hKL = m_swiCurrent.KeyboardLayout; if(optUnicodeChar.HasValue) vKey = (int)(NativeMethods.VkKeyScan3(optUnicodeChar.Value, hKL) & 0xFFU); pInput[0].KeyboardInput.VirtualKeyCode = (ushort)vKey; pInput[0].KeyboardInput.ScanCode = (ushort)(NativeMethods.MapVirtualKey3((uint)vKey, NativeMethods.MAPVK_VK_TO_VSC, hKL) & 0xFFU); pInput[0].KeyboardInput.Flags = GetKeyEventFlags(vKey, bExtKey, bDown); } pInput[0].KeyboardInput.Time = 0; pInput[0].KeyboardInput.ExtraInfo = NativeMethods.GetMessageExtraInfo(); Debug.Assert(Marshal.SizeOf(typeof(NativeMethods.INPUT32)) == 28); if(NativeMethods.SendInput32(1, pInput, Marshal.SizeOf(typeof(NativeMethods.INPUT32))) != 1) return false; return true; } private bool SendVKeyNative64(int vKey, bool? bExtKey, char? optUnicodeChar, bool bDown) { NativeMethods.SpecializedKeyboardINPUT64[] pInput = new NativeMethods.SpecializedKeyboardINPUT64[1]; pInput[0].Type = NativeMethods.INPUT_KEYBOARD; if(optUnicodeChar.HasValue && WinUtil.IsAtLeastWindows2000) { pInput[0].VirtualKeyCode = 0; pInput[0].ScanCode = (ushort)optUnicodeChar.Value; pInput[0].Flags = ((bDown ? 0 : NativeMethods.KEYEVENTF_KEYUP) | NativeMethods.KEYEVENTF_UNICODE); } else { IntPtr hKL = m_swiCurrent.KeyboardLayout; if(optUnicodeChar.HasValue) vKey = (int)(NativeMethods.VkKeyScan3(optUnicodeChar.Value, hKL) & 0xFFU); pInput[0].VirtualKeyCode = (ushort)vKey; pInput[0].ScanCode = (ushort)(NativeMethods.MapVirtualKey3( (uint)vKey, NativeMethods.MAPVK_VK_TO_VSC, hKL) & 0xFFU); pInput[0].Flags = GetKeyEventFlags(vKey, bExtKey, bDown); } pInput[0].Time = 0; pInput[0].ExtraInfo = NativeMethods.GetMessageExtraInfo(); Debug.Assert(Marshal.SizeOf(typeof(NativeMethods.SpecializedKeyboardINPUT64)) == 40); if(NativeMethods.SendInput64Special(1, pInput, Marshal.SizeOf(typeof(NativeMethods.SpecializedKeyboardINPUT64))) != 1) return false; return true; } private static uint GetKeyEventFlags(int vKey, bool? bExtKey, bool bDown) { uint u = 0; if(!bDown) u |= NativeMethods.KEYEVENTF_KEYUP; if(bExtKey.HasValue) { if(bExtKey.Value) u |= NativeMethods.KEYEVENTF_EXTENDEDKEY; } else if(IsExtendedKeyEx(vKey)) u |= NativeMethods.KEYEVENTF_EXTENDEDKEY; return u; } private static bool IsExtendedKeyEx(int vKey) { #if DEBUG // https://msdn.microsoft.com/en-us/library/windows/desktop/dd375731.aspx // https://www.win.tue.nl/~aeb/linux/kbd/scancodes-1.html const uint m = NativeMethods.MAPVK_VK_TO_VSC; IntPtr h = IntPtr.Zero; Debug.Assert(NativeMethods.MapVirtualKey3((uint) NativeMethods.VK_LSHIFT, m, h) == 0x2AU); Debug.Assert(NativeMethods.MapVirtualKey3((uint) NativeMethods.VK_RSHIFT, m, h) == 0x36U); Debug.Assert(NativeMethods.MapVirtualKey3((uint) NativeMethods.VK_SHIFT, m, h) == 0x2AU); Debug.Assert(NativeMethods.MapVirtualKey3((uint) NativeMethods.VK_LCONTROL, m, h) == 0x1DU); Debug.Assert(NativeMethods.MapVirtualKey3((uint) NativeMethods.VK_RCONTROL, m, h) == 0x1DU); Debug.Assert(NativeMethods.MapVirtualKey3((uint) NativeMethods.VK_CONTROL, m, h) == 0x1DU); Debug.Assert(NativeMethods.MapVirtualKey3((uint) NativeMethods.VK_LMENU, m, h) == 0x38U); Debug.Assert(NativeMethods.MapVirtualKey3((uint) NativeMethods.VK_RMENU, m, h) == 0x38U); Debug.Assert(NativeMethods.MapVirtualKey3((uint) NativeMethods.VK_MENU, m, h) == 0x38U); Debug.Assert(NativeMethods.MapVirtualKey3(0x5BU, m, h) == 0x5BU); Debug.Assert(NativeMethods.MapVirtualKey3(0x5CU, m, h) == 0x5CU); Debug.Assert(NativeMethods.MapVirtualKey3(0x5DU, m, h) == 0x5DU); Debug.Assert(NativeMethods.MapVirtualKey3(0x6AU, m, h) == 0x37U); Debug.Assert(NativeMethods.MapVirtualKey3(0x6BU, m, h) == 0x4EU); Debug.Assert(NativeMethods.MapVirtualKey3(0x6DU, m, h) == 0x4AU); Debug.Assert(NativeMethods.MapVirtualKey3(0x6EU, m, h) == 0x53U); Debug.Assert(NativeMethods.MapVirtualKey3(0x6FU, m, h) == 0x35U); #endif if((vKey >= 0x21) && (vKey <= 0x2E)) return true; if((vKey >= 0x5B) && (vKey <= 0x5D)) return true; if(vKey == 0x6F) return true; // VK_DIVIDE // RShift is separate; no E0 if(vKey == NativeMethods.VK_RCONTROL) return true; if(vKey == NativeMethods.VK_RMENU) return true; return false; } private int ReleaseModifiers(bool bWithSpecial) { List lMods = new List(); lMods.AddRange(new int[] { NativeMethods.VK_LWIN, NativeMethods.VK_RWIN, NativeMethods.VK_LSHIFT, NativeMethods.VK_RSHIFT, NativeMethods.VK_SHIFT, NativeMethods.VK_LCONTROL, NativeMethods.VK_RCONTROL, NativeMethods.VK_CONTROL, NativeMethods.VK_LMENU, NativeMethods.VK_RMENU, NativeMethods.VK_MENU }); lMods.AddRange(g_vToggleKeys); List lReleased = new List(); foreach(int vKey in lMods) { if(IsKeyActive(vKey)) { // The generic modifiers should not be activated, // when the left and right keys are up Debug.Assert(vKey != NativeMethods.VK_SHIFT); Debug.Assert(vKey != NativeMethods.VK_CONTROL); Debug.Assert(vKey != NativeMethods.VK_MENU); ActivateOrToggleKey(vKey, false); lReleased.Add(vKey); Application.DoEvents(); } } if(bWithSpecial) ReleaseModifiersSpecialPost(lReleased); return lReleased.Count; } private static bool IsKeyActive(int vKey) { if(Array.IndexOf(g_vToggleKeys, vKey) >= 0) { ushort us = NativeMethods.GetKeyState(vKey); return ((us & 1) != 0); } ushort usState = NativeMethods.GetAsyncKeyState(vKey); return ((usState & 0x8000) != 0); // For GetKeyState: // if(Array.IndexOf(g_vToggleKeys, vKey) >= 0) // return ((usState & 1) != 0); // else // return ((usState & 0x8000) != 0); } private void ActivateOrToggleKey(int vKey, bool bDown) { if(Array.IndexOf(g_vToggleKeys, vKey) >= 0) { SendVKeyNative(vKey, null, true); SendVKeyNative(vKey, null, false); } else SendVKeyNative(vKey, null, bDown); } private void ReleaseModifiersSpecialPost(List vKeys) { if(vKeys.Count == 0) return; // Get out of a menu bar that was focused when only // using Alt as hot key modifier if(Program.Config.Integration.AutoTypeReleaseAltWithKeyPress && vKeys.TrueForAll(SiEngineWin.IsAltOrToggle)) { if(vKeys.Contains(NativeMethods.VK_LMENU)) { SendVKeyNative(NativeMethods.VK_LMENU, null, true); SendVKeyNative(NativeMethods.VK_LMENU, null, false); } else if(vKeys.Contains(NativeMethods.VK_RMENU)) { SendVKeyNative(NativeMethods.VK_RMENU, null, true); SendVKeyNative(NativeMethods.VK_RMENU, null, false); } } } private static bool IsAltOrToggle(int vKey) { if(vKey == NativeMethods.VK_LMENU) return true; if(vKey == NativeMethods.VK_RMENU) return true; if(vKey == NativeMethods.VK_MENU) return true; if(Array.IndexOf(g_vToggleKeys, vKey) >= 0) return true; return false; } private static char[] m_vForcedUniChars = null; private bool TrySendCharByKeypresses(char ch, bool? bDown) { if(ch == char.MinValue) { Debug.Assert(false); return false; } SiSendMethod sm = GetSendMethod(m_swiCurrent); if(sm == SiSendMethod.UnicodePacket) return false; if(m_vForcedUniChars == null) m_vForcedUniChars = new char[] { // All of the following diacritics are spacing / non-combining '\u005E', // Circumflex ^ '\u0060', // Grave accent '\u00A8', // Diaeresis '\u00AF', // Macron above, long '\u00B0', // Degree (e.g. for Czech) '\u00B4', // Acute accent '\u00B8', // Cedilla // E.g. for US-International; // https://sourceforge.net/p/keepass/discussion/329220/thread/5708e5ef/ '\u0022', // Quotation mark '\u0027', // Apostrophe '\u007E' // Tilde // Spacing Modifier Letters; see below // '\u02C7', // Caron (e.g. for Canadian Multilingual) // '\u02C9', // Macron above, modifier, short // '\u02CD', // Macron below, modifier, short // '\u02D8', // Breve // '\u02D9', // Dot above // '\u02DA', // Ring above // '\u02DB', // Ogonek // '\u02DC', // Small tilde // '\u02DD', // Double acute accent }; if(sm != SiSendMethod.KeyEvent) // If Unicode packets allowed { if(Array.IndexOf(m_vForcedUniChars, ch) >= 0) return false; // U+02B0 to U+02FF are Spacing Modifier Letters; // https://www.unicode.org/charts/PDF/U02B0.pdf // https://en.wikipedia.org/wiki/Spacing_Modifier_Letters if((ch >= '\u02B0') && (ch <= '\u02FF')) return false; } IntPtr hKL = m_swiCurrent.KeyboardLayout; ushort u = NativeMethods.VkKeyScan3(ch, hKL); if(u == 0xFFFFU) return false; int vKey = (int)(u & 0xFFU); Keys kMod = Keys.None; int nMods = 0; if((u & 0x100U) != 0U) { ++nMods; kMod |= Keys.Shift; } if((u & 0x200U) != 0U) { ++nMods; kMod |= Keys.Control; } if((u & 0x400U) != 0U) { ++nMods; kMod |= Keys.Alt; } if((u & 0x800U) != 0U) return false; // Hankaku unsupported // Do not send a key combination that is registered as hot key; // https://sourceforge.net/p/keepass/bugs/1235/ // Windows shortcut hot keys involve at least 2 modifiers if(nMods >= 2) { Keys kFull = (kMod | (Keys)vKey); if(HotKeyManager.IsHotKeyRegistered(kFull, true)) return false; } // Windows' GetKeyboardState function does not return the // current virtual key array (especially not after changing // them below), thus we build the array on our own byte[] pbState = new byte[256]; if((kMod & Keys.Shift) != Keys.None) { pbState[NativeMethods.VK_SHIFT] = 0x80; pbState[NativeMethods.VK_LSHIFT] = 0x80; } if((kMod & Keys.Control) != Keys.None) { pbState[NativeMethods.VK_CONTROL] = 0x80; pbState[NativeMethods.VK_LCONTROL] = 0x80; } if((kMod & Keys.Alt) != Keys.None) { pbState[NativeMethods.VK_MENU] = 0x80; pbState[NativeMethods.VK_RMENU] = 0x80; // See below } pbState[NativeMethods.VK_NUMLOCK] = 0x01; // Toggled bool bCapsLock = false; // The keypress that VkKeyScan returns may require a specific // state of toggle keys, on which it provides no information; // thus we now check whether the keypress will really result // in the character that we expect; // https://sourceforge.net/p/keepass/bugs/1594/ string strUni = NativeMethods.ToUnicode3(vKey, pbState, hKL); if((strUni != null) && (strUni.Length == 0)) { } // Dead key else if(string.IsNullOrEmpty(strUni) || (strUni[strUni.Length - 1] != ch)) { // Among the keyboard layouts that were tested, the // Czech one was the only one where the translation // may fail (due to dependency on the Caps Lock state) Debug.Assert(NativeMethods.GetPrimaryLangID((ushort)(hKL.ToInt64() & 0xFFFFL)) == NativeMethods.LANG_CZECH); // Test whether Caps Lock is required pbState[NativeMethods.VK_CAPITAL] = 0x01; strUni = NativeMethods.ToUnicode3(vKey, pbState, hKL); if((strUni != null) && (strUni.Length == 0)) { } // Dead key else if(string.IsNullOrEmpty(strUni) || (strUni[strUni.Length - 1] != ch)) { Debug.Assert(false); // An unknown key modifier is required return false; } bCapsLock = true; } if(bCapsLock) { SendKeyImpl(NativeMethods.VK_CAPITAL, null, null); Thread.Sleep(1); Application.DoEvents(); } Keys kModDiff = (kMod & ~m_kModCur); if(kModDiff != Keys.None) { // Send RAlt for better AltGr compatibility; // https://sourceforge.net/p/keepass/bugs/1475/ SetKeyModifierImplEx(kModDiff, true, true); Thread.Sleep(1); Application.DoEvents(); } SendKeyImpl(vKey, null, bDown); if(kModDiff != Keys.None) { Thread.Sleep(1); Application.DoEvents(); SetKeyModifierImplEx(kModDiff, false, true); } if(bCapsLock) { Thread.Sleep(1); Application.DoEvents(); SendKeyImpl(NativeMethods.VK_CAPITAL, null, null); } return true; } private SiSendMethod GetSendMethod(SiWindowInfo swi) { if(m_osmEnforced.HasValue) return m_osmEnforced.Value; return swi.SendMethod; } private SiWindowInfo GetWindowInfo(IntPtr hWnd) { SiWindowInfo swi; if(m_dWindowInfos.TryGetValue(hWnd, out swi)) return swi; swi = new SiWindowInfo(hWnd); Process p = null; try { uint uPID; uint uTID = NativeMethods.GetWindowThreadProcessId(hWnd, out uPID); swi.KeyboardLayout = NativeMethods.GetKeyboardLayout(uTID); p = Process.GetProcessById((int)uPID); string strName = GetProcessName(p); foreach(KeyValuePair kvp in g_dProcessSendMethods) { if(ProcessNameMatches(strName, kvp.Key)) { swi.SendMethod = kvp.Value; break; } } // The workaround attempt for Edge below doesn't work; // Edge simply ignores Unicode packets for '@', Euro sign, etc. /* if(swi.SendMethod == SiSendMethod.Default) { string strTitle = NativeMethods.GetWindowText(hWnd, true); // Workaround for Edge; // https://sourceforge.net/p/keepass/discussion/329220/thread/fd3a6776/ // The window title is: // Page name + Space + U+200E (left-to-right mark) + "- Microsoft Edge" if(strTitle.EndsWith("- Microsoft Edge", StrUtil.CaseIgnoreCmp)) swi.SendMethod = SiSendMethod.UnicodePacket; } */ } catch(Exception) { Debug.Assert(false); } finally { try { if(p != null) p.Dispose(); } catch(Exception) { Debug.Assert(false); } } m_dWindowInfos[hWnd] = swi; return swi; } private void PrepareSend() { IntPtr hWnd = NativeMethods.GetForegroundWindowHandle(); m_swiCurrent = GetWindowInfo(hWnd); EnsureSameKeyboardLayout(); } private void EnsureSameKeyboardLayout() { if(!Program.Config.Integration.AutoTypeAdjustKeyboardLayout) return; IntPtr hklTarget = m_swiCurrent.KeyboardLayout; Debug.Assert(hklTarget != IntPtr.Zero); Debug.Assert(NativeMethods.GetKeyboardLayout(0) == m_hklCurrent); if((m_hklCurrent != hklTarget) && (hklTarget != IntPtr.Zero)) { if(NativeMethods.ActivateKeyboardLayout(hklTarget, 0) != m_hklCurrent) { Debug.Assert(false); } m_hklCurrent = hklTarget; Thread.Sleep(1); Application.DoEvents(); } } private static string GetProcessName(Process p) { if(p == null) { Debug.Assert(false); return string.Empty; } try { return (p.ProcessName ?? string.Empty).Trim(); } catch(Exception) { Debug.Assert(false); } return string.Empty; } private static bool ProcessNameMatches(string strUnk, string strPattern) { if(strUnk == null) { Debug.Assert(false); return false; } if(strPattern == null) { Debug.Assert(false); return false; } Debug.Assert(strUnk.Trim() == strUnk); Debug.Assert(strPattern.Trim() == strPattern); Debug.Assert(!strPattern.EndsWith(".exe", StrUtil.CaseIgnoreCmp)); return (strUnk.Equals(strPattern, StrUtil.CaseIgnoreCmp) || strUnk.Equals(strPattern + ".exe", StrUtil.CaseIgnoreCmp)); } } /* internal sealed class SiImeBlocker : IDisposable { private IntPtr m_hWnd; private IntPtr m_hOrgIme = IntPtr.Zero; public SiImeBlocker(IntPtr hWnd) { m_hWnd = hWnd; if(hWnd == IntPtr.Zero) return; try { m_hOrgIme = NativeMethods.ImmAssociateContext(hWnd, IntPtr.Zero); } catch(Exception) { Debug.Assert(false); } } ~SiImeBlocker() { Dispose(false); } public void Dispose() { Dispose(true); GC.SuppressFinalize(this); } private void Dispose(bool bDisposing) { if(m_hOrgIme != IntPtr.Zero) { try { NativeMethods.ImmAssociateContext(m_hWnd, m_hOrgIme); } catch(Exception) { Debug.Assert(false); } m_hOrgIme = IntPtr.Zero; } } } */ } KeePass/Util/SendInputExt/SiObf.cs0000664000000000000000000001073313222430416015752 0ustar rootroot/* KeePass Password Safe - The Open-Source Password Manager Copyright (C) 2003-2018 Dominik Reichl This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ using System; using System.Collections.Generic; using System.Text; using System.Windows.Forms; using System.Diagnostics; namespace KeePass.Util.SendInputExt { internal static class SiObf { public static void Obfuscate(List l) { if(l == null) { Debug.Assert(false); return; } int n = l.Count; if(n <= 1) return; bool[] vValid = new bool[n]; Keys kMod = Keys.None; for(int i = 0; i < n; ++i) { SiEvent si = l[i]; if(si.Type == SiEventType.KeyModifier) { if(si.Down.HasValue) { if(si.Down.Value) { Debug.Assert((kMod & si.KeyModifier) == Keys.None); kMod |= si.KeyModifier; } else { Debug.Assert((kMod & si.KeyModifier) == si.KeyModifier); kMod &= ~si.KeyModifier; } } else { Debug.Assert(false); } } else if((si.Type == SiEventType.Char) && (kMod == Keys.None)) vValid[i] = true; } int c = 0; for(int i = n - 1; i >= -1; --i) { if((i == -1) || !vValid[i]) { if(c > 0) { ReplaceByMixedTransfer(l, i + 1, c); c = 0; } } else ++c; } } private static void ReplaceByMixedTransfer(List l, int iOffset, int nCount) { List lNew = new List(); StringBuilder sbClip = new StringBuilder(); // The string should be split randomly, but the same each // time this function is called. Otherwise an attacker could // get information by observing different splittings each // time auto-type is performed. Therefore, compute the random // seed based on the string to be auto-typed. Random r = new Random(GetRandomSeed(l, iOffset, nCount)); for(int i = 0; i < nCount; ++i) { char ch = l[iOffset + i].Char; SiEvent si = new SiEvent(); if(r.Next(0, 2) == 0) { sbClip.Append(ch); si.Type = SiEventType.Key; si.VKey = (int)Keys.Right; } else { si.Type = SiEventType.Char; si.Char = ch; } lNew.Add(si); } string strClip = sbClip.ToString(); if(strClip.Length > 0) { SiEvent si = new SiEvent(); si.Type = SiEventType.ClipboardCopy; si.Text = strClip; lNew.Insert(0, si); // Mixed transfer occurs only for text without any modifiers, // thus we can press Ctrl+V for pasting here si = new SiEvent(); si.Type = SiEventType.KeyModifier; si.KeyModifier = Keys.Control; si.Down = true; lNew.Insert(1, si); // Send the 'v' using a virtual key code, not as char; // sending it as char (translated to a keypress) doesn't // work with all keyboard layouts (e.g. Russian); // https://sourceforge.net/p/keepass/discussion/329220/thread/938d06a7/ si = new SiEvent(); si.Type = SiEventType.Key; si.VKey = (int)Keys.V; lNew.Insert(2, si); si = new SiEvent(); si.Type = SiEventType.KeyModifier; si.KeyModifier = Keys.Control; si.Down = false; lNew.Insert(3, si); for(int i = 0; i < strClip.Length; ++i) { si = new SiEvent(); si.Type = SiEventType.Key; si.VKey = (int)Keys.Left; lNew.Insert(4, si); } } l.RemoveRange(iOffset, nCount); l.InsertRange(iOffset, lNew); } private static int GetRandomSeed(List l, int iOffset, int nCount) { int nSeed = 3; unchecked { for(int i = 0; i < nCount; ++i) nSeed = nSeed * 13 + l[iOffset + i].Char; } // Prevent overflow (see .NET 2.0 Random class constructor) if(nSeed == int.MinValue) nSeed = 13; return nSeed; } } } KeePass/Util/SendInputExt/ISiEngine.cs0000664000000000000000000000234013222430416016555 0ustar rootroot/* KeePass Password Safe - The Open-Source Password Manager Copyright (C) 2003-2018 Dominik Reichl This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ using System; using System.Collections.Generic; using System.Text; using System.Windows.Forms; namespace KeePass.Util.SendInputExt { public interface ISiEngine { void Init(); void Release(); void SendKey(int iVKey, bool? bExtKey, bool? bDown); void SetKeyModifier(Keys kMod, bool bDown); void SendChar(char ch, bool? bDown); void Delay(uint uMs); } } KeePass/Util/SendInputExt/SiCodes.cs0000664000000000000000000003730013222430416016300 0ustar rootroot/* KeePass Password Safe - The Open-Source Password Manager Copyright (C) 2003-2018 Dominik Reichl This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ using System; using System.Collections.Generic; using System.Text; using System.Windows.Forms; using System.Globalization; using System.Diagnostics; namespace KeePass.Util.SendInputExt { internal sealed class SiCode { public readonly string Code; public readonly int VKey; public readonly bool? ExtKey = null; // Currently all have default ext state public readonly string XKeySym; public SiCode(string strCode, int iVKey, string strXKeySym) { if(string.IsNullOrEmpty(strCode)) { Debug.Assert(false); strCode = " "; } this.Code = strCode; this.VKey = iVKey; this.XKeySym = strXKeySym; } public SiCode(string strCode, Keys k, string strXKeySym) { if(string.IsNullOrEmpty(strCode)) { Debug.Assert(false); strCode = " "; } this.Code = strCode; this.VKey = (int)k; this.XKeySym = strXKeySym; } } internal enum SiDiacritic { None = 0, Grave, Acute, Circumflex, Tilde, Diaeresis, // Umlaut Ring, // Ring above Cedilla, Macron, Breve, Ogonek, DotAbove, Caron, AcuteDouble } internal static class SiCodes { private static List m_l = null; public static List KeyCodes { get { if(m_l != null) return m_l; List l = new List(); // XKeySym codes from 'keysymdef.h' l.Add(new SiCode("BACKSPACE", Keys.Back, "BackSpace")); l.Add(new SiCode("BKSP", Keys.Back, "BackSpace")); l.Add(new SiCode("BS", Keys.Back, "BackSpace")); l.Add(new SiCode("BREAK", Keys.Cancel, "Cancel")); l.Add(new SiCode("CAPSLOCK", Keys.CapsLock, "Caps_Lock")); l.Add(new SiCode("CLEAR", Keys.Clear, "Clear")); l.Add(new SiCode("DEL", Keys.Delete, "Delete")); l.Add(new SiCode("DELETE", Keys.Delete, "Delete")); l.Add(new SiCode("END", Keys.End, "End")); l.Add(new SiCode("ENTER", Keys.Enter, "Return")); l.Add(new SiCode("ESC", Keys.Escape, "Escape")); l.Add(new SiCode("ESCAPE", Keys.Escape, "Escape")); l.Add(new SiCode("HELP", Keys.Help, "Help")); l.Add(new SiCode("HOME", Keys.Home, "Home")); l.Add(new SiCode("INS", Keys.Insert, "Insert")); l.Add(new SiCode("INSERT", Keys.Insert, "Insert")); l.Add(new SiCode("NUMLOCK", Keys.NumLock, "Num_Lock")); l.Add(new SiCode("PGDN", Keys.PageDown, "Page_Down")); l.Add(new SiCode("PGUP", Keys.PageUp, "Page_Up")); l.Add(new SiCode("PRTSC", Keys.PrintScreen, "Print")); l.Add(new SiCode("SCROLLLOCK", Keys.Scroll, "Scroll_Lock")); l.Add(new SiCode("SPACE", Keys.Space, "space")); l.Add(new SiCode("TAB", Keys.Tab, "Tab")); l.Add(new SiCode("UP", Keys.Up, "Up")); l.Add(new SiCode("DOWN", Keys.Down, "Down")); l.Add(new SiCode("LEFT", Keys.Left, "Left")); l.Add(new SiCode("RIGHT", Keys.Right, "Right")); for(int i = 1; i <= 24; ++i) { string strF = "F" + i.ToString(NumberFormatInfo.InvariantInfo); l.Add(new SiCode(strF, (int)Keys.F1 + i - 1, strF)); Debug.Assert(Enum.IsDefined(typeof(Keys), (int)Keys.F1 + i - 1) && Enum.GetName(typeof(Keys), (int)Keys.F1 + i - 1) == strF); } l.Add(new SiCode("ADD", Keys.Add, "KP_Add")); l.Add(new SiCode("SUBTRACT", Keys.Subtract, "KP_Subtract")); l.Add(new SiCode("MULTIPLY", Keys.Multiply, "KP_Multiply")); l.Add(new SiCode("DIVIDE", Keys.Divide, "KP_Divide")); for(int i = 0; i < 10; ++i) { string strI = i.ToString(NumberFormatInfo.InvariantInfo); l.Add(new SiCode("NUMPAD" + strI, (int)Keys.NumPad0 + i, "KP_" + strI)); Debug.Assert(((int)Keys.NumPad9 - (int)Keys.NumPad0) == 9); } l.Add(new SiCode("WIN", Keys.LWin, "Super_L")); l.Add(new SiCode("LWIN", Keys.LWin, "Super_L")); l.Add(new SiCode("RWIN", Keys.RWin, "Super_R")); l.Add(new SiCode("APPS", Keys.Apps, "Menu")); #if DEBUG foreach(SiCode si in l) { // All key codes must be upper-case (for 'Get' method) Debug.Assert(si.Code == si.Code.ToUpperInvariant()); } #endif m_l = l; return l; } } private static Dictionary m_dictS = null; public static SiCode Get(string strCode) { if(strCode == null) { Debug.Assert(false); return null; } if(m_dictS == null) { Dictionary d = new Dictionary(); foreach(SiCode siCp in SiCodes.KeyCodes) { d[siCp.Code] = siCp; } Debug.Assert(d.Count == SiCodes.KeyCodes.Count); m_dictS = d; } string strUp = strCode.ToUpperInvariant(); SiCode si; if(m_dictS.TryGetValue(strUp, out si)) return si; return null; } public static SiCode Get(int iVKey, bool? bExtKey) { foreach(SiCode si in SiCodes.KeyCodes) { if(si.VKey == iVKey) { if(!si.ExtKey.HasValue || !bExtKey.HasValue) return si; if(si.ExtKey.Value == bExtKey.Value) return si; } } return null; } // Characters that should be converted to VKeys in special // situations (e.g. when a key modifier is active) private static Dictionary m_dChToVk = null; // Characters that should always be converted to VKeys // (independent of e.g. whether key modifier is active or not) private static Dictionary m_dChToVkAlways = null; private static void EnsureChToVkDicts() { if(m_dChToVk != null) return; Dictionary d = new Dictionary(); // The following characters should *always* be converted d['\u0008'] = (int)Keys.Back; d['\t'] = (int)Keys.Tab; d['\n'] = (int)Keys.LineFeed; d['\r'] = (int)Keys.Return; d['\u001B'] = (int)Keys.Escape; d[' '] = (int)Keys.Space; // For toggling checkboxes d['\u007F'] = (int)Keys.Delete; // Different values m_dChToVkAlways = new Dictionary(d); Debug.Assert((int)Keys.D0 == (int)'0'); for(char ch = '0'; ch <= '9'; ++ch) d[ch] = (int)ch - (int)'0' + (int)Keys.D0; Debug.Assert(d['9'] == (int)Keys.D9); Debug.Assert((int)Keys.A == (int)'A'); // Do not translate upper-case letters; // on Windows, sending VK_A results in 'a', and 'A' with Shift; // on some Linux systems, only Ctrl+'v' pastes, not Ctrl+'V': // https://sourceforge.net/p/keepass/discussion/329220/thread/bce61102/ // for(char ch = 'A'; ch <= 'Z'; ++ch) // d[ch] = (int)ch - (int)'A' + (int)Keys.A; for(char ch = 'a'; ch <= 'z'; ++ch) d[ch] = (int)ch - (int)'a' + (int)Keys.A; Debug.Assert(d['z'] == (int)Keys.Z); m_dChToVk = d; Debug.Assert(m_dChToVk.Count > m_dChToVkAlways.Count); // Independency } public static int CharToVKey(char ch, bool bLightConv) { EnsureChToVkDicts(); Dictionary d = (bLightConv ? m_dChToVkAlways : m_dChToVk); int iVKey; if(d.TryGetValue(ch, out iVKey)) return iVKey; return 0; } public static char VKeyToChar(int iVKey) { EnsureChToVkDicts(); foreach(KeyValuePair kvp in m_dChToVk) { if(kvp.Value == iVKey) return kvp.Key; } return char.MinValue; } private static Dictionary m_dChToXKeySym = null; public static string CharToXKeySym(char ch) { if(m_dChToXKeySym == null) { Dictionary d = new Dictionary(); // XDoTool sends some characters in the wrong case; // a workaround is to specify the keypress as an // XKeySym combination; // https://sourceforge.net/p/keepass/bugs/1532/ // https://github.com/jordansissel/xdotool/issues/41 AddDiacritic(d, 'A', '\u00C0', '\u00E0', SiDiacritic.Grave); AddDiacritic(d, 'A', '\u00C1', '\u00E1', SiDiacritic.Acute); AddDiacritic(d, 'A', '\u00C2', '\u00E2', SiDiacritic.Circumflex); AddDiacritic(d, 'A', '\u00C3', '\u00E3', SiDiacritic.Tilde); AddDiacritic(d, 'A', '\u00C4', '\u00E4', SiDiacritic.Diaeresis); AddDiacritic(d, 'A', '\u00C5', '\u00E5', SiDiacritic.Ring); AddDiacritic(d, 'C', '\u00C7', '\u00E7', SiDiacritic.Cedilla); AddDiacritic(d, 'E', '\u00C8', '\u00E8', SiDiacritic.Grave); AddDiacritic(d, 'E', '\u00C9', '\u00E9', SiDiacritic.Acute); AddDiacritic(d, 'E', '\u00CA', '\u00EA', SiDiacritic.Circumflex); AddDiacritic(d, 'E', '\u00CB', '\u00EB', SiDiacritic.Diaeresis); AddDiacritic(d, 'I', '\u00CC', '\u00EC', SiDiacritic.Grave); AddDiacritic(d, 'I', '\u00CD', '\u00ED', SiDiacritic.Acute); AddDiacritic(d, 'I', '\u00CE', '\u00EE', SiDiacritic.Circumflex); AddDiacritic(d, 'I', '\u00CF', '\u00EF', SiDiacritic.Diaeresis); AddDiacritic(d, 'N', '\u00D1', '\u00F1', SiDiacritic.Tilde); AddDiacritic(d, 'O', '\u00D2', '\u00F2', SiDiacritic.Grave); AddDiacritic(d, 'O', '\u00D3', '\u00F3', SiDiacritic.Acute); AddDiacritic(d, 'O', '\u00D4', '\u00F4', SiDiacritic.Circumflex); AddDiacritic(d, 'O', '\u00D5', '\u00F5', SiDiacritic.Tilde); AddDiacritic(d, 'O', '\u00D6', '\u00F6', SiDiacritic.Diaeresis); AddDiacritic(d, 'U', '\u00D9', '\u00F9', SiDiacritic.Grave); AddDiacritic(d, 'U', '\u00DA', '\u00FA', SiDiacritic.Acute); AddDiacritic(d, 'U', '\u00DB', '\u00FB', SiDiacritic.Circumflex); AddDiacritic(d, 'U', '\u00DC', '\u00FC', SiDiacritic.Diaeresis); AddDiacritic(d, 'Y', '\u00DD', '\u00FD', SiDiacritic.Acute); AddDiacritic(d, 'Y', '\u0178', '\u00FF', SiDiacritic.Diaeresis); AddDiacritic(d, 'A', '\u0100', '\u0101', SiDiacritic.Macron); AddDiacritic(d, 'A', '\u0102', '\u0103', SiDiacritic.Breve); AddDiacritic(d, 'A', '\u0104', '\u0105', SiDiacritic.Ogonek); AddDiacritic(d, 'C', '\u0106', '\u0107', SiDiacritic.Acute); AddDiacritic(d, 'C', '\u0108', '\u0109', SiDiacritic.Circumflex); AddDiacritic(d, 'C', '\u010A', '\u010B', SiDiacritic.DotAbove); AddDiacritic(d, 'C', '\u010C', '\u010D', SiDiacritic.Caron); AddDiacritic(d, 'D', '\u010E', '\u010F', SiDiacritic.Caron); AddDiacritic(d, 'E', '\u0112', '\u0113', SiDiacritic.Macron); AddDiacritic(d, 'E', '\u0114', '\u0115', SiDiacritic.Breve); AddDiacritic(d, 'E', '\u0116', '\u0117', SiDiacritic.DotAbove); AddDiacritic(d, 'E', '\u0118', '\u0119', SiDiacritic.Ogonek); AddDiacritic(d, 'E', '\u011A', '\u011B', SiDiacritic.Caron); AddDiacritic(d, 'G', '\u011C', '\u011D', SiDiacritic.Circumflex); AddDiacritic(d, 'G', '\u011E', '\u011F', SiDiacritic.Breve); AddDiacritic(d, 'G', '\u0120', '\u0121', SiDiacritic.DotAbove); AddDiacritic(d, 'G', '\u0122', '\u0123', SiDiacritic.Cedilla); AddDiacritic(d, 'H', '\u0124', '\u0125', SiDiacritic.Circumflex); AddDiacritic(d, 'I', '\u0128', '\u0129', SiDiacritic.Tilde); AddDiacritic(d, 'I', '\u012A', '\u012B', SiDiacritic.Macron); AddDiacritic(d, 'I', '\u012C', '\u012D', SiDiacritic.Breve); AddDiacritic(d, 'I', '\u012E', '\u012F', SiDiacritic.Ogonek); AddDiacritic(d, 'I', '\u0130', '\0', SiDiacritic.DotAbove); AddDiacritic(d, 'J', '\u0134', '\u0135', SiDiacritic.Circumflex); AddDiacritic(d, 'K', '\u0136', '\u0137', SiDiacritic.Cedilla); AddDiacritic(d, 'L', '\u0139', '\u013A', SiDiacritic.Acute); AddDiacritic(d, 'L', '\u013B', '\u013C', SiDiacritic.Cedilla); AddDiacritic(d, 'L', '\u013D', '\u013E', SiDiacritic.Caron); AddDiacritic(d, 'N', '\u0143', '\u0144', SiDiacritic.Acute); AddDiacritic(d, 'N', '\u0145', '\u0146', SiDiacritic.Cedilla); AddDiacritic(d, 'N', '\u0147', '\u0148', SiDiacritic.Caron); AddDiacritic(d, 'O', '\u014C', '\u014D', SiDiacritic.Macron); AddDiacritic(d, 'O', '\u014E', '\u014F', SiDiacritic.Breve); AddDiacritic(d, 'O', '\u0150', '\u0151', SiDiacritic.AcuteDouble); AddDiacritic(d, 'R', '\u0154', '\u0155', SiDiacritic.Acute); AddDiacritic(d, 'R', '\u0156', '\u0157', SiDiacritic.Cedilla); AddDiacritic(d, 'R', '\u0158', '\u0159', SiDiacritic.Caron); AddDiacritic(d, 'S', '\u015A', '\u015B', SiDiacritic.Acute); AddDiacritic(d, 'S', '\u015C', '\u015D', SiDiacritic.Circumflex); AddDiacritic(d, 'S', '\u015E', '\u015F', SiDiacritic.Cedilla); AddDiacritic(d, 'S', '\u0160', '\u0161', SiDiacritic.Caron); AddDiacritic(d, 'T', '\u0162', '\u0163', SiDiacritic.Cedilla); AddDiacritic(d, 'T', '\u0164', '\u0165', SiDiacritic.Caron); AddDiacritic(d, 'U', '\u0168', '\u0169', SiDiacritic.Tilde); AddDiacritic(d, 'U', '\u016A', '\u016B', SiDiacritic.Macron); AddDiacritic(d, 'U', '\u016C', '\u016D', SiDiacritic.Breve); AddDiacritic(d, 'U', '\u016E', '\u016F', SiDiacritic.Ring); AddDiacritic(d, 'U', '\u0170', '\u0171', SiDiacritic.AcuteDouble); AddDiacritic(d, 'U', '\u0172', '\u0173', SiDiacritic.Ogonek); AddDiacritic(d, 'W', '\u0174', '\u0175', SiDiacritic.Circumflex); AddDiacritic(d, 'Y', '\u0176', '\u0177', SiDiacritic.Circumflex); AddDiacritic(d, 'Z', '\u0179', '\u017A', SiDiacritic.Acute); AddDiacritic(d, 'Z', '\u017B', '\u017C', SiDiacritic.DotAbove); AddDiacritic(d, 'Z', '\u017D', '\u017E', SiDiacritic.Caron); m_dChToXKeySym = d; } string str; if(m_dChToXKeySym.TryGetValue(ch, out str)) return str; // Unicode is supported; codes are 'UHHHH' with 'HHHH' being // the Unicode value; see header of 'keysymdef.h' return ("U" + ((int)ch).ToString("X4", NumberFormatInfo.InvariantInfo)); } private static void AddDiacritic(Dictionary d, char chBase, char chDiaU, char chDiaL, SiDiacritic dc) { if(d == null) { Debug.Assert(false); return; } string strPrefix = string.Empty; switch(dc) { case SiDiacritic.Grave: strPrefix = "dead_grave "; break; case SiDiacritic.Acute: strPrefix = "dead_acute "; break; case SiDiacritic.Circumflex: strPrefix = "dead_circumflex "; break; case SiDiacritic.Tilde: strPrefix = "dead_tilde "; break; case SiDiacritic.Diaeresis: strPrefix = "dead_diaeresis "; break; case SiDiacritic.Ring: strPrefix = "dead_abovering "; break; case SiDiacritic.Cedilla: strPrefix = "dead_cedilla "; break; case SiDiacritic.Macron: strPrefix = "dead_macron "; break; case SiDiacritic.Breve: strPrefix = "dead_breve "; break; case SiDiacritic.Ogonek: strPrefix = "dead_ogonek "; break; case SiDiacritic.DotAbove: strPrefix = "dead_abovedot "; break; case SiDiacritic.Caron: strPrefix = "dead_caron "; break; case SiDiacritic.AcuteDouble: strPrefix = "dead_doubleacute "; break; default: Debug.Assert(dc == SiDiacritic.None); break; } Debug.Assert((strPrefix.Length == 0) || strPrefix.EndsWith(" ")); if(chDiaU != '\0') { Debug.Assert(!d.ContainsKey(chDiaU)); d[chDiaU] = (strPrefix + char.ToUpperInvariant(chBase)); } if(chDiaL != '\0') { Debug.Assert(!d.ContainsKey(chDiaL)); d[chDiaL] = (strPrefix + char.ToLowerInvariant(chBase)); } } } } KeePass/Util/SendInputExt/SiWindowInfo.cs0000664000000000000000000000305113222430416017322 0ustar rootroot/* KeePass Password Safe - The Open-Source Password Manager Copyright (C) 2003-2018 Dominik Reichl This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ using System; using System.Collections.Generic; using System.Text; namespace KeePass.Util.SendInputExt { internal enum SiSendMethod { Default = 0, KeyEvent, UnicodePacket // VK_PACKET via SendInput } internal sealed class SiWindowInfo { private readonly IntPtr m_hWnd; public IntPtr HWnd { get { return m_hWnd; } } private IntPtr m_hkl = IntPtr.Zero; public IntPtr KeyboardLayout { get { return m_hkl; } set { m_hkl = value; } } private SiSendMethod m_sm = SiSendMethod.Default; public SiSendMethod SendMethod { get { return m_sm; } set { m_sm = value; } } public SiWindowInfo(IntPtr hWnd) { m_hWnd = hWnd; } } } KeePass/Util/ShutdownBlocker.cs0000664000000000000000000000444613222430416015477 0ustar rootroot/* KeePass Password Safe - The Open-Source Password Manager Copyright (C) 2003-2018 Dominik Reichl This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ using System; using System.Collections.Generic; using System.Text; using System.Diagnostics; using KeePass.Native; using NativeLib = KeePassLib.Native.NativeLib; namespace KeePass.Util { public sealed class ShutdownBlocker : IDisposable { private static ShutdownBlocker g_sdbPrimary = null; #if DEBUG internal static ShutdownBlocker Instance { get { return g_sdbPrimary; } } #endif private readonly IntPtr m_hWnd; public ShutdownBlocker(IntPtr hWnd, string strReason) { Debug.Assert(hWnd != IntPtr.Zero); m_hWnd = hWnd; if(g_sdbPrimary != null) return; // We're not the first if(!WinUtil.IsAtLeastWindowsVista) return; if(NativeLib.IsUnix()) return; string str = strReason; if(string.IsNullOrEmpty(str)) { Debug.Assert(false); str = "..."; } try { if(NativeMethods.ShutdownBlockReasonCreate(hWnd, str)) g_sdbPrimary = this; else { Debug.Assert(false); } } catch(Exception) { Debug.Assert(false); } } ~ShutdownBlocker() { Dispose(false); } public void Dispose() { Dispose(true); GC.SuppressFinalize(this); } private void Dispose(bool bDisposing) { if(object.ReferenceEquals(this, g_sdbPrimary)) { try { if(!NativeMethods.ShutdownBlockReasonDestroy(m_hWnd)) { Debug.Assert(false); } } catch(Exception) { Debug.Assert(false); } g_sdbPrimary = null; } } } } KeePass/Util/UpdateCheckEx.cs0000664000000000000000000004247413222430416015042 0ustar rootroot/* KeePass Password Safe - The Open-Source Password Manager Copyright (C) 2003-2018 Dominik Reichl This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ using System; using System.Collections.Generic; using System.Diagnostics; using System.IO; using System.Security.Cryptography; using System.Text; using System.Threading; using System.Windows.Forms; using KeePass.App; using KeePass.Forms; using KeePass.Plugins; using KeePass.Resources; using KeePass.UI; using KeePassLib; using KeePassLib.Interfaces; using KeePassLib.Serialization; using KeePassLib.Utility; namespace KeePass.Util { public enum UpdateComponentStatus { Unknown = 0, UpToDate, NewVerAvailable, PreRelease, DownloadFailed } public sealed class UpdateComponentInfo { private readonly string m_strName; // Never null public string Name { get { return m_strName; } } private readonly ulong m_uVerInstalled; public ulong VerInstalled { get { return m_uVerInstalled; } } private ulong m_uVerAvailable = 0; public ulong VerAvailable { get { return m_uVerAvailable; } set { m_uVerAvailable = value; } } private UpdateComponentStatus m_status = UpdateComponentStatus.Unknown; public UpdateComponentStatus Status { get { return m_status; } set { m_status = value; } } private readonly string m_strUpdateUrl; // Never null public string UpdateUrl { get { return m_strUpdateUrl; } } private readonly string m_strCat; // Never null public string Category { get { return m_strCat; } } public UpdateComponentInfo(string strName, ulong uVerInstalled, string strUpdateUrl, string strCategory) { if(strName == null) throw new ArgumentNullException("strName"); if(strUpdateUrl == null) throw new ArgumentNullException("strUpdateUrl"); if(strCategory == null) throw new ArgumentNullException("strCategory"); m_strName = strName; m_uVerInstalled = uVerInstalled; m_strUpdateUrl = strUpdateUrl; m_strCat = strCategory; } } public static class UpdateCheckEx { private static Dictionary g_dFileSigKeys = new Dictionary(); private const string CompMain = PwDefs.ShortProductName; private sealed class UpdateCheckParams { public readonly bool ForceUI; public readonly Form Parent; // May be null public UpdateCheckParams(bool bForceUI, Form fOptParent) { this.ForceUI = bForceUI; this.Parent = fOptParent; } } public static void Run(bool bForceUI, Form fOptParent) { DateTime dtNow = DateTime.UtcNow, dtLast; string strLast = Program.Config.Application.LastUpdateCheck; if(!bForceUI && (strLast.Length > 0) && TimeUtil.TryDeserializeUtc( strLast, out dtLast)) { if(CompareDates(dtLast, dtNow) == 0) return; // Checked today already } Program.Config.Application.LastUpdateCheck = TimeUtil.SerializeUtc(dtNow); UpdateCheckParams p = new UpdateCheckParams(bForceUI, fOptParent); if(!bForceUI) // Async { // // Local, but thread will continue to run anyway // Thread th = new Thread(new ParameterizedThreadStart( // UpdateCheckEx.RunPriv)); // th.Start(p); try { ThreadPool.QueueUserWorkItem(new WaitCallback( UpdateCheckEx.RunPriv), p); } catch(Exception) { Debug.Assert(false); } } else RunPriv(p); } private static int CompareDates(DateTime a, DateTime b) { Debug.Assert(a.Kind == b.Kind); if(a.Year != b.Year) return ((a.Year < b.Year) ? -1 : 1); if(a.Month != b.Month) return ((a.Month < b.Month) ? -1 : 1); if(a.Day != b.Day) return ((a.Day < b.Day) ? -1 : 1); return 0; } private static void RunPriv(object o) { UpdateCheckParams p = (o as UpdateCheckParams); if(p == null) { Debug.Assert(false); return; } IStatusLogger sl = null; try { if(p.ForceUI) { Form fStatusDialog; sl = StatusUtil.CreateStatusDialog(p.Parent, out fStatusDialog, KPRes.UpdateCheck, KPRes.CheckingForUpd + "...", true, true); } List lInst = GetInstalledComponents(); List lUrls = GetUrls(lInst); Dictionary> dictAvail = DownloadInfoFiles(lUrls, sl); if(dictAvail == null) return; // User cancelled MergeInfo(lInst, dictAvail); bool bUpdAvail = false; foreach(UpdateComponentInfo uc in lInst) { if(uc.Status == UpdateComponentStatus.NewVerAvailable) { bUpdAvail = true; break; } } if(sl != null) { sl.EndLogging(); sl = null; } if(bUpdAvail || p.ForceUI) ShowUpdateDialogAsync(lInst, p.ForceUI); } catch(Exception) { Debug.Assert(false); } finally { try { if(sl != null) sl.EndLogging(); } catch(Exception) { Debug.Assert(false); } } } private static void ShowUpdateDialogAsync(List lInst, bool bModal) { try { MainForm mf = Program.MainForm; if((mf != null) && mf.InvokeRequired) mf.BeginInvoke(new UceShDlgDelegate(ShowUpdateDialogPriv), lInst, bModal); else ShowUpdateDialogPriv(lInst, bModal); } catch(Exception) { Debug.Assert(false); } } private delegate void UceShDlgDelegate(List lInst, bool bModal); private static void ShowUpdateDialogPriv(List lInst, bool bModal) { try { // Do not show the update dialog while auto-typing; // https://sourceforge.net/p/keepass/bugs/1265/ if(SendInputEx.IsSending) return; UpdateCheckForm dlg = new UpdateCheckForm(); dlg.InitEx(lInst, bModal); UIUtil.ShowDialogAndDestroy(dlg); } catch(Exception) { Debug.Assert(false); } } private sealed class UpdateDownloadInfo { public readonly string Url; // Never null public readonly object SyncObj = new object(); public bool Ready = false; public List ComponentInfo = null; public UpdateDownloadInfo(string strUrl) { if(strUrl == null) throw new ArgumentNullException("strUrl"); this.Url = strUrl; } } private static Dictionary> DownloadInfoFiles(List lUrls, IStatusLogger sl) { List lDl = new List(); foreach(string strUrl in lUrls) { if(string.IsNullOrEmpty(strUrl)) { Debug.Assert(false); continue; } UpdateDownloadInfo dl = new UpdateDownloadInfo(strUrl); lDl.Add(dl); ThreadPool.QueueUserWorkItem(new WaitCallback( UpdateCheckEx.DownloadInfoFile), dl); } while(true) { bool bReady = true; foreach(UpdateDownloadInfo dl in lDl) { lock(dl.SyncObj) { bReady &= dl.Ready; } } if(bReady) break; Thread.Sleep(40); if(sl != null) { if(!sl.ContinueWork()) return null; } } Dictionary> dict = new Dictionary>(); foreach(UpdateDownloadInfo dl in lDl) { dict[dl.Url.ToLower()] = dl.ComponentInfo; } return dict; } private static void DownloadInfoFile(object o) { UpdateDownloadInfo dl = (o as UpdateDownloadInfo); if(dl == null) { Debug.Assert(false); return; } dl.ComponentInfo = LoadInfoFile(dl.Url); lock(dl.SyncObj) { dl.Ready = true; } } private static List GetUrls(List l) { List lUrls = new List(); foreach(UpdateComponentInfo uc in l) { string strUrl = uc.UpdateUrl; if(string.IsNullOrEmpty(strUrl)) continue; bool bFound = false; for(int i = 0; i < lUrls.Count; ++i) { if(lUrls[i].Equals(strUrl, StrUtil.CaseIgnoreCmp)) { bFound = true; break; } } if(!bFound) lUrls.Add(strUrl); } return lUrls; } private static List LoadInfoFile(string strUrl) { try { IOConnectionInfo ioc = IOConnectionInfo.FromPath(strUrl.Trim()); Stream s = IOConnection.OpenRead(ioc); if(s == null) throw new InvalidOperationException(); MemoryStream ms = new MemoryStream(); MemUtil.CopyStream(s, ms); s.Close(); byte[] pb = ms.ToArray(); ms.Close(); if(ioc.Path.EndsWith(".gz", StrUtil.CaseIgnoreCmp)) { // Decompress in try-catch, because some web filters // incorrectly pre-decompress the returned data // https://sourceforge.net/projects/keepass/forums/forum/329221/topic/4915083 try { byte[] pbDec = MemUtil.Decompress(pb); List l = LoadInfoFilePriv(pbDec, ioc); if(l != null) return l; } catch(Exception) { } } return LoadInfoFilePriv(pb, ioc); } catch(Exception) { } return null; } private static List LoadInfoFilePriv(byte[] pbData, IOConnectionInfo iocSource) { if((pbData == null) || (pbData.Length == 0)) return null; int iOffset = 0; StrEncodingInfo sei = StrUtil.GetEncoding(StrEncodingType.Utf8); byte[] pbBom = sei.StartSignature; if((pbData.Length >= pbBom.Length) && MemUtil.ArraysEqual(pbBom, MemUtil.Mid(pbData, 0, pbBom.Length))) iOffset += pbBom.Length; string strData = sei.Encoding.GetString(pbData, iOffset, pbData.Length - iOffset); strData = StrUtil.NormalizeNewLines(strData, false); string[] vLines = strData.Split('\n'); string strSigKey; g_dFileSigKeys.TryGetValue(iocSource.Path.ToLowerInvariant(), out strSigKey); string strLdSig = null; StringBuilder sbToVerify = ((strSigKey != null) ? new StringBuilder() : null); List l = new List(); bool bHeader = true, bFooterFound = false; char chSep = ':'; // Modified by header for(int i = 0; i < vLines.Length; ++i) { string str = vLines[i].Trim(); if(str.Length == 0) continue; if(bHeader) { chSep = str[0]; bHeader = false; string[] vHdr = str.Split(chSep); if(vHdr.Length >= 2) strLdSig = vHdr[1]; } else if(str[0] == chSep) { bFooterFound = true; break; } else // Component info { if(sbToVerify != null) { sbToVerify.Append(str); sbToVerify.Append('\n'); } string[] vInfo = str.Split(chSep); if(vInfo.Length >= 2) { UpdateComponentInfo c = new UpdateComponentInfo( vInfo[0].Trim(), 0, iocSource.Path, string.Empty); c.VerAvailable = StrUtil.ParseVersion(vInfo[1]); AddComponent(l, c); } } } if(!bFooterFound) { Debug.Assert(false); return null; } if(sbToVerify != null) { if(!VerifySignature(sbToVerify.ToString(), strLdSig, strSigKey)) return null; } return l; } private static void AddComponent(List l, UpdateComponentInfo c) { if((l == null) || (c == null)) { Debug.Assert(false); return; } for(int i = l.Count - 1; i >= 0; --i) { if(l[i].Name.Equals(c.Name, StrUtil.CaseIgnoreCmp)) l.RemoveAt(i); } l.Add(c); } private static List GetInstalledComponents() { List l = new List(); foreach(PluginInfo pi in Program.MainForm.PluginManager) { Plugin p = pi.Interface; string strUrl = ((p != null) ? (p.UpdateUrl ?? string.Empty) : string.Empty); AddComponent(l, new UpdateComponentInfo(pi.Name.Trim(), StrUtil.ParseVersion(pi.FileVersion), strUrl.Trim(), KPRes.Plugins)); } // Add KeePass at the end to override any buggy plugin names AddComponent(l, new UpdateComponentInfo(CompMain, PwDefs.FileVersion64, PwDefs.VersionUrl, PwDefs.ShortProductName)); l.Sort(UpdateCheckEx.CompareComponents); return l; } private static int CompareComponents(UpdateComponentInfo a, UpdateComponentInfo b) { if(a.Name == b.Name) return 0; if(a.Name == CompMain) return -1; if(b.Name == CompMain) return 1; return a.Name.CompareTo(b.Name); } private static void MergeInfo(List lInst, Dictionary> dictAvail) { string strOvrId = PwDefs.VersionUrl.ToLower(); List lOvr; dictAvail.TryGetValue(strOvrId, out lOvr); foreach(UpdateComponentInfo uc in lInst) { string strUrlId = uc.UpdateUrl.ToLower(); List lAvail; dictAvail.TryGetValue(strUrlId, out lAvail); if(SetComponentAvail(uc, lOvr)) { } else if(SetComponentAvail(uc, lAvail)) { } else if((strUrlId.Length > 0) && (lAvail == null)) uc.Status = UpdateComponentStatus.DownloadFailed; else uc.Status = UpdateComponentStatus.Unknown; } } private static bool SetComponentAvail(UpdateComponentInfo uc, List lAvail) { if(uc == null) { Debug.Assert(false); return false; } if(lAvail == null) return false; // No assert if((uc.Name == CompMain) && WinUtil.IsAppX) { // The user's AppX may be old; do not claim it's up-to-date // uc.VerAvailable = uc.VerInstalled; // uc.Status = UpdateComponentStatus.UpToDate; uc.Status = UpdateComponentStatus.Unknown; return true; } foreach(UpdateComponentInfo ucAvail in lAvail) { if(ucAvail.Name.Equals(uc.Name, StrUtil.CaseIgnoreCmp)) { uc.VerAvailable = ucAvail.VerAvailable; if(uc.VerInstalled == uc.VerAvailable) uc.Status = UpdateComponentStatus.UpToDate; else if(uc.VerInstalled < uc.VerAvailable) uc.Status = UpdateComponentStatus.NewVerAvailable; else uc.Status = UpdateComponentStatus.PreRelease; return true; } } return false; } private static bool VerifySignature(string strContent, string strSig, string strKey) { if(string.IsNullOrEmpty(strSig)) { Debug.Assert(false); return false; } try { byte[] pbMsg = StrUtil.Utf8.GetBytes(strContent); byte[] pbSig = Convert.FromBase64String(strSig); using(SHA512Managed sha = new SHA512Managed()) { using(RSACryptoServiceProvider rsa = new RSACryptoServiceProvider()) { // Watching this code in the debugger may result in a // CryptographicException when disposing the object rsa.PersistKeyInCsp = false; // Default key rsa.FromXmlString(strKey); rsa.PersistKeyInCsp = false; // Loaded key if(!rsa.VerifyData(pbMsg, sha, pbSig)) { Debug.Assert(false); return false; } rsa.PersistKeyInCsp = false; } } } catch(Exception) { Debug.Assert(false); return false; } return true; } public static void SetFileSigKey(string strUrl, string strKey) { if(string.IsNullOrEmpty(strUrl)) { Debug.Assert(false); return; } if(string.IsNullOrEmpty(strKey)) { Debug.Assert(false); return; } g_dFileSigKeys[strUrl.ToLowerInvariant()] = strKey; } public static void EnsureConfigured(Form fParent) { SetFileSigKey(PwDefs.VersionUrl, AppDefs.Rsa4096PublicKeyXml); if(Program.Config.Application.Start.CheckForUpdateConfigured) return; // If the user has manually enabled the automatic update check // before, there's no need to ask him again if(!Program.Config.Application.Start.CheckForUpdate && !Program.IsDevelopmentSnapshot()) { string strHdr = KPRes.UpdateCheckInfo; string strSub = KPRes.UpdateCheckInfoRes + MessageService.NewParagraph + KPRes.UpdateCheckInfoPriv; VistaTaskDialog dlg = new VistaTaskDialog(); dlg.CommandLinks = true; dlg.Content = strHdr; dlg.MainInstruction = KPRes.UpdateCheckEnableQ; dlg.WindowTitle = PwDefs.ShortProductName; dlg.AddButton((int)DialogResult.Yes, KPRes.Enable + " (" + KPRes.Recommended + ")", null); dlg.AddButton((int)DialogResult.No, KPRes.Disable, null); dlg.SetIcon(VtdCustomIcon.Question); dlg.FooterText = strSub; dlg.SetFooterIcon(VtdIcon.Information); int iResult; if(dlg.ShowDialog(fParent)) iResult = dlg.Result; else { string strMain = strHdr + MessageService.NewParagraph + strSub; iResult = (MessageService.AskYesNo(strMain + MessageService.NewParagraph + KPRes.UpdateCheckEnableQ) ? (int)DialogResult.Yes : (int)DialogResult.No); } Program.Config.Application.Start.CheckForUpdate = ((iResult == (int)DialogResult.OK) || (iResult == (int)DialogResult.Yes)); } Program.Config.Application.Start.CheckForUpdateConfigured = true; } } } KeePass/Util/IpcUtilEx.cs0000664000000000000000000002106213222430416014221 0ustar rootroot/* KeePass Password Safe - The Open-Source Password Manager Copyright (C) 2003-2018 Dominik Reichl This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ using System; using System.Collections.Generic; using System.Text; using System.Diagnostics; using System.IO; using System.Xml.Serialization; using System.Threading; using KeePass.Forms; using KeePass.Native; using KeePass.UI; using KeePassLib; using KeePassLib.Cryptography; using KeePassLib.Serialization; using KeePassLib.Utility; namespace KeePass.Util { public sealed class IpcParamEx { public string Message { get; set; } public string Param0 { get; set; } public string Param1 { get; set; } public string Param2 { get; set; } public string Param3 { get; set; } public string Param4 { get; set; } public IpcParamEx() { this.Message = string.Empty; this.Param0 = string.Empty; this.Param1 = string.Empty; this.Param2 = string.Empty; this.Param3 = string.Empty; this.Param4 = string.Empty; } public IpcParamEx(string strMessage, string strParam0, string strParam1, string strParam2, string strParam3, string strParam4) { this.Message = (strMessage ?? string.Empty); this.Param0 = (strParam0 ?? string.Empty); this.Param1 = (strParam1 ?? string.Empty); this.Param2 = (strParam2 ?? string.Empty); this.Param3 = (strParam3 ?? string.Empty); this.Param4 = (strParam4 ?? string.Empty); } } public sealed class IpcEventArgs : EventArgs { private readonly string m_strName; public string Name { get { return m_strName; } } private readonly CommandLineArgs m_args; public CommandLineArgs Args { get { return m_args; } } public IpcEventArgs(string strName, CommandLineArgs clArgs) { if(strName == null) throw new ArgumentNullException("strName"); m_strName = strName; m_args = clArgs; } } public static class IpcUtilEx { internal const string IpcMsgFilePreID = "KeePassIPC-"; internal const string IpcMsgFilePostID = "-Msgs.tmp"; public const string CmdOpenDatabase = "OpenDatabase"; public const string CmdOpenEntryUrl = "OpenEntryUrl"; public const string CmdIpcEvent = "IpcEvent"; /// /// Event that is raised e.g. when running KeePass with the /// AppDefs.CommandLineOptions.IpcEvent command line parameter. /// /// public static event EventHandler IpcEvent; public static void SendGlobalMessage(IpcParamEx ipcMsg) { if(ipcMsg == null) throw new ArgumentNullException("ipcMsg"); int nId = (int)(MemUtil.BytesToUInt32(CryptoRandom.Instance.GetRandomBytes( 4)) & 0x7FFFFFFF); if(WriteIpcInfoFile(nId, ipcMsg) == false) return; try { // NativeMethods.SendMessage((IntPtr)NativeMethods.HWND_BROADCAST, // Program.ApplicationMessage, (IntPtr)Program.AppMessage.IpcByFile, // (IntPtr)nId); // IntPtr pResult = new IntPtr(0); // NativeMethods.SendMessageTimeout((IntPtr)NativeMethods.HWND_BROADCAST, // Program.ApplicationMessage, (IntPtr)Program.AppMessage.IpcByFile, // (IntPtr)nId, NativeMethods.SMTO_ABORTIFHUNG, 5000, ref pResult); IpcBroadcast.Send(Program.AppMessage.IpcByFile, nId, true); } catch(Exception) { Debug.Assert(false); } string strIpcFile = GetIpcFilePath(nId); for(int r = 0; r < 50; ++r) { try { if(!File.Exists(strIpcFile)) break; } catch(Exception) { } Thread.Sleep(20); } RemoveIpcInfoFile(nId); } private static string GetIpcFilePath(int nId) { try { string str = UrlUtil.GetTempPath(); str = UrlUtil.EnsureTerminatingSeparator(str, false); return (str + IpcMsgFilePreID + nId.ToString() + ".tmp"); } catch(Exception) { Debug.Assert(false); } return null; } private static bool WriteIpcInfoFile(int nId, IpcParamEx ipcMsg) { string strPath = GetIpcFilePath(nId); if(string.IsNullOrEmpty(strPath)) return false; try { XmlSerializer xml = new XmlSerializer(typeof(IpcParamEx)); FileStream fs = new FileStream(strPath, FileMode.Create, FileAccess.Write, FileShare.None); try { xml.Serialize(fs, ipcMsg); } catch(Exception) { Debug.Assert(false); } fs.Close(); return true; } catch(Exception) { Debug.Assert(false); } return false; } private static void RemoveIpcInfoFile(int nId) { string strPath = GetIpcFilePath(nId); if(string.IsNullOrEmpty(strPath)) return; try { if(File.Exists(strPath)) File.Delete(strPath); } catch(Exception) { Debug.Assert(false); } } private static IpcParamEx LoadIpcInfoFile(int nId) { string strPath = GetIpcFilePath(nId); if(string.IsNullOrEmpty(strPath)) return null; string strMtxName = (IpcMsgFilePreID + nId.ToString()); // Mutex m = Program.TrySingleInstanceLock(strMtxName, true); bool bMutex = GlobalMutexPool.CreateMutex(strMtxName, true); // if(m == null) return null; if(!bMutex) return null; IpcParamEx ipcParam = null; try { XmlSerializer xml = new XmlSerializer(typeof(IpcParamEx)); FileStream fs = new FileStream(strPath, FileMode.Open, FileAccess.Read, FileShare.Read); try { ipcParam = (IpcParamEx)xml.Deserialize(fs); } catch(Exception) { Debug.Assert(false); } fs.Close(); } catch(Exception) { } RemoveIpcInfoFile(nId); // Program.DestroyMutex(m, true); if(!GlobalMutexPool.ReleaseMutex(strMtxName)) { Debug.Assert(false); } return ipcParam; } public static void ProcessGlobalMessage(int nId, MainForm mf) { if(mf == null) throw new ArgumentNullException("mf"); IpcParamEx ipcMsg = LoadIpcInfoFile(nId); if(ipcMsg == null) return; if(ipcMsg.Message == CmdOpenDatabase) { mf.UIBlockAutoUnlock(true); mf.EnsureVisibleForegroundWindow(true, true); mf.UIBlockAutoUnlock(false); // Don't try to open another database while a dialog // is displayed (3489098) if(GlobalWindowManager.WindowCount > 0) return; string[] vArgs = CommandLineArgs.SafeDeserialize(ipcMsg.Param0); if(vArgs == null) { Debug.Assert(false); return; } CommandLineArgs args = new CommandLineArgs(vArgs); Program.CommandLineArgs.CopyFrom(args); mf.OpenDatabase(mf.IocFromCommandLine(), KeyUtil.KeyFromCommandLine( Program.CommandLineArgs), true); } else if(ipcMsg.Message == CmdOpenEntryUrl) OpenEntryUrl(ipcMsg, mf); else if(ipcMsg.Message == CmdIpcEvent) { try { if(IpcUtilEx.IpcEvent == null) return; string strName = ipcMsg.Param0; if(string.IsNullOrEmpty(strName)) { Debug.Assert(false); return; } string[] vArgs = CommandLineArgs.SafeDeserialize(ipcMsg.Param1); if(vArgs == null) { Debug.Assert(false); return; } CommandLineArgs clArgs = new CommandLineArgs(vArgs); IpcEventArgs e = new IpcEventArgs(strName, clArgs); IpcUtilEx.IpcEvent(null, e); } catch(Exception) { Debug.Assert(false); } } else { Debug.Assert(false); } } private static void OpenEntryUrl(IpcParamEx ip, MainForm mf) { string strUuid = ip.Param0; if(string.IsNullOrEmpty(strUuid)) return; // No assert (user data) byte[] pbUuid = MemUtil.HexStringToByteArray(strUuid); if((pbUuid == null) || (pbUuid.Length != PwUuid.UuidSize)) return; PwUuid pwUuid = new PwUuid(pbUuid); List lDocs = mf.DocumentManager.GetDocuments(int.MinValue); foreach(PwDocument pwDoc in lDocs) { if(pwDoc == null) { Debug.Assert(false); continue; } PwDatabase pdb = pwDoc.Database; if((pdb == null) || !pdb.IsOpen) continue; PwEntry pe = pdb.RootGroup.FindEntry(pwUuid, true); if(pe == null) continue; mf.PerformDefaultUrlAction(new PwEntry[]{ pe }, true); break; } } } } KeePass/Util/BinaryDataUtil.cs0000664000000000000000000002564413222430416015241 0ustar rootroot/* KeePass Password Safe - The Open-Source Password Manager Copyright (C) 2003-2018 Dominik Reichl This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ using System; using System.Collections.Generic; using System.Text; using System.IO; using System.Windows.Forms; using System.Threading; using System.Diagnostics; using KeePass.Forms; using KeePass.Native; using KeePass.Resources; using KeePass.UI; using KeePassLib; using KeePassLib.Collections; using KeePassLib.Cryptography; using KeePassLib.Interfaces; using KeePassLib.Security; using KeePassLib.Utility; namespace KeePass.Util { public enum BinaryDataHandler { Default = 0, InternalViewer = 1, InternalEditor = 2, ExternalApp = 3 } public sealed class BinaryDataOpenOptions : IDeepCloneable { private BinaryDataHandler m_h = BinaryDataHandler.Default; public BinaryDataHandler Handler { get { return m_h; } set { m_h = value; } } private bool m_bReadOnly = false; public bool ReadOnly { get { return m_bReadOnly; } set { m_bReadOnly = value; } } public BinaryDataOpenOptions CloneDeep() { BinaryDataOpenOptions opt = new BinaryDataOpenOptions(); opt.m_h = m_h; opt.m_bReadOnly = m_bReadOnly; return opt; } } public sealed class EntryBinaryDataContext { private PwEntry m_pe = null; public PwEntry Entry { get { return m_pe; } set { m_pe = value; } } private string m_strDataName = null; public string Name { get { return m_strDataName; } set { m_strDataName = value; } } private BinaryDataOpenOptions m_oo = null; public BinaryDataOpenOptions Options { get { return m_oo; } set { m_oo = value; } } } public static class BinaryDataUtil { public static ProtectedBinary Open(string strName, ProtectedBinary pb, BinaryDataOpenOptions opt) { if(string.IsNullOrEmpty(strName)) { Debug.Assert(false); return null; } if(pb == null) { Debug.Assert(false); return null; } if(opt == null) opt = new BinaryDataOpenOptions(); byte[] pbData = pb.ReadData(); if(pbData == null) { Debug.Assert(false); return null; } BinaryDataHandler h = opt.Handler; if(h == BinaryDataHandler.Default) h = ChooseHandler(strName, pbData, opt); byte[] pbModData = null; if(h == BinaryDataHandler.InternalViewer) { DataViewerForm dvf = new DataViewerForm(); dvf.InitEx(strName, pbData); UIUtil.ShowDialogAndDestroy(dvf); } else if(h == BinaryDataHandler.InternalEditor) { DataEditorForm def = new DataEditorForm(); def.InitEx(strName, pbData); def.ShowDialog(); if(def.EditedBinaryData != null) pbModData = def.EditedBinaryData; UIUtil.DestroyForm(def); } else if(h == BinaryDataHandler.ExternalApp) pbModData = OpenExternal(strName, pbData, opt); else { Debug.Assert(false); } if((pbModData != null) && !MemUtil.ArraysEqual(pbData, pbModData) && !opt.ReadOnly) { if(FileDialogsEx.CheckAttachmentSize(pbModData.LongLength, KPRes.AttachFailed + MessageService.NewParagraph + strName)) return new ProtectedBinary(pb.IsProtected, pbModData); } return null; } private static BinaryDataHandler ChooseHandler(string strName, byte[] pbData, BinaryDataOpenOptions opt) { BinaryDataClass bdc = BinaryDataClassifier.Classify(strName, pbData); if(DataEditorForm.SupportsDataType(bdc) && !opt.ReadOnly) return BinaryDataHandler.InternalEditor; if(DataViewerForm.SupportsDataType(bdc)) return BinaryDataHandler.InternalViewer; return BinaryDataHandler.ExternalApp; } 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()); } 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; } private static bool AskForRetry(string strObj, string strText) { string strContent = strObj + MessageService.NewParagraph + strText; int i = VistaTaskDialog.ShowMessageBoxEx(strContent, null, PwDefs.ShortProductName, VtdIcon.Warning, null, KPRes.RetryCmd, (int)DialogResult.Retry, KPRes.Cancel, (int)DialogResult.Cancel); if(i < 0) i = (int)MessageService.Ask(strContent, PwDefs.ShortProductName, MessageBoxButtons.RetryCancel); return ((i == (int)DialogResult.Retry) || (i == (int)DialogResult.Yes) || (i == (int)DialogResult.OK)); } private static void ShellOpenFn(object o) { if(o == null) { Debug.Assert(false); return; } try { ProcessStartInfo psi = (o as ProcessStartInfo); if(psi == null) { Debug.Assert(false); return; } // Let the main thread finish showing the message box Thread.Sleep(200); Process.Start(psi); } catch(Exception ex) { try { MessageService.ShowWarning(ex.Message); } catch(Exception) { Debug.Assert(false); } } } internal static void BuildOpenWithMenu(DynamicMenu dm, string strItem, ProtectedBinary pb, bool bReadOnly) { if(dm == null) { Debug.Assert(false); return; } dm.Clear(); if(string.IsNullOrEmpty(strItem)) { Debug.Assert(false); return; } if(pb == null) { Debug.Assert(false); return; } byte[] pbData = pb.ReadData(); if(pbData == null) { Debug.Assert(false); return; } BinaryDataClass bdc = BinaryDataClassifier.Classify(strItem, pbData); BinaryDataOpenOptions oo = new BinaryDataOpenOptions(); oo.Handler = BinaryDataHandler.InternalViewer; dm.AddItem(KPRes.InternalViewer, Properties.Resources.B16x16_View_Detailed, oo); oo = new BinaryDataOpenOptions(); oo.Handler = BinaryDataHandler.InternalEditor; ToolStripMenuItem tsmiIntEditor = dm.AddItem(KPRes.InternalEditor, Properties.Resources.B16x16_View_Detailed, oo); oo = new BinaryDataOpenOptions(); oo.Handler = BinaryDataHandler.ExternalApp; ToolStripMenuItem tsmiExt = dm.AddItem(KPRes.ExternalApp, Properties.Resources.B16x16_Make_KDevelop, oo); if(!DataEditorForm.SupportsDataType(bdc) || bReadOnly) tsmiIntEditor.Enabled = false; if(bReadOnly) tsmiExt.Enabled = false; } } } KeePass/Util/HotKeyManager.cs0000664000000000000000000002046713222430416015061 0ustar rootroot/* KeePass Password Safe - The Open-Source Password Manager Copyright (C) 2003-2018 Dominik Reichl This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ using System; using System.Collections.Generic; using System.Text; using System.Runtime.InteropServices; using System.Windows.Forms; using System.Diagnostics; using KeePass.App; using KeePass.Forms; using KeePass.Native; using KeePass.Resources; using KeePass.UI; using KeePassLib; using KeePassLib.Utility; using NativeLib = KeePassLib.Native.NativeLib; namespace KeePass.Util { public static class HotKeyManager { private static Form m_fRecvWnd = null; private static Dictionary m_vRegKeys = new Dictionary(); // private static NativeMethods.BindKeyHandler m_hOnHotKey = // new NativeMethods.BindKeyHandler(HotKeyManager.OnHotKey); // public static Form ReceiverWindow // { // get { return m_fRecvWnd; } // set { m_fRecvWnd = value; } // } public static bool Initialize(Form fRecvWnd) { m_fRecvWnd = fRecvWnd; // if(NativeLib.IsUnix()) // { // try { NativeMethods.tomboy_keybinder_init(); } // catch(Exception) { Debug.Assert(false); return false; } // } return true; } public static bool RegisterHotKey(int nId, Keys kKey) { UnregisterHotKey(nId); uint uMod = 0; if((kKey & Keys.Shift) != Keys.None) uMod |= NativeMethods.MOD_SHIFT; if((kKey & Keys.Alt) != Keys.None) uMod |= NativeMethods.MOD_ALT; if((kKey & Keys.Control) != Keys.None) uMod |= NativeMethods.MOD_CONTROL; uint vkCode = (uint)(kKey & Keys.KeyCode); if(vkCode == (uint)Keys.None) return false; // Don't register mod keys only try { if(!NativeLib.IsUnix()) { if(NativeMethods.RegisterHotKey(m_fRecvWnd.Handle, nId, uMod, vkCode)) { m_vRegKeys[nId] = kKey; return true; } } else // Unix { // NativeMethods.tomboy_keybinder_bind(EggAccKeysToString(kKey), // m_hOnHotKey); // m_vRegKeys[nId] = kKey; // return true; } } catch(Exception) { Debug.Assert(false); } return false; } public static bool UnregisterHotKey(int nId) { if(m_vRegKeys.ContainsKey(nId)) { // Keys k = m_vRegKeys[nId]; m_vRegKeys.Remove(nId); try { bool bResult; if(!NativeLib.IsUnix()) bResult = NativeMethods.UnregisterHotKey(m_fRecvWnd.Handle, nId); else // Unix { // NativeMethods.tomboy_keybinder_unbind(EggAccKeysToString(k), // m_hOnHotKey); // bResult = true; bResult = false; } // Debug.Assert(bResult); return bResult; } catch(Exception) { Debug.Assert(false); } } return false; } public static void UnregisterAll() { List vIDs = new List(m_vRegKeys.Keys); foreach(int nID in vIDs) UnregisterHotKey(nID); Debug.Assert(m_vRegKeys.Count == 0); } public static bool IsHotKeyRegistered(Keys kKey, bool bGlobal) { if(m_vRegKeys.ContainsValue(kKey)) return true; if(!bGlobal) return false; int nID = AppDefs.GlobalHotKeyId.TempRegTest; if(!RegisterHotKey(nID, kKey)) return true; UnregisterHotKey(nID); return false; } /* private static void OnHotKey(string strKey, IntPtr lpUserData) { if(string.IsNullOrEmpty(strKey)) return; if(strKey.IndexOf(@"", StrUtil.CaseIgnoreCmp) >= 0) return; if(m_fRecvWnd != null) { MainForm mf = (m_fRecvWnd as MainForm); if(mf == null) { Debug.Assert(false); return; } Keys k = EggAccStringToKeys(strKey); foreach(KeyValuePair kvp in m_vRegKeys) { if(kvp.Value == k) mf.HandleHotKey(kvp.Key); } } else { Debug.Assert(false); } } private static Keys EggAccStringToKeys(string strKey) { if(string.IsNullOrEmpty(strKey)) return Keys.None; Keys k = Keys.None; if(strKey.IndexOf(@"", StrUtil.CaseIgnoreCmp) >= 0) k |= Keys.Alt; if((strKey.IndexOf(@"", StrUtil.CaseIgnoreCmp) >= 0) || (strKey.IndexOf(@"", StrUtil.CaseIgnoreCmp) >= 0) || (strKey.IndexOf(@"", StrUtil.CaseIgnoreCmp) >= 0)) k |= Keys.Control; if((strKey.IndexOf(@"", StrUtil.CaseIgnoreCmp) >= 0) || (strKey.IndexOf(@"", StrUtil.CaseIgnoreCmp) >= 0)) k |= Keys.Shift; string strKeyCode = strKey; while(strKeyCode.IndexOf('<') >= 0) { int nStart = strKeyCode.IndexOf('<'); int nEnd = strKeyCode.IndexOf('>'); if((nStart < 0) || (nEnd < 0) || (nEnd <= nStart)) { Debug.Assert(false); break; } strKeyCode = strKeyCode.Remove(nStart, nEnd - nStart + 1); } strKeyCode = strKeyCode.Trim(); try { k |= (Keys)Enum.Parse(typeof(Keys), strKeyCode, true); } catch(Exception) { Debug.Assert(false); } return k; } private static string EggAccKeysToString(Keys k) { StringBuilder sb = new StringBuilder(); if((k & Keys.Shift) != Keys.None) sb.Append(@""); if((k & Keys.Control) != Keys.None) sb.Append(@""); if((k & Keys.Alt) != Keys.None) sb.Append(@""); sb.Append((k & Keys.KeyCode).ToString()); return sb.ToString(); } */ internal static void CheckCtrlAltA(Form fParent) { try { if(!Program.Config.Integration.CheckHotKeys) return; if(NativeLib.IsUnix()) return; // Check for a conflict only in the very specific case of // Ctrl+Alt+A; in all other cases we assume that the user // is aware of a possible conflict and intentionally wants // to override any system key combination if(Program.Config.Integration.HotKeyGlobalAutoType != (ulong)(Keys.Control | Keys.Alt | Keys.A)) return; // Check for a conflict only on Polish systems; other // languages typically don't use Ctrl+Alt+A frequently // and a conflict warning would just be confusing for // most users IntPtr hKL = NativeMethods.GetKeyboardLayout(0); ushort uLangID = (ushort)(hKL.ToInt64() & 0xFFFFL); ushort uPriLangID = NativeMethods.GetPrimaryLangID(uLangID); if(uPriLangID != NativeMethods.LANG_POLISH) return; int vk = (int)Keys.A; // We actually check for RAlt (which maps to Ctrl+Alt) // instead of LCtrl+LAlt byte[] pbState = new byte[256]; pbState[NativeMethods.VK_CONTROL] = 0x80; pbState[NativeMethods.VK_LCONTROL] = 0x80; pbState[NativeMethods.VK_MENU] = 0x80; pbState[NativeMethods.VK_RMENU] = 0x80; pbState[NativeMethods.VK_NUMLOCK] = 0x01; // Toggled // pbState[vk] = 0x80; string strUni = NativeMethods.ToUnicode3(vk, pbState, IntPtr.Zero); if(string.IsNullOrEmpty(strUni)) return; if(strUni.EndsWith("a") || strUni.EndsWith("A")) return; if(char.IsControl(strUni, 0)) { Debug.Assert(false); strUni = "?"; } string str = KPRes.CtrlAltAConflict.Replace(@"{PARAM}", strUni) + MessageService.NewParagraph + KPRes.CtrlAltAConflictHint; VistaTaskDialog dlg = new VistaTaskDialog(); dlg.AddButton((int)DialogResult.Cancel, KPRes.Ok, null); dlg.CommandLinks = false; dlg.Content = str; dlg.DefaultButtonID = (int)DialogResult.Cancel; dlg.MainInstruction = KPRes.KeyboardKeyCtrl + "+" + KPRes.KeyboardKeyAlt + "+A - " + KPRes.Warning; dlg.SetIcon(VtdIcon.Warning); dlg.VerificationText = KPRes.DialogNoShowAgain; dlg.WindowTitle = PwDefs.ShortProductName; if(dlg.ShowDialog(fParent)) { if(dlg.ResultVerificationChecked) Program.Config.Integration.CheckHotKeys = false; } else MessageService.ShowWarning(str); } catch(Exception) { Debug.Assert(false); } } } } KeePass/Util/EntryTemplates.cs0000664000000000000000000001510213222430416015331 0ustar rootroot/* KeePass Password Safe - The Open-Source Password Manager Copyright (C) 2003-2018 Dominik Reichl This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ using System; using System.Collections.Generic; using System.Text; using System.Drawing; using System.Windows.Forms; using System.Diagnostics; using KeePass.Forms; using KeePass.Resources; using KeePass.UI; using KeePassLib; using KeePassLib.Collections; using KeePassLib.Utility; namespace KeePass.Util { public sealed class TemplateEntryEventArgs : EventArgs { private PwEntry m_peTemplate; public PwEntry TemplateEntry { get { return m_peTemplate; } } private PwEntry m_pe; public PwEntry Entry { get { return m_pe; } } public TemplateEntryEventArgs(PwEntry peTemplate, PwEntry pe) { m_peTemplate = peTemplate; m_pe = pe; } } public static class EntryTemplates { private static ToolStripSplitButton m_btnItemsHost = null; private static List m_vToolStripItems = new List(); public static event EventHandler EntryCreating; public static event EventHandler EntryCreated; public static void Init(ToolStripSplitButton btnHost) { if(btnHost == null) throw new ArgumentNullException("btnHost"); m_btnItemsHost = btnHost; m_btnItemsHost.DropDownOpening += OnMenuOpening; } public static void Release() { if(m_btnItemsHost != null) { Clear(); m_btnItemsHost.DropDownOpening -= OnMenuOpening; m_btnItemsHost = null; } } private static void AddSeparator() { ToolStripSeparator tsSep = new ToolStripSeparator(); m_btnItemsHost.DropDownItems.Add(tsSep); m_vToolStripItems.Add(tsSep); } private static void AddItem(PwEntry pe) { if(pe == null) { Debug.Assert(false); return; } string strText = StrUtil.EncodeMenuText(pe.Strings.ReadSafe( PwDefs.TitleField)); ToolStripMenuItem tsmi = new ToolStripMenuItem(strText); tsmi.Tag = pe; tsmi.Click += OnMenuExecute; Image img = null; PwDatabase pd = Program.MainForm.DocumentManager.SafeFindContainerOf(pe); if(pd != null) { if(!pe.CustomIconUuid.Equals(PwUuid.Zero)) img = DpiUtil.GetIcon(pd, pe.CustomIconUuid); if(img == null) { try { img = Program.MainForm.ClientIcons.Images[(int)pe.IconId]; } catch(Exception) { Debug.Assert(false); } } } if(img == null) img = Properties.Resources.B16x16_KGPG_Key1; tsmi.Image = img; m_btnItemsHost.DropDownItems.Add(tsmi); m_vToolStripItems.Add(tsmi); } private static void AddEmpty() { AddSeparator(); ToolStripMenuItem tsmi = new ToolStripMenuItem("(" + KPRes.TemplatesNotFound + ")"); tsmi.Click += OnMenuExecute; // Required for clean releasing tsmi.Enabled = false; m_btnItemsHost.DropDownItems.Add(tsmi); m_vToolStripItems.Add(tsmi); } private static void Update() { Clear(); if(!UpdateEx()) AddEmpty(); } private static bool UpdateEx() { PwDatabase pd = Program.MainForm.ActiveDatabase; if(pd == null) { Debug.Assert(false); return false; } if(pd.IsOpen == false) { Debug.Assert(false); return false; } if(pd.EntryTemplatesGroup.Equals(PwUuid.Zero)) return false; PwGroup pg = pd.RootGroup.FindGroup(pd.EntryTemplatesGroup, true); if(pg == null) { Debug.Assert(false); return false; } if(pg.Entries.UCount == 0) return false; AddSeparator(); for(uint u = 0; u < Math.Min(pg.Entries.UCount, 30); ++u) { try { AddItem(pg.Entries.GetAt(u)); } catch(Exception) { Debug.Assert(false); } } return true; } private static void Clear() { int nCount = m_vToolStripItems.Count; for(int i = 0; i < nCount; ++i) { int j = nCount - i - 1; ToolStripItem tsmi = m_vToolStripItems[j]; if(tsmi is ToolStripMenuItem) tsmi.Click -= OnMenuExecute; m_btnItemsHost.DropDownItems.Remove(tsmi); } m_vToolStripItems.Clear(); } private static void OnMenuExecute(object sender, EventArgs e) { ToolStripMenuItem tsmi = (sender as ToolStripMenuItem); if(tsmi == null) { Debug.Assert(false); return; } CreateEntry(tsmi.Tag as PwEntry); } private static void OnMenuOpening(object sender, EventArgs e) { Update(); } private static void CreateEntry(PwEntry peTemplate) { if(peTemplate == null) { Debug.Assert(false); return; } PwDatabase pd = Program.MainForm.ActiveDatabase; if(pd == null) { Debug.Assert(false); return; } if(pd.IsOpen == false) { Debug.Assert(false); return; } PwGroup pgContainer = Program.MainForm.GetSelectedGroup(); if(pgContainer == null) pgContainer = pd.RootGroup; PwEntry pe = peTemplate.Duplicate(); pe.History.Clear(); if(EntryTemplates.EntryCreating != null) EntryTemplates.EntryCreating(null, new TemplateEntryEventArgs( peTemplate.CloneDeep(), pe)); PwEntryForm pef = new PwEntryForm(); pef.InitEx(pe, PwEditMode.AddNewEntry, pd, Program.MainForm.ClientIcons, false, true); if(UIUtil.ShowDialogAndDestroy(pef) == DialogResult.OK) { pgContainer.AddEntry(pe, true, true); MainForm mf = Program.MainForm; if(mf != null) { mf.UpdateUI(false, null, pd.UINeedsIconUpdate, null, true, null, true); PwObjectList vSelect = new PwObjectList(); vSelect.Add(pe); mf.SelectEntries(vSelect, true, true); mf.EnsureVisibleEntry(pe.Uuid); mf.UpdateUI(false, null, false, null, false, null, false); } else { Debug.Assert(false); } if(EntryTemplates.EntryCreated != null) EntryTemplates.EntryCreated(null, new TemplateEntryEventArgs( peTemplate.CloneDeep(), pe)); } else Program.MainForm.UpdateUI(false, null, pd.UINeedsIconUpdate, null, pd.UINeedsIconUpdate, null, false); } } } KeePass/Util/KeyUtil.cs0000664000000000000000000001440613222430416013745 0ustar rootroot/* KeePass Password Safe - The Open-Source Password Manager Copyright (C) 2003-2018 Dominik Reichl This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ using System; using System.Collections.Generic; using System.Text; using System.Windows.Forms; using System.Diagnostics; using KeePass.App; using KeePass.Resources; using KeePass.UI; using KeePassLib; using KeePassLib.Keys; using KeePassLib.Resources; using KeePassLib.Utility; using KeePassLib.Serialization; using KeePass.Forms; namespace KeePass.Util { public static class KeyUtil { 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; } MemUtil.ZeroByteArray(pbProvKey); } 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; } private static void ClearKeyOptions(CommandLineArgs args, bool bOnlyIfOptionEnabled) { if(args == null) { Debug.Assert(false); return; } if(bOnlyIfOptionEnabled && !Program.Config.Security.ClearKeyCommandLineParams) return; args.Remove(AppDefs.CommandLineOptions.Password); args.Remove(AppDefs.CommandLineOptions.PasswordEncrypted); args.Remove(AppDefs.CommandLineOptions.PasswordStdIn); args.Remove(AppDefs.CommandLineOptions.KeyFile); args.Remove(AppDefs.CommandLineOptions.PreSelect); args.Remove(AppDefs.CommandLineOptions.UserAccount); } private static bool m_bReadPwStdIn = false; private static string m_strReadPwStdIn = null; /// /// Read a password from StdIn. The password is read only once /// and then cached. /// internal static KcpPassword ReadPasswordStdIn(bool bFailWithUI) { string strPw = null; if(m_bReadPwStdIn) strPw = m_strReadPwStdIn; else { try { strPw = Console.ReadLine(); } catch(Exception exCon) { if(bFailWithUI) MessageService.ShowWarning(exCon); } } if(strPw == null) { m_strReadPwStdIn = null; m_bReadPwStdIn = true; return null; } strPw = strPw.Trim(); m_strReadPwStdIn = strPw; m_bReadPwStdIn = true; return new KcpPassword(strPw); } internal static string[] MakeCtxIndependent(string[] vCmdLineArgs) { if(vCmdLineArgs == null) { Debug.Assert(false); return new string[0]; } CommandLineArgs cl = new CommandLineArgs(vCmdLineArgs); List lFlt = new List(); foreach(string strArg in vCmdLineArgs) { KeyValuePair 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(); } public static bool ReAskKey(PwDatabase pwDatabase, bool bFailWithUI) { if(pwDatabase == null) { Debug.Assert(false); return false; } KeyPromptForm dlg = new KeyPromptForm(); dlg.InitEx(pwDatabase.IOConnectionInfo, false, true, KPRes.EnterCurrentCompositeKey); if(UIUtil.ShowDialogNotValue(dlg, DialogResult.OK)) return false; CompositeKey ck = dlg.CompositeKey; bool bResult = ck.EqualsValue(pwDatabase.MasterKey); if(!bResult) MessageService.ShowWarning(KLRes.InvalidCompositeKey, KLRes.InvalidCompositeKeyHint); UIUtil.DestroyForm(dlg); return bResult; } } } KeePass/Util/NetUtil.cs0000664000000000000000000000766113222430416013750 0ustar rootroot/* KeePass Password Safe - The Open-Source Password Manager Copyright (C) 2003-2018 Dominik Reichl This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ using System; using System.Collections.Generic; using System.Text; using System.Net; using System.IO; using System.IO.Compression; using KeePassLib.Utility; namespace KeePass.Util { public static class NetUtil { /* public static string GZipUtf8ResultToString(DownloadDataCompletedEventArgs e) { if(e.Cancelled || (e.Error != null) || (e.Result == null)) return null; MemoryStream msZipped = new MemoryStream(e.Result); GZipStream gz = new GZipStream(msZipped, CompressionMode.Decompress); BinaryReader br = new BinaryReader(gz); MemoryStream msUTF8 = new MemoryStream(); while(true) { byte[] pb = null; try { pb = br.ReadBytes(4096); } catch(Exception) { } if((pb == null) || (pb.Length == 0)) break; msUTF8.Write(pb, 0, pb.Length); } br.Close(); gz.Close(); msZipped.Close(); return StrUtil.Utf8.GetString(msUTF8.ToArray()); } */ public static string WebPageLogin(Uri url, string strPostData, out List> vCookies) { if(url == null) throw new ArgumentNullException("url"); HttpWebRequest hwr = (HttpWebRequest)HttpWebRequest.Create(url); byte[] pbPostData = Encoding.ASCII.GetBytes(strPostData); hwr.Method = "POST"; hwr.ContentType = "application/x-www-form-urlencoded"; hwr.ContentLength = pbPostData.Length; hwr.UserAgent = "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.0)"; Stream s = hwr.GetRequestStream(); s.Write(pbPostData, 0, pbPostData.Length); s.Close(); WebResponse wr = hwr.GetResponse(); StreamReader sr = new StreamReader(wr.GetResponseStream()); string strResponse = sr.ReadToEnd(); sr.Close(); wr.Close(); vCookies = new List>(); foreach(string strHeader in wr.Headers.AllKeys) { if(strHeader == "Set-Cookie") { string strCookie = wr.Headers.Get(strHeader); string[] vParts = strCookie.Split(new char[]{ ';' }); if(vParts.Length < 1) continue; string[] vInfo = vParts[0].Split(new char[]{ '=' }); if(vInfo.Length != 2) continue; vCookies.Add(new KeyValuePair( vInfo[0], vInfo[1])); } } return strResponse; } public static string WebPageGetWithCookies(Uri url, List> vCookies, string strDomain) { if(url == null) throw new ArgumentNullException("url"); HttpWebRequest hwr = (HttpWebRequest)HttpWebRequest.Create(url); hwr.Method = "GET"; hwr.UserAgent = "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.0)"; if(vCookies != null) { hwr.CookieContainer = new CookieContainer(); foreach(KeyValuePair kvpCookie in vCookies) { Cookie ck = new Cookie(kvpCookie.Key, kvpCookie.Value, "/", strDomain); hwr.CookieContainer.Add(ck); } } WebResponse wr = hwr.GetResponse(); StreamReader sr = new StreamReader(wr.GetResponseStream()); string strResponse = sr.ReadToEnd(); sr.Close(); wr.Close(); return strResponse; } } } KeePass/Util/TempFilesPool.cs0000664000000000000000000002067113222430416015102 0ustar rootroot/* KeePass Password Safe - The Open-Source Password Manager Copyright (C) 2003-2018 Dominik Reichl This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ using System; using System.Collections.Generic; using System.Diagnostics; using System.IO; using System.Text; using System.Threading; using KeePassLib.Native; using KeePassLib.Utility; namespace KeePass.Util { [Flags] internal enum TempClearFlags { None = 0, RegisteredFiles = 1, RegisteredDirectories = 2, ContentTaggedFiles = 4, All = 0x7FFF } public sealed class TempFilesPool { private List m_vFiles = new List(); private List> m_vDirs = new List>(); private Dictionary m_dContentLoc = new Dictionary(); private readonly object m_oContentLocSync = new object(); private long m_nThreads = 0; private string m_strContentTag = null; public string TempContentTag { get { if(m_strContentTag == null) { // The tag should consist only of lower case letters // and digits (for maximum compatibility); it can // for instance be used as CSS class name string strL = "cfbm4v27xyk0dk5lyeq5"; string strR = "qxi7bxozyph6qyexr9kw"; // Together ~207 bit // Avoid that the content tag is directly visible in // the source code and binaries, in case the development // environment creates temporary files containing the // tag that might then be deleted unintentionally StringBuilder sb = new StringBuilder(); sb.Append(strL); for(int i = strR.Length - 1; i >= 0; --i) sb.Append(strR[i]); // Reverse m_strContentTag = sb.ToString(); } return m_strContentTag; } } public TempFilesPool() { } #if DEBUG ~TempFilesPool() { Debug.Assert(Interlocked.Read(ref m_nThreads) == 0); } #endif internal void Clear(TempClearFlags f) { if((f & TempClearFlags.RegisteredFiles) != TempClearFlags.None) { for(int i = m_vFiles.Count - 1; i >= 0; --i) { try { if(File.Exists(m_vFiles[i])) File.Delete(m_vFiles[i]); m_vFiles.RemoveAt(i); } catch(Exception) { Debug.Assert(false); } } } if((f & TempClearFlags.RegisteredDirectories) != TempClearFlags.None) { for(int i = m_vDirs.Count - 1; i >= 0; --i) { try { if(Directory.Exists(m_vDirs[i].Key)) Directory.Delete(m_vDirs[i].Key, m_vDirs[i].Value); m_vDirs.RemoveAt(i); } catch(Exception) { Debug.Assert(false); } } } if((f & TempClearFlags.ContentTaggedFiles) != TempClearFlags.None) ClearContentAsync(); } internal void WaitForThreads() { try { while(Interlocked.Read(ref m_nThreads) > 0) { Thread.Sleep(1); } } catch(Exception) { Debug.Assert(false); } } public void Add(string strTempFile) { Debug.Assert(strTempFile != null); if(string.IsNullOrEmpty(strTempFile)) return; m_vFiles.Add(strTempFile); } public void AddDirectory(string strTempDir, bool bRecursive) { Debug.Assert(strTempDir != null); if(string.IsNullOrEmpty(strTempDir)) return; m_vDirs.Add(new KeyValuePair(strTempDir, bRecursive)); } public void AddContent(string strFilePattern, bool bRecursive) { if(string.IsNullOrEmpty(strFilePattern)) { Debug.Assert(false); return; } lock(m_oContentLocSync) { if(m_dContentLoc.ContainsKey(strFilePattern) && !bRecursive) return; // Do not overwrite recursive with non-recursive m_dContentLoc[strFilePattern] = bRecursive; } } public void AddWebBrowserPrintContent() { if(!NativeLib.IsUnix()) { // MSHTML may create and forget temporary files under // C:\\Users\\USER\\AppData\\Local\\Temp\\*.htm // (e.g. when printing fails) AddContent("*.htm", false); } } public string GetTempFileName() { return GetTempFileName(true); } public string GetTempFileName(bool bCreateEmptyFile) { string strFile = Path.GetTempFileName(); m_vFiles.Add(strFile); if(!bCreateEmptyFile) { try { File.Delete(strFile); } catch(Exception) { Debug.Assert(false); } } return strFile; } 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(); } public bool Delete(string strTempFile) { Debug.Assert(strTempFile != null); if(string.IsNullOrEmpty(strTempFile)) return false; int nFile = m_vFiles.IndexOf(strTempFile); if(nFile < 0) { Debug.Assert(false); return false; } bool bResult = false; try { File.Delete(strTempFile); m_vFiles.RemoveAt(nFile); bResult = true; } catch(Exception) { Debug.Assert(false); } return bResult; } private void ClearContentAsync() { lock(m_oContentLocSync) { if(m_dContentLoc.Count == 0) return; } Interlocked.Increment(ref m_nThreads); // Here, not in thread try { ThreadPool.QueueUserWorkItem(this.ClearContentTh); } catch(Exception) { Debug.Assert(false); Interlocked.Decrement(ref m_nThreads); } } private void ClearContentTh(object state) { try { Debug.Assert(Interlocked.Read(ref m_nThreads) > 0); string strTag = m_strContentTag; if(string.IsNullOrEmpty(strTag)) { Debug.Assert(false); return; } UnicodeEncoding ue = new UnicodeEncoding(false, false, false); byte[] pbTagA = StrUtil.Utf8.GetBytes(strTag); byte[] pbTagW = ue.GetBytes(strTag); string strTempPath = UrlUtil.GetTempPath(); Dictionary dToDo; lock(m_oContentLocSync) { dToDo = new Dictionary(m_dContentLoc); m_dContentLoc.Clear(); } foreach(KeyValuePair kvp in dToDo) { bool bSuccess = false; try { bSuccess = ClearContentPriv(strTempPath, kvp.Key, kvp.Value, pbTagA, pbTagW); } catch(Exception) { Debug.Assert(false); } if(!bSuccess) { lock(m_oContentLocSync) { m_dContentLoc[kvp.Key] = kvp.Value; // Try again next time } } } } catch(Exception) { Debug.Assert(false); } finally { Interlocked.Decrement(ref m_nThreads); } } private bool ClearContentPriv(string strTempPath, string strFilePattern, bool bRecursive, byte[] pbTagA, byte[] pbTagW) { List lFiles = UrlUtil.GetFilePaths(strTempPath, strFilePattern, (bRecursive ? SearchOption.AllDirectories : SearchOption.TopDirectoryOnly)); bool bSuccess = true; foreach(string strFile in lFiles) { if(string.IsNullOrEmpty(strFile)) continue; if((strFile == ".") || (strFile == "..")) continue; try { byte[] pb = File.ReadAllBytes(strFile); if(pb == null) { Debug.Assert(false); continue; } if((MemUtil.IndexOf(pb, pbTagA) >= 0) || (MemUtil.IndexOf(pb, pbTagW) >= 0)) { File.Delete(strFile); } } catch(Exception) { Debug.Assert(false); bSuccess = false; } } return bSuccess; } } } KeePass/Util/AutoType.cs0000664000000000000000000004767713222430416014151 0ustar rootroot/* KeePass Password Safe - The Open-Source Password Manager Copyright (C) 2003-2018 Dominik Reichl This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ using System; using System.Collections.Generic; using System.Diagnostics; using System.Media; using System.Security; using System.Text; using System.Text.RegularExpressions; using System.Threading; using System.Windows.Forms; using KeePass.App; using KeePass.Forms; using KeePass.Native; using KeePass.Resources; using KeePass.UI; using KeePass.Util.Spr; using KeePassLib; using KeePassLib.Security; using KeePassLib.Collections; using KeePassLib.Delegates; using KeePassLib.Utility; namespace KeePass.Util { public sealed class AutoTypeEventArgs : EventArgs { private string m_strSeq; // Never null public string Sequence { get { return m_strSeq; } set { if(value == null) throw new ArgumentNullException("value"); m_strSeq = value; } } public bool SendObfuscated { get; set; } public PwEntry Entry { get; private set; } public PwDatabase Database { get; private set; } public AutoTypeEventArgs(string strSequence, bool bObfuscated, PwEntry pe, PwDatabase pd) { if(strSequence == null) throw new ArgumentNullException("strSequence"); // pe may be null m_strSeq = strSequence; this.SendObfuscated = bObfuscated; this.Entry = pe; this.Database = pd; } } public static class AutoType { private const int TargetActivationDelay = 100; public static event EventHandler FilterCompilePre; public static event EventHandler FilterSendPre; public static event EventHandler FilterSend; public static event EventHandler SequenceQueryPre; public static event EventHandler SequenceQuery; public static event EventHandler SequenceQueryPost; public static event EventHandler SequenceQueriesBegin; public static event EventHandler SequenceQueriesEnd; private static int m_iEventID = 0; public static int GetNextEventID() { return Interlocked.Increment(ref m_iEventID); } internal static void InitStatic() { try { // SendKeys is not used anymore, thus the following is // not required: // // Enable new SendInput method; see // // https://msdn.microsoft.com/en-us/library/system.windows.forms.sendkeys.aspx // ConfigurationManager.AppSettings.Set("SendKeys", "SendInput"); } catch(Exception) { Debug.Assert(false); } } internal static bool MatchWindows(string strFilter, string strWindow) { Debug.Assert(strFilter != null); if(strFilter == null) return false; Debug.Assert(strWindow != null); if(strWindow == null) return false; string strF = strFilter.Trim(); /* bool bArbStart = strF.StartsWith("*"), bArbEnd = strF.EndsWith("*"); if(bArbStart) strF = strF.Remove(0, 1); if(bArbEnd) strF = strF.Substring(0, strF.Length - 1); if(bArbStart && bArbEnd) return (strWindow.IndexOf(strF, StrUtil.CaseIgnoreCmp) >= 0); else if(bArbStart) return strWindow.EndsWith(strF, StrUtil.CaseIgnoreCmp); else if(bArbEnd) return strWindow.StartsWith(strF, StrUtil.CaseIgnoreCmp); return strWindow.Equals(strF, StrUtil.CaseIgnoreCmp); */ if(strF.StartsWith(@"//") && strF.EndsWith(@"//") && (strF.Length > 4)) { try { Regex rx = new Regex(strF.Substring(2, strF.Length - 4), RegexOptions.IgnoreCase); return rx.IsMatch(strWindow); } catch(Exception) { } } return StrUtil.SimplePatternMatch(strF, strWindow, StrUtil.CaseIgnoreCmp); } private static bool Execute(AutoTypeCtx ctx) { if(ctx == null) { Debug.Assert(false); return false; } string strSeq = ctx.Sequence; PwEntry pweData = ctx.Entry; if(pweData == null) { Debug.Assert(false); return false; } if(!pweData.GetAutoTypeEnabled()) return false; if(!AppPolicy.Try(AppPolicyId.AutoType)) return false; if(KeePassLib.Native.NativeLib.IsUnix()) { if(!NativeMethods.TryXDoTool()) { MessageService.ShowWarning(KPRes.AutoTypeXDoToolRequired, KPRes.PackageInstallHint); return false; } } PwDatabase pwDatabase = ctx.Database; bool bObfuscate = (pweData.AutoType.ObfuscationOptions != AutoTypeObfuscationOptions.None); AutoTypeEventArgs args = new AutoTypeEventArgs(strSeq, bObfuscate, pweData, pwDatabase); if(AutoType.FilterCompilePre != null) AutoType.FilterCompilePre(null, args); args.Sequence = SprEngine.Compile(args.Sequence, new SprContext( pweData, pwDatabase, SprCompileFlags.All, true, false)); // string strError = ValidateAutoTypeSequence(args.Sequence); // if(!string.IsNullOrEmpty(strError)) // { // MessageService.ShowWarning(args.Sequence + // MessageService.NewParagraph + strError); // return false; // } Application.DoEvents(); if(AutoType.FilterSendPre != null) AutoType.FilterSendPre(null, args); if(AutoType.FilterSend != null) AutoType.FilterSend(null, args); if(args.Sequence.Length > 0) { string strError = null; try { SendInputEx.SendKeysWait(args.Sequence, args.SendObfuscated); } catch(SecurityException exSec) { strError = exSec.Message; } catch(Exception ex) { strError = args.Sequence + MessageService.NewParagraph + ex.Message; } if(!string.IsNullOrEmpty(strError)) { try { MainForm mfP = Program.MainForm; if(mfP != null) mfP.EnsureVisibleForegroundWindow(false, false); } catch(Exception) { Debug.Assert(false); } MessageService.ShowWarning(strError); } } pweData.Touch(false); EntryUtil.ExpireTanEntryIfOption(pweData, pwDatabase); MainForm mf = Program.MainForm; if(mf != null) { // Always refresh entry list (e.g. {NEWPASSWORD} might // have changed data) mf.RefreshEntriesList(); // SprEngine.Compile might have modified the database; // pd.Modified is set by SprEngine mf.UpdateUI(false, null, false, null, false, null, false); } return true; } private static bool PerformInternal(AutoTypeCtx ctx, string strWindow) { if(ctx == null) { Debug.Assert(false); return false; } AutoTypeCtx ctxNew = ctx.Clone(); if(Program.Config.Integration.AutoTypePrependInitSequenceForIE && WinUtil.IsInternetExplorer7Window(strWindow)) { ctxNew.Sequence = @"{DELAY 50}1{DELAY 50}{BACKSPACE}" + ctxNew.Sequence; } return AutoType.Execute(ctxNew); } private static SequenceQueriesEventArgs GetSequencesForWindowBegin( IntPtr hWnd, string strWindow) { SequenceQueriesEventArgs e = new SequenceQueriesEventArgs( GetNextEventID(), hWnd, strWindow); if(AutoType.SequenceQueriesBegin != null) AutoType.SequenceQueriesBegin(null, e); return e; } private static void GetSequencesForWindowEnd(SequenceQueriesEventArgs e) { if(AutoType.SequenceQueriesEnd != null) AutoType.SequenceQueriesEnd(null, e); } // Multiple calls of this method are wrapped in // GetSequencesForWindowBegin and GetSequencesForWindowEnd private static List GetSequencesForWindow(PwEntry pwe, IntPtr hWnd, string strWindow, PwDatabase pdContext, int iEventID) { List l = new List(); if(pwe == null) { Debug.Assert(false); return l; } if(strWindow == null) { Debug.Assert(false); return l; } // May be empty if(!pwe.GetAutoTypeEnabled()) return l; SprContext sprCtx = new SprContext(pwe, pdContext, SprCompileFlags.NonActive); RaiseSequenceQueryEvent(AutoType.SequenceQueryPre, iEventID, hWnd, strWindow, pwe, pdContext, l); // Specifically defined sequences must match before the title, // in order to allow selecting the first item as default one foreach(AutoTypeAssociation a in pwe.AutoType.Associations) { string strWndSpec = a.WindowName; if(strWndSpec == null) { Debug.Assert(false); continue; } strWndSpec = SprEngine.Compile(strWndSpec.Trim(), sprCtx); if(MatchWindows(strWndSpec, strWindow)) { string strSeq = a.Sequence; if(string.IsNullOrEmpty(strSeq)) strSeq = pwe.GetAutoTypeSequence(); AddSequence(l, strSeq); } } RaiseSequenceQueryEvent(AutoType.SequenceQuery, iEventID, hWnd, strWindow, pwe, pdContext, l); if(Program.Config.Integration.AutoTypeMatchByTitle) { string strTitle = SprEngine.Compile(pwe.Strings.ReadSafe( PwDefs.TitleField).Trim(), sprCtx); if((strTitle.Length > 0) && (strWindow.IndexOf(strTitle, StrUtil.CaseIgnoreCmp) >= 0)) AddSequence(l, pwe.GetAutoTypeSequence()); } string strCmpUrl = null; // To cache compiled URL if(Program.Config.Integration.AutoTypeMatchByUrlInTitle) { strCmpUrl = SprEngine.Compile(pwe.Strings.ReadSafe( PwDefs.UrlField).Trim(), sprCtx); if((strCmpUrl.Length > 0) && (strWindow.IndexOf(strCmpUrl, StrUtil.CaseIgnoreCmp) >= 0)) AddSequence(l, pwe.GetAutoTypeSequence()); } if(Program.Config.Integration.AutoTypeMatchByUrlHostInTitle) { if(strCmpUrl == null) strCmpUrl = SprEngine.Compile(pwe.Strings.ReadSafe( PwDefs.UrlField).Trim(), sprCtx); string strCleanUrl = StrUtil.RemovePlaceholders(strCmpUrl); string strHost = UrlUtil.GetHost(strCleanUrl); if(strHost.StartsWith("www.", StrUtil.CaseIgnoreCmp) && (strCleanUrl.StartsWith("http:", StrUtil.CaseIgnoreCmp) || strCleanUrl.StartsWith("https:", StrUtil.CaseIgnoreCmp))) strHost = strHost.Substring(4); if((strHost.Length > 0) && (strWindow.IndexOf(strHost, StrUtil.CaseIgnoreCmp) >= 0)) AddSequence(l, pwe.GetAutoTypeSequence()); } if(Program.Config.Integration.AutoTypeMatchByTagInTitle) { foreach(string strTag in pwe.Tags) { if(string.IsNullOrEmpty(strTag)) { Debug.Assert(false); continue; } if(strWindow.IndexOf(strTag, StrUtil.CaseIgnoreCmp) >= 0) { AddSequence(l, pwe.GetAutoTypeSequence()); break; } } } RaiseSequenceQueryEvent(AutoType.SequenceQueryPost, iEventID, hWnd, strWindow, pwe, pdContext, l); return l; } private static void RaiseSequenceQueryEvent( EventHandler f, int iEventID, IntPtr hWnd, string strWindow, PwEntry pwe, PwDatabase pdContext, List lSeq) { if(f == null) return; SequenceQueryEventArgs e = new SequenceQueryEventArgs(iEventID, hWnd, strWindow, pwe, pdContext); f(null, e); foreach(string strSeq in e.Sequences) AddSequence(lSeq, strSeq); } private static void AddSequence(List lSeq, string strSeq) { if(strSeq == null) { Debug.Assert(false); return; } string strCanSeq = CanonicalizeSeq(strSeq); for(int i = 0; i < lSeq.Count; ++i) { string strCanEx = CanonicalizeSeq(lSeq[i]); if(strCanEx.Equals(strCanSeq)) return; // Exists already } lSeq.Add(strSeq); // Non-canonical version } private const string StrBraceOpen = @"{1E1F63AB-2F63-4B60-ADBA-7F38B8D7778E}"; private const string StrBraceClose = @"{34D698D7-CEBF-4AF0-87BF-DC1B1F5E95A0}"; private static string CanonicalizeSeq(string strSeq) { // Preprocessing: balance braces strSeq = strSeq.Replace(@"{{}", StrBraceOpen); strSeq = strSeq.Replace(@"{}}", StrBraceClose); StringBuilder sb = new StringBuilder(); bool bInPlh = false; for(int i = 0; i < strSeq.Length; ++i) { char ch = strSeq[i]; if(ch == '{') bInPlh = true; else if(ch == '}') bInPlh = false; else if(bInPlh) ch = char.ToUpper(ch); sb.Append(ch); } strSeq = sb.ToString(); // Postprocessing: restore braces strSeq = strSeq.Replace(StrBraceOpen, @"{{}"); strSeq = strSeq.Replace(StrBraceClose, @"{}}"); return strSeq; } internal static bool IsOwnWindow(IntPtr hWindow) { return ((hWindow == Program.MainForm.Handle) || GlobalWindowManager.HasWindow(hWindow)); } public static bool IsValidAutoTypeWindow(IntPtr hWindow, bool bBeepIfNot) { bool bValid = !IsOwnWindow(hWindow); if(!bValid && bBeepIfNot) SystemSounds.Beep.Play(); return bValid; } public static bool PerformGlobal(List vSources, ImageList ilIcons) { Debug.Assert(vSources != null); if(vSources == null) return false; if(KeePassLib.Native.NativeLib.IsUnix()) { if(!NativeMethods.TryXDoTool(true)) { MessageService.ShowWarning(KPRes.AutoTypeXDoToolRequiredGlobalVer); return false; } } IntPtr hWnd; string strWindow; try { // hWnd = NativeMethods.GetForegroundWindowHandle(); // strWindow = NativeMethods.GetWindowText(hWnd); NativeMethods.GetForegroundWindowInfo(out hWnd, out strWindow, true); } catch(Exception) { Debug.Assert(false); hWnd = IntPtr.Zero; strWindow = null; } // if(string.IsNullOrEmpty(strWindow)) return false; if(strWindow == null) { Debug.Assert(false); return false; } if(!IsValidAutoTypeWindow(hWnd, true)) return false; SequenceQueriesEventArgs evQueries = GetSequencesForWindowBegin( hWnd, strWindow); List lCtxs = new List(); PwDatabase pdCurrent = null; bool bExpCanMatch = Program.Config.Integration.AutoTypeExpiredCanMatch; DateTime dtNow = DateTime.UtcNow; EntryHandler eh = delegate(PwEntry pe) { if(!bExpCanMatch && pe.Expires && (pe.ExpiryTime <= dtNow)) return true; // Ignore expired entries List lSeq = GetSequencesForWindow(pe, hWnd, strWindow, pdCurrent, evQueries.EventID); foreach(string strSeq in lSeq) { lCtxs.Add(new AutoTypeCtx(strSeq, pe, pdCurrent)); } return true; }; foreach(PwDatabase pwSource in vSources) { if(pwSource.IsOpen == false) continue; pdCurrent = pwSource; pwSource.RootGroup.TraverseTree(TraversalMethod.PreOrder, null, eh); } GetSequencesForWindowEnd(evQueries); bool bForceDlg = Program.Config.Integration.AutoTypeAlwaysShowSelDialog; if((lCtxs.Count >= 2) || bForceDlg) { AutoTypeCtxForm dlg = new AutoTypeCtxForm(); dlg.InitEx(lCtxs, ilIcons); bool bOK = (dlg.ShowDialog() == DialogResult.OK); AutoTypeCtx ctx = (bOK ? dlg.SelectedCtx : null); UIUtil.DestroyForm(dlg); if(ctx != null) { try { NativeMethods.EnsureForegroundWindow(hWnd); } catch(Exception) { Debug.Assert(false); } int nActDelayMS = TargetActivationDelay; string strWindowT = strWindow.Trim(); // https://sourceforge.net/p/keepass/discussion/329220/thread/3681f343/ // This apparently is only required here (after showing the // auto-type entry selection dialog), not when using the // context menu command in the main window if(strWindowT.EndsWith("Microsoft Edge", StrUtil.CaseIgnoreCmp)) { // 700 skips the first 1-2 characters, // 750 sometimes skips the first character nActDelayMS = 1000; } // Allow target window to handle its activation // (required by some applications, e.g. Edge) Application.DoEvents(); Thread.Sleep(nActDelayMS); Application.DoEvents(); AutoType.PerformInternal(ctx, strWindow); } } else if(lCtxs.Count == 1) AutoType.PerformInternal(lCtxs[0], strWindow); return true; } [Obsolete] public static bool PerformIntoPreviousWindow(Form fCurrent, PwEntry pe) { return PerformIntoPreviousWindow(fCurrent, pe, Program.MainForm.DocumentManager.SafeFindContainerOf(pe), null); } public static bool PerformIntoPreviousWindow(Form fCurrent, PwEntry pe, PwDatabase pdContext) { return PerformIntoPreviousWindow(fCurrent, pe, pdContext, null); } public static bool PerformIntoPreviousWindow(Form fCurrent, PwEntry pe, PwDatabase pdContext, string strSeq) { if(pe == null) { Debug.Assert(false); return false; } if(!pe.GetAutoTypeEnabled()) return false; if(!AppPolicy.Try(AppPolicyId.AutoTypeWithoutContext)) return false; bool bTopMost = ((fCurrent != null) ? fCurrent.TopMost : false); if(bTopMost) fCurrent.TopMost = false; try { if(!NativeMethods.LoseFocus(fCurrent)) { Debug.Assert(false); } return PerformIntoCurrentWindow(pe, pdContext, strSeq); } finally { if(bTopMost) fCurrent.TopMost = true; } } [Obsolete] public static bool PerformIntoCurrentWindow(PwEntry pe) { return PerformIntoCurrentWindow(pe, Program.MainForm.DocumentManager.SafeFindContainerOf(pe), null); } public static bool PerformIntoCurrentWindow(PwEntry pe, PwDatabase pdContext) { return PerformIntoCurrentWindow(pe, pdContext, null); } public static bool PerformIntoCurrentWindow(PwEntry pe, PwDatabase pdContext, string strSeq) { if(pe == null) { Debug.Assert(false); return false; } if(!pe.GetAutoTypeEnabled()) return false; if(!AppPolicy.Try(AppPolicyId.AutoTypeWithoutContext)) return false; Thread.Sleep(TargetActivationDelay); IntPtr hWnd; string strWindow; try { NativeMethods.GetForegroundWindowInfo(out hWnd, out strWindow, true); } catch(Exception) { hWnd = IntPtr.Zero; strWindow = null; } if(!KeePassLib.Native.NativeLib.IsUnix()) { if(strWindow == null) { Debug.Assert(false); return false; } } else strWindow = string.Empty; if(strSeq == null) { SequenceQueriesEventArgs evQueries = GetSequencesForWindowBegin( hWnd, strWindow); List lSeq = GetSequencesForWindow(pe, hWnd, strWindow, pdContext, evQueries.EventID); GetSequencesForWindowEnd(evQueries); if(lSeq.Count == 0) strSeq = pe.GetAutoTypeSequence(); else strSeq = lSeq[0]; } AutoTypeCtx ctx = new AutoTypeCtx(strSeq, pe, pdContext); return AutoType.PerformInternal(ctx, strWindow); } // ValidateAutoTypeSequence is not required anymore, because // SendInputEx now validates the sequence /* private static string ValidateAutoTypeSequence(string strSequence) { Debug.Assert(strSequence != null); string strSeq = strSequence; strSeq = strSeq.Replace(@"{{}", string.Empty); strSeq = strSeq.Replace(@"{}}", string.Empty); int cBrackets = 0; for(int c = 0; c < strSeq.Length; ++c) { if(strSeq[c] == '{') ++cBrackets; else if(strSeq[c] == '}') --cBrackets; if((cBrackets < 0) || (cBrackets > 1)) return KPRes.AutoTypeSequenceInvalid; } if(cBrackets != 0) return KPRes.AutoTypeSequenceInvalid; if(strSeq.IndexOf(@"{}") >= 0) return KPRes.AutoTypeSequenceInvalid; try { Regex r = new Regex(@"\{[^\{\}]+\}", RegexOptions.CultureInvariant); MatchCollection matches = r.Matches(strSeq); foreach(Match m in matches) { string strValue = m.Value; if(strValue.StartsWith(@"{s:", StrUtil.CaseIgnoreCmp)) return (KPRes.AutoTypeUnknownPlaceholder + MessageService.NewLine + strValue); } } catch(Exception ex) { Debug.Assert(false); return ex.Message; } return null; } */ } } KeePass/Util/ClipboardUtil.Windows.cs0000664000000000000000000001357413222430416016552 0ustar rootroot/* KeePass Password Safe - The Open-Source Password Manager Copyright (C) 2003-2018 Dominik Reichl This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ using System; using System.Collections.Generic; using System.Text; using System.Threading; using System.Runtime.InteropServices; using System.Windows.Forms; using System.Diagnostics; using KeePass.Native; using KeePass.UI; using KeePassLib; using KeePassLib.Utility; namespace KeePass.Util { public static partial class ClipboardUtil { private const int CntUnmanagedRetries = 10; private const int CntUnmanagedDelay = 100; private static bool OpenW(IntPtr hOwner, bool bEmpty) { IntPtr h = hOwner; if(h == IntPtr.Zero) { try { Form f = GlobalWindowManager.TopWindow; h = ((f != null) ? f.Handle : IntPtr.Zero); if(h == IntPtr.Zero) h = Program.MainForm.Handle; } catch(Exception) { Debug.Assert(false); } } for(int i = 0; i < CntUnmanagedRetries; ++i) { if(NativeMethods.OpenClipboard(h)) { if(bEmpty) { if(!NativeMethods.EmptyClipboard()) { Debug.Assert(false); } } return true; } Thread.Sleep(CntUnmanagedDelay); } return false; } private static byte[] GetDataW(uint uFormat) { IntPtr h = NativeMethods.GetClipboardData(uFormat); if(h == IntPtr.Zero) return null; UIntPtr pSize = NativeMethods.GlobalSize(h); if(pSize == UIntPtr.Zero) return MemUtil.EmptyByteArray; IntPtr hMem = NativeMethods.GlobalLock(h); if(hMem == IntPtr.Zero) { Debug.Assert(false); return null; } byte[] pbMem = new byte[pSize.ToUInt64()]; Marshal.Copy(hMem, pbMem, 0, pbMem.Length); NativeMethods.GlobalUnlock(h); // May return false on success return pbMem; } private static string GetStringW(string strFormat, bool? bForceUni) { bool bUni = (bForceUni.HasValue ? bForceUni.Value : WinUtil.IsAtLeastWindows2000); uint uFormat = (bUni ? NativeMethods.CF_UNICODETEXT : NativeMethods.CF_TEXT); if(!string.IsNullOrEmpty(strFormat)) uFormat = NativeMethods.RegisterClipboardFormat(strFormat); byte[] pb = GetDataW(uFormat); if(pb == null) { Debug.Assert(false); return null; } int nBytes = 0; for(int i = 0; i < pb.Length; i += (bUni ? 2 : 1)) { if(bUni && (i == (pb.Length - 1))) { Debug.Assert(false); return null; } ushort uValue = (bUni ? (ushort)(((ushort)pb[i] << 8) | (ushort)pb[i + 1]) : (ushort)pb[i]); if(uValue == 0) break; nBytes += (bUni ? 2 : 1); } byte[] pbCharsOnly = new byte[nBytes]; Array.Copy(pb, pbCharsOnly, nBytes); Encoding enc = (bUni ? new UnicodeEncoding(false, false) : Encoding.Default); return enc.GetString(pbCharsOnly); } private static bool SetDataW(uint uFormat, byte[] pbData) { UIntPtr pSize = new UIntPtr((uint)pbData.Length); IntPtr h = NativeMethods.GlobalAlloc(NativeMethods.GHND, pSize); if(h == IntPtr.Zero) { Debug.Assert(false); return false; } Debug.Assert(NativeMethods.GlobalSize(h).ToUInt64() >= (ulong)pbData.Length); // Might be larger IntPtr hMem = NativeMethods.GlobalLock(h); if(hMem == IntPtr.Zero) { Debug.Assert(false); NativeMethods.GlobalFree(h); return false; } Marshal.Copy(pbData, 0, hMem, pbData.Length); NativeMethods.GlobalUnlock(h); // May return false on success if(NativeMethods.SetClipboardData(uFormat, h) == IntPtr.Zero) { Debug.Assert(false); NativeMethods.GlobalFree(h); return false; } return true; } private static bool SetDataW(uint? uFormat, string strData, bool? bForceUni) { if(strData == null) { Debug.Assert(false); return false; } bool bUni = (bForceUni.HasValue ? bForceUni.Value : WinUtil.IsAtLeastWindows2000); uint uFmt = (uFormat.HasValue ? uFormat.Value : (bUni ? NativeMethods.CF_UNICODETEXT : NativeMethods.CF_TEXT)); Encoding enc = (bUni ? new UnicodeEncoding(false, false) : Encoding.Default); byte[] pb = enc.GetBytes(strData); byte[] pbWithZero = new byte[pb.Length + (bUni ? 2 : 1)]; Array.Copy(pb, pbWithZero, pb.Length); pbWithZero[pb.Length] = 0; if(bUni) pbWithZero[pb.Length + 1] = 0; return SetDataW(uFmt, pbWithZero); } /* private static bool SetDataWithLengthW(string strFormat, byte[] pbData) { uint uFormat = NativeMethods.RegisterClipboardFormat(strFormat); uint uLenFormat = NativeMethods.RegisterClipboardFormat(strFormat + "_Length"); byte[] pbLen = MemUtil.UInt64ToBytes((ulong)pbData.LongLength); bool bResult = true; if(!SetDataW(uLenFormat, pbLen)) bResult = false; if(!SetDataW(uFormat, pbData)) bResult = false; return bResult; } */ private static void CloseW() { if(!NativeMethods.CloseClipboard()) { Debug.Assert(false); } } private static bool AttachIgnoreFormatW() { if(!Program.Config.Security.UseClipboardViewerIgnoreFormat) return true; uint uIgnoreFmt = NativeMethods.RegisterClipboardFormat( ClipboardIgnoreFormatName); if(uIgnoreFmt == 0) { Debug.Assert(false); return false; } return SetDataW(uIgnoreFmt, PwDefs.ProductName, null); } } } KeePass/Util/XmlUtil.XmlReplace.cs0000664000000000000000000002465413222430420016011 0ustar rootroot/* KeePass Password Safe - The Open-Source Password Manager Copyright (C) 2003-2018 Dominik Reichl This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ using System; using System.Collections.Generic; using System.Text; using System.Text.RegularExpressions; using System.IO; using System.Xml; using System.Xml.XPath; using System.Windows.Forms; using System.Diagnostics; using KeePass.Forms; using KeePass.Resources; using KeePass.UI; using KeePassLib; using KeePassLib.Collections; using KeePassLib.Delegates; using KeePassLib.Interfaces; using KeePassLib.Security; using KeePassLib.Serialization; using KeePassLib.Utility; namespace KeePass.Util { [Flags] public enum XmlReplaceFlags { None = 0x0, StatusUI = 0x1, CaseSensitive = 0x10, Regex = 0x20 } public enum XmlReplaceOp { None = 0, RemoveNodes, ReplaceData } public enum XmlReplaceData { None = 0, InnerText, InnerXml, OuterXml } public sealed class XmlReplaceOptions { private XmlReplaceFlags m_f = XmlReplaceFlags.None; public XmlReplaceFlags Flags { get { return m_f; } set { m_f = value; } } private string m_strSelXPath = string.Empty; public string SelectNodesXPath { get { return m_strSelXPath; } set { if(value == null) { Debug.Assert(false); m_strSelXPath = string.Empty; } else m_strSelXPath = value; } } private XmlReplaceOp m_op = XmlReplaceOp.None; public XmlReplaceOp Operation { get { return m_op; } set { m_op = value; } } private XmlReplaceData m_d = XmlReplaceData.None; public XmlReplaceData Data { get { return m_d; } set { m_d = value; } } private string m_strFind = string.Empty; public string FindText { get { return m_strFind; } set { if(value == null) { Debug.Assert(false); m_strFind = string.Empty; } else m_strFind = value; } } private string m_strReplace = string.Empty; public string ReplaceText { get { return m_strReplace; } set { if(value == null) { Debug.Assert(false); m_strReplace = string.Empty; } else m_strReplace = value; } } private Form m_fParent = null; public Form ParentForm { get { return m_fParent; } set { m_fParent = value; } } public XmlReplaceOptions() { } } public static partial class XmlUtil { public static void Replace(PwDatabase pd, XmlReplaceOptions opt) { if(pd == null) { Debug.Assert(false); return; } if(opt == null) { Debug.Assert(false); return; } StatusProgressForm dlg = null; try { if((opt.Flags & XmlReplaceFlags.StatusUI) != XmlReplaceFlags.None) dlg = StatusProgressForm.ConstructEx(KPRes.XmlReplace, true, false, opt.ParentForm, KPRes.XmlReplace + "..."); PerformXmlReplace(pd, opt, dlg); } finally { if(dlg != null) StatusProgressForm.DestroyEx(dlg); } } private static void PerformXmlReplace(PwDatabase pd, XmlReplaceOptions opt, IStatusLogger sl) { if(opt.SelectNodesXPath.Length == 0) return; if(opt.Operation == XmlReplaceOp.None) return; bool bRemove = (opt.Operation == XmlReplaceOp.RemoveNodes); bool bReplace = (opt.Operation == XmlReplaceOp.ReplaceData); bool bMatchCase = ((opt.Flags & XmlReplaceFlags.CaseSensitive) != XmlReplaceFlags.None); bool bRegex = ((opt.Flags & XmlReplaceFlags.Regex) != XmlReplaceFlags.None); Regex rxFind = null; if(bReplace && bRegex) rxFind = new Regex(opt.FindText, (bMatchCase ? RegexOptions.None : RegexOptions.IgnoreCase)); EnsureStandardFieldsExist(pd); KdbxFile kdbxOrg = new KdbxFile(pd); MemoryStream msOrg = new MemoryStream(); kdbxOrg.Save(msOrg, null, KdbxFormat.PlainXml, sl); byte[] pbXml = msOrg.ToArray(); msOrg.Close(); string strXml = StrUtil.Utf8.GetString(pbXml); XmlDocument xd = new XmlDocument(); xd.LoadXml(strXml); XPathNavigator xpNavRoot = xd.CreateNavigator(); XPathNodeIterator xpIt = xpNavRoot.Select(opt.SelectNodesXPath); // XPathNavigators must be cloned to make them independent List lNodes = new List(); while(xpIt.MoveNext()) lNodes.Add(xpIt.Current.Clone()); if(lNodes.Count == 0) return; for(int i = lNodes.Count - 1; i >= 0; --i) { if((sl != null) && !sl.ContinueWork()) return; XPathNavigator xpNav = lNodes[i]; if(bRemove) xpNav.DeleteSelf(); else if(bReplace) ApplyReplace(xpNav, opt, rxFind); else { Debug.Assert(false); } // Unknown action } MemoryStream msMod = new MemoryStream(); XmlWriterSettings xws = new XmlWriterSettings(); xws.Encoding = StrUtil.Utf8; xws.Indent = true; xws.IndentChars = "\t"; XmlWriter xw = XmlWriter.Create(msMod, xws); xd.Save(xw); byte[] pbMod = msMod.ToArray(); msMod.Close(); PwDatabase pdMod = new PwDatabase(); msMod = new MemoryStream(pbMod, false); try { KdbxFile kdbxMod = new KdbxFile(pdMod); kdbxMod.Load(msMod, KdbxFormat.PlainXml, sl); } catch(Exception) { throw new Exception(KPRes.XmlModInvalid + MessageService.NewParagraph + KPRes.OpAborted + MessageService.NewParagraph + KPRes.DbNoModBy.Replace(@"{PARAM}", @"'" + KPRes.XmlReplace + @"'")); } finally { msMod.Close(); } PrepareModDbForMerge(pdMod, pd); pd.Modified = true; pd.UINeedsIconUpdate = true; pd.MergeIn(pdMod, PwMergeMethod.Synchronize, sl); } private static void ApplyReplace(XPathNavigator xpNav, XmlReplaceOptions opt, Regex rxFind) { string strData; if(opt.Data == XmlReplaceData.InnerText) strData = xpNav.Value; else if(opt.Data == XmlReplaceData.InnerXml) strData = xpNav.InnerXml; else if(opt.Data == XmlReplaceData.OuterXml) strData = xpNav.OuterXml; else return; if(strData == null) { Debug.Assert(false); strData = string.Empty; } string str = null; if(rxFind != null) str = rxFind.Replace(strData, opt.ReplaceText); else { if((opt.Flags & XmlReplaceFlags.CaseSensitive) != XmlReplaceFlags.None) str = strData.Replace(opt.FindText, opt.ReplaceText); else str = StrUtil.ReplaceCaseInsensitive(strData, opt.FindText, opt.ReplaceText); } if((str != null) && (str != strData)) { if(opt.Data == XmlReplaceData.InnerText) xpNav.SetValue(str); else if(opt.Data == XmlReplaceData.InnerXml) xpNav.InnerXml = str; else if(opt.Data == XmlReplaceData.OuterXml) xpNav.OuterXml = str; else { Debug.Assert(false); } } } private static void PrepareModDbForMerge(PwDatabase pd, PwDatabase pdOrg) { PwGroup pgRootOrg = pdOrg.RootGroup; PwGroup pgRootNew = pd.RootGroup; if(pgRootNew == null) { Debug.Assert(false); return; } PwCompareOptions pwCmp = (PwCompareOptions.IgnoreParentGroup | PwCompareOptions.NullEmptyEquivStd); DateTime dtNow = DateTime.UtcNow; GroupHandler ghOrg = delegate(PwGroup pg) { PwGroup pgNew = pgRootNew.FindGroup(pg.Uuid, true); if(pgNew == null) { AddDeletedObject(pd, pg.Uuid); return true; } if(!pgNew.EqualsGroup(pg, (pwCmp | PwCompareOptions.PropertiesOnly), MemProtCmpMode.Full)) pgNew.Touch(true, false); PwGroup pgParentA = pg.ParentGroup; PwGroup pgParentB = pgNew.ParentGroup; if((pgParentA != null) && (pgParentB != null)) { if(!pgParentA.Uuid.Equals(pgParentB.Uuid)) pgNew.LocationChanged = dtNow; } else if((pgParentA == null) && (pgParentB == null)) { } else pgNew.LocationChanged = dtNow; return true; }; EntryHandler ehOrg = delegate(PwEntry pe) { PwEntry peNew = pgRootNew.FindEntry(pe.Uuid, true); if(peNew == null) { AddDeletedObject(pd, pe.Uuid); return true; } if(!peNew.EqualsEntry(pe, pwCmp, MemProtCmpMode.Full)) { peNew.Touch(true, false); bool bRestoreHistory = false; if(peNew.History.UCount != pe.History.UCount) bRestoreHistory = true; else { for(uint u = 0; u < pe.History.UCount; ++u) { if(!peNew.History.GetAt(u).EqualsEntry( pe.History.GetAt(u), pwCmp, MemProtCmpMode.CustomOnly)) { bRestoreHistory = true; break; } } } if(bRestoreHistory) { peNew.History = pe.History.CloneDeep(); foreach(PwEntry peHistNew in peNew.History) peHistNew.ParentGroup = peNew.ParentGroup; } } PwGroup pgParentA = pe.ParentGroup; PwGroup pgParentB = peNew.ParentGroup; if((pgParentA != null) && (pgParentB != null)) { if(!pgParentA.Uuid.Equals(pgParentB.Uuid)) peNew.LocationChanged = dtNow; } else if((pgParentA == null) && (pgParentB == null)) { } else peNew.LocationChanged = dtNow; return true; }; pgRootOrg.TraverseTree(TraversalMethod.PreOrder, ghOrg, ehOrg); } private static void AddDeletedObject(PwDatabase pd, PwUuid pu) { foreach(PwDeletedObject pdo in pd.DeletedObjects) { if(pdo.Uuid.Equals(pu)) { Debug.Assert(false); return; } } PwDeletedObject pdoNew = new PwDeletedObject(pu, DateTime.UtcNow); pd.DeletedObjects.Add(pdoNew); } private static void EnsureStandardFieldsExist(PwDatabase pd) { List l = PwDefs.GetStandardFields(); EntryHandler eh = delegate(PwEntry pe) { foreach(string strName in l) { ProtectedString ps = pe.Strings.Get(strName); if(ps == null) pe.Strings.Set(strName, new ProtectedString( pd.MemoryProtection.GetProtection(strName), string.Empty)); } return true; }; pd.RootGroup.TraverseTree(TraversalMethod.PreOrder, null, eh); } } } KeePass/Util/EntryMenu.cs0000664000000000000000000001415213222430416014303 0ustar rootroot/* KeePass Password Safe - The Open-Source Password Manager Copyright (C) 2003-2018 Dominik Reichl This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ using System; using System.Collections.Generic; using System.Text; using System.Windows.Forms; using System.Diagnostics; using KeePass.Resources; using KeePass.UI; using KeePassLib; using KeePassLib.Utility; namespace KeePass.Util { public static class EntryMenu { private static CustomContextMenuStripEx m_ctx = null; public static void Show() { EntryMenu.Show(Cursor.Position.X, Cursor.Position.Y); } public static void Show(int iPosX, int iPosY) { EntryMenu.Destroy(); m_ctx = EntryMenu.Construct(); m_ctx.Show(iPosX, iPosY); } public static void Destroy() { if(m_ctx != null) { m_ctx.Close(); m_ctx.Dispose(); m_ctx = null; } } private static CustomContextMenuStripEx Construct() { CustomContextMenuStripEx ctx = new CustomContextMenuStripEx(); // Clone the image list in order to prevent event handlers // from the global client icons list to the context menu ctx.ImageList = UIUtil.CloneImageList(Program.MainForm.ClientIcons, true); bool bAppendSeparator = false; foreach(PwDocument ds in Program.MainForm.DocumentManager.Documents) { if(ds.Database.IsOpen) { if(bAppendSeparator) ctx.Items.Add(new ToolStripSeparator()); foreach(PwGroup pg in ds.Database.RootGroup.Groups) { ToolStripMenuItem tsmi = MenuCreateGroup(ds, pg); ctx.Items.Add(tsmi); MenuProcessGroup(ds, tsmi, pg); } bAppendSeparator = true; } } GlobalWindowManager.CustomizeControl(ctx); return ctx; } private static ToolStripMenuItem MenuCreateGroup(PwDocument ds, PwGroup pg) { ToolStripMenuItem tsmi = new ToolStripMenuItem(); tsmi.Text = pg.Name; tsmi.ImageIndex = MenuGetImageIndex(ds, pg.IconId, pg.CustomIconUuid); return tsmi; } private static int MenuGetImageIndex(PwDocument ds, PwIcon pwID, PwUuid pwCustomID) { if(!pwCustomID.Equals(PwUuid.Zero) && (ds == Program.MainForm.DocumentManager.ActiveDocument)) { return (int)PwIcon.Count + Program.MainForm.DocumentManager.ActiveDatabase.GetCustomIconIndex( pwCustomID); } if((int)pwID < (int)PwIcon.Count) return (int)pwID; return (int)PwIcon.Key; } private static void MenuAddEntry(PwDocument ds, ToolStripMenuItem tsmiContainer, PwEntry pe) { ToolStripMenuItem tsmiEntry = new ToolStripMenuItem(); string strTitle = pe.Strings.ReadSafe(PwDefs.TitleField); string strUser = pe.Strings.ReadSafe(PwDefs.UserNameField); string strText = string.Empty; if((strTitle.Length > 0) && (strUser.Length > 0)) strText = strTitle + ": " + strUser; else if(strTitle.Length > 0) strText = strTitle; else if(strUser.Length > 0) strText = strUser; tsmiEntry.Text = strText; tsmiEntry.ImageIndex = MenuGetImageIndex(ds, pe.IconId, pe.CustomIconUuid); tsmiContainer.DropDownItems.Add(tsmiEntry); ToolStripMenuItem tsmi; tsmi = new ToolStripMenuItem(KPRes.AutoType); tsmi.ImageIndex = (int)PwIcon.Run; tsmi.Tag = pe; tsmi.Click += OnAutoType; tsmi.Enabled = pe.GetAutoTypeEnabled(); tsmiEntry.DropDownItems.Add(tsmi); tsmiEntry.DropDownItems.Add(new ToolStripSeparator()); tsmi = new ToolStripMenuItem(KPRes.Copy + " " + KPRes.UserName); tsmi.ImageIndex = (int)PwIcon.UserKey; tsmi.Tag = pe; tsmi.Click += OnCopyUserName; tsmiEntry.DropDownItems.Add(tsmi); tsmi = new ToolStripMenuItem(KPRes.Copy + " " + KPRes.Password); tsmi.ImageIndex = (int)PwIcon.Key; tsmi.Tag = pe; tsmi.Click += OnCopyPassword; tsmiEntry.DropDownItems.Add(tsmi); } private static void MenuProcessGroup(PwDocument ds, ToolStripMenuItem tsmiContainer, PwGroup pgSource) { if((pgSource.Groups.UCount == 0) && (pgSource.Entries.UCount == 0)) return; foreach(PwGroup pg in pgSource.Groups) { ToolStripMenuItem tsmi = MenuCreateGroup(ds, pg); tsmiContainer.DropDownItems.Add(tsmi); MenuProcessGroup(ds, tsmi, pg); } foreach(PwEntry pe in pgSource.Entries) MenuAddEntry(ds, tsmiContainer, pe); } private static void OnAutoType(object sender, EventArgs e) { ToolStripMenuItem tsmi = (sender as ToolStripMenuItem); Debug.Assert(tsmi != null); if(tsmi == null) return; PwEntry pe = (tsmi.Tag as PwEntry); Debug.Assert(pe != null); if(pe == null) return; try { AutoType.PerformIntoCurrentWindow(pe, Program.MainForm.DocumentManager.SafeFindContainerOf(pe)); } catch(Exception ex) { MessageService.ShowWarning(ex); } } private static void OnCopyField(object sender, string strField) { ToolStripMenuItem tsmi = (sender as ToolStripMenuItem); Debug.Assert(tsmi != null); if(tsmi == null) return; PwEntry pe = (tsmi.Tag as PwEntry); Debug.Assert(pe != null); if(pe == null) return; ClipboardUtil.Copy(pe.Strings.ReadSafe(strField), true, true, pe, Program.MainForm.DocumentManager.SafeFindContainerOf(pe), IntPtr.Zero); } private static void OnCopyUserName(object sender, EventArgs e) { OnCopyField(sender, PwDefs.UserNameField); } private static void OnCopyPassword(object sender, EventArgs e) { OnCopyField(sender, PwDefs.PasswordField); } } } KeePass/Util/Spr/0000775000000000000000000000000013222430416012567 5ustar rootrootKeePass/Util/Spr/SprEngine.PickChars.cs0000664000000000000000000002131013222430416016653 0ustar rootroot/* KeePass Password Safe - The Open-Source Password Manager Copyright (C) 2003-2018 Dominik Reichl This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ using System; using System.Collections.Generic; using System.Text; using System.Windows.Forms; using System.Diagnostics; using KeePass.Forms; using KeePass.UI; using KeePassLib; using KeePassLib.Security; using KeePassLib.Utility; namespace KeePass.Util.Spr { /// /// String placeholders and field reference replacement engine. /// public static partial class SprEngine { // Legacy, for backward compatibility only; see PickChars private static string ReplacePickPw(string strText, SprContext ctx, uint uRecursionLevel) { if(ctx.Entry == null) { Debug.Assert(false); return strText; } string str = strText; while(true) { const string strStart = @"{PICKPASSWORDCHARS"; int iStart = str.IndexOf(strStart, StrUtil.CaseIgnoreCmp); if(iStart < 0) break; int iEnd = str.IndexOf('}', iStart); if(iEnd < 0) break; string strPlaceholder = str.Substring(iStart, iEnd - iStart + 1); string strParam = str.Substring(iStart + strStart.Length, iEnd - (iStart + strStart.Length)); string[] vParams = strParam.Split(new char[] { ':' }); uint uCharCount = 0; if(vParams.Length >= 2) uint.TryParse(vParams[1], out uCharCount); str = ReplacePickPwPlaceholder(str, strPlaceholder, uCharCount, ctx, uRecursionLevel); } return str; } private static string ReplacePickPwPlaceholder(string str, string strPlaceholder, uint uCharCount, SprContext ctx, uint uRecursionLevel) { if(str.IndexOf(strPlaceholder, StrUtil.CaseIgnoreCmp) < 0) return str; ProtectedString ps = ctx.Entry.Strings.Get(PwDefs.PasswordField); if(ps != null) { string strPassword = ps.ReadString(); string strPick = SprEngine.CompileInternal(strPassword, ctx.WithoutContentTransformations(), uRecursionLevel + 1); if(!string.IsNullOrEmpty(strPick)) { ProtectedString psPick = new ProtectedString(false, strPick); string strPicked = (CharPickerForm.ShowAndRestore(psPick, true, true, uCharCount, null) ?? string.Empty); str = StrUtil.ReplaceCaseInsensitive(str, strPlaceholder, SprEngine.TransformContent(strPicked, ctx)); } } return StrUtil.ReplaceCaseInsensitive(str, strPlaceholder, string.Empty); } private static string ReplacePickChars(string strText, SprContext ctx, uint uRecursionLevel) { if(ctx.Entry == null) return strText; // No assert string str = strText; Dictionary dPicked = new Dictionary(); while(true) { const string strStart = @"{PICKCHARS"; int iStart = str.IndexOf(strStart, StrUtil.CaseIgnoreCmp); if(iStart < 0) break; int iEnd = str.IndexOf('}', iStart); if(iEnd < 0) break; string strPlaceholder = str.Substring(iStart, iEnd - iStart + 1); string strParam = str.Substring(iStart + strStart.Length, iEnd - (iStart + strStart.Length)); string strRep = string.Empty; bool bEncode = true; if(strParam.Length == 0) strRep = ShowCharPickDlg(ctx.Entry.Strings.ReadSafe( PwDefs.PasswordField), 0, null, ctx, uRecursionLevel); else if(strParam.StartsWith(":")) { string strParams = strParam.Substring(1); string[] vParams = strParams.Split(new char[] { ':' }, StringSplitOptions.None); string strField = string.Empty; if(vParams.Length >= 1) strField = (vParams[0] ?? string.Empty).Trim(); if(strField.Length == 0) strField = PwDefs.PasswordField; string strOptions = string.Empty; if(vParams.Length >= 2) strOptions = (vParams[1] ?? string.Empty); Dictionary dOptions = SplitParams(strOptions); string strID = GetParam(dOptions, "id", string.Empty).ToLower(); uint uCharCount = 0; if(dOptions.ContainsKey("c")) uint.TryParse(dOptions["c"], out uCharCount); if(dOptions.ContainsKey("count")) uint.TryParse(dOptions["count"], out uCharCount); bool? bInitHide = null; if(dOptions.ContainsKey("hide")) bInitHide = StrUtil.StringToBool(dOptions["hide"]); string strContent = ctx.Entry.Strings.ReadSafe(strField); if(strContent.Length == 0) { } // Leave strRep empty else if((strID.Length > 0) && dPicked.ContainsKey(strID)) strRep = dPicked[strID]; else strRep = ShowCharPickDlg(strContent, uCharCount, bInitHide, ctx, uRecursionLevel); if(strID.Length > 0) dPicked[strID] = strRep; if(dOptions.ContainsKey("conv")) { int iOffset = 0; if(dOptions.ContainsKey("conv-offset")) int.TryParse(dOptions["conv-offset"], out iOffset); string strConvFmt = GetParam(dOptions, "conv-fmt", string.Empty); string strConv = dOptions["conv"]; // Exists, see above if(strConv.Equals("d", StrUtil.CaseIgnoreCmp)) { strRep = ConvertToDownArrows(strRep, iOffset, strConvFmt); bEncode = false; } } } str = StrUtil.ReplaceCaseInsensitive(str, strPlaceholder, bEncode ? SprEngine.TransformContent(strRep, ctx) : strRep); } return str; } private static string ShowCharPickDlg(string strWord, uint uCharCount, bool? bInitHide, SprContext ctx, uint uRecursionLevel) { string strPick = SprEngine.CompileInternal(strWord, ctx.WithoutContentTransformations(), uRecursionLevel + 1); // No need to show the dialog when there's nothing to pick from // (this also prevents the dialog from showing up MaxRecursionDepth // times in case of a cyclic {PICKCHARS}) if(string.IsNullOrEmpty(strPick)) return string.Empty; ProtectedString psWord = new ProtectedString(false, strPick); string strPicked = CharPickerForm.ShowAndRestore(psWord, true, true, uCharCount, bInitHide); return (strPicked ?? string.Empty); // Don't transform here } private static string ConvertToDownArrows(string str, int iOffset, string strLayout) { if(string.IsNullOrEmpty(str)) return string.Empty; Dictionary dDowns = new Dictionary(); int iDowns = 0; foreach(char ch in strLayout) { if(ch == '0') AddCharSeq(dDowns, '0', '9', ref iDowns); else if(ch == '1') { AddCharSeq(dDowns, '1', '9', ref iDowns); AddCharSeq(dDowns, '0', '0', ref iDowns); } else if(ch == 'a') { AddCharSeq(dDowns, 'a', 'z', ref iDowns); if(strLayout.IndexOf('A') < 0) { iDowns -= 26; // Make case-insensitive AddCharSeq(dDowns, 'A', 'Z', ref iDowns); } } else if(ch == 'A') { AddCharSeq(dDowns, 'A', 'Z', ref iDowns); if(strLayout.IndexOf('a') < 0) { iDowns -= 26; // Make case-insensitive AddCharSeq(dDowns, 'a', 'z', ref iDowns); } } else if(ch == '?') ++iDowns; } // Defaults for undefined characters if(!dDowns.ContainsKey('0')) { iDowns = 0; AddCharSeq(dDowns, '0', '9', ref iDowns); } if(!dDowns.ContainsKey('a')) { iDowns = 0; AddCharSeq(dDowns, 'a', 'z', ref iDowns); iDowns = 0; AddCharSeq(dDowns, 'A', 'Z', ref iDowns); } else { Debug.Assert(dDowns.ContainsKey('A')); } StringBuilder sb = new StringBuilder(); for(int i = 0; i < str.Length; ++i) { // if((sb.Length > 0) && !string.IsNullOrEmpty(strSep)) sb.Append(strSep); char ch = str[i]; if(!dDowns.TryGetValue(ch, out iDowns)) continue; for(int j = 0; j < (iOffset + iDowns); ++j) sb.Append(@"{DOWN}"); } return sb.ToString(); } private static void AddCharSeq(Dictionary d, char chStart, char chLast, ref int iStart) { int p = iStart; for(char ch = chStart; ch <= chLast; ++ch) { // Prefer the first definition (less keypresses) if(!d.ContainsKey(ch)) d[ch] = p; ++p; } iStart = p; } } } KeePass/Util/Spr/SprEngine.cs0000664000000000000000000007751513222430416015027 0ustar rootroot/* KeePass Password Safe - The Open-Source Password Manager Copyright (C) 2003-2018 Dominik Reichl This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ using System; using System.Collections; using System.Collections.Generic; using System.Text; using System.Text.RegularExpressions; using System.IO; using System.Globalization; using System.Diagnostics; using KeePass.App.Configuration; using KeePass.Forms; using KeePassLib; using KeePassLib.Collections; using KeePassLib.Security; using KeePassLib.Utility; namespace KeePass.Util.Spr { /// /// String placeholders and field reference replacement engine. /// public static partial class SprEngine { private const uint MaxRecursionDepth = 12; private const StringComparison ScMethod = StringComparison.OrdinalIgnoreCase; private static string m_strAppExePath = string.Empty; // private static readonly char[] m_vPlhEscapes = new char[] { '{', '}', '%' }; // Important notes for plugin developers subscribing to the following events: // * If possible, prefer subscribing to FilterCompile instead of // FilterCompilePre. // * If your plugin provides an active transformation (e.g. replacing a // placeholder that changes some state or requires UI interaction), you // must only perform the transformation if the ExtActive bit is set in // args.Context.Flags of the event arguments object args provided to the // event handler. // * Non-active transformations should only be performed if the ExtNonActive // bit is set in args.Context.Flags. // * If your plugin provides a placeholder (like e.g. {EXAMPLE}), you // should add this placeholder to the FilterPlaceholderHints list // (e.g. add the string "{EXAMPLE}"). Please remove your strings from // the list when your plugin is terminated. public static event EventHandler FilterCompilePre; public static event EventHandler FilterCompile; private static List m_lFilterPlh = new List(); // See the events above public static List FilterPlaceholderHints { get { return m_lFilterPlh; } } private static void InitializeStatic() { m_strAppExePath = WinUtil.GetExecutable(); } [Obsolete] public static string Compile(string strText, bool bIsAutoTypeSequence, PwEntry pwEntry, PwDatabase pwDatabase, bool bEscapeForAutoType, bool bEscapeQuotesForCommandLine) { SprContext ctx = new SprContext(pwEntry, pwDatabase, SprCompileFlags.All, bEscapeForAutoType, bEscapeQuotesForCommandLine); return Compile(strText, ctx); } public static string Compile(string strText, SprContext ctx) { if(strText == null) { Debug.Assert(false); return string.Empty; } if(strText.Length == 0) return string.Empty; SprEngine.InitializeStatic(); if(ctx == null) ctx = new SprContext(); ctx.RefCache.Clear(); string str = SprEngine.CompileInternal(strText, ctx, 0); // if(bEscapeForAutoType && !bIsAutoTypeSequence) // str = SprEncoding.MakeAutoTypeSequence(str); return str; } private static string CompileInternal(string strText, SprContext ctx, uint uRecursionLevel) { if(strText == null) { Debug.Assert(false); return string.Empty; } if(ctx == null) { Debug.Assert(false); ctx = new SprContext(); } if(uRecursionLevel >= SprEngine.MaxRecursionDepth) { Debug.Assert(false); // Most likely a recursive reference return string.Empty; // Do not return strText (endless loop) } string str = strText; MainForm mf = Program.MainForm; bool bExt = ((ctx.Flags & (SprCompileFlags.ExtActive | SprCompileFlags.ExtNonActive)) != SprCompileFlags.None); if(bExt && (SprEngine.FilterCompilePre != null)) { SprEventArgs args = new SprEventArgs(str, ctx.Clone()); SprEngine.FilterCompilePre(null, args); str = args.Text; } if((ctx.Flags & SprCompileFlags.Comments) != SprCompileFlags.None) str = RemoveComments(str); // The following realizes {T-CONV:/Text/Raw/}, which should be // one of the first transformations (except comments) if((ctx.Flags & SprCompileFlags.TextTransforms) != SprCompileFlags.None) str = PerformTextTransforms(str, ctx, uRecursionLevel); if((ctx.Flags & SprCompileFlags.Run) != SprCompileFlags.None) str = RunCommands(str, ctx, uRecursionLevel); if((ctx.Flags & SprCompileFlags.AppPaths) != SprCompileFlags.None) str = AppLocator.FillPlaceholders(str, ctx); if(ctx.Entry != null) { if((ctx.Flags & SprCompileFlags.PickChars) != SprCompileFlags.None) str = ReplacePickPw(str, ctx, uRecursionLevel); if((ctx.Flags & SprCompileFlags.EntryStrings) != SprCompileFlags.None) str = FillEntryStrings(str, ctx, uRecursionLevel); if((ctx.Flags & SprCompileFlags.EntryStringsSpecial) != SprCompileFlags.None) { // ctx.UrlRemoveSchemeOnce = true; // str = SprEngine.FillIfExists(str, @"{URL:RMVSCM}", // ctx.Entry.Strings.GetSafe(PwDefs.UrlField), ctx, uRecursionLevel); // Debug.Assert(!ctx.UrlRemoveSchemeOnce); str = FillEntryStringsSpecial(str, ctx, uRecursionLevel); } if(((ctx.Flags & SprCompileFlags.PasswordEnc) != SprCompileFlags.None) && (str.IndexOf(@"{PASSWORD_ENC}", SprEngine.ScMethod) >= 0)) { string strPwCmp = SprEngine.FillIfExists(@"{PASSWORD}", @"{PASSWORD}", ctx.Entry.Strings.GetSafe(PwDefs.PasswordField), ctx.WithoutContentTransformations(), uRecursionLevel); str = SprEngine.FillPlaceholder(str, @"{PASSWORD_ENC}", StrUtil.EncryptString(strPwCmp), ctx); } PwGroup pg = ctx.Entry.ParentGroup; if(((ctx.Flags & SprCompileFlags.Group) != SprCompileFlags.None) && (pg != null)) str = FillGroupPlh(str, @"{GROUP", pg, ctx, uRecursionLevel); } if((ctx.Flags & SprCompileFlags.Paths) != SprCompileFlags.None) { if(mf != null) { PwGroup pgSel = mf.GetSelectedGroup(); if(pgSel != null) str = FillGroupPlh(str, @"{GROUP_SEL", pgSel, ctx, uRecursionLevel); } str = SprEngine.FillIfExists(str, @"{APPDIR}", new ProtectedString( false, UrlUtil.GetFileDirectory(m_strAppExePath, false, false)), ctx, uRecursionLevel); } if(ctx.Database != null) { if((ctx.Flags & SprCompileFlags.Paths) != SprCompileFlags.None) { // For backward compatibility only str = SprEngine.FillIfExists(str, @"{DOCDIR}", new ProtectedString( false, UrlUtil.GetFileDirectory(ctx.Database.IOConnectionInfo.Path, false, false)), ctx, uRecursionLevel); str = SprEngine.FillIfExists(str, @"{DB_PATH}", new ProtectedString( false, ctx.Database.IOConnectionInfo.Path), ctx, uRecursionLevel); str = SprEngine.FillIfExists(str, @"{DB_DIR}", new ProtectedString( false, UrlUtil.GetFileDirectory(ctx.Database.IOConnectionInfo.Path, false, false)), ctx, uRecursionLevel); str = SprEngine.FillIfExists(str, @"{DB_NAME}", new ProtectedString( false, UrlUtil.GetFileName(ctx.Database.IOConnectionInfo.Path)), ctx, uRecursionLevel); str = SprEngine.FillIfExists(str, @"{DB_BASENAME}", new ProtectedString( false, UrlUtil.StripExtension(UrlUtil.GetFileName( ctx.Database.IOConnectionInfo.Path))), ctx, uRecursionLevel); str = SprEngine.FillIfExists(str, @"{DB_EXT}", new ProtectedString( false, UrlUtil.GetExtension(ctx.Database.IOConnectionInfo.Path)), ctx, uRecursionLevel); } } if((ctx.Flags & SprCompileFlags.Paths) != SprCompileFlags.None) { str = SprEngine.FillIfExists(str, @"{ENV_DIRSEP}", new ProtectedString( false, Path.DirectorySeparatorChar.ToString()), ctx, uRecursionLevel); string strPF86 = Environment.GetEnvironmentVariable("ProgramFiles(x86)"); if(string.IsNullOrEmpty(strPF86)) strPF86 = Environment.GetFolderPath(Environment.SpecialFolder.ProgramFiles); if(strPF86 != null) str = SprEngine.FillIfExists(str, @"{ENV_PROGRAMFILES_X86}", new ProtectedString(false, strPF86), ctx, uRecursionLevel); else { Debug.Assert(false); } } if((ctx.Flags & SprCompileFlags.AutoType) != SprCompileFlags.None) { // Use Bksp instead of Del (in order to avoid Ctrl+Alt+Del); // https://sourceforge.net/p/keepass/discussion/329220/thread/4f1aa6b8/ str = StrUtil.ReplaceCaseInsensitive(str, @"{CLEARFIELD}", @"{HOME}+({END}){BKSP}{DELAY 50}"); } if((ctx.Flags & SprCompileFlags.DateTime) != SprCompileFlags.None) { DateTime dtNow = DateTime.UtcNow; str = SprEngine.FillIfExists(str, @"{DT_UTC_YEAR}", new ProtectedString( false, dtNow.Year.ToString("D4")), ctx, uRecursionLevel); str = SprEngine.FillIfExists(str, @"{DT_UTC_MONTH}", new ProtectedString( false, dtNow.Month.ToString("D2")), ctx, uRecursionLevel); str = SprEngine.FillIfExists(str, @"{DT_UTC_DAY}", new ProtectedString( false, dtNow.Day.ToString("D2")), ctx, uRecursionLevel); str = SprEngine.FillIfExists(str, @"{DT_UTC_HOUR}", new ProtectedString( false, dtNow.Hour.ToString("D2")), ctx, uRecursionLevel); str = SprEngine.FillIfExists(str, @"{DT_UTC_MINUTE}", new ProtectedString( false, dtNow.Minute.ToString("D2")), ctx, uRecursionLevel); str = SprEngine.FillIfExists(str, @"{DT_UTC_SECOND}", new ProtectedString( false, dtNow.Second.ToString("D2")), ctx, uRecursionLevel); str = SprEngine.FillIfExists(str, @"{DT_UTC_SIMPLE}", new ProtectedString( false, dtNow.ToString("yyyyMMddHHmmss")), ctx, uRecursionLevel); dtNow = dtNow.ToLocalTime(); str = SprEngine.FillIfExists(str, @"{DT_YEAR}", new ProtectedString( false, dtNow.Year.ToString("D4")), ctx, uRecursionLevel); str = SprEngine.FillIfExists(str, @"{DT_MONTH}", new ProtectedString( false, dtNow.Month.ToString("D2")), ctx, uRecursionLevel); str = SprEngine.FillIfExists(str, @"{DT_DAY}", new ProtectedString( false, dtNow.Day.ToString("D2")), ctx, uRecursionLevel); str = SprEngine.FillIfExists(str, @"{DT_HOUR}", new ProtectedString( false, dtNow.Hour.ToString("D2")), ctx, uRecursionLevel); str = SprEngine.FillIfExists(str, @"{DT_MINUTE}", new ProtectedString( false, dtNow.Minute.ToString("D2")), ctx, uRecursionLevel); str = SprEngine.FillIfExists(str, @"{DT_SECOND}", new ProtectedString( false, dtNow.Second.ToString("D2")), ctx, uRecursionLevel); str = SprEngine.FillIfExists(str, @"{DT_SIMPLE}", new ProtectedString( false, dtNow.ToString("yyyyMMddHHmmss")), ctx, uRecursionLevel); } if((ctx.Flags & SprCompileFlags.References) != SprCompileFlags.None) str = SprEngine.FillRefPlaceholders(str, ctx, uRecursionLevel); if(((ctx.Flags & SprCompileFlags.EnvVars) != SprCompileFlags.None) && (str.IndexOf('%') >= 0)) { // Replace environment variables foreach(DictionaryEntry de in Environment.GetEnvironmentVariables()) { string strKey = (de.Key as string); string strValue = (de.Value as string); if((strKey != null) && (strValue != null)) str = SprEngine.FillIfExists(str, @"%" + strKey + @"%", new ProtectedString(false, strValue), ctx, uRecursionLevel); else { Debug.Assert(false); } } } if((ctx.Flags & SprCompileFlags.Env) != SprCompileFlags.None) str = FillUriSpecial(str, ctx, @"{BASE", (ctx.Base ?? string.Empty), ctx.BaseIsEncoded, uRecursionLevel); str = EntryUtil.FillPlaceholders(str, ctx, uRecursionLevel); if((ctx.Flags & SprCompileFlags.PickChars) != SprCompileFlags.None) str = ReplacePickChars(str, ctx, uRecursionLevel); if(bExt && (SprEngine.FilterCompile != null)) { SprEventArgs args = new SprEventArgs(str, ctx.Clone()); SprEngine.FilterCompile(null, args); str = args.Text; } if(ctx.EncodeAsAutoTypeSequence) { str = StrUtil.NormalizeNewLines(str, false); str = str.Replace("\n", @"{ENTER}"); } return str; } private static string FillIfExists(string strData, string strPlaceholder, ProtectedString psParsable, SprContext ctx, uint uRecursionLevel) { // // The UrlRemoveSchemeOnce property of ctx must be cleared // // before this method returns and before any recursive call // bool bRemoveScheme = false; // if(ctx != null) // { // bRemoveScheme = ctx.UrlRemoveSchemeOnce; // ctx.UrlRemoveSchemeOnce = false; // } if(strData == null) { Debug.Assert(false); return string.Empty; } if(strPlaceholder == null) { Debug.Assert(false); return strData; } if(strPlaceholder.Length == 0) { Debug.Assert(false); return strData; } if(psParsable == null) { Debug.Assert(false); return strData; } if(strData.IndexOf(strPlaceholder, SprEngine.ScMethod) >= 0) { string strReplacement = SprEngine.CompileInternal( psParsable.ReadString(), ctx.WithoutContentTransformations(), uRecursionLevel + 1); // if(bRemoveScheme) // strReplacement = UrlUtil.RemoveScheme(strReplacement); return SprEngine.FillPlaceholder(strData, strPlaceholder, strReplacement, ctx); } return strData; } private static string FillPlaceholder(string strData, string strPlaceholder, string strReplaceWith, SprContext ctx) { if(strData == null) { Debug.Assert(false); return string.Empty; } if(strPlaceholder == null) { Debug.Assert(false); return strData; } if(strPlaceholder.Length == 0) { Debug.Assert(false); return strData; } if(strReplaceWith == null) { Debug.Assert(false); return strData; } return StrUtil.ReplaceCaseInsensitive(strData, strPlaceholder, SprEngine.TransformContent(strReplaceWith, ctx)); } public static string TransformContent(string strContent, SprContext ctx) { if(strContent == null) { Debug.Assert(false); return string.Empty; } string str = strContent; if(ctx != null) { if(ctx.EncodeForCommandLine) str = SprEncoding.EncodeForCommandLine(str); if(ctx.EncodeAsAutoTypeSequence) str = SprEncoding.EncodeAsAutoTypeSequence(str); } return str; } private static string FillEntryStrings(string str, SprContext ctx, uint uRecursionLevel) { List vKeys = ctx.Entry.Strings.GetKeys(); // Ensure that all standard field names are in the list // (this is required in order to replace the standard placeholders // even if the corresponding standard field isn't present in // the entry) List vStdNames = PwDefs.GetStandardFields(); foreach(string strStdField in vStdNames) { if(!vKeys.Contains(strStdField)) vKeys.Add(strStdField); } // Do not directly enumerate the strings in ctx.Entry.Strings, // because strings might change during the Spr compilation foreach(string strField in vKeys) { string strKey = (PwDefs.IsStandardField(strField) ? (@"{" + strField + @"}") : (@"{" + PwDefs.AutoTypeStringPrefix + strField + @"}")); if(!ctx.ForcePlainTextPasswords && strKey.Equals(@"{" + PwDefs.PasswordField + @"}", StrUtil.CaseIgnoreCmp) && Program.Config.MainWindow.IsColumnHidden(AceColumnType.Password)) { str = SprEngine.FillIfExists(str, strKey, new ProtectedString( false, PwDefs.HiddenPassword), ctx, uRecursionLevel); continue; } // Use GetSafe because the field doesn't necessarily exist // (might be a standard field that has been added above) str = SprEngine.FillIfExists(str, strKey, ctx.Entry.Strings.GetSafe( strField), ctx, uRecursionLevel); } return str; } private static string FillEntryStringsSpecial(string str, SprContext ctx, uint uRecursionLevel) { return FillUriSpecial(str, ctx, @"{URL", ctx.Entry.Strings.ReadSafe( PwDefs.UrlField), false, uRecursionLevel); } private static string FillUriSpecial(string strText, SprContext ctx, string strPlhInit, string strData, bool bDataIsEncoded, uint uRecursionLevel) { Debug.Assert(strPlhInit.StartsWith(@"{") && !strPlhInit.EndsWith(@"}")); Debug.Assert(strData != null); string[] vPlhs = new string[] { strPlhInit + @"}", strPlhInit + @":RMVSCM}", strPlhInit + @":SCM}", strPlhInit + @":HOST}", strPlhInit + @":PORT}", strPlhInit + @":PATH}", strPlhInit + @":QUERY}", strPlhInit + @":USERINFO}", strPlhInit + @":USERNAME}", strPlhInit + @":PASSWORD}" }; string str = strText; string strDataCmp = null; Uri uri = null; for(int i = 0; i < vPlhs.Length; ++i) { string strPlh = vPlhs[i]; if(str.IndexOf(strPlh, SprEngine.ScMethod) < 0) continue; if(strDataCmp == null) { SprContext ctxData = (bDataIsEncoded ? ctx.WithoutContentTransformations() : ctx); strDataCmp = SprEngine.CompileInternal(strData, ctxData, uRecursionLevel + 1); } string strRep = null; if(i == 0) strRep = strDataCmp; else if(i == 1) strRep = UrlUtil.RemoveScheme(strDataCmp); else { try { if(uri == null) uri = new Uri(strDataCmp); int t; switch(i) { case 2: strRep = uri.Scheme; break; case 3: strRep = uri.Host; break; case 4: strRep = uri.Port.ToString( NumberFormatInfo.InvariantInfo); break; case 5: strRep = uri.AbsolutePath; break; case 6: strRep = uri.Query; break; case 7: strRep = uri.UserInfo; break; case 8: strRep = uri.UserInfo; t = strRep.IndexOf(':'); if(t >= 0) strRep = strRep.Substring(0, t); break; case 9: strRep = uri.UserInfo; t = strRep.IndexOf(':'); if(t < 0) strRep = string.Empty; else strRep = strRep.Substring(t + 1); break; default: Debug.Assert(false); break; } } catch(Exception) { } // Invalid URI } if(strRep == null) strRep = string.Empty; // No assert str = StrUtil.ReplaceCaseInsensitive(str, strPlh, strRep); } return str; } private const string StrRemStart = @"{C:"; private const string StrRemEnd = @"}"; private static string RemoveComments(string strSeq) { string str = strSeq; while(true) { int iStart = str.IndexOf(StrRemStart, SprEngine.ScMethod); if(iStart < 0) break; int iEnd = str.IndexOf(StrRemEnd, iStart + 1, SprEngine.ScMethod); if(iEnd <= iStart) break; str = (str.Substring(0, iStart) + str.Substring(iEnd + StrRemEnd.Length)); } return str; } internal const string StrRefStart = @"{REF:"; internal const string StrRefEnd = @"}"; private static string FillRefPlaceholders(string strSeq, SprContext ctx, uint uRecursionLevel) { if(ctx.Database == null) return strSeq; string str = strSeq; int nOffset = 0; for(int iLoop = 0; iLoop < 20; ++iLoop) { str = ctx.RefCache.Fill(str, ctx); int nStart = str.IndexOf(StrRefStart, nOffset, SprEngine.ScMethod); if(nStart < 0) break; int nEnd = str.IndexOf(StrRefEnd, nStart + 1, SprEngine.ScMethod); if(nEnd <= nStart) break; string strFullRef = str.Substring(nStart, nEnd - nStart + 1); char chScan, chWanted; PwEntry peFound = FindRefTarget(strFullRef, ctx, out chScan, out chWanted); if(peFound != null) { string strInsData; if(chWanted == 'T') strInsData = peFound.Strings.ReadSafe(PwDefs.TitleField); else if(chWanted == 'U') strInsData = peFound.Strings.ReadSafe(PwDefs.UserNameField); else if(chWanted == 'A') strInsData = peFound.Strings.ReadSafe(PwDefs.UrlField); else if(chWanted == 'P') strInsData = peFound.Strings.ReadSafe(PwDefs.PasswordField); else if(chWanted == 'N') strInsData = peFound.Strings.ReadSafe(PwDefs.NotesField); else if(chWanted == 'I') strInsData = peFound.Uuid.ToHexString(); else { nOffset = nStart + 1; continue; } if((chWanted == 'P') && !ctx.ForcePlainTextPasswords && Program.Config.MainWindow.IsColumnHidden(AceColumnType.Password)) strInsData = PwDefs.HiddenPassword; SprContext sprSub = ctx.WithoutContentTransformations(); sprSub.Entry = peFound; string strInnerContent = SprEngine.CompileInternal(strInsData, sprSub, uRecursionLevel + 1); strInnerContent = SprEngine.TransformContent(strInnerContent, ctx); // str = str.Substring(0, nStart) + strInnerContent + str.Substring(nEnd + 1); ctx.RefCache.Add(strFullRef, strInnerContent, ctx); str = ctx.RefCache.Fill(str, ctx); } else { nOffset = nStart + 1; continue; } } return str; } public static PwEntry FindRefTarget(string strFullRef, SprContext ctx, out char chScan, out char chWanted) { chScan = char.MinValue; chWanted = char.MinValue; if(strFullRef == null) { Debug.Assert(false); return null; } if(!strFullRef.StartsWith(StrRefStart, SprEngine.ScMethod) || !strFullRef.EndsWith(StrRefEnd, SprEngine.ScMethod)) return null; if((ctx == null) || (ctx.Database == null)) { Debug.Assert(false); return null; } string strRef = strFullRef.Substring(StrRefStart.Length, strFullRef.Length - StrRefStart.Length - StrRefEnd.Length); if(strRef.Length <= 4) return null; if(strRef[1] != '@') return null; if(strRef[3] != ':') return null; chScan = char.ToUpper(strRef[2]); chWanted = char.ToUpper(strRef[0]); SearchParameters sp = SearchParameters.None; sp.SearchString = strRef.Substring(4); sp.RespectEntrySearchingDisabled = false; if(chScan == 'T') sp.SearchInTitles = true; else if(chScan == 'U') sp.SearchInUserNames = true; else if(chScan == 'A') sp.SearchInUrls = true; else if(chScan == 'P') sp.SearchInPasswords = true; else if(chScan == 'N') sp.SearchInNotes = true; else if(chScan == 'I') sp.SearchInUuids = true; else if(chScan == 'O') sp.SearchInOther = true; else return null; PwObjectList lFound = new PwObjectList(); ctx.Database.RootGroup.SearchEntries(sp, lFound); return ((lFound.UCount > 0) ? lFound.GetAt(0) : null); } // internal static bool MightChange(string strText) // { // if(string.IsNullOrEmpty(strText)) return false; // return (strText.IndexOfAny(m_vPlhEscapes) >= 0); // } /* internal static bool MightChange(string str) { if(str == null) { Debug.Assert(false); return false; } int iBStart = str.IndexOf('{'); if(iBStart >= 0) { int iBEnd = str.LastIndexOf('}'); if(iBStart < iBEnd) return true; } int iPFirst = str.IndexOf('%'); if(iPFirst >= 0) { int iPLast = str.LastIndexOf('%'); if(iPFirst < iPLast) return true; } return false; } */ internal static bool MightChange(char[] v) { if(v == null) { Debug.Assert(false); return false; } int iBStart = Array.IndexOf(v, '{'); if(iBStart >= 0) { int iBEnd = Array.LastIndexOf(v, '}'); if(iBStart < iBEnd) return true; } int iPFirst = Array.IndexOf(v, '%'); if(iPFirst >= 0) { int iPLast = Array.LastIndexOf(v, '%'); if(iPFirst < iPLast) return true; } return false; } /// /// Fast probabilistic test whether a string might be /// changed when compiling with SprCompileFlags.Deref. /// internal static bool MightDeref(string strText) { if(strText == null) return false; return (strText.IndexOf('{') >= 0); } internal static string DerefFn(string str, PwEntry pe) { if(!MightDeref(str)) return str; SprContext ctx = new SprContext(pe, Program.MainForm.DocumentManager.SafeFindContainerOf(pe), SprCompileFlags.Deref); // ctx.ForcePlainTextPasswords = false; return Compile(str, ctx); } /// /// Parse and remove a placeholder of the form /// {PLH:/Param1/Param2/.../}. /// internal static bool ParseAndRemovePlhWithParams(ref string str, SprContext ctx, uint uRecursionLevel, string strPlhStart, out int iStart, out List lParams, bool bSprCmpParams) { Debug.Assert(strPlhStart.StartsWith(@"{") && !strPlhStart.EndsWith(@"}")); iStart = str.IndexOf(strPlhStart, StrUtil.CaseIgnoreCmp); if(iStart < 0) { lParams = null; return false; } lParams = new List(); try { int p = iStart + strPlhStart.Length; if(p >= str.Length) throw new FormatException(); char chSep = str[p]; while(true) { if((p + 1) >= str.Length) throw new FormatException(); if(str[p + 1] == '}') break; int q = str.IndexOf(chSep, p + 1); if(q < 0) throw new FormatException(); lParams.Add(str.Substring(p + 1, q - p - 1)); p = q; } Debug.Assert(str[p + 1] == '}'); str = str.Remove(iStart, (p + 1) - iStart + 1); } catch(Exception) { str = str.Substring(0, iStart); } if(bSprCmpParams && (ctx != null)) { SprContext ctxSub = ctx.WithoutContentTransformations(); for(int i = 0; i < lParams.Count; ++i) lParams[i] = CompileInternal(lParams[i], ctxSub, uRecursionLevel); } return true; } private static string PerformTextTransforms(string strText, SprContext ctx, uint uRecursionLevel) { string str = strText; int iStart; List lParams; // {T-CONV:/Text/Raw/} should be the first transformation while(ParseAndRemovePlhWithParams(ref str, ctx, uRecursionLevel, @"{T-CONV:", out iStart, out lParams, true)) { if(lParams.Count < 2) continue; try { string strNew = lParams[0]; string strCmd = lParams[1].ToLower(); if((strCmd == "u") || (strCmd == "upper")) strNew = strNew.ToUpper(); else if((strCmd == "l") || (strCmd == "lower")) strNew = strNew.ToLower(); else if(strCmd == "base64") { byte[] pbUtf8 = StrUtil.Utf8.GetBytes(strNew); strNew = Convert.ToBase64String(pbUtf8); } else if(strCmd == "hex") { byte[] pbUtf8 = StrUtil.Utf8.GetBytes(strNew); strNew = MemUtil.ByteArrayToHexString(pbUtf8); } else if(strCmd == "uri") strNew = Uri.EscapeDataString(strNew); else if(strCmd == "uri-dec") strNew = Uri.UnescapeDataString(strNew); // "raw": no modification if(strCmd != "raw") strNew = TransformContent(strNew, ctx); str = str.Insert(iStart, strNew); } catch(Exception) { Debug.Assert(false); } } while(ParseAndRemovePlhWithParams(ref str, ctx, uRecursionLevel, @"{T-REPLACE-RX:", out iStart, out lParams, true)) { if(lParams.Count < 2) continue; if(lParams.Count == 2) lParams.Add(string.Empty); try { string strNew = Regex.Replace(lParams[0], lParams[1], lParams[2]); strNew = TransformContent(strNew, ctx); str = str.Insert(iStart, strNew); } catch(Exception) { } } return str; } private static string FillGroupPlh(string strData, string strPlhPrefix, PwGroup pg, SprContext ctx, uint uRecursionLevel) { Debug.Assert(strPlhPrefix.StartsWith("{")); Debug.Assert(!strPlhPrefix.EndsWith("_")); Debug.Assert(!strPlhPrefix.EndsWith("}")); string str = strData; str = SprEngine.FillIfExists(str, strPlhPrefix + @"}", new ProtectedString(false, pg.Name), ctx, uRecursionLevel); ProtectedString psGroupPath = new ProtectedString(false, pg.GetFullPath()); str = SprEngine.FillIfExists(str, strPlhPrefix + @"_PATH}", psGroupPath, ctx, uRecursionLevel); str = SprEngine.FillIfExists(str, strPlhPrefix + @"PATH}", psGroupPath, ctx, uRecursionLevel); // Obsolete; for backward compatibility str = SprEngine.FillIfExists(str, strPlhPrefix + @"_NOTES}", new ProtectedString(false, pg.Notes), ctx, uRecursionLevel); return str; } private static string RunCommands(string strText, SprContext ctx, uint uRecursionLevel) { string str = strText; int iStart; List lParams; while(ParseAndRemovePlhWithParams(ref str, ctx, uRecursionLevel, @"{CMD:", out iStart, out lParams, true)) { if(lParams.Count == 0) continue; string strCmd = lParams[0]; if(string.IsNullOrEmpty(strCmd)) continue; try { const StringComparison sc = StrUtil.CaseIgnoreCmp; string strOpt = ((lParams.Count >= 2) ? lParams[1] : string.Empty); Dictionary d = SplitParams(strOpt); ProcessStartInfo psi = new ProcessStartInfo(); string strApp, strArgs; StrUtil.SplitCommandLine(strCmd, out strApp, out strArgs); if(string.IsNullOrEmpty(strApp)) continue; psi.FileName = strApp; if(!string.IsNullOrEmpty(strArgs)) psi.Arguments = strArgs; string strMethod = GetParam(d, "m", "s"); bool bShellExec = !strMethod.Equals("c", sc); psi.UseShellExecute = bShellExec; string strO = GetParam(d, "o", (bShellExec ? "0" : "1")); bool bStdOut = strO.Equals("1", sc); if(bStdOut) psi.RedirectStandardOutput = true; string strWS = GetParam(d, "ws", "n"); if(strWS.Equals("h", sc)) { psi.CreateNoWindow = true; psi.WindowStyle = ProcessWindowStyle.Hidden; } else if(strWS.Equals("min", sc)) psi.WindowStyle = ProcessWindowStyle.Minimized; else if(strWS.Equals("max", sc)) psi.WindowStyle = ProcessWindowStyle.Maximized; else { Debug.Assert(psi.WindowStyle == ProcessWindowStyle.Normal); } string strVerb = GetParam(d, "v", null); if(!string.IsNullOrEmpty(strVerb)) psi.Verb = strVerb; bool bWait = GetParam(d, "w", "1").Equals("1", sc); Process p = Process.Start(psi); if(p == null) { Debug.Assert(false); continue; } if(bStdOut) { string strOut = p.StandardOutput.ReadToEnd(); strOut = TransformContent(strOut, ctx); str = str.Insert(iStart, strOut); } if(bWait) p.WaitForExit(); } catch(Exception ex) { string strMsg = strCmd + MessageService.NewParagraph + ex.Message; MessageService.ShowWarning(strMsg); } } return str; } private static Dictionary SplitParams(string str) { Dictionary d = new Dictionary(); if(string.IsNullOrEmpty(str)) return d; char[] vSplitPrm = new char[] { ',' }; char[] vSplitKvp = new char[] { '=' }; string[] v = str.Split(vSplitPrm); foreach(string strOption in v) { if(string.IsNullOrEmpty(strOption)) continue; string[] vKvp = strOption.Split(vSplitKvp); if(vKvp.Length != 2) continue; string strKey = (vKvp[0] ?? string.Empty).Trim().ToLower(); string strValue = (vKvp[1] ?? string.Empty).Trim(); d[strKey] = strValue; } return d; } private static string GetParam(Dictionary d, string strName, string strDefaultValue) { if(d == null) { Debug.Assert(false); return strDefaultValue; } if(strName == null) { Debug.Assert(false); return strDefaultValue; } Debug.Assert(strName == strName.ToLower()); string strValue; if(d.TryGetValue(strName, out strValue)) return strValue; return strDefaultValue; } } } KeePass/Util/Spr/SprContext.cs0000664000000000000000000001363213222430416015234 0ustar rootroot/* KeePass Password Safe - The Open-Source Password Manager Copyright (C) 2003-2018 Dominik Reichl This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ using System; using System.Collections.Generic; using System.Text; using System.Diagnostics; using KeePassLib; using KeePassLib.Interfaces; namespace KeePass.Util.Spr { [Flags] public enum SprCompileFlags { None = 0, AppPaths = 0x1, // Paths to IE, Firefox, Opera, ... PickChars = 0x2, // {PICKCHARS}, {PICKFIELD} EntryStrings = 0x4, EntryStringsSpecial = 0x8, // {URL:RMVSCM}, ... PasswordEnc = 0x10, Group = 0x20, Paths = 0x40, // App-dir, doc-dir, path sep, ... AutoType = 0x80, // Replacements like {CLEARFIELD}, ... DateTime = 0x100, References = 0x200, EnvVars = 0x400, NewPassword = 0x800, HmacOtp = 0x1000, Comments = 0x2000, TextTransforms = 0x10000, Env = 0x20000, // {BASE}, ... Run = 0x40000, // Running other (console) applications ExtActive = 0x4000, // Active transformations provided by plugins ExtNonActive = 0x8000, // Non-active transformations provided by plugins // Next free: 0x80000 All = 0x7FFFF, // Internal: UIInteractive = (SprCompileFlags.PickChars | SprCompileFlags.Run), StateChanging = (SprCompileFlags.NewPassword | SprCompileFlags.HmacOtp), Active = (SprCompileFlags.UIInteractive | SprCompileFlags.StateChanging | SprCompileFlags.ExtActive), NonActive = (SprCompileFlags.All & ~SprCompileFlags.Active), Deref = (SprCompileFlags.EntryStrings | SprCompileFlags.EntryStringsSpecial | SprCompileFlags.References) } public sealed class SprContext { private PwEntry m_pe = null; public PwEntry Entry { get { return m_pe; } set { m_pe = value; } } private PwDatabase m_pd = null; public PwDatabase Database { get { return m_pd; } set { m_pd = value; } } private string m_strBase = null; /// /// The parent string, like e.g. the input string before any /// override has been applied. /// public string Base { get { return m_strBase; } set { m_strBase = value; } } private bool m_bBaseIsEnc = false; /// /// Specifies whether Base has been content-transformed already. /// public bool BaseIsEncoded { get { return m_bBaseIsEnc; } set { m_bBaseIsEnc = value; } } private bool m_bMakeAT = false; public bool EncodeAsAutoTypeSequence { get { return m_bMakeAT; } set { m_bMakeAT = value; } } private bool m_bMakeCmd = false; public bool EncodeForCommandLine { get { return m_bMakeCmd; } set { m_bMakeCmd = value; } } private bool m_bForcePlainTextPasswords = true; public bool ForcePlainTextPasswords { get { return m_bForcePlainTextPasswords; } set { m_bForcePlainTextPasswords = value; } } private SprCompileFlags m_flags = SprCompileFlags.All; public SprCompileFlags Flags { get { return m_flags; } set { m_flags = value; } } private SprRefCache m_refCache = new SprRefCache(); /// /// Used internally by SprEngine; don't modify it. /// internal SprRefCache RefCache { get { return m_refCache; } } // private bool m_bNoUrlSchemeOnce = false; // /// // /// Used internally by SprEngine; don't modify it. // /// // internal bool UrlRemoveSchemeOnce // { // get { return m_bNoUrlSchemeOnce; } // set { m_bNoUrlSchemeOnce = value; } // } public SprContext() { } public SprContext(PwEntry pe, PwDatabase pd, SprCompileFlags fl) { Init(pe, pd, false, false, fl); } public SprContext(PwEntry pe, PwDatabase pd, SprCompileFlags fl, bool bEncodeAsAutoTypeSequence, bool bEncodeForCommandLine) { Init(pe, pd, bEncodeAsAutoTypeSequence, bEncodeForCommandLine, fl); } private void Init(PwEntry pe, PwDatabase pd, bool bAT, bool bCmd, SprCompileFlags fl) { m_pe = pe; m_pd = pd; m_bMakeAT = bAT; m_bMakeCmd = bCmd; m_flags = fl; } public SprContext Clone() { return (SprContext)this.MemberwiseClone(); } /// /// Used by SprEngine internally; do not use. /// internal SprContext WithoutContentTransformations() { SprContext ctx = Clone(); ctx.m_bMakeAT = false; ctx.m_bMakeCmd = false; // ctx.m_bNoUrlSchemeOnce = false; Debug.Assert(object.ReferenceEquals(m_pe, ctx.m_pe)); Debug.Assert(object.ReferenceEquals(m_pd, ctx.m_pd)); Debug.Assert(object.ReferenceEquals(m_refCache, ctx.m_refCache)); return ctx; } } public sealed class SprEventArgs : EventArgs { private string m_str = string.Empty; public string Text { get { return m_str; } set { if(value == null) throw new ArgumentNullException("value"); m_str = value; } } private SprContext m_ctx = null; public SprContext Context { get { return m_ctx; } } public SprEventArgs() { } public SprEventArgs(string strText, SprContext ctx) { if(strText == null) throw new ArgumentNullException("strText"); // ctx == null is allowed m_str = strText; m_ctx = ctx; } } } KeePass/Util/Spr/SprSyntax.cs0000664000000000000000000002255213222430416015077 0ustar rootroot/* KeePass Password Safe - The Open-Source Password Manager Copyright (C) 2003-2018 Dominik Reichl This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ using System; using System.Collections.Generic; using System.Text; using System.Drawing; using System.Windows.Forms; using System.Diagnostics; using KeePass.App; using KeePassLib; using KeePassLib.Utility; namespace KeePass.Util.Spr { public static class SprSyntax { private static readonly string[] m_vDynSepPlh = new string[] { @"{NEWPASSWORD:", @"{T-REPLACE-RX:", @"{T-CONV:", @"{CMD:" }; private static readonly SprStyle SprStyleOK = new SprStyle( Color.FromArgb(0, 128, 0)); // Color.FromArgb(212, 255, 212)); private static readonly SprStyle SprStyleRaw = new SprStyle( Color.FromArgb(0, 0, 224)); // Color.FromArgb(214, 226, 255)); private static readonly SprStyle SprStyleWarning = new SprStyle( Color.FromArgb(255, 106, 0)); // AppDefs.ColorEditError); private static readonly SprStyle SprStyleError = new SprStyle( Color.FromArgb(224, 0, 0)); // AppDefs.ColorEditError); private sealed class SprStyle : IEquatable // Immutable { private readonly Color? m_clr; public Color? Color { get { return m_clr; } } public SprStyle(Color? clr) { m_clr = clr; } public bool Equals(SprStyle other) { if(other == null) return false; if(m_clr.HasValue != other.m_clr.HasValue) return false; if(m_clr.HasValue) { if(m_clr.Value != other.m_clr.Value) return false; } return true; } } private sealed class SprPart // Immutable { private readonly string m_str; public string Text { get { return m_str; } } private readonly int m_iStart; public int Start { get { return m_iStart; } } public SprPart(string str, int iStart) { if(str == null) throw new ArgumentNullException("str"); m_str = str; m_iStart = iStart; } public SprPart GetPart(int iOffset) { return GetPart(iOffset, m_str.Length - iOffset); } public SprPart GetPart(int iOffset, int nLength) { if(iOffset < 0) throw new ArgumentOutOfRangeException("iOffset"); if(nLength < 0) throw new ArgumentOutOfRangeException("nLength"); if((iOffset + nLength) > m_str.Length) throw new ArgumentException(); SprPart pSub = new SprPart(m_str.Substring(iOffset, nLength), m_iStart + iOffset); return pSub; } } public static void Highlight(RichTextBox rtb, SprContext ctx) { try { HighlightPriv(rtb, ctx); } catch(Exception) { Debug.Assert(false); } } private static void HighlightPriv(RichTextBox rtb, SprContext ctx) { if(rtb == null) { Debug.Assert(false); return; } int iSelStart = rtb.SelectionStart; int iSelLen = rtb.SelectionLength; string strText = rtb.Text; rtb.SelectAll(); // rtb.SelectionBackColor = SystemColors.Window; rtb.SelectionColor = SystemColors.ControlText; List l = GetHighlight(strText, ctx); l.Add(null); // Sentinel SprStyle sFrom = null; int pFrom = 0; for(int i = 0; i < l.Count; ++i) { SprStyle s = l[i]; if(sFrom != null) { if((s == null) || !sFrom.Equals(s)) { if(sFrom.Color.HasValue) { rtb.Select(pFrom, i - pFrom); rtb.SelectionColor = sFrom.Color.Value; // rtb.SelectionBackColor = sFrom.Color.Value; } sFrom = s; pFrom = i; } } else { sFrom = s; pFrom = i; } } rtb.Select(iSelStart, iSelLen); } private static List GetHighlight(string str, SprContext ctx) { if(str == null) { Debug.Assert(false); return new List(); } List l = new List(str.Length + 1); // 1 for sentinel for(int i = 0; i < str.Length; ++i) l.Add(null); Stack sToDo = new Stack(); sToDo.Push(new SprPart(str, 0)); while(sToDo.Count > 0) { SprPart p = sToDo.Pop(); Debug.Assert(p.Start >= 0); Debug.Assert((p.Start + p.Text.Length) <= l.Count); Debug.Assert(str.Substring(p.Start, p.Text.Length) == p.Text); HighlightPart(p, l, sToDo, ctx); } return l; } private static void HighlightPart(SprPart p, List lStyles, Stack sToDo, SprContext ctx) { if(p.Text.Length == 0) return; if(HighlightDynSepPlh(p, lStyles, sToDo)) return; if(HighlightRegularPlh(p, lStyles, sToDo, ctx)) return; HighlightInvalid(p, lStyles, sToDo, ctx); } private static bool HighlightDynSepPlh(SprPart pPart, List lStyles, Stack sToDo) { string str = pPart.Text; int iStart = -1, p = -1; foreach(string strPlh in m_vDynSepPlh) { iStart = str.IndexOf(strPlh, StrUtil.CaseIgnoreCmp); if(iStart >= 0) { p = iStart + strPlh.Length; break; } } if(iStart < 0) return false; try { if(p >= str.Length) throw new FormatException(); char chSep = str[p]; while(true) { if((p + 1) >= str.Length) throw new FormatException(); if(str[p + 1] == '}') break; int q = str.IndexOf(chSep, p + 1); if(q < 0) throw new FormatException(); p = q; } Debug.Assert(str[p + 1] == '}'); if((p + 2) < str.Length) sToDo.Push(pPart.GetPart(p + 2)); SetStyle(lStyles, pPart, iStart, (p + 1) - iStart + 1, SprStyleRaw); } catch(Exception) { SetStyle(lStyles, pPart, iStart, str.Length - iStart, SprStyleError); } if(iStart > 0) sToDo.Push(pPart.GetPart(0, iStart)); return true; } private static bool HighlightRegularPlh(SprPart pPart, List lStyles, Stack sToDo, SprContext ctx) { string str = pPart.Text; int iStart = str.IndexOf('{'); if(iStart < 0) return false; if((iStart + 2) >= str.Length) SetStyle(lStyles, pPart, iStart, str.Length - iStart, SprStyleError); else { int iOpen = str.IndexOf('{', iStart + 2); int iClose = str.IndexOf('}', iStart + 2); bool bAT = ((ctx != null) && ctx.EncodeAsAutoTypeSequence); if(iClose < 0) SetStyle(lStyles, pPart, iStart, str.Length - iStart, SprStyleError); else if((iOpen >= 0) && (iOpen < iClose)) { sToDo.Push(pPart.GetPart(iOpen)); SetStyle(lStyles, pPart, iStart, iOpen - iStart, SprStyleError); } else if(bAT && ((str[iStart + 1] == '{') || (str[iStart + 1] == '}')) && (iClose != (iStart + 2))) { sToDo.Push(pPart.GetPart(iClose + 1)); SetStyle(lStyles, pPart, iStart, iClose - iStart + 1, SprStyleError); } else { sToDo.Push(pPart.GetPart(iClose + 1)); int iErrLvl = 0; string strPlh = str.Substring(iStart + 1, iClose - iStart - 1); if(strPlh.Length == 0) { Debug.Assert(false); iErrLvl = 2; } else if(char.IsWhiteSpace(strPlh[0])) iErrLvl = 2; else if(strPlh.StartsWith("S:", StrUtil.CaseIgnoreCmp) && (ctx != null) && (ctx.Entry != null)) { string strField = strPlh.Substring(2); List lFields = PwDefs.GetStandardFields(); lFields.AddRange(ctx.Entry.Strings.GetKeys()); bool bFound = false; foreach(string strAvail in lFields) { if(strField.Equals(strAvail, StrUtil.CaseIgnoreCmp)) { bFound = true; break; } } if(!bFound) iErrLvl = 1; } SprStyle s = SprStyleOK; if(iErrLvl == 1) s = SprStyleWarning; else if(iErrLvl > 1) s = SprStyleError; SetStyle(lStyles, pPart, iStart, iClose - iStart + 1, s); } } if(iStart > 0) sToDo.Push(pPart.GetPart(0, iStart)); return true; } private static bool HighlightInvalid(SprPart pPart, List lStyles, Stack sToDo, SprContext ctx) { bool bAT = ((ctx != null) && ctx.EncodeAsAutoTypeSequence); if(!bAT) return false; string str = pPart.Text; int p = str.IndexOf('}'); if(p >= 0) { Debug.Assert(str.IndexOf('{') < 0); // Must be called after regular sToDo.Push(pPart.GetPart(p + 1)); SetStyle(lStyles, pPart, 0, p + 1, SprStyleError); return true; } return false; } private static void SetStyle(List l, SprPart p, int iPartOffset, int nLength, SprStyle s) { int px = p.Start + iPartOffset; if(px < 0) { Debug.Assert(false); return; } if(nLength < 0) { Debug.Assert(false); return; } if((px + nLength) > l.Count) { Debug.Assert(false); return; } for(int i = 0; i < nLength; ++i) { Debug.Assert(l[px + i] == null); l[px + i] = s; } } } } KeePass/Util/Spr/SprEncoding.cs0000664000000000000000000000547713222430416015346 0ustar rootroot/* KeePass Password Safe - The Open-Source Password Manager Copyright (C) 2003-2018 Dominik Reichl This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ using System; using System.Collections.Generic; using System.Diagnostics; using System.Text; using KeePassLib.Native; using KeePassLib.Utility; namespace KeePass.Util.Spr { internal static class SprEncoding { internal static string EncodeAsAutoTypeSequence(string str) { if(str == null) { Debug.Assert(false); return string.Empty; } str = SprEncoding.EscapeAutoTypeBrackets(str); str = str.Replace(@"[", @"{[}"); str = str.Replace(@"]", @"{]}"); str = str.Replace(@"+", @"{+}"); str = str.Replace(@"%", @"{%}"); str = str.Replace(@"~", @"{~}"); str = str.Replace(@"(", @"{(}"); str = str.Replace(@")", @"{)}"); str = str.Replace(@"^", @"{^}"); return str; } private static string EscapeAutoTypeBrackets(string str) { char chOpen = '\u25A1'; while(str.IndexOf(chOpen) >= 0) ++chOpen; char chClose = chOpen; ++chClose; while(str.IndexOf(chClose) >= 0) ++chClose; str = str.Replace('{', chOpen); str = str.Replace('}', chClose); str = str.Replace(new string(chOpen, 1), @"{{}"); str = str.Replace(new string(chClose, 1), @"{}}"); return str; } internal static string EncodeForCommandLine(string strRaw) { if(strRaw == null) { Debug.Assert(false); return string.Empty; } if(MonoWorkarounds.IsRequired(3471228285U) && NativeLib.IsUnix()) { string str = strRaw; str = str.Replace("\\", "\\\\"); str = str.Replace("\"", "\\\""); str = str.Replace("\'", "\\\'"); str = str.Replace("\u0060", "\\\u0060"); // Grave accent str = str.Replace("$", "\\$"); str = str.Replace("&", "\\&"); str = str.Replace("<", "\\<"); str = str.Replace(">", "\\>"); str = str.Replace("|", "\\|"); str = str.Replace(";", "\\;"); str = str.Replace("(", "\\("); str = str.Replace(")", "\\)"); return str; } // See SHELLEXECUTEINFO structure documentation return strRaw.Replace("\"", "\"\"\""); } } } KeePass/Util/Spr/SprRefCache.cs0000664000000000000000000000614313222430416015247 0ustar rootroot/* KeePass Password Safe - The Open-Source Password Manager Copyright (C) 2003-2018 Dominik Reichl This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ using System; using System.Collections.Generic; using System.Diagnostics; using System.Text; using KeePassLib.Utility; namespace KeePass.Util.Spr { internal sealed class SprRefCache { private sealed class SprRefCacheItem { public readonly string Ref; public readonly string Value; public readonly uint Context; public SprRefCacheItem(string strRef, string strValue, uint uContext) { this.Ref = strRef; this.Value = strValue; this.Context = uContext; } } private List m_l = new List(); public SprRefCache() { } /// /// Hash all settings of that may /// affect the encoded value of a field reference. /// private static uint HashContext(SprContext ctx) { if(ctx == null) { Debug.Assert(false); return 0; } uint u = 0; if(ctx.ForcePlainTextPasswords) u |= 1; if(ctx.EncodeForCommandLine) u |= 2; if(ctx.EncodeAsAutoTypeSequence) u |= 4; return u; } public void Clear() { m_l.Clear(); } private string Get(string strRef, uint uCtx) { if(strRef == null) { Debug.Assert(false); return null; } foreach(SprRefCacheItem ci in m_l) { if(ci.Context != uCtx) continue; if(string.Equals(strRef, ci.Ref, StrUtil.CaseIgnoreCmp)) return ci.Value; } return null; } public bool Add(string strRef, string strValue, SprContext ctx) { if(strRef == null) throw new ArgumentNullException("strRef"); if(strValue == null) throw new ArgumentNullException("strValue"); uint uCtx = HashContext(ctx); if(Get(strRef, uCtx) != null) { Debug.Assert(false); return false; // Exists already, do not overwrite } m_l.Add(new SprRefCacheItem(strRef, strValue, uCtx)); return true; } public string Fill(string strText, SprContext ctx) { if(strText == null) { Debug.Assert(false); return string.Empty; } string str = strText; uint uCtx = HashContext(ctx); foreach(SprRefCacheItem ci in m_l) { if(ci.Context != uCtx) continue; // str = str.Replace(ci.Ref, ci.Value); str = StrUtil.ReplaceCaseInsensitive(str, ci.Ref, ci.Value); } return str; } } } KeePass/Program.cs0000664000000000000000000006026013222450030013042 0ustar rootroot/* KeePass Password Safe - The Open-Source Password Manager Copyright (C) 2003-2018 Dominik Reichl This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ using System; using System.Collections; using System.Collections.Generic; using System.Diagnostics; using System.Drawing; using System.Drawing.Imaging; using System.Globalization; using System.IO; using System.Reflection; using System.Resources; using System.Security.AccessControl; using System.Security.Principal; using System.Threading; using System.Windows.Forms; using KeePass.App; using KeePass.App.Configuration; using KeePass.DataExchange; using KeePass.Ecas; using KeePass.Forms; using KeePass.Native; using KeePass.Plugins; using KeePass.Resources; using KeePass.UI; using KeePass.Util; using KeePass.Util.Archive; using KeePass.Util.XmlSerialization; using KeePassLib; using KeePassLib.Cryptography; using KeePassLib.Cryptography.Cipher; using KeePassLib.Cryptography.PasswordGenerator; using KeePassLib.Keys; using KeePassLib.Resources; using KeePassLib.Security; using KeePassLib.Serialization; using KeePassLib.Translation; using KeePassLib.Utility; using NativeLib = KeePassLib.Native.NativeLib; namespace KeePass { public static class Program { private const string m_strWndMsgID = "EB2FE38E1A6A4A138CF561442F1CF25A"; private static CommandLineArgs m_cmdLineArgs = null; private static Random m_rndGlobal = null; private static int m_nAppMessage = 0; private static MainForm m_formMain = null; private static AppConfigEx m_appConfig = null; private static KeyProviderPool m_keyProviderPool = null; private static KeyValidatorPool m_keyValidatorPool = null; private static FileFormatPool m_fmtPool = null; private static KPTranslation m_kpTranslation = new KPTranslation(); private static TempFilesPool m_tempFilesPool = null; private static EcasPool m_ecasPool = null; private static EcasTriggerSystem m_ecasTriggers = null; private static CustomPwGeneratorPool m_pwGenPool = null; private static ColumnProviderPool m_colProvPool = null; private static bool m_bDesignMode = true; #if DEBUG private static bool m_bDesignModeQueried = false; #endif public enum AppMessage { Null = 0, RestoreWindow = 1, Exit = 2, IpcByFile = 3, AutoType = 4, Lock = 5, Unlock = 6, AutoTypeSelected = 7 } public static CommandLineArgs CommandLineArgs { get { if(m_cmdLineArgs == null) { Debug.Assert(false); m_cmdLineArgs = new CommandLineArgs(null); } return m_cmdLineArgs; } } public static Random GlobalRandom { get { return m_rndGlobal; } } public static int ApplicationMessage { get { return m_nAppMessage; } } public static MainForm MainForm { get { return m_formMain; } } public static AppConfigEx Config { get { if(m_appConfig == null) m_appConfig = new AppConfigEx(); return m_appConfig; } } public static KeyProviderPool KeyProviderPool { get { if(m_keyProviderPool == null) m_keyProviderPool = new KeyProviderPool(); return m_keyProviderPool; } } public static KeyValidatorPool KeyValidatorPool { get { if(m_keyValidatorPool == null) m_keyValidatorPool = new KeyValidatorPool(); return m_keyValidatorPool; } } public static FileFormatPool FileFormatPool { get { if(m_fmtPool == null) m_fmtPool = new FileFormatPool(); return m_fmtPool; } } public static KPTranslation Translation { get { return m_kpTranslation; } } public static TempFilesPool TempFilesPool { get { if(m_tempFilesPool == null) m_tempFilesPool = new TempFilesPool(); return m_tempFilesPool; } } public static EcasPool EcasPool // Construct on first access { get { if(m_ecasPool == null) m_ecasPool = new EcasPool(true); return m_ecasPool; } } public static EcasTriggerSystem TriggerSystem { get { if(m_ecasTriggers == null) m_ecasTriggers = new EcasTriggerSystem(); return m_ecasTriggers; } } public static CustomPwGeneratorPool PwGeneratorPool { get { if(m_pwGenPool == null) m_pwGenPool = new CustomPwGeneratorPool(); return m_pwGenPool; } } public static ColumnProviderPool ColumnProviderPool { get { if(m_colProvPool == null) m_colProvPool = new ColumnProviderPool(); return m_colProvPool; } } public static ResourceManager Resources { get { return KeePass.Properties.Resources.ResourceManager; } } public static bool DesignMode { get { #if DEBUG m_bDesignModeQueried = true; #endif return m_bDesignMode; } } /// /// Main entry point for the application. /// [STAThread] public static void Main(string[] args) { #if DEBUG MainPriv(args); #else try { MainPriv(args); } catch(Exception ex) { ShowFatal(ex); } #endif } private static void MainPriv(string[] args) { #if DEBUG // Program.DesignMode should not be queried before executing // Main (e.g. by a static Control) when running the program // normally Debug.Assert(!m_bDesignModeQueried); #endif m_bDesignMode = false; // Designer doesn't call Main method m_cmdLineArgs = new CommandLineArgs(args); // Before loading the configuration string strWaDisable = m_cmdLineArgs[ AppDefs.CommandLineOptions.WorkaroundDisable]; if(!string.IsNullOrEmpty(strWaDisable)) MonoWorkarounds.SetEnabled(strWaDisable, false); DpiUtil.ConfigureProcess(); Application.EnableVisualStyles(); Application.SetCompatibleTextRenderingDefault(false); Application.DoEvents(); // Required #if DEBUG string strInitialWorkDir = WinUtil.GetWorkingDirectory(); #endif if(!CommonInit()) { CommonTerminate(); return; } if(m_appConfig.Application.Start.PluginCacheClearOnce) { PlgxCache.Clear(); m_appConfig.Application.Start.PluginCacheClearOnce = false; AppConfigSerializer.Save(Program.Config); } if(m_cmdLineArgs[AppDefs.CommandLineOptions.FileExtRegister] != null) { ShellUtil.RegisterExtension(AppDefs.FileExtension.FileExt, AppDefs.FileExtension.ExtId, KPRes.FileExtName, WinUtil.GetExecutable(), PwDefs.ShortProductName, false); MainCleanUp(); return; } if(m_cmdLineArgs[AppDefs.CommandLineOptions.FileExtUnregister] != null) { ShellUtil.UnregisterExtension(AppDefs.FileExtension.FileExt, AppDefs.FileExtension.ExtId); MainCleanUp(); return; } if(m_cmdLineArgs[AppDefs.CommandLineOptions.PreLoad] != null) { // All important .NET assemblies are in memory now already try { SelfTest.Perform(); } catch(Exception) { Debug.Assert(false); } MainCleanUp(); return; } /* if(m_cmdLineArgs[AppDefs.CommandLineOptions.PreLoadRegister] != null) { string strPreLoadPath = WinUtil.GetExecutable().Trim(); if(strPreLoadPath.StartsWith("\"") == false) strPreLoadPath = "\"" + strPreLoadPath + "\""; ShellUtil.RegisterPreLoad(AppDefs.PreLoadName, strPreLoadPath, @"--" + AppDefs.CommandLineOptions.PreLoad, true); MainCleanUp(); return; } if(m_cmdLineArgs[AppDefs.CommandLineOptions.PreLoadUnregister] != null) { ShellUtil.RegisterPreLoad(AppDefs.PreLoadName, string.Empty, string.Empty, false); MainCleanUp(); return; } */ if((m_cmdLineArgs[AppDefs.CommandLineOptions.Help] != null) || (m_cmdLineArgs[AppDefs.CommandLineOptions.HelpLong] != null)) { AppHelp.ShowHelp(AppDefs.HelpTopics.CommandLine, null); MainCleanUp(); return; } if(m_cmdLineArgs[AppDefs.CommandLineOptions.ConfigSetUrlOverride] != null) { Program.Config.Integration.UrlOverride = m_cmdLineArgs[ AppDefs.CommandLineOptions.ConfigSetUrlOverride]; AppConfigSerializer.Save(Program.Config); MainCleanUp(); return; } if(m_cmdLineArgs[AppDefs.CommandLineOptions.ConfigClearUrlOverride] != null) { Program.Config.Integration.UrlOverride = string.Empty; AppConfigSerializer.Save(Program.Config); MainCleanUp(); return; } if(m_cmdLineArgs[AppDefs.CommandLineOptions.ConfigGetUrlOverride] != null) { try { string strFileOut = UrlUtil.EnsureTerminatingSeparator( UrlUtil.GetTempPath(), false) + "KeePass_UrlOverride.tmp"; string strContent = ("[KeePass]\r\nKeeURLOverride=" + Program.Config.Integration.UrlOverride + "\r\n"); File.WriteAllText(strFileOut, strContent); } catch(Exception) { Debug.Assert(false); } MainCleanUp(); return; } if(m_cmdLineArgs[AppDefs.CommandLineOptions.ConfigSetLanguageFile] != null) { Program.Config.Application.LanguageFile = m_cmdLineArgs[ AppDefs.CommandLineOptions.ConfigSetLanguageFile]; AppConfigSerializer.Save(Program.Config); MainCleanUp(); return; } if(m_cmdLineArgs[AppDefs.CommandLineOptions.PlgxCreate] != null) { PlgxPlugin.CreateFromCommandLine(); MainCleanUp(); return; } if(m_cmdLineArgs[AppDefs.CommandLineOptions.PlgxCreateInfo] != null) { PlgxPlugin.CreateInfoFile(m_cmdLineArgs.FileName); MainCleanUp(); return; } if(m_cmdLineArgs[AppDefs.CommandLineOptions.ShowAssemblyInfo] != null) { MessageService.ShowInfo(Assembly.GetExecutingAssembly().ToString()); MainCleanUp(); return; } if(m_cmdLineArgs[AppDefs.CommandLineOptions.MakeXmlSerializerEx] != null) { XmlSerializerEx.GenerateSerializers(m_cmdLineArgs); MainCleanUp(); return; } if(m_cmdLineArgs[AppDefs.CommandLineOptions.MakeXspFile] != null) { XspArchive.CreateFile(m_cmdLineArgs.FileName, m_cmdLineArgs["d"]); MainCleanUp(); return; } if(m_cmdLineArgs[AppDefs.CommandLineOptions.Version] != null) { Console.WriteLine(PwDefs.ShortProductName + " " + PwDefs.VersionString); Console.WriteLine(PwDefs.Copyright); MainCleanUp(); return; } #if DEBUG if(m_cmdLineArgs[AppDefs.CommandLineOptions.TestGfx] != null) { List lImg = new List(); lImg.Add(Properties.Resources.B16x16_Browser); lImg.Add(Properties.Resources.B48x48_Keyboard_Layout); ImageArchive aHighRes = new ImageArchive(); aHighRes.Load(Properties.Resources.Images_Client_HighRes); lImg.Add(aHighRes.GetForObject("C12_IRKickFlash")); if(File.Exists("Test.png")) lImg.Add(Image.FromFile("Test.png")); Image img = GfxUtil.ScaleTest(lImg.ToArray()); img.Save("GfxScaleTest.png", ImageFormat.Png); return; } #endif // #if (DEBUG && !KeePassLibSD) // if(m_cmdLineArgs[AppDefs.CommandLineOptions.MakePopularPasswordTable] != null) // { // PopularPasswords.MakeList(); // MainCleanUp(); // return; // } // #endif try { m_nAppMessage = NativeMethods.RegisterWindowMessage(m_strWndMsgID); } catch(Exception) { Debug.Assert(NativeLib.IsUnix()); } if(m_cmdLineArgs[AppDefs.CommandLineOptions.ExitAll] != null) { BroadcastAppMessageAndCleanUp(AppMessage.Exit); return; } if(m_cmdLineArgs[AppDefs.CommandLineOptions.AutoType] != null) { BroadcastAppMessageAndCleanUp(AppMessage.AutoType); return; } if(m_cmdLineArgs[AppDefs.CommandLineOptions.AutoTypeSelected] != null) { BroadcastAppMessageAndCleanUp(AppMessage.AutoTypeSelected); return; } if(m_cmdLineArgs[AppDefs.CommandLineOptions.OpenEntryUrl] != null) { string strEntryUuid = m_cmdLineArgs[AppDefs.CommandLineOptions.Uuid]; if(!string.IsNullOrEmpty(strEntryUuid)) { IpcParamEx ipUrl = new IpcParamEx(IpcUtilEx.CmdOpenEntryUrl, strEntryUuid, null, null, null, null); IpcUtilEx.SendGlobalMessage(ipUrl); } MainCleanUp(); return; } if(m_cmdLineArgs[AppDefs.CommandLineOptions.LockAll] != null) { BroadcastAppMessageAndCleanUp(AppMessage.Lock); return; } if(m_cmdLineArgs[AppDefs.CommandLineOptions.UnlockAll] != null) { BroadcastAppMessageAndCleanUp(AppMessage.Unlock); return; } if(m_cmdLineArgs[AppDefs.CommandLineOptions.IpcEvent] != null) { string strName = m_cmdLineArgs[AppDefs.CommandLineOptions.IpcEvent]; if(!string.IsNullOrEmpty(strName)) { string[] vFlt = KeyUtil.MakeCtxIndependent(args); IpcParamEx ipEvent = new IpcParamEx(IpcUtilEx.CmdIpcEvent, strName, CommandLineArgs.SafeSerialize(vFlt), null, null, null); IpcUtilEx.SendGlobalMessage(ipEvent); } MainCleanUp(); return; } // Mutex mSingleLock = TrySingleInstanceLock(AppDefs.MutexName, true); bool bSingleLock = GlobalMutexPool.CreateMutex(AppDefs.MutexName, true); // if((mSingleLock == null) && m_appConfig.Integration.LimitToSingleInstance) if(!bSingleLock && m_appConfig.Integration.LimitToSingleInstance) { ActivatePreviousInstance(args); MainCleanUp(); return; } Mutex mGlobalNotify = TryGlobalInstanceNotify(AppDefs.MutexNameGlobal); AutoType.InitStatic(); CustomMessageFilterEx cmfx = new CustomMessageFilterEx(); Application.AddMessageFilter(cmfx); #if DEBUG if(m_cmdLineArgs[AppDefs.CommandLineOptions.DebugThrowException] != null) throw new Exception(AppDefs.CommandLineOptions.DebugThrowException); m_formMain = new MainForm(); Application.Run(m_formMain); #else try { if(m_cmdLineArgs[AppDefs.CommandLineOptions.DebugThrowException] != null) throw new Exception(AppDefs.CommandLineOptions.DebugThrowException); m_formMain = new MainForm(); Application.Run(m_formMain); } catch(Exception exPrg) { ShowFatal(exPrg); } #endif Application.RemoveMessageFilter(cmfx); Debug.Assert(GlobalWindowManager.WindowCount == 0); Debug.Assert(MessageService.CurrentMessageCount == 0); MainCleanUp(); #if DEBUG string strEndWorkDir = WinUtil.GetWorkingDirectory(); Debug.Assert(strEndWorkDir.Equals(strInitialWorkDir, StrUtil.CaseIgnoreCmp)); #endif if(mGlobalNotify != null) { GC.KeepAlive(mGlobalNotify); } // if(mSingleLock != null) { GC.KeepAlive(mSingleLock); } } /// /// Common program initialization function that can also be /// used by applications that use KeePass as a library /// (like e.g. KPScript). /// public static bool CommonInit() { m_bDesignMode = false; // Again, for the ones not calling Main m_rndGlobal = CryptoRandom.NewWeakRandom(); InitEnvSecurity(); MonoWorkarounds.Initialize(); // try { NativeMethods.SetProcessDPIAware(); } // catch(Exception) { } // Do not run as AppX, because of compatibility problems // (unless we're a special compatibility build) if(WinUtil.IsAppX && !IsBuildType( "CDE75CF0D4CA04D577A5A2E6BF5D19BFD5DDBBCF89D340FBBB0E4592C04496F1")) return false; try { SelfTest.TestFipsComplianceProblems(); } catch(Exception exFips) { MessageService.ShowWarning(KPRes.SelfTestFailed, exFips); return false; } // Set global localized strings PwDatabase.LocalizedAppName = PwDefs.ShortProductName; KdbxFile.DetermineLanguageId(); m_appConfig = AppConfigSerializer.Load(); if(m_appConfig.Logging.Enabled) AppLogEx.Open(PwDefs.ShortProductName); AppPolicy.Current = m_appConfig.Security.Policy.CloneDeep(); m_appConfig.Apply(AceApplyFlags.All); m_ecasTriggers = m_appConfig.Application.TriggerSystem; m_ecasTriggers.SetToInitialState(); string strHelpFile = UrlUtil.StripExtension(WinUtil.GetExecutable()) + ".chm"; AppHelp.LocalHelpFile = strHelpFile; // InitEnvWorkarounds(); LoadTranslation(); CustomResourceManager.Override(typeof(KeePass.Properties.Resources)); return true; } public static void CommonTerminate() { #if DEBUG Debug.Assert(ShutdownBlocker.Instance == null); Debug.Assert(!SendInputEx.IsSending); // GC.Collect(); // Force invocation of destructors #endif AppLogEx.Close(); if(m_tempFilesPool != null) { m_tempFilesPool.Clear(TempClearFlags.All); m_tempFilesPool.WaitForThreads(); } EnableThemingInScope.StaticDispose(); MonoWorkarounds.Terminate(); } private static void MainCleanUp() { IpcBroadcast.StopServer(); EntryMenu.Destroy(); GlobalMutexPool.ReleaseAll(); CommonTerminate(); } private static void ShowFatal(Exception ex) { if(ex == null) { Debug.Assert(false); return; } // Catch message box exception; // https://sourceforge.net/p/keepass/patches/86/ try { MessageService.ShowFatal(ex); } catch(Exception) { Console.Error.WriteLine(ex.ToString()); } } private static void InitEnvSecurity() { try { // Do not load libraries from the current working directory if(!NativeMethods.SetDllDirectory(string.Empty)) { Debug.Assert(false); } } catch(Exception) { } // Throws on Unix and Windows < XP SP1 } // internal static Mutex TrySingleInstanceLock(string strName, bool bInitiallyOwned) // { // if(strName == null) throw new ArgumentNullException("strName"); // try // { // bool bCreatedNew; // Mutex mSingleLock = new Mutex(bInitiallyOwned, strName, out bCreatedNew); // if(!bCreatedNew) return null; // return mSingleLock; // } // catch(Exception) { } // return null; // } internal static Mutex TryGlobalInstanceNotify(string strBaseName) { if(strBaseName == null) throw new ArgumentNullException("strBaseName"); try { string strName = "Global\\" + strBaseName; string strIdentity = Environment.UserDomainName + "\\" + Environment.UserName; MutexSecurity ms = new MutexSecurity(); MutexAccessRule mar = new MutexAccessRule(strIdentity, MutexRights.FullControl, AccessControlType.Allow); ms.AddAccessRule(mar); SecurityIdentifier sid = new SecurityIdentifier( WellKnownSidType.WorldSid, null); mar = new MutexAccessRule(sid, MutexRights.ReadPermissions | MutexRights.Synchronize, AccessControlType.Allow); ms.AddAccessRule(mar); bool bCreatedNew; return new Mutex(false, strName, out bCreatedNew, ms); } catch(Exception) { } // Windows 9x and Mono 2.0+ (AddAccessRule) throw return null; } // internal static void DestroyMutex(Mutex m, bool bReleaseFirst) // { // if(m == null) return; // if(bReleaseFirst) // { // try { m.ReleaseMutex(); } // catch(Exception) { Debug.Assert(false); } // } // try { m.Close(); } // catch(Exception) { Debug.Assert(false); } // } private static void ActivatePreviousInstance(string[] args) { if((m_nAppMessage == 0) && !NativeLib.IsUnix()) { Debug.Assert(false); return; } try { if(string.IsNullOrEmpty(m_cmdLineArgs.FileName)) { // NativeMethods.PostMessage((IntPtr)NativeMethods.HWND_BROADCAST, // m_nAppMessage, (IntPtr)AppMessage.RestoreWindow, IntPtr.Zero); IpcBroadcast.Send(AppMessage.RestoreWindow, 0, false); } else { string[] vFlt = KeyUtil.MakeCtxIndependent(args); IpcParamEx ipcMsg = new IpcParamEx(IpcUtilEx.CmdOpenDatabase, CommandLineArgs.SafeSerialize(vFlt), null, null, null, null); IpcUtilEx.SendGlobalMessage(ipcMsg); } } catch(Exception) { Debug.Assert(false); } } // For plugins public static void NotifyUserActivity() { if(Program.m_formMain != null) Program.m_formMain.NotifyUserActivity(); } public static IntPtr GetSafeMainWindowHandle() { if(m_formMain == null) return IntPtr.Zero; try { return m_formMain.Handle; } catch(Exception) { Debug.Assert(false); } return IntPtr.Zero; } private static void BroadcastAppMessageAndCleanUp(AppMessage msg) { try { // NativeMethods.PostMessage((IntPtr)NativeMethods.HWND_BROADCAST, // m_nAppMessage, (IntPtr)msg, IntPtr.Zero); IpcBroadcast.Send(msg, 0, false); } catch(Exception) { Debug.Assert(false); } MainCleanUp(); } private static void LoadTranslation() { string strPath = m_appConfig.Application.GetLanguageFilePath(); if(string.IsNullOrEmpty(strPath)) return; try { // Performance optimization if(!File.Exists(strPath)) return; XmlSerializerEx xs = new XmlSerializerEx(typeof(KPTranslation)); m_kpTranslation = KPTranslation.Load(strPath, xs); KPRes.SetTranslatedStrings( m_kpTranslation.SafeGetStringTableDictionary( "KeePass.Resources.KPRes")); KLRes.SetTranslatedStrings( m_kpTranslation.SafeGetStringTableDictionary( "KeePassLib.Resources.KLRes")); StrUtil.RightToLeft = m_kpTranslation.Properties.RightToLeft; } // catch(DirectoryNotFoundException) { } // Ignore // catch(FileNotFoundException) { } // Ignore catch(Exception) { Debug.Assert(false); } } internal static bool IsDevelopmentSnapshot() { try { Assembly asm = Assembly.GetExecutingAssembly(); byte[] pk = asm.GetName().GetPublicKeyToken(); string strPk = MemUtil.ByteArrayToHexString(pk); return !strPk.Equals("fed2ed7716aecf5c", StrUtil.CaseIgnoreCmp); } catch(Exception) { Debug.Assert(false); } return false; } private static bool IsBuildType(string str) { try { string strFile = UrlUtil.GetFileDirectory(WinUtil.GetExecutable(), true, false) + "Application.ini"; if(!File.Exists(strFile)) return false; IniFile f = IniFile.Read(strFile, StrUtil.Utf8); string strType = f.Get("Application", "Type"); if(string.IsNullOrEmpty(strType)) return false; byte[] pb = CryptoUtil.HashSha256(StrUtil.Utf8.GetBytes(strType.Trim())); return string.Equals(MemUtil.ByteArrayToHexString(pb), str, StrUtil.CaseIgnoreCmp); } catch(Exception) { Debug.Assert(false); } return false; } /* private static void InitEnvWorkarounds() { InitFtpWorkaround(); } */ /* private static void InitFtpWorkaround() { // https://support.microsoft.com/kb/2134299 // https://connect.microsoft.com/VisualStudio/feedback/details/621450/problem-renaming-file-on-ftp-server-using-ftpwebrequest-in-net-framework-4-0-vs2010-only try { if((Environment.Version.Major >= 4) && !NativeLib.IsUnix()) { Type tFtp = typeof(FtpWebRequest); Assembly asm = Assembly.GetAssembly(tFtp); Type tFlags = asm.GetType("System.Net.FtpMethodFlags"); Debug.Assert(Enum.GetUnderlyingType(tFlags) == typeof(int)); int iAdd = (int)Enum.Parse(tFlags, "MustChangeWorkingDirectoryToPath"); Debug.Assert(iAdd == 0x100); FieldInfo fiMethod = tFtp.GetField("m_MethodInfo", BindingFlags.Instance | BindingFlags.NonPublic); if(fiMethod == null) { Debug.Assert(false); return; } Type tMethod = fiMethod.FieldType; FieldInfo fiKnown = tMethod.GetField("KnownMethodInfo", BindingFlags.Static | BindingFlags.NonPublic); if(fiKnown == null) { Debug.Assert(false); return; } Array arKnown = (Array)fiKnown.GetValue(null); FieldInfo fiFlags = tMethod.GetField("Flags", BindingFlags.Instance | BindingFlags.NonPublic); if(fiFlags == null) { Debug.Assert(false); return; } foreach(object oKnown in arKnown) { int i = (int)fiFlags.GetValue(oKnown); i |= iAdd; fiFlags.SetValue(oKnown, i); } } } catch(Exception) { Debug.Assert(false); } } */ } } KeePass/Resources/0000775000000000000000000000000013222750172013064 5ustar rootrootKeePass/Resources/Nuvola/0000775000000000000000000000000012706643030014330 5ustar rootrootKeePass/Resources/Nuvola/B16x16_Redo.png0000664000000000000000000000130410125245344016673 0ustar rootrootPNG  IHDRagAMA7tEXtSoftwareAdobe ImageReadyqe<VIDATxbf 3q\L X`(| ^)iW&]qBk>?@  ^p3\;!D_ >|xyZZZ XCT7o~?b|@ *@@i~  QLIENDB`KeePass/Resources/Nuvola/B16x16_XMag.png0000664000000000000000000000130712666321352016647 0ustar rootrootPNG  IHDRaIDAT8˝ohq_n7šuBg$# 0)y$xb˘Z%y2vOL-ڹm  <|ݧ|# R__OYY}tH$tQQ(p8L[[Fֲkܶva -;*OX)())Gwtt/˚l</մ4.m .$jn| ֒G-yΒ "g_/p82u,/X:sNO^=N*ޥq3ˢ\Mk(t:2phu86LǓЗ7IxOkaG]`S2aL: ``kiˁpyMӔ ݱ. Ma`$,g&TUVV'ݱ:!/f7 #w3(ÖNW^E .u xaMgYC>(K_H6lt>}Rxis/:Z|Mk0=8ir~`9.)U@G OJG' @F;S2H$hTW})"RrIpwsnf Y{2րWk]wv>}F ˁBs!NZd`e y ~R@L$J &&&0-yA[alr0}< @/ _0IC 00&+!&?vB%+d ;gD0 lgRRDsNRJ8ŋ 3#`ɝs{fXQZCsCո7ƀڰ+Ur@  TLO!XF1ǁ'"?hfZ+WP 5 7|ޕ-D_ 3MKG1*%%%9 fA4 jjj23K@r WUUc`i9BZZALL yd8}h1 d``@D'M%ec^sCC;ZJlM9;Ĺcz't @!D/ڥl, EY@{'#?*f&!)c @Z+Q{R /\TUA8k->oNϼ;u9/hJ3Av G Xi qC/^-[L@惒 q_ɁɁb ?*[42H=@aMBQ3&2Y\D` ASRJR@6@G_ |z8l հVઙ%!Y Z< Ăt%#bW \GW - Q|} b!@q%L![U^ b1ZY>XӇ/p]6 dTق`HY>vҧxZK>~S˺[Z, wgyd͘536*4dxfJD79 m)a"1K7j@wDPl4!iA(NVwߌV"0 [/a.Bޛ~tl?PD41Đ Aul(3 ~Oо(pEx{ɓ' ׯ_7'@M`7ܾ8MhPA-X'''r%[7 "؜`mv<ɁW@ c J5=rLU elP B B)R[DyVDָUoYAa_WUM\^y]qs{_|.P\YY ɁB 9PȾ}A^^AII AB8P1^AjA,ATl]Yd@Q`qرcvuaKa 1% 6 aY8y 06L 9P̀y0fQZDC`2&Ɂ0Qd#Wk#Y3~C[  AG jPD?@/c6-Zz_ b0 ҁ,%+2ћ/b6b"&Ja@!B*rS4 6C\@r6/  NAةė'tWprBvCB:Qdf7lf67CajB%y%GUA}ȹZтGB[P &ys9T޻w%B}}}p(VVV7K@cMd yPj}Pqʕ /_$@LQyTKذ"( 5 ǂ j<󸊊  USDSr `Ű&aX JV-Vg`@kuZo޼7"AvFp%!b"vp]pG^uh@zjx%9P a^g:Ɂ . 3A@|@l&<2 Ɯ7nJ0 07\-l6DR" OFKXs }Ƚ2P3d X(FAjiiʡ4`cy֡%Îș z(r2 -ĐG@lА$LGoc[+݄L;[眐>d;eb0z?416Һ $r09?@ax{F`$ zQsY(2yAAkA &@ؖ:ii`&mӧ@, ~}a^6{i2\޳a  fSC_Bs@OP ؀g8!2g-ow03,dcuC٫  /p30D&{aCIX 0׹22 0?YYr 230p00l<&jvDG20[Յ _dX>`byûL lߙa?@O @xD#Z0aㅿ | zsOA XBç 70nnVO_~1|şR ۟ .F; >WGt3N`-y&+2 W3Hsx^cR/C&{*$a w ?W@. dP@E= IENDB`KeePass/Resources/Nuvola/B16x16_Folder.png0000664000000000000000000000062312666316326017233 0ustar rootrootPNG  IHDRaZIDAT8˥JAR;A++k`·k+FG0R 6B,lD b6dw~,l7 Xf|s,kKY&8`zXD= Q5i^Utz(@RI܎[p|rLuc ?Qh;hux1w`d2C +T"6r+Ԅu/tZ@Ou2y8} Ni*˟Nȃ92/av ĸq֋8$eW/ < 6uyU X=`uF{ a(`9f2(=7 }IENDB`KeePass/Resources/Nuvola/B16x16_Colorize.png0000664000000000000000000000216110133443202017562 0ustar rootrootPNG  IHDRagAMA7tEXtSoftwareAdobe ImageReadyqe<IDATxbb`/\3NAiaqf^?q&å{/z20l``@@-' ajY fږ |L ll}aaFg[?nXGî߷nxIG) X$0Tet1,i[s/Ჰ(e) b(e [D^]^ϟ3E)3; X~b3P,x 1c0cyͰYaSwԤ2 3(j {U6/0}+`&ȋ? |@dVdHb7NaY , \ LĤhbd[O 033pH00\fx.O @,jR 7c`EZALG ^fߌ^mˠ~#(.#w0oOf~a&1!@͟^300:+33\&ýw>"p7O- OMMF7 Oa `ab`x 7,а ? s7c{a (0O x>}yΰn}afx @,?]-w8>}cd NB0P?3/̿pfF- abGng| ̂R I8Y޾Űyy{_L`fbh I߁ Ώ  l @UL߸p`9v1ge`b ^ݾ_ſ3\:xʮ{>İ#  z`cAHXE321}yu'MlL4_10| υ{iIENDB`KeePass/Resources/Nuvola/B48x48_Folder_Txt.png0000664000000000000000000001262710126472514020102 0ustar rootrootPNG  IHDR00WgAMA7tEXtSoftwareAdobe ImageReadyqe<)IDATxb?P0@FFF'ӭٳk>ף7o<ۯ@%bzdee[ZZ1|6/{ϟ?}8sҥw@( AyZ1Ϩq͔5u~Ç 7nЫ۷ozf/^p 3$gH<==UCBB/%%%rSO1ܾ}…oo߾y 3^p@% @Q5 jhhrRΠ nnϟp[n_~_y͉SNMjDHHH ,,D߿1}3w]޽;O?~珻߿cρ"@Q>7 gx0m jvUUUMm ,yX[[AOOW6_ :bt}yy1 djUb߿&&&L#5#@Y?6c@Ҡ;wn~ qU<娬 ߿ P1?R'0p0ա74!уW P=w7ՀA4AYE ,bؑ+8c` `P?G0Y`0@Go מ~gxO^|/8{QZ_)@O{3خbw?`*^{~)aSbdPgcfc7Ü.,+wiy:jj/7_0x ^bx? 12p0q1H r2(3Kp0\aS ~ XXdzG`Q}@\Tl(,؀ 8gmyqAI>ѷ~+177_2`~'3? ' ;?;/+70@퟿!Q[#<} *"/  $S`{S`{ DxCv<> O V?T/ `,7+WQ?%XQ/-`à* ) L;М~ $YX8^}/A Aۓ'?n  $88\|ZT@ hχ C]5X4եy|dPc: d8~!?<_PtB=?Qw`;@%cО?|woq-'>@P~~ 4 ( ,v`L/` L:l 5'Z5çS_x 1޻?_=l)@c؀2+7é9 e1yӛ/v`6 `Ԅlfax.͠,ʘ>P ,''+`4Xrd=T}0U]. @\ [^sǃq/WWbgr4P3!t<mp],nh,0/1"b?*7v..zõD ,DTe|ݠ@~}wpr9O@o`$b!qcP owbX88bP_Hi O0<yfd,.< /U؎N5Ɂi P~Hh ŝ6wf+dA_A߰8P="$,#7`iwkOaeee-7a%kBw_>pal(Sc/3ĕ00 eKa+]la3{>&~1]eW.,̇ `=)...~+4&Ocxќ۷|jǃCZ2{(d&lv@k;&91atUv A9i`m mGt`.BJz`;`ч V>޽+@!bׇo^4 ܹJoex!: V2vs@E %?p_/ sg3|aQWc I_e5l x' hЌ1.@积o} l1 t_,c< at!Wg?ԇ߾3xaf/?" sK`QM:!r1 j0y˟ 01?|vN>GP_ׯ5+6`ͅ 7t1{dPql" lmj`O`ɞKQճg~忐o@0>wml>gFf>/|@!ܞ=@thn,`\ Mn@U@?-`XTh ggx  8X9:/8PLs1;/1Sû3xtϡ}P1@??_V˝ml0 X{l"?t<#hT 30e*w0n` 10fal3 _3}z ,C`R`a`=,zXϮ1`{M.fN^`؏~}%rSdBwpeV .a@1`'z *2C 3M`xc>A~I̠P'#?A|g`{`,=l<, L X=x>ސ=А,.c?o/>&|9 P=ڃC};1XpFϷA{72Å3 -gX0pqS?hRc3gt1#,~}f`L=p+-i5U^XaN[c~ % T|wM< |0ma`x,.4`dx|t52N`/ 9ԌfS 8y <݁]vVA` , /]c*WfX{"e`fzLعga3` ꁟ0s_w!nl;>ij`,|8Oz2Po`72FQPN>X`bD"\ žOnegp=0#]Iѳ_h؞ۛ 1s3l{6^}Б߁ʚaD520%{t̸ GbF`Jcy ҋcbFȨ!Dѹ )ު rJ\ 6y9x8>/n p k3/OR`` H;l៨ αI&H=q#ïtO~}W_}k b~ t tpWh?A_H;T c I(Ą?e'{߻4L% ,ξ1@G?_^~g`~d3` đ?ZoPGDs(yb|;~ #6zn3<ïW L ? G1>@ q_+C#?8 X&BXZ݇/@, oH!zh80lX:*JIENDB`KeePass/Resources/Nuvola/B16x16_MessageBox_Info.png0000664000000000000000000000172210133446760021022 0ustar rootrootPNG  IHDRagAMA7tEXtSoftwareAdobe ImageReadyqe<dIDATxb?% X@ ?c`W5_T\_PWoo>{ն?~300]f TJbA1t%>__}.UO_~1|V^${&@+€ ffX1q1<}B;ïv]e`f b9Cc@ ] m㷖tknV6O~3LZG Oc5zßF  Fooa>V@~|o+o?2~T 쏟3|{w+6_T %$Ý' ?~21gۿ@À|y𛙉_  ̵ &, a0@ ɼi.0s30qr؀cap70J13\c`AY? /|g?2s>çB~1cg0=(Jhe H/@c㋷?F#01joA/0_ ̌ @Kp مDY^a09h1+H`-~h H:`aڽO3K1p1yI2po/%aEQ6Q^0z| $%20B޷0aѷ4񛁓wk?yds!@!2#파n\ l<0Z7Pb6b4;/u[?&AIENDB`KeePass/Resources/Nuvola/B16x16_Folder_Blue_Open.png0000664000000000000000000000112710133525322021144 0ustar rootrootPNG  IHDRagAMA7tEXtSoftwareAdobe ImageReadyqe<IDATxbd```bp7@ @8P ];@$=4N/F{ |܃ ^ d {l/ ?00p@={6\^" -3'go6x1s:Fw> u 8yB(0n~@y3)ds@#mcX;T#k? Wm c+_ 4Ȁ?r?C6520ċ5Ѐ M@h_ 2 nql5.BBDv7퇁@ i7b6F |t @۫ Ă]@@ `bC 0!A} XPP xThbCIENDB`KeePass/Resources/Nuvola/B16x16_WWW.png0000664000000000000000000000220210126472606016470 0ustar rootrootPNG  IHDRagAMA7tEXtSoftwareAdobe ImageReadyqe<IDATxbd`h``d`a'_m$il&.#)o (:}I@!uk)Z9x9y^~zsO߿3Kq Y4uߟ7GIPH"_w/8Yu8٥؁?1Q/63<}3LeYkn'  |A/3\&"D '+M?2Sߘ&q=+';0Qr20p1???/^:??C##?:j @123['V)`Wp`x;?@Wgd``̔\̐u#ߓ~k9Y82 10s00r10('4?'˗r2k~=O7oI=}wz/` ;OcW H~.7*tfS'A]1    E8#P߿|'ʿc@~!+IENDB`KeePass/Resources/Nuvola/B16x16_1UpArrow.png0000664000000000000000000000141510133443762017470 0ustar rootrootPNG  IHDRagAMA7tEXtSoftwareAdobe ImageReadyqe<IDATxb?% ("Mga.FFFv LQ2 "zF&S٘ݷ6NF> >Ī93J-xS~va246￧70 3\ˠf8( /@A n];@a5/%UTca`e`V T.%ƕSop np5/ =.d&vnv^ ȳd'̰?1=z?n&)MB&k .[@RaMG0|+3~|]RA##T%a* rrꊞ*< L >ccc)w X~Ġ1p -FF`^GG6>>N70^ׯ&߿4$$$W mãG}:ADAZZAHt!!aǏoܸ| @A @3,[wihY\#'' 6`ݺ_ϟg & ر**2.]:=a߾ˁ1.!!Y ӇoY޽{k/_]AFFMCC_'$$AO߿c^F ,-YLÇ>b>u7o^~5+_JIIs XZZ)(H1/2,Z(@xx?VPPa`aaPY hjwA\\AJJ(W _5W qq `%++.Gϟ89ف)ܹ8q`ӧ˯_?,X0@\moQAQQ 8gP`FP͛gW^jy X@ĭ[WWp缼ڥrr߿bsP>0a2<{f2@0 ܹss %(qrr1̜9=z/F=ã  ,-mqssCX=;&cg+IENDB`KeePass/Resources/Nuvola/B48x48_KCMSystem.png0000664000000000000000000001052410125245344017637 0ustar rootrootPNG  IHDR00WgAMA7tEXtSoftwareAdobe ImageReadyqe<IDATxb?P8=@C4=@p022R@󘠘d;;6mZͷTׯ_ǀn8x_op>2 &j++؟?}䨿2,]:IDD8άF[[mc37=gU< Ő[1 ]*++JAAo!i"-?L/ 6@,$CZZ48nܸcOGGMLWW\8D88℄DYQ`cce$ `L)u&&SXd02İ 3lӛ7/Zdddxyyc4l N1=-!! --@!!`666/; v ?,sqsjںx=AXAPIIr9rr" O_ņÏVӫL/EyX`CBb 3ם;7nKAr:ï_ ..6{{KKm~~N`crf\ ԫ JJ NN.0ܹc gaex1ӧ?"##?~eL!!X3;o?ppss(B޽Uty"PZvepu dd n߾Q%%-&& \4;8Af02gx9г1 ,X+ 3(*Jcg3s>qqi|e`t&\Q-[6lg082,p;|@}3WAyˇgSTVRReaxc&IaxLzͫ~L?@I^CZ 2T&?~|c04{@RR]YY]`P:%Iۏ .8eJK$0@'((^^!>ښ >|fz~`q80Pp>04݁ >4FX]xxxف;`~xL߁P ︻]y޿{Ӧ+W]~xy<=] vsppIBw#@a>J%L22M(CAAA ,,l`#|l|xCX_ߘ#00 uaO3O>yHZ8!88Ă ݭ~~!`C+AUUD6i 477+`f`Pq:7 ؎p`{ 8⁄& J** _|m{`x` (7A?xL +8 0BrrJ  `>hVWי l0hk+38Yl?CT2K WgrUUehv677姢+WIk ?P+W.YXY)*JC  H3߂j{ \|v?Bd~ 1# UC^|GD۷oxi_`6$ ~?~|w y@&,,Ǐϟ?&$$+-- `D!Iܖy A>ٟ 5 j IPGDE@恚 OHSWW`8yaѢySE'`sm5mrrʋ$$%EMG`>&ػ._\$ mٲ-+W.>%Pm 0ݻ7 π+PlJPhqpB@I{J޽t07=``` K@w(pTKJJ1jtP jC)>`f`9s)- .ڸq^ٳut TTAi@mXij8{ׯ#jkW=`ƾL*988@2TIb4'  亃>@'O=^"#43r5˼ude%ȠP)vÉGj`qh;`F &R<f @˗}y3n< +)q[t1B.@22QTU>Ж$"V*fA#Ae9WF@?R Kx~c`5MDDŶÝ;<@s̖v ZZܠZd(_kBŎ(x Y#"dηo?nԀ:/~7ܹJD啂 ,x;U9!P̀:0GBbPAR2;#4}# p̼zp0vUl޽c8xp/)CĂC/*)@5@)(@m?@I 4tjn<_vH%4@ 䔀yfw`ZmkV{p I'f|z0AC  mIN uAb˗+xX4?q==SFiiYwL}p09]{O @(9sb<0[EE59 l|'` .%zP֧8+rۗaPC* lHw2 ׯ_<m+8Ǜl@G C#?i7={;w+Sox.q<W`xse 순 1MM,PJVZ2lA^fx.1ZZ~(d~paPSTnV*))#72 _G pؐ{ ү.^<Wei!$$ lf\d8ujߣӧOد@`8{,ED}+`-| x/iݻk.}ѣ{g^z@| +XO(D5+5h KH~"_yvڵ˟cO<"@+$*@j||t ߿~0eWf``/~1D2h* ï#\@,` 2/ 7e*yAhՀ6 b%'; JL \O l3 @@1fd􎁑OFY ɆNc[HM}Rl;(@z@I#0Çl L E?I7Di9ALr'S`4210Gʉ@:Ydx)˗> ҀjYX12Pa@Y^~ ˮb_IENDB`KeePass/Resources/Nuvola/B32x32_Trashcan_Full.png0000664000000000000000000000543410126541400020524 0ustar rootrootPNG  IHDR szzgAMA7tEXtSoftwareAdobe ImageReadyqe< IDATxb?@bb`@,320a``6`dg̠,.W?[ לa0p{'w1,Eub4?Se t$YXXXXcd?P@o 믿 bx`?sÛsqY@iX UE̤y9^pW1|ӗ ~b` ,@M, | RR < oc8uۗ2\4o!@,X‡uBb(Ù{?6{7??}" X^|#!~0~^n-=Mk3K"m3\:)Y |e#Ї` 1 ^|b|) |`w/^1yލ{ n ?3o:{.%?a$9E6Yc >~!SF JR y\ ^&ư"?0  xT-mi~~p%К[0|\,b ?b󟉁+ly9)F&Iq`&?>~N`t7cTLP??1|X830 ; 0Q?W e`gccb;׀%EEnnn6ÇdETU$Ņð;M]#w_3Np-N.bf`fΚ?b`ddfEO|nneG2 3Ў?}0eseHNqQHq@ELGMAA+,;` /0bx ^1|@*ca(vhSxe UZcp)kɋ ? Brf Qk>ZA UL`=w_I,$l5`7R3K lءDX23C_]fg?0[}׿UY2Xfx7_pykI@kF e L1 ? `L??3A C_'0ș'8fH΀.`)9~ ' ?>`xf.n]e~G_37OX~t0ȁy& ((ˇo <=y'ءL򝍁d@iWacq@1aA njH  Fo߿QAA5@VTa3 `+[] B$?H L|c`A?Ï_h6ƿ ?U2bbbf l/^'ʿXB ƿ~  .e`x~|ʱr10q2|Z` p6Nv`1ps/@1aK P6|;\<'?0?` Dgϛ0S?r+7Ý7L w}a8qX89y@ r2|֪\3 nϛa!>cl +@03;_.?L O?g ,o`? 0W|fxԿ秝axȏfM NBfiRvR _32L i Xi: ,Aw1|5G~>4w'@ p9ǒA$_EAR]TLxk` !e>}?zoA}@.' @s [ "& r RL̬0+a?]0| >k"d;00B17 %HU2/@/N$; pE(#IENDB`KeePass/Resources/Nuvola/B16x16_KNotes.png0000664000000000000000000000167210131463222017207 0ustar rootrootPNG  IHDRagAMA7tEXtSoftwareAdobe ImageReadyqe<LIDATxb?% ArC a"6 ql=?!oAG _6 k #8?  A 0K  9e~\o&C-?>}Ē \ \ 8210|gǦ^:n00؛1h00=1|P ?1|}GĒb+4AI;G_h?00c#ço o+ &^?@Eo~A5@[/@0ssg'0ۡ5bw ?Cb0 ??@K?9@gcʠiW&@ٌ@g7~z%@0cH 0 9ނr;ba`dF:o@{X~?fxqA@,"߀).([@d0 `F'_&~1oq0wϵc𭙑 H/@ dۛ>חVpHv38X!A@0(dg&^X'k8o&5ef$` h?{! ϿbX T&F?zP<~F{8b*͎+[+Erir@8æ@g <Zeǫ+O \1O7~/>  1OMPgx 4o/FVpo?2 3p}W LLb ]^N&qK39|K;ޭ H,a3F\^,Q_Z 68|w߿Wo~˪,,StbfR L`X2 @` Q>w7o^A;1ٵѿ߼?~Ÿ2|fffWb A M%'o9Ǐ_ W RZfl"" \\m#@ `3]/??Tm@XWM?[lklLϿ 831/;d?*61 $ h#;/(PyǺ 쿀t М`V>~n~P &bs,<ދ3k*1( pDagoMnv!ܣL  ȰApqP#̰2SCa͹ //_eysd&Iie{ff= @A WMcCWÞnޟ7;'Z`3i B'4*2aϦK n>ia`+??<" *Jzl@z 㘽k}O6203?++H < JIENDB`KeePass/Resources/Nuvola/B16x16_2DownArrow.png0000664000000000000000000000204710133443756020021 0ustar rootrootPNG  IHDRagAMA7tEXtSoftwareAdobe ImageReadyqe<IDATxAS(&y V &Yx t69oO^Ju0g``ddȔaS>^b/? ,ҹ3lܜ$dxobafS`t'ý w~b FNɮ%2ZH^a d`ce/*7@랾f7C3Fٹq嗃W`4dbd3PK2x00\d |{1Р_ppuʝ I * m _?k ~ ?1ppE˴)`P~& 7^1!@@X3  >A$}Y@`dlbxs;@ l 3c+/?aa}$g r~{ {3 3&Ɠ@ +g2ed8r=Owoqbƥ0:>} #@ݳϾdvaMgp 0cIf)!mJN|r r| ߿f Ȁ ^Բt_)`ppax][;x8X~)목=fdgwo43փ$b=/N(1pex];~1zwʀ)j4 ЈJ̺pcbCەBAC& RaWc EAJ&16ع ݪܰRU  %,f 7dff`gROh@ad` 5xY^{-Š (͠pbQFU%9)1!6V,f'babbbPRfeLc``e``! hAI 00prC_p<4D+/'0<Ӈ[ 2e`@,cf`cc +mG~0ں{8u.c'eFfF!by+Ñ#7޽t.bb" 8}&Nvbx{>0}  of^p]_7ؘei ,,~7!~ay} } -@nHXIENDB`KeePass/Resources/Nuvola/B16x16_EditDelete.png0000664000000000000000000000153410133443156020017 0ustar rootrootPNG  IHDRagAMA7tEXtSoftwareAdobe ImageReadyqe<IDATxb?ZhǞo{ǀ1g=yBKbP0c$A@MgHa /ftbkó'~}r_ Og'N1#@ @L6 Z[̞ ŏ,e9w6ûE7B17 gbJMe~ĉ w|Γ'T"b!koC| Ox7l`ZAVTUD^ 슊 1bA6A&..#ÚyqQP1<۸u~p\,ÿ/ Aŀ@@>{й xx/(!16@30&0蒿 ,L {:>ձ17 a>z;=A{1.NiS{ %(?;!I?kDK3~U2xὓ+40&. @*k913 /GJ=c}3&?$ j0ZŸ $ec:0P=?VM&AI ޙAbAbcgI^':?ߌt?,fY?fFf&]c1f0Hv;׎IENDB`KeePass/Resources/Nuvola/B16x16_FTP.png0000664000000000000000000000162712666321312016445 0ustar rootrootPNG  IHDRa^IDAT8MO[usίXW_lƋ-06P$dy1 q7^j F/L^85l,K5\6J)ОsN f><Pτ;s#6\_nɗŕfl| dA#G{tWyO?u{EOV6e9{tsw\/\eYX[ܚ6c2֗d*;%gٸ@z/\ 'KIQ-s=zO11:3~r6 'ϮϗԌ ŎM|g8#XM&gQmK;o>QZUws t;:Dr~w#>/BP:Kܯ5g'cls-u D*mo(# S>)3mvӣa"nek:N㏏ ئvʇ3iH]S] f XIyS0v!EEX!J TY'ԦS6 &;+H6))忉;m`x{$%㹈xD4BF4h4t|5[ok@OO uF$$g J󱯲pԎJ˜֞: `d">t}/쒧FU5:4jʹVXIͬ=7~&^yߐl-Y%^ZŒrs=[T{1^.0rGޭ2 .]b{6HP< lX>Gl8BZvN;)2܆Xe2e,B 2eIENDB`KeePass/Resources/Nuvola/B48x48_KGPG_Key2.png0000664000000000000000000001014710125245344017443 0ustar rootrootPNG  IHDR00WgAMA7tEXtSoftwareAdobe ImageReadyqe<IDATxb?P8=@C4=@C4=@C4=@`022€Be``>@ Puf gXl&gL Cz:vB:X>@1&=qe%qu# %1WO3<?|z=q>hw" ~{@ C'Cl Fbrj& Zf  r8``x }cxtÙͻMG#B AC7CJe +Dx10q30ʩ,Ï@90ag44õ+}xR3*^ @$Fn ~xP?/Ë 1Hs11|cPTx.%MttlA ĩAW|{9- Ó< N ?`xñ6AEĄAOAJ17gP *A}A0S ^I% PqbAQ T;/#˻v`dG>iyyHh Vc56O `yLN~313-@\F? V22!12 1\w@f/P?oX)\8 Û? z g+۷^7XXpys1|a0:Y ll a?@, bXgk7f\dx6`  *@pclER. 6 ||@Nj1pp3 0O2|g \\ /^>gXv%CaSw\`@ CA?v$@< cͼ==d$E-00 ҹ("LLL@ϰ222>|Ço@9KV0x{g~;#q@/āL`Pff&%`l 2}%ǰqW]k[2@/;9IǔYXAQV wzAAAh_~ ;;Co3ܾ!3#a /mc( NI Pgd% fFvH1@̉S r._b /L4e^Pjkl.+{0Ð&.p2;`*keP=xY~au H (ˮO`i# t  0_fPU'/_>0 !P31V-ӧo1,b1\p+y,PG dZO_2|ק=h ȟdA(k@2M\FFfa=dPV;ThFp=r00ࡎgl77'( _<@eس K>>e)Ӈ7 10~l~h?0"UX 81@`gp1ANNA]X99 Jɓ,b޼p߾}_7Z|~~g`vEpas/H jY+lB19 @@ ضQ: @FXAM Py+Ë A1`(?`E >uׁ]llS@20{0fނv@)uih#whhIƾBBB i`XX,y50~kmipjrzhûw9 Z_V̿hE3~2ܹs3"0t)쁨l l$?|xڦ-n:"99jaK؀$ 9qqa'ރ=p#GO2a#0Y[TPK/ WI8@HH2''0$z'~|4+ U 9`{׏`0<=ƍ;iP% JJO<6}{ 0<&浖!ЂآMq|?:ЁBBB޽ OEI O~2[R 0p2(*Jc䱷@O37n J7n\`8~|/ ol(sJ)d,z_sXzbπl/r^^C`w"DffnhFe0vu]=zuRJK,@°erp  pz@UQQ Lsq=j2: 4 >c`, ,NVȱ@;ITj=zmeʱ1Z( }l&`w^((^ %?`πx6H] w<|L~YY @"WPvY偎<}nzpLзo_}`( a`OAVVܴ˗Oiuu}>`cMHHWpR`_A CC eiiA`>w#>}̰rG@:@w~^ھ}%@${>4H\\~c_|0d@DEV(a##u>>>v`ls&Y^#= lc `-[k7 D݀!,U 0V€Mv7`iX6WݸX*=0y&$@427 $`g2aa 2(lܸX }ChА@ yА@ yА@ ym=oIENDB`KeePass/Resources/Nuvola/B16x16_FileQuickPrint.png0000664000000000000000000000225010133443140020665 0ustar rootrootPNG  IHDRagAMA7tEXtSoftwareAdobe ImageReadyqe<:IDATxbf߿3 gfeFFFY6ߺѓlll`zׯP?~0 |ӝ L,L BB"?ffdbA  ਄ մ< h9_@o6N_?_>d  WȝAPRo0  4@zv[Yh762شAԳWe~x T A d $013x"#.9  (U LA~kkox---C "30 \:5 B)A776Y897Ey Ӯ5"517PA""!&(7Mƹ- #! A .m,] + ݻO^}P.|? oI1P' L?N]'P/@A  <1%MOZ%$)A=CF$0je7 YYYEZZA@@@߄ˆAM{2t1[0H1K1(**3(+k1pqq0<{&{nz./N~ 7Q}}߿S3g۾o_/ `2vVVN?|_&An3S,P#0W++ 3ׯld0GcBIENDB`KeePass/Resources/Nuvola/B16x16_KGPG_Import.png0000664000000000000000000000173210125245344020071 0ustar rootrootPNG  IHDRagAMA7tEXtSoftwareAdobe ImageReadyqe<lIDATxb?% A7 o  #Þ a;LZ ;l÷/Wo؝Gb*gwf= o ?8{˴N?@f& Y @Y& o,/d82 ۯbȹĬ 3ndл_~"W.I &\?9°i+2x߯jĬK>a#OqB7/|{KL@oc,42AHd`2< ~v Y  .p{?C__O f`80@410B\R __@>p.7h}p GUP*bM\Yb=;__?r )xI\ƆIENDB`KeePass/Resources/Nuvola/B16x16_Configure.png0000664000000000000000000000172410133443176017733 0ustar rootrootPNG  IHDRagAMA7tEXtSoftwareAdobe ImageReadyqe<fIDATxbd``UQ($$(Ç7o^Y' @ׯ ljjjZ ޽xYʕ lܹĬS͓wސUggPQp̯_W\r: fOOMIַn]uZwT5EEE2<~TڵK?A  ""']]hOӽ ݻ߾}!--ːZ#/kk[ az006 ?~ab fNNve}cY scӧo jlo߾3zi03jIKKhbYY1 kG]~п  >=t۱ceݻ/tտGeRUUgVRGЕ \ r^Kl@12hii11]***ŋww'$dbbd`c f q`ffw,,j/]tlmyxy 3g/ϝ;{1@ 0_){dee  n<;;wۻr0mg'C\\4͛7`ddzԦMk_|K@&{0<@5@G׭[񊕕 _"":? X7o^畐k/]|1>ym%GIENDB`KeePass/Resources/Nuvola/B16x16_ASCII.png0000664000000000000000000000106010130001224016610 0ustar rootrootPNG  IHDRagAMA7tEXtSoftwareAdobe ImageReadyqe<IDATxb:a### q޽[ZZ aǎ?_0+W?@,@@&D0 S}vKKK+׀ 3033 1K@BWWW%%%_~-0L͹s^xv@LA6W o޼[xl"{{{?Y16  ]9D;vӧ ,,,`9bB+ >@1 }t Ąl6/{ɓ Ϟ=G#@ pqq1{= @`6spp00@w `Fa@NIoddl ?@܉RRRi@yVPCX^| 2/IENDB`KeePass/Resources/Nuvola/B48x48_Package_Settings.png0000664000000000000000000001355210130241032021221 0ustar rootrootPNG  IHDR00WgAMA7tEXtSoftwareAdobe ImageReadyqe<IDATxb?P0@FFFτO>޲e-/ Jr'T7o={dwbfhSc֔G]VVV.{igJ<r80P܌ebXp˗/ >^F o`x5kJ31[ppК#GNOLL~TCgu?|?-/}:P@Q-艋˘jhBB ~4ra&O2 ׯeqm`z T ""W%% ik+3rpprmիw߿{틧O~ AYTTd䈈h.)) ݻ3-E%30ع:00M_>2ySλrb ЈgOqttvuk]vKg ¢ .f(Vc0g`: u1-'; GW19}w+@pwl`8xÆ =zN1(ͿŕwhDGGZ2sss1ݻX3>gc8#Cv2 \@0ġx,H1Ei{8~g̳bS3{NKYN+3*ãT cŰ XݵӇ@94nHLL \;;gpu~~/_?2څ 2 ǿ ̨ Rr.ϡ(Z30c@AKӄa 7ep3`r1Ξ89  T ,I X/ru65V̓] Ľ ߿axr{Cw1÷? K1Xb0 pßW~SWsF c`PV6`Xa#Ã[ \|1ro1ffb=yjyB X>/Z_߄7xF`˷ a1d$ɰOv ,Usy+k0\]5 0 I31dX 6Æ ^=``gO!5 o/ݼ@=93Z7É[732gW`z C3>w&;~ 70X[Y3\?v _0q30i2(*2lܴكC 6 Y=gbВ*"Cf'+VKFYg|T+. 5f 0ϟm3432!' (%T8,cf0yx r rJ +W`x"C|BCf9w=3_ ``WfHMgT6VY,+&ht78@174404662<#"uʹ ͸G6EsE00 d11dЗ+a  ,}Xe1 {1\y aJ A ,|J |o~~pK_~3(Iq]CA[C;o?^jK?ܷoϽ3gPdU" BLW8LE};l|grDw×[7yx>bxwÍWO,5;R\ \r xEAG׀﷧$Xi=) E?m O~7P[X w'3?_0(cTa`B " o?/= &?7~n iɭx"^8]a **<,~|]O2| ޾a'33H3|Xq_;dM, <a`aԐb`JN<$T Sw?`O˘OFy;>l9Zɠ ߁؃]?_ }l}gbd =A~r?3x/? ,Z!`+ۇֿg0O?/'|xi`#={22ç~<~)0gt4o^' R rBo~?,y)ƿ@w00&=2z)÷zpG᣾ O[/x;zl I蒸1ܻAH oeO ?p;ؤY+6a>>y` n8_T¤>w׳ ķ<j/ñ [~|:2A({[U2ȞU'`23)b)a lVWİcەϿ=wEA &/cܳ3?gg/4t9ÏۯIi;C[X΃ {wGrTZ܃6т}N6f&d[9KO>;А' @0S s ?+3 ҟW?9M/5#8E':dR BF끚pȴhfK @,͋oș  > ͼCk|b-@KN0 \#«IENDB`KeePass/Resources/Nuvola/B16x16_Package_Development.png0000664000000000000000000000173110130240702021670 0ustar rootrootPNG  IHDRagAMA7tEXtSoftwareAdobe ImageReadyqe<kIDATxbTWWgFFF2[RLLWUEMÇnߺ3n޸V,""fn66;J+mx}Tj`` 'Ol d@4GuuFf(sg=p__|]LLI߿;@z @[mm^`w> 7ñ#GW}=@ ( EEE91{;ÇO xn1~z!y޻5@_09))|yY 㕫.]緌VlmtUhy X@1'Z:<a?:Tt,}~wG  VV=w~3@Π?}}ʿg={z-&F$ 4Ub3P όZ?֚v2g@Uh/ ?+# ߾3E3>V1vQva&A2{7U;R S @lll DH317gos |gpg0ַT:~V'''JFb@Lya&;"Ucx58&Ǐ>|  a #oI&Fi)VV&%V6E,߿} +,K 3߿ f33331'yy%rp )"%$"* ,| @}ܑ} /}̾o_Z<%((N.߾}c(Y1cADDϸC]tt89'3+P=# @O>30|gSAEF巜+Ӛӧx< ; 0YeeeçOc ̼@ g1dSgx3j{/÷~| LjcR 002aq{߿߿]z٥˗/*} f `)p!;Ý{Xcc .n&^~V~ceo~G~AIAU` 1fc4…@kD@Ip`q g6>EM~B_ (d>1|﷯|o "{i "|hF ~@dy= PO `S׮2ܾ뗟|_ǯ|O|`ϖ>lݸ "f˧%* Vy=@dyh#+'#X,I?>pAW~}yɉ_.?|?ThZeb?,##??X"@[hl`g`\ו'=~ ~f$bpxC% /~ v`<{POߠR#.ψ\JVl/@4F lX9=%uDD5e^{p]~1ALZARAI^ῄ ;}1G^+k:8e’?Q!@L!YR*zB \| b/rӫ o\aeQb`,e330K.V~^ 2 BL :>ɣ4w:=h3PVT~@_Ռ̄L\kY`o`0&^q`o``vU ?KyV bB,g̮:+ß7>`Z'Ĝߞ 󗉅 6`_N#g6%l@O| )H8iCL@9%%МO ). 7? }bc db+Y1GL@?A!߀m7ᔂ+P `[`cC') OKB&%;߁ys@023kU5J1A<"P XD /! e( fegl.c Om UVXB bD-lfHpP&;f6{?`R;?r 6N#;0b_AlI2pBĀ55;f818#7 >/,@OФca3 fbq A#8@MLL‡,`JGN.063 ϱq10Eaf_)Nnj<$m0bIF` ?;ebL6Ha6,y(  JJ(1*Y X 3PpcG  |##`(z~У\r[Z` dbv6n^POp#%#F$6H2bĞl16  {.' m_<8{AؖK@җ`z %&X  w`!2ssS50faas?@O6K :i[0p @:Z@c|=ypU33bR`Ƞ0'] ?n`Za1!UMQ/^pܴ W!;ňBq?$ȣcklj:eAS凿 ! ,* Lrl!, hcBG`2}eeg;ߟȑ[~}NԴj~żY߿x$%eM޻vf2J3h5?И)u6)???0rǻ_=s_Nf* %%y/2ܽ //'7/;@GrC02xϭۿ12qa8ZBi3zBi`,|/J\S@| @x_:A** }d+lff`s>~@}̗/_nߺ魠к "gt`$M!@:Tfg`x5Ǐ_!?uݻdaaidd(7PȀc  tt:}/;hz4/!ydf^=@<"ء51C3?z@w/@ t: IENDB`KeePass/Resources/Nuvola/B16x16_Folder_Locked.png0000664000000000000000000000143610133523172020501 0ustar rootrootPNG  IHDRagAMA7tEXtSoftwareAdobe ImageReadyqe<IDATxbd```bpcC@15@@y' b(fbFdd8;ݷ%2+Tx- W8GA؀W_d`Xx P JL^h/؀ _B^\ ,||@gx sb",FƧ3, !e`3;CDc# Xߓ' g&Mb(g/Q s+@15u G020~ | L@P,}O^3@ .xK2ܻw߿ ޽c{ݻ 3ܾv26 o1| t.:`fs30s h>X ^x ,PafƙxrLLL _>}$NVV`Ud`y7??9 <<_BhE&.?0 (ec&I< ~Q(Āׯ~d8ư GWe.(uf0bgP0رzw++HI10?f8C;s 0 X@"LL5BBbb ^}>ݽ[ KXXA)^@ Lf g9r0g6S&IENDB`KeePass/Resources/Nuvola/B16x16_Folder_Outbox.png0000664000000000000000000000070410125245344020560 0ustar rootrootPNG  IHDRagAMA7tEXtSoftwareAdobe ImageReadyqe<VIDATxb?% XIbd~Azϰ  @jϞׯd6uĈ Nb`XSwIa jyd32J!/nݙ`C%A5KB(Hv ƔF@(@ } ψ.@L А~&51؀Y&pSfagcg2pnjDlMӧ ? ASa'`6@Ăwr"_?( 'ÿ?znv0@1R &]ʸIENDB`KeePass/Resources/Nuvola/B16x16_Browser.png0000664000000000000000000000220210130460504017414 0ustar rootrootPNG  IHDRagAMA7tEXtSoftwareAdobe ImageReadyqe<IDATxbd`h``d`a'_m$il&.#)o (:}I@!uk)Z9x9y^~zsO߿3Kq Y4uߟ7GIPH"_w/8Yu8٥؁?1Q/63<}3LeYkn'  |A/3\&"D '+M?2Sߘ&q=+';0Qr20p1???/^:??C##?:j @123['V)`Wp`x;?@Wgd``̔\̐u#ߓ~k9Y82 10s00r10('4?'˗r2k~=O7oI=}wz/` ;OcW H~.7*tfS'A]1    E8#P߿|'ʿc@!~狥IENDB`KeePass/Resources/Nuvola/B48x48_Font.png0000664000000000000000000000437510130001040016710 0ustar rootrootPNG  IHDR00WgAMA7tEXtSoftwareAdobe ImageReadyqe<IDATxb?P8=@`dddptttP222}ˇ޾}{7o^ @,,6p)((0$  >)U@G OJG' @F;S2H$hTW})"RrIpwsnf Y{2րWk]wv>}F ˁBs!NZd`e y ~R@L$#6%ba0(^ f 1iX$)!A T9YJq 6`@,İaB`C 6aKBDNAXX=zpaw2lܸJ91@Lt1Px"a ..pyw5,%1Dfȑo߾e8z( jcdc(Cm-zk׮ l31˰zj0P%?` `Slf6b 9|: R(@%| H G{AAA \\\ #dqIpzFO xyGWWqPҹ|2roE{P޻w֭[4J H۲e VAc pR s@a- C@>}l(id)Y۷3dgg3ɁI`G2@'t@mЦML|#nnlgrǰFC >?fFf0if>`#ݽ]Grq㝪R?o0cA .gM(sa)EnKF<{i-t58@PkFi0 p֟ZCM¯gEK UnVVV`6n\y 0ׁ ;PE#VaHrKYH $4,a5(}@#/ 1+}+#\43 8\43ؒ01}t@DWd"f@M j; 2[)@LQj;/d 1vQM z%|v2 pJpr'-AP;  -1@VA `\ "Ml 7J`@|e˖5/ gbX@p AS| -5Ruv})ˇ KGlv3[}33`TCw T }G0l|` b`@ 5Envn`a9qT*  /Y|}<@pbd;J&*)0KJ- (7c82æӧl<C3Pg{51mΔ?%7е CFCf~7s'>{ 0<tV< K(20|pP ؠ+x~ A 3#o e"?cqpYSW7cbT:0@%`Ԟd8[pC dIEF2++-Ȏa0 86N\Ȱܹ_[޼QC w)%@ePGfDJPm ?.0tyP0 ,JƮӳ.,d`abfɏA)E 4_XXY1 Uǯk/N3I|c 3zA L t.0'{w].Eփc`ٴ d1 t1#0?|=v/0/ #00nB6 3̅ 0r3eadI ~e@Ch(0*@Ff 0N`xs:8֙!0},(SB+.t/@%] ~Fa5 @1!ca:Ԁr<`+AA Uh:(B_a u,3؀s u< D_Ԫ cIʤ[20\ L`RPPL.0Oᾯ$C:K,2#bYC0 Ny%4Ԭ @( g`>ё1|y8Z0!TAE!K/YK C !'~dhQ )ASy1_&,yj@@]nb^߾1jz3|͠"/+C0fN]`8!m~^hoA@OBF&"{P%p*D!B3|Ji iZ1(I0,a߁O 1HXP_H &@p= r1n(Y%O7 ߀y!0@&C!#$~ *p;Cor^g+!Eo`7ĄB`yo' ~fUQ Q - D͚_PPZI?pFAG?Lkbh) Og?0ibBz`,X{'f Tlaߋ0V8!s8f2B;g&6þνgc`feaGsO00,>p>C u|S@,hz^3g<$D+"FPr7OV3}PΉL(9t3`y*od˄м X"]g K3U@P_dVc=uNPPNb:{ {n -j9e,Ll@_O3y/v c;T O>v֑3_f&h'0o[槼fpx x 6%De= )I />|~'QQQ^^^`Zgbp#3VT²o&";qaks3@(yn.03C#`ȇS6ƊO*3,ةy+?+76`3Iqfe_b|zá 7u\]xshuAIhq( !NJB|Ԅ=X>< lME+# *~tv࿿pg{ B$sW4@ &P03N@Ӏ5?2@uA z} pzߌ/|v'#ycLP?.?1 7gגw1f"VVh)qB`+9 y孁X2RB6&`^w=@y (_~*3:n"0Pw} &̡գo &gb- 4/.'B_ z H@77_,U;Cw(2'q:@_՞e>cx(V Hxtw~A<ߘ#{ \y.dd8thPp$7cz he@z_2 _$9" xn:s ^V1Z0w&N@B9C >`x:H@mАb!!!0=/^IENDB`KeePass/Resources/Nuvola/B16x16_KGPG_Info.png0000664000000000000000000000140610125245344017510 0ustar rootrootPNG  IHDRagAMA7tEXtSoftwareAdobe ImageReadyqe<IDATxb?% X@D&c|h, 6I+.K+ ziow?{a 2R Nq ?0<``vAD-Zwf8?C6@KGA(,') +')6v&1/sq1|U d@ fc)8P E0ܿA\^_ Ǐ ">eАNa` ~3p 0!߿`-6=/ ?y ? 2pm ֌A.pC% g2=u{'l}b3%@\@LP˅ s^] <a6p@1/w2|g?3 Qq@1!(1N~c `T N(\@ p@"ͫ B &xGv6+@ 10H#AH';3Q4p2033s $cPon ׏sŁq*IpsYY [P0LfsNd '&'# a""IENDB`KeePass/Resources/Nuvola/B16x16_KGPG_Key2.png0000664000000000000000000000152210125245344017426 0ustar rootrootPNG  IHDRagAMA7tEXtSoftwareAdobe ImageReadyqe<IDATxb?% (DYE@KIOUR\}q~FF( @, SvLw615v bG,۶P14e9@9~2s12yҍ  E@#njWWI 3z'4ɜEE 793|c`x 5$A-%GA@Hz!73$ݿ .,@Ӽ )Y>?M8..&/?3 " }8z0_9?cd&GXn A&&1=  5? 4/GY[׿}ZۗJ?~|gz Њ @'o~WQ A,,4 %#N)Y_@62ߞ߿׶/_|>(bRRR@jݻ`-+by"1 B}cgoX>}9W@1&& 0 FJs#@Q v<(IENDB`KeePass/Resources/Nuvola/B16x16_FileSaveAs.png0000664000000000000000000000176110133443100017760 0ustar rootrootPNG  IHDRagAMA7tEXtSoftwareAdobe ImageReadyqe<IDATxb?#c200@BL@VzIn؅\?w' X@Beڒ~Blj4?H^ < _=Z+&yS=>?  h; W/^`ng $ @`x33H ]/W?3X0>g`a W{0؀?h @?@1 fɻwƠ)DSe(tX}6^L LL c20|ə _TN0q)Eb7P;3$YAt̓s_2H)10< ù'u ĭx?U}e & Ŀ?_W1]ge`0W /41țx22F?F Ͼ0197ßO3Ch/݋of|,=^`0CR@]p?o~0~}Š '0\eaɑð~Ù,T^v_20( a(piGw9fjG[;X] oH0 ~0u)321(g2&10 Q s@A\o 30ea`ffx9gbc`bxt)LLg 3q20|_BIo |f_?dY~dc?X/@]pu̓\|wg>^Vg?!NYɗo ?aŻ߯9@g:|k㭏IENDB`KeePass/Resources/Nuvola/B48x48_Make_KDevelop.png0000664000000000000000000000616610133444030020465 0ustar rootrootPNG  IHDR00WgAMA7tEXtSoftwareAdobe ImageReadyqe< IDATxb?P8=@C4=@p02&+303&և Y=  $$nqvbP/4J|IJz!A1I/ /`͉X @,g(O`b C|<\*BCf g``8=-4` $01gfb+`$1" d0,`bGQőC },v2L,`\ jjA[>  4%7fG4iVApP u5QtbAV~b-? CI?ýT„kB/`erSf`ee@gG^p?y P?g4@ my?4c<;{#Q_߽V>߾]//33[X0dx 'JQB$ Oy# wee 7oDyTxyEDΜ o_C=bb+bRr&!Bx bxt(ã'~|36 _`uoX>es']??IȍM $Db: b M`i5ueKϫWՀ<~fE >> l {Cq~aq.ÿ/y `*Ic qõ'l v<$ İ$ g"BxIB.d]m-??ï? v?V6FiF`-@#˽pi|+k-)LBAbW ~/[|'`X}@[48-AX# >`c/Z^(~ &(4}V..f66AX@f0Ca4 S3\߽ Q/ $JHI  (| <Z UQ 2?~{`7֯ex#zfhf+CP21@!yL,pap[cP77?E%@N.+[ )sDv``69ʂQ|;`y<@#qXLK aRr 4[X10(20101'%f`f7bg7IH44<@,(yȚX܂̢ ߼c$?޾a>zo 'LF#( `He p "7?@:z PK%!.`aaMp`%C050DWeXfx /Ȇ;?$oԦ@8%Է0.ee12d`}3(a a`Y!5 pFD 637 ë<xĿ$R)@L9R [m=?fHA|Xp? 7a!C`ZtCĨ51j J=\aw<,-VX elm2e>ȼWpP>ا/2|6R!jE &RҔko_gVP#/20c }3`F?3oík4 ?RlCmJ ֘c`@w?!!aఴdxk"A: :`X&W.1xۃ * Y  L`EI>Qxr)@h&?M|Tp~` l@0?mr$#^Y6`GƆA9%ABI~HAu8zEڔ@$ˆ.r, Wa/`{FCῩÓ}{O&`Hz0iVϝaɠʠ , &~dx?Dc~p r?{Ü&K,PlHza! _ (7K!~OF8P+6F(4, Y:J pe8XRJ 20 ;Q>C< @`^~h~ъ wcǫ7_ 0dfexm?B. a]3]A?0gns_ _Cfh0 P}p(.7P"k ex!Ƥ'Ȁ -"_ @_Ex%aGyau;v9E0_2؀7P4?^+n {blb 矈p  Mx5 ,O3^``a?! /  @04  ~53C%%6 R _3ـ0^et~mg{ۼ ɗeV{2WKa`` @]X@ XXhQABz,v _/|.+@gx`|1\M b>ç3sJ00#Xy0,1#ZAA{L`Q6IENDB`KeePass/Resources/Nuvola/B16x16_No.png0000664000000000000000000000163210125245344016362 0ustar rootrootPNG  IHDRagAMA7tEXtSoftwareAdobe ImageReadyqe<,IDATxbd@i J"**\LL \pڵ ?|0!zBA{v7oד'II_) P au)Sxz2 o20y7 ~@`*%$S d>~`w^f`xs>*1e`8@@?{DF0`¡C / 4+@ſ--2pݹ~&@1=z_s w[!Lp^@;qKJ$$hQO]}Oq3SPX,,,`@?0D?k@|qCH/@SY?>}z+珗0o@JW °l P8^A0dd1=zOߡg/TUm{Na;l߿}}C6p }xqϊKAYQQZۂS%ۼsLϯh&&  ` gEn{y7!_?_0>WĘIA{WlA99:RMNW '% ɖ!=7LD*A!!!_=[T$EO\;+-(4,3Aȷ76( *^R& &)3$2A;d9%: ߞ`b! 32 D91%A$$Q{ 䒋2"3A/!" a> F3>F+Yg]IBl޳Kپ;o;%8krp<&g~-Sz%?ޜԆZ$@ ߵ >31$8rtGkq 1@@1LT|UJjL Ic8.&&i^tz U@1h30X20gd\R  Aư00)=4`ct]ԒIENDB`KeePass/Resources/Nuvola/B16x16_KGPG_Key1.png0000664000000000000000000000107210125245344017425 0ustar rootrootPNG  IHDRagAMA7tEXtSoftwareAdobe ImageReadyqe<IDATxb?% (DDD"Yxy=5u}~'z-3@`#)J0010iNRw~0 3_ l oAb6@^뫧30(0201ke(]2O?3H3'?ڹePvb⿳mR?=_C(} ; vԿ%KyBEd^03g`?~qCd:P @ P /@6cxz/?v30e`xa"4H/@1Ϝ!aϒ/{ nct!C6'Pb$#R @Hi^ @Ql@Ql@ IENDB`KeePass/Resources/Nuvola/B48x48_KMag.png0000664000000000000000000001053210133310510016621 0ustar rootrootPNG  IHDR00WgAMA7tEXtSoftwareAdobe ImageReadyqe<IDATxb?P8=@CFFF4kׁŔK]ϟ?/_ϟjx$311)++si11nn.ff_3|ŋ ?`y[ny'1"@ X f=]~>?2y퇟 ߾??;_ \cؿ?0&ξ}˗{f}F@=;EֆA٫ G.cNo؁0g.7  3h10:|aڵ߿?דF46@n p^ʧONa`aP̠$ /?n<`b7 3Xi|f0Qdx5ٳΝ;7O:V< N;155OYA 2HJ 0gp7;3?߿@@F1߿?cY)þw3xX 1002={v&0zF'@n :^z 721?`n`!uF4CGD+O b323p2r1=m\;bذ-˓ ~< 13{n-Z%9yvb!!#+ò ֖<  O}c6Csg ݯ+z^1jb|QPs n L[ R > L*Q ێaddj@xMFggg55X[k+`03=ǠŠ X|Y|{O0| ~gx,~.no0F2' w20Kc=Tʱ++k /íW< e^|p#63| ?d 0 gfXJMfcae8}Ý'^,b|ax!(28=a/9 WWPP*6xd_^mc00s. A9?P?ß )3l?^`facubgts2ѣG݀/R34@x<&!A>_xϰZ5,CeLgcc_kA`bv lޜ] ~~gxSf`\pwo ;f̐xfxğI@x\IIv?L~1tE0`|M3ǟ ׾^L Η a`ebc`bv&nanL/_ 2 /_`d$ lCG@DDD" 7FcW 1?dfR` z衛_n3pTN^3{De7Y5w3hJ1=-iHr_b2&R 0S?cF"i\:-+/y_l0FV`` j\uآNFO-e CQCS#ʹΝ#AЗ;0 AK 7z7bk oXJ |`1?O-/GgUlPB9r?!Ew< P̰1S;3n``3d@ʫ @ śGEZ-vxX].P;4B׃Po-sJӖ@M@JA4HSI7Y'~}oO>~6_ B'a/þ7` 7>?ggp837sp1 j1l|A{ \ ǏBP/) >|lf`ecx3#-XyYP"xͳu g_f`$~`bh׭F .e6N% o``x1UBjE@(!` 挢9z61ma\, & s bDyPaed׸alj _~cq!3w7{O-ҏ&!B } 780Ê 7]D1yaٍ TJ `>dp l:!5AL@AS^aM \>~pڵ.&~Jj%`T~[9sDFFA) `T1e`e1e0Vg8rcן_5,(C YaxIÐ;$q˽ j lcx}@T ߽{c!CSSÀAVq`f&V_1qAHHI Pfȏo ?0v/å=yp/Tzܞ@{">}Zo߾UBB2@ 12* lSk kׯc uՁÏtfxmkؿP^ ,$ps20 -+Ϡɐc%۷ ޾g`x_lAbhN=!nhhXckkmcc $'OC@ 3x/2AX@ 6+g0<~_ةag`PzO2ĂK4nsNX\$0{  (3 #v9ׯ ޾`}ëG}}L /_f8x7//rc+OF bb7W񆁡_ =1 ޯ ,oy\1e/`o ~/`P gΜٳϟ=Sfg `2A@AsQ% @ n߾=/>y$'`GHTTԒJ"pH Ϟ=c,z_nq|ddN' 2"ǀ5'&#`dveDx X' O6_x[6ɹ=` !!!+ LĽ~o_z sw%-_?_J~{jͳ{ "N20?l1^`-/?'tꍕ<@BG$XΈ"''8\8@~ d6B+)P9A֘Yo`f6ņPVAaec?|<r;@5?9Nh9/ t4V<0020̰bWqjbqA` x1`ُ1(>i=0c  yZ2#uFA=GygN`ӳ1l~10| \ [`;߯ C7b@" d ?tA> [Pe`Pk2uqyN [<@9d PO>𧃑Oym쐑Aa- pOlz߾?6" 'ÓV3$&wuPd; P0h0 pn-ǟAc@=T`3L Ax@gテ-EAX 4<ՠf4o د?0;#̌ ;2+4hx< `7fb#=/aY 0a r+2ZP]"hL LouNk@ ?h0z Pz@,4@|Am/@'쟠]_= HsbIENDB`KeePass/Resources/Nuvola/B16x16_View_Detailed.png0000664000000000000000000000170110133443370020506 0ustar rootrootPNG  IHDRagAMA7tEXtSoftwareAdobe ImageReadyqe<SIDATxbTUg20 4*ba(PD/DO( 񛁁qFby߿2|?@k@&B,@_xmFGM!_2:`6###п [/|gH A kS  /3?&߯_1~Z%W aXd%æM;^z'kC&1' ,2 ~| ϐt2#CDD_`F/'ö112 Ȕ??~00J3k 04Xd0@ aY9*L#y oE`4.?+;ÿ;IB~u _?m6(]󇁅0f  !  fx/0]]{{;eV2~& Ž@X/ d`2d`b`af@@a_@/21_3}_7Э@`._ Y2p04bd Y!!P?p(S9A y;X~3ˋ_m?A=H?h.L@B2 e `"@1! mh:{ܺIENDB`KeePass/Resources/Nuvola/B16x16_FileSave.png0000664000000000000000000000160210133443104017472 0ustar rootrootPNG  IHDRagAMA7tEXtSoftwareAdobe ImageReadyqe<IDATxb?Z\~11004@az{>r /_/ ğ?/ (AU'7[*xvkwѰA !ŪDZ?e>,q6cd``b;?# 7P7L@^>A.~baFF@El@H8L@ 8@`db2Clg`27P32102C ؘA 85yh.'T@Af?mF#P߿ /! _??3|_w3WY|v@À/$Z33;?0FX fc7 ˯ L _12 F~3L`3e`gf@Aߟ@ge0w_S&s}6@qr220Xjb_P4 Vq2pbPt67;#ODy^- 4j@A4   X Y3|AT/F &l| ٘0ewt30ДU>ad VHL؀ /6}3p]Fh"bFWp|afxo參 KC4>Sg%IENDB`KeePass/Resources/Nuvola/B16x16_Trashcan_Full.png0000664000000000000000000000213310126541400020521 0ustar rootrootPNG  IHDRagAMA7tEXtSoftwareAdobe ImageReadyqe<IDATxA[e M# պA\76+*$  ٻ׬mlAͻJnd [gn >fz X0(11  g< _ %i~1pfP/˿_ Nc`cdj UbV`d.=eg8 |c 2i20j1}'>`cGQwXb`x'   ҆, 31{g0\yK?3 '{?z`  G fe`fG!^V^}pgd`b32 |(l 7L~ փL/#W>XYy8Medo0AAh*3Û^~5 pcx;ç/^ ,l b;e@20 '<:&}egxë/L /0|| ?Āח 6`͔څ\ L0o 3}%pób L|  Ͽ2ܽs  p^`ddcb/5w̓3pU pL, @?3}7rc}w[Azb ÷_,8lY?׷~9 =@ `*LwtIENDB`KeePass/Resources/Nuvola/B48x48_View_Detailed.png0000664000000000000000000000532010133443366020526 0ustar rootrootPNG  IHDR00WgAMA7tEXtSoftwareAdobe ImageReadyqe< bIDATxb?P8=@C4=@p02&+303&և Y=  ܿ >.Z 12z/4J|IJz!A1I/ /MPjB/o}k/ ?(?ʇšbP,$9qj~&3ݲJjBf&onF#€HB &H|tXU,?b'3v+`v6s!BT'EӳJuEvrOT"ބIT&Nl d~a`8_h.FN?:t93Kh L ?30ptDr5@2hC=  $?{ Y lL 6g^JP| @(L"" An H4+v##"JF3@c?4 yvD}"FOW0x ,cXed1a`df!πa1R)@H$1|2@v)L_%G'>2o-B|a`bbD BX$\I `b,:4A U b Z1|y#T lllp5fJrAfC*< o<@a&!,GgA3 Z1s6?a:'9CAA6g\a4i8&& )!! I5QZ3`-H:_,t ϟ?v'<i@u#%iX凜fH)聏 _/F?f̙SPJP2/@a֬h?ZJBlf L `1.>N72ܝ/(O}cj0Jԃ2'@/w(cb"$/F 21# b 1pa`1*톖0vD/%D, Rz#y~y䤃\@)6e A`$BPfS PJ!pKB_%3,31fL ǣP/3T Fc'U _^eTS`P_<g@)QC+Fb Pc{| #dQ O2=!AM6gAm#5e@a<HXOBH]]B) M ,>A@FA3{ e$>>:oxȃW˗$TUj@~ŭ[w1J&Dށ BBBYZEc l6?6}e` T_p2iz ޘ-Ceeit-^r1 l: ?IF`s÷?f`fR=iذ("#mP򑕕k@9LZZ!""HF@eeeIC<@1ܬE?2 }`` Z b76K{^3efw ~- i2| AA7Fi(ЋQc Z A"! at$4(@5$# F6~@Gc8D4P gX@iTW F<#C ꑿw`3yQ`x@)HoFch?'ZLE]F@6#g@dxGwQQBPfVzNF $>$ Ҭ45&Agt`H>fب;ۍzhZG1Xc6;%9>0gJїo;I˧D=a=L L,ρJ=L <1@ yА@ yА@1-\IENDB`KeePass/Resources/Nuvola/B48x48_KGPG_Sign.png0000664000000000000000000001057410125245344017535 0ustar rootrootPNG  IHDR00WgAMA7tEXtSoftwareAdobe ImageReadyqe<IDATxb?P## qOd``na`xpӫbp  1O08h|⽿_o]#hx sXp7N}g 7/Ywi o.@L#;f89 1tz2q30{AZA%)Z%y% H%@ (35i3p20(13(q3|yK_A]$ X@+&27ܑXXL%^|>ex.H@|@ /i 楪X^02vir2H30p-ï?%j L2<84s1 -D0ء4{W@_@ 6 *Ddz3p'\bbC^=Ű}Ν7| @=uU $@ߒxA D<I 5V :``h㙁h񚎝>$} #HbMhS;8aE& ;jwIsEf~`@2 Lbr.d), ,8f>g9@4?<Om5rMwwwa A( t<'09=aԩ6@X3 !9`f&k׾10&\s~C bKHE_mUKͮtpeֻ `{`˚|}n"@axH@"m㬤U&.YRp'1P ڢL @ y6n!q." ǟ1+4ͳ3^b`t[JS>asqЙ8`Sҥ 7_f8/ǕM8,1ƵW$)3(q.o 艳_1,,0 schK$Q%(4ۄAPtM 6f?dgxNO 6dv8?ݓ4:#ld@*2;X쩞Ĥ,u-,W!W2,({M5y-An Ġ?DRxӀ ="(-:#t}a W UDbikSEŀ 0M/:/R~omC$d3000#o,10,٤ʠlE| W !#!'=R-ufGDs W3p 3x3`Ylkc@`&0 o,&S}3|mİ7 /0; ZAN Ջ'H}艏2ql@tO` ڤ`=?Pߋ O3h0k2)p6;OWf]&rrEu92`.0z;6&à&Dz02f@AQ[`gbg01CMm <]׬,`<#k>{6}ˈ =X4~aÃ#0p% ܟ ߿|a|yr-)A"ĂO Dv}nyRaQ+U ?|dn xI#ã0lYy] O1@;Abо ~IR YÖ-G;} P0) q(;Z7 @ HpS /־dzV A+U3DJmyykwf$A j_"n[$pg512*~C}H|8Jz~r1k+% ö kڷ2y 4?g%@㍠B4BS@yy 6V J08jh]lixc: u'`oN!S9qMgI8ݷ xY!2٠4v"j:N AkI1y#`ɛi3Bl 0I=y2 Ʋ ,;CM~WM,{@192~ؑ4T#W̸PNfG/"43")LR0[(16{aHa9!1/pq#D$7RbKyy{Cz *Ҋ .lFԴ %䞽gpӌdBYJ0 e6dQ+F0z/`U$j A`l|6ch˽/`o ] (\@'4 wC[ N3dг@l:@,^,@'$ZESfv> jqAd OPH>% )>g޴A34?!SM>g` uy| R’!L Y;1f` t3`50V|_>W@nfAj@} ZqcCځ$d60]L6x"u?@C} @ y(IENDB`KeePass/Resources/Nuvola/B16x16_History.png0000664000000000000000000000221610133443064017444 0ustar rootrootPNG  IHDRagAMA7tEXtSoftwareAdobe ImageReadyqe< IDATxA) F!%\%= f+`J/0o_?1_V 2r{ɓ[oˁ<@ ! @ʤ8Po_1XH3+,Ƿ~`з{ٛǟ02} foNII|,~3HJ3HJ1 2HI3003c`fG^F _@,,&]B,<վ3k12;;ХEDDd8s-w8(1>|ӧ/ LL 0 @W02q22J``bJA<G<% *"#**% J3A +/-55-"" !  ?#;?0daaG#u0ܖc02b+o~ ?@볠 77P,Qs#seexX;''. ? oo~ȩ a9 H!{ GO_cok&߁^q%̺pm%:0/=}+_h2{{ yx}7߿pןrVAj8-    _ /B|{ϰ&YVYi!/>1?6byMȁ!S  {Kf`Ҝl 8$XLD9gx\xzB 0D;|f֌&IENDB`KeePass/Resources/Nuvola/B16x16_KGPG_Key3.png0000664000000000000000000000166210125245344017434 0ustar rootrootPNG  IHDRagAMA7tEXtSoftwareAdobe ImageReadyqe<DIDATxb?% X@Dxx:b1r&o}n=n@ LHX7?)"wf&W|{| <,K{FGϸTb=ܲK 33#жYŰZ VAF````dbfx֍Xc{ 2030\\ 0 tΟ9'WWKÇ0o+}Dg8  6ǏWXX-DDxo  `ve{*p ={tOߏau&Ó'~h60>|22pp0{E&_suSH[ ~AZR-=4## bҿ?~z̹#n_`@1((H:s١Czvw 2|<<<˗o?}ԥ+t7o>}͛w,,/^g.(033 n_x7/f PJϛ7 _x[Gn G o LL nfPWW1-ZŒ _?`b/;#t&"Å ._>0Ǐ':tƻw4z?0 )MYIENDB`KeePass/Resources/Nuvola/B16x16_Exit.png0000664000000000000000000000174310133447116016722 0ustar rootrootPNG  IHDRagAMA7tEXtSoftwareAdobe ImageReadyqe<uIDATxb?% X@JFF1 3S>?ȿ?=|ų۾TsTm;rbA6 (.cfܧ% 0#S7^ub@ k0>EDӣG /]e' ++ U_i %Zg7o`gxw" ~=7P \1,ݾ/?@L`Ss4 ]YN10O3ܹw7 VRp 2^3߿3 ' 304{W.1 @0m Ë$6fxf( 33䗯 /;;d 1p= @`wF6@'=}?oO ?N`[@ bO_30 0ym wodۯ Bֶ ,<| _do O_l{ï#[;Xť~`fߟ ~gx L7~[0q5B^ `^*/ :#P+  FJ3@c튢BIENDB`KeePass/Resources/Nuvola/B16x16_HwInfo.png0000664000000000000000000000214210131265442017173 0ustar rootrootPNG  IHDRagAMA7tEXtSoftwareAdobe ImageReadyqe<IDATxA5  )"A ͽ| [\^ FF cu< ?13XOٲn +@11-C_ 1Xcx {P,Z@CP  &>A:3s g_Y?c`xF@=#g?Xbeb@HJec`efdXtÇ^}ճ~/g&~2*? @, Fi_ ^a[M1C&Cߜ 3{'#sπ' F j gx 0 &˟?,߿|c4fW0y ( Begc ll=|a̬?QA..a7'6?~_GoKo#U'̌8B}CK?̌ L;"_ J xFFFWD*a6IENDB`KeePass/Resources/Nuvola/B16x16_Binary.png0000664000000000000000000000150710130001210017205 0ustar rootrootPNG  IHDRagAMA7tEXtSoftwareAdobe ImageReadyqe<IDATxb:a߿ LLL  Ab lllR1aX?X{@%XQ3@U陹dDpww63'sl0 @1bll\#Vb&zfZ 3L"UÝfO1 rǏ60 {$r.'߿@jA@ -[| R6A -7@~<<< W KQ(l!!؂XHRݱ仫 \  c,l>d  pJx "03S.nfF}(3 V"@ MLL PL  9PX X@ ++ ,kkk@ @lk Vp @A 1H  ={6@R_ATOY^7 ߽cbXYx X10 c(3bkc)*U~ Y``p018 `p 0= ,׮3toDZ 301ef JFɴ>7蝿aa`e{~3(L ,@w>2fgg ڸ?oUJlaA;b)KE}IENDB`KeePass/Resources/Nuvola/B48x48_Folder_Download.png0000664000000000000000000001175610126472456021101 0ustar rootrootPNG  IHDR00WgAMA7tEXtSoftwareAdobe ImageReadyqe<IDATxb?P0@FFF+ۯ鳋۷#@gϿ!ʚgccG˗/[]pߵkn<}tϟyիW>bjŀVsf8(} 7nWo<? @TVhhxN|c7o=t{w/|ϟ޽{>I=TKK:NNvuu0p&57n8\rΝ[wIm˗/ډӧOj,j $%% K߿>| Lj߿K<{ӧO;|GФ/j>ʞ^333x?~exÝ;w{߾}}wl޼8PbbK$ Ī ڪ ߾{{m/^<[ܹaÆD59*++Ӭbcc555`  # }Sqq1Ծpb5bNfihh$ bGZ 9A \m4&&F/^2ܾ}/DqG~~dú% 8,`V0  T12k?1| ?f``b 21ܺuX<| ꁈR@ *W$$3O%6L|+#C tf`(B 3t$ѻ W|gó?=P#^Ira: ff&ϟ2ܻwC  b" "$+# - - ) կVu=y_ff2l >~c3o F l 32(dЊ fzz b+yXjr22ȋ2Xq3ȋp003r21mv|?@wpG9 ldAI'zSV~ @$h%İ& <|PA@Qc A!~6>qYl | / 8z@fxBfceg @G}0fG84DCKGC< 9Pew d78 | 0&@%P h. 6OhIP~?Hyʊp7`X@@0CCɡȎAD%1`Ao?A1|1<{[}J> |СC-A!*aX쐿1S(Rp!!*3?3\v pZ O>~gF6pM>H ?" Ia,I?ZL P$Ąwp 0O wo_yoP?RǯA ;x[!%;+; տ$Rɏ !&w~ t 0?pڃ˫A>8ϟ~/؀ٲ?PGEr*FZ)`@*(G 4`cغw数gU j nlp?z0C@6򁙗H `Lȱw, ypeBZ9^BWϿ3 :K&w\ y? ܼ._[p` V ؟_?'g"veqMG~~c3-,`Z_Eǀ 0889^ }PF.99pC˓_^b Dcw_53M o.EaFmB2`Qq|O100Cԡ!K+<`4>wO0' /=;d-Q @_/]3g0[0|{ٙRWT2ڱI&  ?j,%*&>3ׯ_<|IA聏0w (} @O?| Dl, _} yف3}!gH- D.&*?+;`|Wf?wodt@H1ћW} оCݯ _~#L?E# q yFL J'Pr2cDo^3<7oO.}dTw޽?젚N _P&ByóC \$[`mh[#(Bx|/E/䁟 |v8~̼,6nyK#=/`K%+SIfjĚ@ݾ  7fz@ Ă4z7`Q>L0TyTt>| W=aW!m  1cg`688]Jg A_ݳ{n01=y>^V6P8x~ 4bSo= ``7Rra,L ρEѧW~xX3a?p灅 0_-[F`Y 'jbg & A| {.=,2>j'xIAwM6Wc/(ç?oP?ֈOBXЃB$l3ee' w*G1 2)1pp002ŀE7_\cxp%ÿ/]6[x9-^Ge>߿+`=1XYJż_k]LÛoMW?pc@aM`f`fdckͯ `w1|yl#dlKI10CbF782c/e ízN erc/| 8d-oq&*G 0p0˗&'`ب t-022Kf`]sX1H30J;?(R?pUtOuI)vdAԸ>Źy tݩM?Ip/(EQR@Xe nB <2Lϑ 7{xd !Py68W1hK2:J3 K1 ލ_]}->?!@w%ov¹_Ǡ& ) ,4HP ^םX2Ne53vl"07 .܀-5N--G7_293|v/C?J @ȥG 5|gx|nXL~>ɛAB_f:uyX*1]//0i_dx-ïOj˟??21V$?| ??3pķK  l`a67d _`lja Z o9_3|6o zP0?tfN!hAyǀ#/`Iǿ?>˫{?|a34 u M.?P>J p͑q2X3F,T2s{l%?  ECXj?d;a߀-O ?_c0'`B u7(DA'~CEc҇3ğ{\fcxX Y9/H`r bYJ >ЁF.?P8t2Rq?"Dh$ 9)PGZA%  uQM+`=, IENDB`KeePass/Resources/Nuvola/B16x16_Laptop_Charge.png0000664000000000000000000000224510133447050020514 0ustar rootrootPNG  IHDRagAMA7tEXtSoftwareAdobe ImageReadyqe<7IDATxba20gexyy qzBfշ?nw~~hF}wϟ}Qgb/f`{4 @0112Oj;0+7o}S7lP{n-憋?~:}hX9eUUU?~ѿwQNÏa'@Az(lXDCV@9'?GYLB F&vFFnSN^wN~Aq`sm+mk 10cfr`~zsA}<>A[%'+,5DZ6t-7y"bÂs| TWYqmeWfǶZW* cG Ȩgbm_+7X 20013003q\c0uz  Sm A0yOR # AJ'( ]Ͻ{ȪAd4<N&(V ' Aw][4 87@ ۴@ԓ$vn } 3 >9Gzͮ\Yxz3Vm@ @ , \l ȠP8s++~ig=sc P d g_ >3LAXܷ?1, \XIENDB`KeePass/Resources/Nuvola/B16x16_KGPG_Sign.png0000664000000000000000000000166010125245344017517 0ustar rootrootPNG  IHDRagAMA7tEXtSoftwareAdobe ImageReadyqe<BIDATxbdN @c ~/d3@#wv# AB@ BK}k BTwgU37 0j0\B>M+xXqTbJ1#+kH,2esdUyn=e`X\e |!G[Qk?;G+Pq]l/S`]??K@؀X&&#Uߞp3ީʰ /sPV ف:P77_=_AWJLAQp#Fo9l>|hPbb 4C1777/'0]H þiLzX@Cc 41A2h8+3CiL ww 2te b~T+,?>p'2~¦'>!o 7s>{c@r 6f(t Iևn>e8b=~'W@g7%A{GAIENDB`KeePass/Resources/Nuvola/B16x16_MessageBox_Warning.png0000664000000000000000000000165110133444024021524 0ustar rootrootPNG  IHDRagAMA7tEXtSoftwareAdobe ImageReadyqe<;IDATxb\΀g`P~@sb)ϤNŬQ'o: a`P27wtf3b33` 4 /0|%;;[W74 @(.``.ib,i` " -"Ơt4 @,,,i>| 20s0誨pH0Bm ɚI00143wu1bfP` P @L<gv3ܽv̌Q@;M@ x.& , ",#''ׯ jsy @㓕Pۏkˁ]%.. -- IX. ~2qsqt @1AQFEڋc*Z  !^e 2#P(  tV>L%&| C~?iII9@쟿32Qd=h@`+#/5{0/ ?c>u*Cco/o `%8のA zWb,V`fuïW?o\ F =޾ ?>~l YY q7K%^o/^0f1~g?@Mt #а 9\%N/@l@_Lhge~ ld"IZ Y IENDB`KeePass/Resources/Nuvola/B16x16_MessageBox_Critical.png0000664000000000000000000000201010133443724021645 0ustar rootrootPNG  IHDRagAMA7tEXtSoftwareAdobe ImageReadyqe<IDATxb?% X@RFF_ jo\7Q>˻H1,,٩S7]trb`!PVc/NHBD ӄwGwxx5 6`O)u=<[9/JPG Ry')oܹۿ_!6_\?H/@1񶭻^~6e>ov?1HdAý __?3ddbP= W֮; @`e`Y$)uX4;" o(p, /@̝۟Ыʧd@zf7?`9e xx~|g_ r334cok{ݻ O@zH(0 .EB c U: drty ۪@`㙗CXdߎ] ?ņ1z+ofv3\e`s!g!)-@D@zlU+݅~f@ۥf2(\dЯ ^jJ^$p'$/ 03(N_߈ᷜE XX~p 6A?"  g=bzvL 1@+kF.u10ϕWeWjAH;8CK ۶\)A0dqIJ e"* avW:J"3]A0!3W0<S6.*#Y  A/"[/'0$M  YHC/Y~Uaga'.S&W3x ;?>93\˯\1 %0bb> GW1~Y y' @jF(ef`bdCmyLo, #Hiv0P!3#IENDB`KeePass/Resources/Nuvola/B16x16_Spreadsheet.png0000664000000000000000000000173610127777600020271 0ustar rootrootPNG  IHDRagAMA7tEXtSoftwareAdobe ImageReadyqe<pIDATxb:a߿ Ȁ y&vv6|oii) ;]KK[j?C<< ll ,, \SN F?a`x//H__~1<{AZ$ l  \\  cjԉ%$ ǥ,J,&@/@, _͌ lL@CL|fe 0 r@1!^pc̬@t0;f@@ ?72?VƟ, b\| ̬@/@f9M wXyV\,>!Ca',< %<1 *`C@ X@ ^`8RmQߚ 52,c}_g2̴v@ 4j \ \ \ 3q10/,Цk1y+?00[2>`>=0 ]Ġeeb+ v! _8E03]L\Y,\ _~ 10Ve0c+ ?_ԅw1L87*,~`bACZ, @,̌,,, rPe04dãOpe lvvvPd s}78sĚ R 2"RL _|cx0S0\rϿ;QJJ* AA)B Y_߿? `Qv u'IENDB`KeePass/Resources/Nuvola/B16x16_Undo.png0000664000000000000000000000130310125245344016706 0ustar rootrootPNG  IHDRagAMA7tEXtSoftwareAdobe ImageReadyqe<UIDATxbdXY7|׽bBpUSSRPm'8@(K^~[soFJJ@@0'j7nWG˖d86AZV@QU//ß? bЏ\aZ=^ހcg~@L,; px/_20~ _``x ?ffsPzr ֧O';][NMo޽'O?789?{8b?}:= 5`i0P8. 12|ꙸ_ fS|;'OZ꺸sq1[fӉ;W[B $U?ٷ@aymk--/}3[YRR{@))HH$ ~~( @ Pº6yu54lTQKuuuϞ &2W'c`M 2؁.0@f`ڱPlMIENDB`KeePass/Resources/Nuvola/B48x48_KOrganizer.png0000664000000000000000000001451410125245344020076 0ustar rootrootPNG  IHDR00WgAMA7tEXtSoftwareAdobe ImageReadyqe<IDATxb?P0@ y `ddda`e``bb(.'G_0|I?X% iiL}[~=e˰ F2P? \ @`30&ǨWij)h0ps07߶;U8 y G]lfP3@`g` "Fz22a9؉=?;'E~=g7=-ŐT6meOk"A?+7#/7@_?eͰG0;~b#0,1@`: 4-R1CL%g?\fZQ, >e`&4D`$CHVVF.miu[ 9 L6&`昌eoT-ߟ XإDYx؄XBD.|`a軼I&7 | @O0'@ObV&`e-` * L?3?#m& {OYzݫ.@LxPL @eo]c(3!om(_W.%?3? ?!3Ʊ asvCyõ?>FC{{o ɳ1S0X`0C;G̼ww`J gPaef.`p&pHq!-p( &` `W Ì`Pd`ffb`eaa`0cpdraޏ9 : ?cx/`&1o %L}d"M86 ,YPuTo-GL>}=a=##k?0"?ؘ'Y[&[Sbdh 40 3ry ˉ ?23!p(QC[" N.fxx1#*`b`xT!D3!זAJcC" Ñ f4b({M zxf+O2dwD@`ː,$ d\@03Ddho z2\ X8_a^F?C*uW71|߁u ?Tx-,16X8Ͽ0HJ0: XL{FW_38(Ï?? 1̈,<A@M6/ f)1I_c8⥭&j!"_34n=2A@AQFϞ0kh- s?4~0mpAo0y*V.L38#3A➁чG {cEI *R78&= 4Xg/33fx`. rl ;߼dqu ~U ` &h a ޼rĄ~1I}fXr(+4+1+{f9 IQa&P J1.=x%) kfx٫ oaOû/w}lf ,Hb X8zп6O7?:  Xn}Կ2O\a|×^+?p/G~3<݇? ߾c7!Ou%n>7'! _ePfzAa +0LepU ǀ!?e}'Sws115qޜİ`rn F/o ?~`8|3/3, 3FEyE`̰0cD\`"ư3h-;O)M KfxGv72b!Pc , _ξ0ucG3s}!Eq^ ?2zAM  `l 2 ḛ{O?mE~3Jg8M.y j\/uOW38XPb(Q0 Xb= ҙA[~2~dì-ױ7 _@ hFdCr9Ykg`p d`!Cw /I3|~`y_31p3[@E aceT eXrb -CA"0V0ldq@U.??k3,IE/܌ԑ@GO}鸳lপg/_>0AUA^AV9# `b,Q~O=p+YO?6!Iˇ!8@!/Ȁ!RՍ_+24Ԁ,oY8TdIį`C >~b^<\ _l?1,>ܜ7C .`u^POR_!Pٗaɻ w_b`ʠ+`?PaX)9)Ltku^́0V??aی\q8m>2_f3$ wFEv9i6) 6afp?w7?k?0 }fm/I2T220 ^BzT_P5KF뺇 (Xրr^jbP:C_`> ه? 2 . O?ex!>ͷ|ǰv[  N f'y`1V okJ`; ,pX?H;R+Z}Ĭ "|>2,>\߸z ‰ص`fgeacbq`&u`xMЬ3| 5>dز3ß 6`mjaC,3GhT`F ]T$BȐ"ur`)O 1]&?d L:JP~AX!An`ej`X 4X_3ߟ2Uga `d}a d|áǿEՀS+#c`do{(Н/=;`T>6T<` Tcgx 2<f;A`rz ?~g. o 0`OK1$1xS( ֝x*&̠#`o&e*Π!l]P22@`:!P?<=zfk]i! I⃯=1`Zt /9U`1)I`egflq1VN`G\Aۜb>/\ 4Mfw|gf0VwYH`dK`'_Q&%L @ĵ Xq<03s_`6|p;G2(J*< oK Vpu/H2zg1qbbPpebF@ ^8l _o30p[Lo^3\ƃO ‚ j "~3K"^~Vp!`H?28v9X$$@yLÉ.U\~(C27#$⁻@i ^}.?E8#7 L}lqp ˝ (VJ@:kP'XcBF;l \&J_DVp2-Ym`bav`dȀ P< %#P&W>TF\5?2,7~vKcP/]$ QP$ l;u bqqn9 ;a /0d)p;qo3q30 =v!VP~1309 qi?EԃW6ΰws{uD2f`AKWA,< A ,Yi&֮ o3@Ao߽̠-} tX3;FMX@c2 ~fd`&]`X Ge8pV6͟z!6-x; vj Xd$X4xe#320  660LQ;~ys =Q@C73D?e:Ew v& g#` rKTCW`/0f ߁5^ a`7;̍CAc6 s0õt zOb⭓ U03pz3.3e8 t?? :2ҍ3ة|a0 /4쯗'@]I` 16s/n?B+R/`w+gaoN>@1: qJ-+"@30H4 )ůge`3ثaPx͠&XG| i KfCW>cH`C=zۧ@6}?{ lE}hV r;@40@Chu6vەX䁼߂PJ|a};3"F"kf`/`+>o^ex7} ď0sc`N%XMr;@t flHl*0A,[g`_F,ypkA7C@]gQj|ĂK'8ꙟYc v 13|ֲo| T/CCC!(T?! b _e j Z ղ쌲QsC?@G} i8W A@ n40؁f7pبq/!V  )lfJIENDB`KeePass/Resources/Nuvola/B16x16_1DownArrow.png0000664000000000000000000000145010133444022020000 0ustar rootrootPNG  IHDRagAMA7tEXtSoftwareAdobe ImageReadyqe<IDATxb?% ("fb`0t̷qq0g_? LY9$2cfo>@ P*bİKnN``eta`a 7t 3|=^{ՋB-dR  Ld>dO,/f_؀wo5g++Рh~1\S(U7R`՛? _g` (ijj^aARI?tfs fxӻO [ļ 030r6O!. ./j'"`_Pk13K= `1__RݽW/1 12()3Hk(2<}aq5 1ֲmz1Hcbc ?~\ȴ^k 2 |e`e/?q㥃130O߁Q.PSzB ^hƒz~dЖ LL   X|}R1hvlI A1.0%D?=P#s@F^⃉{IENDB`KeePass/Resources/Nuvola/B16x16_History_Clear.png0000664000000000000000000000225710133443060020553 0ustar rootrootPNG  IHDRagAMA7tEXtSoftwareAdobe ImageReadyqe<AIDATxA) F!%\%= f+`J/0o_?1_V 2r{ɓ[oˁ<@ ! @ʤ8Po_1XH3+,Ƿ~`з{ٛǟ02} foNII|,~3HJ3HJ1 2HI3003c`fG^F _@,,&]B,<վ3k12;;ХEDDd8s-w8(1>|ӧ/ LL 0 @W02q22IdeJA<G<%BE?E@.3A'i -溼  뢜?#;ЦvM R jf :720>Ubo_4xLFSTt4^gfx{$\| ϛwn| @LQƒ|?7` 3;s῀;Ǐ~n ~CCogN0>IqbǢ~wWn\g}Qo X~e`غ Ec~"5 Ae"*@)-穪  칇A$޾BRWRßϟq= b%cS_?0ӈ<#+tA (|a+L":2 ?c`yAK?/2lW`0aljOWeobd= vf`Ҝl 8$TMxr×sK.{?O܃esRϽy_`*9p4Z@IENDB`KeePass/Resources/Nuvola/B16x16_KOrganizer.png0000664000000000000000000000206110125245344020056 0ustar rootrootPNG  IHDRagAMA7tEXtSoftwareAdobe ImageReadyqe<IDATxb?% 96zZS4M9}^Ʃ{%0qp0rzc#@en+@1Pp4/*PG/aVa&?3|raB6,ඕo;&ga:OFMA2-Wq.= 1b =̃p 3+A:·0Q nA5y!MA9#//2* و(:Aa#ΏA!+ ]B0,  ńͬé^uˇ ϙf`7k5]=FNo`%:\ x@@g>'+V7@X~r0102ϰ<חDB4~2 0H m=x7w 49ɱn%ɠ _L B 3F33|[o> &[8}^21oFdX8Кȡ@O#g/v6+? $I3#.yp%71Xap4`8'@ ۏnҡX_| ?1}})"޻ ZO8a`x [} @yQifWzĠ|~֯}{5ë_'iBL :v39 ^z OaxT( \@@Ĉ;YXd ? a2\ Vjw*IENDB`KeePass/Resources/Nuvola/B48x48_XMag.png0000664000000000000000000000730310131465444016657 0ustar rootrootPNG  IHDR00WgAMA7tEXtSoftwareAdobe ImageReadyqe<UIDATxb?P0@ y 2(Mu`aa1egg/>|p˗/~'Z~?j;9򀟟=S27fab`aff7çO^xp7ou֙/|߿ <+ `a`'Û?~o301sp0p53c۷o[^|hWjD^^^s\\\lmmxp_^}d~30A5OmU!6C2]'~z27BCCt5~ɰ"á| <| Z L $ /~>é+{ gEO_3̞=ܹsShsJ<r;@􀻻SSS>0?/?9+$+ddU20p- VB e8{L`Fo*{F'@n :^z 721?`j`r$331!@ L]7zd5ï m޽[ ,U$'O@Vwy]m YdaWgd0sؿNt`T/&#Ű>NHnn|`f d@pvvQSS33ڳ| * `ǀ@9/?~7``g`d.p5ccsss `rx 0<ʚkgg(,p5/ovvF!`pCc'~?9̔|fx!(28=aZ+((hksÉ RR ?I'4Y';åodttti h$zˀ@(5ɇCHgn8 B yXbђT ,@$^e 4dT̕؁/ ܼLD%I!a7Z@eĀIJ @y@H@xh0~cfcd`Zv\~@ed`SMف42gUcx7????RFx Pe) 1&FHy+Q=63#&B@13@ ?Ó_jd̤Tl`T 97$#+k 9Լ`e$PY 1i? *韓T Z&8ʂ2#< adL} 3 g`3`&@(0żPKZ@ @ft@i_߀ _A<ڜ @(k3 3X4 mH1ً{ \ Ǐ5h/) v?|" md!70iqB0φʁ 6'4BA}*/ãǏR`!e @(!` g8Pe!Lu4F;4BcT@[O^|c$dr (=H?% ]~p3 3 ,iTg@M: oXL䑯@sn }ڵk?%]`s)PgR+2B`T~[9sO ?;,L@|Pb; ##p1w:؇c7R=@荧[ MM V`)+88-<ϼ LF( !P .[ 'ScǏ}%O۷dz/~ ˯K̨ˆƇfH3 Ga`AHXȑ# ?|x @koBK!9[իW[(l `xO Hx1ʈ|ù[^fgPdHHLdxۆB=de`x =@: am ?' >iFn1.G 8So@g~S ϯ6xàl~2TTa2bx R| #r X|bn2#z b O6/_x[6ɹ=` !!!+ LĽ~o_z sw%-_?_J~{jͳ{ "N20?,x8j$ "Z^޼yC_Qz yoSh%*?KW7z]URXC> 3h!E0o(4ɜ|Ow6WD:9}X^(怊*@K/hXȚl0ʊ_}2!1~`Y~w@O{= H@JVuFA=GygN`ӳ1lW!1?-`0WNx zfHG`Xrş: > [Pe`Pk2?xN [<@9d PO>X[9>5v4ABh<&' 'ÓV3$&wuPd =Ow>=w+t|MsKo0< {@ %>C'^s13|~ٻ idO5#@ycP~҆w>d8 /X@pO承 OӼ5×yɰ{@""A;`B/Ud}+`_of_`Y[ xeꬸdt~d` y½4] 6?Q40@Mn+ßobdpwԖPfՐfeab_?3cdg@sY2? ?~f+#+ +$lg~f`va}HnI? 1? ~|atᓗ~'_6 c /?#õJYֿb-<0uc3Jfb,qgCo(g$۟ 1<}U=]GpW\;_zwp4\ϸkx[mBA y;6]ܽ?|;Wn?3LJNF5>`-0}lyI!//^1|bdx[G9 (' ÏL 9w>}dxq +c+?0|zà( ?vc3+û?L ~20pE߼ˠy ]gh?U￀F/@`=rO^M e7X\>IENDB`KeePass/Resources/Nuvola/B16x16_Folder_Inbox.png0000664000000000000000000000076410125245344020365 0ustar rootrootPNG  IHDRagAMA7tEXtSoftwareAdobe ImageReadyqe<IDATxb?% X V|YL佈g蘡s?C6kljv3KW>6\jB@L~gd|K1ckd1B(> QFd9_2~x.8@14os]Lz1\n7"<"bb(@t=bX@.kFJ""ƠEcw۟(aS @R"rb™ J76 #h S_ ͰiTa CA@4xxJ2l hNNd+ÿ__70`d\@ َ\s> # 7 0LDIENDB`KeePass/Resources/Nuvola/B48x48_MessageBox_Info.png0000664000000000000000000000736510133446754021050 0ustar rootrootPNG  IHDR00WgAMA7tEXtSoftwareAdobe ImageReadyqe<IDATxb?P0@ yА@ y 6AFYěJgbC1hi% ?#Pw }H@?>(0zQ!@,T# E1# 4XXX~7ÿ?@i0fd|ļw%Z@xZ_عԴddD$Ex8_3z oU3i GjG#z@ LUtd$L0 ?dҿ;ow0ܺ|ɵ; EYc(/HIBDd`Ǜ_\ݜJA``v?}  ?_ wo?b(û|pDx HIB@SW̐!"ȘASAL6/|c8y6÷_gRg`afd_G7@n> ۀ(hb@z@ 1wb 6dGX!n{=WICuU .fX70 = 3 +'G$|Ҋ b< 4hVR" ف! " J􏟿=xБ #+cD9ZV8f3$û$30Hh3(XY 8D@ x6* l;/43? FVyg ~c2cPY4({ {f Nt ^.v+~0 & faectõ'?8XjQb //%5+7'0k W }Օ\d<$++V&6^aK cw C Bdq|g&yUuPԋ0  Qg12RgyG`|i1~#=b7DE$8X4 G  %o`3KNeeؚĂb%WDOR'!N"eN߿ * X1 GF3 #'?ç +m.; px1D% e6N÷082+)t : >;O _ٿl~>`=?4#( @|)%)#&y py@c`JMGndx?C)4 # ax Ç/؀!vVN66 ̴L L gsOX2J g7>wnnNV~>F[ͩk255} ,`Oȃo?dP`( U{ _ ni&6{1z1?pL'?20s00ߊ؜ @8J,L  ߀ao .fPr`)##p k%'?>}j%'p{T~X@ǃL@OBS G 233TL@ת Ӷ ֟pX:L_IFAJBa١O +b`c@oBH&$Ai/@458tjTUAkHIX a/ 7>?#01_%0$)`] kz1P^}Xl(j`HwABء}a`caPga`gN`ef8pxL0B[#~ L2?d@ ,Pf l \@򍁝X| }g [~0z y`?M03PہR{3;!]7X2dLہh, pL'^`_WG̒pO_2|F4,!1E߁}ϟ203" s<0)1=3+>'8as(@WA /e "`CQR4C=.*A^FkCw2sȇ&5lN \`}xz0X%Zjy?, _I= %6vn_ $IlN \1{~| ܬ BXdGdtFH GȎx, ,ï'ρ;ͩ~r.88 274<1=9c.~`ae@SWy0zv. " -̎ QТ ^|bfȃC7c#|co_%W#J+T@:4>ۯGNzŸxX #V$H @C*.x(j&on05+zp p$!X2kʠ!l]w34xd? E!5?`d20 s12_p&%SnI`t~?xr 1_ pFX([;zZAJSAK^棷 _?ebeegp6`Hud#P+$J/>24EH3 Շ^0x`3B^@W ]y3\?<@؇eЅm],lbJ6 b* _5^F30yI=ue04 vNpFz'O^` 7/'(0:`ψ9 xjlp+@;2w QXv{a_*002|?ҧ'JV =+>J<80Êc'`v  1x0@. e) >篿06!QaW`— ߯du!(|&$ G N:>}+!%>y``P~Ƞ=ȠrԶaL~6̬ECXisK8 HIrИ);$  Lz @|RI10'2, J<J?oX # \"̐)&P{I jUA!y`lʮyMtsd1*CV1m6)W1p74?0S07; ?B  ơ <1@ yА@ yfWIENDB`KeePass/Resources/Nuvola/B16x16_Edit.png0000664000000000000000000000133610133443164016673 0ustar rootrootPNG  IHDRagAMA7tEXtSoftwareAdobe ImageReadyqe<pIDATxb?ZhǞo{& )4T(ȴm3WZȀeO(b ʭ' Vǰś3>x99@##KUi)q?~@%@#Q``ȱ_~  ]=߾0;ӯ l L@ bb\1QI\|wt?o&@EZX3 9~Ͽ~fd|`x-4y@()) 00˯ ' 3\p=?5}g``cPPV 1>}? s2{xFF( >bx _~ w>z!pgbPM_f7 ف.d 芟 .|e X~xúSY88XATw_(UMw ?=-//0'TyÇāa ##ۧwݹ7o^㊏OcRd* N`_ L JJ:DvΕZ@̊ 灌Wej&"?t  <4S~]M$5oBf9]2yKvivbBА:("L?xl#t42x|X #Ta( l T"gv1_TE3Q6 Oǐa###ݧ)|7?~ gˠ'!*@@E߿?~koh훫'z/_@'- ߯~A Rgcjo,G+H %  Ѡ}Aq"+_c ҦrOKs1 gdt~1>2 ث@ͻA^ w~o|)7Ms'8`1M {NOa81uE bfdg,lAڇeu5Xĸظ1z- gn`8=wow$݃>@DO7?OXߨGv@e^#rR'V? ^ӛ]+r#@!+ 0Js.dbg 1El@ -kIENDB`KeePass/Resources/Nuvola/B16x16_Attach.png0000664000000000000000000000200210133443526017203 0ustar rootrootPNG  IHDRagAMA7tEXtSoftwareAdobe ImageReadyqe<IDATxb?% X[w6>!.n?V1E\\`e[nOfey a`fd`bec`&D~ͬ*&,b3^`d@[\Ahaаc10`o0lo~j|;x?N?d$ou+uktխ{;aQzÇԀ 3 +*Os۵'+#2Ò[>\_Eڷ=k-G7bb`)M[}v (lİr٪OE5RZ!F&&ibisQ롿i ~Qeq%~}|;CX]aoNϩ#W~-5c\A%;.UzG/ ' sl +$IkW@Ʒ:TRLA"9#)s| 1*DdT87OI\ ׯٹxw˧.>E)ΩfdƆ N~~x#K4 # ? ? L"LpkdK},'cDCޘ;+óze?^2 V <>^3 v_闣+$gl<|`xVF?L'@, \\@|eF0-0aQY9@o  X~ /^<j|7o^?j\3 Xm W^+^rV`ZNW>`DeUIENDB`KeePass/Resources/Nuvola/B48x48_Source_Moc.png0000664000000000000000000000641610127777704020077 0ustar rootrootPNG  IHDR00WgAMA7tEXtSoftwareAdobe ImageReadyqe< IDATxb?P0@ 02228:::qpptrsskc@:_~۷oO~K/X 888X*))m.))RPP`/IR;I2333<|Ǐ @T<@( @ݢBL 5S9h_}/"J)o"b%aι*d c@ "ZfF^ugL@1. yd!,:M:|jizAVV ( H @adb`H2b_!V6>>cqb6@PHT@ z:ǣ# 3%Q19k܁[@Lb[t21w ` ˣx6v?0y ##"DJY tC1vvf VNNP\N6L@s1t-c #'$Hn pt 02ĉ g-,͟ϰ&$ٳ`Obgaec4څ D2lbu uOo,`hlI wP  ?-c:XJS('þ --- Zx>x=Mp}ybN r{0|Y?FvP#)bW3L gNDG3l PC$(6cX LZ7Na0gjße KxAJ?`7 {ٻ ,>=7p'!Y 1HJbd 0ml whgA@D!à m=e KoӫX_g3f`7bAKtX8SI B B>g YF&I  _& * * df! M4_fX9Aϵ 6iӇx00Joa?b| 0@aMB Uv` (9L ҇ZI׫W ߀zEo89W!靁K<j_@@ˆ M O 06c8l308/<?`(=9|pPqJaz  !W>3`cH @, m,+> ~ ͳl{)@8By Ü9 Ơ7W+3F4kcI j$C F71Jd9 17:4]rᑍ-  R\c v10ga cwXoZ*E=$p7 -_|bJ̐J+l2 PZ; \||  m'8ba/×"'VaڈaPzM~)04_ax M10c d` )jY+0;6ik3V(i0&6PjN:$@۾ϰ?o} FfG`It#j @$<@xs~eP֬Rc}=<ի1>de`fdB2"@-0Y<kz%D?<ˆGgsd`[ǠS›' _)l]&60l25eB8??0Kj7x<   ;4ʘ ]pߧAm> q-R/Р [jjMoP @ꟽ|kQ`_0Zƃ?3wn]ߥ v @3c o=/ d<cpXTk >6x ~bx9Ë $ê10AÏOL?0"ѻb BXFLJ݁Aڊʈ1ʷ>+EBD%B́!DިPͿog~Œe1le<Ȝ;yC5|- Rߨ__RBIJ;`ӈgKh,gmЖ'(ά b!w\Ͽ? |< n b 2<~`j" fx@o wmByy~M.1 O|!(aiJ/ {6bx++ /6F.Np?1 RFb0Df%3l8ж3Nu!`Z{&!?A@HD 9R g?? #yM`O,9Ғ ?}mbDǖP1J??} %"НPɐ ATA?"*H] -_? db r/ٍ96J qb{|y Ȟ!w_ K= X5HՏĂ9/TUUU<Փ a^^^}} 0<׵˖-kD/dbXXXX@nb(((Ѡqm0 FtC!ꤥdddE]sO>PGdĻ~ l5$XZZ ԲFݠg. >@a,ibB4y?V&{ p^_65IENDB`KeePass/Resources/Nuvola/B16x16_EditCopy.png0000664000000000000000000000133210133521102017507 0ustar rootrootPNG  IHDRagAMA7tEXtSoftwareAdobe ImageReadyqe<lIDATxbdЎg`Ij?1`a#33ӑS H_ l||NeRF2 Ă"Zd?bUh??!?@e\ @ 糲1 faF@ 2  n:^^KfF&gn0x%`ۀl# Y_ b pLrg㧯 @gl'o.'t);? X$Exqub_D ?a`aaka&<@i~}3+~]?H8@E3PT Rz_~  [Bd< d@ 0Ph`j0@0Bli2b0C`l3"FboA526h*H@dd Vff. @Af-@G1A sp@IJŇI@Y9 Ncp&w?3<?@[LgN`#bƠY IENDB`KeePass/Resources/Nuvola/B16x16_Folder_Yellow_Open.png0000664000000000000000000000115110133525306021527 0ustar rootrootPNG  IHDRagAMA7tEXtSoftwareAdobe ImageReadyqe<IDATxbd```.ˀJ>h@ ? qs1 31#~I0r ܊@2x/!W؀C@>ӿ>  q2N1H; h(#+Xُ[{`W]h3j?5ge`bv;5\ۇ p/wyW8D H~aՎ )@C?$a/ o~%H3_ 4~<?°7b? ? `Qǁ@ x3î? V z+~lalH!PHw :t @۫ D@L cĠ&D@?y(8^ `DC @L3(0IENDB`KeePass/Resources/Nuvola/B16x16_Wizard.png0000664000000000000000000000160310133442532017241 0ustar rootrootPNG  IHDRagAMA7tEXtSoftwareAdobe ImageReadyqe<IDATxb300020 *r-Ϲx12ŰbhqJC_!TAe0q&13}~o`bԦOزž = ?^axvWnjN638d9>\>?  ͬ@̂?9?I02?f`G翓|_+@]@̡ .2v*3Xŀ5 \ Ln|>NP0@1Ry 0? oaZaWcoLV ._}ی[}oTG:a=k5n`XưF׬G 3OyǾ/fQDbX8iLsu|?KF.#Ҳ;w-s(?f_~g݇߿_]}+GIٍo dNIJ>tO>G6 CYЀ@NzFCOgbkv?EEEd={7Ѐߐws|K,Ow壢”wޗ?~8 2 PcccΞҥKӧO!(( >"\82ϟ? =O୥Ŕ}'D@<8x𠯱1@0쨯)!!q F])jhIENDB`KeePass/Resources/Nuvola/B48x48_Keyboard_Layout.png0000664000000000000000000000673410131465220021117 0ustar rootrootPNG  IHDR00WgAMA7tEXtSoftwareAdobe ImageReadyqe< nIDATxb?###=@迿dda`Pb`e^{x_>xg&@1I&&̿UfˎSQAXXPAd d }ӧ_qW^4.^$?K>|A0`fo?BvaeҔfeRP````0̿~`XY 4=ϟg=~{ > | lg[/o}~fFR||A>gfffz__k?L߼1VOYY^RWFAL 8.`ab 40,~f`!$t 4,g* py zߌr|E={x˗G;Əp*ԯ_|ҿ~1KCNMXAD p< {\ZE, @G)o>p-fB~ L@L`G` (ā` ?H@IPFdZ P`:Ayb0!١ Pp03B? z0UPAs#U 5/,@(*Дc`&$$UI(/@@s{ {cc/@ !\@L, + , oOFNB4Gk< @iCT6r0pe}3Ï/@}dF`3]z @+00(HK!C~c 9Ffh2۠P MB(%UkV.m! n; ?od7 74Б<:sC?e]@** r& *ӥy@,DdPhƌ@TW1C0 j <oY޿faxqXsK+Kڈ qv<@ne`"#I 7'}fp|a]߿a{w o.|懏 <+3t #R X'^2<|[v^C%-=7 G^| 4$}ҟYq(tOQ[@g/D!qx#ןl+7(dAu;0&f1|x; ^~fTB: zr b |R&0ifP LgLBY{g m,dV U`{FG7?3eeӒdO& %N9]Sa؀j3 _~?xYG[?~` (^03TuruFh SC\A{p1Ó^,CQ)`Gؔ8c73? t?'Xf! z u`<6|c AL`՘a]1~ # ブaa=J^///W?! dr ï?17XI&6f_ j 0Td-ep~qĴN|jh,5L l3?`~dl %ȿPU`5[@2F`R`d_N`ӷ jo`@= pii1`/óg/M&i)q`'ÃE=A'p _|c0e5+EDAe z.\e8}Ǐ GN73S`g0hth0j6?u)޽{@9` c`1,ܯ  K5vp |Tɳgρrs^^npO I07CfĂ܍eg4A1 ))LF ԃ<XYoR,A+`L2 k 1pJd=1@LƠ O?⒟XJJC\FFB44bAPqrr0ۛ3f RRp[#  ,@23+!yp,< dd$"{\?u DKA31A OXt Tj&@cHPEDh%㭱1\zH012"갫 `bG+ U?i'00A AvXY;@@A*G%@CO82;5a@Z}zëG_Y a//"f/#l(B*)fEu'9w޿g|9ugO^o^Ǘ6xxyE%ed~YRr@jtHcJ8Al>xڵw۷v*{ ã\ EOi9_?~ ?Aw9/xy(*2{pO=G޽{ݻwA@1Ap|oĔlק_}$@ݻ/>=yy1h2"?&>};L uuͻS^yo^BAr4VA= @?pKI 1s Ob3ks++ `deߓgϟ'A;?A X`{\>|lNɇ! 4oRRKn@*1ׯ?fx bn"?0\X€ 8A!MB?}@$ ' q Lvo;Ь ܦY ۷o I-=w ~7#4'.L 0;ȣFAG+aS߼yҥ'B& Z v<qohQwoA30@!/y4KWhU 5pj˄;IENDB`KeePass/Resources/Nuvola/B16x16_Cut.png0000664000000000000000000000200010133443172016525 0ustar rootrootPNG  IHDRagAMA7tEXtSoftwareAdobe ImageReadyqe<IDATxbPSc7߿ ̬ /l dֶOMM-y޽?~XT @L P1 ?eX P ߿0vvv~a͚5[}ϟ`-F tB\\\fM6z6QQQAAA% uĂ@WAG[;] t'򜜜 2@># G|@?D@߿ٳgO]]]޾}륫k%k׮1Iׯ-@Tݻ  /mfسg7n 'gfܤϞ}ux3Ľaa~e:z(8puE%SYoΥKlljxy-\0|gu ÛW?}M?Ƿa@,B,,Br~x۷׮UHz햳gk~~`+#3e7o8;.u:lٗ9o1 ecbz 4@,~-+8z(߿qqѹs8xy #<YTHï_10l̬4ϿS$*6]b&aP·_. &YzLyKϟk3233S86 j1_@ 9/S]ӧ?}k~,|@@1 3F+W?gz{2/˼fi A1`oa}^7IENDB`KeePass/Resources/Nuvola/B48x48_KGPG_Gen.png0000664000000000000000000001202410125245344017336 0ustar rootrootPNG  IHDR00WgAMA7tEXtSoftwareAdobe ImageReadyqe<IDATxb?P8=@C4=@C4=@pD0220ğN003@|2xr;@a@ltoȮ#$fŠi$w7_2<㧿?}ϻ@20gg`!ЬTr= ~`(``ee`4Q:XBAK_A^ 1Щ8>~dx_ ~e8KWgc e O<@p32V+ʴD3h1(*21p~b``t4P",0^3@Pct Cg#er&U}؀y X|han) h5``C=S1a _S=𤛁'0 2 bg fP1{ C]3#yY yfb&&n02le_X䙀Az  $@Gߧ@w L;?:HB~F2I#ß^tE%І/-JCm^2| $ 0)=Â2(f_T/3` 8E ?&NVk(06 ]o30Z02pd`ÑHٿ" . Ma LݟPu`1i 'k0\E +% gÖ/ОKj@ &3F^ӫ@{8 !8k LN@6334& h6'ßw/Dx34dX{^#Ay = ^kfe[?;0`,?M- H<%_`gFȘAA f ׀K  B @a k ttC  WJL`eÊ a 50+; Cl?4 1`T~H-=\;#ϐb7#ܵ`B|2б@iXgY#V Z \5[~:~#r@+H?6"PA ;v#jPT1s" tO`~#aJ`ۼr-xiA]iW9  @ȍ{yMVa@z o9p!雂 0$AG5 *_dD1roH@< ~pXU Lc п : ^eXN@Sb{a!ʆ@@pD12/RPweu;;| 21xիW ?ퟗ o}b`zc?2hntgP+D,dx-oh ,,O%C^3+ *!ˠ(/ )! ,`6V6,,L #_&W.~N6P gO-+  VPHz@>`Xd_Fj<|p9-f-ac,op[A11Ann.?/_o K? ZJb wd>^z$; 16s@ NV`'pzp(ۈ6Gp;?z%-R D)$- /_|``6 Ņ! -((ęx1glNvv2 䡶@Z"8< [Re. ?:ֵ@pjʕ1H z`eo/V%>`{Yٟ_lgdbʠ ZXY98lz2 #m$)^I[풆 _~?F&NX'N* \Pr= 쨀Bիw W|'nn`l3pqqCg&#?<@1Ll ?fxe;s;l" ܒj2 v>۵Ak@_ ԣ6 PBr×޼yάR@eUf ZV`s7TT@r;(A | !)\ nc 좰G1F3cd8z>JKg O@ : ŧO`ś7/%\\쁭 J Ƒ@D=]~7 TS2 Nbx lj3@m[`aĠoms6i00310s%1h??@(P0_} KG'ܻ ^YYÇO$I^yR#>(f#S Ov3W08g8Up?o *0:u?}gx8-?pCڀ OB'()Č~C~\ރ2P`;w^0x ofx7çO30Y7F.^)Ko6,3>=` P 詙 sXTUМKA7vdoffHO cTpRJJ֭M@Յ*0p?#6̬ Z҉^Z1AK 8(t1YR̓, 3pY38,c^a`vd 'X2.]bߑᓟ?g123j2X@e>uuU`.(EEp J^:L38IK0 1'sp>á& ߂no;BӻXV0z/X`ZaPR_`qrr,F-J!4У??.1_ $A7f07W3b`2@: rz=S/XFkg N2k!܏SrNPv`y |L쓂2_%*6pWPXkMRV0pCa_}HhOA҈A@:w]?) r1NϿ?RHݟ?}{@gF..~10lѲAR,hAI?D)p^a@H1 {Pgdd1<ˈ9`ƍ;:߿dgϵ*R`e6ic`CI~0<=h?\y&fV?qMH%@!+ jJ22 l15A QC޽u00}O^V?qd%+°Jcr87[|;"M"D>ë?9~"C4k ld .]=}ޯn1|98fPYɃ\@ t_ /fxg`Z,Bo3p)\u99[Es=cbt6ß?C;28wERh)H7PO0?G&VB.Vo߾}E@91z}U`j} 6I3h , I2b`xpL?óhvp0~N+fe^ZLQ74lbl1=a s;iݻo޼5mc#?xXc{ d?21Z4lQDBuCȺ, n`xne8paBP+x?XyD8 l?\cAkW6dxF$:7jd)?{E6+}_!`L[0Çw`=?~|;O(L`6+foaj+L Kab##-fPAթ4 i y܂Nhc9ԃ-R L=@jH}͡IENDB`KeePass/Resources/Nuvola/B16x16_KRec_Record.png0000664000000000000000000000120712666321340020131 0ustar rootrootPNG  IHDRaNIDAT8˕KTQ{ZɜLfFe`Ŗ-Da`!fE M "H,1S.Hhtsϼ#Mq{ZX{J"@u) vAG {^q& N,(B\Fo57V `0XO|iQ>VV- l<.sɤ̭L&e016&oó^PĀ##5H1Mti"3qwxⵦ*h"k`ǃsJ6K`Kp_ (PݘG*PsR)e ЮJWWt# H kkd ppβH/-D4XXcvhضmσ㐆uUHTWtE^!?AWJ6gfT :kxm9/8 Lž7>Z@d܆~x  (/ г [d!9 /!Z BР@I V x w70 GIENDB`KeePass/Resources/Nuvola/B48x48_Wizard.png0000664000000000000000000000526710133442530017263 0ustar rootrootPNG  IHDR00WgAMA7tEXtSoftwareAdobe ImageReadyqe< IIDATxb?P8=@C4=@gd(i)P 쾿 (45=`a ?Ë_/R1h &A]RjGjʸ J,V8S~;PT4 1: \mW }M@Z  )@m×?@{xj@ A0g'I2Ae~8# 2W3ܙ}Lǻo = ܞ@Ӂqw _9_H^g`z [h B "I ‰N n޽a`Ѝ:S_о_fzZ -{>텪)@g@B3^_0|{ U~Aj#BF 0: &l1vfs% C{@ǿ~f XwR  qvF*:2 Beޞ~R;? r4!9?j &Ơb 9DP#-<@0d:?o !$ b'f)v  aB F LNChJldDlk`Vs"xI69 O; ev`[0#`0 hnR hFs/@VRfCφsh200?u<+a'A< o6@iIhjx Xp7D9!Z<&B0(?B @0} }c+ÇwAH l07̤ t~u=CVK 3|E72|m>5׏Y!t$X,$݃<'ûg@q֔!A][a̙Bk/Wkȳg 0A? Ƈ[ L1(gd`"Q,m<& ]SV﹚6 0U== +gX0AIIa K/Ɩb7Aϟ?`'π ,3gD(/#\:{g Ba_>@mݼXuuu1203'ϛ?+33s #oR@@|~+5Cf.(sx[ރ/3|,pp%721ܺu!++!<,,oJN &kd+ly'lpMԼO>1Q"Z/, % k۟?/,&%o B"" O֭[1JN )@Yx X(@ijBhc/$$Tx @`„ MMM 5SLΞJ NF 9Z@@TVVǏ``nVVV֔o@Dbb>>zIIn&&&0T2ܾ}!###=JB<<P#k @HX8A$LNy3f\U2(] kłdc̝; PY@11 .D75ş Xt 0@4XP#+ Xr PlK`hLML@@W@C~ h{  #TLIENDB`KeePass/Resources/Nuvola/B48x48_Run.png0000664000000000000000000000614310133442664016571 0ustar rootrootPNG  IHDR00WgAMA7tEXtSoftwareAdobe ImageReadyqe< IDATxb?P8=@C4=@Ci?(N_s mʳ20rd,n zz~õ d{13[ s˫1zݻǙZI0 Xh`V`f`6bVeVRb`a8cÝwz:Zk@P& ́i' %. t4ϟ =cu"{ -T1pX;<  .C``b`ccgfTUePgPbNNNf`ϧO9?2 |@yNN_1@@ᗱ TZ:jt`sM͟<#xd5E_tӌ,PY wzp4F(+TD 8}<20j0RTT31e31f47ge{6U ^f ÿOq߿`P=gb9..ޙŘA@<*-h?;;0d?01ad)Fk& Paff 2˱2|K )(D)3[Z23pIH200CB_20 "@3\@Z_@z@a00J:80Xvt <tohXE8h00?I*6 ,rb&WN1$mHOb:/ _00_# (`1vۿ3$#4C݇f'#fy KJX g8@&@_ujy|PcJ/_YY`q @1r~ fee@1(:'3;=-}1)YԠnh('. ;ܟ/_Dyh,$@8=_y}#Jh#B96Ԁ*)9`>d1PM000w`.`SB1@,8ËϜqV'e?`3 z ܌Lj J L ̦$on(" që[̀q_SX2{}3eըP1kjf0Y@1Q1F/_&}C5$sD̐~f61g ? 0}my{\WXxāI/J|j:'36p%c៌,3 @1(C܈RAEA@woo_xB kEe&81v43,=޼v 00^6%Nd` L ρAy  *M~)Y5 z=0Pk70 >۷OS-,ڗ =VPۂ7F`Sһxs 3_-n0 !R&Un.q`+ޅ,x<@x4N+?m|.`;K]:`lePX^A `PcGa0 AqPq?KUx"/om+?`~&P8F5p c-` //" 8"O!Ʀ/e;cs@᪉ϯ_4u&P~v?6vvlL^*JZ=aVS! O hn|:p/ t%x#  @TqP*?!P?>PssU1#O=cJ 9EW0\̢VI XJ222 &!h2:˗߽vCn!(?d 0ٱ`a4!AQ`-%($gCln bK`fdwMb 6!˗ ZAoՂ &`BBFNn5P>30"*@y y-oPEDA OъLpIu4>߿gx9G{ V"z\|}7ld#2fd`~ 8߀F?O`&wn#1l =_}{[Y%!!ԌB_e`wb'` ,.{q}e3ÇW]:XA~yo&FR"X#/?+Y̒ #Cc; ,~cᏲ*O` ɟo0|wбfto6΀,!k HZ5+^BA|&P_@ @0A)z _od'pǻ/;4I6{訟 @ъ4ـc ߡ:3 ?.3@Gyh`zˈ4A  Rc0=$ `29(AҠe@6H_~`N@-H@@::h;'}m JR?c_~/$I:#d FDR?&BԴ t80v2L_,HDqˏL@bYǞ 4+@ yА@ yА@s$)IENDB`KeePass/Resources/Nuvola/B16x16_KGPG_Gen.png0000664000000000000000000000176710125245344017340 0ustar rootrootPNG  IHDRagAMA7tEXtSoftwareAdobe ImageReadyqe<IDATxb?% ("x<Ռd5L=]|:#84b%]O^Mﯨ6x#P  @`~ _A&> vFVF7 q]_{3cdh?~`=/K P nNͰbEڕB<=O~@oY@u@] Wlv?>'?}c`n@ "m O4 dod8-C@ x_}57t80qc`|x/\0O ;1}g`z@ 87 ?^|0sܽgv/mr=fX!}E 6W/|d```ca|?{[yyt )fXoRma8{/O*@ '߆ [Wk8h^,7 o>kǟ280Hx*3)dpP@]©53=zSwU?2r02 2p30r`Ҹ~Wp/_؈hsqq}ݻw|;K\#$tF/,jw>0ܸqGI30c(f4޽wG~d`8 bGw>0|zQQQ/117k``8 |Y`?ߋb@g0`!%"qÇ@C~ž<1:P5KH0pi` ddXDw@CO@HÇ_2|* MO񞛍Y/0Uř1UP`m۷Igmm@}{;_gP#(c^5?'60Yj30K17!!A`gu*@1CWG\|*1?:oj@iCFƌEJJ?ZXOPR@ bb @[%vf>0Gj1,,{ aj ,pZKԔoIENDB`KeePass/Resources/Nuvola/B48x48_FilePrint.png0000664000000000000000000000645110133505000017703 0ustar rootrootPNG  IHDR00WtEXtSoftwareAdobe ImageReadyqe< IDATx՚o\}?gI Eq%*YLKTQ;4.K4A(6m}K@"}p AF E. jHu쪑Ťgr>YZwx9~緜=j"}/=M?2:{v,A ^S!OeyeLJ?կ*Px뭟|2}R gphdXJM>_^-_SLhxy4[{ΑCx9?Ϧlݰ1)|Ǐ;u4tB8pNZCӇx7Y.z )]07[g׸u/_beez7ߕRCF-cMNNto /,gvvaB2d =%ٳr5Y3B‰'֢C֭.^ٳP_Av.$0>5::7Ɵ1?,0#IZxA)ѰwwVH8sJ@7](Rx#Ԓū)%R-gz?qw(x,,~y]Òh%dCIvA?:OVj')gSk H) "P'###9#MvJ!z4:́q bgA1~hZ"RvJ\cуᇙ=pŧu?MNNC}p4 &X4_yޓZf<'YՋD$N||7՚yVssX\xsvaffBD$do-K5hun:"UMa5J 4)e;LDH%+P9Es(%Bω&4&S78,ѐ#$ ^es W&>)aKjqbW`(B0 αo|{0Β9 !! Mz=VkϏ$!BA*2$1fGIp<5dqcڪĶs!YJ1 Zn٘( \*LӊV-'RR (lHE:TwN>ڄ@!m\Oo%s.b7 p|an~d1ϓWzA@7pάt !UE7n|g) XkI{Ig*A&Mirh h"B*Ƙ.)'F)sƝR(`aa39]v =CC8gÑMMz~K@)QRJ X)EQZC!'~4Mg!Qq9~`BaDZ2RRQ;w yfӳw4Vnp)cwIt>\=>1{G8̣h  !ƈ6I$Z 4+.&ٳ_=֪? |t{uA6uΡfff3gD8q8N1ơuҕ+RS0)%JxB\:D^|eڇ֪}QH)BKyy0Zߝ+ɵ#tIbE!ZkƘI)]@g^aqqJF"I2׫ܺu#Gګucu|sisj} ePTܸq_.\ߢ(z?fz!7~7{;wZ(w q.,;vbd"YfN.pgߛM =z=f||'kGQl6okJR8zU؊Bi|[~zûWrЮNhhgzyjѣ[K.!Z%!D*"|ȷemTJA Si.8HIaIENDB`KeePass/Resources/Nuvola/B16x16_EditShred.png0000664000000000000000000000127710133521076017664 0ustar rootrootPNG  IHDRagAMA7tEXtSoftwareAdobe ImageReadyqe<QIDATxb?ZhǞo{ǀA#33Ӷ'\Y\h @  fDP4b  )6\6@ r PЩ@6߿X i X4 2wj 6jito=+D-@1a9F P ( FF > O@_8?|?+`6ho_~0y@k>~oS=es2l@agef%X3P3@} t2#hGρ .?@] z(@/0@if@`^~ @&H? fHK(ਃ_hL?"xA$0 cd@2 HK?,}R;! B_z QWFT>&>y?~ D0~ tÓGy_nݸs!U 8]ZIENDB`KeePass/Resources/Nuvola/B16x16_Help.png0000664000000000000000000000160012666321326016700 0ustar rootrootPNG  IHDRaGIDAT8eYlTu;w:ә.3]RLmJ`[R4hL4A#` 6&`čE1T-nMT6PhziPܺKN{+? "":Z{c6k/%EX#<fK:cs9%>` ۔\gW1})b|mr<;>nlmLelLYDVv4C>%MaRרhZfyy!;Й/5RplW)fR_61sm 43:2&Qs Lcz|&]XX8|ٛB E^~@D `dy-ʵ iBPC֕*S}KfB1}t7+|"c`p;Y{?b؀'o2l=AMC{+.0\v ec3`c@2bbxx.ÑC| bSf9ñ}20h1H 3< @ X+o nĠ K~n&@Wü@,! zfF Z o?301DE{1J0|_ RB\ .X @, S鄁 hH þ{xgoW2p3r/b^b(cgfpWpSO>db HA^| _ L$ <,  ?> 2^>VPA\ ʸ  fd RFNNN0f4&b9ww ߿380 _͝(%%J!Qѳ8H Y^~ J^TIENDB`KeePass/Resources/Nuvola/B16x16_FileNew.png0000664000000000000000000000144510133443150017333 0ustar rootrootPNG  IHDRagAMA7tEXtSoftwareAdobe ImageReadyqe<IDATxb?a„͡^6 \?`bfb7u7޺v+ X@^&Ua $OzܺJ jE@Nb a r?P6H 6l:@r?(J#'30 /`b`LaN/V`  @I ĂYHefV* ?Xy3 P_~ct"9 \ _ ^b~ 02"H_@6} ~I2p2c| Cb؀!.௓ 81yaq/z>p؀߁@  秏ZAO^m`YDL ? rp1o@m/P~ .`eafdg/ إ%xb~Y)g893p 0xo6L^_@]30^0>~pAE.oeLz~a wnz:f&@q-Ll̥On^P_MjIGIENDB`KeePass/Resources/Nuvola/B16x16_Identity.png0000664000000000000000000000155210133443056017577 0ustar rootrootPNG  IHDRagAMA7tEXtSoftwareAdobe ImageReadyqe<IDATxb?% (X{X]/)X302c dc`faL 1H/<}@,&rUU00|~  fׯ10111###23pqs1 ǫ+ ̬l _2}q÷X35202 1XYi3/@~g`zUZS@m `_b?3r00y*_2paݫ Š%by.~dxqv8= -?3 Pxpq 俁 ?|ῴ5g=j7?aAAAAAA?S1AUN@ocC@bÏoffx`qϥ a]NL/Fh 2Ͽ? ~c o?1gPs20[+1~e&(V`4?/??18b7?%!4u01 9NVF]O: Nf4P_fo> F g d`xva;&]=_pk400J2\AcFw;2lbxß~10e''f_.30s2i L X)YM@3 abYPa 7^1p abd AWAh("b6JF.I ;(Rn@ ?@/1]& t#/V Hd?O?`߁@ 2? 'P_ PB @P/9LLg1w ^db@A 0pp1@#0e#@@d`bf Rxa`J2@9 L 6)V0lt"#0V0(& o13p} +pc1U@S!&ów7Y AJ(  Ļ1_,?~`HHL }  +XJiIENDB`KeePass/Resources/Nuvola/B16x16_Folder_Home.png0000664000000000000000000000204710126472772020202 0ustar rootrootPNG  IHDRagAMA7tEXtSoftwareAdobe ImageReadyqe<IDATxb?% Á0)'g`?̟3g` >νO&bc48ÿle`Ie Բf` @Ľ n\0| oc?#PǛ_|%xgr  f-6e.mfl"Vj J< ?c7 @/0mgav+ # _D? =&2I3Z10pr30?W?)6V̺g}?@LL?AQZ[E狟 _?× 1ff$#f5 ARP2   % #rA+  ? 70 :' $nɚo,fv4? o  2lMc`b(x @LN _ 7_x `/ 7 0Ҥy1ĉ>a`baB h+#+ VNw y3s00 ARM/mF1pbߟ|Y50y K.6Nq`6>pd"W`9 XvO.MtWfqQ0``2@<@\ d{(Ñ]{je``y*gJ212 Ĭ 12˲DYjb7?b d"/"#*TOJ >V -e?JfȐ4h%u _ 6@3|d}!ZO{ @թKl."pԿ ـt÷ ( 'j.vAaD_DV$#9JN ~p A,+L KW` "')*&Aq <"< x    y  !Y_H$2}`OK??>bOG Lj&l̘~Űܹ ld/̿9%Zun+w/2|Lo3 緤6 `2+;@?$SOe699!\L`%~Qj ûO~ܖc8u1bdg`feݚla˵ L r*d0bx.7+X)?w .`/ϟ>3}G> a'؀@ ǖ=>5~>@A[ a;at">  ! ~#Ï( e Y޻s-3(+ @@;`W]S ߾T t@g`)nIENDB`KeePass/Resources/Nuvola/B48x48_WWW.png0000664000000000000000000001273210126472604016511 0ustar rootrootPNG  IHDR00WgAMA7tEXtSoftwareAdobe ImageReadyqe<lIDATxb?P8=@,p02oV?u1fˠ̤.4/_?_1}M=>v[J<@ <} 3p h(*2HJ2K1pr t?/0xɓO Ǘ?n-GT'y6bP%eg %ʠ, #3P$0Кc`7.~pp?obU@/N <9J6^"P=^]c=AUpf1 `π|?dbƽo eضOcuݶ @߁` =eI?͒BA/4?`2|d￿dd`b/'Ȋ_@~3 Yf_Xb/ G^dص뿟O`x1e@.ova9"N1 4r  &F&~.!3p ?~}g~~a7@zafbK^ߘ\xȰ`o94bDL\1̚CKO*y+˧qsk:C-_ 1b$ο,`A`l|#Xb"@pcD4&nbxr*g@%y p{ lg q0H2^`pP`l, "2 }dY!On3_D;0Xuw V :1uË]@y  s?($d- I`;0A[AGCA_ fFV++71`?'w  fseJ`3L-2v^eafpt'Q`}W`fddT`fZ).6~` J2q3/?~?Q߁ILCe&7Ȇ߻2uP-TN}.",WMV2 gggZ ₦ | jp}pm_&@o?8dsׯ <" F KwU0:22Hd( ,Se]+=U ?|& >QS..i`Fw_(i<|O Zr RL@Gs2 ûM ?~_? ~1ڋ  ܆ <@a 4t(y0;ADa ރ L> _|(Tgx>ß_>|piۏcARTARD۷o o=!q_`7аv2L^~[PW\ŐX-×kA ?B/mq &6K2F0he0W^A h(7#0ܻ{ = Ljh-@f Lw~d.õ/<{h;0dB.\;/8*@< dɫ3}hw~1eVPXBk=&Hh L.@ }d`6{Wn2AXH=@͎KO `xw> ga-أ'zӇ ^cPVgr@\(%j20(j92:3r~ *e t(0aUa|z70ɈX3lW/ lP;lp/Ѐ?ELL@À?>0i;39?+s1|?Bs0D@!yI]LNkz>o{Nx=1*u@au]`Ȱ}C_4 ,C| lZ*@XAiM ,1p1Ikkp;W22{} &~ \@'Z'fa8|l/8ů?prQi# q)]xyh`1w*: d0op2%`W``R`lɰjy"Т BB 으>VBx,l ~``6Yam_VY6^`K+YpP 6 6P_z8Oy gc  V JjQ _>=`fVex$=*0O 2 F#X؀B(-<fvgOw18Ơm-̠oR (f@4Y 0K ys20?` q0X;w0j2Xmex y01h(px1A X00@ & H2mRje @ gi.+ 8 fs`Ap`^͠j !$ {A}x@ߵy?`Th*$.#$z:*_T*a0ϯ 2. **_XlydD%xOM_~CBJB?Q@Aq** zb#)Fz _Xp 3h0p)OAGfb 1g?2UunxUXKA%0;) >(ԁn./ T`&' #i toN_eg/3X  @]~Rk;W0( 030gd&X: 3#jN yP r/_p3b`ed|` ( AY`ipr3ڝpbƿ :;OB_=~ Ù[{c;pbM An` ʬ(&pg6+4;`g XgP6-v'%$``d#{=[π߃b b`^mp ^ ((Q9-.8rBL2C$CiP(I0H3d|ƢBZ P:vu^`7kĄ< Nw <:ܡ۵V#``b';~>('<ـ2 z)C@ I{=`_Ǡ#kV#̠g0PcQ=çX6lgx֡Yp+ G67 g8t6) rzqA,C+vAR2 FrXaIgxb!؞pX-wV238ؤ@m@O0@}b`~>y՜0x2/ |lQgP0 M +f`Pl@E#T]#AO #D!DbX<0>`>Н$* s|iOo^2Cy- 7á m(%PlHyPyrJӟ.?#X}W]ew44KeduFJ  0Hp3|Hv(&H?)nРVbay \y=Ú2]uo`&`- p -;.OԢyf('`[h!/d/H)i`0A=0P1 bba {Y|͚@c)PgPFH']H)a9 ^ L_)#`?jI 3r %Pn E}!h4PP^Ryd~+CR"(sCC ˆS&h2>W ^qCcawn:J`p QD<1# FN]f3/FknQ=%U5yV9 `IALK#` ?ÇL O`x,a}o C++qL|33{ r "B\B|̠@O_` y=m4TZEC4c" P JfA'nhcFv $0Bκ (}}P4C3>3R{?3? d(3IENDB`KeePass/Resources/Nuvola_Derived/0000775000000000000000000000000012666322032015773 5ustar rootrootKeePass/Resources/Nuvola_Derived/B16x16_File_SaveAll.png0000664000000000000000000000066112666321632021746 0ustar rootrootPNG  IHDRaxIDAT8˕;N[A an$@rXP:*@D,RR BRPQP'{ƾ/Έ2i{Z_+*0(Mu(ҧUv X .n9;jPФ( B Ce2ff}mH lwi"f<?Oy=iٵeꟐ쬚0!!U$LdOTZ8b9Ę&w7_ |TbN=<Z/}vM,U ARH@Ӌ-JmٕGXWgcĠdլ=LhV@iP+"#GoIENDB`KeePass/Resources/Nuvola_Derived/B16x16_File_SaveAll_Disabled.png0000664000000000000000000000061612504535412023527 0ustar rootrootPNG  IHDRabKGDCIDAT8˕A0F4A,.\rW*@Wii ab)`yq!ဒ Y’ Pr~Nu.9b=.˴X2mY/"O /,qϝP0>IENDB`KeePass/Resources/Nuvola_Derived/B16x16_Window_3Horz.png0000664000000000000000000000102512666321720022005 0ustar rootrootPNG  IHDRaIDAT8˥jAofv?uh ,,;; {\( lS 6)L$&,͚΁agy%g;Ѻb8 ǧ(`>a$'np#~ :7*8@oNG\Wo(ǧ_Tm2:eQX^)6ݾ/_{+3)ںHXk@ZN*lU$E,UɸDžl4RxH@.d(N9+:afa&i`XhrHE_T M$"3N0̳dI,/ApUI#!TIIu<[JYG$Qݽ#*Ɨ&;K~DT(|`h"#9*Ÿ8PUQ 8DN\[>/+ |)IENDB`KeePass/Resources/Nuvola_Derived/B16x16_File_Close.png0000664000000000000000000000126212666321616021464 0ustar rootrootPNG  IHDRayIDAT8˥KHTq">j$Q,lTD VJwѮMdh1$BhѢ$F̨̌y]Źw[/697ÎO0 B!D4 lw ;F kr5W yV+ȨH1= e͵i)/0>v<;u`A<foQ-SWEVTUnc_%`΂y`5>L1)S躎^cs?cG_(bBIENDB`KeePass/Resources/Nuvola_Derived/B16x16_TextAlignLeft.png0000664000000000000000000000064612505257452022175 0ustar rootrootPNG  IHDRabKGD[IDAT8ˍSn@=.h4|&ujj _CF/P-q;)9 V|jX.OHƷ1~_m^_lx#T9e<ϙeI2 Cwڥt+4EY YPUjqcX N8u">r4*oN7Y`8A$:Urs*ǝjáF-8MF n(5ѫN3_ei~Cp]+zb|k 9A  "vtX<E&AJ@H$h<^@Eь|wǖzi\EF]lDg@b!-Nliv?7Q(=L203O' WofmмCDCX]ne-NE{ҕ(_ݽM<[kG(`_hFgQԾ/ܱoښ0;T; 3E* E(XKX9ºŚ 7#22nmIENDB`KeePass/Resources/Nuvola_Derived/B16x16_DeleteEntry.png0000664000000000000000000000120112026562262021667 0ustar rootrootPNG  IHDRaHIDATxڕYH光R-aAEE%"E]&A֋H"Xk!AEZ*Vתwz>yofAU 0 jE*KMrW9s6EetF4 g5csxϤO.1P ݄#*+Cjz֖fܵ5x\dį7FtE{ {`q"{'ړz6Sr`Na.3>%Kgki+P4QucVePxjBFQgL2Cvddw0j;{v˓jf`8 8?3xAUJ@.i^cY*ߏ<,XkaIAjpMMo*p=[ǖ_ IUDQ 4Ɍ͢⯮>}t]p8t:ՖLӟsTR$IrcflAU!"M誂nUSt(.np8\xWUa0 !"Yt:}.hވDYi^'nI|E7lRGIENDB`KeePass/Resources/Nuvola_Derived/B16x16_TextAlignCenter.png0000664000000000000000000000065012505257570022517 0ustar rootrootPNG  IHDRabKGD]IDAT8}=n@ߘ MCEA!p&ujjNPh|*$,dEg_di|+cZ= I""="cvfyv?⽧i^WVUELӔy=R%IQU= ٣(2IY3@Q=Y9Urviء8N{ b˅8ݚ6S=yDdY֖pkhU$fYz8:OHsHz\qCD"rX5NN$Iki(2L >|;Ny}| 5IENDB`KeePass/Resources/Nuvola_Derived/B15x14_FileNew.png0000664000000000000000000000110310414152334020764 0ustar rootrootPNG  IHDRѸ IDATxڍOHqg۳"aT T!QD"o]Dg'ޥWӸ5ck&)`6Xؘ `xݝt߆cI|I 'SţbJ$:9c6v M6;hז".p*s***x-Kĩ]{hy-=YDZ+d_P > JX|j²Mdo5Q63e;O(|q)(2PjΛ{nYNo)A3S+(#(뺪P'l[̀iKH:lx?zd7?w*-%qEDf iIBEۇδ>f|ag%  FJb'"ᴯ']_FLY3;IENDB`KeePass/Resources/Nuvola_Derived/B16x16_Window_2Horz1Vert.png0000664000000000000000000000107712666321706022741 0ustar rootrootPNG  IHDRaIDAT8˥jQKjc,Pۂkq!Rtx \qW;jnb-J 5I6̸8Xpygg#{:b\I@ f+ M )3mݼ'Hcߵz(A& Cp1 TQQޯo1??GQ  n7Tbo X GqӾ\`rcn]ȩ10>9OQ1wp<%lfIki@PU(KE' 7Qsռq%jN CqڟWic8\9@M'*= j"E$S$`jHRD,'JR..]Nz61T`̋yb±y<S͂MLKJM|$F$ \9fbQ#p 1F,憏Y,4MsL&Xk !\ض-{x9l6( sem gYc$@QLS1GZKUU\__M4("yI*"f3=EQt[jh4*5yB@UVt???l6w_'0IENDB`KeePass/Resources/Nuvola_Derived/B16x16_Folder_New_Ex.png0000664000000000000000000000124712505305576022142 0ustar rootrootPNG  IHDRabKGD\IDAT8˕KTaߙ箣V2JE) 63F\$$uAtmP0HN4:X\x: Ι9\, >}W>Yem@6? ` ~g7s#Vyo"Ѭ 4Ld %ZqmPu &CpSI>9glGMFjS5HLCBxT ]_UśDbRy]:Ӑdh/bi^F4c0F, ~0zڲ̻iq"j'w*|NV lAAk([+8a{-ՓHjbO #NdZegzJlN'ZbG !I $u s8l4ly+ `>y@ۢsp rd"(a`Y& o`CQi~^*婅ܵݧCFb6 ]͌ptWv۷_F_- 4B@HY1EH <1^:{ᶿ,q@Ղf߾0xS)IENDB`KeePass/Resources/Nuvola_Derived/B16x16_EditCopyLink.png0000664000000000000000000000127712666321600022015 0ustar rootrootPNG  IHDRaIDAT8mKTQ?7M@⸒lW WB [k[E•RkY# B)3^̼i1s>GͳrV.$\BPR~7ϕpFWO/-(Kw(Ru4 8&I(" C&7#hfT*199IGG8J)D9\?@#Jr9YXXV>."B8CK`E}WU<c $ AprrӖU,9==% C18C^Ra cccc8>>fmm Z&}2Zk* "u@k4E{{{ fffxObH.d8;;cl6˽G$t癟gkk>BiǙ"b֚D Hl{ ZQf.'0222`ZЗZ+|Z#z5KKKevvv4NE-j)=my iׂ<:`S<88bG\% 6wx! HCr? 3/IENDB`KeePass/Resources/Nuvola_Derived/B16x16_EditCopyUrl.png0000664000000000000000000000124112231525242021645 0ustar rootrootPNG  IHDRahIDAT8uNSQsi@J%-ABBxwN1rl;0Љ(!!@*ZnǞvprs^{_kek z7͔kNR{4ֆ5N MWIFojмXuBe:}ybkLm?Nvr9,[`t]'ELS305IjhCns'+YYŽ+(+ Rb;P` 0<(y)shg 'A^bEBHlE0{ߧD}DJܡʶ(%(3Р aւ눰W%-\*0"x@MM0v=.u N2V=χԁȁulw $*ݥ98AS`HpKk^O[TBBHT w򺮳k7H0_IENDB`KeePass/Resources/Icons/0000775000000000000000000000000013062207716014142 5ustar rootrootKeePass/Resources/Icons/QuadNormal_R.ico0000664000000000000000000006406613062207176017176 0ustar rootroot00 .h00 %>  B S ] hc(0`  (   (,@H 0$$$X @$$4 H$$@((4((8$$H,,0((@((D,,8((H((P00@00D00H((h00P44D88800X44P00`88D88H88P88X00x<,7//0y5/ r*%e{vVI=;EVPJ JD4&D4&vY 7<<<<<<<<888885555555////,,"&&JJ??( @  , 0$00""& <$$0&&0$$8((0$$@**2,,,,,0,,2,,<,,@444$$p44@00P888<SSI;w>[SSI a\\UUKKOicJ??<<633X_[SS |,De_[S |,Dje_[ WWNNLGCYi=885511fjje_ .Qnjje .Qrnjj hhdd^ZZR\RHCAA==::otrnj `ttrn `vttrP97++2~zvtt}~zvt~zv {~z&qZ!~@($-l^{074' &# y%  %m}T*aT/(               (" !!"!!!!+$$;++.--:*+B))[*+U--U,,\..V,-b45E,,f./\//g45U22`44[33b12g55\77U55`99U44h66a55e88]88a77h:;]::i<941UqlQ`n6sqeCA;pv532XusoRPMjrHB<\wu VFyw Of_=}{y 'YS ~}{ /70-~}!tb]c~ZT"a^zx"h.|,kh"+*)(&&%$#i(0` IH*(D,))F--O--O,,O++O*+O**N))N()N((N''N&'N&&N%%N$%N$$N##M""M""M!!M M MMMMMLC*C*!\]}~{|yzwxuvstqropmnklijggeecc`a^_\]Z[XYVWTURSLM12 )::[}~{|yzwxuvstqropmnklijggeecc`a^_\]Z[XYVWTURSPQLMUJ::X}~{|yzwxuvstqropmnklijggeecc`a^_\]Z[XYVWTURSPQNOYH"}~{|yzwxuvstqropmnklijggeecc`a^_\]Z[XYVWTURSPQLM hhMM|11O00O/0O//O..O--O--O,,O++O*+O**N))N()N((N''N&'N&&N%%N$%N$$N##M""M""M!!M M M00xZ[XYVWTURSPQ12))A?\]Z[XYVWTURSLM /))A?^_\]Z[XYVWTURS+11EHIp))@((@'(@''?&'?&&?%%?%%?$$?$$?##?##?""?!"?!!? !? >>>>>>>>>>//m`a^_\]Z[XYVWTUA55Jyzwxvvtussqropnnllkkii}~lmbc`a__]^[\ZZXYVWUVSSWWcc`a^_\]Z[XYVWF66J++Auu,,R?eecc`a^_\]Z[XYF66J,,Aww,-R?ggeecc`a^_\]Z[F77J,,Ayy--R?ijggeecc`a^_\]F78J~~|}z{yzwxuvturrggeecdab`a^_]][\ZZXY]^klijggeecc`a^_G88K??["""""""""""==l'''''''''&,,\mnklijggeecc`aG99K..A~//S?opmnklijggeeccG9:K..A00S?qropmnklijggeeG::KiiNNnMMnLLnKKnJJnIImHHmGGmFGmEFmDEmXX<>K;;O??X33U,,N}~{|yzwxuvst##G>>L>>RBB[66Y..Q}~{|yzwxuv##H??L>>RCC\77Y//P}~{|yzwx$$H@@L>?RCC\88Z//O}~{|yz$%H@@LFG[??T33R55Y}~{|%%HAALVVn..=%%:ABk}~&&HAALkk  RR&'HBBL RSlCCe ''HCCL66Dww ++D'(HCDL"yy!mn((HDDLBBROPhHHf 67R))HEEL**4 ,,;;?Q>>Q==Q<=Q<>^OO0--3  ~oo 0--3WWm ^_}WW| FGl0..355B,,;++; --A0""%FFX>>X!CCT>>T}}uuIJvrrro uuPQx##&--2--2,,2++2++2**2))1))1((1((1''1&&1&&1%%1$%1$$1##1##0$ qp(0 -MM[[YYWWSTQQNOKLIIFGCC@A=>;;78+,{ & DDi}~yzuvqrmnijee`a\]XYTUNO[.hi__\\YYWWSTQQNOKLIIFGCC@ABBXYTUNO &ZZ \]XYTU+,{oo``UURSPPNNLLRROPFGCC@A>><a<?zz99Q&&7%%7$$7##6""611U3333&&LqrmnijBB}}CC]00D//D..D--D+,C*+C)*C((C''C&&C%%C#$B./ZuvqrmnDE$#yzuvqrGHWWvGGbpp77`BBt}~yzuvJJ$$0ss`a/}~yzLM&&2ttab1}~OO88G``OP|+,FQRffPPUU**6%%4WW  ++ uuYY}}66D11DLL..1~-ggoDDi ..1}}}}z{wwuuqq[[. (( 4240bcvwuuqqllhhdd__[\WXRSNOHI67-2 0}}xxssnnijde_`Z[UVNO-qq00M          JZ[UV67`aGHsEErBCr@ArCCzBB{::q77q55p34p>?_`Z[IJ,-CiiAde_`OPefMNuKKtHItFFtz{@@s==s::s88sDDijdeST//Cpq AnnijWXlmRSvPPuMNtKKtRRRRCDr@Ar??r<-0&)yzzxxxwwwussrrrppppn$M! L$O!C9#########[8v;]PPPPOOOOOwMKKKKKJJJZ;* $O"*7$O"6>\EEEEDDDDDm????====(": 7}hhhgggfffffcccbbbaaaa`l6* +' *; 2'; 2'vN ,'F$ {(#o.AB@@); nkmo;6_^ 5SN2VddU1FSqo ki| RQ qvXCCWtjNG.{y-YNLI; 7>II>7 ;;**;??( @    ((,, ,,(,,,,,00 00$00(00000.2244$44,44244444.66$88,880888888::,<<4<<<<<4@@8@@4DD8DDLLL(PPDPP0TT0XX4XXHXXL\\bbbdddhhhDll4pp`pp===;W}9!4&  2, /j\\\[ZZYYVUTTSQg1/1 !eGFFEEDDCBBAA??_, !5(#3&85$#4~8f64a*< :)7|p][n{9!" lk @X{ .GG- yPKrvst! uI% $Gt XR!|z&@*fc'@7!//!88!  !8??(     $((%))()))**///&00(00/00011222/88588";;$;;1::&;;4::)<<+<<8;;-<<5<<>>>CC"CC)CC+CCBBBCCCDDDEEE(KK=NN$SS9TT.\\2\\5]]=^^@^^A``E``0gg4hhhhhLkkiiiQmmkkklllnnnoooqqqrrr]pmq|}]v|Z_[rejajQ[admvA B>YqtsmW?*HzjfedbcoF+=IxlihfedbaiD?}r  ap@[wt/'&QX%$.bcWB|yv:43T\107dbm{y<65JP218eds~{-!,fet~S vtrn Ohfq?]ZuvtkVijYA#gEyvC`lz"9MURrxG>(K_NL^wI);#]|[ =?@PNG  IHDR\rf IDATxw3;{רp*"EAh 1%b)"(DQEDA@Hs wep3swy5wyy|_]@ħ=Pڦ|J['%@yoH=c=+3lWW$l)@ħ}JTC!q\+/; T   @H~" TcXb|P|CQh \O13`> 0j @%Áq14a0@j^!LC盯d^8|9Wp9'tUUŇmc.!M_q]Q xMtQS5]QϋTWWsWsM7ЪU+X>ziӦ᫯6[sE/kRj|Ԏ֙":U8HR"?^h3fq/V[䑳jPE dQ$_ѣr W^9@ @qP[2"q%N"ׇɲK/wk-䬧kQ4z5x Շ֭z+SLFeŃ_<;Jahh?9L 1*z`6=|z9i)p.WKS5pj&EE?n9NUo<a ~t$AiSh1)!=]wϾ}5u|d^(Yz]ꢎ'273E.ٳgsg~!:EAQ(C2OEQjdy'EM]JJػ';nW]u9HE=(\; Y5@9OT/j̘1<ЃuѴ/Q%B/fϔ'-QD[ Fvmà_x)?m̟"7jӷן:oPbYbrïIvIՃ7|h'b繑+Q7Y]ta :Fl+={ulO/%3ßnɒe6l"t&%Z7s#N:sһwo(dsqD)+Z9oCQ (:'NjٸqI~Yi,pտ'9/Ď# ;q o{H$ºu_jz֬ʕYl5: uud (//,L˖ Л#wûӣG5%%+!j|A(pӎl[G"yq|x܍rW Ũ|r;;]M2v:PXkkX`1-c(B8J;ǯ4} #9!w\DC.I{& 9_{={7Q} o_II =_~_^"w^c,^9("ud QW) ܗINeıizE1D0x8@k3/H$Qԥss( GݥDZʘ9s&ǟf3՗.ՇT }}=6i^dp`q Jb;ɓӆ IչHJc,7x .:TFʼ(*F K&̚5cOy^ϞDFrPW%``PΥU+m_q׎PN(t$P;oa>2?`ז6Ám|W @rɤUVFa3(Jv԰|}N'y9{/B!5~p7t>ֺ7HR+??3ԍfODb>?o.~(%%̖3 } >)>eZ.dBDёJKK3g'`w3# { ⫯vk'l߾'xR ;b¯~dmB k~s 63_eBuhp&2 B` JJJ5kVC} } q[3&oP(I'͓O-($%%}QpJko3q\ R`|P-qN O<ĉLai}8ł|$,Y5iy-FGǎU~Yދ, 8b&9}s̞xW\ ܙKwy'7tfkx _~ @qz{mj/P8K ˻:LMU@<$- Vs$m.Ocs3䪫n!1KNsLu;j?đ_K0IgKrJ4x?t҉̜93eg3-~o7~Ew-'mRKQžA:H*i}N?},7:* 3A4?8Mܭ[7|M*+St~YNS,o.ǿ7^\% 7ӎ}zb퉖@ꏐj$0TfΜ޽ĻN3R 彎ü98P/ sͲ/[2˗o r ڠQ1'߁$uraii1c3siۜf`| luF=補q6b3Νw>ßq WSYYСZ&|¯]O, I꘡/0tp]tvWHuГkPAaW%ޑ֭S+;: DÁ%8?cype|UIq2n%E}Ep8Dmm=(СC}tMjUI֕( [޽ٽ5k6m.dY4D]]}Q D0ɰaS,aTM8|,{%0z,Yxd|4TiT&v'E>vi)G}Rb{^:j<;wA L˖;cqqٳ܍W4eϙ;wS}Eł4Qj֭uŁ_;7Rz_|ge*cXe7 T1}QN*C,3# ~E0J{oasi %%A&Meɐ!G ~:/Zg?N[/\F(⋷ ~ "aQgU+£> 7"mFMA]25N:眳y饗22?oS̡z;x @0S~՜{ Ͻu~BH$/}=Ö-;FcyE()뮋3v G IF;Mï{̙AZ[ڎ! $ر#K,vKy9̅V0rĂL Knǯ}g9Q3=WGYV3nqnU$7^f_[$NN %c. 9mv6~ibMnq״i2fkcހ_}l߾+S|A I pWSwӯ_Tu[߾:LJJ|⡽!A/⊓l9GXl;`Ȁ=֭ 3gα/fgL=w8<99Hʾ8>g嵓,*a>cv(WX#3i̟9{۰(suTj+ "I KRTׇKWjZ Ěr}8ziٲ%˗/SN&1ϝ;pcٿ?>?ѥy-2*_OŹgӟfoCee)K6m} >,L0P3mݺ޽5,5u_ Gʥ /NPZ_3fID7_l٪}o暉)MMI'ݙ=üu 73W}C0 Aۆ-[kXĵԑX.- pј1cx睷MUZ4͉w :=/チ@pW^#F 2;?p/ވȧ=no0Eᤓ&,X\e' : w9(sA\9;@iiyltˆGۿ4pW$is?(>esFJ;tYvzŋqԫLyg?׶ڼy++y$ٳȀweΜt3S$_ϦM;=w$Xlg裏'gP|' ZբE NLS94+%:ܕ$x6_sӛ C.K׎uuѰ&FRZPwJN++SNI9ƨ=1O{^.'/ J֫<;~~](,\x\fٲ:dJKK,R(Q@FS! AxMu6le2 =zK9k8\ 3fZIICs-k2ka?D 7=IR^ZhY¯$ߡco]͆3dٱ8u!k~)|ޘ_Qx׷*) 2}<=QIrC6´iLR O]Bw?j z45Hmb[*oYO>\z%3W r#˖C Ji׮7c-K]o,_5k8^"Ognq,*JBwun /=7P( ~xW&O>v+ѫWZČ ҮWLc$ ~*aFRÂA_>i:evV s$ ?~ނ}v[v Sh~H8Ng,+fܪuDk5MzفgdLurk>-[Yx3n%j ;v6S0ix˲7UAaҤѮ۹s?7v9ݔX'`Z`ʔ mOQFv39^5pfOA/RZ2):t9l^tږ}*jV~V@ٸ˝)I@OѵkW+ ( ?(^᫒ >zM~xiG%<.QK/Xks6vĸqM-&]&h磌W@ˋ\ֵA3f0f̑5%.ʪUރ_;F"JmErؕW:~ *T, աC8|}9/ KvU$ee#F!qǕ,+,[a Wht ͔6a)TWOՉ˅LL02 ~HNj]I]WUU+KӮלOӺuӮ%8N}tf$)%d*f2YI&OBw&3fiaރjj'{5z ~-~^?PYkdak̘ɓf3~YiذꥹF?^?WEߧ ?( ŵih ^_;B,1B>=8qLu<`8bfcf,! IDAT=?o¯(p{ա5g*\ur2ŭ3NCd ϰg*8,H㳽 w޹d~ϻMꕽҤPQvuypMMeů3@,Yާ;o /a|l]ku6z%dUd $zBm#T w6w3] הf*Կ0 u=={~~5;Bm+<ޖ멫VL\ ݻw7UPʁv٦֭aae_;z:[j,Pz,+ o_pP&L 2~h2_:ypj:a ?7=R (/B&"ZU!  6:{]@fwdTMe2ӡ~7^7}s 'yvW˾WwHa;'z@ Cԭ[Wg;я4E(q|&B/ xANME:wdj 6UNZÞX_w<&o¯;ƪЦM+xj+m6I{(J-grX۶ @d2Fށ_yɛaWr7ȡh-jWIIws";Y-Zd/@Hā#ug[¤ <(/&jmljyQR4 Sn\ o IY 92%"{RYZz~4?y~e!7MIޅ@Yshv0/PEߣ_H=EA[]S.- -[2H/QR½S}}3˛('mڴ"v@)7n܄,)g NB^>>f2e},y6&MUWWǶmߘ輺͑q+sMIރ5ܠ-[;^A6l4-yF/l|-AQ`Æ&-Eؑmj؅A#E&My~IjgR֔3S7Yj+PM[mu֙?( @_(˛B pAYS( a;jl9M| JVރ_1/v#{/m*ޠ|3Jrkf`fzٲŲ2ރ_)ʇ\ރ_$]@fX  Zf-%kJ} /|=Ak]Jlֲn&:Zj4e٦X6(9a~aM^y ~P.k#V`N-%8p Wz%T5⃭?@09&,_ڠ^Uƀ/Op[0u4\pa[f s.tVC~:$m(U]Dy>^.%}/Y|}Nb!Awilr<(-z?1ZX4 Xc {uhZu^;eִn}2{:<-˺0]ftrjjtN|Ň$ہf?+V|inCzQq>xQb>M΍~EQ{'&%,xQIwr!jG`VϟcOL/I%BwއؿFI ˶a9?PZ*YoHWgTm>pESjH)ϢDB(JgC/˲zHN$=2}w &={=n8|ހ$(Oo>XbT.'K00oH5g5kY?U"h7ׇ5U S?Ňʗի78]ƶxIίbq%BЇ?r z (&4jW_g^kmddFhVB wn܄)ޫ $o̙7U `d"p"6loe] Ahq'4MB e^7F޸2j.:EQ9Skd Pz~w<2߯ $җȪ̘L@֓{k ydzoS7{T<Bc bUNxEGc`f`I|5k W0hݰIq%@+ uH0+}v^}U{OWAA&󅅿voBIшb J+7촬AkՀz81+>3sΙ1+(I;)?nanTÒ{35^k{99n&kn|zcaVLuySdlizG< 4-gs@ 5K5éU Y,P/8rӇ܈V졾԰`7-ZLXll5w- c`0+۫q~1sAA:S/k ثCӪss_Qa,s6~xS32Nʕl9-[j:kDV!_D<}}ݾ%%GТms6jjЧiw4N C?^ӂ|l<3gT\?Lx¿4N gٖs玬Y`0høS}f2rlOʔO6{_'f'L,ثf(ԟKO4#d˖o,'"ep7`F6o3fqɒԍx|/ +jxÑ5_TGѪL 1{ם {ߐa8L[bT^Kt᫩̥#uϳ>ae~'U&]b_/w8e<~ ^N"n~|5_~Q,$YOի7جC1ܣ lo痯PVv UYiZ 312>_~gIM- o$Uߪ,~zoU e+[u Ic馈BL-?@Ey$/r*z~'l EKQVAiذ+GugA$Ho |S>W(-=>>l޼- L+}=֭ߐMb(%M}#<EUbovʪ:Hqp]Vo =~ʉ:fNm=DMͷ6˟_OSI72hXȇߗ;r~ xT-^ǫY/:I8lȲ7t {`/w@KR{Rg_/U,t;5Zg_Oh{ۃ_@(t$wjr ~ARQ1ɢo=L>QT/ގPs[d˖3d_  ܜ[R^~Jeضm'w,K[-/APg$aM~~ïIRg$w @{Ãu~̮co{މOK[cYj@+8eW_}_w{5JJ@ .]0thOu385\ӧ'OQܹ 7먼3gZƱPu~N ~ׁch׮aoL:QW! ydN;NguE-o ;v3dl߾2nsXSFu#mס(j']!LIx>v[";_Q旹 k dbK`7p_~sV7S]n)!gNoCEw"]o?OB璁&^ܞZ ҷoYkDV᷑·:]&Nl< _cIgkw.fCnZGs~@}b>%%O Oo,> DYi+3uu|{?T[)^4imwrYϦ@0dy7RKɇ?s:d^TV^ֺ͚ۊk[8$~F.>n/I]ir2PB/_=9Wpʯ`Yzx{S(uu s>v_MSuHo?^θqStY+ á3+ק]NsSرC&? t x>'F˖W9}\zOsv?q )N8a$/Bf&kà(},᷑·?~IH˖W"$8V|=_k(_-PU.GHSܠ@B#Em+h~~{i*k}r/py W i EO;~M "I=(Ay|6=ib XJpGfb|@h-އTWƐ!G A@:(07eCTV^긷`ڴVGszZ)}z yŧ8&1̾J"_Z:H>_.De%H6LPN3(- 3{s)`~MꖠvS TT|pxy 9s<>cdbW4ëGYY)OFδ}C}B%ߌ2*+' נ?.\g\Ám1:\2Fk9ihY^cܸ1TWf~Q@5o ~mOzه՜y5D?I6*t ԡǗptXSUU^_}􀔐'Qd>%[LJ)\'_ :ڵv]P1 @)fsɤesqlLvâѵo Dy>Zskٽ{_Bm;ĩeV(dTyy3gq㎷e0~jk?D$7 %=%>キλsfv=0OULuxu.B%Lg0ED|A:>~ul<`>?.rYׯi70 XkFNUNTD]58<q^z5;*1YHSW@ŶQ К-.% |3ɓo>j;9˩m6kYy[)Alۘ&x|gJ:~/PZ:Ka.{+}=O~@.[xiÉ`>G5!ג ?e5u)HQ"3u;uÅZ\~/¯}pX=zك>ԩw׿V RϹY*v@FF'0*fduc> (QZz2#Pڹs^\Wu3B5NCp#Νy6l0O9I독_DB! 7=/.17Zan |W^ZjQMO8dNTM0Y6aWwpxnROs›ٹ3 >~ Vfnɋ`PCzq̙ˆ 8 %!L0#a`:M EIDAT7QZ:Q; 7xw0k~8D5_x<ߗg A.)N}bb! 6~{SV6IBr\qŭ,YڰJG2t[^mhZEر~ =pC$eJ·?=~@(ԟ(+;QlIrĉ?d&G[\)\ͭ !4]<yZ:}ʊBZrD"Pz2ßNÄB&:Vb.ܹ.^}T=p)0Lb@29 r+?w{n¯?(qbDH |KRGᡔsQo:]z8jL7`2/ ;w曯fԋ )ìF};]V^qՊn/eb D5TE Ij(B} ^(3f=7[I(|P > Lv~vW\q[S\,CuA6qZu(rh1:!JD]AJ0P("eB@đy ,˼qǟXvE8p#TFd4<ѩ~v-\0`Оρlœn{H$ /o~kl?\q 5E+3uЎS/믠ukmz3y<̿ygؼٵfzu뼽SKMZQ{i]Bl-*2B{t$۸k~x:O=y3):t7?4x6&+Q9\uE|;^|s3/2k| ib qb9P=_ꐡl߾/?+H>=Lb[^i^ggcn4u+uy)GNgҤлwY~M2{|B^jn:_/Cqy3aXznfFy_}n>o܂qܬ r'_|ѣ cǎGr)ӢEEmm=~wY9XrE* <d$՜ Pwf-ÇfԨc9 ;- M~>h)~`#)?D8l~CF (пFGɠAGЯ_/JuuX%˗fɒ̟ +V|Y{;Z{|qs مr}ٳ ݻw{NTWfÏ;˲̖-ٸq 6lfݺM|:.]źu:+w&֕mV ,aAE.-ҥN:Ю]ZӦM+ZѦM+**ʨP▗ J ,ljFc|A8ȁٵkveܹ;ve7lڴH$1 /P7N3?C?\5xuJhncyߺ' Fu\z`/_yTkYc(> GuoP|e!ES/|_*ذ4O x uu^+߆/_ET[T'N9-6DGл eS~0:`Aa+L1:PM|Zn +G/Bs8p;Nc{J|v$;Q=lH|Un^^[IENDB`(@ R||Q10 rq ~#((EPPfuu}{cttCOO"((}^ZggUeef"AJJ``                              "\\QOMK!((9XXTTTQOMM} MRR:XX TTVTQOMbBOO tCdd                 &``XVTQOMrEII}{xvtromkhfda_][XVTQOWXXV#UU_][XVTQ_dii>XXX$UUa_][XVTQTdd@ZZ!!Y%UUda_][XVTS}{yvtrpmkigfda_][XVhQ)++Kgg   22a      /ffhfda_][XV"((|ORRBYY^(UUkhfda_][XBNNuyyBYY_(UUmkhfda_][cttI``            ((b+XXomkhfda_]z}{xvtromkhfda_Unn   5jjtromkhfdaFYY,VVvtromkhfdGYY-VVxvtromkhfGZZ.VV{xvtromkh|wyy}{xvtromkettQSSwG^^8[[ U}{xvtromDNN+,,wI__9\\T}{xvtro$))}TxJ``:]]T}{xvtRyK``<]]U}{xvjll|K__<^^V}{xZggCTT5QQi}50;;&991KLL AJJtEQQWjjGgg3OOrTUUvXIQQ $**(00!..**~***x#**))]$((dyzz=FF DSS}w>RR 1EEjvv_*11&&&&#00#077(66"U!!!HRR=RRY,,,6>>/>>'** bss:EE+33)337EE\ss!##yzznww&&&(**QTUULQQX$KLLEII#^ikkdiio*++QSSvxxtxxORR)++tt 54T~S????(0` WWlk /66P\\crrl~~l~~arrMZZ.55 o#''pk~~!''%BKKxxTT=TT||spmjgdak}}}5CC!AAvspmjgdk}}suu6DD"AAyvspmjgapp^__}{yvtrpmkifdah|yvspmjP\\9:: :LL-JJ  |yvsps/66=PP0LL|yvs Z>PP1LL|yvW>MM1LL|zp***%,,1==';;++#''n9DD *BBkNOOhyye{{RwwLuuBJJ  333R__""|@^^+00x%**AOOun;NN**r~~t$077)77(Sw+22'22hPg|h||f||wm`whS333.11Q'NOOIMM&o*++(**9::^__tvv~~svv\__799nmZY????( @ WV 7??GSSGSS5>>"3::{t/88&**zv(00.uvrmhd_[VVh||- {vrmhd_[VQT {vrmhd_[VQMx{vrmhd_[VQMh||%+.. 11//QM)11""4422VQT 8;;iYWTROQYDA><9>[VQ/88 X,, +PP**_[VVtUgUyyRyyPxxNxxKxxNX>tt  B S ] hc(0`      $ ( $$$, , ,0,$4$(4($8$<,8,@ @ ,<,D888$@$D(@(,@,$D$0@0(D( H $H$0D0L(H(4D4 L 8D8$L$(L(4H4,L,T@H@,P,8L80P0X,"5:D@1"5:D@1"5:D@1"5D:4>"5WK%5d\%7ĮTH%7(|o %7z |oj%7;OJ6%7Ÿ99%.ş Ÿ;< z(&q mĮdWDDVcf N NLBLB mi 7========;;;;;;::::::999999+N  N??( @     $,"&"000,,,$0$&0&(0(,0,*2*,2,$8$444 < 666,<,888$@$,@,4@40P0>T>BTB>x{c{c=52//8~ | "r %ZI#6)(0OLl,21+"  !'& \%  $W7-kX7. (                    "!!!!"!! ( ++.+$;$-:-*B*4E4*U*-U-.V.4U47U7)[)9U9,\,.\.4[45\58]8,b,2`2:]:5`53b36a68a8,f,D]D/g/5e51g1@c@4h4CcC7h7EdE:i:czy TG{zEfa:|{'VR"|.0/-i^[eUS}sXWqrY,~u+\Y)(&%$$#! Z(0` IH*(D,)F)-O--O-,O,+O+*O**N*)N)(N((N('N'&N&&N&%N%$N$$N$#M#"M""M"!M! M MMMMMLC*C*!\\}}{{yywwuussqqoommkkiiggeecc``^^\\ZZXXVVTTRRLL11  ):[:}}{{yywwuussqqoommkkiiggeecc``^^\\ZZXXVVTTRRPPLLUJ:X:}}{{yywwuussqqoommkkiiggeecc``^^\\ZZXXVVTTRRPPNNYH"}}{{yywwuussqqoommkkiiggeecc``^^\\ZZXXVVTTRRPPLL  hhM|M1O10O0/O//O/.O.-O--O-,O,+O+*O**N*)N)(N((N('N'&N&&N&%N%$N$$N$#M#"M""M"!M! M M0x0ZZXXVVTTRRPP11)A)?\\ZZXXVVTTRRLL / )A)?^^\\ZZXXVVTTRR+1E1HpH)@)(@('@''?'&?&&?&%?%%?%$?$$?$#?##?#"?"!?!!?! ? > >>>>>>>>>/m/``^^\\ZZXXVVTTA5J5˄yywwvvttssqqoonnllkkii}}llbb``__]][[ZZXXVVUUSSWWcc``^^\\ZZXXVVF6J6+A+uu,R,?eecc``^^\\ZZXXF6J6,A,ww,R,?ggeecc``^^\\ZZF7J7,A,yy-R-?iiggeecc``^^\\F7J7яŅăā~~||zzyywwuuttrrggeeccaa``^^]][[ZZXX]]kkiiggeecc``^^G8K8?[?"""""""""""=l='''''''''&,\,mmkkiiggeecc``G9K9.A.~~/S/?oommkkiiggeeccG9K9.A.Ѐ0S0?qqoommkkiiggeeG:K:iiNnNMnMLnLKnKJnJImIHmHGmGFmFEmEDmDߊXXK>;O;?X?3U3,N,}}{{yywwuuss#G#>L>>R>B[B6Y6.Q.}}{{yywwuu#H#?L?>R>C\C7Y7/P/}}{{yyww$H$@L@>R>C\C8Z8/O/}}{{yy$H$@L@F[F?T?3R35Y5}}{{%H%ALAVnV.=.%:%AkA}}&H&ALAkk  ڤՋ RR&H&BLBگ RlRCeC ԃ'H'CLC6D6ww  +D+'H'CLC"yy!mm(H(DLDBRBOhOءՙHfH  6R6)H)ELE*4* ,;,;P;;P;+;+ #5#*H*AHAѫ+5+$5$Ό'C',0,BSB;T;-8E8   3E3||ܰkkXpXG\GF[FUpUffڣ]]"$"!KX^X<_<HZaZ;[;,"$"hh"*F,0,CJCKSKJSJISIISIHSHGSGGSGFSFEREEREDRDCRCCRCBRBARAARA@R@?R?>Q>>Q>=Q=^>OO0-3-ө   ~~oo  ΂0-3-WmW  ^}^W|W FlF0.3.5B5,;,+;+  -A-0"%"FXF>X>!CTC>T>}}܆uuIvIrrro uuߘPxP#&#-2--2-,2,+2++2+*2*)1))1)(1((1('1'&1&&1&%1%$1$$1$#1##0#$ qp(0 -MM[[YYWWSSQQNNKKIIFFCC@@==;;77+{+ & DiD}}yyuuqqmmiiee``\\XXTTNN[.hh__\\YYWWSSQQNNKKIIFFCC@@BBXXTTNN & ZZ   \\XXTT+{+oo``UURRPPNNLLRROOFFCC@@>><>zz9Q9&7&%7%$7$#6#"6"1U13333&L&qqmmiiBB}}C]C0D0/D/.D.-D-+C+*C*)C)(C('C'&C&%C%#B#.Z.uuqqmmDD$#yyuuqqGGWvWGbGpp7`7BtB}}yyuuJJ$0$ss``/}}yyLL&2&ttaa1}}OO8G8``O|O+F+QQffܥړPPUU*6*%4%܎WW   + +  uuYY}}6D61D1LL.1.ѧ~~Ҟ-gogDiD .1.}}}}zzwwuuqq[[. (( 4240bbvvuuqqllhhdd__[[WWRRNNHH66-2 0 }}xxssnniidd__ZZUUNN-qq0M0          JZZUU66ϐ``GsGErEBrB@r@CzCB{B:q:7q75p53p3>>__ZZIIԘ,C,iiAdd__OO՝eeMuMKtKHtHFtFzz@s@=s=:s:8s8DDiiddSSա/C/pp A nniiWW֥llRvRPuPMtMKtKRRRRCrC@r@?r?  B S ] hc(0`    $$$$$ ((,, ,,,00$44(44$88888<<,<<@@ @@$@@(@@,@@0@@DDDD$DD(DD0DD4DD8DD HH$HH(HH4HH@HHLL LL$LL(LL,LL8LL<E E eV2222211111,++++++******)))U_  RL&yyyxxwwwvvu}}}|||{{zz-1-1-1-~~uttsssrrrq#-B M @#-:#-:#.bQPPPPOOOONNcHHHGGGGFFFX#.h``^^^]]]\\\\[[[ZZZZYYYYYXXf#. #. #.&#.ppommm$/5?:,$/6C>2$/6C>2$/6C>2$/C;3=$/TN%/aW%0ÚQI%0"nj%0l nji%07KJ4%0Ĭ55%'ĒĬ7; l"!k gÚaTCCS`d E EDADA ge 088888888777777666666555555&E  E??( @   $$"&&,,,,,000000$00&00(00,00*22,22444666$88888 <<,<<$@@,@@4@@0PP>TTBTT<<;;::t~g7^g7^NNMMGFFLSLKE??>>==vo_o_941//8wx"un %UF#5)(2pHGe+10*"  !'& Y%  $Tx3-[X3y. (               !!!!!!!!!!!!"""" ((+++..-::$;;*BB4EE*UU-UU4UU7UU9UU.VV)[[4[[,\\.\\5\\8]]:]]D]]2``5``6aa8aa,bb3bb@ccCcc5eeEdd,ff/gg1ggDff4hh7hh:iic_8~})VT(~-0/.g^]dUSvr\[qsW,wt+YW '&%$##"! X(0` IH*(D,,)FF-OO-OO,OO+OO*OO*NN)NN(NN(NN'NN&NN&NN%NN$NN$NN#MM"MM"MM!MM MMMMMMMMMMMMLLCC**C*!!\}{ywusqomkigec`^\ZXVTRL1 ):[[}{ywusqomkigec`^\ZXVTRPLUUJ:XX}{ywusqomkigec`^\ZXVTRPNYYH""}{ywusqomkigec`^\ZXVTRPL hM||1OO0OO/OO/OO.OO-OO-OO,OO+OO*OO*NN)NN(NN(NN'NN&NN&NN%NN$NN$NN#MM"MM"MM!MM MMMM0xxZXVTRP1)AA??\ZXVTRL //)AA??^\ZXVTR++1EEHpp)@@(@@'@@'??&??&??%??%??$??$??#??#??"??!??!?? ?? >>>>>>>>>>>>>>>>>>>>/mm`^\ZXVTAA5JJywvtsqonlki}lb`_][ZXVUSWc`^\ZXVFF6JJ+AAu,RR??ec`^\ZXFF6JJ,AAw,RR??gec`^\ZFF7JJ,AAy-RR??igec`^\FF7JJ~|zywutrgeca`^][ZX]kigec`^GG8KK?[[""""""""""""""""""""""=ll''''''''''''''''''&&,\\mkigec`GG9KK.AA~/SS??omkigecGG9KK.AA0SS??qomkigeGG:KKiNnnMnnLnnKnnJnnImmHmmGmmFmmEmmDmmXKK;OO?XX3UU,NN}{ywus#GG>LL>RRB[[6YY.QQ}{ywu#HH?LL>RRC\\7YY/PP}{yw$HH@LL>RRC\\8ZZ/OO}{y$HH@LLF[[?TT3RR5YY}{%HHALLVnn.==%::Akk}&HHALLk  R&HHBLL RllCee 'HHCLL6DDw +DD'HHCLL""y!!m(HHDLLBRROhhHff 6RR)HHELL*44 ,;;;PP;PP+;; #55*HHAHH+55$55'CC,00BSS;TT--8EE  3EE|kXppG\\F[[Uppf]"$$!!KX^^<__HZaa;[[,"$$h""*F,00CJJKSSJSSISSISSHSSGSSGSSFSSERRERRDRRCRRCRRBRRARRARR@RR?RR>QQ>QQ=QQ^^O00-33  ~o 00-33Wmm ^}}W|| Fll00.335BB,;;+;; -AA00"%%FXX>XX!!CTT>TT}uIvvrro uPxx#&&-22-22,22+22+22*22)11)11(11(11'11&11&11%11$11$11#11#00$$ qp(0 --M[YWSQNKIFC@=;7+{{ && Dii}yuqmie`\XTN[[..h_\YWSQNKIFC@BXTN &&Z \XT+{{o`URPNLROFC@>z9QQ&77%77$77#66"661UU33333333&LLqmiB}C]]0DD/DD.DD-DD+CC*CC)CC(CC'CC&CC%CC#BB.ZZuqmD$$##yuqGWvvGbbp7``Btt}yuJ$00s`//}yL&22ta11}O8GG`O||+FFQfPU*66%44W  ++++ uY}6DD1DDL.11~--gooDii .11}}zwuq[.. (( 42400bvuqlhd_[WRNH6--2 00}xsnid_ZUN--q0MM          JJZU6`GssErrBrr@rrCzzB{{:qq7qq5pp3pp>_ZI,CCiAAd_OeMuuKttHttFttz@ss=ss:ss8ssDidS/CCp AAniWlRvvPuuMttKttRRCrr@rr?rr#@~yyhccc[[[6P`BBBB?????j~~y777733333:hhccc[[A ZB00000,,,,,,,'''''''' 3hhhccc[HZ)mhhhcccHP*mmhhhccA >}tttqqqqiiidddd]]]TTTTNXsmmhhhc61( +~~% usssmmhhh"1M /~%uusssmmhyM /%yuusssmme .%yyuusssmO$#yyyuuss~(*{~yyyuus4GE;;~~yyyu-M |nj~~yyyM$6la 0~~yfe/WppS,{~Of q"w UK _HH\zeV$42oe^^M(>P^^P>(M$$M11M??( @   (,04 , 0$$0$$4$$8((,((0,,,,,4,,8..2000((P00400822444444<44@44D00T88888:88@88D04X44X<<<44p88pDDP<cc]#s~!jcccfR^IIFFCDU64421:ojccV% /pojc* $ )rpoj|, 9nZZZWTTPLLHEEBAJurpoy39yurp{3 %iSNNMMIIFCC@@<>>56]99T45h==NBBBCCCDDD==^EEE@@^AA`EE`LLkQRm]]ZZ]]hhhiii[[kkk__lllnnnoooqqqQRrrrmmeeabppqqjj[[jjvvrsab||}}||demnvwF! HC%cuqor`"D3Uzd]YWOSkM5AXxfb_]YWOGbLD&~n Gm$Egvq.@KOS`Hyt964JP*(+WOr|y:87=B-*/YWo}|0 ]Yp}Z tqni <_]uDlawtqjNbdcF,{ Iyt;efz'>\^RnxTC1[sVQhvX2?,lg)AD##EPNG  IHDR\rf IDATxw*pt+TF`=Q)&1c4$3HP((D7A E"hܶٙrwz<=S<|>"2t:>"@I@0w7S6:*[r]WÀ!@_O%gR l|sW,WfS08 w ,>1\{uF @aNK9K`>%jr @Ӏchݿ=`؃,5_xT\,ToU 8\WG*] cf]ʉ:Ņic!p+MWJ#^F?qa]L];Y 4\rN#Qs| ͕4edZ&卋x*mko~} ]ȵqYL)ЧwouFΝо=:tP۷@ @YY^,˄aԀ74pAۧ|e}޽~-[hhh6u6ϡMp#KB 0 O?哅 PfuArlʁ_?(@JN8'23)++3\s_+O.yj4U#$pp0WȥZߢLމ%_̹'ӷ2>B+?P{ } fΞ͢/@FLC[Z2ewb6O:x L_N}#RönΜs5g,\mc1p7Vb|(t"KKq+**꫹ׯr0 xZ֮_ϴ_';wҏߣ)6{0 p_y<N=n?<~4Ѕ_9d#]8f̴i̙7P(9-FyT*'˕ZXk۶-7p|3zJ¯r[m㉧iӨ9tH?3 N"j3y nF~t뭔kGrW9\CL1Wlۦ} \⾬E%PڥhW殻)Sy]C* 2s~1VYGAGz1'ɶZ(AL;뮽כ1xl/"Pd!#aa<թĒǃF}>$"k̔1džɲ̫sro~ÚӤ78ij)?*}ջwoN|/B!hlTrL w[ i aGB()P!{Je^}5~۸Q?}zZ\ddC--s_ZZ/︣i%U oll=t 147L'T@**R>J!E3ߞ~55eLd-5g @y_''_~;tIy+ Y ]mS &y}H%xJJJK^6q"l}<<쳙X$P2E3]a\ @ //ꤓNO?2؈wz5N iV{Y _l?.,\}ep&2Ϥ@q5L˹-49ʈ`A| _ 0SAvxV>5X/`̙Wbik)/tR ^z;鹓'OУG/azeTaY?1LkԾ=„6;wwɬ^מfd&mʰ'x;O?RFD}ҽՅ_;TTcG:ĽU0lg3fϛǭwݻ[!b^\Tӟ"iy> eCճgOf͜ɘ1cRG6 KgHx;vߧLC1|5]{-l˚B٤$oo=[?8)'{GSG6 5sFrǫ.Wy;DIveSl޺U;?kԢ SjtՕWOSHKf09c naݼU65r‘ד^@" i[VƐاGQ}PYQAߗG)KET;PhXAӟ̙q,Hq"t/2>iK==w&HР|LB Yx1-͏>b5!( p I>Đ~4n'q+yS| |]We`xǢ}Q|@>Io_AAO?4W]y)~t 5#7`kox :9M ?iillDN뾒| &L`.Ώ'B!eYM||WN0 |>FVU~I > ,ܤa/9ktddbEToEv3(**b޼yx c_}s-~TX}Ͼ:eE;` e»v" M5cWУ[79Ys禳wjp2-eleK̞=&[~u/&N?T[??FdY:$Ye-ի8se0 WA4^l<T!Cxet~"1Q dT2M,I>,S.\HDԉ29:u*KVh]~#e0w7huHWY&aۗݺo<]n(U6 dpn3Y~uOL\?8먩Vy,Sѽz1G̸@G(3,C5~ ~U# !g<#t2ILk%?<Y\4B8XBdY?|BǶm8UWz** M¯qظy3VLyN L'#e)'̬YI~5_L\?pIsSG MFЮ]v+_hHY'>c QNdN+Wvݛwy%Zҁ_֓+t}oѣJֱkuLoJl {H "a>s8Yqxo )0 ey y7;⋭rϪ²M66r!_;ؠL=FXQa!' f; 촛2a|(:S멧N?Oz }q~ 2֬1UU ~5`{uf<cvLn[ ,z geߖnfϓY~zx',˴--e2c9n`v?VߍWcۿ__pa<O Gض-1ڕKo~Q ha<`u=tGaxn⧞z8+&N̹]Ge=*I():iWsqC*/Vⅷ'HC4~?' +wܡxs6 e~5USӧs~N\26m9eʁN:xW# )#1qrO==?%IҽKF.8T qم?vN0~CӧP(+>M}NGpv2_ vc7v2?[n,Y.\[s_bLD‚*:us&LBazvݛeCah 2%SNE*){egsvr-@M(#zȻ<_9ٽwo4^y}<]Y"9 CAOӴ@&$I]էN?˄߫f$%ٓYm1^3`:bN[S.{[?H.<}Lf̙A@AC9sxHtMH4ʂoaC{)`m-1we~eʰ8r_n\>GWUl V_o9(m'tNCYoYm۶e_ӽ{wF8q"gΧ'W\?V^ل ȱP(/_!eEE,{/),g_P8b$~ʘ ~5l 855vcʾN@^E`Y_9餓ʛ/v|zuF|$~.$y01W#8eVO?$I:ps"r ?Bw4e%%mӆ7>ns "m\ͭN:$>x}iFēݦM ;묌x_[͟x vz,=e\3jԨTBy]׶;ܹyxfH~~{13T0 :/W+j]:\# )S6`"; 2^G˓~ڴiì3)--He1hr/d٪Ux^^8ef ]ѡ=++' |8cpSe4jXhĪL ;׿PjA;j:x衇8hQ_.}p2@Aw^=לf N Ek8:e޲&J,ق_ B׵"-uVR\$I|`2wDV$gPYYo%ae| |wm ~ W)/9^^laY $,j=WuuKxjV (,_ka;g_~ىT3>;##?~S|L??WE@ǣs ?CSƊ_v/0 c= 6mիSUے<|mtj׾~w)oW\x/`mݱC9?&?@pUSзwoaQ+`8ʎ%u}E_ 7OGsHĂ^/G5bW;4u@cg ~XpҨ 5LO0ǯ3[f[3/%_,g#/̙'g~#\cnol >;_>l lYL;(!ly1ЌS\mlD+63u]1KUu,#y ;ٮ׆$Ib6,-~GdhQ瀶ǷG'WÂk 7S 7d9.:h\X~pݻ7Mb ~ '_TU7-˽7sޖ M[>Z*0Kh\ !s驱Є hHn3~U_>';8kǎ6vl NP}c#XGB[ޛt~Pn*Mr=&S#mڴګ֏Sؕ~?~꘣@kZjN>BSe!p {u0jX0~U7\vm쎕RE2cns|ճz76&mߝOoپ=UےANDkS'LpԕXClۻZ?mU 6\{%v$% @|gzܬ7a`:&GVnXOQ _qTYI]Z%ձ=jgy \3橡[J)@;r X'y&zJ0?V6SAf&^_5~|_>s'$e9!mV{,^ݻsڄ voR[oPA W>U;_$N5)?N41޹\rz,7Bqvǀ @0ٺvg0Oe85ظok-#*-ml!;#qㆨGk=%{Tt6j?Q'(22cc\?vw*!iW|lIU}X^NIaQ!( (6ޭ_r?( +bz`r@aBT$IW&G?5,GjjkSYUW]ǦoԌ Z:Vk.D,([ұcT IDATOul~P4Ve ~ xN~ ӱi0P^Ï ͛ o?BPUY1Ci-z;aHP&_o8:xyt,/w|w,+uԹʑ`^ï Z-t UM9l ǎSĩSc~-@L~4q^m-f;b]ǩVs>l*Nw~oMj' E^.GBh6 9(+-i.GY/B!7?F?^Nβ4 dL DZujpo1`j@xTݗkķF:%I0.WЎ1`&` 6 O*Ao^w0ٔx<4M}f?c @ C  YJhL;Lpl5 \yh=ń ;8r?⨪* )"JgtZ~V*ZѲ8'Հ ?`\SE|D5ADM :4ڨZW+hӺXôҥ"ە 1'{~@B zi_C 02 QPi5AʢA"i4fu?Z>6tHkN58T$D @VV/c^큘B_p-W6'ޛ`n@BЧGU%(JNVS[0[~'ӺXôYQUlyƆ5V$V/=s GU2eSlS ~{k>Gʄs䡼08-5ÏK[.3dž5GDG1a}w׏/ z[MYXXH\LT}o/~a"0~ uPAHJ{hď J\Dõ֭KT1H{q6SPY{ ~V:=5ӹkA "iAG׮vv9LZ)r'y5fO;kZ1MzTT1=@:ud~&@4MUS y.@ :kg-бAvΟU+R.ov )esw~]]ePy ?B Խ(Mۗilthް0Iy]L!uu`tS&=( `0WP yH*vj!Ԭ >D͝?vZ~ ~ k-|aH~l%v`][~@5ʬs Ao@@0%?ohS@8]V:{ kNUм'jEcySQg7XMlߺ % k=F6в6F :vw+E.FS]9=$~5V?%OXvl4SXuƦcyT>/iy5`G{ ѽb <!`Rfi@>/8}Gb˞` t IbE9O0fDZy?5U19L+0K7{7˙y:7ZcƼja:4(P!78#a8a0\g^I/1aZ隳'GDLhm(Nq.Lw,i7 n:hEôˤ<\[555) +!bUk]ta.\SkNHEEJWo5UubŅy=1_Ks7NŸ:]s!1$鰶4!1}R(6Lx*u%e '^y|#'xVZor\9aF{ZU+iV*〬y`(~6v,?Hcow8@؛2Zb*u"-}`?6[v[{ASc4T #Ra#@ lz0 ?I y !kKROq# lj wÅ?7rPju~Ӷm|fa,۷,P<>_o\ [b3)4[wr֭Ȫx7dYfΝ6ڀ`TܵK@Z% .Bͨ(Or'w;h؈_wͺ<71oav<!;`ӶmVk&=VSoڼv܄c6 xy]1+۷'`Lf´7[ES~߳VuXjC,âdC"@"N'ǏS ̣c'?0יq:+{ڵCy[4W>+0-S8˩uEdE*)X~t.EM%!V[ngX\0xJJ*Ÿ* t~!~ƧӒ,\{#"@K/X'\?+!wO._o 8d T<Χw4^/E^_r|t L+A_?|x~}5M X+OGr%$)@ il+]$ݓ's'. pZN!#ȅn1_wl~/׽JJi)&%KTsb<`,SQyoƂyՑ  TY( MUUʋ2h= ?/x[5L0"9kz]H%%H>^rJ”'{ڶ׽{rMע1lvL}7y Ѕ?3rW~4XYLO,PH4oZuma-Qj҆OGCOCk6m(m-𖝜vN%R~Bo[hӮ~AoVUZcN3^x$Å?r~߲* Mfo۩l ܠeVs_l}<%^(FL(17m+-o\:X!^ m.LgۻOB/8s'mr fTXc_CzjSN Ҿ]Nt,S%@ Ml vzix85W@>XC6OglXsuz1NikД9ǎ:;_/#^`ճax=h?%p.15„AVL/xihʀ'f̰&Cj3?H?(BP~nN>afYܕ%9H/yurn^\T7;) 1sؾk~<}x4UToT=<萬m~9s좋*/޽ 8"qؖ5WTۖg ~$N/^Koi 0LD3H:AO %:4STso|WqR5qte?w2k T֬_K0S׫ONӷ +GS\L)Ĝ753eͦMlD+`j/$## *~:tFeA3^wV cn^ ץ+RqQfo sպy}{\|:͢ćc6nfb)beX.zG &1O(.W(Bݗxٔ eiY5Hæ-[SOEl Er2TBP4׿ l۹n~ʬ[^ zQveQ|x _=*3{)>4{yVf 61aA8T[}'i0_u*3]8Eq{j ?ÇU~ v P7,3RkSۮ]b!~WiIݝ_N8~վ\?_nmIhȲOh!: kZץ ʼn34Η(Y]Vbco y^&@ 9epբOS3f2[j/QxR:@?{eDRI ~]]-(<_׮z'-jKwF76v:?ӱ:a=u]:#GF'$8pN|^޵̯4O3Մ㻓'G_UȵzvhϘ}&! b'EWaΞ^̅O/(* }(:E1nYk~h@Aeiɬ?T6v>So:T_OOF-L&F]t5g&V#P܈[ݻ[PH 1~霄ق_?wM+tGInF*t#St=H{vӅ\Y'ʼn^IR Kߌ)ft2P#;ScPU=XW&q />d'M"I&_aN!e\}L$Rt#(5H]Wt A uޮ]\]œ?0tgIL_~t?܀CsG عk|THNCÅ߅iQvHlLÇ LѝZr|tKٽ;#ML+$ o }{u..?)NzE۫A*( N&WmrxZ\)zrr V EXUa A kL \CԵ*|9]{mֺtc$'bp \rQ_X݆ =VY8o,.j5ܙ]o}r/~w!3'v2_GPH'#efMJxu?\\ۗ6\(e~{Wz^:$Li1@c9}Tt̨-J$|ݺ!"…߅_С]~~igs|klP܉ T9f0"EKnWW'_4n<^h=?/xE@(Ut׀Z⽤ y % mD%q7JJ$J O,?"οVeMh`c:U6 (.* ǥqЮ]4|lto{)t*5(,h2=rt (J'+# (Fd4By N;$*bw\U b7ofe++]t> vQHbfv L!~4̅҅K.W2}G(^~\Q K'@A3|:iv0o IDATLprV,\[('MBe?Y:UȮ=jUSICq87ޠsǎd!UVů@x:v$g749uo{۵WP8v,Gg?\s]446NF|reW6wIcu,˼{N2)-߯?Y87%Qvx;uBW&BSOGMw(Nss; !i>,+V]Oǧ3*׵+nc^FR% |{~TfN){Aky)<چ_+L޿)3 0ן387MA~#WSƵ{Qv;8p׿2d@GUxn,&[\3$)Og!MWmwɒU(v*CXv m#g^˔2fĈd7c`" Mk3 $I )>D^ YTp0L3b@29T];u>w>QcpЖ-W$[ǧUt1  9DʻGIg^-.;iԜ @ @{}3q"УfFi(AW\qHM¯y FcvqwVWGa{駷(r6ߪ0GږqsG3^(o\&ފiCG<_^`0!UI_UdU]5GP2Ng<~^It4+{AhNBиe = Z$HUPп?u }7p~g˖駵W+LdI5WJݻSѹsj?/2wflڶ [r^͆[:+et:cQЖLFym8,e1tڕNӱ];ڗӱSY[R\k2r8Lc(#G=r#Gػ?{`߁T8}ؾk[w J3h\9+/sǥ(w |>pȥ+W(SBs}qsq{2a?P\?bw?ʧUeY27(WhPKhze5n7U^I4װOxeu^_Õ(SNs QsQ~tLBeGPLBltתU{z e5ٗȧYL4ʠ*Kr @8(|dubB~J~>'jr @b rY(VP^~!r/4PvD Al*rW,@yNl*BƠ+ۇOȧʆ>`                              ""\QROPMNKL!!(9:X TTUQROPMNMN} MMR::X TVWTUQROPMNbcBBO tCCd                  &&`XYVWTUQROPMNrEEI}~{{xyvwturropmnkkhifgdeab_`]^[[XYVWTUQROPWX<>XVV#$U_`]^[[XYVWTUQR_`ddi>>XXX$%Uab_`]^[[XYVWTUQRTTd@AZ!YZ%&Udeab_`]^[[XYVWTUS}}{|yyvwtursppmnkliighfgdeab_`]^[[XYVWhiQ))+KKg   2ab      //fhifgdeab_`]^[[XYVW""(|OORBBY^^((Ukkhifgdeab_`]^[[XYBBNuuyBCY_`()Umnkkhifgdeab_`]^[[cctII`            (bb++Xopmnkkhifgdeab_`]^zz}~{{xyvwturropmnkkhifgdeab_`UVn   56jturropmnkkhifgdeabFFY,,VvwturropmnkkhifgdeGGY--VxyvwturropmnkkhifgGGZ..V{{xyvwturropmnkkhi||wwy}~{{xyvwturropmnkkeetQQSwwGG^88[ UU}~{{xyvwturropmnDDN++,wwII_99\TT}~{{xyvwturrop$$)}TxxJJ`:;]TT}~{{xyvwtuRyyKK`<<]UV}~{{xyvwjjl||KK_<<^VW}~{{xyZZgCCT55Qii}~500;&&91KKL AAJtEEQWWjGGg33OrTTUvwXXIIQ $$*((0!".*~***xx##*)]]$$(dyyz==F DDS}~ww>>R 11Ejjv_**1&&##0#007((6"U!!!HHR==RY,,,66>/0>''* bbs::E++3))378E\\s!!#yyznnw&&&((*QTTULLQX$KKLEEI#^iikddio**+QQSvvxttxOOR))+tt 54T~S????(0` WWlk //6PP\ccrll~ll~aarMMZ..5 o##'ppkk~!!'%BBK<>x<=xJKpqmnjkghdeab^_``p}}dd@@T??T>>T==T<?|stpqmnjkghdeabkk}}}55C!!Avwstpqmnjkghdekk}ssu66D""Ayzvwstpqmnjkghaap^^_}}{{yyvvttrrppmmkkiifgddabhi|}yzvwstpqmnjkPP\99: ::L--J  |}yzvwstpqst//6=>P00L|}yzvwst Z>>P11L|}yzvwW>>M11L|}z{pp***%%,11='';+##'n99D **BkNNOhhyee{RRwLLuBBJ  333RR_"|}@@^++0x%%*AAOuuno;;N*rr~t$007))7(Sww++2''2hiPg||hh|ff|wwm`wwhS333..1Q'NNOIIM&o**+((*99:^^_ttv~~~~ssv\\_779nmZY????( @ WV 77?GGSGGS55>"33:{{tt//8&&*z{vw((0.uuvwrrmnhide_`[[VWVWhh|- {{vwrrmnhide_`[[VWQRTU {{vwrrmnhide_`[[VWQRMNxx{{vwrrmnhide_`[[VWQRMNhh|%++. 1/QRMN))1""#42VWQRTU 88;iiYZWWTURROPQQYYDDAA>?<<9:>?[[VWQR//8 X, ++P*_`[[VWVWttUghUUyRRyPPxNNxKLxNNXY>?t<KK>6@[K}GQ/zw+wK||xGr||xxh ||xxx ||xxut||xxuhVN||xxuG[(%xxu@$|xxxwC1-%||xx+vvsssqqqpnnjjjggggk||xxw&I||x#Q&J||xG;$$$$$$$$$Z7||}@^MMMMJJJJJqIFFFFFBBBU|@.#&J".9&J"8C\HHHHDDDDDo====<<<<:L> OH444440000000--------** 9~mmmiiiffffbbbbaaa````]e8.# ,( .@ 2(@ 2(S /(K&!)$z3AE??+@ wlo@8c_ 5VS2WddT0KVz ir { RP }YGGXytSN31[SQQ@#9CQQC9#@@..@??( @      (,0 , (,( 0 ,,,4$0$(0($4$000.2.,4,$8$242.6.444,8,0808888:84<4<<<4@48@84D48D8(P(0T0LLLDPD0X04X4HXHL\L4p48p8DlDbbbddd&  &>>+44*:Z(d`%T)uw&[Rs}~p&r}|q&N]}|RT}|:y}~w:'gVVSSQWjKHHFDX}%h.`:bCCBBAJf<;;76L>#3& ! /+ 0k^^^\YYVSSQOOMKa101 #eIGGEECCBAA??==U+ #4% 2&:4$ 3:i53d)@ 8(9q_\mz>#" nl Ncz -II, v[Ztuos# xP% $Is c]#{&N)ih'N9#00#::#  #:??(       $($%)%()()*)&0&(0(////0/010222";"$;$&;&/8/)<)585+<+1:1-<-4:4C"C"5<58;8)C)+C+>>>(K(BBBCCCDDDEEE$S$=N=9T9.\.2\25]5=^=@^@A`A0g0E`E4h4LkLQmQhhhiiikkklllnnnoooqqqrrr]]mmppqq]]||}}vvZZ__[[||rreejjaajjQQ[[aaddѣmmߐvvջA B> ZtsqpY?+Izieca_`mF,=Jxjhfeca_^hE?|o  ^n@\ws/&%NV"!-_`YByu943SX106a_p{y:75GM218caq}{.(ecs}T usol Lfet?][vuskUhiZA'rDyuCdjz#;QWRoxH>)PgOKbw~J*<']\$=?@PNG  IHDR\rf IDATxw*8HJQAb`5DMl1FhL?c%B{#FsQ1{[fvgfgK||>@OJAdCFdY"1 \!5JCN2W$`408j'?  XfZ,y9qt `9l>#=XʐZsˤzSh|Z#]`7ɱdɸ:@X]#βd)+ z'C,Fudi^C?^a-eM]{d <%~T,+/20"sd)%3$>Cq^,,pٯG[ghIET hW^t֍Ν;ӾC{:t@iߡ=%%%nl6 @jOcǎq0SUUTTTo>v܅l^DM!DKB0[ϗS_E"2\dS~ >L=c*SNigS\\ f[}}=?_Βɇժa, p,[ȦZ"O܍%ǝ̥^Sާ<ʽ5sm[Y0o+WDxҤ (pUk3}NM ̙3ӷ {Yp /d3m BͨU"GRRzz O+?6[ye+~MV={7f`F#}Xfqә5k^t!N3f;\ Kgxb~jX UL,[j܁lӺ^۶mu,n6znr:sO?gSS]$[B'TyqiIii)r wJJJX/ښZΞ_+{vQ gW#o_֢ %}y4s}1vUiIeἅ<ؓlZI՟ FGz%7ɴZ(Dtݠ{oݞ>x /?~ DqqJAB&ٰa.8$6lF#݂ Xo [7mU c܆KWK177]z{oe~G@╡2"5-&7IpI.8pI.ܒ)9F$2/lA|M#l߲]5|Z\ dB-,3_TTw='2 ra]/̩Ÿ([r//S W0|>^K&}D$Ts3^fF:O5C~%XeFRnƌÜp '$g"6#Z_-b[1==(Gg&`zͭYFտN .OfEhrp&Yb޼yq["@^$hf2GxTP!_O" ЭC\~ՊT鐄,r<ڌxggWOE 5D]SZᏼl` [AxQaOo9 ~){LFn.1#23D>#e1o<ƎԯV"ܹ ~S/!ށrg ^"}[nFvإN݇|HI(Zw0#ɧO?_~Ij+{~G Z}׉:B{Vt+gU޹[1> "/ʥȽ)kJ"@uMM\k.oΎ;ؾa;Dͱ;^C0 O6yn +ȣm1ГzSZ^H,?_gkzG#zw1y~tH7#T+J|R$x?|LV"%_ w:y' \UWb >}S6݄w[Csn$$<}e´ <'Ɲ9#!Jg=z!x7O#OSqy@  G\.{9M=t7 G͹oݪlHדލln 0κ,ΜJqbyN3鶹@;{;G9qw<_T#JE6ȧVAAigk %>u~E}]vr]~N3q8܎?ҭIMLѻqӥ7Pߐx8((3W*pBL~ u j0ϳy}|>D0flN%w^ŷ_LQ/ BQ$?˹kR<dHe'III Z5O`=Ch\eE%/E>3WNcwL閷֋GЮsGG+?8 T+`YO RJytԉw{#Fh`zQ=79_~^yv{?V<@ !Z ..<4nUvZ.;2WX*Z ; ec | m۶޻5J$qqTT wq^K|ϣA|E/,K.:W r(p)M'ԵϚ̛LO` DWnLG>p_aa!o6r&j/ԉ:U3 ;aI9\OO(;,kG9$C\ChW^0|W\q [oex7A~~>/ӴKMx n>fgT0hQz-x/%hkkFO[n`eJʔ(>@>ː\. ,`NV{xξH?ق^S^|E|^`XV `5[Æ/708άyP~B2|^_ʳG3y@Z)p$ /0c M@ olvZrVkMD }|NcY?}4x`-Ugާ{oDVe\ wNM~"H?قr7Q[]sR@O^'$U*XEW{רIC~c{}Ȉ! I#T"It2MRx_lxn?|>sʛA>؆g @%0VC0y;d IgI"O4'3y|h/Oc?{UIWQ_S),|^ ]] DY~$zT 4|T@s ͌+FՋ~U d ~[t/AU[8z(Ζxdstƃ Ҹ3r;uY,cG όFH2?//w}f_Jӫ` Ȏ;y} 9mC{p(pI_7i_Jo8`458'[kг>˹瞛ԟ/˙fԃOYP0dӊMl6Cnn C箝V֍wc;1yp: /{ oK/~y;6-V<_`'k~BwNT5!ԋzUtwt$`аATۯ |F#PS1?fnVu.t]_/θ*MSAItڑei߆bp57@"(p4xj N;0N5#J`2Cz\xʅ]mxdl1A4&Ǩ/W~iЎдG?z(ӆOH呌sAqԓ8iI >y0tlzܱy|۾d+9~86-MIؖ'|vEY?ٗ!!Qהewn*,AflͳnNGK-"MĊOW}{$Irt9v4λ<y {|G$i8N:{^'\c{{r4+Ks/"ՍȳkSY @^t!oFB?jxlyꁧ2$I؝vt-”p%؎ u|^.9Ρro<)~x^}OGIStM|!u; Bf ح[7V^ej0gu߬c愙sѩ?zGr)rg<ş}S*#-o^C{e)J4jPg>C-??78$3F"7G 5{lFVC ~<֟+n*:t`wع[Kr$I(H7<.'}6-|@:$I[ן-i_ /%W d ?@AaeX< T1s=w*1s?p N>>svh9&=.iϳG' fSnwI۰#+mGὲ (=NM!DUn:nj8ȳm$pH_ڶm˷k{ϵ Zm8!aH$ ׿I&)%*Щ?w>o7O$NQM\!,{sY:%I 7*>}Y ݝɓ4PX\Hm폍 R8f,ˁks} JR:0QA 끛 G3ό`D~9Gٵ?3}{o.hʳ_)B6dj@0d׷2k |WDO:BG (7%E IK?^j8: ]'W 0so`"Wxs ~yocw۴u ;rW>^DvV"y388vSMwDCstv5";WkQs !x8:JNmN9{Y2{I,]1ÑO,ѭz(ش7WXB\ěn瀞\xÅQ59ϸ n^Kv|e7o£WnJ 9s0tl.g—{d?HO'64U O[_]uMIn^q!&WE?Qq/TUMnAjܫݐs΄CeJL_ 67c׎;cB1NE>Z=-`VwwQ^~ZeѨʮLtiӆo^]-Q+4V87p&emssjL-&33U>YgjjoS+ !]9J&?KASybf}ڶUj _+S&߻k/\xvŴ䕩/r)n%VSY=MC:۷kZTԦnLG)D)) @"wzrF" [q5C2*K.BгN0(gt9+56Z+gyHٳgDD.t/شô+s&&N_ ?=8\,lL)>>žDltٝS8Hd.04w' ŗʔNnj$I4Z~~`ФAMkq`yT~Nnd5D @)0Qݺv9u- ~`ӚM-iy} }Lk,AoC&ͷ-j^b 6ںKGI$VI ׊\8 IDAT.;VTŶ yt"wV@;\t8$I\k_ ³BEZ]H=_+?K_(jH1C7x7O3`fz GKcOK߾Zy/ŠfЦrj eCLg3*WxD 2jhԩp .DPZr~֚ow)XtV ?@Q"S7W%@&yț Νyh 栤iz IϸX5#J#r~Nof_<0GZR7k2ަο?di+|k?Q1,-ey'\W*L)ӧh.űdt8a},}cTi([Ag`tdۛ}_(肁]ϞvvԿdZ'skR33My官[igL5b Ӧ55d5񗦂eCOOZ9:Wj~b4m" IG^5siZ-Қ\?LY7YB\H]~iJ\ϳ.z~'0ɡ?" p >I25R?L5<X)bz$\bE?!~+sTP }͞eyVw,x`DuoxCCC 7Qo~/ʟ:Vq0T­F%*`˥I4:,lH?oßj)RX yVd}p#6'JRz#3EaP+?$ 8M|PkTU`Jt?юdt#O^^^SbrZ= a%Z CyVsJ=[(Sh"4 @5tЄO Pƚ#0l4<+9s,x,abu4K@(zРATI)dkm7ihlԁ@e\k*&[o>y @+pCF/[gޑqs-I\H@УwӤr NzCK11j?"-iPusZ)c/˰5$,6nE9g u.dF @W ρ r[ٮsH[ACCG J [FIs!}u.`}\Z#rEЂR)WD]TD(i_b:0оCU ~KYV.P/5Pht}HPN?RR/ԋWtGʠhg#bP*..NX ܆)6p0JXTVZ[Jr~Ar)cr&&*ae+Wy\)jyp  y{ ]Jdm[F)4hr?-1PFk򯷌|u:gvEڧ5/~ހyh4x&(r!NưSYy,/W5%ElxSPKPB?ADi?Lpr  yhqyCr))M$sUWW'MPl-"͂?q8 ?@$oHQ@pDoʪ+%(->f8pY_ (>XhQItC,T tK=(7ۚ(MGg~&?7֜>3hF3r~<["DqJ8@J-6TeeEٰ,G*k s^5Ur0U/@CŜ D+@2 llhZ|K,\ 5F -D C8)?`-r~!mmmQt{&MP6G{.R+6`D @Pb+ ?A r nwP.ߒ+r[NI`{)6`P $4mz۶m*JXgDUqiU@mvC-@x׭]&:8'oy0%-E?@G$:mF V~6&MD :1#DY+wHpM`mںy+qU[ke\_ 7#ЋIt޶H| M[m ?4-qό̂?ҭ%)eزnKܜ205Xk@2/-bGʂ_]?@gFԦd h#IJ\}q,XT+KOS΃P!Z 2^zbW /oϩ?[1A&^ |,= %$''-#U͟l+^6?Y҈;Fp/O JR妤H՟6/ `2/0.*S ?דf?` MsU/wrK^'^n,GKѩ>3/Ŷ✁?Yz[̀Q./w ?%+d4P(├ )2=i:#rD  I4Ʈ݂EnzhY+W>>O-gZ#7֭m9[KU!! v]ǶxHo/R>YG-ERQxC ,[j9evvtw7mP* 7Y"e,/qcDrs޼v*2ftO2^0ofCd{[̀Q6DxuC XAE}!V}T`;{;=Oo,[Ze<[\%J'Ƚh$E05;2k*O{ 4ʂ_Yق_ 5.QBZ0zUy4GsgkkВQ!fZC2 ZNـ_$g\V|27CTqޒSf)9igoi[l7 ( #\#hck0]d'T4͏g**v5`^&pE空+eQJe2+<+strO(t:*jU$& BtэUWt:2޻ÁQ~ g/o>Շ&ݒ=d4f,-1[f=sI6sUU9oy{P_ x"d!P&YEcἅ\r%qnr/G/hNnw fd`^5%$?3Z;c~/0GG-I2n&|:;:DRU&&OHjt f$VɵuVxi Sk󮧣'ao)J7N?=~h"vla4[QX|?-GVVA>GG{:;,>~3 Τ}^< 'u`ۖm+%*KyԺ KwrԵDi i?gYK)@u>yBac{@ÂߒJ'3fD-rK< ^x< ,)aصcJTL7gRYҦt/*u_F;t1v%x'8B)w㶹̈́jN [ gWUTғ/& 1ᨭ屇M19ߒiJ3gWtߟ8^}h~;!oܗI7ɬe;{BL}}/VWe4k׍4jlA~uׯTװ*&/ER[Fl8pfA?* ؏3_C-˗.AA\bu,+Pm'cϚ/ 5BېR1 Ky4!Jsු̜[2p:]]UTq/:{#yf"#kkmC [GJo)uG#F'GM(5GuFՀ,7okik Z '|_M%ݓIwxEw{k񓑲PУ9qqņOIE^e)I~ tڙOW}JNP A4a>3 ԷP9fm8\wʷsG;hoϸT2:%/*z hR}ۈVŁ nvS#yRC\CY[mظJC !xAq#e7#aB#oN.5"-Qa nME"|͂߂?pA w'Vxo2&@_AHfzP4 pŇ?Z2#ѻȳoV0Xim\1 <~U 04Lz9A2s5x#?ػD[[ 00.8Xi"Y? QȆZ3M%!ޙԋzAٗ f,}o&*0<_XIf/nF7t/БC@>t^JU`Xv{:zrCpI."_|glrZ ܄)j2 RE8$w7?yc:)a9ǂǢ--_(eVY᭽B /r7_o x>H} ]F =q%у³B^Jl(f+i JHz_b ?8i $wSD2 6d3h~ͤ3&ѹdي(sq(A hO HӚMP[]9~ N5=t Go`ppH;!#D]" _ݿ=ʏˆdH..XqO=_[ѪG^G~~s 򼀏qDҦm^Y cƏշo<W> _x="8v0*Z*6|*Qet(hPAawN=TU?Z CMe8<f2ESPOW?xMn#qe|0*a^Fm |V'A>|CV3I 6jGيG IDAT (7 ܇_BbB*NNI+B}YNyӜ+0ys#!_K^57lgp7*MѕnnU\ǘ1q"~__'bFd*};mϽ;6m۬h/ A蕅9)S?TT_kAw)/0Kf@>ifDTڣ^}'L Hy7I(?ف&مgS (>Hi}۩~NKQDj9r_T#ӱKGcдHOgOGm;fYCE_U|F'.hiK~cVdf)[!݃r53y3 ۑ4QI7~~Up=xSO獿ԯ=|zV) [!=I{0_8d)G"P**Y ~ ~~L-J, ۹{ٰڴayJg"4[ Vс@ա*^k1b숸mx%*ٗ^^GGZ$I vfF N+8q*1v:RIfofEz ˀ9+Gt$|ɨf Dk=k݈Gx, gc{ &Pl+UZ@߷ПNyfF5Ʌ@G"Ե޹y= bw=*ؼp)9M6!}Sbh$I\|ⷿS$zVFvv9G?ggu>?@%~IpYFb)^By}{~O?t:UU{RyR%Jl%i&Lc|#_ؽu\a:y17Y ;ߎ!CQ&nرKGf\;Ϥ n;6`>tX5ɪG޼ }-Zyy晙iA9g9\pWsۿ{? >Oΐ lMf@c@X6v8Owq~Z#;7şTçQwgST e#eeL: S&pꙧRئPoKSaղU,x9K/aۆm, p?PDdS-ɬY;q#3q &bI#(j#wW4wkkXV-[ŪX|5^W1SVhhv 4b }/Eزn nb |+ے{-Z8 Y ^g nS֧@A)SF=޻;K;'a`ݹ=;{n5ٽmGgC!Gu2ʒÆòMrҵ{WwjO(i_BIJڗPPT@A6`O:j먫HVjZJ@9ە09͒o>Gݠ,Yң@-هאGkfRU!RlR>~y%%KYTM$!O96D@Ug[( uCW0 ~]V5r]䩺/d^N!if1(wȭ%Ke6IFabwVV'f@~d"7.1Fa`DPX뾪syq@FkNӓokIENDB`(@ R||Q10 rq ~#(#EPEfuf}}{{ctcCOC"("}^ZgZUeUf"AJA`>                              "\"QQOOMMKK!(!9X9TTTQQOOMMMM} MRM:X: T VVTTQQOOMMbbBOB tʾCdC                  &`&XXVVTTQQOOMMɩrEIE}}{{xxvvttrroommkkhhffddaa__]][[XXVVTTQQOOWWX>VV#U#__]][[XXVVTTQQ__did>X>XX$U$aa__]][[XXVVTTQQTdT@Z@!YY%U%ddaa__]][[XXVVTTS}}{{yyvvttrrppmmkkiiggffddaa__]][[XXVVhhQ)+)KgK    2aa       /f/hhffddaa__]][[XXVV"("|OROBYB^^(U(kkhhffddaa__]][[XXBNBuyuBYB__(U(mmkkhhffddaa__]][[ctcI`I            (bb+X+oommkkhhffddaa__]]zz}}{{xxvvttrroommkkhhffddaa__UnU   5j5ttrroommkkhhffddaaFYF,V,vvttrroommkkhhffddGYG-V-xxvvttrroommkkhhffGZG.V.{{xxvvttrroommkkhh||wyw}}{{xxvvttrroommkketeQSQwwG^G8[8  UU}}{{xxvvttrroommDND+,+wwI_I9\9TT}}{{xxvvttrroo$)$}TxxJ`J:]:TT}}{{xxvvttRyyK`K<]<UU}}{{xxvvjlj||K_K<^<VV}}{{xxZgZCTC5Q5ii}}5ٸ0;0&9&ӂ1KLK ٯӐ AJAtEQEWjWGgG3O3̶rTUTvvšXXIQI $*$(0(ڲ؜!.!*~***xx#*#)]]$($dyzy=F= DSD}}ww>R> 1E1jvj_*1*&&#0##ҹ070(6(Γ"U!!!HRH=R=Y,,,6>6/>/'*' bsb:E:+3+)3)7E7\s\!#!yzynwn&&&(*(QTUTLQLX$KLKEIE#^ikidido*+*QSQvxvtxtORO)+)tt 54T~S????(0` WWlk  /6/P\Pcrcl~ll~laraMZM.5.  o#'#ppĭæk~k!'!%BKBx>T>=T=|>ssppmmjjggddaak}k}}5C5!A!vvssppmmjjggddk}ksus6D6"A"yyvvssppmmjjggapa^_^ʢ}}{{yyvvttrrppmmkkiiffddaahh||yyvvssppmmjjP\P9:9 :L:-J-  ||yyvvssppss/6/=P=0L0||yyvvss  Z>P>1L1||yyvvĭW>M>1L1||zzpp***%,%1=1';'+#'#n9D9ߘ  *B*kNONhyhe{eRwRLuLBJBȮ  ā®333R_R"||@^@+0+x%*%AOAuunn;N;*ٖr~rt$ε070)7)˖о(Sww+2+'2'hhνPgĩ||h|hf|fwwŞm`wwhS333ƺ.1.Q'NONĺIMI&o*+*(*(9:9^_^tvt~~~~svs\_\797nmZY????( @ WV 7?7GSGGSG5>5"3:3{{ٿ׷tt/8/&*&zzvv(0(.uuvvrrmmhhdd__[[VVVVh|h- {{vvrrmmhhdd__[[VVQQTT {{vvrrmmhhdd__[[VVQQMMxx{{vvrrmmhhdd__[[VVQQMMh|h%+.+ 1 /QQMM)1)""4"2VVQQTT 8;8iiYYWWTTRROOQQYYDDAA>><<99>>[[VVQQ/8/ X,  +P+*__[[VVVVttUggUyURyRPxPNxNKxKNNXX>t>CGcp 88yyff!!ws[ Q)#Tj{88mmggffggggffggqqoovj._,Wk YYttaa____``````````____^^ee55wi.P T}j mmYYUUVVVVVVVVVVVVVVVVVVVVVVVVTTffCCwjB!PPf[[}}PPMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMLLZZ22uZ1 `rAA~~EECCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCUUs>N URj{{JJ99::::::::::::::::::::::::::::::::::::88``^^xh"CbuGGbb00111111111111111111111111111111111111111177vvu5CZ6emm11''$$ !!&&''QQNNvY k^_i))bb """"""""""""""""""""""""""""""""))gg g`pAABB99^^ n-atNN-- == NN**s5cxQQ== >>00t8dyMM== ::00t8cvGG== ;;''t9dr99$$99 DDp5fil%%88 !!JJk-ye=gDD>>ydOeg|77 99uN#cfjm;; //::??BBDDDDDDEEEEDDDDCCBB>>77++ <<|q*a ghz..DDVV\\\\[[[[[[[[[[[[[[[[[[[[[[[[[[\\\\[[OOBBuZ !egek ==ggrrqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqpp\\((xm:[hioDDuuff//|tOijq 99ss^^&&}t]"ki)jp&&[[GGzub.#kikny $$KKttee<<vr_}2hkempz++2200&& uun[Q# ilkknoqtuuutttsp`R4 'ilm=ohnnnnnmk_f6N?(  $F~TYXO5? Otm--``oonn[[""f0)\rrwweeccccffzzgg}<[oppRRRRRRRRRRRRRRUUmm}/ Ouaa??????????????????BBVVf?bt11;;))((((((((((((((((**II5hDDQQ>>==Qn::jj::[o33kk33\k//OO99//Xg}$$ K~f }..88HHNNOOPPPPOOMMGG33++q$idd||||||||||||||||XX WtilccSS eil}NNlliiFFxfo.k n}qrrrotYAAAAAAAAAAAAAAAAKeePass/Resources/Icons/KeePass.ico0000664000000000000000000017613113062014574016200 0ustar rootroot (00 ~h& M!@@ (B9o00 %a     9 h( @  "" "$DDB" "4DDDDC"DDDDDDDD $DDDDDDDDBDAD $DADB4DDDDDDDDDDC DDAADD #DDAADD2 $DDDDDDDDDDDDB $DDAADDB4DDAADDC DDDDDDDDDDDDDD DDDADDD DDDADDD DDDDDDDDDDDDDD 4DDDADDADDDC $DDDADDADDDB $DDDADDADDDB#DDDADDADDD2DDDADDADDD 4DDADDADDC $DDADDDDBDDDDDD $DDADDBDDDDDDDD "4DDDDC""#DD2" ""   ??( DD 0DDDD3333@0DDD34C3D DAD@D3333D@DD@DADDD@DADDD DA4CDD1D@0DADDD 0(0`  (  8 ( @ $$$H(8( (((@( 0((8((,,,0,,@0(000800@00H00444P8(@80H80888P80h8(@88H@8P@8H@@P@@XH@HHHxH8LHHLLLxP@XPPP@xPHX@pXPXHxXPXH\\\`P`H`Xp```XhXhXxh`h`h`xhhxphpHpppphp`pPxpppXtttxpx`xXxPxpxxxhx`xXxh||Ȁ`X|xpȀh|x`xxȈphȈxȐxpȐxȘ蘀蠀Ƞ蠈ؠ訐بȨĬȰȸļȸȼF++F""F0@JJ<0FlM~D\({(zkgggaaaaq{MqqkkkgggaaaYUPkDvttqqkkkgggaaaYUPPku zxxvttqqkkkgggaaaYUPPPz zzzxxvttqqkkkgggaaaYUPPEqzzzxxvttqqkkkgggaaaYUPPEkufRzzzxxvttqqkkkgggaaaYUPPEqDl!PPEFUPPP{L-#YUPPk(yrrrooiihetvtt^^XTTOOOKIaYUPP{9xvtaaYUPk"Z =xxvaaaYUPD4Hzxx $gaaaYU~FcBBBB???==izzx955555331:ggaaaYqF+" ?zzzgggaaaa+8 ?zzkgggaaa0L`AAAA>;;;;mz2222////,7kkgggaa<WA***)''''''''########/kkkgggaDW%qkkkgggDL%qqkkkgg< 8}ssspppjjjjdddd]]]]SSSNVtqqkkkg0+" &xvttqqkkk+F )!xxvttqqkzF )!zxxvttqqb )!zzxxvttqM  zzzxxvt"%|zzzxxv.CC66zzzx(F{pmzzzF0 nc *zfb)[nnQ'|Mf pw [G ~_DC[}bR.-lbZ\F"8L\\L8"FF++F??( @      (,04 ,$ 0$ ($$0($4($8($0((,,,0,,00,40,80,000<0,400422840P4(444<44@84888D84P80@88X<0D<8<<<X@4pD4pH8PHDtL<L8LLLXLHtL@lPDP<P<\PLtPDP@T<xTHTDxXLXHXLXL\Hx\P\Lx\T\P`P`Lx`X`Tbbbxd\dddpd`dXxd`h\hhhhXl`xlhlX|lhldpdpdtLtttthxPxpxtxxxxTxtxxxl|t|X||||x\txdhlptx|윀위전절줌쨐谜ฬĴȸȼ̼V)  )VV,33( Ql'mg$e/{)d{xvsrnnkk[{xvsrnnkbf|){xvsrnnkb_|)`h{xvsrnnkb_[eb_QkbfQ)aSSNNJKZA>>:5?nkb$t%nnkkgQ^IIGBBDW84421;rnnkV& 0srnn ) # +vsrn, 6p]]\XUUSSNJHECALxvsr}36{xvs3 &jTPPMMIIGBB@@==F{xv. &7!-{x )Q7-{Qz<0m/R 9'O~cUiV&"wo`q.TT*ydl u& Y" T qh&")`/zt)`O&66&QQ&  &Q??(      (%$)&%C()((;("0(&*));*$0*(C*";,&<-)///0//>>g?0]?5T@9hA4NA=BBBCCCDDDEEE^E=^H@`IA`LEkTLmYQg]hhhiiijZk]kkkl[lllnnnn_oooqqqrrrsmupuevqwaxQ{j|v~r~j[|}|admvߤ禍ѯ»ƶʽ˽˾̾G HC%cvrps`"D4U{e^[YSXmL5AWygda^[YSNdJD&o Nn$Fhwr/!BMSX`Hzu:76KR*)-YSs}z;98@E.+0[Yp~}1 ^[q~Z uroj ?a^vDkbxurlOdecG,| Izu<fg{'=]_QoyTC2\tVPiwW3>,kh(AD##FPNG  IHDR\rf IDATxw|8;NlȞdA  )=j-mZ RZ?J %ve%@ !=^c>?uw;Iɶ^}:}ޟ|GgH8j:@?_]6u>n(>T l65QcIʵt ^@ϺN9JGsew@(wf9#O(8 T֠8R8ܫ0 L&y9({ _riPK_`,0 eM"`!ʳG|5ʀiI4<|s*=-5`gnqȼ@8"'O.ޑ=p=?vעtV < T{X_-QXOh;nO#Gi8{\)AY`XQFdZ&7.큣f[ \Vw%%f]ѓ.]бCGڶmGvhۮm۶@qq1n@e" P[ˑ#G8x@}{~NmJ dl@yH%JBw04Ƕ$ЧO_ ̠AY^N=(//sR$I9B$C$lhiP !ؽ{[lfۖlڼ5kVjJ6nXO$bKξFα-4 30xƏuk@7g?͞=Yfj{QZ4qZ8\.'xW_}5gy^>́?vC_E">Cz1p8R+ V1g(CxΧ׺ukzwa(vƜ>SO>FeeEؖ(jfډ:(CNAJKKkɍ?uf؍LW{ ;vd}Z(ӗ5+5Gpʃ6"[5A_`(Ăs}oS䒱*P#=̓4(Dlo+m/" " R):F" I$Wݧ.KK[G•Ǝ/ك_}YyW]cu)rXOסL\@9-W=[= <epY.GD‚`XrDC/x4SD kH 1aKx{%|> WR.F_-YyWe )rH+:@c98Qe7/~7~$4.y($F q0#6>~DO"?O/h\bY_+ 䞻"+*P/F%w @ʠ'+3v\\|%ꫜq}e! AMZPU#H<_(j2 dLe A9=mdhWS7 ٍ&KiFAecePSx p5/,5??￟x/Gkda t tf{0BULυ+Y?@~Ag<={ bDn(ˬ0[{ :!5gygPDPw72(衸s ǵ\Šo,cV7*CeX䤮ΝKNR3 DT׊wك_`Gev *kמ/|)uKBlcm':;(//Gynnw?ԯD r.}A="TU ]x{?*ÉSN7%QZZ-oPXݺucy=:m\ýl ~+qHڵqS^UIf9W\~۶nI!݊HmdOhYh}IW/V&1}Dn;gu`AaaN:3kօ,Koߪ1MPi6]rɥ̙3/D@zȂxZ ٶm7|ǖ-ټa-[Iejk>J P\X#[ӧ z@YޏҲr<_ ە/?I+Q\ѡH'jAn鏘%SGcVd.D'$n]2Y~!Nnְ%|C>M} !~P"|$  Iл Ɵ0c&3pq}Jm=Lp _.,TA;~vpp>ǜ9sKuOnT.>t7^{W?UpI.$I"^@Acs0e,[e]Kb7 ~^z~qӵOBʾ(ӌ2Q(VAASLje T_L@ /=ŧ-QSۉi|>?Hc0ٌ*úsӧ̋p?EoqRkeR0e)(aHL2),,dt>R{}{_qO!zoBABBk[Irzxsэ}+~=G? ǖ)*;`hؒsgRUUrRk 0ؓiFf+P2qdRRR…3n8]S)=b.&r }{yb<# AVW9s-Ϗu޵sOiӶc~J@n^:,7T, =C訕 DȅpLd:t୷fذa'_QԳGVs<&hC#yΏߒ_PS-Nm<Sy@Zr9<뫔ZD m4QV֭y뭷1be8Z+D q%YHE"adYfúoxTڃ9w0B|$݉Сcg&t w^(L[QO27x'ꊟ pDP9b"7oټ~}_/Py.I;`8?ѭG%Ѿ$P귁_- 9-g2JL21lDDєYp!'odC qe3~6R>q 0hLNBi>h]s*ߨt)c1y](26 % |>,X@1CӾ}pJZcwҞի/][0 rU5= nvn&: G/TUV4R׶,Gjx^~LsƄ?zjdiH7^"ncaD">_jj8*L)*wo7ݷ_eXXr曮"aA&/!,K0"gGE(mb&؟hlݺo׬0W1/YY1'2o޼y)Gkg9=wE'e_OJ>)gG?!Ca:9aC%IbɧOa~(q$9Jʦ p=zwޡ8ml=~ʿY?TB2È g {)mN2+]nSNWqaSuUl-0exxͷLOˏ-Sپ߷RaUBA ?!gG/@еv jl gI{LZ~ @v_{zG9Kofnw7 Yn9?/ӥ)z;莎;ӥoaeXU8(OM[oM/vyy=ra,ڣ?z3E]5 <4$?y!ݳ+6T*uFYu3h@|?j(>Syi !%\tԜK ?@IrѾCgKVm)nUBq6a*+Sq ۷!A=^~;fLW_;=3`: yDV\n Ԫf/+2IfKM/ڡk>ȴr~dqz}r֌710pqt-+4^PwlfYxK?G\$E__RT&GeP/}1JT'd"QްtWs&~Gԃ jlҽW+/K>\QI1mq% 82%h횥ڳIIlt8xnelOy׸*虧7k ޵*PBgyJ8GGkWw$I=^:u57IKc>:_'Kr]bpd>Zcw5J>G9?H4¼4p>N9q$/M~fGe[(Sy=S12ix2PHDdpqOR$F_DYqx=>V.YdKb÷_r'L6~BuWF/GfxH.fΜm.ix2AN3}_,x>$?9ϾτNEruڮ| ~5@f4V#6CiWJ>Cs  5.kU~ǰf 6N%4ȍKE3`*𮙄[fUtU3<vL8G3!6n79?ĥr> Da}Nw" yjSaѻLP05Q[ŔRQa4u5L)Az!&M ~F[2+|$z__`?%IlW4\.<}a3l s0L^|R}t#V["ӳKˌe8KM4{_so*ehռ[6m)Crv2|avKcК~H0Pq\t\^_\,.tq|R۪ `֙'KӝIhvrN7p\w@ `/GGpe\.|x&0`8{\-)_|_GdVnVޝk&t&Y6{ 19fħG=];xmYyq{ۜWoP?{B3(/v[Mv[=oS]Ƭk9fyFyhOV;wEEE1/_ygoYvn%F=l۾>C?x|5 }-s(\*qTq# 02'G qWHw'OO᰽?| ٥O[MhA X KrmWrW~ R:ĄiI ITG;޸ 3z 4r}z*&" Aa+71ph.f̺=`r=|+?vk}#~Zp=0`ߨ8嵃avm1|VLuM /q+umvhvG?[W߉km+`ǖUڱ6Gٰ=1ѯν={zbԈ L6dJWez2?yᳰ)v^ޏ3gnG?θ]{rY7gj+wG|>BNKWˍ?j@ߒs/ȹ6g-^[~ լWһ}v? k~‚ JTg}}0V ވz@gLg[y@7,d[¿{i*4%Iʐ= @ރ$:ܿCѰuۃT= H?n6^:ꉨ  ѣfc~P K>5\nk~r{?e6/`7a7"u Ģ.ΥKn鉨H\o?" $a>dA ;tf- ~ 9mtHR(X˚5mOb@rVETW]8 HBGZj峯0?(+~şgD~gκ<2|<!!d|-~_@:).n.z$я~LVچ'?Z3ܱT L~A_8B!QT};l `8)Z**ny^a/-@;,Gu\{v% ~!`o^8A彏Si+_#:vK7SIic˜c[5]:z#gmREHާ:3?" Ba `˦uz}LtZ ە/ѧ^F$Ş7~!aTSCB@ײL<~ QVN.0磌Jؗ ~ n/b+#`ㆵjy(I#Lj US՛NpE߁2qORrGܹ3g:ƪ>_֮!PAƶh;HؚBزlhuԢde~)@{ IDAT3رTgMh2)Y`*p.& Ϟ}^oCt~lۺXePIhSz2ڻkB]%xgͺHW'f& L I$.|vw= l{PUUa>R{-ԵzKښJ[g H"ZGuVR92 i1L=BHfge|\.z_[ ˺G!‘a]S*Pޫ/]*t HV?HT眣<3 ?(~TUU鮇tr=wWԪkm sVUǠ4G7N1KOLOiF Ig=Hë?;/Tn >,\SS|`0GdLyf_Ek2|Fs;v{hؑ~=ѣ$^gM /eUݺT~!;nI$~.]1d(lHiOh?@m?@ ˢk>2- ~!êE0Xk{dD N9Z43qF-Na?{/! RW$鲽Κf 5$I/5F jTNy;G lk9W޺@ D_ rg_:Gmܡ1J0 ={ӽ9:NSPfiJ[U, T-;BGN|H f w:ԆFCaY-h[)IHM~!Vfwt91#`҉wSws'͋UIog!X X%!HR?mOX7Ǎoj23v&L$??_7`ˆ_@ְHxjo}WHq[j/`HÝu!|QM8ӤW@+/b¬@YY#`Ձnc`$<@FGt7^È$C&4C Ie12lVA?Q ȏX0hNѣ㒥?M~/`ECzK$ 5) L ?cN~\tCeȐ:  ng_Gg}钔vrv틎L?@QQ+245$کWƩ :GhmBgrY25`Gejd q% Mэ"1bD!LBWM ~=lK~ D^sǾL:44@ ?475cHI 67k_tfo( ;ÀDi,NjZy#`!n-ذ}8@G^^nxV{%#ii_p˧Aa!`M~,C̾eU&B(?G4Oq 08IHJPn4F  j7YS+5 kRm h^ ?@$:_S3fV2Ĕ/z/F6!q (+뙺BUʫB=EIai0ܴ(o>j$8וa2ď}$ַHn{?A& A2EӔu"VRu<(o{5_P7~!Kt^gM -~_˄]6'%^sv_8rT9D?jH@hʼ<:u`L KAY9Y v?b;k/C0s"R)p*uQOQN] / P!Ɋ!Խ{)/G}).\/d8'=Ik/C0-8DbXs"ħSwB@m B0,y_\.m+K=u76j#Rb3E+x ւ ~I?vG󯨒i_G JKM9.Tw ?@8b_SU-ubl%u*6mMΔh.:~XjgJ?@6h GFVv_46JJ:`upx-;PS+R^񼕴1;uJHI@l:Q˒]j*cN؀@B81dawdgjj5R.٢Vz߅@|>_JcwYHv_1&l4|z c f ]w-WvW l~ sLdH޺ d{';/DTwz ߠ ntul1hy1޳1_M9dɁߑ=eGANWfr@J ?>OG-Nv?湔3]@hP!I:$ac[ PmfJ^)  Ҁ_z%l /wp`0h9m 0zZPxUF1"&O]3ouyck'UXJۣ20j{Bj[x[m4튺-.H?@(ҊN&Z$)+CϐL$]|i򜈄8I2'޿OKA a&[nbհ9(ԶkYf~kN~P0P h+4 p$~r%H$Ɂ?ʜ5-טW|Ĩ޴ CFS8? -[y"ڞŗ!i9a)ωHӒ@A^1 :|@:Nu` R$a0o,x2yfj qyL$~ig^τ(Q2o>੿YTf=.cƞK[O| >s=OmPů<Ѵ'e* B9VG"!j+*-Bnt/>hpa~[-"iAl7'~Ol_F9Ɏ#uqAZaf;mv1nݢ~[ 9 (Ms5σ`-zJ`[7o ?`G|Z#%DssV]E.6j6Mi&Zq݁c-/mMvl3/_h͚U&%Z|>C@Lxd7:kh`w,fhp^jeIIr4_",VxgzGva4o+#B@w:I(۷iߎJhp+SDT$a5G@667Ë;*W5~t ?ukbWXV\~j@:w} Ixu ntf \tP?>%Fz`/J'Czs-B;?l6@g?@Ea~pς,YS@R/[7~_ɷ2L'sg\GաĝSu70b@ï~e3EZN4i_qzͰdQ"7nWt"m)ͭƅ?/űq⍋ ۲y}$+%_^2sy*a__+xVR~nI7_zlQ̥n#z5xA&BlLU7z!$1n`! FWrQ^ ޽{x-=J)vקilEhόo~u a}}_+,z)(=|5Q^&=3O?J.6#9аxܪ1h}WN|?钅iQ_f4=~Cc8c в],bLاP eNr.4WgA9`ܐ<&ڬ+/=$$*0Ċ;4bvYr=ee´j͖ GO81hdŸ (s|b4ӮS}Ok{>ݼ>1~VΘrkdR=j$a?N/6bTs;]6; ~`4d+?ٹ~H3s'5#E a.J\)m(@:%UmJ@UU =,F:=.uQUU%<*FIwuuOjF5lvp9b6cU#b:t==F-ҵe+ +#Y9Zax#64}:BkN:fnj [3f؜*|TLFkzN6sѩņCqޙ,f* ?]tozZ(߹r9&:=:{8\_۾cFA;j*8$8yt!|?f艨`i^'$ӽp8f_:ϟcwԲԘϙʧcZ=ˑO^7)G ۓiurHT;y%KODR'2]8*_}Զϳe:%=ǽxϸ-p"(:N *#1] Kb:,3-#8Mxgcw?йZ;&xI [0ivllhie.juo_. ube~\0sr@-?'Z_:Ma۶-g~_:GQ#rЍ^G7myĉۙ'v:3LsA.t[O*hUf ]y8{R){yc,2z HzH0y;бcg>tw Km@xu-?6̙C 1Zd.~rNkڶjX u^)t>Ι1u =fG-@TwL#nX{kg#VK krO]f~wIp)ŦB8 NEAL37o@N 6"!,ѯy.^" ?N(bh߸^S3$0L}}ߗ~d*Sف_7G0ml~o-=@mؚåUt pL⚚j@}f19' @n>:iX](Ӂ߁ sj|g2}%n:T+`Ϟ߿Moة~2Z6nVƅ˼\4~5kyݷ3n^$xY>I7_ӵk7$IwsB6qw <̞/ }:ckj9p%&&,,Qy >~_: KVrRW_g u^:jŗ\qT c09O*Y @;&j8` ~Gb< $~U3ZO/~(ep O8羁ϟE)! |#U2FÕ3ZSo OuGIGx@+p9:oʦM>l$Ijȕ'!z=n=PS+4/N^A+ !7tan S6@ 8l߭] B0adCGrItPLuиc^]\1>sŃb âgj0%˓Ͼ̔i'_md֠]"~5ap>'"0_p>p@-{ Uc9(3A^^>Ͻr;^ڲ+Ȳ2&1nPܘ~C~rYR% 0 ؜I&z՘dM2/s؉q ŷBA߂/bvb˿ǗNuuT Q:5RՍ @M(Ng o,\S ZIDATةT3N:]ta_E8נ?cܼ8_v?}U7SfbD+:U۶yqޛ lQ,z]-w|/'!`oW/+s42pr@>06LZjs/ƨ77͆po{<3&O+r?ȑRij)JHL+X $B<\7QUV,^Uá !́ߩQZG39z@*Mmơʥ8`L2M+C$<_eWT=K'0#;8(dx[W_~ZN>u:O] Q$ˀ,_e~؁_vt$Seʨu7ֆTڼq-r֮Y#. [ڿYղ-ZK(o2vaG7L3 ].ңԋJ@@o ~IXg扅0Es) ];ݻ눭K*Ve ٽy3/]Dt)寏Ō(4 V$ as1(.~G}K_yVf 5J@tCǿqZ ‹Ȃm|5{ʪ)cׇ#%ֱE鮟gJgZiԔ@ N9 ХKYBX&H-A6~Z8J\ g?TKngv;΢秈eJa~jje*n՚_v.:\.ia4@pRf m RQ-H[8Ǡ^~w꽝 B^y_<[8YUNFUSt(])huƣL u߿`m{lbߑH(MO~ݼtBQ7VÿzR_bRgKhI}E@F}ZtCiF]ʸڛTf-UY2E_G"Ebm\/ЩNm=dno-?q;oN*S-fHSwgS2lkYwל{ݞF?JQZ Tյ2|mHDQ$\W-/''QR覤ȕ8frg~Yy߱}ƤYǀ&j&0hӟ~kfu.7!<<^lI ]C o-|3[Oa]:\ ̓42X@:t̅\W@ʴ J3<ă޵#eR jl5WJnDyJkYb- +nkYw8)ؑxwdu 1+ʌףLPlߡ3ϹY_Ny[6cKOg9x`_ K,U kj) ^(3Oñw,Mκ}~v>X*2˿ZHPzXטͥZ̗Đa9mLᯭf5nkW/童azrGKQZ};qw`x [^0[^uIײtT8Ae{vsVvش[[6YtV6PP&xaK@EMT)5 %(HE$*v/lu6JNC;Q.skfcX+5v;刢!*݆c J)%L1 Ot(u(:}ďAF&}Q `R'3@# D6B@s #_?cLOH *(PvVrVDUAGxG<1ͺ?8۹u:lĀ!dcIENDB`(@ R||Q10 rq ~($#PHEuif}{tgcOFC(#"}^g]ZeYUf"JCAG><!PQKI˻ɻﭖǯOEBV$"!읃omkhfda_][}X{VhĴ*%#vmjòxvtromkhfda_][}X{VyTxQ`ﮗrd_Ǹ}{xvtromkhfda_][}X{VyTxQvO|Xﭗﮗퟄ읂}{xvtromkhfda_][}X{VyTxQvOtMcijּ"*(';ퟄ읂}{xvtromkhfda_][}X{VyTxQvOtMsMĻ*%#T禍ퟄ읂}{xvtromkhfda_][}X{VyTxQvOtMrKuĻR#ﭖ䀹禍ퟄ읂}{xvtromkhfda_][}X{VyTxQvOtMrKjѸ"ﯙﭖ䀹禍ퟄ읂}{xvtromkhfda_][}X{VyTxQvOtMrKjbwpnǸﯙﭖ䀹禍ퟄ읂}{xvtromkhfda_][}X{VyTxQvOtMrKurd_]&$#`G>                              \0"xQvOtMrK朗(#!XA9T-yTxQvOtMsMij} RNMǷXB:T. {VyTxQvOtMbOEB tdLC                              `5&}X{VyTxQvOtMﭗɱrIFEȹ²ﯙﭖ䀹禍ퟄ읂}{xvtromkhfda_][}X{VyTxQvO{WG><4ƶĴ²lSJ9'!ퟄ읂o[""""""""""""k<,][}X{VyTxQvOﮗ0ȹƶĴ²XD>ퟄ읂iVU0#_][}X{VyTxQ_ied˽ʻȹƶĴ²XE>ퟄjXU1$a_][}X{VyTxQĴdXT˽ʻȹƶĴ²ZG@!kYU2%da_][}X{VyTS˽ʻȹƶĴ²ﯙﭖ䀹禍젅蜁}{yvtrpmkigfda_][}X{VhQ+))˽ʻȹƶĴgRK   2$禍ta      f=/hfda_][}X{V(#"|RPO˽ʻȹƶYGB䀹禍o^U3(khfda_][}XNEByvu˽ʻȹYHBﭖ䀹禍p_U4(mkhfda_][tgc˽ʻ`NI            (ﯙﭖ䀹禍sbX6+omkhfda_]z˽ʻȹƶĴ²ﯙﭖ䀹禍ퟄ읂}{xvtromkhfda_n\U   jC5tromkhfdaYKFV7,vtromkhfdYKGV7-xvtromkhfZLGV8.{xvtromkhﭗ|yxw˽ʻȹƶĴ²ﯙﭖ䀹禍ퟄ읂}{xvtromktieSQQw^MGƶĴ²ﯙﭖ䀹[A8 eUퟄ읂}{xvtromɻNGD,++~w_OIȹƶĴ²ﯙﭖ\B9cTퟄ읂}{xvtro)%$}Tx`OJʻȹƶĴ²ﯙ]C:cTퟄ읂}{xvt읃Ry`PK˽ʻȹƶĴ²]D<dUퟄ읂}{xvlkj|_PK˽ʻȹƶĴ²^E<eVퟄ읂}{xg]ZTGC˽ʻȹƶĴ²Q<5ziퟄ읂}좇5ٿ;30˽ʻȹƶĴ²9+&ӗ禍ퟄ읂ò1LKK ٺ˽ʻȹƶĴ²ӡ ꪓ䀹禍ퟄJCAtQHEj\W˽ʻȹƶĴ²gOGO:3ﯙﭖ䀹禍Ǹ̼rUTT{vŪ˽ʻȹƶĴ²dXﯙﭖ䀹禍ﮗQKI *&$0*(ڼ˽ʻȹƶĴ²ث.$!*讚ﯙﭖ䀹禍~***}x*$#˽ʻȹƶ)!g]ﯙﭖ䀹禍ʻ(%$dzyyF@= SHD}ʽöwRC> E61ﯙﭖvmj_1,*&!& 0&#௞#ҿ7106+(Σ"U!!!RJHRB=纫²ǸY,,,>86>4/ȹƶĴ²*(' sfbE=:3-+3,)E;7sb\˽ʻȹƶĴ²Ǹ#!!˽ʻȹƶǹzyy˽wpn&&&*((QUTTQMLX$LKKIFE#^kjiiedo+**SQQxwvxutRPO+))tt 54T~S????(0` WWlk 61/\SPrfc~ql~plreaZQM5/. o'$#tpIJí~pk'"!%KDBǸƸ˽H?<$P0,+³淚sjgda^[_wﯗ.(&N`~urﬕzvspmjgda^[|XzTyRo|mhgf잂|yvspmjgda^[|XzTxQuNmʻ dQ;잂|yvspmjgda^[|XzTxQuNtMʲN$ ±禍잂|yvspmjgda^[|XzTxQuNsKz̴ 'ﮘﬕ禍잂|yvspmjgda^[|XzTxQuNsKowywȹﮘﬕ禍잂|yvspmjgda^[|XzTxQuNsKy|mhs1/.I6/                      F%xQuNsKﭖ/)'ƼB1+?"zTxQuNuNɺMJI̿M93                      I(|XzTxQuNmH?<mļijפ˙ʗʕʓʑ~ʎ{ɍyɋvȉsߗ}잂|̂iˀf~c{az^x[uYtVqTtU[|XzTxQuNj*((ƶijB3.aR잂?$^[|XzTxQp'"!˼ȹƶijB4/cT잂@%a^[|XzTyR~pkY˼ȹƶijoXO=/+=/*<.)<-(<-(<,'<,&<+%<*%ud8&7$6#6#6"6"6!6!6 h=.da^[|XzTﯗíV˼ȹƶijylbj`i^h]f[eYdXbVaTƌy^N\L[JYHXGVEUCTAR@bJgda^[|Xx :87˼ȹƶC61gY禍@'jgda^[`5/._]\˼ȹC62h[ﬕ禍@'mjgda^[[QNurr˼{i`h_f]e\dZbXaW`U_TĐ~ﮘﬕ禍zVIyTGySEyRDxQBxOAxN?xL>xK<^Jpmjgda^̽pd`}}kdTE@TD?TD>TC=TB8S>7S=5R<4R;3R:2R:1R90R8/R7.Q7-Q5,Q5+Q4*|N>spmjgdaǸ}ok~}C85A)!vspmjgdȺ}pkussD96A*"yvspmjgpea_^^ʬ}{yvtrpm}k|iyfxdvah|yvspmj\SP:99 L>:ƶijﮘﬕJ4-  잂|yvsps61/PB=ȹƶijﮘL70잂|yvs轢 ZPB>˼ȹƶijL81잂|yvIJWMB>˼ȹƶijL71잂|ztp***,&%=41˼ȹƶij;,'+禍잂ﬕ'$#nD;9ĸ˼ȹƶij߫ B0*ﬕ禍잂kONNykh{je˼ȹƶijw\RuWLﮘﬕ禍JCBȴ ˼ȹƶij Ēﮘﬕ禍³333_UR"˼ȹƶ|^H@ﮘﬕ禍̽0,+x*%%ODA|uwnN@;* ٧ﮘ±~urt$μ7207-)ˤȹ¾(S|w2-+2*'phŶƶijPgį||mh|lf}wŨ˼ȹƶij̿m`˼ywhS333Ƽ1/.Q'ONNļMJI&o+***((:99_^^vtt~~~vss_]\977nmZY????( @ WV ?97SJGSJG>75":53{ſ׿zt82/*'&ʻﱛzv움0*(.xuvrmhd_[{V|V|mh- ퟄ{vrmhd_[{VxQzT Ƿ禍ퟄ{vrmhd_[{VxQtM힄zx˽ﭖ禍ퟄ{vrmhd_[{VxQtMퟄ|mh%.,+1$ /xQtM1+)"±4'"2{VxQyT ;98²vieYcWaT_R]O`QퟄnYUDRAQ>N[{VxQ82/ X˽ƶ²," ퟄP4+*_[{V|VytUʻƶ²rgy^Uy\RxZPxYNxWK[NjXtL>sK  B S ] hc(0`! % /3  5 =2AMQV*!%n"z-A"$""C#.# >%%%%F%F'5(#G(L):*%U+E+"M,!H,#2-+Y- H.%N.$;/+ K0& D1+F,<=2.J2*# 9'b P7.777 E83\8,999 E;8S<4 m>/Y>6Q?:C;QKA=eA5QA<xB0\B:!KDBfD:REARIEI1## [KESKIeKCkKA&$ !fPH$:/(hVO>1VEVEfK}YJ".mZT^[[p[U%1a\Z14\N76p^X^P(4aaaG@=>fRIFk]cfxtP>c2 7^^7 *>c2*;2f^ O J'ߖll̏'#aLaH#֚2cmmmmmmmggggfgfffff^f^^^^WWJ%HL' '??( @  "%    ! @ 1Ufj$ <)#o+++,,,@,& ;/,A1- } 555A62 888p8& B95  S;3 TD>XD> ^F>TGC XKFaOI"lPFM:T8vTI{UH ,E8~VI&/x[P%0dF\Om]W57_J+6|`W_C.8aNbR1:cK2<eQeRoKfN}f^hUhRiViT8C>HlIlVlNl[nPngcp_HOrRrVcUtUtYvPvXwuxSx^x[b[z]zazl{V{XRY|o}Y}a~f~_\^ȁircޅgfzn~}igo{ߌpmpzotruΔx{ҙ~ڛܜ읂۝쟅埈ߩ䀹٦ﭗح鰜ﰚ屟Ӵ浥㳲а輭彰ƶȹʿʼ.)490# .!::::::::7!!-::: +~M+ ~ȵS! !+ +(  I( Q&"++ \};*$.,+  B0*:1-[5) U7-\8,E84b:,D0Yf:,O4Kg=/`>2[>4g?1`@5_@;eB5 lMC!jRJVHv(2V@W?XEk[V_LaB:;bYyc[eVye^?Bjbn`?J@JsssssvuuuVX{VX[\\yc~ipoƍzoswuȖ{읂䀹ﰚаԷóÿȹG% HG+I^R,-PQOMJ;H+p~~v.+&$!7J; K~~v.Da(6MJ%`~v.E}{+OL Vv.D}~s(8QO/.E}~~A-)'":TQ 2+d|r5(*WTj<((+0Ucb?#[ZWwuf 4igec1 ][Zxwumkge_][yxwNBlh=Cb_]zyxw93ecb_ nzyxw\@>XkgecS FozyxwutqmkgY HF  F(0` I4 z/H*M  U(D! F,1qomkigec`^\~Z|X{VyTwRvPpL WXa9'bN0&N/%N/$N.$M.#M-"M-"M,!M, M+xB0~Z|X{VyTwRvPI1 )5 ?#\~Z|X{VyTwRpL6%?#^\~Z|X{VyTwR+(4##>'>'>&>&>%>%>%>$>$m>/`^\~Z|X{VyTA" |iq:/x`w_u]t[sZqXpVoUnStWc`^\~Z|X{VF%  ?%ec`^\~Z|XF&  ?%gec`^\~ZF&  ?&igec`^\F' &${eycxaw`u^t]s[rZpXw]kigec`^G' v~go ''''''''&\8,mkigec`G'$0!n?'omkigecG(3"?'qomkigeG(  $##fFۻ=>G@ݨﰚﮘﭖ䀹U<3N5,임읂}{ywusG,#LB>1476ﰚﮘﭖ䀹Y?6Q7.젆임읂}{ywuH,#LB?ϯuIF !rѦﰚﮘﭖ䀹Y?7P7/젆임읂}{ywH-$LC@˽RC>\IC±ﰚﮘﭖZ@8O7/젆임읂}{yH-$LC@[KFTE?ó±ﰚﮘR;3Y>5젆임읂}{H.%LDAn\V=2.ŵó±ﰚ:*%kKA젆임읂}H.&LDArk ڱŵó±՞ ^R젆임읂H/&LEBں lYRƷŵó±eKC Ԙ젆임읂H/'LECD:6Ʒŵó±w D1+ﭖ䀹젆임H0'LEC"Ʒŵó±y!}mﮘﭖ䀹젆H0(LFDRFBhVOدŵó±էfPH R=6ﰚﮘﭖ䀹H1)LGEƼ4-* ;/,P@;P@;;/+ 5(#⫘ﰚﮘﭖ䀹H1*HBAѴ5-+5($Μﰚﮘﭖ䀹C.'0-,ƼSFBTA;屠ﰚﮘﭖ䀹-E;8  E83|ﰚﮘﭖ䀹㠉ܻrkp^X\LG[LFp[Unfڱó±ﰚﮘﭖ䀹k]$""˽ʻȹƷŵó±ﰚﮘ訒!K^YX˽ʻȹƷŵó±ﰚ_E<Ha\Z˽ʻȹƷŵó±鮚[C;,$""˽ʻȹƷŵó±毝th"*F0-,JDCSMKSLJSLISKISKHSJGSJGSIFRIERHERHDRGCRFCRFBREAREARD@RD?QC>QC>QB=QBH ~furol $b[.8go @ȁixuro $znﰚﭗ䀹埈{UH~VIbR읂~{xur $57cU٦ﰚﭗ䀹ڛ<)#쟅읂~{xu $аz{㳲ﰚﭗ۝<)#쟅읂~{x $A62حﰚҙ@,&쟅읂~{ $UGCózlS;3쟅읂~ $ngaOIƶó^F>\O쟅읂 $Ӵ ~ƶó|o Δ䀹쟅 $m]W }f^輭ó浥|`W lPFﰚﭗ䀹 $B95;/,;/+ A1-鰜ﰚﭗ䀹 $ʿXKFXD>屟ﰚﭗ䀹 TGCTD>}ﰚﭗ䀹ܜwu彰ȹƶóﰚﭗvTIrʼȹƶóro wuʼȹƶóߩx[P$$$$$$$$$$$$$$$$$$$$ qp(0   T lG]I[FYCW@U=S;O7{?+& T/8(0imie`\|XyTsN[.dl , [W]I[FYCW@[B|XyTsN& 09 ,(4#{ \|XyT{?+  ,(4TCR@O>N)3+'3%,-&3#3"3!3 L0&qmiWB '3HP?-5C.'C-&C,%B+#Z:.uqmYDna'1"I#yuq[Gﰚﭖp`B7tNB읂}yu^J}p35 "&j⯭ﰚﭖo`/ 젆읂}y`L2*&tﰚpa1"젆읂}bOG;8h`ó|[OF2+젆읂dQmfܳóڤ\P젆fU·6-*ó4)%ܢﭖhW +# +" uﰚﭖiY}¦D:6D51ﰚﭖYL1..ѱ~ҫóﰚ- oigʻƷóiMD 1..}}zwu}qe[.# (( 4~  N24*.4$,H5xbw[sWpRmNhHP6-2v|fGnid_~ZzUtN-w|#  )   J)~ZzUP6 #=-qF7pD5pB3S>_~ZhI2:# A&d_nO &0#1)sK=sI:sG8WDidqS #uw]A( nitWS mLLrM@rK?rJ<\Jsnx\JG$fmOD,$xs{`ӵi`ﰚﬕ]@6eD9읂}xeؼвs ~糭ﰚﬕ)읂}͂iؿ2)& 黬檔 1#읂Άm»]NIvóte\B9Ήr|²~rwﬕόuſwpg\ﰚﬕˌwPC@##P@:ﰚﬕsb310˽Ǹóꭗ0"5310ĿľֺֽշԳӰӬөҦΟ~q0$ 354(  v &      VXpo~ic\{VaB( vg?1g=/f:,W?{VaBX[?JO4K\8,[5)V@\{V?JIb:,c\sw?JD0YU7-U5*XEic @J?B_@;`@5`>2_Loi+!(2QeB5uoԷ:; ﰚ䀹eV[>4읂{uа\VHvﰚlMC"읂{:1-E84óB0*;*$읂yjbbYn`䀹k[V  jRJﰚ䀹ÿye^yc[ﰚƍz.,+ȹóȖ+ KeePass/Resources/Icons/QuadNormal.ico0000664000000000000000000006406613062207124016706 0ustar rootroot00 .h00 %>  B S ] hc(0`    *!&!'",A"$""?#C#/$ >$%%%F%>%F'>' 5(#G(?)!@)!L)G* :*%U+?+$M,!?,&H,#2-+Y-E-%A.'H.%@.(N.$;/+H0'N0&A0+E0*H0)N2(=2.A2-O4*B40N5-E61Q6-777O80S8/\8,E94999J:5S;3E;8J<7K>9m>/Y>6Q?:K@=eA5ZA9QB<xB0KDBfD:_E<REAYF?RIEI1lI=[JDSKIeKClMCfPHmPFpSHmTKVEVE|YMYJmZT^[[p[Ua\Z\Np^X^P^RaaabTeYfRhXh]k\lbnSoUpVpLqYrYrksit[tWtNt]thv^vQw`wdw]xbxayfzU{e|g}m}Y}j\]m`ƄncrywΆltey‡tvg|͉r‰vyjËyɌwΌvnÎ|ϏyÐ~rĐĒuГ~ĔwДՔŔy˖{Ԙ}暁Μ읂՞임⟉џ㠉젆̡袉է訒⫘䀹ﭖ鮚ﮘد寝ﰚڱ屠Ѵܻ±ŵƷƼɺ˽n nDD 6<>>:::777733000000''''""""  tyX DTy%?O+ny nd@@@@<>>>::::7733300000''''QX/y5 =`///--((&&&&&!!!!! JEݼ~~{xwvH4>E4>H9AHɺˢ~zzIVYBI;A!I;A!I}aaaa```____rYSSSSNNNNNcMuuuussspppppoollljjjjeeebcq#M;!#M;!#ME.#M̰ҧ)MPVF<þ)PPZKA)MUZK@þ.RPZOA.RZUFK.Rh8$].R| m2Rf\2RC 52R2RU f^ L6R*1PP16R*,*UPG C |kZZhutgngTDiO? ق *R[[[[[[[WWWWUWUUUUUPUPPPPLL= ?Dnn??( @     ! #$<)#;*$+++,,,@,&;/+;/,<1-A1-555A62888p8&B95S;3TD>XD>^F>TGCXKFaOIlPFT8vTI{UH~VIYIx[P\O]Nm]W_J|`WaNbR~cZcKeQeRfN}f^g^gThVhRiVlIlVlNl[nXnPngn]p_qarRrVrctUtctYtbufvPvXvdwmwiwuxdxSx^x[xgygybykyjz]zizaznzl{V{X|m|o}j}Y}a~n~q~f~_\Ѐe^tȁiƂjrvЃhxcDŽnхkޅgчmfɈq~щp}iߌpmҍuӏyrӒ|uʓԔ~ΔʕxԖ{ҙ˙~ڛ̛ܜ읂۝쟅͟埈͡ΥШ먒ީߩ嫖䀹ﭗح߯鰜ﰚ䰞ಢӴ浥鵤踧輭彰ƶȹʿʼ '~yqoidW>u~yqoidWP&+}{wppj_YQKHedWP@idW>CqidW kk``ZRNVzt\B??<<74nqqid *Iyqoi *M~yqo b]TOOJGh;;5511/|~yq -X~y -a~ xvrrlff^`[LFEAA=:6 m ¤s S93()2    "c D$!, ȴg .80%   # Ȑ"  Uƿ'uU+(    ( ""+ ;*$.,+B0*:1-U5*[5)E84V9.\9-b:,f:,g=/U>5[>4a>2g?1\?5`@5UA9aA8eB5hB5]B9iF:iG<iJ?]JDeMDlMCjRJiTMV@W?nXPXEk[V_LaBbYyc[dUeVye^jbn`qcssssithueuuuwg{V{f|p}j\m\yci̊uƍzouȖ{읂䀹ﰚóÿȹ<<< IRQONKJGFD>/<MT;#"!!*>/VU7 )D>XV%2?FBZX:AH,GF]Z@%%%=C.JG^](KJ_^]$9VUTS3ONK`_^+XVUT&QONa`_ ZXVU RQOba`E5YW06SRQcba`-'UTSR[cba`P41LXVUTI8 \cba`_^]ZXVM <88(0` IH*(D,F0)O6-O5-O5,O4+O4*N3*N3)N2(N1(N1'N0&N0&N/%N/$N.$M.#M-"M-"M,!M, M+M+M*M)M)L(C#*C*!k\⟉젆임읂}{ywusqomkigec`^\~Z|X{VyTwRpLI1 )[B:訒䀹젆임읂}{ywusqomkigec`^\~Z|X{VyTwRvPpLU+JXB:ﰚﮘﭖ䀹젆임읂}{ywusqomkigec`^\~Z|X{VyTwRvPtNY-H"鮚ﰚﮘﭖ䀹젆임읂}{ywusqomkigec`^\~Z|X{VyTwRvPpL thﰚﮘﭖ|YMO81O80O7/O7/O6.O6-O5-O5,O4+O4*N3*N3)N2(N1(N1'N0&N0&N/%N/$N.$M.#M-"M-"M,!M, M+xB0~Z|X{VyTwRvPI1寝ﰚﮘA/)?#\~Z|X{VyTwRpL/$ ﰚA/)?#^\~Z|X{VyTwR+E61pSH@.)@.(@.'?-'?-&?,&?,%?+%?+$?+$?*#?*#?)"?)!?)!?( >' >'>'>&>&>%>%>%>$>$m>/`^\~Z|X{VyTA"J:5˖ywvtsqonl~k}i暁읂}Άlybx`w_u]t[sZqXpVoUnStWc`^\~Z|X{VF%J;6A0+Όu임읂R5,?%ec`^\~Z|XF&J;6A1,ύw젆임읂R6,?%gec`^\~ZF&J<7±A1,Ϗy젆임R7-?&igec`^\F'J<7ó±џŔĔĒĐÐ~Î|ÍzËyŠw‰u‡t袉젆͉r|g{eycxaw`u^t]s[rZpXw]kigec`^G'K=8ŵó±[F?"""""""""""ՔlI='''''''''&\8,mkigec`G'K=9Ʒŵó±A3.Г~S8/?'omkigecG(K>9ȹƷŵó±A3.ДS90?'qomkigeG(K>:ʻȹƷŵó±sinVNnUMnULnTKnSJmRImQHmQGmPFmOEmODߠhXfF˽ʻȹƷO@;XF?ﰚﮘﭖ䀹U<3N5,임읂}{ywusG,#LB>˽ʻȹRB>[IBﰚﮘﭖ䀹Y?6Q7.젆임읂}{ywuH,#LB?˽ʻRC>\ICﰚﮘﭖ䀹Y?7P7/젆임읂}{ywH-$LC@˽RC>\IC±ﰚﮘﭖZ@8O7/젆임읂}{yH-$LC@[KFTE?ó±ﰚﮘR;3Y>5젆임읂}{H.%LDAn\V=2.ŵó±ﰚ:*%kKA젆임읂}H.&LDArk ڱŵó±՞ ^R젆임읂H/&LEBں lYRƷŵó±eKC Ԙ젆임읂H/'LECD:6Ʒŵó±w D1+ﭖ䀹젆임H0'LEC"Ʒŵó±y!}mﮘﭖ䀹젆H0(LFDRFBhVOدŵó±էfPH R=6ﰚﮘﭖ䀹H1)LGEƼ4-* ;/,P@;P@;;/+ 5(#⫘ﰚﮘﭖ䀹H1*HBAѴ5-+5($Μﰚﮘﭖ䀹C.'0-,ƼSFBTA;屠ﰚﮘﭖ䀹-E;8  E83|ﰚﮘﭖ䀹㠉ܻrkp^X\LG[LFp[Unfڱó±ﰚﮘﭖ䀹k]$""˽ʻȹƷŵó±ﰚﮘ訒!K^YX˽ʻȹƷŵó±ﰚ_E<Ha\Z˽ʻȹƷŵó±鮚[C;,$""˽ʻȹƷŵó±毝th"*F0-,JDCSMKSLJSLISKISKHSJGSJGSIFRIERHERHDRGCRFCRFBREAREARD@RD?QC>QC>QB=QB\O쟅읂 #Ӵ ~ƶó|o Δ䀹쟅 #m]W }f^輭ó浥|`W lPFﰚﭗ䀹 #B95;/,;/+ A1-鰜ﰚﭗ䀹 #ʿXKFXD>屟ﰚﭗ䀹 TGCTD>}ﰚﭗ䀹ܜwu彰ȹƶóﰚﭗvTIrʼȹƶóro wuʼȹƶóߩx[P$$$$$$$$$$$$$$$$$$$$ qp(0 - ZMk[kYiWfSdQbN`K]I[FYCW@U=S;O7{?+& iMD젆읂}yuqmie`\|XyTsN[..#ﰚﭖyho_m\kYiWfSdQbN`K]I[FYCW@[B|XyTsN& eZﰚ  \|XyT{?+zom`aU`R^P\NZLcRaOXFTCR@O>NzƷóQ?97*&7)%7)$6(#6'"㡋U:13#3"3!3 L0&qmiWB}ʻƷó]JCD50D5/D3.D3-C2+C1*C0)C/(C.'C-&C,%B+#Z:.uqmYDʻƷ$#yuq[GʻƷv_WbNGﰚﭖp`B7tNB읂}yu^Jʻ0&$sﰚﭖo`/ 젆읂}y`L2*&tﰚpa1"젆읂}bOG;8h`ó|[OF2+젆읂dQmfܳóڤ\P젆fU·6-*ó4)%ܢﭖhW +# +" uﰚﭖiY}¦D:6D51ﰚﭖYL1..ѱ~ҫóﰚ- oigʻƷóiMD 1..}}zwu}qe[.# (( 4240"sbʌv͋u͈q̅lˁh~dz_w[sWpRmNhHP6-20$ ꭗﬕ읂}xsnid_~ZzUtN-~qﰚM70          J)~ZzUP6Ϡn`sRGrPErNBrL@zPC{PBqH:qF7pD5pB3S>_~ZhIԧC2,}iA&d_nOիqeuXMtVKtTHtRFϏz랄sM@sK=sI:sG8WDidqSծóC4/p衈A( nitWֲǸówlv[RuZPtWMtUK_R`RrOCrM@rK?rJ<\Jsnx\ֵ˽ǸG94D,$xs{`׹˽ǸgSL_KDﰚﬕ]@6eD9읂}xeؼ˽)!ﰚﬕ)읂}͂iؿ2)& 黬檔 1#읂Άm»]NIvóte\B9Ήr|²~rwﬕόuſwpg\ﰚﬕˌwPC@##P@:ﰚﬕsb310˽Ǹóꭗ0"5310ĿľֺֽշԳӰӬөҦΟ~q0$ 354(            + ƍz읂{uoic\{VaB( ȖﰚueiJ?iG2_Loi ȹiTMeB5uo ȹ]JDsiﰚ䀹eV[>4읂{u "nXPﰚlMC"읂{ :1-E84óB0*;*$읂 yjbbYn`䀹 k[V  jRJﰚ䀹ÿye^yc[ﰚƍz.,+ȹóȖ+ KeePass/Resources/Images/0000775000000000000000000000000013147553650014301 5ustar rootrootKeePass/Resources/Images/B19x07_3BlackDots.png0000664000000000000000000000015012365136206017701 0ustar rootrootPNG  IHDRvA/IDAT(c?#0FFF@1F!K + Y|pF0oPrIIENDB`KeePass/Resources/Images/B16x16_Imp_KeePassX.png0000664000000000000000000000161412666320050020237 0ustar rootrootPNG  IHDRaSIDAT8}oL?q@rCYV"a,q4.<@9AX4uI-EL\ )[V52D=px}||< \Da2]$%')Ȉa0y)]nH6oĒIO'3uݝ gb Vc9uM,fo2<̗cg9v0rZ7 Gİa}*.N317փ]*`m4B[)TYfttU{>;Tb;KH̺!s/4 B`O䒿.ߺȹxjX5 RDl6VLRT('? n|jTinlQ0":JD J ~e앎}AOe[g7r2x[\2%NxIMn<`b|B<թP+f^Y$[G`O_7Vԇ|CScmmj? s9lqWLQax,[Cmmi8 ηHu{\3ogڰ _"M"*zŧЃ:?Jww7G  Oe>IgW H #}hiP 91OeA)y{O_ VMTj*_&]ő져#ռrq?18LNNbOJJ7EÑP-A~h4FP4M@LL Nik;ᕡ!t]`pFj>IENDB`KeePass/Resources/Images/B16x16_FontUnderline.png0000664000000000000000000000015312231156750020522 0ustar rootrootPNG  IHDRa2IDAT8c@df000GƸB\G `{\iq .FB❐IENDB`KeePass/Resources/Images/B16x16_KeePass.png0000664000000000000000000000146712666320134017313 0ustar rootrootPNG  IHDRaIDAT8}Mh\uyf|؆13 uR!h4q, ;7BP5`(! Lc.DJմJ1D3ZhI3{o 腳;\\zn^,+JکTmYV?d2G˅bYK,|cޖλv(`0q*͊*_y}2vƖa'49RYɟ+rpu5.7om+^+xGFFKr;[z^zL&l*vz^m {_xE'm9>*O282'CGWTY:R@[xgPIz|/eOph47ߐԘ8niNOSs ={FkP"h 5WH?iaoN""/7%7(HN(\Oӟ2jy_'4AYM(% -8^Vgo'&&niLއi qPv\P@JC$ր fΎSxl븣S:22ZM-DŸ axÍs߶]隵. tH73k9T#j:1|^ |[vpp،CqfP< l;?{hKNv?+3wv?L}3 m@.lN$W7'@Jg繏DBIENDB`KeePass/Resources/Images/B16x16_WinFavs.png0000664000000000000000000000107012666320226017325 0ustar rootrootPNG  IHDRaIDAT8˕MKTa(fM3CXwAA@WM\A!ZJe9Ә9xァؐ4#xgyyB\~s[ ^=-8?.ɣXch)+3ГPt_-LjSD(T?oҝL_;?_4lCN0;t  b,D|]XXzGbShBϩbgistD= *O tFBPAmT=I |~vCNb+m- bAʉ;J վ} l>x6r qܐ\!{q#g@C4yORK5K]zM7^V$A\pp]p]&O[Q*Y_bjeA@WE|m>sKv]#'kDS+Q+6GpK2dho<J|b ߫G;3nլ=@1"fc?&G$|~JYIENDB`KeePass/Resources/Images/B16x16_FontBold.png0000664000000000000000000000023412231156750017455 0ustar rootrootPNG  IHDRacIDAT8c@df0džϜ9?AN:$}v0!& ++KYYX)]@r=rX8 ͼ 鍦QIENDB`KeePass/Resources/Images/B16x16_MenuRadio.png0000664000000000000000000000052612666320176017644 0ustar rootrootPNG  IHDRaIDAT8哽JQ{w ft b-[-,,lWIv"Xhi4ܻw샰B O9 saT143O(: 16ik{=I]5b,*]ɱԜЊ)sGIrax@Qh-~0ۂX~Y0ac=6% 1gq 6L6_`Abj&F6԰B0WTp( Ao^)-l-vQ(n]o ~uIENDB`KeePass/Resources/Images/B16x16_LockWorkspace.png0000664000000000000000000000127012666320150020515 0ustar rootrootPNG  IHDRaIDAT8mKHTQw8e{^$0鱨A4Q`IAA$$l!QKE(%YDIq " v%FMzH9;sϿ\Mxr;3x vhF "`' XV_(УjWh,Vzbm#wn^qscbu>q(ū<d(/+D86!Z2΋/n=zñmtgM$2|ʯr]=v͌ vN3<~Ϭ2HN{ܸ3GwiÙ#ij+cd%9mjc$'ϊ "( kXU(G,fEU1SSU97u`zD?݉~`fmkiٷDa%O߂hu5^d%JsWvIܗ`2q3nJf!CYAG|R8 R(Gؿs-FC"nSXE(#86 Z/!B!eIr¼;*)˹J%f[&~:ȡPWd/x-2WR/*߾IENDB`KeePass/Resources/Images/B16x16_FontItalic.png0000664000000000000000000000023312231156750020001 0ustar rootrootPNG  IHDRabIDAT8c@d00 Lw܁ku]j*fM~I0͛@$v]yiIFPhlti`wlq? xәIENDB`KeePass/Resources/Images/B16x16_Transparent.png0000664000000000000000000000012512666320212020244 0ustar rootrootPNG  IHDRaIDAT8c?%B0j c=AIENDB`KeePass/Resources/Images/B16x16_FontStrikeout.png0000664000000000000000000000017012231156750020565 0ustar rootrootPNG  IHDRa?IDAT8c@d000ah5bl. abkpj"&bsH6h}IENDB`KeePass/Resources/Images/B16x16_MenuCheck.png0000664000000000000000000000041512666320164017615 0ustar rootrootPNG  IHDRaIDAT8œ aY/A(Z f]|l>U64ZE+(X ȲkU]o|g0bN)/T}/:%D$}@d2mZT*1=(~vуW9,Um @N21_K@8UeqeF0=6^qw0zx > $ƴ(zt^uNDxh>@IENDB`KeePass/Resources/Images/B48x35_WritingHand.png0000664000000000000000000000235113147553472020205 0ustar rootrootPNG  IHDR0#@IDATX՘kUUM:jB$'9IÔ **凌LCAD}h3!DLj^~$Ik2W_vs\g{kN_XՀcۀQx0[y כs3`z2S; x x[-|W`}V{+߀] D5XWB󀏁Jya(p/4)7eg`Fͱ -)0lš្ oCGcV~*ZNPuzx:ۀ)^B<^@ Xާ /z1 l7J3Vj<]ʗEiAdYJA+A)/)Ʀ9, sbG i}_+ 0V3IJ0KÄӇjU O?4kn$0X(HP N45 NѠoU%jzR 2r,`?Dpw>l6`7 a1-sWNGx\="9U9-Mܽ̆ - ߭9`D=P5IUkfEu}^KFFBUM]>L >.wnt?dw`Jb]tIENDB`KeePass/Resources/KPRes.Generated.cs0000664000000000000000000121314113222750172016277 0ustar rootroot// This is a generated file! // Do not edit manually, changes will be overwritten. using System; using System.Collections.Generic; namespace KeePass.Resources { /// /// A strongly-typed resource class, for looking up localized strings, etc. /// public static class KPRes { private static string TryGetEx(Dictionary dictNew, string strName, string strDefault) { string strTemp; if(dictNew.TryGetValue(strName, out strTemp)) return strTemp; return strDefault; } public static void SetTranslatedStrings(Dictionary dictNew) { if(dictNew == null) throw new ArgumentNullException("dictNew"); m_strAbort = TryGetEx(dictNew, "Abort", m_strAbort); m_strAbortTrigger = TryGetEx(dictNew, "AbortTrigger", m_strAbortTrigger); m_strAction = TryGetEx(dictNew, "Action", m_strAction); m_strActivateDatabaseTab = TryGetEx(dictNew, "ActivateDatabaseTab", m_strActivateDatabaseTab); m_strActive = TryGetEx(dictNew, "Active", m_strActive); m_strAddEntry = TryGetEx(dictNew, "AddEntry", m_strAddEntry); m_strAddEntryDesc = TryGetEx(dictNew, "AddEntryDesc", m_strAddEntryDesc); m_strAddGroup = TryGetEx(dictNew, "AddGroup", m_strAddGroup); m_strAddGroupDesc = TryGetEx(dictNew, "AddGroupDesc", m_strAddGroupDesc); m_strAddStringField = TryGetEx(dictNew, "AddStringField", m_strAddStringField); m_strAddStringFieldDesc = TryGetEx(dictNew, "AddStringFieldDesc", m_strAddStringFieldDesc); m_strAdvanced = TryGetEx(dictNew, "Advanced", m_strAdvanced); m_strAfterDatabaseOpen = TryGetEx(dictNew, "AfterDatabaseOpen", m_strAfterDatabaseOpen); m_strAlignCenter = TryGetEx(dictNew, "AlignCenter", m_strAlignCenter); m_strAlignLeft = TryGetEx(dictNew, "AlignLeft", m_strAlignLeft); m_strAlignRight = TryGetEx(dictNew, "AlignRight", m_strAlignRight); m_strAll = TryGetEx(dictNew, "All", m_strAll); m_strAllEntriesTitle = TryGetEx(dictNew, "AllEntriesTitle", m_strAllEntriesTitle); m_strAllFiles = TryGetEx(dictNew, "AllFiles", m_strAllFiles); m_strAllSupportedFiles = TryGetEx(dictNew, "AllSupportedFiles", m_strAllSupportedFiles); m_strAlternatingBgColors = TryGetEx(dictNew, "AlternatingBgColors", m_strAlternatingBgColors); m_strApplication = TryGetEx(dictNew, "Application", m_strApplication); m_strApplicationExit = TryGetEx(dictNew, "ApplicationExit", m_strApplicationExit); m_strApplicationInitialized = TryGetEx(dictNew, "ApplicationInitialized", m_strApplicationInitialized); m_strApplicationStarted = TryGetEx(dictNew, "ApplicationStarted", m_strApplicationStarted); m_strArguments = TryGetEx(dictNew, "Arguments", m_strArguments); m_strAscending = TryGetEx(dictNew, "Ascending", m_strAscending); m_strAskContinue = TryGetEx(dictNew, "AskContinue", m_strAskContinue); m_strAsterisks = TryGetEx(dictNew, "Asterisks", m_strAsterisks); m_strAttachedExistsAlready = TryGetEx(dictNew, "AttachedExistsAlready", m_strAttachedExistsAlready); m_strAttachExtDiscardDesc = TryGetEx(dictNew, "AttachExtDiscardDesc", m_strAttachExtDiscardDesc); m_strAttachExtImportDesc = TryGetEx(dictNew, "AttachExtImportDesc", m_strAttachExtImportDesc); m_strAttachExtOpened = TryGetEx(dictNew, "AttachExtOpened", m_strAttachExtOpened); m_strAttachExtOpenedPost = TryGetEx(dictNew, "AttachExtOpenedPost", m_strAttachExtOpenedPost); m_strAttachExtSecDel = TryGetEx(dictNew, "AttachExtSecDel", m_strAttachExtSecDel); m_strAttachFailed = TryGetEx(dictNew, "AttachFailed", m_strAttachFailed); m_strAttachFiles = TryGetEx(dictNew, "AttachFiles", m_strAttachFiles); m_strAttachments = TryGetEx(dictNew, "Attachments", m_strAttachments); m_strAttachmentSave = TryGetEx(dictNew, "AttachmentSave", m_strAttachmentSave); m_strAttachmentsSave = TryGetEx(dictNew, "AttachmentsSave", m_strAttachmentsSave); m_strAttachNewRename = TryGetEx(dictNew, "AttachNewRename", m_strAttachNewRename); m_strAttachNewRenameRemarks0 = TryGetEx(dictNew, "AttachNewRenameRemarks0", m_strAttachNewRenameRemarks0); m_strAttachNewRenameRemarks1 = TryGetEx(dictNew, "AttachNewRenameRemarks1", m_strAttachNewRenameRemarks1); m_strAttachNewRenameRemarks2 = TryGetEx(dictNew, "AttachNewRenameRemarks2", m_strAttachNewRenameRemarks2); m_strAuthor = TryGetEx(dictNew, "Author", m_strAuthor); m_strAuto = TryGetEx(dictNew, "Auto", m_strAuto); m_strAutoCreateNew = TryGetEx(dictNew, "AutoCreateNew", m_strAutoCreateNew); m_strAutoGeneratedPasswordSettings = TryGetEx(dictNew, "AutoGeneratedPasswordSettings", m_strAutoGeneratedPasswordSettings); m_strAutoRememberOpenLastFile = TryGetEx(dictNew, "AutoRememberOpenLastFile", m_strAutoRememberOpenLastFile); m_strAutoSaveAtExit = TryGetEx(dictNew, "AutoSaveAtExit", m_strAutoSaveAtExit); m_strAutoShowExpiredEntries = TryGetEx(dictNew, "AutoShowExpiredEntries", m_strAutoShowExpiredEntries); m_strAutoShowSoonToExpireEntries = TryGetEx(dictNew, "AutoShowSoonToExpireEntries", m_strAutoShowSoonToExpireEntries); m_strAutoType = TryGetEx(dictNew, "AutoType", m_strAutoType); m_strAutoTypeAbortedOnWindow = TryGetEx(dictNew, "AutoTypeAbortedOnWindow", m_strAutoTypeAbortedOnWindow); m_strAutoTypeAlwaysShowSelDialog = TryGetEx(dictNew, "AutoTypeAlwaysShowSelDialog", m_strAutoTypeAlwaysShowSelDialog); m_strAutoTypeCancelOnTitleChange = TryGetEx(dictNew, "AutoTypeCancelOnTitleChange", m_strAutoTypeCancelOnTitleChange); m_strAutoTypeCancelOnWindowChange = TryGetEx(dictNew, "AutoTypeCancelOnWindowChange", m_strAutoTypeCancelOnWindowChange); m_strAutoTypeEntrySelection = TryGetEx(dictNew, "AutoTypeEntrySelection", m_strAutoTypeEntrySelection); m_strAutoTypeEntrySelectionDescLong2 = TryGetEx(dictNew, "AutoTypeEntrySelectionDescLong2", m_strAutoTypeEntrySelectionDescLong2); m_strAutoTypeEntrySelectionDescShort = TryGetEx(dictNew, "AutoTypeEntrySelectionDescShort", m_strAutoTypeEntrySelectionDescShort); m_strAutoTypeGlobalHint = TryGetEx(dictNew, "AutoTypeGlobalHint", m_strAutoTypeGlobalHint); m_strAutoTypeMatchByTagInTitle = TryGetEx(dictNew, "AutoTypeMatchByTagInTitle", m_strAutoTypeMatchByTagInTitle); m_strAutoTypeMatchByTitle = TryGetEx(dictNew, "AutoTypeMatchByTitle", m_strAutoTypeMatchByTitle); m_strAutoTypeMatchByUrlHostInTitle = TryGetEx(dictNew, "AutoTypeMatchByUrlHostInTitle", m_strAutoTypeMatchByUrlHostInTitle); m_strAutoTypeMatchByUrlInTitle = TryGetEx(dictNew, "AutoTypeMatchByUrlInTitle", m_strAutoTypeMatchByUrlInTitle); m_strAutoTypeObfuscationHint = TryGetEx(dictNew, "AutoTypeObfuscationHint", m_strAutoTypeObfuscationHint); m_strAutoTypePrependInitSeqForIE = TryGetEx(dictNew, "AutoTypePrependInitSeqForIE", m_strAutoTypePrependInitSeqForIE); m_strAutoTypeReleaseAltWithKeyPress = TryGetEx(dictNew, "AutoTypeReleaseAltWithKeyPress", m_strAutoTypeReleaseAltWithKeyPress); m_strAutoTypeSelectedNoEntry = TryGetEx(dictNew, "AutoTypeSelectedNoEntry", m_strAutoTypeSelectedNoEntry); m_strAutoTypeSequenceInvalid = TryGetEx(dictNew, "AutoTypeSequenceInvalid", m_strAutoTypeSequenceInvalid); m_strAutoTypeUnknownPlaceholder = TryGetEx(dictNew, "AutoTypeUnknownPlaceholder", m_strAutoTypeUnknownPlaceholder); m_strAutoTypeXDoToolRequired = TryGetEx(dictNew, "AutoTypeXDoToolRequired", m_strAutoTypeXDoToolRequired); m_strAutoTypeXDoToolRequiredGlobalVer = TryGetEx(dictNew, "AutoTypeXDoToolRequiredGlobalVer", m_strAutoTypeXDoToolRequiredGlobalVer); m_strAvailable = TryGetEx(dictNew, "Available", m_strAvailable); m_strBackgroundColor = TryGetEx(dictNew, "BackgroundColor", m_strBackgroundColor); m_strBackupDatabase = TryGetEx(dictNew, "BackupDatabase", m_strBackupDatabase); m_strBackupFile = TryGetEx(dictNew, "BackupFile", m_strBackupFile); m_strBackupLocation = TryGetEx(dictNew, "BackupLocation", m_strBackupLocation); m_strBinaryNoConv = TryGetEx(dictNew, "BinaryNoConv", m_strBinaryNoConv); m_strBits = TryGetEx(dictNew, "Bits", m_strBits); m_strBitsStc = TryGetEx(dictNew, "BitsStc", m_strBitsStc); m_strBold = TryGetEx(dictNew, "Bold", m_strBold); m_strBothForms = TryGetEx(dictNew, "BothForms", m_strBothForms); m_strBrowser = TryGetEx(dictNew, "Browser", m_strBrowser); m_strBuiltIn = TryGetEx(dictNew, "BuiltIn", m_strBuiltIn); m_strBuiltInU = TryGetEx(dictNew, "BuiltInU", m_strBuiltInU); m_strButton = TryGetEx(dictNew, "Button", m_strButton); m_strButtonBack = TryGetEx(dictNew, "ButtonBack", m_strButtonBack); m_strButtonDefault = TryGetEx(dictNew, "ButtonDefault", m_strButtonDefault); m_strButtonFinish = TryGetEx(dictNew, "ButtonFinish", m_strButtonFinish); m_strButtonNext = TryGetEx(dictNew, "ButtonNext", m_strButtonNext); m_strButtons = TryGetEx(dictNew, "Buttons", m_strButtons); m_strCancel = TryGetEx(dictNew, "Cancel", m_strCancel); m_strCannotMoveEntriesBcsGroup = TryGetEx(dictNew, "CannotMoveEntriesBcsGroup", m_strCannotMoveEntriesBcsGroup); m_strChangeMasterKey = TryGetEx(dictNew, "ChangeMasterKey", m_strChangeMasterKey); m_strChangeMasterKeyIntroShort = TryGetEx(dictNew, "ChangeMasterKeyIntroShort", m_strChangeMasterKeyIntroShort); m_strCharsAbbr = TryGetEx(dictNew, "CharsAbbr", m_strCharsAbbr); m_strCharsStc = TryGetEx(dictNew, "CharsStc", m_strCharsStc); m_strCheckForUpdAtStart = TryGetEx(dictNew, "CheckForUpdAtStart", m_strCheckForUpdAtStart); m_strCheckingForUpd = TryGetEx(dictNew, "CheckingForUpd", m_strCheckingForUpd); m_strClassicAdj = TryGetEx(dictNew, "ClassicAdj", m_strClassicAdj); m_strClearKeyCmdLineParams = TryGetEx(dictNew, "ClearKeyCmdLineParams", m_strClearKeyCmdLineParams); m_strClearMru = TryGetEx(dictNew, "ClearMru", m_strClearMru); m_strClipboard = TryGetEx(dictNew, "Clipboard", m_strClipboard); m_strClipboardClearInSeconds = TryGetEx(dictNew, "ClipboardClearInSeconds", m_strClipboardClearInSeconds); m_strClipboardClearOnExit = TryGetEx(dictNew, "ClipboardClearOnExit", m_strClipboardClearOnExit); m_strClipboardDataCopied = TryGetEx(dictNew, "ClipboardDataCopied", m_strClipboardDataCopied); m_strClipboardViewerIgnoreFormat = TryGetEx(dictNew, "ClipboardViewerIgnoreFormat", m_strClipboardViewerIgnoreFormat); m_strCloseActiveDatabase = TryGetEx(dictNew, "CloseActiveDatabase", m_strCloseActiveDatabase); m_strCloseButton = TryGetEx(dictNew, "CloseButton", m_strCloseButton); m_strCloseButtonMinimizes = TryGetEx(dictNew, "CloseButtonMinimizes", m_strCloseButtonMinimizes); m_strClosingDatabaseFile = TryGetEx(dictNew, "ClosingDatabaseFile", m_strClosingDatabaseFile); m_strClusterCenters = TryGetEx(dictNew, "ClusterCenters", m_strClusterCenters); m_strClusterCentersDesc = TryGetEx(dictNew, "ClusterCentersDesc", m_strClusterCentersDesc); m_strColumn = TryGetEx(dictNew, "Column", m_strColumn); m_strColumns = TryGetEx(dictNew, "Columns", m_strColumns); m_strComments = TryGetEx(dictNew, "Comments", m_strComments); m_strCompany = TryGetEx(dictNew, "Company", m_strCompany); m_strComparison = TryGetEx(dictNew, "Comparison", m_strComparison); m_strComponent = TryGetEx(dictNew, "Component", m_strComponent); m_strCondition = TryGetEx(dictNew, "Condition", m_strCondition); m_strConfigAffectAdmin = TryGetEx(dictNew, "ConfigAffectAdmin", m_strConfigAffectAdmin); m_strConfigAffectUser = TryGetEx(dictNew, "ConfigAffectUser", m_strConfigAffectUser); m_strConfigSaveFailed = TryGetEx(dictNew, "ConfigSaveFailed", m_strConfigSaveFailed); m_strConfigureAutoType = TryGetEx(dictNew, "ConfigureAutoType", m_strConfigureAutoType); m_strConfigureAutoTypeDesc = TryGetEx(dictNew, "ConfigureAutoTypeDesc", m_strConfigureAutoTypeDesc); m_strConfigureAutoTypeItem = TryGetEx(dictNew, "ConfigureAutoTypeItem", m_strConfigureAutoTypeItem); m_strConfigureAutoTypeItemDesc = TryGetEx(dictNew, "ConfigureAutoTypeItemDesc", m_strConfigureAutoTypeItemDesc); m_strConfigureColumns = TryGetEx(dictNew, "ConfigureColumns", m_strConfigureColumns); m_strConfigureColumnsDesc = TryGetEx(dictNew, "ConfigureColumnsDesc", m_strConfigureColumnsDesc); m_strConfigureKeystrokeSeq = TryGetEx(dictNew, "ConfigureKeystrokeSeq", m_strConfigureKeystrokeSeq); m_strConfigureKeystrokeSeqDesc = TryGetEx(dictNew, "ConfigureKeystrokeSeqDesc", m_strConfigureKeystrokeSeqDesc); m_strConfigureOnNewDatabase2 = TryGetEx(dictNew, "ConfigureOnNewDatabase2", m_strConfigureOnNewDatabase2); m_strContact = TryGetEx(dictNew, "Contact", m_strContact); m_strContainsOp = TryGetEx(dictNew, "ContainsOp", m_strContainsOp); m_strCopiedEntryData = TryGetEx(dictNew, "CopiedEntryData", m_strCopiedEntryData); m_strCopy = TryGetEx(dictNew, "Copy", m_strCopy); m_strCopyAll = TryGetEx(dictNew, "CopyAll", m_strCopyAll); m_strCopyLink = TryGetEx(dictNew, "CopyLink", m_strCopyLink); m_strCopyOfItem = TryGetEx(dictNew, "CopyOfItem", m_strCopyOfItem); m_strCopyPasswordFull = TryGetEx(dictNew, "CopyPasswordFull", m_strCopyPasswordFull); m_strCopyPasswordMenu = TryGetEx(dictNew, "CopyPasswordMenu", m_strCopyPasswordMenu); m_strCopyTanMenu = TryGetEx(dictNew, "CopyTanMenu", m_strCopyTanMenu); m_strCopyUrlsInsteadOfOpening = TryGetEx(dictNew, "CopyUrlsInsteadOfOpening", m_strCopyUrlsInsteadOfOpening); m_strCopyUrlToClipboard = TryGetEx(dictNew, "CopyUrlToClipboard", m_strCopyUrlToClipboard); m_strCopyUserFull = TryGetEx(dictNew, "CopyUserFull", m_strCopyUserFull); m_strCopyWholeEntries = TryGetEx(dictNew, "CopyWholeEntries", m_strCopyWholeEntries); m_strCorruptionByExt = TryGetEx(dictNew, "CorruptionByExt", m_strCorruptionByExt); m_strCount = TryGetEx(dictNew, "Count", m_strCount); m_strCreateMasterKey = TryGetEx(dictNew, "CreateMasterKey", m_strCreateMasterKey); m_strCreateNewDatabase = TryGetEx(dictNew, "CreateNewDatabase", m_strCreateNewDatabase); m_strCreateNewIDs = TryGetEx(dictNew, "CreateNewIDs", m_strCreateNewIDs); m_strCreationTime = TryGetEx(dictNew, "CreationTime", m_strCreationTime); m_strCredSaveAll = TryGetEx(dictNew, "CredSaveAll", m_strCredSaveAll); m_strCredSaveNone = TryGetEx(dictNew, "CredSaveNone", m_strCredSaveNone); m_strCredSaveUserOnly = TryGetEx(dictNew, "CredSaveUserOnly", m_strCredSaveUserOnly); m_strCredSpecifyDifferent = TryGetEx(dictNew, "CredSpecifyDifferent", m_strCredSpecifyDifferent); m_strCsprojCountError = TryGetEx(dictNew, "CsprojCountError", m_strCsprojCountError); m_strCsvTextFile = TryGetEx(dictNew, "CsvTextFile", m_strCsvTextFile); m_strCtrlAltAConflict = TryGetEx(dictNew, "CtrlAltAConflict", m_strCtrlAltAConflict); m_strCtrlAltAConflictHint = TryGetEx(dictNew, "CtrlAltAConflictHint", m_strCtrlAltAConflictHint); m_strCurrentStyle = TryGetEx(dictNew, "CurrentStyle", m_strCurrentStyle); m_strCustom = TryGetEx(dictNew, "Custom", m_strCustom); m_strCustomFields = TryGetEx(dictNew, "CustomFields", m_strCustomFields); m_strCustomizableHtml = TryGetEx(dictNew, "CustomizableHtml", m_strCustomizableHtml); m_strCustomTbButtonAdd = TryGetEx(dictNew, "CustomTbButtonAdd", m_strCustomTbButtonAdd); m_strCustomTbButtonClicked = TryGetEx(dictNew, "CustomTbButtonClicked", m_strCustomTbButtonClicked); m_strCustomTbButtonRemove = TryGetEx(dictNew, "CustomTbButtonRemove", m_strCustomTbButtonRemove); m_strCut = TryGetEx(dictNew, "Cut", m_strCut); m_strData = TryGetEx(dictNew, "Data", m_strData); m_strDatabase = TryGetEx(dictNew, "Database", m_strDatabase); m_strDatabaseDescPrompt = TryGetEx(dictNew, "DatabaseDescPrompt", m_strDatabaseDescPrompt); m_strDatabaseFile = TryGetEx(dictNew, "DatabaseFile", m_strDatabaseFile); m_strDatabaseFileIntro = TryGetEx(dictNew, "DatabaseFileIntro", m_strDatabaseFileIntro); m_strDatabaseFileRem = TryGetEx(dictNew, "DatabaseFileRem", m_strDatabaseFileRem); m_strDatabaseHasUnsavedChanges = TryGetEx(dictNew, "DatabaseHasUnsavedChanges", m_strDatabaseHasUnsavedChanges); m_strDatabaseMaintenance = TryGetEx(dictNew, "DatabaseMaintenance", m_strDatabaseMaintenance); m_strDatabaseMaintenanceDesc = TryGetEx(dictNew, "DatabaseMaintenanceDesc", m_strDatabaseMaintenanceDesc); m_strDatabaseModifiedNoDot = TryGetEx(dictNew, "DatabaseModifiedNoDot", m_strDatabaseModifiedNoDot); m_strDatabaseNamePrompt = TryGetEx(dictNew, "DatabaseNamePrompt", m_strDatabaseNamePrompt); m_strDatabaseSettings = TryGetEx(dictNew, "DatabaseSettings", m_strDatabaseSettings); m_strDatabaseSettingsDesc = TryGetEx(dictNew, "DatabaseSettingsDesc", m_strDatabaseSettingsDesc); m_strDataEditor = TryGetEx(dictNew, "DataEditor", m_strDataEditor); m_strDataLoss = TryGetEx(dictNew, "DataLoss", m_strDataLoss); m_strDataViewer = TryGetEx(dictNew, "DataViewer", m_strDataViewer); m_strDbMntncResults = TryGetEx(dictNew, "DbMntncResults", m_strDbMntncResults); m_strDbNoModBy = TryGetEx(dictNew, "DbNoModBy", m_strDbNoModBy); m_strDefault = TryGetEx(dictNew, "Default", m_strDefault); m_strDelete = TryGetEx(dictNew, "Delete", m_strDelete); m_strDeleteCmd = TryGetEx(dictNew, "DeleteCmd", m_strDeleteCmd); m_strDeleteEntriesTitle = TryGetEx(dictNew, "DeleteEntriesTitle", m_strDeleteEntriesTitle); m_strDeleteEntriesTitleSingle = TryGetEx(dictNew, "DeleteEntriesTitleSingle", m_strDeleteEntriesTitleSingle); m_strDeleteEntriesQuestion = TryGetEx(dictNew, "DeleteEntriesQuestion", m_strDeleteEntriesQuestion); m_strDeleteEntriesQuestionSingle = TryGetEx(dictNew, "DeleteEntriesQuestionSingle", m_strDeleteEntriesQuestionSingle); m_strDeleteGroupTitle = TryGetEx(dictNew, "DeleteGroupTitle", m_strDeleteGroupTitle); m_strDeleteGroupInfo = TryGetEx(dictNew, "DeleteGroupInfo", m_strDeleteGroupInfo); m_strDeleteGroupQuestion = TryGetEx(dictNew, "DeleteGroupQuestion", m_strDeleteGroupQuestion); m_strDescending = TryGetEx(dictNew, "Descending", m_strDescending); m_strDescription = TryGetEx(dictNew, "Description", m_strDescription); m_strDetails = TryGetEx(dictNew, "Details", m_strDetails); m_strDialogNoShowAgain = TryGetEx(dictNew, "DialogNoShowAgain", m_strDialogNoShowAgain); m_strDialogs = TryGetEx(dictNew, "Dialogs", m_strDialogs); m_strDisable = TryGetEx(dictNew, "Disable", m_strDisable); m_strDisabled = TryGetEx(dictNew, "Disabled", m_strDisabled); m_strDisableSaveIfNotModified = TryGetEx(dictNew, "DisableSaveIfNotModified", m_strDisableSaveIfNotModified); m_strDiscardChangesCmd = TryGetEx(dictNew, "DiscardChangesCmd", m_strDiscardChangesCmd); m_strDocumentationHint = TryGetEx(dictNew, "DocumentationHint", m_strDocumentationHint); m_strDragDrop = TryGetEx(dictNew, "DragDrop", m_strDragDrop); m_strDropToBackOnCopy = TryGetEx(dictNew, "DropToBackOnCopy", m_strDropToBackOnCopy); m_strDuplicatePasswords = TryGetEx(dictNew, "DuplicatePasswords", m_strDuplicatePasswords); m_strDuplicatePasswordsGroup = TryGetEx(dictNew, "DuplicatePasswordsGroup", m_strDuplicatePasswordsGroup); m_strDuplicatePasswordsList = TryGetEx(dictNew, "DuplicatePasswordsList", m_strDuplicatePasswordsList); m_strDuplicatePasswordsNone = TryGetEx(dictNew, "DuplicatePasswordsNone", m_strDuplicatePasswordsNone); m_strDuplicateStringFieldName = TryGetEx(dictNew, "DuplicateStringFieldName", m_strDuplicateStringFieldName); m_strEditCmd = TryGetEx(dictNew, "EditCmd", m_strEditCmd); m_strEditEntry = TryGetEx(dictNew, "EditEntry", m_strEditEntry); m_strEditEntryDesc = TryGetEx(dictNew, "EditEntryDesc", m_strEditEntryDesc); m_strEditGroup = TryGetEx(dictNew, "EditGroup", m_strEditGroup); m_strEditGroupDesc = TryGetEx(dictNew, "EditGroupDesc", m_strEditGroupDesc); m_strEditStringField = TryGetEx(dictNew, "EditStringField", m_strEditStringField); m_strEditStringFieldDesc = TryGetEx(dictNew, "EditStringFieldDesc", m_strEditStringFieldDesc); m_strEMail = TryGetEx(dictNew, "EMail", m_strEMail); m_strEmergencySheet = TryGetEx(dictNew, "EmergencySheet", m_strEmergencySheet); m_strEmergencySheetAsk = TryGetEx(dictNew, "EmergencySheetAsk", m_strEmergencySheetAsk); m_strEmergencySheetInfo = TryGetEx(dictNew, "EmergencySheetInfo", m_strEmergencySheetInfo); m_strEmergencySheetPrintInfo = TryGetEx(dictNew, "EmergencySheetPrintInfo", m_strEmergencySheetPrintInfo); m_strEmergencySheetQ = TryGetEx(dictNew, "EmergencySheetQ", m_strEmergencySheetQ); m_strEmergencySheetRec = TryGetEx(dictNew, "EmergencySheetRec", m_strEmergencySheetRec); m_strEmpty = TryGetEx(dictNew, "Empty", m_strEmpty); m_strEmptyMasterPw = TryGetEx(dictNew, "EmptyMasterPw", m_strEmptyMasterPw); m_strEmptyMasterPwHint = TryGetEx(dictNew, "EmptyMasterPwHint", m_strEmptyMasterPwHint); m_strEmptyMasterPwQuestion = TryGetEx(dictNew, "EmptyMasterPwQuestion", m_strEmptyMasterPwQuestion); m_strEmptyRecycleBinQuestion = TryGetEx(dictNew, "EmptyRecycleBinQuestion", m_strEmptyRecycleBinQuestion); m_strEnable = TryGetEx(dictNew, "Enable", m_strEnable); m_strEnabled = TryGetEx(dictNew, "Enabled", m_strEnabled); m_strEncoding = TryGetEx(dictNew, "Encoding", m_strEncoding); m_strEncodingFail = TryGetEx(dictNew, "EncodingFail", m_strEncodingFail); m_strEndsWith = TryGetEx(dictNew, "EndsWith", m_strEndsWith); m_strEnterCompositeKey = TryGetEx(dictNew, "EnterCompositeKey", m_strEnterCompositeKey); m_strEnterCurrentCompositeKey = TryGetEx(dictNew, "EnterCurrentCompositeKey", m_strEnterCurrentCompositeKey); m_strEntropyDesc = TryGetEx(dictNew, "EntropyDesc", m_strEntropyDesc); m_strEntropyTitle = TryGetEx(dictNew, "EntropyTitle", m_strEntropyTitle); m_strEntry = TryGetEx(dictNew, "Entry", m_strEntry); m_strEntryList = TryGetEx(dictNew, "EntryList", m_strEntryList); m_strEntryListAutoResizeColumns = TryGetEx(dictNew, "EntryListAutoResizeColumns", m_strEntryListAutoResizeColumns); m_strEntrySelGroupSel = TryGetEx(dictNew, "EntrySelGroupSel", m_strEntrySelGroupSel); m_strEnvironmentVariable = TryGetEx(dictNew, "EnvironmentVariable", m_strEnvironmentVariable); m_strEqualsOp = TryGetEx(dictNew, "EqualsOp", m_strEqualsOp); m_strError = TryGetEx(dictNew, "Error", m_strError); m_strErrorCode = TryGetEx(dictNew, "ErrorCode", m_strErrorCode); m_strErrors = TryGetEx(dictNew, "Errors", m_strErrors); m_strEscMinimizesToTray = TryGetEx(dictNew, "EscMinimizesToTray", m_strEscMinimizesToTray); m_strEvent = TryGetEx(dictNew, "Event", m_strEvent); m_strExecuteCmdLineUrl = TryGetEx(dictNew, "ExecuteCmdLineUrl", m_strExecuteCmdLineUrl); m_strExitInsteadOfLockingAfterTime = TryGetEx(dictNew, "ExitInsteadOfLockingAfterTime", m_strExitInsteadOfLockingAfterTime); m_strExitInsteadOfLockingAlways = TryGetEx(dictNew, "ExitInsteadOfLockingAlways", m_strExitInsteadOfLockingAlways); m_strExpiredEntries = TryGetEx(dictNew, "ExpiredEntries", m_strExpiredEntries); m_strExpiredEntriesCanMatch = TryGetEx(dictNew, "ExpiredEntriesCanMatch", m_strExpiredEntriesCanMatch); m_strExpiryTime = TryGetEx(dictNew, "ExpiryTime", m_strExpiryTime); m_strExpiryTimeDateOnly = TryGetEx(dictNew, "ExpiryTimeDateOnly", m_strExpiryTimeDateOnly); m_strExport = TryGetEx(dictNew, "Export", m_strExport); m_strExportFileDesc = TryGetEx(dictNew, "ExportFileDesc", m_strExportFileDesc); m_strExportFileTitle = TryGetEx(dictNew, "ExportFileTitle", m_strExportFileTitle); m_strExportHtml = TryGetEx(dictNew, "ExportHtml", m_strExportHtml); m_strExportHtmlDesc = TryGetEx(dictNew, "ExportHtmlDesc", m_strExportHtmlDesc); m_strExportingStatusMsg = TryGetEx(dictNew, "ExportingStatusMsg", m_strExportingStatusMsg); m_strExportStc = TryGetEx(dictNew, "ExportStc", m_strExportStc); m_strExportToPrompt = TryGetEx(dictNew, "ExportToPrompt", m_strExportToPrompt); m_strExternal = TryGetEx(dictNew, "External", m_strExternal); m_strExternalApp = TryGetEx(dictNew, "ExternalApp", m_strExternalApp); m_strFatalError = TryGetEx(dictNew, "FatalError", m_strFatalError); m_strFeature = TryGetEx(dictNew, "Feature", m_strFeature); m_strField = TryGetEx(dictNew, "Field", m_strField); m_strFieldName = TryGetEx(dictNew, "FieldName", m_strFieldName); m_strFieldNameExistsAlready = TryGetEx(dictNew, "FieldNameExistsAlready", m_strFieldNameExistsAlready); m_strFieldNameInvalid = TryGetEx(dictNew, "FieldNameInvalid", m_strFieldNameInvalid); m_strFieldNamePrompt = TryGetEx(dictNew, "FieldNamePrompt", m_strFieldNamePrompt); m_strFieldRefInvalidChars = TryGetEx(dictNew, "FieldRefInvalidChars", m_strFieldRefInvalidChars); m_strFieldRefMultiMatch = TryGetEx(dictNew, "FieldRefMultiMatch", m_strFieldRefMultiMatch); m_strFieldRefMultiMatchHint = TryGetEx(dictNew, "FieldRefMultiMatchHint", m_strFieldRefMultiMatchHint); m_strFieldValue = TryGetEx(dictNew, "FieldValue", m_strFieldValue); m_strFile = TryGetEx(dictNew, "File", m_strFile); m_strFileChanged = TryGetEx(dictNew, "FileChanged", m_strFileChanged); m_strFileChangedOverwrite = TryGetEx(dictNew, "FileChangedOverwrite", m_strFileChangedOverwrite); m_strFileChangedSync = TryGetEx(dictNew, "FileChangedSync", m_strFileChangedSync); m_strFileExists = TryGetEx(dictNew, "FileExists", m_strFileExists); m_strFileExistsAlready = TryGetEx(dictNew, "FileExistsAlready", m_strFileExistsAlready); m_strFileExtInstallFailed = TryGetEx(dictNew, "FileExtInstallFailed", m_strFileExtInstallFailed); m_strFileExtInstallSuccess = TryGetEx(dictNew, "FileExtInstallSuccess", m_strFileExtInstallSuccess); m_strFileExtName = TryGetEx(dictNew, "FileExtName", m_strFileExtName); m_strFileFormatStc = TryGetEx(dictNew, "FileFormatStc", m_strFileFormatStc); m_strFileLockedBy = TryGetEx(dictNew, "FileLockedBy", m_strFileLockedBy); m_strFileLockedWarning = TryGetEx(dictNew, "FileLockedWarning", m_strFileLockedWarning); m_strFileNameContainsSemicolonError = TryGetEx(dictNew, "FileNameContainsSemicolonError", m_strFileNameContainsSemicolonError); m_strFileNotFoundError = TryGetEx(dictNew, "FileNotFoundError", m_strFileNotFoundError); m_strFileOrUrl = TryGetEx(dictNew, "FileOrUrl", m_strFileOrUrl); m_strFiles = TryGetEx(dictNew, "Files", m_strFiles); m_strFileSaveQ = TryGetEx(dictNew, "FileSaveQ", m_strFileSaveQ); m_strFileSaveQClosing = TryGetEx(dictNew, "FileSaveQClosing", m_strFileSaveQClosing); m_strFileSaveQExiting = TryGetEx(dictNew, "FileSaveQExiting", m_strFileSaveQExiting); m_strFileSaveQLocking = TryGetEx(dictNew, "FileSaveQLocking", m_strFileSaveQLocking); m_strFileSaveQOpCancel = TryGetEx(dictNew, "FileSaveQOpCancel", m_strFileSaveQOpCancel); m_strFileSaveQOpCancelClosing = TryGetEx(dictNew, "FileSaveQOpCancelClosing", m_strFileSaveQOpCancelClosing); m_strFileSaveQOpCancelExiting = TryGetEx(dictNew, "FileSaveQOpCancelExiting", m_strFileSaveQOpCancelExiting); m_strFileSaveQOpCancelLocking = TryGetEx(dictNew, "FileSaveQOpCancelLocking", m_strFileSaveQOpCancelLocking); m_strFileSaveQOpNoClosing = TryGetEx(dictNew, "FileSaveQOpNoClosing", m_strFileSaveQOpNoClosing); m_strFileSaveQOpNoExiting = TryGetEx(dictNew, "FileSaveQOpNoExiting", m_strFileSaveQOpNoExiting); m_strFileSaveQOpNoLocking = TryGetEx(dictNew, "FileSaveQOpNoLocking", m_strFileSaveQOpNoLocking); m_strFileSaveQOpYesClosing = TryGetEx(dictNew, "FileSaveQOpYesClosing", m_strFileSaveQOpYesClosing); m_strFileSaveQOpYesExiting = TryGetEx(dictNew, "FileSaveQOpYesExiting", m_strFileSaveQOpYesExiting); m_strFileSaveQOpYesLocking = TryGetEx(dictNew, "FileSaveQOpYesLocking", m_strFileSaveQOpYesLocking); m_strFileTooLarge = TryGetEx(dictNew, "FileTooLarge", m_strFileTooLarge); m_strFileTxExtra = TryGetEx(dictNew, "FileTxExtra", m_strFileTxExtra); m_strFileVerifyHashFail = TryGetEx(dictNew, "FileVerifyHashFail", m_strFileVerifyHashFail); m_strFileVerifyHashFailRec = TryGetEx(dictNew, "FileVerifyHashFailRec", m_strFileVerifyHashFailRec); m_strFilter = TryGetEx(dictNew, "Filter", m_strFilter); m_strFind = TryGetEx(dictNew, "Find", m_strFind); m_strFocusQuickFindOnRestore = TryGetEx(dictNew, "FocusQuickFindOnRestore", m_strFocusQuickFindOnRestore); m_strFocusQuickFindOnUntray = TryGetEx(dictNew, "FocusQuickFindOnUntray", m_strFocusQuickFindOnUntray); m_strFocusResultsAfterQuickSearch = TryGetEx(dictNew, "FocusResultsAfterQuickSearch", m_strFocusResultsAfterQuickSearch); m_strFolder = TryGetEx(dictNew, "Folder", m_strFolder); m_strFont = TryGetEx(dictNew, "Font", m_strFont); m_strFontDefault = TryGetEx(dictNew, "FontDefault", m_strFontDefault); m_strForceSystemFontUnix = TryGetEx(dictNew, "ForceSystemFontUnix", m_strForceSystemFontUnix); m_strFormat = TryGetEx(dictNew, "Format", m_strFormat); m_strFormatNoDatabaseDesc = TryGetEx(dictNew, "FormatNoDatabaseDesc", m_strFormatNoDatabaseDesc); m_strFormatNoDatabaseName = TryGetEx(dictNew, "FormatNoDatabaseName", m_strFormatNoDatabaseName); m_strFormatNoRootEntries = TryGetEx(dictNew, "FormatNoRootEntries", m_strFormatNoRootEntries); m_strFormatNoSubGroupsInRoot = TryGetEx(dictNew, "FormatNoSubGroupsInRoot", m_strFormatNoSubGroupsInRoot); m_strFormatOnlyOneAttachment = TryGetEx(dictNew, "FormatOnlyOneAttachment", m_strFormatOnlyOneAttachment); m_strGeneral = TryGetEx(dictNew, "General", m_strGeneral); m_strGenerate = TryGetEx(dictNew, "Generate", m_strGenerate); m_strGenerateCount = TryGetEx(dictNew, "GenerateCount", m_strGenerateCount); m_strGenerateCountDesc = TryGetEx(dictNew, "GenerateCountDesc", m_strGenerateCountDesc); m_strGenerateCountLongDesc = TryGetEx(dictNew, "GenerateCountLongDesc", m_strGenerateCountLongDesc); m_strGeneratedPasswordSamples = TryGetEx(dictNew, "GeneratedPasswordSamples", m_strGeneratedPasswordSamples); m_strGeneratePassword = TryGetEx(dictNew, "GeneratePassword", m_strGeneratePassword); m_strGenericCsvImporter = TryGetEx(dictNew, "GenericCsvImporter", m_strGenericCsvImporter); m_strGenProfileRemove = TryGetEx(dictNew, "GenProfileRemove", m_strGenProfileRemove); m_strGenProfileRemoveDesc = TryGetEx(dictNew, "GenProfileRemoveDesc", m_strGenProfileRemoveDesc); m_strGenProfileSave = TryGetEx(dictNew, "GenProfileSave", m_strGenProfileSave); m_strGenProfileSaveDesc = TryGetEx(dictNew, "GenProfileSaveDesc", m_strGenProfileSaveDesc); m_strGenProfileSaveDescLong = TryGetEx(dictNew, "GenProfileSaveDescLong", m_strGenProfileSaveDescLong); m_strGenPwAccept = TryGetEx(dictNew, "GenPwAccept", m_strGenPwAccept); m_strGenPwBasedOnPrevious = TryGetEx(dictNew, "GenPwBasedOnPrevious", m_strGenPwBasedOnPrevious); m_strGenPwSprVariant = TryGetEx(dictNew, "GenPwSprVariant", m_strGenPwSprVariant); m_strGradient = TryGetEx(dictNew, "Gradient", m_strGradient); m_strGroup = TryGetEx(dictNew, "Group", m_strGroup); m_strGroupCannotStoreEntries = TryGetEx(dictNew, "GroupCannotStoreEntries", m_strGroupCannotStoreEntries); m_strGroupsSkipped = TryGetEx(dictNew, "GroupsSkipped", m_strGroupsSkipped); m_strGroupsSkipped1 = TryGetEx(dictNew, "GroupsSkipped1", m_strGroupsSkipped1); m_strHelpSourceNoLocalOption = TryGetEx(dictNew, "HelpSourceNoLocalOption", m_strHelpSourceNoLocalOption); m_strHelpSourceSelection = TryGetEx(dictNew, "HelpSourceSelection", m_strHelpSourceSelection); m_strHelpSourceSelectionDesc = TryGetEx(dictNew, "HelpSourceSelectionDesc", m_strHelpSourceSelectionDesc); m_strHexKeyEx = TryGetEx(dictNew, "HexKeyEx", m_strHexKeyEx); m_strHexViewer = TryGetEx(dictNew, "HexViewer", m_strHexViewer); m_strHidden = TryGetEx(dictNew, "Hidden", m_strHidden); m_strHideCloseDatabaseTb = TryGetEx(dictNew, "HideCloseDatabaseTb", m_strHideCloseDatabaseTb); m_strHideUsingAsterisks = TryGetEx(dictNew, "HideUsingAsterisks", m_strHideUsingAsterisks); m_strHistory = TryGetEx(dictNew, "History", m_strHistory); m_strHomebanking = TryGetEx(dictNew, "Homebanking", m_strHomebanking); m_strHost = TryGetEx(dictNew, "Host", m_strHost); m_strHotKeyAltOnly = TryGetEx(dictNew, "HotKeyAltOnly", m_strHotKeyAltOnly); m_strHotKeyAltOnlyHint = TryGetEx(dictNew, "HotKeyAltOnlyHint", m_strHotKeyAltOnlyHint); m_strHotKeyAltOnlyQuestion = TryGetEx(dictNew, "HotKeyAltOnlyQuestion", m_strHotKeyAltOnlyQuestion); m_strIcon = TryGetEx(dictNew, "Icon", m_strIcon); m_strId = TryGetEx(dictNew, "Id", m_strId); m_strIgnore = TryGetEx(dictNew, "Ignore", m_strIgnore); m_strImageFormatFeatureUnsupported = TryGetEx(dictNew, "ImageFormatFeatureUnsupported", m_strImageFormatFeatureUnsupported); m_strImageViewer = TryGetEx(dictNew, "ImageViewer", m_strImageViewer); m_strImport = TryGetEx(dictNew, "Import", m_strImport); m_strImportBehavior = TryGetEx(dictNew, "ImportBehavior", m_strImportBehavior); m_strImportBehaviorDesc = TryGetEx(dictNew, "ImportBehaviorDesc", m_strImportBehaviorDesc); m_strImportFailed = TryGetEx(dictNew, "ImportFailed", m_strImportFailed); m_strImportFileDesc = TryGetEx(dictNew, "ImportFileDesc", m_strImportFileDesc); m_strImportFilesPrompt = TryGetEx(dictNew, "ImportFilesPrompt", m_strImportFilesPrompt); m_strImportFileTitle = TryGetEx(dictNew, "ImportFileTitle", m_strImportFileTitle); m_strImportFinished = TryGetEx(dictNew, "ImportFinished", m_strImportFinished); m_strImportingStatusMsg = TryGetEx(dictNew, "ImportingStatusMsg", m_strImportingStatusMsg); m_strImportMustRead = TryGetEx(dictNew, "ImportMustRead", m_strImportMustRead); m_strImportMustReadQuestion = TryGetEx(dictNew, "ImportMustReadQuestion", m_strImportMustReadQuestion); m_strImportStc = TryGetEx(dictNew, "ImportStc", m_strImportStc); m_strIncompatibleEnv = TryGetEx(dictNew, "IncompatibleEnv", m_strIncompatibleEnv); m_strIncompatibleWithSorting = TryGetEx(dictNew, "IncompatibleWithSorting", m_strIncompatibleWithSorting); m_strInheritSettingFromParent = TryGetEx(dictNew, "InheritSettingFromParent", m_strInheritSettingFromParent); m_strInstalled = TryGetEx(dictNew, "Installed", m_strInstalled); m_strInstalledLanguages = TryGetEx(dictNew, "InstalledLanguages", m_strInstalledLanguages); m_strInstrAndGenInfo = TryGetEx(dictNew, "InstrAndGenInfo", m_strInstrAndGenInfo); m_strInterleavedKeySending = TryGetEx(dictNew, "InterleavedKeySending", m_strInterleavedKeySending); m_strInternalEditor = TryGetEx(dictNew, "InternalEditor", m_strInternalEditor); m_strInternalViewer = TryGetEx(dictNew, "InternalViewer", m_strInternalViewer); m_strInternet = TryGetEx(dictNew, "Internet", m_strInternet); m_strInvalidKey = TryGetEx(dictNew, "InvalidKey", m_strInvalidKey); m_strInvalidUrl = TryGetEx(dictNew, "InvalidUrl", m_strInvalidUrl); m_strInvalidUserPassword = TryGetEx(dictNew, "InvalidUserPassword", m_strInvalidUserPassword); m_strIOConnection = TryGetEx(dictNew, "IOConnection", m_strIOConnection); m_strIOConnectionLong = TryGetEx(dictNew, "IOConnectionLong", m_strIOConnectionLong); m_strItalic = TryGetEx(dictNew, "Italic", m_strItalic); m_strIterations = TryGetEx(dictNew, "Iterations", m_strIterations); m_strKdbKeePassLibC = TryGetEx(dictNew, "KdbKeePassLibC", m_strKdbKeePassLibC); m_strKdbWUA = TryGetEx(dictNew, "KdbWUA", m_strKdbWUA); m_strKdbxFiles = TryGetEx(dictNew, "KdbxFiles", m_strKdbxFiles); m_strKdfAdjust = TryGetEx(dictNew, "KdfAdjust", m_strKdfAdjust); m_strKdfParams1Sec = TryGetEx(dictNew, "KdfParams1Sec", m_strKdfParams1Sec); m_strKeePassLibCLong = TryGetEx(dictNew, "KeePassLibCLong", m_strKeePassLibCLong); m_strKeePassLibCNotFound = TryGetEx(dictNew, "KeePassLibCNotFound", m_strKeePassLibCNotFound); m_strKeePassLibCNotWindows = TryGetEx(dictNew, "KeePassLibCNotWindows", m_strKeePassLibCNotWindows); m_strKeePassLibCNotWindowsHint = TryGetEx(dictNew, "KeePassLibCNotWindowsHint", m_strKeePassLibCNotWindowsHint); m_strKeepExisting = TryGetEx(dictNew, "KeepExisting", m_strKeepExisting); m_strKeyboardKeyAlt = TryGetEx(dictNew, "KeyboardKeyAlt", m_strKeyboardKeyAlt); m_strKeyboardKeyCtrl = TryGetEx(dictNew, "KeyboardKeyCtrl", m_strKeyboardKeyCtrl); m_strKeyboardKeyCtrlLeft = TryGetEx(dictNew, "KeyboardKeyCtrlLeft", m_strKeyboardKeyCtrlLeft); m_strKeyboardKeyEsc = TryGetEx(dictNew, "KeyboardKeyEsc", m_strKeyboardKeyEsc); m_strKeyboardKeyModifiers = TryGetEx(dictNew, "KeyboardKeyModifiers", m_strKeyboardKeyModifiers); m_strKeyboardKeyReturn = TryGetEx(dictNew, "KeyboardKeyReturn", m_strKeyboardKeyReturn); m_strKeyboardKeyShift = TryGetEx(dictNew, "KeyboardKeyShift", m_strKeyboardKeyShift); m_strKeyboardKeyShiftLeft = TryGetEx(dictNew, "KeyboardKeyShiftLeft", m_strKeyboardKeyShiftLeft); m_strKeyFile = TryGetEx(dictNew, "KeyFile", m_strKeyFile); m_strKeyFileCreate = TryGetEx(dictNew, "KeyFileCreate", m_strKeyFileCreate); m_strKeyFileError = TryGetEx(dictNew, "KeyFileError", m_strKeyFileError); m_strKeyFiles = TryGetEx(dictNew, "KeyFiles", m_strKeyFiles); m_strKeyFileSelect = TryGetEx(dictNew, "KeyFileSelect", m_strKeyFileSelect); m_strKeyFileUseExisting = TryGetEx(dictNew, "KeyFileUseExisting", m_strKeyFileUseExisting); m_strKeyProvider = TryGetEx(dictNew, "KeyProvider", m_strKeyProvider); m_strKeyProvIncmpWithSD = TryGetEx(dictNew, "KeyProvIncmpWithSD", m_strKeyProvIncmpWithSD); m_strKeyProvIncmpWithSDHint = TryGetEx(dictNew, "KeyProvIncmpWithSDHint", m_strKeyProvIncmpWithSDHint); m_strLanguageSelected = TryGetEx(dictNew, "LanguageSelected", m_strLanguageSelected); m_strLastAccessTime = TryGetEx(dictNew, "LastAccessTime", m_strLastAccessTime); m_strLastModificationTime = TryGetEx(dictNew, "LastModificationTime", m_strLastModificationTime); m_strLastModTimePwHist = TryGetEx(dictNew, "LastModTimePwHist", m_strLastModTimePwHist); m_strLatestVersionWeb = TryGetEx(dictNew, "LatestVersionWeb", m_strLatestVersionWeb); m_strLimitSingleInstance = TryGetEx(dictNew, "LimitSingleInstance", m_strLimitSingleInstance); m_strLngInAppDir = TryGetEx(dictNew, "LngInAppDir", m_strLngInAppDir); m_strLngInAppDirNote = TryGetEx(dictNew, "LngInAppDirNote", m_strLngInAppDirNote); m_strLngInAppDirQ = TryGetEx(dictNew, "LngInAppDirQ", m_strLngInAppDirQ); m_strLocked = TryGetEx(dictNew, "Locked", m_strLocked); m_strLockMenuLock = TryGetEx(dictNew, "LockMenuLock", m_strLockMenuLock); m_strLockMenuUnlock = TryGetEx(dictNew, "LockMenuUnlock", m_strLockMenuUnlock); m_strLockOnMinimizeTaskbar = TryGetEx(dictNew, "LockOnMinimizeTaskbar", m_strLockOnMinimizeTaskbar); m_strLockOnMinimizeTray = TryGetEx(dictNew, "LockOnMinimizeTray", m_strLockOnMinimizeTray); m_strLockOnRemoteControlChange = TryGetEx(dictNew, "LockOnRemoteControlChange", m_strLockOnRemoteControlChange); m_strLockOnSessionSwitch = TryGetEx(dictNew, "LockOnSessionSwitch", m_strLockOnSessionSwitch); m_strLockOnSuspend = TryGetEx(dictNew, "LockOnSuspend", m_strLockOnSuspend); m_strMainInstruction = TryGetEx(dictNew, "MainInstruction", m_strMainInstruction); m_strMainWindow = TryGetEx(dictNew, "MainWindow", m_strMainWindow); m_strMasterKey = TryGetEx(dictNew, "MasterKey", m_strMasterKey); m_strMasterKeyChanged = TryGetEx(dictNew, "MasterKeyChanged", m_strMasterKeyChanged); m_strMasterKeyChangedSave = TryGetEx(dictNew, "MasterKeyChangedSave", m_strMasterKeyChangedSave); m_strMasterKeyChangedShort = TryGetEx(dictNew, "MasterKeyChangedShort", m_strMasterKeyChangedShort); m_strMasterKeyChangeForce = TryGetEx(dictNew, "MasterKeyChangeForce", m_strMasterKeyChangeForce); m_strMasterKeyChangeInfo = TryGetEx(dictNew, "MasterKeyChangeInfo", m_strMasterKeyChangeInfo); m_strMasterKeyChangeQ = TryGetEx(dictNew, "MasterKeyChangeQ", m_strMasterKeyChangeQ); m_strMasterKeyChangeRec = TryGetEx(dictNew, "MasterKeyChangeRec", m_strMasterKeyChangeRec); m_strMasterKeyComponents = TryGetEx(dictNew, "MasterKeyComponents", m_strMasterKeyComponents); m_strMasterKeyOnSecureDesktop = TryGetEx(dictNew, "MasterKeyOnSecureDesktop", m_strMasterKeyOnSecureDesktop); m_strMasterPassword = TryGetEx(dictNew, "MasterPassword", m_strMasterPassword); m_strMasterPasswordMinLengthFailed = TryGetEx(dictNew, "MasterPasswordMinLengthFailed", m_strMasterPasswordMinLengthFailed); m_strMasterPasswordMinQualityFailed = TryGetEx(dictNew, "MasterPasswordMinQualityFailed", m_strMasterPasswordMinQualityFailed); m_strMaxAttachmentSize = TryGetEx(dictNew, "MaxAttachmentSize", m_strMaxAttachmentSize); m_strMaximized = TryGetEx(dictNew, "Maximized", m_strMaximized); m_strMemory = TryGetEx(dictNew, "Memory", m_strMemory); m_strMenus = TryGetEx(dictNew, "Menus", m_strMenus); m_strMethod = TryGetEx(dictNew, "Method", m_strMethod); m_strMinimizeAfterCopy = TryGetEx(dictNew, "MinimizeAfterCopy", m_strMinimizeAfterCopy); m_strMinimizeAfterLocking = TryGetEx(dictNew, "MinimizeAfterLocking", m_strMinimizeAfterLocking); m_strMinimizeAfterOpeningDatabase = TryGetEx(dictNew, "MinimizeAfterOpeningDatabase", m_strMinimizeAfterOpeningDatabase); m_strMinimized = TryGetEx(dictNew, "Minimized", m_strMinimized); m_strMinimizeToTray = TryGetEx(dictNew, "MinimizeToTray", m_strMinimizeToTray); m_strMore = TryGetEx(dictNew, "More", m_strMore); m_strMoreEntries = TryGetEx(dictNew, "MoreEntries", m_strMoreEntries); m_strName = TryGetEx(dictNew, "Name", m_strName); m_strNativeLibUse = TryGetEx(dictNew, "NativeLibUse", m_strNativeLibUse); m_strNavigation = TryGetEx(dictNew, "Navigation", m_strNavigation); m_strNetwork = TryGetEx(dictNew, "Network", m_strNetwork); m_strNeverExpires = TryGetEx(dictNew, "NeverExpires", m_strNeverExpires); m_strNew = TryGetEx(dictNew, "New", m_strNew); m_strNewDatabase = TryGetEx(dictNew, "NewDatabase", m_strNewDatabase); m_strNewDatabaseFileName = TryGetEx(dictNew, "NewDatabaseFileName", m_strNewDatabaseFileName); m_strNewerNetRequired = TryGetEx(dictNew, "NewerNetRequired", m_strNewerNetRequired); m_strNewGroup = TryGetEx(dictNew, "NewGroup", m_strNewGroup); m_strNewLine = TryGetEx(dictNew, "NewLine", m_strNewLine); m_strNewState = TryGetEx(dictNew, "NewState", m_strNewState); m_strNewVersionAvailable = TryGetEx(dictNew, "NewVersionAvailable", m_strNewVersionAvailable); m_strNo = TryGetEx(dictNew, "No", m_strNo); m_strNoCmd = TryGetEx(dictNew, "NoCmd", m_strNoCmd); m_strNoEncNoCompress = TryGetEx(dictNew, "NoEncNoCompress", m_strNoEncNoCompress); m_strNoFileAccessRead = TryGetEx(dictNew, "NoFileAccessRead", m_strNoFileAccessRead); m_strNoKeyFileSpecifiedMeta = TryGetEx(dictNew, "NoKeyFileSpecifiedMeta", m_strNoKeyFileSpecifiedMeta); m_strNoKeyRepeat = TryGetEx(dictNew, "NoKeyRepeat", m_strNoKeyRepeat); m_strNone = TryGetEx(dictNew, "None", m_strNone); m_strNormal = TryGetEx(dictNew, "Normal", m_strNormal); m_strNoSort = TryGetEx(dictNew, "NoSort", m_strNoSort); m_strNot = TryGetEx(dictNew, "Not", m_strNot); m_strNotNow = TryGetEx(dictNew, "NotNow", m_strNotNow); m_strNotRecommended = TryGetEx(dictNew, "NotRecommended", m_strNotRecommended); m_strNotes = TryGetEx(dictNew, "Notes", m_strNotes); m_strNotInstalled = TryGetEx(dictNew, "NotInstalled", m_strNotInstalled); m_strNoXslFile = TryGetEx(dictNew, "NoXslFile", m_strNoXslFile); m_strObjectNotFound = TryGetEx(dictNew, "ObjectNotFound", m_strObjectNotFound); m_strObjectsDeleted = TryGetEx(dictNew, "ObjectsDeleted", m_strObjectsDeleted); m_strOff = TryGetEx(dictNew, "Off", m_strOff); m_strOfLower = TryGetEx(dictNew, "OfLower", m_strOfLower); m_strOk = TryGetEx(dictNew, "Ok", m_strOk); m_strOldFormat = TryGetEx(dictNew, "OldFormat", m_strOldFormat); m_strOn = TryGetEx(dictNew, "On", m_strOn); m_strOpAborted = TryGetEx(dictNew, "OpAborted", m_strOpAborted); m_strOpenCmd = TryGetEx(dictNew, "OpenCmd", m_strOpenCmd); m_strOpenDatabase = TryGetEx(dictNew, "OpenDatabase", m_strOpenDatabase); m_strOpenDatabaseFile = TryGetEx(dictNew, "OpenDatabaseFile", m_strOpenDatabaseFile); m_strOpenDatabaseFileStc = TryGetEx(dictNew, "OpenDatabaseFileStc", m_strOpenDatabaseFileStc); m_strOpened = TryGetEx(dictNew, "Opened", m_strOpened); m_strOpenedDatabaseFile = TryGetEx(dictNew, "OpenedDatabaseFile", m_strOpenedDatabaseFile); m_strOpeningDatabase = TryGetEx(dictNew, "OpeningDatabase", m_strOpeningDatabase); m_strOpenUrl = TryGetEx(dictNew, "OpenUrl", m_strOpenUrl); m_strOpenWith = TryGetEx(dictNew, "OpenWith", m_strOpenWith); m_strOptimizeForScreenReader = TryGetEx(dictNew, "OptimizeForScreenReader", m_strOptimizeForScreenReader); m_strOptions = TryGetEx(dictNew, "Options", m_strOptions); m_strOptionsDesc = TryGetEx(dictNew, "OptionsDesc", m_strOptionsDesc); m_strOtherPlaceholders = TryGetEx(dictNew, "OtherPlaceholders", m_strOtherPlaceholders); m_strOverridesBuiltIn = TryGetEx(dictNew, "OverridesBuiltIn", m_strOverridesBuiltIn); m_strOverridesCustom = TryGetEx(dictNew, "OverridesCustom", m_strOverridesCustom); m_strOverwrite = TryGetEx(dictNew, "Overwrite", m_strOverwrite); m_strOverwriteExisting = TryGetEx(dictNew, "OverwriteExisting", m_strOverwriteExisting); m_strOverwriteExistingFileQuestion = TryGetEx(dictNew, "OverwriteExistingFileQuestion", m_strOverwriteExistingFileQuestion); m_strOverwriteIfNewer = TryGetEx(dictNew, "OverwriteIfNewer", m_strOverwriteIfNewer); m_strOverwriteIfNewerAndApplyDel = TryGetEx(dictNew, "OverwriteIfNewerAndApplyDel", m_strOverwriteIfNewerAndApplyDel); m_strPackageInstallHint = TryGetEx(dictNew, "PackageInstallHint", m_strPackageInstallHint); m_strParallelism = TryGetEx(dictNew, "Parallelism", m_strParallelism); m_strParamDescHelp = TryGetEx(dictNew, "ParamDescHelp", m_strParamDescHelp); m_strParameters = TryGetEx(dictNew, "Parameters", m_strParameters); m_strPassword = TryGetEx(dictNew, "Password", m_strPassword); m_strPasswordLength = TryGetEx(dictNew, "PasswordLength", m_strPasswordLength); m_strPasswordManagers = TryGetEx(dictNew, "PasswordManagers", m_strPasswordManagers); m_strPasswordOptions = TryGetEx(dictNew, "PasswordOptions", m_strPasswordOptions); m_strPasswordOptionsDesc = TryGetEx(dictNew, "PasswordOptionsDesc", m_strPasswordOptionsDesc); m_strPasswordPrompt = TryGetEx(dictNew, "PasswordPrompt", m_strPasswordPrompt); m_strPasswordQuality = TryGetEx(dictNew, "PasswordQuality", m_strPasswordQuality); m_strPasswordQualityReport = TryGetEx(dictNew, "PasswordQualityReport", m_strPasswordQualityReport); m_strPasswordRepeatFailed = TryGetEx(dictNew, "PasswordRepeatFailed", m_strPasswordRepeatFailed); m_strPasswordRepeatHint = TryGetEx(dictNew, "PasswordRepeatHint", m_strPasswordRepeatHint); m_strPaste = TryGetEx(dictNew, "Paste", m_strPaste); m_strPerformAutoType = TryGetEx(dictNew, "PerformAutoType", m_strPerformAutoType); m_strPerformGlobalAutoType = TryGetEx(dictNew, "PerformGlobalAutoType", m_strPerformGlobalAutoType); m_strPerformSelectedAutoType = TryGetEx(dictNew, "PerformSelectedAutoType", m_strPerformSelectedAutoType); m_strPickCharacters = TryGetEx(dictNew, "PickCharacters", m_strPickCharacters); m_strPickCharactersDesc = TryGetEx(dictNew, "PickCharactersDesc", m_strPickCharactersDesc); m_strPickField = TryGetEx(dictNew, "PickField", m_strPickField); m_strPickFieldDesc = TryGetEx(dictNew, "PickFieldDesc", m_strPickFieldDesc); m_strPickIcon = TryGetEx(dictNew, "PickIcon", m_strPickIcon); m_strPlugin = TryGetEx(dictNew, "Plugin", m_strPlugin); m_strPlugin1x = TryGetEx(dictNew, "Plugin1x", m_strPlugin1x); m_strPlugin1xHint = TryGetEx(dictNew, "Plugin1xHint", m_strPlugin1xHint); m_strPluginCacheClearInfo = TryGetEx(dictNew, "PluginCacheClearInfo", m_strPluginCacheClearInfo); m_strPluginIncompatible = TryGetEx(dictNew, "PluginIncompatible", m_strPluginIncompatible); m_strPluginLoadFailed = TryGetEx(dictNew, "PluginLoadFailed", m_strPluginLoadFailed); m_strPluginOperatingSystemUnsupported = TryGetEx(dictNew, "PluginOperatingSystemUnsupported", m_strPluginOperatingSystemUnsupported); m_strPluginProvided = TryGetEx(dictNew, "PluginProvided", m_strPluginProvided); m_strPlugins = TryGetEx(dictNew, "Plugins", m_strPlugins); m_strPluginsCompilingAndLoading = TryGetEx(dictNew, "PluginsCompilingAndLoading", m_strPluginsCompilingAndLoading); m_strPluginsDesc = TryGetEx(dictNew, "PluginsDesc", m_strPluginsDesc); m_strPluginUpdateHint = TryGetEx(dictNew, "PluginUpdateHint", m_strPluginUpdateHint); m_strPolicyAutoTypeDesc = TryGetEx(dictNew, "PolicyAutoTypeDesc", m_strPolicyAutoTypeDesc); m_strPolicyAutoTypeWithoutContextDesc = TryGetEx(dictNew, "PolicyAutoTypeWithoutContextDesc", m_strPolicyAutoTypeWithoutContextDesc); m_strPolicyChangeMasterKey = TryGetEx(dictNew, "PolicyChangeMasterKey", m_strPolicyChangeMasterKey); m_strPolicyChangeMasterKeyNoKeyDesc = TryGetEx(dictNew, "PolicyChangeMasterKeyNoKeyDesc", m_strPolicyChangeMasterKeyNoKeyDesc); m_strPolicyClipboardDesc = TryGetEx(dictNew, "PolicyClipboardDesc", m_strPolicyClipboardDesc); m_strPolicyCopyWholeEntriesDesc = TryGetEx(dictNew, "PolicyCopyWholeEntriesDesc", m_strPolicyCopyWholeEntriesDesc); m_strPolicyDisallowed = TryGetEx(dictNew, "PolicyDisallowed", m_strPolicyDisallowed); m_strPolicyDragDropDesc = TryGetEx(dictNew, "PolicyDragDropDesc", m_strPolicyDragDropDesc); m_strPolicyExportDesc2 = TryGetEx(dictNew, "PolicyExportDesc2", m_strPolicyExportDesc2); m_strPolicyExportNoKeyDesc = TryGetEx(dictNew, "PolicyExportNoKeyDesc", m_strPolicyExportNoKeyDesc); m_strPolicyImportDesc = TryGetEx(dictNew, "PolicyImportDesc", m_strPolicyImportDesc); m_strPolicyNewDatabaseDesc = TryGetEx(dictNew, "PolicyNewDatabaseDesc", m_strPolicyNewDatabaseDesc); m_strPolicyPluginsDesc = TryGetEx(dictNew, "PolicyPluginsDesc", m_strPolicyPluginsDesc); m_strPolicyPrintDesc = TryGetEx(dictNew, "PolicyPrintDesc", m_strPolicyPrintDesc); m_strPolicyPrintNoKeyDesc = TryGetEx(dictNew, "PolicyPrintNoKeyDesc", m_strPolicyPrintNoKeyDesc); m_strPolicyRequiredFlag = TryGetEx(dictNew, "PolicyRequiredFlag", m_strPolicyRequiredFlag); m_strPolicySaveDatabaseDesc = TryGetEx(dictNew, "PolicySaveDatabaseDesc", m_strPolicySaveDatabaseDesc); m_strPolicyTriggersEditDesc = TryGetEx(dictNew, "PolicyTriggersEditDesc", m_strPolicyTriggersEditDesc); m_strPreReleaseVersion = TryGetEx(dictNew, "PreReleaseVersion", m_strPreReleaseVersion); m_strPrint = TryGetEx(dictNew, "Print", m_strPrint); m_strPrintDesc = TryGetEx(dictNew, "PrintDesc", m_strPrintDesc); m_strPrivate = TryGetEx(dictNew, "Private", m_strPrivate); m_strProfessional = TryGetEx(dictNew, "Professional", m_strProfessional); m_strQuality = TryGetEx(dictNew, "Quality", m_strQuality); m_strQuickSearchExclExpired = TryGetEx(dictNew, "QuickSearchExclExpired", m_strQuickSearchExclExpired); m_strQuickSearchInPwFields = TryGetEx(dictNew, "QuickSearchInPwFields", m_strQuickSearchInPwFields); m_strQuickSearchDerefData = TryGetEx(dictNew, "QuickSearchDerefData", m_strQuickSearchDerefData); m_strQuickSearchTb = TryGetEx(dictNew, "QuickSearchTb", m_strQuickSearchTb); m_strRandomMacAddress = TryGetEx(dictNew, "RandomMacAddress", m_strRandomMacAddress); m_strReady = TryGetEx(dictNew, "Ready", m_strReady); m_strRecommended = TryGetEx(dictNew, "Recommended", m_strRecommended); m_strRecommendedCmd = TryGetEx(dictNew, "RecommendedCmd", m_strRecommendedCmd); m_strRecycleBin = TryGetEx(dictNew, "RecycleBin", m_strRecycleBin); m_strRecycleBinCollapse = TryGetEx(dictNew, "RecycleBinCollapse", m_strRecycleBinCollapse); m_strRecycleEntryConfirm = TryGetEx(dictNew, "RecycleEntryConfirm", m_strRecycleEntryConfirm); m_strRecycleEntryConfirmSingle = TryGetEx(dictNew, "RecycleEntryConfirmSingle", m_strRecycleEntryConfirmSingle); m_strRecycleGroupConfirm = TryGetEx(dictNew, "RecycleGroupConfirm", m_strRecycleGroupConfirm); m_strRecycleShowConfirm = TryGetEx(dictNew, "RecycleShowConfirm", m_strRecycleShowConfirm); m_strRedo = TryGetEx(dictNew, "Redo", m_strRedo); m_strRememberHidingSettings = TryGetEx(dictNew, "RememberHidingSettings", m_strRememberHidingSettings); m_strRememberKeySources = TryGetEx(dictNew, "RememberKeySources", m_strRememberKeySources); m_strRememberWorkingDirectories = TryGetEx(dictNew, "RememberWorkingDirectories", m_strRememberWorkingDirectories); m_strRemoteHostReachable = TryGetEx(dictNew, "RemoteHostReachable", m_strRemoteHostReachable); m_strRepairCmd = TryGetEx(dictNew, "RepairCmd", m_strRepairCmd); m_strRepairMode = TryGetEx(dictNew, "RepairMode", m_strRepairMode); m_strRepairModeInt = TryGetEx(dictNew, "RepairModeInt", m_strRepairModeInt); m_strRepairModeQ = TryGetEx(dictNew, "RepairModeQ", m_strRepairModeQ); m_strRepairModeUse = TryGetEx(dictNew, "RepairModeUse", m_strRepairModeUse); m_strRepeatOnlyWhenHidden = TryGetEx(dictNew, "RepeatOnlyWhenHidden", m_strRepeatOnlyWhenHidden); m_strReplace = TryGetEx(dictNew, "Replace", m_strReplace); m_strReplaceNo = TryGetEx(dictNew, "ReplaceNo", m_strReplaceNo); m_strRestartKeePassQuestion = TryGetEx(dictNew, "RestartKeePassQuestion", m_strRestartKeePassQuestion); m_strRetry = TryGetEx(dictNew, "Retry", m_strRetry); m_strRetryCmd = TryGetEx(dictNew, "RetryCmd", m_strRetryCmd); m_strRootDirectory = TryGetEx(dictNew, "RootDirectory", m_strRootDirectory); m_strSameKeybLayout = TryGetEx(dictNew, "SameKeybLayout", m_strSameKeybLayout); m_strSampleEntry = TryGetEx(dictNew, "SampleEntry", m_strSampleEntry); m_strSave = TryGetEx(dictNew, "Save", m_strSave); m_strSaveBeforeCloseEntry = TryGetEx(dictNew, "SaveBeforeCloseEntry", m_strSaveBeforeCloseEntry); m_strSaveBeforeCloseQuestion = TryGetEx(dictNew, "SaveBeforeCloseQuestion", m_strSaveBeforeCloseQuestion); m_strSaveBeforeCloseTitle = TryGetEx(dictNew, "SaveBeforeCloseTitle", m_strSaveBeforeCloseTitle); m_strSaveCmd = TryGetEx(dictNew, "SaveCmd", m_strSaveCmd); m_strSaveDatabase = TryGetEx(dictNew, "SaveDatabase", m_strSaveDatabase); m_strSaveDatabaseStc = TryGetEx(dictNew, "SaveDatabaseStc", m_strSaveDatabaseStc); m_strSavedDatabaseFile = TryGetEx(dictNew, "SavedDatabaseFile", m_strSavedDatabaseFile); m_strSaveForceSync = TryGetEx(dictNew, "SaveForceSync", m_strSaveForceSync); m_strSavingDatabase = TryGetEx(dictNew, "SavingDatabase", m_strSavingDatabase); m_strSavingDatabaseFile = TryGetEx(dictNew, "SavingDatabaseFile", m_strSavingDatabaseFile); m_strSavingPost = TryGetEx(dictNew, "SavingPost", m_strSavingPost); m_strSavingPre = TryGetEx(dictNew, "SavingPre", m_strSavingPre); m_strScheme = TryGetEx(dictNew, "Scheme", m_strScheme); m_strSearch = TryGetEx(dictNew, "Search", m_strSearch); m_strSearchDesc = TryGetEx(dictNew, "SearchDesc", m_strSearchDesc); m_strSearchEntriesFound = TryGetEx(dictNew, "SearchEntriesFound", m_strSearchEntriesFound); m_strSearchEntriesFound1 = TryGetEx(dictNew, "SearchEntriesFound1", m_strSearchEntriesFound1); m_strSearchGroupName = TryGetEx(dictNew, "SearchGroupName", m_strSearchGroupName); m_strSearchingOp = TryGetEx(dictNew, "SearchingOp", m_strSearchingOp); m_strSearchKeyFiles = TryGetEx(dictNew, "SearchKeyFiles", m_strSearchKeyFiles); m_strSearchKeyFilesAlsoOnRemovable = TryGetEx(dictNew, "SearchKeyFilesAlsoOnRemovable", m_strSearchKeyFilesAlsoOnRemovable); m_strSearchQuickPrompt = TryGetEx(dictNew, "SearchQuickPrompt", m_strSearchQuickPrompt); m_strSearchResultsInSeparator = TryGetEx(dictNew, "SearchResultsInSeparator", m_strSearchResultsInSeparator); m_strSearchTitle = TryGetEx(dictNew, "SearchTitle", m_strSearchTitle); m_strSecDeskFileDialogHint = TryGetEx(dictNew, "SecDeskFileDialogHint", m_strSecDeskFileDialogHint); m_strSecDeskOtherSwitched = TryGetEx(dictNew, "SecDeskOtherSwitched", m_strSecDeskOtherSwitched); m_strSecDeskPlaySound = TryGetEx(dictNew, "SecDeskPlaySound", m_strSecDeskPlaySound); m_strSecDeskSwitchBack = TryGetEx(dictNew, "SecDeskSwitchBack", m_strSecDeskSwitchBack); m_strSelectAll = TryGetEx(dictNew, "SelectAll", m_strSelectAll); m_strSelectColor = TryGetEx(dictNew, "SelectColor", m_strSelectColor); m_strSelectDifferentGroup = TryGetEx(dictNew, "SelectDifferentGroup", m_strSelectDifferentGroup); m_strSelectedColumn = TryGetEx(dictNew, "SelectedColumn", m_strSelectedColumn); m_strSelectedLower = TryGetEx(dictNew, "SelectedLower", m_strSelectedLower); m_strSelectFile = TryGetEx(dictNew, "SelectFile", m_strSelectFile); m_strSelectIcon = TryGetEx(dictNew, "SelectIcon", m_strSelectIcon); m_strSelectLanguage = TryGetEx(dictNew, "SelectLanguage", m_strSelectLanguage); m_strSelectLanguageDesc = TryGetEx(dictNew, "SelectLanguageDesc", m_strSelectLanguageDesc); m_strSelfTestFailed = TryGetEx(dictNew, "SelfTestFailed", m_strSelfTestFailed); m_strSendingNoun = TryGetEx(dictNew, "SendingNoun", m_strSendingNoun); m_strSeparator = TryGetEx(dictNew, "Separator", m_strSeparator); m_strSequence = TryGetEx(dictNew, "Sequence", m_strSequence); m_strShowAdvAutoTypeCommands = TryGetEx(dictNew, "ShowAdvAutoTypeCommands", m_strShowAdvAutoTypeCommands); m_strShowDerefData = TryGetEx(dictNew, "ShowDerefData", m_strShowDerefData); m_strShowDerefDataAndRefs = TryGetEx(dictNew, "ShowDerefDataAndRefs", m_strShowDerefDataAndRefs); m_strShowDerefDataAsync = TryGetEx(dictNew, "ShowDerefDataAsync", m_strShowDerefDataAsync); m_strShowEntries = TryGetEx(dictNew, "ShowEntries", m_strShowEntries); m_strShowEntriesByTag = TryGetEx(dictNew, "ShowEntriesByTag", m_strShowEntriesByTag); m_strShowFullPathInTitleBar = TryGetEx(dictNew, "ShowFullPathInTitleBar", m_strShowFullPathInTitleBar); m_strShowIn = TryGetEx(dictNew, "ShowIn", m_strShowIn); m_strShowMessageBox = TryGetEx(dictNew, "ShowMessageBox", m_strShowMessageBox); m_strShowTrayOnlyIfTrayed = TryGetEx(dictNew, "ShowTrayOnlyIfTrayed", m_strShowTrayOnlyIfTrayed); m_strSimilarPasswords = TryGetEx(dictNew, "SimilarPasswords", m_strSimilarPasswords); m_strSimilarPasswordsGroup = TryGetEx(dictNew, "SimilarPasswordsGroup", m_strSimilarPasswordsGroup); m_strSimilarPasswordsList = TryGetEx(dictNew, "SimilarPasswordsList", m_strSimilarPasswordsList); m_strSimilarPasswordsNoDup = TryGetEx(dictNew, "SimilarPasswordsNoDup", m_strSimilarPasswordsNoDup); m_strSize = TryGetEx(dictNew, "Size", m_strSize); m_strSkip = TryGetEx(dictNew, "Skip", m_strSkip); m_strSlow = TryGetEx(dictNew, "Slow", m_strSlow); m_strSoonToExpireEntries = TryGetEx(dictNew, "SoonToExpireEntries", m_strSoonToExpireEntries); m_strSpecialKeys = TryGetEx(dictNew, "SpecialKeys", m_strSpecialKeys); m_strSslCertsAcceptInvalid = TryGetEx(dictNew, "SslCertsAcceptInvalid", m_strSslCertsAcceptInvalid); m_strStandardExpireSelect = TryGetEx(dictNew, "StandardExpireSelect", m_strStandardExpireSelect); m_strStandardFields = TryGetEx(dictNew, "StandardFields", m_strStandardFields); m_strStartAndExit = TryGetEx(dictNew, "StartAndExit", m_strStartAndExit); m_strStartMinimizedAndLocked = TryGetEx(dictNew, "StartMinimizedAndLocked", m_strStartMinimizedAndLocked); m_strStartsWith = TryGetEx(dictNew, "StartsWith", m_strStartsWith); m_strStatus = TryGetEx(dictNew, "Status", m_strStatus); m_strStrikeout = TryGetEx(dictNew, "Strikeout", m_strStrikeout); m_strString = TryGetEx(dictNew, "String", m_strString); m_strSuccess = TryGetEx(dictNew, "Success", m_strSuccess); m_strSyncFailed = TryGetEx(dictNew, "SyncFailed", m_strSyncFailed); m_strSynchronize = TryGetEx(dictNew, "Synchronize", m_strSynchronize); m_strSynchronizeStc = TryGetEx(dictNew, "SynchronizeStc", m_strSynchronizeStc); m_strSynchronizing = TryGetEx(dictNew, "Synchronizing", m_strSynchronizing); m_strSynchronizingHint = TryGetEx(dictNew, "SynchronizingHint", m_strSynchronizingHint); m_strSyncSuccess = TryGetEx(dictNew, "SyncSuccess", m_strSyncSuccess); m_strSystem = TryGetEx(dictNew, "System", m_strSystem); m_strSystemCodePage = TryGetEx(dictNew, "SystemCodePage", m_strSystemCodePage); m_strTag = TryGetEx(dictNew, "Tag", m_strTag); m_strTagAddNew = TryGetEx(dictNew, "TagAddNew", m_strTagAddNew); m_strTagNew = TryGetEx(dictNew, "TagNew", m_strTagNew); m_strTags = TryGetEx(dictNew, "Tags", m_strTags); m_strTagsNotFound = TryGetEx(dictNew, "TagsNotFound", m_strTagsNotFound); m_strTanExpiresOnUse = TryGetEx(dictNew, "TanExpiresOnUse", m_strTanExpiresOnUse); m_strTanWizard = TryGetEx(dictNew, "TanWizard", m_strTanWizard); m_strTanWizardDesc = TryGetEx(dictNew, "TanWizardDesc", m_strTanWizardDesc); m_strTargetWindow = TryGetEx(dictNew, "TargetWindow", m_strTargetWindow); m_strTemplatesNotFound = TryGetEx(dictNew, "TemplatesNotFound", m_strTemplatesNotFound); m_strTestSuccess = TryGetEx(dictNew, "TestSuccess", m_strTestSuccess); m_strText = TryGetEx(dictNew, "Text", m_strText); m_strTextColor = TryGetEx(dictNew, "TextColor", m_strTextColor); m_strTextViewer = TryGetEx(dictNew, "TextViewer", m_strTextViewer); m_strTimeSpan = TryGetEx(dictNew, "TimeSpan", m_strTimeSpan); m_strTitle = TryGetEx(dictNew, "Title", m_strTitle); m_strToggle = TryGetEx(dictNew, "Toggle", m_strToggle); m_strTogglePasswordAsterisks = TryGetEx(dictNew, "TogglePasswordAsterisks", m_strTogglePasswordAsterisks); m_strToolBarNew = TryGetEx(dictNew, "ToolBarNew", m_strToolBarNew); m_strToolBarOpen = TryGetEx(dictNew, "ToolBarOpen", m_strToolBarOpen); m_strToolBarSaveAll = TryGetEx(dictNew, "ToolBarSaveAll", m_strToolBarSaveAll); m_strTooManyFilesError = TryGetEx(dictNew, "TooManyFilesError", m_strTooManyFilesError); m_strTransformTime = TryGetEx(dictNew, "TransformTime", m_strTransformTime); m_strTrayIcon = TryGetEx(dictNew, "TrayIcon", m_strTrayIcon); m_strTrayIconGray = TryGetEx(dictNew, "TrayIconGray", m_strTrayIconGray); m_strTrayIconSingleClick = TryGetEx(dictNew, "TrayIconSingleClick", m_strTrayIconSingleClick); m_strTrigger = TryGetEx(dictNew, "Trigger", m_strTrigger); m_strTriggerActionTypeUnknown = TryGetEx(dictNew, "TriggerActionTypeUnknown", m_strTriggerActionTypeUnknown); m_strTriggerAdd = TryGetEx(dictNew, "TriggerAdd", m_strTriggerAdd); m_strTriggerAddDesc = TryGetEx(dictNew, "TriggerAddDesc", m_strTriggerAddDesc); m_strTriggerConditionTypeUnknown = TryGetEx(dictNew, "TriggerConditionTypeUnknown", m_strTriggerConditionTypeUnknown); m_strTriggerEdit = TryGetEx(dictNew, "TriggerEdit", m_strTriggerEdit); m_strTriggerEditDesc = TryGetEx(dictNew, "TriggerEditDesc", m_strTriggerEditDesc); m_strTriggerEventTypeUnknown = TryGetEx(dictNew, "TriggerEventTypeUnknown", m_strTriggerEventTypeUnknown); m_strTriggerExecutionFailed = TryGetEx(dictNew, "TriggerExecutionFailed", m_strTriggerExecutionFailed); m_strTriggering = TryGetEx(dictNew, "Triggering", m_strTriggering); m_strTriggerName = TryGetEx(dictNew, "TriggerName", m_strTriggerName); m_strTriggers = TryGetEx(dictNew, "Triggers", m_strTriggers); m_strTriggersDesc = TryGetEx(dictNew, "TriggersDesc", m_strTriggersDesc); m_strTriggersEdit = TryGetEx(dictNew, "TriggersEdit", m_strTriggersEdit); m_strTriggerStateChange = TryGetEx(dictNew, "TriggerStateChange", m_strTriggerStateChange); m_strTypeUnknownHint = TryGetEx(dictNew, "TypeUnknownHint", m_strTypeUnknownHint); m_strUnderline = TryGetEx(dictNew, "Underline", m_strUnderline); m_strUndo = TryGetEx(dictNew, "Undo", m_strUndo); m_strUnhidePasswords = TryGetEx(dictNew, "UnhidePasswords", m_strUnhidePasswords); m_strUnhidePasswordsDesc = TryGetEx(dictNew, "UnhidePasswordsDesc", m_strUnhidePasswordsDesc); m_strUnhideSourceCharactersToo = TryGetEx(dictNew, "UnhideSourceCharactersToo", m_strUnhideSourceCharactersToo); m_strUnknown = TryGetEx(dictNew, "Unknown", m_strUnknown); m_strUnknownError = TryGetEx(dictNew, "UnknownError", m_strUnknownError); m_strUnsupportedByMono = TryGetEx(dictNew, "UnsupportedByMono", m_strUnsupportedByMono); m_strUpdateCheck = TryGetEx(dictNew, "UpdateCheck", m_strUpdateCheck); m_strUpdateCheckEnableQ = TryGetEx(dictNew, "UpdateCheckEnableQ", m_strUpdateCheckEnableQ); m_strUpdateCheckFailedNoDl = TryGetEx(dictNew, "UpdateCheckFailedNoDl", m_strUpdateCheckFailedNoDl); m_strUpdateCheckInfo = TryGetEx(dictNew, "UpdateCheckInfo", m_strUpdateCheckInfo); m_strUpdateCheckInfoPriv = TryGetEx(dictNew, "UpdateCheckInfoPriv", m_strUpdateCheckInfoPriv); m_strUpdateCheckInfoRes = TryGetEx(dictNew, "UpdateCheckInfoRes", m_strUpdateCheckInfoRes); m_strUpdateCheckResults = TryGetEx(dictNew, "UpdateCheckResults", m_strUpdateCheckResults); m_strUpdatedUIState = TryGetEx(dictNew, "UpdatedUIState", m_strUpdatedUIState); m_strUpToDate = TryGetEx(dictNew, "UpToDate", m_strUpToDate); m_strUrl = TryGetEx(dictNew, "Url", m_strUrl); m_strUrlOpenDesc = TryGetEx(dictNew, "UrlOpenDesc", m_strUrlOpenDesc); m_strUrlOpenTitle = TryGetEx(dictNew, "UrlOpenTitle", m_strUrlOpenTitle); m_strUrlOverride = TryGetEx(dictNew, "UrlOverride", m_strUrlOverride); m_strUrlOverrides = TryGetEx(dictNew, "UrlOverrides", m_strUrlOverrides); m_strUrlSaveDesc = TryGetEx(dictNew, "UrlSaveDesc", m_strUrlSaveDesc); m_strUrlSaveTitle = TryGetEx(dictNew, "UrlSaveTitle", m_strUrlSaveTitle); m_strUseFileLocks = TryGetEx(dictNew, "UseFileLocks", m_strUseFileLocks); m_strUseTransactedDatabaseWrites = TryGetEx(dictNew, "UseTransactedDatabaseWrites", m_strUseTransactedDatabaseWrites); m_strUserName = TryGetEx(dictNew, "UserName", m_strUserName); m_strUserNamePrompt = TryGetEx(dictNew, "UserNamePrompt", m_strUserNamePrompt); m_strUserNameStc = TryGetEx(dictNew, "UserNameStc", m_strUserNameStc); m_strUuid = TryGetEx(dictNew, "Uuid", m_strUuid); m_strUuidDupInDb = TryGetEx(dictNew, "UuidDupInDb", m_strUuidDupInDb); m_strUuidFix = TryGetEx(dictNew, "UuidFix", m_strUuidFix); m_strValidationFailed = TryGetEx(dictNew, "ValidationFailed", m_strValidationFailed); m_strValue = TryGetEx(dictNew, "Value", m_strValue); m_strVerb = TryGetEx(dictNew, "Verb", m_strVerb); m_strVerifyWrittenFileAfterSave = TryGetEx(dictNew, "VerifyWrittenFileAfterSave", m_strVerifyWrittenFileAfterSave); m_strVersion = TryGetEx(dictNew, "Version", m_strVersion); m_strView = TryGetEx(dictNew, "View", m_strView); m_strViewCmd = TryGetEx(dictNew, "ViewCmd", m_strViewCmd); m_strViewEntry = TryGetEx(dictNew, "ViewEntry", m_strViewEntry); m_strViewEntryDesc = TryGetEx(dictNew, "ViewEntryDesc", m_strViewEntryDesc); m_strWait = TryGetEx(dictNew, "Wait", m_strWait); m_strWaitForExit = TryGetEx(dictNew, "WaitForExit", m_strWaitForExit); m_strWarning = TryGetEx(dictNew, "Warning", m_strWarning); m_strWarnings = TryGetEx(dictNew, "Warnings", m_strWarnings); m_strWebBrowser = TryGetEx(dictNew, "WebBrowser", m_strWebBrowser); m_strWebSiteLogin = TryGetEx(dictNew, "WebSiteLogin", m_strWebSiteLogin); m_strWebSites = TryGetEx(dictNew, "WebSites", m_strWebSites); m_strWindowsFavorites = TryGetEx(dictNew, "WindowsFavorites", m_strWindowsFavorites); m_strWindowsOS = TryGetEx(dictNew, "WindowsOS", m_strWindowsOS); m_strWindowStyle = TryGetEx(dictNew, "WindowStyle", m_strWindowStyle); m_strWindowsUserAccount = TryGetEx(dictNew, "WindowsUserAccount", m_strWindowsUserAccount); m_strWindowsUserAccountBackup = TryGetEx(dictNew, "WindowsUserAccountBackup", m_strWindowsUserAccountBackup); m_strWithoutContext = TryGetEx(dictNew, "WithoutContext", m_strWithoutContext); m_strWorkspaceLocked = TryGetEx(dictNew, "WorkspaceLocked", m_strWorkspaceLocked); m_strXmlModInvalid = TryGetEx(dictNew, "XmlModInvalid", m_strXmlModInvalid); m_strXmlReplace = TryGetEx(dictNew, "XmlReplace", m_strXmlReplace); m_strXmlReplaceDesc = TryGetEx(dictNew, "XmlReplaceDesc", m_strXmlReplaceDesc); m_strXslExporter = TryGetEx(dictNew, "XslExporter", m_strXslExporter); m_strXslFileType = TryGetEx(dictNew, "XslFileType", m_strXslFileType); m_strXslSelectFile = TryGetEx(dictNew, "XslSelectFile", m_strXslSelectFile); m_strXslStylesheetsKdbx = TryGetEx(dictNew, "XslStylesheetsKdbx", m_strXslStylesheetsKdbx); m_strYes = TryGetEx(dictNew, "Yes", m_strYes); m_strYesCmd = TryGetEx(dictNew, "YesCmd", m_strYesCmd); m_strZoom = TryGetEx(dictNew, "Zoom", m_strZoom); } private static readonly string[] m_vKeyNames = { "Abort", "AbortTrigger", "Action", "ActivateDatabaseTab", "Active", "AddEntry", "AddEntryDesc", "AddGroup", "AddGroupDesc", "AddStringField", "AddStringFieldDesc", "Advanced", "AfterDatabaseOpen", "AlignCenter", "AlignLeft", "AlignRight", "All", "AllEntriesTitle", "AllFiles", "AllSupportedFiles", "AlternatingBgColors", "Application", "ApplicationExit", "ApplicationInitialized", "ApplicationStarted", "Arguments", "Ascending", "AskContinue", "Asterisks", "AttachedExistsAlready", "AttachExtDiscardDesc", "AttachExtImportDesc", "AttachExtOpened", "AttachExtOpenedPost", "AttachExtSecDel", "AttachFailed", "AttachFiles", "Attachments", "AttachmentSave", "AttachmentsSave", "AttachNewRename", "AttachNewRenameRemarks0", "AttachNewRenameRemarks1", "AttachNewRenameRemarks2", "Author", "Auto", "AutoCreateNew", "AutoGeneratedPasswordSettings", "AutoRememberOpenLastFile", "AutoSaveAtExit", "AutoShowExpiredEntries", "AutoShowSoonToExpireEntries", "AutoType", "AutoTypeAbortedOnWindow", "AutoTypeAlwaysShowSelDialog", "AutoTypeCancelOnTitleChange", "AutoTypeCancelOnWindowChange", "AutoTypeEntrySelection", "AutoTypeEntrySelectionDescLong2", "AutoTypeEntrySelectionDescShort", "AutoTypeGlobalHint", "AutoTypeMatchByTagInTitle", "AutoTypeMatchByTitle", "AutoTypeMatchByUrlHostInTitle", "AutoTypeMatchByUrlInTitle", "AutoTypeObfuscationHint", "AutoTypePrependInitSeqForIE", "AutoTypeReleaseAltWithKeyPress", "AutoTypeSelectedNoEntry", "AutoTypeSequenceInvalid", "AutoTypeUnknownPlaceholder", "AutoTypeXDoToolRequired", "AutoTypeXDoToolRequiredGlobalVer", "Available", "BackgroundColor", "BackupDatabase", "BackupFile", "BackupLocation", "BinaryNoConv", "Bits", "BitsStc", "Bold", "BothForms", "Browser", "BuiltIn", "BuiltInU", "Button", "ButtonBack", "ButtonDefault", "ButtonFinish", "ButtonNext", "Buttons", "Cancel", "CannotMoveEntriesBcsGroup", "ChangeMasterKey", "ChangeMasterKeyIntroShort", "CharsAbbr", "CharsStc", "CheckForUpdAtStart", "CheckingForUpd", "ClassicAdj", "ClearKeyCmdLineParams", "ClearMru", "Clipboard", "ClipboardClearInSeconds", "ClipboardClearOnExit", "ClipboardDataCopied", "ClipboardViewerIgnoreFormat", "CloseActiveDatabase", "CloseButton", "CloseButtonMinimizes", "ClosingDatabaseFile", "ClusterCenters", "ClusterCentersDesc", "Column", "Columns", "Comments", "Company", "Comparison", "Component", "Condition", "ConfigAffectAdmin", "ConfigAffectUser", "ConfigSaveFailed", "ConfigureAutoType", "ConfigureAutoTypeDesc", "ConfigureAutoTypeItem", "ConfigureAutoTypeItemDesc", "ConfigureColumns", "ConfigureColumnsDesc", "ConfigureKeystrokeSeq", "ConfigureKeystrokeSeqDesc", "ConfigureOnNewDatabase2", "Contact", "ContainsOp", "CopiedEntryData", "Copy", "CopyAll", "CopyLink", "CopyOfItem", "CopyPasswordFull", "CopyPasswordMenu", "CopyTanMenu", "CopyUrlsInsteadOfOpening", "CopyUrlToClipboard", "CopyUserFull", "CopyWholeEntries", "CorruptionByExt", "Count", "CreateMasterKey", "CreateNewDatabase", "CreateNewIDs", "CreationTime", "CredSaveAll", "CredSaveNone", "CredSaveUserOnly", "CredSpecifyDifferent", "CsprojCountError", "CsvTextFile", "CtrlAltAConflict", "CtrlAltAConflictHint", "CurrentStyle", "Custom", "CustomFields", "CustomizableHtml", "CustomTbButtonAdd", "CustomTbButtonClicked", "CustomTbButtonRemove", "Cut", "Data", "Database", "DatabaseDescPrompt", "DatabaseFile", "DatabaseFileIntro", "DatabaseFileRem", "DatabaseHasUnsavedChanges", "DatabaseMaintenance", "DatabaseMaintenanceDesc", "DatabaseModifiedNoDot", "DatabaseNamePrompt", "DatabaseSettings", "DatabaseSettingsDesc", "DataEditor", "DataLoss", "DataViewer", "DbMntncResults", "DbNoModBy", "Default", "Delete", "DeleteCmd", "DeleteEntriesTitle", "DeleteEntriesTitleSingle", "DeleteEntriesQuestion", "DeleteEntriesQuestionSingle", "DeleteGroupTitle", "DeleteGroupInfo", "DeleteGroupQuestion", "Descending", "Description", "Details", "DialogNoShowAgain", "Dialogs", "Disable", "Disabled", "DisableSaveIfNotModified", "DiscardChangesCmd", "DocumentationHint", "DragDrop", "DropToBackOnCopy", "DuplicatePasswords", "DuplicatePasswordsGroup", "DuplicatePasswordsList", "DuplicatePasswordsNone", "DuplicateStringFieldName", "EditCmd", "EditEntry", "EditEntryDesc", "EditGroup", "EditGroupDesc", "EditStringField", "EditStringFieldDesc", "EMail", "EmergencySheet", "EmergencySheetAsk", "EmergencySheetInfo", "EmergencySheetPrintInfo", "EmergencySheetQ", "EmergencySheetRec", "Empty", "EmptyMasterPw", "EmptyMasterPwHint", "EmptyMasterPwQuestion", "EmptyRecycleBinQuestion", "Enable", "Enabled", "Encoding", "EncodingFail", "EndsWith", "EnterCompositeKey", "EnterCurrentCompositeKey", "EntropyDesc", "EntropyTitle", "Entry", "EntryList", "EntryListAutoResizeColumns", "EntrySelGroupSel", "EnvironmentVariable", "EqualsOp", "Error", "ErrorCode", "Errors", "EscMinimizesToTray", "Event", "ExecuteCmdLineUrl", "ExitInsteadOfLockingAfterTime", "ExitInsteadOfLockingAlways", "ExpiredEntries", "ExpiredEntriesCanMatch", "ExpiryTime", "ExpiryTimeDateOnly", "Export", "ExportFileDesc", "ExportFileTitle", "ExportHtml", "ExportHtmlDesc", "ExportingStatusMsg", "ExportStc", "ExportToPrompt", "External", "ExternalApp", "FatalError", "Feature", "Field", "FieldName", "FieldNameExistsAlready", "FieldNameInvalid", "FieldNamePrompt", "FieldRefInvalidChars", "FieldRefMultiMatch", "FieldRefMultiMatchHint", "FieldValue", "File", "FileChanged", "FileChangedOverwrite", "FileChangedSync", "FileExists", "FileExistsAlready", "FileExtInstallFailed", "FileExtInstallSuccess", "FileExtName", "FileFormatStc", "FileLockedBy", "FileLockedWarning", "FileNameContainsSemicolonError", "FileNotFoundError", "FileOrUrl", "Files", "FileSaveQ", "FileSaveQClosing", "FileSaveQExiting", "FileSaveQLocking", "FileSaveQOpCancel", "FileSaveQOpCancelClosing", "FileSaveQOpCancelExiting", "FileSaveQOpCancelLocking", "FileSaveQOpNoClosing", "FileSaveQOpNoExiting", "FileSaveQOpNoLocking", "FileSaveQOpYesClosing", "FileSaveQOpYesExiting", "FileSaveQOpYesLocking", "FileTooLarge", "FileTxExtra", "FileVerifyHashFail", "FileVerifyHashFailRec", "Filter", "Find", "FocusQuickFindOnRestore", "FocusQuickFindOnUntray", "FocusResultsAfterQuickSearch", "Folder", "Font", "FontDefault", "ForceSystemFontUnix", "Format", "FormatNoDatabaseDesc", "FormatNoDatabaseName", "FormatNoRootEntries", "FormatNoSubGroupsInRoot", "FormatOnlyOneAttachment", "General", "Generate", "GenerateCount", "GenerateCountDesc", "GenerateCountLongDesc", "GeneratedPasswordSamples", "GeneratePassword", "GenericCsvImporter", "GenProfileRemove", "GenProfileRemoveDesc", "GenProfileSave", "GenProfileSaveDesc", "GenProfileSaveDescLong", "GenPwAccept", "GenPwBasedOnPrevious", "GenPwSprVariant", "Gradient", "Group", "GroupCannotStoreEntries", "GroupsSkipped", "GroupsSkipped1", "HelpSourceNoLocalOption", "HelpSourceSelection", "HelpSourceSelectionDesc", "HexKeyEx", "HexViewer", "Hidden", "HideCloseDatabaseTb", "HideUsingAsterisks", "History", "Homebanking", "Host", "HotKeyAltOnly", "HotKeyAltOnlyHint", "HotKeyAltOnlyQuestion", "Icon", "Id", "Ignore", "ImageFormatFeatureUnsupported", "ImageViewer", "Import", "ImportBehavior", "ImportBehaviorDesc", "ImportFailed", "ImportFileDesc", "ImportFilesPrompt", "ImportFileTitle", "ImportFinished", "ImportingStatusMsg", "ImportMustRead", "ImportMustReadQuestion", "ImportStc", "IncompatibleEnv", "IncompatibleWithSorting", "InheritSettingFromParent", "Installed", "InstalledLanguages", "InstrAndGenInfo", "InterleavedKeySending", "InternalEditor", "InternalViewer", "Internet", "InvalidKey", "InvalidUrl", "InvalidUserPassword", "IOConnection", "IOConnectionLong", "Italic", "Iterations", "KdbKeePassLibC", "KdbWUA", "KdbxFiles", "KdfAdjust", "KdfParams1Sec", "KeePassLibCLong", "KeePassLibCNotFound", "KeePassLibCNotWindows", "KeePassLibCNotWindowsHint", "KeepExisting", "KeyboardKeyAlt", "KeyboardKeyCtrl", "KeyboardKeyCtrlLeft", "KeyboardKeyEsc", "KeyboardKeyModifiers", "KeyboardKeyReturn", "KeyboardKeyShift", "KeyboardKeyShiftLeft", "KeyFile", "KeyFileCreate", "KeyFileError", "KeyFiles", "KeyFileSelect", "KeyFileUseExisting", "KeyProvider", "KeyProvIncmpWithSD", "KeyProvIncmpWithSDHint", "LanguageSelected", "LastAccessTime", "LastModificationTime", "LastModTimePwHist", "LatestVersionWeb", "LimitSingleInstance", "LngInAppDir", "LngInAppDirNote", "LngInAppDirQ", "Locked", "LockMenuLock", "LockMenuUnlock", "LockOnMinimizeTaskbar", "LockOnMinimizeTray", "LockOnRemoteControlChange", "LockOnSessionSwitch", "LockOnSuspend", "MainInstruction", "MainWindow", "MasterKey", "MasterKeyChanged", "MasterKeyChangedSave", "MasterKeyChangedShort", "MasterKeyChangeForce", "MasterKeyChangeInfo", "MasterKeyChangeQ", "MasterKeyChangeRec", "MasterKeyComponents", "MasterKeyOnSecureDesktop", "MasterPassword", "MasterPasswordMinLengthFailed", "MasterPasswordMinQualityFailed", "MaxAttachmentSize", "Maximized", "Memory", "Menus", "Method", "MinimizeAfterCopy", "MinimizeAfterLocking", "MinimizeAfterOpeningDatabase", "Minimized", "MinimizeToTray", "More", "MoreEntries", "Name", "NativeLibUse", "Navigation", "Network", "NeverExpires", "New", "NewDatabase", "NewDatabaseFileName", "NewerNetRequired", "NewGroup", "NewLine", "NewState", "NewVersionAvailable", "No", "NoCmd", "NoEncNoCompress", "NoFileAccessRead", "NoKeyFileSpecifiedMeta", "NoKeyRepeat", "None", "Normal", "NoSort", "Not", "NotNow", "NotRecommended", "Notes", "NotInstalled", "NoXslFile", "ObjectNotFound", "ObjectsDeleted", "Off", "OfLower", "Ok", "OldFormat", "On", "OpAborted", "OpenCmd", "OpenDatabase", "OpenDatabaseFile", "OpenDatabaseFileStc", "Opened", "OpenedDatabaseFile", "OpeningDatabase", "OpenUrl", "OpenWith", "OptimizeForScreenReader", "Options", "OptionsDesc", "OtherPlaceholders", "OverridesBuiltIn", "OverridesCustom", "Overwrite", "OverwriteExisting", "OverwriteExistingFileQuestion", "OverwriteIfNewer", "OverwriteIfNewerAndApplyDel", "PackageInstallHint", "Parallelism", "ParamDescHelp", "Parameters", "Password", "PasswordLength", "PasswordManagers", "PasswordOptions", "PasswordOptionsDesc", "PasswordPrompt", "PasswordQuality", "PasswordQualityReport", "PasswordRepeatFailed", "PasswordRepeatHint", "Paste", "PerformAutoType", "PerformGlobalAutoType", "PerformSelectedAutoType", "PickCharacters", "PickCharactersDesc", "PickField", "PickFieldDesc", "PickIcon", "Plugin", "Plugin1x", "Plugin1xHint", "PluginCacheClearInfo", "PluginIncompatible", "PluginLoadFailed", "PluginOperatingSystemUnsupported", "PluginProvided", "Plugins", "PluginsCompilingAndLoading", "PluginsDesc", "PluginUpdateHint", "PolicyAutoTypeDesc", "PolicyAutoTypeWithoutContextDesc", "PolicyChangeMasterKey", "PolicyChangeMasterKeyNoKeyDesc", "PolicyClipboardDesc", "PolicyCopyWholeEntriesDesc", "PolicyDisallowed", "PolicyDragDropDesc", "PolicyExportDesc2", "PolicyExportNoKeyDesc", "PolicyImportDesc", "PolicyNewDatabaseDesc", "PolicyPluginsDesc", "PolicyPrintDesc", "PolicyPrintNoKeyDesc", "PolicyRequiredFlag", "PolicySaveDatabaseDesc", "PolicyTriggersEditDesc", "PreReleaseVersion", "Print", "PrintDesc", "Private", "Professional", "Quality", "QuickSearchExclExpired", "QuickSearchInPwFields", "QuickSearchDerefData", "QuickSearchTb", "RandomMacAddress", "Ready", "Recommended", "RecommendedCmd", "RecycleBin", "RecycleBinCollapse", "RecycleEntryConfirm", "RecycleEntryConfirmSingle", "RecycleGroupConfirm", "RecycleShowConfirm", "Redo", "RememberHidingSettings", "RememberKeySources", "RememberWorkingDirectories", "RemoteHostReachable", "RepairCmd", "RepairMode", "RepairModeInt", "RepairModeQ", "RepairModeUse", "RepeatOnlyWhenHidden", "Replace", "ReplaceNo", "RestartKeePassQuestion", "Retry", "RetryCmd", "RootDirectory", "SameKeybLayout", "SampleEntry", "Save", "SaveBeforeCloseEntry", "SaveBeforeCloseQuestion", "SaveBeforeCloseTitle", "SaveCmd", "SaveDatabase", "SaveDatabaseStc", "SavedDatabaseFile", "SaveForceSync", "SavingDatabase", "SavingDatabaseFile", "SavingPost", "SavingPre", "Scheme", "Search", "SearchDesc", "SearchEntriesFound", "SearchEntriesFound1", "SearchGroupName", "SearchingOp", "SearchKeyFiles", "SearchKeyFilesAlsoOnRemovable", "SearchQuickPrompt", "SearchResultsInSeparator", "SearchTitle", "SecDeskFileDialogHint", "SecDeskOtherSwitched", "SecDeskPlaySound", "SecDeskSwitchBack", "SelectAll", "SelectColor", "SelectDifferentGroup", "SelectedColumn", "SelectedLower", "SelectFile", "SelectIcon", "SelectLanguage", "SelectLanguageDesc", "SelfTestFailed", "SendingNoun", "Separator", "Sequence", "ShowAdvAutoTypeCommands", "ShowDerefData", "ShowDerefDataAndRefs", "ShowDerefDataAsync", "ShowEntries", "ShowEntriesByTag", "ShowFullPathInTitleBar", "ShowIn", "ShowMessageBox", "ShowTrayOnlyIfTrayed", "SimilarPasswords", "SimilarPasswordsGroup", "SimilarPasswordsList", "SimilarPasswordsNoDup", "Size", "Skip", "Slow", "SoonToExpireEntries", "SpecialKeys", "SslCertsAcceptInvalid", "StandardExpireSelect", "StandardFields", "StartAndExit", "StartMinimizedAndLocked", "StartsWith", "Status", "Strikeout", "String", "Success", "SyncFailed", "Synchronize", "SynchronizeStc", "Synchronizing", "SynchronizingHint", "SyncSuccess", "System", "SystemCodePage", "Tag", "TagAddNew", "TagNew", "Tags", "TagsNotFound", "TanExpiresOnUse", "TanWizard", "TanWizardDesc", "TargetWindow", "TemplatesNotFound", "TestSuccess", "Text", "TextColor", "TextViewer", "TimeSpan", "Title", "Toggle", "TogglePasswordAsterisks", "ToolBarNew", "ToolBarOpen", "ToolBarSaveAll", "TooManyFilesError", "TransformTime", "TrayIcon", "TrayIconGray", "TrayIconSingleClick", "Trigger", "TriggerActionTypeUnknown", "TriggerAdd", "TriggerAddDesc", "TriggerConditionTypeUnknown", "TriggerEdit", "TriggerEditDesc", "TriggerEventTypeUnknown", "TriggerExecutionFailed", "Triggering", "TriggerName", "Triggers", "TriggersDesc", "TriggersEdit", "TriggerStateChange", "TypeUnknownHint", "Underline", "Undo", "UnhidePasswords", "UnhidePasswordsDesc", "UnhideSourceCharactersToo", "Unknown", "UnknownError", "UnsupportedByMono", "UpdateCheck", "UpdateCheckEnableQ", "UpdateCheckFailedNoDl", "UpdateCheckInfo", "UpdateCheckInfoPriv", "UpdateCheckInfoRes", "UpdateCheckResults", "UpdatedUIState", "UpToDate", "Url", "UrlOpenDesc", "UrlOpenTitle", "UrlOverride", "UrlOverrides", "UrlSaveDesc", "UrlSaveTitle", "UseFileLocks", "UseTransactedDatabaseWrites", "UserName", "UserNamePrompt", "UserNameStc", "Uuid", "UuidDupInDb", "UuidFix", "ValidationFailed", "Value", "Verb", "VerifyWrittenFileAfterSave", "Version", "View", "ViewCmd", "ViewEntry", "ViewEntryDesc", "Wait", "WaitForExit", "Warning", "Warnings", "WebBrowser", "WebSiteLogin", "WebSites", "WindowsFavorites", "WindowsOS", "WindowStyle", "WindowsUserAccount", "WindowsUserAccountBackup", "WithoutContext", "WorkspaceLocked", "XmlModInvalid", "XmlReplace", "XmlReplaceDesc", "XslExporter", "XslFileType", "XslSelectFile", "XslStylesheetsKdbx", "Yes", "YesCmd", "Zoom" }; public static string[] GetKeyNames() { return m_vKeyNames; } private static string m_strAbort = @"Abort"; /// /// Look up a localized string similar to /// 'Abort'. /// public static string Abort { get { return m_strAbort; } } private static string m_strAbortTrigger = @"Abort current trigger execution"; /// /// Look up a localized string similar to /// 'Abort current trigger execution'. /// public static string AbortTrigger { get { return m_strAbortTrigger; } } private static string m_strAction = @"Action"; /// /// Look up a localized string similar to /// 'Action'. /// public static string Action { get { return m_strAction; } } private static string m_strActivateDatabaseTab = @"Activate database (select tab)"; /// /// Look up a localized string similar to /// 'Activate database (select tab)'. /// public static string ActivateDatabaseTab { get { return m_strActivateDatabaseTab; } } private static string m_strActive = @"Active"; /// /// Look up a localized string similar to /// 'Active'. /// public static string Active { get { return m_strActive; } } private static string m_strAddEntry = @"Add Entry"; /// /// Look up a localized string similar to /// 'Add Entry'. /// public static string AddEntry { get { return m_strAddEntry; } } private static string m_strAddEntryDesc = @"Create a new entry."; /// /// Look up a localized string similar to /// 'Create a new entry.'. /// public static string AddEntryDesc { get { return m_strAddEntryDesc; } } private static string m_strAddGroup = @"Add Group"; /// /// Look up a localized string similar to /// 'Add Group'. /// public static string AddGroup { get { return m_strAddGroup; } } private static string m_strAddGroupDesc = @"Create a new entry group."; /// /// Look up a localized string similar to /// 'Create a new entry group.'. /// public static string AddGroupDesc { get { return m_strAddGroupDesc; } } private static string m_strAddStringField = @"Add Entry String Field"; /// /// Look up a localized string similar to /// 'Add Entry String Field'. /// public static string AddStringField { get { return m_strAddStringField; } } private static string m_strAddStringFieldDesc = @"Create a new string field for the current entry."; /// /// Look up a localized string similar to /// 'Create a new string field for the current entry.'. /// public static string AddStringFieldDesc { get { return m_strAddStringFieldDesc; } } private static string m_strAdvanced = @"Advanced"; /// /// Look up a localized string similar to /// 'Advanced'. /// public static string Advanced { get { return m_strAdvanced; } } private static string m_strAfterDatabaseOpen = @"After Opening a Database"; /// /// Look up a localized string similar to /// 'After Opening a Database'. /// public static string AfterDatabaseOpen { get { return m_strAfterDatabaseOpen; } } private static string m_strAlignCenter = @"Align Center"; /// /// Look up a localized string similar to /// 'Align Center'. /// public static string AlignCenter { get { return m_strAlignCenter; } } private static string m_strAlignLeft = @"Align Left"; /// /// Look up a localized string similar to /// 'Align Left'. /// public static string AlignLeft { get { return m_strAlignLeft; } } private static string m_strAlignRight = @"Align Right"; /// /// Look up a localized string similar to /// 'Align Right'. /// public static string AlignRight { get { return m_strAlignRight; } } private static string m_strAll = @"All"; /// /// Look up a localized string similar to /// 'All'. /// public static string All { get { return m_strAll; } } private static string m_strAllEntriesTitle = @"All Entries"; /// /// Look up a localized string similar to /// 'All Entries'. /// public static string AllEntriesTitle { get { return m_strAllEntriesTitle; } } private static string m_strAllFiles = @"All Files"; /// /// Look up a localized string similar to /// 'All Files'. /// public static string AllFiles { get { return m_strAllFiles; } } private static string m_strAllSupportedFiles = @"All Supported Files"; /// /// Look up a localized string similar to /// 'All Supported Files'. /// public static string AllSupportedFiles { get { return m_strAllSupportedFiles; } } private static string m_strAlternatingBgColors = @"Use alternating item background colors"; /// /// Look up a localized string similar to /// 'Use alternating item background colors'. /// public static string AlternatingBgColors { get { return m_strAlternatingBgColors; } } private static string m_strApplication = @"Application"; /// /// Look up a localized string similar to /// 'Application'. /// public static string Application { get { return m_strApplication; } } private static string m_strApplicationExit = @"Application exit"; /// /// Look up a localized string similar to /// 'Application exit'. /// public static string ApplicationExit { get { return m_strApplicationExit; } } private static string m_strApplicationInitialized = @"Application initialized"; /// /// Look up a localized string similar to /// 'Application initialized'. /// public static string ApplicationInitialized { get { return m_strApplicationInitialized; } } private static string m_strApplicationStarted = @"Application started and ready"; /// /// Look up a localized string similar to /// 'Application started and ready'. /// public static string ApplicationStarted { get { return m_strApplicationStarted; } } private static string m_strArguments = @"Arguments"; /// /// Look up a localized string similar to /// 'Arguments'. /// public static string Arguments { get { return m_strArguments; } } private static string m_strAscending = @"&Ascending"; /// /// Look up a localized string similar to /// '&Ascending'. /// public static string Ascending { get { return m_strAscending; } } private static string m_strAskContinue = @"Do you want to continue?"; /// /// Look up a localized string similar to /// 'Do you want to continue?'. /// public static string AskContinue { get { return m_strAskContinue; } } private static string m_strAsterisks = @"Asterisks"; /// /// Look up a localized string similar to /// 'Asterisks'. /// public static string Asterisks { get { return m_strAsterisks; } } private static string m_strAttachedExistsAlready = @"The following file has already been attached to the current entry:"; /// /// Look up a localized string similar to /// 'The following file has already been attached to the current entry:'. /// public static string AttachedExistsAlready { get { return m_strAttachedExistsAlready; } } private static string m_strAttachExtDiscardDesc = @"Discard any changes made to the temporary file and do not modify the current attachment."; /// /// Look up a localized string similar to /// 'Discard any changes made to the temporary file and do not modify the current attachment.'. /// public static string AttachExtDiscardDesc { get { return m_strAttachExtDiscardDesc; } } private static string m_strAttachExtImportDesc = @"Replace the attachment by the (modified) temporary file."; /// /// Look up a localized string similar to /// 'Replace the attachment by the (modified) temporary file.'. /// public static string AttachExtImportDesc { get { return m_strAttachExtImportDesc; } } private static string m_strAttachExtOpened = @"KeePass has extracted the attachment to a (EFS-encrypted) temporary file and opened it using an external application."; /// /// Look up a localized string similar to /// 'KeePass has extracted the attachment to a (EFS-encrypted) temporary file and opened it using an external application.'. /// public static string AttachExtOpened { get { return m_strAttachExtOpened; } } private static string m_strAttachExtOpenedPost = @"After viewing/editing and closing the file in the external application, please choose how to continue"; /// /// Look up a localized string similar to /// 'After viewing/editing and closing the file in the external application, please choose how to continue'. /// public static string AttachExtOpenedPost { get { return m_strAttachExtOpenedPost; } } private static string m_strAttachExtSecDel = @"In any case, KeePass will securely delete the temporary file afterwards."; /// /// Look up a localized string similar to /// 'In any case, KeePass will securely delete the temporary file afterwards.'. /// public static string AttachExtSecDel { get { return m_strAttachExtSecDel; } } private static string m_strAttachFailed = @"Failed to attach file:"; /// /// Look up a localized string similar to /// 'Failed to attach file:'. /// public static string AttachFailed { get { return m_strAttachFailed; } } private static string m_strAttachFiles = @"Attach Files To Entry"; /// /// Look up a localized string similar to /// 'Attach Files To Entry'. /// public static string AttachFiles { get { return m_strAttachFiles; } } private static string m_strAttachments = @"Attachments"; /// /// Look up a localized string similar to /// 'Attachments'. /// public static string Attachments { get { return m_strAttachments; } } private static string m_strAttachmentSave = @"Save Attached File As"; /// /// Look up a localized string similar to /// 'Save Attached File As'. /// public static string AttachmentSave { get { return m_strAttachmentSave; } } private static string m_strAttachmentsSave = @"Save attached files to:"; /// /// Look up a localized string similar to /// 'Save attached files to:'. /// public static string AttachmentsSave { get { return m_strAttachmentsSave; } } private static string m_strAttachNewRename = @"Do you wish to rename the new file or overwrite the existing attached file?"; /// /// Look up a localized string similar to /// 'Do you wish to rename the new file or overwrite the existing attached file?'. /// public static string AttachNewRename { get { return m_strAttachNewRename; } } private static string m_strAttachNewRenameRemarks0 = @"Click [Yes] to rename the new file."; /// /// Look up a localized string similar to /// 'Click [Yes] to rename the new file.'. /// public static string AttachNewRenameRemarks0 { get { return m_strAttachNewRenameRemarks0; } } private static string m_strAttachNewRenameRemarks1 = @"Click [No] to overwrite the existing attached file."; /// /// Look up a localized string similar to /// 'Click [No] to overwrite the existing attached file.'. /// public static string AttachNewRenameRemarks1 { get { return m_strAttachNewRenameRemarks1; } } private static string m_strAttachNewRenameRemarks2 = @"Click [Cancel] to skip this file."; /// /// Look up a localized string similar to /// 'Click [Cancel] to skip this file.'. /// public static string AttachNewRenameRemarks2 { get { return m_strAttachNewRenameRemarks2; } } private static string m_strAuthor = @"Author"; /// /// Look up a localized string similar to /// 'Author'. /// public static string Author { get { return m_strAuthor; } } private static string m_strAuto = @"Auto"; /// /// Look up a localized string similar to /// 'Auto'. /// public static string Auto { get { return m_strAuto; } } private static string m_strAutoCreateNew = @"Automatically create new"; /// /// Look up a localized string similar to /// 'Automatically create new'. /// public static string AutoCreateNew { get { return m_strAutoCreateNew; } } private static string m_strAutoGeneratedPasswordSettings = @"Automatically generated passwords for new entries"; /// /// Look up a localized string similar to /// 'Automatically generated passwords for new entries'. /// public static string AutoGeneratedPasswordSettings { get { return m_strAutoGeneratedPasswordSettings; } } private static string m_strAutoRememberOpenLastFile = @"Remember and automatically open last used database on startup"; /// /// Look up a localized string similar to /// 'Remember and automatically open last used database on startup'. /// public static string AutoRememberOpenLastFile { get { return m_strAutoRememberOpenLastFile; } } private static string m_strAutoSaveAtExit = @"Automatically save when closing/locking the database"; /// /// Look up a localized string similar to /// 'Automatically save when closing/locking the database'. /// public static string AutoSaveAtExit { get { return m_strAutoSaveAtExit; } } private static string m_strAutoShowExpiredEntries = @"Show expired entries (if any)"; /// /// Look up a localized string similar to /// 'Show expired entries (if any)'. /// public static string AutoShowExpiredEntries { get { return m_strAutoShowExpiredEntries; } } private static string m_strAutoShowSoonToExpireEntries = @"Show entries that will expire soon (if any)"; /// /// Look up a localized string similar to /// 'Show entries that will expire soon (if any)'. /// public static string AutoShowSoonToExpireEntries { get { return m_strAutoShowSoonToExpireEntries; } } private static string m_strAutoType = @"Auto-Type"; /// /// Look up a localized string similar to /// 'Auto-Type'. /// public static string AutoType { get { return m_strAutoType; } } private static string m_strAutoTypeAbortedOnWindow = @"Auto-Type has been aborted, because the target window is disallowed by the application policy (defined by your administrator)."; /// /// Look up a localized string similar to /// 'Auto-Type has been aborted, because the target window is disallowed by the application policy (defined by your administrator).'. /// public static string AutoTypeAbortedOnWindow { get { return m_strAutoTypeAbortedOnWindow; } } private static string m_strAutoTypeAlwaysShowSelDialog = @"Always show global auto-type entry selection dialog"; /// /// Look up a localized string similar to /// 'Always show global auto-type entry selection dialog'. /// public static string AutoTypeAlwaysShowSelDialog { get { return m_strAutoTypeAlwaysShowSelDialog; } } private static string m_strAutoTypeCancelOnTitleChange = @"Cancel auto-type when the target window title changes"; /// /// Look up a localized string similar to /// 'Cancel auto-type when the target window title changes'. /// public static string AutoTypeCancelOnTitleChange { get { return m_strAutoTypeCancelOnTitleChange; } } private static string m_strAutoTypeCancelOnWindowChange = @"Cancel auto-type when the target window changes"; /// /// Look up a localized string similar to /// 'Cancel auto-type when the target window changes'. /// public static string AutoTypeCancelOnWindowChange { get { return m_strAutoTypeCancelOnWindowChange; } } private static string m_strAutoTypeEntrySelection = @"Auto-Type Entry Selection"; /// /// Look up a localized string similar to /// 'Auto-Type Entry Selection'. /// public static string AutoTypeEntrySelection { get { return m_strAutoTypeEntrySelection; } } private static string m_strAutoTypeEntrySelectionDescLong2 = @"The following entries have been found for the currently active target window. Please select the entry that you want to auto-type into the target window."; /// /// Look up a localized string similar to /// 'The following entries have been found for the currently active target window. Please select the entry that you want to auto-type into the target window.'. /// public static string AutoTypeEntrySelectionDescLong2 { get { return m_strAutoTypeEntrySelectionDescLong2; } } private static string m_strAutoTypeEntrySelectionDescShort = @"Multiple entries exist for the current window."; /// /// Look up a localized string similar to /// 'Multiple entries exist for the current window.'. /// public static string AutoTypeEntrySelectionDescShort { get { return m_strAutoTypeEntrySelectionDescShort; } } private static string m_strAutoTypeGlobalHint = @"If you want KeePass to search the active database for a matching entry and auto-type it, use the 'Global auto-type' hot key."; /// /// Look up a localized string similar to /// 'If you want KeePass to search the active database for a matching entry and auto-type it, use the 'Global auto-type' hot key.'. /// public static string AutoTypeGlobalHint { get { return m_strAutoTypeGlobalHint; } } private static string m_strAutoTypeMatchByTagInTitle = @"An entry matches if one of its tags is contained in the target window title"; /// /// Look up a localized string similar to /// 'An entry matches if one of its tags is contained in the target window title'. /// public static string AutoTypeMatchByTagInTitle { get { return m_strAutoTypeMatchByTagInTitle; } } private static string m_strAutoTypeMatchByTitle = @"An entry matches if its title is contained in the target window title"; /// /// Look up a localized string similar to /// 'An entry matches if its title is contained in the target window title'. /// public static string AutoTypeMatchByTitle { get { return m_strAutoTypeMatchByTitle; } } private static string m_strAutoTypeMatchByUrlHostInTitle = @"An entry matches if the host component of its URL is contained in the target window title"; /// /// Look up a localized string similar to /// 'An entry matches if the host component of its URL is contained in the target window title'. /// public static string AutoTypeMatchByUrlHostInTitle { get { return m_strAutoTypeMatchByUrlHostInTitle; } } private static string m_strAutoTypeMatchByUrlInTitle = @"An entry matches if its URL is contained in the target window title"; /// /// Look up a localized string similar to /// 'An entry matches if its URL is contained in the target window title'. /// public static string AutoTypeMatchByUrlInTitle { get { return m_strAutoTypeMatchByUrlInTitle; } } private static string m_strAutoTypeObfuscationHint = @"Auto-Type obfuscation may not work with all windows."; /// /// Look up a localized string similar to /// 'Auto-Type obfuscation may not work with all windows.'. /// public static string AutoTypeObfuscationHint { get { return m_strAutoTypeObfuscationHint; } } private static string m_strAutoTypePrependInitSeqForIE = @"Prepend special initialization sequence for Internet Explorer windows"; /// /// Look up a localized string similar to /// 'Prepend special initialization sequence for Internet Explorer windows'. /// public static string AutoTypePrependInitSeqForIE { get { return m_strAutoTypePrependInitSeqForIE; } } private static string m_strAutoTypeReleaseAltWithKeyPress = @"Send Alt keypress when only the Alt modifier is active"; /// /// Look up a localized string similar to /// 'Send Alt keypress when only the Alt modifier is active'. /// public static string AutoTypeReleaseAltWithKeyPress { get { return m_strAutoTypeReleaseAltWithKeyPress; } } private static string m_strAutoTypeSelectedNoEntry = @"To use the 'Auto-type selected entry' hot key, you first need to select an entry in KeePass."; /// /// Look up a localized string similar to /// 'To use the 'Auto-type selected entry' hot key, you first need to select an entry in KeePass.'. /// public static string AutoTypeSelectedNoEntry { get { return m_strAutoTypeSelectedNoEntry; } } private static string m_strAutoTypeSequenceInvalid = @"The specified auto-type sequence is invalid."; /// /// Look up a localized string similar to /// 'The specified auto-type sequence is invalid.'. /// public static string AutoTypeSequenceInvalid { get { return m_strAutoTypeSequenceInvalid; } } private static string m_strAutoTypeUnknownPlaceholder = @"The following auto-type placeholder or special key code is unknown/unsupported:"; /// /// Look up a localized string similar to /// 'The following auto-type placeholder or special key code is unknown/unsupported:'. /// public static string AutoTypeUnknownPlaceholder { get { return m_strAutoTypeUnknownPlaceholder; } } private static string m_strAutoTypeXDoToolRequired = @"The 'xdotool' utility/package is required for auto-type."; /// /// Look up a localized string similar to /// 'The 'xdotool' utility/package is required for auto-type.'. /// public static string AutoTypeXDoToolRequired { get { return m_strAutoTypeXDoToolRequired; } } private static string m_strAutoTypeXDoToolRequiredGlobalVer = @"For global auto-type, the 'xdotool' utility/package is required (version 2.20100818.3004 or higher!)."; /// /// Look up a localized string similar to /// 'For global auto-type, the 'xdotool' utility/package is required (version 2.20100818.3004 or higher!).'. /// public static string AutoTypeXDoToolRequiredGlobalVer { get { return m_strAutoTypeXDoToolRequiredGlobalVer; } } private static string m_strAvailable = @"Available"; /// /// Look up a localized string similar to /// 'Available'. /// public static string Available { get { return m_strAvailable; } } private static string m_strBackgroundColor = @"Background Color"; /// /// Look up a localized string similar to /// 'Background Color'. /// public static string BackgroundColor { get { return m_strBackgroundColor; } } private static string m_strBackupDatabase = @"You should regularly create a backup of the database file (onto an independent data storage device)."; /// /// Look up a localized string similar to /// 'You should regularly create a backup of the database file (onto an independent data storage device).'. /// public static string BackupDatabase { get { return m_strBackupDatabase; } } private static string m_strBackupFile = @"You should create a backup of this file."; /// /// Look up a localized string similar to /// 'You should create a backup of this file.'. /// public static string BackupFile { get { return m_strBackupFile; } } private static string m_strBackupLocation = @"Backups are stored here:"; /// /// Look up a localized string similar to /// 'Backups are stored here:'. /// public static string BackupLocation { get { return m_strBackupLocation; } } private static string m_strBinaryNoConv = @"Binary (no conversion)"; /// /// Look up a localized string similar to /// 'Binary (no conversion)'. /// public static string BinaryNoConv { get { return m_strBinaryNoConv; } } private static string m_strBits = @"Bits"; /// /// Look up a localized string similar to /// 'Bits'. /// public static string Bits { get { return m_strBits; } } private static string m_strBitsStc = @"bits"; /// /// Look up a localized string similar to /// 'bits'. /// public static string BitsStc { get { return m_strBitsStc; } } private static string m_strBold = @"Bold"; /// /// Look up a localized string similar to /// 'Bold'. /// public static string Bold { get { return m_strBold; } } private static string m_strBothForms = @"Both forms"; /// /// Look up a localized string similar to /// 'Both forms'. /// public static string BothForms { get { return m_strBothForms; } } private static string m_strBrowser = @"Browser"; /// /// Look up a localized string similar to /// 'Browser'. /// public static string Browser { get { return m_strBrowser; } } private static string m_strBuiltIn = @"built-in"; /// /// Look up a localized string similar to /// 'built-in'. /// public static string BuiltIn { get { return m_strBuiltIn; } } private static string m_strBuiltInU = @"Built-in"; /// /// Look up a localized string similar to /// 'Built-in'. /// public static string BuiltInU { get { return m_strBuiltInU; } } private static string m_strButton = @"Button"; /// /// Look up a localized string similar to /// 'Button'. /// public static string Button { get { return m_strButton; } } private static string m_strButtonBack = @"< &Back"; /// /// Look up a localized string similar to /// '< &Back'. /// public static string ButtonBack { get { return m_strButtonBack; } } private static string m_strButtonDefault = @"Default button"; /// /// Look up a localized string similar to /// 'Default button'. /// public static string ButtonDefault { get { return m_strButtonDefault; } } private static string m_strButtonFinish = @"&Finish"; /// /// Look up a localized string similar to /// '&Finish'. /// public static string ButtonFinish { get { return m_strButtonFinish; } } private static string m_strButtonNext = @"&Next >"; /// /// Look up a localized string similar to /// '&Next >'. /// public static string ButtonNext { get { return m_strButtonNext; } } private static string m_strButtons = @"Buttons"; /// /// Look up a localized string similar to /// 'Buttons'. /// public static string Buttons { get { return m_strButtons; } } private static string m_strCancel = @"Cancel"; /// /// Look up a localized string similar to /// 'Cancel'. /// public static string Cancel { get { return m_strCancel; } } private static string m_strCannotMoveEntriesBcsGroup = @"Cannot move entries because they aren't stored in the same group."; /// /// Look up a localized string similar to /// 'Cannot move entries because they aren't stored in the same group.'. /// public static string CannotMoveEntriesBcsGroup { get { return m_strCannotMoveEntriesBcsGroup; } } private static string m_strChangeMasterKey = @"Change Master Key"; /// /// Look up a localized string similar to /// 'Change Master Key'. /// public static string ChangeMasterKey { get { return m_strChangeMasterKey; } } private static string m_strChangeMasterKeyIntroShort = @"You are changing the composite master key for the currently opened database."; /// /// Look up a localized string similar to /// 'You are changing the composite master key for the currently opened database.'. /// public static string ChangeMasterKeyIntroShort { get { return m_strChangeMasterKeyIntroShort; } } private static string m_strCharsAbbr = @"ch."; /// /// Look up a localized string similar to /// 'ch.'. /// public static string CharsAbbr { get { return m_strCharsAbbr; } } private static string m_strCharsStc = @"characters"; /// /// Look up a localized string similar to /// 'characters'. /// public static string CharsStc { get { return m_strCharsStc; } } private static string m_strCheckForUpdAtStart = @"Check for update at KeePass startup"; /// /// Look up a localized string similar to /// 'Check for update at KeePass startup'. /// public static string CheckForUpdAtStart { get { return m_strCheckForUpdAtStart; } } private static string m_strCheckingForUpd = @"Checking for updates"; /// /// Look up a localized string similar to /// 'Checking for updates'. /// public static string CheckingForUpd { get { return m_strCheckingForUpd; } } private static string m_strClassicAdj = @"Classic"; /// /// Look up a localized string similar to /// 'Classic'. /// public static string ClassicAdj { get { return m_strClassicAdj; } } private static string m_strClearKeyCmdLineParams = @"Clear master key command line parameters after using them once"; /// /// Look up a localized string similar to /// 'Clear master key command line parameters after using them once'. /// public static string ClearKeyCmdLineParams { get { return m_strClearKeyCmdLineParams; } } private static string m_strClearMru = @"&Clear List"; /// /// Look up a localized string similar to /// '&Clear List'. /// public static string ClearMru { get { return m_strClearMru; } } private static string m_strClipboard = @"Clipboard"; /// /// Look up a localized string similar to /// 'Clipboard'. /// public static string Clipboard { get { return m_strClipboard; } } private static string m_strClipboardClearInSeconds = @"Clipboard will be cleared in [PARAM] seconds"; /// /// Look up a localized string similar to /// 'Clipboard will be cleared in [PARAM] seconds'. /// public static string ClipboardClearInSeconds { get { return m_strClipboardClearInSeconds; } } private static string m_strClipboardClearOnExit = @"Clear clipboard when closing KeePass"; /// /// Look up a localized string similar to /// 'Clear clipboard when closing KeePass'. /// public static string ClipboardClearOnExit { get { return m_strClipboardClearOnExit; } } private static string m_strClipboardDataCopied = @"Data copied to clipboard."; /// /// Look up a localized string similar to /// 'Data copied to clipboard.'. /// public static string ClipboardDataCopied { get { return m_strClipboardDataCopied; } } private static string m_strClipboardViewerIgnoreFormat = @"Use 'Clipboard Viewer Ignore' clipboard format"; /// /// Look up a localized string similar to /// 'Use 'Clipboard Viewer Ignore' clipboard format'. /// public static string ClipboardViewerIgnoreFormat { get { return m_strClipboardViewerIgnoreFormat; } } private static string m_strCloseActiveDatabase = @"Close active database"; /// /// Look up a localized string similar to /// 'Close active database'. /// public static string CloseActiveDatabase { get { return m_strCloseActiveDatabase; } } private static string m_strCloseButton = @"&Close"; /// /// Look up a localized string similar to /// '&Close'. /// public static string CloseButton { get { return m_strCloseButton; } } private static string m_strCloseButtonMinimizes = @"Close button [X] minimizes main window instead of terminating the application"; /// /// Look up a localized string similar to /// 'Close button [X] minimizes main window instead of terminating the application'. /// public static string CloseButtonMinimizes { get { return m_strCloseButtonMinimizes; } } private static string m_strClosingDatabaseFile = @"Closing database file"; /// /// Look up a localized string similar to /// 'Closing database file'. /// public static string ClosingDatabaseFile { get { return m_strClosingDatabaseFile; } } private static string m_strClusterCenters = @"Clusters of similar passwords."; /// /// Look up a localized string similar to /// 'Clusters of similar passwords.'. /// public static string ClusterCenters { get { return m_strClusterCenters; } } private static string m_strClusterCentersDesc = @"Each entry in the list below is the center of a cluster of entries that have similar, but not identical passwords. Click on an entry to see the cluster (list of entries with descending similarity)."; /// /// Look up a localized string similar to /// 'Each entry in the list below is the center of a cluster of entries that have similar, but not identical passwords. Click on an entry to see the cluster (list of entries with descending similarity).'. /// public static string ClusterCentersDesc { get { return m_strClusterCentersDesc; } } private static string m_strColumn = @"Column"; /// /// Look up a localized string similar to /// 'Column'. /// public static string Column { get { return m_strColumn; } } private static string m_strColumns = @"Columns"; /// /// Look up a localized string similar to /// 'Columns'. /// public static string Columns { get { return m_strColumns; } } private static string m_strComments = @"Comments"; /// /// Look up a localized string similar to /// 'Comments'. /// public static string Comments { get { return m_strComments; } } private static string m_strCompany = @"Company"; /// /// Look up a localized string similar to /// 'Company'. /// public static string Company { get { return m_strCompany; } } private static string m_strComparison = @"Comparison"; /// /// Look up a localized string similar to /// 'Comparison'. /// public static string Comparison { get { return m_strComparison; } } private static string m_strComponent = @"Component"; /// /// Look up a localized string similar to /// 'Component'. /// public static string Component { get { return m_strComponent; } } private static string m_strCondition = @"Condition"; /// /// Look up a localized string similar to /// 'Condition'. /// public static string Condition { get { return m_strCondition; } } private static string m_strConfigAffectAdmin = @"Changes to the configuration/policy will affect you and all users of this KeePass installation."; /// /// Look up a localized string similar to /// 'Changes to the configuration/policy will affect you and all users of this KeePass installation.'. /// public static string ConfigAffectAdmin { get { return m_strConfigAffectAdmin; } } private static string m_strConfigAffectUser = @"Changes to the configuration/policy will only affect you. Policy flags that are enforced by the administrator are reset after restarting KeePass."; /// /// Look up a localized string similar to /// 'Changes to the configuration/policy will only affect you. Policy flags that are enforced by the administrator are reset after restarting KeePass.'. /// public static string ConfigAffectUser { get { return m_strConfigAffectUser; } } private static string m_strConfigSaveFailed = @"Failed to save the configuration."; /// /// Look up a localized string similar to /// 'Failed to save the configuration.'. /// public static string ConfigSaveFailed { get { return m_strConfigSaveFailed; } } private static string m_strConfigureAutoType = @"Configure Auto-Type"; /// /// Look up a localized string similar to /// 'Configure Auto-Type'. /// public static string ConfigureAutoType { get { return m_strConfigureAutoType; } } private static string m_strConfigureAutoTypeDesc = @"Configure auto-type behaviour for this entry."; /// /// Look up a localized string similar to /// 'Configure auto-type behaviour for this entry.'. /// public static string ConfigureAutoTypeDesc { get { return m_strConfigureAutoTypeDesc; } } private static string m_strConfigureAutoTypeItem = @"Configure Auto-Type Item"; /// /// Look up a localized string similar to /// 'Configure Auto-Type Item'. /// public static string ConfigureAutoTypeItem { get { return m_strConfigureAutoTypeItem; } } private static string m_strConfigureAutoTypeItemDesc = @"Associate a window title with a keystroke sequence."; /// /// Look up a localized string similar to /// 'Associate a window title with a keystroke sequence.'. /// public static string ConfigureAutoTypeItemDesc { get { return m_strConfigureAutoTypeItemDesc; } } private static string m_strConfigureColumns = @"Configure Columns"; /// /// Look up a localized string similar to /// 'Configure Columns'. /// public static string ConfigureColumns { get { return m_strConfigureColumns; } } private static string m_strConfigureColumnsDesc = @"Configure entry list columns."; /// /// Look up a localized string similar to /// 'Configure entry list columns.'. /// public static string ConfigureColumnsDesc { get { return m_strConfigureColumnsDesc; } } private static string m_strConfigureKeystrokeSeq = @"Configure Keystroke Sequence"; /// /// Look up a localized string similar to /// 'Configure Keystroke Sequence'. /// public static string ConfigureKeystrokeSeq { get { return m_strConfigureKeystrokeSeq; } } private static string m_strConfigureKeystrokeSeqDesc = @"Define a default keystroke sequence."; /// /// Look up a localized string similar to /// 'Define a default keystroke sequence.'. /// public static string ConfigureKeystrokeSeqDesc { get { return m_strConfigureKeystrokeSeqDesc; } } private static string m_strConfigureOnNewDatabase2 = @"Create New Database - Step 3"; /// /// Look up a localized string similar to /// 'Create New Database - Step 3'. /// public static string ConfigureOnNewDatabase2 { get { return m_strConfigureOnNewDatabase2; } } private static string m_strContact = @"Contact"; /// /// Look up a localized string similar to /// 'Contact'. /// public static string Contact { get { return m_strContact; } } private static string m_strContainsOp = @"Contains"; /// /// Look up a localized string similar to /// 'Contains'. /// public static string ContainsOp { get { return m_strContainsOp; } } private static string m_strCopiedEntryData = @"Copied entry data to clipboard"; /// /// Look up a localized string similar to /// 'Copied entry data to clipboard'. /// public static string CopiedEntryData { get { return m_strCopiedEntryData; } } private static string m_strCopy = @"Copy"; /// /// Look up a localized string similar to /// 'Copy'. /// public static string Copy { get { return m_strCopy; } } private static string m_strCopyAll = @"Copy All"; /// /// Look up a localized string similar to /// 'Copy All'. /// public static string CopyAll { get { return m_strCopyAll; } } private static string m_strCopyLink = @"Copy Link"; /// /// Look up a localized string similar to /// 'Copy Link'. /// public static string CopyLink { get { return m_strCopyLink; } } private static string m_strCopyOfItem = @"Copy"; /// /// Look up a localized string similar to /// 'Copy'. /// public static string CopyOfItem { get { return m_strCopyOfItem; } } private static string m_strCopyPasswordFull = @"Copy Password to Clipboard"; /// /// Look up a localized string similar to /// 'Copy Password to Clipboard'. /// public static string CopyPasswordFull { get { return m_strCopyPasswordFull; } } private static string m_strCopyPasswordMenu = @"Copy &Password"; /// /// Look up a localized string similar to /// 'Copy &Password'. /// public static string CopyPasswordMenu { get { return m_strCopyPasswordMenu; } } private static string m_strCopyTanMenu = @"Copy &TAN"; /// /// Look up a localized string similar to /// 'Copy &TAN'. /// public static string CopyTanMenu { get { return m_strCopyTanMenu; } } private static string m_strCopyUrlsInsteadOfOpening = @"Copy URLs to clipboard instead of opening them"; /// /// Look up a localized string similar to /// 'Copy URLs to clipboard instead of opening them'. /// public static string CopyUrlsInsteadOfOpening { get { return m_strCopyUrlsInsteadOfOpening; } } private static string m_strCopyUrlToClipboard = @"&Copy URL(s) to Clipboard"; /// /// Look up a localized string similar to /// '&Copy URL(s) to Clipboard'. /// public static string CopyUrlToClipboard { get { return m_strCopyUrlToClipboard; } } private static string m_strCopyUserFull = @"Copy User Name to Clipboard"; /// /// Look up a localized string similar to /// 'Copy User Name to Clipboard'. /// public static string CopyUserFull { get { return m_strCopyUserFull; } } private static string m_strCopyWholeEntries = @"Copy Whole Entries"; /// /// Look up a localized string similar to /// 'Copy Whole Entries'. /// public static string CopyWholeEntries { get { return m_strCopyWholeEntries; } } private static string m_strCorruptionByExt = @"Such a corruption is usually caused by a plugin or a KeePass port. Please try to find out which plugin/port is causing it and report the issue to the corresponding developer."; /// /// Look up a localized string similar to /// 'Such a corruption is usually caused by a plugin or a KeePass port. Please try to find out which plugin/port is causing it and report the issue to the corresponding developer.'. /// public static string CorruptionByExt { get { return m_strCorruptionByExt; } } private static string m_strCount = @"Count"; /// /// Look up a localized string similar to /// 'Count'. /// public static string Count { get { return m_strCount; } } private static string m_strCreateMasterKey = @"Create Composite Master Key"; /// /// Look up a localized string similar to /// 'Create Composite Master Key'. /// public static string CreateMasterKey { get { return m_strCreateMasterKey; } } private static string m_strCreateNewDatabase = @"Create New Password Database"; /// /// Look up a localized string similar to /// 'Create New Password Database'. /// public static string CreateNewDatabase { get { return m_strCreateNewDatabase; } } private static string m_strCreateNewIDs = @"Create new &IDs"; /// /// Look up a localized string similar to /// 'Create new &IDs'. /// public static string CreateNewIDs { get { return m_strCreateNewIDs; } } private static string m_strCreationTime = @"Creation Time"; /// /// Look up a localized string similar to /// 'Creation Time'. /// public static string CreationTime { get { return m_strCreationTime; } } private static string m_strCredSaveAll = @"Remember user name and password"; /// /// Look up a localized string similar to /// 'Remember user name and password'. /// public static string CredSaveAll { get { return m_strCredSaveAll; } } private static string m_strCredSaveNone = @"Do not remember user name and password"; /// /// Look up a localized string similar to /// 'Do not remember user name and password'. /// public static string CredSaveNone { get { return m_strCredSaveNone; } } private static string m_strCredSaveUserOnly = @"Remember user name only"; /// /// Look up a localized string similar to /// 'Remember user name only'. /// public static string CredSaveUserOnly { get { return m_strCredSaveUserOnly; } } private static string m_strCredSpecifyDifferent = @"&Specify different server credentials"; /// /// Look up a localized string similar to /// '&Specify different server credentials'. /// public static string CredSpecifyDifferent { get { return m_strCredSpecifyDifferent; } } private static string m_strCsprojCountError = @"There must be exactly one .csproj or .vbproj file."; /// /// Look up a localized string similar to /// 'There must be exactly one .csproj or .vbproj file.'. /// public static string CsprojCountError { get { return m_strCsprojCountError; } } private static string m_strCsvTextFile = @"CSV / Text File"; /// /// Look up a localized string similar to /// 'CSV / Text File'. /// public static string CsvTextFile { get { return m_strCsvTextFile; } } private static string m_strCtrlAltAConflict = @"KeePass' global auto-type hot key Ctrl+Alt+A is in conflict with a system key combination that is producing '{PARAM}'."; /// /// Look up a localized string similar to /// 'KeePass' global auto-type hot key Ctrl+Alt+A is in conflict with a system key combination that is producing '{PARAM}'.'. /// public static string CtrlAltAConflict { get { return m_strCtrlAltAConflict; } } private static string m_strCtrlAltAConflictHint = @"You can change the global auto-type hot key to a different key combination in 'Tools' -> 'Options' -> tab 'Integration'."; /// /// Look up a localized string similar to /// 'You can change the global auto-type hot key to a different key combination in 'Tools' -> 'Options' -> tab 'Integration'.'. /// public static string CtrlAltAConflictHint { get { return m_strCtrlAltAConflictHint; } } private static string m_strCurrentStyle = @"Current Style"; /// /// Look up a localized string similar to /// 'Current Style'. /// public static string CurrentStyle { get { return m_strCurrentStyle; } } private static string m_strCustom = @"Custom"; /// /// Look up a localized string similar to /// 'Custom'. /// public static string Custom { get { return m_strCustom; } } private static string m_strCustomFields = @"Custom Fields"; /// /// Look up a localized string similar to /// 'Custom Fields'. /// public static string CustomFields { get { return m_strCustomFields; } } private static string m_strCustomizableHtml = @"Customizable HTML File"; /// /// Look up a localized string similar to /// 'Customizable HTML File'. /// public static string CustomizableHtml { get { return m_strCustomizableHtml; } } private static string m_strCustomTbButtonAdd = @"Add custom toolbar button"; /// /// Look up a localized string similar to /// 'Add custom toolbar button'. /// public static string CustomTbButtonAdd { get { return m_strCustomTbButtonAdd; } } private static string m_strCustomTbButtonClicked = @"Custom toolbar button clicked"; /// /// Look up a localized string similar to /// 'Custom toolbar button clicked'. /// public static string CustomTbButtonClicked { get { return m_strCustomTbButtonClicked; } } private static string m_strCustomTbButtonRemove = @"Remove custom toolbar button"; /// /// Look up a localized string similar to /// 'Remove custom toolbar button'. /// public static string CustomTbButtonRemove { get { return m_strCustomTbButtonRemove; } } private static string m_strCut = @"Cut"; /// /// Look up a localized string similar to /// 'Cut'. /// public static string Cut { get { return m_strCut; } } private static string m_strData = @"Data"; /// /// Look up a localized string similar to /// 'Data'. /// public static string Data { get { return m_strData; } } private static string m_strDatabase = @"Database"; /// /// Look up a localized string similar to /// 'Database'. /// public static string Database { get { return m_strDatabase; } } private static string m_strDatabaseDescPrompt = @"Enter a short description of the database or leave it empty."; /// /// Look up a localized string similar to /// 'Enter a short description of the database or leave it empty.'. /// public static string DatabaseDescPrompt { get { return m_strDatabaseDescPrompt; } } private static string m_strDatabaseFile = @"Database file"; /// /// Look up a localized string similar to /// 'Database file'. /// public static string DatabaseFile { get { return m_strDatabaseFile; } } private static string m_strDatabaseFileIntro = @"Your data will be stored in a KeePass database file, which is a regular file. After clicking [OK], you will be prompted to specify the location where KeePass should save this file."; /// /// Look up a localized string similar to /// 'Your data will be stored in a KeePass database file, which is a regular file. After clicking [OK], you will be prompted to specify the location where KeePass should save this file.'. /// public static string DatabaseFileIntro { get { return m_strDatabaseFileIntro; } } private static string m_strDatabaseFileRem = @"It is important that you remember where the database file is stored."; /// /// Look up a localized string similar to /// 'It is important that you remember where the database file is stored.'. /// public static string DatabaseFileRem { get { return m_strDatabaseFileRem; } } private static string m_strDatabaseHasUnsavedChanges = @"Database has unsaved changes"; /// /// Look up a localized string similar to /// 'Database has unsaved changes'. /// public static string DatabaseHasUnsavedChanges { get { return m_strDatabaseHasUnsavedChanges; } } private static string m_strDatabaseMaintenance = @"Database Maintenance"; /// /// Look up a localized string similar to /// 'Database Maintenance'. /// public static string DatabaseMaintenance { get { return m_strDatabaseMaintenance; } } private static string m_strDatabaseMaintenanceDesc = @"Here you can maintain the currently opened database."; /// /// Look up a localized string similar to /// 'Here you can maintain the currently opened database.'. /// public static string DatabaseMaintenanceDesc { get { return m_strDatabaseMaintenanceDesc; } } private static string m_strDatabaseModifiedNoDot = @"The current database file has been modified"; /// /// Look up a localized string similar to /// 'The current database file has been modified'. /// public static string DatabaseModifiedNoDot { get { return m_strDatabaseModifiedNoDot; } } private static string m_strDatabaseNamePrompt = @"Enter a name for the database or leave it empty."; /// /// Look up a localized string similar to /// 'Enter a name for the database or leave it empty.'. /// public static string DatabaseNamePrompt { get { return m_strDatabaseNamePrompt; } } private static string m_strDatabaseSettings = @"Database Settings"; /// /// Look up a localized string similar to /// 'Database Settings'. /// public static string DatabaseSettings { get { return m_strDatabaseSettings; } } private static string m_strDatabaseSettingsDesc = @"Here you can configure various database settings."; /// /// Look up a localized string similar to /// 'Here you can configure various database settings.'. /// public static string DatabaseSettingsDesc { get { return m_strDatabaseSettingsDesc; } } private static string m_strDataEditor = @"Data Editor"; /// /// Look up a localized string similar to /// 'Data Editor'. /// public static string DataEditor { get { return m_strDataEditor; } } private static string m_strDataLoss = @"If you lose the database file or any of the master key components (or forget the composition), all data stored in the database is lost. KeePass does not have any built-in file backup functionality. There is no backdoor and no universal key that can open your database."; /// /// Look up a localized string similar to /// 'If you lose the database file or any of the master key components (or forget the composition), all data stored in the database is lost. KeePass does not have any built-in file backup functionality. There is no backdoor and no universal key that can open your database.'. /// public static string DataLoss { get { return m_strDataLoss; } } private static string m_strDataViewer = @"Data Viewer"; /// /// Look up a localized string similar to /// 'Data Viewer'. /// public static string DataViewer { get { return m_strDataViewer; } } private static string m_strDbMntncResults = @"Show results of database maintenance in a dialog"; /// /// Look up a localized string similar to /// 'Show results of database maintenance in a dialog'. /// public static string DbMntncResults { get { return m_strDbMntncResults; } } private static string m_strDbNoModBy = @"{PARAM} has not modified the database."; /// /// Look up a localized string similar to /// '{PARAM} has not modified the database.'. /// public static string DbNoModBy { get { return m_strDbNoModBy; } } private static string m_strDefault = @"Default"; /// /// Look up a localized string similar to /// 'Default'. /// public static string Default { get { return m_strDefault; } } private static string m_strDelete = @"Delete"; /// /// Look up a localized string similar to /// 'Delete'. /// public static string Delete { get { return m_strDelete; } } private static string m_strDeleteCmd = @"&Delete"; /// /// Look up a localized string similar to /// '&Delete'. /// public static string DeleteCmd { get { return m_strDeleteCmd; } } private static string m_strDeleteEntriesTitle = @"Delete Entries"; /// /// Look up a localized string similar to /// 'Delete Entries'. /// public static string DeleteEntriesTitle { get { return m_strDeleteEntriesTitle; } } private static string m_strDeleteEntriesTitleSingle = @"Delete Entry"; /// /// Look up a localized string similar to /// 'Delete Entry'. /// public static string DeleteEntriesTitleSingle { get { return m_strDeleteEntriesTitleSingle; } } private static string m_strDeleteEntriesQuestion = @"Are you sure you want to permanently delete the selected entries?"; /// /// Look up a localized string similar to /// 'Are you sure you want to permanently delete the selected entries?'. /// public static string DeleteEntriesQuestion { get { return m_strDeleteEntriesQuestion; } } private static string m_strDeleteEntriesQuestionSingle = @"Are you sure you want to permanently delete the selected entry?"; /// /// Look up a localized string similar to /// 'Are you sure you want to permanently delete the selected entry?'. /// public static string DeleteEntriesQuestionSingle { get { return m_strDeleteEntriesQuestionSingle; } } private static string m_strDeleteGroupTitle = @"Delete Group"; /// /// Look up a localized string similar to /// 'Delete Group'. /// public static string DeleteGroupTitle { get { return m_strDeleteGroupTitle; } } private static string m_strDeleteGroupInfo = @"Deleting a group will also delete all entries and subgroups in that group."; /// /// Look up a localized string similar to /// 'Deleting a group will also delete all entries and subgroups in that group.'. /// public static string DeleteGroupInfo { get { return m_strDeleteGroupInfo; } } private static string m_strDeleteGroupQuestion = @"Are you sure you want to permanently delete the selected group?"; /// /// Look up a localized string similar to /// 'Are you sure you want to permanently delete the selected group?'. /// public static string DeleteGroupQuestion { get { return m_strDeleteGroupQuestion; } } private static string m_strDescending = @"&Descending"; /// /// Look up a localized string similar to /// '&Descending'. /// public static string Descending { get { return m_strDescending; } } private static string m_strDescription = @"Description"; /// /// Look up a localized string similar to /// 'Description'. /// public static string Description { get { return m_strDescription; } } private static string m_strDetails = @"Details"; /// /// Look up a localized string similar to /// 'Details'. /// public static string Details { get { return m_strDetails; } } private static string m_strDialogNoShowAgain = @"Do not show this dialog again."; /// /// Look up a localized string similar to /// 'Do not show this dialog again.'. /// public static string DialogNoShowAgain { get { return m_strDialogNoShowAgain; } } private static string m_strDialogs = @"Dialogs"; /// /// Look up a localized string similar to /// 'Dialogs'. /// public static string Dialogs { get { return m_strDialogs; } } private static string m_strDisable = @"Disable"; /// /// Look up a localized string similar to /// 'Disable'. /// public static string Disable { get { return m_strDisable; } } private static string m_strDisabled = @"Disabled"; /// /// Look up a localized string similar to /// 'Disabled'. /// public static string Disabled { get { return m_strDisabled; } } private static string m_strDisableSaveIfNotModified = @"Disable 'Save' command (instead of graying it out) if the database hasn't been modified"; /// /// Look up a localized string similar to /// 'Disable 'Save' command (instead of graying it out) if the database hasn't been modified'. /// public static string DisableSaveIfNotModified { get { return m_strDisableSaveIfNotModified; } } private static string m_strDiscardChangesCmd = @"&Discard changes"; /// /// Look up a localized string similar to /// '&Discard changes'. /// public static string DiscardChangesCmd { get { return m_strDiscardChangesCmd; } } private static string m_strDocumentationHint = @"Please see the documentation for more details."; /// /// Look up a localized string similar to /// 'Please see the documentation for more details.'. /// public static string DocumentationHint { get { return m_strDocumentationHint; } } private static string m_strDragDrop = @"Drag&Drop"; /// /// Look up a localized string similar to /// 'Drag&Drop'. /// public static string DragDrop { get { return m_strDragDrop; } } private static string m_strDropToBackOnCopy = @"Drop to background after copying data to the clipboard"; /// /// Look up a localized string similar to /// 'Drop to background after copying data to the clipboard'. /// public static string DropToBackOnCopy { get { return m_strDropToBackOnCopy; } } private static string m_strDuplicatePasswords = @"Duplicate Passwords"; /// /// Look up a localized string similar to /// 'Duplicate Passwords'. /// public static string DuplicatePasswords { get { return m_strDuplicatePasswords; } } private static string m_strDuplicatePasswordsGroup = @"Entries using the same password:"; /// /// Look up a localized string similar to /// 'Entries using the same password:'. /// public static string DuplicatePasswordsGroup { get { return m_strDuplicatePasswordsGroup; } } private static string m_strDuplicatePasswordsList = @"List of entries that are using the same passwords."; /// /// Look up a localized string similar to /// 'List of entries that are using the same passwords.'. /// public static string DuplicatePasswordsList { get { return m_strDuplicatePasswordsList; } } private static string m_strDuplicatePasswordsNone = @"No duplicate passwords have been found."; /// /// Look up a localized string similar to /// 'No duplicate passwords have been found.'. /// public static string DuplicatePasswordsNone { get { return m_strDuplicatePasswordsNone; } } private static string m_strDuplicateStringFieldName = @"The string field name you specified already exists. String field names must be unique for each entry."; /// /// Look up a localized string similar to /// 'The string field name you specified already exists. String field names must be unique for each entry.'. /// public static string DuplicateStringFieldName { get { return m_strDuplicateStringFieldName; } } private static string m_strEditCmd = @"&Edit"; /// /// Look up a localized string similar to /// '&Edit'. /// public static string EditCmd { get { return m_strEditCmd; } } private static string m_strEditEntry = @"Edit Entry"; /// /// Look up a localized string similar to /// 'Edit Entry'. /// public static string EditEntry { get { return m_strEditEntry; } } private static string m_strEditEntryDesc = @"You're editing an existing entry."; /// /// Look up a localized string similar to /// 'You're editing an existing entry.'. /// public static string EditEntryDesc { get { return m_strEditEntryDesc; } } private static string m_strEditGroup = @"Edit Group"; /// /// Look up a localized string similar to /// 'Edit Group'. /// public static string EditGroup { get { return m_strEditGroup; } } private static string m_strEditGroupDesc = @"Edit properties of the currently selected group."; /// /// Look up a localized string similar to /// 'Edit properties of the currently selected group.'. /// public static string EditGroupDesc { get { return m_strEditGroupDesc; } } private static string m_strEditStringField = @"Edit Entry String Field"; /// /// Look up a localized string similar to /// 'Edit Entry String Field'. /// public static string EditStringField { get { return m_strEditStringField; } } private static string m_strEditStringFieldDesc = @"Edit one of the entry's string fields."; /// /// Look up a localized string similar to /// 'Edit one of the entry's string fields.'. /// public static string EditStringFieldDesc { get { return m_strEditStringFieldDesc; } } private static string m_strEMail = @"eMail"; /// /// Look up a localized string similar to /// 'eMail'. /// public static string EMail { get { return m_strEMail; } } private static string m_strEmergencySheet = @"Emergency Sheet"; /// /// Look up a localized string similar to /// 'Emergency Sheet'. /// public static string EmergencySheet { get { return m_strEmergencySheet; } } private static string m_strEmergencySheetAsk = @"Ask whether to create an emergency sheet"; /// /// Look up a localized string similar to /// 'Ask whether to create an emergency sheet'. /// public static string EmergencySheetAsk { get { return m_strEmergencySheetAsk; } } private static string m_strEmergencySheetInfo = @"A KeePass emergency sheet contains all important information that is required to open your database. It should be printed, filled out and stored in a secure location, where only you and possibly a few other people that you trust have access to."; /// /// Look up a localized string similar to /// 'A KeePass emergency sheet contains all important information that is required to open your database. It should be printed, filled out and stored in a secure location, where only you and possibly a few other people that you trust have access to.'. /// public static string EmergencySheetInfo { get { return m_strEmergencySheetInfo; } } private static string m_strEmergencySheetPrintInfo = @"KeePass will print an emergency sheet, which you can then fill out."; /// /// Look up a localized string similar to /// 'KeePass will print an emergency sheet, which you can then fill out.'. /// public static string EmergencySheetPrintInfo { get { return m_strEmergencySheetPrintInfo; } } private static string m_strEmergencySheetQ = @"Do you want to print an emergency sheet now?"; /// /// Look up a localized string similar to /// 'Do you want to print an emergency sheet now?'. /// public static string EmergencySheetQ { get { return m_strEmergencySheetQ; } } private static string m_strEmergencySheetRec = @"It is recommended that you create an emergency sheet for your database."; /// /// Look up a localized string similar to /// 'It is recommended that you create an emergency sheet for your database.'. /// public static string EmergencySheetRec { get { return m_strEmergencySheetRec; } } private static string m_strEmpty = @"Empty"; /// /// Look up a localized string similar to /// 'Empty'. /// public static string Empty { get { return m_strEmpty; } } private static string m_strEmptyMasterPw = @"You have selected to use an empty master password."; /// /// Look up a localized string similar to /// 'You have selected to use an empty master password.'. /// public static string EmptyMasterPw { get { return m_strEmptyMasterPw; } } private static string m_strEmptyMasterPwHint = @"An empty master password is not the same as using no master password at all."; /// /// Look up a localized string similar to /// 'An empty master password is not the same as using no master password at all.'. /// public static string EmptyMasterPwHint { get { return m_strEmptyMasterPwHint; } } private static string m_strEmptyMasterPwQuestion = @"Are you sure you want to use an empty master password?"; /// /// Look up a localized string similar to /// 'Are you sure you want to use an empty master password?'. /// public static string EmptyMasterPwQuestion { get { return m_strEmptyMasterPwQuestion; } } private static string m_strEmptyRecycleBinQuestion = @"Are you sure you want to permanently delete the items?"; /// /// Look up a localized string similar to /// 'Are you sure you want to permanently delete the items?'. /// public static string EmptyRecycleBinQuestion { get { return m_strEmptyRecycleBinQuestion; } } private static string m_strEnable = @"Enable"; /// /// Look up a localized string similar to /// 'Enable'. /// public static string Enable { get { return m_strEnable; } } private static string m_strEnabled = @"Enabled"; /// /// Look up a localized string similar to /// 'Enabled'. /// public static string Enabled { get { return m_strEnabled; } } private static string m_strEncoding = @"Encoding"; /// /// Look up a localized string similar to /// 'Encoding'. /// public static string Encoding { get { return m_strEncoding; } } private static string m_strEncodingFail = @"Selected encoding is invalid. The file cannot be interpreted using the selected encoding."; /// /// Look up a localized string similar to /// 'Selected encoding is invalid. The file cannot be interpreted using the selected encoding.'. /// public static string EncodingFail { get { return m_strEncodingFail; } } private static string m_strEndsWith = @"Ends with"; /// /// Look up a localized string similar to /// 'Ends with'. /// public static string EndsWith { get { return m_strEndsWith; } } private static string m_strEnterCompositeKey = @"Enter Master Key"; /// /// Look up a localized string similar to /// 'Enter Master Key'. /// public static string EnterCompositeKey { get { return m_strEnterCompositeKey; } } private static string m_strEnterCurrentCompositeKey = @"Enter Current Master Key"; /// /// Look up a localized string similar to /// 'Enter Current Master Key'. /// public static string EnterCurrentCompositeKey { get { return m_strEnterCurrentCompositeKey; } } private static string m_strEntropyDesc = @"Generate additional random bits."; /// /// Look up a localized string similar to /// 'Generate additional random bits.'. /// public static string EntropyDesc { get { return m_strEntropyDesc; } } private static string m_strEntropyTitle = @"Entropy Collection"; /// /// Look up a localized string similar to /// 'Entropy Collection'. /// public static string EntropyTitle { get { return m_strEntropyTitle; } } private static string m_strEntry = @"Entry"; /// /// Look up a localized string similar to /// 'Entry'. /// public static string Entry { get { return m_strEntry; } } private static string m_strEntryList = @"Entry List"; /// /// Look up a localized string similar to /// 'Entry List'. /// public static string EntryList { get { return m_strEntryList; } } private static string m_strEntryListAutoResizeColumns = @"Automatically resize entry list columns when resizing the main window"; /// /// Look up a localized string similar to /// 'Automatically resize entry list columns when resizing the main window'. /// public static string EntryListAutoResizeColumns { get { return m_strEntryListAutoResizeColumns; } } private static string m_strEntrySelGroupSel = @"When selecting an entry, automatically select its parent group, too"; /// /// Look up a localized string similar to /// 'When selecting an entry, automatically select its parent group, too'. /// public static string EntrySelGroupSel { get { return m_strEntrySelGroupSel; } } private static string m_strEnvironmentVariable = @"Environment variable"; /// /// Look up a localized string similar to /// 'Environment variable'. /// public static string EnvironmentVariable { get { return m_strEnvironmentVariable; } } private static string m_strEqualsOp = @"Equals"; /// /// Look up a localized string similar to /// 'Equals'. /// public static string EqualsOp { get { return m_strEqualsOp; } } private static string m_strError = @"Error"; /// /// Look up a localized string similar to /// 'Error'. /// public static string Error { get { return m_strError; } } private static string m_strErrorCode = @"Error Code"; /// /// Look up a localized string similar to /// 'Error Code'. /// public static string ErrorCode { get { return m_strErrorCode; } } private static string m_strErrors = @"Errors"; /// /// Look up a localized string similar to /// 'Errors'. /// public static string Errors { get { return m_strErrors; } } private static string m_strEscMinimizesToTray = @"Esc minimizes to tray instead of locking the workspace"; /// /// Look up a localized string similar to /// 'Esc minimizes to tray instead of locking the workspace'. /// public static string EscMinimizesToTray { get { return m_strEscMinimizesToTray; } } private static string m_strEvent = @"Event"; /// /// Look up a localized string similar to /// 'Event'. /// public static string Event { get { return m_strEvent; } } private static string m_strExecuteCmdLineUrl = @"Execute command line / URL"; /// /// Look up a localized string similar to /// 'Execute command line / URL'. /// public static string ExecuteCmdLineUrl { get { return m_strExecuteCmdLineUrl; } } private static string m_strExitInsteadOfLockingAfterTime = @"Exit instead of locking the workspace after the specified time"; /// /// Look up a localized string similar to /// 'Exit instead of locking the workspace after the specified time'. /// public static string ExitInsteadOfLockingAfterTime { get { return m_strExitInsteadOfLockingAfterTime; } } private static string m_strExitInsteadOfLockingAlways = @"Always exit instead of locking the workspace"; /// /// Look up a localized string similar to /// 'Always exit instead of locking the workspace'. /// public static string ExitInsteadOfLockingAlways { get { return m_strExitInsteadOfLockingAlways; } } private static string m_strExpiredEntries = @"Expired Entries"; /// /// Look up a localized string similar to /// 'Expired Entries'. /// public static string ExpiredEntries { get { return m_strExpiredEntries; } } private static string m_strExpiredEntriesCanMatch = @"Expired entries can match"; /// /// Look up a localized string similar to /// 'Expired entries can match'. /// public static string ExpiredEntriesCanMatch { get { return m_strExpiredEntriesCanMatch; } } private static string m_strExpiryTime = @"Expiry Time"; /// /// Look up a localized string similar to /// 'Expiry Time'. /// public static string ExpiryTime { get { return m_strExpiryTime; } } private static string m_strExpiryTimeDateOnly = @"Expiry Time (Date Only)"; /// /// Look up a localized string similar to /// 'Expiry Time (Date Only)'. /// public static string ExpiryTimeDateOnly { get { return m_strExpiryTimeDateOnly; } } private static string m_strExport = @"Export"; /// /// Look up a localized string similar to /// 'Export'. /// public static string Export { get { return m_strExport; } } private static string m_strExportFileDesc = @"Export data to an external file."; /// /// Look up a localized string similar to /// 'Export data to an external file.'. /// public static string ExportFileDesc { get { return m_strExportFileDesc; } } private static string m_strExportFileTitle = @"Export File/Data"; /// /// Look up a localized string similar to /// 'Export File/Data'. /// public static string ExportFileTitle { get { return m_strExportFileTitle; } } private static string m_strExportHtml = @"Export To HTML"; /// /// Look up a localized string similar to /// 'Export To HTML'. /// public static string ExportHtml { get { return m_strExportHtml; } } private static string m_strExportHtmlDesc = @"Export entries to a HTML file."; /// /// Look up a localized string similar to /// 'Export entries to a HTML file.'. /// public static string ExportHtmlDesc { get { return m_strExportHtmlDesc; } } private static string m_strExportingStatusMsg = @"Exporting..."; /// /// Look up a localized string similar to /// 'Exporting...'. /// public static string ExportingStatusMsg { get { return m_strExportingStatusMsg; } } private static string m_strExportStc = @"Export active database"; /// /// Look up a localized string similar to /// 'Export active database'. /// public static string ExportStc { get { return m_strExportStc; } } private static string m_strExportToPrompt = @"Export to:"; /// /// Look up a localized string similar to /// 'Export to:'. /// public static string ExportToPrompt { get { return m_strExportToPrompt; } } private static string m_strExternal = @"External"; /// /// Look up a localized string similar to /// 'External'. /// public static string External { get { return m_strExternal; } } private static string m_strExternalApp = @"External Application"; /// /// Look up a localized string similar to /// 'External Application'. /// public static string ExternalApp { get { return m_strExternalApp; } } private static string m_strFatalError = @"Fatal Error"; /// /// Look up a localized string similar to /// 'Fatal Error'. /// public static string FatalError { get { return m_strFatalError; } } private static string m_strFeature = @"Feature"; /// /// Look up a localized string similar to /// 'Feature'. /// public static string Feature { get { return m_strFeature; } } private static string m_strField = @"Field"; /// /// Look up a localized string similar to /// 'Field'. /// public static string Field { get { return m_strField; } } private static string m_strFieldName = @"Field Name"; /// /// Look up a localized string similar to /// 'Field Name'. /// public static string FieldName { get { return m_strFieldName; } } private static string m_strFieldNameExistsAlready = @"The entered name exists already and cannot be used."; /// /// Look up a localized string similar to /// 'The entered name exists already and cannot be used.'. /// public static string FieldNameExistsAlready { get { return m_strFieldNameExistsAlready; } } private static string m_strFieldNameInvalid = @"The entered name is invalid and cannot be used."; /// /// Look up a localized string similar to /// 'The entered name is invalid and cannot be used.'. /// public static string FieldNameInvalid { get { return m_strFieldNameInvalid; } } private static string m_strFieldNamePrompt = @"Please enter a field name."; /// /// Look up a localized string similar to /// 'Please enter a field name.'. /// public static string FieldNamePrompt { get { return m_strFieldNamePrompt; } } private static string m_strFieldRefInvalidChars = @"The selected field, which identifies the source entry, contains illegal characters (like '{', '}', newline characters, ...)."; /// /// Look up a localized string similar to /// 'The selected field, which identifies the source entry, contains illegal characters (like '{', '}', newline characters, ...).'. /// public static string FieldRefInvalidChars { get { return m_strFieldRefInvalidChars; } } private static string m_strFieldRefMultiMatch = @"Multiple entries match the specified identifying field."; /// /// Look up a localized string similar to /// 'Multiple entries match the specified identifying field.'. /// public static string FieldRefMultiMatch { get { return m_strFieldRefMultiMatch; } } private static string m_strFieldRefMultiMatchHint = @"To avoid ambiguity, entries can be identified by their UUIDs, which are unique."; /// /// Look up a localized string similar to /// 'To avoid ambiguity, entries can be identified by their UUIDs, which are unique.'. /// public static string FieldRefMultiMatchHint { get { return m_strFieldRefMultiMatchHint; } } private static string m_strFieldValue = @"Field Value"; /// /// Look up a localized string similar to /// 'Field Value'. /// public static string FieldValue { get { return m_strFieldValue; } } private static string m_strFile = @"File"; /// /// Look up a localized string similar to /// 'File'. /// public static string File { get { return m_strFile; } } private static string m_strFileChanged = @"The file on disk/server has changed since it was loaded. Probably someone else has edited and saved the database."; /// /// Look up a localized string similar to /// 'The file on disk/server has changed since it was loaded. Probably someone else has edited and saved the database.'. /// public static string FileChanged { get { return m_strFileChanged; } } private static string m_strFileChangedOverwrite = @"Save the current database to the file. Changes made by the other user will be lost."; /// /// Look up a localized string similar to /// 'Save the current database to the file. Changes made by the other user will be lost.'. /// public static string FileChangedOverwrite { get { return m_strFileChangedOverwrite; } } private static string m_strFileChangedSync = @"Load the file on disk/server and merge it with the current database in memory."; /// /// Look up a localized string similar to /// 'Load the file on disk/server and merge it with the current database in memory.'. /// public static string FileChangedSync { get { return m_strFileChangedSync; } } private static string m_strFileExists = @"File exists"; /// /// Look up a localized string similar to /// 'File exists'. /// public static string FileExists { get { return m_strFileExists; } } private static string m_strFileExistsAlready = @"The following file exists already:"; /// /// Look up a localized string similar to /// 'The following file exists already:'. /// public static string FileExistsAlready { get { return m_strFileExistsAlready; } } private static string m_strFileExtInstallFailed = @"Failed to create the file association. Make sure you have write access to the file associations list."; /// /// Look up a localized string similar to /// 'Failed to create the file association. Make sure you have write access to the file associations list.'. /// public static string FileExtInstallFailed { get { return m_strFileExtInstallFailed; } } private static string m_strFileExtInstallSuccess = @"Successfully associated KDBX files with KeePass! KDBX files will now be opened by KeePass when you double-click on them."; /// /// Look up a localized string similar to /// 'Successfully associated KDBX files with KeePass! KDBX files will now be opened by KeePass when you double-click on them.'. /// public static string FileExtInstallSuccess { get { return m_strFileExtInstallSuccess; } } private static string m_strFileExtName = @"KeePass Password Database"; /// /// Look up a localized string similar to /// 'KeePass Password Database'. /// public static string FileExtName { get { return m_strFileExtName; } } private static string m_strFileFormatStc = @"File format"; /// /// Look up a localized string similar to /// 'File format'. /// public static string FileFormatStc { get { return m_strFileFormatStc; } } private static string m_strFileLockedBy = @"The specified file is currently locked by the following user:"; /// /// Look up a localized string similar to /// 'The specified file is currently locked by the following user:'. /// public static string FileLockedBy { get { return m_strFileLockedBy; } } private static string m_strFileLockedWarning = @"KeePass will open the file, but note that you might overwrite changes each other when saving."; /// /// Look up a localized string similar to /// 'KeePass will open the file, but note that you might overwrite changes each other when saving.'. /// public static string FileLockedWarning { get { return m_strFileLockedWarning; } } private static string m_strFileNameContainsSemicolonError = @"This file path contains a semicolon (;) and therefore cannot be processed. Replace the semicolon and repeat the procedure."; /// /// Look up a localized string similar to /// 'This file path contains a semicolon (;) and therefore cannot be processed. Replace the semicolon and repeat the procedure.'. /// public static string FileNameContainsSemicolonError { get { return m_strFileNameContainsSemicolonError; } } private static string m_strFileNotFoundError = @"The specified file could not be found."; /// /// Look up a localized string similar to /// 'The specified file could not be found.'. /// public static string FileNotFoundError { get { return m_strFileNotFoundError; } } private static string m_strFileOrUrl = @"File/URL"; /// /// Look up a localized string similar to /// 'File/URL'. /// public static string FileOrUrl { get { return m_strFileOrUrl; } } private static string m_strFiles = @"Files"; /// /// Look up a localized string similar to /// 'Files'. /// public static string Files { get { return m_strFiles; } } private static string m_strFileSaveQ = @"Do you want to save the database now?"; /// /// Look up a localized string similar to /// 'Do you want to save the database now?'. /// public static string FileSaveQ { get { return m_strFileSaveQ; } } private static string m_strFileSaveQClosing = @"Save database changes before closing the file?"; /// /// Look up a localized string similar to /// 'Save database changes before closing the file?'. /// public static string FileSaveQClosing { get { return m_strFileSaveQClosing; } } private static string m_strFileSaveQExiting = @"Save database changes before exiting KeePass?"; /// /// Look up a localized string similar to /// 'Save database changes before exiting KeePass?'. /// public static string FileSaveQExiting { get { return m_strFileSaveQExiting; } } private static string m_strFileSaveQLocking = @"Save database changes before locking the workspace?"; /// /// Look up a localized string similar to /// 'Save database changes before locking the workspace?'. /// public static string FileSaveQLocking { get { return m_strFileSaveQLocking; } } private static string m_strFileSaveQOpCancel = @"Abort the current operation."; /// /// Look up a localized string similar to /// 'Abort the current operation.'. /// public static string FileSaveQOpCancel { get { return m_strFileSaveQOpCancel; } } private static string m_strFileSaveQOpCancelClosing = @"The file will not be closed."; /// /// Look up a localized string similar to /// 'The file will not be closed.'. /// public static string FileSaveQOpCancelClosing { get { return m_strFileSaveQOpCancelClosing; } } private static string m_strFileSaveQOpCancelExiting = @"KeePass will not be closed."; /// /// Look up a localized string similar to /// 'KeePass will not be closed.'. /// public static string FileSaveQOpCancelExiting { get { return m_strFileSaveQOpCancelExiting; } } private static string m_strFileSaveQOpCancelLocking = @"The KeePass workspace will not be locked."; /// /// Look up a localized string similar to /// 'The KeePass workspace will not be locked.'. /// public static string FileSaveQOpCancelLocking { get { return m_strFileSaveQOpCancelLocking; } } private static string m_strFileSaveQOpNoClosing = @"Discard all changes made to the database and close the file."; /// /// Look up a localized string similar to /// 'Discard all changes made to the database and close the file.'. /// public static string FileSaveQOpNoClosing { get { return m_strFileSaveQOpNoClosing; } } private static string m_strFileSaveQOpNoExiting = @"Discard all changes made to the database and exit KeePass."; /// /// Look up a localized string similar to /// 'Discard all changes made to the database and exit KeePass.'. /// public static string FileSaveQOpNoExiting { get { return m_strFileSaveQOpNoExiting; } } private static string m_strFileSaveQOpNoLocking = @"Discard all changes made to the database and lock the KeePass workspace."; /// /// Look up a localized string similar to /// 'Discard all changes made to the database and lock the KeePass workspace.'. /// public static string FileSaveQOpNoLocking { get { return m_strFileSaveQOpNoLocking; } } private static string m_strFileSaveQOpYesClosing = @"Save all changes made to the database and close the file."; /// /// Look up a localized string similar to /// 'Save all changes made to the database and close the file.'. /// public static string FileSaveQOpYesClosing { get { return m_strFileSaveQOpYesClosing; } } private static string m_strFileSaveQOpYesExiting = @"Save all changes made to the database and exit KeePass."; /// /// Look up a localized string similar to /// 'Save all changes made to the database and exit KeePass.'. /// public static string FileSaveQOpYesExiting { get { return m_strFileSaveQOpYesExiting; } } private static string m_strFileSaveQOpYesLocking = @"Save all changes made to the database and lock the KeePass workspace."; /// /// Look up a localized string similar to /// 'Save all changes made to the database and lock the KeePass workspace.'. /// public static string FileSaveQOpYesLocking { get { return m_strFileSaveQOpYesLocking; } } private static string m_strFileTooLarge = @"The file is too large."; /// /// Look up a localized string similar to /// 'The file is too large.'. /// public static string FileTooLarge { get { return m_strFileTooLarge; } } private static string m_strFileTxExtra = @"Extra-safe file transactions"; /// /// Look up a localized string similar to /// 'Extra-safe file transactions'. /// public static string FileTxExtra { get { return m_strFileTxExtra; } } private static string m_strFileVerifyHashFail = @"The new file's content does not match the data that KeePass has written, i.e. writing to the file has failed and it might be corrupted now."; /// /// Look up a localized string similar to /// 'The new file's content does not match the data that KeePass has written, i.e. writing to the file has failed and it might be corrupted now.'. /// public static string FileVerifyHashFail { get { return m_strFileVerifyHashFail; } } private static string m_strFileVerifyHashFailRec = @"Please try saving again, and if that fails, save the database to a different location."; /// /// Look up a localized string similar to /// 'Please try saving again, and if that fails, save the database to a different location.'. /// public static string FileVerifyHashFailRec { get { return m_strFileVerifyHashFailRec; } } private static string m_strFilter = @"Filter"; /// /// Look up a localized string similar to /// 'Filter'. /// public static string Filter { get { return m_strFilter; } } private static string m_strFind = @"Find"; /// /// Look up a localized string similar to /// 'Find'. /// public static string Find { get { return m_strFind; } } private static string m_strFocusQuickFindOnRestore = @"Focus quick search box when restoring from taskbar"; /// /// Look up a localized string similar to /// 'Focus quick search box when restoring from taskbar'. /// public static string FocusQuickFindOnRestore { get { return m_strFocusQuickFindOnRestore; } } private static string m_strFocusQuickFindOnUntray = @"Focus quick search box when restoring from tray"; /// /// Look up a localized string similar to /// 'Focus quick search box when restoring from tray'. /// public static string FocusQuickFindOnUntray { get { return m_strFocusQuickFindOnUntray; } } private static string m_strFocusResultsAfterQuickSearch = @"Focus entry list after a successful quick search"; /// /// Look up a localized string similar to /// 'Focus entry list after a successful quick search'. /// public static string FocusResultsAfterQuickSearch { get { return m_strFocusResultsAfterQuickSearch; } } private static string m_strFolder = @"Folder"; /// /// Look up a localized string similar to /// 'Folder'. /// public static string Folder { get { return m_strFolder; } } private static string m_strFont = @"Font"; /// /// Look up a localized string similar to /// 'Font'. /// public static string Font { get { return m_strFont; } } private static string m_strFontDefault = @"Default &Font"; /// /// Look up a localized string similar to /// 'Default &Font'. /// public static string FontDefault { get { return m_strFontDefault; } } private static string m_strForceSystemFontUnix = @"Force using system font (Unix only)"; /// /// Look up a localized string similar to /// 'Force using system font (Unix only)'. /// public static string ForceSystemFontUnix { get { return m_strForceSystemFontUnix; } } private static string m_strFormat = @"Format"; /// /// Look up a localized string similar to /// 'Format'. /// public static string Format { get { return m_strFormat; } } private static string m_strFormatNoDatabaseDesc = @"This file format doesn't support database descriptions."; /// /// Look up a localized string similar to /// 'This file format doesn't support database descriptions.'. /// public static string FormatNoDatabaseDesc { get { return m_strFormatNoDatabaseDesc; } } private static string m_strFormatNoDatabaseName = @"This file format doesn't support database names."; /// /// Look up a localized string similar to /// 'This file format doesn't support database names.'. /// public static string FormatNoDatabaseName { get { return m_strFormatNoDatabaseName; } } private static string m_strFormatNoRootEntries = @"This file format doesn't support root groups. All entries in the root group are moved to the first subgroup."; /// /// Look up a localized string similar to /// 'This file format doesn't support root groups. All entries in the root group are moved to the first subgroup.'. /// public static string FormatNoRootEntries { get { return m_strFormatNoRootEntries; } } private static string m_strFormatNoSubGroupsInRoot = @"To export to this file format, the root group must have at least one subgroup."; /// /// Look up a localized string similar to /// 'To export to this file format, the root group must have at least one subgroup.'. /// public static string FormatNoSubGroupsInRoot { get { return m_strFormatNoSubGroupsInRoot; } } private static string m_strFormatOnlyOneAttachment = @"This file format only supports one attachment per entry. Only the first attachment is saved, the others are ignored."; /// /// Look up a localized string similar to /// 'This file format only supports one attachment per entry. Only the first attachment is saved, the others are ignored.'. /// public static string FormatOnlyOneAttachment { get { return m_strFormatOnlyOneAttachment; } } private static string m_strGeneral = @"General"; /// /// Look up a localized string similar to /// 'General'. /// public static string General { get { return m_strGeneral; } } private static string m_strGenerate = @"Generate"; /// /// Look up a localized string similar to /// 'Generate'. /// public static string Generate { get { return m_strGenerate; } } private static string m_strGenerateCount = @"Generated Passwords Count"; /// /// Look up a localized string similar to /// 'Generated Passwords Count'. /// public static string GenerateCount { get { return m_strGenerateCount; } } private static string m_strGenerateCountDesc = @"Enter number of passwords to generate."; /// /// Look up a localized string similar to /// 'Enter number of passwords to generate.'. /// public static string GenerateCountDesc { get { return m_strGenerateCountDesc; } } private static string m_strGenerateCountLongDesc = @"Please enter the number of passwords to generate:"; /// /// Look up a localized string similar to /// 'Please enter the number of passwords to generate:'. /// public static string GenerateCountLongDesc { get { return m_strGenerateCountLongDesc; } } private static string m_strGeneratedPasswordSamples = @"Generated Passwords Samples"; /// /// Look up a localized string similar to /// 'Generated Passwords Samples'. /// public static string GeneratedPasswordSamples { get { return m_strGeneratedPasswordSamples; } } private static string m_strGeneratePassword = @"Generate a password"; /// /// Look up a localized string similar to /// 'Generate a password'. /// public static string GeneratePassword { get { return m_strGeneratePassword; } } private static string m_strGenericCsvImporter = @"Generic CSV Importer"; /// /// Look up a localized string similar to /// 'Generic CSV Importer'. /// public static string GenericCsvImporter { get { return m_strGenericCsvImporter; } } private static string m_strGenProfileRemove = @"Remove selected profile"; /// /// Look up a localized string similar to /// 'Remove selected profile'. /// public static string GenProfileRemove { get { return m_strGenProfileRemove; } } private static string m_strGenProfileRemoveDesc = @"Remove the currently selected profile."; /// /// Look up a localized string similar to /// 'Remove the currently selected profile.'. /// public static string GenProfileRemoveDesc { get { return m_strGenProfileRemoveDesc; } } private static string m_strGenProfileSave = @"Save as Profile"; /// /// Look up a localized string similar to /// 'Save as Profile'. /// public static string GenProfileSave { get { return m_strGenProfileSave; } } private static string m_strGenProfileSaveDesc = @"Save current settings as a profile."; /// /// Look up a localized string similar to /// 'Save current settings as a profile.'. /// public static string GenProfileSaveDesc { get { return m_strGenProfileSaveDesc; } } private static string m_strGenProfileSaveDescLong = @"Please enter a name for the new password generator profile, or select an existing profile name to overwrite it:"; /// /// Look up a localized string similar to /// 'Please enter a name for the new password generator profile, or select an existing profile name to overwrite it:'. /// public static string GenProfileSaveDescLong { get { return m_strGenProfileSaveDescLong; } } private static string m_strGenPwAccept = @"Accept this password?"; /// /// Look up a localized string similar to /// 'Accept this password?'. /// public static string GenPwAccept { get { return m_strGenPwAccept; } } private static string m_strGenPwBasedOnPrevious = @"Derive from previous password"; /// /// Look up a localized string similar to /// 'Derive from previous password'. /// public static string GenPwBasedOnPrevious { get { return m_strGenPwBasedOnPrevious; } } private static string m_strGenPwSprVariant = @"The generated password contains a placeholder. When using this password (e.g. by copying it to the clipboard or auto-typing it), the placeholder will be replaced, i.e. effectively a different password might be used."; /// /// Look up a localized string similar to /// 'The generated password contains a placeholder. When using this password (e.g. by copying it to the clipboard or auto-typing it), the placeholder will be replaced, i.e. effectively a different password might be used.'. /// public static string GenPwSprVariant { get { return m_strGenPwSprVariant; } } private static string m_strGradient = @"Gradient"; /// /// Look up a localized string similar to /// 'Gradient'. /// public static string Gradient { get { return m_strGradient; } } private static string m_strGroup = @"Group"; /// /// Look up a localized string similar to /// 'Group'. /// public static string Group { get { return m_strGroup; } } private static string m_strGroupCannotStoreEntries = @"The selected group cannot store any entries."; /// /// Look up a localized string similar to /// 'The selected group cannot store any entries.'. /// public static string GroupCannotStoreEntries { get { return m_strGroupCannotStoreEntries; } } private static string m_strGroupsSkipped = @"{PARAM} groups skipped"; /// /// Look up a localized string similar to /// '{PARAM} groups skipped'. /// public static string GroupsSkipped { get { return m_strGroupsSkipped; } } private static string m_strGroupsSkipped1 = @"1 group skipped"; /// /// Look up a localized string similar to /// '1 group skipped'. /// public static string GroupsSkipped1 { get { return m_strGroupsSkipped1; } } private static string m_strHelpSourceNoLocalOption = @"This option is disabled, because local help is not installed."; /// /// Look up a localized string similar to /// 'This option is disabled, because local help is not installed.'. /// public static string HelpSourceNoLocalOption { get { return m_strHelpSourceNoLocalOption; } } private static string m_strHelpSourceSelection = @"Help Source Selection"; /// /// Look up a localized string similar to /// 'Help Source Selection'. /// public static string HelpSourceSelection { get { return m_strHelpSourceSelection; } } private static string m_strHelpSourceSelectionDesc = @"Choose between local help and online help center."; /// /// Look up a localized string similar to /// 'Choose between local help and online help center.'. /// public static string HelpSourceSelectionDesc { get { return m_strHelpSourceSelectionDesc; } } private static string m_strHexKeyEx = @"Hex Key - {PARAM}-Bit"; /// /// Look up a localized string similar to /// 'Hex Key - {PARAM}-Bit'. /// public static string HexKeyEx { get { return m_strHexKeyEx; } } private static string m_strHexViewer = @"Hex Viewer"; /// /// Look up a localized string similar to /// 'Hex Viewer'. /// public static string HexViewer { get { return m_strHexViewer; } } private static string m_strHidden = @"Hidden"; /// /// Look up a localized string similar to /// 'Hidden'. /// public static string Hidden { get { return m_strHidden; } } private static string m_strHideCloseDatabaseTb = @"Hide 'Close Database' toolbar button when at most one database is opened"; /// /// Look up a localized string similar to /// 'Hide 'Close Database' toolbar button when at most one database is opened'. /// public static string HideCloseDatabaseTb { get { return m_strHideCloseDatabaseTb; } } private static string m_strHideUsingAsterisks = @"Hide field using asterisks"; /// /// Look up a localized string similar to /// 'Hide field using asterisks'. /// public static string HideUsingAsterisks { get { return m_strHideUsingAsterisks; } } private static string m_strHistory = @"History"; /// /// Look up a localized string similar to /// 'History'. /// public static string History { get { return m_strHistory; } } private static string m_strHomebanking = @"Homebanking"; /// /// Look up a localized string similar to /// 'Homebanking'. /// public static string Homebanking { get { return m_strHomebanking; } } private static string m_strHost = @"Host"; /// /// Look up a localized string similar to /// 'Host'. /// public static string Host { get { return m_strHost; } } private static string m_strHotKeyAltOnly = @"It is highly recommended not to use global hot keys with only Alt or Alt-Shift as modifier."; /// /// Look up a localized string similar to /// 'It is highly recommended not to use global hot keys with only Alt or Alt-Shift as modifier.'. /// public static string HotKeyAltOnly { get { return m_strHotKeyAltOnly; } } private static string m_strHotKeyAltOnlyHint = @"Recommended modifiers are Ctrl-Alt, Ctrl-Shift and Ctrl-Alt-Shift."; /// /// Look up a localized string similar to /// 'Recommended modifiers are Ctrl-Alt, Ctrl-Shift and Ctrl-Alt-Shift.'. /// public static string HotKeyAltOnlyHint { get { return m_strHotKeyAltOnlyHint; } } private static string m_strHotKeyAltOnlyQuestion = @"Are you sure you want to use the specified hot keys?"; /// /// Look up a localized string similar to /// 'Are you sure you want to use the specified hot keys?'. /// public static string HotKeyAltOnlyQuestion { get { return m_strHotKeyAltOnlyQuestion; } } private static string m_strIcon = @"Icon"; /// /// Look up a localized string similar to /// 'Icon'. /// public static string Icon { get { return m_strIcon; } } private static string m_strId = @"ID"; /// /// Look up a localized string similar to /// 'ID'. /// public static string Id { get { return m_strId; } } private static string m_strIgnore = @"Ignore"; /// /// Look up a localized string similar to /// 'Ignore'. /// public static string Ignore { get { return m_strIgnore; } } private static string m_strImageFormatFeatureUnsupported = @"This file uses a file format feature that is not supported."; /// /// Look up a localized string similar to /// 'This file uses a file format feature that is not supported.'. /// public static string ImageFormatFeatureUnsupported { get { return m_strImageFormatFeatureUnsupported; } } private static string m_strImageViewer = @"Image Viewer"; /// /// Look up a localized string similar to /// 'Image Viewer'. /// public static string ImageViewer { get { return m_strImageViewer; } } private static string m_strImport = @"Import"; /// /// Look up a localized string similar to /// 'Import'. /// public static string Import { get { return m_strImport; } } private static string m_strImportBehavior = @"Import Behavior"; /// /// Look up a localized string similar to /// 'Import Behavior'. /// public static string ImportBehavior { get { return m_strImportBehavior; } } private static string m_strImportBehaviorDesc = @"Select an import method."; /// /// Look up a localized string similar to /// 'Select an import method.'. /// public static string ImportBehaviorDesc { get { return m_strImportBehaviorDesc; } } private static string m_strImportFailed = @"Import failed."; /// /// Look up a localized string similar to /// 'Import failed.'. /// public static string ImportFailed { get { return m_strImportFailed; } } private static string m_strImportFileDesc = @"Import an external file."; /// /// Look up a localized string similar to /// 'Import an external file.'. /// public static string ImportFileDesc { get { return m_strImportFileDesc; } } private static string m_strImportFilesPrompt = @"Files to be imported:"; /// /// Look up a localized string similar to /// 'Files to be imported:'. /// public static string ImportFilesPrompt { get { return m_strImportFilesPrompt; } } private static string m_strImportFileTitle = @"Import File/Data"; /// /// Look up a localized string similar to /// 'Import File/Data'. /// public static string ImportFileTitle { get { return m_strImportFileTitle; } } private static string m_strImportFinished = @"The import process has finished!"; /// /// Look up a localized string similar to /// 'The import process has finished!'. /// public static string ImportFinished { get { return m_strImportFinished; } } private static string m_strImportingStatusMsg = @"Importing..."; /// /// Look up a localized string similar to /// 'Importing...'. /// public static string ImportingStatusMsg { get { return m_strImportingStatusMsg; } } private static string m_strImportMustRead = @"It is indispensable that you read the documentation about this import method before continuing."; /// /// Look up a localized string similar to /// 'It is indispensable that you read the documentation about this import method before continuing.'. /// public static string ImportMustRead { get { return m_strImportMustRead; } } private static string m_strImportMustReadQuestion = @"Have you understood how the import process works and want to start it now?"; /// /// Look up a localized string similar to /// 'Have you understood how the import process works and want to start it now?'. /// public static string ImportMustReadQuestion { get { return m_strImportMustReadQuestion; } } private static string m_strImportStc = @"Import into active database"; /// /// Look up a localized string similar to /// 'Import into active database'. /// public static string ImportStc { get { return m_strImportStc; } } private static string m_strIncompatibleEnv = @"incompatible with current environment"; /// /// Look up a localized string similar to /// 'incompatible with current environment'. /// public static string IncompatibleEnv { get { return m_strIncompatibleEnv; } } private static string m_strIncompatibleWithSorting = @"incompatible with sorting"; /// /// Look up a localized string similar to /// 'incompatible with sorting'. /// public static string IncompatibleWithSorting { get { return m_strIncompatibleWithSorting; } } private static string m_strInheritSettingFromParent = @"Inherit setting from parent"; /// /// Look up a localized string similar to /// 'Inherit setting from parent'. /// public static string InheritSettingFromParent { get { return m_strInheritSettingFromParent; } } private static string m_strInstalled = @"Installed"; /// /// Look up a localized string similar to /// 'Installed'. /// public static string Installed { get { return m_strInstalled; } } private static string m_strInstalledLanguages = @"Installed Languages"; /// /// Look up a localized string similar to /// 'Installed Languages'. /// public static string InstalledLanguages { get { return m_strInstalledLanguages; } } private static string m_strInstrAndGenInfo = @"Instructions and General Information"; /// /// Look up a localized string similar to /// 'Instructions and General Information'. /// public static string InstrAndGenInfo { get { return m_strInstrAndGenInfo; } } private static string m_strInterleavedKeySending = @"Allow interleaved sending of keys"; /// /// Look up a localized string similar to /// 'Allow interleaved sending of keys'. /// public static string InterleavedKeySending { get { return m_strInterleavedKeySending; } } private static string m_strInternalEditor = @"Internal Editor"; /// /// Look up a localized string similar to /// 'Internal Editor'. /// public static string InternalEditor { get { return m_strInternalEditor; } } private static string m_strInternalViewer = @"Internal Viewer"; /// /// Look up a localized string similar to /// 'Internal Viewer'. /// public static string InternalViewer { get { return m_strInternalViewer; } } private static string m_strInternet = @"Internet"; /// /// Look up a localized string similar to /// 'Internet'. /// public static string Internet { get { return m_strInternet; } } private static string m_strInvalidKey = @"Invalid Key"; /// /// Look up a localized string similar to /// 'Invalid Key'. /// public static string InvalidKey { get { return m_strInvalidKey; } } private static string m_strInvalidUrl = @"The specified URL is invalid."; /// /// Look up a localized string similar to /// 'The specified URL is invalid.'. /// public static string InvalidUrl { get { return m_strInvalidUrl; } } private static string m_strInvalidUserPassword = @"The specified user name / password combination is invalid."; /// /// Look up a localized string similar to /// 'The specified user name / password combination is invalid.'. /// public static string InvalidUserPassword { get { return m_strInvalidUserPassword; } } private static string m_strIOConnection = @"IO Connection"; /// /// Look up a localized string similar to /// 'IO Connection'. /// public static string IOConnection { get { return m_strIOConnection; } } private static string m_strIOConnectionLong = @"File Input/Output Connections"; /// /// Look up a localized string similar to /// 'File Input/Output Connections'. /// public static string IOConnectionLong { get { return m_strIOConnectionLong; } } private static string m_strItalic = @"Italic"; /// /// Look up a localized string similar to /// 'Italic'. /// public static string Italic { get { return m_strItalic; } } private static string m_strIterations = @"Iterations"; /// /// Look up a localized string similar to /// 'Iterations'. /// public static string Iterations { get { return m_strIterations; } } private static string m_strKdbKeePassLibC = @"The KeePassLibC library is required to open and save KDB files created by KeePass 1.x."; /// /// Look up a localized string similar to /// 'The KeePassLibC library is required to open and save KDB files created by KeePass 1.x.'. /// public static string KdbKeePassLibC { get { return m_strKdbKeePassLibC; } } private static string m_strKdbWUA = @"KDB files can be encrypted using a master password and/or a key file, not using a Windows User Account."; /// /// Look up a localized string similar to /// 'KDB files can be encrypted using a master password and/or a key file, not using a Windows User Account.'. /// public static string KdbWUA { get { return m_strKdbWUA; } } private static string m_strKdbxFiles = @"KeePass KDBX Files"; /// /// Look up a localized string similar to /// 'KeePass KDBX Files'. /// public static string KdbxFiles { get { return m_strKdbxFiles; } } private static string m_strKdfAdjust = @"The value of a key derivation function parameter lies outside the range of valid values. KeePass adjusts the value to the nearest valid value."; /// /// Look up a localized string similar to /// 'The value of a key derivation function parameter lies outside the range of valid values. KeePass adjusts the value to the nearest valid value.'. /// public static string KdfAdjust { get { return m_strKdfAdjust; } } private static string m_strKdfParams1Sec = @"Compute parameters that lead to a delay of 1 second on this computer."; /// /// Look up a localized string similar to /// 'Compute parameters that lead to a delay of 1 second on this computer.'. /// public static string KdfParams1Sec { get { return m_strKdfParams1Sec; } } private static string m_strKeePassLibCLong = @"KeePassLibC (1.x File Support)"; /// /// Look up a localized string similar to /// 'KeePassLibC (1.x File Support)'. /// public static string KeePassLibCLong { get { return m_strKeePassLibCLong; } } private static string m_strKeePassLibCNotFound = @"KeePassLibC could not be found."; /// /// Look up a localized string similar to /// 'KeePassLibC could not be found.'. /// public static string KeePassLibCNotFound { get { return m_strKeePassLibCNotFound; } } private static string m_strKeePassLibCNotWindows = @"Importing/exporting data from/to KDB files is only supported on Windows (because a library is used that contains the core code of KeePass 1.x, which is Windows-only)."; /// /// Look up a localized string similar to /// 'Importing/exporting data from/to KDB files is only supported on Windows (because a library is used that contains the core code of KeePass 1.x, which is Windows-only).'. /// public static string KeePassLibCNotWindows { get { return m_strKeePassLibCNotWindows; } } private static string m_strKeePassLibCNotWindowsHint = @"Please use a different file format for migrating your data."; /// /// Look up a localized string similar to /// 'Please use a different file format for migrating your data.'. /// public static string KeePassLibCNotWindowsHint { get { return m_strKeePassLibCNotWindowsHint; } } private static string m_strKeepExisting = @"&Keep existing"; /// /// Look up a localized string similar to /// '&Keep existing'. /// public static string KeepExisting { get { return m_strKeepExisting; } } private static string m_strKeyboardKeyAlt = @"Alt"; /// /// Look up a localized string similar to /// 'Alt'. /// public static string KeyboardKeyAlt { get { return m_strKeyboardKeyAlt; } } private static string m_strKeyboardKeyCtrl = @"Ctrl"; /// /// Look up a localized string similar to /// 'Ctrl'. /// public static string KeyboardKeyCtrl { get { return m_strKeyboardKeyCtrl; } } private static string m_strKeyboardKeyCtrlLeft = @"LCtrl"; /// /// Look up a localized string similar to /// 'LCtrl'. /// public static string KeyboardKeyCtrlLeft { get { return m_strKeyboardKeyCtrlLeft; } } private static string m_strKeyboardKeyEsc = @"Esc"; /// /// Look up a localized string similar to /// 'Esc'. /// public static string KeyboardKeyEsc { get { return m_strKeyboardKeyEsc; } } private static string m_strKeyboardKeyModifiers = @"Key Modifiers"; /// /// Look up a localized string similar to /// 'Key Modifiers'. /// public static string KeyboardKeyModifiers { get { return m_strKeyboardKeyModifiers; } } private static string m_strKeyboardKeyReturn = @"Return"; /// /// Look up a localized string similar to /// 'Return'. /// public static string KeyboardKeyReturn { get { return m_strKeyboardKeyReturn; } } private static string m_strKeyboardKeyShift = @"Shift"; /// /// Look up a localized string similar to /// 'Shift'. /// public static string KeyboardKeyShift { get { return m_strKeyboardKeyShift; } } private static string m_strKeyboardKeyShiftLeft = @"LShift"; /// /// Look up a localized string similar to /// 'LShift'. /// public static string KeyboardKeyShiftLeft { get { return m_strKeyboardKeyShiftLeft; } } private static string m_strKeyFile = @"Key file"; /// /// Look up a localized string similar to /// 'Key file'. /// public static string KeyFile { get { return m_strKeyFile; } } private static string m_strKeyFileCreate = @"Create a new key file"; /// /// Look up a localized string similar to /// 'Create a new key file'. /// public static string KeyFileCreate { get { return m_strKeyFileCreate; } } private static string m_strKeyFileError = @"The specified key file could not be found or its format is unknown."; /// /// Look up a localized string similar to /// 'The specified key file could not be found or its format is unknown.'. /// public static string KeyFileError { get { return m_strKeyFileError; } } private static string m_strKeyFiles = @"Key Files"; /// /// Look up a localized string similar to /// 'Key Files'. /// public static string KeyFiles { get { return m_strKeyFiles; } } private static string m_strKeyFileSelect = @"Select key file manually"; /// /// Look up a localized string similar to /// 'Select key file manually'. /// public static string KeyFileSelect { get { return m_strKeyFileSelect; } } private static string m_strKeyFileUseExisting = @"Use an existing file as key file"; /// /// Look up a localized string similar to /// 'Use an existing file as key file'. /// public static string KeyFileUseExisting { get { return m_strKeyFileUseExisting; } } private static string m_strKeyProvider = @"Key provider"; /// /// Look up a localized string similar to /// 'Key provider'. /// public static string KeyProvider { get { return m_strKeyProvider; } } private static string m_strKeyProvIncmpWithSD = @"The selected key provider cannot be used, because it is incompatible with the secure desktop."; /// /// Look up a localized string similar to /// 'The selected key provider cannot be used, because it is incompatible with the secure desktop.'. /// public static string KeyProvIncmpWithSD { get { return m_strKeyProvIncmpWithSD; } } private static string m_strKeyProvIncmpWithSDHint = @"If you want to use the selected key provider, you have to disable the secure desktop option in 'Tools' -> 'Options' -> tab 'Security'."; /// /// Look up a localized string similar to /// 'If you want to use the selected key provider, you have to disable the secure desktop option in 'Tools' -> 'Options' -> tab 'Security'.'. /// public static string KeyProvIncmpWithSDHint { get { return m_strKeyProvIncmpWithSDHint; } } private static string m_strLanguageSelected = @"The selected language has been activated. KeePass must be restarted in order to load the language."; /// /// Look up a localized string similar to /// 'The selected language has been activated. KeePass must be restarted in order to load the language.'. /// public static string LanguageSelected { get { return m_strLanguageSelected; } } private static string m_strLastAccessTime = @"Last Access Time"; /// /// Look up a localized string similar to /// 'Last Access Time'. /// public static string LastAccessTime { get { return m_strLastAccessTime; } } private static string m_strLastModificationTime = @"Last Modification Time"; /// /// Look up a localized string similar to /// 'Last Modification Time'. /// public static string LastModificationTime { get { return m_strLastModificationTime; } } private static string m_strLastModTimePwHist = @"Last Password Modification Time (Based on History)"; /// /// Look up a localized string similar to /// 'Last Password Modification Time (Based on History)'. /// public static string LastModTimePwHist { get { return m_strLastModTimePwHist; } } private static string m_strLatestVersionWeb = @"The latest KeePass version can be found on the KeePass website"; /// /// Look up a localized string similar to /// 'The latest KeePass version can be found on the KeePass website'. /// public static string LatestVersionWeb { get { return m_strLatestVersionWeb; } } private static string m_strLimitSingleInstance = @"Limit to single instance"; /// /// Look up a localized string similar to /// 'Limit to single instance'. /// public static string LimitSingleInstance { get { return m_strLimitSingleInstance; } } private static string m_strLngInAppDir = @"One or more language files have been found in the KeePass application directory."; /// /// Look up a localized string similar to /// 'One or more language files have been found in the KeePass application directory.'. /// public static string LngInAppDir { get { return m_strLngInAppDir; } } private static string m_strLngInAppDirNote = @"Loading language files directly from the application directory is not supported. Language files should instead be stored in the 'Languages' folder of the application directory."; /// /// Look up a localized string similar to /// 'Loading language files directly from the application directory is not supported. Language files should instead be stored in the 'Languages' folder of the application directory.'. /// public static string LngInAppDirNote { get { return m_strLngInAppDirNote; } } private static string m_strLngInAppDirQ = @"Do you want to open the application directory (in order to move or delete language files)?"; /// /// Look up a localized string similar to /// 'Do you want to open the application directory (in order to move or delete language files)?'. /// public static string LngInAppDirQ { get { return m_strLngInAppDirQ; } } private static string m_strLocked = @"Locked"; /// /// Look up a localized string similar to /// 'Locked'. /// public static string Locked { get { return m_strLocked; } } private static string m_strLockMenuLock = @"&Lock Workspace"; /// /// Look up a localized string similar to /// '&Lock Workspace'. /// public static string LockMenuLock { get { return m_strLockMenuLock; } } private static string m_strLockMenuUnlock = @"Un&lock Workspace"; /// /// Look up a localized string similar to /// 'Un&lock Workspace'. /// public static string LockMenuUnlock { get { return m_strLockMenuUnlock; } } private static string m_strLockOnMinimizeTaskbar = @"Lock workspace when minimizing main window to taskbar"; /// /// Look up a localized string similar to /// 'Lock workspace when minimizing main window to taskbar'. /// public static string LockOnMinimizeTaskbar { get { return m_strLockOnMinimizeTaskbar; } } private static string m_strLockOnMinimizeTray = @"Lock workspace when minimizing main window to tray"; /// /// Look up a localized string similar to /// 'Lock workspace when minimizing main window to tray'. /// public static string LockOnMinimizeTray { get { return m_strLockOnMinimizeTray; } } private static string m_strLockOnRemoteControlChange = @"Lock workspace when the remote control mode changes"; /// /// Look up a localized string similar to /// 'Lock workspace when the remote control mode changes'. /// public static string LockOnRemoteControlChange { get { return m_strLockOnRemoteControlChange; } } private static string m_strLockOnSessionSwitch = @"Lock workspace when locking the computer or switching the user"; /// /// Look up a localized string similar to /// 'Lock workspace when locking the computer or switching the user'. /// public static string LockOnSessionSwitch { get { return m_strLockOnSessionSwitch; } } private static string m_strLockOnSuspend = @"Lock workspace when the computer is about to be suspended"; /// /// Look up a localized string similar to /// 'Lock workspace when the computer is about to be suspended'. /// public static string LockOnSuspend { get { return m_strLockOnSuspend; } } private static string m_strMainInstruction = @"Main instruction"; /// /// Look up a localized string similar to /// 'Main instruction'. /// public static string MainInstruction { get { return m_strMainInstruction; } } private static string m_strMainWindow = @"Main Window"; /// /// Look up a localized string similar to /// 'Main Window'. /// public static string MainWindow { get { return m_strMainWindow; } } private static string m_strMasterKey = @"Master Key"; /// /// Look up a localized string similar to /// 'Master Key'. /// public static string MasterKey { get { return m_strMasterKey; } } private static string m_strMasterKeyChanged = @"The master key has been changed!"; /// /// Look up a localized string similar to /// 'The master key has been changed!'. /// public static string MasterKeyChanged { get { return m_strMasterKeyChanged; } } private static string m_strMasterKeyChangedSave = @"In order to apply the new master key, the database must be saved."; /// /// Look up a localized string similar to /// 'In order to apply the new master key, the database must be saved.'. /// public static string MasterKeyChangedSave { get { return m_strMasterKeyChangedSave; } } private static string m_strMasterKeyChangedShort = @"Master key changed"; /// /// Look up a localized string similar to /// 'Master key changed'. /// public static string MasterKeyChangedShort { get { return m_strMasterKeyChangedShort; } } private static string m_strMasterKeyChangeForce = @"The master key for this database has been used for quite a while and must be changed now."; /// /// Look up a localized string similar to /// 'The master key for this database has been used for quite a while and must be changed now.'. /// public static string MasterKeyChangeForce { get { return m_strMasterKeyChangeForce; } } private static string m_strMasterKeyChangeInfo = @"Click [OK] to open the master key changing dialog."; /// /// Look up a localized string similar to /// 'Click [OK] to open the master key changing dialog.'. /// public static string MasterKeyChangeInfo { get { return m_strMasterKeyChangeInfo; } } private static string m_strMasterKeyChangeQ = @"Do you want to change the master key now?"; /// /// Look up a localized string similar to /// 'Do you want to change the master key now?'. /// public static string MasterKeyChangeQ { get { return m_strMasterKeyChangeQ; } } private static string m_strMasterKeyChangeRec = @"The master key for this database has been used for quite a while and it is recommended to change it now."; /// /// Look up a localized string similar to /// 'The master key for this database has been used for quite a while and it is recommended to change it now.'. /// public static string MasterKeyChangeRec { get { return m_strMasterKeyChangeRec; } } private static string m_strMasterKeyComponents = @"The master key for this database file consists of the following components:"; /// /// Look up a localized string similar to /// 'The master key for this database file consists of the following components:'. /// public static string MasterKeyComponents { get { return m_strMasterKeyComponents; } } private static string m_strMasterKeyOnSecureDesktop = @"Enter master key on secure desktop"; /// /// Look up a localized string similar to /// 'Enter master key on secure desktop'. /// public static string MasterKeyOnSecureDesktop { get { return m_strMasterKeyOnSecureDesktop; } } private static string m_strMasterPassword = @"Master password"; /// /// Look up a localized string similar to /// 'Master password'. /// public static string MasterPassword { get { return m_strMasterPassword; } } private static string m_strMasterPasswordMinLengthFailed = @"The master password must be at least {PARAM} characters long!"; /// /// Look up a localized string similar to /// 'The master password must be at least {PARAM} characters long!'. /// public static string MasterPasswordMinLengthFailed { get { return m_strMasterPasswordMinLengthFailed; } } private static string m_strMasterPasswordMinQualityFailed = @"The estimated quality of the master password must be at least {PARAM} bits!"; /// /// Look up a localized string similar to /// 'The estimated quality of the master password must be at least {PARAM} bits!'. /// public static string MasterPasswordMinQualityFailed { get { return m_strMasterPasswordMinQualityFailed; } } private static string m_strMaxAttachmentSize = @"The maximum supported attachment size is {PARAM}."; /// /// Look up a localized string similar to /// 'The maximum supported attachment size is {PARAM}.'. /// public static string MaxAttachmentSize { get { return m_strMaxAttachmentSize; } } private static string m_strMaximized = @"Maximized"; /// /// Look up a localized string similar to /// 'Maximized'. /// public static string Maximized { get { return m_strMaximized; } } private static string m_strMemory = @"Memory"; /// /// Look up a localized string similar to /// 'Memory'. /// public static string Memory { get { return m_strMemory; } } private static string m_strMenus = @"Menus"; /// /// Look up a localized string similar to /// 'Menus'. /// public static string Menus { get { return m_strMenus; } } private static string m_strMethod = @"Method"; /// /// Look up a localized string similar to /// 'Method'. /// public static string Method { get { return m_strMethod; } } private static string m_strMinimizeAfterCopy = @"Minimize main window after copying data to the clipboard"; /// /// Look up a localized string similar to /// 'Minimize main window after copying data to the clipboard'. /// public static string MinimizeAfterCopy { get { return m_strMinimizeAfterCopy; } } private static string m_strMinimizeAfterLocking = @"Minimize main window after locking the workspace"; /// /// Look up a localized string similar to /// 'Minimize main window after locking the workspace'. /// public static string MinimizeAfterLocking { get { return m_strMinimizeAfterLocking; } } private static string m_strMinimizeAfterOpeningDatabase = @"Minimize main window after opening a database"; /// /// Look up a localized string similar to /// 'Minimize main window after opening a database'. /// public static string MinimizeAfterOpeningDatabase { get { return m_strMinimizeAfterOpeningDatabase; } } private static string m_strMinimized = @"Minimized"; /// /// Look up a localized string similar to /// 'Minimized'. /// public static string Minimized { get { return m_strMinimized; } } private static string m_strMinimizeToTray = @"Minimize to tray instead of taskbar"; /// /// Look up a localized string similar to /// 'Minimize to tray instead of taskbar'. /// public static string MinimizeToTray { get { return m_strMinimizeToTray; } } private static string m_strMore = @"More"; /// /// Look up a localized string similar to /// 'More'. /// public static string More { get { return m_strMore; } } private static string m_strMoreEntries = @"{PARAM} more entries"; /// /// Look up a localized string similar to /// '{PARAM} more entries'. /// public static string MoreEntries { get { return m_strMoreEntries; } } private static string m_strName = @"Name"; /// /// Look up a localized string similar to /// 'Name'. /// public static string Name { get { return m_strName; } } private static string m_strNativeLibUse = @"Use native library for faster key transformations"; /// /// Look up a localized string similar to /// 'Use native library for faster key transformations'. /// public static string NativeLibUse { get { return m_strNativeLibUse; } } private static string m_strNavigation = @"Navigation"; /// /// Look up a localized string similar to /// 'Navigation'. /// public static string Navigation { get { return m_strNavigation; } } private static string m_strNetwork = @"Network"; /// /// Look up a localized string similar to /// 'Network'. /// public static string Network { get { return m_strNetwork; } } private static string m_strNeverExpires = @"Never expires"; /// /// Look up a localized string similar to /// 'Never expires'. /// public static string NeverExpires { get { return m_strNeverExpires; } } private static string m_strNew = @"New"; /// /// Look up a localized string similar to /// 'New'. /// public static string New { get { return m_strNew; } } private static string m_strNewDatabase = @"New Database"; /// /// Look up a localized string similar to /// 'New Database'. /// public static string NewDatabase { get { return m_strNewDatabase; } } private static string m_strNewDatabaseFileName = @"NewDatabase.kdbx"; /// /// Look up a localized string similar to /// 'NewDatabase.kdbx'. /// public static string NewDatabaseFileName { get { return m_strNewDatabaseFileName; } } private static string m_strNewerNetRequired = @"A newer .NET Framework is required."; /// /// Look up a localized string similar to /// 'A newer .NET Framework is required.'. /// public static string NewerNetRequired { get { return m_strNewerNetRequired; } } private static string m_strNewGroup = @"New Group"; /// /// Look up a localized string similar to /// 'New Group'. /// public static string NewGroup { get { return m_strNewGroup; } } private static string m_strNewLine = @"New line"; /// /// Look up a localized string similar to /// 'New line'. /// public static string NewLine { get { return m_strNewLine; } } private static string m_strNewState = @"New state"; /// /// Look up a localized string similar to /// 'New state'. /// public static string NewState { get { return m_strNewState; } } private static string m_strNewVersionAvailable = @"New version available"; /// /// Look up a localized string similar to /// 'New version available'. /// public static string NewVersionAvailable { get { return m_strNewVersionAvailable; } } private static string m_strNo = @"No"; /// /// Look up a localized string similar to /// 'No'. /// public static string No { get { return m_strNo; } } private static string m_strNoCmd = @"&No"; /// /// Look up a localized string similar to /// '&No'. /// public static string NoCmd { get { return m_strNoCmd; } } private static string m_strNoEncNoCompress = @"Make sure that it is not encrypted and not compressed."; /// /// Look up a localized string similar to /// 'Make sure that it is not encrypted and not compressed.'. /// public static string NoEncNoCompress { get { return m_strNoEncNoCompress; } } private static string m_strNoFileAccessRead = @"The operating system didn't grant KeePass read access to the specified file."; /// /// Look up a localized string similar to /// 'The operating system didn't grant KeePass read access to the specified file.'. /// public static string NoFileAccessRead { get { return m_strNoFileAccessRead; } } private static string m_strNoKeyFileSpecifiedMeta = @"(None)"; /// /// Look up a localized string similar to /// '(None)'. /// public static string NoKeyFileSpecifiedMeta { get { return m_strNoKeyFileSpecifiedMeta; } } private static string m_strNoKeyRepeat = @"No Key Repeat"; /// /// Look up a localized string similar to /// 'No Key Repeat'. /// public static string NoKeyRepeat { get { return m_strNoKeyRepeat; } } private static string m_strNone = @"None"; /// /// Look up a localized string similar to /// 'None'. /// public static string None { get { return m_strNone; } } private static string m_strNormal = @"Normal"; /// /// Look up a localized string similar to /// 'Normal'. /// public static string Normal { get { return m_strNormal; } } private static string m_strNoSort = @"&No Sort"; /// /// Look up a localized string similar to /// '&No Sort'. /// public static string NoSort { get { return m_strNoSort; } } private static string m_strNot = @"Not"; /// /// Look up a localized string similar to /// 'Not'. /// public static string Not { get { return m_strNot; } } private static string m_strNotNow = @"Not now"; /// /// Look up a localized string similar to /// 'Not now'. /// public static string NotNow { get { return m_strNotNow; } } private static string m_strNotRecommended = @"(not recommended)"; /// /// Look up a localized string similar to /// '(not recommended)'. /// public static string NotRecommended { get { return m_strNotRecommended; } } private static string m_strNotes = @"Notes"; /// /// Look up a localized string similar to /// 'Notes'. /// public static string Notes { get { return m_strNotes; } } private static string m_strNotInstalled = @"Not installed"; /// /// Look up a localized string similar to /// 'Not installed'. /// public static string NotInstalled { get { return m_strNotInstalled; } } private static string m_strNoXslFile = @"The selected file isn't a valid XSL stylesheet."; /// /// Look up a localized string similar to /// 'The selected file isn't a valid XSL stylesheet.'. /// public static string NoXslFile { get { return m_strNoXslFile; } } private static string m_strObjectNotFound = @"The object with the specified name could not be found."; /// /// Look up a localized string similar to /// 'The object with the specified name could not be found.'. /// public static string ObjectNotFound { get { return m_strObjectNotFound; } } private static string m_strObjectsDeleted = @"{PARAM} object(s) deleted"; /// /// Look up a localized string similar to /// '{PARAM} object(s) deleted'. /// public static string ObjectsDeleted { get { return m_strObjectsDeleted; } } private static string m_strOff = @"Off"; /// /// Look up a localized string similar to /// 'Off'. /// public static string Off { get { return m_strOff; } } private static string m_strOfLower = @"of"; /// /// Look up a localized string similar to /// 'of'. /// public static string OfLower { get { return m_strOfLower; } } private static string m_strOk = @"OK"; /// /// Look up a localized string similar to /// 'OK'. /// public static string Ok { get { return m_strOk; } } private static string m_strOldFormat = @"Old Format"; /// /// Look up a localized string similar to /// 'Old Format'. /// public static string OldFormat { get { return m_strOldFormat; } } private static string m_strOn = @"On"; /// /// Look up a localized string similar to /// 'On'. /// public static string On { get { return m_strOn; } } private static string m_strOpAborted = @"Operation aborted."; /// /// Look up a localized string similar to /// 'Operation aborted.'. /// public static string OpAborted { get { return m_strOpAborted; } } private static string m_strOpenCmd = @"&Open"; /// /// Look up a localized string similar to /// '&Open'. /// public static string OpenCmd { get { return m_strOpenCmd; } } private static string m_strOpenDatabase = @"Open Database"; /// /// Look up a localized string similar to /// 'Open Database'. /// public static string OpenDatabase { get { return m_strOpenDatabase; } } private static string m_strOpenDatabaseFile = @"Open Database File"; /// /// Look up a localized string similar to /// 'Open Database File'. /// public static string OpenDatabaseFile { get { return m_strOpenDatabaseFile; } } private static string m_strOpenDatabaseFileStc = @"Open database file"; /// /// Look up a localized string similar to /// 'Open database file'. /// public static string OpenDatabaseFileStc { get { return m_strOpenDatabaseFileStc; } } private static string m_strOpened = @"Opened"; /// /// Look up a localized string similar to /// 'Opened'. /// public static string Opened { get { return m_strOpened; } } private static string m_strOpenedDatabaseFile = @"Opened database file"; /// /// Look up a localized string similar to /// 'Opened database file'. /// public static string OpenedDatabaseFile { get { return m_strOpenedDatabaseFile; } } private static string m_strOpeningDatabase = @"Opening password database..."; /// /// Look up a localized string similar to /// 'Opening password database...'. /// public static string OpeningDatabase { get { return m_strOpeningDatabase; } } private static string m_strOpenUrl = @"&Open URL(s)"; /// /// Look up a localized string similar to /// '&Open URL(s)'. /// public static string OpenUrl { get { return m_strOpenUrl; } } private static string m_strOpenWith = @"Open with {PARAM}"; /// /// Look up a localized string similar to /// 'Open with {PARAM}'. /// public static string OpenWith { get { return m_strOpenWith; } } private static string m_strOptimizeForScreenReader = @"Optimize for screen reader (only enable if you're using a screen reader)"; /// /// Look up a localized string similar to /// 'Optimize for screen reader (only enable if you're using a screen reader)'. /// public static string OptimizeForScreenReader { get { return m_strOptimizeForScreenReader; } } private static string m_strOptions = @"Options"; /// /// Look up a localized string similar to /// 'Options'. /// public static string Options { get { return m_strOptions; } } private static string m_strOptionsDesc = @"Here you can configure the global KeePass program options."; /// /// Look up a localized string similar to /// 'Here you can configure the global KeePass program options.'. /// public static string OptionsDesc { get { return m_strOptionsDesc; } } private static string m_strOtherPlaceholders = @"Other Placeholders"; /// /// Look up a localized string similar to /// 'Other Placeholders'. /// public static string OtherPlaceholders { get { return m_strOtherPlaceholders; } } private static string m_strOverridesBuiltIn = @"Built-In Overrides"; /// /// Look up a localized string similar to /// 'Built-In Overrides'. /// public static string OverridesBuiltIn { get { return m_strOverridesBuiltIn; } } private static string m_strOverridesCustom = @"Custom Overrides"; /// /// Look up a localized string similar to /// 'Custom Overrides'. /// public static string OverridesCustom { get { return m_strOverridesCustom; } } private static string m_strOverwrite = @"Overwrite"; /// /// Look up a localized string similar to /// 'Overwrite'. /// public static string Overwrite { get { return m_strOverwrite; } } private static string m_strOverwriteExisting = @"Overwrite &existing"; /// /// Look up a localized string similar to /// 'Overwrite &existing'. /// public static string OverwriteExisting { get { return m_strOverwriteExisting; } } private static string m_strOverwriteExistingFileQuestion = @"Overwrite the existing file?"; /// /// Look up a localized string similar to /// 'Overwrite the existing file?'. /// public static string OverwriteExistingFileQuestion { get { return m_strOverwriteExistingFileQuestion; } } private static string m_strOverwriteIfNewer = @"Overwrite if &newer"; /// /// Look up a localized string similar to /// 'Overwrite if &newer'. /// public static string OverwriteIfNewer { get { return m_strOverwriteIfNewer; } } private static string m_strOverwriteIfNewerAndApplyDel = @"Overwrite if newer and apply &deletions"; /// /// Look up a localized string similar to /// 'Overwrite if newer and apply &deletions'. /// public static string OverwriteIfNewerAndApplyDel { get { return m_strOverwriteIfNewerAndApplyDel; } } private static string m_strPackageInstallHint = @"Install this package and try again."; /// /// Look up a localized string similar to /// 'Install this package and try again.'. /// public static string PackageInstallHint { get { return m_strPackageInstallHint; } } private static string m_strParallelism = @"Parallelism"; /// /// Look up a localized string similar to /// 'Parallelism'. /// public static string Parallelism { get { return m_strParallelism; } } private static string m_strParamDescHelp = @"Detailed descriptions of all parameters can be found in the help manual."; /// /// Look up a localized string similar to /// 'Detailed descriptions of all parameters can be found in the help manual.'. /// public static string ParamDescHelp { get { return m_strParamDescHelp; } } private static string m_strParameters = @"Parameters"; /// /// Look up a localized string similar to /// 'Parameters'. /// public static string Parameters { get { return m_strParameters; } } private static string m_strPassword = @"Password"; /// /// Look up a localized string similar to /// 'Password'. /// public static string Password { get { return m_strPassword; } } private static string m_strPasswordLength = @"Password length"; /// /// Look up a localized string similar to /// 'Password length'. /// public static string PasswordLength { get { return m_strPasswordLength; } } private static string m_strPasswordManagers = @"Password Managers"; /// /// Look up a localized string similar to /// 'Password Managers'. /// public static string PasswordManagers { get { return m_strPasswordManagers; } } private static string m_strPasswordOptions = @"Password Generation Options"; /// /// Look up a localized string similar to /// 'Password Generation Options'. /// public static string PasswordOptions { get { return m_strPasswordOptions; } } private static string m_strPasswordOptionsDesc = @"Here you can define properties of generated passwords."; /// /// Look up a localized string similar to /// 'Here you can define properties of generated passwords.'. /// public static string PasswordOptionsDesc { get { return m_strPasswordOptionsDesc; } } private static string m_strPasswordPrompt = @"Enter the password:"; /// /// Look up a localized string similar to /// 'Enter the password:'. /// public static string PasswordPrompt { get { return m_strPasswordPrompt; } } private static string m_strPasswordQuality = @"Password Quality"; /// /// Look up a localized string similar to /// 'Password Quality'. /// public static string PasswordQuality { get { return m_strPasswordQuality; } } private static string m_strPasswordQualityReport = @"Estimated quality of the entry passwords."; /// /// Look up a localized string similar to /// 'Estimated quality of the entry passwords.'. /// public static string PasswordQualityReport { get { return m_strPasswordQualityReport; } } private static string m_strPasswordRepeatFailed = @"Password and repeated password aren't identical!"; /// /// Look up a localized string similar to /// 'Password and repeated password aren't identical!'. /// public static string PasswordRepeatFailed { get { return m_strPasswordRepeatFailed; } } private static string m_strPasswordRepeatHint = @"Repeat the password to prevent typing errors."; /// /// Look up a localized string similar to /// 'Repeat the password to prevent typing errors.'. /// public static string PasswordRepeatHint { get { return m_strPasswordRepeatHint; } } private static string m_strPaste = @"Paste"; /// /// Look up a localized string similar to /// 'Paste'. /// public static string Paste { get { return m_strPaste; } } private static string m_strPerformAutoType = @"Perform Auto-&Type"; /// /// Look up a localized string similar to /// 'Perform Auto-&Type'. /// public static string PerformAutoType { get { return m_strPerformAutoType; } } private static string m_strPerformGlobalAutoType = @"Perform global auto-type"; /// /// Look up a localized string similar to /// 'Perform global auto-type'. /// public static string PerformGlobalAutoType { get { return m_strPerformGlobalAutoType; } } private static string m_strPerformSelectedAutoType = @"Perform auto-type with selected entry"; /// /// Look up a localized string similar to /// 'Perform auto-type with selected entry'. /// public static string PerformSelectedAutoType { get { return m_strPerformSelectedAutoType; } } private static string m_strPickCharacters = @"Pick Characters"; /// /// Look up a localized string similar to /// 'Pick Characters'. /// public static string PickCharacters { get { return m_strPickCharacters; } } private static string m_strPickCharactersDesc = @"Select the requested character positions."; /// /// Look up a localized string similar to /// 'Select the requested character positions.'. /// public static string PickCharactersDesc { get { return m_strPickCharactersDesc; } } private static string m_strPickField = @"Pick Field"; /// /// Look up a localized string similar to /// 'Pick Field'. /// public static string PickField { get { return m_strPickField; } } private static string m_strPickFieldDesc = @"Choose a field whose value will be inserted."; /// /// Look up a localized string similar to /// 'Choose a field whose value will be inserted.'. /// public static string PickFieldDesc { get { return m_strPickFieldDesc; } } private static string m_strPickIcon = @"Pick an icon."; /// /// Look up a localized string similar to /// 'Pick an icon.'. /// public static string PickIcon { get { return m_strPickIcon; } } private static string m_strPlugin = @"Plugin"; /// /// Look up a localized string similar to /// 'Plugin'. /// public static string Plugin { get { return m_strPlugin; } } private static string m_strPlugin1x = @"This plugin appears to be a plugin for KeePass 1.x."; /// /// Look up a localized string similar to /// 'This plugin appears to be a plugin for KeePass 1.x.'. /// public static string Plugin1x { get { return m_strPlugin1x; } } private static string m_strPlugin1xHint = @"KeePass 1.x plugins cannot be used together with KeePass 2.x and vice versa."; /// /// Look up a localized string similar to /// 'KeePass 1.x plugins cannot be used together with KeePass 2.x and vice versa.'. /// public static string Plugin1xHint { get { return m_strPlugin1xHint; } } private static string m_strPluginCacheClearInfo = @"The plugin cache will be cleared and rebuilt if necessary when KeePass is restarted."; /// /// Look up a localized string similar to /// 'The plugin cache will be cleared and rebuilt if necessary when KeePass is restarted.'. /// public static string PluginCacheClearInfo { get { return m_strPluginCacheClearInfo; } } private static string m_strPluginIncompatible = @"The following plugin is incompatible with the current KeePass version:"; /// /// Look up a localized string similar to /// 'The following plugin is incompatible with the current KeePass version:'. /// public static string PluginIncompatible { get { return m_strPluginIncompatible; } } private static string m_strPluginLoadFailed = @"The plugin cannot be loaded."; /// /// Look up a localized string similar to /// 'The plugin cannot be loaded.'. /// public static string PluginLoadFailed { get { return m_strPluginLoadFailed; } } private static string m_strPluginOperatingSystemUnsupported = @"The current operating system is unsupported by the plugin."; /// /// Look up a localized string similar to /// 'The current operating system is unsupported by the plugin.'. /// public static string PluginOperatingSystemUnsupported { get { return m_strPluginOperatingSystemUnsupported; } } private static string m_strPluginProvided = @"Provided by Plugins"; /// /// Look up a localized string similar to /// 'Provided by Plugins'. /// public static string PluginProvided { get { return m_strPluginProvided; } } private static string m_strPlugins = @"Plugins"; /// /// Look up a localized string similar to /// 'Plugins'. /// public static string Plugins { get { return m_strPlugins; } } private static string m_strPluginsCompilingAndLoading = @"Compiling and loading plugins..."; /// /// Look up a localized string similar to /// 'Compiling and loading plugins...'. /// public static string PluginsCompilingAndLoading { get { return m_strPluginsCompilingAndLoading; } } private static string m_strPluginsDesc = @"Here you can configure all loaded KeePass plugins."; /// /// Look up a localized string similar to /// 'Here you can configure all loaded KeePass plugins.'. /// public static string PluginsDesc { get { return m_strPluginsDesc; } } private static string m_strPluginUpdateHint = @"Have a look at the plugin's website for an appropriate version."; /// /// Look up a localized string similar to /// 'Have a look at the plugin's website for an appropriate version.'. /// public static string PluginUpdateHint { get { return m_strPluginUpdateHint; } } private static string m_strPolicyAutoTypeDesc = @"Allow auto-typing entries to other windows."; /// /// Look up a localized string similar to /// 'Allow auto-typing entries to other windows.'. /// public static string PolicyAutoTypeDesc { get { return m_strPolicyAutoTypeDesc; } } private static string m_strPolicyAutoTypeWithoutContextDesc = @"Allow auto-typing using the 'Perform Auto-Type' command (Ctrl+V)."; /// /// Look up a localized string similar to /// 'Allow auto-typing using the 'Perform Auto-Type' command (Ctrl+V).'. /// public static string PolicyAutoTypeWithoutContextDesc { get { return m_strPolicyAutoTypeWithoutContextDesc; } } private static string m_strPolicyChangeMasterKey = @"Allow changing the master key of a database."; /// /// Look up a localized string similar to /// 'Allow changing the master key of a database.'. /// public static string PolicyChangeMasterKey { get { return m_strPolicyChangeMasterKey; } } private static string m_strPolicyChangeMasterKeyNoKeyDesc = @"Do not require entering current master key before changing it."; /// /// Look up a localized string similar to /// 'Do not require entering current master key before changing it.'. /// public static string PolicyChangeMasterKeyNoKeyDesc { get { return m_strPolicyChangeMasterKeyNoKeyDesc; } } private static string m_strPolicyClipboardDesc = @"Allow copying entry information to clipboard (main window only)."; /// /// Look up a localized string similar to /// 'Allow copying entry information to clipboard (main window only).'. /// public static string PolicyClipboardDesc { get { return m_strPolicyClipboardDesc; } } private static string m_strPolicyCopyWholeEntriesDesc = @"Allow copying whole entries to clipboard."; /// /// Look up a localized string similar to /// 'Allow copying whole entries to clipboard.'. /// public static string PolicyCopyWholeEntriesDesc { get { return m_strPolicyCopyWholeEntriesDesc; } } private static string m_strPolicyDisallowed = @"This operation is disallowed by the application policy. Ask your administrator to allow this operation."; /// /// Look up a localized string similar to /// 'This operation is disallowed by the application policy. Ask your administrator to allow this operation.'. /// public static string PolicyDisallowed { get { return m_strPolicyDisallowed; } } private static string m_strPolicyDragDropDesc = @"Allow sending information to other windows using drag&drop."; /// /// Look up a localized string similar to /// 'Allow sending information to other windows using drag&drop.'. /// public static string PolicyDragDropDesc { get { return m_strPolicyDragDropDesc; } } private static string m_strPolicyExportDesc2 = @"Allow exporting entries."; /// /// Look up a localized string similar to /// 'Allow exporting entries.'. /// public static string PolicyExportDesc2 { get { return m_strPolicyExportDesc2; } } private static string m_strPolicyExportNoKeyDesc = @"Do not require entering current master key before exporting."; /// /// Look up a localized string similar to /// 'Do not require entering current master key before exporting.'. /// public static string PolicyExportNoKeyDesc { get { return m_strPolicyExportNoKeyDesc; } } private static string m_strPolicyImportDesc = @"Allow importing entries from external files."; /// /// Look up a localized string similar to /// 'Allow importing entries from external files.'. /// public static string PolicyImportDesc { get { return m_strPolicyImportDesc; } } private static string m_strPolicyNewDatabaseDesc = @"Allow creating new database files."; /// /// Look up a localized string similar to /// 'Allow creating new database files.'. /// public static string PolicyNewDatabaseDesc { get { return m_strPolicyNewDatabaseDesc; } } private static string m_strPolicyPluginsDesc = @"Allow loading plugins to extend KeePass functionality."; /// /// Look up a localized string similar to /// 'Allow loading plugins to extend KeePass functionality.'. /// public static string PolicyPluginsDesc { get { return m_strPolicyPluginsDesc; } } private static string m_strPolicyPrintDesc = @"Allow printing entry lists."; /// /// Look up a localized string similar to /// 'Allow printing entry lists.'. /// public static string PolicyPrintDesc { get { return m_strPolicyPrintDesc; } } private static string m_strPolicyPrintNoKeyDesc = @"Do not require entering current master key before printing."; /// /// Look up a localized string similar to /// 'Do not require entering current master key before printing.'. /// public static string PolicyPrintNoKeyDesc { get { return m_strPolicyPrintNoKeyDesc; } } private static string m_strPolicyRequiredFlag = @"The following policy flag is required"; /// /// Look up a localized string similar to /// 'The following policy flag is required'. /// public static string PolicyRequiredFlag { get { return m_strPolicyRequiredFlag; } } private static string m_strPolicySaveDatabaseDesc = @"Allow saving databases to disk/URL."; /// /// Look up a localized string similar to /// 'Allow saving databases to disk/URL.'. /// public static string PolicySaveDatabaseDesc { get { return m_strPolicySaveDatabaseDesc; } } private static string m_strPolicyTriggersEditDesc = @"Allow editing triggers."; /// /// Look up a localized string similar to /// 'Allow editing triggers.'. /// public static string PolicyTriggersEditDesc { get { return m_strPolicyTriggersEditDesc; } } private static string m_strPreReleaseVersion = @"Pre-release version"; /// /// Look up a localized string similar to /// 'Pre-release version'. /// public static string PreReleaseVersion { get { return m_strPreReleaseVersion; } } private static string m_strPrint = @"Print"; /// /// Look up a localized string similar to /// 'Print'. /// public static string Print { get { return m_strPrint; } } private static string m_strPrintDesc = @"Print password entries."; /// /// Look up a localized string similar to /// 'Print password entries.'. /// public static string PrintDesc { get { return m_strPrintDesc; } } private static string m_strPrivate = @"Private"; /// /// Look up a localized string similar to /// 'Private'. /// public static string Private { get { return m_strPrivate; } } private static string m_strProfessional = @"Professional"; /// /// Look up a localized string similar to /// 'Professional'. /// public static string Professional { get { return m_strProfessional; } } private static string m_strQuality = @"Quality"; /// /// Look up a localized string similar to /// 'Quality'. /// public static string Quality { get { return m_strQuality; } } private static string m_strQuickSearchExclExpired = @"Exclude expired entries in quick searches"; /// /// Look up a localized string similar to /// 'Exclude expired entries in quick searches'. /// public static string QuickSearchExclExpired { get { return m_strQuickSearchExclExpired; } } private static string m_strQuickSearchInPwFields = @"Search for passwords in quick searches"; /// /// Look up a localized string similar to /// 'Search for passwords in quick searches'. /// public static string QuickSearchInPwFields { get { return m_strQuickSearchInPwFields; } } private static string m_strQuickSearchDerefData = @"Resolve field references in quick searches"; /// /// Look up a localized string similar to /// 'Resolve field references in quick searches'. /// public static string QuickSearchDerefData { get { return m_strQuickSearchDerefData; } } private static string m_strQuickSearchTb = @"Quick Search (Toolbar)"; /// /// Look up a localized string similar to /// 'Quick Search (Toolbar)'. /// public static string QuickSearchTb { get { return m_strQuickSearchTb; } } private static string m_strRandomMacAddress = @"Random MAC Address"; /// /// Look up a localized string similar to /// 'Random MAC Address'. /// public static string RandomMacAddress { get { return m_strRandomMacAddress; } } private static string m_strReady = @"Ready."; /// /// Look up a localized string similar to /// 'Ready.'. /// public static string Ready { get { return m_strReady; } } private static string m_strRecommended = @"recommended"; /// /// Look up a localized string similar to /// 'recommended'. /// public static string Recommended { get { return m_strRecommended; } } private static string m_strRecommendedCmd = @"&Recommended"; /// /// Look up a localized string similar to /// '&Recommended'. /// public static string RecommendedCmd { get { return m_strRecommendedCmd; } } private static string m_strRecycleBin = @"Recycle Bin"; /// /// Look up a localized string similar to /// 'Recycle Bin'. /// public static string RecycleBin { get { return m_strRecycleBin; } } private static string m_strRecycleBinCollapse = @"Collapse newly-created recycle bin tree node"; /// /// Look up a localized string similar to /// 'Collapse newly-created recycle bin tree node'. /// public static string RecycleBinCollapse { get { return m_strRecycleBinCollapse; } } private static string m_strRecycleEntryConfirm = @"Are you sure you want to move the selected entries to the recycle bin?"; /// /// Look up a localized string similar to /// 'Are you sure you want to move the selected entries to the recycle bin?'. /// public static string RecycleEntryConfirm { get { return m_strRecycleEntryConfirm; } } private static string m_strRecycleEntryConfirmSingle = @"Are you sure you want to move the selected entry to the recycle bin?"; /// /// Look up a localized string similar to /// 'Are you sure you want to move the selected entry to the recycle bin?'. /// public static string RecycleEntryConfirmSingle { get { return m_strRecycleEntryConfirmSingle; } } private static string m_strRecycleGroupConfirm = @"Are you sure you want to move the selected group to the recycle bin?"; /// /// Look up a localized string similar to /// 'Are you sure you want to move the selected group to the recycle bin?'. /// public static string RecycleGroupConfirm { get { return m_strRecycleGroupConfirm; } } private static string m_strRecycleShowConfirm = @"Show confirmation dialog when moving entries/groups to the recycle bin"; /// /// Look up a localized string similar to /// 'Show confirmation dialog when moving entries/groups to the recycle bin'. /// public static string RecycleShowConfirm { get { return m_strRecycleShowConfirm; } } private static string m_strRedo = @"Redo"; /// /// Look up a localized string similar to /// 'Redo'. /// public static string Redo { get { return m_strRedo; } } private static string m_strRememberHidingSettings = @"Remember password hiding setting in 'Edit Entry' window"; /// /// Look up a localized string similar to /// 'Remember password hiding setting in 'Edit Entry' window'. /// public static string RememberHidingSettings { get { return m_strRememberHidingSettings; } } private static string m_strRememberKeySources = @"Remember key sources (key file paths, provider names, ...)"; /// /// Look up a localized string similar to /// 'Remember key sources (key file paths, provider names, ...)'. /// public static string RememberKeySources { get { return m_strRememberKeySources; } } private static string m_strRememberWorkingDirectories = @"Remember working directories"; /// /// Look up a localized string similar to /// 'Remember working directories'. /// public static string RememberWorkingDirectories { get { return m_strRememberWorkingDirectories; } } private static string m_strRemoteHostReachable = @"Remote host is reachable (ping)"; /// /// Look up a localized string similar to /// 'Remote host is reachable (ping)'. /// public static string RemoteHostReachable { get { return m_strRemoteHostReachable; } } private static string m_strRepairCmd = @"&Repair"; /// /// Look up a localized string similar to /// '&Repair'. /// public static string RepairCmd { get { return m_strRepairCmd; } } private static string m_strRepairMode = @"Repair Mode"; /// /// Look up a localized string similar to /// 'Repair Mode'. /// public static string RepairMode { get { return m_strRepairMode; } } private static string m_strRepairModeInt = @"In repair mode, the integrity of the data is not checked (in order to rescue as much data as possible). When no integrity checks are performed, corrupted/malicious data might be incorporated into the database."; /// /// Look up a localized string similar to /// 'In repair mode, the integrity of the data is not checked (in order to rescue as much data as possible). When no integrity checks are performed, corrupted/malicious data might be incorporated into the database.'. /// public static string RepairModeInt { get { return m_strRepairModeInt; } } private static string m_strRepairModeQ = @"Are you sure you want to attempt to repair the selected file?"; /// /// Look up a localized string similar to /// 'Are you sure you want to attempt to repair the selected file?'. /// public static string RepairModeQ { get { return m_strRepairModeQ; } } private static string m_strRepairModeUse = @"Thus the repair functionality should only be used when there really is no other solution. If you use it, afterwards you should thoroughly check your whole database for corrupted/malicious data."; /// /// Look up a localized string similar to /// 'Thus the repair functionality should only be used when there really is no other solution. If you use it, afterwards you should thoroughly check your whole database for corrupted/malicious data.'. /// public static string RepairModeUse { get { return m_strRepairModeUse; } } private static string m_strRepeatOnlyWhenHidden = @"Require password repetition only when hiding using asterisks is enabled"; /// /// Look up a localized string similar to /// 'Require password repetition only when hiding using asterisks is enabled'. /// public static string RepeatOnlyWhenHidden { get { return m_strRepeatOnlyWhenHidden; } } private static string m_strReplace = @"Replace"; /// /// Look up a localized string similar to /// 'Replace'. /// public static string Replace { get { return m_strReplace; } } private static string m_strReplaceNo = @"Do not replace"; /// /// Look up a localized string similar to /// 'Do not replace'. /// public static string ReplaceNo { get { return m_strReplaceNo; } } private static string m_strRestartKeePassQuestion = @"Do you wish to restart KeePass now?"; /// /// Look up a localized string similar to /// 'Do you wish to restart KeePass now?'. /// public static string RestartKeePassQuestion { get { return m_strRestartKeePassQuestion; } } private static string m_strRetry = @"Retry"; /// /// Look up a localized string similar to /// 'Retry'. /// public static string Retry { get { return m_strRetry; } } private static string m_strRetryCmd = @"&Retry"; /// /// Look up a localized string similar to /// '&Retry'. /// public static string RetryCmd { get { return m_strRetryCmd; } } private static string m_strRootDirectory = @"Root Directory"; /// /// Look up a localized string similar to /// 'Root Directory'. /// public static string RootDirectory { get { return m_strRootDirectory; } } private static string m_strSameKeybLayout = @"Ensure same keyboard layouts during auto-type"; /// /// Look up a localized string similar to /// 'Ensure same keyboard layouts during auto-type'. /// public static string SameKeybLayout { get { return m_strSameKeybLayout; } } private static string m_strSampleEntry = @"Sample Entry"; /// /// Look up a localized string similar to /// 'Sample Entry'. /// public static string SampleEntry { get { return m_strSampleEntry; } } private static string m_strSave = @"Save"; /// /// Look up a localized string similar to /// 'Save'. /// public static string Save { get { return m_strSave; } } private static string m_strSaveBeforeCloseEntry = @"Do you want to save the changes you have made to this entry?"; /// /// Look up a localized string similar to /// 'Do you want to save the changes you have made to this entry?'. /// public static string SaveBeforeCloseEntry { get { return m_strSaveBeforeCloseEntry; } } private static string m_strSaveBeforeCloseQuestion = @"Do you want to save the changes before closing?"; /// /// Look up a localized string similar to /// 'Do you want to save the changes before closing?'. /// public static string SaveBeforeCloseQuestion { get { return m_strSaveBeforeCloseQuestion; } } private static string m_strSaveBeforeCloseTitle = @"KeePass - Save Before Close/Lock?"; /// /// Look up a localized string similar to /// 'KeePass - Save Before Close/Lock?'. /// public static string SaveBeforeCloseTitle { get { return m_strSaveBeforeCloseTitle; } } private static string m_strSaveCmd = @"&Save"; /// /// Look up a localized string similar to /// '&Save'. /// public static string SaveCmd { get { return m_strSaveCmd; } } private static string m_strSaveDatabase = @"Save Database"; /// /// Look up a localized string similar to /// 'Save Database'. /// public static string SaveDatabase { get { return m_strSaveDatabase; } } private static string m_strSaveDatabaseStc = @"Save active database"; /// /// Look up a localized string similar to /// 'Save active database'. /// public static string SaveDatabaseStc { get { return m_strSaveDatabaseStc; } } private static string m_strSavedDatabaseFile = @"Saved database file"; /// /// Look up a localized string similar to /// 'Saved database file'. /// public static string SavedDatabaseFile { get { return m_strSavedDatabaseFile; } } private static string m_strSaveForceSync = @"Do not ask whether to synchronize or overwrite; force synchronization"; /// /// Look up a localized string similar to /// 'Do not ask whether to synchronize or overwrite; force synchronization'. /// public static string SaveForceSync { get { return m_strSaveForceSync; } } private static string m_strSavingDatabase = @"Saving database..."; /// /// Look up a localized string similar to /// 'Saving database...'. /// public static string SavingDatabase { get { return m_strSavingDatabase; } } private static string m_strSavingDatabaseFile = @"Saving database file"; /// /// Look up a localized string similar to /// 'Saving database file'. /// public static string SavingDatabaseFile { get { return m_strSavingDatabaseFile; } } private static string m_strSavingPost = @"after saving"; /// /// Look up a localized string similar to /// 'after saving'. /// public static string SavingPost { get { return m_strSavingPost; } } private static string m_strSavingPre = @"before saving"; /// /// Look up a localized string similar to /// 'before saving'. /// public static string SavingPre { get { return m_strSavingPre; } } private static string m_strScheme = @"Scheme"; /// /// Look up a localized string similar to /// 'Scheme'. /// public static string Scheme { get { return m_strScheme; } } private static string m_strSearch = @"Search..."; /// /// Look up a localized string similar to /// 'Search...'. /// public static string Search { get { return m_strSearch; } } private static string m_strSearchDesc = @"Search the password database for entries."; /// /// Look up a localized string similar to /// 'Search the password database for entries.'. /// public static string SearchDesc { get { return m_strSearchDesc; } } private static string m_strSearchEntriesFound = @"{PARAM} entries found"; /// /// Look up a localized string similar to /// '{PARAM} entries found'. /// public static string SearchEntriesFound { get { return m_strSearchEntriesFound; } } private static string m_strSearchEntriesFound1 = @"1 entry found"; /// /// Look up a localized string similar to /// '1 entry found'. /// public static string SearchEntriesFound1 { get { return m_strSearchEntriesFound1; } } private static string m_strSearchGroupName = @"Search Results"; /// /// Look up a localized string similar to /// 'Search Results'. /// public static string SearchGroupName { get { return m_strSearchGroupName; } } private static string m_strSearchingOp = @"Searching"; /// /// Look up a localized string similar to /// 'Searching'. /// public static string SearchingOp { get { return m_strSearchingOp; } } private static string m_strSearchKeyFiles = @"Automatically search key files"; /// /// Look up a localized string similar to /// 'Automatically search key files'. /// public static string SearchKeyFiles { get { return m_strSearchKeyFiles; } } private static string m_strSearchKeyFilesAlsoOnRemovable = @"Automatically search key files also on removable media"; /// /// Look up a localized string similar to /// 'Automatically search key files also on removable media'. /// public static string SearchKeyFilesAlsoOnRemovable { get { return m_strSearchKeyFilesAlsoOnRemovable; } } private static string m_strSearchQuickPrompt = @"Type to search the database"; /// /// Look up a localized string similar to /// 'Type to search the database'. /// public static string SearchQuickPrompt { get { return m_strSearchQuickPrompt; } } private static string m_strSearchResultsInSeparator = @"in"; /// /// Look up a localized string similar to /// 'in'. /// public static string SearchResultsInSeparator { get { return m_strSearchResultsInSeparator; } } private static string m_strSearchTitle = @"Find"; /// /// Look up a localized string similar to /// 'Find'. /// public static string SearchTitle { get { return m_strSearchTitle; } } private static string m_strSecDeskFileDialogHint = @"Note: KeePass shows this simple file browser dialog, because standard Windows file dialogs cannot be shown on the secure desktop for security reasons."; /// /// Look up a localized string similar to /// 'Note: KeePass shows this simple file browser dialog, because standard Windows file dialogs cannot be shown on the secure desktop for security reasons.'. /// public static string SecDeskFileDialogHint { get { return m_strSecDeskFileDialogHint; } } private static string m_strSecDeskOtherSwitched = @"An application has switched from the secure desktop to a different desktop."; /// /// Look up a localized string similar to /// 'An application has switched from the secure desktop to a different desktop.'. /// public static string SecDeskOtherSwitched { get { return m_strSecDeskOtherSwitched; } } private static string m_strSecDeskPlaySound = @"Play UAC sound when switching to secure desktop"; /// /// Look up a localized string similar to /// 'Play UAC sound when switching to secure desktop'. /// public static string SecDeskPlaySound { get { return m_strSecDeskPlaySound; } } private static string m_strSecDeskSwitchBack = @"Click [OK] to switch back to the secure desktop."; /// /// Look up a localized string similar to /// 'Click [OK] to switch back to the secure desktop.'. /// public static string SecDeskSwitchBack { get { return m_strSecDeskSwitchBack; } } private static string m_strSelectAll = @"Select All"; /// /// Look up a localized string similar to /// 'Select All'. /// public static string SelectAll { get { return m_strSelectAll; } } private static string m_strSelectColor = @"Select Color"; /// /// Look up a localized string similar to /// 'Select Color'. /// public static string SelectColor { get { return m_strSelectColor; } } private static string m_strSelectDifferentGroup = @"Please select a different group."; /// /// Look up a localized string similar to /// 'Please select a different group.'. /// public static string SelectDifferentGroup { get { return m_strSelectDifferentGroup; } } private static string m_strSelectedColumn = @"Selected column"; /// /// Look up a localized string similar to /// 'Selected column'. /// public static string SelectedColumn { get { return m_strSelectedColumn; } } private static string m_strSelectedLower = @"selected"; /// /// Look up a localized string similar to /// 'selected'. /// public static string SelectedLower { get { return m_strSelectedLower; } } private static string m_strSelectFile = @"Select a file."; /// /// Look up a localized string similar to /// 'Select a file.'. /// public static string SelectFile { get { return m_strSelectFile; } } private static string m_strSelectIcon = @"Select an icon"; /// /// Look up a localized string similar to /// 'Select an icon'. /// public static string SelectIcon { get { return m_strSelectIcon; } } private static string m_strSelectLanguage = @"Select Language"; /// /// Look up a localized string similar to /// 'Select Language'. /// public static string SelectLanguage { get { return m_strSelectLanguage; } } private static string m_strSelectLanguageDesc = @"Here you can change the user interface language."; /// /// Look up a localized string similar to /// 'Here you can change the user interface language.'. /// public static string SelectLanguageDesc { get { return m_strSelectLanguageDesc; } } private static string m_strSelfTestFailed = @"One or more of the KeePass self-tests failed."; /// /// Look up a localized string similar to /// 'One or more of the KeePass self-tests failed.'. /// public static string SelfTestFailed { get { return m_strSelfTestFailed; } } private static string m_strSendingNoun = @"Sending"; /// /// Look up a localized string similar to /// 'Sending'. /// public static string SendingNoun { get { return m_strSendingNoun; } } private static string m_strSeparator = @"Separator"; /// /// Look up a localized string similar to /// 'Separator'. /// public static string Separator { get { return m_strSeparator; } } private static string m_strSequence = @"Sequence"; /// /// Look up a localized string similar to /// 'Sequence'. /// public static string Sequence { get { return m_strSequence; } } private static string m_strShowAdvAutoTypeCommands = @"Show additional auto-type menu commands"; /// /// Look up a localized string similar to /// 'Show additional auto-type menu commands'. /// public static string ShowAdvAutoTypeCommands { get { return m_strShowAdvAutoTypeCommands; } } private static string m_strShowDerefData = @"Show dereferenced data"; /// /// Look up a localized string similar to /// 'Show dereferenced data'. /// public static string ShowDerefData { get { return m_strShowDerefData; } } private static string m_strShowDerefDataAndRefs = @"When showing dereferenced data, additionally show references"; /// /// Look up a localized string similar to /// 'When showing dereferenced data, additionally show references'. /// public static string ShowDerefDataAndRefs { get { return m_strShowDerefDataAndRefs; } } private static string m_strShowDerefDataAsync = @"Show dereferenced data asynchronously"; /// /// Look up a localized string similar to /// 'Show dereferenced data asynchronously'. /// public static string ShowDerefDataAsync { get { return m_strShowDerefDataAsync; } } private static string m_strShowEntries = @"Show Entries"; /// /// Look up a localized string similar to /// 'Show Entries'. /// public static string ShowEntries { get { return m_strShowEntries; } } private static string m_strShowEntriesByTag = @"Show entries by tag"; /// /// Look up a localized string similar to /// 'Show entries by tag'. /// public static string ShowEntriesByTag { get { return m_strShowEntriesByTag; } } private static string m_strShowFullPathInTitleBar = @"Show full path in title bar (instead of file name only)"; /// /// Look up a localized string similar to /// 'Show full path in title bar (instead of file name only)'. /// public static string ShowFullPathInTitleBar { get { return m_strShowFullPathInTitleBar; } } private static string m_strShowIn = @"Show in"; /// /// Look up a localized string similar to /// 'Show in'. /// public static string ShowIn { get { return m_strShowIn; } } private static string m_strShowMessageBox = @"Show message box"; /// /// Look up a localized string similar to /// 'Show message box'. /// public static string ShowMessageBox { get { return m_strShowMessageBox; } } private static string m_strShowTrayOnlyIfTrayed = @"Show tray icon only if main window has been sent to tray"; /// /// Look up a localized string similar to /// 'Show tray icon only if main window has been sent to tray'. /// public static string ShowTrayOnlyIfTrayed { get { return m_strShowTrayOnlyIfTrayed; } } private static string m_strSimilarPasswords = @"Similar Passwords"; /// /// Look up a localized string similar to /// 'Similar Passwords'. /// public static string SimilarPasswords { get { return m_strSimilarPasswords; } } private static string m_strSimilarPasswordsGroup = @"Entries using similar passwords (similarity: {PARAM}):"; /// /// Look up a localized string similar to /// 'Entries using similar passwords (similarity: {PARAM}):'. /// public static string SimilarPasswordsGroup { get { return m_strSimilarPasswordsGroup; } } private static string m_strSimilarPasswordsList = @"List of entries that are using similar passwords."; /// /// Look up a localized string similar to /// 'List of entries that are using similar passwords.'. /// public static string SimilarPasswordsList { get { return m_strSimilarPasswordsList; } } private static string m_strSimilarPasswordsNoDup = @"The list shows entries that are using similar, but not identical passwords. For finding entries that are using the same passwords, use the 'Find Duplicate Passwords' command (in the main menu)."; /// /// Look up a localized string similar to /// 'The list shows entries that are using similar, but not identical passwords. For finding entries that are using the same passwords, use the 'Find Duplicate Passwords' command (in the main menu).'. /// public static string SimilarPasswordsNoDup { get { return m_strSimilarPasswordsNoDup; } } private static string m_strSize = @"Size"; /// /// Look up a localized string similar to /// 'Size'. /// public static string Size { get { return m_strSize; } } private static string m_strSkip = @"Skip"; /// /// Look up a localized string similar to /// 'Skip'. /// public static string Skip { get { return m_strSkip; } } private static string m_strSlow = @"slow"; /// /// Look up a localized string similar to /// 'slow'. /// public static string Slow { get { return m_strSlow; } } private static string m_strSoonToExpireEntries = @"Expired Entries and Entries That Will Expire Soon"; /// /// Look up a localized string similar to /// 'Expired Entries and Entries That Will Expire Soon'. /// public static string SoonToExpireEntries { get { return m_strSoonToExpireEntries; } } private static string m_strSpecialKeys = @"Special Keys"; /// /// Look up a localized string similar to /// 'Special Keys'. /// public static string SpecialKeys { get { return m_strSpecialKeys; } } private static string m_strSslCertsAcceptInvalid = @"Accept invalid SSL certificates (self-signed, expired, ...)"; /// /// Look up a localized string similar to /// 'Accept invalid SSL certificates (self-signed, expired, ...)'. /// public static string SslCertsAcceptInvalid { get { return m_strSslCertsAcceptInvalid; } } private static string m_strStandardExpireSelect = @"Select one of the standard expire times"; /// /// Look up a localized string similar to /// 'Select one of the standard expire times'. /// public static string StandardExpireSelect { get { return m_strStandardExpireSelect; } } private static string m_strStandardFields = @"Standard Fields"; /// /// Look up a localized string similar to /// 'Standard Fields'. /// public static string StandardFields { get { return m_strStandardFields; } } private static string m_strStartAndExit = @"Start and Exit"; /// /// Look up a localized string similar to /// 'Start and Exit'. /// public static string StartAndExit { get { return m_strStartAndExit; } } private static string m_strStartMinimizedAndLocked = @"Start minimized and locked"; /// /// Look up a localized string similar to /// 'Start minimized and locked'. /// public static string StartMinimizedAndLocked { get { return m_strStartMinimizedAndLocked; } } private static string m_strStartsWith = @"Starts with"; /// /// Look up a localized string similar to /// 'Starts with'. /// public static string StartsWith { get { return m_strStartsWith; } } private static string m_strStatus = @"Status"; /// /// Look up a localized string similar to /// 'Status'. /// public static string Status { get { return m_strStatus; } } private static string m_strStrikeout = @"Strikeout"; /// /// Look up a localized string similar to /// 'Strikeout'. /// public static string Strikeout { get { return m_strStrikeout; } } private static string m_strString = @"String"; /// /// Look up a localized string similar to /// 'String'. /// public static string String { get { return m_strString; } } private static string m_strSuccess = @"Success."; /// /// Look up a localized string similar to /// 'Success.'. /// public static string Success { get { return m_strSuccess; } } private static string m_strSyncFailed = @"Synchronization failed."; /// /// Look up a localized string similar to /// 'Synchronization failed.'. /// public static string SyncFailed { get { return m_strSyncFailed; } } private static string m_strSynchronize = @"Synchronize"; /// /// Look up a localized string similar to /// 'Synchronize'. /// public static string Synchronize { get { return m_strSynchronize; } } private static string m_strSynchronizeStc = @"Synchronize active database with a file/URL"; /// /// Look up a localized string similar to /// 'Synchronize active database with a file/URL'. /// public static string SynchronizeStc { get { return m_strSynchronizeStc; } } private static string m_strSynchronizing = @"Synchronizing..."; /// /// Look up a localized string similar to /// 'Synchronizing...'. /// public static string Synchronizing { get { return m_strSynchronizing; } } private static string m_strSynchronizingHint = @"Make sure that the two databases use the same composite master key. This is required for synchronization."; /// /// Look up a localized string similar to /// 'Make sure that the two databases use the same composite master key. This is required for synchronization.'. /// public static string SynchronizingHint { get { return m_strSynchronizingHint; } } private static string m_strSyncSuccess = @"Synchronization completed successfully."; /// /// Look up a localized string similar to /// 'Synchronization completed successfully.'. /// public static string SyncSuccess { get { return m_strSyncSuccess; } } private static string m_strSystem = @"System"; /// /// Look up a localized string similar to /// 'System'. /// public static string System { get { return m_strSystem; } } private static string m_strSystemCodePage = @"System Code Page"; /// /// Look up a localized string similar to /// 'System Code Page'. /// public static string SystemCodePage { get { return m_strSystemCodePage; } } private static string m_strTag = @"Tag"; /// /// Look up a localized string similar to /// 'Tag'. /// public static string Tag { get { return m_strTag; } } private static string m_strTagAddNew = @"Add a new tag."; /// /// Look up a localized string similar to /// 'Add a new tag.'. /// public static string TagAddNew { get { return m_strTagAddNew; } } private static string m_strTagNew = @"New Tag"; /// /// Look up a localized string similar to /// 'New Tag'. /// public static string TagNew { get { return m_strTagNew; } } private static string m_strTags = @"Tags"; /// /// Look up a localized string similar to /// 'Tags'. /// public static string Tags { get { return m_strTags; } } private static string m_strTagsNotFound = @"No tags found"; /// /// Look up a localized string similar to /// 'No tags found'. /// public static string TagsNotFound { get { return m_strTagsNotFound; } } private static string m_strTanExpiresOnUse = @"Mark TAN entries as expired when using them"; /// /// Look up a localized string similar to /// 'Mark TAN entries as expired when using them'. /// public static string TanExpiresOnUse { get { return m_strTanExpiresOnUse; } } private static string m_strTanWizard = @"TAN Wizard"; /// /// Look up a localized string similar to /// 'TAN Wizard'. /// public static string TanWizard { get { return m_strTanWizard; } } private static string m_strTanWizardDesc = @"With this TAN wizard you can easily add TAN entries."; /// /// Look up a localized string similar to /// 'With this TAN wizard you can easily add TAN entries.'. /// public static string TanWizardDesc { get { return m_strTanWizardDesc; } } private static string m_strTargetWindow = @"Target Window"; /// /// Look up a localized string similar to /// 'Target Window'. /// public static string TargetWindow { get { return m_strTargetWindow; } } private static string m_strTemplatesNotFound = @"No templates found"; /// /// Look up a localized string similar to /// 'No templates found'. /// public static string TemplatesNotFound { get { return m_strTemplatesNotFound; } } private static string m_strTestSuccess = @"Test succeeded!"; /// /// Look up a localized string similar to /// 'Test succeeded!'. /// public static string TestSuccess { get { return m_strTestSuccess; } } private static string m_strText = @"Text"; /// /// Look up a localized string similar to /// 'Text'. /// public static string Text { get { return m_strText; } } private static string m_strTextColor = @"Text Color"; /// /// Look up a localized string similar to /// 'Text Color'. /// public static string TextColor { get { return m_strTextColor; } } private static string m_strTextViewer = @"Text Viewer"; /// /// Look up a localized string similar to /// 'Text Viewer'. /// public static string TextViewer { get { return m_strTextViewer; } } private static string m_strTimeSpan = @"Time span"; /// /// Look up a localized string similar to /// 'Time span'. /// public static string TimeSpan { get { return m_strTimeSpan; } } private static string m_strTitle = @"Title"; /// /// Look up a localized string similar to /// 'Title'. /// public static string Title { get { return m_strTitle; } } private static string m_strToggle = @"Toggle"; /// /// Look up a localized string similar to /// 'Toggle'. /// public static string Toggle { get { return m_strToggle; } } private static string m_strTogglePasswordAsterisks = @"Show/hide password using asterisks"; /// /// Look up a localized string similar to /// 'Show/hide password using asterisks'. /// public static string TogglePasswordAsterisks { get { return m_strTogglePasswordAsterisks; } } private static string m_strToolBarNew = @"New..."; /// /// Look up a localized string similar to /// 'New...'. /// public static string ToolBarNew { get { return m_strToolBarNew; } } private static string m_strToolBarOpen = @"Open..."; /// /// Look up a localized string similar to /// 'Open...'. /// public static string ToolBarOpen { get { return m_strToolBarOpen; } } private static string m_strToolBarSaveAll = @"Save All"; /// /// Look up a localized string similar to /// 'Save All'. /// public static string ToolBarSaveAll { get { return m_strToolBarSaveAll; } } private static string m_strTooManyFilesError = @"Too many files have been selected. Select smaller groups and repeat the current procedure a few times."; /// /// Look up a localized string similar to /// 'Too many files have been selected. Select smaller groups and repeat the current procedure a few times.'. /// public static string TooManyFilesError { get { return m_strTooManyFilesError; } } private static string m_strTransformTime = @"The key transformation took {PARAM} seconds."; /// /// Look up a localized string similar to /// 'The key transformation took {PARAM} seconds.'. /// public static string TransformTime { get { return m_strTransformTime; } } private static string m_strTrayIcon = @"Tray Icon"; /// /// Look up a localized string similar to /// 'Tray Icon'. /// public static string TrayIcon { get { return m_strTrayIcon; } } private static string m_strTrayIconGray = @"Use gray tray icon"; /// /// Look up a localized string similar to /// 'Use gray tray icon'. /// public static string TrayIconGray { get { return m_strTrayIconGray; } } private static string m_strTrayIconSingleClick = @"Single click instead of double click for default tray icon action"; /// /// Look up a localized string similar to /// 'Single click instead of double click for default tray icon action'. /// public static string TrayIconSingleClick { get { return m_strTrayIconSingleClick; } } private static string m_strTrigger = @"Trigger"; /// /// Look up a localized string similar to /// 'Trigger'. /// public static string Trigger { get { return m_strTrigger; } } private static string m_strTriggerActionTypeUnknown = @"The trigger action type is unknown."; /// /// Look up a localized string similar to /// 'The trigger action type is unknown.'. /// public static string TriggerActionTypeUnknown { get { return m_strTriggerActionTypeUnknown; } } private static string m_strTriggerAdd = @"Add Trigger"; /// /// Look up a localized string similar to /// 'Add Trigger'. /// public static string TriggerAdd { get { return m_strTriggerAdd; } } private static string m_strTriggerAddDesc = @"Create a new workflow automation."; /// /// Look up a localized string similar to /// 'Create a new workflow automation.'. /// public static string TriggerAddDesc { get { return m_strTriggerAddDesc; } } private static string m_strTriggerConditionTypeUnknown = @"The trigger condition type is unknown."; /// /// Look up a localized string similar to /// 'The trigger condition type is unknown.'. /// public static string TriggerConditionTypeUnknown { get { return m_strTriggerConditionTypeUnknown; } } private static string m_strTriggerEdit = @"Edit Trigger"; /// /// Look up a localized string similar to /// 'Edit Trigger'. /// public static string TriggerEdit { get { return m_strTriggerEdit; } } private static string m_strTriggerEditDesc = @"Modify an existing workflow automation."; /// /// Look up a localized string similar to /// 'Modify an existing workflow automation.'. /// public static string TriggerEditDesc { get { return m_strTriggerEditDesc; } } private static string m_strTriggerEventTypeUnknown = @"The trigger event type is unknown."; /// /// Look up a localized string similar to /// 'The trigger event type is unknown.'. /// public static string TriggerEventTypeUnknown { get { return m_strTriggerEventTypeUnknown; } } private static string m_strTriggerExecutionFailed = @"Trigger execution failed"; /// /// Look up a localized string similar to /// 'Trigger execution failed'. /// public static string TriggerExecutionFailed { get { return m_strTriggerExecutionFailed; } } private static string m_strTriggering = @"Triggering"; /// /// Look up a localized string similar to /// 'Triggering'. /// public static string Triggering { get { return m_strTriggering; } } private static string m_strTriggerName = @"Trigger name"; /// /// Look up a localized string similar to /// 'Trigger name'. /// public static string TriggerName { get { return m_strTriggerName; } } private static string m_strTriggers = @"Triggers"; /// /// Look up a localized string similar to /// 'Triggers'. /// public static string Triggers { get { return m_strTriggers; } } private static string m_strTriggersDesc = @"Automate workflows using the trigger system."; /// /// Look up a localized string similar to /// 'Automate workflows using the trigger system.'. /// public static string TriggersDesc { get { return m_strTriggersDesc; } } private static string m_strTriggersEdit = @"Edit Triggers"; /// /// Look up a localized string similar to /// 'Edit Triggers'. /// public static string TriggersEdit { get { return m_strTriggersEdit; } } private static string m_strTriggerStateChange = @"Change trigger on/off state"; /// /// Look up a localized string similar to /// 'Change trigger on/off state'. /// public static string TriggerStateChange { get { return m_strTriggerStateChange; } } private static string m_strTypeUnknownHint = @"A newer KeePass version or a plugin might be required for this type."; /// /// Look up a localized string similar to /// 'A newer KeePass version or a plugin might be required for this type.'. /// public static string TypeUnknownHint { get { return m_strTypeUnknownHint; } } private static string m_strUnderline = @"Underline"; /// /// Look up a localized string similar to /// 'Underline'. /// public static string Underline { get { return m_strUnderline; } } private static string m_strUndo = @"Undo"; /// /// Look up a localized string similar to /// 'Undo'. /// public static string Undo { get { return m_strUndo; } } private static string m_strUnhidePasswords = @"Unhide Passwords"; /// /// Look up a localized string similar to /// 'Unhide Passwords'. /// public static string UnhidePasswords { get { return m_strUnhidePasswords; } } private static string m_strUnhidePasswordsDesc = @"Allow displaying passwords as plain-text."; /// /// Look up a localized string similar to /// 'Allow displaying passwords as plain-text.'. /// public static string UnhidePasswordsDesc { get { return m_strUnhidePasswordsDesc; } } private static string m_strUnhideSourceCharactersToo = @"Unhide button also unhides source characters"; /// /// Look up a localized string similar to /// 'Unhide button also unhides source characters'. /// public static string UnhideSourceCharactersToo { get { return m_strUnhideSourceCharactersToo; } } private static string m_strUnknown = @"Unknown"; /// /// Look up a localized string similar to /// 'Unknown'. /// public static string Unknown { get { return m_strUnknown; } } private static string m_strUnknownError = @"An unknown error occurred."; /// /// Look up a localized string similar to /// 'An unknown error occurred.'. /// public static string UnknownError { get { return m_strUnknownError; } } private static string m_strUnsupportedByMono = @"unsupported by Mono"; /// /// Look up a localized string similar to /// 'unsupported by Mono'. /// public static string UnsupportedByMono { get { return m_strUnsupportedByMono; } } private static string m_strUpdateCheck = @"Update Check"; /// /// Look up a localized string similar to /// 'Update Check'. /// public static string UpdateCheck { get { return m_strUpdateCheck; } } private static string m_strUpdateCheckEnableQ = @"Enable automatic update check?"; /// /// Look up a localized string similar to /// 'Enable automatic update check?'. /// public static string UpdateCheckEnableQ { get { return m_strUpdateCheckEnableQ; } } private static string m_strUpdateCheckFailedNoDl = @"Update check failed. Version information file cannot be downloaded."; /// /// Look up a localized string similar to /// 'Update check failed. Version information file cannot be downloaded.'. /// public static string UpdateCheckFailedNoDl { get { return m_strUpdateCheckFailedNoDl; } } private static string m_strUpdateCheckInfo = @"KeePass can automatically check for updates on each program start."; /// /// Look up a localized string similar to /// 'KeePass can automatically check for updates on each program start.'. /// public static string UpdateCheckInfo { get { return m_strUpdateCheckInfo; } } private static string m_strUpdateCheckInfoPriv = @"No personal information is sent to the KeePass web server. KeePass just downloads a small version information file and compares the available version with the installed version."; /// /// Look up a localized string similar to /// 'No personal information is sent to the KeePass web server. KeePass just downloads a small version information file and compares the available version with the installed version.'. /// public static string UpdateCheckInfoPriv { get { return m_strUpdateCheckInfoPriv; } } private static string m_strUpdateCheckInfoRes = @"Automatic update checks are performed unintrusively in the background. A notification is only displayed when an update is available. Updates are not downloaded or installed automatically."; /// /// Look up a localized string similar to /// 'Automatic update checks are performed unintrusively in the background. A notification is only displayed when an update is available. Updates are not downloaded or installed automatically.'. /// public static string UpdateCheckInfoRes { get { return m_strUpdateCheckInfoRes; } } private static string m_strUpdateCheckResults = @"The results of the update check."; /// /// Look up a localized string similar to /// 'The results of the update check.'. /// public static string UpdateCheckResults { get { return m_strUpdateCheckResults; } } private static string m_strUpdatedUIState = @"User interface state updated"; /// /// Look up a localized string similar to /// 'User interface state updated'. /// public static string UpdatedUIState { get { return m_strUpdatedUIState; } } private static string m_strUpToDate = @"Up to date"; /// /// Look up a localized string similar to /// 'Up to date'. /// public static string UpToDate { get { return m_strUpToDate; } } private static string m_strUrl = @"URL"; /// /// Look up a localized string similar to /// 'URL'. /// public static string Url { get { return m_strUrl; } } private static string m_strUrlOpenDesc = @"Open a database stored on a server."; /// /// Look up a localized string similar to /// 'Open a database stored on a server.'. /// public static string UrlOpenDesc { get { return m_strUrlOpenDesc; } } private static string m_strUrlOpenTitle = @"Open From URL"; /// /// Look up a localized string similar to /// 'Open From URL'. /// public static string UrlOpenTitle { get { return m_strUrlOpenTitle; } } private static string m_strUrlOverride = @"URL Override"; /// /// Look up a localized string similar to /// 'URL Override'. /// public static string UrlOverride { get { return m_strUrlOverride; } } private static string m_strUrlOverrides = @"URL Overrides"; /// /// Look up a localized string similar to /// 'URL Overrides'. /// public static string UrlOverrides { get { return m_strUrlOverrides; } } private static string m_strUrlSaveDesc = @"Save current database on a server."; /// /// Look up a localized string similar to /// 'Save current database on a server.'. /// public static string UrlSaveDesc { get { return m_strUrlSaveDesc; } } private static string m_strUrlSaveTitle = @"Save To URL"; /// /// Look up a localized string similar to /// 'Save To URL'. /// public static string UrlSaveTitle { get { return m_strUrlSaveTitle; } } private static string m_strUseFileLocks = @"Use database lock files"; /// /// Look up a localized string similar to /// 'Use database lock files'. /// public static string UseFileLocks { get { return m_strUseFileLocks; } } private static string m_strUseTransactedDatabaseWrites = @"Use file transactions for writing databases"; /// /// Look up a localized string similar to /// 'Use file transactions for writing databases'. /// public static string UseTransactedDatabaseWrites { get { return m_strUseTransactedDatabaseWrites; } } private static string m_strUserName = @"User Name"; /// /// Look up a localized string similar to /// 'User Name'. /// public static string UserName { get { return m_strUserName; } } private static string m_strUserNamePrompt = @"Enter the user name:"; /// /// Look up a localized string similar to /// 'Enter the user name:'. /// public static string UserNamePrompt { get { return m_strUserNamePrompt; } } private static string m_strUserNameStc = @"User name"; /// /// Look up a localized string similar to /// 'User name'. /// public static string UserNameStc { get { return m_strUserNameStc; } } private static string m_strUuid = @"UUID"; /// /// Look up a localized string similar to /// 'UUID'. /// public static string Uuid { get { return m_strUuid; } } private static string m_strUuidDupInDb = @"The database contains duplicate UUIDs."; /// /// Look up a localized string similar to /// 'The database contains duplicate UUIDs.'. /// public static string UuidDupInDb { get { return m_strUuidDupInDb; } } private static string m_strUuidFix = @"When closing this dialog, KeePass will fix the problem (by generating new UUIDs for duplicates) and continue."; /// /// Look up a localized string similar to /// 'When closing this dialog, KeePass will fix the problem (by generating new UUIDs for duplicates) and continue.'. /// public static string UuidFix { get { return m_strUuidFix; } } private static string m_strValidationFailed = @"Validation failed"; /// /// Look up a localized string similar to /// 'Validation failed'. /// public static string ValidationFailed { get { return m_strValidationFailed; } } private static string m_strValue = @"Value"; /// /// Look up a localized string similar to /// 'Value'. /// public static string Value { get { return m_strValue; } } private static string m_strVerb = @"Verb"; /// /// Look up a localized string similar to /// 'Verb'. /// public static string Verb { get { return m_strVerb; } } private static string m_strVerifyWrittenFileAfterSave = @"Verify written file after saving a database"; /// /// Look up a localized string similar to /// 'Verify written file after saving a database'. /// public static string VerifyWrittenFileAfterSave { get { return m_strVerifyWrittenFileAfterSave; } } private static string m_strVersion = @"Version"; /// /// Look up a localized string similar to /// 'Version'. /// public static string Version { get { return m_strVersion; } } private static string m_strView = @"View"; /// /// Look up a localized string similar to /// 'View'. /// public static string View { get { return m_strView; } } private static string m_strViewCmd = @"&View"; /// /// Look up a localized string similar to /// '&View'. /// public static string ViewCmd { get { return m_strViewCmd; } } private static string m_strViewEntry = @"View Entry"; /// /// Look up a localized string similar to /// 'View Entry'. /// public static string ViewEntry { get { return m_strViewEntry; } } private static string m_strViewEntryDesc = @"You're viewing an entry."; /// /// Look up a localized string similar to /// 'You're viewing an entry.'. /// public static string ViewEntryDesc { get { return m_strViewEntryDesc; } } private static string m_strWait = @"Wait"; /// /// Look up a localized string similar to /// 'Wait'. /// public static string Wait { get { return m_strWait; } } private static string m_strWaitForExit = @"Wait for exit"; /// /// Look up a localized string similar to /// 'Wait for exit'. /// public static string WaitForExit { get { return m_strWaitForExit; } } private static string m_strWarning = @"Warning"; /// /// Look up a localized string similar to /// 'Warning'. /// public static string Warning { get { return m_strWarning; } } private static string m_strWarnings = @"Warnings"; /// /// Look up a localized string similar to /// 'Warnings'. /// public static string Warnings { get { return m_strWarnings; } } private static string m_strWebBrowser = @"Web Browser"; /// /// Look up a localized string similar to /// 'Web Browser'. /// public static string WebBrowser { get { return m_strWebBrowser; } } private static string m_strWebSiteLogin = @"Web Site Login"; /// /// Look up a localized string similar to /// 'Web Site Login'. /// public static string WebSiteLogin { get { return m_strWebSiteLogin; } } private static string m_strWebSites = @"Web Sites"; /// /// Look up a localized string similar to /// 'Web Sites'. /// public static string WebSites { get { return m_strWebSites; } } private static string m_strWindowsFavorites = @"Windows Favorites"; /// /// Look up a localized string similar to /// 'Windows Favorites'. /// public static string WindowsFavorites { get { return m_strWindowsFavorites; } } private static string m_strWindowsOS = @"Windows"; /// /// Look up a localized string similar to /// 'Windows'. /// public static string WindowsOS { get { return m_strWindowsOS; } } private static string m_strWindowStyle = @"Window style"; /// /// Look up a localized string similar to /// 'Window style'. /// public static string WindowStyle { get { return m_strWindowStyle; } } private static string m_strWindowsUserAccount = @"Windows user account"; /// /// Look up a localized string similar to /// 'Windows user account'. /// public static string WindowsUserAccount { get { return m_strWindowsUserAccount; } } private static string m_strWindowsUserAccountBackup = @"You should create a complete backup of your Windows user account."; /// /// Look up a localized string similar to /// 'You should create a complete backup of your Windows user account.'. /// public static string WindowsUserAccountBackup { get { return m_strWindowsUserAccountBackup; } } private static string m_strWithoutContext = @"Without Context"; /// /// Look up a localized string similar to /// 'Without Context'. /// public static string WithoutContext { get { return m_strWithoutContext; } } private static string m_strWorkspaceLocked = @"Workspace Locked"; /// /// Look up a localized string similar to /// 'Workspace Locked'. /// public static string WorkspaceLocked { get { return m_strWorkspaceLocked; } } private static string m_strXmlModInvalid = @"The modified XML data is invalid."; /// /// Look up a localized string similar to /// 'The modified XML data is invalid.'. /// public static string XmlModInvalid { get { return m_strXmlModInvalid; } } private static string m_strXmlReplace = @"XML Replace"; /// /// Look up a localized string similar to /// 'XML Replace'. /// public static string XmlReplace { get { return m_strXmlReplace; } } private static string m_strXmlReplaceDesc = @"Replace data in the XML representation of the database."; /// /// Look up a localized string similar to /// 'Replace data in the XML representation of the database.'. /// public static string XmlReplaceDesc { get { return m_strXmlReplaceDesc; } } private static string m_strXslExporter = @"Transform using XSL Stylesheet"; /// /// Look up a localized string similar to /// 'Transform using XSL Stylesheet'. /// public static string XslExporter { get { return m_strXslExporter; } } private static string m_strXslFileType = @"XSL Stylesheets"; /// /// Look up a localized string similar to /// 'XSL Stylesheets'. /// public static string XslFileType { get { return m_strXslFileType; } } private static string m_strXslSelectFile = @"Select XSL Transformation File"; /// /// Look up a localized string similar to /// 'Select XSL Transformation File'. /// public static string XslSelectFile { get { return m_strXslSelectFile; } } private static string m_strXslStylesheetsKdbx = @"XSL Stylesheets for KDBX XML"; /// /// Look up a localized string similar to /// 'XSL Stylesheets for KDBX XML'. /// public static string XslStylesheetsKdbx { get { return m_strXslStylesheetsKdbx; } } private static string m_strYes = @"Yes"; /// /// Look up a localized string similar to /// 'Yes'. /// public static string Yes { get { return m_strYes; } } private static string m_strYesCmd = @"&Yes"; /// /// Look up a localized string similar to /// '&Yes'. /// public static string YesCmd { get { return m_strYesCmd; } } private static string m_strZoom = @"Zoom"; /// /// Look up a localized string similar to /// 'Zoom'. /// public static string Zoom { get { return m_strZoom; } } } } KeePass/Resources/Data/0000775000000000000000000000000013204325236013734 5ustar rootrootKeePass/Resources/Data/Images_Client_16.bin0000664000000000000000000020101113224757312017440 0ustar rootrootO|,VC00_Password.pngPNG  IHDRagAMA7tEXtSoftwareAdobe ImageReadyqe<GIDATxblUgؙ1|&u1[V3e@, 8ߌ 1*?)YfPd2cY'V/ u4SFIfk|ee:;ÅG5ew+L~#3 fbd`ddڣ.GVp]|vn%@OA  wJx T&KQ? ?}uϟ eؘ կ É_ Dd%ąĄxZ0~e`$4ňH2 (:}I@!uk)Z9x9y^~zsO߿3Kq Y4uߟ7GIPH"_w/8Yu8٥؁?1Q/63<}3LeYkn'  |A/3\&"D '+M?2Sߘ&q=+';0Qr20p1???/^:??C##?:j @123['V)`Wp`x;?@Wgd``̔\̐u#ߓ~k9Y82 10s00r10('4?'˗r2k~=O7oI=}wz/` ;OcW H~.7*tfS'A]1    E8#P߿|'ʿc@!~狥IENDB`C02_MessageBox_Warning.pngPNG  IHDRagAMA7tEXtSoftwareAdobe ImageReadyqe<;IDATxb\΀g`P~@sb)ϤNŬQ'o: a`P27wtf3b33` 4 /0|%;;[W74 @(.``.ib,i` " -"Ơt4 @,,,i>| 20s0誨pH0Bm ɚI00143wu1bfP` P @L<gv3ܽv̌Q@;M@ x.& , ",#''ׯ jsy @㓕Pۏkˁ]%.. -- IX. ~2qsqt @1AQFEڋc*Z  !^e 2#P(  tV>L%&| C~?iII9@쟿32Qd=h@`+#/5{0/ ?c>u*Cco/o `%8のA zWb,V`fuïW?o\ F =޾ ?>~l YY q7K%^o/^0f1~g?@Mt #а 9\%N/@l@_Lhge~ ld"IZ Y IENDB`C03_Server.pngPNG  IHDRagAMA7tEXtSoftwareAdobe ImageReadyqe<$IDATxb?  ~f`g琕itrr av_>wG|!H@1 akkk##COO׮߿>}knnޙ0=€mlEUbo߾góg.cb`ddc`ff rs>};?~1| ee`cc)@Lps0~ϟ_ JJR ?fx5 3'ze|,,tqss6|  P `ddb7?|F! ?351P%\@5Wށm+T3#VNNv>>^p7߿l6 yxx=xp6?10{hWCh|oG@(y_ED~1~c`w}v1̟?Ƀځf] 2h!륳fkWW /_GBIEń^x&x҈׏VQg`akcg_888z ̴3nw013eՏZ& t U5>bgAD8C7} B wVZJ =::z _s~f`_/8Y˃W} )e=޿IENDB`C04_Klipper.pngPNG  IHDRaIDAT8˥Mhy3$IW%V-XqV\<Mœz DYDî=qY+GU55h6|cf߃ԋxOSJ=2Բ*U#+VO ni¬BBMF@&D{rݧ_@, q O2Ife`'=sՏN|a )tVϽc?bR7e420beqy /Г˰gA   Ы ӌe ?ڧŭ#mg0ܸq;A} |bKCb t++û+6b+G < LL ?|goO \ L,\n@ſ ^3p0s1~g:~  s;>Q2ee` Z0aӗo v˟  F`J &( (çWnΚ''xn@12/.d^fU&V&Pcߟ_~Q`~bJIENDB` C06_KCMDF.pngPNG  IHDRagAMA7tEXtSoftwareAdobe ImageReadyqe<VIDATxb?% Ad+''Q {6  *dVAC ?JJ|B6'0tAǴD @YXQQHbvy s4%$X3;~]A}ڽO/PE 0~q0|xX88YN&?0\}PsL33'$Zs~FV ;ýw@_>s P]@ P0Ii CI20naLj@O0pOgd`ne:\ )"9#IENDB` C07_Kate.pngIPNG  IHDRagAMA7tEXtSoftwareAdobe ImageReadyqe<IDATxb?% X+˫Hg?+VƿYK6LE //1@bQdTg`d``ce`b _yVSmGϯ30dq33P @,?C' OaPUfB >UӳOK4}qҜ AS#@3=̔_` "]X&A5) " ْCXCk+ '~{i-nVظy^\p!XADj0P5bO}|7_ee~| "&-y  "JX0T@@N ӵ/>2+  ?o2|#q?۽Wz˪ @ WkWCo2<~ɂZ7#.e)_E0 @L, ?15 odXqÍ_V`aX|_OjH## 0 >=vы_~|g`ebc?bf>!IIMk/@,LLykי 30303;0csp02L 0Eꕿmaf D Y۳@.a>IENDB`C08_Socket.pngPNG  IHDRagAMA7tEXtSoftwareAdobe ImageReadyqe<.IDATxbdp?ß l6Vz¦:|LLwvWݘ|_W@1 [!eog}0QK]#IY;@108gQoן+O~&ciA(]>65Z?  (IL~2]g0|x׷ >f8}y=àhr@A 7 ž /$' SC ϜaxCP+G 70bA BUP#;ED: k5?3A %(?;c<0]DKJXA[Sшhw By3p2py`p-C &'7Aǭ@;.  #!,lTH.A˵%'%!6ѫA߶))ŷ AիǺ* (    ]$}e`~.̚l }í 👑//C߫Wwo}T| ~g0Vq`i10\0(~ $ `ZlfIENDB`C09_Identity.pngjPNG  IHDRagAMA7tEXtSoftwareAdobe ImageReadyqe<IDATxb?% (X{X]/)X302c dc`faL 1H/<}@,&rUU00|~  fׯ10111###23pqs1 ǫ+ ̬l _2}q÷X35202 1XYi3/@~g`zUZS@m `_b?3r00y*_2paݫ Š%by.~dxqv8= -?3 Pxpq 俁 ?|ῴ5g=j7?aAAAAAA?S1AUN@ocC@bÏoffx`qϥ a]NL/Fh 2Ͽ? ~c o?1gPs20[+1~e&(V`4?/??18b7?%!4u01 pTe̴6uضtOy3(e30l'@L`o@1WMQTbbd?swMߘ \~'n \([j(۷, < _b`f - CHp'V100@ !s}?y_@`5m30Z\@OԴtWfbx"{ W^cgead tǏ?/,ɴ|nߞ@ʾ^yœ* k' ex=P#+ 0ce8z{f M^6:Ĵ ⌒ l ٞ0b<0ZQoN`/dž50| .KV!6.v&@x)inAw0d``c [> 1WeT5q%@1 )p[32> x׷ O11:1p 2' gdaxMIY0U8~Ÿ?)30L`Tff tMhC@033) (_e<ʸ0:2)wn^V.&`L?XTLmA5  :ss &3+A̸Qš_]6qGR'ÑSg_:v '^xt ÷ Ŀns|Ni`s1V¡+k@ ؁'@fga!+IENDB`C11_Camera.pngPNG  IHDRagAMA7tEXtSoftwareAdobe ImageReadyqe<IDATxb?% (A99ig :6 #ALL; .   ~|hIJJMVVA@YY?ɰO_2\zAGWAXZ&9b`cTAF;*B:)% ~̠`a'P6@/ b ,??@L @?~ d _3?p+ >*be``+FXR &&&ffV02ٳa ΀ @ 4%^r8ttL,~ 4 ubA<~00cpsuf.Nn?]r3@ 9 tçO_|gec'P)(Y?1&vvNK ` \` _y_h/0@Q )6rO~tvv/~1Lp@Wfx>ׯ~\??00`A ߿wF`3]L,̠Xc˿. FJ3@é "IENDB`C12_IRKickFlash.pngTPNG  IHDRagAMA7tEXtSoftwareAdobe ImageReadyqe<IDATxb,,e`OF,,o?oas LL 30L/f""h0#+?Ϲ_q2P]/P H o P")h3)/k @I |Y ti'#9b:EdjߙEEO2Y333+߿? e|V -]߿}hq&@ :2 )7 K{/G4>@=*@]u4@A1 6 S t..UGG:GPfgZ|ޗOO5jǎܿ%<&vv;`,D @11}d6 Gf.. W/?.\$c#P ?@9`ذ311}db5@ӯݻr9`4``/vv6FPzc`Z &<P?ai o7 3 033?P(ï_>|x_ocecub?OA gf Lr;Lb$@L@[IY)\ @z 2@dsrq10|Lo~ tybR`~5>ΰaj!!9FFvS[S}B]^b`&[_~x'N0pj*)1( h3gyϫWL Xf: yo:)0|4ԁ)QA*Ṕj^@LHFƿ|a`&ه>|y`x lA jrjIENDB`C13_KGPG_Key3.pngPNG  IHDRagAMA7tEXtSoftwareAdobe ImageReadyqe<DIDATxb?% X@Dxx:b1r&o}n=n@ LHX7?)"wf&W|{| <,K{FGϸTb=ܲK 33#жYŰZ VAF````dbfx֍Xc{ 2030\\ 0 tΟ9'WWKÇ0o+}Dg8  6ǏWXX-DDxo  `ve{*p ={tOߏau&Ó'~h60>|22pp0{E&_suSH[ ~AZR-=4## bҿ?~z̹#n_`@1((H:s١Czvw 2|<<<˗o?}ԥ+t7o>}͛w,,/^g.(033 n_x7/f PJϛ7 _x[Gn G o LL nfPWW1-ZŒ _?`b/;#t&"Å ._>0Ǐ':tƻw4z?0 )MYIENDB`C14_Laptop_Power.pngPNG  IHDRagAMA7tEXtSoftwareAdobe ImageReadyqe<+IDATxb?% (AKLY x($Qw  l###2:?vAnA1yyE a}U>^?5\yu뎵.] @0?3xx8|< jgln<v ~}ax 20ĉ`b``fddc0M: Xph000EpWٶ, bb"`Hin s#@74PNG  IHDRagAMA7tEXtSoftwareAdobe ImageReadyqe<IDATxbLJd2tgxp+b6c`ddd`aaex͋םVVVd#ej89tϟ_W`!X3;;÷o=TU\?|7_3())3yʕ z  f۷/1\tŋG ߿fx۷h i; @(r]r@S0TL$T޽}PUVahO@pq1 (\rߎ;  B _f3f07P ϯ- _h0/?޽ X@ß?~bd@qk^s޼x UY#\:Y @,7{iԙ 10`y3{d9Y-Td1s (~e4AXEJ;x910p0feaך6^CCSn IIv_ ``𖝉3+o&x{. 3WZrox3o?pի<>}:@1̜ lЏo?:e 9)庬WWl{?jDCWX_BB|„6 a @@Ƞ + Je a1 ?QSSo ;;g(`^w3XIENDB`C16_Mozilla_Firebird.pngPNG  IHDRagAMA7tEXtSoftwareAdobe ImageReadyqe<|IDATxb?% X@###:G7;b/sqiNo}rOsd PO @ \ wa?^}_ #h.Pad>O?xw>G5\T.@LȚYi62? vo?2| c>s+@  ,–z3 0zmдk_0:xGQR+ P e3s< \3ppZ/ z7?xExy9tƿy`!wF ɺ?ޱ0l[x'>|4C7.Fbb~~o 06^KJA@O_?޲[ۂxP#3@1gPSmGO|/`?~?uڥBB@|";mx޼e`_@K~: YX,,߾=q$КG8"F[NZ 00iүo_>zЀ=e`0wc5-a`` &5u@ i/@[mdGgc`q >з>g`bbvff e~Y~v/@:@&{? O8ޓf4?'[ \\ r\ i$$^38].@Lr6H306v6]5w|!a20@L`%+PRAiWp&NP(@A ߿y @LG>~'!@[ udd``bd7=ݳ׬:KBAQ1L(d2 A)]㇖jbӃ{wHI130| 0H0 @^>2Lj`rf8@L@U痲ac/_^`H*|À n&IENDB`C18_Display.pngxPNG  IHDRagAMA7tEXtSoftwareAdobe ImageReadyqe< IDATxb\hS#CC1?30g$ψB&&f?Yz+X0@ lFFe``aa͠@,wCs?$E}@7ß?@203 gח\c ç ?02(+0zz:Ͼxzh@1z2𰥦$[ʈ3z_ ߿30nNNF)}9CWg*A!KK+-+"=@/W[JɢdECSrݏ?{ =~ l@fd`HJeABZ_0@,Ғa8|*7XYDD89~bdcHJdf10ܼ@18gZ9(3K00033q1gfaHUbPS 'g;vF(nemcŠ$`h Ơ)t;ï? Z ߾ a߾\>]_@@dD5$|f`ANAOADWF_@:h?FGs>~|(@1sr~3d:PwbF`1ߠ]/ L' ~t7^7W@H_10? N|p]&8x/`j`b ~|]RA##T%a* rrꊞ*< L >ccc)w X~Ġ1p -FF`^GG6>>N70^ׯ&߿4$$$W mãG}:ADAZZAHt!!aǏoܸ| @A @3,[wihY\#'' 6`ݺ_ϟg & ر**2.]:=a߾ˁ1.!!Y ӇoY޽{k/_]AFFMCC_'$$AO߿c^F ,-YLÇ>b>u7o^~5+_JIIs XZZ)(H1/2,Z(@xx?VPPa`aaPY hjwA\\AJJ(W _5W qq `%++.Gϟ89ف)ܹ8q`ӧ˯_?,X0@\moQAQQ 8gP`FP͛gW^jy X@ĭ[WWp缼ڥrr߿bsP>0a2<{f2@0 ܹss %(qrr1̜9=z/F=ã  ,-mqssCX=;&cg+IENDB`C21_KOrganizer.png1PNG  IHDRagAMA7tEXtSoftwareAdobe ImageReadyqe<IDATxb?% 96zZS4M9}^Ʃ{%0qp0rzc#@en+@1Pp4/*PG/aVa&?3|raB6,ඕo;&ga:OFMA2-Wq.= 1b =̃p 3+A:·0Q nA5y!MA9#//2* و(:Aa#ΏA!+ ]B0,  ńͬé^uˇ ϙf`7k5]=FNo`%:\ x@@g>'+V7@X~r0102ϰ<חDB4~2 0H m=x7w 49ɱn%ɠ _L B 3F33|[o> &[8}^21oFdX8Кȡ@O#g/v6+? $I3#.yp%71Xap4`8'@ ۏnҡX_| ?1}})"޻ ZO8a`x [} @yQifWzĠ|~֯}{5ë_'iBL :v39 ^z OaxT( \@@Ĉ;YXd ? a2\ Vjw*IENDB` C22_ASCII.png0PNG  IHDRagAMA7tEXtSoftwareAdobe ImageReadyqe<IDATxb:a### q޽[ZZ aǎ?_0+W?@,@@&D0 S}vKKK+׀ 3033 1K@BWWW%%%_~-0L͹s^xv@LA6W o޼[xl"{{{?Y16  ]9D;vӧ ,,,`9bB+ >@1 }t Ąl6/{ɓ Ϟ=G#@ pqq1{= @`6spp00@w `Fa@NIoddl ?@܉RRRi@yVPCX^| 2/IENDB` C23_Icons.png PNG  IHDRagAMA7tEXtSoftwareAdobe ImageReadyqe<IDATxb?% Xt>)kr񛁑hؿ CHd?g* w-їǛ 2be` T7! @>3P P~f)bM1zwY_ C 5gbd`؟&11|P o |+OYc`C9<@eN'0fe`'0p@CxPߠ XxDXd?! J0  L 0Tr02˓{-c2R@~bdlV`Z 4_߿` `"a`dQ,alf_ srZe IENDB`C24_Connect_Established.pngPNG  IHDRagAMA7tEXtSoftwareAdobe ImageReadyqe<IDATxba!Fٿ@۷`6' 1 2[F/;} *`jTߏ_>?CO~gAx8˯F/گ3"ԎڕTo?_|[P+G ߘ~g{ 7 _0|}xc93>ad'Χ^ $\ 44Q#SÅ12o GwALK ) Alw\bwh5 قˉ9?`\A  ·ryFsȌCb)q`f^]^^_L,,W>,ۿK/:`hΓ? }J@ ƺ/~3`Ѧ3#`A s#0MƐv˧ $_νE !07ڲwIENDB`C25_Folder_Mail.pngKPNG  IHDRagAMA7tEXtSoftwareAdobe ImageReadyqe<IDATxbd```bpcC@15@@y' b(fbFdd8;ݷ%2+Tx- W8GA؀W_d`Xx&Ml@ x E+g>38aK > OgXe@>C 3ȋ1Xi0\< } 3w ' obSfH 7dad/55&0<iT " @`^@{?0X23㌉_ ~ge61dq0Ha @L ͧ ρ~ưc G0}ab^rW.Nn`LwbxuÏ7`W$30%/7#W~&pr 10b0Ta8}:67F| ;vb(ra`̠4 d8 )HZd忴g|߾C/pE3XN% @ @ 3q%##󤬬?/ɩ} @X, :@Oƕ EHGIENDB`C26_FileSave.pngPNG  IHDRagAMA7tEXtSoftwareAdobe ImageReadyqe<IDATxb?Z\~11004@az{>r /_/ ğ?/ (AU'7[*xvkwѰA !ŪDZ?e>,q6cd``b;?# 7P7L@^>A.~baFF@El@H8L@ 8@`db2Clg`27P32102C ؘA 85yh.'T@Af?mF#P߿ /! _??3|_w3WY|v@À/$Z33;?0FX fc7 ˯ L _12 F~3L`3e`gf@Aߟ@ge0w_S&s}6@qr220Xjb_P4 Vq2pbPt67;#ODy^- 4j@A4   X Y3|AT/F &l| ٘0ewt30ДU>ad VHL؀ /6}3p]Fh"bFWp|afxo參 KC4>Sg%IENDB`C27_NFS_Unmount.pngPNG  IHDRagAMA7tEXtSoftwareAdobe ImageReadyqe<IDATxb Nb៣' XXfa|3C];/_ELLLOKKYXYؘ888޾;]޽{@,,J< ?~`LH63  & AAQ} b ,,@_ ?cbdR* NNn-..߿;Ab3 # 4@ XE5LL4~'fK l}gegPUUbaa EEYU--߁ v? r߿ /00ՕYxyLERRT ?BL(ـ.dv'':&@pq۷o@5Hd(b P??@1rqq-8@d *?7 oY˷& 4GnY>} ؿ@W0t>#Ï߿^x;_ F33 c'@_9% !O۷u vV?LLLll,?q^bdc,fd.W \%)um_^|o`hÇw,'O_ A LLI//-./4(4 R +nnix >~|rȱ>c?ט90ܻaČ7?{tD bi`& _|ѻw10Ȱ1 3<@W@ ',f k0#IENDB`C28_Message.pngPNG  IHDRagAMA7tEXtSoftwareAdobe ImageReadyqe<KIDATxb:a### [ZZ aǎ?ϟ~O˗@!n(4iLⅠ;yTI=8k4ͦ#X@4+óV_YpN @qa&i`h1%?Rr @1 i:C˞?\|L< 0c{mf  3,9!AZB |0~cf`tAs)3 ߸>2 0~AEAy4Y^V ;. ?b`q"?_1<~ {$n֟Y9~gv ܿ%1\|3 _+ Y{70<~lyưzY~b`z`` ѿ 2 ~1 6/a8 w>p#s'n0&03|1ˏ A \ 3OLgxk/+; ,8"uBb0bMH~SssU}k0h"(?~bafff%_...x8lE@1 @,Νnaaod k0!R L ?@܉RRRi@ѳ8H Y^~ xwjzIENDB`C29_KGPG_Term.pngPNG  IHDRagAMA7tEXtSoftwareAdobe ImageReadyqe<IDATxb?% X@D6cjh$fQ>0p |uMwm6qd`aanb &2 I RL;W[g$Vd/_~3 v@]`4JX5T̚KNSA@R /3331Pk@ bc P}K_ 1H02 <{pA𕉙1K@ҽ `/؀wNȠ%*}_0\8 XXYΝ? [!Hl@A xʐu%I6'+ffx} @33r0 I Lg &(19@}ʠn3*>o51{ 7^VvvHx@1ć g b[ J 2J j"  l| < MOQL b@dbdf [ ?g #vya1 0WGDK!!ABA? /8*節  ?~gx L 8~{qi/J2Xf&$&?~ Nb  / ?329ˏʊ`|f>LCObs㻞$Xd"fb?@1R >IUIENDB`C30_Konsole.pngPNG  IHDRagAMA7tEXtSoftwareAdobe ImageReadyqe<RIDATxb >?101110221f`` #77'k7wo߾h X`H3.NNsS}^yYTbӌϞa`ecf; mA e/ï_?TXXp88@@DVl[B,$YkZE)HA f1'Dk R:xbaeae#gOjkkrsΞ=Pjd9bbaee=/;w2:۷ ?A ` YXAPP bef a`i <&fp 2@14}ܹ oN^f Ûv͐0qD... `C@119l@ׯ^2$3~h++Y0  `(2Սl/tgf{?͠f30 3 ;+Ï=z @6͚ @?@v@,@?00vI `1m4Y&`Hg` L ` $bafafdUSex7Pf?2|Ѐ_@0B8/@s3571a`,##RPr&=`3oPJe w0p;X([B,c!/0Lx/_`+@1Hڨ T@&@5A,Pc8; *zݨIENDB`C31_FilePrint.pngPNG  IHDRagAMA7tEXtSoftwareAdobe ImageReadyqe<IDATxbf߿3 rH12022h-[vo9vd4?b7Ǐ ||FFz< XgDj ;ffn&&^VVF3,ׯ@7b(i_0!4-?b9@ۛ/8,-5?_C\N>>x99@##KUi)q?~@%@#Q``ȱ_~  ]=߾0;ӯ l L@ bb\1QI\|wt?o&@EZX3 9~Ͽ~fd|`x-4y@()) 00˯ ' 3\p=?5}g``cPPV 1>}? s2{xFF( >bx _~ w>z!pgbPM_f7 ف.d 芟 .|e X~xúSY88XATw_(UMw ?=-//0'TyÇāa ##ۧwݹ7o^㊏OcRd* N`_ L JJ:DvΕZ@̊ 灌Wej&"2Z@`- Du~ /P~T` <{/Fa/ ?|f`b }Ʈ$1ITxg_? YXDM`5y/?2(L ! @20.c`drGahAD*5vx)08.B)p*&YwWF|'~)@,/8?|Ó c/HO5?ß JPg^w@Y_`l_`d`7pGouJ @ 0"w?@w221$  `ÕgTD,<o3av@A ?^~O_e(P=P]5H/@ `/+Lll b>~a{~ e58-x3H/@]͛lpO_~0KF c޿cf_=P lk7=~m.R ώdxyw^"$>O 痟?3c9~zO ?al;##ׯ{oף?n^Fƛ_߼~%-_w t5# ތt԰IENDB`C34_Configure.pngPNG  IHDRagAMA7tEXtSoftwareAdobe ImageReadyqe<fIDATxbd``UQ($$(Ç7o^Y' @ׯ ljjjZ ޽xYʕ lܹĬS͓wސUggPQp̯_W\r: fOOMIַn]uZwT5EEE2<~TڵK?A  ""']]hOӽ ݻ߾}!--ːZ#/kk[ az006 ?~ab fNNve}cY scӧo jlo߾3zi03jIKKhbYY1 kG]~п  >=t۱ceݻ/tտGeRUUgVRGЕ \ r^Kl@12hii11]***ŋww'$dbbd`c f q`ffw,,j/]tlmyxy 3g/ϝ;{1@ 0_){dee  n<;;wۻr0mg'C\\4͛7`ddzԦMk_|K@&{0<@5@G׭[񊕕 _"":? X7o^畐k/]|1>ym%GIENDB` C35_KRFB.pngPNG  IHDRagAMA7tEXtSoftwareAdobe ImageReadyqe<?IDATxbTSSc 3S#Qv6f6ff&Vf6&FFf&&F&& q}[ X}_2~rJpr3ffd1~!&A]U`>.o Sn)Ƴji! n~:VV _?3hà&+v Xԁ ߿}g|jz 88~G+%q6N. /{@^aa<|\j o|b`d``h '~3J3 =yh@11 i3×_~`n$ 1ax?Y)I-rO5EQs~_5Yf \< y2|gaWR>~$ @04G,WN)>ϟ1hj0(b0gg '/yAOF Ń^%#,ERoN(;n? ~bv*"!-痌FA2u52# L8G4+ '.sA-M ! 5@@(RF?4<8 #. 3102b77V^)-3g~~﷗ ?s0'#:E+AHbtyQ!!I;#ՈMB1 PJQ#0щSG/&7}`x{$=~֫W.0.@1+[\Nz7orSU@E(13oFF&0JtZ[;IENDB` C36_Ark.png6PNG  IHDRagAMA7tEXtSoftwareAdobe ImageReadyqe<IDATxb?Cxx8 Zm߿)S8qq=MHpEqqA6W3\t˗ 8Wa[ %׍כ~iI 3#{8̷'&?| dcf񏓁PޢE^|```HXDPR_PH/]<t5byai"&  ˬ+#  ?O_~kG-@] !;,8og_y|N$GE62qAw3>}Ϸ+ o3=foG_?;[M hN6pedffP }``cfd)c.)D ̼| O/3([ , _2  8 >20|)0A ajfb`e``dhߠ 6SSAVFV!a@M|@ ivY031FX3? r "@q20t6d3q3Ͽxxx~l@SuGZɳkϗ ess? mdge` ߌNHvv"_?*`{޽k@+ x@1laSDDb50\ŀrz@@H`2@IENDB`C37_KPercentage.pngSPNG  IHDRagAMA7tEXtSoftwareAdobe ImageReadyqe<IDATxb?% L3i->}aSy_xqť# Ne2-PPNëצR(P -{c ~S/'xom Rq/>꿤K@@ X B%$3y tCahq &韉.6J_!×;GD̢lc̙ϰ} "byxUt3$p/ -(( 2 .`/y8&O13a0}`l%GD K3a| &&]"/7?qϾ3a7 o>`p9()wFFA>eeUVQ@BZAAIO?2&cPcgxwWOaASSU j+ˋ0(e30Zgx _߾a`vePb'377-@ =o?L cQaQef` ~101ps2h1 knn1| `1n6.b:?0` #2Fa`8tsruphq%އ:af )1.AF-v*ld FP^pv 7`_W%v^kbc~_vN~;~t#@ `=W"߿~Z3ppϠ-MIIǪ |ӧ/ LL 0 @W02q22J``bJA<G<% *"#**% J3A +/-55-"" !  ?#;?0daaG#u0ܖc02b+o~ ?@볠 77P,Qs#seexX;''. ? oo~ȩ a9 H!{ GO_cok&߁^q%̺pm%:0/=}+_h2{{ yx}7߿pןrVAj8-    _ /B|{ϰ&YVYi!/>1?6byMȁ!S  {Kf`Ҝl 8$XLD9gx\xzB 0D;|f֌&IENDB`C40_Mail_Find.pnguPNG  IHDRagAMA7tEXtSoftwareAdobe ImageReadyqe<IDATxb Z_ LL 11|[[WG)ѣ;wh3FFV 4?Đ_~krprKE2:pʰϏN`` de 7/o;+k,$]Bs/>πd ???_B<#0_AFT!(Kie oߜmc`d F7uMS36u5w1ܺ?~^|2 kT10yA77W9<843#! 1" !̾/+&A00XH+1##6 GG;ĸYBL _fO| _~g3 df6V.2893##wǏ\/.6Vv& F iAAYwIqybaaeN?pq(/aN6o?A B@C?{ðmǞ߯lŻϯ?`cvݿ1r31|xpAAFEpI3zdE-~eA##MSEF'  c3 5A%%N: #庴ūCCw+)G98|ghk_yۇ8>?+?zu * x^`dd??S+0XX~01 C~39?[X@T 0r#333 &dr~r`yS{YIENDB`C41_VectorGfx.pngkPNG  IHDRagAMA7tEXtSoftwareAdobe ImageReadyqe<IDATxb:aA Ȁ[ZZ aǎ?c~_~'X? TfmreV>>%{{?~`bbK9^ii13AX=i Ϗg}4 ïӧ00 1  `@}m2'O2&T$ tQ3Hx{3/ @~_ dAA @/4@1|*䷵e`WWg*&}; P\`L@ll \F ..>1z`5s1\ ¯͘ #+u g,0]-ׇA  E߿ ~ 450 YZ2up``d`  dO}}0ll ߁ 궕WWna ,DiF fJ03ܾvA=rr UU0002_k.`4D\Ey ߁y wA`Z`j dsrr2@;wo`L%kP43|?> ҀXFH6gyO0-|>IENDB`C42_KCMMemory.pngPNG  IHDRagAMA7tEXtSoftwareAdobe ImageReadyqe<#IDATxbdpPb`0`򓁁 H3a`d%ĭr׃/ v~b`g| T y1ГQPSfc= sZ Y3~?lhiAAg/o>2ex{?w Iu#M ,3A3w ’&@a1;Ŧ$i` 蚿T+fy.9/5@cE} ARa7c lOJ0k 30s'+?t} v&yH`•AMі!S+e} ]7 A30*2 fz X0(11  g< _ %i~1pfP/˿_ Nc`cdj UbV`d.=eg8 |c 2i20j1}'>`cGQwXb`x'   ҆, 31{g0\yK?3 '{?z`  G fe`fG!^V^}pgd`b32 |(l 7L~ փL/#W>XYy8Medo0AAh*3Û^~5 pcx;ç/^ ,l b;e@20 '<:&}egxë/L /0|| ?Āח 6`͔څ\ L0o 3}%pób L|  Ͽ2ܽs  p^`ddcb/5w̓3pU pL, @?3}7rc}w[Azb ÷_,8lY?׷~9 =@ `*LwtIENDB`C44_KNotes.pngPNG  IHDRagAMA7tEXtSoftwareAdobe ImageReadyqe<LIDATxb?% ArC a"6 ql=?!oAG _6 k #8?  A 0K  9e~\o&C-?>}Ē \ \ 8210|gǦ^:n00؛1h00=1|P ?1|}GĒb+4AI;G_h?00c#ço o+ &^?@Eo~A5@[/@0ssg'0ۡ5bw ?Cb0 ??@K?9@gcʠiW&@ٌ@g7~z%@0cH 0 9ނr;ba`dF:o@{X~?fxqA@,"߀).([@d0 `F'_&~1oq ?+ly޽#/ $&@Ⴧ'l@7321H= _"ܸx42|)3KtP!@1۰_~}ׯ^beTb` )8P3#T3g.lѣE@v<< Ǐ^{YDx \ L@|ɓ gos…Ne m~g6ß?_yAo2 abb`Ǐ ߁;I !+PP6}:ˋ `_PeaP A ]YYl1]c#Ws?~}@w&669fAׯ^=`b&^jjK>}?HNjd`tO+8g323G #;oy?zx.{#?%ff?@_t y޾ j3NΟGpppPg &&&p @L?~}L&`x($ܷo[tߧ>;'0@Q ~1|@1}t/33e~?g^*Tf ^yV..O99(>~''oiK) NfE0A<=x̌' -H^IENDB` C46_Help.pngPNG  IHDRagAMA7tEXtSoftwareAdobe ImageReadyqe<5IDATxbdНd`ft̑?û7_?2`[S(^ 00W gX_>xrק/rn3f9Y!>* ߾ex P b`daefQVz7o103AG  loIH>4[>* 8' %-A6AF0\:13$  [C1<<RA j+1% 3& kETZK^2h'# dx7'wU1w_0|, ?CDH Xx^~p 69!Fdggi, !0o#;< ,\lA1 ,cH _f`/wl2y/PO` L@@18˯ L 10^jZp#ÝG_3o`Pٯׯӗw}zpAZ 䀊~mao),LL!' :_ĸ2`à`J@~8߸y߯UA EF$ Z G?}3%~n5> !3FNFnƷd~oF5@12A2$?gf3(}׫7~x3caK̢ZtIENDB`C47_KPackage.pngPNG  IHDRagAMA7tEXtSoftwareAdobe ImageReadyqe<iIDATxb?_g?&,bU'qP|һ;$P-+]~@, @LD=L[kĘ toIo^}YeL\/X` A.mW3ȫ 0))2(30 30depwW|~Ll?q6@Y@Y3.. ܏ؘ1I22H(2pɋ10pr00|cXXgA@`/){3`P/*#_.1;2ég2(h0pD2ܿϰ j@l82'*0p!Ó;> ?e`~ŋ 1 `ضs  gbdQd06cxL9%g~c`Re`ba@   @`| Y`Tȳ _8ؘ~ QQ @L`LL L@Ȁ1aX?EĄ`22E L X { ?~g cd{_1B|tOwo~0I30qb%@͌h Ox 3*)3Ȫ03)/8} +d@`~λ71S5TQWae`gb`zR8)KJ0|̮%''-b odd?k×/ @`BBB[WNNAn.QPFHlY 0:vzRAIENDB`C48_Folder.pngPNG  IHDRaZIDAT8˥JAR;A++k`·k+FG0R 6B,lD b6dw~,l7 Xf|s,kKY&8`zXD= Q5i^Utz(@RI܎[p|rLuc ?Qh;hux1w`d2C +T"6r+Ԅu/tZ@Ou2y8} Ni*˟Nȃ92/av ĸq֋8$eW/ < 6uyU X=`uF{ a(`9f2(=7 }IENDB`C49_Folder_Blue_Open.pngWPNG  IHDRagAMA7tEXtSoftwareAdobe ImageReadyqe<IDATxbd```bp7@ @8P ];@$=4N/F{ |܃ ^ d {l/ ?00p@={6\^" -3'go6x1s:Fw> u 8yB(0n~@y3)ds@#mcX;T#k? Wm c+_ 4Ȁ?r?C6520ċ5Ѐ M@h_ 2 nql5.BBDv7퇁@ i7b6F |t @۫ Ă]@@ `bC 0!A} XPP xThbCIENDB`C50_Folder_Tar.pngaPNG  IHDRagAMA7tEXtSoftwareAdobe ImageReadyqe<IDATxbd```bpcC@15@@y' b(fbFdd8;ݷ%2+Tx- W8GA؀W_d`Xx P P_1  /?A4hz /b`db`bafxE87P ,bge{0 Ǡll! >=;pc*×iq >C~Aڝ }+a !.`@y4 ؀_ ~cF&F.>aPw` j|U6Wp؀7 SAH0Z^}|^a~4o0!  h`h@00]TD\؀O@XY@ -c`zh~\~#bw !aHFAT>mZ&>?L?p: J.pg//#*r }pl+v@}Kx@2bP2 t2set`}tއ?T d;0 6^A" B (]@ ml ._iIENDB`C51_Decrypted.pngPNG  IHDRagAMA7tEXtSoftwareAdobe ImageReadyqe<^IDATxb? 񝑛=@P^^I;;4ۗs9r 0QQХ6&_|3~^^,ii޿"ka ,`aiiY?â>pޝ}}+Xs988l@ %v[wlݻ.~ڝRXpLIQY]];ϟ? 3  az#4oJ><}5? b92|pOJZNUșNDx 0L,ٙ102q} qJ=@ ݮj`??S6aaca^Ơ]EIyn%lfH÷o | |ae` T!# 3J؀e7??1\r!ï Jxll0  ~20| =0F33y@緾30<h(01b0a`p#`! Xੁ+>\ 4MQ#N pِD @/@Ц_򚸁't:;#&HB QcX88!@o0!h;6 PfkBFTv' 6W8(JR.`6IENDB`C52_Encrypted.png~PNG  IHDRagAMA7tEXtSoftwareAdobe ImageReadyqe<IDATxb:a### [ZZ aǎ?ϟ~O˗ @2ի >|`afWA. ~fO.\[NNN30RH=%Ąl ++í;#/>Aw3\Vk0 ~p ?=aPUdx  =ack@, @Ƿo oex zNv37wO35-ga@e` _ kfbPg, ߿~#DFf~1o b0Π(};-O` Ƣ L8߀A  X@&߿ Ey.]ʠ@7+ 3  D+3 @7ÛXi@2m``򍉁@`/8F&dϭq T!8qQLA/0@A fffF399u$\q p7ߟ`R`e s}7TPF5ɹ篟 _͝(%%THY=C2#ׯ~@ⵊWșIENDB` C53_Apply.pngsPNG  IHDRagAMA7tEXtSoftwareAdobe ImageReadyqe<IDATxb?% qp @~-:,\Nf6Z:xձ՘0ڏr$@;A]YjW+?"WE11vЛ_(sJ  % 3㜟좥б<ñ26_S'UNMǘF\|y]3b`@L|ܟ} VONk`X4uj$Ck >g=bzvL 1@+kF.u10ϕWeWjAH;8CK ۶\)A0dqIJ e"* avW:J"3]A0!3W0<S6.*#Y  A/"[/'0$M  YHC/Y~Uaga'.S&W3x ;?>93\˯\1 %0bb> GW1~Y y' @jF(ef`bdCmyLo, #Hiv0P!3#IENDB`C54_Signature.pngPNG  IHDRagAMA7tEXtSoftwareAdobe ImageReadyqe<IDATxb?#c~8xSe&=8 @L\80;3?fVVOI^ H'@]-v]#QB~-Cw?={dg: p6{ӷ3_$*/{Q7$ >- ~Âofy-):&ff77~kb`@,&v~z]ˠ61p h/s3V@,0deE.Zy " ޔ3g @`߇g4/>Ѣ 14c8zFClP`g={F '7ál7vo(J5KX)3^0G2ay ĦX>8nC(a@p0LTW] ]kaXN A /Ow@ Lc .Аe rO`a N _ #0Ƙ@`M5C_03ϗ~0(:F r2NGBOMgx#Q |sjI3 WʪIENDB`C55_Thumbnail.pngPNG  IHDRagAMA7tEXtSoftwareAdobe ImageReadyqe<,IDATxb?Cee]m!FF >H3a @1 .|6m@h)EGG3<{ߟ@iFF @# a`bUPcXlH pp;s*S# 2 @̌ g'/>fb 89X~j i 7/ ^00~o&1|(~+ +_u!Nf&|`` ?@< B\  *xdx/F~1|dfde``d # @A//vV71# ?%lXgGX'@11@)ˇ k'0 ̙_b lhnIENDB`C56_KAddressBook.pngPNG  IHDRagAMA7tEXtSoftwareAdobe ImageReadyqe<LIDATxb?%  ~ɠ(3?~?QAVjG:1uf@ X@_@C20gd``'"K9ӫ/>?t  <4S~]M$5oBf9]2yKvivbBА:("L?xl#t42x|X #Ta( l T"gv1_TE3Q6 Oǐa###ݧ)|7?~ gˠ'!*@@E߿?~koh훫'z/_@'- ߯~A Rgcjo,G+H %  Ѡ}Aq"+_c ҦrOKs1 gdt~1>2 ث@ͻA^ w~o|)7Ms'8`1M {NOa81uE bfdg,lAڇeu5Xĸظ1z- gn`8=wow$݃>@DO7?OXߨGv@e^#rR'V? ^ӛ]+r#@!+ 0Js.dbg 1El@ -kIENDB`C57_View_Text.pngPNG  IHDRagAMA7tEXtSoftwareAdobe ImageReadyqe<IDATxbTUg20 4*ba(PD/?܏ l +7˻OӇ L 6DAX/׿ Z Z"`&E;/bH X021p2}v艳 Z fff _f8p ?: _?01pq`f ? L@c`bc (( E@_@aef/H/@ 3@-$$Ȁ \:?3#@:٣ bWP`Tgx=ŋ] !/uE EL  fp0} `W *+c V bb4 : ::`AJJ!**dy3(> L@޾zpc1qqyy9>0ܿPɊ]%4 XMafffxp!ÎM>|# E? &,(0BΏk~~w /L߾o{p X8y8gb-8B >VDf ?;8~3ˋ_m7`t )s?P`bd@1`IENDB` C58_KGPG.pngPNG  IHDRagAMA7tEXtSoftwareAdobe ImageReadyqe<IDATxbLdhtbe`?_?ElxFRsz021æߞ@1T1{MnR?ݟzrսEc77~>&8 %Y&ND$q3201:Y(E&}b`Ϡ)-ΖU᧯'  &Q1> ?7cqL OМ/ 6>@@ =:@hV?@C}}tC0߯ Jbl@EJ@ ^e4h~ " 4c_2o o\g|W@;A6',:̩ AaDD ej)&"{@ȴA#8ӓzh51QT)5u h K]7F`Xhs30q10 :+/K`#t@~.FH$%0`Ǜ/ "~1ۿ ^ Ӈ _`x R 01|*@LTO~g`eed!0Y<(~ý 3z7 ?= @,j@Wd`p4ca?Å7~|fPTexɧpOv ?>20<؂_^A֠,9+%0/ ΎQVLuo= (;0J\Pe4  wl<2IENDB`C59_Package_Development.pngPNG  IHDRagAMA7tEXtSoftwareAdobe ImageReadyqe<kIDATxbTWWgFFF2[RLLWUEMÇnߺ3n޸V,""fn66;J+mx}Tj`` 'Ol d@4GuuFf(sg=p__|]LLI߿;@z @[mm^`w> 7ñ#GW}=@ ( EEE91{;ÇO xn1~z!y޻5@_09))|yY 㕫.]緌VlmtUhy X@1'Z:<a?:Tt,}~wG  VV=w~3@Π?}}ʿg={z-&F$ 4Ub3P όZ?֚v2g@Uh/ ?+# ߾3E3>V1vQva&A2{7U;R S @lll DH317gos |gpg0ַT:~VνO&bc48ÿle`Ie Բf` @Ľ n\0| oc?#PǛ_|%xgr  f-6e.mfl"Vj J< ?c7 @/0mgav+ # _D? =&2I3Z10pr30?W?)6V̺g}?@LL?AQZ[E狟 _?× 1ff$#f5 ARP2   % #rA+  ? 70 :' $nɚo,fv4? o  2lMc`b(x @LN _ 7_x `/ 7 0Ҥy1ĉ>a`baB h+#+ VNw y3s00 ARM/mF1pbߟ|Y50y K.6Nq`6>pd"W`9 XvO.MtWfqQ0``2@<@\ d{(Ñ]{^DϿ |A| F&LߡmgcbX5䊿   I>Q M3fQ )-US5i{>8w xy @Lcÿ|`/n%YR_c}'n^/_2ص'wO|FN@w>w(3VW_vpr|bg`b̽^b\c&x0"7~@02 /Á20L @a7 6_cH <~kbՁbo@5Ï[ 0dTxrշ"b4xXKG 0#/(|a2 _eַ{30$%9P 00X[30KWGX{\/ ? N 34'P-7_?~c`Tb*(a#/3c`Rcb`b@rh*Tv5 4Ãg}n˕ R ƌ\  d&L @A !x?Ll0İH,KOs+($L @zjt+ô30CR&FEtRcb bn c`WecLN05cjNūIENDB` C62_Tux.png|PNG  IHDRabKGD1IDAT8ˍRMkQ=c&N&&F(ڢXB K@k[O!  +&BUTZXhd2uaRҘgss\7l{RJ4bk8h5BSSqpWBd7s%s=[ys7Ew4]x*RP(hFĭMa>!,g]58`5[e& `)+?&A0l/+/DDվޣ}v։(H͝6gJǡ\.G\gL$QZX,浶6!T1˲FEK`S``??1)LaBRԗy(NuJ)3#χv!׌`RJǢ,-= z7=^Ĉ9<(iWK0q~)ܖ-"!y6t=@4^T7v"jofq5mCێI ?;/:aIENDB`C63_Feather.pngMPNG  IHDRaIDAT8˕S?H[a=mAҢ  TLAR(ѩ Rg`w tsС[I(SD kiMҤ}yyץ 5qZ4dRuƨJd]=4qBWHwjT]6=`vH8Q|rbQo?`Y!01z^v߆a IKK Px+-k_n( 8H` WW66h4FHU]xPP<N3pz>ja7}>n8JLVV$4#|'%iNd7Ԏ@miMr3Bmq:1 e׻j5)?C:'`LtFZe2rlj R| <]ڒH%s&e2L\AZX.~Ri 4U4E~壼p8Դ u ԖQ^WZ/N}}IENDB` C64_Apple.png9PNG  IHDRaIDAT8mOHluǿw39T|qGK6䠴"@BE-ںi1 T22&D0 Ivy޹~Z ^Á|IR#333neYj# X\\|\,qH$044[/9S_T*hT{{{ N;?$ϯ[ P.pxnnf?}hiY5\yw}yyYnllDkkkBq[UB LBAq288F6Z>𝾰@677SSS0vTt]J)R Lӌ׊" ˽k8I$P(MP*i2 (bx[b{w!?AExN !/f_R s!(_wk۶u]x cB@uNuvy|C8`AJ TJR}_;;;{:66AE\c! ~@RJBxj(4MyqqXi0 590DTRhywyrrJ&=::ba.Sm? 3R+an?lZv tɣZyvIENDB` C65_W.pngPNG  IHDRabKGDNIDAT8˭1K\QoUHbh;T)ThaVIcB"]I' +-lQ$L3O./ xr{f<\UK`0?8A/"gcCG"-Cւ\%WBn3αf@GXG%?1w-J5\_00 c\o͋=3\`.0ijN_c&zЏ]cR,bSj*rAoQV )"?tk4mp=f^w!qdJ Ñ#-؋ov~dcQJtC6IENDB` C66_Money.png}PNG  IHDRaDIDAT8˕ӿJ\Q "(Z ]I*8Xؤ@H8`)X(B@Z Z䬬殻of(eh[7Mo%9NQ&0[vJb$_ĉ.0rgͬj5Q&nmZ8 -TxO*>/}^bYp-;S ) G vc 5\o̤ޫǙYA{9V4 As"%b3 *?`G髨P1,I<wzZTIG(r'eU,ZIENDB`C67_Certificate.pngPNG  IHDRaIDAT8ݒNTQP"/ DL5v`kg饳0K0ca q᜽P&~ei0 YI)cfFNLqR\ko K780%Fd$)U(eA:M bΉ%nN][hZ }"5 i4#G[{ DwTÊh!b8ʢQ4i6JRNԈ>gMbqw#~]DX|~('{BDY 3-`S׷~ȏp8&5f}&a 78u};55 !BY[I#~~ECV|P{ 5F&[39[`ü $2ɱO4Jf#&"$hY4X$DVKo;w*!U !e`dJ:W$2R2S"eIENDB`C68_Smartphone.pngPNG  IHDRabKGDIDAT8ˍnQ]{M1 Qy% A ~B׎?wb ɛ[^̙{t:=w? UPp8|yQ/U^6FEU(iNey*`}<{aT޽}Y>xc >Ɠ%FrdY_OS,ށ|%[b9 N "v%xs>`#"*z!p~:Rvw4JXU^\!A$šܽ -ZTn)"6M¢ ?NNpw w'^UZpIENDB`KeePass/Resources/Data/MostPopularPasswords.txt.gz0000664000000000000000000006176012164326166021330 0ustar rootrootbQMostPopularPasswords.txtDG@y/oP XIrv#ܪ? KW9]^ډ1,tO `d:Dz8?(5D Qp0!Xƿ˰'kYFIˮ} Oj90 )Z22 ⏵LkğhX#cΫ]~gB\=In$JY$X_;Vz$aqKMkw}~!b&H5 (9=NrrFew!QIq35Q (0@T" @ dP@uRP` e0@ƿQoH S# @ dP@-UΫM涝a@o)Яjh?|'8LxnWa<`[VVg4b>waszQb3''I.r-iֻw;y clH-D~y(YXd=f".#`AThI<26ۍWő ZJ|6wCd{iA[W孷 2cxwAß |y݂F@qprOX3◇xz3GQ-JQg2R jjNO"DdFANLh=ׯ'h)oAǸ zxzN;wAy>1=:1:zVi ,6'FZX1SpuL@FrX}Sb4iC˰aĨnO2RJy%KNO.=Eɖf|.R+g\^.獷ySB8!RIBbXɃ&-7OpB.#FdO]pvzQ2l~оŌ2x6B'+h1!H5-/v6 DaݫXXlYL⬾sG8B=!S xz9<~6Fr Ӹ\t>>;愐 ze )w7\G~7XO;=S#w%\ΒLT& y*E\Y \|`#->ڙpl|^5_kHE0FyL|w+2ȳrP|tΧ# JQqTy~Lo7ݫx玻 Dd@}M:KfB(,fDVҨE ÛVXyBE>:Ӯc옣Ĕ붊~"ĘBLОiQ%aC.INg\3 4 9R87 +0G9):oRRK9w,aQ21E_)vۃcd5ԶExS _44z[43쭜=z4yn[흲+X( ,̲yL9X s!gW)WC,~zzR免LJ/wE\-e'M["gk!kQk-+8) #綦Q@N$84fݩV*w+tS" R94#"!>&v`Tų#idnK-wtKsSBm:G$w:I<<'NښuLK[#HXUX4~)NdcC@Nk'~:ՙXJ ^SvWL?0jl멛[}4`NgPV^dgRcvmMg#^[!{ښ'wm5"XrଃoΦznTӇp#[).}R,[I 9R뤦)LL i E()ʋ/p^35 .ޮ9uλ〩1ݯAcbXS<Ķ8.-<""׎r>95{B|);r?p^ANImM Tg( BXE9dZ1nd۵:FyCdu̼5G>E'][+h=XKPv8DafrVa-8*"V?U9M58&KǨRqT&aRNA&u{Pk )Qpؽxȿ}~Ra+> yɕƨdWO\W׸e&^o -^mhrD G؇tsmDƍVd)oSV1uaY(Rm\w`*ҒfC,'Ff6x\2kOTRtjÔO> !l4c"QmiOIȸ*2($Le-\Cj(Z@wf4J&W#1X9K s!b;HM cAn*: 'JA+mlrk漺{h)#eB9G 0v ֌& }p3pPlT[gm@ظv3RXiqtdG~26,,0]\=7qE_mL )lN,ĆÕ[e36opfj'6بie}u:Q3 ÅGV\ =,\N{ ޤF6Ͳٯgs3N*.Qle/;?S2t0|18RBn[;zJiPe\@j-7 3 -ܚ$5R@M?|ʷan\;F5+,TԎ6NFb9TM eyK[tH]Dxp}^FJ@%}<B٪ N~Tũ̴>=.6eqd9Zv?h -&vL8 6dxK" n\Ff52Q)_4d/)F:ؔ\M8(sI>y7~'qO7wy–NvDzSnmDInG>돱tRIuT}ol\#5:nosLLu: TبNqx9Bm^:!GCU}zx?_>:PE SeY:X`D/OMӁDor§%yZ-;|חWο ?VFCe3C[q ݓ FiqoPhp5RL] ƭa,ĆQRQ2=Sĉ8^6 pGttO+R &)?@BIuBEp\@_!m =;SQjX7˞)hj~UG|H !?P)DFe0U7'jLuj&1RS: fIldL&v1^\Q 1"N"SK5PW]6 2r²򤚭_hp5RI_ħ<?+U R|E>w/{K=~;Jr#s7xu7"792)o> PSI0Na,Lm5JIФ6Y\ m6opqë ng;S!mTLy&zYFy\UʨԲme! #3ZR+!AM9:+m7 R˩ ]#9>9g ^%Rبv,K%sKc73ܮ*BO6;esT&&LU1^0"!i:MF%G&aZnY8g\ E7QX9;ո  BKRRI!k=& t_J4< Fj*5ob(h0F<9*p#ZʟT1R!->SjC: fOr8;66̒N*xGis4Pؐ6Qb46W{l<cӽ[S c"uR3Veи)gِjT OחFk"R ѓ (?nu=E柧%G#/P{k)7:$'U |/A |s>~??(}e1v1rr4\YBT'Hw-F=KD* e`CS Q"^u ^ŲfI:-'K:_N+^f)mGQ4>V`kH6Ow1z/UfyN<$ѳKCF&nQv {?zɵ~Vsȡ2.Z1sr r~:| .OOy9e'Os)QeFnLH>1*1[.{E'Ɔ,AI~>a^`-CQ JK* ׏<'f`FaXd˷Std>< q,Xg$䩦4{'<Ǖ|tjq1W3ǬS'/~E y2ӆKA9C"x!+%2ͭ[*nzUh|-ߞ_ei|(Iaq`/ 乁yn`yzNNP7yi '2, $,K@ ؤxZ'qoQXȩD%WBl櫬i 9Ғ]lO 4q - 5'X4-V/fT'P3ϰ܎vFɰ1\ůH-Ce1_,3N\QWYNX3Zܐ6Tﷷ¬NޑŹN{/cN x'O jXQPjD]N>?w͒e='+YB""cE0'C 1ϋ,%UBD aAjwUFbntQ+cV-,gC ̨Ku50HI 1aI 4R#͍W0xҲէmiV%g%uKRo0Z^Cz9Bmϕ &\t.TCeh j!p\F^A_埸YmiJ.[gݭy9ᖮ^R݃tq Ipyo_yY[/x| ߃ 1+F ;](p99ٱ/#'ιx` p!63rrּU(6 *!@*H ]Oq$E=`!m|`hLC|"I f9s\Փu=)\>z)+I2dj~sYYI4KNJ-T)(QҐ6X4R|GUabbW,/_ʘ8d99 rbQ#i `M_SCԜ?Yp^c}td .C=s,vDI@='b<\&`E+J8$'+VINR~%>vO/b|ÝS$UXsR DI[̹ SQv#.p-Αi"Ib"JJ&߄} ,DB.‹ }" K+GN+! RWhP:/&EՖҘO%˚7/QC#SA?o]k'G[9b(!Le:qjXwy2&P-#w)+4dn` GNJrb6ypC<´1ftcB J22\f\CwDѥrAde-,srxnK|q襱]699BRg#rBeQ''O w@2Y P~䔁- ќm` xȢn4n -d6 2E9$ |%n{$TFn#TE ) P 8E5 !\֭K>@妯9ެp/1$}K*KPźBKE̼GEn?$oGQf*1͉TK1rx.b^N,8{=£j1yk<}ᥞ)󩝜NLPN=O.t ^5wb1dzloKU$1v5OFPrHl=We|, ɣo+AL>113 X R" `Ӝ 9sJѱBB"seg-} OҒvEIS'aU/`7*[TѱfKD$<3UYeh$ q!mP ̗C9Ѳ1CA>h=tIA* %$pG@ \:GNs}w v2FNQZ.G+eI8WKD%zC~c %$,§z_@;$z~گ<7];ַRQP-%j%+>X[ k~MJN ي%;DX7D :e J.rHIҚQp;h%v5 /l.1FNc01k ˓ Ԑ!^\C֋ӀUlR2ث7 *ǫy~wM"ۜº`o$36b0N<;u2&&cPV/Qy,%67Cwy?YI4}֭ewƜ,ep#_kऋ%v;hv'KCV֤fЧ_jD9F fncٔ<@=''yMP_Y-(W1#Q{߰m 1O#f/G^vTy6Jy1$N(nʛNCm is&Z<=uuitDYkP &g;52q^DO1ϘC/憱pr'Ȧ@:mÉ$_fuL Oϼf liq!Sq%z6ԹBeb??wf)S'ϐpj>yS(@Y K! 6k%4?~1\p4_r4TM>3KS2-W<-5xy\d < FNj8kfiLlmu^>fZI7y4d o]pѺiळmnTIis"5(L. :*:(Psnoefeɯ!V Emcѕժ aM<\UIZde-*J ԃ`-RA[;$AU1.?99pc :xnڼ/M]~tv G'xţQ$Nw1/Zla֗}!eFǣhC)&7EJ Yps GF)rN-gNF VCa彂'6o99`nˮN99}/I)i;[N W|w`[+s Hr7/G.Mش &hKX? _+YPϋht`t K\e^u99k/-p RWfp=4w41VDeIo n%,AHCV _ZPT/ uAAe-YH% 97n|^r(#.R_!VA0 $d>zĕ1kX4 6<,AU),ă11<Ȣe0QR=$tUz Z|z&y5 vK:y=164YP%pYI3RPX$gSM<e͞i/Sw8rDxoW>Ǫ۞w&)T&*J{#*B(X2f>oDKƐ)?`4gn *K?kv9`9i}EK0u$T#!~ddSOTLI1],'y0K4&g*RX eϩhXQXHa*þdC2+,Fmt;nSSViY'O؟'r>7́ݳݯ*f?C0Vd["sT3fLKEtiih~s(҈^d.νO} }E_ۇY~ltCɜM]R4X0XoB'u%^ȗo;ң0^ m k44Z8uN,Åk,s"x"`j$)C j,ga,rRWqQ4 n6`b_Fj(m^4J ˉ̺`R k^S {h9{3Ύeua3)K+66"@G~%) E ʃ^K*ȉRYPV|0AY" ۜUo?Z4F򩅜YVͺL?'-)rEZXZ7/pH c!FT2r 0{|Qj`TPv O6cA-KK_pE g$lxBj(i/]+J*.ʈ h]gR +=}J}0V~?)pQҲhqpc܎vh#Y*cO<-t+^fȴ(KO)sOLJʓ2o .YإΩ~seI7 &{q;0wI9dA,Z2R!WmdY9#Uл8*ʸՓ`%ƟENWm/e)0O:r nQ}E12|䃥yOKს{F';~6bHKv9$)T4#gE}T“] J FNdQ t)yv1/ P|Fӓ߯2Ԣ[4Fu!~>3iҁǒJeĵb1`9]m Z.q)XN p1?<ܿ퐄(]bcϗ*n(%?<۱]xnMO/ ơ6hAu&emX=yUOlK?zG}ZWqÑռ|YmYB,xރ/'Q0]k8hoaQrzhnN%5.=(IG*2,kh DW˻M}UОjq񉎓x^[)s'YYJ7߾O:Ǣ. HY24VPKZdܻ`AmBnrt--NŤ(2m=-n4nֽ$AysX:MeF6,-EL(e y hL o4榺z KGj|Hɶ)Ո໎d"3y*2$~OP!4pr;XxvI岲YS6oH/)VKr-`LLɁek'I8?Mکr9](9<.ꡫ6gr1 Mz>ue4 TķɳLwY]#FN`FRq2r;2J ySJV4] h;LϚRKxjs>98vb/h|#<4߁] ~ޕ \QE mq~g`}b <#o*^JC,#$)Xj,g'tOE9LV9]RQvFNSf Hr (aS4[x4G $ۜoa$"ǺJ}rfNk@BI9攕u`nŠc5.ׇ)":gEhd)Is0 I)J PFsW1&ek"cm2?YjzZsLTP6! &وzeE{ΊcI$#uqo)L}ǺJϾn~Y $ jTaodhs2 ckVjLtHJv3umU>4~%ʮtY2JS i^?k&q|8 H |_=oR+CZ(&<"-Pډ )1b۞|*REPVvgFr%䑼Y=rO/x}ӏ )S̨6R&-rr&Ӈ$I9>Sq"9&`E]ΰo@%`[*31 ׃GN=fPa;\y;...srN, n!?Eyyl`hs' <`쵉5m0 &)E}*Pmq߁=)XNMˣ}P,Xdǝĝv;VXځ14q^'~ R>1S0K9/I.%ZŭeIx(]}rW44 3¯\ei9te &mqLPIKcw(+V_tM(I`vԩ6`pO0lS=ۂ"w L&QENS-'Oi |ʪg1IAnJS'XxvaQN+iSpg]J##V瞠yr:xbK㌜?K]ԢQ 8G{g2zARgDO3[bݣo<>qKR~|=eVKBi GeŶ([* Sޅ~0u h]f餾$%u%/P| 5--dн' h^tkDki0I.֜Ϥs7dmNZإL,xj4 ,gʸC\ ,m2ItC<]sQ W8EV~ͨ ^e~EZ*,ڌ#K7]f4IM2,@Ys%/ij=Jy /ΓkoYa'-<ȕec& `F?br|Ѥ IlAȰ(ȉ`-K>"aQNQ`R#ׯg5a~q-$)[mE'Ie` җ $FcAdMH^LC(O$|27Yd?8bڤ'׿Pjɪ45Tص ˏQn|~Mu}ܓܱ^E-IFR^5`gh 1*%IDMO-4>/o@sGJA }h(BpBbS.MwP{_Qڗߣ,7%oJ/vK+˯UXɲ,˼II% sa*R4]hXv)t(yKoIC'mH4KIz9"rbUSr)*06 OܒEf+?idհ6zi.jQ٤tʢHe(iIRPrh, ]>i-v:99"hZ٘ǒ)ry͗U>"W1^pJAy0LSF]e VOkt%ц9y(cI k3YJKEN^Sv<cMri,/":UƉTƻO+0>vj(Evɜ5($;h9P?F1 HbR匜@FPX9t-~ˀ$Rn9k/s\\M<͑6(ʲ3V@Vs֗$g]pQGz` g,uEZ}?#'P'[1Wt79V3r a٥D1jfLTkA[U`ڵ]NW1.kPrbYZ'l*9J5e9#'I@a`TOuv)Զi#'/cڀ2J4ZSxKkA>7= ZX tD YeUkb66sF0 }5נT zkKYy(]$)h'4ҜoixZ]}vK?~S΢^b |ן~G|OΚZv~,zڊzV4SfP<|jâ>8Y0:1wGQ1sʊ<%f%J,n+Iѫc4ʆgp^%M2~eY`xe S$Xr=~ N)32ӿ>]U(ʿ럿~EEÑqkb2?E|a:.WF`8Z2d翽Ճ{=QmdP=d鉼=ܣs OS"TXy/tnI]8ӝR@Q3X>Xj됣8xkNb=Nc%XcVQ?s`YLYY`rUz.-J}(RPDbt@N2'~,VBx͒ʼ4#]=r t-K-HցS y43)L&;_K9/\/ &|*ǭ.3*Y-#gTn/wY:EvqQKf`?>prdo K%/9I7g"z{珂-4`/tf^>9f@Iwi8G\>R07gL#}Wb?)[Is)?^Q=Aod}SniN_⤗:ws3MFUu+8<|zQ3qR8p$~OlUhf걟k]\Rw5ƄtU^fꎂ~T,q!w)utOfn6h9߬I3إy*/j'j4'dhkk fp.O-ƒ:)E'hyMs7IW're`.Ƹ*dDYu0 ͝7i M@Z@X#HFY_.ߞ\i[MvEN9%l:IX ÜNuذ >:CS~66ce9WLK}{8?_<|-Q*-WYtO3-<m`.TK#'9+FRdad5c720Ų.y$|ZWƑtCI#9Z)xŞ-1ݭϬΓz dv׹_r 9z!"}j6 ohSpK9 >DAtQ3Koʑ,|efw3r˓(]Rճ>Sa٤\]FRYia9(s;~[KCqo}%er3 s v)Q|G߿U D[ nv!][KC;Keσ'CSYy9]E`Mete{5%Ղ^TLJ)伏~.cgܴACʜYkl}$JZqB[Dw Ym77J>ȉC}WO*OIf=j,4F%1E#I '2/V£<,II}s@e2?M;rFNN{0z>YNdap7gS05&\Gy*t6c9V^LR Jªc;v.O|ѩ.t0(.a\ע hΤEN`wi S\.59Ճ#ʑ(XrBٓءIK%-Zޥe=), $ߚ4?":؅xL쇁2`55HmbvO]~o<ݜOl/?|&XT+jFR!jYaκOFr9]ż) :`cw $5zFNRW/m9<1$IF$#(?vpEKb<= 6ZO__?v;ͩţɞ9>ǟ{vL/)x@wѾ+s?駹guW?ƊlY~??> &|C̩0?~_a[u39ICx(CS*F@$>r[@c`ygy#򏿇`xkx\wϨ~??t_<9ihY9|M470+J*+8 Y2{ઈ">9* %c=Jarʯ6Jw):Pgp>GNARwE-k5r7"ĊM)L X$gZqAXvrFN`ehLCwL358£|Pf!ϣ%Q~1.] 0#{|jsνƥPYh*+=46`87gXrX j,9[6ZmԆ[$k(7iZ9YX@%펢{/I'*˥T`QߑjJcKHX`6ų륱Ժz~>՜zYu%"XӼe ʢ2wq0TY6%W)28r9UN蒝j렧 C^A͇,S!uQ:.m逓G+ΧJ&eURKO^ןgww>%)R#()8M=#=UCUEy >gAD4b~o y,799(+c|h~8%h$+iG[)Ax?~*\-JYYQʻhc>KNos`ʰ 9[K4ԂR=R-J- 9rkE\(R8دɍ.d( 4)NtXkv3Ym9K}h]%ӔLrJAF*# ih 945 g('s*@<@IjΤ;ĚEIr~SAC 9 79ɼ,Z@YKu5ݛXO. \44x4 Ż;OLĩr׌:wR$Ry8OHנKCYH_i"1SP&<;ޛ]gݴHW*G9I zЧƁ>4됇3ǧRJ|Z[$ZK['8$E9 3bba-@Eԓe,KRh-J cJ]/&,5.?F1xȕ !# =ub0P95rGIBʠˉ'P9S`Ij!H%R.U"%P߲;*MI\RgRWLtH=C Nҵ]XMۂ"%N3no] m)8 V̰I 4/ 3,H%D' `{~Obj CGqGjOS[ʊz :cց ^ mDŽXZڟ<@}#1K 8S<=VOZˢG7Z "]w"9['svZO䧶4%FN`ks)@ϬZ-(қ,`Β`gm,dzL]mtEGr`nWk[niCAsiǑD$a[~ޙ+d|0bݗ8'h"v0pumdQDP ۹9gxl01paIRN*`R.JCbes2ȶ gȴivtXP 6*$)43֏<,`$On?wU"|]2/䰔bXJ6Kf)`gu{_c~FI[ǖrcM᧋'c 3ƨ&Tvd9?Qb4KgѺ``=Qٕ蠤|RA' l|o5obbT bs[r(wdCF 6tFGNbF1;}=UJWwaE T%N͸b|2xK(U=SmIs,sиNwU>#P, ʽ1|rmZb*(!YP2c -,7sZ4)`K^ "xdY/%avd=)3>~1AtZp!O/%?32v%͖ZJIV_>eVq=Or e 'vn3.f8GxQ.A8KKwj'fNwYY)x鮲"sGxnIҡ+!0\*Z;ŨF)h=p#~>DеԤe5O! "[Z^l$K)fYXF퀗#RFf&G}XNpΈYvP-̳:IRW ~#mG 3VM*!R7-2S B8x[2Đ&Ɛ9`12[uXf~X-}D07vNTS|V+ԕeFpl{Zr g3E6Xe%a2rg=M҆-eP.+ݧAQ2K2 p_YIa6) aLE-w!-p1<ra GH(p rR޸<7CZ%PW(I:mb&2!J5ͲK1CZP0VƜ6͋\WPf{Wfk>9IWCj Q[`V:J~TOg-Ϻ(MVKSm0 hNqYvGk1@d,q05MVx HEGw-8tK1Kt`cHhŃ>))s`Vx#'tuM嬜n_ ( E?_=h9^pu'0 Jx1DPn eDE4I_~~Ff)E_AgyQg-2j"",Q)[ϚQfIS`X*e0 [:9LQCI ڠ~,#\sq/D+r?&/{gἶ2JFrr>XV߈px]O-ﹲ iN2"PV̌b4$SvmaL|2 i¤s功IJ! R~ Ӵ$K)&6dNߩc.Jh s!q %ԁS-(hq/ya̖!R >lod?w#ǣQn>ۘdNͲٮS0VZɣKr0 R`]-=i>ɹ+|^A˧A1"[N^ӡk'ϓ 5(5'K)GoF~0BKw%M|/r2/˚ 1?zuN_wLR2ςW4B՘:C$ v?xVMEJ9=M0]ec~’a_r&L|_BX8}y܊oN[ґ-?JWgɖΐ ->RkCQ/"jFvPRR9 4rHtҪP_EP#:/+$(E4{ʺ,s)dVErFeve,`fB,yvYYc}9 Ł6|EPJ' N/U8$ҁ#kN Xb"{ƴE }l"VݡCiR⸫"Q*sށ,g+Cۗyx极;$!O冂ҧJwfx|apgZ̐D cŰ'-O,\6n!\k` *3GXl )$8[V#pzlkWOlSmiRe%OY9)Pw(M iO_f#?\~kzt-ݷqW}}z}^>ԯ=D|b,Ȭ}۾^/DT 3-{IKt@z5Xwc3^G9v?Q޺"_O3$uN߁+-+iAl"7o,;zů %k^C  4)G鸺~O_==mxY+z8%*8dOaZ,(='=3&|u{>i{GSs1%t_zG뤥wHgvjm?2|e ;<ZJtƶ׷׻w}l{sxj/}_~5qLҡ臂_"oHgr*UzWB#KeePass/Resources/Data/Images_Client_HighRes.bin0000664000000000000000000100221313224757312020547 0ustar rootrootO|,VC00_Password.png% PNG  IHDR00WgAMA7tEXtSoftwareAdobe ImageReadyqe< IDATxb?P0@ yА@ sfB%A1 Y(:(\8g<; j_KIfv}m1 )8zN3@D@&GAH:٠bcx[aͳ{?~RKKW^f;U}o\6)LJ'MeE$}d`f{XH9Fߙ?w}7@gq_^) . 4KX13Br <<0Jqc;QA -x c'WyWL̆@@: >: C &Wow;=DB"@p`5#d u0倥! t<3LlW/!No1|E/mdլO?N!J:Ϡ-+=2")\-uaoM?B{Pmt`!t)QА LGIWtwogaA  G.[+|?? ߆&?@D{CE/ o L\i*`yF$*I緁f~ngc8׷o ?1 ^p/Pr9u 8P7Ic<@X3q3  tg`cV X*2k}g`=t@K.w?W} ~PL5@,X 03@,zx`[I xa`.L/2|p×5hzu:@;Tu42 231l{s< ؉~ xF^` ,_Koik7_'86 hEj&~ftRlf a̓@Jб~>#ûW o_1<~/P b@B?002AzunB*r9ee _02lZ(p)}yχ{?=hq&`)~̬BV(Yn_aX{Ѧ[ώ1y =o:`% +` |RU5 `rZ/P==@(`//^nyhU n<&6@2\@(E9f ӷa_H >5=h;Bn]+_r>t^}:(^Ӻ$zSbmh6R/@:vBRR^=@C} @ JXIENDB`C01_Package_Network.pngPNG  IHDR00WgAMA7tEXtSoftwareAdobe ImageReadyqe<oIDATxb?P0@"0O2h303222qM*W ~c`se1](#, >U_cDx4eEYe$y%8XË_^'g{˿_mf`|#@~|J<pu1d(PvUaeP`>Aa5_10ŔY@[?#D9X83Hc{t1 3~ t40|(Fgzn/ycbxr!Âytz>FTa0uspOwRcdĠ#?`vpra:0F&/??3|:j>#/ $3Pߑ' 200k7-ax> .O~0vzsps,ͭ%AKß?`& F`j9X_}(W7 ٘?xp(:ÄM On^16O *ÌmQF7O B3( 2| v`fa6N^>2H,e`'O//"?3axf'g2<&u { J 4crdçW+L$_47&&n9!^a ~%gYr \ 쬜`?'w  fseJ`3L-2v^eafpt'Q`}W`fddT`fZ).6~` J2q3/?~?Q߁ILCe&7Ȇ߻2uP-TN}.",WMV2 gggZ ₦ | jp}pm_&@o?8dsׯ <" F KwU0:22Hd(T{GspxOIATĔK?#;A_=d?8%)0yq8ќ :<+`S/`_? ~1ڋ  ܆ <@a 4t(y0;ADa ރ L> _|(Tgx>ß_>|piۏcARTARD۷o o=!q_`7аv2L^~rg B̐,jv\|0?dxW^iŧ> Ïo/<+>1c>.-~yptז3J1d0K{PDSqe6ϟ^' y}3/MVw-no_]k"cHUcd`eF<01dacd3I k t0qUX _(ςc؇Va?phFדg>zlxG?(Z×O,ldU<<ɠi + @(s c z6`(J ]] '1hf1psK3(ě T jV0RGBޜ Ll=C<  ?<l[^f; *z ʦ@s"4 51q e`f*F`!~po9CZ?9!1q 3®AAc??2ܺ3Z3H vP^"xw->a``1kjơ 8IKIF`Wa`?J1 + +}'718[3&i~n^Q `+` Џ_|wP:/00@ܿ&J^)XdH 0dbD;\ j! j\afDy@CL<: ~C@U_B/~d0tV`R2py LbNJ* u| p6 a&}( %nà*np]{g1t V~3"ǫ/ay'   , N@, h&Ab4% ,%-yDx%"JBPXڱ3 v2/3ý~: bWϥy%p^(Ơl;CPXs2+I\(Y M$3ؙ}VFTyt * 9-?>1(0|p+`3X W.| `c /aiTΠ%k *'+$4+<Ab0>Ŋ 9O`,*``un~ l']gekĄ< Nw <:ܡ۵V#``b';~>('<ـ2 z)C@ I{=`_Ǡ#kV#̠g0PcQ=çX6lgx֡Yp+ G67 g8t6) rzqA,C+vAR2 Fr*0ee3<|JlOq,?;+ vxl\M6'ހl >10g?jB_ 6Ȩ3pn( eͅ&A0 N6* 'P}"P l1,\qG0zNPD Ą94g㧷wv/z!ɼAÅ 6(fb6$ Û5ہlS<̡OJyꤥ N NwؘG`z?`-S6X< ١4;tCJ')5K_j29 ë-BhE B,6IVW(E P i >3+8Ld}X3ɯ@;ƶ /xz^`4 pd7 LS:>_ח\S~_|/a(/֟A(TT 2p9 #c''&}jF 6 7ٶ2l{ X0p2q3hcf|f'~C3g~3# }k)D5IENDB`C02_MessageBox_Warning.png PNG  IHDR00WgAMA7tEXtSoftwareAdobe ImageReadyqe< MIDATxb?P0@ yА@i.+c`0vfڀԲ wFt|3++ûՁiŃ;5- Z$![`hh28Μ8g:OAF DmĠnmʠ DsR@@)B2eua`{e-uw'$g1\+à30|z`gP `Wa A j@Qid ̪~oXD<XhV jy@ D%CC:o@'ܩZh04!Io${A @0Q N Tf:$ o |pR ɠan3'B)i-,,L: ̒r _B /_bb xXlyAʈR>Rdq:pPHgn`Ą᧦&J 3[+C2%I (IB[Π)yWQ @76 (我$⁡o }^]CpQ Ĭ<<  X9M %,Az ȍA5 H;8yf`PSc`cb?Y+"--X`k((1J*D Dn 4 QVreT: tC[au fff --- L@1zx쐤;Z L@2DT&I2(30v 8dQNar :::>|(*`l l#}7%A!5UEP,8Mr%Drzf`&0AE\'0$..fXΎYd0QRd`VATD{ Hk`%j1H_!<) 6XI($$$98 P,xz20|u2Ơ^)y Hn]L~ L<&4ĎXJJ J0 ,?}a0d @Q@í,RsAW***p ZÛ 1^C `?#6 Q>Ъ|>~`[<&b:FtiYYY,-(`ݡ#2rq3H+7`J:R)Wwf`yZQ ,6#'(P&PU`Ma&sX2(2 @/N4[>.n^Ïo`LR EGk3\ѳ b\ *bX I8HX10>c,@{ l06PD9"F#^q12/`z $3+Pb y% Rr ?kL^΋w?`QAbP Op kf Y;$d= ,PAŪ|@0HXY5 2 r@yn6r`1 `/%%VVVq$``We1yACTT6ŕ OjaY~ݼ,‚OwS߾0:=nF0BkapC̒ b{`A1KAk\ Zv d,3 NF0G 9 Aʊ Fv4r /x؁;$^<ʠ%$ Р>(<@PPkb%H1eol 8XP RTKFY`>#P䈗h\@ ҟe 8@vL|;90/ hc4Px6`Ұ2fy4ß4 }A`w ,k_b`68@gE0h1\?a dh1pM`0A Y!9?J ˰4`Q͈ 9g2.O VfgHd[~zAo |h7_$?466Z=5Pf@'` 3o_y}AXJb9g3"M|Yfâ^_ @șx0޽EC TLGK҃f$_Ȝ ơV L=@ yА@d"?VIENDB`C03_Server.png PNG  IHDR00WgAMA7tEXtSoftwareAdobe ImageReadyqe< AIDATxb?PBFFFzyy3#ǏN"0.ŋ؀ FRcXCKK+"22k ?ax/^_~bbbׯN~@4񀓓?;;doo/0nnnp2333X7o0\~ /^bx/^ڻw{Ј7@q@P3=WMM7))ASSϟ? ߾}y, R rr`8p4y3=("NXYYCBBexyyMˌ`"p؟?|po2 ( ė@P.Z^o̠ 0&&`~xp3`+yX"8::K. A?Ó  +'O^=_$eJb!3eܧ͠ _ _~pDafftKw>C!f0K< =2]7!ǖIo~ax%8ɀU  r<@${߿ i..@}`+tFǃBXyʷ _˳ACJ%` 0H1 r1pqħO_߿@F+`5P6ᐐ0qRjy 2 YXHPP3{x)r$ѐ"#ZƢ?Z!0:ޙq<3<@r06 HH~ضE$(mCq<# #40y͛ VaaPQePVXPAv0"3@D,P@?1 1xzZ2`ZLL))ahffcH33- YT@LdbP>ԩPQdW:9I 0HR$!A!s<,FDf a(= 1`+6.pq jA <"BIDV1 Ǐ_'iM&xyB"#sr3`  JJ \jaaXRB$}@d@۷m*x `! +mc\Y P 8778ɉ3/4!s$$$!=@d%!ぽ'` J*AbI`GSDV.AabD13CJB(X%k AZ@UBb?<)12ؐ3#L%2F 0<ꌃ /!5I3"yu'ɰg~`/x$E9w9022pBHRd-)3<'4TG"ߜ:ux5,70|AOa=29.kD贖gÛ/V̠K ?g8xùs'ߜ={ׯCC =?@ s)9 ֔5f4Qe`m{? ߁/_^ Է  rJ@|={t];/{C %%duDY={b*נ|Z܇T r<'9 X\ xA;Annv >|_Cr<1 G@%("",jXF?@LT4 A$dJ3(j0%?OS 5=_pÜv/ ̿2vɥPllϟYQ'1 ?ZxOOpd4O>,<-0:5%WL-RY[;M @$aazd=̮*P#i-jETr[nB[q@QQ18N@ce78<+$tYm$ jjL&q ?coea3g=@X8ݺ:qy8g ,-_*x ?ex+Ç[:g"'P*1 =7ׯc6N{du֗ _Y!@0{;W0>Fx.jd|áCۘ0o`sYu&sM`9)P% /˺/XG~Z]ɥ޻w^ LRcb]RE-x__q]:='`aP;i]q@ӘR@̋#A*qEeEo.?ͼρJ{ oZ+IENDB`C04_Klipper.png PNG  IHDR00W wIDAThy\}?9sAB$('LHI '8IAA  $ ;@(*s HH+-SsfwVjHQW~fݿr_S^nȑ# FVI &on?φ ֢= p < a: :KUd'I)\AR\YIuH!I+\),9М|_c=vb ,H?ޖJ}n</BD*c$L =L ]p]LHAz.ȄđsFR 4=7oϖy&;/$v}Ygv 8:ENvO8vO8=`OL~=׬6t?\ uV8LKAOnfשgk;9AgdxEN KlCn= j*Va}Xv1 4ܤj9P>ߏͅ| @kzP&R MC PhN7|ف:w4L"j@R[?8?\LtgtJLkm7s6,h'VJ!0Eo=_۟!㛟E_y!82242z<,L$TJtn8N~qՄZI j{fO|F .{}j\`0 nʃv~pB52!:p\ g-Ҩ90NͧL1׭%GD2 vq;?AA8d&~(`IT6*5)>&}2g ӳW AžeL#/p*bFŤvCf .^|rlkas+P[+dB+ԲV(*DAJk0cR uTާ9AHPF=0..v.u\/=t]].²0Y @h-a.#82۰%6&LU74C;rG8⥙f\+o$"?dft$SBa\5&Jm(u?hx DziMV|ɘ1X1̇}&xWwf[$롅Hu ʦe4Pr6y+i탎BO<oqEM8ZR`ht [ڨg#V@Ád>B(d&%V99eS?ӵI .XdBy{TSi0W6ʸX=R  l♗RqS77^& :;%@R#Q#"q0t& *k6 RF6 ·k/O:ݰ=?-]}PReqJ\K fc 0MM&8h[y[؃e7|jN8kK$t--HBFOY*X\@%lP#4R>kt',-ɷaOZVl;7؋.?,4l%O `\#QT#sbcIa&Ko0zҵGW] rz\7#ϻPoXYjr @cɌVA'ʸW㕑?Qr Qk,[><%(c }0~ϰ=/L-‘B$XYW5M-l.ʶfU:Z9{z:vɟ8.J[/e6lZ "לG-۾GTVtu0}JLFfT` mnO¡#bu$W՝2h\15b~)O0pUMCN9D_ɳ ?џ/9Еw|A{@1s4?x2$9'$/322󏟿~NP_̍%Vsr02000Fl $ 7˰o_U1|ۼ%@R.W7Q74ge`ced+7/n]O{ {9h-l9^}gdxaqn^v`^ff``fx@qg` d+23h2^b@(*[,'YYϔhw1΂*nbz_dMVMLRgVvc``y) H c@z'PLIGኸܷW @Z9;$5%گ$@WrYU%DŅ96s5Cʛ߻K%qs31D:L$ a1CQ!^F` D?~~2wH-t(Tf.pt? v@GcYǧ6>^`#0?_ MK ̬, F66 6J_}ZO9  `b ešId`xá&!"⢮*: L3# ߟ9P@=Cbc01{iK33eBV&$O av$B| Oe5ۋ͗ȷ@@LB?~PWez7бLb_@{dJ@b2w\k}h3ςR+TpS3Rej&H G~0^wo0Yz#0i opI$<JR@?@Gb J>.&!H3g0)=~? | ';0YYXYX RV^@{/3w~z?w^} hBgłN绕ʇw_5ucXc`e`caF#s)L ?cxןIM:@o٣n~OX ;W93333FpfgV1ex%k~<4e>j"`qf(H3Sadd8}*on}U3W!I`?{~3h0_yaWwΞfX 4k+gpp1% y9y' ,ex5Ë~g+A@߽cx.qy|r# @C<@@C Gv0J:2 iiyV>pmw ,d11wRgE`^|6cK=jz g`Xi+1,:;A_ABב܁ 'mbPx8iF` _󅐫:10àի a R^}1[ !<@b62Ѳ4s.77م#?:ΠK׎itf`` wk2|6^3bs! ֫+ b kgx^m@S#Cj)32$GU]'`,ao * bYY 2TA÷< Q j ߀_1T3JF129:W ]@rEΈ_7{j`CĴ~W__{s ׮ f9sP~B@+E3/O| - k?1|AQH؟ee6'.z132q  "< e#G>~?1\~}AR_A4Bi,+ʙJ 2xseqLؿ _+# 92-%~: =T/+(2pXSAd}[@!2 RT>ֲ`63? m.P&X;t>w`b0Pf"T1!D X8,eD|,LF @O<`O0ˑP: j=¿y )z  @=Y `fc`x9 Lc6`a: L(c9@lN=y/ 7,1q0 p`ae#A@03ǀ009xpa&pA?5$ KiI@p;1>.` L>!?$fF!yZ(0_pCb`?@;y)Jb  K2MVa>ЇH 1?$(/{fr<'G`Byn g`r80j&DP``pk﯀?BdOPðΕo=>1p- ylHR0B?Z @?A"btw ~1 }[#eܸ`:X MBP0PFHkÓ(2@:NJ 0qf{Ý?1| LI ~l+[2?+8 q<R)Fc(+JA1= 4(_ `{ ߮ݧޡ`P-fWcsffֶ@g;4.|%!pL La?2|z w{ jć@v tr8 '` <+3VGz7>} F u)YOJ \ \< , lB ,\L,l@=L?w_Ar}}h\6 @3BkHG$ajN. t S60_tHtP;dlr@UyZs"9 I|v8d_wl hFNIENDB` C06_KCMDF.png PNG  IHDR00WgAMA7tEXtSoftwareAdobe ImageReadyqe< IDATxb?P8=@C4=@C4=@CFFF'30d`~0aP35٘N%7_x(.D t2'yn ׁJ~<J>W29fg>.*y @/C!';{+.H!÷7o8ҥg00,*BdpK˄ x_30}F}6'n<淲u8 ^C]ii'QII_~b`k ۏ}۷5kOZM2:Y<Z^p}8x@ .r0dó_u9g| c`fcfn7S5g`gg8oL _fw Áw/?b`hWt o{)2o)%H}P7$=bbuGV\߲Chl=@4ADT>4AVS7? >y,,`.^dy?~ P0q `7I,k ? 9X E n0^:.hvBFFstmḿI d`F| 7?pѣwKeηhwsJ}Ħ p89s ?N7`ٜ0ULV F @ (:g$dQ0b8߾dFO~r|b`dXN0r0X^+Ă(g l30\ ܐht313۷;g-8ٟ@P HAhd>34I%`$3BR-18t(E,STU!1f?`΁&>" |EsIcMfb9$'&hx PO@ 85 IAu`G0|&.| %,ٿn{;C )"?!{ Q DKPb9#H {X0P9/.p#H!XA 31M'Hbh1C1(ԯCt&4Gz0@,X2| -%ρ@B π ՟i,FhFȞ^c` b8*D \ hJ >Lp$ ?AeH1t$3+nݻ ", ((LL zͧ {ogK nE231f[s>2\-hǨk@jzǀ1%ъm&&H-ة l 3\}ao _^ [y-ù?} W @,DT[ۻV>~<@66SA!/O0lԐ1|;?3hK51'"ȱ,>We= oq0P[m?%cIp HD6߀U?P?/qte*(nF~#i'AD On~s4L F%1}rS`l۟3Ch4L @$"6a&m5\Z,ff2:"Ο?+,ckE؟H/Vhms~2C/[?_-U@lUp/Jh π& v1HJ2"LFl < ( !p52*H ß?VH:74v@jc; bDt̼_+KyQzSU=dQOood`84-@1A|uo֯dbbcsF. adpMgRd`Xdý8!E%(A! r0  r<(A|#×/"?i g ʽ Ҭ /jX͐WڄỸ;O C.zYz`c`''" <@0i!`pu1NB=Kb0_@7>߁z=Ȱ9!\kCXvg6j~ }bW[ȔApMz߿h 7g_D8\ꀢ06I)NWa׺} <`↔L?,ۀb'0|z{;1``y8!uVz&`P%~?f2(p1+001( ,߿l<}Ǩ$һ | _0eyKpLp=7f6FW  2 J |gxp,g`bNO0|K*z B Rss!],b X2~; %Á< {'Fck _[A "_^AAPQ#`Q ?4/'(?8l@k0|;wWd8s  sf8`+Ys%H ^cppLJZ-@ g@!{>l;̺,5؁0(778?ppq037niPӄAZFC yn>o_3+\66`҈d/PShX'İùoIĽUPĿ>rw~bó *r@98x}x (" NF?! =lXa5HCXb`acez ۳D1a0HZ$  ?`p`*?îiq b8J2@|?ߤ=z &.p820v7?/çW>Lk `2zr.&}ܐct V L:rX/&XFW7Dִc8q >8 1oZ !}~3\}X1A,3pi ,DANn)pb`x>æJ'* 2g3+\K`|q `8AaotEkP9 @֘O[&>4po ï?"A3\@{JP;=$ )a w30˧F Qߟ_H+ ;ֽy參e@W X0KǏ~ ?}`Ql X`..- LO€p`7l!Nag?dX<Ñ+_cP)s' @a;OO?0` +*Ao/_^>z,b0<{xATRAXr1\sئ +!ki‘aV~-+>0%1`ȩXb`?X|A3M+w-[Hsf)*/`@˰prJ)= )L@1a?}B??^\.%/ bMa0 af55&N! H04Lk0m "`]7Y9~~~`BDׯ?+ecYat`{`g"2|!)efw3\xNg2<859{AA!!e^ie'OXE9(>‘בOY^ .-Gi >X k;tA Bb2 & y NJJ r2 0923P /H|_ >Ă[?ؾ=yKIE o1p-PE ?֭W Z 2 ΠlI3p p_A`R7 AR*Ӳe@0@s?y pzׯ%wY ?yϚÚЧ޻`i -%nrC_ 1K-`y/"" t<+dh NAXDNÇ3b@a.b<@xb7Ж=+(+$B:B3*_=#u ؼ%` juSG1ddE44=ܣ'^P2 4@<<+3+1<XbatAcr1@;X1r?#bp6 58z`P)2 &>xw>O ǀOn08Y Xi_AؿAr@(D_[أ ?JB/~\{-\~fxl>W@Ml&Ȩ4g4A.!Fw`k:1A ;Wl< NL~ @X@Ͷr^z2 /^fP&I8$xXY x8z Aolû YxClE$"Xx4$Z% f0YI11 s2s=389 RO_=ۏ_`/2W np=mku]s+=TK Sb‘<"=5}N&A>Nyq~a^`bqP:*?|pG \ ߾c;3yw;/;#_-'22{10hf#1>}G3=w7q!./$ T||o*;  * b\ |cx3"yϟf8}C;Hfv ">A@I”?BOԥ bl  7 2`XE:y;Õ^.Ne`x  P-|S0 L I ~ -jf;{)þ3w-yLM7M޼0UBFcUѷo_2||+Xt 02<4Xًr& Wn mp, mPf1\ ogd8+Dp^0lldNP8Ot`lR(K tUp{ `Ж$TF/_/&0b刔B;!nrO2%QNc9rƐRDQqAʴpHS69nG!GxtFQP&Foff]1!NFnaO73l_4ANUAY]AJZXH?'4M]]v6pUXĿЪ:(AP .&VO1H(i0|zգ;me=GE12_u@xMIXa ˗o߿p~eM]cKKii`g ŧ&C SâEˁ'0X X|U?`)=^AavnEmcKw1{1|g`-CB+og3q JPƅ odM`@=~[j yE ߿}gbcÜs xh2_^?{ (. ;Wxg naXgLN@uXEmZddB/FA闙`x&L` !)n(+SN>>.~>pK*aQ Oc?P?E?$`~`P5g01V,s=5;p0xq1.?V#Έ-~zo-~o000c`vCba| 9~~`0A+^`1p1c ``ˠ1Cғ^_`IGpXzT/hg .#, L'#6_`e0tf`:@I - # ) vQ ++`?f?­ i >/\|a{ƜqH)'` ~֧tq5wq5:mi%AP/Hfoh30~~fp=9!A&$X^b|AX:y3T3h ( e̅ OuQ(a>k3|YdЛy \$gt_`k?rGC_1HC3þ ?3#οgߢMmLY Bُw]x woEM91ނ 0?>@B  dB%6օ GV28A6`C~s ,/?on.dPAU#U_].arG7mt%i/@5 ~#׍F* |WZ $[~(0P- lngІ ߽+[^2[>vY}pm17} jR V 60|61[ocX31M kkN_zAINAUQAHP@X;dI:\d9a~v;䓛 O=x)>gvj?q3 k ^azF/%N>0M#w @77, &1}m4 @aV½g1hVoN7;āɊA0Al<lN|b`t ?&wXMgexUAh'lV2ep|`W}Ty'^@aRbxfFvy K' u<m>P֤'={{# 2| @K9`nj+c#g~ffk.{hA   @LX{O>l䕗) 1k;JPˆ}Ab ?c`ؼ! p6jbb(' t< xG'Hcf82awh P@a_ g[Wvj MXE&' bX7AIiC$  3@LAs`0)s#Ёq  /|?f`ǰ73۱ -LPML*NC߫0`O<$͠A, P\XZp 7ebE60"xЇ4d.垆wߟyt休T01Wg0#gА`wg&#p:dgPI`7515d^_~, _02|*=ϠT3(D?2pWN`I(0f ,:?;:C`#79~]`hh?D3a5drg5Pbd``e/kG8׳s :RpF..`煓XA@c(#d:ϟguXDLBؐ \bǠMP:uv )`010]O?F_>( 4\h=!t 4*zQʰ ? t+  f)Qt,y!Qh2Lc&&CA! :d3;(|C8P mBGɋ+8՘%C:d(kaa0##W@ no˭ .20 gJ npNcAcI`#X*s?h`6 ,̾;o30{ɨ?n`<mz1hrc:4FzAk\0w== hpAuW(A$@`!Y ;ff"IENDB`C09_Identity.png PNG  IHDR00WgAMA7tEXtSoftwareAdobe ImageReadyqe< bIDATxb?P8=@C4=@C4=@C4=@CIf~ ($XQ crXrbĐ͆n/#l f`{ʜt,@|&aa~WggCVVЈA8f;8ÀXdqLs`@F}( ~mPY=_`\\ "1#~~}gD# ; PJ 7AR2| L~}? Yxdt`(0~ և+|as p033i&&!@1?`1 :ϟ E+Dû3x~X$D^\_"-O?c LLB FNI춿@X $|v@`%o/o0a;`0 TY~2IJ0AɵAGG0Ř  }H &&䁿`O!'!bAeP F(` DǓ ܼbAUTK a6# f#F U 9D  &RQ y Q#g{SM0{ f8G=%/`)hp*Q@ćHXH`!I"ѰLbRbeb{u +*Ël8ܹi_ltjD34@ d aɋJBh X>  1{ 7i÷oovn~X3 p'@G@GfPz@9k2ocʃ )@h1Ig?=|/95[/v .= DzCPM4 y /4?Q%.OhH+?J+ PK!x&Ƭn'XhJÚΠ $ ""`/r’.`FFÞ* *``e0|fxs 0Q <>w<`0w)~P 3Rܡ_d@XnHf L5febfb%mFg&N N Lg`)0}sʠ#+ e fDb3c(P/( fs?hNJ|s{" Þ#[`ZMNneXZpwPFMuK`3 A3N ܸCB0t/_8 1d_ op V1<~^6 lgc$ggC߾?Zs P ǀ>ׯaeX ?g>FHC OMU0~Σ>TȀ1 Ȁ1䈩8j`ߕG  f~ o;@/?P85<8ˀ 8r Lhb`q`1;`!?@C4=@C4=@C4=@C4=`zџ:IENDB`C10_Kontact.pngPNG  IHDR00WgAMA7tEXtSoftwareAdobe ImageReadyqe<IDATxb?P0@ yА@ yА@ y `dds~wb`g bne1UmbIΫpb`*l-a#pk 0KfPWjz (v9fSqq3gc`dgePO?ofx<6Tb32-;( ;+ïL g t L 0$lf8g<[&=bp\6~|cGW0OS[-\cāQ'0;+$,/ hk>?@c :ьl̮ZRFF"@Gۨ000 }[~1xΫ ?f'ܗ ʠ . \ ll, }cЏX -1Bcj ?!mb `".=t_@GBZA  ~u.IV)60q /B8@ B`j &4v^7| Op23e qm&&? `haJ(bceAR` 2kbDLLCnâFH1xqP @c 2ѝ"w`'fa v.&cY!}9f;MsPD9y KMy/Ч2 a^30߿i%fPa}IÛep]Zp ,z~V r H$3|< >CYИCM_ f-|uONZhx<0<4DBR,B.:~0ɟ2|فIث g~`dF{ ]\tİ>Zf`fgec`eg`cas@G3"<^Ug`5M yy a_oΝ}#d[A ?bXb65. , &ö{pc1\}z l "BZKЂ^XUe^ɋ _]JG/R&Xmf;0=GNI^[7DdTtɰl&{3ݷ gx%ӏ$CU=3_@i&P ٠dNf e(mZyrmP(F@#NuUX,a*,$U`Lw ܌ ̖ .fpCR>=jd8lz3<2R v4(Ng!󂟵$LޞtX =ODDDHE @O. f&1Q /qXp\c^3g2~5o%;>1HJ0ï P6 bX2|6 ,$4,DAZ] Pg?{_h ' @o+3a t>0T#߁N}z.C?3 2pp2}pnoN}r!=AVA\SI*TĂ8Y(3I@g^xƃ@-m$Bˤ^YNlo,i@Vπ ^0<6ٙ-S` g>bX oURl8?He!!|2śȰn ?^߅y +/'vH{<⛔Oe`6~ `; zhV&fWonΠáp=#bum]6`oH άжtŠR S@6/uy܋ e> P[P@m`P7V<ߟ%\<0h=C87c?wo ?<Ĥ$D4tX:fU`aڐ N@o-(cf. tzy~8 80pK > -%Ttn ffegPc`q;o746]o2􃁓څa?h24aT2Bi&h+?O`j!j뎋;>6sAn!F9 L0g8I01B ʜd_`QEARĿ' >fPPvV 81343۹0Afz!:`c1MaW[V3 z &L\ o`eO翟|p0(0dzAE ,l ?0\{AAUẌ́( mh`VjLHy_/?3;S0Yq zק\lw_g1\xyԣS O {8v23K2H 2pd'? ,GY-(־O/1<~؍ Rb@vm!)_?ǿG>|~ӟ* qc[4VO \`(=8 _b`~$bnOK[Apl;q]@ L/Ó7?p77?0\~ ~}1P]@FمXYx뿗@1Pc {m Q= L s1rgasaύ 2RJ2bg`g`ftx@{._}O _?zcO16Xbyh/Tu_풬ݭ7J3z &0Sk^?@GC' /c2\~ ÿ3|ߟO27 bx{%w=}}#O @A5wMX/kKwo&}?3#Ƞ!,5~1'`8õ?@w}Hݽ o}{9ß| u{h H152^? W L;׷0 ~ o0'C@@Q vi1 w3G[1ș3}`o:9÷} wH!K D $м"&P sG$P2k@,ӳ@1:9tRs R4=@C4=`>'5VBIENDB`C11_Camera.png PNG  IHDR00WgAMA7tEXtSoftwareAdobe ImageReadyqe< IDATxb?P0@ yА@ yА@ yА@8O7''!/_~x7o^xq&o@w <@ C$? 1 lQQnn6?Az>p;/_=k=;;g&&PpM:& _>8qb}o @ppr62Rd;"߿@ 3 (bH ϟ?` 9&z̄f:97n<|ٚs֬ } $E  ߿bA-a333pYϟ30 3|X)PppcW踿 ?~| 2 /3.fw Zv& ޽G )&`RW ۷dC0ՂBa g/a7gha c037af8~84óg^z $`zĠ#}&C_F^q-&fV)) `f޿ (O琤Bh %,, ^=gz3jvw: Έ3\~a޽jo`ppg;ëN]#*Y^~g`x,>a`޼ _bNba@Ji1Ll2|;!+'Pݼy3Å I &STRfxá[X3| ߟGyv,, ``(Je#QXAQJ! ''k ǀ򘔨 ï/0 @ςJ Lb`'#2@P,'ʕΉAWcG{t e c`gg7eR~>~}-~2))0q1ACӌ >~{=*?4 ̐&$2!Y8Ax~ Ta M=v3ܾ ""I 9 @ϰK)~W~. '0ɃbV .ML,><T:( BbMAHH-wG^վG'DEŀXXC95JP=!'' @;tbDac.A:7F K"n /0b)=nϟU  I\ 0~7JȃB LZWuȧ3ÇIHH \"'%&&6>/_=ɇHD@˗:stÇ7@L 03I1\rXz7>}x `k@0U< ='#d@,$_1HJ -afF-U 00+0ٽހլ[!#3 ?+ 0v=c@v?...pi_ B"gf2xhc)ip )mQXPpppC=ƈKĄL 9Ff1ϟ?Zp{I_A|@Uhi822` &J*2y =@O`~P&.. />HԐD؃ (Pg..nopZFY **j%E ֋߁ =M P(s+7 bR)iZ;+߾}Vbi]a] ߁)/^> N>"" n 30 -^hmbTzR^1ԀjڻwnKAGG<0ˁ2 WNMM߿HFvFw+@]JP2abFW`BE)mw0|VD߿}!W?R#o``c (nNC(XEP} 0$߿K(%#cYYPS'$pӃo@ϯBI=*n< %_2 K3t4ǠN =?? ?~` 'q`u@Qܜϲ /_:'f/Ѡ ⠒aP2e^lٓ@ @Q<i0ll" Ν[ʐ2?rt]$FG!|@ԀIȑ}@opOz|,x`hh 6 &⊉O60n#?$AɁ?|x˰sV``m nBM 4.7(Á!0b ;B  ǎf Ɔ . RA4K`S ,RMXrAf@pk]g4FF"Ȱ" cA6j 2?? 06Ԟ2s TkYG$;P>}t[ XI=k.@lTcPoϟ?| =صk7˗sqqr ($ #r 3e&.ׯ5@=qf#*MP  9:Rb# 5( @51*Z^4*Qo8ghϑА@ yА@ yPrIENDB`C12_IRKickFlash.pngPNG  IHDR00WgAMA7tEXtSoftwareAdobe ImageReadyqe<IDATxb$$ĀAQ@7f`dcdd@1A UH d@YM (4#ĄHYތLL@K=Т@oOwI@2@Z h-4SOo)P|+P3r<@xL@ %}B~ٱ@3 3z"l@\ 40 L `Y)7O@)OY@uR w=a,E;R4t-?w8ܢ$;憦@'<3?@j8M@O^M{b&V  cyxpZ kՉ ##3C#@[jv0  T LzBϟXn@Oб a!_c:PyPiH @1U0k[ ߇ \I`Lp@዁,#=Pl(YDE@1 ,,A00l:="fff#$6!Q,'_kzoz+@~!Po.ˁ*% 6P6 _P:hȍ 0AG p3{ #À{6i@f:ӧ /u7Pnteaat1e@,Z J* G(?0iV |P3?yF7@o@w013$`hq!)˗cd t,~#FP2hi&66PR:'$ 03JBǘzal$b+-CQ tȜ8#_2y@f@9L Pr'? 3p @@1^k$P *4A)8!i>ғ ,bb$tkP;@=tCC Y &(Gم@r_`hbhPn#P,hdr@=w -@s` @аЯZ>TڀBhC{Hzd!(cItp 0-hn@#j{j*!k4hFϟ~Z g=yT:12y_y9Ae`(C o:>oL, 4 @TqC)@4&pYy@Jz ?%?HP PϞ70zr P /KHhIo *UXհ@<+p5`yH~Xz -Y=yA| v+03 п !AV@Gm&M@XX[ TG?_zFh b6| do8, $<À. uv?pm@Д XjtUU,-Ph\cG?Ȯ߯_t!^ I̾ ֿ@ +RRP8 tC@$ dæŬ3{FFu`^&R>pJ.ݼɰajʡWE?g0>?D (/ d@ $*K+pa%0$iiu`\:`}VV.M`H5.Xa`8lPS [2:hk ĠFH$B@45"yԪ` L : dm:Cܿ@nb]&BF3` bP,@F&&7#Pn-8IzFFSp~`f_v`t:aYl?1_ 96pe,g] L1*/0c8L@@ad\v ur#DP & E=`zUe> H_aA2n0V5x0۾LdzŁ a~21>`}&7#vbflq`TKJdߏ((i7 ΂K `X|[ ^'>̰/fht\[CX>hB$UN߁ €ja=^]JIg?],~e錍dAPS> a!4RG,o><"P] jс*G" EGkz s$0@<9]P,|i(6?0.LL7@M_d^M1A@Xw2<+}vt 2hHav$3/p  P PL1nzR@g`-LLrhr֦?ͅ@Z}W:_35!胵$Az5545hrbhva_H)a@s,(?BITK:3''{ Ҧ3õ7~@b00 #P)@Ġ1nhM@f(?ȃo>*MacL %@s&pt Y!h 6AC@ PnQ*()1xyy&4?(&OPGVr@qPǼ $.z<=f%U ̌J%mPAя@![24Ъ nC| HC>0(@O5`R|sB=]Sss?$ àFY ;vTv>Pg6fwc?0C#h MgIl7PS3PV@PT!7)H3SѶ>ԗ%`7%Andb SM>'@mxPP( A/eS2a$D@'i AC AC*(j TN2rj@vBJB`Xn ?; @1P7@1A"c]l>X%#@BAP"0$΃B"?ρ=0fD0O]~8t. &lB3"0ВAPq* NR@E^!0 [@C@I/ ,,!2SЈ`G4jz`7N73"yC\-R} l@fؿf/; hG0 Id Jza_OJԂFA@C؅TPСБdp sNX,%͋xP57P,% o@} zb@pQt<P@11*)@*'.>c01=*AV qШPh=`Gǂu>|h+Hvbx C?t l@ R* ` @11 S@Ot xiFڂF@icenv , pC)BB^E-n`e>0#Ȯ?JrH)( t+ qt¹@>(DIL'BTCV瀵0rI벪 |""pǃh!HڗEi9rOYyh1 #x@7F@hT&&` 4Hh~X `T_a0㝻uf< < r &ö́xv"d XJ @,(=`O̠f2h 5 !_@<#RuȌ}1( 3V)0 AP; XpLnO!d`('?̂z/0~F;vffYvi|?$3˾H ߐ f_@OCfd4^`Un9 XLMj|F#$Ro c& ܠ7X27 _i5Ly>>`@E' _М@8gϠllzOO,}aAAv)!f7RQ* }}vw@# BYA !8 pOa+V4ڴ1``RBZ@3o133)Nb =*CeG >!r0@D@Gmf泟N &RB$03')e;MBLHjI'3`d}`$0320(Ɋwp\`QM2"-]#uΠ!XK @R26?ņ;$e#ۂc>::1؁},6&HvxPa>eQT03ѭRtcIENDB`C13_KGPG_Key3.png/PNG  IHDR00WgAMA7tEXtSoftwareAdobe ImageReadyqe<IDATxb?P8=@p022H_ ? R?,30xu8^00@|;L fTpo4>. bXYDȆS@Z]YRXA]_ǟ naxvëG/>xoM @|y z@H1;᠐`crTSԳTeбPdPVd {~|aaxKV+3l43*xd7 _<@px= rtLHapW/21j1)A '7@+`{ _at5Cǿ~VfLd{T #d̈4'nANÖ= k2((2lqY' zz  r0bEN-_~_`a'70 =šYP % u @$ @p4?ӿo eXwP]Myy}u?0xa߾ ke `o/`j*  |\~> 8F @wga%㯿?>Z 1Ă=0#qjFnF[YxeTUXXXy ,,+3|ӧ ϟ`hi9!3_ 08cϏ? B?3(a#cЬ, N~eX3߿UNGl{j_% -l g\`ضm7_m^^>}}-5k2DAD:s$(A03BP?0ȉ33(*X0j2͋Zs7@3qo}  @3pK}?ý{.^fO_LLt֯_Cjj~PA'PPjF$ &F/4J1>y/'v}U=x:{i wQYv<\8G!,YW]ȑ >|Ƃ<0)I3 caɒE NN _|c8xc`|C߿G  <3@!$/Ҥyyy9 03`h''@ `s œ۷nxpI%u>ëW<+íN:Ǐ99:_2 ,WN30=;,CA!hi{ ""׻Y 3CT:4XQlll`|%`,b3LJ˗ ]Uɯ h`?߾00~ v˓_: AKի@|K @@ ,R5$ r(0?()h $ d33{@Os0HJ c!<}N?~EXL@?~-{=0\=Ea۷_ Gr@}߿vJ3Yo_a~P3rfaa>k, ;@K3g`L0󃴴0:ف@\\,v30C73] /^90Yz LJr@ Kg .ԔAy2엑QB@B/֜.ce9O 0@1Cp++pp5!% Z@|o{ÿށCҥ 0Yax09]LI (0px i%i 9P4h k.`tZ3cEEY%yy!pEt0A! ƚXzO kn̈FHj ,uW utT= t ~Ap`_X@&H*]@Lk:`c1ׯ׿{O +Ã00C=0rK ZFk7;I,X~@{W28p `QPi"H]P2""8?u..22Rl V UU5O?=t{t #Ê@㪌fsrrRTf@NvXcٯ^=&pON489v#RA馦:}eb+ /_;@5Yz %(%Lk` ,O0H`ŊXG _5S`wqX1sPLu\\ r>K3PЂIPF{n[;lQ`Zl@w @3]ʇ͇Q==Ø_hxpC`xZ}\`quz j=}\*󯀝Ϟ} K>nppp-ŀ *DV 44 :Dtumx +05KDPgaa6M1߿ IbbJ;WJpp}P,2=??;al&8߂+JaaQp@yV$} 5 li*o\uWނ _Kr@Qx6z5޼y lЭgT Yp_ ,lV ޑ|@QO6\ r-FF6`{^0f`m~kC@%5vU<^t< \P=nxxO<Ͼ||?;Y r<@X=/ D3|AFHV6V fa`egd`:?1͘%،@f1}F;wn^vٳgy?:b=@Bj0334 vfyYyyx9؄ED3 L +YX ,F޽{p)0ܽ{w0?U? (%P@Z$ 2@ ôiߺu#u>͹B3=S ?:p[[dJK0| f`pE7ϟ?zb H ,`'T BL*@iT`Oϝ;llaѢ 3fLmR {Ν;a>@a5,9Xs.'v'8(_EĤ$%elQy/^ܹ ` bl~߿cy ;A@ U8XHāE@M,?=󒉑.#y` \K?~JKKP]&,, 8ʻw  ?v$BN>6.`}!͂?7o_>2|}y갳$bFdjN{@z hh0#VHJ*2i2HF.V,Zb@/߁o/~2yVÛ2/2|AMM̚AGW_ͫ{ #TQDI))_+;'k;Ga!vNH @7P?` -~C'y7~0|ɣ wnapi>0ӧ޾}s46@,? dN d``Dif1M $"jZb}X6ձ$íw<˰{ M9@0* {TnT 00JCH 'pf%U!hLL\v/"͛ vꁱ~ڇX UU!ڔA]>d`~I`"b`R fe>p1; >y2j[f f3402r13(;$$RZ_20<}<0c`g`e`zA0(fO`u+`2z0pj1||_@eUY<P>eM$$%Kl$64S2m]{4"rg$#νx -],龢X0z/S7@Ψe"{08cggmI-̖L TK-XpcbWڟ>(2p@,yq?4`}bx,3o2 0A 9g00j1[ R`p;@9 X+_Pj~c86`7_"0VRꁡLjd~{ŗ q #!=F1ܹa6)2̼ ,@bd37_+o߰ z۷e7~AW2H ^fP4| '8?V% UY48>pw{߃+ >`v33߿f ?ˠ>uln UU7+" J^Ю+0t~b`عp+W*H%H92O ?I`(ps# O-.`WTXH;+0A/o>;jTnVp÷?=?:a0Rs!Ú 4~TN  ǶA?ƎUSӾ00 `f&)W8Կ}plܻLJǙ`s+@a/F3s0Z[d3*ӱy#C~>ע< n~ + #// /AAX|UX~@@A<T2ܸ7Lr?I!ymd(V z߅嶟 z>A 'Tطas>/<Y]zy#f&;&V)1qsh{ Lr`Zva|zp7#X튇k`ǿz}Eh1331\oH@=}/uLo`!E7el100,ީpWA% A?#X4;71)K3"Vknqf3w l6bbX#/zH2Z/Tz?@%ght>[v03\ &³+ RRf*%+# ٘!pWV[5}jO6`g3fV^6&/snTykopTp+;&^aax|{j,,j||,:.2+0HƯ^]#vdffLee 0S _&N,Qv?{Pf n%Pp`8̨%;zOdcfbYu 6zHߟ~ddd@l pء=O ă:G`[A "43|Xbe`t@YX # @+ l +` jabb HdZ 6:b.@xU TKqА!!!0tsIENDB`C15_Scanner.pngYPNG  IHDR00WgAMA7tEXtSoftwareAdobe ImageReadyqe<IDATxb?P8=@,p02!/UǏo}ϟ/??맽{jY( gj?1|' _}_|奲S߿_^ߗyuџz H/ݿǏxdeEJ?L~f(=GG?=o ?䟟? ˗O]T<+ŵ96֛ + Ib# DǏ ߾o f8xWfox XȈ۶-ĢÕ p"l ?7o}Xvj@X9;4)ʊۛ0Dc= ##`jOwR b@Iϳ'w oTRf7)o@G]]ѣg^ޅ_~~J& bnhh3I߼ggz?W99)6NN_?p A@ǯ|LL84#x#vv?vʲLq@\\ ,,R0?}(C&Y XP|ڷoLA]!!P++#P"-7kw߿ĻwvD 3kyxxyy54?8%~+0?3[ׯm YwZ7 (MB@o߾^``p(A988XA##+'d:e\I p+ݻo fPʤ.`j5ݻw1I|;uj11<<ܹffb/3{n;WB3tDNS`%yijcV;(Sx ϟr2Z  МzӦr\:Dr PAA9PKX\vL3@L4j7.]p=0)p_05 ť-^ fuuL`)g4"f&Ϟ=|#l] 1BZPfUTS;O\lI1a4@0$% o_|?jݨ#7,H/R.\8 ziE&fHKfZg'N%EY=YV A/ fr+/ y`[X1BK%&p{:Ç<{Romfg o: 3w02{'ÿ?}/_I^81H cT``&??y0Ŀ3|@!`epM']ٳgC: D$Z’ogeikAa!&ݷY~cR.0 ̆~3 ނ<СEA ]$991=ٙ *? =hjMME_WgCaQ=V_`#O A 13, `2zÏϿӿ Ux8}kW  =" LŶ6:ڊ w2,p7"3ÁFPef`A"3@3o|ңxy9I'_ #aF'ĠlPf32| l03\ PH r8ix]eXp^xIh9 ď' X{,,69 ր`siXGh0[T2GF_}ae,fa8cÐlAY/ aݷ8+>=ԫWNCCaeM` BHJK+˫jꪱJ0 C2<> A(hT7cR y{ÂkYիA hf%zb =DTIJ(kh뫳*5QQg@$`O0b؀p BP+7O_{Wn޼xdNC?Ii`zb~hA }mm3;iiye-a`̰bFH\nCF§ tpF灎A rIYqhy̠ @_ A9Ɍ 6i@'bIENDB`C16_Mozilla_Firebird.pngPNG  IHDR00WgAMA7tEXtSoftwareAdobe ImageReadyqe<DIDATxb?P8=@p022S@f" 2~e`dpad5aWdaeab÷o/?e`f> ,yf10ڋ yb`f``bFx ċKi1j2H 3r230 /d o.^}w;13@xqw}X=@{Ku &+4VWS4AHA[A1o~00|p{0;xÿQ&N;؏" n@CH--.c!Π! t_`Jـ L@9/ (FaK߯\| 7  ( =J@u 4n'+ i? L@213= T򏁓 _ Q ٘ANcb[ۮ2\syݿ1ÕZ`{ X@e d+0Ϗ Ќ vSd' YA?pL!-y <, ^ AS#;BN%H &Ž*1b`jq3C\m`dtןAϿ  6 ?I_ ??3H3:X2g lw`a%`a00ȹ$C%U_O "@A r(q2Hs;3>X {'tř?axÐh 4pb$ v@V2ߠ?3C=6; ew_-%? _T%d9y&32=% 30|HT( Ā=g3depMH>b›u3Q+XxX'Eh\ï߿@H r0Jp1\;q_LU{'û}= ?b`g O ,/Ds^}ǯ2:j2Zt1!vOH@= c 6}oaI_ן.=ATA^ X72<>w~V ~:'$/#~?~1|;C߾_#' ;avf0/$Uv0~$00@;f~abCm)'/3|a |`~bo00 2e~00o x 7p_SUAIan2yo A ?}fh]z ccPZs*@a/FEtM/2ѭGO~} $ɰ6(~%E/2=pc_1xG@z0eWo?`/00ZVVfpt#{03prp0pIO1> fW!}V&t$k@ t,3 (1ˈ fw[ !_N=ĐhnP WTRkLb<is 6 RRJ h?Ha{p6~`x?.[-3w1CҠ`WQ_pk_0| A1/3@ݹ +000IC?8VefWgx-/7'/3-?p3}c>}u %#P/×o?>|X2}\=%$)Š5Hvdfbf``SUMUR X$ IaKpqede%SDTt LԹd0u?T~^:( y?j`@Z@1 R0`c֪lŧ5 OTARQOp ; J2&LJ cЗF^`{G0$ ㎡/Å޿xǟ=a8u4C%06cדqF`I5C%Òr <//0ypZpUpRL< b n Gv5* Z1JPFd{T#+;' +;C|V<&3'w]QiObs`j&0 3>#5? uvU_?}&%YAq)~1&2cJQYANhP HB"9`NhV@W331D&e? JK$t- ßkƣ7U o1|V r @%隕Q  %l"fx_AEEp-D1黟@Gs 2e'lFF%%pq ';~{ o0<Rl y>ㄛßr2ba0Od\ ?~a`ce +I1.'A ? 21,3@!E'`I 0$ mşBf,2 X}6^bAG \,  #Đ?`.p2.ex ꉌvpdZ=?޼ Xg~@51$]I:( )]}X`*- soW3]~y+1{5p*/2f ,f֮3 ó.ۏg@ZFyQDdz+(3*A,#O *E@-՗6/,yLRBEpd?.7+?3 ^1\:|AB\!+X> UݯO#( Vx8x̀ he>PcT܌AX) /_$Lk-ï;X#lf`8 W`'_ <¢ lvgxpy`{ HXrv}'Ngr}g')*k?Ai@c@+`9_\?T`  H30=9/?Þ  ;D1Ua8}9ï35E< /UgzΚ]? K8:1 6;!I<&B%psA90~{Wv`wM_HbXI@AX@A^!טAAOSAAZaci00 R ؘʱ7ӥ tb ïLT``ac` vl޽c~g`I0<'`<\8? hw2 X3A$E{96 1(2(ˈKn`R&gF` dn@%^PI5 oX `Fb`6l_V100^&h; `lI0l>aJל 4 Cfp|XXZA s4n،&! <- ?@? 22V|wT^dg`4xfFv<+$eyޣW;*ҩ@wl4ZF%iQa}!x73;/H]Tz =liAYߝ~;xG`7ucESg_67NìS`œA߭ ?d`w(3#o lE ##12pz|fPSAi%X1'h(77c6MzM/PITV@8=`&Ƞ$ .@f 0| t"Q# s3f`| @c@2:ǿ.M{.2}#Ϡ̠Şa[ lƢ : pz R "Iy^0,0Cc oA|`0~Wa`xw'ß?`9 {`z Æ6 w~g~_fxm3Ï[݀ژTҺde5sY0Hc˿ ~ed.AdW14cwt 5yo~1|L^16&O 5: UV?ƕqrOa;o`- AC9Z1<_ FZԑLMݙruw'[`>kH;^!VLc V6%5`iԷI@mb;p= Mү%ˠ%ǹТ+<v(9 @@ܛ t%1Y?f[3 -szo"Ԧ 89rwz4تG $s83#,% i2L> [C_0'}w,5挬wP0 r *R EŦ ':nHhOwV,)RHN <[< mX[w$񻯛ox;A NcޫUyp|r;@`QRN.D]Xupt;&7$@d#޽ Äs O/ E .A?{*kɑ @v87cܜG-՜ |fhh8pʳ?`P$b@Xv rU62X[KDR@</ҠyCm+}zM;@=Ą/nTXa`j" ,E !(̓2-(si(AaM!-PUc '/-,^%g t/67L8X!G1YA9 'P<!̈YRRa+0eQP:I @L82 r jdC d?PORqܟ?30H)J0j0pZʆ&J13[ {_& 9i<cÒ&#HI P>y+; D-ØXѓ@1a }9` uTb8?C`q0#C' " Z lb@cđ @L/[Qڀ2#f?"|&7/çz0&/@fǚr b@A%1̽Ă֪dG8HE:Q/OQ5$arB@XR#ſ|V ϼ &XTA\W<<_ܽ %Mb=fV[`Ì Qs}3vK =ay0_gO009 ǂBl%W@q30pS;3c*Z \`C%?%41R#" E@y@@e2Br#p6&HZtbo "&hdPTp?x7 @0GM^ Ps01X@,m FAvfH`hPAFDuu=z?6lfafo o^1쟁J1&.^`-@RĄnvvfp)ALuRx~ (䁎Q{jٖ-OO+p2QX Yn5UX0} J6{?`G32Q8 0MZq@uPQXAFE x]ffas''qnn&OBFGYI(HQ8@y~GLP@ MO80VWk3l" ?)%@'8ɱ'R]C(շ/?Zu j7b{F'h5xG`[VpQ *m̄ t<0s_ex$H??] )Ij?yӇo@G4@I?~tA\lzS`},J9`i/?0f&'0pC/s#_?2}}!IB?_/|XYg0Q?  R&|p_=򔁅ҞT0گUe!4!\``` $i. ueޚz >}f@ǫ;z*PRa¢; rhDX: !\ mv0 *}poC+P $@ߟ?|0p"z FJ|#oj] % @,,ɰ9R}ݻw&b9l 07π*m`Oe`f@v<; BTL oy{:P4  Ջ?>}:[\g:\?OX(wzՖ {ڙQ޷> O >篐gbO~f8:sՋ39e7|ڄgͅnBǎ5~ͰqIW/{p)e -B pY[O>~k~>zrߧOGj/^zÓ_ '%БF&"TV6d8~>ë믽~}4{[iBL2}8wi)×o(~ 잿ہ%7?b??tI d '~Y._xuW>p( '8/GAn b@)*)",R&( # & .2AM{ # ǀؠ&lBu$ٹã|ʫWOUNg\d34΃|b5?cL,p.$ | ca?1ܹa οE}{|l.@C "e:.$'g&%Ƞ! ,8CDž`SLq?m;=_{/oТD>`@@3K J Z.||v*|lB RR 2 BZ2 bY_gW1o~p۷'.נ iWybfhlyyUMt98XX@s0쌌̠iǯ>?/_>!дoҙzG@U3R ႊs 6A_@_H ?X愎ٰAό;3_А_`|WCIENDB`C18_Display.png PNG  IHDR00WgAMA7tEXtSoftwareAdobe ImageReadyqe< IDATxb?P"bcceXXXZ#tO"Ig.>s?~ѣ'N XYYRSSc ~M2jr4 MMM"@$BBB -C#A#ƌ_~10P &?2prr2fggbO88 81rf K Z{W 7^fHeD32+2HKK3S k]90?0<|!v/i! fG b Q1b L@f02yx9׋!)%{Ă~K\!ANedPA AC=u1 ?<\CA~21^&F,I z9 *BL ?~A s߿P8Fs_ @_P=6x@Ä5`VAXw \}v8 ?0r(F &7 x+.fpĂ`fPKFs(!$3C# 4,)"_‘uRT>3x?T c?4&1B@/nkGJ6;ɑ`{H$r?B?[{ !#9_DiR%7_"(!?G߿6$8(@0|%@oH 0 ܑ, ?/_dx۷аD@PP t777" 0h:  9 $eVg@Pl<Af=zߟ4LÇ߀?ռo߾y Mf A+;1hs^0*D `nwMf$Н(#2hs c$+1kEQr)Q'Ud,RJOvVXՐ+Hu4na}%wP{@ ! 87Py@-,,"m@x l&&& Cݻ$Jd0J+sssJ`%E===K.icP=0 2 ʨ 'b T=  b$f''r`F??h:LX 3?`Yի:Eh%(xw N3hA>'IENDB`C19_Mail_Generic.pngPNG  IHDR00WgAMA7tEXtSoftwareAdobe ImageReadyqe<PIDATxb?PĂ.H~~s'|ݻ[fݻ%P'= xb?9z|922@n -?_zx >AĂEL37}?5[;p" =5#4?_=_y *ʺi#0Y- Oc~sgڥ|&W\ <>}„ ӧ__㲲rbP+/3QDW9>~W`8߿S@ "_৺zIIos1&+{h(781 J&5 6ofo.N{r} bDu|Ϭhee%mm   C@_8+030ܽa֬3 w_{íǏg,bn" %΅zwcci_ ytOCNQ`ccex 48'o1<}ç |aX3+ 3 ''38b`byqNqA/RJ?T oGH0;e^AF2o`ӗ} ρ f ,@3333pr3034p_}m##1E`F`PRebYM@( wPÓ <&&A_ o~;/b'0Scb`& ` )>cdQeP6WfedcaxPF h$oĂq{rRߜ ?J4<}eP԰mfeea`g9P21B y&Hcbp6bfb866&A&H>/*&/nc@`&Izl\ k^' P30}03 t u(d!5{ x&G@?03|;Hx6 QH J $"㧲_ [3 trp1l@:  $IΈL`CI, 1=X~F $Q_Xbz퇶>"Оwt Ξ:  |F[&F FJ _(1\™ _f?%+02rF'`%ӂ= We9b5ihH3(;B"LLr}o @_[MX 27'1ܹ X3`zFh '!H`:G`~ ! 1KF"(0 p#5 ĂyW_㐗!vVE`JTb0fje32;@XIVt@;?}gcxCv :8cz\ZA@WYEkB@a6d@۷^CPPE |&e| ~  q R ߿fzv2bbag -`k-BʒX_h3T"ePJAX2p 0<퍟}s#6EAL & y Z  ߾|~3|i1+dֿ~hvv.` -t,#}GIYwP If WXV' pq3JK1Q8`-2t-&@Fl<cؿ!.^zgӠ1@˗G?]v?heAr<ȝL>Їy/t`N` @޽p++_1=W v_k`_+=H5a"42Ϲ7xf&V v4_:v & AP1w1С Ǐ?h5xg`xhkh?5[  -_n| (-5v(fD8$up,w ;v߾ ρ㻟X]}x?_+PPǃB?Lj}{z_.<Qaxj0AoX Lb9/2\? }c8{ Ù.\xp`ӧgVуW>z߼z$^@;@Ll @3*ܺއ7+8<=7_3,Y ׮ax_??>Q1/oc<0:y2"?`3,87Ù3._yg`(wg?~PI)Ħ@  Mo-T;zsRIENDB` C20_Misc.pngPNG  IHDR00WgAMA7tEXtSoftwareAdobe ImageReadyqe<mIDATxb?P8=@`022UdnR @fff%}hI+@u?dr;@R^ t_t@0VV?~301ԧsssqrr1|Ǐ@?o}Tz&'0}… &  ~D%~jBh ^C @2@~dx?}l8 J 0I22lݺA]]A\\lڵ z pz!00QtX'<Ï?!` PL(]S`  #0P1<ر w*~ N23dfV0prraY8=@X=7G]߿@v82 ÷o?cfs^߿Ih(b@Nj`ab [UUm;\%ùsDZz 0<`iN Àr<>Ao0d(1(**& Ǡv44?2FC6_~bオ&L@KDD\(tI ;`rvCdVʰoV3g@(vZ L:_|_3ps3 ^FpA`f 7@/9@P?SDDL`L;¦#[@2vyY( -@IXQ d`aay7 y)Ae9(&@1}8VV& -IIa`yCΝ[I?VG|2`bQQ%Y0(t i 8,i cAcgy$ ̠2 RR"d!,~2ʁ=L>po>O$Pmܸ!..aٲ`V?z#0jW80z^|P&e<'@qAgJJ `gETht:|8@*V@L=z5ϟ__z N> BB|`π 0 ~}!@Ev<第A |13 p DGgK`Z:r۷t/4LX0C֨{×/?޿ #=\,rr3-7 0+|nPXK(`*!7ÇSQQ!V3.V={p'OB\,ԁe3`ǂ r(!PH܃π!O ,~98!40ܿXpHLRׯ?;ի'@ۻvmj(>X@t}`a`-K\`|,yb`;136+PGٷn߾>zjz:::)H @,v]>>~pUJRD(̓<+2AL~Íޜ9slÇwO MayC`,@YYC DVpL| ,ٸ0<*0@۷oh_UU `k .P1 ]X`yFxMK/ g_,7 l{v`9>,ޭׯt ++ 6@ֆQQ i``*,,z@-PkX/jr0_6)~>nnNp X *@?~gxP/߻poo5S@E+(&~Lm(bX ;6VV.߾}5@/J 4A%PuAI2T|oAA>x3&mɅ޽[ )@$ 2@O;>OAuɻwo~6߿?[͜D-׵@v.P@78V@sӬH/AUU aE)t ..5G={ S>QQ`O!268XY|/^PV/߁IxlMV;TT4B|>VF߿Z΍@1  emP~a.0@ H?<@=7HR6 o߾= $@,ܴp@0O0\tٳP O@}F) 5=d/Ϟ:4Ǐ_@|| '`J`Y'&&1!7 ')]]99)`9O>| e>QQQ`~QK@;iVӃؠP;!5=@f~ X*~@,8wv2DD$|*ǏRMMcF~~~'Ea(&@Q-( 5mmp)٘U03v_{f|X'\{]@=`dd0EBB|"@2xAFF\" 0O@"2t͔B6/kA?8}"27?ނ%cB PzT{T3{d._>ɓǻ@#\@F #qU}>$}vV>Á% hPO P 9&}HFn"J1'`C4<( tQ`=|_$}}I@E,wBy}j{ 'ZN:"!I/~sP  < XA1 J0?w*``6@_ '\zb0M֤޾}woCYiRǰ.\J@e ѧNǠo౥g^[>6bp`w //>nYYy`[ܟ$`"T<r,ZA%H7q߾ Nz$x+_bOa;;ak ++8{X_3@c{%/}TP~@3^pXBG!qH;N 7`} 4G<o~eM۷o.y͛Wnݺ>{#`I_>z{w@mq#/^|ہ@,ffwԁd|v;wF,ټ!bb& P03<L P+/~-0_]arB{<LnK^W\'`ӛ4Wzd %%@e>l,g)((/' tݽ{G/ DY>>>w݄6@ 3DADD4ÊK p`6I51!~E |-0Fx=@ ,y= JVhRU@SP>4W%)-rUIENDB`C21_KOrganizer.pngLPNG  IHDR00WgAMA7tEXtSoftwareAdobe ImageReadyqe<IDATxb?P0@ y `ddda`e``bb(.'G_0|I?X% iiL}[~=e˰ F2P? \ @`30&ǨWij)h0ps07߶;U8 y G]lfP3@`g` "Fz22a9؉=?;'E~=g7=-ŐT6meOk"A?+7#/7@_?eͰG0;~b#0,1@`: 4-R1CL%g?\fZQ, >e`&4D`$CHVVF.miu[ 9 L6&`昌eoT-ߟ XإDYx؄XBD.|`a軼I&7 | @O0'@ObV&`e-` * L?3?#m& {OYzݫ.@LxPL @eo]c(3!om(_W.%?3? ?!3Ʊ asvCyõ?>FC{{o ɳ1S0X`0C;G̼ww`J gPaef.`p&pHq!-p( &` `W Ì`Pd`ffb`eaa`0cpdraޏ9 : ?cx/`&1o %L}d"M86 ,YPuTo-GL>}=a=##k?0"?ؘ'Y[&[Sbdh 40 3ry ˉ ?23!p(QC[" N.fxx1#*`b`xT!D3!זAJcC" Ñ f4b({M zxf+O2dwD@`ː,$ d\@03Ddho z2\ X8_a^F?C*uW71|߁u ?Tx-,16X8Ͽ0HJ0: XL{FW_38(Ï?? 1̈,<A@M6/ f)1I_c8⥭&j!"_34n=2A@AQFϞ0kh- s?4~0mpAo0y*V.L38#3A➁чG {cEI *R78&= 4Xg/33fx`. rl ;߼dqu ~U ` &h a ޼rĄ~1I}fXr(+4+1+{f9 IQa&P J1.=x%) kfx٫ oaOû/w}lf ,Hb X8zп6O7?:  Xn}Կ2O\a|×^+?p/G~3<݇? ߾c7!Ou%n>7'! _ePfzAa +0LepU ǀ!?e}'Sws115qޜİ`rn F/o ?~`8|3/3, 3FEyE`̰0cD\`"ư3h-;O)M KfxGv72b!Pc , _ξ0ucG3s}!Eq^ ?2zAM  `l 2 ḛ{O?mE~3Jg8M.y j\/uOW38XPb(Q0 Xb= ҙA[~2~dì-ױ7 _@ hFdCr9Ykg`p d`!Cw /I3|~`y_31p3[@E aceT eXrb -CA"0V0ldq@U.??k3,IE/܌ԑ@GO}鸳lপg/_>0AUA^AV9# `b,Q~O=p+YO?6!Iˇ!8@!/Ȁ!RՍ_+24Ԁ,oY8TdIį`C >~b^<\ _l?1,>ܜ7C .`u^POR_!Pٗaɻ w_b`ʠ+`?PaX)9)Ltku^́0V??aی\q8m>2_f3$ wFEv9i6) 6afp?w7?k?0 }fm/I2T220 ^BzT_P5KF뺇 (Xրr^jbP:C_`> ه? 2 . O?ex!>ͷ|ǰv[  N f'y`1V okJ`; ,pX?H;R+Z}Ĭ "|>2,>\߸z ‰ص`fgeacbq`&u`xMЬ3| 5>dز3ß 6`mjaC,3GhT`F ]T$BȐ"ur`)O 1]&?d L:JP~AX!An`ej`X 4X_3ߟ2Uga `d}a d|áǿEՀS+#c`do{(Н/=;`T>6T<` Tcgx 2<f;A`rz ?~g. o 0`OK1$1xS( ֝x*&̠#`o&e*Π!l]P22@`:!P?<=zfk]i! I⃯=1`Zt /9U`1)I`egflq1VN`G\Aۜb>/\ 4Mfw|gf0VwYH`dK`'_Q&%L @ĵ Xq<03s_`6|p;G2(J*< oK Vpu/H2zg1qbbPpebF@ ^8l _o30p[Lo^3\ƃO ‚ j "~3K"^~Vp!`H?28v9X$$@yLÉ.U\~(C27#$⁻@i ^}.?E8#7 L}lqp ˝ (VJ@:kP'XcBF;l \&J_DVp2-Ym`bav`dȀ P< %#P&W>TF\5?2,7~vKcP/]$ QP$ l;u bqqn9 ;a /0d)p;qo3q30 =v!VP~1309 qi?EԃW6ΰws{uD2f`AKWA,< A ,Yi&֮ o3@Ao߽̠-} tX3;FMX@c2 ~fd`&]`X Ge8pV6͟z!6-x; vj Xd$X4xe#320  660LQ;~ys =Q@C73D?e:Ew v& g#` rKTCW`/0f ߁5^ a`7;̍CAc6 s0õt zOb⭓ U03pz3.3e8 t?? :2ҍ3ة|a0 /4쯗'@]I` 16s/n?B+R/`w+gaoN>@1: qJ-+"@30H4 )ůge`3ثaPx͠&XG| i KfCW>cH`C=zۧ@6}?{ lE}hV r;@40@Chu6vەX䁼߂PJ|a};3"F"kf`/`+>o^ex7} ď0sc`N%XMr;@t flHl*0A,[g`_F,ypkA7C@]gQj|ĂK'8ꙟYc v 13|ֲo| T/CCC!(T?! b _e j Z ղ쌲QsC?@G} i8W A@ n40؁f7pبq/!V  )lfJIENDB` C22_ASCII.pngPNG  IHDR00WgAMA7tEXtSoftwareAdobe ImageReadyqe<IDATxb?P8=@`dddptttP222}ˇ޾}{7o^ @,,6p)((0$  >)U@G OJG' @F;R# 1TW})".f^[. sNclwZZ+V)eSUϸ󙎷#0b]ȞCYt\uj`l666pba`1= ++T H=@ax a4({ ` 1 2HIIŐxA 1i%Wh.]c  f@!K ɓ$ad \bB@2j8 `][@d-BFK$py{` Hr<,۷ "~d@J!1@dl>(Г3$@,;%ɁT31112+@VVV`H |:.P3ͣ''PhbP nѠ@7[ jdXr<p8#*1Pe*N@1h汉?{͛ ϟ?'X @$BH$nz>PCTSbD<@ISRm!bFA4k'`s@pYJ4_*BA"D5da2Bn |I<@~;`L[ &bBʉT} GbH0 zdԤaσ3 &z gv%ElիWaj Pڠ%!P0j1@qz*(F"{T߽{ O B,`4"'&&İ_ z x&DXX 6b!@dn&(A&5Q(-!#0 3,"\za޽`}L[ &bQZ%bƟI XaqkJ*0Pe՘DD(:٠ºQb5*A 3|@##s$ FA511=2ۘ@/6 ǂ< ЃOrki/TUU r[@$r0?@axׯk-[HGD6jձPPPAS oc@NZZ:حmӧO>y(o@w?60)I 6b- V*j7(Y t7 =I {l-h 7IENDB` C23_Icons.png PNG  IHDR00WgAMA7tEXtSoftwareAdobe ImageReadyqe< /IDATxb?P8=@C4=@C4=@,`_02f`dfπ7ţ w0@ @`dbW\o2PbHCb?AC?L-X?av1 %0,U0Ҿ/f]%ıPL\6{2@w![D_qv} "3_DY>1qp0?~|cxOA@A PGv,GA?$f +@( ri9ß?5Ö @w?05 •Pc9`'9 <(0|ׯ_@ 1|Q<-<Hr,K V RA a]"i 2;4jnm9Uq*%ډ54H^:-A=r< <CH1\?0cF]bA.sa~ۗ L JBL8Y,ĕޱ:Ǡ3rfdt2;}S~|* "WFtc t bĂ!1'Wm`y!ؘ*`@c/EIfȥZ `DD( * lo`5Ȍ,ǰ?,)U@&!&W.1(~ּL\l}!.9=b–2 eV>@p{I PQ802}z`je/$ H&ÃVǑQ"2r,Cc X Qx ؀V},Hlz $K?f鄜L4XU۠@1~C8crh7bENv59h51@ w+@!\+H.O /r?@ Pc*\޾zRo_3/~tπ%԰50 ZSHi Pb?"U2`Xy8] ?5W ;_/a1OB@,:_ j j?%wakWhؚ(c@5?x  2"# Z+ dbRen<G-@IX2P;7,ؘ\UƐV'fFĀ%Y`i"haiVE+Fkk F | T}zʑbŕo0 h X,cOoo`?P~;/fds:4Ă4D$ Wb XD!y_,E%? o@ @(1 )Pt0 A1XbEѮ& Xjc-zp "b PЖ5>÷y7{O kMg@؋Q4y P[ LL͜aޝ@}ИǠN#|ehfc`8, @8=~Lff Ҳ ?3<|Ν9?~͵u.0.cz]@w330 #ڿ Lb8w";$b pz0'(T13| ''Xϟ]ʰrj͛<|(;G'f?B~[Ac/v g])կ{=LJɃ!LUUM < "aɒP V`hhưk6. -[~GYBQ_ROW 3L@É ϟ2!fHB! ET ݽv_eappeV`ض8۷P4IKK3L/nIMv1&i`43@凷 f83`%6(F&B \XXXX&%% << >}b0}`00Pdd8q <=,/EE3,]8AMQJABLa?O3o:sV̡`&[0`[{waQIFfF z ÷o_d;0Bp0_XȾp="" ߀50O[=/v1qgY8n0flpx1PdJJH?4IexÕyLj`B'=K?1ߐ:9ց0q᫣74az`E) vGQ ~f`d8yM "4|Guޯ' ;Rt5 |6I|bx߰WJ2K ̺OX+r2 ?90俲d$t/6VK?XfX #:e Z"=#?OЛx92 P<L~@72+3gp=eeݚB6(Oo o`HL )w&` ώ1e8Ӿ޹p` @,h'&` _~,}d`> sC?$,9?02,T4QHcbhTTYvqhEV 3'ߥ@ mobD8AWP`0cfu)I߁U<С!+. 2uEDDTU <ǀ0× gX9!E6R _7fxy`ʠ hʠ)l6@ 0] ~d>6!/`[A{V`o0@/3h _ j—~! &z`w>X*@`ߕADXT2301R%K7-fpJ>?<ȿt$ j&ʄRc?1Ji, zEv W?3xM 2D\0h=pM\P5|Y~ܺ X+9.i`Ĉ=Xn4axuL`oBW@,=v/3̐J.L÷o>06y߿cfў+ k00) Xq(ְaex72,^d . s%h$~`Y//^<_203 r&`J&+5EI rX`zĂe 5 "ع}}y=\6lXyϟ B@1ܾ}晘BKNFMnjU;136B@00_.8 lC}-pu[kT1B|+"ޭx"l hw߾pŋ@/aP/֮]՛OV˫ ,f#g`x~`u(>}2E-l&n. gΜ}X[[;&\ bVdʪM?`/wpo\@XSg~!XOBwܽJN|B |F.1,a2X 1~rq 0}?9'Xl8kp/`_Y93ةKI݅TIl _c:*l@3 @$r_|ݶpJ7` ؉wAJ<33ZVVR/`@߸ %hA_H_hI߃ {/0wijѺe8@1 K@pp031(0_ 0y`{,tbc> ApY78=o<0 `Ik> rWlȕVl2߿IDR:fX ҹ8 h:Xғc ߀Ћܜ\|Zv5Ãsov00j@l?=&,xdфP# @4o`+Uk  xuA퓾 ξҝ!Mo`V6WԬe)yzݛ@ԃzàN<4@Q@h Ȥ.I2P+XR'#q!?S@C4=`>^qi>yIENDB`C25_Folder_Mail.png}PNG  IHDR00WgAMA7tEXtSoftwareAdobe ImageReadyqe<IDATxb?P0@FFF'ӭٳk>ף7o<ۯ@%bzdee[ZZ1|6/{ϟ?}8sҥw@( AyZ1Ϩq͔5u~Ç 7nЫ۷ozf/^p 3$gH<==UCBB/%%%rSO1ܾ}…oo߾y 3^p@% @Q5 jhhrRΠ nnϟp[n_~_y͉SNMjDHHH ,,D߿1}3w]޽;O?~珻߿cρ"@Q>7 gx0m jvUUUMm ,yX[[AOOW6_ :bt}yy1 djUb߿&&&L#5#@Y?6c@Ҡ;wn~ qU<娬 ߿ P1?R'0p0ա74!уW P=w7ՀA4AYE ,bؑ+8c` `P?G0Y`0@Go מ~gxO^|/8{QZ_)@O{3خbw?`*^{~)aSbdPgcfc7Ü.,+wiy:jj/7_0x ^bx? 12p0q1H r2(3Kp0\aS ~ XXdzG`Q}@\Tl(,؀ 8gmyqAI>ѷ~+177_?oAPAZAATxߐ(-Бdd?hbdx)=u)0="@A_2\~ݯ_@ (߾eKlH/ ? ?~ )X T'9$3E@?`Osd@A޽+@=3Y]]|"whCkY`b::ر( ̡w38e[1j1&Z 53891 b &/߁]d @=X /0 IFhҸq"bb"?h?RC?j/A_]/n \ | ݅;m!b8?̠&p]o@[54$z®3|c8z&C}!{`Z"~9>c`;XXs3Uaٲv_}yPƝ}^fsse^p^vE.H/ad6E I{'{`%͠˰0'm`I-?_’PKA%:NP!Ei=g!ixa Wgήz ?~B<J6!!l 2c5>peA-Ria6{o>Ϡ 3 `6``s8MŰDE M1QY3?o`!?h7tT.*RW?;One(c ['Ly ѳ_h,h@@20Y`,a0zḐO; 3131 Y? @ѿCzʐ g1SN|xp@;3_,@ r#NR&NǰzE-maP`C}(9 RS32B* `Ͽ?_O_~l`3Zを-hGk&<rL=]%o~~'_o}ķ@ t(#B6 ZLBߡbc (bN>fH J%w/1{pȺu̱ߠPtʥk?{%?&P聚:ԬC} v_?H`ʕῡ)6 bK *Cah |@05IENDB`C26_FileSave.pngC PNG  IHDR00WgAMA7tEXtSoftwareAdobe ImageReadyqe< IDATxb?P8=@C4=@X=$i00-d``01|ʈOR?π {/ª Xt< 'si)]"o@A2??,h@G0h4W;W1(Kjݬkĸ>%yAR\_GyfCu0##,V` Ԃ? /\dV +?_F)",wg&+uUIN?jvv!!r@abFF.Th0 NJCᾐt@=? ?cCRb P !403 :ߏ lʄ# 1g Q !? u ̈́OA= >#81BdW&^?̿A2.* e$ p(13c$('1? oT4!#\+ \8Jit`eDIP&pXbA8 Hlcz Q`; $ 1Cc?4ȁhfhMB  Fx O>L@A.1Ą3` v#`XZabg"'#ʂ' P8##R' PRHQψ(p@DfDx#$ (FF؇&Q\ pzryPLy?#f@DF9hx"D{5R T e2;<ŗ"{aH$QOĂ E̐Yf$ G'!yAX m&F9F< p'!<E1(/#"X# ˆ@!P̌'oCC5ТggoMdd(&F N8?HU2$ @x?x 0kDFCP,JV mÊL=THR X$"c~@;Ab`CDL-LL&,1+ x pBham>DTGI  8XSQt_Lf9b 7?^}cx,/Ǒ3?,l^/4y%& IԔeQP5l, ?#R?jŗgbֆ0J}1G6Jd#l#AXA@oٰf>(j]#Ci#?%0CǏ 90 #bj/& =2V:y~cw?Q^eϟ3gadjRRYKi7P7TF*XC/ 3A'~ .Nz231/ o$+@C[6,<п_, ?R9߿2=tQ XRBkc"X' 1{b/ßx_` Bz’L @x{drȰ.:?'@qb<? , }P,|c$X/R=DCi 90 cDa >(d pZV ȣdѡ d@AH6r F@Բ'099 ?>RED ^4%@yHhTX*1QI!1\ 1 QX&&I G/ 㗿~̟ '(@t J2` p@R逸?"Ăo.^ G@?FH~ZZrv2y} A%#ߨ= @,E*$D|ȠH7b q '0sK2oX/<4 z_^{%ë 4tIIAFpC^[7 ,  ÷_N}fe`lj0c`B|L?N٧E <| dU#?_WMdb N,L\|ͳe:/$Ӭ4=@C4=@C4=`KU8IENDB`C27_NFS_Unmount.png PNG  IHDR00WgAMA7tEXtSoftwareAdobe ImageReadyqe< _IDATxb?P0@ y 2E244Ul@)fPrCWC @ՊݜA%~=G<  FV r@,22߿e@Y FF!|Ąć1aɓW d`aafx+ed<h @8=o3QQ k -@! 6$sG19)d 9ffX>} v A=OdwNNJO?`033٠fb,"y5!aˬ l _s-R ~f8D3H @axETƘǏ @n _L? <p(_?M B@ff4UP(oqq!` ˗Ox P_i`((ȏ8\ 0 ˃Zڰ @LMjB@v,,Lđ@$!` -** -kP0||r5=*@A@ >hI@,Y` VcU..L /^|6@x5gv4I <Ǡ **Bf`^w3|j߿+3 1hBVaEjJ@$,Jul"c׾ZԔy֕vt!MlDAETc (y V('իWsPPP`x a{P$Rj=|v`%E1atA0?~Bb T_B6@C~(DA ߿_ ?~?;\GG#e hb/HĂLJ#! m@X4XR A`VFVm3w h7#?o1Zޘ r,1r4q  a Úz@FJ_ y$ : :|z""tAC𨕒@A>HXFϟ?RiYʁi ^2zԽo\ @ t0AT0bԩed\p ֺ/^~HUG@|  @ ,@@|ZZ&?LqNP!~@HPVb}d lK}o ,hP~įUCz«811 X~h |ρ1Ojn -V`{_2\?CeUU r}Ry1wq۷o% F@?~Hʭ3D)p1_[ R82XnjL+ٳK>Pɉ>' I6#$%%ƌ` n1zՅÂF~cA[UA7Xh:*˧O0f@мHU@,$#OK;X=;e.`r;0ʠƳ_>3<v>\~f X%K1!Q HBbO`~[ "0 ?P+{/1Ğ~7H*$[_N@16IENDB`C28_Message.pngPNG  IHDR00WgAMA7tEXtSoftwareAdobe ImageReadyqe<zIDATxb?P8=@`dddptttP222}ˇ޾}{7o^ @,,6p)((0$  >)U@G OJG' @F;S2H$hTW})"RrIpwsnf Y{2րWk]wv>}F ˁBs!NZd`e y ~R@L$#6%ba0(^ f 1iX$)!A T9YJqG![@ Nl%"@2&ȡ, L,L _?0, v_?"%pp@ _+O2~k ^f 1beb?>~[0LXPh_PQmAtCĂ\V^2f|{C?O6_, ,X~$P//O_30 +p3] ^a9AO艟FDB7?1ufғSX~e7 $(_`4 l_Hw+0AEC.200,˜ 6?8=-  )TҰ00d,azw;Ô )j _?b`- -!O3~w ,MAŀJƖAæssg `غ|;CѢZI]`DR6?0|" ;1dg84Þo^f`c's0>vdp`bxw%) ׯ`1cpַe+ѥ@] J?2,jƐe6ΰa6OJ jEbxu'!pYwO0I2e3x|O?ՌKT)@D O`8p(Ärn`~' ñ{g62,```1S4ASX1VW3Rҙ- YJ33g*'ñ'^a`dt6×6y TKGCLܺ9 D iEn{o9ǁV+*sG+],9ke/쒔5XEA{54CA>O#xnVd.f@Li47 (?`XɳL~rc_~6␉ݏW VXFat? ߁ %!x,_&p7;!1Pd=o2|A6Trş7 ,$@LĶYX_1q?pb ?_~fv(gy}~3n_3`;AV@w w~c!HԒa {l:`z| # v, RwŠppn ,&ùon: ņDĉR.*3e0bff0.0LxUK`ff "7QI <i{W0y'^02`ζa E,!\A]a% ߾`gbf3d8bCݣ 2h3111(`0*0l1@D|5;2Xd8l=C8& k:ÊO3zvAA n<2ùW{Tߚ Gf:M~*Pމ j F/* V" q }U ?D2>gpbWϰb,& *f *Tdmx%@,Td`HWEa.Ή [v3H8ca3Ok`תn1o`1jf`8cЙΠ(#@5-Y򃨠 Ҷ:M-e|/& ؁M `gVKN`Q)Ƞ!͐OZ+SI1n_d#0dw,᳗? `znpq1H3k1XEh381aa&/ %!"7bŸ~e`gqq`v'1Phv6Vp XÂ< *i@IA_l bs,W4b ȖV]*FC% (bQb5*Aɤqb'JD  ur&(<l1@/^0bPN6yyy@n(}g@t |um~~eqԑ3MZdu,M  4 R~ U'-- ##Ç- ƧO} hQ Ļ~ l`R@lZ@,-jU#nP@|np .&-PL&t05}6exIENDB`C29_KGPG_Term.pngsPNG  IHDR00WgAMA7tEXtSoftwareAdobe ImageReadyqe<IDATxb?P8=@p$22Ī~20d@w g?3+C5P7S@ P<dw~A4P# 7 FO!/P+'а@Ă, i=a~>7g{e @.  @161@|@2q0<p??Ԁ q z P<Lf2@ǃ F'adf'3g  Ë bTݸn ~5+0fF0,"d c\Y `bP,, W}(bBy/,jUd`AB@-sprS#s1r&0>86uld@<^ot5Ppo-kqe~{0ھC|L,2Z `b.&4 per0 |;dAI&8fVC'/X~f`X$##%e TL(L Z\ ܂2@tQ R``2B+H7?0= K>_=FA@T!P 7=MǏC &?0)=xbAEyP3@z@pE,0Gz4 5 | 0Y0<~߿93:8 ?hzFA߿P10u68?+ 1 ܩ3&Ñ=! *Yi `9j2h0Hq3͟+(%'~#Ājd[ [ =ab|e$߁@e!#4Ko@qV!%e6v9~c{H\΀Cΐ!jAh;;F)@,Haq+pUnfB'a, 1 ReC) 0%@L ?'3 ꛷ n_4nJ/  2|uh9M >R] e0Sbp0D@pSw0p?ywodTca JXZ0˛V>iR r ϧ ,"6È& \{W33ӟXB.N0|vR | "дv,#r lcX1ó;O|7r\ͬ60ZR 9} l=xؤ6ެD0H2|gx Ez'9;70Д{38T{3|{a_Fb,;7%!bRC'ٺ] ʬ ȃL`az򠐁v$@L=|FTOo$XEƽx=ưz /apMl'^0ǣ8LP1E0aĪyC^J# X 0ة[0켴ANR ?dSa1d0a ?řX#q!F Pb#e۶_LAs̠?j\=İp) Q L\ b\Y̰QN]QAa`33p'X՚ο Pb4p" 6\x8bSnJ@њ7 KϬc8~Ö 3nHag@nYAhEDT !]@Pb@V jX_M`P0Vby#@~33X+_ omp2"#7WZ`# %)Pjt}VH1@,]F@Կ!0Lw17RK@:hɋV1"`9FF4rj\ӐoH(" PAs]]@{X00i@~gCeBd?%͋~f \>h$1P >(RP_1S;y)6Eh|i`9g3lEI`C8P`CHrX`3633-{Њ/j?3ƍMڵ2S-ՂeLx?auL4<  P< aryQ&pX#33Afh%C}`Nl@J 00 ! Zt?{sYGfD^~$E䟏V K0Zsg_h㋙l>a ㍌LC5tl 0e!V ^^TRPԷF;.>.:x 0@0tǼdsv`胪_4Jnb?PhġEG 0e  pzܠI ̲*?/5n=h{ BvIENDB`C30_Konsole.pngl PNG  IHDR00WgAMA7tEXtSoftwareAdobe ImageReadyqe< IDATxb?P0@ yА@ z/`fffbd`"r`5L †ŀfb 09Fzl f7߾}ye@?;??8CcV6pgD/#*"3CbDGoڲ뷯J= c1`_66S ȟ?2q0x1z:(||Zj ?}bpuo߾Qzx^m U߾22ԁ @=Ls,LL \ fhhjc&:h ޾{\`kof&fP 1@AP&|-߿ }@O3; @!bTJp 0#J RR1AJ> bVBW`GSG2A Av< ) </u@,k1<P!ұdX $ |ɡ@Ca P)؃< <4tAfRr7f,GJ 01z 0P@ ۶mchjjb,VN@~=×ϟQa-f4CXrafx5X+  @!hP0 mR0 '9!Im@S  ruh0C yDMM,`bbpIɓ'39s !,@F'ȎFx<YF(J)_21(cIII1̙3ANNPPl.)PA*@%#=ĄR"9{ 'J ]cgt XHGCa 7l`C\LJ!a`2ڽA h8i/VLpJA@1ČLEPZ Ϗh7o@\ P,cx3ep bps.1HKH0=R,qRBJBMR 0|J -- :/Z$E`me ;P3,Ġ F$@M fHsA0 r$߼u!&:n '3 !CbDCBH/(0 3g2l ^^ VLB⶿L(@4Cֈ'ogL>X "*.2Hn\OfbzhΝ @Kr#@$xE@X C",&Űh+`X"2jjBzR PI|Ξ=0XiOP bT!8.Gt>I %ÕZ(bun@ 3N]n"kw`{J>d ٭fE b G lalbA3P@'@<00*eT128 55Z2Xzk`tx`u̐ԁOĂeKӰ-)/zYC38% X6|@"}`!of@nȐ P`ELm`SXr&&2lػ,} XX30hqzV`5`$cD.&U\'403c4%51h x><n&YAaP&ꇵa# ! ꬃF@Uc򨃣`X`DP 5C Dk庩SI"eֶP: ztlu9iP7'}ԣeXR VS3^}ܘc N`$(`<0ǃ00Yb;#@%G:w0AKoЃ:Zqw/.hLͷ+C^р4`zlGHuhkLc$w7SШs8AXTF1F(v@! *03|:gb'=Ho"Ф?쾲lH zg },@DMXC)@, ߿`pc8}+:#x!5*(#Q7X r󞦖:?!y)% ,UC#5C%]13 =~aL xf:8I@23!+<H4}(y ߻SdDj-` & @p|m߼EZXaH (TF,",ky|xAP9 Ȭ)#Wo> @@1,K)[ f: dڼ  K`:bUhȯ0 IENDB`C31_FilePrint.png) PNG  IHDR00WtEXtSoftwareAdobe ImageReadyqe< IDATx՚o\}?gI Eq%*YLKTQ;4.K4A(6m}K@"}p AF E. jHu쪑Ťgr>YZwx9~緜=j"}/=M?2:{v,A ^S!OeyeLJ?կ*Px뭟|2}R gphdXJM>_^-_SLhxy4[{ΑCx9?Ϧlݰ1)|Ǐ;u4tB8pNZCӇx7Y.z )]07[g׸u/_beez7ߕRCF-cMNNto /,gvvaB2d =%ٳr5Y3B‰'֢C֭.^ٳP_Av.$0>5::7Ɵ1?,0#IZxA)ѰwwVH8sJ@7](Rx#Ԓū)%R-gz?qw(x,,~y]Òh%dCIvA?:OVj')gSk H) "P'###9#MvJ!z4:́q bgA1~hZ"RvJ\cуᇙ=pŧu?MNNC}p4 &X4_yޓZf<'YՋD$N||7՚yVssX\xsvaffBD$do-K5hun:"UMa5J 4)e;LDH%+P9Es(%Bω&4&S78,ѐ#$ ^es W&>)aKjqbW`(B0 αo|{0Β9 !! Mz=VkϏ$!BA*2$1fGIp<5dqcڪĶs!YJ1 Zn٘( \*LӊV-'RR (lHE:TwN>ڄ@!m\Oo%s.b7 p|an~d1ϓWzA@7pάt !UE7n|g) XkI{Ig*A&Mirh h"B*Ƙ.)'F)sƝR(`aa39]v =CC8gÑMMz~K@)QRJ X)EQZC!'~4Mg!Qq9~`BaDZ2RRQ;w yfӳw4Vnp)cwIt>\=>1{G8̣h  !ƈ6I$Z 4+.&ٳ_=֪? |t{uA6uΡfff3gD8q8N1ơuҕ+RS0)%JxB\:D^|eڇ֪}QH)BKyy0Zߝ+ɵ#tIbE!ZkƘI)]@g^aqqJF"I2׫ܺu#Gګucu|sisj} ePTܸq_.\ߢ(z?fz!7~7{;wZ(w q.,;vbd"YfN.pgߛM =z=f||'kGQl6okJR8zU؊Bi|[~zûWrЮNhhgzyjѣ[K.!Z%!D*"|ȷemTJA Si.8HIaIENDB`C32_FSView.pngS PNG  IHDR00WgAMA7tEXtSoftwareAdobe ImageReadyqe< IDATxb?P8=@C4=@C4=@C񱼼\yl, L id#Q0Ǣ v"n S@X=\rՖR ?c Te@A@?afApwҗ+#; t+[[Hp`8RP"`5H`5C6E=YH`1P$dm { z&o|oa#,aq VG"yA4ϡ ++3'3Pِ @X=C;2230 D0.#42aK'pWO @ÙF&/2qc :QQ\GR(rde5%~݄ Vb 6321RXޡ3 ?$/`y NN){@Cs#R`eee02b`daA$k^fHHHg7?us8 p$!Fp1k˖1|.+cz$#0(brCУ3@.& rZ^~c`bg9{NNTHB3 Y 1 - -t7 C_Hg@A 0[K00pr10K6@ @Gڷ@+3 I{ 0 4ؐaD)bP A A dQJ= `l7G NNQ mƿz'Rl21Cė%>;CPGDr(#ԡ$ @v6RQ RxRb yXˀTCi9@g:?<b3G$1=$le# o$_HP6C"y )›_$dOha``d\(fx}?xB@lJ`&& ?RRe4ρn;Xp00B2`(hv%p%!]a2й  "" _`7@ˁ쟿)߁O CRXA4?b _`FM 1`23O?~A4 $Y@D^`*ACKG)@88 (0: G oH,`=-}1)YԠnh('. ;ܟ/_Dyh,$@8=_y}#Jh#B96Ԁ*)9`>d1PM000w`.`SB1@,8ËϜqV'e?`3 z ܌Lj J L ̦$on(" që[̀q_SX2{}3eըP1kjf0Y@1Q1F/_&}C5$sD̐~f61g ? 0}my{\WXxāI/J|j:'36p%c៌,3 @1(C܈RAEA@woo_xB kEe&81v43,=޼v 00^6%Nd` L ρAy  *M~)Y5 z=0Pk70 >۷OS-,ڗ =VPۂ7F`Sһxs 3_-n0 !R&Un.q`+ޅ,x<@x4N+?m|.`;K]:`lePX^A `PcGa0 AqPq?KUx"/om+?`~&P8F5p c-` //" 8"O!Ʀ/e;cs@᪉ϯ_4u&P~v?6vvlL^*JZ=aVS! O hn|:p/ t%x#  @TqP*?!P?>PssU1#O=cJ 9EW0\̢VI XJ222 &!h2:˗߽vCn!(?d 0ٱ`a4!AQ`-%($gCln bK`fdwMb 6!˗ ZAoՂ &`BBFNn5P>30"*@y y-oPEDA OъLpIu4>߿gx9G{ V"z\|}7ld#2fd`~ 8߀F?O`&wn#1l =_}{[Y%!!ԌB_e`wb'` ,.{q}e3ÇW]:XA~yo&FR"X#/?+Y̒ #Cc; ,~cᏲ*O` ɟo0|wбfto6΀,!k HZ5+^BA|&P_@ @0A)z _od'pǻ/;4I6{訟 @ъ4ـc ߡ:3 ?.3@Gyh`zˈ4A  Rc0=$ `29(AҠe@6H_~`N@-H@@::h;'}m JR?c_~/$I:#d FDR?&BԴ t80v2L_,HDqˏL@bYǞ 4+@ yА@ yА@s$)IENDB`C34_Configure.pngQ PNG  IHDR00WgAMA7tEXtSoftwareAdobe ImageReadyqe< IDATxb?P8=@C4=@©j!:###7P= PP9-m6>@Ubbb"" BB" ,, ~dx޾}_3ⓀyO < aNN70--uAA~vff&1| nݒ8spÓ'w1r < };yaaAVV&O_| etzb-=@LDz??ssӦ- `O?3z(: hb—ly?k]PgcgX`bbd+;;3 ߿'€V &j`r߿0q -ao{ ¼,@0cABBϟ?1@1a)*UYY"|T`߿<_a{knp ř`{D,9H[:b 0<F@@YKK!<<Ƌm)~:@i߿mϞ= eb̌ m EZx 0_#qpb`7;py$?~'߿se'!P $6$$l@@)F% 1  ?=/ȴ0|ׯ߻wϟ`23,@1Lb" S@`0tR~\ڸ8w߾uP 7TEI`PBAfb@6 ;PTÂ<e?33H מ=d12S166Cs<$ׯ_ _~\ GP@# 6\{?7_|\`/P^9^RR^@<NJ?~ ={7di)rT^997KK'55M11q`;TB\x 3Ф[)S&3l޼ 9\L _xb@3= J3v+9 bcVܔ%5 Oa:u Æ +0n"`+CHـM+T166 %577}m`-֬Yr@x XHJo}>f M+cD;33Vě9PVV#ګW/ Yb@LT+n-ؽ{E2ܿX|#T< ,~8E,@1Qe`~҇ J>S=7 5@O,z" 'nJk]7o&O=&@#PQp-$PTTFPL H<0&WZpcΜx+\ }Fʨ: .'H6KND@=LNQ+V{ 'OނYaU~0ObX,cb<@4t, ́K~8g4pGx J:Xsp22$$dc6扳x񬫳fM&?(& ߿`xlK= ə?<@449X fk#%!.m- uu1L`g͚tcԉ$PL R" 12£i# Ŗ;J!pwqCΥQa 0xߡDT{.F6UCMČٗ}}RMJڶui(ߟ.BOꝜee1;;С @4+fg::L$`! p-3ge .b!@{y92hkT ` rQ `y ? qqQNN. r@|(\v߿2 ,[2?F_~3 Ŀٿ 0Q@>@ 2=/ 0311p3 bvln 0n}۷`> -:n4 DQfdҬ`1?#T%̠ČDW Lb."=߾b'<0~304v٘!|V @ L LAi/FÛ O}g;$''8 f@)68틏?~|& BKGGV@n: Bsh$H qF'/+'F.o? 0,(@W^<+ " ;HBCbVdC¬ Wv/߁Al NBo߾_~LF`1QAi)V7~˃xhRbzъ?@'3cū $$"(}Ev@1P7~OTTA^hϏ:=Ayl@,Yo;//7?$z)f_|/ .44ŀ^ =V&'XlPGAApyZ`1ӏ ߿ (qn`=5 IV?~>AbX~T 3,OɎ 8bxk`Hcx l;rr\||B@8%1X>UT0(++ρH*2Ybon.A3r}  Xdx P+ 0DX$%Aez R#H`8}H N _~B2%" yP6#8e0 X @%$BgTj;o߾a@m.Jʡ$->Xƌ3 51?HM9xlC||=#O>5޾,faE4Xac`fx`96`-d@5, </ͧRPFB@_~@FVc"3 j=/ۙg@ a6HH?#Ͼ_ /V`H_$ =p>|Ts+J}6ۘag8A4sY o3>`I',,,! 9x_? mAPHAE~CJlH0;cؙ6 I 35;-7#D:V{L *̍_2K2|Xq0h+=fX&fP  V< M&~2ϟ ?DŘ2=#'+ qqq0 B6X u`7OK$o< 7Of`>s㋿ f)a?`/02q2o |_1 / -  p!`GX@Pf`RdYm~?~ Ң%@6F`)+ eZ˺ sjp3|~pw< v^1MmE6q~vYA` Loֳ0Yc x5Ahjfx9I T{r!'!b a ocNrfГ @ -e8,ߟ'3=t!ED/#; .pM`?//uwYLOph?{Ǐ|ͷ ?8{)0 {eȲXC7_C^`H,!б?? ΁)a [wd0`eTk; r oϟ񓟯_lg}ׯxK`Iu ~9@azs }Kkf^`q L\꠴ Rop3uTA_F72\=AMYO =J~@֛>{O0 d0|6C'XXFgvղ#ç? "l ,l`x? 8L`@V _dxz}YGP|E B u?< |89X)AYd " ܄/P; {} ."kN7Ew IY3|TQexvUPPP +@ACeב@TdʢܼY B\B`w /|% +0?2||=ñ.ݸn hǠ- X_rJ7nff8?8ჴ@G _ ޿VLNha ;O0?| _âݸZ[0CJ2gee燷o_8zt}Gz vb|W+gw@;Kl$Ā-3'3~AA|cv'n{@͉_2~rATR1f``ac9[XH). /(( l[p}7Yœ߽kך<A.s!o0xEF AK`;?`<#0jOO~ל<| bR _>}N ؞yOV Zz,r" B@v'#3;022APDKKSٳ={Իg$2@pq?{ͫ gUd16a063 􈎩%×Ξ9x50 6F6` Ti+*f!IEaqI`?Ç7XIIV۔AUALJA\R౶#}w6~i_0 3+oݺp޳ fF7ϟ1s=zt `ǃAE]5]l\M k619uآD1 j:& S4L,lBS4-@[` '0pظ o{ FjjNKpqT߿q5b@ `g{S0( pU`XJK3(l/C_axtlҊ <2`#o_3ۚ0`LJX{+D`Tzb4*,~~~LLL9gwÇ7o o?* (3pY?( (+dP/g|+< /'s! -9 . ^`G YE ޿~_6`ڟ]P <:铴7Eg/ߜ7SScF?uV8Tmq@opzf00a7~1>pE>O'". @Co׏o f l[ ٿ?P>% jii1`RԬ/==fÛ_%m؁I_ȠP>c1q Y0H `b`n`'4#`A;7%0Kv`^ <(!*AXCXAR`/ G\`8vShߘ ٣<`lp='}qϠq?aPPZUavBtUde݇ ag0Qfa7$|| " -6 ! B%xr$fذC/p0 u`2vf9Y 5!=;1/ܹ/^=Ν˷r8=ujsKRL)t_sPDOaR5v# ɔСPƠP;0v$b ǂz]çO_3z޸qˍ_>{Ƿߠ$@ЦBm~{މU$VsG7 #~ȼ3#x.dJX}+f=Ϥ)'' t{ן0}'~>zW/9 WO^yſ_&|ޡ=[A3=%48Θ_NJ4(@bLlӳ2Syϗ/{ `g_?C֟-ԏPG ;CA> D#4AB]0hNvFp$N2Yy?Y :Oh9;T & @:L`O(e[;ip##dWD# e8|Ú^>3÷)'''JFb@Lya&;"Ucx58&Ǐ>|  a #oI&Fi)VV&%V6E,߿} +,K 3߿ f33331'yy%rp )"%$"* ,| @}ܑ} /}̾o_Z<%((N.߾}c(Y1cADDϸC]tt89'3+P=# @O>30|gSAEF巜+Ӛӧx< ; 0YeeeçOc ̼@ g1dSgx3j{/÷~| LjcR 002aq{߿߿]z٥˗/*} f `)p!;Ý{Xcc .n&^~V~ceo~G~AIAU` 1fc4…@kD@Ip`q g6>EM~B_ (d>1|﷯|o "{i "|hF ~@dy= PO `S׮2ܾ뗟|_ǯ|O|`ϖ>lݸ "f˧%* Vy=@dyh#+'#X,I?>pAW~}yɉ_.?|?ThZeb?,##??X"@[hl`g`\ו'=~ ~f$bpxC% /~ v`<{POߠR#.ψ\JVl/@4F lX9=%uDD5e^{p]~1ALZARAI^ῄ ;}1G^+k:8e’?Q!@L!YR*zB \| b/rӫ o\aeQb`,e330K.V~^ 2 BL :>ɣ4w:=h3PVT~@_Ռ̄L\kY`o`0&^q`o``vU ?KyV bB,g̮:+ß7>`Z'Ĝߞ 󗉅 6`_N#g6%l@O| )H8iCL@9%%МO ). 7? }bc db+Y1GL@?A!߀m7ᔂ+P `[`cC') OKB&%;߁ys@023kU5J1A<"P XD /! e( fegl.c Om UVXB bD-lfHpP&;f6{?`R;?r 6N#;0b_AlI2pBĀ55;f818#7 >/,@OФca3 fbq A#8@MLL‡,`JGN.063 ϱq10Eaf_)Nnj<$m0bIF` ?;ebL6Ha6,y(  JJ(1*Y X 3PpcG  |##`(z~У\r[Z` dbv6n^POp#%#F$6H2bĞl16  {.' m_<8{AؖK@җ`z %&X  w`!2ssS50faas?@O6K :i[0p @:Z@c|=ypU33bR`Ƞ0'] ?n`Za1!UMQ/^pܴ W!;ňBq?$ȣcklj:eAS凿 ! ,* Lrl!, hcBG`2}eeg;ߟȑ[~}NԴj~żY߿x$%eM޻vf2J3h5?И)u6)???0rǻ_=s_Nf* %%y/2ܽ //'7/;@GrC02xϭۿ12qa8ZBi3zBi`,|/J\S@| @x_:A** }d+lff`s>~@}̗/_nߺ魠к "gt`$M!@:Tfg`x5Ǐ_!?uݻdaaidd(7PȀc  tt:}/;hz4/!ydf^=@<"ء51C3?z@w/@ t: IENDB`C37_KPercentage.pngPNG  IHDR00WgAMA7tEXtSoftwareAdobe ImageReadyqe<ZIDATxb?P0@ y `ddL10RA~?C/~߿~= 2200?g05d`3:n 1U9 " l, G ,!o,P ڟ 29\޿{;O0(|a3Ë{oC  ؀!h7X ,dkoY}*-1+ûL 1?:P 4*(gf6h `+7 7b`_;EB$&&aV6`\C,eY맿ooR0B<  4EHAIYX-8TA[a>3|76YVjY fðz `;= ̸L?`8F#SjR7Ճ:PL2 b Ÿ+"Hpzpm`\2ZT * zu ?>~fa?"c 6ԌU l` ,M>~c`W`xlA< 6 EǏO@sEXQ= ``0lC h jB t; #,X9~2`RfcA3?@ ?~32(*(2hg3  /‰ ne+0ð/fdafp6p&{aVwq5!C`MX:] ) /?~ah^c lN? O?z*\| XCx* t7`ʇoXH!{*pG_>1Hq rrqc߿sY^(2rg`O['s jV`"B+[u.{CArOek֔B~fi6=^)I|гE[\:V?90}Ȉ376X1O.VF^[iaZ@#!aOM"%5&*S h)tﯟ?|c`Xr32(Y931f& ?kXeb&9iM>d95?3IHi˘ S^}ccsOa?)-n7oz $OXjL~qH:|UR~Óǯ8^ ' ןz 12}Š.Xodg}0Zc>}6~ ! JTA d+_ɾwg&0y3@c `֏n3{{&NHjukۏ3Hqb0# PS/420҉vZ1 ?:/aP}2|d QBLLs~x e r(31/`724$YeAecĄgw wefw^C\-fzR l u[~3;,/0@3m7dR/F`#WAybW~f``AHT(r6@{='3sӧ7o,YVbx/C580I #nɇp;5;Uf>@ǿŰ6/A`cF07(0g # 3hex7/}ɟ ׇmF< -dc왙>q8GS- `faeVDh c`b`p~!PeD!.Y>Vmɿ v}>6#ϸ.>p `/Pa/*w`,|b<(D~3H3;D @%''=Ƅ7~]P~wz`3B?[PJF29RDg65?+XK /@!p-d ,vkAPKbY?;U@|p`T@,l1Od@!2Ϸ ;!R}u&wM`KF6w"2 , VJzgdfGv^ lKC @V1 A_ ִfd@_b`:а3#O0<0<| q$NAZgXu?ûϿ>lg01@"2^((& X+f1| \/ҿ CHTOܼfb t,#N`^2/d > XɁ$Wl͚5 @0Q &P $6b`030K3X(13c8=ã {ҟ^3_N.`i؏V` 333L !6v`!.f`Adfai &Xq' K ZY?@y$!a1y>p0{X򼜌0Oo^s߿ހzi3}| rL , B | 2>~;/~0|ـiM(ġܠ. + P/?9X*31e-8t@/#% }`#×/~>WA?oFn^npR'@?:11x1+)0 2d8|/@Ϭ >X\}p$@#ſ. T=dҿE#??C530(Cn~2yk϶Qo?a7?8$Dy>y珟2tIL tQ^+P\x؁4@`|h)Ê3H?-)i``$WL pSWcxaߍ /5گE\߾}5b}WXמggȷ%(6'>}fTm@cSA6l@n =z$MN q*MIP 3RJIIX6}}]ݦk~opz j\ f GN(bRB P)m 3`f Peg{ӧ'IH@ͬ< Ü,>dPab0V!+,X0~߽b{G73sWy^ 6lch bpqay)óEoh4$ ,w20 o1}X%Y@,o߾|< 4\@4ׯ>32,?Ƞ,. k`Zq?Ç|xM]҆HF8sjnC.#U;u, ?&._>a`|E~[?{ *FO<CZ?($c t֝߿>}-,?y |1?ዧ ߎoʓ l|B4VyubzAIAFVa'Sw nO/3}~%ΗOh^{Ȁ)`WO8e|gVdbbfDd`f;={?lZ}n`1k`4˵Oyż2e~Vb ~cw ^\r&oG6(`7A6׮]c;)_bޒCF;b(?w~>;3s..7V<߯]` +/ƿO_q3SA#<bL,l_X]:Io>eX` q/!V  t|:IENDB`C38_Samba_Unmount.pngQPNG  IHDR00WgAMA7tEXtSoftwareAdobe ImageReadyqe<IDATxb?:`ddd Pmi̤*)i&ի_wp3P  X(1'&+ 1v>>aa!!&&oxW``(/?PP a9^GAY_߿,,Νc{FTNIMcW/oh/X:| ߻88 B{2HK303003▁}c`da`AK5O]XLhk ~  de{w` w| *! %*hfLrj_33C`ľ B  =W &NNII`T>8@c@3j0 r21Hq1pq0/0%ge6߀0BB &r=h * }@y@e`%(;P=L < q3| '񏡡; J?U޿f~b OIB@ǃѳn2|cg%()+T *AA? ex ç~|b`Ƿ@@dd&j888rٹ9yN:=c /+и7oas~3(iɹEWnedD_`ћ LO]D_zf±'ObxùOgx+ "p~= ^Nn:V`z3o?`/ΠpK46A o&`1{2}g.Q9%N> /gx;'u C0ȼG_>3; j \:0H1< oϱ0ػ0pp3|!>` 111bbɕI< 7> 0L` ,9bX]xp_ ـr 4;v fbxÕ`reRUV,`ADD[˗O\&@߿9ؘ.>`,B @:R@UNp+G? ̋ԕm<=pן3hIV.{uM * R o_7&YIRHHM\\F˗k`V*^ g."63o E@,' o%o b̯xdey *sPC?E/_ro0޼bu\ < v<ss=!&5`K@Ă`2/G߸5 @ | _?1yW3(ɰ13>XG1V{A/tj=a`xM0c:Ki`^yY>+A_)/^D^@NrAɗYrm%*ix'A Q #(*~bWd:7 a8SMO-+86Y)`y2%nΦDrr9#++<77Xt I>X'P$3Hc 0=?H@fÿ D5F`kc74ac%! @Lx?U oYcPF(lnA0 ?}L>Xn0wYYdi@C_axh+VF^6`؄Dmv.hFFĄd6X3<XԀTpP g`0^<=:/#<З@37e?O lҊ L@?p `{E?00%yb]V,#'<K`BCXJ2< g rb\ zc`z/0~|ax=k1)1`` D`26]D`CoN01 0 [~`<Ǡ%AJ j1|΃{ 'q0z AU';`ɸ! Е)Ghÿן>npB)o`&JF0Z@X/H2<)!,PDɚݝYY b*--BZR@l?q#/,m u1>Av`auU>o/_/. J "\@A%x&@a$R `6,1Hϟ`98dR[2r ?>WtXԥ/&}T\ 2 =JFMkb^VfՊ!gm|!`Mޑᗍ= `🁍Ԉe?R '!x ?4!{ XpDE`#t# ab|C0`V hԌT"7)G@GRRlWPġG<)Ó DR8 }=11!`5ûwy (deY) Xp4XXU;L$ VdYbьt(e{֑C $rBՀ3 @f^@,4K f|LNouAebCA o߾~N??Ma\%A3PC (Pu  `{DcԨ ;w}>ׯLLLDEE!G㙀 ?}N>nNp XA ǃ20-iP~ 5A 4)x5úKؾ3s38*93&zG`Op%H$@9PA4ZP<l} H1|p=9V|ܽ{/$%++`Z\\LKKKihAkO`H|Nfgb`l0H/4,r P[ϥK?2P GV@8&8i33vvN-``Ǚ0\Ί J/_exÕ+_}=sHG2>@ȱY vGqYY93f4:93?ر 3gN>q R&@ 4R?RT `Ϡ=!sw߁Z;@6+L '{UDxt7z?P"%#KdT1~gd>]7tHDw|||1oCG܎2 fNnmwKNF>ۼysӇZBv3@5YTT )J`U]Y4jz'IDATxl 0:6`kCԈ*q "|qӌSQD'A@wW,Z lSծ@U7p dOJ+SI}y Jce ٺ,\| B |, l ? /dx'Ï~=xic;J1@A2 F2b NZ$,f`&`.Ƞ TR!S71ݏ ^}J;4ҭNJ  {hPEꂌ &B | DhF  1 pfol#C^{h& { (,~-SRMRa2:;_@|xÛ nfxv-0b`cd_p23ȩ1H11=4K70Xsܥ7/@G'"2@3X٘c|<y>2}wn? " "B bb ga'^Ɵ~11`dfP3aec?v!Âw޿~4@Č ҭ0`0gx;_1;yA+,'30 'Ý{; 0Y2|O Gg3>:40*3i2O?ox Q@Bbf.ĤfI JKiYa'?phyGv1D 327, L^l /_f+%Sc`ga01`P{v30 2`fgpdz-GXN}~3 G$ Ւ\ l|| ?00\=Ē ΎΞ .0X f^AYҕ JR8pcgfg/`fk85` DX,jc`gx w2+220lݺASS\)NCAWXXAUUAHHb˗/0_!22XAOƱ[ fP`n+pkO?95@}Ev/@13C j󯊍1؊[B 04 CN: 09c X 2 ~ &%SpLrp1 0O * 1f.pC?Cj {A8 _ f3Ve O0f3 iP:SSScgNHڇyHHu q< 3B @@12_GO." NYQvSG>j>s3@13= ̴KdT-nfax;Ç'ʲ$i#AA{Hx"6w/ԣPjyDKk / 3bbx=Ó[oIi>н?@ &H ĿZMXû oWb}%TA8# C2*,B</y93#hfg!jX|>A>UOg/2|& c`cKF @@=#Ve֔'0~81'3}\rWX 6ѓ$@|ꍃ 2g_x=P098)  }A ''͙>r 3}l;Cxx 2\S"B  wO?q@E/6`5` w!ßAX\T;>p,<}ŋ j⁊JxRyI7YaϾg 8~d},u U&?:L%>à>C8;''<%ՁmF`l;8i /0+_2̺@f ؀no؁3g3\qކw`PTGlƔA[[a.PenǏ?2ܔaf0O}99!`J` pq ,D^dϟ?vpu|vV`373'@=l5@ rާO|_?`i"((0mR󂮊 7n`ყ30ĥ :d>.'Pr{=î93h,?ؼdy ؙ3Rl#2rT'@髩fPga UU,-]O`3 hP+0Hzl? | Vdd!)X2?hFĉ yxx**AE pA x+× r s3?X2q1pʊ1<{' R4!Wiİr%×ӧg7H;?C߁/@wP@zx 3×Oߡ ! 4{7͛2p7 (Qc'G~1+Y`'o@1z qo& ''mPhxοhx xr<\p=Xy 4t1k* h]zۿ@EgXN|g`g'`I ,+W&(=w,E ï3~fe3E!K`'8YY.^x 32pP=t]u@Abx4ý 7o>`X|铁ͅ`π c`(V;;YZ2:800x ɓ' e5k 7;XR* 7> eR<0Ƙ]d_mSIf6mLL̠! =P}IJ'9dxz+6Bo$X?0<X7;* b ֖6DU aMNU$ydC ,''j 'g~Õc@t_@@0313vLOl_@_3؞yKٶmavÿ `kiP k`+`H ( `XeCbT~xa{ Z ~}e6^'d lCqJ3hZi 1NOgwç^1`q_$C!bMfVͰy]`s]\G;v;`7aag) @_ɼyݘWZAFAVX/< , 1}bٺUP8灝/v h >d(H@.5P "" Űe{,}cd8{'Υw 4; @ ™Mh׳$$p] 'm^#co2LL  5ؿ, ,0808q%yf 0<&4+w?.ϰa#6IÀn|^bfF#`>qrH1Ȉ21ZH0|Űf[)fgw;o¢(kPPshXuA%Qen1I3x:u ó:;K(m@x(~~t6Q^)`L 2I1l\{ʕ 624349@c1++G&w}X\}=bd}?] \Vc+ 34w8_w ( `i%*po˗?`wPʕX /`vŠgg !pÊV/{6h)h,اA"VPNbð X9h31x00K20| gO=fLǬ6?' 8طx nϿ| Eex?|! *-K ˷~cp u%+Sÿ?2/1%uD?r 6| Al  "$,<,^3k?~{o /]V`7ԄL$Sȉ a8[_ @/Dc3LJf&%QENCnSKu10;d>ͱ#&D?o3<ضa*@ iLF60Yi0Hɲ11h)032H 10\쐮OݯA3Fwp/!9>x_b<@x@'2z1czƅQfbb``bd/?yT~ 3w2u@{B;P1*LF@t"S@6 UH~@G?׀PdI@e­ ]IENDB`C40_Mail_Find.pngPNG  IHDR00WgAMA7tEXtSoftwareAdobe ImageReadyqe<@IDATxb?P0@ yА@ sBC3Ŀ`3Br Hrh b6V_?pH1I` XZ`/Ǐ?Y""\zJ nfhs8  yXک/߿R Yj wop1ppf#C7o!\b~S%9l4,޾pGH?̚ ϟU~pa?k>@Y37FQQ\A[GAX `'pӋ^^LMDmp_sYXYe,4$X6JK10\ 6> d8t^>){?&B߿ϣa"Ϡ+Ϡ&u8++?0#ǰu{%-.f߿~2õK:6Xxs1vo, /$ϣ`b #e؀fgc``ztm?&#hezښ @Ͽ~SͿ~}JDo`$"*Ȭ`l " v,s=Lll3C=S'?3X3p1c^zEY W/-رc;I3 8*3ء sC/0=|xݻ ?|XXcbfPUa F84T >Ixj~."@'66vMUuE}U%eQ~`de2//@=|K b"`o1x 18:1 0Aå VN޻Dx})> ZS1I%CV[WA@A^^Lx~%2HC fxo77y>19arwh+pl50TX ~ &*p-pq  Zѽ]S/^:v%^bpT2&38ef`|qPoJ/¿!_C Š8nPH  R6Aނ* P,0(j9  pČwLܱj8dՔ0OKf`SeKP)aM3PrdU ^`#(׀WE etÏ_>KgS K_~\p3Q)`b9} +٘3pjc6H,AcZ?R@ 1d26AE9Nb`ظ)^^6˗( <9Ƈ,,Ws=Z  ~@7P 9\HI?VAdzA4?hOo߿1 ťϞm\ @,);߼}kcY bu ,E=01 r<4O1x1'_1pϟ{߼9 @,,:|AAD$+Ϟ>bUdxA:lw7QL)P{`z ̾sօwMLL? -23LcG l0\z+6`J2lR ٘ >8?k>c!ÓgO~@Č>ee?; Ϟ;u/{[ׯ0z̎HGH u Nw/:|qI03 C 0[@xR^؝;&ư{w`t~Lf#4/0yU |=p|0 D&/ >ŷqDd+ߥǎ_kpse  /^]m-->vNwW`Wr_ 'O 4qPw *wYY>z^AS \,a K+0lٶAG)SV`%37l~bï/@n>~|\Ff&YU-Iuqc&^k+G7c!i.Hq!`Wy;ߓW״c l^+/o\'a%..asg`y`;/fmۛ,mJuy!緓4vA4YA#k1B?`s@QK$ZV' /?dxOL~_^?_E聟_~}۷+? (S:X,]9 )`A2[$t>'@]et#sXy 6Z}wǖ|yvݷooހ[@p`k(F=Lr,?CuϹꕚGe!gFfpTΧ,o2P[d`}˗1 #R ~?Ȧ,~rVx2 `c@@16lMl?CւH[@>W y][ T@|6Ão `9vZRe c7L@ iVf'|wm ``X?gPISf1 A/C]1pѴb48>ާG04(=[`)b?+@ж<#Î^6  { {]X}I*bUhȯ0M&[5IENDB`C41_VectorGfx.png PNG  IHDR00WgAMA7tEXtSoftwareAdobe ImageReadyqe< /IDATxb?P0@ 02228:::qpptrsskc@:_~۷oO~K/X 888X*))m.))RPP`/IR;I2333<|Ǐ @T<@( @ݢBL 5S9h_}/"J)o"b%aι*d c@ "ZfF^ugL@1. yd!,:M:|jizAVV ( H @adb`H2b_AWGL,,`W"Xx &@,Ĥab-OV..F`3C=y*ΈĄ6yV 0 b8r%3OJ`` @XLb 3%Q1գ@@_\nc][@,bpAXE~FV! HIƍ ߽col;XCTK^Ă#_ kk2xL/P: +ǖB/_2\fXjf&&o0D @1QbW q`2ٝ vgAI0p30dBe8hv)`HM`g<ax۳g vd5MB߯_D#hlI HʰH4 0Ӟe tMa!ӧ LO00| KPA(i<@ϒZDt@0į_!m##H &-[Xŋ ?|Udxb"T ;Obw/S_f#a0@4W ?9 [ &b(Y$NJL>ee _A s`?  Pf'S@`>e:;0}f0LIaf t,Ëρ+$*B<؏GIM B4 }0|3 :yAԔAё'0A2<۶5RD= ԍ[$ fB[; p``q\QCC?@GՀ*c䓓?~~PZ%%zB; lf3c$A4f@kqb+ @ĺ;0ݿYӍ $qPf6|(cw^t?:l XOk@? -``cPALQlh}t@dJb/yU~`=t3`W*2"-dVD 3H#qD'II`|L5:_ 6EB0'+ 6ÂB`@m + f 67aKBB%aӮ1Z J2 *q@O>f/^0|C//` 2#t@,fXB12.-gla&p z=06cyFA\J hh ?<@,6%%/P X 9;7ܼp X*@dzcʹ'?@8FɚbUUUUP93TAg&@j@ m3Q/34xO C0@xsԚ#'Oa`?dHsS =˃%K0}:W@|e˖5/ gbXXM  4 憷)fNo@WԌO>@w$@<6NX Z,<@<KZMU-[~: .LR)E]IENDB`C42_KCMMemory.pngYPNG  IHDR00WgAMA7tEXtSoftwareAdobe ImageReadyqe<IDATxb?P8=@  'C3xy"@JvX 3 |(#?LVF% FӀh ߵN, J li l@Yq f&xý 13Ɂ3O<322L|7(9pr|b`xh/?I Ͼ#? p{P 8bkȻKͯ*1ƌ \ +8f2 ?q3Q c3 藄\YFޖ/L ģ& *v ܆Q VIW@񀋌;e2VC-#C] o2$aehMc LL XƖbyI.<&7!A2;Åds1gf8'ε \ ;2( ~dy)Ï01,{#o" ߱1H3fr('Nl l_3_gPt  ?bQ$Ɇ #9b^1E)2|| ,y X *Q xfxA 123fsÏs3T:m<`,m#;`Ȑ= y~og Gt~0bY9丟0<Dž%gD$dL6?狛1, Cv$0å G10 4n a L@`_aPe 1 u=`t,1ߜ?0|PdϠ-pA L@ǃB2=bprd8+pUÁ5~cpa5U w |a`x h"*2+p&oEL~~|/3 C]*/4~3_ LL`3111|< ?cx ~fX}AM O?ftCSBkD&E~(#;C]: 'Ù4ـe=3(ˢ&ѝ(â:?+ 1byN(Ј@ ( M`>Kǧ ?!pU79~_X? \B<}`h!0ԁ? 0b8!";3h1 >'@QZL|Q.~N^F`q}?Oo;|fX{ Q~ {3L00|a!sANî, g8>}P9d.@3X `e#)0xyDX 8/n[  3Lؔ&&`Q&q`(O,U;LǃB~'O%~1802+ߞ1 `lL>gׯ?n3D2ְ=1T6h/oXŽq2|:t)DzEf,mt?~+ CA07]-~G_1,p ` LV_e_33x0`e_XAm$!!b?7Ç?-a HKB:BjfJ-f,?Ơ ??8t5/(ma-/ 0̻d3p0J1,4ɠasf\@C71`c!/%}dH agbu &$_ ` 70Bl11hsgj{AV'Ñ ޛ>=2,6@ŀ;#j9~cl,dy];Π!XT6bƀ/N.&6Ug`cbeAL T *?A;9Ox ™R+bNͷ?_3}Pp`2 ,EX~ 0}s2}{a~K).o,z^20Ɛi ?&2,6@f ׏Jg!#AG 2< 7'-+e0û_C7B' >f+[` xP3. &q$dt2NdbДP`س{#(̠~b4e; G2̻ ]'Z[ 9>206/.^㏒x IV=bV7_>gb(dbXz>4+7о FnU~ʰ7Â뫁 j : \ O0h`8!'34>h9Hq<TezB/`'<} j0fVFhabbm 3gEb`a :فi!Ë ~904ZjWvgQKE`YG`{_ ּ X%hÌ!Clp þ GBfG  }eb8 s@!RϵR8?h3p|`fR'>kx胒 C=o&Pۆ N[ ~gb> uTq< o<a~ .&?pc@O$ ?@Ɇ>CLXñ sNVT : nb, ˌ2ğ8/00><$Px ~^𑏁A o d0<􄁋 X00 /AW 1 g?I3Lػ#b" ъ /2h(d8!/sLJ 0@y@A_A1Fߌ,,Txx8J#cDDj@lVfgMMgGo_>1|bXtA^ö'L >]VRg?P5a = SHe`cbTgcbbXALAIZ Po y;\  ?>dbH:y' ?*Ct<zM *V%4XzYCY \\ |a`x-5o y_ 32gr1{6x 41LMO BL؀=Z>` ?a&o WŰt!v@j fF$DڙTEg,+0{1r~c0ư<0\ebH,*3>f  3r@ḵR[TG ,/iQ@i6\a&de`9q/yJ@а=a(Xˤ?S `;Aac=q`<#C&`is l> @:47ø81peeǰ #CV^`Ql> @v)!TI_4$H 㯽 d|16[ADʨ$92j2$c {p3Z"uXRY5122 <,mѺ h|^_AZ @Ѐb4>x0 IENDB`C43_Trashcan_Full.pngPNG  IHDR00WgAMA7tEXtSoftwareAdobe ImageReadyqe<IDATxb?P0@ y >IFFF&$`cMo-a`fe`fdd`ϟ ~bÿߏ~USo!Ʊؒ;@18=rw3?Y}T8Yxd_/_~0|wû_`~'۫.x b=@y 4~,,ERr B "`+ ~gt_6첿 @u?fÃ^|+^puu_V" G\'h3J20sn>w~2|ϟ LU_20] %! )%O0\y71ka#8=@y X ?go/`$ң/ /7@h#0 7ÿ?d07x~^.)i um Aan篿3psfxy!t+@@dIQ99^* * f8r ów?fLJ.@?|}ǠtAI?Å' O 1e'@O<?g Ove u}s#F&g/3ܿr2ɺ$`t7ln H:q_C@Qaו }.0`3O ~ :R o[C`I ,EX89`Rb|ݻw ?~?ѿ@ς Xz?Û@adu c z \  n+]^S/1| >8MsrrCmb`Vfo߾e7+C8òCioAee$oPX22qv28b$6 S FdR`蝽7y3?!^;\Ÿ! jpUIc013Hq[1y+ ~2H 1H[2ׯ ߿'NC"o`̜b nq0yoȠ𗉉Λ7 ?$B/w(XޏP0*&bff3?l l/ʹSֻ7S_b0@∁$!C,rx.p>grhRuEuL#e9wNߩUD6Qh[LyίX8ȣX H,vA T |2VCM>.O։4[쁹Q97+^0^-+0,cŃk7{)j~(Җ6IUaP`b4XLEÙfi&j)_>c0UĘua$H@b<@/`fjq= B}: =̽ 0'',BA5%4ŗ@!x@b Jb܌?|`;g30ax3;`wz!Vn`[ae;E`0= )C̠Z=\R 1\aaeiFY) wafo 0ּ?r3` ""T 1?j`x&o>|_!A!XA^f,z?|Ux ?csJ;A|P{?I B, LH?| L6 7.e^~;IAP37~ l y^p`b` Xq"`h z WpDew#aFr3;y?>2zr_ gd6@r!B%TL1< AMw0J7\s0 n 9501~1|J` "` lnvH22Hɳofn`/ ؅^e1N_ef *&LR 3VB |iP vw>5!QM B`EX3[>@>MAT ~{jv30#31{ }w< '~K$PT&ɟ r<2a`2 *K*u&λ XOpߘ_5i$´uQbR'>!wϒVCĠOg^v@J!vk *M$P *06Ԁݫ/ 7 ղ+?@}epFp? ʰ ??ܿ4/{ID x͠:' u}Еw@ |̿dEy>~m`\'p0&W2 _`RdpZL@ +@`sPuJLV +z &By\01Gp;Hm k9PC6.hDTrHFp/@c,,HHQ~^>nvN'} ge`g q;((j9XF`F[u-%$@F&@ oi0_01b ̬L *xqQ`Bʒ`5Y$Y2_LhL@:l4 FË!^@ܡgw`2y=÷ ,@| u|| Ps=D39 |W@0kb 0&d^܄ġi g(B٣`|z&m*|FWh́tf*p"ϑ#2ƴf_ \z CW0ps9 "00 7Ã, ן|ex'O/~^~06A'3 +=av`ʋX1 xe6XPX|z ߤ@/FXt##Ys%npP첁6,\ o/G__Yv`ӀoP0J*N`Ϳ~ >a 2% lN y|ע'o[xMdPe&!P_f.?Yncg_ _}gxX3,0h.p337pӁIAn`- w~Ǐ?n 36'G;[!4̼ `-()|ee>`EX9àn&T:+8#/gx#{FN~.f6`LB߯oV(?-_.Go{3hF@  nf &!jxA=ИС'C_"+4iNC*.; @zgء Z80C1#@ h'GRbm CI٪FIENDB`C44_KNotes.png PNG  IHDR00WgAMA7tEXtSoftwareAdobe ImageReadyqe< UIDATxb?P8=@C4=@CFFFx [1SьQPFo=~߿+10* aH``hU?|R fhJ 02rp3233%,(* p*îW1raXp?óO>q ïY@1ׄg9a?޲0iK܇O nJ6F=}W_<Nwݯ_OG~1} +wg$_gK O lR(fh8 f e.&,@ K7B \V00u{@>ԚPZR` k$<6E u̿HK_ @J֋Hem9UX @%~@=񉙉_bNa KB8$0|," =Kj¤k N1<<~ XKNVeyQ;W+yqQÕֱ%\:/h0~?l@{0333Kh1H2'` l/p=73 0E y\CS?{ ox  f ]P5t0)YR`ɰpFC^K?lcDKp q`Ϳo=?tX 0_h  ??@axQO'x(FvWb @h1KGD{KѳB@lDzSohge`8}WBf!FXja|t|kY_) 9kԯέa^!@@|  p@`eaAc FD_o. Z2 84Lsf6mcxc@ɓ@|_'!B'(D k#_ qBi6OVVpI ?V# JQXq mf`|~,#ï,gU;S]S@| 29@(ϓ20=u d63001020@<Aib6y XvC0lh?dt !?n] ޾k5Hc# M  2p22003si~V6^Nv~.&>>Fv^.fV.FFfN&FV&FfnF&bf^&^6  /c& febxKfoo2~ct 4s 's_RadV4 ꪱcA. `bڼ 84'7;73#ٙXؘY9Y ՝?f>z}0Yb t0B6(̈́F3&kbC4 ZAlTˠn 45G@ӬL"5G<Ɍ&ƄG D~i; D7@ yА@&c53IENDB`C45_Cancel.png8PNG  IHDR00WgAMA7tEXtSoftwareAdobe ImageReadyqe< IDATxb?P8=@C4=@hRP߿ad`4q!P/#3`#3; d03V9LE@c?yyx L@n~]Vj"0p曘0p 2ܸrӧ:ll@-utdp|?6V֖?USLSl |BC1~b"xv.pC2|bPt! f斿x-72R'O`z+2AHJ*' v|7޽ ?!ý~=M DE䁞&)6<`z_l˩_*w#9AHV6 l`:[@%:*AA_ k0030-[᫴4ŋ hz}$8>!iiqj233|`onf`a`3-ῑ02}5PYĄ%ZSx Wع7`6 x>|```3Ồ(9=D y`4UYMꟀ+.f`* _20|WVmQuu￿~a@W E… 6F;&^^2]$",Z20Tq|00,tfQ=06XA! PO1`&'x&t3 K ~300{AdD@Oܼ'@섅d&JV`( nK @pKW1" dfnў40qC<#I+h"g^^.Ubb b (6Q h߾1^ l՟;? @5q_`  jnF!!eh\T}*7`rLt+`-ZL.2@bnj8X"?og`v3|zh Gjҷo?V ̠gwmm ' ,AA+W~fc~wJK:Z@GC k OO,aagOP@O0=  Rpx0AUz?iWط@s** vb`yᇦ&ٳ>"9 &faai5kS`\WKH[:>kk3p-&W |]4ٲ\[vK?"; 1kQ0扟 XwXcg{ ţri)QX 9e>ׯ͞VVDJ6j_8{3y2?`H338J @*z%*@Ta1%֞ݻ>}@axXC0-c=׶-d:%@@aPLռ:X@N``AA 0P'0*AI" NLP&3= ~ӼXD3f{0i}oe`x?_LﷰUJDI( .%/ӫ@ږ ذpO`C^c`J_&@| LPH F L6>,#lMM%`y ſ DzX2+:pL=Ma@ǂL`(' ,u+'O[=+܁gA{!h =21-rR:0/ P6t瘁VJ 였4{ `ϯ_5,@Ov A ͽDR)r?P7KPCA1r,8ԡ>\Xnk߿I R-,8ݩSz4ƊD{ 3m3>(x<VA^@=Xc9& DC ?*1Ñ<=0H po ԹzBa8xy A.,g`?Å`ʨP|Xb? 'Nexre`RlBW@Jnc[nZ᭷7ftuvK7>,$CGE@OԀ:2JАg&1G&Ndxr`A7 p߁Hk2|`&X/؉4|ϥK ?}Z%cD߿k;7CLfdxq`I  |5O`*ӧ wnX2q= &w>GI{y WVf`y`=r%k@!r \fF`z[X662b`VJgΞex5Q}XX K>+'W.gu7C 9y" Z`3`x*4$x0Â̿nhOtА@ yА@Jsք6u5IENDB` C46_Help.png6PNG  IHDR00WgAMA7tEXtSoftwareAdobe ImageReadyqe<IDATxb?P8=@CFY% 93b?@.r `~π Lemb/ 7?(3(2WaߟhVV=N>fAA^N. ~aȗO_>߾zb-3JAu@@GgC,C_AIAW_AQA4!/@OO_>~GWn3gr ï8Xc dEX~=+(X>|p!g`E6!pC~ S\T I.0ǃ0pc+IJ  LLyO6x3+?/'d/~1 3e`'=;Xy:NfɉNep3I>~g(CC~+3{| ;pDx pXebl$xPil"DJbX@?dX63iCj&  ocd&(_0A֑]_ `R 0jW~#m&_gUpI)Aۯx03 2111p5'2Ͼ]r@X:H1)2rpP> _=񋁕_A q`H pu$ 71$R<0A` ֺ 0)Nav@___倅 ,((2@q3@a6~P6$x>}&,;VZ@cBTAVN!C4Xga35#ANcTy,yaŸ/#?>Y/5j̹ĂVH Pʹ48/4t | &mi\ +7!$T_xS/0i@ JF! n>Ȯo8%$XxY|jbA˼z̜Ҋr2 _1180|(_`&agDP RbT6-4@E-#X#<({ !'}d'j_o>aXs;էFay?ro4A!_a8v!01pՃc _~BjkXނ%O~wz] @w5Sv /`_29!ɖX11E?h$ ?}XCyׯ yR JZ̠=cxH@vl[q,Amid'Z'.bffЕbдfp2T6yRppr0=o R") 6P eсfN`:dbFv2@gbnP>( '}˰oW-6mIQJ$"+ΰN:_|< >a(y ,@t<(0 Pvd'Z&773a/Ƴ_nH0X(2q1mfp;v%66vϾ3N- 8o߁+ `vC+C*Pr5*C33L'?#ʠ$ 0,l < _5?>~\c: - YE?97ʰ * &)P?{Ň3{]@9NVF_Aaw |aX{ yx83<} |b&#"vA7n$c @`dg`8pk_`106A1J:_ L@}&:\/z?0?pO 04;YX16O @Lhg`gHT"''xZ(Y ( ;0ɀq%N ~f H=d'Zkҟ|Xo039-B ҵ[LF,L @K~ D:G* +d %dz>032p3Ar.O`ןp_O~G)PCWrXrB >5"; `013/{׏_80s>x Y01 8C >0\fl؄,~ Hy`lf`g?=U*ǀd'ZT1˫ ҂@= xg'_kMZ WWk23#RnGqpX3yTd'ڰ!ȀzXuʋr@/j3hHaE24QaK:3ɡ$C$Ok^Vv.v@̼+2Œp8۫/r"+ @J 3l$/7_ mBlĀBKd (CPT $ޣWkT5W302I1ps@od93#4E#+7vhVC)mЋP1OQ`]p f0l}4÷O_88X4d!Cȡ?~3bT|6@ge8zT~Qy'%i]ݛO}L3$v,_^>mAcA]N "{foyл#?6.O a{ X00Q Fn`ȳs 1 ?nf}cj~K`%6Pc;ЧK~MpnD Jx!]"A ?.&9?O_K\k@S HD{ (R_ mN^YHs@A#]i)Ж{@@| hYP7h=@C~@ yА@T΁IENDB`C47_KPackage.png7 PNG  IHDR00WgAMA7tEXtSoftwareAdobe ImageReadyqe< IDATxb?P0@ y( :{M2מ  I1;L!M.ͩ2\ln N냹в&_ijEYZJ__99^/ɦfbFZy e/Y̊ljJL "@a` Wӗ=s>>jpsL`I1ÿcO>~񵗛|ç4%@ŏL̰dWhw ? d<VS 9Hfd-C>ʽ_SֽowR^ 7 4[ZȈxf L__޷/\->FAnL01 0{prB2;_|Vu`%g{2Y(30|L?! O>d`1g` : daz@2#j?禝} 6!0 9mw7?20\c 3|Π- -/'.̲<͊p<+"V@bJj_0ٻ?^ɻr΍!D s|R_f;W1\{ɿ _Gm  RJ J < #Gi6H0cgw2|:}ۇ}n趧'aͭD-5l}TyJrg{=XF^ <Vl @c$/&<`<} Lb?qik@#_26 1y?Ojחag<(ÿ_@eoϟ2ܼeIE1`z?0cDK@/ϨrTkl b1p˯ ?~f t+J^3ܼATJANMA^]APFEZJ;//zkm?awʢ7o|} X,7Ъ ;103߿c 0ygd ,pg44eUXN`.^=a|E ]ĥY9 r W. F``b??ـNdaa"4U-[0ieyu % VH?.&/Y^3Y}cgUn?dWe`dg_;lf, H1(1Kp1\?LP+vY`?P(p$oQ'qyQ^3ٶ;g_vh UDtY< Iz /_|c81Õo^ Fffl*@h00c`| 9JQ&`Y=7? .ṣ]:V/@`xu? d8w5_~~+ B L> ^cï/03|b``f`LV ?ýwxV@_ @Dz8e`&`*7 '2= Ly+L0a`b?o~ %- ("40=&5F&P6_ & eb\M{Ǥ]Xt~d8q5;߁%_vv`2fhfV!mUI6>>` 0)QA 47Mw (4,+_p?=XCLOGd' X/Da Rw1^ [/IVF zBl JJ`\(EVxc OI!fHVG0FTW"9??69X3BÛ@}?ztD[1Q-Ke+U cQ>9`- fdxr]FVF`/ 9 +,,y XHv᎗3@T-դ,EuL>X11''1P ZbiV6n %g c[-y{Yeq#!nqf`fb#eN=yzӻw*9hx'8Z@n2qXX+=(**g.iΦ( &{N2\ۍ{woC~hbs+@QX27'?{vwnP] яs?b Zz M^R sClA~ϡj3ln zx9yAc:d Čas+@16'悃sIENDB`C48_Folder.pngPNG  IHDR00WgAMA7tEXtSoftwareAdobe ImageReadyqe<GIDATxb?P8=@,`_02R@___!^^~UUO]|o߾g={5=@,VV̜8K?Z]|…]vӧ>͛7g^/8 Q+50A˗ |ݻ}P\HJJ>c#((@1|1ܿի^?xp§Ov<{l'A yXȻ{\VW3ܹso~Kd+>r@z 00hZߺu _j֊ՊQ~~~`O@8XACCA_߀ի@SDKT__T\\./++ h2*1fihh$ ba& RoJLL /^d}GDqG3akxxxTTTwbM& &Ǐ ex0;;_֭zKP> TDcWYrFE_?4T?2xΚð=m)PgX#+++$$t`:H01] ,1;~7÷?0~_dKA0`033߀?O</Ì ~5sqJ p1CAMAAAZ֫? +D&o`8X 䉿h)rr3|Ё OϾ3\ǿ /2p2s@0;$>'Ñ_AS] o߾cpܻׯ_=@$+'V=!AAEc ?,Ul?R dP>ʠsÄ˕m7κ?1->.V. A.]ev)Av A.Ymv|VO߀477'ûo? 'lbx)N輧 , EZ2H0Jkw@~ (3f p 1~ebbTcP`eaz 2~{B Y7 0_~ Lv?y F0䉏_w?]g``pـ KQnYFl]&)>fnQ>6_ ?~ba`:_@Ǿ Вd_({89^/L0+A-دf$ˠ# =pqA0`z4$߽hPGArh2zU3@b h;'ë -@|z@|~7z$4a!aW`Z. 66\@ n.pIO'@j? ,o= z?@A<נ ̬Oן! #,!Ȍ`3?hCX:/D'4@$.*_~0&*`޽{wT3} rC@Z oɉX#;AXr#a Md bشbfan߼ׯπZ@i Ç?t<,!R;+;4% #~eo+waW?2b:ԨB9,Jk$)AJ><Z*>PI ŋG 732ȩebWW@1@,Ϗ;w_~Àj8i]XCԁg^A?d 3"%WX, ` `/n`2|{㣯~}+} Dkϧ^g va(%?~ %&pVC C4{NP0ëG, _|a`X7 ]y mJ E黷+-py ;GTXi6v@nR#h|Pbxw k|6`wǫu'\VI 0KG޼*BqZZhu&Ʉd>l+jg3^&1 AB{~], o?Ҙk4xO 娍/0z쮱5#ЧBx}v.^Àj?PKA? 0Hpgaddfـ@r$#4F`2H@!57Г4?r1z|N`2므A<@|.$/p[1#+/7+/' |'; YE2#4Gx?R>a&.yG ;ϗ}Σw51) z޳ᆱ)4 M1 9uH9Լ?G`cO`ă[v=c e_5 kSomHH:7{/.IP eU! 4  __X}b`؀59;0vX!=7>zC á/cc`c~s9#  TuۯPa2O\?N`wKlh|zp.i0g ػ غdLi壗 o~dШ˰C@O=/_]y 0'|h D `GbdĠ}P0" P@ `-00.{Мjpl ge9s 1cd|sˋ_?0ߞ}7_ go?6401B?R?倱FQ ov0 .^d#Ϡ0 S#/ *xŹg @zw^W'&`?;$GH;`-#3*@DŽc`8L.xq!,+CÚ \ <].p흛Z|B Tܙ l?0ÏMfH #BtP&)"B: IFzs_֮Oڋ.e`x?,_O6ʳ71W ߞߐ @c~~rQ&sFFAo.@ v`PXIkh6P+\0B/`C0~c Ŀ;/}w/~2L>}e3oO~{??C|Nu}@q.>9W9-F  L ,@w~xO#MEԨ̙o'þAW$ ol!k5G $;SƓGX?<0~/˿>3| C{_\ uQ G Fĸ \ 3HEH84 o,_'HT|pߡ5~r !@f)AҘA hQ -T9)q$>@Y xC4S62Z|IENDB`C49_Folder_Blue_Open.pngPNG  IHDR00WgAMA7tEXtSoftwareAdobe ImageReadyqe<pIDATxb?P8=@C4=@C4=@C4=@,`_02BxqG~fG_9e ,* gd#@o@l[c0&?䁢2 *l:L,nKc8(q2@Y{`a`gefgbx7cbZLxs"ف "̮ M6^yvN~nvVQ>v v9a Q>%3\+ h{ ?qy /(:T^?@07?WOSN1t!W_Sg[EI)V ^>QQA.a~nVIAeQ6Ev!6aVV&f_?=>b`a1c>3 xa`+Р!SPVmO+7vv&AQ1A>N.)A6&iAvq6I~6P 2q03r00m4С_oo= !age@̎/5,LJl\  .4ԁ ALZj  JzrҟRd&(|Q:]`1??|qq1#542 ȡh䂒ct%ٿ8 ,1yby9AIM_Ki ~OcZ0H3"BK, ŠPh B+x$yBNfbcfcbbb`&w?gvg{>3ymN $] ="A3R 'A4' 74;7+#+P X_}3:@__o=~ىIh((QZRBN + E1qa',,,#? L< L, ?bGPv DcO^q?e8P߀H37R-!:HR2gj$ *Jگ_ :?30d_WMz @d߿F5)@~l˼6=>+/ p)S@'QfFDt4ƀD ?:"+ϯ@7>8ۣ@#^~=럯,e,D (~ ^g!Z'fg5@ }F40Ty iwP!ç<(/__|_Yi+Q?g{@sBm u4, ǁB?fG k(#K_7 ?OGBxǛW??y/e 1.`47A+cw3EJiNdf&h(3B0!, 9X,"_gxp>0z02Ʌ n%2b{o ?y;8ta֝`|`_D +>Ml0D7R k'2|i??=,X1~~P_*qbb@W߾;8A5$#0=za͉n2$Z_8uR~#xXg^2{3L ;C XP<+з;Of,8@(CZC E`avɂ|@J-,RB l:yar '`ŵÝ~*}BU 8$A}S0{XG ]PLA<t'XL Vcʑ  ߮  ?>+0oOw(鼆N>zßX@Iĵ)TA<C`O8<ghfbfUbX r҂׳lX bۣ/OL c`ub@BK&x: 0X#- !xgo&1{ Pd`q&k??~? Tקo^+w` G:^fJCG&H229dЌZT`KB #23da8}ANAAKE >gXf@1xsW_?^@2\@_PQ bAO$6@ 2 V:R fb I/ |d'׋O[5bH_( `c{a%0.@\ %PL 6+ $3f`y۳' O9d 3|+2|ٮ@m <ˈbb *T5 0/ndJ1K,6&VVfbP_߁u/~?y >]X 񯷟~y'?]vc LBf&Lt\dĕ\ X5VNfv``6tXXC _`~e÷}~BG_} 0xl}tGh@iP}~!; y$=gZ J)3| о_?0(4 닯v@!0}G_o> _P$T"_А -2P.\ŝE}?|Q ?1: @MߠQ? '@2Z@lP˾EW$ߡDAH+gS`1'4 Ɂ4s$>@C~ h{ h{  / }kIENDB`C50_Folder_Tar.pngPNG  IHDR00WgAMA7tEXtSoftwareAdobe ImageReadyqe<IDATxb?P0@FFF'ӭٳk>ף7o<ۯ@%bzdee[ZZ1|6/{ϟ?}8sҥw@( AyZ1Ϩq͔5u~Ç 7nЫ۷ozf/^p 3$gH<==UCBB/%%%rSO1ܾ}…oo߾y 3^p@% @Q5 jhhrRΠ nnϟp[n_~/_y͉SNMjDHHH8k/,,D߿1}3w_OիAn ~~:-YAW b PuO5b83HYeOz1mkyn3<} " 'h +\Fp h t;W%>3 c/n`dx UjL(QCJP)=ȥ!6b!]qI1L?RKñ0?Z%4x}s}]iYTlFрam r6=n@FxˠxGnh]A#h@0ư* ߐr83?0&"yeE8x30̠*/t/8 _WA/c 7_?1\00kW`14 @eBGQF+7]ߤe aH6O#i 9Di D= ɤ 걗mVAlt%)|&?a?Bj@@x;-8nZ+gƵ ~ C(gc>ȡ(~ P1ر99cAx/ģ qP̱= ן~AcϞ=yd=Hxo>gg!!\`&Ё5}r6vv"9?PG g< $1a/3|A1:~]P#>@Ŀ_O>| OL@ؘ@? Ae0BFXـi9_4>L( .zIqA1Xg~ h=9 聯?t84(!t qg1\ֳr C 0dG!;/@ à  hp 2|`.\|*R$o~XuPhe?10?=oFN~#vʮ PZIGCOh /VQ߁ɔ ؟/UQH&oty p?!'?7e4аo~^]zOWTļy wF3|f`Tpc`KW:@ہ1? 7,&~;g_45̕^]v@\A݇O?9FwX4.xv.5{ ex{c?5+~00)x0Wb+jBMN bRK^0Xpps2^>c?6 O~0 jc+N}8?YMIdIYC3|}A\3Hy1Hz0|6M^\tZY27)a% q_HSt<̣+` Ͼs }ako@{N 2r <  o1:ׯ ޽56.`NY4+/Ç^:P5K, H?`7g'L _}c gF`Ë7 ]~ m  >`SWrdw[_30G%#3f`da5ā:R@HN)>} m). O0 ?b%+E^Ǐ.<2P#G2|Oo`` ,t]X- A5|6|FFny&Г@~{ ,g; Qn`Iv-r gX$A1L,|~򙑁U3|w ǃ쁿r 610\[t` ,]zI`3[i@1NU. X<\ 8R y&Cc/EWyÇ_*+`@[P`_CRL?_qf ɩFPc-6Nm&-P(3@ǀZ @cnfx3í0J0pr3zm;qZ2xd @G]-f6o(í@20CZ.t$P`ÙY Tr_>[hN@NFo1y/0Y^}(r3|{rABAN H,)8Pa@i_c uQY$'/^1s\f6n`s4ffDQ[emnpi1` l|v-0pC~{,8@8AI?$sŁ}{k#@3pj.2N6::~]Q^>hI ɛ[v+ϡ2@Ab*3:€$Tir"6AKfv$ '!N`p ̵8ppd'ϯI <@z .=eWep ѿ,X{Hi-@ԓ1`?H x&Xp{,! 5hR!pBA}?c`ݛ >fepXF nmx˓'d4 %`:{ @<(<% q31\`kivA2X1 3:@ZQ`cÏ'a АjDpF! ņ 3u3'}5ӗ ٹ [o! G`tȻy{!yo?dİpP300Df0x X}eت ؃n~'2sw߁Uw@~/ ~d- _qk{`ϭU^^]wuuqI=km&e=%IEq`z*oH%!PyT='o18tʥ ߋ1\tcx^Ͽ>#@G_3|{ _Whrze͑] 0ЗvВಓQ42Q3RfU` U I>7Sǯ2\9t?|qϿ[O^1PG|:RM"ئ^Fh03IIjxHIky9=dQWa5RfPcG^p֋W|r{?/`hz G#@_HKD7@adB`1 ^~̟t ks((ʈo_=7T=I: BӬXbh̀DXWО3h u?:XۡgUIENDB`C51_Decrypted.png+ PNG  IHDR00WgAMA7tEXtSoftwareAdobe ImageReadyqe< IDATxb?PĂK"<}l3k׮14ݻ7?e0^@)uvvN55mIkk[`L=I+tSL t!W 돁I߿N> & l@piwKw}*'ATT dw:֭K뀱T9et`. O:å@<L"YYb>Se/_?÷o?+\ Dz7 S`RpU/baa*?!zɓ =_|cPUUe'L&$L>m˖?e?(0u@;X/0++X |`evY?}}#AYYIP~b5d@8c_F0Fy@XX)ft/̱ـ@SeZP^Ag`zA+oh``Dt)+D Q3s?06~gfXcN B`V.qn O22Wo }4柏fL?\ I`Qn@B?1GsHsF 7??ag/*Ѝ9_^f@ጁ5똫&8#?֦6#7#F>AE-kP=wSĮ wzas'@;;&0!.A_p L?qZ6"X*j0\?}[2ݜfo@_@9A0X${A@I$DP~Y38 _!A q0C=LH3 Ç ?ށZ lB TC豿K423[b?0Ԁđ? xAI]N3ɠ$PxXS /X 01Z AL 6H 03Z0Ā <}@*2FH7Y1^ЌV;0DjDh' *"P׶jX.)R&!f:+%1u@pT!18@n2AjρĂw  ]JF< 5(#@؅2b= gS׳ 1)@5f#w>z2b=pң?o?gdbD -'lyo@ P_@L C@NNՅIIENDB`C52_Encrypted.png PNG  IHDR00WgAMA7tEXtSoftwareAdobe ImageReadyqe< IDATxb?P0@ 02228:::qpptrsskc@:_~۷oO~K/X 888X*))m.))RPP`/IR;I2333<|Ǐ @T<@( @ݢBL 5S9h_}/"J)o"b%aι*d c@ "ZfF^ugL@1. yd!,:M:|jizAVV ( H @adb`H2b_!V6>>cqb6@PHT@ za%1l@a$!`$*m|f^?~30 wc+x&&&#={pQPO tuuN$'7\1@$l:dزe y?00xa@cagdd@,8r:QE ,A`͚5 ׯfprrczt45U|pys1DGG1xPŕ$֭[S@))Aln` 10O1# %k>} 3[3 șAi֭[ W\gadb9\ɓ$s "" Cuu%iik/⑨ Rt~UU-~~.NVVN͛1\xfL **@=bfصkW4Nؒ@aYYYn޼ L /\\t@YA@@aժ5 o_cpwweӧR8QQa?^=p `a1@D5 3 +СI XT  1ܾsoCۗɉALLAXXחΖaXf`eczDw +ٕ@1*CXd21|X?f: , OaPVR& #p)߿}ge Ԟ | 7/>ax>|mĂ+`+A+a;B׌G6`}~^"س3x*1l1@$ @BA_ǘ3|0{aW1k@g3 EzP=L b2 iCI0P9N00VpiY^zɰeQ~>|Bzİ%!b!P:jX_LjJ T LBC9@,vlDb?`b@y3'u`Qz$c(s|V4 %(0=<@8Vx?xG,A]?ï? \l 4 Q,@1$h~K_o_1y񓁕 Pɝ@Qف1lZ`Xb21@aIP9v0@1pG"X2p 񃇁/Ăp<Α l1@X+2\ DIm|A#\͗ ,"Fnf`:QZ+#WLr1DRM$%!@X,|d PL.X/ '`KBDR?, s@ˁɆ Qbܨ5;s! 3020\=c!jLe0c /0(ԠBWǖbhy`2\q 3"?R;@L 6 R 1+`@ n0h{$30m+AFgb!)"l="2f4r̠ˁB1v96Jɤ13t\"{I |5,)C0@,sԚz@ax_x D|v!fyyy@n_X 0<׵˖-k5_@6jчnb(((Ѡ@1b ^12{ u 222|آ95ӧO>30 ہx7A$ @[jj7(Y t7# @<KZMU-`x?C`P1)5IENDB` C53_Apply.png' PNG  IHDR00WgAMA7tEXtSoftwareAdobe ImageReadyqe< IDATxb?P8=@C4=@C4=@Ca^N.sPym?w%}`>0i(Y`!e}* h-Ao 44O>(x{{xw0Lpx}` Y`^NAqQ3aQaC ]@ Rǫ:3g޽  ߿ ]\RZ* * >}fx5:h0y@ߟUed6?ưU7޽dbb)D@o)\"| nBb K_^!S])`%iC>A`-ð n1<7c+)ȸ (򚊎z34C$73 ?߿g~ @bddej/0  0c,`egfbed01d/ hz0C,0n}ʰC10~gvF&aUgSe}?`=!C #+s2(C<Ͽ0?&` Ņ@1afbL~|Գ Z Z *& ,|@O7ҋ90eSg3f1daV:X(&0>yǰKs>1}33s(Ʒ4'No]҇ ~ q &\ ,^3uZje. C:1/o~1  46@ax aƷ3yr ‘ R܁^ H47A6QPEsnP+CN$;o߯6{pW_`b`UJ0Ê^3Fzqgau[!oZk}o߿`dVdcgapWbe`/ o :뿗 d8uï[232G3Y`҄K\ 0+*0H 0j13˃3ߠto^1z_ ߮9?^B @a_##.Z&4"(0x ^2^No dC0_2м?ߙ!/x 0c7 )ü2aPe t(#т, /`e N6 oCȹ@3guJO $!ft>3>zI#q)`Ì? :yG+2`#-KFR*[ ,S~=`a l^ae`´1 ؾcT@X3//n%AOP`?p,BT~a) `;;O_L غ3c? gA1 0?,*02=q/)1}c iӽ &l1 310Obz#G_2|e >a8{I,W"Iٔτ30aʼ-N/2|6Ⱦ,0m&7'ebfvG X?c~{ g l0c g7@|o7xu+}f#=^W'nfdtP%UYcƧ Ipz Ok?Ggw?Z""C>36},(rWP 5&WZ@%@712[5cf^X@C~ h{ h{ h{ Cu:IENDB`C54_Signature.png? PNG  IHDR00WgAMA7tEXtSoftwareAdobe ImageReadyqe<IDATxb?P8=@C}tr9~&>6/޽){10NB`:80#uW_2ǭV߾\/``$.Ą4XX:-My}.Ï/7X?10`^υD ~2ـ<kdCc~20x9 ox8tްg @/Z&/Ne.'O9ӗ33 #Q'ï@&hg \f*00C dGO3 x'-B9PIZa֧ ?_g"{I: ?f(4sN!f [>`xv&DI&2 x=۝O]"*R P4zNi=Z`2CD$GSlZp 7 bylC0}yk1Q~I:t0 @R 2egbHd!,]ZŠprd 'K00zQ58@3嚧!% LAOÛz d-Z 쓈> jz?ҜmYo67 fxS1Ԭf?CqtؑoO;'v#@Pǰ%K:AA A~_UZUgdה`ج-J5<ư΁K*"f}}ìo/ss28x#2m5R9(3-VVr ``sg`,6&/pCK N ˦rxCXpG`Wؚ +_T ? 5XaiG 3 })`}u؎_ysf3<0V>YX"Қ s$ _eH+xGԎ <= T/H"d11y1(810y3<|h<0?1|{a׿:& IJ`| HMdNmf⑳a\OQMSdzưw }gF  #@B v`r`8u2îsAtg R<`*`adp']7Aa`~ÿ g=d0c Ӏj?DJ5e)0(27+ >aXч sqaSzV[7Q`&m+@zۀI_]^Sg%l ^z+T 1ВePe8%!RT@lǏ޽ SGw+@aϟ? Qı6l1*>x` a0CC [GfĆ R#B]S (Gq8B-cb/6. /çO89@ &6ɀgĈX;fEB(2o;a"ٌ0#A44f#ƅANV`)@= lʁ ll Lq##j:@P  7H3iyÊ * =2;4Wh+C5v7ɸ_e{%G7 Pր8kQqtT *@9 X70kP`)$VA=rDh/Y` LD%!" 0@< cϠAf^_v'?Y8(@ɊRKM`KcFHbR iA*L0He * (?c,^baF X(?}w4xX )>qv@1N6y9h' A #0 J?x1$7$,~ϰ ݘaC=ÿ_ɇhpiB\)@,20(W22A<Ĉ^vN)APe/Hn90i\{  F^~ ߿gg7/20(LV#qi X9{LZ хGޱcՐ`VDe; w/p!S?pÐf`b_2~O~P7%.g: h/ Wg3piêa}/`)ưkv5;1|՞72 ~~e893?3Y6û?3aXTϞ#exAXa3<}p{,JV`032}۷@3!@DPqm{6]Nx0qieNe5MdX B]`맯 ?~cռ_Do>_am`S0ƙz܌Ж Å!'{Ta¨о (05yylYpy?1MN nW0<ܒp3u4@ݔJJv?- `?G?d1a | g6ͰuGN 0ڭ? "l@'-@F`y #: <`D$!`tK=>e?| ,yK?޿|0>.J" e?}~ag|;DT?$@,ҠzK<{sE nG6|u Q1Pi@UDSDT~x&=]C ]<LDHP//; 䣡Xz `/} j)D֋<Ǎ}t~ Dwv:~] -"nd\G+ vQb%A G3rn6.b" :?A"* Q/*Ib"Ԕ(شFy!6O8RT{@`%' cWFD9% .@,8,b13Ȉ0 4`aa k`VvիSآ??sVa&+͛7A @@7MV=h{ q؉IENDB`C56_KAddressBook.pngPNG  IHDR00WgAMA7tEXtSoftwareAdobe ImageReadyqe<wIDATxb?P8=@C4=@C 70刲8U 1 )nfíij+y|gP/J1 za9Y yrܲ/598D퀲M14``bO1HcI4gЖa`f*$xj8J7X1=g~t20ȖU1+!3`a](!ͤ͐iý& à* T-NȍDw0q-LrYj^c+Ɨ ^!,\r9 |@%@ѷv^ao`͋/A=u025.b[MŌ'2w72ب1De1ܸ/ *_te+J偘 D7pK)15bw }e1^Go2|!"A'G>}ĠiACуA[* Z?0 @@sTANJ2ÿ g ÝW_9tM{)[=W1'7l"0?MDD{xZ4+b-(tG^Gf&% pN6R"|[s~^CjVf-v.dE&ìDyf#cn?`}9ן~2q0<~TIʼ-O_2|b0Ud0Q`g+t0󏿁/0?~X1?x| dFLo'0~awpED;i:)70?`f{V`,|zן `}헟 v1 ^}Y $"1/  ukŧ P) P<ۆu_QeX&ưᢾ $" p@73 L., ,@Gl~c/P \|o  b" bx Nw_f8rob 6^xp9 ğ jM|_7F o0,{+#m`HK p `oX*AXcPz?cADX7 ofdo?2Ġ(ưgǭ_ V"s_?le @7%=`Д{pkV0E ALIX lP/00+.Vpy,MP4"& %n2~Xp1[ /2p ~gص9û#7o0vWa @'Tzީ \ 7^yqymJ3, p0 ـp0p3) ’UeԐV\ ."A5, + k402?3`-(s< #xVyzHn('WyVwc$lgxxTWv @ A`SXW00z:8{F; &S1\ùG[vbP[D1lmq:IJ62)}A۞aY31?`rd$akgo ?eq=Å??õǀg?P ~j3: @ĴF$MdV&oz!}LcJ_W2zk x~dxp%ɫ_ӟ3:gPfmVa@ۜf0NַUe=r"Cg Ͼ0HnfcxG</ ׿ }c8wٿs^}K7[sw14AE%X<@z""̳,2y}`pY / jNw^0?}O[phSh} mۼT4DJؑdqVِgjRASAUA]O Oa8~O~ax>ó7eShH?:=:/B w)IQq[73v헿^zՏ P@}M =W]JȘtg-7;>0_>@ PG( i| r<҅bh94M:;1 r<kC@fXi+!53R4=@C 2ƁEZIENDB`C57_View_Text.pngD PNG  IHDR00WgAMA7tEXtSoftwareAdobe ImageReadyqe<IDATxb?P0@ yА@ &00q pև Y=  ܿ >.Z 12f!0?( ?$y( cǀj$(j#32rC7]@!Kl}J?Ă?(&C$Pal8._pw* Le` I! 58#!bTqdrB 6 ح0W r!Xېp!"J !,Cvq3Q""08jV@ \Ă?##? 30 i?Z~@bGS#yQpi-c Pbon2|yh V6V>mR߿gP>~P#qA 쐒z+ 3"i"iiITCOYY0`%DR$ď88b5̐<-J¥ '@j13 J&Ud`9 %U a^".BČP) q|axHi^*􏔄k=aHrddDx R"*)fh:z $T#%CL @H`ƚA̾&vvPOi 1YXXc?`7obhnnG~12VB-0jO;7@+?~33#G@,51++;J=/a,@@CPcRqjZ=@$ f@ϟ ښ %$iX0;/њ<L,8*hp2bbbҪDdazCC䁿$R)@9RPlXB2 (Z j 0b&!+)Gha'"CJ)iJ۞G0<q<#̉4BPH51@Ud sIπ%ai61X9#::ȥ@<`7oJ1 j(3!լ bҥ +WR^nR#?p,*Ц"F }c8wJEO #LL>1\p #.iXSbRM `D0r --uhe?`GԀVWWȪѺ2/!*>Ā@>;lhףo O[e>q1Oz)2<GuF(4, Y:J̀ԟb PbY^ܨC!G@A@u/$l2iG @x `gS_[O bBmz(L4-=9 U|i (R*`$0KXq/5!? @C4=@C+ͶIENDB` C58_KGPG.pngSPNG  IHDR00WgAMA7tEXtSoftwareAdobe ImageReadyqe<IDATxb?Pc0228_ @o1y7P Oܯ on30̺$F 2'A=ȗCL~ 03' ЗL L w.t*'UY>_/?Kf```T)s%8!4Po L@or9!+Ñ s;2G0 t~LQba`l&u?~ݳҋ;@@M@K 8Ai   f11\/SO}Y=fy'7,%$E޼{pMᅳ8\ͬ8 c+ۗόnO撻ov·I#Ă7WVbzd3Éu, +S`xz ,ADh$0F1y (tU.֌tZz[2H*00cW@}Î+|G |džUb x3ZNV? W߾pHȃo2 uAeudx0Hjp'I 80T~ o&6CeIm;OtO b  -- yF3$No^>n&Q%9` q cJIAQF//A @If.|F`0?P XR1X00p3oY=jz+9@/ 20 A e &L|;hR\AL BpO>聿@ps21pz@,HxdG3bA ,Ϡ* 4h8A @/po`~}c&Fvh`1 R;G/; ߁I'3+ !e=#6 0`_p t_~}o0T. &W`dgD<Б_?ÓdUāy$b??&>#?0|姿?}ڲȝ,cA6 _u&$@"QK'w/$4K$;kjZ 8PT^R8Vd w߱udnRp}>'!+`6LFJ`6lA-ԝ0u/'`J  @~fxXH U B;L Т!fw b8& >`kǁ)XK JB ]10s;0\޾ "ַ%Nk ;30d0} "kVcxߙYߑ yb-Jgz]l_h6"X/ lD֧2_YWADџBϛa- ߯lbػE@ /l,[~ n`X) $=+:z 9& 콿 1q~ #REɠ,-[!pG`epa?_"V4xO]-w|aprAכ0Gق;%/4Cl,ãǟUM FV B9@K z~=O:< v<] o~av{RWA?@GIc`b`q`p?eAFF f0QAX 038XK28A!?X!q3)@,86 G~|C#?R9/"#_4^6d ?''#;SEۏ ?8=fV<?#O` Dy\pOO7~{9£~u] Ąu( *!Y3fbA0kzAA#߀l0|b^^FP_Ûް=ɬB@|PchO>~adf~04mc"Yd=@mǮdu|- j<LLpaNN+ĀWf0a`0H ⋊q2 < b2| v.@k%@) z`ҧ?NiTR޼K_&' /o4%1VV`w w~50>5< ^d`efPU5̔ Xy A NW Ԩ?QmÀ!$L矁I AA݅7>}'vY8@\F fK>| /4/"4R H($m|7,,~t0p0=h #Pǃ0WL o_a5accKācG`>;|)`(@+’@@@0fja 2`{ŠL }VcACh7 ˰0[p r ,. ,wWP B4Û5"` !>'_?Mʗ_>3<V~o2~%HFL xP p`Jn`Ykݯ@t 10$Y+M`{gW?8RP%!6<jO1s0Oan: e8'sLLp&_Ȭ"A(^<nj7C?"5<~wKhǞ R1# 2W` t$8+4AiP,fdxnȰdÇ G^څ0𚙂cOhb A4Z />ӣ d̄~ B1 c2lv@;à w7gR;7>` `b3@i2?#<n?é9y%A_e:O ʼ LJr oŒo/)1h2jJ1paHH!1(& N!#3$#;;2| Ϟ8Ġob32b20[뭵[ 5Ph00( '+-9&`0 t`nl.V__}dxw> {.2 r8S@^4f3%uC|c  W= zز@B6+3 +## l/1#rkf??~1_P-P}3.=] Ġ6J@<Wg`6&{3'MdΔ72]D!3*c`QA` x`w陠3{2] Ԑ戏@0>B_B@I4S@<@<ˑ[N^v;udСofhŋhHXh}Њ7t@;t +4PF@'bdAcG($A-Ʀ `O&,?<J#4@z`˂>Մh9mh 0)&Y.IENDB`C59_Package_Development.pngOPNG  IHDR00WgAMA7tEXtSoftwareAdobe ImageReadyqe<IDATxb?P0@ s)6Lϟ?5bcgcccaeeeddF}kLLW~~1Iz9 v:.CZZOZZANNDsssׯ^z _>G 4%D~ &.aic`ia "" e@G? 3#ï?~wǏ3\pݹsƍ~'&F@n r ?.rfaPQRb`gg?y o!/gXXY؀je$D<` ݋u_q@PWT%eаs3s.NG gϜb+33`YXXYXYgxǏ ׮^epǏם?~'@@˶3(33,÷o0Ic5#3 8X!4#= KKJ22(*(h"NNcǎ-J×/T&s+k՘X q1Á !޽y[`_@G30qP hi /90004ͬ5gPP2te-Tb>ãG~w= G>=:y̬<@OdzgϮbf| ⋬R|zN \\ ߾:pfbddx m?~0@! ʜO#M=lP]D|`/  ].pL0c p:fx,>_@ǃ~{ u?=B7TN@,D"?TUUa9XfɁAEU?>{%-#ɓ@-8?D-daa E:: ޾ax=_~ ǿAo ?ddPQef2TQqn  ^ 2MVV$×O9T#?f`Ewk3x aCFKg*tM  n.$hQVVfc:@πoHC%rb{X۲1|] n<]0i _=U4}S@n , b6d xPPR L߁',_gxzyC6m{)WIk] Orm1==jyyŖ6Y9ǏrpfabFϟ.^,shh02<| -|x5=aS .zP ZTROIHHebx-8'Ņ ?0|s ׮]{l=alJ3}|!X(o A%W a nf}M,WxJNɃ  ZsvO_?xxxI 0۷]z FɷnnxW7yY1 3O` 7 ,y|;m^i;թg4Tko[3og ) ʾ ^G?|!'.]瀭``q`Ih2؋3ϞegffgZz͘u7:Z#ӯ " ^R}~oO@ Ք?yd)ubw;3A18XXEvP !IL̓\o?t#DטU= {PK{iMU^99?/xq7usi4h@K Byʤ$֜ O8N͍ܗcrg?D}70Sf,  !drz$H@zhϏ?],cǯŸ n`ϐH/A^O=F |}<~| /?25'3X=U[J8\Z̄  z ~;ނGi`W |fX(0f1z13JJI'@gI?wW~s~k??3pA֏}1vG^~l z{}{ɕg /e-g`UҖ->COT_DM[ bo=13|{v /a /_^}u' H^æpKҋYv!)W0|y񙁝 l1`bf8LOO-d@ @˵/xĞwd5ëB LL ?g`a,71~p%+^c 4fxϟl 0| W Gp?_N=@T 3歪>AQ=ZB;?`'Ý7?yA@ ghx9YYx8ܙч~u߿>3hTt?4<մF@chyXXd}&F0cIENDB`C60_KFM_Home.pngPNG  IHDR00WgAMA7tEXtSoftwareAdobe ImageReadyqe<IDATxb?P0@ yА@ yА@1( FF'`Q~߀_@=-a35}b`aP+%6=P %X8 ;O8+;CƒJJXdy`}ڶK|C}EAVf6Bh:w&|ۓy !Ͳ݄:7)F@Lq\N:M D`jNP˷{ֿfm/RZɫ&Rz;*h]7xnҩr"<(!3R4#0Qȑq5v)* ' 0iq(LP/OW'A 7;mn@ IXi9,cR9E MX΍$wXBm;hSuGԏ'&e)6F/,ABNYecMrS}_z F>0{ك /_`'s$tݿ6ɥ : c`bbbxz8ã[׀A)a)9gX?bpUaedg`ŏ@G CAtObX ^x k؃gYDfM0*k{:K%v圪 -֛h5A){xw,.K50nB&dHAKv#Y0ޟQ ;._wH=R =X/>M(@}`B>F%9Il< -,"D j= YJ]+0_fhFtoJ<+Pl SH`mo0"XM,1 NDw I;ˉn1iRWRN[!*U}s[Ma-<| u0T4H[H`݆u67N"ڪRωIb<޼yCl{u..d֧1OZ&.iċ#eY :l9.eeK=ۣhHC"t_%mOEYJxiq ,q݉ń۽Q2/*{(? M'b,bL0uӽ73gl%1MQq:6M;l.bGgk6Nuoh>|S]dj>. N@E^`.- F^^ uY#֢자;,L@p$10Hb?~0H 3kʖSMՁk r* L \k bR ^a&` L_^>`zTPBX0|{ G_LJW ̌@yy/>2%G[ G8?:Xg2WVFԟ/_Yt! xV`da adW|Y /K ooX='/ 8çWFsX=%_Ϗ.2K=a#+`!$cPt,@c@wŋ͛ A.(`#5&fpǠg`t\  9`e:Xaq 2H3|:T/{WLX=-NA O2GwT5>*TV K>~%%v`y,X{2&hg>:#xW? dP 62 02̴ r#+?q &o* `(X ʨ330PX? ,޽tW-`/ { LJ܂@k`7O2p 1~r/ûO+KU5 `ǻwj7 e0 wb ( )|{FsJ 9ovFL5֖k zvx_JN/fpwJ򇒊(ApJ)3OLOu}Ps8WMe!08Vm$BKz3Ϡ~ b A"tu>KXb;d侜?}̪mP;YnYOL=#&sy|>+Y(<LSZ>VE}rD)g*;S9 hp@, FĽR\=p$1&`'ep>.`/lm l 1_ l2@'1R0'pC@+e@  j`T ;1ƅAU/ l:`bþ~T l ao2| $~aFS`Ty]f4)>C_ĂĈ( a?32B;Pؠ"CMʐi6`#X0{/ȗP57?`oٶ 7~1ae<]_~{) y Ă r ̨>>ax=(6.ly2pde4SnŰel׹qJ$c 160v0v'`gx^FS`2꘠AO@,xPO/1<_9?0I3؉L>88Yb HprLT9@8Yc!,LD9$ٌ;_=gf8 þ\ UUƠm ;?m`,~9J!ITپS)U X,#~@8=&@BL^ <f#q Mz$ lgSfd8 v@ `)4/`F,M P&{@ \ YW Xy3.ETs )baX-H8C3AYd .0V! L .2×,`o`( &IZjP@ ch^$* c@A%`נPAO0dzCW?<~>ïF@NBL YzX9Tifv&$ :#0yoAP?v>y lJqepc t< Тx33@/X  ?z<{o3|=P ̣1MN lL>?}pM`,8#` ? (s?>OhN@8!q ?@KU>` Z_-gb`OYU%lsā-q`MAU``M, M3` 4gEt0?vj3( i"+iFD%ŷC'bP/Z2@2(SB ӗ ? \]oex/&`2bί<H h +R 031VV!b0yh@b%û{/ aU% #ez+o:+3fbep^?W`02CFUu#C>3|{ wgxx"ë; 2A1P pPι T s럳-K͵ ,N 00ss2C(@ 3p#~{Q2<3?y#`yX X<:%:} `ADXNPрCYD!2AX42J 憖_>OawÃy0?g@89l}~CD (RpUa`pd`RaPqc5d1fxw<Ãcǀ,y30Y2ЕOC/Q-("zؠ"`g UcaД`x' L π!ıP~u;O"$@x=VU*0(V#fR4ȷ~ ] -M`t@z[@'CF8{А! D=+IENDB`C61_Services.png5 PNG  IHDR00WgAMA7tEXtSoftwareAdobe ImageReadyqe< IDATxb?P0@FFFA'C _j@ HB+008hlY R ]D,f`X3yD@)c f]Dk Zn Lf,, by8JaH hm-b j&6#RL޿WHh߽ccfqՄx k I0\>t@=a/׌슏S`1*<8T!2!ct#LF`|y1@3C]`N&TIQ{2.? FPFQ&4&Y103Kw@ǀJm!H<'³, F@7|?á :2\n@ٝO ju10ą20* )δfc`H1c]h !+`=x _q1l=pjݽ߇I3@| ``6čm4R!v }FTio@þ3 gz%?]SXO j1.z4gX\TI*˅!BOCy`zEMj?]0d8Ќ J2pE3@X^~>IIs l_K)֧b89 A u`0 RZ ( i17G6u-!C]Hے"tL` R7E&1g`D!m!r7 2&d8|I_- ;%$ui_h@IW7oi+&}4h = /Kv!`s-.ff"K7?1({0(;KAK><@$y`#00XC{łxbh4+00[%N}a !(UHF~CL2 <Tl-!!) 4'0` '؞1|y &o`{;?Q )& BO De0~@d@%W/3l~? J;;JF`듙Ⅻ@ceA;=@D{`O !K>HʏQ(+o3ܘq ~2<?i~&7 ?(6~#@AEAf&W e 0(xE@!53$s2-gsˉ 3\:;҆?ᯮߔ(z flXBF*L R:u/^4~$hk . L:lͿ+` tI 3z=b/4a3N=&9` @72 00 k.0NdAjc <l, !si KҢ`گ ,bVy j߂6Mq> %7bXSe`#!M f"[A1wm/&`h"w3̼N5| "Sz0~>vկO b4`sд@҉m[)&U ?hYï@=dPQ 5DT4TAC'QRTV_0@T3H5M}hVH \a5 Ѐ2b{ `x@l$ ?P74p.@fL@zhfLRBS0a>h#4pDR+eIENDB` C62_Tux.png6 PNG  IHDR00WbKGD IDATh͙mpTϽww捐W$`h#v BX8Heڎ|:vʌv~ h2aZ-Z ZF@Ңl$}{釽7D6!37{sr93;o OW@1_Qdi;N/Ph; d~sqe.c\"I_$zo9_~I(i\(.}o~`ڵ 0::R Mؼy3xu)` 'V׭['eÇz\ۭr9VD)e:('i@JKKe""%""۶m'sN9}l߾u'q8P;04R `477}v:::8;,YY`/ڵe˖QSS'-Tr䓿ŋ<.CQ@QRVt801|~8rchXTVPKQS7T 8^[SI*dd,9Y1w: 4JaZR#ߞ^榳|z !8Qz<;*$ "ЋC@Mj'К:ֈcf/-&0VJ)DT[l5ް $5/ppZX ]syt`$#1ؗ`,nk)A!1 &18fPSe*J\:ʀk#14E^E(e$ȧ{ytנț؄D)|/E*-o,ԭ\MJ2J)#N5]Ge#)CWx [tFLKHPSxzY)PJi"Lp|׽Q`OɹOC4t@i`X̛aZuQB鑷]Y [MzNR,Y޽X`p|= ɋD#$bcF_I )cx5 i&92]ۀ箔ĕo)l@СC""Gh$.)/KywعKb%%q씆RN-[H,"ܰ3"vK$""裏$l#'kW^t+OGiNm[Y"VFJ;3'>jےN% M^cgmذ7[ q)U(=g`\\r˯f۪Ux>S cO'x#WA\illnjG:KNϬj466dpʗu_1 ؔ)//#innL qg3UUU׬ٮG`entϤ@ p|V-B`E~)f]Y \Y[0Mܘre穚 |Ʈ SʇIb\3kF۶|]!f_"#DHR1cn>uTBt ׅN8Si up8LooderWP&qK']8prAWu]g$~9O"Mgكgsw[ZZom{Z4MdzY[[u+B hb䓘7ciJ&)h6B[naaN\Qϵ8BSJ!eʾ=wIKĶIJL1͉2Mn6e$&Y%C&tc\A̕rؖ-Wò^BS n.d2BLSPJd2Ƞ)eٶzWb}!CW بS^ijw/Ϭ2D&Lz;aXn,VVח0܃+bI'ɻFVH۟5;yMx}S}q? 5WT}eM]ߧkJĚȲl^/c/tJ T S/գC ѡfABۙxaBQ 'z{-aa hrR >g(-M~\SS%pZsv-<-Lm5ii߿:[&Y ;׏/QLє=83vBDE@A;KJ[D)q,[W۶Le,NoܻpUoVn|O¶y*Osqp@ճJ/:`damiNz ŧχS[2MwUT$#ixZ:'k׿lW粟uWi2e>Y;hvusG" O0ĚSS&S)lmUɉgpΜZ}!8zSioYe'N0jl(GD*9{t?Uf1CIENDB`C63_Feather.pngkPNG  IHDR00WbKGD IDAThՙ{LTg9gaP-׺b]Ƥnlt^"FEFW7PGXJD7Yo vuݰmIfc5K]׍U*9?e@&gΙ0| \NmP42wq\Zz4 ~i~²ںIIAۇi>x۶lР xMQLt rFmۂlN*;.o%۲WI =r ǏǏR۷:{%",Ξ\/޽ 80 ""^,d,G֦V6HJʱmOu/6ofDb"H,P ^z&6\&O8HTBj_#p{{(){nQ5oRW+W(ٺ鹹̓oݻ[|3Q5g0xpZv gq1S֮ڐC/ʕnHŒDIH {QQqq?usǏ3!#xTI ?ϣU ի=cˏͱc\--eҥ7de U.@I pxPBݸver-jde UJ$?9Tqq0%$ mN'mۆ2M&ΟlBWYbz[,L@[L=0i`q enwUyyPVTR~"ܻy|5Jbegӹ_?O |"iigUA&RX6RS?C\4C3-Zpv6]^qLJMpvGs͆,˖=u&|")11G^~q7(\}l!7xs`<MG>)+364\3ƸPe^W[kܸa|)^onV"uG;\M_<əO?%~4FӹB޼:A2O2q"JN.q8+.BӌMI_Ḷ,_~@څ$'#$uwv(ĉ1v @xl샖b֭]̌ :MnGI׮=u) Y [oٷO7uetꄻw9Oc3''@44ie*ڶ8I@*-ֵpq8D"`χ&234M{-(ڵKP/&C,QwIz`cN4ߏ z"˖ZIzz7Iȅ0D]g ҚVWMdڴ3$3ynW6a$Q[VD`s~> .m ^gwð$1l7! uuD*Us@i)֬n %-mܹKK?)P<& 6''o@-2!im@d P`EDmDԩkKF 3pd#zPPJG ~LH`0\0$t0Q(}k4IENDB` C64_Apple.png&PNG  IHDR00WbKGD IDAThޭZklWv3$HDI$eYr"?*JNm -Z$AE@쏢iQ`(٢hh6pm olZXoMf]DvGbYM%*BUUCJ)Ѩ5::NLLxHP8pMMM\.?D"W\W^y={ּWڴŢJp,۫aY4MSyLOOc߾}0M\~R 5z{{:>??^3Ϝ9NOOm2I.,s?sT* "… sh49E b$0H^'RJhj155@T"'NG=?Bko&$vD^B)E^'RʻB_9/+o o ߌb#^קh4|Gw0ٳriiLMM5u];ߐR~tIoo{̐l6+[HҒ C*ASSS{`4=iڸhRJ,,,p8L^z1l6+~R!L!L4fX,r\@֚066Ex!;R"P=t(q\|/RJLOOCu!siY9j5E4͕F7n\.|]|@?"ȯ=c gE(~B!4 PeV!JX,1&+ 9p4MBⰾ, s9B!$R\.s?ͽ o_]n z.h<:t;HRS)B! Ðs9B"((faB8鳵  !+J%dٙ?f;Q Ç_;~ٳzM夔RJ%( 4qlpH&4 lTRUU,k RJ9^|@ D6PJYLNN~wrr4MNQE!J)aG. |>(c N i0 *]4߬ !pΩFOOc Bvxා=(]Q1 vvycdd>`yyappƍGTB0ip\B8=!S.c`|||٪y]|E aJҿ4 !1@'F.P,,,[ SO=Ez~6L1,˒-vkw1^,QPڶ'n4R ԇ&:;ѧۭ...LR7 IT*%P(Jg2b4ͭ@L1s}}zϫjvixp…s\eeYnڮjz!l6{+J6P(ӧObLRNܫRJjZ]$IBp)l6e&IG@ GJi !hkIAqE)uݾ}ӫWFIVÎ4؊:{Jϟ;wNv{E#'|Bޟ^>19h^5J/^[oE{=yOI8&W\A"X8pq-)%sSBf)|mN6b Eadŋ9:_)J,#P2 =w޷bX(wPh 6 ØSe$ FV󱾎.,,z7%D"j__o:.(.?rnKXq1kYVX,} !>?~/\#$nRIENDB` C65_W.pngPNG  IHDR00WbKGDYIDATh_U요 VئKf+A$aEDEeA^( HZB^vZ,( Št!n,Bݝspά|yy>9:ґgz.2M$\0;0s1fŝz0"38[ׁAn[s}>|C:;A 8i(q]A̭ lju@W_Ev߀ /O3Rq #cEFQ'}Gc بe䀣rN؁V6Fs}ZV_G0; 6wk̹۰Jj+b@\c\# ݣ1/M?]#6AJm`~\{b^esR|V3slj"V>ԻJ+%',.ʉ&D`MἝ";kHq?DG}vfYH5'LgF(I*BݺLxXo!iχ9eːmnZz}Z5@p?YPPpI_~:F+S,bs:.4+o^8CQJ*T,&\{S_f*Le\ `!G!u|(:2UeE9pnE2\D\+q.ƕ؍>VT$5[}j*Ns-؀p~ mBe[UPYMnf~H[kS$Z|z4 ȼ>JZŃxF0xd6iNRa)vų] JJ*krNXa#M7]3q>2л(TgmUm(SwԏrK檽,Qy W;}g07d[z¢x^<}hߡ% *5$kk17k(ȼeT!NcRTwz g(E?Qr'H}sH:C#Vwߴ% ,yl& ј>kO]#1{2kybn, #\΍r v~ 5*nSSs:ObLڎa^=QM6_W12 .A eexl_Mިi}[Š[ɩp`ʴ;S'j-/XSI"bR{ʬUj40 0,d3GC};sB)S\XE2j+NƖ(j spZd/vT/8Ό 48Oбۭp}KfnҺnvPUl(PsgJ hӴcq\4'ҦsS0{;r#sR[ v*Z Y3; x0~RwM5OCp7_VcXm"OFSIENDB`C67_Certificate.pngPNG  IHDR00WbKGDIDATh}uϽϳ,‚"bSEK`@bmu(&!uZּvH]TK#fEQDQe4D"+ >4?Efwν=s9s9QQgwVah\M(<,y0\2M2Iƙ xNEp8'xXh3I>7/% wN8#؇1Pp5%۱KE;*d૒X/%땜':_^rUܦ|^CЖܧ]YrWU Rx ]Jא͓kOj\j6FEw5.4i:[]HgF9>eP, Tb.5N1/GJBlM3~#VQ̵St zZkڱIv.Tz>M8MTQ-ک:ݎ Qqn m(4 W#uDeT0HP+YeM~Ъ5U' ѹ/to֣U!dcV*g:fI+Li*jٮNݮGz-z0cKj  #T<)&"xE$Tժ$kYg &.eIT5{HjM%[$$ {Ѭ=*N,SxKY{u;O҃- ;$M tq$HDhQt~A=H{R۱"3-a&p}~U냄LדD46s=6fo%y+L.|I<'~8ka+T2UlxðfE.r|{Ӽw,:pV6,C CQj$Q3ۛWo0Qk^AgKfhR4+qŠ,xй7tȺ_q&clB]&Gtv`*jrQmztx_f}SN0%Z,iuA#"Z,Y))\t e7Hn튈StTЃvqz(?B n|2RX"!9UEY,YÌs_IQw) 1_CʢiꬵPP 0`UiPӗsU_Kk=*I-uwT8_^6<;3iVfoP|:`T!ٲ`f]9_[o`aVZ<Ѹ%ҫW1 >Ј$(.J0'&~YUNNݩeI}?fsHJ]h܎ɝ"ǢoNn2[rg8>+}.Ky'䦲sz@?#_x/goykOq5JaUjPs͌;e5nր>(x# 扚qhVCܓ[6-֢`{6Wj5@\yw3MZ ֦ ic{`J4א'l͚t,%jT2Hpc({\R %K|Y-Um"dsѭwpk w 0P.`3]h$_*Ƈ5Ϧ_ LU5)H DSDUy"٢KEV4B4p]-<%%$L=&Hޕ11 _0Y+U%ph`d - %S}^0M0@a?88## ZIENDB`C68_Smartphone.pngPNG  IHDR00WbKGDHIDATh՚n#I?_Uwql("8e/Xހ o ͑Bif8U`;ig3iij].ۿo}=}J)UD=f~>99|ÿ93LrA˲9ibBht'3%,988{u_߿7xH)tU%Jjc\sUZWheY.;KR qpxSBXh`6,N eDe% Z/bQ8GZ -(?޼bnݨ@\d j&g_w(y7us 9r~z/wYSuXܷhO 1&:nh|; \^8/Ri |[Iua FٌIjl3Xݦ:`@֟l\Lk,>iyp)pUR d&W5ӈsAUk{\դlH_ uDlx+raMΆˈS2.o#YB.v>2a&r7a:md>BwЫ5XY,z /,rXko)R?bpwܠ5Gh3|-BL%T%R-uCjȀ:,>0xt\[Â53Bzs^`w)= 愲\7p {p[ Zȇ壭답u'YAN66 gT%hZ]f"U ^{fYe hF|>n%}(re^%ᇽ*c;;%XO,L/ ,Qئ-B7ov;k{3#[>hyx5Zwpph0|sޘLzF1R+MN0fwzyɄt6s^xAJ-R7v*"8<{>)ڪ<Nu.~p0n%Ba%]]&|OtYY'?7yZSm#OP.GFƪE)kj"¬Y򾬬(#ɋ_:U#7 _<Īܸ/^,ey~I|7NV~XpvQa:9y2b5kdd^Xa^\>)\pz8N_^Hj=IJ9<,zH33v::QӿXfώ >>2Rs .6̶ZMSs箿)竦zp2{6QsJc1}۽uө\koS RSת8ii #99%mm뵋 D@F녑P!eBY=f|XQρX2by*!tW9KBo/hDp8{E݁mC}A#t.|>Z]M47WnlhuS4-mZ5l~sѨ[Lu׃=pÇgņ.و ~uOIyo) 6 SrUpM8;xun^Xue (@@>lե{7FΜi$OF(+Kd ]D_C+耝;@@y4'@mS[ө|hhk@Jh97Ѩ&L焮ߏ$ByyʇF!صqꚸ:v!,:^ á|6HJZ5k̙J5!)l__McqudD4m߾V< /.u?oMy ʡ?n[\zV|z]aa.,Cb A0FAJǏ۱Cľ;׍ };>`8B_;R֬~!(}3ӕ o-x92 k~>rd$D"9MMmrB_BfTg[1ePqxqH޶MwnsPpsA>Ò۪\ヒ@MJBh=½or E7EU%؇{'d?xq)PZ {Aͧo}NoD߱Qav%W,)+*zM3z[ZS$iٌ95a6_R"C+p(qA!E`>\qU dB2  n:L _X8kW=}Ƥ'iL7nbY\PTvب(B`2.)%BUQ-4ddzŔS]rI7K~_ { !]f{dMK"C}_7XҎ;L0 mqie 32t*p" Ąi(b2hf2٧No((%pϣeD k ,@9g@d4~i.2Ǐ.le咯8뭷T1y}B(ҧBӴZ,=QRUe9Wtu7Ax>-t3\_|2#^Z .^Fn2- d•(S:2L/PdRo,(ïXy${VѫbCR |@44-JkkMe WSknLk){"duZAĸ5]0Bs`0dQ$/mBQХD&i:"žp)U- m.(juuF@'LK?+#tey n̈́h,0Y)0'(DУ!>"˧!v<,5B+4 wTU1ܡ2L$f#w2{˜4ܲeRfnv͊rmq5&M쇗nRn d'$yun#ssxIg!MnPhEŢ}G|>%4bqNZ>KRҊ1&J\T~E3@MSyNE啕72i>8gC(YVnna0c P_;\tǏolFoZc6 YZI]׷z)̙TTdaXPM&PUl}YMYYUɰ庛RݕCnգX쩔ϳSuFc$GD$>FЙ{peT0It>q<-v[owGg CS)߸cBM<|BQ)Yx챭pYHV2{"Ip `xA9 I>bgwBC7(qj(RUiizczҸXFUջuC)oPV+(ԕNS3厧޺ =ʽet&qHg(j ,Gelf@DA8ITzfèBQ?J,\./SѴiSS=\ߠܑDSeܯ< $Ɣ(:צ1U8-3˳D* ep ~6ێ&ý† σrIS7oOJk&l=dܘYJ>obcDƘ{)0]AR^>2(M=čٗ» lOAo9I--ƍ٪S:1@`.k> 4!R'9Qh#T^aa⬫9ggx?7?jcUpi\8a7P~%?f'b@(ŐSkn!( 8\J$yLOd]x%`D}0v4\Сl9L.X J5;5d, 9@ p ̠`Np ZNR!m|Y8|Q>lsTx]Ba~괱r:qg/Չ<@'I1|S\:@ǖF > C/5hoh 1Nuv3{&l3a!y4[{s,=P >ufmJ >23S$0yG ,#'f3NfWBuI*[H[~)iZlа}HZθ`>!#~ 6Q]N{ע= (p01 8'C8iIENDB`B48x48_EditCopyLink.png] PNG  IHDR00WbKGD IDATh}lU?yo-l+ @4: Ĺ uad-H"f l aK4ʘq?4hbDEHC)Aල޶<ޖBk ɞ^{ иuQX<;a>7n Xt/\vqX}}Sf]g4&Nzrs8tY;[G}cS@h?xhS.;/^kM@aZ 8s&Ck}BQ?Ȃ' H5wU8HuucJ^Y TeǼB4MCQf٢Z^)B{?( Jp]qrK.#NHR&y2"˒LH$rYRlٶYs4 rEqH8~8 /J`LTMSS#Bjjj8z(`29͋J`b8|0RJnJ6%u@ @(BuBţ1L&åKxwbds9jJR`ʕ۷{n`y̫X(dX,R 0uݏ !@uJd.]˗ٸq#J|^JضM?`f>R#ƫlذ˗ŦMƲaʲ t1r>u׳|rb7o4MU)`v: G~dn͚5a8vidytuu<`i:RA΃>u1L&Æ Hٳs"o:BfdY! aK R&OR@4zilf455.eyTUUZP:ljN*q43`H:vM{vAcc#"LӃR )%y\%YRIuYb---X)%J)N| ee*p[z(c%b!sXt9rO?hii+gPr}v[lO /"+VRoL1M6AOOO>$RJ^۽t9l0M遦 !Jz@!WE!x_ իWsYfϞt-lyJ3DMә7;F0ɖ-[8o|vb|o1crPYБq\H 4 tZ F4Z˲߅q(_qqx]T\u"SIY * $4mVzNU6X6vo (=wc-#ÖfQ-}O ݍTcGP7*,_iu VƳi9bd6\vhIENDB`B48x48_EditCopyUrl.pngPNG  IHDR00WbKGD IDATh޽yp]yYղlٖ%o lRP\2%CNRhڴHf2@'QhJ @\P8 Ll lcYJWw9|?νֽa9::wg37ǽ&E1X?wz3vmH 3M D3<={Jؘpԛ-mwA 8U `o_>,X̗|a^qut}ѱޱ#a}"?i;O&ᢏ K;=Zُ\ߗ'wȫ䍑I [yb>oN{CEfl2Y p?cn^-m7.:? ݲ/FrlqL|ysZE2Vx7쿟^d͟>Gro ~XkO^05\)C̾fFeplXF$)d$@^V^VzFz{[gG kXW}k^3tuF cEhhy>~O{xHiu(7;2vޫi+:Gv B%l:>۾s]޺#_u;|#v) d(ꐔ+6a/ÌH+}mzwC_8K`.` 7s,;ivwLY@x"N*9L*6^KmC!h< Z4Yfr{>!WtN`ǁf~ǞOE,_Fͭ)CI2^Csc##Y"$E?X:} ?ls%;\nykԥ\u㦵n _ﷶ7'nɛ<" "hee"ڛqbY2Yt`(=l00{#>йv"cu=;jƶ{&νdSխ?[xW[t˜˧ps-t$:EԎPyl6hR(F"qo/4&[:jWy4- pK,ﴳ{8~ mCJʜEݖN44VEzpaW1v2k  m &/dD5ƶ΍@FP"t!l 庑R|&,8MA)k Zlea їĭ/P`4bD¨&vTi@ϋ CMUK_s'Z|!sk˜3^7eZL1pbsCr Fh ~G 9xS^ITJ}i#NBVJkRK31"V(66}^SPDôDgs:Ӓ";2sYH'a%HX N#DU䜔L+=b;jB udluWGvyV"kkI9)jjvJ%@QC_ 6Eߑn~\{U2k.[N%mI;in:.pkԡcFZ4Givirhtirhtiti4i8&9 ~6v”H,Isut7|”H v#MNMHS$7ڍ4LSYSX-.*C<1ҢoǞF~J}v L'>4Y'"[0Am&|jCKJn-ZF_.u#! P>jl$e e([~  e`|v;sz#BKLQ:g4zJa`wIZIꥁpuI:a"UFa–d/*{a,g:@vϻ7 ݨTߍ]ºu\5ĴG0@ɰ=ۙL)#N_2 S6bC|^pC/sǦYsWO~04ihtßg7ׇnN.dѲ謅VˬzL6œ]&0'f"7ٞXh?~.OKɏGFֽ\5ӈ."X徽2a_Jr $iW%1MԙG'trg ROIm_ A‚TTf.?|ŽgBs C,3OPҟ)ETV W&_˪V#Ηdr+TNr*YtldU1^PK L\m&iטEEL '- K Wl.Ul'Y&yhL*Odȁu'BT/L Ej˜"uY@ + W̄[.Fu2*,MN*FWH%_&~bYEpĀFtHQq4U[~'1bueDleP@ o_}+5KʼnILemW* -yjY3>L֌u`-(QRS;R lT+']'Ϣc{Ȯ_pٻ}:V9\^ ey?XCD܈ ZIENDB`B48x48_FileSave_Disabled.pngPNG  IHDR00WbKGDIIDAThYKk#G{1~ ",$ч_ٻOI\s@.>||`lfmCf;M=%9 nWwWUWuH)%/|Swh߿R@)$Pv|]>~|{,句HYw:7t u7jl>8R^/?=筭.:!0DVR_ћ=!s}stt{vz9,ZRJtBp?+8X[[CL !,nzPJe!R!cZ-K'V& XJ Ji ]1ҿS2(j=9)|QZ􆩰*lnnR`0(#l*$(w tY10t/LN `XQŪ@Tr̵^QQ d(lSꮬZЌQ]E!]NQc@Y- J"JYRS [6,9e1i`wJêD2.W}[e<+ -*@&S8S܅l@ =uNJ3oLaeUf^9/:tuK bRLW\Wey@p8Y?zTD)E2L8.T3@yaL*;ifU1VHxesg*tB1NOOXY>(L@"1`*uM:cH8??_dt]ATj6u|߇jpShbNWPu)TA籢Ȳ cY\U圉&9HB`nnn cc B)SSȬ$(H>|Fey_gt(T֖)B8<iq\qH1xI4e8E!=cJi:SHm9REeY]eLchVŜ^P]]]A^O +l Ѯ΄aMZIENDB`B48x48_File_Close.png PNG  IHDR00WgAMA7tEXtSoftwareAdobe ImageReadyqe< IDATxb?###5@?2b( .=#@1R@9@lD!] Gsrq1033p0jj203|5o/^0:s a;ȸ@'3D:^@MW9(LJALAHh06Ȟ_=c`x {bu.4yx0ݝ!ΎA?nb I9 ~̔ v0<@C@|i)  lC21< {Ob(>pxf'!fe`q0 C`rC&P,;;Û7 s`=f] Kvsrs'L OU}TXa66 FgQpO1X*<$O,ػ10{Xg,(莇^ eAz ɜKp0N0T~Ȱwn߆ GH O18q8d /0(c q/b P6 ȞҜX]\ `0,Ǽ87A@Xh^`Q R@ `aOc`@ [`db>002(CpB5@J!5mmHu218 J!.X7Coq1X*!'`l|x1C10qxb$'m @0(20| ia.3]oa!AOpk{.h%ɡ0 `t)#@LpGO>80goANL16`|a R@ XPBXbrV$ڷ7?oLt<0ss!`㑓` TB9`IB`PQ RSI 7[dST˅t&h! # qtB*P@=a`!@0ISWcԮB}b=@=@\/3<6E*1P } 4 of38YlիD8=p Gr $  .<>A 7l3>c  ==cP!<yV%/{ F/yᱤ$Q5,15}}Dx_@* `WAFoKKK2Nx(xҺ@(8̐( r|1,PE79'@u]$G;K  a`8+)`o TO3)7) '@Q~4` @1H@!6}ϘI)/ 2<^ P5,s%Dq#.!XDg 2`+4Ăd_"bL_'+A V4 @Z@8<O {;4^6vw| R扙Ձu  030Pf M£IfytgXl ș:L6!c b Iy[ |`=45#@QVBXA!d2A7 .8̬C< #VA#מV̀E//zJ؛X|7XG4 Fj.%1hf" !`!F~IENDB`B48x48_File_SaveAll.png PNG  IHDR00WbKGD IDATh޽[lyoHDQ)ZJT)$Gq\N#)\EuP  EZHbp\I5&ĖȖ`9 )Rv;3>3$e ,f8wفn>r;]dfn2irH޹e?θoĆKd@Z0d%*3 c1֮mmu5v8P.]z/ iX{5 O}K`2;b|j +u.q2C0WO=GO#E>MFЉ`1 `" ´9?]80^3~g9ɟ>I^zu}&,w0͔ !Y 8O?ǯĿ>ivfK% K$Z 㒖hTpK%AHP|~תӋsց7`@66}¯;§Ҵ!+6FB0z({-ܒ$&NĀR)rVIphM0 wV X CΜ#.M-prf̋4m77J_m:`,ӏcz qHT* !i Rrwnb]J22<;d<ηTi}YPnz|WxYW֍jMnхԞ.1 蝊xQӬks \}߿!xy2ƸsNn,P%',C,DL,V[Ptko ľ ܩεfahg /:Ki41J=9n,+4Xs͚}MFnXeIlB7^8}|(i=R 3k၄a@A7chDnr%/a&ײnCrB Ń8֭^|Dˁq.X\D@T 6RZ0nsI(nu!5aUSA`:Fp{ Ci8<(Y8X3T\Qa߷Mų9}\yM`lDoF1Br^rU tӝOgzSuO,z))KqD0)aoBS,X%jw5m ql?vyDa0:>@ߨb G݄h!HvYz-,/.RҤT*+KQ;&#р>2ǿv28l̓edޤ=SJJS4h+721чѶ+<)[O'8р Mߢ*|ayڄ<<}.\xhͣ`5+f$2n@HK/>w 067Aϫ<tRʕ'z f|ʳ0#`!Ơ!΁{<ihj(R}d{x_<M{.yF?9HѠ[<ƶ7NV ;xР;ЧMfJ"@xxA2(x~553+ ?Em5jX 6yვv@G[!-!V(OEA$ DKzFS@m~~H#A K5{1a|Ї*hNDhDvH5GLיL3G[OkC%,-5?#KtiWOجVVf|F-טĩi!&iݛ2)1a":fD7h`V5^g"TYٴ(4skJHvFLc&HG17'LƧm(bm5ՀֆF#!c~=;VD1kР?oY:#QֺfZZAiվ I!GI5w.aZ oܺ~/hΡB54ox;u>d ^T/9竿,1LNpu%Qt?_u5XufT:+ Ь1X:̞~c0$#-m3==M\}G}8<^ϻp.N=~;G?<v.z8$UVY^)9<*Nw.^⮠RHz&1M#DǤH4HX T*O'ۃ-lR2EJX-2_ǒ&B0Ѩcq"wWJu?]a胃Z'pFWIgRo;ݍ%,[e?~c l6A%,"ˑdd``Y" )Z)dʙJYߕW?&հϯ13>bmϱcǘl"AВ`3-AYW'͌7Ü7G)37JT7<4;h5PuL#mt:s⍬7WUu LJ!S \MFgHtGyxی@k9m)6>^{S.B*GU(,6ǫSW\I(Ykd7|_!}6~ޤ4xGbd2A>'Ns}%f,vؑۅ annϯv210tɓLNNn"Oe\ԩSضdY\\\xg>;wl.:& .]~y=@`!T`DkW\w~ǥ7[RvL9_ՍnhhYONJ7@Gs 'h7`3y4 fxPHЩ7`k ÍIF@)[Mx( iUyNQt؊4@F'NAkrl6K2-{ިi}6u؊41L49FJ%Q ̄RJ.A0::JTVl& );DJ&XaXhhjRHF1 ,J)nVRζBI=+:{FIoLjIٿB^y`aabWWW)*J)FFF v6?Z. "΁_`)?x#ZkjZ[-98s̟:ʮ_okӗ#`| QOk7|IENDB`B48x48_Folder_2.png PNG  IHDR00WbKGD NIDAThy\uzMhF@ )2{D $@\Mpb@1T HT H!1vL c(%`HHY bFh,{ޓ?ЌvUyUvwwν߽D_K+~Վf/-߾]fG*Ӓ)>vMdQ_|V$@{ kN+-uw`6>3)?&KI@KH]OA+DkiL¾}|-Aot3KᇚT>7}"+WIk604yOJ\rz 7=uyEc jI=3U~hc1x饍-xEsnP1bd+-M4pIiVNќ< ~OԦ_ 3ՏRG~N.oijh{DiЮ0XTS zզGw6mυ3,rF+i洠芏Q=#`Y !9'iRe@$jUZAOWq''028(~ 90 ~}\2XPI(XVS,@(`,Vrq 0Q-FQ!ձQF-ff''PWmU03 h B9oA `D!m ނ  Z?ѳh` BM  (?ÀTMVFm2Д|h9"SX R(8^q?e'/ae`]xnMFTe <BB F"AM ݋&n TbmkhnJN@9&7{ Lt:6ZX=;"v%d,n-9팷޼~M~UEK}g٬wd.RR ;HR 󨚞;XБsih] IEJ~j|t; gTyj6lI<=xמ;o:[W?鹬-2=j:PA;kE7E\ "Wg[LV&QyR#;W[MThԘPoiN ƖOsWϰs;:5R2a66d2=zC9 >cs8μ;Rurgឣ+/\F=[[VWU9XLm}Togzz~e{zu.Ϻ{uӮ'q|-2cVG_tyۺ.0U&ʣ_[W Lez^/4;I^PΑ7'%?Uh^5sKdzF> Tۉ.Vj.LqMS:QmޭoDaO|hfz*"G'% @>6ez&ȈJ^(ұ) @MV"OxX# 1=I(1LJ@ś{{8pdџcEF ~o045l=o?j_&0тGRiND ~[RǑW*.q$F 'Mԋ5^t:H|S ٪@b8Bͤ:UMw6;ƴ PaՒ.< gO`zWju\a`Mg9;7(RxW6T-Fo*GՀq&?g.WY=s%Ik<\crqã?ӝ7=㺓 UUHB_h `нq3\>woY1(9U)!6e'5=(U`YZ hhokS.%%gyp7܆t5"Z2jpD:qTlVGfNnzg"bD J+W4:2` o<^|͘~G)49>xhrba1yfݱpKK7{+Qr,HBG)ZHze*Fca528`Mq,$%}{ٵ޷Kv:Zz@B7?ɭs8eN+Z { wn_xÿZ%JJOR* ]ԃQa7 =Gg'a~'Jtk +VJ7Zas3tx PVtv&˗z٥97l,)z(Dv.c>s8P`hx>{1ʖF0pl2 k\X CWf4NF%[2w\ *^y IENDB`B48x48_Folder_New_Ex.pngPPNG  IHDR00WbKGDIDAThi]egktwd# FEE g,-QFGG*X:2nK9ʀ㌅8BNӝooow޳3ι7)\J2:T=< m/BOcǎƚ/Zcc'Q. (|(r>]}d2N:uՉݮ ouvvfַWJYf<(K z||^x!wرcɵ^qPsr%G맯'Q(~;66SP[~_ fpX5k.b͡/޾lkccӮX,vwww_۶jժb%@mmYM6GSaM6]W"yDu>ꕗ\r<\.s!yy/=( $vOxA=ۮ+nU.ض.  T)9a`6/D<$G 8ٳ=$Ó@\U3na1 S_CH]Eݒ~_#P񶶶ض纈H( xi薋f 3idf$cӛ2̔͘\\ XBD 2CChܼ_6 Ec]RoK慸EeiSE *gS6XC0؎E"!Ft).iq3Ida`3Yɕ!ua_jC,Yu,opwӬ]P8\B`f&͉/|kY,}Z.6 rۯYˮ~A4HJ|OM O0lHv}q\?$,d0Y4m' 8n"HU1ӺSg [S@`~ nxąRl~^ʳha@Q/Y} ?;w7 6"Hdeض㸈H6ĉT*5 $, O_CS jS}~Ґ$PtJ4@@1C @pED Bl4IfǙPUAItgh쏈(s, f<=s/%຾"QR 0LA1z{ $x>d MaE& G-@UCn*n(z3N-uQ0 @_k%͛"('y-e$%$ (_Xq^_~_HG%װ-I(tMƁ2GOd%+o$oYۛq}wB]]-.$LJ8~ 4?_YOЦr)]vԶkz]*(򿐦W\n#P^w.HϷot,z2HdFuB(ވ+v}@w=yS^| L͠'33Ȓ?CUU^a}vN{ W,#:a`]%vm7Һ+xW|OۘZOJrliLM 8i}¥[f ̹S(bg387"UJ[UErĜK) 1&L&W"+"TN-%70g?;@^kC{Q^X@u2(b 'm<%S*J( uȪBqj/}z,h%iJ5f2(Div'o2;?.g"g$18Y}g^U06)]5@}6+Ρ.d:lhnidԕҜ+⪵xKf$9Ԃ\sxfWz:QmϵoÈ8LKw}[8q~j{њ?c8xxź!^M xr Ao|_E*J* Oe'ّy[EV􂆗9R@xN+kS3E5+'7rcB($\ȵD@lZ.yBGnǭU;hAB˩\?g Hp ٌOZ^3yMlm-$Ň;(?:[z-] HsÜH`uΣt$CX8ێxBU)W`xp@Q#L(8I:9 `˟h"w붼-_N4ޚHz Җ&6M` ,oi=^ĕƖCbHtz/ێ*zd 5A GQYҞx>R_k+ )JIVE,IEbR=.,7`: \J="ZEB!CTCjLL2=+ϺAEn1 INf׿/}LyCrյ|r13YGxM{Za`!\}trjh)Wճ@ abз~3W )j"AP%tF7m-aDq =?OH%}s>p uT֝7/ sW>k0})l!]r.FݰM?mlZO7#J$ TXU}j!Q<)J^~.^Г/khܽQQ*fr~+oū3OP xLEk ey;yվoެؖme[',b& WI'D5kF I3}==1s} ~%݇+tnD%\OSe?-`^`-.>S=1 Ů 2<`͑PJr ͣNOL"ࡏKyZmj~G]JxpSloq9aG2V?V`ߠ $3V=QI8yxdcLe ZX(뮭d'_^;a!غ.k:5ה0__(C\' X57c~Z m(Q/x ],cet4 wٔUL' ̜6b/ae XL=.d!80s,x x:-E[ujhJɊ!L/@vS7E1~xm`+eg<-?czVwE H =9kp|ˁ" /SʇeNkw^vvEDOPBdMw$Vr.:v_^~ӇXt3 V!PTe ܣ2VfngR @ .u??'k:nksuNll̙TsAΟǠY%)_A4@k&NXuط>(Z:O Qԋ@<60h\&UwIENDB`B48x48_Key_New.pngPNG  IHDR00WbKGDrIDAThՙytUս? wȜb@&(KxXXA-k._Z[8]-"*VA s!1 ޳BqzUZ{sNr}-| *!6GO:*d9^;n{4 v$saP6D9@J{L3!KrX}EekL.k)6dQ!1 vh<>OU"}oY9idcQ(P{hg;:z+gMq0t@$.U zΦ'P\f8 J3{CrS/ 2%nuϕATG"E$')f_)R_LR_+̰vݰlـz p7͖NI eȽm>3OṁMuŻ'~u+CdIDpmiٵjw4X'`W  :ԗosUsOV+ÏxCv@/n}Q3tTPM!#Otl:O>W f~1IQ̤=Oٱ ǶvL@iج%k-6$j& (AX|Mq c!d C>X)G< vw:MQl~[F*͏Jv m[؟G'M5`A͠uڴӇp_NlY 2~̼q8TL^ظg ƿET:z<DַFy<:Pk޶[o8fP40ˏ\.X',a8bB Iў} ;wx. F=~z͐%2 >>qN^Czo 8vs﶑NJ.YĭMRU&{1!B\el~`yZ1`Tn5|:|R4!m@ tTCZUyц:aG휫Ժ!,¶+O0j.k}'"LC !O|"!ʯsɍL&ZA[H r !|$:-<2`yP|9laXVI3^痿Rʐ(TC6t!Ю d he-y@ D@P{ ݼ Xx1>h QF:dB}q奍`JJaBPmך~#k6YjR3aq xE@: s6@t\ Ÿ{`ۍi?tt6zk;U8YřCI)h"jAIXJXx51*[0?"V2'JlmWZ h/x${ﳀ b;)$R :Z0lG’H(˅8UZB$&᭻kP`_&*Y>FHָLԠ고 ^+Dްp4KV=_J0z3TL@3 (hHr65$=]&m3yWUzc[, kjm_ @csw,nժh*g{(3AU>6./TU~9[7hk{2"4@+@VB4{V*{5񠄟 &p /YL$,Uk:TK.OCsr4S3`$PªGs|zܯΌzC^TLn H4%oQðVۢB H_ Tw8Ʀ1$ im VK= UP@` F ^PCg@ V=A7vX̂$U@{82&#ڦ3\ySul~$`{66Yw&F*|? 63{ReBMZ _w3  W,ӊ5 ujD$T(?~:LּPh^0/'[H?T@ Bp?'HM?\KX8*t%5!/G*1{iml%4Ȳ͐iޕ ϸ Mp$q0"**s6#_> m1SY(ۊul ~WlGor,\rP2Y Kvuy6v8t{J8cL SXuG"cOh/~b\*}KZ m.'rpũ-/cՓB?5Nb"L ENvϿmU /'$&!̓Jlz:Aސ Nݑ" 0r ?w;zejXs0N6xT94 F@ k[r7YVSCy-$ǴBEI_r YڊhߜС(7e3ynh.$[Q tuԐ7!3%txܺ>5zL;f`g)A @]C ,h Ͻ qy2ȄOC::MV!t*xYMY_1fY}rHh'yZ@Y$Y~] 5IENDB`B48x48_TextAlignCenter.pngPNG  IHDR00WbKGDIDAThZ=o@~.HB`(jJY:5HؙPvn11003"vj*I*َG&ǝ}I''yy;s) ˕{D/ c9}t܀9Sz||VV!PP7% [qNw<`|>;; !HAy4u]r] r!۶ɶm,,"9qΩSߧ^G^L$"s$;RYZϸN^KjL666pB5xedE}O28&hkI\MIENDB`B48x48_TextAlignRight.pngPNG  IHDR00WbKGDIDAThZo@P(m*U Ebح[{ɐ.WֿuСsǪK2EUAH gcuLN:{w޻3Ko0P_/--}Z]]!"/K{{쳦ilsf }pZuDv|>eU5M8YP\669,J`q!F*HV`8Kė6w+(kQ/0=&>]H|TRƁN+Յ(]3FdUYZ 뉉+ڿ5M*4OLBeyy9Hjb%́EJ-\.&WsaR\h\H̥v4`mmMf,?slVҹH҈D.$cAӴԹˀW;-~jHDp;_}UAN 7C"ǾȽ:̾=pL`x.Xmw}ǶoX}ý|'܌OxٿDƛNj~v'~ǡ-9C㎱Rs8 XJ8J-1'q҂_DIcMˀ 6L`#$L0frYB&a?/G5q(/ LsR{*=R0^~`R؃jkB%X׶M)K<#[+DǴhdpc g,\z򲕁2fAoM vá`[v߯2oj!^;x m}2z=y5088wiLclr'^zn'z=\_&Tju7<~e`P0(F@JwH c1 &')^T<(f֪BR0GG&U !'kDXXBdvVc"AF!]7[mzX+y%`Dn ^B>E &x4P˙'J BmĆV P *+).g1.h[h@ˍ8 &^@p¼f.9 z2b*#Go D!Eyv̧wQ$]6` B%B"ܨ)B&ܗ&D6%$~!in '#^,ō%r!P,Eya:g!%S`$361̍t]RɜZ+$6gD/ޥPN|3/"l-SIƋ1"JSE?`<`` XcC0en^^U5'{FYVR11#ln7JmfqW1ПpcY iĹY9yj2&n陳yP;9V ;i(}E[ F|ǔ2%iM bRѣRGȓ9?:.V6%7%Ӓ>ďw`B$Z䞻Yt? MDF8,vs1 dЀ0wyoO^ [gɚRWoN){@?s{`t/W6܃W?#qvG!NSc4:n`vإڽ[f&v T}ࡧ¹ g}Oh/cb+.oaXUn~~|wpqN :K<5g%Y_1Qf;1ݶg~wfJ*VA˜R}WuO8T,IENDB`B48x48_Window_3Horz.pngPNG  IHDR00WoIDAThZͫEU5$Q$~\G hn"EsQЫo9ѳzHQ޽DAT 1hԐ %yovsXWY͇]~l_Ml1` \_|;"`Vpm 2dp8.>_x2`ˇ;G~v'C[|uC㞱Rshy3N}|>d B!g, XMW-1'eˉZgZ4 uf0l!aj jT%qkB FxTtP0*I4za:RŃjkB%`=^ cF/< )pӟphaH[ }`60 y{da~Ŷ6o'#_˥UFk} _!a{«/c0s'؂+/Eإ XNN7U@%h#}(\MJ1 v| 0K 8^17&BŢ+=P,<@BNV,"A_Y/ Qr^QNcD8yD"sR- Zub .R>٩2tIa1Ч|RHi/ 0d<#$)p7OԴ\T{_)8N1`} !" \K VƇx.|"e< T+9Oy}F+#vebCxHU\>,3eVr5uL{$}1`| !Qt(AU\eKu!QsZ) %A\%W9Y&h9]ʋU|?,ϥ X4cUFMb BM!Xq%c@+_B3SX0rJԙW+!T*ĽlRB0\zEKђc 1Yf!_JUB, $MZ2\iƾDg&&7+TM[&\ LIKJ; fnk襄e2 eD-WT\D&0}+\M#o1}ʷJ<6GebB`Z5mvǀQO[2♉,d@Ijk+`?JgBYNd !DFE1'*Kc<Li\Is1g_Q;}&dJk-Uu|#5 1=C[1 먐vjF# c(C񀀰q}oN]``*qss [3:{Mc *_rDȑ* 6m /mC;Ȗe1u]pƄg454d.,apW1 '?_HD] M3uy\ >|bPh0\;|-t)PrDT߱jtȷr33ʕ ]ص7mc;X4`{i_ 6>(qIENDB`B48x48_Folder_Inbox.pngPNG  IHDR00WbKGDIDATh[U{3r/aEEI [T||豗F"!( 1"( 1gҰQ/3r̜sޫgN̨go߷k TPAšJp&lF$B|_P(S q NJyaK('{J+ә準7i>Z0rJ~|#cq84b۹z٩P͎ "G G1PQ HэEhB,<'S*&yAzc^D>,nL88;92$F!]|-ʹ BLMG:'Yjc% ޴s`@0(3)^d{YG<1kD=uB:JHFҞ #z8N)MĈG*V|Cyzrۨ[6qDbE}BNH>A@(M&*D"BTe? tD P* D,] *Ajx dbsq?YdBMǝjt4@]'.w>ݟW/E\k<1ZB+s"8BA{ 2~5 p"8ɺıW.<"*AiV_\SƐj%Y} xz {'?t<GSST٘lTD8k0qb}ޔbWIvI*M~4z"Fq7ËT~cC@Dq*O_{d܂g'&5ߺlx6]ȵ=ФFz\=3onu,9wSvnJ6M3337r镗GB>O_v69K?bG̏Mܝg4M.doޫBtw LIENDB`B48x48_Folder_Outbox.pngrPNG  IHDR00WbKGD'IDAThKlE3޵c&mRJ%< C Q5QZ.@*;6R$$TB &*TVHp@84$ ]Nivfov2(3D1:K DQXdWaGg%ZeJGvUMU!npdAɨkg:5N?Bg6Fe16H)H6ŨKHyS![ބgA[D$nvp\'oKiҰ#A*kOtW0^>X9 0k6Mq M7n^r`XWlO6 P\]3B$yh`rsʀg;bLMpK^8<4TP,m@T" i>+5c^`/a {7#;Î, ִg G<N8%4&"j+$Ó8]lgW7ׂہx̄˼6i U_J 6f_6L8`||+Z:NA[>/[ZGJ06'xL]@=`_*Dm:DKM#U8Qjٞ[$"9p3 EuUwnATomnthD[#އ9F(bøAY/DYd) ƍCMҍ>%Wځc╂a*/@ϮuiXAE kzN`~xgk=1E?㒺tSN8 O%]aXS`[tL.YiPFl,3߉b:}yRy'l5^:6{ymf =ZeŅX6f6 sLSMOb )ʟ8jظ*\yBW¸l2ؠNGIENDB`B32x32_KRec_Record.pngPNG  IHDR szzIDATXŗ[lUs[/Жjд\ Dh &@| $L !H|E#( 5"iPݦmf Ɠ9s9HBϦ:tQRhB ( P IpMz ~b7 sN @mm-'NT4=iҚ3J^twf&,4:;?gup1sB,#t% ÕʼKg*dBv8@0ud8L[ .{:{+ 2 E+^lMYU8NEq:B&$)g[^μ (r婆'?tҀ$+L>ZzuQ]偪a`hڸd5Cny9+aLѣGm8%p/ Uu{,(޴ d3D8,ٶEr;>p_GP[p[ys1Ix4Ձyؼ{v!%Fdʵ[H) `NE[(q 8זl܈,f,(CXPYIͷo?'0$ESTVMȑm5gC>YXOSzY jYVz: 4'L=q?S(uSDȄ0#!tաl #@#c .]$C!d 9" [u&h_Q$=ۥ@[]--8m$h)!#(!n CQ?P_=7n '@ܒ~t N\`$ B"g9K8W3GXv\. $Y:QM#a$8F!p/eXFma`jMC\e$YU-M!0MC1ժc,4y uh*\ l>wSu]qh -o=^ Ҙ\"|, 2@r7@ cxҭ<4݄l>ڔ6grÞefQ`бCi 0e Tt4`dccehJP`mHYJ2 A7` -4#29 p3P'S,;뻷o3dv`x78OUe߁} !%U`_ -.D2^2%G!Ohb0}߿ ԛwS \n?'ϼd9L N.PEG'L%5I PccDZAWGa%H: }d;pL nv534ͿN  p`}Od``, `fĺt1e/ðPOђ0Z iP{- {d1CjFAiv [b`: h4 e<g5QYAP~ i@/f#(ð6ë  ?b$M11Ș?`߿ %1\X | t,pMQ!]N;/?2{pedm|$TL̊}͛ e/2< AŁ,W 30) s3XKJP 67\A5fpfM`ieߠ  '!d|hp'k3t-N)L5\,wdԴi؞b`eBǧ :(20 5 @,8K!` Ђ y>cge`:BS O? i[UC/0 )+i" I sn`@Ҝ 131=a N9n`V8O-( " ̿v/Pc|qydL:@pa`Ɣr5qO+W`~(h9%/r|Nbf~t|, @,0+p? SVcx/Q&%``-F@ *GK@9=2"' |`{ƭO s6=fՠXXp0@h(V߿̚ 9> L /^`y=8ٰY`մ<4j  $D+cū_8D e x@a؊~@N#vkA4V`- `a~ $6F#!@ԎPX`:/(_ t^`RE 0b1@@A ~31*3:[[wXfд6%# b)`$Rq3_  F Co _ P=0I *(1k2Y'PKu73|pl=+?!_UCRz`Lc \t``XpM7d@x/XD?0&ɉ"`o_j͠*pX:GH'`| X8@A L*Hj& r2 '1\9ta*LK?!I#$ PL= ēu@j@5M|+`-p@ǿ9{_1\=qj ?dp{` tԴ, <"t|0&< OJPaj3?õ).Cӯ wc2[@ּ ^a6 ,|~u=bbefVa` F@k3`, @'0̀yԞAIM3~o g (D*2>'C Ifx 3##WF Z0=1 3NB @.0jSI!9BFSa`]pE>c,L%@0$ N]p],gD S.f`yy bdr&Q"w 5\ -nf` l߼ )q@w]N@׭:n2(@3[{S `/+=")' $% Ŕ D>>\`¡l:0L@WpA T`l$1L@O,z\C֍ r5$) R/.>hQ0o@Gh 0 T a8p ?A` ( 0rْ &FB@?82$Oa 41ڔAs`- t#(@ c젨n\(43 Mc`w_0g{`o*Sfg0*ejfGlN `g`a&/1y׿ ?e/^q<J - gPIJ:67>2ܹ?0䁑_3I3T/ͩĈmdA e',؀?pXbq WHer(i dGP cVD-m10`.!- o>!# Y1H J,<<ļ`T0̈C< Xb-`; :`3`&; o`L| 4#hL` i@`B ,&@;b3 ,%@ i!!!!ooIENDB`B48x48_2DownArrow.pngWPNG  IHDR00WgAMA7tEXtSoftwareAdobe ImageReadyqe< IDATxb?P8=@C4=,Di =LDk($.R9Eh QZ@Tf{oD [ JFh(_Pxd+뙼םbb#XXYDL 4?ÿ 6 L@_xl@4, xHW5  ̰BAL?@&E[^2ܹݛa?PG,'b@h 0@t-K\  W ( pZ|oF5G1ɰ3xp2(q2Hr0Hq0(p2d2hj60̶ux9 MEA_@S'0DF ߿vaLLYw!Ç?X~10|3(33I0%1Jm <& -YĘn>a``9PC#10\e @'ön -޾`, !?_ F[0 0R`*z6d -İ o9|@G/ uf=,~Hz9\  ga{/ |cЗ``Pc` _PHX؀ԗd0o`eOgİ9:񟿂Hz| XH!r񛿭O: bm`JU\^'B;clcfvae8aEAlx !;Ý Թ@?r@Yj9?}% 2.=qh7`dcPc,@`1p#`:xPg @2H b!Wxe&5(R]yic-I.00ll, /32|p<eܷ0~\ރkЎR*b"^ 0`Qx Mk?3HrkEU` _A雉A ʬ x.A߀O! @Ld6AK(o.kb(\KWmHP߁I:T΃+.xt<]FCU<#6\ɼߥ s1|V!̌AV@!I2m?VR@(+  Xc` @cf@i Fp'6:*g//3X˞HK=9 ǃɃb\A G\X2|# 3wky3?@ֶ|@ZHakq2p10L %, FH@uD.S8vp%Oo?FƋ3eȬonH*l]B" ʺFϯ@ֈ,FF f O .^y!UN w!L/p9 awMf>S[7eH.?l`P!n{ Jba} /fz@ r IƂ&`ǜ1HQ"7X_Ja Fp!r47(=O_0|=@;A{@B&+VXK [BHI+`[C:/=;|?,)$ΰ$c'p[?h}:ȕRX @Ġj [s~!KT!i{]`6ac#ƿ3sJ3|%X(CĠ%_i.0Â@w(#& 238X>1ew'`w2LX:0s 0K3 H?1< Eg"fa r[RX݁!l⼻ 3pc6H!;0Y@Hy @Gx J'X}ظCa5pB!X3/J`{LLTЬU: 8l Sw3`rJ2# o_Y -rDYcn ?'֞}\`^2l ^\S@=^> y@O,~7Cq}˷24`l, _>3a`]oSbF%TûxİG~19 ص @5ḑ@}lмqb l _}< ZeD $`1؎O5RZX@C~ h{  -,ez IENDB`B48x48_2UpArrow.pngPNG  IHDR00WgAMA7tEXtSoftwareAdobe ImageReadyqe< IDATxb?P0@ yА@`\ adP9$>V 001f`b^ /Ff& c3Bh0!r0owNbQ3~FfF{001dgP"EbwV m "b @AF@QU ?O:[u#Ch.4S#; TL- Z`no?[ED9[]<b`X[E'7!!'j5, jx*%@ǗH1t38(1y0s ?201(ػ0pS(0&6Rj9@Q `)ˏEUa$.߇8 o?>~b`Ǡh#! `~X8 ({wsT`;͗ARVm9ds) 0m209D]@28"@˷1|L߼\ 20==l!߁W /+Ehf(9 r2#eʐb3.@BZ ]? l 2 _A QFPUAB׀+|ؓIq @b?Kq%CJ>c`hp0Y]'tWpkp[l2 {/"*lPzKT.b  RP01O& [tLA!,q?aw>Ͽn9`?$1(Ϡbi&Tq@1S蕔bX0ݛ!,Pkin`f`{ XJr9;fbz!X| _&xt/ٱ 9 y$b,yE~@ǛK1VPr#0y9'2s':$s3fު+ Ϯ2`gж7c@}ۀᇷ &e EXXK3,ɠ(p%ów ? ?Ma v;Ӹہ1nug08b`aLq=a ,' -@ˑ2ʰ`',?S`t80 3?.=pe`U h38 ̤^ l}puo ?=LJ_Bb/ c`he @.1cacd`x'~ #aS 7/>a` xC"=`Ly2p-sˋ z ?9g3|< *r c/&@㿭7I+ 4` L`G?@dz]! 0Bڞ1 j`=,&%>(0|aF0 ,'p9 p{^m~z#HF {j@xV s0L S LN0O a`cb:T׆˙ĈkXd,4Y`8 JPs 40#!zPlR`v+aK`@Ci vj՝DLMP4BBRccQc@.ID>1a̬ ר kQ28ȣ@b1FFm JN2,l26@. Ji@:c>h_Hyt@LdjЌɌ> o`W:M!=F((s@rAr:D| AIDK8H:(m`o5?ndؿ"'+;`5̀/ #DThTy07$12k1"_##æ M lmV8P@ ^H~±@=mP+$`_njjvpn.VlC@wE63 [+ `kSDAyZˀXcdX@yXfr i,d/HLԌAAI,u XwAWH!'Ƞlio> w1bܨn ta÷?Aj 3k-UןBڠw`#3? l2ƨ8P&3|@q"S V -$d&`! jA0++S :2񇉝AHADA Sp+Lr@xxP1i0ܔ={YB|×߿3 ˏ?, r:j V "D{WWb-2fxtɇ ڐᔿ?1T[=a`b4 "÷cx *R<j,02 p7%NSID`1#Ѝ*x' ? % `r[wwwh ~@d@:p@xF%WFH}VoX26nQ!JkP;me@14gh{  (tXxpw IENDB`B48x48_Apply.png' PNG  IHDR00WgAMA7tEXtSoftwareAdobe ImageReadyqe< IDATxb?P8=@C4=@C4=@Ca^N.sPym?w%}`>0i(Y`!e}* h-Ao 44O>(x{{xw0Lpx}` Y`^NAqQ3aQaC ]@ Rǫ:3g޽  ߿ ]\RZ* * >}fx5:h0y@ߟUed6?ưU7޽dbb)D@o)\"| nBb K_^!S])`%iC>A`-ð n1<7c+)ȸ (򚊎z34C$73 ?߿g~ @bddej/0  0c,`egfbed01d/ hz0C,0n}ʰC10~gvF&aUgSe}?`=!C #+s2(C<Ͽ0?&` Ņ@1afbL~|Գ Z Z *& ,|@O7ҋ90eSg3f1daV:X(&0>yǰKs>1}33s(Ʒ4'No]҇ ~ q &\ ,^3uZje. C:1/o~1  46@ax aƷ3yr ‘ R܁^ H47A6QPEsnP+CN$;o߯6{pW_`b`UJ0Ê^3Fzqgau[!oZk}o߿`dVdcgapWbe`/ o :뿗 d8uï[232G3Y`҄K\ 0+*0H 0j13˃3ߠto^1z_ ߮9?^B @a_##.Z&4"(0x ^2^No dC0_2м?ߙ!/x 0c7 )ü2aPe t(#т, /`e N6 oCȹ@3guJO $!ft>3>zI#q)`Ì? :yG+2`#-KFR*[ ,S~=`a l^ae`´1 ؾcT@X3//n%AOP`?p,BT~a) `;;O_L غ3c? gA1 0?,*02=q/)1}c iӽ &l1 310Obz#G_2|e >a8{I,W"Iٔτ30aʼ-N/2|6Ⱦ,0m&7'ebfvG X?c~{ g l0c g7@|o7xu+}f#=^W'nfdtP%UYcƧ Ipz Ok?Ggw?Z""C>36},(rWP 5&WZ@%@712[5cf^X@C~ h{ h{ h{ Cu:IENDB`B48x48_ASCII.pngPNG  IHDR00WgAMA7tEXtSoftwareAdobe ImageReadyqe<IDATxb?P8=@`dddptttP222}ˇ޾}{7o^ @,,6p)((0$  >)U@G OJG' @F;R# 1TW})".f^[. sNclwZZ+V)eSUϸ󙎷#0b]ȞCYt\uj`l666pba`1= ++T H=@ax a4({ ` 1 2HIIŐxA 1i%Wh.]c  f@!K ɓ$ad \bB@2j8 `][@d-BFK$py{` Hr<,۷ "~d@J!1@dl>(Г3$@,;%ɁT31112+@VVV`H |:.P3ͣ''PhbP nѠ@7[ jdXr<p8#*1Pe*N@1h汉?{͛ ϟ?'X @$BH$nz>PCTSbD<@ISRm!bFA4k'`s@pYJ4_*BA"D5da2Bn |I<@~;`L[ &bBʉT} GbH0 zdԤaσ3 &z gv%ElիWaj Pڠ%!P0j1@qz*(F"{T߽{ O B,`4"'&&İ_ z x&DXX 6b!@dn&(A&5Q(-!#0 3,"\za޽`}L[ &bQZ%bƟI XaqkJ*0Pe՘DD(:٠ºQb5*A 3|@##s$ FA511=2ۘ@/6 ǂ< ЃOrki/TUU r[@$r0?@axׯk-[HGD6jձPPPAS oc@NZZ:حmӧO>y(o@w?60)I 6b- V*j7(Y t7 =I {l-h 7IENDB`B48x48_Attach.pngBPNG  IHDR00WgAMA7tEXtSoftwareAdobe ImageReadyqe<IDATxb?P0@ yА@ yА@ 02Q X30 c7(ƴC0C7[Pl څ/kURvf::/?L\kT=-Xn< N+@4O_N9űmڼ .8&~U!EqR@730ɩz8X/j@ rSSZA]K7IPCqnv .2000 gˌT1˛[AvE|.' f8;} OY\"SD>``8|ᅩ ?02$x0||x ^c6=+_Cyn\'^=pw5Ǘ\*#R|Da`8~ϛ H10D_z;a l;D% PpNN{H$/:c[28zXÓ ^bçG@O!d3@PB3ۼX8e`I!Y*p1én~VF?oϟϟn^23D30 8j@1˯2' l8Ñ r|$C0Շ@?;^8^ p:fWN}4/O￘E~?q*ٷk(lI (BQSݞfw&s9VC ?pk5÷?B.3Y`_\t@.C<6Ӎ?6M? H;qjCضbs@P(Β5Jsb2ee8 Lof8>a- 6| 7ߠ:6VBjXg[租؟\ !.\ ,L֯Xf0V XHwB1SfW# &S@ǟHrMC/5/ pc8 *V3_t35k4=˖2 ȰEDbȃ`(p ߁!yO?%/;Lpǫ2lP̰fP tfWgV9u;  Zv 2u &_%`ܗ`%pXao"_[Bmy l`xsl.a/CJ1EIJ  rj "N ~ L\@R. "_-jژP̠#p0m}pl A & AM>\R,c8?b4=C%~``Xq?ó~}yrСvB! b`xpy## aiq4qbs?2yf>>Pc_l6,Õ Kp8ބSxGl^ӛ30<=篇2 KDV*2h;Ó˧^ Lz. <PI/fPk#Oa8ڵ]ZܟEKW3]ח[RgBK~0J b @?>ǯ2pjJG+%3{zkGn lC+qFCzt9!us0pH1W1i2y td{w8WC z ' C~? ONm <6RB ׁv?7720|;lVɿIj ʼ á/cUy-f#^pvwo3fx? K)`o=M?<=xWSM%F$7$[/ûk[nV`ՐF)dD5`1 tcN+)^Uߊ@'!;Ùd y.f!! tmpD_`,v``xtb?Obt f8 lnfw7_ނ @X<Π,mCjާ '{W0k0T #à gɣ``+ر4 yßAXio';cx||O ,*! V ]:ÿ@ǟ%W@Xb cAN/Pd VT*%01<:~~`9 rM6(PuqwCOg!%}BŒV&.X /TaH4 2Vzjg0903<:~ O/d%A:C|$ifU0<;(;UA 0)U@G OJG' @F;S2H$hTW})"RrIpwsnf Y{2րWk]wv>}F ˁBs!NZd`e y ~R@L$J &&&0-yA[alr0}< @/ _0IC 00&+!&?vB%+d ;gD0 lgRRDsNRJ8ŋ 3#`ɝs{fXQZCsCո7ƀڰ+Ur@  TLO!XF1ǁ'"?hfZ+WP 5 7|ޕ-D_ 3MKG1*%%%9 fA4 jjj23K@r WUUc`i9BZZALL yd8}h1 d``@D'M%ec^sCC;ZJlM9;Ĺcz't @!D/ڥl, EY@{'#?*f&!)c @Z+Q{R /\TUA8k->oNϼ;u9/hJ3Av G Xi qC/^-[L@惒 q_ɁɁb ?*[42H=@aMBQ3&2Y\D` ASRJR@6@G_ |z8l հVઙ%!Y Z< Ăt%#bW \GW - Q|} b!@q%L![U^ b1ZY>XӇ/p]6 dTق`HY>vҧxZK>~S˺[Z, wgyd͘536*4dxfJD79 m)a"1K7j@wDPl4!iA(NVwߌV"0 [/a.Bޛ~tl?PD41Đ Aul(3 ~Oо(pEx{ɓ' ׯ_7'@M`7ܾ8MhPA-X'''r%[7 "؜`mv<ɁW@ c J5=rLU elP B B)R[DyVDָUoYAa_WUM\^y]qs{_|.P\YY ɁB 9PȾ}A^^AII AB8P1^AjA,ATl]Yd@Q`qرcvuaKa 1% 6 aY8y 06L 9P̀y0fQZDC`2&Ɂ0Qd#Wk#Y3~C[  AG jPD?@/c6-Zz_ b0 ҁ,%+2ћ/b6b"&Ja@!B*rS4 6C\@r6/  NAةė'tWprBvCB:Qdf7lf67CajB%y%GUA}ȹZтGB[P &ys9T޻w%B}}}p(VVV7K@cMd yPj}Pqʕ /_$@LQyTKذ"( 5 ǂ j<󸊊  USDSr `Ű&aX JV-Vg`@kuZo޼7"AvFp%!b"vp]pG^uh@zjx%9P a^g:Ɂ . 3A@|@l&<2 Ɯ7nJ0 07\-l6DR" OFKXs }Ƚ2P3d X(FAjiiʡ4`cy֡%Îș z(r2 -ĐG@lА$LGoc[+݄L;[眐>d;eb0z?416Һ $r09?@ax{F`$ zQsY(2yAAkA &@ؖ:ii`&mӧ}33`TCw T }G0l|` b`@ 5Envn`a9qT*  /Y|}<@pbd;J&*)0KJ- (7c82æӧl<C3Pg{51mΔ?%7е CFCf~7s'>{ 0<tV< K(20|pP ؠ+x~ A 3#o e"?cqpYSW7cbT:0@%`Ԟd8[pC dIEF2++-Ȏa0 86N\Ȱܹ_[޼QC w)%@ePGfDJPm ?.0tyP0 ,JƮӳ.,d`abfɏA)E 4_XXY1 Uǯk/N3I|c 3zA L t.0'{w].Eփc`ٴ d1 t1#0?|=v/0/ #00nB6 3̅ 0r3eadI ~e@Ch(0*@Ff 0N`xs:8֙!0},(SB+.t/@%] ~Fa5 @1!ca:Ԁr<`+AA Uh:(B_a u,3؀s u< D_Ԫ cIʤ[20\ L`RPPL.0Oᾯ$C:K,2#bYC0 Ny%4Ԭ @( g`>ё1|y8Z0!TAE!K/YK C !'~dhQ )ASy1_&,yj@@]nb^߾1jz3|͠"/+C0fN]`8!m~^hoA@OBF&"{P%p*D!B3|Ji iZ1(I0,a߁O 1HXP_H &@p= r1n(Y%O7 ߀y!0@&C!#$~ *p;Cor^g+!Eo`7ĄB`yo' ~fUQ Q - D͚_PPZI?pFAG?Lkbh) Og?0ibBz`,X{'f Tlaߋ0V8!s8f2B;g&6þνgc`feaGsO00,>p>C u|S@,hz^3g<$D+"FPr7OV3}PΉL(9t3`y*od˄м X"]g K3U@P_dVc=uNPPNb:{ {n -j9e,Ll@_O3y/v c;T O>v֑3_f&h'0o[槼fpx x 6%De= )I />|~'QQQ^^^`Zgbp#3VT²o&";qaks3@(yn.03C#`ȇS6ƊO*3,ةy+?+76`3Iqfe_b|zá 7u\]xshuAIhq( !NJB|Ԅ=X>< lME+# *~tv࿿pg{ B$sW4@ &P03N@Ӏ5?2@uA z} pzߌ/|v'#ycLP?.?1 7gגw1f"VVh)qB`+9 y孁X2RB6&`^w=@y (_~*3:n"0Pw} &̡գo &gb- 4/.'B_ z H@77_,U;Cw(2'q:@_՞e>cx(V Hxtw~A<ߘ#{ \y.dd8thPp$7cz he@z_2 _$9" xn:s ^V1Z0w&N@B9C >`x:H@mАb!!!0=/^IENDB`B48x48_Browser.pngPNG  IHDR00WgAMA7tEXtSoftwareAdobe ImageReadyqe<oIDATxb?P0@"0O2h303222qM*W ~c`se1](#, >U_cDx4eEYe$y%8XË_^'g{˿_mf`|#@~|J<pu1d(PvUaeP`>Aa5_10ŔY@[?#D9X83Hc{t1 3~ t40|(Fgzn/ycbxr!Âytz>FTa0uspOwRcdĠ#?`vpra:0F&/??3|:j>#/ $3Pߑ' 200k7-ax> .O~0vzsps,ͭ%AKß?`& F`j9X_}(W7 ٘?xp(:ÄM On^16O *ÌmQF7O B3( 2| v`fa6N^>2H,e`'O//"?3axf'g2<&u { J 4crdçW+L$_47&&n9!^a ~%gYr \ 쬜`?'w  fseJ`3L-2v^eafpt'Q`}W`fddT`fZ).6~` J2q3/?~?Q߁ILCe&7Ȇ߻2uP-TN}.",WMV2 gggZ ₦ | jp}pm_&@o?8dsׯ <" F KwU0:22Hd(T{GspxOIATĔK?#;A_=d?8%)0yq8ќ :<+`S/`_? ~1ڋ  ܆ <@a 4t(y0;ADa ރ L> _|(Tgx>ß_>|piۏcARTARD۷o o=!q_`7аv2L^~rg B̐,jv\|0?dxW^iŧ> Ïo/<+>1c>.-~yptז3J1d0K{PDSqe6ϟ^' y}3/MVw-no_]k"cHUcd`eF<01dacd3I k t0qUX _(ςc؇Va?phFדg>zlxG?(Z×O,ldU<<ɠi + @(s c z6`(J ]] '1hf1psK3(ě T jV0RGBޜ Ll=C<  ?<l[^f; *z ʦ@s"4 51q e`f*F`!~po9CZ?9!1q 3®AAc??2ܺ3Z3H vP^"xw->a``1kjơ 8IKIF`Wa`?J1 + +}'718[3&i~n^Q `+` Џ_|wP:/00@ܿ&J^)XdH 0dbD;\ j! j\afDy@CL<: ~C@U_B/~d0tV`R2py LbNJ* u| p6 a&}( %nà*np]{g1t V~3"ǫ/ay'   , N@, h&Ab4% ,%-yDx%"JBPXڱ3 v2/3ý~: bWϥy%p^(Ơl;CPXs2+I\(Y M$3ؙ}VFTyt * 9-?>1(0|p+`3X W.| `c /aiTΠ%k *'+$4+<Ab0>Ŋ 9O`,*``un~ l']gekĄ< Nw <:ܡ۵V#``b';~>('<ـ2 z)C@ I{=`_Ǡ#kV#̠g0PcQ=çX6lgx֡Yp+ G67 g8t6) rzqA,C+vAR2 Fr*0ee3<|JlOq,?;+ vxl\M6'ހl >10g?jB_ 6Ȩ3pn( eͅ&A0 N6* 'P}"P l1,\qG0zNPD Ą94g㧷wv/z!ɼAÅ 6(fb6$ Û5ہlS<̡OJyꤥ N NwؘG`z?`-S6X< ١4;tCJ')5K_j29 ë-BhE B,6IVW(E P i >3+8Ld}X3ɯ@;ƶ /xz^`4 pd7 LS:>_ח\S~_|/a(/֟A(TT 2p9 #c''&}jF 6 7ٶ2l{ X0p2q3hcf|f'~C3g~3# }k)D5IENDB`B48x48_Colorize.png"PNG  IHDR00WgAMA7tEXtSoftwareAdobe ImageReadyqe<IDATxb?P8=@C4=@p1_\2(ˠ?_y" 1И?@[fL W @1bA`? @kxY88X0 >exk}补@ ж v.!aY^MaY-~E]^I%/8003f`d ~'01|~qK0\;_ nup@Qy`HŐĠ&,jh(t(//?Оc`` H2||aӒ[ 6gVxk<@z@o8DXELT |tTx }d&<#'?1p:Ý 2sc`.}ɰ<Ës00u_B@J*dH4g0 bS"0_& f`fb.` [1np36M:&`F ^bҜà/ [0ܺ%;/=@x 9ԭ<}^:wkqy6CjFA~w?1axM2;[^<@ĔB,C{U:Ј C ÏoJc$<~a#þ~P!`l. LRTax/ Q` t۟ c`-ɰ?JJa & ** cH\5A\v20? o ?12ݻð^(?;g`V̌ , ,3T;{!׿^p?@fe>03_?282nb`e {q5c`Ɛ t ́1l\P0m~ 266wo2lO &`F%MƿL < υ~0ܿy=2L*b0!+2;;n`c_ bZ3gͽ8X"0G.ZX,a$݈D{; VML ,ZDE33<>rݗ ?e`pL3+C/ê k3v. mv2Hrc?3")96aPfs(@a@+;g'Ûݳ^a`de%^FAV.7kɭ'v{Nf&? $ EI/aa`cБg|bos& %$~gS?Ϡ#0xR`Q D2k193 {L@w= *L> Oc`zAJW_  ;~$ !jgfx1Ò)~ym aBq`ަͧ~^HPX~g&o>3=AY YDtD $?tܟ$@(1c a!H R )5`dfaFq7@xhg<7MR*W !i00 $(w^ @4*jl`[\# 2>g??0p1Is3HA~Cw` J N3:A" ~mǀ ̔o^`PV =PC?, :5~0ܕbVa0V`m?T ￀ X @3et<% ;f?P1C볗 ggQcVe?P9Ph8 !Ë/ ;N2>A($*>1?phY"03׿ _^= ) 0(3 /3}iˀ~~axw.-BcX-35( /20l 1H0AZexkmcӷ ߲=:bA򀎰0]C4хwcVRp_$DeO2Cc YB$0CdbG~}ksh18^h{aϔ  fs7?˩c0w R&'0,>]6$9}pg Lܼ < @et)v@4`gFhV69>O>1@ w@1\ \z4?pnbAJK<쬐P$?P: H r%% 4f@f}]3 *Z>SÁ8g0b5 oeiBdb&@=?d愤cP1e<0AC'DCr')'8[=Ù]z>## #`c ho  ڍ\"~'dĊ\nC3" HE gЌa`@t=^~o~-!.P=Õۏ\gx+CP?J Xjk^vn3)*# ?2<Fg& 1{Rv3"aX҂p FTAT]@c2 2r` Bor \Ós'B A 7=dxu. @1 |cHAy 6a3K}c6>2|z=P @LH8oz7!&~0#{a GWg|(اλ+b޽> /f5 _0\cdxr 3;CEԪa &+/ݻpZEٖaxx -g^:۟MtϛC #!mC1#D! 2\9v~R02B#g =.m`(v[ >~Be@ -?&3uF°u@#Kw1ܹ*#nrfh3 @D3#9Mwddxp÷+ρ=X8ҁG`JAE?%_W`74ܘcjDto`9k O=`0+, w?,W`&`Pm@ ߿2rZ'GGJ7pˊw.xp"7ë3zx`P |pht }c9A O5Y9IQ+[u/o3MN1|n b=@Z l򭃌¢& <5afb`ZȈ$<3cj_?pOwX>]ǟ@%~  |[KP7f` NȍFJx&P ./72|)h/RФ ؕ}` _>g8w íkl-קMoeGd@?~1|~p_ XsAFB '~dx}' ylܙ."Rm-t6 !Kpy .a Wo RQ2@Dy_uȰ򑛕ҦdM `  [o 0i|ӷjfI(jUfDɰΆ(qU`tU[NATǏ /dx :%Ч`_h9Nq1.ӌ+o10rG VP@@obdd.@Qe袙@(?d7i`>@yrhOtА@ yА@>&\IENDB`B48x48_Color_Fill.png PNG  IHDR00WgAMA7tEXtSoftwareAdobe ImageReadyqe< IDATxb?P0@ yА@ h 03fbb`012ׯ_`>@8ҀM:˗/sc9xC, Z%!V nL^^^֒ &0ȀBnP _ ppp0033e@@rrr  VVV <<ѠER 4== b@䣣ܹpҥXgk@ $x0t[EDD***Y *@AAN yyy %b?:t 0 0TUU1hkkCP( AIDyRF %%`'O+"dHMMe8{,ؑ G߼y@q=(` (@n  @ yx.qY=0@^gxC0_lm.3%(*A5-(c<=j:Bݻw`=Z@1C @P ^`zn7XN [ @c70dz?x:` \ 1 Xkk222&( ʜ.9m$'^x6   ǎС+6{YV fـ%6U(-,%~8^k<3UkNИcDpݽ/DAaBY`DXf'bA<\B$ʩz;|G+1,~;w.X] | σ3$8 GJ:XuPm,, >-x-#$۷Ձ1 ONuYxxNKyx+$^  %`+h"'8@!E:n@1KpyԩS O>%@e! ^6Cͮ_ׯ*rJHH`'`yTjmٲ ` ΁ 憆 DϷoႠ9_bUxpOWl޾JK$2P J+ 1jS 8.c)566U.'|~23[-HLl翯_@-PSJݻ /k(Px#@K!P&%z߿E΁b%޻w/UhĠRT%&! ы߬lw= \4=Iȑ#p71l%1C\X6caaAmP=i@ jl޼|P P o2V*ެLhTu T`ڀ l35քĠ6lpuPdPhb6%P00Ng`Xs)cb lMC[ ,z Up*@lJ0lڴ VME}  Xe 000  pgCQ`|vN *x5@l /Rkdz*U L?JM@6 X`I 8 ,vP<(_!B'+WM 9Gvc\ vAw8ytH`wpgO |@i4mTX0;Д@:DXޠ^kFA=2Prrzrr3K81\0_J:q |@# O@$h~ ;HJ BOa YٖG@: @1 "sIK)9#X=`B9DCY :JiəAJJ D!bEZJw@-cCj2zB-YqZ!8 :bW~ŗƉI6Ę@, %w?3ٽRA4Í3#Sd'ѱ@l!c`TM2DV+!p/* ƚ ?1|ݞB U{U+2B1@, 雁߿^0!d> $@v  G5|B1i Bœ@G:?` @Cx3i=b`{DUR &?_ ^pcL1@İtEgE_md>LN= & |ME [_db/+ +@01psq0\aْ If V0p=  & w XAcðpÕo&L gd8p:fFN׎?I!6R_`Q˷/ vjv K3N f螴A^Fԡ 3g1Y2| Xy!:;þ= L aX?b PU "4|A[aS` 6ix &B}OXeV')@`k; [r!mC: &jv" ߸>=3(1@LԊb"gs0@ !B`"X G#O Mt3K 7G5@ax˗/@xPi: [>{,((a؜0:c؜1:!c؜2cǎ||| g{ s\55PQQQf:u+89w'`,r;~,@tJ8g9贖J??Z @C} @Yj IENDB`B48x48_Configure.pngQ PNG  IHDR00WgAMA7tEXtSoftwareAdobe ImageReadyqe< IDATxb?P8=@C4=@©j!:###7P= PP9-m6>@Ubbb"" BB" ,, ~dx޾}_3ⓀyO < aNN70--uAA~vff&1| nݒ8spÓ'w1r < };yaaAVV&O_| etzb-=@LDz??ssӦ- `O?3z(: hb—ly?k]PgcgX`bbd+;;3 ߿'€V &j`r߿0q -ao{ ¼,@0cABBϟ?1@1a)*UYY"|T`߿<_a{knp ř`{D,9H[:b 0<F@@YKK!<<Ƌm)~:@i߿mϞ= eb̌ m EZx 0_#qpb`7;py$?~'߿se'!P $6$$l@@)F% 1  ?=/ȴ0|ׯ߻wϟ`23,@1Lb" S@`0tR~\ڸ8w߾uP 7TEI`PBAfb@6 ;PTÂ<e?33H מ=d12S166Cs<$ׯ_ _~\ GP@# 6\{?7_|\`/P^9^RR^@<NJ?~ ={7di)rT^997KK'55M11q`;TB\x 3Ф[)S&3l޼ 9\L _xb@3= J3v+9 bcVܔ%5 Oa:u Æ +0n"`+CHـM+T166 %577}m`-֬Yr@x XHJo}>f M+cD;33Vě9PVV#ګW/ Yb@LT+n-ؽ{E2ܿX|#T< ,~8E,@1Qe`~҇ J>S=7 5@O,z" 'nJk]7o&O=&@#PQp-$PTTFPL H<0&WZpcΜx+\ }Fʨ: .'H6KND@=LNQ+V{ 'OނYaU~0ObX,cb<@4t, ́K~8g4pGx J:Xsp22$$dc6扳x񬫳fM&?(& ߿`xlK= ə?<@449X fk#%!.m- uu1L`g͚tcԉ$PL R" 12|&M=_^~~4P&{xP>61RP9M=td&çOz gϞ1ܹs90Sb@UZZ:=::pP m@ڵkX"f hV kp{{{}P0ǃ.\d!V@:f$'M<hQ 8䁞 ǀ0(޻w4쿀@ig...}=UUUcccΗ/_2_~!L=@(8;;3.,ـ0(+.`fcczHSGt >QQQ {/$d~2K F`(K@yzz2#;|=zpŏ:KHHH_VVVYF`P:,017> w+m0_o(¢gyyWc6L0h@x=<<&+))1b Az` Llٲ@32%7}@]߾CVVښAH@:Νs[_i,~"ׯp`Z#`E'CHH*@I T##A @z@b @,:BΝi11 |h+ )TUe};iҳgo}لo NfRp20(( 5*1P3իW606]-@ ;/##͛ \ LwLw2Ě2{ď 99}2n/aa Г߽6 8BT:(5j1CD*g28qٻwZi~S%YbAN?*r ex yс/O((2?Uׯsb?)*v͛\`Mqp` t(۷֭[ v(_x`ee/VA6N x7 c|e @=w-?*C|}޾eSSyw >D+ Lf22 VϞeXhi13?t1a7" J qP G6/3:WC1E6@= 3ֳ8* 3o~|( TTI+01L f|28B͛`@0=p# @T?:)*BM !`P1!ՐbXl00c?w=)b` Lb_0AH}pow~,&/F ȭ4@AE(ā宆#˗DM4/8T`RaeݾZA!ls@М )?WZ`o `HC6Z 1[tA}@[KKOݼ 'gx9LY/-=ILmo;?`fke0.f'n_,t)FԔX3rC*2@!</ ǀO/V-Ew~rO0{W2lx'}&Vg 4 xb9rm N&,fL>tj=|ȰB1=՝9C˗TT%0jN8G#@!F ѣ9G1+ C `z_sKXJJ>}r5|CG|<8`-8M5@nN|Ee [0%,ek2t- <|o咾t.AP:X3| ##+oV99_ihX~:LoG&Px`+%,Pra)0>P &]*`K% =6s?v5{lEsl0̓ jl <)"/K,vZ@@k6%<ז$, lBU6Ͼs?j ?`l=zku2@4*j1zfa!# ljm۷9>in?u=\_8 I}?rflycqp/6O}׽{ Z$!">@߿$@% ?'m&XO5gPs3a j_ @jPaA}V`sNFQٳ?fbԟ/Aeyy71Ҡ> lϼxxN>84M߾}1C]99‡W=pBJj'/1@u811PP`0by2_3BQ]lBBmp<II4(&6oʠ *e@1 (s 6}?"70ybD]*8!!cg`/ iV`'X4ϰUBbo RVWhFjb"}!㇕߿Js~bfg>] d6@0А_j@C4=`97u}IENDB`B48x48_Edit.pngPNG  IHDR00WgAMA7tEXtSoftwareAdobe ImageReadyqe<mIDATxb?P0@ y 6AFtXXաXX?3  ~Jn NdQ``jĈ;XJ^$nҥ^ MCW @,8ǃCH?zo:w+JS`,^n`>aELvvفFc@@,8ջ ^` D;nO2\y˷ ܜ R 8>QCC >n͟(C*رXedb`Je ~b03d5" pC+9A|p9^bE%ŀ&W J:@/$a b1*!< PG";2PïdCP5 XhlO6 ȜЋZ\ X"ـJ 4QbM/@,N6j% z&pz u$9R  Z&d4$Q;40sqHBdy" ֤ 8#&HAJ(H۱ՠĔ6(IB c@,ސd@B68ԑl31(@BIH6 b!y $Б?@|ix,  ?f/0'3GJrLBĂ+|v&3A  m0Ǡ8GG(.@=҉Dp0A\ZЋE\Ɇd?f>g Q!ـhYw1 a`2Ƞ&/;(q%,.\ l; nnN5i XU,@,|:< ցWɆpʺ~ 9`h2*e`d?@x=ni_GcYIN60-`J`& tO@W]uo@?3 D0@&`%|CiRŌ(?bdb0Tep3`R?Ăd ߁UPJ JHl1h>vMR"XC*d@_1 ?<riɠo\*pk)T@K6O+Dl= J&Jr $ &MQp]!P! ,^PhJ[HbCl@3CАg E76@f)_')~a8#'MҌz136vщ~U ҂ L2De@kjEE3 ~2\ݻ9 LtNffdg_^/ bk%h{ CIENDB`B48x48_EditCopy.pngPNG  IHDR00WgAMA7tEXtSoftwareAdobe ImageReadyqe<WIDATxb?P8=@CI:!u 20300h L Y @,Dw\_P?Tt au=#Çdl\;[R@J"98rb*Bp[@1c#1=/H ~wvn+fbE,u"a^Ő_?vZ-`Tb@u8rlAr@A<Ȥce`)O< `` F六Gh1 @,(rJXCbG8 u0GC(d‡6B K\ZCk h́h=@PZC?jf1DH!WH XJ%x@ XN6H9MπT:g b8Cr&T3B'lebd@,$d  ه ,K& zdE9@1lBX?ђ/ HHd6n  8KH1D(+Õb Xqd+PE#J |rw1CZa>CȖ# _  z ĈF33buè4#Zc) dCaQ3?bYFyd%cZD@`aai<[3rR{`#e^\(4F e!-1bLȹ €=1uF]O$1W0#( T ̨̰Zu d?DYτ`:#733VF0aEFt$ߋ}@l[ϝ<2AA a|c#B٫7 Onc4fh(1K]gbbbx $@nZÂwQj_~4А@ yGTOIENDB`B48x48_EditDelete.pngM PNG  IHDR00WgAMA7tEXtSoftwareAdobe ImageReadyqe< IDATxb?P0@ y 6AFtXXաXX?3  ~Jn NdQ``jĈ8fddx̺K޻zI(2 ] @x/Ki"02 GGbcoV(<@X=.'## 3S31B r)ьHA820H 2p`3 XpEM:FP'F Kegt46Gҋ/ dG<(^wl`S,MGNHВ6@{ ޼a@nS!;R9 O_1|yIG"|a;%%mmu r%j/ΝpɆᔻýX8В Z]̈< =- /30c8ZF&̴ r#0/.\𮶊ʊJSANM;9T ϿG@dy03؜<ɠf ÷JCpa\eR 66  +lĎX4 o H?2؟= `l9wm-3ï*ݵg8l͙,/‚A(;W'l֔2zn POخ]ca``ٳg `É&#l Օ4pi2 & cL>=onqq! _=aRFDTDEE CܲQV5?a0Ѻjc@qIJ1<)gPQa a`@{g0PRe1b) @UTW3'زh&99`3"AA @ǝln`x LGJ 2 @?w09ቑ D`1kSZp@OUU0,]bb\c%Ir@6 ߃1S7o2<1bPc`bgFfDx =Xv}e9#672l t(3?? epr<(A}y${oʠ7m: ''&Brꉿ SS0ò1f0طX'RA/P#>ax?}60ٰ1E yM b!m.A ,E.43h3(0SzޕA{4`x&5Rk I! 0}} f ?0Onn10 1q32Z3&& HH:r&c԰`Z`@71|FH-P( 6 _^Rٖ ׀S0 Xj?K? r ?+J abF)/in2YQ;6GD zaȭJ.]0,ZΈf8#0 8] g+r3#'%\ T:'9`##)iPxjs:#DB PUICArVGhf &BPlLe c@8aJ]@Id`+(cxTP򄲎 Or?L@ X G%kO d&1͜ ,*Yn 1;d;>&Fm!b•?TVe4+o1qHc  t,[YrU9seãwo14ln|e !QIL @=4,H% KA +0|&XytF` Svv <g5󅋗~g1piբw™G5̜ G@+4%1hLAtLMßR30 t 1,eJ7c[Ăg`3*4*`v3é ǥ0M YfHxq 055 πK3sp053E3y&"jbb!T2b6 Xc91< G=J34 xYGkGF }E QGb!6܇!'xTdwFp j+%8t<RP lQPP;I#B&fH8G9l'$ q;Cc$"s)5IN6 +6IB`3~/j;ژ 126њh4&^ H3BDL )6@L8f)_RˀAEd18481X, {S{gDTXZW?M`пޕ }؄ͩĈmdw2#`6$hJeXR+$^x?3b=hȯ!P!ʆIENDB`B48x48_EditPaste.png PNG  IHDR00WgAMA7tEXtSoftwareAdobe ImageReadyqe< "IDATxb?P8=@=`i2900Qdtg`w~A7 _~oF?u/W>ĐC_ 3 S r}A џ^0=OGUVԋw gğAw~33|*a`b`WL@?UIFZ?s#xI^_5Jcb&Pe,@23(=esaM;n/ ABT2AB7cI" ?H3ݷ7 տ T HB< 3Y&PTE- G?0l|1@xc#/i@#^=IIgY$U:Pz㘘@Dφa) PccB3p @0 iP3"<2/иo!yd63ȹ,?-8@! XOqHr$27gPłTHAv nb[H)xaș9V0n@( 3 "CN6e;(ؓ?L1G#\K qIai?\aq8zA_hr<+F ?؎?Fv?!l/̈́G@x? HʔÉI6j9M2@k #>,II6p5P[ 5 gbfz<ؒ_,lV70ȘDKɈ9 xǬk\&@1m2gXN@OZ螇QpMwT`BdbЀ3#F)B@txT0pM @ITRb;O܈$)CEnC-b #/^T_"DĨ#ig!gI>3s03^8c_(  7u z& B1@&dX~"ßfF?ah)ҮBgV^E?l~킖@EpM L+, e?!NئbP h6HW E)okx@ďfQp=q? @h+Q ww \ (!t31?( ,-w 0{+$PC3/]HXЀ{@9SGO$1`v>7hMXaCg Bl!V h{ h' ( dIENDB`B48x48_EditShred.pngPNG  IHDR00WgAMA7tEXtSoftwareAdobe ImageReadyqe<IDATxb?P8=@C& :0V3CLzI ,,bowQ)-!щ, L@S0q \ ##wd֭\K@ij\|YJA0Ell?_ ,Q =mBy z]NFFAgjPC0CH +b7Q75#tA|Fޔ8pHrs!@к!?bl?bl!π.O  )I6ԞBg 5Gs8̄< Al@ob XCa@Abη? g Z%41 mhE |@,J6 D$?#WGDE @,l@I7P/a!|Q@,4K6'~EdNtu@,lB39%bBdʨ$~#DI33 B eDss@BԉBM| &rj e`fFȃLLA@pW ,̨_0}A4pHDA5{RbxV`(q` Sps`b?^@޼İhv~C$6b" = R _g8x2БIdcd`9p>0iVv6X@r0›@1s;X:{ P#50K/ P 07$3@6`B11@܈BIRhC+qR`BLɃs(?ZbkG4a/B' &b$Eh~ ?rQ| &\/DS怿P5i wޱAnp{ D| qˀdtcc3 XEO2Czeb@*3 ,iWg@-0z?Z'PE5 gi5ǀs?t$,r=oBL UFe;fz,cuqX@1s=Cq2Xj%4> @ke7^3`/il: ( m!L3G+2u1h`4%IĄ))1ao2ŠYFDˈYˈf]ȈlȈb1KӇw ?A`M L 54 ÚaDcD220s4?cglN yŏNlfPujn/e84/mXUxa޹ ;=?2023< -|fFHrvZ~ϰ_c@degf|ç:BZ^ex?8^|puJ>lT3;S0GD<'̿ 1~FMЎ_Oe2'ZNZ.:P] I~1ebf_^/c`ff7tА_j@C4=`-rIENDB`B48x48_Error.png}PNG  IHDR00WgAMA7tEXtSoftwareAdobe ImageReadyqe<IDATxb?P8=@CFFFr55CLcׯo߁*!0G߿3qaϟR76= AdkiE20,UIo p>*D'{4/=w>d?jJc9::I@6߳Xx[!! sݻ>l*H'zY]#`cϟ?p 豮bepN?&>X>}O *"F=Z@ )-ϯ_2|ga65eaa+fb%_ fE7 z S_?y۷\N3p 6AhJׯ\bfplM'E~C^NS+м R " DD,0`a `djE9R#~ y~nnX݁Yg^2|z揸8~`Hos}&¼$ _ s䊊vuL?G.v@@yvbnhhtÆ&ϟ3? dc[@7@CU''#0Q>xCQ?q9CXX߿Ź@G LFf3rq1()1{A|EC-E30*t?BIBYX*UK|>0Z*+$;У6@O upq}bb@O.tWTdx`OLd'ß5^^OOXc&1=FLbA4&  @Kr *XX~qf;YYvv ɂ̥?F)ZEEE~7_VF%\FU""e/?@G3 1'fƄ(##'~5% ~ @(ϱ{~7!z4 d( LhMspHS=8OtKHg;7oH=* \lB+K8_f]6[@@_1p13H @x z|=bP޲ Q v0'33Th(o`xk^&2`ltINN;G $ǨƠL~ F`)-۷Xđ# -B/+!<В_P# 1Ce fPPVf8Tw`ct)c@$@0Бkw:5 V'7=t4@6+L+`W2ǫW-"_v؁"Ś_(_g’Am]]T#Z/+yBWw/1 &b! y݁i]ؽ yJ,Rutt%$$&{5P@c@[W xHko8*1P'`57,tuAMI/&~ef{_7212neMAM?副,@A22 Sܙ}@ጁ\==p:Xy`Qˠljsp0\ֲ_8o@lK:X@a4]]kv|OIAk?CDXXX0hKKK7ه k 20j_<&-"q<;JUC~gcg`L P TZYY1?rDٳ Q@@(͋v`a&}s<'W:20N-aۥO1JNёA[AA8)(y PDžj!r'Y! lϟvkwn|댜6m3 $-0c?z4jATs b Po6AEE.K9V셟?ƇoN?y XSف*Bv`Ϟes` @(_wTeerrQ8pj0ǁQ{?߼9u7Xȟ{[͛)ށzfX26H"9 G|y(P>tj Л Ls| ῡTÉ X:p߿_޼9wpN# K G` ,rA jr1hx#0=zׯ/&'(_()u*qs;f@O0Aɠo!!`yn!B @?+!! ;mmp+ x`f8 t<2|t^`s46 r;@ЀlRz~vB=pW\8pfgvaf'..bL^ X,y uA@둁cO^SJMhu`koJt'< *+k7n0g` wKwP~ ~r͛K~b;cהLQX_$4܁<>1+t4 jA|B?#tHA4@C;a b;x=Ă@ 53( b:tIENDB`B48x48_Exit.pngPNG  IHDR00WgAMA7tEXtSoftwareAdobe ImageReadyqe<?IDATxb?P0@ yА@ y 6ՌD6k w ~ס,P3_$A- XF@cCFa`E)3`&&v6_@ zխ+ S t;0Dd,utxT8EEW/_2|{ͭ[ /\yEo4G6r@I+T% cǠ g/~?{yN0ܺp? xAJ R= T=4o!i1T Q Ʌ#~`#c`O L@5, w Ϟd8m'O.M:< R< Tx]M7;66#khNraI(|ʠ-(  - @<j 3ˉ20zv@>vX ,B<ᖔdg0 |D@30=ND .Tab: @<` 1 ß {e@x03ATW+ow0HH@R 099XEC`RcPRy¡ ?|`` +/`V @X=HBHQF[2T NO``fW`ȳ!FD0yz2H7p#{ \\ ff 4ׯ Җ J@ݻlCɋ { 7as+@&3+ 0O|}L'0<: LF@OePdPwqa3Bt80%Jpl2ibx/~`@p(1ͭ+ )25qq3򟍁uWû{\]~)+O :׻wwph'! ʠ?m!Po V` S, >:?uVD p/P##0=~ %)*(@X .C VQ1c)Fa5_: `֭ A Gu~hVb)@ݜ 2b'4 Ik%- ,[ xHbz?y6]e@A ( *(g10M`@%j&F +] 2p\(L & 7mXEm&."4#U SඓM%W,͹71##XpC`' X}bbeT (5K~"&!&𠹉=0ÃB x/o0|y˗ >~c`b` ,=#8ro pyoϯ030J1sXx`_߿g``P]G( A1i/Tq2hL oXm!^1|aX, w|e\s`s+@J};8d84ImeW93:  􋃁Xfp1 t/f5ͽ{X>jqr16+w&P`` _ݲW LD  MRl> _f`y jgP{xy8brϙ3 AY&c#y2\< ~dfPfһ߾g8 ܿ m3[``H5c003`,._.`rb6᫜,P[TCbefe$I`1 J؁Iy0ܘ6&0ga:^AoGhJ- K'cbrtbR& g=)9r8@JАH.r؀I ԑ6?642ܸx.NN@A߾ۿ)-<@X=Ѕ92bgg2aPUQ`lBy iMܔÛĘ២"` $ fx VZAؒct i <@DyGvzbD6gRU ~x ߀n`sH|̠ XsԮL>eSYA靝Aa%m?1|'Ply Hx5&@Z]IZ\GAܞ-Ƿ>?JB!0y89x4Oc?3\&PxMЪJl R=r@v0D1hI1(K2>ЬCAMj0clـ-J-p7pQ F%Cy lZ(AcbT^DANHA!|R/ j<m`?p10'~XiC@H=cj3-,YX@ iYhP_Ph< ^ c@Q:GU@Ǭ(@X_ǿߊZ k @|$t't8ԗА'!!bBP IENDB`B48x48_FileNew.png PNG  IHDR00WgAMA7tEXtSoftwareAdobe ImageReadyqe< OIDATxb?P0@ y 6AFt)}}>_ ̈쬐9ɋnaly& Z3ap]<}ovhkpȿqZ])A Nm`ퟟn \'hKQCJZ0=K%t˳^9,]YD}c0҇KEhy)~mi 7ó ԿeΠx ҩ.3|83 0X7 2K3bP4g`6-~3#0蚲0~+iF9>Q]` K5g{GXY&(a`Ue2gb^eOf5d z ?l2m \E>B1(@@iZwiHzIgP#5g9[8 J w.bn6Ҁ_߀%7&`C L?3((30H( rO1w&vM 9y1g Dt=ݑ=ݫ^p3 :0Y8~uv5a{.PnE'8?;o@ h2d B| = ?L, >c[`Q ^V393?30;3Hp_)YNJC%/~ &|(&&GC0&XX?pП%bIX.s.u2~f~O1*J0/QePXk._]n 3$1CsD(1a?ԌJڟb`ȠR9(N]Á gc8qç +2D\˪>9)Ҧ`g \E%4π%C=INkLBRgE?Cy*` |gvrc(p.x#014G=pyl8+ž4:j0@b0h431 j .21\< ?i%/`qgI Ro1{2s`r4;U @8Y} ,kF6~i0bb8qZAa&o< ?ffDD/``LKdV%76'3_:er p%Nmkd v=^UY tPkAI 3>AWvFsXؘ0f6`F=nci]F?WD" `fK[np!K(b oz79f/7?=9!WT{]_]>2`b> `Jʟ_a/ 3bLؗNL1 ơ .MIENDB`B48x48_FilePrint.png) PNG  IHDR00WtEXtSoftwareAdobe ImageReadyqe< IDATx՚o\}?gI Eq%*YLKTQ;4.K4A(6m}K@"}p AF E. jHu쪑Ťgr>YZwx9~緜=j"}/=M?2:{v,A ^S!OeyeLJ?կ*Px뭟|2}R gphdXJM>_^-_SLhxy4[{ΑCx9?Ϧlݰ1)|Ǐ;u4tB8pNZCӇx7Y.z )]07[g׸u/_beez7ߕRCF-cMNNto /,gvvaB2d =%ٳr5Y3B‰'֢C֭.^ٳP_Av.$0>5::7Ɵ1?,0#IZxA)ѰwwVH8sJ@7](Rx#Ԓū)%R-gz?qw(x,,~y]Òh%dCIvA?:OVj')gSk H) "P'###9#MvJ!z4:́q bgA1~hZ"RvJ\cуᇙ=pŧu?MNNC}p4 &X4_yޓZf<'YՋD$N||7՚yVssX\xsvaffBD$do-K5hun:"UMa5J 4)e;LDH%+P9Es(%Bω&4&S78,ѐ#$ ^es W&>)aKjqbW`(B0 αo|{0Β9 !! Mz=VkϏ$!BA*2$1fGIp<5dqcڪĶs!YJ1 Zn٘( \*LӊV-'RR (lHE:TwN>ڄ@!m\Oo%s.b7 p|an~d1ϓWzA@7pάt !UE7n|g) XkI{Ig*A&Mirh h"B*Ƙ.)'F)sƝR(`aa39]v =CC8gÑMMz~K@)QRJ X)EQZC!'~4Mg!Qq9~`BaDZ2RRQ;w yfӳw4Vnp)cwIt>\=>1{G8̣h  !ƈ6I$Z 4+.&ٳ_=֪? |t{uA6uΡfff3gD8q8N1ơuҕ+RS0)%JxB\:D^|eڇ֪}QH)BKyy0Zߝ+ɵ#tIbE!ZkƘI)]@g^aqqJF"I2׫ܺu#Gګucu|sisj} ePTܸq_.\ߢ(z?fz!7~7{;wZ(w q.,;vbd"YfN.pgߛM =z=f||'kGQl6okJR8zU؊Bi|[~zûWrЮNhhgzyjѣ[K.!Z%!D*"|ȷemTJA Si.8HIaIENDB`B48x48_FileQuickPrint.pngPNG  IHDR00WgAMA7tEXtSoftwareAdobe ImageReadyqe<yIDATxb?P@dd&IdzHPĥ _|"FFƽ\|:@c?TB(@FF1LPu/#H@,dh&9 or@zaas2PNY <dbAX@I@ES204?d/3J  L,d $#GT` E+(g1,.`Pc? k%xaµ 1a5Nׯ>cef`gg`ff{LPF fje`<t#?Pcdg{ ߹8ɂa., A/ϟ~ *C@L|S?=2+,hgd|`0rav b`ta,Oj. &A @211 X  @)o3B <<`BL@ Qȫ3T y[ rN`8}Ciu9íE $9}`AnCB >3@C89111~cI8i13G:/ÿk?ˠ``nw $ J?>N1@1%ûw?ؑBSg8~dPF+4 (ñ UؙX@bl(߿tx`=2o@OgZ9!{u ’@Coh0Ջ 03XezҜϟ@>p@Uop7;6,C Amg,ɇ} zO21;XABvH2;OW0 Қ <@r//2tA|@Vt{|w$Od8_ cZF`R,^@[ n?lUVV6y%0F u$U1(BHv3B ).`l lf`a`PbaRRW c`YYYNc$x͝a+**,-- ,,| R kl`PS}(f"0H1'1@Af60 @޻w!11^ӧ2޽exݻw^zǏoǁ1}Ăl.KK.MMYnn66H n+##` ßd\UɇZ|Bz`aetPZFj+Ng`p+cT',=\k!'N yA?Ph+IŠoJ^^1:4 6?`t2|W`;#fwo3{e`1 .z b^Ȱ{7͉ ço$@&xAYYASS֞ѣGW:d@cXa97xW!0 ?eU`cgf̰kJ"  < "vBZ'G/Naa7ß_ ª ?0zAT3/_%`X?Ͱp2@%@@;'BNNpʃ}#4?aofGx"ƿ ?c0R "gx1e)%%L?qɁ#`t4,ã$v-#sC4}{ 6U 7}>h20s< Ye{JA< 0p0Z .\r@288ZkL?`t?bh0~ sleĀ7И2wf&&C^;0i3MXϿ 8b`:?P( σ:_ prr(@=`Ka5,o` qexoV`<G2d?Π2 ؘ 2]X /}c8#p=0Tـ9T/S@ \ B*K`h.aa!P`@,*" yAZky 4SMep-AaHE;'EPb v];͇ *⬠d t??(A^&!&+!66`fo?hL>~) %{ ?$K垗 _>b/Pcܬ ?Wg9_ԿG˯ ᄒ 1:/_ L ߾H2HH00"VV&zCE+01<;&,CģU *d=l0p:Li`X CC`b٠JҠT r_^o &Fb7o>s<; /' lpK'6` 01|pPT' Ϛ2pJ0dO- 72tugft<3 fx]،Lb+0~` EU?Aibb%'Pӷg9Dd~X? `4aW,F& ~e%E3K2gfH.` A8ío^߀/+uy[{`ccw&ŗ/?gzƁ90,zL&vN72k4rڗaaq%é J= %xXy `,y>p_h['Q31A  5 Av`FEBl%0-~ws铉Xnt0H6~ǟ 7O33b74d` o+2^6hb{@! n6#0VΜ9pi<69OBx?37fXq _& 9h#'' C*+]OX@Q Tu?{n``(lR^ua; o_ex)'-O;rLRׯ@| b~9%a> _QQ1p2ؚ!촨Z h )}_~pnga z_'dݻw?~ T20ֹ*5FpG bǰ> -B5@Qnii?A-ׯ&  oUc^ n˹sV^NBh(.'(oV >xa} )) K}}p2u1u!w L<,å |z#,)i &Jl'^Z޽讀息;wt0 !!'ޖ%< @ -X!t ?Med`hc/Ax qPڗ{p:Sɱc޽@=za &πe O.dʕ JJ`1H(Lbϵ |b g5:÷|k+6FȬ 9|fp3tc`Hy;@ys[NĄ(.No3',5yye8%cVXSpqT7BV "U 9=K6JAeCLaÆ?&_|~ ,d|0+ĂVeee[,aֿ|Ogc?Dt_\;PLLHاv<Es

%yAR\_GyfCu0##,V` Ԃ? /\dV +?_F)",wg&+uUIN?jvv!!r@abFF.Th0 NJCᾐt@=? ?cCRb P !403 :ߏ lʄ# 1g Q !? u ̈́OA= >#81BdW&^?̿A2.* e$ p(13c$('1? oT4!#\+ \8Jit`eDIP&pXbA8 Hlcz Q`; $ 1Cc?4ȁhfhMB  Fx O>L@A.1Ą3` v#`XZabg"'#ʂ' P8##R' PRHQψ(p@DfDx#$ (FF؇&Q\ pzryPLy?#f@DF9hx"D{5R T e2;<ŗ"{aH$QOĂ E̐Yf$ G'!yAX m&F9F< p'!<E1(/#"X# ˆ@!P̌'oCC5ТggoMdd(&F N8?HU2$ @x?x 0kDFCP,JV mÊL=THR X$"c~@;Ab`CDL-LL&,1+ x pBham>DTGI  8XSQt_Lf9b 7?^}cx,/Ǒ3?,l^/4y%& IԔeQP5l, ?#R?jŗgbֆ0J}1G6Jd#l#AXA@oٰf>(j]#Ci#?%0CǏ 90 #bj/& =2V:y~cw?Q^eϟ3gadjRRYKi7P7TF*XC/ 3A'~ .Nz231/ o$+@C[6,<п_, ?R9߿2=tQ XRBkc"X' 1{b/ßx_` Bz’L @x{drȰ.:?'@qb<? , }P,|c$X/R=DCi 90 cDa >(d pZV ȣdѡ d@AH6r F@Բ'099 ?>RED ^4%@yHhTX*1QI!1\ 1 QX&&I G/ 㗿~̟ '(@t J2` p@R逸?"Ăo.^ G@?FH~ZZrv2y} A%#ߨ= @,E*$D|ȠH7b q '0sK2oX/<4 z_^{%ë 4tIIAFpC^[7 ,  ÷_N}fe`lj0c`B|L?N٧E <| dU#?_WMdb N,L\|ͳe:/$Ӭ4=@C4=@C4=`KU8IENDB`B48x48_FileSaveAs.pngPNG  IHDR00WgAMA7tEXtSoftwareAdobe ImageReadyqe<IDATxb?PĈ}Ve; Jgd)_LYXGV=0 @,',1|3_]UT.s|!s|Op`d` XSr;E9%9t~`3vpVlB 8e pϒĬj -`YY'3@c pyTFqd)Qf L/  . Md*A6삗 2Fpf`:%ק!ý\1W@8<;MY5٭2A[? /x@213̿A@D Bp@偘㻯 f/gu gj 0=@_```fc(b-M?eo l젌v?@F`1K`!hFÙ F`> #? j*"7220p&- L n` #&y0@="&,0.~iFA;PǣxFVPaiK'b0}C〾: @3nl^Ý% +<2B#jyn ;1ZQĐXW)(a4-ttb`ϰ{_.}Č o;401x=#3< >d=%!.n8PhÏ@)q؀ co$ 3r&FIb  ˨ynOu'3(*fpIlYゴ,?n6B 90L`N1K߂@Gg730h'`VW`0cw0eJNT@j0c)* ;o`p!T (QきWk/1Z$͠`l'H1 jB=@( <KB0C,bǷ@Wp?g6=3;%'c!LX?)`([/-˷g1maê B B ʆ On^   `) =@İɏ 'Z7@Ll=fxm&Cj670 /'8zUrcd0in]? U@ʔx'Vpz跽'bM?fW`G)y Z?v`XI.Ík03X8 Z0 K!@e/fI<3 πmА* c8pa"n% D?n& C2<@xcfSXz: #B&622fdc`~ p uõ[ .G0\R``=Vfg9PbPE@+2}6_3(3Xc R"@6'0`-d*`/n6)/CJ^F3LbxXEK2zj,JB"C` ѿ J< 3@ g>2y2w z% \" w2\>aC.%uyp /Q o03pԋ#T%@O`z?ß K=ypC6Pÿ_w@pz"=CxK ÷EO'V$P F:>`?FVG0G c  fz3,uT.;';0} `ccaxUC3# Qd<Tex É80?v r\ Br y *Fdb÷//0cb(eV0p IFFP򒁓"YTt5>t4='[ K!"Xh /`1؃ ' 3&{ 5-*EWPh7RcV$Wh?(z #1@=?LSJa|>>c[H2 [&Mgoߎ"@,^~PY^^lXJcϟ? 0Y`߿"dػwP @ OA lb}}iiftF JAJJ>q3×a>e PP$]G)LG3-yIIIi XDoP=?1<~󓁙 b8!A,b cb`_?'zٜ2$= Gb!;+#'G@,̌IĄ.& h K@Lb`pQ t@,b0b__Я?/[ RB4?̣ pOmВ#4J, ˊ7A}c' DdqP@!W @HHIaM 4<+ @ i!k>\ThfK3›Hϟ /_fx>_899de~ArD  .]bغu+DD=C7@Hgg'33sPk%m Ă?x]v2޽ԒASSl ϟ}.Ǐ01 D(rC;`` F`H0 )00ܸqaMF#Ub (V?~̰cn`pcbbggx 033Jղ 'ٳ.\8O'p <@pPIs`BHf!!13?~۷pp(rsa022&= **@=,xc` -@?yρC޵kofPUUb gte~<Ú5EBNNlg`x"@Ub3d+Wbaa|p~777GGGpafffg:u*0\bVax!"266!Hb"'/Ĥ8͠#𗉕?&aqIgKATR ``.#3Ó[>=q 0\-~e%E{_xT;l3\X|c ; 6~gU7d0pzoъ9+YB֮ 0ȨK1CH?H;6 -ß'`c(H)L 6l#'Щ\ f2, bxvp1Çg BhhF712HZ9'*@ !lf`bqa-v2H3qD@uC):YXn:/P+BiÙ₦@ o^e`SZfvb H,`@ PC'8&~qY1ꍣ *J .. _cshVz/HĂ+`/B-vB#<Î7np5 f8(cEp<6Lc#P'X&T̄lAj?x3("!5b *FQhFh <,R<9, [`@_.c /?@1k (@ŰX^ _E<o20|<-~`J"[0@,X  3f#ˏ< l, o>ex#0/0bq3_JM ˨>Fhπ. >s +Ù$l.p;쨘\F35>` `O_^?c!P;+Po`[+ ̨*2`,%1`=-4- ? [ &OY5.0M1` =🉉z 2F%@1+$by' c> X!%ڼ1E($3 9@ԴaG0A"-Q P Gf=@avf@ߔ{?%+ 3p]-̻)veefxq!/fep` 601AKtpb+o\sx2IQn`=G_`߿|A?8,3He89#2BIR1A ޽c֘( y/{{/^[O I~?1k׮ e 0@LRRNIIk,= ;w <@5@P0S4WmP жIENDB`B48x48_Folder.pngPNG  IHDR00WgAMA7tEXtSoftwareAdobe ImageReadyqe<GIDATxb?P8=@,`_02R@___!^^~UUO]|o߾g={5=@,VV̜8K?Z]|…]vӧ>͛7g^/8 Q+50A˗ |ݻ}P\HJJ>c#((@1|1ܿի^?xp§Ov<{l'A yXȻ{\VW3ܹso~Kd+>r@z 00hZߺu _j֊ՊQ~~~`O@8XACCA_߀ի@SDKT__T\\./++ h2*1fihh$ ba& RoJLL /^d}GDqG3akxxxTTTwbM& &Ǐ ex0;;_֭zKP> TDcWYrFE_?4T?2xΚð=m)PgX#+++$$t`:H01] ,1;~7÷?0~_dKA0`033߀?O</Ì ~5sqJ p1CAMAAAZ֫? +D&o`8X 䉿h)rr3|Ё OϾ3\ǿ /2p2s@0;$>'Ñ_AS] o߾cpܻׯ_=@$+'V=!AAEc ?,Ul?R dP>ʠsÄ˕m7κ?1->.V. A.]ev)Av A.Ymv|VO߀477'ûo? 'lbx)N輧 , EZ2H0Jkw@~ (3f p 1~ebbTcP`eaz 2~{B Y7 0_~ Lv?y F0䉏_w?]g``pـ KQnYFl]&)>fnQ>6_ ?~ba`:_@Ǿ Вd_({89^/L0+A-دf$ˠ# =pqA0`z4$߽hPGArh2zU3@b h;'ë -@|z@|~7z$4a!aW`Z. 66\@ n.pIO'@j? ,o= z?@A<נ ̬Oן! #,!Ȍ`3?hCX:/D'4@$.*_~0&*`޽{wT3} rC@Z oɉX#;AXr#a Md bشbfan߼ׯπZ@i Ç?t<,!R;+;4% #~eo+waW?2b:ԨB9,Jk$)AJ><Z*>PI ŋG 732ȩebWW@1@,Ϗ;w_~Àj8i]XCԁg^A?d 3"%WX, ` `/n`2|{㣯~}+} Dkϧ^g va(%?~ %&pVC C4{NP0ëG, _|a`X7 ]y mJ E黷+-py ;GTXi6v@nR#h|Pbxw k|6`wǫu'\VI 0KG޼*BqZZhu&Ʉd>l+jg3^&1 AB{~], o?Ҙk4xO 娍/0z쮱5#ЧBx}v.^Àj?PKA? 0Hpgaddfـ@r$#4F`2H@!57Г4?r1z|N`2므A<@|.$/p[1#+/7+/' |'; YE2#4Gx?R>a&.yG ;ϗ}Σw51) z޳ᆱ)4 M1 9uH9Լ?G`cO`ă[v=c e_5 kSomHH:7{/.IP eU! 4  __X}b`؀59;0vX!=7>zC á/cc`c~s9#  TuۯPa2O\?N`wKlh|zp.i0g ػ غdLi壗 o~dШ˰C@O=/_]y 0'|h D `GbdĠ}P0" P@ `-00.{Мjpl ge9s 1cd|sˋ_?0ߞ}7_ go?6401B?R?倱FQ ov0 .^d#Ϡ0 S#/ *xŹg @zw^W'&`?;$GH;`-#3*@DŽc`8L.xq!,+CÚ \ <].p흛Z|B Tܙ l?0ÏMfH #BtP&)"B: IFzs_֮Oڋ.e`x?,_O6ʳ71W ߞߐ @c~~rQ&sFFAo.@ v`PXIkh6P+\0B/`C0~c Ŀ;/}w/~2L>}e3oO~{??C|Nu}@q.>9W9-F  L ,@w~xO#MEԨ̙o'þAW$ ol!k5G $;SƓGX?<0~/˿>3| C{_\ uQ G Fĸ \ 3HEH84 o,_'HT|pߡ5~r !@f)AҘA hQ -T9)q$>@Y xC4S62Z|IENDB`B48x48_Folder_Blue_Open.pngPNG  IHDR00WgAMA7tEXtSoftwareAdobe ImageReadyqe<pIDATxb?P8=@C4=@C4=@C4=@,`_02BxqG~fG_9e ,* gd#@o@l[c0&?䁢2 *l:L,nKc8(q2@Y{`a`gefgbx7cbZLxs"ف "̮ M6^yvN~nvVQ>v v9a Q>%3\+ h{ ?qy /(:T^?@07?WOSN1t!W_Sg[EI)V ^>QQA.a~nVIAeQ6Ev!6aVV&f_?=>b`a1c>3 xa`+Р!SPVmO+7vv&AQ1A>N.)A6&iAvq6I~6P 2q03r00m4С_oo= !age@̎/5,LJl\  .4ԁ ALZj  JzrҟRd&(|Q:]`1??|qq1#542 ȡh䂒ct%ٿ8 ,1yby9AIM_Ki ~OcZ0H3"BK, ŠPh B+x$yBNfbcfcbbb`&w?gvg{>3ymN $] ="A3R 'A4' 74;7+#+P X_}3:@__o=~ىIh((QZRBN + E1qa',,,#? L< L, ?bGPv DcO^q?e8P߀H37R-!:HR2gj$ *Jگ_ :?30d_WMz @d߿F5)@~l˼6=>+/ p)S@'QfFDt4ƀD ?:"+ϯ@7>8ۣ@#^~=럯,e,D (~ ^g!Z'fg5@ }F40Ty iwP!ç<(/__|_Yi+Q?g{@sBm u4, ǁB?fG k(#K_7 ?OGBxǛW??y/e 1.`47A+cw3EJiNdf&h(3B0!, 9X,"_gxp>0z02Ʌ n%2b{o ?y;8ta֝`|`_D +>Ml0D7R k'2|i??=,X1~~P_*qbb@W߾;8A5$#0=za͉n2$Z_8uR~#xXg^2{3L ;C XP<+з;Of,8@(CZC E`avɂ|@J-,RB l:yar '`ŵÝ~*}BU 8$A}S0{XG ]PLA<t'XL Vcʑ  ߮  ?>+0oOw(鼆N>zßX@Iĵ)TA<C`O8<ghfbfUbX r҂׳lX bۣ/OL c`ub@BK&x: 0X#- !xgo&1{ Pd`q&k??~? Tקo^+w` G:^fJCG&H229dЌZT`KB #23da8}ANAAKE >gXf@1xsW_?^@2\@_PQ bAO$6@ 2 V:R fb I/ |d'׋O[5bH_( `c{a%0.@\ %PL 6+ $3f`y۳' O9d 3|+2|ٮ@m <ˈbb *T5 0/ndJ1K,6&VVfbP_߁u/~?y >]X 񯷟~y'?]vc LBf&Lt\dĕ\ X5VNfv``6tXXC _`~e÷}~BG_} 0xl}tGh@iP}~!; y$=gZ J)3| о_?0(4 닯v@!0}G_o> _P$T"_А -2P.\ŝE}?|Q ?1: @MߠQ? '@2Z@lP˾EW$ߡDAH+gS`1'4 Ɂ4s$>@C~ h{ h{  / }kIENDB`B48x48_Folder_Home.pngPNG  IHDR00WgAMA7tEXtSoftwareAdobe ImageReadyqe<IDATxb?P0@ yА@ yА@1( FF'`Q~߀_@=-a35}b`aP+%6=P %X8 ;O8+;CƒJJXdy`}ڶK|C}EAVf6Bh:w&|ۓy !Ͳ݄:7)F@Lq\N:M D`jNP˷{ֿfm/RZɫ&Rz;*h]7xnҩr"<(!3R4#0Qȑq5v)* ' 0iq(LP/OW'A 7;mn@ IXi9,cR9E MX΍$wXBm;hSuGԏ'&e)6F/,ABNYecMrS}_z F>0{ك /_`'s$tݿ6ɥ : c`bbbxz8ã[׀A)a)9gX?bpUaedg`ŏ@G CAtObX ^x k؃gYDfM0*k{:K%v圪 -֛h5A){xw,.K50nB&dHAKv#Y0ޟQ ;._wH=R =X/>M(@}`B>F%9Il< -,"D j= YJ]+0_fhFtoJ<+Pl SH`mo0"XM,1 NDw I;ˉn1iRWRN[!*U}s[Ma-<| u0T4H[H`݆u67N"ڪRωIb<޼yCl{u..d֧1OZ&.iċ#eY :l9.eeK=ۣhHC"t_%mOEYJxiq ,q݉ń۽Q2/*{(? M'b,bL0uӽ73gl%1MQq:6M;l.bGgk6Nuoh>|S]dj>. N@E^`.- F^^ uY#֢자;,L@p$10Hb?~0H 3kʖSMՁk r* L \k bR ^a&` L_^>`zTPBX0|{ G_LJW ̌@yy/>2%G[ G8?:Xg2WVFԟ/_Yt! xV`da adW|Y /K ooX='/ 8çWFsX=%_Ϗ.2K=a#+`!$cPt,@c@wŋ͛ A.(`#5&fpǠg`t\  9`e:Xaq 2H3|:T/{WLX=-NA O2GwT5>*TV K>~%%v`y,X{2&hg>:#xW? dP 62 02̴ r#+?q &o* `(X ʨ330PX? ,޽tW-`/ { LJ܂@k`7O2p 1~r/ûO+KU5 `ǻwj7 e0 wb ( )|{FsJ 9ovFL5֖k zvx_JN/fpwJ򇒊(ApJ)3OLOu}Ps8WMe!08Vm$BKz3Ϡ~ b A"tu>KXb;d侜?}̪mP;YnYOL=#&sy|>+Y(<LSZ>VE}rD)g*;S9 hp@, FĽR\=p$1&`'ep>.`/lm l 1_ l2@'1R0'pC@+e@  j`T ;1ƅAU/ l:`bþ~T l ao2| $~aFS`Ty]f4)>C_ĂĈ( a?32B;Pؠ"CMʐi6`#X0{/ȗP57?`oٶ 7~1ae<]_~{) y Ă r ̨>>ax=(6.ly2pde4SnŰel׹qJ$c 160v0v'`gx^FS`2꘠AO@,xPO/1<_9?0I3؉L>88Yb HprLT9@8Yc!,LD9$ٌ;_=gf8 þ\ UUƠm ;?m`,~9J!ITپS)U X,#~@8=&@BL^ <f#q Mz$ lgSfd8 v@ `)4/`F,M P&{@ \ YW Xy3.ETs )baX-H8C3AYd .0V! L .2×,`o`( &IZjP@ ch^$* c@A%`נPAO0dzCW?<~>ïF@NBL YzX9Tifv&$ :#0yoAP?v>y lJqepc t< Тx33@/X  ?z<{o3|=P ̣1MN lL>?}pM`,8#` ? (s?>OhN@8!q ?@KU>` Z_-gb`OYU%lsā-q`MAU``M, M3` 4gEt0?vj3( i"+iFD%ŷC'bP/Z2@2(SB ӗ ? \]oex/&`2bί<H h +R 031VV!b0yh@b%û{/ aU% #ez+o:+3fbep^?W`02CFUu#C>3|{ wgxx"ë; 2A1P pPι T s럳-K͵ ,N 00ss2C(@ 3p#~{Q2<3?y#`yX X<:%:} `ADXNPрCYD!2AX42J 憖_>OawÃy0?g@89l}~CD (RpUa`pd`RaPqc5d1fxw<Ãcǀ,y30Y2ЕOC/Q-("zؠ"`g UcaД`x' L π!ıP~u;O"$@x=VU*0(V#fR4ȷ~ ] -M`t@z[@'CF8{А! D=+IENDB`B48x48_Folder_Locked.pngPNG  IHDR00WgAMA7tEXtSoftwareAdobe ImageReadyqe<]IDATxb?P0@FFF'ӭٳk>ף7o<ۯ@%bzdee[ZZ1|6/{ϟ?}8sҥw@( AyZ1Ϩq͔5u~Ç 7nЫ۷ozf/^p 3$gH<==UCBB/%%%rSO1ܾ}…oo߾y 3^p@% @Q5 jhhrRΠ nnϟp[n_~/_y͉SNMjDHHH8k/,,D߿1}3w_OիAn ~~:-YAW b PuO5b83HYeOz1mkyn3<} " 'h +\Fp h t;W%>3 c/n`dx UjL(QCJP)=ȥ!6b!]qI1L?RKñ0?Z%4x}s}]iYTlFрam r6=n@FxˠxGnh]A#h@0ư* ߐr83?0&"yeE8x30̠*/t/8 _WA/c 7_?1\00kW`14 @eBGQF+7]ߤe aH6O#i 9Di D= ɤ 걗mVAlt%)|&?a?Bj@@x;-8nZ+gƵ ~ C(gc>ȡ(~ P1ر99cAx/ģ qP̱= ן~AcϞ=yd=Hxo>gg!!\`&Ё5}r6vv"9?PG g< $1a/3|A1:~]P#>@Ŀ_O>| OL@ؘ@? Ae0bX++P#m#wáza@iXpK 28#7_|ׯg@gw?߁ @3A9%Fϟ `0!; <Jlex`@cOH/&~C'0֘^>p'V?>oFEXzeU2X1q %tOE`PZ9N$ hÇ?*ʠd=!N;]@<†O^|ɯ/pwm\Y?0&?GHቮ>WP@_pP!|l2ppp1'0g+#yҫkuK3xݺu`mӻXmeABEAP_|>=}dj;k27cI*`u?QohLB"Ƀh``#vzƻ * <‚ _?b7!@,2;w_'+62xжkbAyiO701[ۂ=:K/3vv ) 6/b8, l 104GMDDl@0>~|pl@}_B= ~slXUA5à `I0jk3<:ፅ;?H ƈπZw?Dό b -O.|bxPs@=qy"8-!VII>>&66H6mz _f7`EtOZ3;8Eh,`` |1|l2^{ ꍽ5@03%HH2~;sXC`܁, #00X:f4WzT5g|ӝ F(f?P0K{_3<{֏ %8X~ 춝@?@=,0E?6@mCDRXg\`Op"g30p2║a5bX2~ak )?÷'p-{*+ o0.A¿u,B@7Hs2= Q!O.3|~8qvpӘ1/FAXvLW \ac(|M?@`i'uPL,@O2&Y PK6 jĀl '0݂(f0?'#_ÏX>~b`yx&```ִ l >tt SG21EK2dO B {h:ʨoq r`ܐ<$: JJEO._@ ?10~~LR ?pSyU ǀͶ_? ,r _߽eHKWP2`b`~%c O1 }09P 0?l@s7#+362lZߟ@wo^3:!O3+ `A),:oseͿ/O@w`·Oji1J`Q\A:2.!Č@ L/f ` W?2|T`gX̲ 2>wJMNaaPVy}qXG5@```&WWu.))]o/r)ĈfA|`>bd`cw8' `U# ^30}ɐkȰ6P)n< dxw޿?o<>CHc7oTtt>^O#(HH0v.ric'vE Gϯ?^^Po𕝉.K+GYU23?|l$N.00,޻7G:)I_ T`6p͢w~ " *qX K 2| ,W~4 -eB3(3$0JS)6IT=؜7B#SXd~fؽiw ;7_~:ߟPG|:RM"ئ^$fwb`HdcK1vZdU :/0i=Nd8q?^?v߿@,uoC!9/9k ac`[2LPJHHLJJxW&-`BR W0ԑ@fAfPy@hЄ T4~6oAC~ozV0t)IENDB`B48x48_Folder_Txt.pngPNG  IHDR00WgAMA7tEXtSoftwareAdobe ImageReadyqe<)IDATxb?P0@FFF'ӭٳk>ף7o<ۯ@%bzdee[ZZ1|6/{ϟ?}8sҥw@( AyZ1Ϩq͔5u~Ç 7nЫ۷ozf/^p 3$gH<==UCBB/%%%rSO1ܾ}…oo߾y 3^p@% @Q5 jhhrRΠ nnϟp[n_~_y͉SNMjDHHH ,,D߿1}3w]޽;O?~珻߿cρ"@Q>7 gx0m jvUUUMm ,yX[[AOOW6_ :bt}yy1 djUb߿&&&L#5#@Y?6c@Ҡ;wn~ qU<娬 ߿ P1?R'0p0ա74!уW P=w7ՀA4AYE ,bؑ+8c` `P?G0Y`0@Go מ~gxO^|/8{QZ_)@O{3خbw?`*^{~)aSbdPgcfc7Ü.,+wiy:jj/7_0x ^bx? 12p0q1H r2(3Kp0\aS ~ XXdzG`Q}@\Tl(,؀ 8gmyqAI>ѷ~+177_2`~'3? ' ;?;/+70@퟿!Q[#<} *"/  $S`{S`{ DxCv<> O V?T/ `,7+WQ?%XQ/-`à* ) L;М~ $YX8^}/A Aۓ'?n  $88\|ZT@ hχ C]5X4եy|dPc: d8~!?<_PtB=?Qw`;@%cО?|woq-'>@P~~ 4 ( ,v`L/` L:l 5'Z5çS_x 1޻?_=l)@c؀2+7é9 e1yӛ/v`6 `Ԅlfax.͠,ʘ>P ,''+`4Xrd=T}0U]. @\ [^sǃq/WWbgr4P3!t<mp],nh,0/1"b?*7v..zõD ,DTe|ݠ@~}wpr9O@o`$b!qcP owbX88bP_Hi O0<yfd,.< /U؎N5Ɂi P~Hh ŝ6wf+dA_A߰8P="$,#7`iwkOaeee-7a%kBw_>pal(Sc/3ĕ00 eKa+]la3{>&~1]eW.,̇ `=)...~+4&Ocxќ۷|jǃCZ2{(d&lv@k;&91atUv A9i`m mGt`.BJz`;`ч V>޽+@!bׇo^4 ܹJoex!: V2vs@E %?p_/ sg3|aQWc I_e5l x' hЌ1.@积o} l1 t_,c< at!Wg?ԇ߾3xaf/?" sK`QM:!r1 j0y˟ 01?|vN>GP_ׯ5+6`ͅ 7t1{dPql" lmj`O`ɞKQճg~忐o@0>wml>gFf>/|@!ܞ=@thn,`\ Mn@U@?-`XTh ggx  8X9:/8PLs1;/1Sû3xtϡ}P1@??_V˝ml0 X{l"?t<#hT 30e*w0n` 10fal3 _3}z ,C`R`a`=,zXϮ1`{M.fN^`؏~}%rSdBwpeV .a@1`'z *2C 3M`xc>A~I̠P'#?A|g`{`,=l<, L X=x>ސ=А,.c?o/>&|9 P=ڃC};1XpFϷA{72Å3 -gX0pqS?hRc3gt1#,~}f`L=p+-i5U^XaN[c~ % T|wM< |0ma`x,.4`dx|t52N`/ 9ԌfS 8y <݁]vVA` , /]c*WfX{"e`fzLعga3` ꁟ0s_w!nl;>ij`,|8Oz2Po`72FQPN>X`bD"\ žOnegp=0#]Iѳ_h؞ۛ 1s3l{6^}Б߁ʚaD520%{t̸ GbF`Jcy ҋcbFȨ!Dѹ )ު rJ\ 6y9x8>/n p k3/OR`` H;l៨ αI&H=q#ïtO~}W_}k b~ t tpWh?A_H;T c I(Ą?e'{߻4L% ,ξ1@G?_^~g`~d3` đ?ZoPGDs(yb|;~ #6zn3<ïW L ? G1>@ q_+C#?8 X&BXZ݇/@, oH!zh80lX:*JIENDB`B48x48_Folder_Yellow_Open.pngoPNG  IHDR00WgAMA7tEXtSoftwareAdobe ImageReadyqe<IDATxb?P0@ yА@ yА@ yА@FFF02_ 2H A(,ɠ۟6ofɵh_ 1HA2 *\ : Xf]aH;p H .KQQAPAPARK~a P+ Ձ a/43+OM.>892e`ڧ ßzM hpvE R , L~:ٳ ) d8? 1àĠ @Jp 22Ipp0Jq2(  B@{+oh@G `)P| XX2B ď ? h-. ~0p0 r1J11-Aq~`10pj/ 9@+$2! t 2 "@APLKIB J π7+$a:85(YA< @w300@1} ߇fPAŠj1=F"<<@`=9k0YQjfa 4 \@h_ tGP&&8/Hh3"AhFoh?= +OAw| ~bRۆA7@3CJ@ tHLȎ盿G1B y s?C+ 3`SazZ{O{ ,~_Pt3Bb uRH"iR4@~!w` N5l?C+ @`̵@zAY'u9OH 3<+8Ə/fZv`I\ pMÓoc{?+ -HBbhy/_"+@YXX@c/^3ds XH*F )d1b JJd7нXA_A)Z#4#,WYv{w3XB2,C[L<8"'?д߀oFH &@`^fbp'Fa2,0 db^`?˰ 98Χ~C,#244Z@ _ K@'a`G0?f_?`f@.30 X?jOw w% 3KHZ'#eHi4 A4lhbrP=&ga6R" 0~lK#S7 o!m2k`R;`;aIyH c06w@*07n2|(y&)p_3 N6L #"3Aիd` *f@K>12aZ|EP A7_-]gP!b6+# `GrhSdYA͌,پBćE&#h:(7ßbݿ?32<X+O F##"q*s0V`ؤX`t`1 Xs@wdAGo8z7_O{`[5ß7g~z/>cd/`iOπ׿X0c 0<j#D 1)0ga0:p'0z e&|c r 3a~?Þ2}@~g÷?>\2|?B74J +_Ȏ lj "IB B Zڟ~L{e#{>d ½_ >e1_Z~2 k5B @<+eϖdha}'0$O0|yt؃_ bxNA ?rF: \y4.@, ZtEaCXz u$>@<h\F:/,hH| L=@ 92!!.Ҏu+IENDB`B48x48_FTP.pngCPNG  IHDR00WgAMA7tEXtSoftwareAdobe ImageReadyqe<IDATxb?P8=@,p02o+: 3OQ@1Ͽ{@M 9p[ % x {%U_cyE5%X%e%88ـng`7^~O{omfo-G: 󀍊0K9Y\e44 ؕDX8Q ~0|dxp-k_3<|uG = bc@Xi`g񻒕:@CDފՎA.&1f/+ JB@o@ O O2s 7?`8w?cx @ " v:812gPfaab ж :;;0[e`zo@?٘aʟ 2y{ Gv~ P <`Ŵ+MF_A=9030g??0Kb`w/;@Wm618[Kw|ʞo\N 0raZRȩd#щ_Af '031303S?3 ×_ VKB @ # P O[NmgaS O[poP\ 0a^ҫ,`Տǐ7T(óW1_ T'8G+ QɠƉK\B>feaef; ;8~;{ ɰ klԕM;i w=E ? )W2pCf _`ppp0p;?'?rpR`$!6û/1 v lR&,Ü=~Up:ȥ@a7*}Q3yO62J77;;.`o8ǯ_ XB߁QĀjΐhpwGLt]\N Ls$0w՛C0s q1J 0psO_ Z:D;{2|/Z7 AҊ7!E/a۲ J& &" @ 7?W;DJrp}sᅢKq3򱀓1,a˧ >eePSVb&%fpav(/}x? ?~_@>(O73x30. XC@z@G[˛g s`8(fH%I_  w?dx%>~pedo?޾ q?v2L^7_2*3( 20x]*bA ?A1\/bxu*޿x`/` *,+&Pf6 3/y{xGx~e\{ 9Tw03<{a]  2;o vNZ eʰZ~ ؙ'h:0򈁋AU`p9?2p01>Peó_~/&f&͘papRbV`J}ϰIW/0|lAComy+ʮM@jj qipoo1{I&`~f |b8w9T8UإX1<ӟ70VѠaҿ1O{O3\yz֋ oC$&!ג^\&߬ B7Ş=( HZ#- ?vaKy߃=s6afQkׁ ¼Zy#z;` $'O@;aĠ*?0} 7yeŀ _GHd }+NQ`# }X /bxW㳞3ZPd&pAu€Tq8023 0!SWR@!`Kyc>AB@@01 ˰1õ ?^Mق 1e)&)] ' `8=O`n3A<*7XY+?6``T ?'3Jg Lg s1ǻ lL`} oO=A"I l <l&+#ó߁3kӁz{ҬvOr|| h"7P5+@!< JL G0 W3=UfHJL |`L z?pi+u6>FK_% ./eIA s@-6P5@,HdE3 S0-`ڿ 18ҿ!TP^ j /Nj&6+ߪơ40Ocexq;׻ gPPgPg`V<@py@2y3|A>P_Af/6A(_)/24[?&0hu'~2<_AUKA\H?Pr^?#0AC?P `ǣ%tPӀEȠM?+LVI]n@0<9Cwfn>i1Q>Vǟ07t?@!Ud|ۑ_ Ϭ[e l123H8=,bXc(;[#ᠼX6`alr1 121/^a<nyA[K,XPJ e 1i+*`MhQX" a&xgU`R`Vg`>'+' ߀g\xX32pK4*Š,¯WjS?'~c\BSP6N&!Qcx`;X}aXzd;>a8й9̋2B @XCy*2mI V ߁BC+VjAHo @ B31e`P[[ N`虽偏O 44A3?@6O(2(JLaV8w_?[~rO7zokv7\?d? ̠fqD+89z0pkh1Y3fAA^N. ~aȗO_>߾zb-3JAu@@GgC,C_AIAW_AQA4!/@OO_>~GWn3gr ï8Xc dEX~=+(X>|p!g`E6!pC~ S\T I.0ǃ0pc+IJ  LLyO6x3+?/'d/~1 3e`'=;Xy:NfɉNep3I>~g(CC~+3{| ;pDx pXebl$xPil"DJbX@?dX63iCj&  ocd&(_0A֑]_ `R 0jW~#m&_gUpI)Aۯx03 2111p5'2Ͼ]r@X:H1)2rpP> _=񋁕_A q`H pu$ 71$R<0A` ֺ 0)Nav@___倅 ,((2@q3@a6~P6$x>}&,;VZ@cBTAVN!C4Xga35#ANcTy,yaŸ/#?>Y/5j̹ĂVH Pʹ48/4t | &mi\ +7!$T_xS/0i@ JF! n>Ȯo8%$XxY|jbA˼z̜Ҋr2 _1180|(_`&agDP RbT6-4@E-#X#<({ !'}d'j_o>aXs;էFay?ro4A!_a8v!01pՃc _~BjkXނ%O~wz] @w5Sv /`_29!ɖX11E?h$ ?}XCyׯ yR JZ̠=cxH@vl[q,Amid'Z'.bffЕbдfp2T6yRppr0=o R") 6P eсfN`:dbFv2@gbnP>( '}˰oW-6mIQJ$"+ΰN:_|< >a(y ,@t<(0 Pvd'Z&773a/Ƴ_nH0X(2q1mfp;v%66vϾ3N- 8o߁+ `vC+C*Pr5*C33L'?#ʠ$ 0,l < _5?>~\c: - YE?97ʰ * &)P?{Ň3{]@9NVF_Aaw |aX{ yx83<} |b&#"vA7n$c @`dg`8pk_`106A1J:_ L@}&:\/z?0?pO 04;YX16O @Lhg`gHT"''xZ(Y ( ;0ɀq%N ~f H=d'Zkҟ|Xo039-B ҵ[LF,L @K~ D:G* +d %dz>032p3Ar.O`ןp_O~G)PCWrXrB >5"; `013/{׏_80s>x Y01 8C >0\fl؄,~ Hy`lf`g?=U*ǀd'ZT1˫ ҂@= xg'_kMZ WWk23#RnGqpX3yTd'ڰ!ȀzXuʋr@/j3hHaE24QaK:3ɡ$C$Ok^Vv.v@̼+2Œp8۫/r"+ @J 3l$/7_ mBlĀBKd (CPT $ޣWkT5W302I1ps@od93#4E#+7vhVC)mЋP1OQ`]p f0l}4÷O_88X4d!Cȡ?~3bT|6@ge8zT~Qy'%i]ݛO}L3$v,_^>mAcA]N "{foyл#?6.O a{ X00Q Fn`ȳs 1 ?nf}cj~K`%6Pc;ЧK~MpnD Jx!]"A ?.&9?O_K\k@S HD{ (R_ mN^YHs@A#]i)Ж{@@| hYP7h=@C~@ yА@T΁IENDB`B48x48_History.pngPNG  IHDR00WgAMA7tEXtSoftwareAdobe ImageReadyqe<>IDATxl 0:6`kCԈ*q "|qӌSQD'A@wW,Z lSծ@U7p dOJ+SI}y Jce ٺ,\| B |, l ? /dx'Ï~=xic;J1@A2 F2b NZ$,f`&`.Ƞ TR!S71ݏ ^}J;4ҭNJ  {hPEꂌ &B | DhF  1 pfol#C^{h& { (,~-SRMRa2:;_@|xÛ nfxv-0b`cd_p23ȩ1H11=4K70Xsܥ7/@G'"2@3X٘c|<y>2}wn? " "B bb ga'^Ɵ~11`dfP3aec?v!Âw޿~4@Č ҭ0`0gx;_1;yA+,'30 'Ý{; 0Y2|O Gg3>:40*3i2O?ox Q@Bbf.ĤfI JKiYa'?phyGv1D 327, L^l /_f+%Sc`ga01`P{v30 2`fgpdz-GXN}~3 G$ Ւ\ l|| ?00\=Ē ΎΞ .0X f^AYҕ JR8pcgfg/`fk85` DX,jc`gx w2+220lݺASS\)NCAWXXAUUAHHb˗/0_!22XAOƱ[ fP`n+pkO?95@}Ev/@13C j󯊍1؊[B 04 CN: 09c X 2 ~ &%SpLrp1 0O * 1f.pC?Cj {A8 _ f3Ve O0f3 iP:SSScgNHڇyHHu q< 3B @@12_GO." NYQvSG>j>s3@13= ̴KdT-nfax;Ç'ʲ$i#AA{Hx"6w/ԣPjyDKk / 3bbx=Ó[oIi>н?@ &H ĿZMXû oWb}%TA8# C2*,B</y93#hfg!jX|>A>UOg/2|& c`cKF @@=#Ve֔'0~81'3}\rWX 6ѓ$@|ꍃ 2g_x=P098)  }A ''͙>r 3}l;Cxx 2\S"B  wO?q@E/6`5` w!ßAX\T;>p,<}ŋ j⁊JxRyI7YaϾg 8~d},u U&?:L%>à>C8;''<%ՁmF`l;8i /0+_2̺@f ؀no؁3g3\qކw`PTGlƔA[[a.PenǏ?2ܔaf0O}99!`J` pq ,D^dϟ?vpu|vV`373'@=l5@ rާO|_?`i"((0mR󂮊 7n`ყ30ĥ :d>.'Pr{=î93h,?ؼdy ؙ3Rl#2rT'@髩fPga UU,-]O`3 hP+0Hzl? | Vdd!)X2?hFĉ yxx**AE pA x+× r s3?X2q1pʊ1<{' R4!Wiİr%×ӧg7H;?C߁/@wP@zx 3×Oߡ ! 4{7͛2p7 (Qc'G~1+Y`'o@1z qo& ''mPhxοhx xr<\p=Xy 4t1k* h]zۿ@EgXN|g`g'`I ,+W&(=w,E ï3~fe3E!K`'8YY.^x 32pP=t]u@Abx4ý 7o>`X|铁ͅ`π c`(V;;YZ2:800x ɓ' e5k 7;XR* 7> eR<0Ƙ]d_mSIf6mLL̠! =P}IJ'9dxz+6Bo$X?0<X7;* b ֖6DU aMNU$ydC ,''j 'g~Õc@t_@@0313vLOl_@_3؞yKٶmavÿ `kiP k`+`H ( `XeCbT~xa{ Z ~}e6^'d lCqJ3hZi 1NOgwç^1`q_$C!bMfVͰy]`s]\G;v;`7aag) @_ɼyݘWZAFAVX/< , 1}bٺUP8灝/v h >d(H@.5P "" Űe{,}cd8{'Υw 4; @ ™Mh׳$$p] 'm^#co2LL  5ؿ, ,0808q%yf 0<&4+w?.ϰa#6IÀn|^bfF#`>qrH1Ȉ21ZH0|Űf[)fgw;o¢(kPPshXuA%Qen1I3x:u ó:;K(m@x(~~t6Q^)`L 2I1l\{ʕ 624349@c1++G&w}X\}=bd}?] \Vc+ 34w8_w ( `i%*po˗?`wPʕX /`vŠgg !pÊV/{6h)h,اA"VPNbð X9h31x00K20| gO=fLǬ6?' 8طx nϿ| Eex?|! *-K ˷~cp u%+Sÿ?2/1%uD?r 6| Al  "$,<,^3k?~{o /]V`7ԄL$Sȉ a8[_ @/Dc3LJf&%QENCnSKu10;d>ͱ#&D?o3<ضa*@ iLF60Yi0Hɲ11h)032H 10\쐮OݯA3Fwp/!9>x_b<@x@'2z1czƅQfbb``bd/?yT~ 3w2u@{B;P1*LF@t"S@6 UH~@G?׀PdI@e­ ]IENDB`B48x48_History_Clear.pngPNG  IHDR00WgAMA7tEXtSoftwareAdobe ImageReadyqe<IDATxl 0:6`kCԈ*q "|qӌSQD'A@wW,Z lSծ@U7p dOJ+SI}y Jce ٺ,\| B |, l ? /dx'Ï~=xic;J1@A2 F2b NZ$,f`&`.Ƞ TR!S71ݏ ^}J;4ҭNJ  {hPEꂌ &B | DhF  1 pfol#C^{h& { (,~-SRMRa2:;_@|xÛ nfxv-0b`cd_p23ȩ1H11=4K70Xsܥ7/@G'"2@3X٘c|<y>2}wn? " "B bb ga'^Ɵ~11`dfP3aec?v!Âw޿~4@Č ҭ0`0gx;_1;yA+,'30 'Ý{; 0Y2|O Gg3>:40*3i2O?ox Q@Bbf.ĤfI JKiYa'?phyGv1D 327, L^l /_f+%Sc`ga01`P{v30 2`fgpdz-GXN}~3 G$ Ւ\ l|| ?00\=Ē ΎΞ .0X f^AYҕ JR8pcgfg/`fk85` DX,jc`gx w2+220lݺASS\)NCAWXXAUUAHHb˗/0_!22XAOƱ[ fP`n+pkO?95@}Ev/@13C j󯊍1؊[B 04 CN: 09c X 2 ~ &%SpLrp1 0O * 1f.pC?Cj {A8 _ f3Ve O0f3 iP:SSScgNHڇyHHu q< 3B @@12_GO." NYQvSG>j>s3@13= ̴KdT-nfax;Ç'ʲ$i#AA{Hx"6w/ԣPjyDKk / 3bbx=Ó[oIi>н?@ &H ĿZMXû oWb}%TA8# C2*,B</y93#hfg!jX|>A>UOg/2|& c`cKF @@=#Ve֔'0~81'3}\rWX 6ѓ$@|ꍃ 2g_x=P098)  }A ''͙>r 3}l;Cxx 2\S"B  wO?q@E/6`5` w!ßAX\T;>p,<}ŋ j⁊JxRyI7YaϾg 8~d},u U&?:L%>à>C8;''<%ՁmF`l~&`~Pg3U7+$/{eA>bf ;`8r###͐p{O0ܻ W@?@OZpkAÃ}جÇ_̸ 4X{pͺ jO.}26@I@\< _~31|?1p{T*)HU(Ё 0]d8rQ_< ")옼clmePaXa5  ~r1|w؀MyyIYY)AMPכؿxqѤx1tmF{  8ف`z }d;~C@Ôi 0xۡN֤zͩ kNn"+3{`Q _9"MXax$00 t01؇UՖִ#<@P X "q  3\a;0V4/E k72`*Wtsc`ͅ``HJf%~?w6BX^?/;l#Ą>d?ߊ [ ,a /2 f-\Ǐ0?ΠTPR j0+Pc`&iWsݿ?820pH 0mavi0iW`Fd:ё# rrStɠeٷoga_l_WaeV! %`p2[W.@bO3>>NY1g^_`A (Wiİr%×'8g0'bd 9c@]@9RSy&WW,n\gP21a`QH9dxdCM>ewؘ`_`%)&7-@D-ݻZXdr 01\?׮1@ԀȠZTyL]Kdu1 ,M b Ö- WOdCaL?|3؜!MXP ~?Š.APApH2G}ߵ |n& e^^ ׬as ,'@4? f|Aa@  73;qa1Q.׾d`W @@DFֺr L f .VK. ahўEn҅#qrs3Hy{3\ڴMAP9 O ##APȃK` O.=DČm _0|z0X@(/732j֐f ˗/b>}2p@ s;;YZ2:8 $e L^׀0cx *@Al(@OgX!abP ;;o@^t?v>ち"o*hJ2p03q0_ (IN0\9T"M% .bz` / lT13 1u Pc5Ȩv]~97;0`eFr!; !/+=`;X_av. l`=;0 oQkF w3`*L£oDcccRv)98N 00 :{ R2e`ux2< `Q<(c\bT᱀&, 6Y{^!̾Xz1@13<·^Ƽ 2 | }fx'^3ij1\&_M2b&=95UD)J0 r4(?J$P7@(&("%gޱyG' 3=8?g 2H 31I0<ⱻ N F _޼e<h0vtƨ?C+ WT1("J`Ƈ!0 ,4$Թp2@xaE c쁅fE@z=0Rt00&E%%EE.<{f @Abs~+˅ݿEA  rR|  62xyؾbûZ{`& yP͊P|X"]2dx r=| =bcB8 {2Cs3??} , z V l of|0cc4͠&*  JK@ ,ff8|, B<'O E+~}pWor3Hzpkw3~ _W.b0tqOӃKd@3[7nY3/]a#^=? ?݄Xl}'@~ &ɼz]? ޱ0,LV&B N>(Н ׯ}bq'Ϸ W3i 7o\fxykμden^bdc_鼇2l z %'6:pٳnbdP# 4L)k%3"' 7) : `?|:?pX; հý v i204b8p n>T:*ϻM%$ E+6"mz Hff6͡ %ƠƠ # lʋ;]lqASw0<)U@G OJG' @F;S2H$hTW})"RrIpwsnf Y{2րWk]wv>}F ˁBs!NZd`e y ~R@L$#6%ba0(^ f 1iX$)!A T9YJq1LAL\N@ h*0Cxex?Á_&~ XϿ$ X< yFG_1lLY/_?g͠ΰ+ŏ_?x %fx/f&Fc  ` >|ͰganIO x88xXؘ!Xb';` 0hgp'Â-Ɏf@1*30\v8? ; ?i@ gdb`̫ l _|e3ׯ߀;W^p ý)@]30wsW>1\" lJq[W)}n?~p `1ʗ LLL ܜ ? 7a ?dcPqd8r C?Pf[ bTp;g`db𓙓(k! l#ЃOXX I'T˷n?yp]?n3<{pû_889@~1'X0C0^c`p;O3Xw f`e`fcc`_߿2y>Ã'չ@=bs@0?G`p2gxp Ã$ uXL20([0\}a} t_pl00=& 20H3pr1 (W=-`i?z m!bbfxß`faxr.ó~KCSC`&z{0vfr2;"3ۥeDDxy~}]Z VdV6VVv^xx9xp @00|%$+& ,$``l23x gW``x%4åw8eq<<@D@y!nF`뒅'*XG?E/7Yy/1?0ԙ 7l-c@3gBjë "*👝OÉAX7`PY5*{BHAJQ(f`L0=*'% `cxd/?Vc":@zUINd#WK sO_q1Rô "u-ePßAKWAMM̞>| 8TD9}`???ï?Bl 8ce0WfP6'@S]3Dz@QA[E [@ nQbWV/P!< Po: ՠ t'öT\ * C@K]@ XV3`aP7?`,AIA3ıy HuA%Io ڪ \ @q@h(GفҼjAa \bư%!b!?)tI5'C Z _% DL 00 ձ |12 XHضѕe(0{UdL~~fpl>D` `? v\c*Cu*<Ÿ@DWd1 Вch ec.$~`X${?`+' O_aVb+n3PDT1==Bb*n=zp]s/0óŸ? @)JXK[OLE@$z@gPbPdآ7_~K VXJJ[f&4`A-D0@U3b:s0+2h0B=\/36гB? $]l bh "vƒ|y r e>bO p<"{I |5,)C0@xsԚtr_c 042gϠ΢, L,珧 ^c<û'.Myڎ%bD=෋OoD4e8EyDx9cd7û?g^`lk ._d7<@{c1?fI)OO3YSuQ&Vo?~?F04Ͽ 7|a8yÃ'@Ɨ[Kex~1ğ@׍Lmn|a@G23<}dD[ ( L?11Ѕ{ ?߸tG)Ý凁P ~mc~/mG=3?fdz?3Py& pu1|xu-ãE Vn@'@n *~, 7bЗccW`331edd_ #ԏ_Ԥ]q 0s3[ =H9 1`6OXdZ\íNPJ* ʌ@10|@&)x,,uKnNbxutI^دgdb鴷b4P`?Ûa~CDYGAA -&O JAB?<0*}ʀ61'91@*V4TLE~f`xx`2@|:;1 GJ bf|E&p RKY}eVA'd$T~~7s0Wd`~rGw/أw>f߁@5xLA>I(C3$+N,A|!.GuVfF1,=܀F1"g@e@ 0| lmgR24@zd23G؄CX0"J ʣsΑ ΀ _C z'΁0#7tg`@X~cbt/ #((x?!?CbT| H+\l?ÑbГ\d L9ܚj ,< \'?y؀3`M'1(v‹Ov J @؀j@4'+#c}?}@`cd` *V 1L L4H+Ph6~fl`ߠ,?)*!.!񝟏oll8RS@}'N@d@BLe68Q2<_ )U65=o)?GdZ(dd+_^i X~:uaǎ^x J: E5$2bC=R1aGNL @i XbdJ wb=Cev;Hn]{'@/EAm!À^Gm>3G Ab4ZAc/~~^Q&`defbJ˗@.jM> I)I㈡!A\HlXW""7/4B ?x) *Q.GX +' P0 V _X}9;` |e`Db4 9_VAJVX(@b\f`@#ps%~\=Ǘ`eF'6z p:/4X|h ?0@@zW ߬~0Op2Fh?T@CTgn _)P.;@70g?>ܹ *jBTz VNbz 9T}/AK@ٿ5 ) 1Q 祗xuyo03ѰR `3-f~: 9+XܷeƿH4,_=aP cЌŝ['u??<) #ת7aO7(#e(M<  Pǃ1~v)_A2J7< Gĸc J8^fRq1Ej710t0cOḥ,@ÒDzp6CrCJ4LQ- hOB<װOeJ0mb|% Ĵ!*3X4-fFƿH(2FH2Lg`y,X3R"Đq'!9:;O;Mkߋǐ?()1 f eF$ cf^4c}!$Da~MԱ O P /21]/d` tq`L:5) xXR99׷%/ue9^Dπ0Qb!i`a U?10;̂h:+0g!%0O10 ! A}dV6` ق] 1NPCc/_ ayÙ=e, 5b`o`F C̅TGll lܠlH̀ `&. ddRu[?þ _0X;=48,RAEO` Rn8d&|?a T@=  h-v !A܂ _mɠŠhT I|4 GJBc xezw1.)$/3X03~a`fdl ?AI4 lstLMLy$ ͼ.@8=Gokwf) PL p lvzNmi5Uno9{H3*;gRs_e~rŘ x/>}ȳR fDSKXŲʔUzvd:Ug: 8]6JXjbGv@# ڨ7`?d4xZs hgfد@`s#б >3fWe |h? u>YN֋Ndbӿy[ - To%P] f^3?؂gb{/fb9 |@"*k} Q#JK IIIJrAF%@y s Xh9 ~L bW~>/X҃"m7VSX Ԗ@| hjC iOZvbm 44IENDB`B48x48_Identity.png PNG  IHDR00WgAMA7tEXtSoftwareAdobe ImageReadyqe< bIDATxb?P8=@C4=@C4=@C4=@CIf~ ($XQ crXrbĐ͆n/#l f`{ʜt,@|&aa~WggCVVЈA8f;8ÀXdqLs`@F}( ~mPY=_`\\ "1#~~}gD# ; PJ 7AR2| L~}? Yxdt`(0~ և+|as p033i&&!@1?`1 :ϟ E+Dû3x~X$D^\_"-O?c LLB FNI춿@X $|v@`%o/o0a;`0 TY~2IJ0AɵAGG0Ř  }H &&䁿`O!'!bAeP F(` DǓ ܼbAUTK a6# f#F U 9D  &RQ y Q#g{SM0{ f8G=%/`)hp*Q@ćHXH`!I"ѰLbRbeb{u +*Ël8ܹi_ltjD34@ d aɋJBh X>  1{ 7i÷oovn~X3 p'@G@GfPz@9k2ocʃ )@h1Ig?=|/95[/v .= DzCPM4 y /4?Q%.OhH+?J+ PK!x&Ƭn'XhJÚΠ $ ""`/r’.`FFÞ* *``e0|fxs 0Q <>w<`0w)~P 3Rܡ_d@XnHf L5febfb%mFg&N N Lg`)0}sʠ#+ e fDb3c(P/( fs?hNJ|s{" Þ#[`ZMNneXZpwPFMuK`3 A3N ܸCB0t/_8 1d_ op V1<~^6 lgc$ggC߾?Zs P ǀ>ׯaeX ?g>FHC OMU0~Σ>TȀ1 Ȁ1䈩8j`ߕG  f~ o;@/?P85<8ˀ 8r Lhb`q`1;`!?@C4=@C4=@C4=@C4=`zџ:IENDB`B48x48_KaboodleLoop.png/ PNG  IHDR00WgAMA7tEXtSoftwareAdobe ImageReadyqe< IDATxb?:`4@  001OJ & C h2Y9X~ N=- yifFG$`23(e @2AAȌab, ÷_! 71-=L exLaBCjߵ FZ^g`0AzK Gf?N5" ,bׂ'ҘQ7&goֿTj*[`"A>eؾ4@_1S!:DB2\EK?2 6(^~df|j Tc`6ÜI~tEtD(t]/ûHc@-lo\~=`i~M-@608APˁ'O`ˁics_؀+0c PTwG'3<|79-¦ yovqc1Ui@Gp"+2V`9Ço~9# '!iX|p '/3|{hI'U,å py@Q S-4ß_@8(\9zʡ _;F^Ԗ`g! vax})l}:P9X \aCZX>k 1CR`tˏ2\st,>^+@11v Á_=ptYgn-m P py,& 2 ?€{pi% p ,,&021fs ?YŒ3>[x{֝c80o}U;>PR &fQVclA `Qہ p5AI~= )~O˰eiWހb;k5u@FP.˛@?ý[/.c67 '%ML|ck/3\:Ht&P ~Fnk { )gL8L m@zH0+`&; î-FZ`)mC_ πR~0253öMW{{`b9 l۴e7Q@ 0)A GܒOXj<*@,xzS/( P/X~/-}D>1#r<< ;~=Da'bÅ|Lft>m#I;wޱK`nZ \`RCZd  s10ӪI* 3dZ00dTqm8t`w 8 jx|=y\<9\z쭁{ b1{Gi 2r?yO1*@Q-Hw# 6o1/`1 ?08y ]0a1V ϾCR/@h5Udp 6a7}6Џ ZWG<7._`K6`ֽqï@cwXD,cGKPZ˘AT[J7@,>+$4܍^ ]p$^}0v֫@zhY0p3h90:3 s2|:7:P7 A=_$3 n𗕓G97.=``8aD*O2^i=uuk=I%q`I _bfufFxq! %I?{T3Iʩ 4` XT*b_qIqEK#)-%pz4 ALk \DDb :a py LX,r)i1H;# >C, 4:r;@| >GpaaO^>N=@(ANL&+@3+y 8pFca~y? {g}6 _q@@XU\M>22\ ̘`y  4=tYA~:E1ٯ0lZ|ǠLHhgs -=Q㏛$/&_`'x(#8UE 055xG/{pp]Oz 1 VBaW?3Mc@G}4RWS5A?/0ܺk`9 Թ/th2`t" &L*_f!⪶7@Q {Qh)=2""{RV@V>~7z' JzJ f6Ç\h p/.F&`/+@L@kvKAXwԦU`H0N]ӞzCD.$B=" !f@#sis r{d!j ,#~~|w 55v PX":Np@t)߃[,zO~MPQ7  j􉁵Cq^{/ÐiE~HbjkkdOX}2:[)@NYL1ɌoEI`V1`$(UIENDB`B48x48_Keyboard_Layout.png PNG  IHDR00WgAMA7tEXtSoftwareAdobe ImageReadyqe< nIDATxb?###=@迿dda`Pb`e^{x_>xg&@1I&&̿UfˎSQAXXPAd d }ӧ_qW^4.^$?K>|A0`fo?BvaeҔfeRP````0̿~`XY 4=ϟg=~{ > | lg[/o}~fFR||A>gfffz__k?L߼1VOYY^RWFAL 8.`ab 40,~f`!$t 4,g* py zߌr|E={x˗G;Əp*ԯ_|ҿ~1KCNMXAD p< {\ZE, @G)o>p-fB~ L@L`G` (ā` ?H@IPFdZ P`:Ayb0!١ Pp03B? z0UPAs#U 5/,@(*Дc`&$$UI(/@@s{ {cc/@ !\@L, + , oOFNB4Gk< @iCT6r0pe}3Ï/@}dF`3]z @+00(HK!C~c 9Ffh2۠P MB(%UkV.m! n; ?od7 74Б<:sC?e]@** r& *ӥy@,DdPhƌ@TW1C0 j <oY޿faxqXsK+Kڈ qv<@ne`"#I 7'}fp|a]߿a{w o.|懏 <+3t #R X'^2<|[v^C%-=7 G^| 4$}ҟYq(tOQ[@g/D!qx#ןl+7(dAu;0&f1|x; ^~fTB: zr b |R&0ifP LgLBY{g m,dV U`{FG7?3eeӒdO& %N9]Sa؀j3 _~?xYG[?~` (^03TuruFh SC\A{p1Ó^,CQ)`Gؔ8c73? t?'Xf! z u`<6|c AL`՘a]1~ # ブaa=J^///W?! dr ï?17XI&6f_ j 0Td-ep~qĴN|jh,5L l3?`~dl %ȿPU`5[@2F`R`d_N`ӷ jo`@= pii1`/óg/M&i)q`'ÃE=A'p _|c0e5+EDAe z.\e8}Ǐ GN73S`g0hth0j6?u)޽{@9` c`1,ܯ  K5vp |Tɳgρrs^^npO I07CfĂ܍eg4A1 ))LF ԃ<XYoR,A+`L2 k 1pJd=1@LƠ O?⒟XJJC\FFB44bAPqrr0ۛ3f RRp[#  ,@23+!yp,< dd$"{\?u DKA31A OXt Tj&@cHPEDh%㭱1\zH012"갫 `bG+ U?i'00A AvXY;@@A*G%@CO82;5a@Z}zëG_Y a//"f/#l(B*)fEu'9w޿g|9ugO^o^Ǘ6xxyE%ed~YRr@jtHcJ8Al>xڵw۷v*{ ã\ EOi9_?~ ?Aw9/xy(*2{pO=G޽{ݻwA@1Ap|oĔlק_}$@ݻ/>=yy1h2"?&>};L uuͻS^yo^BAr4VA= @?pKI 1s Ob3ks++ `deߓgϟ'A;?A X`{\>|lNɇ! 4oRRKn@*1ׯ?fx bn"?0\X€ 8A!MB?}@$ ' q Lvo;Ь ܦY ۷o I-=w ~7#4'.L 0;ȣFAG+aS߼yҥ'B& Z v<qohQwoA30@!/y4KWhU 5pj˄;IENDB`B48x48_KGPG_Gen.pngPNG  IHDR00WgAMA7tEXtSoftwareAdobe ImageReadyqe<IDATxb?P8=@C4=@C4=@pD0220ğN003@|2xr;@a@ltoȮ#$fŠi$w7_2<㧿?}ϻ@20gg`!ЬTr= ~`(``ee`4Q:XBAK_A^ 1Щ8>~dx_ ~e8KWgc e O<@p32V+ʴD3h1(*21p~b``t4P",0^3@Pct Cg#er&U}؀y X|han) h5``C=S1a _S=𤛁'0 2 bg fP1{ C]3#yY yfb&&n02le_X䙀Az  $@Gߧ@w L;?:HB~F2I#ß^tE%І/-JCm^2| $ 0)=Â2(f_T/3` 8E ?&NVk(06 ]o30Z02pd`ÑHٿ" . Ma LݟPu`1i 'k0\E +% gÖ/ОKj@ &3F^ӫ@{8 !8k LN@6334& h6'ßw/Dx34dX{^#Ay = ^kfe[?;0`,?M- H<%_`gFȘAA f ׀K  B @a k ttC  WJL`eÊ a 50+; Cl?4 1`T~H-=\;#ϐb7#ܵ`B|2б@iXgY#V Z \5[~:~#r@+H?6"PA ;v#jPT1s" tO`~#aJ`ۼr-xiA]iW9  @ȍ{yMVa@z o9p!雂 0$AG5 *_dD1roH@< ~pXU Lc п : ^eXN@Sb{a!ʆ@@pD12/RPweu;;| 21xիW ?ퟗ o}b`zc?2hntgP+D,dx-oh ,,O%C^3+ *!ˠ(/ )! ,`6V6,,L #_&W.~N6P gO-+  VPHz@>`Xd_Fj<|p9-f-ac,op[A11Ann.?/_o K? ZJb wd>^z$; 16s@ NV`'pzp(ۈ6Gp;?z%-R D)$- /_|``6 Ņ! -((ęx1glNvv2 䡶@Z"8< [Re. ?:ֵ@pjʕ1H z`eo/V%>`{Yٟ_lgdbʠ ZXY98lz2 #m$)^I[풆 _~?F&NX'N* \Pr= 쨀Bիw W|'nn`l3pqqCg&#?<@1Ll ?fxe;s;l" ܒj2 v>۵Ak@_ ԣ6 PBr×޼yάR@eUf ZV`s7TT@r;(A | !)\ nc 좰G1F3cd8z>JKg O@ : ŧO`ś7/%\\쁭 J Ƒ@D=]~7 TS2 Nbx lj3@m[`aĠoms6i00310s%1h??@(P0_} KG'ܻ ^YYÇO$I^yR#>(f#S Ov3W08g8Up?o *0:u?}gx8-?pCڀ OB'()Č~C~\ރ2P`;w^0x ofx7çO30Y7F.^)Ko6,3>=` P 詙 sXTUМKA7vdoffHO cTpRJJ֭M@Յ*0p?#6̬ Z҉^Z1AK 8(t1YR̓, 3pY38,c^a`vd 'X2.]bߑᓟ?g123j2X@e>uuU`.(EEp J^:L38IK0 1'sp>á& ߂no;BӻXV0z/X`ZaPR_`qrr,F-J!4У??.1_ $A7f07W3b`2@: rz=S/XFkg N2k!܏SrNPv`y |L쓂2_%*6pWPXkMRV0pCa_}HhOA҈A@:w]?) r1NϿ?RHݟ?}{@gF..~10lѲAR,hAI?D)p^a@H1 {Pgdd1<ˈ9`ƍ;:߿dgϵ*R`e6ic`CI~0<=h?\y&fV?qMH%@!+ jJ22 l15A QC޽u00}O^V?qd%+°Jcr87[|;"M"D>ë?9~"C4k ld .]=}ޯn1|98fPYɃ\@ t_ /fxg`Z,Bo3p)\u99[Es=cbt6ß?C;28wERh)H7PO0?G&VB.Vo߾}E@91z}U`j} 6I3h , I2b`xpL?óhvp0~N+fe^ZLQ74lbl1=a s;iݻo޼5mc#?xXc{ d?21Z4lQDBuCȺ, n`xne8paBP+x?XyD8 l?\cAkW6dxF$:7jd)?{E6+}_!`L[0Çw`=?~|;O(L`6+foaj+L Kab##-fPAթ4 i y܂Nhc9ԃ-R L=@jH}͡IENDB`B48x48_KGPG_Import.pngSPNG  IHDR00WgAMA7tEXtSoftwareAdobe ImageReadyqe<IDATxb?P8=@C###mLdg`Pg```? ?~l C4F +"@n#?1 MGQ?`fgdcg L _}zzyo;@3zB hVB@3a``:/oMWu 8`a`fx0ٱ'腦A0 Xh8 //Hr5LL" S I'<_0} =*I^yh <U# D 7PG"=+*cÃ{ pb`Y peb%  /1v$**1؀Q @[1 }9 z@ Z(zDR4KAc94v"@G}z@أ ?exPÊD,s@iP1'34HB; ǣx/0)|PRy+}n2{ݗ 2>_T z@@r0|aNǟ}SY` P 7@Z0+3P5ՌG 7[u?"ӳ'vme}%+'++; 0/k^(f, 3#O^0ςr TmVx$ ; @}aVϠ['`(,R8lea ,6i\+v>f?p!n`+h0l,ʶ[ N?Ec+:  &RgYJz&S 0L '?V`>`aab Cag{) N_7+nu0k;; 0)sp1 Ϯ| }MHm Sew0 b, 4lٰf6cef`6WR.$8W;#O 1!cCQ:90X)!XU\vaڣ'm 3T%wp oZd:0(FXyi70C `9>OespSEL(M7 @0f8l!Ǘ_[G%gx T01tt˳>|ơc(ϰv1/~z0Ѕ8d> q@R(~p4BX80ɀ  .V`Y/ e?ꚉZ0摿`ÏB3,b > |@QZ0\׫a QpǃĀ)a)Nǃ@P"#xFh@V`Y:maPYH 703p 0ڊK`?zI kg x$F ov{-#>ϣ?CT#{!*kׁGAYAH=+~vfX3öIہVJP^g` l|5@!p_v{ ޘ'0 6d1~ y`|tovcASi`?T[, 2,ᣋ@@a){~`@jX@=@+02YA:pxY *@ZAQ_X9x ,.1|ʰ1Ñ#ah`"{ y, Ӏm -!? 7$Ă;,2t#4W`>6YmdXѸw;qdA, x7QJ ZO3AꑏВV;2C1'M 僪 >ڛfaw O3̯pW@o D;y,cP 4H#@ dt\_6|zI@ LRO03p3HiJ10':1_,C1sШR6`@a ByD "[b t=#1bKP:Ё#10w2lـ&^,nU\7dXP{{׀tAm."{ F&i?G@7̈ Tag< Q Z +fk\@h!߁HAR؄0/~UW_2\02 V\))@8'8@}d[h=F5j1P ]Xecx:0=K2%S4@u8t ρ͵/ZWfcC5mg>Pl6FA[y  AYk`> d˜>QNO]`E Pqe4ChtW`10\yrd~ vrv"j  ^RC0z+*ihȰAK5` )" c.X\zOԃ-*AN X t;@4G&FJZȽXzA}11Ȁ4 Le |@Cv4a߱d#,? Hyŷ6-HRCPܵ|>CP;0]p `hzwg3ܓdAO/!mFH"k CHH\Mj 3Eƛ^x+&10YA\&&Y =cA=Ã,Xh 4BtD8+Ҕ0dX0Q @Bky`BF 0~Ơ,\}d ׇl>@v2ZʎV (6gAwHIP 4g`5V?a h;э>) aWԁb<x9N|X;wi0v ^@]=nФč|~ ķŷ.|I {=4JА@(҂KtLMIENDB`B48x48_KGPG_Info.png PNG  IHDR00WgAMA7tEXtSoftwareAdobe ImageReadyqe< IDATxb?P0@`R\@To  ?T~~KU~ȑ#(bĂ:B,>KX'Y>a ـ?Xdaf / n^Z6///@x^" \n.@J]l@o\ ,"@ 1P Sz9hl P$9#<$!GtÇל ⿿Buo0hXh2<{̌$aKKKWHg"@pJAFZ X rÖn_3\޵AAGz_rm`dp``zрa 1Kpfƚ<{Ձ>r&+@ 9G7 6apPH3s1yy߿~:GmBR ö D^be+R邭IabAOjC  7kbI  k1]~ALN]AFOo VlJ*3| X'ρI_ 7&#&&X}XL~db߸l +0` }0jZDBh^@J BI Xp~`A#FH1_&voY%'%߰4 ؒ'!ebV `V O_Od`ta`0J0Bb_D__>| +Eq,;V1(F.F@=c[o5~`? Pa%!Ff3w.&0j#T @0$9[ wX R(avD}+όL _&fjGCLv|@篟H3Fh Rh (C? ?>7mr516u4A`σ?  zۚ[ȸ{HI JBf5(VxeI#3JQQ4bcD*ZQ.$@(coH6_zdCm LȄڪZklB rG/ԧzCWn3{3Bj`rz#PѝG!IKшDOBA^1@(Pbi㡍@^ ` C ) @fҩ d@#1bT^̍?zUSX5++ffLR#3bi"0Hr$@S ; hҠ#h&=TGiaP:9:X8ro b'D+0 laتo h90wV& LjF H%mQ l <l3(@Hb0_.Y=زaVP?(ւddfr$p1&v9 v<FcˣbzIZZ2232D5>BВzk xϷ5@}dyB RFz#<B›\ 90tFdx] +fը !5mhzL`% Rz艭! A ^3tFbx `5sg=@X=@Լ6Y#r/ÅSWq00D  -K6X#W?a =@C} @ *V?RIENDB`B48x48_KGPG_Key1.png# PNG  IHDR00WgAMA7tEXtSoftwareAdobe ImageReadyqe<IDATxb?P8=@C4=@C4=@C4=@C4=@C4=@C4=@pD022 "10xո޲00S@|3/F@>U EC @ex /?|1P /20\`c`+"Ь$8W8<@(:C,0$-yyu4͵tLU10a:/'\ o߱1<{ ngqH ?xfh@@=Ș-(!6۞ATAUAL+ь?x<&g@[_Bh=7Ái&V%N$ M@SU~@ף/{( 90 ݠY#Pv=2Bz=" !}`[}iz6~!lGА!!!!!!0;'-IENDB`B48x48_KGPG_Key2.pnggPNG  IHDR00WgAMA7tEXtSoftwareAdobe ImageReadyqe<IDATxb?P8=@C4=@C4=@C4=@`022€Be``>@ Puf gXl&gL Cz:vB:X>@1&=qe%qu# %1WO3<?|z=q>hw" ~{@ C'Cl Fbrj& Zf  r8``x }cxtÙͻMG#B AC7CJe +Dx10q30ʩ,Ï@90ag44õ+}xR3*^ @$Fn ~xP?/Ë 1Hs11|cPTx.%MttlA ĩAW|{9- Ó< N ?`xñ6AEĄAOAJ17gP *A}A0S ^I% PqbAQ T;/#˻v`dG>iyyHh Vc56O `yLN~313-@\F? V22!12 1\w@f/P?oX)\8 Û? z g+۷^7XXpys1|a0:Y ll a?@, bXgk7f\dx6`  *@pclER. 6 ||@Nj1pp3 0O2|g \\ /^>gXv%CaSw\`@ CA?v$@< cͼ==d$E-00 ҹ("LLL@ϰ222>|Ço@9KV0x{g~;#q@/āL`Pff&%`l 2}%ǰqW]k[2@/;9IǔYXAQV wzAAAh_~ ;;Co3ܾ!3#a /mc( NI Pgd% fFvH1@̉S r._b /L4e^Pjkl.+{0Ð&.p2;`*keP=xY~au H (ˮO`i# t  0_fPU'/_>0 !P31V-ӧo1,b1\p+y,PG dZO_2|ק=h ȟdA(k@2M\FFfa=dPV;ThFp=r00ࡎgl77'( _<@eس K>>e)Ӈ7 10~l~h?0"UX 81@`gp1ANNA]X99 Jɓ,b޼p߾}_7Z|~~g`vEpas/H jY+lB19 @@ ضQ: @FXAM Py+Ë A1`(?`E >uׁ]llS@20{0fނv@)uih#whhIƾBBB i`XX,y50~kmipjrzhûw9 Z_V̿hE3~2ܹs3"0t)쁨l l$?|xڦ-n:"99jaK؀$ 9qqa'ރ=p#GO2a#0Y[TPK/ WI8@HH2''0$z'~|4+ U 9`{׏`0<=ƍ;iP% JJO<6}{ 0<&浖!ЂآMq|?:ЁBBB޽ OEI O~2[R 0p2(*Jc䱷@O37n J7n\`8~|/ ol(sJ)d,z_sXzbπl/r^^C`w"DffnhFe0vu]=zuRJK,@°erp  pz@UQQ Lsq=j2: 4 >c`, ,NVȱ@;ITj=zmeʱ1Z( }l&`w^((^ %?`πx6H] w<|L~YY @"WPvY偎<}nzpLзo_}`( a`OAVVܴ˗Oiuu}>`cMHHWpR`_A CC eiiA`>w#>}̰rG@:@w~^ھ}%@${>4H\\~c_|0d@DEV(a##u>>>v`ls&Y^#= lc `-[k7 D݀!,U 0V€Mv7`iX6WݸX*=0y&$@427 $`g2aa 2(lܸX }ChА@ yА@ yА@ ym=oIENDB`B48x48_KGPG_Key3.png/PNG  IHDR00WgAMA7tEXtSoftwareAdobe ImageReadyqe<IDATxb?P8=@p022H_ ? R?,30xu8^00@|;L fTpo4>. bXYDȆS@Z]YRXA]_ǟ naxvëG/>xoM @|y z@H1;᠐`crTSԳTeбPdPVd {~|aaxKV+3l43*xd7 _<@px= rtLHapW/21j1)A '7@+`{ _at5Cǿ~VfLd{T #d̈4'nANÖ= k2((2lqY' zz  r0bEN-_~_`a'70 =šYP % u @$ @p4?ӿo eXwP]Myy}u?0xa߾ ke `o/`j*  |\~> 8F @wga%㯿?>Z 1Ă=0#qjFnF[YxeTUXXXy ,,+3|ӧ ϟ`hi9!3_ 08cϏ? B?3(a#cЬ, N~eX3߿UNGl{j_% -l g\`ضm7_m^^>}}-5k2DAD:s$(A03BP?0ȉ33(*X0j2͋Zs7@3qo}  @3pK}?ý{.^fO_LLt֯_Cjj~PA'PPjF$ &F/4J1>y/'v}U=x:{i wQYv<\8G!,YW]ȑ >|Ƃ<0)I3 caɒE NN _|c8xc`|C߿G  <3@!$/Ҥyyy9 03`h''@ `s œ۷nxpI%u>ëW<+íN:Ǐ99:_2 ,WN30=;,CA!hi{ ""׻Y 3CT:4XQlll`|%`,b3LJ˗ ]Uɯ h`?߾00~ v˓_: AKի@|K @@ ,R5$ r(0?()h $ d33{@Os0HJ c!<}N?~EXL@?~-{=0\=Ea۷_ Gr@}߿vJ3Yo_a~P3rfaa>k, ;@K3g`L0󃴴0:ف@\\,v30C73] /^90Yz LJr@ Kg .ԔAy2엑QB@B/֜.ce9O 0@1Cp++pp5!% Z@|o{ÿށCҥ 0Yax09]LI (0px i%i 9P4h k.`tZ3cEEY%yy!pEt0A! ƚXzO kn̈FHj ,uW utT= t ~Ap`_X@&H*]@Lk:`c1ׯ׿{O +Ã00C=0rK ZFk7;I,X~@{W28p `QPi"H]P2""8?u..22Rl V UU5O?=t{t #Ê@㪌fsrrRTf@NvXcٯ^=&pON489v#RA馦:}eb+ /_;@5Yz %(%Lk` ,O0H`ŊXG _5S`wqX1sPLu\\ r>K3PЂIPF{n[;lQ`Zl@w @3]ʇ͇Q==Ø_hxpC`xZ}\`quz j=}\*󯀝Ϟ} K>nppp-ŀ *DV 44 :Dtumx +05KDPgaa6M1߿ IbbJ;WJpp}P,2=??;al&8߂+JaaQp@yV$} 5 li*o\uWނ _Kr@Qx6z5޼y lЭgT Yp_ ,lV ޑ|@QO6\ r-FF6`{^0f`m~kC@%5vU<^t< \P=nxxO<ex.H@|@ /i 楪X^02vir2H30p-ï?%j L2<84s1 -D0ء4{W@_@ 6 *Ddz3p'\bbC^=Ű}Ν7| @=uU $@ߒxA D<I 5V :``h㙁h񚎝>$} #HbMhS;8aE& ;jwIsEf~`@2 Lbr.d), ,8f>g9@4?<Om5rMwwwa A( t<'09=aԩ6@X3 !9`f&k׾10&\s~C bKHE_mUKͮtpeֻ `{`˚|}n"@axH@"m㬤U&.YRp'1P ڢL @ y6n!q." ǟ1+4ͳ3^b`t[JS>asqЙ8`Sҥ 7_f8/ǕM8,1ƵW$)3(q.o 艳_1,,0 schK$Q%(4ۄAPtM 6f?dgxNO 6dv8?ݓ4:#ld@*2;X쩞Ĥ,u-,W!W2,({M5y-An Ġ?DRxӀ ="(-:#t}a W UDbikSEŀ 0M/:/R~omC$d3000#o,10,٤ʠlE| W !#!'=R-ufGDs W3p 3x3`Ylkc@`&0 o,&S}3|mİ7 /0; ZAN Ջ'H}艏2ql@tO` ڤ`=?Pߋ O3h0k2)p6;OWf]&rrEu92`.0z;6&à&Dz02f@AQ[`gbg01CMm <]׬,`<#k>{6}ˈ =X4~aÃ#0p% ܟ ߿|a|yr-)A"ĂO Dv}nyRaQ+U ?|dn xI#ã0lYy] O1@;Abо ~IR YÖ-G;} P0) q(;Z7 @ HpS /־dzV A+U3DJmyykwf$A j_"n[$pg512*~C}H|8Jz~r1k+% ö kڷ2y 4?g%@㍠B4BS@yy 6V J08jh]lixc: u'`oN!S9qMgI8ݷ xY!2٠4v"j:N AkI1y#`ɛi3Bl 0I=y2 Ʋ ,;CM~WM,{@192~ؑ4T#W̸PNfG/"43")LR0[(16{aHa9!1/pq#D$7RbKyy{Cz *Ҋ .lFԴ %䞽gpӌdBYJ0 e6dQ+F0z/`U$j A`l|6ch˽/`o ] (\@'4 wC[ N3dг@l:@,^,@'$ZESfv> jqAd OPH>% )>g޴A34?!SM>g` uy| R’!L Y;1f` t3`50V|_>W@nfAj@} ZqcCځ$d60]L6x"u?@C} @ y(IENDB`B48x48_KNotes.png PNG  IHDR00WgAMA7tEXtSoftwareAdobe ImageReadyqe< UIDATxb?P8=@C4=@CFFFx [1SьQPFo=~߿+10* aH``hU?|R fhJ 02rp3233%,(* p*îW1raXp?óO>q ïY@1ׄg9a?޲0iK܇O nJ6F=}W_<Nwݯ_OG~1} +wg$_gK O lR(fh8 f e.&,@ K7B \V00u{@>ԚPZR` k$<6E u̿HK_ @J֋Hem9UX @%~@=񉙉_bNa KB8$0|," =Kj¤k N1<<~ XKNVeyQ;W+yqQÕֱ%\:/h0~?l@{0333Kh1H2'` l/p=73 0E y\CS?{ ox  f ]P5t0)YR`ɰpFC^K?lcDKp q`Ϳo=?tX 0_h  ??@axQO'x(FvWb @h1KGD{KѳB@lDzSohge`8}WBf!FXja|t|kY_) 9kԯέa^!@@|  p@`eaAc FD_o. Z2 84Lsf6mcxc@ɓ@|_'!B'(D k#_ qBi6OVVpI ?V# JQXq mf`|~,#ï,gU;S]S@| 29@(ϓ20=u d63001020@<Aib6y XvC0lh?dt !?n] ޾k5Hc# M  2p22003si~V6^Nv~.&>>Fv^.fV.FFfN&FV&FfnF&bf^&^6  /c& febxKfoo2~ct 4s 's_RadV4 ꪱcA. `bڼ 84'7;73#ٙXؘY9Y ՝?f>z}0Yb t0B6(̈́F3&kbC4 ZAlTˠn 45G@ӬL"5G<Ɍ&ƄG D~i; D7@ yА@&c53IENDB`B48x48_KOrganizer.pngLPNG  IHDR00WgAMA7tEXtSoftwareAdobe ImageReadyqe<IDATxb?P0@ y `ddda`e``bb(.'G_0|I?X% iiL}[~=e˰ F2P? \ @`30&ǨWij)h0ps07߶;U8 y G]lfP3@`g` "Fz22a9؉=?;'E~=g7=-ŐT6meOk"A?+7#/7@_?eͰG0;~b#0,1@`: 4-R1CL%g?\fZQ, >e`&4D`$CHVVF.miu[ 9 L6&`昌eoT-ߟ XإDYx؄XBD.|`a軼I&7 | @O0'@ObV&`e-` * L?3?#m& {OYzݫ.@LxPL @eo]c(3!om(_W.%?3? ?!3Ʊ asvCyõ?>FC{{o ɳ1S0X`0C;G̼ww`J gPaef.`p&pHq!-p( &` `W Ì`Pd`ffb`eaa`0cpdraޏ9 : ?cx/`&1o %L}d"M86 ,YPuTo-GL>}=a=##k?0"?ؘ'Y[&[Sbdh 40 3ry ˉ ?23!p(QC[" N.fxx1#*`b`xT!D3!זAJcC" Ñ f4b({M zxf+O2dwD@`ː,$ d\@03Ddho z2\ X8_a^F?C*uW71|߁u ?Tx-,16X8Ͽ0HJ0: XL{FW_38(Ï?? 1̈,<A@M6/ f)1I_c8⥭&j!"_34n=2A@AQFϞ0kh- s?4~0mpAo0y*V.L38#3A➁чG {cEI *R78&= 4Xg/33fx`. rl ;߼dqu ~U ` &h a ޼rĄ~1I}fXr(+4+1+{f9 IQa&P J1.=x%) kfx٫ oaOû/w}lf ,Hb X8zп6O7?:  Xn}Կ2O\a|×^+?p/G~3<݇? ߾c7!Ou%n>7'! _ePfzAa +0LepU ǀ!?e}'Sws115qޜİ`rn F/o ?~`8|3/3, 3FEyE`̰0cD\`"ư3h-;O)M KfxGv72b!Pc , _ξ0ucG3s}!Eq^ ?2zAM  `l 2 ḛ{O?mE~3Jg8M.y j\/uOW38XPb(Q0 Xb= ҙA[~2~dì-ױ7 _@ hFdCr9Ykg`p d`!Cw /I3|~`y_31p3[@E aceT eXrb -CA"0V0ldq@U.??k3,IE/܌ԑ@GO}鸳lপg/_>0AUA^AV9# `b,Q~O=p+YO?6!Iˇ!8@!/Ȁ!RՍ_+24Ԁ,oY8TdIį`C >~b^<\ _l?1,>ܜ7C .`u^POR_!Pٗaɻ w_b`ʠ+`?PaX)9)Ltku^́0V??aی\q8m>2_f3$ wFEv9i6) 6afp?w7?k?0 }fm/I2T220 ^BzT_P5KF뺇 (Xրr^jbP:C_`> ه? 2 . O?ex!>ͷ|ǰv[  N f'y`1V okJ`; ,pX?H;R+Z}Ĭ "|>2,>\߸z ‰ص`fgeacbq`&u`xMЬ3| 5>dز3ß 6`mjaC,3GhT`F ]T$BȐ"ur`)O 1]&?d L:JP~AX!An`ej`X 4X_3ߟ2Uga `d}a d|áǿEՀS+#c`do{(Н/=;`T>6T<` Tcgx 2<f;A`rz ?~g. o 0`OK1$1xS( ֝x*&̠#`o&e*Π!l]P22@`:!P?<=zfk]i! I⃯=1`Zt /9U`1)I`egflq1VN`G\Aۜb>/\ 4Mfw|gf0VwYH`dK`'_Q&%L @ĵ Xq<03s_`6|p;G2(J*< oK Vpu/H2zg1qbbPpebF@ ^8l _o30p[Lo^3\ƃO ‚ j "~3K"^~Vp!`H?28v9X$$@yLÉ.U\~(C27#$⁻@i ^}.?E8#7 L}lqp ˝ (VJ@:kP'XcBF;l \&J_DVp2-Ym`bav`dȀ P< %#P&W>TF\5?2,7~vKcP/]$ QP$ l;u bqqn9 ;a /0d)p;qo3q30 =v!VP~1309 qi?EԃW6ΰws{uD2f`AKWA,< A ,Yi&֮ o3@Ao߽̠-} tX3;FMX@c2 ~fd`&]`X Ge8pV6͟z!6-x; vj Xd$X4xe#320  660LQ;~ys =Q@C73D?e:Ew v& g#` rKTCW`/0f ߁5^ a`7;̍CAc6 s0õt zOb⭓ U03pz3.3e8 t?? :2ҍ3ة|a0 /4쯗'@]I` 16s/n?B+R/`w+gaoN>@1: qJ-+"@30H4 )ůge`3ثaPx͠&XG| i KfCW>cH`C=zۧ@6}?{ lE}hV r;@40@Chu6vەX䁼߂PJ|a};3"F"kf`/`+>o^ex7} ď0sc`N%XMr;@t flHl*0A,[g`_F,ypkA7C@]gQj|ĂK'8ꙟYc v 13|ֲo| T/CCC!(T?! b _e j Z ղ쌲QsC?@G} i8W A@ n40؁f7pبq/!V  )lfJIENDB`B48x48_KTouch.png PNG  IHDR00WgAMA7tEXtSoftwareAdobe ImageReadyqe< IDATxb?PĂadd$$_1V\b@aDs g?g2<(AP Ղ_ZSVr+?6 PnՕ@@|Pb-@Q lb <\ ̿*/;7$ï@,?D=gdË/~UN/00edra?@Q> ׿_H kj`?FɼL L@֣y T 7~ B5212 _ex3H4b(.2(33׿"_~{ L_yw KL&`gd Xd]d(;qȲnQ Jόbet?_n{p\p2@?cb4/ ý}@H2|uƃ<N /~?`e ÏX~$3J030Hr3﵏π%#E H2{7'kރәH1|`^bVPV1g{.aq@QZe>ÅGYw>ZrigUu%^En& v43 ~.{}]@qr@ȍ9 BI[R(U883W[ O> @_ė_ O7ùɍo? ǁ!MDV[ R]u`1p;s g$+__ _Ϣ %6s /!qqj9lc"{gٷl͛}?$E 1p|x1g~;Äs}a烻?EEyzK)31gϭ߿uU۷o?@(1 &&5NH/P_%b:7e$Ï_x~e(j`1X?A1L'/×? 8lhV bҒ+p}ͰyVGBBA%@x@@@X@Xf&򏍍 Xފ1g`&6VvFaayy---9EU4D=\ {$(*ƖAb||@r͠GdW } u6?Dtjn96o}-uѸ#0`}Č!eb8 ? &b!?䑿3r2Æ _M?n߿xA3%`_'@x;w0<|\ 0~!F?~?| /_d8;HTj>@oݺpE<<< hq=/>+M P5/<{>Pfс Гw`M `!^ 4;гx`ŀ4-05?f`I߸GPC`R%+rٌ0O=?wٳ|=Q2Y؈cf~fPT Ba)0$9zEWnA L*LԀ =zpQPc @=2Qaaa/;M|0ǃ+(((o`'`ellr~cfI >|d0?s_23/@wۿO 4`3ŋ~ _B{տ t.@,i-##+ JD@#ZAhG5O8IʿDFB^Tldcx }^}d={ƥLEwhS5jE {҂[JJFUHH c,E3¡, djЃ} a ) (,t '>--- e/_٪`Ǡ~7I/l"<~tǥ@]f/|2@ԩ4Xd'ćQk6ׯR^A &bFq!H ϟmw1}j9"AXLLy~cK@-PF%%ep;,D;3ZqX D+AP5c,B H~nn>PWh0A"L`KA;㰞zH,pbkIp@2C# Ħ@DDhQńςf=0:.ץIENDB`B48x48_Laptop_Charge.pngOPNG  IHDR00WgAMA7tEXtSoftwareAdobe ImageReadyqe<IDATxb?P0@ yА@DFfŢl 2^9UJ 23x3%@Q÷?Z @,tK0zeat2ۻ 'hrߣ$?(|ˏ '.gxa0V#W`LӧOSgΜ~^f&~ffVfaf 畖dd$@Op 28;;00~@I8F%#`Z eJb8Y00'0̬lo|s?4UMEY\\TY__WPKKQMMAXX ߿ [/  "GACktDT=*I`Vh!󃙙++@ܾ}_Z@qKNUUww&w&VfGG.3~yA^Sh?i-\pϿfb } pz`c; ǃ#(/]ǎ:rXҶm't1|>AH,h炖>Q `# |_:Y cdeb?Ñ@E6?`e& +3#g X<Կ;CО=O4c̲fbSXX76`A Lv3^hd <CpPCt.00pyP{A5Wff@3~B?/~xm=w(5>IPEu  I`X -CH-Vve&fvFFff~) +z]HHBE^b_/kxX 3'Z0ʵ n| ADD[09112E H2J~A `q 8_>}|+K~7 5%~Ukk'3O2K:}_ YX,Q{u`KC)I0|8y܄on @߿gqki3k1r3pj\H9ISߪ _ dy̛]xOфAy}]c#N2|9:A@OVjE+1 ?o֛Oa2Ymdx1(@ ,5@u_Y403iœ ~Kr1|SdŒ7 ?fxîw7z{o` ;64P^`;\w<r(6A '2gVi/d!]aĠSm, J]o/yb?@=_̌ 2 Rr9XQ*+*Z> {.0%1# l1(v!f`4 zX:-hfpm֮Ns+̏'~h @OcTͫФ~'/ ``6#G>n[|ؑE`qfH*p7+0_e *u6!2 ֳ>Z LAR/=W/t~|SW0D4Pp~6?x`8 ` Xa~^>&n RL "L d[`zkXxebb08@XxXg!Qw8Óa -A/zfW ̰4q1ᙸ1߰ h, 13<{ 7e>R ?0Vxv Wdxh/9'QТ er=[}nGb#jǧ.^c\ MDd_'p~PJAAճ_ `|3c&1I dn%Me+ ׀h'LO2\; *  o p3I~Ŭ-k?(W+A#nywI-/  ?c:^c+,L;Kg3J 11| OWLD ?;'' ( R>U @c o|>@v6r&?pVsA] 1fȰ \uSY`ZAA؎2l9ˠXNk2u!/xAE z !-0#A*p2<I[ ?pZ[e-#8sg:~K13Lۙ?as3V5Ae9s O V< ~C.k`pcQg  1 :ç_tldV~_5,A! X+z adp'S)? B`^%1v#ÒN F *Z\;CT, 7`Aؠ5$P9&ޝ~5 Xz{>`ssf%/r2o`[ʏ?_ [l~KzdCK'02dx+A"/2K(2 IK^>P~yW 12=cV1p!%/+M/uht1 @˟g5LLw3fbdA<=^c o Cf&7X^ffcggvS=pr'Ǿ(p3 r02|NF~bt?0?2C^@,_wƿ3201:e+?Hfi o:u X&21Z߿_7{;; 4D>~zחIzOP4ҩva]}U@%f `π22yQ5=r2 00l;[_0q\D  P'q  Ηvl̗X /\cxwZVHS(@,hSGdVQJgz  =?Ϡ!M82Z/M 3A"uf6:5gߒ:STh̯*llnLϿE,H]b@3IJP;A*QŁ3S .tRF Α v9xޯz@43a@yJ$CKUǫ~Xd2B0$bk%hА@ y2"IENDB`B48x48_Make_KDevelop.pngv PNG  IHDR00WgAMA7tEXtSoftwareAdobe ImageReadyqe< IDATxb?P8=@C4=@p02&+303&և Y=  $$nqvbP/4J|IJz!A1I/ /`͉X @,g(O`b C|<\*BCf g``8=-4` $01gfb+`$1" d0,`bGQőC },v2L,`\ jjA[>  4%7fG4iVApP u5QtbAV~b-? CI?ýT„kB/`erSf`ee@gG^p?y P?g4@ my?4c<;{#Q_߽V>߾]//33[X0dx 'JQB$ Oy# wee 7oDyTxyEDΜ o_C=bb+bRr&!Bx bxt(ã'~|36 _`uoX>es']??IȍM $Db: b M`i5ueKϫWՀ<~fE >> l {Cq~aq.ÿ/y `*Ic qõ'l v<$ İ$ g"BxIB.d]m-??ï? v?V6FiF`-@#˽pi|+k-)LBAbW ~/[|'`X}@[48-AX# >`c/Z^(~ &(4}V..f66AX@f0Ca4 S3\߽ Q/ $JHI  (| <Z UQ 2?~{`7֯ex#zfhf+CP21@!yL,pap[cP77?E%@N.+[ )sDv``69ʂQ|;`y<@#qXLK aRr 4[X10(20101'%f`f7bg7IH44<@,(yȚX܂̢ ߼c$?޾a>zo 'LF#( `He p "7?@:z PK%!.`aaMp`%C050DWeXfx /Ȇ;?$oԦ@8%Է0.ee12d`}3(a a`Y!5 pFD 637 ë<xĿ$R)@L9R [m=?fHA|Xp? 7a!C`ZtCĨ51j J=\aw<,-VX elm2e>ȼWpP>ا/2|6R!jE &RҔko_gVP#/20c }3`F?3oík4 ?RlCmJ ֘c`@w?!!aఴdxk"A: :`X&W.1xۃ * Y  L`EI>Qxr)@h&?M|Tp~` l@0?mr$#^Y6`GƆA9%ABI~HAu8zEڔ@$ˆ.r, Wa/`{FCῩÓ}{O&`Hz0iVϝaɠʠ , &~dx?Dc~p r?{Ü&K,PlHza! _ (7K!~OF8P+6F(4, Y:J pe8XRJ 20 ;Q>C< 3YX~}pksq@ C/**Ԏe`ze؟{k׮y @@/`H14ZA x``Щa09Cxbk t~F 쒒 ~10ih0x,Y T3 6_,!l~=/p>NpJb>PZ  q&`LV駤0N4 b~0÷X-ePrrbd4| PMW%q)]ܿ={ M(*w?0Ax33ܾ_z^,+_ǏW66P`q+@r;tu~ 3; Lo '.uw:W1@v_2|r^ nln \еO7o23weSl@O|ld6gb&*I`e"7)8T^@D"/:9o^e9 p.õn0))h9#! `󥯑sw9C ?f _fx[_ xxn]p`lVb‘փ&66^^kW3lNK#~++BT`.:URLZPfd`ɬ;A'%@Dz30I2)Na/d󍁁/Ak3пq#d?_tKln Fl]eH+Ԁp `M g 1[W#8cgⰿ)8' !/9 ǯdIダF<[PS#8T l4TpԁX<<:OYr `G[@رR`''&F?L Jcq(#K6NqDl8 #.`.c!JFf&`tmh:l7:X`g'b" Vo?s&_`!j,`QR/ǏO]'m5<#`[0x==b$]DPvӧciaA=i 1GK'܁jG{ BDȣv!ٿ?8jX 8f[:j+>}`S^3B |DJ*A'aa#cD ˀu #Ak=o؇1c.7 q_d ybXI F000Kxck>4A6 ['@X-` pB.A'XD!=ty~>^˗30Xg+a*o'1<]70APVD@lŌ $av ضuF}R 2<i+1a6=&`q[as+@R{u<{؀IȂAtZ&`9W5f?};L2&G>~~`* _ W,P1l~ C@ 6btϟa5a 6a.8#= XtN~``zB6A@;AHe&`Mݻ ,P:.v;~/x 4nl6w}W_۰ //h R=$3q5iis)h ^p|J6@m[艙 T@<(͖̓ }S tI ,l bsӀ~ֵ͛oIH`)'/;;ÕU O`{@ - !.,Rg# ȎSCj 3;ׯ3?p$wplp̳s(9`%*A䝃C2lfa"&F#N>hhv xs d' *fbq9Pz6y R4=@C4=`+Kt20IENDB`B48x48_MessageBox_Info.pngPNG  IHDR00WgAMA7tEXtSoftwareAdobe ImageReadyqe<IDATxb?P0@ yА@ y 6AFYěJgbC1hi% ?#Pw }H@?>(0zQ!@,T# E1# 4XXX~7ÿ?@i0fd|ļw%Z@xZ_عԴddD$Ex8_3z oU3i GjG#z@ LUtd$L0 ?dҿ;ow0ܺ|ɵ; EYc(/HIBDd`Ǜ_\ݜJA``v?}  ?_ wo?b(û|pDx HIB@SW̐!"ȘASAL6/|c8y6÷_gRg`afd_G7@n> ۀ(hb@z@ 1wb 6dGX!n{=WICuU .fX70 = 3 +'G$|Ҋ b< 4hVR" ف! " J􏟿=xБ #+cD9ZV8f3$û$30Hh3(XY 8D@ x6* l;/43? FVyg ~c2cPY4({ {f Nt ^.v+~0 & faectõ'?8XjQb //%5+7'0k W }Օ\d<$++V&6^aK cw C Bdq|g&yUuPԋ0  Qg12RgyG`|i1~#=b7DE$8X4 G  %o`3KNeeؚĂb%WDOR'!N"eN߿ * X1 GF3 #'?ç +m.; px1D% e6N÷082+)t : >;O _ٿl~>`=?4#( @|)%)#&y py@c`JMGndx?C)4 # ax Ç/؀!vVN66 ̴L L gsOX2J g7>wnnNV~>F[ͩk255} ,`Oȃo?dP`( U{ _ ni&6{1z1?pL'?20s00ߊ؜ @8J,L  ߀ao .fPr`)##p k%'?>}j%'p{T~X@ǃL@OBS G 233TL@ת Ӷ ֟pX:L_IFAJBa١O +b`c@oBH&$Ai/@458tjTUAkHIX a/ 7>?#01_%0$)`] kz1P^}Xl(j`HwABء}a`caPga`gN`ef8pxL0B[#~ L2?d@ ,Pf l \@򍁝X| }g [~0z y`?M03PہR{3;!]7X2dLہh, pL'^`_WG̒pO_2|F4,!1E߁}ϟ203" s<0)1=3+>'8as(@WA /e "`CQR4C=.*A^FkCw2sȇ&5lN \`}xz0X%Zjy?, _I= %6vn_ $IlN \1{~| ܬ BXdGdtFH GȎx, ,ï'ρ;ͩ~r.88 274<1=9c.~`ae@SWy0zv. " -̎ QТ ^|bfȃC7c#|co_%W#J+T@:4>ۯGNzŸxX #V$H @C*.x(j&on05+zp p$!X2kʠ!l]w34xd? E!5?`d20 s12_p&%SnI`t~?xr 1_ pFX([;zZAJSAK^棷 _?ebeegp6`Hud#P+$J/>24EH3 Շ^0x`3B^@W ]y3\?<@؇eЅm],lbJ6 b* _5^F30yI=ue04 vNpFz'O^` 7/'(0:`ψ9 xjlp+@;2w QXv{a_*002|?ҧ'JV =+>J<80Êc'`v  1x0@. e) >篿06!QaW`— ߯du!(|&$ G N:>}+!%>y``P~Ƞ=ȠrԶaL~6̬ECXisK8 HIrИ);$  Lz @|RI10'2, J<J?oX # \"̐)&P{I jUA!y`lʮyMtsd1*CV1m6)W1p74?0S07; ?B  ơ <1@ yА@ yfWIENDB`B48x48_MessageBox_Warning.png PNG  IHDR00WgAMA7tEXtSoftwareAdobe ImageReadyqe< MIDATxb?P0@ yА@i.+c`0vfڀԲ wFt|3++ûՁiŃ;5- Z$![`hh28Μ8g:OAF DmĠnmʠ DsR@@)B2eua`{e-uw'$g1\+à30|z`gP `Wa A j@Qid ̪~oXD<XhV jy@ D%CC:o@'ܩZh04!Io${A @0Q N Tf:$ o |pR ɠan3'B)i-,,L: ̒r _B /_bb xXlyAʈR>Rdq:pPHgn`Ą᧦&J 3[+C2%I (IB[Π)yWQ @76 (我$⁡o }^]CpQ Ĭ<<  X9M %,Az ȍA5 H;8yf`PSc`cb?Y+"--X`k((1J*D Dn 4 QVreT: tC[au fff --- L@1zx쐤;Z L@2DT&I2(30v 8dQNar :::>|(*`l l#}7%A!5UEP,8Mr%Drzf`&0AE\'0$..fXΎYd0QRd`VATD{ Hk`%j1H_!<) 6XI($$$98 P,xz20|u2Ơ^)y Hn]L~ L<&4ĎXJJ J0 ,?}a0d @Q@í,RsAW***p ZÛ 1^C `?#6 Q>Ъ|>~`[<&b:FtiYYY,-(`ݡ#2rq3H+7`J:R)Wwf`yZQ ,6#'(P&PU`Ma&sX2(2 @/N4[>.n^Ïo`LR EGk3\ѳ b\ *bX I8HX10>c,@{ l06PD9"F#^q12/`z $3+Pb y% Rr ?kL^΋w?`QAbP Op kf Y;$d= ,PAŪ|@0HXY5 2 r@yn6r`1 `/%%VVVq$``We1yACTT6ŕ OjaY~ݼ,‚OwS߾0:=nF0BkapC̒ b{`A1KAk\ Zv d,3 NF0G 9 Aʊ Fv4r /x؁;$^<ʠ%$ Р>(<@PPkb%H1eol 8XP RTKFY`>#P䈗h\@ ҟe 8@vL|;90/ hc4Px6`Ұ2fy4ß4 }A`w ,k_b`68@gE0h1\?a dh1pM`0A Y!9?J ˰4`Q͈ 9g2.O VfgHd[~zAo |h7_$?466Z=5Pf@'` 3o_y}AXJb9g3"M|Yfâ^_ @șx0޽EC TLGK҃f$_Ȝ ơV L=@ yА@d"?VIENDB`B48x48_Misc.pngPNG  IHDR00WgAMA7tEXtSoftwareAdobe ImageReadyqe<mIDATxb?P8=@`022UdnR @fff%}hI+@u?dr;@R^ t_t@0VV?~301ԧsssqrr1|Ǐ@?o}Tz&'0}… &  ~D%~jBh ^C @2@~dx?}l8 J 0I22lݺA]]A\\lڵ z pz!00QtX'<Ï?!` PL(]S`  #0P1<ر w*~ N23dfV0prraY8=@X=7G]߿@v82 ÷o?cfs^߿Ih(b@Nj`ab [UUm;\%ùsDZz 0<`iN Àr<>Ao0d(1(**& Ǡv44?2FC6_~bオ&L@KDD\(tI ;`rvCdVʰoV3g@(vZ L:_|_3ps3 ^FpA`f 7@/9@P?SDDL`L;¦#[@2vyY( -@IXQ d`aay7 y)Ae9(&@1}8VV& -IIa`yCΝ[I?VG|2`bQQ%Y0(t i 8,i cAcgy$ ̠2 RR"d!,~2ʁ=L>po>O$Pmܸ!..aٲ`V?z#0jW80z^|P&e<'@qAgJJ `gETht:|8@*V@L=z5ϟ__z N> BB|`π 0 ~}!@Ev<第A |13 p DGgK`Z:r۷t/4LX0C֨{×/?޿ #=\,rr3-7 0+|nPXK(`*!7ÇSQQ!V3.V={p'OB\,ԁe3`ǂ r(!PH܃π!O ,~98!40ܿXpHLRׯ?;ի'@ۻvmj(>X@t}`a`-K\`|,yb`;136+PGٷn߾>zjz:::)H @,v]>>~pUJRD(̓<+2AL~Íޜ9slÇwO MayC`,@YYC DVpL| ,ٸ0<*0@۷oh_UU `k .P1 ]X`yFxMK/ g_,7 l{v`9>,ޭׯt ++ 6@ֆQQ i``*,,z@-PkX/jr0_6)~>nnNp X *@?~gxP/߻poo5S@E+(&~Lm(bX ;6VV.߾}5@/J 4A%PuAI2T|oAA>x3&mɅ޽[ )@$ 2@O;>OAuɻwo~6߿?[͜D-׵@v.P@78V@sӬH/AUU aE)t ..5G={ S>QQ`O!268XY|/^PV/߁IxlMV;TT4B|>VF߿Z΍@1  emP~a.0@ H?<@=7HR6 o߾= $@,ܴp@0O0\tٳP O@}F) 5=d/Ϟ:4Ǐ_@|| '`J`Y'&&1!7 ')]]99)`9O>| e>QQQ`~QK@;iVӃؠP;!5=@f~ X*~@,8wv2DD$|*ǏRMMcF~~~'Ea(&@Q-( 5mmp)٘U03v_{f|X'\{]@=`dd0EBB|"@2xAFF\" 0O@"2t͔B6/kA?8}"27?ނ%cB PzT{T3{d._>ɓǻ@#\@F #qU}>$}vV>Á% hPO P 9&}HFn"J1'`C4<( tQ`=|_$}}I@E,wBy}j{ 'ZN:"!I/~sP  < XA1 J0?w*``6@_ '\zb0M֤޾}woCYiRǰ.\J@e ѧNǠo౥g^[>6bp`w //>nYYy`[ܟ$`"T<r,ZA%H7q߾ Nz$x+_bOa;;ak ++8{X_3@c{%/}TP~@3^pXBG!qH;N 7`} 4G<o~eM۷o.y͛Wnݺ>{#`I_>z{w@mq#/^|ہ@,ffwԁd|v;wF,ټ!bb& P03<L P+/~-0_]arB{<LnK^W\'`ӛ4Wzd %%@e>l,g)((/' tݽ{G/ DY>>>w݄6@ 3DADD4ÊK p`6I51!~E |-0Fx=@ ,y= JVhRU@SP>4W%)-rUIENDB` B48x48_No.png PNG  IHDR00WgAMA7tEXtSoftwareAdobe ImageReadyqe< IDATxb?###5@?2b( .=#@1R@9@lD!] Gsrq1033p0jj203|5o/^0:s a;ȸ@'3D:^@MW9(LJALAHh06Ȟ_=c`x {bu.4yx0ݝ!ΎA?nb I9 ~̔ v0<@C@|i)  lC21< {Ob(>pxf'!fe`q0 C`rC&P,;;Û7 s`=f] Kvsrs'L OU}TXa66 FgQpO1X*<$O,ػ10{Xg,(莇^ eAz ɜKp0N0T~Ȱwn߆ GH O18q8d /0(c q/b P6 ȞҜX]\ `0,Ǽ87A@Xh^`Q R@ `aOc`@ [`db>002(CpB5@J!5mmHu218 J!.X7Coq1X*!'`l|x1C10qxb$'m @0(20| ia.3]oa!AOpk{.h%ɡ0 `t)#@LpGO>80goANL16`|a R@ XPBXbrV$ڷ7?oLt<0ss!`㑓` TB9`IB`PQ RSI 7[dST˅t&h! # qtB*P@=a`!@0ISWcԮB}b=@=@\/3<6E*1P } 4 of38YlիD8=p Gr $  .<>A 7l3>c  ==cP!<yV%/{ F/yᱤ$Q5,15}}Dx_@* `WAFoKKK2Nx(xҺ@(8̐( r|1,PE79'@u]$G;K  a`8+)`o TO3)7) '@Q~4` @1H@!6}ϘI)/ 2<^ P5,s%Dq#.!XDg 2`+4Ăd_"bL_'+A V4 @Z@8<O {;4^6vw| R扙Ձu  030Pf M£IfytgXl ș:L6!c b Iy[ |`=45#@QVBXA!d2A7 .8̬C< #VA#מV̀E//zJ؛X|7XG4 Fj.%1hf" !`!F~IENDB`B48x48_Package_Development.pngOPNG  IHDR00WgAMA7tEXtSoftwareAdobe ImageReadyqe<IDATxb?P0@ s)6Lϟ?5bcgcccaeeeddF}kLLW~~1Iz9 v:.CZZOZZANNDsssׯ^z _>G 4%D~ &.aic`ia "" e@G? 3#ï?~wǏ3\pݹsƍ~'&F@n r ?.rfaPQRb`gg?y o!/gXXY؀je$D<` ݋u_q@PWT%eаs3s.NG gϜb+33`YXXYXYgxǏ ׮^epǏם?~'@@˶3(33,÷o0Ic5#3 8X!4#= KKJ22(*(h"NNcǎ-J×/T&s+k՘X q1Á !޽y[`_@G30qP hi /90004ͬ5gPP2te-Tb>ãG~w= G>=:y̬<@OdzgϮbf| ⋬R|zN \\ ߾:pfbddx m?~0@! ʜO#M=lP]D|`/  ].pL0c p:fx,>_@ǃ~{ u?=B7TN@,D"?TUUa9XfɁAEU?>{%-#ɓ@-8?D-daa E:: ޾ax=_~ ǿAo ?ddPQef2TQqn  ^ 2MVV$×O9T#?f`Ewk3x aCFKg*tM  n.$hQVVfc:@πoHC%rb{X۲1|] n<]0i _=U4}S@n , b6d xPPR L߁',_gxzyC6m{)WIk] Orm1==jyyŖ6Y9ǏrpfabFϟ.^,shh02<| -|x5=aS .zP ZTROIHHebx-8'Ņ ?0|s ׮]{l=alJ3}|!X(o A%W a nf}M,WxJNɃ  ZsvO_?xxxI 0۷]z FɷnnxW7yY1 3O` 7 ,y|;m^i;թg4Tko[3og ) ʾ ^G?|!'.]瀭``q`Ih2؋3ϞegffgZz͘u7:Z#ӯ " ^R}~oO@ Ք?yd)ubw;3A18XXEvP !IL̓\o?t#DטU= {PK{iMU^99?/xq7usi4h@K Byʤ$֜ O8N͍ܗcrg?D}70Sf,  !drz$H@zhϏ?],cǯŸ n`ϐH/A^O=F |}<~| /?25'3X=U[J8\Z̄  z ~;ނGi`W |fX(0f1z13JJI'@gI?wW~s~k??3pA֏}1vG^~l z{}{ɕg /e-g`UҖ->COT_DM[ bo=13|{v /a /_^}u' H^æpKҋYv!)W0|y񙁝 l1`bf8LOO-d@ @˵/xĞwd5ëB LL ?g`a,71~p%+^c 4fxϟl 0| W Gp?_N=@T 3歪>AQ=ZB;?`'Ý7?yA@ ghx9YYx8ܙч~u߿>3hTt?4<մF@chyXXd}&F0cIENDB`B48x48_Package_Settings.pngjPNG  IHDR00WgAMA7tEXtSoftwareAdobe ImageReadyqe<IDATxb?P0@FFFτO>޲e-/ Jr'T7o={dwbfhSc֔G]VVV.{igJ<r80P܌ebXp˗/ >^F o`x5kJ31[ppК#GNOLL~TCgu?|?-/}:P@Q-艋˘jhBB ~4ra&O2 ׯeqm`z T ""W%% ik+3rpprmիw߿{틧O~ AYTTd䈈h.)) ݻ3-E%30ع:00M_>2ySλrb ЈgOqttvuk]vKg ¢ .f(Vc0g`: u1-'; GW19}w+@pwl`8xÆ =zN1(ͿŕwhDGGZ2sss1ݻX3>gc8#Cv2 \@0ġx,H1Ei{8~g̳bS3{NKYN+3*ãT cŰ XݵӇ@94nHLL \;;gpu~~/_?2څ 2 ǿ ̨ Rr.ϡ(Z30c@AKӄa 7ep3`r1Ξ89  T ,I X/ru65V̓] Ľ ߿axr{Cw1÷? K1Xb0 pßW~SWsF c`PV6`Xa#Ã[ \|1ro1ffb=yjyB X>/Z_߄7xF`˷ a1d$ɰOv ,Usy+k0\]5 0 I31dX 6Æ ^=``gO!5 o/ݼ@=93Z7É[732gW`z C3>w&;~ 70X[Y3\?v _0q30i2(*2lܴكC 6 Y=gbВ*"Cf'+VKFYg|T+. 5f 0ϟm3432!' (%T8,cf0yx r rJ +W`x"C|BCf9w=3_ ``WfHMgT6VY,+&ht78@174404662<#"uʹ ͸G6EsE00 d11dЗ+a  ,}Xe1 {1\y aJ A ,|J |o~~pK_~3(Iq]CA[C;o?^jK?ܷoϽ3gPdU" BLW8LE};l|grDw×[7yx>bxwÍWO,5;R\ \r xEAG׀﷧$Xi=) E?m O~7P[X w'3?_0(cTa`B " o?/= &?7~n iɭx"^8]a **<,~|]O2| ޾a'33H3|Xq_;dM, <a`aԐb`JN<$T Sw?`O˘OFy;>l9Zɠ ߁؃]?_ }l}gbd =A~r?3x/? ,Z!`+ۇֿg0O?/'|xi`#={22ç~<~)0gt4o^' R rBo~?,y)ƿ@w00&=2z)÷zpG᣾ O[/x;zl I蒸1ܻAH oeO ?p;ؤY+6a>>y` n8_T¤>w׳ ķ<j/ñ [~|:2A({[U2ȞU'`23)b)a lVWİcەϿ=wEA &/cܳ3?gg/4t9ÏۯIi;C[X΃ {wGrTZ܃6т}N6f&d[9KO>;А' @0S s ?+3 ҟW?9M/5#8E':dR BF끚pȴhfK @,͋oș  > ͼCk|b-@KN0 \#«IENDB`B48x48_Personal.pngLPNG  IHDR00WgAMA7tEXtSoftwareAdobe ImageReadyqe<IDATxb?PĂKd1i+ 4׷/~v'cؽ# F\1@'3OV%J@݆_ł[Zğ@[ ex8Oڿt8-$9I1MH2W `g` _@exw㣛xAO??E8T!bѮ.kt0Ё1б?@`|__2<ڿԱSS}?I@큣9lIsC!" r<AƆ2vl޽3}{@99d1>Zo%?APef``bbvd4#Ah@t<1b& :@a)| 6@dyF1YWrA]L:C90t!b01#;P9P8Y&h-f(f L_!eڿ IL~B8HHR?%T  8€V1+ =/a I#'"m93t?qi3Xi b@yu@˭"Rj?!E%{T ؀xxH,_`RbbPUדeg H  <(2333?!"rK$O<ƿ!t`*2p1+b@ @$DXX!!Z021#?H}j2{ ~YYX H_Y3g:rdsfPy?~C=IJ Cï_?4pb2H`QdfKY!;xPavz?e}]0T']?"W|)5RYfGgUH&;晿~ƿe˿o~}&xDR&[˳/~ C߁l ftN@a3 ?={ړ_/@@Z{ӎW.=9!!"r4 Xyo/ ??fT"BP,꿀i+}A 0l: ğu@0T=Db&4\Z/Z~AJP ؆_@Oybǀ.#b0@xA7>f1 V2)XSBcE%0 *.0*q~6??|DrF<7c& 1v38 &%}Hq@1iK?@v+{ۆa6UC-:uhkּ41")OreX$9Ó?'1W3~ _\b5o} ߾g;|k Ͼr3he漒Ww2pFF%719>kAk$Õ;_̽`b` ,ˇv2\ڶ..q_|`bf mܫ \epqdvcXCt)H@4?ZpL by̐ (p)qYnff`Ǡ53] &``8/ؾ-8$\Ha F Ynlpf{ہ*JN @N/~A^ɹ<@l=AB\WAQpfd/ y#*cxX%}{ d) N XH~A؝U`dЖcct`~LO&X~8?hg zyҌ w^fr+ ÏƧsd~A $$ĸ2L_cPTVf`ᣰ0`SIN`Ǜ31@߁T6 /c*;UQϵC: ߿#,uX8Iы bPUg b1z+0ڄK`1 X}ecc```X/@У? b -ګi'c&~Ow@͍̃)?xXcԘ</`'ٟ#;003II1Kw3| q8 bȼ@q A/J21(kq~~b.'w2HHp3|y y# $bf`_`z>H @h7; -efVKc$e  珉0Ck `8 #fa ,YY~_~ex%Ļ B OճO`?>}adT /P[X0 $? @8=̤' _KnppI6~3|X-Fg}!_^Fpmz``/o@;xAHWJZr y@|} 4?,<'`r`fdPL2|dçߦ‡X'L f|&9? L,6't # N$hV?3o`MXȳ0"%w2 0h>&PiC@Жg LN\p/@YJ`tsr 9Ф* ϟ0Hss[b$'c 5'nJPS`TVb?330_/nBjT3h, :FAHeeu˾Ӣ3,0'PK:Fk[9ГaH-"1n1t/ˇ3|3{U{R #@?@g+g/UggVce`,,FHF}S;@ '}; RX%-h'[6XƄ@b-!U ӻᦼIENDB`B48x48_Redo.png PNG  IHDR00WgAMA7tEXtSoftwareAdobe ImageReadyqe< IDATxb?0222 X @,=Zf}@C7e0@ l@+HA<# @ 02t,[ ` {J z 8%Z3E3(q0 p20z\ #kLd@9$)|z+Vзec@\zBqys 3d641e{0p0*C߿7?}ZI }`O#n` 0|r+6uϟ7EXPHY u`fUְN.py泗/7eA _ \1j{. uc/>3L/pj( ˗ˁ!fXTX8\~P=c'Ȱme}̛/_z޺%?!| \Hu=5cX{*FP΃x{rf "I+dfd8t!k`={ӧ@?B lX59)|F/ -Zne PbT@+;&oAvHB j ׏?> 5- ̎,/P/2t@axٳКwPbBoF~gsB`}`6=@T4n@@]kd̨IENDB`B48x48_Reload_Page.pngZPNG  IHDR00WgAMA7tEXtSoftwareAdobe ImageReadyqe<IDATxb? 0f32@5i@5&@\%&L} ?&3TӐ@m!dS:TD  PxG@$ZnJ xfdcаee9߿C@ՎZ@֘?tWmctNf`׈@X@'2o'88eaXSAO@$xbX9`U z@ X; 2 ӲN^8Tu Y`#0:]bH^#r 3`01UGxuR0,۽؄s##SP9B C bbdeab8\7к?C?_L gv1b|Ϟϰ`:$CϪ L*;QDԀx20@#Ci,52+3{$?O &/2Yę_P7Ai#7P\F#5/0Cc1'n2Cɠ TG@,8u fQ c󪇁pf`:QV #.cN- [F֋_V LwC`K3!7ΝkڅwPa\f fI pGM'b2~:`O&1E210|ݷ \$) ^qg@O E2W2 3N]: r*<|@,h! P~̵Ì 33/P%p)= Gdx#3!Ŀ) zJ xL}7Wh$If0T,*gW d́8wgT32FS/`@32LT .еiCn?~g`:A  Tc0 V V O?a8_>2 Cx<ãOwAlSdԬ& 2L&Hz XP3P90@@1 *Ф҆>`&0[>νGHP_*6cW'0iZ$C T0p|!qyE(! (~ڹA3\]HCB<  W^z=ɳE*p,0@eb~8{OHA LjHLl ߀P@ t5=H 숀`R@=@6(e`Z=`È1ojc.h;뇳D{߀t7H,W0۰s3/Tt#}@~v‡S .@Gu$:+; ^anwc(k`x%Czg÷_r{@P rQKqffXp' %0\w`' + XwаS!ʐXW΃(c3 X0:iax1Ï?Yu?1P@$ 3fK>'(dCas}O2v3ܻ{5@E% \,Xp(+g nar=C:?dž`a).uf!* ϡ`(` g 9;2Z%Trp9@ Z c`+!qٽeCG1;7CBw^.!_`kn|HKϯ 7g81aѮ- >ρ/Ǖl@n}C&ٗ^32LPP ,3o`S17cZ'Pݫ={[?_j <Ӂj'c1@D= yM:]Շ7 SjcUN_r7 ~+S81AzCL803f.R1r]sxڂ+40|0 X?`duȎv iJ0,[@_@+ ~DJwer87m*L`!›0> 1W3.79a12🴙2@3ʒ ,V=v-պ>=vQ ^`v`>5SQ_d3~<@Nt:,N )2l``Of@.=@OZ)U@G OJG' @F;S2H$hTW})"RrIpwsnf Y{2րWk]wv>}F ˁBs!NZd`e y ~R@$#,HWj 0w"2Iy &@, /c`de/T-B? 2_?@=GABBAEEl1 HF8(` 1Ϝ``eddb FFX:7  Z| `17W0(+K͂yd;d&+;&!aJ* $Q?ư}1]IV"$@`1ҭǕq@0ed8v?h'HO,,>,ɀzgj 1| /8-@(y^H % ?zHxln% 0 3>~6vmێc=F@1OQB^y_Eo)6`2>w?pc88^XU},F CҋV’[ |!c*'f`Y#JI31z\WB"!lZff& Yo`L}=}g/Ij#!b_ c hlI VdxBE0@IrY#AZ|a3LLf-ږC#M @% - #w o00d U/z`Q @,:."#scnŸA oY>axMO].^k`xY8! yJ1s 2e;V0 Rʸ zͿy6>c;Aˏbx9aĄ; bƌP?SY3s1=P+0vwv ^,@?N3_Uz#C̓2 Wef4w&f8T9< y lͭ ?1@30'8ʄ!aN`cK6_ɰ3y/ T+U Ǟ11nd0d'Jc@1OBĥ{o08 ư+WK2xiٗ V:+ b!X'ؘY &!Y ! '"." 0d}°>R LJ@1Y`} ~VP 23y;q ,0-&T1023MBDCj ra5 ˥xxX3~aO*ß @3\x0!C 2seu+ '|̠$#7o ,`tpa,ʁll/ ߟ0|rX,e`LW ^ 1~ʐ}+A ~" - @;9~0a1" @zL?}z $4) rV~ Ȗ5÷ JL @fffbe`f?>C/̸31@ZvЁ$`& F`y l X R)t+ `/ Aez[ yRg02/ L rį82pc[xl>`$6FfH*7@U4~3šp 7v&A nf yye8ۏ bܢĖPk70bdDP ,V2383|A*O^d6g$gwY_[ -_^c0~E9Fh` 61QOA,l1@/^0">b-'6Ao߾aT-ၯ_^lX#hc5N#caaDVC@0 lK a:ii>lFOӿO<-18 ہx7A& hvXU!oP@|n .&-PL2@И&O? pmAzJ{IENDB`B48x48_Toggle_Log.pngPNG  IHDR00WgAMA7tEXtSoftwareAdobe ImageReadyqe<wIDATxb?P8=@C4=@C 70刲8U 1 )nfíij+y|gP/J1 za9Y yrܲ/598D퀲M14``bO1HcI4gЖa`f*$xj8J7X1=g~t20ȖU1+!3`a](!ͤ͐iý& à* T-NȍDw0q-LrYj^c+Ɨ ^!,\r9 |@%@ѷv^ao`͋/A=u025.b[MŌ'2w72ب1De1ܸ/ *_te+J偘 D7pK)15bw }e1^Go2|!"A'G>}ĠiACуA[* Z?0 @@sTANJ2ÿ g ÝW_9tM{)[=W1'7l"0?MDD{xZ4+b-(tG^Gf&% pN6R"|[s~^CjVf-v.dE&ìDyf#cn?`}9ן~2q0<~TIʼ-O_2|b0Ud0Q`g+t0󏿁/0?~X1?x| dFLo'0~awpED;i:)70?`f{V`,|zן `}헟 v1 ^}Y $"1/  ukŧ P) P<ۆu_QeX&ưᢾ $" p@73 L., ,@Gl~c/P \|o  b" bx Nw_f8rob 6^xp9 ğ jM|_7F o0,{+#m`HK p `oX*AXcPz?cADX7 ofdo?2Ġ(ưgǭ_ V"s_?le @7%=`Д{pkV0E ALIX lP/00+.Vpy,MP4"& %n2~Xp1[ /2p ~gص9û#7o0vWa @'Tzީ \ 7^yqymJ3, p0 ـp0p3) ’UeԐV\ ."A5, + k402?3`-(s< #xVyzHn('WyVwc$lgxxTWv @ A`SXW00z:8{F; &S1\ùG[vbP[D1lmq:IJ62)}A۞aY31?`rd$akgo ?eq=Å??õǀg?P ~j3: @ĴF$MdV&oz!}LcJ_W2zk x~dxp%ɫ_ӟ3:gPfmVa@ۜf0NַUe=r"Cg Ͼ0HnfcxG</ ׿ }c8wٿs^}K7[sw14AE%X<@z""̳,2y}`pY / jNw^0?}O[phSh} mۼT4DJؑdqVِgjRASAUA]O Oa8~O~ax>ó7eShH?:=:/B w)IQq[73v헿^zՏ P@}M =W]JȘtg-7;>0_>@ PG( i| r<҅bh94M:;1 r<kC@fXi+!53R4=@C 2ƁEZIENDB`B48x48_Trashcan_Full.pngPNG  IHDR00WgAMA7tEXtSoftwareAdobe ImageReadyqe<IDATxb?P0@ y >IFFF&$`cMo-a`fe`fdd`ϟ ~bÿߏ~USo!Ʊؒ;@18=rw3?Y}T8Yxd_/_~0|wû_`~'۫.x b=@y 4~,,ERr B "`+ ~gt_6첿 @u?fÃ^|+^puu_V" G\'h3J20sn>w~2|ϟ LU_20] %! )%O0\y71ka#8=@y X ?go/`$ң/ /7@h#0 7ÿ?d07x~^.)i um Aan篿3psfxy!t+@@dIQ99^* * f8r ów?fLJ.@?|}ǠtAI?Å' O 1e'@O<?g Ove u}s#F&g/3ܿr2ɺ$`t7ln H:q_C@Qaו }.0`3O ~ :R o[C`I ,EX89`Rb|ݻw ?~?ѿ@ς Xz?Û@adu c z \  n+]^S/1| >8MsrrCmb`Vfo߾e7+C8òCioAee$oPX22qv28b$6 S FdR`蝽7y3?!^;\Ÿ! jpUIc013Hq[1y+ ~2H 1H[2ׯ ߿'NC"o`̜b nq0yoȠ𗉉Λ7 ?$B/w(XޏP0*&bff3?l l/ʹSֻ7S_b0@∁$!C,rx.p>grhRuEuL#e9wNߩUD6Qh[LyίX8ȣX H,vA T |2VCM>.O։4[쁹Q97+^0^-+0,cŃk7{)j~(Җ6IUaP`b4XLEÙfi&j)_>c0UĘua$H@b<@/`fjq= B}: =̽ 0'',BA5%4ŗ@!x@b Jb܌?|`;g30ax3;`wz!Vn`[ae;E`0= )C̠Z=\R 1\aaeiFY) wafo 0ּ?r3` ""T 1?j`x&o>|_!A!XA^f,z?|Ux ?csJ;A|P{?I B, LH?| L6 7.e^~;IAP37~ l y^p`b` Xq"`h z WpDew#aFr3;y?>2zr_ gd6@r!B%TL1< AMw0J7\s0 n 9501~1|J` "` lnvH22Hɳofn`/ ؅^e1N_ef *&LR 3VB |iP vw>5!QM B`EX3[>@>MAT ~{jv30#31{ }w< '~K$PT&ɟ r<2a`2 *K*u&λ XOpߘ_5i$´uQbR'>!wϒVCĠOg^v@J!vk *M$P *06Ԁݫ/ 7 ղ+?@}epFp? ʰ ??ܿ4/{ID x͠:' u}Еw@ |̿dEy>~m`\'p0&W2 _`RdpZL@ +@`sPuJLV +z &By\01Gp;Hm k9PC6.hDTrHFp/@c,,HHQ~^>nvN'} ge`g q;((j9XF`F[u-%$@F&@ oi0_01b ̬L *xqQ`Bʒ`5Y$Y2_LhL@:l4 FË!^@ܡgw`2y=÷ ,@| u|| Ps=D39 |W@0kb 0&d^܄ġi g(B٣`|z&m*|FWh́tf*p"ϑ#2ƴf_ \z CW0ps9 "00 7Ã, ן|ex'O/~^~06A'3 +=av`ʋX1 xe6XPX|z ߤ@/FXt##Ys%npP첁6,\ o/G__Yv`ӀoP0J*N`Ϳ~ >a 2% lN y|ע'o[xMdPe&!P_f.?Yncg_ _}gxX3,0h.p337pӁIAn`- w~Ǐ?n 36'G;[!4̼ `-()|ee>`EX9àn&T:+8#/gx#{FN~.f6`LB߯oV(?-_.Go{3hF@  nf &!jxA=ИС'C_"+4iNC*.; @zgء Z80C1#@ h'GRbm CI٪FIENDB`B48x48_Undo.png] PNG  IHDR00WgAMA7tEXtSoftwareAdobe ImageReadyqe< IDATxb?###51? @ٳ h@n Fjyx}?6(ܺ /5?+<~!-=@LT |ϟ/߾l`33 g4~e\AasC@1Qd(޼*#Ps<7@1x_(_nϐw/ß? BN)#e 2@$ O %;w칸dfXawpsBIfÇ PgpoMəf/ h@b @ yS C~~hׯ34|ɐ\X`LX*.hEsafs0gx+.x $?v0`Hct(6# HӁ_ /dd@葏x 61g[N&& a%% \BBab?2,8a߽{ H@>|l1 30`:i\pxڵ 3Ξ% I@aܹ 2ZZ  bB#;d[yx0<~aݻwTU,@!x_'߻p&,E)0o H%l.Xa32|,)urB1@(%73bH6|a`ݠh[AzA4>G;8X ̼`sg L{Q`µk[y 0QM1>^/^xi== ŋ ?Bs: Jj &jam&lr@3gnhk?;z qy 0syuyUgxy`a?ABa!  : pY@zTXW Zаcc[pCXq1q.00psc`@)$/k_pr=r4 ߾5y-l1@s$˻V*جURb`␛ꭏRP d!  OÃ8=Ǟ=c㚼W桗J ̦mB_[ V w00\ IH|wMif A9`Y=؎۵sfPT I*F::6R80I13`=0c{߾ɩf뗱w@6$ P=ǀTKLUȱr;@<."//),(^cs]`m *DLp+llw>1;QWea X3 QQX7R"y0U DDr'/\~(#3042\8p=F ..|Z͛-ǯ^uǗ~IZYcЏYY0?~RA7 V{||QW%%?2l:X0107oz-e;7=OIHh0  (!@̝|y難\[ lР6_ UbTA:PHۜLL6D"0I\?zCYٕ*` s تLJLLltP2 *b%$t*c@ԅ υ.|y͇O"ր  @C :1pclA:L 9@VRR^UA! 4bDŽ[Ym`??i vbb2 ~I*u0ੂƒ `O`.,Re S @T,]jAGplY`o/dT0D+P@^ ,6,%04(=KJ/de]]p* ,@m+NIX}@ .^,G4ή@  oC`6S p.TV`p,| F==>  p '#pAPS8w7IIpF[&@C!@(@D`ߚ)@ l +54@C:c{p @C%~qp\701}a耆jj{A Abr:P?SZ<-@WIENDB`B48x48_View_Detailed.png PNG  IHDR00WgAMA7tEXtSoftwareAdobe ImageReadyqe< bIDATxb?P8=@C4=@p02&+303&և Y=  ܿ >.Z 12z/4J|IJz!A1I/ /MPjB/o}k/ ?(?ʇšbP,$9qj~&3ݲJjBf&onF#€HB &H|tXU,?b'3v+`v6s!BT'EӳJuEvrOT"ބIT&Nl d~a`8_h.FN?:t93Kh L ?30ptDr5@2hC=  $?{ Y lL 6g^JP| @(L"" An H4+v##"JF3@c?4 yvD}"FOW0x ,cXed1a`df!πa1R)@H$1|2@v)L_%G'>2o-B|a`bbD BX$\I `b,:4A U b Z1|y#T lllp5fJrAfC*< o<@a&!,GgA3 Z1s6?a:'9CAA6g\a4i8&& )!! I5QZ3`-H:_,t ϟ?v'<i@u#%iX凜fH)聏 _/F?f̙SPJP2/@a֬h?ZJBlf L `1.>N72ܝ/(O}cj0Jԃ2'@/w(cb"$/F 21# b 1pa`1*톖0vD/%D, Rz#y~y䤃\@)6e A`$BPfS PJ!pKB_%3,31fL ǣP/3T Fc'U _^eTS`P_<g@)QC+Fb Pc{| #dQ O2=!AM6gAm#5e@a<HXOBH]]B) M ,>A@FA3{ e$>>:oxȃW˗$TUj@~ŭ[w1J&Dށ BBBYZEc l6?6}e` T_p2iz ޘ-Ceeit-^r1 l: ?IF`s÷?f`fR=iذ("#mP򑕕k@9LZZ!""HF@eeeIC<@1ܬE?2 }`` Z b76K{^3efw ~- i2| AA7Fi(ЋQc Z A"! at$4(@5$# F6~@Gc8D4P gX@iTW F<#C ꑿw`3yQ`x@)HoFch?'ZLE]F@6#g@dxGwQQBPfVzNF $>$ Ҭ45&Agt`H>fب;ۍzhZG1Xc6;%9>0gJїo;I˧D=a=L L,ρJ=L <1@ yА@ yА@1-\IENDB`B48x48_Wizard.png PNG  IHDR00WgAMA7tEXtSoftwareAdobe ImageReadyqe< IIDATxb?P8=@C4=@gd(i)P 쾿 (45=`a ?Ë_/R1h &A]RjGjʸ J,V8S~;PT4 1: \mW }M@Z  )@m×?@{xj@ A0g'I2Ae~8# 2W3ܙ}Lǻo = ܞ@Ӂqw _9_H^g`z [h B "I ‰N n޽a`Ѝ:S_о_fzZ -{>텪)@g@B3^_0|{ U~Aj#BF 0: &l1vfs% C{@ǿ~f XwR  qvF*:2 Beޞ~R;? r4!9?j &Ơb 9DP#-<@0d:?o !$ b'f)v  aB F LNChJldDlk`Vs"xI69 O; ev`[0#`0 hnR hFs/@VRfCφsh200?u<+a'A< o6@iIhjx Xp7D9!Z<&B0(?B @0} }c+ÇwAH l07̤ t~u=CVK 3|E72|m>5׏Y!t$X,$݃<'ûg@q֔!A][a̙Bk/Wkȳg 0A? Ƈ[ L1(gd`"Q,m<& ]SV﹚6 0U== +gX0AIIa K/Ɩb7Aϟ?`'π ,3gD(/#\:{g Ba_>@mݼXuuu1203'ϛ?+33s #oR@@|~+5Cf.(sx[ރ/3|,pp%721ܺu!++!<,,oJN &kd+ly'lpMԼO>1Q"Z/, % k۟?/,&%o B"" O֭[1JN )@Yx X(@ijBhc/$$Tx @`„ MMM 5SLΞJ NF 9Z@@TVVǏ``nVVV֔o@Dbb>>zIIn&&&0T2ܾ}!###=JB<<P#k @HX8A$LNy3f\U2(] kłdc̝; PY@11 .D75ş Xt 0@4XP#+ Xr PlK`hLML@@W@C~ h{  #TLIENDB`B48x48_WWW.pngPNG  IHDR00WgAMA7tEXtSoftwareAdobe ImageReadyqe<lIDATxb?P8=@,p02oV?u1fˠ̤.4/_?_1}M=>v[J<@ <} 3p h(*2HJ2K1pr t?/0xɓO Ǘ?n-GT'y6bP%eg %ʠ, #3P$0Кc`7.~pp?obU@/N <9J6^"P=^]c=AUpf1 `π|?dbƽo eضOcuݶ @߁` =eI?͒BA/4?`2|d￿dd`b/'Ȋ_@~3 Yf_Xb/ G^dص뿟O`x1e@.ova9"N1 4r  &F&~.!3p ?~}g~~a7@zafbK^ߘ\xȰ`o94bDL\1̚CKO*y+˧qsk:C-_ 1b$ο,`A`l|#Xb"@pcD4&nbxr*g@%y p{ lg q0H2^`pP`l, "2 }dY!On3_D;0Xuw V :1uË]@y  s?($d- I`;0A[AGCA_ fFV++71`?'w  fseJ`3L-2v^eafpt'Q`}W`fddT`fZ).6~` J2q3/?~?Q߁ILCe&7Ȇ߻2uP-TN}.",WMV2 gggZ ₦ | jp}pm_&@o?8dsׯ <" F KwU0:22Hd( ,Se]+=U ?|& >QS..i`Fw_(i<|O Zr RL@Gs2 ûM ?~_? ~1ڋ  ܆ <@a 4t(y0;ADa ރ L> _|(Tgx>ß_>|piۏcARTARD۷o o=!q_`7аv2L^~[PW\ŐX-×kA ?B/mq &6K2F0he0W^A h(7#0ܻ{ = Ljh-@f Lw~d.õ/<{h;0dB.\;/8*@< dɫ3}hw~1eVPXBk=&Hh L.@ }d`6{Wn2AXH=@͎KO `xw> ga-أ'zӇ ^cPVgr@\(%j20(j92:3r~ *e t(0aUa|z70ɈX3lW/ lP;lp/Ѐ?ELL@À?>0i;39?+s1|?Bs0D@!yI]LNkz>o{Nx=1*u@au]`Ȱ}C_4 ,C| lZ*@XAiM ,1p1Ikkp;W22{} &~ \@'Z'fa8|l/8ů?prQi# q)]xyh`1w*: d0op2%`W``R`lɰjy"Т BB 으>VBx,l ~``6Yam_VY6^`K+YpP 6 6P_z8Oy gc  V JjQ _>=`fVex$=*0O 2 F#X؀B(-<fvgOw18Ơm-̠oR (f@4Y 0K ys20?` q0X;w0j2Xmex y01h(px1A X00@ & H2mRje @ gi.+ 8 fs`Ap`^͠j !$ {A}x@ߵy?`Th*$.#$z:*_T*a0ϯ 2. **_XlydD%xOM_~CBJB?Q@Aq** zb#)Fz _Xp 3h0p)OAGfb 1g?2UunxUXKA%0;) >(ԁn./ T`&' #i toN_eg/3X  @]~Rk;W0( 030gd&X: 3#jN yP r/_p3b`ed|` ( AY`ipr3ڝpbƿ :;OB_=~ Ù[{c;pbM An` ʬ(&pg6+4;`g XgP6-v'%$``d#{=[π߃b b`^mp ^ ((Q9-.8rBL2C$CiP(I0H3d|ƢBZ P:vu^`7kĄ< Nw <:ܡ۵V#``b';~>('<ـ2 z)C@ I{=`_Ǡ#kV#̠g0PcQ=çX6lgx֡Yp+ G67 g8t6) rzqA,C+vAR2 FrXaIgxb!؞pX-wV238ؤ@m@O0@}b`~>y՜0x2/ |lQgP0 M +f`Pl@E#T]#AO #D!DbX<0>`>Н$* s|iOo^2Cy- 7á m(%PlHyPyrJӟ.?#X}W]ew44KeduFJ  0Hp3|Hv(&H?)nРVbay \y=Ú2]uo`&`- p -;.OԢyf('`[h!/d/H)i`0A=0P1 bba {Y|͚@c)PgPFH']H)a9 ^ L_)#`?jI 3r %Pn E}!h4PP^Ryd~+CR"(sCC ˆS&h2>W ^qCcawn:J`p QD<1# FN]f3/FknQ=%U5yV9 `IALK#` ?ÇL O`x,a}o C++qL|33{ r "B\B|̠@O_` y=m4TZEC4c" P JfA'nhcFv $0Bκ (}}P4C3>3R{?3? d(3IENDB`B48x48_XMag.pngPNG  IHDR00WgAMA7tEXtSoftwareAdobe ImageReadyqe<UIDATxb?P0@ y 2(Mu`aa1egg/>|p˗/~'Z~?j;9򀟟=S27fab`aff7çO^xp7ou֙/|߿ <+ `a`'Û?~o301sp0p53c۷o[^|hWjD^^^s\\\lmmxp_^}d~30A5OmU!6C2]'~z27BCCt5~ɰ"á| <| Z L $ /~>é+{ gEO_3̞=ܹsShsJ<r;@􀻻SSS>0?/?9+$+ddU20p- VB e8{L`Fo*{F'@n :^z 721?`j`r$331!@ L]7zd5ï m޽[ ,U$'O@Vwy]m YdaWgd0sؿNt`T/&#Ű>NHnn|`f d@pvvQSS33ڳ| * `ǀ@9/?~7``g`d.p5ccsss `rx 0<ʚkgg(,p5/ovvF!`pCc'~?9̔|fx!(28=aZ+((hksÉ RR ?I'4Y';åodttti h$zˀ@(5ɇCHgn8 B yXbђT ,@$^e 4dT̕؁/ ܼLD%I!a7Z@eĀIJ @y@H@xh0~cfcd`Zv\~@ed`SMف42gUcx7????RFx Pe) 1&FHy+Q=63#&B@13@ ?Ó_jd̤Tl`T 97$#+k 9Լ`e$PY 1i? *韓T Z&8ʂ2#< adL} 3 g`3`&@(0żPKZ@ @ft@i_߀ _A<ڜ @(k3 3X4 mH1ً{ \ Ǐ5h/) v?|" md!70iqB0φʁ 6'4BA}*/ãǏR`!e @(!` g8Pe!Lu4F;4BcT@[O^|c$dr (=H?% ]~p3 3 ,iTg@M: oXL䑯@sn }ڵk?%]`s)PgR+2B`T~[9sO ?;,L@|Pb; ##p1w:؇c7R=@荧[ MM V`)+88-<ϼ LF( !P .[ 'ScǏ}%O۷dz/~ ˯K̨ˆƇfH3 Ga`AHXȑ# ?|x @koBK!9[իW[(l `xO Hx1ʈ|ù[^fgPdHHLdxۆB=de`x =@: am ?' >iFn1.G 8So@g~S ϯ6xàl~2TTa2bx R| #r X|bn2#z b O6/_x[6ɹ=` !!!+ LĽ~o_z sw%-_?_J~{jͳ{ "N20?,x8j$ "Z^޼yC_Qz yoSh%*?KW7z]URXC> 3h!E0o(4ɜ|Ow6WD:9}X^(怊*@K/hXȚl0ʊ_}2!1~`Y~w@O{= H@JVuFA=GygN`ӳ1lW!1?-`0WNx zfHG`Xrş: > [Pe`Pk2?xN [<@9d PO>X[9>5v4ABh<&' 'ÓV3$&wuPd =Ow>=w+t|MsKo0< {@ %>C'^s13|~ٻ idO5#@ycP~҆w>d8 /X@pO承 OӼ5×yɰ{@""A;`B/Ud}+Ï>Xl%_m L?8` 'V,[Z~Lqql /Yx Yr*'w{Ug$~/hyEwmGOX>|Xl%yl_;;;|ͷBkM~D@ Cab>!,X"$~ U48mqhrY1222e"u1ᶻaH_R""BHa0ˆ1LUsNׂ&r5iEoŲFX2 J)*E(E@yB|+X(@H icF3B&7ODX*apٳRE*"bֈ@eL'HI(LbDѽ 4FFGp)Ya^Z̝IT.UM(6\**UY\"PErG Ƕ!"uMKD)80` U]C"a0L_BSk߲? bMH<"9Vtz^qʩEI>nkxmHb,5V^;ľz;2nT [bQLjl^(%l߾E?,Exw<mO D >y8Hihٶ ,f ,[cܳSlA_P&녚"41ފ\kбm{0sL`i~jRvkO AFh`66nq`݉#l XpPJUR / Is8W[R0<|3fX݂/ϛ{v'af:dRZge/ąMXvr1fXb9UF8˲RZrx_/뮙-d\.(Oo|m"޺McEӧ#8QS%3p縲!kz>WX|`YRE& >}V" ڵgϚ8U.TD깭iqg3"Ao W_}Uj94t w}kO,zjկ<ѣxd~ C]A l%GQ6ņ.! "x˖h(J=aR Bj݋0,5I׍3òl Ao4@_sc Rq r~>? UjQ9 (EU7ioC͔Q/H5KI>3"=o"BD*/Fq,:ֻL>mTplTZ[`ޕp=Җe |YgQWgLy-z?w;NJPY5D9gqC܄)KKٳOcW>pfgʫ#G3܅_sWϛܓN: mٶsJSSTXB[^) iգ#m,oϞr|jzG3ϝ>seM仵-.D[wԀTj ð4xtGw ?9sqXuiSa,o3ew= GFpm7]:YtF,XKX4  4ZJ bR` H"BRd(PTtt`{Ӛ约cYgб1)yٶ [om;g}T[q=L98 ǥLɸmk[kQJ9Z+[DdAHvrU-m1"H` A`bTbK `׻u? ϝm5]~FGз7\yMۧ:zU_A23+ìٰ!$,"T"VHXiZ)b۶f<=r<SNgo?":?RD@IENDB`B48x48_FontItalic.png PNG  IHDR00WbKGD 5IDAThYi{z`d=6 VZ˘hr|H%RVb%x4ߒ/FV4cLJ "dϙ=fˇ>{fvvVs]~;o=r?`.0]~qWKꁇæ Gߑ07R?{6:P,HΉw.r@Em]dPPJm{ SweA1@a fr@o-o-!DwǏcKhb F$A8[#'6$ȼ)zر:ԉ܂)^^FDT iLQ*ƞ{ƚbZ".Oy񪃉8qj9"Oyex-$֮Yby1 to,^z$ Q)'Rx?axhgKqH\T"JyVkLf;w"w'NtA qa7[{@y/#}:f"<9$&:0lX:RhL+r\8IЄy8oQ.uh_)?.f_& uk=/fAoLӬAa4E)Z*EJ'f2 λ{V2Yea̙jǑfKzPL eC ZF^ MMhko(fdM=ƨeYHjtd*Py&L76]T mh؅|A(ca``0ƬWR}V{MNPfX>D x琰8l8v  3 DT*+/\ D\2FQxx`ohnˋ:ǽdXR`Yk E1")AgLo#A΄5 m8s_5J~bL޴U"0}ۋ0 s:`IuWeF+l OFccc HR0 y]G8~>8 ÀRz]adt"Q!$=1jٶ0뮇 uh~Mt^Lе572IS"D"?udv#&"A'BUB2ĉ'3::d#B0> |>tOQ8p08v8<al,X8rUM|P 7os8zh\%3j߽ѱqyg71̘>s.ŋ*lR>tw@DyB>V*Oa(pW>DhGhlhUW@aO!34]^EM}P" pb(Rgr (o+@(5 >iGi~u12ETOEٶ5kPJϟ#)쯘Y*ϫtUt"uER8aW3Tؾm %%)U̖Hw9@/u?WPևċ[R peW^unӆaf3ٛ͟犈ֆw^7\}ͪќ-p?;vEK.X05 r]*UD Zk 9z>t=2/K4guVu/Y^_g=E =\7IsJSfiӧyv?g8tŪ/L^Qwηo쌦Ƶ-3g^4cs ðz)1QUJhAo\%r'??x`fOoy~ς ol6F\Ic&Ɔ#]'o(~s5VœO@ `1b`@ C DU@L L R.@)rȁ"G9w /]O<㭖Ӱp~ gFF$_Po/֭izvS\kAeH%dҲLSZ TBke*" " h)<ҋx]qEauf:v\.XRk"n}ngWH&u{ӧT3jphD*7^P7\3+Y J(P3D ED 0HҊRRVlKp]y9m|ťKcbi>ۿ9\fC2IENDB`B48x48_FontStrikeout.png< PNG  IHDR00WbKGD IDAThY{dD EښV1LӴ66)PJi,* ,,wܙs<.`/̝93ssAԯlX /!y<`?lX_R@'qxOn{/Yi Y8Hx]UZOʎqtwuὃI;/mXiͯ%~ذn|֚tD 0CcN̞`E#}2CkD""[_' kρZukH!۶H@k3C Aa::sH7DU5G+綐zܰn|_rAqER,{J0OE )_8>o\(H¢Y4P0<_=&mr@DaZaYPD\TȘǜ(p ĀA]I#9Ĕ+\`h$.eM\ 2x*Bͩ@`D\13" ) lЗ ">]9c>8Ӷ\l ](0"'MQğ[`8_xg֦X`Вϳ@(% A8ɵF C@^yeN:-<빀 c0֋Q2AB Ku)4Mj @@[[[h+xq/A.8LD1 ܇܈ ̌'NZ9cD";bE.!n)r4 + RZW_C"ʕq뢽q?0 TbGFǁ$Iy睸yWbfA0%xAi<>s@ |M$*+0c Wcll,|ihiii|(Pثm2%X4], ؀x<G;¶bگ x6 SyGmja0 5:::`Y Ģ%HTishkii.t<2r&fpp$hCmp7"iHR!޽p 7 Y]]a ϧ#3lpƃJ@DطzVb9P=<zdaW|7DZsG3"s_,&2@(V60TnD#Q,vaN .=Yنt ;F8/L{;\tu91MnE4J($%/Î=;;ozzø(7̈qGô>xZd2VR)%E}~|l8{{~ X;c4D,Y30uԢ&"| z{zADh݊0cܹp\MM"BD,'De"o_e Ɣ)SJ pD7z{!"={.DRX'`[X.t".^X&cު8Ji7.\h*584)ύH wuX˶PSE| X{N;," ) J)vAiڀ3AAU뤝-Q"k4rxEr=. .ΎX28nwղ PYMF`T=kBb {R iugMC}O1N7sLWDȥ}o_xso'g̞=5#r] .tD&zδ֒m9z#?3iŪ;\1iM7.YTn9_~9*Zʮ\e`uM̙38AԘ=q\5idM '+DGȷyuՕk'/0hfS.|oSh)uW)CVs*eq}qkp``翷Ϟ=-kjєɠhMueȱ>|}ͪhĜE@5 `1b`@ C D@L L R.@)rȁ"G9w`زǞmk0gU44<2 Vft2\3+Y J(*%D J+JJ)ZiFXJ,xE`awwE@cevgvgχ9vBR7޿贈/ x7mAX ee-KY'z <(|3n KP3y22P,$D`=]!fȑJq9>zn}i-ۇW(͛??رc{֚L?"\C! a@#'>OvF""_zDȽYhEj7T\%DZH@p3;! @>pws7DcƢ̊3۶zݼi]@…NJE\( Rq"@Qޕ%U'qJ͝7!G6onfɆm  15"PVIODdm&4"mCF"uN2\]] `V$.M(0\ *Yx 9 (0*ẅ&Dd&%8t6eHwϸ.?O[ ](~0"O6%"@Zu] t7׮^ό~I%ya ! *یgbߞU@R> Rji ] KHTb@X`&Vb1455(OɭHjk6PI_kjj96, m%?@t|0"BIP cG]kmv?AFS6 ԇԈg|/Bk 朸8v慎Rʷ P;U QYHQj \l>8V\uCIx~<0ÍBR[AKs ֬Yߴ@G3_ B\uϜG@u;/a0M[WF* o&aXv@/l( DE}ض{:;1udbxf'8NQ^5k QGY$O׃uR`my "B9|chjl=e% p17MuuuD"chofҥ7@eYWDxsDpA'ى/ّjАn1/s04x-TTT`3&H$Vt ^u bBQs]:* T({՟zt\#!Nc׮H"b1iҤAkk+ {L&6|m[ap=+`{ĝRi"dz 8n_s{DB[Džjmxuoi۶p]_yˣh=͟;}E#QFFO~4Ғq9y#{>~tgdqJ]үݰ(Vfm;o'"]f_ RV "~OnKWW=ڥe+Wdo"&(;y}u\EꪪM0 *q>a[*0[jq3vwgw{Gg{ݽɿ>0s,"vScZJ VO|xZ:.'bE `a=1X`,C aр,Vha(1)0H"xS \E*RU^|;+`S7٧ vY< 3zLkUk]ޮzjջ\UB[Eu`xA^L2o?朓dBgΜ3}w~|K &@dXF(p | qr{uڌ< ŨQe0`@>AN5a؏A`9+z@K[,++_bmP8*v%6%6%oߞ|ZJK:Hx^j# Ð3o7I$%@[T-Q9Ʀ46G%*-A%@켩%*k}"7M0\qL6e!+++YL8 !8 k(AuAb5a6!޶~ݻvmn,YK/La D@oՄB{:9xPgeb_Pywr\ ֋/dggr\s5ƃmB8"q@;@ڱ=wp)@vv.#'R2c(%LFS hnn< p! \F#BM'V#e97JEnv{qbN%apa=`{;p@YVo(}G}V;?p`/?{vnWaԘ+0&f/vTwq^ia-Ym΢vdds|Ԓ1ʗ QXb[̎W`@YYWNq9A勊z^i!-CG9N%$5 SQ<o+T̙36v-xɒd=xZ/Kp!?ٶ$ h4m7-,4hɅWS;x vD`7GkM $++#,v%f|+%$h8@1c VV ˨QeaW\.7L}hǎԴLi.W_ iQR)P4Dp{ij:XdsA 8V-%yw޴,u=5}IO3wW,1Sr7J]RUsot;s-mT7;eiWZv~i {I7plL/ xOkR¸kef;H]ty;/(?L.c:"G`=aDu fD;;@UHr'î^Kcb3 4x<1`ũ9_De-xo{4iY *wgz4#eĸ$4dm&ӊBRi :9xf;dT8zw[%ڴ*LEJA((]+-|k=T\9 bO4,3V29{OǙN YWJU쐭!h}of]_A?߻#[בQ/u2+іθ89rO;4ߍݻ@o+P>fXn cU'ة#{طkC0nm XЃeüiw8e7VX]6HI{oӀ։6t=- !;D{g=S ~ v'LTŹ/]N/Ǧ 1J:Oo#xVZ ʢ+_^x`}(.s[- fW ,~o'_dz*2L2RMζnʲ'ط.уN &i…d9pTO tS\x6NdX'ˁG_7mc+)*Lq[)BABmB%" j)Fqvle5-̸+"~n&bhCSp{xӺpn_uty|ov%؉šw?yGoHꡒ:=acGr`/<͋/Cm?ou ߹ %V0 3a7XhiZcx[(#g;ղϲqg;p受lmQ<[g3)3t9sl}{q >?/@ Zɹ;[FFF2 rr˰>5pIg|i> pzIENDB`B48x48_LockWorkspace.pngNPNG  IHDR00WIDAThݚ{p?Ar*!7L"6PU Vl;ap:3:Q&tC-)J E$5<_ݛ{wnb8ݿqo?;s*$JUUս~   *"o(e@LƋkN4yPeMMMMSR֬YS)"c4JFeC'Į$,vnq?3n8ˁN‘hb#}TUUݢ[@^_4dIyh "`8Dc:mDckDQ= uG/h66ڱc9֭[`0XLПΝ]bxTeXAU5F`~ڂ=tLP)++Y2oN=x^0<(m hnjĘʥ1lm8 3~ /0[x<꧂ohzDQTϊe ]^4*T#y(ѳ)C@=;3!vRQWÒ6QKx|b.{^U/ P5lGࡣ#I<;E3jr}4/ 2h䨺ܜAß;_O o3d<>?{L^n+x$7` ?| hdA.+0Ȕm.\g㴶w 4<o}'׹1mKuGMJ'<) &_V)7;:rIS3{G| ?mbi/ N["/7+^?㙿vg ?[o65{岯P-5ͿKglo8Ǘw!G17'W׳܃/;3n3C Eq!1STGx z{æWÑF8A?E" ^ZnU(j MFkt,:.FW8c1L&ӎ9ƌaX: rbl1 {{{;}#tp8_\8"Ey.,X%%Gщ1-9ҀKl.oo/O$&'=JvMޞxǥ{=Vs\x ‰N柜>ucKz=s/ol|ϝ?y ^d]ps~:;/;]7|WpQoH!ɻVsnYs}ҽ~4] =>=:`;cܱ'?e~!ańD#G&}'/?^xI֓?+\wx20;5\ӯ_etWf^Qs-mw3+?~O~T/ cHRMz&u0`:pQ<bKGDAIDATh 0B$swc]5)ovIENDB`B57x21_3BlackDots.png2PNG  IHDR9vFIDATXؽ 02ǣH (@pKc$\9@6'8$=n@,N# ّ$]8##<P̍́fpafӁ,L;(RqIу#xNt'6fgIgޢ# ;٭$Zsf`4N4W&2Dl3֨sdҴ3+6_BiY˝]`Y @>WӚ߸;8IU5IENDB`KeePass/KeePass.ico0000664000000000000000000017613113062014574013153 0ustar rootroot (00 ~h& M!@@ (B9o00 %a     9 h( @  "" "$DDB" "4DDDDC"DDDDDDDD $DDDDDDDDBDAD $DADB4DDDDDDDDDDC DDAADD #DDAADD2 $DDDDDDDDDDDDB $DDAADDB4DDAADDC DDDDDDDDDDDDDD DDDADDD DDDADDD DDDDDDDDDDDDDD 4DDDADDADDDC $DDDADDADDDB $DDDADDADDDB#DDDADDADDD2DDDADDADDD 4DDADDADDC $DDADDDDBDDDDDD $DDADDBDDDDDDDD "4DDDDC""#DD2" ""   ??( DD 0DDDD3333@0DDD34C3D DAD@D3333D@DD@DADDD@DADDD DA4CDD1D@0DADDD 0(0`  (  8 ( @ $$$H(8( (((@( 0((8((,,,0,,@0(000800@00H00444P8(@80H80888P80h8(@88H@8P@8H@@P@@XH@HHHxH8LHHLLLxP@XPPP@xPHX@pXPXHxXPXH\\\`P`H`Xp```XhXhXxh`h`h`xhhxphpHpppphp`pPxpppXtttxpx`xXxPxpxxxhx`xXxh||Ȁ`X|xpȀh|x`xxȈphȈxȐxpȐxȘ蘀蠀Ƞ蠈ؠ訐بȨĬȰȸļȸȼF++F""F0@JJ<0FlM~D\({(zkgggaaaaq{MqqkkkgggaaaYUPkDvttqqkkkgggaaaYUPPku zxxvttqqkkkgggaaaYUPPPz zzzxxvttqqkkkgggaaaYUPPEqzzzxxvttqqkkkgggaaaYUPPEkufRzzzxxvttqqkkkgggaaaYUPPEqDl!PPEFUPPP{L-#YUPPk(yrrrooiihetvtt^^XTTOOOKIaYUPP{9xvtaaYUPk"Z =xxvaaaYUPD4Hzxx $gaaaYU~FcBBBB???==izzx955555331:ggaaaYqF+" ?zzzgggaaaa+8 ?zzkgggaaa0L`AAAA>;;;;mz2222////,7kkgggaa<WA***)''''''''########/kkkgggaDW%qkkkgggDL%qqkkkgg< 8}ssspppjjjjdddd]]]]SSSNVtqqkkkg0+" &xvttqqkkk+F )!xxvttqqkzF )!zxxvttqqb )!zzxxvttqM  zzzxxvt"%|zzzxxv.CC66zzzx(F{pmzzzF0 nc *zfb)[nnQ'|Mf pw [G ~_DC[}bR.-lbZ\F"8L\\L8"FF++F??( @      (,04 ,$ 0$ ($$0($4($8($0((,,,0,,00,40,80,000<0,400422840P4(444<44@84888D84P80@88X<0D<8<<<X@4pD4pH8PHDtL<L8LLLXLHtL@lPDP<P<\PLtPDP@T<xTHTDxXLXHXLXL\Hx\P\Lx\T\P`P`Lx`X`Tbbbxd\dddpd`dXxd`h\hhhhXl`xlhlX|lhldpdpdtLtttthxPxpxtxxxxTxtxxxl|t|X||||x\txdhlptx|윀위전절줌쨐谜ฬĴȸȼ̼V)  )VV,33( Ql'mg$e/{)d{xvsrnnkk[{xvsrnnkbf|){xvsrnnkb_|)`h{xvsrnnkb_[eb_QkbfQ)aSSNNJKZA>>:5?nkb$t%nnkkgQ^IIGBBDW84421;rnnkV& 0srnn ) # +vsrn, 6p]]\XUUSSNJHECALxvsr}36{xvs3 &jTPPMMIIGBB@@==F{xv. &7!-{x )Q7-{Qz<0m/R 9'O~cUiV&"wo`q.TT*ydl u& Y" T qh&")`/zt)`O&66&QQ&  &Q??(      (%$)&%C()((;("0(&*));*$0*(C*";,&<-)///0//>>g?0]?5T@9hA4NA=BBBCCCDDDEEE^E=^H@`IA`LEkTLmYQg]hhhiiijZk]kkkl[lllnnnn_oooqqqrrrsmupuevqwaxQ{j|v~r~j[|}|admvߤ禍ѯ»ƶʽ˽˾̾G HC%cvrps`"D4U{e^[YSXmL5AWygda^[YSNdJD&o Nn$Fhwr/!BMSX`Hzu:76KR*)-YSs}z;98@E.+0[Yp~}1 ^[q~Z uroj ?a^vDkbxurlOdecG,| Izu<fg{'=]_QoyTC2\tVPiwW3>,kh(AD##FPNG  IHDR\rf IDATxw|8;NlȞdA  )=j-mZ RZ?J %ve%@ !=^c>?uw;Iɶ^}:}ޟ|GgH8j:@?_]6u>n(>T l65QcIʵt ^@ϺN9JGsew@(wf9#O(8 T֠8R8ܫ0 L&y9({ _riPK_`,0 eM"`!ʳG|5ʀiI4<|s*=-5`gnqȼ@8"'O.ޑ=p=?vעtV < T{X_-QXOh;nO#Gi8{\)AY`XQFdZ&7.큣f[ \Vw%%f]ѓ.]бCGڶmGvhۮm۶@qq1n@e" P[ˑ#G8x@}{~NmJ dl@yH%JBw04Ƕ$ЧO_ ̠AY^N=(//sR$I9B$C$lhiP !ؽ{[lfۖlڼ5kVjJ6nXO$bKξFα-4 30xƏuk@7g?͞=Yfj{QZ4qZ8\.'xW_}5gy^>́?vC_E">Cz1p8R+ V1g(CxΧ׺ukzwa(vƜ>SO>FeeEؖ(jfډ:(CNAJKKkɍ?uf؍LW{ ;vd}Z(ӗ5+5Gpʃ6"[5A_`(Ăs}oS䒱*P#=̓4(Dlo+m/" " R):F" I$Wݧ.KK[G•Ǝ/ك_}YyW]cu)rXOסL\@9-W=[= <epY.GD‚`XrDC/x4SD kH 1aKx{%|> WR.F_-YyWe )rH+:@c98Qe7/~7~$4.y($F q0#6>~DO"?O/h\bY_+ 䞻"+*P/F%w @ʠ'+3v\\|%ꫜq}e! AMZPU#H<_(j2 dLe A9=mdhWS7 ٍ&KiFAecePSx p5/,5??￟x/Gkda t tf{0BULυ+Y?@~Ag<={ bDn(ˬ0[{ :!5gygPDPw72(衸s ǵ\Šo,cV7*CeX䤮ΝKNR3 DT׊wك_`Gev *kמ/|)uKBlcm':;(//Gynnw?ԯD r.}A="TU ]x{?*ÉSN7%QZZ-oPXݺucy=:m\ýl ~+qHڵqS^UIf9W\~۶nI!݊HmdOhYh}IW/V&1}Dn;gu`AaaN:3kօ,Koߪ1MPi6]rɥ̙3/D@zȂxZ ٶm7|ǖ-ټa-[Iejk>J P\X#[ӧ z@YޏҲr<_ ە/?I+Q\ѡH'jAn鏘%SGcVd.D'$n]2Y~!Nnְ%|C>M} !~P"|$  Iл Ɵ0c&3pq}Jm=Lp _.,TA;~vpp>ǜ9sKuOnT.>t7^{W?UpI.$I"^@Acs0e,[e]Kb7 ~^z~qӵOBʾ(ӌ2Q(VAASLje T_L@ /=ŧ-QSۉi|>?Hc0ٌ*úsӧ̋p?EoqRkeR0e)(aHL2),,dt>R{}{_qO!zoBABBk[Irzxsэ}+~=G? ǖ)*;`hؒsgRUUrRk 0ؓiFf+P2qdRRR…3n8]S)=b.&r }{yb<# AVW9s-Ϗu޵sOiӶc~J@n^:,7T, =C訕 DȅpLd:t୷fذa'_QԳGVs<&hC#yΏߒ_PS-Nm<Sy@Zr9<뫔ZD m4QV֭y뭷1be8Z+D q%YHE"adYfúoxTڃ9w0B|$݉Сcg&t w^(L[QO27x'ꊟ pDP9b"7oټ~}_/Py.I;`8?ѭG%Ѿ$P귁_- 9-g2JL21lDDєYp!'odC qe3~6R>q 0hLNBi>h]s*ߨt)c1y](26 % |>,X@1CӾ}pJZcwҞի/][0 rU5= nvn&: G/TUV4R׶,Gjx^~LsƄ?zjdiH7^"ncaD">_jj8*L)*wo7ݷ_eXXr曮"aA&/!,K0"gGE(mb&؟hlݺo׬0W1/YY1'2o޼y)Gkg9=wE'e_OJ>)gG?!Ca:9aC%IbɧOa~(q$9Jʦ p=zwޡ8ml=~ʿY?TB2È g {)mN2+]nSNWqaSuUl-0exxͷLOˏ-Sپ߷RaUBA ?!gG/@еv jl gI{LZ~ @v_{zG9Kofnw7 Yn9?/ӥ)z;莎;ӥoaeXU8(OM[oM/vyy=ra,ڣ?z3E]5 <4$?y!ݳ+6T*uFYu3h@|?j(>Syi !%\tԜK ?@IrѾCgKVm)nUBq6a*+Sq ۷!A=^~;fLW_;=3`: yDV\n Ԫf/+2IfKM/ڡk>ȴr~dqz}r֌710pqt-+4^PwlfYxK?G\$E__RT&GeP/}1JT'd"QްtWs&~Gԃ jlҽW+/K>\QI1mq% 82%h횥ڳIIlt8xnelOy׸*虧7k ޵*PBgyJ8GGkWw$I=^:u57IKc>:_'Kr]bpd>Zcw5J>G9?H4¼4p>N9q$/M~fGe[(Sy=S12ix2PHDdpqOR$F_DYqx=>V.YdKb÷_r'L6~BuWF/GfxH.fΜm.ix2AN3}_,x>$?9ϾτNEruڮ| ~5@f4V#6CiWJ>Cs  5.kU~ǰf 6N%4ȍKE3`*𮙄[fUtU3<vL8G3!6n79?ĥr> Da}Nw" yjSaѻLP05Q[ŔRQa4u5L)Az!&M ~F[2+|$z__`?%IlW4\.<}a3l s0L^|R}t#V["ӳKˌe8KM4{_so*ehռ[6m)Crv2|avKcК~H0Pq\t\^_\,.tq|R۪ `֙'KӝIhvrN7p\w@ `/GGpe\.|x&0`8{\-)_|_GdVnVޝk&t&Y6{ 19fħG=];xmYyq{ۜWoP?{B3(/v[Mv[=oS]Ƭk9fyFyhOV;wEEE1/_ygoYvn%F=l۾>C?x|5 }-s(\*qTq# 02'G qWHw'OO᰽?| ٥O[MhA X KrmWrW~ R:ĄiI ITG;޸ 3z 4r}z*&" Aa+71ph.f̺=`r=|+?vk}#~Zp=0`ߨ8嵃avm1|VLuM /q+umvhvG?[W߉km+`ǖUڱ6Gٰ=1ѯν={zbԈ L6dJWez2?yᳰ)v^ޏ3gnG?θ]{rY7gj+wG|>BNKWˍ?j@ߒs/ȹ6g-^[~ լWһ}v? k~‚ JTg}}0V ވz@gLg[y@7,d[¿{i*4%Iʐ= @ރ$:ܿCѰuۃT= H?n6^:ꉨ  ѣfc~P K>5\nk~r{?e6/`7a7"u Ģ.ΥKn鉨H\o?" $a>dA ;tf- ~ 9mtHR(X˚5mOb@rVETW]8 HBGZj峯0?(+~şgD~gκ<2|<!!d|-~_@:).n.z$я~LVچ'?Z3ܱT L~A_8B!QT};l `8)Z**ny^a/-@;,Gu\{v% ~!`o^8A彏Si+_#:vK7SIic˜c[5]:z#gmREHާ:3?" Ba `˦uz}LtZ ە/ѧ^F$Ş7~!aTSCB@ײL<~ QVN.0磌Jؗ ~ n/b+#`ㆵjy(I#Lj US՛NpE߁2qORrGܹ3g:ƪ>_֮!PAƶh;HؚBزlhuԢde~)@{ IDAT3رTgMh2)Y`*p.& Ϟ}^oCt~lۺXePIhSz2ڻkB]%xgͺHW'f& L I$.|vw= l{PUUa>R{-ԵzKښJ[g H"ZGuVR92 i1L=BHfge|\.z_[ ˺G!‘a]S*Pޫ/]*t HV?HT眣<3 ?(~TUU鮇tr=wWԪkm sVUǠ4G7N1KOLOiF Ig=Hë?;/Tn >,\SS|`0GdLyf_Ek2|Fs;v{hؑ~=ѣ$^gM /eUݺT~!;nI$~.]1d(lHiOh?@m?@ ˢk>2- ~!êE0Xk{dD N9Z43qF-Na?{/! RW$鲽Κf 5$I/5F jTNy;G lk9W޺@ D_ rg_:Gmܡ1J0 ={ӽ9:NSPfiJ[U, T-;BGN|H f w:ԆFCaY-h[)IHM~!Vfwt91#`҉wSws'͋UIog!X X%!HR?mOX7Ǎoj23v&L$??_7`ˆ_@ְHxjo}WHq[j/`HÝu!|QM8ӤW@+/b¬@YY#`Ձnc`$<@FGt7^È$C&4C Ie12lVA?Q ȏX0hNѣ㒥?M~/`ECzK$ 5) L ?cN~\tCeȐ:  ng_Gg}钔vrv틎L?@QQ+245$کWƩ :GhmBgrY25`Gejd q% Mэ"1bD!LBWM ~=lK~ D^sǾL:44@ ?475cHI 67k_tfo( ;ÀDi,NjZy#`!n-ذ}8@G^^nxV{%#ii_p˧Aa!`M~,C̾eU&B(?G4Oq 08IHJPn4F  j7YS+5 kRm h^ ?@$:_S3fV2Ĕ/z/F6!q (+뙺BUʫB=EIai0ܴ(o>j$8וa2ď}$ַHn{?A& A2EӔu"VRu<(o{5_P7~!Kt^gM -~_˄]6'%^sv_8rT9D?jH@hʼ<:u`L KAY9Y v?b;k/C0s"R)p*uQOQN] / P!Ɋ!Խ{)/G}).\/d8'=Ik/C0-8DbXs"ħSwB@m B0,y_\.m+K=u76j#Rb3E+x ւ ~I?vG󯨒i_G JKM9.Tw ?@8b_SU-ubl%u*6mMΔh.:~XjgJ?@6h GFVv_46JJ:`upx-;PS+R^񼕴1;uJHI@l:Q˒]j*cN؀@B81dawdgjj5R.٢Vz߅@|>_JcwYHv_1&l4|z c f ]w-WvW l~ sLdH޺ d{';/DTwz ߠ ntul1hy1޳1_M9dɁߑ=eGANWfr@J ?>OG-Nv?湔3]@hP!I:$ac[ PmfJ^)  Ҁ_z%l /wp`0h9m 0zZPxUF1"&O]3ouyck'UXJۣ20j{Bj[x[m4튺-.H?@(ҊN&Z$)+CϐL$]|i򜈄8I2'޿OKA a&[nbհ9(ԶkYf~kN~P0P h+4 p$~r%H$Ɂ?ʜ5-טW|Ĩ޴ CFS8? -[y"ڞŗ!i9a)ωHӒ@A^1 :|@:Nu` R$a0o,x2yfj qyL$~ig^τ(Q2o>੿YTf=.cƞK[O| >s=OmPů<Ѵ'e* B9VG"!j+*-Bnt/>hpa~[-"iAl7'~Ol_F9Ɏ#uqAZaf;mv1nݢ~[ 9 (Ms5σ`-zJ`[7o ?`G|Z#%DssV]E.6j6Mi&Zq݁c-/mMvl3/_h͚U&%Z|>C@Lxd7:kh`w,fhp^jeIIr4_",VxgzGva4o+#B@w:I(۷iߎJhp+SDT$a5G@667Ë;*W5~t ?ukbWXV\~j@:w} Ixu ntf \tP?>%Fz`/J'Czs-B;?l6@g?@Ea~pς,YS@R/[7~_ɷ2L'sg\GաĝSu70b@ï~e3EZN4i_qzͰdQ"7nWt"m)ͭƅ?/űq⍋ ۲y}$+%_^2sy*a__+xVR~nI7_zlQ̥n#z5xA&BlLU7z!$1n`! FWrQ^ ޽{x-=J)vקilEhόo~u a}}_+,z)(=|5Q^&=3O?J.6#9аxܪ1h}WN|?钅iQ_f4=~Cc8c в],bLاP eNr.4WgA9`ܐ<&ڬ+/=$$*0Ċ;4bvYr=ee´j͖ GO81hdŸ (s|b4ӮS}Ok{>ݼ>1~VΘrkdR=j$a?N/6bTs;]6; ~`4d+?ٹ~H3s'5#E a.J\)m(@:%UmJ@UU =,F:=.uQUU%<*FIwuuOjF5lvp9b6cU#b:t==F-ҵe+ +#Y9Zax#64}:BkN:fnj [3f؜*|TLFkzN6sѩņCqޙ,f* ?]tozZ(߹r9&:=:{8\_۾cFA;j*8$8yt!|?f艨`i^'$ӽp8f_:ϟcwԲԘϙʧcZ=ˑO^7)G ۓiurHT;y%KODR'2]8*_}Զϳe:%=ǽxϸ-p"(:N *#1] Kb:,3-#8Mxgcw?йZ;&xI [0ivllhie.juo_. ube~\0sr@-?'Z_:Ma۶-g~_:GQ#rЍ^G7myĉۙ'v:3LsA.t[O*hUf ]y8{R){yc,2z HzH0y;бcg>tw Km@xu-?6̙C 1Zd.~rNkڶjX u^)t>Ι1u =fG-@TwL#nX{kg#VK krO]f~wIp)ŦB8 NEAL37o@N 6"!,ѯy.^" ?N(bh߸^S3$0L}}ߗ~d*Sف_7G0ml~o-=@mؚåUt pL⚚j@}f19' @n>:iX](Ӂ߁ sj|g2}%n:T+`Ϟ߿Moة~2Z6nVƅ˼\4~5kyݷ3n^$xY>I7_ӵk7$IwsB6qw <̞/ }:ckj9p%&&,,Qy >~_: KVrRW_g u^:jŗ\qT c09O*Y @;&j8` ~Gb< $~U3ZO/~(ep O8羁ϟE)! |#U2FÕ3ZSo OuGIGx@+p9:oʦM>l$Ijȕ'!z=n=PS+4/N^A+ !7tan S6@ 8l߭] B0adCGrItPLuиc^]\1>sŃb âgj0%˓Ͼ̔i'_md֠]"~5ap>'"0_p>p@-{ Uc9(3A^^>Ͻr;^ڲ+Ȳ2&1nPܘ~C~rYR% 0 ؜I&z՘dM2/s؉q ŷBA߂/bvb˿ǗNuuT Q:5RՍ @M(Ng o,\S ZIDATةT3N:]ta_E8נ?cܼ8_v?}U7SfbD+:U۶yqޛ lQ,z]-w|/'!`oW/+s42pr@>06LZjs/ƨ77͆po{<3&O+r?ȑRij)JHL+X $B<\7QUV,^Uá !́ߩQZG39z@*Mmơʥ8`L2M+C$<_eWT=K'0#;8(dx[W_~ZN>u:O] Q$ˀ,_e~؁_vt$Seʨu7ֆTڼq-r֮Y#. [ڿYղ-ZK(o2vaG7L3 ].ңԋJ@@o ~IXg扅0Es) ];ݻ눭K*Ve ٽy3/]Dt)寏Ō(4 V$ as1(.~G}K_yVf 5J@tCǿqZ ‹Ȃm|5{ʪ)cׇ#%ֱE鮟gJgZiԔ@ N9 ХKYBX&H-A6~Z8J\ g?TKngv;΢秈eJa~jje*n՚_v.:\.ia4@pRf m RQ-H[8Ǡ^~w꽝 B^y_<[8YUNFUSt(])huƣL u߿`m{lbߑH(MO~ݼtBQ7VÿzR_bRgKhI}E@F}ZtCiF]ʸڛTf-UY2E_G"Ebm\/ЩNm=dno-?q;oN*S-fHSwgS2lkYwל{ݞF?JQZ Tյ2|mHDQ$\W-/''QR覤ȕ8frg~Yy߱}ƤYǀ&j&0hӟ~kfu.7!<<^lI ]C o-|3[Oa]:\ ̓42X@:t̅\W@ʴ J3<ă޵#eR jl5WJnDyJkYb- +nkYw8)ؑxwdu 1+ʌףLPlߡ3ϹY_Ny[6cKOg9x`_ K,U kj) ^(3Oñw,Mκ}~v>X*2˿ZHPzXטͥZ̗Đa9mLᯭf5nkW/童azrGKQZ};qw`x [^0[^uIײtT8Ae{vsVvش[[6YtV6PP&xaK@EMT)5 %(HE$*v/lu6JNC;Q.skfcX+5v;刢!*݆c J)%L1 Ot(u(:}ďAF&}Q `R'3@# D6B@s #_?cLOH *(PvVrVDUAGxG<1ͺ?8۹u:lĀ!dcIENDB`(@ R||Q10 rq ~($#PHEuif}{tgcOFC(#"}^g]ZeYUf"JCAG><!PQKI˻ɻﭖǯOEBV$"!읃omkhfda_][}X{VhĴ*%#vmjòxvtromkhfda_][}X{VyTxQ`ﮗrd_Ǹ}{xvtromkhfda_][}X{VyTxQvO|Xﭗﮗퟄ읂}{xvtromkhfda_][}X{VyTxQvOtMcijּ"*(';ퟄ읂}{xvtromkhfda_][}X{VyTxQvOtMsMĻ*%#T禍ퟄ읂}{xvtromkhfda_][}X{VyTxQvOtMrKuĻR#ﭖ䀹禍ퟄ읂}{xvtromkhfda_][}X{VyTxQvOtMrKjѸ"ﯙﭖ䀹禍ퟄ읂}{xvtromkhfda_][}X{VyTxQvOtMrKjbwpnǸﯙﭖ䀹禍ퟄ읂}{xvtromkhfda_][}X{VyTxQvOtMrKurd_]&$#`G>                              \0"xQvOtMrK朗(#!XA9T-yTxQvOtMsMij} RNMǷXB:T. {VyTxQvOtMbOEB tdLC                              `5&}X{VyTxQvOtMﭗɱrIFEȹ²ﯙﭖ䀹禍ퟄ읂}{xvtromkhfda_][}X{VyTxQvO{WG><4ƶĴ²lSJ9'!ퟄ읂o[""""""""""""k<,][}X{VyTxQvOﮗ0ȹƶĴ²XD>ퟄ읂iVU0#_][}X{VyTxQ_ied˽ʻȹƶĴ²XE>ퟄjXU1$a_][}X{VyTxQĴdXT˽ʻȹƶĴ²ZG@!kYU2%da_][}X{VyTS˽ʻȹƶĴ²ﯙﭖ䀹禍젅蜁}{yvtrpmkigfda_][}X{VhQ+))˽ʻȹƶĴgRK   2$禍ta      f=/hfda_][}X{V(#"|RPO˽ʻȹƶYGB䀹禍o^U3(khfda_][}XNEByvu˽ʻȹYHBﭖ䀹禍p_U4(mkhfda_][tgc˽ʻ`NI            (ﯙﭖ䀹禍sbX6+omkhfda_]z˽ʻȹƶĴ²ﯙﭖ䀹禍ퟄ읂}{xvtromkhfda_n\U   jC5tromkhfdaYKFV7,vtromkhfdYKGV7-xvtromkhfZLGV8.{xvtromkhﭗ|yxw˽ʻȹƶĴ²ﯙﭖ䀹禍ퟄ읂}{xvtromktieSQQw^MGƶĴ²ﯙﭖ䀹[A8 eUퟄ읂}{xvtromɻNGD,++~w_OIȹƶĴ²ﯙﭖ\B9cTퟄ읂}{xvtro)%$}Tx`OJʻȹƶĴ²ﯙ]C:cTퟄ읂}{xvt읃Ry`PK˽ʻȹƶĴ²]D<dUퟄ읂}{xvlkj|_PK˽ʻȹƶĴ²^E<eVퟄ읂}{xg]ZTGC˽ʻȹƶĴ²Q<5ziퟄ읂}좇5ٿ;30˽ʻȹƶĴ²9+&ӗ禍ퟄ읂ò1LKK ٺ˽ʻȹƶĴ²ӡ ꪓ䀹禍ퟄJCAtQHEj\W˽ʻȹƶĴ²gOGO:3ﯙﭖ䀹禍Ǹ̼rUTT{vŪ˽ʻȹƶĴ²dXﯙﭖ䀹禍ﮗQKI *&$0*(ڼ˽ʻȹƶĴ²ث.$!*讚ﯙﭖ䀹禍~***}x*$#˽ʻȹƶ)!g]ﯙﭖ䀹禍ʻ(%$dzyyF@= SHD}ʽöwRC> E61ﯙﭖvmj_1,*&!& 0&#௞#ҿ7106+(Σ"U!!!RJHRB=纫²ǸY,,,>86>4/ȹƶĴ²*(' sfbE=:3-+3,)E;7sb\˽ʻȹƶĴ²Ǹ#!!˽ʻȹƶǹzyy˽wpn&&&*((QUTTQMLX$LKKIFE#^kjiiedo+**SQQxwvxutRPO+))tt 54T~S????(0` WWlk 61/\SPrfc~ql~plreaZQM5/. o'$#tpIJí~pk'"!%KDBǸƸ˽H?<$P0,+³淚sjgda^[_wﯗ.(&N`~urﬕzvspmjgda^[|XzTyRo|mhgf잂|yvspmjgda^[|XzTxQuNmʻ dQ;잂|yvspmjgda^[|XzTxQuNtMʲN$ ±禍잂|yvspmjgda^[|XzTxQuNsKz̴ 'ﮘﬕ禍잂|yvspmjgda^[|XzTxQuNsKowywȹﮘﬕ禍잂|yvspmjgda^[|XzTxQuNsKy|mhs1/.I6/                      F%xQuNsKﭖ/)'ƼB1+?"zTxQuNuNɺMJI̿M93                      I(|XzTxQuNmH?<mļijפ˙ʗʕʓʑ~ʎ{ɍyɋvȉsߗ}잂|̂iˀf~c{az^x[uYtVqTtU[|XzTxQuNj*((ƶijB3.aR잂?$^[|XzTxQp'"!˼ȹƶijB4/cT잂@%a^[|XzTyR~pkY˼ȹƶijoXO=/+=/*<.)<-(<-(<,'<,&<+%<*%ud8&7$6#6#6"6"6!6!6 h=.da^[|XzTﯗíV˼ȹƶijylbj`i^h]f[eYdXbVaTƌy^N\L[JYHXGVEUCTAR@bJgda^[|Xx :87˼ȹƶC61gY禍@'jgda^[`5/._]\˼ȹC62h[ﬕ禍@'mjgda^[[QNurr˼{i`h_f]e\dZbXaW`U_TĐ~ﮘﬕ禍zVIyTGySEyRDxQBxOAxN?xL>xK<^Jpmjgda^̽pd`}}kdTE@TD?TD>TC=TB8S>7S=5R<4R;3R:2R:1R90R8/R7.Q7-Q5,Q5+Q4*|N>spmjgdaǸ}ok~}C85A)!vspmjgdȺ}pkussD96A*"yvspmjgpea_^^ʬ}{yvtrpm}k|iyfxdvah|yvspmj\SP:99 L>:ƶijﮘﬕJ4-  잂|yvsps61/PB=ȹƶijﮘL70잂|yvs轢 ZPB>˼ȹƶijL81잂|yvIJWMB>˼ȹƶijL71잂|ztp***,&%=41˼ȹƶij;,'+禍잂ﬕ'$#nD;9ĸ˼ȹƶij߫ B0*ﬕ禍잂kONNykh{je˼ȹƶijw\RuWLﮘﬕ禍JCBȴ ˼ȹƶij Ēﮘﬕ禍³333_UR"˼ȹƶ|^H@ﮘﬕ禍̽0,+x*%%ODA|uwnN@;* ٧ﮘ±~urt$μ7207-)ˤȹ¾(S|w2-+2*'phŶƶijPgį||mh|lf}wŨ˼ȹƶij̿m`˼ywhS333Ƽ1/.Q'ONNļMJI&o+***((:99_^^vtt~~~vss_]\977nmZY????( @ WV ?97SJGSJG>75":53{ſ׿zt82/*'&ʻﱛzv움0*(.xuvrmhd_[{V|V|mh- ퟄ{vrmhd_[{VxQzT Ƿ禍ퟄ{vrmhd_[{VxQtM힄zx˽ﭖ禍ퟄ{vrmhd_[{VxQtMퟄ|mh%.,+1$ /xQtM1+)"±4'"2{VxQyT ;98²vieYcWaT_R]O`QퟄnYUDRAQ>N[{VxQ82/ X˽ƶ²," ퟄP4+*_[{V|VytUʻƶ²rgy^Uy\RxZPxYNxWK[NjXtL>sK This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ using System; namespace KeePass.Ecas { public enum EcasValueType { None = 0, String = 1, Bool = 2, EnumStrings = 3, Int64 = 4, UInt64 = 5 } } KeePass/Ecas/EcasConditionProvider.cs0000664000000000000000000000437013222430406016550 0ustar rootroot/* KeePass Password Safe - The Open-Source Password Manager Copyright (C) 2003-2018 Dominik Reichl This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ using System; using System.Collections.Generic; using System.Text; using KeePassLib; namespace KeePass.Ecas { public abstract class EcasConditionProvider { protected List m_conditions = new List(); internal List Conditions { get { return m_conditions; } } public bool IsSupported(PwUuid uuidType) { if(uuidType == null) throw new ArgumentNullException("uuidType"); foreach(EcasConditionType t in m_conditions) { if(t.Type.Equals(uuidType)) return true; } return false; } public EcasConditionType Find(string strConditionName) { if(strConditionName == null) throw new ArgumentNullException("strConditionName"); foreach(EcasConditionType t in m_conditions) { if(t.Name == strConditionName) return t; } return null; } public EcasConditionType Find(PwUuid uuid) { if(uuid == null) throw new ArgumentNullException("uuid"); foreach(EcasConditionType t in m_conditions) { if(t.Type.Equals(uuid)) return t; } return null; } public bool Evaluate(EcasCondition c, EcasContext ctx) { if(c == null) throw new ArgumentNullException("c"); foreach(EcasConditionType t in m_conditions) { if(t.Type.Equals(c.Type)) return t.EvaluateMethod(c, ctx); } throw new NotSupportedException(); } } } KeePass/Ecas/EcasAction.cs0000664000000000000000000000406613222430406014326 0ustar rootroot/* KeePass Password Safe - The Open-Source Password Manager Copyright (C) 2003-2018 Dominik Reichl This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ using System; using System.Collections.Generic; using System.Text; using System.Xml.Serialization; using KeePassLib; using KeePassLib.Interfaces; namespace KeePass.Ecas { public sealed class EcasAction : IDeepCloneable, IEcasObject { private PwUuid m_type = PwUuid.Zero; [XmlIgnore] public PwUuid Type { get { return m_type; } set { m_type = value; } } [XmlElement("TypeGuid")] public string TypeString { get { return Convert.ToBase64String(m_type.UuidBytes, Base64FormattingOptions.None); } set { if(value == null) throw new ArgumentNullException("value"); m_type = new PwUuid(Convert.FromBase64String(value)); } } private List m_params = new List(); [XmlArrayItem("Parameter")] public List Parameters { get { return m_params; } set { if(value == null) throw new ArgumentNullException("value"); m_params = value; } } public EcasAction() { } public EcasAction CloneDeep() { EcasAction e = new EcasAction(); e.m_type = m_type; // PwUuid is immutable for(int i = 0; i < m_params.Count; ++i) e.m_params.Add(m_params[i]); return e; } } } KeePass/Ecas/EcasConditionType.cs0000664000000000000000000000450713222430406015701 0ustar rootroot/* KeePass Password Safe - The Open-Source Password Manager Copyright (C) 2003-2018 Dominik Reichl This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ using System; using System.Collections.Generic; using System.Text; using KeePassLib; namespace KeePass.Ecas { public delegate bool EcasConditionEvaluate(EcasCondition c, EcasContext ctx); public sealed class EcasConditionType : IEcasParameterized { private PwUuid m_type; public PwUuid Type { get { return m_type; } } private string m_strName; public string Name { get { return m_strName; } } private PwIcon m_pwIcon; public PwIcon Icon { get { return m_pwIcon; } } private EcasParameter[] m_vParams; public EcasParameter[] Parameters { get { return m_vParams; } } private EcasConditionEvaluate m_fn; public EcasConditionEvaluate EvaluateMethod { get { return m_fn; } } private static bool EcasConditionEvaluateTrue(EcasCondition c, EcasContext ctx) { return true; } public EcasConditionType(PwUuid uuidType, string strName, PwIcon pwIcon, EcasParameter[] vParams, EcasConditionEvaluate f) { if((uuidType == null) || PwUuid.Zero.Equals(uuidType)) throw new ArgumentNullException("uuidType"); if(strName == null) throw new ArgumentNullException("strName"); // if(vParams == null) throw new ArgumentNullException("vParams"); // if(f == null) throw new ArgumentNullException("f"); m_type = uuidType; m_strName = strName; m_pwIcon = pwIcon; m_vParams = (vParams ?? EcasParameter.EmptyArray); m_fn = (f ?? EcasConditionEvaluateTrue); } } } KeePass/Ecas/EcasCondition.cs0000664000000000000000000000434413222430406015036 0ustar rootroot/* KeePass Password Safe - The Open-Source Password Manager Copyright (C) 2003-2018 Dominik Reichl This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ using System; using System.Collections.Generic; using System.Text; using System.Xml.Serialization; using KeePassLib; using KeePassLib.Interfaces; namespace KeePass.Ecas { public sealed class EcasCondition : IDeepCloneable, IEcasObject { private PwUuid m_type = PwUuid.Zero; [XmlIgnore] public PwUuid Type { get { return m_type; } set { m_type = value; } } [XmlElement("TypeGuid")] public string TypeString { get { return Convert.ToBase64String(m_type.UuidBytes, Base64FormattingOptions.None); } set { if(value == null) throw new ArgumentNullException("value"); m_type = new PwUuid(Convert.FromBase64String(value)); } } private List m_params = new List(); [XmlArrayItem("Parameter")] public List Parameters { get { return m_params; } set { if(value == null) throw new ArgumentNullException("value"); m_params = value; } } private bool m_bNegate = false; public bool Negate { get { return m_bNegate; } set { m_bNegate = value; } } public EcasCondition() { } public EcasCondition CloneDeep() { EcasCondition e = new EcasCondition(); e.m_type = m_type; // PwUuid is immutable for(int i = 0; i < m_params.Count; ++i) e.m_params.Add(m_params[i]); e.Negate = m_bNegate; return e; } } } KeePass/Ecas/EcasPool.cs0000664000000000000000000001417213222430406014021 0ustar rootroot/* KeePass Password Safe - The Open-Source Password Manager Copyright (C) 2003-2018 Dominik Reichl This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ using System; using System.Collections.Generic; using System.Text; using KeePass.Resources; using KeePassLib; using KeePassLib.Utility; namespace KeePass.Ecas { public sealed class EcasPool { private List m_vEventProviders = new List(); private List m_vConditionProviders = new List(); private List m_vActionProviders = new List(); internal List EventProviders { get { return m_vEventProviders; } } internal List ConditionProviders { get { return m_vConditionProviders; } } internal List ActionProviders { get { return m_vActionProviders; } } public EcasPool() { } public EcasPool(bool bAddDefaultProviders) { if(bAddDefaultProviders) AddDefaultProviders(); } private void AddDefaultProviders() { m_vEventProviders.Add(new EcasDefaultEventProvider()); m_vConditionProviders.Add(new EcasDefaultConditionProvider()); m_vActionProviders.Add(new EcasDefaultActionProvider()); } public void AddEventProvider(EcasEventProvider p) { if(p == null) throw new ArgumentNullException("p"); m_vEventProviders.Add(p); } public bool RemoveEventProvider(EcasEventProvider p) { if(p == null) throw new ArgumentNullException("p"); return m_vEventProviders.Remove(p); } public EcasEventType FindEvent(string strEventName) { if(strEventName == null) throw new ArgumentNullException("strEventName"); foreach(EcasEventProvider p in m_vEventProviders) { EcasEventType t = p.Find(strEventName); if(t != null) return t; } return null; } public EcasEventType FindEvent(PwUuid uuid) { if(uuid == null) throw new ArgumentNullException("uuid"); foreach(EcasEventProvider p in m_vEventProviders) { EcasEventType t = p.Find(uuid); if(t != null) return t; } return null; } public void AddConditionProvider(EcasConditionProvider p) { if(p == null) throw new ArgumentNullException("p"); m_vConditionProviders.Add(p); } public bool RemoveConditionProvider(EcasConditionProvider p) { if(p == null) throw new ArgumentNullException("p"); return m_vConditionProviders.Remove(p); } public EcasConditionType FindCondition(string strConditionName) { if(strConditionName == null) throw new ArgumentNullException("strConditionName"); foreach(EcasConditionProvider p in m_vConditionProviders) { EcasConditionType t = p.Find(strConditionName); if(t != null) return t; } return null; } public EcasConditionType FindCondition(PwUuid uuid) { if(uuid == null) throw new ArgumentNullException("uuid"); foreach(EcasConditionProvider p in m_vConditionProviders) { EcasConditionType t = p.Find(uuid); if(t != null) return t; } return null; } public void AddActionProvider(EcasActionProvider p) { if(p == null) throw new ArgumentNullException("p"); m_vActionProviders.Add(p); } public bool RemoveActionProvider(EcasActionProvider p) { if(p == null) throw new ArgumentNullException("p"); return m_vActionProviders.Remove(p); } public EcasActionType FindAction(string strActionName) { if(strActionName == null) throw new ArgumentNullException("strActionName"); foreach(EcasActionProvider p in m_vActionProviders) { EcasActionType t = p.Find(strActionName); if(t != null) return t; } return null; } public EcasActionType FindAction(PwUuid uuid) { if(uuid == null) throw new ArgumentNullException("uuid"); foreach(EcasActionProvider p in m_vActionProviders) { EcasActionType t = p.Find(uuid); if(t != null) return t; } return null; } public bool CompareEvents(EcasEvent e, EcasContext ctx) { if(e == null) throw new ArgumentNullException("e"); if(ctx == null) throw new ArgumentNullException("ctx"); if(e.Type.Equals(ctx.Event.Type) == false) return false; foreach(EcasEventProvider p in m_vEventProviders) { if(p.IsSupported(e.Type)) return p.Compare(e, ctx); } throw new Exception(KPRes.TriggerEventTypeUnknown + " " + KPRes.TypeUnknownHint + MessageService.NewParagraph + e.TypeString); } public bool EvaluateCondition(EcasCondition c, EcasContext ctx) { if(c == null) throw new ArgumentNullException("c"); foreach(EcasConditionProvider p in m_vConditionProviders) { if(p.IsSupported(c.Type)) { bool bResult = p.Evaluate(c, ctx); return (c.Negate ? !bResult : bResult); } } throw new Exception(KPRes.TriggerConditionTypeUnknown + " " + KPRes.TypeUnknownHint + MessageService.NewParagraph + c.TypeString); } public void ExecuteAction(EcasAction a, EcasContext ctx) { if(a == null) throw new ArgumentNullException("a"); foreach(EcasActionProvider p in m_vActionProviders) { if(p.IsSupported(a.Type)) { p.Execute(a, ctx); return; } } throw new Exception(KPRes.TriggerActionTypeUnknown + " " + KPRes.TypeUnknownHint + MessageService.NewParagraph + a.TypeString); } } } KeePass/Ecas/EcasContext.cs0000664000000000000000000000377613222430406014544 0ustar rootroot/* KeePass Password Safe - The Open-Source Password Manager Copyright (C) 2003-2018 Dominik Reichl This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ using System; using System.Collections.Generic; using System.Text; namespace KeePass.Ecas { public sealed class EcasContext { private EcasTriggerSystem m_coll; public EcasTriggerSystem TriggerSystem { get { return m_coll; } } private EcasTrigger m_trigger; public EcasTrigger Trigger { get { return m_trigger; } } private EcasEvent m_eOccured; public EcasEvent Event { get { return m_eOccured; } } private EcasPropertyDictionary m_props; public EcasPropertyDictionary Properties { get { return m_props; } } private bool m_bCancel = false; public bool Cancel { get { return m_bCancel; } set { m_bCancel = value; } } public EcasContext(EcasTriggerSystem coll, EcasTrigger trigger, EcasEvent e, EcasPropertyDictionary props) { if(coll == null) throw new ArgumentNullException("coll"); if(trigger == null) throw new ArgumentNullException("trigger"); if(e == null) throw new ArgumentNullException("e"); if(props == null) throw new ArgumentNullException("props"); m_coll = coll; m_trigger = trigger; m_eOccured = e; m_props = props; } } } KeePass/Ecas/EcasSystemEvents.cs0000664000000000000000000000251213222430406015554 0ustar rootroot/* KeePass Password Safe - The Open-Source Password Manager Copyright (C) 2003-2018 Dominik Reichl This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ using System; using KeePass.Util; namespace KeePass.Ecas { public sealed class EcasRaisingEventArgs : CancellableOperationEventArgs { private EcasEvent m_evt; public EcasEvent Event { get { return m_evt; } } private EcasPropertyDictionary m_props; public EcasPropertyDictionary Properties { get { return m_props; } } public EcasRaisingEventArgs(EcasEvent evt, EcasPropertyDictionary props) { m_evt = evt; m_props = props; } } } KeePass/Ecas/IEcasObject.cs0000664000000000000000000000231113222430406014417 0ustar rootroot/* KeePass Password Safe - The Open-Source Password Manager Copyright (C) 2003-2018 Dominik Reichl This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ using System; using System.Collections.Generic; using System.Text; using KeePassLib; namespace KeePass.Ecas { public enum EcasObjectType { None = 0, Event = 1, Condition = 2, Action = 3 } public interface IEcasObject { PwUuid Type { get; set; } string TypeString { get; set; } List Parameters { get; set; } } } KeePass/Ecas/EcasPropertyDictionary.cs0000664000000000000000000000367213222430406016765 0ustar rootroot/* KeePass Password Safe - The Open-Source Password Manager Copyright (C) 2003-2018 Dominik Reichl This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ using System; using System.Collections.Generic; using System.Text; using System.Diagnostics; namespace KeePass.Ecas { public static class EcasProperty { // Triggering objects public const string Database = "Database"; // PwDatabase public const string IOConnectionInfo = "IOConnectionInfo"; // IOConnectionInfo public const string Text = "Text"; // String public const string CommandID = "CommandID"; // String } public sealed class EcasPropertyDictionary { private Dictionary m_dict = new Dictionary(); public EcasPropertyDictionary() { } public void Set(string strKey, object oValue) { if(string.IsNullOrEmpty(strKey)) { Debug.Assert(false); return; } m_dict[strKey] = oValue; } public T Get(string strKey) where T : class { if(string.IsNullOrEmpty(strKey)) { Debug.Assert(false); return null; } object o; if(m_dict.TryGetValue(strKey, out o)) { if(o == null) return null; T p = (o as T); Debug.Assert(p != null); return p; } return null; } } } KeePass/Ecas/IEcasParameterized.cs0000664000000000000000000000210413222430406016005 0ustar rootroot/* KeePass Password Safe - The Open-Source Password Manager Copyright (C) 2003-2018 Dominik Reichl This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ using System; using System.Collections.Generic; using System.Text; using KeePassLib; namespace KeePass.Ecas { public interface IEcasParameterized { PwUuid Type { get; } EcasParameter[] Parameters { get; } } } KeePass/Ecas/EcasDefaultEventProvider.cs0000664000000000000000000001643213222430406017212 0ustar rootroot/* KeePass Password Safe - The Open-Source Password Manager Copyright (C) 2003-2018 Dominik Reichl This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ using System; using System.Collections.Generic; using System.Text; using System.Diagnostics; using KeePass.Resources; using KeePassLib; using KeePassLib.Utility; using KeePassLib.Serialization; namespace KeePass.Ecas { internal static class EcasEventIDs { public static readonly PwUuid OpenedDatabaseFile = new PwUuid(new byte[] { 0xE5, 0xFF, 0x13, 0x06, 0x85, 0xB8, 0x41, 0x89, 0xB9, 0x06, 0xF6, 0x9E, 0x2B, 0x3B, 0x40, 0xA7 }); public static readonly PwUuid SavingDatabaseFile = new PwUuid(new byte[] { 0x95, 0xC1, 0xA6, 0xFD, 0x72, 0x7C, 0x40, 0xC7, 0xA2, 0xF9, 0x5B, 0x0F, 0xA0, 0x99, 0x63, 0x1C }); public static readonly PwUuid SavedDatabaseFile = new PwUuid(new byte[] { 0xB3, 0xA8, 0xFD, 0xFE, 0x78, 0x13, 0x4A, 0x6A, 0x9C, 0x5D, 0xD5, 0xBA, 0x84, 0x3A, 0x9B, 0x8E }); public static readonly PwUuid ClosingDatabaseFilePre = new PwUuid(new byte[] { 0x8C, 0xEA, 0xDE, 0x9A, 0xA8, 0x17, 0x49, 0x19, 0xA3, 0x2F, 0xF4, 0x1E, 0x3B, 0x1D, 0xEC, 0x49 }); public static readonly PwUuid ClosingDatabaseFilePost = new PwUuid(new byte[] { 0x94, 0xFA, 0x70, 0xE5, 0xB1, 0x3F, 0x41, 0x26, 0xA6, 0x4E, 0x06, 0x4F, 0xD8, 0xC3, 0x6C, 0x95 }); public static readonly PwUuid CopiedEntryInfo = new PwUuid(new byte[] { 0x3F, 0x7E, 0x5E, 0xC6, 0x2A, 0x54, 0x4C, 0x58, 0x95, 0x44, 0x85, 0xFB, 0xF2, 0x6F, 0x56, 0xDC }); public static readonly PwUuid AppInitPost = new PwUuid(new byte[] { 0xD4, 0xCE, 0xCD, 0xB5, 0x4B, 0x98, 0x4F, 0xF2, 0xA6, 0xA9, 0xE2, 0x55, 0x26, 0x1E, 0xC8, 0xE8 }); public static readonly PwUuid AppLoadPost = new PwUuid(new byte[] { 0xD8, 0xF3, 0x1E, 0xE9, 0xCC, 0x69, 0x48, 0x1B, 0x89, 0xC5, 0xFC, 0xE2, 0xEA, 0x4B, 0x6A, 0x97 }); public static readonly PwUuid AppExit = new PwUuid(new byte[] { 0x82, 0x8A, 0xB7, 0xAB, 0xB1, 0x1C, 0x4E, 0xBF, 0x80, 0x39, 0x36, 0x3F, 0x91, 0x71, 0x97, 0x78 }); public static readonly PwUuid CustomTbButtonClicked = new PwUuid(new byte[] { 0x47, 0x47, 0x59, 0x92, 0x97, 0xA7, 0x43, 0xA2, 0xB9, 0x68, 0x1F, 0x1F, 0xC2, 0xF7, 0x9B, 0x92 }); public static readonly PwUuid UpdatedUIState = new PwUuid(new byte[] { 0x8D, 0x12, 0xD4, 0x9A, 0xF2, 0xCB, 0x4F, 0xF7, 0xA8, 0xEF, 0xCF, 0xDA, 0xAC, 0x62, 0x68, 0x99 }); } internal sealed class EcasDefaultEventProvider : EcasEventProvider { public EcasDefaultEventProvider() { EcasParameter[] epFileFilter = new EcasParameter[] { new EcasParameter(KPRes.FileOrUrl + " - " + KPRes.Comparison, EcasValueType.EnumStrings, EcasUtil.StdStringCompare), new EcasParameter(KPRes.FileOrUrl + " - " + KPRes.Filter, EcasValueType.String, null) }; EcasParameter[] epValueFilter = new EcasParameter[] { new EcasParameter(KPRes.Value + " - " + KPRes.Comparison, EcasValueType.EnumStrings, EcasUtil.StdStringCompare), new EcasParameter(KPRes.Value + " - " + KPRes.Filter, EcasValueType.String, null) }; m_events.Add(new EcasEventType(EcasEventIDs.AppInitPost, KPRes.ApplicationInitialized, PwIcon.ProgramIcons, null, null)); m_events.Add(new EcasEventType(EcasEventIDs.AppLoadPost, KPRes.ApplicationStarted, PwIcon.ProgramIcons, null, null)); m_events.Add(new EcasEventType(EcasEventIDs.AppExit, KPRes.ApplicationExit, PwIcon.ProgramIcons, null, null)); m_events.Add(new EcasEventType(EcasEventIDs.OpenedDatabaseFile, KPRes.OpenedDatabaseFile, PwIcon.FolderOpen, epFileFilter, IsMatchIocDbEvent)); m_events.Add(new EcasEventType(EcasEventIDs.SavingDatabaseFile, KPRes.SavingDatabaseFile, PwIcon.Disk, epFileFilter, IsMatchIocDbEvent)); m_events.Add(new EcasEventType(EcasEventIDs.SavedDatabaseFile, KPRes.SavedDatabaseFile, PwIcon.Disk, epFileFilter, IsMatchIocDbEvent)); m_events.Add(new EcasEventType(EcasEventIDs.ClosingDatabaseFilePre, KPRes.ClosingDatabaseFile + " (" + KPRes.SavingPre + ")", PwIcon.PaperQ, epFileFilter, IsMatchIocDbEvent)); m_events.Add(new EcasEventType(EcasEventIDs.ClosingDatabaseFilePost, KPRes.ClosingDatabaseFile + " (" + KPRes.SavingPost + ")", PwIcon.PaperQ, epFileFilter, IsMatchIocDbEvent)); m_events.Add(new EcasEventType(EcasEventIDs.CopiedEntryInfo, KPRes.CopiedEntryData, PwIcon.ClipboardReady, epValueFilter, IsMatchTextEvent)); m_events.Add(new EcasEventType(EcasEventIDs.UpdatedUIState, KPRes.UpdatedUIState, PwIcon.PaperReady, null, null)); m_events.Add(new EcasEventType(EcasEventIDs.CustomTbButtonClicked, KPRes.CustomTbButtonClicked, PwIcon.Star, new EcasParameter[] { new EcasParameter(KPRes.Id, EcasValueType.String, null) }, IsMatchIdEvent)); } private static bool IsMatchIocDbEvent(EcasEvent e, EcasContext ctx) { uint uCompareType = EcasUtil.GetParamEnum(e.Parameters, 0, EcasUtil.StdStringCompareEquals, EcasUtil.StdStringCompare); string strFilter = EcasUtil.GetParamString(e.Parameters, 1, true); if(string.IsNullOrEmpty(strFilter)) return true; // Must prefer IOC (e.g. for SavingDatabaseFile) IOConnectionInfo ioc = ctx.Properties.Get( EcasProperty.IOConnectionInfo); if(ioc == null) { PwDatabase pd = ctx.Properties.Get(EcasProperty.Database); if(pd == null) { Debug.Assert(false); return false; } ioc = pd.IOConnectionInfo; } if(ioc == null) { Debug.Assert(false); return false; } string strCurFile = ioc.Path; if(string.IsNullOrEmpty(strCurFile)) return false; return EcasUtil.CompareStrings(strCurFile, strFilter, uCompareType); } private static bool IsMatchTextEvent(EcasEvent e, EcasContext ctx) { uint uCompareType = EcasUtil.GetParamEnum(e.Parameters, 0, EcasUtil.StdStringCompareEquals, EcasUtil.StdStringCompare); string strFilter = EcasUtil.GetParamString(e.Parameters, 1, true); if(string.IsNullOrEmpty(strFilter)) return true; string str = ctx.Properties.Get(EcasProperty.Text); if(str == null) { Debug.Assert(false); return false; } return EcasUtil.CompareStrings(str, strFilter, uCompareType); } private static bool IsMatchIdEvent(EcasEvent e, EcasContext ctx) { string strIdRef = EcasUtil.GetParamString(e.Parameters, 0, true); if(string.IsNullOrEmpty(strIdRef)) return true; string strIdCur = ctx.Properties.Get(EcasProperty.CommandID); if(string.IsNullOrEmpty(strIdCur)) return false; return strIdRef.Equals(strIdCur, StrUtil.CaseIgnoreCmp); } } } KeePass/Ecas/EcasActionProvider.cs0000664000000000000000000000431113222430406016032 0ustar rootroot/* KeePass Password Safe - The Open-Source Password Manager Copyright (C) 2003-2018 Dominik Reichl This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ using System; using System.Collections.Generic; using System.Text; using KeePassLib; namespace KeePass.Ecas { public abstract class EcasActionProvider { protected List m_actions = new List(); internal List Actions { get { return m_actions; } } public bool IsSupported(PwUuid uuidType) { if(uuidType == null) throw new ArgumentNullException("uuidType"); foreach(EcasActionType t in m_actions) { if(t.Type.Equals(uuidType)) return true; } return false; } public EcasActionType Find(string strActionName) { if(strActionName == null) throw new ArgumentNullException("strActionName"); foreach(EcasActionType t in m_actions) { if(t.Name == strActionName) return t; } return null; } public EcasActionType Find(PwUuid uuid) { if(uuid == null) throw new ArgumentNullException("uuid"); foreach(EcasActionType t in m_actions) { if(t.Type.Equals(uuid)) return t; } return null; } public void Execute(EcasAction a, EcasContext ctx) { if(a == null) throw new ArgumentNullException("a"); foreach(EcasActionType t in m_actions) { if(t.Type.Equals(a.Type)) { t.ExecuteMethod(a, ctx); return; } } throw new NotSupportedException(); } } } KeePass/Ecas/EcasEventType.cs0000664000000000000000000000443013222430406015027 0ustar rootroot/* KeePass Password Safe - The Open-Source Password Manager Copyright (C) 2003-2018 Dominik Reichl This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ using System; using System.Collections.Generic; using System.Text; using KeePassLib; namespace KeePass.Ecas { public delegate bool EcasEventCompare(EcasEvent e, EcasContext ctx); public sealed class EcasEventType : IEcasParameterized { private PwUuid m_type; public PwUuid Type { get { return m_type; } } private string m_strName; public string Name { get { return m_strName; } } private PwIcon m_pwIcon; public PwIcon Icon { get { return m_pwIcon; } } private EcasParameter[] m_vParams; public EcasParameter[] Parameters { get { return m_vParams; } } private EcasEventCompare m_fn; public EcasEventCompare CompareMethod { get { return m_fn; } } private static bool EcasEventCompareTrue(EcasEvent e, EcasContext ctx) { return true; } public EcasEventType(PwUuid uuidType, string strName, PwIcon pwIcon, EcasParameter[] vParams, EcasEventCompare f) { if((uuidType == null) || PwUuid.Zero.Equals(uuidType)) throw new ArgumentNullException("uuidType"); if(strName == null) throw new ArgumentNullException("strName"); // if(vParams == null) throw new ArgumentNullException("vParams"); // if(f == null) throw new ArgumentNullException("f"); m_type = uuidType; m_strName = strName; m_pwIcon = pwIcon; m_vParams = (vParams ?? EcasParameter.EmptyArray); m_fn = (f ?? EcasEventCompareTrue); } } } KeePass/Ecas/EcasTrigger.cs0000664000000000000000000001406613222430406014515 0ustar rootroot/* KeePass Password Safe - The Open-Source Password Manager Copyright (C) 2003-2018 Dominik Reichl This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ using System; using System.Collections.Generic; using System.Text; using System.Xml.Serialization; using System.ComponentModel; using System.Diagnostics; using KeePassLib; using KeePassLib.Collections; using KeePassLib.Interfaces; namespace KeePass.Ecas { [DebuggerDisplay("Name = {m_strName}")] public sealed class EcasTrigger : IDeepCloneable { private PwUuid m_uuid = PwUuid.Zero; [XmlIgnore] public PwUuid Uuid { get { return m_uuid; } set { if(value == null) throw new ArgumentNullException("value"); m_uuid = value; } } [XmlElement("Guid")] public string UuidString { get { return Convert.ToBase64String(m_uuid.UuidBytes, Base64FormattingOptions.None); } set { if(value == null) throw new ArgumentNullException("value"); m_uuid = new PwUuid(Convert.FromBase64String(value)); } } private string m_strName = string.Empty; [DefaultValue("")] public string Name { get { return m_strName; } set { if(value == null) throw new ArgumentNullException("value"); m_strName = value; } } private string m_strComments = string.Empty; [DefaultValue("")] public string Comments { get { return m_strComments; } set { if(value == null) throw new ArgumentNullException("value"); m_strComments = value; } } private bool m_bEnabled = true; [DefaultValue(true)] public bool Enabled { get { return m_bEnabled; } set { m_bEnabled = value; } } private bool m_bInitiallyOn = true; [DefaultValue(true)] public bool InitiallyOn { get { return m_bInitiallyOn; } set { m_bInitiallyOn = value; } } private bool m_bOn = true; [XmlIgnore] public bool On { get { return m_bOn; } set { m_bOn = value; } } private bool m_bTurnOffAfterAction = false; [DefaultValue(false)] public bool TurnOffAfterAction { get { return m_bTurnOffAfterAction; } set { m_bTurnOffAfterAction = value; } } private PwObjectList m_events = new PwObjectList(); [XmlIgnore] public PwObjectList EventCollection { get { return m_events; } set { if(value == null) throw new ArgumentNullException("value"); m_events = value; } } [XmlArray("Events")] [XmlArrayItem("Event")] public EcasEvent[] EventArrayForSerialization { get { return m_events.CloneShallowToList().ToArray(); } set { m_events = PwObjectList.FromArray(value); } } private PwObjectList m_conds = new PwObjectList(); [XmlIgnore] public PwObjectList ConditionCollection { get { return m_conds; } set { if(value == null) throw new ArgumentNullException("value"); m_conds = value; } } [XmlArray("Conditions")] [XmlArrayItem("Condition")] public EcasCondition[] ConditionsArrayForSerialization { get { return m_conds.CloneShallowToList().ToArray(); } set { m_conds = PwObjectList.FromArray(value); } } private PwObjectList m_acts = new PwObjectList(); [XmlIgnore] public PwObjectList ActionCollection { get { return m_acts; } set { if(value == null) throw new ArgumentNullException("value"); m_acts = value; } } [XmlArray("Actions")] [XmlArrayItem("Action")] public EcasAction[] ActionArrayForSerialization { get { return m_acts.CloneShallowToList().ToArray(); } set { m_acts = PwObjectList.FromArray(value); } } public EcasTrigger() { } public EcasTrigger(bool bCreateNewUuid) { if(bCreateNewUuid) m_uuid = new PwUuid(true); } public EcasTrigger CloneDeep() { EcasTrigger e = new EcasTrigger(false); e.m_uuid = m_uuid; // PwUuid is immutable e.m_strName = m_strName; e.m_strComments = m_strComments; e.m_bEnabled = m_bEnabled; e.m_bInitiallyOn = m_bInitiallyOn; e.m_bOn = m_bOn; e.m_bTurnOffAfterAction = m_bTurnOffAfterAction; for(uint i = 0; i < m_events.UCount; ++i) e.m_events.Add(m_events.GetAt(i).CloneDeep()); for(uint j = 0; j < m_conds.UCount; ++j) e.m_conds.Add(m_conds.GetAt(j).CloneDeep()); for(uint k = 0; k < m_acts.UCount; ++k) e.m_acts.Add(m_acts.GetAt(k).CloneDeep()); return e; } internal void SetToInitialState() { m_bOn = m_bInitiallyOn; } public void RunIfMatching(EcasEvent ctxOccured, EcasPropertyDictionary props) { if(!m_bEnabled || !m_bOn) return; EcasContext ctx = new EcasContext(Program.TriggerSystem, this, ctxOccured, props); bool bEventMatches = false; foreach(EcasEvent e in m_events) { if(Program.EcasPool.CompareEvents(e, ctx)) { bEventMatches = true; break; } } if(!bEventMatches) return; foreach(EcasCondition c in m_conds) { if(Program.EcasPool.EvaluateCondition(c, ctx) == false) return; } for(uint iAction = 0; iAction < m_acts.UCount; ++iAction) { if(ctx.Cancel) break; Program.EcasPool.ExecuteAction(m_acts.GetAt(iAction), ctx); } if(m_bTurnOffAfterAction) m_bOn = false; } } } KeePass/Ecas/EcasParameter.cs0000664000000000000000000000362513222430406015031 0ustar rootroot/* KeePass Password Safe - The Open-Source Password Manager Copyright (C) 2003-2018 Dominik Reichl This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ using System; using System.Collections.Generic; using System.Text; namespace KeePass.Ecas { public sealed class EcasParameter { private static EcasParameter[] m_epvNone = null; public static EcasParameter[] EmptyArray { get { if(m_epvNone == null) m_epvNone = new EcasParameter[0]; return m_epvNone; } } private string m_strName; public string Name { get { return m_strName; } set { if(value == null) throw new ArgumentNullException("value"); m_strName = value; } } private EcasValueType m_type; public EcasValueType Type { get { return m_type; } set { m_type = value; } } private EcasEnum m_vEnumValues; public EcasEnum EnumValues { get { return m_vEnumValues; } set { m_vEnumValues = value; } // May be null } public EcasParameter(string strName, EcasValueType t, EcasEnum eEnumValues) { if(strName == null) throw new ArgumentNullException("strName"); m_strName = strName; m_type = t; m_vEnumValues = eEnumValues; } } } KeePass/Ecas/EcasDefaultActionProvider.cs0000664000000000000000000006774613222430406017364 0ustar rootroot/* KeePass Password Safe - The Open-Source Password Manager Copyright (C) 2003-2018 Dominik Reichl This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ using System; using System.Collections.Generic; using System.Collections.ObjectModel; using System.Text; using System.IO; using System.Windows.Forms; using System.Threading; using System.Diagnostics; using KeePass.App; using KeePass.DataExchange; using KeePass.Forms; using KeePass.Native; using KeePass.Resources; using KeePass.UI; using KeePass.Util; using KeePassLib; using KeePassLib.Collections; using KeePassLib.Delegates; using KeePassLib.Keys; using KeePassLib.Serialization; using KeePassLib.Utility; namespace KeePass.Ecas { internal sealed class EcasDefaultActionProvider : EcasActionProvider { private const uint IdWindowNormal = 0; private const uint IdWindowHidden = 1; private const uint IdWindowMin = 2; private const uint IdWindowMax = 3; private const uint IdTriggerOff = 0; private const uint IdTriggerOn = 1; private const uint IdTriggerToggle = 2; private const uint IdMbcY = 0; private const uint IdMbcN = 1; private const uint IdMbaNone = 0; private const uint IdMbaAbort = 1; private const uint IdMbaCmd = 2; public EcasDefaultActionProvider() { m_actions.Add(new EcasActionType(new PwUuid(new byte[] { 0xDA, 0xE5, 0xF8, 0x3B, 0x07, 0x30, 0x4C, 0x13, 0x9E, 0xEF, 0x2E, 0xBA, 0xCB, 0x6E, 0xE4, 0xC7 }), KPRes.ExecuteCmdLineUrl, PwIcon.Console, new EcasParameter[] { new EcasParameter(KPRes.FileOrUrl, EcasValueType.String, null), new EcasParameter(KPRes.Arguments, EcasValueType.String, null), new EcasParameter(KPRes.WaitForExit, EcasValueType.Bool, null), new EcasParameter(KPRes.WindowStyle, EcasValueType.EnumStrings, new EcasEnum(new EcasEnumItem[] { new EcasEnumItem(IdWindowNormal, KPRes.Normal), new EcasEnumItem(IdWindowHidden, KPRes.Hidden), new EcasEnumItem(IdWindowMin, KPRes.Minimized), new EcasEnumItem(IdWindowMax, KPRes.Maximized) })), new EcasParameter(KPRes.Verb, EcasValueType.String, null) }, ExecuteShellCmd)); m_actions.Add(new EcasActionType(new PwUuid(new byte[] { 0xB6, 0x46, 0xA6, 0x9F, 0xDE, 0x94, 0x4B, 0xB9, 0x9B, 0xAE, 0x3C, 0xA4, 0x7E, 0xCC, 0x10, 0xEA }), KPRes.TriggerStateChange, PwIcon.Run, new EcasParameter[] { new EcasParameter(KPRes.TriggerName, EcasValueType.String, null), new EcasParameter(KPRes.NewState, EcasValueType.EnumStrings, new EcasEnum(new EcasEnumItem[] { new EcasEnumItem(IdTriggerOn, KPRes.On), new EcasEnumItem(IdTriggerOff, KPRes.Off), new EcasEnumItem(IdTriggerToggle, KPRes.Toggle) })) }, ChangeTriggerOnOff)); m_actions.Add(new EcasActionType(new PwUuid(new byte[] { 0xFD, 0x41, 0x55, 0xD5, 0x79, 0x8F, 0x44, 0xFA, 0xAB, 0x89, 0xF2, 0xF8, 0x70, 0xEF, 0x94, 0xB8 }), KPRes.OpenDatabaseFileStc, PwIcon.FolderOpen, new EcasParameter[] { new EcasParameter(KPRes.FileOrUrl, EcasValueType.String, null), new EcasParameter(KPRes.IOConnection + " - " + KPRes.UserName, EcasValueType.String, null), new EcasParameter(KPRes.IOConnection + " - " + KPRes.Password, EcasValueType.String, null), new EcasParameter(KPRes.Password, EcasValueType.String, null), new EcasParameter(KPRes.KeyFile, EcasValueType.String, null), new EcasParameter(KPRes.WindowsUserAccount, EcasValueType.Bool, null) }, OpenDatabaseFile)); m_actions.Add(new EcasActionType(new PwUuid(new byte[] { 0xF5, 0x57, 0x61, 0x4B, 0xF8, 0x4C, 0x41, 0x5D, 0xA9, 0x13, 0x7A, 0x39, 0xCD, 0x10, 0xF0, 0xBD }), KPRes.SaveDatabaseStc, PwIcon.Disk, null, SaveDatabaseFile)); m_actions.Add(new EcasActionType(new PwUuid(new byte[] { 0x22, 0xAD, 0x77, 0xE4, 0x17, 0x78, 0x4E, 0xED, 0x99, 0xB4, 0x57, 0x1D, 0x02, 0xB3, 0xAD, 0x4D }), KPRes.SynchronizeStc, PwIcon.PaperReady, new EcasParameter[] { new EcasParameter(KPRes.FileOrUrl, EcasValueType.String, null), new EcasParameter(KPRes.IOConnection + " - " + KPRes.UserName, EcasValueType.String, null), new EcasParameter(KPRes.IOConnection + " - " + KPRes.Password, EcasValueType.String, null) }, SyncDatabaseFile)); m_actions.Add(new EcasActionType(new PwUuid(new byte[] { 0x80, 0xE6, 0x7F, 0x4E, 0x72, 0xF1, 0x40, 0x45, 0x91, 0x76, 0x1F, 0x2C, 0x23, 0xD8, 0xEC, 0xBE }), KPRes.ImportStc, PwIcon.PaperReady, new EcasParameter[] { new EcasParameter(KPRes.FileOrUrl, EcasValueType.String, null), new EcasParameter(KPRes.FileFormatStc, EcasValueType.String, null), new EcasParameter(KPRes.Method, EcasValueType.EnumStrings, new EcasEnum(new EcasEnumItem[] { new EcasEnumItem((uint)PwMergeMethod.None, KPRes.Default), new EcasEnumItem((uint)PwMergeMethod.CreateNewUuids, StrUtil.RemoveAccelerator(KPRes.CreateNewIDs)), new EcasEnumItem((uint)PwMergeMethod.KeepExisting, StrUtil.RemoveAccelerator(KPRes.KeepExisting)), new EcasEnumItem((uint)PwMergeMethod.OverwriteExisting, StrUtil.RemoveAccelerator(KPRes.OverwriteExisting)), new EcasEnumItem((uint)PwMergeMethod.OverwriteIfNewer, StrUtil.RemoveAccelerator(KPRes.OverwriteIfNewer)), new EcasEnumItem((uint)PwMergeMethod.Synchronize, StrUtil.RemoveAccelerator(KPRes.OverwriteIfNewerAndApplyDel)) })), new EcasParameter(KPRes.Password, EcasValueType.String, null), new EcasParameter(KPRes.KeyFile, EcasValueType.String, null), new EcasParameter(KPRes.WindowsUserAccount, EcasValueType.Bool, null) }, ImportIntoCurrentDatabase)); m_actions.Add(new EcasActionType(new PwUuid(new byte[] { 0x0F, 0x9A, 0x6B, 0x5B, 0xCE, 0xD5, 0x46, 0xBE, 0xB9, 0x34, 0xED, 0xB1, 0x3F, 0x94, 0x48, 0x22 }), KPRes.ExportStc, PwIcon.Disk, new EcasParameter[] { new EcasParameter(KPRes.FileOrUrl, EcasValueType.String, null), new EcasParameter(KPRes.FileFormatStc, EcasValueType.String, null), new EcasParameter(KPRes.Filter + " - " + KPRes.Group, EcasValueType.String, null), new EcasParameter(KPRes.Filter + " - " + KPRes.Tag, EcasValueType.String, null) }, ExportDatabaseFile)); m_actions.Add(new EcasActionType(new PwUuid(new byte[] { 0x5B, 0xBF, 0x45, 0x9D, 0x54, 0xBF, 0x49, 0xBD, 0x97, 0xFB, 0x2C, 0xEE, 0x5F, 0x99, 0x0A, 0x67 }), KPRes.CloseActiveDatabase, PwIcon.PaperReady, null, CloseDatabaseFile)); m_actions.Add(new EcasActionType(new PwUuid(new byte[] { 0x3F, 0xB8, 0x33, 0x2D, 0xD6, 0x16, 0x4E, 0x87, 0x99, 0x05, 0x64, 0xDB, 0x16, 0x4C, 0xD6, 0x26 }), KPRes.ActivateDatabaseTab, PwIcon.List, new EcasParameter[] { new EcasParameter(KPRes.FileOrUrl, EcasValueType.String, null), new EcasParameter(KPRes.Filter, EcasValueType.EnumStrings, new EcasEnum(new EcasEnumItem[] { new EcasEnumItem(0, KPRes.All), new EcasEnumItem(1, KPRes.Triggering) })) }, ActivateDatabaseTab)); m_actions.Add(new EcasActionType(new PwUuid(new byte[] { 0x3B, 0x3D, 0x3E, 0x31, 0xE4, 0xB3, 0x42, 0xA6, 0xBA, 0xCC, 0xD5, 0xC0, 0x3B, 0xAC, 0xA9, 0x69 }), KPRes.Wait, PwIcon.Clock, new EcasParameter[] { new EcasParameter(KPRes.TimeSpan + @" [ms]", EcasValueType.UInt64, null) }, ExecuteSleep)); m_actions.Add(new EcasActionType(new PwUuid(new byte[] { 0x09, 0xF7, 0x8F, 0x73, 0x24, 0xEC, 0x4F, 0xEC, 0x88, 0xB6, 0x25, 0xD5, 0x30, 0xF4, 0x34, 0x6E }), KPRes.ShowMessageBox, PwIcon.UserCommunication, new EcasParameter[] { new EcasParameter(KPRes.MainInstruction, EcasValueType.String, null), new EcasParameter(KPRes.Text, EcasValueType.String, null), new EcasParameter(KPRes.Icon, EcasValueType.EnumStrings, new EcasEnum(new EcasEnumItem[] { new EcasEnumItem((uint)MessageBoxIcon.None, KPRes.None), new EcasEnumItem((uint)MessageBoxIcon.Information, "i"), new EcasEnumItem((uint)MessageBoxIcon.Question, "?"), new EcasEnumItem((uint)MessageBoxIcon.Warning, KPRes.Warning), new EcasEnumItem((uint)MessageBoxIcon.Error, KPRes.Error) })), new EcasParameter(KPRes.Buttons, EcasValueType.EnumStrings, new EcasEnum(new EcasEnumItem[] { new EcasEnumItem((uint)MessageBoxButtons.OK, KPRes.Ok), new EcasEnumItem((uint)MessageBoxButtons.OKCancel, KPRes.Ok + "/" + KPRes.Cancel), new EcasEnumItem((uint)MessageBoxButtons.YesNo, KPRes.Yes + "/" + KPRes.No) })), new EcasParameter(KPRes.ButtonDefault, EcasValueType.EnumStrings, new EcasEnum(new EcasEnumItem[] { new EcasEnumItem(0, KPRes.Button + " 1"), new EcasEnumItem(1, KPRes.Button + " 2") })), new EcasParameter(KPRes.Action + " - " + KPRes.Condition, EcasValueType.EnumStrings, new EcasEnum(new EcasEnumItem[] { new EcasEnumItem(IdMbcY, KPRes.Button + " " + KPRes.Ok + "/" + KPRes.Yes), new EcasEnumItem(IdMbcN, KPRes.Button + " " + KPRes.Cancel + "/" + KPRes.No) })), new EcasParameter(KPRes.Action, EcasValueType.EnumStrings, new EcasEnum(new EcasEnumItem[] { new EcasEnumItem(IdMbaNone, KPRes.None), new EcasEnumItem(IdMbaAbort, KPRes.AbortTrigger), new EcasEnumItem(IdMbaCmd, KPRes.ExecuteCmdLineUrl) })), new EcasParameter(KPRes.Action + " - " + KPRes.Parameters, EcasValueType.String, null) }, ShowMessageBox)); m_actions.Add(new EcasActionType(new PwUuid(new byte[] { 0x40, 0x69, 0xA5, 0x36, 0x57, 0x1B, 0x47, 0x92, 0xA9, 0xB3, 0x73, 0x65, 0x30, 0xE0, 0xCF, 0xC3 }), KPRes.PerformGlobalAutoType, PwIcon.Run, null, ExecuteGlobalAutoType)); m_actions.Add(new EcasActionType(new PwUuid(new byte[] { 0x31, 0x70, 0x8F, 0xAD, 0x64, 0x93, 0x43, 0xF5, 0x94, 0xEE, 0xC8, 0x1A, 0x23, 0x6E, 0x32, 0x4D }), KPRes.PerformSelectedAutoType, PwIcon.Run, new EcasParameter[] { new EcasParameter(KPRes.Sequence, EcasValueType.String, null) }, ExecuteSelectedAutoType)); m_actions.Add(new EcasActionType(new PwUuid(new byte[] { 0x42, 0xE8, 0x37, 0x81, 0x73, 0xD3, 0x4E, 0xEC, 0x81, 0x48, 0x9E, 0x3B, 0x36, 0xAC, 0x83, 0x84 }), KPRes.ShowEntriesByTag, PwIcon.List, new EcasParameter[] { new EcasParameter(KPRes.Tag, EcasValueType.String, null) }, ShowEntriesByTag)); m_actions.Add(new EcasActionType(new PwUuid(new byte[] { 0x95, 0x81, 0x8F, 0x45, 0x99, 0x66, 0x49, 0x88, 0xAB, 0x3E, 0x86, 0xE8, 0x1A, 0x96, 0x68, 0x36 }), KPRes.CustomTbButtonAdd, PwIcon.Screen, new EcasParameter[] { new EcasParameter(KPRes.Id, EcasValueType.String, null), new EcasParameter(KPRes.Name, EcasValueType.String, null), new EcasParameter(KPRes.Description, EcasValueType.String, null) }, AddToolBarButton)); m_actions.Add(new EcasActionType(new PwUuid(new byte[] { 0xD6, 0x6D, 0x41, 0xA2, 0x6C, 0xB2, 0x44, 0xBA, 0xA4, 0x48, 0x0A, 0x41, 0xFA, 0x09, 0x48, 0x79 }), KPRes.CustomTbButtonRemove, PwIcon.Screen, new EcasParameter[] { new EcasParameter(KPRes.Id, EcasValueType.String, null) }, RemoveToolBarButton)); } private static void ExecuteShellCmd(EcasAction a, EcasContext ctx) { string strCmd = EcasUtil.GetParamString(a.Parameters, 0, true, true); string strArgs = EcasUtil.GetParamString(a.Parameters, 1, true, true); bool bWait = StrUtil.StringToBool(EcasUtil.GetParamString(a.Parameters, 2, string.Empty)); uint uWindowStyle = EcasUtil.GetParamUInt(a.Parameters, 3); string strVerb = EcasUtil.GetParamString(a.Parameters, 4, true); if(string.IsNullOrEmpty(strCmd)) return; try { ProcessStartInfo psi = new ProcessStartInfo(strCmd); if(!string.IsNullOrEmpty(strArgs)) psi.Arguments = strArgs; bool bShEx = true; if(!string.IsNullOrEmpty(strVerb)) { } // Need ShellExecute else if((uWindowStyle == IdWindowMin) || (uWindowStyle == IdWindowMax)) { } // Need ShellExecute else { string strCmdFlt = strCmd.TrimEnd(new char[] { '\"', '\'', ' ', '\t', '\r', '\n' }); if(strCmdFlt.EndsWith(".exe", StrUtil.CaseIgnoreCmp) || strCmdFlt.EndsWith(".com", StrUtil.CaseIgnoreCmp)) bShEx = false; } psi.UseShellExecute = bShEx; if(uWindowStyle == IdWindowHidden) { psi.CreateNoWindow = true; psi.WindowStyle = ProcessWindowStyle.Hidden; } else if(uWindowStyle == IdWindowMin) psi.WindowStyle = ProcessWindowStyle.Minimized; else if(uWindowStyle == IdWindowMax) psi.WindowStyle = ProcessWindowStyle.Maximized; if(!string.IsNullOrEmpty(strVerb)) psi.Verb = strVerb; Process p = Process.Start(psi); if((p != null) && bWait) { Program.MainForm.UIBlockInteraction(true); MessageService.ExternalIncrementMessageCount(); try { p.WaitForExit(); } catch(Exception) { Debug.Assert(false); } MessageService.ExternalDecrementMessageCount(); Program.MainForm.UIBlockInteraction(false); } } catch(Exception e) { throw new Exception(strCmd + MessageService.NewParagraph + e.Message); } } private static void ChangeTriggerOnOff(EcasAction a, EcasContext ctx) { string strName = EcasUtil.GetParamString(a.Parameters, 0, true); uint uState = EcasUtil.GetParamUInt(a.Parameters, 1); EcasTrigger t = null; if(strName.Length == 0) t = ctx.Trigger; else { foreach(EcasTrigger trg in ctx.TriggerSystem.TriggerCollection) { if(trg.Name == strName) { t = trg; break; } } } if(t == null) throw new Exception(KPRes.ObjectNotFound + MessageService.NewParagraph + KPRes.TriggerName + ": " + strName + "."); if(uState == IdTriggerOn) t.On = true; else if(uState == IdTriggerOff) t.On = false; else if(uState == IdTriggerToggle) t.On = !t.On; else { Debug.Assert(false); } } private static void OpenDatabaseFile(EcasAction a, EcasContext ctx) { string strPath = EcasUtil.GetParamString(a.Parameters, 0, true); if(string.IsNullOrEmpty(strPath)) return; string strIOUserName = EcasUtil.GetParamString(a.Parameters, 1, true); string strIOPassword = EcasUtil.GetParamString(a.Parameters, 2, true); IOConnectionInfo ioc = IOFromParameters(strPath, strIOUserName, strIOPassword); if(ioc == null) return; CompositeKey cmpKey = KeyFromParams(a, 3, 4, 5); Program.MainForm.OpenDatabase(ioc, cmpKey, ioc.IsLocalFile()); } private static CompositeKey KeyFromParams(EcasAction a, int iPassword, int iKeyFile, int iUserAccount) { string strPassword = EcasUtil.GetParamString(a.Parameters, iPassword, true); string strKeyFile = EcasUtil.GetParamString(a.Parameters, iKeyFile, true); bool bUserAccount = StrUtil.StringToBool(EcasUtil.GetParamString( a.Parameters, iUserAccount, true)); CompositeKey cmpKey = null; if(!string.IsNullOrEmpty(strPassword) || !string.IsNullOrEmpty(strKeyFile) || bUserAccount) { List vArgs = new List(); if(!string.IsNullOrEmpty(strPassword)) vArgs.Add("-" + AppDefs.CommandLineOptions.Password + ":" + strPassword); if(!string.IsNullOrEmpty(strKeyFile)) vArgs.Add("-" + AppDefs.CommandLineOptions.KeyFile + ":" + strKeyFile); if(bUserAccount) vArgs.Add("-" + AppDefs.CommandLineOptions.UserAccount); CommandLineArgs cmdArgs = new CommandLineArgs(vArgs.ToArray()); cmpKey = KeyUtil.KeyFromCommandLine(cmdArgs); } return cmpKey; } private static void SaveDatabaseFile(EcasAction a, EcasContext ctx) { Program.MainForm.UIFileSave(false); } private static void SyncDatabaseFile(EcasAction a, EcasContext ctx) { string strPath = EcasUtil.GetParamString(a.Parameters, 0, true); if(string.IsNullOrEmpty(strPath)) return; string strIOUserName = EcasUtil.GetParamString(a.Parameters, 1, true); string strIOPassword = EcasUtil.GetParamString(a.Parameters, 2, true); IOConnectionInfo ioc = IOFromParameters(strPath, strIOUserName, strIOPassword); if(ioc == null) return; PwDatabase pd = Program.MainForm.ActiveDatabase; if((pd == null) || !pd.IsOpen) return; bool? b = ImportUtil.Synchronize(pd, Program.MainForm, ioc, false, Program.MainForm); Program.MainForm.UpdateUI(false, null, true, null, true, null, false); if(b.HasValue) Program.MainForm.SetStatusEx(b.Value ? KPRes.SyncSuccess : KPRes.SyncFailed); } private static IOConnectionInfo IOFromParameters(string strPath, string strUser, string strPassword) { IOConnectionInfo ioc = IOConnectionInfo.FromPath(strPath); // Set the user name, which acts as a filter for the MRU items if(!string.IsNullOrEmpty(strUser)) ioc.UserName = strUser; // Try to complete it using the MRU list; this will especially // retrieve the CredSaveMode of the MRU item (if one exists) ioc = Program.MainForm.CompleteConnectionInfoUsingMru(ioc); // Override the password using the trigger value; do not change // the CredSaveMode anymore (otherwise e.g. values retrieved // using field references would be stored in the MRU list) if(!string.IsNullOrEmpty(strPassword)) ioc.Password = strPassword; if(ioc.Password.Length > 0) ioc.IsComplete = true; return MainForm.CompleteConnectionInfo(ioc, false, true, true, false); } private static void ImportIntoCurrentDatabase(EcasAction a, EcasContext ctx) { PwDatabase pd = Program.MainForm.ActiveDatabase; if((pd == null) || !pd.IsOpen) return; string strPath = EcasUtil.GetParamString(a.Parameters, 0, true); if(string.IsNullOrEmpty(strPath)) return; IOConnectionInfo ioc = IOConnectionInfo.FromPath(strPath); string strFormat = EcasUtil.GetParamString(a.Parameters, 1, true); if(string.IsNullOrEmpty(strFormat)) return; FileFormatProvider ff = Program.FileFormatPool.Find(strFormat); if(ff == null) throw new Exception(KPRes.Unknown + ": " + strFormat); uint uMethod = EcasUtil.GetParamUInt(a.Parameters, 2); Type tMM = Enum.GetUnderlyingType(typeof(PwMergeMethod)); object oMethod = Convert.ChangeType(uMethod, tMM); PwMergeMethod mm = PwMergeMethod.None; if(Enum.IsDefined(typeof(PwMergeMethod), oMethod)) mm = (PwMergeMethod)oMethod; else { Debug.Assert(false); } if(mm == PwMergeMethod.None) mm = PwMergeMethod.CreateNewUuids; CompositeKey cmpKey = KeyFromParams(a, 3, 4, 5); if((cmpKey == null) && ff.RequiresKey) { KeyPromptForm kpf = new KeyPromptForm(); kpf.InitEx(ioc, false, true); if(UIUtil.ShowDialogNotValue(kpf, DialogResult.OK)) return; cmpKey = kpf.CompositeKey; UIUtil.DestroyForm(kpf); } bool? b = true; try { b = ImportUtil.Import(pd, ff, ioc, mm, cmpKey); } finally { if(b.GetValueOrDefault(false)) Program.MainForm.UpdateUI(false, null, true, null, true, null, true); } } private static void ExportDatabaseFile(EcasAction a, EcasContext ctx) { string strPath = EcasUtil.GetParamString(a.Parameters, 0, true); // if(string.IsNullOrEmpty(strPath)) return; // Allow no-file exports string strFormat = EcasUtil.GetParamString(a.Parameters, 1, true); if(string.IsNullOrEmpty(strFormat)) return; string strGroup = EcasUtil.GetParamString(a.Parameters, 2, true); string strTag = EcasUtil.GetParamString(a.Parameters, 3, true); PwDatabase pd = Program.MainForm.ActiveDatabase; if((pd == null) || !pd.IsOpen) return; PwGroup pg = pd.RootGroup; if(!string.IsNullOrEmpty(strGroup)) { char chSep = strGroup[0]; PwGroup pgSub = pg.FindCreateSubTree(strGroup.Substring(1), new char[] { chSep }, false); pg = (pgSub ?? (new PwGroup(true, true, KPRes.Group, PwIcon.Folder))); } if(!string.IsNullOrEmpty(strTag)) { // Do not use pg.Duplicate, because this method // creates new UUIDs pg = pg.CloneDeep(); pg.TakeOwnership(true, true, true); GroupHandler gh = delegate(PwGroup pgSub) { PwObjectList l = pgSub.Entries; long n = (long)l.UCount; for(long i = n - 1; i >= 0; --i) { if(!l.GetAt((uint)i).HasTag(strTag)) l.RemoveAt((uint)i); } return true; }; gh(pg); pg.TraverseTree(TraversalMethod.PreOrder, gh, null); } PwExportInfo pei = new PwExportInfo(pg, pd, true); IOConnectionInfo ioc = (!string.IsNullOrEmpty(strPath) ? IOConnectionInfo.FromPath(strPath) : null); ExportUtil.Export(pei, strFormat, ioc); } private static void CloseDatabaseFile(EcasAction a, EcasContext ctx) { Program.MainForm.CloseDocument(null, false, false, true, true); } private static void ActivateDatabaseTab(EcasAction a, EcasContext ctx) { string strName = EcasUtil.GetParamString(a.Parameters, 0, true); bool bEmptyName = string.IsNullOrEmpty(strName); uint uSel = EcasUtil.GetParamUInt(a.Parameters, 1, 0); PwDatabase pdSel = ctx.Properties.Get(EcasProperty.Database); DocumentManagerEx dm = Program.MainForm.DocumentManager; foreach(PwDocument doc in dm.Documents) { if(doc.Database == null) { Debug.Assert(false); continue; } if(uSel == 0) // Select from all { if(bEmptyName) continue; // Name required in this case } else if(uSel == 1) // Triggering only { if(!object.ReferenceEquals(doc.Database, pdSel)) continue; } else { Debug.Assert(false); continue; } IOConnectionInfo ioc = null; if((doc.LockedIoc != null) && !string.IsNullOrEmpty(doc.LockedIoc.Path)) ioc = doc.LockedIoc; else if((doc.Database.IOConnectionInfo != null) && !string.IsNullOrEmpty(doc.Database.IOConnectionInfo.Path)) ioc = doc.Database.IOConnectionInfo; if(bEmptyName || ((ioc != null) && (ioc.Path.IndexOf(strName, StrUtil.CaseIgnoreCmp) >= 0))) { Program.MainForm.MakeDocumentActive(doc); break; } } } private static void ExecuteSleep(EcasAction a, EcasContext ctx) { uint uTimeSpan = EcasUtil.GetParamUInt(a.Parameters, 0); if((uTimeSpan != 0) && (uTimeSpan <= (uint)int.MaxValue)) Thread.Sleep((int)uTimeSpan); } private static void ExecuteGlobalAutoType(EcasAction a, EcasContext ctx) { Program.MainForm.ExecuteGlobalAutoType(); } private static void ExecuteSelectedAutoType(EcasAction a, EcasContext ctx) { try { // Do not Spr-compile the sequence here; it'll be compiled by // the auto-type engine (and this expects an auto-type sequence // as input, not a data string; compiling it here would e.g. // result in broken '%' characters in passwords) string strSeq = EcasUtil.GetParamString(a.Parameters, 0, false); if(string.IsNullOrEmpty(strSeq)) strSeq = null; PwEntry pe = Program.MainForm.GetSelectedEntry(true); if(pe == null) return; PwDatabase pd = Program.MainForm.DocumentManager.SafeFindContainerOf(pe); IntPtr hFg = NativeMethods.GetForegroundWindowHandle(); if(AutoType.IsOwnWindow(hFg)) AutoType.PerformIntoPreviousWindow(Program.MainForm, pe, pd, strSeq); else AutoType.PerformIntoCurrentWindow(pe, pd, strSeq); } catch(Exception) { Debug.Assert(false); } } private static void ShowEntriesByTag(EcasAction a, EcasContext ctx) { string strTag = EcasUtil.GetParamString(a.Parameters, 0, true); Program.MainForm.ShowEntriesByTag(strTag); } private static void AddToolBarButton(EcasAction a, EcasContext ctx) { string strID = EcasUtil.GetParamString(a.Parameters, 0, true); string strName = EcasUtil.GetParamString(a.Parameters, 1, true); string strDesc = EcasUtil.GetParamString(a.Parameters, 2, true); Program.MainForm.AddCustomToolBarButton(strID, strName, strDesc); } private static void RemoveToolBarButton(EcasAction a, EcasContext ctx) { string strID = EcasUtil.GetParamString(a.Parameters, 0, true); Program.MainForm.RemoveCustomToolBarButton(strID); } private static void ShowMessageBox(EcasAction a, EcasContext ctx) { VistaTaskDialog vtd = new VistaTaskDialog(); string strMain = EcasUtil.GetParamString(a.Parameters, 0, true); if(!string.IsNullOrEmpty(strMain)) vtd.MainInstruction = strMain; string strText = EcasUtil.GetParamString(a.Parameters, 1, true); if(!string.IsNullOrEmpty(strText)) vtd.Content = strText; uint uIcon = EcasUtil.GetParamUInt(a.Parameters, 2, 0); if(uIcon == (uint)MessageBoxIcon.Information) vtd.SetIcon(VtdIcon.Information); else if(uIcon == (uint)MessageBoxIcon.Question) vtd.SetIcon(VtdCustomIcon.Question); else if(uIcon == (uint)MessageBoxIcon.Warning) vtd.SetIcon(VtdIcon.Warning); else if(uIcon == (uint)MessageBoxIcon.Error) vtd.SetIcon(VtdIcon.Error); else { Debug.Assert(uIcon == (uint)MessageBoxIcon.None); } vtd.CommandLinks = false; uint uBtns = EcasUtil.GetParamUInt(a.Parameters, 3, 0); bool bCanCancel = false; if(uBtns == (uint)MessageBoxButtons.OKCancel) { vtd.AddButton((int)DialogResult.OK, KPRes.Ok, null); vtd.AddButton((int)DialogResult.Cancel, KPRes.Cancel, null); bCanCancel = true; } else if(uBtns == (uint)MessageBoxButtons.YesNo) { vtd.AddButton((int)DialogResult.OK, KPRes.YesCmd, null); vtd.AddButton((int)DialogResult.Cancel, KPRes.NoCmd, null); bCanCancel = true; } else vtd.AddButton((int)DialogResult.OK, KPRes.Ok, null); uint uDef = EcasUtil.GetParamUInt(a.Parameters, 4, 0); ReadOnlyCollection lButtons = vtd.Buttons; if(uDef < (uint)lButtons.Count) vtd.DefaultButtonID = lButtons[(int)uDef].ID; vtd.WindowTitle = PwDefs.ShortProductName; string strTrg = ctx.Trigger.Name; if(!string.IsNullOrEmpty(strTrg)) { vtd.FooterText = KPRes.Trigger + @": '" + strTrg + @"'."; vtd.SetFooterIcon(VtdIcon.Information); } int dr; if(vtd.ShowDialog()) dr = vtd.Result; else { string str = (strMain ?? string.Empty); if(!string.IsNullOrEmpty(strText)) { if(str.Length > 0) str += MessageService.NewParagraph; str += strText; } MessageBoxDefaultButton mbdb = MessageBoxDefaultButton.Button1; if(uDef == 1) mbdb = MessageBoxDefaultButton.Button2; else if(uDef == 2) mbdb = MessageBoxDefaultButton.Button3; MessageService.ExternalIncrementMessageCount(); try { dr = (int)MessageService.SafeShowMessageBox(str, PwDefs.ShortProductName, (MessageBoxButtons)uBtns, (MessageBoxIcon)uIcon, mbdb); } finally { MessageService.ExternalDecrementMessageCount(); } } uint uActCondID = EcasUtil.GetParamUInt(a.Parameters, 5, 0); bool bDrY = ((dr == (int)DialogResult.OK) || (dr == (int)DialogResult.Yes)); bool bDrN = ((dr == (int)DialogResult.Cancel) || (dr == (int)DialogResult.No)); bool bPerformAction = (((uActCondID == IdMbcY) && bDrY) || ((uActCondID == IdMbcN) && bDrN)); if(!bPerformAction) return; uint uActID = EcasUtil.GetParamUInt(a.Parameters, 6, 0); string strActionParam = EcasUtil.GetParamString(a.Parameters, 7, true); if(uActID == IdMbaNone) { } else if(uActID == IdMbaAbort) { if(bCanCancel) ctx.Cancel = true; } else if(uActID == IdMbaCmd) { if(!string.IsNullOrEmpty(strActionParam)) WinUtil.OpenUrl(strActionParam, null); } else { Debug.Assert(false); } } } } KeePass/Ecas/EcasEvent.cs0000664000000000000000000000417613222430406014174 0ustar rootroot/* KeePass Password Safe - The Open-Source Password Manager Copyright (C) 2003-2018 Dominik Reichl This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ using System; using System.Collections.Generic; using System.Text; using System.Xml.Serialization; using KeePassLib; using KeePassLib.Interfaces; namespace KeePass.Ecas { public sealed class EcasEvent : IDeepCloneable, IEcasObject { private PwUuid m_type = PwUuid.Zero; [XmlIgnore] public PwUuid Type { get { return m_type; } set { if(value == null) throw new ArgumentNullException("value"); m_type = value; } } [XmlElement("TypeGuid")] public string TypeString { get { return Convert.ToBase64String(m_type.UuidBytes, Base64FormattingOptions.None); } set { if(value == null) throw new ArgumentNullException("value"); m_type = new PwUuid(Convert.FromBase64String(value)); } } private List m_params = new List(); [XmlArrayItem("Parameter")] public List Parameters { get { return m_params; } set { if(value == null) throw new ArgumentNullException("value"); m_params = value; } } public EcasEvent() { } public EcasEvent CloneDeep() { EcasEvent e = new EcasEvent(); e.m_type = m_type; // PwUuid is immutable for(int i = 0; i < m_params.Count; ++i) e.m_params.Add(m_params[i]); return e; } } } KeePass/Ecas/EcasEventProvider.cs0000664000000000000000000000445013222430406015702 0ustar rootroot/* KeePass Password Safe - The Open-Source Password Manager Copyright (C) 2003-2018 Dominik Reichl This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ using System; using System.Collections.Generic; using System.Text; using System.Diagnostics; using KeePassLib; namespace KeePass.Ecas { public abstract class EcasEventProvider { protected List m_events = new List(); internal List Events { get { return m_events; } } public bool IsSupported(PwUuid uuidType) { if(uuidType == null) throw new ArgumentNullException("uuidType"); foreach(EcasEventType t in m_events) { if(t.Type.Equals(uuidType)) return true; } return false; } public EcasEventType Find(string strEventName) { if(strEventName == null) throw new ArgumentNullException("strEventName"); foreach(EcasEventType t in m_events) { if(t.Name == strEventName) return t; } return null; } public EcasEventType Find(PwUuid uuid) { if(uuid == null) throw new ArgumentNullException("uuid"); foreach(EcasEventType t in m_events) { if(t.Type.Equals(uuid)) return t; } return null; } public bool Compare(EcasEvent e, EcasContext ctx) { if(e == null) throw new ArgumentNullException("e"); if(ctx == null) throw new ArgumentNullException("ctx"); Debug.Assert(e.Type.Equals(ctx.Event.Type)); foreach(EcasEventType t in m_events) { if(t.Type.Equals(e.Type)) return t.CompareMethod(e, ctx); } throw new NotSupportedException(); } } } KeePass/Ecas/EcasEnum.cs0000664000000000000000000000500013222430406014002 0ustar rootroot/* KeePass Password Safe - The Open-Source Password Manager Copyright (C) 2003-2018 Dominik Reichl This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ using System; using System.Collections.Generic; using System.Text; using KeePass.Resources; using KeePassLib.Utility; namespace KeePass.Ecas { public sealed class EcasEnum { private EcasEnumItem[] m_vItems; public EcasEnumItem[] Items { get { return m_vItems; } } public int ItemCount { get { return m_vItems.Length; } } public EcasEnum(EcasEnumItem[] vItems) { if(vItems == null) throw new ArgumentNullException("vItems"); m_vItems = vItems; } public uint GetItemID(string strName, uint uDefaultIfNotFound) { if(strName == null) throw new ArgumentNullException("strName"); foreach(EcasEnumItem e in m_vItems) { if(e.Name == strName) return e.ID; } return uDefaultIfNotFound; } ///

/// Get the localized descriptive text of an enumeration item. /// /// ID of the enumeration item. /// Default value, may be null. /// Localized enumeration item text or the default value. public string GetItemString(uint uID, string strDefaultIfNotFound) { foreach(EcasEnumItem e in m_vItems) { if(e.ID == uID) return e.Name; } return strDefaultIfNotFound; } } public sealed class EcasEnumItem { private uint m_id; public uint ID { get { return m_id; } } private string m_name; public string Name { get { return m_name; } } public EcasEnumItem(uint uID, string strName) { if(strName == null) throw new ArgumentNullException("strName"); m_id = uID; m_name = strName; } } } KeePass/Ecas/EcasActionType.cs0000664000000000000000000000442113222430406015163 0ustar rootroot/* KeePass Password Safe - The Open-Source Password Manager Copyright (C) 2003-2018 Dominik Reichl This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ using System; using System.Collections.Generic; using System.Text; using KeePassLib; namespace KeePass.Ecas { public delegate void EcasActionExecute(EcasAction a, EcasContext ctx); public sealed class EcasActionType : IEcasParameterized { private PwUuid m_type; public PwUuid Type { get { return m_type; } } private string m_strName; public string Name { get { return m_strName; } } private PwIcon m_pwIcon; public PwIcon Icon { get { return m_pwIcon; } } private EcasParameter[] m_vParams; public EcasParameter[] Parameters { get { return m_vParams; } } private EcasActionExecute m_fn; public EcasActionExecute ExecuteMethod { get { return m_fn; } } private static void EcasActionExecuteNull(EcasAction a, EcasContext ctx) { } public EcasActionType(PwUuid uuidType, string strName, PwIcon pwIcon, EcasParameter[] vParams, EcasActionExecute f) { if((uuidType == null) || PwUuid.Zero.Equals(uuidType)) throw new ArgumentNullException("uuidType"); if(strName == null) throw new ArgumentNullException("strName"); // if(vParams == null) throw new ArgumentNullException("vParams"); // if(f == null) throw new ArgumentNullException("f"); m_type = uuidType; m_strName = strName; m_pwIcon = pwIcon; m_vParams = (vParams ?? EcasParameter.EmptyArray); m_fn = (f ?? EcasActionExecuteNull); } } } KeePass/Ecas/EcasDefaultConditionProvider.cs0000664000000000000000000001432113222430406020052 0ustar rootroot/* KeePass Password Safe - The Open-Source Password Manager Copyright (C) 2003-2018 Dominik Reichl This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ using System; using System.Collections.Generic; using System.Text; using System.IO; using System.Net.NetworkInformation; using System.Windows.Forms; using System.Diagnostics; using KeePass.Resources; using KeePass.UI; using KeePassLib; using KeePassLib.Serialization; using KeePassLib.Utility; namespace KeePass.Ecas { internal sealed class EcasDefaultConditionProvider : EcasConditionProvider { public EcasDefaultConditionProvider() { m_conditions.Add(new EcasConditionType(new PwUuid(new byte[] { 0x9F, 0x11, 0xD0, 0xBD, 0xEC, 0xE9, 0x45, 0x3B, 0xA5, 0x45, 0x26, 0x1F, 0xF7, 0xA4, 0xFF, 0x1F }), KPRes.EnvironmentVariable, PwIcon.Console, new EcasParameter[] { new EcasParameter(KPRes.Name, EcasValueType.String, null), new EcasParameter(KPRes.Value + " - " + KPRes.Comparison, EcasValueType.EnumStrings, EcasUtil.StdStringCompare), new EcasParameter(KPRes.Value, EcasValueType.String, null) }, IsMatchEnvironmentVar)); m_conditions.Add(new EcasConditionType(new PwUuid(new byte[] { 0xB9, 0x0F, 0xF8, 0x07, 0x73, 0x38, 0x4F, 0xEA, 0xBB, 0x2E, 0xBC, 0x0B, 0xEA, 0x3B, 0x98, 0xC3 }), KPRes.String, PwIcon.Configuration, new EcasParameter[] { new EcasParameter(KPRes.String, EcasValueType.String, null), new EcasParameter(KPRes.Value + " - " + KPRes.Comparison, EcasValueType.EnumStrings, EcasUtil.StdStringCompare), new EcasParameter(KPRes.Value, EcasValueType.String, null) }, IsMatchString)); m_conditions.Add(new EcasConditionType(new PwUuid(new byte[] { 0xCB, 0x4A, 0x9E, 0x34, 0x56, 0x8C, 0x4C, 0x95, 0xAD, 0x67, 0x4D, 0x1C, 0xA1, 0x04, 0x19, 0xBC }), KPRes.FileExists, PwIcon.PaperReady, new EcasParameter[] { new EcasParameter(KPRes.FileOrUrl, EcasValueType.String, null) }, IsMatchFileExists)); m_conditions.Add(new EcasConditionType(new PwUuid(new byte[] { 0x2A, 0x22, 0x83, 0xA8, 0x9D, 0x13, 0x41, 0xE8, 0x99, 0x87, 0x8B, 0xAC, 0x21, 0x8D, 0x81, 0xF4 }), KPRes.RemoteHostReachable, PwIcon.NetworkServer, new EcasParameter[] { new EcasParameter(KPRes.Host, EcasValueType.String, null) }, IsHostReachable)); m_conditions.Add(new EcasConditionType(new PwUuid(new byte[] { 0xD3, 0xCA, 0xFA, 0xEF, 0x28, 0x2A, 0x46, 0x4A, 0x99, 0x90, 0xD8, 0x65, 0xFC, 0xE0, 0x16, 0xED }), KPRes.DatabaseHasUnsavedChanges, PwIcon.PaperFlag, new EcasParameter[] { new EcasParameter(KPRes.Database, EcasValueType.EnumStrings, new EcasEnum(new EcasEnumItem[] { new EcasEnumItem(0, KPRes.Active), new EcasEnumItem(1, KPRes.Triggering) })) }, IsDatabaseModified)); } private static bool IsMatchEnvironmentVar(EcasCondition c, EcasContext ctx) { string strName = EcasUtil.GetParamString(c.Parameters, 0, true); uint uCompareType = EcasUtil.GetParamEnum(c.Parameters, 1, EcasUtil.StdStringCompareEquals, EcasUtil.StdStringCompare); string strValue = EcasUtil.GetParamString(c.Parameters, 2, true); if(string.IsNullOrEmpty(strName) || (strValue == null)) return false; try { string strVar = Environment.GetEnvironmentVariable(strName); if(strVar == null) return false; return EcasUtil.CompareStrings(strVar, strValue, uCompareType); } catch(Exception) { Debug.Assert(false); } return false; } private static bool IsMatchString(EcasCondition c, EcasContext ctx) { string str = EcasUtil.GetParamString(c.Parameters, 0, true); uint uCompareType = EcasUtil.GetParamEnum(c.Parameters, 1, EcasUtil.StdStringCompareEquals, EcasUtil.StdStringCompare); string strValue = EcasUtil.GetParamString(c.Parameters, 2, true); if((str == null) || (strValue == null)) return false; return EcasUtil.CompareStrings(str, strValue, uCompareType); } private static bool IsMatchFileExists(EcasCondition c, EcasContext ctx) { string strFile = EcasUtil.GetParamString(c.Parameters, 0, true); if(string.IsNullOrEmpty(strFile)) return true; try { // return File.Exists(strFile); IOConnectionInfo ioc = IOConnectionInfo.FromPath(strFile); return IOConnection.FileExists(ioc); } catch(Exception) { } return false; } private static bool IsHostReachable(EcasCondition c, EcasContext ctx) { string strHost = EcasUtil.GetParamString(c.Parameters, 0, true); if(string.IsNullOrEmpty(strHost)) return true; int[] vTimeOuts = { 250, 1250 }; const string strBuffer = "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"; byte[] pbBuffer = Encoding.ASCII.GetBytes(strBuffer); try { Ping ping = new Ping(); // We have sufficient privileges? PingOptions options = new PingOptions(64, true); foreach(int nTimeOut in vTimeOuts) { PingReply reply = ping.Send(strHost, nTimeOut, pbBuffer, options); if(reply.Status == IPStatus.Success) return true; } return false; } catch(Exception) { } return false; } private static bool IsDatabaseModified(EcasCondition c, EcasContext ctx) { PwDatabase pd = null; uint uSel = EcasUtil.GetParamUInt(c.Parameters, 0, 0); if(uSel == 0) pd = Program.MainForm.ActiveDatabase; else if(uSel == 1) pd = ctx.Properties.Get(EcasProperty.Database); else { Debug.Assert(false); } if((pd == null) || !pd.IsOpen) return false; return pd.Modified; } } } KeePass/Ecas/EcasUtil.cs0000664000000000000000000003703313222430406014026 0ustar rootroot/* KeePass Password Safe - The Open-Source Password Manager Copyright (C) 2003-2018 Dominik Reichl This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ using System; using System.Collections.Generic; using System.Text; using System.Diagnostics; using System.Windows.Forms; using System.Drawing; using KeePass.Ecas; using KeePass.Resources; using KeePass.UI; using KeePass.Util.Spr; using KeePassLib; using KeePassLib.Utility; namespace KeePass.Ecas { public enum EcasTypeDxMode // Type data exchange modes { None = 0, Selection, // DX with the type UI control (combobox) ParamsTag // Get type from the parameters control } public static class EcasUtil { public const uint StdCompareEqual = 0; public const uint StdCompareNotEqual = 1; public const uint StdCompareLesser = 2; public const uint StdCompareLesserEqual = 3; public const uint StdCompareGreater = 4; public const uint StdCompareGreaterEqual = 5; private static EcasEnum m_enumCompare = null; public static EcasEnum StdCompare { get { if(m_enumCompare == null) m_enumCompare = new EcasEnum(new EcasEnumItem[] { new EcasEnumItem(StdCompareEqual, "="), new EcasEnumItem(StdCompareNotEqual, "<>"), new EcasEnumItem(StdCompareLesser, "<"), new EcasEnumItem(StdCompareLesserEqual, "<="), new EcasEnumItem(StdCompareGreater, ">"), new EcasEnumItem(StdCompareGreaterEqual, ">=") }); return m_enumCompare; } } public const uint StdStringCompareEquals = 0; public const uint StdStringCompareContains = 1; public const uint StdStringCompareStartsWith = 2; public const uint StdStringCompareEndsWith = 3; private static EcasEnum m_enumStringCompare = null; public static EcasEnum StdStringCompare { get { if(m_enumStringCompare == null) m_enumStringCompare = new EcasEnum(new EcasEnumItem[] { new EcasEnumItem(StdStringCompareEquals, KPRes.EqualsOp), new EcasEnumItem(StdStringCompareContains, KPRes.ContainsOp), new EcasEnumItem(StdStringCompareStartsWith, KPRes.StartsWith), new EcasEnumItem(StdStringCompareEndsWith, KPRes.EndsWith) }); return m_enumStringCompare; } } public static string GetParamString(List vParams, int iIndex) { return GetParamString(vParams, iIndex, string.Empty); } public static string GetParamString(List vParams, int iIndex, bool bSprCompile) { return GetParamString(vParams, iIndex, bSprCompile, false); } public static string GetParamString(List vParams, int iIndex, bool bSprCompile, bool bSprForCommandLine) { string str = GetParamString(vParams, iIndex, string.Empty); if(bSprCompile && !string.IsNullOrEmpty(str)) { PwEntry pe = null; try { pe = Program.MainForm.GetSelectedEntry(false); } catch(Exception) { Debug.Assert(false); } PwDatabase pd = Program.MainForm.DocumentManager.SafeFindContainerOf(pe); str = SprEngine.Compile(str, new SprContext(pe, pd, SprCompileFlags.All, false, bSprForCommandLine)); } return str; } public static string GetParamString(List vParams, int iIndex, string strDefault) { if(vParams == null) { Debug.Assert(false); return strDefault; } if(iIndex < 0) { Debug.Assert(false); return strDefault; } if(iIndex >= vParams.Count) return strDefault; // No assert return vParams[iIndex]; } public static uint GetParamUInt(List vParams, int iIndex) { return GetParamUInt(vParams, iIndex, 0); } public static uint GetParamUInt(List vParams, int iIndex, uint uDefault) { string str = GetParamString(vParams, iIndex, string.Empty); uint u; if(uint.TryParse(str, out u)) return u; return uDefault; } public static uint GetParamEnum(List vParams, int iIndex, uint uDefault, EcasEnum enumItems) { if(enumItems == null) { Debug.Assert(false); return uDefault; } string str = GetParamString(vParams, iIndex, null); if(string.IsNullOrEmpty(str)) { Debug.Assert(false); return uDefault; } uint uID; if(!uint.TryParse(str, out uID)) { Debug.Assert(false); return uDefault; } // Make sure the enumeration contains the value if(enumItems.GetItemString(uID, null) == null) { Debug.Assert(false); return uDefault; } return uID; } public static void ParametersToDataGridView(DataGridView dg, IEcasParameterized p, IEcasObject objDefaults) { if(dg == null) throw new ArgumentNullException("dg"); if(p == null) throw new ArgumentNullException("p"); if(p.Parameters == null) throw new ArgumentException(); if(objDefaults == null) throw new ArgumentNullException("objDefaults"); if(objDefaults.Parameters == null) throw new ArgumentException(); dg.Rows.Clear(); dg.Columns.Clear(); Color clrBack = dg.DefaultCellStyle.BackColor; Color clrValueBack = dg.DefaultCellStyle.BackColor; if(clrValueBack.GetBrightness() >= 0.5) clrValueBack = UIUtil.DarkenColor(clrValueBack, 0.075); else clrValueBack = UIUtil.LightenColor(clrValueBack, 0.075); dg.ColumnHeadersVisible = false; dg.RowHeadersVisible = false; dg.GridColor = clrBack; dg.BackgroundColor = clrBack; dg.DefaultCellStyle.SelectionBackColor = clrBack; dg.DefaultCellStyle.SelectionForeColor = dg.DefaultCellStyle.ForeColor; dg.AllowDrop = false; dg.AllowUserToAddRows = false; dg.AllowUserToDeleteRows = false; dg.AllowUserToOrderColumns = false; dg.AllowUserToResizeColumns = false; dg.AllowUserToResizeRows = false; // dg.EditMode: see below dg.Tag = p; int nWidth = (dg.ClientSize.Width - UIUtil.GetVScrollBarWidth()); dg.Columns.Add("Name", KPRes.FieldName); dg.Columns.Add("Value", KPRes.FieldValue); dg.Columns[0].Width = (nWidth / 2); dg.Columns[1].Width = (nWidth / 2); bool bUseDefaults = true; if(objDefaults.Type == null) { Debug.Assert(false); } // Optimistic else if(p.Type == null) { Debug.Assert(false); } // Optimistic else if(!objDefaults.Type.Equals(p.Type)) bUseDefaults = false; for(int i = 0; i < p.Parameters.Length; ++i) { EcasParameter ep = p.Parameters[i]; dg.Rows.Add(); DataGridViewRow row = dg.Rows[dg.Rows.Count - 1]; DataGridViewCellCollection cc = row.Cells; Debug.Assert(cc.Count == 2); cc[0].Value = ep.Name; cc[0].ReadOnly = true; string strParam = (bUseDefaults ? EcasUtil.GetParamString( objDefaults.Parameters, i) : string.Empty); DataGridViewCell c = null; switch(ep.Type) { case EcasValueType.String: c = new DataGridViewTextBoxCell(); c.Value = strParam; break; case EcasValueType.Bool: c = new DataGridViewCheckBoxCell(false); (c as DataGridViewCheckBoxCell).Value = StrUtil.StringToBool(strParam); break; case EcasValueType.EnumStrings: DataGridViewComboBoxCell cmb = new DataGridViewComboBoxCell(); cmb.Sorted = false; cmb.DisplayStyle = DataGridViewComboBoxDisplayStyle.DropDownButton; int iFound = -1; for(int e = 0; e < ep.EnumValues.ItemCount; ++e) { EcasEnumItem eei = ep.EnumValues.Items[e]; cmb.Items.Add(eei.Name); if(eei.ID.ToString() == strParam) iFound = e; } if(iFound >= 0) cmb.Value = ep.EnumValues.Items[iFound].Name; else if(ep.EnumValues.ItemCount > 0) cmb.Value = ep.EnumValues.Items[0].Name; else { Debug.Assert(false); } c = cmb; break; case EcasValueType.Int64: c = new DataGridViewTextBoxCell(); c.Value = FilterTypeI64(strParam); break; case EcasValueType.UInt64: c = new DataGridViewTextBoxCell(); c.Value = FilterTypeU64(strParam); break; default: Debug.Assert(false); break; } if(c != null) cc[1] = c; cc[1].ReadOnly = false; cc[1].Style.BackColor = clrValueBack; cc[1].Style.SelectionBackColor = clrValueBack; } // Perform postponed setting of EditMode (cannot set it earlier // due to a Mono bug on FreeBSD); // https://sourceforge.net/p/keepass/discussion/329220/thread/cb8270e2/ dg.EditMode = DataGridViewEditMode.EditOnEnter; } public static void DataGridViewToParameters(DataGridView dg, IEcasObject objOut, IEcasParameterized eTypeInfo) { if(dg == null) throw new ArgumentNullException("dg"); if(objOut == null) throw new ArgumentNullException("objOut"); // if(vParamDesc == null) throw new ArgumentNullException("vParamDesc"); // if(dg.Rows.Count != vParamDesc.Length) { Debug.Assert(false); return; } objOut.Parameters.Clear(); bool bTypeInfoValid = ((eTypeInfo != null) && (eTypeInfo.Parameters.Length == dg.Rows.Count)); for(int i = 0; i < dg.RowCount; ++i) { DataGridViewCell c = dg.Rows[i].Cells[1]; object oValue = c.Value; string strValue = ((oValue != null) ? oValue.ToString() : string.Empty); if(bTypeInfoValid && (eTypeInfo.Parameters[i].EnumValues != null) && (c is DataGridViewComboBoxCell)) { objOut.Parameters.Add(eTypeInfo.Parameters[i].EnumValues.GetItemID( strValue, 0).ToString()); } else objOut.Parameters.Add(strValue); } } public static bool UpdateDialog(EcasObjectType objType, ComboBox cmbTypes, DataGridView dgvParams, IEcasObject o, bool bGuiToInternal, EcasTypeDxMode dxType) { bool bResult = true; try { if(bGuiToInternal) { IEcasParameterized eTypeInfo = null; if(dxType == EcasTypeDxMode.Selection) { string strSel = (cmbTypes.SelectedItem as string); if(!string.IsNullOrEmpty(strSel)) { if(objType == EcasObjectType.Event) { eTypeInfo = Program.EcasPool.FindEvent(strSel); o.Type = eTypeInfo.Type; } else if(objType == EcasObjectType.Condition) { eTypeInfo = Program.EcasPool.FindCondition(strSel); o.Type = eTypeInfo.Type; } else if(objType == EcasObjectType.Action) { eTypeInfo = Program.EcasPool.FindAction(strSel); o.Type = eTypeInfo.Type; } else { Debug.Assert(false); } } } else if(dxType == EcasTypeDxMode.ParamsTag) { IEcasParameterized p = (dgvParams.Tag as IEcasParameterized); if((p != null) && (p.Type != null)) { eTypeInfo = p; o.Type = eTypeInfo.Type; } else { Debug.Assert(false); } } EcasUtil.DataGridViewToParameters(dgvParams, o, eTypeInfo); } else // Internal to GUI { if(dxType == EcasTypeDxMode.Selection) { if(o.Type.Equals(PwUuid.Zero)) cmbTypes.SelectedIndex = 0; else { int i = -1; if(objType == EcasObjectType.Event) i = cmbTypes.FindString(Program.EcasPool.FindEvent(o.Type).Name); else if(objType == EcasObjectType.Condition) i = cmbTypes.FindString(Program.EcasPool.FindCondition(o.Type).Name); else if(objType == EcasObjectType.Action) i = cmbTypes.FindString(Program.EcasPool.FindAction(o.Type).Name); else { Debug.Assert(false); } if(i >= 0) cmbTypes.SelectedIndex = i; else { Debug.Assert(false); } } } else { Debug.Assert(dxType != EcasTypeDxMode.ParamsTag); } IEcasParameterized t = null; if(objType == EcasObjectType.Event) t = Program.EcasPool.FindEvent(cmbTypes.SelectedItem as string); else if(objType == EcasObjectType.Condition) t = Program.EcasPool.FindCondition(cmbTypes.SelectedItem as string); else if(objType == EcasObjectType.Action) t = Program.EcasPool.FindAction(cmbTypes.SelectedItem as string); else { Debug.Assert(false); } if(t != null) EcasUtil.ParametersToDataGridView(dgvParams, t, o); } } catch(Exception e) { MessageService.ShowWarning(e); bResult = false; } return bResult; } public static string ParametersToString(IEcasObject ecasObj, EcasParameter[] vParamInfo) { if(ecasObj == null) throw new ArgumentNullException("ecasObj"); if(ecasObj.Parameters == null) throw new ArgumentException(); bool bParamInfoValid = true; if((vParamInfo == null) || (ecasObj.Parameters.Count > vParamInfo.Length)) { Debug.Assert(false); bParamInfoValid = false; } StringBuilder sb = new StringBuilder(); EcasCondition eCond = (ecasObj as EcasCondition); if(eCond != null) { if(eCond.Negate) sb.Append(KPRes.Not); } for(int i = 0; i < ecasObj.Parameters.Count; ++i) { string strParam = ecasObj.Parameters[i]; string strAppend; if(bParamInfoValid) { EcasValueType t = vParamInfo[i].Type; if(t == EcasValueType.String) strAppend = strParam; else if(t == EcasValueType.Bool) strAppend = (StrUtil.StringToBool(strParam) ? KPRes.Yes : KPRes.No); else if(t == EcasValueType.EnumStrings) { uint uEnumID; if(uint.TryParse(strParam, out uEnumID) == false) { Debug.Assert(false); } EcasEnum ee = vParamInfo[i].EnumValues; if(ee != null) strAppend = ee.GetItemString(uEnumID, string.Empty); else { Debug.Assert(false); strAppend = strParam; } } else if(t == EcasValueType.Int64) strAppend = FilterTypeI64(strParam); else if(t == EcasValueType.UInt64) strAppend = FilterTypeU64(strParam); else { Debug.Assert(false); strAppend = strParam; } } else strAppend = strParam; if(string.IsNullOrEmpty(strAppend)) continue; string strAppTrimmed = strAppend.Trim(); if(strAppTrimmed.Length == 0) continue; if(sb.Length > 0) sb.Append(", "); sb.Append(strAppTrimmed); } return sb.ToString(); } public static bool CompareStrings(string x, string y, uint uCompareType) { if(x == null) { Debug.Assert(false); return false; } if(y == null) { Debug.Assert(false); return false; } if(uCompareType == EcasUtil.StdStringCompareEquals) return x.Equals(y, StrUtil.CaseIgnoreCmp); if(uCompareType == EcasUtil.StdStringCompareStartsWith) return x.StartsWith(y, StrUtil.CaseIgnoreCmp); if(uCompareType == EcasUtil.StdStringCompareEndsWith) return x.EndsWith(y, StrUtil.CaseIgnoreCmp); Debug.Assert(uCompareType == EcasUtil.StdStringCompareContains); return (x.IndexOf(y, StrUtil.CaseIgnoreCmp) >= 0); } private static string FilterTypeI64(string str) { if(string.IsNullOrEmpty(str)) return string.Empty; long i64; if(long.TryParse(str, out i64)) return i64.ToString(); return string.Empty; } private static string FilterTypeU64(string str) { if(string.IsNullOrEmpty(str)) return string.Empty; ulong u64; if(ulong.TryParse(str, out u64)) return u64.ToString(); return string.Empty; } } } KeePass/Ecas/EcasTriggerSystem.cs0000664000000000000000000001144013222430406015713 0ustar rootroot/* KeePass Password Safe - The Open-Source Password Manager Copyright (C) 2003-2018 Dominik Reichl This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ using System; using System.Collections.Generic; using System.Text; using System.Xml.Serialization; using System.ComponentModel; using KeePass.Resources; using KeePass.UI; using KeePassLib; using KeePassLib.Collections; using KeePassLib.Interfaces; using KeePassLib.Utility; namespace KeePass.Ecas { public sealed class EcasTriggerSystem : IDeepCloneable { private bool m_bEnabled = true; [DefaultValue(true)] public bool Enabled { get { return m_bEnabled; } set { m_bEnabled = value; } } private PwObjectList m_vTriggers = new PwObjectList(); [XmlIgnore] public PwObjectList TriggerCollection { get { return m_vTriggers; } set { if(value == null) throw new ArgumentNullException("value"); m_vTriggers = value; } } [XmlArray("Triggers")] [XmlArrayItem("Trigger")] public EcasTrigger[] TriggerArrayForSerialization { get { return m_vTriggers.CloneShallowToList().ToArray(); } set { m_vTriggers = PwObjectList.FromArray(value); } } public event EventHandler RaisingEvent; public EcasTriggerSystem() { } public EcasTriggerSystem CloneDeep() { EcasTriggerSystem c = new EcasTriggerSystem(); c.m_bEnabled = m_bEnabled; for(uint i = 0; i < m_vTriggers.UCount; ++i) c.m_vTriggers.Add(m_vTriggers.GetAt(i).CloneDeep()); return c; } internal void SetToInitialState() { for(uint i = 0; i < m_vTriggers.UCount; ++i) m_vTriggers.GetAt(i).SetToInitialState(); } public object FindObjectByUuid(PwUuid pwUuid) { if(pwUuid == null) throw new ArgumentNullException("pwUuid"); foreach(EcasTrigger t in m_vTriggers) { if(t.Uuid.Equals(pwUuid)) return t; foreach(EcasEvent e in t.EventCollection) { if(e.Type.Equals(pwUuid)) return e; } foreach(EcasCondition c in t.ConditionCollection) { if(c.Type.Equals(pwUuid)) return c; } foreach(EcasAction a in t.ActionCollection) { if(a.Type.Equals(pwUuid)) return a; } } return null; } public void RaiseEvent(PwUuid eventType) { RaiseEvent(eventType, null); } internal void RaiseEvent(PwUuid eventType, string strPropKey, object oPropValue) { EcasPropertyDictionary d = new EcasPropertyDictionary(); d.Set(strPropKey, oPropValue); RaiseEvent(eventType, d); } public void RaiseEvent(PwUuid eventType, EcasPropertyDictionary props) { if(eventType == null) throw new ArgumentNullException("eventType"); // if(props == null) throw new ArgumentNullException("props"); if(!m_bEnabled) return; EcasEvent e = new EcasEvent(); e.Type = eventType; RaiseEventObj(e, (props ?? new EcasPropertyDictionary())); } private void RaiseEventObj(EcasEvent e, EcasPropertyDictionary props) { // if(e == null) throw new ArgumentNullException("e"); // if(m_bEnabled == false) return; if(this.RaisingEvent != null) { EcasRaisingEventArgs args = new EcasRaisingEventArgs(e, props); this.RaisingEvent(this, args); if(args.Cancel) return; } try { foreach(EcasTrigger t in m_vTriggers) t.RunIfMatching(e, props); } catch(Exception ex) { if(!VistaTaskDialog.ShowMessageBox(ex.Message, KPRes.TriggerExecutionFailed, PwDefs.ShortProductName, VtdIcon.Warning, null)) { MessageService.ShowWarning(KPRes.TriggerExecutionFailed + ".", ex); } } } } [XmlRoot("TriggerCollection")] public sealed class EcasTriggerContainer { private List m_vTriggers = new List(); [XmlArrayItem("Trigger")] public List Triggers { get { return m_vTriggers; } set { if(value == null) throw new ArgumentNullException("value"); m_vTriggers = value; } } public EcasTriggerContainer() { } } } KeePass/Native/0000775000000000000000000000000013222430412012330 5ustar rootrootKeePass/Native/NativeMethods.Unix.cs0000664000000000000000000001500413222430412016353 0ustar rootroot/* KeePass Password Safe - The Open-Source Password Manager Copyright (C) 2003-2018 Dominik Reichl This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ using System; using System.Collections.Generic; using System.Text; using System.Windows.Forms; using System.Runtime.InteropServices; using System.Diagnostics; using KeePass.Forms; using KeePass.UI; using KeePassLib.Utility; using NativeLib = KeePassLib.Native.NativeLib; namespace KeePass.Native { internal static partial class NativeMethods { /* private const string PathLibDo = "/usr/lib/gnome-do/libdo"; private const UnmanagedType NtvStringType = UnmanagedType.LPStr; [DllImport(PathLibDo)] internal static extern void gnomedo_keybinder_init(); [DllImport(PathLibDo)] [return: MarshalAs(UnmanagedType.Bool)] internal static extern bool gnomedo_keybinder_bind( [MarshalAs(NtvStringType)] string strKey, BindKeyHandler lpfnHandler); [DllImport(PathLibDo)] [return: MarshalAs(UnmanagedType.Bool)] internal static extern bool gnomedo_keybinder_unbind( [MarshalAs(NtvStringType)] string strKey, BindKeyHandler lpfnHandler); internal delegate void BindKeyHandler([MarshalAs(NtvStringType)] string strKey, IntPtr lpUserData); */ /* private const string PathLibTomBoy = "/usr/lib/tomboy/libtomboy.so"; [DllImport(PathLibTomBoy)] internal static extern void tomboy_keybinder_init(); [DllImport(PathLibTomBoy)] internal static extern void tomboy_keybinder_bind(string strKey, BindKeyHandler lpHandler); [DllImport(PathLibTomBoy)] internal static extern void tomboy_keybinder_unbind(string strKey, BindKeyHandler lpHandler); internal delegate void BindKeyHandler(string strKey, IntPtr lpUserData); */ private static bool LoseFocusUnix(Form fCurrent) { if(fCurrent == null) { Debug.Assert(false); return true; } try { string strCurrent = RunXDoTool("getwindowfocus -f"); long lCurrent; long.TryParse(strCurrent.Trim(), out lCurrent); MainForm mf = Program.MainForm; Debug.Assert(mf == fCurrent); if(mf != null) mf.UIBlockWindowStateAuto(true); UIUtil.SetWindowState(fCurrent, FormWindowState.Minimized); int nStart = Environment.TickCount; while((Environment.TickCount - nStart) < 1000) { Application.DoEvents(); string strActive = RunXDoTool("getwindowfocus -f"); long lActive; long.TryParse(strActive.Trim(), out lActive); if(lActive != lCurrent) break; } if(mf != null) mf.UIBlockWindowStateAuto(false); return true; } catch(Exception) { Debug.Assert(false); } return false; } internal static bool TryXDoTool() { return !string.IsNullOrEmpty(RunXDoTool("help")); } internal static bool TryXDoTool(bool bRequireWindowNameSupport) { if(!bRequireWindowNameSupport) return TryXDoTool(); string str = RunXDoTool("getactivewindow getwindowname"); if(string.IsNullOrEmpty(str)) return false; return !(str.Trim().Equals("usage: getactivewindow", StrUtil.CaseIgnoreCmp)); } internal static string RunXDoTool(string strParams) { try { Application.DoEvents(); // E.g. for clipboard updates string strOutput = NativeLib.RunConsoleApp("xdotool", strParams); Application.DoEvents(); // E.g. for clipboard updates return (strOutput ?? string.Empty); } catch(Exception) { Debug.Assert(false); } return string.Empty; } /* private static Dictionary m_dAsms = null; internal static Assembly LoadAssembly(string strAsmName, string strFileName) { if(m_dAsms == null) m_dAsms = new Dictionary(); Assembly asm; if(m_dAsms.TryGetValue(strAsmName, out asm)) return asm; try { asm = Assembly.Load(strAsmName); if(asm != null) { m_dAsms[strAsmName] = asm; return asm; } } catch(Exception) { } try { asm = Assembly.LoadFrom(strFileName); if(asm != null) { m_dAsms[strAsmName] = asm; return asm; } } catch(Exception) { } for(int d = 0; d < 4; ++d) { string strDir; switch(d) { case 0: strDir = "/usr/lib/mono/gac"; break; case 1: strDir = "/usr/lib/cli"; break; case 2: strDir = "/usr/lib/mono"; break; case 3: strDir = "/lib/mono"; break; default: strDir = null; break; } if(string.IsNullOrEmpty(strDir)) { Debug.Assert(false); continue; } try { string[] vFiles = Directory.GetFiles(strDir, strFileName, SearchOption.AllDirectories); if(vFiles == null) continue; for(int i = vFiles.Length - 1; i >= 0; --i) { string strFoundName = UrlUtil.GetFileName(vFiles[i]); if(!strFileName.Equals(strFoundName, StrUtil.CaseIgnoreCmp)) continue; try { asm = Assembly.LoadFrom(vFiles[i]); if(asm != null) { m_dAsms[strAsmName] = asm; return asm; } } catch(Exception) { } } } catch(Exception) { } } m_dAsms[strAsmName] = null; return null; } private static bool m_bGtkInitialized = false; internal static bool GtkEnsureInit() { if(m_bGtkInitialized) return true; try { Assembly asm = LoadAssembly("gtk-sharp", "gtk-sharp.dll"); if(asm == null) return false; Type tApp = asm.GetType("Gtk.Application", true); MethodInfo miInitCheck = tApp.GetMethod("InitCheck", BindingFlags.Public | BindingFlags.Static); if(miInitCheck == null) { Debug.Assert(false); return false; } string[] vArgs = new string[0]; bool bResult = (bool)miInitCheck.Invoke(null, new object[] { PwDefs.ShortProductName, vArgs }); if(!bResult) return false; m_bGtkInitialized = true; return true; } catch(Exception) { Debug.Assert(false); } return false; } */ } } KeePass/Native/NativeMethods.Structs.cs0000664000000000000000000002042113222430412017076 0ustar rootroot/* KeePass Password Safe - The Open-Source Password Manager Copyright (C) 2003-2018 Dominik Reichl This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ using System; using System.Text; using System.Security; using System.Runtime.InteropServices; using System.Diagnostics; using System.Windows.Forms; using System.Drawing; namespace KeePass.Native { internal static partial class NativeMethods { [StructLayout(LayoutKind.Sequential, Pack = 1)] internal struct MOUSEINPUT32_WithSkip { public uint __Unused0; // See INPUT32 structure public int X; public int Y; public uint MouseData; public uint Flags; public uint Time; public IntPtr ExtraInfo; } [StructLayout(LayoutKind.Sequential, Pack = 1)] internal struct KEYBDINPUT32_WithSkip { public uint __Unused0; // See INPUT32 structure public ushort VirtualKeyCode; public ushort ScanCode; public uint Flags; public uint Time; public IntPtr ExtraInfo; } [StructLayout(LayoutKind.Explicit)] internal struct INPUT32 { [FieldOffset(0)] public uint Type; [FieldOffset(0)] public MOUSEINPUT32_WithSkip MouseInput; [FieldOffset(0)] public KEYBDINPUT32_WithSkip KeyboardInput; } // INPUT.KI (40). vk: 8, sc: 10, fl: 12, t: 16, ex: 24 [StructLayout(LayoutKind.Explicit, Size = 40)] internal struct SpecializedKeyboardINPUT64 { [FieldOffset(0)] public uint Type; [FieldOffset(8)] public ushort VirtualKeyCode; [FieldOffset(10)] public ushort ScanCode; [FieldOffset(12)] public uint Flags; [FieldOffset(16)] public uint Time; [FieldOffset(24)] public IntPtr ExtraInfo; } [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Auto)] internal struct CHARFORMAT2 { public UInt32 cbSize; public UInt32 dwMask; public UInt32 dwEffects; public Int32 yHeight; public Int32 yOffset; public UInt32 crTextColor; public Byte bCharSet; public Byte bPitchAndFamily; [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 32)] public string szFaceName; public UInt16 wWeight; public UInt16 sSpacing; public Int32 crBackColor; public Int32 lcid; public UInt32 dwReserved; public Int16 sStyle; public Int16 wKerning; public Byte bUnderlineType; public Byte bAnimation; public Byte bRevAuthor; public Byte bReserved1; } [StructLayout(LayoutKind.Sequential)] internal struct RECT { public Int32 Left; public Int32 Top; public Int32 Right; public Int32 Bottom; public RECT(Rectangle rect) { this.Left = rect.Left; this.Top = rect.Top; this.Right = rect.Right; this.Bottom = rect.Bottom; } } [StructLayout(LayoutKind.Sequential)] internal struct COMBOBOXINFO { public Int32 cbSize; public RECT rcItem; public RECT rcButton; [MarshalAs(UnmanagedType.U4)] public ComboBoxButtonState buttonState; public IntPtr hwndCombo; public IntPtr hwndEdit; public IntPtr hwndList; } [StructLayout(LayoutKind.Sequential)] internal struct MARGINS { public Int32 Left; public Int32 Right; public Int32 Top; public Int32 Bottom; } [StructLayout(LayoutKind.Sequential)] internal struct COPYDATASTRUCT { public IntPtr dwData; public Int32 cbData; public IntPtr lpData; } [StructLayout(LayoutKind.Sequential)] private struct SCROLLINFO { public uint cbSize; public uint fMask; public int nMin; public int nMax; public uint nPage; public int nPos; public int nTrackPos; } [StructLayout(LayoutKind.Sequential)] internal struct HDITEM { public UInt32 mask; public Int32 cxy; [MarshalAs(UnmanagedType.LPTStr)] public string pszText; public IntPtr hbm; public Int32 cchTextMax; public Int32 fmt; public IntPtr lParam; public Int32 iImage; public Int32 iOrder; } [StructLayout(LayoutKind.Sequential)] internal struct NMHDR { public IntPtr hwndFrom; public IntPtr idFrom; public uint code; } [StructLayout(LayoutKind.Sequential)] private struct LASTINPUTINFO { public uint cbSize; public uint dwTime; } [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Auto)] private struct SHFILEINFO { public IntPtr hIcon; public int iIcon; public uint dwAttributes; [MarshalAs(UnmanagedType.ByValTStr, SizeConst = KeePassLib.Native.NativeMethods.MAX_PATH)] public string szDisplayName; [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 80)] public string szTypeName; } /* // LVGROUP for Windows Vista and higher [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)] private struct LVGROUP { public uint cbSize; public uint mask; // [MarshalAs(UnmanagedType.LPWStr)] // public StringBuilder pszHeader; public IntPtr pszHeader; public int cchHeader; // [MarshalAs(UnmanagedType.LPWStr)] // public StringBuilder pszFooter; public IntPtr pszFooter; public int cchFooter; public int iGroupId; public uint stateMask; public uint state; public uint uAlign; // [MarshalAs(UnmanagedType.LPWStr)] // public StringBuilder pszSubtitle; public IntPtr pszSubtitle; public uint cchSubtitle; [MarshalAs(UnmanagedType.LPWStr)] public string pszTask; // public StringBuilder pszTask; // public IntPtr pszTask; public uint cchTask; // [MarshalAs(UnmanagedType.LPWStr)] // public StringBuilder pszDescriptionTop; public IntPtr pszDescriptionTop; public uint cchDescriptionTop; // [MarshalAs(UnmanagedType.LPWStr)] // public StringBuilder pszDescriptionBottom; public IntPtr pszDescriptionBottom; public uint cchDescriptionBottom; public int iTitleImage; public int iExtendedImage; public int iFirstItem; public uint cItems; // [MarshalAs(UnmanagedType.LPWStr)] // public StringBuilder pszSubsetTitle; public IntPtr pszSubsetTitle; public uint cchSubsetTitle; [Conditional("DEBUG")] internal void AssertSize() { if(IntPtr.Size == 4) { Debug.Assert(Marshal.SizeOf(this) == 96); } else if(IntPtr.Size == 8) { Debug.Assert(Marshal.SizeOf(this) == 152); } else { Debug.Assert(false); } } } */ internal const uint PROCESSENTRY32SizeUni32 = 556; internal const uint PROCESSENTRY32SizeUni64 = 568; [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Auto)] internal struct PROCESSENTRY32 { public uint dwSize; public uint cntUsage; public uint th32ProcessID; public UIntPtr th32DefaultHeapID; public uint th32ModuleID; public uint cntThreads; public uint th32ParentProcessID; public int pcPriClassBase; public uint dwFlags; [MarshalAs(UnmanagedType.ByValTStr, SizeConst = KeePassLib.Native.NativeMethods.MAX_PATH)] public string szExeFile; } internal const uint ACTCTXSize32 = 32; internal const uint ACTCTXSize64 = 56; [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Auto)] internal struct ACTCTX { public uint cbSize; public uint dwFlags; [MarshalAs(UnmanagedType.LPTStr)] // Not LPWStr, see source code public string lpSource; public ushort wProcessorArchitecture; public ushort wLangId; [MarshalAs(UnmanagedType.LPTStr)] public string lpAssemblyDirectory; [MarshalAs(UnmanagedType.LPTStr)] public string lpResourceName; [MarshalAs(UnmanagedType.LPTStr)] public string lpApplicationName; public IntPtr hModule; } } } KeePass/Native/NativeProgressDialog.cs0000664000000000000000000001060113222430412016750 0ustar rootroot/* KeePass Password Safe - The Open-Source Password Manager Copyright (C) 2003-2018 Dominik Reichl This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ /* using System; using System.Runtime.InteropServices; using System.Diagnostics; using KeePass.Util; using KeePassLib; using KeePassLib.Interfaces; namespace KeePass.Native { [Flags] public enum ProgDlgFlags { Normal = 0x0, Modal = 0x1, AutoTime = 0x2, NoTime = 0x4, NoMinimize = 0x8, NoProgressBar = 0x10, MarqueeProgress = 0x20, NoCancel = 0x40 } public sealed class NativeProgressDialog : IStatusLogger { private IProgressDialog m_p; private uint m_uFlags; private IntPtr m_hWndParent; private uint m_uLastPercent = 0; private const uint PDTIMER_RESET = 0x1; private const uint PDTIMER_PAUSE = 0x2; private const uint PDTIMER_RESUME = 0x3; public static bool IsSupported { get { return (WinUtil.IsAtLeastWindowsVista && !KeePassLib.Native.NativeLib.IsUnix()); } } public NativeProgressDialog(IntPtr hWndParent, ProgDlgFlags fl) { m_hWndParent = hWndParent; m_uFlags = (uint)fl; try { m_p = (IProgressDialog)(new Win32ProgressDialog()); } catch(Exception) { Debug.Assert(false); m_p = null; } } ~NativeProgressDialog() { try { EndLogging(); } catch(Exception) { Debug.Assert(false); } } public void StartLogging(string strOperation, bool bWriteOperationToLog) { if(m_p == null) { Debug.Assert(false); return; } m_p.SetTitle(PwDefs.ShortProductName); m_p.StartProgressDialog(m_hWndParent, IntPtr.Zero, m_uFlags, IntPtr.Zero); m_p.Timer(PDTIMER_RESET, IntPtr.Zero); m_p.SetLine(1, strOperation, false, IntPtr.Zero); m_p.SetProgress(0, 100); m_uLastPercent = 0; } public void EndLogging() { if(m_p == null) return; // Might be freed/null already, don't assert m_p.StopProgressDialog(); try { Marshal.ReleaseComObject(m_p); } catch(Exception) { Debug.Assert(false); } m_p = null; } public bool SetProgress(uint uPercent) { if(m_p == null) { Debug.Assert(false); return true; } if(uPercent != m_uLastPercent) { m_p.SetProgress(uPercent, 100); m_uLastPercent = uPercent; } return !m_p.HasUserCancelled(); } public bool SetText(string strNewText, LogStatusType lsType) { if(m_p == null) { Debug.Assert(false); return true; } m_p.SetLine(2, strNewText, false, IntPtr.Zero); return !m_p.HasUserCancelled(); } public bool ContinueWork() { if(m_p == null) { Debug.Assert(false); return true; } return !m_p.HasUserCancelled(); } } [ComImport] [Guid("EBBC7C04-315E-11D2-B62F-006097DF5BD4")] [InterfaceType(ComInterfaceType.InterfaceIsIUnknown)] internal interface IProgressDialog { void StartProgressDialog(IntPtr hwndParent, IntPtr punkEnableModless, uint dwFlags, IntPtr pvReserved); void StopProgressDialog(); void SetTitle([MarshalAs(UnmanagedType.LPWStr)] string pwzTitle); void SetAnimation(IntPtr hInstAnimation, uint idAnimation); [PreserveSig] [return: MarshalAs(UnmanagedType.Bool)] bool HasUserCancelled(); void SetProgress(uint dwCompleted, uint dwTotal); void SetProgress64(ulong ullCompleted, ulong ullTotal); void SetLine(uint dwLineNum, [MarshalAs(UnmanagedType.LPWStr)] string pwzString, [MarshalAs(UnmanagedType.Bool)] bool fCompactPath, IntPtr pvReserved); void SetCancelMsg([MarshalAs(UnmanagedType.LPWStr)] string pwzCancelMsg, IntPtr pvReserved); void Timer(uint dwTimerAction, IntPtr pvReserved); } [ComImport] [Guid("F8383852-FCD3-11D1-A6B9-006097DF5BD4")] internal class Win32ProgressDialog { } } */ KeePass/Native/NativeMethods.New.cs0000664000000000000000000005361113222430412016167 0ustar rootroot/* KeePass Password Safe - The Open-Source Password Manager Copyright (C) 2003-2018 Dominik Reichl This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ using System; using System.Text; using System.Security; using System.Runtime.InteropServices; using System.Windows.Forms; using System.Drawing; using System.Drawing.Drawing2D; using System.Drawing.Imaging; using System.IO; using System.Diagnostics; using KeePass.UI; using KeePass.Util; using KeePassLib.Utility; using NativeLib = KeePassLib.Native.NativeLib; namespace KeePass.Native { internal static partial class NativeMethods { internal static string GetWindowText(IntPtr hWnd, bool bTrim) { int nLength = GetWindowTextLength(hWnd); if(nLength <= 0) return string.Empty; StringBuilder sb = new StringBuilder(nLength + 1); GetWindowText(hWnd, sb, sb.Capacity); string strWindow = sb.ToString(); return (bTrim ? strWindow.Trim() : strWindow); } /* internal static string GetWindowClassName(IntPtr hWnd) { try { StringBuilder sb = new StringBuilder(260); if(GetClassName(hWnd, sb, 258) > 0) return sb.ToString(); else { Debug.Assert(false); } return string.Empty; } catch(Exception) { Debug.Assert(false); } return null; } */ internal static IntPtr GetForegroundWindowHandle() { if(!NativeLib.IsUnix()) return GetForegroundWindow(); // Windows API try { return new IntPtr(long.Parse(RunXDoTool( "getactivewindow").Trim())); } catch(Exception) { Debug.Assert(false); } return IntPtr.Zero; } private static readonly char[] m_vWindowTrim = { '\r', '\n' }; internal static void GetForegroundWindowInfo(out IntPtr hWnd, out string strWindowText, bool bTrimWindow) { hWnd = GetForegroundWindowHandle(); if(!NativeLib.IsUnix()) // Windows strWindowText = GetWindowText(hWnd, bTrimWindow); else // Unix { strWindowText = RunXDoTool("getactivewindow getwindowname"); if(!string.IsNullOrEmpty(strWindowText)) { if(bTrimWindow) strWindowText = strWindowText.Trim(); else strWindowText = strWindowText.Trim(m_vWindowTrim); } } } internal static bool IsWindowEx(IntPtr hWnd) { if(!NativeLib.IsUnix()) // Windows return IsWindow(hWnd); return true; } internal static int GetWindowStyle(IntPtr hWnd) { return GetWindowLong(hWnd, GWL_STYLE); } internal static IntPtr GetClassLongPtr(IntPtr hWnd, int nIndex) { if(IntPtr.Size > 4) return GetClassLongPtr64(hWnd, nIndex); return GetClassLongPtr32(hWnd, nIndex); } internal static bool SetForegroundWindowEx(IntPtr hWnd) { if(!NativeLib.IsUnix()) return SetForegroundWindow(hWnd); return (RunXDoTool("windowactivate " + hWnd.ToInt64().ToString()).Trim().Length == 0); } internal static bool EnsureForegroundWindow(IntPtr hWnd) { if(!IsWindowEx(hWnd)) return false; IntPtr hWndInit = GetForegroundWindowHandle(); if(!SetForegroundWindowEx(hWnd)) { Debug.Assert(false); return false; } int nStartMS = Environment.TickCount; while((Environment.TickCount - nStartMS) < 1000) { IntPtr h = GetForegroundWindowHandle(); if(h == hWnd) return true; // Some applications (like Microsoft Edge) have multiple // windows and automatically redirect the focus to other // windows, thus also break when a different window gets // focused (except when h is zero, which can occur while // the focus transfer occurs) if((h != IntPtr.Zero) && (h != hWndInit)) return true; Application.DoEvents(); } return false; } internal static IntPtr FindWindow(string strTitle) { if(strTitle == null) { Debug.Assert(false); return IntPtr.Zero; } if(!NativeLib.IsUnix()) return FindWindowEx(IntPtr.Zero, IntPtr.Zero, null, strTitle); // Not --onlyvisible (due to not finding minimized windows) string str = RunXDoTool("search --name \"" + strTitle + "\"").Trim(); if(str.Length == 0) return IntPtr.Zero; long l; if(long.TryParse(str, out l)) return new IntPtr(l); return IntPtr.Zero; } internal static bool LoseFocus(Form fCurrent) { if(NativeLib.IsUnix()) return LoseFocusUnix(fCurrent); try { IntPtr hCurrentWnd = ((fCurrent != null) ? fCurrent.Handle : IntPtr.Zero); IntPtr hWnd = GetWindow(hCurrentWnd, GW_HWNDNEXT); while(true) { if(hWnd != hCurrentWnd) { int nStyle = GetWindowStyle(hWnd); if(((nStyle & WS_VISIBLE) != 0) && (GetWindowTextLength(hWnd) > 0)) { // Skip the taskbar window (required for Windows 7, // when the target window is the only other window // in the taskbar) if(!IsTaskBar(hWnd)) break; } } hWnd = GetWindow(hWnd, GW_HWNDNEXT); if(hWnd == IntPtr.Zero) break; } if(hWnd == IntPtr.Zero) return false; Debug.Assert(GetWindowText(hWnd, true) != "Start"); return EnsureForegroundWindow(hWnd); } catch(Exception) { Debug.Assert(false); } return false; } internal static bool IsTaskBar(IntPtr hWnd) { Process p = null; try { string strText = GetWindowText(hWnd, true); if(strText == null) return false; if(!strText.Equals("Start", StrUtil.CaseIgnoreCmp)) return false; uint uProcessId; NativeMethods.GetWindowThreadProcessId(hWnd, out uProcessId); p = Process.GetProcessById((int)uProcessId); string strExe = UrlUtil.GetFileName(p.MainModule.FileName).Trim(); return strExe.Equals("Explorer.exe", StrUtil.CaseIgnoreCmp); } catch(Exception) { Debug.Assert(false); } finally { try { if(p != null) p.Dispose(); } catch(Exception) { Debug.Assert(false); } } return false; } /* internal static bool IsMetroWindow(IntPtr hWnd) { if(hWnd == IntPtr.Zero) { Debug.Assert(false); return false; } if(NativeLib.IsUnix() || !WinUtil.IsAtLeastWindows8) return false; try { uint uProcessId; NativeMethods.GetWindowThreadProcessId(hWnd, out uProcessId); if(uProcessId == 0) { Debug.Assert(false); return false; } IntPtr h = NativeMethods.OpenProcess(NativeMethods.PROCESS_QUERY_INFORMATION, false, uProcessId); if(h == IntPtr.Zero) return false; // No assert bool bRet = NativeMethods.IsImmersiveProcess(h); NativeMethods.CloseHandle(h); return bRet; } catch(Exception) { Debug.Assert(false); } return false; } */ public static bool IsInvalidHandleValue(IntPtr p) { long h = p.ToInt64(); if(h == -1) return true; if(h == 0xFFFFFFFF) return true; return false; } public static int GetHeaderHeight(ListView lv) { if(lv == null) { Debug.Assert(false); return 0; } try { if((lv.View == View.Details) && (lv.HeaderStyle != ColumnHeaderStyle.None) && (lv.Columns.Count > 0) && !NativeLib.IsUnix()) { IntPtr hHeader = NativeMethods.SendMessage(lv.Handle, NativeMethods.LVM_GETHEADER, IntPtr.Zero, IntPtr.Zero); if(hHeader != IntPtr.Zero) { NativeMethods.RECT rect = new NativeMethods.RECT(); if(NativeMethods.GetWindowRect(hHeader, ref rect)) return (rect.Bottom - rect.Top); else { Debug.Assert(false); } } else { Debug.Assert(false); } } } catch(Exception) { Debug.Assert(false); } return 0; } // Workaround for only partially visible list view items /* public static void EnsureVisible(ListView lv, int nIndex, bool bPartialOK) { Debug.Assert(lv != null); if(lv == null) return; Debug.Assert(nIndex >= 0); if(nIndex < 0) return; Debug.Assert(nIndex < lv.Items.Count); if(nIndex >= lv.Items.Count) return; int nPartialOK = (bPartialOK ? 1 : 0); try { NativeMethods.SendMessage(lv.Handle, LVM_ENSUREVISIBLE, new IntPtr(nIndex), new IntPtr(nPartialOK)); } catch(Exception) { Debug.Assert(false); } } */ public static int GetScrollPosY(IntPtr hWnd) { if(NativeLib.IsUnix()) return 0; try { SCROLLINFO si = new SCROLLINFO(); si.cbSize = (uint)Marshal.SizeOf(si); si.fMask = (uint)ScrollInfoMask.SIF_POS; if(GetScrollInfo(hWnd, (int)ScrollBarDirection.SB_VERT, ref si)) return si.nPos; Debug.Assert(false); } catch(Exception) { Debug.Assert(false); } return 0; } public static void Scroll(ListView lv, int dx, int dy) { if(lv == null) throw new ArgumentNullException("lv"); if(NativeLib.IsUnix()) return; try { SendMessage(lv.Handle, LVM_SCROLL, (IntPtr)dx, (IntPtr)dy); } catch(Exception) { Debug.Assert(false); } } /* public static void ScrollAbsY(IntPtr hWnd, int y) { try { SCROLLINFO si = new SCROLLINFO(); si.cbSize = (uint)Marshal.SizeOf(si); si.fMask = (uint)ScrollInfoMask.SIF_POS; si.nPos = y; SetScrollInfo(hWnd, (int)ScrollBarDirection.SB_VERT, ref si, true); } catch(Exception) { Debug.Assert(false); } } */ /* public static void Scroll(IntPtr h, int dx, int dy) { if(h == IntPtr.Zero) { Debug.Assert(false); return; } // No throw try { ScrollWindowEx(h, dx, dy, IntPtr.Zero, IntPtr.Zero, IntPtr.Zero, IntPtr.Zero, SW_INVALIDATE); } catch(Exception) { Debug.Assert(false); } } */ /* internal static void ClearIconicBitmaps(IntPtr hWnd) { // TaskbarList.SetThumbnailClip(hWnd, new Rectangle(0, 0, 1, 1)); // TaskbarList.SetThumbnailClip(hWnd, null); try { DwmInvalidateIconicBitmaps(hWnd); } catch(Exception) { Debug.Assert(!WinUtil.IsAtLeastWindows7); } } */ internal static uint? GetLastInputTime() { try { LASTINPUTINFO lii = new LASTINPUTINFO(); lii.cbSize = (uint)Marshal.SizeOf(typeof(LASTINPUTINFO)); if(!GetLastInputInfo(ref lii)) { Debug.Assert(false); return null; } return lii.dwTime; } catch(Exception) { Debug.Assert(NativeLib.IsUnix() || WinUtil.IsWindows9x); } return null; } internal static bool SHGetFileInfo(string strPath, int nPrefImgDim, out Image img, out string strDisplayName) { img = null; strDisplayName = null; try { SHFILEINFO fi = new SHFILEINFO(); IntPtr p = SHGetFileInfo(strPath, 0, ref fi, (uint)Marshal.SizeOf(typeof( SHFILEINFO)), SHGFI_ICON | SHGFI_SMALLICON | SHGFI_DISPLAYNAME); if(p == IntPtr.Zero) return false; if(fi.hIcon != IntPtr.Zero) { using(Icon ico = Icon.FromHandle(fi.hIcon)) // Doesn't take ownership { img = new Bitmap(nPrefImgDim, nPrefImgDim); using(Graphics g = Graphics.FromImage(img)) { g.Clear(Color.Transparent); g.InterpolationMode = InterpolationMode.HighQualityBicubic; g.SmoothingMode = SmoothingMode.HighQuality; g.DrawIcon(ico, new Rectangle(0, 0, nPrefImgDim, nPrefImgDim)); } } if(!DestroyIcon(fi.hIcon)) { Debug.Assert(false); } } strDisplayName = fi.szDisplayName; return true; } catch(Exception) { Debug.Assert(false); } return false; } /// /// Method for testing whether a file exists or not. Also /// supports NTFS alternate data streams. /// /// Path of the file or stream. /// true if the file exists. public static bool FileExists(string strFilePath) { if(strFilePath == null) throw new ArgumentNullException("strFilePath"); try { // https://sourceforge.net/p/keepass/discussion/329221/thread/65244cc9/ if(!NativeLib.IsUnix()) return (GetFileAttributes(strFilePath) != INVALID_FILE_ATTRIBUTES); } catch(Exception) { Debug.Assert(false); } // Fallback to .NET method (for Unix-like systems) try { return File.Exists(strFilePath); } catch(Exception) { Debug.Assert(false); } // Invalid path return false; } /* internal static LVGROUP GetGroupInfoByIndex(ListView lv, uint uIndex) { if(lv == null) throw new ArgumentNullException("lv"); if(uIndex >= (uint)lv.Groups.Count) throw new ArgumentOutOfRangeException("uIndex"); const int nStrLen = 1024; LVGROUP g = new LVGROUP(); g.cbSize = (uint)Marshal.SizeOf(typeof(LVGROUP)); g.mask = ...; g.pszHeader = new StringBuilder(nStrLen); g.cchHeader = nStrLen - 1; g.pszFooter = new StringBuilder(nStrLen); g.cchFooter = nStrLen - 1; g.pszSubtitle = new StringBuilder(nStrLen); g.cchSubtitle = (uint)(nStrLen - 1); g.pszTask = new StringBuilder(nStrLen); g.cchTask = (uint)(nStrLen - 1); g.pszDescriptionTop = new StringBuilder(nStrLen); g.cchDescriptionTop = (uint)(nStrLen - 1); g.pszDescriptionBottom = new StringBuilder(nStrLen); g.cchDescriptionBottom = (uint)(nStrLen - 1); g.pszSubsetTitle = new StringBuilder(nStrLen); g.cchSubsetTitle = (uint)(nStrLen - 1); SendMessageLVGroup(lv.Handle, LVM_GETGROUPINFOBYINDEX, new IntPtr((int)uIndex), ref g); return g; } */ /* internal static uint GetGroupStateByIndex(ListView lv, uint uIndex, uint uStateMask, out int iGroupID) { if(lv == null) throw new ArgumentNullException("lv"); if(uIndex >= (uint)lv.Groups.Count) throw new ArgumentOutOfRangeException("uIndex"); LVGROUP g = new LVGROUP(); g.cbSize = (uint)Marshal.SizeOf(g); g.mask = (LVGF_STATE | LVGF_GROUPID); g.stateMask = uStateMask; SendMessageLVGroup(lv.Handle, LVM_GETGROUPINFOBYINDEX, new IntPtr((int)uIndex), ref g); iGroupID = g.iGroupId; return g.state; } internal static void SetGroupState(ListView lv, int iGroupID, uint uStateMask, uint uState) { if(lv == null) throw new ArgumentNullException("lv"); LVGROUP g = new LVGROUP(); g.cbSize = (uint)Marshal.SizeOf(g); g.mask = LVGF_STATE; g.stateMask = uStateMask; g.state = uState; SendMessageLVGroup(lv.Handle, LVM_SETGROUPINFO, new IntPtr(iGroupID), ref g); } */ /* internal static int GetGroupIDByIndex(ListView lv, uint uIndex) { if(lv == null) { Debug.Assert(false); return 0; } LVGROUP g = new LVGROUP(); g.cbSize = (uint)Marshal.SizeOf(g); g.AssertSize(); g.mask = NativeMethods.LVGF_GROUPID; if(SendMessageLVGroup(lv.Handle, LVM_GETGROUPINFOBYINDEX, new IntPtr((int)uIndex), ref g) == IntPtr.Zero) { Debug.Assert(false); } return g.iGroupId; } internal static void SetGroupTask(ListView lv, int iGroupID, string strTask) { if(lv == null) { Debug.Assert(false); return; } LVGROUP g = new LVGROUP(); g.cbSize = (uint)Marshal.SizeOf(g); g.AssertSize(); g.mask = LVGF_TASK; g.pszTask = strTask; g.cchTask = (uint)((strTask != null) ? strTask.Length : 0); if(SendMessageLVGroup(lv.Handle, LVM_SETGROUPINFO, new IntPtr(iGroupID), ref g) == (new IntPtr(-1))) { Debug.Assert(false); } } */ /* internal static void SetListViewGroupInfo(ListView lv, int iGroupID, string strTask, bool? obCollapsible) { if(lv == null) { Debug.Assert(false); return; } if(!WinUtil.IsAtLeastWindowsVista) return; LVGROUP g = new LVGROUP(); g.cbSize = (uint)Marshal.SizeOf(g); g.AssertSize(); if(strTask != null) { g.mask |= LVGF_TASK; g.pszTask = strTask; g.cchTask = (uint)strTask.Length; } if(obCollapsible.HasValue) { g.mask |= LVGF_STATE; g.stateMask = LVGS_COLLAPSIBLE; g.state = (obCollapsible.Value ? LVGS_COLLAPSIBLE : 0); } if(g.mask == 0) return; if(SendMessageLVGroup(lv.Handle, LVM_SETGROUPINFO, new IntPtr(iGroupID), ref g) == (new IntPtr(-1))) { Debug.Assert(false); } } internal static int GetListViewGroupID(ListViewGroup lvg) { if(lvg == null) { Debug.Assert(false); return -1; } Type t = typeof(ListViewGroup); PropertyInfo pi = t.GetProperty("ID", (BindingFlags.Instance | BindingFlags.NonPublic)); if(pi == null) { Debug.Assert(false); return -1; } if(pi.PropertyType != typeof(int)) { Debug.Assert(false); return -1; } return (int)pi.GetValue(lvg, null); } */ private static bool GetDesktopName(IntPtr hDesk, out string strAnsi, out string strUni) { strAnsi = null; strUni = null; const uint cbZ = 12; // Minimal number of terminating zeros const uint uBufSize = 64 + cbZ; IntPtr pBuf = Marshal.AllocCoTaskMem((int)uBufSize); byte[] pbZero = new byte[uBufSize]; Marshal.Copy(pbZero, 0, pBuf, pbZero.Length); try { uint uReqSize = uBufSize - cbZ; bool bSuccess = GetUserObjectInformation(hDesk, 2, pBuf, uBufSize - cbZ, ref uReqSize); if(uReqSize > (uBufSize - cbZ)) { Marshal.FreeCoTaskMem(pBuf); pBuf = Marshal.AllocCoTaskMem((int)(uReqSize + cbZ)); pbZero = new byte[uReqSize + cbZ]; Marshal.Copy(pbZero, 0, pBuf, pbZero.Length); bSuccess = GetUserObjectInformation(hDesk, 2, pBuf, uReqSize, ref uReqSize); Debug.Assert((uReqSize + cbZ) == (uint)pbZero.Length); } if(bSuccess) { try { strAnsi = Marshal.PtrToStringAnsi(pBuf).Trim(); } catch(Exception) { } try { strUni = Marshal.PtrToStringUni(pBuf).Trim(); } catch(Exception) { } return true; } } finally { Marshal.FreeCoTaskMem(pBuf); } Debug.Assert(false); return false; } // The GetUserObjectInformation function apparently returns the // desktop name using ANSI encoding even on Windows 7 systems. // As the encoding is not documented, we test both ANSI and // Unicode versions of the name. internal static bool? DesktopNameContains(IntPtr hDesk, string strName) { if(string.IsNullOrEmpty(strName)) { Debug.Assert(false); return false; } string strAnsi, strUni; if(!GetDesktopName(hDesk, out strAnsi, out strUni)) return null; if((strAnsi == null) && (strUni == null)) return null; try { if((strAnsi != null) && (strAnsi.IndexOf(strName, StringComparison.OrdinalIgnoreCase) >= 0)) return true; } catch(Exception) { Debug.Assert(false); } try { if((strUni != null) && (strUni.IndexOf(strName, StringComparison.OrdinalIgnoreCase) >= 0)) return true; } catch(Exception) { Debug.Assert(false); } return false; } internal static bool? IsKeyDownMessage(ref Message m) { if(m.Msg == NativeMethods.WM_KEYDOWN) return true; if(m.Msg == NativeMethods.WM_KEYUP) return false; return null; } /// /// PRIMARYLANGID macro. /// internal static ushort GetPrimaryLangID(ushort uLangID) { return (ushort)(uLangID & 0x3FFU); } internal static uint MapVirtualKey3(uint uCode, uint uMapType, IntPtr hKL) { if(hKL == IntPtr.Zero) return MapVirtualKey(uCode, uMapType); return MapVirtualKeyEx(uCode, uMapType, hKL); } internal static ushort VkKeyScan3(char ch, IntPtr hKL) { if(hKL == IntPtr.Zero) return VkKeyScan(ch); return VkKeyScanEx(ch, hKL); } /// /// Null, if there exists no translation or an error occured. /// An empty string, if the key is a dead key. /// Otherwise, the generated Unicode string (typically 1 character, /// but can be more when a dead key is stored in the keyboard layout). /// internal static string ToUnicode3(int vKey, byte[] pbKeyState, IntPtr hKL) { const int cbState = 256; IntPtr pState = IntPtr.Zero; try { uint uScanCode = MapVirtualKey3((uint)vKey, MAPVK_VK_TO_VSC, hKL); pState = Marshal.AllocHGlobal(cbState); if(pState == IntPtr.Zero) { Debug.Assert(false); return null; } if(pbKeyState != null) { if(pbKeyState.Length == cbState) Marshal.Copy(pbKeyState, 0, pState, cbState); else { Debug.Assert(false); return null; } } else { // Windows' GetKeyboardState function does not return // the current virtual key array; as a workaround, // calling GetKeyState is mentioned sometimes, but // this doesn't work reliably either; // http://pinvoke.net/default.aspx/user32/GetKeyboardState.html // GetKeyState(VK_SHIFT); // if(!GetKeyboardState(pState)) { Debug.Assert(false); return null; } Debug.Assert(false); return null; } const int cchUni = 30; StringBuilder sbUni = new StringBuilder(cchUni + 2); int r; if(hKL == IntPtr.Zero) r = ToUnicode((uint)vKey, uScanCode, pState, sbUni, cchUni, 0); else r = ToUnicodeEx((uint)vKey, uScanCode, pState, sbUni, cchUni, 0, hKL); if(r < 0) return string.Empty; // Dead key if(r == 0) return null; // No translation string str = sbUni.ToString(); if(string.IsNullOrEmpty(str)) { Debug.Assert(false); return null; } // Extra characters may be returned, but are invalid // and should be ignored; // https://msdn.microsoft.com/en-us/library/windows/desktop/ms646320.aspx if(r < str.Length) str = str.Substring(0, r); return str; } catch(Exception) { Debug.Assert(false); } finally { if(pState != IntPtr.Zero) Marshal.FreeHGlobal(pState); } return null; } } } KeePass/Native/NativeMethods.Defs.cs0000664000000000000000000003264313222430412016321 0ustar rootroot/* KeePass Password Safe - The Open-Source Password Manager Copyright (C) 2003-2018 Dominik Reichl This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ using System; using System.Text; using System.Security; using System.Runtime.InteropServices; using System.Diagnostics; using System.Windows.Forms; namespace KeePass.Native { internal static partial class NativeMethods { internal const int WM_SETFOCUS = 0x0007; internal const int WM_KILLFOCUS = 0x0008; internal const int WM_KEYDOWN = 0x0100; internal const int WM_KEYUP = 0x0101; internal const int WM_DRAWCLIPBOARD = 0x0308; internal const int WM_CHANGECBCHAIN = 0x030D; internal const int WM_HOTKEY = 0x0312; internal const int WM_USER = 0x0400; internal const int WM_SYSCOMMAND = 0x0112; internal const int WM_POWERBROADCAST = 0x0218; internal const int WM_COPYDATA = 0x004A; // internal const int WM_MOUSEMOVE = 0x0200; internal const int WM_LBUTTONDOWN = 0x0201; internal const int WM_RBUTTONDOWN = 0x0204; internal const int WM_MBUTTONDOWN = 0x0207; // internal const int WM_MOUSEWHEEL = 0x020A; // internal const int WM_ERASEBKGND = 0x0014; internal const int WM_INPUTLANGCHANGEREQUEST = 0x0050; internal const int WM_NOTIFY = 0x004E; // See Control.ReflectMessageInternal; // https://msdn.microsoft.com/en-us/library/eeah46xd.aspx internal const int WM_REFLECT = 0x2000; internal const int WM_NOTIFY_REFLECT = (WM_NOTIFY + WM_REFLECT); internal const int WM_GETTEXTLENGTH = 0x000E; internal const int WM_GETICON = 0x007F; internal const int HWND_BROADCAST = 0xFFFF; internal const uint SMTO_NORMAL = 0x0000; internal const uint SMTO_BLOCK = 0x0001; internal const uint SMTO_ABORTIFHUNG = 0x0002; internal const uint SMTO_NOTIMEOUTIFNOTHUNG = 0x0008; internal const uint INPUT_MOUSE = 0; internal const uint INPUT_KEYBOARD = 1; internal const uint INPUT_HARDWARE = 2; // internal const int VK_RETURN = 0x0D; internal const int VK_SHIFT = 0x10; internal const int VK_CONTROL = 0x11; internal const int VK_MENU = 0x12; internal const int VK_CAPITAL = 0x14; // Caps Lock // internal const int VK_ESCAPE = 0x1B; // internal const int VK_SPACE = 0x20; internal const int VK_NUMLOCK = 0x90; internal const int VK_LSHIFT = 0xA0; internal const int VK_RSHIFT = 0xA1; internal const int VK_LCONTROL = 0xA2; internal const int VK_RCONTROL = 0xA3; internal const int VK_LMENU = 0xA4; internal const int VK_RMENU = 0xA5; internal const int VK_LWIN = 0x5B; internal const int VK_RWIN = 0x5C; internal const int VK_SNAPSHOT = 0x2C; // internal const int VK_F5 = 0x74; // internal const int VK_F6 = 0x75; // internal const int VK_F7 = 0x76; // internal const int VK_F8 = 0x77; internal const uint MAPVK_VK_TO_VSC = 0; internal const uint KEYEVENTF_EXTENDEDKEY = 1; internal const uint KEYEVENTF_KEYUP = 2; internal const uint KEYEVENTF_UNICODE = 4; internal const ushort LANG_CZECH = 0x05; internal const ushort LANG_POLISH = 0x15; // internal const uint GW_CHILD = 5; internal const uint GW_HWNDNEXT = 2; internal const int GWL_STYLE = -16; internal const int GWL_EXSTYLE = -20; internal const int WS_VISIBLE = 0x10000000; // internal const int WS_EX_COMPOSITED = 0x02000000; internal const int SW_SHOW = 5; internal const int GCLP_HICON = -14; internal const int GCLP_HICONSM = -34; internal const int ICON_SMALL = 0; internal const int ICON_BIG = 1; internal const int ICON_SMALL2 = 2; internal const int EM_GETCHARFORMAT = WM_USER + 58; internal const int EM_SETCHARFORMAT = WM_USER + 68; internal const int ES_WANTRETURN = 0x1000; internal const int SCF_SELECTION = 0x0001; internal const uint CFM_BOLD = 0x00000001; internal const uint CFM_ITALIC = 0x00000002; internal const uint CFM_UNDERLINE = 0x00000004; internal const uint CFM_STRIKEOUT = 0x00000008; internal const uint CFM_LINK = 0x00000020; internal const uint CFM_SIZE = 0x80000000; internal const uint CFE_BOLD = 0x0001; internal const uint CFE_ITALIC = 0x0002; internal const uint CFE_UNDERLINE = 0x0004; internal const uint CFE_STRIKEOUT = 0x0008; internal const uint CFE_LINK = 0x0020; internal const int SC_MINIMIZE = 0xF020; internal const int SC_MAXIMIZE = 0xF030; internal const int IDANI_CAPTION = 3; internal const int PBT_APMQUERYSUSPEND = 0x0000; internal const int PBT_APMSUSPEND = 0x0004; internal const int ECM_FIRST = 0x1500; internal const int EM_SETCUEBANNER = ECM_FIRST + 1; internal const uint INVALID_FILE_ATTRIBUTES = 0xFFFFFFFFU; internal const uint FSCTL_LOCK_VOLUME = 589848; internal const uint FSCTL_UNLOCK_VOLUME = 589852; internal const int LVM_FIRST = 0x1000; // internal const int LVM_ENSUREVISIBLE = LVM_FIRST + 19; internal const int LVM_SCROLL = LVM_FIRST + 20; // internal const int LVM_SETGROUPINFO = LVM_FIRST + 147; // >= Vista // internal const int LVM_GETGROUPINFOBYINDEX = LVM_FIRST + 153; // >= Vista internal const int TV_FIRST = 0x1100; internal const int TVM_GETTOOLTIPS = TV_FIRST + 25; internal const int TVM_SETEXTENDEDSTYLE = TV_FIRST + 44; internal const int TTM_SETDELAYTIME = WM_USER + 3; internal const int TTM_GETDELAYTIME = WM_USER + 21; internal const int TTDT_AUTOPOP = 2; internal const int WM_MOUSEACTIVATE = 0x21; internal const int MA_ACTIVATE = 1; internal const int MA_ACTIVATEANDEAT = 2; internal const int MA_NOACTIVATE = 3; internal const int MA_NOACTIVATEANDEAT = 4; internal const int BCM_SETSHIELD = 0x160C; internal const int SHCNE_ASSOCCHANGED = 0x08000000; internal const uint SHCNF_IDLIST = 0x0000; // internal const uint SW_INVALIDATE = 0x0002; internal const uint TVS_FULLROWSELECT = 0x1000; internal const uint TVS_NONEVENHEIGHT = 0x4000; internal const uint TVS_EX_DOUBLEBUFFER = 0x0004; internal const uint TVS_EX_FADEINOUTEXPANDOS = 0x0040; internal const int HDI_FORMAT = 0x0004; internal const int HDF_SORTUP = 0x0400; internal const int HDF_SORTDOWN = 0x0200; internal const int LVM_GETHEADER = LVM_FIRST + 31; internal const int HDM_FIRST = 0x1200; internal const int HDM_GETITEMA = HDM_FIRST + 3; internal const int HDM_GETITEMW = HDM_FIRST + 11; internal const int HDM_SETITEMA = HDM_FIRST + 4; internal const int HDM_SETITEMW = HDM_FIRST + 12; internal const int OFN_DONTADDTORECENT = 0x02000000; internal const uint SHGFI_DISPLAYNAME = 0x000000200; internal const uint SHGFI_ICON = 0x000000100; internal const uint SHGFI_TYPENAME = 0x000000400; internal const uint SHGFI_SMALLICON = 0x000000001; internal const uint MOD_ALT = 1; internal const uint MOD_CONTROL = 2; internal const uint MOD_SHIFT = 4; internal const uint MOD_WIN = 8; internal const int IDHOT_SNAPDESKTOP = -2; internal const int IDHOT_SNAPWINDOW = -1; internal const uint GHND = 0x0042; internal const uint GMEM_MOVEABLE = 0x0002; internal const uint GMEM_ZEROINIT = 0x0040; internal const uint CF_TEXT = 1; internal const uint CF_UNICODETEXT = 13; internal const uint SND_ASYNC = 0x0001; internal const uint SND_FILENAME = 0x00020000; internal const uint SND_NODEFAULT = 0x0002; internal const int LOGPIXELSX = 88; internal const int LOGPIXELSY = 90; // internal const int SM_CXSMICON = 49; // internal const int SM_CYSMICON = 50; // internal const uint PROCESS_QUERY_INFORMATION = 0x0400; internal const uint ACTCTX_FLAG_ASSEMBLY_DIRECTORY_VALID = 0x04; internal const int INFOTIPSIZE = 1024; // internal const uint DI_NORMAL = 0x0003; // internal const int LVN_FIRST = -100; // internal const int LVN_LINKCLICK = LVN_FIRST - 84; // internal const uint LVGF_NONE = 0x00000000; // internal const uint LVGF_HEADER = 0x00000001; // internal const uint LVGF_FOOTER = 0x00000002; // internal const uint LVGF_STATE = 0x00000004; // internal const uint LVGF_ALIGN = 0x00000008; // internal const uint LVGF_GROUPID = 0x00000010; // internal const uint LVGF_SUBTITLE = 0x00000100; // internal const uint LVGF_TASK = 0x00000200; // internal const uint LVGF_DESCRIPTIONTOP = 0x00000400; // internal const uint LVGF_DESCRIPTIONBOTTOM = 0x00000800; // internal const uint LVGF_TITLEIMAGE = 0x00001000; // internal const uint LVGF_EXTENDEDIMAGE = 0x00002000; // internal const uint LVGF_ITEMS = 0x00004000; // internal const uint LVGF_SUBSET = 0x00008000; // internal const uint LVGF_SUBSETITEMS = 0x00010000; // internal const uint LVGS_NORMAL = 0x00000000; // internal const uint LVGS_COLLAPSED = 0x00000001; // internal const uint LVGS_HIDDEN = 0x00000002; // internal const uint LVGS_NOHEADER = 0x00000004; // internal const uint LVGS_COLLAPSIBLE = 0x00000008; // internal const uint LVGS_FOCUSED = 0x00000010; // internal const uint LVGS_SELECTED = 0x00000020; // internal const uint LVGS_SUBSETED = 0x00000040; // internal const uint LVGS_SUBSETLINKFOCUSED = 0x00000080; // private const int TTN_FIRST = -520; // internal const int TTN_NEEDTEXTA = TTN_FIRST; // internal const int TTN_NEEDTEXTW = TTN_FIRST - 10; [return: MarshalAs(UnmanagedType.Bool)] internal delegate bool EnumWindowsProc(IntPtr hWnd, IntPtr lParam); internal enum ComboBoxButtonState : uint { STATE_SYSTEM_NONE = 0, STATE_SYSTEM_INVISIBLE = 0x00008000, STATE_SYSTEM_PRESSED = 0x00000008 } [Flags] internal enum DesktopFlags : uint { ReadObjects = 0x0001, CreateWindow = 0x0002, CreateMenu = 0x0004, HookControl = 0x0008, JournalRecord = 0x0010, JournalPlayback = 0x0020, Enumerate = 0x0040, WriteObjects = 0x0080, SwitchDesktop = 0x0100, } [Flags] internal enum EFileAccess : uint { GenericRead = 0x80000000, GenericWrite = 0x40000000, GenericExecute = 0x20000000, GenericAll = 0x10000000 } [Flags] internal enum EFileShare : uint { None = 0x00000000, Read = 0x00000001, Write = 0x00000002, Delete = 0x00000004 } internal enum ECreationDisposition : uint { CreateNew = 1, CreateAlways = 2, OpenExisting = 3, OpenAlways = 4, TruncateExisting = 5 } private enum ScrollBarDirection : int { SB_HORZ = 0, SB_VERT = 1, SB_CTL = 2, SB_BOTH = 3 } private enum ScrollInfoMask : uint { SIF_RANGE = 0x1, SIF_PAGE = 0x2, SIF_POS = 0x4, SIF_DISABLENOSCROLL = 0x8, SIF_TRACKPOS = 0x10, SIF_ALL = SIF_RANGE + SIF_PAGE + SIF_POS + SIF_TRACKPOS } [Flags] internal enum MessageBoxFlags : uint { // Buttons MB_ABORTRETRYIGNORE = 0x00000002, MB_CANCELTRYCONTINUE = 0x00000006, MB_HELP = 0x00004000, MB_OK = 0, MB_OKCANCEL = 0x00000001, MB_RETRYCANCEL = 0x00000005, MB_YESNO = 0x00000004, MB_YESNOCANCEL = 0x00000003, // Icons MB_ICONEXCLAMATION = 0x00000030, MB_ICONWARNING = 0x00000030, MB_ICONINFORMATION = 0x00000040, MB_ICONASTERISK = 0x00000040, MB_ICONQUESTION = 0x00000020, MB_ICONSTOP = 0x00000010, MB_ICONERROR = 0x00000010, MB_ICONHAND = 0x00000010, // Default buttons MB_DEFBUTTON1 = 0, MB_DEFBUTTON2 = 0x00000100, MB_DEFBUTTON3 = 0x00000200, MB_DEFBUTTON4 = 0x00000300, // Modality MB_APPLMODAL = 0, MB_SYSTEMMODAL = 0x00001000, MB_TASKMODAL = 0x00002000, // Other options MB_DEFAULT_DESKTOP_ONLY = 0x00020000, MB_RIGHT = 0x00080000, MB_RTLREADING = 0x00100000, MB_SETFOREGROUND = 0x00010000, MB_TOPMOST = 0x00040000, MB_SERVICE_NOTIFICATION = 0x00200000 } // See DialogResult /* internal enum CommandID { None = 0, OK = 1, // IDOK Cancel = 2, // IDCANCEL Abort = 3, // IDABORT Retry = 4, // IDRETRY Ignore = 5, // IDIGNORE Yes = 6, // IDYES No = 7, // IDNO Close = 8, // IDCLOSE Help = 9, // IDHELP TryAgain = 10, // IDTRYAGAIN Continue = 11, // IDCONTINUE TimeOut = 32000 // IDTIMEOUT } */ [Flags] internal enum ToolHelpFlags : uint { SnapHeapList = 0x00000001, SnapProcess = 0x00000002, SnapThread = 0x00000004, SnapModule = 0x00000008, SnapModule32 = 0x00000010, SnapAll = (SnapHeapList | SnapProcess | SnapThread | SnapModule), Inherit = 0x80000000U } // https://msdn.microsoft.com/en-us/library/windows/desktop/aa380337.aspx [Flags] internal enum STGM : uint { Read = 0x00000000, Write = 0x00000001, ReadWrite = 0x00000002, ShareDenyNone = 0x00000040, ShareDenyRead = 0x00000030, ShareDenyWrite = 0x00000020, ShareExclusive = 0x00000010 } internal enum ProcessDpiAwareness : uint { Unaware = 0, SystemAware = 1, PerMonitorAware = 2 } } } KeePass/Native/ShellLinkEx.cs0000664000000000000000000001225013222430412015041 0ustar rootroot/* KeePass Password Safe - The Open-Source Password Manager Copyright (C) 2003-2018 Dominik Reichl This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ using System; using System.Collections.Generic; using System.Text; using System.Runtime.InteropServices; using System.Runtime.InteropServices.ComTypes; using System.Diagnostics; using KeePassLib.Utility; namespace KeePass.Native { internal sealed class ShellLinkEx { private string m_strPath = null; public string Path { get { return m_strPath; } set { m_strPath = value; } } private string m_strArgs = null; public string Arguments { get { return m_strArgs; } set { m_strArgs = value; } } private string m_strDesc = null; public string Description { get { return m_strDesc; } set { if((value != null) && (value.Length >= NativeMethods.INFOTIPSIZE)) { Debug.Assert(false); m_strDesc = StrUtil.CompactString3Dots(value, NativeMethods.INFOTIPSIZE - 1); } else m_strDesc = value; } } public ShellLinkEx() { } public ShellLinkEx(string strPath, string strArgs, string strDesc) { m_strPath = strPath; m_strArgs = strArgs; this.Description = strDesc; // Shortens description if necessary } public static ShellLinkEx Load(string strLnkFilePath) { try { CShellLink csl = new CShellLink(); IShellLinkW sl = (csl as IShellLinkW); if(sl == null) { Debug.Assert(false); return null; } IPersistFile pf = (csl as IPersistFile); if(pf == null) { Debug.Assert(false); return null; } pf.Load(strLnkFilePath, (int)(NativeMethods.STGM.Read | NativeMethods.STGM.ShareDenyWrite)); const int ccMaxPath = KeePassLib.Native.NativeMethods.MAX_PATH; const int ccInfoTip = NativeMethods.INFOTIPSIZE; ShellLinkEx r = new ShellLinkEx(); StringBuilder sb = new StringBuilder(ccMaxPath + 1); sl.GetPath(sb, sb.Capacity, IntPtr.Zero, 0); r.Path = sb.ToString(); sb = new StringBuilder(ccInfoTip + 1); sl.GetArguments(sb, sb.Capacity); r.Arguments = sb.ToString(); sb = new StringBuilder(ccInfoTip + 1); sl.GetDescription(sb, sb.Capacity); r.Description = sb.ToString(); return r; } catch(Exception) { Debug.Assert(false); } return null; } public bool Save(string strLnkFilePath) { try { CShellLink csl = new CShellLink(); IShellLinkW sl = (csl as IShellLinkW); if(sl == null) { Debug.Assert(false); return false; } IPersistFile pf = (csl as IPersistFile); if(pf == null) { Debug.Assert(false); return false; } if(!string.IsNullOrEmpty(m_strPath)) sl.SetPath(m_strPath); if(!string.IsNullOrEmpty(m_strArgs)) sl.SetArguments(m_strArgs); if(!string.IsNullOrEmpty(m_strDesc)) sl.SetDescription(m_strDesc); pf.Save(strLnkFilePath, true); return true; } catch(Exception) { Debug.Assert(false); } return false; } } [ComImport] [Guid("000214F9-0000-0000-C000-000000000046")] [InterfaceType(ComInterfaceType.InterfaceIsIUnknown)] internal interface IShellLinkW { void GetPath([MarshalAs(UnmanagedType.LPWStr)] StringBuilder pszFile, int cch, IntPtr pfd, uint fFlags); void GetIDList(out IntPtr ppidl); void SetIDList(IntPtr pidl); void GetDescription([MarshalAs(UnmanagedType.LPWStr)] StringBuilder pszName, int cch); void SetDescription([MarshalAs(UnmanagedType.LPWStr)] string pszName); void GetWorkingDirectory([MarshalAs(UnmanagedType.LPWStr)] StringBuilder pszDir, int cch); void SetWorkingDirectory([MarshalAs(UnmanagedType.LPWStr)] string pszDir); void GetArguments([MarshalAs(UnmanagedType.LPWStr)] StringBuilder pszArgs, int cch); void SetArguments([MarshalAs(UnmanagedType.LPWStr)] string pszArgs); void GetHotkey(out ushort pwHotkey); void SetHotkey(ushort wHotkey); void GetShowCmd(out int piShowCmd); void SetShowCmd(int iShowCmd); void GetIconLocation([MarshalAs(UnmanagedType.LPWStr)] StringBuilder pszIconPath, int cch, out int piIcon); void SetIconLocation([MarshalAs(UnmanagedType.LPWStr)] string pszIconPath, int iIcon); void SetRelativePath([MarshalAs(UnmanagedType.LPWStr)] string pszPathRel, uint dwReserved); void Resolve(IntPtr hwnd, uint fFlags); void SetPath([MarshalAs(UnmanagedType.LPWStr)] string pszFile); } [ComImport] [Guid("00021401-0000-0000-C000-000000000046")] internal class CShellLink { } } KeePass/Native/NativeMethods.cs0000664000000000000000000004514113222430412015436 0ustar rootroot/* KeePass Password Safe - The Open-Source Password Manager Copyright (C) 2003-2018 Dominik Reichl This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ using System; using System.Text; using System.Security; using System.Runtime.InteropServices; using System.Windows.Forms; using System.Diagnostics; using KeePass.UI; namespace KeePass.Native { internal static partial class NativeMethods { [DllImport("Kernel32.dll", SetLastError = true, CharSet = CharSet.Auto)] [return: MarshalAs(UnmanagedType.Bool)] internal static extern bool SetDllDirectory(string lpPathName); [DllImport("User32.dll")] [return: MarshalAs(UnmanagedType.Bool)] private static extern bool IsWindow(IntPtr hWnd); [DllImport("User32.dll")] internal static extern IntPtr SendMessage(IntPtr hWnd, int nMsg, IntPtr wParam, IntPtr lParam); [DllImport("User32.dll", EntryPoint = "SendMessage")] internal static extern IntPtr SendMessageHDItem(IntPtr hWnd, int nMsg, IntPtr wParam, ref HDITEM hdItem); // [DllImport("User32.dll", EntryPoint = "SendMessage")] // private static extern IntPtr SendMessageLVGroup(IntPtr hWnd, int nMsg, // IntPtr wParam, ref LVGROUP lvGroup); [DllImport("User32.dll", SetLastError = true)] internal static extern IntPtr SendMessageTimeout(IntPtr hWnd, int nMsg, IntPtr wParam, IntPtr lParam, uint fuFlags, uint uTimeout, ref IntPtr lpdwResult); [DllImport("User32.dll")] [return: MarshalAs(UnmanagedType.Bool)] internal static extern bool PostMessage(IntPtr hWnd, int nMsg, IntPtr wParam, IntPtr lParam); // [DllImport("User32.dll")] // internal static extern uint GetMessagePos(); [DllImport("User32.dll", SetLastError = true, CharSet = CharSet.Auto)] internal static extern int RegisterWindowMessage(string lpString); // [DllImport("User32.dll")] // internal static extern IntPtr GetDesktopWindow(); [DllImport("User32.dll", SetLastError = true, CharSet = CharSet.Auto)] internal static extern IntPtr FindWindowEx(IntPtr hwndParent, IntPtr hwndChildAfter, string lpszClass, string lpszWindow); [DllImport("User32.dll")] internal static extern IntPtr GetWindow(IntPtr hWnd, uint uCmd); [DllImport("User32.dll")] internal static extern int GetWindowLong(IntPtr hWnd, int nIndex); [DllImport("User32.dll", SetLastError = true)] internal static extern int SetWindowLong(IntPtr hWnd, int nIndex, int dwNewLong); [DllImport("User32.dll", EntryPoint = "GetClassLong")] private static extern IntPtr GetClassLongPtr32(IntPtr hWnd, int nIndex); [DllImport("User32.dll", EntryPoint = "GetClassLongPtr")] private static extern IntPtr GetClassLongPtr64(IntPtr hWnd, int nIndex); // [DllImport("User32.dll", SetLastError = true, CharSet = CharSet.Auto)] // private static extern int GetClassName(IntPtr hWnd, // StringBuilder lpClassName, int nMaxCount); [DllImport("User32.dll")] [return: MarshalAs(UnmanagedType.Bool)] internal static extern bool IsIconic(IntPtr hWnd); [DllImport("User32.dll")] [return: MarshalAs(UnmanagedType.Bool)] internal static extern bool IsZoomed(IntPtr hWnd); [DllImport("User32.dll", SetLastError = true)] private static extern int GetWindowTextLength(IntPtr hWnd); [DllImport("User32.dll", SetLastError = true, CharSet = CharSet.Auto)] private static extern int GetWindowText(IntPtr hWnd, StringBuilder lpString, int nMaxCount); [DllImport("User32.dll", SetLastError = true)] [return: MarshalAs(UnmanagedType.Bool)] internal static extern bool GetWindowRect(IntPtr hWnd, ref RECT lpRect); // [DllImport("User32.dll")] // internal static extern IntPtr GetActiveWindow(); [DllImport("User32.dll")] private static extern IntPtr GetForegroundWindow(); // Private, is wrapped [DllImport("User32.dll")] [return: MarshalAs(UnmanagedType.Bool)] private static extern bool SetForegroundWindow(IntPtr hWnd); [DllImport("User32.dll")] [return: MarshalAs(UnmanagedType.Bool)] internal static extern bool EnumWindows(EnumWindowsProc lpEnumFunc, IntPtr lParam); [DllImport("User32.dll")] [return: MarshalAs(UnmanagedType.Bool)] internal static extern bool RegisterHotKey(IntPtr hWnd, int id, uint fsModifiers, uint vk); [DllImport("User32.dll")] [return: MarshalAs(UnmanagedType.Bool)] internal static extern bool UnregisterHotKey(IntPtr hWnd, int id); [DllImport("User32.dll", EntryPoint = "SendInput", SetLastError = true)] internal static extern uint SendInput32(uint nInputs, INPUT32[] pInputs, int cbSize); [DllImport("User32.dll", EntryPoint = "SendInput", SetLastError = true)] internal static extern uint SendInput64Special(uint nInputs, SpecializedKeyboardINPUT64[] pInputs, int cbSize); [DllImport("User32.dll")] internal static extern IntPtr GetMessageExtraInfo(); // [DllImport("User32.dll")] // internal static extern void keybd_event(byte bVk, byte bScan, uint dwFlags, // IntPtr dwExtraInfo); [DllImport("User32.dll")] private static extern uint MapVirtualKey(uint uCode, uint uMapType); [DllImport("User32.dll")] private static extern uint MapVirtualKeyEx(uint uCode, uint uMapType, IntPtr hKL); [DllImport("User32.dll", CharSet = CharSet.Auto)] private static extern ushort VkKeyScan(char ch); [DllImport("User32.dll", CharSet = CharSet.Auto)] private static extern ushort VkKeyScanEx(char ch, IntPtr hKL); [DllImport("User32.dll", CharSet = CharSet.Unicode, ExactSpelling = true)] private static extern int ToUnicode(uint wVirtKey, uint wScanCode, IntPtr lpKeyState, [MarshalAs(UnmanagedType.LPWStr)] StringBuilder sbBuff, int cchBuff, uint wFlags); [DllImport("User32.dll", CharSet = CharSet.Unicode, ExactSpelling = true)] private static extern int ToUnicodeEx(uint wVirtKey, uint wScanCode, IntPtr lpKeyState, [MarshalAs(UnmanagedType.LPWStr)] StringBuilder sbBuff, int cchBuff, uint wFlags, IntPtr hKL); // [DllImport("User32.dll")] // [return: MarshalAs(UnmanagedType.Bool)] // private static extern bool GetKeyboardState(IntPtr lpKeyState); [DllImport("User32.dll")] internal static extern ushort GetKeyState(int vKey); [DllImport("User32.dll")] internal static extern ushort GetAsyncKeyState(int vKey); [DllImport("User32.dll")] [return: MarshalAs(UnmanagedType.Bool)] internal static extern bool BlockInput([MarshalAs(UnmanagedType.Bool)] bool fBlockIt); // [DllImport("User32.dll")] // [return: MarshalAs(UnmanagedType.Bool)] // internal static extern bool AttachThreadInput(uint idAttach, // uint idAttachTo, [MarshalAs(UnmanagedType.Bool)] bool fAttach); [DllImport("User32.dll")] internal static extern IntPtr SetClipboardViewer(IntPtr hWndNewViewer); [DllImport("User32.dll")] [return: MarshalAs(UnmanagedType.Bool)] internal static extern bool ChangeClipboardChain(IntPtr hWndRemove, IntPtr hWndNewNext); [DllImport("User32.dll")] [return: MarshalAs(UnmanagedType.Bool)] internal static extern bool OpenClipboard(IntPtr hWndNewOwner); [DllImport("User32.dll")] [return: MarshalAs(UnmanagedType.Bool)] internal static extern bool EmptyClipboard(); [DllImport("User32.dll")] [return: MarshalAs(UnmanagedType.Bool)] internal static extern bool CloseClipboard(); [DllImport("User32.dll", SetLastError = true)] internal static extern IntPtr SetClipboardData(uint uFormat, IntPtr hMem); [DllImport("User32.dll", SetLastError = true)] internal static extern IntPtr GetClipboardData(uint uFormat); [DllImport("User32.dll", SetLastError = true, CharSet = CharSet.Auto)] internal static extern uint RegisterClipboardFormat(string lpszFormat); [DllImport("User32.dll")] internal static extern uint GetClipboardSequenceNumber(); // [DllImport("User32.dll")] // internal static extern IntPtr GetClipboardOwner(); [DllImport("Kernel32.dll")] internal static extern IntPtr GlobalAlloc(uint uFlags, UIntPtr dwBytes); [DllImport("Kernel32.dll")] internal static extern IntPtr GlobalFree(IntPtr hMem); [DllImport("Kernel32.dll")] internal static extern IntPtr GlobalLock(IntPtr hMem); [DllImport("Kernel32.dll", SetLastError = true)] [return: MarshalAs(UnmanagedType.Bool)] internal static extern bool GlobalUnlock(IntPtr hMem); [DllImport("Kernel32.dll")] internal static extern UIntPtr GlobalSize(IntPtr hMem); [DllImport("ShlWApi.dll", CharSet = CharSet.Auto)] [return: MarshalAs(UnmanagedType.Bool)] internal static extern bool PathCompactPathEx(StringBuilder pszOut, string szPath, uint cchMax, uint dwFlags); [DllImport("User32.dll")] [return: MarshalAs(UnmanagedType.Bool)] internal static extern bool DrawAnimatedRects(IntPtr hWnd, int idAni, [In] ref RECT lprcFrom, [In] ref RECT lprcTo); [DllImport("User32.dll")] [return: MarshalAs(UnmanagedType.Bool)] internal static extern bool GetComboBoxInfo(IntPtr hWnd, ref COMBOBOXINFO pcbi); [DllImport("User32.dll", SetLastError = true, CharSet = CharSet.Auto)] internal static extern IntPtr CreateDesktop(string lpszDesktop, string lpszDevice, IntPtr pDevMode, UInt32 dwFlags, [MarshalAs(UnmanagedType.U4)] DesktopFlags dwDesiredAccess, IntPtr lpSecurityAttributes); [DllImport("User32.dll", SetLastError = true)] [return: MarshalAs(UnmanagedType.Bool)] internal static extern bool CloseDesktop(IntPtr hDesktop); // [DllImport("User32.dll", SetLastError = true)] // internal static extern IntPtr OpenDesktop(string lpszDesktop, // UInt32 dwFlags, [MarshalAs(UnmanagedType.Bool)] bool fInherit, // [MarshalAs(UnmanagedType.U4)] DesktopFlags dwDesiredAccess); [DllImport("User32.dll", SetLastError = true)] [return: MarshalAs(UnmanagedType.Bool)] internal static extern bool SwitchDesktop(IntPtr hDesktop); [DllImport("User32.dll", SetLastError = true)] internal static extern IntPtr OpenInputDesktop(uint dwFlags, [MarshalAs(UnmanagedType.Bool)] bool fInherit, [MarshalAs(UnmanagedType.U4)] DesktopFlags dwDesiredAccess); [DllImport("User32.dll", SetLastError = true)] [return: MarshalAs(UnmanagedType.Bool)] internal static extern bool GetUserObjectInformation(IntPtr hObj, int nIndex, IntPtr pvInfo, uint nLength, ref uint lpnLengthNeeded); [DllImport("User32.dll", SetLastError = true)] internal static extern IntPtr GetThreadDesktop(uint dwThreadId); [DllImport("User32.dll", SetLastError = true)] [return: MarshalAs(UnmanagedType.Bool)] internal static extern bool SetThreadDesktop(IntPtr hDesktop); [DllImport("Kernel32.dll")] internal static extern uint GetCurrentThreadId(); // [DllImport("Imm32.dll")] // [return: MarshalAs(UnmanagedType.Bool)] // internal static extern bool ImmDisableIME(uint idThread); // [DllImport("Imm32.dll")] // internal static extern IntPtr ImmAssociateContext(IntPtr hWnd, IntPtr hIMC); [DllImport("Kernel32.dll", SetLastError = true, CharSet = CharSet.Auto)] internal static extern IntPtr CreateFile(string lpFileName, [MarshalAs(UnmanagedType.U4)] EFileAccess dwDesiredAccess, [MarshalAs(UnmanagedType.U4)] EFileShare dwShareMode, IntPtr lpSecurityAttributes, [MarshalAs(UnmanagedType.U4)] ECreationDisposition dwCreationDisposition, [MarshalAs(UnmanagedType.U4)] uint dwFlagsAndAttributes, IntPtr hTemplateFile); [DllImport("Kernel32.dll", SetLastError = true)] [return: MarshalAs(UnmanagedType.Bool)] internal static extern bool CloseHandle(IntPtr hObject); [DllImport("Kernel32.dll", SetLastError = true, CharSet = CharSet.Auto)] internal static extern uint GetFileAttributes(string lpFileName); [DllImport("Kernel32.dll", SetLastError = true, CharSet = CharSet.Auto)] [return: MarshalAs(UnmanagedType.Bool)] internal static extern bool DeleteFile(string lpFileName); [DllImport("Kernel32.dll", ExactSpelling = true, SetLastError = true)] [return: MarshalAs(UnmanagedType.Bool)] internal static extern bool DeviceIoControl(IntPtr hDevice, uint dwIoControlCode, IntPtr lpInBuffer, uint nInBufferSize, IntPtr lpOutBuffer, uint nOutBufferSize, out uint lpBytesReturned, IntPtr lpOverlapped); [DllImport("ComCtl32.dll", CharSet = CharSet.Auto)] internal static extern Int32 TaskDialogIndirect([In] ref VtdConfig pTaskConfig, [Out] out int pnButton, [Out] out int pnRadioButton, [Out] [MarshalAs(UnmanagedType.Bool)] out bool pfVerificationFlagChecked); [DllImport("UxTheme.dll", ExactSpelling = true, CharSet = CharSet.Unicode)] internal static extern int SetWindowTheme(IntPtr hWnd, string pszSubAppName, string pszSubIdList); [DllImport("Shell32.dll")] internal static extern void SHChangeNotify(int wEventId, uint uFlags, IntPtr dwItem1, IntPtr dwItem2); [DllImport("User32.dll")] [return: MarshalAs(UnmanagedType.Bool)] private static extern bool GetScrollInfo(IntPtr hwnd, int fnBar, ref SCROLLINFO lpsi); // [DllImport("User32.dll")] // private static extern int SetScrollInfo(IntPtr hwnd, int fnBar, // [In] ref SCROLLINFO lpsi, [MarshalAs(UnmanagedType.Bool)] bool fRedraw); // [DllImport("User32.dll")] // private static extern int ScrollWindowEx(IntPtr hWnd, int dx, int dy, // IntPtr prcScroll, IntPtr prcClip, IntPtr hrgnUpdate, IntPtr prcUpdate, // uint flags); [DllImport("User32.dll")] internal static extern IntPtr GetKeyboardLayout(uint idThread); [DllImport("User32.dll")] internal static extern IntPtr ActivateKeyboardLayout(IntPtr hkl, uint uFlags); [DllImport("User32.dll")] internal static extern uint GetWindowThreadProcessId(IntPtr hWnd, [Out] out uint lpdwProcessId); // [DllImport("UxTheme.dll")] // internal static extern IntPtr OpenThemeData(IntPtr hWnd, // [MarshalAs(UnmanagedType.LPWStr)] string pszClassList); // [DllImport("UxTheme.dll")] // internal static extern uint CloseThemeData(IntPtr hTheme); // [DllImport("UxTheme.dll")] // internal extern static uint DrawThemeBackground(IntPtr hTheme, IntPtr hdc, // int iPartId, int iStateId, ref RECT pRect, ref RECT pClipRect); [DllImport("Gdi32.dll")] [return: MarshalAs(UnmanagedType.Bool)] internal static extern bool DeleteObject(IntPtr hObject); [DllImport("User32.dll")] [return: MarshalAs(UnmanagedType.Bool)] private static extern bool GetLastInputInfo(ref LASTINPUTINFO plii); [DllImport("Shell32.dll", CharSet = CharSet.Auto)] private static extern IntPtr SHGetFileInfo(string pszPath, uint dwFileAttributes, ref SHFILEINFO psfi, uint cbFileInfo, uint uFlags); [DllImport("User32.dll")] [return: MarshalAs(UnmanagedType.Bool)] internal static extern bool DestroyIcon(IntPtr hIcon); // [DllImport("User32.dll", SetLastError = true)] // [return: MarshalAs(UnmanagedType.Bool)] // internal static extern bool DrawIconEx(IntPtr hdc, int xLeft, int yTop, // IntPtr hIcon, int cxWidth, int cyWidth, uint istepIfAniCur, // IntPtr hbrFlickerFreeDraw, uint diFlags); [DllImport("User32.dll")] internal static extern IntPtr GetDC(IntPtr hWnd); [DllImport("User32.dll")] internal static extern int ReleaseDC(IntPtr hWnd, IntPtr hDC); [DllImport("Gdi32.dll")] internal static extern int GetDeviceCaps(IntPtr hdc, int nIndex); [DllImport("WinMM.dll", CharSet = CharSet.Auto)] [return: MarshalAs(UnmanagedType.Bool)] internal static extern bool PlaySound(string pszSound, IntPtr hmod, uint fdwSound); [DllImport("Shell32.dll", CharSet = CharSet.Auto)] internal static extern IntPtr ShellExecute(IntPtr hwnd, string lpOperation, string lpFile, string lpParameters, string lpDirectory, int nShowCmd); [DllImport("User32.dll", CharSet = CharSet.Auto)] internal static extern int MessageBox(IntPtr hWnd, string lpText, string lpCaption, [MarshalAs(UnmanagedType.U4)] MessageBoxFlags uType); [DllImport("User32.dll")] [return: MarshalAs(UnmanagedType.Bool)] internal static extern bool SetProcessDPIAware(); [DllImport("ShCore.dll")] internal static extern int SetProcessDpiAwareness( [MarshalAs(UnmanagedType.U4)] ProcessDpiAwareness a); [DllImport("Kernel32.dll")] internal static extern IntPtr CreateToolhelp32Snapshot( [MarshalAs(UnmanagedType.U4)] ToolHelpFlags dwFlags, uint th32ProcessID); [DllImport("Kernel32.dll", CharSet = CharSet.Auto)] [return: MarshalAs(UnmanagedType.Bool)] internal static extern bool Process32First(IntPtr hSnapshot, ref PROCESSENTRY32 lppe); [DllImport("Kernel32.dll", CharSet = CharSet.Auto)] [return: MarshalAs(UnmanagedType.Bool)] internal static extern bool Process32Next(IntPtr hSnapshot, ref PROCESSENTRY32 lppe); // [DllImport("Kernel32.dll", SetLastError = true)] // internal static extern IntPtr OpenProcess(uint dwDesiredAccess, // [MarshalAs(UnmanagedType.Bool)] bool bInheritHandle, uint dwProcessId); // [DllImport("User32.dll")] // [return: MarshalAs(UnmanagedType.Bool)] // internal static extern bool IsImmersiveProcess(IntPtr hProcess); [DllImport("Kernel32.dll", CharSet = CharSet.Auto)] internal static extern IntPtr CreateActCtx(ref ACTCTX pActCtx); [DllImport("Kernel32.dll")] internal static extern void ReleaseActCtx(IntPtr hActCtx); [DllImport("Kernel32.dll")] [return: MarshalAs(UnmanagedType.Bool)] internal static extern bool ActivateActCtx(IntPtr hActCtx, ref UIntPtr lpCookie); [DllImport("Kernel32.dll")] [return: MarshalAs(UnmanagedType.Bool)] internal static extern bool DeactivateActCtx(uint dwFlags, UIntPtr ulCookie); [DllImport("User32.dll", SetLastError = true)] [return: MarshalAs(UnmanagedType.Bool)] internal static extern bool ShutdownBlockReasonCreate(IntPtr hWnd, [MarshalAs(UnmanagedType.LPWStr)] string pwszReason); [DllImport("User32.dll", SetLastError = true)] [return: MarshalAs(UnmanagedType.Bool)] internal static extern bool ShutdownBlockReasonDestroy(IntPtr hWnd); // [DllImport("User32.dll")] // internal static extern int GetSystemMetrics(int nIndex); } } KeePass/KeePassLib/0000775000000000000000000000000012606740434013101 5ustar rootrootKeePass/KeePassLib/Delegates/0000775000000000000000000000000013015635736015001 5ustar rootrootKeePass/KeePassLib/Collections/0000775000000000000000000000000010417651566015364 5ustar rootrootKeePass/KeePassLib/Keys/0000775000000000000000000000000010566354210014010 5ustar rootrootKeePass/KeePassLib/Translation/0000775000000000000000000000000010756004762015400 5ustar rootrootKeePass/KeePassLib/Interfaces/0000775000000000000000000000000010411330300015137 5ustar rootrootKeePass/KeePassLib/Utility/0000775000000000000000000000000010566354244014547 5ustar rootrootKeePass/KeePassLib/Resources/0000775000000000000000000000000010577552046015060 5ustar rootrootKeePass/KeePassLib/Security/0000775000000000000000000000000010566354530014711 5ustar rootrootKeePass/KeePassLib/Native/0000775000000000000000000000000010603243112014311 5ustar rootrootKeePass/KeePassLib/Cryptography/0000775000000000000000000000000012734522072015572 5ustar rootrootKeePass/KeePassLib/Cryptography/KeyDerivation/0000775000000000000000000000000012732510540020342 5ustar rootrootKeePass/KeePassLib/Cryptography/Cipher/0000775000000000000000000000000010566354140017004 5ustar rootrootKeePass/KeePassLib/Cryptography/Hash/0000775000000000000000000000000012734522072016455 5ustar rootrootKeePass/KeePassLib/Cryptography/PasswordGenerator/0000775000000000000000000000000010666473212021246 5ustar rootrootKeePass/KeePassLib/Serialization/0000775000000000000000000000000010567077776015736 5ustar rootrootKeePass/Forms/0000775000000000000000000000000013224154300012171 5ustar rootrootKeePass/Forms/EditAutoTypeItemForm.Designer.cs0000664000000000000000000002544012507243066020322 0ustar rootrootnamespace KeePass.Forms { partial class EditAutoTypeItemForm { /// /// Erforderliche Designervariable. /// private System.ComponentModel.IContainer components = null; /// /// Verwendete Ressourcen bereinigen. /// /// True, wenn verwaltete Ressourcen gelöscht werden sollen; andernfalls False. protected override void Dispose(bool disposing) { if(disposing && (components != null)) { components.Dispose(); } base.Dispose(disposing); } #region Vom Windows Form-Designer generierter Code /// /// Erforderliche Methode für die Designerunterstützung. /// Der Inhalt der Methode darf nicht mit dem Code-Editor geändert werden. /// private void InitializeComponent() { this.m_bannerImage = new System.Windows.Forms.PictureBox(); this.m_btnOK = new System.Windows.Forms.Button(); this.m_btnCancel = new System.Windows.Forms.Button(); this.m_btnHelp = new System.Windows.Forms.Button(); this.m_lblTargetWindow = new System.Windows.Forms.Label(); this.m_lblKeySeqInsertInfo = new System.Windows.Forms.Label(); this.m_lblSeparator = new System.Windows.Forms.Label(); this.m_lblOpenHint = new System.Windows.Forms.Label(); this.m_lnkWildcardRegexHint = new System.Windows.Forms.LinkLabel(); this.m_rbSeqDefault = new System.Windows.Forms.RadioButton(); this.m_rbSeqCustom = new System.Windows.Forms.RadioButton(); this.m_cmbWindow = new KeePass.UI.ImageComboBoxEx(); this.m_rtbPlaceholders = new KeePass.UI.CustomRichTextBoxEx(); this.m_rbKeySeq = new KeePass.UI.CustomRichTextBoxEx(); ((System.ComponentModel.ISupportInitialize)(this.m_bannerImage)).BeginInit(); this.SuspendLayout(); // // m_bannerImage // this.m_bannerImage.Dock = System.Windows.Forms.DockStyle.Top; this.m_bannerImage.Location = new System.Drawing.Point(0, 0); this.m_bannerImage.Name = "m_bannerImage"; this.m_bannerImage.Size = new System.Drawing.Size(511, 60); this.m_bannerImage.TabIndex = 0; this.m_bannerImage.TabStop = false; // // m_btnOK // this.m_btnOK.DialogResult = System.Windows.Forms.DialogResult.OK; this.m_btnOK.Location = new System.Drawing.Point(343, 388); this.m_btnOK.Name = "m_btnOK"; this.m_btnOK.Size = new System.Drawing.Size(75, 23); this.m_btnOK.TabIndex = 8; this.m_btnOK.Text = "OK"; this.m_btnOK.UseVisualStyleBackColor = true; this.m_btnOK.Click += new System.EventHandler(this.OnBtnOK); // // m_btnCancel // this.m_btnCancel.DialogResult = System.Windows.Forms.DialogResult.Cancel; this.m_btnCancel.Location = new System.Drawing.Point(424, 388); this.m_btnCancel.Name = "m_btnCancel"; this.m_btnCancel.Size = new System.Drawing.Size(75, 23); this.m_btnCancel.TabIndex = 9; this.m_btnCancel.Text = "Cancel"; this.m_btnCancel.UseVisualStyleBackColor = true; this.m_btnCancel.Click += new System.EventHandler(this.OnBtnCancel); // // m_btnHelp // this.m_btnHelp.Location = new System.Drawing.Point(12, 388); this.m_btnHelp.Name = "m_btnHelp"; this.m_btnHelp.Size = new System.Drawing.Size(75, 23); this.m_btnHelp.TabIndex = 10; this.m_btnHelp.Text = "&Help"; this.m_btnHelp.UseVisualStyleBackColor = true; this.m_btnHelp.Click += new System.EventHandler(this.OnBtnHelp); // // m_lblTargetWindow // this.m_lblTargetWindow.AutoSize = true; this.m_lblTargetWindow.Location = new System.Drawing.Point(9, 75); this.m_lblTargetWindow.Name = "m_lblTargetWindow"; this.m_lblTargetWindow.Size = new System.Drawing.Size(80, 13); this.m_lblTargetWindow.TabIndex = 12; this.m_lblTargetWindow.Text = "Target window:"; // // m_lblKeySeqInsertInfo // this.m_lblKeySeqInsertInfo.AutoSize = true; this.m_lblKeySeqInsertInfo.Location = new System.Drawing.Point(29, 214); this.m_lblKeySeqInsertInfo.Name = "m_lblKeySeqInsertInfo"; this.m_lblKeySeqInsertInfo.Size = new System.Drawing.Size(94, 13); this.m_lblKeySeqInsertInfo.TabIndex = 6; this.m_lblKeySeqInsertInfo.Text = "Insert placeholder:"; // // m_lblSeparator // this.m_lblSeparator.BorderStyle = System.Windows.Forms.BorderStyle.Fixed3D; this.m_lblSeparator.Location = new System.Drawing.Point(0, 379); this.m_lblSeparator.Name = "m_lblSeparator"; this.m_lblSeparator.Size = new System.Drawing.Size(511, 2); this.m_lblSeparator.TabIndex = 11; // // m_lblOpenHint // this.m_lblOpenHint.AutoSize = true; this.m_lblOpenHint.Location = new System.Drawing.Point(92, 99); this.m_lblOpenHint.Name = "m_lblOpenHint"; this.m_lblOpenHint.Size = new System.Drawing.Size(351, 13); this.m_lblOpenHint.TabIndex = 1; this.m_lblOpenHint.Text = "Click the drop-down button on the right to see currently opened windows."; // // m_lnkWildcardRegexHint // this.m_lnkWildcardRegexHint.AutoSize = true; this.m_lnkWildcardRegexHint.Location = new System.Drawing.Point(92, 116); this.m_lnkWildcardRegexHint.Name = "m_lnkWildcardRegexHint"; this.m_lnkWildcardRegexHint.Size = new System.Drawing.Size(270, 13); this.m_lnkWildcardRegexHint.TabIndex = 2; this.m_lnkWildcardRegexHint.TabStop = true; this.m_lnkWildcardRegexHint.Text = "Simple wildcards and regular expressions are supported."; this.m_lnkWildcardRegexHint.LinkClicked += new System.Windows.Forms.LinkLabelLinkClickedEventHandler(this.OnWildcardRegexLinkClicked); // // m_rbSeqDefault // this.m_rbSeqDefault.AutoSize = true; this.m_rbSeqDefault.Location = new System.Drawing.Point(12, 142); this.m_rbSeqDefault.Name = "m_rbSeqDefault"; this.m_rbSeqDefault.Size = new System.Drawing.Size(234, 17); this.m_rbSeqDefault.TabIndex = 3; this.m_rbSeqDefault.TabStop = true; this.m_rbSeqDefault.Text = "Use default keystroke sequence of the entry"; this.m_rbSeqDefault.UseVisualStyleBackColor = true; this.m_rbSeqDefault.CheckedChanged += new System.EventHandler(this.OnSeqDefaultCheckedChanged); // // m_rbSeqCustom // this.m_rbSeqCustom.AutoSize = true; this.m_rbSeqCustom.Location = new System.Drawing.Point(12, 164); this.m_rbSeqCustom.Name = "m_rbSeqCustom"; this.m_rbSeqCustom.Size = new System.Drawing.Size(183, 17); this.m_rbSeqCustom.TabIndex = 4; this.m_rbSeqCustom.TabStop = true; this.m_rbSeqCustom.Text = "Use custom keystroke sequence:"; this.m_rbSeqCustom.UseVisualStyleBackColor = true; this.m_rbSeqCustom.CheckedChanged += new System.EventHandler(this.OnSeqCustomCheckedChanged); // // m_cmbWindow // this.m_cmbWindow.IntegralHeight = false; this.m_cmbWindow.Location = new System.Drawing.Point(95, 72); this.m_cmbWindow.Name = "m_cmbWindow"; this.m_cmbWindow.Size = new System.Drawing.Size(404, 21); this.m_cmbWindow.TabIndex = 0; this.m_cmbWindow.SelectedIndexChanged += new System.EventHandler(this.OnWindowSelectedIndexChanged); this.m_cmbWindow.TextUpdate += new System.EventHandler(this.OnWindowTextUpdate); // // m_rtbPlaceholders // this.m_rtbPlaceholders.BorderStyle = System.Windows.Forms.BorderStyle.FixedSingle; this.m_rtbPlaceholders.Location = new System.Drawing.Point(32, 230); this.m_rtbPlaceholders.Name = "m_rtbPlaceholders"; this.m_rtbPlaceholders.ReadOnly = true; this.m_rtbPlaceholders.ScrollBars = System.Windows.Forms.RichTextBoxScrollBars.ForcedVertical; this.m_rtbPlaceholders.Size = new System.Drawing.Size(467, 136); this.m_rtbPlaceholders.TabIndex = 7; this.m_rtbPlaceholders.Text = ""; this.m_rtbPlaceholders.LinkClicked += new System.Windows.Forms.LinkClickedEventHandler(this.OnPlaceholdersLinkClicked); // // m_rbKeySeq // this.m_rbKeySeq.DetectUrls = false; this.m_rbKeySeq.Font = new System.Drawing.Font("Courier New", 8.25F); this.m_rbKeySeq.HideSelection = false; this.m_rbKeySeq.Location = new System.Drawing.Point(32, 187); this.m_rbKeySeq.Multiline = false; this.m_rbKeySeq.Name = "m_rbKeySeq"; this.m_rbKeySeq.Size = new System.Drawing.Size(467, 21); this.m_rbKeySeq.TabIndex = 5; this.m_rbKeySeq.Text = ""; this.m_rbKeySeq.TextChanged += new System.EventHandler(this.OnTextChangedKeySeq); // // EditAutoTypeItemForm // this.AcceptButton = this.m_btnOK; this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F); this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; this.CancelButton = this.m_btnCancel; this.ClientSize = new System.Drawing.Size(511, 423); this.Controls.Add(this.m_rbSeqCustom); this.Controls.Add(this.m_rbSeqDefault); this.Controls.Add(this.m_lnkWildcardRegexHint); this.Controls.Add(this.m_lblOpenHint); this.Controls.Add(this.m_cmbWindow); this.Controls.Add(this.m_rtbPlaceholders); this.Controls.Add(this.m_rbKeySeq); this.Controls.Add(this.m_lblSeparator); this.Controls.Add(this.m_lblKeySeqInsertInfo); this.Controls.Add(this.m_lblTargetWindow); this.Controls.Add(this.m_btnHelp); this.Controls.Add(this.m_btnCancel); this.Controls.Add(this.m_btnOK); this.Controls.Add(this.m_bannerImage); this.FormBorderStyle = System.Windows.Forms.FormBorderStyle.FixedDialog; this.MaximizeBox = false; this.MinimizeBox = false; this.Name = "EditAutoTypeItemForm"; this.ShowInTaskbar = false; this.SizeGripStyle = System.Windows.Forms.SizeGripStyle.Hide; this.StartPosition = System.Windows.Forms.FormStartPosition.CenterParent; this.Text = "Edit Auto-Type Item"; this.Load += new System.EventHandler(this.OnFormLoad); this.Shown += new System.EventHandler(this.OnFormShown); this.FormClosed += new System.Windows.Forms.FormClosedEventHandler(this.OnFormClosed); this.FormClosing += new System.Windows.Forms.FormClosingEventHandler(this.OnFormClosing); ((System.ComponentModel.ISupportInitialize)(this.m_bannerImage)).EndInit(); this.ResumeLayout(false); this.PerformLayout(); } #endregion private System.Windows.Forms.PictureBox m_bannerImage; private System.Windows.Forms.Button m_btnOK; private System.Windows.Forms.Button m_btnCancel; private System.Windows.Forms.Button m_btnHelp; private System.Windows.Forms.Label m_lblTargetWindow; private System.Windows.Forms.Label m_lblKeySeqInsertInfo; private System.Windows.Forms.Label m_lblSeparator; private KeePass.UI.CustomRichTextBoxEx m_rbKeySeq; private KeePass.UI.CustomRichTextBoxEx m_rtbPlaceholders; private KeePass.UI.ImageComboBoxEx m_cmbWindow; private System.Windows.Forms.Label m_lblOpenHint; private System.Windows.Forms.LinkLabel m_lnkWildcardRegexHint; private System.Windows.Forms.RadioButton m_rbSeqDefault; private System.Windows.Forms.RadioButton m_rbSeqCustom; } }KeePass/Forms/EntryReportForm.Designer.cs0000664000000000000000000000417111134431162017405 0ustar rootrootnamespace KeePass.Forms { partial class EntryReportForm { /// /// Required designer variable. /// private System.ComponentModel.IContainer components = null; /// /// Clean up any resources being used. /// /// true if managed resources should be disposed; otherwise, false. protected override void Dispose(bool disposing) { if(disposing && (components != null)) { components.Dispose(); } base.Dispose(disposing); } #region Windows Form Designer generated code /// /// Required method for Designer support - do not modify /// the contents of this method with the code editor. /// private void InitializeComponent() { this.m_lvEntries = new KeePass.UI.CustomListViewEx(); this.SuspendLayout(); // // m_lvEntries // this.m_lvEntries.Dock = System.Windows.Forms.DockStyle.Fill; this.m_lvEntries.FullRowSelect = true; this.m_lvEntries.GridLines = true; this.m_lvEntries.HeaderStyle = System.Windows.Forms.ColumnHeaderStyle.Nonclickable; this.m_lvEntries.Location = new System.Drawing.Point(0, 0); this.m_lvEntries.Name = "m_lvEntries"; this.m_lvEntries.ShowItemToolTips = true; this.m_lvEntries.Size = new System.Drawing.Size(612, 412); this.m_lvEntries.TabIndex = 0; this.m_lvEntries.UseCompatibleStateImageBehavior = false; this.m_lvEntries.View = System.Windows.Forms.View.Details; // // EntryReportForm // this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F); this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; this.ClientSize = new System.Drawing.Size(612, 412); this.Controls.Add(this.m_lvEntries); this.MinimizeBox = false; this.Name = "EntryReportForm"; this.ShowInTaskbar = false; this.StartPosition = System.Windows.Forms.FormStartPosition.CenterParent; this.Text = "<>"; this.Load += new System.EventHandler(this.OnFormLoad); this.ResumeLayout(false); } #endregion private KeePass.UI.CustomListViewEx m_lvEntries; } }KeePass/Forms/AutoTypeCtxForm.cs0000664000000000000000000002100513222430410015570 0ustar rootroot/* KeePass Password Safe - The Open-Source Password Manager Copyright (C) 2003-2018 Dominik Reichl This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ using System; using System.Collections.Generic; using System.ComponentModel; using System.Diagnostics; using System.Drawing; using System.Text; using System.Windows.Forms; using KeePass.App; using KeePass.App.Configuration; using KeePass.Resources; using KeePass.UI; using KeePass.Util; using KeePassLib; namespace KeePass.Forms { public partial class AutoTypeCtxForm : Form { private List m_lCtxs = null; private ImageList m_ilIcons = null; private string m_strInitialFormRect = string.Empty; private string m_strInitialColWidths = string.Empty; private int m_nBannerWidth = -1; private bool m_bCanShowPasswords = true; private CustomContextMenuStripEx m_ctxTools = null; private ToolStripMenuItem m_tsmiColumns = null; private AutoTypeCtx m_atcSel = null; public AutoTypeCtx SelectedCtx { get { return m_atcSel; } } public void InitEx(List lCtxs, ImageList ilIcons) { m_lCtxs = lCtxs; m_ilIcons = UIUtil.CloneImageList(ilIcons, true); } public AutoTypeCtxForm() { InitializeComponent(); Program.Translation.ApplyTo(this); } private void OnFormLoad(object sender, EventArgs e) { Size sz = this.ClientSize; this.MinimumSize = new Size((int)(0.949f * (float)sz.Width), (int)(0.824f * (float)sz.Height)); GlobalWindowManager.AddWindow(this); Debug.Assert(!m_lblText.AutoSize); // For RTL support m_lblText.Text = KPRes.AutoTypeEntrySelectionDescLong2; this.Text = KPRes.AutoTypeEntrySelection; this.Icon = AppIcons.Default; m_strInitialFormRect = UIUtil.SetWindowScreenRectEx(this, Program.Config.UI.AutoTypeCtxRect); UIUtil.SetExplorerTheme(m_lvItems, true); if(m_ilIcons != null) m_lvItems.SmallImageList = m_ilIcons; else { Debug.Assert(false); m_ilIcons = new ImageList(); } m_bCanShowPasswords = AppPolicy.Current.UnhidePasswords; RecreateEntryList(); string strColWidths = Program.Config.UI.AutoTypeCtxColumnWidths; if(strColWidths.Length > 0) UIUtil.SetColumnWidths(m_lvItems, strColWidths); m_strInitialColWidths = UIUtil.GetColumnWidths(m_lvItems); ProcessResize(); this.BringToFront(); this.Activate(); UIUtil.SetFocus(m_lvItems, this); } private void RecreateEntryList() { long lFlags = Program.Config.UI.AutoTypeCtxFlags; if(!m_bCanShowPasswords) lFlags &= ~(long)AceAutoTypeCtxFlags.ColPassword; UIUtil.CreateEntryList(m_lvItems, m_lCtxs, (AceAutoTypeCtxFlags)lFlags, m_ilIcons); } private void OnFormClosed(object sender, FormClosedEventArgs e) { CleanUpEx(); GlobalWindowManager.RemoveWindow(this); } private void CleanUpEx() { string strColWidths = UIUtil.GetColumnWidths(m_lvItems); if(strColWidths != m_strInitialColWidths) Program.Config.UI.AutoTypeCtxColumnWidths = strColWidths; string strRect = UIUtil.GetWindowScreenRect(this); if(strRect != m_strInitialFormRect) // Don't overwrite "" Program.Config.UI.AutoTypeCtxRect = strRect; DestroyToolsContextMenu(); if(m_ilIcons != null) { m_lvItems.SmallImageList = null; // Detach event handlers m_ilIcons.Dispose(); m_ilIcons = null; } } private void ProcessResize() { if(m_lCtxs == null) return; // TrlUtil or design mode string strSub = KPRes.AutoTypeEntrySelectionDescShort; int n = m_lCtxs.Count; if(n == 1) strSub = KPRes.SearchEntriesFound1 + "."; else if(n <= 0) { strSub = KPRes.SearchEntriesFound + "."; strSub = strSub.Replace(@"{PARAM}", "0"); } BannerFactory.UpdateBanner(this, m_bannerImage, Properties.Resources.B48x48_KGPG_Key2, KPRes.AutoTypeEntrySelection, strSub, ref m_nBannerWidth); } private bool GetSelectedEntry() { ListView.SelectedListViewItemCollection slvic = m_lvItems.SelectedItems; if(slvic.Count == 1) { m_atcSel = (slvic[0].Tag as AutoTypeCtx); return (m_atcSel != null); } return false; } private void ProcessItemSelection() { if(this.DialogResult == DialogResult.OK) return; // Already closing if(GetSelectedEntry()) this.DialogResult = DialogResult.OK; } private void OnListItemActivate(object sender, EventArgs e) { ProcessItemSelection(); } // The item activation handler has a slight delay when clicking an // item, thus as a performance optimization we additionally handle // item clicks private void OnListClick(object sender, EventArgs e) { ProcessItemSelection(); } private void OnFormResize(object sender, EventArgs e) { ProcessResize(); } private void DestroyToolsContextMenu() { if(m_ctxTools == null) return; foreach(ToolStripItem tsi in m_tsmiColumns.DropDownItems) tsi.Click -= this.OnToggleColumn; m_tsmiColumns = null; m_ctxTools.Dispose(); m_ctxTools = null; } private void RecreateToolsContextMenu() { DestroyToolsContextMenu(); m_ctxTools = new CustomContextMenuStripEx(); m_tsmiColumns = new ToolStripMenuItem(KPRes.Columns); m_ctxTools.Items.Add(m_tsmiColumns); long lFlags = Program.Config.UI.AutoTypeCtxFlags; ToolStripMenuItem tsmi = new ToolStripMenuItem(KPRes.Title); UIUtil.SetChecked(tsmi, true); tsmi.Tag = AceAutoTypeCtxFlags.ColTitle; tsmi.Click += this.OnToggleColumn; tsmi.Enabled = false; m_tsmiColumns.DropDownItems.Add(tsmi); tsmi = new ToolStripMenuItem(KPRes.UserName); UIUtil.SetChecked(tsmi, ((lFlags & (long)AceAutoTypeCtxFlags.ColUserName) != 0)); tsmi.Tag = AceAutoTypeCtxFlags.ColUserName; tsmi.Click += this.OnToggleColumn; m_tsmiColumns.DropDownItems.Add(tsmi); tsmi = new ToolStripMenuItem(KPRes.Password); UIUtil.SetChecked(tsmi, (((lFlags & (long)AceAutoTypeCtxFlags.ColPassword) != 0) && m_bCanShowPasswords)); tsmi.Tag = AceAutoTypeCtxFlags.ColPassword; tsmi.Click += this.OnToggleColumn; if(!m_bCanShowPasswords) tsmi.Enabled = false; m_tsmiColumns.DropDownItems.Add(tsmi); tsmi = new ToolStripMenuItem(KPRes.Url); UIUtil.SetChecked(tsmi, ((lFlags & (long)AceAutoTypeCtxFlags.ColUrl) != 0)); tsmi.Tag = AceAutoTypeCtxFlags.ColUrl; tsmi.Click += this.OnToggleColumn; m_tsmiColumns.DropDownItems.Add(tsmi); tsmi = new ToolStripMenuItem(KPRes.Notes); UIUtil.SetChecked(tsmi, ((lFlags & (long)AceAutoTypeCtxFlags.ColNotes) != 0)); tsmi.Tag = AceAutoTypeCtxFlags.ColNotes; tsmi.Click += this.OnToggleColumn; m_tsmiColumns.DropDownItems.Add(tsmi); tsmi = new ToolStripMenuItem(KPRes.Sequence + " - " + KPRes.Comments); UIUtil.SetChecked(tsmi, ((lFlags & (long)AceAutoTypeCtxFlags.ColSequenceComments) != 0)); tsmi.Tag = AceAutoTypeCtxFlags.ColSequenceComments; tsmi.Click += this.OnToggleColumn; m_tsmiColumns.DropDownItems.Add(tsmi); tsmi = new ToolStripMenuItem(KPRes.Sequence); UIUtil.SetChecked(tsmi, ((lFlags & (long)AceAutoTypeCtxFlags.ColSequence) != 0)); tsmi.Tag = AceAutoTypeCtxFlags.ColSequence; tsmi.Click += this.OnToggleColumn; m_tsmiColumns.DropDownItems.Add(tsmi); } private void OnToggleColumn(object sender, EventArgs e) { ToolStripMenuItem tsmi = (sender as ToolStripMenuItem); if(tsmi == null) { Debug.Assert(false); return; } AceAutoTypeCtxFlags f = (AceAutoTypeCtxFlags)tsmi.Tag; long lFlags = Program.Config.UI.AutoTypeCtxFlags; lFlags ^= (long)f; lFlags |= (long)AceAutoTypeCtxFlags.ColTitle; // Enforce title Program.Config.UI.AutoTypeCtxFlags = lFlags; RecreateEntryList(); } private void OnBtnTools(object sender, EventArgs e) { RecreateToolsContextMenu(); m_ctxTools.ShowEx(m_btnTools); } } } KeePass/Forms/EcasActionForm.cs0000664000000000000000000000624513222430410015361 0ustar rootroot/* KeePass Password Safe - The Open-Source Password Manager Copyright (C) 2003-2018 Dominik Reichl This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ using System; using System.Collections.Generic; using System.ComponentModel; using System.Diagnostics; using System.Drawing; using System.Text; using System.Windows.Forms; using KeePass.App; using KeePass.Ecas; using KeePass.Resources; using KeePass.UI; using KeePassLib; using KeePassLib.Utility; namespace KeePass.Forms { public partial class EcasActionForm : Form { private EcasAction m_actionInOut = null; private EcasAction m_action = null; // Working copy private bool m_bBlockTypeSelectionHandler = false; public void InitEx(EcasAction e) { m_actionInOut = e; m_action = e.CloneDeep(); } public EcasActionForm() { InitializeComponent(); Program.Translation.ApplyTo(this); } private void OnFormLoad(object sender, EventArgs e) { GlobalWindowManager.AddWindow(this); this.Text = KPRes.Action; this.Icon = AppIcons.Default; Debug.Assert(!m_lblParamHint.AutoSize); // For RTL support m_lblParamHint.Text = KPRes.ParamDescHelp; foreach(EcasActionProvider ap in Program.EcasPool.ActionProviders) { foreach(EcasActionType t in ap.Actions) m_cmbActions.Items.Add(t.Name); } UpdateDataEx(m_action, false, EcasTypeDxMode.Selection); } private void OnFormClosed(object sender, FormClosedEventArgs e) { GlobalWindowManager.RemoveWindow(this); } private bool UpdateDataEx(EcasAction a, bool bGuiToInternal, EcasTypeDxMode dxType) { m_bBlockTypeSelectionHandler = true; bool bResult = EcasUtil.UpdateDialog(EcasObjectType.Action, m_cmbActions, m_dgvParams, a, bGuiToInternal, dxType); m_bBlockTypeSelectionHandler = false; return bResult; } private void OnBtnOK(object sender, EventArgs e) { if(!UpdateDataEx(m_actionInOut, true, EcasTypeDxMode.Selection)) this.DialogResult = DialogResult.None; } private void OnBtnCancel(object sender, EventArgs e) { } private void OnActionsSelectedIndexChanged(object sender, EventArgs e) { if(m_bBlockTypeSelectionHandler) return; UpdateDataEx(m_action, true, EcasTypeDxMode.ParamsTag); UpdateDataEx(m_action, false, EcasTypeDxMode.None); } private void OnBtnHelp(object sender, EventArgs e) { AppHelp.ShowHelp(AppDefs.HelpTopics.Triggers, AppDefs.HelpTopics.TriggersActions); } } } KeePass/Forms/TanWizardForm.resx0000664000000000000000000001373512501532426015642 0ustar rootroot text/microsoft-resx 2.0 System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 Paste your TANs into the edit box below. All characters that are not explicitly specified as TAN characters are treated as separators, and only substrings consisting of TAN characters are added as TAN entries. KeePass/Forms/LanguageForm.Designer.cs0000664000000000000000000001176113217213726016646 0ustar rootrootnamespace KeePass.Forms { partial class LanguageForm { /// /// Erforderliche Designervariable. /// private System.ComponentModel.IContainer components = null; /// /// Verwendete Ressourcen bereinigen. /// /// True, wenn verwaltete Ressourcen gelöscht werden sollen; andernfalls False. protected override void Dispose(bool disposing) { if(disposing && (components != null)) { components.Dispose(); } base.Dispose(disposing); } #region Vom Windows Form-Designer generierter Code /// /// Erforderliche Methode für die Designerunterstützung. /// Der Inhalt der Methode darf nicht mit dem Code-Editor geändert werden. /// private void InitializeComponent() { this.m_bannerImage = new System.Windows.Forms.PictureBox(); this.m_btnClose = new System.Windows.Forms.Button(); this.m_btnMore = new System.Windows.Forms.Button(); this.m_btnOpenFolder = new System.Windows.Forms.Button(); this.m_lvLanguages = new KeePass.UI.CustomListViewEx(); ((System.ComponentModel.ISupportInitialize)(this.m_bannerImage)).BeginInit(); this.SuspendLayout(); // // m_bannerImage // this.m_bannerImage.Dock = System.Windows.Forms.DockStyle.Top; this.m_bannerImage.Location = new System.Drawing.Point(0, 0); this.m_bannerImage.Name = "m_bannerImage"; this.m_bannerImage.Size = new System.Drawing.Size(708, 60); this.m_bannerImage.TabIndex = 0; this.m_bannerImage.TabStop = false; // // m_btnClose // this.m_btnClose.DialogResult = System.Windows.Forms.DialogResult.Cancel; this.m_btnClose.Location = new System.Drawing.Point(621, 321); this.m_btnClose.Name = "m_btnClose"; this.m_btnClose.Size = new System.Drawing.Size(75, 23); this.m_btnClose.TabIndex = 1; this.m_btnClose.Text = "&Close"; this.m_btnClose.UseVisualStyleBackColor = true; this.m_btnClose.Click += new System.EventHandler(this.OnBtnClose); // // m_btnMore // this.m_btnMore.Location = new System.Drawing.Point(13, 321); this.m_btnMore.Name = "m_btnMore"; this.m_btnMore.Size = new System.Drawing.Size(134, 23); this.m_btnMore.TabIndex = 2; this.m_btnMore.Text = "Get More &Languages..."; this.m_btnMore.UseVisualStyleBackColor = true; this.m_btnMore.Click += new System.EventHandler(this.OnBtnGetMore); // // m_btnOpenFolder // this.m_btnOpenFolder.Location = new System.Drawing.Point(153, 321); this.m_btnOpenFolder.Name = "m_btnOpenFolder"; this.m_btnOpenFolder.Size = new System.Drawing.Size(83, 23); this.m_btnOpenFolder.TabIndex = 3; this.m_btnOpenFolder.Text = "Open &Folder"; this.m_btnOpenFolder.UseVisualStyleBackColor = true; this.m_btnOpenFolder.Click += new System.EventHandler(this.OnBtnOpenFolder); // // m_lvLanguages // this.m_lvLanguages.Activation = System.Windows.Forms.ItemActivation.OneClick; this.m_lvLanguages.FullRowSelect = true; this.m_lvLanguages.HeaderStyle = System.Windows.Forms.ColumnHeaderStyle.Nonclickable; this.m_lvLanguages.HideSelection = false; this.m_lvLanguages.Location = new System.Drawing.Point(13, 67); this.m_lvLanguages.MultiSelect = false; this.m_lvLanguages.Name = "m_lvLanguages"; this.m_lvLanguages.ShowItemToolTips = true; this.m_lvLanguages.Size = new System.Drawing.Size(683, 248); this.m_lvLanguages.TabIndex = 0; this.m_lvLanguages.UseCompatibleStateImageBehavior = false; this.m_lvLanguages.View = System.Windows.Forms.View.Details; this.m_lvLanguages.ItemActivate += new System.EventHandler(this.OnLanguagesItemActivate); // // LanguageForm // this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F); this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; this.CancelButton = this.m_btnClose; this.ClientSize = new System.Drawing.Size(708, 356); this.Controls.Add(this.m_btnOpenFolder); this.Controls.Add(this.m_btnMore); this.Controls.Add(this.m_btnClose); this.Controls.Add(this.m_lvLanguages); this.Controls.Add(this.m_bannerImage); this.FormBorderStyle = System.Windows.Forms.FormBorderStyle.FixedDialog; this.MaximizeBox = false; this.MinimizeBox = false; this.Name = "LanguageForm"; this.ShowInTaskbar = false; this.StartPosition = System.Windows.Forms.FormStartPosition.CenterParent; this.Text = "<>"; this.Load += new System.EventHandler(this.OnFormLoad); this.FormClosed += new System.Windows.Forms.FormClosedEventHandler(this.OnFormClosed); ((System.ComponentModel.ISupportInitialize)(this.m_bannerImage)).EndInit(); this.ResumeLayout(false); } #endregion private System.Windows.Forms.PictureBox m_bannerImage; private KeePass.UI.CustomListViewEx m_lvLanguages; private System.Windows.Forms.Button m_btnClose; private System.Windows.Forms.Button m_btnMore; private System.Windows.Forms.Button m_btnOpenFolder; } }KeePass/Forms/EditAutoTypeItemForm.cs0000664000000000000000000005010713222430410016543 0ustar rootroot/* KeePass Password Safe - The Open-Source Password Manager Copyright (C) 2003-2018 Dominik Reichl This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ using System; using System.Collections.Generic; using System.ComponentModel; using System.Diagnostics; using System.Drawing; using System.Text; using System.Threading; using System.Windows.Forms; using KeePass.App; using KeePass.Native; using KeePass.Resources; using KeePass.UI; using KeePass.Util; using KeePass.Util.Spr; using KeePassLib; using KeePassLib.Collections; using KeePassLib.Security; using KeePassLib.Utility; using NativeLib = KeePassLib.Native.NativeLib; namespace KeePass.Forms { public partial class EditAutoTypeItemForm : Form { private AutoTypeConfig m_atConfig = null; private int m_iAssocIndex = -1; private bool m_bEditSequenceOnly = false; private string m_strDefaultSeq = string.Empty; private ProtectedStringDictionary m_vStringDict = null; private readonly object m_objDialogSync = new object(); private bool m_bDialogClosed = false; #if DEBUG private static Dictionary m_dWndTasks = new Dictionary(); private static readonly object m_oWndTasksSync = new object(); #endif // private Color m_clrOriginalForeground = Color.Black; // private Color m_clrOriginalBackground = Color.White; private List m_vWndImages = new List(); private RichTextBoxContextMenu m_ctxKeySeq = new RichTextBoxContextMenu(); private RichTextBoxContextMenu m_ctxKeyCodes = new RichTextBoxContextMenu(); private bool m_bBlockUpdates = false; public EditAutoTypeItemForm() { InitializeComponent(); Program.Translation.ApplyTo(this); } public void InitEx(AutoTypeConfig atConfig, int iAssocIndex, bool bEditSequenceOnly, string strDefaultSeq, ProtectedStringDictionary vStringDict) { Debug.Assert(atConfig != null); if(atConfig == null) throw new ArgumentNullException("atConfig"); m_atConfig = atConfig; m_iAssocIndex = iAssocIndex; m_bEditSequenceOnly = bEditSequenceOnly; m_strDefaultSeq = (strDefaultSeq ?? string.Empty); m_vStringDict = (vStringDict ?? new ProtectedStringDictionary()); } private void OnFormLoad(object sender, EventArgs e) { Debug.Assert(m_atConfig != null); if(m_atConfig == null) throw new InvalidOperationException(); Debug.Assert(m_vStringDict != null); if(m_vStringDict == null) throw new InvalidOperationException(); GlobalWindowManager.AddWindow(this); m_ctxKeySeq.Attach(m_rbKeySeq, this); m_ctxKeyCodes.Attach(m_rtbPlaceholders, this); if(!m_bEditSequenceOnly) { BannerFactory.CreateBannerEx(this, m_bannerImage, Properties.Resources.B48x48_KCMSystem, KPRes.ConfigureAutoTypeItem, KPRes.ConfigureAutoTypeItemDesc); } else // Edit keystrokes only { BannerFactory.CreateBannerEx(this, m_bannerImage, Properties.Resources.B48x48_KCMSystem, KPRes.ConfigureKeystrokeSeq, KPRes.ConfigureKeystrokeSeqDesc); } this.Icon = AppIcons.Default; // FontUtil.AssignDefaultBold(m_lblTargetWindow); // FontUtil.AssignDefaultBold(m_rbSeqDefault); // FontUtil.AssignDefaultBold(m_rbSeqCustom); UIUtil.EnableAutoCompletion(m_cmbWindow, false); // m_clrOriginalForeground = m_lblOpenHint.ForeColor; // m_clrOriginalBackground = m_cmbWindow.BackColor; // m_strOriginalWindowHint = m_lblTargetWindowInfo.Text; InitPlaceholdersBox(); string strInitSeq = m_atConfig.DefaultSequence; if(m_iAssocIndex >= 0) { AutoTypeAssociation asInit = m_atConfig.GetAt(m_iAssocIndex); m_cmbWindow.Text = asInit.WindowName; if(!m_bEditSequenceOnly) strInitSeq = asInit.Sequence; } else if(m_bEditSequenceOnly) m_cmbWindow.Text = "(" + KPRes.Default + ")"; else strInitSeq = string.Empty; bool bSetDefault = false; m_bBlockUpdates = true; if(strInitSeq.Length > 0) m_rbSeqCustom.Checked = true; else { m_rbSeqDefault.Checked = true; bSetDefault = true; } m_bBlockUpdates = false; if(bSetDefault) m_rbKeySeq.Text = m_strDefaultSeq; else m_rbKeySeq.Text = strInitSeq; try { if(NativeLib.IsUnix()) PopulateWindowsListUnix(); else PopulateWindowsListWin(); } catch(Exception) { Debug.Assert(false); } EnableControlsEx(); } private void InitPlaceholdersBox() { const string VkcBreak = @""; string[] vSpecialKeyCodes = new string[] { "TAB", "ENTER", "UP", "DOWN", "LEFT", "RIGHT", "HOME", "END", "PGUP", "PGDN", "INSERT", "DELETE", "SPACE", VkcBreak, "BACKSPACE", "BREAK", "CAPSLOCK", "ESC", "WIN", "LWIN", "RWIN", "APPS", "HELP", "NUMLOCK", "PRTSC", "SCROLLLOCK", VkcBreak, "F1", "F2", "F3", "F4", "F5", "F6", "F7", "F8", "F9", "F10", "F11", "F12", "F13", "F14", "F15", "F16", VkcBreak, "ADD", "SUBTRACT", "MULTIPLY", "DIVIDE", "NUMPAD0", "NUMPAD1", "NUMPAD2", "NUMPAD3", "NUMPAD4", "NUMPAD5", "NUMPAD6", "NUMPAD7", "NUMPAD8", "NUMPAD9" }; string[] vSpecialPlaceholders = new string[] { "GROUP", "GROUP_PATH", "GROUP_NOTES", "GROUP_SEL", "GROUP_SEL_PATH", "GROUP_SEL_NOTES", "PASSWORD_ENC", "URL:RMVSCM", "URL:SCM", "URL:HOST", "URL:PORT", "URL:PATH", "URL:QUERY", "URL:USERINFO", "URL:USERNAME", "URL:PASSWORD", // "BASE", "T-REPLACE-RX:/T/S/R/", "T-CONV:/T/C/", "C:Comment", VkcBreak, "DELAY 1000", "DELAY=200", "VKEY 13", "VKEY-NX 13", "VKEY-EX 13", "PICKCHARS", "PICKCHARS:Password:C=3", "PICKFIELD", "NEWPASSWORD", "NEWPASSWORD:/Profile/", "HMACOTP", "CLEARFIELD", "APPACTIVATE " + KPRes.Title, "BEEP 800 200", "CMD:/C/O/", VkcBreak, "APPDIR", "DB_PATH", "DB_DIR", "DB_NAME", "DB_BASENAME", "DB_EXT", "ENV_DIRSEP", "ENV_PROGRAMFILES_X86", VkcBreak, // "INTERNETEXPLORER", "FIREFOX", "OPERA", "GOOGLECHROME", // "SAFARI", VkcBreak, "DT_SIMPLE", "DT_YEAR", "DT_MONTH", "DT_DAY", "DT_HOUR", "DT_MINUTE", "DT_SECOND", "DT_UTC_SIMPLE", "DT_UTC_YEAR", "DT_UTC_MONTH", "DT_UTC_DAY", "DT_UTC_HOUR", "DT_UTC_MINUTE", "DT_UTC_SECOND" }; RichTextBuilder rb = new RichTextBuilder(); rb.AppendLine(KPRes.StandardFields, FontStyle.Bold, null, null, ":", null); rb.Append("{" + PwDefs.TitleField + "} "); rb.Append("{" + PwDefs.UserNameField + "} "); rb.Append("{" + PwDefs.PasswordField + "} "); rb.Append("{" + PwDefs.UrlField + "} "); rb.Append("{" + PwDefs.NotesField + "}"); bool bCustomInitialized = false, bFirst = true; foreach(KeyValuePair kvp in m_vStringDict) { if(!PwDefs.IsStandardField(kvp.Key)) { if(bCustomInitialized == false) { rb.AppendLine(); rb.AppendLine(); rb.AppendLine(KPRes.CustomFields, FontStyle.Bold, null, null, ":", null); bCustomInitialized = true; } if(!bFirst) rb.Append(" "); rb.Append("{" + PwDefs.AutoTypeStringPrefix + kvp.Key + "}"); bFirst = false; } } rb.AppendLine(); rb.AppendLine(); rb.AppendLine(KPRes.KeyboardKeyModifiers, FontStyle.Bold, null, null, ":", null); rb.Append(KPRes.KeyboardKeyShift + @": +, "); rb.Append(KPRes.KeyboardKeyCtrl + @": ^, "); rb.Append(KPRes.KeyboardKeyAlt + @": %"); rb.AppendLine(); rb.AppendLine(); rb.AppendLine(KPRes.SpecialKeys, FontStyle.Bold, null, null, ":", null); bFirst = true; foreach(string strNav in vSpecialKeyCodes) { if(strNav == VkcBreak) { rb.AppendLine(); rb.AppendLine(); bFirst = true; } else { if(!bFirst) rb.Append(" "); rb.Append("{" + strNav + "}"); bFirst = false; } } rb.AppendLine(); rb.AppendLine(); rb.AppendLine(KPRes.OtherPlaceholders, FontStyle.Bold, null, null, ":", null); bFirst = true; foreach(string strPH in vSpecialPlaceholders) { if(strPH == VkcBreak) { rb.AppendLine(); rb.AppendLine(); bFirst = true; } else { if(!bFirst) rb.Append(" "); rb.Append("{" + strPH + "}"); bFirst = false; } } if(SprEngine.FilterPlaceholderHints.Count > 0) { rb.AppendLine(); rb.AppendLine(); rb.AppendLine(KPRes.PluginProvided, FontStyle.Bold, null, null, ":", null); bFirst = true; foreach(string strP in SprEngine.FilterPlaceholderHints) { if(string.IsNullOrEmpty(strP)) continue; if(!bFirst) rb.Append(" "); rb.Append(strP); bFirst = false; } } rb.Build(m_rtbPlaceholders, true); LinkifyRtf(m_rtbPlaceholders); } private void OnFormShown(object sender, EventArgs e) { // Focusing doesn't work in OnFormLoad if(m_cmbWindow.Enabled) UIUtil.SetFocus(m_cmbWindow, this); else if(m_rbKeySeq.Enabled) UIUtil.SetFocus(m_rbKeySeq, this); else UIUtil.SetFocus(m_btnOK, this); } private void CleanUpEx() { lock(m_objDialogSync) { m_bDialogClosed = true; } m_cmbWindow.OrderedImageList = null; foreach(Image img in m_vWndImages) { if(img != null) img.Dispose(); } m_vWndImages.Clear(); m_ctxKeyCodes.Detach(); m_ctxKeySeq.Detach(); #if DEBUG lock(m_oWndTasksSync) { Debug.Assert(m_dWndTasks.Count == 0); } #endif } private void OnBtnOK(object sender, EventArgs e) { EnableControlsEx(); Debug.Assert(m_btnOK.Enabled); if(!m_btnOK.Enabled) return; string strNewSeq = (m_rbSeqCustom.Checked ? m_rbKeySeq.Text : string.Empty); if(!m_bEditSequenceOnly) { AutoTypeAssociation atAssoc; if(m_iAssocIndex >= 0) atAssoc = m_atConfig.GetAt(m_iAssocIndex); else { atAssoc = new AutoTypeAssociation(); m_atConfig.Add(atAssoc); } atAssoc.WindowName = m_cmbWindow.Text; atAssoc.Sequence = strNewSeq; } else m_atConfig.DefaultSequence = strNewSeq; } private void OnBtnCancel(object sender, EventArgs e) { } private void OnBtnHelp(object sender, EventArgs e) { AppHelp.ShowHelp(AppDefs.HelpTopics.AutoType, null); } private void EnableControlsEx() { if(m_bBlockUpdates) return; m_bBlockUpdates = true; // string strItemName = m_cmbWindow.Text; // bool bEnableOK = true; // // string strError = string.Empty; // if((m_atConfig.Get(strItemName) != null) && !m_bEditSequenceOnly) // { // if((m_strOriginalName == null) || !strItemName.Equals(m_strOriginalName)) // { // bEnableOK = false; // // strError = KPRes.FieldNameExistsAlready; // } // } // // if((strItemName.IndexOf('{') >= 0) || (strItemName.IndexOf('}') >= 0)) // // { // // bEnableOK = false; // // // strError = KPRes.FieldNameInvalid; // // } // if(bEnableOK) // { // // m_lblTargetWindowInfo.Text = m_strOriginalWindowHint; // // m_lblTargetWindowInfo.ForeColor = m_clrOriginalForeground; // m_cmbWindow.BackColor = m_clrOriginalBackground; // m_btnOK.Enabled = true; // } // else // { // // m_lblTargetWindowInfo.Text = strError; // // m_lblTargetWindowInfo.ForeColor = Color.Red; // m_cmbWindow.BackColor = AppDefs.ColorEditError; // m_btnOK.Enabled = false; // } m_lblTargetWindow.Enabled = !m_bEditSequenceOnly; m_cmbWindow.Enabled = !m_bEditSequenceOnly; m_lblOpenHint.Enabled = !m_bEditSequenceOnly; m_lnkWildcardRegexHint.Enabled = !m_bEditSequenceOnly; // Workaround for disabled link render bug (gray too dark) m_lnkWildcardRegexHint.Visible = !m_bEditSequenceOnly; bool bCustom = m_rbSeqCustom.Checked; m_rbKeySeq.Enabled = bCustom; m_lblKeySeqInsertInfo.Enabled = bCustom; m_rtbPlaceholders.Enabled = bCustom; m_bBlockUpdates = false; } private void ColorizeKeySeq() { SprContext ctx = new SprContext(); ctx.EncodeAsAutoTypeSequence = true; PwEntry pe = new PwEntry(true, true); pe.Strings = m_vStringDict; ctx.Entry = pe; SprSyntax.Highlight(m_rbKeySeq, ctx); } /* private void ColorizeKeySeq() { string strText = m_rbKeySeq.Text; int iSelStart = m_rbKeySeq.SelectionStart, iSelLen = m_rbKeySeq.SelectionLength; m_rbKeySeq.SelectAll(); m_rbKeySeq.SelectionBackColor = SystemColors.Window; int iStart = 0; while(true) { int iPos = strText.IndexOf('{', iStart); if(iPos < 0) break; int iEnd = strText.IndexOf('}', iPos + 1); if(iEnd < 0) break; m_rbKeySeq.Select(iPos, iEnd - iPos + 1); m_rbKeySeq.SelectionBackColor = Color.FromArgb(212, 255, 212); iStart = iEnd; } m_rbKeySeq.SelectionStart = iSelStart; m_rbKeySeq.SelectionLength = iSelLen; } */ private void OnTextChangedKeySeq(object sender, EventArgs e) { ColorizeKeySeq(); } private static void LinkifyRtf(RichTextBox rtb) { Debug.Assert(rtb.HideSelection); // Flicker otherwise string str = rtb.Text; int iPos = str.IndexOf('{'); while(iPos >= 0) { int iEnd = str.IndexOf('}', iPos); if(iEnd >= 1) { rtb.Select(iPos, iEnd - iPos + 1); UIUtil.RtfSetSelectionLink(rtb); } iPos = str.IndexOf('{', iPos + 1); } rtb.Select(0, 0); } private void OnPlaceholdersLinkClicked(object sender, LinkClickedEventArgs e) { if(!m_rbSeqCustom.Checked) m_rbSeqCustom.Checked = true; int nSelStart = m_rbKeySeq.SelectionStart; int nSelLength = m_rbKeySeq.SelectionLength; string strText = m_rbKeySeq.Text; string strUrl = e.LinkText; if(nSelLength > 0) strText = strText.Remove(nSelStart, nSelLength); m_rbKeySeq.Text = strText.Insert(nSelStart, strUrl); m_rbKeySeq.Select(nSelStart + strUrl.Length, 0); UIUtil.SetFocus(m_rbKeySeq, this); } private void OnWindowTextUpdate(object sender, EventArgs e) { EnableControlsEx(); } private void OnWindowSelectedIndexChanged(object sender, EventArgs e) { EnableControlsEx(); } private void OnFormClosed(object sender, FormClosedEventArgs e) { GlobalWindowManager.RemoveWindow(this); } private void OnWildcardRegexLinkClicked(object sender, LinkLabelLinkClickedEventArgs e) { AppHelp.ShowHelp(AppDefs.HelpTopics.AutoType, AppDefs.HelpTopics.AutoTypeWindowFilters); } private void OnSeqDefaultCheckedChanged(object sender, EventArgs e) { EnableControlsEx(); } private void OnSeqCustomCheckedChanged(object sender, EventArgs e) { EnableControlsEx(); } private void OnFormClosing(object sender, FormClosingEventArgs e) { CleanUpEx(); } private sealed class PwlwInfo { public EditAutoTypeItemForm Form { get; private set; } public IntPtr WindowHandle { get; private set; } public PwlwInfo(EditAutoTypeItemForm f, IntPtr h) { this.Form = f; this.WindowHandle = h; } } private void PopulateWindowsListWin() { Dictionary dWnds = new Dictionary(); NativeMethods.EnumWindowsProc procEnum = delegate(IntPtr hWnd, IntPtr lParam) { try { if(hWnd != IntPtr.Zero) dWnds[hWnd] = true; } catch(Exception) { Debug.Assert(false); } return true; }; NativeMethods.EnumWindows(procEnum, IntPtr.Zero); GC.KeepAlive(procEnum); // Like in MainWindowFinder.FindMainWindow // On Windows 8 and higher, EnumWindows does not return Metro // app windows, thus we try to discover these windows using // the FindWindowEx function; we do this in addition to EnumWindows, // because calling FindWindowEx in a loop is less reliable (and // by additionally using EnumWindows we at least get all desktop // windows for sure) if(WinUtil.IsAtLeastWindows8) { int nMax = (dWnds.Count * 2) + 2; IntPtr h = NativeMethods.FindWindowEx(IntPtr.Zero, IntPtr.Zero, null, null); for(int i = 0; i < nMax; ++i) { if(h == IntPtr.Zero) break; dWnds[h] = true; h = NativeMethods.FindWindowEx(IntPtr.Zero, h, null, null); } } foreach(KeyValuePair kvp in dWnds) ThreadPool.QueueUserWorkItem(new WaitCallback( EditAutoTypeItemForm.EvalWindowProc), new PwlwInfo(this, kvp.Key)); m_cmbWindow.OrderedImageList = m_vWndImages; } private static void EvalWindowProc(object objState) { #if DEBUG string strTaskID = Guid.NewGuid().ToString(); lock(m_oWndTasksSync) { m_dWndTasks[strTaskID] = @"<<>>"; } #endif try { PwlwInfo pInfo = (objState as PwlwInfo); IntPtr hWnd = pInfo.WindowHandle; if(hWnd == IntPtr.Zero) { Debug.Assert(false); return; } uint uSmtoFlags = (NativeMethods.SMTO_NORMAL | NativeMethods.SMTO_ABORTIFHUNG); IntPtr pLen = IntPtr.Zero; IntPtr pSmto = NativeMethods.SendMessageTimeout(hWnd, NativeMethods.WM_GETTEXTLENGTH, IntPtr.Zero, IntPtr.Zero, uSmtoFlags, 2000, ref pLen); if(pSmto == IntPtr.Zero) return; string strName = NativeMethods.GetWindowText(hWnd, true); if(string.IsNullOrEmpty(strName)) return; #if DEBUG Debug.Assert(strName.Length <= pLen.ToInt64()); lock(m_oWndTasksSync) { m_dWndTasks[strTaskID] = strName; } #endif if((NativeMethods.GetWindowStyle(hWnd) & NativeMethods.WS_VISIBLE) == 0) return; if(NativeMethods.IsTaskBar(hWnd)) return; Image img = UIUtil.GetWindowImage(hWnd, true); if(pInfo.Form.InvokeRequired) pInfo.Form.Invoke(new AddWindowProcDelegate( EditAutoTypeItemForm.AddWindowProc), new object[] { pInfo.Form, hWnd, strName, img }); else AddWindowProc(pInfo.Form, hWnd, strName, img); } catch(Exception) { Debug.Assert(false); } #if DEBUG finally { lock(m_oWndTasksSync) { m_dWndTasks.Remove(strTaskID); } } #endif } private delegate void AddWindowProcDelegate(EditAutoTypeItemForm f, IntPtr h, string strWndName, Image img); private static void AddWindowProc(EditAutoTypeItemForm f, IntPtr h, string strWndName, Image img) { if(f == null) { Debug.Assert(false); return; } if(h == IntPtr.Zero) { Debug.Assert(false); return; } try { if(!AutoType.IsValidAutoTypeWindow(h, false)) return; lock(f.m_objDialogSync) { if(!f.m_bDialogClosed) { f.m_vWndImages.Add(img); f.m_cmbWindow.Items.Add(strWndName); } } } catch(Exception) { Debug.Assert(false); } } private void PopulateWindowsListUnix() { string strWindows = NativeMethods.RunXDoTool( @"search --onlyvisible --name '.+' getwindowname %@"); if(string.IsNullOrEmpty(strWindows)) return; strWindows = StrUtil.NormalizeNewLines(strWindows, false); string[] vWindows = strWindows.Split(new char[]{ '\n' }); List vListed = new List(); for(int i = 0; i < vWindows.Length; ++i) { string str = vWindows[i].Trim(); bool bValid = true; foreach(Form f in Application.OpenForms) { if(IsOwnWindow(f, str)) { bValid = false; break; } } if(!bValid) continue; if((str.Length > 0) && (vListed.IndexOf(str) < 0)) { m_cmbWindow.Items.Add(str); vListed.Add(str); } } } private static bool IsOwnWindow(Control cRoot, string strText) { if(cRoot == null) { Debug.Assert(false); return false; } if(cRoot.Text.Trim() == strText) return true; foreach(Control cSub in cRoot.Controls) { if(cSub == cRoot) { Debug.Assert(false); continue; } if(IsOwnWindow(cSub, strText)) return true; } return false; } } } KeePass/Forms/PwEntryForm.cs0000664000000000000000000020260213222430410014753 0ustar rootroot/* KeePass Password Safe - The Open-Source Password Manager Copyright (C) 2003-2018 Dominik Reichl This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ using System; using System.Collections.Generic; using System.ComponentModel; using System.Diagnostics; using System.Drawing; using System.Globalization; using System.IO; using System.Text; using System.Threading; using System.Windows.Forms; using KeePass.App; using KeePass.App.Configuration; using KeePass.Native; using KeePass.Resources; using KeePass.UI; using KeePass.Util; using KeePassLib; using KeePassLib.Collections; using KeePassLib.Cryptography; using KeePassLib.Cryptography.PasswordGenerator; using KeePassLib.Delegates; using KeePassLib.Security; using KeePassLib.Utility; using NativeLib = KeePassLib.Native.NativeLib; namespace KeePass.Forms { public enum PwEditMode { Invalid = 0, AddNewEntry, EditExistingEntry, ViewReadOnlyEntry } public partial class PwEntryForm : Form { private PwEditMode m_pwEditMode = PwEditMode.Invalid; private PwDatabase m_pwDatabase = null; private bool m_bShowAdvancedByDefault = false; private bool m_bSelectFullTitle = false; private PwEntry m_pwEntry = null; private PwEntry m_pwInitialEntry = null; private ProtectedStringDictionary m_vStrings = null; private ProtectedBinaryDictionary m_vBinaries = null; private AutoTypeConfig m_atConfig = null; private PwObjectList m_vHistory = null; private Color m_clrForeground = Color.Empty; private Color m_clrBackground = Color.Empty; private StringDictionaryEx m_sdCustomData = null; private PwIcon m_pwEntryIcon = PwIcon.Key; private PwUuid m_pwCustomIconID = PwUuid.Zero; private ImageList m_ilIcons = null; private bool m_bLockEnabledState = false; private bool m_bTouchedOnce = false; private bool m_bInitializing = true; private bool m_bForceClosing = false; private PwInputControlGroup m_icgPassword = new PwInputControlGroup(); private ExpiryControlGroup m_cgExpiry = new ExpiryControlGroup(); private RichTextBoxContextMenu m_ctxNotes = new RichTextBoxContextMenu(); private Image m_imgTools = null; private Image m_imgGenPw = null; private Image m_imgStdExpire = null; private Image m_imgColorFg = null; private Image m_imgColorBg = null; private List m_lOverrideUrlIcons = new List(); private CustomContextMenuStripEx m_ctxBinOpen = null; private DynamicMenu m_dynBinOpen = null; private readonly string DeriveFromPrevious = "(" + KPRes.GenPwBasedOnPrevious + ")"; private readonly string AutoGenProfile = "(" + KPRes.AutoGeneratedPasswordSettings + ")"; private DynamicMenu m_dynGenProfiles; private const PwIcon m_pwObjectProtected = PwIcon.PaperLocked; private const PwIcon m_pwObjectPlainText = PwIcon.PaperNew; public event EventHandler EntrySaving; public event EventHandler EntrySaved; private const PwCompareOptions m_cmpOpt = (PwCompareOptions.NullEmptyEquivStd | PwCompareOptions.IgnoreTimes); private enum ListSelRestore { None = 0, ByIndex, ByRef } public bool HasModifiedEntry { get { if((m_pwEntry == null) || (m_pwInitialEntry == null)) { Debug.Assert(false); return true; } return !m_pwEntry.EqualsEntry(m_pwInitialEntry, m_cmpOpt, MemProtCmpMode.CustomOnly); } } public PwEntry EntryRef { get { return m_pwEntry; } } public ProtectedStringDictionary EntryStrings { get { return m_vStrings; } } public ProtectedBinaryDictionary EntryBinaries { get { return m_vBinaries; } } public ContextMenuStrip ToolsContextMenu { get { return m_ctxTools; } } public ContextMenuStrip DefaultTimesContextMenu { get { return m_ctxDefaultTimes; } } public ContextMenuStrip ListOperationsContextMenu { get { return m_ctxListOperations; } } public ContextMenuStrip PasswordGeneratorContextMenu { get { return m_ctxPwGen; } } public ContextMenuStrip StandardStringMovementContextMenu { get { return m_ctxStrMoveToStandard; } } public ContextMenuStrip AttachmentsContextMenu { get { return m_ctxBinAttach; } } private bool m_bInitSwitchToHistory = false; internal bool InitSwitchToHistoryTab { // get { return m_bInitSwitchToHistory; } // Internal, uncalled set { m_bInitSwitchToHistory = value; } } public PwEntryForm() { InitializeComponent(); Program.Translation.ApplyTo(this); Program.Translation.ApplyTo("KeePass.Forms.PwEntryForm.m_ctxTools", m_ctxTools.Items); Program.Translation.ApplyTo("KeePass.Forms.PwEntryForm.m_ctxDefaultTimes", m_ctxDefaultTimes.Items); Program.Translation.ApplyTo("KeePass.Forms.PwEntryForm.m_ctxListOperations", m_ctxListOperations.Items); Program.Translation.ApplyTo("KeePass.Forms.PwEntryForm.m_ctxPwGen", m_ctxPwGen.Items); Program.Translation.ApplyTo("KeePass.Forms.PwEntryForm.m_ctxStrMoveToStandard", m_ctxStrMoveToStandard.Items); Program.Translation.ApplyTo("KeePass.Forms.PwEntryForm.m_ctxBinAttach", m_ctxBinAttach.Items); } public void InitEx(PwEntry pwEntry, PwEditMode pwMode, PwDatabase pwDatabase, ImageList ilIcons, bool bShowAdvancedByDefault, bool bSelectFullTitle) { Debug.Assert(pwEntry != null); if(pwEntry == null) throw new ArgumentNullException("pwEntry"); Debug.Assert(pwMode != PwEditMode.Invalid); if(pwMode == PwEditMode.Invalid) throw new ArgumentException(); Debug.Assert(ilIcons != null); if(ilIcons == null) throw new ArgumentNullException("ilIcons"); m_pwEntry = pwEntry; m_pwEditMode = pwMode; m_pwDatabase = pwDatabase; m_ilIcons = ilIcons; m_bShowAdvancedByDefault = bShowAdvancedByDefault; m_bSelectFullTitle = bSelectFullTitle; m_vStrings = m_pwEntry.Strings.CloneDeep(); m_vBinaries = m_pwEntry.Binaries.CloneDeep(); m_atConfig = m_pwEntry.AutoType.CloneDeep(); m_vHistory = m_pwEntry.History.CloneDeep(); } private void InitEntryTab() { m_pwEntryIcon = m_pwEntry.IconId; m_pwCustomIconID = m_pwEntry.CustomIconUuid; if(!m_pwCustomIconID.Equals(PwUuid.Zero)) { // int nInx = (int)PwIcon.Count + m_pwDatabase.GetCustomIconIndex(m_pwCustomIconID); // if((nInx > -1) && (nInx < m_ilIcons.Images.Count)) // m_btnIcon.Image = m_ilIcons.Images[nInx]; // else m_btnIcon.Image = m_ilIcons.Images[(int)m_pwEntryIcon]; Image imgCustom = DpiUtil.GetIcon(m_pwDatabase, m_pwCustomIconID); // m_btnIcon.Image = (imgCustom ?? m_ilIcons.Images[(int)m_pwEntryIcon]); UIUtil.SetButtonImage(m_btnIcon, (imgCustom ?? m_ilIcons.Images[ (int)m_pwEntryIcon]), true); } else { // m_btnIcon.Image = m_ilIcons.Images[(int)m_pwEntryIcon]; UIUtil.SetButtonImage(m_btnIcon, m_ilIcons.Images[ (int)m_pwEntryIcon], true); } bool bHideInitial = m_cbHidePassword.Checked; m_icgPassword.Attach(m_tbPassword, m_cbHidePassword, m_lblPasswordRepeat, m_tbRepeatPassword, m_lblQuality, m_pbQuality, m_lblQualityInfo, m_ttRect, this, bHideInitial, false); m_icgPassword.ContextDatabase = m_pwDatabase; m_icgPassword.ContextEntry = m_pwEntry; m_icgPassword.IsSprVariant = true; if(m_pwEntry.Expires) { m_dtExpireDateTime.Value = TimeUtil.ToLocal(m_pwEntry.ExpiryTime, true); m_cbExpires.Checked = true; } else // Does not expire { m_dtExpireDateTime.Value = DateTime.Now.Date; m_cbExpires.Checked = false; } m_cgExpiry.Attach(m_cbExpires, m_dtExpireDateTime); if(m_pwEditMode == PwEditMode.ViewReadOnlyEntry) { m_tbTitle.ReadOnly = m_tbUserName.ReadOnly = m_tbPassword.ReadOnly = m_tbRepeatPassword.ReadOnly = m_tbUrl.ReadOnly = m_rtNotes.ReadOnly = true; m_btnIcon.Enabled = m_btnGenPw.Enabled = m_cbExpires.Enabled = m_dtExpireDateTime.Enabled = m_btnStandardExpires.Enabled = false; m_rtNotes.SelectAll(); m_rtNotes.BackColor = m_rtNotes.SelectionBackColor = AppDefs.ColorControlDisabled; m_rtNotes.DeselectAll(); m_ctxToolsUrlSelApp.Enabled = m_ctxToolsUrlSelDoc.Enabled = false; m_ctxToolsFieldRefsInTitle.Enabled = m_ctxToolsFieldRefsInUserName.Enabled = m_ctxToolsFieldRefsInPassword.Enabled = m_ctxToolsFieldRefsInUrl.Enabled = m_ctxToolsFieldRefsInNotes.Enabled = false; m_ctxToolsFieldRefs.Enabled = false; m_btnOK.Enabled = false; } // Show URL in blue, if it's black in the current visual theme if(m_tbUrl.ForeColor.ToArgb() == Color.Black.ToArgb()) m_tbUrl.ForeColor = Color.Blue; } private void InitAdvancedTab() { m_lvStrings.SmallImageList = m_ilIcons; m_lvBinaries.SmallImageList = m_ilIcons; int nWidth = m_lvStrings.ClientSize.Width / 2; m_lvStrings.Columns.Add(KPRes.FieldName, nWidth); m_lvStrings.Columns.Add(KPRes.FieldValue, nWidth); nWidth = m_lvBinaries.ClientSize.Width / 2; m_lvBinaries.Columns.Add(KPRes.Attachments, nWidth); m_lvBinaries.Columns.Add(KPRes.Size, nWidth, HorizontalAlignment.Right); if(m_pwEditMode == PwEditMode.ViewReadOnlyEntry) { m_btnStrAdd.Enabled = m_btnStrEdit.Enabled = m_btnStrDelete.Enabled = m_btnStrMove.Enabled = m_btnBinAdd.Enabled = m_btnBinDelete.Enabled = false; // Always available: // m_btnBinOpen.Enabled = m_btnBinSave.Enabled = false; m_lvBinaries.LabelEdit = false; } } // Public for plugins public void UpdateEntryStrings(bool bGuiToInternal, bool bSetRepeatPw) { UpdateEntryStrings(bGuiToInternal, bSetRepeatPw, false); } public void UpdateEntryStrings(bool bGuiToInternal, bool bSetRepeatPw, bool bUpdateState) { if(bGuiToInternal) { m_vStrings.Set(PwDefs.TitleField, new ProtectedString(m_pwDatabase.MemoryProtection.ProtectTitle, m_tbTitle.Text)); m_vStrings.Set(PwDefs.UserNameField, new ProtectedString(m_pwDatabase.MemoryProtection.ProtectUserName, m_tbUserName.Text)); byte[] pb = m_icgPassword.GetPasswordUtf8(); m_vStrings.Set(PwDefs.PasswordField, new ProtectedString(m_pwDatabase.MemoryProtection.ProtectPassword, pb)); MemUtil.ZeroByteArray(pb); m_vStrings.Set(PwDefs.UrlField, new ProtectedString(m_pwDatabase.MemoryProtection.ProtectUrl, m_tbUrl.Text)); m_vStrings.Set(PwDefs.NotesField, new ProtectedString(m_pwDatabase.MemoryProtection.ProtectNotes, m_rtNotes.Text)); } else // Internal to GUI { m_tbTitle.Text = m_vStrings.ReadSafe(PwDefs.TitleField); m_tbUserName.Text = m_vStrings.ReadSafe(PwDefs.UserNameField); byte[] pb = m_vStrings.GetSafe(PwDefs.PasswordField).ReadUtf8(); m_icgPassword.SetPassword(pb, bSetRepeatPw); MemUtil.ZeroByteArray(pb); m_tbUrl.Text = m_vStrings.ReadSafe(PwDefs.UrlField); m_rtNotes.Text = m_vStrings.ReadSafe(PwDefs.NotesField); UIScrollInfo s = UIUtil.GetScrollInfo(m_lvStrings, true); m_lvStrings.BeginUpdate(); m_lvStrings.Items.Clear(); foreach(KeyValuePair kvpStr in m_vStrings) { if(!PwDefs.IsStandardField(kvpStr.Key)) { PwIcon pwIcon = (kvpStr.Value.IsProtected ? m_pwObjectProtected : m_pwObjectPlainText); ListViewItem lvi = m_lvStrings.Items.Add(kvpStr.Key, (int)pwIcon); if(kvpStr.Value.IsProtected) lvi.SubItems.Add(PwDefs.HiddenPassword); else { string strValue = StrUtil.MultiToSingleLine( kvpStr.Value.ReadString()); lvi.SubItems.Add(strValue); } } } UIUtil.Scroll(m_lvStrings, s, false); m_lvStrings.EndUpdate(); } if(bUpdateState) EnableControlsEx(); } // Public for plugins public void UpdateEntryBinaries(bool bGuiToInternal) { UpdateEntryBinaries(bGuiToInternal, false, null); } public void UpdateEntryBinaries(bool bGuiToInternal, bool bUpdateState) { UpdateEntryBinaries(bGuiToInternal, bUpdateState, null); } public void UpdateEntryBinaries(bool bGuiToInternal, bool bUpdateState, string strFocusItem) { if(bGuiToInternal) { } else // Internal to GUI { UIScrollInfo s = UIUtil.GetScrollInfo(m_lvBinaries, true); m_lvBinaries.BeginUpdate(); m_lvBinaries.Items.Clear(); foreach(KeyValuePair kvpBin in m_vBinaries) { PwIcon pwIcon = (kvpBin.Value.IsProtected ? m_pwObjectProtected : m_pwObjectPlainText); ListViewItem lvi = m_lvBinaries.Items.Add(kvpBin.Key, (int)pwIcon); lvi.SubItems.Add(StrUtil.FormatDataSizeKB(kvpBin.Value.Length)); } UIUtil.Scroll(m_lvBinaries, s, false); if(strFocusItem != null) { ListViewItem lvi = m_lvBinaries.FindItemWithText(strFocusItem, false, 0, false); if(lvi != null) { m_lvBinaries.EnsureVisible(lvi.Index); UIUtil.SetFocusedItem(m_lvBinaries, lvi, true); } else { Debug.Assert(false); } } m_lvBinaries.EndUpdate(); } if(bUpdateState) EnableControlsEx(); } private void InitPropertiesTab() { m_clrForeground = m_pwEntry.ForegroundColor; m_clrBackground = m_pwEntry.BackgroundColor; if(m_clrForeground != Color.Empty) UIUtil.OverwriteButtonImage(m_btnPickFgColor, ref m_imgColorFg, UIUtil.CreateColorBitmap24(m_btnPickFgColor, m_clrForeground)); if(m_clrBackground != Color.Empty) UIUtil.OverwriteButtonImage(m_btnPickBgColor, ref m_imgColorBg, UIUtil.CreateColorBitmap24(m_btnPickBgColor, m_clrBackground)); m_cbCustomForegroundColor.Checked = (m_clrForeground != Color.Empty); m_cbCustomBackgroundColor.Checked = (m_clrBackground != Color.Empty); m_cmbOverrideUrl.Text = m_pwEntry.OverrideUrl; m_tbTags.Text = StrUtil.TagsToString(m_pwEntry.Tags, true); m_sdCustomData = m_pwEntry.CustomData.CloneDeep(); UIUtil.StrDictListInit(m_lvCustomData); UIUtil.StrDictListUpdate(m_lvCustomData, m_sdCustomData); m_tbUuid.Text = m_pwEntry.Uuid.ToHexString(); if(m_pwEditMode == PwEditMode.ViewReadOnlyEntry) { m_cbCustomForegroundColor.Enabled = false; m_cbCustomBackgroundColor.Enabled = false; m_btnPickFgColor.Enabled = false; m_btnPickBgColor.Enabled = false; m_cmbOverrideUrl.Enabled = false; m_tbTags.ReadOnly = true; m_btnCDDel.Enabled = false; } } private void InitAutoTypeTab() { m_lvAutoType.SmallImageList = m_ilIcons; m_cbAutoTypeEnabled.Checked = m_atConfig.Enabled; m_cbAutoTypeObfuscation.Checked = (m_atConfig.ObfuscationOptions != AutoTypeObfuscationOptions.None); string strDefaultSeq = m_atConfig.DefaultSequence; if(strDefaultSeq.Length > 0) m_rbAutoTypeOverride.Checked = true; else m_rbAutoTypeSeqInherit.Checked = true; if(strDefaultSeq.Length == 0) { PwGroup pg = m_pwEntry.ParentGroup; if(pg != null) { strDefaultSeq = pg.GetAutoTypeSequenceInherited(); if(strDefaultSeq.Length == 0) { if(PwDefs.IsTanEntry(m_pwEntry)) strDefaultSeq = PwDefs.DefaultAutoTypeSequenceTan; else strDefaultSeq = PwDefs.DefaultAutoTypeSequence; } } } m_tbDefaultAutoTypeSeq.Text = strDefaultSeq; int nWidth = m_lvAutoType.ClientRectangle.Width / 2; m_lvAutoType.Columns.Add(KPRes.TargetWindow, nWidth); m_lvAutoType.Columns.Add(KPRes.Sequence, nWidth); UpdateAutoTypeList(ListSelRestore.None, null, false); if(m_pwEditMode == PwEditMode.ViewReadOnlyEntry) { m_cbAutoTypeEnabled.Enabled = m_cbAutoTypeObfuscation.Enabled = m_rbAutoTypeSeqInherit.Enabled = m_rbAutoTypeOverride.Enabled = m_btnAutoTypeAdd.Enabled = m_btnAutoTypeDelete.Enabled = m_btnAutoTypeEdit.Enabled = false; m_btnAutoTypeUp.Enabled = m_btnAutoTypeDown.Enabled = false; m_tbDefaultAutoTypeSeq.Enabled = m_btnAutoTypeEditDefault.Enabled = false; } } private void UpdateAutoTypeList(ListSelRestore r, AutoTypeAssociation aToSel, bool bUpdateState) { UIScrollInfo uiScroll = UIUtil.GetScrollInfo(m_lvAutoType, true); int s = m_lvAutoType.SelectedIndices.Count; int[] vSel = null; List lSel = new List(); if(aToSel != null) lSel.Add(aToSel); if((r == ListSelRestore.ByIndex) && (s > 0)) { vSel = new int[s]; m_lvAutoType.SelectedIndices.CopyTo(vSel, 0); } else if(r == ListSelRestore.ByRef) { foreach(ListViewItem lviSel in m_lvAutoType.SelectedItems) { AutoTypeAssociation a = (lviSel.Tag as AutoTypeAssociation); if(a == null) { Debug.Assert(false); } else lSel.Add(a); } } m_lvAutoType.BeginUpdate(); m_lvAutoType.Items.Clear(); string strDefault = "(" + KPRes.Default + ")"; foreach(AutoTypeAssociation a in m_atConfig.Associations) { ListViewItem lvi = m_lvAutoType.Items.Add(a.WindowName, (int)PwIcon.List); lvi.SubItems.Add((a.Sequence.Length > 0) ? a.Sequence : strDefault); lvi.Tag = a; foreach(AutoTypeAssociation aSel in lSel) { if(object.ReferenceEquals(a, aSel)) lvi.Selected = true; } } if(vSel != null) { foreach(int iSel in vSel) m_lvAutoType.Items[iSel].Selected = true; } UIUtil.Scroll(m_lvAutoType, uiScroll, true); m_lvAutoType.EndUpdate(); if(bUpdateState) EnableControlsEx(); } private void InitHistoryTab() { m_lvHistory.SmallImageList = m_ilIcons; m_lvHistory.Columns.Add(KPRes.Version); m_lvHistory.Columns.Add(KPRes.Title); m_lvHistory.Columns.Add(KPRes.UserName); m_lvHistory.Columns.Add(KPRes.Size, 72, HorizontalAlignment.Right); UpdateHistoryList(false); if(m_pwEditMode == PwEditMode.ViewReadOnlyEntry) { m_btnHistoryDelete.Enabled = m_btnHistoryRestore.Enabled = m_btnHistoryView.Enabled = false; } } private void UpdateHistoryList(bool bUpdateState) { UIScrollInfo s = UIUtil.GetScrollInfo(m_lvHistory, true); m_lvHistory.BeginUpdate(); m_lvHistory.Items.Clear(); foreach(PwEntry pe in m_vHistory) { ListViewItem lvi = m_lvHistory.Items.Add(TimeUtil.ToDisplayString( pe.LastModificationTime), (int)pe.IconId); lvi.SubItems.Add(pe.Strings.ReadSafe(PwDefs.TitleField)); lvi.SubItems.Add(pe.Strings.ReadSafe(PwDefs.UserNameField)); lvi.SubItems.Add(StrUtil.FormatDataSizeKB(pe.GetSize())); } UIUtil.Scroll(m_lvHistory, s, true); m_lvHistory.EndUpdate(); if(bUpdateState) EnableControlsEx(); } private void ResizeColumnHeaders() { UIUtil.ResizeColumns(m_lvStrings, true); UIUtil.ResizeColumns(m_lvBinaries, new int[] { 4, 1 }, true); UIUtil.ResizeColumns(m_lvAutoType, true); UIUtil.ResizeColumns(m_lvHistory, new int[] { 21, 20, 18, 11 }, true); } private void OnFormLoad(object sender, EventArgs e) { Debug.Assert(m_pwEntry != null); if(m_pwEntry == null) throw new InvalidOperationException(); Debug.Assert(m_pwEditMode != PwEditMode.Invalid); if(m_pwEditMode == PwEditMode.Invalid) throw new ArgumentException(); Debug.Assert(m_pwDatabase != null); if(m_pwDatabase == null) throw new InvalidOperationException(); Debug.Assert(m_ilIcons != null); if(m_ilIcons == null) throw new InvalidOperationException(); m_bInitializing = true; GlobalWindowManager.AddWindow(this); GlobalWindowManager.CustomizeControl(m_ctxTools); GlobalWindowManager.CustomizeControl(m_ctxPwGen); GlobalWindowManager.CustomizeControl(m_ctxStrMoveToStandard); m_pwInitialEntry = m_pwEntry.CloneDeep(); StrUtil.NormalizeNewLines(m_pwInitialEntry.Strings, true); UIUtil.ConfigureToolTip(m_ttRect); m_ttRect.SetToolTip(m_btnIcon, KPRes.SelectIcon); // m_ttRect.SetToolTip(m_cbHidePassword, KPRes.TogglePasswordAsterisks); m_ttRect.SetToolTip(m_btnGenPw, KPRes.GeneratePassword); m_ttRect.SetToolTip(m_btnStandardExpires, KPRes.StandardExpireSelect); UIUtil.ConfigureToolTip(m_ttBalloon); m_ttBalloon.SetToolTip(m_tbRepeatPassword, KPRes.PasswordRepeatHint); m_dynGenProfiles = new DynamicMenu(m_ctxPwGen.Items); m_dynGenProfiles.MenuClick += this.OnProfilesDynamicMenuClick; m_ctxNotes.Attach(m_rtNotes, this); m_ctxBinOpen = new CustomContextMenuStripEx(); m_ctxBinOpen.Opening += this.OnCtxBinOpenOpening; m_dynBinOpen = new DynamicMenu(m_ctxBinOpen.Items); m_dynBinOpen.MenuClick += this.OnDynBinOpen; m_btnBinOpen.SplitDropDownMenu = m_ctxBinOpen; string strTitle = string.Empty, strDesc = string.Empty; if(m_pwEditMode == PwEditMode.AddNewEntry) { strTitle = KPRes.AddEntry; strDesc = KPRes.AddEntryDesc; } else if(m_pwEditMode == PwEditMode.EditExistingEntry) { strTitle = KPRes.EditEntry; strDesc = KPRes.EditEntryDesc; } else if(m_pwEditMode == PwEditMode.ViewReadOnlyEntry) { strTitle = KPRes.ViewEntry; strDesc = KPRes.ViewEntryDesc; } else { Debug.Assert(false); } BannerFactory.CreateBannerEx(this, m_bannerImage, KeePass.Properties.Resources.B48x48_KGPG_Sign, strTitle, strDesc); this.Icon = AppIcons.Default; this.Text = strTitle; m_imgGenPw = UIUtil.CreateDropDownImage(Properties.Resources.B16x16_Key_New); m_imgStdExpire = UIUtil.CreateDropDownImage(Properties.Resources.B16x16_History); Image imgOrg = Properties.Resources.B16x16_Package_Settings; Image imgSc = UIUtil.SetButtonImage(m_btnTools, imgOrg, true); if(!object.ReferenceEquals(imgOrg, imgSc)) m_imgTools = imgSc; // Only dispose scaled image imgSc = UIUtil.SetButtonImage(m_btnGenPw, m_imgGenPw, true); UIUtil.OverwriteIfNotEqual(ref m_imgGenPw, imgSc); imgSc = UIUtil.SetButtonImage(m_btnStandardExpires, m_imgStdExpire, true); UIUtil.OverwriteIfNotEqual(ref m_imgStdExpire, imgSc); if(m_pwEditMode == PwEditMode.ViewReadOnlyEntry) m_bLockEnabledState = true; // UIUtil.SetExplorerTheme(m_lvStrings, true); // UIUtil.SetExplorerTheme(m_lvBinaries, true); // UIUtil.SetExplorerTheme(m_lvCustomData, true); // UIUtil.SetExplorerTheme(m_lvAutoType, true); // UIUtil.SetExplorerTheme(m_lvHistory, true); UIUtil.PrepareStandardMultilineControl(m_rtNotes, true, true); bool bForceHide = !AppPolicy.Current.UnhidePasswords; if(Program.Config.UI.Hiding.SeparateHidingSettings) m_cbHidePassword.Checked = (Program.Config.UI.Hiding.HideInEntryWindow || bForceHide); else { AceColumn colPw = Program.Config.MainWindow.FindColumn(AceColumnType.Password); m_cbHidePassword.Checked = (((colPw != null) ? colPw.HideWithAsterisks : true) || bForceHide); } InitEntryTab(); InitAdvancedTab(); InitPropertiesTab(); InitAutoTypeTab(); InitHistoryTab(); UpdateEntryStrings(false, true, false); UpdateEntryBinaries(false, false); if(PwDefs.IsTanEntry(m_pwEntry)) m_btnTools.Enabled = false; CustomizeForScreenReader(); m_bInitializing = false; if(m_bInitSwitchToHistory) // Before 'Advanced' tab switch m_tabMain.SelectedTab = m_tabHistory; else if(m_bShowAdvancedByDefault) m_tabMain.SelectedTab = m_tabAdvanced; ResizeColumnHeaders(); EnableControlsEx(); ThreadPool.QueueUserWorkItem(delegate(object state) { try { InitOverridesBox(); } catch(Exception) { Debug.Assert(false); } }); if(MonoWorkarounds.IsRequired(2140)) Application.DoEvents(); if(m_pwEditMode == PwEditMode.ViewReadOnlyEntry) UIUtil.SetFocus(m_btnCancel, this); else { if(m_bSelectFullTitle) m_tbTitle.Select(0, m_tbTitle.TextLength); else m_tbTitle.Select(0, 0); UIUtil.SetFocus(m_tbTitle, this); } } private void CustomizeForScreenReader() { if(!Program.Config.UI.OptimizeForScreenReader) return; m_btnIcon.Text = KPRes.PickIcon; m_cbHidePassword.Text = KPRes.HideUsingAsterisks; m_btnGenPw.Text = m_ttRect.GetToolTip(m_btnGenPw); m_btnStandardExpires.Text = m_ttRect.GetToolTip(m_btnStandardExpires); m_btnPickFgColor.Text = KPRes.SelectColor; m_btnPickBgColor.Text = KPRes.SelectColor; m_btnAutoTypeUp.Text = "\u2191"; // Upwards arrow m_btnAutoTypeDown.Text = "\u2193"; // Downwards arrow } private void EnableControlsEx() { if(m_bInitializing) return; int nStringsSel = m_lvStrings.SelectedItems.Count; int nBinSel = m_lvBinaries.SelectedItems.Count; m_btnBinOpen.Enabled = (nBinSel == 1); m_btnBinSave.Enabled = (nBinSel >= 1); if(m_bLockEnabledState) return; m_btnStrEdit.Enabled = (nStringsSel == 1); m_btnStrDelete.Enabled = (nStringsSel >= 1); m_btnBinDelete.Enabled = (nBinSel >= 1); m_btnPickFgColor.Enabled = m_cbCustomForegroundColor.Checked; m_btnPickBgColor.Enabled = m_cbCustomBackgroundColor.Checked; m_btnCDDel.Enabled = (m_lvCustomData.SelectedItems.Count > 0); bool bATEnabled = m_cbAutoTypeEnabled.Checked; m_lvAutoType.Enabled = m_btnAutoTypeAdd.Enabled = m_rbAutoTypeSeqInherit.Enabled = m_rbAutoTypeOverride.Enabled = m_cbAutoTypeObfuscation.Enabled = bATEnabled; if(!m_rbAutoTypeOverride.Checked) m_tbDefaultAutoTypeSeq.Enabled = m_btnAutoTypeEditDefault.Enabled = false; else m_tbDefaultAutoTypeSeq.Enabled = m_btnAutoTypeEditDefault.Enabled = bATEnabled; int nAutoTypeSel = m_lvAutoType.SelectedItems.Count; if(m_pwEditMode != PwEditMode.ViewReadOnlyEntry) { m_btnAutoTypeEdit.Enabled = (bATEnabled && (nAutoTypeSel == 1)); m_btnAutoTypeDelete.Enabled = (bATEnabled && (nAutoTypeSel >= 1)); m_btnAutoTypeUp.Enabled = (bATEnabled && (nAutoTypeSel >= 1)); m_btnAutoTypeDown.Enabled = (bATEnabled && (nAutoTypeSel >= 1)); } int nAccumSel = nStringsSel + nBinSel + nAutoTypeSel; m_menuListCtxCopyFieldValue.Enabled = (nAccumSel != 0); int nHistorySel = m_lvHistory.SelectedIndices.Count; m_btnHistoryRestore.Enabled = (nHistorySel == 1); m_btnHistoryDelete.Enabled = m_btnHistoryView.Enabled = (nHistorySel >= 1); m_menuListCtxMoveStandardTitle.Enabled = m_menuListCtxMoveStandardUser.Enabled = m_menuListCtxMoveStandardPassword.Enabled = m_menuListCtxMoveStandardURL.Enabled = m_menuListCtxMoveStandardNotes.Enabled = m_btnStrMove.Enabled = (nStringsSel == 1); } private bool SaveEntry(PwEntry peTarget, bool bValidate) { if(m_pwEditMode == PwEditMode.ViewReadOnlyEntry) return true; if(bValidate && !m_icgPassword.ValidateData(true)) return false; if(this.EntrySaving != null) { CancellableOperationEventArgs eaCancel = new CancellableOperationEventArgs(); this.EntrySaving(this, eaCancel); if(eaCancel.Cancel) return false; } peTarget.History = m_vHistory; // Must be called before CreateBackup() bool bCreateBackup = (m_pwEditMode != PwEditMode.AddNewEntry); if(bCreateBackup) peTarget.CreateBackup(null); peTarget.IconId = m_pwEntryIcon; peTarget.CustomIconUuid = m_pwCustomIconID; if(m_cbCustomForegroundColor.Checked) peTarget.ForegroundColor = m_clrForeground; else peTarget.ForegroundColor = Color.Empty; if(m_cbCustomBackgroundColor.Checked) peTarget.BackgroundColor = m_clrBackground; else peTarget.BackgroundColor = Color.Empty; peTarget.OverrideUrl = m_cmbOverrideUrl.Text; List vNewTags = StrUtil.StringToTags(m_tbTags.Text); peTarget.Tags.Clear(); foreach(string strTag in vNewTags) peTarget.AddTag(strTag); peTarget.Expires = m_cgExpiry.Checked; if(peTarget.Expires) peTarget.ExpiryTime = m_cgExpiry.Value; UpdateEntryStrings(true, false, false); peTarget.Strings = m_vStrings; peTarget.Binaries = m_vBinaries; peTarget.CustomData = m_sdCustomData; m_atConfig.Enabled = m_cbAutoTypeEnabled.Checked; m_atConfig.ObfuscationOptions = (m_cbAutoTypeObfuscation.Checked ? AutoTypeObfuscationOptions.UseClipboard : AutoTypeObfuscationOptions.None); SaveDefaultSeq(); peTarget.AutoType = m_atConfig; peTarget.Touch(true, false); // Touch *after* backup if(object.ReferenceEquals(peTarget, m_pwEntry)) m_bTouchedOnce = true; StrUtil.NormalizeNewLines(peTarget.Strings, true); bool bUndoBackup = false; PwCompareOptions cmpOpt = m_cmpOpt; if(bCreateBackup) cmpOpt |= PwCompareOptions.IgnoreLastBackup; if(peTarget.EqualsEntry(m_pwInitialEntry, cmpOpt, MemProtCmpMode.CustomOnly)) { // No modifications at all => restore last mod time and undo backup peTarget.LastModificationTime = m_pwInitialEntry.LastModificationTime; bUndoBackup = bCreateBackup; } else if(bCreateBackup) { // If only history items have been modified (deleted) => undo // backup, but without restoring the last mod time PwCompareOptions cmpOptNH = (m_cmpOpt | PwCompareOptions.IgnoreHistory); if(peTarget.EqualsEntry(m_pwInitialEntry, cmpOptNH, MemProtCmpMode.CustomOnly)) bUndoBackup = true; } if(bUndoBackup) peTarget.History.RemoveAt(peTarget.History.UCount - 1); peTarget.MaintainBackups(m_pwDatabase); if(this.EntrySaved != null) this.EntrySaved(this, EventArgs.Empty); return true; } private void SaveDefaultSeq() { if(m_rbAutoTypeSeqInherit.Checked) m_atConfig.DefaultSequence = string.Empty; else if(m_rbAutoTypeOverride.Checked) m_atConfig.DefaultSequence = m_tbDefaultAutoTypeSeq.Text; else { Debug.Assert(false); } } private void OnBtnOK(object sender, EventArgs e) { if(SaveEntry(m_pwEntry, true)) m_bForceClosing = true; else this.DialogResult = DialogResult.None; } private void OnBtnCancel(object sender, EventArgs e) { m_bForceClosing = true; try { ushort usEsc = NativeMethods.GetAsyncKeyState((int)Keys.Escape); if((usEsc & 0x8000) != 0) m_bForceClosing = false; } catch(Exception) { Debug.Assert(NativeLib.IsUnix()); } } private void CleanUpEx() { m_dynGenProfiles.MenuClick -= this.OnProfilesDynamicMenuClick; m_dynGenProfiles.Clear(); m_btnBinOpen.SplitDropDownMenu = null; m_dynBinOpen.MenuClick -= this.OnDynBinOpen; m_dynBinOpen.Clear(); m_ctxBinOpen.Opening -= this.OnCtxBinOpenOpening; m_ctxBinOpen.Dispose(); if(m_pwEditMode != PwEditMode.ViewReadOnlyEntry) Program.Config.UI.Hiding.HideInEntryWindow = m_cbHidePassword.Checked; m_ctxNotes.Detach(); m_icgPassword.Release(); m_cgExpiry.Release(); m_cmbOverrideUrl.OrderedImageList = null; foreach(Image img in m_lOverrideUrlIcons) { if(img != null) img.Dispose(); } m_lOverrideUrlIcons.Clear(); // Detach event handlers m_lvStrings.SmallImageList = null; m_lvBinaries.SmallImageList = null; m_lvAutoType.SmallImageList = null; m_lvHistory.SmallImageList = null; if(m_imgTools != null) // Only dispose scaled image UIUtil.DisposeButtonImage(m_btnTools, ref m_imgTools); UIUtil.DisposeButtonImage(m_btnGenPw, ref m_imgGenPw); UIUtil.DisposeButtonImage(m_btnStandardExpires, ref m_imgStdExpire); UIUtil.DisposeButtonImage(m_btnPickFgColor, ref m_imgColorFg); UIUtil.DisposeButtonImage(m_btnPickBgColor, ref m_imgColorBg); } private void OnBtnStrAdd(object sender, EventArgs e) { if(m_pwEditMode == PwEditMode.ViewReadOnlyEntry) return; UpdateEntryStrings(true, false, false); EditStringForm esf = new EditStringForm(); esf.InitEx(m_vStrings, null, null, m_pwDatabase); if(UIUtil.ShowDialogAndDestroy(esf) == DialogResult.OK) { UpdateEntryStrings(false, false, true); ResizeColumnHeaders(); } } private void OnBtnStrEdit(object sender, EventArgs e) { if(m_pwEditMode == PwEditMode.ViewReadOnlyEntry) return; ListView.SelectedListViewItemCollection vSel = m_lvStrings.SelectedItems; if(vSel.Count <= 0) return; UpdateEntryStrings(true, false, false); string strName = vSel[0].Text; ProtectedString psValue = m_vStrings.Get(strName); Debug.Assert(psValue != null); EditStringForm esf = new EditStringForm(); esf.InitEx(m_vStrings, strName, psValue, m_pwDatabase); if(UIUtil.ShowDialogAndDestroy(esf) == DialogResult.OK) UpdateEntryStrings(false, false, true); } private void OnBtnStrDelete(object sender, EventArgs e) { if(m_pwEditMode == PwEditMode.ViewReadOnlyEntry) return; UpdateEntryStrings(true, false, false); ListView.SelectedListViewItemCollection lvsc = m_lvStrings.SelectedItems; foreach(ListViewItem lvi in lvsc) { if(!m_vStrings.Remove(lvi.Text)) { Debug.Assert(false); } } if(lvsc.Count > 0) { UpdateEntryStrings(false, false, true); ResizeColumnHeaders(); } } private void OnBtnBinAdd(object sender, EventArgs e) { m_ctxBinAttach.ShowEx(m_btnBinAdd); } private void OnBtnBinDelete(object sender, EventArgs e) { if(m_pwEditMode == PwEditMode.ViewReadOnlyEntry) return; UpdateEntryBinaries(true, false); ListView.SelectedListViewItemCollection lvsc = m_lvBinaries.SelectedItems; foreach(ListViewItem lvi in lvsc) { if(!m_vBinaries.Remove(lvi.Text)) { Debug.Assert(false); } } if(lvsc.Count > 0) { UpdateEntryBinaries(false, true); ResizeColumnHeaders(); } } private void OnBtnBinSave(object sender, EventArgs e) { ListView.SelectedListViewItemCollection lvsc = m_lvBinaries.SelectedItems; int nSelCount = lvsc.Count; if(nSelCount == 0) { Debug.Assert(false); return; } if(nSelCount == 1) { SaveFileDialogEx sfd = UIUtil.CreateSaveFileDialog(KPRes.AttachmentSave, lvsc[0].Text, UIUtil.CreateFileTypeFilter(null, null, true), 1, null, AppDefs.FileDialogContext.Attachments); if(sfd.ShowDialog() == DialogResult.OK) SaveAttachmentTo(lvsc[0], sfd.FileName, false); } else // nSelCount > 1 { FolderBrowserDialog fbd = UIUtil.CreateFolderBrowserDialog(KPRes.AttachmentsSave); if(fbd.ShowDialog() == DialogResult.OK) { string strRootPath = UrlUtil.EnsureTerminatingSeparator(fbd.SelectedPath, false); foreach(ListViewItem lvi in lvsc) SaveAttachmentTo(lvi, strRootPath + lvi.Text, true); } fbd.Dispose(); } } private void SaveAttachmentTo(ListViewItem lvi, string strFileName, bool bConfirmOverwrite) { Debug.Assert(lvi != null); if(lvi == null) throw new ArgumentNullException("lvi"); Debug.Assert(strFileName != null); if(strFileName == null) throw new ArgumentNullException("strFileName"); if(bConfirmOverwrite && File.Exists(strFileName)) { string strMsg = KPRes.FileExistsAlready + MessageService.NewLine + strFileName + MessageService.NewParagraph + KPRes.OverwriteExistingFileQuestion; if(MessageService.AskYesNo(strMsg) == false) return; } ProtectedBinary pb = m_vBinaries.Get(lvi.Text); Debug.Assert(pb != null); if(pb == null) throw new ArgumentException(); byte[] pbData = pb.ReadData(); try { File.WriteAllBytes(strFileName, pbData); } catch(Exception exWrite) { MessageService.ShowWarning(strFileName, exWrite); } MemUtil.ZeroByteArray(pbData); } private void OnBtnAutoTypeAdd(object sender, EventArgs e) { if(m_pwEditMode == PwEditMode.ViewReadOnlyEntry) return; EditAutoTypeItemForm dlg = new EditAutoTypeItemForm(); dlg.InitEx(m_atConfig, -1, false, m_tbDefaultAutoTypeSeq.Text, m_vStrings); if(UIUtil.ShowDialogAndDestroy(dlg) == DialogResult.OK) { AutoTypeAssociation a = null; if(m_atConfig.AssociationsCount > 0) a = m_atConfig.GetAt(m_atConfig.AssociationsCount - 1); else { Debug.Assert(false); } UpdateAutoTypeList(ListSelRestore.None, a, true); ResizeColumnHeaders(); } } private void OnBtnAutoTypeEdit(object sender, EventArgs e) { if(m_pwEditMode == PwEditMode.ViewReadOnlyEntry) return; ListView.SelectedIndexCollection lvSel = m_lvAutoType.SelectedIndices; Debug.Assert(lvSel.Count == 1); if(lvSel.Count != 1) return; EditAutoTypeItemForm dlg = new EditAutoTypeItemForm(); dlg.InitEx(m_atConfig, lvSel[0], false, m_tbDefaultAutoTypeSeq.Text, m_vStrings); if(UIUtil.ShowDialogAndDestroy(dlg) == DialogResult.OK) UpdateAutoTypeList(ListSelRestore.ByIndex, null, true); } private void OnBtnAutoTypeDelete(object sender, EventArgs e) { if(m_pwEditMode == PwEditMode.ViewReadOnlyEntry) return; int j, nItemCount = m_lvAutoType.Items.Count; for(int i = 0; i < nItemCount; ++i) { j = nItemCount - i - 1; if(m_lvAutoType.Items[j].Selected) m_atConfig.RemoveAt(j); } UpdateAutoTypeList(ListSelRestore.None, null, true); ResizeColumnHeaders(); } private void OnBtnHistoryView(object sender, EventArgs e) { Debug.Assert(m_vHistory.UCount == m_lvHistory.Items.Count); ListView.SelectedIndexCollection lvsi = m_lvHistory.SelectedIndices; if(lvsi.Count != 1) { Debug.Assert(false); return; } PwEntry pe = m_vHistory.GetAt((uint)lvsi[0]); if(pe == null) { Debug.Assert(false); return; } PwEntryForm pwf = new PwEntryForm(); pwf.InitEx(pe, PwEditMode.ViewReadOnlyEntry, m_pwDatabase, m_ilIcons, false, false); UIUtil.ShowDialogAndDestroy(pwf); } private void OnBtnHistoryDelete(object sender, EventArgs e) { if(m_pwEditMode == PwEditMode.ViewReadOnlyEntry) return; Debug.Assert(m_vHistory.UCount == m_lvHistory.Items.Count); ListView.SelectedIndexCollection lvsc = m_lvHistory.SelectedIndices; int n = lvsc.Count; // Getting Count sends a message if(n == 0) return; // LVSIC: one access by index requires O(n) time, thus copy // all to an array (which requires O(1) for each element) int[] v = new int[n]; lvsc.CopyTo(v, 0); for(int i = 0; i < n; ++i) m_vHistory.RemoveAt((uint)v[n - i - 1]); UpdateHistoryList(true); ResizeColumnHeaders(); } private void OnBtnHistoryRestore(object sender, EventArgs e) { if(m_pwEditMode == PwEditMode.ViewReadOnlyEntry) return; Debug.Assert(m_vHistory.UCount == m_lvHistory.Items.Count); ListView.SelectedIndexCollection lvsi = m_lvHistory.SelectedIndices; if(lvsi.Count != 1) { Debug.Assert(false); return; } m_pwEntry.RestoreFromBackup((uint)lvsi[0], m_pwDatabase); m_pwEntry.Touch(true, false); m_bTouchedOnce = true; this.DialogResult = DialogResult.OK; // Doesn't invoke OnBtnOK } private void OnHistorySelectedIndexChanged(object sender, EventArgs e) { EnableControlsEx(); } private void OnStringsSelectedIndexChanged(object sender, EventArgs e) { EnableControlsEx(); } private void OnBinariesSelectedIndexChanged(object sender, EventArgs e) { EnableControlsEx(); } private void SetExpireIn(int nYears, int nMonths, int nDays) { if(m_pwEditMode == PwEditMode.ViewReadOnlyEntry) return; DateTime dt = DateTime.Now; // Not UTC if((nYears != 0) || (nMonths != 0) || (nDays != 0)) { dt = dt.Date; // Remove time part dt = dt.AddYears(nYears); dt = dt.AddMonths(nMonths); dt = dt.AddDays(nDays); DateTime dtPrev = TimeUtil.ToLocal(m_cgExpiry.Value, false); dt = dt.AddHours(dtPrev.Hour); dt = dt.AddMinutes(dtPrev.Minute); dt = dt.AddSeconds(dtPrev.Second); } // else do not change the time part of dt m_cgExpiry.Checked = true; m_cgExpiry.Value = dt; EnableControlsEx(); } private void OnMenuExpireNow(object sender, EventArgs e) { SetExpireIn(0, 0, 0); } private void OnMenuExpire1Week(object sender, EventArgs e) { SetExpireIn(0, 0, 7); } private void OnMenuExpire2Weeks(object sender, EventArgs e) { SetExpireIn(0, 0, 14); } private void OnMenuExpire1Month(object sender, EventArgs e) { SetExpireIn(0, 1, 0); } private void OnMenuExpire3Months(object sender, EventArgs e) { SetExpireIn(0, 3, 0); } private void OnMenuExpire6Months(object sender, EventArgs e) { SetExpireIn(0, 6, 0); } private void OnMenuExpire1Year(object sender, EventArgs e) { SetExpireIn(1, 0, 0); } private void OnBtnStandardExpiresClick(object sender, EventArgs e) { m_ctxDefaultTimes.ShowEx(m_btnStandardExpires); } private void OnCtxCopyFieldValue(object sender, EventArgs e) { ListView.SelectedListViewItemCollection lvsc; if(m_lvStrings.Focused) { lvsc = m_lvStrings.SelectedItems; if((lvsc != null) && (lvsc.Count > 0)) { string strName = lvsc[0].Text; ClipboardUtil.Copy(m_vStrings.ReadSafe(strName), true, true, null, m_pwDatabase, this.Handle); } } else if(m_lvAutoType.Focused) { lvsc = m_lvAutoType.SelectedItems; if((lvsc != null) && (lvsc.Count > 0)) ClipboardUtil.Copy(lvsc[0].SubItems[1].Text, true, true, null, m_pwDatabase, this.Handle); } else { Debug.Assert(false); } } private void OnBtnPickIcon(object sender, EventArgs e) { if(m_pwEditMode == PwEditMode.ViewReadOnlyEntry) return; IconPickerForm ipf = new IconPickerForm(); ipf.InitEx(m_ilIcons, (uint)PwIcon.Count, m_pwDatabase, (uint)m_pwEntryIcon, m_pwCustomIconID); if(ipf.ShowDialog() == DialogResult.OK) { if(!ipf.ChosenCustomIconUuid.Equals(PwUuid.Zero)) // Custom icon { m_pwCustomIconID = ipf.ChosenCustomIconUuid; UIUtil.SetButtonImage(m_btnIcon, DpiUtil.GetIcon( m_pwDatabase, m_pwCustomIconID), true); } else // Standard icon { m_pwEntryIcon = (PwIcon)ipf.ChosenIconId; m_pwCustomIconID = PwUuid.Zero; UIUtil.SetButtonImage(m_btnIcon, m_ilIcons.Images[ (int)m_pwEntryIcon], true); } } UIUtil.DestroyForm(ipf); } private void OnAutoTypeSeqInheritCheckedChanged(object sender, EventArgs e) { EnableControlsEx(); } private void OnAutoTypeEnableCheckedChanged(object sender, EventArgs e) { EnableControlsEx(); } private void OnBtnAutoTypeEditDefault(object sender, EventArgs e) { if(m_pwEditMode == PwEditMode.ViewReadOnlyEntry) return; SaveDefaultSeq(); EditAutoTypeItemForm ef = new EditAutoTypeItemForm(); ef.InitEx(m_atConfig, -1, true, m_tbDefaultAutoTypeSeq.Text, m_vStrings); if(UIUtil.ShowDialogAndDestroy(ef) == DialogResult.OK) m_tbDefaultAutoTypeSeq.Text = m_atConfig.DefaultSequence; } private void OnCtxMoveToTitle(object sender, EventArgs e) { MoveSelectedStringTo(PwDefs.TitleField); } private void OnCtxMoveToUserName(object sender, EventArgs e) { MoveSelectedStringTo(PwDefs.UserNameField); } private void OnCtxMoveToPassword(object sender, EventArgs e) { MoveSelectedStringTo(PwDefs.PasswordField); } private void OnCtxMoveToURL(object sender, EventArgs e) { MoveSelectedStringTo(PwDefs.UrlField); } private void OnCtxMoveToNotes(object sender, EventArgs e) { MoveSelectedStringTo(PwDefs.NotesField); } private void MoveSelectedStringTo(string strStandardField) { ListView.SelectedListViewItemCollection lvsic = m_lvStrings.SelectedItems; Debug.Assert(lvsic.Count == 1); if(lvsic.Count != 1) return; ListViewItem lvi = lvsic[0]; string strText = m_vStrings.ReadSafe(lvi.Text); if(strStandardField == PwDefs.TitleField) { if((m_tbTitle.TextLength > 0) && (strText.Length > 0)) m_tbTitle.Text += ", "; m_tbTitle.Text += strText; } else if(strStandardField == PwDefs.UserNameField) { if((m_tbUserName.TextLength > 0) && (strText.Length > 0)) m_tbUserName.Text += ", "; m_tbUserName.Text += strText; } else if(strStandardField == PwDefs.PasswordField) { string strPw = m_icgPassword.GetPassword(); if((strPw.Length > 0) && (strText.Length > 0)) strPw += ", "; strPw += strText; string strRep = m_icgPassword.GetRepeat(); if((strRep.Length > 0) && (strText.Length > 0)) strRep += ", "; strRep += strText; m_icgPassword.SetPasswords(strPw, strRep); } else if(strStandardField == PwDefs.UrlField) { if((m_tbUrl.TextLength > 0) && (strText.Length > 0)) m_tbUrl.Text += ", "; m_tbUrl.Text += strText; } else if(strStandardField == PwDefs.NotesField) { if((m_rtNotes.TextLength > 0) && (strText.Length > 0)) m_rtNotes.Text += MessageService.NewParagraph; m_rtNotes.Text += strText; } else { Debug.Assert(false); } UpdateEntryStrings(true, false, false); m_vStrings.Remove(lvi.Text); UpdateEntryStrings(false, false, true); } private void OnBtnStrMove(object sender, EventArgs e) { m_ctxStrMoveToStandard.ShowEx(m_btnStrMove); } private void OnNotesLinkClicked(object sender, LinkClickedEventArgs e) { WinUtil.OpenUrl(e.LinkText, m_pwEntry); } private void OnAutoTypeSelectedIndexChanged(object sender, EventArgs e) { EnableControlsEx(); } private void OnAutoTypeItemActivate(object sender, EventArgs e) { OnBtnAutoTypeEdit(sender, e); } private void OnStringsItemActivate(object sender, EventArgs e) { OnBtnStrEdit(sender, e); } private void OnPwGenOpen(object sender, EventArgs e) { byte[] pbCurPassword = m_icgPassword.GetPasswordUtf8(); bool bAtLeastOneChar = (pbCurPassword.Length > 0); ProtectedString ps = new ProtectedString(true, pbCurPassword); MemUtil.ZeroByteArray(pbCurPassword); PwProfile opt = PwProfile.DeriveFromPassword(ps); PwGeneratorForm pgf = new PwGeneratorForm(); pgf.InitEx((bAtLeastOneChar ? opt : null), true, false); if(pgf.ShowDialog() == DialogResult.OK) { byte[] pbEntropy = EntropyForm.CollectEntropyIfEnabled(pgf.SelectedProfile); ProtectedString psNew = PwGeneratorUtil.GenerateAcceptable( pgf.SelectedProfile, pbEntropy, m_pwEntry, m_pwDatabase); byte[] pbNew = psNew.ReadUtf8(); m_icgPassword.SetPassword(pbNew, true); MemUtil.ZeroByteArray(pbNew); } UIUtil.DestroyForm(pgf); EnableControlsEx(); } private void OnProfilesDynamicMenuClick(object sender, DynamicMenuEventArgs e) { string strProfile = (e.Tag as string); if(strProfile == null) { Debug.Assert(false); return; } PwProfile pwp = null; if(strProfile == DeriveFromPrevious) { byte[] pbCur = m_icgPassword.GetPasswordUtf8(); ProtectedString psCur = new ProtectedString(true, pbCur); MemUtil.ZeroByteArray(pbCur); pwp = PwProfile.DeriveFromPassword(psCur); } else if(strProfile == AutoGenProfile) pwp = Program.Config.PasswordGenerator.AutoGeneratedPasswordsProfile; else { foreach(PwProfile pwgo in PwGeneratorUtil.GetAllProfiles(false)) { if(pwgo.Name == strProfile) { pwp = pwgo; break; } } } if(pwp != null) { ProtectedString psNew = PwGeneratorUtil.GenerateAcceptable( pwp, null, m_pwEntry, m_pwDatabase); byte[] pbNew = psNew.ReadUtf8(); m_icgPassword.SetPassword(pbNew, true); MemUtil.ZeroByteArray(pbNew); } else { Debug.Assert(false); } } private void OnPwGenClick(object sender, EventArgs e) { m_dynGenProfiles.Clear(); m_dynGenProfiles.AddSeparator(); List lAvailKeys = new List(PwCharSet.MenuAccels); DynAddProfile(DeriveFromPrevious, Properties.Resources.B16x16_CompFile, lAvailKeys); DynAddProfile(AutoGenProfile, Properties.Resources.B16x16_FileNew, lAvailKeys); bool bHideBuiltIn = ((Program.Config.UI.UIFlags & (ulong)AceUIFlags.HideBuiltInPwGenPrfInEntryDlg) != 0); List> l = new List>(); foreach(PwProfile pwgo in PwGeneratorUtil.GetAllProfiles(true)) { if((pwgo.Name != DeriveFromPrevious) && (pwgo.Name != AutoGenProfile)) { if(bHideBuiltIn && PwGeneratorUtil.IsBuiltInProfile(pwgo.Name)) continue; l.Add(new KeyValuePair(pwgo.Name, Properties.Resources.B16x16_KOrganizer)); } } if(l.Count > 0) m_dynGenProfiles.AddSeparator(); foreach(KeyValuePair kvp in l) DynAddProfile(kvp.Key, kvp.Value, lAvailKeys); m_ctxPwGen.ShowEx(m_btnGenPw); } private void DynAddProfile(string strProfile, Image img, List lAvailKeys) { string strText = StrUtil.EncodeMenuText(strProfile); strText = StrUtil.AddAccelerator(strText, lAvailKeys); m_dynGenProfiles.AddItem(strText, img, strProfile); } private void OnPickForegroundColor(object sender, EventArgs e) { Color? clr = UIUtil.ShowColorDialog(m_clrForeground); if(clr.HasValue) { m_clrForeground = clr.Value; UIUtil.OverwriteButtonImage(m_btnPickFgColor, ref m_imgColorFg, UIUtil.CreateColorBitmap24(m_btnPickFgColor, m_clrForeground)); } } private void OnPickBackgroundColor(object sender, EventArgs e) { Color? clr = UIUtil.ShowColorDialog(m_clrBackground); if(clr.HasValue) { m_clrBackground = clr.Value; UIUtil.OverwriteButtonImage(m_btnPickBgColor, ref m_imgColorBg, UIUtil.CreateColorBitmap24(m_btnPickBgColor, m_clrBackground)); } } private void OnCustomForegroundColorCheckedChanged(object sender, EventArgs e) { EnableControlsEx(); } private void OnCustomBackgroundColorCheckedChanged(object sender, EventArgs e) { EnableControlsEx(); } private void OnFormClosed(object sender, FormClosedEventArgs e) { GlobalWindowManager.RemoveWindow(this); } private void OnAutoTypeObfuscationLink(object sender, LinkLabelLinkClickedEventArgs e) { if(e.Button == MouseButtons.Left) AppHelp.ShowHelp(AppDefs.HelpTopics.AutoTypeObfuscation, null); } private void OnAutoTypeObfuscationCheckedChanged(object sender, EventArgs e) { if(m_bInitializing) return; if(m_cbAutoTypeObfuscation.Checked == false) return; MessageService.ShowInfo(KPRes.AutoTypeObfuscationHint, KPRes.DocumentationHint); } private bool GetSelBin(out string strDataItem, out ProtectedBinary pb) { strDataItem = null; pb = null; ListView.SelectedListViewItemCollection lvsic = m_lvBinaries.SelectedItems; if((lvsic == null) || (lvsic.Count != 1)) return false; // No assert strDataItem = lvsic[0].Text; pb = m_vBinaries.Get(strDataItem); if(pb == null) { Debug.Assert(false); return false; } return true; } private void OpenSelBin(BinaryDataOpenOptions optBase) { string strDataItem; ProtectedBinary pb; if(!GetSelBin(out strDataItem, out pb)) return; BinaryDataOpenOptions opt = ((optBase != null) ? optBase.CloneDeep() : new BinaryDataOpenOptions()); if(m_pwEditMode == PwEditMode.ViewReadOnlyEntry) { if(optBase == null) opt.Handler = BinaryDataHandler.InternalViewer; opt.ReadOnly = true; } ProtectedBinary pbMod = BinaryDataUtil.Open(strDataItem, pb, opt); if(pbMod != null) { m_vBinaries.Set(strDataItem, pbMod); UpdateEntryBinaries(false, true, strDataItem); // Update size } } private void OnBtnBinOpen(object sender, EventArgs e) { OpenSelBin(null); } private void OnDynBinOpen(object sender, DynamicMenuEventArgs e) { if(e == null) { Debug.Assert(false); return; } BinaryDataOpenOptions opt = (e.Tag as BinaryDataOpenOptions); if(opt == null) { Debug.Assert(false); return; } OpenSelBin(opt); } private void OnCtxBinOpenOpening(object sender, CancelEventArgs e) { string strDataItem; ProtectedBinary pb; if(!GetSelBin(out strDataItem, out pb)) { e.Cancel = true; return; } BinaryDataUtil.BuildOpenWithMenu(m_dynBinOpen, strDataItem, pb, (m_pwEditMode == PwEditMode.ViewReadOnlyEntry)); } private void OnBtnTools(object sender, EventArgs e) { m_ctxTools.ShowEx(m_btnTools); } private void OnCtxToolsHelp(object sender, EventArgs e) { if(m_tabMain.SelectedTab == m_tabAdvanced) AppHelp.ShowHelp(AppDefs.HelpTopics.Entry, AppDefs.HelpTopics.EntryStrings); else if(m_tabMain.SelectedTab == m_tabAutoType) AppHelp.ShowHelp(AppDefs.HelpTopics.Entry, AppDefs.HelpTopics.EntryAutoType); else if(m_tabMain.SelectedTab == m_tabHistory) AppHelp.ShowHelp(AppDefs.HelpTopics.Entry, AppDefs.HelpTopics.EntryHistory); else AppHelp.ShowHelp(AppDefs.HelpTopics.Entry, null); } private void OnCtxUrlHelp(object sender, EventArgs e) { AppHelp.ShowHelp(AppDefs.HelpTopics.UrlField, null); } private void SelectFileAsUrl(string strFilter) { string strFlt = string.Empty; if(strFilter != null) strFlt += strFilter; strFlt += KPRes.AllFiles + @" (*.*)|*.*"; OpenFileDialogEx dlg = UIUtil.CreateOpenFileDialog(null, strFlt, 1, null, false, AppDefs.FileDialogContext.Attachments); if(dlg.ShowDialog() == DialogResult.OK) m_tbUrl.Text = "cmd://\"" + dlg.FileName + "\""; } private void OnCtxUrlSelApp(object sender, EventArgs e) { SelectFileAsUrl(KPRes.Application + @" (*.exe, *.com, *.bat, *.cmd)|" + @"*.exe;*.com;*.bat;*.cmd|"); } private void OnCtxUrlSelDoc(object sender, EventArgs e) { SelectFileAsUrl(null); } private string CreateFieldReference(string strDefaultRef) { FieldRefForm dlg = new FieldRefForm(); dlg.InitEx(m_pwDatabase.RootGroup, m_ilIcons, strDefaultRef); string strResult = string.Empty; if(dlg.ShowDialog() == DialogResult.OK) strResult = dlg.ResultReference; UIUtil.DestroyForm(dlg); return strResult; } private void OnFieldRefInTitle(object sender, EventArgs e) { m_tbTitle.Text += CreateFieldReference(PwDefs.TitleField); } private void OnFieldRefInUserName(object sender, EventArgs e) { m_tbUserName.Text += CreateFieldReference(PwDefs.UserNameField); } private void OnFieldRefInPassword(object sender, EventArgs e) { string strRef = CreateFieldReference(PwDefs.PasswordField); if(strRef.Length == 0) return; string strPw = m_icgPassword.GetPassword(); string strRep = m_icgPassword.GetRepeat(); m_icgPassword.SetPasswords(strPw + strRef, strRep + strRef); } private void OnFieldRefInUrl(object sender, EventArgs e) { m_tbUrl.Text += CreateFieldReference(PwDefs.UrlField); } private void OnFieldRefInNotes(object sender, EventArgs e) { string strRef = CreateFieldReference(PwDefs.NotesField); if(m_rtNotes.Text.Length == 0) m_rtNotes.Text = strRef; else m_rtNotes.Text += "\r\n" + strRef; } protected override bool ProcessDialogKey(Keys keyData) { if(((keyData == Keys.Return) || (keyData == Keys.Enter)) && m_rtNotes.Focused) return false; // Forward to RichTextBox return base.ProcessDialogKey(keyData); } private bool m_bClosing = false; // Mono bug workaround private void OnFormClosing(object sender, FormClosingEventArgs e) { if(m_bClosing) return; m_bClosing = true; HandleFormClosing(e); m_bClosing = false; } private void HandleFormClosing(FormClosingEventArgs e) { bool bCancel = false; if(!m_bForceClosing && (m_pwEditMode != PwEditMode.ViewReadOnlyEntry)) { PwEntry pe = m_pwInitialEntry.CloneDeep(); SaveEntry(pe, false); bool bModified = !pe.EqualsEntry(m_pwInitialEntry, m_cmpOpt, MemProtCmpMode.CustomOnly); bModified |= !m_icgPassword.ValidateData(false); if(bModified) { string strTitle = pe.Strings.ReadSafe(PwDefs.TitleField).Trim(); string strHdr = ((strTitle.Length == 0) ? (KPRes.Save + "?") : (KPRes.Entry + @" '" + strTitle + @"'")); VistaTaskDialog dlg = new VistaTaskDialog(); dlg.CommandLinks = false; dlg.Content = KPRes.SaveBeforeCloseEntry; dlg.MainInstruction = strHdr; dlg.WindowTitle = PwDefs.ShortProductName; dlg.SetIcon(VtdCustomIcon.Question); dlg.AddButton((int)DialogResult.Yes, KPRes.YesCmd, null); dlg.AddButton((int)DialogResult.No, KPRes.NoCmd, null); dlg.AddButton((int)DialogResult.Cancel, KPRes.Cancel, null); dlg.DefaultButtonID = (int)DialogResult.Yes; DialogResult dr; if(dlg.ShowDialog(this)) dr = (DialogResult)dlg.Result; else dr = MessageService.Ask(KPRes.SaveBeforeCloseEntry, PwDefs.ShortProductName, MessageBoxButtons.YesNoCancel); if((dr == DialogResult.Yes) || (dr == DialogResult.OK)) { bCancel = !SaveEntry(m_pwEntry, true); if(!bCancel) this.DialogResult = DialogResult.OK; } else if((dr == DialogResult.Cancel) || (dr == DialogResult.None)) bCancel = true; } } if(bCancel) { this.DialogResult = DialogResult.None; e.Cancel = true; return; } if(!m_bTouchedOnce) m_pwEntry.Touch(false, false); CleanUpEx(); } private void OnBinariesItemActivate(object sender, EventArgs e) { OnBtnBinOpen(sender, e); } private void OnHistoryItemActivate(object sender, EventArgs e) { OnBtnHistoryView(sender, e); } private void OnCtxBinImport(object sender, EventArgs e) { if(m_pwEditMode == PwEditMode.ViewReadOnlyEntry) return; OpenFileDialogEx ofd = UIUtil.CreateOpenFileDialog(KPRes.AttachFiles, UIUtil.CreateFileTypeFilter(null, null, true), 1, null, true, AppDefs.FileDialogContext.Attachments); if(ofd.ShowDialog() == DialogResult.OK) BinImportFiles(ofd.FileNames); } private void BinImportFiles(string[] vPaths) { if(vPaths == null) { Debug.Assert(false); return; } UpdateEntryBinaries(true, false); foreach(string strFile in vPaths) { if(string.IsNullOrEmpty(strFile)) { Debug.Assert(false); continue; } string strItem = UrlUtil.GetFileName(strFile); if(m_vBinaries.Get(strItem) != null) { string strMsg = KPRes.AttachedExistsAlready + MessageService.NewLine + strItem + MessageService.NewParagraph + KPRes.AttachNewRename + MessageService.NewParagraph + KPRes.AttachNewRenameRemarks0 + MessageService.NewLine + KPRes.AttachNewRenameRemarks1 + MessageService.NewLine + KPRes.AttachNewRenameRemarks2; DialogResult dr = MessageService.Ask(strMsg, null, MessageBoxButtons.YesNoCancel); if(dr == DialogResult.Cancel) continue; else if(dr == DialogResult.Yes) { string strFileName = UrlUtil.StripExtension(strItem); string strExtension = "." + UrlUtil.GetExtension(strItem); int nTry = 0; while(true) { string strNewName = strFileName + nTry.ToString() + strExtension; if(m_vBinaries.Get(strNewName) == null) { strItem = strNewName; break; } ++nTry; } } } try { if(!FileDialogsEx.CheckAttachmentSize(strFile, KPRes.AttachFailed + MessageService.NewParagraph + strFile)) continue; byte[] vBytes = File.ReadAllBytes(strFile); vBytes = DataEditorForm.ConvertAttachment(strItem, vBytes); if(vBytes != null) { ProtectedBinary pb = new ProtectedBinary(false, vBytes); m_vBinaries.Set(strItem, pb); } } catch(Exception exAttach) { MessageService.ShowWarning(KPRes.AttachFailed, strFile, exAttach); } } UpdateEntryBinaries(false, true); ResizeColumnHeaders(); } private void OnCtxBinNew(object sender, EventArgs e) { if(m_pwEditMode == PwEditMode.ViewReadOnlyEntry) return; string strName; for(int i = 0; ; ++i) { strName = KPRes.New; if(i >= 1) strName += " (" + i.ToString() + ")"; strName += ".rtf"; if(m_vBinaries.Get(strName) == null) break; } ProtectedBinary pb = new ProtectedBinary(); m_vBinaries.Set(strName, pb); UpdateEntryBinaries(false, true, strName); ResizeColumnHeaders(); ListViewItem lviNew = m_lvBinaries.FindItemWithText(strName, false, 0, false); if(lviNew != null) lviNew.BeginEdit(); } private void OnBinAfterLabelEdit(object sender, LabelEditEventArgs e) { string strNew = e.Label; e.CancelEdit = true; // In the case of success, we update it on our own if(string.IsNullOrEmpty(strNew)) return; if(m_pwEditMode == PwEditMode.ViewReadOnlyEntry) return; int iItem = e.Item; if((iItem < 0) || (iItem >= m_lvBinaries.Items.Count)) return; string strOld = m_lvBinaries.Items[iItem].Text; if(strNew == strOld) return; if(m_vBinaries.Get(strNew) != null) { MessageService.ShowWarning(KPRes.FieldNameExistsAlready); return; } ProtectedBinary pb = m_vBinaries.Get(strOld); if(pb == null) { Debug.Assert(false); return; } m_vBinaries.Remove(strOld); m_vBinaries.Set(strNew, pb); UpdateEntryBinaries(false, true, strNew); } private static void BinDragAccept(DragEventArgs e) { if(e == null) { Debug.Assert(false); return; } IDataObject ido = e.Data; if((ido == null) || !ido.GetDataPresent(DataFormats.FileDrop)) e.Effect = DragDropEffects.None; else e.Effect = DragDropEffects.Copy; } private void OnBinDragEnter(object sender, DragEventArgs e) { BinDragAccept(e); } private void OnBinDragOver(object sender, DragEventArgs e) { BinDragAccept(e); } private void OnBinDragDrop(object sender, DragEventArgs e) { try { BinImportFiles(e.Data.GetData(DataFormats.FileDrop) as string[]); } catch(Exception) { Debug.Assert(false); } } private void InitOverridesBox() { List> l = new List>(); AddOverrideUrlItem(l, "cmd://{INTERNETEXPLORER} \"{URL}\"", AppLocator.InternetExplorerPath); AddOverrideUrlItem(l, "cmd://{INTERNETEXPLORER} -private \"{URL}\"", AppLocator.InternetExplorerPath); AddOverrideUrlItem(l, "microsoft-edge:{URL}", AppLocator.EdgePath); AddOverrideUrlItem(l, "cmd://{FIREFOX} \"{URL}\"", AppLocator.FirefoxPath); AddOverrideUrlItem(l, "cmd://{FIREFOX} -private-window \"{URL}\"", AppLocator.FirefoxPath); AddOverrideUrlItem(l, "cmd://{GOOGLECHROME} \"{URL}\"", AppLocator.ChromePath); AddOverrideUrlItem(l, "cmd://{GOOGLECHROME} --incognito \"{URL}\"", AppLocator.ChromePath); AddOverrideUrlItem(l, "cmd://{OPERA} \"{URL}\"", AppLocator.OperaPath); AddOverrideUrlItem(l, "cmd://{OPERA} --private \"{URL}\"", AppLocator.OperaPath); AddOverrideUrlItem(l, "cmd://{SAFARI} \"{URL}\"", AppLocator.SafariPath); Debug.Assert(m_cmbOverrideUrl.InvokeRequired || MonoWorkarounds.IsRequired(373134)); VoidDelegate f = delegate() { try { Debug.Assert(!m_cmbOverrideUrl.InvokeRequired); foreach(KeyValuePair kvp in l) { m_cmbOverrideUrl.Items.Add(kvp.Key); m_lOverrideUrlIcons.Add(kvp.Value); } m_cmbOverrideUrl.OrderedImageList = m_lOverrideUrlIcons; } catch(Exception) { Debug.Assert(false); } }; m_cmbOverrideUrl.Invoke(f); } private void AddOverrideUrlItem(List> l, string strOverride, string strIconPath) { if(string.IsNullOrEmpty(strOverride)) { Debug.Assert(false); return; } int w = DpiUtil.ScaleIntX(16); int h = DpiUtil.ScaleIntY(16); Image img = null; string str = UrlUtil.GetQuotedAppPath(strIconPath ?? string.Empty); str = str.Trim(); if(str.Length > 0) img = UIUtil.GetFileIcon(str, w, h); if(img == null) img = GfxUtil.ScaleImage(m_ilIcons.Images[ (int)PwIcon.Console], w, h, ScaleTransformFlags.UIIcon); l.Add(new KeyValuePair(strOverride, img)); } private void OnBtnAutoTypeUp(object sender, EventArgs e) { MoveSelectedAutoTypeItems(false); } private void OnBtnAutoTypeDown(object sender, EventArgs e) { MoveSelectedAutoTypeItems(true); } private void MoveSelectedAutoTypeItems(bool bDown) { if(m_pwEditMode == PwEditMode.ViewReadOnlyEntry) return; int n = m_lvAutoType.Items.Count; int s = m_lvAutoType.SelectedIndices.Count; if(s == 0) return; int[] v = new int[s]; m_lvAutoType.SelectedIndices.CopyTo(v, 0); Array.Sort(v); if((bDown && (v[s - 1] >= (n - 1))) || (!bDown && (v[0] <= 0))) return; // Moving as a block is not possible int iStart = (bDown ? (s - 1) : 0); int iExcl = (bDown ? -1 : s); int iStep = (bDown ? -1 : 1); for(int i = iStart; i != iExcl; i += iStep) { int p = v[i]; AutoTypeAssociation a = m_atConfig.GetAt(p); if(bDown) { Debug.Assert(p < (n - 1)); m_atConfig.RemoveAt(p); m_atConfig.Insert(p + 1, a); } else // Up { Debug.Assert(p > 0); m_atConfig.RemoveAt(p); m_atConfig.Insert(p - 1, a); } } UpdateAutoTypeList(ListSelRestore.ByRef, null, true); } private void OnCustomDataSelectedIndexChanged(object sender, EventArgs e) { EnableControlsEx(); } private void OnBtnCDDel(object sender, EventArgs e) { UIUtil.StrDictListDeleteSel(m_lvCustomData, m_sdCustomData); UIUtil.SetFocus(m_lvCustomData, this); EnableControlsEx(); } } } KeePass/Forms/FieldRefForm.cs0000664000000000000000000001706413222430410015031 0ustar rootroot/* KeePass Password Safe - The Open-Source Password Manager Copyright (C) 2003-2018 Dominik Reichl This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ using System; using System.Collections.Generic; using System.ComponentModel; using System.Diagnostics; using System.Drawing; using System.Text; using System.Windows.Forms; using KeePass.App; using KeePass.Resources; using KeePass.UI; using KeePassLib; using KeePassLib.Collections; using KeePassLib.Utility; namespace KeePass.Forms { public partial class FieldRefForm : Form { private PwGroup m_pgEntrySource = null; private ImageList m_ilIcons = null; private string m_strDefaultRef = string.Empty; private List> m_vColumns = new List>(); private string m_strResultRef = string.Empty; public string ResultReference { get { return m_strResultRef; } } public void InitEx(PwGroup pgEntrySource, ImageList ilClientIcons, string strDefaultRef) { m_pgEntrySource = pgEntrySource; m_ilIcons = ilClientIcons; m_strDefaultRef = (strDefaultRef ?? string.Empty); } public FieldRefForm() { InitializeComponent(); Program.Translation.ApplyTo(this); } private void OnFormLoad(object sender, EventArgs e) { if(m_pgEntrySource == null) { Debug.Assert(false); return; } if(m_ilIcons == null) { Debug.Assert(false); return; } GlobalWindowManager.AddWindow(this); this.Icon = AppIcons.Default; UIUtil.SetExplorerTheme(m_lvEntries, true); m_vColumns.Add(new KeyValuePair(PwDefs.TitleField, KPRes.Title)); m_vColumns.Add(new KeyValuePair(PwDefs.UserNameField, KPRes.UserName)); m_vColumns.Add(new KeyValuePair(PwDefs.UrlField, KPRes.Url)); m_vColumns.Add(new KeyValuePair(PwDefs.NotesField, KPRes.Notes)); PwObjectList vEntries = m_pgEntrySource.GetEntries(true); UIUtil.CreateEntryList(m_lvEntries, vEntries, m_vColumns, m_ilIcons); m_radioIdUuid.Checked = true; if(m_strDefaultRef == PwDefs.TitleField) m_radioRefTitle.Checked = true; else if(m_strDefaultRef == PwDefs.UserNameField) m_radioRefUserName.Checked = true; // else if(m_strDefaultRef == PwDefs.PasswordField) // m_radioRefPassword.Checked = true; else if(m_strDefaultRef == PwDefs.UrlField) m_radioRefUrl.Checked = true; else if(m_strDefaultRef == PwDefs.NotesField) m_radioRefNotes.Checked = true; else m_radioRefPassword.Checked = true; } private void CleanUpEx() { m_lvEntries.SmallImageList = null; // Detach event handlers } private void OnFormClosed(object sender, FormClosedEventArgs e) { CleanUpEx(); GlobalWindowManager.RemoveWindow(this); } private PwEntry GetSelectedEntry() { ListView.SelectedListViewItemCollection lvsic = m_lvEntries.SelectedItems; if((lvsic == null) || (lvsic.Count != 1)) return null; return (lvsic[0].Tag as PwEntry); } private bool CreateResultRef() { PwEntry pe = this.GetSelectedEntry(); if(pe == null) return false; string str = @"{REF:"; if(m_radioRefTitle.Checked) str += "T"; else if(m_radioRefUserName.Checked) str += "U"; else if(m_radioRefPassword.Checked) str += "P"; else if(m_radioRefUrl.Checked) str += "A"; else if(m_radioRefNotes.Checked) str += "N"; else { Debug.Assert(false); return false; } str += @"@"; string strId; if(m_radioIdTitle.Checked) strId = @"T:" + pe.Strings.ReadSafe(PwDefs.TitleField); else if(m_radioIdUserName.Checked) strId = @"U:" + pe.Strings.ReadSafe(PwDefs.UserNameField); else if(m_radioIdPassword.Checked) strId = @"P:" + pe.Strings.ReadSafe(PwDefs.PasswordField); else if(m_radioIdUrl.Checked) strId = @"A:" + pe.Strings.ReadSafe(PwDefs.UrlField); else if(m_radioIdNotes.Checked) strId = @"N:" + pe.Strings.ReadSafe(PwDefs.NotesField); else if(m_radioIdUuid.Checked) strId = @"I:" + pe.Uuid.ToHexString(); else { Debug.Assert(false); return false; } char[] vInvalidChars = new char[] { '{', '}', '\r', '\n' }; if(strId.IndexOfAny(vInvalidChars) >= 0) { MessageService.ShowWarning(KPRes.FieldRefInvalidChars); return false; } string strIdData = strId.Substring(2, strId.Length - 2); if(IdMatchesMultipleTimes(strIdData, strId[0])) { MessageService.ShowWarning(KPRes.FieldRefMultiMatch, KPRes.FieldRefMultiMatchHint); return false; } str += strId + @"}"; m_strResultRef = str; return true; } private bool IdMatchesMultipleTimes(string strSearch, char tchField) { if(m_pgEntrySource == null) { Debug.Assert(false); return false; } SearchParameters sp = SearchParameters.None; sp.SearchString = strSearch; sp.RespectEntrySearchingDisabled = false; if(tchField == 'T') sp.SearchInTitles = true; else if(tchField == 'U') sp.SearchInUserNames = true; else if(tchField == 'P') sp.SearchInPasswords = true; else if(tchField == 'A') sp.SearchInUrls = true; else if(tchField == 'N') sp.SearchInNotes = true; else if(tchField == 'I') sp.SearchInUuids = true; else { Debug.Assert(false); return true; } PwObjectList l = new PwObjectList(); m_pgEntrySource.SearchEntries(sp, l); if(l.UCount == 0) { Debug.Assert(false); return false; } else if(l.UCount == 1) return false; return true; } private void OnBtnOK(object sender, EventArgs e) { if(!CreateResultRef()) this.DialogResult = DialogResult.None; } private void OnBtnCancel(object sender, EventArgs e) { } private void EnableChildControls() { m_btnOK.Enabled = (GetSelectedEntry() != null); } private void OnEntriesSelectedIndexChanged(object sender, EventArgs e) { EnableChildControls(); } private void OnBtnHelp(object sender, EventArgs e) { AppHelp.ShowHelp(AppDefs.HelpTopics.FieldRefs, null); } protected override bool ProcessDialogKey(Keys keyData) { if(((keyData == Keys.Return) || (keyData == Keys.Enter)) && m_tbFilter.Focused) return false; // Forward to TextBox return base.ProcessDialogKey(keyData); } private void OnFilterKeyDown(object sender, KeyEventArgs e) { if((e.KeyCode == Keys.Return) || (e.KeyCode == Keys.Enter)) { e.SuppressKeyPress = true; SearchParameters sp = new SearchParameters(); sp.SearchString = m_tbFilter.Text; sp.SearchInPasswords = true; PwObjectList lResults = new PwObjectList(); m_pgEntrySource.SearchEntries(sp, lResults); UIUtil.CreateEntryList(m_lvEntries, lResults, m_vColumns, m_ilIcons); } } private void OnFilterKeyUp(object sender, KeyEventArgs e) { if((e.KeyCode == Keys.Return) || (e.KeyCode == Keys.Enter)) e.SuppressKeyPress = true; } } } KeePass/Forms/DataEditorForm.Designer.cs0000664000000000000000000005331213072671030017134 0ustar rootrootnamespace KeePass.Forms { partial class DataEditorForm { /// /// Required designer variable. /// private System.ComponentModel.IContainer components = null; /// /// Clean up any resources being used. /// /// true if managed resources should be disposed; otherwise, false. protected override void Dispose(bool disposing) { if(disposing && (components != null)) { components.Dispose(); } base.Dispose(disposing); } #region Windows Form Designer generated code /// /// Required method for Designer support - do not modify /// the contents of this method with the code editor. /// private void InitializeComponent() { this.m_menuMain = new KeePass.UI.CustomMenuStripEx(); this.m_menuFile = new System.Windows.Forms.ToolStripMenuItem(); this.m_menuFileSave = new System.Windows.Forms.ToolStripMenuItem(); this.m_menuFileSep0 = new System.Windows.Forms.ToolStripSeparator(); this.m_menuFileExit = new System.Windows.Forms.ToolStripMenuItem(); this.m_menuView = new System.Windows.Forms.ToolStripMenuItem(); this.m_menuViewFont = new System.Windows.Forms.ToolStripMenuItem(); this.m_menuViewSep0 = new System.Windows.Forms.ToolStripSeparator(); this.m_menuViewWordWrap = new System.Windows.Forms.ToolStripMenuItem(); this.m_toolFile = new KeePass.UI.CustomToolStripEx(); this.m_tbFileSave = new System.Windows.Forms.ToolStripButton(); this.m_tbFileSep0 = new System.Windows.Forms.ToolStripSeparator(); this.m_tbEditCut = new System.Windows.Forms.ToolStripButton(); this.m_tbEditCopy = new System.Windows.Forms.ToolStripButton(); this.m_tbEditPaste = new System.Windows.Forms.ToolStripButton(); this.m_tbFileSep1 = new System.Windows.Forms.ToolStripSeparator(); this.m_tbEditUndo = new System.Windows.Forms.ToolStripButton(); this.m_tbEditRedo = new System.Windows.Forms.ToolStripButton(); this.m_tbFileSep2 = new System.Windows.Forms.ToolStripSeparator(); this.m_tbFind = new System.Windows.Forms.ToolStripTextBox(); this.m_toolFormat = new KeePass.UI.CustomToolStripEx(); this.m_tbFontCombo = new System.Windows.Forms.ToolStripComboBox(); this.m_tbFontSizeCombo = new System.Windows.Forms.ToolStripComboBox(); this.m_tbFormatSep0 = new System.Windows.Forms.ToolStripSeparator(); this.m_tbFormatBold = new System.Windows.Forms.ToolStripButton(); this.m_tbFormatItalic = new System.Windows.Forms.ToolStripButton(); this.m_tbFormatUnderline = new System.Windows.Forms.ToolStripButton(); this.m_tbFormatStrikeout = new System.Windows.Forms.ToolStripButton(); this.m_tbFormatSep1 = new System.Windows.Forms.ToolStripSeparator(); this.m_tbColorForeground = new System.Windows.Forms.ToolStripButton(); this.m_tbColorBackground = new System.Windows.Forms.ToolStripButton(); this.m_tbFormatSep2 = new System.Windows.Forms.ToolStripSeparator(); this.m_tbAlignLeft = new System.Windows.Forms.ToolStripButton(); this.m_tbAlignCenter = new System.Windows.Forms.ToolStripButton(); this.m_tbAlignRight = new System.Windows.Forms.ToolStripButton(); this.m_statusMain = new System.Windows.Forms.StatusStrip(); this.m_tssStatusMain = new System.Windows.Forms.ToolStripStatusLabel(); this.m_rtbText = new KeePass.UI.CustomRichTextBoxEx(); this.m_menuMain.SuspendLayout(); this.m_toolFile.SuspendLayout(); this.m_toolFormat.SuspendLayout(); this.m_statusMain.SuspendLayout(); this.SuspendLayout(); // // m_menuMain // this.m_menuMain.Items.AddRange(new System.Windows.Forms.ToolStripItem[] { this.m_menuFile, this.m_menuView}); this.m_menuMain.Location = new System.Drawing.Point(0, 0); this.m_menuMain.Name = "m_menuMain"; this.m_menuMain.Size = new System.Drawing.Size(608, 24); this.m_menuMain.TabIndex = 1; // // m_menuFile // this.m_menuFile.DropDownItems.AddRange(new System.Windows.Forms.ToolStripItem[] { this.m_menuFileSave, this.m_menuFileSep0, this.m_menuFileExit}); this.m_menuFile.Name = "m_menuFile"; this.m_menuFile.Size = new System.Drawing.Size(37, 20); this.m_menuFile.Text = "&File"; // // m_menuFileSave // this.m_menuFileSave.Image = global::KeePass.Properties.Resources.B16x16_FileSave; this.m_menuFileSave.Name = "m_menuFileSave"; this.m_menuFileSave.Size = new System.Drawing.Size(103, 22); this.m_menuFileSave.Text = "&Save"; this.m_menuFileSave.Click += new System.EventHandler(this.OnFileSave); // // m_menuFileSep0 // this.m_menuFileSep0.Name = "m_menuFileSep0"; this.m_menuFileSep0.Size = new System.Drawing.Size(100, 6); // // m_menuFileExit // this.m_menuFileExit.Image = global::KeePass.Properties.Resources.B16x16_Exit; this.m_menuFileExit.Name = "m_menuFileExit"; this.m_menuFileExit.Size = new System.Drawing.Size(103, 22); this.m_menuFileExit.Text = "&Close"; this.m_menuFileExit.Click += new System.EventHandler(this.OnFileExit); // // m_menuView // this.m_menuView.DropDownItems.AddRange(new System.Windows.Forms.ToolStripItem[] { this.m_menuViewFont, this.m_menuViewSep0, this.m_menuViewWordWrap}); this.m_menuView.Name = "m_menuView"; this.m_menuView.Size = new System.Drawing.Size(44, 20); this.m_menuView.Text = "&View"; // // m_menuViewFont // this.m_menuViewFont.Name = "m_menuViewFont"; this.m_menuViewFont.Size = new System.Drawing.Size(134, 22); this.m_menuViewFont.Text = "&Font..."; this.m_menuViewFont.Click += new System.EventHandler(this.OnViewFont); // // m_menuViewSep0 // this.m_menuViewSep0.Name = "m_menuViewSep0"; this.m_menuViewSep0.Size = new System.Drawing.Size(131, 6); // // m_menuViewWordWrap // this.m_menuViewWordWrap.Name = "m_menuViewWordWrap"; this.m_menuViewWordWrap.Size = new System.Drawing.Size(134, 22); this.m_menuViewWordWrap.Text = "Word &Wrap"; this.m_menuViewWordWrap.Click += new System.EventHandler(this.OnViewWordWrap); // // m_toolFile // this.m_toolFile.Items.AddRange(new System.Windows.Forms.ToolStripItem[] { this.m_tbFileSave, this.m_tbFileSep0, this.m_tbEditCut, this.m_tbEditCopy, this.m_tbEditPaste, this.m_tbFileSep1, this.m_tbEditUndo, this.m_tbEditRedo, this.m_tbFileSep2, this.m_tbFind}); this.m_toolFile.Location = new System.Drawing.Point(0, 24); this.m_toolFile.Name = "m_toolFile"; this.m_toolFile.Size = new System.Drawing.Size(608, 25); this.m_toolFile.TabIndex = 2; // // m_tbFileSave // this.m_tbFileSave.DisplayStyle = System.Windows.Forms.ToolStripItemDisplayStyle.Image; this.m_tbFileSave.Image = global::KeePass.Properties.Resources.B16x16_FileSave; this.m_tbFileSave.ImageTransparentColor = System.Drawing.Color.Magenta; this.m_tbFileSave.Name = "m_tbFileSave"; this.m_tbFileSave.Size = new System.Drawing.Size(23, 22); this.m_tbFileSave.Click += new System.EventHandler(this.OnFileSave); // // m_tbFileSep0 // this.m_tbFileSep0.Name = "m_tbFileSep0"; this.m_tbFileSep0.Size = new System.Drawing.Size(6, 25); // // m_tbEditCut // this.m_tbEditCut.DisplayStyle = System.Windows.Forms.ToolStripItemDisplayStyle.Image; this.m_tbEditCut.Image = global::KeePass.Properties.Resources.B16x16_Cut; this.m_tbEditCut.ImageTransparentColor = System.Drawing.Color.Magenta; this.m_tbEditCut.Name = "m_tbEditCut"; this.m_tbEditCut.Size = new System.Drawing.Size(23, 22); this.m_tbEditCut.Click += new System.EventHandler(this.OnEditCut); // // m_tbEditCopy // this.m_tbEditCopy.DisplayStyle = System.Windows.Forms.ToolStripItemDisplayStyle.Image; this.m_tbEditCopy.Image = global::KeePass.Properties.Resources.B16x16_EditCopy; this.m_tbEditCopy.ImageTransparentColor = System.Drawing.Color.Magenta; this.m_tbEditCopy.Name = "m_tbEditCopy"; this.m_tbEditCopy.Size = new System.Drawing.Size(23, 22); this.m_tbEditCopy.Click += new System.EventHandler(this.OnEditCopy); // // m_tbEditPaste // this.m_tbEditPaste.DisplayStyle = System.Windows.Forms.ToolStripItemDisplayStyle.Image; this.m_tbEditPaste.Image = global::KeePass.Properties.Resources.B16x16_EditPaste; this.m_tbEditPaste.ImageTransparentColor = System.Drawing.Color.Magenta; this.m_tbEditPaste.Name = "m_tbEditPaste"; this.m_tbEditPaste.Size = new System.Drawing.Size(23, 22); this.m_tbEditPaste.Click += new System.EventHandler(this.OnEditPaste); // // m_tbFileSep1 // this.m_tbFileSep1.Name = "m_tbFileSep1"; this.m_tbFileSep1.Size = new System.Drawing.Size(6, 25); // // m_tbEditUndo // this.m_tbEditUndo.DisplayStyle = System.Windows.Forms.ToolStripItemDisplayStyle.Image; this.m_tbEditUndo.Image = global::KeePass.Properties.Resources.B16x16_Undo; this.m_tbEditUndo.ImageTransparentColor = System.Drawing.Color.Magenta; this.m_tbEditUndo.Name = "m_tbEditUndo"; this.m_tbEditUndo.RightToLeftAutoMirrorImage = true; this.m_tbEditUndo.Size = new System.Drawing.Size(23, 22); this.m_tbEditUndo.Click += new System.EventHandler(this.OnEditUndo); // // m_tbEditRedo // this.m_tbEditRedo.DisplayStyle = System.Windows.Forms.ToolStripItemDisplayStyle.Image; this.m_tbEditRedo.Image = global::KeePass.Properties.Resources.B16x16_Redo; this.m_tbEditRedo.ImageTransparentColor = System.Drawing.Color.Magenta; this.m_tbEditRedo.Name = "m_tbEditRedo"; this.m_tbEditRedo.RightToLeftAutoMirrorImage = true; this.m_tbEditRedo.Size = new System.Drawing.Size(23, 22); this.m_tbEditRedo.Click += new System.EventHandler(this.OnEditRedo); // // m_tbFileSep2 // this.m_tbFileSep2.Name = "m_tbFileSep2"; this.m_tbFileSep2.Size = new System.Drawing.Size(6, 25); // // m_tbFind // this.m_tbFind.AcceptsReturn = true; this.m_tbFind.Name = "m_tbFind"; this.m_tbFind.Size = new System.Drawing.Size(121, 25); this.m_tbFind.KeyDown += new System.Windows.Forms.KeyEventHandler(this.OnTextFindKeyDown); this.m_tbFind.KeyUp += new System.Windows.Forms.KeyEventHandler(this.OnTextFindKeyUp); // // m_toolFormat // this.m_toolFormat.Items.AddRange(new System.Windows.Forms.ToolStripItem[] { this.m_tbFontCombo, this.m_tbFontSizeCombo, this.m_tbFormatSep0, this.m_tbFormatBold, this.m_tbFormatItalic, this.m_tbFormatUnderline, this.m_tbFormatStrikeout, this.m_tbFormatSep1, this.m_tbColorForeground, this.m_tbColorBackground, this.m_tbFormatSep2, this.m_tbAlignLeft, this.m_tbAlignCenter, this.m_tbAlignRight}); this.m_toolFormat.Location = new System.Drawing.Point(0, 49); this.m_toolFormat.Name = "m_toolFormat"; this.m_toolFormat.Size = new System.Drawing.Size(608, 25); this.m_toolFormat.TabIndex = 3; // // m_tbFontCombo // this.m_tbFontCombo.Name = "m_tbFontCombo"; this.m_tbFontCombo.Size = new System.Drawing.Size(160, 25); this.m_tbFontCombo.SelectedIndexChanged += new System.EventHandler(this.OnFontComboSelectedIndexChanged); this.m_tbFontCombo.KeyDown += new System.Windows.Forms.KeyEventHandler(this.OnFontComboKeyDown); // // m_tbFontSizeCombo // this.m_tbFontSizeCombo.Name = "m_tbFontSizeCombo"; this.m_tbFontSizeCombo.Size = new System.Drawing.Size(75, 25); this.m_tbFontSizeCombo.SelectedIndexChanged += new System.EventHandler(this.OnFontSizeComboSelectedIndexChanged); this.m_tbFontSizeCombo.KeyDown += new System.Windows.Forms.KeyEventHandler(this.OnFontSizeComboKeyDown); // // m_tbFormatSep0 // this.m_tbFormatSep0.Name = "m_tbFormatSep0"; this.m_tbFormatSep0.Size = new System.Drawing.Size(6, 25); // // m_tbFormatBold // this.m_tbFormatBold.DisplayStyle = System.Windows.Forms.ToolStripItemDisplayStyle.Image; this.m_tbFormatBold.Image = global::KeePass.Properties.Resources.B16x16_FontBold; this.m_tbFormatBold.ImageTransparentColor = System.Drawing.Color.Magenta; this.m_tbFormatBold.Name = "m_tbFormatBold"; this.m_tbFormatBold.Size = new System.Drawing.Size(23, 22); this.m_tbFormatBold.Click += new System.EventHandler(this.OnFormatBoldClicked); // // m_tbFormatItalic // this.m_tbFormatItalic.DisplayStyle = System.Windows.Forms.ToolStripItemDisplayStyle.Image; this.m_tbFormatItalic.Image = global::KeePass.Properties.Resources.B16x16_FontItalic; this.m_tbFormatItalic.ImageTransparentColor = System.Drawing.Color.Magenta; this.m_tbFormatItalic.Name = "m_tbFormatItalic"; this.m_tbFormatItalic.Size = new System.Drawing.Size(23, 22); this.m_tbFormatItalic.Click += new System.EventHandler(this.OnFormatItalicClicked); // // m_tbFormatUnderline // this.m_tbFormatUnderline.DisplayStyle = System.Windows.Forms.ToolStripItemDisplayStyle.Image; this.m_tbFormatUnderline.Image = global::KeePass.Properties.Resources.B16x16_FontUnderline; this.m_tbFormatUnderline.ImageTransparentColor = System.Drawing.Color.Magenta; this.m_tbFormatUnderline.Name = "m_tbFormatUnderline"; this.m_tbFormatUnderline.Size = new System.Drawing.Size(23, 22); this.m_tbFormatUnderline.Click += new System.EventHandler(this.OnFormatUnderlineClicked); // // m_tbFormatStrikeout // this.m_tbFormatStrikeout.DisplayStyle = System.Windows.Forms.ToolStripItemDisplayStyle.Image; this.m_tbFormatStrikeout.Image = global::KeePass.Properties.Resources.B16x16_FontStrikeout; this.m_tbFormatStrikeout.ImageTransparentColor = System.Drawing.Color.Magenta; this.m_tbFormatStrikeout.Name = "m_tbFormatStrikeout"; this.m_tbFormatStrikeout.Size = new System.Drawing.Size(23, 22); this.m_tbFormatStrikeout.Click += new System.EventHandler(this.OnFormatStrikeoutClicked); // // m_tbFormatSep1 // this.m_tbFormatSep1.Name = "m_tbFormatSep1"; this.m_tbFormatSep1.Size = new System.Drawing.Size(6, 25); // // m_tbColorForeground // this.m_tbColorForeground.DisplayStyle = System.Windows.Forms.ToolStripItemDisplayStyle.Image; this.m_tbColorForeground.Image = global::KeePass.Properties.Resources.B16x16_Colorize; this.m_tbColorForeground.ImageTransparentColor = System.Drawing.Color.Magenta; this.m_tbColorForeground.Name = "m_tbColorForeground"; this.m_tbColorForeground.Size = new System.Drawing.Size(23, 22); this.m_tbColorForeground.Click += new System.EventHandler(this.OnColorForegroundClicked); // // m_tbColorBackground // this.m_tbColorBackground.DisplayStyle = System.Windows.Forms.ToolStripItemDisplayStyle.Image; this.m_tbColorBackground.Image = global::KeePass.Properties.Resources.B16x16_Color_Fill; this.m_tbColorBackground.ImageTransparentColor = System.Drawing.Color.Magenta; this.m_tbColorBackground.Name = "m_tbColorBackground"; this.m_tbColorBackground.Size = new System.Drawing.Size(23, 22); this.m_tbColorBackground.Click += new System.EventHandler(this.OnColorBackgroundClicked); // // m_tbFormatSep2 // this.m_tbFormatSep2.Name = "m_tbFormatSep2"; this.m_tbFormatSep2.Size = new System.Drawing.Size(6, 25); // // m_tbAlignLeft // this.m_tbAlignLeft.DisplayStyle = System.Windows.Forms.ToolStripItemDisplayStyle.Image; this.m_tbAlignLeft.Image = global::KeePass.Properties.Resources.B16x16_TextAlignLeft; this.m_tbAlignLeft.ImageTransparentColor = System.Drawing.Color.Magenta; this.m_tbAlignLeft.Name = "m_tbAlignLeft"; this.m_tbAlignLeft.Size = new System.Drawing.Size(23, 22); this.m_tbAlignLeft.Click += new System.EventHandler(this.OnAlignLeftClicked); // // m_tbAlignCenter // this.m_tbAlignCenter.DisplayStyle = System.Windows.Forms.ToolStripItemDisplayStyle.Image; this.m_tbAlignCenter.Image = global::KeePass.Properties.Resources.B16x16_TextAlignCenter; this.m_tbAlignCenter.ImageTransparentColor = System.Drawing.Color.Magenta; this.m_tbAlignCenter.Name = "m_tbAlignCenter"; this.m_tbAlignCenter.Size = new System.Drawing.Size(23, 22); this.m_tbAlignCenter.Click += new System.EventHandler(this.OnAlignCenterClicked); // // m_tbAlignRight // this.m_tbAlignRight.DisplayStyle = System.Windows.Forms.ToolStripItemDisplayStyle.Image; this.m_tbAlignRight.Image = global::KeePass.Properties.Resources.B16x16_TextAlignRight; this.m_tbAlignRight.ImageTransparentColor = System.Drawing.Color.Magenta; this.m_tbAlignRight.Name = "m_tbAlignRight"; this.m_tbAlignRight.Size = new System.Drawing.Size(23, 22); this.m_tbAlignRight.Click += new System.EventHandler(this.OnAlignRightClicked); // // m_statusMain // this.m_statusMain.Items.AddRange(new System.Windows.Forms.ToolStripItem[] { this.m_tssStatusMain}); this.m_statusMain.Location = new System.Drawing.Point(0, 394); this.m_statusMain.Name = "m_statusMain"; this.m_statusMain.Size = new System.Drawing.Size(608, 22); this.m_statusMain.TabIndex = 4; // // m_tssStatusMain // this.m_tssStatusMain.Name = "m_tssStatusMain"; this.m_tssStatusMain.Size = new System.Drawing.Size(593, 17); this.m_tssStatusMain.Spring = true; this.m_tssStatusMain.TextAlign = System.Drawing.ContentAlignment.MiddleLeft; // // m_rtbText // this.m_rtbText.AcceptsTab = true; this.m_rtbText.HideSelection = false; this.m_rtbText.Location = new System.Drawing.Point(25, 102); this.m_rtbText.Name = "m_rtbText"; this.m_rtbText.Size = new System.Drawing.Size(100, 96); this.m_rtbText.TabIndex = 0; this.m_rtbText.Text = ""; this.m_rtbText.SelectionChanged += new System.EventHandler(this.OnTextSelectionChanged); this.m_rtbText.LinkClicked += new System.Windows.Forms.LinkClickedEventHandler(this.OnTextLinkClicked); this.m_rtbText.TextChanged += new System.EventHandler(this.OnTextTextChanged); // // DataEditorForm // this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F); this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; this.ClientSize = new System.Drawing.Size(608, 416); this.Controls.Add(this.m_rtbText); this.Controls.Add(this.m_statusMain); this.Controls.Add(this.m_toolFormat); this.Controls.Add(this.m_toolFile); this.Controls.Add(this.m_menuMain); this.MainMenuStrip = this.m_menuMain; this.MinimizeBox = false; this.Name = "DataEditorForm"; this.ShowInTaskbar = false; this.StartPosition = System.Windows.Forms.FormStartPosition.CenterParent; this.Text = "<>"; this.Load += new System.EventHandler(this.OnFormLoad); this.FormClosing += new System.Windows.Forms.FormClosingEventHandler(this.OnFormClosing); this.m_menuMain.ResumeLayout(false); this.m_menuMain.PerformLayout(); this.m_toolFile.ResumeLayout(false); this.m_toolFile.PerformLayout(); this.m_toolFormat.ResumeLayout(false); this.m_toolFormat.PerformLayout(); this.m_statusMain.ResumeLayout(false); this.m_statusMain.PerformLayout(); this.ResumeLayout(false); this.PerformLayout(); } #endregion private KeePass.UI.CustomRichTextBoxEx m_rtbText; private KeePass.UI.CustomMenuStripEx m_menuMain; private System.Windows.Forms.ToolStripMenuItem m_menuFile; private System.Windows.Forms.ToolStripMenuItem m_menuFileSave; private System.Windows.Forms.ToolStripSeparator m_menuFileSep0; private System.Windows.Forms.ToolStripMenuItem m_menuFileExit; private KeePass.UI.CustomToolStripEx m_toolFile; private System.Windows.Forms.ToolStripButton m_tbFileSave; private KeePass.UI.CustomToolStripEx m_toolFormat; private System.Windows.Forms.ToolStripComboBox m_tbFontCombo; private System.Windows.Forms.StatusStrip m_statusMain; private System.Windows.Forms.ToolStripComboBox m_tbFontSizeCombo; private System.Windows.Forms.ToolStripSeparator m_tbFormatSep0; private System.Windows.Forms.ToolStripButton m_tbFormatBold; private System.Windows.Forms.ToolStripButton m_tbFormatItalic; private System.Windows.Forms.ToolStripButton m_tbFormatUnderline; private System.Windows.Forms.ToolStripButton m_tbFormatStrikeout; private System.Windows.Forms.ToolStripButton m_tbColorForeground; private System.Windows.Forms.ToolStripButton m_tbColorBackground; private System.Windows.Forms.ToolStripSeparator m_tbFormatSep1; private System.Windows.Forms.ToolStripSeparator m_tbFormatSep2; private System.Windows.Forms.ToolStripButton m_tbAlignLeft; private System.Windows.Forms.ToolStripButton m_tbAlignCenter; private System.Windows.Forms.ToolStripButton m_tbAlignRight; private System.Windows.Forms.ToolStripSeparator m_tbFileSep0; private System.Windows.Forms.ToolStripButton m_tbEditCut; private System.Windows.Forms.ToolStripButton m_tbEditCopy; private System.Windows.Forms.ToolStripButton m_tbEditPaste; private System.Windows.Forms.ToolStripSeparator m_tbFileSep1; private System.Windows.Forms.ToolStripButton m_tbEditUndo; private System.Windows.Forms.ToolStripButton m_tbEditRedo; private System.Windows.Forms.ToolStripMenuItem m_menuView; private System.Windows.Forms.ToolStripMenuItem m_menuViewFont; private System.Windows.Forms.ToolStripSeparator m_menuViewSep0; private System.Windows.Forms.ToolStripMenuItem m_menuViewWordWrap; private System.Windows.Forms.ToolStripStatusLabel m_tssStatusMain; private System.Windows.Forms.ToolStripSeparator m_tbFileSep2; private System.Windows.Forms.ToolStripTextBox m_tbFind; } }KeePass/Forms/TextEncodingForm.cs0000664000000000000000000000706013222430412015741 0ustar rootroot/* KeePass Password Safe - The Open-Source Password Manager Copyright (C) 2003-2018 Dominik Reichl This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ using System; using System.Collections.Generic; using System.ComponentModel; using System.Diagnostics; using System.Drawing; using System.Text; using System.Windows.Forms; using KeePass.App; using KeePass.Resources; using KeePass.UI; using KeePass.Util; using KeePassLib.Utility; namespace KeePass.Forms { public partial class TextEncodingForm : Form { private string m_strContext = string.Empty; private byte[] m_pbData = null; private bool m_bInitializing = false; private Encoding m_encSel = null; private uint m_uStartOffset = 0; public Encoding SelectedEncoding { get { return m_encSel; } } public uint DataStartOffset { get { return m_uStartOffset; } } public void InitEx(string strContext, byte[] pbData) { m_strContext = (strContext ?? string.Empty); m_pbData = pbData; } public TextEncodingForm() { InitializeComponent(); Program.Translation.ApplyTo(this); } private void OnFormLoad(object sender, EventArgs e) { GlobalWindowManager.AddWindow(this); m_bInitializing = true; this.Icon = AppIcons.Default; FontUtil.AssignDefaultBold(m_lblContext); Debug.Assert(!m_lblContext.AutoSize); // For RTL support m_lblContext.Text = m_strContext; m_cmbEnc.Items.Add(KPRes.BinaryNoConv); foreach(StrEncodingInfo sei in StrUtil.Encodings) m_cmbEnc.Items.Add(sei.Name); StrEncodingInfo seiGuess = BinaryDataClassifier.GetStringEncoding( m_pbData, out m_uStartOffset); int iSel = 0; if(seiGuess != null) iSel = Math.Max(m_cmbEnc.FindStringExact(seiGuess.Name), 0); m_cmbEnc.SelectedIndex = iSel; m_bInitializing = false; UpdateTextPreview(); } private void OnFormClosed(object sender, FormClosedEventArgs e) { GlobalWindowManager.RemoveWindow(this); } private Encoding GetSelEnc() { StrEncodingInfo sei = StrUtil.GetEncoding(m_cmbEnc.Text); return ((sei != null) ? sei.Encoding : null); } private void UpdateTextPreview() { if(m_bInitializing) return; m_rtbPreview.Clear(); // Clear formatting try { Encoding enc = GetSelEnc(); if(enc == null) throw new InvalidOperationException(); string str = (enc.GetString(m_pbData, (int)m_uStartOffset, m_pbData.Length - (int)m_uStartOffset) ?? string.Empty); m_rtbPreview.Text = StrUtil.ReplaceNulls(str); } catch(Exception) { m_rtbPreview.Text = string.Empty; } } private void OnEncSelectedIndexChanged(object sender, EventArgs e) { UpdateTextPreview(); } private void OnBtnOK(object sender, EventArgs e) { m_encSel = GetSelEnc(); } private void OnBtnCancel(object sender, EventArgs e) { } } } KeePass/Forms/UrlOverridesForm.cs0000664000000000000000000001553313222430412015777 0ustar rootroot/* KeePass Password Safe - The Open-Source Password Manager Copyright (C) 2003-2018 Dominik Reichl This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ using System; using System.Collections.Generic; using System.ComponentModel; using System.Diagnostics; using System.Drawing; using System.Text; using System.Windows.Forms; using KeePass.App; using KeePass.App.Configuration; using KeePass.Resources; using KeePass.UI; namespace KeePass.Forms { public partial class UrlOverridesForm : Form { private AceUrlSchemeOverrides m_aceOvr = null; private AceUrlSchemeOverrides m_aceTmp = null; private bool m_bEnfSch = false; private bool m_bEnfAll = false; private string m_strUrlOverrideAll = string.Empty; public string UrlOverrideAll { get { return m_strUrlOverrideAll; } } public void InitEx(AceUrlSchemeOverrides aceOvr, string strOverrideAll) { m_aceOvr = aceOvr; Debug.Assert(strOverrideAll != null); m_strUrlOverrideAll = (strOverrideAll ?? string.Empty); } public UrlOverridesForm() { InitializeComponent(); Program.Translation.ApplyTo(this); } private void OnFormLoad(object sender, EventArgs e) { if(m_aceOvr == null) throw new InvalidOperationException(); m_aceTmp = m_aceOvr.CloneDeep(); GlobalWindowManager.AddWindow(this); this.Icon = AppIcons.Default; this.Text = KPRes.UrlOverrides; UIUtil.SetExplorerTheme(m_lvOverrides, false); int nWidth = m_lvOverrides.ClientSize.Width - UIUtil.GetVScrollBarWidth(); m_lvOverrides.Columns.Add(KPRes.Scheme, nWidth / 4); m_lvOverrides.Columns.Add(KPRes.UrlOverride, (nWidth * 3) / 4); m_bEnfSch = AppConfigEx.IsOptionEnforced(Program.Config.Integration, "UrlSchemeOverrides"); m_bEnfAll = AppConfigEx.IsOptionEnforced(Program.Config.Integration, "UrlOverride"); UpdateOverridesList(false, false); m_cbOverrideAll.Checked = (m_strUrlOverrideAll.Length > 0); m_tbOverrideAll.Text = m_strUrlOverrideAll; EnableControlsEx(); } private void OnFormClosed(object sender, FormClosedEventArgs e) { GlobalWindowManager.RemoveWindow(this); } private void UpdateOverridesList(bool bRestoreView, bool bUpdateState) { UIScrollInfo s = (bRestoreView ? UIUtil.GetScrollInfo( m_lvOverrides, true) : null); m_lvOverrides.BeginUpdate(); m_lvOverrides.Items.Clear(); m_lvOverrides.Groups.Clear(); for(int i = 0; i < 2; ++i) { List l = ((i == 0) ? m_aceTmp.BuiltInOverrides : m_aceTmp.CustomOverrides); ListViewGroup lvg = new ListViewGroup((i == 0) ? KPRes.OverridesBuiltIn : KPRes.OverridesCustom); m_lvOverrides.Groups.Add(lvg); foreach(AceUrlSchemeOverride ovr in l) { ListViewItem lvi = new ListViewItem(ovr.Scheme); lvi.SubItems.Add(ovr.UrlOverride); lvi.Tag = ovr; // Set before setting the Checked property lvi.Checked = ovr.Enabled; m_lvOverrides.Items.Add(lvi); lvg.Items.Add(lvi); } } if(bRestoreView) UIUtil.Scroll(m_lvOverrides, s, false); m_lvOverrides.EndUpdate(); if(bUpdateState) EnableControlsEx(); } private void OnOverridesItemChecked(object sender, ItemCheckedEventArgs e) { AceUrlSchemeOverride ovr = (e.Item.Tag as AceUrlSchemeOverride); if(ovr == null) { Debug.Assert(false); return; } ovr.Enabled = e.Item.Checked; } private void EnableControlsEx() { bool bAll = m_cbOverrideAll.Checked; m_cbOverrideAll.Enabled = !m_bEnfAll; m_tbOverrideAll.Enabled = (!m_bEnfAll && bAll); ListView.SelectedListViewItemCollection lvsc = m_lvOverrides.SelectedItems; bool bOne = (lvsc.Count == 1); bool bAtLeastOne = (lvsc.Count >= 1); bool bBuiltIn = false; foreach(ListViewItem lvi in lvsc) { AceUrlSchemeOverride ovr = (lvi.Tag as AceUrlSchemeOverride); if(ovr == null) { Debug.Assert(false); continue; } if(ovr.IsBuiltIn) { bBuiltIn = true; break; } } bool bSch = !m_bEnfSch; m_lvOverrides.Enabled = bSch; m_btnAdd.Enabled = bSch; m_btnEdit.Enabled = (bSch && bOne && !bBuiltIn); m_btnDelete.Enabled = (bSch && bAtLeastOne && !bBuiltIn); } private void OnOverridesSelectedIndexChanged(object sender, EventArgs e) { EnableControlsEx(); } private void OnBtnAdd(object sender, EventArgs e) { AceUrlSchemeOverride ovr = new AceUrlSchemeOverride(true, string.Empty, string.Empty); UrlOverrideForm dlg = new UrlOverrideForm(); dlg.InitEx(ovr); if(UIUtil.ShowDialogAndDestroy(dlg) == DialogResult.OK) { m_aceTmp.CustomOverrides.Add(ovr); UpdateOverridesList(true, true); // m_lvOverrides.EnsureVisible(m_lvOverrides.Items.Count - 1); } } private void OnBtnEdit(object sender, EventArgs e) { ListView.SelectedListViewItemCollection lvsic = m_lvOverrides.SelectedItems; if((lvsic == null) || (lvsic.Count != 1)) return; AceUrlSchemeOverride ovr = (lvsic[0].Tag as AceUrlSchemeOverride); if(ovr == null) { Debug.Assert(false); return; } if(ovr.IsBuiltIn) { Debug.Assert(false); return; } UrlOverrideForm dlg = new UrlOverrideForm(); dlg.InitEx(ovr); if(UIUtil.ShowDialogAndDestroy(dlg) == DialogResult.OK) UpdateOverridesList(true, true); } private void OnBtnDelete(object sender, EventArgs e) { ListView.SelectedListViewItemCollection lvsic = m_lvOverrides.SelectedItems; if((lvsic == null) || (lvsic.Count == 0)) return; foreach(ListViewItem lvi in lvsic) { AceUrlSchemeOverride ovr = (lvi.Tag as AceUrlSchemeOverride); if(ovr == null) { Debug.Assert(false); continue; } if(ovr.IsBuiltIn) { Debug.Assert(false); continue; } try { m_aceTmp.CustomOverrides.Remove(ovr); } catch(Exception) { Debug.Assert(false); } } UpdateOverridesList(true, true); } private void OnBtnOK(object sender, EventArgs e) { m_aceTmp.CopyTo(m_aceOvr); if(m_cbOverrideAll.Checked) m_strUrlOverrideAll = m_tbOverrideAll.Text; else m_strUrlOverrideAll = string.Empty; } private void OnOverrideAllCheckedChanged(object sender, EventArgs e) { EnableControlsEx(); } } } KeePass/Forms/FileBrowserForm.resx0000664000000000000000000001326612501531110016146 0ustar rootroot text/microsoft-resx 2.0 System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 KeePass/Forms/UrlOverrideForm.resx0000664000000000000000000001326612501532514016176 0ustar rootroot text/microsoft-resx 2.0 System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 KeePass/Forms/DatabaseOperationsForm.resx0000664000000000000000000001326612775452624017524 0ustar rootroot text/microsoft-resx 2.0 System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 KeePass/Forms/GroupForm.cs0000664000000000000000000001723513222430410014445 0ustar rootroot/* KeePass Password Safe - The Open-Source Password Manager Copyright (C) 2003-2018 Dominik Reichl This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ using System; using System.Collections.Generic; using System.ComponentModel; using System.Diagnostics; using System.Drawing; using System.Globalization; using System.Text; using System.Windows.Forms; using KeePass.App; using KeePass.Resources; using KeePass.UI; using KeePassLib; using KeePassLib.Collections; using KeePassLib.Utility; namespace KeePass.Forms { public partial class GroupForm : Form { private PwGroup m_pwGroup = null; private bool m_bCreatingNew = false; private ImageList m_ilClientIcons = null; private PwDatabase m_pwDatabase = null; private PwIcon m_pwIconIndex = 0; private PwUuid m_pwCustomIconID = PwUuid.Zero; private StringDictionaryEx m_sdCustomData = null; private ExpiryControlGroup m_cgExpiry = new ExpiryControlGroup(); [Obsolete] public void InitEx(PwGroup pg, ImageList ilClientIcons, PwDatabase pwDatabase) { InitEx(pg, false, ilClientIcons, pwDatabase); } public void InitEx(PwGroup pg, bool bCreatingNew, ImageList ilClientIcons, PwDatabase pwDatabase) { m_pwGroup = pg; m_bCreatingNew = bCreatingNew; m_ilClientIcons = ilClientIcons; m_pwDatabase = pwDatabase; } public GroupForm() { InitializeComponent(); Program.Translation.ApplyTo(this); } private void OnFormLoad(object sender, EventArgs e) { Debug.Assert(m_pwGroup != null); if(m_pwGroup == null) throw new InvalidOperationException(); Debug.Assert(m_pwDatabase != null); if(m_pwDatabase == null) throw new InvalidOperationException(); GlobalWindowManager.AddWindow(this); string strTitle = (m_bCreatingNew ? KPRes.AddGroup : KPRes.EditGroup); BannerFactory.CreateBannerEx(this, m_bannerImage, Properties.Resources.B48x48_Folder_Txt, strTitle, (m_bCreatingNew ? KPRes.AddGroupDesc : KPRes.EditGroupDesc)); this.Icon = AppIcons.Default; this.Text = strTitle; UIUtil.SetButtonImage(m_btnAutoTypeEdit, Properties.Resources.B16x16_Wizard, true); m_pwIconIndex = m_pwGroup.IconId; m_pwCustomIconID = m_pwGroup.CustomIconUuid; m_tbName.Text = m_pwGroup.Name; UIUtil.SetMultilineText(m_tbNotes, m_pwGroup.Notes); if(!m_pwCustomIconID.Equals(PwUuid.Zero)) UIUtil.SetButtonImage(m_btnIcon, DpiUtil.GetIcon( m_pwDatabase, m_pwCustomIconID), true); else UIUtil.SetButtonImage(m_btnIcon, m_ilClientIcons.Images[ (int)m_pwIconIndex], true); if(m_pwGroup.Expires) { m_dtExpires.Value = TimeUtil.ToLocal(m_pwGroup.ExpiryTime, true); m_cbExpires.Checked = true; } else // Does not expire { m_dtExpires.Value = DateTime.Now.Date; m_cbExpires.Checked = false; } m_cgExpiry.Attach(m_cbExpires, m_dtExpires); PwGroup pgParent = m_pwGroup.ParentGroup; bool bParentAutoType = ((pgParent != null) ? pgParent.GetAutoTypeEnabledInherited() : PwGroup.DefaultAutoTypeEnabled); UIUtil.MakeInheritableBoolComboBox(m_cmbEnableAutoType, m_pwGroup.EnableAutoType, bParentAutoType); bool bParentSearching = ((pgParent != null) ? pgParent.GetSearchingEnabledInherited() : PwGroup.DefaultSearchingEnabled); UIUtil.MakeInheritableBoolComboBox(m_cmbEnableSearching, m_pwGroup.EnableSearching, bParentSearching); m_tbDefaultAutoTypeSeq.Text = m_pwGroup.GetAutoTypeSequenceInherited(); if(m_pwGroup.DefaultAutoTypeSequence.Length == 0) m_rbAutoTypeInherit.Checked = true; else m_rbAutoTypeOverride.Checked = true; m_sdCustomData = m_pwGroup.CustomData.CloneDeep(); UIUtil.StrDictListInit(m_lvCustomData); UIUtil.StrDictListUpdate(m_lvCustomData, m_sdCustomData); CustomizeForScreenReader(); EnableControlsEx(); UIUtil.SetFocus(m_tbName, this); } private void CustomizeForScreenReader() { if(!Program.Config.UI.OptimizeForScreenReader) return; m_btnIcon.Text = KPRes.PickIcon; m_btnAutoTypeEdit.Text = KPRes.ConfigureAutoType; } private void EnableControlsEx() { m_tbDefaultAutoTypeSeq.Enabled = m_btnAutoTypeEdit.Enabled = !m_rbAutoTypeInherit.Checked; m_btnCDDel.Enabled = (m_lvCustomData.SelectedItems.Count > 0); } private void OnBtnOK(object sender, EventArgs e) { m_pwGroup.Touch(true, false); m_pwGroup.Name = m_tbName.Text; m_pwGroup.Notes = m_tbNotes.Text; m_pwGroup.IconId = m_pwIconIndex; m_pwGroup.CustomIconUuid = m_pwCustomIconID; m_pwGroup.Expires = m_cgExpiry.Checked; m_pwGroup.ExpiryTime = m_cgExpiry.Value; m_pwGroup.EnableAutoType = UIUtil.GetInheritableBoolComboBoxValue(m_cmbEnableAutoType); m_pwGroup.EnableSearching = UIUtil.GetInheritableBoolComboBoxValue(m_cmbEnableSearching); if(m_rbAutoTypeInherit.Checked) m_pwGroup.DefaultAutoTypeSequence = string.Empty; else m_pwGroup.DefaultAutoTypeSequence = m_tbDefaultAutoTypeSeq.Text; m_pwGroup.CustomData = m_sdCustomData; } private void OnBtnCancel(object sender, EventArgs e) { } private void CleanUpEx() { m_cgExpiry.Release(); } private void OnBtnIcon(object sender, EventArgs e) { IconPickerForm ipf = new IconPickerForm(); ipf.InitEx(m_ilClientIcons, (uint)PwIcon.Count, m_pwDatabase, (uint)m_pwIconIndex, m_pwCustomIconID); if(ipf.ShowDialog() == DialogResult.OK) { if(!ipf.ChosenCustomIconUuid.Equals(PwUuid.Zero)) // Custom icon { m_pwCustomIconID = ipf.ChosenCustomIconUuid; UIUtil.SetButtonImage(m_btnIcon, DpiUtil.GetIcon( m_pwDatabase, m_pwCustomIconID), true); } else // Standard icon { m_pwIconIndex = (PwIcon)ipf.ChosenIconId; m_pwCustomIconID = PwUuid.Zero; UIUtil.SetButtonImage(m_btnIcon, m_ilClientIcons.Images[ (int)m_pwIconIndex], true); } } UIUtil.DestroyForm(ipf); } private void OnAutoTypeInheritCheckedChanged(object sender, EventArgs e) { EnableControlsEx(); } private void OnBtnAutoTypeEdit(object sender, EventArgs e) { // string strName = @"(" + KPRes.AutoType + @")"; AutoTypeConfig atConfig = new AutoTypeConfig(); atConfig.DefaultSequence = m_tbDefaultAutoTypeSeq.Text; EditAutoTypeItemForm dlg = new EditAutoTypeItemForm(); dlg.InitEx(atConfig, -1, true, atConfig.DefaultSequence, null); if(dlg.ShowDialog() == DialogResult.OK) m_tbDefaultAutoTypeSeq.Text = atConfig.DefaultSequence; UIUtil.DestroyForm(dlg); EnableControlsEx(); } private void OnFormClosed(object sender, FormClosedEventArgs e) { CleanUpEx(); GlobalWindowManager.RemoveWindow(this); } private void OnCustomDataSelectedIndexChanged(object sender, EventArgs e) { EnableControlsEx(); } private void OnBtnCDDel(object sender, EventArgs e) { UIUtil.StrDictListDeleteSel(m_lvCustomData, m_sdCustomData); UIUtil.SetFocus(m_lvCustomData, this); EnableControlsEx(); } } } KeePass/Forms/EditStringForm.Designer.cs0000664000000000000000000002103012563316156017171 0ustar rootrootnamespace KeePass.Forms { partial class EditStringForm { /// /// Erforderliche Designervariable. /// private System.ComponentModel.IContainer components = null; /// /// Verwendete Ressourcen bereinigen. /// /// True, wenn verwaltete Ressourcen gelöscht werden sollen; andernfalls False. protected override void Dispose(bool disposing) { if(disposing && (components != null)) { components.Dispose(); } base.Dispose(disposing); } #region Vom Windows Form-Designer generierter Code /// /// Erforderliche Methode für die Designerunterstützung. /// Der Inhalt der Methode darf nicht mit dem Code-Editor geändert werden. /// private void InitializeComponent() { System.ComponentModel.ComponentResourceManager resources = new System.ComponentModel.ComponentResourceManager(typeof(EditStringForm)); this.m_bannerImage = new System.Windows.Forms.PictureBox(); this.m_lblStringValueDesc = new System.Windows.Forms.Label(); this.m_lblStringIdDesc = new System.Windows.Forms.Label(); this.m_lblIDIntro = new System.Windows.Forms.Label(); this.m_richStringValue = new KeePass.UI.CustomRichTextBoxEx(); this.m_lblSeparator = new System.Windows.Forms.Label(); this.m_btnOK = new System.Windows.Forms.Button(); this.m_btnCancel = new System.Windows.Forms.Button(); this.m_btnHelp = new System.Windows.Forms.Button(); this.m_cbProtect = new System.Windows.Forms.CheckBox(); this.m_lblValidationInfo = new System.Windows.Forms.Label(); this.m_cmbStringName = new System.Windows.Forms.ComboBox(); ((System.ComponentModel.ISupportInitialize)(this.m_bannerImage)).BeginInit(); this.SuspendLayout(); // // m_bannerImage // this.m_bannerImage.Dock = System.Windows.Forms.DockStyle.Top; this.m_bannerImage.Location = new System.Drawing.Point(0, 0); this.m_bannerImage.Name = "m_bannerImage"; this.m_bannerImage.Size = new System.Drawing.Size(409, 60); this.m_bannerImage.TabIndex = 0; this.m_bannerImage.TabStop = false; // // m_lblStringValueDesc // this.m_lblStringValueDesc.AutoSize = true; this.m_lblStringValueDesc.Location = new System.Drawing.Point(12, 156); this.m_lblStringValueDesc.Name = "m_lblStringValueDesc"; this.m_lblStringValueDesc.Size = new System.Drawing.Size(37, 13); this.m_lblStringValueDesc.TabIndex = 2; this.m_lblStringValueDesc.Text = "Value:"; // // m_lblStringIdDesc // this.m_lblStringIdDesc.AutoSize = true; this.m_lblStringIdDesc.Location = new System.Drawing.Point(12, 116); this.m_lblStringIdDesc.Name = "m_lblStringIdDesc"; this.m_lblStringIdDesc.Size = new System.Drawing.Size(38, 13); this.m_lblStringIdDesc.TabIndex = 10; this.m_lblStringIdDesc.Text = "Name:"; // // m_lblIDIntro // this.m_lblIDIntro.Location = new System.Drawing.Point(12, 67); this.m_lblIDIntro.Name = "m_lblIDIntro"; this.m_lblIDIntro.Size = new System.Drawing.Size(385, 40); this.m_lblIDIntro.TabIndex = 9; this.m_lblIDIntro.Text = resources.GetString("m_lblIDIntro.Text"); // // m_richStringValue // this.m_richStringValue.Location = new System.Drawing.Point(56, 154); this.m_richStringValue.Name = "m_richStringValue"; this.m_richStringValue.ScrollBars = System.Windows.Forms.RichTextBoxScrollBars.Vertical; this.m_richStringValue.Size = new System.Drawing.Size(341, 78); this.m_richStringValue.TabIndex = 3; this.m_richStringValue.Text = ""; // // m_lblSeparator // this.m_lblSeparator.BorderStyle = System.Windows.Forms.BorderStyle.Fixed3D; this.m_lblSeparator.Location = new System.Drawing.Point(0, 271); this.m_lblSeparator.Name = "m_lblSeparator"; this.m_lblSeparator.Size = new System.Drawing.Size(409, 2); this.m_lblSeparator.TabIndex = 5; // // m_btnOK // this.m_btnOK.DialogResult = System.Windows.Forms.DialogResult.OK; this.m_btnOK.Location = new System.Drawing.Point(241, 282); this.m_btnOK.Name = "m_btnOK"; this.m_btnOK.Size = new System.Drawing.Size(75, 23); this.m_btnOK.TabIndex = 6; this.m_btnOK.Text = "OK"; this.m_btnOK.UseVisualStyleBackColor = true; this.m_btnOK.Click += new System.EventHandler(this.OnBtnOK); // // m_btnCancel // this.m_btnCancel.DialogResult = System.Windows.Forms.DialogResult.Cancel; this.m_btnCancel.Location = new System.Drawing.Point(322, 282); this.m_btnCancel.Name = "m_btnCancel"; this.m_btnCancel.Size = new System.Drawing.Size(75, 23); this.m_btnCancel.TabIndex = 7; this.m_btnCancel.Text = "Cancel"; this.m_btnCancel.UseVisualStyleBackColor = true; this.m_btnCancel.Click += new System.EventHandler(this.OnBtnCancel); // // m_btnHelp // this.m_btnHelp.Location = new System.Drawing.Point(12, 282); this.m_btnHelp.Name = "m_btnHelp"; this.m_btnHelp.Size = new System.Drawing.Size(75, 23); this.m_btnHelp.TabIndex = 8; this.m_btnHelp.Text = "&Help"; this.m_btnHelp.UseVisualStyleBackColor = true; this.m_btnHelp.Click += new System.EventHandler(this.OnBtnHelp); // // m_cbProtect // this.m_cbProtect.AutoSize = true; this.m_cbProtect.Location = new System.Drawing.Point(56, 238); this.m_cbProtect.Name = "m_cbProtect"; this.m_cbProtect.Size = new System.Drawing.Size(159, 17); this.m_cbProtect.TabIndex = 4; this.m_cbProtect.Text = "Enable in-memory &protection"; this.m_cbProtect.UseVisualStyleBackColor = true; // // m_lblValidationInfo // this.m_lblValidationInfo.ForeColor = System.Drawing.Color.Crimson; this.m_lblValidationInfo.Location = new System.Drawing.Point(53, 137); this.m_lblValidationInfo.Name = "m_lblValidationInfo"; this.m_lblValidationInfo.Size = new System.Drawing.Size(344, 14); this.m_lblValidationInfo.TabIndex = 1; this.m_lblValidationInfo.Text = "<>"; // // m_cmbStringName // this.m_cmbStringName.FormattingEnabled = true; this.m_cmbStringName.Location = new System.Drawing.Point(56, 113); this.m_cmbStringName.Name = "m_cmbStringName"; this.m_cmbStringName.Size = new System.Drawing.Size(341, 21); this.m_cmbStringName.TabIndex = 0; this.m_cmbStringName.TextChanged += new System.EventHandler(this.OnNameTextChanged); // // EditStringForm // this.AcceptButton = this.m_btnOK; this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F); this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; this.CancelButton = this.m_btnCancel; this.ClientSize = new System.Drawing.Size(409, 317); this.Controls.Add(this.m_cmbStringName); this.Controls.Add(this.m_lblValidationInfo); this.Controls.Add(this.m_cbProtect); this.Controls.Add(this.m_btnHelp); this.Controls.Add(this.m_btnCancel); this.Controls.Add(this.m_btnOK); this.Controls.Add(this.m_lblSeparator); this.Controls.Add(this.m_richStringValue); this.Controls.Add(this.m_lblIDIntro); this.Controls.Add(this.m_lblStringIdDesc); this.Controls.Add(this.m_lblStringValueDesc); this.Controls.Add(this.m_bannerImage); this.FormBorderStyle = System.Windows.Forms.FormBorderStyle.FixedDialog; this.MaximizeBox = false; this.MinimizeBox = false; this.Name = "EditStringForm"; this.ShowInTaskbar = false; this.StartPosition = System.Windows.Forms.FormStartPosition.CenterParent; this.Text = "Edit Entry String"; this.Load += new System.EventHandler(this.OnFormLoad); this.FormClosed += new System.Windows.Forms.FormClosedEventHandler(this.OnFormClosed); this.FormClosing += new System.Windows.Forms.FormClosingEventHandler(this.OnFormClosing); ((System.ComponentModel.ISupportInitialize)(this.m_bannerImage)).EndInit(); this.ResumeLayout(false); this.PerformLayout(); } #endregion private System.Windows.Forms.PictureBox m_bannerImage; private System.Windows.Forms.Label m_lblStringValueDesc; private System.Windows.Forms.Label m_lblStringIdDesc; private System.Windows.Forms.Label m_lblIDIntro; private KeePass.UI.CustomRichTextBoxEx m_richStringValue; private System.Windows.Forms.Label m_lblSeparator; private System.Windows.Forms.Button m_btnOK; private System.Windows.Forms.Button m_btnCancel; private System.Windows.Forms.Button m_btnHelp; private System.Windows.Forms.CheckBox m_cbProtect; private System.Windows.Forms.Label m_lblValidationInfo; private System.Windows.Forms.ComboBox m_cmbStringName; } }KeePass/Forms/MainForm.Designer.cs0000664000000000000000000036223013151565314016007 0ustar rootrootnamespace KeePass.Forms { partial class MainForm { /// /// Erforderliche Designervariable. /// private System.ComponentModel.IContainer components = null; /// /// Verwendete Ressourcen bereinigen. /// /// True, wenn verwaltete Ressourcen gelöscht werden sollen; andernfalls False. protected override void Dispose(bool disposing) { if(disposing && (components != null)) { components.Dispose(); } base.Dispose(disposing); } #region Vom Windows Form-Designer generierter Code /// /// Erforderliche Methode für die Designerunterstützung. /// Der Inhalt der Methode darf nicht mit dem Code-Editor geändert werden. /// private void InitializeComponent() { this.components = new System.ComponentModel.Container(); this.m_ctxGroupList = new KeePass.UI.CustomContextMenuStripEx(this.components); this.m_ctxGroupAdd = new System.Windows.Forms.ToolStripMenuItem(); this.m_ctxGroupSep0 = new System.Windows.Forms.ToolStripSeparator(); this.m_ctxGroupEdit = new System.Windows.Forms.ToolStripMenuItem(); this.m_ctxGroupDuplicate = new System.Windows.Forms.ToolStripMenuItem(); this.m_ctxGroupDelete = new System.Windows.Forms.ToolStripMenuItem(); this.m_ctxGroupEmpty = new System.Windows.Forms.ToolStripMenuItem(); this.m_ctxGroupSep1 = new System.Windows.Forms.ToolStripSeparator(); this.m_ctxGroupFind = new System.Windows.Forms.ToolStripMenuItem(); this.m_ctxGroupSep2 = new System.Windows.Forms.ToolStripSeparator(); this.m_ctxGroupPrint = new System.Windows.Forms.ToolStripMenuItem(); this.m_ctxGroupExport = new System.Windows.Forms.ToolStripMenuItem(); this.m_ctxGroupSep3 = new System.Windows.Forms.ToolStripSeparator(); this.m_ctxGroupRearrange = new System.Windows.Forms.ToolStripMenuItem(); this.m_ctxGroupMoveToTop = new System.Windows.Forms.ToolStripMenuItem(); this.m_ctxGroupMoveOneUp = new System.Windows.Forms.ToolStripMenuItem(); this.m_ctxGroupMoveOneDown = new System.Windows.Forms.ToolStripMenuItem(); this.m_ctxGroupMoveToBottom = new System.Windows.Forms.ToolStripMenuItem(); this.m_ctxGroupRearrSep0 = new System.Windows.Forms.ToolStripSeparator(); this.m_ctxGroupSort = new System.Windows.Forms.ToolStripMenuItem(); this.m_ctxGroupSortRec = new System.Windows.Forms.ToolStripMenuItem(); this.m_ctxGroupRearrSep1 = new System.Windows.Forms.ToolStripSeparator(); this.m_ctxGroupExpand = new System.Windows.Forms.ToolStripMenuItem(); this.m_ctxGroupCollapse = new System.Windows.Forms.ToolStripMenuItem(); this.m_ctxPwList = new KeePass.UI.CustomContextMenuStripEx(this.components); this.m_ctxEntryCopyUserName = new System.Windows.Forms.ToolStripMenuItem(); this.m_ctxEntryCopyPassword = new System.Windows.Forms.ToolStripMenuItem(); this.m_ctxEntryUrl = new System.Windows.Forms.ToolStripMenuItem(); this.m_ctxEntryOpenUrl = new System.Windows.Forms.ToolStripMenuItem(); this.m_ctxEntryCopyUrl = new System.Windows.Forms.ToolStripMenuItem(); this.m_ctxEntryUrlSep0 = new System.Windows.Forms.ToolStripSeparator(); this.m_ctxEntryUrlOpenInInternal = new System.Windows.Forms.ToolStripMenuItem(); this.m_ctxEntryCopyString = new System.Windows.Forms.ToolStripMenuItem(); this.m_ctxEntryAttachments = new System.Windows.Forms.ToolStripMenuItem(); this.m_ctxEntrySaveAttachedFiles = new System.Windows.Forms.ToolStripMenuItem(); this.m_ctxEntrySep0 = new System.Windows.Forms.ToolStripSeparator(); this.m_ctxEntryPerformAutoType = new System.Windows.Forms.ToolStripMenuItem(); this.m_ctxEntryAutoTypeAdv = new System.Windows.Forms.ToolStripMenuItem(); this.m_ctxEntrySep1 = new System.Windows.Forms.ToolStripSeparator(); this.m_ctxEntryAdd = new System.Windows.Forms.ToolStripMenuItem(); this.m_ctxEntryEdit = new System.Windows.Forms.ToolStripMenuItem(); this.m_ctxEntryDuplicate = new System.Windows.Forms.ToolStripMenuItem(); this.m_ctxEntryDelete = new System.Windows.Forms.ToolStripMenuItem(); this.m_ctxEntryMassModify = new System.Windows.Forms.ToolStripMenuItem(); this.m_ctxEntrySetColor = new System.Windows.Forms.ToolStripMenuItem(); this.m_ctxEntryColorStandard = new System.Windows.Forms.ToolStripMenuItem(); this.m_ctxEntryColorSep0 = new System.Windows.Forms.ToolStripSeparator(); this.m_ctxEntryColorLightRed = new System.Windows.Forms.ToolStripMenuItem(); this.m_ctxEntryColorLightGreen = new System.Windows.Forms.ToolStripMenuItem(); this.m_ctxEntryColorLightBlue = new System.Windows.Forms.ToolStripMenuItem(); this.m_ctxEntryColorLightYellow = new System.Windows.Forms.ToolStripMenuItem(); this.m_ctxEntryColorSep1 = new System.Windows.Forms.ToolStripSeparator(); this.m_ctxEntryColorCustom = new System.Windows.Forms.ToolStripMenuItem(); this.m_ctxEntryMassSetIcon = new System.Windows.Forms.ToolStripMenuItem(); this.m_ctxEntrySelectedSep0 = new System.Windows.Forms.ToolStripSeparator(); this.m_ctxEntrySelectedAddTag = new System.Windows.Forms.ToolStripMenuItem(); this.m_ctxEntrySelectedNewTag = new System.Windows.Forms.ToolStripMenuItem(); this.m_ctxEntrySelectedRemoveTag = new System.Windows.Forms.ToolStripMenuItem(); this.m_ctxEntrySelectedSep1 = new System.Windows.Forms.ToolStripSeparator(); this.m_ctxEntrySelectedPrint = new System.Windows.Forms.ToolStripMenuItem(); this.m_ctxEntrySelectedExport = new System.Windows.Forms.ToolStripMenuItem(); this.m_ctxEntrySelectedSep2 = new System.Windows.Forms.ToolStripSeparator(); this.m_ctxEntryMoveToGroup = new System.Windows.Forms.ToolStripMenuItem(); this.m_ctxEntryShowParentGroup = new System.Windows.Forms.ToolStripMenuItem(); this.m_ctxEntrySelectAll = new System.Windows.Forms.ToolStripMenuItem(); this.m_ctxEntrySep2 = new System.Windows.Forms.ToolStripSeparator(); this.m_ctxEntryClipboard = new System.Windows.Forms.ToolStripMenuItem(); this.m_ctxEntryClipCopy = new System.Windows.Forms.ToolStripMenuItem(); this.m_ctxEntryClipPaste = new System.Windows.Forms.ToolStripMenuItem(); this.m_ctxEntryRearrangePopup = new System.Windows.Forms.ToolStripMenuItem(); this.m_ctxEntryMoveToTop = new System.Windows.Forms.ToolStripMenuItem(); this.m_ctxEntryMoveOneUp = new System.Windows.Forms.ToolStripMenuItem(); this.m_ctxEntryMoveOneDown = new System.Windows.Forms.ToolStripMenuItem(); this.m_ctxEntryMoveToBottom = new System.Windows.Forms.ToolStripMenuItem(); this.m_menuMain = new KeePass.UI.CustomMenuStripEx(); this.m_menuFile = new System.Windows.Forms.ToolStripMenuItem(); this.m_menuFileNew = new System.Windows.Forms.ToolStripMenuItem(); this.m_menuFileOpen = new System.Windows.Forms.ToolStripMenuItem(); this.m_menuFileOpenLocal = new System.Windows.Forms.ToolStripMenuItem(); this.m_menuFileOpenUrl = new System.Windows.Forms.ToolStripMenuItem(); this.m_menuFileRecent = new System.Windows.Forms.ToolStripMenuItem(); this.m_menuFileRecentDummy = new System.Windows.Forms.ToolStripMenuItem(); this.m_menuFileClose = new System.Windows.Forms.ToolStripMenuItem(); this.m_menuFileSep0 = new System.Windows.Forms.ToolStripSeparator(); this.m_menuFileSave = new System.Windows.Forms.ToolStripMenuItem(); this.m_menuFileSaveAs = new System.Windows.Forms.ToolStripMenuItem(); this.m_menuFileSaveAsLocal = new System.Windows.Forms.ToolStripMenuItem(); this.m_menuFileSaveAsUrl = new System.Windows.Forms.ToolStripMenuItem(); this.m_menuFileSaveAsSep0 = new System.Windows.Forms.ToolStripSeparator(); this.m_menuFileSaveAsCopy = new System.Windows.Forms.ToolStripMenuItem(); this.m_menuFileSep1 = new System.Windows.Forms.ToolStripSeparator(); this.m_menuFileDbSettings = new System.Windows.Forms.ToolStripMenuItem(); this.m_menuFileChangeMasterKey = new System.Windows.Forms.ToolStripMenuItem(); this.m_menuFileSep2 = new System.Windows.Forms.ToolStripSeparator(); this.m_menuFilePrint = new System.Windows.Forms.ToolStripMenuItem(); this.m_menuFileSep3 = new System.Windows.Forms.ToolStripSeparator(); this.m_menuFileImport = new System.Windows.Forms.ToolStripMenuItem(); this.m_menuFileExport = new System.Windows.Forms.ToolStripMenuItem(); this.m_menuFileSync = new System.Windows.Forms.ToolStripMenuItem(); this.m_menuFileSyncFile = new System.Windows.Forms.ToolStripMenuItem(); this.m_menuFileSyncUrl = new System.Windows.Forms.ToolStripMenuItem(); this.m_menuFileSyncSep0 = new System.Windows.Forms.ToolStripSeparator(); this.m_menuFileSyncRecent = new System.Windows.Forms.ToolStripMenuItem(); this.m_menuFileSyncRecentDummy = new System.Windows.Forms.ToolStripMenuItem(); this.m_menuFileSep4 = new System.Windows.Forms.ToolStripSeparator(); this.m_menuFileLock = new System.Windows.Forms.ToolStripMenuItem(); this.m_menuFileExit = new System.Windows.Forms.ToolStripMenuItem(); this.m_menuEdit = new System.Windows.Forms.ToolStripMenuItem(); this.m_menuEditShowEntries = new System.Windows.Forms.ToolStripMenuItem(); this.m_menuEditShowAll = new System.Windows.Forms.ToolStripMenuItem(); this.m_menuEditShowParentGroup = new System.Windows.Forms.ToolStripMenuItem(); this.m_menuEditShowSep0 = new System.Windows.Forms.ToolStripSeparator(); this.m_menuEditShowExp = new System.Windows.Forms.ToolStripMenuItem(); this.m_menuEditShowExp1 = new System.Windows.Forms.ToolStripMenuItem(); this.m_menuEditShowExp2 = new System.Windows.Forms.ToolStripMenuItem(); this.m_menuEditShowExp3 = new System.Windows.Forms.ToolStripMenuItem(); this.m_menuEditShowExp7 = new System.Windows.Forms.ToolStripMenuItem(); this.m_menuEditShowExp14 = new System.Windows.Forms.ToolStripMenuItem(); this.m_menuEditShowExp28 = new System.Windows.Forms.ToolStripMenuItem(); this.m_menuEditShowExp56 = new System.Windows.Forms.ToolStripMenuItem(); this.m_menuEditShowExpInF = new System.Windows.Forms.ToolStripMenuItem(); this.m_menuEditShowSep1 = new System.Windows.Forms.ToolStripSeparator(); this.m_menuEditFindDupPasswords = new System.Windows.Forms.ToolStripMenuItem(); this.m_menuEditFindSimPasswordsP = new System.Windows.Forms.ToolStripMenuItem(); this.m_menuEditFindSimPasswordsC = new System.Windows.Forms.ToolStripMenuItem(); this.m_menuEditPwQualityReport = new System.Windows.Forms.ToolStripMenuItem(); this.m_menuEditShowByTag = new System.Windows.Forms.ToolStripMenuItem(); this.m_menuEditSep0 = new System.Windows.Forms.ToolStripSeparator(); this.m_menuEditFind = new System.Windows.Forms.ToolStripMenuItem(); this.m_menuView = new System.Windows.Forms.ToolStripMenuItem(); this.m_menuChangeLanguage = new System.Windows.Forms.ToolStripMenuItem(); this.m_menuViewSep0 = new System.Windows.Forms.ToolStripSeparator(); this.m_menuViewShowToolBar = new System.Windows.Forms.ToolStripMenuItem(); this.m_menuViewShowEntryView = new System.Windows.Forms.ToolStripMenuItem(); this.m_menuViewWindowLayout = new System.Windows.Forms.ToolStripMenuItem(); this.m_menuViewWindowsStacked = new System.Windows.Forms.ToolStripMenuItem(); this.m_menuViewWindowsSideBySide = new System.Windows.Forms.ToolStripMenuItem(); this.m_menuViewSep1 = new System.Windows.Forms.ToolStripSeparator(); this.m_menuViewAlwaysOnTop = new System.Windows.Forms.ToolStripMenuItem(); this.m_menuViewSep2 = new System.Windows.Forms.ToolStripSeparator(); this.m_menuViewConfigColumns = new System.Windows.Forms.ToolStripMenuItem(); this.m_menuViewSortBy = new System.Windows.Forms.ToolStripMenuItem(); this.m_menuViewTanOptions = new System.Windows.Forms.ToolStripMenuItem(); this.m_menuViewTanSimpleList = new System.Windows.Forms.ToolStripMenuItem(); this.m_menuViewTanIndices = new System.Windows.Forms.ToolStripMenuItem(); this.m_menuViewEntryListGrouping = new System.Windows.Forms.ToolStripMenuItem(); this.m_menuViewSep3 = new System.Windows.Forms.ToolStripSeparator(); this.m_menuViewShowEntriesOfSubGroups = new System.Windows.Forms.ToolStripMenuItem(); this.m_menuTools = new System.Windows.Forms.ToolStripMenuItem(); this.m_menuToolsPwGenerator = new System.Windows.Forms.ToolStripMenuItem(); this.m_menuToolsGeneratePwList = new System.Windows.Forms.ToolStripMenuItem(); this.m_menuToolsSep0 = new System.Windows.Forms.ToolStripSeparator(); this.m_menuToolsTanWizard = new System.Windows.Forms.ToolStripMenuItem(); this.m_menuToolsDb = new System.Windows.Forms.ToolStripMenuItem(); this.m_menuToolsDbMaintenance = new System.Windows.Forms.ToolStripMenuItem(); this.m_menuToolsDbSep0 = new System.Windows.Forms.ToolStripSeparator(); this.m_menuToolsDbDelDupEntries = new System.Windows.Forms.ToolStripMenuItem(); this.m_menuToolsDbDelEmptyGroups = new System.Windows.Forms.ToolStripMenuItem(); this.m_menuToolsDbDelUnusedIcons = new System.Windows.Forms.ToolStripMenuItem(); this.m_menuToolsDbSep1 = new System.Windows.Forms.ToolStripSeparator(); this.m_menuToolsDbXmlRep = new System.Windows.Forms.ToolStripMenuItem(); this.m_menuToolsDbSep2 = new System.Windows.Forms.ToolStripSeparator(); this.m_menuToolsPrintEmSheet = new System.Windows.Forms.ToolStripMenuItem(); this.m_menuToolsSep1 = new System.Windows.Forms.ToolStripSeparator(); this.m_menuToolsTriggers = new System.Windows.Forms.ToolStripMenuItem(); this.m_menuToolsPlugins = new System.Windows.Forms.ToolStripMenuItem(); this.m_menuToolsSep2 = new System.Windows.Forms.ToolStripSeparator(); this.m_menuToolsOptions = new System.Windows.Forms.ToolStripMenuItem(); this.m_menuHelp = new System.Windows.Forms.ToolStripMenuItem(); this.m_menuHelpContents = new System.Windows.Forms.ToolStripMenuItem(); this.m_menuHelpSelectSource = new System.Windows.Forms.ToolStripMenuItem(); this.m_menuHelpSep0 = new System.Windows.Forms.ToolStripSeparator(); this.m_menuHelpWebsite = new System.Windows.Forms.ToolStripMenuItem(); this.m_menuHelpDonate = new System.Windows.Forms.ToolStripMenuItem(); this.m_menuHelpSep1 = new System.Windows.Forms.ToolStripSeparator(); this.m_menuHelpCheckForUpdates = new System.Windows.Forms.ToolStripMenuItem(); this.m_menuHelpSep2 = new System.Windows.Forms.ToolStripSeparator(); this.m_menuHelpAbout = new System.Windows.Forms.ToolStripMenuItem(); this.m_toolMain = new KeePass.UI.CustomToolStripEx(); this.m_tbNewDatabase = new System.Windows.Forms.ToolStripButton(); this.m_tbOpenDatabase = new System.Windows.Forms.ToolStripButton(); this.m_tbSaveDatabase = new System.Windows.Forms.ToolStripButton(); this.m_tbSaveAll = new System.Windows.Forms.ToolStripButton(); this.m_tbSep0 = new System.Windows.Forms.ToolStripSeparator(); this.m_tbAddEntry = new System.Windows.Forms.ToolStripSplitButton(); this.m_tbAddEntryDefault = new System.Windows.Forms.ToolStripMenuItem(); this.m_tbSep1 = new System.Windows.Forms.ToolStripSeparator(); this.m_tbCopyUserName = new System.Windows.Forms.ToolStripButton(); this.m_tbCopyPassword = new System.Windows.Forms.ToolStripButton(); this.m_tbOpenUrl = new System.Windows.Forms.ToolStripSplitButton(); this.m_tbOpenUrlDefault = new System.Windows.Forms.ToolStripMenuItem(); this.m_tbCopyUrl = new System.Windows.Forms.ToolStripButton(); this.m_tbAutoType = new System.Windows.Forms.ToolStripButton(); this.m_tbSep4 = new System.Windows.Forms.ToolStripSeparator(); this.m_tbFind = new System.Windows.Forms.ToolStripButton(); this.m_tbEntryViewsDropDown = new System.Windows.Forms.ToolStripDropDownButton(); this.m_tbViewsShowAll = new System.Windows.Forms.ToolStripMenuItem(); this.m_tbViewsShowExpired = new System.Windows.Forms.ToolStripMenuItem(); this.m_tbSep2 = new System.Windows.Forms.ToolStripSeparator(); this.m_tbLockWorkspace = new System.Windows.Forms.ToolStripButton(); this.m_tbSep3 = new System.Windows.Forms.ToolStripSeparator(); this.m_tbQuickFind = new System.Windows.Forms.ToolStripComboBox(); this.m_tbCloseTab = new System.Windows.Forms.ToolStripButton(); this.m_statusMain = new System.Windows.Forms.StatusStrip(); this.m_statusPartSelected = new System.Windows.Forms.ToolStripStatusLabel(); this.m_statusPartInfo = new System.Windows.Forms.ToolStripStatusLabel(); this.m_statusPartProgress = new System.Windows.Forms.ToolStripProgressBar(); this.m_statusClipboard = new System.Windows.Forms.ToolStripProgressBar(); this.m_ctxTray = new KeePass.UI.CustomContextMenuStripEx(this.components); this.m_ctxTrayTray = new System.Windows.Forms.ToolStripMenuItem(); this.m_ctxTraySep0 = new System.Windows.Forms.ToolStripSeparator(); this.m_ctxTrayGenPw = new System.Windows.Forms.ToolStripMenuItem(); this.m_ctxTraySep1 = new System.Windows.Forms.ToolStripSeparator(); this.m_ctxTrayOptions = new System.Windows.Forms.ToolStripMenuItem(); this.m_ctxTraySep2 = new System.Windows.Forms.ToolStripSeparator(); this.m_ctxTrayLock = new System.Windows.Forms.ToolStripMenuItem(); this.m_ctxTrayFileExit = new System.Windows.Forms.ToolStripMenuItem(); this.m_timerMain = new System.Windows.Forms.Timer(this.components); this.m_tabMain = new System.Windows.Forms.TabControl(); this.m_splitHorizontal = new KeePass.UI.CustomSplitContainerEx(); this.m_splitVertical = new KeePass.UI.CustomSplitContainerEx(); this.m_tvGroups = new KeePass.UI.CustomTreeViewEx(); this.m_lvEntries = new KeePass.UI.CustomListViewEx(); this.m_richEntryView = new KeePass.UI.CustomRichTextBoxEx(); this.m_ctxGroupList.SuspendLayout(); this.m_ctxPwList.SuspendLayout(); this.m_menuMain.SuspendLayout(); this.m_toolMain.SuspendLayout(); this.m_statusMain.SuspendLayout(); this.m_ctxTray.SuspendLayout(); this.m_splitHorizontal.Panel1.SuspendLayout(); this.m_splitHorizontal.Panel2.SuspendLayout(); this.m_splitHorizontal.SuspendLayout(); this.m_splitVertical.Panel1.SuspendLayout(); this.m_splitVertical.Panel2.SuspendLayout(); this.m_splitVertical.SuspendLayout(); this.SuspendLayout(); // // m_ctxGroupList // this.m_ctxGroupList.Items.AddRange(new System.Windows.Forms.ToolStripItem[] { this.m_ctxGroupAdd, this.m_ctxGroupSep0, this.m_ctxGroupEdit, this.m_ctxGroupDuplicate, this.m_ctxGroupDelete, this.m_ctxGroupEmpty, this.m_ctxGroupSep1, this.m_ctxGroupFind, this.m_ctxGroupSep2, this.m_ctxGroupPrint, this.m_ctxGroupExport, this.m_ctxGroupSep3, this.m_ctxGroupRearrange}); this.m_ctxGroupList.Name = "m_ctxGroupList"; this.m_ctxGroupList.Size = new System.Drawing.Size(178, 226); this.m_ctxGroupList.Opening += new System.ComponentModel.CancelEventHandler(this.OnCtxGroupListOpening); // // m_ctxGroupAdd // this.m_ctxGroupAdd.Image = global::KeePass.Properties.Resources.B16x16_Folder_New_Ex; this.m_ctxGroupAdd.Name = "m_ctxGroupAdd"; this.m_ctxGroupAdd.Size = new System.Drawing.Size(177, 22); this.m_ctxGroupAdd.Text = "Add &Group..."; this.m_ctxGroupAdd.Click += new System.EventHandler(this.OnGroupsAdd); // // m_ctxGroupSep0 // this.m_ctxGroupSep0.Name = "m_ctxGroupSep0"; this.m_ctxGroupSep0.Size = new System.Drawing.Size(174, 6); // // m_ctxGroupEdit // this.m_ctxGroupEdit.Image = global::KeePass.Properties.Resources.B16x16_Folder_Txt; this.m_ctxGroupEdit.Name = "m_ctxGroupEdit"; this.m_ctxGroupEdit.Size = new System.Drawing.Size(177, 22); this.m_ctxGroupEdit.Text = "Ed&it Group..."; this.m_ctxGroupEdit.Click += new System.EventHandler(this.OnGroupsEdit); // // m_ctxGroupDuplicate // this.m_ctxGroupDuplicate.Image = global::KeePass.Properties.Resources.B16x16_Folder_2; this.m_ctxGroupDuplicate.Name = "m_ctxGroupDuplicate"; this.m_ctxGroupDuplicate.Size = new System.Drawing.Size(177, 22); this.m_ctxGroupDuplicate.Text = "Dupli&cate Group"; this.m_ctxGroupDuplicate.Click += new System.EventHandler(this.OnGroupsDuplicate); // // m_ctxGroupDelete // this.m_ctxGroupDelete.Image = global::KeePass.Properties.Resources.B16x16_Folder_Locked; this.m_ctxGroupDelete.Name = "m_ctxGroupDelete"; this.m_ctxGroupDelete.Size = new System.Drawing.Size(177, 22); this.m_ctxGroupDelete.Text = "Dele&te Group"; this.m_ctxGroupDelete.Click += new System.EventHandler(this.OnGroupsDelete); // // m_ctxGroupEmpty // this.m_ctxGroupEmpty.Image = global::KeePass.Properties.Resources.B16x16_Trashcan_Full; this.m_ctxGroupEmpty.Name = "m_ctxGroupEmpty"; this.m_ctxGroupEmpty.Size = new System.Drawing.Size(177, 22); this.m_ctxGroupEmpty.Text = "Empty Recycle &Bin"; this.m_ctxGroupEmpty.Click += new System.EventHandler(this.OnGroupsEmpty); // // m_ctxGroupSep1 // this.m_ctxGroupSep1.Name = "m_ctxGroupSep1"; this.m_ctxGroupSep1.Size = new System.Drawing.Size(174, 6); // // m_ctxGroupFind // this.m_ctxGroupFind.Image = global::KeePass.Properties.Resources.B16x16_XMag; this.m_ctxGroupFind.Name = "m_ctxGroupFind"; this.m_ctxGroupFind.Size = new System.Drawing.Size(177, 22); this.m_ctxGroupFind.Text = "&Find in this Group..."; this.m_ctxGroupFind.Click += new System.EventHandler(this.OnGroupsFind); // // m_ctxGroupSep2 // this.m_ctxGroupSep2.Name = "m_ctxGroupSep2"; this.m_ctxGroupSep2.Size = new System.Drawing.Size(174, 6); // // m_ctxGroupPrint // this.m_ctxGroupPrint.Image = global::KeePass.Properties.Resources.B16x16_FilePrint; this.m_ctxGroupPrint.Name = "m_ctxGroupPrint"; this.m_ctxGroupPrint.Size = new System.Drawing.Size(177, 22); this.m_ctxGroupPrint.Text = "&Print Group..."; this.m_ctxGroupPrint.Click += new System.EventHandler(this.OnGroupsPrint); // // m_ctxGroupExport // this.m_ctxGroupExport.Image = global::KeePass.Properties.Resources.B16x16_Folder_Outbox; this.m_ctxGroupExport.Name = "m_ctxGroupExport"; this.m_ctxGroupExport.Size = new System.Drawing.Size(177, 22); this.m_ctxGroupExport.Text = "&Export..."; this.m_ctxGroupExport.Click += new System.EventHandler(this.OnGroupsExport); // // m_ctxGroupSep3 // this.m_ctxGroupSep3.Name = "m_ctxGroupSep3"; this.m_ctxGroupSep3.Size = new System.Drawing.Size(174, 6); // // m_ctxGroupRearrange // this.m_ctxGroupRearrange.DropDownItems.AddRange(new System.Windows.Forms.ToolStripItem[] { this.m_ctxGroupMoveToTop, this.m_ctxGroupMoveOneUp, this.m_ctxGroupMoveOneDown, this.m_ctxGroupMoveToBottom, this.m_ctxGroupRearrSep0, this.m_ctxGroupSort, this.m_ctxGroupSortRec, this.m_ctxGroupRearrSep1, this.m_ctxGroupExpand, this.m_ctxGroupCollapse}); this.m_ctxGroupRearrange.Name = "m_ctxGroupRearrange"; this.m_ctxGroupRearrange.Size = new System.Drawing.Size(177, 22); this.m_ctxGroupRearrange.Text = "&Rearrange"; // // m_ctxGroupMoveToTop // this.m_ctxGroupMoveToTop.Image = global::KeePass.Properties.Resources.B16x16_2UpArrow; this.m_ctxGroupMoveToTop.Name = "m_ctxGroupMoveToTop"; this.m_ctxGroupMoveToTop.Size = new System.Drawing.Size(199, 22); this.m_ctxGroupMoveToTop.Text = "Move Group to &Top"; this.m_ctxGroupMoveToTop.Click += new System.EventHandler(this.OnGroupsMoveToTop); // // m_ctxGroupMoveOneUp // this.m_ctxGroupMoveOneUp.Image = global::KeePass.Properties.Resources.B16x16_1UpArrow; this.m_ctxGroupMoveOneUp.Name = "m_ctxGroupMoveOneUp"; this.m_ctxGroupMoveOneUp.Size = new System.Drawing.Size(199, 22); this.m_ctxGroupMoveOneUp.Text = "Move Group One &Up"; this.m_ctxGroupMoveOneUp.Click += new System.EventHandler(this.OnGroupsMoveOneUp); // // m_ctxGroupMoveOneDown // this.m_ctxGroupMoveOneDown.Image = global::KeePass.Properties.Resources.B16x16_1DownArrow; this.m_ctxGroupMoveOneDown.Name = "m_ctxGroupMoveOneDown"; this.m_ctxGroupMoveOneDown.Size = new System.Drawing.Size(199, 22); this.m_ctxGroupMoveOneDown.Text = "Move Group One &Down"; this.m_ctxGroupMoveOneDown.Click += new System.EventHandler(this.OnGroupsMoveOneDown); // // m_ctxGroupMoveToBottom // this.m_ctxGroupMoveToBottom.Image = global::KeePass.Properties.Resources.B16x16_2DownArrow; this.m_ctxGroupMoveToBottom.Name = "m_ctxGroupMoveToBottom"; this.m_ctxGroupMoveToBottom.Size = new System.Drawing.Size(199, 22); this.m_ctxGroupMoveToBottom.Text = "Move Group to &Bottom"; this.m_ctxGroupMoveToBottom.Click += new System.EventHandler(this.OnGroupsMoveToBottom); // // m_ctxGroupRearrSep0 // this.m_ctxGroupRearrSep0.Name = "m_ctxGroupRearrSep0"; this.m_ctxGroupRearrSep0.Size = new System.Drawing.Size(196, 6); // // m_ctxGroupSort // this.m_ctxGroupSort.Image = global::KeePass.Properties.Resources.B16x16_KaboodleLoop; this.m_ctxGroupSort.Name = "m_ctxGroupSort"; this.m_ctxGroupSort.RightToLeftAutoMirrorImage = true; this.m_ctxGroupSort.Size = new System.Drawing.Size(199, 22); this.m_ctxGroupSort.Text = "&Sort Direct Subgroups"; this.m_ctxGroupSort.Click += new System.EventHandler(this.OnGroupsSort); // // m_ctxGroupSortRec // this.m_ctxGroupSortRec.Image = global::KeePass.Properties.Resources.B16x16_KaboodleLoop; this.m_ctxGroupSortRec.Name = "m_ctxGroupSortRec"; this.m_ctxGroupSortRec.RightToLeftAutoMirrorImage = true; this.m_ctxGroupSortRec.Size = new System.Drawing.Size(199, 22); this.m_ctxGroupSortRec.Text = "Sort &Recursively"; this.m_ctxGroupSortRec.Click += new System.EventHandler(this.OnGroupsSortRec); // // m_ctxGroupRearrSep1 // this.m_ctxGroupRearrSep1.Name = "m_ctxGroupRearrSep1"; this.m_ctxGroupRearrSep1.Size = new System.Drawing.Size(196, 6); // // m_ctxGroupExpand // this.m_ctxGroupExpand.Image = global::KeePass.Properties.Resources.B16x16_Folder_Blue_Open; this.m_ctxGroupExpand.Name = "m_ctxGroupExpand"; this.m_ctxGroupExpand.Size = new System.Drawing.Size(199, 22); this.m_ctxGroupExpand.Text = "&Expand Recursively"; this.m_ctxGroupExpand.Click += new System.EventHandler(this.OnGroupsExpand); // // m_ctxGroupCollapse // this.m_ctxGroupCollapse.Image = global::KeePass.Properties.Resources.B16x16_Folder; this.m_ctxGroupCollapse.Name = "m_ctxGroupCollapse"; this.m_ctxGroupCollapse.Size = new System.Drawing.Size(199, 22); this.m_ctxGroupCollapse.Text = "&Collapse Recursively"; this.m_ctxGroupCollapse.Click += new System.EventHandler(this.OnGroupsCollapse); // // m_ctxPwList // this.m_ctxPwList.Items.AddRange(new System.Windows.Forms.ToolStripItem[] { this.m_ctxEntryCopyUserName, this.m_ctxEntryCopyPassword, this.m_ctxEntryUrl, this.m_ctxEntryCopyString, this.m_ctxEntryAttachments, this.m_ctxEntrySaveAttachedFiles, this.m_ctxEntrySep0, this.m_ctxEntryPerformAutoType, this.m_ctxEntryAutoTypeAdv, this.m_ctxEntrySep1, this.m_ctxEntryAdd, this.m_ctxEntryEdit, this.m_ctxEntryDuplicate, this.m_ctxEntryDelete, this.m_ctxEntryMassModify, this.m_ctxEntrySelectAll, this.m_ctxEntrySep2, this.m_ctxEntryClipboard, this.m_ctxEntryRearrangePopup}); this.m_ctxPwList.Name = "m_ctxPwList"; this.m_ctxPwList.Size = new System.Drawing.Size(209, 374); this.m_ctxPwList.Opening += new System.ComponentModel.CancelEventHandler(this.OnCtxPwListOpening); // // m_ctxEntryCopyUserName // this.m_ctxEntryCopyUserName.Image = global::KeePass.Properties.Resources.B16x16_Personal; this.m_ctxEntryCopyUserName.Name = "m_ctxEntryCopyUserName"; this.m_ctxEntryCopyUserName.Size = new System.Drawing.Size(208, 22); this.m_ctxEntryCopyUserName.Text = "Copy User &Name"; this.m_ctxEntryCopyUserName.Click += new System.EventHandler(this.OnEntryCopyUserName); // // m_ctxEntryCopyPassword // this.m_ctxEntryCopyPassword.Image = global::KeePass.Properties.Resources.B16x16_KGPG_Info; this.m_ctxEntryCopyPassword.Name = "m_ctxEntryCopyPassword"; this.m_ctxEntryCopyPassword.Size = new System.Drawing.Size(208, 22); this.m_ctxEntryCopyPassword.Text = ""; this.m_ctxEntryCopyPassword.Click += new System.EventHandler(this.OnEntryCopyPassword); // // m_ctxEntryUrl // this.m_ctxEntryUrl.DropDownItems.AddRange(new System.Windows.Forms.ToolStripItem[] { this.m_ctxEntryOpenUrl, this.m_ctxEntryCopyUrl, this.m_ctxEntryUrlSep0, this.m_ctxEntryUrlOpenInInternal}); this.m_ctxEntryUrl.Name = "m_ctxEntryUrl"; this.m_ctxEntryUrl.Size = new System.Drawing.Size(208, 22); this.m_ctxEntryUrl.Text = "&URL(s)"; // // m_ctxEntryOpenUrl // this.m_ctxEntryOpenUrl.Image = global::KeePass.Properties.Resources.B16x16_FTP; this.m_ctxEntryOpenUrl.Name = "m_ctxEntryOpenUrl"; this.m_ctxEntryOpenUrl.Size = new System.Drawing.Size(204, 22); this.m_ctxEntryOpenUrl.Text = "<>"; this.m_ctxEntryOpenUrl.Click += new System.EventHandler(this.OnEntryOpenUrl); // // m_ctxEntryCopyUrl // this.m_ctxEntryCopyUrl.Image = global::KeePass.Properties.Resources.B16x16_EditCopyUrl; this.m_ctxEntryCopyUrl.Name = "m_ctxEntryCopyUrl"; this.m_ctxEntryCopyUrl.Size = new System.Drawing.Size(204, 22); this.m_ctxEntryCopyUrl.Text = "&Copy to Clipboard"; this.m_ctxEntryCopyUrl.Click += new System.EventHandler(this.OnEntryCopyURL); // // m_ctxEntryUrlSep0 // this.m_ctxEntryUrlSep0.Name = "m_ctxEntryUrlSep0"; this.m_ctxEntryUrlSep0.Size = new System.Drawing.Size(201, 6); this.m_ctxEntryUrlSep0.Visible = false; // // m_ctxEntryUrlOpenInInternal // this.m_ctxEntryUrlOpenInInternal.Image = global::KeePass.Properties.Resources.B16x16_Browser; this.m_ctxEntryUrlOpenInInternal.Name = "m_ctxEntryUrlOpenInInternal"; this.m_ctxEntryUrlOpenInInternal.Size = new System.Drawing.Size(204, 22); this.m_ctxEntryUrlOpenInInternal.Text = "Open in Internal Browser"; this.m_ctxEntryUrlOpenInInternal.Visible = false; this.m_ctxEntryUrlOpenInInternal.Click += new System.EventHandler(this.OnEntryUrlOpenInInternal); // // m_ctxEntryCopyString // this.m_ctxEntryCopyString.Name = "m_ctxEntryCopyString"; this.m_ctxEntryCopyString.Size = new System.Drawing.Size(208, 22); this.m_ctxEntryCopyString.Text = "Copy &String"; // // m_ctxEntryAttachments // this.m_ctxEntryAttachments.Name = "m_ctxEntryAttachments"; this.m_ctxEntryAttachments.Size = new System.Drawing.Size(208, 22); this.m_ctxEntryAttachments.Text = "Attach&ments"; // // m_ctxEntrySaveAttachedFiles // this.m_ctxEntrySaveAttachedFiles.Image = global::KeePass.Properties.Resources.B16x16_Attach; this.m_ctxEntrySaveAttachedFiles.Name = "m_ctxEntrySaveAttachedFiles"; this.m_ctxEntrySaveAttachedFiles.Size = new System.Drawing.Size(208, 22); this.m_ctxEntrySaveAttachedFiles.Text = "Save Attached &File(s) To..."; this.m_ctxEntrySaveAttachedFiles.Click += new System.EventHandler(this.OnEntrySaveAttachments); // // m_ctxEntrySep0 // this.m_ctxEntrySep0.Name = "m_ctxEntrySep0"; this.m_ctxEntrySep0.Size = new System.Drawing.Size(205, 6); // // m_ctxEntryPerformAutoType // this.m_ctxEntryPerformAutoType.Image = global::KeePass.Properties.Resources.B16x16_KTouch; this.m_ctxEntryPerformAutoType.Name = "m_ctxEntryPerformAutoType"; this.m_ctxEntryPerformAutoType.Size = new System.Drawing.Size(208, 22); this.m_ctxEntryPerformAutoType.Text = "Perform Auto-&Type"; this.m_ctxEntryPerformAutoType.Click += new System.EventHandler(this.OnEntryPerformAutoType); // // m_ctxEntryAutoTypeAdv // this.m_ctxEntryAutoTypeAdv.Name = "m_ctxEntryAutoTypeAdv"; this.m_ctxEntryAutoTypeAdv.Size = new System.Drawing.Size(208, 22); this.m_ctxEntryAutoTypeAdv.Text = "Perform Auto-Type"; // // m_ctxEntrySep1 // this.m_ctxEntrySep1.Name = "m_ctxEntrySep1"; this.m_ctxEntrySep1.Size = new System.Drawing.Size(205, 6); // // m_ctxEntryAdd // this.m_ctxEntryAdd.Image = global::KeePass.Properties.Resources.B16x16_KGPG_Import; this.m_ctxEntryAdd.Name = "m_ctxEntryAdd"; this.m_ctxEntryAdd.Size = new System.Drawing.Size(208, 22); this.m_ctxEntryAdd.Text = "&Add Entry..."; this.m_ctxEntryAdd.Click += new System.EventHandler(this.OnEntryAdd); // // m_ctxEntryEdit // this.m_ctxEntryEdit.Image = global::KeePass.Properties.Resources.B16x16_KGPG_Sign; this.m_ctxEntryEdit.Name = "m_ctxEntryEdit"; this.m_ctxEntryEdit.Size = new System.Drawing.Size(208, 22); this.m_ctxEntryEdit.Text = "&Edit/View Entry..."; this.m_ctxEntryEdit.Click += new System.EventHandler(this.OnEntryEdit); // // m_ctxEntryDuplicate // this.m_ctxEntryDuplicate.Image = global::KeePass.Properties.Resources.B16x16_KGPG_Key2; this.m_ctxEntryDuplicate.Name = "m_ctxEntryDuplicate"; this.m_ctxEntryDuplicate.Size = new System.Drawing.Size(208, 22); this.m_ctxEntryDuplicate.Text = "Dupli&cate Entry"; this.m_ctxEntryDuplicate.Click += new System.EventHandler(this.OnEntryDuplicate); // // m_ctxEntryDelete // this.m_ctxEntryDelete.Image = global::KeePass.Properties.Resources.B16x16_DeleteEntry; this.m_ctxEntryDelete.Name = "m_ctxEntryDelete"; this.m_ctxEntryDelete.Size = new System.Drawing.Size(208, 22); this.m_ctxEntryDelete.Text = "&Delete Entry"; this.m_ctxEntryDelete.Click += new System.EventHandler(this.OnEntryDelete); // // m_ctxEntryMassModify // this.m_ctxEntryMassModify.DropDownItems.AddRange(new System.Windows.Forms.ToolStripItem[] { this.m_ctxEntrySetColor, this.m_ctxEntryMassSetIcon, this.m_ctxEntrySelectedSep0, this.m_ctxEntrySelectedAddTag, this.m_ctxEntrySelectedRemoveTag, this.m_ctxEntrySelectedSep1, this.m_ctxEntrySelectedPrint, this.m_ctxEntrySelectedExport, this.m_ctxEntrySelectedSep2, this.m_ctxEntryMoveToGroup, this.m_ctxEntryShowParentGroup}); this.m_ctxEntryMassModify.Name = "m_ctxEntryMassModify"; this.m_ctxEntryMassModify.Size = new System.Drawing.Size(208, 22); this.m_ctxEntryMassModify.Text = "Selected Entr&ies"; // // m_ctxEntrySetColor // this.m_ctxEntrySetColor.DropDownItems.AddRange(new System.Windows.Forms.ToolStripItem[] { this.m_ctxEntryColorStandard, this.m_ctxEntryColorSep0, this.m_ctxEntryColorLightRed, this.m_ctxEntryColorLightGreen, this.m_ctxEntryColorLightBlue, this.m_ctxEntryColorLightYellow, this.m_ctxEntryColorSep1, this.m_ctxEntryColorCustom}); this.m_ctxEntrySetColor.Name = "m_ctxEntrySetColor"; this.m_ctxEntrySetColor.Size = new System.Drawing.Size(176, 22); this.m_ctxEntrySetColor.Text = "Set &Color"; // // m_ctxEntryColorStandard // this.m_ctxEntryColorStandard.Name = "m_ctxEntryColorStandard"; this.m_ctxEntryColorStandard.Size = new System.Drawing.Size(200, 22); this.m_ctxEntryColorStandard.Text = "&Standard"; this.m_ctxEntryColorStandard.Click += new System.EventHandler(this.OnEntryColorStandard); // // m_ctxEntryColorSep0 // this.m_ctxEntryColorSep0.Name = "m_ctxEntryColorSep0"; this.m_ctxEntryColorSep0.Size = new System.Drawing.Size(197, 6); // // m_ctxEntryColorLightRed // this.m_ctxEntryColorLightRed.Name = "m_ctxEntryColorLightRed"; this.m_ctxEntryColorLightRed.Size = new System.Drawing.Size(200, 22); this.m_ctxEntryColorLightRed.Text = "Light &Red"; this.m_ctxEntryColorLightRed.Click += new System.EventHandler(this.OnEntryColorLightRed); // // m_ctxEntryColorLightGreen // this.m_ctxEntryColorLightGreen.Name = "m_ctxEntryColorLightGreen"; this.m_ctxEntryColorLightGreen.Size = new System.Drawing.Size(200, 22); this.m_ctxEntryColorLightGreen.Text = "Light &Green"; this.m_ctxEntryColorLightGreen.Click += new System.EventHandler(this.OnEntryColorLightGreen); // // m_ctxEntryColorLightBlue // this.m_ctxEntryColorLightBlue.Name = "m_ctxEntryColorLightBlue"; this.m_ctxEntryColorLightBlue.Size = new System.Drawing.Size(200, 22); this.m_ctxEntryColorLightBlue.Text = "Light &Blue"; this.m_ctxEntryColorLightBlue.Click += new System.EventHandler(this.OnEntryColorLightBlue); // // m_ctxEntryColorLightYellow // this.m_ctxEntryColorLightYellow.Name = "m_ctxEntryColorLightYellow"; this.m_ctxEntryColorLightYellow.Size = new System.Drawing.Size(200, 22); this.m_ctxEntryColorLightYellow.Text = "Light &Yellow"; this.m_ctxEntryColorLightYellow.Click += new System.EventHandler(this.OnEntryColorLightYellow); // // m_ctxEntryColorSep1 // this.m_ctxEntryColorSep1.Name = "m_ctxEntryColorSep1"; this.m_ctxEntryColorSep1.Size = new System.Drawing.Size(197, 6); // // m_ctxEntryColorCustom // this.m_ctxEntryColorCustom.Name = "m_ctxEntryColorCustom"; this.m_ctxEntryColorCustom.Size = new System.Drawing.Size(200, 22); this.m_ctxEntryColorCustom.Text = "&Choose Custom Color..."; this.m_ctxEntryColorCustom.Click += new System.EventHandler(this.OnEntryColorCustom); // // m_ctxEntryMassSetIcon // this.m_ctxEntryMassSetIcon.Image = global::KeePass.Properties.Resources.B16x16_Spreadsheet; this.m_ctxEntryMassSetIcon.Name = "m_ctxEntryMassSetIcon"; this.m_ctxEntryMassSetIcon.Size = new System.Drawing.Size(176, 22); this.m_ctxEntryMassSetIcon.Text = "Set &Icons..."; this.m_ctxEntryMassSetIcon.Click += new System.EventHandler(this.OnEntryMassSetIcon); // // m_ctxEntrySelectedSep0 // this.m_ctxEntrySelectedSep0.Name = "m_ctxEntrySelectedSep0"; this.m_ctxEntrySelectedSep0.Size = new System.Drawing.Size(173, 6); // // m_ctxEntrySelectedAddTag // this.m_ctxEntrySelectedAddTag.DropDownItems.AddRange(new System.Windows.Forms.ToolStripItem[] { this.m_ctxEntrySelectedNewTag}); this.m_ctxEntrySelectedAddTag.Name = "m_ctxEntrySelectedAddTag"; this.m_ctxEntrySelectedAddTag.Size = new System.Drawing.Size(176, 22); this.m_ctxEntrySelectedAddTag.Text = "Add &Tag"; this.m_ctxEntrySelectedAddTag.DropDownOpening += new System.EventHandler(this.OnEntrySelectedAddTagOpening); // // m_ctxEntrySelectedNewTag // this.m_ctxEntrySelectedNewTag.Image = global::KeePass.Properties.Resources.B16x16_KNotes; this.m_ctxEntrySelectedNewTag.Name = "m_ctxEntrySelectedNewTag"; this.m_ctxEntrySelectedNewTag.Size = new System.Drawing.Size(129, 22); this.m_ctxEntrySelectedNewTag.Text = "&New Tag..."; this.m_ctxEntrySelectedNewTag.Click += new System.EventHandler(this.OnEntrySelectedNewTag); // // m_ctxEntrySelectedRemoveTag // this.m_ctxEntrySelectedRemoveTag.Name = "m_ctxEntrySelectedRemoveTag"; this.m_ctxEntrySelectedRemoveTag.Size = new System.Drawing.Size(176, 22); this.m_ctxEntrySelectedRemoveTag.Text = "&Remove Tag"; this.m_ctxEntrySelectedRemoveTag.DropDownOpening += new System.EventHandler(this.OnEntrySelectedRemoveTagOpening); // // m_ctxEntrySelectedSep1 // this.m_ctxEntrySelectedSep1.Name = "m_ctxEntrySelectedSep1"; this.m_ctxEntrySelectedSep1.Size = new System.Drawing.Size(173, 6); // // m_ctxEntrySelectedPrint // this.m_ctxEntrySelectedPrint.Image = global::KeePass.Properties.Resources.B16x16_FilePrint; this.m_ctxEntrySelectedPrint.Name = "m_ctxEntrySelectedPrint"; this.m_ctxEntrySelectedPrint.Size = new System.Drawing.Size(176, 22); this.m_ctxEntrySelectedPrint.Text = "&Print..."; this.m_ctxEntrySelectedPrint.Click += new System.EventHandler(this.OnEntrySelectedPrint); // // m_ctxEntrySelectedExport // this.m_ctxEntrySelectedExport.Image = global::KeePass.Properties.Resources.B16x16_Folder_Outbox; this.m_ctxEntrySelectedExport.Name = "m_ctxEntrySelectedExport"; this.m_ctxEntrySelectedExport.Size = new System.Drawing.Size(176, 22); this.m_ctxEntrySelectedExport.Text = "&Export..."; this.m_ctxEntrySelectedExport.Click += new System.EventHandler(this.OnEntrySelectedExport); // // m_ctxEntrySelectedSep2 // this.m_ctxEntrySelectedSep2.Name = "m_ctxEntrySelectedSep2"; this.m_ctxEntrySelectedSep2.Size = new System.Drawing.Size(173, 6); // // m_ctxEntryMoveToGroup // this.m_ctxEntryMoveToGroup.Name = "m_ctxEntryMoveToGroup"; this.m_ctxEntryMoveToGroup.Size = new System.Drawing.Size(176, 22); this.m_ctxEntryMoveToGroup.Text = "Move to &Group"; this.m_ctxEntryMoveToGroup.DropDownOpening += new System.EventHandler(this.OnEntryMoveToGroupOpening); // // m_ctxEntryShowParentGroup // this.m_ctxEntryShowParentGroup.Image = global::KeePass.Properties.Resources.B16x16_Folder_Blue_Open; this.m_ctxEntryShowParentGroup.Name = "m_ctxEntryShowParentGroup"; this.m_ctxEntryShowParentGroup.Size = new System.Drawing.Size(176, 22); this.m_ctxEntryShowParentGroup.Text = "&Show Parent Group"; this.m_ctxEntryShowParentGroup.Click += new System.EventHandler(this.OnEditShowParentGroup); // // m_ctxEntrySelectAll // this.m_ctxEntrySelectAll.Name = "m_ctxEntrySelectAll"; this.m_ctxEntrySelectAll.Size = new System.Drawing.Size(208, 22); this.m_ctxEntrySelectAll.Text = "Se&lect All"; this.m_ctxEntrySelectAll.Click += new System.EventHandler(this.OnEntrySelectAll); // // m_ctxEntrySep2 // this.m_ctxEntrySep2.Name = "m_ctxEntrySep2"; this.m_ctxEntrySep2.Size = new System.Drawing.Size(205, 6); // // m_ctxEntryClipboard // this.m_ctxEntryClipboard.DropDownItems.AddRange(new System.Windows.Forms.ToolStripItem[] { this.m_ctxEntryClipCopy, this.m_ctxEntryClipPaste}); this.m_ctxEntryClipboard.Name = "m_ctxEntryClipboard"; this.m_ctxEntryClipboard.Size = new System.Drawing.Size(208, 22); this.m_ctxEntryClipboard.Text = "Clip&board"; this.m_ctxEntryClipboard.DropDownOpening += new System.EventHandler(this.OnCtxEntryClipboardOpening); // // m_ctxEntryClipCopy // this.m_ctxEntryClipCopy.Image = global::KeePass.Properties.Resources.B16x16_EditCopy; this.m_ctxEntryClipCopy.Name = "m_ctxEntryClipCopy"; this.m_ctxEntryClipCopy.Size = new System.Drawing.Size(140, 22); this.m_ctxEntryClipCopy.Text = "&Copy Entries"; this.m_ctxEntryClipCopy.Click += new System.EventHandler(this.OnEntryClipCopy); // // m_ctxEntryClipPaste // this.m_ctxEntryClipPaste.Image = global::KeePass.Properties.Resources.B16x16_EditPaste; this.m_ctxEntryClipPaste.Name = "m_ctxEntryClipPaste"; this.m_ctxEntryClipPaste.Size = new System.Drawing.Size(140, 22); this.m_ctxEntryClipPaste.Text = "&Paste Entries"; this.m_ctxEntryClipPaste.Click += new System.EventHandler(this.OnEntryClipPaste); // // m_ctxEntryRearrangePopup // this.m_ctxEntryRearrangePopup.DropDownItems.AddRange(new System.Windows.Forms.ToolStripItem[] { this.m_ctxEntryMoveToTop, this.m_ctxEntryMoveOneUp, this.m_ctxEntryMoveOneDown, this.m_ctxEntryMoveToBottom}); this.m_ctxEntryRearrangePopup.Name = "m_ctxEntryRearrangePopup"; this.m_ctxEntryRearrangePopup.Size = new System.Drawing.Size(208, 22); this.m_ctxEntryRearrangePopup.Text = "&Rearrange"; // // m_ctxEntryMoveToTop // this.m_ctxEntryMoveToTop.Image = global::KeePass.Properties.Resources.B16x16_2UpArrow; this.m_ctxEntryMoveToTop.Name = "m_ctxEntryMoveToTop"; this.m_ctxEntryMoveToTop.Size = new System.Drawing.Size(193, 22); this.m_ctxEntryMoveToTop.Text = "Move Entry to &Top"; this.m_ctxEntryMoveToTop.Click += new System.EventHandler(this.OnEntryMoveToTop); // // m_ctxEntryMoveOneUp // this.m_ctxEntryMoveOneUp.Image = global::KeePass.Properties.Resources.B16x16_1UpArrow; this.m_ctxEntryMoveOneUp.Name = "m_ctxEntryMoveOneUp"; this.m_ctxEntryMoveOneUp.Size = new System.Drawing.Size(193, 22); this.m_ctxEntryMoveOneUp.Text = "Move Entry One &Up"; this.m_ctxEntryMoveOneUp.Click += new System.EventHandler(this.OnEntryMoveOneUp); // // m_ctxEntryMoveOneDown // this.m_ctxEntryMoveOneDown.Image = global::KeePass.Properties.Resources.B16x16_1DownArrow; this.m_ctxEntryMoveOneDown.Name = "m_ctxEntryMoveOneDown"; this.m_ctxEntryMoveOneDown.Size = new System.Drawing.Size(193, 22); this.m_ctxEntryMoveOneDown.Text = "Move Entry One &Down"; this.m_ctxEntryMoveOneDown.Click += new System.EventHandler(this.OnEntryMoveOneDown); // // m_ctxEntryMoveToBottom // this.m_ctxEntryMoveToBottom.Image = global::KeePass.Properties.Resources.B16x16_2DownArrow; this.m_ctxEntryMoveToBottom.Name = "m_ctxEntryMoveToBottom"; this.m_ctxEntryMoveToBottom.Size = new System.Drawing.Size(193, 22); this.m_ctxEntryMoveToBottom.Text = "Move Entry to &Bottom"; this.m_ctxEntryMoveToBottom.Click += new System.EventHandler(this.OnEntryMoveToBottom); // // m_menuMain // this.m_menuMain.Items.AddRange(new System.Windows.Forms.ToolStripItem[] { this.m_menuFile, this.m_menuEdit, this.m_menuView, this.m_menuTools, this.m_menuHelp}); this.m_menuMain.Location = new System.Drawing.Point(0, 0); this.m_menuMain.Name = "m_menuMain"; this.m_menuMain.Size = new System.Drawing.Size(654, 24); this.m_menuMain.TabIndex = 0; // // m_menuFile // this.m_menuFile.DropDownItems.AddRange(new System.Windows.Forms.ToolStripItem[] { this.m_menuFileNew, this.m_menuFileOpen, this.m_menuFileRecent, this.m_menuFileClose, this.m_menuFileSep0, this.m_menuFileSave, this.m_menuFileSaveAs, this.m_menuFileSep1, this.m_menuFileDbSettings, this.m_menuFileChangeMasterKey, this.m_menuFileSep2, this.m_menuFilePrint, this.m_menuFileSep3, this.m_menuFileImport, this.m_menuFileExport, this.m_menuFileSync, this.m_menuFileSep4, this.m_menuFileLock, this.m_menuFileExit}); this.m_menuFile.Name = "m_menuFile"; this.m_menuFile.Size = new System.Drawing.Size(37, 20); this.m_menuFile.Text = "&File"; // // m_menuFileNew // this.m_menuFileNew.Image = global::KeePass.Properties.Resources.B16x16_FileNew; this.m_menuFileNew.Name = "m_menuFileNew"; this.m_menuFileNew.Size = new System.Drawing.Size(185, 22); this.m_menuFileNew.Text = "&New..."; this.m_menuFileNew.Click += new System.EventHandler(this.OnFileNew); // // m_menuFileOpen // this.m_menuFileOpen.DropDownItems.AddRange(new System.Windows.Forms.ToolStripItem[] { this.m_menuFileOpenLocal, this.m_menuFileOpenUrl}); this.m_menuFileOpen.Name = "m_menuFileOpen"; this.m_menuFileOpen.Size = new System.Drawing.Size(185, 22); this.m_menuFileOpen.Text = "&Open"; // // m_menuFileOpenLocal // this.m_menuFileOpenLocal.Image = global::KeePass.Properties.Resources.B16x16_Folder_Yellow_Open; this.m_menuFileOpenLocal.Name = "m_menuFileOpenLocal"; this.m_menuFileOpenLocal.Size = new System.Drawing.Size(136, 22); this.m_menuFileOpenLocal.Text = "Open &File..."; this.m_menuFileOpenLocal.Click += new System.EventHandler(this.OnFileOpen); // // m_menuFileOpenUrl // this.m_menuFileOpenUrl.Image = global::KeePass.Properties.Resources.B16x16_Browser; this.m_menuFileOpenUrl.Name = "m_menuFileOpenUrl"; this.m_menuFileOpenUrl.Size = new System.Drawing.Size(136, 22); this.m_menuFileOpenUrl.Text = "Open &URL..."; this.m_menuFileOpenUrl.Click += new System.EventHandler(this.OnFileOpenUrl); // // m_menuFileRecent // this.m_menuFileRecent.DropDownItems.AddRange(new System.Windows.Forms.ToolStripItem[] { this.m_menuFileRecentDummy}); this.m_menuFileRecent.Name = "m_menuFileRecent"; this.m_menuFileRecent.Size = new System.Drawing.Size(185, 22); this.m_menuFileRecent.Text = "Open &Recent"; // // m_menuFileRecentDummy // this.m_menuFileRecentDummy.Name = "m_menuFileRecentDummy"; this.m_menuFileRecentDummy.Size = new System.Drawing.Size(90, 22); this.m_menuFileRecentDummy.Text = "<>"; // // m_menuFileClose // this.m_menuFileClose.Image = global::KeePass.Properties.Resources.B16x16_File_Close; this.m_menuFileClose.Name = "m_menuFileClose"; this.m_menuFileClose.Size = new System.Drawing.Size(185, 22); this.m_menuFileClose.Text = "&Close"; this.m_menuFileClose.Click += new System.EventHandler(this.OnFileClose); // // m_menuFileSep0 // this.m_menuFileSep0.Name = "m_menuFileSep0"; this.m_menuFileSep0.Size = new System.Drawing.Size(182, 6); // // m_menuFileSave // this.m_menuFileSave.Image = global::KeePass.Properties.Resources.B16x16_FileSave; this.m_menuFileSave.Name = "m_menuFileSave"; this.m_menuFileSave.Size = new System.Drawing.Size(185, 22); this.m_menuFileSave.Text = "&Save"; this.m_menuFileSave.Click += new System.EventHandler(this.OnFileSave); // // m_menuFileSaveAs // this.m_menuFileSaveAs.DropDownItems.AddRange(new System.Windows.Forms.ToolStripItem[] { this.m_menuFileSaveAsLocal, this.m_menuFileSaveAsUrl, this.m_menuFileSaveAsSep0, this.m_menuFileSaveAsCopy}); this.m_menuFileSaveAs.Name = "m_menuFileSaveAs"; this.m_menuFileSaveAs.Size = new System.Drawing.Size(185, 22); this.m_menuFileSaveAs.Text = "Save &As"; // // m_menuFileSaveAsLocal // this.m_menuFileSaveAsLocal.Image = global::KeePass.Properties.Resources.B16x16_FileSaveAs; this.m_menuFileSaveAsLocal.Name = "m_menuFileSaveAsLocal"; this.m_menuFileSaveAsLocal.Size = new System.Drawing.Size(173, 22); this.m_menuFileSaveAsLocal.Text = "Save to &File..."; this.m_menuFileSaveAsLocal.Click += new System.EventHandler(this.OnFileSaveAs); // // m_menuFileSaveAsUrl // this.m_menuFileSaveAsUrl.Image = global::KeePass.Properties.Resources.B16x16_Browser; this.m_menuFileSaveAsUrl.Name = "m_menuFileSaveAsUrl"; this.m_menuFileSaveAsUrl.Size = new System.Drawing.Size(173, 22); this.m_menuFileSaveAsUrl.Text = "Save to &URL..."; this.m_menuFileSaveAsUrl.Click += new System.EventHandler(this.OnFileSaveAsUrl); // // m_menuFileSaveAsSep0 // this.m_menuFileSaveAsSep0.Name = "m_menuFileSaveAsSep0"; this.m_menuFileSaveAsSep0.Size = new System.Drawing.Size(170, 6); // // m_menuFileSaveAsCopy // this.m_menuFileSaveAsCopy.Image = global::KeePass.Properties.Resources.B16x16_FileSaveAs; this.m_menuFileSaveAsCopy.Name = "m_menuFileSaveAsCopy"; this.m_menuFileSaveAsCopy.Size = new System.Drawing.Size(173, 22); this.m_menuFileSaveAsCopy.Text = "Save &Copy to File..."; this.m_menuFileSaveAsCopy.Click += new System.EventHandler(this.OnFileSaveAsCopy); // // m_menuFileSep1 // this.m_menuFileSep1.Name = "m_menuFileSep1"; this.m_menuFileSep1.Size = new System.Drawing.Size(182, 6); // // m_menuFileDbSettings // this.m_menuFileDbSettings.Image = global::KeePass.Properties.Resources.B16x16_Package_Development; this.m_menuFileDbSettings.Name = "m_menuFileDbSettings"; this.m_menuFileDbSettings.Size = new System.Drawing.Size(185, 22); this.m_menuFileDbSettings.Text = "&Database Settings..."; this.m_menuFileDbSettings.Click += new System.EventHandler(this.OnFileDbSettings); // // m_menuFileChangeMasterKey // this.m_menuFileChangeMasterKey.Image = global::KeePass.Properties.Resources.B16x16_File_Locked; this.m_menuFileChangeMasterKey.Name = "m_menuFileChangeMasterKey"; this.m_menuFileChangeMasterKey.Size = new System.Drawing.Size(185, 22); this.m_menuFileChangeMasterKey.Text = "Change &Master Key..."; this.m_menuFileChangeMasterKey.Click += new System.EventHandler(this.OnFileChangeMasterKey); // // m_menuFileSep2 // this.m_menuFileSep2.Name = "m_menuFileSep2"; this.m_menuFileSep2.Size = new System.Drawing.Size(182, 6); // // m_menuFilePrint // this.m_menuFilePrint.Image = global::KeePass.Properties.Resources.B16x16_FilePrint; this.m_menuFilePrint.Name = "m_menuFilePrint"; this.m_menuFilePrint.Size = new System.Drawing.Size(185, 22); this.m_menuFilePrint.Text = "&Print..."; this.m_menuFilePrint.Click += new System.EventHandler(this.OnFilePrint); // // m_menuFileSep3 // this.m_menuFileSep3.Name = "m_menuFileSep3"; this.m_menuFileSep3.Size = new System.Drawing.Size(182, 6); // // m_menuFileImport // this.m_menuFileImport.Image = global::KeePass.Properties.Resources.B16x16_Folder_Inbox; this.m_menuFileImport.Name = "m_menuFileImport"; this.m_menuFileImport.Size = new System.Drawing.Size(185, 22); this.m_menuFileImport.Text = "&Import..."; this.m_menuFileImport.Click += new System.EventHandler(this.OnFileImport); // // m_menuFileExport // this.m_menuFileExport.Image = global::KeePass.Properties.Resources.B16x16_Folder_Outbox; this.m_menuFileExport.Name = "m_menuFileExport"; this.m_menuFileExport.Size = new System.Drawing.Size(185, 22); this.m_menuFileExport.Text = "&Export..."; this.m_menuFileExport.Click += new System.EventHandler(this.OnFileExport); // // m_menuFileSync // this.m_menuFileSync.DropDownItems.AddRange(new System.Windows.Forms.ToolStripItem[] { this.m_menuFileSyncFile, this.m_menuFileSyncUrl, this.m_menuFileSyncSep0, this.m_menuFileSyncRecent}); this.m_menuFileSync.Name = "m_menuFileSync"; this.m_menuFileSync.Size = new System.Drawing.Size(185, 22); this.m_menuFileSync.Text = "S&ynchronize"; // // m_menuFileSyncFile // this.m_menuFileSyncFile.Image = global::KeePass.Properties.Resources.B16x16_Reload_Page; this.m_menuFileSyncFile.Name = "m_menuFileSyncFile"; this.m_menuFileSyncFile.RightToLeftAutoMirrorImage = true; this.m_menuFileSyncFile.Size = new System.Drawing.Size(197, 22); this.m_menuFileSyncFile.Text = "Synchronize with &File..."; this.m_menuFileSyncFile.Click += new System.EventHandler(this.OnFileSynchronize); // // m_menuFileSyncUrl // this.m_menuFileSyncUrl.Image = global::KeePass.Properties.Resources.B16x16_Reload_Page; this.m_menuFileSyncUrl.Name = "m_menuFileSyncUrl"; this.m_menuFileSyncUrl.RightToLeftAutoMirrorImage = true; this.m_menuFileSyncUrl.Size = new System.Drawing.Size(197, 22); this.m_menuFileSyncUrl.Text = "Synchronize with &URL..."; this.m_menuFileSyncUrl.Click += new System.EventHandler(this.OnFileSynchronizeUrl); // // m_menuFileSyncSep0 // this.m_menuFileSyncSep0.Name = "m_menuFileSyncSep0"; this.m_menuFileSyncSep0.Size = new System.Drawing.Size(194, 6); // // m_menuFileSyncRecent // this.m_menuFileSyncRecent.DropDownItems.AddRange(new System.Windows.Forms.ToolStripItem[] { this.m_menuFileSyncRecentDummy}); this.m_menuFileSyncRecent.Name = "m_menuFileSyncRecent"; this.m_menuFileSyncRecent.Size = new System.Drawing.Size(197, 22); this.m_menuFileSyncRecent.Text = "&Recent Files"; // // m_menuFileSyncRecentDummy // this.m_menuFileSyncRecentDummy.Name = "m_menuFileSyncRecentDummy"; this.m_menuFileSyncRecentDummy.Size = new System.Drawing.Size(90, 22); this.m_menuFileSyncRecentDummy.Text = "<>"; // // m_menuFileSep4 // this.m_menuFileSep4.Name = "m_menuFileSep4"; this.m_menuFileSep4.Size = new System.Drawing.Size(182, 6); // // m_menuFileLock // this.m_menuFileLock.Image = global::KeePass.Properties.Resources.B16x16_LockWorkspace; this.m_menuFileLock.Name = "m_menuFileLock"; this.m_menuFileLock.Size = new System.Drawing.Size(185, 22); this.m_menuFileLock.Text = "&Lock Workspace"; this.m_menuFileLock.Click += new System.EventHandler(this.OnFileLock); // // m_menuFileExit // this.m_menuFileExit.Image = global::KeePass.Properties.Resources.B16x16_Exit; this.m_menuFileExit.Name = "m_menuFileExit"; this.m_menuFileExit.Size = new System.Drawing.Size(185, 22); this.m_menuFileExit.Text = "E&xit"; this.m_menuFileExit.Click += new System.EventHandler(this.OnFileExit); // // m_menuEdit // this.m_menuEdit.DropDownItems.AddRange(new System.Windows.Forms.ToolStripItem[] { this.m_menuEditShowEntries, this.m_menuEditShowByTag, this.m_menuEditSep0, this.m_menuEditFind}); this.m_menuEdit.Name = "m_menuEdit"; this.m_menuEdit.Size = new System.Drawing.Size(39, 20); this.m_menuEdit.Text = "&Edit"; this.m_menuEdit.DropDownOpening += new System.EventHandler(this.OnMenuEditOpening); // // m_menuEditShowEntries // this.m_menuEditShowEntries.DropDownItems.AddRange(new System.Windows.Forms.ToolStripItem[] { this.m_menuEditShowAll, this.m_menuEditShowParentGroup, this.m_menuEditShowSep0, this.m_menuEditShowExp, this.m_menuEditShowExp1, this.m_menuEditShowExp2, this.m_menuEditShowExp3, this.m_menuEditShowExp7, this.m_menuEditShowExp14, this.m_menuEditShowExp28, this.m_menuEditShowExp56, this.m_menuEditShowExpInF, this.m_menuEditShowSep1, this.m_menuEditFindDupPasswords, this.m_menuEditFindSimPasswordsP, this.m_menuEditFindSimPasswordsC, this.m_menuEditPwQualityReport}); this.m_menuEditShowEntries.Name = "m_menuEditShowEntries"; this.m_menuEditShowEntries.Size = new System.Drawing.Size(179, 22); this.m_menuEditShowEntries.Text = "&Show Entries"; // // m_menuEditShowAll // this.m_menuEditShowAll.Image = global::KeePass.Properties.Resources.B16x16_KGPG_Key3; this.m_menuEditShowAll.Name = "m_menuEditShowAll"; this.m_menuEditShowAll.Size = new System.Drawing.Size(256, 22); this.m_menuEditShowAll.Text = "&All"; this.m_menuEditShowAll.Click += new System.EventHandler(this.OnEditShowAll); // // m_menuEditShowParentGroup // this.m_menuEditShowParentGroup.Image = global::KeePass.Properties.Resources.B16x16_Folder_Blue_Open; this.m_menuEditShowParentGroup.Name = "m_menuEditShowParentGroup"; this.m_menuEditShowParentGroup.Size = new System.Drawing.Size(256, 22); this.m_menuEditShowParentGroup.Text = "Selected Entry\'s Group"; this.m_menuEditShowParentGroup.Click += new System.EventHandler(this.OnEditShowParentGroup); // // m_menuEditShowSep0 // this.m_menuEditShowSep0.Name = "m_menuEditShowSep0"; this.m_menuEditShowSep0.Size = new System.Drawing.Size(253, 6); // // m_menuEditShowExp // this.m_menuEditShowExp.Image = global::KeePass.Properties.Resources.B16x16_History_Clear; this.m_menuEditShowExp.Name = "m_menuEditShowExp"; this.m_menuEditShowExp.Size = new System.Drawing.Size(256, 22); this.m_menuEditShowExp.Text = "E&xpired"; this.m_menuEditShowExp.Click += new System.EventHandler(this.OnEditShowExp); // // m_menuEditShowExp1 // this.m_menuEditShowExp1.Image = global::KeePass.Properties.Resources.B16x16_History_Clear; this.m_menuEditShowExp1.Name = "m_menuEditShowExp1"; this.m_menuEditShowExp1.Size = new System.Drawing.Size(256, 22); this.m_menuEditShowExp1.Text = "Expiring in &1 Day"; this.m_menuEditShowExp1.Click += new System.EventHandler(this.OnEditShowExp1); // // m_menuEditShowExp2 // this.m_menuEditShowExp2.Image = global::KeePass.Properties.Resources.B16x16_History_Clear; this.m_menuEditShowExp2.Name = "m_menuEditShowExp2"; this.m_menuEditShowExp2.Size = new System.Drawing.Size(256, 22); this.m_menuEditShowExp2.Text = "Expiring in &2 Days"; this.m_menuEditShowExp2.Click += new System.EventHandler(this.OnEditShowExp2); // // m_menuEditShowExp3 // this.m_menuEditShowExp3.Image = global::KeePass.Properties.Resources.B16x16_History_Clear; this.m_menuEditShowExp3.Name = "m_menuEditShowExp3"; this.m_menuEditShowExp3.Size = new System.Drawing.Size(256, 22); this.m_menuEditShowExp3.Text = "Expiring in &3 Days"; this.m_menuEditShowExp3.Click += new System.EventHandler(this.OnEditShowExp3); // // m_menuEditShowExp7 // this.m_menuEditShowExp7.Image = global::KeePass.Properties.Resources.B16x16_History_Clear; this.m_menuEditShowExp7.Name = "m_menuEditShowExp7"; this.m_menuEditShowExp7.Size = new System.Drawing.Size(256, 22); this.m_menuEditShowExp7.Text = "Expiring in 1 &Week"; this.m_menuEditShowExp7.Click += new System.EventHandler(this.OnEditShowExp7); // // m_menuEditShowExp14 // this.m_menuEditShowExp14.Image = global::KeePass.Properties.Resources.B16x16_History_Clear; this.m_menuEditShowExp14.Name = "m_menuEditShowExp14"; this.m_menuEditShowExp14.Size = new System.Drawing.Size(256, 22); this.m_menuEditShowExp14.Text = "Expiring in 2 W&eeks"; this.m_menuEditShowExp14.Click += new System.EventHandler(this.OnEditShowExp14); // // m_menuEditShowExp28 // this.m_menuEditShowExp28.Image = global::KeePass.Properties.Resources.B16x16_History_Clear; this.m_menuEditShowExp28.Name = "m_menuEditShowExp28"; this.m_menuEditShowExp28.Size = new System.Drawing.Size(256, 22); this.m_menuEditShowExp28.Text = "Expiring in 4 Wee&ks"; this.m_menuEditShowExp28.Click += new System.EventHandler(this.OnEditShowExp28); // // m_menuEditShowExp56 // this.m_menuEditShowExp56.Image = global::KeePass.Properties.Resources.B16x16_History_Clear; this.m_menuEditShowExp56.Name = "m_menuEditShowExp56"; this.m_menuEditShowExp56.Size = new System.Drawing.Size(256, 22); this.m_menuEditShowExp56.Text = "Expiring in 8 Week&s"; this.m_menuEditShowExp56.Click += new System.EventHandler(this.OnEditShowExp56); // // m_menuEditShowExpInF // this.m_menuEditShowExpInF.Image = global::KeePass.Properties.Resources.B16x16_History_Clear; this.m_menuEditShowExpInF.Name = "m_menuEditShowExpInF"; this.m_menuEditShowExpInF.Size = new System.Drawing.Size(256, 22); this.m_menuEditShowExpInF.Text = "Expiring in the &Future"; this.m_menuEditShowExpInF.Click += new System.EventHandler(this.OnEditShowExpInF); // // m_menuEditShowSep1 // this.m_menuEditShowSep1.Name = "m_menuEditShowSep1"; this.m_menuEditShowSep1.Size = new System.Drawing.Size(253, 6); // // m_menuEditFindDupPasswords // this.m_menuEditFindDupPasswords.Image = global::KeePass.Properties.Resources.B16x16_KGPG_Key2; this.m_menuEditFindDupPasswords.Name = "m_menuEditFindDupPasswords"; this.m_menuEditFindDupPasswords.Size = new System.Drawing.Size(256, 22); this.m_menuEditFindDupPasswords.Text = "Find &Duplicate Passwords..."; this.m_menuEditFindDupPasswords.Click += new System.EventHandler(this.OnEditFindDupPasswords); // // m_menuEditFindSimPasswordsP // this.m_menuEditFindSimPasswordsP.Image = global::KeePass.Properties.Resources.B16x16_KGPG_Key2; this.m_menuEditFindSimPasswordsP.Name = "m_menuEditFindSimPasswordsP"; this.m_menuEditFindSimPasswordsP.Size = new System.Drawing.Size(256, 22); this.m_menuEditFindSimPasswordsP.Text = "Find Similar Passwords (&Pairs)..."; this.m_menuEditFindSimPasswordsP.Click += new System.EventHandler(this.OnEditFindSimPasswordsP); // // m_menuEditFindSimPasswordsC // this.m_menuEditFindSimPasswordsC.Image = global::KeePass.Properties.Resources.B16x16_KGPG_Key2; this.m_menuEditFindSimPasswordsC.Name = "m_menuEditFindSimPasswordsC"; this.m_menuEditFindSimPasswordsC.Size = new System.Drawing.Size(256, 22); this.m_menuEditFindSimPasswordsC.Text = "Find Similar Passwords (&Clusters)..."; this.m_menuEditFindSimPasswordsC.Click += new System.EventHandler(this.OnEditFindSimPasswordsC); // // m_menuEditPwQualityReport // this.m_menuEditPwQualityReport.Image = global::KeePass.Properties.Resources.B16x16_KOrganizer; this.m_menuEditPwQualityReport.Name = "m_menuEditPwQualityReport"; this.m_menuEditPwQualityReport.Size = new System.Drawing.Size(256, 22); this.m_menuEditPwQualityReport.Text = "Password &Quality Report..."; this.m_menuEditPwQualityReport.Click += new System.EventHandler(this.OnEditPwQualityReport); // // m_menuEditShowByTag // this.m_menuEditShowByTag.Name = "m_menuEditShowByTag"; this.m_menuEditShowByTag.Size = new System.Drawing.Size(179, 22); this.m_menuEditShowByTag.Text = "Show Entries &by Tag"; this.m_menuEditShowByTag.DropDownOpening += new System.EventHandler(this.OnEditShowByTagOpening); // // m_menuEditSep0 // this.m_menuEditSep0.Name = "m_menuEditSep0"; this.m_menuEditSep0.Size = new System.Drawing.Size(176, 6); // // m_menuEditFind // this.m_menuEditFind.Image = global::KeePass.Properties.Resources.B16x16_XMag; this.m_menuEditFind.Name = "m_menuEditFind"; this.m_menuEditFind.Size = new System.Drawing.Size(179, 22); this.m_menuEditFind.Text = "&Find..."; this.m_menuEditFind.Click += new System.EventHandler(this.OnPwListFind); // // m_menuView // this.m_menuView.DropDownItems.AddRange(new System.Windows.Forms.ToolStripItem[] { this.m_menuChangeLanguage, this.m_menuViewSep0, this.m_menuViewShowToolBar, this.m_menuViewShowEntryView, this.m_menuViewWindowLayout, this.m_menuViewSep1, this.m_menuViewAlwaysOnTop, this.m_menuViewSep2, this.m_menuViewConfigColumns, this.m_menuViewSortBy, this.m_menuViewTanOptions, this.m_menuViewEntryListGrouping, this.m_menuViewSep3, this.m_menuViewShowEntriesOfSubGroups}); this.m_menuView.Name = "m_menuView"; this.m_menuView.Size = new System.Drawing.Size(44, 20); this.m_menuView.Text = "&View"; // // m_menuChangeLanguage // this.m_menuChangeLanguage.Image = global::KeePass.Properties.Resources.B16x16_Keyboard_Layout; this.m_menuChangeLanguage.Name = "m_menuChangeLanguage"; this.m_menuChangeLanguage.Size = new System.Drawing.Size(215, 22); this.m_menuChangeLanguage.Text = "Change &Language..."; this.m_menuChangeLanguage.Click += new System.EventHandler(this.OnMenuChangeLanguage); // // m_menuViewSep0 // this.m_menuViewSep0.Name = "m_menuViewSep0"; this.m_menuViewSep0.Size = new System.Drawing.Size(212, 6); // // m_menuViewShowToolBar // this.m_menuViewShowToolBar.Name = "m_menuViewShowToolBar"; this.m_menuViewShowToolBar.Size = new System.Drawing.Size(215, 22); this.m_menuViewShowToolBar.Text = "Show &Toolbar"; this.m_menuViewShowToolBar.Click += new System.EventHandler(this.OnViewShowToolBar); // // m_menuViewShowEntryView // this.m_menuViewShowEntryView.Name = "m_menuViewShowEntryView"; this.m_menuViewShowEntryView.Size = new System.Drawing.Size(215, 22); this.m_menuViewShowEntryView.Text = "Show &Entry View"; this.m_menuViewShowEntryView.Click += new System.EventHandler(this.OnViewShowEntryView); // // m_menuViewWindowLayout // this.m_menuViewWindowLayout.DropDownItems.AddRange(new System.Windows.Forms.ToolStripItem[] { this.m_menuViewWindowsStacked, this.m_menuViewWindowsSideBySide}); this.m_menuViewWindowLayout.Name = "m_menuViewWindowLayout"; this.m_menuViewWindowLayout.Size = new System.Drawing.Size(215, 22); this.m_menuViewWindowLayout.Text = "&Window Layout"; // // m_menuViewWindowsStacked // this.m_menuViewWindowsStacked.Image = global::KeePass.Properties.Resources.B16x16_Window_2Horz1Vert; this.m_menuViewWindowsStacked.Name = "m_menuViewWindowsStacked"; this.m_menuViewWindowsStacked.Size = new System.Drawing.Size(137, 22); this.m_menuViewWindowsStacked.Text = "&Stacked"; this.m_menuViewWindowsStacked.Click += new System.EventHandler(this.OnViewWindowsStacked); // // m_menuViewWindowsSideBySide // this.m_menuViewWindowsSideBySide.Image = global::KeePass.Properties.Resources.B16x16_Window_3Horz; this.m_menuViewWindowsSideBySide.Name = "m_menuViewWindowsSideBySide"; this.m_menuViewWindowsSideBySide.Size = new System.Drawing.Size(137, 22); this.m_menuViewWindowsSideBySide.Text = "Side &by Side"; this.m_menuViewWindowsSideBySide.Click += new System.EventHandler(this.OnViewWindowsSideBySide); // // m_menuViewSep1 // this.m_menuViewSep1.Name = "m_menuViewSep1"; this.m_menuViewSep1.Size = new System.Drawing.Size(212, 6); // // m_menuViewAlwaysOnTop // this.m_menuViewAlwaysOnTop.Name = "m_menuViewAlwaysOnTop"; this.m_menuViewAlwaysOnTop.Size = new System.Drawing.Size(215, 22); this.m_menuViewAlwaysOnTop.Text = "&Always on Top"; this.m_menuViewAlwaysOnTop.Click += new System.EventHandler(this.OnViewAlwaysOnTop); // // m_menuViewSep2 // this.m_menuViewSep2.Name = "m_menuViewSep2"; this.m_menuViewSep2.Size = new System.Drawing.Size(212, 6); // // m_menuViewConfigColumns // this.m_menuViewConfigColumns.Image = global::KeePass.Properties.Resources.B16x16_View_Detailed; this.m_menuViewConfigColumns.Name = "m_menuViewConfigColumns"; this.m_menuViewConfigColumns.Size = new System.Drawing.Size(215, 22); this.m_menuViewConfigColumns.Text = "&Configure Columns..."; this.m_menuViewConfigColumns.Click += new System.EventHandler(this.OnViewConfigColumns); // // m_menuViewSortBy // this.m_menuViewSortBy.Name = "m_menuViewSortBy"; this.m_menuViewSortBy.Size = new System.Drawing.Size(215, 22); this.m_menuViewSortBy.Text = "&Sort By"; // // m_menuViewTanOptions // this.m_menuViewTanOptions.DropDownItems.AddRange(new System.Windows.Forms.ToolStripItem[] { this.m_menuViewTanSimpleList, this.m_menuViewTanIndices}); this.m_menuViewTanOptions.Name = "m_menuViewTanOptions"; this.m_menuViewTanOptions.Size = new System.Drawing.Size(215, 22); this.m_menuViewTanOptions.Text = "TAN &View Options"; // // m_menuViewTanSimpleList // this.m_menuViewTanSimpleList.Name = "m_menuViewTanSimpleList"; this.m_menuViewTanSimpleList.Size = new System.Drawing.Size(296, 22); this.m_menuViewTanSimpleList.Text = "Use &Simple List View for TAN-Only Groups"; this.m_menuViewTanSimpleList.Click += new System.EventHandler(this.OnViewTanSimpleListClick); // // m_menuViewTanIndices // this.m_menuViewTanIndices.Name = "m_menuViewTanIndices"; this.m_menuViewTanIndices.Size = new System.Drawing.Size(296, 22); this.m_menuViewTanIndices.Text = "Show TAN &Indices in Entry Titles"; this.m_menuViewTanIndices.Click += new System.EventHandler(this.OnViewTanIndicesClick); // // m_menuViewEntryListGrouping // this.m_menuViewEntryListGrouping.Name = "m_menuViewEntryListGrouping"; this.m_menuViewEntryListGrouping.Size = new System.Drawing.Size(215, 22); this.m_menuViewEntryListGrouping.Text = "&Grouping in Entry List"; // // m_menuViewSep3 // this.m_menuViewSep3.Name = "m_menuViewSep3"; this.m_menuViewSep3.Size = new System.Drawing.Size(212, 6); // // m_menuViewShowEntriesOfSubGroups // this.m_menuViewShowEntriesOfSubGroups.Name = "m_menuViewShowEntriesOfSubGroups"; this.m_menuViewShowEntriesOfSubGroups.Size = new System.Drawing.Size(215, 22); this.m_menuViewShowEntriesOfSubGroups.Text = "Show Entries of Su&bgroups"; this.m_menuViewShowEntriesOfSubGroups.Click += new System.EventHandler(this.OnViewShowEntriesOfSubGroups); // // m_menuTools // this.m_menuTools.DropDownItems.AddRange(new System.Windows.Forms.ToolStripItem[] { this.m_menuToolsPwGenerator, this.m_menuToolsGeneratePwList, this.m_menuToolsSep0, this.m_menuToolsTanWizard, this.m_menuToolsDb, this.m_menuToolsSep1, this.m_menuToolsTriggers, this.m_menuToolsPlugins, this.m_menuToolsSep2, this.m_menuToolsOptions}); this.m_menuTools.Name = "m_menuTools"; this.m_menuTools.Size = new System.Drawing.Size(47, 20); this.m_menuTools.Text = "&Tools"; // // m_menuToolsPwGenerator // this.m_menuToolsPwGenerator.Image = global::KeePass.Properties.Resources.B16x16_Key_New; this.m_menuToolsPwGenerator.Name = "m_menuToolsPwGenerator"; this.m_menuToolsPwGenerator.Size = new System.Drawing.Size(204, 22); this.m_menuToolsPwGenerator.Text = "&Generate Password..."; this.m_menuToolsPwGenerator.Click += new System.EventHandler(this.OnToolsPwGenerator); // // m_menuToolsGeneratePwList // this.m_menuToolsGeneratePwList.Image = global::KeePass.Properties.Resources.B16x16_KGPG_Gen; this.m_menuToolsGeneratePwList.Name = "m_menuToolsGeneratePwList"; this.m_menuToolsGeneratePwList.Size = new System.Drawing.Size(204, 22); this.m_menuToolsGeneratePwList.Text = "Generate Password &List..."; this.m_menuToolsGeneratePwList.Click += new System.EventHandler(this.OnToolsGeneratePasswordList); // // m_menuToolsSep0 // this.m_menuToolsSep0.Name = "m_menuToolsSep0"; this.m_menuToolsSep0.Size = new System.Drawing.Size(201, 6); // // m_menuToolsTanWizard // this.m_menuToolsTanWizard.Image = global::KeePass.Properties.Resources.B16x16_Wizard; this.m_menuToolsTanWizard.Name = "m_menuToolsTanWizard"; this.m_menuToolsTanWizard.Size = new System.Drawing.Size(204, 22); this.m_menuToolsTanWizard.Text = "&TAN Wizard..."; this.m_menuToolsTanWizard.Click += new System.EventHandler(this.OnToolsTanWizard); // // m_menuToolsDb // this.m_menuToolsDb.DropDownItems.AddRange(new System.Windows.Forms.ToolStripItem[] { this.m_menuToolsDbMaintenance, this.m_menuToolsDbSep0, this.m_menuToolsDbDelDupEntries, this.m_menuToolsDbDelEmptyGroups, this.m_menuToolsDbDelUnusedIcons, this.m_menuToolsDbSep1, this.m_menuToolsDbXmlRep, this.m_menuToolsDbSep2, this.m_menuToolsPrintEmSheet}); this.m_menuToolsDb.Name = "m_menuToolsDb"; this.m_menuToolsDb.Size = new System.Drawing.Size(204, 22); this.m_menuToolsDb.Text = "&Database Tools"; // // m_menuToolsDbMaintenance // this.m_menuToolsDbMaintenance.Image = global::KeePass.Properties.Resources.B16x16_Package_Settings; this.m_menuToolsDbMaintenance.Name = "m_menuToolsDbMaintenance"; this.m_menuToolsDbMaintenance.Size = new System.Drawing.Size(226, 22); this.m_menuToolsDbMaintenance.Text = "Database &Maintenance..."; this.m_menuToolsDbMaintenance.Click += new System.EventHandler(this.OnToolsDbMaintenance); // // m_menuToolsDbSep0 // this.m_menuToolsDbSep0.Name = "m_menuToolsDbSep0"; this.m_menuToolsDbSep0.Size = new System.Drawing.Size(223, 6); // // m_menuToolsDbDelDupEntries // this.m_menuToolsDbDelDupEntries.Image = global::KeePass.Properties.Resources.B16x16_DeleteEntry; this.m_menuToolsDbDelDupEntries.Name = "m_menuToolsDbDelDupEntries"; this.m_menuToolsDbDelDupEntries.Size = new System.Drawing.Size(226, 22); this.m_menuToolsDbDelDupEntries.Text = "Delete &Duplicate Entries"; this.m_menuToolsDbDelDupEntries.Click += new System.EventHandler(this.OnToolsDelDupEntries); // // m_menuToolsDbDelEmptyGroups // this.m_menuToolsDbDelEmptyGroups.Image = global::KeePass.Properties.Resources.B16x16_Folder_Locked; this.m_menuToolsDbDelEmptyGroups.Name = "m_menuToolsDbDelEmptyGroups"; this.m_menuToolsDbDelEmptyGroups.Size = new System.Drawing.Size(226, 22); this.m_menuToolsDbDelEmptyGroups.Text = "Delete Empty &Groups"; this.m_menuToolsDbDelEmptyGroups.Click += new System.EventHandler(this.OnToolsDelEmptyGroups); // // m_menuToolsDbDelUnusedIcons // this.m_menuToolsDbDelUnusedIcons.Image = global::KeePass.Properties.Resources.B16x16_Trashcan_Full; this.m_menuToolsDbDelUnusedIcons.Name = "m_menuToolsDbDelUnusedIcons"; this.m_menuToolsDbDelUnusedIcons.Size = new System.Drawing.Size(226, 22); this.m_menuToolsDbDelUnusedIcons.Text = "Delete Unused Custom &Icons"; this.m_menuToolsDbDelUnusedIcons.Click += new System.EventHandler(this.OnToolsDelUnusedIcons); // // m_menuToolsDbSep1 // this.m_menuToolsDbSep1.Name = "m_menuToolsDbSep1"; this.m_menuToolsDbSep1.Size = new System.Drawing.Size(223, 6); // // m_menuToolsDbXmlRep // this.m_menuToolsDbXmlRep.Image = global::KeePass.Properties.Resources.B16x16_Binary; this.m_menuToolsDbXmlRep.Name = "m_menuToolsDbXmlRep"; this.m_menuToolsDbXmlRep.Size = new System.Drawing.Size(226, 22); this.m_menuToolsDbXmlRep.Text = "&XML Replace..."; this.m_menuToolsDbXmlRep.Click += new System.EventHandler(this.OnToolsXmlRep); // // m_menuToolsDbSep2 // this.m_menuToolsDbSep2.Name = "m_menuToolsDbSep2"; this.m_menuToolsDbSep2.Size = new System.Drawing.Size(223, 6); // // m_menuToolsPrintEmSheet // this.m_menuToolsPrintEmSheet.Image = global::KeePass.Properties.Resources.B16x16_KOrganizer; this.m_menuToolsPrintEmSheet.Name = "m_menuToolsPrintEmSheet"; this.m_menuToolsPrintEmSheet.Size = new System.Drawing.Size(226, 22); this.m_menuToolsPrintEmSheet.Text = "Print &Emergency Sheet..."; this.m_menuToolsPrintEmSheet.Click += new System.EventHandler(this.OnToolsPrintEmSheet); // // m_menuToolsSep1 // this.m_menuToolsSep1.Name = "m_menuToolsSep1"; this.m_menuToolsSep1.Size = new System.Drawing.Size(201, 6); // // m_menuToolsTriggers // this.m_menuToolsTriggers.Image = global::KeePass.Properties.Resources.B16x16_Make_KDevelop; this.m_menuToolsTriggers.Name = "m_menuToolsTriggers"; this.m_menuToolsTriggers.Size = new System.Drawing.Size(204, 22); this.m_menuToolsTriggers.Text = "T&riggers..."; this.m_menuToolsTriggers.Click += new System.EventHandler(this.OnToolsTriggers); // // m_menuToolsPlugins // this.m_menuToolsPlugins.Image = global::KeePass.Properties.Resources.B16x16_BlockDevice; this.m_menuToolsPlugins.Name = "m_menuToolsPlugins"; this.m_menuToolsPlugins.Size = new System.Drawing.Size(204, 22); this.m_menuToolsPlugins.Text = "&Plugins..."; this.m_menuToolsPlugins.Click += new System.EventHandler(this.OnToolsPlugins); // // m_menuToolsSep2 // this.m_menuToolsSep2.Name = "m_menuToolsSep2"; this.m_menuToolsSep2.Size = new System.Drawing.Size(201, 6); // // m_menuToolsOptions // this.m_menuToolsOptions.Image = global::KeePass.Properties.Resources.B16x16_Misc; this.m_menuToolsOptions.Name = "m_menuToolsOptions"; this.m_menuToolsOptions.Size = new System.Drawing.Size(204, 22); this.m_menuToolsOptions.Text = "&Options..."; this.m_menuToolsOptions.Click += new System.EventHandler(this.OnToolsOptions); // // m_menuHelp // this.m_menuHelp.DropDownItems.AddRange(new System.Windows.Forms.ToolStripItem[] { this.m_menuHelpContents, this.m_menuHelpSelectSource, this.m_menuHelpSep0, this.m_menuHelpWebsite, this.m_menuHelpDonate, this.m_menuHelpSep1, this.m_menuHelpCheckForUpdates, this.m_menuHelpSep2, this.m_menuHelpAbout}); this.m_menuHelp.Name = "m_menuHelp"; this.m_menuHelp.Size = new System.Drawing.Size(44, 20); this.m_menuHelp.Text = "&Help"; // // m_menuHelpContents // this.m_menuHelpContents.Image = global::KeePass.Properties.Resources.B16x16_Toggle_Log; this.m_menuHelpContents.Name = "m_menuHelpContents"; this.m_menuHelpContents.Size = new System.Drawing.Size(171, 22); this.m_menuHelpContents.Text = "&Help Contents"; this.m_menuHelpContents.Click += new System.EventHandler(this.OnHelpContents); // // m_menuHelpSelectSource // this.m_menuHelpSelectSource.Image = global::KeePass.Properties.Resources.B16x16_KOrganizer; this.m_menuHelpSelectSource.Name = "m_menuHelpSelectSource"; this.m_menuHelpSelectSource.Size = new System.Drawing.Size(171, 22); this.m_menuHelpSelectSource.Text = "Help &Source..."; this.m_menuHelpSelectSource.Click += new System.EventHandler(this.OnHelpSelectSource); // // m_menuHelpSep0 // this.m_menuHelpSep0.Name = "m_menuHelpSep0"; this.m_menuHelpSep0.Size = new System.Drawing.Size(168, 6); // // m_menuHelpWebsite // this.m_menuHelpWebsite.Image = global::KeePass.Properties.Resources.B16x16_Folder_Home; this.m_menuHelpWebsite.Name = "m_menuHelpWebsite"; this.m_menuHelpWebsite.Size = new System.Drawing.Size(171, 22); this.m_menuHelpWebsite.Text = "KeePass &Website"; this.m_menuHelpWebsite.Click += new System.EventHandler(this.OnHelpHomepage); // // m_menuHelpDonate // this.m_menuHelpDonate.Image = global::KeePass.Properties.Resources.B16x16_Identity; this.m_menuHelpDonate.Name = "m_menuHelpDonate"; this.m_menuHelpDonate.Size = new System.Drawing.Size(171, 22); this.m_menuHelpDonate.Text = "&Donate..."; this.m_menuHelpDonate.Click += new System.EventHandler(this.OnHelpDonate); // // m_menuHelpSep1 // this.m_menuHelpSep1.Name = "m_menuHelpSep1"; this.m_menuHelpSep1.Size = new System.Drawing.Size(168, 6); // // m_menuHelpCheckForUpdates // this.m_menuHelpCheckForUpdates.Image = global::KeePass.Properties.Resources.B16x16_FTP; this.m_menuHelpCheckForUpdates.Name = "m_menuHelpCheckForUpdates"; this.m_menuHelpCheckForUpdates.Size = new System.Drawing.Size(171, 22); this.m_menuHelpCheckForUpdates.Text = "&Check for Updates"; this.m_menuHelpCheckForUpdates.Click += new System.EventHandler(this.OnHelpCheckForUpdate); // // m_menuHelpSep2 // this.m_menuHelpSep2.Name = "m_menuHelpSep2"; this.m_menuHelpSep2.Size = new System.Drawing.Size(168, 6); // // m_menuHelpAbout // this.m_menuHelpAbout.Image = global::KeePass.Properties.Resources.B16x16_Help; this.m_menuHelpAbout.Name = "m_menuHelpAbout"; this.m_menuHelpAbout.Size = new System.Drawing.Size(171, 22); this.m_menuHelpAbout.Text = "&About KeePass..."; this.m_menuHelpAbout.Click += new System.EventHandler(this.OnHelpAbout); // // m_toolMain // this.m_toolMain.Items.AddRange(new System.Windows.Forms.ToolStripItem[] { this.m_tbNewDatabase, this.m_tbOpenDatabase, this.m_tbSaveDatabase, this.m_tbSaveAll, this.m_tbSep0, this.m_tbAddEntry, this.m_tbSep1, this.m_tbCopyUserName, this.m_tbCopyPassword, this.m_tbOpenUrl, this.m_tbCopyUrl, this.m_tbAutoType, this.m_tbSep4, this.m_tbFind, this.m_tbEntryViewsDropDown, this.m_tbSep2, this.m_tbLockWorkspace, this.m_tbSep3, this.m_tbQuickFind, this.m_tbCloseTab}); this.m_toolMain.Location = new System.Drawing.Point(0, 24); this.m_toolMain.Name = "m_toolMain"; this.m_toolMain.Size = new System.Drawing.Size(654, 25); this.m_toolMain.TabIndex = 1; this.m_toolMain.TabStop = true; // // m_tbNewDatabase // this.m_tbNewDatabase.DisplayStyle = System.Windows.Forms.ToolStripItemDisplayStyle.Image; this.m_tbNewDatabase.Image = global::KeePass.Properties.Resources.B16x16_FileNew; this.m_tbNewDatabase.ImageTransparentColor = System.Drawing.Color.Magenta; this.m_tbNewDatabase.Name = "m_tbNewDatabase"; this.m_tbNewDatabase.Size = new System.Drawing.Size(23, 22); this.m_tbNewDatabase.Click += new System.EventHandler(this.OnFileNew); // // m_tbOpenDatabase // this.m_tbOpenDatabase.DisplayStyle = System.Windows.Forms.ToolStripItemDisplayStyle.Image; this.m_tbOpenDatabase.Image = global::KeePass.Properties.Resources.B16x16_Folder_Yellow_Open; this.m_tbOpenDatabase.ImageTransparentColor = System.Drawing.Color.Magenta; this.m_tbOpenDatabase.Name = "m_tbOpenDatabase"; this.m_tbOpenDatabase.Size = new System.Drawing.Size(23, 22); this.m_tbOpenDatabase.Click += new System.EventHandler(this.OnFileOpen); // // m_tbSaveDatabase // this.m_tbSaveDatabase.DisplayStyle = System.Windows.Forms.ToolStripItemDisplayStyle.Image; this.m_tbSaveDatabase.Image = global::KeePass.Properties.Resources.B16x16_FileSave; this.m_tbSaveDatabase.ImageTransparentColor = System.Drawing.Color.Magenta; this.m_tbSaveDatabase.Name = "m_tbSaveDatabase"; this.m_tbSaveDatabase.Size = new System.Drawing.Size(23, 22); this.m_tbSaveDatabase.Click += new System.EventHandler(this.OnFileSave); // // m_tbSaveAll // this.m_tbSaveAll.DisplayStyle = System.Windows.Forms.ToolStripItemDisplayStyle.Image; this.m_tbSaveAll.Image = global::KeePass.Properties.Resources.B16x16_File_SaveAll; this.m_tbSaveAll.ImageTransparentColor = System.Drawing.Color.Magenta; this.m_tbSaveAll.Name = "m_tbSaveAll"; this.m_tbSaveAll.Size = new System.Drawing.Size(23, 22); this.m_tbSaveAll.Click += new System.EventHandler(this.OnFileSaveAll); // // m_tbSep0 // this.m_tbSep0.Name = "m_tbSep0"; this.m_tbSep0.Size = new System.Drawing.Size(6, 25); // // m_tbAddEntry // this.m_tbAddEntry.DisplayStyle = System.Windows.Forms.ToolStripItemDisplayStyle.Image; this.m_tbAddEntry.DropDownItems.AddRange(new System.Windows.Forms.ToolStripItem[] { this.m_tbAddEntryDefault}); this.m_tbAddEntry.Image = global::KeePass.Properties.Resources.B16x16_KGPG_Import; this.m_tbAddEntry.ImageTransparentColor = System.Drawing.Color.Magenta; this.m_tbAddEntry.Name = "m_tbAddEntry"; this.m_tbAddEntry.Size = new System.Drawing.Size(32, 22); this.m_tbAddEntry.ButtonClick += new System.EventHandler(this.OnEntryAdd); // // m_tbAddEntryDefault // this.m_tbAddEntryDefault.Image = global::KeePass.Properties.Resources.B16x16_KGPG_Import; this.m_tbAddEntryDefault.Name = "m_tbAddEntryDefault"; this.m_tbAddEntryDefault.Size = new System.Drawing.Size(90, 22); this.m_tbAddEntryDefault.Text = "<>"; this.m_tbAddEntryDefault.Click += new System.EventHandler(this.OnEntryAdd); // // m_tbSep1 // this.m_tbSep1.Name = "m_tbSep1"; this.m_tbSep1.Size = new System.Drawing.Size(6, 25); // // m_tbCopyUserName // this.m_tbCopyUserName.DisplayStyle = System.Windows.Forms.ToolStripItemDisplayStyle.Image; this.m_tbCopyUserName.Image = global::KeePass.Properties.Resources.B16x16_Personal; this.m_tbCopyUserName.ImageTransparentColor = System.Drawing.Color.Magenta; this.m_tbCopyUserName.Name = "m_tbCopyUserName"; this.m_tbCopyUserName.Size = new System.Drawing.Size(23, 22); this.m_tbCopyUserName.Click += new System.EventHandler(this.OnEntryCopyUserName); // // m_tbCopyPassword // this.m_tbCopyPassword.DisplayStyle = System.Windows.Forms.ToolStripItemDisplayStyle.Image; this.m_tbCopyPassword.Image = global::KeePass.Properties.Resources.B16x16_KGPG_Info; this.m_tbCopyPassword.ImageTransparentColor = System.Drawing.Color.Magenta; this.m_tbCopyPassword.Name = "m_tbCopyPassword"; this.m_tbCopyPassword.Size = new System.Drawing.Size(23, 22); this.m_tbCopyPassword.Click += new System.EventHandler(this.OnEntryCopyPassword); // // m_tbOpenUrl // this.m_tbOpenUrl.DisplayStyle = System.Windows.Forms.ToolStripItemDisplayStyle.Image; this.m_tbOpenUrl.DropDownItems.AddRange(new System.Windows.Forms.ToolStripItem[] { this.m_tbOpenUrlDefault}); this.m_tbOpenUrl.Image = global::KeePass.Properties.Resources.B16x16_FTP; this.m_tbOpenUrl.ImageTransparentColor = System.Drawing.Color.Magenta; this.m_tbOpenUrl.Name = "m_tbOpenUrl"; this.m_tbOpenUrl.Size = new System.Drawing.Size(32, 22); this.m_tbOpenUrl.ButtonClick += new System.EventHandler(this.OnEntryOpenUrl); // // m_tbOpenUrlDefault // this.m_tbOpenUrlDefault.Image = global::KeePass.Properties.Resources.B16x16_FTP; this.m_tbOpenUrlDefault.Name = "m_tbOpenUrlDefault"; this.m_tbOpenUrlDefault.Size = new System.Drawing.Size(90, 22); this.m_tbOpenUrlDefault.Text = "<>"; this.m_tbOpenUrlDefault.Click += new System.EventHandler(this.OnEntryOpenUrl); // // m_tbCopyUrl // this.m_tbCopyUrl.DisplayStyle = System.Windows.Forms.ToolStripItemDisplayStyle.Image; this.m_tbCopyUrl.Image = global::KeePass.Properties.Resources.B16x16_EditCopyUrl; this.m_tbCopyUrl.ImageTransparentColor = System.Drawing.Color.Magenta; this.m_tbCopyUrl.Name = "m_tbCopyUrl"; this.m_tbCopyUrl.Size = new System.Drawing.Size(23, 22); this.m_tbCopyUrl.Click += new System.EventHandler(this.OnEntryCopyURL); // // m_tbAutoType // this.m_tbAutoType.DisplayStyle = System.Windows.Forms.ToolStripItemDisplayStyle.Image; this.m_tbAutoType.Image = global::KeePass.Properties.Resources.B16x16_KTouch; this.m_tbAutoType.ImageTransparentColor = System.Drawing.Color.Magenta; this.m_tbAutoType.Name = "m_tbAutoType"; this.m_tbAutoType.Size = new System.Drawing.Size(23, 22); this.m_tbAutoType.Click += new System.EventHandler(this.OnEntryPerformAutoType); // // m_tbSep4 // this.m_tbSep4.Name = "m_tbSep4"; this.m_tbSep4.Size = new System.Drawing.Size(6, 25); // // m_tbFind // this.m_tbFind.DisplayStyle = System.Windows.Forms.ToolStripItemDisplayStyle.Image; this.m_tbFind.Image = global::KeePass.Properties.Resources.B16x16_XMag; this.m_tbFind.ImageTransparentColor = System.Drawing.Color.Magenta; this.m_tbFind.Name = "m_tbFind"; this.m_tbFind.Size = new System.Drawing.Size(23, 22); this.m_tbFind.Click += new System.EventHandler(this.OnPwListFind); // // m_tbEntryViewsDropDown // this.m_tbEntryViewsDropDown.DisplayStyle = System.Windows.Forms.ToolStripItemDisplayStyle.Image; this.m_tbEntryViewsDropDown.DropDownItems.AddRange(new System.Windows.Forms.ToolStripItem[] { this.m_tbViewsShowAll, this.m_tbViewsShowExpired}); this.m_tbEntryViewsDropDown.Image = global::KeePass.Properties.Resources.B16x16_KGPG_Key3; this.m_tbEntryViewsDropDown.ImageTransparentColor = System.Drawing.Color.Magenta; this.m_tbEntryViewsDropDown.Name = "m_tbEntryViewsDropDown"; this.m_tbEntryViewsDropDown.Size = new System.Drawing.Size(29, 22); this.m_tbEntryViewsDropDown.DropDownOpening += new System.EventHandler(this.OnEntryViewsByTagOpening); // // m_tbViewsShowAll // this.m_tbViewsShowAll.Image = global::KeePass.Properties.Resources.B16x16_KGPG_Key3; this.m_tbViewsShowAll.Name = "m_tbViewsShowAll"; this.m_tbViewsShowAll.Size = new System.Drawing.Size(67, 22); this.m_tbViewsShowAll.Click += new System.EventHandler(this.OnEditShowAll); // // m_tbViewsShowExpired // this.m_tbViewsShowExpired.Image = global::KeePass.Properties.Resources.B16x16_History_Clear; this.m_tbViewsShowExpired.Name = "m_tbViewsShowExpired"; this.m_tbViewsShowExpired.Size = new System.Drawing.Size(67, 22); this.m_tbViewsShowExpired.Click += new System.EventHandler(this.OnEditShowExp); // // m_tbSep2 // this.m_tbSep2.Name = "m_tbSep2"; this.m_tbSep2.Size = new System.Drawing.Size(6, 25); // // m_tbLockWorkspace // this.m_tbLockWorkspace.DisplayStyle = System.Windows.Forms.ToolStripItemDisplayStyle.Image; this.m_tbLockWorkspace.Image = global::KeePass.Properties.Resources.B16x16_LockWorkspace; this.m_tbLockWorkspace.ImageTransparentColor = System.Drawing.Color.Magenta; this.m_tbLockWorkspace.Name = "m_tbLockWorkspace"; this.m_tbLockWorkspace.Size = new System.Drawing.Size(23, 22); this.m_tbLockWorkspace.Click += new System.EventHandler(this.OnFileLock); // // m_tbSep3 // this.m_tbSep3.Name = "m_tbSep3"; this.m_tbSep3.Size = new System.Drawing.Size(6, 25); // // m_tbQuickFind // this.m_tbQuickFind.Name = "m_tbQuickFind"; this.m_tbQuickFind.Size = new System.Drawing.Size(121, 25); this.m_tbQuickFind.SelectedIndexChanged += new System.EventHandler(this.OnQuickFindSelectedIndexChanged); this.m_tbQuickFind.KeyUp += new System.Windows.Forms.KeyEventHandler(this.OnQuickFindKeyUp); this.m_tbQuickFind.KeyDown += new System.Windows.Forms.KeyEventHandler(this.OnQuickFindKeyDown); // // m_tbCloseTab // this.m_tbCloseTab.Alignment = System.Windows.Forms.ToolStripItemAlignment.Right; this.m_tbCloseTab.DisplayStyle = System.Windows.Forms.ToolStripItemDisplayStyle.Image; this.m_tbCloseTab.Image = global::KeePass.Properties.Resources.B16x16_File_Close; this.m_tbCloseTab.ImageTransparentColor = System.Drawing.Color.Magenta; this.m_tbCloseTab.Name = "m_tbCloseTab"; this.m_tbCloseTab.Size = new System.Drawing.Size(23, 22); this.m_tbCloseTab.Click += new System.EventHandler(this.OnFileClose); // // m_statusMain // this.m_statusMain.GripStyle = System.Windows.Forms.ToolStripGripStyle.Visible; this.m_statusMain.Items.AddRange(new System.Windows.Forms.ToolStripItem[] { this.m_statusPartSelected, this.m_statusPartInfo, this.m_statusPartProgress, this.m_statusClipboard}); this.m_statusMain.Location = new System.Drawing.Point(0, 464); this.m_statusMain.Name = "m_statusMain"; this.m_statusMain.Size = new System.Drawing.Size(654, 22); this.m_statusMain.TabIndex = 3; // // m_statusPartSelected // this.m_statusPartSelected.AutoSize = false; this.m_statusPartSelected.BorderSides = System.Windows.Forms.ToolStripStatusLabelBorderSides.Right; this.m_statusPartSelected.Name = "m_statusPartSelected"; this.m_statusPartSelected.Size = new System.Drawing.Size(140, 17); this.m_statusPartSelected.Text = "0 entries"; this.m_statusPartSelected.TextAlign = System.Drawing.ContentAlignment.MiddleLeft; // // m_statusPartInfo // this.m_statusPartInfo.Name = "m_statusPartInfo"; this.m_statusPartInfo.Size = new System.Drawing.Size(245, 17); this.m_statusPartInfo.Spring = true; this.m_statusPartInfo.Text = "Ready."; this.m_statusPartInfo.TextAlign = System.Drawing.ContentAlignment.MiddleLeft; // // m_statusPartProgress // this.m_statusPartProgress.AutoSize = false; this.m_statusPartProgress.Name = "m_statusPartProgress"; this.m_statusPartProgress.Size = new System.Drawing.Size(150, 16); this.m_statusPartProgress.Style = System.Windows.Forms.ProgressBarStyle.Continuous; // // m_statusClipboard // this.m_statusClipboard.AutoSize = false; this.m_statusClipboard.Name = "m_statusClipboard"; this.m_statusClipboard.Size = new System.Drawing.Size(100, 16); this.m_statusClipboard.Style = System.Windows.Forms.ProgressBarStyle.Continuous; // // m_ctxTray // this.m_ctxTray.Items.AddRange(new System.Windows.Forms.ToolStripItem[] { this.m_ctxTrayTray, this.m_ctxTraySep0, this.m_ctxTrayGenPw, this.m_ctxTraySep1, this.m_ctxTrayOptions, this.m_ctxTraySep2, this.m_ctxTrayLock, this.m_ctxTrayFileExit}); this.m_ctxTray.Name = "m_ctxTray"; this.m_ctxTray.Size = new System.Drawing.Size(184, 132); this.m_ctxTray.Opening += new System.ComponentModel.CancelEventHandler(this.OnCtxTrayOpening); // // m_ctxTrayTray // this.m_ctxTrayTray.Image = global::KeePass.Properties.Resources.B16x16_View_Detailed; this.m_ctxTrayTray.Name = "m_ctxTrayTray"; this.m_ctxTrayTray.Size = new System.Drawing.Size(183, 22); this.m_ctxTrayTray.Text = "&Tray / Untray"; this.m_ctxTrayTray.Click += new System.EventHandler(this.OnTrayTray); // // m_ctxTraySep0 // this.m_ctxTraySep0.Name = "m_ctxTraySep0"; this.m_ctxTraySep0.Size = new System.Drawing.Size(180, 6); // // m_ctxTrayGenPw // this.m_ctxTrayGenPw.Image = global::KeePass.Properties.Resources.B16x16_Key_New; this.m_ctxTrayGenPw.Name = "m_ctxTrayGenPw"; this.m_ctxTrayGenPw.Size = new System.Drawing.Size(183, 22); this.m_ctxTrayGenPw.Text = "&Generate Password..."; this.m_ctxTrayGenPw.Click += new System.EventHandler(this.OnTrayGenPw); // // m_ctxTraySep1 // this.m_ctxTraySep1.Name = "m_ctxTraySep1"; this.m_ctxTraySep1.Size = new System.Drawing.Size(180, 6); // // m_ctxTrayOptions // this.m_ctxTrayOptions.Image = global::KeePass.Properties.Resources.B16x16_Misc; this.m_ctxTrayOptions.Name = "m_ctxTrayOptions"; this.m_ctxTrayOptions.Size = new System.Drawing.Size(183, 22); this.m_ctxTrayOptions.Text = "&Options..."; this.m_ctxTrayOptions.Click += new System.EventHandler(this.OnTrayOptions); // // m_ctxTraySep2 // this.m_ctxTraySep2.Name = "m_ctxTraySep2"; this.m_ctxTraySep2.Size = new System.Drawing.Size(180, 6); // // m_ctxTrayLock // this.m_ctxTrayLock.Image = global::KeePass.Properties.Resources.B16x16_LockWorkspace; this.m_ctxTrayLock.Name = "m_ctxTrayLock"; this.m_ctxTrayLock.Size = new System.Drawing.Size(183, 22); this.m_ctxTrayLock.Text = "<>"; this.m_ctxTrayLock.Click += new System.EventHandler(this.OnTrayLock); // // m_ctxTrayFileExit // this.m_ctxTrayFileExit.Image = global::KeePass.Properties.Resources.B16x16_Exit; this.m_ctxTrayFileExit.Name = "m_ctxTrayFileExit"; this.m_ctxTrayFileExit.Size = new System.Drawing.Size(183, 22); this.m_ctxTrayFileExit.Text = "E&xit"; this.m_ctxTrayFileExit.Click += new System.EventHandler(this.OnTrayExit); // // m_timerMain // this.m_timerMain.Enabled = true; this.m_timerMain.Interval = 1000; this.m_timerMain.Tick += new System.EventHandler(this.OnTimerMainTick); // // m_tabMain // this.m_tabMain.Dock = System.Windows.Forms.DockStyle.Top; this.m_tabMain.Location = new System.Drawing.Point(0, 49); this.m_tabMain.Name = "m_tabMain"; this.m_tabMain.SelectedIndex = 0; this.m_tabMain.ShowToolTips = true; this.m_tabMain.Size = new System.Drawing.Size(654, 22); this.m_tabMain.TabIndex = 2; this.m_tabMain.KeyUp += new System.Windows.Forms.KeyEventHandler(this.OnTabMainKeyUp); this.m_tabMain.MouseClick += new System.Windows.Forms.MouseEventHandler(this.OnTabMainMouseClick); this.m_tabMain.SelectedIndexChanged += new System.EventHandler(this.OnTabMainSelectedIndexChanged); this.m_tabMain.KeyDown += new System.Windows.Forms.KeyEventHandler(this.OnTabMainKeyDown); // // m_splitHorizontal // this.m_splitHorizontal.Dock = System.Windows.Forms.DockStyle.Fill; this.m_splitHorizontal.Location = new System.Drawing.Point(0, 71); this.m_splitHorizontal.Name = "m_splitHorizontal"; this.m_splitHorizontal.Orientation = System.Windows.Forms.Orientation.Horizontal; // // m_splitHorizontal.Panel1 // this.m_splitHorizontal.Panel1.Controls.Add(this.m_splitVertical); // // m_splitHorizontal.Panel2 // this.m_splitHorizontal.Panel2.Controls.Add(this.m_richEntryView); this.m_splitHorizontal.Size = new System.Drawing.Size(654, 393); this.m_splitHorizontal.SplitterDistance = 306; this.m_splitHorizontal.TabIndex = 2; this.m_splitHorizontal.TabStop = false; // // m_splitVertical // this.m_splitVertical.Dock = System.Windows.Forms.DockStyle.Fill; this.m_splitVertical.Location = new System.Drawing.Point(0, 0); this.m_splitVertical.Name = "m_splitVertical"; // // m_splitVertical.Panel1 // this.m_splitVertical.Panel1.Controls.Add(this.m_tvGroups); // // m_splitVertical.Panel2 // this.m_splitVertical.Panel2.Controls.Add(this.m_lvEntries); this.m_splitVertical.Size = new System.Drawing.Size(654, 306); this.m_splitVertical.SplitterDistance = 177; this.m_splitVertical.TabIndex = 0; this.m_splitVertical.TabStop = false; // // m_tvGroups // this.m_tvGroups.AllowDrop = true; this.m_tvGroups.ContextMenuStrip = this.m_ctxGroupList; this.m_tvGroups.Dock = System.Windows.Forms.DockStyle.Fill; this.m_tvGroups.HideSelection = false; this.m_tvGroups.HotTracking = true; this.m_tvGroups.Location = new System.Drawing.Point(0, 0); this.m_tvGroups.Name = "m_tvGroups"; this.m_tvGroups.ShowNodeToolTips = true; this.m_tvGroups.ShowRootLines = false; this.m_tvGroups.Size = new System.Drawing.Size(177, 306); this.m_tvGroups.TabIndex = 0; this.m_tvGroups.AfterCollapse += new System.Windows.Forms.TreeViewEventHandler(this.OnGroupsAfterCollapse); this.m_tvGroups.DragLeave += new System.EventHandler(this.OnGroupsListDragLeave); this.m_tvGroups.DragDrop += new System.Windows.Forms.DragEventHandler(this.OnGroupsListDragDrop); this.m_tvGroups.DragEnter += new System.Windows.Forms.DragEventHandler(this.OnGroupsListDragEnter); this.m_tvGroups.KeyUp += new System.Windows.Forms.KeyEventHandler(this.OnGroupsKeyUp); this.m_tvGroups.NodeMouseClick += new System.Windows.Forms.TreeNodeMouseClickEventHandler(this.OnGroupsListClickNode); this.m_tvGroups.KeyDown += new System.Windows.Forms.KeyEventHandler(this.OnGroupsKeyDown); this.m_tvGroups.AfterExpand += new System.Windows.Forms.TreeViewEventHandler(this.OnGroupsAfterExpand); this.m_tvGroups.ItemDrag += new System.Windows.Forms.ItemDragEventHandler(this.OnGroupsListItemDrag); this.m_tvGroups.DragOver += new System.Windows.Forms.DragEventHandler(this.OnGroupsListDragOver); // // m_lvEntries // this.m_lvEntries.AllowColumnReorder = true; this.m_lvEntries.ContextMenuStrip = this.m_ctxPwList; this.m_lvEntries.Dock = System.Windows.Forms.DockStyle.Fill; this.m_lvEntries.FullRowSelect = true; this.m_lvEntries.HideSelection = false; this.m_lvEntries.Location = new System.Drawing.Point(0, 0); this.m_lvEntries.Name = "m_lvEntries"; this.m_lvEntries.ShowItemToolTips = true; this.m_lvEntries.Size = new System.Drawing.Size(473, 306); this.m_lvEntries.TabIndex = 0; this.m_lvEntries.UseCompatibleStateImageBehavior = false; this.m_lvEntries.View = System.Windows.Forms.View.Details; this.m_lvEntries.MouseDoubleClick += new System.Windows.Forms.MouseEventHandler(this.OnPwListMouseDoubleClick); this.m_lvEntries.ColumnWidthChanged += new System.Windows.Forms.ColumnWidthChangedEventHandler(this.OnPwListColumnWidthChanged); this.m_lvEntries.SelectedIndexChanged += new System.EventHandler(this.OnPwListSelectedIndexChanged); this.m_lvEntries.ColumnClick += new System.Windows.Forms.ColumnClickEventHandler(this.OnPwListColumnClick); this.m_lvEntries.MouseDown += new System.Windows.Forms.MouseEventHandler(this.OnPwListMouseDown); this.m_lvEntries.KeyUp += new System.Windows.Forms.KeyEventHandler(this.OnPwListKeyUp); this.m_lvEntries.KeyDown += new System.Windows.Forms.KeyEventHandler(this.OnPwListKeyDown); this.m_lvEntries.ItemDrag += new System.Windows.Forms.ItemDragEventHandler(this.OnPwListItemDrag); this.m_lvEntries.Click += new System.EventHandler(this.OnPwListClick); // // m_richEntryView // this.m_richEntryView.Dock = System.Windows.Forms.DockStyle.Fill; this.m_richEntryView.Location = new System.Drawing.Point(0, 0); this.m_richEntryView.Name = "m_richEntryView"; this.m_richEntryView.ReadOnly = true; this.m_richEntryView.Size = new System.Drawing.Size(654, 83); this.m_richEntryView.TabIndex = 0; this.m_richEntryView.Text = ""; this.m_richEntryView.KeyDown += new System.Windows.Forms.KeyEventHandler(this.OnEntryViewKeyDown); this.m_richEntryView.LinkClicked += new System.Windows.Forms.LinkClickedEventHandler(this.OnEntryViewLinkClicked); this.m_richEntryView.KeyUp += new System.Windows.Forms.KeyEventHandler(this.OnEntryViewKeyUp); // // MainForm // this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F); this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; this.ClientSize = new System.Drawing.Size(654, 486); this.Controls.Add(this.m_splitHorizontal); this.Controls.Add(this.m_statusMain); this.Controls.Add(this.m_tabMain); this.Controls.Add(this.m_toolMain); this.Controls.Add(this.m_menuMain); this.MainMenuStrip = this.m_menuMain; this.Name = "MainForm"; this.StartPosition = System.Windows.Forms.FormStartPosition.Manual; this.Text = "<>"; this.Load += new System.EventHandler(this.OnFormLoad); this.Shown += new System.EventHandler(this.OnFormShown); this.Activated += new System.EventHandler(this.OnFormActivated); this.FormClosed += new System.Windows.Forms.FormClosedEventHandler(this.OnFormClosed); this.FormClosing += new System.Windows.Forms.FormClosingEventHandler(this.OnFormClosing); this.Resize += new System.EventHandler(this.OnFormResize); this.m_ctxGroupList.ResumeLayout(false); this.m_ctxPwList.ResumeLayout(false); this.m_menuMain.ResumeLayout(false); this.m_menuMain.PerformLayout(); this.m_toolMain.ResumeLayout(false); this.m_toolMain.PerformLayout(); this.m_statusMain.ResumeLayout(false); this.m_statusMain.PerformLayout(); this.m_ctxTray.ResumeLayout(false); this.m_splitHorizontal.Panel1.ResumeLayout(false); this.m_splitHorizontal.Panel2.ResumeLayout(false); this.m_splitHorizontal.ResumeLayout(false); this.m_splitVertical.Panel1.ResumeLayout(false); this.m_splitVertical.Panel2.ResumeLayout(false); this.m_splitVertical.ResumeLayout(false); this.ResumeLayout(false); this.PerformLayout(); } #endregion private KeePass.UI.CustomMenuStripEx m_menuMain; private System.Windows.Forms.ToolStripMenuItem m_menuFile; private System.Windows.Forms.ToolStripMenuItem m_menuFileNew; private System.Windows.Forms.ToolStripMenuItem m_menuFileClose; private System.Windows.Forms.ToolStripSeparator m_menuFileSep0; private System.Windows.Forms.ToolStripMenuItem m_menuFileSave; private System.Windows.Forms.ToolStripSeparator m_menuFileSep1; private System.Windows.Forms.ToolStripMenuItem m_menuFileDbSettings; private System.Windows.Forms.ToolStripMenuItem m_menuFileChangeMasterKey; private System.Windows.Forms.ToolStripSeparator m_menuFileSep2; private System.Windows.Forms.ToolStripMenuItem m_menuFilePrint; private System.Windows.Forms.ToolStripSeparator m_menuFileSep3; private System.Windows.Forms.ToolStripMenuItem m_menuFileExport; private System.Windows.Forms.ToolStripSeparator m_menuFileSep4; private System.Windows.Forms.ToolStripMenuItem m_menuFileLock; private System.Windows.Forms.ToolStripMenuItem m_menuFileExit; private System.Windows.Forms.ToolStripMenuItem m_menuEdit; private System.Windows.Forms.ToolStripMenuItem m_menuView; private System.Windows.Forms.ToolStripMenuItem m_menuTools; private System.Windows.Forms.ToolStripMenuItem m_menuHelp; private System.Windows.Forms.ToolStripMenuItem m_menuHelpWebsite; private System.Windows.Forms.ToolStripMenuItem m_menuHelpDonate; private System.Windows.Forms.ToolStripSeparator m_menuHelpSep0; private System.Windows.Forms.ToolStripMenuItem m_menuHelpContents; private System.Windows.Forms.ToolStripSeparator m_menuHelpSep1; private System.Windows.Forms.ToolStripMenuItem m_menuHelpCheckForUpdates; private System.Windows.Forms.ToolStripSeparator m_menuHelpSep2; private System.Windows.Forms.ToolStripMenuItem m_menuHelpAbout; private KeePass.UI.CustomToolStripEx m_toolMain; private System.Windows.Forms.ToolStripButton m_tbNewDatabase; private System.Windows.Forms.ToolStripButton m_tbOpenDatabase; private KeePass.UI.CustomRichTextBoxEx m_richEntryView; private KeePass.UI.CustomSplitContainerEx m_splitHorizontal; private KeePass.UI.CustomSplitContainerEx m_splitVertical; private KeePass.UI.CustomTreeViewEx m_tvGroups; private System.Windows.Forms.StatusStrip m_statusMain; private System.Windows.Forms.ToolStripStatusLabel m_statusPartSelected; private System.Windows.Forms.ToolStripStatusLabel m_statusPartInfo; private KeePass.UI.CustomListViewEx m_lvEntries; private System.Windows.Forms.ToolStripButton m_tbSaveDatabase; private KeePass.UI.CustomContextMenuStripEx m_ctxPwList; private System.Windows.Forms.ToolStripMenuItem m_ctxEntryCopyUserName; private System.Windows.Forms.ToolStripMenuItem m_ctxEntryCopyPassword; private System.Windows.Forms.ToolStripMenuItem m_ctxEntrySaveAttachedFiles; private System.Windows.Forms.ToolStripSeparator m_ctxEntrySep0; private System.Windows.Forms.ToolStripMenuItem m_ctxEntryPerformAutoType; private System.Windows.Forms.ToolStripSeparator m_ctxEntrySep1; private System.Windows.Forms.ToolStripMenuItem m_ctxEntryAdd; private System.Windows.Forms.ToolStripMenuItem m_ctxEntryEdit; private System.Windows.Forms.ToolStripMenuItem m_ctxEntryDuplicate; private System.Windows.Forms.ToolStripMenuItem m_ctxEntryDelete; private System.Windows.Forms.ToolStripMenuItem m_ctxEntryMassModify; private System.Windows.Forms.ToolStripMenuItem m_ctxEntrySelectAll; private System.Windows.Forms.ToolStripSeparator m_ctxEntrySep2; private System.Windows.Forms.ToolStripMenuItem m_ctxEntryRearrangePopup; private System.Windows.Forms.ToolStripMenuItem m_ctxEntryMoveToTop; private System.Windows.Forms.ToolStripMenuItem m_ctxEntryMoveOneUp; private System.Windows.Forms.ToolStripMenuItem m_ctxEntryMoveOneDown; private System.Windows.Forms.ToolStripMenuItem m_ctxEntryMoveToBottom; private System.Windows.Forms.ToolStripMenuItem m_menuChangeLanguage; private System.Windows.Forms.ToolStripSeparator m_tbSep0; private System.Windows.Forms.ToolStripMenuItem m_menuEditFind; private System.Windows.Forms.ToolStripSeparator m_menuViewSep0; private System.Windows.Forms.ToolStripMenuItem m_menuViewShowToolBar; private System.Windows.Forms.ToolStripMenuItem m_menuViewShowEntryView; private System.Windows.Forms.ToolStripSeparator m_tbSep1; private System.Windows.Forms.ToolStripButton m_tbFind; private System.Windows.Forms.ToolStripSeparator m_tbSep2; private System.Windows.Forms.ToolStripButton m_tbLockWorkspace; private System.Windows.Forms.ToolStripSeparator m_tbSep3; private System.Windows.Forms.ToolStripComboBox m_tbQuickFind; private System.Windows.Forms.ToolStripMenuItem m_menuToolsOptions; private System.Windows.Forms.ToolStripSeparator m_menuViewSep1; private KeePass.UI.CustomContextMenuStripEx m_ctxGroupList; private System.Windows.Forms.ToolStripMenuItem m_ctxGroupAdd; private System.Windows.Forms.ToolStripSeparator m_ctxGroupSep0; private System.Windows.Forms.ToolStripMenuItem m_ctxGroupEdit; private System.Windows.Forms.ToolStripMenuItem m_ctxGroupDelete; private System.Windows.Forms.ToolStripProgressBar m_statusPartProgress; private System.Windows.Forms.ToolStripMenuItem m_menuViewAlwaysOnTop; private System.Windows.Forms.ToolStripSeparator m_menuViewSep2; private System.Windows.Forms.ToolStripSeparator m_ctxGroupSep1; private System.Windows.Forms.ToolStripMenuItem m_ctxGroupPrint; private System.Windows.Forms.ToolStripMenuItem m_menuViewConfigColumns; private System.Windows.Forms.ToolStripSeparator m_menuViewSep3; private System.Windows.Forms.ToolStripMenuItem m_menuFileRecent; private KeePass.UI.CustomContextMenuStripEx m_ctxTray; private System.Windows.Forms.ToolStripMenuItem m_ctxTrayTray; private System.Windows.Forms.Timer m_timerMain; private System.Windows.Forms.ToolStripMenuItem m_menuToolsPlugins; private System.Windows.Forms.ToolStripMenuItem m_ctxEntryUrl; private System.Windows.Forms.ToolStripMenuItem m_ctxEntryOpenUrl; private System.Windows.Forms.ToolStripMenuItem m_ctxEntryCopyUrl; private System.Windows.Forms.ToolStripMenuItem m_ctxEntryMassSetIcon; private System.Windows.Forms.ToolStripMenuItem m_ctxGroupFind; private System.Windows.Forms.ToolStripSeparator m_ctxGroupSep2; private System.Windows.Forms.ToolStripMenuItem m_menuViewTanOptions; private System.Windows.Forms.ToolStripMenuItem m_menuViewTanSimpleList; private System.Windows.Forms.ToolStripMenuItem m_menuViewTanIndices; private System.Windows.Forms.ToolStripMenuItem m_menuToolsPwGenerator; private System.Windows.Forms.ToolStripSeparator m_menuToolsSep0; private System.Windows.Forms.ToolStripMenuItem m_menuToolsTanWizard; private System.Windows.Forms.ToolStripSeparator m_menuEditSep0; private System.Windows.Forms.ToolStripProgressBar m_statusClipboard; private System.Windows.Forms.ToolStripMenuItem m_ctxEntryClipboard; private System.Windows.Forms.ToolStripMenuItem m_ctxEntryClipCopy; private System.Windows.Forms.ToolStripMenuItem m_ctxEntryClipPaste; private System.Windows.Forms.ToolStripMenuItem m_ctxEntrySetColor; private System.Windows.Forms.ToolStripMenuItem m_ctxEntryColorStandard; private System.Windows.Forms.ToolStripSeparator m_ctxEntryColorSep0; private System.Windows.Forms.ToolStripMenuItem m_ctxEntryColorLightRed; private System.Windows.Forms.ToolStripMenuItem m_ctxEntryColorLightGreen; private System.Windows.Forms.ToolStripMenuItem m_ctxEntryColorLightBlue; private System.Windows.Forms.ToolStripMenuItem m_ctxEntryColorLightYellow; private System.Windows.Forms.ToolStripSeparator m_ctxEntryColorSep1; private System.Windows.Forms.ToolStripMenuItem m_ctxEntryColorCustom; private System.Windows.Forms.ToolStripDropDownButton m_tbEntryViewsDropDown; private System.Windows.Forms.ToolStripMenuItem m_tbViewsShowAll; private System.Windows.Forms.ToolStripMenuItem m_tbViewsShowExpired; private System.Windows.Forms.ToolStripSplitButton m_tbAddEntry; private System.Windows.Forms.ToolStripMenuItem m_tbAddEntryDefault; private System.Windows.Forms.ToolStripMenuItem m_ctxEntryCopyString; private System.Windows.Forms.ToolStripMenuItem m_menuToolsGeneratePwList; private System.Windows.Forms.ToolStripSeparator m_menuToolsSep1; private System.Windows.Forms.ToolStripMenuItem m_menuViewWindowLayout; private System.Windows.Forms.ToolStripMenuItem m_menuViewWindowsStacked; private System.Windows.Forms.ToolStripMenuItem m_menuViewWindowsSideBySide; private System.Windows.Forms.ToolStripButton m_tbCopyUserName; private System.Windows.Forms.ToolStripButton m_tbCopyPassword; private System.Windows.Forms.ToolStripSeparator m_tbSep4; private System.Windows.Forms.ToolStripMenuItem m_menuHelpSelectSource; private System.Windows.Forms.ToolStripMenuItem m_menuFileOpen; private System.Windows.Forms.ToolStripMenuItem m_menuFileOpenLocal; private System.Windows.Forms.ToolStripMenuItem m_menuFileOpenUrl; private System.Windows.Forms.ToolStripMenuItem m_menuFileSaveAs; private System.Windows.Forms.ToolStripMenuItem m_menuFileSaveAsLocal; private System.Windows.Forms.ToolStripMenuItem m_menuFileSaveAsUrl; private System.Windows.Forms.ToolStripMenuItem m_menuFileImport; private System.Windows.Forms.ToolStripSeparator m_ctxGroupSep3; private System.Windows.Forms.ToolStripMenuItem m_ctxGroupRearrange; private System.Windows.Forms.ToolStripMenuItem m_ctxGroupMoveToTop; private System.Windows.Forms.ToolStripMenuItem m_ctxGroupMoveOneUp; private System.Windows.Forms.ToolStripMenuItem m_ctxGroupMoveOneDown; private System.Windows.Forms.ToolStripMenuItem m_ctxGroupMoveToBottom; private System.Windows.Forms.ToolStripMenuItem m_ctxEntryAttachments; private System.Windows.Forms.ToolStripSeparator m_ctxEntryUrlSep0; private System.Windows.Forms.ToolStripMenuItem m_ctxEntryUrlOpenInInternal; private System.Windows.Forms.ToolStripSeparator m_ctxTraySep0; private System.Windows.Forms.ToolStripMenuItem m_ctxTrayFileExit; private System.Windows.Forms.TabControl m_tabMain; private System.Windows.Forms.ToolStripButton m_tbSaveAll; private System.Windows.Forms.ToolStripButton m_tbCloseTab; private System.Windows.Forms.ToolStripSeparator m_menuFileSaveAsSep0; private System.Windows.Forms.ToolStripMenuItem m_menuFileSaveAsCopy; private System.Windows.Forms.ToolStripSeparator m_ctxEntrySelectedSep0; private System.Windows.Forms.ToolStripMenuItem m_ctxEntrySelectedPrint; private System.Windows.Forms.ToolStripMenuItem m_menuViewShowEntriesOfSubGroups; private System.Windows.Forms.ToolStripMenuItem m_menuFileSync; private System.Windows.Forms.ToolStripMenuItem m_menuFileSyncFile; private System.Windows.Forms.ToolStripMenuItem m_menuFileSyncUrl; private System.Windows.Forms.ToolStripMenuItem m_ctxTrayLock; private System.Windows.Forms.ToolStripSeparator m_ctxTraySep1; private System.Windows.Forms.ToolStripMenuItem m_ctxGroupExport; private System.Windows.Forms.ToolStripMenuItem m_ctxEntrySelectedExport; private System.Windows.Forms.ToolStripSeparator m_menuFileSyncSep0; private System.Windows.Forms.ToolStripMenuItem m_menuFileSyncRecent; private System.Windows.Forms.ToolStripSeparator m_menuToolsSep2; private System.Windows.Forms.ToolStripMenuItem m_menuToolsTriggers; private System.Windows.Forms.ToolStripMenuItem m_menuEditShowByTag; private System.Windows.Forms.ToolStripMenuItem m_ctxEntrySelectedAddTag; private System.Windows.Forms.ToolStripMenuItem m_ctxEntrySelectedNewTag; private System.Windows.Forms.ToolStripSeparator m_ctxEntrySelectedSep1; private System.Windows.Forms.ToolStripMenuItem m_ctxEntrySelectedRemoveTag; private System.Windows.Forms.ToolStripMenuItem m_menuViewSortBy; private System.Windows.Forms.ToolStripSeparator m_ctxGroupRearrSep0; private System.Windows.Forms.ToolStripMenuItem m_ctxGroupSort; private System.Windows.Forms.ToolStripMenuItem m_ctxGroupSortRec; private System.Windows.Forms.ToolStripMenuItem m_ctxGroupEmpty; private System.Windows.Forms.ToolStripMenuItem m_menuToolsDb; private System.Windows.Forms.ToolStripMenuItem m_menuToolsDbMaintenance; private System.Windows.Forms.ToolStripMenuItem m_menuToolsDbDelDupEntries; private System.Windows.Forms.ToolStripSeparator m_menuToolsDbSep0; private System.Windows.Forms.ToolStripMenuItem m_menuToolsDbDelEmptyGroups; private System.Windows.Forms.ToolStripMenuItem m_menuToolsDbDelUnusedIcons; private System.Windows.Forms.ToolStripMenuItem m_ctxTrayOptions; private System.Windows.Forms.ToolStripMenuItem m_menuViewEntryListGrouping; private System.Windows.Forms.ToolStripSeparator m_ctxTraySep2; private System.Windows.Forms.ToolStripMenuItem m_ctxTrayGenPw; private System.Windows.Forms.ToolStripMenuItem m_ctxGroupDuplicate; private System.Windows.Forms.ToolStripSplitButton m_tbOpenUrl; private System.Windows.Forms.ToolStripMenuItem m_tbOpenUrlDefault; private System.Windows.Forms.ToolStripButton m_tbCopyUrl; private System.Windows.Forms.ToolStripButton m_tbAutoType; private System.Windows.Forms.ToolStripSeparator m_menuToolsDbSep1; private System.Windows.Forms.ToolStripMenuItem m_menuToolsDbXmlRep; private System.Windows.Forms.ToolStripMenuItem m_menuFileRecentDummy; private System.Windows.Forms.ToolStripMenuItem m_menuFileSyncRecentDummy; private System.Windows.Forms.ToolStripSeparator m_ctxEntrySelectedSep2; private System.Windows.Forms.ToolStripMenuItem m_ctxEntryMoveToGroup; private System.Windows.Forms.ToolStripSeparator m_ctxGroupRearrSep1; private System.Windows.Forms.ToolStripMenuItem m_ctxGroupExpand; private System.Windows.Forms.ToolStripMenuItem m_ctxGroupCollapse; private System.Windows.Forms.ToolStripMenuItem m_menuEditShowEntries; private System.Windows.Forms.ToolStripMenuItem m_menuEditShowAll; private System.Windows.Forms.ToolStripSeparator m_menuEditShowSep0; private System.Windows.Forms.ToolStripMenuItem m_menuEditShowExp; private System.Windows.Forms.ToolStripMenuItem m_menuEditShowExp1; private System.Windows.Forms.ToolStripMenuItem m_menuEditShowExp2; private System.Windows.Forms.ToolStripMenuItem m_menuEditShowExp3; private System.Windows.Forms.ToolStripMenuItem m_menuEditShowExp7; private System.Windows.Forms.ToolStripMenuItem m_menuEditShowExp14; private System.Windows.Forms.ToolStripMenuItem m_menuEditShowExp28; private System.Windows.Forms.ToolStripMenuItem m_menuEditShowExpInF; private System.Windows.Forms.ToolStripMenuItem m_menuEditShowExp56; private System.Windows.Forms.ToolStripSeparator m_menuEditShowSep1; private System.Windows.Forms.ToolStripMenuItem m_menuEditShowParentGroup; private System.Windows.Forms.ToolStripMenuItem m_ctxEntryShowParentGroup; private System.Windows.Forms.ToolStripMenuItem m_ctxEntryAutoTypeAdv; private System.Windows.Forms.ToolStripMenuItem m_menuEditFindDupPasswords; private System.Windows.Forms.ToolStripMenuItem m_menuEditPwQualityReport; private System.Windows.Forms.ToolStripMenuItem m_menuEditFindSimPasswordsP; private System.Windows.Forms.ToolStripMenuItem m_menuEditFindSimPasswordsC; private System.Windows.Forms.ToolStripSeparator m_menuToolsDbSep2; private System.Windows.Forms.ToolStripMenuItem m_menuToolsPrintEmSheet; } } KeePass/Forms/AutoTypeCtxForm.Designer.cs0000664000000000000000000001541212501526634017351 0ustar rootrootnamespace KeePass.Forms { partial class AutoTypeCtxForm { /// /// Required designer variable. /// private System.ComponentModel.IContainer components = null; /// /// Clean up any resources being used. /// /// true if managed resources should be disposed; otherwise, false. protected override void Dispose(bool disposing) { if(disposing && (components != null)) { components.Dispose(); } base.Dispose(disposing); } #region Windows Form Designer generated code /// /// Required method for Designer support - do not modify /// the contents of this method with the code editor. /// private void InitializeComponent() { this.m_bannerImage = new System.Windows.Forms.PictureBox(); this.m_lblText = new System.Windows.Forms.Label(); this.m_btnCancel = new System.Windows.Forms.Button(); this.m_lvItems = new KeePass.UI.CustomListViewEx(); this.m_pnlTop = new System.Windows.Forms.Panel(); this.m_pnlBottom = new System.Windows.Forms.Panel(); this.m_btnTools = new System.Windows.Forms.Button(); this.m_pnlMiddle = new System.Windows.Forms.Panel(); ((System.ComponentModel.ISupportInitialize)(this.m_bannerImage)).BeginInit(); this.m_pnlTop.SuspendLayout(); this.m_pnlBottom.SuspendLayout(); this.m_pnlMiddle.SuspendLayout(); this.SuspendLayout(); // // m_bannerImage // this.m_bannerImage.Dock = System.Windows.Forms.DockStyle.Top; this.m_bannerImage.Location = new System.Drawing.Point(0, 0); this.m_bannerImage.Name = "m_bannerImage"; this.m_bannerImage.Size = new System.Drawing.Size(579, 60); this.m_bannerImage.TabIndex = 0; this.m_bannerImage.TabStop = false; // // m_lblText // this.m_lblText.Dock = System.Windows.Forms.DockStyle.Fill; this.m_lblText.Location = new System.Drawing.Point(9, 11); this.m_lblText.Name = "m_lblText"; this.m_lblText.Size = new System.Drawing.Size(561, 30); this.m_lblText.TabIndex = 0; this.m_lblText.Text = "<>"; // // m_btnCancel // this.m_btnCancel.DialogResult = System.Windows.Forms.DialogResult.Cancel; this.m_btnCancel.Dock = System.Windows.Forms.DockStyle.Right; this.m_btnCancel.Location = new System.Drawing.Point(492, 6); this.m_btnCancel.Name = "m_btnCancel"; this.m_btnCancel.Size = new System.Drawing.Size(75, 23); this.m_btnCancel.TabIndex = 0; this.m_btnCancel.Text = "Cancel"; this.m_btnCancel.UseVisualStyleBackColor = true; // // m_lvItems // this.m_lvItems.Activation = System.Windows.Forms.ItemActivation.OneClick; this.m_lvItems.Dock = System.Windows.Forms.DockStyle.Fill; this.m_lvItems.FullRowSelect = true; this.m_lvItems.HeaderStyle = System.Windows.Forms.ColumnHeaderStyle.Nonclickable; this.m_lvItems.HideSelection = false; this.m_lvItems.HotTracking = true; this.m_lvItems.HoverSelection = true; this.m_lvItems.Location = new System.Drawing.Point(12, 0); this.m_lvItems.MultiSelect = false; this.m_lvItems.Name = "m_lvItems"; this.m_lvItems.ShowItemToolTips = true; this.m_lvItems.Size = new System.Drawing.Size(555, 219); this.m_lvItems.TabIndex = 0; this.m_lvItems.UseCompatibleStateImageBehavior = false; this.m_lvItems.View = System.Windows.Forms.View.Details; this.m_lvItems.ItemActivate += new System.EventHandler(this.OnListItemActivate); this.m_lvItems.Click += new System.EventHandler(this.OnListClick); // // m_pnlTop // this.m_pnlTop.Controls.Add(this.m_lblText); this.m_pnlTop.Dock = System.Windows.Forms.DockStyle.Top; this.m_pnlTop.Location = new System.Drawing.Point(0, 60); this.m_pnlTop.Name = "m_pnlTop"; this.m_pnlTop.Padding = new System.Windows.Forms.Padding(9, 11, 9, 3); this.m_pnlTop.Size = new System.Drawing.Size(579, 44); this.m_pnlTop.TabIndex = 1; // // m_pnlBottom // this.m_pnlBottom.Controls.Add(this.m_btnTools); this.m_pnlBottom.Controls.Add(this.m_btnCancel); this.m_pnlBottom.Dock = System.Windows.Forms.DockStyle.Bottom; this.m_pnlBottom.Location = new System.Drawing.Point(0, 323); this.m_pnlBottom.Name = "m_pnlBottom"; this.m_pnlBottom.Padding = new System.Windows.Forms.Padding(12, 6, 12, 12); this.m_pnlBottom.Size = new System.Drawing.Size(579, 41); this.m_pnlBottom.TabIndex = 2; // // m_btnTools // this.m_btnTools.Dock = System.Windows.Forms.DockStyle.Left; this.m_btnTools.Location = new System.Drawing.Point(12, 6); this.m_btnTools.Name = "m_btnTools"; this.m_btnTools.Size = new System.Drawing.Size(75, 23); this.m_btnTools.TabIndex = 1; this.m_btnTools.Text = "&Options"; this.m_btnTools.UseVisualStyleBackColor = true; this.m_btnTools.Click += new System.EventHandler(this.OnBtnTools); // // m_pnlMiddle // this.m_pnlMiddle.Controls.Add(this.m_lvItems); this.m_pnlMiddle.Dock = System.Windows.Forms.DockStyle.Fill; this.m_pnlMiddle.Location = new System.Drawing.Point(0, 104); this.m_pnlMiddle.Name = "m_pnlMiddle"; this.m_pnlMiddle.Padding = new System.Windows.Forms.Padding(12, 0, 12, 0); this.m_pnlMiddle.Size = new System.Drawing.Size(579, 219); this.m_pnlMiddle.TabIndex = 0; // // AutoTypeCtxForm // this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F); this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; this.CancelButton = this.m_btnCancel; this.ClientSize = new System.Drawing.Size(579, 364); this.Controls.Add(this.m_pnlMiddle); this.Controls.Add(this.m_pnlBottom); this.Controls.Add(this.m_pnlTop); this.Controls.Add(this.m_bannerImage); this.MaximizeBox = false; this.MinimizeBox = false; this.Name = "AutoTypeCtxForm"; this.StartPosition = System.Windows.Forms.FormStartPosition.CenterScreen; this.Text = "<>"; this.Load += new System.EventHandler(this.OnFormLoad); this.FormClosed += new System.Windows.Forms.FormClosedEventHandler(this.OnFormClosed); this.Resize += new System.EventHandler(this.OnFormResize); ((System.ComponentModel.ISupportInitialize)(this.m_bannerImage)).EndInit(); this.m_pnlTop.ResumeLayout(false); this.m_pnlBottom.ResumeLayout(false); this.m_pnlMiddle.ResumeLayout(false); this.ResumeLayout(false); } #endregion private System.Windows.Forms.PictureBox m_bannerImage; private System.Windows.Forms.Label m_lblText; private KeePass.UI.CustomListViewEx m_lvItems; private System.Windows.Forms.Button m_btnCancel; private System.Windows.Forms.Panel m_pnlTop; private System.Windows.Forms.Panel m_pnlBottom; private System.Windows.Forms.Panel m_pnlMiddle; private System.Windows.Forms.Button m_btnTools; } }KeePass/Forms/StatusLoggerForm.Designer.cs0000664000000000000000000001003712501532366017540 0ustar rootrootnamespace KeePass.Forms { partial class StatusLoggerForm { /// /// Erforderliche Designervariable. /// private System.ComponentModel.IContainer components = null; /// /// Verwendete Ressourcen bereinigen. /// /// True, wenn verwaltete Ressourcen gelöscht werden sollen; andernfalls False. protected override void Dispose(bool disposing) { if(disposing && (components != null)) { components.Dispose(); } base.Dispose(disposing); } #region Vom Windows Form-Designer generierter Code /// /// Erforderliche Methode für die Designerunterstützung. /// Der Inhalt der Methode darf nicht mit dem Code-Editor geändert werden. /// private void InitializeComponent() { this.m_btnCancel = new System.Windows.Forms.Button(); this.m_lvMessages = new KeePass.UI.CustomListViewEx(); this.m_pbProgress = new System.Windows.Forms.ProgressBar(); this.m_tbDetails = new System.Windows.Forms.TextBox(); this.SuspendLayout(); // // m_btnCancel // this.m_btnCancel.DialogResult = System.Windows.Forms.DialogResult.Cancel; this.m_btnCancel.Location = new System.Drawing.Point(392, 276); this.m_btnCancel.Name = "m_btnCancel"; this.m_btnCancel.Size = new System.Drawing.Size(75, 23); this.m_btnCancel.TabIndex = 0; this.m_btnCancel.Text = "Cancel"; this.m_btnCancel.UseVisualStyleBackColor = true; this.m_btnCancel.Click += new System.EventHandler(this.OnBtnCancel); // // m_lvMessages // this.m_lvMessages.FullRowSelect = true; this.m_lvMessages.HeaderStyle = System.Windows.Forms.ColumnHeaderStyle.None; this.m_lvMessages.Location = new System.Drawing.Point(12, 12); this.m_lvMessages.MultiSelect = false; this.m_lvMessages.Name = "m_lvMessages"; this.m_lvMessages.Size = new System.Drawing.Size(455, 134); this.m_lvMessages.TabIndex = 1; this.m_lvMessages.UseCompatibleStateImageBehavior = false; this.m_lvMessages.View = System.Windows.Forms.View.Details; this.m_lvMessages.SelectedIndexChanged += new System.EventHandler(this.OnMessagesSelectedIndexChanged); // // m_pbProgress // this.m_pbProgress.Location = new System.Drawing.Point(12, 152); this.m_pbProgress.Name = "m_pbProgress"; this.m_pbProgress.Size = new System.Drawing.Size(455, 17); this.m_pbProgress.TabIndex = 2; // // m_tbDetails // this.m_tbDetails.Location = new System.Drawing.Point(12, 175); this.m_tbDetails.Multiline = true; this.m_tbDetails.Name = "m_tbDetails"; this.m_tbDetails.ReadOnly = true; this.m_tbDetails.ScrollBars = System.Windows.Forms.ScrollBars.Vertical; this.m_tbDetails.Size = new System.Drawing.Size(455, 95); this.m_tbDetails.TabIndex = 3; // // StatusLoggerForm // this.AcceptButton = this.m_btnCancel; this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F); this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; this.CancelButton = this.m_btnCancel; this.ClientSize = new System.Drawing.Size(479, 311); this.Controls.Add(this.m_tbDetails); this.Controls.Add(this.m_pbProgress); this.Controls.Add(this.m_lvMessages); this.Controls.Add(this.m_btnCancel); this.FormBorderStyle = System.Windows.Forms.FormBorderStyle.FixedDialog; this.MaximizeBox = false; this.MinimizeBox = false; this.Name = "StatusLoggerForm"; this.ShowInTaskbar = false; this.StartPosition = System.Windows.Forms.FormStartPosition.CenterScreen; this.Text = "<>"; this.Load += new System.EventHandler(this.OnFormLoad); this.FormClosed += new System.Windows.Forms.FormClosedEventHandler(this.OnFormClosed); this.ResumeLayout(false); this.PerformLayout(); } #endregion private System.Windows.Forms.Button m_btnCancel; private KeePass.UI.CustomListViewEx m_lvMessages; private System.Windows.Forms.ProgressBar m_pbProgress; private System.Windows.Forms.TextBox m_tbDetails; } }KeePass/Forms/InternalBrowserForm.cs0000664000000000000000000000725413222430410016471 0ustar rootroot/* KeePass Password Safe - The Open-Source Password Manager Copyright (C) 2003-2018 Dominik Reichl This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ using System; using System.Collections.Generic; using System.ComponentModel; using System.Diagnostics; using System.Drawing; using System.Text; using System.Windows.Forms; using KeePass.App; using KeePass.UI; using KeePassLib; namespace KeePass.Forms { public partial class InternalBrowserForm : Form { private string m_strInitialUrl = string.Empty; // private PwGroup m_pgDataSource = null; // See InitEx public void InitEx(string strUrl, PwGroup pgDataSource) { if(strUrl != null) m_strInitialUrl = strUrl; // m_pgDataSource = pgDataSource; // Not used yet } public InternalBrowserForm() { InitializeComponent(); Program.Translation.ApplyTo(this); } private void OnFormLoad(object sender, EventArgs e) { GlobalWindowManager.AddWindow(this); this.Icon = AppIcons.Default; if(m_strInitialUrl.Length > 0) m_webBrowser.Navigate(m_strInitialUrl); ProcessResize(); UpdateUIState(); } private void OnFormClosing(object sender, FormClosingEventArgs e) { GlobalWindowManager.RemoveWindow(this); } private void UpdateUIState() { m_btnBack.Enabled = m_webBrowser.CanGoBack; m_btnForward.Enabled = m_webBrowser.CanGoForward; string strTitle = m_webBrowser.DocumentTitle; if(strTitle.Length > 0) strTitle += " - "; this.Text = strTitle + PwDefs.ShortProductName; } private void ProcessResize() { int nWidth = m_toolNav.ClientRectangle.Width; int nRight = m_btnGo.Bounds.X + m_btnGo.Bounds.Width; Size size = new Size(m_tbUrl.Size.Width, m_tbUrl.Size.Height); size.Width += nWidth - nRight - 2; m_tbUrl.Size = size; } private static void DoAutoFill() // Remove static when implementing { } private void OnBtnBack(object sender, EventArgs e) { m_webBrowser.GoBack(); } private void OnBtnForward(object sender, EventArgs e) { m_webBrowser.GoForward(); } private void OnBtnReload(object sender, EventArgs e) { m_webBrowser.Refresh(WebBrowserRefreshOption.Completely); } private void OnBtnStop(object sender, EventArgs e) { m_webBrowser.Stop(); } private void OnBtnGo(object sender, EventArgs e) { m_webBrowser.Navigate(m_tbUrl.Text); } private void OnWbNavigated(object sender, WebBrowserNavigatedEventArgs e) { UpdateUIState(); } private void OnWbDocumentCompleted(object sender, WebBrowserDocumentCompletedEventArgs e) { m_tbUrl.Text = e.Url.ToString(); DoAutoFill(); UpdateUIState(); } private void OnTbUrlKeyDown(object sender, KeyEventArgs e) { if((e.KeyCode == Keys.Enter) || (e.KeyCode == Keys.Return)) { UIUtil.SetHandled(e, true); OnBtnGo(sender, e); } } private void OnFormSizeChanged(object sender, EventArgs e) { ProcessResize(); } } }KeePass/Forms/StatusLoggerForm.resx0000664000000000000000000001326612501532366016364 0ustar rootroot text/microsoft-resx 2.0 System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 KeePass/Forms/PwEntryForm.resx0000664000000000000000000001641312760322670015350 0ustar rootroot text/microsoft-resx 2.0 System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 372, 17 17, 17 113, 17 642, 17 487, 54 667, 54 17, 43 135, 46 KeePass/Forms/LanguageForm.resx0000664000000000000000000001326613217213726015465 0ustar rootroot text/microsoft-resx 2.0 System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 KeePass/Forms/AboutForm.resx0000664000000000000000000001326612501526572015015 0ustar rootroot text/microsoft-resx 2.0 System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 KeePass/Forms/OptionsForm.resx0000664000000000000000000001326613110047772015373 0ustar rootroot text/microsoft-resx 2.0 System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 KeePass/Forms/EcasConditionForm.resx0000664000000000000000000001326612501527700016457 0ustar rootroot text/microsoft-resx 2.0 System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 KeePass/Forms/DatabaseSettingsForm.cs0000664000000000000000000006751313222430410016602 0ustar rootroot/* KeePass Password Safe - The Open-Source Password Manager Copyright (C) 2003-2018 Dominik Reichl This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ using System; using System.Collections.Generic; using System.ComponentModel; using System.Diagnostics; using System.Drawing; using System.Text; using System.Threading; using System.Windows.Forms; using KeePass.App; using KeePass.App.Configuration; using KeePass.Resources; using KeePass.UI; using KeePassLib; using KeePassLib.Cryptography.Cipher; using KeePassLib.Cryptography.KeyDerivation; using KeePassLib.Delegates; using KeePassLib.Keys; using KeePassLib.Security; using KeePassLib.Utility; namespace KeePass.Forms { public partial class DatabaseSettingsForm : Form { private bool m_bCreatingNew = false; private PwDatabase m_pwDatabase = null; private Color m_clr = Color.Empty; private CustomContextMenuEx m_ctxColor = null; private List m_vColorItems = new List(); private Image m_imgColor = null; private string m_strAutoCreateNew = "(" + KPRes.AutoCreateNew + ")"; private Dictionary m_dictRecycleBinGroups = new Dictionary(); private Dictionary m_dictEntryTemplateGroups = new Dictionary(); private bool m_bInitializing = true; private volatile Thread m_thKdf = null; public PwDatabase DatabaseEx { get { return m_pwDatabase; } } public DatabaseSettingsForm() { InitializeComponent(); Program.Translation.ApplyTo(this); } public void InitEx(bool bCreatingNew, PwDatabase pwDatabase) { m_bCreatingNew = bCreatingNew; Debug.Assert(pwDatabase != null); if(pwDatabase == null) throw new ArgumentNullException("pwDatabase"); m_pwDatabase = pwDatabase; } private void OnFormLoad(object sender, EventArgs e) { Debug.Assert(m_pwDatabase != null); if(m_pwDatabase == null) throw new InvalidOperationException(); m_bInitializing = true; GlobalWindowManager.AddWindow(this); BannerFactory.CreateBannerEx(this, m_bannerImage, Properties.Resources.B48x48_Ark, KPRes.DatabaseSettings, KPRes.DatabaseSettingsDesc); this.Icon = AppIcons.Default; FontUtil.AssignDefaultItalic(m_lblHeaderCpAlgo); FontUtil.AssignDefaultItalic(m_lblHeaderCp); FontUtil.AssignDefaultItalic(m_lblHeaderPerf); FontUtil.AssignDefaultBold(m_rbNone); FontUtil.AssignDefaultBold(m_rbGZip); UIUtil.ConfigureToolTip(m_ttRect); m_ttRect.SetToolTip(m_btnKdf1Sec, KPRes.KdfParams1Sec); m_tbDbName.PromptText = KPRes.DatabaseNamePrompt; m_tbDbDesc.PromptText = KPRes.DatabaseDescPrompt; if(m_bCreatingNew) this.Text = KPRes.ConfigureOnNewDatabase2; else this.Text = KPRes.DatabaseSettings; m_tbDbName.Text = m_pwDatabase.Name; UIUtil.SetMultilineText(m_tbDbDesc, m_pwDatabase.Description); m_tbDefaultUser.Text = m_pwDatabase.DefaultUserName; m_clr = m_pwDatabase.Color; if(m_clr != Color.Empty) { m_clr = AppIcons.RoundColor(m_clr); UIUtil.OverwriteButtonImage(m_btnColor, ref m_imgColor, UIUtil.CreateColorBitmap24(m_btnColor, m_clr)); } m_cbColor.Checked = (m_clr != Color.Empty); for(int inx = 0; inx < CipherPool.GlobalPool.EngineCount; ++inx) m_cmbEncAlgo.Items.Add(CipherPool.GlobalPool[inx].DisplayName); if(m_cmbEncAlgo.Items.Count > 0) { int nIndex = CipherPool.GlobalPool.GetCipherIndex(m_pwDatabase.DataCipherUuid); m_cmbEncAlgo.SelectedIndex = ((nIndex >= 0) ? nIndex : 0); } Debug.Assert(m_cmbKdf.Items.Count == 0); foreach(KdfEngine kdf in KdfPool.Engines) { m_cmbKdf.Items.Add(kdf.Name); } m_numKdfIt.Minimum = ulong.MinValue; m_numKdfIt.Maximum = ulong.MaxValue; m_numKdfMem.Minimum = ulong.MinValue; m_numKdfMem.Maximum = ulong.MaxValue; Debug.Assert(m_cmbKdfMem.Items.Count == 0); Debug.Assert(!m_cmbKdfMem.Sorted); m_cmbKdfMem.Items.Add("B"); m_cmbKdfMem.Items.Add("KB"); m_cmbKdfMem.Items.Add("MB"); m_cmbKdfMem.Items.Add("GB"); m_numKdfPar.Minimum = uint.MinValue; m_numKdfPar.Maximum = uint.MaxValue; SetKdfParameters(m_pwDatabase.KdfParameters); // m_lbMemProt.Items.Add(KPRes.Title, m_pwDatabase.MemoryProtection.ProtectTitle); // m_lbMemProt.Items.Add(KPRes.UserName, m_pwDatabase.MemoryProtection.ProtectUserName); // m_lbMemProt.Items.Add(KPRes.Password, m_pwDatabase.MemoryProtection.ProtectPassword); // m_lbMemProt.Items.Add(KPRes.Url, m_pwDatabase.MemoryProtection.ProtectUrl); // m_lbMemProt.Items.Add(KPRes.Notes, m_pwDatabase.MemoryProtection.ProtectNotes); // m_cbAutoEnableHiding.Checked = m_pwDatabase.MemoryProtection.AutoEnableVisualHiding; // m_cbAutoEnableHiding.Checked = false; if(m_pwDatabase.Compression == PwCompressionAlgorithm.None) m_rbNone.Checked = true; else if(m_pwDatabase.Compression == PwCompressionAlgorithm.GZip) m_rbGZip.Checked = true; else { Debug.Assert(false); } InitRecycleBinTab(); InitAdvancedTab(); m_bInitializing = false; EnableControlsEx(); } private void InitRecycleBinTab() { m_cbRecycleBin.Checked = m_pwDatabase.RecycleBinEnabled; m_cmbRecycleBin.Items.Add(m_strAutoCreateNew); m_dictRecycleBinGroups[0] = PwUuid.Zero; int iSelect; UIUtil.CreateGroupList(m_pwDatabase.RootGroup, m_cmbRecycleBin, m_dictRecycleBinGroups, m_pwDatabase.RecycleBinUuid, out iSelect); m_cmbRecycleBin.SelectedIndex = Math.Max(0, iSelect); } private void InitAdvancedTab() { m_cmbEntryTemplates.Items.Add("(" + KPRes.None + ")"); m_dictEntryTemplateGroups[0] = PwUuid.Zero; int iSelect; UIUtil.CreateGroupList(m_pwDatabase.RootGroup, m_cmbEntryTemplates, m_dictEntryTemplateGroups, m_pwDatabase.EntryTemplatesGroup, out iSelect); m_cmbEntryTemplates.SelectedIndex = Math.Max(0, iSelect); m_numHistoryMaxItems.Minimum = 0; m_numHistoryMaxItems.Maximum = int.MaxValue; bool bHistMaxItems = (m_pwDatabase.HistoryMaxItems >= 0); m_numHistoryMaxItems.Value = (bHistMaxItems ? m_pwDatabase.HistoryMaxItems : PwDatabase.DefaultHistoryMaxItems); m_cbHistoryMaxItems.Checked = bHistMaxItems; m_numHistoryMaxSize.Minimum = 0; m_numHistoryMaxSize.Maximum = long.MaxValue / (1024 * 1024); bool bHistMaxSize = (m_pwDatabase.HistoryMaxSize >= 0); m_numHistoryMaxSize.Value = (bHistMaxSize ? m_pwDatabase.HistoryMaxSize : PwDatabase.DefaultHistoryMaxSize) / (1024 * 1024); m_cbHistoryMaxSize.Checked = bHistMaxSize; m_numKeyRecDays.Minimum = 0; m_numKeyRecDays.Maximum = long.MaxValue; bool bChangeRec = (m_pwDatabase.MasterKeyChangeRec >= 0); m_numKeyRecDays.Value = (bChangeRec ? m_pwDatabase.MasterKeyChangeRec : 182); m_cbKeyRec.Checked = bChangeRec; m_numKeyForceDays.Minimum = 0; m_numKeyForceDays.Maximum = long.MaxValue; bool bChangeForce = (m_pwDatabase.MasterKeyChangeForce >= 0); m_numKeyForceDays.Value = (bChangeForce ? m_pwDatabase.MasterKeyChangeForce : 365); m_cbKeyForce.Checked = bChangeForce; m_cbKeyForceOnce.Checked = m_pwDatabase.MasterKeyChangeForceOnce; } private void EnableControlsEx() { if(m_bInitializing) return; m_btnColor.Enabled = m_cbColor.Checked; KdfEngine kdf = GetKdf(); if(kdf != null) { if(kdf is AesKdf) { m_lblKdfMem.Visible = false; m_numKdfMem.Visible = false; m_cmbKdfMem.Visible = false; m_lblKdfPar.Visible = false; m_numKdfPar.Visible = false; } else if(kdf is Argon2Kdf) { m_lblKdfMem.Visible = true; m_numKdfMem.Visible = true; m_cmbKdfMem.Visible = true; m_lblKdfPar.Visible = true; m_numKdfPar.Visible = true; } // else { Debug.Assert(false); } // Plugins may provide controls } else { Debug.Assert(false); } m_numHistoryMaxItems.Enabled = m_cbHistoryMaxItems.Checked; m_numHistoryMaxSize.Enabled = m_cbHistoryMaxSize.Checked; bool bEnableDays = ((Program.Config.UI.UIFlags & (ulong)AceUIFlags.DisableKeyChangeDays) == 0); m_numKeyRecDays.Enabled = (bEnableDays && m_cbKeyRec.Checked); m_numKeyForceDays.Enabled = (bEnableDays && m_cbKeyForce.Checked); m_cbKeyRec.Enabled = bEnableDays; m_cbKeyForce.Enabled = bEnableDays; m_cbKeyForceOnce.Enabled = bEnableDays; bool bKdfTh = (m_thKdf != null); m_tabMain.Enabled = !bKdfTh; m_pbKdf.Visible = bKdfTh; m_btnHelp.Enabled = !bKdfTh; m_btnCancelOp.Enabled = bKdfTh; m_btnCancelOp.Visible = bKdfTh; m_btnOK.Enabled = !bKdfTh; m_btnCancel.Enabled = !bKdfTh; } private void OnBtnOK(object sender, EventArgs e) { m_pwDatabase.SettingsChanged = DateTime.UtcNow; if(!m_tbDbName.Text.Equals(m_pwDatabase.Name)) { m_pwDatabase.Name = m_tbDbName.Text; m_pwDatabase.NameChanged = DateTime.UtcNow; } string strNew = m_tbDbDesc.Text; string strOrgFlt = StrUtil.NormalizeNewLines(m_pwDatabase.Description, false); string strNewFlt = StrUtil.NormalizeNewLines(strNew, false); if(!strNewFlt.Equals(strOrgFlt)) { m_pwDatabase.Description = strNew; m_pwDatabase.DescriptionChanged = DateTime.UtcNow; } if(!m_tbDefaultUser.Text.Equals(m_pwDatabase.DefaultUserName)) { m_pwDatabase.DefaultUserName = m_tbDefaultUser.Text; m_pwDatabase.DefaultUserNameChanged = DateTime.UtcNow; } if(!m_cbColor.Checked) m_pwDatabase.Color = Color.Empty; else m_pwDatabase.Color = m_clr; int nCipher = CipherPool.GlobalPool.GetCipherIndex(m_cmbEncAlgo.Text); Debug.Assert(nCipher >= 0); if(nCipher >= 0) m_pwDatabase.DataCipherUuid = CipherPool.GlobalPool[nCipher].CipherUuid; else m_pwDatabase.DataCipherUuid = StandardAesEngine.AesUuid; // m_pwDatabase.KeyEncryptionRounds = (ulong)m_numKdfIt.Value; KdfParameters pKdf = GetKdfParameters(true); if(pKdf != null) m_pwDatabase.KdfParameters = pKdf; // No assert, plugins may assign KDF parameters if(m_rbNone.Checked) m_pwDatabase.Compression = PwCompressionAlgorithm.None; else if(m_rbGZip.Checked) m_pwDatabase.Compression = PwCompressionAlgorithm.GZip; else { Debug.Assert(false); } // m_pwDatabase.MemoryProtection.ProtectTitle = UpdateMemoryProtection(0, // m_pwDatabase.MemoryProtection.ProtectTitle, PwDefs.TitleField); // m_pwDatabase.MemoryProtection.ProtectUserName = UpdateMemoryProtection(1, // m_pwDatabase.MemoryProtection.ProtectUserName, PwDefs.UserNameField); // m_pwDatabase.MemoryProtection.ProtectPassword = UpdateMemoryProtection(2, // m_pwDatabase.MemoryProtection.ProtectPassword, PwDefs.PasswordField); // m_pwDatabase.MemoryProtection.ProtectUrl = UpdateMemoryProtection(3, // m_pwDatabase.MemoryProtection.ProtectUrl, PwDefs.UrlField); // m_pwDatabase.MemoryProtection.ProtectNotes = UpdateMemoryProtection(4, // m_pwDatabase.MemoryProtection.ProtectNotes, PwDefs.NotesField); // m_pwDatabase.MemoryProtection.AutoEnableVisualHiding = m_cbAutoEnableHiding.Checked; if(m_cbRecycleBin.Checked != m_pwDatabase.RecycleBinEnabled) { m_pwDatabase.RecycleBinEnabled = m_cbRecycleBin.Checked; m_pwDatabase.RecycleBinChanged = DateTime.UtcNow; } int iRecBinSel = m_cmbRecycleBin.SelectedIndex; if(m_dictRecycleBinGroups.ContainsKey(iRecBinSel)) { if(!m_dictRecycleBinGroups[iRecBinSel].Equals(m_pwDatabase.RecycleBinUuid)) { m_pwDatabase.RecycleBinUuid = m_dictRecycleBinGroups[iRecBinSel]; m_pwDatabase.RecycleBinChanged = DateTime.UtcNow; } } else { Debug.Assert(false); if(!PwUuid.Zero.Equals(m_pwDatabase.RecycleBinUuid)) { m_pwDatabase.RecycleBinUuid = PwUuid.Zero; m_pwDatabase.RecycleBinChanged = DateTime.UtcNow; } } int iTemplSel = m_cmbEntryTemplates.SelectedIndex; if(m_dictEntryTemplateGroups.ContainsKey(iTemplSel)) { if(!m_dictEntryTemplateGroups[iTemplSel].Equals(m_pwDatabase.EntryTemplatesGroup)) { m_pwDatabase.EntryTemplatesGroup = m_dictEntryTemplateGroups[iTemplSel]; m_pwDatabase.EntryTemplatesGroupChanged = DateTime.UtcNow; } } else { Debug.Assert(false); if(!PwUuid.Zero.Equals(m_pwDatabase.EntryTemplatesGroup)) { m_pwDatabase.EntryTemplatesGroup = PwUuid.Zero; m_pwDatabase.EntryTemplatesGroupChanged = DateTime.UtcNow; } } if(!m_cbHistoryMaxItems.Checked) m_pwDatabase.HistoryMaxItems = -1; else m_pwDatabase.HistoryMaxItems = (int)m_numHistoryMaxItems.Value; if(!m_cbHistoryMaxSize.Checked) m_pwDatabase.HistoryMaxSize = -1; else m_pwDatabase.HistoryMaxSize = (long)m_numHistoryMaxSize.Value * 1024 * 1024; m_pwDatabase.MaintainBackups(); // Apply new history settings if(!m_cbKeyRec.Checked) m_pwDatabase.MasterKeyChangeRec = -1; else m_pwDatabase.MasterKeyChangeRec = (long)m_numKeyRecDays.Value; if(!m_cbKeyForce.Checked) m_pwDatabase.MasterKeyChangeForce = -1; else m_pwDatabase.MasterKeyChangeForce = (long)m_numKeyForceDays.Value; m_pwDatabase.MasterKeyChangeForceOnce = m_cbKeyForceOnce.Checked; } // private bool UpdateMemoryProtection(int nIndex, bool bOldSetting, // string strFieldID) // { // bool bNewProt = m_lbMemProt.GetItemChecked(nIndex); // if(bNewProt != bOldSetting) // m_pwDatabase.RootGroup.EnableStringFieldProtection(strFieldID, bNewProt); // #if DEBUG // EntryHandler eh = delegate(PwEntry pe) // { // ProtectedString ps = pe.Strings.Get(strFieldID); // if(ps != null) { Debug.Assert(ps.IsProtected == bNewProt); } // return true; // }; // Debug.Assert(m_pwDatabase.RootGroup.TraverseTree( // TraversalMethod.PreOrder, null, eh)); // #endif // return bNewProt; // } private void OnBtnCancel(object sender, EventArgs e) { } private void OnBtnHelp(object sender, EventArgs e) { string strSubTopic = null; if(m_tabMain.SelectedTab == m_tabGeneral) strSubTopic = AppDefs.HelpTopics.DbSettingsGeneral; else if(m_tabMain.SelectedTab == m_tabSecurity) strSubTopic = AppDefs.HelpTopics.DbSettingsSecurity; // else if(m_tabMain.SelectedTab == m_tabProtection) // strSubTopic = AppDefs.HelpTopics.DbSettingsProtection; else if(m_tabMain.SelectedTab == m_tabCompression) strSubTopic = AppDefs.HelpTopics.DbSettingsCompression; AppHelp.ShowHelp(AppDefs.HelpTopics.DatabaseSettings, strSubTopic); } private bool AbortKdfThread() { if(m_thKdf == null) return false; try { m_thKdf.Abort(); } catch(Exception) { Debug.Assert(false); } m_thKdf = null; return true; } private void OnFormClosed(object sender, FormClosedEventArgs e) { if(AbortKdfThread()) { Debug.Assert(false); } GlobalWindowManager.RemoveWindow(this); foreach(ColorMenuItem mi in m_vColorItems) mi.Click -= this.HandleColorButtonClicked; m_vColorItems.Clear(); UIUtil.DisposeButtonImage(m_btnColor, ref m_imgColor); } private void OnKeyRecCheckedChanged(object sender, EventArgs e) { EnableControlsEx(); } private void OnKeyForceCheckedChanged(object sender, EventArgs e) { EnableControlsEx(); } // private void OnLinkClickedMemProtHelp(object sender, LinkLabelLinkClickedEventArgs e) // { // AppHelp.ShowHelp(AppDefs.HelpTopics.FaqTech, AppDefs.HelpTopics.FaqTechMemProt); // } private void OnHistoryMaxItemsCheckedChanged(object sender, EventArgs e) { EnableControlsEx(); } private void OnHistoryMaxSizeCheckedChanged(object sender, EventArgs e) { EnableControlsEx(); } private void HandleColorButtonClicked(object sender, EventArgs e) { if(sender == null) { Debug.Assert(false); return; } ColorMenuItem mi = (sender as ColorMenuItem); if(mi == null) { Debug.Assert(false); return; } m_clr = mi.Color; UIUtil.OverwriteButtonImage(m_btnColor, ref m_imgColor, UIUtil.CreateColorBitmap24(m_btnColor, m_clr)); } private void OnBtnColor(object sender, EventArgs e) { // Color? clr = UIUtil.ShowColorDialog(m_clr); // if(clr.HasValue) // { // float h, s, v; // UIUtil.ColorToHsv(clr.Value, out h, out s, out v); // m_clr = UIUtil.ColorFromHsv(h, 1.0f, 1.0f); // UIUtil.OverwriteButtonImage(m_btnColor, ref m_imgColor, // UIUtil.CreateColorBitmap24(m_btnColor, m_clr)); // } if(m_ctxColor == null) { m_ctxColor = new CustomContextMenuEx(); int qSize = (int)((20.0f * m_btnColor.Height) / 23.0f + 0.01f); // const int nMaxColors = 64; int nMaxColors = AppIcons.Colors.Length; int nBreakAt = (int)Math.Sqrt(0.1 + nMaxColors); // m_ctxColor.LayoutStyle = ToolStripLayoutStyle.Flow; // FlowLayoutSettings fls = (m_ctxColor.LayoutSettings as FlowLayoutSettings); // if(fls == null) { Debug.Assert(false); return; } // fls.FlowDirection = FlowDirection.LeftToRight; // m_ctxColor.LayoutStyle = ToolStripLayoutStyle.Table; // TableLayoutSettings tls = (m_ctxColor.LayoutSettings as TableLayoutSettings); // if(tls == null) { Debug.Assert(false); return; } // tls.ColumnCount = nBreakAt; // tls.RowCount = nBreakAt; // m_ctxColor.SuspendLayout(); for(int i = 0; i < nMaxColors; ++i) { // float fHue = ((float)i * 360.0f) / (float)nMaxColors; // Color clr = UIUtil.ColorFromHsv(fHue, 1.0f, 1.0f); Color clr = AppIcons.Colors[i]; // Image img = UIUtil.CreateColorBitmap24(16, 16, clr); // ToolStripButton btn = new ToolStripButton(string.Empty, img); // btn.DisplayStyle = ToolStripItemDisplayStyle.Image; // btn.ImageAlign = ContentAlignment.MiddleCenter; // btn.AutoSize = true; ColorMenuItem mi = new ColorMenuItem(clr, qSize); if((i > 0) && ((i % nBreakAt) == 0)) mi.Break = true; // fls.SetFlowBreak(btn, true); mi.Click += this.HandleColorButtonClicked; // m_ctxColor.Items.Add(btn); m_vColorItems.Add(mi); } m_ctxColor.MenuItems.AddRange(m_vColorItems.ToArray()); // m_ctxColor.ResumeLayout(true); // this.Controls.Add(m_ctxColor); // m_ctxColor.BringToFront(); } // m_ctxColor.Show(m_btnColor, new Point(0, m_btnColor.Height)); // m_ctxColor.Location = new Point(m_btnColor.Location.X, // m_btnColor.Location.Y - m_btnColor.Height - m_ctxColor.Height); // m_ctxColor.Visible = true; // m_ctxColor.Show(); m_ctxColor.ShowEx(m_btnColor); } private void OnColorCheckedChanged(object sender, EventArgs e) { EnableControlsEx(); } private KdfEngine GetKdf() { return KdfPool.Get(m_cmbKdf.Text); } private KdfParameters GetKdfParameters(bool bShowAdjustments) { KdfEngine kdf = GetKdf(); if(kdf == null) { Debug.Assert(false); return null; } string strAdj = string.Empty; KdfParameters pKdf = kdf.GetDefaultParameters(); if(kdf is AesKdf) pKdf.SetUInt64(AesKdf.ParamRounds, (ulong)m_numKdfIt.Value); else if(kdf is Argon2Kdf) { ulong uIt = (ulong)m_numKdfIt.Value; AdjustKdfParam(ref uIt, ">=", Argon2Kdf.MinIterations, KPRes.Iterations, ref strAdj); AdjustKdfParam(ref uIt, "<=", Argon2Kdf.MaxIterations, KPRes.Iterations, ref strAdj); pKdf.SetUInt64(Argon2Kdf.ParamIterations, uIt); // Adjust parallelism first, as memory depends on it uint uPar = (uint)m_numKdfPar.Value; AdjustKdfParam(ref uPar, ">=", Argon2Kdf.MinParallelism, KPRes.Parallelism, ref strAdj); uint uParMax = Argon2Kdf.MaxParallelism; int cp = Environment.ProcessorCount; if((cp > 0) && (cp <= (int.MaxValue / 2))) uParMax = Math.Min(uParMax, (uint)(cp * 2)); AdjustKdfParam(ref uPar, "<=", uParMax, KPRes.Parallelism, ref strAdj); pKdf.SetUInt32(Argon2Kdf.ParamParallelism, uPar); ulong uMem = (ulong)m_numKdfMem.Value; int iMemUnit = m_cmbKdfMem.SelectedIndex; while(iMemUnit > 0) { if(uMem > (ulong.MaxValue / 1024UL)) { uMem = ulong.MaxValue; break; } uMem *= 1024UL; --iMemUnit; } // 8*p blocks = 1024*8*p bytes minimum memory, see spec Debug.Assert(Argon2Kdf.MinMemory == (1024UL * 8UL)); ulong uMemMin = Argon2Kdf.MinMemory * uPar; AdjustKdfParam(ref uMem, ">=", uMemMin, KPRes.Memory, ref strAdj); AdjustKdfParam(ref uMem, "<=", Argon2Kdf.MaxMemory, KPRes.Memory, ref strAdj); pKdf.SetUInt64(Argon2Kdf.ParamMemory, uMem); } else return null; // Plugins may handle it if(bShowAdjustments && (strAdj.Length > 0)) { strAdj = KPRes.KdfAdjust + MessageService.NewParagraph + strAdj; MessageService.ShowInfo(strAdj); } return pKdf; } private static void AdjustKdfParam(ref T tValue, string strReq, T tCmp, string strName, ref string strAdj) where T : struct, IComparable { if(strReq == ">=") { if(tValue.CompareTo(tCmp) >= 0) return; } else if(strReq == "<=") { if(tValue.CompareTo(tCmp) <= 0) return; } else { Debug.Assert(false); return; } if(strAdj.Length > 0) strAdj += MessageService.NewLine; strAdj += "* " + strName + ": " + tValue.ToString() + " -> " + tCmp.ToString() + "."; tValue = tCmp; } private void SetKdfParameters(KdfParameters p) { if(p == null) { Debug.Assert(false); return; } KdfEngine kdf = KdfPool.Get(p.KdfUuid); if(kdf == null) { Debug.Assert(false); return; } for(int i = 0; i < m_cmbKdf.Items.Count; ++i) { string strKdf = (m_cmbKdf.Items[i] as string); if(string.IsNullOrEmpty(strKdf)) { Debug.Assert(false); continue; } if(strKdf.Equals(kdf.Name, StrUtil.CaseIgnoreCmp)) { bool bPrevInit = m_bInitializing; m_bInitializing = true; // Prevent selection handler m_cmbKdf.SelectedIndex = i; m_bInitializing = bPrevInit; break; } } if(kdf is AesKdf) { ulong uIt = p.GetUInt64(AesKdf.ParamRounds, PwDefs.DefaultKeyEncryptionRounds); SetKdfParameters(uIt, 1024, 2); } else if(kdf is Argon2Kdf) { ulong uIt = p.GetUInt64(Argon2Kdf.ParamIterations, Argon2Kdf.DefaultIterations); ulong uMem = p.GetUInt64(Argon2Kdf.ParamMemory, Argon2Kdf.DefaultMemory); uint uPar = p.GetUInt32(Argon2Kdf.ParamParallelism, Argon2Kdf.DefaultParallelism); SetKdfParameters(uIt, uMem, uPar); } // else { Debug.Assert(false); } // Plugins may provide other KDFs } private void SetKdfParameters(ulong uIt, ulong uMem, uint uPar) { m_numKdfIt.Value = uIt; int nUnits = m_cmbKdfMem.Items.Count; if((nUnits == 0) || (uMem == 0)) { m_numKdfMem.Value = uMem; if(nUnits > 0) m_cmbKdfMem.SelectedIndex = 0; else { Debug.Assert(false); } return; } ulong uMemWrtUnit = uMem; int iUnit = 0; while(iUnit < (nUnits - 1)) { if((uMemWrtUnit % 1024UL) != 0UL) break; uMemWrtUnit /= 1024UL; ++iUnit; } m_numKdfMem.Value = uMemWrtUnit; m_cmbKdfMem.SelectedIndex = iUnit; m_numKdfPar.Value = uPar; } private void OnKdfSelectedIndexChanged(object sender, EventArgs e) { if(m_bInitializing) return; KdfEngine kdf = GetKdf(); if(kdf == null) { Debug.Assert(false); return; } SetKdfParameters(kdf.GetDefaultParameters()); EnableControlsEx(); } private void OnBtnKdf1Sec(object sender, EventArgs e) { KdfEngine kdf = GetKdf(); if(kdf == null) { Debug.Assert(false); return; } if(!(kdf is AesKdf) && !(kdf is Argon2Kdf)) return; // No assert, plugins if(m_thKdf != null) { Debug.Assert(false); return; } try { m_thKdf = new Thread(new ParameterizedThreadStart(this.Kdf1SecTh)); EnableControlsEx(); // Disable controls (m_thKdf is not null) m_thKdf.Start(kdf); } catch(Exception) { Debug.Assert(false); m_thKdf = null; EnableControlsEx(); } } private void Kdf1SecTh(object o) { KdfParameters p = null; string strMsg = null; try { KdfEngine kdf = (o as KdfEngine); if(kdf != null) p = kdf.GetBestParameters(1000); else { Debug.Assert(false); } } catch(ThreadAbortException) { try { Thread.ResetAbort(); } catch(Exception) { Debug.Assert(false); } return; } catch(Exception ex) { if((ex != null) && !string.IsNullOrEmpty(ex.Message)) strMsg = ex.Message; } finally { m_thKdf = null; } // Before continuation, to enable controls try { m_btnOK.Invoke(new KdfpDelegate(this.Kdf1SecPost), p, strMsg); } catch(Exception) { Debug.Assert(false); } } private delegate void KdfpDelegate(KdfParameters p, string strMsg); private void Kdf1SecPost(KdfParameters p, string strMsg) { try { Debug.Assert(!m_btnOK.InvokeRequired); if(!string.IsNullOrEmpty(strMsg)) MessageService.ShowInfo(strMsg); else SetKdfParameters(p); EnableControlsEx(); } catch(Exception) { Debug.Assert(false); } } private void OnBtnKdfTest(object sender, EventArgs e) { KdfParameters p = GetKdfParameters(true); if(p == null) return; // No assert, plugins if(m_thKdf != null) { Debug.Assert(false); return; } try { SetKdfParameters(p); // Show auto-adjusted parameters m_thKdf = new Thread(new ParameterizedThreadStart(this.KdfTestTh)); EnableControlsEx(); // Disable controls (m_thKdf is not null) m_thKdf.Start(p); } catch(Exception) { Debug.Assert(false); m_thKdf = null; EnableControlsEx(); } } private void KdfTestTh(object o) { string strMsg = KPRes.UnknownError; try { KdfParameters p = (o as KdfParameters); if(p == null) { Debug.Assert(false); return; } KdfEngine kdf = KdfPool.Get(p.KdfUuid); if(kdf == null) { Debug.Assert(false); return; } byte[] pbMsg = new byte[32]; Program.GlobalRandom.NextBytes(pbMsg); kdf.Randomize(p); Stopwatch sw = Stopwatch.StartNew(); kdf.Transform(pbMsg, p); sw.Stop(); long lMS = sw.ElapsedMilliseconds; lMS = Math.Max(lMS, 1L); double dS = (double)lMS / 1000.0; strMsg = KPRes.TestSuccess + MessageService.NewParagraph + KPRes.TransformTime.Replace(@"{PARAM}", dS.ToString()); } catch(ThreadAbortException) { try { Thread.ResetAbort(); } catch(Exception) { Debug.Assert(false); } return; } catch(Exception ex) { Debug.Assert(false); if((ex != null) && !string.IsNullOrEmpty(ex.Message)) strMsg = ex.Message; } finally { m_thKdf = null; } // Before continuation, to enable controls try { m_btnOK.Invoke(new KdfsDelegate(this.KdfTestPost), strMsg); } catch(Exception) { Debug.Assert(false); } } private delegate void KdfsDelegate(string strMsg); private void KdfTestPost(string strMsg) { try { Debug.Assert(!m_btnOK.InvokeRequired); if(!string.IsNullOrEmpty(strMsg)) MessageService.ShowInfo(strMsg); else { Debug.Assert(false); } EnableControlsEx(); } catch(Exception) { Debug.Assert(false); } } private void OnBtnCancelOp(object sender, EventArgs e) { AbortKdfThread(); EnableControlsEx(); } } } KeePass/Forms/UpdateCheckForm.cs0000664000000000000000000001405313222430412015526 0ustar rootroot/* KeePass Password Safe - The Open-Source Password Manager Copyright (C) 2003-2018 Dominik Reichl This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ using System; using System.Collections.Generic; using System.ComponentModel; using System.Diagnostics; using System.Drawing; using System.Text; using System.Windows.Forms; using KeePass.App; using KeePass.Native; using KeePass.Resources; using KeePass.UI; using KeePass.Util; using KeePassLib; using KeePassLib.Utility; namespace KeePass.Forms { public partial class UpdateCheckForm : Form, IGwmWindow { private List m_lInfo = null; private ImageList m_ilIcons = null; public bool CanCloseWithoutDataLoss { get { return true; } } public void InitEx(List lInfo, bool bModal) { m_lInfo = lInfo; if(!bModal) this.ShowInTaskbar = true; } public UpdateCheckForm() { InitializeComponent(); Program.Translation.ApplyTo(this); } private void OnFormLoad(object sender, EventArgs e) { if(m_lInfo == null) throw new InvalidOperationException(); GlobalWindowManager.AddWindow(this, this); BannerFactory.CreateBannerEx(this, m_bannerImage, Properties.Resources.B48x48_WWW, KPRes.UpdateCheck, KPRes.UpdateCheckResults); this.Icon = AppIcons.Default; this.Text = KPRes.UpdateCheck + " - " + PwDefs.ShortProductName; UIUtil.SetExplorerTheme(m_lvInfo, true); m_lvInfo.Columns.Add(KPRes.Component); m_lvInfo.Columns.Add(KPRes.Status); m_lvInfo.Columns.Add(KPRes.Installed); m_lvInfo.Columns.Add(KPRes.Available); List lImages = new List(); lImages.Add(Properties.Resources.B16x16_Help); lImages.Add(Properties.Resources.B16x16_Apply); lImages.Add(Properties.Resources.B16x16_Redo); lImages.Add(Properties.Resources.B16x16_History); lImages.Add(Properties.Resources.B16x16_Error); m_ilIcons = UIUtil.BuildImageListUnscaled(lImages, DpiUtil.ScaleIntX(16), DpiUtil.ScaleIntY(16)); m_lvInfo.SmallImageList = m_ilIcons; string strCat = string.Empty; ListViewGroup lvg = null; const uint uMinComp = 2; foreach(UpdateComponentInfo uc in m_lInfo) { if(uc.Category != strCat) { lvg = new ListViewGroup(uc.Category); m_lvInfo.Groups.Add(lvg); strCat = uc.Category; } ListViewItem lvi = new ListViewItem(uc.Name); string strStatus = KPRes.Unknown + "."; if(uc.Status == UpdateComponentStatus.UpToDate) { strStatus = KPRes.UpToDate + "."; lvi.ImageIndex = 1; } else if(uc.Status == UpdateComponentStatus.NewVerAvailable) { strStatus = KPRes.NewVersionAvailable + "!"; lvi.ImageIndex = 2; } else if(uc.Status == UpdateComponentStatus.PreRelease) { strStatus = KPRes.PreReleaseVersion + "."; lvi.ImageIndex = 3; } else if(uc.Status == UpdateComponentStatus.DownloadFailed) { strStatus = KPRes.UpdateCheckFailedNoDl; lvi.ImageIndex = 4; } else lvi.ImageIndex = 0; lvi.SubItems.Add(strStatus); lvi.SubItems.Add(StrUtil.VersionToString(uc.VerInstalled, uMinComp)); if((uc.Status == UpdateComponentStatus.UpToDate) || (uc.Status == UpdateComponentStatus.NewVerAvailable) || (uc.Status == UpdateComponentStatus.PreRelease)) lvi.SubItems.Add(StrUtil.VersionToString(uc.VerAvailable, uMinComp)); else lvi.SubItems.Add("?"); if(lvg != null) lvi.Group = lvg; m_lvInfo.Items.Add(lvi); } UIUtil.ResizeColumns(m_lvInfo, new int[] { 2, 2, 1, 1 }, true); } private void CleanUpEx() { if(m_ilIcons != null) { m_lvInfo.SmallImageList = null; // Detach event handlers m_ilIcons.Dispose(); m_ilIcons = null; } } private void OnFormClosed(object sender, FormClosedEventArgs e) { CleanUpEx(); GlobalWindowManager.RemoveWindow(this); } private void OnLinkWeb(object sender, LinkLabelLinkClickedEventArgs e) { OpenUrl(PwDefs.HomepageUrl); } private void OnLinkPlugins(object sender, LinkLabelLinkClickedEventArgs e) { OpenUrl(PwDefs.PluginsUrl); } private void OpenUrl(string strUrl) { if(!KeePassLib.Native.NativeLib.IsUnix()) { // Process.Start has a considerable delay when opening URLs // here (different thread, etc.), therefore try the native // ShellExecute first (which doesn't have any delay) try { IntPtr h = NativeMethods.ShellExecute(this.Handle, null, strUrl, null, null, NativeMethods.SW_SHOW); long l = h.ToInt64(); if((l < 0) || (l > 32)) return; else { Debug.Assert(false); } } catch(Exception) { Debug.Assert(false); } } try { Process.Start(strUrl); } catch(Exception) { Debug.Assert(false); } } private void OnInfoItemActivate(object sender, EventArgs e) { ListView.SelectedListViewItemCollection lvsic = m_lvInfo.SelectedItems; if((lvsic == null) || (lvsic.Count != 1)) { Debug.Assert(false); return; } ListViewItem lvi = lvsic[0]; if((lvi == null) || (lvi.Group == null)) { Debug.Assert(false); return; } string strGroup = (lvi.Group.Header ?? string.Empty); if(strGroup == PwDefs.ShortProductName) OpenUrl(PwDefs.HomepageUrl); else if(strGroup == KPRes.Plugins) OpenUrl(PwDefs.PluginsUrl); else { Debug.Assert(false); } } } } KeePass/Forms/UrlOverrideForm.Designer.cs0000664000000000000000000001075212501532514017356 0ustar rootrootnamespace KeePass.Forms { partial class UrlOverrideForm { /// /// Required designer variable. /// private System.ComponentModel.IContainer components = null; /// /// Clean up any resources being used. /// /// true if managed resources should be disposed; otherwise, false. protected override void Dispose(bool disposing) { if(disposing && (components != null)) { components.Dispose(); } base.Dispose(disposing); } #region Windows Form Designer generated code /// /// Required method for Designer support - do not modify /// the contents of this method with the code editor. /// private void InitializeComponent() { this.m_btnOK = new System.Windows.Forms.Button(); this.m_btnCancel = new System.Windows.Forms.Button(); this.m_lblScheme = new System.Windows.Forms.Label(); this.m_tbScheme = new System.Windows.Forms.TextBox(); this.m_lblUrlOverride = new System.Windows.Forms.Label(); this.m_tbOverride = new System.Windows.Forms.TextBox(); this.SuspendLayout(); // // m_btnOK // this.m_btnOK.DialogResult = System.Windows.Forms.DialogResult.OK; this.m_btnOK.Location = new System.Drawing.Point(160, 100); this.m_btnOK.Name = "m_btnOK"; this.m_btnOK.Size = new System.Drawing.Size(75, 23); this.m_btnOK.TabIndex = 3; this.m_btnOK.Text = "OK"; this.m_btnOK.UseVisualStyleBackColor = true; this.m_btnOK.Click += new System.EventHandler(this.OnBtnOK); // // m_btnCancel // this.m_btnCancel.DialogResult = System.Windows.Forms.DialogResult.Cancel; this.m_btnCancel.Location = new System.Drawing.Point(241, 100); this.m_btnCancel.Name = "m_btnCancel"; this.m_btnCancel.Size = new System.Drawing.Size(75, 23); this.m_btnCancel.TabIndex = 4; this.m_btnCancel.Text = "Cancel"; this.m_btnCancel.UseVisualStyleBackColor = true; // // m_lblScheme // this.m_lblScheme.AutoSize = true; this.m_lblScheme.Location = new System.Drawing.Point(9, 15); this.m_lblScheme.Name = "m_lblScheme"; this.m_lblScheme.Size = new System.Drawing.Size(49, 13); this.m_lblScheme.TabIndex = 5; this.m_lblScheme.Text = "Scheme:"; // // m_tbScheme // this.m_tbScheme.Location = new System.Drawing.Point(64, 12); this.m_tbScheme.Name = "m_tbScheme"; this.m_tbScheme.Size = new System.Drawing.Size(252, 20); this.m_tbScheme.TabIndex = 0; // // m_lblUrlOverride // this.m_lblUrlOverride.AutoSize = true; this.m_lblUrlOverride.Location = new System.Drawing.Point(9, 45); this.m_lblUrlOverride.Name = "m_lblUrlOverride"; this.m_lblUrlOverride.Size = new System.Drawing.Size(73, 13); this.m_lblUrlOverride.TabIndex = 1; this.m_lblUrlOverride.Text = "URL override:"; // // m_tbOverride // this.m_tbOverride.Location = new System.Drawing.Point(12, 63); this.m_tbOverride.Name = "m_tbOverride"; this.m_tbOverride.Size = new System.Drawing.Size(304, 20); this.m_tbOverride.TabIndex = 2; // // UrlOverrideForm // this.AcceptButton = this.m_btnOK; this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F); this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; this.CancelButton = this.m_btnCancel; this.ClientSize = new System.Drawing.Size(328, 135); this.Controls.Add(this.m_tbOverride); this.Controls.Add(this.m_lblUrlOverride); this.Controls.Add(this.m_tbScheme); this.Controls.Add(this.m_lblScheme); this.Controls.Add(this.m_btnCancel); this.Controls.Add(this.m_btnOK); this.FormBorderStyle = System.Windows.Forms.FormBorderStyle.FixedDialog; this.MaximizeBox = false; this.MinimizeBox = false; this.Name = "UrlOverrideForm"; this.ShowInTaskbar = false; this.StartPosition = System.Windows.Forms.FormStartPosition.CenterParent; this.Text = "<>"; this.Load += new System.EventHandler(this.OnFormLoad); this.FormClosed += new System.Windows.Forms.FormClosedEventHandler(this.OnFormClosed); this.ResumeLayout(false); this.PerformLayout(); } #endregion private System.Windows.Forms.Button m_btnOK; private System.Windows.Forms.Button m_btnCancel; private System.Windows.Forms.Label m_lblScheme; private System.Windows.Forms.TextBox m_tbScheme; private System.Windows.Forms.Label m_lblUrlOverride; private System.Windows.Forms.TextBox m_tbOverride; } }KeePass/Forms/EcasConditionForm.Designer.cs0000664000000000000000000001536512501527700017644 0ustar rootrootnamespace KeePass.Forms { partial class EcasConditionForm { /// /// Required designer variable. /// private System.ComponentModel.IContainer components = null; /// /// Clean up any resources being used. /// /// true if managed resources should be disposed; otherwise, false. protected override void Dispose(bool disposing) { if(disposing && (components != null)) { components.Dispose(); } base.Dispose(disposing); } #region Windows Form Designer generated code /// /// Required method for Designer support - do not modify /// the contents of this method with the code editor. /// private void InitializeComponent() { this.m_btnCancel = new System.Windows.Forms.Button(); this.m_btnOK = new System.Windows.Forms.Button(); this.m_lblCondition = new System.Windows.Forms.Label(); this.m_cmbConditions = new System.Windows.Forms.ComboBox(); this.m_cbNegate = new System.Windows.Forms.CheckBox(); this.m_dgvParams = new System.Windows.Forms.DataGridView(); this.m_lblParamHint = new System.Windows.Forms.Label(); this.m_lblSep = new System.Windows.Forms.Label(); this.m_btnHelp = new System.Windows.Forms.Button(); ((System.ComponentModel.ISupportInitialize)(this.m_dgvParams)).BeginInit(); this.SuspendLayout(); // // m_btnCancel // this.m_btnCancel.DialogResult = System.Windows.Forms.DialogResult.Cancel; this.m_btnCancel.Location = new System.Drawing.Point(447, 309); this.m_btnCancel.Name = "m_btnCancel"; this.m_btnCancel.Size = new System.Drawing.Size(75, 23); this.m_btnCancel.TabIndex = 6; this.m_btnCancel.Text = "Cancel"; this.m_btnCancel.UseVisualStyleBackColor = true; this.m_btnCancel.Click += new System.EventHandler(this.OnBtnCancel); // // m_btnOK // this.m_btnOK.DialogResult = System.Windows.Forms.DialogResult.OK; this.m_btnOK.Location = new System.Drawing.Point(366, 309); this.m_btnOK.Name = "m_btnOK"; this.m_btnOK.Size = new System.Drawing.Size(75, 23); this.m_btnOK.TabIndex = 5; this.m_btnOK.Text = "OK"; this.m_btnOK.UseVisualStyleBackColor = true; this.m_btnOK.Click += new System.EventHandler(this.OnBtnOK); // // m_lblCondition // this.m_lblCondition.AutoSize = true; this.m_lblCondition.Location = new System.Drawing.Point(9, 46); this.m_lblCondition.Name = "m_lblCondition"; this.m_lblCondition.Size = new System.Drawing.Size(54, 13); this.m_lblCondition.TabIndex = 8; this.m_lblCondition.Text = "Condition:"; // // m_cmbConditions // this.m_cmbConditions.DropDownStyle = System.Windows.Forms.ComboBoxStyle.DropDownList; this.m_cmbConditions.FormattingEnabled = true; this.m_cmbConditions.Location = new System.Drawing.Point(12, 62); this.m_cmbConditions.Name = "m_cmbConditions"; this.m_cmbConditions.Size = new System.Drawing.Size(510, 21); this.m_cmbConditions.TabIndex = 0; this.m_cmbConditions.SelectedIndexChanged += new System.EventHandler(this.OnConditionsSelectedIndexChanged); // // m_cbNegate // this.m_cbNegate.AutoSize = true; this.m_cbNegate.Location = new System.Drawing.Point(12, 15); this.m_cbNegate.Name = "m_cbNegate"; this.m_cbNegate.Size = new System.Drawing.Size(202, 17); this.m_cbNegate.TabIndex = 7; this.m_cbNegate.Text = "&Not (negate result of condition below)"; this.m_cbNegate.UseVisualStyleBackColor = true; // // m_dgvParams // this.m_dgvParams.AllowUserToAddRows = false; this.m_dgvParams.AllowUserToDeleteRows = false; this.m_dgvParams.BorderStyle = System.Windows.Forms.BorderStyle.Fixed3D; this.m_dgvParams.ColumnHeadersHeightSizeMode = System.Windows.Forms.DataGridViewColumnHeadersHeightSizeMode.AutoSize; this.m_dgvParams.Location = new System.Drawing.Point(12, 89); this.m_dgvParams.Name = "m_dgvParams"; this.m_dgvParams.Size = new System.Drawing.Size(510, 168); this.m_dgvParams.TabIndex = 1; // // m_lblParamHint // this.m_lblParamHint.Location = new System.Drawing.Point(9, 269); this.m_lblParamHint.Name = "m_lblParamHint"; this.m_lblParamHint.Size = new System.Drawing.Size(513, 15); this.m_lblParamHint.TabIndex = 2; this.m_lblParamHint.Text = "<>"; // // m_lblSep // this.m_lblSep.BorderStyle = System.Windows.Forms.BorderStyle.Fixed3D; this.m_lblSep.Location = new System.Drawing.Point(0, 300); this.m_lblSep.Name = "m_lblSep"; this.m_lblSep.Size = new System.Drawing.Size(535, 2); this.m_lblSep.TabIndex = 3; // // m_btnHelp // this.m_btnHelp.Location = new System.Drawing.Point(12, 309); this.m_btnHelp.Name = "m_btnHelp"; this.m_btnHelp.Size = new System.Drawing.Size(75, 23); this.m_btnHelp.TabIndex = 4; this.m_btnHelp.Text = "&Help"; this.m_btnHelp.UseVisualStyleBackColor = true; this.m_btnHelp.Click += new System.EventHandler(this.OnBtnHelp); // // EcasConditionForm // this.AcceptButton = this.m_btnOK; this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F); this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; this.CancelButton = this.m_btnCancel; this.ClientSize = new System.Drawing.Size(534, 344); this.Controls.Add(this.m_btnHelp); this.Controls.Add(this.m_lblSep); this.Controls.Add(this.m_lblParamHint); this.Controls.Add(this.m_dgvParams); this.Controls.Add(this.m_cbNegate); this.Controls.Add(this.m_btnCancel); this.Controls.Add(this.m_btnOK); this.Controls.Add(this.m_lblCondition); this.Controls.Add(this.m_cmbConditions); this.FormBorderStyle = System.Windows.Forms.FormBorderStyle.FixedDialog; this.MaximizeBox = false; this.MinimizeBox = false; this.Name = "EcasConditionForm"; this.ShowInTaskbar = false; this.StartPosition = System.Windows.Forms.FormStartPosition.CenterParent; this.Text = "<>"; this.Load += new System.EventHandler(this.OnFormLoad); this.FormClosed += new System.Windows.Forms.FormClosedEventHandler(this.OnFormClosed); ((System.ComponentModel.ISupportInitialize)(this.m_dgvParams)).EndInit(); this.ResumeLayout(false); this.PerformLayout(); } #endregion private System.Windows.Forms.Button m_btnCancel; private System.Windows.Forms.Button m_btnOK; private System.Windows.Forms.Label m_lblCondition; private System.Windows.Forms.ComboBox m_cmbConditions; private System.Windows.Forms.CheckBox m_cbNegate; private System.Windows.Forms.DataGridView m_dgvParams; private System.Windows.Forms.Label m_lblParamHint; private System.Windows.Forms.Label m_lblSep; private System.Windows.Forms.Button m_btnHelp; } }KeePass/Forms/TextEncodingForm.resx0000664000000000000000000001326612501532466016335 0ustar rootroot text/microsoft-resx 2.0 System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 KeePass/Forms/MainForm_Events.cs0000664000000000000000000001610313222430410015552 0ustar rootroot/* KeePass Password Safe - The Open-Source Password Manager Copyright (C) 2003-2018 Dominik Reichl This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ using System; using System.Collections.Generic; using System.Text; using System.Windows.Forms; using System.ComponentModel; using KeePass.App; using KeePass.Util; using KeePassLib; using KeePassLib.Serialization; namespace KeePass.Forms { public sealed class FileCreatedEventArgs : EventArgs { private PwDatabase m_pwDatabase; public PwDatabase Database { get { return m_pwDatabase; } } /// /// Default constructor. /// public FileCreatedEventArgs(PwDatabase pwDatabase) { m_pwDatabase = pwDatabase; } } public sealed class FileOpenedEventArgs : EventArgs { private PwDatabase m_pwDatabase; public PwDatabase Database { get { return m_pwDatabase; } } /// /// Default constructor. /// public FileOpenedEventArgs(PwDatabase pwDatabase) { m_pwDatabase = pwDatabase; } } /// /// Event arguments structure for the file-saving event. /// public sealed class FileSavingEventArgs : CancellableOperationEventArgs { private bool m_bSaveAs; private bool m_bCopy; private PwDatabase m_pwDatabase; private Guid m_eventGuid; /// /// Flag that determines if the user is performing a 'Save As' operation. /// If this flag is false, the operation is a standard 'Save' operation. /// public bool SaveAs { get { return m_bSaveAs; } } public bool Copy { get { return m_bCopy; } } public PwDatabase Database { get { return m_pwDatabase; } } public Guid EventGuid { get { return m_eventGuid; } } /// /// Default constructor. /// /// See SaveAs property. public FileSavingEventArgs(bool bSaveAs, bool bCopy, PwDatabase pwDatabase, Guid eventGuid) { m_bSaveAs = bSaveAs; m_bCopy = bCopy; m_pwDatabase = pwDatabase; m_eventGuid = eventGuid; } } /// /// Event arguments structure for the file-saved event. /// public sealed class FileSavedEventArgs : EventArgs { private bool m_bResult; private PwDatabase m_pwDatabase; private Guid m_eventGuid; /// /// Specifies the result of the attempt to save the database. If /// this property is true, the database has been saved /// successfully. /// public bool Success { get { return m_bResult; } } public PwDatabase Database { get { return m_pwDatabase; } } public Guid EventGuid { get { return m_eventGuid; } } /// /// Default constructor. /// /// See Result property. public FileSavedEventArgs(bool bSuccess, PwDatabase pwDatabase, Guid eventGuid) { m_bResult = bSuccess; m_pwDatabase = pwDatabase; m_eventGuid = eventGuid; } } /// /// Event arguments structure for file-closing events. /// public sealed class FileClosingEventArgs : CancellableOperationEventArgs { private PwDatabase m_pwDatabase; private FileEventFlags m_f; public PwDatabase Database { get { return m_pwDatabase; } } public FileEventFlags Flags { get { return m_f; } } /// /// Default constructor. /// public FileClosingEventArgs(PwDatabase pwDatabase, FileEventFlags f) { m_pwDatabase = pwDatabase; m_f = f; } } /// /// Event arguments structure for the file-closed event. /// public sealed class FileClosedEventArgs : EventArgs { private IOConnectionInfo m_ioClosed; private FileEventFlags m_f; public IOConnectionInfo IOConnectionInfo { get { return m_ioClosed; } } public FileEventFlags Flags { get { return m_f; } } /// /// Default constructor. /// public FileClosedEventArgs(IOConnectionInfo ioClosed, FileEventFlags f) { m_ioClosed = ioClosed; m_f = f; } } public sealed class CancelEntryEventArgs : CancellableOperationEventArgs { private PwEntry m_pwEntry; private int m_nColumn; public PwEntry Entry { get { return m_pwEntry; } } public int ColumnId { get { return m_nColumn; } } public CancelEntryEventArgs(PwEntry pe, int colId) { m_pwEntry = pe; m_nColumn = colId; } } public sealed class FocusEventArgs : CancellableOperationEventArgs { private Control m_cNewRequested; private Control m_cNewFocusing; public Control RequestedControl { get { return m_cNewRequested; } } public Control FocusingControl { get { return m_cNewFocusing; } } public FocusEventArgs(Control cRequested, Control cFocusing) { m_cNewRequested = cRequested; m_cNewFocusing = cFocusing; } } [Flags] public enum FileEventFlags { None = 0, Exiting = 1, Locking = 2, Ecas = 4 } public partial class MainForm : Form { /// /// Event that is fired after a database has been created. /// public event EventHandler FileCreated; /// /// Event that is fired after a database has been opened. /// public event EventHandler FileOpened; public event EventHandler FileClosingPre; public event EventHandler FileClosingPost; /// /// Event that is fired after a database has been closed. /// public event EventHandler FileClosed; /// /// If possible, use the FileSaving event instead. /// public event EventHandler FileSavingPre; /// /// Event that is fired before a database is being saved. By handling this /// event, you can abort the file saving operation. /// public event EventHandler FileSaving; /// /// Event that is fired after a database has been saved. /// public event EventHandler FileSaved; public event EventHandler FormLoadPost; public event EventHandler DefaultEntryAction; public event EventHandler UIStateUpdated; public event EventHandler FocusChanging; public event EventHandler UserActivityPost; } } KeePass/Forms/EntropyForm.resx0000664000000000000000000001326612501530514015372 0ustar rootroot text/microsoft-resx 2.0 System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 KeePass/Forms/EcasTriggerForm.resx0000664000000000000000000001326612501530246016133 0ustar rootroot text/microsoft-resx 2.0 System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 KeePass/Forms/DataEditorForm.resx0000664000000000000000000001472513072671030015756 0ustar rootroot text/microsoft-resx 2.0 System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 17, 17 137, 17 241, 17 362, 17 KeePass/Forms/ListViewForm.resx0000664000000000000000000001326613110314076015500 0ustar rootroot text/microsoft-resx 2.0 System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 KeePass/Forms/KeyPromptForm.cs0000664000000000000000000004606413222430410015305 0ustar rootroot/* KeePass Password Safe - The Open-Source Password Manager Copyright (C) 2003-2018 Dominik Reichl This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ using System; using System.Collections.Generic; using System.ComponentModel; using System.Diagnostics; using System.Drawing; using System.IO; using System.Text; using System.Threading; using System.Windows.Forms; using KeePass.App; using KeePass.App.Configuration; using KeePass.Resources; using KeePass.UI; using KeePass.Util; using KeePassLib; using KeePassLib.Delegates; using KeePassLib.Keys; using KeePassLib.Native; using KeePassLib.Serialization; using KeePassLib.Utility; namespace KeePass.Forms { public partial class KeyPromptForm : Form { private CompositeKey m_pKey = null; private IOConnectionInfo m_ioInfo = new IOConnectionInfo(); private string m_strCustomTitle = null; // private bool m_bRedirectActivation = false; private bool m_bCanExit = false; private bool m_bHasExited = false; private SecureEdit m_secPassword = new SecureEdit(); private bool m_bInitializing = true; private bool m_bDisposed = false; private AceKeyAssoc m_aKeyAssoc = null; private bool m_bCanModKeyFile = false; private List m_lKeyFileNames = new List(); // private List m_lKeyFileImages = new List(); private bool m_bPwStatePreset = false; private bool m_bUaStatePreset = false; public CompositeKey CompositeKey { get { return m_pKey; } } public bool HasClosedWithExit { get { return m_bHasExited; } } private bool m_bSecureDesktop = false; public bool SecureDesktopMode { get { return m_bSecureDesktop; } set { m_bSecureDesktop = value; } } private bool m_bShowHelpAfterClose = false; public bool ShowHelpAfterClose { get { return m_bShowHelpAfterClose; } } public KeyPromptForm() { InitializeComponent(); Program.Translation.ApplyTo(this); } public void InitEx(IOConnectionInfo ioInfo, bool bCanExit, bool bRedirectActivation) { InitEx(ioInfo, bCanExit, bRedirectActivation, null); } public void InitEx(IOConnectionInfo ioInfo, bool bCanExit, bool bRedirectActivation, string strCustomTitle) { if(ioInfo != null) m_ioInfo = ioInfo; m_bCanExit = bCanExit; // m_bRedirectActivation = bRedirectActivation; m_strCustomTitle = strCustomTitle; } 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 } private void OnFormShown(object sender, EventArgs e) { // Focusing doesn't always work in OnFormLoad; // https://sourceforge.net/p/keepass/feature-requests/1735/ if(m_tbPassword.CanFocus) UIUtil.ResetFocus(m_tbPassword, this); else if(m_cmbKeyFile.CanFocus) UIUtil.SetFocus(m_cmbKeyFile, this); else if(m_btnOK.CanFocus) UIUtil.SetFocus(m_btnOK, this); else { Debug.Assert(false); } } private void CustomizeForScreenReader() { if(!Program.Config.UI.OptimizeForScreenReader) return; m_cbHidePassword.Text = KPRes.HideUsingAsterisks; m_btnOpenKeyFile.Text = KPRes.SelectFile; } private void CleanUpEx() { Debug.Assert(m_cmbKeyFile.Items.Count == m_lKeyFileNames.Count); if(m_bDisposed) { Debug.Assert(false); return; } m_bDisposed = true; // m_cmbKeyFile.OrderedImageList = null; // m_lKeyFileImages.Clear(); m_secPassword.Detach(); } private bool CreateCompositeKey() { m_pKey = new CompositeKey(); if(m_cbPassword.Checked) // Use a password { byte[] pb = m_secPassword.ToUtf8(); m_pKey.AddUserKey(new KcpPassword(pb)); MemUtil.ZeroByteArray(pb); } string strKeyFile = m_cmbKeyFile.Text; Debug.Assert(strKeyFile != null); if(strKeyFile == null) strKeyFile = string.Empty; bool bIsProvKey = Program.KeyProviderPool.IsKeyProvider(strKeyFile); if(m_cbKeyFile.Checked && !strKeyFile.Equals(KPRes.NoKeyFileSpecifiedMeta) && !bIsProvKey) { if(!ValidateKeyFile()) return false; try { m_pKey.AddUserKey(new KcpKeyFile(strKeyFile)); } catch(Exception) { MessageService.ShowWarning(strKeyFile, KPRes.KeyFileError); return false; } } else if(m_cbKeyFile.Checked && !strKeyFile.Equals(KPRes.NoKeyFileSpecifiedMeta) && bIsProvKey) { KeyProvider kp = Program.KeyProviderPool.Get(strKeyFile); if((kp != null) && m_bSecureDesktop) { if(!kp.SecureDesktopCompatible) { MessageService.ShowWarning(KPRes.KeyProvIncmpWithSD, KPRes.KeyProvIncmpWithSDHint); return false; } } KeyProviderQueryContext ctxKP = new KeyProviderQueryContext( m_ioInfo, false, m_bSecureDesktop); bool bPerformHash; byte[] pbProvKey = Program.KeyProviderPool.GetKey(strKeyFile, ctxKP, out bPerformHash); if((pbProvKey != null) && (pbProvKey.Length > 0)) { try { m_pKey.AddUserKey(new KcpCustomKey(strKeyFile, pbProvKey, bPerformHash)); } catch(Exception exCKP) { MessageService.ShowWarning(exCKP); return false; } MemUtil.ZeroByteArray(pbProvKey); } else return false; // Provider has shown error message } if(m_cbUserAccount.Checked) { try { m_pKey.AddUserKey(new KcpUserAccount()); } catch(Exception exUA) { MessageService.ShowWarning(exUA); return false; } } return true; } private bool ValidateKeyFile() { string strKeyFile = m_cmbKeyFile.Text; Debug.Assert(strKeyFile != null); if(strKeyFile == null) strKeyFile = string.Empty; if(strKeyFile.Equals(KPRes.NoKeyFileSpecifiedMeta)) return true; if(Program.KeyProviderPool.IsKeyProvider(strKeyFile)) return true; bool bSuccess = true; IOConnectionInfo ioc = IOConnectionInfo.FromPath(strKeyFile); if(!IOConnection.FileExists(ioc)) { MessageService.ShowWarning(strKeyFile, KPRes.FileNotFoundError); bSuccess = false; } // if(!bSuccess) // { // int nPos = m_cmbKeyFile.Items.IndexOf(strKeyFile); // if(nPos >= 0) // { // m_cmbKeyFile.Items.RemoveAt(nPos); // m_lKeyFileNames.RemoveAt(nPos); // } // m_cmbKeyFile.SelectedIndex = 0; // } return bSuccess; } private void EnableUserControls() { string strKeyFile = m_cmbKeyFile.Text; Debug.Assert(strKeyFile != null); if(strKeyFile == null) strKeyFile = string.Empty; if(m_cbKeyFile.Checked && strKeyFile.Equals(KPRes.NoKeyFileSpecifiedMeta)) UIUtil.SetEnabled(m_btnOK, false); else UIUtil.SetEnabled(m_btnOK, true); bool bExclusiveProv = false; KeyProvider prov = Program.KeyProviderPool.Get(strKeyFile); if(prov != null) bExclusiveProv = prov.Exclusive; if(bExclusiveProv) { m_tbPassword.Text = string.Empty; UIUtil.SetChecked(m_cbPassword, false); UIUtil.SetChecked(m_cbUserAccount, false); } bool bPwAllowed = ((Program.Config.UI.KeyPromptFlags & (ulong)AceKeyUIFlags.DisablePassword) == 0); bool bPwInput = (bPwAllowed || m_cbPassword.Checked); UIUtil.SetEnabled(m_cbPassword, !bExclusiveProv && bPwAllowed); UIUtil.SetEnabled(m_tbPassword, !bExclusiveProv && bPwInput); if((Program.Config.UI.KeyPromptFlags & (ulong)AceKeyUIFlags.DisableHidePassword) == 0) UIUtil.SetEnabled(m_cbHidePassword, !bExclusiveProv && bPwInput); bool bUaAllowed = ((Program.Config.UI.KeyPromptFlags & (ulong)AceKeyUIFlags.DisableUserAccount) == 0); bUaAllowed &= !(WinUtil.IsWindows9x || NativeLib.IsUnix()); UIUtil.SetEnabled(m_cbUserAccount, !bExclusiveProv && bUaAllowed); } private void OnCheckedPassword(object sender, EventArgs e) { if(m_cbPassword.Checked) UIUtil.SetFocus(m_tbPassword, this); } private void OnCheckedKeyFile(object sender, EventArgs e) { if(m_bInitializing) return; if(!m_cbKeyFile.Checked) m_cmbKeyFile.SelectedIndex = 0; EnableUserControls(); } private void ProcessTextChangedPassword(object sender, EventArgs e) { if(((Program.Config.UI.KeyPromptFlags & (ulong)AceKeyUIFlags.CheckPassword) == 0) && ((Program.Config.UI.KeyPromptFlags & (ulong)AceKeyUIFlags.UncheckPassword) == 0)) UIUtil.SetChecked(m_cbPassword, m_tbPassword.TextLength > 0); } private void OnCheckedHidePassword(object sender, EventArgs e) { bool bHide = m_cbHidePassword.Checked; if(!bHide && !AppPolicy.Try(AppPolicyId.UnhidePasswords)) { m_cbHidePassword.Checked = true; return; } m_secPassword.EnableProtection(bHide); if(!m_bInitializing) UIUtil.SetFocus(m_tbPassword, this); } private void OnBtnOK(object sender, EventArgs e) { if(!CreateCompositeKey()) this.DialogResult = DialogResult.None; } private void OnBtnCancel(object sender, EventArgs e) { m_pKey = null; } private void OnBtnHelp(object sender, EventArgs e) { if(m_bSecureDesktop) { m_bShowHelpAfterClose = true; this.DialogResult = DialogResult.Cancel; } else AppHelp.ShowHelp(AppDefs.HelpTopics.KeySources, null); } private void OnClickKeyFileBrowse(object sender, EventArgs e) { string strFile = null; if(m_bSecureDesktop) { FileBrowserForm dlg = new FileBrowserForm(); dlg.InitEx(false, KPRes.KeyFileSelect, KPRes.SecDeskFileDialogHint, AppDefs.FileDialogContext.KeyFile); if(dlg.ShowDialog() == DialogResult.OK) strFile = dlg.SelectedFile; UIUtil.DestroyForm(dlg); } else { string strFilter = UIUtil.CreateFileTypeFilter("key", KPRes.KeyFiles, true); OpenFileDialogEx ofd = UIUtil.CreateOpenFileDialog(KPRes.KeyFileSelect, strFilter, 2, null, false, AppDefs.FileDialogContext.KeyFile); if(ofd.ShowDialog() == DialogResult.OK) strFile = ofd.FileName; } if(!string.IsNullOrEmpty(strFile)) { if((Program.Config.UI.KeyPromptFlags & (ulong)AceKeyUIFlags.UncheckKeyFile) == 0) UIUtil.SetChecked(m_cbKeyFile, true); AddKeyFileSuggPriv(strFile, true); } EnableUserControls(); } private void OnKeyFileSelectedIndexChanged(object sender, EventArgs e) { if(m_bInitializing) return; string strKeyFile = m_cmbKeyFile.Text; Debug.Assert(strKeyFile != null); if(strKeyFile == null) strKeyFile = string.Empty; if(!strKeyFile.Equals(KPRes.NoKeyFileSpecifiedMeta)) { // if(ValidateKeyFile()) // { if((Program.Config.UI.KeyPromptFlags & (ulong)AceKeyUIFlags.UncheckKeyFile) == 0) UIUtil.SetChecked(m_cbKeyFile, true); // } } else if((Program.Config.UI.KeyPromptFlags & (ulong)AceKeyUIFlags.CheckKeyFile) == 0) UIUtil.SetChecked(m_cbKeyFile, false); EnableUserControls(); } private void AsyncFormLoad() { try { PopulateKeyFileSuggestions(); } catch(Exception) { Debug.Assert(false); } } private void PopulateKeyFileSuggestions() { if(Program.Config.Integration.SearchKeyFiles) { bool bSearchOnRemovable = Program.Config.Integration.SearchKeyFilesOnRemovableMedia; DriveInfo[] vDrives = DriveInfo.GetDrives(); foreach(DriveInfo di in vDrives) { if(di.DriveType == DriveType.NoRootDirectory) continue; else if((di.DriveType == DriveType.Removable) && !bSearchOnRemovable) continue; else if(di.DriveType == DriveType.CDRom) continue; ThreadPool.QueueUserWorkItem(new WaitCallback( this.AddKeyDriveSuggAsync), di); } } } private void AddKeyDriveSuggAsync(object oDriveInfo) { try { DriveInfo di = (oDriveInfo as DriveInfo); if(di == null) { Debug.Assert(false); return; } if(!di.IsReady) return; List lFiles = UrlUtil.GetFileInfos(di.RootDirectory, "*." + AppDefs.FileExtension.KeyFile, SearchOption.TopDirectoryOnly); foreach(FileInfo fi in lFiles) AddKeyFileSuggAsync(fi.FullName, null); } catch(Exception) { Debug.Assert(false); } } private void AddKeyFileSuggAsync(string str, bool? obSelect) { if(m_cmbKeyFile.InvokeRequired) m_cmbKeyFile.BeginInvoke(new AkfsDelegate( this.AddKeyFileSuggPriv), str, obSelect); else AddKeyFileSuggPriv(str, obSelect); } private delegate void AkfsDelegate(string str, bool? obSelect); private void AddKeyFileSuggPriv(string str, bool? obSelect) { try { if(m_bDisposed) return; // Slow drive if(string.IsNullOrEmpty(str)) { Debug.Assert(false); return; } int iIndex = m_lKeyFileNames.IndexOf(str); if(iIndex < 0) { iIndex = m_lKeyFileNames.Count; m_lKeyFileNames.Add(str); // m_lKeyFileImages.Add(img); if(m_cmbKeyFile.Items.Add(str) != iIndex) { Debug.Assert(false); } } if(obSelect.HasValue) { if(obSelect.Value) m_cmbKeyFile.SelectedIndex = iIndex; } else if((m_aKeyAssoc != null) && m_bCanModKeyFile) { if(str.Equals(m_aKeyAssoc.KeyFilePath, StrUtil.CaseIgnoreCmp) || str.Equals(m_aKeyAssoc.KeyProvider, StrUtil.CaseIgnoreCmp)) { m_cmbKeyFile.SelectedIndex = iIndex; m_bCanModKeyFile = false; } } } catch(Exception) { Debug.Assert(false); } } private void OnFormClosed(object sender, FormClosedEventArgs e) { GlobalWindowManager.RemoveWindow(this); } private void OnBtnExit(object sender, EventArgs e) { if(!m_bCanExit) { Debug.Assert(false); this.DialogResult = DialogResult.None; return; } m_bHasExited = true; } private void OnFormClosing(object sender, FormClosingEventArgs e) { // if(m_bRedirectActivation) Program.MainForm.RedirectActivationPop(); CleanUpEx(); } } } KeePass/Forms/TextEncodingForm.Designer.cs0000664000000000000000000001277412501532466017523 0ustar rootrootnamespace KeePass.Forms { partial class TextEncodingForm { /// /// Required designer variable. /// private System.ComponentModel.IContainer components = null; /// /// Clean up any resources being used. /// /// true if managed resources should be disposed; otherwise, false. protected override void Dispose(bool disposing) { if(disposing && (components != null)) { components.Dispose(); } base.Dispose(disposing); } #region Windows Form Designer generated code /// /// Required method for Designer support - do not modify /// the contents of this method with the code editor. /// private void InitializeComponent() { this.m_btnOK = new System.Windows.Forms.Button(); this.m_btnCancel = new System.Windows.Forms.Button(); this.m_lblSelEnc = new System.Windows.Forms.Label(); this.m_cmbEnc = new System.Windows.Forms.ComboBox(); this.m_lblPreview = new System.Windows.Forms.Label(); this.m_rtbPreview = new KeePass.UI.CustomRichTextBoxEx(); this.m_lblContext = new System.Windows.Forms.Label(); this.SuspendLayout(); // // m_btnOK // this.m_btnOK.DialogResult = System.Windows.Forms.DialogResult.OK; this.m_btnOK.Location = new System.Drawing.Point(459, 12); this.m_btnOK.Name = "m_btnOK"; this.m_btnOK.Size = new System.Drawing.Size(75, 23); this.m_btnOK.TabIndex = 0; this.m_btnOK.Text = "OK"; this.m_btnOK.UseVisualStyleBackColor = true; this.m_btnOK.Click += new System.EventHandler(this.OnBtnOK); // // m_btnCancel // this.m_btnCancel.DialogResult = System.Windows.Forms.DialogResult.Cancel; this.m_btnCancel.Location = new System.Drawing.Point(459, 41); this.m_btnCancel.Name = "m_btnCancel"; this.m_btnCancel.Size = new System.Drawing.Size(75, 23); this.m_btnCancel.TabIndex = 1; this.m_btnCancel.Text = "Cancel"; this.m_btnCancel.UseVisualStyleBackColor = true; this.m_btnCancel.Click += new System.EventHandler(this.OnBtnCancel); // // m_lblSelEnc // this.m_lblSelEnc.AutoSize = true; this.m_lblSelEnc.Location = new System.Drawing.Point(9, 37); this.m_lblSelEnc.Name = "m_lblSelEnc"; this.m_lblSelEnc.Size = new System.Drawing.Size(155, 13); this.m_lblSelEnc.TabIndex = 3; this.m_lblSelEnc.Text = "Select the encoding of the text:"; // // m_cmbEnc // this.m_cmbEnc.DropDownStyle = System.Windows.Forms.ComboBoxStyle.DropDownList; this.m_cmbEnc.FormattingEnabled = true; this.m_cmbEnc.Location = new System.Drawing.Point(12, 53); this.m_cmbEnc.MaxDropDownItems = 12; this.m_cmbEnc.Name = "m_cmbEnc"; this.m_cmbEnc.Size = new System.Drawing.Size(385, 21); this.m_cmbEnc.TabIndex = 4; this.m_cmbEnc.SelectedIndexChanged += new System.EventHandler(this.OnEncSelectedIndexChanged); // // m_lblPreview // this.m_lblPreview.AutoSize = true; this.m_lblPreview.Location = new System.Drawing.Point(9, 86); this.m_lblPreview.Name = "m_lblPreview"; this.m_lblPreview.Size = new System.Drawing.Size(71, 13); this.m_lblPreview.TabIndex = 5; this.m_lblPreview.Text = "Text preview:"; // // m_rtbPreview // this.m_rtbPreview.AcceptsTab = true; this.m_rtbPreview.DetectUrls = false; this.m_rtbPreview.Location = new System.Drawing.Point(12, 102); this.m_rtbPreview.Name = "m_rtbPreview"; this.m_rtbPreview.ReadOnly = true; this.m_rtbPreview.ScrollBars = System.Windows.Forms.RichTextBoxScrollBars.ForcedBoth; this.m_rtbPreview.Size = new System.Drawing.Size(522, 314); this.m_rtbPreview.TabIndex = 6; this.m_rtbPreview.Text = ""; this.m_rtbPreview.WordWrap = false; // // m_lblContext // this.m_lblContext.Location = new System.Drawing.Point(9, 13); this.m_lblContext.Name = "m_lblContext"; this.m_lblContext.Size = new System.Drawing.Size(444, 17); this.m_lblContext.TabIndex = 2; this.m_lblContext.Text = "<>"; // // TextEncodingForm // this.AcceptButton = this.m_btnOK; this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F); this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; this.CancelButton = this.m_btnCancel; this.ClientSize = new System.Drawing.Size(546, 428); this.Controls.Add(this.m_lblContext); this.Controls.Add(this.m_rtbPreview); this.Controls.Add(this.m_lblPreview); this.Controls.Add(this.m_cmbEnc); this.Controls.Add(this.m_lblSelEnc); this.Controls.Add(this.m_btnCancel); this.Controls.Add(this.m_btnOK); this.FormBorderStyle = System.Windows.Forms.FormBorderStyle.FixedDialog; this.MaximizeBox = false; this.MinimizeBox = false; this.Name = "TextEncodingForm"; this.ShowInTaskbar = false; this.StartPosition = System.Windows.Forms.FormStartPosition.CenterParent; this.Text = "Text Encoding"; this.Load += new System.EventHandler(this.OnFormLoad); this.FormClosed += new System.Windows.Forms.FormClosedEventHandler(this.OnFormClosed); this.ResumeLayout(false); this.PerformLayout(); } #endregion private System.Windows.Forms.Button m_btnOK; private System.Windows.Forms.Button m_btnCancel; private System.Windows.Forms.Label m_lblSelEnc; private System.Windows.Forms.ComboBox m_cmbEnc; private System.Windows.Forms.Label m_lblPreview; private KeePass.UI.CustomRichTextBoxEx m_rtbPreview; private System.Windows.Forms.Label m_lblContext; } }KeePass/Forms/AboutForm.Designer.cs0000664000000000000000000002026712501526572016177 0ustar rootrootnamespace KeePass.Forms { partial class AboutForm { /// /// Erforderliche Designervariable. /// private System.ComponentModel.IContainer components = null; /// /// Verwendete Ressourcen bereinigen. /// /// True, wenn verwaltete Ressourcen gelöscht werden sollen; andernfalls False. protected override void Dispose(bool disposing) { if(disposing && (components != null)) { components.Dispose(); } base.Dispose(disposing); } #region Vom Windows Form-Designer generierter Code /// /// Erforderliche Methode für die Designerunterstützung. /// Der Inhalt der Methode darf nicht mit dem Code-Editor geändert werden. /// private void InitializeComponent() { this.m_bannerImage = new System.Windows.Forms.PictureBox(); this.m_lblCopyright = new System.Windows.Forms.Label(); this.m_lblOsi = new System.Windows.Forms.Label(); this.m_lblGpl = new System.Windows.Forms.Label(); this.m_linkHomepage = new System.Windows.Forms.LinkLabel(); this.m_linkHelp = new System.Windows.Forms.LinkLabel(); this.m_linkLicense = new System.Windows.Forms.LinkLabel(); this.m_linkAcknowledgements = new System.Windows.Forms.LinkLabel(); this.m_linkDonate = new System.Windows.Forms.LinkLabel(); this.m_btnOK = new System.Windows.Forms.Button(); this.m_lvComponents = new KeePass.UI.CustomListViewEx(); ((System.ComponentModel.ISupportInitialize)(this.m_bannerImage)).BeginInit(); this.SuspendLayout(); // // m_bannerImage // this.m_bannerImage.Dock = System.Windows.Forms.DockStyle.Top; this.m_bannerImage.Location = new System.Drawing.Point(0, 0); this.m_bannerImage.Name = "m_bannerImage"; this.m_bannerImage.Size = new System.Drawing.Size(424, 60); this.m_bannerImage.TabIndex = 0; this.m_bannerImage.TabStop = false; // // m_lblCopyright // this.m_lblCopyright.Location = new System.Drawing.Point(10, 72); this.m_lblCopyright.Name = "m_lblCopyright"; this.m_lblCopyright.Size = new System.Drawing.Size(402, 15); this.m_lblCopyright.TabIndex = 1; // // m_lblOsi // this.m_lblOsi.Location = new System.Drawing.Point(10, 96); this.m_lblOsi.Name = "m_lblOsi"; this.m_lblOsi.Size = new System.Drawing.Size(402, 14); this.m_lblOsi.TabIndex = 2; this.m_lblOsi.Text = "KeePass is OSI Certified Open Source Software."; // // m_lblGpl // this.m_lblGpl.Location = new System.Drawing.Point(10, 119); this.m_lblGpl.Name = "m_lblGpl"; this.m_lblGpl.Size = new System.Drawing.Size(402, 27); this.m_lblGpl.TabIndex = 3; this.m_lblGpl.Text = "The program is distributed under the terms of the GNU General Public License v2 o" + "r later."; // // m_linkHomepage // this.m_linkHomepage.AutoSize = true; this.m_linkHomepage.Location = new System.Drawing.Point(10, 155); this.m_linkHomepage.Name = "m_linkHomepage"; this.m_linkHomepage.Size = new System.Drawing.Size(91, 13); this.m_linkHomepage.TabIndex = 4; this.m_linkHomepage.TabStop = true; this.m_linkHomepage.Text = "KeePass Website"; this.m_linkHomepage.LinkClicked += new System.Windows.Forms.LinkLabelLinkClickedEventHandler(this.OnLinkHomepage); // // m_linkHelp // this.m_linkHelp.AutoSize = true; this.m_linkHelp.Location = new System.Drawing.Point(213, 155); this.m_linkHelp.Name = "m_linkHelp"; this.m_linkHelp.Size = new System.Drawing.Size(29, 13); this.m_linkHelp.TabIndex = 6; this.m_linkHelp.TabStop = true; this.m_linkHelp.Text = "Help"; this.m_linkHelp.LinkClicked += new System.Windows.Forms.LinkLabelLinkClickedEventHandler(this.OnLinkHelpFile); // // m_linkLicense // this.m_linkLicense.AutoSize = true; this.m_linkLicense.Location = new System.Drawing.Point(10, 177); this.m_linkLicense.Name = "m_linkLicense"; this.m_linkLicense.Size = new System.Drawing.Size(44, 13); this.m_linkLicense.TabIndex = 7; this.m_linkLicense.TabStop = true; this.m_linkLicense.Text = "License"; this.m_linkLicense.LinkClicked += new System.Windows.Forms.LinkLabelLinkClickedEventHandler(this.OnLinkLicenseFile); // // m_linkAcknowledgements // this.m_linkAcknowledgements.AutoSize = true; this.m_linkAcknowledgements.Location = new System.Drawing.Point(107, 155); this.m_linkAcknowledgements.Name = "m_linkAcknowledgements"; this.m_linkAcknowledgements.Size = new System.Drawing.Size(100, 13); this.m_linkAcknowledgements.TabIndex = 5; this.m_linkAcknowledgements.TabStop = true; this.m_linkAcknowledgements.Text = "Acknowledgements"; this.m_linkAcknowledgements.LinkClicked += new System.Windows.Forms.LinkLabelLinkClickedEventHandler(this.OnLinkAcknowledgements); // // m_linkDonate // this.m_linkDonate.AutoSize = true; this.m_linkDonate.Location = new System.Drawing.Point(107, 177); this.m_linkDonate.Name = "m_linkDonate"; this.m_linkDonate.Size = new System.Drawing.Size(42, 13); this.m_linkDonate.TabIndex = 8; this.m_linkDonate.TabStop = true; this.m_linkDonate.Text = "Donate"; this.m_linkDonate.LinkClicked += new System.Windows.Forms.LinkLabelLinkClickedEventHandler(this.OnLinkDonate); // // m_btnOK // this.m_btnOK.DialogResult = System.Windows.Forms.DialogResult.OK; this.m_btnOK.Location = new System.Drawing.Point(337, 315); this.m_btnOK.Name = "m_btnOK"; this.m_btnOK.Size = new System.Drawing.Size(75, 23); this.m_btnOK.TabIndex = 0; this.m_btnOK.Text = "OK"; this.m_btnOK.UseVisualStyleBackColor = true; // // m_lvComponents // this.m_lvComponents.FullRowSelect = true; this.m_lvComponents.HeaderStyle = System.Windows.Forms.ColumnHeaderStyle.Nonclickable; this.m_lvComponents.Location = new System.Drawing.Point(13, 203); this.m_lvComponents.Name = "m_lvComponents"; this.m_lvComponents.Size = new System.Drawing.Size(398, 101); this.m_lvComponents.TabIndex = 9; this.m_lvComponents.UseCompatibleStateImageBehavior = false; this.m_lvComponents.View = System.Windows.Forms.View.Details; // // AboutForm // this.AcceptButton = this.m_btnOK; this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F); this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; this.CancelButton = this.m_btnOK; this.ClientSize = new System.Drawing.Size(424, 350); this.Controls.Add(this.m_lvComponents); this.Controls.Add(this.m_btnOK); this.Controls.Add(this.m_linkDonate); this.Controls.Add(this.m_linkAcknowledgements); this.Controls.Add(this.m_linkLicense); this.Controls.Add(this.m_linkHelp); this.Controls.Add(this.m_linkHomepage); this.Controls.Add(this.m_lblGpl); this.Controls.Add(this.m_lblOsi); this.Controls.Add(this.m_lblCopyright); this.Controls.Add(this.m_bannerImage); this.FormBorderStyle = System.Windows.Forms.FormBorderStyle.FixedDialog; this.MaximizeBox = false; this.MinimizeBox = false; this.Name = "AboutForm"; this.ShowInTaskbar = false; this.SizeGripStyle = System.Windows.Forms.SizeGripStyle.Hide; this.StartPosition = System.Windows.Forms.FormStartPosition.CenterParent; this.Text = "About KeePass"; this.Load += new System.EventHandler(this.OnFormLoad); this.FormClosed += new System.Windows.Forms.FormClosedEventHandler(this.OnFormClosed); ((System.ComponentModel.ISupportInitialize)(this.m_bannerImage)).EndInit(); this.ResumeLayout(false); this.PerformLayout(); } #endregion private System.Windows.Forms.PictureBox m_bannerImage; private System.Windows.Forms.Label m_lblCopyright; private System.Windows.Forms.Label m_lblOsi; private System.Windows.Forms.Label m_lblGpl; private System.Windows.Forms.LinkLabel m_linkHomepage; private System.Windows.Forms.LinkLabel m_linkHelp; private System.Windows.Forms.LinkLabel m_linkLicense; private System.Windows.Forms.LinkLabel m_linkAcknowledgements; private System.Windows.Forms.LinkLabel m_linkDonate; private System.Windows.Forms.Button m_btnOK; private KeePass.UI.CustomListViewEx m_lvComponents; } }KeePass/Forms/DataViewerForm.cs0000664000000000000000000003665113222430410015407 0ustar rootroot/* KeePass Password Safe - The Open-Source Password Manager Copyright (C) 2003-2018 Dominik Reichl This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ using System; using System.Collections.Generic; using System.ComponentModel; using System.Diagnostics; using System.Drawing; using System.Drawing.Drawing2D; using System.Drawing.Imaging; using System.IO; using System.Text; using System.Windows.Forms; using KeePass.App; using KeePass.Native; using KeePass.Resources; using KeePass.UI; using KeePass.Util; using KeePassLib; using KeePassLib.Utility; namespace KeePass.Forms { public partial class DataViewerForm : Form { private string m_strDataDesc = string.Empty; private byte[] m_pbData = null; private bool m_bInitializing = true; private uint m_uStartOffset = 0; private BinaryDataClass m_bdc = BinaryDataClass.Unknown; private readonly string m_strViewerHex = KPRes.HexViewer; private readonly string m_strViewerText = KPRes.TextViewer; private readonly string m_strViewerImage = KPRes.ImageViewer; private readonly string m_strViewerWeb = KPRes.WebBrowser; private readonly string m_strDataExpand = "--- " + KPRes.More + " ---"; private bool m_bDataExpanded = false; private string m_strInitialFormRect = string.Empty; private RichTextBoxContextMenu m_ctxText = new RichTextBoxContextMenu(); private Image m_img = null; private Image m_imgResized = null; public event EventHandler DvfInit; public event EventHandler DvfUpdating; public event EventHandler DvfRelease; public static bool SupportsDataType(BinaryDataClass bdc) { return ((bdc == BinaryDataClass.Text) || (bdc == BinaryDataClass.RichText) || (bdc == BinaryDataClass.Image) || (bdc == BinaryDataClass.WebDocument)); } public void InitEx(string strDataDesc, byte[] pbData) { if(strDataDesc != null) m_strDataDesc = strDataDesc; m_pbData = pbData; } public DataViewerForm() { InitializeComponent(); Program.Translation.ApplyTo(this); } private void OnFormLoad(object sender, EventArgs e) { Debug.Assert(m_pbData != null); if(m_pbData == null) throw new InvalidOperationException(); m_bInitializing = true; GlobalWindowManager.AddWindow(this); this.Icon = AppIcons.Default; this.DoubleBuffered = true; string strTitle = PwDefs.ShortProductName + " " + KPRes.DataViewer; if(m_strDataDesc.Length > 0) strTitle = m_strDataDesc + " - " + strTitle; this.Text = strTitle; m_strInitialFormRect = UIUtil.SetWindowScreenRectEx(this, Program.Config.UI.DataViewerRect); m_tssStatusMain.Text = KPRes.Ready; m_ctxText.Attach(m_rtbText, this); m_rtbText.Dock = DockStyle.Fill; m_webBrowser.Dock = DockStyle.Fill; m_pnlImageViewer.Dock = DockStyle.Fill; m_picBox.Dock = DockStyle.Fill; m_tslEncoding.Text = KPRes.Encoding + ":"; foreach(StrEncodingInfo seiEnum in StrUtil.Encodings) { m_tscEncoding.Items.Add(seiEnum.Name); } StrEncodingInfo seiGuess = BinaryDataClassifier.GetStringEncoding( m_pbData, out m_uStartOffset); int iSel = 0; if(seiGuess != null) iSel = Math.Max(m_tscEncoding.FindStringExact(seiGuess.Name), 0); m_tscEncoding.SelectedIndex = iSel; m_tslZoom.Text = KPRes.Zoom + ":"; m_tscZoom.Items.Add(KPRes.Auto); int[] vZooms = new int[] { 10, 25, 50, 75, 100, 125, 150, 200, 400 }; foreach(int iZoom in vZooms) m_tscZoom.Items.Add(iZoom.ToString() + @"%"); m_tscZoom.SelectedIndex = 0; m_tslViewer.Text = KPRes.ShowIn + ":"; m_tscViewers.Items.Add(m_strViewerHex); m_tscViewers.Items.Add(m_strViewerText); m_tscViewers.Items.Add(m_strViewerImage); m_tscViewers.Items.Add(m_strViewerWeb); m_bdc = BinaryDataClassifier.Classify(m_strDataDesc, m_pbData); if((m_bdc == BinaryDataClass.Text) || (m_bdc == BinaryDataClass.RichText)) m_tscViewers.SelectedIndex = 1; else if(m_bdc == BinaryDataClass.Image) m_tscViewers.SelectedIndex = 2; else if(m_bdc == BinaryDataClass.WebDocument) m_tscViewers.SelectedIndex = 3; else m_tscViewers.SelectedIndex = 0; if(this.DvfInit != null) this.DvfInit(this, new DvfContextEventArgs(this, m_pbData, m_strDataDesc, m_tscViewers)); m_bInitializing = false; UpdateDataView(); } private void OnRichTextBoxLinkClicked(object sender, LinkClickedEventArgs e) { string strLink = e.LinkText; if(string.IsNullOrEmpty(strLink)) { Debug.Assert(false); return; } try { if((strLink == m_strDataExpand) && (m_tscViewers.Text == m_strViewerHex)) { m_bDataExpanded = true; UpdateHexView(); m_rtbText.Select(m_rtbText.TextLength, 0); m_rtbText.ScrollToCaret(); } else WinUtil.OpenUrl(strLink, null); } catch(Exception) { } // ScrollToCaret might throw (but still works) } private string BinaryDataToString(bool bReplaceNulls) { string strEnc = m_tscEncoding.Text; StrEncodingInfo sei = StrUtil.GetEncoding(strEnc); try { string str = (sei.Encoding.GetString(m_pbData, (int)m_uStartOffset, m_pbData.Length - (int)m_uStartOffset) ?? string.Empty); if(bReplaceNulls) str = StrUtil.ReplaceNulls(str); return str; } catch(Exception) { } return string.Empty; } private void SetRtbData(string strData, bool bRtf, bool bFixedFont) { if(strData == null) { Debug.Assert(false); strData = string.Empty; } m_rtbText.Clear(); // Clear formatting (esp. induced by Unicode) if(bFixedFont) FontUtil.AssignDefaultMono(m_rtbText, false); else FontUtil.AssignDefault(m_rtbText); if(bRtf) m_rtbText.Rtf = strData; else { m_rtbText.Text = strData; Font f = (bFixedFont ? FontUtil.MonoFont : FontUtil.DefaultFont); if(f != null) { m_rtbText.SelectAll(); m_rtbText.SelectionFont = f; m_rtbText.Select(0, 0); } else { Debug.Assert(false); } } } private void UpdateHexView() { int cbData = (m_bDataExpanded ? m_pbData.Length : Math.Min(m_pbData.Length, 16 * 256)); const int cbGrp = 4; const int cbLine = 16; int iMaxAddrWidth = Convert.ToString(Math.Max(cbData - 1, 0), 16).Length; int cbDataUp = cbData; if((cbDataUp % cbLine) != 0) cbDataUp = cbDataUp + cbLine - (cbDataUp % cbLine); Debug.Assert(((cbDataUp % cbLine) == 0) && (cbDataUp >= cbData)); StringBuilder sb = new StringBuilder(); for(int i = 0; i < cbDataUp; ++i) { if((i % cbLine) == 0) { sb.Append(Convert.ToString(i, 16).ToUpper().PadLeft( iMaxAddrWidth, '0')); sb.Append(": "); } if(i < cbData) { byte bt = m_pbData[i]; byte btHigh = (byte)(bt >> 4); byte btLow = (byte)(bt & 0x0F); if(btHigh >= 10) sb.Append((char)('A' + btHigh - 10)); else sb.Append((char)('0' + btHigh)); if(btLow >= 10) sb.Append((char)('A' + btLow - 10)); else sb.Append((char)('0' + btLow)); } else sb.Append(" "); if(((i + 1) % cbGrp) == 0) sb.Append(' '); if(((i + 1) % cbLine) == 0) { sb.Append(' '); int iStart = i - cbLine + 1; int iEndExcl = Math.Min(iStart + cbLine, cbData); for(int j = iStart; j < iEndExcl; ++j) sb.Append(StrUtil.ByteToSafeChar(m_pbData[j])); sb.AppendLine(); } } if(cbData < m_pbData.Length) sb.AppendLine(m_strDataExpand); SetRtbData(sb.ToString(), false, true); if(cbData < m_pbData.Length) { int iLinkStart = m_rtbText.Text.LastIndexOf(m_strDataExpand); if(iLinkStart >= 0) { m_rtbText.Select(iLinkStart, m_strDataExpand.Length); UIUtil.RtfSetSelectionLink(m_rtbText); m_rtbText.Select(0, 0); } else { Debug.Assert(false); } } } private void UpdateVisibility(string strViewer, bool bMakeVisible) { if(string.IsNullOrEmpty(strViewer)) { Debug.Assert(false); return; } if(!bMakeVisible) // Hide all except strViewer { if((strViewer != m_strViewerHex) && (strViewer != m_strViewerText)) m_rtbText.Visible = false; if(strViewer != m_strViewerImage) { m_picBox.Visible = false; m_pnlImageViewer.Visible = false; } if(strViewer != m_strViewerWeb) m_webBrowser.Visible = false; } else // Show strViewer { if((strViewer == m_strViewerHex) || (strViewer == m_strViewerText)) m_rtbText.Visible = true; else if(strViewer == m_strViewerImage) { m_pnlImageViewer.Visible = true; m_picBox.Visible = true; } else if(strViewer == m_strViewerWeb) m_webBrowser.Visible = true; } } private void UpdateDataView() { if(m_bInitializing) return; string strViewer = m_tscViewers.Text; bool bText = ((strViewer == m_strViewerText) || (strViewer == m_strViewerWeb)); bool bImage = (strViewer == m_strViewerImage); UpdateVisibility(strViewer, false); m_tssSeparator0.Visible = (bText || bImage); m_tslEncoding.Visible = m_tscEncoding.Visible = bText; m_tslZoom.Visible = m_tscZoom.Visible = bImage; try { if(this.DvfUpdating != null) { DvfContextEventArgs args = new DvfContextEventArgs(this, m_pbData, m_strDataDesc, m_tscViewers); this.DvfUpdating(this, args); if(args.Cancel) return; } if(strViewer == m_strViewerHex) UpdateHexView(); else if(strViewer == m_strViewerText) { string strData = BinaryDataToString(true); SetRtbData(strData, (m_bdc == BinaryDataClass.RichText), false); } else if(strViewer == m_strViewerImage) { if(m_img == null) m_img = GfxUtil.LoadImage(m_pbData); UpdateImageView(); } else if(strViewer == m_strViewerWeb) { string strData = BinaryDataToString(false); UIUtil.SetWebBrowserDocument(m_webBrowser, strData); } } catch(Exception) { } UpdateVisibility(strViewer, true); } private void OnViewersSelectedIndexChanged(object sender, EventArgs e) { UpdateDataView(); } private void OnEncodingSelectedIndexChanged(object sender, EventArgs e) { UpdateDataView(); } private void OnFormSizeChanged(object sender, EventArgs e) { UpdateImageView(); } private void UpdateImageView() { if(m_img == null) return; string strZoom = m_tscZoom.Text; if(string.IsNullOrEmpty(strZoom) || (strZoom == KPRes.Auto)) { m_pnlImageViewer.AutoScroll = false; m_picBox.Dock = DockStyle.Fill; m_picBox.Image = m_img; if((m_img.Width > m_picBox.ClientSize.Width) || (m_img.Height > m_picBox.ClientSize.Height)) { m_picBox.SizeMode = PictureBoxSizeMode.Zoom; } else m_picBox.SizeMode = PictureBoxSizeMode.CenterImage; return; } if(!strZoom.EndsWith(@"%")) { Debug.Assert(false); return; } int iZoom; if(!int.TryParse(strZoom.Substring(0, strZoom.Length - 1), out iZoom)) { Debug.Assert(false); return; } int cliW = m_pnlImageViewer.ClientRectangle.Width; int cliH = m_pnlImageViewer.ClientRectangle.Height; int dx = (m_img.Width * iZoom) / 100; int dy = (m_img.Height * iZoom) / 100; float fScrollX = 0.5f, fScrollY = 0.5f; if(m_pnlImageViewer.AutoScroll) { Point ptOffset = m_pnlImageViewer.AutoScrollPosition; Size sz = m_picBox.ClientSize; if(sz.Width > cliW) { fScrollX = Math.Abs((float)ptOffset.X / (float)(sz.Width - cliW)); if(fScrollX < 0.0f) { Debug.Assert(false); fScrollX = 0.0f; } if(fScrollX > 1.0f) { Debug.Assert(false); fScrollX = 1.0f; } } if(sz.Height > cliH) { fScrollY = Math.Abs((float)ptOffset.Y / (float)(sz.Height - cliH)); if(fScrollY < 0.0f) { Debug.Assert(false); fScrollY = 0.0f; } if(fScrollY > 1.0f) { Debug.Assert(false); fScrollY = 1.0f; } } } m_pnlImageViewer.AutoScroll = false; m_picBox.Dock = DockStyle.None; m_picBox.SizeMode = PictureBoxSizeMode.AutoSize; int x = 0, y = 0; if(dx < cliW) x = (cliW - dx) / 2; if(dy < cliH) y = (cliH - dy) / 2; m_picBox.Location = new Point(x, y); if((dx == m_img.Width) && (dy == m_img.Height)) m_picBox.Image = m_img; else if((m_imgResized != null) && (m_imgResized.Width == dx) && (m_imgResized.Height == dy)) m_picBox.Image = m_imgResized; else { Image imgToDispose = m_imgResized; m_imgResized = GfxUtil.ScaleImage(m_img, dx, dy); m_picBox.Image = m_imgResized; if(imgToDispose != null) imgToDispose.Dispose(); } m_pnlImageViewer.AutoScroll = true; int sx = 0, sy = 0; if(dx > cliW) sx = (int)(fScrollX * (float)(dx - cliW)); if(dy > cliH) sy = (int)(fScrollY * (float)(dy - cliH)); try { m_pnlImageViewer.AutoScrollPosition = new Point(sx, sy); } catch(Exception) { Debug.Assert(false); } } private void OnFormClosing(object sender, FormClosingEventArgs e) { if(this.DvfRelease != null) { DvfContextEventArgs args = new DvfContextEventArgs(this, m_pbData, m_strDataDesc, m_tscViewers); this.DvfRelease(sender, args); if(args.Cancel) { e.Cancel = true; return; } } string strRect = UIUtil.GetWindowScreenRect(this); if(strRect != m_strInitialFormRect) // Don't overwrite "" Program.Config.UI.DataViewerRect = strRect; m_picBox.Image = null; if(m_img != null) { m_img.Dispose(); m_img = null; } if(m_imgResized != null) { m_imgResized.Dispose(); m_imgResized = null; } m_ctxText.Detach(); GlobalWindowManager.RemoveWindow(this); } protected override bool ProcessCmdKey(ref Message msg, Keys keyData) { if(keyData == Keys.Escape) { bool? obKeyDown = NativeMethods.IsKeyDownMessage(ref msg); if(obKeyDown.HasValue) { if(obKeyDown.Value) this.Close(); return true; } } return base.ProcessCmdKey(ref msg, keyData); } private void OnZoomSelectedIndexChanged(object sender, EventArgs e) { UpdateImageView(); } } public sealed class DvfContextEventArgs : CancellableOperationEventArgs { private DataViewerForm m_form; public DataViewerForm Form { get { return m_form; } } private byte[] m_pbData; public byte[] Data { get { return m_pbData; } } private string m_strDataDesc; public string DataDescription { get { return m_strDataDesc; } } private ToolStripComboBox m_tscViewers; public ToolStripComboBox ViewersComboBox { get { return m_tscViewers; } } public DvfContextEventArgs(DataViewerForm form, byte[] pbData, string strDataDesc, ToolStripComboBox cbViewers) { m_form = form; m_pbData = pbData; m_strDataDesc = strDataDesc; m_tscViewers = cbViewers; } } } KeePass/Forms/PrintForm.Designer.cs0000664000000000000000000007220013214231130016174 0ustar rootrootnamespace KeePass.Forms { partial class PrintForm { /// /// Erforderliche Designervariable. /// private System.ComponentModel.IContainer components = null; /// /// Verwendete Ressourcen bereinigen. /// /// True, wenn verwaltete Ressourcen gelöscht werden sollen; andernfalls False. protected override void Dispose(bool disposing) { if(disposing && (components != null)) { components.Dispose(); } base.Dispose(disposing); } #region Vom Windows Form-Designer generierter Code /// /// Erforderliche Methode für die Designerunterstützung. /// Der Inhalt der Methode darf nicht mit dem Code-Editor geändert werden. /// private void InitializeComponent() { this.m_tabMain = new System.Windows.Forms.TabControl(); this.m_tabPreview = new System.Windows.Forms.TabPage(); this.m_wbMain = new System.Windows.Forms.WebBrowser(); this.m_lblPreviewHint = new System.Windows.Forms.Label(); this.m_tabDataLayout = new System.Windows.Forms.TabPage(); this.m_grpOptions = new System.Windows.Forms.GroupBox(); this.m_lblSpr = new System.Windows.Forms.Label(); this.m_cmbSpr = new System.Windows.Forms.ComboBox(); this.m_grpSorting = new System.Windows.Forms.GroupBox(); this.m_lblEntrySortHint = new System.Windows.Forms.Label(); this.m_cmbSortEntries = new System.Windows.Forms.ComboBox(); this.m_lblSortEntries = new System.Windows.Forms.Label(); this.m_grpFont = new System.Windows.Forms.GroupBox(); this.m_cbSmallMono = new System.Windows.Forms.CheckBox(); this.m_cbMonospaceForPasswords = new System.Windows.Forms.CheckBox(); this.m_rbMonospace = new System.Windows.Forms.RadioButton(); this.m_rbSansSerif = new System.Windows.Forms.RadioButton(); this.m_rbSerif = new System.Windows.Forms.RadioButton(); this.m_grpFields = new System.Windows.Forms.GroupBox(); this.m_cbIcon = new System.Windows.Forms.CheckBox(); this.m_cbUuid = new System.Windows.Forms.CheckBox(); this.m_cbTags = new System.Windows.Forms.CheckBox(); this.m_cbCustomStrings = new System.Windows.Forms.CheckBox(); this.m_cbGroups = new System.Windows.Forms.CheckBox(); this.m_linkDeselectAllFields = new System.Windows.Forms.LinkLabel(); this.m_linkSelectAllFields = new System.Windows.Forms.LinkLabel(); this.m_cbAutoType = new System.Windows.Forms.CheckBox(); this.m_cbLastMod = new System.Windows.Forms.CheckBox(); this.m_cbCreation = new System.Windows.Forms.CheckBox(); this.m_cbExpire = new System.Windows.Forms.CheckBox(); this.m_cbNotes = new System.Windows.Forms.CheckBox(); this.m_cbPassword = new System.Windows.Forms.CheckBox(); this.m_cbUrl = new System.Windows.Forms.CheckBox(); this.m_cbUser = new System.Windows.Forms.CheckBox(); this.m_cbTitle = new System.Windows.Forms.CheckBox(); this.m_grpLayout = new System.Windows.Forms.GroupBox(); this.m_lblDetailsInfo = new System.Windows.Forms.Label(); this.m_lblTabularInfo = new System.Windows.Forms.Label(); this.m_rbDetails = new System.Windows.Forms.RadioButton(); this.m_rbTabular = new System.Windows.Forms.RadioButton(); this.m_bannerImage = new System.Windows.Forms.PictureBox(); this.m_btnOK = new System.Windows.Forms.Button(); this.m_btnCancel = new System.Windows.Forms.Button(); this.m_btnConfigPrinter = new System.Windows.Forms.Button(); this.m_btnPrintPreview = new System.Windows.Forms.Button(); this.m_tabMain.SuspendLayout(); this.m_tabPreview.SuspendLayout(); this.m_tabDataLayout.SuspendLayout(); this.m_grpOptions.SuspendLayout(); this.m_grpSorting.SuspendLayout(); this.m_grpFont.SuspendLayout(); this.m_grpFields.SuspendLayout(); this.m_grpLayout.SuspendLayout(); ((System.ComponentModel.ISupportInitialize)(this.m_bannerImage)).BeginInit(); this.SuspendLayout(); // // m_tabMain // this.m_tabMain.Controls.Add(this.m_tabPreview); this.m_tabMain.Controls.Add(this.m_tabDataLayout); this.m_tabMain.Location = new System.Drawing.Point(12, 66); this.m_tabMain.Name = "m_tabMain"; this.m_tabMain.SelectedIndex = 0; this.m_tabMain.Size = new System.Drawing.Size(601, 463); this.m_tabMain.TabIndex = 2; this.m_tabMain.SelectedIndexChanged += new System.EventHandler(this.OnTabSelectedIndexChanged); // // m_tabPreview // this.m_tabPreview.Controls.Add(this.m_wbMain); this.m_tabPreview.Controls.Add(this.m_lblPreviewHint); this.m_tabPreview.Location = new System.Drawing.Point(4, 22); this.m_tabPreview.Name = "m_tabPreview"; this.m_tabPreview.Padding = new System.Windows.Forms.Padding(3); this.m_tabPreview.Size = new System.Drawing.Size(593, 437); this.m_tabPreview.TabIndex = 0; this.m_tabPreview.Text = "Preview"; this.m_tabPreview.UseVisualStyleBackColor = true; // // m_wbMain // this.m_wbMain.AllowWebBrowserDrop = false; this.m_wbMain.Dock = System.Windows.Forms.DockStyle.Fill; this.m_wbMain.IsWebBrowserContextMenuEnabled = false; this.m_wbMain.Location = new System.Drawing.Point(3, 22); this.m_wbMain.MinimumSize = new System.Drawing.Size(20, 20); this.m_wbMain.Name = "m_wbMain"; this.m_wbMain.ScriptErrorsSuppressed = true; this.m_wbMain.Size = new System.Drawing.Size(587, 412); this.m_wbMain.TabIndex = 1; this.m_wbMain.WebBrowserShortcutsEnabled = false; // // m_lblPreviewHint // this.m_lblPreviewHint.Dock = System.Windows.Forms.DockStyle.Top; this.m_lblPreviewHint.ForeColor = System.Drawing.Color.Brown; this.m_lblPreviewHint.Location = new System.Drawing.Point(3, 3); this.m_lblPreviewHint.Name = "m_lblPreviewHint"; this.m_lblPreviewHint.Size = new System.Drawing.Size(587, 19); this.m_lblPreviewHint.TabIndex = 0; this.m_lblPreviewHint.Text = "Note that this preview is a layout preview only. To see a preview of the printed " + "document, click the \'Print Preview\' button."; // // m_tabDataLayout // this.m_tabDataLayout.Controls.Add(this.m_grpOptions); this.m_tabDataLayout.Controls.Add(this.m_grpSorting); this.m_tabDataLayout.Controls.Add(this.m_grpFont); this.m_tabDataLayout.Controls.Add(this.m_grpFields); this.m_tabDataLayout.Controls.Add(this.m_grpLayout); this.m_tabDataLayout.Location = new System.Drawing.Point(4, 22); this.m_tabDataLayout.Name = "m_tabDataLayout"; this.m_tabDataLayout.Size = new System.Drawing.Size(593, 437); this.m_tabDataLayout.TabIndex = 2; this.m_tabDataLayout.Text = "Layout"; this.m_tabDataLayout.UseVisualStyleBackColor = true; // // m_grpOptions // this.m_grpOptions.Controls.Add(this.m_lblSpr); this.m_grpOptions.Controls.Add(this.m_cmbSpr); this.m_grpOptions.Location = new System.Drawing.Point(299, 258); this.m_grpOptions.Name = "m_grpOptions"; this.m_grpOptions.Size = new System.Drawing.Size(282, 92); this.m_grpOptions.TabIndex = 3; this.m_grpOptions.TabStop = false; this.m_grpOptions.Text = "Options"; // // m_lblSpr // this.m_lblSpr.AutoSize = true; this.m_lblSpr.Location = new System.Drawing.Point(6, 22); this.m_lblSpr.Name = "m_lblSpr"; this.m_lblSpr.Size = new System.Drawing.Size(71, 13); this.m_lblSpr.TabIndex = 0; this.m_lblSpr.Text = "Placeholders:"; // // m_cmbSpr // this.m_cmbSpr.DropDownStyle = System.Windows.Forms.ComboBoxStyle.DropDownList; this.m_cmbSpr.FormattingEnabled = true; this.m_cmbSpr.Location = new System.Drawing.Point(83, 18); this.m_cmbSpr.Name = "m_cmbSpr"; this.m_cmbSpr.Size = new System.Drawing.Size(189, 21); this.m_cmbSpr.TabIndex = 1; // // m_grpSorting // this.m_grpSorting.Controls.Add(this.m_lblEntrySortHint); this.m_grpSorting.Controls.Add(this.m_cmbSortEntries); this.m_grpSorting.Controls.Add(this.m_lblSortEntries); this.m_grpSorting.Location = new System.Drawing.Point(10, 356); this.m_grpSorting.Name = "m_grpSorting"; this.m_grpSorting.Size = new System.Drawing.Size(571, 69); this.m_grpSorting.TabIndex = 4; this.m_grpSorting.TabStop = false; this.m_grpSorting.Text = "Sorting"; // // m_lblEntrySortHint // this.m_lblEntrySortHint.AutoSize = true; this.m_lblEntrySortHint.Location = new System.Drawing.Point(6, 46); this.m_lblEntrySortHint.Name = "m_lblEntrySortHint"; this.m_lblEntrySortHint.Size = new System.Drawing.Size(371, 13); this.m_lblEntrySortHint.TabIndex = 2; this.m_lblEntrySortHint.Text = "Entries are sorted within their groups, i.e. the group structure is not broken up" + "."; // // m_cmbSortEntries // this.m_cmbSortEntries.DropDownStyle = System.Windows.Forms.ComboBoxStyle.DropDownList; this.m_cmbSortEntries.FormattingEnabled = true; this.m_cmbSortEntries.Location = new System.Drawing.Point(111, 18); this.m_cmbSortEntries.Name = "m_cmbSortEntries"; this.m_cmbSortEntries.Size = new System.Drawing.Size(172, 21); this.m_cmbSortEntries.TabIndex = 1; // // m_lblSortEntries // this.m_lblSortEntries.AutoSize = true; this.m_lblSortEntries.Location = new System.Drawing.Point(6, 22); this.m_lblSortEntries.Name = "m_lblSortEntries"; this.m_lblSortEntries.Size = new System.Drawing.Size(99, 13); this.m_lblSortEntries.TabIndex = 0; this.m_lblSortEntries.Text = "Sort entries by field:"; // // m_grpFont // this.m_grpFont.Controls.Add(this.m_cbSmallMono); this.m_grpFont.Controls.Add(this.m_cbMonospaceForPasswords); this.m_grpFont.Controls.Add(this.m_rbMonospace); this.m_grpFont.Controls.Add(this.m_rbSansSerif); this.m_grpFont.Controls.Add(this.m_rbSerif); this.m_grpFont.Location = new System.Drawing.Point(10, 258); this.m_grpFont.Name = "m_grpFont"; this.m_grpFont.Size = new System.Drawing.Size(283, 92); this.m_grpFont.TabIndex = 2; this.m_grpFont.TabStop = false; this.m_grpFont.Text = "Font"; // // m_cbSmallMono // this.m_cbSmallMono.AutoSize = true; this.m_cbSmallMono.Location = new System.Drawing.Point(10, 66); this.m_cbSmallMono.Name = "m_cbSmallMono"; this.m_cbSmallMono.Size = new System.Drawing.Size(176, 17); this.m_cbSmallMono.TabIndex = 4; this.m_cbSmallMono.Text = "Use extra small monospace font"; this.m_cbSmallMono.UseVisualStyleBackColor = true; // // m_cbMonospaceForPasswords // this.m_cbMonospaceForPasswords.AutoSize = true; this.m_cbMonospaceForPasswords.Checked = true; this.m_cbMonospaceForPasswords.CheckState = System.Windows.Forms.CheckState.Checked; this.m_cbMonospaceForPasswords.Location = new System.Drawing.Point(10, 43); this.m_cbMonospaceForPasswords.Name = "m_cbMonospaceForPasswords"; this.m_cbMonospaceForPasswords.Size = new System.Drawing.Size(192, 17); this.m_cbMonospaceForPasswords.TabIndex = 3; this.m_cbMonospaceForPasswords.Text = "Use monospace font for passwords"; this.m_cbMonospaceForPasswords.UseVisualStyleBackColor = true; // // m_rbMonospace // this.m_rbMonospace.AutoSize = true; this.m_rbMonospace.Font = new System.Drawing.Font("Courier New", 8.25F); this.m_rbMonospace.Location = new System.Drawing.Point(142, 19); this.m_rbMonospace.Name = "m_rbMonospace"; this.m_rbMonospace.Size = new System.Drawing.Size(88, 18); this.m_rbMonospace.TabIndex = 2; this.m_rbMonospace.Text = "Monospace"; this.m_rbMonospace.UseVisualStyleBackColor = true; // // m_rbSansSerif // this.m_rbSansSerif.AutoSize = true; this.m_rbSansSerif.Checked = true; this.m_rbSansSerif.Font = new System.Drawing.Font("Tahoma", 8.25F); this.m_rbSansSerif.Location = new System.Drawing.Point(63, 19); this.m_rbSansSerif.Name = "m_rbSansSerif"; this.m_rbSansSerif.Size = new System.Drawing.Size(74, 17); this.m_rbSansSerif.TabIndex = 1; this.m_rbSansSerif.TabStop = true; this.m_rbSansSerif.Text = "Sans-Serif"; this.m_rbSansSerif.UseVisualStyleBackColor = true; // // m_rbSerif // this.m_rbSerif.AutoSize = true; this.m_rbSerif.Font = new System.Drawing.Font("Times New Roman", 8.25F); this.m_rbSerif.Location = new System.Drawing.Point(10, 19); this.m_rbSerif.Name = "m_rbSerif"; this.m_rbSerif.Size = new System.Drawing.Size(46, 18); this.m_rbSerif.TabIndex = 0; this.m_rbSerif.Text = "Serif"; this.m_rbSerif.UseVisualStyleBackColor = true; // // m_grpFields // this.m_grpFields.Controls.Add(this.m_cbIcon); this.m_grpFields.Controls.Add(this.m_cbUuid); this.m_grpFields.Controls.Add(this.m_cbTags); this.m_grpFields.Controls.Add(this.m_cbCustomStrings); this.m_grpFields.Controls.Add(this.m_cbGroups); this.m_grpFields.Controls.Add(this.m_linkDeselectAllFields); this.m_grpFields.Controls.Add(this.m_linkSelectAllFields); this.m_grpFields.Controls.Add(this.m_cbAutoType); this.m_grpFields.Controls.Add(this.m_cbLastMod); this.m_grpFields.Controls.Add(this.m_cbCreation); this.m_grpFields.Controls.Add(this.m_cbExpire); this.m_grpFields.Controls.Add(this.m_cbNotes); this.m_grpFields.Controls.Add(this.m_cbPassword); this.m_grpFields.Controls.Add(this.m_cbUrl); this.m_grpFields.Controls.Add(this.m_cbUser); this.m_grpFields.Controls.Add(this.m_cbTitle); this.m_grpFields.Location = new System.Drawing.Point(10, 136); this.m_grpFields.Name = "m_grpFields"; this.m_grpFields.Size = new System.Drawing.Size(571, 116); this.m_grpFields.TabIndex = 1; this.m_grpFields.TabStop = false; this.m_grpFields.Text = "Fields"; // // m_cbIcon // this.m_cbIcon.AutoSize = true; this.m_cbIcon.Location = new System.Drawing.Point(10, 66); this.m_cbIcon.Name = "m_cbIcon"; this.m_cbIcon.Size = new System.Drawing.Size(47, 17); this.m_cbIcon.TabIndex = 10; this.m_cbIcon.Text = "Icon"; this.m_cbIcon.UseVisualStyleBackColor = true; this.m_cbIcon.CheckedChanged += new System.EventHandler(this.OnIconCheckedChanged); // // m_cbUuid // this.m_cbUuid.AutoSize = true; this.m_cbUuid.Location = new System.Drawing.Point(360, 66); this.m_cbUuid.Name = "m_cbUuid"; this.m_cbUuid.Size = new System.Drawing.Size(53, 17); this.m_cbUuid.TabIndex = 13; this.m_cbUuid.Text = "UUID"; this.m_cbUuid.UseVisualStyleBackColor = true; // // m_cbTags // this.m_cbTags.AutoSize = true; this.m_cbTags.Location = new System.Drawing.Point(464, 43); this.m_cbTags.Name = "m_cbTags"; this.m_cbTags.Size = new System.Drawing.Size(50, 17); this.m_cbTags.TabIndex = 9; this.m_cbTags.Text = "Tags"; this.m_cbTags.UseVisualStyleBackColor = true; // // m_cbCustomStrings // this.m_cbCustomStrings.AutoSize = true; this.m_cbCustomStrings.Location = new System.Drawing.Point(107, 66); this.m_cbCustomStrings.Name = "m_cbCustomStrings"; this.m_cbCustomStrings.Size = new System.Drawing.Size(116, 17); this.m_cbCustomStrings.TabIndex = 11; this.m_cbCustomStrings.Text = "Custom string fields"; this.m_cbCustomStrings.UseVisualStyleBackColor = true; // // m_cbGroups // this.m_cbGroups.AutoSize = true; this.m_cbGroups.Location = new System.Drawing.Point(245, 66); this.m_cbGroups.Name = "m_cbGroups"; this.m_cbGroups.Size = new System.Drawing.Size(84, 17); this.m_cbGroups.TabIndex = 12; this.m_cbGroups.Text = "Group name"; this.m_cbGroups.UseVisualStyleBackColor = true; // // m_linkDeselectAllFields // this.m_linkDeselectAllFields.AutoSize = true; this.m_linkDeselectAllFields.Location = new System.Drawing.Point(63, 91); this.m_linkDeselectAllFields.Name = "m_linkDeselectAllFields"; this.m_linkDeselectAllFields.Size = new System.Drawing.Size(63, 13); this.m_linkDeselectAllFields.TabIndex = 15; this.m_linkDeselectAllFields.TabStop = true; this.m_linkDeselectAllFields.Text = "Deselect All"; this.m_linkDeselectAllFields.LinkClicked += new System.Windows.Forms.LinkLabelLinkClickedEventHandler(this.OnLinkDeselectAllFields); // // m_linkSelectAllFields // this.m_linkSelectAllFields.AutoSize = true; this.m_linkSelectAllFields.Location = new System.Drawing.Point(6, 91); this.m_linkSelectAllFields.Name = "m_linkSelectAllFields"; this.m_linkSelectAllFields.Size = new System.Drawing.Size(51, 13); this.m_linkSelectAllFields.TabIndex = 14; this.m_linkSelectAllFields.TabStop = true; this.m_linkSelectAllFields.Text = "Select All"; this.m_linkSelectAllFields.LinkClicked += new System.Windows.Forms.LinkLabelLinkClickedEventHandler(this.OnLinkSelectAllFields); // // m_cbAutoType // this.m_cbAutoType.AutoSize = true; this.m_cbAutoType.Location = new System.Drawing.Point(360, 43); this.m_cbAutoType.Name = "m_cbAutoType"; this.m_cbAutoType.Size = new System.Drawing.Size(75, 17); this.m_cbAutoType.TabIndex = 8; this.m_cbAutoType.Text = "Auto-Type"; this.m_cbAutoType.UseVisualStyleBackColor = true; // // m_cbLastMod // this.m_cbLastMod.AutoSize = true; this.m_cbLastMod.Location = new System.Drawing.Point(107, 43); this.m_cbLastMod.Name = "m_cbLastMod"; this.m_cbLastMod.Size = new System.Drawing.Size(127, 17); this.m_cbLastMod.TabIndex = 6; this.m_cbLastMod.Text = "Last modification time"; this.m_cbLastMod.UseVisualStyleBackColor = true; // // m_cbCreation // this.m_cbCreation.AutoSize = true; this.m_cbCreation.Location = new System.Drawing.Point(10, 43); this.m_cbCreation.Name = "m_cbCreation"; this.m_cbCreation.Size = new System.Drawing.Size(87, 17); this.m_cbCreation.TabIndex = 5; this.m_cbCreation.Text = "Creation time"; this.m_cbCreation.UseVisualStyleBackColor = true; // // m_cbExpire // this.m_cbExpire.AutoSize = true; this.m_cbExpire.Location = new System.Drawing.Point(245, 43); this.m_cbExpire.Name = "m_cbExpire"; this.m_cbExpire.Size = new System.Drawing.Size(76, 17); this.m_cbExpire.TabIndex = 7; this.m_cbExpire.Text = "Expiry time"; this.m_cbExpire.UseVisualStyleBackColor = true; // // m_cbNotes // this.m_cbNotes.AutoSize = true; this.m_cbNotes.Checked = true; this.m_cbNotes.CheckState = System.Windows.Forms.CheckState.Checked; this.m_cbNotes.Location = new System.Drawing.Point(464, 20); this.m_cbNotes.Name = "m_cbNotes"; this.m_cbNotes.Size = new System.Drawing.Size(54, 17); this.m_cbNotes.TabIndex = 4; this.m_cbNotes.Text = "Notes"; this.m_cbNotes.UseVisualStyleBackColor = true; // // m_cbPassword // this.m_cbPassword.AutoSize = true; this.m_cbPassword.Checked = true; this.m_cbPassword.CheckState = System.Windows.Forms.CheckState.Checked; this.m_cbPassword.Location = new System.Drawing.Point(245, 20); this.m_cbPassword.Name = "m_cbPassword"; this.m_cbPassword.Size = new System.Drawing.Size(72, 17); this.m_cbPassword.TabIndex = 2; this.m_cbPassword.Text = "Password"; this.m_cbPassword.UseVisualStyleBackColor = true; // // m_cbUrl // this.m_cbUrl.AutoSize = true; this.m_cbUrl.Location = new System.Drawing.Point(360, 20); this.m_cbUrl.Name = "m_cbUrl"; this.m_cbUrl.Size = new System.Drawing.Size(48, 17); this.m_cbUrl.TabIndex = 3; this.m_cbUrl.Text = "URL"; this.m_cbUrl.UseVisualStyleBackColor = true; // // m_cbUser // this.m_cbUser.AutoSize = true; this.m_cbUser.Checked = true; this.m_cbUser.CheckState = System.Windows.Forms.CheckState.Checked; this.m_cbUser.Location = new System.Drawing.Point(107, 20); this.m_cbUser.Name = "m_cbUser"; this.m_cbUser.Size = new System.Drawing.Size(77, 17); this.m_cbUser.TabIndex = 1; this.m_cbUser.Text = "User name"; this.m_cbUser.UseVisualStyleBackColor = true; // // m_cbTitle // this.m_cbTitle.AutoSize = true; this.m_cbTitle.Checked = true; this.m_cbTitle.CheckState = System.Windows.Forms.CheckState.Checked; this.m_cbTitle.Location = new System.Drawing.Point(10, 20); this.m_cbTitle.Name = "m_cbTitle"; this.m_cbTitle.Size = new System.Drawing.Size(46, 17); this.m_cbTitle.TabIndex = 0; this.m_cbTitle.Text = "Title"; this.m_cbTitle.UseVisualStyleBackColor = true; // // m_grpLayout // this.m_grpLayout.Controls.Add(this.m_lblDetailsInfo); this.m_grpLayout.Controls.Add(this.m_lblTabularInfo); this.m_grpLayout.Controls.Add(this.m_rbDetails); this.m_grpLayout.Controls.Add(this.m_rbTabular); this.m_grpLayout.Location = new System.Drawing.Point(10, 10); this.m_grpLayout.Name = "m_grpLayout"; this.m_grpLayout.Size = new System.Drawing.Size(571, 120); this.m_grpLayout.TabIndex = 0; this.m_grpLayout.TabStop = false; this.m_grpLayout.Text = "Layout"; // // m_lblDetailsInfo // this.m_lblDetailsInfo.AutoSize = true; this.m_lblDetailsInfo.Location = new System.Drawing.Point(27, 95); this.m_lblDetailsInfo.Name = "m_lblDetailsInfo"; this.m_lblDetailsInfo.Size = new System.Drawing.Size(337, 13); this.m_lblDetailsInfo.TabIndex = 3; this.m_lblDetailsInfo.Text = "Arrange the entries in blocks. The fields selected below will be printed."; // // m_lblTabularInfo // this.m_lblTabularInfo.Location = new System.Drawing.Point(27, 39); this.m_lblTabularInfo.Name = "m_lblTabularInfo"; this.m_lblTabularInfo.Size = new System.Drawing.Size(538, 28); this.m_lblTabularInfo.TabIndex = 1; this.m_lblTabularInfo.Text = "Arrange the entries in a tabular form. Each entry will occupy approximately one l" + "ine. The fields selected below will be printed; auto-type configuration is not p" + "rinted."; // // m_rbDetails // this.m_rbDetails.AutoSize = true; this.m_rbDetails.Location = new System.Drawing.Point(10, 75); this.m_rbDetails.Name = "m_rbDetails"; this.m_rbDetails.Size = new System.Drawing.Size(57, 17); this.m_rbDetails.TabIndex = 2; this.m_rbDetails.TabStop = true; this.m_rbDetails.Text = "&Details"; this.m_rbDetails.UseVisualStyleBackColor = true; // // m_rbTabular // this.m_rbTabular.AutoSize = true; this.m_rbTabular.Location = new System.Drawing.Point(10, 19); this.m_rbTabular.Name = "m_rbTabular"; this.m_rbTabular.Size = new System.Drawing.Size(61, 17); this.m_rbTabular.TabIndex = 0; this.m_rbTabular.TabStop = true; this.m_rbTabular.Text = "&Tabular"; this.m_rbTabular.UseVisualStyleBackColor = true; this.m_rbTabular.CheckedChanged += new System.EventHandler(this.OnTabularCheckedChanged); // // m_bannerImage // this.m_bannerImage.Dock = System.Windows.Forms.DockStyle.Top; this.m_bannerImage.Location = new System.Drawing.Point(0, 0); this.m_bannerImage.Name = "m_bannerImage"; this.m_bannerImage.Size = new System.Drawing.Size(625, 60); this.m_bannerImage.TabIndex = 1; this.m_bannerImage.TabStop = false; // // m_btnOK // this.m_btnOK.DialogResult = System.Windows.Forms.DialogResult.OK; this.m_btnOK.Location = new System.Drawing.Point(457, 537); this.m_btnOK.Name = "m_btnOK"; this.m_btnOK.Size = new System.Drawing.Size(75, 23); this.m_btnOK.TabIndex = 0; this.m_btnOK.Text = "&Print..."; this.m_btnOK.UseVisualStyleBackColor = true; this.m_btnOK.Click += new System.EventHandler(this.OnBtnOK); // // m_btnCancel // this.m_btnCancel.DialogResult = System.Windows.Forms.DialogResult.Cancel; this.m_btnCancel.Location = new System.Drawing.Point(538, 537); this.m_btnCancel.Name = "m_btnCancel"; this.m_btnCancel.Size = new System.Drawing.Size(75, 23); this.m_btnCancel.TabIndex = 1; this.m_btnCancel.Text = "Cancel"; this.m_btnCancel.UseVisualStyleBackColor = true; this.m_btnCancel.Click += new System.EventHandler(this.OnBtnCancel); // // m_btnConfigPrinter // this.m_btnConfigPrinter.Location = new System.Drawing.Point(12, 537); this.m_btnConfigPrinter.Name = "m_btnConfigPrinter"; this.m_btnConfigPrinter.Size = new System.Drawing.Size(100, 23); this.m_btnConfigPrinter.TabIndex = 3; this.m_btnConfigPrinter.Text = "Page &Setup"; this.m_btnConfigPrinter.TextImageRelation = System.Windows.Forms.TextImageRelation.ImageBeforeText; this.m_btnConfigPrinter.UseVisualStyleBackColor = true; this.m_btnConfigPrinter.Click += new System.EventHandler(this.OnBtnConfigPage); // // m_btnPrintPreview // this.m_btnPrintPreview.Location = new System.Drawing.Point(118, 537); this.m_btnPrintPreview.Name = "m_btnPrintPreview"; this.m_btnPrintPreview.Size = new System.Drawing.Size(100, 23); this.m_btnPrintPreview.TabIndex = 4; this.m_btnPrintPreview.Text = "Print Pre&view"; this.m_btnPrintPreview.TextImageRelation = System.Windows.Forms.TextImageRelation.ImageBeforeText; this.m_btnPrintPreview.UseVisualStyleBackColor = true; this.m_btnPrintPreview.Click += new System.EventHandler(this.OnBtnPrintPreview); // // PrintForm // this.AcceptButton = this.m_btnOK; this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F); this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; this.CancelButton = this.m_btnCancel; this.ClientSize = new System.Drawing.Size(625, 572); this.Controls.Add(this.m_btnCancel); this.Controls.Add(this.m_tabMain); this.Controls.Add(this.m_btnOK); this.Controls.Add(this.m_btnPrintPreview); this.Controls.Add(this.m_btnConfigPrinter); this.Controls.Add(this.m_bannerImage); this.FormBorderStyle = System.Windows.Forms.FormBorderStyle.FixedDialog; this.MaximizeBox = false; this.MinimizeBox = false; this.MinimumSize = new System.Drawing.Size(64, 32); this.Name = "PrintForm"; this.ShowInTaskbar = false; this.StartPosition = System.Windows.Forms.FormStartPosition.CenterParent; this.Text = "Print"; this.Load += new System.EventHandler(this.OnFormLoad); this.FormClosed += new System.Windows.Forms.FormClosedEventHandler(this.OnFormClosed); this.FormClosing += new System.Windows.Forms.FormClosingEventHandler(this.OnFormClosing); this.m_tabMain.ResumeLayout(false); this.m_tabPreview.ResumeLayout(false); this.m_tabDataLayout.ResumeLayout(false); this.m_grpOptions.ResumeLayout(false); this.m_grpOptions.PerformLayout(); this.m_grpSorting.ResumeLayout(false); this.m_grpSorting.PerformLayout(); this.m_grpFont.ResumeLayout(false); this.m_grpFont.PerformLayout(); this.m_grpFields.ResumeLayout(false); this.m_grpFields.PerformLayout(); this.m_grpLayout.ResumeLayout(false); this.m_grpLayout.PerformLayout(); ((System.ComponentModel.ISupportInitialize)(this.m_bannerImage)).EndInit(); this.ResumeLayout(false); } #endregion private System.Windows.Forms.TabControl m_tabMain; private System.Windows.Forms.TabPage m_tabPreview; private System.Windows.Forms.PictureBox m_bannerImage; private System.Windows.Forms.Button m_btnOK; private System.Windows.Forms.Button m_btnCancel; private System.Windows.Forms.WebBrowser m_wbMain; private System.Windows.Forms.TabPage m_tabDataLayout; private System.Windows.Forms.Button m_btnConfigPrinter; private System.Windows.Forms.Button m_btnPrintPreview; private System.Windows.Forms.GroupBox m_grpLayout; private System.Windows.Forms.RadioButton m_rbTabular; private System.Windows.Forms.RadioButton m_rbDetails; private System.Windows.Forms.Label m_lblDetailsInfo; private System.Windows.Forms.Label m_lblTabularInfo; private System.Windows.Forms.GroupBox m_grpFields; private System.Windows.Forms.CheckBox m_cbNotes; private System.Windows.Forms.CheckBox m_cbPassword; private System.Windows.Forms.CheckBox m_cbUrl; private System.Windows.Forms.CheckBox m_cbUser; private System.Windows.Forms.CheckBox m_cbTitle; private System.Windows.Forms.Label m_lblPreviewHint; private System.Windows.Forms.GroupBox m_grpFont; private System.Windows.Forms.CheckBox m_cbMonospaceForPasswords; private System.Windows.Forms.RadioButton m_rbMonospace; private System.Windows.Forms.RadioButton m_rbSansSerif; private System.Windows.Forms.RadioButton m_rbSerif; private System.Windows.Forms.CheckBox m_cbSmallMono; private System.Windows.Forms.CheckBox m_cbExpire; private System.Windows.Forms.CheckBox m_cbAutoType; private System.Windows.Forms.CheckBox m_cbLastMod; private System.Windows.Forms.CheckBox m_cbCreation; private System.Windows.Forms.LinkLabel m_linkDeselectAllFields; private System.Windows.Forms.LinkLabel m_linkSelectAllFields; private System.Windows.Forms.CheckBox m_cbGroups; private System.Windows.Forms.CheckBox m_cbCustomStrings; private System.Windows.Forms.GroupBox m_grpSorting; private System.Windows.Forms.ComboBox m_cmbSortEntries; private System.Windows.Forms.Label m_lblSortEntries; private System.Windows.Forms.Label m_lblEntrySortHint; private System.Windows.Forms.CheckBox m_cbTags; private System.Windows.Forms.CheckBox m_cbUuid; private System.Windows.Forms.GroupBox m_grpOptions; private System.Windows.Forms.CheckBox m_cbIcon; private System.Windows.Forms.ComboBox m_cmbSpr; private System.Windows.Forms.Label m_lblSpr; } }KeePass/Forms/FileBrowserForm.cs0000664000000000000000000003666013222430410015577 0ustar rootroot/* KeePass Password Safe - The Open-Source Password Manager Copyright (C) 2003-2018 Dominik Reichl This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ using System; using System.Collections.Generic; using System.ComponentModel; using System.Diagnostics; using System.Drawing; using System.Drawing.Drawing2D; using System.Drawing.Imaging; using System.IO; using System.Text; using System.Windows.Forms; using KeePass.App; using KeePass.Native; using KeePass.Resources; using KeePass.UI; using KeePass.Util; using KeePassLib; using KeePassLib.Utility; namespace KeePass.Forms { public partial class FileBrowserForm : Form { private bool m_bSaveMode = false; private string m_strTitle = PwDefs.ShortProductName; private string m_strHint = string.Empty; private string m_strContext = null; private ImageList m_ilFolders = null; private List m_vFolderImages = new List(); private ImageList m_ilFiles = null; private List m_vFileImages = new List(); private int m_nIconDim = DpiUtil.ScaleIntY(16); private const string StrDummyNode = "66913D76EA3F4F2A8B1A0899B7322EC3"; private sealed class FbfPrivTviComparer : IComparer { public int Compare(TreeNode x, TreeNode y) { Debug.Assert((x != null) && (y != null)); return StrUtil.CompareNaturally(x.Text, y.Text); } } private sealed class FbfPrivLviComparer : IComparer { public int Compare(ListViewItem x, ListViewItem y) { Debug.Assert((x != null) && (y != null)); return StrUtil.CompareNaturally(x.Text, y.Text); } } private string m_strSelectedFile = null; public string SelectedFile { get { return m_strSelectedFile; } } public void InitEx(bool bSaveMode, string strTitle, string strHint, string strContext) { m_bSaveMode = bSaveMode; if(strTitle != null) m_strTitle = strTitle; if(strHint != null) m_strHint = strHint; m_strContext = strContext; } public FileBrowserForm() { InitializeComponent(); Program.Translation.ApplyTo(this); } private void OnFormLoad(object sender, EventArgs e) { GlobalWindowManager.AddWindow(this); this.Icon = AppIcons.Default; this.Text = m_strTitle; m_nIconDim = m_tvFolders.ItemHeight; if(UIUtil.VistaStyleListsSupported) { m_tvFolders.ShowLines = false; UIUtil.SetExplorerTheme(m_tvFolders, true); UIUtil.SetExplorerTheme(m_lvFiles, true); } m_btnOK.Text = (m_bSaveMode ? KPRes.SaveCmd : KPRes.OpenCmd); Debug.Assert(!m_lblHint.AutoSize); // For RTL support m_lblHint.Text = m_strHint; if(UIUtil.ColorsEqual(m_lblHint.ForeColor, Color.Black)) m_lblHint.ForeColor = Color.FromArgb(96, 96, 96); int nWidth = m_lvFiles.ClientSize.Width - UIUtil.GetVScrollBarWidth(); m_lvFiles.Columns.Add(KPRes.Name, (nWidth * 3) / 4); m_lvFiles.Columns.Add(KPRes.Size, nWidth / 4, HorizontalAlignment.Right); InitialPopulateFolders(); string strWorkDir = Program.Config.Application.GetWorkingDirectory(m_strContext); if(string.IsNullOrEmpty(strWorkDir)) strWorkDir = WinUtil.GetHomeDirectory(); BrowseToFolder(strWorkDir); EnableControlsEx(); } private void OnFormClosed(object sender, FormClosedEventArgs e) { m_tvFolders.Nodes.Clear(); m_lvFiles.Items.Clear(); m_tvFolders.ImageList = null; m_lvFiles.SmallImageList = null; if(m_ilFolders != null) { m_ilFolders.Dispose(); m_ilFolders = null; } if(m_ilFiles != null) { m_ilFiles.Dispose(); m_ilFiles = null; } foreach(Image imgFld in m_vFolderImages) imgFld.Dispose(); m_vFolderImages.Clear(); foreach(Image imgFile in m_vFileImages) imgFile.Dispose(); m_vFileImages.Clear(); GlobalWindowManager.RemoveWindow(this); } private void EnableControlsEx() { m_btnOK.Enabled = (m_lvFiles.SelectedIndices.Count == 1); } private void InitialPopulateFolders() { List l = new List(); string str = Environment.GetFolderPath(Environment.SpecialFolder.DesktopDirectory); if(!string.IsNullOrEmpty(str)) { TreeNode tn = CreateFolderNode(str, false, null); if(tn != null) l.Add(tn); } str = Environment.GetEnvironmentVariable("USERPROFILE"); if(!string.IsNullOrEmpty(str)) { TreeNode tn = CreateFolderNode(str, false, null); if(tn != null) l.Add(tn); } DriveInfo[] vDrives = DriveInfo.GetDrives(); foreach(DriveInfo drv in vDrives) { try { DirectoryInfo diDrive = drv.RootDirectory; TreeNode tn = CreateFolderNode(diDrive.FullName, true, drv); if(tn != null) l.Add(tn); } catch(Exception) { Debug.Assert(false); } } RebuildFolderImageList(); m_tvFolders.Nodes.AddRange(l.ToArray()); } private void GetObjectProps(string strPath, DriveInfo drvHint, out Image img, ref string strDisplayName) { GetObjectPropsUnscaled(strPath, drvHint, out img, ref strDisplayName); if(img != null) { if((img.Width != m_nIconDim) || (img.Height != m_nIconDim)) { Image imgScaled = GfxUtil.ScaleImage(img, m_nIconDim, m_nIconDim, ScaleTransformFlags.UIIcon); img.Dispose(); // Dispose unscaled version img = imgScaled; } } } private void GetObjectPropsUnscaled(string strPath, DriveInfo drvHint, out Image img, ref string strDisplayName) { img = null; try { string strName; NativeMethods.SHGetFileInfo(strPath, m_nIconDim, out img, out strName); if(!string.IsNullOrEmpty(strName) && (strName.IndexOf( Path.DirectorySeparatorChar) < 0)) strDisplayName = strName; if(img != null) return; } catch(Exception) { Debug.Assert(false); } ImageList.ImageCollection icons = Program.MainForm.ClientIcons.Images; if((strPath.Length <= 3) && (drvHint != null)) { switch(drvHint.DriveType) { case DriveType.Fixed: img = new Bitmap(icons[(int)PwIcon.Drive]); break; case DriveType.CDRom: img = new Bitmap(icons[(int)PwIcon.CDRom]); break; case DriveType.Network: img = new Bitmap(icons[(int)PwIcon.NetworkServer]); break; case DriveType.Ram: img = new Bitmap(icons[(int)PwIcon.Memory]); break; case DriveType.Removable: img = new Bitmap(icons[(int)PwIcon.Disk]); break; default: img = new Bitmap(icons[(int)PwIcon.Folder]); break; } return; } img = UIUtil.GetFileIcon(strPath, m_nIconDim, m_nIconDim); if(img != null) return; if(Directory.Exists(strPath)) { img = new Bitmap(icons[(int)PwIcon.Folder]); return; } if(File.Exists(strPath)) { img = new Bitmap(icons[(int)PwIcon.PaperNew]); return; } Debug.Assert(false); img = new Bitmap(icons[(int)PwIcon.Star]); } private TreeNode CreateFolderNode(string strDir, bool bForcePlusMinus, DriveInfo drvHint) { try { DirectoryInfo di = new DirectoryInfo(strDir); Image img; string strText = di.Name; GetObjectProps(di.FullName, drvHint, out img, ref strText); m_vFolderImages.Add(img); TreeNode tn = new TreeNode(strText, m_vFolderImages.Count - 1, m_vFolderImages.Count - 1); tn.Tag = di.FullName; InitNodePlusMinus(tn, di, bForcePlusMinus); return tn; } catch(Exception) { Debug.Assert(false); } return null; } private static void InitNodePlusMinus(TreeNode tn, DirectoryInfo di, bool bForce) { bool bMark = true; if(!bForce) { try { DirectoryInfo[] vDirs = di.GetDirectories(); bool bFoundDir = false; foreach(DirectoryInfo diSub in vDirs) { if(!IsValidFileSystemObject(diSub)) continue; bFoundDir = true; break; } if(!bFoundDir) bMark = false; } catch(Exception) { bMark = false; } // Usually unauthorized } if(bMark) { tn.Nodes.Add(StrDummyNode); tn.Collapse(); } } private void RebuildFolderImageList() { ImageList imgNew = UIUtil.BuildImageListUnscaled( m_vFolderImages, m_nIconDim, m_nIconDim); m_tvFolders.ImageList = imgNew; if(m_ilFolders != null) m_ilFolders.Dispose(); m_ilFolders = imgNew; } private void BuildFilesList(DirectoryInfo di) { m_lvFiles.BeginUpdate(); m_lvFiles.Items.Clear(); DirectoryInfo[] vDirs; FileInfo[] vFiles; try { vDirs = di.GetDirectories(); vFiles = di.GetFiles(); } catch(Exception) { m_lvFiles.EndUpdate(); return; } // Unauthorized foreach(Image imgFile in m_vFileImages) imgFile.Dispose(); m_vFileImages.Clear(); List lDirItems = new List(); List lFileItems = new List(); foreach(DirectoryInfo diSub in vDirs) { AddFileItem(diSub, m_vFileImages, lDirItems, -1); } foreach(FileInfo fi in vFiles) { AddFileItem(fi, m_vFileImages, lFileItems, fi.Length); } m_lvFiles.SmallImageList = null; if(m_ilFiles != null) m_ilFiles.Dispose(); m_ilFiles = UIUtil.BuildImageListUnscaled(m_vFileImages, m_nIconDim, m_nIconDim); m_lvFiles.SmallImageList = m_ilFiles; lDirItems.Sort(new FbfPrivLviComparer()); m_lvFiles.Items.AddRange(lDirItems.ToArray()); lFileItems.Sort(new FbfPrivLviComparer()); m_lvFiles.Items.AddRange(lFileItems.ToArray()); m_lvFiles.EndUpdate(); EnableControlsEx(); } private static bool IsValidFileSystemObject(FileSystemInfo fsi) { if(fsi == null) { Debug.Assert(false); return false; } string strName = fsi.Name; if(string.IsNullOrEmpty(strName) || (strName == ".") || (strName == "..")) return false; if(strName.EndsWith(".lnk", StrUtil.CaseIgnoreCmp)) return false; if(strName.EndsWith(".url", StrUtil.CaseIgnoreCmp)) return false; FileAttributes fa = fsi.Attributes; if((long)(fa & FileAttributes.ReparsePoint) != 0) return false; if(((long)(fa & FileAttributes.System) != 0) && ((long)(fa & FileAttributes.Hidden) != 0)) return false; return true; } private void AddFileItem(FileSystemInfo fsi, List lImages, List lItems, long lFileLength) { if(!IsValidFileSystemObject(fsi)) return; Image img; string strText = fsi.Name; GetObjectProps(fsi.FullName, null, out img, ref strText); lImages.Add(img); ListViewItem lvi = new ListViewItem(strText, lImages.Count - 1); lvi.Tag = fsi.FullName; if(lFileLength < 0) lvi.SubItems.Add(string.Empty); else lvi.SubItems.Add(StrUtil.FormatDataSizeKB((ulong)lFileLength)); lItems.Add(lvi); } private bool PerformFileSelection() { ListView.SelectedListViewItemCollection lvsic = m_lvFiles.SelectedItems; if((lvsic == null) || (lvsic.Count != 1)) { Debug.Assert(false); return false; } string str = (lvsic[0].Tag as string); if(string.IsNullOrEmpty(str)) { Debug.Assert(false); return false; } try { if(Directory.Exists(str)) { TreeNode tn = m_tvFolders.SelectedNode; if(tn == null) { Debug.Assert(false); return false; } if(!tn.IsExpanded) tn.Expand(); foreach(TreeNode tnSub in tn.Nodes) { string strSub = (tnSub.Tag as string); if(string.IsNullOrEmpty(strSub)) { Debug.Assert(false); continue; } if(strSub.Equals(str, StrUtil.CaseIgnoreCmp)) { m_tvFolders.SelectedNode = tnSub; tnSub.EnsureVisible(); return false; // Success, but not a file selection! } } Debug.Assert(false); } else if(File.Exists(str)) { m_strSelectedFile = str; Program.Config.Application.SetWorkingDirectory(m_strContext, UrlUtil.GetFileDirectory(str, false, true)); return true; } else { Debug.Assert(false); } } catch(Exception) { Debug.Assert(false); } return false; } private void OnBtnOK(object sender, EventArgs e) { if(!PerformFileSelection()) this.DialogResult = DialogResult.None; } private void OnFilesItemActivate(object sender, EventArgs e) { if(PerformFileSelection()) this.DialogResult = DialogResult.OK; } private void OnFoldersBeforeExpand(object sender, TreeViewCancelEventArgs e) { TreeNode tn = e.Node; if(tn == null) { Debug.Assert(false); e.Cancel = true; return; } if((tn.Nodes.Count == 1) && (tn.Nodes[0].Text == StrDummyNode)) { tn.Nodes.Clear(); List lNodes = new List(); try { DirectoryInfo di = new DirectoryInfo(tn.Tag as string); DirectoryInfo[] vSubDirs = di.GetDirectories(); foreach(DirectoryInfo diSub in vSubDirs) { if(!IsValidFileSystemObject(diSub)) continue; TreeNode tnSub = CreateFolderNode(diSub.FullName, false, null); if(tnSub != null) lNodes.Add(tnSub); } } catch(Exception) { Debug.Assert(false); } RebuildFolderImageList(); lNodes.Sort(new FbfPrivTviComparer()); tn.Nodes.AddRange(lNodes.ToArray()); } } private void BrowseToFolder(string strPath) { try { DirectoryInfo di = new DirectoryInfo(strPath); string[] vPath = di.FullName.Split(new char[]{ Path.DirectorySeparatorChar }); if((vPath == null) || (vPath.Length == 0)) { Debug.Assert(false); return; } TreeNode tn = null; string str = string.Empty; for(int i = 0; i < vPath.Length; ++i) { if(i > 0) str = UrlUtil.EnsureTerminatingSeparator(str, false); str += vPath[i]; if(i == 0) str = UrlUtil.EnsureTerminatingSeparator(str, false); TreeNodeCollection tnc = ((tn != null) ? tn.Nodes : m_tvFolders.Nodes); tn = null; foreach(TreeNode tnSub in tnc) { string strSub = (tnSub.Tag as string); if(string.IsNullOrEmpty(strSub)) { Debug.Assert(false); continue; } if(strSub.Equals(str, StrUtil.CaseIgnoreCmp)) { tn = tnSub; break; } } if(tn == null) { Debug.Assert(false); break; } if((i != (vPath.Length - 1)) && !tn.IsExpanded) tn.Expand(); } if(tn != null) { m_tvFolders.SelectedNode = tn; tn.EnsureVisible(); } else { Debug.Assert(false); } } catch(Exception) { Debug.Assert(false); } } private void OnFoldersAfterSelect(object sender, TreeViewEventArgs e) { TreeNode tn = e.Node; string strPath = (tn.Tag as string); if(strPath == null) { Debug.Assert(false); return; } try { DirectoryInfo di = new DirectoryInfo(strPath); BuildFilesList(di); } catch(Exception) { Debug.Assert(false); } } private void OnFilesSelectedIndexChanged(object sender, EventArgs e) { EnableControlsEx(); } } } KeePass/Forms/DatabaseOperationsForm.Designer.cs0000664000000000000000000003562012775452624020705 0ustar rootrootnamespace KeePass.Forms { partial class DatabaseOperationsForm { /// /// Erforderliche Designervariable. /// private System.ComponentModel.IContainer components = null; /// /// Verwendete Ressourcen bereinigen. /// /// True, wenn verwaltete Ressourcen gelöscht werden sollen; andernfalls False. protected override void Dispose(bool disposing) { if(disposing && (components != null)) { components.Dispose(); } base.Dispose(disposing); } #region Vom Windows Form-Designer generierter Code /// /// Erforderliche Methode für die Designerunterstützung. /// Der Inhalt der Methode darf nicht mit dem Code-Editor geändert werden. /// private void InitializeComponent() { this.m_btnClose = new System.Windows.Forms.Button(); this.m_bannerImage = new System.Windows.Forms.PictureBox(); this.m_grpHistoryDelete = new System.Windows.Forms.GroupBox(); this.m_lblEntryHistoryWarning = new System.Windows.Forms.Label(); this.m_btnHistoryEntriesDelete = new System.Windows.Forms.Button(); this.m_numHistoryDays = new System.Windows.Forms.NumericUpDown(); this.m_lblHistoryEntriesDays = new System.Windows.Forms.Label(); this.m_lblDeleteHistoryEntries = new System.Windows.Forms.Label(); this.m_lblTrashIcon = new System.Windows.Forms.Label(); this.m_tabMain = new System.Windows.Forms.TabControl(); this.m_tabCleanUp = new System.Windows.Forms.TabPage(); this.m_grpDeletedObjectsInfo = new System.Windows.Forms.GroupBox(); this.m_lblDelObjInfoWarning = new System.Windows.Forms.Label(); this.m_btnRemoveDelObjInfo = new System.Windows.Forms.Button(); this.m_lblTrashIcon2 = new System.Windows.Forms.Label(); this.m_lblDelObjInfoIntro = new System.Windows.Forms.Label(); this.m_tabCustomData = new System.Windows.Forms.TabPage(); this.m_btnCDDel = new System.Windows.Forms.Button(); this.m_lvCustomData = new KeePass.UI.CustomListViewEx(); this.m_pbStatus = new System.Windows.Forms.ProgressBar(); ((System.ComponentModel.ISupportInitialize)(this.m_bannerImage)).BeginInit(); this.m_grpHistoryDelete.SuspendLayout(); ((System.ComponentModel.ISupportInitialize)(this.m_numHistoryDays)).BeginInit(); this.m_tabMain.SuspendLayout(); this.m_tabCleanUp.SuspendLayout(); this.m_grpDeletedObjectsInfo.SuspendLayout(); this.m_tabCustomData.SuspendLayout(); this.SuspendLayout(); // // m_btnClose // this.m_btnClose.DialogResult = System.Windows.Forms.DialogResult.Cancel; this.m_btnClose.Location = new System.Drawing.Point(376, 354); this.m_btnClose.Name = "m_btnClose"; this.m_btnClose.Size = new System.Drawing.Size(75, 23); this.m_btnClose.TabIndex = 0; this.m_btnClose.Text = "&Close"; this.m_btnClose.UseVisualStyleBackColor = true; this.m_btnClose.Click += new System.EventHandler(this.OnBtnClose); // // m_bannerImage // this.m_bannerImage.Dock = System.Windows.Forms.DockStyle.Top; this.m_bannerImage.Location = new System.Drawing.Point(0, 0); this.m_bannerImage.Name = "m_bannerImage"; this.m_bannerImage.Size = new System.Drawing.Size(463, 60); this.m_bannerImage.TabIndex = 1; this.m_bannerImage.TabStop = false; // // m_grpHistoryDelete // this.m_grpHistoryDelete.Controls.Add(this.m_lblEntryHistoryWarning); this.m_grpHistoryDelete.Controls.Add(this.m_btnHistoryEntriesDelete); this.m_grpHistoryDelete.Controls.Add(this.m_numHistoryDays); this.m_grpHistoryDelete.Controls.Add(this.m_lblHistoryEntriesDays); this.m_grpHistoryDelete.Controls.Add(this.m_lblDeleteHistoryEntries); this.m_grpHistoryDelete.Controls.Add(this.m_lblTrashIcon); this.m_grpHistoryDelete.Location = new System.Drawing.Point(6, 6); this.m_grpHistoryDelete.Name = "m_grpHistoryDelete"; this.m_grpHistoryDelete.Size = new System.Drawing.Size(417, 118); this.m_grpHistoryDelete.TabIndex = 0; this.m_grpHistoryDelete.TabStop = false; this.m_grpHistoryDelete.Text = "Entry history"; // // m_lblEntryHistoryWarning // this.m_lblEntryHistoryWarning.Location = new System.Drawing.Point(44, 81); this.m_lblEntryHistoryWarning.Name = "m_lblEntryHistoryWarning"; this.m_lblEntryHistoryWarning.Size = new System.Drawing.Size(367, 29); this.m_lblEntryHistoryWarning.TabIndex = 5; this.m_lblEntryHistoryWarning.Text = "Clicking the \'Delete\' button will remove all history entries older than the speci" + "fied number of days. There\'s no way to get them back."; // // m_btnHistoryEntriesDelete // this.m_btnHistoryEntriesDelete.Location = new System.Drawing.Point(335, 52); this.m_btnHistoryEntriesDelete.Name = "m_btnHistoryEntriesDelete"; this.m_btnHistoryEntriesDelete.Size = new System.Drawing.Size(75, 23); this.m_btnHistoryEntriesDelete.TabIndex = 4; this.m_btnHistoryEntriesDelete.Text = "&Delete"; this.m_btnHistoryEntriesDelete.UseVisualStyleBackColor = true; this.m_btnHistoryEntriesDelete.Click += new System.EventHandler(this.OnBtnDelete); // // m_numHistoryDays // this.m_numHistoryDays.Location = new System.Drawing.Point(239, 54); this.m_numHistoryDays.Maximum = new decimal(new int[] { 3650, 0, 0, 0}); this.m_numHistoryDays.Name = "m_numHistoryDays"; this.m_numHistoryDays.Size = new System.Drawing.Size(59, 20); this.m_numHistoryDays.TabIndex = 3; this.m_numHistoryDays.TextAlign = System.Windows.Forms.HorizontalAlignment.Right; this.m_numHistoryDays.Value = new decimal(new int[] { 365, 0, 0, 0}); // // m_lblHistoryEntriesDays // this.m_lblHistoryEntriesDays.AutoSize = true; this.m_lblHistoryEntriesDays.Location = new System.Drawing.Point(44, 56); this.m_lblHistoryEntriesDays.Name = "m_lblHistoryEntriesDays"; this.m_lblHistoryEntriesDays.Size = new System.Drawing.Size(189, 13); this.m_lblHistoryEntriesDays.TabIndex = 2; this.m_lblHistoryEntriesDays.Text = "Delete history entries older than (days):"; // // m_lblDeleteHistoryEntries // this.m_lblDeleteHistoryEntries.Location = new System.Drawing.Point(44, 17); this.m_lblDeleteHistoryEntries.Name = "m_lblDeleteHistoryEntries"; this.m_lblDeleteHistoryEntries.Size = new System.Drawing.Size(367, 32); this.m_lblDeleteHistoryEntries.TabIndex = 1; this.m_lblDeleteHistoryEntries.Text = "Old history entries (items shown on the \'History\' tab page in the entries dialog)" + " can be deleted. This will decrease the database size a bit."; // // m_lblTrashIcon // this.m_lblTrashIcon.Image = global::KeePass.Properties.Resources.B32x32_Trashcan_Full; this.m_lblTrashIcon.Location = new System.Drawing.Point(6, 16); this.m_lblTrashIcon.Name = "m_lblTrashIcon"; this.m_lblTrashIcon.Size = new System.Drawing.Size(32, 32); this.m_lblTrashIcon.TabIndex = 0; // // m_tabMain // this.m_tabMain.Controls.Add(this.m_tabCleanUp); this.m_tabMain.Controls.Add(this.m_tabCustomData); this.m_tabMain.Location = new System.Drawing.Point(12, 66); this.m_tabMain.Name = "m_tabMain"; this.m_tabMain.SelectedIndex = 0; this.m_tabMain.Size = new System.Drawing.Size(439, 276); this.m_tabMain.TabIndex = 1; // // m_tabCleanUp // this.m_tabCleanUp.Controls.Add(this.m_grpDeletedObjectsInfo); this.m_tabCleanUp.Controls.Add(this.m_grpHistoryDelete); this.m_tabCleanUp.Location = new System.Drawing.Point(4, 22); this.m_tabCleanUp.Name = "m_tabCleanUp"; this.m_tabCleanUp.Padding = new System.Windows.Forms.Padding(3); this.m_tabCleanUp.Size = new System.Drawing.Size(431, 250); this.m_tabCleanUp.TabIndex = 0; this.m_tabCleanUp.Text = "Clean Up"; this.m_tabCleanUp.UseVisualStyleBackColor = true; // // m_grpDeletedObjectsInfo // this.m_grpDeletedObjectsInfo.Controls.Add(this.m_lblDelObjInfoWarning); this.m_grpDeletedObjectsInfo.Controls.Add(this.m_btnRemoveDelObjInfo); this.m_grpDeletedObjectsInfo.Controls.Add(this.m_lblTrashIcon2); this.m_grpDeletedObjectsInfo.Controls.Add(this.m_lblDelObjInfoIntro); this.m_grpDeletedObjectsInfo.Location = new System.Drawing.Point(6, 130); this.m_grpDeletedObjectsInfo.Name = "m_grpDeletedObjectsInfo"; this.m_grpDeletedObjectsInfo.Size = new System.Drawing.Size(417, 114); this.m_grpDeletedObjectsInfo.TabIndex = 1; this.m_grpDeletedObjectsInfo.TabStop = false; this.m_grpDeletedObjectsInfo.Text = "Deleted objects information"; // // m_lblDelObjInfoWarning // this.m_lblDelObjInfoWarning.Location = new System.Drawing.Point(44, 67); this.m_lblDelObjInfoWarning.Name = "m_lblDelObjInfoWarning"; this.m_lblDelObjInfoWarning.Size = new System.Drawing.Size(367, 41); this.m_lblDelObjInfoWarning.TabIndex = 3; this.m_lblDelObjInfoWarning.Text = "Warning! After removing this information, deleted objects (groups, entries, ...) " + "may reappear when synchronizing the current database with another one (which sti" + "ll contains the objects)."; // // m_btnRemoveDelObjInfo // this.m_btnRemoveDelObjInfo.Location = new System.Drawing.Point(335, 16); this.m_btnRemoveDelObjInfo.Name = "m_btnRemoveDelObjInfo"; this.m_btnRemoveDelObjInfo.Size = new System.Drawing.Size(75, 23); this.m_btnRemoveDelObjInfo.TabIndex = 2; this.m_btnRemoveDelObjInfo.Text = "D&elete"; this.m_btnRemoveDelObjInfo.UseVisualStyleBackColor = true; this.m_btnRemoveDelObjInfo.Click += new System.EventHandler(this.OnBtnRemoveDelObjInfo); // // m_lblTrashIcon2 // this.m_lblTrashIcon2.Image = global::KeePass.Properties.Resources.B32x32_Trashcan_Full; this.m_lblTrashIcon2.Location = new System.Drawing.Point(6, 16); this.m_lblTrashIcon2.Name = "m_lblTrashIcon2"; this.m_lblTrashIcon2.Size = new System.Drawing.Size(32, 32); this.m_lblTrashIcon2.TabIndex = 0; // // m_lblDelObjInfoIntro // this.m_lblDelObjInfoIntro.Location = new System.Drawing.Point(44, 17); this.m_lblDelObjInfoIntro.Name = "m_lblDelObjInfoIntro"; this.m_lblDelObjInfoIntro.Size = new System.Drawing.Size(285, 41); this.m_lblDelObjInfoIntro.TabIndex = 1; this.m_lblDelObjInfoIntro.Text = "KeePass keeps some information about deleted objects. This information can be rem" + "oved in order to reduce the size of the database."; // // m_tabCustomData // this.m_tabCustomData.Controls.Add(this.m_btnCDDel); this.m_tabCustomData.Controls.Add(this.m_lvCustomData); this.m_tabCustomData.Location = new System.Drawing.Point(4, 22); this.m_tabCustomData.Name = "m_tabCustomData"; this.m_tabCustomData.Size = new System.Drawing.Size(431, 250); this.m_tabCustomData.TabIndex = 1; this.m_tabCustomData.Text = "Plugin Data"; this.m_tabCustomData.UseVisualStyleBackColor = true; // // m_btnCDDel // this.m_btnCDDel.Location = new System.Drawing.Point(349, 220); this.m_btnCDDel.Name = "m_btnCDDel"; this.m_btnCDDel.Size = new System.Drawing.Size(75, 23); this.m_btnCDDel.TabIndex = 1; this.m_btnCDDel.Text = "&Delete"; this.m_btnCDDel.UseVisualStyleBackColor = true; this.m_btnCDDel.Click += new System.EventHandler(this.OnBtnCDDel); // // m_lvCustomData // this.m_lvCustomData.FullRowSelect = true; this.m_lvCustomData.HeaderStyle = System.Windows.Forms.ColumnHeaderStyle.Nonclickable; this.m_lvCustomData.HideSelection = false; this.m_lvCustomData.Location = new System.Drawing.Point(6, 12); this.m_lvCustomData.Name = "m_lvCustomData"; this.m_lvCustomData.ShowItemToolTips = true; this.m_lvCustomData.Size = new System.Drawing.Size(417, 202); this.m_lvCustomData.TabIndex = 0; this.m_lvCustomData.UseCompatibleStateImageBehavior = false; this.m_lvCustomData.View = System.Windows.Forms.View.Details; this.m_lvCustomData.SelectedIndexChanged += new System.EventHandler(this.OnCustomDataSelectedIndexChanged); // // m_pbStatus // this.m_pbStatus.Location = new System.Drawing.Point(12, 359); this.m_pbStatus.Name = "m_pbStatus"; this.m_pbStatus.Size = new System.Drawing.Size(341, 13); this.m_pbStatus.Style = System.Windows.Forms.ProgressBarStyle.Continuous; this.m_pbStatus.TabIndex = 2; // // DatabaseOperationsForm // this.AcceptButton = this.m_btnClose; this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F); this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; this.CancelButton = this.m_btnClose; this.ClientSize = new System.Drawing.Size(463, 389); this.Controls.Add(this.m_pbStatus); this.Controls.Add(this.m_tabMain); this.Controls.Add(this.m_bannerImage); this.Controls.Add(this.m_btnClose); this.FormBorderStyle = System.Windows.Forms.FormBorderStyle.FixedDialog; this.MaximizeBox = false; this.MinimizeBox = false; this.Name = "DatabaseOperationsForm"; this.ShowInTaskbar = false; this.StartPosition = System.Windows.Forms.FormStartPosition.CenterParent; this.Text = ""; this.Load += new System.EventHandler(this.OnFormLoad); this.FormClosed += new System.Windows.Forms.FormClosedEventHandler(this.OnFormClosed); ((System.ComponentModel.ISupportInitialize)(this.m_bannerImage)).EndInit(); this.m_grpHistoryDelete.ResumeLayout(false); this.m_grpHistoryDelete.PerformLayout(); ((System.ComponentModel.ISupportInitialize)(this.m_numHistoryDays)).EndInit(); this.m_tabMain.ResumeLayout(false); this.m_tabCleanUp.ResumeLayout(false); this.m_grpDeletedObjectsInfo.ResumeLayout(false); this.m_tabCustomData.ResumeLayout(false); this.ResumeLayout(false); } #endregion private System.Windows.Forms.Button m_btnClose; private System.Windows.Forms.PictureBox m_bannerImage; private System.Windows.Forms.GroupBox m_grpHistoryDelete; private System.Windows.Forms.Label m_lblTrashIcon; private System.Windows.Forms.NumericUpDown m_numHistoryDays; private System.Windows.Forms.Label m_lblHistoryEntriesDays; private System.Windows.Forms.Label m_lblDeleteHistoryEntries; private System.Windows.Forms.Button m_btnHistoryEntriesDelete; private System.Windows.Forms.TabControl m_tabMain; private System.Windows.Forms.TabPage m_tabCleanUp; private System.Windows.Forms.Label m_lblEntryHistoryWarning; private System.Windows.Forms.ProgressBar m_pbStatus; private System.Windows.Forms.GroupBox m_grpDeletedObjectsInfo; private System.Windows.Forms.Label m_lblTrashIcon2; private System.Windows.Forms.Label m_lblDelObjInfoIntro; private System.Windows.Forms.Label m_lblDelObjInfoWarning; private System.Windows.Forms.Button m_btnRemoveDelObjInfo; private System.Windows.Forms.TabPage m_tabCustomData; private KeePass.UI.CustomListViewEx m_lvCustomData; private System.Windows.Forms.Button m_btnCDDel; } }KeePass/Forms/PluginsForm.cs0000664000000000000000000001357313222430410014773 0ustar rootroot/* KeePass Password Safe - The Open-Source Password Manager Copyright (C) 2003-2018 Dominik Reichl This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ using System; using System.Collections.Generic; using System.ComponentModel; using System.Diagnostics; using System.Drawing; using System.IO; using System.Text; using System.Windows.Forms; using KeePass.App; using KeePass.Plugins; using KeePass.Resources; using KeePass.UI; using KeePass.Util; using KeePassLib; using KeePassLib.Utility; namespace KeePass.Forms { public partial class PluginsForm : Form, IGwmWindow { private PluginManager m_mgr = null; private bool m_bBlockListUpdate = false; private ImageList m_ilIcons = new ImageList(); public bool CanCloseWithoutDataLoss { get { return true; } } internal void InitEx(PluginManager mgr) { Debug.Assert(mgr != null); m_mgr = mgr; } public PluginsForm() { InitializeComponent(); Program.Translation.ApplyTo(this); } private void OnFormLoad(object sender, EventArgs e) { Debug.Assert(m_mgr != null); if(m_mgr == null) throw new ArgumentException(); GlobalWindowManager.AddWindow(this, this); BannerFactory.CreateBannerEx(this, m_bannerImage, Properties.Resources.B48x48_BlockDevice, KPRes.Plugins, KPRes.PluginsDesc); this.Icon = AppIcons.Default; Debug.Assert(!m_lblCacheSize.AutoSize); // For RTL support m_lblCacheSize.Text += " " + StrUtil.FormatDataSize( PlgxCache.GetUsedCacheSize()) + "."; m_cbCacheDeleteOld.Checked = Program.Config.Application.Start.PluginCacheDeleteOld; if(string.IsNullOrEmpty(PluginManager.UserDirectory)) { Debug.Assert(false); m_btnOpenFolder.Enabled = false; } m_lvPlugins.Columns.Add(KPRes.Plugin); m_lvPlugins.Columns.Add(KPRes.Version); m_lvPlugins.Columns.Add(KPRes.Author); m_lvPlugins.Columns.Add(KPRes.Description); m_lvPlugins.Columns.Add(KPRes.File); UIUtil.ResizeColumns(m_lvPlugins, new int[] { 4, 2, 3, 0, 2 }, true); m_ilIcons.ImageSize = new Size(DpiUtil.ScaleIntX(16), DpiUtil.ScaleIntY(16)); m_ilIcons.ColorDepth = ColorDepth.Depth32Bit; m_lvPlugins.SmallImageList = m_ilIcons; UpdatePluginsList(); if(m_lvPlugins.Items.Count > 0) { m_lvPlugins.Items[0].Selected = true; UIUtil.SetFocus(m_lvPlugins, this); } UpdatePluginDescription(); } private void CleanUpEx() { if(m_ilIcons != null) { m_lvPlugins.SmallImageList = null; // Detach event handlers m_ilIcons.Dispose(); m_ilIcons = null; } } private void UpdatePluginsList() { if(m_bBlockListUpdate) return; m_bBlockListUpdate = true; m_lvPlugins.Items.Clear(); m_ilIcons.Images.Clear(); m_ilIcons.Images.Add(Properties.Resources.B16x16_BlockDevice); foreach(PluginInfo plugin in m_mgr) { ListViewItem lvi = new ListViewItem(plugin.Name); ListViewItem lviNew = m_lvPlugins.Items.Add(lvi); lviNew.SubItems.Add(plugin.FileVersion); lviNew.SubItems.Add(plugin.Author); lviNew.SubItems.Add(plugin.Description); lviNew.SubItems.Add(plugin.DisplayFilePath); int nImageIndex = 0; Debug.Assert(plugin.Interface != null); if((plugin.Interface != null) && (plugin.Interface.SmallIcon != null)) { nImageIndex = m_ilIcons.Images.Count; m_ilIcons.Images.Add(plugin.Interface.SmallIcon); } lviNew.ImageIndex = nImageIndex; } m_bBlockListUpdate = false; UpdatePluginDescription(); } private void UpdatePluginDescription() { Debug.Assert(!m_lblSelectedPluginDesc.AutoSize); // For RTL support ListView.SelectedListViewItemCollection lvsic = m_lvPlugins.SelectedItems; if(lvsic.Count == 0) { m_grpPluginDesc.Text = string.Empty; m_lblSelectedPluginDesc.Text = string.Empty; return; } ListViewItem lvi = lvsic[0]; m_grpPluginDesc.Text = lvi.SubItems[0].Text; m_lblSelectedPluginDesc.Text = lvi.SubItems[3].Text; } private void OnBtnClose(object sender, EventArgs e) { } private void OnPluginListSelectedIndexChanged(object sender, EventArgs e) { UpdatePluginDescription(); } private void OnFormClosed(object sender, FormClosedEventArgs e) { CleanUpEx(); GlobalWindowManager.RemoveWindow(this); } private void OnBtnClearCache(object sender, EventArgs e) { Program.Config.Application.Start.PluginCacheClearOnce = true; MessageService.ShowInfo(KPRes.PluginCacheClearInfo); } private void OnFormClosing(object sender, FormClosingEventArgs e) { Program.Config.Application.Start.PluginCacheDeleteOld = m_cbCacheDeleteOld.Checked; } private void OnBtnGetMore(object sender, EventArgs e) { WinUtil.OpenUrl(PwDefs.PluginsUrl, null); } private void OnBtnOpenFolder(object sender, EventArgs e) { try { string str = PluginManager.UserDirectory; if(string.IsNullOrEmpty(str)) { Debug.Assert(false); return; } if(!Directory.Exists(str)) Directory.CreateDirectory(str); WinUtil.OpenUrl("cmd://\"" + str + "\"", null, false); } catch(Exception ex) { MessageService.ShowWarning(ex.Message); } } } } KeePass/Forms/CsvImportForm.Designer.cs0000664000000000000000000006243312650414546017056 0ustar rootrootnamespace KeePass.Forms { partial class CsvImportForm { /// /// Required designer variable. /// private System.ComponentModel.IContainer components = null; /// /// Clean up any resources being used. /// /// true if managed resources should be disposed; otherwise, false. protected override void Dispose(bool disposing) { if(disposing && (components != null)) { components.Dispose(); } base.Dispose(disposing); } #region Windows Form Designer generated code /// /// Required method for Designer support - do not modify /// the contents of this method with the code editor. /// private void InitializeComponent() { this.m_tabMain = new System.Windows.Forms.TabControl(); this.m_tabEnc = new System.Windows.Forms.TabPage(); this.m_rtbEncPreview = new KeePass.UI.CustomRichTextBoxEx(); this.m_lblEncPreview = new System.Windows.Forms.Label(); this.m_cmbEnc = new System.Windows.Forms.ComboBox(); this.m_lblEnc = new System.Windows.Forms.Label(); this.m_tabStructure = new System.Windows.Forms.TabPage(); this.m_grpSem = new System.Windows.Forms.GroupBox(); this.m_grpFieldAdd = new System.Windows.Forms.GroupBox(); this.m_btnFieldAdd = new System.Windows.Forms.Button(); this.m_linkFieldFormat = new System.Windows.Forms.LinkLabel(); this.m_cmbFieldFormat = new System.Windows.Forms.ComboBox(); this.m_lblFieldFormat = new System.Windows.Forms.Label(); this.m_tbFieldName = new System.Windows.Forms.TextBox(); this.m_lblFieldName = new System.Windows.Forms.Label(); this.m_cmbFieldType = new System.Windows.Forms.ComboBox(); this.m_lblFieldType = new System.Windows.Forms.Label(); this.m_btnFieldMoveDown = new System.Windows.Forms.Button(); this.m_btnFieldMoveUp = new System.Windows.Forms.Button(); this.m_btnFieldDel = new System.Windows.Forms.Button(); this.m_lblFields = new System.Windows.Forms.Label(); this.m_lvFields = new KeePass.UI.CustomListViewEx(); this.m_grpSyntax = new System.Windows.Forms.GroupBox(); this.m_cbIgnoreFirst = new System.Windows.Forms.CheckBox(); this.m_cbTrim = new System.Windows.Forms.CheckBox(); this.m_cmbTextQual = new System.Windows.Forms.ComboBox(); this.m_lblTextQual = new System.Windows.Forms.Label(); this.m_cbBackEscape = new System.Windows.Forms.CheckBox(); this.m_lblFieldSep = new System.Windows.Forms.Label(); this.m_cmbFieldSep = new System.Windows.Forms.ComboBox(); this.m_cmbRecSep = new System.Windows.Forms.ComboBox(); this.m_lblRecSep = new System.Windows.Forms.Label(); this.m_tabPreview = new System.Windows.Forms.TabPage(); this.m_cbMergeGroups = new System.Windows.Forms.CheckBox(); this.m_lvImportPreview = new KeePass.UI.CustomListViewEx(); this.m_btnOK = new System.Windows.Forms.Button(); this.m_btnCancel = new System.Windows.Forms.Button(); this.m_btnTabBack = new System.Windows.Forms.Button(); this.m_btnTabNext = new System.Windows.Forms.Button(); this.m_btnHelp = new System.Windows.Forms.Button(); this.m_tabMain.SuspendLayout(); this.m_tabEnc.SuspendLayout(); this.m_tabStructure.SuspendLayout(); this.m_grpSem.SuspendLayout(); this.m_grpFieldAdd.SuspendLayout(); this.m_grpSyntax.SuspendLayout(); this.m_tabPreview.SuspendLayout(); this.SuspendLayout(); // // m_tabMain // this.m_tabMain.Controls.Add(this.m_tabEnc); this.m_tabMain.Controls.Add(this.m_tabStructure); this.m_tabMain.Controls.Add(this.m_tabPreview); this.m_tabMain.Location = new System.Drawing.Point(12, 12); this.m_tabMain.Name = "m_tabMain"; this.m_tabMain.SelectedIndex = 0; this.m_tabMain.Size = new System.Drawing.Size(684, 462); this.m_tabMain.TabIndex = 2; this.m_tabMain.SelectedIndexChanged += new System.EventHandler(this.OnTabMainSelectedIndexChanged); // // m_tabEnc // this.m_tabEnc.Controls.Add(this.m_rtbEncPreview); this.m_tabEnc.Controls.Add(this.m_lblEncPreview); this.m_tabEnc.Controls.Add(this.m_cmbEnc); this.m_tabEnc.Controls.Add(this.m_lblEnc); this.m_tabEnc.Location = new System.Drawing.Point(4, 22); this.m_tabEnc.Name = "m_tabEnc"; this.m_tabEnc.Padding = new System.Windows.Forms.Padding(3); this.m_tabEnc.Size = new System.Drawing.Size(676, 436); this.m_tabEnc.TabIndex = 0; this.m_tabEnc.Text = "Encoding"; this.m_tabEnc.UseVisualStyleBackColor = true; // // m_rtbEncPreview // this.m_rtbEncPreview.AcceptsTab = true; this.m_rtbEncPreview.DetectUrls = false; this.m_rtbEncPreview.Location = new System.Drawing.Point(9, 60); this.m_rtbEncPreview.Name = "m_rtbEncPreview"; this.m_rtbEncPreview.ReadOnly = true; this.m_rtbEncPreview.ScrollBars = System.Windows.Forms.RichTextBoxScrollBars.ForcedVertical; this.m_rtbEncPreview.Size = new System.Drawing.Size(657, 366); this.m_rtbEncPreview.TabIndex = 3; this.m_rtbEncPreview.Text = ""; // // m_lblEncPreview // this.m_lblEncPreview.AutoSize = true; this.m_lblEncPreview.Location = new System.Drawing.Point(6, 44); this.m_lblEncPreview.Name = "m_lblEncPreview"; this.m_lblEncPreview.Size = new System.Drawing.Size(71, 13); this.m_lblEncPreview.TabIndex = 2; this.m_lblEncPreview.Text = "Text preview:"; // // m_cmbEnc // this.m_cmbEnc.DropDownStyle = System.Windows.Forms.ComboBoxStyle.DropDownList; this.m_cmbEnc.FormattingEnabled = true; this.m_cmbEnc.Location = new System.Drawing.Point(91, 13); this.m_cmbEnc.Name = "m_cmbEnc"; this.m_cmbEnc.Size = new System.Drawing.Size(298, 21); this.m_cmbEnc.TabIndex = 1; this.m_cmbEnc.SelectedIndexChanged += new System.EventHandler(this.OnEncSelectedIndexChanged); // // m_lblEnc // this.m_lblEnc.AutoSize = true; this.m_lblEnc.Location = new System.Drawing.Point(6, 16); this.m_lblEnc.Name = "m_lblEnc"; this.m_lblEnc.Size = new System.Drawing.Size(78, 13); this.m_lblEnc.TabIndex = 0; this.m_lblEnc.Text = "Text encoding:"; // // m_tabStructure // this.m_tabStructure.Controls.Add(this.m_grpSem); this.m_tabStructure.Controls.Add(this.m_grpSyntax); this.m_tabStructure.Location = new System.Drawing.Point(4, 22); this.m_tabStructure.Name = "m_tabStructure"; this.m_tabStructure.Padding = new System.Windows.Forms.Padding(3); this.m_tabStructure.Size = new System.Drawing.Size(676, 436); this.m_tabStructure.TabIndex = 1; this.m_tabStructure.Text = "Structure"; this.m_tabStructure.UseVisualStyleBackColor = true; // // m_grpSem // this.m_grpSem.Controls.Add(this.m_grpFieldAdd); this.m_grpSem.Controls.Add(this.m_btnFieldMoveDown); this.m_grpSem.Controls.Add(this.m_btnFieldMoveUp); this.m_grpSem.Controls.Add(this.m_btnFieldDel); this.m_grpSem.Controls.Add(this.m_lblFields); this.m_grpSem.Controls.Add(this.m_lvFields); this.m_grpSem.Location = new System.Drawing.Point(6, 140); this.m_grpSem.Name = "m_grpSem"; this.m_grpSem.Size = new System.Drawing.Size(662, 290); this.m_grpSem.TabIndex = 1; this.m_grpSem.TabStop = false; this.m_grpSem.Text = "Semantics"; // // m_grpFieldAdd // this.m_grpFieldAdd.Controls.Add(this.m_btnFieldAdd); this.m_grpFieldAdd.Controls.Add(this.m_linkFieldFormat); this.m_grpFieldAdd.Controls.Add(this.m_cmbFieldFormat); this.m_grpFieldAdd.Controls.Add(this.m_lblFieldFormat); this.m_grpFieldAdd.Controls.Add(this.m_tbFieldName); this.m_grpFieldAdd.Controls.Add(this.m_lblFieldName); this.m_grpFieldAdd.Controls.Add(this.m_cmbFieldType); this.m_grpFieldAdd.Controls.Add(this.m_lblFieldType); this.m_grpFieldAdd.Location = new System.Drawing.Point(380, 143); this.m_grpFieldAdd.Name = "m_grpFieldAdd"; this.m_grpFieldAdd.Size = new System.Drawing.Size(272, 137); this.m_grpFieldAdd.TabIndex = 5; this.m_grpFieldAdd.TabStop = false; this.m_grpFieldAdd.Text = "Add field"; // // m_btnFieldAdd // this.m_btnFieldAdd.Location = new System.Drawing.Point(188, 103); this.m_btnFieldAdd.Name = "m_btnFieldAdd"; this.m_btnFieldAdd.Size = new System.Drawing.Size(75, 23); this.m_btnFieldAdd.TabIndex = 7; this.m_btnFieldAdd.Text = "&Add"; this.m_btnFieldAdd.UseVisualStyleBackColor = true; this.m_btnFieldAdd.Click += new System.EventHandler(this.OnBtnFieldAdd); // // m_linkFieldFormat // this.m_linkFieldFormat.AutoSize = true; this.m_linkFieldFormat.Location = new System.Drawing.Point(234, 75); this.m_linkFieldFormat.Name = "m_linkFieldFormat"; this.m_linkFieldFormat.Size = new System.Drawing.Size(29, 13); this.m_linkFieldFormat.TabIndex = 6; this.m_linkFieldFormat.TabStop = true; this.m_linkFieldFormat.Text = "Help"; this.m_linkFieldFormat.LinkClicked += new System.Windows.Forms.LinkLabelLinkClickedEventHandler(this.OnFieldFormatLinkClicked); // // m_cmbFieldFormat // this.m_cmbFieldFormat.FormattingEnabled = true; this.m_cmbFieldFormat.Location = new System.Drawing.Point(74, 72); this.m_cmbFieldFormat.Name = "m_cmbFieldFormat"; this.m_cmbFieldFormat.Size = new System.Drawing.Size(154, 21); this.m_cmbFieldFormat.TabIndex = 5; // // m_lblFieldFormat // this.m_lblFieldFormat.AutoSize = true; this.m_lblFieldFormat.Location = new System.Drawing.Point(6, 75); this.m_lblFieldFormat.Name = "m_lblFieldFormat"; this.m_lblFieldFormat.Size = new System.Drawing.Size(19, 13); this.m_lblFieldFormat.TabIndex = 4; this.m_lblFieldFormat.Text = "<>"; // // m_tbFieldName // this.m_tbFieldName.Location = new System.Drawing.Point(74, 46); this.m_tbFieldName.Name = "m_tbFieldName"; this.m_tbFieldName.Size = new System.Drawing.Size(189, 20); this.m_tbFieldName.TabIndex = 3; // // m_lblFieldName // this.m_lblFieldName.AutoSize = true; this.m_lblFieldName.Location = new System.Drawing.Point(6, 49); this.m_lblFieldName.Name = "m_lblFieldName"; this.m_lblFieldName.Size = new System.Drawing.Size(38, 13); this.m_lblFieldName.TabIndex = 2; this.m_lblFieldName.Text = "Name:"; // // m_cmbFieldType // this.m_cmbFieldType.DropDownStyle = System.Windows.Forms.ComboBoxStyle.DropDownList; this.m_cmbFieldType.FormattingEnabled = true; this.m_cmbFieldType.Location = new System.Drawing.Point(74, 19); this.m_cmbFieldType.Name = "m_cmbFieldType"; this.m_cmbFieldType.Size = new System.Drawing.Size(189, 21); this.m_cmbFieldType.TabIndex = 1; this.m_cmbFieldType.SelectedIndexChanged += new System.EventHandler(this.OnFieldTypeSelectedIndexChanged); // // m_lblFieldType // this.m_lblFieldType.AutoSize = true; this.m_lblFieldType.Location = new System.Drawing.Point(6, 22); this.m_lblFieldType.Name = "m_lblFieldType"; this.m_lblFieldType.Size = new System.Drawing.Size(34, 13); this.m_lblFieldType.TabIndex = 0; this.m_lblFieldType.Text = "Type:"; // // m_btnFieldMoveDown // this.m_btnFieldMoveDown.Image = global::KeePass.Properties.Resources.B16x16_1DownArrow; this.m_btnFieldMoveDown.Location = new System.Drawing.Point(380, 96); this.m_btnFieldMoveDown.Name = "m_btnFieldMoveDown"; this.m_btnFieldMoveDown.Size = new System.Drawing.Size(75, 23); this.m_btnFieldMoveDown.TabIndex = 4; this.m_btnFieldMoveDown.UseVisualStyleBackColor = true; this.m_btnFieldMoveDown.Click += new System.EventHandler(this.OnBtnFieldMoveDown); // // m_btnFieldMoveUp // this.m_btnFieldMoveUp.Image = global::KeePass.Properties.Resources.B16x16_1UpArrow; this.m_btnFieldMoveUp.Location = new System.Drawing.Point(380, 67); this.m_btnFieldMoveUp.Name = "m_btnFieldMoveUp"; this.m_btnFieldMoveUp.Size = new System.Drawing.Size(75, 23); this.m_btnFieldMoveUp.TabIndex = 3; this.m_btnFieldMoveUp.UseVisualStyleBackColor = true; this.m_btnFieldMoveUp.Click += new System.EventHandler(this.OnBtnFieldMoveUp); // // m_btnFieldDel // this.m_btnFieldDel.Location = new System.Drawing.Point(380, 38); this.m_btnFieldDel.Name = "m_btnFieldDel"; this.m_btnFieldDel.Size = new System.Drawing.Size(75, 23); this.m_btnFieldDel.TabIndex = 2; this.m_btnFieldDel.Text = "&Delete"; this.m_btnFieldDel.UseVisualStyleBackColor = true; this.m_btnFieldDel.Click += new System.EventHandler(this.OnBtnFieldDel); // // m_lblFields // this.m_lblFields.AutoSize = true; this.m_lblFields.Location = new System.Drawing.Point(6, 22); this.m_lblFields.Name = "m_lblFields"; this.m_lblFields.Size = new System.Drawing.Size(268, 13); this.m_lblFields.TabIndex = 0; this.m_lblFields.Text = "Specify the layout (fields and their order) of the CSV file:"; // // m_lvFields // this.m_lvFields.FullRowSelect = true; this.m_lvFields.HeaderStyle = System.Windows.Forms.ColumnHeaderStyle.Nonclickable; this.m_lvFields.HideSelection = false; this.m_lvFields.Location = new System.Drawing.Point(9, 38); this.m_lvFields.Name = "m_lvFields"; this.m_lvFields.ShowItemToolTips = true; this.m_lvFields.Size = new System.Drawing.Size(365, 242); this.m_lvFields.TabIndex = 1; this.m_lvFields.UseCompatibleStateImageBehavior = false; this.m_lvFields.View = System.Windows.Forms.View.Details; this.m_lvFields.SelectedIndexChanged += new System.EventHandler(this.OnFieldsSelectedIndexChanged); // // m_grpSyntax // this.m_grpSyntax.Controls.Add(this.m_cbIgnoreFirst); this.m_grpSyntax.Controls.Add(this.m_cbTrim); this.m_grpSyntax.Controls.Add(this.m_cmbTextQual); this.m_grpSyntax.Controls.Add(this.m_lblTextQual); this.m_grpSyntax.Controls.Add(this.m_cbBackEscape); this.m_grpSyntax.Controls.Add(this.m_lblFieldSep); this.m_grpSyntax.Controls.Add(this.m_cmbFieldSep); this.m_grpSyntax.Controls.Add(this.m_cmbRecSep); this.m_grpSyntax.Controls.Add(this.m_lblRecSep); this.m_grpSyntax.Location = new System.Drawing.Point(6, 13); this.m_grpSyntax.Name = "m_grpSyntax"; this.m_grpSyntax.Size = new System.Drawing.Size(662, 121); this.m_grpSyntax.TabIndex = 0; this.m_grpSyntax.TabStop = false; this.m_grpSyntax.Text = "Syntax"; // // m_cbIgnoreFirst // this.m_cbIgnoreFirst.AutoSize = true; this.m_cbIgnoreFirst.Location = new System.Drawing.Point(9, 73); this.m_cbIgnoreFirst.Name = "m_cbIgnoreFirst"; this.m_cbIgnoreFirst.Size = new System.Drawing.Size(95, 17); this.m_cbIgnoreFirst.TabIndex = 7; this.m_cbIgnoreFirst.Text = "Ignore first row"; this.m_cbIgnoreFirst.UseVisualStyleBackColor = true; // // m_cbTrim // this.m_cbTrim.AutoSize = true; this.m_cbTrim.Checked = true; this.m_cbTrim.CheckState = System.Windows.Forms.CheckState.Checked; this.m_cbTrim.Location = new System.Drawing.Point(9, 96); this.m_cbTrim.Name = "m_cbTrim"; this.m_cbTrim.Size = new System.Drawing.Size(331, 17); this.m_cbTrim.TabIndex = 8; this.m_cbTrim.Text = "Remove white space characters from the beginning/end of fields"; this.m_cbTrim.UseVisualStyleBackColor = true; // // m_cmbTextQual // this.m_cmbTextQual.FormattingEnabled = true; this.m_cmbTextQual.Location = new System.Drawing.Point(91, 46); this.m_cmbTextQual.Name = "m_cmbTextQual"; this.m_cmbTextQual.Size = new System.Drawing.Size(112, 21); this.m_cmbTextQual.TabIndex = 5; this.m_cmbTextQual.SelectedIndexChanged += new System.EventHandler(this.OnTextQualSelectedIndexChanged); this.m_cmbTextQual.TextUpdate += new System.EventHandler(this.OnTextQualTextUpdate); // // m_lblTextQual // this.m_lblTextQual.AutoSize = true; this.m_lblTextQual.Location = new System.Drawing.Point(6, 49); this.m_lblTextQual.Name = "m_lblTextQual"; this.m_lblTextQual.Size = new System.Drawing.Size(70, 13); this.m_lblTextQual.TabIndex = 4; this.m_lblTextQual.Text = "Text qualifier:"; // // m_cbBackEscape // this.m_cbBackEscape.AutoSize = true; this.m_cbBackEscape.Checked = true; this.m_cbBackEscape.CheckState = System.Windows.Forms.CheckState.Checked; this.m_cbBackEscape.Location = new System.Drawing.Point(248, 48); this.m_cbBackEscape.Name = "m_cbBackEscape"; this.m_cbBackEscape.Size = new System.Drawing.Size(192, 17); this.m_cbBackEscape.TabIndex = 6; this.m_cbBackEscape.Text = "Interpret \'\\\' as an escape character"; this.m_cbBackEscape.UseVisualStyleBackColor = true; // // m_lblFieldSep // this.m_lblFieldSep.AutoSize = true; this.m_lblFieldSep.Location = new System.Drawing.Point(6, 22); this.m_lblFieldSep.Name = "m_lblFieldSep"; this.m_lblFieldSep.Size = new System.Drawing.Size(79, 13); this.m_lblFieldSep.TabIndex = 0; this.m_lblFieldSep.Text = "Field separator:"; // // m_cmbFieldSep // this.m_cmbFieldSep.FormattingEnabled = true; this.m_cmbFieldSep.Location = new System.Drawing.Point(91, 19); this.m_cmbFieldSep.Name = "m_cmbFieldSep"; this.m_cmbFieldSep.Size = new System.Drawing.Size(112, 21); this.m_cmbFieldSep.TabIndex = 1; this.m_cmbFieldSep.SelectedIndexChanged += new System.EventHandler(this.OnFieldSepSelectedIndexChanged); this.m_cmbFieldSep.TextUpdate += new System.EventHandler(this.OnFieldSepTextUpdate); // // m_cmbRecSep // this.m_cmbRecSep.FormattingEnabled = true; this.m_cmbRecSep.Location = new System.Drawing.Point(343, 19); this.m_cmbRecSep.Name = "m_cmbRecSep"; this.m_cmbRecSep.Size = new System.Drawing.Size(112, 21); this.m_cmbRecSep.TabIndex = 3; this.m_cmbRecSep.SelectedIndexChanged += new System.EventHandler(this.OnRecSepSelectedIndexChanged); this.m_cmbRecSep.TextUpdate += new System.EventHandler(this.OnRecSepTextUpdate); // // m_lblRecSep // this.m_lblRecSep.AutoSize = true; this.m_lblRecSep.Location = new System.Drawing.Point(245, 22); this.m_lblRecSep.Name = "m_lblRecSep"; this.m_lblRecSep.Size = new System.Drawing.Size(92, 13); this.m_lblRecSep.TabIndex = 2; this.m_lblRecSep.Text = "Record separator:"; // // m_tabPreview // this.m_tabPreview.Controls.Add(this.m_cbMergeGroups); this.m_tabPreview.Controls.Add(this.m_lvImportPreview); this.m_tabPreview.Location = new System.Drawing.Point(4, 22); this.m_tabPreview.Name = "m_tabPreview"; this.m_tabPreview.Size = new System.Drawing.Size(676, 436); this.m_tabPreview.TabIndex = 2; this.m_tabPreview.Text = "Preview"; this.m_tabPreview.UseVisualStyleBackColor = true; // // m_cbMergeGroups // this.m_cbMergeGroups.AutoSize = true; this.m_cbMergeGroups.Location = new System.Drawing.Point(6, 414); this.m_cbMergeGroups.Name = "m_cbMergeGroups"; this.m_cbMergeGroups.Size = new System.Drawing.Size(342, 17); this.m_cbMergeGroups.TabIndex = 1; this.m_cbMergeGroups.Text = "&Merge imported groups with groups already existing in the database"; this.m_cbMergeGroups.UseVisualStyleBackColor = true; // // m_lvImportPreview // this.m_lvImportPreview.FullRowSelect = true; this.m_lvImportPreview.HeaderStyle = System.Windows.Forms.ColumnHeaderStyle.Nonclickable; this.m_lvImportPreview.HideSelection = false; this.m_lvImportPreview.Location = new System.Drawing.Point(6, 13); this.m_lvImportPreview.Name = "m_lvImportPreview"; this.m_lvImportPreview.ShowItemToolTips = true; this.m_lvImportPreview.Size = new System.Drawing.Size(662, 395); this.m_lvImportPreview.TabIndex = 0; this.m_lvImportPreview.UseCompatibleStateImageBehavior = false; this.m_lvImportPreview.View = System.Windows.Forms.View.Details; // // m_btnOK // this.m_btnOK.DialogResult = System.Windows.Forms.DialogResult.OK; this.m_btnOK.Location = new System.Drawing.Point(539, 480); this.m_btnOK.Name = "m_btnOK"; this.m_btnOK.Size = new System.Drawing.Size(75, 23); this.m_btnOK.TabIndex = 0; this.m_btnOK.Text = "&Finish"; this.m_btnOK.UseVisualStyleBackColor = true; this.m_btnOK.Click += new System.EventHandler(this.OnBtnOK); // // m_btnCancel // this.m_btnCancel.DialogResult = System.Windows.Forms.DialogResult.Cancel; this.m_btnCancel.Location = new System.Drawing.Point(620, 480); this.m_btnCancel.Name = "m_btnCancel"; this.m_btnCancel.Size = new System.Drawing.Size(75, 23); this.m_btnCancel.TabIndex = 1; this.m_btnCancel.Text = "Cancel"; this.m_btnCancel.UseVisualStyleBackColor = true; // // m_btnTabBack // this.m_btnTabBack.Location = new System.Drawing.Point(383, 480); this.m_btnTabBack.Name = "m_btnTabBack"; this.m_btnTabBack.Size = new System.Drawing.Size(75, 23); this.m_btnTabBack.TabIndex = 4; this.m_btnTabBack.Text = "< &Back"; this.m_btnTabBack.UseVisualStyleBackColor = true; this.m_btnTabBack.Click += new System.EventHandler(this.OnBtnTabBack); // // m_btnTabNext // this.m_btnTabNext.Location = new System.Drawing.Point(458, 480); this.m_btnTabNext.Name = "m_btnTabNext"; this.m_btnTabNext.Size = new System.Drawing.Size(75, 23); this.m_btnTabNext.TabIndex = 5; this.m_btnTabNext.Text = "&Next >"; this.m_btnTabNext.UseVisualStyleBackColor = true; this.m_btnTabNext.Click += new System.EventHandler(this.OnBtnTabNext); // // m_btnHelp // this.m_btnHelp.Location = new System.Drawing.Point(11, 480); this.m_btnHelp.Name = "m_btnHelp"; this.m_btnHelp.Size = new System.Drawing.Size(75, 23); this.m_btnHelp.TabIndex = 3; this.m_btnHelp.Text = "&Help"; this.m_btnHelp.UseVisualStyleBackColor = true; this.m_btnHelp.Click += new System.EventHandler(this.OnBtnHelp); // // CsvImportForm // this.AcceptButton = this.m_btnOK; this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F); this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; this.CancelButton = this.m_btnCancel; this.ClientSize = new System.Drawing.Size(708, 515); this.Controls.Add(this.m_btnHelp); this.Controls.Add(this.m_btnTabNext); this.Controls.Add(this.m_btnTabBack); this.Controls.Add(this.m_btnCancel); this.Controls.Add(this.m_btnOK); this.Controls.Add(this.m_tabMain); this.FormBorderStyle = System.Windows.Forms.FormBorderStyle.FixedDialog; this.MaximizeBox = false; this.MinimizeBox = false; this.Name = "CsvImportForm"; this.ShowInTaskbar = false; this.StartPosition = System.Windows.Forms.FormStartPosition.CenterScreen; this.Text = "<>"; this.Load += new System.EventHandler(this.OnFormLoad); this.FormClosed += new System.Windows.Forms.FormClosedEventHandler(this.OnFormClosed); this.m_tabMain.ResumeLayout(false); this.m_tabEnc.ResumeLayout(false); this.m_tabEnc.PerformLayout(); this.m_tabStructure.ResumeLayout(false); this.m_grpSem.ResumeLayout(false); this.m_grpSem.PerformLayout(); this.m_grpFieldAdd.ResumeLayout(false); this.m_grpFieldAdd.PerformLayout(); this.m_grpSyntax.ResumeLayout(false); this.m_grpSyntax.PerformLayout(); this.m_tabPreview.ResumeLayout(false); this.m_tabPreview.PerformLayout(); this.ResumeLayout(false); } #endregion private System.Windows.Forms.TabControl m_tabMain; private System.Windows.Forms.TabPage m_tabEnc; private System.Windows.Forms.TabPage m_tabStructure; private System.Windows.Forms.Button m_btnOK; private System.Windows.Forms.Button m_btnCancel; private System.Windows.Forms.TabPage m_tabPreview; private System.Windows.Forms.ComboBox m_cmbEnc; private System.Windows.Forms.Label m_lblEnc; private KeePass.UI.CustomRichTextBoxEx m_rtbEncPreview; private System.Windows.Forms.Label m_lblEncPreview; private System.Windows.Forms.ComboBox m_cmbRecSep; private System.Windows.Forms.Label m_lblRecSep; private System.Windows.Forms.Label m_lblFieldSep; private System.Windows.Forms.ComboBox m_cmbFieldSep; private System.Windows.Forms.GroupBox m_grpSyntax; private System.Windows.Forms.GroupBox m_grpSem; private System.Windows.Forms.Button m_btnFieldDel; private System.Windows.Forms.Label m_lblFields; private KeePass.UI.CustomListViewEx m_lvFields; private System.Windows.Forms.GroupBox m_grpFieldAdd; private System.Windows.Forms.Label m_lblFieldFormat; private System.Windows.Forms.TextBox m_tbFieldName; private System.Windows.Forms.Label m_lblFieldName; private System.Windows.Forms.ComboBox m_cmbFieldType; private System.Windows.Forms.Label m_lblFieldType; private System.Windows.Forms.Button m_btnFieldMoveDown; private System.Windows.Forms.Button m_btnFieldMoveUp; private System.Windows.Forms.Button m_btnFieldAdd; private System.Windows.Forms.LinkLabel m_linkFieldFormat; private System.Windows.Forms.ComboBox m_cmbFieldFormat; private KeePass.UI.CustomListViewEx m_lvImportPreview; private System.Windows.Forms.CheckBox m_cbBackEscape; private System.Windows.Forms.ComboBox m_cmbTextQual; private System.Windows.Forms.Label m_lblTextQual; private System.Windows.Forms.CheckBox m_cbTrim; private System.Windows.Forms.Button m_btnTabBack; private System.Windows.Forms.Button m_btnTabNext; private System.Windows.Forms.CheckBox m_cbIgnoreFirst; private System.Windows.Forms.Button m_btnHelp; private System.Windows.Forms.CheckBox m_cbMergeGroups; } }KeePass/Forms/DuplicationForm.resx0000664000000000000000000001375312501527406016214 0ustar rootroot text/microsoft-resx 2.0 System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 If this option is enabled, the copies will reference the user names and passwords of the original entries. When a user name or password is changed in an original entry, the copy will automatically use the new data, too. KeePass/Forms/ColumnsForm.cs0000664000000000000000000002436313222430410014771 0ustar rootroot/* KeePass Password Safe - The Open-Source Password Manager Copyright (C) 2003-2018 Dominik Reichl This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ using System; using System.Collections.Generic; using System.ComponentModel; using System.Diagnostics; using System.Drawing; using System.Text; using System.Threading; using System.Windows.Forms; using KeePass.App; using KeePass.App.Configuration; using KeePass.Resources; using KeePass.UI; using KeePassLib; using KeePassLib.Delegates; using KeePassLib.Security; using KeePassLib.Utility; namespace KeePass.Forms { public delegate void AceColumnDelegate(AceColumn c); // public delegate void UpdateUIDelegate(bool bGuiToInternal); public partial class ColumnsForm : Form { private bool m_bIgnoreHideCheckEvent = false; public ColumnsForm() { InitializeComponent(); Program.Translation.ApplyTo(this); } private void OnFormLoad(object sender, EventArgs e) { GlobalWindowManager.AddWindow(this); BannerFactory.CreateBannerEx(this, m_bannerImage, Properties.Resources.B48x48_View_Detailed, KPRes.ConfigureColumns, KPRes.ConfigureColumnsDesc); this.Icon = AppIcons.Default; this.Text = KPRes.ConfigureColumns; float fWidth = (float)(m_lvColumns.ClientRectangle.Width - UIUtil.GetVScrollBarWidth()) / 5.0f; m_lvColumns.Columns.Add(KPRes.Column, (int)(fWidth * 3.0f)); m_lvColumns.Columns.Add(KPRes.Asterisks + " ***", (int)fWidth); m_lvColumns.Columns.Add(KPRes.Toggle + " ***", (int)fWidth); UIUtil.SetExplorerTheme(m_lvColumns, false); UpdateColumnPropInfo(); ThreadPool.QueueUserWorkItem(new WaitCallback(FillColumnsList)); } private void AddAceColumnTh(AceColumn c) { string strLvgName = KPRes.StandardFields; if(c.Type == AceColumnType.CustomString) strLvgName = KPRes.CustomFields; else if(c.Type == AceColumnType.PluginExt) strLvgName = KPRes.PluginProvided; else if((int)c.Type > (int)AceColumnType.PluginExt) strLvgName = KPRes.More; ListViewGroup lvgContainer = null; foreach(ListViewGroup lvg in m_lvColumns.Groups) { if(lvg.Header == strLvgName) { lvgContainer = lvg; break; } } if(lvgContainer == null) { lvgContainer = new ListViewGroup(strLvgName); m_lvColumns.Groups.Add(lvgContainer); } ListViewItem lvi = new ListViewItem(c.GetDisplayName()); lvi.Tag = c; lvi.SubItems.Add(c.HideWithAsterisks ? KPRes.Yes : KPRes.No); if(c.Type == AceColumnType.Password) lvi.SubItems.Add(KPRes.KeyboardKeyCtrl + "+H"); else if(c.Type == AceColumnType.UserName) lvi.SubItems.Add(KPRes.KeyboardKeyCtrl + "+J"); else lvi.SubItems.Add(string.Empty); bool bChecked = false; List lCur = Program.Config.MainWindow.EntryListColumns; foreach(AceColumn cCur in lCur) { if(cCur.Type != c.Type) continue; if((c.Type != AceColumnType.CustomString) && (c.Type != AceColumnType.PluginExt)) { bChecked = true; break; } else if((c.Type == AceColumnType.CustomString) && (cCur.CustomName == c.CustomName)) { bChecked = true; break; } else if((c.Type == AceColumnType.PluginExt) && (cCur.CustomName == c.CustomName)) { bChecked = true; break; } } lvi.Checked = bChecked; lvi.Group = lvgContainer; m_lvColumns.Items.Add(lvi); } private void AddAceColumn(List lContainer, AceColumn c) { m_lvColumns.Invoke(new AceColumnDelegate(AddAceColumnTh), c); lContainer.Add(c); } private void AddStdAceColumn(List lContainer, AceColumnType colType) { bool bHide = (colType == AceColumnType.Password); // Passwords hidden by default int nWidth = -1; List lCur = Program.Config.MainWindow.EntryListColumns; foreach(AceColumn cCur in lCur) { if(cCur.Type == colType) { bHide = cCur.HideWithAsterisks; nWidth = cCur.Width; break; } } AddAceColumn(lContainer, new AceColumn(colType, string.Empty, bHide, nWidth)); } private void FillColumnsList(object state) { List l = new List(); AddStdAceColumn(l, AceColumnType.Title); AddStdAceColumn(l, AceColumnType.UserName); AddStdAceColumn(l, AceColumnType.Password); AddStdAceColumn(l, AceColumnType.Url); AddStdAceColumn(l, AceColumnType.Notes); AddStdAceColumn(l, AceColumnType.CreationTime); if((Program.Config.UI.UIFlags & (ulong)AceUIFlags.ShowLastAccessTime) != 0) AddStdAceColumn(l, AceColumnType.LastAccessTime); AddStdAceColumn(l, AceColumnType.LastModificationTime); AddStdAceColumn(l, AceColumnType.ExpiryTime); AddStdAceColumn(l, AceColumnType.Uuid); AddStdAceColumn(l, AceColumnType.Attachment); SortedDictionary d = new SortedDictionary(StrUtil.CaseIgnoreComparer); List lCur = Program.Config.MainWindow.EntryListColumns; foreach(AceColumn cCur in lCur) { if((cCur.Type == AceColumnType.CustomString) && !d.ContainsKey(cCur.CustomName)) { d[cCur.CustomName] = new AceColumn(AceColumnType.CustomString, cCur.CustomName, cCur.HideWithAsterisks, cCur.Width); } } foreach(PwDocument pwDoc in Program.MainForm.DocumentManager.Documents) { if(string.IsNullOrEmpty(pwDoc.LockedIoc.Path) && pwDoc.Database.IsOpen) { EntryHandler eh = delegate(PwEntry pe) { foreach(KeyValuePair kvp in pe.Strings) { if(PwDefs.IsStandardField(kvp.Key)) continue; if(d.ContainsKey(kvp.Key)) continue; d[kvp.Key] = new AceColumn(AceColumnType.CustomString, kvp.Key, kvp.Value.IsProtected, -1); } return true; }; pwDoc.Database.RootGroup.TraverseTree(TraversalMethod.PreOrder, null, eh); } } foreach(KeyValuePair kvpCustom in d) { AddAceColumn(l, kvpCustom.Value); } AddStdAceColumn(l, AceColumnType.Size); AddStdAceColumn(l, AceColumnType.AttachmentCount); AddStdAceColumn(l, AceColumnType.HistoryCount); AddStdAceColumn(l, AceColumnType.OverrideUrl); AddStdAceColumn(l, AceColumnType.Tags); AddStdAceColumn(l, AceColumnType.ExpiryTimeDateOnly); AddStdAceColumn(l, AceColumnType.LastPasswordModTime); d.Clear(); // Add active plugin columns (including those of uninstalled plugins) foreach(AceColumn cCur in lCur) { if(cCur.Type != AceColumnType.PluginExt) continue; if(d.ContainsKey(cCur.CustomName)) { Debug.Assert(false); continue; } d[cCur.CustomName] = new AceColumn(AceColumnType.PluginExt, cCur.CustomName, cCur.HideWithAsterisks, cCur.Width); } // Add unused plugin columns string[] vPlgExtNames = Program.ColumnProviderPool.GetColumnNames(); foreach(string strPlgName in vPlgExtNames) { if(d.ContainsKey(strPlgName)) continue; // Do not overwrite d[strPlgName] = new AceColumn(AceColumnType.PluginExt, strPlgName, false, -1); } foreach(KeyValuePair kvpExt in d) { AddAceColumn(l, kvpExt.Value); } // m_lvColumns.Invoke(new UpdateUIDelegate(UpdateListEx), false); } private void UpdateListEx(bool bGuiToInternal) { if(bGuiToInternal) { } else // Internal to GUI { foreach(ListViewItem lvi in m_lvColumns.Items) { AceColumn c = (lvi.Tag as AceColumn); if(c == null) { Debug.Assert(false); continue; } string str = (c.HideWithAsterisks ? KPRes.Yes : KPRes.No); lvi.SubItems[1].Text = str; } } } private void UpdateColumnPropInfo() { ListView.SelectedListViewItemCollection lvsic = m_lvColumns.SelectedItems; if((lvsic == null) || (lvsic.Count != 1) || (lvsic[0] == null)) { m_grpColumn.Text = KPRes.SelectedColumn + ": (" + KPRes.None + ")"; m_cbHide.Checked = false; m_cbHide.Enabled = false; } else { ListViewItem lvi = lvsic[0]; AceColumn c = (lvi.Tag as AceColumn); if(c == null) { Debug.Assert(false); return; } m_grpColumn.Text = KPRes.SelectedColumn + ": " + c.GetDisplayName(); m_cbHide.Enabled = true; m_bIgnoreHideCheckEvent = true; UIUtil.SetChecked(m_cbHide, c.HideWithAsterisks); m_bIgnoreHideCheckEvent = false; } } private void OnFormClosed(object sender, FormClosedEventArgs e) { GlobalWindowManager.RemoveWindow(this); } private void OnBtnOK(object sender, EventArgs e) { List l = Program.Config.MainWindow.EntryListColumns; l.Clear(); foreach(ListViewItem lvi in m_lvColumns.Items) { if(!lvi.Checked) continue; AceColumn c = (lvi.Tag as AceColumn); if(c == null) { Debug.Assert(false); continue; } l.Add(c); } } private void OnBtnCancel(object sender, EventArgs e) { } private void OnColumnsSelectedIndexChanged(object sender, EventArgs e) { UpdateColumnPropInfo(); } private void OnHideCheckedChanged(object sender, EventArgs e) { if(m_bIgnoreHideCheckEvent) return; bool bChecked = m_cbHide.Checked; foreach(ListViewItem lvi in m_lvColumns.SelectedItems) { AceColumn c = (lvi.Tag as AceColumn); if(c == null) { Debug.Assert(false); continue; } if((c.Type == AceColumnType.Password) && c.HideWithAsterisks && !AppPolicy.Try(AppPolicyId.UnhidePasswords)) { // Do not change c.HideWithAsterisks } else c.HideWithAsterisks = bChecked; } UpdateListEx(false); } } } KeePass/Forms/LanguageForm.cs0000664000000000000000000002137713222430410015076 0ustar rootroot/* KeePass Password Safe - The Open-Source Password Manager Copyright (C) 2003-2018 Dominik Reichl This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ using System; using System.Collections.Generic; using System.ComponentModel; using System.Diagnostics; using System.Drawing; using System.IO; using System.Text; using System.Windows.Forms; using KeePass.App; using KeePass.App.Configuration; using KeePass.Resources; using KeePass.UI; using KeePass.Util; using KeePass.Util.XmlSerialization; using KeePassLib; using KeePassLib.Translation; using KeePassLib.Utility; namespace KeePass.Forms { public partial class LanguageForm : Form, IGwmWindow { private ImageList m_ilIcons = null; public bool CanCloseWithoutDataLoss { get { return true; } } public LanguageForm() { InitializeComponent(); Program.Translation.ApplyTo(this); } public bool InitEx() { try { string strDir = UrlUtil.GetFileDirectory(WinUtil.GetExecutable(), false, true); List l = UrlUtil.GetFilePaths(strDir, "*." + KPTranslation.FileExtension, SearchOption.TopDirectoryOnly); if(l.Count != 0) { string str = KPRes.LngInAppDir + MessageService.NewParagraph; const int cMaxFL = 6; for(int i = 0; i < Math.Min(l.Count, cMaxFL); ++i) { if(i == (cMaxFL - 1)) str += "..."; else str += l[i]; str += MessageService.NewLine; } str += MessageService.NewLine; str += KPRes.LngInAppDirNote + MessageService.NewParagraph; str += KPRes.LngInAppDirQ; if(MessageService.AskYesNo(str, PwDefs.ShortProductName, true, MessageBoxIcon.Warning)) { WinUtil.OpenUrl("cmd://\"" + strDir + "\"", null, false); return false; } } } catch(Exception) { Debug.Assert(false); } return true; } private void OnFormLoad(object sender, EventArgs e) { GlobalWindowManager.AddWindow(this, this); BannerFactory.CreateBannerEx(this, m_bannerImage, Properties.Resources.B48x48_Keyboard_Layout, KPRes.SelectLanguage, KPRes.SelectLanguageDesc); this.Icon = AppIcons.Default; this.Text = KPRes.SelectLanguage; UIUtil.SetExplorerTheme(m_lvLanguages, true); List lImg = new List(); lImg.Add(Properties.Resources.B16x16_Browser); m_ilIcons = UIUtil.BuildImageListUnscaled(lImg, DpiUtil.ScaleIntX(16), DpiUtil.ScaleIntY(16)); m_lvLanguages.SmallImageList = m_ilIcons; m_lvLanguages.Columns.Add(KPRes.InstalledLanguages); m_lvLanguages.Columns.Add(KPRes.Version); m_lvLanguages.Columns.Add(KPRes.Author); m_lvLanguages.Columns.Add(KPRes.Contact); m_lvLanguages.Columns.Add(KPRes.File); KPTranslation trlEng = new KPTranslation(); trlEng.Properties.NameEnglish = "English"; trlEng.Properties.NameNative = "English"; trlEng.Properties.ApplicationVersion = PwDefs.VersionString; trlEng.Properties.AuthorName = AppDefs.DefaultTrlAuthor; trlEng.Properties.AuthorContact = AppDefs.DefaultTrlContact; string strDirA = AceApplication.GetLanguagesDir(AceDir.App, false); string strDirASep = UrlUtil.EnsureTerminatingSeparator(strDirA, false); string strDirU = AceApplication.GetLanguagesDir(AceDir.User, false); List> lTrls = new List>(); lTrls.Add(new KeyValuePair(string.Empty, trlEng)); AddTranslations(strDirA, lTrls); if(WinUtil.IsAppX) AddTranslations(strDirU, lTrls); lTrls.Sort(LanguageForm.CompareTrlItems); foreach(KeyValuePair kvp in lTrls) { KPTranslationProperties p = kvp.Value.Properties; string strName = p.NameEnglish + " (" + p.NameNative + ")"; bool bBuiltIn = ((kvp.Key.Length == 0) || (WinUtil.IsAppX && kvp.Key.StartsWith(strDirASep, StrUtil.CaseIgnoreCmp))); ListViewItem lvi = m_lvLanguages.Items.Add(strName, 0); lvi.SubItems.Add(p.ApplicationVersion); lvi.SubItems.Add(p.AuthorName); lvi.SubItems.Add(p.AuthorContact); lvi.SubItems.Add(bBuiltIn ? KPRes.BuiltInU : kvp.Key); lvi.Tag = kvp.Key; // try // { // string nl = MessageService.NewLine; // lvi.ToolTipText = strName + " " + p.ApplicationVersion + nl + // p.AuthorName + nl + p.AuthorContact + nl + nl + kvp.Key; // } // catch(Exception) { Debug.Assert(false); } // Too long? // if(kvp.Key.Equals(Program.Config.Application.GetLanguageFilePath(), // StrUtil.CaseIgnoreCmp)) // UIUtil.SetFocusedItem(m_lvLanguages, lvi, true); } UIUtil.ResizeColumns(m_lvLanguages, new int[] { 5, 2, 5, 5, 3 }, true); UIUtil.SetFocus(m_lvLanguages, this); } private static void AddTranslations(string strDir, List> lTrls) { try { List lFiles = UrlUtil.GetFilePaths(strDir, "*." + KPTranslation.FileExtension, SearchOption.TopDirectoryOnly); foreach(string strFilePath in lFiles) { try { XmlSerializerEx xs = new XmlSerializerEx(typeof(KPTranslation)); KPTranslation t = KPTranslation.Load(strFilePath, xs); if(t != null) lTrls.Add(new KeyValuePair( strFilePath, t)); else { Debug.Assert(false); } } catch(Exception ex) { MessageService.ShowWarning(ex.Message); } } } catch(Exception) { } // Directory might not exist or cause access violation } private static int CompareTrlItems(KeyValuePair a, KeyValuePair b) { KPTranslationProperties pA = a.Value.Properties; KPTranslationProperties pB = b.Value.Properties; int c = StrUtil.CompareNaturally(pA.NameEnglish, pB.NameEnglish); if(c != 0) return c; c = StrUtil.CompareNaturally(pA.NameNative, pB.NameNative); if(c != 0) return c; c = StrUtil.CompareNaturally(pA.ApplicationVersion, pB.ApplicationVersion); if(c != 0) return ((c < 0) ? 1 : -1); // Descending return string.Compare(a.Key, b.Key, StrUtil.CaseIgnoreCmp); } private void OnBtnClose(object sender, EventArgs e) { } private void OnLanguagesItemActivate(object sender, EventArgs e) { ListView.SelectedListViewItemCollection lvic = m_lvLanguages.SelectedItems; if((lvic == null) || (lvic.Count != 1)) return; string strSel = ((lvic[0].Tag as string) ?? string.Empty); // The following creates confusion when the configured language // is different from the loaded language (which can occur when // the language file has been deleted/moved) // if(strSel.Equals(Program.Config.Application.GetLanguageFilePath(), // StrUtil.CaseIgnoreCmp)) // return; // Is active already, do not close the dialog Program.Config.Application.SetLanguageFilePath(strSel); this.DialogResult = DialogResult.OK; } private void OnFormClosed(object sender, FormClosedEventArgs e) { if(m_ilIcons != null) { m_lvLanguages.SmallImageList = null; m_ilIcons.Dispose(); m_ilIcons = null; } else { Debug.Assert(false); } GlobalWindowManager.RemoveWindow(this); } private void OnBtnGetMore(object sender, EventArgs e) { WinUtil.OpenUrl(PwDefs.TranslationsUrl, null); this.DialogResult = DialogResult.Cancel; } private void OnBtnOpenFolder(object sender, EventArgs e) { try { AceDir d = (WinUtil.IsAppX ? AceDir.User : AceDir.App); // try // { // string strU = AceApplication.GetLanguagesDir(AceDir.User, false); // List l = UrlUtil.GetFilePaths(strU, "*." + // KPTranslation.FileExtension, SearchOption.TopDirectoryOnly); // if(l.Count > 0) d = AceDir.User; // } // catch(Exception) { } string str = AceApplication.GetLanguagesDir(d, false); if(!Directory.Exists(str)) Directory.CreateDirectory(str); WinUtil.OpenUrl("cmd://\"" + str + "\"", null, false); this.DialogResult = DialogResult.Cancel; } catch(Exception ex) { MessageService.ShowWarning(ex.Message); } } } } KeePass/Forms/DuplicationForm.cs0000664000000000000000000000754013222430410015622 0ustar rootroot/* KeePass Password Safe - The Open-Source Password Manager Copyright (C) 2003-2018 Dominik Reichl This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ using System; using System.Collections.Generic; using System.ComponentModel; using System.Diagnostics; using System.Drawing; using System.Text; using System.Windows.Forms; using KeePass.App; using KeePass.Resources; using KeePass.UI; using KeePassLib; using KeePassLib.Collections; using KeePassLib.Security; namespace KeePass.Forms { public partial class DuplicationForm : Form { // Copy data from controls to simple member variables, // because ApplyTo must work after the dialog has been destroyed. private bool m_bAppendCopy = true; // public bool AppendCopyToTitles // { // get { return m_bAppendCopy; } // } private bool m_bFieldRefs = false; // public bool ReplaceDataByFieldRefs // { // get { return m_bFieldRefs; } // } private bool m_bCopyHistory = true; // public bool CopyHistory // { // get { return m_bCopyHistory; } // } public void ApplyTo(PwEntry peNew, PwEntry pe, PwDatabase pd) { if((peNew == null) || (pe == null)) { Debug.Assert(false); return; } Debug.Assert(peNew.Strings.ReadSafe(PwDefs.UserNameField) == pe.Strings.ReadSafe(PwDefs.UserNameField)); Debug.Assert(peNew.Strings.ReadSafe(PwDefs.PasswordField) == pe.Strings.ReadSafe(PwDefs.PasswordField)); if(m_bAppendCopy && (pd != null)) { string strTitle = peNew.Strings.ReadSafe(PwDefs.TitleField); peNew.Strings.Set(PwDefs.TitleField, new ProtectedString( pd.MemoryProtection.ProtectTitle, strTitle + " - " + KPRes.CopyOfItem)); } if(m_bFieldRefs && (pd != null)) { string strUser = @"{REF:U@I:" + pe.Uuid.ToHexString() + @"}"; peNew.Strings.Set(PwDefs.UserNameField, new ProtectedString( pd.MemoryProtection.ProtectUserName, strUser)); string strPw = @"{REF:P@I:" + pe.Uuid.ToHexString() + @"}"; peNew.Strings.Set(PwDefs.PasswordField, new ProtectedString( pd.MemoryProtection.ProtectPassword, strPw)); } if(!m_bCopyHistory) peNew.History = new PwObjectList(); } public DuplicationForm() { InitializeComponent(); Program.Translation.ApplyTo(this); } private void OnFormLoad(object sender, EventArgs e) { GlobalWindowManager.AddWindow(this); this.Icon = AppIcons.Default; FontUtil.AssignDefaultBold(m_cbAppendCopy); FontUtil.AssignDefaultBold(m_cbFieldRefs); FontUtil.AssignDefaultBold(m_cbCopyHistory); m_cbAppendCopy.Checked = m_bAppendCopy; m_cbFieldRefs.Checked = m_bFieldRefs; m_cbCopyHistory.Checked = m_bCopyHistory; } private void OnFormClosed(object sender, FormClosedEventArgs e) { GlobalWindowManager.RemoveWindow(this); } private void OnFieldRefsLinkClicked(object sender, LinkLabelLinkClickedEventArgs e) { AppHelp.ShowHelp(AppDefs.HelpTopics.FieldRefs, null); } private void OnBtnOK(object sender, EventArgs e) { m_bAppendCopy = m_cbAppendCopy.Checked; m_bFieldRefs = m_cbFieldRefs.Checked; m_bCopyHistory = m_cbCopyHistory.Checked; } } } KeePass/Forms/EcasTriggersForm.resx0000664000000000000000000001357412501537774016335 0ustar rootroot text/microsoft-resx 2.0 System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 17, 17 KeePass/Forms/GroupForm.resx0000664000000000000000000001326612760323236015036 0ustar rootroot text/microsoft-resx 2.0 System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 KeePass/Forms/KeyCreationForm.resx0000664000000000000000000001505613122740232016146 0ustar rootroot text/microsoft-resx 2.0 System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 A composite master key consists of one or more of the following key sources. All sources you specify will be required to open the database. If you lose one source, you will not be able to open the database anymore. 17, 17 If the Windows user account is lost, it will not be enough to create a new account with the same user name and password. A complete backup of the account is required. Creating and restoring such a backup is a very complicated task. If you don't know how to do this, don't enable this option. KeePass/Forms/PrintForm.cs0000664000000000000000000007360113224154300014447 0ustar rootroot/* KeePass Password Safe - The Open-Source Password Manager Copyright (C) 2003-2018 Dominik Reichl This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ using System; using System.Collections.Generic; using System.ComponentModel; using System.Diagnostics; using System.Drawing; using System.Globalization; using System.Text; using System.Windows.Forms; using KeePass.App; using KeePass.App.Configuration; using KeePass.Resources; using KeePass.UI; using KeePass.Util.Spr; using KeePassLib; using KeePassLib.Collections; using KeePassLib.Delegates; using KeePassLib.Native; using KeePassLib.Resources; using KeePassLib.Security; using KeePassLib.Translation; using KeePassLib.Utility; namespace KeePass.Forms { public partial class PrintForm : Form { private PwGroup m_pgDataSource = null; private PwDatabase m_pdContext = null; private ImageList m_ilClientIcons = null; private bool m_bPrintMode = true; private int m_nDefaultSortColumn = -1; private bool m_bBlockPreviewRefresh = false; private Control m_cPreBlock = null; private ImageList m_ilTabIcons = null; private string m_strGeneratedHtml = string.Empty; public string GeneratedHtml { get { return m_strGeneratedHtml; } } private static string g_strCodeItS = null; private static string g_strCodeItE = null; private sealed class PfOptions { public bool MonoPasswords = true; public bool SmallMono = false; public int SprMode = 0; public string CellInit = string.Empty; public string CellExit = string.Empty; public string FontInit = string.Empty; public string FontExit = string.Empty; public bool Rtl = false; public PwEntry Entry = null; public PwDatabase Database = null; public ImageList ClientIcons = null; public SprContext SprContext = null; public PfOptions() { } public PfOptions CloneShallow() { return (PfOptions)this.MemberwiseClone(); } } public void InitEx(PwGroup pgDataSource, PwDatabase pdContext, ImageList ilClientIcons, bool bPrintMode, int nDefaultSortColumn) { Debug.Assert(pgDataSource != null); if(pgDataSource == null) throw new ArgumentNullException("pgDataSource"); m_pgDataSource = pgDataSource; m_pdContext = pdContext; m_ilClientIcons = ilClientIcons; m_bPrintMode = bPrintMode; m_nDefaultSortColumn = nDefaultSortColumn; } public PrintForm() { InitializeComponent(); Program.Translation.ApplyTo(this); } private void CreateDialogBanner() { string strTitle, strDesc; if(m_bPrintMode) { strTitle = KPRes.Print; strDesc = KPRes.PrintDesc; } else // HTML export mode { strTitle = KPRes.ExportHtml; strDesc = KPRes.ExportHtmlDesc; } BannerFactory.CreateBannerEx(this, m_bannerImage, Properties.Resources.B48x48_FilePrint, strTitle, strDesc); this.Text = strTitle; } private void OnFormLoad(object sender, EventArgs e) { Debug.Assert(m_pgDataSource != null); if(m_pgDataSource == null) throw new ArgumentException(); GlobalWindowManager.AddWindow(this); this.Icon = AppIcons.Default; CreateDialogBanner(); List lTabImg = new List(); lTabImg.Add(Properties.Resources.B16x16_XMag); lTabImg.Add(Properties.Resources.B16x16_Configure); m_ilTabIcons = UIUtil.BuildImageListUnscaled(lTabImg, DpiUtil.ScaleIntX(16), DpiUtil.ScaleIntY(16)); m_tabMain.ImageList = m_ilTabIcons; m_tabPreview.ImageIndex = 0; m_tabDataLayout.ImageIndex = 1; UIUtil.SetButtonImage(m_btnConfigPrinter, Properties.Resources.B16x16_EditCopy, true); UIUtil.SetButtonImage(m_btnPrintPreview, Properties.Resources.B16x16_FileQuickPrint, true); FontUtil.AssignDefaultBold(m_rbTabular); FontUtil.AssignDefaultBold(m_rbDetails); Debug.Assert(!m_cmbSpr.Sorted); m_cmbSpr.Items.Add(KPRes.ReplaceNo); m_cmbSpr.Items.Add(KPRes.Replace + " (" + KPRes.Slow + ")"); m_cmbSpr.Items.Add(KPRes.BothForms + " (" + KPRes.Slow + ")"); m_cmbSpr.SelectedIndex = 0; if(!m_bPrintMode) m_btnOK.Text = KPRes.Export; m_bBlockPreviewRefresh = true; m_rbTabular.Checked = true; m_cmbSortEntries.Items.Add("(" + KPRes.None + ")"); m_cmbSortEntries.Items.Add(KPRes.Title); m_cmbSortEntries.Items.Add(KPRes.UserName); m_cmbSortEntries.Items.Add(KPRes.Password); m_cmbSortEntries.Items.Add(KPRes.Url); m_cmbSortEntries.Items.Add(KPRes.Notes); AceColumnType colType = AceColumnType.Count; List vCols = Program.Config.MainWindow.EntryListColumns; if((m_nDefaultSortColumn >= 0) && (m_nDefaultSortColumn < vCols.Count)) colType = vCols[m_nDefaultSortColumn].Type; int nSortSel = 0; if(colType == AceColumnType.Title) nSortSel = 1; else if(colType == AceColumnType.UserName) nSortSel = 2; else if(colType == AceColumnType.Password) nSortSel = 3; else if(colType == AceColumnType.Url) nSortSel = 4; else if(colType == AceColumnType.Notes) nSortSel = 5; m_cmbSortEntries.SelectedIndex = nSortSel; m_bBlockPreviewRefresh = false; if(!m_bPrintMode) // Export to HTML { m_btnConfigPrinter.Visible = m_btnPrintPreview.Visible = false; m_lblPreviewHint.Visible = false; } Program.TempFilesPool.AddWebBrowserPrintContent(); UpdateHtmlDocument(true); UpdateUIState(); } private void OnBtnOK(object sender, EventArgs e) { UpdateHtmlDocument(false); if(m_bPrintMode) { try { m_wbMain.ShowPrintDialog(); } // Throws in Mono 1.2.6+ catch(NotImplementedException) { MessageService.ShowWarning(KLRes.FrameworkNotImplExcp); } catch(Exception ex) { MessageService.ShowWarning(ex); } } else m_strGeneratedHtml = UIUtil.GetWebBrowserDocument(m_wbMain); if(m_strGeneratedHtml == null) m_strGeneratedHtml = string.Empty; } private void OnBtnCancel(object sender, EventArgs e) { } private void UpdateUIState() { bool bTabular = m_rbTabular.Checked; bool bDetails = m_rbDetails.Checked; UIUtil.SetEnabled(m_cbAutoType, bDetails); UIUtil.SetEnabled(m_cbCustomStrings, bDetails); if(bTabular) { UIUtil.SetChecked(m_cbAutoType, false); UIUtil.SetChecked(m_cbCustomStrings, false); } bool bIcon = m_cbIcon.Checked; if(m_ilClientIcons == null) { UIUtil.SetChecked(m_cbIcon, false); UIUtil.SetEnabled(m_cbIcon, false); bIcon = false; } UIUtil.SetEnabled(m_cbTitle, !bIcon); if(bIcon) UIUtil.SetChecked(m_cbTitle, true); } private void UIBlockInteraction(bool bBlock) { if(bBlock) m_cPreBlock = UIUtil.GetActiveControl(this); this.UseWaitCursor = bBlock; // this.Enabled = !bBlock; // Prevents wait cursor m_tabMain.Enabled = !bBlock; m_btnConfigPrinter.Enabled = !bBlock; m_btnPrintPreview.Enabled = !bBlock; m_btnOK.Enabled = !bBlock; m_btnCancel.Enabled = !bBlock; m_wbMain.Visible = !bBlock; if(!bBlock && (m_cPreBlock != null)) UIUtil.SetFocus(m_cPreBlock, this); } /* private void ShowWaitDocument() { StringBuilder sbW = new StringBuilder(); sbW.AppendLine(""); sbW.AppendLine(""); sbW.AppendLine(""); sbW.AppendLine(""); sbW.AppendLine("..."); sbW.AppendLine("

"); sbW.AppendLine("

"); sbW.AppendLine(""); try { UIUtil.SetWebBrowserDocument(m_wbMain, sbW.ToString()); } catch(Exception) { Debug.Assert(NativeLib.IsUnix()); } // Throws in Mono 2.0+ } */ private void UpdateHtmlDocument(bool bInitial) { if(m_bBlockPreviewRefresh) return; m_bBlockPreviewRefresh = true; if(!bInitial) UIBlockInteraction(true); // ShowWaitDocument(); PwGroup pgDataSource = m_pgDataSource.CloneDeep(); int nSortEntries = m_cmbSortEntries.SelectedIndex; string strSortFieldName = null; if(nSortEntries == 0) { } // No sort else if(nSortEntries == 1) strSortFieldName = PwDefs.TitleField; else if(nSortEntries == 2) strSortFieldName = PwDefs.UserNameField; else if(nSortEntries == 3) strSortFieldName = PwDefs.PasswordField; else if(nSortEntries == 4) strSortFieldName = PwDefs.UrlField; else if(nSortEntries == 5) strSortFieldName = PwDefs.NotesField; else { Debug.Assert(false); } if(strSortFieldName != null) SortGroupEntriesRecursive(pgDataSource, strSortFieldName); bool bGroup = m_cbGroups.Checked; bool bTitle = m_cbTitle.Checked, bUserName = m_cbUser.Checked; bool bPassword = m_cbPassword.Checked, bUrl = m_cbUrl.Checked; bool bNotes = m_cbNotes.Checked; bool bCreation = m_cbCreation.Checked, bLastMod = m_cbLastMod.Checked; // bool bLastAcc = m_cbLastAccess.Checked; bool bExpire = m_cbExpire.Checked; bool bAutoType = m_cbAutoType.Checked; bool bTags = m_cbTags.Checked; bool bCustomStrings = m_cbCustomStrings.Checked; bool bUuid = m_cbUuid.Checked; PfOptions p = new PfOptions(); p.MonoPasswords = m_cbMonospaceForPasswords.Checked; if(m_rbMonospace.Checked) p.MonoPasswords = false; // Monospace anyway p.SmallMono = m_cbSmallMono.Checked; p.SprMode = m_cmbSpr.SelectedIndex; p.Rtl = (this.RightToLeft == RightToLeft.Yes); p.Database = m_pdContext; if(m_cbIcon.Checked) p.ClientIcons = m_ilClientIcons; if(m_rbSerif.Checked) { p.FontInit = ""; p.FontExit = ""; } else if(m_rbSansSerif.Checked) { p.FontInit = string.Empty; p.FontExit = string.Empty; } else if(m_rbMonospace.Checked) { p.FontInit = (p.SmallMono ? "" : ""); p.FontExit = (p.SmallMono ? "" : ""); } else { Debug.Assert(false); } GFunc h = new GFunc(StrUtil.StringToHtml); GFunc c = delegate(string strRaw) { return CompileText(strRaw, p, true, false); }; GFunc cs = delegate(string strRaw) { return CompileText(strRaw, p, true, true); }; StringBuilder sb = new StringBuilder(); sb.AppendLine(""); sb.Append(""); sb.AppendLine(""); sb.AppendLine(""); sb.Append(""); sb.Append(h(pgDataSource.Name)); sb.AppendLine(""); sb.AppendLine(""); sb.AppendLine(""); sb.AppendLine(""); sb.AppendLine(""); sb.AppendLine(""); sb.AppendLine("

" + h(pgDataSource.Name) + "

"); WriteGroupNotes(sb, pgDataSource); EntryHandler ehInit = delegate(PwEntry pe) { p.Entry = pe; if(p.SprMode != 0) p.SprContext = new SprContext(pe, p.Database, SprCompileFlags.NonActive, false, false); else { Debug.Assert(p.SprContext == null); } Application.DoEvents(); return true; }; EntryHandler eh = null; string strTableInit = ""; PwGroup pgLast = null; if(m_rbTabular.Checked) { int nEquiCols = 0; if(bGroup) ++nEquiCols; if(bTitle) ++nEquiCols; if(bUserName) ++nEquiCols; if(bPassword) ++nEquiCols; if(bUrl) ++nEquiCols; if(bNotes) nEquiCols += 2; if(bCreation) ++nEquiCols; // if(bLastAcc) ++nEquiCols; if(bLastMod) ++nEquiCols; if(bExpire) ++nEquiCols; if(bTags) ++nEquiCols; if(bUuid) ++nEquiCols; if(nEquiCols == 0) nEquiCols = 1; string strColWidth = (100.0f / (float)nEquiCols).ToString( "F2", NumberFormatInfo.InvariantInfo); string strColWidth2 = (200.0f / (float)nEquiCols).ToString( "F2", NumberFormatInfo.InvariantInfo); string strHTdInit = ""; string strDataTdInit = ""; p.CellInit = strDataTdInit + p.FontInit; p.CellExit = p.FontExit + strDataTdExit; StringBuilder sbH = new StringBuilder(); sbH.AppendLine(); sbH.Append(""); if(bGroup) sbH.AppendLine(strHTdInit + h(KPRes.Group) + strHTdExit); if(bTitle) sbH.AppendLine(strHTdInit + h(KPRes.Title) + strHTdExit); if(bUserName) sbH.AppendLine(strHTdInit + h(KPRes.UserName) + strHTdExit); if(bPassword) sbH.AppendLine(strHTdInit + h(KPRes.Password) + strHTdExit); if(bUrl) sbH.AppendLine(strHTdInit + h(KPRes.Url) + strHTdExit); if(bNotes) sbH.AppendLine(strHTdInit2 + h(KPRes.Notes) + strHTdExit); if(bCreation) sbH.AppendLine(strHTdInit + h(KPRes.CreationTime) + strHTdExit); // if(bLastAcc) sbH.AppendLine(strHTdInit + h(KPRes.LastAccessTime) + strHTdExit); if(bLastMod) sbH.AppendLine(strHTdInit + h(KPRes.LastModificationTime) + strHTdExit); if(bExpire) sbH.AppendLine(strHTdInit + h(KPRes.ExpiryTime) + strHTdExit); if(bTags) sbH.AppendLine(strHTdInit + h(KPRes.Tags) + strHTdExit); if(bUuid) sbH.AppendLine(strHTdInit + h(KPRes.Uuid) + strHTdExit); sbH.Append(""); // No terminating \r\n strTableInit += sbH.ToString(); sb.AppendLine(strTableInit); eh = delegate(PwEntry pe) { ehInit(pe); sb.AppendLine(""); WriteTabularIf(bGroup, sb, c(pe.ParentGroup.Name), p); WriteTabularIf(bTitle, sb, pe, PwDefs.TitleField, p); WriteTabularIf(bUserName, sb, pe, PwDefs.UserNameField, p); if(bPassword) { if(p.MonoPasswords) sb.Append(strDataTdInit + (p.SmallMono ? "" : "")); else sb.Append(p.CellInit); string strInner = cs(pe.Strings.ReadSafe(PwDefs.PasswordField)); if(strInner.Length == 0) strInner = " "; sb.Append(strInner); if(p.MonoPasswords) sb.AppendLine((p.SmallMono ? "" : "") + strDataTdExit); else sb.AppendLine(p.CellExit); } // WriteTabularIf(bUrl, sb, pe, PwDefs.UrlField, p); WriteTabularIf(bUrl, sb, MakeUrlLink(pe.Strings.ReadSafe( PwDefs.UrlField), p), p); WriteTabularIf(bNotes, sb, pe, PwDefs.NotesField, p); WriteTabularIf(bCreation, sb, h(TimeUtil.ToDisplayString( pe.CreationTime)), p); // WriteTabularIf(bLastAcc, sb, h(TimeUtil.ToDisplayString( // pe.LastAccessTime)), p); WriteTabularIf(bLastMod, sb, h(TimeUtil.ToDisplayString( pe.LastModificationTime)), p); WriteTabularIf(bExpire, sb, h(pe.Expires ? TimeUtil.ToDisplayString( pe.ExpiryTime) : KPRes.NeverExpires), p); WriteTabularIf(bTags, sb, h(StrUtil.TagsToString(pe.Tags, true)), p); WriteTabularIf(bUuid, sb, pe.Uuid.ToHexString(), p); sb.AppendLine(""); return true; }; } else if(m_rbDetails.Checked) { sb.AppendLine(strTableInit); if(pgDataSource.Entries.UCount == 0) sb.AppendLine(@""); eh = delegate(PwEntry pe) { ehInit(pe); if((pgLast != null) && (pgLast == pe.ParentGroup)) sb.AppendLine(""); if(bGroup) WriteDetailsLine(sb, KPRes.Group, pe.ParentGroup.Name, p); if(bTitle) { PfOptions pSub = p.CloneShallow(); pSub.FontInit = MakeIconImg(pe.IconId, pe.CustomIconUuid, p) + pSub.FontInit + ""; pSub.FontExit = "" + pSub.FontExit; WriteDetailsLine(sb, KPRes.Title, pe.Strings.ReadSafe( PwDefs.TitleField), pSub); } if(bUserName) WriteDetailsLine(sb, KPRes.UserName, pe.Strings.ReadSafe( PwDefs.UserNameField), p); if(bPassword) WriteDetailsLine(sb, KPRes.Password, pe.Strings.ReadSafe( PwDefs.PasswordField), p); if(bUrl) WriteDetailsLine(sb, KPRes.Url, pe.Strings.ReadSafe( PwDefs.UrlField), p); if(bNotes) WriteDetailsLine(sb, KPRes.Notes, pe.Strings.ReadSafe( PwDefs.NotesField), p); if(bCreation) WriteDetailsLine(sb, KPRes.CreationTime, TimeUtil.ToDisplayString( pe.CreationTime), p); // if(bLastAcc) WriteDetailsLine(sb, KPRes.LastAccessTime, TimeUtil.ToDisplayString( // pe.LastAccessTime), p); if(bLastMod) WriteDetailsLine(sb, KPRes.LastModificationTime, TimeUtil.ToDisplayString( pe.LastModificationTime), p); if(bExpire) WriteDetailsLine(sb, KPRes.ExpiryTime, (pe.Expires ? TimeUtil.ToDisplayString( pe.ExpiryTime) : KPRes.NeverExpires), p); if(bAutoType) { foreach(AutoTypeAssociation a in pe.AutoType.Associations) WriteDetailsLine(sb, KPRes.AutoType, a.WindowName + ": " + a.Sequence, p); } if(bTags) WriteDetailsLine(sb, KPRes.Tags, StrUtil.TagsToString( pe.Tags, true), p); if(bUuid) WriteDetailsLine(sb, KPRes.Uuid, pe.Uuid.ToHexString(), p); foreach(KeyValuePair kvp in pe.Strings) { if(bCustomStrings && !PwDefs.IsStandardField(kvp.Key)) WriteDetailsLine(sb, kvp, p); } pgLast = pe.ParentGroup; return true; }; } else { Debug.Assert(false); } GroupHandler gh = delegate(PwGroup pg) { if(pg.Entries.UCount == 0) return true; sb.Append("
"; string strHTdInit2 = ""; string strHTdExit = ""; string strDataTdExit = "
 



"); // "

" // sb.Append(MakeIconImg(pg.IconId, pg.CustomIconUuid, p)); sb.Append(h(pg.GetFullPath(" - ", false))); sb.AppendLine("

"); WriteGroupNotes(sb, pg); sb.AppendLine(strTableInit); return true; }; pgDataSource.TraverseTree(TraversalMethod.PreOrder, gh, eh); if(m_rbTabular.Checked) sb.AppendLine(""); else if(m_rbDetails.Checked) sb.AppendLine("
"); sb.AppendLine(""); try { UIUtil.SetWebBrowserDocument(m_wbMain, sb.ToString()); } catch(Exception) { Debug.Assert(NativeLib.IsUnix()); } // Throws in Mono 2.0+ try { m_wbMain.AllowNavigation = false; } catch(Exception) { Debug.Assert(false); } if(!bInitial) UIBlockInteraction(false); m_bBlockPreviewRefresh = false; } private static string CompileText(string strText, PfOptions p, bool bToHtml, bool bNbsp) { string str = strText; if(g_strCodeItS == null) { g_strCodeItS = (new PwUuid(true)).ToHexString(); g_strCodeItE = (new PwUuid(true)).ToHexString(); } if((p.SprMode != 0) && (p.SprContext != null)) { string strPre = str; str = SprEngine.Compile(str, p.SprContext); if((p.SprMode == 2) && (str != strPre)) { if(bToHtml) str += " - " + g_strCodeItS + strPre + g_strCodeItE; else str += " - " + strPre; } } if(bToHtml) str = StrUtil.StringToHtml(str, bNbsp); str = str.Replace(g_strCodeItS, ""); str = str.Replace(g_strCodeItE, ""); return str; } private static void WriteTabularIf(bool bCondition, StringBuilder sb, PwEntry pe, string strField, PfOptions p) { if(!bCondition) return; string str = CompileText(pe.Strings.ReadSafe(strField), p, true, false); if(strField == PwDefs.TitleField) str = MakeIconImg(pe.IconId, pe.CustomIconUuid, p) + str; WriteTabularIf(bCondition, sb, str, p); } private static void WriteTabularIf(bool bCondition, StringBuilder sb, string strValue, PfOptions p) { if(!bCondition) return; sb.Append(p.CellInit); if(strValue.Length > 0) sb.Append(strValue); // Don't HTML-encode else sb.Append(@" "); sb.AppendLine(p.CellExit); } private static void WriteDetailsLine(StringBuilder sb, KeyValuePair kvp, PfOptions p) { sb.Append(""); sb.Append(StrUtil.StringToHtml(kvp.Key)); sb.AppendLine(":"); sb.Append(""); bool bPassword = (kvp.Key == PwDefs.PasswordField); bool bCode = (p.MonoPasswords && bPassword); if(bCode) sb.Append(p.SmallMono ? "" : ""); else sb.Append(p.FontInit); if((kvp.Key == PwDefs.UrlField) && !kvp.Value.IsEmpty) sb.Append(MakeUrlLink(kvp.Value.ReadString(), p)); else { string strInner = CompileText(kvp.Value.ReadString(), p, true, bPassword); if(strInner.Length == 0) strInner = " "; sb.Append(strInner); } if(bCode) sb.Append(p.SmallMono ? "" : ""); else sb.Append(p.FontExit); sb.AppendLine(""); } private static void WriteDetailsLine(StringBuilder sb, string strIndex, string strValue, PfOptions p) { if(string.IsNullOrEmpty(strValue)) return; KeyValuePair kvp = new KeyValuePair( strIndex, new ProtectedString(false, strValue)); WriteDetailsLine(sb, kvp, p); } private static string MakeIconImg(PwIcon i, PwUuid ci, PfOptions p) { if(p.ClientIcons == null) return string.Empty; Image img = null; PwDatabase pd = p.Database; if((ci != null) && !ci.Equals(PwUuid.Zero) && (pd != null)) { int cix = pd.GetCustomIconIndex(ci); if(cix >= 0) { cix += (int)PwIcon.Count; if(cix < p.ClientIcons.Images.Count) img = p.ClientIcons.Images[cix]; else { Debug.Assert(false); } } else { Debug.Assert(false); } } int ix = (int)i; if((img == null) && (ix >= 0) && (ix < p.ClientIcons.Images.Count)) img = p.ClientIcons.Images[ix]; string strData = GfxUtil.ImageToDataUri(img); if(string.IsNullOrEmpty(strData)) { Debug.Assert(false); return string.Empty; } StringBuilder sb = new StringBuilder(); sb.Append("\"\" "); return sb.ToString(); } private static string MakeUrlLink(string strRawUrl, PfOptions p) { if(string.IsNullOrEmpty(strRawUrl)) return string.Empty; string strCmp = CompileText(strRawUrl, p, true, false); string strHRef = strCmp; if(p.SprMode == 2) // Use only Spr-compiled URL for HRef, not both { PfOptions pSub = p.CloneShallow(); pSub.SprMode = 1; strHRef = CompileText(strRawUrl, pSub, true, false); } // Do not Spr-compile URL for HRef when p.SprMode == 0, because // this could unexpectedly disclose external data return ("
" + p.FontInit + strCmp + p.FontExit + ""); } private static void WriteGroupNotes(StringBuilder sb, PwGroup pg) { string str = pg.Notes.Trim(); if(str.Length == 0) return; // No

...

due to padding/margin sb.AppendLine("
" + StrUtil.StringToHtml(str) + "

"); } private static void SortGroupEntriesRecursive(PwGroup pg, string strFieldName) { PwEntryComparer cmp = new PwEntryComparer(strFieldName, true, true); pg.Entries.Sort(cmp); foreach(PwGroup pgSub in pg.Groups) { SortGroupEntriesRecursive(pgSub, strFieldName); } } private void OnBtnConfigPage(object sender, EventArgs e) { UpdateHtmlDocument(false); try { m_wbMain.ShowPageSetupDialog(); } // Throws in Mono 1.2.6+ catch(NotImplementedException) { MessageService.ShowWarning(KLRes.FrameworkNotImplExcp); } catch(Exception ex) { MessageService.ShowWarning(ex); } } private void OnBtnPrintPreview(object sender, EventArgs e) { UpdateHtmlDocument(false); try { m_wbMain.ShowPrintPreviewDialog(); } // Throws in Mono 1.2.6+ catch(NotImplementedException) { MessageService.ShowWarning(KLRes.FrameworkNotImplExcp); } catch(Exception ex) { MessageService.ShowWarning(ex); } } private void OnTabSelectedIndexChanged(object sender, EventArgs e) { if(m_tabMain.SelectedIndex == 0) UpdateHtmlDocument(false); } private void OnTabularCheckedChanged(object sender, EventArgs e) { UpdateUIState(); } private CheckBox[] GetAllFields() { return new CheckBox[] { m_cbTitle, m_cbUser, m_cbPassword, m_cbUrl, m_cbNotes, m_cbCreation, m_cbLastMod, m_cbExpire, // m_cbLastAccess m_cbAutoType, m_cbTags, m_cbIcon, m_cbCustomStrings, m_cbGroups, m_cbUuid }; } private void OnLinkSelectAllFields(object sender, LinkLabelLinkClickedEventArgs e) { foreach(CheckBox cb in GetAllFields()) { cb.Checked = true; } UpdateUIState(); } private void OnLinkDeselectAllFields(object sender, LinkLabelLinkClickedEventArgs e) { foreach(CheckBox cb in GetAllFields()) { cb.Checked = false; } UpdateUIState(); } private void OnFormClosed(object sender, FormClosedEventArgs e) { if(m_ilTabIcons != null) { m_tabMain.ImageList = null; m_ilTabIcons.Dispose(); m_ilTabIcons = null; } else { Debug.Assert(false); } GlobalWindowManager.RemoveWindow(this); } private void OnFormClosing(object sender, FormClosingEventArgs e) { if(m_bBlockPreviewRefresh) e.Cancel = true; } private void OnIconCheckedChanged(object sender, EventArgs e) { UpdateUIState(); } } } KeePass/Forms/SingleLineEditForm.resx0000664000000000000000000001326612501532346016576 0ustar rootroot text/microsoft-resx 2.0 System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 KeePass/Forms/KeyCreationForm.Designer.cs0000664000000000000000000005031213122740232017323 0ustar rootrootnamespace KeePass.Forms { partial class KeyCreationForm { /// /// Erforderliche Designervariable. /// private System.ComponentModel.IContainer components = null; /// /// Verwendete Ressourcen bereinigen. /// /// True, wenn verwaltete Ressourcen gelöscht werden sollen; andernfalls False. protected override void Dispose(bool disposing) { if(disposing && (components != null)) { components.Dispose(); } base.Dispose(disposing); } #region Vom Windows Form-Designer generierter Code /// /// Erforderliche Methode für die Designerunterstützung. /// Der Inhalt der Methode darf nicht mit dem Code-Editor geändert werden. /// private void InitializeComponent() { this.components = new System.ComponentModel.Container(); System.ComponentModel.ComponentResourceManager resources = new System.ComponentModel.ComponentResourceManager(typeof(KeyCreationForm)); this.m_lblIntro = new System.Windows.Forms.Label(); this.m_lblMultiInfo = new System.Windows.Forms.Label(); this.m_cbPassword = new System.Windows.Forms.CheckBox(); this.m_tbPassword = new System.Windows.Forms.TextBox(); this.m_lblRepeatPassword = new System.Windows.Forms.Label(); this.m_tbRepeatPassword = new System.Windows.Forms.TextBox(); this.m_cbKeyFile = new System.Windows.Forms.CheckBox(); this.m_cbUserAccount = new System.Windows.Forms.CheckBox(); this.m_lblWindowsAccDesc = new System.Windows.Forms.Label(); this.m_btnCancel = new System.Windows.Forms.Button(); this.m_btnCreate = new System.Windows.Forms.Button(); this.m_ttRect = new System.Windows.Forms.ToolTip(this.components); this.m_cbHidePassword = new System.Windows.Forms.CheckBox(); this.m_btnSaveKeyFile = new System.Windows.Forms.Button(); this.m_btnOpenKeyFile = new System.Windows.Forms.Button(); this.m_btnHelp = new System.Windows.Forms.Button(); this.m_lblSeparator = new System.Windows.Forms.Label(); this.m_lblEstimatedQuality = new System.Windows.Forms.Label(); this.m_lblQualityInfo = new System.Windows.Forms.Label(); this.m_bannerImage = new System.Windows.Forms.PictureBox(); this.m_cmbKeyFile = new System.Windows.Forms.ComboBox(); this.m_lblWindowsAccDesc2 = new System.Windows.Forms.Label(); this.m_picAccWarning = new System.Windows.Forms.PictureBox(); this.m_cbExpert = new System.Windows.Forms.CheckBox(); this.m_picKeyFileWarning = new System.Windows.Forms.PictureBox(); this.m_lblKeyFileWarning = new System.Windows.Forms.Label(); this.m_lnkKeyFile = new System.Windows.Forms.LinkLabel(); this.m_lnkUserAccount = new System.Windows.Forms.LinkLabel(); this.m_pbPasswordQuality = new KeePass.UI.QualityProgressBar(); this.m_lblKeyFileInfo = new System.Windows.Forms.Label(); ((System.ComponentModel.ISupportInitialize)(this.m_bannerImage)).BeginInit(); ((System.ComponentModel.ISupportInitialize)(this.m_picAccWarning)).BeginInit(); ((System.ComponentModel.ISupportInitialize)(this.m_picKeyFileWarning)).BeginInit(); this.SuspendLayout(); // // m_lblIntro // this.m_lblIntro.Location = new System.Drawing.Point(9, 72); this.m_lblIntro.Name = "m_lblIntro"; this.m_lblIntro.Size = new System.Drawing.Size(498, 13); this.m_lblIntro.TabIndex = 22; this.m_lblIntro.Text = "Specify the composite master key, which will be used to encrypt the database."; // // m_lblMultiInfo // this.m_lblMultiInfo.Location = new System.Drawing.Point(9, 93); this.m_lblMultiInfo.Name = "m_lblMultiInfo"; this.m_lblMultiInfo.Size = new System.Drawing.Size(498, 42); this.m_lblMultiInfo.TabIndex = 23; this.m_lblMultiInfo.Text = resources.GetString("m_lblMultiInfo.Text"); // // m_cbPassword // this.m_cbPassword.AutoSize = true; this.m_cbPassword.Location = new System.Drawing.Point(12, 147); this.m_cbPassword.Name = "m_cbPassword"; this.m_cbPassword.Size = new System.Drawing.Size(109, 17); this.m_cbPassword.TabIndex = 24; this.m_cbPassword.Text = "Master &password:"; this.m_cbPassword.UseVisualStyleBackColor = true; this.m_cbPassword.CheckedChanged += new System.EventHandler(this.OnCheckedPassword); // // m_tbPassword // this.m_tbPassword.Location = new System.Drawing.Point(150, 145); this.m_tbPassword.Name = "m_tbPassword"; this.m_tbPassword.Size = new System.Drawing.Size(319, 20); this.m_tbPassword.TabIndex = 0; this.m_tbPassword.UseSystemPasswordChar = true; // // m_lblRepeatPassword // this.m_lblRepeatPassword.AutoSize = true; this.m_lblRepeatPassword.Location = new System.Drawing.Point(28, 174); this.m_lblRepeatPassword.Name = "m_lblRepeatPassword"; this.m_lblRepeatPassword.Size = new System.Drawing.Size(93, 13); this.m_lblRepeatPassword.TabIndex = 2; this.m_lblRepeatPassword.Text = "Repeat password:"; // // m_tbRepeatPassword // this.m_tbRepeatPassword.Location = new System.Drawing.Point(150, 171); this.m_tbRepeatPassword.Name = "m_tbRepeatPassword"; this.m_tbRepeatPassword.Size = new System.Drawing.Size(319, 20); this.m_tbRepeatPassword.TabIndex = 3; this.m_tbRepeatPassword.UseSystemPasswordChar = true; // // m_cbKeyFile // this.m_cbKeyFile.AutoSize = true; this.m_cbKeyFile.Location = new System.Drawing.Point(12, 249); this.m_cbKeyFile.Name = "m_cbKeyFile"; this.m_cbKeyFile.Size = new System.Drawing.Size(112, 17); this.m_cbKeyFile.TabIndex = 8; this.m_cbKeyFile.Text = "&Key file / provider:"; this.m_cbKeyFile.UseVisualStyleBackColor = true; this.m_cbKeyFile.CheckedChanged += new System.EventHandler(this.OnCheckedKeyFile); // // m_cbUserAccount // this.m_cbUserAccount.AutoSize = true; this.m_cbUserAccount.Location = new System.Drawing.Point(12, 391); this.m_cbUserAccount.Name = "m_cbUserAccount"; this.m_cbUserAccount.Size = new System.Drawing.Size(135, 17); this.m_cbUserAccount.TabIndex = 14; this.m_cbUserAccount.Text = "Windows &user account"; this.m_cbUserAccount.UseVisualStyleBackColor = true; this.m_cbUserAccount.CheckedChanged += new System.EventHandler(this.OnWinUserCheckedChanged); // // m_lblWindowsAccDesc // this.m_lblWindowsAccDesc.Location = new System.Drawing.Point(28, 411); this.m_lblWindowsAccDesc.Name = "m_lblWindowsAccDesc"; this.m_lblWindowsAccDesc.Size = new System.Drawing.Size(479, 27); this.m_lblWindowsAccDesc.TabIndex = 15; this.m_lblWindowsAccDesc.Text = "This source uses data of the current Windows user account. This data does not cha" + "nge when the account password changes."; // // m_btnCancel // this.m_btnCancel.DialogResult = System.Windows.Forms.DialogResult.Cancel; this.m_btnCancel.Location = new System.Drawing.Point(432, 542); this.m_btnCancel.Name = "m_btnCancel"; this.m_btnCancel.Size = new System.Drawing.Size(75, 23); this.m_btnCancel.TabIndex = 20; this.m_btnCancel.Text = "Cancel"; this.m_btnCancel.TextImageRelation = System.Windows.Forms.TextImageRelation.ImageBeforeText; this.m_btnCancel.UseVisualStyleBackColor = true; this.m_btnCancel.Click += new System.EventHandler(this.OnBtnCancel); // // m_btnCreate // this.m_btnCreate.DialogResult = System.Windows.Forms.DialogResult.OK; this.m_btnCreate.Location = new System.Drawing.Point(351, 542); this.m_btnCreate.Name = "m_btnCreate"; this.m_btnCreate.Size = new System.Drawing.Size(75, 23); this.m_btnCreate.TabIndex = 19; this.m_btnCreate.Text = "OK"; this.m_btnCreate.TextImageRelation = System.Windows.Forms.TextImageRelation.ImageBeforeText; this.m_btnCreate.UseVisualStyleBackColor = true; this.m_btnCreate.Click += new System.EventHandler(this.OnBtnOK); // // m_cbHidePassword // this.m_cbHidePassword.Appearance = System.Windows.Forms.Appearance.Button; this.m_cbHidePassword.Location = new System.Drawing.Point(475, 143); this.m_cbHidePassword.Name = "m_cbHidePassword"; this.m_cbHidePassword.Size = new System.Drawing.Size(32, 23); this.m_cbHidePassword.TabIndex = 1; this.m_cbHidePassword.Text = "***"; this.m_cbHidePassword.TextAlign = System.Drawing.ContentAlignment.MiddleCenter; this.m_cbHidePassword.UseVisualStyleBackColor = true; // // m_btnSaveKeyFile // this.m_btnSaveKeyFile.Image = global::KeePass.Properties.Resources.B15x14_FileNew; this.m_btnSaveKeyFile.Location = new System.Drawing.Point(341, 273); this.m_btnSaveKeyFile.Name = "m_btnSaveKeyFile"; this.m_btnSaveKeyFile.Size = new System.Drawing.Size(80, 23); this.m_btnSaveKeyFile.TabIndex = 10; this.m_btnSaveKeyFile.Text = " &Create..."; this.m_btnSaveKeyFile.TextImageRelation = System.Windows.Forms.TextImageRelation.ImageBeforeText; this.m_btnSaveKeyFile.UseVisualStyleBackColor = true; this.m_btnSaveKeyFile.Click += new System.EventHandler(this.OnClickKeyFileCreate); // // m_btnOpenKeyFile // this.m_btnOpenKeyFile.Image = global::KeePass.Properties.Resources.B16x16_Folder_Blue_Open; this.m_btnOpenKeyFile.Location = new System.Drawing.Point(427, 273); this.m_btnOpenKeyFile.Name = "m_btnOpenKeyFile"; this.m_btnOpenKeyFile.Size = new System.Drawing.Size(80, 23); this.m_btnOpenKeyFile.TabIndex = 11; this.m_btnOpenKeyFile.Text = " &Browse..."; this.m_btnOpenKeyFile.TextImageRelation = System.Windows.Forms.TextImageRelation.ImageBeforeText; this.m_btnOpenKeyFile.UseVisualStyleBackColor = true; this.m_btnOpenKeyFile.Click += new System.EventHandler(this.OnClickKeyFileBrowse); // // m_btnHelp // this.m_btnHelp.Location = new System.Drawing.Point(12, 542); this.m_btnHelp.Name = "m_btnHelp"; this.m_btnHelp.Size = new System.Drawing.Size(75, 23); this.m_btnHelp.TabIndex = 21; this.m_btnHelp.Text = "&Help"; this.m_btnHelp.UseVisualStyleBackColor = true; this.m_btnHelp.Click += new System.EventHandler(this.OnBtnHelp); // // m_lblSeparator // this.m_lblSeparator.BorderStyle = System.Windows.Forms.BorderStyle.Fixed3D; this.m_lblSeparator.Location = new System.Drawing.Point(0, 531); this.m_lblSeparator.Name = "m_lblSeparator"; this.m_lblSeparator.Size = new System.Drawing.Size(519, 2); this.m_lblSeparator.TabIndex = 18; // // m_lblEstimatedQuality // this.m_lblEstimatedQuality.AutoSize = true; this.m_lblEstimatedQuality.Location = new System.Drawing.Point(28, 198); this.m_lblEstimatedQuality.Name = "m_lblEstimatedQuality"; this.m_lblEstimatedQuality.Size = new System.Drawing.Size(89, 13); this.m_lblEstimatedQuality.TabIndex = 4; this.m_lblEstimatedQuality.Text = "Estimated quality:"; // // m_lblQualityInfo // this.m_lblQualityInfo.Location = new System.Drawing.Point(422, 198); this.m_lblQualityInfo.Name = "m_lblQualityInfo"; this.m_lblQualityInfo.Size = new System.Drawing.Size(50, 13); this.m_lblQualityInfo.TabIndex = 6; this.m_lblQualityInfo.Text = "0 ch."; this.m_lblQualityInfo.TextAlign = System.Drawing.ContentAlignment.MiddleRight; // // m_bannerImage // this.m_bannerImage.Dock = System.Windows.Forms.DockStyle.Top; this.m_bannerImage.Location = new System.Drawing.Point(0, 0); this.m_bannerImage.Name = "m_bannerImage"; this.m_bannerImage.Size = new System.Drawing.Size(519, 60); this.m_bannerImage.TabIndex = 15; this.m_bannerImage.TabStop = false; // // m_cmbKeyFile // this.m_cmbKeyFile.DropDownStyle = System.Windows.Forms.ComboBoxStyle.DropDownList; this.m_cmbKeyFile.FormattingEnabled = true; this.m_cmbKeyFile.Location = new System.Drawing.Point(150, 246); this.m_cmbKeyFile.MaxDropDownItems = 16; this.m_cmbKeyFile.Name = "m_cmbKeyFile"; this.m_cmbKeyFile.Size = new System.Drawing.Size(356, 21); this.m_cmbKeyFile.TabIndex = 9; this.m_cmbKeyFile.SelectedIndexChanged += new System.EventHandler(this.OnKeyFileSelectedIndexChanged); // // m_lblWindowsAccDesc2 // this.m_lblWindowsAccDesc2.Location = new System.Drawing.Point(53, 446); this.m_lblWindowsAccDesc2.Name = "m_lblWindowsAccDesc2"; this.m_lblWindowsAccDesc2.Size = new System.Drawing.Size(454, 54); this.m_lblWindowsAccDesc2.TabIndex = 16; this.m_lblWindowsAccDesc2.Text = resources.GetString("m_lblWindowsAccDesc2.Text"); // // m_picAccWarning // this.m_picAccWarning.Location = new System.Drawing.Point(31, 446); this.m_picAccWarning.Name = "m_picAccWarning"; this.m_picAccWarning.Size = new System.Drawing.Size(16, 16); this.m_picAccWarning.SizeMode = System.Windows.Forms.PictureBoxSizeMode.StretchImage; this.m_picAccWarning.TabIndex = 22; this.m_picAccWarning.TabStop = false; // // m_cbExpert // this.m_cbExpert.AutoSize = true; this.m_cbExpert.Location = new System.Drawing.Point(12, 223); this.m_cbExpert.Name = "m_cbExpert"; this.m_cbExpert.Size = new System.Drawing.Size(125, 17); this.m_cbExpert.TabIndex = 7; this.m_cbExpert.Text = "Show &expert options:"; this.m_cbExpert.UseVisualStyleBackColor = true; this.m_cbExpert.CheckedChanged += new System.EventHandler(this.OnExpertCheckedChanged); // // m_picKeyFileWarning // this.m_picKeyFileWarning.Location = new System.Drawing.Point(31, 334); this.m_picKeyFileWarning.Name = "m_picKeyFileWarning"; this.m_picKeyFileWarning.Size = new System.Drawing.Size(16, 16); this.m_picKeyFileWarning.SizeMode = System.Windows.Forms.PictureBoxSizeMode.StretchImage; this.m_picKeyFileWarning.TabIndex = 24; this.m_picKeyFileWarning.TabStop = false; // // m_lblKeyFileWarning // this.m_lblKeyFileWarning.Location = new System.Drawing.Point(53, 334); this.m_lblKeyFileWarning.Name = "m_lblKeyFileWarning"; this.m_lblKeyFileWarning.Size = new System.Drawing.Size(454, 28); this.m_lblKeyFileWarning.TabIndex = 12; this.m_lblKeyFileWarning.Text = "If the key file is lost or its contents are changed, the database cannot be opene" + "d anymore. You should create a backup of the key file."; // // m_lnkKeyFile // this.m_lnkKeyFile.AutoSize = true; this.m_lnkKeyFile.Location = new System.Drawing.Point(53, 366); this.m_lnkKeyFile.Name = "m_lnkKeyFile"; this.m_lnkKeyFile.Size = new System.Drawing.Size(159, 13); this.m_lnkKeyFile.TabIndex = 13; this.m_lnkKeyFile.TabStop = true; this.m_lnkKeyFile.Text = "More information about key files."; this.m_lnkKeyFile.LinkClicked += new System.Windows.Forms.LinkLabelLinkClickedEventHandler(this.OnKeyFileLinkClicked); // // m_lnkUserAccount // this.m_lnkUserAccount.AutoSize = true; this.m_lnkUserAccount.Location = new System.Drawing.Point(53, 504); this.m_lnkUserAccount.Name = "m_lnkUserAccount"; this.m_lnkUserAccount.Size = new System.Drawing.Size(235, 13); this.m_lnkUserAccount.TabIndex = 17; this.m_lnkUserAccount.TabStop = true; this.m_lnkUserAccount.Text = "More information about Windows user accounts."; this.m_lnkUserAccount.LinkClicked += new System.Windows.Forms.LinkLabelLinkClickedEventHandler(this.OnUserAccountLinkClicked); // // m_pbPasswordQuality // this.m_pbPasswordQuality.Location = new System.Drawing.Point(150, 197); this.m_pbPasswordQuality.Name = "m_pbPasswordQuality"; this.m_pbPasswordQuality.Size = new System.Drawing.Size(269, 16); this.m_pbPasswordQuality.TabIndex = 5; this.m_pbPasswordQuality.TabStop = false; // // m_lblKeyFileInfo // this.m_lblKeyFileInfo.Location = new System.Drawing.Point(28, 299); this.m_lblKeyFileInfo.Name = "m_lblKeyFileInfo"; this.m_lblKeyFileInfo.Size = new System.Drawing.Size(479, 27); this.m_lblKeyFileInfo.TabIndex = 25; this.m_lblKeyFileInfo.Text = "A key file can be used as part of the master key; it does not store any database " + "data. If an attacker has access to the key file, it does not provide any protect" + "ion."; // // KeyCreationForm // this.AcceptButton = this.m_btnCreate; this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F); this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; this.CancelButton = this.m_btnCancel; this.ClientSize = new System.Drawing.Size(519, 576); this.Controls.Add(this.m_lblKeyFileInfo); this.Controls.Add(this.m_lnkUserAccount); this.Controls.Add(this.m_lnkKeyFile); this.Controls.Add(this.m_lblKeyFileWarning); this.Controls.Add(this.m_picKeyFileWarning); this.Controls.Add(this.m_cbExpert); this.Controls.Add(this.m_picAccWarning); this.Controls.Add(this.m_lblWindowsAccDesc2); this.Controls.Add(this.m_cmbKeyFile); this.Controls.Add(this.m_lblQualityInfo); this.Controls.Add(this.m_lblEstimatedQuality); this.Controls.Add(this.m_pbPasswordQuality); this.Controls.Add(this.m_lblSeparator); this.Controls.Add(this.m_btnHelp); this.Controls.Add(this.m_lblWindowsAccDesc); this.Controls.Add(this.m_cbHidePassword); this.Controls.Add(this.m_bannerImage); this.Controls.Add(this.m_btnCancel); this.Controls.Add(this.m_btnCreate); this.Controls.Add(this.m_cbUserAccount); this.Controls.Add(this.m_btnSaveKeyFile); this.Controls.Add(this.m_btnOpenKeyFile); this.Controls.Add(this.m_cbKeyFile); this.Controls.Add(this.m_tbRepeatPassword); this.Controls.Add(this.m_lblRepeatPassword); this.Controls.Add(this.m_tbPassword); this.Controls.Add(this.m_cbPassword); this.Controls.Add(this.m_lblMultiInfo); this.Controls.Add(this.m_lblIntro); this.FormBorderStyle = System.Windows.Forms.FormBorderStyle.FixedDialog; this.MaximizeBox = false; this.MinimizeBox = false; this.Name = "KeyCreationForm"; this.ShowInTaskbar = false; this.SizeGripStyle = System.Windows.Forms.SizeGripStyle.Hide; this.StartPosition = System.Windows.Forms.FormStartPosition.CenterParent; this.Text = "<>"; this.Load += new System.EventHandler(this.OnFormLoad); this.Shown += new System.EventHandler(this.OnFormShown); this.FormClosed += new System.Windows.Forms.FormClosedEventHandler(this.OnFormClosed); this.FormClosing += new System.Windows.Forms.FormClosingEventHandler(this.OnFormClosing); ((System.ComponentModel.ISupportInitialize)(this.m_bannerImage)).EndInit(); ((System.ComponentModel.ISupportInitialize)(this.m_picAccWarning)).EndInit(); ((System.ComponentModel.ISupportInitialize)(this.m_picKeyFileWarning)).EndInit(); this.ResumeLayout(false); this.PerformLayout(); } #endregion private System.Windows.Forms.Label m_lblIntro; private System.Windows.Forms.Label m_lblMultiInfo; private System.Windows.Forms.CheckBox m_cbPassword; private System.Windows.Forms.TextBox m_tbPassword; private System.Windows.Forms.Label m_lblRepeatPassword; private System.Windows.Forms.TextBox m_tbRepeatPassword; private System.Windows.Forms.CheckBox m_cbKeyFile; private System.Windows.Forms.Button m_btnOpenKeyFile; private System.Windows.Forms.Button m_btnSaveKeyFile; private System.Windows.Forms.CheckBox m_cbUserAccount; private System.Windows.Forms.Button m_btnCreate; private System.Windows.Forms.Button m_btnCancel; private System.Windows.Forms.PictureBox m_bannerImage; private System.Windows.Forms.CheckBox m_cbHidePassword; private System.Windows.Forms.Label m_lblWindowsAccDesc; private System.Windows.Forms.ToolTip m_ttRect; private System.Windows.Forms.Button m_btnHelp; private System.Windows.Forms.Label m_lblSeparator; private KeePass.UI.QualityProgressBar m_pbPasswordQuality; private System.Windows.Forms.Label m_lblEstimatedQuality; private System.Windows.Forms.Label m_lblQualityInfo; private System.Windows.Forms.ComboBox m_cmbKeyFile; private System.Windows.Forms.Label m_lblWindowsAccDesc2; private System.Windows.Forms.PictureBox m_picAccWarning; private System.Windows.Forms.CheckBox m_cbExpert; private System.Windows.Forms.PictureBox m_picKeyFileWarning; private System.Windows.Forms.Label m_lblKeyFileWarning; private System.Windows.Forms.LinkLabel m_lnkKeyFile; private System.Windows.Forms.LinkLabel m_lnkUserAccount; private System.Windows.Forms.Label m_lblKeyFileInfo; } }KeePass/Forms/KeyPromptForm.Designer.cs0000664000000000000000000002357012747422662017066 0ustar rootrootnamespace KeePass.Forms { partial class KeyPromptForm { /// /// Erforderliche Designervariable. /// private System.ComponentModel.IContainer components = null; /// /// Verwendete Ressourcen bereinigen. /// /// True, wenn verwaltete Ressourcen gelöscht werden sollen; andernfalls False. protected override void Dispose(bool disposing) { if(disposing && (components != null)) { components.Dispose(); } base.Dispose(disposing); } #region Vom Windows Form-Designer generierter Code /// /// Erforderliche Methode für die Designerunterstützung. /// Der Inhalt der Methode darf nicht mit dem Code-Editor geändert werden. /// private void InitializeComponent() { this.components = new System.ComponentModel.Container(); this.m_cbUserAccount = new System.Windows.Forms.CheckBox(); this.m_btnOpenKeyFile = new System.Windows.Forms.Button(); this.m_cbKeyFile = new System.Windows.Forms.CheckBox(); this.m_tbPassword = new System.Windows.Forms.TextBox(); this.m_cbPassword = new System.Windows.Forms.CheckBox(); this.m_btnOK = new System.Windows.Forms.Button(); this.m_btnCancel = new System.Windows.Forms.Button(); this.m_bannerImage = new System.Windows.Forms.PictureBox(); this.m_cbHidePassword = new System.Windows.Forms.CheckBox(); this.m_ttRect = new System.Windows.Forms.ToolTip(this.components); this.m_btnHelp = new System.Windows.Forms.Button(); this.m_lblSeparator = new System.Windows.Forms.Label(); this.m_cmbKeyFile = new System.Windows.Forms.ComboBox(); this.m_btnExit = new System.Windows.Forms.Button(); ((System.ComponentModel.ISupportInitialize)(this.m_bannerImage)).BeginInit(); this.SuspendLayout(); // // m_cbUserAccount // this.m_cbUserAccount.AutoSize = true; this.m_cbUserAccount.Location = new System.Drawing.Point(12, 125); this.m_cbUserAccount.Name = "m_cbUserAccount"; this.m_cbUserAccount.Size = new System.Drawing.Size(138, 17); this.m_cbUserAccount.TabIndex = 5; this.m_cbUserAccount.Text = "Windows &User Account"; this.m_cbUserAccount.UseVisualStyleBackColor = true; // // m_btnOpenKeyFile // this.m_btnOpenKeyFile.Image = global::KeePass.Properties.Resources.B16x16_Folder_Blue_Open; this.m_btnOpenKeyFile.Location = new System.Drawing.Point(373, 97); this.m_btnOpenKeyFile.Name = "m_btnOpenKeyFile"; this.m_btnOpenKeyFile.Size = new System.Drawing.Size(32, 23); this.m_btnOpenKeyFile.TabIndex = 4; this.m_btnOpenKeyFile.UseVisualStyleBackColor = true; this.m_btnOpenKeyFile.Click += new System.EventHandler(this.OnClickKeyFileBrowse); // // m_cbKeyFile // this.m_cbKeyFile.AutoSize = true; this.m_cbKeyFile.Location = new System.Drawing.Point(12, 100); this.m_cbKeyFile.Name = "m_cbKeyFile"; this.m_cbKeyFile.Size = new System.Drawing.Size(66, 17); this.m_cbKeyFile.TabIndex = 2; this.m_cbKeyFile.Text = "&Key File:"; this.m_cbKeyFile.UseVisualStyleBackColor = true; this.m_cbKeyFile.CheckedChanged += new System.EventHandler(this.OnCheckedKeyFile); // // m_tbPassword // this.m_tbPassword.Location = new System.Drawing.Point(144, 74); this.m_tbPassword.Name = "m_tbPassword"; this.m_tbPassword.Size = new System.Drawing.Size(223, 20); this.m_tbPassword.TabIndex = 0; this.m_tbPassword.UseSystemPasswordChar = true; // // m_cbPassword // this.m_cbPassword.AutoSize = true; this.m_cbPassword.Location = new System.Drawing.Point(12, 75); this.m_cbPassword.Name = "m_cbPassword"; this.m_cbPassword.Size = new System.Drawing.Size(110, 17); this.m_cbPassword.TabIndex = 10; this.m_cbPassword.Text = "Master &Password:"; this.m_cbPassword.UseVisualStyleBackColor = true; this.m_cbPassword.CheckedChanged += new System.EventHandler(this.OnCheckedPassword); // // m_btnOK // this.m_btnOK.DialogResult = System.Windows.Forms.DialogResult.OK; this.m_btnOK.Location = new System.Drawing.Point(249, 177); this.m_btnOK.Name = "m_btnOK"; this.m_btnOK.Size = new System.Drawing.Size(75, 23); this.m_btnOK.TabIndex = 6; this.m_btnOK.Text = "OK"; this.m_btnOK.UseVisualStyleBackColor = true; this.m_btnOK.Click += new System.EventHandler(this.OnBtnOK); // // m_btnCancel // this.m_btnCancel.DialogResult = System.Windows.Forms.DialogResult.Cancel; this.m_btnCancel.Location = new System.Drawing.Point(330, 177); this.m_btnCancel.Name = "m_btnCancel"; this.m_btnCancel.Size = new System.Drawing.Size(75, 23); this.m_btnCancel.TabIndex = 7; this.m_btnCancel.Text = "Cancel"; this.m_btnCancel.UseVisualStyleBackColor = true; this.m_btnCancel.Click += new System.EventHandler(this.OnBtnCancel); // // m_bannerImage // this.m_bannerImage.Dock = System.Windows.Forms.DockStyle.Top; this.m_bannerImage.Location = new System.Drawing.Point(0, 0); this.m_bannerImage.Name = "m_bannerImage"; this.m_bannerImage.Size = new System.Drawing.Size(417, 60); this.m_bannerImage.TabIndex = 24; this.m_bannerImage.TabStop = false; // // m_cbHidePassword // this.m_cbHidePassword.Appearance = System.Windows.Forms.Appearance.Button; this.m_cbHidePassword.Location = new System.Drawing.Point(373, 72); this.m_cbHidePassword.Name = "m_cbHidePassword"; this.m_cbHidePassword.Size = new System.Drawing.Size(32, 23); this.m_cbHidePassword.TabIndex = 1; this.m_cbHidePassword.Text = "***"; this.m_cbHidePassword.TextAlign = System.Drawing.ContentAlignment.MiddleCenter; this.m_cbHidePassword.UseVisualStyleBackColor = true; this.m_cbHidePassword.CheckedChanged += new System.EventHandler(this.OnCheckedHidePassword); // // m_ttRect // this.m_ttRect.StripAmpersands = true; // // m_btnHelp // this.m_btnHelp.Location = new System.Drawing.Point(12, 177); this.m_btnHelp.Name = "m_btnHelp"; this.m_btnHelp.Size = new System.Drawing.Size(75, 23); this.m_btnHelp.TabIndex = 8; this.m_btnHelp.Text = "&Help"; this.m_btnHelp.UseVisualStyleBackColor = true; this.m_btnHelp.Click += new System.EventHandler(this.OnBtnHelp); // // m_lblSeparator // this.m_lblSeparator.BorderStyle = System.Windows.Forms.BorderStyle.Fixed3D; this.m_lblSeparator.Location = new System.Drawing.Point(0, 164); this.m_lblSeparator.Name = "m_lblSeparator"; this.m_lblSeparator.Size = new System.Drawing.Size(417, 2); this.m_lblSeparator.TabIndex = 9; // // m_cmbKeyFile // this.m_cmbKeyFile.DropDownStyle = System.Windows.Forms.ComboBoxStyle.DropDownList; this.m_cmbKeyFile.FormattingEnabled = true; this.m_cmbKeyFile.Location = new System.Drawing.Point(144, 98); this.m_cmbKeyFile.Name = "m_cmbKeyFile"; this.m_cmbKeyFile.Size = new System.Drawing.Size(223, 21); this.m_cmbKeyFile.TabIndex = 3; this.m_cmbKeyFile.SelectedIndexChanged += new System.EventHandler(this.OnKeyFileSelectedIndexChanged); // // m_btnExit // this.m_btnExit.DialogResult = System.Windows.Forms.DialogResult.Abort; this.m_btnExit.Location = new System.Drawing.Point(93, 177); this.m_btnExit.Name = "m_btnExit"; this.m_btnExit.Size = new System.Drawing.Size(75, 23); this.m_btnExit.TabIndex = 25; this.m_btnExit.Text = "E&xit"; this.m_btnExit.UseVisualStyleBackColor = true; this.m_btnExit.Click += new System.EventHandler(this.OnBtnExit); // // KeyPromptForm // this.AcceptButton = this.m_btnOK; this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F); this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; this.CancelButton = this.m_btnCancel; this.ClientSize = new System.Drawing.Size(417, 212); this.Controls.Add(this.m_btnExit); this.Controls.Add(this.m_cmbKeyFile); this.Controls.Add(this.m_lblSeparator); this.Controls.Add(this.m_btnHelp); this.Controls.Add(this.m_cbHidePassword); this.Controls.Add(this.m_bannerImage); this.Controls.Add(this.m_btnCancel); this.Controls.Add(this.m_btnOK); this.Controls.Add(this.m_cbUserAccount); this.Controls.Add(this.m_btnOpenKeyFile); this.Controls.Add(this.m_cbKeyFile); this.Controls.Add(this.m_tbPassword); this.Controls.Add(this.m_cbPassword); this.FormBorderStyle = System.Windows.Forms.FormBorderStyle.FixedDialog; this.MaximizeBox = false; this.MinimizeBox = false; this.Name = "KeyPromptForm"; this.SizeGripStyle = System.Windows.Forms.SizeGripStyle.Hide; this.StartPosition = System.Windows.Forms.FormStartPosition.CenterScreen; this.Text = "<>"; this.Load += new System.EventHandler(this.OnFormLoad); this.Shown += new System.EventHandler(this.OnFormShown); this.FormClosed += new System.Windows.Forms.FormClosedEventHandler(this.OnFormClosed); this.FormClosing += new System.Windows.Forms.FormClosingEventHandler(this.OnFormClosing); ((System.ComponentModel.ISupportInitialize)(this.m_bannerImage)).EndInit(); this.ResumeLayout(false); this.PerformLayout(); } #endregion private System.Windows.Forms.CheckBox m_cbUserAccount; private System.Windows.Forms.Button m_btnOpenKeyFile; private System.Windows.Forms.CheckBox m_cbKeyFile; private System.Windows.Forms.TextBox m_tbPassword; private System.Windows.Forms.CheckBox m_cbPassword; private System.Windows.Forms.Button m_btnOK; private System.Windows.Forms.Button m_btnCancel; private System.Windows.Forms.PictureBox m_bannerImage; private System.Windows.Forms.CheckBox m_cbHidePassword; private System.Windows.Forms.ToolTip m_ttRect; private System.Windows.Forms.Button m_btnHelp; private System.Windows.Forms.Label m_lblSeparator; private System.Windows.Forms.ComboBox m_cmbKeyFile; private System.Windows.Forms.Button m_btnExit; } }KeePass/Forms/EditAutoTypeItemForm.resx0000664000000000000000000001326612501530356017135 0ustar rootroot text/microsoft-resx 2.0 System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 KeePass/Forms/EcasConditionForm.cs0000664000000000000000000000646713222430410016100 0ustar rootroot/* KeePass Password Safe - The Open-Source Password Manager Copyright (C) 2003-2018 Dominik Reichl This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ using System; using System.Collections.Generic; using System.ComponentModel; using System.Diagnostics; using System.Drawing; using System.Text; using System.Windows.Forms; using KeePass.App; using KeePass.Ecas; using KeePass.Resources; using KeePass.UI; namespace KeePass.Forms { public partial class EcasConditionForm : Form { private EcasCondition m_conditionInOut = null; private EcasCondition m_condition = null; // Working copy private bool m_bBlockTypeSelectionHandler = false; public void InitEx(EcasCondition e) { m_conditionInOut = e; m_condition = e.CloneDeep(); } public EcasConditionForm() { InitializeComponent(); Program.Translation.ApplyTo(this); } private void OnFormLoad(object sender, EventArgs e) { GlobalWindowManager.AddWindow(this); this.Text = KPRes.Condition; this.Icon = AppIcons.Default; Debug.Assert(!m_lblParamHint.AutoSize); // For RTL support m_lblParamHint.Text = KPRes.ParamDescHelp; foreach(EcasConditionProvider cp in Program.EcasPool.ConditionProviders) { foreach(EcasConditionType t in cp.Conditions) m_cmbConditions.Items.Add(t.Name); } UpdateDataEx(m_condition, false, EcasTypeDxMode.Selection); m_cbNegate.Checked = m_condition.Negate; } private void OnFormClosed(object sender, FormClosedEventArgs e) { GlobalWindowManager.RemoveWindow(this); } private bool UpdateDataEx(EcasCondition c, bool bGuiToInternal, EcasTypeDxMode dxType) { m_bBlockTypeSelectionHandler = true; bool bResult = EcasUtil.UpdateDialog(EcasObjectType.Condition, m_cmbConditions, m_dgvParams, c, bGuiToInternal, dxType); m_bBlockTypeSelectionHandler = false; return bResult; } private void OnBtnOK(object sender, EventArgs e) { if(!UpdateDataEx(m_conditionInOut, true, EcasTypeDxMode.Selection)) { this.DialogResult = DialogResult.None; return; } m_conditionInOut.Negate = m_cbNegate.Checked; } private void OnBtnCancel(object sender, EventArgs e) { } private void OnConditionsSelectedIndexChanged(object sender, EventArgs e) { if(m_bBlockTypeSelectionHandler) return; UpdateDataEx(m_condition, true, EcasTypeDxMode.ParamsTag); UpdateDataEx(m_condition, false, EcasTypeDxMode.None); } private void OnBtnHelp(object sender, EventArgs e) { AppHelp.ShowHelp(AppDefs.HelpTopics.Triggers, AppDefs.HelpTopics.TriggersConditions); } } } KeePass/Forms/EditStringForm.cs0000664000000000000000000002070413222430410015420 0ustar rootroot/* KeePass Password Safe - The Open-Source Password Manager Copyright (C) 2003-2018 Dominik Reichl This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ using System; using System.Collections.Generic; using System.ComponentModel; using System.Diagnostics; using System.Drawing; using System.Text; using System.Threading; using System.Windows.Forms; using KeePass.App; using KeePass.Resources; using KeePass.UI; using KeePassLib; using KeePassLib.Collections; using KeePassLib.Delegates; using KeePassLib.Security; using KeePassLib.Utility; namespace KeePass.Forms { public partial class EditStringForm : Form { private ProtectedStringDictionary m_vStringDict = null; private string m_strStringName = null; private ProtectedString m_psStringInitialValue = null; private RichTextBoxContextMenu m_ctxValue = new RichTextBoxContextMenu(); private PwDatabase m_pwContext = null; private List m_lSuggestedNames = new List(); private List m_lStdNames = PwDefs.GetStandardFields(); private char[] m_vInvalidChars = new char[] { '{', '}' }; public EditStringForm() { InitializeComponent(); Program.Translation.ApplyTo(this); } /// /// Initialize the dialog. Needs to be called before the dialog is shown. /// /// String container. Must not be null. /// Initial name of the string. May be null. /// Initial value. May be null. public void InitEx(ProtectedStringDictionary vStringDict, string strStringName, ProtectedString psStringInitialValue, PwDatabase pwContext) { Debug.Assert(vStringDict != null); if(vStringDict == null) throw new ArgumentNullException("vStringDict"); m_vStringDict = vStringDict; m_strStringName = strStringName; m_psStringInitialValue = psStringInitialValue; m_pwContext = pwContext; } private void OnFormLoad(object sender, EventArgs e) { Debug.Assert(m_vStringDict != null); if(m_vStringDict == null) throw new InvalidOperationException(); GlobalWindowManager.AddWindow(this); m_ctxValue.Attach(m_richStringValue, this); string strTitle, strDesc; if(m_strStringName == null) { strTitle = KPRes.AddStringField; strDesc = KPRes.AddStringFieldDesc; } else { strTitle = KPRes.EditStringField; strDesc = KPRes.EditStringFieldDesc; } BannerFactory.CreateBannerEx(this, m_bannerImage, Properties.Resources.B48x48_Font, strTitle, strDesc); this.Icon = AppIcons.Default; UIUtil.EnableAutoCompletion(m_cmbStringName, true); UIUtil.PrepareStandardMultilineControl(m_richStringValue, true, true); if(m_strStringName != null) m_cmbStringName.Text = m_strStringName; if(m_psStringInitialValue != null) { m_richStringValue.Text = m_psStringInitialValue.ReadString(); m_cbProtect.Checked = m_psStringInitialValue.IsProtected; } ValidateStringNameUI(); PopulateNamesComboBox(); // UIUtil.SetFocus(..., this); // See PopulateNamesComboBox } private bool ValidateStringNameUI() { string strResult; bool bError; bool b = ValidateStringName(m_cmbStringName.Text, out strResult, out bError); Debug.Assert(!m_lblValidationInfo.AutoSize); // For RTL support m_lblValidationInfo.Text = strResult; if(bError) m_cmbStringName.BackColor = AppDefs.ColorEditError; else m_cmbStringName.ResetBackColor(); m_btnOK.Enabled = b; return b; } private bool ValidateStringName(string str) { string strResult; bool bError; return ValidateStringName(str, out strResult, out bError); } private bool ValidateStringName(string str, out string strResult, out bool bError) { strResult = KPRes.FieldNameInvalid; bError = true; if(str == null) { Debug.Assert(false); return false; } if(str.Length == 0) { strResult = KPRes.FieldNamePrompt; bError = false; // Name not acceptable, but no error return false; } if(str == m_strStringName) // Case-sensitive { strResult = string.Empty; bError = false; return true; } foreach(string strStd in m_lStdNames) { if(str.Equals(strStd, StrUtil.CaseIgnoreCmp)) return false; } if(str.IndexOfAny(m_vInvalidChars) >= 0) return false; if(str.Equals(m_strStringName, StrUtil.CaseIgnoreCmp) && !m_vStringDict.Exists(str)) { } // Just changing case else { foreach(string strExisting in m_vStringDict.GetKeys()) { if(str.Equals(strExisting, StrUtil.CaseIgnoreCmp)) { strResult = KPRes.FieldNameExistsAlready; return false; } } } strResult = string.Empty; bError = false; return true; } private void OnBtnOK(object sender, EventArgs e) { string strName = m_cmbStringName.Text; if(!ValidateStringNameUI()) { this.DialogResult = DialogResult.None; return; } if(m_strStringName == null) // Add string field { Debug.Assert(!m_vStringDict.Exists(strName)); } else // Edit string field { if(!m_strStringName.Equals(strName)) m_vStringDict.Remove(m_strStringName); } ProtectedString ps = new ProtectedString(m_cbProtect.Checked, m_richStringValue.Text); m_vStringDict.Set(strName, ps); } private void OnBtnCancel(object sender, EventArgs e) { } private void CleanUpEx() { m_ctxValue.Detach(); } private void PopulateNamesComboBox() { ThreadStart ts = new ThreadStart(this.PopulateNamesCollectFunc); Thread th = new Thread(ts); th.Start(); } private void PopulateNamesCollectFunc() { try { PopulateNamesCollectFuncPriv(); } catch(Exception) { Debug.Assert(false); } } private void PopulateNamesCollectFuncPriv() { if(m_pwContext == null) { Debug.Assert(false); return; } EntryHandler eh = delegate(PwEntry pe) { if(pe == null) { Debug.Assert(false); return true; } foreach(KeyValuePair kvp in pe.Strings) { if(ValidateStringName(kvp.Key) && !m_lSuggestedNames.Contains(kvp.Key)) { // Do not suggest any case-insensitive variant of the // initial string, otherwise the string case cannot // be changed (due to auto-completion resetting it) if(!kvp.Key.Equals(m_strStringName, StrUtil.CaseIgnoreCmp)) m_lSuggestedNames.Add(kvp.Key); } } return true; }; m_pwContext.RootGroup.TraverseTree(TraversalMethod.PreOrder, null, eh); m_lSuggestedNames.Sort(); if(m_cmbStringName.InvokeRequired) m_cmbStringName.Invoke(new VoidDelegate(this.PopulateNamesAddFunc)); else PopulateNamesAddFunc(); } private void PopulateNamesAddFunc() { foreach(string str in m_lSuggestedNames) m_cmbStringName.Items.Add(str); if(m_strStringName == null) UIUtil.SetFocus(m_cmbStringName, this); else UIUtil.SetFocus(m_richStringValue, this); } private void OnBtnHelp(object sender, EventArgs e) { AppHelp.ShowHelp(AppDefs.HelpTopics.Entry, AppDefs.HelpTopics.EntryStrings); } private void OnFormClosed(object sender, FormClosedEventArgs e) { GlobalWindowManager.RemoveWindow(this); } private void OnNameTextChanged(object sender, EventArgs e) { ValidateStringNameUI(); } protected override bool ProcessDialogKey(Keys keyData) { if(((keyData == Keys.Return) || (keyData == Keys.Enter)) && m_richStringValue.Focused) return false; // Forward to RichTextBox return base.ProcessDialogKey(keyData); } private void OnFormClosing(object sender, FormClosingEventArgs e) { CleanUpEx(); } } }KeePass/Forms/GroupForm.Designer.cs0000664000000000000000000004366412760333550016226 0ustar rootrootnamespace KeePass.Forms { partial class GroupForm { /// /// Erforderliche Designervariable. /// private System.ComponentModel.IContainer components = null; /// /// Verwendete Ressourcen bereinigen. /// /// True, wenn verwaltete Ressourcen gelöscht werden sollen; andernfalls False. protected override void Dispose(bool disposing) { if(disposing && (components != null)) { components.Dispose(); } base.Dispose(disposing); } #region Vom Windows Form-Designer generierter Code /// /// Erforderliche Methode für die Designerunterstützung. /// Der Inhalt der Methode darf nicht mit dem Code-Editor geändert werden. /// private void InitializeComponent() { this.m_lblName = new System.Windows.Forms.Label(); this.m_bannerImage = new System.Windows.Forms.PictureBox(); this.m_btnOK = new System.Windows.Forms.Button(); this.m_btnCancel = new System.Windows.Forms.Button(); this.m_tbName = new System.Windows.Forms.TextBox(); this.m_lblIcon = new System.Windows.Forms.Label(); this.m_btnIcon = new System.Windows.Forms.Button(); this.m_tabMain = new System.Windows.Forms.TabControl(); this.m_tabGeneral = new System.Windows.Forms.TabPage(); this.m_dtExpires = new System.Windows.Forms.DateTimePicker(); this.m_cbExpires = new System.Windows.Forms.CheckBox(); this.m_tabNotes = new System.Windows.Forms.TabPage(); this.m_lblNotesHint = new System.Windows.Forms.Label(); this.m_tbNotes = new System.Windows.Forms.TextBox(); this.m_tabBehavior = new System.Windows.Forms.TabPage(); this.m_cmbEnableSearching = new System.Windows.Forms.ComboBox(); this.m_cmbEnableAutoType = new System.Windows.Forms.ComboBox(); this.m_lblEnableSearching = new System.Windows.Forms.Label(); this.m_lblEnableAutoType = new System.Windows.Forms.Label(); this.m_tabAutoType = new System.Windows.Forms.TabPage(); this.m_btnAutoTypeEdit = new System.Windows.Forms.Button(); this.m_rbAutoTypeOverride = new System.Windows.Forms.RadioButton(); this.m_rbAutoTypeInherit = new System.Windows.Forms.RadioButton(); this.m_lblAutoTypeDesc = new System.Windows.Forms.Label(); this.m_tbDefaultAutoTypeSeq = new System.Windows.Forms.TextBox(); this.m_tabCustomData = new System.Windows.Forms.TabPage(); this.m_lvCustomData = new KeePass.UI.CustomListViewEx(); this.m_btnCDDel = new System.Windows.Forms.Button(); ((System.ComponentModel.ISupportInitialize)(this.m_bannerImage)).BeginInit(); this.m_tabMain.SuspendLayout(); this.m_tabGeneral.SuspendLayout(); this.m_tabNotes.SuspendLayout(); this.m_tabBehavior.SuspendLayout(); this.m_tabAutoType.SuspendLayout(); this.m_tabCustomData.SuspendLayout(); this.SuspendLayout(); // // m_lblName // this.m_lblName.AutoSize = true; this.m_lblName.Location = new System.Drawing.Point(3, 11); this.m_lblName.Name = "m_lblName"; this.m_lblName.Size = new System.Drawing.Size(38, 13); this.m_lblName.TabIndex = 1; this.m_lblName.Text = "Name:"; // // m_bannerImage // this.m_bannerImage.Dock = System.Windows.Forms.DockStyle.Top; this.m_bannerImage.Location = new System.Drawing.Point(0, 0); this.m_bannerImage.Name = "m_bannerImage"; this.m_bannerImage.Size = new System.Drawing.Size(388, 60); this.m_bannerImage.TabIndex = 1; this.m_bannerImage.TabStop = false; // // m_btnOK // this.m_btnOK.DialogResult = System.Windows.Forms.DialogResult.OK; this.m_btnOK.Location = new System.Drawing.Point(220, 238); this.m_btnOK.Name = "m_btnOK"; this.m_btnOK.Size = new System.Drawing.Size(75, 23); this.m_btnOK.TabIndex = 1; this.m_btnOK.Text = "OK"; this.m_btnOK.UseVisualStyleBackColor = true; this.m_btnOK.Click += new System.EventHandler(this.OnBtnOK); // // m_btnCancel // this.m_btnCancel.DialogResult = System.Windows.Forms.DialogResult.Cancel; this.m_btnCancel.Location = new System.Drawing.Point(301, 238); this.m_btnCancel.Name = "m_btnCancel"; this.m_btnCancel.Size = new System.Drawing.Size(75, 23); this.m_btnCancel.TabIndex = 2; this.m_btnCancel.Text = "Cancel"; this.m_btnCancel.UseVisualStyleBackColor = true; this.m_btnCancel.Click += new System.EventHandler(this.OnBtnCancel); // // m_tbName // this.m_tbName.Location = new System.Drawing.Point(60, 11); this.m_tbName.Name = "m_tbName"; this.m_tbName.Size = new System.Drawing.Size(286, 20); this.m_tbName.TabIndex = 0; // // m_lblIcon // this.m_lblIcon.AutoSize = true; this.m_lblIcon.Location = new System.Drawing.Point(3, 39); this.m_lblIcon.Name = "m_lblIcon"; this.m_lblIcon.Size = new System.Drawing.Size(31, 13); this.m_lblIcon.TabIndex = 2; this.m_lblIcon.Text = "Icon:"; // // m_btnIcon // this.m_btnIcon.Location = new System.Drawing.Point(60, 37); this.m_btnIcon.Name = "m_btnIcon"; this.m_btnIcon.Size = new System.Drawing.Size(33, 23); this.m_btnIcon.TabIndex = 3; this.m_btnIcon.UseVisualStyleBackColor = true; this.m_btnIcon.Click += new System.EventHandler(this.OnBtnIcon); // // m_tabMain // this.m_tabMain.Controls.Add(this.m_tabGeneral); this.m_tabMain.Controls.Add(this.m_tabNotes); this.m_tabMain.Controls.Add(this.m_tabBehavior); this.m_tabMain.Controls.Add(this.m_tabAutoType); this.m_tabMain.Controls.Add(this.m_tabCustomData); this.m_tabMain.Location = new System.Drawing.Point(12, 66); this.m_tabMain.Name = "m_tabMain"; this.m_tabMain.SelectedIndex = 0; this.m_tabMain.Size = new System.Drawing.Size(364, 166); this.m_tabMain.TabIndex = 0; // // m_tabGeneral // this.m_tabGeneral.Controls.Add(this.m_dtExpires); this.m_tabGeneral.Controls.Add(this.m_cbExpires); this.m_tabGeneral.Controls.Add(this.m_lblName); this.m_tabGeneral.Controls.Add(this.m_btnIcon); this.m_tabGeneral.Controls.Add(this.m_tbName); this.m_tabGeneral.Controls.Add(this.m_lblIcon); this.m_tabGeneral.Location = new System.Drawing.Point(4, 22); this.m_tabGeneral.Name = "m_tabGeneral"; this.m_tabGeneral.Size = new System.Drawing.Size(356, 140); this.m_tabGeneral.TabIndex = 0; this.m_tabGeneral.Text = "General"; this.m_tabGeneral.UseVisualStyleBackColor = true; // // m_dtExpires // this.m_dtExpires.Format = System.Windows.Forms.DateTimePickerFormat.Custom; this.m_dtExpires.Location = new System.Drawing.Point(87, 105); this.m_dtExpires.Name = "m_dtExpires"; this.m_dtExpires.Size = new System.Drawing.Size(259, 20); this.m_dtExpires.TabIndex = 5; // // m_cbExpires // this.m_cbExpires.AutoSize = true; this.m_cbExpires.Location = new System.Drawing.Point(6, 105); this.m_cbExpires.Name = "m_cbExpires"; this.m_cbExpires.Size = new System.Drawing.Size(63, 17); this.m_cbExpires.TabIndex = 4; this.m_cbExpires.Text = "Expires:"; this.m_cbExpires.UseVisualStyleBackColor = true; // // m_tabNotes // this.m_tabNotes.Controls.Add(this.m_lblNotesHint); this.m_tabNotes.Controls.Add(this.m_tbNotes); this.m_tabNotes.Location = new System.Drawing.Point(4, 22); this.m_tabNotes.Name = "m_tabNotes"; this.m_tabNotes.Size = new System.Drawing.Size(356, 140); this.m_tabNotes.TabIndex = 2; this.m_tabNotes.Text = "Notes"; this.m_tabNotes.UseVisualStyleBackColor = true; // // m_lblNotesHint // this.m_lblNotesHint.AutoSize = true; this.m_lblNotesHint.Location = new System.Drawing.Point(3, 121); this.m_lblNotesHint.Name = "m_lblNotesHint"; this.m_lblNotesHint.Size = new System.Drawing.Size(167, 13); this.m_lblNotesHint.TabIndex = 1; this.m_lblNotesHint.Text = "Notes are shown in group tooltips."; // // m_tbNotes // this.m_tbNotes.AcceptsReturn = true; this.m_tbNotes.Location = new System.Drawing.Point(6, 10); this.m_tbNotes.Multiline = true; this.m_tbNotes.Name = "m_tbNotes"; this.m_tbNotes.ScrollBars = System.Windows.Forms.ScrollBars.Vertical; this.m_tbNotes.Size = new System.Drawing.Size(341, 107); this.m_tbNotes.TabIndex = 0; // // m_tabBehavior // this.m_tabBehavior.Controls.Add(this.m_cmbEnableSearching); this.m_tabBehavior.Controls.Add(this.m_cmbEnableAutoType); this.m_tabBehavior.Controls.Add(this.m_lblEnableSearching); this.m_tabBehavior.Controls.Add(this.m_lblEnableAutoType); this.m_tabBehavior.Location = new System.Drawing.Point(4, 22); this.m_tabBehavior.Name = "m_tabBehavior"; this.m_tabBehavior.Size = new System.Drawing.Size(356, 140); this.m_tabBehavior.TabIndex = 3; this.m_tabBehavior.Text = "Behavior"; this.m_tabBehavior.UseVisualStyleBackColor = true; // // m_cmbEnableSearching // this.m_cmbEnableSearching.DropDownStyle = System.Windows.Forms.ComboBoxStyle.DropDownList; this.m_cmbEnableSearching.FormattingEnabled = true; this.m_cmbEnableSearching.Location = new System.Drawing.Point(9, 74); this.m_cmbEnableSearching.Name = "m_cmbEnableSearching"; this.m_cmbEnableSearching.Size = new System.Drawing.Size(334, 21); this.m_cmbEnableSearching.TabIndex = 3; // // m_cmbEnableAutoType // this.m_cmbEnableAutoType.DropDownStyle = System.Windows.Forms.ComboBoxStyle.DropDownList; this.m_cmbEnableAutoType.FormattingEnabled = true; this.m_cmbEnableAutoType.Location = new System.Drawing.Point(9, 25); this.m_cmbEnableAutoType.Name = "m_cmbEnableAutoType"; this.m_cmbEnableAutoType.Size = new System.Drawing.Size(334, 21); this.m_cmbEnableAutoType.TabIndex = 1; // // m_lblEnableSearching // this.m_lblEnableSearching.AutoSize = true; this.m_lblEnableSearching.Location = new System.Drawing.Point(6, 58); this.m_lblEnableSearching.Name = "m_lblEnableSearching"; this.m_lblEnableSearching.Size = new System.Drawing.Size(152, 13); this.m_lblEnableSearching.TabIndex = 2; this.m_lblEnableSearching.Text = "Searching entries in this group:"; // // m_lblEnableAutoType // this.m_lblEnableAutoType.AutoSize = true; this.m_lblEnableAutoType.Location = new System.Drawing.Point(6, 9); this.m_lblEnableAutoType.Name = "m_lblEnableAutoType"; this.m_lblEnableAutoType.Size = new System.Drawing.Size(168, 13); this.m_lblEnableAutoType.TabIndex = 0; this.m_lblEnableAutoType.Text = "Auto-Type for entries in this group:"; // // m_tabAutoType // this.m_tabAutoType.Controls.Add(this.m_btnAutoTypeEdit); this.m_tabAutoType.Controls.Add(this.m_rbAutoTypeOverride); this.m_tabAutoType.Controls.Add(this.m_rbAutoTypeInherit); this.m_tabAutoType.Controls.Add(this.m_lblAutoTypeDesc); this.m_tabAutoType.Controls.Add(this.m_tbDefaultAutoTypeSeq); this.m_tabAutoType.Location = new System.Drawing.Point(4, 22); this.m_tabAutoType.Name = "m_tabAutoType"; this.m_tabAutoType.Size = new System.Drawing.Size(356, 140); this.m_tabAutoType.TabIndex = 1; this.m_tabAutoType.Text = "Auto-Type"; this.m_tabAutoType.UseVisualStyleBackColor = true; // // m_btnAutoTypeEdit // this.m_btnAutoTypeEdit.Location = new System.Drawing.Point(315, 54); this.m_btnAutoTypeEdit.Name = "m_btnAutoTypeEdit"; this.m_btnAutoTypeEdit.Size = new System.Drawing.Size(32, 23); this.m_btnAutoTypeEdit.TabIndex = 3; this.m_btnAutoTypeEdit.UseVisualStyleBackColor = true; this.m_btnAutoTypeEdit.Click += new System.EventHandler(this.OnBtnAutoTypeEdit); // // m_rbAutoTypeOverride // this.m_rbAutoTypeOverride.AutoSize = true; this.m_rbAutoTypeOverride.Location = new System.Drawing.Point(9, 33); this.m_rbAutoTypeOverride.Name = "m_rbAutoTypeOverride"; this.m_rbAutoTypeOverride.Size = new System.Drawing.Size(153, 17); this.m_rbAutoTypeOverride.TabIndex = 1; this.m_rbAutoTypeOverride.TabStop = true; this.m_rbAutoTypeOverride.Text = "Override default sequence:"; this.m_rbAutoTypeOverride.UseVisualStyleBackColor = true; // // m_rbAutoTypeInherit // this.m_rbAutoTypeInherit.AutoSize = true; this.m_rbAutoTypeInherit.Location = new System.Drawing.Point(9, 10); this.m_rbAutoTypeInherit.Name = "m_rbAutoTypeInherit"; this.m_rbAutoTypeInherit.Size = new System.Drawing.Size(272, 17); this.m_rbAutoTypeInherit.TabIndex = 0; this.m_rbAutoTypeInherit.TabStop = true; this.m_rbAutoTypeInherit.Text = "Inherit default auto-type sequence from parent group"; this.m_rbAutoTypeInherit.UseVisualStyleBackColor = true; this.m_rbAutoTypeInherit.CheckedChanged += new System.EventHandler(this.OnAutoTypeInheritCheckedChanged); // // m_lblAutoTypeDesc // this.m_lblAutoTypeDesc.Location = new System.Drawing.Point(26, 79); this.m_lblAutoTypeDesc.Name = "m_lblAutoTypeDesc"; this.m_lblAutoTypeDesc.Size = new System.Drawing.Size(321, 27); this.m_lblAutoTypeDesc.TabIndex = 4; this.m_lblAutoTypeDesc.Text = "All subgroups and entries in the current group that inherit the group\'s auto-type" + " sequence will use the one entered above."; // // m_tbDefaultAutoTypeSeq // this.m_tbDefaultAutoTypeSeq.Location = new System.Drawing.Point(29, 56); this.m_tbDefaultAutoTypeSeq.Name = "m_tbDefaultAutoTypeSeq"; this.m_tbDefaultAutoTypeSeq.Size = new System.Drawing.Size(280, 20); this.m_tbDefaultAutoTypeSeq.TabIndex = 2; // // m_tabCustomData // this.m_tabCustomData.Controls.Add(this.m_btnCDDel); this.m_tabCustomData.Controls.Add(this.m_lvCustomData); this.m_tabCustomData.Location = new System.Drawing.Point(4, 22); this.m_tabCustomData.Name = "m_tabCustomData"; this.m_tabCustomData.Size = new System.Drawing.Size(356, 140); this.m_tabCustomData.TabIndex = 4; this.m_tabCustomData.Text = "Plugin Data"; this.m_tabCustomData.UseVisualStyleBackColor = true; // // m_lvCustomData // this.m_lvCustomData.FullRowSelect = true; this.m_lvCustomData.HeaderStyle = System.Windows.Forms.ColumnHeaderStyle.None; this.m_lvCustomData.HideSelection = false; this.m_lvCustomData.Location = new System.Drawing.Point(6, 10); this.m_lvCustomData.Name = "m_lvCustomData"; this.m_lvCustomData.ShowItemToolTips = true; this.m_lvCustomData.Size = new System.Drawing.Size(341, 93); this.m_lvCustomData.TabIndex = 0; this.m_lvCustomData.UseCompatibleStateImageBehavior = false; this.m_lvCustomData.View = System.Windows.Forms.View.Details; this.m_lvCustomData.SelectedIndexChanged += new System.EventHandler(this.OnCustomDataSelectedIndexChanged); // // m_btnCDDel // this.m_btnCDDel.Location = new System.Drawing.Point(273, 109); this.m_btnCDDel.Name = "m_btnCDDel"; this.m_btnCDDel.Size = new System.Drawing.Size(75, 23); this.m_btnCDDel.TabIndex = 1; this.m_btnCDDel.Text = "&Delete"; this.m_btnCDDel.UseVisualStyleBackColor = true; this.m_btnCDDel.Click += new System.EventHandler(this.OnBtnCDDel); // // GroupForm // this.AcceptButton = this.m_btnOK; this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F); this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; this.CancelButton = this.m_btnCancel; this.ClientSize = new System.Drawing.Size(388, 273); this.Controls.Add(this.m_tabMain); this.Controls.Add(this.m_btnCancel); this.Controls.Add(this.m_btnOK); this.Controls.Add(this.m_bannerImage); this.FormBorderStyle = System.Windows.Forms.FormBorderStyle.FixedDialog; this.MaximizeBox = false; this.MinimizeBox = false; this.Name = "GroupForm"; this.ShowInTaskbar = false; this.StartPosition = System.Windows.Forms.FormStartPosition.CenterParent; this.Text = ""; this.Load += new System.EventHandler(this.OnFormLoad); this.FormClosed += new System.Windows.Forms.FormClosedEventHandler(this.OnFormClosed); ((System.ComponentModel.ISupportInitialize)(this.m_bannerImage)).EndInit(); this.m_tabMain.ResumeLayout(false); this.m_tabGeneral.ResumeLayout(false); this.m_tabGeneral.PerformLayout(); this.m_tabNotes.ResumeLayout(false); this.m_tabNotes.PerformLayout(); this.m_tabBehavior.ResumeLayout(false); this.m_tabBehavior.PerformLayout(); this.m_tabAutoType.ResumeLayout(false); this.m_tabAutoType.PerformLayout(); this.m_tabCustomData.ResumeLayout(false); this.ResumeLayout(false); } #endregion private System.Windows.Forms.Label m_lblName; private System.Windows.Forms.PictureBox m_bannerImage; private System.Windows.Forms.Button m_btnOK; private System.Windows.Forms.Button m_btnCancel; private System.Windows.Forms.TextBox m_tbName; private System.Windows.Forms.Label m_lblIcon; private System.Windows.Forms.Button m_btnIcon; private System.Windows.Forms.TabControl m_tabMain; private System.Windows.Forms.TabPage m_tabGeneral; private System.Windows.Forms.TabPage m_tabAutoType; private System.Windows.Forms.Label m_lblAutoTypeDesc; private System.Windows.Forms.TextBox m_tbDefaultAutoTypeSeq; private System.Windows.Forms.CheckBox m_cbExpires; private System.Windows.Forms.DateTimePicker m_dtExpires; private System.Windows.Forms.RadioButton m_rbAutoTypeInherit; private System.Windows.Forms.RadioButton m_rbAutoTypeOverride; private System.Windows.Forms.Button m_btnAutoTypeEdit; private System.Windows.Forms.TabPage m_tabNotes; private System.Windows.Forms.TextBox m_tbNotes; private System.Windows.Forms.TabPage m_tabBehavior; private System.Windows.Forms.Label m_lblEnableSearching; private System.Windows.Forms.Label m_lblEnableAutoType; private System.Windows.Forms.ComboBox m_cmbEnableSearching; private System.Windows.Forms.ComboBox m_cmbEnableAutoType; private System.Windows.Forms.Label m_lblNotesHint; private System.Windows.Forms.TabPage m_tabCustomData; private System.Windows.Forms.Button m_btnCDDel; private KeePass.UI.CustomListViewEx m_lvCustomData; } }KeePass/Forms/EcasEventForm.resx0000664000000000000000000001326612501527726015622 0ustar rootroot text/microsoft-resx 2.0 System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 KeePass/Forms/ImportMethodForm.cs0000664000000000000000000000617313222430410015763 0ustar rootroot/* KeePass Password Safe - The Open-Source Password Manager Copyright (C) 2003-2018 Dominik Reichl This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ using System; using System.Collections.Generic; using System.ComponentModel; using System.Diagnostics; using System.Drawing; using System.Text; using System.Windows.Forms; using KeePass.App; using KeePass.Resources; using KeePass.UI; using KeePassLib; namespace KeePass.Forms { public partial class ImportMethodForm : Form { PwMergeMethod m_mmSelected = PwMergeMethod.CreateNewUuids; public PwMergeMethod MergeMethod { get { return m_mmSelected; } } public ImportMethodForm() { InitializeComponent(); Program.Translation.ApplyTo(this); } private void OnFormLoad(object sender, EventArgs e) { GlobalWindowManager.AddWindow(this); try { if(this.Owner == null) this.Owner = Program.MainForm; } catch(Exception) { Debug.Assert(false); } BannerFactory.CreateBannerEx(this, m_bannerImage, Properties.Resources.B48x48_Folder_Download, KPRes.ImportBehavior, KPRes.ImportBehaviorDesc); this.Icon = AppIcons.Default; this.Text = KPRes.ImportBehavior; m_radioCreateNew.Text = KPRes.CreateNewIDs; m_radioKeepExisting.Text = KPRes.KeepExisting; m_radioOverwrite.Text = KPRes.OverwriteExisting; m_radioOverwriteIfNewer.Text = KPRes.OverwriteIfNewer; m_radioSynchronize.Text = KPRes.OverwriteIfNewerAndApplyDel; FontUtil.AssignDefaultBold(m_radioCreateNew); FontUtil.AssignDefaultBold(m_radioKeepExisting); FontUtil.AssignDefaultBold(m_radioOverwrite); FontUtil.AssignDefaultBold(m_radioOverwriteIfNewer); FontUtil.AssignDefaultBold(m_radioSynchronize); m_radioCreateNew.Checked = true; } private void OnBtnOK(object sender, EventArgs e) { if(m_radioCreateNew.Checked) m_mmSelected = PwMergeMethod.CreateNewUuids; else if(m_radioKeepExisting.Checked) m_mmSelected = PwMergeMethod.KeepExisting; else if(m_radioOverwrite.Checked) m_mmSelected = PwMergeMethod.OverwriteExisting; else if(m_radioOverwriteIfNewer.Checked) m_mmSelected = PwMergeMethod.OverwriteIfNewer; else if(m_radioSynchronize.Checked) m_mmSelected = PwMergeMethod.Synchronize; } private void OnBtnCancel(object sender, EventArgs e) { } private void OnFormClosed(object sender, FormClosedEventArgs e) { GlobalWindowManager.RemoveWindow(this); } } }KeePass/Forms/EcasEventForm.Designer.cs0000664000000000000000000001414312501527726017000 0ustar rootrootnamespace KeePass.Forms { partial class EcasEventForm { /// /// Required designer variable. /// private System.ComponentModel.IContainer components = null; /// /// Clean up any resources being used. /// /// true if managed resources should be disposed; otherwise, false. protected override void Dispose(bool disposing) { if(disposing && (components != null)) { components.Dispose(); } base.Dispose(disposing); } #region Windows Form Designer generated code /// /// Required method for Designer support - do not modify /// the contents of this method with the code editor. /// private void InitializeComponent() { this.m_lblEvent = new System.Windows.Forms.Label(); this.m_cmbEvents = new System.Windows.Forms.ComboBox(); this.m_btnOK = new System.Windows.Forms.Button(); this.m_btnCancel = new System.Windows.Forms.Button(); this.m_dgvParams = new System.Windows.Forms.DataGridView(); this.m_lblParamHint = new System.Windows.Forms.Label(); this.m_lblSep = new System.Windows.Forms.Label(); this.m_btnHelp = new System.Windows.Forms.Button(); ((System.ComponentModel.ISupportInitialize)(this.m_dgvParams)).BeginInit(); this.SuspendLayout(); // // m_lblEvent // this.m_lblEvent.AutoSize = true; this.m_lblEvent.Location = new System.Drawing.Point(9, 14); this.m_lblEvent.Name = "m_lblEvent"; this.m_lblEvent.Size = new System.Drawing.Size(38, 13); this.m_lblEvent.TabIndex = 7; this.m_lblEvent.Text = "Event:"; // // m_cmbEvents // this.m_cmbEvents.DropDownStyle = System.Windows.Forms.ComboBoxStyle.DropDownList; this.m_cmbEvents.FormattingEnabled = true; this.m_cmbEvents.Location = new System.Drawing.Point(12, 30); this.m_cmbEvents.Name = "m_cmbEvents"; this.m_cmbEvents.Size = new System.Drawing.Size(510, 21); this.m_cmbEvents.TabIndex = 0; this.m_cmbEvents.SelectedIndexChanged += new System.EventHandler(this.OnEventsSelectedIndexChanged); // // m_btnOK // this.m_btnOK.DialogResult = System.Windows.Forms.DialogResult.OK; this.m_btnOK.Location = new System.Drawing.Point(366, 289); this.m_btnOK.Name = "m_btnOK"; this.m_btnOK.Size = new System.Drawing.Size(75, 23); this.m_btnOK.TabIndex = 5; this.m_btnOK.Text = "OK"; this.m_btnOK.UseVisualStyleBackColor = true; this.m_btnOK.Click += new System.EventHandler(this.OnBtnOK); // // m_btnCancel // this.m_btnCancel.DialogResult = System.Windows.Forms.DialogResult.Cancel; this.m_btnCancel.Location = new System.Drawing.Point(447, 289); this.m_btnCancel.Name = "m_btnCancel"; this.m_btnCancel.Size = new System.Drawing.Size(75, 23); this.m_btnCancel.TabIndex = 6; this.m_btnCancel.Text = "Cancel"; this.m_btnCancel.UseVisualStyleBackColor = true; this.m_btnCancel.Click += new System.EventHandler(this.OnBtnCancel); // // m_dgvParams // this.m_dgvParams.AllowUserToAddRows = false; this.m_dgvParams.AllowUserToDeleteRows = false; this.m_dgvParams.BorderStyle = System.Windows.Forms.BorderStyle.Fixed3D; this.m_dgvParams.ColumnHeadersHeightSizeMode = System.Windows.Forms.DataGridViewColumnHeadersHeightSizeMode.AutoSize; this.m_dgvParams.Location = new System.Drawing.Point(12, 57); this.m_dgvParams.Name = "m_dgvParams"; this.m_dgvParams.Size = new System.Drawing.Size(510, 180); this.m_dgvParams.TabIndex = 1; // // m_lblParamHint // this.m_lblParamHint.Location = new System.Drawing.Point(9, 249); this.m_lblParamHint.Name = "m_lblParamHint"; this.m_lblParamHint.Size = new System.Drawing.Size(513, 15); this.m_lblParamHint.TabIndex = 2; this.m_lblParamHint.Text = "<>"; // // m_lblSep // this.m_lblSep.BorderStyle = System.Windows.Forms.BorderStyle.Fixed3D; this.m_lblSep.Location = new System.Drawing.Point(0, 280); this.m_lblSep.Name = "m_lblSep"; this.m_lblSep.Size = new System.Drawing.Size(535, 2); this.m_lblSep.TabIndex = 3; // // m_btnHelp // this.m_btnHelp.Location = new System.Drawing.Point(12, 289); this.m_btnHelp.Name = "m_btnHelp"; this.m_btnHelp.Size = new System.Drawing.Size(75, 23); this.m_btnHelp.TabIndex = 4; this.m_btnHelp.Text = "&Help"; this.m_btnHelp.UseVisualStyleBackColor = true; this.m_btnHelp.Click += new System.EventHandler(this.OnBtnHelp); // // EcasEventForm // this.AcceptButton = this.m_btnOK; this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F); this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; this.CancelButton = this.m_btnCancel; this.ClientSize = new System.Drawing.Size(534, 324); this.Controls.Add(this.m_btnHelp); this.Controls.Add(this.m_lblSep); this.Controls.Add(this.m_lblParamHint); this.Controls.Add(this.m_dgvParams); this.Controls.Add(this.m_btnCancel); this.Controls.Add(this.m_btnOK); this.Controls.Add(this.m_lblEvent); this.Controls.Add(this.m_cmbEvents); this.FormBorderStyle = System.Windows.Forms.FormBorderStyle.FixedDialog; this.MaximizeBox = false; this.MinimizeBox = false; this.Name = "EcasEventForm"; this.ShowInTaskbar = false; this.StartPosition = System.Windows.Forms.FormStartPosition.CenterParent; this.Text = "<>"; this.Load += new System.EventHandler(this.OnFormLoad); this.FormClosed += new System.Windows.Forms.FormClosedEventHandler(this.OnFormClosed); ((System.ComponentModel.ISupportInitialize)(this.m_dgvParams)).EndInit(); this.ResumeLayout(false); this.PerformLayout(); } #endregion private System.Windows.Forms.Label m_lblEvent; private System.Windows.Forms.ComboBox m_cmbEvents; private System.Windows.Forms.Button m_btnOK; private System.Windows.Forms.Button m_btnCancel; private System.Windows.Forms.DataGridView m_dgvParams; private System.Windows.Forms.Label m_lblParamHint; private System.Windows.Forms.Label m_lblSep; private System.Windows.Forms.Button m_btnHelp; } }KeePass/Forms/XmlReplaceForm.resx0000664000000000000000000001326612501532574015776 0ustar rootroot text/microsoft-resx 2.0 System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 KeePass/Forms/SingleLineEditForm.cs0000664000000000000000000000715713222430410016212 0ustar rootroot/* KeePass Password Safe - The Open-Source Password Manager Copyright (C) 2003-2018 Dominik Reichl This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ using System; using System.Collections.Generic; using System.ComponentModel; using System.Diagnostics; using System.Drawing; using System.Text; using System.Windows.Forms; using KeePass.App; using KeePass.UI; namespace KeePass.Forms { public partial class SingleLineEditForm : Form { private string m_strTitle = string.Empty; private string m_strDesc = string.Empty; private string m_strLongDesc = string.Empty; private Image m_imgIcon = null; private string m_strDefaultText = string.Empty; private string[] m_vSelectable = null; private string m_strResultString = string.Empty; public string ResultString { get { return m_strResultString; } } public SingleLineEditForm() { InitializeComponent(); Program.Translation.ApplyTo(this); } public void InitEx(string strTitle, string strDesc, string strLongDesc, Image imgIcon, string strDefaultText, string[] vSelectable) { m_strTitle = strTitle; m_strDesc = strDesc; m_strLongDesc = strLongDesc; m_imgIcon = imgIcon; m_strDefaultText = strDefaultText; m_vSelectable = vSelectable; } private void OnFormLoad(object sender, EventArgs e) { if(m_strTitle == null) throw new InvalidOperationException(); if(m_strDesc == null) throw new InvalidOperationException(); if(m_strLongDesc == null) throw new InvalidOperationException(); if(m_imgIcon == null) throw new InvalidOperationException(); if(m_strDefaultText == null) throw new InvalidOperationException(); GlobalWindowManager.AddWindow(this); BannerFactory.CreateBannerEx(this, m_bannerImage, m_imgIcon, m_strTitle, m_strDesc); this.Icon = AppIcons.Default; this.Text = m_strTitle; Debug.Assert(!m_lblLongDesc.AutoSize); // For RTL support m_lblLongDesc.Text = m_strLongDesc; Control cFocus = null; if((m_vSelectable == null) || (m_vSelectable.Length == 0)) { m_cmbEdit.Enabled = false; m_cmbEdit.Visible = false; cFocus = m_tbEdit; } else // With selectable values { m_tbEdit.Enabled = false; m_tbEdit.Visible = false; cFocus = m_cmbEdit; foreach(string strPreDef in m_vSelectable) m_cmbEdit.Items.Add(strPreDef); UIUtil.EnableAutoCompletion(m_cmbEdit, false); } cFocus.Text = m_strDefaultText; this.Invalidate(); UIUtil.SetFocus(cFocus, this); } private void OnBtnOK(object sender, EventArgs e) { if((m_vSelectable == null) || (m_vSelectable.Length == 0)) m_strResultString = m_tbEdit.Text; else m_strResultString = m_cmbEdit.Text; } private void OnBtnCancel(object sender, EventArgs e) { } private void OnFormClosed(object sender, FormClosedEventArgs e) { GlobalWindowManager.RemoveWindow(this); } } } KeePass/Forms/CharPickerForm.cs0000664000000000000000000002276613222430410015371 0ustar rootroot/* KeePass Password Safe - The Open-Source Password Manager Copyright (C) 2003-2018 Dominik Reichl This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ using System; using System.Collections.Generic; using System.ComponentModel; using System.Diagnostics; using System.Drawing; using System.Text; using System.Windows.Forms; using KeePass.App; using KeePass.App.Configuration; using KeePass.Native; using KeePass.Resources; using KeePass.UI; using KeePassLib; using KeePassLib.Security; using KeePassLib.Utility; using NativeLib = KeePassLib.Native.NativeLib; namespace KeePass.Forms { public partial class CharPickerForm : Form { private ProtectedString m_psWord = null; private ProtectedString m_psSelected = ProtectedString.Empty; private SecureEdit m_secWord = new SecureEdit(); private List

>>c[H2 [&Mgoߎ"@,^~PY^^lXJcϟ? 0Y`߿"dػwP @ OA lb}}iiftF JAJJ>q3×a>e PP$]G)LG3-yIIIi XDoP=?1<~󓁙 b8!A,b cb`_?'zٜ2$= Gb!;+#'G@,̌IĄ.& h K@Lb`pQ t@,b0b__Я?/[ RB4?̣ pOmВ#4J, ˊ7A}c' DdqP@!W @HHIaM 4<+ @ i!k>\ThfK3›Hϟ /_fx>_899de~ArD  .]bغu+DD=C7@Hgg'33sPk%m Ă?x]v2޽ԒASSl ϟ}.Ǐ01 D(rC;`` F`H0 )00ܸqaMF#Ub (V?~̰cn`pcbbggx 033Jղ 'ٳ.\8O'p <@pPIs`BHf!!13?~۷pp(rsa022&= **@=,xc` -@?yρC޵kofPUUb gte~<Ú5EBNNlg`x"@Ub3d+Wbaa|p~777GGGpafffg:u*0\bVax!"266!Hb"'/Ĥ8͠#𗉕?&aqIgKATR ``.#3Ó[>=q 0\-~e%E{_xT;l3\X|c ; 6~gU7d0pzoъ9+YB֮ 0ȨK1CH?H;6 -ß'`c(H)L 6l#'Щ\ f2, bxvp1Çg BhhF712HZ9'*@ !lf`bqa-v2H3qD@uC):YXn:/P+BiÙ₦@ o^e`SZfvb H,`@ PC'8&~qY1ꍣ *J .. _cshVz/HĂ+`/B-vB#<Î7np5 f8(cEp<6Lc#P'X&T̄lAj?x3("!5b *FQhFh <,R<9, [`@_.c /?@1k (@ŰX^ _E<o20|<-~`J"[0@,X  3f#ˏ< l, o>ex#0/0bq3_JM ˨>Fhπ. >s +Ù$l.p;쨘\F35>` `O_^?c!P;+Po`[+ ̨*2`,%1`=-4- ? [ &OY5.0M1` =🉉z 2F%@1+$by' c> X!%ڼ1E($3 9@ԴaG0A"-Q P Gf=@avf@ߔ{?%+ 3p]-̻)veefxq!/fep` 601AKtpb+o\sx2IQn`=G_`߿|A?8,3He89#2BIR1A ޽c֘( y/{{/^[O I~?1k׮ e 0@LRRNIIk,= ;w <@5@P0S4WmP жIENDB`Ext/Images_App_HighRes/Nuvola/B48x48_BlockDevice.png0000664000000000000000000000644510125245344021052 0ustar rootrootPNG  IHDR00WgAMA7tEXtSoftwareAdobe ImageReadyqe< IDATxb?P8=@C4=@C4=@C###\0?3@ @{6 o u ` A$0D1kw݁koK~(0wxt oT0d`(2!Æwma`( 13blbk'V]P~̄ pA5Ե`/,+õg?w_304#%L Q 2@s1@2:176kFV'UnO9:?8=@p,z$ vvVK>}33`TCw T }G0l|` b`@ 5Envn`a9qT*  /Y|}<@pbd;J&*)0KJ- (7c82æӧl<C3Pg{51mΔ?%7е CFCf~7s'>{ 0<tV< K(20|pP ؠ+x~ A 3#o e"?cqpYSW7cbT:0@%`Ԟd8[pC dIEF2++-Ȏa0 86N\Ȱܹ_[޼QC w)%@ePGfDJPm ?.0tyP0 ,JƮӳ.,d`abfɏA)E 4_XXY1 Uǯk/N3I|c 3zA L t.0'{w].Eփc`ٴ d1 t1#0?|=v/0/ #00nB6 3̅ 0r3eadI ~e@Ch(0*@Ff 0N`xs:8֙!0},(SB+.t/@%] ~Fa5 @1!ca:Ԁr<`+AA Uh:(B_a u,3؀s u< D_Ԫ cIʤ[20\ L`RPPL.0Oᾯ$C:K,2#bYC0 Ny%4Ԭ @( g`>ё1|y8Z0!TAE!K/YK C !'~dhQ )ASy1_&,yj@@]nb^߾1jz3|͠"/+C0fN]`8!m~^hoA@OBF&"{P%p*D!B3|Ji iZ1(I0,a߁O 1HXP_H &@p= r1n(Y%O7 ߀y!0@&C!#$~ *p;Cor^g+!Eo`7ĄB`yo' ~fUQ Q - D͚_PPZI?pFAG?Lkbh) Og?0ibBz`,X{'f Tlaߋ0V8!s8f2B;g&6þνgc`feaGsO00,>p>C u|S@,hz^3g<$D+"FPr7OV3}PΉL(9t3`y*od˄м X"]g K3U@P_dVc=uNPPNb:{ {n -j9e,Ll@_O3y/v c;T O>v֑3_f&h'0o[槼fpx x 6%De= )I />|~'QQQ^^^`Zgbp#3VT²o&";qaks3@(yn.03C#`ȇS6ƊO*3,ةy+?+76`3Iqfe_b|zá 7u\]xshuAIhq( !NJB|Ԅ=X>< lME+# *~tv࿿pg{ B$sW4@ &P03N@Ӏ5?2@uA z} pzߌ/|v'#ycLP?.?1 7gגw1f"VVh)qB`+9 y孁X2RB6&`^w=@y (_~*3:n"0Pw} &̡գo &gb- 4/.'B_ z H@77_,U;Cw(2'q:@_՞e>cx(V Hxtw~A<ߘ#{ \y.dd8thPp$7cz he@z_2 _$9" xn:s ^V1Z0w&N@B9C >`x:H@mАb!!!0=/^IENDB`Ext/Images_App_HighRes/Nuvola/B48x48_HwInfo.png0000664000000000000000000001012410131265440020053 0ustar rootrootPNG  IHDR00WgAMA7tEXtSoftwareAdobe ImageReadyqe<IDATxb?P0@ y 2x>42gϠ΢, L,珧 ^c<û'.Myڎ%bD=෋OoD4e8EyDx9cd7û?g^`lk ._d7<@{c1?fI)OO3YSuQ&Vo?~?F04Ͽ 7|a8yÃ'@Ɨ[Kex~1ğ@׍Lmn|a@G23<}dD[ ( L?11Ѕ{ ?߸tG)Ý凁P ~mc~/mG=3?fdz?3Py& pu1|xu-ãE Vn@'@n *~, 7bЗccW`331edd_ #ԏ_Ԥ]q 0s3[ =H9 1`6OXdZ\íNPJ* ʌ@10|@&)x,,uKnNbxutI^دgdb鴷b4P`?Ûa~CDYGAA -&O JAB?<0*}ʀ61'91@*V4TLE~f`xx`2@|:;1 GJ bf|E&p RKY}eVA'd$T~~7s0Wd`~rGw/أw>f߁@5xLA>I(C3$+N,A|!.GuVfF1,=܀F1"g@e@ 0| lmgR24@zd23G؄CX0"J ʣsΑ ΀ _C z'΁0#7tg`@X~cbt/ #((x?!?CbT| H+\l?ÑbГ\d L9ܚj ,< \'?y؀3`M'1(v‹Ov J @؀j@4'+#c}?}@`cd` *V 1L L4H+Ph6~fl`ߠ,?)*!.!񝟏oll8RS@}'N@d@BLe68Q2<_ )U65=o)?GdZ(dd+_^i X~:uaǎ^x J: E5$2bC=R1aGNL @i XbdJ wb=Cev;Hn]{'@/EAm!À^Gm>3G Ab4ZAc/~~^Q&`defbJ˗@.jM> I)I㈡!A\HlXW""7/4B ?x) *Q.GX +' P0 V _X}9;` |e`Db4 9_VAJVX(@b\f`@#ps%~\=Ǘ`eF'6z p:/4X|h ?0@@zW ߬~0Op2Fh?T@CTgn _)P.;@70g?>ܹ *jBTz VNbz 9T}/AK@ٿ5 ) 1Q 祗xuyo03ѰR `3-f~: 9+XܷeƿH4,_=aP cЌŝ['u??<) #ת7aO7(#e(M<  Pǃ1~v)_A2J7< Gĸc J8^fRq1Ej710t0cOḥ,@ÒDzp6CrCJ4LQ- hOB<װOeJ0mb|% Ĵ!*3X4-fFƿH(2FH2Lg`y,X3R"Đq'!9:;O;Mkߋǐ?()1 f eF$ cf^4c}!$Da~MԱ O P /21]/d` tq`L:5) xXR99׷%/ue9^Dπ0Qb!i`a U?10;̂h:+0g!%0O10 ! A}dV6` ق] 1NPCc/_ ayÙ=e, 5b`o`F C̅TGll lܠlH̀ `&. ddRu[?þ _0X;=48,RAEO` Rn8d&|?a T@=  h-v !A܂ _mɠŠhT I|4 GJBc xezw1.)$/3X03~a`fdl ?AI4 lstLMLy$ ͼ.@8=Gokwf) PL p lvzNmi5Uno9{H3*;gRs_e~rŘ x/>}ȳR fDSKXŲʔUzvd:Ug: 8]6JXjbGv@# ڨ7`?d4xZs hgfد@`s#б >3fWe |h? u>YN֋Ndbӿy[ - To%P] f^3?؂gb{/fb9 |@"*k} Q#JK IIIJrAF%@y s Xh9 ~L bW~>/X҃"m7VSX Ԗ@| hjC iOZvbm 44IENDB`Ext/Images_App_HighRes/Nuvola/B48x48_FileSave.png0000664000000000000000000000510310133443102020353 0ustar rootrootPNG  IHDR00WgAMA7tEXtSoftwareAdobe ImageReadyqe< IDATxb?P8=@C4=@X=$i00-d``01|ʈOR?π {/ª Xt< 'si)]"o@A2??,h@G0h4W;W1(Kjݬkĸ>%yAR\_GyfCu0##,V` Ԃ? /\dV +?_F)",wg&+uUIN?jvv!!r@abFF.Th0 NJCᾐt@=? ?cCRb P !403 :ߏ lʄ# 1g Q !? u ̈́OA= >#81BdW&^?̿A2.* e$ p(13c$('1? oT4!#\+ \8Jit`eDIP&pXbA8 Hlcz Q`; $ 1Cc?4ȁhfhMB  Fx O>L@A.1Ą3` v#`XZabg"'#ʂ' P8##R' PRHQψ(p@DfDx#$ (FF؇&Q\ pzryPLy?#f@DF9hx"D{5R T e2;<ŗ"{aH$QOĂ E̐Yf$ G'!yAX m&F9F< p'!<E1(/#"X# ˆ@!P̌'oCC5ТggoMdd(&F N8?HU2$ @x?x 0kDFCP,JV mÊL=THR X$"c~@;Ab`CDL-LL&,1+ x pBham>DTGI  8XSQt_Lf9b 7?^}cx,/Ǒ3?,l^/4y%& IԔeQP5l, ?#R?jŗgbֆ0J}1G6Jd#l#AXA@oٰf>(j]#Ci#?%0CǏ 90 #bj/& =2V:y~cw?Q^eϟ3gadjRRYKi7P7TF*XC/ 3A'~ .Nz231/ o$+@C[6,<п_, ?R9߿2=tQ XRBkc"X' 1{b/ßx_` Bz’L @x{drȰ.:?'@qb<? , }P,|c$X/R=DCi 90 cDa >(d pZV ȣdѡ d@AH6r F@Բ'099 ?>RED ^4%@yHhTX*1QI!1\ 1 QX&&I G/ 㗿~̟ '(@t J2` p@R逸?"Ăo.^ G@?FH~ZZrv2y} A%#ߨ= @,E*$D|ȠH7b q '0sK2oX/<4 z_^{%ë 4tIIAFpC^[7 ,  ÷_N}fe`lj0c`B|L?N٧E <| dU#?_WMdb N,L\|ͳe:/$Ӭ4=@C4=@C4=`KU8IENDB`Ext/Images_App_HighRes/Nuvola/B48x48_Apply.png0000664000000000000000000000544710133445206017764 0ustar rootrootPNG  IHDR00WgAMA7tEXtSoftwareAdobe ImageReadyqe< IDATxb?P8=@C4=@C4=@Ca^N.sPym?w%}`>0i(Y`!e}* h-Ao 44O>(x{{xw0Lpx}` Y`^NAqQ3aQaC ]@ Rǫ:3g޽  ߿ ]\RZ* * >}fx5:h0y@ߟUed6?ưU7޽dbb)D@o)\"| nBb K_^!S])`%iC>A`-ð n1<7c+)ȸ (򚊎z34C$73 ?߿g~ @bddej/0  0c,`egfbed01d/ hz0C,0n}ʰC10~gvF&aUgSe}?`=!C #+s2(C<Ͽ0?&` Ņ@1afbL~|Գ Z Z *& ,|@O7ҋ90eSg3f1daV:X(&0>yǰKs>1}33s(Ʒ4'No]҇ ~ q &\ ,^3uZje. C:1/o~1  46@ax aƷ3yr ‘ R܁^ H47A6QPEsnP+CN$;o߯6{pW_`b`UJ0Ê^3Fzqgau[!oZk}o߿`dVdcgapWbe`/ o :뿗 d8uï[232G3Y`҄K\ 0+*0H 0j13˃3ߠto^1z_ ߮9?^B @a_##.Z&4"(0x ^2^No dC0_2м?ߙ!/x 0c7 )ü2aPe t(#т, /`e N6 oCȹ@3guJO $!ft>3>zI#q)`Ì? :yG+2`#-KFR*[ ,S~=`a l^ae`´1 ؾcT@X3//n%AOP`?p,BT~a) `;;O_L غ3c? gA1 0?,*02=q/)1}c iӽ &l1 310Obz#G_2|e >a8{I,W"Iٔτ30aʼ-N/2|6Ⱦ,0m&7'ebfvG X?c~{ g l0c g7@|o7xu+}f#=^W'nfdtP%UYcƧ Ipz Ok?Ggw?Z""C>36},(rWP 5&WZ@%@712[5cf^X@C~ h{ h{ h{ Cu:IENDB`Ext/Images_App_HighRes/Nuvola/B48x48_Make_KDevelop.png0000664000000000000000000000616610133444030021336 0ustar rootrootPNG  IHDR00WgAMA7tEXtSoftwareAdobe ImageReadyqe< IDATxb?P8=@C4=@p02&+303&և Y=  $$nqvbP/4J|IJz!A1I/ /`͉X @,g(O`b C|<\*BCf g``8=-4` $01gfb+`$1" d0,`bGQőC },v2L,`\ jjA[>  4%7fG4iVApP u5QtbAV~b-? CI?ýT„kB/`erSf`ee@gG^p?y P?g4@ my?4c<;{#Q_߽V>߾]//33[X0dx 'JQB$ Oy# wee 7oDyTxyEDΜ o_C=bb+bRr&!Bx bxt(ã'~|36 _`uoX>es']??IȍM $Db: b M`i5ueKϫWՀ<~fE >> l {Cq~aq.ÿ/y `*Ic qõ'l v<$ İ$ g"BxIB.d]m-??ï? v?V6FiF`-@#˽pi|+k-)LBAbW ~/[|'`X}@[48-AX# >`c/Z^(~ &(4}V..f66AX@f0Ca4 S3\߽ Q/ $JHI  (| <Z UQ 2?~{`7֯ex#zfhf+CP21@!yL,pap[cP77?E%@N.+[ )sDv``69ʂQ|;`y<@#qXLK aRr 4[X10(20101'%f`f7bg7IH44<@,(yȚX܂̢ ߼c$?޾a>zo 'LF#( `He p "7?@:z PK%!.`aaMp`%C050DWeXfx /Ȇ;?$oԦ@8%Է0.ee12d`}3(a a`Y!5 pFD 637 ë<xĿ$R)@L9R [m=?fHA|Xp? 7a!C`ZtCĨ51j J=\aw<,-VX elm2e>ȼWpP>ا/2|6R!jE &RҔko_gVP#/20c }3`F?3oík4 ?RlCmJ ֘c`@w?!!aఴdxk"A: :`X&W.1xۃ * Y  L`EI>Qxr)@h&?M|Tp~` l@0?mr$#^Y6`GƆA9%ABI~HAu8zEڔ@$ˆ.r, Wa/`{FCῩÓ}{O&`Hz0iVϝaɠʠ , &~dx?Dc~p r?{Ü&K,PlHza! _ (7K!~OF8P+6F(4, Y:J pe8XRJ 20 ;Q>C< .Z 12z/4J|IJz!A1I/ /MPjB/o}k/ ?(?ʇšbP,$9qj~&3ݲJjBf&onF#€HB &H|tXU,?b'3v+`v6s!BT'EӳJuEvrOT"ބIT&Nl d~a`8_h.FN?:t93Kh L ?30ptDr5@2hC=  $?{ Y lL 6g^JP| @(L"" An H4+v##"JF3@c?4 yvD}"FOW0x ,cXed1a`df!πa1R)@H$1|2@v)L_%G'>2o-B|a`bbD BX$\I `b,:4A U b Z1|y#T lllp5fJrAfC*< o<@a&!,GgA3 Z1s6?a:'9CAA6g\a4i8&& )!! I5QZ3`-H:_,t ϟ?v'<i@u#%iX凜fH)聏 _/F?f̙SPJP2/@a֬h?ZJBlf L `1.>N72ܝ/(O}cj0Jԃ2'@/w(cb"$/F 21# b 1pa`1*톖0vD/%D, Rz#y~y䤃\@)6e A`$BPfS PJ!pKB_%3,31fL ǣP/3T Fc'U _^eTS`P_<g@)QC+Fb Pc{| #dQ O2=!AM6gAm#5e@a<HXOBH]]B) M ,>A@FA3{ e$>>:oxȃW˗$TUj@~ŭ[w1J&Dށ BBBYZEc l6?6}e` T_p2iz ޘ-Ceeit-^r1 l: ?IF`s÷?f`fR=iذ("#mP򑕕k@9LZZ!""HF@eeeIC<@1ܬE?2 }`` Z b76K{^3efw ~- i2| AA7Fi(ЋQc Z A"! at$4(@5$# F6~@Gc8D4P gX@iTW F<#C ꑿw`3yQ`x@)HoFch?'ZLE]F@6#g@dxGwQQBPfVzNF $>$ Ҭ45&Agt`H>fب;ۍzhZG1Xc6;%9>0gJїo;I˧D=a=L L,ρJ=L <1@ yА@ yА@1-\IENDB`Ext/Images_App_HighRes/Nuvola/B48x48_KGPG_Sign.png0000664000000000000000000001057410125245344020406 0ustar rootrootPNG  IHDR00WgAMA7tEXtSoftwareAdobe ImageReadyqe<IDATxb?P## qOd``na`xpӫbp  1O08h|⽿_o]#hx sXp7N}g 7/Ywi o.@L#;f89 1tz2q30{AZA%)Z%y% H%@ (35i3p20(13(q3|yK_A]$ X@+&27ܑXXL%^|>ex.H@|@ /i 楪X^02vir2H30p-ï?%j L2<84s1 -D0ء4{W@_@ 6 *Ddz3p'\bbC^=Ű}Ν7| @=uU $@ߒxA D<I 5V :``h㙁h񚎝>$} #HbMhS;8aE& ;jwIsEf~`@2 Lbr.d), ,8f>g9@4?<Om5rMwwwa A( t<'09=aԩ6@X3 !9`f&k׾10&\s~C bKHE_mUKͮtpeֻ `{`˚|}n"@axH@"m㬤U&.YRp'1P ڢL @ y6n!q." ǟ1+4ͳ3^b`t[JS>asqЙ8`Sҥ 7_f8/ǕM8,1ƵW$)3(q.o 艳_1,,0 schK$Q%(4ۄAPtM 6f?dgxNO 6dv8?ݓ4:#ld@*2;X쩞Ĥ,u-,W!W2,({M5y-An Ġ?DRxӀ ="(-:#t}a W UDbikSEŀ 0M/:/R~omC$d3000#o,10,٤ʠlE| W !#!'=R-ufGDs W3p 3x3`Ylkc@`&0 o,&S}3|mİ7 /0; ZAN Ջ'H}艏2ql@tO` ڤ`=?Pߋ O3h0k2)p6;OWf]&rrEu92`.0z;6&à&Dz02f@AQ[`gbg01CMm <]׬,`<#k>{6}ˈ =X4~aÃ#0p% ܟ ߿|a|yr-)A"ĂO Dv}nyRaQ+U ?|dn xI#ã0lYy] O1@;Abо ~IR YÖ-G;} P0) q(;Z7 @ HpS /־dzV A+U3DJmyykwf$A j_"n[$pg512*~C}H|8Jz~r1k+% ö kڷ2y 4?g%@㍠B4BS@yy 6V J08jh]lixc: u'`oN!S9qMgI8ݷ xY!2٠4v"j:N AkI1y#`ɛi3Bl 0I=y2 Ʋ ,;CM~WM,{@192~ؑ4T#W̸PNfG/"43")LR0[(16{aHa9!1/pq#D$7RbKyy{Cz *Ҋ .lFԴ %䞽gpӌdBYJ0 e6dQ+F0z/`U$j A`l|6ch˽/`o ] (\@'4 wC[ N3dг@l:@,^,@'$ZESfv> jqAd OPH>% )>g޴A34?!SM>g` uy| R’!L Y;1f` t3`50V|_>W@nfAj@} ZqcCځ$d60]L6x"u?@C} @ y(IENDB`Ext/Images_App_HighRes/Nuvola/B48x48_Trashcan_Full.png0000664000000000000000000001160510126541376021424 0ustar rootrootPNG  IHDR00WgAMA7tEXtSoftwareAdobe ImageReadyqe<IDATxb?P0@ y >IFFF&$`cMo-a`fe`fdd`ϟ ~bÿߏ~USo!Ʊؒ;@18=rw3?Y}T8Yxd_/_~0|wû_`~'۫.x b=@y 4~,,ERr B "`+ ~gt_6첿 @u?fÃ^|+^puu_V" G\'h3J20sn>w~2|ϟ LU_20] %! )%O0\y71ka#8=@y X ?go/`$ң/ /7@h#0 7ÿ?d07x~^.)i um Aan篿3psfxy!t+@@dIQ99^* * f8r ów?fLJ.@?|}ǠtAI?Å' O 1e'@O<?g Ove u}s#F&g/3ܿr2ɺ$`t7ln H:q_C@Qaו }.0`3O ~ :R o[C`I ,EX89`Rb|ݻw ?~?ѿ@ς Xz?Û@adu c z \  n+]^S/1| >8MsrrCmb`Vfo߾e7+C8òCioAee$oPX22qv28b$6 S FdR`蝽7y3?!^;\Ÿ! jpUIc013Hq[1y+ ~2H 1H[2ׯ ߿'NC"o`̜b nq0yoȠ𗉉Λ7 ?$B/w(XޏP0*&bff3?l l/ʹSֻ7S_b0@∁$!C,rx.p>grhRuEuL#e9wNߩUD6Qh[LyίX8ȣX H,vA T |2VCM>.O։4[쁹Q97+^0^-+0,cŃk7{)j~(Җ6IUaP`b4XLEÙfi&j)_>c0UĘua$H@b<@/`fjq= B}: =̽ 0'',BA5%4ŗ@!x@b Jb܌?|`;g30ax3;`wz!Vn`[ae;E`0= )C̠Z=\R 1\aaeiFY) wafo 0ּ?r3` ""T 1?j`x&o>|_!A!XA^f,z?|Ux ?csJ;A|P{?I B, LH?| L6 7.e^~;IAP37~ l y^p`b` Xq"`h z WpDew#aFr3;y?>2zr_ gd6@r!B%TL1< AMw0J7\s0 n 9501~1|J` "` lnvH22Hɳofn`/ ؅^e1N_ef *&LR 3VB |iP vw>5!QM B`EX3[>@>MAT ~{jv30#31{ }w< '~K$PT&ɟ r<2a`2 *K*u&λ XOpߘ_5i$´uQbR'>!wϒVCĠOg^v@J!vk *M$P *06Ԁݫ/ 7 ղ+?@}epFp? ʰ ??ܿ4/{ID x͠:' u}Еw@ |̿dEy>~m`\'p0&W2 _`RdpZL@ +@`sPuJLV +z &By\01Gp;Hm k9PC6.hDTrHFp/@c,,HHQ~^>nvN'} ge`g q;((j9XF`F[u-%$@F&@ oi0_01b ̬L *xqQ`Bʒ`5Y$Y2_LhL@:l4 FË!^@ܡgw`2y=÷ ,@| u|| Ps=D39 |W@0kb 0&d^܄ġi g(B٣`|z&m*|FWh́tf*p"ϑ#2ƴf_ \z CW0ps9 "00 7Ã, ן|ex'O/~^~06A'3 +=av`ʋX1 xe6XPX|z ߤ@/FXt##Ys%npP첁6,\ o/G__Yv`ӀoP0J*N`Ϳ~ >a 2% lN y|ע'o[xMdPe&!P_f.?Yncg_ _}gxX3,0h.p337pӁIAn`- w~Ǐ?n 36'G;[!4̼ `-()|ee>`EX9àn&T:+8#/gx#{FN~.f6`LB߯oV(?-_.Go{3hF@  nf &!jxA=ИС'C_"+4iNC*.; @zgء Z80C1#@ h'GRbm CI٪FIENDB`Ext/Images_App_HighRes/Nuvola/B48x48_ASCII.png0000664000000000000000000000300010130001222017465 0ustar rootrootPNG  IHDR00WgAMA7tEXtSoftwareAdobe ImageReadyqe<IDATxb?P8=@`dddptttP222}ˇ޾}{7o^ @,,6p)((0$  >)U@G OJG' @F;R# 1TW})".f^[. sNclwZZ+V)eSUϸ󙎷#0b]ȞCYt\uj`l666pba`1= ++T H=@ax a4({ ` 1 2HIIŐxA 1i%Wh.]c  f@!K ɓ$ad \bB@2j8 `][@d-BFK$py{` Hr<,۷ "~d@J!1@dl>(Г3$@,;%ɁT31112+@VVV`H |:.P3ͣ''PhbP nѠ@7[ jdXr<p8#*1Pe*N@1h汉?{͛ ϟ?'X @$BH$nz>PCTSbD<@ISRm!bFA4k'`s@pYJ4_*BA"D5da2Bn |I<@~;`L[ &bBʉT} GbH0 zdԤaσ3 &z gv%ElիWaj Pڠ%!P0j1@qz*(F"{T߽{ O B,`4"'&&İ_ z x&DXX 6b!@dn&(A&5Q(-!#0 3,"\za޽`}L[ &bQZ%bƟI XaqkJ*0Pe՘DD(:٠ºQb5*A 3|@##s$ FA511=2ۘ@/6 ǂ< ЃOrki/TUU r[@$r0?@axׯk-[HGD6jձPPPAS oc@NZZ:حmӧO>y(o@w?60)I 6b- V*j7(Y t7 =I {l-h 7IENDB`Ext/Images_App_HighRes/Nuvola/B48x48_Folder_Yellow_Open.png0000664000000000000000000000715710126547500022430 0ustar rootrootPNG  IHDR00WgAMA7tEXtSoftwareAdobe ImageReadyqe<IDATxb?P0@ yА@ yА@ yА@FFF02_ 2H A(,ɠ۟6ofɵh_ 1HA2 *\ : Xf]aH;p H .KQQAPAPARK~a P+ Ձ a/43+OM.>892e`ڧ ßzM hpvE R , L~:ٳ ) d8? 1àĠ @Jp 22Ipp0Jq2(  B@{+oh@G `)P| XX2B ď ? h-. ~0p0 r1J11-Aq~`10pj/ 9@+$2! t 2 "@APLKIB J π7+$a:85(YA< @w300@1} ߇fPAŠj1=F"<<@`=9k0YQjfa 4 \@h_ tGP&&8/Hh3"AhFoh?= +OAw| ~bRۆA7@3CJ@ tHLȎ盿G1B y s?C+ 3`SazZ{O{ ,~_Pt3Bb uRH"iR4@~!w` N5l?C+ @`̵@zAY'u9OH 3<+8Ə/fZv`I\ pMÓoc{?+ -HBbhy/_"+@YXX@c/^3ds XH*F )d1b JJd7нXA_A)Z#4#,WYv{w3XB2,C[L<8"'?д߀oFH &@`^fbp'Fa2,0 db^`?˰ 98Χ~C,#244Z@ _ K@'a`G0?f_?`f@.30 X?jOw w% 3KHZ'#eHi4 A4lhbrP=&ga6R" 0~lK#S7 o!m2k`R;`;aIyH c06w@*07n2|(y&)p_3 N6L #"3Aիd` *f@K>12aZ|EP A7_-]gP!b6+# `GrhSdYA͌,پBćE&#h:(7ßbݿ?32<X+O F##"q*s0V`ؤX`t`1 Xs@wdAGo8z7_O{`[5ß7g~z/>cd/`iOπ׿X0c 0<j#D 1)0ga0:p'0z e&|c r 3a~?Þ2}@~g÷?>\2|?B74J +_Ȏ lj "IB B Zڟ~L{e#{>d ½_ >e1_Z~2 k5B @<+eϖdha}'0$O0|yt؃_ bxNA ?rF: \y4.@, ZtEaCXz u$>@<h\F:/,hH| L=@ 92!!.Ҏu+IENDB`Ext/Images_App_HighRes/Nuvola/B48x48_Package_Development.png0000664000000000000000000000751710130240700022561 0ustar rootrootPNG  IHDR00WgAMA7tEXtSoftwareAdobe ImageReadyqe<IDATxb?P0@ s)6Lϟ?5bcgcccaeeeddF}kLLW~~1Iz9 v:.CZZOZZANNDsssׯ^z _>G 4%D~ &.aic`ia "" e@G? 3#ï?~wǏ3\pݹsƍ~'&F@n r ?.rfaPQRb`gg?y o!/gXXY؀je$D<` ݋u_q@PWT%eаs3s.NG gϜb+33`YXXYXYgxǏ ׮^epǏם?~'@@˶3(33,÷o0Ic5#3 8X!4#= KKJ22(*(h"NNcǎ-J×/T&s+k՘X q1Á !޽y[`_@G30qP hi /90004ͬ5gPP2te-Tb>ãG~w= G>=:y̬<@OdzgϮbf| ⋬R|zN \\ ߾:pfbddx m?~0@! ʜO#M=lP]D|`/  ].pL0c p:fx,>_@ǃ~{ u?=B7TN@,D"?TUUa9XfɁAEU?>{%-#ɓ@-8?D-daa E:: ޾ax=_~ ǿAo ?ddPQef2TQqn  ^ 2MVV$×O9T#?f`Ewk3x aCFKg*tM  n.$hQVVfc:@πoHC%rb{X۲1|] n<]0i _=U4}S@n , b6d xPPR L߁',_gxzyC6m{)WIk] Orm1==jyyŖ6Y9ǏrpfabFϟ.^,shh02<| -|x5=aS .zP ZTROIHHebx-8'Ņ ?0|s ׮]{l=alJ3}|!X(o A%W a nf}M,WxJNɃ  ZsvO_?xxxI 0۷]z FɷnnxW7yY1 3O` 7 ,y|;m^i;թg4Tko[3og ) ʾ ^G?|!'.]瀭``q`Ih2؋3ϞegffgZz͘u7:Z#ӯ " ^R}~oO@ Ք?yd)ubw;3A18XXEvP !IL̓\o?t#DטU= {PK{iMU^99?/xq7usi4h@K Byʤ$֜ O8N͍ܗcrg?D}70Sf,  !drz$H@zhϏ?],cǯŸ n`ϐH/A^O=F |}<~| /?25'3X=U[J8\Z̄  z ~;ނGi`W |fX(0f1z13JJI'@gI?wW~s~k??3pA֏}1vG^~l z{}{ɕg /e-g`UҖ->COT_DM[ bo=13|{v /a /_^}u' H^æpKҋYv!)W0|y񙁝 l1`bf8LOO-d@ @˵/xĞwd5ëB LL ?g`a,71~p%+^c 4fxϟl 0| W Gp?_N=@T 3歪>AQ=ZB;?`'Ý7?yA@ ghx9YYx8ܙч~u߿>3hTt?4<մF@chyXXd}&F0cIENDB`Ext/Images_App_HighRes/Nuvola/B48x48_EditPaste.png0000664000000000000000000000522010133443114020542 0ustar rootrootPNG  IHDR00WgAMA7tEXtSoftwareAdobe ImageReadyqe< "IDATxb?P8=@=`i2900Qdtg`w~A7 _~oF?u/W>ĐC_ 3 S r}A џ^0=OGUVԋw gğAw~33|*a`b`WL@?UIFZ?s#xI^_5Jcb&Pe,@23(=esaM;n/ ABT2AB7cI" ?H3ݷ7 տ T HB< 3Y&PTE- G?0l|1@xc#/i@#^=IIgY$U:Pz㘘@Dφa) PccB3p @0 iP3"<2/иo!yd63ȹ,?-8@! XOqHr$27gPłTHAv nb[H)xaș9V0n@( 3 "CN6e;(ؓ?L1G#\K qIai?\aq8zA_hr<+F ?؎?Fv?!l/̈́G@x? HʔÉI6j9M2@k #>,II6p5P[ 5 gbfz<ؒ_,lV70ȘDKɈ9 xǬk\&@1m2gXN@OZ螇QpMwT`BdbЀ3#F)B@txT0pM @ITRb;O܈$)CEnC-b #/^T_"DĨ#ig!gI>3s03^8c_(  7u z& B1@&dX~"ßfF?ah)ҮBgV^E?l~킖@EpM L+, e?!NئbP h6HW E)okx@ďfQp=q? @h+Q ww \ (!t31?( ,-w 0{+$PC3/]HXЀ{@9SGO$1`v>7hMXaCg Bl!V h{ h' ( dIENDB`Ext/Images_App_HighRes/Nuvola/B48x48_KTouch.png0000664000000000000000000000660510132777146020103 0ustar rootrootPNG  IHDR00WgAMA7tEXtSoftwareAdobe ImageReadyqe< IDATxb?PĂadd$$_1V\b@aDs g?g2<(AP Ղ_ZSVr+?6 PnՕ@@|Pb-@Q lb <\ ̿*/;7$ï@,?D=gdË/~UN/00edra?@Q> ׿_H kj`?FɼL L@֣y T 7~ B5212 _ex3H4b(.2(33׿"_~{ L_yw KL&`gd Xd]d(;qȲnQ Jόbet?_n{p\p2@?cb4/ ý}@H2|uƃ<N /~?`e ÏX~$3J030Hr3﵏π%#E H2{7'kރәH1|`^bVPV1g{.aq@QZe>ÅGYw>ZrigUu%^En& v43 ~.{}]@qr@ȍ9 BI[R(U883W[ O> @_ė_ O7ùɍo? ǁ!MDV[ R]u`1p;s g$+__ _Ϣ %6s /!qqj9lc"{gٷl͛}?$E 1p|x1g~;Äs}a烻?EEyzK)31gϭ߿uU۷o?@(1 &&5NH/P_%b:7e$Ï_x~e(j`1X?A1L'/×? 8lhV bҒ+p}ͰyVGBBA%@x@@@X@Xf&򏍍 Xފ1g`&6VvFaayy---9EU4D=\ {$(*ƖAb||@r͠GdW } u6?Dtjn96o}-uѸ#0`}Č!eb8 ? &b!?䑿3r2Æ _M?n߿xA3%`_'@x;w0<|\ 0~!F?~?| /_d8;HTj>@oݺpE<<< hq=/>+M P5/<{>Pfс Гw`M `!^ 4;гx`ŀ4-05?f`I߸GPC`R%+rٌ0O=?wٳ|=Q2Y؈cf~fPT Ba)0$9zEWnA L*LԀ =zpQPc @=2Qaaa/;M|0ǃ+(((o`'`ellr~cfI >|d0?s_23/@wۿO 4`3ŋ~ _B{տ t.@,i-##+ JD@#ZAhG5O8IʿDFB^Tldcx }^}d={ƥLEwhS5jE {҂[JJFUHH c,E3¡, djЃ} a ) (,t '>--- e/_٪`Ǡ~7I/l"<~tǥ@]f/|2@ԩ4Xd'ćQk6ׯR^A &bFq!H ϟmw1}j9"AXLLy~cK@-PF%%ep;,D;3ZqX D+AP5c,B H~nn>PWh0A"L`KA;㰞zH,pbkIp@2C# Ħ@DDhQńςf=0:.ץIENDB`Ext/Images_App_HighRes/Nuvola/B48x48_Cut.png0000664000000000000000000000651610133443170017426 0ustar rootrootPNG  IHDR00WgAMA7tEXtSoftwareAdobe ImageReadyqe< IDATxb?P8=@C a Tϟ?~gggp2$̙3` X"@P .GGGP|&M=_^~~4P&{xP>61RP9M=td&çOz gϞ1ܹs90Sb@UZZ:=::pP m@ڵkX"f hV kp{{{}P0ǃ.\d!V@:f$'M<hQ 8䁞 ǀ0(޻w4쿀@ig...}=UUUcccΗ/_2_~!L=@(8;;3.,ـ0(+.`fcczHSGt >QQQ {/$d~2K F`(K@yzz2#;|=zpŏ:KHHH_VVVYF`P:,017> w+m0_o(¢gyyWc6L0h@x=<<&+))1b Az` Llٲ@32%7}@]߾CVVښAH@:Νs[_i,~"ׯp`Z#`E'CHH*@I T##A @z@b @,:BΝi11 |h+ )TUe};iҳgo}لo NfRp20(( 5*1P3իW606]-@ ;/##͛ \ LwLw2Ě2{ď 99}2n/aa Г߽6 8BT:(5j1CD*g28qٻwZi~S%YbAN?*r ex yс/O((2?Uׯsb?)*v͛\`Mqp` t(۷֭[ v(_x`ee/VA6N x7 c|e @=w-?*C|}޾eSSyw >D+ Lf22 VϞeXhi13?t1a7" J qP G6/3:WC1E6@= 3ֳ8* 3o~|( TTI+01L f|28B͛`@0=p# @T?:)*BM !`P1!ՐbXl00c?w=)b` Lb_0AH}pow~,&/F ȭ4@AE(ā宆#˗DM4/8T`RaeݾZA!ls@М )?WZ`o `HC6Z 1[tA}@[KKOݼ 'gx9LY/-=ILmo;?`fke0.f'n_,t)FԔX3rC*2@!</ ǀO/V-Ew~rO0{W2lx'}&Vg 4 xb9rm N&,fL>tj=|ȰB1=՝9C˗TT%0jN8G#@!F ѣ9G1+ C `z_sKXJJ>}r5|CG|<8`-8M5@nN|Ee [0%,ek2t- <|o咾t.AP:X3| ##+oV99_ihX~:LoG&Px`+%,Pra)0>P &]*`K% =6s?v5{lEsl0̓ jl <)"/K,vZ@@k6%<ז$, lBU6Ͼs?j ?`l=zku2@4*j1zfa!# ljm۷9>in?u=\_8 I}?rflycqp/6O}׽{ Z$!">@߿$@% ?'m&XO5gPs3a j_ @jPaA}V`sNFQٳ?fbԟ/Aeyy71Ҡ> lϼxxN>84M߾}1C]99‡W=pBJj'/1@u811PP`0by2_3BQ]lBBmp<II4(&6oʠ *e@1 (s 6}?"70ybD]*8!!cg`/ iV`'X4ϰUBbo RVWhFjb"}!㇕߿Js~bfg>] d6@0А_j@C4=`97u}IENDB`Ext/Images_App_HighRes/Nuvola/B48x48_Browser.png0000664000000000000000000001273510130460612020313 0ustar rootrootPNG  IHDR00WgAMA7tEXtSoftwareAdobe ImageReadyqe<oIDATxb?P0@"0O2h303222qM*W ~c`se1](#, >U_cDx4eEYe$y%8XË_^'g{˿_mf`|#@~|J<pu1d(PvUaeP`>Aa5_10ŔY@[?#D9X83Hc{t1 3~ t40|(Fgzn/ycbxr!Âytz>FTa0uspOwRcdĠ#?`vpra:0F&/??3|:j>#/ $3Pߑ' 200k7-ax> .O~0vzsps,ͭ%AKß?`& F`j9X_}(W7 ٘?xp(:ÄM On^16O *ÌmQF7O B3( 2| v`fa6N^>2H,e`'O//"?3axf'g2<&u { J 4crdçW+L$_47&&n9!^a ~%gYr \ 쬜`?'w  fseJ`3L-2v^eafpt'Q`}W`fddT`fZ).6~` J2q3/?~?Q߁ILCe&7Ȇ߻2uP-TN}.",WMV2 gggZ ₦ | jp}pm_&@o?8dsׯ <" F KwU0:22Hd(T{GspxOIATĔK?#;A_=d?8%)0yq8ќ :<+`S/`_? ~1ڋ  ܆ <@a 4t(y0;ADa ރ L> _|(Tgx>ß_>|piۏcARTARD۷o o=!q_`7аv2L^~rg B̐,jv\|0?dxW^iŧ> Ïo/<+>1c>.-~yptז3J1d0K{PDSqe6ϟ^' y}3/MVw-no_]k"cHUcd`eF<01dacd3I k t0qUX _(ςc؇Va?phFדg>zlxG?(Z×O,ldU<<ɠi + @(s c z6`(J ]] '1hf1psK3(ě T jV0RGBޜ Ll=C<  ?<l[^f; *z ʦ@s"4 51q e`f*F`!~po9CZ?9!1q 3®AAc??2ܺ3Z3H vP^"xw->a``1kjơ 8IKIF`Wa`?J1 + +}'718[3&i~n^Q `+` Џ_|wP:/00@ܿ&J^)XdH 0dbD;\ j! j\afDy@CL<: ~C@U_B/~d0tV`R2py LbNJ* u| p6 a&}( %nà*np]{g1t V~3"ǫ/ay'   , N@, h&Ab4% ,%-yDx%"JBPXڱ3 v2/3ý~: bWϥy%p^(Ơl;CPXs2+I\(Y M$3ؙ}VFTyt * 9-?>1(0|p+`3X W.| `c /aiTΠ%k *'+$4+<Ab0>Ŋ 9O`,*``un~ l']gekĄ< Nw <:ܡ۵V#``b';~>('<ـ2 z)C@ I{=`_Ǡ#kV#̠g0PcQ=çX6lgx֡Yp+ G67 g8t6) rzqA,C+vAR2 Fr*0ee3<|JlOq,?;+ vxl\M6'ހl >10g?jB_ 6Ȩ3pn( eͅ&A0 N6* 'P}"P l1,\qG0zNPD Ą94g㧷wv/z!ɼAÅ 6(fb6$ Û5ہlS<̡OJyꤥ N NwؘG`z?`-S6X< ١4;tCJ')5K_j29 ë-BhE B,6IVW(E P i >3+8Ld}X3ɯ@;ƶ /xz^`4 pd7 LS:>_ח\S~_|/a(/֟A(TT 2p9 #c''&}jF 6 7ٶ2l{ X0p2q3hcf|f'~C3g~3# }k)D5IENDB`Ext/Images_App_HighRes/Nuvola/B48x48_Attach.png0000664000000000000000000000750210133443526020100 0ustar rootrootPNG  IHDR00WgAMA7tEXtSoftwareAdobe ImageReadyqe<IDATxb?P0@ yА@ yА@ 02Q X30 c7(ƴC0C7[Pl څ/kURvf::/?L\kT=-Xn< N+@4O_N9űmڼ .8&~U!EqR@730ɩz8X/j@ rSSZA]K7IPCqnv .2000 gˌT1˛[AvE|.' f8;} OY\"SD>``8|ᅩ ?02$x0||x ^c6=+_Cyn\'^=pw5Ǘ\*#R|Da`8~ϛ H10D_z;a l;D% PpNN{H$/:c[28zXÓ ^bçG@O!d3@PB3ۼX8e`I!Y*p1én~VF?oϟϟn^23D30 8j@1˯2' l8Ñ r|$C0Շ@?;^8^ p:fWN}4/O￘E~?q*ٷk(lI (BQSݞfw&s9VC ?pk5÷?B.3Y`_\t@.C<6Ӎ?6M? H;qjCضbs@P(Β5Jsb2ee8 Lof8>a- 6| 7ߠ:6VBjXg[租؟\ !.\ ,L֯Xf0V XHwB1SfW# &S@ǟHrMC/5/ pc8 *V3_t35k4=˖2 ȰEDbȃ`(p ߁!yO?%/;Lpǫ2lP̰fP tfWgV9u;  Zv 2u &_%`ܗ`%pXao"_[Bmy l`xsl.a/CJ1EIJ  rj "N ~ L\@R. "_-jژP̠#p0m}pl A & AM>\R,c8?b4=C%~``Xq?ó~}yrСvB! b`xpy## aiq4qbs?2yf>>Pc_l6,Õ Kp8ބSxGl^ӛ30<=篇2 KDV*2h;Ó˧^ Lz. <PI/fPk#Oa8ڵ]ZܟEKW3]ח[RgBK~0J b @?>ǯ2pjJG+%3{zkGn lC+qFCzt9!us0pH1W1i2y td{w8WC z ' C~? ONm <6RB ׁv?7720|;lVɿIj ʼ á/cUy-f#^pvwo3fx? K)`o=M?<=xWSM%F$7$[/ûk[nV`ՐF)dD5`1 tcN+)^Uߊ@'!;Ùd y.f!! tmpD_`,v``xtb?Obt f8 lnfw7_ނ @X<Π,mCjާ '{W0k0T #à gɣ``+ر4 yßAXio';cx||O ,*! V ]:ÿ@ǟ%W@Xb cAN/Pd VT*%01<:~~`9 rM6(PuqwCOg!%}BŒV&.X /TaH4 2Vzjg0903<:~ O/d%A:C|$ifU0<;(;UA 0=onqq! _=aRFDTDEE CܲQV5?a0Ѻjc@qIJ1<)gPQa a`@{g0PRe1b) @UTW3'زh&99`3"AA @ǝln`x LGJ 2 @?w09ቑ D`1kSZp@OUU0,]bb\c%Ir@6 ߃1S7o2<1bPc`bgFfDx =Xv}e9#672l t(3?? epr<(A}y${oʠ7m: ''&Brꉿ SS0ò1f0طX'RA/P#>ax?}60ٰ1E yM b!m.A ,E.43h3(0SzޕA{4`x&5Rk I! 0}} f ?0Onn10 1q32Z3&& HH:r&c԰`Z`@71|FH-P( 6 _^Rٖ ׀S0 Xj?K? r ?+J abF)/in2YQ;6GD zaȭJ.]0,ZΈf8#0 8] g+r3#'%\ T:'9`##)iPxjs:#DB PUICArVGhf &BPlLe c@8aJ]@Id`+(cxTP򄲎 Or?L@ X G%kO d&1͜ ,*Yn 1;d;>&Fm!b•?TVe4+o1qHc  t,[YrU9seãwo14ln|e !QIL @=4,H% KA +0|&XytF` Svv <g5󅋗~g1piբw™G5̜ G@+4%1hLAtLMßR30 t 1,eJ7c[Ăg`3*4*`v3é ǥ0M YfHxq 055 πK3sp053E3y&"jbb!T2b6 Xc91< G=J34 xYGkGF }E QGb!6܇!'xTdwFp j+%8t<RP lQPP;I#B&fH8G9l'$ q;Cc$"s)5IN6 +6IB`3~/j;ژ 126њh4&^ H3BDL )6@L8f)_RˀAEd18481X, {S{gDTXZW?M`пޕ }؄ͩĈmdw2#`6$hJeXR+$^x?3b=hȯ!P!ʆIENDB`Ext/Images_App_HighRes/Nuvola/B48x48_KaboodleLoop.png0000664000000000000000000000645710133442774021262 0ustar rootrootPNG  IHDR00WgAMA7tEXtSoftwareAdobe ImageReadyqe< IDATxb?:`4@  001OJ & C h2Y9X~ N=- yifFG$`23(e @2AAȌab, ÷_! 71-=L exLaBCjߵ FZ^g`0AzK Gf?N5" ,bׂ'ҘQ7&goֿTj*[`"A>eؾ4@_1S!:DB2\EK?2 6(^~df|j Tc`6ÜI~tEtD(t]/ûHc@-lo\~=`i~M-@608APˁ'O`ˁics_؀+0c PTwG'3<|79-¦ yovqc1Ui@Gp"+2V`9Ço~9# '!iX|p '/3|{hI'U,å py@Q S-4ß_@8(\9zʡ _;F^Ԗ`g! vax})l}:P9X \aCZX>k 1CR`tˏ2\st,>^+@11v Á_=ptYgn-m P py,& 2 ?€{pi% p ,,&021fs ?YŒ3>[x{֝c80o}U;>PR &fQVclA `Qہ p5AI~= )~O˰eiWހb;k5u@FP.˛@?ý[/.c67 '%ML|ck/3\:Ht&P ~Fnk { )gL8L m@zH0+`&; î-FZ`)mC_ πR~0253öMW{{`b9 l۴e7Q@ 0)A GܒOXj<*@,xzS/( P/X~/-}D>1#r<< ;~=Da'bÅ|Lft>m#I;wޱK`nZ \`RCZd  s10ӪI* 3dZ00dTqm8t`w 8 jx|=y\<9\z쭁{ b1{Gi 2r?yO1*@Q-Hw# 6o1/`1 ?08y ]0a1V ϾCR/@h5Udp 6a7}6Џ ZWG<7._`K6`ֽqï@cwXD,cGKPZ˘AT[J7@,>+$4܍^ ]p$^}0v֫@zhY0p3h90:3 s2|:7:P7 A=_$3 n𗕓G97.=``8aD*O2^i=uuk=I%q`I _bfufFxq! %I?{T3Iʩ 4` XT*b_qIqEK#)-%pz4 ALk \DDb :a py LX,r)i1H;# >C, 4:r;@| >GpaaO^>N=@(ANL&+@3+y 8pFca~y? {g}6 _q@@XU\M>22\ ̘`y  4=tYA~:E1ٯ0lZ|ǠLHhgs -=Q㏛$/&_`'x(#8UE 055xG/{pp]Oz 1 VBaW?3Mc@G}4RWS5A?/0ܺk`9 Թ/th2`t" &L*_f!⪶7@Q {Qh)=2""{RV@V>~7z' JzJ f6Ç\h p/.F&`/+@L@kvKAXwԦU`H0N]ӞzCD.$B=" !f@#sis r{d!j ,#~~|w 55v PX":Np@t)߃[,zO~MPQ7  j􉁵Cq^{/ÐiE~HbjkkdOX}2:[)@NYL1ɌoEI`V1`$(UIENDB`Ext/Images_App_HighRes/Nuvola/B48x48_Redo.png0000664000000000000000000000476110125245344017570 0ustar rootrootPNG  IHDR00WgAMA7tEXtSoftwareAdobe ImageReadyqe< IDATxb?0222 X @,=Zf}@C7e0@ l@+HA<# @ 02t,[ ` {J z 8%Z3E3(q0 p20z\ #kLd@9$)|z+Vзec@\zBqys 3d641e{0p0*C߿7?}ZI }`O#n` 0|r+6uϟ7EXPHY u`fUְN.py泗/7eA _ \1j{. uc/>3L/pj( ˗ˁ!fXTX8\~P=c'Ȱme}̛/_z޺%?!| \Hu=5cX{*FP΃x{rf "I+dfd8t!k`={ӧ@?B lX59)|F/ -Zne PbT@+;&oAvHB j ׏?> 5- ̎,/P/2t@axٳКwPbBoF~gsB`}`6=@T4n@@]kd̨IENDB`Ext/Images_App_HighRes/Nuvola/B48x48_MessageBox_Critical.png0000664000000000000000000000716310133443722022544 0ustar rootrootPNG  IHDR00WgAMA7tEXtSoftwareAdobe ImageReadyqe<IDATxb?P0@ yА@ y 6Ռ+|?O U.1 ʹhI w ,R uU^А;J<yq: 0S004p10?&|Ę@z7za]]>3YX~}pksq@ C/**Ԏe`ze؟{k׮y @@/`H14ZA x``Щa09Cxbk t~F 쒒 ~10ih0x,Y T3 6_,!l~=/p>NpJb>PZ  q&`LV駤0N4 b~0÷X-ePrrbd4| PMW%q)]ܿ={ M(*w?0Ax33ܾ_z^,+_ǏW66P`q+@r;tu~ 3; Lo '.uw:W1@v_2|r^ nln \еO7o23weSl@O|ld6gb&*I`e"7)8T^@D"/:9o^e9 p.õn0))h9#! `󥯑sw9C ?f _fx[_ xxn]p`lVb‘փ&66^^kW3lNK#~++BT`.:URLZPfd`ɬ;A'%@Dz30I2)Na/d󍁁/Ak3пq#d?_tKln Fl]eH+Ԁp `M g 1[W#8cgⰿ)8' !/9 ǯdIダF<[PS#8T l4TpԁX<<:OYr `G[@رR`''&F?L Jcq(#K6NqDl8 #.`.c!JFf&`tmh:l7:X`g'b" Vo?s&_`!j,`QR/ǏO]'m5<#`[0x==b$]DPvӧciaA=i 1GK'܁jG{ BDȣv!ٿ?8jX 8f[:j+>}`S^3B |DJ*A'aa#cD ˀu #Ak=o؇1c.7 q_d ybXI F000Kxck>4A6 ['@X-` pB.A'XD!=ty~>^˗30Xg+a*o'1<]70APVD@lŌ $av ضuF}R 2<i+1a6=&`q[as+@R{u<{؀IȂAtZ&`9W5f?};L2&G>~~`* _ W,P1l~ C@ 6btϟa5a 6a.8#= XtN~``zB6A@;AHe&`Mݻ ,P:.v;~/x 4nl6w}W_۰ //h R=$3q5iis)h ^p|J6@m[艙 T@<(͖̓ }S tI ,l bsӀ~ֵ͛oIH`)'/;;ÕU O`{@ - !.,Rg# ȎSCj 3;ׯ3?p$wplp̳s(9`%*A䝃C2lfa"&F#N>hhv xs d' *fbq9Pz6y R4=@C4=`+Kt20IENDB`Ext/Images_App_HighRes/Nuvola/B48x48_Folder_Locked.png0000664000000000000000000001171310126472632021371 0ustar rootrootPNG  IHDR00WgAMA7tEXtSoftwareAdobe ImageReadyqe<]IDATxb?P0@FFF'ӭٳk>ף7o<ۯ@%bzdee[ZZ1|6/{ϟ?}8sҥw@( AyZ1Ϩq͔5u~Ç 7nЫ۷ozf/^p 3$gH<==UCBB/%%%rSO1ܾ}…oo߾y 3^p@% @Q5 jhhrRΠ nnϟp[n_~/_y͉SNMjDHHH8k/,,D߿1}3w_OիAn ~~:-YAW b PuO5b83HYeOz1mkyn3<} " 'h +\Fp h t;W%>3 c/n`dx UjL(QCJP)=ȥ!6b!]qI1L?RKñ0?Z%4x}s}]iYTlFрam r6=n@FxˠxGnh]A#h@0ư* ߐr83?0&"yeE8x30̠*/t/8 _WA/c 7_?1\00kW`14 @eBGQF+7]ߤe aH6O#i 9Di D= ɤ 걗mVAlt%)|&?a?Bj@@x;-8nZ+gƵ ~ C(gc>ȡ(~ P1ر99cAx/ģ qP̱= ן~AcϞ=yd=Hxo>gg!!\`&Ё5}r6vv"9?PG g< $1a/3|A1:~]P#>@Ŀ_O>| OL@ؘ@? Ae0bX++P#m#wáza@iXpK 28#7_|ׯg@gw?߁ @3A9%Fϟ `0!; <Jlex`@cOH/&~C'0֘^>p'V?>oFEXzeU2X1q %tOE`PZ9N$ hÇ?*ʠd=!N;]@<†O^|ɯ/pwm\Y?0&?GHቮ>WP@_pP!|l2ppp1'0g+#yҫkuK3xݺu`mӻXmeABEAP_|>=}dj;k27cI*`u?QohLB"Ƀh``#vzƻ * <‚ _?b7!@,2;w_'+62xжkbAyiO701[ۂ=:K/3vv ) 6/b8, l 104GMDDl@0>~|pl@}_B= ~slXUA5à `I0jk3<:ፅ;?H ƈπZw?Dό b -O.|bxPs@=qy"8-!VII>>&66H6mz _f7`EtOZ3;8Eh,`` |1|l2^{ ꍽ5@03%HH2~;sXC`܁, #00X:f4WzT5g|ӝ F(f?P0K{_3<{֏ %8X~ 춝@?@=,0E?6@mCDRXg\`Op"g30p2║a5bX2~ak )?÷'p-{*+ o0.A¿u,B@7Hs2= Q!O.3|~8qvpӘ1/FAXvLW \ac(|M?@`i'uPL,@O2&Y PK6 jĀl '0݂(f0?'#_ÏX>~b`yx&```ִ l >tt SG21EK2dO B {h:ʨoq r`ܐ<$: JJEO._@ ?10~~LR ?pSyU ǀͶ_? ,r _߽eHKWP2`b`~%c O1 }09P 0?l@s7#+362lZߟ@wo^3:!O3+ `A),:oseͿ/O@w`·Oji1J`Q\A:2.!Č@ L/f ` W?2|T`gX̲ 2>wJMNaaPVy}qXG5@```&WWu.))]o/r)ĈfA|`>bd`cw8' `U# ^30}ɐkȰ6P)n< dxw޿?o<>CHc7oTtt>^O#(HH0v.ric'vE Gϯ?^^Po𕝉.K+GYU23?|l$N.00,޻7G:)I_ T`6p͢w~ " *qX K 2| ,W~4 -eB3(3$0JS)6IT=؜7B#SXd~fؽiw ;7_~:ߟPG|:RM"ئ^$fwb`HdcK1vZdU :/0i=Nd8q?^?v߿@,uoC!9/9k ac`[2LPJHHLJJxW&-`BR W0ԑ@fAfPy@hЄ T4~6oAC~ozV0t)IENDB`Ext/Images_App_HighRes/Nuvola/B48x48_MessageBox_Warning.png0000664000000000000000000000627310133444022022412 0ustar rootrootPNG  IHDR00WgAMA7tEXtSoftwareAdobe ImageReadyqe< MIDATxb?P0@ yА@i.+c`0vfڀԲ wFt|3++ûՁiŃ;5- Z$![`hh28Μ8g:OAF DmĠnmʠ DsR@@)B2eua`{e-uw'$g1\+à30|z`gP `Wa A j@Qid ̪~oXD<XhV jy@ D%CC:o@'ܩZh04!Io${A @0Q N Tf:$ o |pR ɠan3'B)i-,,L: ̒r _B /_bb xXlyAʈR>Rdq:pPHgn`Ą᧦&J 3[+C2%I (IB[Π)yWQ @76 (我$⁡o }^]CpQ Ĭ<<  X9M %,Az ȍA5 H;8yf`PSc`cb?Y+"--X`k((1J*D Dn 4 QVreT: tC[au fff --- L@1zx쐤;Z L@2DT&I2(30v 8dQNar :::>|(*`l l#}7%A!5UEP,8Mr%Drzf`&0AE\'0$..fXΎYd0QRd`VATD{ Hk`%j1H_!<) 6XI($$$98 P,xz20|u2Ơ^)y Hn]L~ L<&4ĎXJJ J0 ,?}a0d @Q@í,RsAW***p ZÛ 1^C `?#6 Q>Ъ|>~`[<&b:FtiYYY,-(`ݡ#2rq3H+7`J:R)Wwf`yZQ ,6#'(P&PU`Ma&sX2(2 @/N4[>.n^Ïo`LR EGk3\ѳ b\ *bX I8HX10>c,@{ l06PD9"F#^q12/`z $3+Pb y% Rr ?kL^΋w?`QAbP Op kf Y;$d= ,PAŪ|@0HXY5 2 r@yn6r`1 `/%%VVVq$``We1yACTT6ŕ OjaY~ݼ,‚OwS߾0:=nF0BkapC̒ b{`A1KAk\ Zv d,3 NF0G 9 Aʊ Fv4r /x؁;$^<ʠ%$ Р>(<@PPkb%H1eol 8XP RTKFY`>#P䈗h\@ ҟe 8@vL|;90/ hc4Px6`Ұ2fy4ß4 }A`w ,k_b`68@gE0h1\?a dh1pM`0A Y!9?J ˰4`Q͈ 9g2.O VfgHd[~zAo |h7_$?466Z=5Pf@'` 3o_y}AXJb9g3"M|Yfâ^_ @șx0޽EC TLGK҃f$_Ȝ ơV L=@ yА@d"?VIENDB`Ext/Images_App_HighRes/Nuvola/B48x48_Personal.png0000664000000000000000000001111410132777116020455 0ustar rootrootPNG  IHDR00WgAMA7tEXtSoftwareAdobe ImageReadyqe<IDATxb?PĂKd1i+ 4׷/~v'cؽ# F\1@'3OV%J@݆_ł[Zğ@[ ex8Oڿt8-$9I1MH2W `g` _@exw㣛xAO??E8T!bѮ.kt0Ё1б?@`|__2<ڿԱSS}?I@큣9lIsC!" r<AƆ2vl޽3}{@99d1>Zo%?APef``bbvd4#Ah@t<1b& :@a)| 6@dyF1YWrA]L:C90t!b01#;P9P8Y&h-f(f L_!eڿ IL~B8HHR?%T  8€V1+ =/a I#'"m93t?qi3Xi b@yu@˭"Rj?!E%{T ؀xxH,_`RbbPUדeg H  <(2333?!"rK$O<ƿ!t`*2p1+b@ @$DXX!!Z021#?H}j2{ ~YYX H_Y3g:rdsfPy?~C=IJ Cï_?4pb2H`QdfKY!;xPavz?e}]0T']?"W|)5RYfGgUH&;晿~ƿe˿o~}&xDR&[˳/~ C߁l ftN@a3 ?={ړ_/@@Z{ӎW.=9!!"r4 Xyo/ ??fT"BP,꿀i+}A 0l: ğu@0T=Db&4\Z/Z~AJP ؆_@Oybǀ.#b0@xA7>f1 V2)XSBcE%0 *.0*q~6??|DrF<7c& 1v38 &%}Hq@1iK?@v+{ۆa6UC-:uhkּ41")OreX$9Ó?'1W3~ _\b5o} ߾g;|k Ͼr3he漒Ww2pFF%719>kAk$Õ;_̽`b` ,ˇv2\ڶ..q_|`bf mܫ \epqdvcXCt)H@4?ZpL by̐ (p)qYnff`Ǡ53] &``8/ؾ-8$\Ha F Ynlpf{ہ*JN @N/~A^ɹ<@l=AB\WAQpfd/ y#*cxX%}{ d) N XH~A؝U`dЖcct`~LO&X~8?hg zyҌ w^fr+ ÏƧsd~A $$ĸ2L_cPTVf`ᣰ0`SIN`Ǜ31@߁T6 /c*;UQϵC: ߿#,uX8Iы bPUg b1z+0ڄK`1 X}ecc```X/@У? b -ګi'c&~Ow@͍̃)?xXcԘ</`'ٟ#;003II1Kw3| q8 bȼ@q A/J21(kq~~b.'w2HHp3|y y# $bf`_`z>H @h7; -efVKc$e  珉0Ck `8 #fa ,YY~_~ex%Ļ B OճO`?>}adT /P[X0 $? @8=̤' _KnppI6~3|X-Fg}!_^Fpmz``/o@;xAHWJZr y@|} 4?,<'`r`fdPL2|dçߦ‡X'L f|&9? L,6't # N$hV?3o`MXȳ0"%w2 0h>&PiC@Жg LN\p/@YJ`tsr 9Ф* ϟ0Hss[b$'c 5'nJPS`TVb?330_/nBjT3h, :FAHeeu˾Ӣ3,0'PK:Fk[9ГaH-"1n1t/ˇ3|3{U{R #@?@g+g/UggVce`,,FHF}S;@ '}; RX%-h'[6XƄ@b-!U ӻᦼIENDB`Ext/Images_App_HighRes/Nuvola/B48x48_KOrganizer.png0000664000000000000000000001451410125245344020747 0ustar rootrootPNG  IHDR00WgAMA7tEXtSoftwareAdobe ImageReadyqe<IDATxb?P0@ y `ddda`e``bb(.'G_0|I?X% iiL}[~=e˰ F2P? \ @`30&ǨWij)h0ps07߶;U8 y G]lfP3@`g` "Fz22a9؉=?;'E~=g7=-ŐT6meOk"A?+7#/7@_?eͰG0;~b#0,1@`: 4-R1CL%g?\fZQ, >e`&4D`$CHVVF.miu[ 9 L6&`昌eoT-ߟ XإDYx؄XBD.|`a軼I&7 | @O0'@ObV&`e-` * L?3?#m& {OYzݫ.@LxPL @eo]c(3!om(_W.%?3? ?!3Ʊ asvCyõ?>FC{{o ɳ1S0X`0C;G̼ww`J gPaef.`p&pHq!-p( &` `W Ì`Pd`ffb`eaa`0cpdraޏ9 : ?cx/`&1o %L}d"M86 ,YPuTo-GL>}=a=##k?0"?ؘ'Y[&[Sbdh 40 3ry ˉ ?23!p(QC[" N.fxx1#*`b`xT!D3!זAJcC" Ñ f4b({M zxf+O2dwD@`ː,$ d\@03Ddho z2\ X8_a^F?C*uW71|߁u ?Tx-,16X8Ͽ0HJ0: XL{FW_38(Ï?? 1̈,<A@M6/ f)1I_c8⥭&j!"_34n=2A@AQFϞ0kh- s?4~0mpAo0y*V.L38#3A➁чG {cEI *R78&= 4Xg/33fx`. rl ;߼dqu ~U ` &h a ޼rĄ~1I}fXr(+4+1+{f9 IQa&P J1.=x%) kfx٫ oaOû/w}lf ,Hb X8zп6O7?:  Xn}Կ2O\a|×^+?p/G~3<݇? ߾c7!Ou%n>7'! _ePfzAa +0LepU ǀ!?e}'Sws115qޜİ`rn F/o ?~`8|3/3, 3FEyE`̰0cD\`"ư3h-;O)M KfxGv72b!Pc , _ξ0ucG3s}!Eq^ ?2zAM  `l 2 ḛ{O?mE~3Jg8M.y j\/uOW38XPb(Q0 Xb= ҙA[~2~dì-ױ7 _@ hFdCr9Ykg`p d`!Cw /I3|~`y_31p3[@E aceT eXrb -CA"0V0ldq@U.??k3,IE/܌ԑ@GO}鸳lপg/_>0AUA^AV9# `b,Q~O=p+YO?6!Iˇ!8@!/Ȁ!RՍ_+24Ԁ,oY8TdIį`C >~b^<\ _l?1,>ܜ7C .`u^POR_!Pٗaɻ w_b`ʠ+`?PaX)9)Ltku^́0V??aی\q8m>2_f3$ wFEv9i6) 6afp?w7?k?0 }fm/I2T220 ^BzT_P5KF뺇 (Xրr^jbP:C_`> ه? 2 . O?ex!>ͷ|ǰv[  N f'y`1V okJ`; ,pX?H;R+Z}Ĭ "|>2,>\߸z ‰ص`fgeacbq`&u`xMЬ3| 5>dز3ß 6`mjaC,3GhT`F ]T$BȐ"ur`)O 1]&?d L:JP~AX!An`ej`X 4X_3ߟ2Uga `d}a d|áǿEՀS+#c`do{(Н/=;`T>6T<` Tcgx 2<f;A`rz ?~g. o 0`OK1$1xS( ֝x*&̠#`o&e*Π!l]P22@`:!P?<=zfk]i! I⃯=1`Zt /9U`1)I`egflq1VN`G\Aۜb>/\ 4Mfw|gf0VwYH`dK`'_Q&%L @ĵ Xq<03s_`6|p;G2(J*< oK Vpu/H2zg1qbbPpebF@ ^8l _o30p[Lo^3\ƃO ‚ j "~3K"^~Vp!`H?28v9X$$@yLÉ.U\~(C27#$⁻@i ^}.?E8#7 L}lqp ˝ (VJ@:kP'XcBF;l \&J_DVp2-Ym`bav`dȀ P< %#P&W>TF\5?2,7~vKcP/]$ QP$ l;u bqqn9 ;a /0d)p;qo3q30 =v!VP~1309 qi?EԃW6ΰws{uD2f`AKWA,< A ,Yi&֮ o3@Ao߽̠-} tX3;FMX@c2 ~fd`&]`X Ge8pV6͟z!6-x; vj Xd$X4xe#320  660LQ;~ys =Q@C73D?e:Ew v& g#` rKTCW`/0f ߁5^ a`7;̍CAc6 s0õt zOb⭓ U03pz3.3e8 t?? :2ҍ3ة|a0 /4쯗'@]I` 16s/n?B+R/`w+gaoN>@1: qJ-+"@30H4 )ůge`3ثaPx͠&XG| i KfCW>cH`C=zۧ@6}?{ lE}hV r;@40@Chu6vەX䁼߂PJ|a};3"F"kf`/`+>o^ex7} ď0sc`N%XMr;@t flHl*0A,[g`_F,ypkA7C@]gQj|ĂK'8ꙟYc v 13|ֲo| T/CCC!(T?! b _e j Z ղ쌲QsC?@G} i8W A@ n40؁f7pبq/!V  )lfJIENDB`Ext/Images_App_HighRes/Nuvola/B48x48_Edit.png0000664000000000000000000000373310133443162017557 0ustar rootrootPNG  IHDR00WgAMA7tEXtSoftwareAdobe ImageReadyqe<mIDATxb?P0@ y 6AFtXXաXX?3  ~Jn NdQ``jĈ;XJ^$nҥ^ MCW @,8ǃCH?zo:w+JS`,^n`>aELvvفFc@@,8ջ ^` D;nO2\y˷ ܜ R 8>QCC >n͟(C*رXedb`Je ~b03d5" pC+9A|p9^bE%ŀ&W J:@/$a b1*!< PG";2PïdCP5 XhlO6 ȜЋZ\ X"ـJ 4QbM/@,N6j% z&pz u$9R  Z&d4$Q;40sqHBdy" ֤ 8#&HAJ(H۱ՠĔ6(IB c@,ސd@B68ԑl31(@BIH6 b!y $Б?@|ix,  ?f/0'3GJrLBĂ+|v&3A  m0Ǡ8GG(.@=҉Dp0A\ZЋE\Ɇd?f>g Q!ـhYw1 a`2Ƞ&/;(q%,.\ l; nnN5i XU,@,|:< ցWɆpʺ~ 9`h2*e`d?@x=ni_GcYIN60-`J`& tO@W]uo@?3 D0@&`%|CiRŌ(?bdb0Tep3`R?Ăd ߁UPJ JHl1h>vMR"XC*d@_1 ?<riɠo\*pk)T@K6O+Dl= J&Jr $ &MQp]!P! ,^PhJ[HbCl@3CАg E76@f)_')~a8#'MҌz136vщ~U ҂ L2De@kjEE3 ~2\ݻ9 LtNffdg_^/ bk%h{ CIENDB`Ext/Images_App_HighRes/Nuvola/B48x48_Color_Fill.png0000664000000000000000000000643210133443244020716 0ustar rootrootPNG  IHDR00WgAMA7tEXtSoftwareAdobe ImageReadyqe< IDATxb?P0@ yА@ h 03fbb`012ׯ_`>@8ҀM:˗/sc9xC, Z%!V nL^^^֒ &0ȀBnP _ ppp0033e@@rrr  VVV <<ѠER 4== b@䣣ܹpҥXgk@ $x0t[EDD***Y *@AAN yyy %b?:t 0 0TUU1hkkCP( AIDyRF %%`'O+"dHMMe8{,ؑ G߼y@q=(` (@n  @ yx.qY=0@^gxC0_lm.3%(*A5-(c<=j:Bݻw`=Z@1C @P ^`zn7XN [ @c70dz?x:` \ 1 Xkk222&( ʜ.9m$'^x6   ǎС+6{YV fـ%6U(-,%~8^k<3UkNИcDpݽ/DAaBY`DXf'bA<\B$ʩz;|G+1,~;w.X] | σ3$8 GJ:XuPm,, >-x-#$۷Ձ1 ONuYxxNKyx+$^  %`+h"'8@!E:n@1KpyԩS O>%@e! ^6Cͮ_ׯ*rJHH`'`yTjmٲ ` ΁ 憆 DϷoႠ9_bUxpOWl޾JK$2P J+ 1jS 8.c)566U.'|~23[-HLl翯_@-PSJݻ /k(Px#@K!P&%z߿E΁b%޻w/UhĠRT%&! ы߬lw= \4=Iȑ#p71l%1C\X6caaAmP=i@ jl޼|P P o2V*ެLhTu T`ڀ l35քĠ6lpuPdPhb6%P00Ng`Xs)cb lMC[ ,z Up*@lJ0lڴ VME}  Xe 000  pgCQ`|vN *x5@l /Rkdz*U L?JM@6 X`I 8 ,vP<(_!B'+WM 9Gvc\ vAw8ytH`wpgO |@i4mTX0;Д@:DXޠ^kFA=2Prrzrr3K81\0_J:q |@# O@$h~ ;HJ BOa YٖG@: @1IDATxl 0:6`kCԈ*q "|qӌSQD'A@wW,Z lSծ@U7p dOJ+SI}y Jce ٺ,\| B |, l ? /dx'Ï~=xic;J1@A2 F2b NZ$,f`&`.Ƞ TR!S71ݏ ^}J;4ҭNJ  {hPEꂌ &B | DhF  1 pfol#C^{h& { (,~-SRMRa2:;_@|xÛ nfxv-0b`cd_p23ȩ1H11=4K70Xsܥ7/@G'"2@3X٘c|<y>2}wn? " "B bb ga'^Ɵ~11`dfP3aec?v!Âw޿~4@Č ҭ0`0gx;_1;yA+,'30 'Ý{; 0Y2|O Gg3>:40*3i2O?ox Q@Bbf.ĤfI JKiYa'?phyGv1D 327, L^l /_f+%Sc`ga01`P{v30 2`fgpdz-GXN}~3 G$ Ւ\ l|| ?00\=Ē ΎΞ .0X f^AYҕ JR8pcgfg/`fk85` DX,jc`gx w2+220lݺASS\)NCAWXXAUUAHHb˗/0_!22XAOƱ[ fP`n+pkO?95@}Ev/@13C j󯊍1؊[B 04 CN: 09c X 2 ~ &%SpLrp1 0O * 1f.pC?Cj {A8 _ f3Ve O0f3 iP:SSScgNHڇyHHu q< 3B @@12_GO." NYQvSG>j>s3@13= ̴KdT-nfax;Ç'ʲ$i#AA{Hx"6w/ԣPjyDKk / 3bbx=Ó[oIi>н?@ &H ĿZMXû oWb}%TA8# C2*,B</y93#hfg!jX|>A>UOg/2|& c`cKF @@=#Ve֔'0~81'3}\rWX 6ѓ$@|ꍃ 2g_x=P098)  }A ''͙>r 3}l;Cxx 2\S"B  wO?q@E/6`5` w!ßAX\T;>p,<}ŋ j⁊JxRyI7YaϾg 8~d},u U&?:L%>à>C8;''<%ՁmF`l;8i /0+_2̺@f ؀no؁3g3\qކw`PTGlƔA[[a.PenǏ?2ܔaf0O}99!`J` pq ,D^dϟ?vpu|vV`373'@=l5@ rާO|_?`i"((0mR󂮊 7n`ყ30ĥ :d>.'Pr{=î93h,?ؼdy ؙ3Rl#2rT'@髩fPga UU,-]O`3 hP+0Hzl? | Vdd!)X2?hFĉ yxx**AE pA x+× r s3?X2q1pʊ1<{' R4!Wiİr%×ӧg7H;?C߁/@wP@zx 3×Oߡ ! 4{7͛2p7 (Qc'G~1+Y`'o@1z qo& ''mPhxοhx xr<\p=Xy 4t1k* h]zۿ@EgXN|g`g'`I ,+W&(=w,E ï3~fe3E!K`'8YY.^x 32pP=t]u@Abx4ý 7o>`X|铁ͅ`π c`(V;;YZ2:800x ɓ' e5k 7;XR* 7> eR<0Ƙ]d_mSIf6mLL̠! =P}IJ'9dxz+6Bo$X?0<X7;* b ֖6DU aMNU$ydC ,''j 'g~Õc@t_@@0313vLOl_@_3؞yKٶmavÿ `kiP k`+`H ( `XeCbT~xa{ Z ~}e6^'d lCqJ3hZi 1NOgwç^1`q_$C!bMfVͰy]`s]\G;v;`7aag) @_ɼyݘWZAFAVX/< , 1}bٺUP8灝/v h >d(H@.5P "" Űe{,}cd8{'Υw 4; @ ™Mh׳$$p] 'm^#co2LL  5ؿ, ,0808q%yf 0<&4+w?.ϰa#6IÀn|^bfF#`>qrH1Ȉ21ZH0|Űf[)fgw;o¢(kPPshXuA%Qen1I3x:u ó:;K(m@x(~~t6Q^)`L 2I1l\{ʕ 624349@c1++G&w}X\}=bd}?] \Vc+ 34w8_w ( `i%*po˗?`wPʕX /`vŠgg !pÊV/{6h)h,اA"VPNbð X9h31x00K20| gO=fLǬ6?' 8طx nϿ| Eex?|! *-K ˷~cp u%+Sÿ?2/1%uD?r 6| Al  "$,<,^3k?~{o /]V`7ԄL$Sȉ a8[_ @/Dc3LJf&%QENCnSKu10;d>ͱ#&D?o3<ضa*@ iLF60Yi0Hɲ11h)032H 10\쐮OݯA3Fwp/!9>x_b<@x@'2z1czƅQfbb``bd/?yT~ 3w2u@{B;P1*LF@t"S@6 UH~@G?׀PdI@e­ ]IENDB`Ext/Images_App_HighRes/Nuvola/B48x48_KGPG_Key3.png0000664000000000000000000001205710125245344020317 0ustar rootrootPNG  IHDR00WgAMA7tEXtSoftwareAdobe ImageReadyqe<IDATxb?P8=@p022H_ ? R?,30xu8^00@|;L fTpo4>. bXYDȆS@Z]YRXA]_ǟ naxvëG/>xoM @|y z@H1;᠐`crTSԳTeбPdPVd {~|aaxKV+3l43*xd7 _<@px= rtLHapW/21j1)A '7@+`{ _at5Cǿ~VfLd{T #d̈4'nANÖ= k2((2lqY' zz  r0bEN-_~_`a'70 =šYP % u @$ @p4?ӿo eXwP]Myy}u?0xa߾ ke `o/`j*  |\~> 8F @wga%㯿?>Z 1Ă=0#qjFnF[YxeTUXXXy ,,+3|ӧ ϟ`hi9!3_ 08cϏ? B?3(a#cЬ, N~eX3߿UNGl{j_% -l g\`ضm7_m^^>}}-5k2DAD:s$(A03BP?0ȉ33(*X0j2͋Zs7@3qo}  @3pK}?ý{.^fO_LLt֯_Cjj~PA'PPjF$ &F/4J1>y/'v}U=x:{i wQYv<\8G!,YW]ȑ >|Ƃ<0)I3 caɒE NN _|c8xc`|C߿G  <3@!$/Ҥyyy9 03`h''@ `s œ۷nxpI%u>ëW<+íN:Ǐ99:_2 ,WN30=;,CA!hi{ ""׻Y 3CT:4XQlll`|%`,b3LJ˗ ]Uɯ h`?߾00~ v˓_: AKի@|K @@ ,R5$ r(0?()h $ d33{@Os0HJ c!<}N?~EXL@?~-{=0\=Ea۷_ Gr@}߿vJ3Yo_a~P3rfaa>k, ;@K3g`L0󃴴0:ف@\\,v30C73] /^90Yz LJr@ Kg .ԔAy2엑QB@B/֜.ce9O 0@1Cp++pp5!% Z@|o{ÿށCҥ 0Yax09]LI (0px i%i 9P4h k.`tZ3cEEY%yy!pEt0A! ƚXzO kn̈FHj ,uW utT= t ~Ap`_X@&H*]@Lk:`c1ׯ׿{O +Ã00C=0rK ZFk7;I,X~@{W28p `QPi"H]P2""8?u..22Rl V UU5O?=t{t #Ê@㪌fsrrRTf@NvXcٯ^=&pON489v#RA馦:}eb+ /_;@5Yz %(%Lk` ,O0H`ŊXG _5S`wqX1sPLu\\ r>K3PЂIPF{n[;lQ`Zl@w @3]ʇ͇Q==Ø_hxpC`xZ}\`quz j=}\*󯀝Ϟ} K>nppp-ŀ *DV 44 :Dtumx +05KDPgaa6M1߿ IbbJ;WJpp}P,2=??;al&8߂+JaaQp@yV$} 5 li*o\uWނ _Kr@Qx6z5޼y lЭgT Yp_ ,lV ޑ|@QO6\ r-FF6`{^0f`m~kC@%5vU<^t< \P=nxxO<v v9a Q>%3\+ h{ ?qy /(:T^?@07?WOSN1t!W_Sg[EI)V ^>QQA.a~nVIAeQ6Ev!6aVV&f_?=>b`a1c>3 xa`+Р!SPVmO+7vv&AQ1A>N.)A6&iAvq6I~6P 2q03r00m4С_oo= !age@̎/5,LJl\  .4ԁ ALZj  JzrҟRd&(|Q:]`1??|qq1#542 ȡh䂒ct%ٿ8 ,1yby9AIM_Ki ~OcZ0H3"BK, ŠPh B+x$yBNfbcfcbbb`&w?gvg{>3ymN $] ="A3R 'A4' 74;7+#+P X_}3:@__o=~ىIh((QZRBN + E1qa',,,#? L< L, ?bGPv DcO^q?e8P߀H37R-!:HR2gj$ *Jگ_ :?30d_WMz @d߿F5)@~l˼6=>+/ p)S@'QfFDt4ƀD ?:"+ϯ@7>8ۣ@#^~=럯,e,D (~ ^g!Z'fg5@ }F40Ty iwP!ç<(/__|_Yi+Q?g{@sBm u4, ǁB?fG k(#K_7 ?OGBxǛW??y/e 1.`47A+cw3EJiNdf&h(3B0!, 9X,"_gxp>0z02Ʌ n%2b{o ?y;8ta֝`|`_D +>Ml0D7R k'2|i??=,X1~~P_*qbb@W߾;8A5$#0=za͉n2$Z_8uR~#xXg^2{3L ;C XP<+з;Of,8@(CZC E`avɂ|@J-,RB l:yar '`ŵÝ~*}BU 8$A}S0{XG ]PLA<t'XL Vcʑ  ߮  ?>+0oOw(鼆N>zßX@Iĵ)TA<C`O8<ghfbfUbX r҂׳lX bۣ/OL c`ub@BK&x: 0X#- !xgo&1{ Pd`q&k??~? Tקo^+w` G:^fJCG&H229dЌZT`KB #23da8}ANAAKE >gXf@1xsW_?^@2\@_PQ bAO$6@ 2 V:R fb I/ |d'׋O[5bH_( `c{a%0.@\ %PL 6+ $3f`y۳' O9d 3|+2|ٮ@m <ˈbb *T5 0/ndJ1K,6&VVfbP_߁u/~?y >]X 񯷟~y'?]vc LBf&Lt\dĕ\ X5VNfv``6tXXC _`~e÷}~BG_} 0xl}tGh@iP}~!; y$=gZ J)3| о_?0(4 닯v@!0}G_o> _P$T"_А -2P.\ŝE}?|Q ?1: @MߠQ? '@2Z@lP˾EW$ߡDAH+gS`1'4 Ɂ4s$>@C~ h{ h{  / }kIENDB`Ext/Images_App_HighRes/Nuvola/B48x48_1UpArrow.png0000664000000000000000000000463110133443760020354 0ustar rootrootPNG  IHDR00WgAMA7tEXtSoftwareAdobe ImageReadyqe< +IDATxb?P0@ yА@ yА@ yА@ yА@`d4E ̀x2 q%g0F#+W`5U- Z$!v r<;; ß@%@,Imh y ;&{2< \Դ  .f!^`RE 0b1@@A ~31*3:[[wXfд6%# b)`$Rq3_  F Co _ P=0I *(1k2Y'PKu73|pl=+?!_UCRz`Lc \t``XpM7d@x/XD?0&ɉ"`o_j͠*pX:GH'`| X8@A L*Hj& r2 '1\9ta*LK?!I#$ PL= ēu@j@5M|+`-p@ǿ9{_1\=qj ?dp{` tԴ, <"t|0&< OJPaj3?õ).Cӯ wc2[@ּ ^a6 ,|~u=bbefVa` F@k3`, @'0̀yԞAIM3~o g (D*2>'C Ifx 3##WF Z0=1 3NB @.0jSI!9BFSa`]pE>c,L%@0$ N]p],gD S.f`yy bdr&Q"w 5\ -nf` l߼ )q@w]N@׭:n2(@3[{S `/+=")' $% Ŕ D>>\`¡l:0L@WpA T`l$1L@O,z\C֍ r5$) R/.>hQ0o@Gh 0 T a8p ?A` ( 0rْ &FB@?82$Oa 41ڔAs`- t#(@ c젨n\(43 Mc`w_0g{`o*Sfg0*ejfGlN `g`a&/1y׿ ?e/^q<J - gPIJ:67>2ܹ?0䁑_3I3T/ͩĈmdA e',؀?pXbq WHer(i dGP cVD-m10`.!- o>!# Y1H J,<<ļ`T0̈C< Xb-`; :`3`&; o`L| 4#hL` i@`B ,&@;b3 ,%@ i!!!!ooIENDB`Ext/Images_App_HighRes/Nuvola/B48x48_XMag.png0000664000000000000000000000730310131465444017530 0ustar rootrootPNG  IHDR00WgAMA7tEXtSoftwareAdobe ImageReadyqe<UIDATxb?P0@ y 2(Mu`aa1egg/>|p˗/~'Z~?j;9򀟟=S27fab`aff7çO^xp7ou֙/|߿ <+ `a`'Û?~o301sp0p53c۷o[^|hWjD^^^s\\\lmmxp_^}d~30A5OmU!6C2]'~z27BCCt5~ɰ"á| <| Z L $ /~>é+{ gEO_3̞=ܹsShsJ<r;@􀻻SSS>0?/?9+$+ddU20p- VB e8{L`Fo*{F'@n :^z 721?`j`r$331!@ L]7zd5ï m޽[ ,U$'O@Vwy]m YdaWgd0sؿNt`T/&#Ű>NHnn|`f d@pvvQSS33ڳ| * `ǀ@9/?~7``g`d.p5ccsss `rx 0<ʚkgg(,p5/ovvF!`pCc'~?9̔|fx!(28=aZ+((hksÉ RR ?I'4Y';åodttti h$zˀ@(5ɇCHgn8 B yXbђT ,@$^e 4dT̕؁/ ܼLD%I!a7Z@eĀIJ @y@H@xh0~cfcd`Zv\~@ed`SMف42gUcx7????RFx Pe) 1&FHy+Q=63#&B@13@ ?Ó_jd̤Tl`T 97$#+k 9Լ`e$PY 1i? *韓T Z&8ʂ2#< adL} 3 g`3`&@(0żPKZ@ @ft@i_߀ _A<ڜ @(k3 3X4 mH1ً{ \ Ǐ5h/) v?|" md!70iqB0φʁ 6'4BA}*/ãǏR`!e @(!` g8Pe!Lu4F;4BcT@[O^|c$dr (=H?% ]~p3 3 ,iTg@M: oXL䑯@sn }ڵk?%]`s)PgR+2B`T~[9sO ?;,L@|Pb; ##p1w:؇c7R=@荧[ MM V`)+88-<ϼ LF( !P .[ 'ScǏ}%O۷dz/~ ˯K̨ˆƇfH3 Ga`AHXȑ# ?|x @koBK!9[իW[(l `xO Hx1ʈ|ù[^fgPdHHLdxۆB=de`x =@: am ?' >iFn1.G 8So@g~S ϯ6xàl~2TTa2bx R| #r X|bn2#z b O6/_x[6ɹ=` !!!+ LĽ~o_z sw%-_?_J~{jͳ{ "N20?,x8j$ "Z^޼yC_Qz yoSh%*?KW7z]URXC> 3h!E0o(4ɜ|Ow6WD:9}X^(怊*@K/hXȚl0ʊ_}2!1~`Y~w@O{= H@JVuFA=GygN`ӳ1lW!1?-`0WNx zfHG`Xrş: > [Pe`Pk2?xN [<@9d PO>X[9>5v4ABh<&' 'ÓV3$&wuPd =Ow>=w+t|MsKo0< {@ %>C'^s13|~ٻ idO5#@ycP~҆w>d8 /X@pO承 OӼ5×yɰ{@""A;`B/Ud}+(0zQ!@,T# E1# 4XXX~7ÿ?@i0fd|ļw%Z@xZ_عԴddD$Ex8_3z oU3i GjG#z@ LUtd$L0 ?dҿ;ow0ܺ|ɵ; EYc(/HIBDd`Ǜ_\ݜJA``v?}  ?_ wo?b(û|pDx HIB@SW̐!"ȘASAL6/|c8y6÷_gRg`afd_G7@n> ۀ(hb@z@ 1wb 6dGX!n{=WICuU .fX70 = 3 +'G$|Ҋ b< 4hVR" ف! " J􏟿=xБ #+cD9ZV8f3$û$30Hh3(XY 8D@ x6* l;/43? FVyg ~c2cPY4({ {f Nt ^.v+~0 & faectõ'?8XjQb //%5+7'0k W }Օ\d<$++V&6^aK cw C Bdq|g&yUuPԋ0  Qg12RgyG`|i1~#=b7DE$8X4 G  %o`3KNeeؚĂb%WDOR'!N"eN߿ * X1 GF3 #'?ç +m.; px1D% e6N÷082+)t : >;O _ٿl~>`=?4#( @|)%)#&y py@c`JMGndx?C)4 # ax Ç/؀!vVN66 ̴L L gsOX2J g7>wnnNV~>F[ͩk255} ,`Oȃo?dP`( U{ _ ni&6{1z1?pL'?20s00ߊ؜ @8J,L  ߀ao .fPr`)##p k%'?>}j%'p{T~X@ǃL@OBS G 233TL@ת Ӷ ֟pX:L_IFAJBa١O +b`c@oBH&$Ai/@458tjTUAkHIX a/ 7>?#01_%0$)`] kz1P^}Xl(j`HwABء}a`caPga`gN`ef8pxL0B[#~ L2?d@ ,Pf l \@򍁝X| }g [~0z y`?M03PہR{3;!]7X2dLہh, pL'^`_WG̒pO_2|F4,!1E߁}ϟ203" s<0)1=3+>'8as(@WA /e "`CQR4C=.*A^FkCw2sȇ&5lN \`}xz0X%Zjy?, _I= %6vn_ $IlN \1{~| ܬ BXdGdtFH GȎx, ,ï'ρ;ͩ~r.88 274<1=9c.~`ae@SWy0zv. " -̎ QТ ^|bfȃC7c#|co_%W#J+T@:4>ۯGNzŸxX #V$H @C*.x(j&on05+zp p$!X2kʠ!l]w34xd? E!5?`d20 s12_p&%SnI`t~?xr 1_ pFX([;zZAJSAK^棷 _?ebeegp6`Hud#P+$J/>24EH3 Շ^0x`3B^@W ]y3\?<@؇eЅm],lbJ6 b* _5^F30yI=ue04 vNpFz'O^` 7/'(0:`ψ9 xjlp+@;2w QXv{a_*002|?ҧ'JV =+>J<80Êc'`v  1x0@. e) >篿06!QaW`— ߯du!(|&$ G N:>}+!%>y``P~Ƞ=ȠrԶaL~6̬ECXisK8 HIrИ);$  Lz @|RI10'2, J<J?oX # \"̐)&P{I jUA!y`lʮyMtsd1*CV1m6)W1p74?0S07; ?B  ơ <1@ yА@ yfWIENDB`Ext/Images_App_HighRes/Nuvola/B48x48_1DownArrow.png0000664000000000000000000000463310133444020020667 0ustar rootrootPNG  IHDR00WgAMA7tEXtSoftwareAdobe ImageReadyqe< -IDATxb?P8=@C4=@C4=@C4=@C4=@X=h2HUq&sJ2133b`b.`7?DfP@Sf21h 2@Xd2-Y s8=.*4g2by)( ȨC7 py Dq3p2`F)fE@K쁂߰{l0x&fN.`D312c; 13lwgWb (f7 hn'J3b`Se֑ad?@ S`B/b2/~pK.v~E caa `UdL0&၂a1]!r?C4&`@11@?F0;$32TuY{aGXa`w`4| TC-C) HS0&F hiA hB? lR\ I @ _⯟0|}/bs*@1XNnRaރ 6 / >Q`бCi 0e Tt4`dccehJP`mHYJ2 A7` -4#29 p3P'S,;뻷o3dv`x78OUe߁} !%U`_ -.D2^2%G!Ohb0}߿ ԛwS \n?'ϼd9L N.PEG'L%5I PccDZAWGa%H: }d;pL nv534ͿN  p`}Od``, `fĺt1e/ðPOђ0Z iP{- {d1CjFAiv [b`: h4 e<g5QYAP~ i@/f#(ð6ë  ?b$M11Ș?`߿ %1\X | t,pMQ!]N;/?2{pedm|$TL̊}͛ e/2< AŁ,W 30) s3XKJP 67\A5fpfM`ieߠ  '!d|hp'k3t-N)L5\,wdԴi؞b`eBǧ :(20 5 @,8K!` Ђ y>cge`:BS O? i[UC/0 )+i" I sn`@Ҝ 131=a N9n`V8O-( " ̿v/Pc|qydL:@pa`Ɣr5qO+W`~(h9%/r|Nbf~t|, @,0+p? SVcx/Q&%``-F@ *GK@9=2"' |`{ƭO s6=fՠXXp0@h(V߿̚ 9> L /^`y=8ٰY`մ<4j  $D+cū_8D e x@a؊~@N#vkA4V`- `a~ $6F#!@ԎPX`:/(_ t2| L~}? Yxdt`(0~ և+|as p033i&&!@1?`1 :ϟ E+Dû3x~X$D^\_"-O?c LLB FNI춿@X $|v@`%o/o0a;`0 TY~2IJ0AɵAGG0Ř  }H &&䁿`O!'!bAeP F(` DǓ ܼbAUTK a6# f#F U 9D  &RQ y Q#g{SM0{ f8G=%/`)hp*Q@ćHXH`!I"ѰLbRbeb{u +*Ël8ܹi_ltjD34@ d aɋJBh X>  1{ 7i÷oovn~X3 p'@G@GfPz@9k2ocʃ )@h1Ig?=|/95[/v .= DzCPM4 y /4?Q%.OhH+?J+ PK!x&Ƭn'XhJÚΠ $ ""`/r’.`FFÞ* *``e0|fxs 0Q <>w<`0w)~P 3Rܡ_d@XnHf L5febfb%mFg&N N Lg`)0}sʠ#+ e fDb3c(P/( fs?hNJ|s{" Þ#[`ZMNneXZpwPFMuK`3 A3N ܸCB0t/_8 1d_ op V1<~^6 lgc$ggC߾?Zs P ǀ>ׯaeX ?g>FHC OMU0~Σ>TȀ1 Ȁ1䈩8j`ߕG  f~ o;@/?P85<8ˀ 8r Lhb`q`1;`!?@C4=@C4=@C4=@C4=`zџ:IENDB`Ext/Images_App_HighRes/Nuvola/B48x48_2UpArrow.png0000664000000000000000000000700110133443742020347 0ustar rootrootPNG  IHDR00WgAMA7tEXtSoftwareAdobe ImageReadyqe< IDATxb?P0@ yА@`\ adP9$>V 001f`b^ /Ff& c3Bh0!r0owNbQ3~FfF{001dgP"EbwV m "b @AF@QU ?O:[u#Ch.4S#; TL- Z`no?[ED9[]<b`X[E'7!!'j5, jx*%@ǗH1t38(1y0s ?201(ػ0pS(0&6Rj9@Q `)ˏEUa$.߇8 o?>~b`Ǡh#! `~X8 ({wsT`;͗ARVm9ds) 0m209D]@28"@˷1|L߼\ 20==l!߁W /+Ehf(9 r2#eʐb3.@BZ ]? l 2 _A QFPUAB׀+|ؓIq @b?Kq%CJ>c`hp0Y]'tWpkp[l2 {/"*lPzKT.b  RP01O& [tLA!,q?aw>Ͽn9`?$1(Ϡbi&Tq@1S蕔bX0ݛ!,Pkin`f`{ XJr9;fbz!X| _&xt/ٱ 9 y$b,yE~@ǛK1VPr#0y9'2s':$s3fު+ Ϯ2`gж7c@}ۀᇷ &e EXXK3,ɠ(p%ów ? ?Ma v;Ӹہ1nug08b`aLq=a ,' -@ˑ2ʰ`',?S`t80 3?.=pe`U h38 ̤^ l}puo ?=LJ_Bb/ c`he @.1cacd`x'~ #aS 7/>a` xC"=`Ly2p-sˋ z ?9g3|< *r c/&@㿭7I+ 4` L`G?@dz]! 0Bڞ1 j`=,&%>(0|aF0 ,'p9 p{^m~z#HF {j@xV s0L S LN0O a`cb:T׆˙ĈkXd,4Y`8 JPs 40#!zPlR`v+aK`@Ci vj՝DLMP4BBRccQc@.ID>1a̬ ר kQ28ȣ@b1FFm JN2,l26@. Ji@:c>h_Hyt@LdjЌɌ> o`W:M!=F((s@rAr:D| AIDK8H:(m`o5?ndؿ"'+;`5̀/ #DThTy07$12k1"_##æ M lmV8P@ ^H~±@=mP+$`_njjvpn.VlC@wE63 [+ `kSDAyZˀXcdX@yXfr i,d/HLԌAAI,u XwAWH!'Ƞlio> w1bܨn ta÷?Aj 3k-UןBڠw`#3? l2ƨ8P&3|@q"S V -$d&`! jA0++S :2񇉝AHADA Sp+Lr@xxP1i0ܔ={YB|×߿3 ˏ?, r:j V "D{WWb-2fxtɇ ڐᔿ?1T[=a`b4 "÷cx *R<j,02 p7%NSID`1#Ѝ*x' ? % `r[wwwh ~@d@:p@xF%WFH}VoX26nQ!JkP;me@14gh{  (tXxpw IENDB`Ext/Images_App_HighRes/Nuvola/B48x48_Keyboard_Layout.png0000664000000000000000000000673410131465220021770 0ustar rootrootPNG  IHDR00WgAMA7tEXtSoftwareAdobe ImageReadyqe< nIDATxb?###=@迿dda`Pb`e^{x_>xg&@1I&&̿UfˎSQAXXPAd d }ӧ_qW^4.^$?K>|A0`fo?BvaeҔfeRP````0̿~`XY 4=ϟg=~{ > | lg[/o}~fFR||A>gfffz__k?L߼1VOYY^RWFAL 8.`ab 40,~f`!$t 4,g* py zߌr|E={x˗G;Əp*ԯ_|ҿ~1KCNMXAD p< {\ZE, @G)o>p-fB~ L@L`G` (ā` ?H@IPFdZ P`:Ayb0!١ Pp03B? z0UPAs#U 5/,@(*Дc`&$$UI(/@@s{ {cc/@ !\@L, + , oOFNB4Gk< @iCT6r0pe}3Ï/@}dF`3]z @+00(HK!C~c 9Ffh2۠P MB(%UkV.m! n; ?od7 74Б<:sC?e]@** r& *ӥy@,DdPhƌ@TW1C0 j <oY޿faxqXsK+Kڈ qv<@ne`"#I 7'}fp|a]߿a{w o.|懏 <+3t #R X'^2<|[v^C%-=7 G^| 4$}ҟYq(tOQ[@g/D!qx#ןl+7(dAu;0&f1|x; ^~fTB: zr b |R&0ifP LgLBY{g m,dV U`{FG7?3eeӒdO& %N9]Sa؀j3 _~?xYG[?~` (^03TuruFh SC\A{p1Ó^,CQ)`Gؔ8c73? t?'Xf! z u`<6|c AL`՘a]1~ # ブaa=J^///W?! dr ï?17XI&6f_ j 0Td-ep~qĴN|jh,5L l3?`~dl %ȿPU`5[@2F`R`d_N`ӷ jo`@= pii1`/óg/M&i)q`'ÃE=A'p _|c0e5+EDAe z.\e8}Ǐ GN73S`g0hth0j6?u)޽{@9` c`1,ܯ  K5vp |Tɳgρrs^^npO I07CfĂ܍eg4A1 ))LF ԃ<XYoR,A+`L2 k 1pJd=1@LƠ O?⒟XJJC\FFB44bAPqrr0ۛ3f RRp[#  ,@23+!yp,< dd$"{\?u DKA31A OXt Tj&@cHPEDh%㭱1\zH012"갫 `bG+ U?i'00A AvXY;@@A*G%@CO82;5a@Z}zëG_Y a//"f/#l(B*)fEu'9w޿g|9ugO^o^Ǘ6xxyE%ed~YRr@jtHcJ8Al>xڵw۷v*{ ã\ EOi9_?~ ?Aw9/xy(*2{pO=G޽{ݻwA@1Ap|oĔlק_}$@ݻ/>=yy1h2"?&>};L uuͻS^yo^BAr4VA= @?pKI 1s Ob3ks++ `deߓgϟ'A;?A X`{\>|lNɇ! 4oRRKn@*1ׯ?fx bn"?0\X€ 8A!MB?}@$ ' q Lvo;Ь ܦY ۷o I-=w ~7#4'.L 0;ȣFAG+aS߼yҥ'B& Z v<qohQwoA30@!/y4KWhU 5pj˄;IENDB`Ext/Images_App_HighRes/Nuvola/B48x48_KGPG_Import.png0000664000000000000000000001112310125245344020747 0ustar rootrootPNG  IHDR00WgAMA7tEXtSoftwareAdobe ImageReadyqe<IDATxb?P8=@C###mLdg`Pg```? ?~l C4F +"@n#?1 MGQ?`fgdcg L _}zzyo;@3zB hVB@3a``:/oMWu 8`a`fx0ٱ'腦A0 Xh8 //Hr5LL" S I'<_0} =*I^yh <U# D 7PG"=+*cÃ{ pb`Y peb%  /1v$**1؀Q @[1 }9 z@ Z(zDR4KAc94v"@G}z@أ ?exPÊD,s@iP1'34HB; ǣx/0)|PRy+}n2{ݗ 2>_T z@@r0|aNǟ}SY` P 7@Z0+3P5ՌG 7[u?"ӳ'vme}%+'++; 0/k^(f, 3#O^0ςr TmVx$ ; @}aVϠ['`(,R8lea ,6i\+v>f?p!n`+h0l,ʶ[ N?Ec+:  &RgYJz&S 0L '?V`>`aab Cag{) N_7+nu0k;; 0)sp1 Ϯ| }MHm Sew0 b, 4lٰf6cef`6WR.$8W;#O 1!cCQ:90X)!XU\vaڣ'm 3T%wp oZd:0(FXyi70C `9>OespSEL(M7 @0f8l!Ǘ_[G%gx T01tt˳>|ơc(ϰv1/~z0Ѕ8d> q@R(~p4BX80ɀ  .V`Y/ e?ꚉZ0摿`ÏB3,b > |@QZ0\׫a QpǃĀ)a)Nǃ@P"#xFh@V`Y:maPYH 703p 0ڊK`?zI kg x$F ov{-#>ϣ?CT#{!*kׁGAYAH=+~vfX3öIہVJP^g` l|5@!p_v{ ޘ'0 6d1~ y`|tovcASi`?T[, 2,ᣋ@@a){~`@jX@=@+02YA:pxY *@ZAQ_X9x ,.1|ʰ1Ñ#ah`"{ y, Ӏm -!? 7$Ă;,2t#4W`>6YmdXѸw;qdA, x7QJ ZO3AꑏВV;2C1'M 僪 >ڛfaw O3̯pW@o D;y,cP 4H#@ dt\_6|zI@ LRO03p3HiJ10':1_,C1sШR6`@a ByD "[b t=#1bKP:Ё#10w2lـ&^,nU\7dXP{{׀tAm."{ F&i?G@7̈ Tag< Q Z +fk\@h!߁HAR؄0/~UW_2\02 V\))@8'8@}d[h=F5j1P ]Xecx:0=K2%S4@u8t ρ͵/ZWfcC5mg>Pl6FA[y  AYk`> d˜>QNO]`E Pqe4ChtW`10\yrd~ vrv"j  ^RC0z+*ihȰAK5` )" c.X\zOԃ-*AN X t;@4G&FJZȽXzA}11Ȁ4 Le |@Cv4a߱d#,? Hyŷ6-HRCPܵ|>CP;0]p `hzwg3ܓdAO/!mFH"k CHH\Mj 3Eƛ^x+&10YA\&&Y =cA=Ã,Xh 4BtD8+Ҕ0dX0Q @Bky`BF 0~Ơ,\}d ׇl>@v2ZʎV (6gAwHIP 4g`5V?a h;э>) aWԁb<x9N|X;wi0v ^@]=nФč|~ ķŷ.|I {=4JА@(҂KtLMIENDB`Ext/Images_App_HighRes/Nuvola/B48x48_Folder_Home.png0000664000000000000000000001161110126472770021060 0ustar rootrootPNG  IHDR00WgAMA7tEXtSoftwareAdobe ImageReadyqe<IDATxb?P0@ yА@ yА@1( FF'`Q~߀_@=-a35}b`aP+%6=P %X8 ;O8+;CƒJJXdy`}ڶK|C}EAVf6Bh:w&|ۓy !Ͳ݄:7)F@Lq\N:M D`jNP˷{ֿfm/RZɫ&Rz;*h]7xnҩr"<(!3R4#0Qȑq5v)* ' 0iq(LP/OW'A 7;mn@ IXi9,cR9E MX΍$wXBm;hSuGԏ'&e)6F/,ABNYecMrS}_z F>0{ك /_`'s$tݿ6ɥ : c`bbbxz8ã[׀A)a)9gX?bpUaedg`ŏ@G CAtObX ^x k؃gYDfM0*k{:K%v圪 -֛h5A){xw,.K50nB&dHAKv#Y0ޟQ ;._wH=R =X/>M(@}`B>F%9Il< -,"D j= YJ]+0_fhFtoJ<+Pl SH`mo0"XM,1 NDw I;ˉn1iRWRN[!*U}s[Ma-<| u0T4H[H`݆u67N"ڪRωIb<޼yCl{u..d֧1OZ&.iċ#eY :l9.eeK=ۣhHC"t_%mOEYJxiq ,q݉ń۽Q2/*{(? M'b,bL0uӽ73gl%1MQq:6M;l.bGgk6Nuoh>|S]dj>. N@E^`.- F^^ uY#֢자;,L@p$10Hb?~0H 3kʖSMՁk r* L \k bR ^a&` L_^>`zTPBX0|{ G_LJW ̌@yy/>2%G[ G8?:Xg2WVFԟ/_Yt! xV`da adW|Y /K ooX='/ 8çWFsX=%_Ϗ.2K=a#+`!$cPt,@c@wŋ͛ A.(`#5&fpǠg`t\  9`e:Xaq 2H3|:T/{WLX=-NA O2GwT5>*TV K>~%%v`y,X{2&hg>:#xW? dP 62 02̴ r#+?q &o* `(X ʨ330PX? ,޽tW-`/ { LJ܂@k`7O2p 1~r/ûO+KU5 `ǻwj7 e0 wb ( )|{FsJ 9ovFL5֖k zvx_JN/fpwJ򇒊(ApJ)3OLOu}Ps8WMe!08Vm$BKz3Ϡ~ b A"tu>KXb;d侜?}̪mP;YnYOL=#&sy|>+Y(<LSZ>VE}rD)g*;S9 hp@, FĽR\=p$1&`'ep>.`/lm l 1_ l2@'1R0'pC@+e@  j`T ;1ƅAU/ l:`bþ~T l ao2| $~aFS`Ty]f4)>C_ĂĈ( a?32B;Pؠ"CMʐi6`#X0{/ȗP57?`oٶ 7~1ae<]_~{) y Ă r ̨>>ax=(6.ly2pde4SnŰel׹qJ$c 160v0v'`gx^FS`2꘠AO@,xPO/1<_9?0I3؉L>88Yb HprLT9@8Yc!,LD9$ٌ;_=gf8 þ\ UUƠm ;?m`,~9J!ITپS)U X,#~@8=&@BL^ <f#q Mz$ lgSfd8 v@ `)4/`F,M P&{@ \ YW Xy3.ETs )baX-H8C3AYd .0V! L .2×,`o`( &IZjP@ ch^$* c@A%`נPAO0dzCW?<~>ïF@NBL YzX9Tifv&$ :#0yoAP?v>y lJqepc t< Тx33@/X  ?z<{o3|=P ̣1MN lL>?}pM`,8#` ? (s?>OhN@8!q ?@KU>` Z_-gb`OYU%lsā-q`MAU``M, M3` 4gEt0?vj3( i"+iFD%ŷC'bP/Z2@2(SB ӗ ? \]oex/&`2bί<H h +R 031VV!b0yh@b%û{/ aU% #ez+o:+3fbep^?W`02CFUu#C>3|{ wgxx"ë; 2A1P pPι T s럳-K͵ ,N 00ss2C(@ 3p#~{Q2<3?y#`yX X<:%:} `ADXNPрCYD!2AX42J 憖_>OawÃy0?g@89l}~CD (RpUa`pd`RaPqc5d1fxw<Ãcǀ,y30Y2ЕOC/Q-("zؠ"`g UcaД`x' L π!ıP~u;O"$@x=VU*0(V#fR4ȷ~ ] -M`t@z[@'CF8{А! D=+IENDB`Ext/Images_App_HighRes/Nuvola/B48x48_Colorize.png0000664000000000000000000001104210133443200020441 0ustar rootrootPNG  IHDR00WgAMA7tEXtSoftwareAdobe ImageReadyqe<IDATxb?P8=@C4=@p1_\2(ˠ?_y" 1И?@[fL W @1bA`? @kxY88X0 >exk}补@ ж v.!aY^MaY-~E]^I%/8003f`d ~'01|~qK0\;_ nup@Qy`HŐĠ&,jh(t(//?Оc`` H2||aӒ[ 6gVxk<@z@o8DXELT |tTx }d&<#'?1p:Ý 2sc`.}ɰ<Ës00u_B@J*dH4g0 bS"0_& f`fb.` [1np36M:&`F ^bҜà/ [0ܺ%;/=@x 9ԭ<}^:wkqy6CjFA~w?1axM2;[^<@ĔB,C{U:Ј C ÏoJc$<~a#þ~P!`l. LRTax/ Q` t۟ c`-ɰ?JJa & ** cH\5A\v20? o ?12ݻð^(?;g`V̌ , ,3T;{!׿^p?@fe>03_?282nb`e {q5c`Ɛ t ́1l\P0m~ 266wo2lO &`F%MƿL < υ~0ܿy=2L*b0!+2;;n`c_ bZ3gͽ8X"0G.ZX,a$݈D{; VML ,ZDE33<>rݗ ?e`pL3+C/ê k3v. mv2Hrc?3")96aPfs(@a@+;g'Ûݳ^a`de%^FAV.7kɭ'v{Nf&? $ EI/aa`cБg|bos& %$~gS?Ϡ#0xR`Q D2k193 {L@w= *L> Oc`zAJW_  ;~$ !jgfx1Ò)~ym aBq`ަͧ~^HPX~g&o>3=AY YDtD $?tܟ$@(1c a!H R )5`dfaFq7@xhg<7MR*W !i00 $(w^ @4*jl`[\# 2>g??0p1Is3HA~Cw` J N3:A" ~mǀ ̔o^`PV =PC?, :5~0ܕbVa0V`m?T ￀ X @3et<% ;f?P1C볗 ggQcVe?P9Ph8 !Ë/ ;N2>A($*>1?phY"03׿ _^= ) 0(3 /3}iˀ~~axw.-BcX-35( /20l 1H0AZexkmcӷ ߲=:bA򀎰0]C4хwcVRp_$DeO2Cc YB$0CdbG~}ksh18^h{aϔ  fs7?˩c0w R&'0,>]6$9}pg Lܼ < @et)v@4`gFhV69>O>1@ w@1\ \z4?pnbAJK<쬐P$?P: H r%% 4f@f}]3 *Z>SÁ8g0b5 oeiBdb&@=?d愤cP1e<0AC'DCr')'8[=Ù]z>## #`c ho  ڍ\"~'dĊ\nC3" HE gЌa`@t=^~o~-!.P=Õۏ\gx+CP?J Xjk^vn3)*# ?2<Fg& 1{Rv3"aX҂p FTAT]@c2 2r` Bor \Ós'B A 7=dxu. @1 |cHAy 6a3K}c6>2|z=P @LH8oz7!&~0#{a GWg|(اλ+b޽> /f5 _0\cdxr 3;CEԪa &+/ݻpZEٖaxx -g^:۟MtϛC #!mC1#D! 2\9v~R02B#g =.m`(v[ >~Be@ -?&3uF°u@#Kw1ܹ*#nrfh3 @D3#9Mwddxp÷+ρ=X8ҁG`JAE?%_W`74ܘcjDto`9k O=`0+, w?,W`&`Pm@ ߿2rZ'GGJ7pˊw.xp"7ë3zx`P |pht }c9A O5Y9IQ+[u/o3MN1|n b=@Z l򭃌¢& <5afb`ZȈ$<3cj_?pOwX>]ǟ@%~  |[KP7f` NȍFJx&P ./72|)h/RФ ؕ}` _>g8w íkl-קMoeGd@?~1|~p_ XsAFB '~dx}' ylܙ."Rm-t6 !Kpy .a Wo RQ2@Dy_uȰ򑛕ҦdM `  [o 0i|ӷjfI(jUfDɰΆ(qU`tU[NATǏ /dx :%Ч`_h9Nq1.ӌ+o10rG VP@@obdd.@Qe袙@(?d7i`>@yrhOtА@ yА@>&\IENDB`Ext/Images_App_HighRes/Nuvola/B48x48_KGPG_Gen.png0000664000000000000000000001202410125245344020207 0ustar rootrootPNG  IHDR00WgAMA7tEXtSoftwareAdobe ImageReadyqe<IDATxb?P8=@C4=@C4=@pD0220ğN003@|2xr;@a@ltoȮ#$fŠi$w7_2<㧿?}ϻ@20gg`!ЬTr= ~`(``ee`4Q:XBAK_A^ 1Щ8>~dx_ ~e8KWgc e O<@p32V+ʴD3h1(*21p~b``t4P",0^3@Pct Cg#er&U}؀y X|han) h5``C=S1a _S=𤛁'0 2 bg fP1{ C]3#yY yfb&&n02le_X䙀Az  $@Gߧ@w L;?:HB~F2I#ß^tE%І/-JCm^2| $ 0)=Â2(f_T/3` 8E ?&NVk(06 ]o30Z02pd`ÑHٿ" . Ma LݟPu`1i 'k0\E +% gÖ/ОKj@ &3F^ӫ@{8 !8k LN@6334& h6'ßw/Dx34dX{^#Ay = ^kfe[?;0`,?M- H<%_`gFȘAA f ׀K  B @a k ttC  WJL`eÊ a 50+; Cl?4 1`T~H-=\;#ϐb7#ܵ`B|2б@iXgY#V Z \5[~:~#r@+H?6"PA ;v#jPT1s" tO`~#aJ`ۼr-xiA]iW9  @ȍ{yMVa@z o9p!雂 0$AG5 *_dD1roH@< ~pXU Lc п : ^eXN@Sb{a!ʆ@@pD12/RPweu;;| 21xիW ?ퟗ o}b`zc?2hntgP+D,dx-oh ,,O%C^3+ *!ˠ(/ )! ,`6V6,,L #_&W.~N6P gO-+  VPHz@>`Xd_Fj<|p9-f-ac,op[A11Ann.?/_o K? ZJb wd>^z$; 16s@ NV`'pzp(ۈ6Gp;?z%-R D)$- /_|``6 Ņ! -((ęx1glNvv2 䡶@Z"8< [Re. ?:ֵ@pjʕ1H z`eo/V%>`{Yٟ_lgdbʠ ZXY98lz2 #m$)^I[풆 _~?F&NX'N* \Pr= 쨀Bիw W|'nn`l3pqqCg&#?<@1Ll ?fxe;s;l" ܒj2 v>۵Ak@_ ԣ6 PBr×޼yάR@eUf ZV`s7TT@r;(A | !)\ nc 좰G1F3cd8z>JKg O@ : ŧO`ś7/%\\쁭 J Ƒ@D=]~7 TS2 Nbx lj3@m[`aĠoms6i00310s%1h??@(P0_} KG'ܻ ^YYÇO$I^yR#>(f#S Ov3W08g8Up?o *0:u?}gx8-?pCڀ OB'()Č~C~\ރ2P`;w^0x ofx7çO30Y7F.^)Ko6,3>=` P 詙 sXTUМKA7vdoffHO cTpRJJ֭M@Յ*0p?#6̬ Z҉^Z1AK 8(t1YR̓, 3pY38,c^a`vd 'X2.]bߑᓟ?g123j2X@e>uuU`.(EEp J^:L38IK0 1'sp>á& ߂no;BӻXV0z/X`ZaPR_`qrr,F-J!4У??.1_ $A7f07W3b`2@: rz=S/XFkg N2k!܏SrNPv`y |L쓂2_%*6pWPXkMRV0pCa_}HhOA҈A@:w]?) r1NϿ?RHݟ?}{@gF..~10lѲAR,hAI?D)p^a@H1 {Pgdd1<ˈ9`ƍ;:߿dgϵ*R`e6ic`CI~0<=h?\y&fV?qMH%@!+ jJ22 l15A QC޽u00}O^V?qd%+°Jcr87[|;"M"D>ë?9~"C4k ld .]=}ޯn1|98fPYɃ\@ t_ /fxg`Z,Bo3p)\u99[Es=cbt6ß?C;28wERh)H7PO0?G&VB.Vo߾}E@91z}U`j} 6I3h , I2b`xpL?óhvp0~N+fe^ZLQ74lbl1=a s;iݻo޼5mc#?xXc{ d?21Z4lQDBuCȺ, n`xne8paBP+x?XyD8 l?\cAkW6dxF$:7jd)?{E6+}_!`L[0Çw`=?~|;O(L`6+foaj+L Kab##-fPAթ4 i y܂Nhc9ԃ-R L=@jH}͡IENDB`Ext/Images_App_HighRes/Nuvola/B48x48_Wizard.png0000664000000000000000000000526710133442530020134 0ustar rootrootPNG  IHDR00WgAMA7tEXtSoftwareAdobe ImageReadyqe< IIDATxb?P8=@C4=@gd(i)P 쾿 (45=`a ?Ë_/R1h &A]RjGjʸ J,V8S~;PT4 1: \mW }M@Z  )@m×?@{xj@ A0g'I2Ae~8# 2W3ܙ}Lǻo = ܞ@Ӂqw _9_H^g`z [h B "I ‰N n޽a`Ѝ:S_о_fzZ -{>텪)@g@B3^_0|{ U~Aj#BF 0: &l1vfs% C{@ǿ~f XwR  qvF*:2 Beޞ~R;? r4!9?j &Ơb 9DP#-<@0d:?o !$ b'f)v  aB F LNChJldDlk`Vs"xI69 O; ev`[0#`0 hnR hFs/@VRfCφsh200?u<+a'A< o6@iIhjx Xp7D9!Z<&B0(?B @0} }c+ÇwAH l07̤ t~u=CVK 3|E72|m>5׏Y!t$X,$݃<'ûg@q֔!A][a̙Bk/Wkȳg 0A? Ƈ[ L1(gd`"Q,m<& ]SV﹚6 0U== +gX0AIIa K/Ɩb7Aϟ?`'π ,3gD(/#\:{g Ba_>@mݼXuuu1203'ϛ?+33s #oR@@|~+5Cf.(sx[ރ/3|,pp%721ܺu!++!<,,oJN &kd+ly'lpMԼO>1Q"Z/, % k۟?/,&%o B"" O֭[1JN )@Yx X(@ijBhc/$$Tx @`„ MMM 5SLΞJ NF 9Z@@TVVǏ``nVVV֔o@Dbb>>zIIn&&&0T2ܾ}!###=JB<<P#k @HX8A$LNy3f\U2(] kłdc̝; PY@11 .D75ş Xt 0@4XP#+ Xr PlK`hLML@@W@C~ h{  #TLIENDB`Ext/Images_App_HighRes/Nuvola/B48x48_Help.png0000664000000000000000000001106610133443072017560 0ustar rootrootPNG  IHDR00WgAMA7tEXtSoftwareAdobe ImageReadyqe<IDATxb?P8=@CFY% 93b?@.r `~π Lemb/ 7?(3(2WaߟhVV=N>fAA^N. ~aȗO_>߾zb-3JAu@@GgC,C_AIAW_AQA4!/@OO_>~GWn3gr ï8Xc dEX~=+(X>|p!g`E6!pC~ S\T I.0ǃ0pc+IJ  LLyO6x3+?/'d/~1 3e`'=;Xy:NfɉNep3I>~g(CC~+3{| ;pDx pXebl$xPil"DJbX@?dX63iCj&  ocd&(_0A֑]_ `R 0jW~#m&_gUpI)Aۯx03 2111p5'2Ͼ]r@X:H1)2rpP> _=񋁕_A q`H pu$ 71$R<0A` ֺ 0)Nav@___倅 ,((2@q3@a6~P6$x>}&,;VZ@cBTAVN!C4Xga35#ANcTy,yaŸ/#?>Y/5j̹ĂVH Pʹ48/4t | &mi\ +7!$T_xS/0i@ JF! n>Ȯo8%$XxY|jbA˼z̜Ҋr2 _1180|(_`&agDP RbT6-4@E-#X#<({ !'}d'j_o>aXs;էFay?ro4A!_a8v!01pՃc _~BjkXނ%O~wz] @w5Sv /`_29!ɖX11E?h$ ?}XCyׯ yR JZ̠=cxH@vl[q,Amid'Z'.bffЕbдfp2T6yRppr0=o R") 6P eсfN`:dbFv2@gbnP>( '}˰oW-6mIQJ$"+ΰN:_|< >a(y ,@t<(0 Pvd'Z&773a/Ƴ_nH0X(2q1mfp;v%66vϾ3N- 8o߁+ `vC+C*Pr5*C33L'?#ʠ$ 0,l < _5?>~\c: - YE?97ʰ * &)P?{Ň3{]@9NVF_Aaw |aX{ yx83<} |b&#"vA7n$c @`dg`8pk_`106A1J:_ L@}&:\/z?0?pO 04;YX16O @Lhg`gHT"''xZ(Y ( ;0ɀq%N ~f H=d'Zkҟ|Xo039-B ҵ[LF,L @K~ D:G* +d %dz>032p3Ar.O`ןp_O~G)PCWrXrB >5"; `013/{׏_80s>x Y01 8C >0\fl؄,~ Hy`lf`g?=U*ǀd'ZT1˫ ҂@= xg'_kMZ WWk23#RnGqpX3yTd'ڰ!ȀzXuʋr@/j3hHaE24QaK:3ɡ$C$Ok^Vv.v@̼+2Œp8۫/r"+ @J 3l$/7_ mBlĀBKd (CPT $ޣWkT5W302I1ps@od93#4E#+7vhVC)mЋP1OQ`]p f0l}4÷O_88X4d!Cȡ?~3bT|6@ge8zT~Qy'%i]ݛO}L3$v,_^>mAcA]N "{foyл#?6.O a{ X00Q Fn`ȳs 1 ?nf}cj~K`%6Pc;ЧK~MpnD Jx!]"A ?.&9?O_K\k@S HD{ (R_ mN^YHs@A#]i)Ж{@@| hYP7h=@C~@ yА@T΁IENDB`Ext/Images_App_HighRes/Nuvola/B48x48_FileSaveAs.png0000664000000000000000000000740610133443076020661 0ustar rootrootPNG  IHDR00WgAMA7tEXtSoftwareAdobe ImageReadyqe<IDATxb?PĈ}Ve; Jgd)_LYXGV=0 @,',1|3_]UT.s|!s|Op`d` XSr;E9%9t~`3vpVlB 8e pϒĬj -`YY'3@c pyTFqd)Qf L/  . Md*A6삗 2Fpf`:%ק!ý\1W@8<;MY5٭2A[? /x@213̿A@D Bp@偘㻯 f/gu gj 0=@_```fc(b-M?eo l젌v?@F`1K`!hFÙ F`> #? j*"7220p&- L n` #&y0@="&,0.~iFA;PǣxFVPaiK'b0}C〾: @3nl^Ý% +<2B#jyn ;1ZQĐXW)(a4-ttb`ϰ{_.}Č o;401x=#3< >d=%!.n8PhÏ@)q؀ co$ 3r&FIb  ˨ynOu'3(*fpIlYゴ,?n6B 90L`N1K߂@Gg730h'`VW`0cw0eJNT@j0c)* ;o`p!T (QきWk/1Z$͠`l'H1 jB=@( <KB0C,bǷ@Wp?g6=3;%'c!LX?)`([/-˷g1maê B B ʆ On^   `) =@İɏ 'Z7@Ll=fxm&Cj670 /'8zUrcd0in]? U@ʔx'Vpz跽'bM?fW`G)y Z?v`XI.Ík03X8 Z0 K!@e/fI<3 πmА* c8pa"n% D?n& C2<@xcfSXz: #B&622fdc`~ p uõ[ .G0\R``=Vfg9PbPE@+2}6_3(3Xc R"@6'0`-d*`/n6)/CJ^F3LbxXEK2zj,JB"C` ѿ J< 3@ g>2y2w z% \" w2\>aC.%uyp /Q o03pԋ#T%@O`z?ß K=ypC6Pÿ_w@pz"=CxK ÷EO'V$P F:>`?FVG0G c  fz3,uT.;';0} `ccaxUC3# Qd<Tex É80?v r\ Br y *Fdb÷//0cb(eV0p IFFP򒁓"YTt5>t4='[ K!"Xh /`1؃ ' 3&{ 5-*EWPh7RcV$Wh?(z #1@=?LSJa|0iVv6X@r0›@1s;X:{ P#50K/ P 07$3@6`B11@܈BIRhC+qR`BLɃs(?ZbkG4a/B' &b$Eh~ ?rQ| &\/DS怿P5i wޱAnp{ D| qˀdtcc3 XEO2Czeb@*3 ,iWg@-0z?Z'PE5 gi5ǀs?t$,r=oBL UFe;fz,cuqX@1s=Cq2Xj%4> @ke7^3`/il: ( m!L3G+2u1h`4%IĄ))1ao2ŠYFDˈYˈf]ȈlȈb1KӇw ?A`M L 54 ÚaDcD220s4?cglN yŏNlfPujn/e84/mXUxa޹ ;=?2023< -|fFHrvZ~ϰ_c@degf|ç:BZ^ex?8^|puJ>lT3;S0GD<'̿ 1~FMЎ_Oe2'ZNZ.:P] I~1ebf_^/c`ff7tА_j@C4=`-rIENDB`Ext/Images_App_HighRes/Nuvola/B48x48_Exit.png0000664000000000000000000001025510133447112017577 0ustar rootrootPNG  IHDR00WgAMA7tEXtSoftwareAdobe ImageReadyqe<?IDATxb?P0@ yА@ y 6ՌD6k w ~ס,P3_$A- XF@cCFa`E)3`&&v6_@ zխ+ S t;0Dd,utxT8EEW/_2|{ͭ[ /\yEo4G6r@I+T% cǠ g/~?{yN0ܺp? xAJ R= T=4o!i1T Q Ʌ#~`#c`O L@5, w Ϟd8m'O.M:< R< Tx]M7;66#khNraI(|ʠ-(  - @<j 3ˉ20zv@>vX ,B<ᖔdg0 |D@30=ND .Tab: @<` 1 ß {e@x03ATW+ow0HH@R 099XEC`RcPRy¡ ?|`` +/`V @X=HBHQF[2T NO``fW`ȳ!FD0yz2H7p#{ \\ ff 4ׯ Җ J@ݻlCɋ { 7as+@&3+ 0O|}L'0<: LF@OePdPwqa3Bt80%Jpl2ibx/~`@p(1ͭ+ )25qq3򟍁uWû{\]~)+O :׻wwph'! ʠ?m!Po V` S, >:?uVD p/P##0=~ %)*(@X .C VQ1c)Fa5_: `֭ A Gu~hVb)@ݜ 2b'4 Ik%- ,[ xHbz?y6]e@A ( *(g10M`@%j&F +] 2p\(L & 7mXEm&."4#U SඓM%W,͹71##XpC`' X}bbeT (5K~"&!&𠹉=0ÃB x/o0|y˗ >~c`b` ,=#8ro pyoϯ030J1sXx`_߿g``P]G( A1i/Tq2hL oXm!^1|aX, w|e\s`s+@J};8d84ImeW93:  􋃁Xfp1 t/f5ͽ{X>jqr16+w&P`` _ݲW LD  MRl> _f`y jgP{xy8brϙ3 AY&c#y2\< ~dfPfһ߾g8 ܿ m3[``H5c003`,._.`rb6᫜,P[TCbefe$I`1 J؁Iy0ܘ6&0ga:^AoGhJ- K'cbrtbR& g=)9r8@JАH.r؀I ԑ6?642ܸx.NN@A߾ۿ)-<@X=Ѕ92bgg2aPUQ`lBy iMܔÛĘ២"` $ fx VZAؒct i <@DyGvzbD6gRU ~x ߀n`sH|̠ XsԮL>eSYA靝Aa%m?1|'Ply Hx5&@Z]IZ\GAܞ-Ƿ>?JB!0y89x4Oc?3\&PxMЪJl R=r@v0D1hI1(K2>ЬCAMj0clـ-J-p7pQ F%Cy lZ(AcbT^DANHA!|R/ j<m`?p10'~XiC@H=cj3-,YX@ iYhP_Ph< ^ c@Q:GU@Ǭ(@X_ǿߊZ k @|$t't8ԗА'!!bBP IENDB`Ext/Images_App_HighRes/Nuvola/B48x48_Spreadsheet.png0000664000000000000000000000630710127777574021165 0ustar rootrootPNG  IHDR00WgAMA7tEXtSoftwareAdobe ImageReadyqe< YIDATxb?P8=@`dddptttP222}ˇ޾}{7o^ @,,6p)((0$  >)U@G OJG' @F;S2H$hTW})"RrIpwsnf Y{2րWk]wv>}F ˁBs!NZd`e y ~R@$#,HWj 0w"2Iy &@, /c`de/T-B? 2_?@=GABBAEEl1 HF8(` 1Ϝ``eddb FFX:7  Z| `17W0(+K͂yd;d&+;&!aJ* $Q?ư}1]IV"$@`1ҭǕq@0ed8v?h'HO,,>,ɀzgj 1| /8-@(y^H % ?zHxln% 0 3>~6vmێc=F@1OQB^y_Eo)6`2>w?pc88^XU},F CҋV’[ |!c*'f`Y#JI31z\WB"!lZff& Yo`L}=}g/Ij#!b_ c hlI VdxBE0@IrY#AZ|a3LLf-ږC#M @% - #w o00d U/z`Q @,:."#scnŸA oY>axMO].^k`xY8! yJ1s 2e;V0 Rʸ zͿy6>c;Aˏbx9aĄ; bƌP?SY3s1=P+0vwv ^,@?N3_Uz#C̓2 Wef4w&f8T9< y lͭ ?1@30'8ʄ!aN`cK6_ɰ3y/ T+U Ǟ11nd0d'Jc@1OBĥ{o08 ư+WK2xiٗ V:+ b!X'ؘY &!Y ! '"." 0d}°>R LJ@1Y`} ~VP 23y;q ,0-&T1023MBDCj ra5 ˥xxX3~aO*ß @3\x0!C 2seu+ '|̠$#7o ,`tpa,ʁll/ ߟ0|rX,e`LW ^ 1~ʐ}+A ~" - @;9~0a1" @zL?}z $4) rV~ Ȗ5÷ JL @fffbe`f?>C/̸31@ZvЁ$`& F`y l X R)t+ `/ Aez[ yRg02/ L rį82pc[xl>`$6FfH*7@U4~3šp 7v&A nf yye8ۏ bܢĖPk70bdDP ,V2383|A*O^d6g$gwY_[ -_^c0~E9Fh` 61QOA,l1@/^0">b-'6Ao߾aT-ၯ_^lX#hc5N#caaDVC@0 lK a:ii>lFOӿO<-18 ہx7A& hvXU!oP@|n .&-PL2@И&O? pmAzJ{IENDB`Ext/Images_App_HighRes/Nuvola/B48x48_FilePrint.png0000664000000000000000000000645110133505000020554 0ustar rootrootPNG  IHDR00WtEXtSoftwareAdobe ImageReadyqe< IDATx՚o\}?gI Eq%*YLKTQ;4.K4A(6m}K@"}p AF E. jHu쪑Ťgr>YZwx9~緜=j"}/=M?2:{v,A ^S!OeyeLJ?կ*Px뭟|2}R gphdXJM>_^-_SLhxy4[{ΑCx9?Ϧlݰ1)|Ǐ;u4tB8pNZCӇx7Y.z )]07[g׸u/_beez7ߕRCF-cMNNto /,gvvaB2d =%ٳr5Y3B‰'֢C֭.^ٳP_Av.$0>5::7Ɵ1?,0#IZxA)ѰwwVH8sJ@7](Rx#Ԓū)%R-gz?qw(x,,~y]Òh%dCIvA?:OVj')gSk H) "P'###9#MvJ!z4:́q bgA1~hZ"RvJ\cуᇙ=pŧu?MNNC}p4 &X4_yޓZf<'YՋD$N||7՚yVssX\xsvaffBD$do-K5hun:"UMa5J 4)e;LDH%+P9Es(%Bω&4&S78,ѐ#$ ^es W&>)aKjqbW`(B0 αo|{0Β9 !! Mz=VkϏ$!BA*2$1fGIp<5dqcڪĶs!YJ1 Zn٘( \*LӊV-'RR (lHE:TwN>ڄ@!m\Oo%s.b7 p|an~d1ϓWzA@7pάt !UE7n|g) XkI{Ig*A&Mirh h"B*Ƙ.)'F)sƝR(`aa39]v =CC8gÑMMz~K@)QRJ X)EQZC!'~4Mg!Qq9~`BaDZ2RRQ;w yfӳw4Vnp)cwIt>\=>1{G8̣h  !ƈ6I$Z 4+.&ٳ_=֪? |t{uA6uΡfff3gD8q8N1ơuҕ+RS0)%JxB\:D^|eڇ֪}QH)BKyy0Zߝ+ɵ#tIbE!ZkƘI)]@g^aqqJF"I2׫ܺu#Gګucu|sisj} ePTܸq_.\ߢ(z?fz!7~7{;wZ(w q.,;vbd"YfN.pgߛM =z=f||'kGQl6okJR8zU؊Bi|[~zûWrЮNhhgzyjѣ[K.!Z%!D*"|ȷemTJA Si.8HIaIENDB`Ext/Images_App_HighRes/Nuvola/B48x48_KNotes.png0000664000000000000000000000630310131463120020063 0ustar rootrootPNG  IHDR00WgAMA7tEXtSoftwareAdobe ImageReadyqe< UIDATxb?P8=@C4=@CFFFx [1SьQPFo=~߿+10* aH``hU?|R fhJ 02rp3233%,(* p*îW1raXp?óO>q ïY@1ׄg9a?޲0iK܇O nJ6F=}W_<Nwݯ_OG~1} +wg$_gK O lR(fh8 f e.&,@ K7B \V00u{@>ԚPZR` k$<6E u̿HK_ @J֋Hem9UX @%~@=񉙉_bNa KB8$0|," =Kj¤k N1<<~ XKNVeyQ;W+yqQÕֱ%\:/h0~?l@{0333Kh1H2'` l/p=73 0E y\CS?{ ox  f ]P5t0)YR`ɰpFC^K?lcDKp q`Ϳo=?tX 0_h  ??@axQO'x(FvWb @h1KGD{KѳB@lDzSohge`8}WBf!FXja|t|kY_) 9kԯέa^!@@|  p@`eaAc FD_o. Z2 84Lsf6mcxc@ɓ@|_'!B'(D k#_ qBi6OVVpI ?V# JQXq mf`|~,#ï,gU;S]S@| 29@(ϓ20=u d63001020@<Aib6y XvC0lh?dt !?n] ޾k5Hc# M  2p22003si~V6^Nv~.&>>Fv^.fV.FFfN&FV&FfnF&bf^&^6  /c& febxKfoo2~ct 4s 's_RadV4 ꪱcA. `bڼ 84'7;73#ٙXؘY9Y ՝?f>z}0Yb t0B6(̈́F3&kbC4 ZAlTˠn 45G@ӬL"5G<Ɍ&ƄG D~i; D7@ yА@&c53IENDB`Ext/Images_App_HighRes/Nuvola/B48x48_History_Clear.png0000664000000000000000000001441010133443056021435 0ustar rootrootPNG  IHDR00WgAMA7tEXtSoftwareAdobe ImageReadyqe<IDATxl 0:6`kCԈ*q "|qӌSQD'A@wW,Z lSծ@U7p dOJ+SI}y Jce ٺ,\| B |, l ? /dx'Ï~=xic;J1@A2 F2b NZ$,f`&`.Ƞ TR!S71ݏ ^}J;4ҭNJ  {hPEꂌ &B | DhF  1 pfol#C^{h& { (,~-SRMRa2:;_@|xÛ nfxv-0b`cd_p23ȩ1H11=4K70Xsܥ7/@G'"2@3X٘c|<y>2}wn? " "B bb ga'^Ɵ~11`dfP3aec?v!Âw޿~4@Č ҭ0`0gx;_1;yA+,'30 'Ý{; 0Y2|O Gg3>:40*3i2O?ox Q@Bbf.ĤfI JKiYa'?phyGv1D 327, L^l /_f+%Sc`ga01`P{v30 2`fgpdz-GXN}~3 G$ Ւ\ l|| ?00\=Ē ΎΞ .0X f^AYҕ JR8pcgfg/`fk85` DX,jc`gx w2+220lݺASS\)NCAWXXAUUAHHb˗/0_!22XAOƱ[ fP`n+pkO?95@}Ev/@13C j󯊍1؊[B 04 CN: 09c X 2 ~ &%SpLrp1 0O * 1f.pC?Cj {A8 _ f3Ve O0f3 iP:SSScgNHڇyHHu q< 3B @@12_GO." NYQvSG>j>s3@13= ̴KdT-nfax;Ç'ʲ$i#AA{Hx"6w/ԣPjyDKk / 3bbx=Ó[oIi>н?@ &H ĿZMXû oWb}%TA8# C2*,B</y93#hfg!jX|>A>UOg/2|& c`cKF @@=#Ve֔'0~81'3}\rWX 6ѓ$@|ꍃ 2g_x=P098)  }A ''͙>r 3}l;Cxx 2\S"B  wO?q@E/6`5` w!ßAX\T;>p,<}ŋ j⁊JxRyI7YaϾg 8~d},u U&?:L%>à>C8;''<%ՁmF`l~&`~Pg3U7+$/{eA>bf ;`8r###͐p{O0ܻ W@?@OZpkAÃ}جÇ_̸ 4X{pͺ jO.}26@I@\< _~31|?1p{T*)HU(Ё 0]d8rQ_< ")옼clmePaXa5  ~r1|w؀MyyIYY)AMPכؿxqѤx1tmF{  8ف`z }d;~C@Ôi 0xۡN֤zͩ kNn"+3{`Q _9"MXax$00 t01؇UՖִ#<@P X "q  3\a;0V4/E k72`*Wtsc`ͅ``HJf%~?w6BX^?/;l#Ą>d?ߊ [ ,a /2 f-\Ǐ0?ΠTPR j0+Pc`&iWsݿ?820pH 0mavi0iW`Fd:ё# rrStɠeٷoga_l_WaeV! %`p2[W.@bO3>>NY1g^_`A (Wiİr%×'8g0'bd 9c@]@9RSy&WW,n\gP21a`QH9dxdCM>ewؘ`_`%)&7-@D-ݻZXdr 01\?׮1@ԀȠZTyL]Kdu1 ,M b Ö- WOdCaL?|3؜!MXP ~?Š.APApH2G}ߵ |n& e^^ ׬as ,'@4? f|Aa@  73;qa1Q.׾d`W @@DFֺr L f .VK. ahўEn҅#qrs3Hy{3\ڴMAP9 O ##APȃK` O.=DČm _0|z0X@(/732j֐f ˗/b>}2p@ s;;YZ2:8 $e L^׀0cx *@Al(@OgX!abP ;;o@^t?v>ち"o*hJ2p03q0_ (IN0\9T"M% .bz` / lT13 1u Pc5Ȩv]~97;0`eFr!; !/+=`;X_av. l`=;0 oQkF w3`*L£oDcccRv)98N 00 :{ R2e`ux2< `Q<(c\bT᱀&, 6Y{^!̾Xz1@13<·^Ƽ 2 | }fx'^3ij1\&_M2b&=95UD)J0 r4(?J$P7@(&("%gޱyG' 3=8?g 2H 31I0<ⱻ N F _޼e<h0vtƨ?C+ WT1("J`Ƈ!0 ,4$Թp2@xaE c쁅fE@z=0Rt00&E%%EE.<{f @Abs~+˅ݿEA  rR|  62xyؾbûZ{`& yP͊P|X"]2dx r=| =bcB8 {2Cs3??} , z V l of|0cc4͠&*  JK@ ,ff8|, B<'O E+~}pWor3Hzpkw3~ _W.b0tqOӃKd@3[7nY3/]a#^=? ?݄Xl}'@~ &ɼz]? ޱ0,LV&B N>(Н ׯ}bq'Ϸ W3i 7o\fxykμden^bdc_鼇2l z %'6:pٳnbdP# 4L)k%3"' 7) : `?|:?pX; հý v i204b8p n>T:*ϻM%$ E+6"mz Hff6͡ %ƠƠ # lʋ;]lqASw0<v[J<@ <} 3p h(*2HJ2K1pr t?/0xɓO Ǘ?n-GT'y6bP%eg %ʠ, #3P$0Кc`7.~pp?obU@/N <9J6^"P=^]c=AUpf1 `π|?dbƽo eضOcuݶ @߁` =eI?͒BA/4?`2|d￿dd`b/'Ȋ_@~3 Yf_Xb/ G^dص뿟O`x1e@.ova9"N1 4r  &F&~.!3p ?~}g~~a7@zafbK^ߘ\xȰ`o94bDL\1̚CKO*y+˧qsk:C-_ 1b$ο,`A`l|#Xb"@pcD4&nbxr*g@%y p{ lg q0H2^`pP`l, "2 }dY!On3_D;0Xuw V :1uË]@y  s?($d- I`;0A[AGCA_ fFV++71`?'w  fseJ`3L-2v^eafpt'Q`}W`fddT`fZ).6~` J2q3/?~?Q߁ILCe&7Ȇ߻2uP-TN}.",WMV2 gggZ ₦ | jp}pm_&@o?8dsׯ <" F KwU0:22Hd( ,Se]+=U ?|& >QS..i`Fw_(i<|O Zr RL@Gs2 ûM ?~_? ~1ڋ  ܆ <@a 4t(y0;ADa ރ L> _|(Tgx>ß_>|piۏcARTARD۷o o=!q_`7аv2L^~[PW\ŐX-×kA ?B/mq &6K2F0he0W^A h(7#0ܻ{ = Ljh-@f Lw~d.õ/<{h;0dB.\;/8*@< dɫ3}hw~1eVPXBk=&Hh L.@ }d`6{Wn2AXH=@͎KO `xw> ga-أ'zӇ ^cPVgr@\(%j20(j92:3r~ *e t(0aUa|z70ɈX3lW/ lP;lp/Ѐ?ELL@À?>0i;39?+s1|?Bs0D@!yI]LNkz>o{Nx=1*u@au]`Ȱ}C_4 ,C| lZ*@XAiM ,1p1Ikkp;W22{} &~ \@'Z'fa8|l/8ů?prQi# q)]xyh`1w*: d0op2%`W``R`lɰjy"Т BB 으>VBx,l ~``6Yam_VY6^`K+YpP 6 6P_z8Oy gc  V JjQ _>=`fVex$=*0O 2 F#X؀B(-<fvgOw18Ơm-̠oR (f@4Y 0K ys20?` q0X;w0j2Xmex y01h(px1A X00@ & H2mRje @ gi.+ 8 fs`Ap`^͠j !$ {A}x@ߵy?`Th*$.#$z:*_T*a0ϯ 2. **_XlydD%xOM_~CBJB?Q@Aq** zb#)Fz _Xp 3h0p)OAGfb 1g?2UunxUXKA%0;) >(ԁn./ T`&' #i toN_eg/3X  @]~Rk;W0( 030gd&X: 3#jN yP r/_p3b`ed|` ( AY`ipr3ڝpbƿ :;OB_=~ Ù[{c;pbM An` ʬ(&pg6+4;`g XgP6-v'%$``d#{=[π߃b b`^mp ^ ((Q9-.8rBL2C$CiP(I0H3d|ƢBZ P:vu^`7kĄ< Nw <:ܡ۵V#``b';~>('<ـ2 z)C@ I{=`_Ǡ#kV#̠g0PcQ=çX6lgx֡Yp+ G67 g8t6) rzqA,C+vAR2 FrXaIgxb!؞pX-wV238ؤ@m@O0@}b`~>y՜0x2/ |lQgP0 M +f`Pl@E#T]#AO #D!DbX<0>`>Н$* s|iOo^2Cy- 7á m(%PlHyPyrJӟ.?#X}W]ew44KeduFJ  0Hp3|Hv(&H?)nРVbay \y=Ú2]uo`&`- p -;.OԢyf('`[h!/d/H)i`0A=0P1 bba {Y|͚@c)PgPFH']H)a9 ^ L_)#`?jI 3r %Pn E}!h4PP^Ryd~+CR"(sCC ˆS&h2>W ^qCcawn:J`p QD<1# FN]f3/FknQ=%U5yV9 `IALK#` ?ÇL O`x,a}o C++qL|33{ r "B\B|̠@O_` y=m4TZEC4c" P JfA'nhcFv $0Bκ (}}P4C3>3R{?3? d(3IENDB`Ext/Images_App_HighRes/Nuvola/B48x48_EditCopy.png0000664000000000000000000000370510133521100020376 0ustar rootrootPNG  IHDR00WgAMA7tEXtSoftwareAdobe ImageReadyqe<WIDATxb?P8=@CI:!u 20300h L Y @,Dw\_P?Tt au=#Çdl\;[R@J"98rb*Bp[@1c#1=/H ~wvn+fbE,u"a^Ő_?vZ-`Tb@u8rlAr@A<Ȥce`)O< `` F六Gh1 @,(rJXCbG8 u0GC(d‡6B K\ZCk h́h=@PZC?jf1DH!WH XJ%x@ XN6H9MπT:g b8Cr&T3B'lebd@,$d  ه ,K& zdE9@1lBX?ђ/ HHd6n  8KH1D(+Õb Xqd+PE#J |rw1CZa>CȖ# _  z ĈF33buè4#Zc) dCaQ3?bYFyd%cZD@`aai<[3rR{`#e^\(4F e!-1bLȹ €=1uF]O$1W0#( T ̨̰Zu d?DYτ`:#733VF0aEFt$ߋ}@l[ϝ<2AA a|c#B٫7 Onc4fh(1K]gbbbx $@nZÂwQj_~4А@ yGTOIENDB`Ext/Images_App_HighRes/Nuvola_Derived/0000775000000000000000000000000012666315770016657 5ustar rootrootExt/Images_App_HighRes/Nuvola_Derived/B48x48_File_SaveAll_Disabled.png0000664000000000000000000000544412504535244024421 0ustar rootrootPNG  IHDR00WbKGD IDATh޽[lWzR&qIh !i)$ px+[Z奨HBA\^zIoݤh5N⮯ݹsx؝z]2=s}leX}}ni-/_tbqnL`X wK4 dsMBHPֺykc̺EZkͶm#Xp] 8z*xu&8 w#={VyKo,!3]M[>~c0$#-m3==M\}G}8<^ϻp.N=~;G?<v.z8$UVY^)9<*Nw.^⮠RHz&1M#DǤH4HX T*O'ۃ-lR2EJX-2_ǒ&B0Ѩcq"wWJu?]a胃Z'pFWIgRo;ݍ%,[e?~c l6A%,"ˑdd``Y" )Z)dʙJYߕW?&հϯ13>bmϱcǘl"AВ`3-AYW'͌7Ü7G)37JT7<4;h5PuL#mt:s⍬7WUu LJ!S \MFgHtGyxی@k9m)6>^{S.B*GU(,6ǫSW\I(Ykd7|_!}6~ޤ4xGbd2A>'Ns}%f,vؑۅ annϯv210tɓLNNn"Oe\ԩSضdY\\\xg>;wl.:& .]~y=@`!T`DkW\w~ǥ7[RvL9_ՍnhhYONJ7@Gs 'h7`3y4 fxPHЩ7`k ÍIF@)[Mx( iUyNQt؊4@F'NAkrl6K2-{ިi}6u؊41L49FJ%Q ̄RJ.A0::JTVl& );DJ&XaXhhjRHF1 ,J)nVRζBI=+:{FIoLjIٿB^y`aabWWW)*J)FFF v6?Z. "΁_`)?x#ZkjZ[-98s̟:ʮ_okӗ#`| QOk7|IENDB`Ext/Images_App_HighRes/Nuvola_Derived/B48x48_TextAlignLeft.png0000664000000000000000000000172212505257734023057 0ustar rootrootPNG  IHDR00WbKGDIDAThZo@.2H-*eTea`G_C7&fFNBR%\%9ql?82;NO:޻サr)ၗ14ͣDi c9OE`yșs׳ Y8N d\[4eEQhK+N88ٶMmx&hkI\MIENDB`Ext/Images_App_HighRes/Nuvola_Derived/B48x48_Window_3Horz.png0000664000000000000000000000325012666315730022676 0ustar rootrootPNG  IHDR00WoIDAThZͫEU5$Q$~\G hn"EsQЫo9ѳzHQ޽DAT 1hԐ %yovsXWY͇]~l_Ml1` \_|;"`Vpm 2dp8.>_x2`ˇ;G~v'C[|uC㞱Rshy3N}|>d B!g, XMW-1'eˉZgZ4 uf0l!aj jT%qkB FxTtP0*I4za:RŃjkB%`=^ cF/< )pӟphaH[ }`60 y{da~Ŷ6o'#_˥UFk} _!a{«/c0s'؂+/Eإ XNN7U@%h#}(\MJ1 v| 0K 8^17&BŢ+=P,<@BNV,"A_Y/ Qr^QNcD8yD"sR- Zub .R>٩2tIa1Ч|RHi/ 0d<#$)p7OԴ\T{_)8N1`} !" \K VƇx.|"e< T+9Oy}F+#vebCxHU\>,3eVr5uL{$}1`| !Qt(AU\eKu!QsZ) %A\%W9Y&h9]ʋU|?,ϥ X4cUFMb BM!Xq%c@+_B3SX0rJԙW+!T*ĽlRB0\zEKђc 1Yf!_JUB, $MZ2\iƾDg&&7+TM[&\ LIKJ; fnk襄e2 eD-WT\D&0}+\M#o1}ʷJ<6GebB`Z5mvǀQO[2♉,d@Ijk+`?JgBYNd !DFE1'*Kc<Li\Is1g_Q;}&dJk-Uu|#5 1=C[1 먐vjF# c(C񀀰q}oN]``*qss [3:{Mc *_rDȑ* 6m /mC;Ȗe1u]pƄg454d.,apW1 '?_HD] M3uy\ >|bPh0\;|-t)PrDT߱jtȷr33ʕ ]ص7mc;X4`{i_ 6>(qIENDB`Ext/Images_App_HighRes/Nuvola_Derived/B48x48_File_SaveAll.png0000664000000000000000000000601512504535010022614 0ustar rootrootPNG  IHDR00WbKGD IDATh޽[lyoHDQ)ZJT)$Gq\N#)\EuP  EZHbp\I5&ĖȖ`9 )Rv;3>3$e ,f8wفn>r;]dfn2irH޹e?θoĆKd@Z0d%*3 c1֮mmu5v8P.]z/ iX{5 O}K`2;b|j +u.q2C0WO=GO#E>MFЉ`1 `" ´9?]80^3~g9ɟ>I^zu}&,w0͔ !Y 8O?ǯĿ>ivfK% K$Z 㒖hTpK%AHP|~תӋsց7`@66}¯;§Ҵ!+6FB0z({-ܒ$&NĀR)rVIphM0 wV X CΜ#.M-prf̋4m77J_m:`,ӏcz qHT* !i Rrwnb]J22<;d<ηTi}YPnz|WxYW֍jMnхԞ.1 蝊xQӬks \}߿!xy2ƸsNn,P%',C,DL,V[Ptko ľ ܩεfahg /:Ki41J=9n,+4Xs͚}MFnXeIlB7^8}|(i=R 3k၄a@A7chDnr%/a&ײnCrB Ń8֭^|Dˁq.X\D@T 6RZ0nsI(nu!5aUSA`:Fp{ Ci8<(Y8X3T\Qa߷Mų9}\yM`lDoF1Br^rU tӝOgzSuO,z))KqD0)aoBS,X%jw5m ql?vyDa0:>@ߨb G݄h!HvYz-,/.RҤT*+KQ;&#р>2ǿv28l̓edޤ=SJJS4h+721чѶ+<)[O'8р Mߢ*|ayڄ<<}.\xhͣ`5+f$2n@HK/>w 067Aϫ<tRʕ'z f|ʳ0#`!Ơ!΁{<ihj(R}d{x_<M{.yF?9HѠ[<ƶ7NV ;xР;ЧMfJ"@xxA2(x~553+ ?Em5jX 6yვv@G[!-!V(OEA$ DKzFS@m~~H#A K5{1a|Ї*hNDhDvH5GLיL3G[OkC%,-5?#KtiWOجVVf|F-טĩi!&iݛ2)1a":fD7h`V5^g"TYٴ(4skJHvFLc&HG17'LƧm(bm5ՀֆF#!c~=;VD1kР?oY:#QֺfZZAiվ I!GI5w.aZ oܺ~/hΡB54ox;u>d ^T/9竿,1LNpu%Qt?_u5XufT:+ Ь1X:̞]}d2N:uՉݮ ouvvfַWJYf<(K z||^x!wرcɵ^qPsr%G맯'Q(~;66SP[~_ fpX5k.b͡/޾lkccӮX,vwww_۶jժb%@mmYM6GSaM6]W"yDu>ꕗ\r<\.s!yy/=( $vOxA=ۮ+nU.ض.  T)9a`6/D<$G 8ٳ=$Ó@\U3na1 S_CH]Eݒ~_#P񶶶ض纈H( xi薋f 3idf$cӛ2̔͘\\ XBD 2CChܼ_6 Ec]RoK慸EeiSE *gS6XC0؎E"!Ft).iq3Ida`3Yɕ!ua_jC,Yu,opwӬ]P8\B`f&͉/|kY,}Z.6 rۯYˮ~A4HJ|OM O0lHv}q\?$,d0Y4m' 8n"HU1ӺSg [S@`~ nxąRl~^ʳha@Q/Y} ?;w7 6"Hdeض㸈H6ĉT*5 $, O_CS jS}~Ґ$PtJ4@@1C @pED Bl4IfǙPUAItgh쏈(s, f<=s/%຾"QR 0LA1z{ $x>d MaE& G-@UCn*n(z3N-uQ0 @_k%͛"('y-e$%$ (_Xq^_~_HG%װ-I(tMƁ2GOd%+o$oYۛq}wB]]-.$LJ8~ 4?_YOЦr)]vԶkz]*(򿐦W\n#P^w.HϷot,z2HdFuB(ވ+v}@w=yS^| L͠'33Ȓ?CUU^a}vN{ W,#:a`]%vm7Һ+xW|OۘZOJrliLM 8i}¥[f ̹S(bg387"UJ[UErĜK) 1&L&W"+"TN-%70g?;@^kC{Q^X@u2(b 'm<%S*J( uȪBqj/}z,h%iJ5f2(Div'o2;?.g"g$18Y}g^U06)]5@}6+Ρ.d:lhnidԕҜ+⪵xKf$9Ԃ\sxfWz:QmϵoÈ8LKw}[8q~j{њ?c8xxź!^M xr Ao|_E*J* Oe'ّy[EV􂆗9R@xN+kS3E5+'7rcB($\ȵD@lZ.yBGnǭU;hAB˩\?g Hp ٌOZ^3yMlm-$Ň;(?:[z-] HsÜH`uΣt$CX8ێxBU)W`xp@Q#L(8I:9 `˟h"w붼-_N4ޚHz Җ&6M` ,oi=^ĕƖCbHtz/ێ*zd 5A GQYҞx>R_k+ )JIVE,IEbR=.,7`: \J="ZEB!CTCjLL2=+ϺAEn1 INf׿/}LyCrյ|r13YGxM{Za`!\}trjh)Wճ@ abз~3W )j"AP%tF7m-aDq =?OH%}s>p uT֝7/ sW>k0})l!]r.FݰM?mlZO7#J$ TXU}j!Q<)J^~.^Г/khܽQQ*fr~+oū3OP xLEk ey;yվoެؖme[',b& WI'D5kF I3}==1s} ~%݇+tnD%\OSe?-`^`-.>S=1 Ů 2<`͑PJr ͣNOL"ࡏKyZmj~G]JxpSloq9aG2V?V`ߠ $3V=QI8yxdcLe ZX(뮭d'_^;a!غ.k:5ה0__(C\' X57c~Z m(Q/x ],cet4 wٔUL' ̜6b/ae XL=.d!80s,x x:-E[ujhJɊ!L/@vS7E1~xm`+eg<-?czVwE H =9kp|ˁ" /SʇeNkw^vvEDOPBdMw$Vr.:v_^~ӇXt3 V!PTe ܣ2VfngR @ .u??'k:nksuNll̙TsAΟǠY%)_A4@k&NXuط>(Z:O Qԋ@<60h\&UwIENDB`Ext/Images_App_HighRes/Nuvola_Derived/B48x48_TextAlignCenter.png0000664000000000000000000000171212505260400023364 0ustar rootrootPNG  IHDR00WbKGDIDAThZ=o@~.HB`(jJY:5HؙPvn11003"vj*I*َG&ǝ}I''yy;s) ˕{D/ c9}t܀9Sz||VV!PP7% [qNw<`|>;; !HAy4u]r] r!۶ɶm,,"9qΩSߧ^G^L$"s$;RYZϸN^KjL666pB5xedE}O28OU"}oY9idcQ(P{hg;:z+gMq0t@$.U zΦ'P\f8 J3{CrS/ 2%nuϕATG"E$')f_)R_LR_+̰vݰlـz p7͖NI eȽm>3OṁMuŻ'~u+CdIDpmiٵjw4X'`W  :ԗosUsOV+ÏxCv@/n}Q3tTPM!#Otl:O>W f~1IQ̤=Oٱ ǶvL@iج%k-6$j& (AX|Mq c!d C>X)G< vw:MQl~[F*͏Jv m[؟G'M5`A͠uڴӇp_NlY 2~̼q8TL^ظg ƿET:z<DַFy<:Pk޶[o8fP40ˏ\.X',a8bB Iў} ;wx. F=~z͐%2 >>qN^Czo 8vs﶑NJ.YĭMRU&{1!B\el~`yZ1`Tn5|:|R4!m@ tTCZUyц:aG휫Ժ!,¶+O0j.k}'"LC !O|"!ʯsɍL&ZA[H r !|$:-<2`yP|9laXVI3^痿Rʐ(TC6t!Ю d he-y@ D@P{ ݼ Xx1>h QF:dB}q奍`JJaBPmך~#k6YjR3aq xE@: s6@t\ Ÿ{`ۍi?tt6zk;U8YřCI)h"jAIXJXx51*[0?"V2'JlmWZ h/x${ﳀ b;)$R :Z0lG’H(˅8UZB$&᭻kP`_&*Y>FHָLԠ고 ^+Dްp4KV=_J0z3TL@3 (hHr65$=]&m3yWUzc[, kjm_ @csw,nժh*g{(3AU>6./TU~9[7hk{2"4@+@VB4{V*{5񠄟 &p /YL$,Uk:TK.OCsr4S3`$PªGs|zܯΌzC^TLn H4%oQðVۢB H_ Tw8Ʀ1$ im VK= UP@` F ^PCg@ V=A7vX̂$U@{82&#ڦ3\ySul~$`{66Yw&F*|? 63{ReBMZ _w3  W,ӊ5 ujD$T(?~:LּPh^0/'[H?T@ Bp?'HM?\KX8*t%5!/G*1{iml%4Ȳ͐iޕ ϸ Mp$q0"**s6#_> m1SY(ۊul ~WlGor,\rP2Y Kvuy6v8t{J8cL SXuG"cOh/~b\*}KZ m.'rpũ-/cՓB?5Nb"L ENvϿmU /'$&!̓Jlz:Aސ Nݑ" 0r ?w;zejXs0N6xT94 F@ k[r7YVSCy-$ǴBEI_r YڊhߜС(7e3ynh.$[Q tuԐ7!3%txܺ>5zL;f`g)A @]C ,h Ͻ qy2ȄOC::MV!t*xYMY_1fY}rHh'yZ@Y$Y~] 5IENDB`Ext/Images_App_HighRes/Nuvola_Derived/B48x48_File_Close.png0000664000000000000000000000576610125245344022353 0ustar rootrootPNG  IHDR00WgAMA7tEXtSoftwareAdobe ImageReadyqe< IDATxb?###5@?2b( .=#@1R@9@lD!] Gsrq1033p0jj203|5o/^0:s a;ȸ@'3D:^@MW9(LJALAHh06Ȟ_=c`x {bu.4yx0ݝ!ΎA?nb I9 ~̔ v0<@C@|i)  lC21< {Ob(>pxf'!fe`q0 C`rC&P,;;Û7 s`=f] Kvsrs'L OU}TXa66 FgQpO1X*<$O,ػ10{Xg,(莇^ eAz ɜKp0N0T~Ȱwn߆ GH O18q8d /0(c q/b P6 ȞҜX]\ `0,Ǽ87A@Xh^`Q R@ `aOc`@ [`db>002(CpB5@J!5mmHu218 J!.X7Coq1X*!'`l|x1C10qxb$'m @0(20| ia.3]oa!AOpk{.h%ɡ0 `t)#@LpGO>80goANL16`|a R@ XPBXbrV$ڷ7?oLt<0ss!`㑓` TB9`IB`PQ RSI 7[dST˅t&h! # qtB*P@=a`!@0ISWcԮB}b=@=@\/3<6E*1P } 4 of38YlիD8=p Gr $  .<>A 7l3>c  ==cP!<yV%/{ F/yᱤ$Q5,15}}Dx_@* `WAFoKKK2Nx(xҺ@(8̐( r|1,PE79'@u]$G;K  a`8+)`o TO3)7) '@Q~4` @1H@!6}ϘI)/ 2<^ P5,s%Dq#.!XDg 2`+4Ăd_"bL_'+A V4 @Z@8<O {;4^6vw| R扙Ձu  030Pf M£IfytgXl ș:L6!c b Iy[ |`=45#@QVBXA!d2A7 .8̬C< #VA#מV̀E//zJ؛X|7XG4 Fj.%1hf" !`!F~IENDB`Ext/Images_App_HighRes/Nuvola_Derived/B48x48_FileSave_Disabled.png0000664000000000000000000000262412504535600023622 0ustar rootrootPNG  IHDR00WbKGDIIDAThYKk#G{1~ ",$ч_ٻOI\s@.>||`lfmCf;M=%9 nWwWUWuH)%/|Swh߿R@)$Pv|]>~|{,句HYw:7t u7jl>8R^/?=筭.:!0DVR_ћ=!s}stt{vz9,ZRJtBp?+8X[[CL !,nzPJe!R!cZ-K'V& XJ Ji ]1ҿS2(j=9)|QZ􆩰*lnnR`0(#l*$(w tY10t/LN `XQŪ@Tr̵^QQ d(lSꮬZЌQ]E!]NQc@Y- J"JYRS [6,9e1i`wJêD2.W}[e<+ -*@&S8S܅l@ =uNJ3oLaeUf^9/:tuK bRLW\Wey@p8Y?zTD)E2L8.T3@yaL*;ifU1VHxesg*tB1NOOXY>(L@"1`*uM:cH8??_dt]ATj6u|߇jpShbNWPu)TA籢Ȳ cY\U圉&9HB`nnn cc B)SSȬ$(H>|Fey_gt(T֖)B8<iq\qH1xI4e8E!=cJi:SHm9REeY]eLchVŜ^P]]]A^O +l Ѯ΄aMZIENDB`Ext/Images_App_HighRes/Nuvola_Derived/B48x48_DeleteEntry.png0000664000000000000000000001022712504527030022555 0ustar rootrootPNG  IHDR00WbKGDLIDAThytUս?s 7DB$B" Bڀ[J}JZ_{۪'mX"s@Z֥"Ȍ H&BI;RE-u>{>)ڪ<Nu.~p0n%Ba%]]&|OtYY'?7yZSm#OP.GFƪE)kj"¬Y򾬬(#ɋ_:U#7 _<Īܸ/^,ey~I|7NV~XpvQa:9y2b5kdd^Xa^\>)\pz8N_^Hj=IJ9<,zH33v::QӿXfώ >>2Rs .6̶ZMSs箿)竦zp2{6QsJc1}۽uө\koS RSת8ii #99%mm뵋 D@F녑P!eBY=f|XQρX2by*!tW9KBo/hDp8{E݁mC}A#t.|>Z]M47WnlhuS4-mZ5l~sѨ[Lu׃=pÇgņ.و ~uOIyo) 6 SrUpM8;xun^Xue (@@>lե{7FΜi$OF(+Kd ]D_C+耝;@@y4'@mS[ө|hhk@Jh97Ѩ&L焮ߏ$ByyʇF!صqꚸ:v!,:^ á|6HJZ5k̙J5!)l__McqudD4m߾V< /.u?oMy ʡ?n[\zV|z]aa.,Cb A0FAJǏ۱Cľ;׍ };>`8B_;R֬~!(}3ӕ o-x92 k~>rd$D"9MMmrB_BfTg[1ePqxqH޶MwnsPpsA>Ò۪\ヒ@MJBh=½or E7EU%؇{'d?xq)PZ {Aͧo}NoD߱Qav%W,)+*zM3z[ZS$iٌ95a6_R"C+p(qA!E`>\qU dB2  n:L _X8kW=}Ƥ'iL7nbY\PTvب(B`2.)%BUQ-4ddzŔS]rI7K~_ { !]f{dMK"C}_7XҎ;L0 mqie 32t*p" Ąi(b2hf2٧No((%pϣeD k ,@9g@d4~i.2Ǐ.le咯8뭷T1y}B(ҧBӴZ,=QRUe9Wtu7Ax>-t3\_|2#^Z .^Fn2- d•(S:2L/PdRo,(ïXy${VѫbCR |@44-JkkMe WSknLk){"duZAĸ5]0Bs`0dQ$/mBQХD&i:"žp)U- m.(juuF@'LK?+#tey n̈́h,0Y)0'(DУ!>"˧!v<,5B+4 wTU1ܡ2L$f#w2{˜4ܲeRfnv͊rmq5&M쇗nRn d'$yun#ssxIg!MnPhEŢ}G|>%4bqNZ>KRҊ1&J\T~E3@MSyNE啕72i>8gC(YVnna0c P_;\tǏolFoZc6 YZI]׷z)̙TTdaXPM&PUl}YMYYUɰ庛RݕCnգX쩔ϳSuFc$GD$>FЙ{peT0It>q<-v[owGg CS)߸cBM<|BQ)Yx챭pYHV2{"Ip `xA9 I>bgwBC7(qj(RUiizczҸXFUջuC)oPV+(ԕNS3厧޺ =ʽet&qHg(j ,Gelf@DA8ITzfèBQ?J,\./SѴiSS=\ߠܑDSeܯ< $Ɣ(:צ1U8-3˳D* ep ~6ێ&ý† σrIS7oOJk&l=dܘYJ>obcDƘ{)0]AR^>2(M=čٗ» lOAo9I--ƍ٪S:1@`.k> 4!R'9Qh#T^aa⬫9ggx?7?jcUpi\8a7P~%?f'b@(ŐSkn!( 8\J$yLOd]x%`D}0v4\Сl9L.X J5;5d, 9@ p ̠`Np ZNR!m|Y8|Q>lsTx]Ba~괱r:qg/Չ<@'I1|S\:@ǖF > C/5hoh 1Nuv3{&l3a!y4[{s,=P >ufmJ >23S$0yG ,#'f3NfWBuI*[H[~)iZlа}HZθ`>!#~ 6Q]N{ע= (p01 8'C8iIENDB`Ext/Images_App_HighRes/Nuvola_Derived/B48x48_EditCopyLink.png0000664000000000000000000000513512504532352022674 0ustar rootrootPNG  IHDR00WbKGD IDATh}lU?yo-l+ @4: Ĺ uad-H"f l aK4ʘq?4hbDEHC)Aල޶<ޖBk ɞ^{ иuQX<;a>7n Xt/\vqX}}Sf]g4&Nzrs8tY;[G}cS@h?xhS.;/^kM@aZ 8s&Ck}BQ?Ȃ' H5wU8HuucJ^Y TeǼB4MCQf٢Z^)B{?( Jp]qrK.#NHR&y2"˒LH$rYRlٶYs4 rEqH8~8 /J`LTMSS#Bjjj8z(`29͋J`b8|0RJnJ6%u@ @(BuBţ1L&åKxwbds9jJR`ʕ۷{n`y̫X(dX,R 0uݏ !@uJd.]˗ٸq#J|^JضM?`f>R#ƫlذ˗ŦMƲaʲ t1r>u׳|rb7o4MU)`v: G~dn͚5a8vidytuu<`i:RA΃>u1L&Æ Hٳs"o:BfdY! aK R&OR@4zilf455.eyTUUZP:ljN*q43`H:vM{vAcc#"LӃR )%y\%YRIuYb---X)%J)N| ee*p[z(c%b!sXt9rO?hii+gPr}v[lO /"+VRoL1M6AOOO>$RJ^۽t9l0M遦 !Jz@!WE!x_ իWsYfϞt-lyJ3DMә7;F0ɖ-[8o|vb|o1crPYБq\H 4 tZ F4Z˲߅q(_qqx]T\u"SIY * $4mVzNU6X6vo (=wc-#ÖfQ-}O ݍTcGP7*,_iu VƳi9bd6\vhIENDB`Ext/Images_App_HighRes/Nuvola_Derived/B48x48_Folder_2.png0000664000000000000000000000663112504536506022001 0ustar rootrootPNG  IHDR00WbKGD NIDAThy\uzMhF@ )2{D $@\Mpb@1T HT H!1vL c(%`HHY bFh,{ޓ?ЌvUyUvwwν߽D_K+~Վf/-߾]fG*Ӓ)>vMdQ_|V$@{ kN+-uw`6>3)?&KI@KH]OA+DkiL¾}|-Aot3KᇚT>7}"+WIk604yOJ\rz 7=uyEc jI=3U~hc1x饍-xEsnP1bd+-M4pIiVNќ< ~OԦ_ 3ՏRG~N.oijh{DiЮ0XTS zզGw6mυ3,rF+i洠芏Q=#`Y !9'iRe@$jUZAOWq''028(~ 90 ~}\2XPI(XVS,@(`,Vrq 0Q-FQ!ձQF-ff''PWmU03 h B9oA `D!m ނ  Z?ѳh` BM  (?ÀTMVFm2Д|h9"SX R(8^q?e'/ae`]xnMFTe <BB F"AM ݋&n TbmkhnJN@9&7{ Lt:6ZX=;"v%d,n-9팷޼~M~UEK}g٬wd.RR ;HR 󨚞;XБsih] IEJ~j|t; gTyj6lI<=xמ;o:[W?鹬-2=j:PA;kE7E\ "Wg[LV&QyR#;W[MThԘPoiN ƖOsWϰs;:5R2a66d2=zC9 >cs8μ;Rurgឣ+/\F=[[VWU9XLm}Togzz~e{zu.Ϻ{uӮ'q|-2cVG_tyۺ.0U&ʣ_[W Lez^/4;I^PΑ7'%?Uh^5sKdzF> Tۉ.Vj.LqMS:QmޭoDaO|hfz*"G'% @>6ez&ȈJ^(ұ) @MV"OxX# 1=I(1LJ@ś{{8pdџcEF ~o045l=o?j_&0тGRiND ~[RǑW*.q$F 'Mԋ5^t:H|S ٪@b8Bͤ:UMw6;ƴ PaՒ.< gO`zWju\a`Mg9;7(RxW6T-Fo*GՀq&?g.WY=s%Ik<\crqã?ӝ7=㺓 UUHB_h `нq3\>woY1(9U)!6e'5=(U`YZ hhokS.%%gyp7܆t5"Z2jpD:qTlVGfNnzg"bD J+W4:2` o<^|͘~G)49>xhrba1yfݱpKK7{+Qr,HBG)ZHze*Fca528`Mq,$%}{ٵ޷Kv:Zz@B7?ɭs8eN+Z { wn_xÿZ%JJOR* ]ԃQa7 =Gg'a~'Jtk +VJ7Zas3tx PVtv&˗z٥97l,)z(Dv.c>s8P`hx>{1ʖF0pl2 k\X CWf4NF%[2w\ *^y IENDB`Ext/Images_App_HighRes/Nuvola_Derived/B48x48_EditCopyUrl.png0000664000000000000000000000701612504533504022541 0ustar rootrootPNG  IHDR00WbKGD IDATh޽yp]yYղlٖ%o lRP\2%CNRhڴHf2@'QhJ @\P8 Ll lcYJWw9|?νֽa9::wg37ǽ&E1X?wz3vmH 3M D3<={Jؘpԛ-mwA 8U `o_>,X̗|a^qut}ѱޱ#a}"?i;O&ᢏ K;=Zُ\ߗ'wȫ䍑I [yb>oN{CEfl2Y p?cn^-m7.:? ݲ/FrlqL|ysZE2Vx7쿟^d͟>Gro ~XkO^05\)C̾fFeplXF$)d$@^V^VzFz{[gG kXW}k^3tuF cEhhy>~O{xHiu(7;2vޫi+:Gv B%l:>۾s]޺#_u;|#v) d(ꐔ+6a/ÌH+}mzwC_8K`.` 7s,;ivwLY@x"N*9L*6^KmC!h< Z4Yfr{>!WtN`ǁf~ǞOE,_Fͭ)CI2^Csc##Y"$E?X:} ?ls%;\nykԥ\u㦵n _ﷶ7'nɛ<" "hee"ڛqbY2Yt`(=l00{#>йv"cu=;jƶ{&νdSխ?[xW[t˜˧ps-t$:EԎPyl6hR(F"qo/4&[:jWy4- pK,ﴳ{8~ mCJʜEݖN44VEzpaW1v2k  m &/dD5ƶ΍@FP"t!l 庑R|&,8MA)k Zlea їĭ/P`4bD¨&vTi@ϋ CMUK_s'Z|!sk˜3^7eZL1pbsCr Fh ~G 9xS^ITJ}i#NBVJkRK31"V(66}^SPDôDgs:Ӓ";2sYH'a%HX N#DU䜔L+=b;jB udluWGvyV"kkI9)jjvJ%@QC_ 6Eߑn~\{U2k.[N%mI;in:.pkԡcFZ4Givirhtirhtiti4i8&9 ~6v”H,Isut7|”H v#MNMHS$7ڍ4LSYSX-.*C<1ҢoǞF~J}v L'>4Y'"[0Am&|jCKJn-ZF_.u#! P>jl$e e([~  e`|v;sz#BKLQ:g4zJa`wIZIꥁpuI:a"UFa–d/*{a,g:@vϻ7 ݨTߍ]ºu\5ĴG0@ɰ=ۙL)#N_2 S6bC|^pC/sǦYsWO~04ihtßg7ׇnN.dѲ謅VˬzL6œ]&0'f"7ٞXh?~.OKɏGFֽ\5ӈ."X徽2a_Jr $iW%1MԙG'trg ROIm_ A‚TTf.?|ŽgBs C,3OPҟ)ETV W&_˪V#Ηdr+TNr*YtldU1^PK L\m&iטEEL '- K Wl.Ul'Y&yhL*Odȁu'BT/L Ej˜"uY@ + W̄[.Fu2*,MN*FWH%_&~bYEpĀFtHQq4U[~'1bueDleP@ o_}+5KʼnILemW* -yjY3>L֌u`-(QRS;R lT+']'Ϣc{Ȯ_pٻ}:V9\^ ey?XCD܈ ZIENDB`Ext/Images_App_HighRes/Nuvola_Derived/B48x48_TextAlignRight.png0000664000000000000000000000172012505260102023217 0ustar rootrootPNG  IHDR00WbKGDIDAThZo@P(m*U Ebح[{ɐ.WֿuСsǪK2EUAH gcuLN:{w޻3Ko0P_/--}Z]]!"/K{{쳦ilsf }pZuDv|>eU5M8YP\669,J`q!F*HV`8Kė6w+(kQ/0=&>]H|TRƁN+Յ(]3FdUYZ 뉉+ڿ5M*4OLBeyy9Hjb%́EJ-\.&WsaR\h\H̥v4`mmMf,?slVҹH҈D.$cAӴԹˀW;-~jHDp;_}UAN 7C"ǾȽ:̾=pL`x.Xmw}ǶoX}ý|'܌OxٿDƛNj~v'~ǡ-9C㎱Rs8 XJ8J-1'q҂_DIcMˀ 6L`#$L0frYB&a?/G5q(/ LsR{*=R0^~`R؃jkB%X׶M)K<#[+DǴhdpc g,\z򲕁2fAoM vá`[v߯2oj!^;x m}2z=y5088wiLclr'^zn'z=\_&Tju7<~e`P0(F@JwH c1 &')^T<(f֪BR0GG&U !'kDXXBdvVc"AF!]7[mzX+y%`Dn ^B>E &x4P˙'J BmĆV P *+).g1.h[h@ˍ8 &^@p¼f.9 z2b*#Go D!Eyv̧wQ$]6` B%B"ܨ)B&ܗ&D6%$~!in '#^,ō%r!P,Eya:g!%S`$361̍t]RɜZ+$6gD/ޥPN|3/"l-SIƋ1"JSE?`<`` XcC0en^^U5'{FYVR11#ln7JmfqW1ПpcY iĹY9yj2&n陳yP;9V ;i(}E[ F|ǔ2%iM bRѣRGȓ9?:.V6%7%Ӓ>ďw`B$Z䞻Yt? MDF8,vs1 dЀ0wyoO^ [gɚRWoN){@?s{`t/W6܃W?#qvG!NSc4:n`vإڽ[f&v T}ࡧ¹ g}Oh/cb+.oaXUn~~|wpqN :K<5g%Y_1Qf;1ݶg~wfJ*VA˜R}WuO8T,IENDB`Ext/Images_App_HighRes/Images/0000775000000000000000000000000012666315216015151 5ustar rootrootExt/Images_App_HighRes/Images/B48x48_FontItalic.png0000664000000000000000000000560012505265526020675 0ustar rootrootPNG  IHDR00WbKGD 5IDAThYi{z`d=6 VZ˘hr|H%RVb%x4ߒ/FV4cLJ "dϙ=fˇ>{fvvVs]~;o=r?`.0]~qWKꁇæ Gߑ07R?{6:P,HΉw.r@Em]dPPJm{ SweA1@a fr@o-o-!DwǏcKhb F$A8[#'6$ȼ)zر:ԉ܂)^^FDT iLQ*ƞ{ƚbZ".Oy񪃉8qj9"Oyex-$֮Yby1 to,^z$ Q)'Rx?axhgKqH\T"JyVkLf;w"w'NtA qa7[{@y/#}:f"<9$&:0lX:RhL+r\8IЄy8oQ.uh_)?.f_& uk=/fAoLӬAa4E)Z*EJ'f2 λ{V2Yea̙jǑfKzPL eC ZF^ MMhko(fdM=ƨeYHjtd*Py&L76]T mh؅|A(ca``0ƬWR}V{MNPfX>D x琰8l8v  3 DT*+/\ D\2FQxx`ohnˋ:ǽdXR`Yk E1")AgLo#A΄5 m8s_5J~bL޴U"0}ۋ0 s:`IuWeF+l OFccc HR0 y]G8~>8 ÀRz]adt"Q!$=1jٶ0뮇 uh~Mt^Lе572IS"D"?udv#&"A'BUB2ĉ'3::d#B0> |>tOQ8p08v8<al,X8rUM|P 7os8zh\%3j߽ѱqyg71̘>s.ŋ*lR>tw@DyB>V*Oa(pW>DhGhlhUW@aO!34]^EM}P" pb(Rgr (o+@(5 >iGi~u12ETOEٶ5kPJϟ#)쯘Y*ϫtUt"uER8aW3Tؾm %%)U̖Hw9@/u?WPևċ[R peW^unӆaf3ٛ͟犈ֆw^7\}ͪќ-p?;vEK.X05 r]*UD Zk 9z>t=2/K4guVu/Y^_g=E =\7IsJSfiӧyv?g8tŪ/L^Qwηo쌦Ƶ-3g^4cs ðz)1QUJhAo\%r'??x`fOoy~ς ol6F\Ic&Ɔ#]'o(~s5VœO@ `1b`@ C DU@L L R.@)rȁ"G9w /]O<㭖Ӱp~ gFF$_Po/֭izvS\kAeH%dҲLSZ TBke*" " h)<ҋx]qEauf:v\.XRk"n}ngWH&u{ӧT3jphD*7^P7\3+Y J(P3D ED 0HҊRRVlKp]y9m|ťKcbi>ۿ9\fC2IENDB`Ext/Images_App_HighRes/Images/B48x48_KeePass.png0000664000000000000000000000622612666314742020204 0ustar rootrootPNG  IHDR00W ]IDAThŚ{tT?L&$BH3$^! ^ ڪȅ>kUk]ޮzjջ\UB[Eu`xA^L2o?朓dBgΜ3}w~|K &@dXF(p | qr{uڌ< ŨQe0`@>AN5a؏A`9+z@K[,++_bmP8*v%6%6%oߞ|ZJK:Hx^j# Ð3o7I$%@[T-Q9Ʀ46G%*-A%@켩%*k}"7M0\qL6e!+++YL8 !8 k(AuAb5a6!޶~ݻvmn,YK/La D@oՄB{:9xPgeb_Pywr\ ֋/dggr\s5ƃmB8"q@;@ڱ=wp)@vv.#'R2c(%LFS hnn< p! \F#BM'V#e97JEnv{qbN%apa=`{;p@YVo(}G}V;?p`/?{vnWaԘ+0&f/vTwq^ia-Ym΢vdds|Ԓ1ʗ QXb[̎W`@YYWNq9A勊z^i!-CG9N%$5 SQ<o+T̙36v-xɒd=xZ/Kp!?ٶ$ h4m7-,4hɅWS;x vD`7GkM $++#,v%f|+%$h8@1c VV ˨QeaW\.7L}hǎԴLi.W_ iQR)P4Dp{ij:XdsA 8V-%yw޴,u=5}IO3wW,1Sr7J]RUsot;s-mT7;eiWZv~i {I7plL/ xOkR¸kef;H]ty;/(?L.c:"G`=aDu fD;;@UHr'î^Kcb3 4x<1`ũ9_De-xo{4iY *wgz4#eĸ$4dm&ӊBRi :9xf;dT8zw[%ڴ*LEJA((]+-|k=T\9 bO4,3V29{OǙN YWJU쐭!h}of]_A?߻#[בQ/u2+іθ89rO;4ߍݻ@o+P>fXn cU'ة#{طkC0nm XЃeüiw8e7VX]6HI{oӀ։6t=- !;D{g=S ~ v'LTŹ/]N/Ǧ 1J:Oo#xVZ ʢ+_^x`}(.s[- fW ,~o'_dz*2L2RMζnʲ'ط.уN &i…d9pTO tS\x6NdX'ˁG_7mc+)*Lq[)BABmB%" j)Fqvle5-̸+"~n&bhCSp{xӺpn_uty|ov%؉šw?yGoHꡒ:=acGr`/<͋/Cm?ou ߹ %V0 3a7XhiZcx[(#g;ղϲqg;p受lmQ<[g3)3t9sl}{q >?/@ Zɹ;[FFF2 rr˰>5pIg|i> pzIENDB`Ext/Images_App_HighRes/Images/B57x21_3BlackDots.png0000664000000000000000000000046212666315110020553 0ustar rootrootPNG  IHDR9vFIDATXؽ 02ǣH (@pKc$\9@6'8$=n@,N# ّ$]8##<P̍́fpafӁ,L;(RqIу#xNt'6fgIgޢ# ;٭$Zsf`4N4W&2Dl3֨sdҴ3+6_BiY˝]`Y @>WӚ߸;8IU5IENDB`Ext/Images_App_HighRes/Images/B48x48_FontUnderline.png0000664000000000000000000000577512505265650021430 0ustar rootrootPNG  IHDR00WbKGD IDAThYi랞Y݀,``eT+wUHTh|O>J,xE`awwE@cevgvgχ9vBR7޿贈/ x7mAX ee-KY'z <(|3n KP3y22P,$D`=]!fȑJq9>zn}i-ۇW(͛??رc{֚L?"\C! a@#'>OvF""_zDȽYhEj7T\%DZH@p3;! @>pws7DcƢ̊3۶zݼi]@…NJE\( Rq"@Qޕ%U'qJ͝7!G6onfɆm  15"PVIODdm&4"mCF"uN2\]] `V$.M(0\ *Yx 9 (0*ẅ&Dd&%8t6eHwϸ.?O[ ](~0"O6%"@Zu] t7׮^ό~I%ya ! *یgbߞU@R> Rji ] KHTb@X`&Vb1455(OɭHjk6PI_kjj96, m%?@t|0"BIP cG]kmv?AFS6 ԇԈg|/Bk 朸8v慎Rʷ P;U QYHQj \l>8V\uCIx~<0ÍBR[AKs ֬Yߴ@G3_ B\uϜG@u;/a0M[WF* o&aXv@/l( DE}ض{:;1udbxf'8NQ^5k QGY$O׃uR`my "B9|chjl=e% p17MuuuD"chofҥ7@eYWDxsDpA'ى/ّjАn1/s04x-TTT`3&H$Vt ^u bBQs]:* T({՟zt\#!Nc׮H"b1iҤAkk+ {L&6|m[ap=+`{ĝRi"dz 8n_s{DB[Džjmxuoi۶p]_yˣh=͟;}E#QFFO~4Ғq9y#{>~tgdqJ]үݰ(Vfm;o'"]f_ RV "~OnKWW=ڥe+Wdo"&(;y}u\EꪪM0 *q>a[*0[jq3vwgw{Gg{ݽɿ>0s,"vScZJ VO|xZ:.'bE `a=1X`,C aр,Vha(1)0H"xS \E*RU^|;+`S7٧ vY< 3zLo\(H¢Y4P0<_=&mr@DaZaYPD\TȘǜ(p ĀA]I#9Ĕ+\`h$.eM\ 2x*Bͩ@`D\13" ) lЗ ">]9c>8Ӷ\l ](0"'MQğ[`8_xg֦X`Вϳ@(% A8ɵF C@^yeN:-<빀 c0֋Q2AB Ku)4Mj @@[[[h+xq/A.8LD1 ܇܈ ̌'NZ9cD";bE.!n)r4 + RZW_C"ʕq뢽q?0 TbGFǁ$Iy睸yWbfA0%xAi<>s@ |M$*+0c Wcll,|ihiii|(Pثm2%X4], ؀x<G;¶bگ x6 SyGmja0 5:::`Y Ģ%HTishkii.t<2r&fpp$hCmp7"iHR!޽p 7 Y]]a ϧ#3lpƃJ@DطzVb9P=<zdaW|7DZsG3"s_,&2@(V60TnD#Q,vaN .=Yنt ;F8/L{;\tu91MnE4J($%/Î=;;ozzø(7̈qGô>xZd2VR)%E}~|l8{{~ X;c4D,Y30uԢ&"| z{zADh݊0cܹp\MM"BD,'De"o_e Ɣ)SJ pD7z{!"={.DRX'`[X.t".^X&cު8Ji7.\h*584)ύH wuX˶PSE| X{N;," ) J)vAiڀ3AAU뤝-Q"k4rxEr=. .ΎX28nwղ PYMF`T=kBb {R iugMC}O1N7sLWDȥ}o_xso'g̞=5#r] .tD&zδ֒m9z#?3iŪ;\1iM7.YTn9_~9*Zʮ\e`uM̙38AԘ=q\5idM '+DGȷyuՕk'/0hfS.|oSh)uW)CVs*eq}qkp``翷Ϟ=-kjєɠhMueȱ>|}ͪhĜE@5 `1b`@ C D@L L R.@)rȁ"G9w`زǞmk0gU44<2 Vft2\3+Y J(*%D J+JJ)ZiFXU(j MFkt,:.FW8c1L&ӎ9ƌaX: rbl1 {{{;}#tp8_\8"Ey.,X%%Gщ1-9ҀKl.oo/O$&'=JvMޞxǥ{=Vs\x ‰N柜>ucKz=s/ol|ϝ?y ^d]ps~:;/;]7|WpQoH!ɻVsnYs}ҽ~4] =>=:`;cܱ'?e~!ańD#G&}'/?^xI֓?+\wx20;5\ӯ_etWf^Qs-mw3+?~O~T/ cHRMz&u0`:pQ<bKGDAIDATh 0B$swc]5)ovIENDB`Ext/Images_App_HighRes/Images/B48x48_FontBold.png0000664000000000000000000000570312505265344020352 0ustar rootrootPNG  IHDR00WbKGD xIDAThYiUνf&"B KJI hX BTK?%DD ,'Բ ?  ,&$ZALLfyKws~,aUu}Ϲ;>Ï>Xl%_m L?8` 'V,[Z~Lqql /Yx Yr*'w{Ug$~/hyEwmGOX>|Xl%yl_;;;|ͷBkM~D@ Cab>!,X"$~ U48mqhrY1222e"u1ᶻaH_R""BHa0ˆ1LUsNׂ&r5iEoŲFX2 J)*E(E@yB|+X(@H icF3B&7ODX*apٳRE*"bֈ@eL'HI(LbDѽ 4FFGp)Ya^Z̝IT.UM(6\**UY\"PErG Ƕ!"uMKD)80` U]C"a0L_BSk߲? bMH<"9Vtz^qʩEI>nkxmHb,5V^;ľz;2nT [bQLjl^(%l߾E?,Exw<mO D >y8Hihٶ ,f ,[cܳSlA_P&녚"41ފ\kбm{0sL`i~jRvkO AFh`66nq`݉#l XpPJUR / Is8W[R0<|3fX݂/ϛ{v'af:dRZge/ąMXvr1fXb9UF8˲RZrx_/뮙-d\.(Oo|m"޺McEӧ#8QS%3p縲!kz>WX|`YRE& >}V" ڵgϚ8U.TD깭iqg3"Ao W_}Uj94t w}kO,zjկ<ѣxd~ C]A l%GQ6ņ.! "x˖h(J=aR Bj݋0,5I׍3òl Ao4@_sc Rq r~>? UjQ9 (EU7ioC͔Q/H5KI>3"=o"BD*/Fq,:ֻL>mTplTZ[`ޕp=Җe |YgQWgLy-z?w;NJPY5D9gqC܄)KKٳOcW>pfgʫ#G3܅_sWϛܓN: mٶsJSSTXB[^) iգ#m,oϞr|jzG3ϝ>seM仵-.D[wԀTj ð4xtGw ?9sqXuiSa,o3ew= GFpm7]:YtF,XKX4  4ZJ bR` H"BRd(PTtt`{Ӛ约cYgб1)yٶ [om;g}T[q=L98 ǥLɸmk[kQJ9Z+[DdAHvrU-m1"H` A`bTbK `׻u? ϝm5]~FGз7\yMۧ:zU_A23+ìٰ!$,"T"VHXiZ)b۶f<=r<SNgo?":?RD@IENDB`Ext/Images_App_HighRes/Images/B48x48_LockWorkspace.png0000664000000000000000000000411612666315034021407 0ustar rootrootPNG  IHDR00WIDAThݚ{p?Ar*!7L"6PU Vl;ap:3:Q&tC-)J E$5<_ݛ{wnb8ݿqo?;s*$JUUս~   *"o(e@LƋkN4yPeMMMMSR֬YS)"c4JFeC'Į$,vnq?3n8ˁN‘hb#}TUUݢ[@^_4dIyh "`8Dc:mDckDQ= uG/h66ڱc9֭[`0XLПΝ]bxTeXAU5F`~ڂ=tLP)++Y2oN=x^0<(m hnjĘʥ1lm8 3~ /0[x<꧂ohzDQTϊe ]^4*T#y(ѳ)C@=;3!vRQWÒ6QKx|b.{^U/ P5lGࡣ#I<;E3jr}4/ 2h䨺ܜAß;_O o3d<>?{L^n+x$7` ?| hdA.+0Ȕm.\g㴶w 4<o}'׹1mKuGMJ'<) &_V)7;:rIS3{G| ?mbi/ N["/7+^?㙿vg ?[o65{岯P-5ͿKglo8Ǘw!G17'W׳܃/;3n3C Eq!1STGx z{æWÑF8A?E" ^ZnZ0rJ~|#cq84b۹z٩P͎ "G G1PQ HэEhB,<'S*&yAzc^D>,nL88;92$F!]|-ʹ BLMG:'Yjc% ޴s`@0(3)^d{YG<1kD=uB:JHFҞ #z8N)MĈG*V|Cyzrۨ[6qDbE}BNH>A@(M&*D"BTe? tD P* D,] *Ajx dbsq?YdBMǝjt4@]'.w>ݟW/E\k<1ZB+s"8BA{ 2~5 p"8ɺıW.<"*AiV_\SƐj%Y} xz {'?t<GSST٘lTD8k0qb}ޔbWIvI*M~4z"Fq7ËT~cC@Dq*O_{d܂g'&5ߺlx6]ȵ=ФFz\=3onu,9wSvnJ6M3337r镗GB>O_v69K?bG̏Mܝg4M.doޫBtw LIENDB`Ext/Images_App_HighRes/Nuvola_Assembled/B48x48_Folder_Outbox.png0000664000000000000000000000216212505231516023422 0ustar rootrootPNG  IHDR00WbKGD'IDAThKlE3޵c&mRJ%< C Q5QZ.@*;6R$$TB &*TVHp@84$ ]Nivfov2(3D1:K DQXdWaGg%ZeJGvUMU!npdAɨkg:5N?Bg6Fe16H)H6ŨKHyS![ބgA[D$nvp\'oKiҰ#A*kOtW0^>X9 0k6Mq M7n^r`XWlO6 P\]3B$yh`rsʀg;bLMpK^8<4TP,m@T" i>+5c^`/a {7#;Î, ִg G<N8%4&"j+$Ó8]lgW7ׂہx̄˼6i U_J 6f_6L8`||+Z:NA[>/[ZGJ06'xL]@=`_*Dm:DKM#U8Qjٞ[$"9p3 EuUwnATomnthD[#އ9F(bøAY/DYd) ƍCMҍ>%Wځc╂a*/@ϮuiXAE kzN`~xgk=1E?㒺tSN8 O%]aXS`[tL.YiPFl,3߉b:}yRy'l5^:6{ymf =ZeŅX6f6 sLSMOb )ʟ8jظ*\yBW¸l2ؠNGIENDB`Ext/Images_Client_HighRes/0000775000000000000000000000000012666316750014446 5ustar rootrootExt/Images_Client_HighRes/C00_Password.png0000664000000000000000000000644510132777110017354 0ustar rootrootPNG  IHDR00WgAMA7tEXtSoftwareAdobe ImageReadyqe< IDATxb?P0@ yА@ sfB%A1 Y(:(\8g<; j_KIfv}m1 )8zN3@D@&GAH:٠bcx[aͳ{?~RKKW^f;U}o\6)LJ'MeE$}d`f{XH9Fߙ?w}7@gq_^) . 4KX13Br <<0Jqc;QA -x c'WyWL̆@@: >: C &Wow;=DB"@p`5#d u0倥! t<3LlW/!No1|E/mdլO?N!J:Ϡ-+=2")\-uaoM?B{Pmt`!t)QА LGIWtwogaA  G.[+|?? ߆&?@D{CE/ o L\i*`yF$*I緁f~ngc8׷o ?1 ^p/Pr9u 8P7Ic<@X3q3  tg`cV X*2k}g`=t@K.w?W} ~PL5@,X 03@,zx`[I xa`.L/2|p×5hzu:@;Tu42 231l{s< ؉~ xF^` ,_Koik7_'86 hEj&~ftRlf a̓@Jб~>#ûW o_1<~/P b@B?002AzunB*r9ee _02lZ(p)}yχ{?=hq&`)~̬BV(Yn_aX{Ѧ[ώ1y =o:`% +` |RU5 `rZ/P==@(`//^nyhU n<&6@2\@(E9f ӷa_H >5=h;Bn]+_r>t^}:(^Ӻ$zSbmh6R/@:vBRR^=@C} @ JXIENDB`Ext/Images_Client_HighRes/C36_Ark.png0000664000000000000000000000761310131164346016276 0ustar rootrootPNG  IHDR00WgAMA7tEXtSoftwareAdobe ImageReadyqe<IDATxb?P8=@CD9]Çlٲ(  6L IOOrO<ں (%,2 &J O#b-PNBDIGA\\/^0zׯ_ bbb@%@Fk Q.//_̍7~ %%e z?|T cGXXÇ ޽c|2ݻw>'''JFb@Lya&;"Ucx58&Ǐ>|  a #oI&Fi)VV&%V6E,߿} +,K 3߿ f33331'yy%rp )"%$"* ,| @}ܑ} /}̾o_Z<%((N.߾}c(Y1cADDϸC]tt89'3+P=# @O>30|gSAEF巜+Ӛӧx< ; 0YeeeçOc ̼@ g1dSgx3j{/÷~| LjcR 002aq{߿߿]z٥˗/*} f `)p!;Ý{Xcc .n&^~V~ceo~G~AIAU` 1fc4…@kD@Ip`q g6>EM~B_ (d>1|﷯|o "{i "|hF ~@dy= PO `S׮2ܾ뗟|_ǯ|O|`ϖ>lݸ "f˧%* Vy=@dyh#+'#X,I?>pAW~}yɉ_.?|?ThZeb?,##??X"@[hl`g`\ו'=~ ~f$bpxC% /~ v`<{POߠR#.ψ\JVl/@4F lX9=%uDD5e^{p]~1ALZARAI^ῄ ;}1G^+k:8e’?Q!@L!YR*zB \| b/rӫ o\aeQb`,e330K.V~^ 2 BL :>ɣ4w:=h3PVT~@_Ռ̄L\kY`o`0&^q`o``vU ?KyV bB,g̮:+ß7>`Z'Ĝߞ 󗉅 6`_N#g6%l@O| )H8iCL@9%%МO ). 7? }bc db+Y1GL@?A!߀m7ᔂ+P `[`cC') OKB&%;߁ys@023kU5J1A<"P XD /! e( fegl.c Om UVXB bD-lfHpP&;f6{?`R;?r 6N#;0b_AlI2pBĀ55;f818#7 >/,@OФca3 fbq A#8@MLL‡,`JGN.063 ϱq10Eaf_)Nnj<$m0bIF` ?;ebL6Ha6,y(  JJ(1*Y X 3PpcG  |##`(z~У\r[Z` dbv6n^POp#%#F$6H2bĞl16  {.' m_<8{AؖK@җ`z %&X  w`!2ssS50faas?@O6K :i[0p @:Z@c|=ypU33bR`Ƞ0'] ?n`Za1!UMQ/^pܴ W!;ňBq?$ȣcklj:eAS凿 ! ,* Lrl!, hcBG`2}eeg;ߟȑ[~}NԴj~żY߿x$%eM޻vf2J3h5?И)u6)???0rǻ_=s_Nf* %%y/2ܽ //'7/;@GrC02xϭۿ12qa8ZBi3zBi`,|/J\S@| @x_:A** }d+lff`s>~@}̗/_nߺ魠к "gt`$M!@:Tfg`x5Ǐ_!?uݻdaaidd(7PȀc  tt:}/;hz4/!ydf^=@<"ء51C3?z@w/@ t: IENDB`Ext/Images_Client_HighRes/C26_FileSave.png0000664000000000000000000000510310133443102017236 0ustar rootrootPNG  IHDR00WgAMA7tEXtSoftwareAdobe ImageReadyqe< IDATxb?P8=@C4=@X=$i00-d``01|ʈOR?π {/ª Xt< 'si)]"o@A2??,h@G0h4W;W1(Kjݬkĸ>%yAR\_GyfCu0##,V` Ԃ? /\dV +?_F)",wg&+uUIN?jvv!!r@abFF.Th0 NJCᾐt@=? ?cCRb P !403 :ߏ lʄ# 1g Q !? u ̈́OA= >#81BdW&^?̿A2.* e$ p(13c$('1? oT4!#\+ \8Jit`eDIP&pXbA8 Hlcz Q`; $ 1Cc?4ȁhfhMB  Fx O>L@A.1Ą3` v#`XZabg"'#ʂ' P8##R' PRHQψ(p@DfDx#$ (FF؇&Q\ pzryPLy?#f@DF9hx"D{5R T e2;<ŗ"{aH$QOĂ E̐Yf$ G'!yAX m&F9F< p'!<E1(/#"X# ˆ@!P̌'oCC5ТggoMdd(&F N8?HU2$ @x?x 0kDFCP,JV mÊL=THR X$"c~@;Ab`CDL-LL&,1+ x pBham>DTGI  8XSQt_Lf9b 7?^}cx,/Ǒ3?,l^/4y%& IԔeQP5l, ?#R?jŗgbֆ0J}1G6Jd#l#AXA@oٰf>(j]#Ci#?%0CǏ 90 #bj/& =2V:y~cw?Q^eϟ3gadjRRYKi7P7TF*XC/ 3A'~ .Nz231/ o$+@C[6,<п_, ?R9߿2=tQ XRBkc"X' 1{b/ßx_` Bz’L @x{drȰ.:?'@qb<? , }P,|c$X/R=DCi 90 cDa >(d pZV ȣdѡ d@AH6r F@Բ'099 ?>RED ^4%@yHhTX*1QI!1\ 1 QX&&I G/ 㗿~̟ '(@t J2` p@R逸?"Ăo.^ G@?FH~ZZrv2y} A%#ߨ= @,E*$D|ȠH7b q '0sK2oX/<4 z_^{%ë 4tIIAFpC^[7 ,  ÷_N}fe`lj0c`B|L?N٧E <| dU#?_WMdb N,L\|ͳe:/$Ӭ4=@C4=@C4=`KU8IENDB`Ext/Images_Client_HighRes/C15_Scanner.png0000664000000000000000000001013110127240336017133 0ustar rootrootPNG  IHDR00WgAMA7tEXtSoftwareAdobe ImageReadyqe<IDATxb?P8=@,p02!/UǏo}ϟ/??맽{jY( gj?1|' _}_|奲S߿_^ߗyuџz H/ݿǏxdeEJ?L~f(=GG?=o ?䟟? ˗O]T<+ŵ96֛ + Ib# DǏ ߾o f8xWfox XȈ۶-ĢÕ p"l ?7o}Xvj@X9;4)ʊۛ0Dc= ##`jOwR b@Iϳ'w oTRf7)o@G]]ѣg^ޅ_~~J& bnhh3I߼ggz?W99)6NN_?p A@ǯ|LL84#x#vv?vʲLq@\\ ,,R0?}(C&Y XP|ڷoLA]!!P++#P"-7kw߿ĻwvD 3kyxxyy54?8%~+0?3[ׯm YwZ7 (MB@o߾^``p(A988XA##+'d:e\I p+ݻo fPʤ.`j5ݻw1I|;uj11<<ܹffb/3{n;WB3tDNS`%yijcV;(Sx ϟr2Z  МzӦr\:Dr PAA9PKX\vL3@L4j7.]p=0)p_05 ť-^ fuuL`)g4"f&Ϟ=|#l] 1BZPfUTS;O\lI1a4@0$% o_|?jݨ#7,H/R.\8 ziE&fHKfZg'N%EY=YV A/ fr+/ y`[X1BK%&p{:Ç<{Romfg o: 3w02{'ÿ?}/_I^81H cT``&??y0Ŀ3|@!`epM']ٳgC: D$Z’ogeikAa!&ݷY~cR.0 ̆~3 ނ<СEA ]$991=ٙ *? =hjMME_WgCaQ=V_`#O A 13, `2zÏϿӿ Ux8}kW  =" LŶ6:ڊ w2,p7"3ÁFPef`A"3@3o|ңxy9I'_ #aF'ĠlPf32| l03\ PH r8ix]eXp^xIh9 ď' X{,,69 ր`siXGh0[T2GF_}ae,fa8cÐlAY/ aݷ8+>=ԫWNCCaeM` BHJK+˫jꪱJ0 C2<> A(hT7cR y{ÂkYիA hf%zb =DTIJ(kh뫳*5QQg@$`O0b؀p BP+7O_{Wn޼xdNC?Ii`zb~hA }mm3;iiye-a`̰bFH\nCF§ tpF灎A rIYqhy̠ @_ A9Ɍ 6i@'bIENDB`Ext/Images_Client_HighRes/C37_KPercentage.png0000664000000000000000000001431010125245344017743 0ustar rootrootPNG  IHDR00WgAMA7tEXtSoftwareAdobe ImageReadyqe<ZIDATxb?P0@ y `ddL10RA~?C/~߿~= 2200?g05d`3:n 1U9 " l, G ,!o,P ڟ 29\޿{;O0(|a3Ë{oC  ؀!h7X ,dkoY}*-1+ûL 1?:P 4*(gf6h `+7 7b`_;EB$&&aV6`\C,eY맿ooR0B<  4EHAIYX-8TA[a>3|76YVjY fðz `;= ̸L?`8F#SjR7Ճ:PL2 b Ÿ+"Hpzpm`\2ZT * zu ?>~fa?"c 6ԌU l` ,M>~c`W`xlA< 6 EǏO@sEXQ= ``0lC h jB t; #,X9~2`RfcA3?@ ?~32(*(2hg3  /‰ ne+0ð/fdafp6p&{aVwq5!C`MX:] ) /?~ah^c lN? O?z*\| XCx* t7`ʇoXH!{*pG_>1Hq rrqc߿sY^(2rg`O['s jV`"B+[u.{CArOek֔B~fi6=^)I|гE[\:V?90}Ȉ376X1O.VF^[iaZ@#!aOM"%5&*S h)tﯟ?|c`Xr32(Y931f& ?kXeb&9iM>d95?3IHi˘ S^}ccsOa?)-n7oz $OXjL~qH:|UR~Óǯ8^ ' ןz 12}Š.Xodg}0Zc>}6~ ! JTA d+_ɾwg&0y3@c `֏n3{{&NHjukۏ3Hqb0# PS/420҉vZ1 ?:/aP}2|d QBLLs~x e r(31/`724$YeAecĄgw wefw^C\-fzR l u[~3;,/0@3m7dR/F`#WAybW~f``AHT(r6@{='3sӧ7o,YVbx/C580I #nɇp;5;Uf>@ǿŰ6/A`cF07(0g # 3hex7/}ɟ ׇmF< -dc왙>q8GS- `faeVDh c`b`p~!PeD!.Y>Vmɿ v}>6#ϸ.>p `/Pa/*w`,|b<(D~3H3;D @%''=Ƅ7~]P~wz`3B?[PJF29RDg65?+XK /@!p-d ,vkAPKbY?;U@|p`T@,l1Od@!2Ϸ ;!R}u&wM`KF6w"2 , VJzgdfGv^ lKC @V1 A_ ִfd@_b`:а3#O0<0<| q$NAZgXu?ûϿ>lg01@"2^((& X+f1| \/ҿ CHTOܼfb t,#N`^2/d > XɁ$Wl͚5 @0Q &P $6b`030K3X(13c8=ã {ҟ^3_N.`i؏V` 333L !6v`!.f`Adfai &Xq' K ZY?@y$!a1y>p0{X򼜌0Oo^s߿ހzi3}| rL , B | 2>~;/~0|ـiM(ġܠ. + P/?9X*31e-8t@/#% }`#×/~>WA?oFn^npR'@?:11x1+)0 2d8|/@Ϭ >X\}p$@#ſ. T=dҿE#??C530(Cn~2yk϶Qo?a7?8$Dy>y珟2tIL tQ^+P\x؁4@`|h)Ê3H?-)i``$WL pSWcxaߍ /5گE\߾}5b}WXמggȷ%(6'>}fTm@cSA6l@n =z$MN q*MIP 3RJIIX6}}]ݦk~opz j\ f GN(bRB P)m 3`f Peg{ӧ'IH@ͬ< Ü,>dPab0V!+,X0~߽b{G73sWy^ 6lch bpqay)óEoh4$ ,w20 o1}X%Y@,o߾|< 4\@4ׯ>32,?Ƞ,. k`Zq?Ç|xM]҆HF8sjnC.#U;u, ?&._>a`|E~[?{ *FO<CZ?($c t֝߿>}-,?y |1?ዧ ߎoʓ l|B4VyubzAIAFVa'Sw nO/3}~%ΗOh^{Ȁ)`WO8e|gVdbbfDd`f;={?lZ}n`1k`4˵Oyż2e~Vb ~cw ^\r&oG6(`7A6׮]c;)_bޒCF;b(?w~>;3s..7V<߯]` +/ƿO_q3SA#<bL,l_X]:Io>eX` q/!V  t|:IENDB`Ext/Images_Client_HighRes/C29_KGPG_Term.png0000664000000000000000000000756310125245344017307 0ustar rootrootPNG  IHDR00WgAMA7tEXtSoftwareAdobe ImageReadyqe<IDATxb?P8=@p$22Ī~20d@w g?3+C5P7S@ P<dw~A4P# 7 FO!/P+'а@Ă, i=a~>7g{e @.  @161@|@2q0<p??Ԁ q z P<Lf2@ǃ F'adf'3g  Ë bTݸn ~5+0fF0,"d c\Y `bP,, W}(bBy/,jUd`AB@-sprS#s1r&0>86uld@<^ot5Ppo-kqe~{0ھC|L,2Z `b.&4 per0 |;dAI&8fVC'/X~f`X$##%e TL(L Z\ ܂2@tQ R``2B+H7?0= K>_=FA@T!P 7=MǏC &?0)=xbAEyP3@z@pE,0Gz4 5 | 0Y0<~߿93:8 ?hzFA߿P10u68?+ 1 ܩ3&Ñ=! *Yi `9j2h0Hq3͟+(%'~#Ājd[ [ =ab|e$߁@e!#4Ko@qV!%e6v9~c{H\΀Cΐ!jAh;;F)@,Haq+pUnfB'a, 1 ReC) 0%@L ?'3 ꛷ n_4nJ/  2|uh9M >R] e0Sbp0D@pSw0p?ywodTca JXZ0˛V>iR r ϧ ,"6È& \{W33ӟXB.N0|vR | "дv,#r lcX1ó;O|7r\ͬ60ZR 9} l=xؤ6ެD0H2|gx Ez'9;70Д{38T{3|{a_Fb,;7%!bRC'ٺ] ʬ ȃL`az򠐁v$@L=|FTOo$XEƽx=ưz /apMl'^0ǣ8LP1E0aĪyC^J# X 0ة[0켴ANR ?dSa1d0a ?řX#q!F Pb#e۶_LAs̠?j\=İp) Q L\ b\Y̰QN]QAa`33p'X՚ο Pb4p" 6\x8bSnJ@њ7 KϬc8~Ö 3nHag@nYAhEDT !]@Pb@V jX_M`P0Vby#@~33X+_ omp2"#7WZ`# %)Pjt}VH1@,]F@Կ!0Lw17RK@:hɋV1"`9FF4rj\ӐoH(" PAs]]@{X00i@~gCeBd?%͋~f \>h$1P >(RP_1S;y)6Eh|i`9g3lEI`C8P`CHrX`3633-{Њ/j?3ƍMڵ2S-ՂeLx?auL4<  P< aryQ&pX#33Afh%C}`Nl@J 00 ! Zt?{sYGfD^~$E䟏V K0Zsg_h㋙l>a ㍌LC5tl 0e!V ^^TRPԷF;.>.:x 0@0tǼdsv`胪_4Jnb?PhġEG 0e  pzܠI ̲*?/5n=h{ BvIENDB`Ext/Images_Client_HighRes/C33_Run.png0000664000000000000000000000614310133442664016323 0ustar rootrootPNG  IHDR00WgAMA7tEXtSoftwareAdobe ImageReadyqe< IDATxb?P8=@C4=@Ci?(N_s mʳ20rd,n zz~õ d{13[ s˫1zݻǙZI0 Xh`V`f`6bVeVRb`a8cÝwz:Zk@P& ́i' %. t4ϟ =cu"{ -T1pX;<  .C``b`ccgfTUePgPbNNNf`ϧO9?2 |@yNN_1@@ᗱ TZ:jt`sM͟<#xd5E_tӌ,PY wzp4F(+TD 8}<20j0RTT31e31f47ge{6U ^f ÿOq߿`P=gb9..ޙŘA@<*-h?;;0d?01ad)Fk& Paff 2˱2|K )(D)3[Z23pIH200CB_20 "@3\@Z_@z@a00J:80Xvt <tohXE8h00?I*6 ,rb&WN1$mHOb:/ _00_# (`1vۿ3$#4C݇f'#fy KJX g8@&@_ujy|PcJ/_YY`q @1r~ fee@1(:'3;=-}1)YԠnh('. ;ܟ/_Dyh,$@8=_y}#Jh#B96Ԁ*)9`>d1PM000w`.`SB1@,8ËϜqV'e?`3 z ܌Lj J L ̦$on(" që[̀q_SX2{}3eըP1kjf0Y@1Q1F/_&}C5$sD̐~f61g ? 0}my{\WXxāI/J|j:'36p%c៌,3 @1(C܈RAEA@woo_xB kEe&81v43,=޼v 00^6%Nd` L ρAy  *M~)Y5 z=0Pk70 >۷OS-,ڗ =VPۂ7F`Sһxs 3_-n0 !R&Un.q`+ޅ,x<@x4N+?m|.`;K]:`lePX^A `PcGa0 AqPq?KUx"/om+?`~&P8F5p c-` //" 8"O!Ʀ/e;cs@᪉ϯ_4u&P~v?6vvlL^*JZ=aVS! O hn|:p/ t%x#  @TqP*?!P?>PssU1#O=cJ 9EW0\̢VI XJ222 &!h2:˗߽vCn!(?d 0ٱ`a4!AQ`-%($gCln bK`fdwMb 6!˗ ZAoՂ &`BBFNn5P>30"*@y y-oPEDA OъLpIu4>߿gx9G{ V"z\|}7ld#2fd`~ 8߀F?O`&wn#1l =_}{[Y%!!ԌB_e`wb'` ,.{q}e3ÇW]:XA~yo&FR"X#/?+Y̒ #Cc; ,~cᏲ*O` ɟo0|wбfto6΀,!k HZ5+^BA|&P_@ @0A)z _od'pǻ/;4I6{訟 @ъ4ـc ߡ:3 ?.3@Gyh`zˈ4A  Rc0=$ `29(AҠe@6H_~`N@-H@@::h;'}m JR?c_~/$I:#d FDR?&BԴ t80v2L_,HDqˏL@bYǞ 4+@ yА@ yА@s$)IENDB`Ext/Images_Client_HighRes/C45_Cancel.png0000664000000000000000000000707010133443250016737 0ustar rootrootPNG  IHDR00WgAMA7tEXtSoftwareAdobe ImageReadyqe< IDATxb?P8=@C4=@hRP߿ad`4q!P/#3`#3; d03V9LE@c?yyx L@n~]Vj"0p曘0p 2ܸrӧ:ll@-utdp|?6V֖?USLSl |BC1~b"xv.pC2|bPt! f斿x-72R'O`z+2AHJ*' v|7޽ ?!ý~=M DE䁞&)6<`z_l˩_*w#9AHV6 l`:[@%:*AA_ k0030-[᫴4ŋ hz}$8>!iiqj233|`onf`a`3-ῑ02}5PYĄ%ZSx Wع7`6 x>|```3Ồ(9=D y`4UYMꟀ+.f`* _20|WVmQuu￿~a@W E… 6F;&^^2]$",Z20Tq|00,tfQ=06XA! PO1`&'x&t3 K ~300{AdD@Oܼ'@섅d&JV`( nK @pKW1" dfnў40qC<#I+h"g^^.Ubb b (6Q h߾1^ l՟;? @5q_`  jnF!!eh\T}*7`rLt+`-ZL.2@bnj8X"?og`v3|zh Gjҷo?V ̠gwmm ' ,AA+W~fc~wJK:Z@GC k OO,aagOP@O0=  Rpx0AUz?iWط@s** vb`yᇦ&ٳ>"9 &faai5kS`\WKH[:>kk3p-&W |]4ٲ\[vK?"; 1kQ0扟 XwXcg{ ţri)QX 9e>ׯ͞VVDJ6j_8{3y2?`H338J @*z%*@Ta1%֞ݻ>}@axXC0-c=׶-d:%@@aPLռ:X@N``AA 0P'0*AI" NLP&3= ~ӼXD3f{0i}oe`x?_LﷰUJDI( .%/ӫ@ږ ذpO`C^c`J_&@| LPH F L6>,#lMM%`y ſ DzX2+:pL=Ma@ǂL`(' ,u+'O[=+܁gA{!h =21-rR:0/ P6t瘁VJ 였4{ `ϯ_5,@Ov A ͽDR)r?P7KPCA1r,8ԡ>\Xnk߿I R-,8ݩSz4ƊD{ 3m3>(x<VA^@=Xc9& DC ?*1Ñ<=0H po ԹzBa8xy A.,g`?Å`ʨP|Xb? 'Nexre`RlBW@Jnc[nZ᭷7ftuvK7>,$CGE@OԀ:2JАg&1G&Ndxr`A7 p߁Hk2|`&X/؉4|ϥK ?}Z%cD߿k;7CLfdxq`I  |5O`*ӧ wnX2q= &w>GI{y WVf`y`=r%k@!r \fF`z[X662b`VJgΞex5Q}XX K>+'W.gu7C 9y" Z`3`x*4$x0Â̿nhOtА@ yА@Jsք6u5IENDB`Ext/Images_Client_HighRes/C22_ASCII.png0000664000000000000000000000300010130001222016344 0ustar rootrootPNG  IHDR00WgAMA7tEXtSoftwareAdobe ImageReadyqe<IDATxb?P8=@`dddptttP222}ˇ޾}{7o^ @,,6p)((0$  >)U@G OJG' @F;R# 1TW})".f^[. sNclwZZ+V)eSUϸ󙎷#0b]ȞCYt\uj`l666pba`1= ++T H=@ax a4({ ` 1 2HIIŐxA 1i%Wh.]c  f@!K ɓ$ad \bB@2j8 `][@d-BFK$py{` Hr<,۷ "~d@J!1@dl>(Г3$@,;%ɁT31112+@VVV`H |:.P3ͣ''PhbP nѠ@7[ jdXr<p8#*1Pe*N@1h汉?{͛ ϟ?'X @$BH$nz>PCTSbD<@ISRm!bFA4k'`s@pYJ4_*BA"D5da2Bn |I<@~;`L[ &bBʉT} GbH0 zdԤaσ3 &z gv%ElիWaj Pڠ%!P0j1@qz*(F"{T߽{ O B,`4"'&&İ_ z x&DXX 6b!@dn&(A&5Q(-!#0 3,"\za޽`}L[ &bQZ%bƟI XaqkJ*0Pe՘DD(:٠ºQb5*A 3|@##s$ FA511=2ۘ@/6 ǂ< ЃOrki/TUU r[@$r0?@axׯk-[HGD6jձPPPAS oc@NZZ:حmӧO>y(o@w?60)I 6b- V*j7(Y t7 =I {l-h 7IENDB`Ext/Images_Client_HighRes/C42_KCMMemory.png0000664000000000000000000001013110131465524017350 0ustar rootrootPNG  IHDR00WgAMA7tEXtSoftwareAdobe ImageReadyqe<IDATxb?P8=@  'C3xy"@JvX 3 |(#?LVF% FӀh ߵN, J li l@Yq f&xý 13Ɂ3O<322L|7(9pr|b`xh/?I Ͼ#? p{P 8bkȻKͯ*1ƌ \ +8f2 ?q3Q c3 藄\YFޖ/L ģ& *v ܆Q VIW@񀋌;e2VC-#C] o2$aehMc LL XƖbyI.<&7!A2;Åds1gf8'ε \ ;2( ~dy)Ï01,{#o" ߱1H3fr('Nl l_3_gPt  ?bQ$Ɇ #9b^1E)2|| ,y X *Q xfxA 123fsÏs3T:m<`,m#;`Ȑ= y~og Gt~0bY9丟0<Dž%gD$dL6?狛1, Cv$0å G10 4n a L@`_aPe 1 u=`t,1ߜ?0|PdϠ-pA L@ǃB2=bprd8+pUÁ5~cpa5U w |a`x h"*2+p&oEL~~|/3 C]*/4~3_ LL`3111|< ?cx ~fX}AM O?ftCSBkD&E~(#;C]: 'Ù4ـe=3(ˢ&ѝ(â:?+ 1byN(Ј@ ( M`>Kǧ ?!pU79~_X? \B<}`h!0ԁ? 0b8!";3h1 >'@QZL|Q.~N^F`q}?Oo;|fX{ Q~ {3L00|a!sANî, g8>}P9d.@3X `e#)0xyDX 8/n[  3Lؔ&&`Q&q`(O,U;LǃB~'O%~1802+ߞ1 `lL>gׯ?n3D2ְ=1T6h/oXŽq2|:t)DzEf,mt?~+ CA07]-~G_1,p ` LV_e_33x0`e_XAm$!!b?7Ç?-a HKB:BjfJ-f,?Ơ ??8t5/(ma-/ 0̻d3p0J1,4ɠasf\@C71`c!/%}dH agbu &$_ ` 70Bl11hsgj{AV'Ñ ޛ>=2,6@ŀ;#j9~cl,dy];Π!XT6bƀ/N.&6Ug`cbeAL T *?A;9Ox ™R+bNͷ?_3}Pp`2 ,EX~ 0}s2}{a~K).o,z^20Ɛi ?&2,6@f ׏Jg!#AG 2< 7'-+e0û_C7B' >f+[` xP3. &q$dt2NdbДP`س{#(̠~b4e; G2̻ ]'Z[ 9>206/.^㏒x IV=bV7_>gb(dbXz>4+7о FnU~ʰ7Â뫁 j : \ O0h`8!'34>h9Hq<TezB/`'<} j0fVFhabbm 3gEb`a :فi!Ë ~904ZjWvgQKE`YG`{_ ּ X%hÌ!Clp þ GBfG  }eb8 s@!RϵR8?h3p|`fR'>kx胒 C=o&Pۆ N[ ~gb> uTq< o<a~ .&?pc@O$ ?@Ɇ>CLXñ sNVT : nb, ˌ2ğ8/00><$Px ~^𑏁A o d0<􄁋 X00 /AW 1 g?I3Lػ#b" ъ /2h(d8!/sLJ 0@y@A_A1Fߌ,,Txx8J#cDDj@lVfgMMgGo_>1|bXtA^ö'L >]VRg?P5a = SHe`cbTgcbbXALAIZ Po y;\  ?>dbH:y' ?*Ct<zM *V%4XzYCY \\ |a`x-5o y_ 32gr1{6x 41LMO BL؀=Z>` ?a&o WŰt!v@j fF$DڙTEg,+0{1r~c0ư<0\ebH,*3>f  3r@ḵR[TG ,/iQ@i6\a&de`9q/yJ@а=a(Xˤ?S `;Aac=q`<#C&`is l> @:47ø81peeǰ #CV^`Ql> @v)!TI_4$H 㯽 d|16[ADʨ$92j2$c {p3Z"uXRY5122 <,mѺ h|^_AZ @Ѐb4>x0 IENDB`Ext/Images_Client_HighRes/C66_Money.png0000664000000000000000000000237712505027176016663 0ustar rootrootPNG  IHDR00WbKGDIDAThI\UNg08GT8@Eq䕈F pnG^\ЍDQPq"nHƘN b][;]UI0~ug>Le\ `!G!u|(:2UeE9pnE2\D\+q.ƕ؍>VT$5[}j*Ns-؀p~ mBe[UPYMnf~H[kS$Z|z4 ȼ>JZŃxF0xd6iNRa)vų] JJ*krNXa#M7]3q>2л(TgmUm(SwԏrK檽,Qy W;}g07d[z¢x^<}hߡ% *5$kk17k(ȼeT!NcRTwz g(E?Qr'H}sH:C#Vwߴ% ,yl& ј>kO]#1{2kybn, #\΍r v~ 5*nSSs:ObLڎa^=QM6_W12 .A eexl_Mިi}[Š[ɩp`ʴ;S'j-/XSI"bR{ʬUj40 0,d3GC};sB)S\XE2j+NƖ(j spZd/vT/8Ό 48Oбۭp}KfnҺnvPUl(PsgJ hӴcq\4'ҦsS0{;r#sR[ v*Z Y3; x0~RwM5OCp7_VcXm"OFSIENDB`Ext/Images_Client_HighRes/C40_Mail_Find.png0000664000000000000000000001065610133443542017377 0ustar rootrootPNG  IHDR00WgAMA7tEXtSoftwareAdobe ImageReadyqe<@IDATxb?P0@ yА@ sBC3Ŀ`3Br Hrh b6V_?pH1I` XZ`/Ǐ?Y""\zJ nfhs8  yXک/߿R Yj wop1ppf#C7o!\b~S%9l4,޾pGH?̚ ϟU~pa?k>@Y37FQQ\A[GAX `'pӋ^^LMDmp_sYXYe,4$X6JK10\ 6> d8t^>){?&B߿ϣa"Ϡ+Ϡ&u8++?0#ǰu{%-.f߿~2õK:6Xxs1vo, /$ϣ`b #e؀fgc``ztm?&#hezښ @Ͽ~SͿ~}JDo`$"*Ȭ`l " v,s=Lll3C=S'?3X3p1c^zEY W/-رc;I3 8*3ء sC/0=|xݻ ?|XXcbfPUa F84T >Ixj~."@'66vMUuE}U%eQ~`de2//@=|K b"`o1x 18:1 0Aå VN޻Dx})> ZS1I%CV[WA@A^^Lx~%2HC fxo77y>19arwh+pl50TX ~ &*p-pq  Zѽ]S/^:v%^bpT2&38ef`|qPoJ/¿!_C Š8nPH  R6Aނ* P,0(j9  pČwLܱj8dՔ0OKf`SeKP)aM3PrdU ^`#(׀WE etÏ_>KgS K_~\p3Q)`b9} +٘3pjc6H,AcZ?R@ 1d26AE9Nb`ظ)^^6˗( <9Ƈ,,Ws=Z  ~@7P 9\HI?VAdzA4?hOo߿1 ťϞm\ @,);߼}kcY bu ,E=01 r<4O1x1'_1pϟ{߼9 @,,:|AAD$+Ϟ>bUdxA:lw7QL)P{`z ̾sօwMLL? -23LcG l0\z+6`J2lR ٘ >8?k>c!ÓgO~@Č>ee?; Ϟ;u/{[ׯ0z̎HGH u Nw/:|qI03 C 0[@xR^؝;&ư{w`t~Lf#4/0yU |=p|0 D&/ >ŷqDd+ߥǎ_kpse  /^]m-->vNwW`Wr_ 'O 4qPw *wYY>z^AS \,a K+0lٶAG)SV`%37l~bï/@n>~|\Ff&YU-Iuqc&^k+G7c!i.Hq!`Wy;ߓW״c l^+/o\'a%..asg`y`;/fmۛ,mJuy!緓4vA4YA#k1B?`s@QK$ZV' /?dxOL~_^?_E聟_~}۷+? (S:X,]9 )`A2[$t>'@]et#sXy 6Z}wǖ|yvݷooހ[@p`k(F=Lr,?CuϹꕚGe!gFfpTΧ,o2P[d`}˗1 #R ~?Ȧ,~rVx2 `c@@16lMl?CւH[@>W y][ T@|6Ão `9vZRe c7L@ iVf'|wm ``X?gPISf1 A/C]1pѴb48>ާG04(=[`)b?+@ж<#Î^6  { {]X}I*bUhȯ0M&[5IENDB`Ext/Images_Client_HighRes/C67_Certificate.png0000664000000000000000000000436312505027656020017 0ustar rootrootPNG  IHDR00WbKGDIDATh}uϽϳ,‚"bSEK`@bmu(&!uZּvH]TK#fEQDQe4D"+ >4?Efwν=s9s9QQgwVah\M(<,y0\2M2Iƙ xNEp8'xXh3I>7/% wN8#؇1Pp5%۱KE;*d૒X/%땜':_^rUܦ|^CЖܧ]YrWU Rx ]Jא͓kOj\j6FEw5.4i:[]HgF9>eP, Tb.5N1/GJBlM3~#VQ̵St zZkڱIv.Tz>M8MTQ-ک:ݎ Qqn m(4 W#uDeT0HP+YeM~Ъ5U' ѹ/to֣U!dcV*g:fI+Li*jٮNݮGz-z0cKj  #T<)&"xE$Tժ$kYg &.eIT5{HjM%[$$ {Ѭ=*N,SxKY{u;O҃- ;$M tq$HDhQt~A=H{R۱"3-a&p}~U냄LדD46s=6fo%y+L.|I<'~8ka+T2UlxðfE.r|{Ӽw,:pV6,C CQj$Q3ۛWo0Qk^AgKfhR4+qŠ,xй7tȺ_q&clB]&Gtv`*jrQmztx_f}SN0%Z,iuA#"Z,Y))\t e7Hn튈StTЃvqz(?B n|2RX"!9UEY,YÌs_IQw) 1_CʢiꬵPP 0`UiPӗsU_Kk=*I-uwT8_^6<;3iVfoP|:`T!ٲ`f]9_[o`aVZ<Ѹ%ҫW1 >Ј$(.J0'&~YUNNݩeI}?fsHJ]h܎ɝ"ǢoNn2[rg8>+}.Ky'䦲sz@?#_x/goykOq5JaUjPs͌;e5nր>(x# 扚qhVCܓ[6-֢`{6Wj5@\yw3MZ ֦ ic{`J4א'l͚t,%jT2Hpc({\R %K|Y-Um"dsѭwpk w 0P.`3]h$_*Ƈ5Ϧ_ LU5)H DSDUy"٢KEV4B4p]-<%%$L=&Hޕ11 _0Y+U%ph`d - %S}^0M0@a?88## ZIENDB`Ext/Images_Client_HighRes/C20_Misc.png0000664000000000000000000001173310125245344016444 0ustar rootrootPNG  IHDR00WgAMA7tEXtSoftwareAdobe ImageReadyqe<mIDATxb?P8=@`022UdnR @fff%}hI+@u?dr;@R^ t_t@0VV?~301ԧsssqrr1|Ǐ@?o}Tz&'0}… &  ~D%~jBh ^C @2@~dx?}l8 J 0I22lݺA]]A\\lڵ z pz!00QtX'<Ï?!` PL(]S`  #0P1<ر w*~ N23dfV0prraY8=@X=7G]߿@v82 ÷o?cfs^߿Ih(b@Nj`ab [UUm;\%ùsDZz 0<`iN Àr<>Ao0d(1(**& Ǡv44?2FC6_~bオ&L@KDD\(tI ;`rvCdVʰoV3g@(vZ L:_|_3ps3 ^FpA`f 7@/9@P?SDDL`L;¦#[@2vyY( -@IXQ d`aay7 y)Ae9(&@1}8VV& -IIa`yCΝ[I?VG|2`bQQ%Y0(t i 8,i cAcgy$ ̠2 RR"d!,~2ʁ=L>po>O$Pmܸ!..aٲ`V?z#0jW80z^|P&e<'@qAgJJ `gETht:|8@*V@L=z5ϟ__z N> BB|`π 0 ~}!@Ev<第A |13 p DGgK`Z:r۷t/4LX0C֨{×/?޿ #=\,rr3-7 0+|nPXK(`*!7ÇSQQ!V3.V={p'OB\,ԁe3`ǂ r(!PH܃π!O ,~98!40ܿXpHLRׯ?;ի'@ۻvmj(>X@t}`a`-K\`|,yb`;136+PGٷn߾>zjz:::)H @,v]>>~pUJRD(̓<+2AL~Íޜ9slÇwO MayC`,@YYC DVpL| ,ٸ0<*0@۷oh_UU `k .P1 ]X`yFxMK/ g_,7 l{v`9>,ޭׯt ++ 6@ֆQQ i``*,,z@-PkX/jr0_6)~>nnNp X *@?~gxP/߻poo5S@E+(&~Lm(bX ;6VV.߾}5@/J 4A%PuAI2T|oAA>x3&mɅ޽[ )@$ 2@O;>OAuɻwo~6߿?[͜D-׵@v.P@78V@sӬH/AUU aE)t ..5G={ S>QQ`O!268XY|/^PV/߁IxlMV;TT4B|>VF߿Z΍@1  emP~a.0@ H?<@=7HR6 o߾= $@,ܴp@0O0\tٳP O@}F) 5=d/Ϟ:4Ǐ_@|| '`J`Y'&&1!7 ')]]99)`9O>| e>QQQ`~QK@;iVӃؠP;!5=@f~ X*~@,8wv2DD$|*ǏRMMcF~~~'Ea(&@Q-( 5mmp)٘U03v_{f|X'\{]@=`dd0EBB|"@2xAFF\" 0O@"2t͔B6/kA?8}"27?ނ%cB PzT{T3{d._>ɓǻ@#\@F #qU}>$}vV>Á% hPO P 9&}HFn"J1'`C4<( tQ`=|_$}}I@E,wBy}j{ 'ZN:"!I/~sP  < XA1 J0?w*``6@_ '\zb0M֤޾}woCYiRǰ.\J@e ѧNǠo౥g^[>6bp`w //>nYYy`[ܟ$`"T<r,ZA%H7q߾ Nz$x+_bOa;;ak ++8{X_3@c{%/}TP~@3^pXBG!qH;N 7`} 4G<o~eM۷o.y͛Wnݺ>{#`I_>z{w@mq#/^|ہ@,ffwԁd|v;wF,ټ!bb& P03<L P+/~-0_]arB{<LnK^W\'`ӛ4Wzd %%@e>l,g)((/' tݽ{G/ DY>>>w݄6@ 3DADD4ÊK p`6I51!~E |-0Fx=@ ,y= JVhRU@SP>4W%)-rUIENDB`Ext/Images_Client_HighRes/C68_Smartphone.png0000664000000000000000000000322312505030470017674 0ustar rootrootPNG  IHDR00WbKGDHIDATh՚n#I?_Uwql("8e/Xހ o ͑Bif8U`;ig3iij].ۿo}=}J)UD=f~>99|ÿ93LrA˲9ibBht'3%,988{u_߿7xH)tU%Jjc\sUZWheY.;KR qpxSBXh`6,N eDe% Z/bQ8GZ -(?޼bnݨ@\d j&g_w(y7us 9r~z/wYSuXܷhO 1&:nh|; \^8/Ri |[Iua FٌIjl3Xݦ:`@֟l\Lk,>iyp)pUR d&W5ӈsAUk{\դlH_ uDlx+raMΆˈS2.o#YB.v>2a&r7a:md>BwЫ5XY,z /,rXko)R?bpwܠ5Gh3|-BL%T%R-uCjȀ:,>0xt\[Â53Bzs^`w)= 愲\7p {p[ Zȇ壭답u'YAN66 gT%hZ]f"U ^{fYe hF|>n%}(re^%ᇽ*c;;%XO,L/ ,Qئ-B7ov;k{3#[>hyx5Zwpph0|sޘLzF1R+MN0fwzyɄt6s^xAJ-R7v*"8< H_aA2n0V5x0۾LdzŁ a~21>`}&7#vbflq`TKJdߏ((i7 ΂K `X|[ ^'>̰/fht\[CX>hB$UN߁ €ja=^]JIg?],~e錍dAPS> a!4RG,o><"P] jс*G" EGkz s$0@<9]P,|i(6?0.LL7@M_d^M1A@Xw2<+}vt 2hHav$3/p  P PL1nzR@g`-LLrhr֦?ͅ@Z}W:_35!胵$Az5545hrbhva_H)a@s,(?BITK:3''{ Ҧ3õ7~@b00 #P)@Ġ1nhM@f(?ȃo>*MacL %@s&pt Y!h 6AC@ PnQ*()1xyy&4?(&OPGVr@qPǼ $.z<=f%U ̌J%mPAя@![24Ъ nC| HC>0(@O5`R|sB=]Sss?$ àFY ;vTv>Pg6fwc?0C#h MgIl7PS3PV@PT!7)H3SѶ>ԗ%`7%Andb SM>'@mxPP( A/eS2a$D@'i AC AC*(j TN2rj@vBJB`Xn ?; @1P7@1A"c]l>X%#@BAP"0$΃B"?ρ=0fD0O]~8t. &lB3"0ВAPq* NR@E^!0 [@C@I/ ,,!2SЈ`G4jz`7N73"yC\-R} l@fؿf/; hG0 Id Jza_OJԂFA@C؅TPСБdp sNX,%͋xP57P,% o@} zb@pQt<P@11*)@*'.>c01=*AV qШPh=`Gǂu>|h+Hvbx C?t l@ R* ` @11 S@Ot xiFڂF@icenv , pC)BB^E-n`e>0#Ȯ?JrH)( t+ qt¹@>(DIL'BTCV瀵0rI벪 |""pǃh!HڗEi9rOYyh1 #x@7F@hT&&` 4Hh~X `T_a0㝻uf< < r &ö́xv"d XJ @,(=`O̠f2h 5 !_@<#RuȌ}1( 3V)0 AP; XpLnO!d`('?̂z/0~F;vffYvi|?$3˾H ߐ f_@OCfd4^`Un9 XLMj|F#$Ro c& ܠ7X27 _i5Ly>>`@E' _М@8gϠllzOO,}aAAv)!f7RQ* }}vw@# BYA !8 pOa+V4ڴ1``RBZ@3o133)Nb =*CeG >!r0@D@Gmf泟N &RB$03')e;MBLHjI'3`d}`$0320(Ɋwp\`QM2"-]#uΠ!XK @R26?ņ;$e#ۂc>::1؁},6&HvxPa>eQT03ѭRtcIENDB`Ext/Images_Client_HighRes/C03_Server.png0000664000000000000000000000565710126474260017032 0ustar rootrootPNG  IHDR00WgAMA7tEXtSoftwareAdobe ImageReadyqe< AIDATxb?PBFFFzyy3#ǏN"0.ŋ؀ FRcXCKK+"22k ?ax/^_~bbbׯN~@4񀓓?;;doo/0nnnp2333X7o0\~ /^bx/^ڻw{Ј7@q@P3=WMM7))ASSϟ? ߾}y, R rr`8p4y3=("NXYYCBBexyyMˌ`"p؟?|po2 ( ė@P.Z^o̠ 0&&`~xp3`+yX"8::K. A?Ó  +'O^=_$eJb!3eܧ͠ _ _~pDafftKw>C!f0K< =2]7!ǖIo~ax%8ɀU  r<@${߿ i..@}`+tFǃBXyʷ _˳ACJ%` 0H1 r1pqħO_߿@F+`5P6ᐐ0qRjy 2 YXHPP3{x)r$ѐ"#ZƢ?Z!0:ޙq<3<@r06 HH~ضE$(mCq<# #40y͛ VaaPQePVXPAv0"3@D,P@?1 1xzZ2`ZLL))ahffcH33- YT@LdbP>ԩPQdW:9I 0HR$!A!s<,FDf a(= 1`+6.pq jA <"BIDV1 Ǐ_'iM&xyB"#sr3`  JJ \jaaXRB$}@d@۷m*x `! +mc\Y P 8778ɉ3/4!s$$$!=@d%!ぽ'` J*AbI`GSDV.AabD13CJB(X%k AZ@UBb?<)12ؐ3#L%2F 0<ꌃ /!5I3"yu'ɰg~`/x$E9w9022pBHRd-)3<'4TG"ߜ:ux5,70|AOa=29.kD贖gÛ/V̠K ?g8xùs'ߜ={ׯCC =?@ s)9 ֔5f4Qe`m{? ߁/_^ Է  rJ@|={t];/{C %%duDY={b*נ|Z܇T r<'9 X\ xA;Annv >|_Cr<1 G@%("",jXF?@LT4 A$dJ3(j0%?OS 5=_pÜv/ ̿2vɥPllϟYQ'1 ?ZxOOpd4O>,<-0:5%WL-RY[;M @$aazd=̮*P#i-jETr[nB[q@QQ18N@ce78<+$tYm$ jjL&q ?coea3g=@X8ݺ:qy8g ,-_*x ?ex+Ç[:g"'P*1 =7ׯc6N{du֗ _Y!@0{;W0>Fx.jd|áCۘ0o`sYu&sM`9)P% /˺/XG~Z]ɥ޻w^ LRcb]RE-x__q]:='`aP;i]q@ӘR@̋#A*qEeEo.?ͼρJ{ oZ+IENDB`Ext/Images_Client_HighRes/C48_Folder.png0000664000000000000000000001126510126472472017003 0ustar rootrootPNG  IHDR00WgAMA7tEXtSoftwareAdobe ImageReadyqe<GIDATxb?P8=@,`_02R@___!^^~UUO]|o߾g={5=@,VV̜8K?Z]|…]vӧ>͛7g^/8 Q+50A˗ |ݻ}P\HJJ>c#((@1|1ܿի^?xp§Ov<{l'A yXȻ{\VW3ܹso~Kd+>r@z 00hZߺu _j֊ՊQ~~~`O@8XACCA_߀ի@SDKT__T\\./++ h2*1fihh$ ba& RoJLL /^d}GDqG3akxxxTTTwbM& &Ǐ ex0;;_֭zKP> TDcWYrFE_?4T?2xΚð=m)PgX#+++$$t`:H01] ,1;~7÷?0~_dKA0`033߀?O</Ì ~5sqJ p1CAMAAAZ֫? +D&o`8X 䉿h)rr3|Ё OϾ3\ǿ /2p2s@0;$>'Ñ_AS] o߾cpܻׯ_=@$+'V=!AAEc ?,Ul?R dP>ʠsÄ˕m7κ?1->.V. A.]ev)Av A.Ymv|VO߀477'ûo? 'lbx)N輧 , EZ2H0Jkw@~ (3f p 1~ebbTcP`eaz 2~{B Y7 0_~ Lv?y F0䉏_w?]g``pـ KQnYFl]&)>fnQ>6_ ?~ba`:_@Ǿ Вd_({89^/L0+A-دf$ˠ# =pqA0`z4$߽hPGArh2zU3@b h;'ë -@|z@|~7z$4a!aW`Z. 66\@ n.pIO'@j? ,o= z?@A<נ ̬Oן! #,!Ȍ`3?hCX:/D'4@$.*_~0&*`޽{wT3} rC@Z oɉX#;AXr#a Md bشbfan߼ׯπZ@i Ç?t<,!R;+;4% #~eo+waW?2b:ԨB9,Jk$)AJ><Z*>PI ŋG 732ȩebWW@1@,Ϗ;w_~Àj8i]XCԁg^A?d 3"%WX, ` `/n`2|{㣯~}+} Dkϧ^g va(%?~ %&pVC C4{NP0ëG, _|a`X7 ]y mJ E黷+-py ;GTXi6v@nR#h|Pbxw k|6`wǫu'\VI 0KG޼*BqZZhu&Ʉd>l+jg3^&1 AB{~], o?Ҙk4xO 娍/0z쮱5#ЧBx}v.^Àj?PKA? 0Hpgaddfـ@r$#4F`2H@!57Г4?r1z|N`2므A<@|.$/p[1#+/7+/' |'; YE2#4Gx?R>a&.yG ;ϗ}Σw51) z޳ᆱ)4 M1 9uH9Լ?G`cO`ă[v=c e_5 kSomHH:7{/.IP eU! 4  __X}b`؀59;0vX!=7>zC á/cc`c~s9#  TuۯPa2O\?N`wKlh|zp.i0g ػ غdLi壗 o~dШ˰C@O=/_]y 0'|h D `GbdĠ}P0" P@ `-00.{Мjpl ge9s 1cd|sˋ_?0ߞ}7_ go?6401B?R?倱FQ ov0 .^d#Ϡ0 S#/ *xŹg @zw^W'&`?;$GH;`-#3*@DŽc`8L.xq!,+CÚ \ <].p흛Z|B Tܙ l?0ÏMfH #BtP&)"B: IFzs_֮Oڋ.e`x?,_O6ʳ71W ߞߐ @c~~rQ&sFFAo.@ v`PXIkh6P+\0B/`C0~c Ŀ;/}w/~2L>}e3oO~{??C|Nu}@q.>9W9-F  L ,@w~xO#MEԨ̙o'þAW$ ol!k5G $;SƓGX?<0~/˿>3| C{_\ uQ G Fĸ \ 3HEH84 o,_'HT|pߡ5~r !@f)AҘA hQ -T9)q$>@Y xC4S62Z|IENDB`Ext/Images_Client_HighRes/C30_Konsole.png0000664000000000000000000000615410132777574017202 0ustar rootrootPNG  IHDR00WgAMA7tEXtSoftwareAdobe ImageReadyqe< IDATxb?P0@ yА@ z/`fffbd`"r`5L †ŀfb 09Fzl f7߾}ye@?;??8CcV6pgD/#*"3CbDGoڲ뷯J= c1`_66S ȟ?2q0x1z:(||Zj ?}bpuo߾Qzx^m U߾22ԁ @=Ls,LL \ fhhjc&:h ޾{\`kof&fP 1@AP&|-߿ }@O3; @!bTJp 0#J RR1AJ> bVBW`GSG2A Av< ) </u@,k1<P!ұdX $ |ɡ@Ca P)؃< <4tAfRr7f,GJ 01z 0P@ ۶mchjjb,VN@~=×ϟQa-f4CXrafx5X+  @!hP0 mR0 '9!Im@S  ruh0C yDMM,`bbpIɓ'39s !,@F'ȎFx<YF(J)_21(cIII1̙3ANNPPl.)PA*@%#=ĄR"9{ 'J ]cgt XHGCa 7l`C\LJ!a`2ڽA h8i/VLpJA@1ČLEPZ Ϗh7o@\ P,cx3ep bps.1HKH0=R,qRBJBMR 0|J -- :/Z$E`me ;P3,Ġ F$@M fHsA0 r$߼u!&:n '3 !CbDCBH/(0 3g2l ^^ VLB⶿L(@4Cֈ'ogL>X "*.2Hn\OfbzhΝ @Kr#@$xE@X C",&Űh+`X"2jjBzR PI|Ξ=0XiOP bT!8.Gt>I %ÕZ(bun@ 3N]n"kw`{J>d ٭fE b G lalbA3P@'@<00*eT128 55Z2Xzk`tx`u̐ԁOĂeKӰ-)/zYC38% X6|@"}`!of@nȐ P`ELm`SXr&&2lػ,} XX30hqzV`5`$cD.&U\'403c4%51h x><n&YAaP&ꇵa# ! ꬃF@Uc򨃣`X`DP 5C Dk庩SI"eֶP: ztlu9iP7'}ԣeXR VS3^}ܘc N`$(`<0ǃ00Yb;#@%G:w0AKoЃ:Zqw/.hLͷ+C^р4`zlGHuhkLc$w7SШs8AXTF1F(v@! *03|:gb'=Ho"Ф?쾲lH zg },@DMXC)@, ߿`pc8}+:#x!5*(#Q7X r󞦖:?!y)% ,UC#5C%]13 =~aL xf:8I@23!+<H4}(y ߻SdDj-` & @p|m߼EZXaH (TF,",ky|xAP9 Ȭ)#Wo> @@1,K)[ f: dڼ  K`:bUhȯ0 IENDB`Ext/Images_Client_HighRes/C44_KNotes.png0000664000000000000000000000630310131463120016746 0ustar rootrootPNG  IHDR00WgAMA7tEXtSoftwareAdobe ImageReadyqe< UIDATxb?P8=@C4=@CFFFx [1SьQPFo=~߿+10* aH``hU?|R fhJ 02rp3233%,(* p*îW1raXp?óO>q ïY@1ׄg9a?޲0iK܇O nJ6F=}W_<Nwݯ_OG~1} +wg$_gK O lR(fh8 f e.&,@ K7B \V00u{@>ԚPZR` k$<6E u̿HK_ @J֋Hem9UX @%~@=񉙉_bNa KB8$0|," =Kj¤k N1<<~ XKNVeyQ;W+yqQÕֱ%\:/h0~?l@{0333Kh1H2'` l/p=73 0E y\CS?{ ox  f ]P5t0)YR`ɰpFC^K?lcDKp q`Ϳo=?tX 0_h  ??@axQO'x(FvWb @h1KGD{KѳB@lDzSohge`8}WBf!FXja|t|kY_) 9kԯέa^!@@|  p@`eaAc FD_o. Z2 84Lsf6mcxc@ɓ@|_'!B'(D k#_ qBi6OVVpI ?V# JQXq mf`|~,#ï,gU;S]S@| 29@(ϓ20=u d63001020@<Aib6y XvC0lh?dt !?n] ޾k5Hc# M  2p22003si~V6^Nv~.&>>Fv^.fV.FFfN&FV&FfnF&bf^&^6  /c& febxKfoo2~ct 4s 's_RadV4 ꪱcA. `bڼ 84'7;73#ٙXؘY9Y ՝?f>z}0Yb t0B6(̈́F3&kbC4 ZAlTˠn 45G@ӬL"5G<Ɍ&ƄG D~i; D7@ yА@&c53IENDB`Ext/Images_Client_HighRes/C65_W.png0000664000000000000000000000224412505025204015760 0ustar rootrootPNG  IHDR00WbKGDYIDATh_U요 VئKf+A$aEDEeA^( HZB^vZ,( Št!n,Bݝspά|yy>9:ґgz.2M$\0;0s1fŝz0"38[ׁAn[s}>|C:;A 8i(q]A̭ lju@W_Ev߀ /O3Rq #cEFQ'}Gc بe䀣rN؁V6Fs}ZV_G0; 6wk̹۰Jj+b@\c\# ݣ1/M?]#6AJm`~\{b^esR|V3slj"V>ԻJ+%',.ʉ&D`MἝ";kHq?DG}vfYH5'LgF(I*BݺLxXo!iχ9eːmnZz}Z5@p?YPPpI_~:F+S,bs:.4+o^8CQJ*T,&\{S_f**BUUCJ)Ѩ5::NLLxHP8pMMM\.?D"W\W^y={ּWڴŢJp,۫aY4MSyLOOc߾}0M\~R 5z{{:>??^3Ϝ9NOOm2I.,s?sT* "… sh49E b$0H^'RJhj155@T"'NG=?Bko&$vD^B)E^'RʻB_9/+o o ߌb#^קh4|Gw0ٳriiLMM5u];ߐR~tIoo{̐l6+[HҒ C*ASSS{`4=iڸhRJ,,,p8L^z1l6+~R!L!L4fX,r\@֚066Ex!;R"P=t(q\|/RJLOOCu!siY9j5E4͕F7n\.|]|@?"ȯ=c gE(~B!4 PeV!JX,1&+ 9p4MBⰾ, s9B!$R\.s?ͽ o_]n z.h<:t;HRS)B! Ðs9B"((faB8鳵  !+J%dٙ?f;Q Ç_;~ٳzM夔RJ%( 4qlpH&4 lTRUU,k RJ9^|@ D6PJYLNN~wrr4MNQE!J)aG. |>(c N i0 *]4߬ !pΩFOOc Bvxා=(]Q1 vvycdd>`yyappƍGTB0ip\B8=!S.c`|||٪y]|E aJҿ4 !1@'F.P,,,[ SO=Ez~6L1,˒-vkw1^,QPڶ'n4R ԇ&:;ѧۭ...LR7 IT*%P(Jg2b4ͭ@L1s}}zϫjvixp…s\eeYnڮjz!l6{+J6P(ӧObLRNܫRJjZ]$IBp)l6e&IG@ GJi !hkIAqE)uݾ}ӫWFIVÎ4؊:{Jϟ;wNv{E#'|Bޟ^>19h^5J/^[oE{=yOI8&W\A"X8pq-)%sSBf)|mN6b Eadŋ9:_)J,#P2 =w޷bX(wPh 6 ØSe$ FV󱾎.,,z7%D"j__o:.(.?rnKXq1kYVX,} !>?~/\#$nRIENDB`Ext/Images_Client_HighRes/C08_Socket.png0000664000000000000000000001242310126472640017006 0ustar rootrootPNG  IHDR00WgAMA7tEXtSoftwareAdobe ImageReadyqe<IDATxb?P0@ y 2t(0e #;<33L ߿b﷧5_]X F<@<11o40/,8/Ьw1 ;Wl< NL~ @X@Ͷr^z2 /^fP&I8$xXY x8z Aolû YxClE$"Xx4$Z% f0YI11 s2s=389 RO_=ۏ_`/2W np=mku]s+=TK Sb‘<"=5}N&A>Nyq~a^`bqP:*?|pG \ ߾c;3yw;/;#_-'22{10hf#1>}G3=w7q!./$ T||o*;  * b\ |cx3"yϟf8}C;Hfv ">A@I”?BOԥ bl  7 2`XE:y;Õ^.Ne`x  P-|S0 L I ~ -jf;{)þ3w-yLM7M޼0UBFcUѷo_2||+Xt 02<4Xًr& Wn mp, mPf1\ ogd8+Dp^0lldNP8Ot`lR(K tUp{ `Ж$TF/_/&0b刔B;!nrO2%QNc9rƐRDQqAʴpHS69nG!GxtFQP&Foff]1!NFnaO73l_4ANUAY]AJZXH?'4M]]v6pUXĿЪ:(AP .&VO1H(i0|zգ;me=GE12_u@xMIXa ˗o߿p~eM]cKKii`g ŧ&C SâEˁ'0X X|U?`)=^AavnEmcKw1{1|g`-CB+og3q JPƅ odM`@=~[j yE ߿}gbcÜs xh2_^?{ (. ;Wxg naXgLN@uXEmZddB/FA闙`x&L` !)n(+SN>>.~>pK*aQ Oc?P?E?$`~`P5g01V,s=5;p0xq1.?V#Έ-~zo-~o000c`vCba| 9~~`0A+^`1p1c ``ˠ1Cғ^_`IGpXzT/hg .#, L'#6_`e0tf`:@I - # ) vQ ++`?f?­ i >/\|a{ƜqH)'` ~֧tq5wq5:mi%AP/Hfoh30~~fp=9!A&$X^b|AX:y3T3h ( e̅ OuQ(a>k3|YdЛy \$gt_`k?rGC_1HC3þ ?3#οgߢMmLY Bُw]x woEM91ނ 0?>@B  dB%6օ GV28A6`C~s ,/?on.dPAU#U_].arG7mt%i/@5 ~#׍F* |WZ $[~(0P- lngІ ߽+[^2[>vY}pm17} jR V 60|61[ocX31M kkN_zAINAUQAHP@X;dI:\d9a~v;䓛 O=x)>gvj?q3 k ^azF/%N>0M#w @77, &1}m4 @aV½g1hVoN7;āɊA0Al<lN|b`t ?&wXMgexUAh'lV2ep|`W}Ty'^@aRbxfFvy K' u<m>P֤'={{# 2| @K9`nj+c#g~ffk.{hA   @LX{O>l䕗) 1k;JPˆ}Ab ?c`ؼ! p6jbb(' t< xG'Hcf82awh P@a_ g[Wvj MXE&' bX7AIiC$  3@LAs`0)s#Ёq  /|?f`ǰ73۱ -LPML*NC߫0`O<$͠A, P\XZp 7ebE60"xЇ4d.垆wߟyt休T01Wg0#gА`wg&#p:dgPI`7515d^_~, _02|*=ϠT3(D?2pWN`I(0f ,:?;:C`#79~]`hh?D3a5drg5Pbd``e/kG8׳s :RpF..`煓XA@c(#d:ϟguXDLBؐ \bǠMP:uv )`010]O?F_>( 4\h=!t 4*zQʰ ? t+  f)Qt,y!Qh2Lc&&CA! :d3;(|C8P mBGɋ+8՘%C:d(kaa0##W@ no˭ .20 gJ npNcAcI`#X*s?h`6 ,̾;o30{ɨ?n`<mz1hrc:4FzAk\0w== hpAuW(A$@`!Y ;ff"IENDB`Ext/Images_Client_HighRes/C60_KFM_Home.png0000664000000000000000000001161110133316662017136 0ustar rootrootPNG  IHDR00WgAMA7tEXtSoftwareAdobe ImageReadyqe<IDATxb?P0@ yА@ yА@1( FF'`Q~߀_@=-a35}b`aP+%6=P %X8 ;O8+;CƒJJXdy`}ڶK|C}EAVf6Bh:w&|ۓy !Ͳ݄:7)F@Lq\N:M D`jNP˷{ֿfm/RZɫ&Rz;*h]7xnҩr"<(!3R4#0Qȑq5v)* ' 0iq(LP/OW'A 7;mn@ IXi9,cR9E MX΍$wXBm;hSuGԏ'&e)6F/,ABNYecMrS}_z F>0{ك /_`'s$tݿ6ɥ : c`bbbxz8ã[׀A)a)9gX?bpUaedg`ŏ@G CAtObX ^x k؃gYDfM0*k{:K%v圪 -֛h5A){xw,.K50nB&dHAKv#Y0ޟQ ;._wH=R =X/>M(@}`B>F%9Il< -,"D j= YJ]+0_fhFtoJ<+Pl SH`mo0"XM,1 NDw I;ˉn1iRWRN[!*U}s[Ma-<| u0T4H[H`݆u67N"ڪRωIb<޼yCl{u..d֧1OZ&.iċ#eY :l9.eeK=ۣhHC"t_%mOEYJxiq ,q݉ń۽Q2/*{(? M'b,bL0uӽ73gl%1MQq:6M;l.bGgk6Nuoh>|S]dj>. N@E^`.- F^^ uY#֢자;,L@p$10Hb?~0H 3kʖSMՁk r* L \k bR ^a&` L_^>`zTPBX0|{ G_LJW ̌@yy/>2%G[ G8?:Xg2WVFԟ/_Yt! xV`da adW|Y /K ooX='/ 8çWFsX=%_Ϗ.2K=a#+`!$cPt,@c@wŋ͛ A.(`#5&fpǠg`t\  9`e:Xaq 2H3|:T/{WLX=-NA O2GwT5>*TV K>~%%v`y,X{2&hg>:#xW? dP 62 02̴ r#+?q &o* `(X ʨ330PX? ,޽tW-`/ { LJ܂@k`7O2p 1~r/ûO+KU5 `ǻwj7 e0 wb ( )|{FsJ 9ovFL5֖k zvx_JN/fpwJ򇒊(ApJ)3OLOu}Ps8WMe!08Vm$BKz3Ϡ~ b A"tu>KXb;d侜?}̪mP;YnYOL=#&sy|>+Y(<LSZ>VE}rD)g*;S9 hp@, FĽR\=p$1&`'ep>.`/lm l 1_ l2@'1R0'pC@+e@  j`T ;1ƅAU/ l:`bþ~T l ao2| $~aFS`Ty]f4)>C_ĂĈ( a?32B;Pؠ"CMʐi6`#X0{/ȗP57?`oٶ 7~1ae<]_~{) y Ă r ̨>>ax=(6.ly2pde4SnŰel׹qJ$c 160v0v'`gx^FS`2꘠AO@,xPO/1<_9?0I3؉L>88Yb HprLT9@8Yc!,LD9$ٌ;_=gf8 þ\ UUƠm ;?m`,~9J!ITپS)U X,#~@8=&@BL^ <f#q Mz$ lgSfd8 v@ `)4/`F,M P&{@ \ YW Xy3.ETs )baX-H8C3AYd .0V! L .2×,`o`( &IZjP@ ch^$* c@A%`נPAO0dzCW?<~>ïF@NBL YzX9Tifv&$ :#0yoAP?v>y lJqepc t< Тx33@/X  ?z<{o3|=P ̣1MN lL>?}pM`,8#` ? (s?>OhN@8!q ?@KU>` Z_-gb`OYU%lsā-q`MAU``M, M3` 4gEt0?vj3( i"+iFD%ŷC'bP/Z2@2(SB ӗ ? \]oex/&`2bί<H h +R 031VV!b0yh@b%û{/ aU% #ez+o:+3fbep^?W`02CFUu#C>3|{ wgxx"ë; 2A1P pPι T s럳-K͵ ,N 00ss2C(@ 3p#~{Q2<3?y#`yX X<:%:} `ADXNPрCYD!2AX42J 憖_>OawÃy0?g@89l}~CD (RpUa`pd`RaPqc5d1fxw<Ãcǀ,y30Y2ЕOC/Q-("zؠ"`g UcaД`x' L π!ıP~u;O"$@x=VU*0(V#fR4ȷ~ ] -M`t@z[@'CF8{А! D=+IENDB`Ext/Images_Client_HighRes/C58_KGPG.png0000664000000000000000000001312310131463510016301 0ustar rootrootPNG  IHDR00WgAMA7tEXtSoftwareAdobe ImageReadyqe<IDATxb?Pc0228_ @o1y7P Oܯ on30̺$F 2'A=ȗCL~ 03' ЗL L w.t*'UY>_/?Kf```T)s%8!4Po L@or9!+Ñ s;2G0 t~LQba`l&u?~ݳҋ;@@M@K 8Ai   f11\/SO}Y=fy'7,%$E޼{pMᅳ8\ͬ8 c+ۗόnO撻ov·I#Ă7WVbzd3Éu, +S`xz ,ADh$0F1y (tU.֌tZz[2H*00cW@}Î+|G |džUb x3ZNV? W߾pHȃo2 uAeudx0Hjp'I 80T~ o&6CeIm;OtO b  -- yF3$No^>n&Q%9` q cJIAQF//A @If.|F`0?P XR1X00p3oY=jz+9@/ 20 A e &L|;hR\AL BpO>聿@ps21pz@,HxdG3bA ,Ϡ* 4h8A @/po`~}c&Fvh`1 R;G/; ߁I'3+ !e=#6 0`_p t_~}o0T. &W`dgD<Б_?ÓdUāy$b??&>#?0|姿?}ڲȝ,cA6 _u&$@"QK'w/$4K$;kjZ 8PT^R8Vd w߱udnRp}>'!+`6LFJ`6lA-ԝ0u/'`J  @~fxXH U B;L Т!fw b8& >`kǁ)XK JB ]10s;0\޾ "ַ%Nk ;30d0} "kVcxߙYߑ yb-Jgz]l_h6"X/ lD֧2_YWADџBϛa- ߯lbػE@ /l,[~ n`X) $=+:z 9& 콿 1q~ #REɠ,-[!pG`epa?_"V4xO]-w|aprAכ0Gق;%/4Cl,ãǟUM FV B9@K z~=O:< v<] o~av{RWA?@GIc`b`q`p?eAFF f0QAX 038XK28A!?X!q3)@,86 G~|C#?R9/"#_4^6d ?''#;SEۏ ?8=fV<?#O` Dy\pOO7~{9£~u] Ąu( *!Y3fbA0kzAA#߀l0|b^^FP_Ûް=ɬB@|PchO>~adf~04mc"Yd=@mǮdu|- j<LLpaNN+ĀWf0a`0H ⋊q2 < b2| v.@k%@) z`ҧ?NiTR޼K_&' /o4%1VV`w w~50>5< ^d`efPU5̔ Xy A NW Ԩ?QmÀ!$L矁I AA݅7>}'vY8@\F fK>| /4/"4R H($m|7,,~t0p0=h #Pǃ0WL o_a5accKācG`>;|)`(@+’@@@0fja 2`{ŠL }VcACh7 ˰0[p r ,. ,wWP B4Û5"` !>'_?Mʗ_>3<V~o2~%HFL xP p`Jn`Ykݯ@t 10$Y+M`{gW?8RP%!6<jO1s0Oan: e8'sLLp&_Ȭ"A(^<nj7C?"5<~wKhǞ R1# 2W` t$8+4AiP,fdxnȰdÇ G^څ0𚙂cOhb A4Z />ӣ d̄~ B1 c2lv@;à w7gR;7>` `b3@i2?#<n?é9y%A_e:O ʼ LJr oŒo/)1h2jJ1paHH!1(& N!#3$#;;2| Ϟ8Ġob32b20[뭵[ 5Ph00( '+-9&`0 t`nl.V__}dxw> {.2 r8S@^4f3%uC|c  W= zز@B6+3 +## l/1#rkf??~1_P-P}3.=] Ġ6J@<Wg`6&{3'MdΔ72]D!3*c`QA` x`w陠3{2] Ԑ戏@0>B_B@I4S@<@<ˑ[N^v;udСofhŋhHXh}Њ7t@;t +4PF@'bdAcG($A-Ʀ `O&,?<J#4@z`˂>Մh9mh 0)&Y.IENDB`Ext/Images_Client_HighRes/C27_NFS_Unmount.png0000664000000000000000000000571510127240422017730 0ustar rootrootPNG  IHDR00WgAMA7tEXtSoftwareAdobe ImageReadyqe< _IDATxb?P0@ y 2E244Ul@)fPrCWC @ՊݜA%~=G<  FV r@,22߿e@Y FF!|Ąć1aɓW d`aafx+ed<h @8=o3QQ k -@! 6$sG19)d 9ffX>} v A=OdwNNJO?`033٠fb,"y5!aˬ l _s-R ~f8D3H @axETƘǏ @n _L? <p(_?M B@ff4UP(oqq!` ˗Ox P_i`((ȏ8\ 0 ˃Zڰ @LMjB@v,,Lđ@$!` -** -kP0||r5=*@A@ >hI@,Y` VcU..L /^|6@x5gv4I <Ǡ **Bf`^w3|j߿+3 1hBVaEjJ@$,Jul"c׾ZԔy֕vt!MlDAETc (y V('իWsPPP`x a{P$Rj=|v`%E1atA0?~Bb T_B6@C~(DA ߿_ ?~?;\GG#e hb/HĂLJ#! m@X4XR A`VFVm3w h7#?o1Zޘ r,1r4q  a Úz@FJ_ y$ : :|z""tAC𨕒@A>HXFϟ?RiYʁi ^2zԽo\ @ t0AT0bԩed\p ֺ/^~HUG@|  @ ,@@|ZZ&?LqNP!~@HPVb}d lK}o ,hP~įUCz«811 X~h |ρ1Ojn -V`{_2\?CeUU r}Ry1wq۷o% F@?~Hʭ3D)p1_[ R82XnjL+ٳK>Pɉ>' I6#$%%ƌ` n1zՅÂF~cA[UA7Xh:*˧O0f@мHU@,$#OK;X=;e.`r;0ʠƳ_>3<v>\~f X%K1!Q HBbO`~[ "0 ?P+{/1Ğ~7H*$[_N@16IENDB`Ext/Images_Client_HighRes/C51_Decrypted.png0000664000000000000000000000605310133443166017500 0ustar rootrootPNG  IHDR00WgAMA7tEXtSoftwareAdobe ImageReadyqe< IDATxb?PĂK"<}l3k׮14ݻ7?e0^@)uvvN55mIkk[`L=I+tSL t!W 돁I߿N> & l@piwKw}*'ATT dw:֭K뀱T9et`. O:å@<L"YYb>Se/_?÷o?+\ Dz7 S`RpU/baa*?!zɓ =_|cPUUe'L&$L>m˖?e?(0u@;X/0++X |`evY?}}#AYYIP~b5d@8c_F0Fy@XX)ft/̱ـ@SeZP^Ag`zA+oh``Dt)+D Q3s?06~gfXcN B`V.qn O22Wo }4柏fL?\ I`Qn@B?1GsHsF 7??ag/*Ѝ9_^f@ጁ5똫&8#?֦6#7#F>AE-kP=wSĮ wzas'@;;&0!.A_p L?qZ6"X*j0\?}[2ݜfo@_@9A0X${A@I$DP~Y38 _!A q0C=LH3 Ç ?ށZ lB TC豿K423[b?0Ԁđ? xAI]N3ɠ$PxXS /X 01Z AL 6H 03Z0Ā <}@*2FH7Y1^ЌV;0DjDh' *"P׶jX.)R&!f:+%1u@pT!18@n2AjρĂw  ]JF< 5(#@؅2b= gS׳ 1)@5f#w>z2b=pң?o?gdbD -'lyo@ P_@L C@NNՅIIENDB`Ext/Images_Client_HighRes/C14_Laptop_Power.png0000664000000000000000000000741710133447036020174 0ustar rootrootPNG  IHDR00WgAMA7tEXtSoftwareAdobe ImageReadyqe<IDATxb?P0@ yА@ yА@ yА@@MՃ9vrDDIk#g_ QƘ:7a4^efNJ|Etqsu/@,h-8Y" lX9~102gO ߿}`Ï|ӧ_}zׯ~} 衫,,,ׁC") gygaf`bn ``dg``ee``Ў?~|4{ٛ7O>Ͼ||?;Y r<@X=/ D3|AFHV6V fa`egd`:?1͘%،@f1}F;wn^vٳgy?:b=@Bj0334 vfyYyyx9؄ED3 L +YX ,F޽{p)0ܽ{w0?U? (%P@Z$ 2@ ôiߺu#u>͹B3=S ?:p[[dJK0| f`pE7ϟ?zb H ,`'T BL*@iT`Oϝ;llaѢ 3fLmR {Ν;a>@a5,9Xs.'v'8(_EĤ$%elQy/^ܹ ` bl~߿cy ;A@ U8XHāE@M,?=󒉑.#y` \K?~JKKP]&,, 8ʻw  ?v$BN>6.`}!͂?7o_>2|}y갳$bFdjN{@z hh0#VHJ*2i2HF.V,Zb@/߁o/~2yVÛ2/2|AMM̚AGW_ͫ{ #TQDI))_+;'k;Ga!vNH @7P?` -~C'y7~0|ɣ wnapi>0ӧ޾}s46@,? dN d``Dif1M $"jZb}X6ձ$íw<˰{ M9@0* {TnT 00JCH 'pf%U!hLL\v/"͛ vꁱ~ڇX UU!ڔA]>d`~I`"b`R fe>p1; >y2j[f f3402r13(;$$RZ_20<}<0c`g`e`zA0(fO`u+`2z0pj1||_@eUY<P>eM$$%Kl$64S2m]{4"rg$#νx -],龢X0z/S7@Ψe"{08cggmI-̖L TK-XpcbWڟ>(2p@,yq?4`}bx,3o2 0A 9g00j1[ R`p;@9 X+_Pj~c86`7_"0VRꁡLjd~{ŗ q #!=F1ܹa6)2̼ ,@bd37_+o߰ z۷e7~AW2H ^fP4| '8?V% UY48>pw{߃+ >`v33߿f ?ˠ>uln UU7+" J^Ю+0t~b`عp+W*H%H92O ?I`(ps# O-.`WTXH;+0A/o>;jTnVp÷?=?:a0Rs!Ú 4~TN  ǶA?ƎUSӾ00 `f&)W8Կ}plܻLJǙ`s+@a/F3s0Z[d3*ӱy#C~>ע< n~ + #// /AAX|UX~@@A<T2ܸ7Lr?I!ymd(V z߅嶟 z>A 'Tطas>/<Y]zy#f&;&V)1qsh{ Lr`Zva|zp7#X튇k`ǿz}Eh1331\oH@=}/uLo`!E7el100,ީpWA% A?#X4;71)K3"Vknqf3w l6bbX#/zH2Z/Tz?@%ght>[v03\ &³+ RRf*%+# ٘!pWV[5}jO6`g3fV^6&/snTykopTp+;&^aax|{j,,j||,:.2+0HƯ^]#vdffLee 0S _&N,Qv?{Pf n%Pp`8̨%;zOdcfbYu 6zHߟ~ddd@l pء=O ă:G`[A "43|Xbe`t@YX # @+ l +` jabb HdZ 6:b.@xU TKqА!!!0tsIENDB`Ext/Images_Client_HighRes/C41_VectorGfx.png0000664000000000000000000000523510127777324017475 0ustar rootrootPNG  IHDR00WgAMA7tEXtSoftwareAdobe ImageReadyqe< /IDATxb?P0@ 02228:::qpptrsskc@:_~۷oO~K/X 888X*))m.))RPP`/IR;I2333<|Ǐ @T<@( @ݢBL 5S9h_}/"J)o"b%aι*d c@ "ZfF^ugL@1. yd!,:M:|jizAVV ( H @adb`H2b_AWGL,,`W"Xx &@,Ĥab-OV..F`3C=y*ΈĄ6yV 0 b8r%3OJ`` @XLb 3%Q1գ@@_\nc][@,bpAXE~FV! HIƍ ߽col;XCTK^Ă#_ kk2xL/P: +ǖB/_2\fXjf&&o0D @1QbW q`2ٝ vgAI0p30dBe8hv)`HM`g<ax۳g vd5MB߯_D#hlI HʰH4 0Ӟe tMa!ӧ LO00| KPA(i<@ϒZDt@0į_!m##H &-[Xŋ ?|Udxb"T ;Obw/S_f#a0@4W ?9 [ &b(Y$NJL>ee _A s`?  Pf'S@`>e:;0}f0LIaf t,Ëρ+$*B<؏GIM B4 }0|3 :yAԔAё'0A2<۶5RD= ԍ[$ fB[; p``q\QCC?@GՀ*c䓓?~~PZ%%zB; lf3c$A4f@kqb+ @ĺ;0ݿYӍ $qPf6|(cw^t?:l XOk@? -``cPALQlh}t@dJb/yU~`=t3`W*2"-dVD 3H#qD'II`|L5:_ 6EB0'+ 6ÂB`@m + f 67aKBB%aӮ1Z J2 *q@O>f/^0|C//` 2#t@,fXB12.-gla&p z=06cyFA\J hh ?<@,6%%/P X 9;7ܼp X*@dzcʹ'?@8FɚbUUUUP93TAg&@j@ m3Q/34xO C0@xsԚ#'Oa`?dHsS =˃%K0}:W@|e˖5/ gbXXM  4 憷)fNo@WԌO>@w$@<6NX Z,<@<KZMU-[~: .LR)E]IENDB`Ext/Images_Client_HighRes/C05_Edu_Languages.png0000664000000000000000000001070610131211520020240 0ustar rootrootPNG  IHDR00WgAMA7tEXtSoftwareAdobe ImageReadyqe<XIDATxb?P0@ yА@} ï L lLſ|C10:ku/ Ȱt R"0pUMCN9D_ɳ ?џ/9Еw|A{@1s4?x2$9'$/322󏟿~NP_̍%Vsr02000Fl $ 7˰o_U1|ۼ%@R.W7Q74ge`ced+7/n]O{ {9h-l9^}gdxaqn^v`^ff``fx@qg` d+23h2^b@(*[,'YYϔhw1΂*nbz_dMVMLRgVvc``y) H c@z'PLIGኸܷW @Z9;$5%گ$@WrYU%DŅ96s5Cʛ߻K%qs31D:L$ a1CQ!^F` D?~~2wH-t(Tf.pt? v@GcYǧ6>^`#0?_ MK ̬, F66 6J_}ZO9  `b ešId`xá&!"⢮*: L3# ߟ9P@=Cbc01{iK33eBV&$O av$B| Oe5ۋ͗ȷ@@LB?~PWez7бLb_@{dJ@b2w\k}h3ςR+TpS3Rej&H G~0^wo0Yz#0i opI$<JR@?@Gb J>.&!H3g0)=~? | ';0YYXYX RV^@{/3w~z?w^} hBgłN绕ʇw_5ucXc`e`caF#s)L ?cxןIM:@o٣n~OX ;W93333FpfgV1ex%k~<4e>j"`qf(H3Sadd8}*on}U3W!I`?{~3h0_yaWwΞfX 4k+gpp1% y9y' ,ex5Ë~g+A@߽cx.qy|r# @C<@@C Gv0J:2 iiyV>pmw ,d11wRgE`^|6cK=jz g`Xi+1,:;A_ABב܁ 'mbPx8iF` _󅐫:10àի a R^}1[ !<@b62Ѳ4s.77م#?:ΠK׎itf`` wk2|6^3bs! ֫+ b kgx^m@S#Cj)32$GU]'`,ao * bYY 2TA÷< Q j ߀_1T3JF129:W ]@rEΈ_7{j`CĴ~W__{s ׮ f9sP~B@+E3/O| - k?1|AQH؟ee6'.z132q  "< e#G>~?1\~}AR_A4Bi,+ʙJ 2xseqLؿ _+# 92-%~: =T/+(2pXSAd}[@!2 RT>ֲ`63? m.P&X;t>w`b0Pf"T1!D X8,eD|,LF @O<`O0ˑP: j=¿y )z  @=Y `fc`x9 Lc6`a: L(c9@lN=y/ 7,1q0 p`ae#A@03ǀ009xpa&pA?5$ KiI@p;1>.` L>!?$fF!yZ(0_pCb`?@;y)Jb  K2MVa>ЇH 1?$(/{fr<'G`Byn g`r80j&DP``pk﯀?BdOPðΕo=>1p- ylHR0B?Z @?A"btw ~1 }[#eܸ`:X MBP0PFHkÓ(2@:NJ 0qf{Ý?1| LI ~l+[2?+8 q<R)Fc(+JA1= 4(_ `{ ߮ݧޡ`P-fWcsffֶ@g;4.|%!pL La?2|z w{ jć@v tr8 '` <+3VGz7>} F u)YOJ \ \< , lB ,\L,l@=L?w_Ar}}h\6 @3BkHG$ajN. t S60_tHtP;dlr@UyZs"9 I|v8d_wl hFNIENDB`Ext/Images_Client_HighRes/C53_Apply.png0000664000000000000000000000544710133445206016647 0ustar rootrootPNG  IHDR00WgAMA7tEXtSoftwareAdobe ImageReadyqe< IDATxb?P8=@C4=@C4=@Ca^N.sPym?w%}`>0i(Y`!e}* h-Ao 44O>(x{{xw0Lpx}` Y`^NAqQ3aQaC ]@ Rǫ:3g޽  ߿ ]\RZ* * >}fx5:h0y@ߟUed6?ưU7޽dbb)D@o)\"| nBb K_^!S])`%iC>A`-ð n1<7c+)ȸ (򚊎z34C$73 ?߿g~ @bddej/0  0c,`egfbed01d/ hz0C,0n}ʰC10~gvF&aUgSe}?`=!C #+s2(C<Ͽ0?&` Ņ@1afbL~|Գ Z Z *& ,|@O7ҋ90eSg3f1daV:X(&0>yǰKs>1}33s(Ʒ4'No]҇ ~ q &\ ,^3uZje. C:1/o~1  46@ax aƷ3yr ‘ R܁^ H47A6QPEsnP+CN$;o߯6{pW_`b`UJ0Ê^3Fzqgau[!oZk}o߿`dVdcgapWbe`/ o :뿗 d8uï[232G3Y`҄K\ 0+*0H 0j13˃3ߠto^1z_ ߮9?^B @a_##.Z&4"(0x ^2^No dC0_2м?ߙ!/x 0c7 )ü2aPe t(#т, /`e N6 oCȹ@3guJO $!ft>3>zI#q)`Ì? :yG+2`#-KFR*[ ,S~=`a l^ae`´1 ؾcT@X3//n%AOP`?p,BT~a) `;;O_L غ3c? gA1 0?,*02=q/)1}c iӽ &l1 310Obz#G_2|e >a8{I,W"Iٔτ30aʼ-N/2|6Ⱦ,0m&7'ebfvG X?c~{ g l0c g7@|o7xu+}f#=^W'nfdtP%UYcƧ Ipz Ok?Ggw?Z""C>36},(rWP 5&WZ@%@712[5cf^X@C~ h{ h{ h{ Cu:IENDB`Ext/Images_Client_HighRes/C06_KCMDF.png0000664000000000000000000000642210131465510016374 0ustar rootrootPNG  IHDR00WgAMA7tEXtSoftwareAdobe ImageReadyqe< IDATxb?P8=@C4=@C4=@CFFF'30d`~0aP35٘N%7_x(.D t2'yn ׁJ~<J>W29fg>.*y @/C!';{+.H!÷7o8ҥg00,*BdpK˄ x_30}F}6'n<淲u8 ^C]ii'QII_~b`k ۏ}۷5kOZM2:Y<Z^p}8x@ .r0dó_u9g| c`fcfn7S5g`gg8oL _fw Áw/?b`hWt o{)2o)%H}P7$=bbuGV\߲Chl=@4ADT>4AVS7? >y,,`.^dy?~ P0q `7I,k ? 9X E n0^:.hvBFFstmḿI d`F| 7?pѣwKeηhwsJ}Ħ p89s ?N7`ٜ0ULV F @ (:g$dQ0b8߾dFO~r|b`dXN0r0X^+Ă(g l30\ ܐht313۷;g-8ٟ@P HAhd>34I%`$3BR-18t(E,STU!1f?`΁&>" |EsIcMfb9$'&hx PO@ 85 IAu`G0|&.| %,ٿn{;C )"?!{ Q DKPb9#H {X0P9/.p#H!XA 31M'Hbh1C1(ԯCt&4Gz0@,X2| -%ρ@B π ՟i,FhFȞ^c` b8*D \ hJ >Lp$ ?AeH1t$3+nݻ ", ((LL zͧ {ogK nE231f[s>2\-hǨk@jzǀ1%ъm&&H-ة l 3\}ao _^ [y-ù?} W @,DT[ۻV>~<@66SA!/O0lԐ1|;?3hK51'"ȱ,>We= oq0P[m?%cIp HD6߀U?P?/qte*(nF~#i'AD On~s4L F%1}rS`l۟3Ch4L @$"6a&m5\Z,ff2:"Ο?+,ckE؟H/Vhms~2lǏ޽ SGw+@aϟ? Qı6l1*>x` a0CC [GfĆ R#B]S (Gq8B-cb/6. /çO89@ &6ɀgĈX;fEB(2o;a"ٌ0#A44f#ƅANV`)@= lʁ ll Lq##j:@P  7H3iyÊ * =2;4Wh+C5v7ɸ_e{%G7 Pր8kQqtT *@9 X70kP`)$VA=rDh/Y` LD%!" 0@< cϠAf^_v'?Y8(@ɊRKM`KcFHbR iA*L0He * (?c,^baF X(?}w4xX )>qv@1N6y9h' A #0 J?x1$7$,~ϰ ݘaC=ÿ_ɇhpiB\)@,20(W22A<Ĉ^vN)APe/Hn90i\{  F^~ ߿gg7/20(LV#qi X9{LZ хGޱcՐ`VDe; w/p!S?pÐf`b_2~O~P7%.g: h/ Wg3piêa}/`)ưkv5;1|՞72 ~~e893?3Y6û?3aXTϞ#exAXa3<}p{,JV`032}۷@3!@DPqm{6]Nx0qieNe5MdX B]`맯 ?~cռ_Do>_am`S0ƙz܌Ж Å!'{Ta¨о (05yylYpy?1MN nW0<ܒp3u4@ݔJJv?- `?G?d1a | g6ͰuGN 0ڭ? "l@'-@F`y #: <`D$!`tK=>e?| ,yK?޿|0>.J" e?}~ag|;DT?$@,ҠzK<{sE nG6|u Q1Pi@UDSDT~x&=]C ]<LDHP//; 䣡Xz `/} j)D֋<Ǎ}t~ Dwv:~] -"nd\G+ vQb%A G3rn6.b" :?A"* Q/*Ib"Ԕ(شFy!6O8RT{@`%' cWFD9% .@,8,b13Ȉ0 4`aa k`VvիSآ??sVa&+͛7A @@7MV=h{ q؉IENDB`Ext/Images_Client_HighRes/C07_Kate.png0000664000000000000000000001156310126464474016453 0ustar rootrootPNG  IHDR00WgAMA7tEXtSoftwareAdobe ImageReadyqe<IDATxb?P8=@C4=@C4=1A (AlP|_\-VDܔ"9$1tg5ސ\z}!q\˸CwiU#p p 02v%cgh`h 101] r #s  !??~ՃԂ԰031a oHϧN~ h$+ꫪ=;k-^~߁r ,PP)&fHԀ Rc j/ï^e1a//ɉ {!E%18~`ia`d0`@u$C O=3 DLP0ρh6vQN }rKUG=:t ςbzl20#V4C ? |(^@(Ëo FV* VB ǎbx|06dP%#`A!Y*_@g0X2}|}77/;Lg9C +3*JDbXluu{99 3`c(h )Gc;.2ps0H 3q8#Zx'~=7D :_@1}$t8>C/[?_-U@lUp/Jh π& v1HJ2"LFl < ( !p52*H ß?VH:74v@jc; bDt̼_+KyQzSU=dQOood`84-@1A|uo֯dbbcsF. adpMgRd`Xdý8!E%(A! r0  r<(A|#×/"?i g ʽ Ҭ /jX͐WڄỸ;O C.zYz`c`''" <@0i!`pu1NB=Kb0_@7>߁z=Ȱ9!\kCXvg6j~ }bW[ȔApMz߿h 7g_D8\ꀢ06I)NWa׺} <`↔L?,ۀb'0|z{;1``y8!uVz&`P%~?f2(p1+001( ,߿l<}Ǩ$һ | _0eyKpLp=7f6FW  2 J |gxp,g`bNO0|K*z B Rss!],b X2~; %Á< {'Fck _[A "_^AAPQ#`Q ?4/'(?8l@k0|;wWd8s  sf8`+Ys%H ^cppLJZ-@ g@!{>l;̺,5؁0(778?ppq037niPӄAZFC yn>o_3+\66`҈d/PShX'İùoIĽUPĿ>rw~bó *r@98x}x (" NF?! =lXa5HCXb`acez ۳D1a0HZ$  ?`p`*?îiq b8J2@|?ߤ=z &.p820v7?/çW>Lk `2zr.&}ܐct V L:rX/&XFW7Dִc8q >8 1oZ !}~3\}X1A,3pi ,DANn)pb`x>æJ'* 2g3+\K`|q `8AaotEkP9 @֘O[&>4po ï?"A3\@{JP;=$ )a w30˧F Qߟ_H+ ;ֽy參e@W X0KǏ~ ?}`Ql X`..- LO€p`7l!Nag?dX<Ñ+_cP)s' @a;OO?0` +*Ao/_^>z,b0<{xATRAXr1\sئ +!ki‘aV~-+>0%1`ȩXb`?X|A3M+w-[Hsf)*/`@˰prJ)= )L@1a?}B??^\.%/ bMa0 af55&N! H04Lk0m "`]7Y9~~~`BDׯ?+ecYat`{`g"2|!)efw3\xNg2<859{AA!!e^ie'OXE9(>‘בOY^ .-Gi >X k;tA Bb2 & y NJJ r2 0923P /H|_ >Ă[?ؾ=yKIE o1p-PE ?֭W Z 2 ΠlI3p p_A`R7 AR*Ӳe@0@s?y pzׯ%wY ?yϚÚЧ޻`i -%nrC_ 1K-`y/"" t<+dh NAXDNÇ3b@a.b<@xb7Ж=+(+$B:B3*_=#u ؼ%` juSG1ddE44=ܣ'^P2 4@<<+3+1<XbatAcr1@;X1r?#bp6 58z`P)2 &>xw>O ǀOn08Y Xi_AؿAr@(D_[أ ?JB/~\{-\~fxl>W@Ml&Ȩ4g4A.!Fw`k:1A2| L~}? Yxdt`(0~ և+|as p033i&&!@1?`1 :ϟ E+Dû3x~X$D^\_"-O?c LLB FNI춿@X $|v@`%o/o0a;`0 TY~2IJ0AɵAGG0Ř  }H &&䁿`O!'!bAeP F(` DǓ ܼbAUTK a6# f#F U 9D  &RQ y Q#g{SM0{ f8G=%/`)hp*Q@ćHXH`!I"ѰLbRbeb{u +*Ël8ܹi_ltjD34@ d aɋJBh X>  1{ 7i÷oovn~X3 p'@G@GfPz@9k2ocʃ )@h1Ig?=|/95[/v .= DzCPM4 y /4?Q%.OhH+?J+ PK!x&Ƭn'XhJÚΠ $ ""`/r’.`FFÞ* *``e0|fxs 0Q <>w<`0w)~P 3Rܡ_d@XnHf L5febfb%mFg&N N Lg`)0}sʠ#+ e fDb3c(P/( fs?hNJ|s{" Þ#[`ZMNneXZpwPFMuK`3 A3N ܸCB0t/_8 1d_ op V1<~^6 lgc$ggC߾?Zs P ǀ>ׯaeX ?g>FHC OMU0~Σ>TȀ1 Ȁ1䈩8j`ߕG  f~ o;@/?P85<8ˀ 8r Lhb`q`1;`!?@C4=@C4=@C4=@C4=`zџ:IENDB`Ext/Images_Client_HighRes/C34_Configure.png0000664000000000000000000000552110133443174017475 0ustar rootrootPNG  IHDR00WgAMA7tEXtSoftwareAdobe ImageReadyqe< IDATxb?P8=@C4=@©j!:###7P= PP9-m6>@Ubbb"" BB" ,, ~dx޾}_3ⓀyO < aNN70--uAA~vff&1| nݒ8spÓ'w1r < };yaaAVV&O_| etzb-=@LDz??ssӦ- `O?3z(: hb—ly?k]PgcgX`bbd+;;3 ߿'€V &j`r߿0q -ao{ ¼,@0cABBϟ?1@1a)*UYY"|T`߿<_a{knp ř`{D,9H[:b 0<F@@YKK!<<Ƌm)~:@i߿mϞ= eb̌ m EZx 0_#qpb`7;py$?~'߿se'!P $6$$l@@)F% 1  ?=/ȴ0|ׯ߻wϟ`23,@1Lb" S@`0tR~\ڸ8w߾uP 7TEI`PBAfb@6 ;PTÂ<e?33H מ=d12S166Cs<$ׯ_ _~\ GP@# 6\{?7_|\`/P^9^RR^@<NJ?~ ={7di)rT^997KK'55M11q`;TB\x 3Ф[)S&3l޼ 9\L _xb@3= J3v+9 bcVܔ%5 Oa:u Æ +0n"`+CHـM+T166 %577}m`-֬Yr@x XHJo}>f M+cD;33Vě9PVV#ګW/ Yb@LT+n-ؽ{E2ܿX|#T< ,~8E,@1Qe`~҇ J>S=7 5@O,z" 'nJk]7o&O=&@#PQp-$PTTFPL H<0&WZpcΜx+\ }Fʨ: .'H6KND@=LNQ+V{ 'OނYaU~0ObX,cb<@4t, ́K~8g4pGx J:Xsp22$$dc6扳x񬫳fM&?(& ߿`xlK= ə?<@449X fk#%!.m- uu1L`g͚tcԉ$PL R" 12>aa!!&&oxW``(/?PP a9^GAY_߿,,Νc{FTNIMcW/oh/X:| ߻88 B{2HK303003▁}c`da`AK5O]XLhk ~  de{w` w| *! %*hfLrj_33C`ľ B  =W &NNII`T>8@c@3j0 r21Hq1pq0/0%ge6߀0BB &r=h * }@y@e`%(;P=L < q3| '񏡡; J?U޿f~b OIB@ǃѳn2|cg%()+T *AA? ex ç~|b`Ƿ@@dd&j888rٹ9yN:=c /+и7oas~3(iɹEWnedD_`ћ LO]D_zf±'ObxùOgx+ "p~= ^Nn:V`z3o?`/ΠpK46A o&`1{2}g.Q9%N> /gx;'u C0ȼG_>3; j \:0H1< oϱ0ػ0pp3|!>` 111bbɕI< 7> 0L` ,9bX]xp_ ـr 4;v fbxÕ`reRUV,`ADD[˗O\&@߿9ؘ.>`,B @:R@UNp+G? ̋ԕm<=pן3hIV.{uM * R o_7&YIRHHM\\F˗k`V*^ g."63o E@,' o%o b̯xdey *sPC?E/_ro0޼bu\ < v<ss=!&5`K@Ă`2/G߸5 @ | _?1yW3(ɰ13>XG1V{A/tj=a`xM0c:Ki`^yY>+A_)/^D^@NrAɗYrm%*ix'A Q #(*~bWd:7 a8SMO-+86Y)`y2%nΦDrr9#++<77Xt I>X'P$3Hc 0=?H@fÿ D5F`kc74ac%! @Lx?U oYcPF(lnA0 ?}L>Xn0wYYdi@C_axh+VF^6`؄Dmv.hFFĄd6X3<XԀTpP g`0^<=:/#<З@37e?O lҊ L@?p `{E?00%yb]V,#'<K`BCXJ2< g rb\ zc`z/0~|ax=k1)1`` D`26]D`CoN01 0 [~`<Ǡ%AJ j1|΃{ 'q0z AU';`ɸ! Е)Ghÿן>npB)o`&JF0Z@X/H2<)!,PDɚݝYY b*--BZR@l?q#/,m u1>Av`auU>o/_/. J "\@A%x&@a$R `6,1Hϟ`98dR[2r ?>WtXԥ/&}T\ 2 =JFMkb^VfՊ!gm|!`Mޑᗍ= `🁍Ԉe?R '!x ?4!{ XpDE`#t# ab|C0`V hԌT"7)G@GRRlWPġG<)Ó DR8 }=11!`5ûwy (deY) Xp4XXU;L$ VdYbьt(e{֑C $rBՀ3 @f^@,4K f|LNouAebCA o߾~N??Ma\%A3PC (Pu  `{DcԨ ;w}>ׯLLLDEE!G㙀 ?}N>nNp XA ǃ20-iP~ 5A 4)x5úKؾ3s38*93&zG`Op%H$@9PA4ZP<l} H1|p=9V|ܽ{/$%++`Z\\LKKKihAkO`H|Nfgb`l0H/4,r P[ϥK?2P GV@8&8i33vvN-``Ǚ0\Ί J/_exÕ+_}=sHG2>@ȱY vGqYY93f4:93?ر 3gN>q R&@ 4R?RT `Ϡ=!sw߁Z;@6+L '{UDxt7z?P"%#KdT1~gd>]7tHDw|||1oCG܎2 fNnmwKNF>ۼysӇZBv3@5YTT )J`U]Y4jz'U_cDx4eEYe$y%8XË_^'g{˿_mf`|#@~|J<pu1d(PvUaeP`>Aa5_10ŔY@[?#D9X83Hc{t1 3~ t40|(Fgzn/ycbxr!Âytz>FTa0uspOwRcdĠ#?`vpra:0F&/??3|:j>#/ $3Pߑ' 200k7-ax> .O~0vzsps,ͭ%AKß?`& F`j9X_}(W7 ٘?xp(:ÄM On^16O *ÌmQF7O B3( 2| v`fa6N^>2H,e`'O//"?3axf'g2<&u { J 4crdçW+L$_47&&n9!^a ~%gYr \ 쬜`?'w  fseJ`3L-2v^eafpt'Q`}W`fddT`fZ).6~` J2q3/?~?Q߁ILCe&7Ȇ߻2uP-TN}.",WMV2 gggZ ₦ | jp}pm_&@o?8dsׯ <" F KwU0:22Hd(T{GspxOIATĔK?#;A_=d?8%)0yq8ќ :<+`S/`_? ~1ڋ  ܆ <@a 4t(y0;ADa ރ L> _|(Tgx>ß_>|piۏcARTARD۷o o=!q_`7аv2L^~rg B̐,jv\|0?dxW^iŧ> Ïo/<+>1c>.-~yptז3J1d0K{PDSqe6ϟ^' y}3/MVw-no_]k"cHUcd`eF<01dacd3I k t0qUX _(ςc؇Va?phFדg>zlxG?(Z×O,ldU<<ɠi + @(s c z6`(J ]] '1hf1psK3(ě T jV0RGBޜ Ll=C<  ?<l[^f; *z ʦ@s"4 51q e`f*F`!~po9CZ?9!1q 3®AAc??2ܺ3Z3H vP^"xw->a``1kjơ 8IKIF`Wa`?J1 + +}'718[3&i~n^Q `+` Џ_|wP:/00@ܿ&J^)XdH 0dbD;\ j! j\afDy@CL<: ~C@U_B/~d0tV`R2py LbNJ* u| p6 a&}( %nà*np]{g1t V~3"ǫ/ay'   , N@, h&Ab4% ,%-yDx%"JBPXڱ3 v2/3ý~: bWϥy%p^(Ơl;CPXs2+I\(Y M$3ؙ}VFTyt * 9-?>1(0|p+`3X W.| `c /aiTΠ%k *'+$4+<Ab0>Ŋ 9O`,*``un~ l']gekĄ< Nw <:ܡ۵V#``b';~>('<ـ2 z)C@ I{=`_Ǡ#kV#̠g0PcQ=çX6lgx֡Yp+ G67 g8t6) rzqA,C+vAR2 Fr*0ee3<|JlOq,?;+ vxl\M6'ހl >10g?jB_ 6Ȩ3pn( eͅ&A0 N6* 'P}"P l1,\qG0zNPD Ą94g㧷wv/z!ɼAÅ 6(fb6$ Û5ہlS<̡OJyꤥ N NwؘG`z?`-S6X< ١4;tCJ')5K_j29 ë-BhE B,6IVW(E P i >3+8Ld}X3ɯ@;ƶ /xz^`4 pd7 LS:>_ח\S~_|/a(/֟A(TT 2p9 #c''&}jF 6 7ٶ2l{ X0p2q3hcf|f'~C3g~3# }k)D5IENDB`Ext/Images_Client_HighRes/C47_KPackage.png0000664000000000000000000000646710132777544017252 0ustar rootrootPNG  IHDR00WgAMA7tEXtSoftwareAdobe ImageReadyqe< IDATxb?P0@ y( :{M2מ  I1;L!M.ͩ2\ln N냹в&_ijEYZJ__99^/ɦfbFZy e/Y̊ljJL "@a` Wӗ=s>>jpsL`I1ÿcO>~񵗛|ç4%@ŏL̰dWhw ? d<VS 9Hfd-C>ʽ_SֽowR^ 7 4[ZȈxf L__޷/\->FAnL01 0{prB2;_|Vu`%g{2Y(30|L?! O>d`1g` : daz@2#j?禝} 6!0 9mw7?20\c 3|Π- -/'.̲<͊p<+"V@bJj_0ٻ?^ɻr΍!D s|R_f;W1\{ɿ _Gm  RJ J < #Gi6H0cgw2|:}ۇ}n趧'aͭD-5l}TyJrg{=XF^ <Vl @c$/&<`<} Lb?qik@#_26 1y?Ojחag<(ÿ_@eoϟ2ܼeIE1`z?0cDK@/ϨrTkl b1p˯ ?~f t+J^3ܼATJANMA^]APFEZJ;//zkm?awʢ7o|} X,7Ъ ;103߿c 0ygd ,pg44eUXN`.^=a|E ]ĥY9 r W. F``b??ـNdaa"4U-[0ieyu % VH?.&/Y^3Y}cgUn?dWe`dg_;lf, H1(1Kp1\?LP+vY`?P(p$oQ'qyQ^3ٶ;g_vh UDtY< Iz /_|c81Õo^ Fffl*@h00c`| 9JQ&`Y=7? .ṣ]:V/@`xu? d8w5_~~+ B L> ^cï/03|b``f`LV ?ýwxV@_ @Dz8e`&`*7 '2= Ly+L0a`b?o~ %- ("40=&5F&P6_ & eb\M{Ǥ]Xt~d8q5;߁%_vv`2fhfV!mUI6>>` 0)QA 47Mw (4,+_p?=XCLOGd' X/Da Rw1^ [/IVF zBl JJ`\(EVxc OI!fHVG0FTW"9??69X3BÛ@}?ztD[1Q-Ke+U cQ>9`- fdxr]FVF`/ 9 +,,y XHv᎗3@T-դ,EuL>X11''1P ZbiV6n %g c[-y{Yeq#!nqf`fb#eN=yzӻw*9hx'8Z@n2qXX+=(**g.iΦ( &{N2\ۍ{woC~hbs+@QX27'?{vwnP] яs?b Zz M^R sClA~ϡj3ln zx9yAc:d Čas+@16'悃sIENDB`Ext/Images_Client_HighRes/C23_Icons.png0000664000000000000000000000463510131260446016627 0ustar rootrootPNG  IHDR00WgAMA7tEXtSoftwareAdobe ImageReadyqe< /IDATxb?P8=@C4=@C4=@,`_02f`dfπ7ţ w0@ @`dbW\o2PbHCb?AC?L-X?av1 %0,U0Ҿ/f]%ıPL\6{2@w![D_qv} "3_DY>1qp0?~|cxOA@A PGv,GA?$f +@( ri9ß?5Ö @w?05 •Pc9`'9 <(0|ׯ_@ 1|Q<-<Hr,K V RA a]"i 2;4jnm9Uq*%ډ54H^:-A=r< <CH1\?0cF]bA.sa~ۗ L JBL8Y,ĕޱ:Ǡ3rfdt2;}S~|* "WFtc t bĂ!1'Wm`y!ؘ*`@c/EIfȥZ `DD( * lo`5Ȍ,ǰ?,)U@&!&W.1(~ּL\l}!.9=b–2 eV>@p{I PQ802}z`je/$ H&ÃVǑQ"2r,Cc X Qx ؀V},Hlz $K?f鄜L4XU۠@1~C8crh7bENv59h51@ w+@!\+H.O /r?@ Pc*\޾zRo_3/~tπ%԰50 ZSHi Pb?"U2`Xy8] ?5W ;_/a1OB@,:_ j j?%wakWhؚ(c@5?x  2"# Z+ dbRen<G-@IX2P;7,ؘ\UƐV'fFĀ%Y`i"haiVE+Fkk F | T}zʑbŕo0 h X,cOoo`?P~;/fds:4Ă4D$ Wb XD!y_,E%? o@ @(1 )Pt0 A1XbEѮ& Xjc-zp "b PЖ5>÷y7{O kMg@؋Q4y P[ LL͜aޝ@}ИǠN#v v9a Q>%3\+ h{ ?qy /(:T^?@07?WOSN1t!W_Sg[EI)V ^>QQA.a~nVIAeQ6Ev!6aVV&f_?=>b`a1c>3 xa`+Р!SPVmO+7vv&AQ1A>N.)A6&iAvq6I~6P 2q03r00m4С_oo= !age@̎/5,LJl\  .4ԁ ALZj  JzrҟRd&(|Q:]`1??|qq1#542 ȡh䂒ct%ٿ8 ,1yby9AIM_Ki ~OcZ0H3"BK, ŠPh B+x$yBNfbcfcbbb`&w?gvg{>3ymN $] ="A3R 'A4' 74;7+#+P X_}3:@__o=~ىIh((QZRBN + E1qa',,,#? L< L, ?bGPv DcO^q?e8P߀H37R-!:HR2gj$ *Jگ_ :?30d_WMz @d߿F5)@~l˼6=>+/ p)S@'QfFDt4ƀD ?:"+ϯ@7>8ۣ@#^~=럯,e,D (~ ^g!Z'fg5@ }F40Ty iwP!ç<(/__|_Yi+Q?g{@sBm u4, ǁB?fG k(#K_7 ?OGBxǛW??y/e 1.`47A+cw3EJiNdf&h(3B0!, 9X,"_gxp>0z02Ʌ n%2b{o ?y;8ta֝`|`_D +>Ml0D7R k'2|i??=,X1~~P_*qbb@W߾;8A5$#0=za͉n2$Z_8uR~#xXg^2{3L ;C XP<+з;Of,8@(CZC E`avɂ|@J-,RB l:yar '`ŵÝ~*}BU 8$A}S0{XG ]PLA<t'XL Vcʑ  ߮  ?>+0oOw(鼆N>zßX@Iĵ)TA<C`O8<ghfbfUbX r҂׳lX bۣ/OL c`ub@BK&x: 0X#- !xgo&1{ Pd`q&k??~? Tקo^+w` G:^fJCG&H229dЌZT`KB #23da8}ANAAKE >gXf@1xsW_?^@2\@_PQ bAO$6@ 2 V:R fb I/ |d'׋O[5bH_( `c{a%0.@\ %PL 6+ $3f`y۳' O9d 3|+2|ٮ@m <ˈbb *T5 0/ndJ1K,6&VVfbP_߁u/~?y >]X 񯷟~y'?]vc LBf&Lt\dĕ\ X5VNfv``6tXXC _`~e÷}~BG_} 0xl}tGh@iP}~!; y$=gZ J)3| о_?0(4 닯v@!0}G_o> _P$T"_А -2P.\ŝE}?|Q ?1: @MߠQ? '@2Z@lP˾EW$ߡDAH+gS`1'4 Ɂ4s$>@C~ h{ h{  / }kIENDB`Ext/Images_Client_HighRes/C28_Message.png0000664000000000000000000000735010130000322017122 0ustar rootrootPNG  IHDR00WgAMA7tEXtSoftwareAdobe ImageReadyqe<zIDATxb?P8=@`dddptttP222}ˇ޾}{7o^ @,,6p)((0$  >)U@G OJG' @F;S2H$hTW})"RrIpwsnf Y{2րWk]wv>}F ˁBs!NZd`e y ~R@L$#6%ba0(^ f 1iX$)!A T9YJqG![@ Nl%"@2&ȡ, L,L _?0, v_?"%pp@ _+O2~k ^f 1beb?>~[0LXPh_PQmAtCĂ\V^2f|{C?O6_, ,X~$P//O_30 +p3] ^a9AO艟FDB7?1ufғSX~e7 $(_`4 l_Hw+0AEC.200,˜ 6?8=-  )TҰ00d,azw;Ô )j _?b`- -!O3~w ,MAŀJƖAæssg `غ|;CѢZI]`DR6?0|" ;1dg84Þo^f`c's0>vdp`bxw%) ׯ`1cpַe+ѥ@] J?2,jƐe6ΰa6OJ jEbxu'!pYwO0I2e3x|O?ՌKT)@D O`8p(Ärn`~' ñ{g62,```1S4ASX1VW3Rҙ- YJ33g*'ñ'^a`dt6×6y TKGCLܺ9 D iEn{o9ǁV+*sG+],9ke/쒔5XEA{54CA>O#xnVd.f@Li47 (?`XɳL~rc_~6␉ݏW VXFat? ߁ %!x,_&p7;!1Pd=o2|A6Trş7 ,$@LĶYX_1q?pb ?_~fv(gy}~3n_3`;AV@w w~c!HԒa {l:`z| # v, RwŠppn ,&ùon: ņDĉR.*3e0bff0.0LxUK`ff "7QI <i{W0y'^02`ζa E,!\A]a% ߾`gbf3d8bCݣ 2h3111(`0*0l1@D|5;2Xd8l=C8& k:ÊO3zvAA n<2ùW{Tߚ Gf:M~*Pމ j F/* V" q }U ?D2>gpbWϰb,& *f *Tdmx%@,Td`HWEa.Ή [v3H8ca3Ok`תn1o`1jf`8cЙΠ(#@5-Y򃨠 Ҷ:M-e|/& ؁M `gVKN`Q)Ƞ!͐OZ+SI1n_d#0dw,᳗? `znpq1H3k1XEh381aa&/ %!"7bŸ~e`gqq`v'1Phv6Vp XÂ< *i@IA_l bs,W4b ȖV]*FC% (bQb5*Aɤqb'JD  ur&(<l1@/^0bPN6yyy@n(}g@t |um~~eqԑ3MZdu,M  4 R~ U'-- ##Ç- ƧO} hQ Ļ~ l`R@lZ@,-jU#nP@|np .&-PL&t05}6exIENDB`Ext/Images_Client_HighRes/C50_Folder_Tar.png0000664000000000000000000001203710126545336017600 0ustar rootrootPNG  IHDR00WgAMA7tEXtSoftwareAdobe ImageReadyqe<IDATxb?P0@FFF'ӭٳk>ף7o<ۯ@%bzdee[ZZ1|6/{ϟ?}8sҥw@( AyZ1Ϩq͔5u~Ç 7nЫ۷ozf/^p 3$gH<==UCBB/%%%rSO1ܾ}…oo߾y 3^p@% @Q5 jhhrRΠ nnϟp[n_~/_y͉SNMjDHHH8k/,,D߿1}3w_OիAn ~~:-YAW b PuO5b83HYeOz1mkyn3<} " 'h +\Fp h t;W%>3 c/n`dx UjL(QCJP)=ȥ!6b!]qI1L?RKñ0?Z%4x}s}]iYTlFрam r6=n@FxˠxGnh]A#h@0ư* ߐr83?0&"yeE8x30̠*/t/8 _WA/c 7_?1\00kW`14 @eBGQF+7]ߤe aH6O#i 9Di D= ɤ 걗mVAlt%)|&?a?Bj@@x;-8nZ+gƵ ~ C(gc>ȡ(~ P1ر99cAx/ģ qP̱= ן~AcϞ=yd=Hxo>gg!!\`&Ё5}r6vv"9?PG g< $1a/3|A1:~]P#>@Ŀ_O>| OL@ؘ@? Ae0BFXـi9_4>L( .zIqA1Xg~ h=9 聯?t84(!t qg1\ֳr C 0dG!;/@ à  hp 2|`.\|*R$o~XuPhe?10?=oFN~#vʮ PZIGCOh /VQ߁ɔ ؟/UQH&oty p?!'?7e4аo~^]zOWTļy wF3|f`Tpc`KW:@ہ1? 7,&~;g_45̕^]v@\A݇O?9FwX4.xv.5{ ex{c?5+~00)x0Wb+jBMN bRK^0Xpps2^>c?6 O~0 jc+N}8?YMIdIYC3|}A\3Hy1Hz0|6M^\tZY27)a% q_HSt<̣+` Ͼs }ako@{N 2r <  o1:ׯ ޽56.`NY4+/Ç^:P5K, H?`7g'L _}c gF`Ë7 ]~ m  >`SWrdw[_30G%#3f`da5ā:R@HN)>} m). O0 ?b%+E^Ǐ.<2P#G2|Oo`` ,t]X- A5|6|FFny&Г@~{ ,g; Qn`Iv-r gX$A1L,|~򙑁U3|w ǃ쁿r 610\[t` ,]zI`3[i@1NU. X<\ 8R y&Cc/EWyÇ_*+`@[P`_CRL?_qf ɩFPc-6Nm&-P(3@ǀZ @cnfx3í0J0pr3zm;qZ2xd @G]-f6o(í@20CZ.t$P`ÙY Tr_>[hN@NFo1y/0Y^}(r3|{rABAN H,)8Pa@i_c uQY$'/^1s\f6n`s4ffDQ[emnpi1` l|v-0pC~{,8@8AI?$sŁ}{k#@3pj.2N6::~]Q^>hI ɛ[v+ϡ2@Ab*3:€$Tir"6AKfv$ '!N`p ̵8ppd'ϯI <@z .=eWep ѿ,X{Hi-@ԓ1`?H x&Xp{,! 5hR!pBA}?c`ݛ >fepXF nmx˓'d4 %`:{ @<(<% q31\`kivA2X1 3:@ZQ`cÏ'a АjDpF! ņ 3u3'}5ӗ ٹ [o! G`tȻy{!yo?dİpP300Df0x X}eت ؃n~'2sw߁Uw@~/ ~d- _qk{`ϭU^^]wuuqI=km&e=%IEq`z*oH%!PyT='o18tʥ ߋ1\tcx^Ͽ>#@G_3|{ _Whrze͑] 0ЗvВಓQ42Q3RfU` U I>7Sǯ2\9t?|qϿ[O^1PG|:RM"ئ^Fh03IIjxHIky9=dQWa5RfPcG^p֋W|r{?/`hz G#@_HKD7@adB`1 ^~̟t ks((ʈo_=7T=I: BӬXbh̀DXWО3h u?:XۡgUIENDB`Ext/Images_Client_HighRes/C04_Klipper.png0000664000000000000000000000626012666316724017175 0ustar rootrootPNG  IHDR00W wIDAThy\}?9sAB$('LHI '8IAA  $ ;@(*s HH+-SsfwVjHQW~fݿr_S^nȑ# FVI &on?φ ֢= p < a: :KUd'I)\AR\YIuH!I+\),9М|_c=vb ,H?ޖJ}n</BD*c$L =L ]p]LHAz.ȄđsFR 4=7oϖy&;/$v}Ygv 8:ENvO8vO8=`OL~=׬6t?\ uV8LKAOnfשgk;9AgdxEN KlCn= j*Va}Xv1 4ܤj9P>ߏͅ| @kzP&R MC PhN7|ف:w4L"j@R[?8?\LtgtJLkm7s6,h'VJ!0Eo=_۟!㛟E_y!82242z<,L$TJtn8N~qՄZI j{fO|F .{}j\`0 nʃv~pB52!:p\ g-Ҩ90NͧL1׭%GD2 vq;?AA8d&~(`IT6*5)>&}2g ӳW AžeL#/p*bFŤvCf .^|rlkas+P[+dB+ԲV(*DAJk0cR uTާ9AHPF=0..v.u\/=t]].²0Y @h-a.#82۰%6&LU74C;rG8⥙f\+o$"?dft$SBa\5&Jm(u?hx DziMV|ɘ1X1̇}&xWwf[$롅Hu ʦe4Pr6y+i탎BO<oqEM8ZR`ht [ڨg#V@Ád>B(d&%V99eS?ӵI .XdBy{TSi0W6ʸX=R  l♗RqS77^& :;%@R#Q#"q0t& *k6 RF6 ·k/O:ݰ=?-]}PReqJ\K fc 0MM&8h[y[؃e7|jN8kK$t--HBFOY*X\@%lP#4R>kt',-ɷaOZVl;7؋.?,4l%O `\#QT#sbcIa&Ko0zҵGW] rz\7#ϻPoXYjr @cɌVA'ʸW㕑?Qr Qk,[><%(c }0~ϰ=/L-‘B$XYW5M-l.ʶfU:Z9{z:vɟ8.J[/e6lZ "לG-۾GTVtu0}JLFfT` mnO¡#bu$W՝2h\15b~)O}ĠiACуA[* Z?0 @@sTANJ2ÿ g ÝW_9tM{)[=W1'7l"0?MDD{xZ4+b-(tG^Gf&% pN6R"|[s~^CjVf-v.dE&ìDyf#cn?`}9ן~2q0<~TIʼ-O_2|b0Ud0Q`g+t0󏿁/0?~X1?x| dFLo'0~awpED;i:)70?`f{V`,|zן `}헟 v1 ^}Y $"1/  ukŧ P) P<ۆu_QeX&ưᢾ $" p@73 L., ,@Gl~c/P \|o  b" bx Nw_f8rob 6^xp9 ğ jM|_7F o0,{+#m`HK p `oX*AXcPz?cADX7 ofdo?2Ġ(ưgǭ_ V"s_?le @7%=`Д{pkV0E ALIX lP/00+.Vpy,MP4"& %n2~Xp1[ /2p ~gص9û#7o0vWa @'Tzީ \ 7^yqymJ3, p0 ـp0p3) ’UeԐV\ ."A5, + k402?3`-(s< #xVyzHn('WyVwc$lgxxTWv @ A`SXW00z:8{F; &S1\ùG[vbP[D1lmq:IJ62)}A۞aY31?`rd$akgo ?eq=Å??õǀg?P ~j3: @ĴF$MdV&oz!}LcJ_W2zk x~dxp%ɫ_ӟ3:gPfmVa@ۜf0NַUe=r"Cg Ͼ0HnfcxG</ ׿ }c8wٿs^}K7[sw14AE%X<@z""̳,2y}`pY / jNw^0?}O[phSh} mۼT4DJؑdqVِgjRASAUA]O Oa8~O~ax>ó7eShH?:=:/B w)IQq[73v헿^zՏ P@}M =W]JȘtg-7;>0_>@ PG( i| r<҅bh94M:;1 r<kC@fXi+!53R4=@C 2ƁEZIENDB`Ext/Images_Client_HighRes/C57_View_Text.png0000664000000000000000000000450410133443324017474 0ustar rootrootPNG  IHDR00WgAMA7tEXtSoftwareAdobe ImageReadyqe<IDATxb?P0@ yА@ &00q pև Y=  ܿ >.Z 12f!0?( ?$y( cǀj$(j#32rC7]@!Kl}J?Ă?(&C$Pal8._pw* Le` I! 58#!bTqdrB 6 ح0W r!Xېp!"J !,Cvq3Q""08jV@ \Ă?##? 30 i?Z~@bGS#yQpi-c Pbon2|yh V6V>mR߿gP>~P#qA 쐒z+ 3"i"iiITCOYY0`%DR$ď88b5̐<-J¥ '@j13 J&Ud`9 %U a^".BČP) q|axHi^*􏔄k=aHrddDx R"*)fh:z $T#%CL @H`ƚA̾&vvPOi 1YXXc?`7obhnnG~12VB-0jO;7@+?~33#G@,51++;J=/a,@@CPcRqjZ=@$ f@ϟ ښ %$iX0;/њ<L,8*hp2bbbҪDdazCC䁿$R)@9RPlXB2 (Z j 0b&!+)Gha'"CJ)iJ۞G0<q<#̉4BPH51@Ud sIπ%ai61X9#::ȥ@<`7oJ1 j(3!լ bҥ +WR^nR#?p,*Ц"F }c8wJEO #LL>1\p #.iXSbRM `D0r --uhe?`GԀVWWȪѺ2/!*>Ā@>;lhףo O[e>q1Oz)2<GuF(4, Y:J̀ԟb PbY^ܨC!G@A@u/$l2iG @x `gS_[O bBmz(L4-=9 U|i (R*`$0KXq/5!? @C4=@C+ͶIENDB`Ext/Images_Client_HighRes/C17_CDROM_Unmount.png0000664000000000000000000000773210127240552020152 0ustar rootrootPNG  IHDR00WgAMA7tEXtSoftwareAdobe ImageReadyqe<lIDATxb?P8=@CFFF ZOǠ?XY@i&?=g`}?G! EX?߿G01sr 3p331㇟ |g;Ï6t͛'ʾD,?98لtld5Ź88X@=躯 _ex;Ý;.{p3wocϟ/ݽ;(PWb=r;@ ei?kb`wuWb PbPSb:/0= P= 0bXY=̰cC5kn1yV߻7πZ~" Ec)Q!4\H蠟?! 1z3|< ,,bw3ÒoK>yp|r;@`QRN.D]Xupt;&7$@d#޽ Äs O/ E .A?{*kɑ @v87cܜG-՜ |fhh8pʳ?`P$b@Xv rU62X[KDR@</ҠyCm+}zM;@=Ą/nTXa`j" ,E !(̓2-(si(AaM!-PUc '/-,^%g t/67L8X!G1YA9 'P<!̈YRRa+0eQP:I @L82 r jdC d?PORqܟ?30H)J0j0pZʆ&J13[ {_& 9i<cÒ&#HI P>y+; D-ØXѓ@1a }9` uTb8?C`q0#C' " Z lb@cđ @L/[Qڀ2#f?"|&7/çz0&/@fǚr b@A%1̽Ă֪dG8HE:Q/OQ5$arB@XR#ſ|V ϼ &XTA\W<<_ܽ %Mb=fV[`Ì Qs}3vK =ay0_gO009 ǂBl%W@q30pS;3c*Z \`C%?%41R#" E@y@@e2Br#p6&HZtbo "&hdPTp?x7 @0GM^ Ps01X@,m FAvfH`hPAFDuu=z?6lfafo o^1쟁J1&.^`-@RĄnvvfp)ALuRx~ (䁎Q{jٖ-OO+p2QX Yn5UX0} J6{?`G32Q8 0MZq@uPQXAFE x]ffas''qnn&OBFGYI(HQ8@y~GLP@ MO80VWk3l" ?)%@'8ɱ'R]C(շ/?Zu j7b{F'h5xG`[VpQ *m̄ t<0s_ex$H??] )Ij?yӇo@G4@I?~tA\lzS`},J9`i/?0f&'0pC/s#_?2}}!IB?_/|XYg0Q?  R&|p_=򔁅ҞT0گUe!4!\``` $i. ueޚz >}f@ǫ;z*PRa¢; rhDX: !\ mv0 *}poC+P $@ߟ?|0p"z FJ|#oj] % @,,ɰ9R}ݻw&b9l 07π*m`Oe`f@v<; BTL oy{:P4  Ջ?>}:[\g:\?OX(wzՖ {ڙQ޷> O >篐gbO~f8:sՋ39e7|ڄgͅnBǎ5~ͰqIW/{p)e -B pY[O>~k~>zrߧOGj/^zÓ_ '%БF&"TV6d8~>ë믽~}4{[iBL2}8wi)×o(~ 잿ہ%7?b??tI d '~Y._xuW>p( '8/GAn b@)*)",R&( # & .2AM{ # ǀؠ&lBu$ٹã|ʫWOUNg\d34΃|b5?cL,p.$ | ca?1ܹa οE}{|l.@C "e:.$'g&%Ƞ! ,8CDž`SLq?m;=_{/oТD>`@@3K J Z.||v*|lB RR 2 BZ2 bY_gW1o~p۷'.נ iWybfhlyyUMt98XX@s0쌌̠iǯ>?/_>!дoҙzG@U3R ႊs 6A_@_H ?X愎ٰAό;3_А_`|WCIENDB`Ext/Images_Client_HighRes/C61_Services.png0000664000000000000000000000646510126474246017355 0ustar rootrootPNG  IHDR00WgAMA7tEXtSoftwareAdobe ImageReadyqe< IDATxb?P0@FFFA'C _j@ HB+008hlY R ]D,f`X3yD@)c f]Dk Zn Lf,, by8JaH hm-b j&6#RL޿WHh߽ccfqՄx k I0\>t@=a/׌슏S`1*<8T!2!ct#LF`|y1@3C]`N&TIQ{2.? FPFQ&4&Y103Kw@ǀJm!H<'³, F@7|?á :2\n@ٝO ju10ą20* )δfc`H1c]h !+`=x _q1l=pjݽ߇I3@| ``6čm4R!v }FTio@þ3 gz%?]SXO j1.z4gX\TI*˅!BOCy`zEMj?]0d8Ќ J2pE3@X^~>IIs l_K)֧b89 A u`0 RZ ( i17G6u-!C]Hے"tL` R7E&1g`D!m!r7 2&d8|I_- ;%$ui_h@IW7oi+&}4h = /Kv!`s-.ff"K7?1({0(;KAK><@$y`#00XC{łxbh4+00[%N}a !(UHF~CL2 <Tl-!!) 4'0` '؞1|y &o`{;?Q )& BO De0~@d@%W/3l~? J;;JF`듙Ⅻ@ceA;=@D{`O !K>HʏQ(+o3ܘq ~2<?i~&7 ?(6~#@AEAf&W e 0(xE@!53$s2-gsˉ 3\:;҆?ᯮߔ(z flXBF*L R:u/^4~$hk . L:lͿ+` tI 3z=b/4a3N=&9` @72 00 k.0NdAjc <l, !si KҢ`گ ,bVy j߂6Mq> %7bXSe`#!M f"[A1wm/&`h"w3̼N5| "Sz0~>vկO b4`sд@҉m[)&U ?hYï@=dPQ 5DT4TAC'QRTV_0@T3H5M}hVH \a5 Ѐ2b{ `x@l$ ?P74p.@fL@zhfLRBS0a>h#4pDR+eIENDB`Ext/Images_Client_HighRes/C11_Camera.png0000664000000000000000000000602610127241024016731 0ustar rootrootPNG  IHDR00WgAMA7tEXtSoftwareAdobe ImageReadyqe< IDATxb?P0@ yА@ yА@ yА@8O7''!/_~x7o^xq&o@w <@ C$? 1 lQQnn6?Az>p;/_=k=;;g&&PpM:& _>8qb}o @ppr62Rd;"߿@ 3 (bH ϟ?` 9&z̄f:97n<|ٚs֬ } $E  ߿bA-a333pYϟ30 3|X)PppcW踿 ?~| 2 /3.fw Zv& ޽G )&`RW ۷dC0ՂBa g/a7gha c037af8~84óg^z $`zĠ#}&C_F^q-&fV)) `f޿ (O琤Bh %,, ^=gz3jvw: Έ3\~a޽jo`ppg;ëN]#*Y^~g`x,>a`޼ _bNba@Ji1Ll2|;!+'Pݼy3Å I &STRfxá[X3| ߟGyv,, ``(Je#QXAQJ! ''k ǀ򘔨 ï/0 @ςJ Lb`'#2@P,'ʕΉAWcG{t e c`gg7eR~>~}-~2))0q1ACӌ >~{=*?4 ̐&$2!Y8Ax~ Ta M=v3ܾ ""I 9 @ϰK)~W~. '0ɃbV .ML,><T:( BbMAHH-wG^վG'DEŀXXC95JP=!'' @;tbDac.A:7F K"n /0b)=nϟU  I\ 0~7JȃB LZWuȧ3ÇIHH \"'%&&6>/_=ɇHD@˗:stÇ7@L 03I1\rXz7>}x `k@0U< ='#d@,$_1HJ -afF-U 00+0ٽހլ[!#3 ?+ 0v=c@v?...pi_ B"gf2xhc)ip )mQXPpppC=ƈKĄL 9Ff1ϟ?Zp{I_A|@Uhi822` &J*2y =@O`~P&.. />HԐD؃ (Pg..nopZFY **j%E ֋߁ =M P(s+7 bR)iZ;+߾}Vbi]a] ߁)/^> N>"" n 30 -^hmbTzR^1ԀjڻwnKAGG<0ˁ2 WNMM߿HFvFw+@]JP2abFW`BE)mw0|VD߿}!W?R#o``c (nNC(XEP} 0$߿K(%#cYYPS'$pӃo@ϯBI=*n< %_2 K3t4ǠN =?? ?~` 'q`u@Qܜϲ /_:'f/Ѡ ⠒aP2e^lٓ@ @Q<i0ll" Ν[ʐ2?rt]$FG!|@ԀIȑ}@opOz|,x`hh 6 &⊉O60n#?$AɁ?|x˰sV``m nBM 4.7(Á!0b ;B  ǎf Ɔ . RA4K`S ,RMXrAf@pk]g4FF"Ȱ" cA6j 2?? 06Ԟ2s TkYG$;P>}t[ XI=k.@lTcPoϟ?| =صk7˗sqqr ($ #r 3e&.ׯ5@=qf#*MP  9:Rb# 5( @51*Z^4*Qo8ghϑА@ yА@ yPrIENDB`Ext/Images_Client_HighRes/C32_FSView.png0000664000000000000000000000512310133310422016700 0ustar rootrootPNG  IHDR00WgAMA7tEXtSoftwareAdobe ImageReadyqe< IDATxb?P8=@C4=@C4=@C񱼼\yl, L id#Q0Ǣ v"n S@X=\rՖR ?c Te@A@?afApwҗ+#; t+[[Hp`8RP"`5H`5C6E=YH`1P$dm { z&o|oa#,aq VG"yA4ϡ ++3'3Pِ @X=C;2230 D0.#42aK'pWO @ÙF&/2qc :QQ\GR(rde5%~݄ Vb 6321RXޡ3 ?$/`y NN){@Cs#R`eee02b`daA$k^fHHHg7?us8 p$!Fp1k˖1|.+cz$#0(brCУ3@.& rZ^~c`bg9{NNTHB3 Y 1 - -t7 C_Hg@A 0[K00pr10K6@ @Gڷ@+3 I{ 0 4ؐaD)bP A A dQJ= `l7G NNQ mƿz'Rl21Cė%>;CPGDr(#ԡ$ @v6RQ RxRb yXˀTCi9@g:?<b3G$1=$le# o$_HP6C"y )›_$dOha``d\(fx}?xB@lJ`&& ?RRe4ρn;Xp00B2`(hv%p%!]a2й  "" _`7@ˁ쟿)߁O CRXA4?b _`FM 1`23O?~A4 $Y@D^`*ACKG)@88 (0: G oH,`£i# Ŗ;J!pwqCΥQa 0xߡDT{.F6UCMČٗ}}RMJڶui(ߟ.BOꝜee1;;С @4+fg::L$`! p-3ge .b!@{y92hkT ` rQ `y ? qqQNN. r@|(\v߿2 ,[2?F_~3 Ŀٿ 0Q@>@ 2=/ 0311p3 bvln 0n}۷`> -:n4 DQfdҬ`1?#T%̠ČDW Lb."=߾b'<0~304v٘!|V @ L LAi/FÛ O}g;$''8 f@)68틏?~|& BKGGV@n: Bsh$H qF'/+'F.o? 0,(@W^<+ " ;HBCbVdC¬ Wv/߁Al NBo߾_~LF`1QAi)V7~˃xhRbzъ?@'3cū $$"(}Ev@1P7~OTTA^hϏ:=Ayl@,Yo;//7?$z)f_|/ .44ŀ^ =V&'XlPGAApyZ`1ӏ ߿ (qn`=5 IV?~>AbX~T 3,OɎ 8bxk`Hcx l;rr\||B@8%1X>UT0(++ρH*2Ybon.A3r}  Xdx P+ 0DX$%Aez R#H`8}H N _~B2%" yP6#8e0 X @%$BgTj;o߾a@m.Jʡ$->Xƌ3 51?HM9xlC||=#O>5޾,faE4Xac`fx`96`-d@5, </ͧRPFB@_~@FVc"3 j=/ۙg@ a6HH?#Ͼ_ /V`H_$ =p>|Ts+J}6ۘag8A4sY o3>`I',,,! 9x_? mAPHAE~CJlH0;cؙ6 I 35;-7#D:V{L *̍_2K2|Xq0h+=fX&fP  V< M&~2ϟ ?DŘ2=#'+ qqq0 B6X u`7OK$o< 7Of`>s㋿ f)a?`/02q2o |_1 / -  p!`GX@Pf`RdYm~?~ Ң%@6F`)+ eZ˺ sjp3|~pw< v^1MmE6q~vYA` Loֳ0Yc x5Ahjfx9I T{r!'!b a ocNrfГ @ -e8,ߟ'3=t!ED/#; .pM`?//uwYLOph?{Ǐ|ͷ ?8{)0 {eȲXC7_C^`H,!б?? ΁)a [wd0`eTk; r oϟ񓟯_lg}ׯxK`Iu ~9@azs }Kkf^`q L\꠴ Rop3uTA_F72\=AMYO =J~@֛>{O0 d0|6C'XXFgvղ#ç? "l ,l`x? 8L`@V _dxz}YGP|E B u?< |89X)AYd " ܄/P; {} ."kN7Ew IY3|TQexvUPPP +@ACeב@TdʢܼY B\B`w /|% +0?2||=ñ.ݸn hǠ- X_rJ7nff8?8ჴ@G _ ޿VLNha ;O0?| _âݸZ[0CJ2gee燷o_8zt}Gz vb|W+gw@;Kl$Ā-3'3~AA|cv'n{@͉_2~rATR1f``ac9[XH). /(( l[p}7Yœ߽kך<A.s!o0xEF AK`;?`<#0jOO~ל<| bR _>}N ؞yOV Zz,r" B@v'#3;022APDKKSٳ={Իg$2@pq?{ͫ gUd16a063 􈎩%×Ξ9x50 6F6` Ti+*f!IEaqI`?Ç7XIIV۔AUALJA\R౶#}w6~i_0 3+oݺp޳ fF7ϟ1s=zt `ǃAE]5]l\M k619uآD1 j:& S4L,lBS4-@[` '0pظ o{ FjjNKpqT߿q5b@ `g{S0( pU`XJK3(l/C_axtlҊ <2`#o_3ۚ0`LJX{+D`Tzb4*,~~~LLL9gwÇ7o o?* (3pY?( (+dP/g|+< /'s! -9 . ^`G YE ޿~_6`ڟ]P <:铴7Eg/ߜ7SScF?uV8Tmq@opzf00a7~1>pE>O'". @Co׏o f l[ ٿ?P>% jii1`RԬ/==fÛ_%m؁I_ȠP>c1q Y0H `b`n`'4#`A;7%0Kv`^ <(!*AXCXAR`/ G\`8vShߘ ٣<`lp='}qϠq?aPPZUavBtUde݇ ag0Qfa7$|| " -6 ! B%xr$fذC/p0 u`2vf9Y 5!=;1/ܹ/^=Ν˷r8=ujsKRL)t_sPDOaR5v# ɔСPƠP;0v$b ǂz]çO_3z޸qˍ_>{Ƿߠ$@ЦBm~{މU$VsG7 #~ȼ3#x.dJX}+f=Ϥ)'' t{ן0}'~>zW/9 WO^yſ_&|ޡ=[A3=%48Θ_NJ4(@bLlӳ2Syϗ/{ `g_?C֟-ԏPG ;CA> D#4AB]0hNvFp$N2Yy?Y :Oh9;T & @:L`O(e[;ip##dWD# e8|Ú^>3÷)6/޽){10NB`:80#uW_2ǭV߾\/``$.Ą4XX:-My}.Ï/7X?10`^υD ~2ـ<kdCc~20x9 ox8tްg @/Z&/Ne.'O9ӗ33 #Q'ï@&hg \f*00C dGO3 x'-B9PIZa֧ ?_g"{I: ?f(4sN!f [>`xv&DI&2 x=۝O]"*R P4zNi=Z`2CD$GSlZp 7 bylC0}yk1Q~I:t0 @R 2egbHd!,]ZŠprd 'K00zQ58@3嚧!% LAOÛz d-Z 쓈> jz?ҜmYo67 fxS1Ԭf?CqtؑoO;'v#@Pǰ%K:AA A~_UZUgdה`ج-J5<ư΁K*"f}}ìo/ss28x#2m5R9(3-VVr ``sg`,6&/pCK N ˦rxCXpG`Wؚ +_T ? 5XaiG 3 })`}u؎_ysf3<0V>YX"Қ s$ _eH+xGԎ <= T/H"d11y1(810y3<|h<0?1|{a׿:& IJ`| HMdNmf⑳a\OQMSdzưw }gF  #@B v`r`8u2îsAtg R<`*`adp']7Aa`~ÿ g=d0c Ӏj?DJ5e)0(27+ >aXч sqaSzV[7Q`&m+@zۀI_]^Sg%l ^z+T 1ВePe8%!RT@s?~ѣ'N XYYRSSc ~M2jr4 MMM"@$BBB -C#A#ƌ_~10P &?2prr2fggbO88 81rf K Z{W 7^fHeD32+2HKK3S k]90?0<|!v/i! fG b Q1b L@f02yx9׋!)%{Ă~K\!ANedPA AC=u1 ?<\CA~21^&F,I z9 *BL ?~A s߿P8Fs_ @_P=6x@Ä5`VAXw \}v8 ?0r(F &7 x+.fpĂ`fPKFs(!$3C# 4,)"_‘uRT>3x?T c?4&1B@/nkGJ6;ɑ`{H$r?B?[{ !#9_DiR%7_"(!?G߿6$8(@0|%@oH 0 ܑ, ?/_dx۷аD@PP t777" 0h:  9 $eVg@Pl<Af=zߟ4LÇ߀?ռo߾y Mf A+;1hs^0*D `nwMf$Н(#2hs c$+1kEQr)Q'Ud,RJOvVXՐ+Hu4na}%wP{@ ! 87Py@-,,"m@x l&&& Cݻ$Jd0J+sssJ`%E===K.icP=0 2 ʨ 'b T=  b$f''r`F??h:LX 3?`Yի:Eh%(xw N3hA>'IENDB`Ext/Images_Client_HighRes/C63_Feather.png0000664000000000000000000000415312505022674017137 0ustar rootrootPNG  IHDR00WbKGD IDAThՙ{LTg9gaP-׺b]Ƥnlt^"FEFW7PGXJD7Yo vuݰmIfc5K]׍U*9?e@&gΙ0| \NmP42wq\Zz4 ~i~²ںIIAۇi>x۶lР xMQLt rFmۂlN*;.o%۲WI =r ǏǏR۷:{%",Ξ\/޽ 80 ""^,d,G֦V6HJʱmOu/6ofDb"H,P ^z&6\&O8HTBj_#p{{(){nQ5oRW+W(ٺ鹹̓oݻ[|3Q5g0xpZv gq1S֮ڐC/ʕnHŒDIH {QQqq?usǏ3!#xTI ?ϣU ի=cˏͱc\--eҥ7de U.@I pxPBݸver-jde UJ$?9Tqq0%$ mN'mۆ2M&ΟlBWYbz[,L@[L=0i`q enwUyyPVTR~"ܻy|5Jbegӹ_?O |"iigUA&RX6RS?C\4C3-Zpv6]^qLJMpvGs͆,˖=u&|")11G^~q7(\}l!7xs`<MG>)+364\3ƸPe^W[kܸa|)^onV"uG;\M_<əO?%~4FӹB޼:A2O2q"JN.q8+.BӌMI_Ḷ,_~@څ$'#$uwv(ĉ1v @xl샖b֭]̌ :MnGI׮=u) Y [oٷO7uetꄻw9Oc3''@44ie*ڶ8I@*-ֵpq8D"`χ&234M{-(ڵKP/&C,QwIz`cN4ߏ z"˖ZIzz7Iȅ0D]g ҚVWMdڴ3$3ynW6a$Q[VD`s~> .m ^gwð$1l7! uuD*Us@i)֬n %-mܹKK?)P<& 6''o@-2!im@d P`EDmDԩkKF 3pd#zPPJG ~LH`0\0$t0Q(}k4IENDB`Ext/Images_Client_HighRes/C46_Help.png0000664000000000000000000001106610133443072016445 0ustar rootrootPNG  IHDR00WgAMA7tEXtSoftwareAdobe ImageReadyqe<IDATxb?P8=@CFY% 93b?@.r `~π Lemb/ 7?(3(2WaߟhVV=N>fAA^N. ~aȗO_>߾zb-3JAu@@GgC,C_AIAW_AQA4!/@OO_>~GWn3gr ï8Xc dEX~=+(X>|p!g`E6!pC~ S\T I.0ǃ0pc+IJ  LLyO6x3+?/'d/~1 3e`'=;Xy:NfɉNep3I>~g(CC~+3{| ;pDx pXebl$xPil"DJbX@?dX63iCj&  ocd&(_0A֑]_ `R 0jW~#m&_gUpI)Aۯx03 2111p5'2Ͼ]r@X:H1)2rpP> _=񋁕_A q`H pu$ 71$R<0A` ֺ 0)Nav@___倅 ,((2@q3@a6~P6$x>}&,;VZ@cBTAVN!C4Xga35#ANcTy,yaŸ/#?>Y/5j̹ĂVH Pʹ48/4t | &mi\ +7!$T_xS/0i@ JF! n>Ȯo8%$XxY|jbA˼z̜Ҋr2 _1180|(_`&agDP RbT6-4@E-#X#<({ !'}d'j_o>aXs;էFay?ro4A!_a8v!01pՃc _~BjkXނ%O~wz] @w5Sv /`_29!ɖX11E?h$ ?}XCyׯ yR JZ̠=cxH@vl[q,Amid'Z'.bffЕbдfp2T6yRppr0=o R") 6P eсfN`:dbFv2@gbnP>( '}˰oW-6mIQJ$"+ΰN:_|< >a(y ,@t<(0 Pvd'Z&773a/Ƴ_nH0X(2q1mfp;v%66vϾ3N- 8o߁+ `vC+C*Pr5*C33L'?#ʠ$ 0,l < _5?>~\c: - YE?97ʰ * &)P?{Ň3{]@9NVF_Aaw |aX{ yx83<} |b&#"vA7n$c @`dg`8pk_`106A1J:_ L@}&:\/z?0?pO 04;YX16O @Lhg`gHT"''xZ(Y ( ;0ɀq%N ~f H=d'Zkҟ|Xo039-B ҵ[LF,L @K~ D:G* +d %dz>032p3Ar.O`ןp_O~G)PCWrXrB >5"; `013/{׏_80s>x Y01 8C >0\fl؄,~ Hy`lf`g?=U*ǀd'ZT1˫ ҂@= xg'_kMZ WWk23#RnGqpX3yTd'ڰ!ȀzXuʋr@/j3hHaE24QaK:3ɡ$C$Ok^Vv.v@̼+2Œp8۫/r"+ @J 3l$/7_ mBlĀBKd (CPT $ޣWkT5W302I1ps@od93#4E#+7vhVC)mЋP1OQ`]p f0l}4÷O_88X4d!Cȡ?~3bT|6@ge8zT~Qy'%i]ݛO}L3$v,_^>mAcA]N "{foyл#?6.O a{ X00Q Fn`ȳs 1 ?nf}cj~K`%6Pc;ЧK~MpnD Jx!]"A ?.&9?O_K\k@S HD{ (R_ mN^YHs@A#]i)Ж{@@| hYP7h=@C~@ yА@T΁IENDB`Ext/Images_Client_HighRes/C24_Connect_Established.png0000664000000000000000000001053710133443124021451 0ustar rootrootPNG  IHDR00WgAMA7tEXtSoftwareAdobe ImageReadyqe<IDATxb?P0@ yА@&3BhVw# FF&fff(fa`bYa}d:Rgr13220ʊ@2|0aby Wll - ? |8y0||nj {\ @:NzF2?6rw_B jx Q 0#Xag``Fls_}Y (@8Ȝ1ן?C66<(耷, xt~yHLAW^AH㰆Ck>|ehfc`8, @8=~Lff Ҳ ?3<|Ν9?~͵u.0.cz]@w330 #ڿ Lb8w";$b pz0'(T13| ''Xϟ]ʰrj͛<|(;G'f?B~[Ac/v g])կ{=LJɃ!LUUM < "aɒP V`hhưk6. -[~GYBQ_ROW 3L@É ϟ2!fHB! ET ݽv_eappeV`ض8۷P4IKK3L/nIMv1&i`43@凷 f83`%6(F&B \XXXX&%% << >}b0}`00Pdd8q <=,/EE3,]8AMQJABLa?O3o:sV̡`&[0`[{waQIFfF z ÷o_d;0Bp0_XȾp="" ߀50O[=/v1qgY8n0flpx1PdJJH?4IexÕyLj`B'=K?1ߐ:9ց0q᫣74az`E) vGQ ~f`d8yM "4|Guޯ' ;Rt5 |6I|bx߰WJ2K ̺OX+r2 ?90俲d$t/6VK?XfX #:e Z"=#?OЛx92 P<L~@72+3gp=eeݚB6(Oo o`HL )w&` ώ1e8Ӿ޹p` @,h'&` _~,}d`> sC?$,9?02,T4QHcbhTTYvqhEV 3'ߥ@ mobD8AWP`0cfu)I߁U<С!+. 2uEDDTU <ǀ0× gX9!E6R _7fxy`ʠ hʠ)l6@ 0] ~d>6!/`[A{V`o0@/3h _ j—~! &z`w>X*@`ߕADXT2301R%K7-fpJ>?<ȿt$ j&ʄRc?1Ji, zEv W?3xM 2D\0h=pM\P5|Y~ܺ X+9.i`Ĉ=Xn4axuL`oBW@,=v/3̐J.L÷o>06y߿cfў+ k00) Xq(ְaex72,^d . s%h$~`Y//^<_203 r&`J&+5EI rX`zĂe 5 "ع}}y=\6lXyϟ B@1ܾ}晘BKNFMnjU;136B@00_.8 lC}-pu[kT1B|+"ޭx"l hw߾pŋ@/aP/֮]՛OV˫ ,f#g`x~`u(>}2E-l&n. gΜ}X[[;&\ bVdʪM?`/wpo\@XSg~!XOBwܽJN|B |F.1,a2X 1~rq 0}?9'Xl8kp/`_Y93ةKI݅TIl _c:*l@3 @$r_|ݶpJ7` ؉wAJ<33ZVVR/`@߸ %hA_H_hI߃ {/0wijѺe8@1 K@pp031(0_ 0y`{,tbc> ApY78=o<0 `Ik> rWlȕVl2߿IDR:fX ҹ8 h:Xғc ߀Ћܜ\|Zv5Ãsov00j@l?=&,xdфP# @4o`+Uk  xuA퓾 ξҝ!Mo`V6WԬe)yzݛ@ԃzàN<4@Q@h Ȥ.I2P+XR'#q!?S@C4=`>^qi>yIENDB`Ext/Images_Client_HighRes/C25_Folder_Mail.png0000664000000000000000000001117510126472570017737 0ustar rootrootPNG  IHDR00WgAMA7tEXtSoftwareAdobe ImageReadyqe<IDATxb?P0@FFF'ӭٳk>ף7o<ۯ@%bzdee[ZZ1|6/{ϟ?}8sҥw@( AyZ1Ϩq͔5u~Ç 7nЫ۷ozf/^p 3$gH<==UCBB/%%%rSO1ܾ}…oo߾y 3^p@% @Q5 jhhrRΠ nnϟp[n_~_y͉SNMjDHHH ,,D߿1}3w]޽;O?~珻߿cρ"@Q>7 gx0m jvUUUMm ,yX[[AOOW6_ :bt}yy1 djUb߿&&&L#5#@Y?6c@Ҡ;wn~ qU<娬 ߿ P1?R'0p0ա74!уW P=w7ՀA4AYE ,bؑ+8c` `P?G0Y`0@Go מ~gxO^|/8{QZ_)@O{3خbw?`*^{~)aSbdPgcfc7Ü.,+wiy:jj/7_0x ^bx? 12p0q1H r2(3Kp0\aS ~ XXdzG`Q}@\Tl(,؀ 8gmyqAI>ѷ~+177_?oAPAZAATxߐ(-Бdd?hbdx)=u)0="@A_2\~ݯ_@ (߾eKlH/ ? ?~ )X T'9$3E@?`Osd@A޽+@=3Y]]|"whCkY`b::ر( ̡w38e[1j1&Z 53891 b &/߁]d @=X /0 IFhҸq"bb"?h?RC?j/A_]/n \ | ݅;m!b8?̠&p]o@[54$z®3|c8z&C}!{`Z"~9>c`;XXs3Uaٲv_}yPƝ}^fsse^p^vE.H/ad6E I{'{`%͠˰0'm`I-?_’PKA%:NP!Ei=g!ixa Wgήz ?~B<J6!!l 2c5>peA-Ria6{o>Ϡ 3 `6``s8MŰDE M1QY3?o`!?h7tT.*RW?;One(c ['Ly ѳ_h,h@@20Y`,a0zḐO; 3131 Y? @ѿCzʐ g1SN|xp@;3_,@ r#NR&NǰzE-maP`C}(9 RS32B* `Ͽ?_O_~l`3Zを-hGk&<rL=]%o~~'_o}ķ@ t(#B6 ZLBߡbc (bN>fH J%w/1{pȺu̱ߠPtʥk?{%?&P聚:ԬC} v_?H`ʕῡ)6 bK *Cah |@05IENDB`Ext/Images_Client_HighRes/C52_Encrypted.png0000664000000000000000000000536410130001056017500 0ustar rootrootPNG  IHDR00WgAMA7tEXtSoftwareAdobe ImageReadyqe< IDATxb?P0@ 02228:::qpptrsskc@:_~۷oO~K/X 888X*))m.))RPP`/IR;I2333<|Ǐ @T<@( @ݢBL 5S9h_}/"J)o"b%aι*d c@ "ZfF^ugL@1. yd!,:M:|jizAVV ( H @adb`H2b_!V6>>cqb6@PHT@ za%1l@a$!`$*m|f^?~30 wc+x&&&#={pQPO tuuN$'7\1@$l:dزe y?00xa@cagdd@,8r:QE ,A`͚5 ׯfprrczt45U|pys1DGG1xPŕ$֭[S@))Aln` 10O1# %k>} 3[3 șAi֭[ W\gadb9\ɓ$s "" Cuu%iik/⑨ Rt~UU-~~.NVVN͛1\xfL **@=bfصkW4Nؒ@aYYYn޼ L /\\t@YA@@aժ5 o_cpwweӧR8QQa?^=p `a1@D5 3 +СI XT  1ܾsoCۗɉALLAXXחΖaXf`eczDw +ٕ@1*CXd21|X?f: , OaPVR& #p)߿}ge Ԟ | 7/>ax>|mĂ+`+A+a;B׌G6`}~^"س3x*1l1@$ @BA_ǘ3|0{aW1k@g3 EzP=L b2 iCI0P9N00VpiY^zɰeQ~>|Bzİ%!b!P:jX_LjJ T LBC9@,vlDb?`b@y3'u`Qz$c(s|V4 %(0=<@8Vx?xG,A]?ï? \l 4 Q,@1$h~K_o_1y񓁕 Pɝ@Qف1lZ`Xb21@aIP9v0@1pG"X2p 񃇁/Ăp<Α l1@X+2\ DIm|A#\͗ ,"Fnf`:QZ+#WLr1DRM$%!@X,|d PL.X/ '`KBDR?, s@ˁɆ Qbܨ5;s! 3020\=c!jLe0c /0(ԠBWǖbhy`2\q 3"?R;@L 6 R 1+`@ n0h{$30m+AFgb!)"l="2f4r̠ˁB1v96Jɤ13t\"{I |5,)C0@,sԚz@ax_x D|v!fyyy@n_X 0<׵˖-k5_@6jчnb(((Ѡ@1b ^12{ u 222|آ95ӧO>30 ہx7A$ @[jj7(Y t7# @<KZMU-`x?C`P1)5IENDB`Ext/Images_Client_HighRes/C02_MessageBox_Warning.png0000664000000000000000000000627310133444022021267 0ustar rootrootPNG  IHDR00WgAMA7tEXtSoftwareAdobe ImageReadyqe< MIDATxb?P0@ yА@i.+c`0vfڀԲ wFt|3++ûՁiŃ;5- Z$![`hh28Μ8g:OAF DmĠnmʠ DsR@@)B2eua`{e-uw'$g1\+à30|z`gP `Wa A j@Qid ̪~oXD<XhV jy@ D%CC:o@'ܩZh04!Io${A @0Q N Tf:$ o |pR ɠan3'B)i-,,L: ̒r _B /_bb xXlyAʈR>Rdq:pPHgn`Ą᧦&J 3[+C2%I (IB[Π)yWQ @76 (我$⁡o }^]CpQ Ĭ<<  X9M %,Az ȍA5 H;8yf`PSc`cb?Y+"--X`k((1J*D Dn 4 QVreT: tC[au fff --- L@1zx쐤;Z L@2DT&I2(30v 8dQNar :::>|(*`l l#}7%A!5UEP,8Mr%Drzf`&0AE\'0$..fXΎYd0QRd`VATD{ Hk`%j1H_!<) 6XI($$$98 P,xz20|u2Ơ^)y Hn]L~ L<&4ĎXJJ J0 ,?}a0d @Q@í,RsAW***p ZÛ 1^C `?#6 Q>Ъ|>~`[<&b:FtiYYY,-(`ݡ#2rq3H+7`J:R)Wwf`yZQ ,6#'(P&PU`Ma&sX2(2 @/N4[>.n^Ïo`LR EGk3\ѳ b\ *bX I8HX10>c,@{ l06PD9"F#^q12/`z $3+Pb y% Rr ?kL^΋w?`QAbP Op kf Y;$d= ,PAŪ|@0HXY5 2 r@yn6r`1 `/%%VVVq$``We1yACTT6ŕ OjaY~ݼ,‚OwS߾0:=nF0BkapC̒ b{`A1KAk\ Zv d,3 NF0G 9 Aʊ Fv4r /x؁;$^<ʠ%$ Р>(<@PPkb%H1eol 8XP RTKFY`>#P䈗h\@ ҟe 8@vL|;90/ hc4Px6`Ұ2fy4ß4 }A`w ,k_b`68@gE0h1\?a dh1pM`0A Y!9?J ˰4`Q͈ 9g2.O VfgHd[~zAo |h7_$?466Z=5Pf@'` 3o_y}AXJb9g3"M|Yfâ^_ @șx0޽EC TLGK҃f$_Ȝ ơV L=@ yА@d"?VIENDB`Ext/Images_Client_HighRes/C13_KGPG_Key3.png0000664000000000000000000001205710125245344017176 0ustar rootrootPNG  IHDR00WgAMA7tEXtSoftwareAdobe ImageReadyqe<IDATxb?P8=@p022H_ ? R?,30xu8^00@|;L fTpo4>. bXYDȆS@Z]YRXA]_ǟ naxvëG/>xoM @|y z@H1;᠐`crTSԳTeбPdPVd {~|aaxKV+3l43*xd7 _<@px= rtLHapW/21j1)A '7@+`{ _at5Cǿ~VfLd{T #d̈4'nANÖ= k2((2lqY' zz  r0bEN-_~_`a'70 =šYP % u @$ @p4?ӿo eXwP]Myy}u?0xa߾ ke `o/`j*  |\~> 8F @wga%㯿?>Z 1Ă=0#qjFnF[YxeTUXXXy ,,+3|ӧ ϟ`hi9!3_ 08cϏ? B?3(a#cЬ, N~eX3߿UNGl{j_% -l g\`ضm7_m^^>}}-5k2DAD:s$(A03BP?0ȉ33(*X0j2͋Zs7@3qo}  @3pK}?ý{.^fO_LLt֯_Cjj~PA'PPjF$ &F/4J1>y/'v}U=x:{i wQYv<\8G!,YW]ȑ >|Ƃ<0)I3 caɒE NN _|c8xc`|C߿G  <3@!$/Ҥyyy9 03`h''@ `s œ۷nxpI%u>ëW<+íN:Ǐ99:_2 ,WN30=;,CA!hi{ ""׻Y 3CT:4XQlll`|%`,b3LJ˗ ]Uɯ h`?߾00~ v˓_: AKի@|K @@ ,R5$ r(0?()h $ d33{@Os0HJ c!<}N?~EXL@?~-{=0\=Ea۷_ Gr@}߿vJ3Yo_a~P3rfaa>k, ;@K3g`L0󃴴0:ف@\\,v30C73] /^90Yz LJr@ Kg .ԔAy2엑QB@B/֜.ce9O 0@1Cp++pp5!% Z@|o{ÿށCҥ 0Yax09]LI (0px i%i 9P4h k.`tZ3cEEY%yy!pEt0A! ƚXzO kn̈FHj ,uW utT= t ~Ap`_X@&H*]@Lk:`c1ׯ׿{O +Ã00C=0rK ZFk7;I,X~@{W28p `QPi"H]P2""8?u..22Rl V UU5O?=t{t #Ê@㪌fsrrRTf@NvXcٯ^=&pON489v#RA馦:}eb+ /_;@5Yz %(%Lk` ,O0H`ŊXG _5S`wqX1sPLu\\ r>K3PЂIPF{n[;lQ`Zl@w @3]ʇ͇Q==Ø_hxpC`xZ}\`quz j=}\*󯀝Ϟ} K>nppp-ŀ *DV 44 :Dtumx +05KDPgaa6M1߿ IbbJ;WJpp}P,2=??;al&8߂+JaaQp@yV$} 5 li*o\uWނ _Kr@Qx6z5޼y lЭgT Yp_ ,lV ޑ|@QO6\ r-FF6`{^0f`m~kC@%5vU<^t< \P=nxxO<YZwx9~緜=j"}/=M?2:{v,A ^S!OeyeLJ?կ*Px뭟|2}R gphdXJM>_^-_SLhxy4[{ΑCx9?Ϧlݰ1)|Ǐ;u4tB8pNZCӇx7Y.z )]07[g׸u/_beez7ߕRCF-cMNNto /,gvvaB2d =%ٳr5Y3B‰'֢C֭.^ٳP_Av.$0>5::7Ɵ1?,0#IZxA)ѰwwVH8sJ@7](Rx#Ԓū)%R-gz?qw(x,,~y]Òh%dCIvA?:OVj')gSk H) "P'###9#MvJ!z4:́q bgA1~hZ"RvJ\cуᇙ=pŧu?MNNC}p4 &X4_yޓZf<'YՋD$N||7՚yVssX\xsvaffBD$do-K5hun:"UMa5J 4)e;LDH%+P9Es(%Bω&4&S78,ѐ#$ ^es W&>)aKjqbW`(B0 αo|{0Β9 !! Mz=VkϏ$!BA*2$1fGIp<5dqcڪĶs!YJ1 Zn٘( \*LӊV-'RR (lHE:TwN>ڄ@!m\Oo%s.b7 p|an~d1ϓWzA@7pάt !UE7n|g) XkI{Ig*A&Mirh h"B*Ƙ.)'F)sƝR(`aa39]v =CC8gÑMMz~K@)QRJ X)EQZC!'~4Mg!Qq9~`BaDZ2RRQ;w yfӳw4Vnp)cwIt>\=>1{G8̣h  !ƈ6I$Z 4+.&ٳ_=֪? |t{uA6uΡfff3gD8q8N1ơuҕ+RS0)%JxB\:D^|eڇ֪}QH)BKyy0Zߝ+ɵ#tIbE!ZkƘI)]@g^aqqJF"I2׫ܺu#Gګucu|sisj} ePTܸq_.\ߢ(z?fz!7~7{;wZ(w q.,;vbd"YfN.pgߛM =z=f||'kGQl6okJR8zU؊Bi|[~zûWrЮNhhgzyjѣ[K.!Z%!D*"|ȷemTJA Si.8HIaIENDB`Ext/Images_Client_HighRes/C19_Mail_Generic.png0000664000000000000000000001027610133501510020065 0ustar rootrootPNG  IHDR00WgAMA7tEXtSoftwareAdobe ImageReadyqe<PIDATxb?PĂ.H~~s'|ݻ[fݻ%P'= xb?9z|922@n -?_zx >AĂEL37}?5[;p" =5#4?_=_y *ʺi#0Y- Oc~sgڥ|&W\ <>}„ ӧ__㲲rbP+/3QDW9>~W`8߿S@ "_৺zIIos1&+{h(781 J&5 6ofo.N{r} bDu|Ϭhee%mm   C@_8+030ܽa֬3 w_{íǏg,bn" %΅zwcci_ ytOCNQ`ccex 48'o1<}ç |aX3+ 3 ''38b`byqNqA/RJ?T oGH0;e^AF2o`ӗ} ρ f ,@3333pr3034p_}m##1E`F`PRebYM@( wPÓ <&&A_ o~;/b'0Scb`& ` )>cdQeP6WfedcaxPF h$oĂq{rRߜ ?J4<}eP԰mfeea`g9P21B y&Hcbp6bfb866&A&H>/*&/nc@`&Izl\ k^' P30}03 t u(d!5{ x&G@?03|;Hx6 QH J $"㧲_ [3 trp1l@:  $IΈL`CI, 1=X~F $Q_Xbz퇶>"Оwt Ξ:  |F[&F FJ _(1\™ _f?%+02rF'`%ӂ= We9b5ihH3(;B"LLr}o @_[MX 27'1ܹ X3`zFh '!H`:G`~ ! 1KF"(0 p#5 ĂyW_㐗!vVE`JTb0fje32;@XIVt@;?}gcxCv :8cz\ZA@WYEkB@a6d@۷^CPPE |&e| ~  q R ߿fzv2bbag -`k-BʒX_h3T"ePJAX2p 0<퍟}s#6EAL & y Z  ߾|~3|i1+dֿ~hvv.` -t,#}GIYwP If WXV' pq3JK1Q8`-2t-&@Fl<cؿ!.^zgӠ1@˗G?]v?heAr<ȝL>Їy/t`N` @޽p++_1=W v_k`_+=H5a"42Ϲ7xf&V v4_:v & AP1w1С Ǐ?h5xg`xhkh?5[  -_n| (-5v(fD8$up,w ;v߾ ρ㻟X]}x?_+PPǃB?Lj}{z_.<Qaxj0AoX Lb9/2\? }c8{ Ù.\xp`ӧgVуW>z߼z$^@;@Ll @3*ܺއ7+8<=7_3,Y ׮ax_??>Q1/oc<0:y2"?`3,87Ù3._yg`(wg?~PI)Ħ@  Mo-T;zsRIENDB`Ext/Images_Client_HighRes/C21_KOrganizer.png0000664000000000000000000001451410125245344017625 0ustar rootrootPNG  IHDR00WgAMA7tEXtSoftwareAdobe ImageReadyqe<IDATxb?P0@ y `ddda`e``bb(.'G_0|I?X% iiL}[~=e˰ F2P? \ @`30&ǨWij)h0ps07߶;U8 y G]lfP3@`g` "Fz22a9؉=?;'E~=g7=-ŐT6meOk"A?+7#/7@_?eͰG0;~b#0,1@`: 4-R1CL%g?\fZQ, >e`&4D`$CHVVF.miu[ 9 L6&`昌eoT-ߟ XإDYx؄XBD.|`a軼I&7 | @O0'@ObV&`e-` * L?3?#m& {OYzݫ.@LxPL @eo]c(3!om(_W.%?3? ?!3Ʊ asvCyõ?>FC{{o ɳ1S0X`0C;G̼ww`J gPaef.`p&pHq!-p( &` `W Ì`Pd`ffb`eaa`0cpdraޏ9 : ?cx/`&1o %L}d"M86 ,YPuTo-GL>}=a=##k?0"?ؘ'Y[&[Sbdh 40 3ry ˉ ?23!p(QC[" N.fxx1#*`b`xT!D3!זAJcC" Ñ f4b({M zxf+O2dwD@`ː,$ d\@03Ddho z2\ X8_a^F?C*uW71|߁u ?Tx-,16X8Ͽ0HJ0: XL{FW_38(Ï?? 1̈,<A@M6/ f)1I_c8⥭&j!"_34n=2A@AQFϞ0kh- s?4~0mpAo0y*V.L38#3A➁чG {cEI *R78&= 4Xg/33fx`. rl ;߼dqu ~U ` &h a ޼rĄ~1I}fXr(+4+1+{f9 IQa&P J1.=x%) kfx٫ oaOû/w}lf ,Hb X8zп6O7?:  Xn}Կ2O\a|×^+?p/G~3<݇? ߾c7!Ou%n>7'! _ePfzAa +0LepU ǀ!?e}'Sws115qޜİ`rn F/o ?~`8|3/3, 3FEyE`̰0cD\`"ư3h-;O)M KfxGv72b!Pc , _ξ0ucG3s}!Eq^ ?2zAM  `l 2 ḛ{O?mE~3Jg8M.y j\/uOW38XPb(Q0 Xb= ҙA[~2~dì-ױ7 _@ hFdCr9Ykg`p d`!Cw /I3|~`y_31p3[@E aceT eXrb -CA"0V0ldq@U.??k3,IE/܌ԑ@GO}鸳lপg/_>0AUA^AV9# `b,Q~O=p+YO?6!Iˇ!8@!/Ȁ!RՍ_+24Ԁ,oY8TdIį`C >~b^<\ _l?1,>ܜ7C .`u^POR_!Pٗaɻ w_b`ʠ+`?PaX)9)Ltku^́0V??aی\q8m>2_f3$ wFEv9i6) 6afp?w7?k?0 }fm/I2T220 ^BzT_P5KF뺇 (Xրr^jbP:C_`> ه? 2 . O?ex!>ͷ|ǰv[  N f'y`1V okJ`; ,pX?H;R+Z}Ĭ "|>2,>\߸z ‰ص`fgeacbq`&u`xMЬ3| 5>dز3ß 6`mjaC,3GhT`F ]T$BȐ"ur`)O 1]&?d L:JP~AX!An`ej`X 4X_3ߟ2Uga `d}a d|áǿEՀS+#c`do{(Н/=;`T>6T<` Tcgx 2<f;A`rz ?~g. o 0`OK1$1xS( ֝x*&̠#`o&e*Π!l]P22@`:!P?<=zfk]i! I⃯=1`Zt /9U`1)I`egflq1VN`G\Aۜb>/\ 4Mfw|gf0VwYH`dK`'_Q&%L @ĵ Xq<03s_`6|p;G2(J*< oK Vpu/H2zg1qbbPpebF@ ^8l _o30p[Lo^3\ƃO ‚ j "~3K"^~Vp!`H?28v9X$$@yLÉ.U\~(C27#$⁻@i ^}.?E8#7 L}lqp ˝ (VJ@:kP'XcBF;l \&J_DVp2-Ym`bav`dȀ P< %#P&W>TF\5?2,7~vKcP/]$ QP$ l;u bqqn9 ;a /0d)p;qo3q30 =v!VP~1309 qi?EԃW6ΰws{uD2f`AKWA,< A ,Yi&֮ o3@Ao߽̠-} tX3;FMX@c2 ~fd`&]`X Ge8pV6͟z!6-x; vj Xd$X4xe#320  660LQ;~ys =Q@C73D?e:Ew v& g#` rKTCW`/0f ߁5^ a`7;̍CAc6 s0õt zOb⭓ U03pz3.3e8 t?? :2ҍ3ة|a0 /4쯗'@]I` 16s/n?B+R/`w+gaoN>@1: qJ-+"@30H4 )ůge`3ثaPx͠&XG| i KfCW>cH`C=zۧ@6}?{ lE}hV r;@40@Chu6vەX䁼߂PJ|a};3"F"kf`/`+>o^ex7} ď0sc`N%XMr;@t flHl*0A,[g`_F,ypkA7C@]gQj|ĂK'8ꙟYc v 13|ֲo| T/CCC!(T?! b _e j Z ղ쌲QsC?@G} i8W A@ n40؁f7pبq/!V  )lfJIENDB`Ext/Images_Client_HighRes/C16_Mozilla_Firebird.png0000664000000000000000000001366210125245344020776 0ustar rootrootPNG  IHDR00WgAMA7tEXtSoftwareAdobe ImageReadyqe<DIDATxb?P8=@p022S@f" 2~e`dpad5aWdaeab÷o/?e`f> ,yf10ڋ yb`f``bFx ċKi1j2H 3r230 /d o.^}w;13@xqw}X=@{Ku &+4VWS4AHA[A1o~00|p{0;xÿQ&N;؏" n@CH--.c!Π! t_`Jـ L@9/ (FaK߯\| 7  ( =J@u 4n'+ i? L@213= T򏁓 _ Q ٘ANcb[ۮ2\syݿ1ÕZ`{ X@e d+0Ϗ Ќ vSd' YA?pL!-y <, ^ AS#;BN%H &Ž*1b`jq3C\m`dtןAϿ  6 ?I_ ??3H3:X2g lw`a%`a00ȹ$C%U_O "@A r(q2Hs;3>X {'tř?axÐh 4pb$ v@V2ߠ?3C=6; ew_-%? _T%d9y&32=% 30|HT( Ā=g3depMH>b›u3Q+XxX'Eh\ï߿@H r0Jp1\;q_LU{'û}= ?b`g O ,/Ds^}ǯ2:j2Zt1!vOH@= c 6}oaI_ן.=ATA^ X72<>w~V ~:'$/#~?~1|;C߾_#' ;avf0/$Uv0~$00@;f~abCm)'/3|a |`~bo00 2e~00o x 7p_SUAIan2yo A ?}fh]z ccPZs*@a/FEtM/2ѭGO~} $ɰ6(~%E/2=pc_1xG@z0eWo?`/00ZVVfpt#{03prp0pIO1> fW!}V&t$k@ t,3 (1ˈ fw[ !_N=ĐhnP WTRkLb<is 6 RRJ h?Ha{p6~`x?.[-3w1CҠ`WQ_pk_0| A1/3@ݹ +000IC?8VefWgx-/7'/3-?p3}c>}u %#P/×o?>|X2}\=%$)Š5Hvdfbf``SUMUR X$ IaKpqede%SDTt LԹd0u?T~^:( y?j`@Z@1 R0`c֪lŧ5 OTARQOp ; J2&LJ cЗF^`{G0$ ㎡/Å޿xǟ=a8u4C%06cדqF`I5C%Òr <//0ypZpUpRL< b n Gv5* Z1JPFd{T#+;' +;C|V<&3'w]QiObs`j&0 3>#5? uvU_?}&%YAq)~1&2cJQYANhP HB"9`NhV@W331D&e? JK$t- ßkƣ7U o1|V r @%隕Q  %l"fx_AEEp-D1黟@Gs 2e'lFF%%pq ';~{ o0<Rl y>ㄛßr2ba0Od\ ?~a`ce +I1.'A ? 21,3@!E'`I 0$ mşBf,2 X}6^bAG \,  #Đ?`.p2.ex ꉌvpdZ=?޼ Xg~@51$]I:( )]}X`*- soW3]~y+1{5p*/2f ,f֮3 ó.ۏg@ZFyQDdz+(3*A,#O *E@-՗6/,yLRBEpd?.7+?3 ^1\:|AB\!+X> UݯO#( Vx8x̀ he>PcT܌AX) /_$Lk-ï;X#lf`8 W`'_ <¢ lvgxpy`{ HXrv}'Ngr}g')*k?Ai@c@+`9_\?T`  H30=9/?Þ  ;D1Ua8}9ï35E< /UgzΚ]? K8:1 6;!I<&B%psA90~{Wv`wM_HbXI@AX@A^!טAAOSAAZaci00 R ؘʱ7ӥ tb ïLT``ac` vl޽c~g`I0<'`<\8? hw2 X3A$E{96 1(2(ˈKn`R&gF` dn@%^PI5 oX `Fb`6l_V100^&h; `lI0l>aJל 4 Cfp|XXZA s4n،&! <- ?@? 22V|wT^dg`4xfFv<+$eyޣW;*ҩ@wl4ZF%iQa}!x73;/H]Tz =liAYߝ~;xG`7ucESg_67NìS`œA߭ ?d`w(3#o lE ##12pz|fPSAi%X1'h(77c6MzM/PITV@8=`&Ƞ$ .@f 0| t"Q# s3f`| @c@2:ǿ.M{.2}#Ϡ̠Şa[ lƢ : pz R "Iy^0,0Cc oA|`0~Wa`xw'ß?`9 {`z Æ6 w~g~_fxm3Ï[݀ژTҺde5sY0Hc˿ ~ed.AdW14cwt 5yo~1|L^16&O 5: UV?ƕqrOa;o`- AC9Z1<_ FZԑLMݙruw'[`>kH;^!VLc V6%5`iԷI@mb;p= Mү%ˠ%ǹТ+<v(9 @@ܛ t%1Y?f[3 -szo"Ԧ 89rwz4تG $s83#,% i2L> [C_0'}w,5挬wP0 r *R EŦ ':nHhOwV,)RHN <[< mX[w$񻯛ox;A NcޫUOS[-\cāQ'0;+$,/ hk>?@c :ьl̮ZRFF"@Gۨ000 }[~1xΫ ?f'ܗ ʠ . \ ll, }cЏX -1Bcj ?!mb `".=t_@GBZA  ~u.IV)60q /B8@ B`j &4v^7| Op23e qm&&? `haJ(bceAR` 2kbDLLCnâFH1xqP @c 2ѝ"w`'fa v.&cY!}9f;MsPD9y KMy/Ч2 a^30߿i%fPa}IÛep]Zp ,z~V r H$3|< >CYИCM_ f-|uONZhx<0<4DBR,B.:~0ɟ2|فIث g~`dF{ ]\tİ>Zf`fgec`eg`cas@G3"<^Ug`5M yy a_oΝ}#d[A ?bXb65. , &ö{pc1\}z l "BZKЂ^XUe^ɋ _]JG/R&Xmf;0=GNI^[7DdTtɰl&{3ݷ gx%ӏ$CU=3_@i&P ٠dNf e(mZyrmP(F@#NuUX,a*,$U`Lw ܌ ̖ .fpCR>=jd8lz3<2R v4(Ng!󂟵$LޞtX =ODDDHE @O. f&1Q /qXp\c^3g2~5o%;>1HJ0ï P6 bX2|6 ,$4,DAZ] Pg?{_h ' @o+3a t>0T#߁N}z.C?3 2pp2}pnoN}r!=AVA\SI*TĂ8Y(3I@g^xƃ@-m$Bˤ^YNlo,i@Vπ ^0<6ٙ-S` g>bX oURl8?He!!|2śȰn ?^߅y +/'vH{<⛔Oe`6~ `; zhV&fWonΠáp=#bum]6`oH άжtŠR S@6/uy܋ e> P[P@m`P7V<ߟ%\<0h=C87c?wo ?<Ĥ$D4tX:fU`aڐ N@o-(cf. tzy~8 80pK > -%Ttn ffegPc`q;o746]o2􃁓څa?h24aT2Bi&h+?O`j!j뎋;>6sAn!F9 L0g8I01B ʜd_`QEARĿ' >fPPvV 81343۹0Afz!:`c1MaW[V3 z &L\ o`eO翟|p0(0dzAE ,l ?0\{AAUẌ́( mh`VjLHy_/?3;S0Yq zק\lw_g1\xyԣS O {8v23K2H 2pd'? ,GY-(־O/1<~؍ Rb@vm!)_?ǿG>|~ӟ* qc[4VO \`(=8 _b`~$bnOK[Apl;q]@ L/Ó7?p77?0\~ ~}1P]@FمXYx뿗@1Pc {m Q= L s1rgasaύ 2RJ2bg`g`ftx@{._}O _?zcO16Xbyh/Tu_풬ݭ7J3z &0Sk^?@GC' /c2\~ ÿ3|ߟO27 bx{%w=}}#O @A5wMX/kKwo&}?3#Ƞ!,5~1'`8õ?@w}Hݽ o}{9ß| u{h H152^? W L;׷0 ~ o0'C@@Q vi1 w3G[1ș3}`o:9÷} wH!K D $м"&P sG$P2k@,ӳ@1:9tRs R4=@C4=`>'5VBIENDB`Ext/Images_Client_HighRes/C59_Package_Development.png0000664000000000000000000000751710130240700021452 0ustar rootrootPNG  IHDR00WgAMA7tEXtSoftwareAdobe ImageReadyqe<IDATxb?P0@ s)6Lϟ?5bcgcccaeeeddF}kLLW~~1Iz9 v:.CZZOZZANNDsssׯ^z _>G 4%D~ &.aic`ia "" e@G? 3#ï?~wǏ3\pݹsƍ~'&F@n r ?.rfaPQRb`gg?y o!/gXXY؀je$D<` ݋u_q@PWT%eаs3s.NG gϜb+33`YXXYXYgxǏ ׮^epǏם?~'@@˶3(33,÷o0Ic5#3 8X!4#= KKJ22(*(h"NNcǎ-J×/T&s+k՘X q1Á !޽y[`_@G30qP hi /90004ͬ5gPP2te-Tb>ãG~w= G>=:y̬<@OdzgϮbf| ⋬R|zN \\ ߾:pfbddx m?~0@! ʜO#M=lP]D|`/  ].pL0c p:fx,>_@ǃ~{ u?=B7TN@,D"?TUUa9XfɁAEU?>{%-#ɓ@-8?D-daa E:: ޾ax=_~ ǿAo ?ddPQef2TQqn  ^ 2MVV$×O9T#?f`Ewk3x aCFKg*tM  n.$hQVVfc:@πoHC%rb{X۲1|] n<]0i _=U4}S@n , b6d xPPR L߁',_gxzyC6m{)WIk] Orm1==jyyŖ6Y9ǏrpfabFϟ.^,shh02<| -|x5=aS .zP ZTROIHHebx-8'Ņ ?0|s ׮]{l=alJ3}|!X(o A%W a nf}M,WxJNɃ  ZsvO_?xxxI 0۷]z FɷnnxW7yY1 3O` 7 ,y|;m^i;թg4Tko[3og ) ʾ ^G?|!'.]瀭``q`Ih2؋3ϞegffgZz͘u7:Z#ӯ " ^R}~oO@ Ք?yd)ubw;3A18XXEvP !IL̓\o?t#DטU= {PK{iMU^99?/xq7usi4h@K Byʤ$֜ O8N͍ܗcrg?D}70Sf,  !drz$H@zhϏ?],cǯŸ n`ϐH/A^O=F |}<~| /?25'3X=U[J8\Z̄  z ~;ނGi`W |fX(0f1z13JJI'@gI?wW~s~k??3pA֏}1vG^~l z{}{ɕg /e-g`UҖ->COT_DM[ bo=13|{v /a /_^}u' H^æpKҋYv!)W0|y񙁝 l1`bf8LOO-d@ @˵/xĞwd5ëB LL ?g`a,71~p%+^c 4fxϟl 0| W Gp?_N=@T 3歪>AQ=ZB;?`'Ý7?yA@ ghx9YYx8ܙч~u߿>3hTt?4<մF@chyXXd}&F0cIENDB`Ext/Images_Client_HighRes/C43_Trashcan_Full.png0000664000000000000000000001160510126541376020306 0ustar rootrootPNG  IHDR00WgAMA7tEXtSoftwareAdobe ImageReadyqe<IDATxb?P0@ y >IFFF&$`cMo-a`fe`fdd`ϟ ~bÿߏ~USo!Ʊؒ;@18=rw3?Y}T8Yxd_/_~0|wû_`~'۫.x b=@y 4~,,ERr B "`+ ~gt_6첿 @u?fÃ^|+^puu_V" G\'h3J20sn>w~2|ϟ LU_20] %! )%O0\y71ka#8=@y X ?go/`$ң/ /7@h#0 7ÿ?d07x~^.)i um Aan篿3psfxy!t+@@dIQ99^* * f8r ów?fLJ.@?|}ǠtAI?Å' O 1e'@O<?g Ove u}s#F&g/3ܿr2ɺ$`t7ln H:q_C@Qaו }.0`3O ~ :R o[C`I ,EX89`Rb|ݻw ?~?ѿ@ς Xz?Û@adu c z \  n+]^S/1| >8MsrrCmb`Vfo߾e7+C8òCioAee$oPX22qv28b$6 S FdR`蝽7y3?!^;\Ÿ! jpUIc013Hq[1y+ ~2H 1H[2ׯ ߿'NC"o`̜b nq0yoȠ𗉉Λ7 ?$B/w(XޏP0*&bff3?l l/ʹSֻ7S_b0@∁$!C,rx.p>grhRuEuL#e9wNߩUD6Qh[LyίX8ȣX H,vA T |2VCM>.O։4[쁹Q97+^0^-+0,cŃk7{)j~(Җ6IUaP`b4XLEÙfi&j)_>c0UĘua$H@b<@/`fjq= B}: =̽ 0'',BA5%4ŗ@!x@b Jb܌?|`;g30ax3;`wz!Vn`[ae;E`0= )C̠Z=\R 1\aaeiFY) wafo 0ּ?r3` ""T 1?j`x&o>|_!A!XA^f,z?|Ux ?csJ;A|P{?I B, LH?| L6 7.e^~;IAP37~ l y^p`b` Xq"`h z WpDew#aFr3;y?>2zr_ gd6@r!B%TL1< AMw0J7\s0 n 9501~1|J` "` lnvH22Hɳofn`/ ؅^e1N_ef *&LR 3VB |iP vw>5!QM B`EX3[>@>MAT ~{jv30#31{ }w< '~K$PT&ɟ r<2a`2 *K*u&λ XOpߘ_5i$´uQbR'>!wϒVCĠOg^v@J!vk *M$P *06Ԁݫ/ 7 ղ+?@}epFp? ʰ ??ܿ4/{ID x͠:' u}Еw@ |̿dEy>~m`\'p0&W2 _`RdpZL@ +@`sPuJLV +z &By\01Gp;Hm k9PC6.hDTrHFp/@c,,HHQ~^>nvN'} ge`g q;((j9XF`F[u-%$@F&@ oi0_01b ̬L *xqQ`Bʒ`5Y$Y2_LhL@:l4 FË!^@ܡgw`2y=÷ ,@| u|| Ps=D39 |W@0kb 0&d^܄ġi g(B٣`|z&m*|FWh́tf*p"ϑ#2ƴf_ \z CW0ps9 "00 7Ã, ן|ex'O/~^~06A'3 +=av`ʋX1 xe6XPX|z ߤ@/FXt##Ys%npP첁6,\ o/G__Yv`ӀoP0J*N`Ϳ~ >a 2% lN y|ע'o[xMdPe&!P_f.?Yncg_ _}gxX3,0h.p337pӁIAn`- w~Ǐ?n 36'G;[!4̼ `-()|ee>`EX9àn&T:+8#/gx#{FN~.f6`LB߯oV(?-_.Go{3hF@  nf &!jxA=ИС'C_"+4iNC*.; @zgء Z80C1#@ h'GRbm CI٪FIENDB`Ext/Images_Client_HighRes/C39_History.png0000664000000000000000000001325410133443062017220 0ustar rootrootPNG  IHDR00WgAMA7tEXtSoftwareAdobe ImageReadyqe<>IDATxl 0:6`kCԈ*q "|qӌSQD'A@wW,Z lSծ@U7p dOJ+SI}y Jce ٺ,\| B |, l ? /dx'Ï~=xic;J1@A2 F2b NZ$,f`&`.Ƞ TR!S71ݏ ^}J;4ҭNJ  {hPEꂌ &B | DhF  1 pfol#C^{h& { (,~-SRMRa2:;_@|xÛ nfxv-0b`cd_p23ȩ1H11=4K70Xsܥ7/@G'"2@3X٘c|<y>2}wn? " "B bb ga'^Ɵ~11`dfP3aec?v!Âw޿~4@Č ҭ0`0gx;_1;yA+,'30 'Ý{; 0Y2|O Gg3>:40*3i2O?ox Q@Bbf.ĤfI JKiYa'?phyGv1D 327, L^l /_f+%Sc`ga01`P{v30 2`fgpdz-GXN}~3 G$ Ւ\ l|| ?00\=Ē ΎΞ .0X f^AYҕ JR8pcgfg/`fk85` DX,jc`gx w2+220lݺASS\)NCAWXXAUUAHHb˗/0_!22XAOƱ[ fP`n+pkO?95@}Ev/@13C j󯊍1؊[B 04 CN: 09c X 2 ~ &%SpLrp1 0O * 1f.pC?Cj {A8 _ f3Ve O0f3 iP:SSScgNHڇyHHu q< 3B @@12_GO." NYQvSG>j>s3@13= ̴KdT-nfax;Ç'ʲ$i#AA{Hx"6w/ԣPjyDKk / 3bbx=Ó[oIi>н?@ &H ĿZMXû oWb}%TA8# C2*,B</y93#hfg!jX|>A>UOg/2|& c`cKF @@=#Ve֔'0~81'3}\rWX 6ѓ$@|ꍃ 2g_x=P098)  }A ''͙>r 3}l;Cxx 2\S"B  wO?q@E/6`5` w!ßAX\T;>p,<}ŋ j⁊JxRyI7YaϾg 8~d},u U&?:L%>à>C8;''<%ՁmF`l;8i /0+_2̺@f ؀no؁3g3\qކw`PTGlƔA[[a.PenǏ?2ܔaf0O}99!`J` pq ,D^dϟ?vpu|vV`373'@=l5@ rާO|_?`i"((0mR󂮊 7n`ყ30ĥ :d>.'Pr{=î93h,?ؼdy ؙ3Rl#2rT'@髩fPga UU,-]O`3 hP+0Hzl? | Vdd!)X2?hFĉ yxx**AE pA x+× r s3?X2q1pʊ1<{' R4!Wiİr%×ӧg7H;?C߁/@wP@zx 3×Oߡ ! 4{7͛2p7 (Qc'G~1+Y`'o@1z qo& ''mPhxοhx xr<\p=Xy 4t1k* h]zۿ@EgXN|g`g'`I ,+W&(=w,E ï3~fe3E!K`'8YY.^x 32pP=t]u@Abx4ý 7o>`X|铁ͅ`π c`(V;;YZ2:800x ɓ' e5k 7;XR* 7> eR<0Ƙ]d_mSIf6mLL̠! =P}IJ'9dxz+6Bo$X?0<X7;* b ֖6DU aMNU$ydC ,''j 'g~Õc@t_@@0313vLOl_@_3؞yKٶmavÿ `kiP k`+`H ( `XeCbT~xa{ Z ~}e6^'d lCqJ3hZi 1NOgwç^1`q_$C!bMfVͰy]`s]\G;v;`7aag) @_ɼyݘWZAFAVX/< , 1}bٺUP8灝/v h >d(H@.5P "" Űe{,}cd8{'Υw 4; @ ™Mh׳$$p] 'm^#co2LL  5ؿ, ,0808q%yf 0<&4+w?.ϰa#6IÀn|^bfF#`>qrH1Ȉ21ZH0|Űf[)fgw;o¢(kPPshXuA%Qen1I3x:u ó:;K(m@x(~~t6Q^)`L 2I1l\{ʕ 624349@c1++G&w}X\}=bd}?] \Vc+ 34w8_w ( `i%*po˗?`wPʕX /`vŠgg !pÊV/{6h)h,اA"VPNbð X9h31x00K20| gO=fLǬ6?' 8طx nϿ| Eex?|! *-K ˷~cp u%+Sÿ?2/1%uD?r 6| Al  "$,<,^3k?~{o /]V`7ԄL$Sȉ a8[_ @/Dc3LJf&%QENCnSKu10;d>ͱ#&D?o3<ضa*@ iLF60Yi0Hɲ11h)032H 10\쐮OݯA3Fwp/!9>x_b<@x@'2z1czƅQfbb``bd/?yT~ 3w2u@{B;P1*LF@t"S@6 UH~@G?׀PdI@e­ ]IENDB`Ext/Images_Client_HighRes/C62_Tux.png0000664000000000000000000000506612505021006016330 0ustar rootrootPNG  IHDR00WbKGD IDATh͙mpTϽww捐W$`h#v BX8Heڎ|:vʌv~ h2aZ-Z ZF@Ңl$}{釽7D6!37{sr93;o OW@1_Qdi;N/Ph; d~sqe.c\"I_$zo9_~I(i\(.}o~`ڵ 0::R Mؼy3xu)` 'V׭['eÇz\ۭr9VD)e:('i@JKKe""%""۶m'sN9}l߾u'q8P;04R `477}v:::8;,YY`/ڵe˖QSS'-Tr䓿ŋ<.CQ@QRVt801|~8rchXTVPKQS7T 8^[SI*dd,9Y1w: 4JaZR#ߞ^榳|z !8Qz<;*$ "ЋC@Mj'К:ֈcf/-&0VJ)DT[l5ް $5/ppZX ]syt`$#1ؗ`,nk)A!1 &18fPSe*J\:ʀk#14E^E(e$ȧ{ytנț؄D)|/E*-o,ԭ\MJ2J)#N5]Ge#)CWx [tFLKHPSxzY)PJi"Lp|׽Q`OɹOC4t@i`X̛aZuQB鑷]Y [MzNR,Y޽X`p|= ɋD#$bcF_I )cx5 i&92]ۀ箔ĕo)l@СC""Gh$.)/KywعKb%%q씆RN-[H,"ܰ3"vK$""裏$l#'kW^t+OGiNm[Y"VFJ;3'>jےN% M^cgmذ7[ q)U(=g`\\r˯f۪Ux>S cO'x#WA\illnjG:KNϬj466dpʗu_1 ؔ)//#innL qg3UUU׬ٮG`entϤ@ p|V-B`E~)f]Y \Y[0Mܘre穚 |Ʈ SʇIb\3kF۶|]!f_"#DHR1cn>uTBt ׅN8Si up8LooderWP&qK']8prAWu]g$~9O"Mgكgsw[ZZom{Z4MdzY[[u+B hb䓘7ciJ&)h6B[naaN\Qϵ8BSJ!eʾ=wIKĶIJL1͉2Mn6e$&Y%C&tc\A̕rؖ-Wò^BS n.d2BLSPJd2Ƞ)eٶzWb}!CW بS^ijw/Ϭ2D&Lz;aXn,VVח0܃+bI'ɻFVH۟5;yMx}S}q? 5WT}eM]ߧkJĚȲl^/c/tJ T S/գC ѡfABۙxaBQ 'z{-aa hrR >g(-M~\SS%pZsv-<-Lm5ii߿:[&Y ;׏/QLє=83vBDE@A;KJ[D)q,[W۶Le,NoܻpUoVn|O¶y*Osqp@ճJ/:`damiNz ŧχS[2MwUT$#ixZ:'k׿lW粟uWi2e>Y;hvusG" O0ĚSS&S)lmUɉgpΜZ}!8zSioYe'N0jl(GD*9{t?Uf1CIENDB`Ext/Icons_Nuvola/0000775000000000000000000000000012606740430012717 5ustar rootrootExt/Icons_Nuvola/License.txt0000664000000000000000000006347610125245344015060 0ustar rootroot GNU LESSER GENERAL PUBLIC LICENSE Version 2.1, February 1999 Copyright (C) 1991, 1999 Free Software Foundation, Inc. 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA Everyone is permitted to copy and distribute verbatim copies of this license document, but changing it is not allowed. [This is the first released version of the Lesser GPL. It also counts as the successor of the GNU Library Public License, version 2, hence the version number 2.1.] Preamble The licenses for most software are designed to take away your freedom to share and change it. By contrast, the GNU General Public Licenses are intended to guarantee your freedom to share and change free software--to make sure the software is free for all its users. This license, the Lesser General Public License, applies to some specially designated software packages--typically libraries--of the Free Software Foundation and other authors who decide to use it. You can use it too, but we suggest you first think carefully about whether this license or the ordinary General Public License is the better strategy to use in any particular case, based on the explanations below. When we speak of free software, we are referring to freedom of use, not price. Our General Public Licenses are designed to make sure that you have the freedom to distribute copies of free software (and charge for this service if you wish); that you receive source code or can get it if you want it; that you can change the software and use pieces of it in new free programs; and that you are informed that you can do these things. To protect your rights, we need to make restrictions that forbid distributors to deny you these rights or to ask you to surrender these rights. These restrictions translate to certain responsibilities for you if you distribute copies of the library or if you modify it. For example, if you distribute copies of the library, whether gratis or for a fee, you must give the recipients all the rights that we gave you. You must make sure that they, too, receive or can get the source code. If you link other code with the library, you must provide complete object files to the recipients, so that they can relink them with the library after making changes to the library and recompiling it. And you must show them these terms so they know their rights. We protect your rights with a two-step method: (1) we copyright the library, and (2) we offer you this license, which gives you legal permission to copy, distribute and/or modify the library. To protect each distributor, we want to make it very clear that there is no warranty for the free library. Also, if the library is modified by someone else and passed on, the recipients should know that what they have is not the original version, so that the original author's reputation will not be affected by problems that might be introduced by others. Finally, software patents pose a constant threat to the existence of any free program. We wish to make sure that a company cannot effectively restrict the users of a free program by obtaining a restrictive license from a patent holder. Therefore, we insist that any patent license obtained for a version of the library must be consistent with the full freedom of use specified in this license. Most GNU software, including some libraries, is covered by the ordinary GNU General Public License. This license, the GNU Lesser General Public License, applies to certain designated libraries, and is quite different from the ordinary General Public License. We use this license for certain libraries in order to permit linking those libraries into non-free programs. When a program is linked with a library, whether statically or using a shared library, the combination of the two is legally speaking a combined work, a derivative of the original library. The ordinary General Public License therefore permits such linking only if the entire combination fits its criteria of freedom. The Lesser General Public License permits more lax criteria for linking other code with the library. We call this license the "Lesser" General Public License because it does Less to protect the user's freedom than the ordinary General Public License. It also provides other free software developers Less of an advantage over competing non-free programs. These disadvantages are the reason we use the ordinary General Public License for many libraries. However, the Lesser license provides advantages in certain special circumstances. For example, on rare occasions, there may be a special need to encourage the widest possible use of a certain library, so that it becomes a de-facto standard. To achieve this, non-free programs must be allowed to use the library. A more frequent case is that a free library does the same job as widely used non-free libraries. In this case, there is little to gain by limiting the free library to free software only, so we use the Lesser General Public License. In other cases, permission to use a particular library in non-free programs enables a greater number of people to use a large body of free software. For example, permission to use the GNU C Library in non-free programs enables many more people to use the whole GNU operating system, as well as its variant, the GNU/Linux operating system. Although the Lesser General Public License is Less protective of the users' freedom, it does ensure that the user of a program that is linked with the Library has the freedom and the wherewithal to run that program using a modified version of the Library. The precise terms and conditions for copying, distribution and modification follow. Pay close attention to the difference between a "work based on the library" and a "work that uses the library". The former contains code derived from the library, whereas the latter must be combined with the library in order to run. GNU LESSER GENERAL PUBLIC LICENSE TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION 0. This License Agreement applies to any software library or other program which contains a notice placed by the copyright holder or other authorized party saying it may be distributed under the terms of this Lesser General Public License (also called "this License"). Each licensee is addressed as "you". A "library" means a collection of software functions and/or data prepared so as to be conveniently linked with application programs (which use some of those functions and data) to form executables. The "Library", below, refers to any such software library or work which has been distributed under these terms. A "work based on the Library" means either the Library or any derivative work under copyright law: that is to say, a work containing the Library or a portion of it, either verbatim or with modifications and/or translated straightforwardly into another language. (Hereinafter, translation is included without limitation in the term "modification".) "Source code" for a work means the preferred form of the work for making modifications to it. For a library, complete source code means all the source code for all modules it contains, plus any associated interface definition files, plus the scripts used to control compilation and installation of the library. Activities other than copying, distribution and modification are not covered by this License; they are outside its scope. The act of running a program using the Library is not restricted, and output from such a program is covered only if its contents constitute a work based on the Library (independent of the use of the Library in a tool for writing it). Whether that is true depends on what the Library does and what the program that uses the Library does. 1. You may copy and distribute verbatim copies of the Library's complete source code as you receive it, in any medium, provided that you conspicuously and appropriately publish on each copy an appropriate copyright notice and disclaimer of warranty; keep intact all the notices that refer to this License and to the absence of any warranty; and distribute a copy of this License along with the Library. You may charge a fee for the physical act of transferring a copy, and you may at your option offer warranty protection in exchange for a fee. 2. You may modify your copy or copies of the Library or any portion of it, thus forming a work based on the Library, and copy and distribute such modifications or work under the terms of Section 1 above, provided that you also meet all of these conditions: a) The modified work must itself be a software library. b) You must cause the files modified to carry prominent notices stating that you changed the files and the date of any change. c) You must cause the whole of the work to be licensed at no charge to all third parties under the terms of this License. d) If a facility in the modified Library refers to a function or a table of data to be supplied by an application program that uses the facility, other than as an argument passed when the facility is invoked, then you must make a good faith effort to ensure that, in the event an application does not supply such function or table, the facility still operates, and performs whatever part of its purpose remains meaningful. (For example, a function in a library to compute square roots has a purpose that is entirely well-defined independent of the application. Therefore, Subsection 2d requires that any application-supplied function or table used by this function must be optional: if the application does not supply it, the square root function must still compute square roots.) These requirements apply to the modified work as a whole. If identifiable sections of that work are not derived from the Library, and can be reasonably considered independent and separate works in themselves, then this License, and its terms, do not apply to those sections when you distribute them as separate works. But when you distribute the same sections as part of a whole which is a work based on the Library, the distribution of the whole must be on the terms of this License, whose permissions for other licensees extend to the entire whole, and thus to each and every part regardless of who wrote it. Thus, it is not the intent of this section to claim rights or contest your rights to work written entirely by you; rather, the intent is to exercise the right to control the distribution of derivative or collective works based on the Library. In addition, mere aggregation of another work not based on the Library with the Library (or with a work based on the Library) on a volume of a storage or distribution medium does not bring the other work under the scope of this License. 3. You may opt to apply the terms of the ordinary GNU General Public License instead of this License to a given copy of the Library. To do this, you must alter all the notices that refer to this License, so that they refer to the ordinary GNU General Public License, version 2, instead of to this License. (If a newer version than version 2 of the ordinary GNU General Public License has appeared, then you can specify that version instead if you wish.) Do not make any other change in these notices. Once this change is made in a given copy, it is irreversible for that copy, so the ordinary GNU General Public License applies to all subsequent copies and derivative works made from that copy. This option is useful when you wish to copy part of the code of the Library into a program that is not a library. 4. You may copy and distribute the Library (or a portion or derivative of it, under Section 2) in object code or executable form under the terms of Sections 1 and 2 above provided that you accompany it with the complete corresponding machine-readable source code, which must be distributed under the terms of Sections 1 and 2 above on a medium customarily used for software interchange. If distribution of object code is made by offering access to copy from a designated place, then offering equivalent access to copy the source code from the same place satisfies the requirement to distribute the source code, even though third parties are not compelled to copy the source along with the object code. 5. A program that contains no derivative of any portion of the Library, but is designed to work with the Library by being compiled or linked with it, is called a "work that uses the Library". Such a work, in isolation, is not a derivative work of the Library, and therefore falls outside the scope of this License. However, linking a "work that uses the Library" with the Library creates an executable that is a derivative of the Library (because it contains portions of the Library), rather than a "work that uses the library". The executable is therefore covered by this License. Section 6 states terms for distribution of such executables. When a "work that uses the Library" uses material from a header file that is part of the Library, the object code for the work may be a derivative work of the Library even though the source code is not. Whether this is true is especially significant if the work can be linked without the Library, or if the work is itself a library. The threshold for this to be true is not precisely defined by law. If such an object file uses only numerical parameters, data structure layouts and accessors, and small macros and small inline functions (ten lines or less in length), then the use of the object file is unrestricted, regardless of whether it is legally a derivative work. (Executables containing this object code plus portions of the Library will still fall under Section 6.) Otherwise, if the work is a derivative of the Library, you may distribute the object code for the work under the terms of Section 6. Any executables containing that work also fall under Section 6, whether or not they are linked directly with the Library itself. 6. As an exception to the Sections above, you may also combine or link a "work that uses the Library" with the Library to produce a work containing portions of the Library, and distribute that work under terms of your choice, provided that the terms permit modification of the work for the customer's own use and reverse engineering for debugging such modifications. You must give prominent notice with each copy of the work that the Library is used in it and that the Library and its use are covered by this License. You must supply a copy of this License. If the work during execution displays copyright notices, you must include the copyright notice for the Library among them, as well as a reference directing the user to the copy of this License. Also, you must do one of these things: a) Accompany the work with the complete corresponding machine-readable source code for the Library including whatever changes were used in the work (which must be distributed under Sections 1 and 2 above); and, if the work is an executable linked with the Library, with the complete machine-readable "work that uses the Library", as object code and/or source code, so that the user can modify the Library and then relink to produce a modified executable containing the modified Library. (It is understood that the user who changes the contents of definitions files in the Library will not necessarily be able to recompile the application to use the modified definitions.) b) Use a suitable shared library mechanism for linking with the Library. A suitable mechanism is one that (1) uses at run time a copy of the library already present on the user's computer system, rather than copying library functions into the executable, and (2) will operate properly with a modified version of the library, if the user installs one, as long as the modified version is interface-compatible with the version that the work was made with. c) Accompany the work with a written offer, valid for at least three years, to give the same user the materials specified in Subsection 6a, above, for a charge no more than the cost of performing this distribution. d) If distribution of the work is made by offering access to copy from a designated place, offer equivalent access to copy the above specified materials from the same place. e) Verify that the user has already received a copy of these materials or that you have already sent this user a copy. For an executable, the required form of the "work that uses the Library" must include any data and utility programs needed for reproducing the executable from it. However, as a special exception, the materials to be distributed need not include anything that is normally distributed (in either source or binary form) with the major components (compiler, kernel, and so on) of the operating system on which the executable runs, unless that component itself accompanies the executable. It may happen that this requirement contradicts the license restrictions of other proprietary libraries that do not normally accompany the operating system. Such a contradiction means you cannot use both them and the Library together in an executable that you distribute. 7. You may place library facilities that are a work based on the Library side-by-side in a single library together with other library facilities not covered by this License, and distribute such a combined library, provided that the separate distribution of the work based on the Library and of the other library facilities is otherwise permitted, and provided that you do these two things: a) Accompany the combined library with a copy of the same work based on the Library, uncombined with any other library facilities. This must be distributed under the terms of the Sections above. b) Give prominent notice with the combined library of the fact that part of it is a work based on the Library, and explaining where to find the accompanying uncombined form of the same work. 8. You may not copy, modify, sublicense, link with, or distribute the Library except as expressly provided under this License. Any attempt otherwise to copy, modify, sublicense, link with, or distribute the Library is void, and will automatically terminate your rights under this License. However, parties who have received copies, or rights, from you under this License will not have their licenses terminated so long as such parties remain in full compliance. 9. You are not required to accept this License, since you have not signed it. However, nothing else grants you permission to modify or distribute the Library or its derivative works. These actions are prohibited by law if you do not accept this License. Therefore, by modifying or distributing the Library (or any work based on the Library), you indicate your acceptance of this License to do so, and all its terms and conditions for copying, distributing or modifying the Library or works based on it. 10. Each time you redistribute the Library (or any work based on the Library), the recipient automatically receives a license from the original licensor to copy, distribute, link with or modify the Library subject to these terms and conditions. You may not impose any further restrictions on the recipients' exercise of the rights granted herein. You are not responsible for enforcing compliance by third parties with this License. 11. If, as a consequence of a court judgment or allegation of patent infringement or for any other reason (not limited to patent issues), conditions are imposed on you (whether by court order, agreement or otherwise) that contradict the conditions of this License, they do not excuse you from the conditions of this License. If you cannot distribute so as to satisfy simultaneously your obligations under this License and any other pertinent obligations, then as a consequence you may not distribute the Library at all. For example, if a patent license would not permit royalty-free redistribution of the Library by all those who receive copies directly or indirectly through you, then the only way you could satisfy both it and this License would be to refrain entirely from distribution of the Library. If any portion of this section is held invalid or unenforceable under any particular circumstance, the balance of the section is intended to apply, and the section as a whole is intended to apply in other circumstances. It is not the purpose of this section to induce you to infringe any patents or other property right claims or to contest validity of any such claims; this section has the sole purpose of protecting the integrity of the free software distribution system which is implemented by public license practices. Many people have made generous contributions to the wide range of software distributed through that system in reliance on consistent application of that system; it is up to the author/donor to decide if he or she is willing to distribute software through any other system and a licensee cannot impose that choice. This section is intended to make thoroughly clear what is believed to be a consequence of the rest of this License. 12. If the distribution and/or use of the Library is restricted in certain countries either by patents or by copyrighted interfaces, the original copyright holder who places the Library under this License may add an explicit geographical distribution limitation excluding those countries, so that distribution is permitted only in or among countries not thus excluded. In such case, this License incorporates the limitation as if written in the body of this License. 13. The Free Software Foundation may publish revised and/or new versions of the Lesser General Public License from time to time. Such new versions will be similar in spirit to the present version, but may differ in detail to address new problems or concerns. Each version is given a distinguishing version number. If the Library specifies a version number of this License which applies to it and "any later version", you have the option of following the terms and conditions either of that version or of any later version published by the Free Software Foundation. If the Library does not specify a license version number, you may choose any version ever published by the Free Software Foundation. 14. If you wish to incorporate parts of the Library into other free programs whose distribution conditions are incompatible with these, write to the author to ask for permission. For software which is copyrighted by the Free Software Foundation, write to the Free Software Foundation; we sometimes make exceptions for this. Our decision will be guided by the two goals of preserving the free status of all derivatives of our free software and of promoting the sharing and reuse of software generally. NO WARRANTY 15. BECAUSE THE LIBRARY IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY FOR THE LIBRARY, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES PROVIDE THE LIBRARY "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE LIBRARY IS WITH YOU. SHOULD THE LIBRARY PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION. 16. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR REDISTRIBUTE THE LIBRARY AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE LIBRARY (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A FAILURE OF THE LIBRARY TO OPERATE WITH ANY OTHER SOFTWARE), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. END OF TERMS AND CONDITIONS How to Apply These Terms to Your New Libraries If you develop a new library, and you want it to be of the greatest possible use to the public, we recommend making it free software that everyone can redistribute and change. You can do so by permitting redistribution under these terms (or, alternatively, under the terms of the ordinary General Public License). To apply these terms, attach the following notices to the library. It is safest to attach them to the start of each source file to most effectively convey the exclusion of warranty; and each file should have at least the "copyright" line and a pointer to where the full notice is found. Copyright (C) This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this library; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA Also add information on how to contact you by electronic and paper mail. You should also get your employer (if you work as a programmer) or your school, if any, to sign a "copyright disclaimer" for the library, if necessary. Here is a sample; alter the names: Yoyodyne, Inc., hereby disclaims all copyright interest in the library `Frob' (a library for tweaking knobs) written by James Random Hacker. , 1 April 1990 Ty Coon, President of Vice That's all there is to it! Ext/Icons_Nuvola/ReadMe.txt0000664000000000000000000000471310133720402014610 0ustar rootroot++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ This copyright and license notice covers the images in this directory. Note the license notice contains an add-on. ************************************************************************ TITLE: NUVOLA ICON THEME for KDE 3.x AUTHOR: David Vignoni | ICON KING SITE: http://www.icon-king.com MAILING LIST: http://mail.icon-king.com/mailman/listinfo/nuvola_icon-king.com Copyright (c) 2003-2004 David Vignoni. This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation, version 2.1 of the License. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this library (see the the license.txt file); if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA #######**** NOTE THIS ADD-ON ****####### The GNU Lesser General Public License or LGPL is written for software libraries in the first place. The LGPL has to be considered valid for this artwork library too. Nuvola icon theme for KDE 3.x is a special kind of software library, it is an artwork library, it's elements can be used in a Graphical User Interface, or GUI. Source code, for this library means: - raster png image* . The LGPL in some sections obliges you to make the files carry notices. With images this is in some cases impossible or hardly usefull. With this library a notice is placed at a prominent place in the directory containing the elements. You may follow this practice. The exception in section 6 of the GNU Lesser General Public License covers the use of elements of this art library in a GUI. dave [at] icon-king.com Date: 15 october 2004 Version: 1.0 DESCRIPTION: Icon theme for KDE 3.x. Icons where designed using Adobe Illustrator, and then exported to PNG format. Icons shadows and minor corrections were done using Adobe Photoshop. Kiconedit was used to correct some 16x16 and 22x22 icons. LICENSE Released under GNU Lesser General Public License (LGPL) Look at the license.txt file. CONTACT David Vignoni e-mail : david [at] icon-king.com ICQ : 117761009 http: http://www.icon-king.com Docs/0000775000000000000000000000000013225117276010454 5ustar rootrootDocs/License.txt0000664000000000000000000004442613222430726012604 0ustar rootrootKeePass: Copyright (C) 2003-2018 Dominik Reichl . The software is distributed under the terms of the GNU General Public License version 2 or later. For acknowledgements and licenses of components/resources/etc., see the file 'KeePass.chm'. GNU GENERAL PUBLIC LICENSE Version 2, June 1991 Copyright (C) 1989, 1991 Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA Everyone is permitted to copy and distribute verbatim copies of this license document, but changing it is not allowed. Preamble The licenses for most software are designed to take away your freedom to share and change it. By contrast, the GNU General Public License is intended to guarantee your freedom to share and change free software--to make sure the software is free for all its users. This General Public License applies to most of the Free Software Foundation's software and to any other program whose authors commit to using it. (Some other Free Software Foundation software is covered by the GNU Lesser General Public License instead.) You can apply it to your programs, too. When we speak of free software, we are referring to freedom, not price. Our General Public Licenses are designed to make sure that you have the freedom to distribute copies of free software (and charge for this service if you wish), that you receive source code or can get it if you want it, that you can change the software or use pieces of it in new free programs; and that you know you can do these things. To protect your rights, we need to make restrictions that forbid anyone to deny you these rights or to ask you to surrender the rights. These restrictions translate to certain responsibilities for you if you distribute copies of the software, or if you modify it. For example, if you distribute copies of such a program, whether gratis or for a fee, you must give the recipients all the rights that you have. You must make sure that they, too, receive or can get the source code. And you must show them these terms so they know their rights. We protect your rights with two steps: (1) copyright the software, and (2) offer you this license which gives you legal permission to copy, distribute and/or modify the software. Also, for each author's protection and ours, we want to make certain that everyone understands that there is no warranty for this free software. If the software is modified by someone else and passed on, we want its recipients to know that what they have is not the original, so that any problems introduced by others will not reflect on the original authors' reputations. Finally, any free program is threatened constantly by software patents. We wish to avoid the danger that redistributors of a free program will individually obtain patent licenses, in effect making the program proprietary. To prevent this, we have made it clear that any patent must be licensed for everyone's free use or not licensed at all. The precise terms and conditions for copying, distribution and modification follow. GNU GENERAL PUBLIC LICENSE TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION 0. This License applies to any program or other work which contains a notice placed by the copyright holder saying it may be distributed under the terms of this General Public License. The "Program", below, refers to any such program or work, and a "work based on the Program" means either the Program or any derivative work under copyright law: that is to say, a work containing the Program or a portion of it, either verbatim or with modifications and/or translated into another language. (Hereinafter, translation is included without limitation in the term "modification".) Each licensee is addressed as "you". Activities other than copying, distribution and modification are not covered by this License; they are outside its scope. The act of running the Program is not restricted, and the output from the Program is covered only if its contents constitute a work based on the Program (independent of having been made by running the Program). Whether that is true depends on what the Program does. 1. You may copy and distribute verbatim copies of the Program's source code as you receive it, in any medium, provided that you conspicuously and appropriately publish on each copy an appropriate copyright notice and disclaimer of warranty; keep intact all the notices that refer to this License and to the absence of any warranty; and give any other recipients of the Program a copy of this License along with the Program. You may charge a fee for the physical act of transferring a copy, and you may at your option offer warranty protection in exchange for a fee. 2. You may modify your copy or copies of the Program or any portion of it, thus forming a work based on the Program, and copy and distribute such modifications or work under the terms of Section 1 above, provided that you also meet all of these conditions: a) You must cause the modified files to carry prominent notices stating that you changed the files and the date of any change. b) You must cause any work that you distribute or publish, that in whole or in part contains or is derived from the Program or any part thereof, to be licensed as a whole at no charge to all third parties under the terms of this License. c) If the modified program normally reads commands interactively when run, you must cause it, when started running for such interactive use in the most ordinary way, to print or display an announcement including an appropriate copyright notice and a notice that there is no warranty (or else, saying that you provide a warranty) and that users may redistribute the program under these conditions, and telling the user how to view a copy of this License. (Exception: if the Program itself is interactive but does not normally print such an announcement, your work based on the Program is not required to print an announcement.) These requirements apply to the modified work as a whole. If identifiable sections of that work are not derived from the Program, and can be reasonably considered independent and separate works in themselves, then this License, and its terms, do not apply to those sections when you distribute them as separate works. But when you distribute the same sections as part of a whole which is a work based on the Program, the distribution of the whole must be on the terms of this License, whose permissions for other licensees extend to the entire whole, and thus to each and every part regardless of who wrote it. Thus, it is not the intent of this section to claim rights or contest your rights to work written entirely by you; rather, the intent is to exercise the right to control the distribution of derivative or collective works based on the Program. In addition, mere aggregation of another work not based on the Program with the Program (or with a work based on the Program) on a volume of a storage or distribution medium does not bring the other work under the scope of this License. 3. You may copy and distribute the Program (or a work based on it, under Section 2) in object code or executable form under the terms of Sections 1 and 2 above provided that you also do one of the following: a) Accompany it with the complete corresponding machine-readable source code, which must be distributed under the terms of Sections 1 and 2 above on a medium customarily used for software interchange; or, b) Accompany it with a written offer, valid for at least three years, to give any third party, for a charge no more than your cost of physically performing source distribution, a complete machine-readable copy of the corresponding source code, to be distributed under the terms of Sections 1 and 2 above on a medium customarily used for software interchange; or, c) Accompany it with the information you received as to the offer to distribute corresponding source code. (This alternative is allowed only for noncommercial distribution and only if you received the program in object code or executable form with such an offer, in accord with Subsection b above.) The source code for a work means the preferred form of the work for making modifications to it. For an executable work, complete source code means all the source code for all modules it contains, plus any associated interface definition files, plus the scripts used to control compilation and installation of the executable. However, as a special exception, the source code distributed need not include anything that is normally distributed (in either source or binary form) with the major components (compiler, kernel, and so on) of the operating system on which the executable runs, unless that component itself accompanies the executable. If distribution of executable or object code is made by offering access to copy from a designated place, then offering equivalent access to copy the source code from the same place counts as distribution of the source code, even though third parties are not compelled to copy the source along with the object code. 4. You may not copy, modify, sublicense, or distribute the Program except as expressly provided under this License. Any attempt otherwise to copy, modify, sublicense or distribute the Program is void, and will automatically terminate your rights under this License. However, parties who have received copies, or rights, from you under this License will not have their licenses terminated so long as such parties remain in full compliance. 5. You are not required to accept this License, since you have not signed it. However, nothing else grants you permission to modify or distribute the Program or its derivative works. These actions are prohibited by law if you do not accept this License. Therefore, by modifying or distributing the Program (or any work based on the Program), you indicate your acceptance of this License to do so, and all its terms and conditions for copying, distributing or modifying the Program or works based on it. 6. Each time you redistribute the Program (or any work based on the Program), the recipient automatically receives a license from the original licensor to copy, distribute or modify the Program subject to these terms and conditions. You may not impose any further restrictions on the recipients' exercise of the rights granted herein. You are not responsible for enforcing compliance by third parties to this License. 7. If, as a consequence of a court judgment or allegation of patent infringement or for any other reason (not limited to patent issues), conditions are imposed on you (whether by court order, agreement or otherwise) that contradict the conditions of this License, they do not excuse you from the conditions of this License. If you cannot distribute so as to satisfy simultaneously your obligations under this License and any other pertinent obligations, then as a consequence you may not distribute the Program at all. For example, if a patent license would not permit royalty-free redistribution of the Program by all those who receive copies directly or indirectly through you, then the only way you could satisfy both it and this License would be to refrain entirely from distribution of the Program. If any portion of this section is held invalid or unenforceable under any particular circumstance, the balance of the section is intended to apply and the section as a whole is intended to apply in other circumstances. It is not the purpose of this section to induce you to infringe any patents or other property right claims or to contest validity of any such claims; this section has the sole purpose of protecting the integrity of the free software distribution system, which is implemented by public license practices. Many people have made generous contributions to the wide range of software distributed through that system in reliance on consistent application of that system; it is up to the author/donor to decide if he or she is willing to distribute software through any other system and a licensee cannot impose that choice. This section is intended to make thoroughly clear what is believed to be a consequence of the rest of this License. 8. If the distribution and/or use of the Program is restricted in certain countries either by patents or by copyrighted interfaces, the original copyright holder who places the Program under this License may add an explicit geographical distribution limitation excluding those countries, so that distribution is permitted only in or among countries not thus excluded. In such case, this License incorporates the limitation as if written in the body of this License. 9. The Free Software Foundation may publish revised and/or new versions of the General Public License from time to time. Such new versions will be similar in spirit to the present version, but may differ in detail to address new problems or concerns. Each version is given a distinguishing version number. If the Program specifies a version number of this License which applies to it and "any later version", you have the option of following the terms and conditions either of that version or of any later version published by the Free Software Foundation. If the Program does not specify a version number of this License, you may choose any version ever published by the Free Software Foundation. 10. If you wish to incorporate parts of the Program into other free programs whose distribution conditions are different, write to the author to ask for permission. For software which is copyrighted by the Free Software Foundation, write to the Free Software Foundation; we sometimes make exceptions for this. Our decision will be guided by the two goals of preserving the free status of all derivatives of our free software and of promoting the sharing and reuse of software generally. NO WARRANTY 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION. 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. END OF TERMS AND CONDITIONS How to Apply These Terms to Your New Programs If you develop a new program, and you want it to be of the greatest possible use to the public, the best way to achieve this is to make it free software which everyone can redistribute and change under these terms. To do so, attach the following notices to the program. It is safest to attach them to the start of each source file to most effectively convey the exclusion of warranty; and each file should have at least the "copyright" line and a pointer to where the full notice is found. Copyright (C) This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. Also add information on how to contact you by electronic and paper mail. If the program is interactive, make it output a short notice like this when it starts in an interactive mode: Gnomovision version 69, Copyright (C) year name of author Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'. This is free software, and you are welcome to redistribute it under certain conditions; type `show c' for details. The hypothetical commands `show w' and `show c' should show the appropriate parts of the General Public License. Of course, the commands you use may be called something other than `show w' and `show c'; they could even be mouse-clicks or menu items--whatever suits your program. You should also get your employer (if you work as a programmer) or your school, if any, to sign a "copyright disclaimer" for the program, if necessary. Here is a sample; alter the names: Yoyodyne, Inc., hereby disclaims all copyright interest in the program `Gnomovision' (which makes passes at compilers) written by James Hacker. , 1 April 1989 Ty Coon, President of Vice This General Public License does not permit incorporating your program into proprietary programs. If your program is a subroutine library, you may consider it more useful to permit linking proprietary applications with the library. If this is what you want to do, use the GNU Lesser General Public License instead of this License. Docs/History.txt0000664000000000000000000050412313224757714012671 0ustar rootroot2018-01-09: 2.38 - The installers (regular and MSI) now create an empty 'Languages' folder in the application directory, and the portable package now also contains such a folder; language files should now be stored in this folder - Added button 'Open Folder' in the language selection dialog, which opens the 'Languages' folder - Added button 'Open Folder' in the plugins dialog, which opens the 'Plugins' folder - Added a runtime activation policy setting (to improve compatibility with Microsoft User Experience Virtualization) - Added option 'Icon' and an option for specifying the placeholder behavior (replace or not, or both forms) in the 'Print' / HTML export dialog - Printing / HTML export: the notes of a group are now displayed below the group name - Enhanced the Password Exporter import module to support XML files created by version 1.3.4 - Added workaround for Microsoft Office breaking the 'Print' shell verb for HTML files - Added workaround for Mono list view item deletion bug - Added workaround for Mono command line argument encoding bug - KPScript: the 'AddEntry' and 'EditEntry' commands now support the '-setx-Icon' and '-setx-CustomIcon' parameters, which set the icon of the entry - KPScript: the 'ChangeMasterKey' command now supports the '-newpw-enc' parameter (for specifying the new master password in encrypted form, compatible with the {PASSWORD_ENC} placeholder) - KPScript: the 'ListEntries' command now supports all '-ref-*' and '-refx-*' parameters - Password quality estimation: improved compatibility with process memory protection - Improved UI scaling when using KeePass on multiple systems with different DPI values - Printing / HTML export: improved embedding of CSS - Printing / HTML export: spaces in passwords are now encoded as non-breaking spaces - Improved UI updating in the 'Print' / HTML export dialog - Enhanced KDE system font detection - Improved fatal error handling - Various improvements in the language selection dialog - KPScript: improved behavior of '-ref-*' parameters when combined with the '-refx-All' option - Various code optimizations - Minor other improvements - Fixed HTML generation bug: when the option 'Use monospace font for passwords' was turned off, a generated HTML file in 'Details' mode could contain invalid end tags 2017-10-12: 2.37 - When creating a new database, KeePass now offers to print a KeePass emergency sheet (which can then be filled out and stored in a secure location, where only the user and possibly a few other people that the user trusts have access to); an emergency sheet can also be created via 'Tools' -> 'Database Tools' -> 'Print Emergency Sheet' - Added database file information dialog that is displayed when creating a new database - Added function to search similar password clusters ('Edit' -> 'Show Entries' -> 'Find Similar Passwords (Clusters)') - On Unix-like systems: if the library 'libgcrypt.so.20' is available, KeePass uses it for AES-KDF transformations - Enhanced PrepMonoDev.sh script to upgrade a DTD processing definition - Added workaround for .NET/Windows column header drawing bug when switching to TAN-only entry list mode - Added workaround for Mono tab switching bug - Added workaround for Mono '}' character RTF encoding bug - TrlUtil: added support for .NET 4.* - Improved dialog for changing the master key (key file and user account are now expert options, added more information and links to help page sections) - KeePass now directly offers to save the database after changing the master key, and it asks whether to print a new emergency sheet - Various improvements in the translation selection dialog (the selected translation can now be activated by pressing Return, the list view now uses the Explorer style, ...) - KeePass now refuses to attach files that are larger than 512 MB (as larger files can result in serialization problems) - Increased default number of AES-KDF rounds - On Unix-like systems, KeePass now uses the CSP implementation of the AES algorithm for encrypting data, which is a bit faster - Improved tool strip checkmark rendering on Unix-like systems - Updated links (to the website, help pages, etc.) - The MSI file is now built using Visual Studio 2017 - Various code optimizations - Minor other improvements 2017-06-09: 2.36 - Added commands 'Find Duplicate Passwords' and 'Find Similar Passwords' (in 'Edit' -> 'Show Entries'), which show entries that are using the same or similar passwords - Added command 'Password Quality Report' (in 'Edit' -> 'Show Entries'), which shows all entries and the estimated quality of their passwords - Added option 'String name' in the 'Edit' -> 'Find' dialog (for searching entries that have a specific custom string field) - Added option for using a gray tray icon - Added {CMD:/.../} placeholder, which runs a command line - Added {T-CONV:/.../Raw/} placeholder, which inserts a text without encoding it for the current context - Added optional 'Last Password Modification Time (Based on History)' entry list column - The internal text editor now supports editing PS1 files - The position and size of the internal data viewer is now remembered and restored - For various dialogs, the maximized state is now remembered and restored - Added configuration option for specifying an expiry date for master keys - Added configuration option for specifying disallowed auto-type target windows - Added workaround for Edge throwing away all keyboard input for a short time after its activation - Added workaround for Mono not properly rendering bold and italic text in rich text boxes - TrlUtil now performs a case-sensitive word validation - The password input controls in the IO connection dialog and the proxy dialog now are secure edit controls - The icon of the 'Save' command in the main menu is now grayed out when there are no database changes (like the toolbar button) - Auto-Type: improved support for target applications that redirect the focus immediately - Auto-Type: improved compatibility with VMware vSphere client - When an error occurs during auto-type, KeePass is now brought to the foreground before showing an error message box - Entries in groups where searching is disabled (e.g. the recycle bin group) are now ignored by the commands that show expired entries - Improved scrolling when moving entries while grouping in the entry list is on - Improved support for right-to-left writing systems - Improved application and system tray icon handling - Updated low resolution ICO files (for Mono development) - Moved single-click tray icon action option from the 'Integration' tab to the 'Interface' tab of the options dialog - Synchronization file path comparisons are case-insensitive now - Improved workaround for Mono clipboard bug (improved performance and window detection; the workaround is now applied only if 'xsel' and 'xdotool' are installed) - Enhanced PrepMonoDev.sh script - KPScript: times in group and entry lists now contain a time zone identifier (typically 'Z' for UTC) - Various code optimizations - Minor other improvements - The drop-down menu commands in the entry editing dialog for setting the expiry date now work as expected 2017-01-09: 2.35 - New KDBX 4 file format, which supports various new features (listed below; e.g. Argon2) - Added Argon2 key derivation function (it can be activated in the database settings dialog) - Improved header and data authentication in KDBX 4 files (using HMAC-SHA-256, Encrypt-then-MAC scheme) - Added ChaCha20 (RFC 7539) encryption algorithm (it can be activated as KDBX file encryption algorithm in the database settings dialog; furthermore, it supersedes Salsa20 as default for generating the inner random stream of KDBX 4 files) - Added support for opening entry URLs with Firefox or Opera in private mode via the context menu -> 'URL(s)' -> 'Open with ... (Private)' - Added URL override suggestions for Firefox and Opera in private mode in the URL override suggestions drop-down list in the entry dialog - Added optional built-in global URL overrides for opening HTTP/HTTPS URLs with Firefox or Opera in private mode - Added {PICKFIELD} placeholder, which shows a dialog to pick a field whose value will be inserted - Added option 'Hide "Close Database" toolbar button when at most one database is opened' (turned on by default) - Added option 'Show additional auto-type menu commands', which can be turned on to show menu commands for performing entry auto-type with some specific sequences - Added menu command 'Selected Entry's Group' (with keyboard shortcut Ctrl+G) in 'Edit' -> 'Show Entries' (and a context menu equivalent 'Show Parent Group' in 'Selected Entries'), which opens the parent group of the currently selected entry and selects the entry again - Added menu commands in 'Edit' -> 'Show Entries' to show entries that expire in a specific number of days (1, 2, 3) or weeks (1, 2, 4, 8) or in the future - Added configuration option that specifies the number of days within which entries are considered to expire 'soon' (the default is 7) - Added option for changing the alternate item background color - When the option 'Remember key sources' is enabled, KeePass now also remembers whether a master password has been used - Added option 'Force changing the master key the next time (once)' (in 'File' -> 'Database Settings' -> tab 'Advanced') - Added parameters 'Window style' and 'Verb' for the 'Execute command line / URL' trigger action - Added support for importing mSecure 3.5.5 CSV files - Added support for importing Password Saver 4.1.2 XML files - Added support for importing Enpass 5.3.0.1 TXT files - Enhanced SplashID CSV import (added support for the old version 3.4, added mappings for types of the latest version, groups are now created only for categories, and types are imported as tags) - LastPass import: added support for CSV files exported by the LastPass Chrome extension, which encodes some special characters as XML entities - Added 'KeePass KDBX (2.34, Old Format)' export module - Export using XSL transformation: added support for the 'xsl:output' element in XSL files - If the global auto-type hot key is Ctrl+Alt+A and the current input locale is Polish, KeePass now shows a warning dialog (telling the user that Ctrl+Alt+A is in conflict with a system key combination producing a character) - Added Alt+X Unicode character conversion support in rich text boxes on Unix-like systems - For development snapshots, the 'About' dialog now shows the snapshot version (in the form 'YYMMDD') - Plugins can provide other key derivation functions now - The header of KDBX 4 files is extensible by plugins - Enhanced support for developing encryption algorithm plugins - Plugins can now store custom data in groups and entries - Plugin data stored in the database, a group or an entry can now be inspected (and deleted) in the database maintenance dialog, the group dialog and the entry dialog, respectively - For plugins: file closing events now contain information about whether KeePass is exiting, locking or performing a trigger action - Added workaround for .NET handle cast overflow bug in InputLanguage.Culture - Added workaround for Mono ignoring the Ctrl+I shortcut - Added workaround for Mono clipboard bug - Added workaround for Mono not focusing the default control in the entry editing dialog - Added workaround for a Mono timer bug that caused high CPU load while showing a file save confirmation dialog - Added Mono workaround: when running on Mac OS X, KeePass now does not try to instantiate a tray icon anymore - Added workaround for XDoTool sending diacritic characters in incorrect case - TrlUtil now recommends to clear the 'Unused Text' tab - Improved behavior when searching entries with exclusions (terms prefixed with '-') - Improved support for auto-typing into target windows using different keyboard layouts - Auto-Type: improved support for keyboard layouts with keys where Shift, Caps Lock and no modifier result in 3 different characters - Auto-Type: improved support for spacing modifier letters (U+02B0 to U+02FF) - Global auto-type now works with target windows having empty titles - When copying entries to the clipboard, the data package now includes custom icons used by the entries - Unified behavior when drag&dropping a field containing a placeholder - Improved entry edit confirmation dialog - If the screen height is insufficient to display a dialog, the dialog's banner (if the dialog has one) is now removed to save some space - Some tooltips are now displayed for a longer time - A new entry created using a template now does not include the history of the template anymore - For empty RTF attachments, the internal data editor now by default uses the font that is specified for TXT files - Internal data editor: added support for changing the format of mixed-format selections - Internal data viewer and editor: null characters ('\0', not '0') in texts are now automatically replaced by spaces (like Notepad on Windows 10) - Improved encoding signature handling for conversions during text attachment imports (via the 'Text Encoding' dialog) - File transactions are not used anymore for files that have a reparse point (e.g. symbolic links) - Improved XSL stylesheets for KDBX XML files - The internal window manager is now thread-safe - Improved date/time handling - Improved button image disposal - When synchronizing two databases, custom data (by plugins) is now merged - When opening a database file, corrupted icon indices are now automatically replaced by default values - Added some more entropy sources for the seed of the cryptographically secure pseudo-random number generator (environment variables, command line, full operating system version, current culture) - ChaCha20 is now used during password generation (instead of Salsa20) - ChaCha20 is now used as fallback process memory encryption algorithm (instead of Salsa20) - When the encryption algorithm for a database file is unknown, the error message now shows the UUID of the algorithm - In KDBX 4, header field lengths are now 4 bytes wide - In KDBX 4, entry attachments are now stored in an inner, binary header (encrypted, possibly compressed), before the XML part; this reduces the database file size and improves the loading/saving performance - In KDBX 4, the inner random stream cipher ID and key (to support process memory protection) are now stored in the inner header instead of in the outer header - KPScript: the 'ChangeMasterKey' command now also updates the master key change date - TrlUtil: improved validation warning dialogs - The MSI file now requires any .NET Framework version, not a specific one - The MSI file is now built using Visual Studio 2015 - Various code optimizations - Minor other improvements - When executing a {HMACOTP} placeholder, the last modification time of the corresponding entry is now updated - Key files containing exactly 64 alphanumeric characters are now loaded as intended 2016-06-11: 2.34 - The version information file (which the optional update check downloads to see if there exists a newer version) is now digitally signed (using RSA-4096 / SHA-512); furthermore, it is downloaded over HTTPS - Added option 'Lock workspace when minimizing main window to tray' - Added option 'Esc minimizes to tray instead of locking the workspace' - Added Ctrl+Q shortcut for closing KeePass (as alternative to Alt+F4) - Added UIFlags bit for disabling the 'Check for Updates' menu item - The installers (regular and MSI) now create an empty 'Plugins' folder in the application directory, and the portable package now also contains such a folder - Plugins: added support for digitally signed version information files - Plugins are now loaded only directly from the application directory and from any subdirectory of the 'Plugins' folder in the application directory - Improved startup performance (by filtering plugin candidates) - When closing a database, KeePass now searches and deletes any temporary files that may have been created and forgotten by MSHTML when printing failed - CHM help file: improved high DPI support - Various code optimizations - Minor other improvements 2016-05-07: 2.33 - Added commands in the group context menu (under 'Rearrange'): 'Expand Recursively' and 'Collapse Recursively' - Added option 'When selecting an entry, automatically select its parent group, too' (turned on by default) - Added placeholders for data of the group that is currently selected in the main window: {GROUP_SEL}, {GROUP_SEL_PATH} and {GROUP_SEL_NOTES} - While importing/synchronizing, indeterminate progress is now displayed on the taskbar button (on Windows 7 and higher) - Added optional parameters 'Filter - Group' and 'Filter - Tag' for the 'Export active database' trigger action - Pressing the Escape key in the main window now locks the workspace (independent of the current database locking state, in contrast to Ctrl+L) - Added option 'Extra-safe file transactions' in 'Tools' -> 'Options' -> tab 'Advanced' - Added customization option to specify how often the master key dialog appears when entering incorrect master keys - Plugins: added event 'FormLoadPost' for the main window - KPScript: the 'GetEntryString' command now supports the '-Spr' option, which causes KPScript to Spr-compile the field value (i.e. placeholders are replaced, field references are resolved, environment variables are inserted, etc.) - Improved database synchronization performance - Improved object reordering during a database synchronization for new and relocated groups/entries - Improved synchronization of deleted objects information - Improved database synchronization to prevent implicit object deletions - HTML export/printing: the notes column now is twice as wide as the other columns - When entering a Spr-variant password in the entry dialog, the quality estimation is now disabled - Group tooltips are now displayed for about 30 seconds - The root group is now always expanded when opening a database - Improved private mode browser detection - Improved DPI awareness declaration (on Windows 10 and higher) - Improved regular expression searching performance in usual use cases - Improved natural string comparison performance (on Unix-like systems) - Improved mnemonic characters in the 'Rearrange' menus - Upgraded installer - Various UI text improvements - Various code optimizations - Minor other improvements 2016-03-09: 2.32 - The quick search box (in the toolbar of the main window) now supports searching using a regular expression; in order to indicate that the search text is a regular expression, enclose it in '//'; for example, performing a quick search for '//Michael|Adam//' shows all entries containing 'Michael' or 'Adam' - Added 'Advanced' tab in the 'Open From URL' dialog (easily extensible by plugins); added options: timeout, pre- authenticate, HTTP/HTTPS/WebDAV user agent and 100-Continue behavior, FTP passive mode - Added per-user Start Menu Internet Application detection - When selecting an entry in the main entry list, its parent group is now selected automatically in the group tree view - Auto-Type matching: added option 'Expired entries can match' (turned off by default, i.e. expired entries are ignored) - Added option 'Always show global auto-type entry selection dialog' (to show the dialog even when no or one entry is found for the currently active target window; turned off by default) - Added {GROUP_NOTES} placeholder - Added support for importing nPassword 1.0.2.41 NPW files - In triggers and KPScript, an import/export module can now be specified both using its display name and its format name - When running under .NET 4.5 or higher, secure connections (e.g. for WebDAV) now support TLS 1.1 and TLS 1.2 (in addition to SSL 3 and TLS 1.0) - Added Mono workaround: when running on the Unity or Pantheon desktop, KeePass now does not try to instantiate a tray icon anymore; if you want a tray icon on Unity/Pantheon, use the application indicator plugin - Added workaround for Mono not implementing the property SystemInformation.SmallIconSize for Mac OS X systems - Added command line parameter '-wa-disable:' for disabling specific Mono workarounds (IDs separated by commas) - KPScript: if the value of a '-ref-*:' parameter is enclosed in '//', it is now treated as a regular expression, which must occur in the entry field for an entry to match - KPScript: .NET 4.0/4.5 is now preferred, if installed - KPScript: enhanced high DPI support - Auto-Type: improved compatibility with target windows that handle activation slowly and ignore any input until being ready (like Microsoft Edge) - Auto-Type: improved sending of characters that are typically realized with the AltGr key - When editing a custom entry string, the value text box now has the initial focus - Improved image/icon shrinking - Improved icon recoloring on high DPI resolutions - Changed some ICO files such that higher resolution images are used - Changed some PNG files to workaround the image DPI scaling behavior on Windows XP - Improved new-line filtering in the main entry view - When trying to use the Windows user account as part of a composite master key fails, a more detailed error message is displayed now - The 'About' dialog now indicates whether the current build is a development snapshot - Changed code signing certificate - Upgraded installer - Various code optimizations - Minor other improvements - After an incomplete drag&drop operation over the group tree view, the previous group selection is now restored 2016-01-09: 2.31 - Added menu/toolbar styles, freely selectable in 'Tools' -> 'Options' -> tab 'Interface'; available styles are 'Windows 10', 'Windows 8.1', 'KeePass - Gradient', '.NET/Office - Professional' and 'System - Classic'; by default KeePass uses the style most similar to the one of the current operating system - Refined application icons (thanks to Victor Andreyenkov) - Auto-Type: new target window classification method, which improves compatibility with target windows hosted within other windows (e.g. a PuTTY window within SuperPuTTY/MTPuTTY) - Auto-Type: added workaround for the default Ctrl+Alt behavior of KiTTY variants (which differs from Windows' behavior) - Before clearing the clipboard, KeePass now first copies a non-sensitive text into it; this ensures that no sensitive information remains in the clipboard even when clearing is prevented by the environment (e.g. when running in a virtual machine, when using a clipboard extension utility, ...) - Added support for opening entry URLs with Internet Explorer or Google Chrome in private mode via the context menu -> 'URL(s)' -> 'Open with ... (Private)' - Added URL override suggestions for Internet Explorer and Google Chrome in private mode in the URL override suggestions drop-down list in the entry dialog - Added optional built-in global URL overrides for opening HTTP/HTTPS URLs with Internet Explorer or Google Chrome in private mode - Added Ctrl+K shortcut for the 'Duplicate Entry' command - Mozilla Bookmarks HTML import: added support for importing tags - Added support for exporting to Mozilla Bookmarks HTML files - Windows/IE favorites export: entry fields are Spr-compiled now, and entries with cmd:// URLs are now exported as LNK files - HTML export/printing: added support for UUIDs, added horizontal lines between entries in details mode, added background color for group headings, long field names are hyphenated now, and long field data now breaks and wraps onto the next line - Plugins: added possibility to configure file transactions for each URI scheme - Plugins: added possibility to provide custom 'Save As' dialogs more easily - Converted some PNG images as a workaround for a problem in Cairo/LibPNG on Unix-like systems - As a workaround for a weakness in Mono's FileDialog, before showing such a dialog on Unix-like systems KeePass now tries to load the file '~/.recently-used' and deletes it, if it is not a valid XML file - KPScript: added support for specifying the master password in encrypted form using the '-pw-enc:' command line parameter (exactly like in KeePass, compatible with the {PASSWORD_ENC} placeholder) - KPScript: the 'Export' command now supports the optional '-GroupPath:' parameter (to export a specific group instead of the whole database) - KPScript: the 'GetEntryString' command now supports the '-FailIfNoEntry' option - KPScript: added '-refx-Expires' and '-refx-Expired' entry identification parameters - KPScript: the 'Import' command now prints more specific error messages - All KeePass program binaries are now dual signed using SHA-1 and SHA-256 - Auto-Type: improved keyboard layout handling when the target window changes during an auto-type process - Auto-Type: improved compatibility with Remote Desktop Connection client and VirtualBox - Improved icon recoloring - Improved printing of dates/times and tags - The password generator based on a character set now ensures that the generated password is Spr-invariant - Password generator based on a pattern or a custom algorithm: when a Spr-variant password is generated, a confirmation dialog for accepting this password is displayed - If the 'Save Database' policy prevents saving, the auto-save option is now ignored - Improved .NET Framework version detection - PLGX debugging: when the command line option '-debug' is passed and a PLGX plugin fails to compile, the output of all tried compilers is saved to a temporary file - Improved file transaction creation time handling on Unix-like systems - Improved compatibility with Mono on BSD systems - Enhanced PrepMonoDev.sh script for compatibility with Mono 4.x - Removed KeePassLibSD sub-project (a KeePass library for Pocket PC / Windows Mobile) from the main solution - Upgraded installer - Various code optimizations - Minor other improvements - When running under Mono (Linux, Mac OS X, ...), two options related to window minimization are disabled now (because they do not work properly due to a Mono bug) 2015-08-09: 2.30 - When opening a database via an URL fails, the error message dialog now has a button 'Specify different server credentials' (on Windows Vista and higher) - Added support for opening entry URLs with Microsoft Edge via the context menu -> 'URL(s)' -> 'Open with Edge' - Added URL override suggestion for Microsoft Edge in the URL override suggestions drop-down list in the entry dialog - Added optional built-in global URL overrides for opening HTTP/HTTPS URLs with Microsoft Edge - When clicking on a group link in the entry view, KeePass now ensures that the group is visible in the group tree - The main window is now moved onto the primary screen when it is restored outside all screens - KDBX loader: added support for non-empty protected binary value reference elements - Plugins: added two auto-type sequence query events - Added workaround for Mono drawing bug when scrolling a rich text box - When running under Mono, some automatic locking options are now disabled (because Mono doesn't implement the required events) - The installer now prevents running the installer while it is already running - KPScript: added '-GroupPath:' parameter (for specifying the full path of a group) - KPScript: the 'MoveEntry' command now also supports the '-GroupName:' parameter (as alternative to '-GroupPath:') - KPScript: added support for specifying the path of an XSL stylesheet file using the command line parameter '-XslFile:' - KPScript: the 'ListGroups' command now also outputs the parent group UUID for each group - KPScript: the parameters for specifying new field data (for the 'AddEntry' and the 'EditEntry' command) now support escape sequences (e.g. '\n' is replaced by a new-line character) - The 'Synchronize' file dialog now shows only KDBX files by default - In the 'Attachments (Count)' column, only non-zero counts are shown now - Improved MRU item refreshes - The entry string dialog now supports changing the case of a string name - The entry string dialog now does not allow adding a string whose name differs from another existing string name in this entry only by case - The entry view in the main window is now updated immediately after pressing Ctrl+H or Ctrl+J - The KDB import module now tries to round any invalid date/time to the nearest valid date/time - XML serializers are now loaded/created at KeePass startup in order to avoid a problem when shutting down Windows and KeePass.XmlSerializers.dll not being present - Changed tab bar behavior in the options dialog to avoid a tab content cropping issue caused by plugins - Improved workaround for Mono splitter bug - Upgraded installer - Various performance improvements - Various code optimizations - Minor other improvements 2015-04-10: 2.29 - Added high resolution icons - Added support for high resolution custom icons - Added option in the proxy configuration dialog to use the user's default credentials (provided by the system) - {FIREFOX} placeholder: if no regular Firefox is installed, KeePass now looks for Firefox ESR - {PICKCHARS} placeholder: the Conv-Fmt option now supports all combinations of '0', 'A', 'a' and '?'; '?' skips a combobox item - Added {BEEP X Y} auto-type command (where X is the frequency in hertz and Y the duration in milliseconds) - Added optional 'Attachments (Count)' entry list column - Added Ctrl+Insert shortcut as alternative for Ctrl+C in the entry list of the main window - Added shortcut keys for 'Copy Entries' (Ctrl+Shift+C) and 'Paste Entries' (Ctrl+Shift+V) - Added some access keys in various dialogs - In the field reference dialog, the field in which the reference will be inserted is now selected as source field by default - Added UUID uniqueness check - Added support for importing Passphrase Keeper 2.60 HTML files (in addition to the already supported 2.50 and 2.70 formats) - The path of the local configuration file can now be changed using the '-cfg-local:' command line parameter - Plugins can now access the KeePass resources (images, icons, etc.) through the IPluginHost interface - Added a few workarounds for external window manipulations before the main window has been fully constructed - Added workaround for .NET gradient drawing bug; 'Blue Carbon' dialog banners are now drawn correctly on high DPI - Added workaround for Mono file version information block generation bug - KPScript: added 'EstimateQuality' command (to estimate the quality of a specified password) - All KeePass program binaries are now digitally signed (thanks to Certum/Unizeto) - In the master key creation dialog, the 'Create' and 'Browse' buttons are now disabled when a key provider is selected - Changed behavior of the 'Use system proxy settings' option (KeePass now directly gets the system proxy settings, not the .NET default proxy settings) - Improved focus restoration after closing the character picking dialog - Removed 'O' and 'C' access keys from 'OK' and 'Cancel' buttons (instead, press Enter for 'OK' and Esc for 'Cancel') - Improved remembering of splitter positions - Improved assignments of check mark images to menu items - Improved behavior when synchronizing a local EFS-encrypted database file with a local database file - On Unix-like systems, hot key boxes now show 'External' instead of 'None' - Various code optimizations - Minor other improvements - AltGr+E (i.e. Ctrl+Alt+E) does not focus the quick search box anymore 2014-10-08: 2.28 - Enhanced high DPI support - Added trigger action 'Show message box' (which can abort the current trigger execution or execute a command line / URL) - The 'Database has unsaved changes' trigger condition now supports choosing between the active database and the database that triggered the event - Added parameter for the trigger action 'Activate database (select tab)' that allows activating the database that triggered the event - Auto-Type: added workaround for KiTTY's default Ctrl+Alt behavior (which differs from Windows' behavior) - Auto-Type: added workaround for PuTTYjp's default Ctrl+Alt behavior (which differs from Windows' behavior) - Added up/down arrow buttons for reordering auto-type associations in the entry editing dialog - While entering the master key on a secure desktop, dimmed screenshots are now also displayed on all non-primary screens - Added support for importing VisKeeper 3.3.0 TXT files - The group tree view is now saved and restored during most group tree updates - In the main entry list, multiple entries can now be moved by one step up/down at once - If Caps Lock is on, a balloon tip indicating this is now also displayed for password text boxes immediately after opening a dialog (where the password text box is the initially focused control) - In the cases where Windows would display outdated thumbnail and peek preview images for the main window, KeePass now requests Windows to use a static bitmap instead (showing only the KeePass logo) - Added fallback method for parsing dates/times (the default parser fails for some custom formats specified in the Control Panel) - Added workaround for .NET ToolStrip height bug - Added own process memory protection for Unix-like systems (as Mono doesn't provide any effective memory protection method) - On Unix-like systems, Shift+F10 (and Ctrl+Alt+5 and Ctrl+NumPad5 on Mac OS X) now shows the context menu in most list/tree view controls and rich text boxes (like on Windows) - KPScript: for the 'Import' command, a different master key can now be specified using the standard master key command line parameters with the prefix 'imp_' (e.g. -imp_pw:Secret) - KPScript: added option '-FailIfNotExists' for the 'GetEntryString' command - KPScript: added '-refx-Group' and '-refx-GroupPath' entry identification parameters - Improved compatibility with ClearType - Improved support for high contrast themes - When duplicating a group/entry, the creation time and the last access time of the copy are now set to the current time - Character picker dialog: initially the text box is now focused, improved tab order, and picked characters are now inserted at the current insertion point (instead of the end) - Ctrl+Tab is now handled only once when the database tab bar has the focus - When exporting to a KeePass 1.x KDB file, a warning/error is now shown if the master key contains/is a Windows User Account - Unknown trigger events/conditions/actions are now ignored by the trigger dialog - Reduced group tree view flickering - Improved default value for the entry history size limit - Improved menu check mark and radio images - Improved list view column resizing - Improved list view scrolling - Secure edit control performance improvements - In some cases, double-clicking the tray icon now brings KeePass to the foreground - Improved concurrent UI behavior during auto-type - Auto-Type: improved compatibility with keyboard layouts with combining apostrophes, quotation marks and tildes - Auto-Type: improved virtual key translation on Unix-like systems - KPScript: the 'EditEntry' command now also updates the time fields of all affected entries - KPScript: the 'DeleteEntry' and 'DeleteAllEntries' commands now create deleted object information (improving synchronization behavior) - Upgraded installer - Various code optimizations - Minor other improvements - When auto-typing a sequence containing a {NEWPASSWORD} placeholder, the raw new password is now stored (in the password field of the entry), not its corresponding auto-type sequence - Synchronizing two unrelated databases now always works as expected 2014-07-06: 2.27 - The estimated password quality (in bits) is now displayed on the quality progress bar, and right of the quality progress bar the length of the password is displayed - Auto-Type: before sending a character using a key combination involving at least two modifiers, KeePass now first tests whether this key combination is a registered system-wide hot key, and, if so, tries to send the character as a Unicode packet instead - Auto-Type: added workaround for Cygwin's default Ctrl+Alt behavior (which differs from Windows' behavior) - Auto-Type: added {APPACTIVATE ...} command - {HMACOTP} placeholder: added support for specifying the shared secret using the entry strings 'HmacOtp-Secret-Hex' (secret as hex string), 'HmacOtp-Secret-Base32' (secret as Base32 string) and 'HmacOtp-Secret-Base64' (secret as Base64 string) - {T-CONV:...} placeholder: added 'Uri-Dec' type (for converting the string to its URI-unescaped representation) - Added placeholders: {URL:USERINFO}, {URL:USERNAME} and {URL:PASSWORD} - Added placeholders: {BASE}, {BASE:RMVSCM}, {BASE:SCM}, {BASE:HOST}, {BASE:PORT}, {BASE:PATH}, {BASE:QUERY}, {BASE:USERINFO}, {BASE:USERNAME}, {BASE:PASSWORD} (within an URL override, each of these placeholders is replaced by the specified part of the string that is being overridden) - Added {NEWPASSWORD:/Profile/} placeholder, which generates a new password for the current entry using the specified password generator profile - Pattern-based password generator: the '^' character now removes the next character from the current custom character set (for example, [a^y] contains all lower-case alphanumeric characters except 'y') - Enhanced syntax highlighting in the sequence field of the 'Edit Auto-Type Item' dialog - Added option 'Do not ask whether to synchronize or overwrite; force synchronization' - Added synchronization support for the group behavior properties 'Auto-Type for entries in this group' and 'Searching entries in this group' - Root group properties are now synchronized based on the last modification time - While saving a database, a shutdown block reason is now specified - Added 'Move to Group' menu in the 'Selected Entries' popup of the main entry list context menu - Items of dynamic menus (tags, strings, attachments, password generator profiles, ...) now have auto-assigned accelerator keys - As alternative to Ctrl+F, pressing F3 in the main window now displays the 'Find' dialog - Added UIFlags bit for hiding password quality progress bars and information labels - Enhanced system font detection on Unix-like systems - When using 'xsel' for clipboard operations on Unix-like systems, text is now copied into both the primary selection and the clipboard - Added '--version' command line option (for Unix-like systems) - Plugins can now subscribe to an IPC event that is raised when running KeePass with the '-e:' command line parameter - Added workaround for .NET AutoWordSelection bug - Added workaround for Mono bug 10163; saving files using WebDAV now also works under Mono 2.11 and higher - Added workaround for Mono image tabs bug - Added workaround for Mono NumericUpDown drawing bug - Merged the URL scheme overrides and the 'Override all URLs' option into a new dialog 'URL Overrides' - Improved autocompletion of IO connection parameters using the MRU list (now treating the user name as filter) - Improved interaction of IO connection trigger parameters and the MRU list - The master key prompt dialog now validates key files only when clicking [OK], and invalid ones are not removed automatically from the list anymore - Improved support for managing columns leftover from uninstalled plugins in the 'Configure Columns' dialog - If the 'Unhide Passwords' policy is turned off, the passwords column in the auto-type entry selection dialog is now unavailable - The entry list in the main window is now updated immediately after performing auto-type or copying data to the clipboard - Various list view performance improvements - The 'Searching entries in this group' group behavior properties are now ignored during resolving field references - Improved behavior in case of syntax errors in placeholders with parameters - Two-channel auto-type obfuscation: improved realization of clipboard paste commands - General main window keyboard shortcuts now also work within the quick search box and the database tab bar - Pressing Ctrl+Shift+Tab in the main window now always selects the previous database tab (independent of which control has the focus) - Changed shortcut keys for moving entries/groups on Unix-like systems, due to Mono's incorrect handling of Alt (preventing key events) and navigation keys (selection updated at the wrong time) - Auto-Type: improved modifier key releasing on Unix-like systems - Various code optimizations - Minor other improvements - A key-up event to the groups tree in the main window without a corresponding key-down event does not change the entry list anymore 2014-04-13: 2.26 - Added option to show a confirmation dialog when moving entries/groups to the recycle bin - Auto-Type: added workaround for applications with broken time-dependent message processing - Auto-Type: added workaround for PuTTY's default Ctrl+Alt behavior (which differs from Windows' behavior) - Auto-Type: added configuration option to specify the default delay between two keypresses - Added optional sequence comments column in the auto-type entry selection dialog (in this column, only {C:...} comments in the sequence are displayed; if a comment starts with '!', only this comment is shown) - If the option 'Automatically search key files' is activated, all drives are now scanned in parallel and any key files are added asynchronously (this avoids issues caused by slow network drives) - Added trigger action 'Show entries by tag' - {OPERA} placeholder: updated detection code to also support the latest versions of Opera - {T-CONV:...} placeholder: added 'Uri' type (for converting the string to its URI-escaped representation) - Synchronization functions are now available for remote databases, too - Enhanced RoboForm importer to additionally support the new file format - Summary lists are now also available in delete confirmation dialogs on Unix-like systems and Windows XP and earlier - Added workaround for Mono Process StdIn BOM bug - KPScript: added 'refx-All' option (matches all entries) - KPScript: added optional parameters 'setx-Expires' and 'setx-ExpiryTime' for the 'EditEntry' command - Improved database tab selection after closing an inactive database - New just-in-time MRU files list - Improved selection of entries created by the password generator - The internal text editor now determines the newline sequence that the data is using the most when opening it, and converts all newline sequences to the initial sequence when saving the data - Improved realization of the {CLEARFIELD} command (now using Bksp instead of Del, in order to avoid Ctrl+Alt+Del issues on newer Windows systems) - The note that deleting a group will also delete all subgroups and entries within this group is now only displayed if the group is not empty - Improved GUI thread safety of the update check dialog - Improved HTML generation - Improved version formatting - On Unix-like systems, window state automations are now disabled during initial auto-type target window switches - On Unix-like systems, the button to choose a password font is disabled now (because this is unsupported due to Mono bug 5795) - Various files (e.g. 'History.txt') are now encoded using UTF-8 - Improved build system - Various code optimizations - Minor other improvements - In the 'Configure Columns' dialog, the activation states of plugin-provided columns are now preset correctly 2014-02-03: 2.25 - New auto-type key sending engine (improved support for sending Unicode characters and for sending keypresses into virtual machine/emulator windows; now largely compatible with the Neo keyboard layout; sequence parsing is faster, more flexible and optimizes the sequence; improved behavior for invalid sequences; differential delays, making the auto-type process less susceptible to externally caused delays; automatic cancelling is now more precise up to at most one keypress and also works on Unix-like systems; improved message processing during auto-type) - When trying to open an entry attachment that the built-in editor/viewer cannot handle, KeePass now extracts the attachment to a (EFS-encrypted) temporary file and opens it using the default application associated with this file; afterwards the user can choose between importing/discarding changes and KeePass deletes the temporary file securely - On Windows Vista and higher, the button in the entry editing dialog to open attachments is now a split button; the drop- down menu allows to choose between the built-in viewer, the built-in editor and an external application - Added 'XML Replace' functionality - Generic CSV importer: added option to merge imported groups with groups already existing in the database - Added support for importing Dashlane 2.3.2 CSV files - On Windows 8 and higher, some running Metro apps are now listed in the 'Edit Auto-Type Item' dialog - Added {T-CONV:/T/C/} placeholder (to convert text to upper- case, lower-case, or its UTF-8 representation to Base64 or Hex) - Added {SPACE} special key code (as alternative for the ' ' character, for improved readability of auto-type sequences) - XML merge (used e.g. when an enforced configuration file is present): added support for comments in inner nodes - Added UIFlags bit for showing last access times - In the history entry viewing dialog, the 'Open' and 'Save' commands are now available for attachments - When replacing the {PASSWORD_ENC} placeholder, KeePass now first Spr-compiles the entry password (i.e. placeholders, environment variables, etc. can be used) - Improved configuration loading performance - Improved displaying of fatal exceptions - Various code optimizations - Minor other improvements - Data inserted by entry URL component placeholders is now encoded correctly 2013-11-03: 2.24 - The URL override field in the entry editing dialog is now an editable combo box, where the drop-down list contains suggestions for browser overrides - Password quality estimations are now computed in separate threads to improve the UI responsiveness - The password generator profile 'Automatically generated passwords for new entries' is now available in the password generator context menu of the entry editing dialog - Added UIFlags bit for hiding built-in profiles in the password generator context menu of the entry editing dialog - Tags can be included in printouts now - Generic CSV importer: added support for importing tags - Added support for importing Norton Identity Safe 2013 CSV files - Mozilla Bookmarks JSON import: added support for importing tags - RoboForm import: URLs are now terminated using a '/', added support for the new file format and for the new note fields - Added support for showing modern task dialogs even when no form exists (requiring a theming activation context) - KeePass now terminates CtfMon child processes started by .NET/Windows, if they are not terminated automatically - Added workarounds for '#', '{', '}', '[', ']', '~' and diaeresis .NET SendKeys issues - Added workaround for 'xsel' hanging on Unix-like systems - Converted some PNG images as a workaround for a problem in Cairo/LibPNG on Unix-like systems - Installer: the version is now shown in the 'Version' field of the item in the Windows 'Programs and Features' dialog - TrlUtil: added 'Go to Next Untranslated' command - TrlUtil: added shortcut keys - The 'Open From URL' dialog is now brought to the foreground when trying to perform global auto-type while the database is locked and the main window is minimized to tray - Profiles are now shown directly in the password generator context menu of the entry editing dialog - After duplicating entries, KeePass now ensures that the copies are visible - User names of TAN entries are now dereferenced, if the option for showing dereferenced data in the main window is enabled - When creating an entry from a template, the new entry is now selected and focused - Empty fields are not included in detailed printouts anymore - Enhanced Internet Explorer detection - The '-preselect' command line option now works together with relative database file paths - Improved quoted app paths parsing - Extended culture invariance - Improved synchronization performance - Improved internal keypress routing - Last access times by default are not shown in the UI anymore - TrlUtil: improved dialog focusing when showing message boxes - KeePassLib/KPScript: improved support for running on systems without any GUI - Various code optimizations - Minor other improvements - Fixed a crash that could occur if the option 'Show expired entries (if any)' is enabled and a trigger switches to a different locked database when unlocking a database - The tab bar is now updated correctly after closing an inactive database by middle-clicking its tab - Column display orders that are unstable with respect to linear auto-adjusting assignment are now restored correctly 2013-07-20: 2.23 - New password quality estimation algorithm - Added toolbar buttons: 'Open URL(s)', 'Copy URL(s) to Clipboard' and 'Perform Auto-Type' - Added 'Generate Password' command in the context menu of the KeePass system tray icon - Added 'Copy history' option in the entry duplication dialog (enabled by default) - Added 'Duplicate Group' context menu command - In the MRU list, currently opened files now have an '[Opened]' suffix and are blue - When a dialog is displayed, (double) clicking the KeePass system tray icon now activates the dialog - Added {T-REPLACE-RX:...} placeholder, which replaces text using a regular expression - Added {VKEY-NX X} and {VKEY-EX X} special key codes - Added 'Perform auto-type with selected entry' trigger action - Added 'Import into active database' trigger action - Mozilla Bookmarks HTML import: added support for groups, bookmark descriptions and icons - Mozilla Bookmarks JSON import: bookmark descriptions are now imported into the note fields of entries - RoboForm import: added support for the new file format - Added support for importing Network Password Manager 4.0 CSV files - Enhanced SafeWallet XML importer to additionally support importing web entries and groups from very old export file versions (for newer versions this was already supported) - Added database repair mode warning - Added option to accept invalid SSL certificates (turned off by default) - Added user activity notification event for plugins - File transactions for FTP URLs are now always disabled when running under .NET 4.0 in order to workaround .NET bug 621450 - Added workaround for Mono list view item selection bug - Added workaround for Mono bug 649266; minimizing to tray now removes the task bar item and restoring does not result in a broken window anymore - Added workaround for Mono bug 5795; text and selections in password boxes are now drawn properly (a monospace font can only be used on Windows due to the bug) - Added workaround for Mono bug 12525; dialog banners are now drawn correctly again - Added workaround for Mono form loading bug - KPScript: added 'Import' command - KPScript: the 'ListEntries' command now also outputs date/time fields of entries - When the option for remembering the last used database is enabled, KeePass now remembers the last active database (instead of the last opened or saved database) - The 'Add Group' command and the F2 key in the groups tree view now open the group editing dialog; in-place tree node label editing is disabled - Custom string and plugin-provided columns in the 'Configure Columns' dialog are sorted alphabetically now - Improved behavior when closing inactive databases - Improved support for trigger actions during database closing - The 'Special' GUI character set now includes '|' and '~' - The 'High ANSI' character set now consists of the range [U+0080, U+00FF] except control and non-printable characters - The options dialog is now listed in the task bar when it is opened while KeePass is minimized to the system tray - A remembered user account usage state can now be preset even when the user account option is disabled using key prompt configuration flags - Improved initial input focus in key creation/prompt dialogs when key creation/prompt configuration flags are specified - During synchronization, the status dialog is now closed after all files have been saved - Improved behavior of the global KeePass activation hot key when a dialog is displayed - Changed auto-type command icon - Shortened product name in main window title - Improved data URI validation - Custom clipboard data is now encoded as data URI (with a vendor-specific MIME type) - Improved configuration loading performance - Enhanced IO connection problem diagnostics - Improved single instance checking on Unix-like systems - KeePassLibC DLLs and ShInstUtil are now explicitly marked as DEP- and ASLR-compatible (like the executable file) - Various UI improvements - Various code optimizations - Minor other improvements - The suffixes to the 'Inherit setting from parent' options on the 'Behavior' tab of the group editing dialog now correctly show the inherited settings of the current group's parent - When locked, the main window's title doesn't show the full path of the database anymore when the option 'Show full path in title bar (instead of file name only)' is turned off - The status bar is now updated correctly after sorting by a column 2013-04-05: 2.22 - When the option for remembering key sources is enabled, KeePass now also remembers whether the user account is required - Added 'View' -> 'Grouping in Entry List' menu - Added 'Close active database' trigger action - Added '-ioiscomplete' command line option, which tells KeePass that the path and file system credentials are complete (the 'Open URL' dialog will not be displayed then) - Added support for importing SafeWallet XML files (3.0.4 and 3.0.5) - Added support for importing TurboPasswords 5.0.1 CSV files - LastPass CSV importer: added support for group trees - Alle meine Passworte XML importer: added support for custom fields and group names with special characters - Password Safe XML importer: added support for the e-mail field - Added 'Help' button in the generic CSV importer dialog - Added workaround for .NET bug 642188; top visible list view items are now remembered in details view with groups enabled - Added workaround for Mono form title bar text update bug (which e.g. caused bug 801414) - After closing a character picking dialog, KeePass now explicitly activates the previous window - Improved behavior when cancelling the icon picker dialog - Main window activation redirection now works with all KeePass dialogs automatically - The window state of the current database is now remembered before opening another database - Previous parameters are now discarded when switching between different trigger event/condition/action types - Unified separators in group paths - The UI state is now updated after adding an entry and clicking an entry reference link in the entry view - The '-entry-url-open' command line option now searches for matching entries in all open databases - Improved database context determination when opening an URL - Added support for special values in date/time fields imported from KeePass 1.x - Improved HTML entity decoding (support for more entities and CDATA sections, improved performance, ...) - RoboForm HTML importer: URLs are converted to lower-case now and support for a special order rotation of attributes has been added - Removed Password Gorilla CSV importer; users should use the generic CSV importer (which can import more data than the old specialized CSV importer) - Improved file discoveries - Improved test form entry auto-type window definition - In the MSI package, the version is now included in the product name - Native key transformation library: replaced Boost threads by Windows API threads (because Boost threads can result in crashes on restricted Windows 7 x64 systems) - Various UI improvements - Various code optimizations - Minor other improvements 2013-02-03: 2.21 - Generic CSV importer: a group separator can be specified now (for importing group trees) - Internal data viewer: added hex viewer mode (which is now the default for unknown data types) - In the 'Show Entries by Tag' menu, the number of entries having a specific tag is now shown right of the tag - In the 'Add Tag' menu, a tag is now disabled if all selected entries already have this tag - Auto-Type: added support for right modifier keys - Added special key codes: {WIN}, {LWIN}, {RWIN}, {APPS}, {NUMPAD0} to {NUMPAD9} - Interleaved sending of keys is now prevented by default (if you e.g. have an auto-type sequence that triggers another auto-type, enable the new option 'Allow interleaved sending of keys' in 'Tools' -> 'Options' -> tab 'Advanced') - Added '-auto-type-selected' command line option (other running KeePass instances perform auto-type for the currently selected entry) - Added option to additionally show references when showing dereferenced data (enabled by default) - The selection in a secure edit control is now preserved when unhiding and hiding the content - The auto-type association editing dialog now does not hang anymore when a window of any other application hangs - When an application switches from the secure desktop to a different desktop, KeePass now shows a warning message box; clicking [OK] switches back to the secure desktop - Added 'OK'/'Cancel' buttons in the icon picker dialog - Added support for importing LastPass 2.0.2 CSV files - KeePass now shows an error message when the user accidentally attempts to use a database file as key file - Added support for UTF-16 surrogate pairs - Added UTF-8 BOM support for version information files - The KeePass version is now also shown in the components list in the 'About' dialog - File operations are now context-independent (this e.g. makes it possible to use the 'Activate database' trigger action during locking) - Plugins can now register their placeholders to be shown in the auto-type item editing dialog - Plugins can now subscribe to IO access events - Added workaround for .NET bug 694242; status dialogs now scale properly with the DPI resolution - Added workaround for Mono DataGridView.EditMode bug - Added workaround for Mono bug 586901; high Unicode characters in rich text boxes are displayed properly now - When the main window UI is being unblocked, the focus is not reset anymore, if a primary control has the focus - When opening the icon picker dialog, KeePass now ensures that the currently selected icon is visible - Internal data viewer: improved visibility updating - The e-mail box icon by default is not inherited by new entries anymore - The database is now marked as modified when auto-typing a TAN entry - Enhanced AnyPassword importer to additionally support CSV files exported by AnyPassword Pro 1.07 - Enhanced Password Safe XML importer (KeePass tries to fix the broken XML files exported by Password Safe 3.29 automatically) - IO credentials can be loaded over IPC now - Enhanced user switch detection - Even when an exception occurs, temporary files created during KDB exports are now deleted immediately - Improved behavior on Unix-like systems when the operating system does not grant KeePass access to the temporary directory - Improved critical sections that are not supposed to be re- entered by the same thread - Improved secure desktop name generation - When a dialog is closed, references within the global client image list to controls (event handlers) are removed now - .NET 4.5 is now preferred, if installed - PLGX plugins are now preferably compiled using the .NET 4.5 compiler, if KeePass is currently running under the 4.5 CLR - Updated KB links - Changed naming of translation files - The installer now always overwrites the KeePassLibC 1.x support libraries - Upgraded installer - Various code optimizations - Minor other improvements - When locking multiple databases and cancelling a 'Save Changes?' dialog, the UI is now updated correctly - '&' characters in dynamic menu texts, in dialog banner texts, in image combobox texts, in text box prompts and in tooltips are now displayed properly 2012-10-04: 2.20.1 - Improved support for images with DPI resolutions different from the DPI resolution of the display device - {GOOGLECHROME} placeholder: updated detection code to also support the latest versions of Chrome - The option to lock on remote control mode changes now additionally watches for remote connects and disconnects - Improved Windows registry accesses - Improved behavior when the user deletes the system temporary directory - On Unix-like systems, KeePass now stores most of its temporary files in a private temporary directory (preferably in $XDG_RUNTIME_DIR) - Added detection support for the following web browsers on Unix-like systems: Rekonq, Midori and Dooble - KeePass does not try to set the WM_CLASS property on Mac OS X systems anymore - Modified some icons to work around unsupported PNG transparency keys in Mono - Various code optimizations - Minor other improvements 2012-09-08: 2.20 - Header data in KDBX files is now authenticated (to prevent silent data corruption attacks; thanks to P. Gasti and K. B. Rasmussen) - Added management of working directories (a separate working directory is remembered for each file dialog context; working directories are remembered relatively to KeePass.exe; the management can be deactivated by turning off the new option 'Remember working directories') - Added option to cancel auto-type when the target window title changes - Added quick search box in the toolbar of the internal text editor - Files can now be attached to entries by using drag&drop from Windows Explorer to the attachments list in the entry editing dialog - Added '-pw-stdin' command line option to make KeePass read the master password from the StdIn stream - Added placeholders to get parts of the entry URL: {URL:SCM}, {URL:HOST}, {URL:PORT}, {URL:PATH} and {URL:QUERY} - Added a 'Details' button in the plugin load failure message box (when clicked, detailed error information for developers is shown) - Added warning icon left of the Windows user account option description in the master key creation dialog - Added support for more image file formats (e.g. when importing custom client icons) - Added support for importing DesktopKnox 3.2 XML files - The generic CSV importer now guesses whether the option to ignore the first row should be enabled or not (the user of course can still specify it manually, too) - Added support for exporting to KeePass 1.x CSV files - Added support for moving the PLGX cache to a different remote drive - The Spr engine is now extensible, i.e. plugins can provide additional transformations/placeholders - On Unix-like systems, KeePass now uses the 'xsel' utility for clipboard operations, if 'xsel' is installed (in order to work around Mono clipboard bugs) - Added Mono workaround to set the WM_CLASS property - Added workaround for Mono splitter bug - The 'PrepMonoDev.sh' script now removes the serialization assembly generating post build event - TrlUtil: added support for importing PO files - Improved FTP file existence checking - High DPI UI improvements - The database is not marked as modified anymore when using in- place label editing to fake-edit a group's name (i.e. when the final new name is the same as the previous one) - Password is not auto-repeated anymore when trying to unhide it fails due to the policy 'Unhide Passwords' being disabled - Improved menu accelerator and shortcut keys - Changed IO connection name display format - Improved browser detection on Mac OS X - Task dialog thread safety improvements - Added UI check during import for KPScript - Upgraded and improved installer (now uses Unicode, LZMA2 compression, ...) - Various UI improvements - Various code optimizations - Minor other improvements - On Windows systems, new line sequences in text to be shown in a standard multiline text box are now converted to Windows format 2012-05-01: 2.19 - New generic CSV importer (now supports multi-line fields, '\' as escape character, field & record separators and the text qualifier can be specified, white space characters can be removed from the beginning/end of fields, the fields and their order can be defined, supported fields now are group name & standard fields like e.g. title & custom strings & times & ignore column, the first row can be ignored, KeePass initially tries to guess the fields and their order based on the first row) - Native master key transformations are now computed in two threads on 64-bit systems, too; on dual/multi core processors this results in almost twice the performance as before (by doubling the amount of rounds you'll get the same waiting time as in 2.18, but the protection against dictionary and guessing attacks is doubled) - New XML configuration and translation deserializer to improve the startup performance - Added option to require a password repetition only when hiding using asterisks is enabled (enabled by default) - Entry attachments can now be renamed using in-place label editing (click on an already selected item to show an edit box) - Empty entry attachments can now be created using 'Attach' -> 'Create Empty Attachment' - Sizes of entry attachments are now shown in a column of the attachments list in the entry editing dialog - Added {ENV_PROGRAMFILES_X86} placeholder (this is %ProgramFiles(x86)%, if it exists, otherwise %ProgramFiles%) - Added auto-type option 'An entry matches if one of its tags is contained in the target window title' - URLs in HTML exports are now linkified - Import modules may now specify multiple default/equivalent file extensions (like e.g. 'htm' and 'html') - Added support for reading texts encoded using UTF-32 Big Endian - Enhanced text encoding detection (now detects UTF-32 LE/BE and UTF-16 LE/BE by zeros, improved UTF-8 detection, ...) - Added zoom function for images in internal data viewer - Drop-down image buttons in the entry editing dialog are now marked using small black triangle overlays - Added support for loading key files from URLs - Controls in the options dialog are now disabled when the options are enforced (using an enforced configuration file) - If KeePass is started with the '-debug' command line option, KeePass now shows a developer-friendly error message when opening a database file fails - Added 'Wait for exit' property in the 'Execute command line / URL' trigger action - The 'File exists' trigger condition now also supports URLs - Added two file closing trigger events (one raised before and one after saving the database file) - Plugins: added file closing events - Plugins: added events (AutoType.Sequence*) that allow plugins to provide auto-type sequence suggestions - Added workaround to support loading data from version information files even when they have incorrectly been decompressed by a web filter - Added workarounds for '°', '|' and '£' .NET SendKeys issues - Added workaround for topmost window .NET/Windows issue (the 'Always on Top' option now works even when switching to a different window while KeePass is starting up) - Added workaround for Mono dialog event ordering bug - Added workaround for Mono clipboard bugs on Mac OS X - KPScript: added 'MoveEntry', 'GetEntryString' and 'GenPw' commands - KPScript: added '-refx-UUID' and '-refx-Tags' entry identification parameters - When only deleting history entries (without changing any data field of an entry), no backup entry is created anymore - Unified text encoding handling for internal data viewer and editor, generic CSV importer and text encoding selection dialog - Improved font sizing in HTML exports/printouts - Improved encoding of group names in HTML exports/printouts - If an entry doesn't expire, 'Never expires' is now shown in the 'Expiry Time' column in HTML exports/printouts - The expiry edit control now accepts incomplete edits and the 'Expires' checkbox is checked immediately - The time component of the default expiry suggestion is now 00:00:00 - The last selected/focused item in the attachments list of the entry editing dialog is now selected/focused after editing an attachment - Improved field to standard field mapping function - Enhanced RoboForm importer to concatenate values of fields with conflicting names - Updated Spamex.com importer - Removed KeePass 1.x CSV importer; users should use the new generic CSV importer (which can import more data than the old specialized 1.x CSV importer) - When trying to open another database while a dialog is displayed, KeePass now just brings itself to the foreground without attempting to open the second database - More list views use the Vista Explorer style - Modifier keys without another key aren't registered as global hot key anymore - Improved default suggestions for custom sequences in the auto-type sequence editing dialog - Improved default focus in the auto-type sequence editing dialog - Added {C:Comment} placeholder in the auto-type sequence editing dialog - On Unix-like systems, the {GOOGLECHROME} placeholder now first searches for Google Chrome and then (if not found) for Chromium - Versions displayed in the update checking dialog now consist of at least two components - Added '@' and '`' to the printable 7-bit ASCII character set - Merged simple and extended special character spaces to one special character space - Reduced control character space from 60 to 32 - The first sample entry's URL now points to the KeePass website - Improved key transformation delay calculation - Improved key file loading performance - The main menu now isn't a tab stop anymore - Some configuration nodes are now allocated only on demand - Improved UI update when moving/copying entries to the currently active group or a subgroup of it using drag&drop - Improved behavior when closing an inactive database having unsaved changes - Changed versioning scheme in file version information blocks from digit- to component-based - Development snapshots don't ask anymore whether to enable the automatic update check (only stable releases do) - Improved PLGX cache directory naming - The PLGX cache directory by default is now located in the local application data folder instead of the roaming one - Improved support for PLGX plugins that are using LINQ - Various UI improvements - Various code optimizations - Minor other improvements - Fixed sorting of items in the most recently used files list - Fixed tab order in the 'Advanced' tab of the entry editing dialog 2012-01-05: 2.18 - The update check now also checks for plugin updates (if plugin developers provide version information files) - When starting KeePass 2.18 for the first time, it asks whether to enable the automatic update check or not (if not enabled already) - When closing the entry editing dialog by closing the window (using [X], Esc, ...) and there are unsaved changes, KeePass now asks whether to save or discard the changes; only when explicitly clicking the 'Cancel' button, KeePass doesn't prompt - When not hiding passwords using asterisks, they don't need to be repeated anymore - Password repetition boxes now provide instant visual feedback whether the password has been repeated correctly (if incorrect, the background color is changed to light red) - When clicking an '***' button to change the visibility of the entered password, KeePass now automatically transfers the input focus into the password box - Visibility of columns in the auto-type entry selection dialog can now be customized using the new 'Options' button - Added auto-type option 'An entry matches if the host component of its URL is contained in the target window title' - Added shortcut keys: Ctrl+Shift+O for 'Open URL', Ctrl+Shift+U for copying URLs to the clipboard, Ctrl+I for 'Add Entry', Ctrl+R for synchronizing with a file, Ctrl+Shift+R for synchronizing with a URL - Ensuring same keyboard layouts during auto-type is now optional (option enabled by default) - Plain text KDB4 XML exports now store the memory protection flag of strings in an attribute 'ProtectInMemory' - Added option to use database lock files (intended for storage providers that don't lock files while writing to them, like e.g. some FTP servers); the option is turned off by default (and especially for local files and files on a network share it's recommended to leave it turned off) - Added UIFlags bit for disabling the controls to specify after how many days the master key should/must be changed - Added support for in-memory protecting strings that are longer than 65536 characters - Added workaround for '@' .NET SendKeys issue - .NET 4.0 is now preferred, if installed - PLGX plugins are now preferably compiled using the .NET 4.0 compiler, if KeePass is currently running under the 4.0 CLR - Automatic update checks are now performed at maximum once per day (you can still check manually as often as you wish) - Auto-Type: entry titles and URLs are now Spr-compiled before being compared with the target window title - Decoupled the options 'Show expired entries' and 'Show entries that will expire soon' - Specifying the data hiding setting (using asterisks) in the column configuration dialog is now done using a checkbox - The entry view now preferably uses the hiding settings (asterisks) of the entry list columns - Improved entry expiry date calculation - Enhanced Password Agent importer to support version 2.6.2 - Enhanced SplashID importer to import last modification dates - Improved locating of system executables - Password generator profiles are now sorted by name - Separated built-in and user-defined password generator profiles (built-in profiles aren't stored in the configuration file anymore) - Improved naming of shortcut keys, and shortcut keys are now displayed in tooltips - Internal window manager can now close windows opened in other threads - Improved entry touching when closing the entry editing dialog by closing the window (using [X], Esc, ...) - Improved behavior when entering an invalid URL in the 'Open URL' dialog - Improved workaround for Mono tab bar height bug - ShInstUtil: improved Native Image Generator version detection - Unified in-memory protection - In-memory protection performance improvements - Developers: in-memory protected objects are now immutable and thread-safe - Various UI text improvements - Various code optimizations - Minor other improvements - The cached/temporary custom icons image list is now updated correctly after running the 'Delete unused custom icons' command 2011-10-19: 2.17 - Multiple auto-type sequences can now be defined for a window in one entry - The auto-type entry selection dialog now displays the sequence that will be typed - The auto-type entry selection dialog is now resizable; KeePass remembers the dialog's position, size and the list view column widths - Added auto-type option 'An entry matches if its URL is contained in the target window title' - Added two options to show dereferenced data in the main entry list (synchronously or asynchronously) - Dereferenced data fields are now shown in the entry view of the main window and the auto-type entry selection dialog (additionally to the references) - Field references in the entry view are now clickable; when clicking one, KeePass jumps to the data source entry - Added option in the 'Find' dialog to search in dereferenced data fields - Added option to search in dereferenced data fields when performing a quick search (toolbar in main window) - The 'Find' dialog now shows a status dialog while searching for entries - The main window now shows a status bar and the UI is disabled while performing a quick search - Added context menu commands to open the URL of an entry in a specific browser - Added {SAFARI} browser path placeholder - Added {C:...} comment placeholder - Added entry duplication options dialog (appending "- Copy" to entry titles, and/or replacing user names and passwords by field references to the original entries) - Added option to focus the quick search box when restoring from taskbar (disabled by default) - Added tray context menu command to show the options dialog - Source fields are now compiled before using them in a {PICKCHARS} dialog - Added 'Copy Link' rich text box context menu command - Before printing, the data/format dialog now shows a print dialog, in which the printer can be selected - Added application policy to ask for the current master key before printing - Added support for importing Passphrase Keeper 2.50 HTML files (in addition to the already supported 2.70 format) - KeePass now removes zone identifiers from itself, ShInstUtil and the CHM help file - Listing currently opened windows works under Unix-like systems now, too - Alternating item background colors are now also supported in list views with item groups - IOConnection now supports reading from data URIs (RFC 2397) - Group headers are now skipped when navigating in single selection list views using the arrow keys - Added detection support for the following web browsers on Unix-like systems: Firefox, Opera, Chromium, Epiphany, Arora, Galeon and Konqueror - Added documentation of the synchronization feature - Key provider plugins can now declare that they're compatible with the secure desktop mode, and a new property in the query context specifies whether the user currently is on the secure desktop - Added workaround for a list view sorting bug under Windows XP - Added workaround for a .NET bug where a cached window state gets out of sync with the real window state - Added workaround for a Mono WebRequest bug affecting WebDAV support - Items in the auto-type entry selection dialog can now be selected using a single click - When performing global auto-type, the Spr engine now uses the entry container database instead of the current database as data source - The generated passwords list in the password generator dialog now uses the password font (monospace by default) - The last modification time of an entry is now updated when a new password is generated using the {NEWPASSWORD} placeholder - The overlay icon for the taskbar button (on Windows 7) is now restored when Windows Explorer crashes and when starting in minimized and locked mode - Improved opening of CHM help file - The buttons in file save dialogs now have accelerator keys - Separated URL scheme overrides into built-in and custom ones - Improved tray command state updating - The default tray command is now rendered using a bold font - The main window is now disabled while searching and removing duplicate entries - Improved banner handling/updating in resizable dialogs - The 'Ctrl+U' shortcut hint is now moved either to the open or to the copy command, depending on whether the option 'Copy URLs to clipboard instead of opening them' is enabled or not - Improved command availability updating of rich text context menus - Quick searches are now invoked asynchronously - Improved quick search performance - The option to minimize the main window after locking the KeePass workspace is now enabled by default - When performing auto-type, newline characters are now converted to Enter keypresses - Auto-type on Unix-like systems: improved sending of backslash characters - On Unix-like systems, the default delay between auto-typed keystrokes is now 3 ms - Spr engine performance improvements - Changing the in-memory protection state of a custom entry string is now treated as a database change - Some options in the options dialog are now linked (e.g. the option 'Automatically search key files also on removable media' can only be enabled when 'Automatically search key files' is enabled) - Most items with default values aren't written to the configuration file anymore (resulting in a smaller file and making it possible to change defaults in future versions) - Path separators in the configuration file are now updated for the current operating system - Improved 'xdotool' version detection - Improved IO response handling when deleting/renaming files - Various UI text improvements - Various code optimizations - Minor other improvements - Status bar text is now correctly updated to 'Ready' after an unsuccessful/cancelled database opening attempt - Password generation based on patterns: escaped curly brackets are now parsed correctly 2011-07-12: 2.16 - When searching for a string containing a whitespace character, KeePass now splits the terms and reports all entries containing all of the terms (e.g. when you search for "Forum KeePass" without the quotes, all entries containing both "Forum" and "KeePass" are reported); the order of the terms is arbitrary; if you want to search for a term containing whitespace, enclose the term in quotes - When searching for a term starting with a minus ('-'), all entries that do not contain the term are reported (e.g. when you search for "Forum -KeePass" without the quotes, all entries containing "Forum" but not "KeePass" are reported) - Added dialog in the options to specify a web proxy (none, system or manual) and user name and password for it - Added option to always exit instead of locking the workspace - Added option to play the UAC sound when switching to a secure desktop (enabled by default) - Added filter box in the field references creation dialog - Added command to delete duplicate entries (entries are considered to be equal when their strings and attachments are the same, all other data is ignored; if one of two equal entries is in the recycle bin, it is deleted preferably; otherwise the decision is based on the last modification time) - Added command to delete empty groups - Added command to delete unused custom icons - For Unix-like systems: new file-based IPC broadcast mechanism (supporting multiple endpoints) - For Unix-like systems: added file-based global mutex mechanism - Auto-type on Unix-like systems: added support for sending square brackets and apostrophes - Two-channel auto-type obfuscation is now supported on Unix-like systems, too - Web access on Unix-like systems: added workarounds for non- implemented cache policy and credentials requirement - Added context menu command to empty the recycle bin (without deleting the recycle bin group) - On Windows Vista and higher, when trying to delete a group, the confirmation dialog now shows a short summary of the subgroups and entries that will be deleted, too - In the auto-type target window drop-down combobox, icons are now shown left of the window names - Added {CLEARFIELD} auto-type command (to clear the contents of single-line edit controls) - Added support for importing Sticky Password 5.0 XML files (formatted memos are imported as RTF file attachments, which you can edit using the internal KeePass editor; e.g. right- click on the entry in the main window and go 'Attachments' -> 'Edit Notes.rtf' or click on the attachment in the entry view at the bottom of the main window; see 'How to store and work with large amounts of formatted text?' in the FAQ) - Added support for importing Kaspersky Password Manager 5.0 XML files (formatted memos are imported the same as by the Sticky Password importer, see above) - Password Depot importer: added support for more fields (new time fields and usage count), time fields can be imported using the stored format specifier, vertical tabulators are removed, improved import of information cards, and auto-type sequences are converted now - Added ability to export links into the root directory of Windows/IE favorites - Windows/IE favorites export: added configuration items to specify a prefix and a suffix for exported links/files - In the entry editing dialog, KeePass now opens an attachment either in the internal editor or in the internal viewer, depending on whether the format is supported by the editor - When creating a new database, KeePass now automatically creates a second sample entry, which is configured for the test form in the online help center - Added configuration option to disable the 'Options', 'Plugins' and/or 'Triggers' menu items - Added workaround for Mono tab bar height bug - Added workaround for Mono FTP bug - Added workaround for Mono CryptoStream bug - Added workaround for a Mono bug related to focusing list view items - Added shell script to prepare the sources for MonoDevelop - Translations can now also be loaded from the KeePass application data directory - TrlUtil: added support for ellipses as alternative to 3 dots - KPScript: added 'DetachBins' command to save all entry attachments (into the directory of the database) and remove them from the database - After performing a quick-find, the search text is now selected - Improved quick-find deselection performance - On Unix-like systems, command line parameters prefixed with a '/' are now treated as absolute file paths instead of options - Improved IPC support on Unix-like systems - Locked databases can now be dismissed using the close command - Invalid target windows (like the taskbar, own KeePass windows, etc.) are not shown in the auto-type target window drop-down combobox anymore - Newly created entries are now selected and focused - The entry list is now focused when duplicating and selecting all entries - If KeePass is blocked from showing a dialog on the secure desktop, KeePass now shows the dialog on the normal desktop - Improved dialog initialization on the secure desktop - The current status is now shown while exporting Windows/IE favorites - Windows/IE favorites export: improved naming of containing folder when exporting selected entries only - Windows/IE favorites export: if a group doesn't contain any exportable entry, no directory is created for this group anymore - Improved data editor window position/size remembering - Key modifiers of shortcut key strings are translated now - Shortcut keys of group and entry commands are now also shown in the main menu - When no template entries are specified/found, this is now indicated in the 'Add Entry' toolbar drop-down menu - When deleting a group, its subgroups and entries are now added correctly to the list of deleted objects - Font handling improvements - Improved lock timeout updating when a dialog is displayed - Improved export error handling - Improved FIPS compliance problems self-test (error message immediately at start), and specified configuration option to prevent .NET from enforcing FIPS policy - Various code optimizations - Minor other improvements - Last modification time is now updated when restoring an older version of an entry - When duplicating an entry, the UUIDs of history items are now changed, too 2011-04-10: 2.15 - Added option to show the master key dialog on a secure desktop (similar to Windows' UAC; almost no keylogger works on a secure desktop; the option is disabled by default for compatibility reasons) - Added option to limit the number of history items per entry (the default is 10) - Added option to limit the history size per entry (the default is 6 MB) - Added {PICKCHARS} placeholder, which shows a dialog to pick certain characters from an entry string; various options like specifying the number of characters to pick and conversion to down arrow keypresses are supported; see the one page long documentation on the auto-type help page; the less powerful {PICKPASSWORDCHARS} is now obsolete (but still supported for backward compatibility) - The character picking dialog now remembers and restores its last position and size - KDBX file format: attachments are now stored in a pool within the file and entries reference these items; this reduces the file size a lot when there are history items of entries having attachments - KDBX file format: attachments are now compressed (if the compression option is enabled) before being Base64-encoded, compressed and encrypted; this results in a smaller file, because the compression algorithm works better on the raw data than on its encoded form - PLGX plugins can now be loaded on Unix-like systems, too - Added option to specify a database color; by specifying a color, the main window icon and the tray icon are recolored and the database tab (shown when multiple databases are opened in one window) gets a colored rectangle icon - New rich text builder, which supports using multiple languages in one text (e.g. different Chinese variants) - Added 'Sort By' popup menu in the 'View' menu - Added context menu commands to sort subgroups of a group - Added option to clear master key command line parameters after using them once (enabled by default) - Added application policies to ask for the current master key before changing the master key and/or exporting - Added option to also unhide source characters when unhiding the selected characters in the character picking dialog - Added ability to export custom icons - Added 'String' trigger condition - Added support for importing DataViz Passwords Plus 1.007 CSV files - Enhanced 1Password Pro importer to also support 1PW CSV files - Enhanced FlexWallet importer to also support version 2006 XML files (in addition to version 1.7 XML files) - Enabled auto-suggest for editable drop-down combo boxes (and auto-append where it makes sense) - Pressing Ctrl+Enter in the rich text boxes of the entry dialog and the custom string dialog now closes with OK (if possible) - Added option to cancel auto-type when the target window changes - Auto-type on Unix-like systems: added support for key modifiers - Added '--saveplgxcr' command line option to save compiler results in case the compilation of a PLGX plugin fails - Added workaround for % .NET SendKeys issue - Added workaround for Mono bug 620618 in the main entry list - Improved key file suggestion performance - When the master key change application policy is disabled and the master key expires (forced change), KeePass now shows the two information dialogs only once per opening - After removing the password column, hiding behind asterisks is suggested by default now when showing the column again - TAN entries now expire on auto-type, if the option for expiring TANs on use is enabled - Auto-type now sends acute and grave accents as separate characters - Auto-type now explicitly skips the taskbar window when searching for the target window - Multiple lines are now separated in the entry list and in the custom string list of the entry dialog by a space - RoboForm importer: improved multiline value support - Improved UNC path support - Improved entry list refresh performance - Improved UI state update performance - Entry list context menus are now configured instantly - Inapplicable group commands are now disabled - Improved control focusing - Improved clipboard handling - Copying and pasting whole entries is now also supported on Windows 98 and ME - Improved releasing of dialog resources - Improved keys/placeholders box in auto-type editing dialog - Improved user-friendliness in UAC dialogs - Tooltips of the tab close button and the password repeat box can be translated now - Improved help (moved placeholders to separate page, ...) - KeePassLibSD now uses the SHA-256 implementation of Bouncy Castle - Upgraded installer - Various code optimizations - Minor other improvements - Window titles are now trimmed, such that auto-type also works with windows whose titles have leading or trailing whitespace characters - Detection of XSL files works under Linux / Mac OS X now, too 2011-01-02: 2.14 - Added option to lock after some time of global user inactivity - Added option to lock when the remote control status changes - Auto-type on Unix-like systems: added special key code support (translation to X KeySyms) and support for {DELAY X} and {DELAY=X} - Added window activation support on Unix-like systems - Auto-type on Windows: added {VKEY X} special key code (sends virtual key X) - Added support for importing DataVault 4.7 CSV files - Added support for importing Revelation 0.4 XML files - Added 'Auto-Type - Without Context' application policy to disable the 'Perform Auto-Type' command (Ctrl+V), but still leave global auto-type available - Added option to collapse newly-created recycle bin tree nodes - Added 'Size' column in the history list of the entry dialog - Added trigger action to remove custom toolbar buttons - Added kdbx:// URL scheme overrides (for Windows and Unix-like systems; disabled by default) - Added KeePass.exe.config file to redirect old assemblies to the latest one, and explicitly declare .NET 4.0 runtime support - Added documentation for the '-pw-enc' command line parameter, the {PASSWORD_ENC} placeholder and URL overrides - Added workaround for ^/& .NET SendKeys issue - New locking timer (using a timeout instead of a countdown) - Improved locking when the Windows session is being ended or switched - Improved multi-database locking - Separated the options for locking when the computer is locked and the computer is about to be suspended - {FIREFOX} placeholder: added support for registry-redirected 32-bit Firefox installations on 64-bit Windows systems - File transactions: the NTFS/EFS encryption flag is now also preserved when the containing directory isn't encrypted - The IPC channel name on Unix-like systems is now dependent on the current user and machine name - KeePass now selects the parent group after deleting a group - Entries are now marked as modified when mass-changing their colors or icons - Key states are now queried on interrupt level - A {DELAY=X} global delay now affects all characters of a keystroke sequence when TCATO is enabled, too - Improved dialog closing when exiting automatically - Plugin-provided entry list columns can now be right-aligned at KeePass startup already - Removed KDBX DOM code - Installer: the KeePass start menu shortcut is now created directly in the programs folder; the other shortcuts have been removed (use the Control Panel for uninstalling and the 'Help' menu in KeePass to access the help) - Various code optimizations - Minor other improvements - Quotes in parameters for the 'Execute command line / URL' trigger action are now escaped correctly - Auto-type on Unix-like systems: window filters without wildcards now match correctly 2010-09-06: 2.13 - Password quality estimation algorithm: added check for about 1500 most common passwords (these are rated down to 1/8th of their statistical rating; Bloom filter-based implementation) - Global auto-type (using a system-wide hot key) is now possible on Unix-like systems (see the documentation for setup instructions, section 'Installation / Portability' in the 'KeePass 2.x' group; thanks to Jordan Sissel for enhancing 'xdotool') - Added IPC functionality for Unix-like systems - Added possibility to write export plugins that don't require an output file - Tag lists are sorted alphabetically now - Password text boxes now use a monospace font by default - Added option to select a different font for password text boxes (menu 'Tools' -> 'Options' -> tab 'Interface') - Added support for importing Password Prompter 1.2 DAT files - Added ability to export to Windows/IE favorites - Added ability to specify IO credentials in the 'Synchronize' trigger action - Added ability to specify IO credentials and a master key in the 'Open database file' trigger action - If IO credentials are stored, they are now obfuscated - Custom colors in the Windows color selection dialog are now remembered - Added high resolution version of the KeePass application icon - Improved lock overlay icon (higher resolution) - PLGX loader: added support for unversioned KeePass assembly references - Added workaround to avoid alpha transparency corruption when adding images to an image list - Improved image list generation performance - Added workaround to display the lock overlay icon when having enabled the option to start minimized and locked - Improved group and entries deletion confirmation dialogs (with preview; only Windows Vista and higher) - The password character picking dialog now offers the raw password characters instead of an auto-type encoded sequence - PINs importer: improved importing of expiry dates - Some button icons are now resized to 16x15 when the 16x16 icon is too large - Renamed character repetition option in the password generator for improved clarity - Improved workspace locking - Locking timer is now thread-safe - Added code to prevent loading libraries from the current working directory (to avoid binary planting attacks) - Removed Tomboy references (on Unix-like systems) - Various code optimizations - Minor other improvements - {NEWPASSWORD} placeholder: special characters in generated passwords are now transformed correctly based on context (auto-type, command line, etc.) 2010-07-09: 2.12 - Auto-type window definitions in custom window-sequence pairs are now Spr-compiled (i.e. placeholders, environment variables, etc. can be used) - Global auto-type delay: added support for multi-modified keys and special keys - Added 'New Database' application policy flag - Added 'Copy Whole Entries' application policy flag - Multi-monitor support: at startup, KeePass now ensures that the main window's normal area at least partially overlaps the virtual screen rectangle of at least one monitor - RoboForm importer: URLs without protocol prefix are now prefixed automatically (HTTP) - Entry-dependent placeholders can now be used in most trigger events, conditions and actions (the currently focused entry is used) - Auto-type on Unix-like systems: KeePass now shows an informative error message when trying to invoke auto-type without having installed the 'xdotool' package - New column engine: drag&dropping hidden fields works as expected again (the field data is transferred, not asterisks) - Improved restoration of a maximized main window - Improved error message when trying to import/export data from/to a KDB file on a non-Windows operating system - Minor other improvements 2010-07-03: 2.11 - Added entry tags (you can assign tags to entries in the entry editing window or by using the 'Selected Entries' context menu; to list all entries having a specific tag, choose the tag either in the 'Edit' main menu or in the 'Show Entries' toolbar drop-down button) - Completely new entry list column engine; the columns are dynamic now, custom entry strings can be shown in the list, to configure go 'View' -> 'Configure Columns...'; the column engine is also extensible now, i.e. plugins can provide new columns - Added 'Size' entry list column (shows the approximate memory required for the entry) - Added 'History (Count)' entry list column (double-clicking a cell of this column opens the entry editing window and automatically switches to the 'History' tab) - Added 'Expiry Time (Date Only)' entry list column - Added options to specify the number of days until the master key of a database is recommended to and/or must be changed - Added support for exporting selected entries to KDB - Added 'FileSaveAsDirectory' configuration key to specify the default directory for 'Save As' database file dialogs - Double-clicking a history entry in the entry editing dialog now opens/views the entry - It's now possible to tab from menus and toolbars to dialog controls - Added option to turn off hiding in-memory protected custom strings using asterisks in the entry view - Added workaround for FTP servers sending a 550 error after opening and closing a file without downloading data - Added 'Unhide Passwords' application policy flag - Password Depot importer: some icons are converted now - {GOOGLECHROME} placeholder: updated detection code to also support the latest versions of Chrome - The main window now uses the shell font by default - On Windows Vista and higher, Explorer-themed tree and list views are now used in the main window - On Windows 7 and higher, the main window peek preview is now disabled when the KeePass workspace is locked - Installer: added option to optimize the on-demand start-up performance of KeePass - TrlUtil: added 3 dots string validation - Improved entry list item selection performance (defer UI state update on selection change burst) - Improved special key code conversion in KDB importer - Icon picker dialog now has a 'Close' button - When sorting is enabled, the entry list view now doesn't get destroyed anymore when trying to move entries - Main window is now brought to the foreground when untraying - Removed grid lines option - Reduced size of MSI file - Various performance improvements - Various code optimizations - Minor other improvements - No file path is requested anymore when double-clicking an import source that doesn't require a file 2010-03-05: 2.10 - Translation system: added support for right-to-left scripts - Added {HMACOTP} placeholder to generate HMAC-based one-time passwords as specified in RFC 4226 (the shared secret is the UTF-8 representation of the value of the 'HmacOtp-Secret' custom entry string field, and the counter is stored in decimal form in the 'HmacOtp-Counter' field) - On Windows 7, KeePass now shows a 'locked' overlay icon on the taskbar button when the database is locked - On Windows 7, the database loading/saving progress is now shown on the taskbar button - Added option to disable automatic searching for key files - Added KDBX database repair functionality (in File -> Import) - Added support for expired root groups - Added global delay support for shifted special keys - Added 'Change Master Key' application policy flag - Added 'Edit Triggers' application policy flag - Added trigger action to activate a database (select tab) - Added configuration options to allow enforcing states (enabled, disabled, checked, unchecked) of key source controls in the master key creation and prompt dialogs (see 'Composite Master Key' documentation page) - Added option to disable the 'Save' command (instead of graying it out) if the database hasn't been modified - Added support for importing KeePassX 0.4.1 XML files - Added support for importing Handy Safe 5.12 TXT files - Added support for importing Handy Safe Pro 1.2 XML files - Added support for importing ZDNet's Password Pro 3.1.4 TXT files - Added dialog for selecting the encoding of text files to be attached to an entry - Added option to search for passwords in quick finds (disabled by default) - Added Ctrl+S shortcut in the internal data editor - Internal data editor window can now be maximized - Document tabs can now be closed by middle-clicking on them - Most strings in the trigger system are now Spr-compiled (i.e. placeholders, environment variables, etc. can be used) - Added '--lock-all' and '--unlock-all' command line options to lock/unlock the workspaces of all other KeePass instances - Added 'pw-enc' command line option and {PASSWORD_ENC} placeholder - Added preliminary auto-type support for Linux (right-click on an entry and select 'Perform Auto-Type'; the 'xdotool' package is required) - Added option to enforce using the system font when running under KDE and Gnome (option enabled by default) - HTML exports are now XHTML 1.0 compliant - Printing: added option to sort entries - Printing: group names are now shown as headings - KPScript: added '-CreateBackup' option for the EditEntry command (to create backups of entries before modifying them) - The PLGX plugin cache root path can now be specified in the configuration file (Application/PluginCachePath) - Plugin developers: added ability to write entropy providers that can update the internal pool of the cryptographically strong random number generator - Plugin developers: added some public PwEntryForm properties, events and methods - Plugin developers: added entry template events - Plugin developers: added group and entry touching events - Plugin developers: added main window focus changing event - Plugin developers: added support for writing format providers for the internal attachments viewer - Expired icons of groups are non-permanent now - Improved search performance and in-memory protection compatibility - The SendKeys class now always uses the SendInput method (not JournalHook anymore) - Improved auto-type delay handling - Two-channel auto-type obfuscation: added support for default delays - The default auto-type delay is now 10 ms - Improved top-most window auto-type support - Improved high DPI support (text rendering, banners, ...) - Temporary file transaction files are now deleted before writing to them - Broadcasted file IPC notification messages do not wait infinitely for hanging applications anymore - On Windows XP and higher, KeePass now uses alpha-transparent icons in the main entry list - In the entry editing dialog, when moving a custom string to a standard field, the string is now appended to the field (instead of overwriting the previous contents of the field) - Improved UTF-8 encoding (don't emit byte order marks) - Improved field to standard field mapping function - HTML exports do not contain byte-order marks anymore - For improved clarity, some controls are now renamed/changed dynamically when using the password generator without having a database open - Improved auto-type definition conversion for KDB exports - Standard field placeholders are now correctly removed when auto-typing, if the standard field doesn't exist - Improved icon picker cancel blocking when removing an icon - The default workspace locking time is now 300 seconds (but the option is still disabled by default) - Modern task dialogs are now displayed on 64-bit Windows systems, too - Improved file corruption error messages - Improved entry attachments renaming method - Double-clicking an attachment in the entry editing dialog now opens it in the internal viewer (the internal editor can only be invoked in the main window) - When attachments are edited using the internal editor, the entry's last modification time is now updated - Improved plugin loading (detect PLGX cache files) - If the application policy disallows clipboard operations, KeePass doesn't unnecessarily decrypt sensitive data anymore - Added tooltip for the 'View' toolbar drop-down button - Improved menu accelerator and shortcut keys - Upgraded installer - Installer: various minor improvements - Various performance improvements - Various code optimizations - Minor other improvements - No exception is thrown anymore when lowering the clipboard auto-clear time in the options below the value of a currently running clearing countdown - The 'Show expired entries' functionality now also works when there's exactly one matching entry 2009-09-12: 2.09 - Added option to use file transactions when writing databases (enabled by default; writing to a temporary file and replacing the actual file afterwards avoids data loss when KeePass is prevented from saving the database completely) - Added PLGX plugin file format - Enhanced database synchronization by structure merging (relocation/moving and reordering groups and entries) - Added synchronization 'Recent Files' list (in 'File' menu) - Synchronization / import: added merging of entry histories - Synchronization / import: backups of current entries are created automatically, if their data would be lost in the merging process - Database name, description, default user name, entry templates group and the recycle bin settings are now synchronized - Added {NEWPASSWORD} placeholder, which generates a new password for the current entry, based on the "Automatically generated passwords for new entries" generator profile; this placeholder is replaced once in an auto-type process, i.e. for a typical 'Old Password'-'New Password'-'Repeat New Password' dialog you can use {PASSWORD}{TAB}{NEWPASSWORD}{TAB}{NEWPASSWORD}{ENTER} - Added scheme-specific URL overrides (this way you can for example tell KeePass to open all http- and https-URLs with Firefox or Opera instead of the system default browser; PuTTY is set as handler for ssh-URLs by default; see Options -> Integration) - Added option to drop to the background when copying data to the clipboard - Added option to use alternating item background colors in the main entry list (option enabled by default) - The Ctrl+E shortcut key now jumps to the quick search box - Added auto-type sequence conversion routine to convert key codes between 1.x and 2.x format - Added workaround for internal queue issue in SendKeys.Flush - Added more simple clipboard backup routine to workaround clipboard issues when special formats are present - Added native clipboard clearing method to avoid empty data objects being left in the clipboard - Added import support for custom icons - Added {GOOGLECHROME} placeholder, which is replaced by the executable path of Google Chrome, if installed - Added {URL:RMVSCM} placeholder, which inserts the URL of the current entry without the scheme specifier - Added ability to search for UUIDs and group names - Toolbar searches now also search in UUIDs and group names - Added {DELAY=X} placeholder to specify a default delay of X milliseconds between standard keypresses in this sequence - Added option to disable verifying written database files - Attachment names in the entry view are now clickable (to open the attachments in the internal editor or viewer) - Added Unicode support in entry details view - Added option to render menus and toolbars with gradient backgrounds (enabled by default) - MRU lists now have numeric access keys - Added '--entry-url-open' command line option (specify the UUID of the entry as '--uuid:' command line parameter) - Added 'Application initialized' trigger event - Added 'User interface state updated' trigger event - Added host reachability trigger condition - Added 'Active database has unsaved changes' trigger condition - Added 'Save active database' trigger action - Added database file synchronization trigger action - Added database file export trigger action - KeePass now restores the last view when opening databases - Added system-wide hot key to execute auto-type for the currently selected entry (configurable in the options) - Added option to disable auto-type entry matching based on title (by default an entry matches if its title is contained in the target window title) - Added option to disable marking TAN entries as expired when using them - Added option to focus the quick search box when restoring from tray (disabled by default) - Added entry context menu commands to sort by UUID and file attachments - Custom string fields are now appended to the notes when exporting to KeePass 1.x KDB files - Enforced configuration files are now item-based (items not defined in the enforced configuration file are now loaded from the global/local configuration files instead of being set to defaults) - File transactions are used when writing configuration files - KPScript: added 'ChangeMasterKey' command - ShInstUtil: added check for the presence of .NET - TrlUtil: added command under 'Import' that loads 2.x LNGX files without checking base hashes - TrlUtil: added control docking support - Plugin developers: added static window addition and removal events to the GlobalWindowManager class - Plugin developers: added ability to write custom dialog banner generators (CustomGenerator of BannerFactory) - Plugin developers: the IOConnectionInfo of the database is now accessible through the key provider query context - Plugin developers: added static auto-type filter events (plugins can provide own placeholders, do sequence customizations like inserting delays, and provide alternative key sending methods) - Plugin developers: added UIStateUpdated main window event - Simple text boxes now convert rich text immediately - Improved entry change detection (avoid unnecessary backups when closing the entry dialog with [OK] but without any changes; detect by content instead of change events) - Header in entry selection dialog is now non-clickable - Entry list header now uses native sorting icons - Key providers are now remembered separately from key files - The main window is now the owner of the import method dialog - The global URL override is now also applied for main entry URLs in the entry details view - Improved grouping behavior when disabling entry sorting - Improved field mapping in RoboForm import - Root groups now support custom icons - In the entry dialog, string values are now copied to the clipboard instead of asterisks - Improved import/synchronization status dialog - Improved import/synchronization error message dialogs - Entry history items are now identified by the last modification time instead of last access time - The trigger system can now be accessed directly through 'Tools' -> 'Triggers...', not the options anymore - Changed order of commands in the 'Tools' menu - Improved auto-type target window validity checking - Ctrl-V does not make the main window lose the focus anymore if auto-type is disabled for the currently selected entry - When restoring from tray, the main window is now brought to the foreground - Double-clicking an icon in the icon picker dialog now chooses the icon and closes the dialog - When adding a custom icon to the database, the new icon is selected automatically - When opening a database by running KeePass.exe with the database file path as parameter (and single instance option enabled), the existing KeePass instance will not prompt for keys of previously locked databases anymore when restoring (they are just left in locked state) - Unlocking routine doesn't display multiple dialogs anymore - Improved shortcut key handling in main window - Master key change success message now has a distinguishable window title - Improved start position and focus of the URL dialog - Improved layout in options dialog - Improved UUID and UI updates when removing custom icons - Improved window deconstruction when closing with [X] - Improved user activity detection - Improved state updating of sorting context menu commands - Improved sorting by UUIDs - Improved naming of options to clarify their meaning - Converted ShInstUtil to a native application (in order to be able to show a warning in case .NET is not installed) - Plugins: improved IOConnection to allow using registered custom WebRequest descendants (WebRequest.RegisterPrefix) - TrlUtil: improved XML comments generation - Various code optimizations - Minor other improvements - Password profile derivation function doesn't incorrectly always add standard character ranges anymore - In-memory protection for the title field of new entries can be enabled now 2009-07-05: 2.08 - Key transformation library: KeePass can now use Windows' CNG/BCrypt API for key transformations (about 50% faster than the KeePass built-in key transformation code; by increasing the amount of rounds by 50%, you'll get the same waiting time as in 2.07, but the protection against dictionary and guessing attacks is raised by a factor of 1.5; only Windows Vista and higher) - Added support for sending keystrokes (auto-type) to windows that are using different keyboard layouts - Added option to remember key file paths (enabled by default) - Added internal editor for text files (text only and RTF formatted text; editor can edit entry attachments) - Internal data viewer: added support for showing rich text (text with formatting) - Added inheritable group settings for disabling auto-type and searching for all entries in this group (see tab 'Behavior'); for new recycle bins, both properties are set to disabled - Added new placeholders: {DB_PATH}, {DB_DIR}, {DB_NAME}, {DB_BASENAME}, {DB_EXT}, {ENV_DIRSEP}, {DT_SIMPLE}, {DT_YEAR}, {DT_MONTH}, {DT_DAY}, {DT_HOUR}, {DT_MINUTE}, {DT_SECOND}, {DT_UTC_SIMPLE}, {DT_UTC_YEAR}, {DT_UTC_MONTH}, {DT_UTC_DAY}, {DT_UTC_HOUR}, {DT_UTC_MINUTE}, {DT_UTC_SECOND} - The password character picking dialog now supports pre- defining the number of characters to pick; append :k in the placeholder to specify a length of k (for example, {PICKPASSWORDCHARS3:5} would be a placeholder with ID 3 and would pick 5 characters from the password); advantage: when having picked k characters, the dialog closes automatically, i.e. saves you to click [OK] - IDs in {PICKPASSWORDCHARSn} do not need to be consecutive anymore - The password character picking dialog now first dereferences passwords (i.e. placeholders can be used here, too) - Added '-minimize' command line option - Added '-iousername', '-iopassword' and '-iocredfromrecent' command line options - Added '--auto-type' command line option - Added support for importing FlexWallet 1.7 XML files - Added option to disable protecting the clipboard using the CF_CLIPBOARD_VIEWER_IGNORE clipboard format - Added support for WebDAV URLs (thanks to Ryan Press) - Added shortcut keys in master key prompt dialog - Added entry templates functionality (first specify an entry templates group in the database settings dialog, then use the 'Add Entry' toolbar drop-down button) - Added AceCustomConfig class (accessible through host interface), that allows plugins to store their configuration data in the KeePass configuration file - Added ability for plugins to store custom data in KDBX database files (PwDatabase.CustomData) - Added interface for custom password generation algorithm plugins - URLs in the entry preview window are now always clickable (especially including cmd:// URLs) - Added option to copy URLs to the clipboard instead of opening them (Options -> Interface, turned off by default) - Added option to automatically resize entry list columns when resizing the main window (turned off by default) - Added 'Sync' command in KPScript scripting tool - Added FIPS compliance problems self-test (see FAQ for details about FIPS compliance) - Added Rijndael/AES block size validation and configuration - Added NotifyIcon workaround for Mono under Mac OS X - Added confirmation box for empty master passwords - Added radio buttons in auto-type sequence editing dialog to choose between the default entry sequence and a custom one - Added hint that group notes are shown in group tooltips - Added test for KeePass 1.x plugins and an appropriate error message - Added interface for writing master password requirements validation plugins - Key provider plugin API: enhanced key query method by a context information object - Key provider plugin API: added 'DirectKey' property to key provider base class that allows returning keys that are directly written to the user key data stream - Key provider plugin API: added support for exclusive plugins - The '-keyfile' command line option now supports selecting key providers (plugins) - Auto-Type: added option to send an Alt keypress when only the Alt modifier is active (option enabled by default) - Added warning when trying to use only Alt or Alt-Shift as global hot key modifier - TrlUtil: added search functionality and toolbar - TrlUtil: version is now shown in the window title - Improved database file versioning and changed KDBX file signature in order to prevent older versions from corrupting newer files - ShInstUtil now first tries to uninstall a previous native image before creating a new one - Improved file corruption error messages (instead of index out of array bounds exception text, ...) - The 'Open in Browser' command now opens all selected entries instead of just the focused one - Data-editing commands in the 'Tools' menu in the entry dialog are now disabled when being in history viewing mode - Right arrow key now works correctly in group tree view - Entry list is now updated when selecting a group by pressing a A-Z, 0-9 or numpad key - Improved entry list performance and sorting behavior - Improved splitter distance remembering - Improved self-tests (KeePass now correctly terminates when a self-test fails) - The attachment column in the main window now shows the names of the attached files instead of the attachments count - Double-clicking an attachment field in the main window now edits (if possible) or shows the first attachment of the entry - Group modification times are now updated after editing groups - Improved scrolling of the entry list in item grouping mode - Changed history view to show last modification times, titles and user names of history entries - KeePass now also automatically prompts to unlock when restoring to a maximized window - Improved file system root directory support - Improved generic CSV importer preview performance - When saving a file, its path is not remembered anymore, if the option for opening the recently used file at startup is disabled - Improved auto-type input blocking - Instead of a blank text, the entry dialog now shows "(Default)" if the default auto-type sequence is used in a window-sequence association - Most broadcasted Windows messages do not wait for hanging applications anymore - Improved main window hiding at startup when the options to minimize after opening a database and to tray are enabled - Default tray action is now dependent on mouse button - New entries can now inherit custom icons from their parent groups - Improved maximized state handling when exiting while the main window is minimized - Improved state updating in key creation form - Improved MRU list updating performance - Improved plugin incompatibility error message - Deprecated {DOCDIR}, use {DB_DIR} instead ({DOCDIR} is still supported for backward compatibility though) - Last modification times of TAN entries are now updated - F12 cannot be registered as global hot key anymore, because it is reserved for kernel-mode / JIT debuggers - Improved auto-type statement conversion routine in KeePass 1.x KDB file importer - Improved column width calculation in file/data format dialog - Improved synchronization status bar messages - TrlUtil: base hash for forms is now computed using the form's client rectangle instead of its window size - Various code optimizations - Minor other improvements - Recycle bin is now cleared correctly when clearing the database 2009-03-14: 2.07 Beta - Added powerful trigger system (when events occur, check some conditions and execute a list of actions; see options dialog in 'Advanced'; more events / conditions / actions can be added later based on user requests, and can also be provided by plugins) - Native master key transformations (rounds) are now computed by the native KeePassLibC support library (which contains the new, highly optimized transformation code used by KeePass 1.15, in two threads); on dual/multi core processors this results in almost triple the performance as before (by tripling the amount of rounds you'll get the same waiting time as in 2.06, but the protection against dictionary and guessing attacks is tripled) - Added recycle bin (enabled by default, it can be disabled in the database settings dialog) - Added Salsa20 stream cipher for CryptoRandomStream (this algorithm is not only more secure than ArcFour, but also achieves a higher performance; CryptoRandomStream defaults to Salsa20 now; port developers: KeePass uses Salsa20 for the inner random stream in KDBX files) - KeePass is now storing file paths (last used file, MRU list) in relative form in the configuration file - Added support for importing 1Password Pro CSV files - Added support for importing KeePass 1.x XML files - Windows XP and higher: added support for double-buffering in all list views (including entry lists) - Windows Vista and higher: added support for alpha-blended marquee selection in all list views (including entry lists) - Added 'EditEntry', 'DeleteEntry', 'AddEntries' and 'DeleteAllEntries' commands in KPScript scripting tool - Added support for importing special ICO files - Added option to exit instead of locking the workspace after the specified time of inactivity - Added option to minimize the main window after locking the KeePass workspace - Added option to minimize the main window after opening a database - Added support for exporting to KDBX files - Added command to remove deleted objects information - TrlUtil now checks for duplicate accelerator keys in dialogs - Added controls in the entry editing dialog to specify a custom text foreground color for entries - KeePass now retrieves the default auto-type sequence from parent groups when adding new entries - The password character picking dialog can now be invoked multiple times when auto-typing (use {PICKPASSWORDCHARS}, {PICKPASSWORDCHARS2}, {PICKPASSWORDCHARS3}, etc.) - Added '-set-urloverride', '-clear-urloverride' and '-get-urloverride' command line options - Added '-set-translation' command line option - Added option to print custom string fields in details mode - Various entry listings now support custom foreground and background colors for entry items - Added 'click through' behavior for menus and toolbars - File association methods are now UAC aware - User interface is now blocked while saving to a file (in order to prevent accidental user actions that might interfere with the saving process) - Improved native modifier keys handling on 64-bit systems - Improved application startup performance - Added image list processing workaround for Windows 7 - OK button is now reenabled after manually activating the key file checkbox and selecting a file in the master key dialog - The master key dialog now appears in the task bar - When KeePass is minimized to tray and locked, pressing the global auto-type hot key doesn't restore the main window anymore - The installer now by default installs KeePass 1.x and 2.x into separate directories in the program files folder - The optional autorun registry keys of KeePass 1.x and 2.x do not collide anymore - File type association identifiers of KeePass 1.x and 2.x do not collide anymore - File MRU list now uses case-insensitive comparisons - Improved preview updates in Print and Data Viewer dialogs - Message service provider is thread safe now - Threading safety improvements in KPScript scripting plugin - Improved control state updates in password generator dialog - Improved master password validation in 'New Database' dialog - Times are now stored as UTC in KDBX files (ISO 8601 format) - Last access time fields are now updated when auto-typing, copying fields to the clipboard and drag&drop operations - KPScript scripting tool now supports in-memory protection - Database is not marked as modified anymore when closing the import dialog with Cancel - Added asterisks in application policy editing dialog to make clearer that changing the policy requires a KeePass restart - Double-clicking a format in the import/export dialog now automatically shows the file browsing dialog - Improved permanent entry deletion confirmation prompt - Improved font objects handling - Expired groups are now rendered using a striked out font - Improved auto-type statement conversion routine in KeePass 1.x KDB file importer - Clipboard clearing countdown is not started anymore when copying data fails (e.g. policy disabled) - Improved synchronization with URLs - The database maintenance dialog now only marks the database as modified when it actually has removed something - KeePass now broadcasts a shell notification after changing the KDBX file association - Improved warning message when trying to directly open KeePass 1.x KDB files - Improved Linux / Mac OS X compatibility - Improved MSI package (removed unnecessary dependency) - TrlUtil: improved NumericUpDown and RichTextBox handling - Installer now checks for minimum operating system version - Installer: file association is now a task, not a component - Installer: various other improvements - Various code optimizations - Minor other improvements - When cloning a group tree using drag&drop, KeePass now assigns correct parent group references to cloned groups and entries - Fixed crash when clicking 'Cancel' in the settings dialog when creating a new database 2008-11-01: 2.06 Beta - Translation system is now complete (translations to various languages will be published on the KeePass translations page when translators finish them) - When saving the database, KeePass now first checks whether the file on disk/server has been modified since it was loaded and if so, asks the user whether to synchronize with the changed file instead of overwriting it (i.e. multiple users can now use a shared database on a network drive) - Database files are now verified (read and hashed) after writing them to disk (in order to prevent data loss caused by damaged/broken devices and/or file systems) - Completely new auto-type/URL placeholder replacement and field reference engine - On Windows Vista, some of the message boxes are now displayed as modern task dialogs - KeePass is now also available as MSI package - Accessibility: added advanced option to optimize the user interface for screen readers (only enable this option if you're really using a screen reader) - Added standard client icons: Tux, feather, apple, generic Wiki icon, '$', certificate and BlackBerry - Secure edit controls in the master key and entry dialogs now accept text drops - Added ability to store notes for each group (see 'Notes' tab in the group editing window), these notes are shown in the tooltip of the group in the group tree of the main window - Group names in the entry details view are now clickable; click it to jump to the group of the entry (especially useful for jumping from search results to the real group of an entry) - Added 'GROUPPATH', 'DELAY' and 'PICKPASSWORDCHARS' special placeholders to auto-type sequence editing dialog - Wildcards (*) may now also appear in the middle of auto-type target window filters - For auto-type target window filters, regular expressions are now supported (enclose in //) - KeePass now shows an explicit file corruption warning message when saving to a file fails - Added option to prepend a special auto-type initialization sequence for Internet Explorer and Maxthon windows to fix a focus issue (option enabled by default) - Added ability to specify a minimum length and minimum estimated quality that master passwords must have (see help file -> Features -> Composite Master Key; for admins) - Added field reference creation dialog (accessible through the 'Tools' menu in the entry editing dialog) - Field references are dereferenced when copying data to the clipboard - Entry field references are now dereferenced in drag&drop operations - KeePass now follows field references in indirect auto-type sequence paths - Added internal field reference cache (highly improves performance of multiple-cyclic/recursive field references) - Added managed system power mode change handler - Added "Lock Workspace" tray context menu command - Moved all export commands into a new export dialog - Added context menu command to export the selected group only - Added context menu command to export selected entries only - Added support for importing Password Memory 2008 XML files - Added support for importing Password Keeper 7.0 CSV files - Added support for importing Passphrase Keeper 2.70 HTML files - Added support for importing data from PassKeeper 1.2 - Added support for importing Mozilla bookmarks JSON files (Firefox 3 bookmark files) - Added support for exporting to KeePass 1.x CSV files - Added XSL transformation file to export passwords only (useful for generating and exporting password lists) - Added support for writing databases to hidden files - When passing '/?', '--help' or similar on the command line, KeePass will now open the command line help - When single instance mode is enabled and a second instance is started with command line parameters, these parameters are now sent to the already open KeePass instance - KeePass now ships with a compiled XML serializer library, which highly improves startup performance - Added support for Uniform Naming Convention (UNC) paths (Windows) in the URL field (without cmd:// prefix) - Added option to exclude expired entries in the 'Find' dialog - Added option to exclude expired entries in quick searches (toolbar; disabled by default) - The box to enter the name of a custom string field is now a combobox that suggests previously-used names in its drop-down list - Added Shift, Control and Alt key modifiers to placeholder overview in the auto-type sequence editing dialog - Added support for 64 byte key files which don't contain hex keys - Added Ctrl-Shift-F accelerator for the 'Find in this Group' context menu command (group tree must have the focus) - Added export ability to KPScript plugin - Ctrl-Tab now also works in the password list, groups tree and entry details view - Added multi-user documentation - Plugin developers: DocumentManagerEx now has an ActiveDocumentSelected event - Plugin developers: instead of manually setting the parent group property and adding an object to a group, use the new AddEntry / AddGroup methods of PwGroup (can take ownership) - Plugins can now add new export file formats (in addition to import formats) - Plugins: added static message service event - When using the installation package and Windows Vista, settings are now stored in the user's profile directory (instead of Virtual Store; like on Windows XP and earlier) - Accessibility: multi-line edit controls do not accept tabs anymore (i.e. tab jumps to the next dialog control), and inserting a new line doesn't require pressing Ctrl anymore - When moving entries, KeePass doesn't switch to the target group anymore - When deleting entries from the search results, the entry list is not cleared anymore - Improved entry duplication method (now also works correctly in search results list and grouped list views) - A more useful error message is shown when checking for updates fails - Improved formats sorting in the import dialog - The 'Limit to single instance' option is now turned on by default (multiple databases are opened in tabs) - Removed 'sort up', 'sort down' and empty client icons - Improved program termination code (common clean-up) - Improved error message that is shown when reading/writing the protected user key fails - The key file selection dialog now by default shows all files - Plugins: improved event handlers (now using generic delegate) - Implemented several workarounds for Mono (1.9.1+) - Added conformance level specification for XSL transformations (in order to improve non-XML text exports using XSLT) - Improved key state toggling for auto-type on 64-bit systems - Removed several unnecessary .NET assembly dependencies - Threading safety improvements - Highly improved entry context menu performance when many entries are selected - Entry selection performance improvements in main window - Improved entries list view performance (state caching) - List view group assignment improvements (to avoid splitting) - Removed tab stops from quality progress bars - After moving entries to a different group, the original group is selected instead of the target group - Layout and text improvements in the master key creation form - Text in the URL field is now shown in blue (if it's black in the standard theme) - Improved auto-type tab in entry dialog (default sequence) - Improved AES/Rijndael cipher engine initialization - Improved build scripts - Various code optimizations - Minor other improvements - Installer: changed AppId to allow parallel installation of KeePass 1.x and 2.x - Minor other installer improvements - The 'View' -> 'Show Columns' -> 'Last Access Time' menu command now works correctly - The 'Clipboard' -> 'Paste Entries' menu command now assigns correct group references to pasted entries 2008-04-08: 2.05 Alpha - Added placeholders for referencing fields of other entries (dereferenced when starting URLs and performing auto-type, see the auto-type placeholders documentation) - Added natural sorting (when sorting the entry list, KeePass now performs a human-like comparison instead of a simple lexicographical one; this sorts entries with numbers more logically) - Added support for importing RoboForm passcards (HTML) - Added {DELAY X} auto-type command (to delay X milliseconds) - Added {GROUPPATH} placeholder (will be replaced by the group hierarchy path to the entry; groups are separated by dots) - When saving databases to removable media, KeePass now tries to lock and unlock the volume, which effectively flushes all system caches related to this drive (this prevents data loss caused by removing USB sticks without correctly unmounting in Windows first; but it only works when no other program is using the drive) - Added pattern placeholder 's' to generate special characters of the printable 7-bit ASCII character set - A " - Copy" suffix is now appended to duplicated entries - After duplicating entries, the new entries are selected - The list view item sorter now supports dates/times, i.e. sorting based on entry times is logically now, not lexicographically - Added GUI option to focus the entry list after a successful quick search (toolbar; disabled by default) - Several entry context menu commands are now only enabled if applicable (if the user name field of an entry is empty, the 'Copy User Name' command is disabled, etc.) - Added a 'Tools' button menu in the entry editing dialog - Tools button menu: Added command to select an application for the URL field (will be prefixed with cmd://) - Tools button menu: Added command to select a document for the URL field (will be prefixed with cmd://) - Added password generator option to exclude/omit user-specified characters in generated passwords - Added clearification paragraph in master key creation dialog about using the Windows user account as source (backup, ...) - Added menu command to synchronize with an URL (database stored on a server) - KeePass is now checking the network connection immediately when trying to close the URL dialog - Added file closed event arguments (IO connection info) - Added "file created" event for plugins - The document manager is now accessible by plugins - Improved field to standard field mapping function - KeePass now locks when the system is suspending (if the option for locking on locking Windows or switching user is enabled) - All documents are now locked when the session is ended or the user is switched (if the option for this is enabled) - Moving a group into one of its child groups does not make the group vanish anymore - Auto-type validator now supports "{{}" and "{}}" sequences (i.e. auto-type can send '{' and '}' characters) - Undo buffers of secure edit controls are now cleared correctly - Disabling sorting does not clear search results anymore - Entry editing dialog: Return and Esc work correctly now - Column sort order indicators are now rendered using text instead of images (improves Windows Vista compatibility) - Splitter positions are now saved correctly when exiting after minimizing the main window to tray - Added handler code for some more unsupported image file format features (when importing special ICO files) - Translation system is now about 75% complete - KeePass is now developed using Visual Studio 2008 - Minor UI improvements - Minor Windows installer improvements - The CSV importer does not crash anymore when clicking Cancel while trying to import entries into an empty folder - IO connection credentials saving works correctly now - Fixed duplicate accelerator keys in the entry context menu - Help button in master key creation dialog now works correctly 2008-01-06: 2.04 Alpha - Added key provider API (it now is very easy to write a plugin that provides additional key methods, like locking to USB device ID, certificates, smart cards, ... see the developers section in the online KeePass help center) - Added option to show entries of sub-groups in the entry list of a group (see 'View' -> 'Show Entries of Sub-Groups') - Added XML valid characters filter (to prevent XML document corruption by ASCII/DOS control characters) - Added context menu command to print selected entries only - Added option to disallow repeating characters in generated passwords (both character set-based and pattern-based) - Moved security-reducing / dangerous password generator options to a separate 'Advanced' tab page (if you enable a security-reducing option, an exclamation mark (!) is appended to the 'Advanced' tab text) - Added 'Get more languages' button to the translations dialog - Added textual cue for the quick-search edit control - The TAN wizard now shows the name of the group into which the TANs will be imported - Improved random number generator (it now additionally collects system entropy manually and hashes it with random numbers provided by the system's default CSP and a counter) - For determining the default text in the 'Override default sequence' edit box in the 'Edit Entry' window, KeePass now recursively traverses up the group tree - Last entry list sorting mode (column, ascending / descending) is now remembered and restored - First item in the auto-type entry selection window is now focused (allowing to immediately navigate using the keyboard) - Text in secure edit controls is now selected when the control gets the focus the first time - For TAN entries, only a command 'Copy TAN' is now shown in the context menu, others (that don't apply) are invisible - Regular expressions are validated before they are matched - KeePass now checks the auto-type string for invalid entry field references before sending it - The clipboard auto-clear information message is now shown in the status bar instead of the tray balloon tooltip - Matching entries are shown only once in the search results list, even when multiple fields match the search text - First item of search results is selected automatically, if no other item is already selected (selection restoration) - Entries with empty titles do not match all windows any more - Improved high DPI support in entry window - When having enabled the option to automatically lock the workspace after some time and saving a file fails, KeePass will prompt again after the specified amount of time instead of 1 second - KeePass now suggests the current file name as name for new files (save as, save as copy) - The password generator profile combo box can now show more profiles in the list without scrolling - Improved native methods exception handling (Mono) - Updated CHM documentation file - TAN wizard now assigns correct indices to TANs after new line characters - Copying KeePass entries to the clipboard now works together with the CF_CLIPBOARD_VIEWER_IGNORE clipboard format - KeePass now uses the correct client icons image list immediately after adding a custom icon to the database - Fixed 'generic error in GDI+' when trying to import a 16x16 icon (thanks to 'stroebele' for the patch) - File close button in the toolbar (multiple files) works now - Fixed minor bug in provider registration of cipher pool 2007-10-11: 2.03 Alpha - Added multi-document support (tabbed interface when multiple files are opened) - KeePass 2.x now runs on Windows 98 / ME, too! (with .NET 2.0) - Added option to permute passwords generated using a pattern (this allows generating passwords that follow complex rules) - Added option to start minimized and locked - Added support for importing Passwort.Tresor XML files - Added support for importing SplashID CSV files - Added '--exit-all' command line parameter; call KeePass.exe with this parameter to close all other open KeePass instances (if you do not wish to see the 'Save?' confirmation dialog, enable the 'Automatically save database on exit' option) - Added support for CF_CLIPBOARD_VIEWER_IGNORE clipboard format (clipboard viewers/extenders compliant with this format ignore data copied by KeePass) - Added support for synchronizing with multiple other databases (select multiple files in the file selection dialog) - Added ability to specify custom character sets in password generation patterns - Added pattern placeholder 'S' to generate printable 7-bit ASCII characters - Added pattern placeholder 'b' to generate brackets - Added support for starting very long command lines - Entry UUID is now shown on the 'Properties' tab page - Added Spanish language for installer - KeePass now creates a mutex in the global name space - Added menu command to save a copy of the current database - The database name is now shown in the title of the 'Enter Password' window - Added "Exit" command to tray icon context menu - Pressing the 'Enter' key in the password list now opens the currently selected entry for editing - Added '-GroupName:' parameter for 'AddEntry' command in the KPScript KeePass scripting tool (see plugins web page) - Added URL example in 'Open URL' dialog - Added support for plugin namespaces with dots (nested) - Added ability to specify the characters a TAN can consist of - '-' is now treated as TAN character by default, not as separator any more - Added ability to search using a regular expression - Notes in the entry list are now CR/LF-filtered - Added {PICKPASSWORDCHARS} placeholder, KeePass will show a dialog which allows you to pick certain characters - The password generator dialog is now shown in the Windows taskbar if the main window is minimized to tray - Caps lock is now disabled before auto-typing - Improved installer (added start menu link to the CHM help file, mutex checking at uninstallation, version information block, ...) - Plugin architecture: added cancellable default entry action event handler - Added support for subitem infotips in various list controls - Group name is now shown in the 'Find' dialog (if not root) - Pressing the 'Insert' key in the password list now opens the 'Add Entry' dialog - Last search settings are now remembered (except search text) - The column order in the main window is now remembered - Pressing F2 in the groups tree now initiates editing the name of the currently selected group - Pressing F2 in the password list now opens the editing dialog - The 'About' dialog is now automatically closed when clicking an hyperlink - Entries generated by 'Tools' - 'Password Generator' are now highlighted in the main window (visible and selected) - Extended auto-close functionality to some more dialogs - Protected user key is now stored in the application data directory instead of the registry (when upgrading from 2.02, first change the master key so it doesn't use the user account credentials option!) - Improved configuration file format (now using XML serialization, allowing serialization of complex structures) - Improved configuration saving/loading (avoid file system virtualization on Windows Vista when using the installer, improved out of the box support for installation by admin / usage by user, better limited user account handling, ...) - Improved password generator profile management (UI) - Improved password generator character set definition - Custom icons can be deleted from the database now - Changed password pattern placeholders to support ANSI - Removed plugin projects from core distribution (plugin source codes will be available separately, like in 1.x) - Window position and size is saved now when exiting KeePass while minimized - Splitter positions are restored correctly now when the main window is maximized - Password list refreshes now restore the previous view (including selected and focused items, ...) - Improved session ending handler - Improved help menu - Added more JPEG extensions in the icon dialog (JFIF/JFI/JIF) - Navigation through the group tree using the keyboard is now possible (entries list is updated) - Options dialog now remembers the last opened tab page - Synchronization: deletion information is merged correctly now - Improved importing status dialog - Improved search results presentation - Title field is now the first control in the focus cycle of the entry dialog - The auto-type entry selection dialog now also shows custom / imported icons - The quick-find box now has the focus after opening a database - The main window title now shows 'File - KeePass Password Safe' instead of 'KeePass Password Safe [File]'; improved tooltip text for tray icon - The 'Save Attachments' context menu command is disabled now if the currently selected entry doesn't have any attachments - A more useful error message is shown when trying to import an unsupported image format - Replaced 'Search All Fields' by an additional 'Other' option - Expired/used TAN entries are not shown in the expired entries dialog any more - UI now mostly follows the Windows Vista UI text guidelines - Improved UI behavior in options dialog - Improved text in password generator preview window - After activating a language, the restart dialog is only shown if the selected language is different from the current one - Online help browser is now started in a separate thread - Value field in 'Edit String' window now accepts 'Return' key - The name prompt in the 'Edit String' window now initially shows a prompt instead of an invalid field name warning - Expired entries are now also shown when unlocking the database - Expired entries are not shown any more in the auto-type entry selection dialog - Various dialogs: Return and Esc work correctly now - Improved key handling in password list - Updated SharpZipLib component in KeePassLibSD - Updated CHM documentation file - Deleting custom string fields of entries works correctly now - Fixed a small bug in the password list view restoration routines (the item above the previous top one was visible) - KeePass doesn't prevent Windows from shutting down any more when the 'Close button minimizes window' option is enabled - The "Application Policy Help" link in the options dialog works now - KeePass doesn't crash any more when viewing an history entry that has a custom/imported icon - Icon in group editing dialog is now initialized correctly - Last TAN is not ignored any more by the TAN wizard - Other minor features and bugfixes 2007-04-11: 2.02 Alpha - Added "Two-Channel Auto-Type Obfuscation" feature, which makes auto-type resistant against keyloggers; this is an opt- in feature, see the documentation - Added KDBX data integrity verification (partial content hashes); note: this is a breaking change to the KDBX format - Added internal data viewer to display attachments (text files, images, and web documents); see the new 'View' button in the 'Edit Entry' window and the new dynamic entry context menu popup 'Show In Internal Viewer' - External images can now be imported and used as entry icons - Added KeePassLibC and KeePassNtv 64-bit compatibility - Added Spamex.com import support - Added KeePass CSV 1.x import support - When adding a group, users are immediately prompted for a name (like Windows Explorer does when creating new folders) - Added prompts for various text boxes - The installer's version is now set to the KeePass version - The key prompt dialog now shows an 'Exit' button when unlocking a database - Added F1 menu shortcut for opening the help file/page - URL override is now displayed in the entry view - Added ability to check if the composite key is valid immdiately after starting to decrypt the file - Added ability to move groups on the same level (up / down), use either the context menu or the Alt+... shortcuts - The database isn't marked as modified any more when closing the 'Edit Entry' dialog with OK but without modifying anything - Added version information for native transformations library - Local file name isn't displayed any more in URL dialog - Improved path clipping (tray text, ...) - Improved data field retrieval in SPM 2007 import module - Improved attachments display/handling in 'Edit Entry' dialog - Improved entry context menu (added some keyboard shortcut indicators, updated icons, ...) - Improved performance of secure password edit controls - Clearified auto-type documentation - Installer uses best compression now - Improved auto-type state handling - In-memory protected custom strings are hidden by asterisks in the entry details window now - Improved entropy collection dialog - Updated import/export documentation - Added delete shortcut key for deleting groups - Instead of showing the number of attachments in the entry view, the actual attachment names are shown now - Improved asterisks hiding behavior in entry view - New entries now by default inherit the icon of their parent groups, except if it's a folder-like icon - Updated AES code in native library - Improved native library detection and configuration - Improved entry/group dragging behavior (window updates, ...) - A more useful error message is shown when you try to export to a KDB3 file without having KeePassLibC installed - Configuration class supports DLL assemblies - KeePass doesn't create an empty directory in the application data path any more, if the global config file is writable - Clipboard isn't cleared any more at exit if it doesn't contain data copied by KeePass - Empty auto-type sequences in custom window-sequence pairs now map to the inherited ones or default overrides, if specified - Cleaned up notify tray resources - Improved help menu - A *lot* code quality improvements - ShInstUtil doesn't crash any more when called without any parameter - Auto-type now sends modifier keys (+ for Shift, % for Alt, ...) and character groups correctly - Fixed alpha transparency multi-shadow bug in groups list - Overwrite confirmation now isn't displayed twice any more when saving an attachment from the 'Edit Entry' window - User interface state is updated after 'Select All' command - Auto-Type warnings are now shown correctly - Fixed auto-type definition in sample entry (when creating a new database) - The global auto-type hot key now also works when KeePass is locked and minimized to tray - Fixed bug in initialization of Random class (KeePass could have crashed 1 time in 2^32 starts) 2007-03-23: 2.01 Alpha - Improved auto-type engine (releases and restores modifier keys, improved focusing, etc.) - Implemented update-checking functionality - Added KPScript plugin (see source code package) for scripting (details about it can be found in the online help center) - Added Whisper 32 1.16 import support - Added Steganos Password Manager 2007 import support - Search results now show the full path of the container group - Entry windows (main password list, auto-type entry selection dialog, etc.) now show item tooltips when hovering over them - Added window box drop-down hint in the auto-type item dialog - Database maintenance history days setting is now remembered - Improved main window update after importing a file - Improved command line handling - If opening/starting external files fails, helpful messages are displayed now - Completely new exception handling mechanism in the Kdb4File class (allows to show more detailed messages) - New message service class (KeePassLib.Utility.MessageService) - Added option to disable remembering the password hiding setting in the 'Edit Entry' window - Added menu shortcuts for opening the current entry URL (Ctrl+U) and performing current entry auto-type (Ctrl+V) - Changed file extension to KDBX - Password generation profiles are now saved when the dialog is closed with 'Close'/'Cancel' - Entry URL overrides now precede the global URL override - Standard password generation profiles are now included in the executable file - Restructured plugin architecture, it's much clearer now (abstract base class, assembly-internal manager class, ...) - Only non-empty strings are now displayed in the entry view - Current working directory is set to the KeePass application directory before executing external files/URLs - Changed fields shown in the auto-type entry selection dialog: title, user name and URL are displayed instead of title, user name and password - Clearified clipboard commands in context menus - Help buttons now open the correct topics in the CHM - Fixed name in the installer script - Workspace is not locked any more if a window is open (this prevents data loss) - The 'Find' toolbar button works now - The OK button in the Import dialog is now enabled when you manually enter a path into the file text box - Fixed entry list focus bug - Fixed menu focus bug - The 'Copy Custom String' menu item doesn't disappear any more - Fixed enabled/disabled state of auto-type menu command 2007-03-17: 2.00 Alpha - Strings containing quotes are now passed correctly over the command-line - Created small help file with links to online resources - Rewrote cipher engines pool - Restructured KeePassLib - Added dialog for browser selection - Added option to disable searching for key files on removable media - Improved KDB3 support (especially added support for empty times as created by the KeePass Toolbar for example) - Added confirmations for deleting entries and groups - Fixed a lot of bugs and inconsistencies; added features - Fixed a bug in the 'Start KeePass at Windows startup' registration method - Added custom split container control to avoid focus problems - Clipboard is only cleared if it contains KeePass data - New system for configuration defaults - A LOT of other features, bugfixes, ... ... (a lot of versions here) ... 2006-10-07: 2.00 Pre-Alpha 29 - Various small additions and bugfixes 2006-10-06: 2.00 Pre-Alpha 28 - Implemented entry data drag-n-drop for main entry list - Implemented URL overriding - Added {} repeat operator in password generator - Added database maintenance dialog (deleting history entries) - Custom entry strings are now shown in the entry preview - Added alternative window layout: side by side - A lot of other features and bugfixes ... (some versions here) ... 2006-09-17: 2.00 Pre-Alpha 25 - Fixed exception that occured when WTS notifications are unavailable 2006-09-16: 2.00 Pre-Alpha 24 - Implemented quality progress bars (gradient bars) - Added special key codes into placeholder insertion field in the 'Edit AutoType' dialog - Currently opened windows are listed in the 'Edit AutoType' dialog - Entries can be copied/pasted to/from Windows clipboard - Added {APPDIR}, {DOCDIR} and {GROUP} codes - Foreground and background colors can be assigned to entries - Expired entries are displayed using a striked-out font - Password generator supports profiles now - Password generator supports patterns now - VariousImport: Added support for Password Exporter XML files - A _lot_ of other features and bugfixes 2006-09-07: 2.00 Pre-Alpha 23 - Internal release 2006-09-07: 2.00 Pre-Alpha 22 - Improved password quality estimation - Implemented secure edit controls (in key creation dialog, key prompt dialog and entry editing dialog) 2006-09-05: 2.00 Pre-Alpha 21 - Removed BZip2 compression - Added font selection for main window lists - Added file association creation/removal buttons in the options dialog - Installer supports associating KDB files with KeePass - Added option to run KeePass at Windows startup (for current user; see Options dialog, Integration page) - Added default tray action (sending/restoring to/from tray) - Added single-click option for default tray action - Added option to automatically open last used database on KeePass startup (see Options dialog, Advanced page) - Added option to automatically save the current database on exit and workspace locking (Options dialog, Advanced page) - Implemented system-wide KeePass application messages - Added 'Limit to single instance' option - Added option to check for update at KeePass startup - Added options to show expired entries and entries that will expire soon after opening a database - Added option to generate random passwords for new entries - Links in the entry view are clickable now - Links in the notes field of the entry dialog are clickable now - Fixed context menu auto-type command (inheriting defaults) - Improved entry list state updating performance - Classic databases are listed in the main MRU list, prefixed with '[Classic]' - Other features and bugfixes 2006-09-03: 2.00 Pre-Alpha 20 - First testing release ... (a lot of versions here) ... 2006-03-21: 2.00 Pre-Alpha 0 - Project started Docs/Chm/0000775000000000000000000000000013225117276011163 5ustar rootrootDocs/Chm/screenshots/0000775000000000000000000000000013225117274013521 5ustar rootrootDocs/Chm/screenshots/main.jpg0000664000000000000000000011177013225117272015154 0ustar rootrootJFIFHHCC,"  g   ! "1#A2QVav$4678RTUWw35BXqu%&SbDfsgrtP !1AQ"a25BRq#3Ub6Ss%4CEcr$t ?8s O-/{Qs6pwn&^\J|Sn'Q=fe:f3pg=0|vDlDгi! r$ZnIvG3*CE|bj <`%>֯@S>PƊHOHu]0C{B@tQJnO _ncQaBҘMEFT~W_*|l79Y=vA^G"xWoznOCHC"+6Ir=rW/cIYbFr&L^TSCu6#9SFj ^ӎ:)vb\VEiLǝX+*LL`UTUUdUog%X8 _#FHMqGD;^ꪛM㙣6уϥ  ][+Ax,fW8Hr^*D:}ֈjY\Wu M$$QCѓxgC~J x$U~]qX8/қZ5J/_X9w/Y!9[g"l2 \2h,2+hY19TT=~_0y_%qU~_đ}cOk{WNsb,~,7n175-|X/S5Mjw HsB;b_Q~[Ó}bǵXj#`*m?/Ǹ8k_Γ' */=S-.h?-㯿7?{7Nsb2-u,L=Yo{d6tupߍyWbNsb_~}9q~]S8?.㧿7?zNsbKmЉ6|l^mMbŗ})gk鿜upNs<$ m|#F躹>כcn9iĈ?w'3dU=?ck`uuJGWwQUol9輏kv lW @R ?`ED*E /p{1JWd#1Ez#:1PwosDUNZ߽kk||X:#U,^ ֽ|ɷWoU~_?&o~_kןF\ȘՇ}`vUd tO:9z-^Ea6b=ɸk.nJH{+4=t,߭8to_A5  M1UT'D"nJ^1иCS wl#bN'z$+"ߴ嚙0EG4[3fʆB69 ֝(^lp VKvcOb-eW7لwOT3yȢݖӤP%-f! {L0PĩeEEqk:y} 1TOUU+0uJ+(Sof=U7֞b) ~U-M>s٭`6HZuvU:sm.Br[ĢW#GpR&qΐ"d//2S4 @AB*RdR%^CĿ*T콨Y$ڂ34s.旮pdLX*` RR.u)g3r"9s&B@m\?$R@7]dq5U4 E_T*K{|3Irh+^v31m7I]n I3Ut/"ET|Kt_|D[C`d\@7!EDUD]7DUD_rb;wlɕLO&h(Ù=IModl"Nj\u 5 ů1)o)"WM*ҎVhBB)"u 3rrUԽlڨ;ΎŹ:APvBwuU$mŅEjZ5V tPZ<.nD Y huVq69zymx,m*%b3-a`ckU1BUD^M,5m5#SBHcH3LD;W!2#2MU4u@kE[1ؙܽ՚w*4tH"C8uVƊ͞dsu7<4#jJqYiv$Q@t M6ׁkCLo0aQ]ⴕGgDty /Ft A$&,nũhnX2HU팲MH&Ԕ[#$d>-$mEym@K+:7dϹ`bEvlD"fHw˰L%YXvQ_62\zUud_Q5!f7bDX#Nd HUL RM$iZfURд71Ut|i * iEVؓ=@B$n ! &.^C29vBty1Mw_pI2F2Fz^n_5k,R5Fn 'Gdލs[h%d6辬l{b'9 &FaɱxTfCbE+n̨FEb! 4*.Kbڧ7Mhn%߰>y.d[/H/ݾR-/jiYP.MjA R VJ롕i[$q I p&aIMoiK;]u1oYSX@q.\^@1VfMI _l˴ucsneaޫe+,",@X|edZ>n(0e[Q^E7E[,Xs]zbW-#4,4d3)OW~օ MYm٧ N qU*KHVdSf`0Z0))IUVFPT1mq1R֕ΥuDԟœ}vcs!SEC\zZlbO_ocy{ytK񛙲o^&:yXDb!҆] ) /#o"]n8$&HӝhUbWU2&ݲh M?( J苾ʩ__85ZlZb;)P4[ўFB**&>hm5>m9ՏHl\7Q}W4fK20^8FH,0FSp| B oV-+zlɩ2@+ "J M@m$Euڴdx,''`Uc@q CMIBؓދ99.a]K'(}ZG&e"1TQNDUMP ^3XS!VdZa/-y. EzKfdL 8D @YV%j a.64 6V( F0SvԁmEN Xs*Uђ(i9Hw_4O4!?"x4dz@%$S =*hE  xp,)qg'bgcIfm$uL}qb"_~n?YiB~77]ϩ+_"Hyl@vSr}S%%@b<" "Bd("/?^XNf+!?Zŋp:=~u 1]>e /_~n,[僨Y 7Liwp[l#nDKDN5qss/''c=gtwF;%%1̥'V' +uz9B>2vcsu{Paϱ̿78]>2pu{Paϱ̿78]>2pu{Paϱ̿78]>2pu{P0P̿HqW3詙 wT]_bqXom.T"~zΘLj񘦴D%?;"}RVCKShFf##tvS߿V5NQ51rI0d8b)[*m("0ϣ csl>:̾\]eЄ{**ymʼn9Ugy6bNo6WH0x[;H+t"(*" љڽɤXH vP3lͮ0 TNO 0g0tS11?UqC65Qƛ #fll\U8lD EDUDہ2瘜v{)3V]5&˧D^'lYpLԡL{zH02DmO\aKCE$dV5)]kEx;}ѝ LZ a_pgU~ASC 48x`3XNʻP#ēLv}h>D*@TH~gU~AcxVeAj͵FAʋɏZl0lUz6ČMrlU!!tvkS'eortd.6o? *La: /y HreHl"F ~TCTU7EEE¬?}&'k|;>nG*y|k; iki`igF'[Aܚg5.G  D"uCq ޫe}uv}GTzK6oـ*n.{>EXn39-.MLD[#UT.6KWS6듍Ej:c+Fl*qr,ؒmSӀǒ+I4{JW 2iEiWFmYq_AQe(,+9 FjE o]zR*՟EV]C׳rAWcҜ{Hg W"h&zPOqt4ԏEzeFY]k,fdeikGduz RgK".F4پ\m^=/ݾXX LQ8ʒ'Hy*p5f_6PjVse_?I|YCq$Dn"*"*ԨJF3Svp4at_7҂1>1X3껌Q354/SVmgrA6 o"ۨIAZw0=!e8eF*mIStE^<G.!~&Ĩk6KBZ՚Y.Fq:| /tAQo^z5)jQƮdɄ72oHhAG&lNJ"d9юҞR^o*I&s)#p#ܕc͋L>8j}P4_./ɍcT9AzcM$K 6 KB$BlĶ$EMp=HfWZv?~.}}4x'%kfKvTP›Q+D7q\k dz ش?+؝8L8L6)Jn|tN4QcMSaҾhmYoo"6NNd *U{?>i>K['laFDz?f-S-tUݽE Bqy)H.OfWՌU\9wԳqE}ǟrP[T4Q6m_˻ф쳢پY.ζu1[:M.DbPOV&F%MMD1!Gُ#1 x=/3$f_Gk"1ƈF;$£)EoaT>Ycros˰Ã֖4a{,K}}(=>~TCǛr>b(OUg\2?'<(7HU?]Hk3se|-hSNjv3. q=i#؊N׈ER>PBEWv4q KrPe\yt_UL̈۠>.bTfz6ryo*;'l&W{6fʲ9h `]Zd)uDioKѻlLOj2fXܨX~x 3FNw: v@@hޖYFcF Ӯ3}(Fc?~TC~nT$3K@I^DQ_EEO:?aƚ]Ό7Ό۷҃;lj>`Rn&l˶f>SFwf2p'S-&—G& uLǛUG$([/r@ȷM57rwf|2a C@ D MFPH;yE#l:kW-Pbis#iy6x-WPIQWSvL %h $Is%`o1Mf?Y([H##Y2HuUdL?I"}:T"T: ,|Õ!<"tu}Oڱ'}_ߊÈtQBDD!ƞcYY>@dTsZv:0ďPk*oߊV#9Vd ɎU8n4# ' t Ĭ#/!\ťM[M/qjT˃YuE]F`NZ*:܋dz>zq*$6buQtGҨ`fday nvuFqpƍj]ShT R.^/6+Fv}NLC>+VTzƩ\fnDuۨ@`PO[JzUit7pJgJv͌dWm_>D&* i*'p6N"hj1/F5gl\mlF6~MD J֬u'Roҥ^G#}f(X3W=uYC J${K& MƎ2"p6i.NuwMu,p*]ES:,E*3&) ֏6ʂMSbRERˆHר ^."?cfy$ɩ4ZzT9=o1H4f[X+}.!жICW_JJP&Y~f4o)Ml[v۪,ѻAQw_J[u8_+ŔX=e+atȐ"R|~ӯeW.]`Pke#r1$xTD#ptBb;B}_ 񸸐Zigek\Y:rmq۠r 1SŋfY׸G4ė|.\W{cu%=Xv"% mƊ=ml,7u9rK3XG*jE ND2$6zD鄻yU`Q(2a\7OΏX^$Yr0DV|1[UbMc5WcZzԐێi8 H2@lE$ Sc IWO?" iŲ+~x&2gs㍕5TO"4!dMh1$VpSoM?-1_{뮳DV.X9%_.xb6㰧Hy=So H 8k&uZ 9T_E]s,?̃:=['~QWo1 IK_7 (즽6+P\;2[hkDEȈ{Dٍ_Q1T }c ,سMík`YŅ5zµU_ pTE]yQOTLPCe\oOQ@G#s*d4Um#]0!YRW H-틯DTGlɕs:ONW0MTmwӼmV]ne}t]#1 Z6DBk2Dwni--i HZEV$Vvq϶VQ A)ۺe?H}{cG (+ܘq}p7#uB),6'lMfVk1=F4Wqiba ,ǒoBW:kb0p Vcły( \R(ݖu N^R(MGIX'Z[ w"4~ImWh+qh &Zm\eʲc$ Z! l)wζxt,K}$cJHAFP ,Ja8"Bf֑T+@JB2N` Qм"ͬ5Q2v\@8b<{qлjZ1d8BmyٮWW-8f$J&հF4X5B$1 6؆2w*)p|z#fFJZt @P6 7o("`cZ?ȶkxm%ïX@`CZ˖3H[bDUqYB*lkW$Gio!5UG ջyƽAnEa)VbJG͔;qła"Ju^p|smzo"[7*4.b.D12Tl'cFbDͶ%0iq6Q(uWnT1s{lu-˳ cÉʲll4ȜL>.Yٶ /1r4c/wLH1NT0g#!&Lb9"+ЄUSE<H5q<&2 ܆ZŐ/)lDm=g%ٍhQz.FIjWuˣvPK%!4 p(u)6uwR/\wmc[{DA8ozq غSd Uu)60:*Y1c;{9ҌEmzp]GRJZ8?iW"}c_=йm%Ei9Qu=MlZCdq?߃HtW-7t)e3; Nk(jd `am ~1U7Fi߆~׹?J?8jE}r~.M*ǤHpAwuu$~ ,z8厙ǭV&n78L`aK>ԡQ"~[y0&%R.XV Ѹ5\.ڂ`h>UwIPӼQ4Wu*S5Ũtg1JIOwz6U-" 8+o\+]5u)\*I`FG< ]nfch 4fF3`Z+JILʦKX<,LÎER8iInt_at:16:SCa"`<Lyv wQluӐ4ߙMI3 -L|vf[w]cemB+Śn̎µA I!%TtGӜǴgEOm"M2KLN40Z+ P!XrEmX3!ؼ  {2\[\GwOL]c6aXȊi iKhMшm4 O)vVs#B;KV?x cJ)Ϥ.aȈnxxy9- !覢WΤh2kfTyܔu0Jp$P*<ێE'3?[?{ O n̬A..[OH!}`ĉ6bTW1V˹(h񭟽ާj4~}q.H)8OKLW.'JGs=^[hT-t z윈z7M}V4O-:/xax\eAnjQ' SvG:BĨ6tE0\O y /DE^-U객>2V LGzQmMQVWTaI^P}A&qY UOީq&r#c(eȌ`r@ mcf윈!_9^PbR3G-AEDDь../H"ĉqQJI65 B"boēJ_qykτ Up=O|b!,SK*P~,yQj\V +q Put/ēP|sjej╤8n$]V!*(Ba3vfU`NU"$JPj{6uT,BZjjC/'ֹqzF%fD4n3,.-$Uuωf#Lyq$Gl"Ǝˊʴ-/ "jѠ&mDɴk 1,219g6Y5mmpšRK3>Ũ,"Ja@҃ IJs gQ(;$0U5(##0'J >)^pȮ/\rl9wdȵ1?\+KTp\MlhIlS'KWmdqymf=tQ9;kxUR+r )Br"tc*F,L'XowvA^YITF; .m^QiAʲ{}Cǽj)koV tf(\aLAC{Fn"ef_e5  }0qحېuוHYibtE'iӲ\iZuSsX6Wd!|qƐf8FHI\xFz;oN^\VpPšFաKzsEu#N5WFNǘ/;ҨrZZ7cRxѰlAiU=y)Ȋ}843~joJX㺁 tn5ٳɩfrh`ҦEGw$rch gFN"ֱiԨݔQŊYGqjhtwa5B(DKw{G9y)]FZ$VAx;aCt]JRQXXFv5 F]ecRXYY,|eY  l 6q6*`?$O:K˗&kzUX̭1J`r$ "1}+4_nMNM<GKY7p.X*)QᜒiZGNIz6W wHMO?`r`dGĆ{gMRs\L3O&\^"Ȩ$S[b7ՅLXEi-\dz\XH}KtbM|_rࢧH|Hֹ%R9MDh (&CЅ@?]85~I1? ?շMz L]d)*}~!OÂ^O :tB< n-UVк=ETHl8!*"Wt_g3z46,%zjI HQTe1T!UqzqaamWhW}\r(YXw )71Uq 'B/q~EU]Pj$$ST:6^+&@Eyʟ#*/J{Td&z̒4Xϳ"'+J;hd(*D/{,6Imx}TEJ@o(&ةK\&7NmiV$oTVz_MTQPW6p-Gj{A\`Ȝ}T$mP? ɾ>?fQoLVoҵ{F Rwaq:ES~2M׍`Tm`4X$D*u"Bi(.3P]q.9br|EInʿ_΁r枷rHP {JH. dס ̝Z31mk2ߨWnt,&@Jb>qh f6ۿnETOz*gak+NccH"H#b"{ [!q)oeWU>us!o? / ׮~-q W?b8ۂrs35=us!o?:̌r'}rߙ6y"y'zi8[%mP"MB*(X4`=w/fajNwmwU C4)BiNA 6$6ԗ:ME1^'MmF-*-ȳKfjuĆHĆ[4@Ǡ1ޓ-DFY ӒbD.5֕X=.C P=lnA6$kA` bVCьFƱy{ci z#ZpXI6.5RZHەbεus+!./! @p8* cG-t'emJp)ƒVP/ 4(NI&$cgSj,ҭzS~j)V=)떁_{>bg9;ҫ8U8vd>FУC=q"+)>_i a'C@2,,7HcU|ڶAeu{"픦8~mɔ}] ]}wfvy8rPTYZFҺgHBj+r&4 m86n6.q-_*(9&90TXv3no4˭ۍNf&"B#'4X"b\VOaUۣG[fHB -9KXXU8,68;u'#\PH5"03GYYkISsY.-m[IBL^l;ڂ{6Kփь[ ͧ1_W7IȣNǂq V,>n+ͫ>L;h>&%-TT؀;H"u2 pB(dJ*);;8q\gO<#pj\z[0L3o͐U)2@RHP6@J#ȜҼmGMsdU$>DkJ55SO& Y8,e=I,zALo=_)xYETZ_VƬ_ό}m%\ 'ڙ?2^n-\OGS"d] ~}P)[@JƑ IƞPN(N4Hq."1..4qkc41%FPDEyWppfӯn9:MӖuSA87sEaV@]ć%+Lec)tft˘xu^Cq9DkCw3itb!mE8C=0lJ>_XLzvVl-FiKUcLoRY/49׬G荫x;(Ak^ˤԗ7cL_%B&;T%e䂨t_v dXu_^8e#$lj1w0Ԑge$|11>*xp <6ТRLf3K9*k<#F8.'1] |k"sjzDdr\KM7ZX5츑6$cz5`BxV¦Q}4Փ.Ͼ ,`ؼҶY'yD1 ,O~7G\JjSH 7h}N\x?#L| NY;ʨ^sh{t/DvD&D\AENcᅯ!ŮFK!*VY(x4m:G3*8jo҄+jvgU'(1 Lly &N:;$)#궣WGL!M7zV®H[( í TFuX%*1[v1NF'J˯DRsMb_-o=Łb9j<[KZ ʔhY&$˻92F5B%6\k7kz|{V1'&=6kv 6"lu*E2ED]Ǒ|+YkХXNm"`r,HPx\FgXЫ`6%%ݷFbЭS9D5/CZC٣Bݐ9֦ "[B-!n(m^sNS*xVU\ŬyK_&BhѦyNOmzwGSd-9MYPjnFc(,/VӁ E00@)*F~{ԭ/k2znU>]z$H,ޱY)ŶN,8;!틦L_%֜.*ŪWd,)nIQ!H+nCm2:>^vro0ijtk7'JGAWEpa̻u(pY,MnX;hJJ~#fPXp%Gj#qD8=;K[V3 c>/RYȖOW|H ! n75Oj. {G:Ne f``LM.zF7*’qbu \}ۯ_11/؞5 =sKW:a-VLsR#5"/׵,'fr<] lʠ 5m| 񯘘N?O._0w5rNG\Hĕ]#."RbX UE^l.>Uڷy4lbIɗ ǝkKUˆXs[iLzH/h΀717]:2-0JRNE؄QStUO/+tL6IJa Ncΐ(JfjRnt3-.BF7ּdh[B)UJQDgk=Rs BA:>O̗C{OIxr|Lm(֡K(RYn:O`S%KJؚ6gG0|Nq;X嶚bk44hcr$z͠X 5xq+͍6fOMb8I.ΟM X rQ0RK}:Vөs+I} zAdim=!^H؁W)UU>aЫ2mE) Ga/h8+WTn^swJ;SI12rLJdmE7rKH2QY_죄 \M4 H鞻f3T<ߋrCb'=Bƃ*4+"Ֆ&Cwz^ܓR)T.XMج[;MX̒ӎ6 (vAhAy5cNXNtJC8n d@*D[IB߼U #yWwm/s84[KIQTkVF@a  Q^9̗ Iű|bOMQoÛf-)%2ډH?% ؃5ot.s-K.'D9ٲ[j0ad+*TuCjW*,݌2zgMjU9 M2'zHؿ <-m'R^%YyU~/E:ͱ⟎ˇǯ3#>( !4j<&qEmUP'OF|i/:)`oZ5XTYPA,t(F` 'wcۈi'ɃxzdE 9\*WCjg,x1oSBuvMTFt.Cږcͻ-[DZ4Udol^~;JԪ]=q^7=rM(Эtw(o*wXdG5"9bٌ 3#pբ$EAB$Bq "*gocwVyRNֲ-T4JxANStLeM85R9@VUilc$Ch C5emPOIr+ /#OrO.rd,WA:ITzouȣn4 L4~+~5rX )⏩Q/%MDTDmKL>q8&OgT]Em'H;1񒒙Nhiq MH3g6iS,4C`ɢ 3Maf2Fd(3V"r(\04E_M!ix J &TVz3x&k=-N INK5*{2k\1q %qG@%*I l Dwՠ5+cDܴm\ܣfWPmK Puq&viSrWm]sU=FUH48v%bOo'h0&"aa²m-i e7lBlgC< Pmܱ=L]MP|ė|XӠɏ29GuDP04]U<J4\6F\SxvV$H'2Km G3}/{(hD^˴<%٫J@; b $<Qaj-t6'H qb; %2ȋ#&d"(K^D|ˏn!p\.#II?%/j1z;;D$H":j(B){׆]N啃ifEQ)K1L &8uF aQZ˂EԁmIEv&KdߥKeؐ@tMݭݤNoaA ;*g,E /*DA/*+a%m)vt7=ʩ3xS3y/l_0Gj>ED,*✛=d!-IQFAfta{a9O]}|FOKLW.'S4~}qOz8;)dt~GD~}3!,! +6di * "nIzٟ"731HQ'"FWebT_w.GZeZӌv"\9_lf%㳍$aqKg .]_ٌLIKybz趨^wbIePr*k;3N(`]wqUN+?O n#i6r8plBu=_@Ž̺3ypԌ&t+U2OvM4+5\#1ٰFSaqb#廘x9Is6vZy"TK +kY8؍>Z8rXDɯ=ɐmiIu&Ya8%JHIªAB+rJ@JiQ^6 B%I p`cWf.2uj$9lu̕K%mb-NEhuuCAbyMҜNHc&/e͓'z'"3lAZt=m!LwLyCIڭ;&ɗr9‚vRiS#=$n2`cik1!ĮgUKbCMJuf" wXn ギ$v4S^0W]KHkw[T(,F}lդl}Rup.lǗ#&!bTb"tHӡˁdFи xʮ wQQT$EE'r׫5zYZsAGk X҈Yzd8L";f@c؆NkZ6U![}Ci7VSۈK̼1{oo$k 9ЎhgAa1HZ~B6d""y볥 FIdmM8Qy!2ҩVһXO0ESJ#2̣vbvUϾT\aּ&H>$l a0IR[~4ڐX2lFU3v1HkA3HCS\vvd:ƝGb$͋6%_j@ YG?Co{E/}g__~ gb3^d6  Nm#I(TtG[yzigڶw*+cFM j$:֜ȫ6ߒD^iQh=0INN1C;_>ZMa71rͺZ̚3G*‹CnX2ɧ$:Y8K(tQrŧñzM_i Fm,yD%Т֢ D5sΥ4Ysys4:ssc"i$0Ǧ$t@iP)e׭`}2O Ss 15,:zJ8h,v$:H/(H ;9gl}:~_1Q7 0.Gf4Bˏ:,Q~*< rZdb0eGcL.7CA;"xƨϸkN*y5\DVv/WA2%@&<..FUJ#-N<1ؘ?]IKyZzطKCo]RwW0rz3ukKb%CN6:F@#6`B3@"v߶^>}B߼;#=A*SL*4#u/ =mXH]KyU u@DTU, UQcxvkPNl5q2< ~4Ix$"orH(JIƴU\aL(v9Cö,wv"ul *,l:`8 Kʖ(&DrO0qJ{DWߝsfzzv$fP h&&&H1198qFPHyh}Zj.Qb،Qhw),:EodT86eyA6UjOWj.H ҥ0Lƫ@M}@p,JWu˲MXirbNUhM;(BK̥;dÎ!&۝'p{$۴^q[8qņSpΖO +Z[$=G 5Y6/BjB] Clj#uJ@* g(:i[0[ tf[͙S4ۑ kģQ.p1]5y>m!җRgjvSCir_ n5ёh_)"xCtӝ(:b2t?Xqi9[WȎ-kd Gyke6 뮲ۆ\.\.,H\;Qʎʱn,C㗝ޣx^_ڍMjՍr܆]mOi#TÐ<,yTu7ۜ65QtF!3kFV+" -GH=m@Şqq o?/c;65? ơ^Js0^#dcLWrsKDU+pz +&+a^2`'PS^̦af8M>p'2uW hZqGqmmrqq3 9.^;Um(ͦ[%Y3q"}zשd~ ޟMrY9#5b3USduA#"o}IPc}uI)]/jޗ*1YMڵm*U$ȐzK^p;L6;.뫮f{,Op:m}Y5 d VTx ƒsCyϞ`QZEɏҫ{Z 1]`)agBS/y6SJV2Xł:&"5E:쀻SEDp効j8A)H<{lގ !q'Y嶖VͪlƎIMa%ldJtלTsJ{NXc?Y=x ۗ# 0ˡm;G4[tK|[:u: ҝIsc!\& lƐpQe^Sq]XM"F9|.vGW¹&AV7IZ$}y{<[Ů˰cy"-E%V ߏ<8܂n|!Xo!JB"Ttfzi~ ֊66Ě\i] aZCuuc5α>btX9wzT3g `5i?%̖vkk\;:QiE6WGzNJzђvt8axhᗼCe6sl<+ 1ymVI0yn4m2x(`Үlfab/>ADrܒcRf0ULÂdJ]3AN4prَ(3]x~mV$2J!2x(b4R8ﮗ#ǙL{J&֊+PƔi89ŏ&^YXHx[_$R%tDK%O:|~wc0qhw=6}T*EE)U@N dr]˅T[ 1 ON6.&ʈH1jS׎jD'ilͮ]Q5"PkܱpppBHJ+nj 7+UK/5sLYUbIƧ큈Q|S]D*n OTؽ03 (S"*؈uW9I44g6':=[Z Z"|nlEcq5Wv"$weeRRjR I' UJ6 dUO`mRWU=9Q)тڴD4a_xŗ!;[tFdEGI@K\PbFHh (, ty]A`qe}ǯv#67uDΕPO>ړvޥ`eH5h9uPV#n9*LKu(Jd \< *6]"IO䏖,=ȯbl4;6 ?C\DpÐĖ;WI0>MSn:8bF\+ Ty՟hC-@WL6SdMׂp\Bp\B p9v23%)N|+i.+$ZM!; q؊*}dDUUd^"41[Z=y`c Jֆsvh׶M("5EBE^EA:34ruЧ.腴I<ֲILQu0NiE 9q (Lw_uEz#>s<Dc(Hsc%x+9_i2oKm Y3`RU39Xg8))qUuE'(4U9 ->aϡeAoX=)23@&Ɍd0գev WsR44ʯr`i]p 5ǭ$"Da-EE7 Cu;Gb( T}lܣ}[/'mYsBHWȄtVaO4gbrnTk苗ef. *>=#0I{N_L&=]Jy5/cb`=uݳE=8C6jfo2iL cbCr;reJmGc8Wg&R)@o$a5m'M&Q2봻& )Ξg8ɦeAbrƎ CGSu\ӫ7~#ӝ>J\DIscsaHLd2 $\i6HDUd^ڱkrWQƃN¡izO=tA{ O4/L b<_6Q0-,>U= FLEz݈6UފM%[qzLsÅWVQs#Y-Vlj13r%,qf:ZxKR+6KynUzIQZyhm֧RxQY+2H230 qf."(JLN9zkdDInKN >pT:*`n(H*k3-`wH}4/^K`t2+Kg)rWJtDV4o51mȮH+Q~Mƕ5᪟AAuxY_agJ<=łO *Ka XiĉxVC>.7)WnM7-a@YYԆePd^I:6|SsEU--R&05򜇖9hZȝ\8?<ݯ-PrXx|Wr 8XlF&VF;_-u7g]7S'i3E6fLToAb.<Feo7^!=]e$TW]v5aN rHtQ"fD *TW<ҊL4 hHȂ2"2>Hx$\c Lo^`>5̷yA~ b^ JMH_T.Bq[>"BBD+! ιF`wq[bҤ7mexNG#]DOCj:/oK/]1OugXSqA W~40\.\.\.\.\.\.\.\.j1UXӯ9cY3u׌1m UI=:`9UNL݌N/p $ݹ'"/X )h?[ODTLQCi+A.)p ˆBJ'ʜ40˗PUxjŇ 2wM!Y΅9 wd*Jt~qX22yt֥J.:pQGo$o^[&)V)e۱h djЂt q͸Ȣjy+gjs<50tTeUٝVӉ79?3m7*1q-Jq=O QE7ۨwJ"`R5oKg&MdtblEW4l+FԨAFfEK3kG-Eّl#lWɣ UP]ӪB 9]N`qu<DRDJ2f(+o9#_pITU~U0**HeAdYM&&6 h $Idb*u2>MԍwdGo}tB<5G,t.Flr7 )d2Z(ђKoB7p>CF^^Q`OeJ8I1Y-JB>BAW#`xIAL jT7 HzNdIl*qMѭ Ֆ#Me`N>Z*dhl"YF|'k&9s-kjWɷa֠S,X"ja$dp Fк ggviroD9ƛi^ Ȩuƹ lU?6y%[)UdŐu9A;kơg]cUbL=c*L8W̊vq7RM|v-a0b\&ɘ"BH:lA:g\"b?:_Fƈb$嘑Bz#Q˩AQ0!3(a@܏`\өjc8O7yu§9$Iu]"!*] M8')뎆MU_S4.i Do$)T-ʣr}̜~Nʽ-G^5IOR تm/௘td*1m9g{C2{ ǭBn@shܡ|; h|@ӹꯣcCv~7@aڗ \A5P(q+ ,W?c+ZVmåaҽ)N1C #3jFmDe6eSh^] ?6*~r0{z4toy)pƴ%rzjQeq>CMHjm˝.^d3~$Qf\rll0.!qI"Pu-Ux}ŪꨀKy`۰C[%+[]7~᧗ 4Sy|6ta=XW掔tK&؆5QbԩORǝ\#wE :7zHtUMwSq~Qe“lƒ$֪ ں`Mmj޹i%G1 ]4M#ZA:MQxum>ṅ_nge΄A!W$*$/gqU]ncLo\ *1V{8 o+O:(ÿoWF=ҋWuyഘ2)Pm2HN5FB-u:ШI˔ht&aڲn7D>=X1tP$Ta3ҝBN51V?"T3E_z/^0GlGPJ b@B(AUDOwM&р_:QkU<>%=Tn ?V?H9b0" Y5$OW:Uɲ2M=;u0|~3.*2MҸGsdmOwBhcDajaNҧ=wY87=yoAOr"x?$o?ߜ ( '/?]a_\T`cߑei kGJXKld" }4g@~N5zO93R3;tqoEDTiv&oWFFI_0E;\Sym{͞P;5Շ}z;;!68+}_eF/2LF}0χ\fbRFSBF#Z}CSA-yl*xgzE鐘"]xxmz]GkHIUI|xNWl#цXdu~y^+}@bQh- &1mB%j b3:d$9 !B.oHE.d>&tB紅оTM5ƶ0h? )𹽱6{UQv6#Y]R2δǚ>ݒ ]4gN`ɵoEMq{7^B;+ӎm:0< [  OznXJZ~0I=Qb^Z d Y5NDocs/Chm/screenshots/windows_vista/0000775000000000000000000000000013225117272016417 5ustar rootrootDocs/Chm/screenshots/windows_vista/syncorsave.png0000664000000000000000000007666413225117272021344 0ustar rootrootPNG  IHDR, pHYs   IDATx}wES=yvfsva9,I2(I`Āg8ޙQ @ PBJQ5?`juRC|?_(u ~D( c(%kՈFbF DqЩ@" @_@*l3isڏ7m4[v-bYS9  ߼~-dfFXe&0bq;N{U7Pf ^e~PgQi:D/ޤw @A.(RQpnB)'!@RPBE"v"0B,ð,H$# HN3 i'J5yFQAml=B())%"i !dRRB#k"F-1 Yd# $ѢΒ0+`G?`_PЅ(H &Qtc( `@aLg WHY]^Q<@)p"z8yIJBfcgN#20BXJ(A&P`0H<$@a(6_`0kOЅA; ) H"Q.@WH>yg  @@0 wopBAWTMbRBP$J0lΦG@3ɑ@X (w5"sp QD_PFHKi^*w6Q 3^~"ND"! Lɠ LEu ;b[\\bj3oڸe>&%x yBH ΫMʰFDZR ,00H(_Bp+[A(P2HIE9DŽ~B׎ |H%Z_s `GgԧD#3t % $b*|E}b*>JPTt"R#D n(TL } <3QIV|1a.NR&`x* &P%~GFTt7wJM!SRVAş"񺜖kf`DY2DXWFItn7/7uU) 'P$wsX~)e),d,H0:ygyw߳.!,L{$קsiMxxtl^!W(o1 !w紙~ͤ4=<=36_P' _MQƖZ)+e݄8qtߡ_~r9Jz΂E3y&4\0k< Bp` WAIJRGԧ|ޗh=sg e )! Zܫ4S@| ɴ∾[Qy A @fN(RH#p |*8KM)S1FO4>;pI;8m`6KB=s^b62,RJJH0ULؕwMWRZ>k֤/Qyy)@x_8BX 0T )$ b=wGcm/1>y=;~Pw-zPOkT߽aR'oo6Tnv%L}`ʖL.;~r:LC. c$ 8e-y׶g^:se-;=#W_)s߹ ]xx;/[yБ?\[Wе4GEEBXAmMfϻ}ȈFuk͜;b8X̳ԴISo5wAqх#YXJdxZ[2hiwm{vlIJI%|wܳ$3[~w~ƺw/: oɲ]; 15c>[WBH̜w-Q*U/r|t.0izvnk{f6}k9}0` Bh \Ҥ# $ NK8C)((!CyRRB0t>U>8FR!o)1C)PBq< %@1B hAS!(&fY( NR?o L/'ޑ?> !|yyH(b < ``x]3SG3XDS  < iL&<6E 2bOL.te7p\(s;ݱu7±fra\Z_L6ҢKCA%COry$#K͸mK,b0Zng,s?~Մ)۬'싈QpD"=u@c}mFV}UUEFFGFf֍3Lo0\x=a:{(0C$$& komZY=-]KS̜nbFz>ەmkF"Nܨ h#L{Q7PEzyQ^rx ӹF } P''J< ._E'2,+0B4Z־y4]6?Ѯf C8'yJ,hQ>!b7Fҕ D m_HFyDۆ:WY?b_u?]T'5 &Q೔E*Y7-Bp<8=z/hŋM!,#5a΃|4ڹAc0 ,`sAQG2!U%ɅscIxQ@Bpx^p@bQloFhp N?A00 #H ٝ٤]r1#i^D<<(1!B@0ӱ(Bܡ} u 2n_jJHh22>! 4PFWyAJM%O\uPc}0*ݩJt|/,%!n)wN}t#!² aQpt}U8bCisz]-&(G'w}jA(ҠJQqbh>4TX싟$;Mtuu"vq8 ƈ`(„O"Bή"tlj)M1980W}p,+lRN"w}?+;rpPp!Pz ^_W4EA#1g( |kNC 1"e阌Sкsm}0Y:iWJH*A38(Hs^b,QRK[5Zl'ą/p)(F@DUܾRJX8p: T !jvR]AlD*"  xJiQTmd7"_ *.5%pPl ȧ|P#3C4x- 8CF}:=>)?})$@U_J w8+Kb B"H*W;It~`K\7"!kO=|`a"n_K7})@.(7#B%ė@NL@<(4 [9|? cx(,F,{ q<zCs߯"L("B O0%C/ 4;uȎP duUGGhNܐ?ױ)e0Ԩ6u- V#UC(tL:w%_P"_XtFxypyƊu) *TUtbt5 !uCp=Ӱ`g_]ƻZ[޳։μzw&:;9coR(tubm_߶]);͉SX'(ej}yB!xwٽv VC!.n Je*9B!7 kX0nE*"!` }s zĵKhoow\SQͫRȓU}2MuuuyyyIII)!{=1!:]+Hob^YBU]-=ٙEEǥkdZk +@͚k|_J3ܫy*qf'o2xJ.'')?zK}N5)Yty9gnd A}3"C1DEXj/raE擪ja1Ir1Zzqx8ыxaDl[uپ蹂1 ׻ ͧ#wlp}jˑ..sIR>,g,eip!)@ 5?AiIqJ9Q&/qQz 866Ztv Jn nջi_tf'i/YsRGrr5}a߷#F)%y\n-VZ $,{sOa1N#垂-ߟS Ɇ',2|f!s&e ox[ _2zLh+؄:?\̑W|}_Yz3fop_lԅGViXj^{lj3ٯ=:|8}5dyb[͈ZR;=3#'q26}Y96lC]``щg=}w&d H;ڥ/p8Z[[k剷''KlRyptыƩ;gh`mv/F%A7Dasmu&+erV'-;H4? (-&BiQj;kZJTm|"ce!=^RQe.{8whrX}n}dQ?C6m϶gE,-giFr!{lڞ80L WHeUl VP0htӺncմR! ﰃBֿfST[#X1 gl`fzʅ.-d8bS{ir4۷a@"c4ۖ%k}Bl-n[zl7w#~*1ђ2zV',ZCpt)2z1)O>T􄅭]289q.n4YrhE7}EkۯbG[?T85 U9"Żǣ)h IDATSf),HF~kB.΍ c'3l̔1rJ1,/JHH5j% Jga0en!jZMʌTmRqA}NVwOzxroV <͌HOՄ˱BLOfGK6ۥ1Kgv["cTz7*7Q-|^Arl6?^«4}bFOPzfOrϔE5n*JGfF'i34r,W+S=3z%I[ zהiᢑ$iU 9ڬqk 3"z*9z/,떑%HG#6a4Zs }{L塔S{ĄS*bcF[f M l"x2Iw>` xWY^uRt]e%ry"J2ڣRXň#I8,L`DG++v./ܝb`@ŗwP׏)S.k@ψ-/PakT+W)cbtDD&9ˆ!_,j]즦xacD%H ozF%}\,瀲0ak'4!p-#x1[uFFf&.s  NW%DžE+Y˼^#~HNIIt!\q 1#<%+d@twZyCۘ 6Yp?rxftHB/481`tCK|v ;vHa pnǪ %s{;iw-l2ݷR )a*/;qnA8kSuQw>ŕ+uhkk?lw@әgxZ6ZtFN|5T~/ߗ8_i8x ?9;YϖCWI¢ÀF3›of^㵪! c.X`IҐ*s|NEΤOkezY%lbz&$I!s8v4;;AGӫ޿kRغ'xǺY4Ä́'!W7O697X``:f$yӖ慖+VwA 1 u#5BbSj !g 2;J(8BA@0B&G{G)0]!p !ƈTx&(B7b^R lEB&B!4p1``EDB7"HpGP}"n { sbBq*js;)UZ:kisXgkupkGjڍ+^^Ҏu6<Gݠ '6-S=mZK;?_T'?i!_ OҲgqR݊vÉמ]/9[޹uKz\#Ϭ{X]{5H|r@IQh :<7X_Lo]827_ћtXBQ1Qar s;fL$Sݤk32U\tuٌzCFl&:=<#wYCreLIfw+#ewx\6SaOF[Ud|F9Uxt2LohC4::8lnLUJ9׫#4IgYXdl ڨ8noַ!F+Zm- NIXB\7<*b"\N7U`oL0v tfAkK"rf'H3F  oo֛+Vda@ЩS_x,//Ζ""#`XDi$&'DFǨd qou$hp9ʢbbjFkh;=|XT|tVW`~\ׅ޵yEᅂ0'Ti"=mN:2.zzCccVM ^02U[lz%FGGzl84Z%6H)C̺j2j^npp gs𒘘h)u6(b"c ^>".YNvGӥFGkf]* QmKō6;_-eN8Pu`8}S~Q3gLHNYlE [YU'Mcዯ(<;_W{*3cޚT$4dk,ϕaƐH׬~qlO1u&Vܕ&q$nli򜂗椬z> mFeJ8G}ⳃۂ-M޷qL;u-+Ej<W%%mHh:g̞vcm}wzkUC~iCyG/|t*?Ր꓃6px](ۧ|4IY^O)E۞ZbIr_Y~~ ,ݴ*}Yv`x{~C \z]<6rDU,gA Tx+&k_a7g#+qTVg\3MtG킰yZ~ӟ%n{uk􎱔:y)?lL';?W h,ɟcn beZډzu|nzϾ/Q˶"ꊞ4.#R{c~k1݁s{t=E=@=p'Gk+<;Wh@8[6zH7sZ@O=|Kʴ5ՙm5gLH\򸒭T]$<}3?WhIP[t{Ye`d.-{O T'].by|9O͈\ZexwҬA< ɸ=Uu^RMJ74VL y{Z~Lܘj\2f(k _~핊;>?Q"I#=7CR!jV*m1jU*F0#j-o{J(D*³b [\Um(g<3sN)3TQ7f eԜ%);:6ẼK$#2dh;s2X%'{}bEv0Uq3So~l3|؇5^*j؝s⮦!,εˁCsYly~}B{Y3ϔmq@nm%u o\F&}0Z=x*+lJmF6J-lQj"bbb<&V@|\ҮjRMScֶruԪΌg8u/Rj.w'DfkSCmq~97 Ɩ72~iY/*$MZ",aHyiɳȚ3&4ŗJyJ%a#I~xr뉭uBB^H ;55gZG23LTrjV&*%-Fdٰ7S{jyDzV& l{ {?%>2%3Jm씩}URr¤sD>W߫א=OHٷ7w-IQaQiɑ0'c3lHM?h[̈_*.Վwۄ1;%1_B$w1=9ZMt *6yCf;u젖NWNYX~B2$%fI7O۱凲:[n5(}G >";ZOM`XE {9F627҈ Z%8Z3\4Z n_tV(}j/?^"]?|V=.e&Iݼm(Ra'GM?rHc"JM  -]!R!CE NŮ3ri3Ooi'O ͭ??f0_n#וR>ћw^x Ԝ?O .8';W+B2!@|Q7;:.qv\foӵMMhPW,wITW#T!QE$E!جZmWc}3ruʱ&~R+KNJݖ͍JHQ"GKêSbZlREB|¿-.;`WΣ?l]ezR[MJx?|fWXtO7HU/߯)/uClj9k?V.={|&)1XwNXLO?xLϾ|ꕇB-78t楷"-O~"n0>>:Xc$%,;X5XU}i j)kEgJWc_^5rl5}A,ث{a V~C󾭭mzue-җY,Ζ;-<|y]Aڊ8NG/ζN*M%UN785rČ/ceUUM&ӹ#?JHZ /Y/WU5L˗L12fJ.:`IV>1)+xHx++7:O2V.^;j,U.\*5cw`.t^oj+;8cKO=1sP&{=,[BaVޱv':9.YL^SRrrq%;Av>ۀq3zꩇ%c4Qu+.[NcQC>u0BHbV^)M~]:=UX IDATMFC9dңO>6}HfdTByŅFwK^{aYƀz=zO̿D%J^>ltVbSW, 6A\yd/%펛m3ie#=zd㐺?~ŗf?_^9v&`Gᝯ"K;}#yyY40b8O"ƆěpVY9sǬxA<Ɖ2{޷b>篴-Ujl8^},odlx[//xG+jE!w=gHQ׳J|;S<߽4I,~pAIO>87CPa֚sl(S]Ia#'? J::[7Bv+jܺhļ)iޝ%'hcúNM<{=>K%$sT(!mom'h+$bFJa>A~~[㧪>ts0cLۙ3V7qH$n!/4֦!`ҝ+zdx;iI҇g.^Sm|/8RXA!R Wv+9n59bV_ P\5xJ$H:(&U`QQ^)7K):t\:/9B3#; 26"ϟ,NTA v~}idlx0<.GlbQqA%>雙k@5_f5?(;[9eYaodJA# a HmQ e=x%KUkxCOIxQqփrΝUsŅBjiUPuν|{u]e ՠ*+ڪr;Z~O8VWV5m^0_>[?QW_(od`١d qB-,[_T 1{zfWiIB#`8H&wbXMn 󵲡3Ovs۳>!^4جk8Qwܕ.[}/js;~9GkܹbUo>B n樫f/&O+CgZ= P`ղQ>_*&j%\{oьZĎJպ0ɪ(inK-y?xH鵏NXhŊӅUѱN^~M]$4{'y ja GOO?ȥySyg:Iٝ53ڃYGZV96JljO:uo4ŪfFsZ2<\ƺ?'yӇ4Ud&T\ӥ4Vyڕ5+eKK"w}{ܤBN :~T[b⅄;cNM:J:uvyt}<9 uAO/[L3]ˏ8ZūGZt/|Y)! gW4$M3TRmA/="~a_>{G_l;e!118k=ێJ3'44҇\J_m6jRkCi.n)UsF+UC{t>_5qLCX ןF4o[Un][Ʌo`uQٺ6iŝqm970to۰%>sQs>6ǧFK.-NZ|H >q᱃$UlZڌ+9wIU_^ZZ.iZY{fԥ#GN~GhH?|ޚ"Ж-E^oyeR7Ԗ峂hY[ǻʝYynsQ3RBIŢ=g/=wǏ*S% MphhD1^,}''tv`iiA:yɢ^ipplz+Lp 7Ir\f+yWuS_+/#FjPj䶯rrΕXthp$Ǧ̞/Д:痗eF;|촴H2$-!eIMK0;b~{|tҴDY[=a iXPOR坥(s F@n}e$eHBjKeByyMo?/5D>Iq2Z-AgEfnpf! E Y aPUy)uQ!#(Q.E$["[\Ђ`ku%cH' :רxӓcp#qBC= H+hO_@&B꿿ٳ/~UyE>{{Å2~Ž?PlDhhro}vkF$r4YPϺqgr6n>xր\ώEFyJ1t |FzH:{SE9(_Z3 VCNJ"ttʰϼO%XtG(ʟ@ ӵ~v~Q.rQiw5IVھĦ-'[@e#}^W6,SBO0B)#Wo:ݱ Dz~C{5۷Y4~OgiYDli]q[׃ys* }1#ӽ'*3"TYsjGpBĂӍG6、4uE"CO'#'v]5 m۷KV[}WG(KgVM\#(mVk{yn6!gqL3_Mވ`UI|_8Kw^<*́ȃ~%#Юy[[76YZC,oް`Iq \3hp@םr╫WЕy'/_l?]3(>r@yz2^?vV6}ź+3WV(xƱMwf3~Ce矛GΜUL_ ;vuGxdw&yVݕb}`Suni3mŒk6n"(_&x`2F[xb `>*V:v]S\COHㅃG0Z.B˲vs8xh4Չ/nЙ6 "T{~ߥV>뢨Srgf_Dޑ2O_zQVcܫ 9kK}H}j\]iX2uM'ݹ\}z|4"cT_nXXc5szܲe\[.I[8.`Ŋ?izҏvxd?lhY-ػd%%UD I*{ZT6UxƪҚ߭=پi=/ʲLMkCNoj(jˋ~u5D#;:vSuo~ڣ[ńG?- 9&Bq/<%z eZsGK[ppbhga XPc6&YtqwPfJɥr|i\rpJDd{ޞ1aՂ*ư!!bSx.0d f]yeP:<ŪǤRQGxyZ 4MY NDW;w~U/B>*]6{kqݏ/bCֳGXI7WbgJso}1gAr:[n!a^싟5J׷V\?u u+-]/^^{k?mڡKJ@B1Go[Vƪ8?' "Xk24|GQWYWf<ܲ2Rf=4,5u d~[c{lնvzDf<$UյP^bp0~zlqͅCO3Sl2v(Q|%V?qRpP;?`S~Tzhvl4{%k(O[FBU:^|eCuf2Y5FIF [NQNyǬgBƃ? mI處?l Y8V#96'M?!,4C[oH9x i>Sf,}w !;RDMfdK&W{ o=&yۏ}GF{G/z]\!@=13No}GKg%&{7\UT榖4vܚuz&D)l-^Cc}$"VR eq#ǥ&x4ZRe,/SYI!]lSZJJ:Y@H} *>}S2);u6&>5n]⚇'  0qzG<87eS-Tae9_̄s}*cim/_Og껔mJYBC_FeLsC~tAcB a-"Ϥ6qb!bDL+ H9 S1yM74B}bEBK"0T&@Ӣ9[~iHK<$:{d2uEkK T>ީq wl(bbmᱏ bȌo1EB0 M# T]%FKEF\aGcȾb 6MKiѡ)ILA<;0nr!R]ty'IO8{D99S#tK;C#2Ez&%EG; :D!G3@[hVEGʁC33-;)QKƆa(H/UqɦC&e?$GGzx{H9,L >wKMfO%>>~ B5 OqzKlQ#FE`2$&~Bz󅂜&ȴ$ڋ3M@k 7=St%|gOdm(+}DOERä;'g_8_\p2uDbT|Roc_*3{bP`T- r1iΊW ǑS wdd滬"*"u c#y܄q>>aRcbƍ躼|>9cKg{k9ar/}ExS讝 #߹\=9mjrgkRgLM!ҼKW>,Λ/4  ȄAA)g39ʛANO 8~|ai;"HMԘ O))udz'MJ3REd)m11]\ui' 5?Q>||в/̥ry`N4)=}ÌYu$Gչ{}h!q˰7(N;;M۱ C >>@Zx{6Oo)UE>P~Tas_Atn9L;j*۴[䜣Iχ ݌Π5Fm+Uk֮[9,Ykf3j-ΰɬVi;4z `sMv9טc.M`5i}U4џV)t_~ަPv2ȧw/ˬ^D1wuZN?l/޾5 ѥў+O}t9Hl݁&M9fdSkS~1B^6x2v޾m@䡖潇bE93B30(?FnG/]pς׬R&5<11)!(.93DePM25Mծmko4[cE 6&t;WVՕ+mVBf,h8ׄ1UZ Kto˄H}nS:49.wB$  $[^[VWP:yS#C*S}O͈d'\.hqCüήK`y8Wg=+KϢ cjQMnր7?3xNwU@emYߣc Q'0@(Ky5ɻr(/[σGC' Q#0`(`z,RYu#eEO.$BL>";م8([GMةj=| b $ź2 c/ݚuOF|/=!N᥵/ e,}|HDz<'%//M ԄNΔ "3/MY9Ak#YIh& GY:GY$MM  h8lV2>B4eztcv|iXuJ?GIFy r%%@ws7"B:|BCHnZ+8×+lGvQp/|?bw4õs5\h \#JZ1UPK!Gz("}S' Ƙ 8&.oNH$!tѣ>ZUF[}ɕ{r/_•SްV_r.ڣO<&3|oZFgwB1k3.ޡ78 >tWg[8pvʲP(4}U{^y+QRF@&_-kF"HE]ezw64e~>"^x3厈3&@S;6C#䬖!d{cf;"12x b9_Fw YbbbEct - h=0N'=N!  ΐ#=9DSΩyOZ!{XIn"6ӥs%VzRֿ9j jۿЋƋoHvkB NۙYe-mnK @ѡS N~Y9o(T_1LfJRZ0)-a/PJb7M;7gEq[?Z͇B&O}rå9 -W'NOlj*,H|,<6+`93fEvjLJJ8#A`ka#O.lۖpԅI $9oB?`UHpBL\뾜ߠCdM"<9zǮum;N5/Z1U}2[ɋ4޵jaKi )߄8W7vBM !lw"(B@QP=$KgHIFxb&+igk6GDBfQ&O )rN''*R&lBVhäP!7ysj/ M* <. .Ea}C$ `Zo  j+3G?9E ]]]?guŧ_Q&4}kcܜy1ܵk7{6|C^ʒS3D2sRo5eL{ ڮ aPRC|>h<{k2l`Ȣx^޲SqNrd祴&ƥKz{O} ;eἐf{.I]$ĺcTeaB4?$N;t]?dQ2rA_9ړ|0i&;)[[`9ipvA3 #`) vhDzv1hDz@SfshC;Mrl !f4 Q DQHP 8% g@ ;yXpVYB&v1&f`YB1 4Y(SxQg\~]ס^23\ˆ3 C;Ew7#t})J3¾1 hQu ׭z?yl@7zt@Huz%03/"93Nt[S,㻁ǿ7L˃ǀΚ/̓G꿞5J<ygkkă~`(/7>a&m" Q,KXpcJ{#̠+]yey{1Xpy$!BScGU71 !z t jϫk4'q3~ԢIq&R}"kpnGC~ב:5FKRY((L FNp0ǎC7( P.pn|݉7ҭfPpCЗ:s kh*4) 1E4vJ!Wtz[^kȐn;'W Qe9"!箪 @ĚK[Gw=q~B7Oܤ!DZ=Z_})'?36l muIENDB`Docs/Chm/screenshots/windows_vista/readonlymode.png0000664000000000000000000006310313225117272021612 0ustar rootrootPNG  IHDR,# pHYs   IDATx}w|TU{ν{2I&#(H`6못k `MB )$>dJ2s~;-tw}e->}rEe-+NN1PBQ(K6#IBy zQGNB (( Q@9 kh1P4z Cgc9bM8!?e|t{C m梹-Y-238NЪf-R PJ)%(eCǿQ ^Q|B(D5)ZFi_G4OihW4PJP (RB(P^p0f0bXc*LQrxxtVHT8o @ 9%@ {!JpPnP5(PJ)(GS" !" `3!BpbỤ!V/'(%FjGF"$5 RBQit#!!j_zF~ `Cx($FJ)+bfzY@ȠʅUHCIi^QjJG5T8|@)(BG)QB(!BCÈ"LYaL1˰ a`8|[yaCap@aTD(P 4HjI֝pn?|i0B(AQJM)P#(zH!TcP@33Ƅa(0EP@WcG5dёƚC8\W14w*Kj+畉A.FR̴EUe߃i訫,mmcMI.T $,HX #y v90.(TAB!@!F<\y;B<4"` B#`$lc1BWcy B0ƀ>x! M.D7Iw1O%B18hTQȉ)wă.bȼ D;|wPC0B-GET"I I5qEQfni4}Yy~h}T&H:&N77BJb\ŧr3.^tgnnhkmdYL&W*dZyןw3:m( pRy+y1GaLr YCjZ^tɕ*j1d8pn5y8WLZf΢(E v 1!9OA>(ASD 8ERHR*88lqQwh;҉Gh#y~Q`'oGaC@8ޣ!YmSL0 HB\ERϐ F6O w9( G &|Tw&Cq !(SB 4G3;tGG+6rXJuw[r er&Oz:]C]lV(UlVK>x}U^J}3+mV [lxO|ޫ%..G$[U~i_u.s5 9;{bYfocOq3f\yئhOOHJIM?RUÕeg 3X 0G  pJ1F#dhtE4ʩA#hFס Hp[(;vxQF#"!`xVT007t"Dy2oa>LJʀB+O!hp(Gy`l+hrCPB" SP29"ˆ((n~\}mucC2Xe?x9ǵ5m^fguxpeC6;/]PwduN]֭~WfpP$)"(Zm\(dlowb__/eۚ2Yzfm|c^̊~ ! Nt|Ƽ.i?31B(GRQ1h،LF#\(hP( X ~Bb8  EI_4nG&Q(6"툢3 eGI(BJP4g6P tJPJ(0@ #Ee)HEF_"b`xD̝8o̤Am)*[R]U9`28sβڿwϴgtچV䴌޾܂b,G-MM%N}sɕ3?c{y]%8ח7p|цqOcҷ^{q_K]֖E]O^pL!+ǔL8W(Sj-KnRӳ|~.oxM|~Fرuӄ3JZm5|n6[u ɈRzÛ/?kig->?O}#qF=ԡ(K]e C(J,ģ0Ba(F5MMtx(xi!"I'z, ]u\s3p62T!<oEd DHBRt#®FZQ 7P%Ȟ 7"X³PH&x`EK"ZIA^p8\;[pɍ&9#F|P(築'_F"P6=t 5jF1*"Ixp9pǁ~ }8Y "K1T-0 1Ƙ8ev(>D;XDe"°h FDu'PJ(pJB%4 u0StVC9n&BQE 3aE|GFhDX&(GQ5toʟJg"BE}ōg0 C.3? eh@E8T: 8Nh;? p(~Y߀GPD'Gf,5"Q1q!y0U`%@h,$vI|@0  !Z!<9=!NPtnT0,CF FLH05B|AXTVcDb@Y$fC8~weD(G B…旨iaDBJ JB4F@?S4D hPAN(E4hc;JwTg! bn |pm((yB$>?=FiR4Y0`"/T94BLg!4r4> ;|G(cE`b""(P▿> |@(zw'+Y38bYL4 &RXZ<@?@' B`6f4XqFԋ P4J;7v" #)a4"6@o-' DxMLjH$?GmX()`0`&8FFG%:9lY>&hqB>ѕ#jqQyJ`P. e N(&6TȠ.3,f0PhȊ44,ʜB[ޖ'1/+ 9Lj'aN]CQ C.uY Jocwc{#BpDZ~P4J-A',mC@fQOD̠ȼyDzO(;{y v]>DDF?;v ղ89' ,DȉEDMЏ> 1<7"8 9JΆ$&'S]NČz :&&19e ?Bb !0&190C!Lc@IL~!a%$ www *:!!!55U0 ͘(z ze:NTXDLT:d2YCcFi^l}'Bd:x@zFoNZkwp$0%[p;&M| ~Rj ǍM;-qivsu- Faœʹѻ"\޵2|8G9nW1sjvLۻ~0MԎ!u-{a:c_TaXgWRUYiHYyY~؏6R'?Rsd2$G4sf^uVkT]uGkW-ߏk̉IWs7CF„TҭG;($zq59W_ֽEolh|um{'<'< Q*\}}Rՠz 3%WMHQJίu5lWgIB}}}\\Hs㼫Θ&PHNhQyŪj8䔋Lu=8Uz'-t=xM5M N7+k;=77鳊ehɞjl-{V'R8;A@uiC<)Z5Y}wd0TӀk3|VytT{.Ŧ|bdE9>(wN+'ԠjzȐ~**Xオ~"' -{k_opM{?}O!oo7LQtT?3%|SuDq?/)HO>bt!Ш}.Ϸk `Uޞ/N}qL!:z<3rz;~Κ ?DE鉢Suܔ3ty;;;G4k e'&3Ckh59qsKW~Y_׃ƽQ;Ro:gfn]lIna~Il/9 nhwXYk>yeu4ɘ8#oq6SQ­]/5{:^Ϸghphmzӧk*9lywQx}F}΋N/q6뻲zi ͸&/;llpy (qx{gܒwy29>7^lX~ lLuB ѱ'0ˆ5! :L}ZV7<0uEƎAquxQSSVVVYpTI<J]f-}fS\)Գ_x.tD/*p؆ʻEcDw}= AGcFk} %ʼnF-@h{rJJ뭝Iw6Zoo}V _Y}1f2 25{?A 4^]ZiBhL^a4R;6 o'&q`DlnR,r%* *1(X>xƹS)I0ԛfo4|ķqqiژb02"-.5 %\pU; @l,]r:4d@?رg?'j%z57redB$.Tر',{S0?Hxȴ:5":nAjٜ+}~j,aMl٬k` m ŏߙTGV[:{YM?ԛiJ;b9uG8CjDmHa@ cbN>wb`V\UI0sXPWFE |cJn|s:\|OWmf{iU ̜uѵIdxU9}4{ww\qY%.Jij81"[S6>1n iKRԚ#o( <8w͊o/+3}= ?X%c_] *YX'?cc~Ѵԅ \]-5woq 1ʯ>7OʇTj}feG3܂;r8ϓ)JV#9>eҺْ"0lq^+TUyxs/ρq7T^ŪU7w+ }vep}V&c_Xd-$^v1桃-36%Ew1x@,Rb-q5trC;*yZ[@C=0Nrl)Sfov%zt˗&IښZ2A3=[)mFt:q4٥81L63&JP3rTq蝹9"nqb"Iwij3c ~ůӥ6$#.Cu[~λg tڤm"R,Ýhr娩NR%llmB>XZR1'oX7y&_efq"3.qls|>2R$s'[lbB#@L8^*^37^MDNK _K{2M2P 燗ijp IDAT3( ]#qrehD 0!W |2;ߐ[\6BH&hYIY/R٬)Q+k(8@෤Lǧh@/%WЯ)(;n8#')1^&F~8[S_+YEs,:*2 ~f@@0bk;ހ\!c `(GsD y`,:1fCZ@a||"Ox`sx/k|S:瑵tozٛ;z_W8Q{CM績XWV1_9fk?~&ނScz=տcMױUO/:gn=$t~|j㫏o@kUc|5dBz')zԧ_sӋZ:Nh굸t)9j8(eHa |6e3 4R Jmv&$'I:$1"}}V#dMV=9-CFYk_Ggv<%rpS2]fs3tԬgmdn'-odcjh+Yi>wЏu9'R2!*MeUBZqv6wU9IpY;[J}Z^=5%,>ܫOMؽ9c䤵lG4IxO#<*t9bF]@K{$Ll1>1C( 3-=êČ@GSŕQ$Y2 R5f1j1PV:~E^no=*9bрk>9 q׵@bfaM@hglmDc.}ZW v1+eו6+7?hmvKyN[@{@Qcl֞.9?M;bEI6c2!=/InrUƦ~[w5=}V|q:Njth Y폁13oI'!{zzd 4LtJWTyULelk>ŸEe.l?voMу䌉 [?^m纕'N~ύ};&%>͵IVܳz1]o[Վ]'N&ij۷iP5ts|}CA_\[5{5R5woQ+,~[7Xs-{w;tjνk^zٶcš ĿK{Nl4q߶umm_Ղ{ַT]L4|pVEo.-@ ˞vȽo͚s !_@`ҹvl7̹;j涔Viج=g_v⦲-ݦ!UK.\0?=p|֋/s/k 74_sW]( Pn}lހs+oӏWJco/_~hǚC~CIc2[?;^ )cZԼvcus{󺳼k6L[xtF;՞v\G#=&&5Tv_{A1ʓDl#_oَtL1uyM;g(U{liq=J}j;|`RbM}d7y]etS1@9nGD@*HSV,gW-vF$fߋ&;tYMMvJ/I:Q'f_ K"@g_p4|;wː+Ur~wsIfjɤ)L?ĝ!WOc;o\Κ޴7+fJoZhQ_tGlav#wKD 3SK&M9ۮ*#MompٽD|?_oT;Ibx4X[iʅ#UkEv0*dGdѶx6Ӵ>=<Jp!Y%A3Un"n@;UoWO*(x|rvaG[dխzW7K%$BsU"yt>wW閮yο  bjxC)^a&Vc rNP".%Yr"hi3J1a!1w'#1%J>|swlZaCd1S7q.ESG[ovRuq%sԉb<mLx}/`q}>.%\&_A5k%&8mn!35^ N3 R?e2sUR4W~2I0Yq)::!-Qmk1#4^].ej$nm!5+O#c^T"Rʑe_tY*ˀW,QFlÞ!9m;'rV79(7ޡ.\$~NyLi\VZ2h4qyqfSu  r|nˇŜ*KHa(^ ZqYq޶^/1-q:IvF2؜Čxiht1xfp8`G* pGzY&'-q4IыdY[Ok vXg'$݃e|jA3ouǧ$HfJK{4v×ZY*+3=80h9izVdD+MLYz JKLw*O!D9_mfeݝf\LJ^AiS~gSkGD~4)~6*Q"vOևgkPMV?rﺋ0Ye ttqK2ȭVEbmpmP]ƶaI4 z.kdwPh8U i/[<ϡ?ݿL(x}Nqޒ )Ov}ULv䟴j uc_p-4 Ϡnlf6b^ϥ, iʄ?Ĝ]gdGQgIθrVU0V4RB;aAi4~IzΦ]}X ˯SfvGXl8X4CێxNf[pL]cr0:{ /qxlpMgN+ȏ߶njzP( &f椰L3g䝐Jg|1)\dC BD2or;7dkg=(3<ˠu׾ v[=Y[/ Z?@`kArq/Wl {7] c9eIY:͎rK/}ͫ6l8{ʹs̝)3Ι +*FJxa #Sa$Ҝqs-E Pk;^zC%DaLbr (|v'0zs@[[>ݱx{j#io'POQL3jjtsmN)48Pޅ$|S_>D#g;{^ziy,+ ' ci3t( 6~kCO/<;;up55>@gKuD{QK<_=iIGSιs%%32Um;=@v *xk! 4jgTݺ\s]yiܡ=[ZCL]t+y{yoC/ zroc_237BJ`t ܸ.2E6k\ϞsK(`SG/!:D;yΏ"BGˏ_1L;vݿt̃}`S8݊~w# nKǴx^~? ުox5߱ёI/Oz̯zd;~r;Ϙկ7mbEWL杫y7^~;U~jh No~cEʞ&Opm]c'ٳ=ޯ?by3~Y61 CwF :~I `A'3EW"ٻkWoIJ9'[=fP9lo[2 bQpeA1mW]e,fT*.XvFye}圄igcცƝƞwWzׇtV#%bY"D86}4Y[|TQD /^VNxO8F"&׊Ӕt#4JcT"cfɓݟ6,E9F/zʷ~~.-]{SU8`9kޅbo%$Wu&Lrv᪛3$(^,}$:'ΛsvZfrrA ѥ$&j5qSq}ko3N(NII4*!3jkiy&M^ (~u0gd:,>W\ONKѪNo0df YiI֐6saJaevb{WT><_b$CZ\mH˘3{њq4%%i4!QRRΞ;AU͛v]C/8Y[2eFIRΐx:=Iu 'F&m`81mUgɞ%ijpٱ>ILN;En]!ٸs9_O 2Q (ILN GCz|E 1ɩ!zĪc_ ʷcS%H |F%(EcSh v(@ 1m/ <6Y*a0&5i@FRQO֟\:C`L~"4 ) +[ILNP( f0&198,[_ !Pr5& );LQf"zcabPox(⟬ IO1)ǽYFP#dTReHzUFO@:f V'f'|WHC_lӍr0';O8 x>]X"GU |qM.x`Үw)DL~,J)DXkr ڿ&bIO3F.3 Y|2^htHO7ϟΆ?8c!i[.xEE6{„E]oϸ%-+~@=S '8O>\t|yMlf$&'/D aN%pKԽmmן-ޖ +^x;iS_Te57/y+\{oZ{ּrwĚwX6ܧi5yԬ}ꉫ~ؑ3 IDATT1 bI~oYWkcJE ek@ L|ڻ&En~7pE٣4Vx !{td;<{N߻}ϧPZ}>alٷmw۠?/C?2% Ι" ՙSr$z1p9ӿ{ti%^[)JLNz`Tzַ@aKNwSrV{%3 I`UZ9y[(n×KWNxLVP?V ".Qɳ˭ESLJ/+G @ YK'Z 7 @V]~ɆҘ䤣p"8Uk`E"L&2,I}_RHJ 5y9ggUtD_9}Vǐ:>NT#fu_)\a6%#0ݐ}F͊3jqFtѢ/OόU䤛Afs % +7XRu2,Iaf"ʛEKDR H$LQ`XJ`i4)uqbK{Uy NI0.Dg; sΙ[R`xOwFۅ7_\"W9))x}sI,]G8 #2keM*󉱱0KXB PJB2ezeRڬ)s\ n2o>3}9Fw g Ӓ ۠ '^8']3195P bT*J$iS/=UU0+%19ʏ(5~=uj)g<;119uv3af,brsSKoS? eZ}ˇhjhp=ܿo^R`Љ *RoO{wth'1ot}XY[>t]#[9OGuq~~ֵGKy0BiЯ ۨ|ѫN>џNVk> 6ou,8̳2ڻIOO̵WOv~Ac[]UvYrӥ25-ں#;pQ^N3ipolӖvwGq];3;;۵:$ c+6<clpq''yy/9yI>9T&D .j{3s "qx>I;;s{st"$ |vCxꂵZ*hJY1x' u'[=-;vTZ9O=PĠXCrZSQpd;@(w)|ݾZsݴ2Mpٲu#7H,GS?nDyayQB?KOYVwd9Lްpƺ l?%N6 >W}cH 2k[)EPwĎb?=$> @t0aLw۪kogYlM\cl(}q|<{NTGYB|,zǐ9x\־+@bx.EU+l,Okh@njQ{}c՛Gl~㚙zOg;wKp3 '.Cģ[6Ie-a`J5ǎt%`l^Mo<=SM^OY?͝@jd(1phҤm_8F$e\m7'd#֎.g,'OUՋ7z-~R:o!=x…Y~M[' @KKs4K^yyq٦=\Q.R'4kO>@׮9~mO* N^wz^Ҏqsygf>>RC7@RwB6Gl{z7|ϑ.P[ĥ?׊DB=`4W'?xTu@OӘ Μkt`)N4..~rs bR5߶e %RR"E#R2@Q"m~+_|a|H =QUJ)"D%ň%C[yK"W_|dacLOݧ4ۛ^ztY|fB.(\Fhf^2Ir$j%(^,~Db‘n쌈[ٺqaV F)76FJ3$M˵(-Ӵ$!\JHRd;}vsUi-[k%J< tD@,%XgeRDpH%bQ"D]rţ_9 "Ek{Pw9/OYqKeḃaӥif +BQ^| ~*a/vT1 Iwȱ*崲7byc*A %l)c>O3Ҵx󣥉Ra+D]OrʪzS2TF3Y3旾2"p9mVM,%wj*+XC#qDDpȲHbJ92b+\NugƘc{>&YyW.m'W.rHu}ohNIB`Ğ2%%?'٠fHJ::9 H$JuFfYx2iͼ,DRSIzCI r@%y) v~x',$~|Ϙh\}pz]N1B"djaq݊ CeiRZ4Ũiz Aѩ: TI-)T;T|i;/ie%᮪>VjnZ.UV@k4*-{/\rF MPiKۮe+Jc$ē@LytP{d0]x|Y&@KQwg}6L[WQPChYy˧/_mq-ZY21q;ޔ7siI䬬lGWjd{+V$?/Gx^d >N`N$nɖ */w'?HÙ+lv~Qyp׏n_uWWA-v2$Q`1d@݃zSP+ߢ !}…%W,^eΟW @3U[ʼn60,GBУ0*-sT'"K {kD hr]uo{zm~QgF+\hFv8.w 1  0n#FMPFxV PԆ .șlhB(N <9W  N~>?L@C|@"0Ҡ 87pR B0DWP%(ۓD?д5ZW h Lœƛ@BweC)|!8lR]ިX O O1)ƘW豃w:CP,Q߬;gQGӵOu@w`L$e΢GrDzl,[^;~?;~vOO۩Z?:\ LE7HQ Fv]E+EZu]smo}=;?w)WǨ{O)1nx yg; I|j!E)eH.ox`d? 埽vuHh{>i< Hrj>ֺh.-]mvE[,R}'ESv_/~ߞ}O'̞0f_|umb4D^ڣfբPRQQ>uݏ_ꖒ/:0!H4n4I7/G-XwϖB)!Z[}mVݤER 7CauD5RhFS4D1#Scc \DX4xEL! Q|J_M#хX,52u:̂:Iꍟh$2/k^m+UN&1ď(NE4M$EQ˩sH*aDNClp|'oXc#C_Hstj'Yhx$/L)Ly[+v 6WUSSw:;m8ˇp~ow x0B1gomvhJ,ڸ8mc%2$JfwL^U"rÜƠKG&H"IJ!AduZ%EHGpĩzD$[}QdsZMw;DZ^D ĂbR pcDfG95O19fl::*6QFڬN_U2 [Hw{i:܈ 1 sKT*hD)izlb>! A/ ư8ՠF@wd$i:4!@?_"G#k& "( >fCliIriDjuY}XDQ"l$r{Y29Iu:}!3)zmxգP+T 8EaL:H~aYyl8"SktJYZ"K+Iv_ bdpz#b{.#}N#]&WoJX׍Dux/Pj uBBpM)_9iIXrbB^V3KD؟TAe)_t;+/k>eo gMl[M@+^W Vζ5'id}q5K]٩kVy͝3vVhb_xFoLVmӍSGҖR}ҨP"OT3+hhinr$A%ُN]t̘dݢtyN E^W+/7/loGMj: 9Wc!B5g-۳Rt[ ʖS]mQ"d}f^A_ml!m "6;ܲ(,IO 3W>|k_ޢ:׿_Pdj,h˗4e5- }]93ֆ@g6 ]vӘj5U,k;w}z}3ɯ|I-fUV֠1Y?vL/״mIܐ4xԍ(kOԐ8T<(^ tގ~F3KW6^tYm!RJ<y$>_yMn(=oUl4ehz_j<<%D"ڔG֕d&"l~~$>2,u%=Ԅ~>xTDMnv֤,Ys6?"Rurj 9F_1oQphK>+%8jky;(oڬM[Wfk4eK6?(WN{kGg746鯬}jդ뵵{{mXBbg*VҖЀuLLVfYi#NWybźՓP>g)k7}Ge9J*e9XnH/TSlswv5-{M伶O@ZiRytVv Q0c[WC:¥[Q:6ES/*;Snvi߰V6]:* 䳹Q޲Hy1q lhpJ Z:H͗W#:9€AP.vLϙQ9iWB{ƚW&t9:bhS{jnJKC/rzXqx߹U)4iJ\9AHgohw =S45נ:9E"0)fVg32.@m * 3r=NCjz{\h D;:Ts#{87tʂTM1YMqKt7U;Ir»;TgY% D12]Kt^>?gtAZ5vG.%%ٽ/w*sBo6])q7 s_q<33 áN= yC|Ld)|',Pe !J[K(^%aeFW6?m4()k6Bgldc3tT9r/f0f$ЀyKSj2% [O%yR:QOMa>`IXHmKr3o#řbE^v%S@bzBl'JAwhrZLAQ]Ґ$.g>XAMJrTm6&ǏiQn P":%S25`NAWT)FO|j2c0ѫ6l"%mNYa$VIy9ZQLfeJYo} Č^:ބt^`gxuu_2os0FE,n֙3' m5r.P3LKS}!}!Y{>} 0ƃcn r3'j٨b^R]Ӿhb1q{?3x Dq  `!&  `=zykFa2 |M jF PXE!@]ߠڣk7O: `|9ހ9" 09:knVh%1?zFwMd;2oyJ A`23㇃c.ɂА*oU4<)e2@"I $Z /#N0tqp  D@ F]婁ʺ%4iF u1ᇫML6/-` Fc'2= (;:Z 'RƐ4q0` 6(, E FsO$IR{w`:AD8y}B]h=9ш?hsyoXF@b #f4Z@ pǘq?KX8!RRckń%fw_.8g%09ahORMSIC$X$#kFs!(( ު0QZeChA Q8o4QeӠ󰄍&aTgY;ZGhth4oǣ4lTq/X.܌1ŘΖX³4}!IRIENDB`Docs/Chm/screenshots/windows_vista/comboboxform.png0000664000000000000000000001500613225117272021623 0ustar rootrootPNG  IHDRgp pHYs.#.#x?vIDATxy\G'FnCFxJ-J+bjZEW[Y UQYEPīX\Fp\@L H}iii?ac-[b$I||}JRZT*DD( +Y,VaaR 555,K.766r~ $J=zm¤)I&ΕH$'NN@Kcaad2|PXUVa0׼PXc KKKؐ/DZ (, ‚@aAƭlvzzzzzzooBp+?eooZ G&]t׾~snT?^,gffLtgϞ CaaaYYٯz!yyy/_VTSN!eh"璒K.>>zʕ+S ?nii9p'|`0fϞ]__w-\L&l޼̙3&L`0W^ݹs3R𰵵ŋݯ_*h4T*TUUIҁ'~w*޽{z^P<|h4>yfO6 paDrY,Vxx7jkkO>00py\N>N8100pLriӦUUU|`0|>r'O^jլYzzz&MVݻW]]]__fM*PPBwwwc__ߎ;vޭhx<`ؼysGGU*UOOJJJbXBvڥjSSSҚ-,,ݛi4ѣGE"QjjH$;88 x䶶dw޶6999vvv}NJJYYY999yyy d2Yќ={V*&&&ٳGTn޼`0x<{{{ wر'OXs֚ LII-ONNMOOj8n޽===<׮]w={p۷oܹf}EEErl6XT333S%%\.pCCCrƍw9sLUU񖐐 8RLMMmhh8tPKK˅ r9BzQNNNJJ{^@uulիWsrrbmmmmll͛"PT*|y}||v^__pM}ǣ蘒7nd29Neeegg'H$nݺ@"‚q8ܞ={ EEEEii\.gX~2_zB=Nꊊe2%Hnnn111t:BDGG~(sپ})㹸|'}cbbߏjjjPaH$;LRYYo>"^˖-[ ZT```cccMMMHHHEEΝ;-ZT]]=-ZfJ  FRHҏ?8((NT;;;<_'Ylllk\\Vg2]]]~{K,2e(ĔHD)V"+-ZdggG&XL&C[իW߽{ִD"XBFEEaX0cƌӧO'%%ݿn c JKKAzWXXwffooٳgF//˗/&M{IҰ0ggg@@xh{mܹI"M'Zr7M)3g4:Mqpp@`X:Y k׮577rʳ+ Zjwmiihnn>,YdʕΜR)\D"h4 șLHH3;vK,qppruu]|yII ZӧI$Ҩ5FGd``J ֦RACCZFTR4%Hd2`@`*R @NЀ @= FGG)ɔh=i4GDxׯoڴ`0X,PX[[ JEdʡ!񺺺t:]SSSkkh4#kkkk Ng2֭;s Dj555 EuuX,FTTh4tNhO_SSZ1JUUUe4ѣ>GWd2{{{Qt:I$- F/ ud0ɥhTjgghP(RT!bd2Fr]]]\.T+Z^hz=az^(t&Gz3hhhx< }v kfdd±Afz7H$rj8qbbb" @ PX(, 3|KJJ˔`"""nƘ򆆆|H$rww'ӦM9"Hh4ԩSB LRaҥRu!fzH*8nTX,vppc>yd@@@ضmѣGlbaa[oKFc]]]GGŋO<) 4ʪ~ٲeǏ/**JIIYxS899ROP(H$̙3GWVVEa"EEE_e2YX,qܤ$@YYّ#Gu'???44ŋsss̙zԼL}F#Ǜ`O0ɓT*㑑h>?r90ѣ;vR/^jqx!D"HQkT*W_}innlu߿ɔooݺGpl6`̘1ㅛ+\~Ç={vҥP.cRX!##FDDX[[߼yS/ 5y̛7̙3a``H$)S:th޼y|󍋋˴X "66Vպϟ?,{o~~~y4P S!,;+ ɲ Kgg%KuŁ7)֋߾b5oSa=讀t:\sj4@ HF"8ʕ+G:@VVVh- ֿԀ6 ‚@ u]`0gCƀZ[[bw^^DM$Q((SX,.++{wFmM(˗,YlQϢT*ܹc bf K&%'' lٲ?Æ zヒzoz2, 333O<988H$_|Eaa#GFmicccgg<-ӌ3P(x(Ɯӧt:tu-++H$|>t_PP޽{z,t_14R׋ t{Cꜜyo޼qƸ.4L^f֭[M/\pdܹs^҃`0BX履~:mڴɓ'[XX^vlׯu։'L)uuuϟ7xxx׿L)ŋGEE544<5u ===ϟhlllrrrz3|||CBBl/^42; ߟH$~׳fͺp*h^gΜT*\[!0`F~>}noo?gY^&GhaDb]Bnq /zN,,,Z jQi&ooo3*P(,.. kmmE7AD%%%k׮ 'OyFYfiP(o~vKOJJ rʭ[8pbxxXTnڴ ݨh}ZWW<cUX&M^t%@gbÆ t +c4bcc7nM?ԩS:77`0,_MәbnO>ƍFQTΞ=%888 'HuֳPVGDDp8h ZeZw`Fjwrrrww郃|󍭭?%L~ơol ŰB#uB̞]BƗkkkV;00sj^H4 bhbbb`ڵPPX =‚@aA  L&e6go/HX]]] ,9[ZZG9`0\]]Y?77߾9r>|Xp |PPꂡYڵk׮]ܼuxxա9]v OB=_~=ÿ3>ez T*,'Nv^`B133ɓCBBΝ;gmmhBCCjf߿ˋL&iکS߿?888$$$33S&΢mZǏ***WWh4u:Hm۶M"ܽ{S `N7o<L _1ΝKRАH$"#2>ǝF1?|rшez>666;;[ج[իzTZUUUzzeiiibb"H}KmooH$v-D Vh4999۶mI*I ǎG-t&L7JgggcccDDO T`z8tGL&sppaccpB)ˣV_2<kի7NBC PXq9Lwj!ᖖ?UIENDB`Docs/Chm/screenshots/windows_vista/pickchars.png0000664000000000000000000002757413225117272021113 0ustar rootrootPNG  IHDRlj1 pHYs.#.#x?v IDATx}itu2+A @ 7-R-ˋ,ljЎ$~qwcGV'ϱ(q'Z-DVH;$H Aľ,]uߏ -e.qFϝ_ݭnU+#P ¼ZZ#u3;1D_g@qCpB H!"#G\P C DD` @sN9R)\'ЪhcB(sq]tAB݉ :(PP `Pk W01UWG" μXmtp(gqi @@GR̉1.Krl:jlW*'q[q0;bp1ƸSz's C ? u9 ņ7M * a+\u [Iop=MBu<@ i͇۳%M"А]HfEV:$ǀ)1 sU][daÑU14xnG y%״W1c(@FS9 8 UE eD1J[]ypCߦe'رc'*++[^8o>wիk)E(Ey>ﵗ_?8;'w'z&菿sÜ/~~g ].׫/:''RѪꚖkWeJMm6{,"P> NQZU4ӈ8's 5鮡!pD9QGDP69{:RHz yl5,4nH Yb!Hd2dmy+ntTP q"#A.@N0cq><:]3셥Kw?Ǖ+W6_||Ѣ?w[}_2(Ji||<4!1qO}w g$WꕦG?؊UCC=]]Yٿ~=33s;{joplqInG@JLc$tNƂH8&)/S[ Pt(~f.n4.wdQ$HPN@ A@g'A6ń,R$R율2q G4_NL] %HTRZ^@b+Mť׮[bciYyxGNn;{r&%gdPI'$$,XX9~}׏ |p3o;YT\RhQlloRJWt&|0CaD1N E$Wr1r w9GJ ;G 0Y$3)fѤHHR3^1)5t]k6&J)(BsA92DYWGڞmk<= %o@W"PBdYze&< Cxs™h}""纳Leq#DsFRXh$vMeRkwBDM4Mc!B 1RV9 f1?$ Y.4-@ ezW4 ‹Dl|{AiEeEw9Bp:0itbwiPP k6t9`HӚ1)iZ&Ayb sDY>^B9gHtpZ\W,Y ƘhaK%KT738"?"M$ULQf#92ӈ`!ˆgT5X ` $ 2RJn_saFQ;m@ Eš0NJv*IS 0f`PJRp2xI0D T @ qM) y"\Sl',Lj{X5 ˜qDL@P*IR0 wc\4Ê-'5@ "8,K*\p[ݱ1ȘiY7nMJVVZZjʈ{g ?{`p#6~Oq si B$JL%J)Psı@0Q*ť pr>ȌB4FQ!U&z <)DUUG > Il9a}Tط/fUUnY{,ˌi^pAnPpagv]uMı5cR*˲i$m$I$l84 9jj4I)D)QGp$> T1D7H <90 Td#!0H`zc*i,6U*$2zi\swt?~q866xmvy#C#˗WƋW1Օ~}{o?߼eWyT__}ܬߙ: KHsΑi @f#(ENT0lB84 s)g r("C * I` N1 ;G{>kc[rZ3q!R0+(c\IɕҳgW%?[^7>>]~ ~+3{_ׯ;)' #$m2d&DzzĄg떵|_>wr^__y٫Wo<@={gs $r~4Me!MP![LPT*H9 F1$YgiPIBU%H(!0BQdXPBpT@h\(]|RW~R#SU4{a8qtcLcLJFcάY Sx;/7킂*\L!eyyهMSQUuԪxYcLUUHR]I^DPUUXGG7|q8O&җxHȹasQA9C$—)Ø25ƑQsA`q #6%$DP5А! h,bmno<1Tþ\Q}#6ee>tS!!;[?N ~ƍk_m@طP_'֯^b3 dddf>|5>7 ݺQR` τ'--eHU7nTXblt~ Smݺ~ť~Ʊ7BAK$4"rJA@UU^4I]qι(!\䀪@M`L,]8A*@)'D9 r S"j3Fxdž[%_ IIloRnu:cbb8#G.hu%__:86%WWF4ipFPPICS Ss4LK*p*Ȅ{DBCrD",Nr}PXrfJJM˿k#Ͼ,1-0hpM,%0%iZw7 N-Z"==3&k$v{^W_U٦75Ea1_آzB)\o$e؈i `E"H8yʘy"K4MU”(i䤼B#@MKK$h@7חgeeTWWM3KV   AS$Rvv&#b{{"Ĵ2Zw%xaZN}OJ J*qΌ 1Ƹn{ ť{Np (q߯GGGzzGGsT%Ngw@CC=ݽ>`ŝ]e%## wGccc6lONvnP/|QUQ ݽkss::8gkVUfwuծ[u 7))UZQS yx[e\}kkkj99_b׿~ D-]488e󆱱1]޸amrMtuv_̑?88nE)֮LIv.[xC߿.-5TWz{z< c1 D8g@.9" n?1ƹ&` gLQbs˖g/z$W7D$ 튢vDHMM]rLEEqrrK/FQfO^߼yhAVvl{2g79魨(q$8~ތ4Wj7Zۮ߸r%Ŧ$Z6::~EQʊwSJs nege666^z/-+ CC#/ݿ`}}mwOς7mvy::1IIIb[wĄѷuqW,XwTUMHt捽RR=ə7#Uee%GD4[6oPU///'>.nsΙdgeѵc[LcׯLIIKNI$[;;ou#.6 ?ˌiUU+(-,,aJHvi4 D$b^~0Yԗ4@`A,Vvuڜ3Bֶm(q˿/lٲx)BTU`~{챂)ېlYYY>mEEy/_^WW7f>gĀ3gxᇍQ&/_>xY&b# FxtԩK.}+_1>XAJ}\+ߟsgy&>>~dd$&&F3!!aΝ---K.|=ŋ T,KO;??~ b|>|k_SUuťF"GQGoַ @ `A;u"IDATqN>t:?Mi /ᗿ!~ڵ֭[O?1vsn]rp&Pbf;t~LJSd(ʢElXvFGGoիf"ʤ!115 };iooh֭5c_YPb`oGAT/fٳGQIY~e˖.]z BȦMv]^^9kժU===F䒒(N3;;{,36mpp4M'/^a [Rt:4M{'B'SRRvO<ci\IyNN?g;g&&&/lʲ<>>(8'>%Kl^tv\^w%%%[D8Emܸѐ !(A%IuuuF)erl6Y&$y%%%?#6,\3Z:R34o5_yk[mڪ>}S;׮]#X̅Ke ;1s-D,++xIJKK-z{{ӷ)uuuXVxh2lÓ^n}6"[$EҤBB&W69ptEW^{SݤcȲ("IR 0L9@ (EkMl6il$~BH p\3]WeK) #|ؙBzJ(EQDv" m6Pλ,؄L"Xuoܸa V 9< .^h75III .β#MYYnkkZeYv:N݂m24n߼y"[pabbLTU@Ė L"@孪[mh ߁5\(Y^SތNBGi>ɰ|l/<6j~z׮]挎]vwvqUUfesݻv52xO<9k>ҥ7~k.kw {:gϞUVΝ{饗lE&W^4瞻rE {p1}>ٳg9oC樸%fY&455ڵ_vZGG/<44⋇~7N<9Gꫳ ܹ7ߜU6l b_՜7oޜiܷ@ P\\kW_}uVݻ˻wޱcDZc3.lllܿ?W^iooԩS]r[f_AC2&''wqĉ;wٳG---˖-kii}vEEž}/]4%>-ZlVG]֚---mddH[]8wYVu{ǎ#smkk+..e#l6mڵkaD;vmfffRJz! 68΄r,B0~&5kfffڵttcɓyyycD:rH\\\II5[llE-httiZ*##"+V7n(߿m۶}B6l35'mYzccc<.6^v޿կGyD|0~<Znݬ<ͪYƂ-33s߾}UsCC%(!Lt{@JsLf@gg3+tE 3331!.}fmlu:cC#*4Ga566l9zMc(E_& n-I\4i|ʏ!2̴" !c#j8p5EQo߾}={̥ɠǏwwwQy qpswqTӧw~ӧN{'Zc{G %[8Wqqq \7,((ؽ{>t:уn۶-[jjj~n޼gy+++"JR8xW~y4 vGgHZ3,Pl*ַTTT竪X|fZ Xw&}V Lew2Fe)/Gyגvh`hm[Xՙ[7o ZoQtg9ذaCX z 38w_@3C ` ]v}MD^Xq> .9sfƍGrVFTG֙3g.\e˖ X4xJ Q`}\l6ᩧzgeYnoo_j\tGsֹszׯ,cnݺ|ӧO N0Jsxfn9x<@ yP]L8wE܉T4s{fffqv{QQ޽{yEQV\9EI=zV-͛ٳyf?sn<|?|!MJKK?^SSt:ggX"1f]hYSSwuy^˵l2mf훊ΈZj޽{׮][]]Դuք;<ǏOHHəQ`s$fdVi… .4\To&UR\\,w\EEE`ǎ1%.`ֽEeYo~U ,<{Yo"@).`lݣ\aRXQ+JQ 9Cc ?.ZFK?\\oQXJ#D9ҪJeJ܈oECwȦ),˲,YK<8i3L0ҨJ"3ѿ1 y,a@t# Ϭe<68|T9"J2nSBYGa,U4f)5M>f2̧ѻ@4h0fz`SP"^!d`ڰ61"?]t?oK̙,:wENyGoۼUjb5o"Vߑèv9h񂱮?{q2ƁaIENDB`Docs/Chm/screenshots/keepass_2x/0000775000000000000000000000000013225117272015563 5ustar rootrootDocs/Chm/screenshots/keepass_2x/gencsvimp.png0000664000000000000000000004577713225117272020310 0ustar rootrootPNG  IHDR,f] pHYs B(x IDATxwxǕ{'c" g`bDɔlYE ږ~~{~7\uXQ$Q(Z(&1  Hȉ3`rz`"QIfz:TWsS&F   ӀyQw&xB"B%~ߛA"JD¥% zC g!!=޹JX1^u3sZߠ^1|X'ߊ-?@ 9ۘnznB[src@9+"7772}?~_?gHD* !}E2$ @`G y$a &` ! B07A/K%z <$JƒDC#eDT.B8y8oF&EQ8X!R42 w 0dpC6/(Klz!@<UB݋n师6 hqBtX.?P<8`޴*HvD]%\`D @$am8w (0DLO(")U*yN98q^4XAҊ /tL.IX"`LPTe/,t!-Z`(?D@EBO`+>#0G8 @L:p8BdG-!0ÀA#LT"4ҺC4FE#<A Q%!AC( BqA!8R]TiJC`o X;a @`v 9t>&0B"  @@"pDQN Q0 vW2Y:ҲrLe qBdp  kҐLa(1ƘH_~#2-BZRx}xyχlW2 "lf>0BFA>n!  BV4 xG)#0iOmMLUƀPR# B ?S *BB T *|pB B8\PJ9MG5jF,h`)؊R uInrQ!hcYKn{j  x> I &E3m}s -\T޴Y2Ap4]jcBMK !@ D B8D880Pm Pxr# nAY_mkR"@X@]ʲ+ހ3#'ȋ9? Z.@ ո|ņ~aެե˱zV$ҋիV뢸C6x\+G^<|4:>%kZ %)ŋKm/uYr:ktI(QH֞8W鐺Sɭu'Μ"X{ͅ}Nfg_9s*omCÓgC#.`;pK'X<OjcRgS݅C=N%*mj3\*oę Ƣ% KHc[T\fX:7. ٍ%J.8pq@]3zğ8[oX'O{'N|g>kkVuҹ6'5[ m׊\pE η9fDl;^ 64P{ĜUj5c^ FyX&#CQ{L0GAw( ^:B! sݩw  rop~%8h6 @9@8LH0tIxdHphx0՟ :4nDLX!, a m;Ie>>%$'0U'z _jo8QSaB0+5ק4D^#Wx>'3ź"ztg>:o{dܙY3N0+'|MC|}LLu% 75v<ƔD1"9|oiqj{w4 z@JLO"皢3en Q$9Kb %H(pHi)-}!٨Q\6+{8l=F7YZrҩU"XxTA4&u(:dEpȤLXߐBFF81G(*T`:FDA !!!@ v!B#if@ r$Luj.)#D@#8^&Nx3fQu VomW.fd FL2^idTs9U\@ySkT<8v 9E10&HzɠFdSE>t50`?]0Cq4|;dT+g4J1"CЌ&0஺Io7 ~@Mx4xn`Y8ʥC.qGƄ(8 x !qna_=6dE2dC )bOꮕF?HpLkI LϑtȽrZ1\:suxKxZ^ֲ`}>?y.lq0^qbȅ( Cy,`0@;zkjr61ƘX1$c4b6^LL 9,;zTOo8UiiɬS[f@FeO2n }voݺuŊfjvJ2'd<ϗW\e͘B F Q$ ?l6o޼YR{YhQRRRFz8e/bWWןBZ\.h4gϞ]x/~^{-66yߏ>}:=Yo O>\v`ps2& Ɯko2N)Hȝ,=FR]]+Ht̙Bcǎ?]vTF') QMFܶm 3g=ztɒ%njllLNNկ~o>}zƍ m0芋7o\\\եvv9۵kWRRROOOcccggg|||͚1hhj2 !\.())IOO/((8sdxO8_~g{yǏ= /~ٳ *sVVVx{T͆1@+W>rY,>`֬Yeee7o?Fi4#GŽ;*Jat#1UQ;I7f9==jFGGo߾=!!cl6oEQLIIO?t޼y^Wg˻tWUVg4 !񕕕fyp^:11QT"xx<ZW.\HOOLNN2,55/YҥK+VS?鳴*^' [z.JT 8)@ @Q%$IX,?`鍓=u91VEz!( }LR<`0wtOaMΘR|~򜇨{ޮ+utu[zzz]Ng6=@ἅ tvYuzg9d-NhjneθedsqpK#+N*r'Q([ڒqrMBv"^eFFM{@M0cE&;/d6^X2 d0& !^e0x-ʤApѣ6U"1yXرcGjj͛714-uVPØ0q'D QBn/XR̞=ѣ+Vx322>\PP`2.\0swyg֬Yf>FQXE3NSSVqHbN((^Z8h˖-)))ׯ_7 wlRPPPRRO_~j%k !1D(B-FC1@زeƍ;;;e2Y||<,Y4͑#G 6oZ0kBB= %O4p;!ˋΝK?111%; MC҄cXbGcB!:fBdN-n FV]DEygCTʇ$ĈЄA'FSK .\~]8]^BO'kwzO1-٩T*h[FUj2*J5j߁6CJ~5lҚ8B&f+Jۭj(D^=Yk¶ٝCA Bcݾ}{{{f chnn...} >wֶw޾8JwGks ?aoog}vzh4_d`ǏFQչn߳gN+++S(uuuׯ_߸q3B\re޽q‰7y~޼y W\yrֶ233/]TPPP\\sϽeΜ9ǎCꪪ*\nXV^|V4tD:Qe˖njժo|L\YYaJxFHl9$zf6ј-T8DE%$$tttx^"pq\zz`hmm%UWW_~bBM&Ӎ7MVWWWTTTQQ3E$fΜY__ƍYfMTEEENS744\u:]ssdHNNNHH>}]vL&;u/^[VV<8{lBHttP Iҗ@]]]ZZZ>tPggg8ò|8z*%x5k֎;-[lq =)6Y'ȼ[9~*Ep= ϗJ+]ǧǏϛ7/&&멩AV[֊'|RE?ٳgWVVFGGO>}Μ9;w|駵Zb _mދ/fdd|56lSO) Jx3>/%%%{؅ ڵkŵ VzM&ӌ3Vn_jUEEܹswڵpӧWUUT*պyfԔl՛\.|===iii .T*}}}6m!//oƌjdeet_zuܹ6m"OÜ_|vqCttt ML6=}'̶vfÂsCv˨ǥzڴi:=S1ת iii_"ryՌyOv ߾;3@)̹i4q% O))҂SE Ŏ7[PʝT(I}R)e˖]vj:::Zٳj/^>KKK+//'FJș/ڊ 1cFRkƽG.}gSK7Jt…Ҍ(/Ξ=/&&h4+ڜĢgϮ_.J%$$466fgg_t`0-YLVoڴ>9sfEE{n۶ms9y͛8dɒbZ =z?! 9HAi`0HǏs=nʢtt:N!]_$/x㍉˿7҂Ӏ4h'#=|0444 ŋ8q"665.....NRvJxA`0_QQѶm._L#W>O>=#####:tH_t[reFFƩSu^xH5! <oؘy [|FҒp8Sջw13f4Z6::z̙jchDQ]GWj 3 c(w [Zau8ܚӧOO0~uLHNy6rs IDAT k cZJZD_Ė&3i ɔB`%={_oSB$8n*B ~Ÿ;!Cxanj a%f< B}q,2bQh'=Z!vc"#1& CǡG̸\.ɀWDtcFycǎE}tuu`<("EI+ N(:sxuعs]mۚ>c?YEػw/{=v֭[ !{۵kWkkkoo͛7]ƚ%1!D:x1ިΌPVGJs۷oOo˿~{eFcǎ^z)''$UVVl6qJJ Ƹ֭[>o1o޼@  Xk1HNԴuaSnG0j!T)e}\.?uB (JyW.ե b4Kxٳg!߰v#HBhh(I{}CJ+]]]}Yff /P( Irywwwbb"ݓP(rss y^B+Wd26-AYz&##'?IF-I1=i|&uIal,kB qO!|0P ׬ ǎi9Lvөj]뎸\.: n;¸0,(JDs|Ѝ !$vod2*1~_dAR̘5N =}exŋ}ޣKJJ}_۶m|ur(7oެ C9rȍ7Μ93C 4׮]xbݻNgGGǡC'vuu8pH8vMJU^gVW~yf +vqkk~h2B555ttΜ9s۶m-[dff^rc\QQ/*?//O?޴i?{j\QUUr/x<}}}ovffd:w k׮t8 ---ZV(œ9s\z3fTUU .vZvv'|'^uܹs7nXnݬY.\1M>.)) cVʲJoBf?NۺukWWVx<׮]۰a_q\WWڵk].WCCfqHJ>yZ~vq/7"Zm߽wvia^^/**R.<" nw__ߞ={A(**1cFiiL&|J2666&&fɒ% :u`0:t(99+_ʅ  n/_yN(--miiycbbf̘QVVFB@l̘1C^vvڴi<χsϘ1㩧 /^ _tѢE999ʕ+VZ.**:qc=Җ-[gϞ^z`0lݺ_KJb׿iۿ@__]ۈ昡W訩jgg端…gܗr^~.٩/ܹsxt{||+e˖+V$&&LO>&2;wnnnK'̌z;:: !(B>aÆiӦ;vlٲen̙3<ɓ'i={rx@rrrttd^p;wvv>d2-[,_b_ryyyRRBhɒ%ΝX,|\:G,Yxq|||8١dz嗷ocTN#G{9r9|G LR]p---v;|0-=m]]ŋm6[yy|v/\pС/z<ݻwnCg/?RVVv>f޽n=z}faȑ#'N8{lyyy__ݻifꢢ"FԴfo߾tػwJϦZ- F1{Gi˜s ł }ٲW_}СCPTTd0 裏N8j333TWWWTT3Ϝ9WOCѥc(fy׮]-^O?]lى'bbb]VPPаw}k߼^o8l>x`llC0uuu/۷oڵ /\pwEd4N9s EBBBVVuuutD7n Jzfsnn\.Z8:I/vww$$$m0ǎSTNSTrViBhѢEv=::{< III.x{{{AEiȎfJt޺u+))yKN~Ǜ7oV(uuu$FX, BEZ@tuu ҋǷtLQ*T;'zj76ac2F- crpcSg.,>b4r2w[,㸄x-<1@V/*`qDQZ}#8ol2'Ƈ[,|>_SsKfzkQ=TwyrL&`rU8 !!8N^)O~uSI{cǎ777+YM9J0!cC7 Ѭ_`l~wʝ 44Q(:==G9vXzzzSShyƍO^re]]u: !c OK˸|`ԼYc#!?r8Fçd2uuuuvv%}JKK C{{;Ih)1&d IPpʕ̝m>y/w^3Lq2gsscVX2 yyyiZZ[1DU&V*t̬榜?m^h΃!mqy^̙*uL16Fcvݺ_/Ǹ `B𠶈LOX1: b&c" }bp⑑jp鴔dc3Ga,cB*h]s6d_ E9UԔ1-*吤{SOa!3'O|Y=ާ|nĎDZQ a mmme͚5555I0Ƣ(:Ṉ76&=vbGǡ $O?4%%/ܹsU*UwwFO?4)\.dirKwDVq0j!"DQjiiIMMl֭$BѬ[U!ʕ+gΜ|#1yB1&LNNt ,[l͚56m%''+v? _a477dǏgSwڵk#@Sdffű}p555㮮.{MϘ#BN>L\ByG\XL&СCcL?jݷoX (Ϭ ]^YYt:9rvxG?GEEuvv޸q#333--{w(ۿO:#L&SYY3<3(1IOOokkuVSSͥ 1&$??_˵i&UV)))4"!pBTф۶m7y5Z=gΜSN=3.]ZPP1cƟYf卉Oo ͛wQVZE1BEmܸ~9s&@sRhy@QQѠÇnaLYd2ټyڒYT2S@NX:_II K,ӁnJLdRSTN M8vˋ/Oz3[tT(̬29Z]]5k|MǓp8J`HKK;uRTիWnkkc F$5?EEE$כi4cbb0'N?䓢(涵EEEzg0ªP1 i,^o4cbbΝvfϞcǎ%KHe1xL8mNGߟaӦMt#L5-- ^~Ql4` g7({ '~hn۝r1 5ḤԩSgvwN1jZ Pc$読>V XD@(xNa6~֭[}B(,,>}-[N:Ūb477eeeʪ7n\}T1WUyt- }555;w˻rJiiiaa޽{:;;U*Օ+WΝ;W ̘5J[5N7 JkʎXWWwL{ٳgt ٳƍv=66a͚5! X5k7f}6@ j;Z c{zzJJJ8dp͝?sR8NlɃ~z.ZcRׄ?~ݻ-..ϏfqߑtRP[[[OOOzzKJJ{tePss͛j x Vo0ϨJ>fR^^+V|XR5k l61!ߢX~#Gplذ.++f I*`o^b޽{7ngEEE+WX,Yf=z499999ܹs2,**J'O[,I} 6x<sAWWWLv?qoo5k^y啉;f[WVV|?jf{뭷On4/_;cƌ+Vٳ^.sweĒpO54MMMy|ߵZ c=|ND18%%t._|׮]ͫ3mmm7oOJ ۷o7Ϝ9fX6o޼}^xBANlc:yīrIhlldUqoƄp8n޼j\.r:~?111!!MEx~iBFv~WWWLLjMIId>zN$p1B2Fd2YVBi6U*h ¥h IDAT'pReOȈ ..Bh.؊_ܘ\d2Y[[㙨"`2&硕z2&k#3Gw>}eTsbL&W [ LwSS3l}n !ЩB !z-[L4G6p Zn BFuTTT$ɪ^ommm}}}{{{SSƸgOOV3tMV8u _Aj 'à>}:++/!!?lllGEE ׿[>>sηzKӽ c8e ;WÛoBT_ ӦddLTr!ہbŊ{reggĸ8Zm6oNy%&&>=쳳fW,6n'0 :_ք  `͟}͛{zzhQ˗/?vի CWWWSA~ BCw7\t&,v -B/t:]tՀ1ЄᴏkL$0 „qw@y|An@"" Ƙou AB[qP&p[qw5\= {.L{+e<IJ&MdIZFc0N8A&WNl V;%n%..G٘釞ӧOGnb߲Ӂ,]ȑ#III۷o/--]~GMJa<,jpj;6w{|w/rwwG%q2bzn`khhP*wNHH8ydKKȫNLI.ۣ]`'G k"ƃnOOOS.kh&d<,X~'y_h!SĩY66O`0!d0RPexznVQT]p,UB~}MZj2 Qj|6#~Ø eD0SeC0;hJ!&L[2nMIp ,sqW` =FEp b0&cbwV>cƘFx08& =;c|B#fcB&5B(...))aܷx]zL0$Iϓ!yhIPeggiLȤb8 Li !rUӒkW%3iѕdNP*{ $76ZTWW]Mv:욚YϤAFIOF/J1j3:iO~=J OR[9.RF#!d5allfHhC)> --F'OhNk׮lŲ`^^^>gBW^ZYY`6 zB h4*F?ow#ꊋ۸qرcӦMÞcBC ~---7nXv㉋s~Ϟ=<+JP__߰e% {rQRRt::$zR<}VMLLܷoߣ>z읒4Z'hiBVjooGiќo֭[*\zŋ]]])))>mҥN*((p8>r6& ~p ~M698t޼yٳ?Ç8i 4]x;c6O}l6[uu5mʿ2{c5n:1i3tkL43=5e3<lrqFFFx'ϕo4u'*z9P l6ۤ,0t*9L* B;NB>  0Ƅ5&)%%e6mIg=u#f`~^x\XXhZ'}"&&f˄anXYa򮖟㸘hݮ/i = !1-`CˮkhaI(/6BA!z2!U*=im#zMB)$z%_ P9P/ ILIh ׃v[y3ֻpX淞#vS߃*;T<*8@Dpv;rCMk瘣٪Lֳ78RG?x0sJ@ H1F HRI Ty/L̞TeB׬:Zx^b7TUI*"$EVcrnzO_ۗKHlq_K~7zcN4e6/'5-ܘ(fGg,w$&Fof:4)i<#B/"2(1"j!3M|08rM Using Stored Passwords - KeePass
Help

Using Stored Passwords


How to transfer passwords stored in KeePass to other applications.