• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 //
2 // Copyright (C) 2012 The Android Open Source Project
3 //
4 // Licensed under the Apache License, Version 2.0 (the "License");
5 // you may not use this file except in compliance with the License.
6 // You may obtain a copy of the License at
7 //
8 //      http://www.apache.org/licenses/LICENSE-2.0
9 //
10 // Unless required by applicable law or agreed to in writing, software
11 // distributed under the License is distributed on an "AS IS" BASIS,
12 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 // See the License for the specific language governing permissions and
14 // limitations under the License.
15 //
16 
17 #include "shill/manager.h"
18 
19 #include <stdio.h>
20 #include <time.h>
21 
22 #include <algorithm>
23 #include <set>
24 #include <string>
25 #include <vector>
26 
27 #include <base/bind.h>
28 #include <base/callback.h>
29 #include <base/files/file_util.h>
30 #include <base/memory/ref_counted.h>
31 #include <base/strings/pattern.h>
32 #include <base/strings/stringprintf.h>
33 #include <base/strings/string_split.h>
34 #include <base/strings/string_util.h>
35 #if defined(__ANDROID__)
36 #include <dbus/service_constants.h>
37 #else
38 #include <chromeos/dbus/service_constants.h>
39 #endif  // __ANDROID__
40 
41 #include "shill/adaptor_interfaces.h"
42 #include "shill/callbacks.h"
43 #include "shill/connection.h"
44 #include "shill/control_interface.h"
45 #include "shill/default_profile.h"
46 #include "shill/device.h"
47 #include "shill/device_claimer.h"
48 #include "shill/device_info.h"
49 #include "shill/ephemeral_profile.h"
50 #include "shill/error.h"
51 #include "shill/ethernet/ethernet_temporary_service.h"
52 #include "shill/event_dispatcher.h"
53 #include "shill/geolocation_info.h"
54 #include "shill/hook_table.h"
55 #include "shill/ip_address_store.h"
56 #include "shill/logging.h"
57 #include "shill/profile.h"
58 #include "shill/property_accessor.h"
59 #include "shill/resolver.h"
60 #include "shill/result_aggregator.h"
61 #include "shill/service.h"
62 #include "shill/service_sorter.h"
63 #include "shill/store_factory.h"
64 #include "shill/vpn/vpn_provider.h"
65 #include "shill/vpn/vpn_service.h"
66 #include "shill/wimax/wimax_service.h"
67 
68 #if defined(__BRILLO__)
69 #include "shill/wifi/wifi_driver_hal.h"
70 #endif  // __BRILLO__
71 
72 #if !defined(DISABLE_WIFI)
73 #include "shill/wifi/wifi.h"
74 #include "shill/wifi/wifi_provider.h"
75 #include "shill/wifi/wifi_service.h"
76 #endif  // DISABLE_WIFI
77 
78 #if !defined(DISABLE_WIRED_8021X)
79 #include "shill/ethernet/ethernet_eap_provider.h"
80 #include "shill/ethernet/ethernet_eap_service.h"
81 #endif  // DISABLE_WIRED_8021X
82 
83 using base::Bind;
84 using base::Callback;
85 using base::FilePath;
86 using base::StringPrintf;
87 using base::Unretained;
88 using std::map;
89 using std::set;
90 using std::string;
91 using std::vector;
92 
93 namespace shill {
94 
95 namespace Logging {
96 static auto kModuleLogScope = ScopeLogger::kManager;
ObjectID(const Manager * m)97 static string ObjectID(const Manager* m) { return "manager"; }
98 }
99 
100 
101 // statics
102 const char Manager::kErrorNoDevice[] = "no wifi devices available";
103 const char Manager::kErrorTypeRequired[] = "must specify service type";
104 const char Manager::kErrorUnsupportedServiceType[] =
105     "service type is unsupported";
106 // This timeout should be less than the upstart job timeout, otherwise
107 // stats for termination actions might be lost.
108 const int Manager::kTerminationActionsTimeoutMilliseconds = 19500;
109 
110 // Device status check interval (every 3 minutes).
111 const int Manager::kDeviceStatusCheckIntervalMilliseconds = 180000;
112 
113 // static
114 const char* Manager::kProbeTechnologies[] = {
115     kTypeEthernet,
116     kTypeWifi,
117     kTypeWimax,
118     kTypeCellular
119 };
120 
121 // static
122 const char Manager::kDefaultClaimerName[] = "";
123 
Manager(ControlInterface * control_interface,EventDispatcher * dispatcher,Metrics * metrics,const string & run_directory,const string & storage_directory,const string & user_storage_directory)124 Manager::Manager(ControlInterface* control_interface,
125                  EventDispatcher* dispatcher,
126                  Metrics* metrics,
127                  const string& run_directory,
128                  const string& storage_directory,
129                  const string& user_storage_directory)
130     : dispatcher_(dispatcher),
131       run_path_(FilePath(run_directory)),
132       storage_path_(FilePath(storage_directory)),
133       user_storage_path_(user_storage_directory),
134       user_profile_list_path_(FilePath(Profile::kUserProfileListPathname)),
135       adaptor_(control_interface->CreateManagerAdaptor(this)),
136       device_info_(control_interface, dispatcher, metrics, this),
137 #if !defined(DISABLE_CELLULAR)
138       modem_info_(control_interface, dispatcher, metrics, this),
139 #endif  // DISABLE_CELLULAR
140 #if !defined(DISABLE_WIRED_8021X)
141       ethernet_eap_provider_(
142           new EthernetEapProvider(
143               control_interface, dispatcher, metrics, this)),
144 #endif  // DISABLE_WIRED_8021X
145       vpn_provider_(
146           new VPNProvider(control_interface, dispatcher, metrics, this)),
147 #if !defined(DISABLE_WIFI)
148       wifi_provider_(
149           new WiFiProvider(control_interface, dispatcher, metrics, this)),
150 #if defined(__BRILLO__)
151       wifi_driver_hal_(WiFiDriverHal::GetInstance()),
152 #endif  // __BRILLO__
153 #endif  // DISABLE_WIFI
154 #if !defined(DISABLE_WIMAX)
155       wimax_provider_(
156           new WiMaxProvider(control_interface, dispatcher, metrics, this)),
157 #endif  // DISABLE_WIMAX
158       resolver_(Resolver::GetInstance()),
159       running_(false),
160       connect_profiles_to_rpc_(true),
161       ephemeral_profile_(
162           new EphemeralProfile(control_interface, metrics, this)),
163       control_interface_(control_interface),
164       metrics_(metrics),
165       use_startup_portal_list_(false),
166       device_status_check_task_(Bind(&Manager::DeviceStatusCheckTask,
167                                      base::Unretained(this))),
168       termination_actions_(dispatcher),
169       suspend_delay_registered_(false),
170       is_wake_on_lan_enabled_(true),
171       ignore_unknown_ethernet_(false),
172       default_service_callback_tag_(0),
173       crypto_util_proxy_(new CryptoUtilProxy(dispatcher)),
174       health_checker_remote_ips_(new IPAddressStore()),
175       suppress_autoconnect_(false),
176       is_connected_state_(false),
177       dhcp_properties_(new DhcpProperties()) {
178   HelpRegisterDerivedString(kActiveProfileProperty,
179                             &Manager::GetActiveProfileRpcIdentifier,
180                             nullptr);
181   store_.RegisterBool(kArpGatewayProperty, &props_.arp_gateway);
182   HelpRegisterConstDerivedStrings(kAvailableTechnologiesProperty,
183                                   &Manager::AvailableTechnologies);
184   HelpRegisterDerivedString(kCheckPortalListProperty,
185                             &Manager::GetCheckPortalList,
186                             &Manager::SetCheckPortalList);
187   HelpRegisterConstDerivedStrings(kConnectedTechnologiesProperty,
188                                   &Manager::ConnectedTechnologies);
189   store_.RegisterConstString(kConnectionStateProperty, &connection_state_);
190   store_.RegisterString(kCountryProperty, &props_.country);
191   HelpRegisterDerivedString(kDefaultTechnologyProperty,
192                             &Manager::DefaultTechnology,
193                             nullptr);
194   HelpRegisterConstDerivedRpcIdentifier(
195       kDefaultServiceProperty, &Manager::GetDefaultServiceRpcIdentifier);
196   HelpRegisterConstDerivedRpcIdentifiers(kDevicesProperty,
197                                          &Manager::EnumerateDevices);
198 #if !defined(DISABLE_WIFI)
199   HelpRegisterDerivedBool(kDisableWiFiVHTProperty,
200                           &Manager::GetDisableWiFiVHT,
201                           &Manager::SetDisableWiFiVHT);
202 #endif  // DISABLE_WIFI
203   HelpRegisterConstDerivedStrings(kEnabledTechnologiesProperty,
204                                   &Manager::EnabledTechnologies);
205   HelpRegisterDerivedString(kIgnoredDNSSearchPathsProperty,
206                             &Manager::GetIgnoredDNSSearchPaths,
207                             &Manager::SetIgnoredDNSSearchPaths);
208   store_.RegisterString(kHostNameProperty, &props_.host_name);
209   store_.RegisterString(kLinkMonitorTechnologiesProperty,
210                         &props_.link_monitor_technologies);
211   store_.RegisterString(kNoAutoConnectTechnologiesProperty,
212                         &props_.no_auto_connect_technologies);
213   store_.RegisterBool(kOfflineModeProperty, &props_.offline_mode);
214   store_.RegisterString(kPortalURLProperty, &props_.portal_url);
215   store_.RegisterInt32(kPortalCheckIntervalProperty,
216                        &props_.portal_check_interval_seconds);
217   HelpRegisterConstDerivedRpcIdentifiers(kProfilesProperty,
218                                          &Manager::EnumerateProfiles);
219   HelpRegisterDerivedString(kProhibitedTechnologiesProperty,
220                             &Manager::GetProhibitedTechnologies,
221                             &Manager::SetProhibitedTechnologies);
222   HelpRegisterDerivedString(kStateProperty,
223                             &Manager::CalculateState,
224                             nullptr);
225   HelpRegisterConstDerivedRpcIdentifiers(kServicesProperty,
226                                          &Manager::EnumerateAvailableServices);
227   HelpRegisterConstDerivedRpcIdentifiers(kServiceCompleteListProperty,
228                                          &Manager::EnumerateCompleteServices);
229   HelpRegisterConstDerivedRpcIdentifiers(kServiceWatchListProperty,
230                                          &Manager::EnumerateWatchedServices);
231   HelpRegisterConstDerivedStrings(kUninitializedTechnologiesProperty,
232                                   &Manager::UninitializedTechnologies);
233   store_.RegisterBool(kWakeOnLanEnabledProperty, &is_wake_on_lan_enabled_);
234   HelpRegisterConstDerivedStrings(kClaimedDevicesProperty,
235                                   &Manager::ClaimedDevices);
236 
237   UpdateProviderMapping();
238 
239   dhcp_properties_->InitPropertyStore(&store_);
240 
241   SLOG(this, 2) << "Manager initialized.";
242 }
243 
~Manager()244 Manager::~Manager() {}
245 
RegisterAsync(const Callback<void (bool)> & completion_callback)246 void Manager::RegisterAsync(const Callback<void(bool)>& completion_callback) {
247   adaptor_->RegisterAsync(completion_callback);
248 }
249 
SetBlacklistedDevices(const vector<string> & blacklisted_devices)250 void Manager::SetBlacklistedDevices(const vector<string>& blacklisted_devices) {
251   blacklisted_devices_ = blacklisted_devices;
252 }
253 
SetWhitelistedDevices(const vector<string> & whitelisted_devices)254 void Manager::SetWhitelistedDevices(const vector<string>& whitelisted_devices) {
255   whitelisted_devices_ = whitelisted_devices;
256 }
257 
Start()258 void Manager::Start() {
259   LOG(INFO) << "Manager started.";
260 
261   power_manager_.reset(
262       new PowerManager(dispatcher_, control_interface_));
263   power_manager_->Start(base::TimeDelta::FromMilliseconds(
264                             kTerminationActionsTimeoutMilliseconds),
265                         Bind(&Manager::OnSuspendImminent, AsWeakPtr()),
266                         Bind(&Manager::OnSuspendDone, AsWeakPtr()),
267                         Bind(&Manager::OnDarkSuspendImminent, AsWeakPtr()));
268   upstart_.reset(new Upstart(control_interface_));
269 
270   CHECK(base::CreateDirectory(run_path_)) << run_path_.value();
271   resolver_->set_path(run_path_.Append("resolv.conf"));
272 
273   InitializeProfiles();
274   running_ = true;
275   device_info_.Start();
276 #if !defined(DISABLE_CELLULAR)
277   modem_info_.Start();
278 #endif  // DISABLE_CELLULAR
279   for (const auto& provider_mapping : providers_) {
280     provider_mapping.second->Start();
281   }
282 
283   // Start task for checking connection status.
284   dispatcher_->PostDelayedTask(device_status_check_task_.callback(),
285                                kDeviceStatusCheckIntervalMilliseconds);
286 }
287 
Stop()288 void Manager::Stop() {
289   running_ = false;
290   // Persist device information to disk;
291   for (const auto& device : devices_) {
292     UpdateDevice(device);
293   }
294 
295 #if !defined(DISABLE_WIFI)
296   UpdateWiFiProvider();
297 #endif  // DISABLE_WIFI
298 
299   // Persist profile, service information to disk.
300   for (const auto& profile : profiles_) {
301     // Since this happens in a loop, the current manager state is stored to
302     // all default profiles in the stack.  This is acceptable because the
303     // only time multiple default profiles are loaded are during autotests.
304     profile->Save();
305   }
306 
307   Error e;
308   for (const auto& service : services_) {
309     service->Disconnect(&e, __func__);
310   }
311 
312   for (const auto& device : devices_) {
313     device->SetEnabled(false);
314   }
315 
316   for (const auto& provider_mapping : providers_) {
317     provider_mapping.second->Stop();
318   }
319 #if !defined(DISABLE_CELLULAR)
320   modem_info_.Stop();
321 #endif  // DISABLE_CELLULAR
322   device_info_.Stop();
323   device_status_check_task_.Cancel();
324   sort_services_task_.Cancel();
325   power_manager_->Stop();
326   power_manager_.reset();
327 }
328 
InitializeProfiles()329 void Manager::InitializeProfiles() {
330   DCHECK(profiles_.empty());  // The default profile must go first on stack.
331   CHECK(base::CreateDirectory(storage_path_)) << storage_path_.value();
332 
333   // Ensure that we have storage for the default profile, and that
334   // the persistent copy of the default profile is not corrupt.
335   scoped_refptr<DefaultProfile>
336       default_profile(new DefaultProfile(control_interface_,
337                                          metrics_,
338                                          this,
339                                          storage_path_,
340                                          DefaultProfile::kDefaultId,
341                                          props_));
342   // The default profile may fail to initialize if it's corrupted.
343   // If so, recreate the default profile.
344   if (!default_profile->InitStorage(Profile::kCreateOrOpenExisting, nullptr))
345     CHECK(default_profile->InitStorage(Profile::kCreateNew, nullptr));
346   // In case we created a new profile, initialize its default values,
347   // and then save. This is required for properties such as
348   // PortalDetector::kDefaultCheckPortalList to be initialized correctly.
349   LoadProperties(default_profile);
350   default_profile->Save();
351   default_profile = nullptr;  // PushProfileInternal will re-create.
352 
353   // Read list of user profiles. This must be done before pushing the
354   // default profile, because modifying the profile stack updates the
355   // user profile list.
356   vector<Profile::Identifier> identifiers =
357       Profile::LoadUserProfileList(user_profile_list_path_);
358 
359   // Push the default profile onto the stack.
360   Error error;
361   string path;
362   Profile::Identifier default_profile_id;
363   CHECK(Profile::ParseIdentifier(
364       DefaultProfile::kDefaultId, &default_profile_id));
365   PushProfileInternal(default_profile_id, &path, &error);
366   CHECK(!profiles_.empty());  // Must have a default profile.
367 
368   // Push user profiles onto the stack.
369   for (const auto& profile_id : identifiers)  {
370     PushProfileInternal(profile_id, &path, &error);
371   }
372 }
373 
CreateProfile(const string & name,string * path,Error * error)374 void Manager::CreateProfile(const string& name, string* path, Error* error) {
375   SLOG(this, 2) << __func__ << " " << name;
376   Profile::Identifier ident;
377   if (!Profile::ParseIdentifier(name, &ident)) {
378     Error::PopulateAndLog(FROM_HERE, error, Error::kInvalidArguments,
379                           "Invalid profile name " + name);
380     return;
381   }
382 
383   if (HasProfile(ident)) {
384     Error::PopulateAndLog(FROM_HERE, error, Error::kAlreadyExists,
385                           "Profile name " + name + " is already on stack");
386     return;
387   }
388 
389   ProfileRefPtr profile;
390   if (ident.user.empty()) {
391     profile = new DefaultProfile(control_interface_,
392                                  metrics_,
393                                  this,
394                                  storage_path_,
395                                  ident.identifier,
396                                  props_);
397   } else {
398     profile = new Profile(control_interface_,
399                           metrics_,
400                           this,
401                           ident,
402                           user_storage_path_,
403                           true);
404   }
405 
406   if (!profile->InitStorage(Profile::kCreateNew, error)) {
407     // |error| will have been populated by InitStorage().
408     return;
409   }
410 
411   // Save profile data out, and then let the scoped pointer fall out of scope.
412   if (!profile->Save()) {
413     Error::PopulateAndLog(FROM_HERE, error, Error::kInternalError,
414                           "Profile name " + name + " could not be saved");
415     return;
416   }
417 
418   *path = profile->GetRpcIdentifier();
419 }
420 
HasProfile(const Profile::Identifier & ident)421 bool Manager::HasProfile(const Profile::Identifier& ident) {
422   for (const auto& profile : profiles_) {
423     if (profile->MatchesIdentifier(ident)) {
424       return true;
425     }
426   }
427   return false;
428 }
429 
PushProfileInternal(const Profile::Identifier & ident,string * path,Error * error)430 void Manager::PushProfileInternal(
431     const Profile::Identifier& ident, string* path, Error* error) {
432   if (HasProfile(ident)) {
433     Error::PopulateAndLog(FROM_HERE, error, Error::kAlreadyExists,
434                           "Profile name " + Profile::IdentifierToString(ident) +
435                           " is already on stack");
436     return;
437   }
438 
439   ProfileRefPtr profile;
440   if (ident.user.empty()) {
441     // Allow a machine-wide-profile to be pushed on the stack only if the
442     // profile stack is empty, or if the topmost profile on the stack is
443     // also a machine-wide (non-user) profile.
444     if (!profiles_.empty() && !profiles_.back()->GetUser().empty()) {
445       Error::PopulateAndLog(FROM_HERE, error, Error::kInvalidArguments,
446                             "Cannot load non-default global profile " +
447                             Profile::IdentifierToString(ident) +
448                             " on top of a user profile");
449       return;
450     }
451 
452     scoped_refptr<DefaultProfile>
453         default_profile(new DefaultProfile(control_interface_,
454                                            metrics_,
455                                            this,
456                                            storage_path_,
457                                            ident.identifier,
458                                            props_));
459     if (!default_profile->InitStorage(Profile::kOpenExisting, nullptr)) {
460       LOG(ERROR) << "Failed to open default profile.";
461       // Try to continue anyway, so that we can be useful in cases
462       // where the disk is full.
463       default_profile->InitStubStorage();
464     }
465 
466     LoadProperties(default_profile);
467     profile = default_profile;
468   } else {
469     profile = new Profile(control_interface_,
470                           metrics_,
471                           this,
472                           ident,
473                           user_storage_path_,
474                           connect_profiles_to_rpc_);
475     if (!profile->InitStorage(Profile::kOpenExisting, error)) {
476       // |error| will have been populated by InitStorage().
477       return;
478     }
479   }
480 
481   profiles_.push_back(profile);
482 
483   for (ServiceRefPtr& service : services_) {
484     service->ClearExplicitlyDisconnected();
485 
486     // Offer each registered Service the opportunity to join this new Profile.
487     if (profile->ConfigureService(service)) {
488       LOG(INFO) << "(Re-)configured service " << service->unique_name()
489                 << " from new profile.";
490     }
491   }
492 
493   // Shop the Profile contents around to Devices which may have configuration
494   // stored in these profiles.
495   for (DeviceRefPtr& device : devices_) {
496     profile->ConfigureDevice(device);
497   }
498 
499   // Offer the Profile contents to the service providers which will
500   // create new services if necessary.
501   for (const auto& provider_mapping : providers_) {
502     provider_mapping.second->CreateServicesFromProfile(profile);
503   }
504 
505   *path = profile->GetRpcIdentifier();
506   SortServices();
507   OnProfilesChanged();
508   LOG(INFO) << __func__ << " finished; " << profiles_.size()
509             << " profile(s) now present.";
510 }
511 
PushProfile(const string & name,string * path,Error * error)512 void Manager::PushProfile(const string& name, string* path, Error* error) {
513   SLOG(this, 2) << __func__ << " " << name;
514   Profile::Identifier ident;
515   if (!Profile::ParseIdentifier(name, &ident)) {
516     Error::PopulateAndLog(FROM_HERE, error, Error::kInvalidArguments,
517                           "Invalid profile name " + name);
518     return;
519   }
520   PushProfileInternal(ident, path, error);
521 }
522 
InsertUserProfile(const string & name,const string & user_hash,string * path,Error * error)523 void Manager::InsertUserProfile(const string& name,
524                                 const string& user_hash,
525                                 string* path,
526                                 Error* error) {
527   SLOG(this, 2) << __func__ << " " << name;
528   Profile::Identifier ident;
529   if (!Profile::ParseIdentifier(name, &ident) ||
530       ident.user.empty()) {
531     Error::PopulateAndLog(FROM_HERE, error, Error::kInvalidArguments,
532                           "Invalid user profile name " + name);
533     return;
534   }
535   ident.user_hash = user_hash;
536   PushProfileInternal(ident, path, error);
537 }
538 
PopProfileInternal()539 void Manager::PopProfileInternal() {
540   CHECK(!profiles_.empty());
541   ProfileRefPtr active_profile = profiles_.back();
542   profiles_.pop_back();
543   for (auto it = services_.begin(); it != services_.end();) {
544     (*it)->ClearExplicitlyDisconnected();
545     if (IsServiceEphemeral(*it)) {
546       // Not affected, since the EphemeralProfile isn't on the stack.
547       // Not logged, since ephemeral services aren't that interesting.
548       ++it;
549       continue;
550     }
551 
552     if ((*it)->profile().get() != active_profile.get()) {
553       LOG(INFO) << "Skipping unload of service " << (*it)->unique_name()
554                 << ": wasn't using this profile.";
555       ++it;
556       continue;
557     }
558 
559     if (MatchProfileWithService(*it)) {
560       LOG(INFO) << "Skipping unload of service " << (*it)->unique_name()
561                 << ": re-configured from another profile.";
562       ++it;
563       continue;
564     }
565 
566     if (!UnloadService(&it)) {
567       LOG(INFO) << "Service " << (*it)->unique_name()
568                 << " not completely unloaded.";
569       ++it;
570       continue;
571     }
572 
573     // Service was totally unloaded. No advance of iterator in this
574     // case, as UnloadService has updated the iterator for us.
575   }
576   SortServices();
577   OnProfilesChanged();
578   LOG(INFO) << __func__ << " finished; " << profiles_.size()
579             << " profile(s) still present.";
580 }
581 
OnProfilesChanged()582 void Manager::OnProfilesChanged() {
583   Error unused_error;
584 
585   adaptor_->EmitStringsChanged(kProfilesProperty,
586                                EnumerateProfiles(&unused_error));
587   Profile::SaveUserProfileList(user_profile_list_path_, profiles_);
588 }
589 
PopProfile(const string & name,Error * error)590 void Manager::PopProfile(const string& name, Error* error) {
591   SLOG(this, 2) << __func__ << " " << name;
592   Profile::Identifier ident;
593   if (profiles_.empty()) {
594     Error::PopulateAndLog(
595         FROM_HERE, error, Error::kNotFound, "Profile stack is empty");
596     return;
597   }
598   ProfileRefPtr active_profile = profiles_.back();
599   if (!Profile::ParseIdentifier(name, &ident)) {
600     Error::PopulateAndLog(FROM_HERE, error, Error::kInvalidArguments,
601                           "Invalid profile name " + name);
602     return;
603   }
604   if (!active_profile->MatchesIdentifier(ident)) {
605     Error::PopulateAndLog(FROM_HERE, error, Error::kNotSupported,
606                           name + " is not the active profile");
607     return;
608   }
609   PopProfileInternal();
610 }
611 
PopAnyProfile(Error * error)612 void Manager::PopAnyProfile(Error* error) {
613   SLOG(this, 2) << __func__;
614   Profile::Identifier ident;
615   if (profiles_.empty()) {
616     Error::PopulateAndLog(
617         FROM_HERE, error, Error::kNotFound, "Profile stack is empty");
618     return;
619   }
620   PopProfileInternal();
621 }
622 
PopAllUserProfiles(Error *)623 void Manager::PopAllUserProfiles(Error* /*error*/) {
624   SLOG(this, 2) << __func__;
625   while (!profiles_.empty() && !profiles_.back()->GetUser().empty()) {
626     PopProfileInternal();
627   }
628 }
629 
RemoveProfile(const string & name,Error * error)630 void Manager::RemoveProfile(const string& name, Error* error) {
631   Profile::Identifier ident;
632   if (!Profile::ParseIdentifier(name, &ident)) {
633     Error::PopulateAndLog(FROM_HERE, error, Error::kInvalidArguments,
634                           "Invalid profile name " + name);
635     return;
636   }
637 
638   if (HasProfile(ident)) {
639     Error::PopulateAndLog(FROM_HERE, error, Error::kInvalidArguments,
640                           "Cannot remove profile name " + name +
641                           " since it is on stack");
642     return;
643   }
644 
645   ProfileRefPtr profile;
646   if (ident.user.empty()) {
647     profile = new DefaultProfile(control_interface_,
648                                  metrics_,
649                                  this,
650                                  storage_path_,
651                                  ident.identifier,
652                                  props_);
653   } else {
654     profile = new Profile(control_interface_,
655                           metrics_,
656                           this,
657                           ident,
658                           user_storage_path_,
659                           false);
660   }
661 
662 
663   // |error| will have been populated if RemoveStorage fails.
664   profile->RemoveStorage(error);
665 
666   return;
667 }
668 
DeviceManagementAllowed(const string & device_name)669 bool Manager::DeviceManagementAllowed(const string& device_name) {
670   if (std::find(blacklisted_devices_.begin(),
671                 blacklisted_devices_.end(),
672                 device_name) != blacklisted_devices_.end()) {
673     return false;
674   }
675   if (!whitelisted_devices_.size()) {
676     // If no whitelist is specified, all devices are considered whitelisted.
677     return true;
678   }
679   if (std::find(whitelisted_devices_.begin(),
680                 whitelisted_devices_.end(),
681                 device_name) != whitelisted_devices_.end()) {
682     return true;
683   }
684   return false;
685 }
686 
ClaimDevice(const string & claimer_name,const string & device_name,Error * error)687 void Manager::ClaimDevice(const string& claimer_name,
688                           const string& device_name,
689                           Error* error) {
690   SLOG(this, 2) << __func__;
691 
692   // Basic check for device name.
693   if (device_name.empty()) {
694     Error::PopulateAndLog(FROM_HERE, error, Error::kInvalidArguments,
695                           "Empty device name");
696     return;
697   }
698 
699   if (!DeviceManagementAllowed(device_name)) {
700     Error::PopulateAndLog(FROM_HERE, error, Error::kInvalidArguments,
701                           "Not allowed to claim unmanaged device");
702     return;
703   }
704 
705   // Verify default claimer.
706   if (claimer_name.empty() &&
707       (!device_claimer_ || !device_claimer_->default_claimer())) {
708     Error::PopulateAndLog(FROM_HERE, error, Error::kInvalidArguments,
709                           "No default claimer");
710     return;
711   }
712 
713   // Create a new device claimer if one doesn't exist yet.
714   if (!device_claimer_) {
715     // Start a device claimer.  No need to verify the existence of the claimer,
716     // since we are using message sender as the claimer name.
717     device_claimer_.reset(
718         new DeviceClaimer(claimer_name, &device_info_, false));
719   }
720 
721   // Verify claimer's name, since we only allow one claimer to exist at a time.
722   if (device_claimer_->name() != claimer_name) {
723     Error::PopulateAndLog(FROM_HERE, error, Error::kInvalidArguments,
724                           "Invalid claimer name " + claimer_name +
725                           ". Claimer " + device_claimer_->name() +
726                           " already exist");
727     return;
728   }
729 
730   // Error will be populated by the claimer if failed to claim the device.
731   if (!device_claimer_->Claim(device_name, error)) {
732     return;
733   }
734 
735   // Deregister the device from manager if it is registered.
736   DeregisterDeviceByLinkName(device_name);
737 }
738 
ReleaseDevice(const string & claimer_name,const string & device_name,bool * claimer_removed,Error * error)739 void Manager::ReleaseDevice(const string& claimer_name,
740                             const string& device_name,
741                             bool* claimer_removed,
742                             Error* error) {
743   SLOG(this, 2) << __func__;
744 
745   *claimer_removed = false;
746 
747   if (!DeviceManagementAllowed(device_name)) {
748     Error::PopulateAndLog(FROM_HERE, error, Error::kInvalidArguments,
749                           "Not allowed to release unmanaged device");
750     return;
751   }
752 
753   if (!device_claimer_) {
754     Error::PopulateAndLog(FROM_HERE, error, Error::kInvalidArguments,
755                           "Device claimer doesn't exist");
756     return;
757   }
758 
759   // Verify claimer's name, since we only allow one claimer to exist at a time.
760   if (device_claimer_->name() != claimer_name) {
761     Error::PopulateAndLog(FROM_HERE, error, Error::kInvalidArguments,
762                           "Invalid claimer name " + claimer_name +
763                           ". Claimer " + device_claimer_->name() +
764                           " already exist");
765     return;
766   }
767 
768   // Release the device from the claimer. Error should be populated by the
769   // claimer if it failed to release the given device.
770   device_claimer_->Release(device_name, error);
771 
772   // Reset claimer if this is not the default claimer and no more devices are
773   // claimed by this claimer.
774   if (!device_claimer_->default_claimer() &&
775       !device_claimer_->DevicesClaimed()) {
776     device_claimer_.reset();
777     *claimer_removed = true;
778   }
779 }
780 
781 #if !defined(DISABLE_WIFI) && defined(__BRILLO__)
SetupApModeInterface(string * out_interface_name,Error * error)782 bool Manager::SetupApModeInterface(string* out_interface_name, Error* error) {
783   string interface_name = wifi_driver_hal_->SetupApModeInterface();
784   if (interface_name.empty()) {
785     Error::PopulateAndLog(FROM_HERE, error, Error::kOperationFailed,
786                           "Failed to setup AP mode interface");
787     return false;
788   }
789   *out_interface_name = interface_name;
790   return true;
791 }
792 
SetupStationModeInterface(string * out_interface_name,Error * error)793 bool Manager::SetupStationModeInterface(string* out_interface_name,
794                                         Error* error) {
795   string interface_name = wifi_driver_hal_->SetupStationModeInterface();
796   if (interface_name.empty()) {
797     Error::PopulateAndLog(FROM_HERE, error, Error::kOperationFailed,
798                           "Failed to setup station mode interface");
799     return false;
800   }
801   *out_interface_name = interface_name;
802   return true;
803 }
804 
OnApModeSetterVanished()805 void Manager::OnApModeSetterVanished() {
806   // Restore station mode interface.
807   string interface_name = wifi_driver_hal_->SetupStationModeInterface();
808   if (interface_name.empty()) {
809     LOG(ERROR) << "Failed to restore station mode interface";
810   }
811 }
812 #endif  // !DISABLE_WIFI && __BRILLO__
813 
RemoveService(const ServiceRefPtr & service)814 void Manager::RemoveService(const ServiceRefPtr& service) {
815   LOG(INFO) << __func__ << " for service " << service->unique_name();
816   if (!IsServiceEphemeral(service)) {
817     service->profile()->AbandonService(service);
818     if (MatchProfileWithService(service)) {
819       // We found another profile to adopt the service; no need to unload.
820       UpdateService(service);
821       return;
822     }
823   }
824   auto service_it = std::find(services_.begin(), services_.end(), service);
825   CHECK(service_it != services_.end());
826   if (!UnloadService(&service_it)) {
827     UpdateService(service);
828   }
829   SortServices();
830 }
831 
HandleProfileEntryDeletion(const ProfileRefPtr & profile,const std::string & entry_name)832 bool Manager::HandleProfileEntryDeletion(const ProfileRefPtr& profile,
833                                          const std::string& entry_name) {
834   bool moved_services = false;
835   for (auto it = services_.begin(); it != services_.end();) {
836     if ((*it)->profile().get() == profile.get() &&
837         (*it)->GetStorageIdentifier() == entry_name) {
838       profile->AbandonService(*it);
839       if (MatchProfileWithService(*it) ||
840           !UnloadService(&it)) {
841         ++it;
842       }
843       moved_services = true;
844     } else {
845       ++it;
846     }
847   }
848   if (moved_services) {
849     SortServices();
850   }
851   return moved_services;
852 }
853 
GetLoadableProfileEntriesForService(const ServiceConstRefPtr & service)854 map<string, string> Manager::GetLoadableProfileEntriesForService(
855     const ServiceConstRefPtr& service) {
856   map<string, string> profile_entries;
857   for (const auto& profile : profiles_) {
858     string entry_name = service->GetLoadableStorageIdentifier(
859         *profile->GetConstStorage());
860     if (!entry_name.empty()) {
861       profile_entries[profile->GetRpcIdentifier()] = entry_name;
862     }
863   }
864   return profile_entries;
865 }
866 
GetServiceWithStorageIdentifier(const ProfileRefPtr & profile,const std::string & entry_name,Error * error)867 ServiceRefPtr Manager::GetServiceWithStorageIdentifier(
868     const ProfileRefPtr& profile, const std::string& entry_name, Error* error) {
869   for (const auto& service : services_) {
870     if (service->profile().get() == profile.get() &&
871         service->GetStorageIdentifier() == entry_name) {
872       return service;
873     }
874   }
875 
876   SLOG(this, 2) << "Entry " << entry_name
877                 << " is not registered in the manager";
878   return nullptr;
879 }
880 
CreateTemporaryServiceFromProfile(const ProfileRefPtr & profile,const std::string & entry_name,Error * error)881 ServiceRefPtr Manager::CreateTemporaryServiceFromProfile(
882     const ProfileRefPtr& profile, const std::string& entry_name, Error* error) {
883   Technology::Identifier technology =
884       Technology::IdentifierFromStorageGroup(entry_name);
885   if (technology == Technology::kUnknown) {
886     Error::PopulateAndLog(
887         FROM_HERE, error, Error::kInternalError,
888         "Could not determine technology for entry: " + entry_name);
889     return nullptr;
890   }
891 
892   ServiceRefPtr service = nullptr;
893   // Since there is no provider for Ethernet services (Ethernet services are
894   // created/provided by the Ethernet device), we will explicitly create
895   // temporary Ethernet services for loading Ethernet entries.
896   if (technology == Technology::kEthernet) {
897     service = new EthernetTemporaryService(control_interface_,
898                                            dispatcher_,
899                                            metrics_,
900                                            this,
901                                            entry_name);
902   } else if (ContainsKey(providers_, technology)) {
903     service =
904         providers_[technology]->CreateTemporaryServiceFromProfile(
905             profile, entry_name, error);
906   }
907 
908   if (!service) {
909     Error::PopulateAndLog(FROM_HERE, error, Error::kNotSupported,
910                           kErrorUnsupportedServiceType);
911     return nullptr;
912   }
913 
914   profile->LoadService(service);
915   return service;
916 }
917 
GetServiceWithGUID(const std::string & guid,Error * error)918 ServiceRefPtr Manager::GetServiceWithGUID(
919     const std::string& guid, Error* error) {
920   for (const auto& service : services_) {
921     if (service->guid() == guid) {
922       return service;
923     }
924   }
925 
926   string error_string(
927       StringPrintf("Service wth GUID %s is not registered in the manager",
928                    guid.c_str()));
929   if (error) {
930     error->Populate(Error::kNotFound, error_string);
931   }
932   SLOG(this, 2) << error_string;
933   return nullptr;
934 }
935 
GetDefaultService() const936 ServiceRefPtr Manager::GetDefaultService() const {
937   SLOG(this, 2) << __func__;
938   if (services_.empty() || !services_[0]->connection().get()) {
939     SLOG(this, 2) << "In " << __func__ << ": No default connection exists.";
940     return nullptr;
941   }
942   return services_[0];
943 }
944 
GetDefaultServiceRpcIdentifier(Error *)945 RpcIdentifier Manager::GetDefaultServiceRpcIdentifier(Error* /*error*/) {
946   ServiceRefPtr default_service = GetDefaultService();
947   return default_service ? default_service->GetRpcIdentifier() :
948       control_interface_->NullRPCIdentifier();
949 }
950 
IsTechnologyInList(const string & technology_list,Technology::Identifier tech) const951 bool Manager::IsTechnologyInList(const string& technology_list,
952                                  Technology::Identifier tech) const {
953   if (technology_list.empty())
954     return false;
955 
956   Error error;
957   vector<Technology::Identifier> technologies;
958   return Technology::GetTechnologyVectorFromString(technology_list,
959                                                    &technologies,
960                                                    &error) &&
961       std::find(technologies.begin(), technologies.end(), tech) !=
962           technologies.end();
963 }
964 
IsPortalDetectionEnabled(Technology::Identifier tech)965 bool Manager::IsPortalDetectionEnabled(Technology::Identifier tech) {
966   return IsTechnologyInList(GetCheckPortalList(nullptr), tech);
967 }
968 
SetStartupPortalList(const string & portal_list)969 void Manager::SetStartupPortalList(const string& portal_list) {
970   startup_portal_list_ = portal_list;
971   use_startup_portal_list_ = true;
972 }
973 
IsProfileBefore(const ProfileRefPtr & a,const ProfileRefPtr & b) const974 bool Manager::IsProfileBefore(const ProfileRefPtr& a,
975                               const ProfileRefPtr& b) const {
976   DCHECK(a != b);
977   for (const auto& profile : profiles_) {
978     if (profile == a) {
979       return true;
980     }
981     if (profile == b) {
982       return false;
983     }
984   }
985   NOTREACHED() << "We should have found both profiles in the profiles_ list!";
986   return false;
987 }
988 
IsServiceEphemeral(const ServiceConstRefPtr & service) const989 bool Manager::IsServiceEphemeral(const ServiceConstRefPtr& service) const {
990   return service->profile() == ephemeral_profile_;
991 }
992 
IsTechnologyLinkMonitorEnabled(Technology::Identifier technology) const993 bool Manager::IsTechnologyLinkMonitorEnabled(
994     Technology::Identifier technology) const {
995   return IsTechnologyInList(props_.link_monitor_technologies, technology);
996 }
997 
IsTechnologyAutoConnectDisabled(Technology::Identifier technology) const998 bool Manager::IsTechnologyAutoConnectDisabled(
999     Technology::Identifier technology) const {
1000   return IsTechnologyInList(props_.no_auto_connect_technologies, technology);
1001 }
1002 
IsTechnologyProhibited(Technology::Identifier technology) const1003 bool Manager::IsTechnologyProhibited(
1004     Technology::Identifier technology) const {
1005   return IsTechnologyInList(props_.prohibited_technologies, technology);
1006 }
1007 
OnProfileStorageInitialized(Profile * profile)1008 void Manager::OnProfileStorageInitialized(Profile* profile) {
1009 #if !defined(DISABLE_WIFI)
1010   wifi_provider_->LoadAndFixupServiceEntries(profile);
1011 #endif  // DISABLE_WIFI
1012 }
1013 
GetEnabledDeviceWithTechnology(Technology::Identifier technology) const1014 DeviceRefPtr Manager::GetEnabledDeviceWithTechnology(
1015     Technology::Identifier technology) const {
1016   for (const auto& device : FilterByTechnology(technology)) {
1017     if (device->enabled()) {
1018       return device;
1019     }
1020   }
1021   return nullptr;
1022 }
1023 
GetEnabledDeviceByLinkName(const string & link_name) const1024 DeviceRefPtr Manager::GetEnabledDeviceByLinkName(
1025     const string& link_name) const {
1026   for (const auto& device : devices_) {
1027     if (device->link_name() == link_name) {
1028       if (!device->enabled()) {
1029         return nullptr;
1030       }
1031       return device;
1032     }
1033   }
1034   return nullptr;
1035 }
1036 
ActiveProfile() const1037 const ProfileRefPtr& Manager::ActiveProfile() const {
1038   DCHECK_NE(profiles_.size(), 0U);
1039   return profiles_.back();
1040 }
1041 
IsActiveProfile(const ProfileRefPtr & profile) const1042 bool Manager::IsActiveProfile(const ProfileRefPtr& profile) const {
1043   return (profiles_.size() > 0 &&
1044           ActiveProfile().get() == profile.get());
1045 }
1046 
MoveServiceToProfile(const ServiceRefPtr & to_move,const ProfileRefPtr & destination)1047 bool Manager::MoveServiceToProfile(const ServiceRefPtr& to_move,
1048                                    const ProfileRefPtr& destination) {
1049   const ProfileRefPtr from = to_move->profile();
1050   SLOG(this, 2) << "Moving service "
1051                 << to_move->unique_name()
1052                 << " to profile "
1053                 << destination->GetFriendlyName()
1054                 << " from "
1055                 << from->GetFriendlyName();
1056   return destination->AdoptService(to_move) && from->AbandonService(to_move);
1057 }
1058 
LookupProfileByRpcIdentifier(const string & profile_rpcid)1059 ProfileRefPtr Manager::LookupProfileByRpcIdentifier(
1060     const string& profile_rpcid) {
1061   for (const auto& profile : profiles_) {
1062     if (profile_rpcid == profile->GetRpcIdentifier()) {
1063       return profile;
1064     }
1065   }
1066   return nullptr;
1067 }
1068 
SetProfileForService(const ServiceRefPtr & to_set,const string & profile_rpcid,Error * error)1069 void Manager::SetProfileForService(const ServiceRefPtr& to_set,
1070                                    const string& profile_rpcid,
1071                                    Error* error) {
1072   ProfileRefPtr profile = LookupProfileByRpcIdentifier(profile_rpcid);
1073   if (!profile) {
1074     Error::PopulateAndLog(FROM_HERE, error, Error::kInvalidArguments,
1075                           StringPrintf("Unknown Profile %s requested for "
1076                                        "Service", profile_rpcid.c_str()));
1077     return;
1078   }
1079 
1080   if (!to_set->profile()) {
1081     // We are being asked to set the profile property of a service that
1082     // has never been registered.  Now is a good time to register it.
1083     RegisterService(to_set);
1084   }
1085 
1086   if (to_set->profile().get() == profile.get()) {
1087     Error::PopulateAndLog(FROM_HERE, error, Error::kInvalidArguments,
1088                           "Service is already connected to this profile");
1089   } else if (!MoveServiceToProfile(to_set, profile)) {
1090     Error::PopulateAndLog(FROM_HERE, error, Error::kInternalError,
1091                           "Unable to move service to profile");
1092   }
1093 }
1094 
SetEnabledStateForTechnology(const std::string & technology_name,bool enabled_state,bool persist,Error * error,const ResultCallback & callback)1095 void Manager::SetEnabledStateForTechnology(const std::string& technology_name,
1096                                            bool enabled_state,
1097                                            bool persist,
1098                                            Error* error,
1099                                            const ResultCallback& callback) {
1100   CHECK(error);
1101   DCHECK(error->IsOngoing());
1102   Technology::Identifier id = Technology::IdentifierFromName(technology_name);
1103   if (id == Technology::kUnknown) {
1104     error->Populate(Error::kInvalidArguments, "Unknown technology");
1105     return;
1106   }
1107   if (enabled_state && IsTechnologyProhibited(id)) {
1108     error->Populate(Error::kPermissionDenied,
1109                     "The " + technology_name + " technology is prohibited");
1110     return;
1111   }
1112   bool deferred = false;
1113   auto result_aggregator(make_scoped_refptr(new ResultAggregator(callback)));
1114   for (auto& device : devices_) {
1115     if (device->technology() != id)
1116       continue;
1117 
1118     Error device_error(Error::kOperationInitiated);
1119     ResultCallback aggregator_callback(
1120         Bind(&ResultAggregator::ReportResult, result_aggregator));
1121     if (persist) {
1122       device->SetEnabledPersistent(
1123           enabled_state, &device_error, aggregator_callback);
1124     } else {
1125       device->SetEnabledNonPersistent(
1126           enabled_state, &device_error, aggregator_callback);
1127     }
1128     if (device_error.IsOngoing()) {
1129       deferred = true;
1130     } else if (!error->IsFailure()) {  // Report first failure.
1131       error->CopyFrom(device_error);
1132     }
1133   }
1134   if (deferred) {
1135     // Some device is handling this change asynchronously. Clobber any error
1136     // from another device, so that we can indicate the operation is still in
1137     // progress.
1138     error->Populate(Error::kOperationInitiated);
1139   } else if (error->IsOngoing()) {
1140     // |error| IsOngoing at entry to this method, but no device
1141     // |deferred|. Reset |error|, to indicate we're done.
1142     error->Reset();
1143   }
1144 }
1145 
UpdateEnabledTechnologies()1146 void Manager::UpdateEnabledTechnologies() {
1147   Error error;
1148   adaptor_->EmitStringsChanged(kEnabledTechnologiesProperty,
1149                                EnabledTechnologies(&error));
1150 }
1151 
UpdateUninitializedTechnologies()1152 void Manager::UpdateUninitializedTechnologies() {
1153   Error error;
1154   adaptor_->EmitStringsChanged(kUninitializedTechnologiesProperty,
1155                                UninitializedTechnologies(&error));
1156 }
1157 
SetPassiveMode()1158 void Manager::SetPassiveMode() {
1159   CHECK(!device_claimer_);
1160   // Create a default device claimer to claim devices from  shill as they're
1161   // detected.  Devices will be managed by remote application, which will use
1162   // the default claimer to specify the devices for shill to manage.
1163   device_claimer_.reset(
1164       new DeviceClaimer(kDefaultClaimerName, &device_info_, true));
1165 }
1166 
SetIgnoreUnknownEthernet(bool ignore)1167 void Manager::SetIgnoreUnknownEthernet(bool ignore) {
1168   LOG(INFO) << __func__ << "(" << ignore << ")";
1169   ignore_unknown_ethernet_ = ignore;
1170 }
1171 
SetPrependDNSServers(const std::string & prepend_dns_servers)1172 void Manager::SetPrependDNSServers(const std::string& prepend_dns_servers) {
1173   props_.prepend_dns_servers = prepend_dns_servers;
1174 }
1175 
SetAcceptHostnameFrom(const string & hostname_from)1176 void Manager::SetAcceptHostnameFrom(const string& hostname_from) {
1177   accept_hostname_from_ = hostname_from;
1178 }
1179 
ShouldAcceptHostnameFrom(const string & device_name) const1180 bool Manager::ShouldAcceptHostnameFrom(const string& device_name) const {
1181   return base::MatchPattern(device_name, accept_hostname_from_);
1182 }
1183 
SetDHCPv6EnabledDevices(const vector<string> & device_list)1184 void Manager::SetDHCPv6EnabledDevices(const vector<string>& device_list) {
1185   dhcpv6_enabled_devices_ = device_list;
1186 }
1187 
IsDHCPv6EnabledForDevice(const string & device_name) const1188 bool Manager::IsDHCPv6EnabledForDevice(const string& device_name) const {
1189   return std::find(dhcpv6_enabled_devices_.begin(),
1190                    dhcpv6_enabled_devices_.end(),
1191                    device_name) != dhcpv6_enabled_devices_.end();
1192 }
1193 
FilterPrependDNSServersByFamily(IPAddress::Family family) const1194 vector<string> Manager::FilterPrependDNSServersByFamily(
1195     IPAddress::Family family) const {
1196   vector<string> dns_servers;
1197   vector<string> split_servers = base::SplitString(
1198       props_.prepend_dns_servers, ",", base::TRIM_WHITESPACE,
1199       base::SPLIT_WANT_ALL);
1200   for (const auto& server : split_servers) {
1201     const IPAddress address(server);
1202     if (address.family() == family) {
1203       dns_servers.push_back(server);
1204     }
1205   }
1206   return dns_servers;
1207 }
1208 
IsSuspending()1209 bool Manager::IsSuspending() {
1210   if (power_manager_ && power_manager_->suspending()) {
1211     return true;
1212   }
1213   return false;
1214 }
1215 
RecordDarkResumeWakeReason(const string & wake_reason)1216 void Manager::RecordDarkResumeWakeReason(const string& wake_reason) {
1217   power_manager_->RecordDarkResumeWakeReason(wake_reason);
1218 }
1219 
RegisterDevice(const DeviceRefPtr & to_manage)1220 void Manager::RegisterDevice(const DeviceRefPtr& to_manage) {
1221   LOG(INFO) << "Device " << to_manage->FriendlyName() << " registered.";
1222   // Manager is running in passive mode when default claimer is created, which
1223   // means devices are being managed by remote application. Only manage the
1224   // device if it was explicitly released by remote application through
1225   // default claimer.
1226   if (device_claimer_ && device_claimer_->default_claimer()) {
1227     if (!device_claimer_->IsDeviceReleased(to_manage->link_name())) {
1228       Error error;
1229       device_claimer_->Claim(to_manage->link_name(), &error);
1230       return;
1231     }
1232   }
1233 
1234   for (const auto& device : devices_) {
1235     if (to_manage == device)
1236       return;
1237   }
1238   devices_.push_back(to_manage);
1239 
1240   LoadDeviceFromProfiles(to_manage);
1241 
1242   if (IsTechnologyProhibited(to_manage->technology())) {
1243     Error unused_error;
1244     to_manage->SetEnabledNonPersistent(false, &unused_error, ResultCallback());
1245   }
1246 
1247   // If |to_manage| is new, it needs to be persisted.
1248   UpdateDevice(to_manage);
1249 
1250   // In normal usage, running_ will always be true when we are here, however
1251   // unit tests sometimes do things in otherwise invalid states.
1252   if (running_ && (to_manage->enabled_persistent() ||
1253                    to_manage->IsUnderlyingDeviceEnabled()))
1254     to_manage->SetEnabled(true);
1255 
1256   EmitDeviceProperties();
1257 }
1258 
DeregisterDevice(const DeviceRefPtr & to_forget)1259 void Manager::DeregisterDevice(const DeviceRefPtr& to_forget) {
1260   SLOG(this, 2) << __func__ << "(" << to_forget->FriendlyName() << ")";
1261   for (auto it = devices_.begin(); it != devices_.end(); ++it) {
1262     if (to_forget.get() == it->get()) {
1263       SLOG(this, 2) << "Deregistered device: " << to_forget->UniqueName();
1264       UpdateDevice(to_forget);
1265       to_forget->SetEnabled(false);
1266       devices_.erase(it);
1267       EmitDeviceProperties();
1268       return;
1269     }
1270   }
1271   SLOG(this, 2) << __func__ << " unknown device: "
1272                 << to_forget->UniqueName();
1273 }
1274 
DeregisterDeviceByLinkName(const string & link_name)1275 void Manager::DeregisterDeviceByLinkName(const string& link_name) {
1276   for (const auto& device : devices_) {
1277     if (device->link_name() == link_name) {
1278       DeregisterDevice(device);
1279       break;
1280     }
1281   }
1282 }
1283 
ClaimedDevices(Error * error)1284 vector<string> Manager::ClaimedDevices(Error* error) {
1285   vector<string> results;
1286   if (!device_claimer_) {
1287     return results;
1288   }
1289 
1290   const auto& devices = device_claimer_->claimed_device_names();
1291   results.resize(devices.size());
1292   std::copy(devices.begin(), devices.end(), results.begin());
1293   return results;
1294 }
1295 
LoadDeviceFromProfiles(const DeviceRefPtr & device)1296 void Manager::LoadDeviceFromProfiles(const DeviceRefPtr& device) {
1297   // We are applying device properties from the DefaultProfile, and adding the
1298   // union of hidden services in all loaded profiles to the device.
1299   for (const auto& profile : profiles_) {
1300     // Load device configuration, if any exists, as well as hidden services.
1301     profile->ConfigureDevice(device);
1302   }
1303 }
1304 
EmitDeviceProperties()1305 void Manager::EmitDeviceProperties() {
1306   Error error;
1307   vector<string> device_paths = EnumerateDevices(&error);
1308   adaptor_->EmitRpcIdentifierArrayChanged(kDevicesProperty,
1309                                           device_paths);
1310   adaptor_->EmitStringsChanged(kAvailableTechnologiesProperty,
1311                                AvailableTechnologies(&error));
1312   adaptor_->EmitStringsChanged(kEnabledTechnologiesProperty,
1313                                EnabledTechnologies(&error));
1314   adaptor_->EmitStringsChanged(kUninitializedTechnologiesProperty,
1315                                UninitializedTechnologies(&error));
1316 }
1317 
OnInnerDevicesChanged()1318 void Manager::OnInnerDevicesChanged() {
1319   EmitDeviceProperties();
1320 }
1321 
OnDeviceClaimerVanished()1322 void Manager::OnDeviceClaimerVanished() {
1323   // Reset device claimer.
1324   device_claimer_.reset();
1325 }
1326 
1327 #if !defined(DISABLE_WIFI)
SetDisableWiFiVHT(const bool & disable_wifi_vht,Error * error)1328 bool Manager::SetDisableWiFiVHT(const bool& disable_wifi_vht, Error* error) {
1329   if (disable_wifi_vht == wifi_provider_->disable_vht()) {
1330     return false;
1331   }
1332   wifi_provider_->set_disable_vht(disable_wifi_vht);
1333   return true;
1334 }
1335 
GetDisableWiFiVHT(Error * error)1336 bool Manager::GetDisableWiFiVHT(Error* error) {
1337   return wifi_provider_->disable_vht();
1338 }
1339 #endif  // DISABLE_WIFI
1340 
SetProhibitedTechnologies(const string & prohibited_technologies,Error * error)1341 bool Manager::SetProhibitedTechnologies(const string& prohibited_technologies,
1342                                         Error* error) {
1343   vector<Technology::Identifier> technology_vector;
1344   if (!Technology::GetTechnologyVectorFromString(prohibited_technologies,
1345                                                  &technology_vector,
1346                                                  error)) {
1347     return false;
1348   }
1349   for (const auto& technology : technology_vector) {
1350     Error unused_error(Error::kOperationInitiated);
1351     ResultCallback result_callback(Bind(
1352         &Manager::OnTechnologyProhibited, Unretained(this), technology));
1353     const bool kPersistentSave = false;
1354     SetEnabledStateForTechnology(Technology::NameFromIdentifier(technology),
1355                                  false,
1356                                  kPersistentSave,
1357                                  &unused_error,
1358                                  result_callback);
1359   }
1360   props_.prohibited_technologies = prohibited_technologies;
1361 
1362   return true;
1363 }
1364 
OnTechnologyProhibited(Technology::Identifier technology,const Error & error)1365 void Manager::OnTechnologyProhibited(Technology::Identifier technology,
1366                                      const Error& error) {
1367   SLOG(this, 2) << __func__ << " for "
1368                 << Technology::NameFromIdentifier(technology);
1369 }
1370 
GetProhibitedTechnologies(Error * error)1371 string Manager::GetProhibitedTechnologies(Error* error) {
1372   return props_.prohibited_technologies;
1373 }
1374 
HasService(const ServiceRefPtr & service)1375 bool Manager::HasService(const ServiceRefPtr& service) {
1376   for (const auto& manager_service : services_) {
1377     if (manager_service->unique_name() == service->unique_name())
1378       return true;
1379   }
1380   return false;
1381 }
1382 
RegisterService(const ServiceRefPtr & to_manage)1383 void Manager::RegisterService(const ServiceRefPtr& to_manage) {
1384   SLOG(this, 2) << "Registering service " << to_manage->unique_name();
1385 
1386   MatchProfileWithService(to_manage);
1387 
1388   // Now add to OUR list.
1389   for (const auto& service : services_) {
1390     CHECK(to_manage->unique_name() != service->unique_name());
1391   }
1392   services_.push_back(to_manage);
1393   SortServices();
1394 }
1395 
DeregisterService(const ServiceRefPtr & to_forget)1396 void Manager::DeregisterService(const ServiceRefPtr& to_forget) {
1397   for (auto it = services_.begin(); it != services_.end(); ++it) {
1398     if (to_forget->unique_name() == (*it)->unique_name()) {
1399       DLOG_IF(FATAL, (*it)->connection())
1400           << "Service " << (*it)->unique_name()
1401           << " still has a connection (in call to " << __func__ << ")";
1402       (*it)->Unload();
1403       (*it)->SetProfile(nullptr);
1404       services_.erase(it);
1405       SortServices();
1406       return;
1407     }
1408   }
1409 }
1410 
UnloadService(vector<ServiceRefPtr>::iterator * service_iterator)1411 bool Manager::UnloadService(vector<ServiceRefPtr>::iterator* service_iterator) {
1412   if (!(**service_iterator)->Unload()) {
1413     return false;
1414   }
1415 
1416   DCHECK(!(**service_iterator)->connection());
1417   (**service_iterator)->SetProfile(nullptr);
1418   *service_iterator = services_.erase(*service_iterator);
1419 
1420   return true;
1421 }
1422 
UpdateService(const ServiceRefPtr & to_update)1423 void Manager::UpdateService(const ServiceRefPtr& to_update) {
1424   CHECK(to_update);
1425   bool is_interesting_state_change = false;
1426   const auto& state_it = watched_service_states_.find(to_update->unique_name());
1427   if (state_it != watched_service_states_.end()) {
1428     is_interesting_state_change = (to_update->state() != state_it->second);
1429   } else {
1430     is_interesting_state_change = to_update->IsActive(nullptr);
1431   }
1432 
1433   string log_message = StringPrintf(
1434       "Service %s updated; state: %s failure %s",
1435       to_update->unique_name().c_str(),
1436       Service::ConnectStateToString(to_update->state()),
1437       Service::ConnectFailureToString(to_update->failure()));
1438   if (is_interesting_state_change) {
1439     LOG(INFO) << log_message;
1440   } else {
1441     SLOG(this, 2) << log_message;
1442   }
1443   SLOG(this, 2) << "IsConnected(): " << to_update->IsConnected();
1444   SLOG(this, 2) << "IsConnecting(): " << to_update->IsConnecting();
1445   if (to_update->IsConnected()) {
1446     to_update->EnableAndRetainAutoConnect();
1447     // Persists the updated auto_connect setting in the profile.
1448     SaveServiceToProfile(to_update);
1449   }
1450   SortServices();
1451 }
1452 
UpdateDevice(const DeviceRefPtr & to_update)1453 void Manager::UpdateDevice(const DeviceRefPtr& to_update) {
1454   LOG(INFO) << "Device " << to_update->link_name() << " updated: "
1455             << (to_update->enabled_persistent() ? "enabled" : "disabled");
1456   // Saves the device to the topmost profile that accepts it (ordinary
1457   // profiles don't update but default profiles do). Normally, the topmost
1458   // updating profile would be the DefaultProfile at the bottom of the stack.
1459   // Autotests, differ from the normal scenario, however, in that they push a
1460   // second test-only DefaultProfile.
1461   for (auto rit = profiles_.rbegin(); rit != profiles_.rend(); ++rit) {
1462     if ((*rit)->UpdateDevice(to_update)) {
1463       return;
1464     }
1465   }
1466 }
1467 
1468 #if !defined(DISABLE_WIFI)
UpdateWiFiProvider()1469 void Manager::UpdateWiFiProvider() {
1470   // Saves |wifi_provider_| to the topmost profile that accepts it (ordinary
1471   // profiles don't update but default profiles do). Normally, the topmost
1472   // updating profile would be the DefaultProfile at the bottom of the stack.
1473   // Autotests, differ from the normal scenario, however, in that they push a
1474   // second test-only DefaultProfile.
1475   for (auto rit = profiles_.rbegin(); rit != profiles_.rend(); ++rit) {
1476     if ((*rit)->UpdateWiFiProvider(*wifi_provider_)) {
1477       return;
1478     }
1479   }
1480 }
1481 #endif  // DISABLE_WIFI
1482 
SaveServiceToProfile(const ServiceRefPtr & to_update)1483 void Manager::SaveServiceToProfile(const ServiceRefPtr& to_update) {
1484   if (IsServiceEphemeral(to_update)) {
1485     if (profiles_.empty()) {
1486       LOG(ERROR) << "Cannot assign profile to service: no profiles exist!";
1487     } else {
1488       MoveServiceToProfile(to_update, profiles_.back());
1489     }
1490   } else {
1491     to_update->profile()->UpdateService(to_update);
1492   }
1493 }
1494 
LoadProperties(const scoped_refptr<DefaultProfile> & profile)1495 void Manager::LoadProperties(const scoped_refptr<DefaultProfile>& profile) {
1496   profile->LoadManagerProperties(&props_, dhcp_properties_.get());
1497   SetIgnoredDNSSearchPaths(props_.ignored_dns_search_paths, nullptr);
1498 }
1499 
AddTerminationAction(const string & name,const base::Closure & start)1500 void Manager::AddTerminationAction(const string& name,
1501                                    const base::Closure& start) {
1502   termination_actions_.Add(name, start);
1503 }
1504 
TerminationActionComplete(const string & name)1505 void Manager::TerminationActionComplete(const string& name) {
1506   SLOG(this, 2) << __func__;
1507   termination_actions_.ActionComplete(name);
1508 }
1509 
RemoveTerminationAction(const string & name)1510 void Manager::RemoveTerminationAction(const string& name) {
1511   SLOG(this, 2) << __func__;
1512   termination_actions_.Remove(name);
1513 }
1514 
RunTerminationActions(const ResultCallback & done_callback)1515 void Manager::RunTerminationActions(const ResultCallback& done_callback) {
1516   LOG(INFO) << "Running termination actions.";
1517   termination_actions_.Run(kTerminationActionsTimeoutMilliseconds,
1518                            done_callback);
1519 }
1520 
RunTerminationActionsAndNotifyMetrics(const ResultCallback & done_callback)1521 bool Manager::RunTerminationActionsAndNotifyMetrics(
1522     const ResultCallback& done_callback) {
1523   if (termination_actions_.IsEmpty())
1524     return false;
1525 
1526   metrics_->NotifyTerminationActionsStarted();
1527   RunTerminationActions(done_callback);
1528   return true;
1529 }
1530 
RegisterDefaultServiceCallback(const ServiceCallback & callback)1531 int Manager::RegisterDefaultServiceCallback(const ServiceCallback& callback) {
1532   default_service_callbacks_[++default_service_callback_tag_] = callback;
1533   return default_service_callback_tag_;
1534 }
1535 
DeregisterDefaultServiceCallback(int tag)1536 void Manager::DeregisterDefaultServiceCallback(int tag) {
1537   default_service_callbacks_.erase(tag);
1538 }
1539 
1540 #if !defined(DISABLE_WIFI)
VerifyDestination(const string & certificate,const string & public_key,const string & nonce,const string & signed_data,const string & destination_udn,const string & hotspot_ssid,const string & hotspot_bssid,const ResultBoolCallback & cb,Error * error)1541 void Manager::VerifyDestination(const string& certificate,
1542                                 const string& public_key,
1543                                 const string& nonce,
1544                                 const string& signed_data,
1545                                 const string& destination_udn,
1546                                 const string& hotspot_ssid,
1547                                 const string& hotspot_bssid,
1548                                 const ResultBoolCallback& cb,
1549                                 Error* error) {
1550   if (hotspot_bssid.length() > 32) {
1551     error->Populate(Error::kOperationFailed,
1552                     "Invalid SSID given for verification.");
1553     return;
1554   }
1555   vector<uint8_t> ssid;
1556   string bssid;
1557   if (hotspot_ssid.length() || hotspot_bssid.length()) {
1558     // If Chrome thinks this destination is already configured, service
1559     // will be an AP that both we and the destination are connected
1560     // to, and not the thing we should verify against.
1561     ssid.assign(hotspot_ssid.begin(), hotspot_ssid.end());
1562     bssid = hotspot_bssid;
1563   } else {
1564     // For now, we only support a single connected WiFi service.  If we change
1565     // that, we'll need to revisit this.
1566     bool found_one = false;
1567     for (const auto& service : services_) {
1568       if (service->technology() == Technology::kWifi &&
1569           service->IsConnected()) {
1570         WiFiService* wifi = reinterpret_cast<WiFiService*>(&(*service));
1571         bssid = wifi->bssid();
1572         ssid = wifi->ssid();
1573         found_one = true;
1574         break;
1575       }
1576     }
1577     if (!found_one) {
1578       error->Populate(Error::kOperationFailed,
1579                       "Unable to find connected WiFi service.");
1580       return;
1581     }
1582   }
1583   crypto_util_proxy_->VerifyDestination(certificate, public_key, nonce,
1584                                         signed_data, destination_udn,
1585                                         ssid, bssid, cb, error);
1586 }
1587 
VerifyToEncryptLink(string public_key,string data,ResultStringCallback cb,const Error & error,bool success)1588 void Manager::VerifyToEncryptLink(string public_key,
1589                                   string data,
1590                                   ResultStringCallback cb,
1591                                   const Error& error,
1592                                   bool success) {
1593   if (!success || !error.IsSuccess()) {
1594     CHECK(error.IsFailure()) << "Return code from CryptoUtilProxy "
1595                              << "inconsistent with error code.";
1596     cb.Run(error, "");
1597     return;
1598   }
1599   Error encrypt_error;
1600   if (!crypto_util_proxy_->EncryptData(public_key, data, cb, &encrypt_error)) {
1601     CHECK(encrypt_error.IsFailure()) << "CryptoUtilProxy::EncryptData returned "
1602                                      << "inconsistently.";
1603     cb.Run(encrypt_error, "");
1604   }
1605 }
1606 
VerifyAndEncryptData(const string & certificate,const string & public_key,const string & nonce,const string & signed_data,const string & destination_udn,const string & hotspot_ssid,const string & hotspot_bssid,const string & data,const ResultStringCallback & cb,Error * error)1607 void Manager::VerifyAndEncryptData(const string& certificate,
1608                                    const string& public_key,
1609                                    const string& nonce,
1610                                    const string& signed_data,
1611                                    const string& destination_udn,
1612                                    const string& hotspot_ssid,
1613                                    const string& hotspot_bssid,
1614                                    const string& data,
1615                                    const ResultStringCallback& cb,
1616                                    Error* error) {
1617   ResultBoolCallback on_verification_success = Bind(
1618       &Manager::VerifyToEncryptLink, AsWeakPtr(), public_key, data, cb);
1619   VerifyDestination(certificate, public_key, nonce, signed_data,
1620                     destination_udn, hotspot_ssid, hotspot_bssid,
1621                     on_verification_success, error);
1622 }
1623 
VerifyAndEncryptCredentials(const string & certificate,const string & public_key,const string & nonce,const string & signed_data,const string & destination_udn,const string & hotspot_ssid,const string & hotspot_bssid,const string & network_path,const ResultStringCallback & cb,Error * error)1624 void Manager::VerifyAndEncryptCredentials(const string& certificate,
1625                                           const string& public_key,
1626                                           const string& nonce,
1627                                           const string& signed_data,
1628                                           const string& destination_udn,
1629                                           const string& hotspot_ssid,
1630                                           const string& hotspot_bssid,
1631                                           const string& network_path,
1632                                           const ResultStringCallback& cb,
1633                                           Error* error) {
1634   // This is intentionally left unimplemented until we have a security review.
1635   error->Populate(Error::kNotImplemented, "Not implemented");
1636 }
1637 #endif  // DISABLE_WIFI
1638 
CalcConnectionId(std::string gateway_ip,std::string gateway_mac)1639 int Manager::CalcConnectionId(std::string gateway_ip,
1640                               std::string gateway_mac) {
1641   return static_cast<int>(std::hash<std::string>()(gateway_ip + gateway_mac +
1642       std::to_string(props_.connection_id_salt)));
1643 }
1644 
ReportServicesOnSameNetwork(int connection_id)1645 void Manager::ReportServicesOnSameNetwork(int connection_id) {
1646   int num_services = 0;
1647   for (const auto& service : services_) {
1648     if (service->connection_id() == connection_id) {
1649       num_services++;
1650     }
1651   }
1652   metrics_->NotifyServicesOnSameNetwork(num_services);
1653 }
1654 
NotifyDefaultServiceChanged(const ServiceRefPtr & service)1655 void Manager::NotifyDefaultServiceChanged(const ServiceRefPtr& service) {
1656   for (const auto& callback : default_service_callbacks_) {
1657     callback.second.Run(service);
1658   }
1659   metrics_->NotifyDefaultServiceChanged(service.get());
1660   EmitDefaultService();
1661 }
1662 
EmitDefaultService()1663 void Manager::EmitDefaultService() {
1664   RpcIdentifier rpc_identifier = GetDefaultServiceRpcIdentifier(nullptr);
1665   if (rpc_identifier != default_service_rpc_identifier_) {
1666     adaptor_->EmitRpcIdentifierChanged(kDefaultServiceProperty, rpc_identifier);
1667     default_service_rpc_identifier_ = rpc_identifier;
1668   }
1669 }
1670 
OnSuspendImminent()1671 void Manager::OnSuspendImminent() {
1672   metrics_->NotifySuspendActionsStarted();
1673   if (devices_.empty()) {
1674     // If there are no devices, then suspend actions succeeded synchronously.
1675     // Make a call to the Manager::OnSuspendActionsComplete directly, since
1676     // result_aggregator will not.
1677     OnSuspendActionsComplete(Error(Error::kSuccess));
1678     return;
1679   }
1680   auto result_aggregator(make_scoped_refptr(new ResultAggregator(
1681       Bind(&Manager::OnSuspendActionsComplete, AsWeakPtr()), dispatcher_,
1682       kTerminationActionsTimeoutMilliseconds)));
1683   for (const auto& device : devices_) {
1684     ResultCallback aggregator_callback(
1685         Bind(&ResultAggregator::ReportResult, result_aggregator));
1686     device->OnBeforeSuspend(aggregator_callback);
1687   }
1688 }
1689 
OnSuspendDone()1690 void Manager::OnSuspendDone() {
1691   metrics_->NotifySuspendDone();
1692   // Un-suppress auto-connect in case this flag was left set in dark resume.
1693   set_suppress_autoconnect(false);
1694   for (const auto& service : services_) {
1695     service->OnAfterResume();
1696   }
1697   SortServices();
1698   for (const auto& device : devices_) {
1699     device->OnAfterResume();
1700   }
1701 }
1702 
OnDarkSuspendImminent()1703 void Manager::OnDarkSuspendImminent() {
1704   metrics_->NotifyDarkResumeActionsStarted();
1705   if (devices_.empty()) {
1706     // If there are no devices, then suspend actions succeeded synchronously.
1707     // Make a call to the Manager::OnDarkResumeActionsComplete directly, since
1708     // result_aggregator will not.
1709     OnDarkResumeActionsComplete(Error(Error::kSuccess));
1710     return;
1711   }
1712   auto result_aggregator(make_scoped_refptr(new ResultAggregator(
1713       Bind(&Manager::OnDarkResumeActionsComplete, AsWeakPtr()), dispatcher_,
1714       kTerminationActionsTimeoutMilliseconds)));
1715   for (const auto& device : devices_) {
1716     ResultCallback aggregator_callback(
1717         Bind(&ResultAggregator::ReportResult, result_aggregator));
1718     device->OnDarkResume(aggregator_callback);
1719   }
1720 }
1721 
OnSuspendActionsComplete(const Error & error)1722 void Manager::OnSuspendActionsComplete(const Error& error) {
1723   LOG(INFO) << "Finished suspend actions. Result: " << error;
1724   metrics_->NotifySuspendActionsCompleted(error.IsSuccess());
1725   power_manager_->ReportSuspendReadiness();
1726 }
1727 
OnDarkResumeActionsComplete(const Error & error)1728 void Manager::OnDarkResumeActionsComplete(const Error& error) {
1729   LOG(INFO) << "Finished dark resume actions. Result: " << error;
1730   metrics_->NotifyDarkResumeActionsCompleted(error.IsSuccess());
1731   power_manager_->ReportDarkSuspendReadiness();
1732 }
1733 
1734 
1735 vector<DeviceRefPtr>
FilterByTechnology(Technology::Identifier tech) const1736 Manager::FilterByTechnology(Technology::Identifier tech) const {
1737   vector<DeviceRefPtr> found;
1738   for (const auto& device : devices_) {
1739     if (device->technology() == tech)
1740       found.push_back(device);
1741   }
1742   return found;
1743 }
1744 
FindService(const string & name)1745 ServiceRefPtr Manager::FindService(const string& name) {
1746   for (const auto& service : services_) {
1747     if (name == service->unique_name())
1748       return service;
1749   }
1750   return nullptr;
1751 }
1752 
HelpRegisterConstDerivedRpcIdentifier(const string & name,RpcIdentifier (Manager::* get)(Error * error))1753 void Manager::HelpRegisterConstDerivedRpcIdentifier(
1754     const string& name,
1755     RpcIdentifier(Manager::*get)(Error* error)) {
1756   store_.RegisterDerivedRpcIdentifier(
1757       name,
1758       RpcIdentifierAccessor(
1759           new CustomAccessor<Manager, RpcIdentifier>(this, get, nullptr)));
1760 }
1761 
HelpRegisterConstDerivedRpcIdentifiers(const string & name,RpcIdentifiers (Manager::* get)(Error * error))1762 void Manager::HelpRegisterConstDerivedRpcIdentifiers(
1763     const string& name,
1764     RpcIdentifiers(Manager::*get)(Error* error)) {
1765   store_.RegisterDerivedRpcIdentifiers(
1766       name,
1767       RpcIdentifiersAccessor(
1768           new CustomAccessor<Manager, RpcIdentifiers>(this, get, nullptr)));
1769 }
1770 
HelpRegisterDerivedString(const string & name,string (Manager::* get)(Error * error),bool (Manager::* set)(const string &,Error *))1771 void Manager::HelpRegisterDerivedString(
1772     const string& name,
1773     string(Manager::*get)(Error* error),
1774     bool(Manager::*set)(const string&, Error*)) {
1775   store_.RegisterDerivedString(
1776       name,
1777       StringAccessor(new CustomAccessor<Manager, string>(this, get, set)));
1778 }
1779 
HelpRegisterConstDerivedStrings(const string & name,Strings (Manager::* get)(Error *))1780 void Manager::HelpRegisterConstDerivedStrings(
1781     const string& name,
1782     Strings(Manager::*get)(Error*)) {
1783   store_.RegisterDerivedStrings(
1784       name, StringsAccessor(
1785                 new CustomAccessor<Manager, Strings>(this, get, nullptr)));
1786 }
1787 
HelpRegisterDerivedBool(const string & name,bool (Manager::* get)(Error * error),bool (Manager::* set)(const bool &,Error *))1788 void Manager::HelpRegisterDerivedBool(
1789     const string& name,
1790     bool(Manager::*get)(Error* error),
1791     bool(Manager::*set)(const bool&, Error*)) {
1792   store_.RegisterDerivedBool(
1793       name,
1794       BoolAccessor(new CustomAccessor<Manager, bool>(this, get, set, nullptr)));
1795 }
1796 
SortServices()1797 void Manager::SortServices() {
1798   // We might be called in the middle of a series of events that
1799   // may result in multiple calls to Manager::SortServices, or within
1800   // an outer loop that may also be traversing the services_ list.
1801   // Defer this work to the event loop.
1802   if (sort_services_task_.IsCancelled()) {
1803     sort_services_task_.Reset(Bind(&Manager::SortServicesTask, AsWeakPtr()));
1804     dispatcher_->PostTask(sort_services_task_.callback());
1805   }
1806 }
1807 
SortServicesTask()1808 void Manager::SortServicesTask() {
1809   SLOG(this, 4) << "In " << __func__;
1810   sort_services_task_.Cancel();
1811   ServiceRefPtr default_service;
1812 
1813   if (!services_.empty()) {
1814     // Keep track of the service that is the candidate for the default
1815     // service.  We have not yet tested to see if this service has a
1816     // connection.
1817     default_service = services_[0];
1818   }
1819   const bool kCompareConnectivityState = true;
1820   sort(services_.begin(), services_.end(),
1821        ServiceSorter(this, kCompareConnectivityState, technology_order_));
1822 
1823   if (!services_.empty()) {
1824     ConnectionRefPtr default_connection = default_service->connection();
1825     if (default_connection &&
1826         services_[0]->connection() != default_connection) {
1827       default_connection->SetIsDefault(false);
1828     }
1829     if (services_[0]->connection()) {
1830       services_[0]->connection()->SetIsDefault(true);
1831       if (default_service != services_[0]) {
1832         default_service = services_[0];
1833         LOG(INFO) << "Default service is now "
1834                   << default_service->unique_name();
1835       }
1836     } else {
1837       default_service = nullptr;
1838     }
1839   }
1840 
1841   Error error;
1842   adaptor_->EmitRpcIdentifierArrayChanged(kServiceCompleteListProperty,
1843                                           EnumerateCompleteServices(nullptr));
1844   adaptor_->EmitRpcIdentifierArrayChanged(kServicesProperty,
1845                                           EnumerateAvailableServices(nullptr));
1846   adaptor_->EmitRpcIdentifierArrayChanged(kServiceWatchListProperty,
1847                                           EnumerateWatchedServices(nullptr));
1848   adaptor_->EmitStringsChanged(kConnectedTechnologiesProperty,
1849                                ConnectedTechnologies(&error));
1850   adaptor_->EmitStringChanged(kDefaultTechnologyProperty,
1851                               DefaultTechnology(&error));
1852   NotifyDefaultServiceChanged(default_service);
1853   RefreshConnectionState();
1854   DetectMultiHomedDevices();
1855 
1856   AutoConnect();
1857 }
1858 
DeviceStatusCheckTask()1859 void Manager::DeviceStatusCheckTask() {
1860   SLOG(this, 4) << "In " << __func__;
1861 
1862   ConnectionStatusCheck();
1863   DevicePresenceStatusCheck();
1864 
1865   dispatcher_->PostDelayedTask(device_status_check_task_.callback(),
1866                                kDeviceStatusCheckIntervalMilliseconds);
1867 }
1868 
ConnectionStatusCheck()1869 void Manager::ConnectionStatusCheck() {
1870   SLOG(this, 4) << "In " << __func__;
1871   // Report current connection status.
1872   Metrics::ConnectionStatus status = Metrics::kConnectionStatusOffline;
1873   if (IsConnected()) {
1874     status = Metrics::kConnectionStatusConnected;
1875     // Check if device is online as well.
1876     if (IsOnline()) {
1877       metrics_->NotifyDeviceConnectionStatus(Metrics::kConnectionStatusOnline);
1878     }
1879   }
1880   metrics_->NotifyDeviceConnectionStatus(status);
1881 }
1882 
DevicePresenceStatusCheck()1883 void Manager::DevicePresenceStatusCheck() {
1884   Error error;
1885   vector<string> available_technologies = AvailableTechnologies(&error);
1886 
1887   for (const auto& technology : kProbeTechnologies) {
1888     bool presence = std::find(available_technologies.begin(),
1889                               available_technologies.end(),
1890                               technology) != available_technologies.end();
1891     metrics_->NotifyDevicePresenceStatus(
1892         Technology::IdentifierFromName(technology), presence);
1893   }
1894 }
1895 
MatchProfileWithService(const ServiceRefPtr & service)1896 bool Manager::MatchProfileWithService(const ServiceRefPtr& service) {
1897   vector<ProfileRefPtr>::reverse_iterator it;
1898   for (it = profiles_.rbegin(); it != profiles_.rend(); ++it) {
1899     if ((*it)->ConfigureService(service)) {
1900       break;
1901     }
1902   }
1903   if (it == profiles_.rend()) {
1904     ephemeral_profile_->AdoptService(service);
1905     return false;
1906   }
1907   return true;
1908 }
1909 
AutoConnect()1910 void Manager::AutoConnect() {
1911   if (suppress_autoconnect_) {
1912     LOG(INFO) << "Auto-connect suppressed -- explicitly suppressed.";
1913     return;
1914   }
1915   if (!running_) {
1916     LOG(INFO) << "Auto-connect suppressed -- not running.";
1917     return;
1918   }
1919   if (power_manager_ && power_manager_->suspending() &&
1920       !power_manager_->in_dark_resume()) {
1921     LOG(INFO) << "Auto-connect suppressed -- system is suspending.";
1922     return;
1923   }
1924   if (services_.empty()) {
1925     LOG(INFO) << "Auto-connect suppressed -- no services.";
1926     return;
1927   }
1928 
1929   if (SLOG_IS_ON(Manager, 4)) {
1930     SLOG(this, 4) << "Sorted service list for AutoConnect: ";
1931     for (size_t i = 0; i < services_.size(); ++i) {
1932       ServiceRefPtr service = services_[i];
1933       const char* compare_reason = nullptr;
1934       if (i + 1 < services_.size()) {
1935         const bool kCompareConnectivityState = true;
1936         Service::Compare(
1937             this, service, services_[i+1], kCompareConnectivityState,
1938             technology_order_, &compare_reason);
1939       } else {
1940         compare_reason = "last";
1941       }
1942       SLOG(this, 4) << "Service " << service->unique_name()
1943                     << " Profile: " << service->profile()->GetFriendlyName()
1944                     << " IsConnected: " << service->IsConnected()
1945                     << " IsConnecting: " << service->IsConnecting()
1946                     << " HasEverConnected: " << service->has_ever_connected()
1947                     << " IsFailed: " << service->IsFailed()
1948                     << " connectable: " << service->connectable()
1949                     << " auto_connect: " << service->auto_connect()
1950                     << " retain_auto_connect: "
1951                     << service->retain_auto_connect()
1952                     << " priority: " << service->priority()
1953                     << " crypto_algorithm: " << service->crypto_algorithm()
1954                     << " key_rotation: " << service->key_rotation()
1955                     << " endpoint_auth: " << service->endpoint_auth()
1956                     << " strength: " << service->strength()
1957                     << " sorted: " << compare_reason;
1958     }
1959   }
1960 
1961 #if !defined(DISABLE_WIFI)
1962   // Report the number of auto-connectable wifi services available when wifi is
1963   // idle (no active or pending connection), which will trigger auto connect
1964   // for wifi services.
1965   if (IsWifiIdle()) {
1966     wifi_provider_->ReportAutoConnectableServices();
1967   }
1968 #endif  // DISABLE_WIFI
1969 
1970   // Perform auto-connect.
1971   for (const auto& service : services_) {
1972     if (service->auto_connect()) {
1973       service->AutoConnect();
1974     }
1975   }
1976 }
1977 
ConnectToBestServices(Error *)1978 void Manager::ConnectToBestServices(Error* /*error*/) {
1979   dispatcher_->PostTask(Bind(&Manager::ConnectToBestServicesTask, AsWeakPtr()));
1980 }
1981 
ConnectToBestServicesTask()1982 void Manager::ConnectToBestServicesTask() {
1983   vector<ServiceRefPtr> services_copy = services_;
1984   const bool kCompareConnectivityState = false;
1985   sort(services_copy.begin(), services_copy.end(),
1986        ServiceSorter(this, kCompareConnectivityState, technology_order_));
1987   set<Technology::Identifier> connecting_technologies;
1988   for (const auto& service : services_copy) {
1989     if (!service->connectable()) {
1990       // Due to service sort order, it is guaranteed that no services beyond
1991       // this one will be connectable either.
1992       break;
1993     }
1994     if (!service->auto_connect() || !service->IsVisible()) {
1995       continue;
1996     }
1997     Technology::Identifier technology = service->technology();
1998     if (!Technology::IsPrimaryConnectivityTechnology(technology) &&
1999         !IsConnected()) {
2000       // Non-primary services need some other service connected first.
2001       continue;
2002     }
2003     if (ContainsKey(connecting_technologies, technology)) {
2004       // We have already started a connection for this technology.
2005       continue;
2006     }
2007     if (service->explicitly_disconnected())
2008       continue;
2009     connecting_technologies.insert(technology);
2010     if (!service->IsConnected() && !service->IsConnecting()) {
2011       // At first blush, it may seem that using Service::AutoConnect might
2012       // be the right choice, however Service::IsAutoConnectable and its
2013       // overridden implementations consider a host of conditions which
2014       // prevent it from attempting a connection which we'd like to ignore
2015       // for the purposes of this user-initiated action.
2016       Error error;
2017       service->Connect(&error, __func__);
2018       if (error.IsFailure()) {
2019         LOG(ERROR) << "Connection failed: " << error.message();
2020       }
2021     }
2022   }
2023 
2024   if (SLOG_IS_ON(Manager, 4)) {
2025     SLOG(this, 4) << "Sorted service list for ConnectToBestServicesTask: ";
2026     for (size_t i = 0; i < services_copy.size(); ++i) {
2027       ServiceRefPtr service = services_copy[i];
2028       const char* compare_reason = nullptr;
2029       if (i + 1 < services_copy.size()) {
2030         if (!service->connectable()) {
2031           // Due to service sort order, it is guaranteed that no services beyond
2032           // this one are connectable either.
2033           break;
2034         }
2035         Service::Compare(
2036             this, service, services_copy[i+1],
2037             kCompareConnectivityState, technology_order_,
2038             &compare_reason);
2039       } else {
2040         compare_reason = "last";
2041       }
2042       SLOG(this, 4) << "Service " << service->unique_name()
2043                     << " Profile: " << service->profile()->GetFriendlyName()
2044                     << " IsConnected: " << service->IsConnected()
2045                     << " IsConnecting: " << service->IsConnecting()
2046                     << " HasEverConnected: " << service->has_ever_connected()
2047                     << " IsFailed: " << service->IsFailed()
2048                     << " connectable: " << service->connectable()
2049                     << " auto_connect: " << service->auto_connect()
2050                     << " retain_auto_connect: "
2051                     << service->retain_auto_connect()
2052                     << " priority: " << service->priority()
2053                     << " crypto_algorithm: " << service->crypto_algorithm()
2054                     << " key_rotation: " << service->key_rotation()
2055                     << " endpoint_auth: " << service->endpoint_auth()
2056                     << " strength: " << service->strength()
2057                     << " sorted: " << compare_reason;
2058     }
2059   }
2060 }
2061 
CreateConnectivityReport(Error *)2062 void Manager::CreateConnectivityReport(Error* /*error*/) {
2063   LOG(INFO) << "Creating Connectivity Report";
2064 
2065   // For each of the connected services, perform a single portal detection
2066   // test to assess connectivity.  The results should be written to the log.
2067   for (const auto& service : services_) {
2068     if (!service->IsConnected()) {
2069       // Service sort order guarantees that no service beyond this one will be
2070       // connected either.
2071       break;
2072     }
2073     // Get the underlying device for this service and perform connectivity test.
2074     for (const auto& device : devices_) {
2075       if (device->IsConnectedToService(service)) {
2076         if (device->StartConnectivityTest()) {
2077           SLOG(this, 3) << "Started connectivity test for service "
2078                         << service->unique_name();
2079         } else {
2080           SLOG(this, 3) << "Failed to start connectivity test for service "
2081                         << service->unique_name()
2082                            << " device not reporting IsConnected.";
2083         }
2084         break;
2085       }
2086     }
2087   }
2088 }
2089 
IsConnected() const2090 bool Manager::IsConnected() const {
2091   // |services_| is sorted such that connected services are first.
2092   return !services_.empty() && services_.front()->IsConnected();
2093 }
2094 
IsOnline() const2095 bool Manager::IsOnline() const {
2096   // |services_| is sorted such that online services are first.
2097   return !services_.empty() && services_.front()->IsOnline();
2098 }
2099 
CalculateState(Error *)2100 string Manager::CalculateState(Error* /*error*/) {
2101   return IsConnected() ? kStateOnline : kStateOffline;
2102 }
2103 
RefreshConnectionState()2104 void Manager::RefreshConnectionState() {
2105   const ServiceRefPtr& service = GetDefaultService();
2106   string connection_state = service ? service->GetStateString() : kStateIdle;
2107   if (connection_state_ == connection_state) {
2108     return;
2109   }
2110   connection_state_ = connection_state;
2111   adaptor_->EmitStringChanged(kConnectionStateProperty, connection_state_);
2112   // Send upstart notifications for the initial idle state
2113   // and when we transition in/out of connected states.
2114   if ((!is_connected_state_) && (IsConnected())) {
2115       is_connected_state_ = true;
2116       upstart_->NotifyConnected();
2117   } else if ((is_connected_state_) && (!IsConnected())) {
2118       is_connected_state_ = false;
2119       upstart_->NotifyDisconnected();
2120   } else if (connection_state_ == kStateIdle) {
2121       upstart_->NotifyDisconnected();
2122   }
2123 }
2124 
AvailableTechnologies(Error *)2125 vector<string> Manager::AvailableTechnologies(Error* /*error*/) {
2126   set<string> unique_technologies;
2127   for (const auto& device : devices_) {
2128     unique_technologies.insert(
2129         Technology::NameFromIdentifier(device->technology()));
2130   }
2131   return vector<string>(unique_technologies.begin(), unique_technologies.end());
2132 }
2133 
ConnectedTechnologies(Error *)2134 vector<string> Manager::ConnectedTechnologies(Error* /*error*/) {
2135   set<string> unique_technologies;
2136   for (const auto& device : devices_) {
2137     if (device->IsConnected())
2138       unique_technologies.insert(
2139           Technology::NameFromIdentifier(device->technology()));
2140   }
2141   return vector<string>(unique_technologies.begin(), unique_technologies.end());
2142 }
2143 
IsTechnologyConnected(Technology::Identifier technology) const2144 bool Manager::IsTechnologyConnected(Technology::Identifier technology) const {
2145   for (const auto& device : devices_) {
2146     if (device->technology() == technology && device->IsConnected())
2147       return true;
2148   }
2149   return false;
2150 }
2151 
DefaultTechnology(Error *)2152 string Manager::DefaultTechnology(Error* /*error*/) {
2153   return (!services_.empty() && services_[0]->IsConnected()) ?
2154       services_[0]->GetTechnologyString() : "";
2155 }
2156 
EnabledTechnologies(Error *)2157 vector<string> Manager::EnabledTechnologies(Error* /*error*/) {
2158   set<string> unique_technologies;
2159   for (const auto& device : devices_) {
2160     if (device->enabled())
2161       unique_technologies.insert(
2162           Technology::NameFromIdentifier(device->technology()));
2163   }
2164   return vector<string>(unique_technologies.begin(), unique_technologies.end());
2165 }
2166 
UninitializedTechnologies(Error *)2167 vector<string> Manager::UninitializedTechnologies(Error* /*error*/) {
2168   return device_info_.GetUninitializedTechnologies();
2169 }
2170 
EnumerateDevices(Error *)2171 RpcIdentifiers Manager::EnumerateDevices(Error* /*error*/) {
2172   RpcIdentifiers device_rpc_ids;
2173   for (const auto& device : devices_) {
2174     device_rpc_ids.push_back(device->GetRpcIdentifier());
2175   }
2176   // Enumerate devices that are internal to the services, such as PPPoE devices.
2177   for (const auto& service : services_) {
2178     if (!service->GetInnerDeviceRpcIdentifier().empty()) {
2179       device_rpc_ids.push_back(service->GetInnerDeviceRpcIdentifier());
2180     }
2181   }
2182   return device_rpc_ids;
2183 }
2184 
EnumerateProfiles(Error *)2185 RpcIdentifiers Manager::EnumerateProfiles(Error* /*error*/) {
2186   RpcIdentifiers profile_rpc_ids;
2187   for (const auto& profile : profiles_) {
2188     profile_rpc_ids.push_back(profile->GetRpcIdentifier());
2189   }
2190   return profile_rpc_ids;
2191 }
2192 
EnumerateAvailableServices(Error *)2193 RpcIdentifiers Manager::EnumerateAvailableServices(Error* /*error*/) {
2194   RpcIdentifiers service_rpc_ids;
2195   for (const auto& service : services_) {
2196     if (service->IsVisible()) {
2197       service_rpc_ids.push_back(service->GetRpcIdentifier());
2198     }
2199   }
2200   return service_rpc_ids;
2201 }
2202 
EnumerateCompleteServices(Error *)2203 RpcIdentifiers Manager::EnumerateCompleteServices(Error* /*error*/) {
2204   RpcIdentifiers service_rpc_ids;
2205   for (const auto& service : services_) {
2206     service_rpc_ids.push_back(service->GetRpcIdentifier());
2207   }
2208   return service_rpc_ids;
2209 }
2210 
EnumerateWatchedServices(Error *)2211 RpcIdentifiers Manager::EnumerateWatchedServices(Error* /*error*/) {
2212   RpcIdentifiers service_rpc_ids;
2213   watched_service_states_.clear();
2214   for (const auto& service : services_) {
2215     if (service->IsVisible() && service->IsActive(nullptr)) {
2216       service_rpc_ids.push_back(service->GetRpcIdentifier());
2217       watched_service_states_[service->unique_name()] = service->state();
2218     }
2219   }
2220   return service_rpc_ids;
2221 }
2222 
GetActiveProfileRpcIdentifier(Error *)2223 string Manager::GetActiveProfileRpcIdentifier(Error* /*error*/) {
2224   return ActiveProfile()->GetRpcIdentifier();
2225 }
2226 
GetCheckPortalList(Error *)2227 string Manager::GetCheckPortalList(Error* /*error*/) {
2228   return use_startup_portal_list_ ? startup_portal_list_ :
2229       props_.check_portal_list;
2230 }
2231 
SetCheckPortalList(const string & portal_list,Error * error)2232 bool Manager::SetCheckPortalList(const string& portal_list, Error* error) {
2233   use_startup_portal_list_ = false;
2234   if (props_.check_portal_list == portal_list) {
2235     return false;
2236   }
2237   props_.check_portal_list = portal_list;
2238   return true;
2239 }
2240 
GetIgnoredDNSSearchPaths(Error *)2241 string Manager::GetIgnoredDNSSearchPaths(Error* /*error*/) {
2242   return props_.ignored_dns_search_paths;
2243 }
2244 
SetIgnoredDNSSearchPaths(const string & ignored_paths,Error *)2245 bool Manager::SetIgnoredDNSSearchPaths(const string& ignored_paths,
2246                                        Error* /*error*/) {
2247   if (props_.ignored_dns_search_paths == ignored_paths) {
2248     return false;
2249   }
2250   vector<string> ignored_path_list;
2251   if (!ignored_paths.empty()) {
2252     ignored_path_list = base::SplitString(
2253         ignored_paths, ",", base::TRIM_WHITESPACE, base::SPLIT_WANT_ALL);
2254   }
2255   props_.ignored_dns_search_paths = ignored_paths;
2256   resolver_->set_ignored_search_list(ignored_path_list);
2257   return true;
2258 }
2259 
2260 // called via RPC (e.g., from ManagerDBusAdaptor)
GetService(const KeyValueStore & args,Error * error)2261 ServiceRefPtr Manager::GetService(const KeyValueStore& args, Error* error) {
2262   if (args.ContainsString(kTypeProperty) &&
2263       args.GetString(kTypeProperty) == kTypeVPN) {
2264      // GetService on a VPN service should actually perform ConfigureService.
2265      // TODO(pstew): Remove this hack and change Chrome to use ConfigureService
2266      // instead, when we no longer need to support flimflam.  crbug.com/213802
2267      return ConfigureService(args, error);
2268   }
2269 
2270   ServiceRefPtr service = GetServiceInner(args, error);
2271   if (service) {
2272     // Configures the service using the rest of the passed-in arguments.
2273     service->Configure(args, error);
2274   }
2275 
2276   return service;
2277 }
2278 
GetServiceInner(const KeyValueStore & args,Error * error)2279 ServiceRefPtr Manager::GetServiceInner(const KeyValueStore& args,
2280                                        Error* error) {
2281   if (args.ContainsString(kGuidProperty)) {
2282     SLOG(this, 2) << __func__ << ": searching by GUID";
2283     ServiceRefPtr service =
2284         GetServiceWithGUID(args.GetString(kGuidProperty), nullptr);
2285     if (service) {
2286       return service;
2287     }
2288   }
2289 
2290   if (!args.ContainsString(kTypeProperty)) {
2291     Error::PopulateAndLog(
2292         FROM_HERE, error, Error::kInvalidArguments, kErrorTypeRequired);
2293     return nullptr;
2294   }
2295 
2296   string type = args.GetString(kTypeProperty);
2297   Technology::Identifier technology = Technology::IdentifierFromName(type);
2298   if (!ContainsKey(providers_, technology)) {
2299     Error::PopulateAndLog(FROM_HERE, error, Error::kNotSupported,
2300                           kErrorUnsupportedServiceType);
2301     return nullptr;
2302   }
2303 
2304   SLOG(this, 2) << __func__ << ": getting " << type << " Service";
2305   return providers_[technology]->GetService(args, error);
2306 }
2307 
2308 // called via RPC (e.g., from ManagerDBusAdaptor)
ConfigureService(const KeyValueStore & args,Error * error)2309 ServiceRefPtr Manager::ConfigureService(const KeyValueStore& args,
2310                                         Error* error) {
2311   ProfileRefPtr profile = ActiveProfile();
2312   bool profile_specified = args.ContainsString(kProfileProperty);
2313   if (profile_specified) {
2314     string profile_rpcid = args.GetString(kProfileProperty);
2315     profile = LookupProfileByRpcIdentifier(profile_rpcid);
2316     if (!profile) {
2317       Error::PopulateAndLog(FROM_HERE, error, Error::kInvalidArguments,
2318                             "Invalid profile name " + profile_rpcid);
2319       return nullptr;
2320     }
2321   }
2322 
2323   ServiceRefPtr service = GetServiceInner(args, error);
2324   if (error->IsFailure() || !service) {
2325     LOG(ERROR) << "GetService failed; returning upstream error.";
2326     return nullptr;
2327   }
2328 
2329   // First pull in any stored configuration associated with the service.
2330   if (service->profile() == profile) {
2331     SLOG(this, 2) << __func__ << ": service " << service->unique_name()
2332                   << " is already a member of profile "
2333                      << profile->GetFriendlyName()
2334                      << " so a load is not necessary.";
2335   } else if (profile->LoadService(service)) {
2336     SLOG(this, 2) << __func__ << ": applied stored information from profile "
2337                   << profile->GetFriendlyName()
2338                   << " into service "
2339                   << service->unique_name();
2340   } else {
2341     SLOG(this, 2) << __func__ << ": no previous information in profile "
2342                   << profile->GetFriendlyName()
2343                   << " exists for service "
2344                   << service->unique_name();
2345   }
2346 
2347   // Overlay this with the passed-in configuration parameters.
2348   service->Configure(args, error);
2349 
2350   // Overwrite the profile data with the resulting configured service.
2351   if (!profile->UpdateService(service)) {
2352     Error::PopulateAndLog(FROM_HERE, error, Error::kInternalError,
2353                           "Unable to save service to profile");
2354     return nullptr;
2355   }
2356 
2357   if (HasService(service)) {
2358     // If the service has been registered (it may not be -- as is the case
2359     // with invisible WiFi networks), we can now transfer the service between
2360     // profiles.
2361     if (IsServiceEphemeral(service) ||
2362         (profile_specified && service->profile() != profile)) {
2363       SLOG(this, 2) << "Moving service to profile "
2364                     << profile->GetFriendlyName();
2365       if (!MoveServiceToProfile(service, profile)) {
2366         Error::PopulateAndLog(FROM_HERE, error, Error::kInternalError,
2367                               "Unable to move service to profile");
2368       }
2369     }
2370   }
2371 
2372   // Notify the service that a profile has been configured for it.
2373   service->OnProfileConfigured();
2374 
2375   return service;
2376 }
2377 
2378 // called via RPC (e.g., from ManagerDBusAdaptor)
ConfigureServiceForProfile(const string & profile_rpcid,const KeyValueStore & args,Error * error)2379 ServiceRefPtr Manager::ConfigureServiceForProfile(
2380     const string& profile_rpcid, const KeyValueStore& args, Error* error) {
2381   if (!args.ContainsString(kTypeProperty)) {
2382     Error::PopulateAndLog(
2383         FROM_HERE, error, Error::kInvalidArguments, kErrorTypeRequired);
2384     return nullptr;
2385   }
2386 
2387   string type = args.GetString(kTypeProperty);
2388   Technology::Identifier technology = Technology::IdentifierFromName(type);
2389 
2390   if (!ContainsKey(providers_, technology)) {
2391     Error::PopulateAndLog(FROM_HERE, error, Error::kNotSupported,
2392                           kErrorUnsupportedServiceType);
2393     return nullptr;
2394   }
2395 
2396   ProviderInterface* provider = providers_[technology];
2397 
2398   ProfileRefPtr profile = LookupProfileByRpcIdentifier(profile_rpcid);
2399   if (!profile) {
2400     Error::PopulateAndLog(FROM_HERE, error, Error::kNotFound,
2401                           "Profile specified was not found");
2402     return nullptr;
2403   }
2404   if (args.LookupString(kProfileProperty, profile_rpcid) != profile_rpcid) {
2405     Error::PopulateAndLog(FROM_HERE, error, Error::kInvalidArguments,
2406                           "Profile argument does not match that in "
2407                           "the configuration arguments");
2408     return nullptr;
2409   }
2410 
2411   ServiceRefPtr service;
2412   if (args.ContainsString(kGuidProperty)) {
2413     SLOG(this, 2) << __func__ << ": searching by GUID";
2414     service = GetServiceWithGUID(args.GetString(kGuidProperty), nullptr);
2415     if (service && service->technology() != technology) {
2416       Error::PopulateAndLog(FROM_HERE, error, Error::kNotSupported,
2417                             StringPrintf("This GUID matches a non-%s service",
2418                                          type.c_str()));
2419       return nullptr;
2420     }
2421   }
2422 
2423   if (!service) {
2424     Error find_error;
2425     service = provider->FindSimilarService(args, &find_error);
2426   }
2427 
2428   // If no matching service exists, create a new service in the specified
2429   // profile using ConfigureService().
2430   if (!service) {
2431     KeyValueStore configure_args;
2432     configure_args.CopyFrom(args);
2433     configure_args.SetString(kProfileProperty, profile_rpcid);
2434     return ConfigureService(configure_args, error);
2435   }
2436 
2437   // The service already exists and is set to the desired profile,
2438   // the service is in the ephemeral profile, or the current profile
2439   // for the service appears before the desired profile, we need to
2440   // reassign the service to the new profile if necessary, leaving
2441   // the old profile intact (i.e, not calling Profile::AbandonService()).
2442   // Then, configure the properties on the service as well as its newly
2443   // associated profile.
2444   if (service->profile() == profile ||
2445       IsServiceEphemeral(service) ||
2446       IsProfileBefore(service->profile(), profile)) {
2447     SetupServiceInProfile(service, profile, args, error);
2448     return service;
2449   }
2450 
2451   // The current profile for the service appears after the desired
2452   // profile.  We must create a temporary service specifically for
2453   // the task of creating configuration data.  This service will
2454   // neither inherit properties from the visible service, nor will
2455   // it exist after this function returns.
2456   service = provider->CreateTemporaryService(args, error);
2457   if (!service || !error->IsSuccess()) {
2458     // Service::CreateTemporaryService() failed, and has set the error
2459     // appropriately.
2460     return nullptr;
2461   }
2462 
2463   // The profile may already have configuration for this service.
2464   profile->ConfigureService(service);
2465 
2466   SetupServiceInProfile(service, profile, args, error);
2467 
2468   // Although we have succeeded, this service will not exist, so its
2469   // path is of no use to the caller.
2470   DCHECK(service->HasOneRef());
2471   return nullptr;
2472 }
2473 
SetupServiceInProfile(ServiceRefPtr service,ProfileRefPtr profile,const KeyValueStore & args,Error * error)2474 void Manager::SetupServiceInProfile(ServiceRefPtr service,
2475                                     ProfileRefPtr profile,
2476                                     const KeyValueStore& args,
2477                                     Error* error) {
2478   service->SetProfile(profile);
2479   service->Configure(args, error);
2480   profile->UpdateService(service);
2481 }
2482 
FindMatchingService(const KeyValueStore & args,Error * error)2483 ServiceRefPtr Manager::FindMatchingService(const KeyValueStore& args,
2484                                            Error* error) {
2485   for (const auto& service : services_) {
2486     if (service->DoPropertiesMatch(args)) {
2487       return service;
2488     }
2489   }
2490   error->Populate(Error::kNotFound, "Matching service was not found");
2491   return nullptr;
2492 }
2493 
2494 const map<string, GeolocationInfos>
GetNetworksForGeolocation() const2495     &Manager::GetNetworksForGeolocation() const {
2496   return networks_for_geolocation_;
2497 }
2498 
OnDeviceGeolocationInfoUpdated(const DeviceRefPtr & device)2499 void Manager::OnDeviceGeolocationInfoUpdated(const DeviceRefPtr& device) {
2500   SLOG(this, 2) << __func__ << " for technology "
2501                 << Technology::NameFromIdentifier(device->technology());
2502   switch (device->technology()) {
2503     // TODO(gauravsh): crbug.com/217833 Need a strategy for combining
2504     // geolocation objects from multiple devices of the same technolgy.
2505     // Currently, we just override the any previously acquired
2506     // geolocation objects for the retrieved technology type.
2507     case Technology::kWifi:
2508       networks_for_geolocation_[kGeoWifiAccessPointsProperty] =
2509           device->GetGeolocationObjects();
2510       break;
2511     case Technology::kCellular:
2512       networks_for_geolocation_[kGeoCellTowersProperty] =
2513           device->GetGeolocationObjects();
2514       break;
2515     default:
2516       // Ignore other technologies.
2517       break;
2518   }
2519 }
2520 
RecheckPortal(Error *)2521 void Manager::RecheckPortal(Error* /*error*/) {
2522   for (const auto& device : devices_) {
2523     if (device->RequestPortalDetection()) {
2524       // Only start Portal Detection on the device with the default connection.
2525       // We will get a "true" return value when we've found that device, and
2526       // can end our loop early as a result.
2527       break;
2528     }
2529   }
2530 }
2531 
RecheckPortalOnService(const ServiceRefPtr & service)2532 void Manager::RecheckPortalOnService(const ServiceRefPtr& service) {
2533   for (const auto& device : devices_) {
2534     if (device->IsConnectedToService(service)) {
2535       // As opposed to RecheckPortal() above, we explicitly stop and then
2536       // restart portal detection, since the service to recheck was explicitly
2537       // specified.
2538       device->RestartPortalDetection();
2539       break;
2540     }
2541   }
2542 }
2543 
RequestScan(Device::ScanType scan_type,const string & technology,Error * error)2544 void Manager::RequestScan(Device::ScanType scan_type,
2545                           const string& technology, Error* error) {
2546   if (technology == kTypeWifi || technology == "") {
2547     for (const auto& wifi_device : FilterByTechnology(Technology::kWifi)) {
2548       metrics_->NotifyUserInitiatedEvent(Metrics::kUserInitiatedEventWifiScan);
2549       wifi_device->Scan(scan_type, error, __func__);
2550     }
2551   } else {
2552     // TODO(quiche): support scanning for other technologies?
2553     Error::PopulateAndLog(FROM_HERE, error, Error::kInvalidArguments,
2554                           "Unrecognized technology " + technology);
2555   }
2556 }
2557 
SetSchedScan(bool enable,Error * error)2558 void Manager::SetSchedScan(bool enable, Error* error) {
2559   for (const auto& wifi_device : FilterByTechnology(Technology::kWifi)) {
2560     wifi_device->SetSchedScan(enable, error);
2561   }
2562 }
2563 
GetTechnologyOrder()2564 string Manager::GetTechnologyOrder() {
2565   vector<string> technology_names;
2566   for (const auto& technology : technology_order_) {
2567     technology_names.push_back(Technology::NameFromIdentifier(technology));
2568   }
2569 
2570   return base::JoinString(technology_names, ",");
2571 }
2572 
SetTechnologyOrder(const string & order,Error * error)2573 void Manager::SetTechnologyOrder(const string& order, Error* error) {
2574   vector<Technology::Identifier> new_order;
2575   SLOG(this, 2) << "Setting technology order to " << order;
2576   if (!Technology::GetTechnologyVectorFromString(order, &new_order, error)) {
2577     return;
2578   }
2579 
2580   technology_order_ = new_order;
2581   if (running_) {
2582     SortServices();
2583   }
2584 }
2585 
IsWifiIdle()2586 bool Manager::IsWifiIdle() {
2587   bool ret = false;
2588 
2589   // Since services are sorted by connection state, status of the wifi device
2590   // can be determine by examing the connection state of the first wifi service.
2591   for (const auto& service : services_) {
2592     if (service->technology() == Technology::kWifi) {
2593       if (!service->IsConnecting() && !service->IsConnected()) {
2594         ret = true;
2595       }
2596       break;
2597     }
2598   }
2599   return ret;
2600 }
2601 
UpdateProviderMapping()2602 void Manager::UpdateProviderMapping() {
2603 #if !defined(DISABLE_WIRED_8021X)
2604   providers_[Technology::kEthernetEap] = ethernet_eap_provider_.get();
2605 #endif  // DISABLE_WIRED_8021X
2606   providers_[Technology::kVPN] = vpn_provider_.get();
2607 #if !defined(DISABLE_WIFI)
2608   providers_[Technology::kWifi] = wifi_provider_.get();
2609 #endif  // DISABLE_WIFI
2610 #if !defined(DISABLE_WIMAX)
2611   providers_[Technology::kWiMax] = wimax_provider_.get();
2612 #endif  // DISABLE_WIMAX
2613 }
2614 
GetDeviceConnectedToService(ServiceRefPtr service)2615 DeviceRefPtr Manager::GetDeviceConnectedToService(ServiceRefPtr service) {
2616   for (DeviceRefPtr device : devices_) {
2617     if (device->IsConnectedToService(service)) {
2618       return device;
2619     }
2620   }
2621   return nullptr;
2622 }
2623 
DetectMultiHomedDevices()2624 void Manager::DetectMultiHomedDevices() {
2625   map<string, vector<DeviceRefPtr>> subnet_buckets;
2626   for (const auto& device : devices_) {
2627     const auto& connection = device->connection();
2628     string subnet_name;
2629     if (connection) {
2630       subnet_name = connection->GetSubnetName();
2631     }
2632     if (subnet_name.empty()) {
2633       device->SetIsMultiHomed(false);
2634     } else {
2635       subnet_buckets[subnet_name].push_back(device);
2636     }
2637   }
2638 
2639   for (const auto& subnet_bucket : subnet_buckets) {
2640     const auto& device_list = subnet_bucket.second;
2641     if (device_list.size() > 1) {
2642       for (const auto& device : device_list) {
2643         device->SetIsMultiHomed(true);
2644       }
2645     } else {
2646       DCHECK_EQ(1U, device_list.size());
2647       device_list.back()->SetIsMultiHomed(false);
2648     }
2649   }
2650 }
2651 
2652 }  // namespace shill
2653