blob: 6e899015be244449fe8855d9d10684a2123ee29c [file] [log] [blame]
// Copyright (c) 2012 The Chromium OS Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifndef LOGIN_MANAGER_SESSION_MANAGER_IMPL_H_
#define LOGIN_MANAGER_SESSION_MANAGER_IMPL_H_
#include "login_manager/session_manager_interface.h"
#include <stdint.h>
#include <stdlib.h>
#include <map>
#include <memory>
#include <string>
#include <vector>
#include <base/memory/ref_counted.h>
#include <brillo/dbus/dbus_method_response.h>
#include <brillo/errors/error.h>
#include <dbus/file_descriptor.h>
#include "login_manager/container_manager_interface.h"
#include "login_manager/dbus_adaptors/org.chromium.SessionManagerInterface.h"
#include "login_manager/device_local_account_manager.h"
#include "login_manager/device_policy_service.h"
#include "login_manager/key_generator.h"
#include "login_manager/policy_service.h"
#include "login_manager/regen_mitigator.h"
#include "login_manager/server_backed_state_key_generator.h"
class Crossystem;
class InstallAttributesReader;
namespace dbus {
class Bus;
class ObjectProxy;
class Response;
} // namespace dbus
namespace login_manager {
class DeviceLocalAccountManager;
class InitDaemonController;
class KeyGenerator;
class LoginMetrics;
class NssUtil;
class PolicyDescriptor;
class PolicyKey;
class ProcessManagerServiceInterface;
class StartArcInstanceRequest;
class SystemUtils;
class TerminaManagerInterface;
class UserPolicyServiceFactory;
class VpdProcess;
// Implements the DBus SessionManagerInterface.
//
// All signatures used in the methods of the ownership API are
// SHA1 with RSA encryption.
class SessionManagerImpl
: public SessionManagerInterface,
public KeyGenerator::Delegate,
public PolicyService::Delegate,
public org::chromium::SessionManagerInterfaceInterface {
public:
// Magic user name strings.
static const char kDemoUser[];
// Payloads for SessionStateChanged DBus signal.
static const char kStarted[];
static const char kStopping[];
static const char kStopped[];
// Path to flag file indicating that a user has logged in since last boot.
static const char kLoggedInFlag[];
// Path to magic file that will trigger device wiping on next boot.
static const char kResetFile[];
// Path to flag file indicating that a TPM firmware update is available.
static const char kTPMFirmwareUpdateAvailableFile[];
// The VPD key that holds the TPM firmware update parameters. These are
// encoded string-value pairs using ':' as the value separator and ',' as the
// pair separator.
static const char kTPMFirmwareUpdateParamsVPDKey[];
// Name of impulse emitted when user session starts.
static const char kStartUserSessionImpulse[];
// Name of the Android container.
static const char kArcContainerName[];
// A UNIX domain server socket path for communicating with the container.
static const char kArcBridgeSocketPath[];
// The group of the socket file.
static const char kArcBridgeSocketGroup[];
// Android container messages.
static const char kStartArcInstanceForLoginScreenImpulse[];
static const char kStartArcInstanceImpulse[];
static const char kStopArcInstanceImpulse[];
static const char kContinueArcBootImpulse[];
static const char kStartArcNetworkImpulse[];
static const char kStopArcNetworkImpulse[];
static const char kArcBootedImpulse[];
static const char kRemoveOldArcDataImpulse[];
// SystemUtils::EnsureJobExit() DCHECKs if the timeout is zero, so this is the
// minimum amount of time we must wait before killing the containers.
static const base::TimeDelta kContainerTimeout;
// The Delegate interface performs actions on behalf of SessionManagerImpl.
class Delegate {
public:
virtual ~Delegate() = default;
// Asks Chrome to lock the screen asynchronously.
virtual void LockScreen() = 0;
// Asks powerd to restart the device. |description| will be logged by powerd
// to explain the reason for the restart.
virtual void RestartDevice(const std::string& description) = 0;
};
// Ownership of raw pointer arguments remains with the caller.
SessionManagerImpl(Delegate* delegate,
std::unique_ptr<InitDaemonController> init_controller,
const scoped_refptr<dbus::Bus>& bus,
KeyGenerator* key_gen,
ServerBackedStateKeyGenerator* state_key_generator,
ProcessManagerServiceInterface* manager,
LoginMetrics* metrics,
NssUtil* nss,
SystemUtils* utils,
Crossystem* crossystem,
VpdProcess* vpd_process,
PolicyKey* owner_key,
ContainerManagerInterface* android_container,
TerminaManagerInterface* termina_manager,
InstallAttributesReader* install_attributes_reader,
dbus::ObjectProxy* component_updater_proxy,
dbus::ObjectProxy* system_clock_proxy);
~SessionManagerImpl() override;
// Checks if string looks like a valid account ID key (as returned by
// AccountId::GetAccountIdKey()).
static bool ValidateAccountIdKey(const std::string& account_id);
// Performs very, very basic validation of |email_address|.
static bool ValidateEmail(const std::string& email_address);
#if USE_CHEETS
// Validates if the given |request| satisfies the requirement of the
// StartArcInstance input. Returns true on success. Otherwise false,
// and brillo::Error instance is set to |error|.
static bool ValidateStartArcInstanceRequest(
const StartArcInstanceRequest& request, brillo::ErrorPtr* error);
// Returns the Android data directory for |normalized_account_id|.
static base::FilePath GetAndroidDataDirForUser(
const std::string& normalized_account_id);
// Returns the directory where old Android data directories are stored for
// |normalized_account_id|.
static base::FilePath GetAndroidDataOldDirForUser(
const std::string& normalized_account_id);
#endif // USE_CHEETS
// Tests can call this before Initialize() to inject their own objects.
void SetPolicyServicesForTesting(
std::unique_ptr<DevicePolicyService> device_policy,
std::unique_ptr<UserPolicyServiceFactory> user_policy_factory,
std::unique_ptr<DeviceLocalAccountManager> device_local_account_manager);
// SessionManagerInterface implementation.
// Should set up policy stuff; if false DIE.
bool Initialize() override;
void Finalize() override;
bool StartDBusService() override;
void AnnounceSessionStoppingIfNeeded() override;
void AnnounceSessionStopped() override;
bool ShouldEndSession() override;
std::vector<std::string> GetStartUpFlags() override {
return device_policy_->GetStartUpFlags();
}
// Starts a 'Powerwash' of the device by touching a flag file, then
// rebooting to allow early-boot code to wipe parts of stateful we
// need wiped. Have a look at /src/platform/init/chromeos_startup
// for the gory details.
void InitiateDeviceWipe(const std::string& reason) override;
//////////////////////////////////////////////////////////////////////////////
// Methods exposed via RPC are defined below.
// org::chromium::SessionManagerInterfaceInterface implementation.
void EmitLoginPromptVisible() override;
bool EnableChromeTesting(brillo::ErrorPtr* error,
bool in_force_relaunch,
const std::vector<std::string>& in_extra_arguments,
std::string* out_filepath) override;
bool StartSession(brillo::ErrorPtr* error,
const std::string& in_account_id,
const std::string& in_unique_identifier) override;
void StopSession(const std::string& in_unique_identifier) override;
// Deprecated, use StorePolicyEx.
void StorePolicy(
std::unique_ptr<brillo::dbus_utils::DBusMethodResponse<>> response,
const std::vector<uint8_t>& in_policy_blob) override;
// Deprecated, use StoreUnsignedPolicyEx.
void StoreUnsignedPolicy(
std::unique_ptr<brillo::dbus_utils::DBusMethodResponse<>> response,
const std::vector<uint8_t>& in_policy_blob) override;
// Deprecated, use RetrievePolicyEx.
bool RetrievePolicy(brillo::ErrorPtr* error,
std::vector<uint8_t>* out_policy_blob) override;
// Deprecated, use StorePolicyEx.
void StorePolicyForUser(
std::unique_ptr<brillo::dbus_utils::DBusMethodResponse<>> response,
const std::string& in_account_id,
const std::vector<uint8_t>& in_policy_blob) override;
// Deprecated, use StoreUnsignedPolicyEx.
void StoreUnsignedPolicyForUser(
std::unique_ptr<brillo::dbus_utils::DBusMethodResponse<>> response,
const std::string& in_account_id,
const std::vector<uint8_t>& in_policy_blob) override;
// Deprecated, use RetrievePolicyEx.
bool RetrievePolicyForUser(brillo::ErrorPtr* error,
const std::string& in_account_id,
std::vector<uint8_t>* out_policy_blob) override;
// Deprecated, use RetrievePolicyEx.
bool RetrievePolicyForUserWithoutSession(
brillo::ErrorPtr* error,
const std::string& in_account_id,
std::vector<uint8_t>* out_policy_blob) override;
// Deprecated, use StorePolicyEx.
void StoreDeviceLocalAccountPolicy(
std::unique_ptr<brillo::dbus_utils::DBusMethodResponse<>> response,
const std::string& in_account_id,
const std::vector<uint8_t>& in_policy_blob) override;
// Deprecated, use RetrievePolicyEx.
bool RetrieveDeviceLocalAccountPolicy(
brillo::ErrorPtr* error,
const std::string& in_account_id,
std::vector<uint8_t>* out_policy_blob) override;
// Interface for storing and retrieving policy.
// TODO(crbug.com/765644): Remove 'Ex', see bug description.
void StorePolicyEx(
std::unique_ptr<brillo::dbus_utils::DBusMethodResponse<>> response,
const std::vector<uint8_t>& in_descriptor_blob,
const std::vector<uint8_t>& in_policy_blob) override;
void StoreUnsignedPolicyEx(
std::unique_ptr<brillo::dbus_utils::DBusMethodResponse<>> response,
const std::vector<uint8_t>& in_descriptor_blob,
const std::vector<uint8_t>& in_policy_blob) override;
bool RetrievePolicyEx(brillo::ErrorPtr* error,
const std::vector<uint8_t>& in_descriptor_blob,
std::vector<uint8_t>* out_policy_blob) override;
std::string RetrieveSessionState() override;
std::map<std::string, std::string> RetrieveActiveSessions() override;
bool IsGuestSessionActive() override;
void HandleSupervisedUserCreationStarting() override;
void HandleSupervisedUserCreationFinished() override;
bool LockScreen(brillo::ErrorPtr* error) override;
void HandleLockScreenShown() override;
void HandleLockScreenDismissed() override;
bool RestartJob(brillo::ErrorPtr* error,
const dbus::FileDescriptor& in_cred_fd,
const std::vector<std::string>& in_argv) override;
bool StartDeviceWipe(brillo::ErrorPtr* error) override;
void StartTPMFirmwareUpdate(
std::unique_ptr<brillo::dbus_utils::DBusMethodResponse<>> response,
const std::string& update_mode) override;
void SetFlagsForUser(const std::string& in_account_id,
const std::vector<std::string>& in_flags) override;
void GetServerBackedStateKeys(
std::unique_ptr<brillo::dbus_utils::DBusMethodResponse<
std::vector<std::vector<uint8_t>>>> response) override;
bool InitMachineInfo(brillo::ErrorPtr* error,
const std::string& in_data) override;
bool StartContainer(brillo::ErrorPtr* error,
const std::string& in_path,
const std::string& in_name,
const std::string& in_hashed_username,
bool in_writable) override;
bool StopContainer(brillo::ErrorPtr* error,
const std::string& in_name) override;
bool StartArcInstance(brillo::ErrorPtr* error,
const std::vector<uint8_t>& in_request,
std::string* out_container_instance_id,
dbus::FileDescriptor* out_fd) override;
bool StopArcInstance(brillo::ErrorPtr* error) override;
bool SetArcCpuRestriction(brillo::ErrorPtr* error,
uint32_t in_restriction_state) override;
bool EmitArcBooted(brillo::ErrorPtr* error,
const std::string& in_account_id) override;
bool GetArcStartTimeTicks(brillo::ErrorPtr* error,
int64_t* out_start_time) override;
bool RemoveArcData(brillo::ErrorPtr* error,
const std::string& in_account_id) override;
// PolicyService::Delegate implementation:
void OnPolicyPersisted(bool success) override;
void OnKeyPersisted(bool success) override;
// KeyGenerator::Delegate implementation:
void OnKeyGenerated(const std::string& username,
const base::FilePath& temp_key_file) override;
void SetSystemClockLastSyncInfoRetryDelayForTesting(
const base::TimeDelta& delay) {
system_clock_last_sync_info_retry_delay_ = delay;
}
private:
class DBusService;
// Holds the state related to one of the signed in users.
struct UserSession;
using UserSessionMap = std::map<std::string, std::unique_ptr<UserSession>>;
// Called when the tlsdated service becomes initially available.
void OnSystemClockServiceAvailable(bool service_available);
// Request the LastSyncInfo from tlsdated daemon.
void GetSystemClockLastSyncInfo();
// The response to LastSyncInfo request is processed here. If the time sync
// was done then the state keys are generated, otherwise another LastSyncInfo
// request is scheduled to be done later.
void OnGotSystemClockLastSyncInfo(dbus::Response* response);
// Given a policy key stored at temp_key_file, pulls it off disk,
// validates that it is a correctly formed key pair, and ensures it is
// stored for the future in the provided user's NSSDB.
void ImportValidateAndStoreGeneratedKey(const std::string& username,
const base::FilePath& temp_key_file);
// Normalizes an account ID in the case of a legacy email address.
// Returns true on success, false otherwise. In case of an error,
// brillo::Error instance is set to |error_out|.
static bool NormalizeAccountId(const std::string& account_id,
std::string* actual_account_id_out,
brillo::ErrorPtr* error_out);
bool AllSessionsAreIncognito();
std::unique_ptr<UserSession> CreateUserSession(const std::string& username,
bool is_incognito,
brillo::ErrorPtr* error);
// Verifies whether unsigned policies are permitted to be stored.
// Returns nullptr on success. Otherwise, an error that should be used in a
// reply to the D-Bus method call is returned.
brillo::ErrorPtr VerifyUnsignedPolicyStore();
PolicyService* GetPolicyService(const std::string& account_id);
// Shared implementation of StorePolicy() and StoreUnsignedPolicy().
void StorePolicyInternal(
const std::vector<uint8_t>& policy_blob,
SignatureCheck signature_check,
std::unique_ptr<brillo::dbus_utils::DBusMethodResponse<>> response);
// Shared implementation of StorePolicyForUser() and
// StoreUnsignedPolicyForUser().
void StorePolicyForUserInternal(
const std::string& account_id,
const std::vector<uint8_t>& policy_blob,
SignatureCheck signature_check,
std::unique_ptr<brillo::dbus_utils::DBusMethodResponse<>> response);
// Shared implementation of StorePolicyEx() and StoreUnsignedPolicyEx().
void StorePolicyInternalEx(
const std::vector<uint8_t>& descriptor_blob,
const std::vector<uint8_t>& policy_blob,
SignatureCheck signature_check,
std::unique_ptr<brillo::dbus_utils::DBusMethodResponse<>> response);
// Completion handler that gets invoked after writing the TPM firmware
// mode to VPD. Checks |success| of the VPD operation, triggers a device reset
// appropriate for |update_mode| and replies to the DBus call via |response|.
void OnTPMFirmwareUpdateModeUpdated(
const std::string& update_mode,
std::unique_ptr<brillo::dbus_utils::DBusMethodResponse<>> response,
bool success);
#if USE_CHEETS
// Creates a server socket for ARC and stores the descriptor in |out_fd|.
bool CreateArcServerSocket(dbus::FileDescriptor* out_fd,
brillo::ErrorPtr* error);
// Implementation of StartArcInstance, except parsing blob to protobuf.
// When |container_pid| is greater than 0, the function tries to continue to
// boot the existing container rather than starting a new one from scratch.
bool StartArcInstanceInternal(brillo::ErrorPtr* error,
const StartArcInstanceRequest& in_request,
pid_t container_pid,
std::string* out_container_instance_id);
// Starts the Android container for ARC. If the container has started,
// container_instance_id will be returned. Otherwise, an empty string
// is returned and brillo::Error instance is set to |error_out|.
// After this succeeds, in case of ARC stop, OnAndroidContainerStopped()
// is called with the returned container_instance_id.
std::string StartArcContainer(const std::string& init_signal,
const std::vector<std::string>& init_keyvals,
brillo::ErrorPtr* error_out);
// Starts the network interface for the Android container for ARC.
// On success, returns true. Otherwise returns false and brillo::Error
// instance is set to |error_out|.
bool StartArcNetwork(brillo::ErrorPtr* error_out);
// Called when the Android container is stopped.
void OnAndroidContainerStopped(const std::string& container_instance_id,
pid_t pid,
bool clean);
// Sends an init signal to turn the container from the one for login screen
// into a fully featured one. If that succeeds, this function also sends an
// init signal for starting the network interface for the container.
// Returns true if both succeed.
bool ContinueArcBoot(const std::vector<std::string>& init_keyvals,
brillo::ErrorPtr* error_out);
// Called when the container fails to continue booting.
void OnContinueArcBootFailed();
// Renames android-data/ in the user's home directory to android-data-old/,
// then recursively removes the renamed directory. Returns false when it
// fails to rename android-data/.
bool RemoveArcDataInternal(const base::FilePath& android_data_dir,
const base::FilePath& android_data_old_dir);
#endif
bool session_started_;
bool session_stopping_;
bool screen_locked_;
bool supervised_user_creation_ongoing_;
bool system_clock_synchronized_;
std::string cookie_;
base::FilePath chrome_testing_path_;
std::unique_ptr<InitDaemonController> init_controller_;
base::TimeDelta system_clock_last_sync_info_retry_delay_;
base::TimeTicks arc_start_time_;
scoped_refptr<dbus::Bus> bus_;
org::chromium::SessionManagerInterfaceAdaptor adaptor_;
std::unique_ptr<DBusService> dbus_service_;
Delegate* delegate_; // Owned by the caller.
KeyGenerator* key_gen_; // Owned by the caller.
ServerBackedStateKeyGenerator* state_key_generator_; // Owned by the caller.
ProcessManagerServiceInterface* manager_; // Owned by the caller.
LoginMetrics* login_metrics_; // Owned by the caller.
NssUtil* nss_; // Owned by the caller.
SystemUtils* system_; // Owned by the caller.
Crossystem* crossystem_; // Owned by the caller.
VpdProcess* vpd_process_; // Owned by the caller.
PolicyKey* owner_key_; // Owned by the caller.
ContainerManagerInterface* android_container_; // Owned by the caller.
TerminaManagerInterface* termina_manager_; // Owned by the caller.
InstallAttributesReader* install_attributes_reader_; // Owned by the caller.
dbus::ObjectProxy* component_updater_proxy_; // Owned by the caller.
dbus::ObjectProxy* system_clock_proxy_; // Owned by the caller.
std::unique_ptr<DevicePolicyService> device_policy_;
std::unique_ptr<UserPolicyServiceFactory> user_policy_factory_;
std::unique_ptr<DeviceLocalAccountManager> device_local_account_manager_;
RegenMitigator mitigator_;
// Callbacks passed to RequestServerBackedStateKeys() while
// |system_clock_synchrononized_| was false. They will be run by
// OnGotSystemClockLastSyncInfo() once the clock is synchronized.
std::vector<ServerBackedStateKeyGenerator::StateKeyCallback>
pending_state_key_callbacks_;
// Map of the currently signed-in users to their state.
UserSessionMap user_sessions_;
base::WeakPtrFactory<SessionManagerImpl> weak_ptr_factory_;
DISALLOW_COPY_AND_ASSIGN(SessionManagerImpl);
};
} // namespace login_manager
#endif // LOGIN_MANAGER_SESSION_MANAGER_IMPL_H_