// Copyright (c) 2011 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/signed_settings.h"
#include "base/file_util.h"
#include "base/logging.h"
#include "base/memory/scoped_temp_dir.h"
#include "base/stringprintf.h"
#include "chrome/browser/chromeos/cros/cros_library.h"
#include "chrome/browser/chromeos/cros/mock_library_loader.h"
#include "chrome/browser/chromeos/cros/mock_login_library.h"
#include "chrome/browser/chromeos/cros_settings_names.h"
#include "chrome/browser/chromeos/login/mock_owner_key_utils.h"
#include "chrome/browser/chromeos/login/mock_ownership_service.h"
#include "chrome/browser/chromeos/login/owner_manager_unittest.h"
#include "chrome/browser/policy/proto/chrome_device_policy.pb.h"
#include "chrome/browser/policy/proto/device_management_backend.pb.h"
#include "chrome/test/thread_test_helper.h"
#include "content/browser/browser_thread.h"
#include "crypto/rsa_private_key.h"
#include "testing/gmock/include/gmock/gmock.h"
#include "testing/gtest/include/gtest/gtest.h"
using ::testing::A;
using ::testing::AnyNumber;
using ::testing::InvokeArgument;
using ::testing::Return;
using ::testing::ReturnRef;
using ::testing::SaveArg;
using ::testing::StrEq;
using ::testing::WithArg;
using ::testing::_;
using google::protobuf::RepeatedPtrField;
namespace em = enterprise_management;
namespace chromeos {
namespace {
template <class T>
class DummyDelegate : public SignedSettings::Delegate<T> {
public:
explicit DummyDelegate(T to_expect)
: expect_success_(false),
expected_failure_(SignedSettings::SUCCESS),
expected_(to_expect),
run_(false) {}
virtual ~DummyDelegate() { EXPECT_TRUE(run_); }
virtual void OnSettingsOpCompleted(SignedSettings::ReturnCode code,
T value) {
run_ = true;
if (expect_success_)
compare_expected(value);
EXPECT_EQ(expected_failure_, code);
}
virtual void expect_success() {
expect_success_ = true;
expected_failure_ = SignedSettings::SUCCESS;
}
virtual void expect_failure(SignedSettings::ReturnCode code) {
expect_success_ = false;
expected_failure_ = code;
}
protected:
bool expect_success_;
SignedSettings::ReturnCode expected_failure_;
T expected_;
bool run_;
virtual void compare_expected(T to_compare) = 0;
};
template <class T>
class NormalDelegate : public DummyDelegate<T> {
public:
explicit NormalDelegate(T to_expect) : DummyDelegate<T>(to_expect) {}
virtual ~NormalDelegate() {}
protected:
virtual void compare_expected(T to_compare) {
EXPECT_EQ(this->expected_, to_compare); // without this-> this won't build.
}
};
class ProtoDelegate : public DummyDelegate<const em::PolicyFetchResponse&> {
public:
explicit ProtoDelegate(const em::PolicyFetchResponse& e)
: DummyDelegate<const em::PolicyFetchResponse&>(e) {
}
virtual ~ProtoDelegate() {}
protected:
virtual void compare_expected(const em::PolicyFetchResponse& to_compare) {
std::string ex_string, comp_string;
EXPECT_TRUE(expected_.SerializeToString(&ex_string));
EXPECT_TRUE(to_compare.SerializeToString(&comp_string));
EXPECT_EQ(ex_string, comp_string);
}
};
} // anonymous namespace
class SignedSettingsTest : public ::testing::Test {
public:
SignedSettingsTest()
: fake_email_("fakey@example.com"),
fake_domain_("*@example.com"),
fake_prop_(kAccountsPrefAllowGuest),
fake_value_("false"),
message_loop_(MessageLoop::TYPE_UI),
ui_thread_(BrowserThread::UI, &message_loop_),
file_thread_(BrowserThread::FILE),
mock_(new MockKeyUtils),
injector_(mock_) /* injector_ takes ownership of mock_ */ {
}
virtual ~SignedSettingsTest() {}
virtual void SetUp() {
file_thread_.Start();
}
virtual void TearDown() {
OwnerKeyUtils::set_factory(NULL);
}
void mock_service(SignedSettings* s, MockOwnershipService* m) {
s->set_service(m);
}
em::PolicyData BuildPolicyData(std::vector<std::string> whitelist) {
em::PolicyData to_return;
em::ChromeDeviceSettingsProto pol;
em::GuestModeEnabledProto* allow = pol.mutable_guest_mode_enabled();
allow->set_guest_mode_enabled(false);
pol.mutable_device_proxy_settings()->set_proxy_mode("direct");
if (!whitelist.empty()) {
em::UserWhitelistProto* whitelist_proto = pol.mutable_user_whitelist();
for (std::vector<std::string>::const_iterator it = whitelist.begin();
it != whitelist.end();
++it) {
whitelist_proto->add_user_whitelist(*it);
}
}
to_return.set_policy_type(SignedSettings::kDevicePolicyType);
to_return.set_policy_value(pol.SerializeAsString());
return to_return;
}
void SetAllowNewUsers(bool desired, em::PolicyData* poldata) {
em::ChromeDeviceSettingsProto pol;
pol.ParseFromString(poldata->policy_value());
em::AllowNewUsersProto* allow = pol.mutable_allow_new_users();
allow->set_allow_new_users(desired);
poldata->set_policy_value(pol.SerializeAsString());
}
bool CheckWhitelist(const std::string& email, const em::PolicyData& poldata) {
if (!poldata.has_policy_value())
return false;
em::ChromeDeviceSettingsProto pol;
pol.ParseFromString(poldata.policy_value());
if (!pol.has_user_whitelist())
return false;
const RepeatedPtrField<std::string>& whitelist =
pol.user_whitelist().user_whitelist();
for (RepeatedPtrField<std::string>::const_iterator it = whitelist.begin();
it != whitelist.end();
++it) {
if (email == *it)
return true;
}
return false;
}
void ExpectWhitelistOp(SignedSettings* s,
em::PolicyData* fake_pol,
em::PolicyData* out_pol) {
mock_service(s, &m_);
EXPECT_CALL(m_, StartSigningAttempt(_, _))
.Times(1);
EXPECT_CALL(m_, has_cached_policy())
.WillOnce(Return(true));
EXPECT_CALL(m_, cached_policy())
.WillOnce(ReturnRef(*fake_pol));
EXPECT_CALL(m_, set_cached_policy(A<const em::PolicyData&>()))
.WillOnce(SaveArg<0>(out_pol));
}
void FailingStorePropertyOp(const OwnerManager::KeyOpCode return_code) {
NormalDelegate<bool> d(false);
scoped_refptr<SignedSettings> s(
SignedSettings::CreateStorePropertyOp(fake_prop_, fake_value_, &d));
d.expect_failure(SignedSettings::MapKeyOpCode(return_code));
mock_service(s.get(), &m_);
EXPECT_CALL(m_, StartSigningAttempt(_, _))
.Times(1);
EXPECT_CALL(m_, GetStatus(_))
.WillOnce(Return(OwnershipService::OWNERSHIP_TAKEN));
EXPECT_CALL(m_, has_cached_policy())
.WillOnce(Return(true));
em::PolicyData fake_pol;
EXPECT_CALL(m_, cached_policy())
.WillOnce(ReturnRef(fake_pol));
s->Execute();
s->OnKeyOpComplete(return_code, std::vector<uint8>());
message_loop_.RunAllPending();
}
void FailingStorePolicyOp(const OwnerManager::KeyOpCode return_code) {
NormalDelegate<bool> d(false);
d.expect_failure(SignedSettings::MapKeyOpCode(return_code));
em::PolicyFetchResponse fake_policy;
fake_policy.set_policy_data(fake_prop_);
std::string serialized;
ASSERT_TRUE(fake_policy.SerializeToString(&serialized));
scoped_refptr<SignedSettings> s(
SignedSettings::CreateStorePolicyOp(&fake_policy, &d));
mock_service(s.get(), &m_);
EXPECT_CALL(m_, StartSigningAttempt(StrEq(fake_prop_), _))
.Times(1);
s->Execute();
s->OnKeyOpComplete(return_code, std::vector<uint8>());
message_loop_.RunAllPending();
}
MockLoginLibrary* MockLoginLib() {
chromeos::CrosLibrary::TestApi* test_api =
chromeos::CrosLibrary::Get()->GetTestApi();
// Mocks, ownership transferred to CrosLibrary class on creation.
MockLoginLibrary* mock_library;
MockLibraryLoader* loader;
loader = new MockLibraryLoader();
ON_CALL(*loader, Load(_))
.WillByDefault(Return(true));
EXPECT_CALL(*loader, Load(_))
.Times(AnyNumber());
test_api->SetLibraryLoader(loader, true);
mock_library = new MockLoginLibrary();
test_api->SetLoginLibrary(mock_library, true);
return mock_library;
}
void UnMockLoginLib() {
// Prevent bogus gMock leak check from firing.
chromeos::CrosLibrary::TestApi* test_api =
chromeos::CrosLibrary::Get()->GetTestApi();
test_api->SetLibraryLoader(NULL, false);
test_api->SetLoginLibrary(NULL, false);
}
em::PolicyFetchResponse BuildProto(const std::string& data,
const std::string& sig,
std::string* out_serialized) {
em::PolicyFetchResponse fake_policy;
if (!data.empty())
fake_policy.set_policy_data(data);
if (!sig.empty())
fake_policy.set_policy_data_signature(sig);
EXPECT_TRUE(fake_policy.SerializeToString(out_serialized));
return fake_policy;
}
void DoRetrieveProperty(const std::string& name,
const std::string& value,
em::PolicyData* fake_pol) {
NormalDelegate<std::string> d(value);
d.expect_success();
scoped_refptr<SignedSettings> s(
SignedSettings::CreateRetrievePropertyOp(name, &d));
mock_service(s.get(), &m_);
EXPECT_CALL(m_, GetStatus(_))
.WillOnce(Return(OwnershipService::OWNERSHIP_TAKEN));
EXPECT_CALL(m_, has_cached_policy())
.WillOnce(Return(true));
EXPECT_CALL(m_, cached_policy())
.WillOnce(ReturnRef(*fake_pol));
s->Execute();
message_loop_.RunAllPending();
}
const std::string fake_email_;
const std::string fake_domain_;
const std::string fake_prop_;
const std::string fake_value_;
MockOwnershipService m_;
ScopedTempDir tmpdir_;
FilePath tmpfile_;
MessageLoop message_loop_;
BrowserThread ui_thread_;
BrowserThread file_thread_;
std::vector<uint8> fake_public_key_;
scoped_ptr<crypto::RSAPrivateKey> fake_private_key_;
MockKeyUtils* mock_;
MockInjector injector_;
ScopedStubCrosEnabler stub_cros_enabler_;
};
TEST_F(SignedSettingsTest, CheckWhitelist) {
NormalDelegate<bool> d(true);
d.expect_success();
scoped_refptr<SignedSettings> s(
SignedSettings::CreateCheckWhitelistOp(fake_email_, &d));
mock_service(s.get(), &m_);
EXPECT_CALL(m_, has_cached_policy())
.WillOnce(Return(true));
std::vector<std::string> whitelist(1, fake_email_);
whitelist.push_back(fake_email_ + "m");
em::PolicyData fake_pol = BuildPolicyData(whitelist);
EXPECT_CALL(m_, cached_policy())
.WillOnce(ReturnRef(fake_pol));
s->Execute();
message_loop_.RunAllPending();
}
TEST_F(SignedSettingsTest, CheckWhitelistWildcards) {
NormalDelegate<bool> d(true);
d.expect_success();
scoped_refptr<SignedSettings> s(
SignedSettings::CreateCheckWhitelistOp(fake_email_, &d));
mock_service(s.get(), &m_);
EXPECT_CALL(m_, has_cached_policy())
.WillOnce(Return(true));
std::vector<std::string> whitelist(1, fake_domain_);
whitelist.push_back(fake_email_ + "m");
em::PolicyData fake_pol = BuildPolicyData(whitelist);
EXPECT_CALL(m_, cached_policy())
.WillOnce(ReturnRef(fake_pol))
.WillOnce(ReturnRef(fake_pol));
s->Execute();
message_loop_.RunAllPending();
}
TEST_F(SignedSettingsTest, CheckWhitelistNotFound) {
NormalDelegate<bool> d(true);
scoped_refptr<SignedSettings> s(
SignedSettings::CreateCheckWhitelistOp(fake_email_, &d));
d.expect_failure(SignedSettings::NOT_FOUND);
mock_service(s.get(), &m_);
EXPECT_CALL(m_, has_cached_policy())
.WillOnce(Return(true));
std::vector<std::string> whitelist(1, fake_email_ + "m");
em::PolicyData fake_pol = BuildPolicyData(whitelist);
EXPECT_CALL(m_, cached_policy())
.WillOnce(ReturnRef(fake_pol))
.WillOnce(ReturnRef(fake_pol));
s->Execute();
message_loop_.RunAllPending();
}
TEST_F(SignedSettingsTest, Whitelist) {
NormalDelegate<bool> d(true);
d.expect_success();
scoped_refptr<SignedSettings> s(
SignedSettings::CreateWhitelistOp(fake_email_, true, &d));
em::PolicyData in_pol = BuildPolicyData(std::vector<std::string>());
em::PolicyData out_pol;
ExpectWhitelistOp(s.get(), &in_pol, &out_pol);
s->Execute();
s->OnKeyOpComplete(OwnerManager::SUCCESS, std::vector<uint8>());
message_loop_.RunAllPending();
ASSERT_TRUE(CheckWhitelist(fake_email_, out_pol));
}
TEST_F(SignedSettingsTest, AddToExistingWhitelist) {
NormalDelegate<bool> d(true);
d.expect_success();
scoped_refptr<SignedSettings> s(
SignedSettings::CreateWhitelistOp(fake_email_, true, &d));
em::PolicyData in_pol =
BuildPolicyData(std::vector<std::string>(1, fake_domain_));
em::PolicyData out_pol;
ExpectWhitelistOp(s.get(), &in_pol, &out_pol);
s->Execute();
s->OnKeyOpComplete(OwnerManager::SUCCESS, std::vector<uint8>());
message_loop_.RunAllPending();
ASSERT_TRUE(CheckWhitelist(fake_email_, out_pol));
}
TEST_F(SignedSettingsTest, Unwhitelist) {
NormalDelegate<bool> d(true);
d.expect_success();
scoped_refptr<SignedSettings> s(
SignedSettings::CreateWhitelistOp(fake_email_, false, &d));
em::PolicyData in_pol =
BuildPolicyData(std::vector<std::string>(1, fake_email_));
em::PolicyData out_pol;
ExpectWhitelistOp(s.get(), &in_pol, &out_pol);
s->Execute();
s->OnKeyOpComplete(OwnerManager::SUCCESS, std::vector<uint8>());
message_loop_.RunAllPending();
ASSERT_FALSE(CheckWhitelist(fake_email_, out_pol));
}
TEST_F(SignedSettingsTest, RemoveFromExistingWhitelist) {
NormalDelegate<bool> d(true);
d.expect_success();
scoped_refptr<SignedSettings> s(
SignedSettings::CreateWhitelistOp(fake_email_, false, &d));
std::vector<std::string> whitelist(1, fake_domain_);
whitelist.push_back(fake_email_);
whitelist.push_back(fake_email_ + "m");
em::PolicyData in_pol = BuildPolicyData(whitelist);
em::PolicyData out_pol;
ExpectWhitelistOp(s.get(), &in_pol, &out_pol);
s->Execute();
s->OnKeyOpComplete(OwnerManager::SUCCESS, std::vector<uint8>());
message_loop_.RunAllPending();
ASSERT_FALSE(CheckWhitelist(fake_email_, out_pol));
}
TEST_F(SignedSettingsTest, StoreProperty) {
NormalDelegate<bool> d(true);
d.expect_success();
scoped_refptr<SignedSettings> s(
SignedSettings::CreateStorePropertyOp(fake_prop_, fake_value_, &d));
mock_service(s.get(), &m_);
EXPECT_CALL(m_, StartSigningAttempt(_, _))
.Times(1);
EXPECT_CALL(m_, GetStatus(_))
.WillOnce(Return(OwnershipService::OWNERSHIP_TAKEN));
EXPECT_CALL(m_, has_cached_policy())
.WillOnce(Return(true));
em::PolicyData in_pol =
BuildPolicyData(std::vector<std::string>(1, fake_email_));
EXPECT_CALL(m_, cached_policy())
.WillOnce(ReturnRef(in_pol));
em::PolicyData out_pol;
EXPECT_CALL(m_, set_cached_policy(A<const em::PolicyData&>()))
.WillOnce(SaveArg<0>(&out_pol));
s->Execute();
s->OnKeyOpComplete(OwnerManager::SUCCESS, std::vector<uint8>());
message_loop_.RunAllPending();
ASSERT_TRUE(out_pol.has_policy_value());
em::ChromeDeviceSettingsProto pol;
pol.ParseFromString(out_pol.policy_value());
ASSERT_TRUE(pol.has_guest_mode_enabled());
ASSERT_TRUE(pol.guest_mode_enabled().has_guest_mode_enabled());
ASSERT_FALSE(pol.guest_mode_enabled().guest_mode_enabled());
}
TEST_F(SignedSettingsTest, StorePropertyNoKey) {
FailingStorePropertyOp(OwnerManager::KEY_UNAVAILABLE);
}
TEST_F(SignedSettingsTest, StorePropertyFailed) {
FailingStorePropertyOp(OwnerManager::OPERATION_FAILED);
}
TEST_F(SignedSettingsTest, RetrieveProperty) {
em::PolicyData fake_pol = BuildPolicyData(std::vector<std::string>());
DoRetrieveProperty(fake_prop_, fake_value_, &fake_pol);
}
TEST_F(SignedSettingsTest, RetrieveOwnerProperty) {
em::PolicyData fake_pol = BuildPolicyData(std::vector<std::string>());
fake_pol.set_username(fake_email_);
DoRetrieveProperty(kDeviceOwner, fake_email_, &fake_pol);
}
TEST_F(SignedSettingsTest, ExplicitlyAllowNewUsers) {
em::PolicyData fake_pol = BuildPolicyData(std::vector<std::string>());
SetAllowNewUsers(true, &fake_pol);
DoRetrieveProperty(kAccountsPrefAllowNewUser, "true", &fake_pol);
}
TEST_F(SignedSettingsTest, ExplicitlyDisallowNewUsers) {
std::vector<std::string> whitelist(1, fake_email_ + "m");
em::PolicyData fake_pol = BuildPolicyData(whitelist);
SetAllowNewUsers(false, &fake_pol);
DoRetrieveProperty(kAccountsPrefAllowNewUser, "false", &fake_pol);
}
TEST_F(SignedSettingsTest, ImplicitlyDisallowNewUsers) {
std::vector<std::string> whitelist(1, fake_email_ + "m");
em::PolicyData fake_pol = BuildPolicyData(whitelist);
DoRetrieveProperty(kAccountsPrefAllowNewUser, "false", &fake_pol);
}
TEST_F(SignedSettingsTest, AccidentallyDisallowNewUsers) {
em::PolicyData fake_pol = BuildPolicyData(std::vector<std::string>());
SetAllowNewUsers(false, &fake_pol);
DoRetrieveProperty(kAccountsPrefAllowNewUser, "true", &fake_pol);
}
TEST_F(SignedSettingsTest, RetrievePropertyNotFound) {
NormalDelegate<std::string> d(fake_value_);
d.expect_failure(SignedSettings::NOT_FOUND);
scoped_refptr<SignedSettings> s(
SignedSettings::CreateRetrievePropertyOp("unknown_prop", &d));
mock_service(s.get(), &m_);
EXPECT_CALL(m_, GetStatus(_))
.WillOnce(Return(OwnershipService::OWNERSHIP_TAKEN));
EXPECT_CALL(m_, has_cached_policy())
.WillOnce(Return(true));
em::PolicyData fake_pol = BuildPolicyData(std::vector<std::string>());
EXPECT_CALL(m_, cached_policy())
.WillOnce(ReturnRef(fake_pol));
s->Execute();
message_loop_.RunAllPending();
}
ACTION_P(Retrieve, s) { (*arg0)((void*)arg1, s.c_str(), s.length()); }
ACTION_P(FinishKeyOp, s) { arg2->OnKeyOpComplete(OwnerManager::SUCCESS, s); }
TEST_F(SignedSettingsTest, RetrievePolicyToRetrieveProperty) {
NormalDelegate<std::string> d(fake_value_);
d.expect_success();
scoped_refptr<SignedSettings> s(
SignedSettings::CreateRetrievePropertyOp(fake_prop_, &d));
em::PolicyData fake_pol = BuildPolicyData(std::vector<std::string>());
std::string data = fake_pol.SerializeAsString();
std::string signed_serialized;
em::PolicyFetchResponse signed_policy = BuildProto(data,
fake_value_,
&signed_serialized);
MockLoginLibrary* lib = MockLoginLib();
EXPECT_CALL(*lib, RequestRetrievePolicy(_, _))
.WillOnce(Retrieve(signed_serialized))
.RetiresOnSaturation();
mock_service(s.get(), &m_);
EXPECT_CALL(m_, GetStatus(_))
.WillOnce(Return(OwnershipService::OWNERSHIP_TAKEN))
.WillOnce(Return(OwnershipService::OWNERSHIP_TAKEN));
EXPECT_CALL(m_, has_cached_policy())
.WillOnce(Return(false))
.WillOnce(Return(true));
em::PolicyData out_pol;
EXPECT_CALL(m_, set_cached_policy(A<const em::PolicyData&>()))
.WillOnce(SaveArg<0>(&out_pol));
EXPECT_CALL(m_, cached_policy())
.WillOnce(ReturnRef(out_pol));
std::vector<uint8> fake_sig(fake_value_.c_str(),
fake_value_.c_str() + fake_value_.length());
EXPECT_CALL(m_, StartVerifyAttempt(data, fake_sig, _))
.WillOnce(FinishKeyOp(fake_sig))
.RetiresOnSaturation();
s->Execute();
message_loop_.RunAllPending();
UnMockLoginLib();
}
TEST_F(SignedSettingsTest, SignAndStorePolicy) {
NormalDelegate<bool> d(true);
d.expect_success();
em::PolicyData in_pol = BuildPolicyData(std::vector<std::string>());
std::string data_serialized = in_pol.SerializeAsString();
std::string serialized;
em::PolicyFetchResponse fake_policy = BuildProto(data_serialized,
std::string(),
&serialized);
scoped_refptr<SignedSettings> s(
SignedSettings::CreateStorePolicyOp(&fake_policy, &d));
mock_service(s.get(), &m_);
EXPECT_CALL(m_, StartSigningAttempt(StrEq(data_serialized), _))
.Times(1);
em::PolicyData out_pol;
EXPECT_CALL(m_, set_cached_policy(A<const em::PolicyData&>()))
.WillOnce(SaveArg<0>(&out_pol));
// Ask for signature over unsigned policy.
s->Execute();
message_loop_.RunAllPending();
// Fake out a successful signing.
std::string signed_serialized;
em::PolicyFetchResponse signed_policy = BuildProto(data_serialized,
fake_value_,
&signed_serialized);
std::vector<uint8> fake_sig(fake_value_.c_str(),
fake_value_.c_str() + fake_value_.length());
MockLoginLibrary* lib = MockLoginLib();
EXPECT_CALL(*lib, RequestStorePolicy(StrEq(signed_serialized), _, s.get()))
.WillOnce(InvokeArgument<1>(static_cast<void*>(s.get()), true))
.RetiresOnSaturation();
s->OnKeyOpComplete(OwnerManager::SUCCESS, fake_sig);
message_loop_.RunAllPending();
UnMockLoginLib();
}
TEST_F(SignedSettingsTest, StoreSignedPolicy) {
NormalDelegate<bool> d(true);
d.expect_success();
em::PolicyData in_pol = BuildPolicyData(std::vector<std::string>());
std::string serialized = in_pol.SerializeAsString();
std::string signed_serialized;
em::PolicyFetchResponse signed_policy = BuildProto(serialized,
fake_value_,
&signed_serialized);
scoped_refptr<SignedSettings> s(
SignedSettings::CreateStorePolicyOp(&signed_policy, &d));
MockLoginLibrary* lib = MockLoginLib();
EXPECT_CALL(*lib, RequestStorePolicy(StrEq(signed_serialized), _, s.get()))
.WillOnce(InvokeArgument<1>(static_cast<void*>(s.get()), true))
.RetiresOnSaturation();
mock_service(s.get(), &m_);
em::PolicyData out_pol;
EXPECT_CALL(m_, set_cached_policy(A<const em::PolicyData&>()))
.WillOnce(SaveArg<0>(&out_pol));
s->Execute();
message_loop_.RunAllPending();
UnMockLoginLib();
}
TEST_F(SignedSettingsTest, StorePolicyNoKey) {
FailingStorePolicyOp(OwnerManager::KEY_UNAVAILABLE);
}
TEST_F(SignedSettingsTest, StorePolicyFailed) {
FailingStorePolicyOp(OwnerManager::OPERATION_FAILED);
}
TEST_F(SignedSettingsTest, StorePolicyNoPolicyData) {
NormalDelegate<bool> d(false);
d.expect_failure(SignedSettings::OPERATION_FAILED);
std::string serialized;
em::PolicyFetchResponse fake_policy = BuildProto(std::string(),
std::string(),
&serialized);
scoped_refptr<SignedSettings> s(
SignedSettings::CreateStorePolicyOp(&fake_policy, &d));
s->Execute();
message_loop_.RunAllPending();
}
TEST_F(SignedSettingsTest, RetrievePolicy) {
em::PolicyData in_pol = BuildPolicyData(std::vector<std::string>());
std::string serialized = in_pol.SerializeAsString();
std::string signed_serialized;
em::PolicyFetchResponse signed_policy = BuildProto(serialized,
fake_value_,
&signed_serialized);
ProtoDelegate d(signed_policy);
d.expect_success();
scoped_refptr<SignedSettings> s(SignedSettings::CreateRetrievePolicyOp(&d));
MockLoginLibrary* lib = MockLoginLib();
EXPECT_CALL(*lib, RequestRetrievePolicy(_, s.get()))
.WillOnce(InvokeArgument<0>(static_cast<void*>(s.get()),
signed_serialized.c_str(),
signed_serialized.length()))
.RetiresOnSaturation();
mock_service(s.get(), &m_);
std::vector<uint8> fake_sig(fake_value_.c_str(),
fake_value_.c_str() + fake_value_.length());
EXPECT_CALL(m_, StartVerifyAttempt(serialized, fake_sig, _))
.Times(1);
em::PolicyData out_pol;
EXPECT_CALL(m_, set_cached_policy(A<const em::PolicyData&>()))
.WillOnce(SaveArg<0>(&out_pol));
s->Execute();
message_loop_.RunAllPending();
UnMockLoginLib();
s->OnKeyOpComplete(OwnerManager::SUCCESS, std::vector<uint8>());
message_loop_.RunAllPending();
}
TEST_F(SignedSettingsTest, RetrieveNullPolicy) {
em::PolicyFetchResponse policy;
ProtoDelegate d(policy);
d.expect_failure(SignedSettings::NOT_FOUND);
scoped_refptr<SignedSettings> s(SignedSettings::CreateRetrievePolicyOp(&d));
MockLoginLibrary* lib = MockLoginLib();
EXPECT_CALL(*lib, RequestRetrievePolicy(_, s.get()))
.WillOnce(InvokeArgument<0>(static_cast<void*>(s.get()),
static_cast<const char*>(NULL),
0))
.RetiresOnSaturation();
s->Execute();
message_loop_.RunAllPending();
UnMockLoginLib();
}
TEST_F(SignedSettingsTest, RetrieveEmptyPolicy) {
std::string serialized;
em::PolicyFetchResponse policy = BuildProto("", "", &serialized);
ProtoDelegate d(policy);
d.expect_failure(SignedSettings::NOT_FOUND);
scoped_refptr<SignedSettings> s(SignedSettings::CreateRetrievePolicyOp(&d));
MockLoginLibrary* lib = MockLoginLib();
EXPECT_CALL(*lib, RequestRetrievePolicy(_, s.get()))
.WillOnce(InvokeArgument<0>(static_cast<void*>(s.get()), "", 0))
.RetiresOnSaturation();
s->Execute();
message_loop_.RunAllPending();
UnMockLoginLib();
}
TEST_F(SignedSettingsTest, RetrieveUnsignedPolicy) {
std::string serialized;
em::PolicyFetchResponse policy = BuildProto(fake_prop_,
std::string(),
&serialized);
ProtoDelegate d(policy);
d.expect_failure(SignedSettings::BAD_SIGNATURE);
scoped_refptr<SignedSettings> s(SignedSettings::CreateRetrievePolicyOp(&d));
MockLoginLibrary* lib = MockLoginLib();
EXPECT_CALL(*lib, RequestRetrievePolicy(_, s.get()))
.WillOnce(InvokeArgument<0>(static_cast<void*>(s.get()),
serialized.c_str(),
serialized.length()))
.RetiresOnSaturation();
s->Execute();
message_loop_.RunAllPending();
UnMockLoginLib();
}
TEST_F(SignedSettingsTest, RetrieveMalsignedPolicy) {
std::string signed_serialized;
em::PolicyFetchResponse signed_policy = BuildProto(fake_prop_,
fake_value_,
&signed_serialized);
ProtoDelegate d(signed_policy);
d.expect_failure(SignedSettings::BAD_SIGNATURE);
scoped_refptr<SignedSettings> s(SignedSettings::CreateRetrievePolicyOp(&d));
MockLoginLibrary* lib = MockLoginLib();
EXPECT_CALL(*lib, RequestRetrievePolicy(_, s.get()))
.WillOnce(InvokeArgument<0>(static_cast<void*>(s.get()),
signed_serialized.c_str(),
signed_serialized.length()))
.RetiresOnSaturation();
mock_service(s.get(), &m_);
std::vector<uint8> fake_sig(fake_value_.c_str(),
fake_value_.c_str() + fake_value_.length());
EXPECT_CALL(m_, StartVerifyAttempt(fake_prop_, fake_sig, _))
.Times(1);
s->Execute();
message_loop_.RunAllPending();
UnMockLoginLib();
s->OnKeyOpComplete(OwnerManager::OPERATION_FAILED, std::vector<uint8>());
message_loop_.RunAllPending();
}
} // namespace chromeos