1 /* 2 KeePass Password Safe - The Open-Source Password Manager 3 Copyright (C) 2003-2021 Dominik Reichl <dominik.reichl@t-online.de> 4 5 This program is free software; you can redistribute it and/or modify 6 it under the terms of the GNU General Public License as published by 7 the Free Software Foundation; either version 2 of the License, or 8 (at your option) any later version. 9 10 This program is distributed in the hope that it will be useful, 11 but WITHOUT ANY WARRANTY; without even the implied warranty of 12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 GNU General Public License for more details. 14 15 You should have received a copy of the GNU General Public License 16 along with this program; if not, write to the Free Software 17 Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA 18 */ 19 20 using System; 21 using System.Collections.Generic; 22 using System.ComponentModel; 23 using System.Diagnostics; 24 using System.Net; 25 using System.Xml.Serialization; 26 27 using KeePassLib.Delegates; 28 using KeePassLib.Interfaces; 29 using KeePassLib.Serialization; 30 31 namespace KeePassLib 32 { 33 /// <summary> 34 /// Contains KeePassLib-global definitions and enums. 35 /// </summary> 36 public static class PwDefs 37 { 38 /// <summary> 39 /// The product name. 40 /// </summary> 41 public static readonly string ProductName = "KeePass Password Safe"; 42 43 /// <summary> 44 /// A short, simple string representing the product name. The string 45 /// should contain no spaces, directory separator characters, etc. 46 /// </summary> 47 public static readonly string ShortProductName = "KeePass"; 48 49 internal const string UnixName = "keepass2"; 50 internal const string ResClass = "KeePass2"; // With initial capital 51 52 /// <summary> 53 /// Version, encoded as 32-bit unsigned integer. 54 /// 2.00 = 0x02000000, 2.01 = 0x02000100, ..., 2.18 = 0x02010800. 55 /// As of 2.19, the version is encoded component-wise per byte, 56 /// e.g. 2.19 = 0x02130000. 57 /// It is highly recommended to use <c>FileVersion64</c> instead. 58 /// </summary> 59 public static readonly uint Version32 = 0x02310000; 60 61 /// <summary> 62 /// Version, encoded as 64-bit unsigned integer 63 /// (component-wise, 16 bits per component). 64 /// </summary> 65 public static readonly ulong FileVersion64 = 0x0002003100000000UL; 66 67 /// <summary> 68 /// Version, encoded as string. 69 /// </summary> 70 public static readonly string VersionString = "2.49"; 71 72 public static readonly string Copyright = @"Copyright © 2003-2021 Dominik Reichl"; 73 74 /// <summary> 75 /// Product website URL. Terminated by a forward slash. 76 /// </summary> 77 public static readonly string HomepageUrl = "https://keepass.info/"; 78 79 /// <summary> 80 /// URL to the online translations page. 81 /// </summary> 82 public static readonly string TranslationsUrl = "https://keepass.info/translations.html"; 83 84 /// <summary> 85 /// URL to the online plugins page. 86 /// </summary> 87 public static readonly string PluginsUrl = "https://keepass.info/plugins.html"; 88 89 /// <summary> 90 /// Product donations URL. 91 /// </summary> 92 public static readonly string DonationsUrl = "https://keepass.info/donate.html"; 93 94 /// <summary> 95 /// URL to the root path of the online KeePass help. Terminated by 96 /// a forward slash. 97 /// </summary> 98 public static readonly string HelpUrl = "https://keepass.info/help/"; 99 100 /// <summary> 101 /// URL to a TXT file (eventually compressed) that contains information 102 /// about the latest KeePass version available on the website. 103 /// </summary> 104 public static readonly string VersionUrl = "https://www.dominik-reichl.de/update/version2x.txt.gz"; 105 106 /// <summary> 107 /// A <c>DateTime</c> object that represents the time when the assembly 108 /// was loaded. 109 /// </summary> 110 public static readonly DateTime DtDefaultNow = DateTime.UtcNow; 111 112 /// <summary> 113 /// Default number of master key encryption/transformation rounds 114 /// (making dictionary attacks harder). 115 /// </summary> 116 public static readonly ulong DefaultKeyEncryptionRounds = 60000; 117 118 /// <summary> 119 /// Default identifier string for the title field. 120 /// Should not contain spaces, tabs or other whitespace. 121 /// </summary> 122 public const string TitleField = "Title"; 123 // Const instead of static readonly for backward compatibility with plugins 124 125 /// <summary> 126 /// Default identifier string for the user name field. 127 /// Should not contain spaces, tabs or other whitespace. 128 /// </summary> 129 public const string UserNameField = "UserName"; 130 // Const instead of static readonly for backward compatibility with plugins 131 132 /// <summary> 133 /// Default identifier string for the password field. 134 /// Should not contain spaces, tabs or other whitespace. 135 /// </summary> 136 public const string PasswordField = "Password"; 137 // Const instead of static readonly for backward compatibility with plugins 138 139 /// <summary> 140 /// Default identifier string for the URL field. 141 /// Should not contain spaces, tabs or other whitespace. 142 /// </summary> 143 public const string UrlField = "URL"; 144 // Const instead of static readonly for backward compatibility with plugins 145 146 /// <summary> 147 /// Default identifier string for the notes field. 148 /// Should not contain spaces, tabs or other whitespace. 149 /// </summary> 150 public const string NotesField = "Notes"; 151 // Const instead of static readonly for backward compatibility with plugins 152 153 /// <summary> 154 /// Default identifier string for the field which will contain TAN indices. 155 /// </summary> 156 public static readonly string TanIndexField = UserNameField; 157 158 /// <summary> 159 /// Default title of an entry that is really a TAN entry. 160 /// </summary> 161 public static readonly string TanTitle = @"<TAN>"; 162 163 /// <summary> 164 /// Prefix of a custom auto-type string field. 165 /// </summary> 166 public static readonly string AutoTypeStringPrefix = "S:"; 167 168 /// <summary> 169 /// Default string representing a hidden password. 170 /// </summary> 171 public static readonly string HiddenPassword = "********"; 172 173 /// <summary> 174 /// Default auto-type keystroke sequence. If no custom sequence is 175 /// specified, this sequence is used. 176 /// </summary> 177 public static readonly string DefaultAutoTypeSequence = @"{USERNAME}{TAB}{PASSWORD}{ENTER}"; 178 179 /// <summary> 180 /// Default auto-type keystroke sequence for TAN entries. If no custom 181 /// sequence is specified, this sequence is used. 182 /// </summary> 183 public static readonly string DefaultAutoTypeSequenceTan = @"{PASSWORD}"; 184 185 /// <summary> 186 /// Maximum time (in milliseconds) after which the user interface 187 /// should be updated. 188 /// </summary> 189 internal const int UIUpdateDelay = 50; 190 191 internal const uint QualityBitsWeak = 79; 192 193 internal const string FavoriteTag = "Favorite"; 194 195 /// <summary> 196 /// Check if a name is a standard field name. 197 /// </summary> 198 /// <param name="strFieldName">Input field name.</param> 199 /// <returns>Returns <c>true</c>, if the field name is a standard 200 /// field name (title, user name, password, ...), otherwise <c>false</c>.</returns> IsStandardField(string strFieldName)201 public static bool IsStandardField(string strFieldName) 202 { 203 Debug.Assert(strFieldName != null); if(strFieldName == null) return false; 204 205 if(strFieldName.Equals(TitleField)) return true; 206 if(strFieldName.Equals(UserNameField)) return true; 207 if(strFieldName.Equals(PasswordField)) return true; 208 if(strFieldName.Equals(UrlField)) return true; 209 if(strFieldName.Equals(NotesField)) return true; 210 211 return false; 212 } 213 GetStandardFields()214 public static List<string> GetStandardFields() 215 { 216 List<string> l = new List<string>(); 217 218 l.Add(TitleField); 219 l.Add(UserNameField); 220 l.Add(PasswordField); 221 l.Add(UrlField); 222 l.Add(NotesField); 223 224 return l; 225 } 226 227 /// <summary> 228 /// Check whether an entry is a TAN entry. 229 /// </summary> IsTanEntry(PwEntry pe)230 public static bool IsTanEntry(PwEntry pe) 231 { 232 if(pe == null) { Debug.Assert(false); return false; } 233 234 return (pe.Strings.ReadSafe(PwDefs.TitleField) == TanTitle); 235 } 236 GetTranslationDisplayVersion(string strFileVersion)237 internal static string GetTranslationDisplayVersion(string strFileVersion) 238 { 239 if(strFileVersion == null) { Debug.Assert(false); return string.Empty; } 240 241 if(strFileVersion == "2.39") return "2.39.1 / 2.39"; 242 if(strFileVersion == "2.42") return "2.42.1 / 2.42"; 243 if(strFileVersion == "2.48") return "2.48.1 / 2.48"; 244 245 return strFileVersion; 246 } 247 GroupIconToEntryIcon(PwIcon i)248 internal static PwIcon GroupIconToEntryIcon(PwIcon i) 249 { 250 PwIcon r = i; // Inherit by default 251 252 switch(i) 253 { 254 case PwIcon.Folder: 255 case PwIcon.FolderOpen: 256 case PwIcon.FolderPackage: 257 Debug.Assert((new PwEntry(false, false)).IconId == PwIcon.Key); 258 r = PwIcon.Key; 259 break; 260 261 case PwIcon.EMailBox: 262 r = PwIcon.EMail; 263 break; 264 265 default: break; 266 } 267 268 return r; 269 } 270 } 271 272 // #pragma warning disable 1591 // Missing XML comments warning 273 /// <summary> 274 /// Search parameters for group and entry searches. 275 /// </summary> 276 public sealed class SearchParameters 277 { 278 private string m_strName = string.Empty; 279 [DefaultValue("")] 280 public string Name 281 { 282 get { return m_strName; } 283 set 284 { 285 if(value == null) throw new ArgumentNullException("value"); 286 m_strName = value; 287 } 288 } 289 290 private string m_strText = string.Empty; 291 [DefaultValue("")] 292 public string SearchString 293 { 294 get { return m_strText; } 295 set 296 { 297 if(value == null) throw new ArgumentNullException("value"); 298 m_strText = value; 299 } 300 } 301 302 private PwSearchMode m_sm = PwSearchMode.Simple; 303 public PwSearchMode SearchMode 304 { 305 get { return m_sm; } 306 set { m_sm = value; } 307 } 308 309 [DefaultValue(false)] 310 [Obsolete] 311 [XmlIgnore] 312 public bool RegularExpression 313 { 314 get { return (m_sm == PwSearchMode.Regular); } 315 set { m_sm = (value ? PwSearchMode.Regular : PwSearchMode.Simple); } 316 } 317 318 private bool m_bSearchInTitles = true; 319 [DefaultValue(true)] 320 public bool SearchInTitles 321 { 322 get { return m_bSearchInTitles; } 323 set { m_bSearchInTitles = value; } 324 } 325 326 private bool m_bSearchInUserNames = true; 327 [DefaultValue(true)] 328 public bool SearchInUserNames 329 { 330 get { return m_bSearchInUserNames; } 331 set { m_bSearchInUserNames = value; } 332 } 333 334 private bool m_bSearchInPasswords = false; 335 [DefaultValue(false)] 336 public bool SearchInPasswords 337 { 338 get { return m_bSearchInPasswords; } 339 set { m_bSearchInPasswords = value; } 340 } 341 342 private bool m_bSearchInUrls = true; 343 [DefaultValue(true)] 344 public bool SearchInUrls 345 { 346 get { return m_bSearchInUrls; } 347 set { m_bSearchInUrls = value; } 348 } 349 350 private bool m_bSearchInNotes = true; 351 [DefaultValue(true)] 352 public bool SearchInNotes 353 { 354 get { return m_bSearchInNotes; } 355 set { m_bSearchInNotes = value; } 356 } 357 358 private bool m_bSearchInOther = true; 359 [DefaultValue(true)] 360 public bool SearchInOther 361 { 362 get { return m_bSearchInOther; } 363 set { m_bSearchInOther = value; } 364 } 365 366 private bool m_bSearchInStringNames = false; 367 [DefaultValue(false)] 368 public bool SearchInStringNames 369 { 370 get { return m_bSearchInStringNames; } 371 set { m_bSearchInStringNames = value; } 372 } 373 374 private bool m_bSearchInTags = true; 375 [DefaultValue(true)] 376 public bool SearchInTags 377 { 378 get { return m_bSearchInTags; } 379 set { m_bSearchInTags = value; } 380 } 381 382 private bool m_bSearchInUuids = false; 383 [DefaultValue(false)] 384 public bool SearchInUuids 385 { 386 get { return m_bSearchInUuids; } 387 set { m_bSearchInUuids = value; } 388 } 389 390 private bool m_bSearchInGroupPaths = false; 391 [DefaultValue(false)] 392 public bool SearchInGroupPaths 393 { 394 get { return m_bSearchInGroupPaths; } 395 set { m_bSearchInGroupPaths = value; } 396 } 397 398 private bool m_bSearchInGroupNames = false; 399 [DefaultValue(false)] 400 public bool SearchInGroupNames 401 { 402 get { return m_bSearchInGroupNames; } 403 set { m_bSearchInGroupNames = value; } 404 } 405 406 private bool m_bSearchInHistory = false; 407 [DefaultValue(false)] 408 public bool SearchInHistory 409 { 410 get { return m_bSearchInHistory; } 411 set { m_bSearchInHistory = value; } 412 } 413 414 #if KeePassUAP 415 private StringComparison m_scType = StringComparison.OrdinalIgnoreCase; 416 #else 417 private StringComparison m_scType = StringComparison.InvariantCultureIgnoreCase; 418 #endif 419 /// <summary> 420 /// String comparison type. Specifies the condition when the specified 421 /// text matches a group/entry string. 422 /// </summary> 423 public StringComparison ComparisonMode 424 { 425 get { return m_scType; } 426 set { m_scType = value; } 427 } 428 429 private bool m_bExcludeExpired = false; 430 [DefaultValue(false)] 431 public bool ExcludeExpired 432 { 433 get { return m_bExcludeExpired; } 434 set { m_bExcludeExpired = value; } 435 } 436 437 private bool m_bRespectEntrySearchingDisabled = true; 438 [DefaultValue(true)] 439 public bool RespectEntrySearchingDisabled 440 { 441 get { return m_bRespectEntrySearchingDisabled; } 442 set { m_bRespectEntrySearchingDisabled = value; } 443 } 444 445 private StrPwEntryDelegate m_fnDataTrf = null; 446 [XmlIgnore] 447 public StrPwEntryDelegate DataTransformationFn 448 { 449 get { return m_fnDataTrf; } 450 set { m_fnDataTrf = value; } 451 } 452 453 private string m_strDataTrf = string.Empty; 454 /// <summary> 455 /// Only for serialization. 456 /// </summary> 457 [DefaultValue("")] 458 public string DataTransformation 459 { 460 get { return m_strDataTrf; } 461 set 462 { 463 if(value == null) throw new ArgumentNullException("value"); 464 m_strDataTrf = value; 465 } 466 } 467 468 [XmlIgnore] 469 public static SearchParameters None 470 { 471 get 472 { 473 SearchParameters sp = new SearchParameters(); 474 475 Debug.Assert(sp.m_strName.Length == 0); 476 Debug.Assert(sp.m_strText.Length == 0); 477 Debug.Assert(sp.m_sm == PwSearchMode.Simple); 478 sp.m_bSearchInTitles = false; 479 sp.m_bSearchInUserNames = false; 480 Debug.Assert(!sp.m_bSearchInPasswords); 481 sp.m_bSearchInUrls = false; 482 sp.m_bSearchInNotes = false; 483 sp.m_bSearchInOther = false; 484 Debug.Assert(!sp.m_bSearchInStringNames); 485 sp.m_bSearchInTags = false; 486 Debug.Assert(!sp.m_bSearchInUuids); 487 Debug.Assert(!sp.m_bSearchInGroupPaths); 488 Debug.Assert(!sp.m_bSearchInGroupNames); 489 Debug.Assert(!sp.m_bSearchInHistory); 490 // Debug.Assert(sp.m_scType == StringComparison.InvariantCultureIgnoreCase); 491 Debug.Assert(!sp.m_bExcludeExpired); 492 Debug.Assert(sp.m_bRespectEntrySearchingDisabled); 493 494 return sp; 495 } 496 } 497 498 /// <summary> 499 /// Construct a new search parameters object. 500 /// </summary> SearchParameters()501 public SearchParameters() 502 { 503 } 504 Clone()505 public SearchParameters Clone() 506 { 507 return (SearchParameters)this.MemberwiseClone(); 508 } 509 } 510 // #pragma warning restore 1591 // Missing XML comments warning 511 512 // #pragma warning disable 1591 // Missing XML comments warning 513 /// <summary> 514 /// Memory protection configuration structure (for default fields). 515 /// </summary> 516 public sealed class MemoryProtectionConfig : IDeepCloneable<MemoryProtectionConfig> 517 { 518 public bool ProtectTitle = false; 519 public bool ProtectUserName = false; 520 public bool ProtectPassword = true; 521 public bool ProtectUrl = false; 522 public bool ProtectNotes = false; 523 524 // public bool AutoEnableVisualHiding = false; 525 CloneDeep()526 public MemoryProtectionConfig CloneDeep() 527 { 528 return (MemoryProtectionConfig)this.MemberwiseClone(); 529 } 530 GetProtection(string strField)531 public bool GetProtection(string strField) 532 { 533 if(strField == PwDefs.TitleField) return this.ProtectTitle; 534 if(strField == PwDefs.UserNameField) return this.ProtectUserName; 535 if(strField == PwDefs.PasswordField) return this.ProtectPassword; 536 if(strField == PwDefs.UrlField) return this.ProtectUrl; 537 if(strField == PwDefs.NotesField) return this.ProtectNotes; 538 539 return false; 540 } 541 } 542 // #pragma warning restore 1591 // Missing XML comments warning 543 544 public sealed class ObjectTouchedEventArgs : EventArgs 545 { 546 private readonly object m_o; 547 public object Object { get { return m_o; } } 548 549 private readonly bool m_bModified; 550 public bool Modified { get { return m_bModified; } } 551 552 private readonly bool m_bParentsTouched; 553 public bool ParentsTouched { get { return m_bParentsTouched; } } 554 ObjectTouchedEventArgs(object o, bool bModified, bool bParentsTouched)555 public ObjectTouchedEventArgs(object o, bool bModified, 556 bool bParentsTouched) 557 { 558 m_o = o; 559 m_bModified = bModified; 560 m_bParentsTouched = bParentsTouched; 561 } 562 } 563 564 public sealed class IOAccessEventArgs : EventArgs 565 { 566 private readonly IOConnectionInfo m_ioc; 567 public IOConnectionInfo IOConnectionInfo { get { return m_ioc; } } 568 569 private readonly IOConnectionInfo m_ioc2; 570 public IOConnectionInfo IOConnectionInfo2 { get { return m_ioc2; } } 571 572 private readonly IOAccessType m_t; 573 public IOAccessType Type { get { return m_t; } } 574 IOAccessEventArgs(IOConnectionInfo ioc, IOConnectionInfo ioc2, IOAccessType t)575 public IOAccessEventArgs(IOConnectionInfo ioc, IOConnectionInfo ioc2, 576 IOAccessType t) 577 { 578 m_ioc = ioc; 579 m_ioc2 = ioc2; 580 m_t = t; 581 } 582 } 583 584 public sealed class IOWebRequestEventArgs : EventArgs 585 { 586 private readonly WebRequest m_wr; 587 public WebRequest Request { get { return m_wr; } } 588 589 private readonly IOConnectionInfo m_ioc; 590 public IOConnectionInfo IOConnectionInfo { get { return m_ioc; } } 591 IOWebRequestEventArgs(WebRequest r, IOConnectionInfo ioc)592 public IOWebRequestEventArgs(WebRequest r, IOConnectionInfo ioc) 593 { 594 m_wr = r; 595 m_ioc = ioc; 596 } 597 } 598 } 599