public override void PopulateEntry(PwEntry pwEntry, PwDatabase pwDatabase, UserPrefs userPrefs, RecordType recordType) { base.PopulateEntry(pwEntry, pwDatabase, userPrefs, recordType); List <SecureContentsSection> sections; if (this.sections != null) { sections = this.sections; } else { sections = this.createSectionsFromPlainFields(recordType); } if (sections != null) { int unnamedSectionNumber = 1; SectionFieldLocator usernameFieldLocator = this.GetUsernameFieldLocator(); SectionFieldLocator passwordFieldLocator = this.GetPasswordFieldLocator(); SectionFieldLocator urlFieldLocator = this.GetURLFieldLocator(); foreach (SecureContentsSection section in sections) { // Linked items are not supported if (section.name.Equals(LINKED_ITEMS_SECTION_NAME)) { continue; } // Section without fields, nothing to import if (section.fields == null) { continue; } string sectionTitle = section.title; // If it's an unnamed user-defined section, set a generic unique name (prevents field name collisions) if (string.IsNullOrEmpty(section.title) && this.IsUserSection(section)) { sectionTitle = string.Format("{0} {1}", Properties.Strings.Section_Title, unnamedSectionNumber++); } foreach (SectionField field in section.fields) { // Special treatment fields if (field.k == SectionFieldType.concealed && OTP_FIELD_NAME.IsMatch(field.n ?? string.Empty)) { // OTP fields must be formatted to comply with one of the OTP plugins this.setOTPField(pwEntry, pwDatabase.MemoryProtection.ProtectPassword, field as GeneralSectionField, userPrefs.OTPFormat); continue; } else if (field.k == SectionFieldType.address && (field as AddressSectionField).v != null) { // Addresses can be imported as a single composite field or splitting each component in a separate field if (userPrefs.AddressFormat == AddressFormat.Compact) { this.setCompactAddressField(pwEntry, sectionTitle, field as AddressSectionField); } else if (userPrefs.AddressFormat == AddressFormat.Multiline) { this.setMultilineAddressField(pwEntry, sectionTitle, field as AddressSectionField); } else { this.setExpandedAddressField(pwEntry, sectionTitle, field as AddressSectionField); } continue; } string fieldLabel = field.t; string fieldValue = null; // If the field is in a named section, prefix its name to avoid collisions if (!string.IsNullOrEmpty(sectionTitle)) { fieldLabel = string.Concat(sectionTitle, " - ", field.t); } // Format the field value according to its type if (field.k == SectionFieldType.date) { DateSectionField dateSectionField = field as DateSectionField; if (!DateTime.MinValue.Equals(dateSectionField.v)) { fieldValue = DateTimeFormatter.FormatDate(dateSectionField.v, userPrefs.DateFormat); } } else if (field.k == SectionFieldType.monthYear) { MonthYearSectionField monthYearSectionField = field as MonthYearSectionField; if (!DateTime.MinValue.Equals(monthYearSectionField.v)) { fieldValue = DateTimeFormatter.FormatMonthYear(monthYearSectionField.v, userPrefs.DateFormat); } } else if (field.k == SectionFieldType.menu || field.k == SectionFieldType.cctype || field.k == SectionFieldType.gender) { GeneralSectionField generalSectionField = field as GeneralSectionField; // Combo-box values can't be empty if (!string.IsNullOrEmpty(generalSectionField.v)) { fieldValue = Properties.Strings.ResourceManager.GetString(string.Join("_", new string[] { "Menu", generalSectionField.n, generalSectionField.v })); } } else { fieldValue = (field as GeneralSectionField).v; } // Use the proper line terminator in multiline values if (field.a != null && field.a.multiline) { fieldValue = StringExt.FixNewLines(fieldValue); } // No point in importing an empty template field. If it's user-defined it might be there for a reason. if (string.IsNullOrEmpty(fieldValue) && !this.IsUserSection(section)) { continue; } bool protect; if (usernameFieldLocator != null && usernameFieldLocator.Equals(section.name, field.n)) { protect = pwDatabase.MemoryProtection.ProtectUserName; pwEntry.Strings.Set(PwDefs.UserNameField, new ProtectedString(protect, fieldValue ?? string.Empty)); fieldValue = "{USERNAME}"; } else if (passwordFieldLocator != null && passwordFieldLocator.Equals(section.name, field.n)) { protect = pwDatabase.MemoryProtection.ProtectPassword; pwEntry.Strings.Set(PwDefs.PasswordField, new ProtectedString(protect, fieldValue ?? string.Empty)); fieldValue = "{PASSWORD}"; } else if (urlFieldLocator != null && urlFieldLocator.Equals(section.name, field.n)) { protect = pwDatabase.MemoryProtection.ProtectUrl; pwEntry.Strings.Set(PwDefs.UrlField, new ProtectedString(protect, fieldValue ?? string.Empty)); fieldValue = "{URL}"; } else { protect = (field.k == SectionFieldType.concealed && pwDatabase.MemoryProtection.ProtectPassword) || (field.k == SectionFieldType.URL && pwDatabase.MemoryProtection.ProtectUrl); } // If it's one of the three special fields (username, password, url) and the 1Password field // has the same name as the KeePass entry field, don't overwrite its value with the placeholder. if (!pwEntry.Strings.Exists(fieldLabel)) { pwEntry.Strings.Set(fieldLabel, new ProtectedString(protect, fieldValue ?? string.Empty)); } } } } if (!string.IsNullOrEmpty(this.notesPlain)) { pwEntry.Strings.Set(PwDefs.NotesField, new ProtectedString(pwDatabase.MemoryProtection.ProtectNotes, StringExt.FixNewLines(this.notesPlain))); } if (this.customIcon != null) { byte[] customIconData = null; try { using (MemoryStream originalIconStream = new MemoryStream(this.customIcon)) using (Bitmap originalIcon = new Bitmap(originalIconStream)) using (MemoryStream convertedIconStream = new MemoryStream()) { originalIcon.Save(convertedIconStream, ImageFormat.Png); customIconData = convertedIconStream.ToArray(); using (MD5 md5 = MD5.Create()) { PwUuid customIconUuid = new PwUuid(md5.ComputeHash(customIconData)); this.PwCustomIcon = new PwCustomIcon(customIconUuid, customIconData); pwEntry.CustomIconUuid = customIconUuid; } } } catch (ArgumentException) { // Image format is not supported or one of its dimensions is bigger than 65,535 } } }
public virtual void PopulateEntry(PwEntry pwEntry, PwDatabase pwDatabase, UserPrefs userPrefs) { if (this.sections != null) { int unnamedSectionNumber = 1; SectionFieldLocator usernameFieldLocator = this.GetUsernameFieldLocator(); SectionFieldLocator passwordFieldLocator = this.GetPasswordFieldLocator(); SectionFieldLocator urlFieldLocator = this.GetURLFieldLocator(); foreach (DetailsSection section in sections) { // Linked items are not supported if (section.name.Equals(LINKED_ITEMS_SECTION_NAME)) { continue; } // Section without fields, nothing to import if (section.fields == null) { continue; } string sectionTitle = section.title; // If it's an unnamed user-defined section, set a generic unique name (prevents field name collisions) if (string.IsNullOrEmpty(section.title) && this.IsUserSection(section)) { sectionTitle = string.Format("{0} {1}", Properties.Strings.Section_Title, unnamedSectionNumber++); } foreach (SectionField field in section.fields) { // Special treatment fields if (field.k == SectionFieldType.concealed && OTP_FIELD_NAME.IsMatch(field.n ?? string.Empty)) { // OTP fields must be formatted to comply with one of the OTP plugins this.setOTPField(pwEntry, pwDatabase.MemoryProtection.ProtectPassword, field as GeneralSectionField, userPrefs.OTPFormat); continue; } else if (field.k == SectionFieldType.address) { if ((field as AddressSectionField).v == null) { // Only import an empty address field if it's user-defined if (this.IsUserSection(section)) { string addressFieldLabel = (field as AddressSectionField).t; // If the field is in a named section, prefix its name to avoid collisions if (!string.IsNullOrEmpty(sectionTitle)) { addressFieldLabel = string.Concat(sectionTitle, " - ", (field as AddressSectionField).t); } pwEntry.Strings.Set(addressFieldLabel, new ProtectedString(false, string.Empty)); } } else { // Addresses can be imported as a single composite field or splitting each component in a separate field if (userPrefs.AddressFormat == AddressFormat.Compact) { this.setCompactAddressField(pwEntry, sectionTitle, field as AddressSectionField); } else if (userPrefs.AddressFormat == AddressFormat.Multiline) { this.setMultilineAddressField(pwEntry, sectionTitle, field as AddressSectionField); } else { this.setExpandedAddressField(pwEntry, sectionTitle, field as AddressSectionField); } } continue; } string fieldLabel = field.t; string fieldValue = null; // If the field is in a named section, prefix its name to avoid collisions if (!string.IsNullOrEmpty(sectionTitle)) { fieldLabel = string.Concat(sectionTitle, " - ", field.t); } // Format the field value according to its type if (field.k == SectionFieldType.date) { DateSectionField dateSectionField = field as DateSectionField; if (!DateTime.MinValue.Equals(dateSectionField.v)) { fieldValue = DateTimeFormatter.FormatDate(dateSectionField.v, userPrefs.DateFormat); } } else if (field.k == SectionFieldType.monthYear) { MonthYearSectionField monthYearSectionField = field as MonthYearSectionField; if (!DateTime.MinValue.Equals(monthYearSectionField.v)) { fieldValue = DateTimeFormatter.FormatMonthYear(monthYearSectionField.v, userPrefs.DateFormat); } } else if (field.k == SectionFieldType.menu || field.k == SectionFieldType.cctype || field.k == SectionFieldType.gender) { GeneralSectionField generalSectionField = field as GeneralSectionField; // Combo-box values can't be empty if (!string.IsNullOrEmpty(generalSectionField.v)) { fieldValue = Properties.Strings.ResourceManager.GetString(string.Join("_", new string[] { "Menu", generalSectionField.n, generalSectionField.v })); } } else { fieldValue = (field as GeneralSectionField).v; } // Use the proper line terminator in multiline values if (field.a != null && field.a.multiline) { fieldValue = StringExt.FixNewLines(fieldValue); } // No point in importing an empty template field. If it's user-defined it might be there for a reason. if (string.IsNullOrEmpty(fieldValue) && !this.IsUserSection(section)) { continue; } bool protect; if (usernameFieldLocator != null && usernameFieldLocator.Equals(section.name, field.n)) { protect = pwDatabase.MemoryProtection.ProtectUserName; pwEntry.Strings.Set(PwDefs.UserNameField, new ProtectedString(protect, fieldValue ?? string.Empty)); fieldValue = "{USERNAME}"; } else if (passwordFieldLocator != null && passwordFieldLocator.Equals(section.name, field.n)) { protect = pwDatabase.MemoryProtection.ProtectPassword; pwEntry.Strings.Set(PwDefs.PasswordField, new ProtectedString(protect, fieldValue ?? string.Empty)); fieldValue = "{PASSWORD}"; } else if (urlFieldLocator != null && urlFieldLocator.Equals(section.name, field.n)) { protect = pwDatabase.MemoryProtection.ProtectUrl; pwEntry.Strings.Set(PwDefs.UrlField, new ProtectedString(protect, fieldValue ?? string.Empty)); fieldValue = "{URL}"; } else { protect = (field.k == SectionFieldType.concealed && pwDatabase.MemoryProtection.ProtectPassword) || (field.k == SectionFieldType.URL && pwDatabase.MemoryProtection.ProtectUrl); } // If it's one of the three special fields (username, password, url) and the 1Password field // has the same name as the KeePass entry field, don't overwrite its value with the placeholder. if (!pwEntry.Strings.Exists(fieldLabel)) { pwEntry.Strings.Set(fieldLabel, new ProtectedString(protect, fieldValue ?? string.Empty)); } } } } if (!string.IsNullOrEmpty(this.notesPlain)) { pwEntry.Strings.Set(PwDefs.NotesField, new ProtectedString(pwDatabase.MemoryProtection.ProtectNotes, StringExt.FixNewLines(this.notesPlain))); } }