Index: chromeos/network/client_cert_resolver.cc |
diff --git a/chromeos/network/client_cert_resolver.cc b/chromeos/network/client_cert_resolver.cc |
index 788e5ee9a5ea503119ed1f308210ebad9cd9c0f8..74cb13651b79d685c32cc38f4e9ed287aa0dc216 100644 |
--- a/chromeos/network/client_cert_resolver.cc |
+++ b/chromeos/network/client_cert_resolver.cc |
@@ -13,6 +13,7 @@ |
#include "base/bind.h" |
#include "base/location.h" |
#include "base/logging.h" |
+#include "base/memory/ptr_util.h" |
#include "base/stl_util.h" |
#include "base/strings/string_util.h" |
#include "base/task_scheduler/post_task.h" |
@@ -191,25 +192,35 @@ std::vector<CertAndIssuer> CreateSortedCertAndIssuerList( |
// Searches for matches between |networks| and |certs| and writes matches to |
// |matches|. Because this calls NSS functions and is potentially slow, it must |
// be run on a worker thread. |
-void FindCertificateMatches(const net::CertificateList& certs, |
- std::vector<NetworkAndCertPattern>* networks, |
- base::Time now, |
- NetworkCertMatches* matches) { |
- std::vector<CertAndIssuer> client_certs( |
- CreateSortedCertAndIssuerList(certs, now)); |
+std::unique_ptr<NetworkCertMatches> FindCertificateMatches( |
+ const net::CertificateList& all_certs, |
+ const net::CertificateList& system_certs, |
+ std::vector<NetworkAndCertPattern>* networks, |
+ base::Time now) { |
+ std::unique_ptr<NetworkCertMatches> matches = |
+ base::MakeUnique<NetworkCertMatches>(); |
+ |
+ std::vector<CertAndIssuer> all_client_certs( |
+ CreateSortedCertAndIssuerList(all_certs, now)); |
+ std::vector<CertAndIssuer> system_client_certs( |
+ CreateSortedCertAndIssuerList(system_certs, now)); |
for (std::vector<NetworkAndCertPattern>::const_iterator it = |
networks->begin(); |
it != networks->end(); ++it) { |
- std::vector<CertAndIssuer>::iterator cert_it = |
- std::find_if(client_certs.begin(), |
- client_certs.end(), |
- MatchCertWithPattern(it->cert_config.pattern)); |
+ // Use only certs from the system token if the source of the client cert |
+ // pattern is device policy. |
+ std::vector<CertAndIssuer>* client_certs = |
+ it->cert_config.onc_source == ::onc::ONC_SOURCE_DEVICE_POLICY |
+ ? &system_client_certs |
+ : &all_client_certs; |
+ auto cert_it = std::find_if(client_certs->begin(), client_certs->end(), |
+ MatchCertWithPattern(it->cert_config.pattern)); |
std::string pkcs11_id; |
int slot_id = -1; |
std::string identity; |
- if (cert_it == client_certs.end()) { |
+ if (cert_it == client_certs->end()) { |
VLOG(1) << "Couldn't find a matching client cert for network " |
<< it->service_path; |
// Leave |pkcs11_id| empty to indicate that no cert was found for this |
@@ -256,6 +267,7 @@ void FindCertificateMatches(const net::CertificateList& certs, |
it->service_path, it->cert_config.location, pkcs11_id, slot_id, |
identity)); |
} |
+ return matches; |
} |
void LogError(const std::string& service_path, |
@@ -325,15 +337,23 @@ bool ClientCertResolver::IsAnyResolveTaskRunning() const { |
// static |
bool ClientCertResolver::ResolveCertificatePatternSync( |
const client_cert::ConfigType client_cert_type, |
- const CertificatePattern& pattern, |
+ const client_cert::ClientCertConfig& client_cert_config, |
base::DictionaryValue* shill_properties) { |
- // Prepare and sort the list of known client certs. |
- std::vector<CertAndIssuer> client_certs(CreateSortedCertAndIssuerList( |
- CertLoader::Get()->cert_list(), base::Time::Now())); |
+ // Prepare and sort the list of known client certs. Use only certs from the |
+ // system token if the source of the client cert pattern is device policy. |
+ std::vector<CertAndIssuer> client_certs; |
+ if (client_cert_config.onc_source == ::onc::ONC_SOURCE_DEVICE_POLICY) { |
+ client_certs = CreateSortedCertAndIssuerList( |
+ CertLoader::Get()->system_certs(), base::Time::Now()); |
+ } else { |
+ client_certs = CreateSortedCertAndIssuerList(CertLoader::Get()->all_certs(), |
+ base::Time::Now()); |
+ } |
// Search for a certificate matching the pattern. |
- std::vector<CertAndIssuer>::iterator cert_it = std::find_if( |
- client_certs.begin(), client_certs.end(), MatchCertWithPattern(pattern)); |
+ std::vector<CertAndIssuer>::iterator cert_it = |
+ std::find_if(client_certs.begin(), client_certs.end(), |
+ MatchCertWithPattern(client_cert_config.pattern)); |
if (cert_it == client_certs.end()) { |
VLOG(1) << "Couldn't find a matching client cert"; |
@@ -452,9 +472,10 @@ void ClientCertResolver::ResolveNetworks( |
if (network->profile_path().empty()) |
continue; |
+ onc::ONCSource onc_source = onc::ONC_SOURCE_NONE; |
const base::DictionaryValue* policy = |
managed_network_config_handler_->FindPolicyByGuidAndProfile( |
- network->guid(), network->profile_path()); |
+ network->guid(), network->profile_path(), &onc_source); |
if (!policy) { |
VLOG(1) << "The policy for network " << network->path() << " with GUID " |
@@ -466,7 +487,7 @@ void ClientCertResolver::ResolveNetworks( |
VLOG(2) << "Inspecting network " << network->path(); |
client_cert::ClientCertConfig cert_config; |
- OncToClientCertConfig(*policy, &cert_config); |
+ OncToClientCertConfig(onc_source, *policy, &cert_config); |
// Skip networks that don't have a ClientCertPattern. |
if (cert_config.client_cert_type != ::onc::client_cert::kPattern) |
@@ -493,16 +514,17 @@ void ClientCertResolver::ResolveNetworks( |
VLOG(2) << "Start task for resolving client cert patterns."; |
resolve_task_running_ = true; |
- NetworkCertMatches* matches = new NetworkCertMatches; |
- base::PostTaskWithTraitsAndReply( |
- FROM_HERE, base::TaskTraits() |
- .WithShutdownBehavior( |
- base::TaskShutdownBehavior::CONTINUE_ON_SHUTDOWN) |
- .MayBlock(), |
- base::Bind(&FindCertificateMatches, CertLoader::Get()->cert_list(), |
- base::Owned(networks_to_resolve.release()), Now(), matches), |
+ base::PostTaskWithTraitsAndReplyWithResult( |
+ FROM_HERE, |
+ base::TaskTraits() |
+ .WithShutdownBehavior( |
+ base::TaskShutdownBehavior::CONTINUE_ON_SHUTDOWN) |
+ .MayBlock(), |
+ base::Bind(&FindCertificateMatches, CertLoader::Get()->all_certs(), |
+ CertLoader::Get()->system_certs(), |
+ base::Owned(networks_to_resolve.release()), Now()), |
base::Bind(&ClientCertResolver::ConfigureCertificates, |
- weak_ptr_factory_.GetWeakPtr(), base::Owned(matches))); |
+ weak_ptr_factory_.GetWeakPtr())); |
} |
void ClientCertResolver::ResolvePendingNetworks() { |
@@ -523,7 +545,8 @@ void ClientCertResolver::ResolvePendingNetworks() { |
ResolveNetworks(networks_to_resolve); |
} |
-void ClientCertResolver::ConfigureCertificates(NetworkCertMatches* matches) { |
+void ClientCertResolver::ConfigureCertificates( |
+ std::unique_ptr<NetworkCertMatches> matches) { |
for (NetworkCertMatches::const_iterator it = matches->begin(); |
it != matches->end(); ++it) { |
VLOG(1) << "Configuring certificate of network " << it->service_path; |