1// Copyright 2013 The Chromium Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
5#include "chrome/browser/chromeos/policy/policy_cert_service.h"
6
7#include "base/bind.h"
8#include "base/bind_helpers.h"
9#include "base/logging.h"
10#include "chrome/browser/chromeos/policy/policy_cert_service_factory.h"
11#include "chrome/browser/chromeos/policy/policy_cert_verifier.h"
12#include "components/user_manager/user_manager.h"
13#include "content/public/browser/browser_thread.h"
14#include "net/cert/x509_certificate.h"
15
16namespace policy {
17
18PolicyCertService::~PolicyCertService() {
19  DCHECK(cert_verifier_)
20      << "CreatePolicyCertVerifier() must be called after construction.";
21}
22
23PolicyCertService::PolicyCertService(
24    const std::string& user_id,
25    UserNetworkConfigurationUpdater* net_conf_updater,
26    user_manager::UserManager* user_manager)
27    : cert_verifier_(NULL),
28      user_id_(user_id),
29      net_conf_updater_(net_conf_updater),
30      user_manager_(user_manager),
31      has_trust_anchors_(false),
32      weak_ptr_factory_(this) {
33  DCHECK(net_conf_updater_);
34  DCHECK(user_manager_);
35}
36
37PolicyCertService::PolicyCertService(const std::string& user_id,
38                                     PolicyCertVerifier* verifier,
39                                     user_manager::UserManager* user_manager)
40    : cert_verifier_(verifier),
41      user_id_(user_id),
42      net_conf_updater_(NULL),
43      user_manager_(user_manager),
44      has_trust_anchors_(false),
45      weak_ptr_factory_(this) {
46}
47
48scoped_ptr<PolicyCertVerifier> PolicyCertService::CreatePolicyCertVerifier() {
49  base::Closure callback = base::Bind(
50      &PolicyCertServiceFactory::SetUsedPolicyCertificates, user_id_);
51  cert_verifier_ = new PolicyCertVerifier(
52      base::Bind(base::IgnoreResult(&content::BrowserThread::PostTask),
53                 content::BrowserThread::UI,
54                 FROM_HERE,
55                 callback));
56  // Certs are forwarded to |cert_verifier_|, thus register here after
57  // |cert_verifier_| is created.
58  net_conf_updater_->AddTrustedCertsObserver(this);
59
60  // Set the current list of trust anchors.
61  net::CertificateList trust_anchors;
62  net_conf_updater_->GetWebTrustedCertificates(&trust_anchors);
63  OnTrustAnchorsChanged(trust_anchors);
64
65  return make_scoped_ptr(cert_verifier_);
66}
67
68void PolicyCertService::OnTrustAnchorsChanged(
69    const net::CertificateList& trust_anchors) {
70  DCHECK(cert_verifier_);
71
72  // Do not use certificates installed via ONC policy if the current session has
73  // multiple profiles. This is important to make sure that any possibly tainted
74  // data is absolutely confined to the managed profile and never, ever leaks to
75  // any other profile.
76  if (!trust_anchors.empty() && user_manager_->GetLoggedInUsers().size() > 1u) {
77    LOG(ERROR) << "Ignoring ONC-pushed certificates update because multiple "
78               << "users are logged in.";
79    return;
80  }
81
82  has_trust_anchors_ = !trust_anchors.empty();
83
84  // It's safe to use base::Unretained here, because it's guaranteed that
85  // |cert_verifier_| outlives this object (see description of
86  // CreatePolicyCertVerifier).
87  // Note: ProfileIOData, which owns the CertVerifier is deleted by a
88  // DeleteSoon on IO, i.e. after all pending tasks on IO are finished.
89  content::BrowserThread::PostTask(
90      content::BrowserThread::IO,
91      FROM_HERE,
92      base::Bind(&PolicyCertVerifier::SetTrustAnchors,
93                 base::Unretained(cert_verifier_),
94                 trust_anchors));
95}
96
97bool PolicyCertService::UsedPolicyCertificates() const {
98  return PolicyCertServiceFactory::UsedPolicyCertificates(user_id_);
99}
100
101void PolicyCertService::Shutdown() {
102  weak_ptr_factory_.InvalidateWeakPtrs();
103  if (net_conf_updater_)
104    net_conf_updater_->RemoveTrustedCertsObserver(this);
105  OnTrustAnchorsChanged(net::CertificateList());
106  net_conf_updater_ = NULL;
107}
108
109// static
110scoped_ptr<PolicyCertService> PolicyCertService::CreateForTesting(
111    const std::string& user_id,
112    PolicyCertVerifier* verifier,
113    user_manager::UserManager* user_manager) {
114  return make_scoped_ptr(
115      new PolicyCertService(user_id, verifier, user_manager));
116}
117
118}  // namespace policy
119