| // Copyright 2018 The Fuchsia Authors. All rights reserved. |
| // Use of this source code is governed by a BSD-style license that can be |
| // found in the LICENSE file. |
| library fuchsia.identity.internal; |
| |
| using fuchsia.identity.account; |
| using fuchsia.identity.authentication; |
| |
| /// The maximum length of the pre-auth account state, in bytes. |
| const ACCOUNT_PRE_AUTH_STATE_MAX_SIZE uint32 = 10240; |
| |
| /// Data associated with an account that is available prior to authentication, |
| /// such as the account name. |
| /// |
| /// This data is generated and used by an AccountHandler, but is persisted as an |
| /// opaque blob by the AccountManager on behalf of the AccountHandler. This |
| /// partitioning means neither component has access to both the device-encrypted |
| /// disk and the account-encrypted disk. |
| alias AccountPreAuthState = vector<uint8>:ACCOUNT_PRE_AUTH_STATE_MAX_SIZE; |
| |
| |
| /// The control channel for an AccountHandler component. |
| /// |
| /// This interface is intended only for use by the AccountManager component that |
| /// starts instances of AccountHandler. We define which account the handler |
| /// should be handling one time via this channel rather than via startup flags |
| /// to provide additional flexibility given the range of scenarios: |
| /// * The account is completely new |
| /// * The account is being added to the current device for the first time |
| /// * Account information is already present on the local disk and is readable |
| /// * Account information is already present on the local disk but is not yet |
| /// readable because the disk is not yet decrypted. |
| /// |
| /// A given Account Handler progresses through the following state machine: |
| /// ``` |
| /// | |
| /// V |
| /// +---------------+ |
| /// | Uninitialized |------------+ |
| /// +---------------+ | |
| /// | | |
| /// | | Preload |
| /// | V |
| /// | +------------------+ |
| /// | | Locked | |
| /// | +------------------+ |
| /// | ^ |
| /// | | |
| /// | | |
| /// | | LockAccount / |
| /// | CreateAccount | UnlockAccount |
| /// | | |
| /// | | |
| /// | | |
| /// V | |
| /// +---------------+ | |
| /// | Initialized |<-----------+ |
| /// +---------------+ |
| /// | |
| /// | Terminate |
| /// V |
| /// +---------------+ |
| /// | Finished | |
| /// +---------------+ |
| /// ``` |
| /// |
| /// * `Uninitialized` - the handler has just been instantiated and contains no |
| /// account information. |
| /// * `Locked` - the handler has loaded pre-authentication data, which lets it |
| /// unlock the account subsequently. |
| /// * `Initialized` - the handler has loaded account information and is ready |
| /// to serve requests for the `Account` interface. If the account is |
| /// persistent, then it is saved to disk. |
| /// * `Finished` - the handler is in the process of shutting down and will soon |
| /// terminate. |
| @discoverable |
| closed protocol AccountHandlerControl { |
| /// Creates a completely new system account, optionally protecting the |
| /// account with a single enrollment of an authentication mechanism. |
| /// |
| /// `id` [required] AccountId for the new account |
| /// `metadata` [required] Metadata for the new account |
| /// `interaction` An `Interaction` channel enabling the user to select and |
| /// enroll authentication mechanisms for the new account. |
| /// |
| /// Returns an `AccountPreAuthState` that the client should persist for |
| /// use in future operations on the account. |
| /// |
| /// Fails with: |
| /// - `FAILED_PRECONDITION` if the AccountHandler is not in the |
| /// `Uninitialized` state. |
| /// - `INVALID_REQUEST` if policy requires authentication factors for the |
| /// new account but no `interaction` channel was supplied. |
| /// - `ABORTED` if the client closes the `interaction` channel. |
| strict CreateAccount(resource table { |
| 1: id fuchsia.identity.account.AccountId; |
| 2: metadata fuchsia.identity.account.AccountMetadata; |
| 3: interaction server_end:fuchsia.identity.authentication.Interaction; |
| }) -> (struct { |
| pre_auth_state AccountPreAuthState; |
| }) error fuchsia.identity.account.Error; |
| |
| /// Loads the supplied pre-auth data, which allows the account to be |
| /// unlocked later. |
| /// |
| /// This moves the AccountHandler from the `Uninitialized` state to the |
| /// `Locked` state. |
| /// |
| /// Fails with `FAILED_PRECONDITION` if the AccountHandler is not in the |
| /// `Uninitialized` state. |
| strict Preload(struct { |
| pre_auth_state AccountPreAuthState; |
| }) -> () error fuchsia.identity.account.Error; |
| |
| /// Reach the `Initialized` state, attempting authentication and unlocking |
| /// the account where necessary. |
| /// |
| /// `interaction` An `Interaction` channel enabling the user to complete |
| /// authentication challenges if these are necessary. |
| /// |
| /// On success, returns an `AccountPreAuthState` if the stored pre- |
| /// authentication state should be updated as a result of the operation. |
| /// |
| /// Fails with |
| /// - `FAILED_PRECONDITION` if the AccountHandler is not in the `Locked` or |
| /// `Initialized` state. |
| /// - `ABORTED` if the client closes the `interaction` channel. |
| strict UnlockAccount(resource table { |
| 1: interaction server_end:fuchsia.identity.authentication.Interaction; |
| }) -> (struct { |
| pre_auth_state AccountPreAuthState:optional; |
| }) error fuchsia.identity.account.Error; |
| |
| /// Reach the `Locked` state, closing any open `Account` and `Persona` |
| /// channels for the account. |
| /// |
| /// On success, returns an `AccountPreAuthState` if the stored pre- |
| /// authentication state should be updated as a result of the operation. |
| /// |
| /// Fails with `FAILED_PRECONDITION` if the AccountHandler is not in the |
| /// `Initialized` or `Locked` state. |
| strict LockAccount() -> (struct { |
| pre_auth_state AccountPreAuthState:optional; |
| }) error fuchsia.identity.account.Error; |
| |
| /// Deletes all persistent information about the Fuchsia account handled by |
| /// this handler, including all credentials and global identifiers. |
| /// After a successful call to RemoveAccount, all other open interfaces for |
| /// this account handler will be closed and any subsequent calls on the |
| /// current interface will fail. |
| strict RemoveAccount() -> () error fuchsia.identity.account.Error; |
| |
| /// Connects an interface to read properties of and perform operations on |
| /// the account handled by this handler. The AccountHandler must be in the |
| /// `Initialized` state. |
| /// |
| /// `account` The server end of an `Account` channel |
| /// |
| /// Fails with `FAILED_PRECONDITION` if the AccountHandler is not in the |
| /// `Initialized` state. |
| strict GetAccount(resource struct { |
| account server_end:fuchsia.identity.account.Account; |
| }) -> () error fuchsia.identity.account.Error; |
| |
| /// Signals that the AccountHandler should tear itself down. After the |
| /// receiver responds by closing its handle, the caller may terminate the |
| /// component if it hasn't already exited. |
| strict Terminate(); |
| }; |