blob: 9efbf66f18435b624d702a9fe62a87cd9d5b86f6 [file] [log] [blame]
// 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.
//! AccountManager manages the overall state of Fuchsia accounts and personae on
//! a Fuchsia device, installation of the AuthProviders that are used to obtain
//! authentication tokens for these accounts, and access to TokenManagers for
//! these accounts.
//!
//! The AccountManager is the most powerful interface in the authentication
//! system and is intended only for use by the most trusted parts of the system.
#![deny(missing_docs)]
mod account_event_emitter;
mod account_handler_connection;
mod account_handler_context;
mod account_manager;
mod account_map;
mod authenticator_connection;
mod fake_account_handler_connection;
pub mod inspect;
mod prototype;
mod stored_account_list;
use crate::account_handler_connection::AccountHandlerConnectionImpl;
use crate::account_manager::AccountManager;
use anyhow::{Context as _, Error};
use fidl_fuchsia_auth::AuthProviderConfig;
use fuchsia_async as fasync;
use fuchsia_component::fuchsia_single_component_package_url;
use fuchsia_component::server::ServiceFs;
use fuchsia_inspect::Inspector;
use futures::prelude::*;
use lazy_static::lazy_static;
use log::{error, info};
use std::path::PathBuf;
use std::sync::Arc;
/// This command line flag (prefixed with `--`) results in a set of hermetic auth providers.
const DEV_AUTH_PROVIDERS_FLAG: &str = "dev-auth-providers";
/// This command line flag (prefixed with `--`) results in a set of hermetic auth mechanisms.
const DEV_AUTH_MECHANISMS_FLAG: &str = "dev-auth-mechanisms";
/// This command line flag (prefixed with `--`) starts account manager with the prototype
/// account transfer interfaces enabled.
const PROTOTYPE_TRANSFER_FLAG: &str = "prototype-account-transfer";
/// Default data directory for the AccountManager.
const DATA_DIR: &str = "/data";
lazy_static! {
/// (Temporary) Configuration for a fixed set of authentication mechanisms,
/// used until file-based configuration is available.
static ref DEFAULT_AUTHENTICATION_MECHANISM_IDS: Vec<String> = vec![];
/// Configuration for a set of fake authentication mechanisms used for
/// testing.
static ref DEV_AUTHENTICATION_MECHANISM_IDS: Vec<String> = vec![
concat!("fuchsia-pkg://fuchsia.com/dev_authenticator",
"#meta/dev_authenticator_always_succeed.cmx").to_string(),
concat!("fuchsia-pkg://fuchsia.com/dev_authenticator",
"#meta/dev_authenticator_always_fail_authentication.cmx").to_string(),
];
/// (Temporary) Configuration for a fixed set of auth providers used until file-based
/// configuration is available.
static ref DEFAULT_AUTH_PROVIDERS_CONFIG: Vec<AuthProviderConfig> = {
vec![AuthProviderConfig {
auth_provider_type: "google".to_string(),
url: fuchsia_single_component_package_url!("google_auth_provider").to_string(),
params: None
}]
};
/// Configuration for a set of fake auth providers used for testing.
static ref DEV_AUTH_PROVIDERS_CONFIG: Vec<AuthProviderConfig> = {
vec![AuthProviderConfig {
auth_provider_type: "dev_auth_provider".to_string(),
url: fuchsia_single_component_package_url!("dev_auth_provider")
.to_string(),
params: None
}]
};
}
fn main() -> Result<(), Error> {
// Parse CLI args
let mut opts = getopts::Options::new();
opts.optflag(
"",
DEV_AUTH_PROVIDERS_FLAG,
"use dev auth providers instead of the default set, for tests",
);
opts.optflag(
"",
DEV_AUTH_MECHANISMS_FLAG,
"use dev authenticators instead of the default set, for tests",
);
opts.optflag("", PROTOTYPE_TRANSFER_FLAG, "Publish prototype account transfer interfaces.");
let args: Vec<String> = std::env::args().collect();
let options = opts.parse(args)?;
let auth_provider_config: &Vec<_> = if options.opt_present(DEV_AUTH_PROVIDERS_FLAG) {
&DEV_AUTH_PROVIDERS_CONFIG
} else {
&DEFAULT_AUTH_PROVIDERS_CONFIG
};
let auth_mechanism_ids: &Vec<_> = if options.opt_present(DEV_AUTH_MECHANISMS_FLAG) {
&DEV_AUTHENTICATION_MECHANISM_IDS
} else {
&DEFAULT_AUTHENTICATION_MECHANISM_IDS
};
fuchsia_syslog::init_with_tags(&["auth"]).expect("Can't init logger");
info!("Starting account manager");
let mut executor = fasync::Executor::new().context("Error creating executor")?;
let mut fs = ServiceFs::new();
let inspector = Inspector::new();
inspector.serve(&mut fs)?;
let account_manager = Arc::new(
AccountManager::<AccountHandlerConnectionImpl>::new(
PathBuf::from(DATA_DIR),
&auth_provider_config,
&auth_mechanism_ids,
&inspector,
)
.map_err(|e| {
error!("Error initializing AccountManager: {:?}", e);
e
})?,
);
fs.dir("svc").add_fidl_service(move |stream| {
let account_manager_clone = Arc::clone(&account_manager);
fasync::Task::spawn(async move {
account_manager_clone
.handle_requests_from_stream(stream)
.await
.unwrap_or_else(|e| error!("Error handling AccountManager channel: {:?}", e))
})
.detach();
});
if options.opt_present(PROTOTYPE_TRANSFER_FLAG) {
prototype::publish_account_transfer_control(&mut fs);
prototype::publish_account_manager_peer_to_overnet()
.unwrap_or_else(|e| error!("Error publishing AccountManagerPeer: {:?}", e));
}
fs.take_and_serve_directory_handle()?;
executor.run_singlethreaded(fs.collect::<()>());
info!("Stopping account manager");
Ok(())
}