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.
5 #include "chrome/browser/chromeos/policy/policy_cert_service.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"
18 PolicyCertService::~PolicyCertService() {
19 DCHECK(cert_verifier_
)
20 << "CreatePolicyCertVerifier() must be called after construction.";
23 PolicyCertService::PolicyCertService(
24 const std::string
& user_id
,
25 UserNetworkConfigurationUpdater
* net_conf_updater
,
26 user_manager::UserManager
* user_manager
)
27 : cert_verifier_(NULL
),
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_
);
37 PolicyCertService::PolicyCertService(const std::string
& user_id
,
38 PolicyCertVerifier
* verifier
,
39 user_manager::UserManager
* user_manager
)
40 : cert_verifier_(verifier
),
42 net_conf_updater_(NULL
),
43 user_manager_(user_manager
),
44 has_trust_anchors_(false),
45 weak_ptr_factory_(this) {
48 scoped_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
,
56 // Certs are forwarded to |cert_verifier_|, thus register here after
57 // |cert_verifier_| is created.
58 net_conf_updater_
->AddTrustedCertsObserver(this);
60 // Set the current list of trust anchors.
61 net::CertificateList trust_anchors
;
62 net_conf_updater_
->GetWebTrustedCertificates(&trust_anchors
);
63 OnTrustAnchorsChanged(trust_anchors
);
65 return make_scoped_ptr(cert_verifier_
);
68 void PolicyCertService::OnTrustAnchorsChanged(
69 const net::CertificateList
& trust_anchors
) {
70 DCHECK(cert_verifier_
);
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
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.";
82 has_trust_anchors_
= !trust_anchors
.empty();
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
,
92 base::Bind(&PolicyCertVerifier::SetTrustAnchors
,
93 base::Unretained(cert_verifier_
),
97 bool PolicyCertService::UsedPolicyCertificates() const {
98 return PolicyCertServiceFactory::UsedPolicyCertificates(user_id_
);
101 void 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
;
110 scoped_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
));
118 } // namespace policy