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/port.h"
11 #include "base/prefs/pref_registry_simple.h"
12 #include "base/prefs/pref_service.h"
13 #include "base/strings/string_number_conversions.h"
14 #include "base/time/time.h"
15 #include "chrome/browser/chromeos/attestation/attestation_policy_observer.h"
16 #include "chrome/browser/chromeos/login/enrollment/auto_enrollment_controller.h"
17 #include "chrome/browser/chromeos/login/startup_utils.h"
18 #include "chrome/browser/chromeos/policy/device_cloud_policy_store_chromeos.h"
19 #include "chrome/browser/chromeos/policy/server_backed_state_keys_broker.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_store.h"
25 #include "content/public/browser/browser_thread.h"
26 #include "crypto/sha2.h"
27 #include "policy/proto/device_management_backend.pb.h"
28 #include "url/gurl.h"
29
30 using content::BrowserThread;
31
32 namespace em = enterprise_management;
33
34 namespace policy {
35
36 namespace {
37
38 const char kNoRequisition[] = "none";
39 const char kRemoraRequisition[] = "remora";
40 const char kSharkRequisition[] = "shark";
41
42 // These are the machine serial number keys that we check in order until we
43 // find a non-empty serial number. The VPD spec says the serial number should be
44 // in the "serial_number" key for v2+ VPDs. However, legacy devices used a
45 // different key to report their serial number, which we fall back to if
46 // "serial_number" is not present.
47 //
48 // Product_S/N is still special-cased due to inconsistencies with serial
49 // numbers on Lumpy devices: On these devices, serial_number is identical to
50 // Product_S/N with an appended checksum. Unfortunately, the sticker on the
51 // packaging doesn't include that checksum either (the sticker on the device
52 // does though!). The former sticker is the source of the serial number used by
53 // device management service, so we prefer Product_S/N over serial number to
54 // match the server.
55 //
56 // TODO(mnissler): Move serial_number back to the top once the server side uses
57 // the correct serial number.
58 const char* kMachineInfoSerialNumberKeys[] = {
59 "Product_S/N", // Lumpy/Alex devices
60 "serial_number", // VPD v2+ devices
61 "Product_SN", // Mario
62 "sn", // old ZGB devices (more recent ones use serial_number)
63 };
64
65 // Fetches a machine statistic value from StatisticsProvider, returns an empty
66 // string on failure.
GetMachineStatistic(const std::string & key)67 std::string GetMachineStatistic(const std::string& key) {
68 std::string value;
69 chromeos::system::StatisticsProvider* provider =
70 chromeos::system::StatisticsProvider::GetInstance();
71 if (!provider->GetMachineStatistic(key, &value))
72 return std::string();
73
74 return value;
75 }
76
77 // Gets a machine flag from StatisticsProvider, returns the given
78 // |default_value| if not present.
GetMachineFlag(const std::string & key,bool default_value)79 bool GetMachineFlag(const std::string& key, bool default_value) {
80 bool value = default_value;
81 chromeos::system::StatisticsProvider* provider =
82 chromeos::system::StatisticsProvider::GetInstance();
83 if (!provider->GetMachineFlag(key, &value))
84 return default_value;
85
86 return value;
87 }
88
89 // Checks whether forced re-enrollment is enabled.
ForcedReEnrollmentEnabled()90 bool ForcedReEnrollmentEnabled() {
91 return chromeos::AutoEnrollmentController::GetMode() ==
92 chromeos::AutoEnrollmentController::MODE_FORCED_RE_ENROLLMENT;
93 }
94
95 } // namespace
96
DeviceCloudPolicyManagerChromeOS(scoped_ptr<DeviceCloudPolicyStoreChromeOS> store,const scoped_refptr<base::SequencedTaskRunner> & task_runner,ServerBackedStateKeysBroker * state_keys_broker)97 DeviceCloudPolicyManagerChromeOS::DeviceCloudPolicyManagerChromeOS(
98 scoped_ptr<DeviceCloudPolicyStoreChromeOS> store,
99 const scoped_refptr<base::SequencedTaskRunner>& task_runner,
100 ServerBackedStateKeysBroker* state_keys_broker)
101 : CloudPolicyManager(
102 PolicyNamespaceKey(dm_protocol::kChromeDevicePolicyType,
103 std::string()),
104 store.get(),
105 task_runner,
106 BrowserThread::GetMessageLoopProxyForThread(BrowserThread::FILE),
107 BrowserThread::GetMessageLoopProxyForThread(BrowserThread::IO)),
108 device_store_(store.Pass()),
109 state_keys_broker_(state_keys_broker),
110 local_state_(NULL) {
111 }
112
~DeviceCloudPolicyManagerChromeOS()113 DeviceCloudPolicyManagerChromeOS::~DeviceCloudPolicyManagerChromeOS() {}
114
Initialize(PrefService * local_state)115 void DeviceCloudPolicyManagerChromeOS::Initialize(PrefService* local_state) {
116 CHECK(local_state);
117
118 local_state_ = local_state;
119
120 state_keys_update_subscription_ = state_keys_broker_->RegisterUpdateCallback(
121 base::Bind(&DeviceCloudPolicyManagerChromeOS::OnStateKeysUpdated,
122 base::Unretained(this)));
123
124 InitializeRequisition();
125 }
126
GetDeviceRequisition() const127 std::string DeviceCloudPolicyManagerChromeOS::GetDeviceRequisition() const {
128 std::string requisition;
129 const PrefService::Preference* pref = local_state_->FindPreference(
130 prefs::kDeviceEnrollmentRequisition);
131 if (!pref->IsDefaultValue())
132 pref->GetValue()->GetAsString(&requisition);
133
134 if (requisition == kNoRequisition)
135 requisition.clear();
136
137 return requisition;
138 }
139
SetDeviceRequisition(const std::string & requisition)140 void DeviceCloudPolicyManagerChromeOS::SetDeviceRequisition(
141 const std::string& requisition) {
142 VLOG(1) << "SetDeviceRequisition " << requisition;
143 if (local_state_) {
144 if (requisition.empty()) {
145 local_state_->ClearPref(prefs::kDeviceEnrollmentRequisition);
146 local_state_->ClearPref(prefs::kDeviceEnrollmentAutoStart);
147 local_state_->ClearPref(prefs::kDeviceEnrollmentCanExit);
148 } else {
149 local_state_->SetString(prefs::kDeviceEnrollmentRequisition, requisition);
150 if (requisition == kNoRequisition) {
151 local_state_->ClearPref(prefs::kDeviceEnrollmentAutoStart);
152 local_state_->ClearPref(prefs::kDeviceEnrollmentCanExit);
153 } else {
154 local_state_->SetBoolean(prefs::kDeviceEnrollmentAutoStart, true);
155 local_state_->SetBoolean(prefs::kDeviceEnrollmentCanExit, false);
156 }
157 }
158 }
159 }
160
IsRemoraRequisition() const161 bool DeviceCloudPolicyManagerChromeOS::IsRemoraRequisition() const {
162 return GetDeviceRequisition() == kRemoraRequisition;
163 }
164
IsSharkRequisition() const165 bool DeviceCloudPolicyManagerChromeOS::IsSharkRequisition() const {
166 return GetDeviceRequisition() == kSharkRequisition;
167 }
168
Shutdown()169 void DeviceCloudPolicyManagerChromeOS::Shutdown() {
170 state_keys_update_subscription_.reset();
171 CloudPolicyManager::Shutdown();
172 }
173
174 // static
RegisterPrefs(PrefRegistrySimple * registry)175 void DeviceCloudPolicyManagerChromeOS::RegisterPrefs(
176 PrefRegistrySimple* registry) {
177 registry->RegisterStringPref(prefs::kDeviceEnrollmentRequisition,
178 std::string());
179 registry->RegisterBooleanPref(prefs::kDeviceEnrollmentAutoStart, false);
180 registry->RegisterBooleanPref(prefs::kDeviceEnrollmentCanExit, true);
181 registry->RegisterDictionaryPref(prefs::kServerBackedDeviceState);
182 }
183
184 // static
GetMachineID()185 std::string DeviceCloudPolicyManagerChromeOS::GetMachineID() {
186 std::string machine_id;
187 chromeos::system::StatisticsProvider* provider =
188 chromeos::system::StatisticsProvider::GetInstance();
189 for (size_t i = 0; i < arraysize(kMachineInfoSerialNumberKeys); i++) {
190 if (provider->GetMachineStatistic(kMachineInfoSerialNumberKeys[i],
191 &machine_id) &&
192 !machine_id.empty()) {
193 break;
194 }
195 }
196
197 if (machine_id.empty())
198 LOG(WARNING) << "Failed to get machine id.";
199
200 return machine_id;
201 }
202
203 // static
GetMachineModel()204 std::string DeviceCloudPolicyManagerChromeOS::GetMachineModel() {
205 return GetMachineStatistic(chromeos::system::kHardwareClassKey);
206 }
207
StartConnection(scoped_ptr<CloudPolicyClient> client_to_connect,scoped_ptr<CloudPolicyClient::StatusProvider> device_status_provider)208 void DeviceCloudPolicyManagerChromeOS::StartConnection(
209 scoped_ptr<CloudPolicyClient> client_to_connect,
210 scoped_ptr<CloudPolicyClient::StatusProvider> device_status_provider) {
211 CHECK(!service());
212
213 device_status_provider_ = device_status_provider.Pass();
214
215 // Set state keys here so the first policy fetch submits them to the server.
216 if (ForcedReEnrollmentEnabled())
217 client_to_connect->SetStateKeysToUpload(state_keys_broker_->state_keys());
218
219 core()->Connect(client_to_connect.Pass());
220 core()->StartRefreshScheduler();
221 core()->TrackRefreshDelayPref(local_state_,
222 prefs::kDevicePolicyRefreshRate);
223 attestation_policy_observer_.reset(
224 new chromeos::attestation::AttestationPolicyObserver(client()));
225 }
226
OnStateKeysUpdated()227 void DeviceCloudPolicyManagerChromeOS::OnStateKeysUpdated() {
228 if (client() && ForcedReEnrollmentEnabled())
229 client()->SetStateKeysToUpload(state_keys_broker_->state_keys());
230 }
231
InitializeRequisition()232 void DeviceCloudPolicyManagerChromeOS::InitializeRequisition() {
233 // OEM statistics are only loaded when OOBE is not completed.
234 if (chromeos::StartupUtils::IsOobeCompleted())
235 return;
236
237 const PrefService::Preference* pref = local_state_->FindPreference(
238 prefs::kDeviceEnrollmentRequisition);
239 if (pref->IsDefaultValue()) {
240 std::string requisition =
241 GetMachineStatistic(chromeos::system::kOemDeviceRequisitionKey);
242
243 if (!requisition.empty()) {
244 local_state_->SetString(prefs::kDeviceEnrollmentRequisition,
245 requisition);
246 if (requisition == kRemoraRequisition ||
247 requisition == kSharkRequisition) {
248 local_state_->SetBoolean(prefs::kDeviceEnrollmentAutoStart, true);
249 local_state_->SetBoolean(prefs::kDeviceEnrollmentCanExit, false);
250 } else {
251 local_state_->SetBoolean(
252 prefs::kDeviceEnrollmentAutoStart,
253 GetMachineFlag(chromeos::system::kOemIsEnterpriseManagedKey,
254 false));
255 local_state_->SetBoolean(
256 prefs::kDeviceEnrollmentCanExit,
257 GetMachineFlag(chromeos::system::kOemCanExitEnterpriseEnrollmentKey,
258 false));
259 }
260 }
261 }
262 }
263
264 } // namespace policy
265