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

Side by Side Diff: chrome/browser/chromeos/policy/enterprise_install_attributes.cc

Issue 1189203003: Add UMA for consistency between TPM and install attributes. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master3
Patch Set: Address more comments. Created 5 years, 6 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. 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 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "chrome/browser/chromeos/policy/enterprise_install_attributes.h" 5 #include "chrome/browser/chromeos/policy/enterprise_install_attributes.h"
6 6
7 #include <utility> 7 #include <utility>
8 8
9 #include "base/bind.h" 9 #include "base/bind.h"
10 #include "base/files/file_util.h" 10 #include "base/files/file_util.h"
11 #include "base/location.h" 11 #include "base/location.h"
12 #include "base/logging.h" 12 #include "base/logging.h"
13 #include "base/message_loop/message_loop.h" 13 #include "base/message_loop/message_loop.h"
14 #include "base/metrics/histogram_base.h"
15 #include "base/metrics/histogram_macros.h"
16 #include "base/time/time.h"
14 #include "chrome/browser/chromeos/policy/proto/install_attributes.pb.h" 17 #include "chrome/browser/chromeos/policy/proto/install_attributes.pb.h"
15 #include "chromeos/cryptohome/cryptohome_util.h" 18 #include "chromeos/cryptohome/cryptohome_util.h"
16 #include "chromeos/dbus/dbus_thread_manager.h" 19 #include "chromeos/dbus/dbus_thread_manager.h"
17 #include "google_apis/gaia/gaia_auth_util.h" 20 #include "google_apis/gaia/gaia_auth_util.h"
18 21
19 namespace policy { 22 namespace policy {
20 23
21 namespace cryptohome_util = chromeos::cryptohome_util; 24 namespace cryptohome_util = chromeos::cryptohome_util;
22 25
23 namespace { 26 namespace {
24 27
28 // Number of TPM lock state query retries during consistency check.
29 int kDbusRetryCount = 12;
30
31 // Interval of TPM lock state query retries during consistency check.
32 int kDbusRetryIntervalInSeconds = 5;
33
25 bool ReadMapKey(const std::map<std::string, std::string>& map, 34 bool ReadMapKey(const std::map<std::string, std::string>& map,
26 const std::string& key, 35 const std::string& key,
27 std::string* value) { 36 std::string* value) {
28 std::map<std::string, std::string>::const_iterator entry = map.find(key); 37 std::map<std::string, std::string>::const_iterator entry = map.find(key);
29 if (entry == map.end()) 38 if (entry == map.end())
30 return false; 39 return false;
31 40
32 *value = entry->second; 41 *value = entry->second;
33 return true; 42 return true;
34 } 43 }
(...skipping 14 matching lines...) Expand all
49 attribute = install_attrs_proto.add_attributes(); 58 attribute = install_attrs_proto.add_attributes();
50 attribute->set_name(EnterpriseInstallAttributes::kAttrEnterpriseUser); 59 attribute->set_name(EnterpriseInstallAttributes::kAttrEnterpriseUser);
51 attribute->set_value(user_name); 60 attribute->set_value(user_name);
52 61
53 return install_attrs_proto.SerializeAsString(); 62 return install_attrs_proto.SerializeAsString();
54 } 63 }
55 64
56 EnterpriseInstallAttributes::EnterpriseInstallAttributes( 65 EnterpriseInstallAttributes::EnterpriseInstallAttributes(
57 chromeos::CryptohomeClient* cryptohome_client) 66 chromeos::CryptohomeClient* cryptohome_client)
58 : device_locked_(false), 67 : device_locked_(false),
68 consistency_check_running_(false),
69 registration_running_(false),
59 registration_mode_(DEVICE_MODE_PENDING), 70 registration_mode_(DEVICE_MODE_PENDING),
60 cryptohome_client_(cryptohome_client), 71 cryptohome_client_(cryptohome_client),
61 weak_ptr_factory_(this) { 72 weak_ptr_factory_(this) {
62 } 73 }
63 74
64 EnterpriseInstallAttributes::~EnterpriseInstallAttributes() {} 75 EnterpriseInstallAttributes::~EnterpriseInstallAttributes() {}
65 76
66 void EnterpriseInstallAttributes::ReadCacheFile( 77 void EnterpriseInstallAttributes::Init(const base::FilePath& cache_file) {
67 const base::FilePath& cache_file) { 78 DCHECK_EQ(false, device_locked_);
68 if (device_locked_ || !base::PathExists(cache_file)) 79
80 // The actual check happens asynchronously, thus it is ok to trigger it before
81 // Init() has completed.
82 TriggerConsistencyCheck(kDbusRetryCount * kDbusRetryIntervalInSeconds);
83
84 if (!base::PathExists(cache_file))
69 return; 85 return;
70 86
71 device_locked_ = true; 87 device_locked_ = true;
72 88
73 char buf[16384]; 89 char buf[16384];
74 int len = base::ReadFile(cache_file, buf, sizeof(buf)); 90 int len = base::ReadFile(cache_file, buf, sizeof(buf));
75 if (len == -1 || len >= static_cast<int>(sizeof(buf))) { 91 if (len == -1 || len >= static_cast<int>(sizeof(buf))) {
76 PLOG(ERROR) << "Failed to read " << cache_file.value(); 92 PLOG(ERROR) << "Failed to read " << cache_file.value();
77 return; 93 return;
78 } 94 }
(...skipping 63 matching lines...) Expand 10 before | Expand all | Expand 10 after
142 } 158 }
143 callback.Run(); 159 callback.Run();
144 } 160 }
145 161
146 void EnterpriseInstallAttributes::LockDevice( 162 void EnterpriseInstallAttributes::LockDevice(
147 const std::string& user, 163 const std::string& user,
148 DeviceMode device_mode, 164 DeviceMode device_mode,
149 const std::string& device_id, 165 const std::string& device_id,
150 const LockResultCallback& callback) { 166 const LockResultCallback& callback) {
151 DCHECK(!callback.is_null()); 167 DCHECK(!callback.is_null());
168 CHECK_EQ(registration_running_, false);
152 CHECK_NE(device_mode, DEVICE_MODE_PENDING); 169 CHECK_NE(device_mode, DEVICE_MODE_PENDING);
153 CHECK_NE(device_mode, DEVICE_MODE_NOT_SET); 170 CHECK_NE(device_mode, DEVICE_MODE_NOT_SET);
154 171
155 // Check for existing lock first. 172 // Check for existing lock first.
156 if (device_locked_) { 173 if (device_locked_) {
157 if (device_mode != registration_mode_) { 174 if (device_mode != registration_mode_) {
158 callback.Run(LOCK_WRONG_MODE); 175 callback.Run(LOCK_WRONG_MODE);
159 return; 176 return;
160 } 177 }
161 178
(...skipping 17 matching lines...) Expand all
179 case DEVICE_MODE_CONSUMER_KIOSK_AUTOLAUNCH: 196 case DEVICE_MODE_CONSUMER_KIOSK_AUTOLAUNCH:
180 // The user parameter is ignored for consumer devices. 197 // The user parameter is ignored for consumer devices.
181 break; 198 break;
182 } 199 }
183 200
184 // Already locked in the right mode, signal success. 201 // Already locked in the right mode, signal success.
185 callback.Run(LOCK_SUCCESS); 202 callback.Run(LOCK_SUCCESS);
186 return; 203 return;
187 } 204 }
188 205
206 registration_running_ = true;
Mattias Nissler (ping if slow) 2015/06/24 13:26:06 nit: It's kinda unfortunate (and fragile) to have
Thiemo Nagel 2015/06/24 15:27:40 I guess that one could also do void EnterpriseIns
Mattias Nissler (ping if slow) 2015/06/24 18:37:10 Yes, that's also a valid approach.
Thiemo Nagel 2015/06/25 09:04:06 Alight. I'd prefer to keep it as it is, then.
207
208 // In case the consistency check is still running, postpone the device locking
209 // until it has finished. This should not introduce additional delay since
210 // device locking must wait for TPM initialization anyways.
211 if (consistency_check_running_) {
212 post_check_action_ = base::Bind(&EnterpriseInstallAttributes::LockDevice,
213 weak_ptr_factory_.GetWeakPtr(),
214 user,
215 device_mode,
216 device_id,
217 callback);
218 return;
219 }
220
189 cryptohome_client_->InstallAttributesIsReady( 221 cryptohome_client_->InstallAttributesIsReady(
190 base::Bind(&EnterpriseInstallAttributes::LockDeviceIfAttributesIsReady, 222 base::Bind(&EnterpriseInstallAttributes::LockDeviceIfAttributesIsReady,
191 weak_ptr_factory_.GetWeakPtr(), 223 weak_ptr_factory_.GetWeakPtr(),
192 user, 224 user,
193 device_mode, 225 device_mode,
194 device_id, 226 device_id,
195 callback)); 227 callback));
196 } 228 }
197 229
198 void EnterpriseInstallAttributes::LockDeviceIfAttributesIsReady( 230 void EnterpriseInstallAttributes::LockDeviceIfAttributesIsReady(
199 const std::string& user, 231 const std::string& user,
200 DeviceMode device_mode, 232 DeviceMode device_mode,
201 const std::string& device_id, 233 const std::string& device_id,
202 const LockResultCallback& callback, 234 const LockResultCallback& callback,
203 chromeos::DBusMethodCallStatus call_status, 235 chromeos::DBusMethodCallStatus call_status,
204 bool result) { 236 bool result) {
205 if (call_status != chromeos::DBUS_METHOD_CALL_SUCCESS || !result) { 237 if (call_status != chromeos::DBUS_METHOD_CALL_SUCCESS || !result) {
238 registration_running_ = false;
206 callback.Run(LOCK_NOT_READY); 239 callback.Run(LOCK_NOT_READY);
207 return; 240 return;
208 } 241 }
209 242
210 // Clearing the TPM password seems to be always a good deal. 243 // Clearing the TPM password seems to be always a good deal.
211 if (cryptohome_util::TpmIsEnabled() && 244 if (cryptohome_util::TpmIsEnabled() &&
212 !cryptohome_util::TpmIsBeingOwned() && 245 !cryptohome_util::TpmIsBeingOwned() &&
213 cryptohome_util::TpmIsOwned()) { 246 cryptohome_util::TpmIsOwned()) {
214 cryptohome_client_->CallTpmClearStoredPasswordAndBlock(); 247 cryptohome_client_->CallTpmClearStoredPasswordAndBlock();
215 } 248 }
216 249
217 // Make sure we really have a working InstallAttrs. 250 // Make sure we really have a working InstallAttrs.
218 if (cryptohome_util::InstallAttributesIsInvalid()) { 251 if (cryptohome_util::InstallAttributesIsInvalid()) {
219 LOG(ERROR) << "Install attributes invalid."; 252 LOG(ERROR) << "Install attributes invalid.";
253 registration_running_ = false;
220 callback.Run(LOCK_BACKEND_INVALID); 254 callback.Run(LOCK_BACKEND_INVALID);
221 return; 255 return;
222 } 256 }
223 257
224 if (!cryptohome_util::InstallAttributesIsFirstInstall()) { 258 if (!cryptohome_util::InstallAttributesIsFirstInstall()) {
225 LOG(ERROR) << "Install attributes already installed."; 259 LOG(ERROR) << "Install attributes already installed.";
260 registration_running_ = false;
226 callback.Run(LOCK_ALREADY_LOCKED); 261 callback.Run(LOCK_ALREADY_LOCKED);
227 return; 262 return;
228 } 263 }
229 264
230 std::string mode = GetDeviceModeString(device_mode); 265 std::string mode = GetDeviceModeString(device_mode);
231 std::string registration_user; 266 std::string registration_user;
232 if (!user.empty()) 267 if (!user.empty())
233 registration_user = gaia::CanonicalizeEmail(user); 268 registration_user = gaia::CanonicalizeEmail(user);
234 269
235 if (device_mode == DEVICE_MODE_CONSUMER_KIOSK_AUTOLAUNCH) { 270 if (device_mode == DEVICE_MODE_CONSUMER_KIOSK_AUTOLAUNCH) {
236 // Set values in the InstallAttrs and lock it. 271 // Set values in the InstallAttrs and lock it.
237 if (!cryptohome_util::InstallAttributesSet(kAttrConsumerKioskEnabled, 272 if (!cryptohome_util::InstallAttributesSet(kAttrConsumerKioskEnabled,
238 "true")) { 273 "true")) {
239 LOG(ERROR) << "Failed writing attributes."; 274 LOG(ERROR) << "Failed writing attributes.";
275 registration_running_ = false;
240 callback.Run(LOCK_SET_ERROR); 276 callback.Run(LOCK_SET_ERROR);
241 return; 277 return;
242 } 278 }
243 } else { 279 } else {
244 std::string domain = gaia::ExtractDomainName(registration_user); 280 std::string domain = gaia::ExtractDomainName(registration_user);
245 // Set values in the InstallAttrs and lock it. 281 // Set values in the InstallAttrs and lock it.
246 if (!cryptohome_util::InstallAttributesSet(kAttrEnterpriseOwned, "true") || 282 if (!cryptohome_util::InstallAttributesSet(kAttrEnterpriseOwned, "true") ||
247 !cryptohome_util::InstallAttributesSet(kAttrEnterpriseUser, 283 !cryptohome_util::InstallAttributesSet(kAttrEnterpriseUser,
248 registration_user) || 284 registration_user) ||
249 !cryptohome_util::InstallAttributesSet(kAttrEnterpriseDomain, 285 !cryptohome_util::InstallAttributesSet(kAttrEnterpriseDomain,
250 domain) || 286 domain) ||
251 !cryptohome_util::InstallAttributesSet(kAttrEnterpriseMode, mode) || 287 !cryptohome_util::InstallAttributesSet(kAttrEnterpriseMode, mode) ||
252 !cryptohome_util::InstallAttributesSet(kAttrEnterpriseDeviceId, 288 !cryptohome_util::InstallAttributesSet(kAttrEnterpriseDeviceId,
253 device_id)) { 289 device_id)) {
254 LOG(ERROR) << "Failed writing attributes."; 290 LOG(ERROR) << "Failed writing attributes.";
291 registration_running_ = false;
255 callback.Run(LOCK_SET_ERROR); 292 callback.Run(LOCK_SET_ERROR);
256 return; 293 return;
257 } 294 }
258 } 295 }
259 296
260 if (!cryptohome_util::InstallAttributesFinalize() || 297 if (!cryptohome_util::InstallAttributesFinalize() ||
261 cryptohome_util::InstallAttributesIsFirstInstall()) { 298 cryptohome_util::InstallAttributesIsFirstInstall()) {
262 LOG(ERROR) << "Failed locking."; 299 LOG(ERROR) << "Failed locking.";
300 registration_running_ = false;
263 callback.Run(LOCK_FINALIZE_ERROR); 301 callback.Run(LOCK_FINALIZE_ERROR);
264 return; 302 return;
265 } 303 }
266 304
267 ReadImmutableAttributes( 305 ReadImmutableAttributes(
268 base::Bind(&EnterpriseInstallAttributes::OnReadImmutableAttributes, 306 base::Bind(&EnterpriseInstallAttributes::OnReadImmutableAttributes,
269 weak_ptr_factory_.GetWeakPtr(), 307 weak_ptr_factory_.GetWeakPtr(),
270 registration_user, 308 registration_user,
271 callback)); 309 callback));
272 } 310 }
273 311
274 void EnterpriseInstallAttributes::OnReadImmutableAttributes( 312 void EnterpriseInstallAttributes::OnReadImmutableAttributes(
275 const std::string& registration_user, 313 const std::string& registration_user,
276 const LockResultCallback& callback) { 314 const LockResultCallback& callback) {
277 315
278 if (GetRegistrationUser() != registration_user) { 316 if (GetRegistrationUser() != registration_user) {
279 LOG(ERROR) << "Locked data doesn't match."; 317 LOG(ERROR) << "Locked data doesn't match.";
318 registration_running_ = false;
280 callback.Run(LOCK_READBACK_ERROR); 319 callback.Run(LOCK_READBACK_ERROR);
281 return; 320 return;
282 } 321 }
283 322
323 registration_running_ = false;
284 callback.Run(LOCK_SUCCESS); 324 callback.Run(LOCK_SUCCESS);
285 } 325 }
286 326
287 bool EnterpriseInstallAttributes::IsEnterpriseDevice() { 327 bool EnterpriseInstallAttributes::IsEnterpriseDevice() {
288 return device_locked_ && !registration_user_.empty(); 328 return device_locked_ && !registration_user_.empty();
289 } 329 }
290 330
291 bool EnterpriseInstallAttributes::IsConsumerKioskDeviceWithAutoLaunch() { 331 bool EnterpriseInstallAttributes::IsConsumerKioskDeviceWithAutoLaunch() {
292 return device_locked_ && 332 return device_locked_ &&
293 registration_mode_ == DEVICE_MODE_CONSUMER_KIOSK_AUTOLAUNCH; 333 registration_mode_ == DEVICE_MODE_CONSUMER_KIOSK_AUTOLAUNCH;
(...skipping 17 matching lines...) Expand all
311 if (!IsEnterpriseDevice()) 351 if (!IsEnterpriseDevice())
312 return std::string(); 352 return std::string();
313 353
314 return registration_device_id_; 354 return registration_device_id_;
315 } 355 }
316 356
317 DeviceMode EnterpriseInstallAttributes::GetMode() { 357 DeviceMode EnterpriseInstallAttributes::GetMode() {
318 return registration_mode_; 358 return registration_mode_;
319 } 359 }
320 360
361 void EnterpriseInstallAttributes::TriggerConsistencyCheck(
362 int dbus_retries) {
363 consistency_check_running_ = true;
364 cryptohome_client_->TpmIsOwned(base::Bind(
365 &EnterpriseInstallAttributes::OnTpmOwnerCheckCompleted,
366 weak_ptr_factory_.GetWeakPtr(),
367 dbus_retries));
368 }
369
370 void EnterpriseInstallAttributes::OnTpmOwnerCheckCompleted(
371 int dbus_retries_remaining,
372 chromeos::DBusMethodCallStatus call_status,
373 bool result) {
374 if (call_status != chromeos::DBUS_METHOD_CALL_SUCCESS &&
375 dbus_retries_remaining) {
376 base::MessageLoop::current()->PostDelayedTask(
377 FROM_HERE,
378 base::Bind(&EnterpriseInstallAttributes::TriggerConsistencyCheck,
379 weak_ptr_factory_.GetWeakPtr(),
380 dbus_retries_remaining - 1),
381 base::TimeDelta::FromSeconds(kDbusRetryIntervalInSeconds));
382 return;
383 }
384
385 base::HistogramBase::Sample state = device_locked_;
386 state |= 0x2 * (registration_mode_ == DEVICE_MODE_ENTERPRISE);
387 if (call_status == chromeos::DBUS_METHOD_CALL_SUCCESS)
388 state |= 0x4 * result;
389 else
390 state = 0x8; // This case is not a bit mask.
391 UMA_HISTOGRAM_ENUMERATION("Enterprise.AttributesTPMConsistency", state, 9);
392
393 // Run any action (LockDevice call) that might have queued behind the
394 // consistency check.
395 consistency_check_running_ = false;
396 if (!post_check_action_.is_null())
397 post_check_action_.Run();
Mattias Nissler (ping if slow) 2015/06/24 13:26:06 nit: add a post_check_action_.reset() here
Thiemo Nagel 2015/06/24 14:05:39 The owner check _should_ only run once, but yes, s
398 }
399
321 // Warning: The values for these keys (but not the keys themselves) are stored 400 // Warning: The values for these keys (but not the keys themselves) are stored
322 // in the protobuf with a trailing zero. Also note that some of these constants 401 // in the protobuf with a trailing zero. Also note that some of these constants
323 // have been copied to login_manager/device_policy_service.cc. Please make sure 402 // have been copied to login_manager/device_policy_service.cc. Please make sure
324 // that all changes to the constants are reflected there as well. 403 // that all changes to the constants are reflected there as well.
325 const char EnterpriseInstallAttributes::kConsumerDeviceMode[] = "consumer"; 404 const char EnterpriseInstallAttributes::kConsumerDeviceMode[] = "consumer";
326 const char EnterpriseInstallAttributes::kEnterpriseDeviceMode[] = "enterprise"; 405 const char EnterpriseInstallAttributes::kEnterpriseDeviceMode[] = "enterprise";
327 const char EnterpriseInstallAttributes::kLegacyRetailDeviceMode[] = "kiosk"; 406 const char EnterpriseInstallAttributes::kLegacyRetailDeviceMode[] = "kiosk";
328 const char EnterpriseInstallAttributes::kConsumerKioskDeviceMode[] = 407 const char EnterpriseInstallAttributes::kConsumerKioskDeviceMode[] =
329 "consumer_kiosk"; 408 "consumer_kiosk";
330 const char EnterpriseInstallAttributes::kUnknownDeviceMode[] = "unknown"; 409 const char EnterpriseInstallAttributes::kUnknownDeviceMode[] = "unknown";
(...skipping 77 matching lines...) Expand 10 before | Expand all | Expand 10 after
408 &consumer_kiosk_enabled) && 487 &consumer_kiosk_enabled) &&
409 consumer_kiosk_enabled == "true") { 488 consumer_kiosk_enabled == "true") {
410 registration_mode_ = DEVICE_MODE_CONSUMER_KIOSK_AUTOLAUNCH; 489 registration_mode_ = DEVICE_MODE_CONSUMER_KIOSK_AUTOLAUNCH;
411 } else if (enterprise_user.empty() && enterprise_owned != "true") { 490 } else if (enterprise_user.empty() && enterprise_owned != "true") {
412 // |registration_user_| is empty on consumer devices. 491 // |registration_user_| is empty on consumer devices.
413 registration_mode_ = DEVICE_MODE_CONSUMER; 492 registration_mode_ = DEVICE_MODE_CONSUMER;
414 } 493 }
415 } 494 }
416 495
417 } // namespace policy 496 } // namespace policy
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698