blob: 8014003a30fec3673e83b1bcfb7bbbc86bebbb26 [file] [log] [blame]
// Copyright (c) 2017 The Chromium 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 CHROME_BROWSER_CHROMEOS_POLICY_PRE_SIGNIN_POLICY_FETCHER_H_
#define CHROME_BROWSER_CHROMEOS_POLICY_PRE_SIGNIN_POLICY_FETCHER_H_
#include <memory>
#include <string>
#include "base/macros.h"
#include "base/memory/ref_counted.h"
#include "base/memory/weak_ptr.h"
#include "base/optional.h"
#include "base/timer/timer.h"
#include "chrome/browser/chromeos/policy/cached_policy_key_loader_chromeos.h"
#include "chromeos/cryptohome/cryptohome_parameters.h"
#include "chromeos/dbus/session_manager_client.h"
#include "components/policy/core/common/cloud/cloud_policy_client.h"
#include "components/policy/core/common/cloud/cloud_policy_validator.h"
#include "components/signin/core/account_id/account_id.h"
#include "third_party/cros_system_api/dbus/cryptohome/dbus-constants.h"
namespace base {
class SequencedTaskRunner;
}
namespace chromeos {
class CryptohomeClient;
}
namespace enterprise_management {
class CloudPolicySettings;
class PolicyData;
class PolicyFetchResponse;
} // namespace enterprise_management
namespace policy {
// Performs a policy fetch before actually mounting cryptohome. This is done in
// the following steps:
// (1) Mount the user's cryptohome to a temporary location.
// (2) Retrieve policy from there, along with the policy verification key.
// (3) Unmount the temporary cryptohome.
//
// And if cached policy was found:
// (4) Validate the cached policy.
// (5) Try to fetch fresh policy from DMServer.
// (6) Validate fresh policy.
//
// If steps (1)-(4) are successful, the cached policy will be used even if no
// fresh policy is available.
class PreSigninPolicyFetcher : public CloudPolicyClient::Observer {
public:
// The result of the pre-signin policy fetch.
enum class PolicyFetchResult {
// The policy could not be fetched, e.g. error in cryptohome/session_manager
// calls or it could not be validated.
ERROR,
// The user does not have policy.
NO_POLICY,
// The policy was successfully fetched. This could be a cached policy or a
// fresh policy.
SUCCESS,
};
using PolicyFetchResultCallback = base::OnceCallback<void(
PolicyFetchResult result,
std::unique_ptr<enterprise_management::CloudPolicySettings> policy_data)>;
PreSigninPolicyFetcher(chromeos::CryptohomeClient* cryptohome_client,
chromeos::SessionManagerClient* session_manager_client,
std::unique_ptr<CloudPolicyClient> cloud_policy_client,
bool is_active_directory_managed,
const AccountId& account_id,
const cryptohome::KeyDefinition& auth_key);
~PreSigninPolicyFetcher() override;
// Start the policy fetch procedure. |callback| will be invoked with the
// result.
void FetchPolicy(PolicyFetchResultCallback callback);
// Forces a policy fetch timeout.
// Returns true if the timer was running and a timeout was forced. If the
// timer was not running, returns false.
bool ForceTimeoutForTesting();
private:
using RetrievePolicyResponseType =
chromeos::SessionManagerClient::RetrievePolicyResponseType;
void OnMountTemporaryUserHome(bool success,
cryptohome::MountError return_code,
const std::string& mount_hash);
void OnCachedPolicyRetrieved(
RetrievePolicyResponseType retrieve_policy_response,
const std::string& policy_blob);
void OnPolicyKeyLoaded(RetrievePolicyResponseType retrieve_policy_response,
const std::string& policy_blob);
void OnUnmountTemporaryUserHome(
RetrievePolicyResponseType retrieve_policy_response,
const std::string& policy_blob,
base::Optional<bool> unmount_success);
void OnCachedPolicyValidated(UserCloudPolicyValidator* validator);
// CloudPolicyClient::Observer:
void OnPolicyFetched(CloudPolicyClient* client) override;
void OnRegistrationStateChanged(CloudPolicyClient* client) override;
void OnClientError(CloudPolicyClient* client) override;
// Called by |policy_fetch_timeout_|.
void OnPolicyFetchTimeout();
void OnFetchedPolicyValidated(UserCloudPolicyValidator* validator);
// Invokes |callback_| with the passed result after cleaning up.
void NotifyCallback(
PolicyFetchResult result,
std::unique_ptr<enterprise_management::CloudPolicySettings>
policy_payload);
// Creates a validator which can be used to validate the cached policy.
std::unique_ptr<UserCloudPolicyValidator> CreateValidatorForCachedPolicy(
std::unique_ptr<enterprise_management::PolicyFetchResponse> policy);
// Creates a validator which can be used to validate the freshly fetched
// policy, based on the cached policy.
std::unique_ptr<UserCloudPolicyValidator> CreateValidatorForFetchedPolicy(
std::unique_ptr<enterprise_management::PolicyFetchResponse> policy);
chromeos::CryptohomeClient* const cryptohome_client_;
chromeos::SessionManagerClient* const session_manager_client_;
const std::unique_ptr<CloudPolicyClient> cloud_policy_client_;
const bool is_active_directory_managed_;
const AccountId account_id_;
const cryptohome::KeyDefinition auth_key_;
scoped_refptr<base::SequencedTaskRunner> task_runner_;
// Callback passed to FetchPolicy method.
PolicyFetchResultCallback callback_;
// |policy_data_| and |policy_payload_| will first hold the cached policy on
// successful load and validation, and will then be reset to hold fresh policy
// if download and validation of the fresh policy is successful.
std::unique_ptr<enterprise_management::PolicyData> policy_data_;
std::unique_ptr<enterprise_management::CloudPolicySettings> policy_payload_;
// A timer that puts a hard limit on the maximum time to wait for the fresh
// policy fetch.
base::Timer policy_fetch_timeout_{false, false};
// Used to load the policy key provided by session manager as a file.
std::unique_ptr<CachedPolicyKeyLoaderChromeOS> cached_policy_key_loader_;
base::WeakPtrFactory<PreSigninPolicyFetcher> weak_ptr_factory_;
DISALLOW_COPY_AND_ASSIGN(PreSigninPolicyFetcher);
};
} // namespace policy
#endif // CHROME_BROWSER_CHROMEOS_POLICY_PRE_SIGNIN_POLICY_FETCHER_H_