Use SQLite for persistence and generate Rust protobuf bindings at build time. Add Docker image support for containerized deployment. Co-Authored-By: codex <[email protected]>
368 lines
15 KiB
Protocol Buffer
368 lines
15 KiB
Protocol Buffer
// 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 go_package = "./sync_pb";
|
|
|
|
option java_multiple_files = true;
|
|
option java_package = "org.chromium.components.sync.protocol";
|
|
|
|
option optimize_for = LITE_RUNTIME;
|
|
|
|
package sync_pb;
|
|
|
|
import "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.
|
|
// kReceivedViaSharing(5), the credential has been received via the password
|
|
// sharing feature.
|
|
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;
|
|
|
|
// For credentials that have been shared by another user, this field captures
|
|
// the sender email. It's empty for credentials that weren't received via
|
|
// password sharing feature.
|
|
optional string sender_email = 23;
|
|
|
|
// Similar to `sender_email` but for the sender name.
|
|
optional string sender_name = 24;
|
|
|
|
// The timestamp when the password was received via sharing feature from
|
|
// another user.
|
|
optional int64 date_received_windows_epoch_micros = 25;
|
|
|
|
// Whether the user has been already notified that they received this password
|
|
// from another user via the password sharing feature. This is synced to avoid
|
|
// showing the notification on multiple devices.
|
|
optional bool sharing_notification_displayed = 26;
|
|
|
|
// Similar to `sender_email` but for the url of the sender profile image.
|
|
optional string sender_profile_image_url = 27;
|
|
}
|
|
|
|
// 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;
|
|
|
|
// Copy from PasswordSpecificsData.type. Introduced in M119.
|
|
optional int32 type = 13;
|
|
}
|
|
|
|
// 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;
|
|
}
|