| // Copyright 2014 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 "chromeos/cryptohome/homedir_methods.h" |
| |
| #include <stdint.h> |
| |
| #include <memory> |
| #include <utility> |
| |
| #include "base/bind.h" |
| #include "base/bind_helpers.h" |
| #include "base/compiler_specific.h" |
| #include "base/macros.h" |
| #include "chromeos/dbus/cryptohome/rpc.pb.h" |
| #include "chromeos/dbus/cryptohome_client.h" |
| #include "chromeos/dbus/dbus_method_call_status.h" |
| #include "chromeos/dbus/dbus_thread_manager.h" |
| #include "chromeos/dbus/mock_cryptohome_client.h" |
| #include "components/signin/core/account_id/account_id.h" |
| #include "testing/gmock/include/gmock/gmock.h" |
| #include "testing/gtest/include/gtest/gtest.h" |
| |
| using testing::_; |
| using testing::Invoke; |
| using testing::WithArg; |
| |
| namespace cryptohome { |
| |
| namespace { |
| |
| MATCHER_P(EqualsProto, expected_proto, "") { |
| std::string expected_value; |
| expected_proto.SerializeToString(&expected_value); |
| std::string actual_value; |
| arg.SerializeToString(&actual_value); |
| return actual_value == expected_value; |
| } |
| |
| MATCHER_P(EqualsIdentification, expected_identification, "") { |
| return arg == expected_identification; |
| } |
| |
| } // namespace |
| |
| const char kUserID[] = "user@example.com"; |
| const char kKeyLabel[] = "key_label"; |
| |
| const int64_t kKeyRevision = 123; |
| const char kProviderData1Name[] = "data_1"; |
| const int64_t kProviderData1Number = 12345; |
| const char kProviderData2Name[] = "data_2"; |
| const char kProviderData2Bytes[] = "data_2 bytes"; |
| |
| class HomedirMethodsTest : public testing::Test { |
| public: |
| HomedirMethodsTest(); |
| ~HomedirMethodsTest() override; |
| |
| // testing::Test: |
| void SetUp() override; |
| void TearDown() override; |
| |
| void RunProtobufMethodCallback( |
| const chromeos::CryptohomeClient::ProtobufMethodCallback& callback); |
| |
| void StoreGetKeyDataExResult( |
| bool success, |
| MountError return_code, |
| const std::vector<KeyDefinition>& key_definitions); |
| |
| protected: |
| chromeos::MockCryptohomeClient* cryptohome_client_; |
| |
| // The reply that |cryptohome_client_| will make. |
| BaseReply cryptohome_reply_; |
| |
| // The results of the most recent |HomedirMethods| method call. |
| bool success_; |
| MountError return_code_; |
| std::vector<KeyDefinition> key_definitions_; |
| |
| private: |
| DISALLOW_COPY_AND_ASSIGN(HomedirMethodsTest); |
| }; |
| |
| HomedirMethodsTest::HomedirMethodsTest() : cryptohome_client_(NULL), |
| success_(false), |
| return_code_(MOUNT_ERROR_FATAL) { |
| } |
| |
| HomedirMethodsTest::~HomedirMethodsTest() { |
| } |
| |
| void HomedirMethodsTest::SetUp() { |
| std::unique_ptr<chromeos::MockCryptohomeClient> cryptohome_client( |
| new chromeos::MockCryptohomeClient); |
| cryptohome_client_ = cryptohome_client.get(); |
| chromeos::DBusThreadManager::GetSetterForTesting()->SetCryptohomeClient( |
| std::move(cryptohome_client)); |
| HomedirMethods::Initialize(); |
| } |
| |
| void HomedirMethodsTest::TearDown() { |
| HomedirMethods::Shutdown(); |
| chromeos::DBusThreadManager::Shutdown(); |
| } |
| |
| void HomedirMethodsTest::RunProtobufMethodCallback( |
| const chromeos::CryptohomeClient::ProtobufMethodCallback& callback) { |
| callback.Run(chromeos::DBUS_METHOD_CALL_SUCCESS, |
| true, |
| cryptohome_reply_); |
| } |
| |
| void HomedirMethodsTest::StoreGetKeyDataExResult( |
| bool success, |
| MountError return_code, |
| const std::vector<KeyDefinition>& key_definitions) { |
| success_ = success; |
| return_code_ = return_code; |
| key_definitions_ = key_definitions; |
| } |
| |
| // Verifies that the result of a GetKeyDataEx() call is correctly parsed. |
| TEST_F(HomedirMethodsTest, GetKeyDataEx) { |
| const Identification expected_id(AccountId::FromUserEmail(kUserID)); |
| const AuthorizationRequest expected_auth; |
| GetKeyDataRequest expected_request; |
| expected_request.mutable_key()->mutable_data()->set_label(kKeyLabel); |
| |
| EXPECT_CALL(*cryptohome_client_, |
| GetKeyDataEx(EqualsIdentification(expected_id), |
| EqualsProto(expected_auth), |
| EqualsProto(expected_request), _)) |
| .Times(1) |
| .WillOnce(WithArg<3>( |
| Invoke(this, &HomedirMethodsTest::RunProtobufMethodCallback))); |
| |
| // Set up the reply that |cryptohome_client_| will make. |
| GetKeyDataReply* reply = |
| cryptohome_reply_.MutableExtension(GetKeyDataReply::reply); |
| KeyData* key_data = reply->add_key_data(); |
| key_data->set_type(KeyData::KEY_TYPE_PASSWORD); |
| key_data->set_label(kKeyLabel); |
| key_data->mutable_privileges()->set_update(false); |
| key_data->set_revision(kKeyRevision); |
| key_data->add_authorization_data()->set_type( |
| KeyAuthorizationData::KEY_AUTHORIZATION_TYPE_HMACSHA256); |
| KeyProviderData* data = key_data->mutable_provider_data(); |
| KeyProviderData::Entry* entry = data->add_entry(); |
| entry->set_name(kProviderData1Name); |
| entry->set_number(kProviderData1Number); |
| entry = data->add_entry(); |
| entry->set_name(kProviderData2Name); |
| entry->set_bytes(kProviderData2Bytes); |
| |
| // Call GetKeyDataEx(). |
| HomedirMethods::GetInstance()->GetKeyDataEx( |
| Identification(AccountId::FromUserEmail(kUserID)), kKeyLabel, |
| base::Bind(&HomedirMethodsTest::StoreGetKeyDataExResult, |
| base::Unretained(this))); |
| |
| // Verify that the call was successful and the result was correctly parsed. |
| EXPECT_TRUE(success_); |
| EXPECT_EQ(MOUNT_ERROR_NONE, return_code_); |
| ASSERT_EQ(1u, key_definitions_.size()); |
| const KeyDefinition& key_definition = key_definitions_.front(); |
| EXPECT_EQ(KeyDefinition::TYPE_PASSWORD, key_definition.type); |
| EXPECT_EQ(PRIV_MOUNT | PRIV_ADD | PRIV_REMOVE, |
| key_definition.privileges); |
| EXPECT_EQ(kKeyRevision, key_definition.revision); |
| ASSERT_EQ(1u, key_definition.authorization_data.size()); |
| EXPECT_EQ(KeyDefinition::AuthorizationData::TYPE_HMACSHA256, |
| key_definition.authorization_data.front().type); |
| ASSERT_EQ(2u, key_definition.provider_data.size()); |
| const KeyDefinition::ProviderData* provider_data = |
| &key_definition.provider_data[0]; |
| EXPECT_EQ(kProviderData1Name, provider_data->name); |
| ASSERT_TRUE(provider_data->number); |
| EXPECT_EQ(kProviderData1Number, *provider_data->number.get()); |
| EXPECT_FALSE(provider_data->bytes); |
| provider_data = &key_definition.provider_data[1]; |
| EXPECT_EQ(kProviderData2Name, provider_data->name); |
| EXPECT_FALSE(provider_data->number); |
| ASSERT_TRUE(provider_data->bytes); |
| EXPECT_EQ(kProviderData2Bytes, *provider_data->bytes.get()); |
| } |
| |
| } // namespace cryptohome |