| // 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 <utility> |
| #include <vector> |
| |
| #include <base/memory/ref_counted.h> |
| #include <base/time/tick_clock.h> |
| #include <brillo/dbus/dbus_method_response.h> |
| #include <brillo/errors/error.h> |
| #include <chromeos/dbus/service_constants.h> |
| #include <libpasswordprovider/password_provider.h> |
| |
| #include "login_manager/arc_sideload_status_interface.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/login_screen_storage.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 StartArcMiniContainerRequest; |
| class SystemUtils; |
| class UpgradeArcContainerRequest; |
| class UserPolicyServiceFactory; |
| class VpdProcess; |
| |
| // Enable further isolation of the user session (including the browser process |
| // tree), beyond merely running as user 'chronos'. |
| constexpr bool __attribute__((unused)) IsolateUserSession() { |
| return USE_USER_SESSION_ISOLATION; |
| } |
| |
| // 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: |
| // 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[]; |
| |
| // File containing the path to the updated TPM firmware binary. |
| static const char kTPMFirmwareUpdateLocationFile[]; |
| |
| // Flag file indicating SRK ROCA vulnerability status. |
| static const char kTPMFirmwareUpdateSRKVulnerableROCAFile[]; |
| |
| // Flag file indicating a request to update TPM firmware after reboot. |
| static const char kTPMFirmwareUpdateRequestFlagFile[]; |
| |
| // Flag file that signals to mount_encrypted that we're requesting it to |
| // preserve the encrypted stateful file system across a TPM reset. |
| static const char kStatefulPreservationRequestFile[]; |
| |
| // Name of impulse emitted when user session starts. |
| static const char kStartUserSessionImpulse[]; |
| |
| // Android container messages. |
| static const char kStartArcInstanceImpulse[]; |
| static const char kStopArcInstanceImpulse[]; |
| static const char kContinueArcBootImpulse[]; |
| static const char kArcBootedImpulse[]; |
| |
| // Lock screen state messages. |
| static const char kScreenLockedImpulse[]; |
| static const char kScreenUnlockedImpulse[]; |
| |
| // How much time we must wait before killing the containers. |
| static const base::TimeDelta kContainerTimeout; |
| |
| // How much time to wait for the key generator job to stop before killing it. |
| static const base::TimeDelta kKeyGenTimeout; |
| |
| // How much time to give the browser to shutdown cleanly before killing it. |
| static const base::TimeDelta kBrowserTimeout; |
| |
| // Time window before or after suspend/resume in which the session should be |
| // ended if Chrome crashes. This is done as a precaution to avoid showing an |
| // unlocked screen if the crash made Chrome fail to lock the screen: |
| // https://crbug.com/867970 |
| static const base::TimeDelta kCrashBeforeSuspendInterval; |
| static const base::TimeDelta kCrashAfterSuspendInterval; |
| |
| // 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, |
| base::Optional<base::FilePath> ns_path, |
| SystemUtils* utils, |
| Crossystem* crossystem, |
| VpdProcess* vpd_process, |
| PolicyKey* owner_key, |
| ContainerManagerInterface* android_container, |
| InstallAttributesReader* install_attributes_reader, |
| dbus::ObjectProxy* powerd_proxy, |
| dbus::ObjectProxy* system_clock_proxy, |
| dbus::ObjectProxy* debugd_proxy, |
| ArcSideloadStatusInterface* arc_sideload_status); |
| SessionManagerImpl(const SessionManagerImpl&) = delete; |
| SessionManagerImpl& operator=(const SessionManagerImpl&) = delete; |
| |
| ~SessionManagerImpl() override; |
| |
| // Tests can call these 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); |
| void SetTickClockForTesting(std::unique_ptr<base::TickClock> clock); |
| void SetUiLogSymlinkPathForTesting(const base::FilePath& path); |
| void SetLoginScreenStorageForTesting( |
| std::unique_ptr<LoginScreenStorage> login_screen_storage); |
| |
| // 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(std::string* reason_out) override; |
| std::vector<std::string> GetStartUpSwitches() override { |
| return device_policy_->GetStartUpSwitches(); |
| } |
| std::vector<std::string> GetFeatureFlags() override { |
| return device_policy_->GetFeatureFlags(); |
| } |
| |
| // 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/platform2/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; |
| void EmitAshInitialized() override; |
| bool EnableChromeTesting( |
| brillo::ErrorPtr* error, |
| bool in_force_relaunch, |
| const std::vector<std::string>& in_extra_arguments, |
| const std::vector<std::string>& in_extra_environment_variables, |
| std::string* out_filepath) override; |
| bool SaveLoginPassword(brillo::ErrorPtr* error, |
| const base::ScopedFD& in_password_fd) override; |
| bool LoginScreenStorageStore(brillo::ErrorPtr* error, |
| const std::string& in_key, |
| const std::vector<uint8_t>& in_metadata, |
| uint64_t in_value_size, |
| const base::ScopedFD& in_value_fd) override; |
| bool LoginScreenStorageRetrieve( |
| brillo::ErrorPtr* error, |
| const std::string& in_key, |
| uint64_t* out_value_size, |
| brillo::dbus_utils::FileDescriptor* out_value_fd) override; |
| bool LoginScreenStorageListKeys(brillo::ErrorPtr* error, |
| std::vector<std::string>* out_keys) override; |
| void LoginScreenStorageDelete(const std::string& in_key) 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; |
| void StopSessionWithReason(uint32_t reason) 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; |
| bool ListStoredComponentPolicies( |
| brillo::ErrorPtr* error, |
| const std::vector<uint8_t>& in_descriptor_blob, |
| std::vector<std::string>* out_component_ids) override; |
| |
| std::string RetrieveSessionState() override; |
| std::map<std::string, std::string> RetrieveActiveSessions() override; |
| void RetrievePrimarySession(std::string* out_username, |
| std::string* out_sanitized_username) override; |
| bool IsGuestSessionActive() override; |
| |
| void HandleSupervisedUserCreationStarting() override; |
| void HandleSupervisedUserCreationFinished() override; |
| |
| bool LockScreen(brillo::ErrorPtr* error) override; |
| void HandleLockScreenShown() override; |
| void HandleLockScreenDismissed() override; |
| bool IsScreenLocked() override; |
| |
| bool RestartJob(brillo::ErrorPtr* error, |
| const base::ScopedFD& in_cred_fd, |
| const std::vector<std::string>& in_argv) override; |
| |
| bool StartDeviceWipe(brillo::ErrorPtr* error) override; |
| bool StartRemoteDeviceWipe( |
| brillo::ErrorPtr* error, |
| const std::vector<uint8_t>& in_signed_command) override; |
| void ClearForcedReEnrollmentVpd( |
| std::unique_ptr<brillo::dbus_utils::DBusMethodResponse<>> response) |
| override; |
| bool StartTPMFirmwareUpdate(brillo::ErrorPtr* error, |
| const std::string& update_mode) override; |
| void SetFlagsForUser(const std::string& in_account_id, |
| const std::vector<std::string>& in_flags) override; |
| void SetFeatureFlagsForUser( |
| const std::string& in_account_id, |
| const std::vector<std::string>& in_feature_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 StartArcMiniContainer(brillo::ErrorPtr* error, |
| const std::vector<uint8_t>& in_request) override; |
| bool UpgradeArcContainer(brillo::ErrorPtr* error, |
| const std::vector<uint8_t>& in_request) override; |
| bool StopArcInstance(brillo::ErrorPtr* error, |
| const std::string& account_id, |
| bool should_backup_log) 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; |
| void EnableAdbSideload( |
| std::unique_ptr<brillo::dbus_utils::DBusMethodResponse<bool>> response) |
| override; |
| void QueryAdbSideload( |
| std::unique_ptr<brillo::dbus_utils::DBusMethodResponse<bool>> response) |
| 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; |
| } |
| |
| void SetPasswordProviderForTesting( |
| std::unique_ptr<password_provider::PasswordProviderInterface> |
| password_provider) { |
| password_provider_ = std::move(password_provider); |
| } |
| |
| 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 powerd announces that a suspend/resume cycle is beginning or |
| // ending. |
| void OnSuspendImminent(dbus::Signal* signal); |
| void OnSuspendDone(dbus::Signal* signal); |
| |
| // 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, |
| const OptionalFilePath& ns_mnt_path, |
| 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(); |
| |
| // Returns the appropriate PolicyService for the given |descriptor|. |storage| |
| // is only set for some |descriptor|s. If set, it controls the lifetime of the |
| // returned pointer. Returns nullptr and sets |error| if no PolicyService |
| // could be found. |
| PolicyService* GetPolicyService(const PolicyDescriptor& descriptor, |
| std::unique_ptr<PolicyService>* storage, |
| brillo::ErrorPtr* error); |
| |
| // Returns the appropriate PolicyService::KeyInstallFlags for the given |
| // |descriptor|. |
| int GetKeyInstallFlags(const PolicyDescriptor& descriptor); |
| |
| // 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); |
| |
| // Requests a reboot. Formats the actual reason string to name session_manager |
| // as the source of the request. |
| void RestartDevice(const std::string& reason); |
| |
| void EnableAdbSideloadCallbackAdaptor( |
| brillo::dbus_utils::DBusMethodResponse<bool>* response, |
| ArcSideloadStatusInterface::Status status, |
| const char* error); |
| void QueryAdbSideloadCallbackAdaptor( |
| brillo::dbus_utils::DBusMethodResponse<bool>* response, |
| ArcSideloadStatusInterface::Status status); |
| |
| void BackupArcBugReport(const std::string& account_id); |
| void DeleteArcBugReportBackup(const std::string& account_id); |
| |
| #if USE_CHEETS |
| // Starts the Android container for ARC. If an error occurs, brillo::Error |
| // instance is set to |error_out|. After this succeeds, in case of ARC stop, |
| // OnAndroidContainerStopped() is called. |
| bool StartArcContainer(const std::vector<std::string>& env_vars, |
| brillo::ErrorPtr* error_out); |
| |
| // Creates environment variables passed to upstart for container upgrade. |
| std::vector<std::string> CreateUpgradeArcEnvVars( |
| const UpgradeArcContainerRequest& request, |
| const std::string& account_id, |
| pid_t pid); |
| |
| // Called when the container fails to continue booting. |
| void OnContinueArcBootFailed(); |
| |
| // Stops the ARC container with the given |reason|. |
| bool StopArcInstanceInternal(ArcContainerStopReason reason); |
| |
| // Called when the Android container is stopped. |
| void OnAndroidContainerStopped(pid_t pid, ArcContainerStopReason reason); |
| #endif |
| |
| bool session_started_ = false; |
| bool session_stopping_ = false; |
| bool screen_locked_ = false; |
| bool supervised_user_creation_ongoing_ = false; |
| bool system_clock_synchronized_ = false; |
| std::string cookie_; |
| |
| // True if a SuspendImminent D-Bus signal was received from |powerd_proxy_| |
| // but the corresponding SuspendDone signal hasn't been received yet. |
| bool suspend_ongoing_ = false; |
| |
| // Time at which the last SuspendDone signal was received from |
| // |powerd_proxy_|. |
| base::TimeTicks last_suspend_done_time_; |
| |
| 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_; |
| |
| std::unique_ptr<base::TickClock> tick_clock_; |
| scoped_refptr<dbus::Bus> bus_; |
| org::chromium::SessionManagerInterfaceAdaptor adaptor_; |
| std::unique_ptr<DBusService> dbus_service_; |
| |
| // Ownership of all of these raw pointers remains elsewhere. |
| Delegate* delegate_; |
| KeyGenerator* key_gen_; |
| ServerBackedStateKeyGenerator* state_key_generator_; |
| ProcessManagerServiceInterface* manager_; |
| LoginMetrics* login_metrics_; |
| NssUtil* nss_; |
| base::Optional<base::FilePath> chrome_mount_ns_path_; |
| SystemUtils* system_; |
| Crossystem* crossystem_; |
| VpdProcess* vpd_process_; |
| PolicyKey* owner_key_; |
| ContainerManagerInterface* android_container_; |
| InstallAttributesReader* install_attributes_reader_; |
| dbus::ObjectProxy* powerd_proxy_; |
| dbus::ObjectProxy* system_clock_proxy_; |
| dbus::ObjectProxy* debugd_proxy_; |
| std::unique_ptr<DevicePolicyService> device_policy_; |
| std::unique_ptr<UserPolicyServiceFactory> user_policy_factory_; |
| std::unique_ptr<DeviceLocalAccountManager> device_local_account_manager_; |
| |
| std::unique_ptr<ArcSideloadStatusInterface> arc_sideload_status_; |
| |
| 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_; |
| |
| // Primary user is the first non-incognito user. |
| std::string primary_user_account_id_; |
| |
| // Path to symlink pointing at log file containing stdout and stderr for |
| // session_manager and Chrome, e.g. "/var/log/ui/ui.LATEST". |
| base::FilePath ui_log_symlink_path_; |
| |
| std::unique_ptr<password_provider::PasswordProviderInterface> |
| password_provider_; |
| |
| std::unique_ptr<LoginScreenStorage> login_screen_storage_; |
| |
| base::WeakPtrFactory<SessionManagerImpl> weak_ptr_factory_; |
| }; |
| |
| } // namespace login_manager |
| #endif // LOGIN_MANAGER_SESSION_MANAGER_IMPL_H_ |