blob: 27400659cc794fc81275770358d547fd25db35d3 [file] [log] [blame]
Paul Stewart75897df2011-04-27 09:05:53 -07001// Copyright (c) 2011 The Chromium OS 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
Chris Masoneb2e326b2011-07-12 13:28:51 -07005#include "shill/service.h"
6
Paul Stewart75897df2011-04-27 09:05:53 -07007#include <time.h>
Paul Stewart75897df2011-04-27 09:05:53 -07008#include <stdio.h>
Chris Masoneee929b72011-05-10 10:02:18 -07009
Chris Masone8fe2c7e2011-06-09 15:51:19 -070010#include <map>
Paul Stewart75897df2011-04-27 09:05:53 -070011#include <string>
Chris Masone8fe2c7e2011-06-09 15:51:19 -070012#include <vector>
Paul Stewart75897df2011-04-27 09:05:53 -070013
Chris Masoneee929b72011-05-10 10:02:18 -070014#include <base/logging.h>
Chris Masone3bd3c8c2011-06-13 08:20:26 -070015#include <base/memory/scoped_ptr.h>
mukesh agrawal51a7e932011-07-27 16:18:26 -070016#include <base/string_number_conversions.h>
Chris Masone3bd3c8c2011-06-13 08:20:26 -070017#include <chromeos/dbus/service_constants.h>
Chris Masoneee929b72011-05-10 10:02:18 -070018
Paul Stewart75897df2011-04-27 09:05:53 -070019#include "shill/control_interface.h"
Chris Masone8fe2c7e2011-06-09 15:51:19 -070020#include "shill/error.h"
Chris Masone6791a432011-07-12 13:23:19 -070021#include "shill/manager.h"
Chris Masone7aa5f902011-07-11 11:13:35 -070022#include "shill/profile.h"
Chris Masone3bd3c8c2011-06-13 08:20:26 -070023#include "shill/property_accessor.h"
Chris Masone7aa5f902011-07-11 11:13:35 -070024#include "shill/refptr_types.h"
Chris Masoned7732e42011-05-20 11:08:56 -070025#include "shill/service_dbus_adaptor.h"
Darin Petkovba40dd32011-07-11 20:06:39 -070026#include "shill/store_interface.h"
Paul Stewart75897df2011-04-27 09:05:53 -070027
Chris Masone8fe2c7e2011-06-09 15:51:19 -070028using std::map;
Paul Stewart75897df2011-04-27 09:05:53 -070029using std::string;
Chris Masone8fe2c7e2011-06-09 15:51:19 -070030using std::vector;
Paul Stewart75897df2011-04-27 09:05:53 -070031
32namespace shill {
Darin Petkovba40dd32011-07-11 20:06:39 -070033
34const char Service::kCheckPortalAuto[] = "auto";
35const char Service::kCheckPortalFalse[] = "false";
36const char Service::kCheckPortalTrue[] = "true";
37
Paul Stewartac4ac002011-08-26 12:04:26 -070038const int Service::kPriorityNone = 0;
39
Darin Petkovba40dd32011-07-11 20:06:39 -070040const char Service::kStorageAutoConnect[] = "AutoConnect";
41const char Service::kStorageCheckPortal[] = "CheckPortal";
42const char Service::kStorageEapAnonymousIdentity[] = "EAP.AnonymousIdentity";
43const char Service::kStorageEapCACert[] = "EAP.CACert";
44const char Service::kStorageEapCACertID[] = "EAP.CACertID";
45const char Service::kStorageEapCertID[] = "EAP.CertID";
46const char Service::kStorageEapClientCert[] = "EAP.ClientCert";
47const char Service::kStorageEapEap[] = "EAP.EAP";
48const char Service::kStorageEapIdentity[] = "EAP.Identity";
49const char Service::kStorageEapInnerEap[] = "EAP.InnerEAP";
50const char Service::kStorageEapKeyID[] = "EAP.KeyID";
51const char Service::kStorageEapKeyManagement[] = "EAP.KeyMgmt";
52const char Service::kStorageEapPIN[] = "EAP.PIN";
53const char Service::kStorageEapPassword[] = "EAP.Password";
54const char Service::kStorageEapPrivateKey[] = "EAP.PrivateKey";
55const char Service::kStorageEapPrivateKeyPassword[] = "EAP.PrivateKeyPassword";
56const char Service::kStorageEapUseSystemCAs[] = "EAP.UseSystemCAs";
57const char Service::kStorageFavorite[] = "Favorite";
58const char Service::kStorageName[] = "Name";
59const char Service::kStoragePriority[] = "Priority";
60const char Service::kStorageProxyConfig[] = "ProxyConfig";
61const char Service::kStorageSaveCredentials[] = "SaveCredentials";
62
mukesh agrawal51a7e932011-07-27 16:18:26 -070063// static
64unsigned int Service::serial_number_ = 0;
65
Paul Stewart75897df2011-04-27 09:05:53 -070066Service::Service(ControlInterface *control_interface,
mukesh agrawalb54601c2011-06-07 17:39:22 -070067 EventDispatcher *dispatcher,
mukesh agrawal51a7e932011-07-27 16:18:26 -070068 Manager *manager)
Paul Stewart03dba0b2011-08-22 16:32:45 -070069 : state_(kStateUnknown),
70 failure_(kFailureUnknown),
71 auto_connect_(false),
Darin Petkovba40dd32011-07-11 20:06:39 -070072 check_portal_(kCheckPortalAuto),
Chris Masone3bd3c8c2011-06-13 08:20:26 -070073 connectable_(false),
74 favorite_(false),
Darin Petkovba40dd32011-07-11 20:06:39 -070075 priority_(kPriorityNone),
76 save_credentials_(true),
Chris Masone3bd3c8c2011-06-13 08:20:26 -070077 dispatcher_(dispatcher),
mukesh agrawal51a7e932011-07-27 16:18:26 -070078 name_(base::UintToString(serial_number_++)),
Chris Masonea82b7112011-05-25 15:16:29 -070079 available_(false),
80 configured_(false),
Chris Masonea82b7112011-05-25 15:16:29 -070081 configuration_(NULL),
82 connection_(NULL),
Chris Masone6791a432011-07-12 13:23:19 -070083 adaptor_(control_interface->CreateServiceAdaptor(this)),
84 manager_(manager) {
Chris Masone3bd3c8c2011-06-13 08:20:26 -070085
Chris Masone27c4aa52011-07-02 13:10:14 -070086 store_.RegisterBool(flimflam::kAutoConnectProperty, &auto_connect_);
Chris Masone4d42df82011-07-02 17:09:39 -070087
88 // flimflam::kActivationStateProperty: Registered in CellularService
89 // flimflam::kCellularApnProperty: Registered in CellularService
90 // flimflam::kCellularLastGoodApnProperty: Registered in CellularService
91 // flimflam::kNetworkTechnologyProperty: Registered in CellularService
Darin Petkov3335b372011-08-22 11:05:32 -070092 // flimflam::kOperatorNameProperty: DEPRECATED
93 // flimflam::kOperatorCodeProperty: DEPRECATED
Chris Masone4d42df82011-07-02 17:09:39 -070094 // flimflam::kRoamingStateProperty: Registered in CellularService
Darin Petkov3335b372011-08-22 11:05:32 -070095 // flimflam::kServingOperatorProperty: Registered in CellularService
Chris Masone4d42df82011-07-02 17:09:39 -070096 // flimflam::kPaymentURLProperty: Registered in CellularService
97
Chris Masone27c4aa52011-07-02 13:10:14 -070098 store_.RegisterString(flimflam::kCheckPortalProperty, &check_portal_);
99 store_.RegisterConstBool(flimflam::kConnectableProperty, &connectable_);
100 HelpRegisterDerivedString(flimflam::kDeviceProperty,
101 &Service::GetDeviceRpcId,
102 NULL);
Chris Masone3bd3c8c2011-06-13 08:20:26 -0700103
Chris Masoneb2e326b2011-07-12 13:28:51 -0700104 store_.RegisterString(flimflam::kEapIdentityProperty, &eap_.identity);
105 store_.RegisterString(flimflam::kEAPEAPProperty, &eap_.eap);
106 store_.RegisterString(flimflam::kEapPhase2AuthProperty, &eap_.inner_eap);
Chris Masone27c4aa52011-07-02 13:10:14 -0700107 store_.RegisterString(flimflam::kEapAnonymousIdentityProperty,
Chris Masoneb2e326b2011-07-12 13:28:51 -0700108 &eap_.anonymous_identity);
109 store_.RegisterString(flimflam::kEAPClientCertProperty, &eap_.client_cert);
110 store_.RegisterString(flimflam::kEAPCertIDProperty, &eap_.cert_id);
111 store_.RegisterString(flimflam::kEapPrivateKeyProperty, &eap_.private_key);
Chris Masone27c4aa52011-07-02 13:10:14 -0700112 store_.RegisterString(flimflam::kEapPrivateKeyPasswordProperty,
Chris Masoneb2e326b2011-07-12 13:28:51 -0700113 &eap_.private_key_password);
114 store_.RegisterString(flimflam::kEAPKeyIDProperty, &eap_.key_id);
115 store_.RegisterString(flimflam::kEapCaCertProperty, &eap_.ca_cert);
116 store_.RegisterString(flimflam::kEapCaCertIDProperty, &eap_.ca_cert_id);
117 store_.RegisterString(flimflam::kEAPPINProperty, &eap_.pin);
118 store_.RegisterString(flimflam::kEapPasswordProperty, &eap_.password);
119 store_.RegisterString(flimflam::kEapKeyMgmtProperty, &eap_.key_management);
120 store_.RegisterBool(flimflam::kEapUseSystemCAsProperty, &eap_.use_system_cas);
Chris Masone3bd3c8c2011-06-13 08:20:26 -0700121
Chris Masone27c4aa52011-07-02 13:10:14 -0700122 store_.RegisterConstString(flimflam::kErrorProperty, &error_);
123 store_.RegisterConstBool(flimflam::kFavoriteProperty, &favorite_);
124 HelpRegisterDerivedBool(flimflam::kIsActiveProperty,
Chris Masoneb2e326b2011-07-12 13:28:51 -0700125 &Service::IsActive,
126 NULL);
Chris Masone4d42df82011-07-02 17:09:39 -0700127 // flimflam::kModeProperty: Registered in WiFiService
Chris Masone27c4aa52011-07-02 13:10:14 -0700128 store_.RegisterConstString(flimflam::kNameProperty, &name_);
Chris Masone4d42df82011-07-02 17:09:39 -0700129 // flimflam::kPassphraseProperty: Registered in WiFiService
130 // flimflam::kPassphraseRequiredProperty: Registered in WiFiService
Chris Masone27c4aa52011-07-02 13:10:14 -0700131 store_.RegisterInt32(flimflam::kPriorityProperty, &priority_);
132 HelpRegisterDerivedString(flimflam::kProfileProperty,
133 &Service::GetProfileRpcId,
134 NULL);
Chris Masone4d42df82011-07-02 17:09:39 -0700135 store_.RegisterString(flimflam::kProxyConfigProperty, &proxy_config_);
Chris Masone43b48a12011-07-01 13:37:07 -0700136 // TODO(cmasone): Create VPN Service with this property
Chris Masone27c4aa52011-07-02 13:10:14 -0700137 // store_.RegisterConstStringmap(flimflam::kProviderProperty, &provider_);
Chris Masone4d42df82011-07-02 17:09:39 -0700138
Chris Masoneb2e326b2011-07-12 13:28:51 -0700139 store_.RegisterBool(flimflam::kSaveCredentialsProperty, &save_credentials_);
Chris Masone4d42df82011-07-02 17:09:39 -0700140 // flimflam::kSecurityProperty: Registered in WiFiService
Chris Masone27c4aa52011-07-02 13:10:14 -0700141 HelpRegisterDerivedString(flimflam::kStateProperty,
142 &Service::CalculateState,
143 NULL);
Chris Masone4d42df82011-07-02 17:09:39 -0700144 // flimflam::kSignalStrengthProperty: Registered in WiFi/CellularService
145 // flimflam::kTypeProperty: Registered in all derived classes.
146 // flimflam::kWifiAuthMode: Registered in WiFiService
147 // flimflam::kWifiHiddenSsid: Registered in WiFiService
148 // flimflam::kWifiFrequency: Registered in WiFiService
149 // flimflam::kWifiPhyMode: Registered in WiFiService
150 // flimflam::kWifiHexSsid: Registered in WiFiService
Chris Masoneb07006b2011-05-14 16:10:04 -0700151 VLOG(2) << "Service initialized.";
Paul Stewart75897df2011-04-27 09:05:53 -0700152}
153
Paul Stewartba41b992011-05-26 07:02:46 -0700154Service::~Service() {}
Paul Stewart75897df2011-04-27 09:05:53 -0700155
Darin Petkovb100ae72011-08-24 16:19:45 -0700156void Service::ActivateCellularModem(const std::string &carrier, Error *error) {
157 const string kMessage = "Service doesn't support cellular modem activation.";
158 LOG(ERROR) << kMessage;
159 CHECK(error);
160 error->Populate(Error::kInvalidArguments, kMessage);
Darin Petkovc408e692011-08-17 13:47:15 -0700161}
162
Paul Stewart03dba0b2011-08-22 16:32:45 -0700163bool Service::IsActive() {
164 return state_ != kStateUnknown &&
165 state_ != kStateIdle &&
166 state_ != kStateFailure;
167}
168
169void Service::SetState(ConnectState state) {
170 if (state == state_) {
171 return;
172 }
173
174 state_ = state;
175 if (state != kStateFailure) {
176 failure_ = kFailureUnknown;
177 }
178 manager_->UpdateService(this);
179 // TODO(pstew): Broadcast property change notification via control interface
180}
181
182void Service::SetFailure(ConnectFailure failure) {
183 failure_ = failure;
184 SetState(kStateFailure);
185}
186
Chris Masone6791a432011-07-12 13:23:19 -0700187string Service::GetRpcIdentifier() const {
Chris Masone3c3f6a12011-07-01 10:01:41 -0700188 return adaptor_->GetRpcIdentifier();
189}
190
Chris Masone34af2182011-08-22 11:59:36 -0700191bool Service::Load(StoreInterface *storage, const string &id_suffix) {
192 const string id = GetStorageIdentifier(id_suffix);
193 if (!storage->ContainsGroup(id)) {
194 LOG(WARNING) << "Service is not available in the persistent store: " << id;
195 return false;
196 }
197 storage->GetBool(id, kStorageAutoConnect, &auto_connect_);
198 storage->GetString(id, kStorageCheckPortal, &check_portal_);
199 storage->GetBool(id, kStorageFavorite, &favorite_);
200 storage->GetInt(id, kStoragePriority, &priority_);
201 storage->GetString(id, kStorageProxyConfig, &proxy_config_);
202 storage->GetBool(id, kStorageSaveCredentials, &save_credentials_);
203
204 LoadEapCredentials(storage, id);
205
206 // TODO(petkov): Load these:
207
208 // "Name"
209 // "WiFi.HiddenSSID"
210 // "SSID"
211 // "Failure"
212 // "Modified"
213 // "LastAttempt"
214 // WiFiService: "Passphrase"
215 // "APN"
216 // "LastGoodAPN"
217
218 return true;
Darin Petkovba40dd32011-07-11 20:06:39 -0700219}
220
Chris Masone34af2182011-08-22 11:59:36 -0700221bool Service::Save(StoreInterface *storage, const string &id_suffix) {
222 const string id = GetStorageIdentifier(id_suffix);
223
224 // TODO(petkov): We could choose to simplify the saving code by removing most
225 // conditionals thus saving even default values.
226 if (favorite_) {
227 storage->SetBool(id, kStorageAutoConnect, auto_connect_);
228 }
229 if (check_portal_ == kCheckPortalAuto) {
230 storage->DeleteKey(id, kStorageCheckPortal);
231 } else {
232 storage->SetString(id, kStorageCheckPortal, check_portal_);
233 }
234 storage->SetBool(id, kStorageFavorite, favorite_);
235 storage->SetString(id, kStorageName, name_);
236 SaveString(storage, id, kStorageProxyConfig, proxy_config_, false, true);
237 if (priority_ != kPriorityNone) {
238 storage->SetInt(id, kStoragePriority, priority_);
239 } else {
240 storage->DeleteKey(id, kStoragePriority);
241 }
242 if (save_credentials_) {
243 storage->DeleteKey(id, kStorageSaveCredentials);
244 } else {
245 storage->SetBool(id, kStorageSaveCredentials, false);
246 }
247
248 SaveEapCredentials(storage, id);
249
250 // TODO(petkov): Save these:
251
252 // "WiFi.HiddenSSID"
253 // "SSID"
254 // "Failure"
255 // "Modified"
256 // "LastAttempt"
257 // WiFiService: "Passphrase"
258 // "APN"
259 // "LastGoodAPN"
260
261 return true;
262}
263
264const ProfileRefPtr &Service::profile() const { return profile_; }
265
266void Service::set_profile(const ProfileRefPtr &p) { profile_ = p; }
267
Chris Masone27c4aa52011-07-02 13:10:14 -0700268void Service::HelpRegisterDerivedBool(const string &name,
Chris Masone34af2182011-08-22 11:59:36 -0700269 bool(Service::*get)(void),
270 bool(Service::*set)(const bool&)) {
Chris Masone27c4aa52011-07-02 13:10:14 -0700271 store_.RegisterDerivedBool(
272 name,
273 BoolAccessor(new CustomAccessor<Service, bool>(this, get, set)));
Chris Masone3bd3c8c2011-06-13 08:20:26 -0700274}
275
Chris Masone27c4aa52011-07-02 13:10:14 -0700276void Service::HelpRegisterDerivedString(const string &name,
Chris Masone34af2182011-08-22 11:59:36 -0700277 string(Service::*get)(void),
278 bool(Service::*set)(const string&)) {
Chris Masone27c4aa52011-07-02 13:10:14 -0700279 store_.RegisterDerivedString(
280 name,
281 StringAccessor(new CustomAccessor<Service, string>(this, get, set)));
Chris Masone3bd3c8c2011-06-13 08:20:26 -0700282}
283
Darin Petkovba40dd32011-07-11 20:06:39 -0700284void Service::SaveString(StoreInterface *storage,
Chris Masone34af2182011-08-22 11:59:36 -0700285 const string &id,
Darin Petkovba40dd32011-07-11 20:06:39 -0700286 const string &key,
287 const string &value,
288 bool crypted,
289 bool save) {
290 if (value.empty() || !save) {
Chris Masone34af2182011-08-22 11:59:36 -0700291 storage->DeleteKey(id, key);
Darin Petkovba40dd32011-07-11 20:06:39 -0700292 return;
293 }
294 if (crypted) {
Chris Masone34af2182011-08-22 11:59:36 -0700295 storage->SetCryptedString(id, key, value);
Darin Petkovba40dd32011-07-11 20:06:39 -0700296 return;
297 }
Chris Masone34af2182011-08-22 11:59:36 -0700298 storage->SetString(id, key, value);
Darin Petkovba40dd32011-07-11 20:06:39 -0700299}
300
Chris Masone34af2182011-08-22 11:59:36 -0700301void Service::LoadEapCredentials(StoreInterface *storage, const string &id) {
Darin Petkovba40dd32011-07-11 20:06:39 -0700302 storage->GetCryptedString(id, kStorageEapIdentity, &eap_.identity);
303 storage->GetString(id, kStorageEapEap, &eap_.eap);
304 storage->GetString(id, kStorageEapInnerEap, &eap_.inner_eap);
305 storage->GetCryptedString(id,
306 kStorageEapAnonymousIdentity,
307 &eap_.anonymous_identity);
308 storage->GetString(id, kStorageEapClientCert, &eap_.client_cert);
309 storage->GetString(id, kStorageEapCertID, &eap_.cert_id);
310 storage->GetString(id, kStorageEapPrivateKey, &eap_.private_key);
311 storage->GetCryptedString(id,
312 kStorageEapPrivateKeyPassword,
313 &eap_.private_key_password);
314 storage->GetString(id, kStorageEapKeyID, &eap_.key_id);
315 storage->GetString(id, kStorageEapCACert, &eap_.ca_cert);
316 storage->GetString(id, kStorageEapCACertID, &eap_.ca_cert_id);
317 storage->GetBool(id, kStorageEapUseSystemCAs, &eap_.use_system_cas);
318 storage->GetString(id, kStorageEapPIN, &eap_.pin);
319 storage->GetCryptedString(id, kStorageEapPassword, &eap_.password);
320 storage->GetString(id, kStorageEapKeyManagement, &eap_.key_management);
321}
322
Chris Masone34af2182011-08-22 11:59:36 -0700323void Service::SaveEapCredentials(StoreInterface *storage, const string &id) {
Darin Petkovba40dd32011-07-11 20:06:39 -0700324 bool save = save_credentials_;
Chris Masone34af2182011-08-22 11:59:36 -0700325 SaveString(storage, id, kStorageEapIdentity, eap_.identity, true, save);
326 SaveString(storage, id, kStorageEapEap, eap_.eap, false, true);
327 SaveString(storage, id, kStorageEapInnerEap, eap_.inner_eap, false, true);
Darin Petkovba40dd32011-07-11 20:06:39 -0700328 SaveString(storage,
Chris Masone34af2182011-08-22 11:59:36 -0700329 id,
Darin Petkovba40dd32011-07-11 20:06:39 -0700330 kStorageEapAnonymousIdentity,
331 eap_.anonymous_identity,
332 true,
333 save);
Chris Masone34af2182011-08-22 11:59:36 -0700334 SaveString(storage, id, kStorageEapClientCert, eap_.client_cert, false, save);
335 SaveString(storage, id, kStorageEapCertID, eap_.cert_id, false, save);
336 SaveString(storage, id, kStorageEapPrivateKey, eap_.private_key, false, save);
Darin Petkovba40dd32011-07-11 20:06:39 -0700337 SaveString(storage,
Chris Masone34af2182011-08-22 11:59:36 -0700338 id,
Darin Petkovba40dd32011-07-11 20:06:39 -0700339 kStorageEapPrivateKeyPassword,
340 eap_.private_key_password,
341 true,
342 save);
Chris Masone34af2182011-08-22 11:59:36 -0700343 SaveString(storage, id, kStorageEapKeyID, eap_.key_id, false, save);
344 SaveString(storage, id, kStorageEapCACert, eap_.ca_cert, false, true);
345 SaveString(storage, id, kStorageEapCACertID, eap_.ca_cert_id, false, true);
346 storage->SetBool(id, kStorageEapUseSystemCAs, eap_.use_system_cas);
347 SaveString(storage, id, kStorageEapPIN, eap_.pin, false, save);
348 SaveString(storage, id, kStorageEapPassword, eap_.password, true, save);
Darin Petkovba40dd32011-07-11 20:06:39 -0700349 SaveString(storage,
Chris Masone34af2182011-08-22 11:59:36 -0700350 id,
Darin Petkovba40dd32011-07-11 20:06:39 -0700351 kStorageEapKeyManagement,
352 eap_.key_management,
353 false,
354 true);
355}
356
Paul Stewartac4ac002011-08-26 12:04:26 -0700357const string &Service::GetEAPKeyManagement() const {
358 return eap_.key_management;
359}
360
361void Service::SetEAPKeyManagement(const string &key_management) {
362 eap_.key_management = key_management;
363}
364
Paul Stewart75897df2011-04-27 09:05:53 -0700365} // namespace shill