1 // Copyright 2019 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 "chromeos/components/sync_wifi/network_type_conversions.h"
6
7 #include "base/strings/string_number_conversions.h"
8 #include "chromeos/network/network_handler.h"
9 #include "chromeos/network/network_state.h"
10 #include "chromeos/network/network_state_handler.h"
11 #include "chromeos/services/network_config/public/mojom/cros_network_config.mojom.h"
12 #include "third_party/cros_system_api/dbus/shill/dbus-constants.h"
13
14 namespace chromeos {
15
16 namespace sync_wifi {
17
DecodeHexString(const std::string & base_16)18 std::string DecodeHexString(const std::string& base_16) {
19 std::string decoded;
20 DCHECK_EQ(base_16.size() % 2, 0u) << "Must be a multiple of 2";
21 decoded.reserve(base_16.size() / 2);
22
23 std::vector<uint8_t> v;
24 if (!base::HexStringToBytes(base_16, &v)) {
25 NOTREACHED();
26 }
27 decoded.assign(reinterpret_cast<const char*>(&v[0]), v.size());
28 return decoded;
29 }
30
SecurityTypeStringFromMojo(const network_config::mojom::SecurityType & security_type)31 std::string SecurityTypeStringFromMojo(
32 const network_config::mojom::SecurityType& security_type) {
33 switch (security_type) {
34 case network_config::mojom::SecurityType::kWpaPsk:
35 return shill::kSecurityPsk;
36 case network_config::mojom::SecurityType::kWepPsk:
37 return shill::kSecurityWep;
38 default:
39 // Only PSK and WEP secured networks are supported by sync.
40 return "";
41 }
42 }
43
SecurityTypeStringFromProto(const sync_pb::WifiConfigurationSpecifics_SecurityType & security_type)44 std::string SecurityTypeStringFromProto(
45 const sync_pb::WifiConfigurationSpecifics_SecurityType& security_type) {
46 switch (security_type) {
47 case sync_pb::WifiConfigurationSpecifics::SECURITY_TYPE_PSK:
48 return shill::kSecurityPsk;
49 case sync_pb::WifiConfigurationSpecifics::SECURITY_TYPE_WEP:
50 return shill::kSecurityWep;
51 default:
52 // Only PSK and WEP secured networks are supported by sync.
53 NOTREACHED();
54 return "";
55 }
56 }
57
SecurityTypeProtoFromMojo(const network_config::mojom::SecurityType & security_type)58 sync_pb::WifiConfigurationSpecifics_SecurityType SecurityTypeProtoFromMojo(
59 const network_config::mojom::SecurityType& security_type) {
60 switch (security_type) {
61 case network_config::mojom::SecurityType::kWpaPsk:
62 return sync_pb::WifiConfigurationSpecifics::SECURITY_TYPE_PSK;
63 case network_config::mojom::SecurityType::kWepPsk:
64 return sync_pb::WifiConfigurationSpecifics::SECURITY_TYPE_WEP;
65 default:
66 // Only PSK and WEP secured networks are supported by sync.
67 NOTREACHED();
68 return sync_pb::WifiConfigurationSpecifics::SECURITY_TYPE_NONE;
69 }
70 }
71
72 sync_pb::WifiConfigurationSpecifics_AutomaticallyConnectOption
AutomaticallyConnectProtoFromMojo(const network_config::mojom::ManagedBooleanPtr & auto_connect)73 AutomaticallyConnectProtoFromMojo(
74 const network_config::mojom::ManagedBooleanPtr& auto_connect) {
75 if (!auto_connect) {
76 return sync_pb::WifiConfigurationSpecifics::
77 AUTOMATICALLY_CONNECT_UNSPECIFIED;
78 }
79
80 if (auto_connect->active_value) {
81 return sync_pb::WifiConfigurationSpecifics::AUTOMATICALLY_CONNECT_ENABLED;
82 }
83
84 return sync_pb::WifiConfigurationSpecifics::AUTOMATICALLY_CONNECT_DISABLED;
85 }
86
IsPreferredProtoFromMojo(const network_config::mojom::ManagedInt32Ptr & is_preferred)87 sync_pb::WifiConfigurationSpecifics_IsPreferredOption IsPreferredProtoFromMojo(
88 const network_config::mojom::ManagedInt32Ptr& is_preferred) {
89 if (!is_preferred) {
90 return sync_pb::WifiConfigurationSpecifics::IS_PREFERRED_UNSPECIFIED;
91 }
92
93 if (is_preferred->active_value == 1) {
94 return sync_pb::WifiConfigurationSpecifics::IS_PREFERRED_ENABLED;
95 }
96
97 return sync_pb::WifiConfigurationSpecifics::IS_PREFERRED_DISABLED;
98 }
99
100 sync_pb::WifiConfigurationSpecifics_ProxyConfiguration_ProxyOption
ProxyOptionProtoFromMojo(const network_config::mojom::ManagedProxySettingsPtr & proxy_settings,bool is_unspecified)101 ProxyOptionProtoFromMojo(
102 const network_config::mojom::ManagedProxySettingsPtr& proxy_settings,
103 bool is_unspecified) {
104 if (!proxy_settings || is_unspecified) {
105 return sync_pb::WifiConfigurationSpecifics_ProxyConfiguration::
106 PROXY_OPTION_UNSPECIFIED;
107 }
108
109 if (proxy_settings->type->active_value == ::onc::proxy::kPAC) {
110 return sync_pb::WifiConfigurationSpecifics_ProxyConfiguration::
111 PROXY_OPTION_AUTOMATIC;
112 }
113
114 if (proxy_settings->type->active_value == ::onc::proxy::kWPAD) {
115 return sync_pb::WifiConfigurationSpecifics_ProxyConfiguration::
116 PROXY_OPTION_AUTODISCOVERY;
117 }
118
119 if (proxy_settings->type->active_value == ::onc::proxy::kManual) {
120 return sync_pb::WifiConfigurationSpecifics_ProxyConfiguration::
121 PROXY_OPTION_MANUAL;
122 }
123
124 return sync_pb::WifiConfigurationSpecifics_ProxyConfiguration::
125 PROXY_OPTION_DISABLED;
126 }
127
128 sync_pb::WifiConfigurationSpecifics_ProxyConfiguration
ProxyConfigurationProtoFromMojo(const network_config::mojom::ManagedProxySettingsPtr & proxy_settings,bool is_unspecified)129 ProxyConfigurationProtoFromMojo(
130 const network_config::mojom::ManagedProxySettingsPtr& proxy_settings,
131 bool is_unspecified) {
132 sync_pb::WifiConfigurationSpecifics_ProxyConfiguration proto;
133 proto.set_proxy_option(
134 ProxyOptionProtoFromMojo(proxy_settings, is_unspecified));
135
136 if (proto.proxy_option() ==
137 sync_pb::WifiConfigurationSpecifics_ProxyConfiguration::
138 PROXY_OPTION_AUTOMATIC) {
139 if (proxy_settings->pac) {
140 proto.set_autoconfiguration_url(proxy_settings->pac->active_value);
141 }
142 } else if (proto.proxy_option() ==
143 sync_pb::WifiConfigurationSpecifics_ProxyConfiguration::
144 PROXY_OPTION_MANUAL) {
145 sync_pb::
146 WifiConfigurationSpecifics_ProxyConfiguration_ManualProxyConfiguration*
147 manual_settings = proto.mutable_manual_proxy_configuration();
148
149 if (proxy_settings->manual->http_proxy) {
150 manual_settings->set_http_proxy_url(
151 proxy_settings->manual->http_proxy->host->active_value);
152 manual_settings->set_http_proxy_port(
153 proxy_settings->manual->http_proxy->port->active_value);
154 }
155
156 if (proxy_settings->manual->secure_http_proxy) {
157 manual_settings->set_secure_http_proxy_url(
158 proxy_settings->manual->secure_http_proxy->host->active_value);
159 manual_settings->set_secure_http_proxy_port(
160 proxy_settings->manual->secure_http_proxy->port->active_value);
161 }
162
163 if (proxy_settings->manual->socks) {
164 manual_settings->set_socks_host_url(
165 proxy_settings->manual->socks->host->active_value);
166 manual_settings->set_socks_host_port(
167 proxy_settings->manual->socks->port->active_value);
168 }
169
170 if (proxy_settings->exclude_domains) {
171 for (const std::string& domain :
172 proxy_settings->exclude_domains->active_value) {
173 manual_settings->add_excluded_domains(domain);
174 }
175 }
176 }
177
178 return proto;
179 }
180
MojoSecurityTypeFromProto(const sync_pb::WifiConfigurationSpecifics_SecurityType & security_type)181 network_config::mojom::SecurityType MojoSecurityTypeFromProto(
182 const sync_pb::WifiConfigurationSpecifics_SecurityType& security_type) {
183 switch (security_type) {
184 case sync_pb::WifiConfigurationSpecifics::SECURITY_TYPE_PSK:
185 return network_config::mojom::SecurityType::kWpaPsk;
186 case sync_pb::WifiConfigurationSpecifics::SECURITY_TYPE_WEP:
187 return network_config::mojom::SecurityType::kWepPsk;
188 default:
189 // Only PSK and WEP secured networks are supported by sync.
190 NOTREACHED();
191 return network_config::mojom::SecurityType::kNone;
192 }
193 }
194
MojoProxySettingsFromProto(const sync_pb::WifiConfigurationSpecifics_ProxyConfiguration & proxy_proto)195 network_config::mojom::ProxySettingsPtr MojoProxySettingsFromProto(
196 const sync_pb::WifiConfigurationSpecifics_ProxyConfiguration& proxy_proto) {
197 auto proxy_settings = network_config::mojom::ProxySettings::New();
198 switch (proxy_proto.proxy_option()) {
199 case sync_pb::WifiConfigurationSpecifics_ProxyConfiguration::
200 PROXY_OPTION_AUTOMATIC:
201 proxy_settings->type = ::onc::proxy::kPAC;
202 proxy_settings->pac = proxy_proto.autoconfiguration_url();
203 break;
204 case sync_pb::WifiConfigurationSpecifics_ProxyConfiguration::
205 PROXY_OPTION_AUTODISCOVERY:
206 proxy_settings->type = ::onc::proxy::kWPAD;
207 break;
208 case sync_pb::WifiConfigurationSpecifics_ProxyConfiguration::
209 PROXY_OPTION_MANUAL: {
210 auto manual_settings = network_config::mojom::ManualProxySettings::New();
211 auto synced_manual_configuration =
212 proxy_proto.manual_proxy_configuration();
213 proxy_settings->type = ::onc::proxy::kManual;
214
215 manual_settings->http_proxy = network_config::mojom::ProxyLocation::New();
216 manual_settings->http_proxy->host =
217 synced_manual_configuration.http_proxy_url();
218 manual_settings->http_proxy->port =
219 synced_manual_configuration.http_proxy_port();
220
221 manual_settings->secure_http_proxy =
222 network_config::mojom::ProxyLocation::New();
223 manual_settings->secure_http_proxy->host =
224 synced_manual_configuration.secure_http_proxy_url();
225 manual_settings->secure_http_proxy->port =
226 synced_manual_configuration.secure_http_proxy_port();
227
228 manual_settings->socks = network_config::mojom::ProxyLocation::New();
229 manual_settings->socks->host =
230 synced_manual_configuration.socks_host_url();
231 manual_settings->socks->port =
232 synced_manual_configuration.socks_host_port();
233
234 proxy_settings->manual = std::move(manual_settings);
235
236 std::vector<std::string> exclude_domains;
237 for (const std::string& domain :
238 synced_manual_configuration.excluded_domains()) {
239 exclude_domains.push_back(domain);
240 }
241 proxy_settings->exclude_domains = std::move(exclude_domains);
242 break;
243 }
244 case sync_pb::WifiConfigurationSpecifics_ProxyConfiguration::
245 PROXY_OPTION_DISABLED:
246 proxy_settings->type = ::onc::proxy::kDirect;
247 break;
248 case sync_pb::WifiConfigurationSpecifics_ProxyConfiguration::
249 PROXY_OPTION_UNSPECIFIED:
250 break;
251 }
252
253 return proxy_settings;
254 }
255
MojoNetworkConfigFromProto(const sync_pb::WifiConfigurationSpecifics & specifics)256 network_config::mojom::ConfigPropertiesPtr MojoNetworkConfigFromProto(
257 const sync_pb::WifiConfigurationSpecifics& specifics) {
258 auto config = network_config::mojom::ConfigProperties::New();
259 auto wifi = network_config::mojom::WiFiConfigProperties::New();
260
261 wifi->ssid = DecodeHexString(specifics.hex_ssid());
262 wifi->security = MojoSecurityTypeFromProto(specifics.security_type());
263 wifi->passphrase = specifics.passphrase();
264
265 config->type_config =
266 network_config::mojom::NetworkTypeConfigProperties::NewWifi(
267 std::move(wifi));
268
269 config->auto_connect = network_config::mojom::AutoConnectConfig::New(
270 specifics.automatically_connect() ==
271 sync_pb::WifiConfigurationSpecifics::AUTOMATICALLY_CONNECT_ENABLED);
272
273 config->priority = network_config::mojom::PriorityConfig::New(
274 specifics.is_preferred() ==
275 sync_pb::WifiConfigurationSpecifics::IS_PREFERRED_ENABLED
276 ? 1
277 : 0);
278
279 if (specifics.has_metered() &&
280 specifics.metered() !=
281 sync_pb::
282 WifiConfigurationSpecifics_MeteredOption_METERED_OPTION_UNSPECIFIED &&
283 specifics.metered() !=
284 sync_pb::
285 WifiConfigurationSpecifics_MeteredOption_METERED_OPTION_AUTO) {
286 config->metered = network_config::mojom::MeteredConfig::New(
287 specifics.metered() ==
288 sync_pb::WifiConfigurationSpecifics_MeteredOption_METERED_OPTION_YES);
289 }
290
291 // For backwards compatibility, any available custom nameservers are still
292 // applied when the dns_option is not set.
293 if (specifics.dns_option() ==
294 sync_pb::WifiConfigurationSpecifics_DnsOption_DNS_OPTION_CUSTOM ||
295 (specifics.dns_option() ==
296 sync_pb::
297 WifiConfigurationSpecifics_DnsOption_DNS_OPTION_UNSPECIFIED &&
298 specifics.custom_dns().size())) {
299 auto ip_config = network_config::mojom::IPConfigProperties::New();
300 std::vector<std::string> custom_dns;
301 for (const std::string& nameserver : specifics.custom_dns()) {
302 custom_dns.push_back(nameserver);
303 }
304 ip_config->name_servers = std::move(custom_dns);
305 config->static_ip_config = std::move(ip_config);
306 config->name_servers_config_type = onc::network_config::kIPConfigTypeStatic;
307 } else if (specifics.dns_option() ==
308 sync_pb::
309 WifiConfigurationSpecifics_DnsOption_DNS_OPTION_DEFAULT_DHCP) {
310 config->name_servers_config_type = onc::network_config::kIPConfigTypeDHCP;
311 }
312
313 if (specifics.has_proxy_configuration() &&
314 specifics.proxy_configuration().proxy_option() !=
315 sync_pb::WifiConfigurationSpecifics_ProxyConfiguration::
316 PROXY_OPTION_UNSPECIFIED) {
317 config->proxy_settings =
318 MojoProxySettingsFromProto(specifics.proxy_configuration());
319 }
320
321 return config;
322 }
323
NetworkStateFromNetworkIdentifier(const NetworkIdentifier & id)324 const NetworkState* NetworkStateFromNetworkIdentifier(
325 const NetworkIdentifier& id) {
326 NetworkStateHandler::NetworkStateList networks;
327 NetworkHandler::Get()->network_state_handler()->GetNetworkListByType(
328 NetworkTypePattern::WiFi(), /*configured_only=*/true,
329 /*visibleOnly=*/false, /*limit=*/0, &networks);
330 for (const NetworkState* network : networks) {
331 if (NetworkIdentifier::FromNetworkState(network) == id) {
332 return network;
333 }
334 }
335 return nullptr;
336 }
337
338 } // namespace sync_wifi
339
340 } // namespace chromeos
341