| // Copyright 2012 The Chromium Authors |
| // Use of this source code is governed by a BSD-style license that can be |
| // found in the LICENSE file. |
| // |
| // Sync protocol datatype extension for password data. |
| |
| // If you change or add any fields in this file, update proto_visitors.h and |
| // potentially proto_enum_conversions.{h, cc}. |
| |
| syntax = "proto2"; |
| |
| option java_multiple_files = true; |
| option java_package = "org.chromium.components.sync.protocol"; |
| |
| option optimize_for = LITE_RUNTIME; |
| |
| package sync_pb; |
| |
| import "components/sync/protocol/encryption.proto"; |
| |
| // These are the properties that get serialized into the |encrypted| field of |
| // PasswordSpecifics. They correspond to fields in |
| // password_manager::PasswordForm. |
| // |
| // Sync unique tag is calculated as |
| // EscapePath(origin) + "|" + |
| // EscapePath(username_element) + "|" + |
| // EscapePath(username_value) + "|" + |
| // EscapePath(password_element) + "|" + |
| // EscapePath(signon_realm) |
| // where '+' is the string concatenation operation. EscapePath escapes a partial |
| // or complete file/pathname. This includes non-printable, non-7bit, and |
| // (including space) the following characters ' "#%:<>?[\]^`{|}'. The space |
| // character is encoded as '%20'. |
| |
| // A simple example of PasswordSpecificsData, as created by Chrome for a web |
| // form that the user submitted. E.g. federated credentials or credentials for |
| // Android apps may have different fields set. |
| // PasswordSpecificsData { |
| // action: "https://example.com/", |
| // avatar_url: "", |
| // blacklisted: false, |
| // date_created: 13305119271948046, |
| // date_last_used: 13305119270102691, |
| // date_password_modified_windows_epoch_micros: 13305119271949070, |
| // display_name: "", |
| // federation_url: "", |
| // notes: {}, |
| // origin: "https://rsolomakhin.github.io/autofill/", |
| // password_element: "password", |
| // password_issues: {}, |
| // password_value: "pwd", |
| // scheme: 0, |
| // signon_realm: "https://rsolomakhin.github.io/", |
| // times_used: 0, |
| // type: 0, |
| // username_element: "username", |
| // username_value: "Superman" |
| // } |
| |
| // All the strings are encoded with UTF-8. URLs are encoded in Punycode. |
| message PasswordIssues { |
| message PasswordIssue { |
| // Timestamp set by a client detecting the issue for the first time. |
| // Number of microseconds since Windows epoch (1601). |
| // This can be unset even if is_muted is set in a few cases in |
| // storage (for a time mutes were written without setting this |
| // field - fixed starting 2021-11-10). |
| optional uint64 date_first_detection_windows_epoch_micros = 1; |
| |
| // Whether the issue was muted by user. |
| optional bool is_muted = 2; |
| |
| // Whether the backend should notify the user about this issue. |
| // Set to true if the user hasn't already seen a client notification for |
| // this issue (e.g. a leak detection prompt in Chrome). The backend sending |
| // notifications does not reset this field. All other sources can write this |
| // in both `PasswordSpecificsData` and `PasswordSpecificsMetadata` and do |
| // so. |
| optional bool trigger_notification_from_backend_on_detection = 3; |
| } |
| optional PasswordIssue leaked_password_issue = 1; |
| optional PasswordIssue reused_password_issue = 2; |
| optional PasswordIssue weak_password_issue = 3; |
| optional PasswordIssue phished_password_issue = 4; |
| } |
| |
| message PasswordSpecificsData { |
| // The different types of the saved credential. |
| enum Scheme { |
| // SCHEME_HTML, the credential represents either a parsed HTML form, or an |
| // android credential or a password saved through Credential Management API |
| // (https://w3c.github.io/webappsec/specs/credentialmanagement/). |
| SCHEME_HTML = 0; |
| // SCHEME_BASIC, basic access http authentication. |
| SCHEME_BASIC = 1; |
| // SCHEME_DIGEST, digest access authentication. |
| SCHEME_DIGEST = 2; |
| // SCHEME_OTHER, another proxy access authentication. |
| SCHEME_OTHER = 3; |
| // USERNAME_ONLY, partial credentials saved on Android that contain only |
| // username and miss the password. |
| USERNAME_ONLY = 4; |
| } |
| // See the enum above. |
| optional int32 scheme = 1; |
| |
| // Signon realm stores information on where the saved password was stored, and |
| // where it's supposed to be filled again. |
| // |
| // It can take various formats depending on the exact circumstances where it |
| // was recorded. Note that the format is *not* guaranteed to be a valid URL or |
| // URI: |
| // |
| // * For parsed web forms and normal passwords saved through Credential |
| // Manager |
| // API: <http-scheme>://<url-host>[:<url-port>]/ |
| // |
| // where |
| // <http-scheme> is one of "http" or "https" |
| // <url-host> is the host for which the password was stored |
| // <url-port> is the option port on the host |
| // The signon realm is a valid URL in this case with an empty path. |
| // Examples: |
| // http://www.example.com/ |
| // https://127.0.0.1/ |
| // http://www.google.com:8080/ |
| // http://192.168.1.254/ |
| // https://accounts.google.com/ |
| // |
| // * For Android apps saved through Autofill with Google: |
| // android://<hash-of-cert>@<package-name>/ |
| // where |
| // <hash-of-cert> is the base64 encoded SHA512 of the app's public |
| // certificate <package-name> is the app's package name |
| // Examples: |
| // android://kCyQDzpaoAX2gs-1zdGPKNAeICb8LzRFOxa4NCq0jO8c8d_NFS_q-Y35bU3Nq3GmFV2lLurmNvIZa6YPYZwmWg==@com.pinterest/ |
| // android://mNUCvTnoWBkzIhSSkVj-uzAdK42YagmCmyUtPoC6JPmYAN3wKpmTdIRsdJtz6pzNBye8XL7nBbEcx-y9CJeo9A==@com.twitter.android.lite/ |
| // |
| // * For federated credentials: |
| // federation://<origin_host>/<federation_host> |
| // where |
| // <origin_host> is the host for which the login information was stored |
| // <federation_host> is the host of the federation provider that was |
| // used to sign in |
| // Examples: |
| // federation://www.example.com/accounts.google.com |
| // federation://uk.trustpilot.com/www.facebook.com |
| // |
| // * For proxy auth: |
| // <proxy-host>[:<proxy_port>]/<auth-realm> |
| // where |
| // <proxy-host> is the host of the proxy for which the password was |
| // stored |
| // <proxy-port> is the port of the proxy |
| // <auth-realm> is a string provided by the proxy during authentication. |
| // It can contain spaces. |
| // Examples: |
| // proxy2.eq.edu.au:80/MISldap |
| // proxy.det.nsw.edu.au:8080/NSW Department of Education |
| // 10.47.2.250:3128/Squid Proxy Server CPUT |
| // default.go2https.com:443/(******Get password from vpnso.com/account/ |
| // *****) |
| // |
| // * For HTTP basic auth: |
| // <http-scheme>://<url-host>[:<url-port>]/<auth-realm> |
| // where |
| // <http-scheme> is one of "http" or "https" |
| // <url-host> is the host for which the password was stored |
| // <url-port> is the option port on the host |
| // <auth-realm> is a string provided by the host during authentication. |
| // It can contain spaces. |
| // Examples: |
| // http://192.168.1.1/Broadband Router |
| // http://192.168.0.1/TP-LINK Wireless N Router WR841N |
| // http://192.168.1.1/index.htm |
| // https://www.edge.asic.gov.au/ASIC eBusiness |
| optional string signon_realm = 2; |
| |
| // For parsed web forms and Credential Management API: |
| // url-scheme://url-host[:url-port]/path |
| // For Android: "android://<hash of cert>@<package name>/" |
| // For proxy/HTTP auth: url-scheme://url-host[:url-port]/path |
| optional string origin = 3; |
| |
| // Only for web-parsed forms - the action target of the form: |
| // url-scheme://url-host[:url-port]/path |
| optional string action = 4; |
| |
| // Only for web-parsed forms - the name of the element containing username. |
| optional string username_element = 5; |
| |
| // For all: the username. |
| // For blacklisted forms: <empty>. |
| optional string username_value = 6; |
| |
| // Only for web-parsed forms - the name of the element containing password. |
| optional string password_element = 7; |
| |
| // For all: the password. |
| // For federated logins and blacklisted forms: <empty> |
| optional string password_value = 8; |
| |
| // Deprecated: http://crbug.com/413020 |
| // True if the credential was saved for a HTTPS session with a valid SSL cert. |
| // Ignored for Android apps. |
| optional bool ssl_valid = 9 [deprecated = true]; |
| |
| // True for the last credential used for logging in on a given site. |
| // Deprecated in M81. |
| optional bool preferred = 10 [deprecated = true]; |
| |
| // Time when the credential was created. Amount of microseconds since 1601. |
| optional int64 date_created = 11; |
| |
| // True, if user chose permanently not to save the credentials for the form. |
| optional bool blacklisted = 12; |
| |
| // kFormSubmission(0), user manually filled the username and the password |
| // in the form. |
| // kGenerated(1), the credential was auto generated. |
| // kApi(2), the credential was generated from Credential Management API. |
| // kManuallyAdded(3), user manually created the password credential |
| // via Settings. |
| // kImported(4), the credential was imported using the import flow. |
| optional int32 type = 13; |
| |
| // Number of times this login was used for logging in using an HTML form. |
| // Chrome uses this field to distinguish log-in and sign-up forms. |
| optional int32 times_used = 14; |
| |
| // A human readable name of the account holder. Set by CredentialManager API |
| // and Android. |
| optional string display_name = 15; |
| |
| // A URL of the avatar for the credential. Set by CredentialManager API and |
| // Android. |
| optional string avatar_url = 16; |
| |
| // A URL of the IdP used to verify the credential. Set by Credential Manager |
| // API and Android. |
| optional string federation_url = 17; |
| |
| // Time when the credential was last used. This covers *successful* logins to |
| // the website, and explicit updates to the password. It does *not* cover if |
| // the password just gets filled but not actually submitted, or if the login |
| // failed. |
| // Note that password consumers other than Chrome (e.g. Google Play Services) |
| // might not update this at all. |
| // Amount of microseconds since 1601, aka Windows epoch. |
| optional int64 date_last_used = 18; |
| |
| // Set if an issue was detected that puts this password at risk. All the |
| // clients are expected to clear the field when the password value is updated. |
| // 'reused' part can be additionally reset when the analysis on the entire |
| // password store is completed. |
| optional PasswordIssues password_issues = 19; |
| |
| // Time when the |password_value| was last modified. For new credentials it |
| // should be set to |date_created|. For subsequent updates the timestamp is |
| // changed if and only if the new password value was saved. |
| // Number of microseconds since Windows epoch (1601). |
| optional int64 date_password_modified_windows_epoch_micros = 20; |
| |
| message Notes { |
| message Note { |
| // The display name must be unique within the scope of a password. |
| optional string unique_display_name = 1; |
| // The user-defined value of the note. |
| optional string value = 2; |
| // The creation time of the note. Number of microseconds since 1601. |
| optional int64 date_created_windows_epoch_micros = 3; |
| // Whether the value of the note is not displayed in plain text by |
| // default. |
| optional bool hide_by_default = 4; |
| } |
| repeated Note note = 1; |
| } |
| reserved 21; |
| // Set of extra notes that the user attached to the password. The presence of |
| // this field, even with an empty Notes message, becomes the authoritative |
| // value for notes and would disregard whatever `encrypted_notes_backup` |
| // contains. |
| optional Notes notes = 22; |
| } |
| |
| // Contains the password specifics metadata which simplifies its lookup. |
| message PasswordSpecificsMetadata { |
| // The signon realm for the credential. For more details, see the |
| // `signon_realm` field in PasswordSpecificsData. |
| optional string url = 1; |
| |
| // True, if user chose permanently not to save the credentials for the form. |
| // Introduced in M82. Copy from PasswordSpecificsData.blacklisted. |
| optional bool blacklisted = 2; |
| |
| // Copy from PasswordSpecificsData.date_last_used. |
| // Introduced in M112. |
| optional int64 date_last_used_windows_epoch_micros = 3; |
| |
| // Copy from PasswordSpecificsData.password_issues. Introduced in M114. |
| optional PasswordIssues password_issues = 4; |
| } |
| |
| // Properties of password sync objects. |
| message PasswordSpecifics { |
| // The actual password data. Contains an encrypted PasswordSpecificsData |
| // message. |
| optional EncryptedData encrypted = 1; |
| // An unsynced field for use internally on the client. This field should |
| // never be set in any network-based communications because it contains |
| // unencrypted material. |
| optional PasswordSpecificsData client_only_encrypted_data = 2; |
| // Password related metadata, which is sent to the server side. The field |
| // should never be set for full encryption users. If encryption is enabled, |
| // this field must be cleared. |
| optional PasswordSpecificsMetadata unencrypted_metadata = 3; |
| reserved 4; |
| // An encrypted backup of the notes field inside the PasswordSpecificsData. |
| // The Sync server preserves the contents of this field across commits from |
| // legacy clients that don't set this field. It is the responsibility of Sync |
| // clients to populate the contents of PasswordSpecificsData notes fields |
| // using the contents of this field. This should be deprecated together with |
| // the logic for preserving it on the server when clients without support for |
| // the |notes| field are no longer allowed by the server (below support |
| // version horizon). |
| // |
| // Encryption key considerations: |
| // a) For commits, the client must use the same key for both encrypted blobs. |
| // b) For handling getupdates, the two keys may NOT necessarily match the |
| // encryption key used, as in theory the new blob could be "behind" if key |
| // rotation took place. As of today, it is safe to assume that if |
| // |encrypted| is decryptable by a client, then |encrypted_notes_backup| |
| // must be decryptable too (i.e. the Nigori keybag should include older |
| // versions of the key). But not the other way round. |
| // |
| // If both `encrypted_notes_backup` and the `notes` in `encrypted` are |
| // populated, the one in notes is considered the authoritative value. |
| optional EncryptedData encrypted_notes_backup = 5; |
| } |