1 // Copyright 2020 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/ui/webui/chromeos/onc_import_message_handler.h"
6
7 #include "base/bind.h"
8 #include "base/callback_helpers.h"
9 #include "base/strings/stringprintf.h"
10 #include "base/values.h"
11 #include "chrome/browser/chromeos/profiles/profile_helper.h"
12 #include "chrome/browser/net/nss_context.h"
13 #include "chrome/browser/profiles/profile.h"
14 #include "chromeos/network/onc/onc_certificate_importer_impl.h"
15 #include "chromeos/network/onc/onc_parsed_certificates.h"
16 #include "chromeos/network/onc/onc_utils.h"
17 #include "components/onc/onc_constants.h"
18 #include "components/policy/core/browser/policy_conversions.h"
19 #include "content/public/browser/browser_task_traits.h"
20 #include "content/public/browser/browser_thread.h"
21
22 namespace chromeos {
23
24 OncImportMessageHandler::OncImportMessageHandler() = default;
25
26 OncImportMessageHandler::~OncImportMessageHandler() = default;
27
RegisterMessages()28 void OncImportMessageHandler::RegisterMessages() {
29 web_ui()->RegisterMessageCallback(
30 "importONC", base::BindRepeating(&OncImportMessageHandler::OnImportONC,
31 base::Unretained(this)));
32 }
33
Respond(const std::string & callback_id,const std::string & result,bool is_error)34 void OncImportMessageHandler::Respond(const std::string& callback_id,
35 const std::string& result,
36 bool is_error) {
37 base::Value response(base::Value::Type::LIST);
38 response.Append(result);
39 response.Append(is_error);
40 ResolveJavascriptCallback(base::Value(callback_id), response);
41 }
42
OnImportONC(const base::ListValue * list)43 void OncImportMessageHandler::OnImportONC(const base::ListValue* list) {
44 CHECK_EQ(2u, list->GetSize());
45 std::string callback_id, onc_blob;
46 CHECK(list->GetString(0, &callback_id));
47 CHECK(list->GetString(1, &onc_blob));
48 AllowJavascript();
49 GetNSSCertDatabaseForProfile(
50 Profile::FromWebUI(web_ui()),
51 base::BindOnce(&OncImportMessageHandler::ImportONCToNSSDB,
52 weak_factory_.GetWeakPtr(), callback_id, onc_blob));
53 }
54
ImportONCToNSSDB(const std::string & callback_id,const std::string & onc_blob,net::NSSCertDatabase * nssdb)55 void OncImportMessageHandler::ImportONCToNSSDB(const std::string& callback_id,
56 const std::string& onc_blob,
57 net::NSSCertDatabase* nssdb) {
58 const user_manager::User* user =
59 ProfileHelper::Get()->GetUserByProfile(Profile::FromWebUI(web_ui()));
60 if (!user) {
61 Respond(callback_id, "User not found.", /*is_error=*/true);
62 return;
63 }
64
65 std::string result;
66 bool has_error = false;
67
68 ::onc::ONCSource onc_source = ::onc::ONC_SOURCE_USER_IMPORT;
69 base::ListValue network_configs;
70 base::DictionaryValue global_network_config;
71 base::ListValue certificates;
72 if (!onc::ParseAndValidateOncForImport(
73 onc_blob, onc_source, /*passphrase=*/std::string(), &network_configs,
74 &global_network_config, &certificates)) {
75 has_error = true;
76 result += "Errors occurred during ONC parsing.\n";
77 }
78
79 std::string import_error;
80 int num_networks_imported =
81 onc::ImportNetworksForUser(user, network_configs, &import_error);
82 if (!import_error.empty()) {
83 has_error = true;
84 result += "Error importing networks: " + import_error + "\n";
85 }
86 result +=
87 base::StringPrintf("Networks imported: %d\n", num_networks_imported);
88 if (certificates.GetList().empty()) {
89 if (!num_networks_imported)
90 has_error = true;
91 Respond(callback_id, result, has_error);
92 return;
93 }
94
95 auto cert_importer = std::make_unique<onc::CertificateImporterImpl>(
96 content::GetIOThreadTaskRunner({}), nssdb);
97 auto certs = std::make_unique<onc::OncParsedCertificates>(certificates);
98 if (certs->has_error()) {
99 has_error = true;
100 result += "Some certificates could not be parsed.\n";
101 }
102 cert_importer->ImportAllCertificatesUserInitiated(
103 certs->server_or_authority_certificates(), certs->client_certificates(),
104 base::BindOnce(&OncImportMessageHandler::OnCertificatesImported,
105 weak_factory_.GetWeakPtr(), std::move(cert_importer),
106 callback_id, result, has_error));
107 }
108
OnCertificatesImported(std::unique_ptr<onc::CertificateImporterImpl> cert_importer,const std::string & callback_id,const std::string & previous_result,bool has_error,bool cert_import_success)109 void OncImportMessageHandler::OnCertificatesImported(
110 std::unique_ptr<onc::CertificateImporterImpl> cert_importer,
111 const std::string& callback_id,
112 const std::string& previous_result,
113 bool has_error,
114 bool cert_import_success) {
115 std::string result = previous_result;
116 if (!cert_import_success) {
117 has_error = true;
118 result += "Some certificates couldn't be imported.\n";
119 }
120 Respond(callback_id, result, has_error);
121 // |cert_importer| will be destroyed when the callback exits.
122 }
123
124 } // namespace chromeos
125