Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(1678)

Unified Diff: chrome/browser/chromeos/policy/user_network_configuration_updater_factory_browsertest.cc

Issue 2862003002: Enable policy-imported root CA certificates for kiosk and AD sessions (Closed)
Patch Set: Addressed comments. Created 3 years, 7 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « chrome/browser/chromeos/policy/user_network_configuration_updater_factory.cc ('k') | chrome/test/BUILD.gn » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: chrome/browser/chromeos/policy/user_network_configuration_updater_factory_browsertest.cc
diff --git a/chrome/browser/chromeos/policy/user_network_configuration_updater_factory_browsertest.cc b/chrome/browser/chromeos/policy/user_network_configuration_updater_factory_browsertest.cc
new file mode 100644
index 0000000000000000000000000000000000000000..ab992a585a5ea023ac6339434d7600dc3ddab8bd
--- /dev/null
+++ b/chrome/browser/chromeos/policy/user_network_configuration_updater_factory_browsertest.cc
@@ -0,0 +1,319 @@
+// 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.
+
+#include <memory>
+
+#include "base/command_line.h"
+#include "base/memory/ptr_util.h"
+#include "base/run_loop.h"
+#include "chrome/browser/browser_process.h"
+#include "chrome/browser/chrome_notification_types.h"
+#include "chrome/browser/chromeos/login/existing_user_controller.h"
+#include "chrome/browser/chromeos/login/session/user_session_manager.h"
+#include "chrome/browser/chromeos/login/session/user_session_manager_test_api.h"
+#include "chrome/browser/chromeos/login/ui/login_display_host.h"
+#include "chrome/browser/chromeos/login/wizard_controller.h"
+#include "chrome/browser/chromeos/policy/device_policy_cros_browser_test.h"
+#include "chrome/browser/chromeos/policy/user_network_configuration_updater.h"
+#include "chrome/browser/chromeos/policy/user_network_configuration_updater_factory.h"
+#include "chrome/browser/policy/test/local_policy_test_server.h"
+#include "chrome/browser/profiles/profile.h"
+#include "chrome/browser/ui/browser.h"
+#include "chrome/browser/ui/browser_list.h"
+#include "chrome/browser/ui/webui/chromeos/login/signin_screen_handler.h"
+#include "chrome/test/base/in_process_browser_test.h"
+#include "chromeos/chromeos_switches.h"
+#include "chromeos/chromeos_test_utils.h"
+#include "chromeos/network/onc/onc_test_utils.h"
+#include "components/policy/core/browser/browser_policy_connector.h"
+#include "components/policy/core/common/cloud/cloud_policy_constants.h"
+#include "components/policy/core/common/mock_configuration_policy_provider.h"
+#include "components/policy/core/common/policy_switches.h"
+#include "components/policy/policy_constants.h"
+#include "components/session_manager/core/session_manager.h"
+#include "content/public/browser/browser_thread.h"
+#include "content/public/test/browser_test.h"
+#include "content/public/test/test_utils.h"
+#include "net/base/test_completion_callback.h"
+#include "net/cert/cert_verifier.h"
+#include "net/test/cert_test_util.h"
+#include "net/url_request/url_request_context.h"
+#include "net/url_request/url_request_context_getter.h"
+
+namespace em = enterprise_management;
+
+namespace {
+
+// Test data file storing an ONC blob with an Authority certificate.
+constexpr char kRootCertOnc[] = "root-ca-cert.onc";
+constexpr char kNetworkComponentDirectory[] = "network";
+// A PEM-encoded certificate which was signed by the Authority specified in
+// |kRootCertOnc|.
+constexpr char kGoodCert[] = "ok_cert.pem";
+constexpr char kDeviceLocalAccountId[] = "dla1@example.com";
+
+// Allows waiting until the list of policy-pushed web-trusted certificates
+// changes.
+class WebTrustedCertsChangedObserver
+ : public policy::UserNetworkConfigurationUpdater::WebTrustedCertsObserver {
+ public:
+ WebTrustedCertsChangedObserver() {}
+
+ // UserNetworkConfigurationUpdater:
+ void OnTrustAnchorsChanged(
+ const net::CertificateList& trust_anchors) override {
+ run_loop.QuitClosure().Run();
+ }
+
+ void Wait() { run_loop.Run(); }
+
+ private:
+ base::RunLoop run_loop;
+
+ DISALLOW_COPY_AND_ASSIGN(WebTrustedCertsChangedObserver);
+};
+
+// Called on the IO thread to verify the |test_server_cert| using the
+// CertVerifier from |request_context_getter|. The result will be written into
+// |verification_result|.
+void VerifyTestServerCertOnIOThread(
+ scoped_refptr<net::URLRequestContextGetter> request_context_getter,
+ scoped_refptr<net::X509Certificate> test_server_cert,
+ int* verification_result) {
+ net::CertVerifier* cert_verifier =
+ request_context_getter->GetURLRequestContext()->cert_verifier();
+
+ net::TestCompletionCallback test_callback;
+ net::CertVerifyResult verify_result;
+ std::unique_ptr<net::CertVerifier::Request> request;
+ // CertVerifier will offload work to a worker pool and post a task back to IO
+ // thread. We need to wait for that to happen. TestCompletionCallback performs
+ // a RunLoop when waiting for the notification to allow tasks to run. As this
+ // is effectively a _nested_ RunLoop, we need ScopedNestableTaskAllower to
+ // allow it.
+ base::MessageLoop::ScopedNestableTaskAllower allow_nested(
+ base::MessageLoop::current());
+ *verification_result = test_callback.GetResult(cert_verifier->Verify(
+ net::CertVerifier::RequestParams(test_server_cert.get(), "127.0.0.1", 0,
+ std::string(), net::CertificateList()),
+ nullptr, &verify_result, test_callback.callback(), &request,
+ net::NetLogWithSource()));
+}
+
+bool IsSessionStarted() {
+ return session_manager::SessionManager::Get()->IsSessionStarted();
+}
+
+} // namespace
+
+namespace policy {
+
+// Base class for testing if policy-provided trust roots take effect.
+class PolicyProvidedTrustRootsTestBase : public DevicePolicyCrosBrowserTest {
+ protected:
+ PolicyProvidedTrustRootsTestBase() {}
+
+ // InProcessBrowserTest:
+ ~PolicyProvidedTrustRootsTestBase() override {}
+
+ void SetUpInProcessBrowserTestFixture() override {
+ // Load the certificate which is only OK if the policy-provided authority is
+ // actually trusted.
+ base::FilePath cert_pem_file_path;
+ chromeos::test_utils::GetTestDataPath(kNetworkComponentDirectory, kGoodCert,
+ &cert_pem_file_path);
+ test_server_cert_ = net::ImportCertFromFile(
+ cert_pem_file_path.DirName(), cert_pem_file_path.BaseName().value());
+
+ // Set up the mock policy provider.
+ EXPECT_CALL(provider_, IsInitializationComplete(testing::_))
+ .WillRepeatedly(testing::Return(true));
+ BrowserPolicyConnector::SetPolicyProviderForTesting(&provider_);
+
+ DevicePolicyCrosBrowserTest::SetUpInProcessBrowserTestFixture();
+ }
+
+ void SetUpCommandLine(base::CommandLine* command_line) override {
+ DevicePolicyCrosBrowserTest::SetUpCommandLine(command_line);
+ }
+
+ // Sets the ONC-policy to the blob defined by |kRootCertOnc| and waits until
+ // the notification that policy-provided trust roots have changed is sent from
+ // |profile|'s UserNetworkConfigurationUpdater.
+ void SetRootCertONCPolicy(Profile* profile) {
+ policy::UserNetworkConfigurationUpdater*
+ user_network_configuration_updater =
+ policy::UserNetworkConfigurationUpdaterFactory::GetForProfile(
+ profile);
+ WebTrustedCertsChangedObserver trust_roots_changed_observer;
+ user_network_configuration_updater->AddTrustedCertsObserver(
+ &trust_roots_changed_observer);
+
+ const std::string& user_policy_blob =
+ chromeos::onc::test_utils::ReadTestData(kRootCertOnc);
+ policy::PolicyMap policy;
+ policy.Set(policy::key::kOpenNetworkConfiguration,
+ policy::POLICY_LEVEL_MANDATORY, policy::POLICY_SCOPE_USER,
+ policy::POLICY_SOURCE_CLOUD,
+ base::MakeUnique<base::Value>(user_policy_blob), nullptr);
+ provider_.UpdateChromePolicy(policy);
+ // Note that this relies on the implementation detail that the notification
+ // is sent even if the trust roots effectively remain the same.
+ trust_roots_changed_observer.Wait();
+ user_network_configuration_updater->RemoveTrustedCertsObserver(
+ &trust_roots_changed_observer);
+ }
+
+ // Verifies |test_server_cert_| with |profile|'s CertVerifier and returns the
+ // result.
+ int VerifyTestServerCert(Profile* profile) {
+ base::RunLoop().RunUntilIdle();
+ base::RunLoop run_loop;
+ int verification_result;
+ scoped_refptr<net::URLRequestContextGetter> url_request_context_getter =
+ profile->GetRequestContext();
+ content::BrowserThread::PostTaskAndReply(
+ content::BrowserThread::IO, FROM_HERE,
+ base::BindOnce(&VerifyTestServerCertOnIOThread,
+ url_request_context_getter, test_server_cert_,
+ &verification_result),
+ run_loop.QuitClosure());
+ run_loop.Run();
+ return verification_result;
+ }
+
+ private:
+ MockConfigurationPolicyProvider provider_;
+
+ protected:
+ // Certificate which is signed by authority specified in |kRootCertOnc|.
+ scoped_refptr<net::X509Certificate> test_server_cert_;
+};
+
+class PolicyProvidedTrustRootsRegularUserTest
+ : public PolicyProvidedTrustRootsTestBase {};
+
+IN_PROC_BROWSER_TEST_F(PolicyProvidedTrustRootsRegularUserTest,
+ AllowedForRegularUser) {
+ SetRootCertONCPolicy(browser()->profile());
+ EXPECT_EQ(net::OK, VerifyTestServerCert(browser()->profile()));
+}
+
+// Base class for testing policy-provided trust roots with device-local
+// accounts. Needs device policy.
+class PolicyProvidedTrustRootsDeviceLocalAccountTest
+ : public PolicyProvidedTrustRootsTestBase {
+ protected:
+ void SetUp() override {
+ // Configure and start the test server.
+ std::unique_ptr<crypto::RSAPrivateKey> signing_key(
+ PolicyBuilder::CreateTestSigningKey());
+ ASSERT_TRUE(policy_server_.SetSigningKeyAndSignature(
+ signing_key.get(), PolicyBuilder::GetTestSigningKeySignature()));
+ signing_key.reset();
+ policy_server_.RegisterClient(PolicyBuilder::kFakeToken,
+ PolicyBuilder::kFakeDeviceId);
+ ASSERT_TRUE(policy_server_.Start());
+
+ PolicyProvidedTrustRootsTestBase::SetUp();
+ }
+
+ virtual void SetupDevicePolicy() = 0;
+
+ void SetUpInProcessBrowserTestFixture() override {
+ PolicyProvidedTrustRootsTestBase::SetUpInProcessBrowserTestFixture();
+
+ InstallOwnerKey();
+ MarkAsEnterpriseOwned();
+
+ device_policy()->policy_data().set_public_key_version(1);
+ em::ChromeDeviceSettingsProto& proto(device_policy()->payload());
+ proto.mutable_show_user_names()->set_show_user_names(true);
+
+ SetupDevicePolicy();
+ }
+
+ void SetUpCommandLine(base::CommandLine* command_line) override {
+ PolicyProvidedTrustRootsTestBase::SetUpCommandLine(command_line);
+ command_line->AppendSwitch(chromeos::switches::kLoginManager);
+ command_line->AppendSwitch(chromeos::switches::kForceLoginManagerInTests);
+ command_line->AppendSwitchASCII(chromeos::switches::kLoginProfile, "user");
+ command_line->AppendSwitch(chromeos::switches::kOobeSkipPostLogin);
+ command_line->AppendSwitchASCII(policy::switches::kDeviceManagementUrl,
+ policy_server_.GetServiceURL().spec());
+ }
+
+ void WaitForSessionStart() {
+ if (IsSessionStarted())
+ return;
+ content::WindowedNotificationObserver(chrome::NOTIFICATION_SESSION_STARTED,
+ base::Bind(IsSessionStarted))
+ .Wait();
+ }
+
+ LocalPolicyTestServer policy_server_;
+
+ const AccountId device_local_account_id_ =
+ AccountId::FromUserEmail(GenerateDeviceLocalAccountUserId(
+ kDeviceLocalAccountId,
+ DeviceLocalAccount::TYPE_PUBLIC_SESSION));
+};
+
+// Sets up device policy for public session and provides functions to sing into
+// it.
+class PolicyProvidedTrustRootsPublicSessionTest
+ : public PolicyProvidedTrustRootsDeviceLocalAccountTest {
+ protected:
+ // PolicyProvidedTrustRootsDeviceLocalAccountTest:
+ void SetupDevicePolicy() override {
+ em::ChromeDeviceSettingsProto& proto(device_policy()->payload());
+ em::DeviceLocalAccountInfoProto* account =
+ proto.mutable_device_local_accounts()->add_account();
+ account->set_account_id(kDeviceLocalAccountId);
+ account->set_type(
+ em::DeviceLocalAccountInfoProto::ACCOUNT_TYPE_PUBLIC_SESSION);
+ RefreshDevicePolicy();
+ ASSERT_TRUE(
+ policy_server_.UpdatePolicy(dm_protocol::kChromeDevicePolicyType,
+ std::string(), proto.SerializeAsString()));
+ }
+
+ void StartLogin() {
+ chromeos::WizardController::SkipPostLoginScreensForTesting();
+ chromeos::WizardController* const wizard_controller =
+ chromeos::WizardController::default_controller();
+ ASSERT_TRUE(wizard_controller);
+ wizard_controller->SkipToLoginForTesting(chromeos::LoginScreenContext());
+
+ content::WindowedNotificationObserver(
+ chrome::NOTIFICATION_LOGIN_OR_LOCK_WEBUI_VISIBLE,
+ content::NotificationService::AllSources())
+ .Wait();
+
+ // Login into the public session.
+ chromeos::ExistingUserController* controller =
+ chromeos::ExistingUserController::current_controller();
+ ASSERT_TRUE(controller);
+ chromeos::UserContext user_context(user_manager::USER_TYPE_PUBLIC_ACCOUNT,
+ device_local_account_id_);
+ controller->Login(user_context, chromeos::SigninSpecifics());
+ }
+};
+
+IN_PROC_BROWSER_TEST_F(PolicyProvidedTrustRootsPublicSessionTest,
+ NotAllowedInPublicSession) {
+ StartLogin();
+ WaitForSessionStart();
+
+ BrowserList* browser_list = BrowserList::GetInstance();
+ EXPECT_EQ(1U, browser_list->size());
+ Browser* browser = browser_list->get(0);
+ ASSERT_TRUE(browser);
+
+ SetRootCertONCPolicy(browser->profile());
+ EXPECT_EQ(net::ERR_CERT_AUTHORITY_INVALID,
+ VerifyTestServerCert(browser->profile()));
+}
+
+} // namespace policy
« no previous file with comments | « chrome/browser/chromeos/policy/user_network_configuration_updater_factory.cc ('k') | chrome/test/BUILD.gn » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698