Upstream version 6.35.121.0
[platform/framework/web/crosswalk.git] / src / chrome / browser / chromeos / policy / device_cloud_policy_manager_chromeos.cc
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 #include "chrome/browser/chromeos/policy/device_cloud_policy_manager_chromeos.h"
6
7 #include "base/bind.h"
8 #include "base/bind_helpers.h"
9 #include "base/command_line.h"
10 #include "base/prefs/pref_registry_simple.h"
11 #include "base/prefs/pref_service.h"
12 #include "chrome/browser/browser_process.h"
13 #include "chrome/browser/chromeos/attestation/attestation_policy_observer.h"
14 #include "chrome/browser/chromeos/login/startup_utils.h"
15 #include "chrome/browser/chromeos/policy/device_cloud_policy_store_chromeos.h"
16 #include "chrome/browser/chromeos/policy/enrollment_handler_chromeos.h"
17 #include "chrome/browser/chromeos/policy/enterprise_install_attributes.h"
18 #include "chrome/browser/chromeos/policy/server_backed_device_state.h"
19 #include "chrome/common/chrome_content_client.h"
20 #include "chrome/common/pref_names.h"
21 #include "chromeos/chromeos_constants.h"
22 #include "chromeos/chromeos_switches.h"
23 #include "chromeos/system/statistics_provider.h"
24 #include "components/policy/core/common/cloud/cloud_policy_constants.h"
25 #include "components/policy/core/common/cloud/cloud_policy_store.h"
26 #include "components/policy/core/common/cloud/device_management_service.h"
27 #include "components/policy/core/common/cloud/system_policy_request_context.h"
28 #include "content/public/browser/browser_thread.h"
29 #include "crypto/sha2.h"
30 #include "policy/proto/device_management_backend.pb.h"
31 #include "url/gurl.h"
32
33 using content::BrowserThread;
34
35 namespace em = enterprise_management;
36
37 namespace policy {
38
39 namespace {
40
41 // Overridden no requisition value.
42 const char kNoRequisition[] = "none";
43
44 // Overridden no requisition value.
45 const char kRemoraRequisition[] = "remora";
46
47 // MachineInfo key names.
48 const char kMachineInfoSystemHwqual[] = "hardware_class";
49
50 // These are the machine serial number keys that we check in order until we
51 // find a non-empty serial number. The VPD spec says the serial number should be
52 // in the "serial_number" key for v2+ VPDs. However, legacy devices used a
53 // different keys to report their serial number, which we fall back to if
54 // "serial_number" is not present.
55 //
56 // Product_S/N is still special-cased due to inconsistencies with serial
57 // numbers on Lumpy devices: On these devices, serial_number is identical to
58 // Product_S/N with an appended checksum. Unfortunately, the sticker on the
59 // packaging doesn't include that checksum either (the sticker on the device
60 // does though!). The former sticker is the source of the serial number used by
61 // device management service, so we prefer Product_S/N over serial number to
62 // match the server.
63 //
64 // TODO(mnissler): Move serial_number back to the top once the server side uses
65 // the correct serial number.
66 const char* kMachineInfoSerialNumberKeys[] = {
67   "Product_S/N",    // Lumpy/Alex devices
68   "serial_number",  // VPD v2+ devices
69   "Product_SN",     // Mario
70   "sn",             // old ZGB devices (more recent ones use serial_number)
71 };
72
73 // Fetches a machine statistic value from StatisticsProvider, returns an empty
74 // string on failure.
75 std::string GetMachineStatistic(const std::string& key) {
76   std::string value;
77   chromeos::system::StatisticsProvider* provider =
78       chromeos::system::StatisticsProvider::GetInstance();
79   if (!provider->GetMachineStatistic(key, &value))
80     return std::string();
81
82   return value;
83 }
84
85 // Gets a machine flag from StatisticsProvider, returns the given
86 // |default_value| if not present.
87 bool GetMachineFlag(const std::string& key, bool default_value) {
88   bool value = default_value;
89   chromeos::system::StatisticsProvider* provider =
90       chromeos::system::StatisticsProvider::GetInstance();
91   if (!provider->GetMachineFlag(key, &value))
92     return default_value;
93
94   return value;
95 }
96
97 }  // namespace
98
99 DeviceCloudPolicyManagerChromeOS::DeviceCloudPolicyManagerChromeOS(
100     scoped_ptr<DeviceCloudPolicyStoreChromeOS> store,
101     const scoped_refptr<base::SequencedTaskRunner>& task_runner,
102     const scoped_refptr<base::SequencedTaskRunner>& background_task_runner,
103     EnterpriseInstallAttributes* install_attributes)
104     : CloudPolicyManager(
105           PolicyNamespaceKey(dm_protocol::kChromeDevicePolicyType,
106                              std::string()),
107           store.get(),
108           task_runner,
109           BrowserThread::GetMessageLoopProxyForThread(BrowserThread::FILE),
110           BrowserThread::GetMessageLoopProxyForThread(BrowserThread::IO)),
111       device_store_(store.Pass()),
112       background_task_runner_(background_task_runner),
113       install_attributes_(install_attributes),
114       device_management_service_(NULL),
115       local_state_(NULL) {}
116
117 DeviceCloudPolicyManagerChromeOS::~DeviceCloudPolicyManagerChromeOS() {}
118
119 void DeviceCloudPolicyManagerChromeOS::Connect(
120     PrefService* local_state,
121     DeviceManagementService* device_management_service,
122     scoped_ptr<CloudPolicyClient::StatusProvider> device_status_provider) {
123   CHECK(!device_management_service_);
124   CHECK(device_management_service);
125   CHECK(local_state);
126
127   local_state_ = local_state;
128   device_management_service_ = device_management_service;
129   device_status_provider_ = device_status_provider.Pass();
130
131   InitalizeRequisition();
132   StartIfManaged();
133 }
134
135 void DeviceCloudPolicyManagerChromeOS::StartEnrollment(
136     const std::string& auth_token,
137     bool is_auto_enrollment,
138     const AllowedDeviceModes& allowed_device_modes,
139     const EnrollmentCallback& callback) {
140   CHECK(device_management_service_);
141   core()->Disconnect();
142
143   enrollment_handler_.reset(
144       new EnrollmentHandlerChromeOS(
145           device_store_.get(), install_attributes_, CreateClient(),
146           background_task_runner_, auth_token,
147           install_attributes_->GetDeviceId(), is_auto_enrollment,
148           GetDeviceRequisition(), GetDeviceStateKey(), allowed_device_modes,
149           base::Bind(&DeviceCloudPolicyManagerChromeOS::EnrollmentCompleted,
150                      base::Unretained(this), callback)));
151   enrollment_handler_->StartEnrollment();
152 }
153
154 void DeviceCloudPolicyManagerChromeOS::CancelEnrollment() {
155   if (enrollment_handler_.get()) {
156     enrollment_handler_.reset();
157     StartIfManaged();
158   }
159 }
160
161 std::string DeviceCloudPolicyManagerChromeOS::GetDeviceRequisition() const {
162   std::string requisition;
163   const PrefService::Preference* pref = local_state_->FindPreference(
164       prefs::kDeviceEnrollmentRequisition);
165   if (!pref->IsDefaultValue())
166     pref->GetValue()->GetAsString(&requisition);
167
168   if (requisition == kNoRequisition)
169     requisition.clear();
170
171   return requisition;
172 }
173
174 void DeviceCloudPolicyManagerChromeOS::SetDeviceRequisition(
175     const std::string& requisition) {
176   if (local_state_) {
177     if (requisition.empty()) {
178       local_state_->ClearPref(prefs::kDeviceEnrollmentRequisition);
179       local_state_->ClearPref(prefs::kDeviceEnrollmentAutoStart);
180       local_state_->ClearPref(prefs::kDeviceEnrollmentCanExit);
181     } else {
182       local_state_->SetString(prefs::kDeviceEnrollmentRequisition, requisition);
183       if (requisition == kNoRequisition) {
184         local_state_->ClearPref(prefs::kDeviceEnrollmentAutoStart);
185         local_state_->ClearPref(prefs::kDeviceEnrollmentCanExit);
186       } else {
187         local_state_->SetBoolean(prefs::kDeviceEnrollmentAutoStart, true);
188         local_state_->SetBoolean(prefs::kDeviceEnrollmentCanExit, false);
189       }
190     }
191   }
192 }
193
194 bool DeviceCloudPolicyManagerChromeOS::ShouldAutoStartEnrollment() const {
195   std::string restore_mode = GetRestoreMode();
196   if (restore_mode == kDeviceStateRestoreModeReEnrollmentRequested ||
197       restore_mode == kDeviceStateRestoreModeReEnrollmentEnforced) {
198     return true;
199   }
200
201   if (local_state_->HasPrefPath(prefs::kDeviceEnrollmentAutoStart))
202     return local_state_->GetBoolean(prefs::kDeviceEnrollmentAutoStart);
203
204   return GetMachineFlag(chromeos::system::kOemIsEnterpriseManagedKey, false);
205 }
206
207 bool DeviceCloudPolicyManagerChromeOS::CanExitEnrollment() const {
208   if (GetRestoreMode() == kDeviceStateRestoreModeReEnrollmentEnforced)
209     return false;
210
211   if (local_state_->HasPrefPath(prefs::kDeviceEnrollmentCanExit))
212     return local_state_->GetBoolean(prefs::kDeviceEnrollmentCanExit);
213
214   return GetMachineFlag(chromeos::system::kOemCanExitEnterpriseEnrollmentKey,
215                         true);
216 }
217
218 std::string
219 DeviceCloudPolicyManagerChromeOS::GetForcedEnrollmentDomain() const {
220   const base::DictionaryValue* device_state_dict =
221       local_state_->GetDictionary(prefs::kServerBackedDeviceState);
222   std::string management_domain;
223   device_state_dict->GetString(kDeviceStateManagementDomain,
224                                &management_domain);
225   return management_domain;
226 }
227
228 void DeviceCloudPolicyManagerChromeOS::Shutdown() {
229   CloudPolicyManager::Shutdown();
230   device_status_provider_.reset();
231 }
232
233 void DeviceCloudPolicyManagerChromeOS::OnStoreLoaded(CloudPolicyStore* store) {
234   CloudPolicyManager::OnStoreLoaded(store);
235
236   if (!enrollment_handler_.get())
237     StartIfManaged();
238 }
239
240 // static
241 void DeviceCloudPolicyManagerChromeOS::RegisterPrefs(
242     PrefRegistrySimple* registry) {
243   registry->RegisterStringPref(prefs::kDeviceEnrollmentRequisition,
244                                std::string());
245   registry->RegisterBooleanPref(prefs::kDeviceEnrollmentAutoStart, false);
246   registry->RegisterBooleanPref(prefs::kDeviceEnrollmentCanExit, true);
247   registry->RegisterDictionaryPref(prefs::kServerBackedDeviceState);
248 }
249
250 // static
251 std::string DeviceCloudPolicyManagerChromeOS::GetMachineID() {
252   std::string machine_id;
253   chromeos::system::StatisticsProvider* provider =
254       chromeos::system::StatisticsProvider::GetInstance();
255   for (size_t i = 0; i < arraysize(kMachineInfoSerialNumberKeys); i++) {
256     if (provider->GetMachineStatistic(kMachineInfoSerialNumberKeys[i],
257                                       &machine_id) &&
258         !machine_id.empty()) {
259       break;
260     }
261   }
262
263   if (machine_id.empty())
264     LOG(WARNING) << "Failed to get machine id.";
265
266   return machine_id;
267 }
268
269 // static
270 std::string DeviceCloudPolicyManagerChromeOS::GetMachineModel() {
271   return GetMachineStatistic(kMachineInfoSystemHwqual);
272 }
273
274 // static
275 std::string DeviceCloudPolicyManagerChromeOS::GetDeviceStateKey() {
276   // TODO(mnissler): Figure out which stable device identifiers should be used
277   // here and update the code. See http://crbug.com/352599.
278   std::string group_code_key =
279       GetMachineStatistic(chromeos::system::kOffersGroupCodeKey);
280   return crypto::SHA256HashString(group_code_key + GetMachineID());
281 }
282
283 scoped_ptr<CloudPolicyClient> DeviceCloudPolicyManagerChromeOS::CreateClient() {
284   scoped_refptr<net::URLRequestContextGetter> request_context =
285       new SystemPolicyRequestContext(
286           g_browser_process->system_request_context(), GetUserAgent());
287
288   scoped_ptr<CloudPolicyClient> client(
289       new CloudPolicyClient(GetMachineID(), GetMachineModel(),
290                             kPolicyVerificationKeyHash,
291                             USER_AFFILIATION_NONE,
292                             device_status_provider_.get(),
293                             device_management_service_,
294                             request_context));
295
296   // Set state keys to upload immediately after creation so the first policy
297   // fetch submits them to the server.
298   if (CommandLine::ForCurrentProcess()->HasSwitch(
299           chromeos::switches::kEnterpriseEnableForcedReEnrollment)) {
300     std::vector<std::string> state_keys;
301     state_keys.push_back(GetDeviceStateKey());
302     client->SetStateKeysToUpload(state_keys);
303   }
304
305   return client.Pass();
306 }
307
308 void DeviceCloudPolicyManagerChromeOS::EnrollmentCompleted(
309     const EnrollmentCallback& callback,
310     EnrollmentStatus status) {
311   if (status.status() == EnrollmentStatus::STATUS_SUCCESS)
312     StartConnection(enrollment_handler_->ReleaseClient());
313   else
314     StartIfManaged();
315
316   enrollment_handler_.reset();
317   if (!callback.is_null())
318     callback.Run(status);
319 }
320
321 void DeviceCloudPolicyManagerChromeOS::StartIfManaged() {
322   if (device_management_service_ &&
323       local_state_ &&
324       store()->is_initialized() &&
325       store()->has_policy() &&
326       !service()) {
327     StartConnection(CreateClient());
328   }
329 }
330
331 void DeviceCloudPolicyManagerChromeOS::StartConnection(
332     scoped_ptr<CloudPolicyClient> client_to_connect) {
333   core()->Connect(client_to_connect.Pass());
334   core()->StartRefreshScheduler();
335   core()->TrackRefreshDelayPref(local_state_,
336                                 prefs::kDevicePolicyRefreshRate);
337   attestation_policy_observer_.reset(
338       new chromeos::attestation::AttestationPolicyObserver(client()));
339 }
340
341 void DeviceCloudPolicyManagerChromeOS::InitalizeRequisition() {
342   // OEM statistics are only loaded when OOBE is not completed.
343   if (chromeos::StartupUtils::IsOobeCompleted())
344     return;
345
346   const PrefService::Preference* pref = local_state_->FindPreference(
347       prefs::kDeviceEnrollmentRequisition);
348   if (pref->IsDefaultValue()) {
349     std::string requisition =
350         GetMachineStatistic(chromeos::system::kOemDeviceRequisitionKey);
351
352     if (!requisition.empty()) {
353       local_state_->SetString(prefs::kDeviceEnrollmentRequisition,
354                               requisition);
355       if (requisition == kRemoraRequisition) {
356         local_state_->SetBoolean(prefs::kDeviceEnrollmentAutoStart, true);
357         local_state_->SetBoolean(prefs::kDeviceEnrollmentCanExit, false);
358       } else {
359         local_state_->SetBoolean(
360             prefs::kDeviceEnrollmentAutoStart,
361             GetMachineFlag(chromeos::system::kOemIsEnterpriseManagedKey,
362                            false));
363         local_state_->SetBoolean(
364             prefs::kDeviceEnrollmentCanExit,
365             GetMachineFlag(chromeos::system::kOemCanExitEnterpriseEnrollmentKey,
366                            false));
367       }
368     }
369   }
370 }
371
372 std::string DeviceCloudPolicyManagerChromeOS::GetRestoreMode() const {
373   const base::DictionaryValue* device_state_dict =
374       local_state_->GetDictionary(prefs::kServerBackedDeviceState);
375   std::string restore_mode;
376   device_state_dict->GetString(kDeviceStateRestoreMode, &restore_mode);
377   return restore_mode;
378 }
379
380 }  // namespace policy