| Index: chrome/browser/chromeos/login/managed/supervised_user_authentication.cc
|
| diff --git a/chrome/browser/chromeos/login/managed/supervised_user_authentication.cc b/chrome/browser/chromeos/login/managed/supervised_user_authentication.cc
|
| deleted file mode 100644
|
| index 5679d8d392ec94a257520541bdc7c5601e5eaf08..0000000000000000000000000000000000000000
|
| --- a/chrome/browser/chromeos/login/managed/supervised_user_authentication.cc
|
| +++ /dev/null
|
| @@ -1,321 +0,0 @@
|
| -// Copyright 2013 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.
|
| -
|
| -#include "chrome/browser/chromeos/login/managed/supervised_user_authentication.h"
|
| -
|
| -#include "base/base64.h"
|
| -#include "base/json/json_file_value_serializer.h"
|
| -#include "base/macros.h"
|
| -#include "base/metrics/histogram.h"
|
| -#include "base/strings/string_number_conversions.h"
|
| -#include "base/strings/string_util.h"
|
| -#include "base/threading/sequenced_worker_pool.h"
|
| -#include "chrome/browser/chromeos/login/managed/locally_managed_user_constants.h"
|
| -#include "chrome/browser/chromeos/login/users/supervised_user_manager.h"
|
| -#include "chrome/browser/chromeos/login/users/user.h"
|
| -#include "chrome/browser/chromeos/login/users/user_manager.h"
|
| -#include "chrome/browser/chromeos/profiles/profile_helper.h"
|
| -#include "chromeos/cryptohome/signed_secret.pb.h"
|
| -#include "chromeos/login/auth/key.h"
|
| -#include "content/public/browser/browser_thread.h"
|
| -#include "crypto/hmac.h"
|
| -#include "crypto/random.h"
|
| -#include "crypto/symmetric_key.h"
|
| -
|
| -namespace chromeos {
|
| -
|
| -namespace {
|
| -
|
| -// Byte size of hash salt.
|
| -const unsigned kSaltSize = 32;
|
| -
|
| -// Size of key signature.
|
| -const unsigned kHMACKeySizeInBits = 256;
|
| -const int kSignatureLength = 32;
|
| -
|
| -// Size of master key (in bytes).
|
| -const int kMasterKeySize = 32;
|
| -
|
| -std::string CreateSalt() {
|
| - char result[kSaltSize];
|
| - crypto::RandBytes(&result, sizeof(result));
|
| - return StringToLowerASCII(base::HexEncode(
|
| - reinterpret_cast<const void*>(result),
|
| - sizeof(result)));
|
| -}
|
| -
|
| -std::string BuildRawHMACKey() {
|
| - scoped_ptr<crypto::SymmetricKey> key(crypto::SymmetricKey::GenerateRandomKey(
|
| - crypto::SymmetricKey::AES, kHMACKeySizeInBits));
|
| - std::string raw_result, result;
|
| - key->GetRawKey(&raw_result);
|
| - base::Base64Encode(raw_result, &result);
|
| - return result;
|
| -}
|
| -
|
| -base::DictionaryValue* LoadPasswordData(base::FilePath profile_dir) {
|
| - JSONFileValueSerializer serializer(profile_dir.Append(kPasswordUpdateFile));
|
| - std::string error_message;
|
| - int error_code = JSONFileValueSerializer::JSON_NO_ERROR;
|
| - scoped_ptr<base::Value> value(
|
| - serializer.Deserialize(&error_code, &error_message));
|
| - if (JSONFileValueSerializer::JSON_NO_ERROR != error_code) {
|
| - LOG(ERROR) << "Could not deserialize password data, error = " << error_code
|
| - << " / " << error_message;
|
| - return NULL;
|
| - }
|
| - base::DictionaryValue* result;
|
| - if (!value->GetAsDictionary(&result)) {
|
| - LOG(ERROR) << "Stored password data is not a dictionary";
|
| - return NULL;
|
| - }
|
| - ignore_result(value.release());
|
| - return result;
|
| -}
|
| -
|
| -void OnPasswordDataLoaded(
|
| - const SupervisedUserAuthentication::PasswordDataCallback& success_callback,
|
| - const base::Closure& failure_callback,
|
| - base::DictionaryValue* value) {
|
| - if (!value) {
|
| - failure_callback.Run();
|
| - return;
|
| - }
|
| - success_callback.Run(value);
|
| - delete value;
|
| -}
|
| -
|
| -} // namespace
|
| -
|
| -SupervisedUserAuthentication::SupervisedUserAuthentication(
|
| - SupervisedUserManager* owner)
|
| - : owner_(owner),
|
| - stable_schema_(SCHEMA_SALT_HASHED) {
|
| -}
|
| -
|
| -SupervisedUserAuthentication::~SupervisedUserAuthentication() {}
|
| -
|
| -SupervisedUserAuthentication::Schema
|
| -SupervisedUserAuthentication::GetStableSchema() {
|
| - return stable_schema_;
|
| -}
|
| -
|
| -UserContext SupervisedUserAuthentication::TransformKey(
|
| - const UserContext& context) {
|
| - UserContext result = context;
|
| - int user_schema = GetPasswordSchema(context.GetUserID());
|
| - if (user_schema == SCHEMA_PLAIN)
|
| - return result;
|
| -
|
| - if (user_schema == SCHEMA_SALT_HASHED) {
|
| - base::DictionaryValue holder;
|
| - std::string salt;
|
| - owner_->GetPasswordInformation(context.GetUserID(), &holder);
|
| - holder.GetStringWithoutPathExpansion(kSalt, &salt);
|
| - DCHECK(!salt.empty());
|
| - Key* const key = result.GetKey();
|
| - key->Transform(Key::KEY_TYPE_SALTED_PBKDF2_AES256_1234, salt);
|
| - key->SetLabel(kCryptohomeSupervisedUserKeyLabel);
|
| - result.SetIsUsingOAuth(false);
|
| - return result;
|
| - }
|
| - NOTREACHED() << "Unknown password schema for " << context.GetUserID();
|
| - return context;
|
| -}
|
| -
|
| -bool SupervisedUserAuthentication::FillDataForNewUser(
|
| - const std::string& user_id,
|
| - const std::string& password,
|
| - base::DictionaryValue* password_data,
|
| - base::DictionaryValue* extra_data) {
|
| - Schema schema = stable_schema_;
|
| - if (schema == SCHEMA_PLAIN)
|
| - return false;
|
| -
|
| - if (schema == SCHEMA_SALT_HASHED) {
|
| - password_data->SetIntegerWithoutPathExpansion(kSchemaVersion, schema);
|
| - std::string salt = CreateSalt();
|
| - password_data->SetStringWithoutPathExpansion(kSalt, salt);
|
| - int revision = kMinPasswordRevision;
|
| - password_data->SetIntegerWithoutPathExpansion(kPasswordRevision, revision);
|
| - Key key(password);
|
| - key.Transform(Key::KEY_TYPE_SALTED_PBKDF2_AES256_1234, salt);
|
| - const std::string salted_password = key.GetSecret();
|
| - const std::string base64_signature_key = BuildRawHMACKey();
|
| - const std::string base64_signature =
|
| - BuildPasswordSignature(salted_password, revision, base64_signature_key);
|
| - password_data->SetStringWithoutPathExpansion(kEncryptedPassword,
|
| - salted_password);
|
| - password_data->SetStringWithoutPathExpansion(kPasswordSignature,
|
| - base64_signature);
|
| -
|
| - extra_data->SetStringWithoutPathExpansion(kPasswordEncryptionKey,
|
| - BuildRawHMACKey());
|
| - extra_data->SetStringWithoutPathExpansion(kPasswordSignatureKey,
|
| - base64_signature_key);
|
| - return true;
|
| - }
|
| - NOTREACHED();
|
| - return false;
|
| -}
|
| -
|
| -std::string SupervisedUserAuthentication::GenerateMasterKey() {
|
| - char master_key_bytes[kMasterKeySize];
|
| - crypto::RandBytes(&master_key_bytes, sizeof(master_key_bytes));
|
| - return StringToLowerASCII(
|
| - base::HexEncode(reinterpret_cast<const void*>(master_key_bytes),
|
| - sizeof(master_key_bytes)));
|
| -}
|
| -
|
| -void SupervisedUserAuthentication::StorePasswordData(
|
| - const std::string& user_id,
|
| - const base::DictionaryValue& password_data) {
|
| - base::DictionaryValue holder;
|
| - owner_->GetPasswordInformation(user_id, &holder);
|
| - const base::Value* value;
|
| - if (password_data.GetWithoutPathExpansion(kSchemaVersion, &value))
|
| - holder.SetWithoutPathExpansion(kSchemaVersion, value->DeepCopy());
|
| - if (password_data.GetWithoutPathExpansion(kSalt, &value))
|
| - holder.SetWithoutPathExpansion(kSalt, value->DeepCopy());
|
| - if (password_data.GetWithoutPathExpansion(kPasswordRevision, &value))
|
| - holder.SetWithoutPathExpansion(kPasswordRevision, value->DeepCopy());
|
| - owner_->SetPasswordInformation(user_id, &holder);
|
| -}
|
| -
|
| -SupervisedUserAuthentication::Schema
|
| -SupervisedUserAuthentication::GetPasswordSchema(
|
| - const std::string& user_id) {
|
| - base::DictionaryValue holder;
|
| -
|
| - owner_->GetPasswordInformation(user_id, &holder);
|
| - // Default version.
|
| - int schema_version_index;
|
| - Schema schema_version = SCHEMA_PLAIN;
|
| - if (holder.GetIntegerWithoutPathExpansion(kSchemaVersion,
|
| - &schema_version_index)) {
|
| - schema_version = static_cast<Schema>(schema_version_index);
|
| - }
|
| - return schema_version;
|
| -}
|
| -
|
| -bool SupervisedUserAuthentication::NeedPasswordChange(
|
| - const std::string& user_id,
|
| - const base::DictionaryValue* password_data) {
|
| - base::DictionaryValue local;
|
| - owner_->GetPasswordInformation(user_id, &local);
|
| - int local_schema = SCHEMA_PLAIN;
|
| - int local_revision = kMinPasswordRevision;
|
| - int updated_schema = SCHEMA_PLAIN;
|
| - int updated_revision = kMinPasswordRevision;
|
| - local.GetIntegerWithoutPathExpansion(kSchemaVersion, &local_schema);
|
| - local.GetIntegerWithoutPathExpansion(kPasswordRevision, &local_revision);
|
| - password_data->GetIntegerWithoutPathExpansion(kSchemaVersion,
|
| - &updated_schema);
|
| - password_data->GetIntegerWithoutPathExpansion(kPasswordRevision,
|
| - &updated_revision);
|
| - if (updated_schema > local_schema)
|
| - return true;
|
| - DCHECK_EQ(updated_schema, local_schema);
|
| - return updated_revision > local_revision;
|
| -}
|
| -
|
| -void SupervisedUserAuthentication::ScheduleSupervisedPasswordChange(
|
| - const std::string& supervised_user_id,
|
| - const base::DictionaryValue* password_data) {
|
| - const User* user = UserManager::Get()->FindUser(supervised_user_id);
|
| - base::FilePath profile_path = ProfileHelper::GetProfilePathByUserIdHash(
|
| - user->username_hash());
|
| - JSONFileValueSerializer serializer(profile_path.Append(kPasswordUpdateFile));
|
| - if (!serializer.Serialize(*password_data)) {
|
| - LOG(ERROR) << "Failed to schedule password update for supervised user "
|
| - << supervised_user_id;
|
| - UMA_HISTOGRAM_ENUMERATION(
|
| - "ManagedUsers.ChromeOS.PasswordChange",
|
| - SupervisedUserAuthentication::PASSWORD_CHANGE_FAILED_STORE_DATA,
|
| - SupervisedUserAuthentication::PASSWORD_CHANGE_RESULT_MAX_VALUE);
|
| - return;
|
| - }
|
| - base::DictionaryValue holder;
|
| - owner_->GetPasswordInformation(supervised_user_id, &holder);
|
| - holder.SetBoolean(kRequirePasswordUpdate, true);
|
| - owner_->SetPasswordInformation(supervised_user_id, &holder);
|
| -}
|
| -
|
| -bool SupervisedUserAuthentication::HasScheduledPasswordUpdate(
|
| - const std::string& user_id) {
|
| - base::DictionaryValue holder;
|
| - owner_->GetPasswordInformation(user_id, &holder);
|
| - bool require_update = false;
|
| - holder.GetBoolean(kRequirePasswordUpdate, &require_update);
|
| - return require_update;
|
| -}
|
| -
|
| -void SupervisedUserAuthentication::ClearScheduledPasswordUpdate(
|
| - const std::string& user_id) {
|
| - base::DictionaryValue holder;
|
| - owner_->GetPasswordInformation(user_id, &holder);
|
| - holder.SetBoolean(kRequirePasswordUpdate, false);
|
| - owner_->SetPasswordInformation(user_id, &holder);
|
| -}
|
| -
|
| -bool SupervisedUserAuthentication::HasIncompleteKey(
|
| - const std::string& user_id) {
|
| - base::DictionaryValue holder;
|
| - owner_->GetPasswordInformation(user_id, &holder);
|
| - bool incomplete_key = false;
|
| - holder.GetBoolean(kHasIncompleteKey, &incomplete_key);
|
| - return incomplete_key;
|
| -}
|
| -
|
| -void SupervisedUserAuthentication::MarkKeyIncomplete(const std::string& user_id,
|
| - bool incomplete) {
|
| - base::DictionaryValue holder;
|
| - owner_->GetPasswordInformation(user_id, &holder);
|
| - holder.SetBoolean(kHasIncompleteKey, incomplete);
|
| - owner_->SetPasswordInformation(user_id, &holder);
|
| -}
|
| -
|
| -void SupervisedUserAuthentication::LoadPasswordUpdateData(
|
| - const std::string& user_id,
|
| - const PasswordDataCallback& success_callback,
|
| - const base::Closure& failure_callback) {
|
| - const User* user = UserManager::Get()->FindUser(user_id);
|
| - base::FilePath profile_path =
|
| - ProfileHelper::GetProfilePathByUserIdHash(user->username_hash());
|
| - PostTaskAndReplyWithResult(
|
| - content::BrowserThread::GetBlockingPool(),
|
| - FROM_HERE,
|
| - base::Bind(&LoadPasswordData, profile_path),
|
| - base::Bind(&OnPasswordDataLoaded, success_callback, failure_callback));
|
| -}
|
| -
|
| -std::string SupervisedUserAuthentication::BuildPasswordSignature(
|
| - const std::string& password,
|
| - int revision,
|
| - const std::string& base64_signature_key) {
|
| - ac::chrome::managedaccounts::account::Secret secret;
|
| - secret.set_revision(revision);
|
| - secret.set_secret(password);
|
| - std::string buffer;
|
| - if (!secret.SerializeToString(&buffer))
|
| - LOG(FATAL) << "Protobuf::SerializeToString failed";
|
| - std::string signature_key;
|
| - base::Base64Decode(base64_signature_key, &signature_key);
|
| -
|
| - crypto::HMAC hmac(crypto::HMAC::SHA256);
|
| - if (!hmac.Init(signature_key))
|
| - LOG(FATAL) << "HMAC::Init failed";
|
| -
|
| - unsigned char out_bytes[kSignatureLength];
|
| - if (!hmac.Sign(buffer, out_bytes, sizeof(out_bytes)))
|
| - LOG(FATAL) << "HMAC::Sign failed";
|
| -
|
| - std::string raw_result(out_bytes, out_bytes + sizeof(out_bytes));
|
| -
|
| - std::string result;
|
| - base::Base64Encode(raw_result, &result);
|
| - return result;
|
| -}
|
| -
|
| -} // namespace chromeos
|
|
|