Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(24)

Side by Side Diff: chromeos/network/network_connection_handler.cc

Issue 14566009: Add NetworkConnectionHandler class (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Revert Associating Stub change for test Created 7 years, 7 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
(Empty)
1 // Copyright (c) 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 "chromeos/network/network_connection_handler.h"
6
7 #include "base/bind.h"
8 #include "base/json/json_reader.h"
9 #include "chromeos/dbus/dbus_thread_manager.h"
10 #include "chromeos/dbus/shill_manager_client.h"
11 #include "chromeos/dbus/shill_service_client.h"
12 #include "chromeos/network/cert_loader.h"
13 #include "chromeos/network/certificate_pattern_matcher.h"
14 #include "chromeos/network/managed_network_configuration_handler.h"
15 #include "chromeos/network/network_configuration_handler.h"
16 #include "chromeos/network/network_event_log.h"
17 #include "chromeos/network/network_handler_callbacks.h"
18 #include "chromeos/network/network_state.h"
19 #include "chromeos/network/network_state_handler.h"
20 #include "chromeos/network/network_ui_data.h"
21 #include "dbus/object_path.h"
22 #include "net/cert/x509_certificate.h"
23 #include "third_party/cros_system_api/dbus/service_constants.h"
24
25 namespace chromeos {
26
27 namespace {
28
29 const char kLogModule[] = "NetworkConnectionHandler";
30
31 void InvokeErrorCallback(
32 const std::string& service_path,
33 const network_handler::ErrorCallback& error_callback,
34 const std::string& error_name) {
35 network_handler::ShillErrorCallbackFunction(
36 kLogModule, service_path, error_callback, error_name, "Connect Error");
37 }
38
39 bool NetworkMayNeedCredentials(const NetworkState* network) {
40 if (network->type() == flimflam::kTypeWifi &&
41 (network->security() == flimflam::kSecurity8021x ||
42 network->security() == flimflam::kSecurityWep /* For dynamic WEP*/))
43 return true;
44 if (network->type() == flimflam::kTypeVPN)
45 return true;
46 return false;
47 }
48
49 bool NetworkRequiresActivation(const NetworkState* network) {
50 return (network->type() == flimflam::kTypeCellular &&
51 (network->activation_state() != flimflam::kActivationStateActivated ||
52 network->cellular_out_of_credits()));
53 }
54
55 bool VPNIsConfigured(const base::DictionaryValue& properties) {
56 std::string provider_type;
57 // Note: we use Value path expansion to extract Provider.Type.
58 properties.GetString(flimflam::kProviderTypeProperty, &provider_type);
59 if (provider_type == flimflam::kProviderOpenVpn) {
60 std::string hostname;
61 properties.GetString(flimflam::kProviderHostProperty, &hostname);
62 if (hostname.empty())
63 return false;
64 std::string username;
65 properties.GetStringWithoutPathExpansion(
66 flimflam::kOpenVPNUserProperty, &username);
67 if (username.empty())
68 return false;
69 std::string client_cert_id;
70 properties.GetStringWithoutPathExpansion(
71 flimflam::kOpenVPNClientCertIdProperty, &client_cert_id);
72 if (client_cert_id.empty())
73 return false;
74 } else {
75 bool passphrase_required = false;
76 std::string passphrase;
77 properties.GetBooleanWithoutPathExpansion(
78 flimflam::kL2tpIpsecPskRequiredProperty, &passphrase_required);
79 properties.GetStringWithoutPathExpansion(
80 flimflam::kL2tpIpsecPskProperty, &passphrase);
81 if (passphrase_required && passphrase.empty())
82 return false;
83 }
84 return true;
85 }
86
87 bool CertificateIsConfigured(NetworkUIData* ui_data) {
88 if (ui_data->certificate_type() != CLIENT_CERT_TYPE_PATTERN)
89 return true; // No certificate or a reference.
90 if (ui_data->onc_source() == onc::ONC_SOURCE_DEVICE_POLICY) {
91 // We skip checking certificate patterns for device policy ONC so that an
92 // unmanaged user can't get to the place where a cert is presented for them
93 // involuntarily.
94 return true;
95 }
96 if (ui_data->certificate_pattern().Empty())
97 return false;
98
99 // Find the matching certificate.
100 scoped_refptr<net::X509Certificate> matching_cert =
101 certificate_pattern::GetCertificateMatch(
102 ui_data->certificate_pattern());
103 if (!matching_cert.get())
104 return false;
105 return true;
106 }
107
108 } // namespace
109
110 static NetworkConnectionHandler* g_connection_handler_instance = NULL;
111
112 const char NetworkConnectionHandler::kErrorNotFound[] = "not-found";
113 const char NetworkConnectionHandler::kErrorConnected[] = "connected";
114 const char NetworkConnectionHandler::kErrorConnecting[] = "connecting";
115 const char NetworkConnectionHandler::kErrorNotConnected[] = "not-connected";
116 const char NetworkConnectionHandler::kErrorPassphraseRequired[] =
117 "passphrase-required";
118 const char NetworkConnectionHandler::kErrorActivationRequired[] =
119 "activation-required";
120 const char NetworkConnectionHandler::kErrorCertificateRequired[] =
121 "certificate-required";
122 const char NetworkConnectionHandler::kErrorConfigurationRequired[] =
123 "configuration-required";
124 const char NetworkConnectionHandler::kErrorShillError[] = "shill-error";
125
126 // static
127 void NetworkConnectionHandler::Initialize() {
128 CHECK(!g_connection_handler_instance);
129 g_connection_handler_instance = new NetworkConnectionHandler;
130 }
131
132 // static
133 void NetworkConnectionHandler::Shutdown() {
134 CHECK(g_connection_handler_instance);
135 delete g_connection_handler_instance;
136 g_connection_handler_instance = NULL;
137 }
138
139 // static
140 NetworkConnectionHandler* NetworkConnectionHandler::Get() {
141 CHECK(g_connection_handler_instance)
142 << "NetworkConnectionHandler::Get() called before Initialize()";
143 return g_connection_handler_instance;
144 }
145
146 NetworkConnectionHandler::NetworkConnectionHandler() {
147 }
148
149 NetworkConnectionHandler::~NetworkConnectionHandler() {
150 }
151
152 void NetworkConnectionHandler::ConnectToNetwork(
153 const std::string& service_path,
154 const base::Closure& success_callback,
155 const network_handler::ErrorCallback& error_callback) {
156 const NetworkState* network =
157 NetworkStateHandler::Get()->GetNetworkState(service_path);
158 if (!network) {
159 InvokeErrorCallback(service_path, error_callback, kErrorNotFound);
160 return;
161 }
162 if (network->IsConnectedState()) {
163 InvokeErrorCallback(service_path, error_callback, kErrorConnected);
164 return;
165 }
166 if (network->IsConnectingState() ||
167 pending_requests_.find(service_path) != pending_requests_.end()) {
168 InvokeErrorCallback(service_path, error_callback, kErrorConnecting);
169 return;
170 }
171 if (network->passphrase_required()) {
172 InvokeErrorCallback(service_path, error_callback, kErrorPassphraseRequired);
173 return;
174 }
175 if (NetworkRequiresActivation(network)) {
176 InvokeErrorCallback(service_path, error_callback, kErrorActivationRequired);
177 return;
178 }
179
180 // All synchronous checks passed, add |service_path| to connecting list.
181 pending_requests_.insert(service_path);
182
183 if (!network->connectable() && NetworkMayNeedCredentials(network)) {
184 // Request additional properties to check.
185 NetworkConfigurationHandler::Get()->GetProperties(
186 network->path(),
187 base::Bind(&NetworkConnectionHandler::VerifyConfiguredAndConnect,
188 AsWeakPtr(), success_callback, error_callback),
189 base::Bind(&NetworkConnectionHandler::HandleConfigurationFailure,
190 AsWeakPtr(), network->path(), error_callback));
191 return;
192 }
193 // All checks passed, send connect request.
194 CallShillConnect(service_path, success_callback, error_callback);
195 }
196
197 void NetworkConnectionHandler::DisconnectNetwork(
198 const std::string& service_path,
199 const base::Closure& success_callback,
200 const network_handler::ErrorCallback& error_callback) {
201 const NetworkState* network =
202 NetworkStateHandler::Get()->GetNetworkState(service_path);
203 if (!network) {
204 InvokeErrorCallback(service_path, error_callback, kErrorNotFound);
205 return;
206 }
207 if (!network->IsConnectedState()) {
208 InvokeErrorCallback(service_path, error_callback, kErrorNotConnected);
209 return;
210 }
211 CallShillDisconnect(service_path, success_callback, error_callback);
212 }
213
214 void NetworkConnectionHandler::CallShillConnect(
215 const std::string& service_path,
216 const base::Closure& success_callback,
217 const network_handler::ErrorCallback& error_callback) {
218 // TODO(stevenjb): Remove SetConnectingNetwork and use this class to maintain
219 // the connecting network(s) once NetworkLibrary path is eliminated.
220 NetworkStateHandler::Get()->SetConnectingNetwork(service_path);
221 network_event_log::AddEntry(kLogModule, "Connect Request", service_path);
222 DBusThreadManager::Get()->GetShillServiceClient()->Connect(
223 dbus::ObjectPath(service_path),
224 base::Bind(&NetworkConnectionHandler::HandleShillSuccess,
225 AsWeakPtr(), service_path, success_callback),
226 base::Bind(&NetworkConnectionHandler::HandleShillFailure,
227 AsWeakPtr(), service_path, error_callback));
228 }
229
230 void NetworkConnectionHandler::CallShillDisconnect(
231 const std::string& service_path,
232 const base::Closure& success_callback,
233 const network_handler::ErrorCallback& error_callback) {
234 network_event_log::AddEntry(kLogModule, "Disconnect Request", service_path);
235 DBusThreadManager::Get()->GetShillServiceClient()->Disconnect(
236 dbus::ObjectPath(service_path),
237 base::Bind(&NetworkConnectionHandler::HandleShillSuccess,
238 AsWeakPtr(), service_path, success_callback),
239 base::Bind(&NetworkConnectionHandler::HandleShillFailure,
240 AsWeakPtr(), service_path, error_callback));
241 }
242
243 void NetworkConnectionHandler::VerifyConfiguredAndConnect(
244 const base::Closure& success_callback,
245 const network_handler::ErrorCallback& error_callback,
246 const std::string& service_path,
247 const base::DictionaryValue& properties) {
248 const NetworkState* network =
249 NetworkStateHandler::Get()->GetNetworkState(service_path);
250 if (!network) {
251 InvokeErrorCallback(service_path, error_callback, kErrorNotFound);
252 return;
253 }
254
255 // VPN requires a host and username to be set.
256 if (network->type() == flimflam::kTypeVPN &&
257 !VPNIsConfigured(properties)) {
258 InvokeErrorCallback(service_path, error_callback,
259 kErrorConfigurationRequired);
260 return;
261 }
262
263 // Check certificate properties in kUIDataProperty.
264 scoped_ptr<NetworkUIData> ui_data =
265 ManagedNetworkConfigurationHandler::GetUIData(properties);
266 if (ui_data && !CertificateIsConfigured(ui_data.get())) {
267 InvokeErrorCallback(service_path, error_callback,
268 kErrorCertificateRequired);
269 return;
270 }
271
272 CallShillConnect(service_path, success_callback, error_callback);
273 }
274
275 void NetworkConnectionHandler::HandleConfigurationFailure(
276 const std::string& service_path,
277 const network_handler::ErrorCallback& error_callback,
278 const std::string& error_name,
279 scoped_ptr<base::DictionaryValue> error_data) {
280 pending_requests_.erase(service_path);
281 if (!error_callback.is_null())
282 error_callback.Run(error_name, error_data.Pass());
283 }
284
285 void NetworkConnectionHandler::HandleShillSuccess(
286 const std::string& service_path,
287 const base::Closure& success_callback) {
288 // TODO(stevenjb): Currently, this only indicates that the connect request
289 // succeeded. It might be preferable to wait for the actually connect
290 // attempt to succeed or fail here and only call |success_callback| at that
291 // point (or maybe call it twice, once indicating in-progress, then success
292 // or failure).
293 pending_requests_.erase(service_path);
294 network_event_log::AddEntry(kLogModule, "Connected", service_path);
295 success_callback.Run();
296 }
297
298 void NetworkConnectionHandler::HandleShillFailure(
299 const std::string& service_path,
300 const network_handler::ErrorCallback& error_callback,
301 const std::string& error_name,
302 const std::string& error_message) {
303 pending_requests_.erase(service_path);
304 std::string error = "Connect Failure: " + error_name + ": " + error_message;
305 network_handler::ShillErrorCallbackFunction(
306 kLogModule, service_path, error_callback, error_name, error_message);
307 }
308
309 } // namespace chromeos
OLDNEW
« no previous file with comments | « chromeos/network/network_connection_handler.h ('k') | chromeos/network/network_connection_handler_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698