Upstream version 10.39.225.0
[platform/framework/web/crosswalk.git] / src / chrome / browser / chromeos / policy / enterprise_install_attributes.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/enterprise_install_attributes.h"
6
7 #include <utility>
8
9 #include "base/bind.h"
10 #include "base/files/file_util.h"
11 #include "base/location.h"
12 #include "base/logging.h"
13 #include "base/message_loop/message_loop.h"
14 #include "chrome/browser/chromeos/policy/proto/install_attributes.pb.h"
15 #include "chromeos/cryptohome/cryptohome_util.h"
16 #include "chromeos/dbus/dbus_thread_manager.h"
17 #include "google_apis/gaia/gaia_auth_util.h"
18
19 namespace policy {
20
21 namespace cryptohome_util = chromeos::cryptohome_util;
22
23 namespace {
24
25 bool ReadMapKey(const std::map<std::string, std::string>& map,
26                 const std::string& key,
27                 std::string* value) {
28   std::map<std::string, std::string>::const_iterator entry = map.find(key);
29   if (entry == map.end())
30     return false;
31
32   *value = entry->second;
33   return true;
34 }
35
36 }  // namespace
37
38 // static
39 std::string
40 EnterpriseInstallAttributes::GetEnterpriseOwnedInstallAttributesBlobForTesting(
41     const std::string& user_name) {
42   cryptohome::SerializedInstallAttributes install_attrs_proto;
43   cryptohome::SerializedInstallAttributes::Attribute* attribute = NULL;
44
45   attribute = install_attrs_proto.add_attributes();
46   attribute->set_name(EnterpriseInstallAttributes::kAttrEnterpriseOwned);
47   attribute->set_value("true");
48
49   attribute = install_attrs_proto.add_attributes();
50   attribute->set_name(EnterpriseInstallAttributes::kAttrEnterpriseUser);
51   attribute->set_value(user_name);
52
53   return install_attrs_proto.SerializeAsString();
54 }
55
56 EnterpriseInstallAttributes::EnterpriseInstallAttributes(
57     chromeos::CryptohomeClient* cryptohome_client)
58     : device_locked_(false),
59       registration_mode_(DEVICE_MODE_PENDING),
60       cryptohome_client_(cryptohome_client),
61       weak_ptr_factory_(this) {
62 }
63
64 EnterpriseInstallAttributes::~EnterpriseInstallAttributes() {}
65
66 void EnterpriseInstallAttributes::ReadCacheFile(
67     const base::FilePath& cache_file) {
68   if (device_locked_ || !base::PathExists(cache_file))
69     return;
70
71   device_locked_ = true;
72
73   char buf[16384];
74   int len = base::ReadFile(cache_file, buf, sizeof(buf));
75   if (len == -1 || len >= static_cast<int>(sizeof(buf))) {
76     PLOG(ERROR) << "Failed to read " << cache_file.value();
77     return;
78   }
79
80   cryptohome::SerializedInstallAttributes install_attrs_proto;
81   if (!install_attrs_proto.ParseFromArray(buf, len)) {
82     LOG(ERROR) << "Failed to parse install attributes cache";
83     return;
84   }
85
86   google::protobuf::RepeatedPtrField<
87       const cryptohome::SerializedInstallAttributes::Attribute>::iterator entry;
88   std::map<std::string, std::string> attr_map;
89   for (entry = install_attrs_proto.attributes().begin();
90        entry != install_attrs_proto.attributes().end();
91        ++entry) {
92     // The protobuf values unfortunately contain terminating null characters, so
93     // we have to sanitize the value here.
94     attr_map.insert(std::make_pair(entry->name(),
95                                    std::string(entry->value().c_str())));
96   }
97
98   DecodeInstallAttributes(attr_map);
99 }
100
101 void EnterpriseInstallAttributes::ReadImmutableAttributes(
102     const base::Closure& callback) {
103   if (device_locked_) {
104     callback.Run();
105     return;
106   }
107
108   cryptohome_client_->InstallAttributesIsReady(
109       base::Bind(&EnterpriseInstallAttributes::ReadAttributesIfReady,
110                  weak_ptr_factory_.GetWeakPtr(),
111                  callback));
112 }
113
114 void EnterpriseInstallAttributes::ReadAttributesIfReady(
115     const base::Closure& callback,
116     chromeos::DBusMethodCallStatus call_status,
117     bool result) {
118   if (call_status == chromeos::DBUS_METHOD_CALL_SUCCESS && result) {
119     registration_mode_ = DEVICE_MODE_NOT_SET;
120     if (!cryptohome_util::InstallAttributesIsInvalid() &&
121         !cryptohome_util::InstallAttributesIsFirstInstall()) {
122       device_locked_ = true;
123
124       static const char* kEnterpriseAttributes[] = {
125         kAttrEnterpriseDeviceId,
126         kAttrEnterpriseDomain,
127         kAttrEnterpriseMode,
128         kAttrEnterpriseOwned,
129         kAttrEnterpriseUser,
130         kAttrConsumerKioskEnabled,
131       };
132       std::map<std::string, std::string> attr_map;
133       for (size_t i = 0; i < arraysize(kEnterpriseAttributes); ++i) {
134         std::string value;
135         if (cryptohome_util::InstallAttributesGet(kEnterpriseAttributes[i],
136                                                   &value))
137           attr_map[kEnterpriseAttributes[i]] = value;
138       }
139
140       DecodeInstallAttributes(attr_map);
141     }
142   }
143   callback.Run();
144 }
145
146 void EnterpriseInstallAttributes::LockDevice(
147     const std::string& user,
148     DeviceMode device_mode,
149     const std::string& device_id,
150     const LockResultCallback& callback) {
151   DCHECK(!callback.is_null());
152   CHECK_NE(device_mode, DEVICE_MODE_PENDING);
153   CHECK_NE(device_mode, DEVICE_MODE_NOT_SET);
154
155   // Check for existing lock first.
156   if (device_locked_) {
157     if (device_mode == DEVICE_MODE_CONSUMER_KIOSK_AUTOLAUNCH) {
158       callback.Run((registration_mode_ == device_mode) ? LOCK_SUCCESS :
159                                                          LOCK_NOT_READY);
160     } else {
161       std::string domain = gaia::ExtractDomainName(user);
162       callback.Run(
163           (!registration_domain_.empty() && domain == registration_domain_) ?
164               LOCK_SUCCESS : LOCK_WRONG_USER);
165     }
166     return;
167   }
168
169   cryptohome_client_->InstallAttributesIsReady(
170       base::Bind(&EnterpriseInstallAttributes::LockDeviceIfAttributesIsReady,
171                  weak_ptr_factory_.GetWeakPtr(),
172                  user,
173                  device_mode,
174                  device_id,
175                  callback));
176 }
177
178 void EnterpriseInstallAttributes::LockDeviceIfAttributesIsReady(
179     const std::string& user,
180     DeviceMode device_mode,
181     const std::string& device_id,
182     const LockResultCallback& callback,
183     chromeos::DBusMethodCallStatus call_status,
184     bool result) {
185   if (call_status != chromeos::DBUS_METHOD_CALL_SUCCESS || !result) {
186     callback.Run(LOCK_NOT_READY);
187     return;
188   }
189
190   // Clearing the TPM password seems to be always a good deal.
191   if (cryptohome_util::TpmIsEnabled() &&
192       !cryptohome_util::TpmIsBeingOwned() &&
193       cryptohome_util::TpmIsOwned()) {
194     cryptohome_client_->CallTpmClearStoredPasswordAndBlock();
195   }
196
197   // Make sure we really have a working InstallAttrs.
198   if (cryptohome_util::InstallAttributesIsInvalid()) {
199     LOG(ERROR) << "Install attributes invalid.";
200     callback.Run(LOCK_BACKEND_ERROR);
201     return;
202   }
203
204   if (!cryptohome_util::InstallAttributesIsFirstInstall()) {
205     callback.Run(LOCK_WRONG_USER);
206     return;
207   }
208
209   std::string mode = GetDeviceModeString(device_mode);
210   std::string registration_user;
211   if (!user.empty())
212     registration_user = gaia::CanonicalizeEmail(user);
213
214   if (device_mode == DEVICE_MODE_CONSUMER_KIOSK_AUTOLAUNCH) {
215     // Set values in the InstallAttrs and lock it.
216     if (!cryptohome_util::InstallAttributesSet(kAttrConsumerKioskEnabled,
217                                                "true")) {
218       LOG(ERROR) << "Failed writing attributes";
219       callback.Run(LOCK_BACKEND_ERROR);
220       return;
221     }
222   } else {
223     std::string domain = gaia::ExtractDomainName(registration_user);
224     // Set values in the InstallAttrs and lock it.
225     if (!cryptohome_util::InstallAttributesSet(kAttrEnterpriseOwned, "true") ||
226         !cryptohome_util::InstallAttributesSet(kAttrEnterpriseUser,
227                                                registration_user) ||
228         !cryptohome_util::InstallAttributesSet(kAttrEnterpriseDomain,
229                                                domain) ||
230         !cryptohome_util::InstallAttributesSet(kAttrEnterpriseMode, mode) ||
231         !cryptohome_util::InstallAttributesSet(kAttrEnterpriseDeviceId,
232                                                device_id)) {
233       LOG(ERROR) << "Failed writing attributes";
234       callback.Run(LOCK_BACKEND_ERROR);
235       return;
236     }
237   }
238
239   if (!cryptohome_util::InstallAttributesFinalize() ||
240       cryptohome_util::InstallAttributesIsFirstInstall()) {
241     LOG(ERROR) << "Failed locking.";
242     callback.Run(LOCK_BACKEND_ERROR);
243     return;
244   }
245
246   ReadImmutableAttributes(
247       base::Bind(&EnterpriseInstallAttributes::OnReadImmutableAttributes,
248                  weak_ptr_factory_.GetWeakPtr(),
249                  registration_user,
250                  callback));
251 }
252
253 void EnterpriseInstallAttributes::OnReadImmutableAttributes(
254     const std::string& registration_user,
255     const LockResultCallback& callback) {
256
257   if (GetRegistrationUser() != registration_user) {
258     LOG(ERROR) << "Locked data doesn't match";
259     callback.Run(LOCK_BACKEND_ERROR);
260     return;
261   }
262
263   callback.Run(LOCK_SUCCESS);
264 }
265
266 bool EnterpriseInstallAttributes::IsEnterpriseDevice() {
267   return device_locked_ && !registration_user_.empty();
268 }
269
270 bool EnterpriseInstallAttributes::IsConsumerKioskDeviceWithAutoLaunch() {
271   return device_locked_ &&
272          registration_mode_ == DEVICE_MODE_CONSUMER_KIOSK_AUTOLAUNCH;
273 }
274
275 std::string EnterpriseInstallAttributes::GetRegistrationUser() {
276   if (!device_locked_)
277     return std::string();
278
279   return registration_user_;
280 }
281
282 std::string EnterpriseInstallAttributes::GetDomain() {
283   if (!IsEnterpriseDevice())
284     return std::string();
285
286   return registration_domain_;
287 }
288
289 std::string EnterpriseInstallAttributes::GetDeviceId() {
290   if (!IsEnterpriseDevice())
291     return std::string();
292
293   return registration_device_id_;
294 }
295
296 DeviceMode EnterpriseInstallAttributes::GetMode() {
297   return registration_mode_;
298 }
299
300 // Warning: The values for these keys (but not the keys themselves) are stored
301 // in the protobuf with a trailing zero.  Also note that some of these constants
302 // have been copied to login_manager/device_policy_service.cc.  Please make sure
303 // that all changes to the constants are reflected there as well.
304 const char EnterpriseInstallAttributes::kConsumerDeviceMode[] = "consumer";
305 const char EnterpriseInstallAttributes::kEnterpriseDeviceMode[] = "enterprise";
306 const char EnterpriseInstallAttributes::kRetailKioskDeviceMode[] = "kiosk";
307 const char EnterpriseInstallAttributes::kConsumerKioskDeviceMode[] =
308     "consumer_kiosk";
309 const char EnterpriseInstallAttributes::kUnknownDeviceMode[] = "unknown";
310
311 const char EnterpriseInstallAttributes::kAttrEnterpriseDeviceId[] =
312     "enterprise.device_id";
313 const char EnterpriseInstallAttributes::kAttrEnterpriseDomain[] =
314     "enterprise.domain";
315 const char EnterpriseInstallAttributes::kAttrEnterpriseMode[] =
316     "enterprise.mode";
317 const char EnterpriseInstallAttributes::kAttrEnterpriseOwned[] =
318     "enterprise.owned";
319 const char EnterpriseInstallAttributes::kAttrEnterpriseUser[] =
320     "enterprise.user";
321 const char EnterpriseInstallAttributes::kAttrConsumerKioskEnabled[] =
322     "consumer.app_kiosk_enabled";
323
324 std::string EnterpriseInstallAttributes::GetDeviceModeString(DeviceMode mode) {
325   switch (mode) {
326     case DEVICE_MODE_CONSUMER:
327       return EnterpriseInstallAttributes::kConsumerDeviceMode;
328     case DEVICE_MODE_ENTERPRISE:
329       return EnterpriseInstallAttributes::kEnterpriseDeviceMode;
330     case DEVICE_MODE_RETAIL_KIOSK:
331       return EnterpriseInstallAttributes::kRetailKioskDeviceMode;
332     case DEVICE_MODE_CONSUMER_KIOSK_AUTOLAUNCH:
333       return EnterpriseInstallAttributes::kConsumerKioskDeviceMode;
334     case DEVICE_MODE_PENDING:
335     case DEVICE_MODE_NOT_SET:
336       break;
337   }
338   NOTREACHED() << "Invalid device mode: " << mode;
339   return EnterpriseInstallAttributes::kUnknownDeviceMode;
340 }
341
342 DeviceMode EnterpriseInstallAttributes::GetDeviceModeFromString(
343     const std::string& mode) {
344   if (mode == EnterpriseInstallAttributes::kConsumerDeviceMode)
345     return DEVICE_MODE_CONSUMER;
346   else if (mode == EnterpriseInstallAttributes::kEnterpriseDeviceMode)
347     return DEVICE_MODE_ENTERPRISE;
348   else if (mode == EnterpriseInstallAttributes::kRetailKioskDeviceMode)
349     return DEVICE_MODE_RETAIL_KIOSK;
350   else if (mode == EnterpriseInstallAttributes::kConsumerKioskDeviceMode)
351     return DEVICE_MODE_CONSUMER_KIOSK_AUTOLAUNCH;
352   NOTREACHED() << "Unknown device mode string: " << mode;
353   return DEVICE_MODE_NOT_SET;
354 }
355
356 void EnterpriseInstallAttributes::DecodeInstallAttributes(
357     const std::map<std::string, std::string>& attr_map) {
358   std::string enterprise_owned;
359   std::string enterprise_user;
360   std::string consumer_kiosk_enabled;
361   if (ReadMapKey(attr_map, kAttrEnterpriseOwned, &enterprise_owned) &&
362       ReadMapKey(attr_map, kAttrEnterpriseUser, &enterprise_user) &&
363       enterprise_owned == "true" &&
364       !enterprise_user.empty()) {
365     registration_user_ = gaia::CanonicalizeEmail(enterprise_user);
366
367     // Initialize the mode to the legacy enterprise mode here and update
368     // below if more information is present.
369     registration_mode_ = DEVICE_MODE_ENTERPRISE;
370
371     // If we could extract basic setting we should try to extract the
372     // extended ones too. We try to set these to defaults as good as
373     // as possible if present, which could happen for device enrolled in
374     // pre 19 revisions of the code, before these new attributes were added.
375     if (ReadMapKey(attr_map, kAttrEnterpriseDomain, &registration_domain_))
376       registration_domain_ = gaia::CanonicalizeDomain(registration_domain_);
377     else
378       registration_domain_ = gaia::ExtractDomainName(registration_user_);
379
380     ReadMapKey(attr_map, kAttrEnterpriseDeviceId, &registration_device_id_);
381
382     std::string mode;
383     if (ReadMapKey(attr_map, kAttrEnterpriseMode, &mode))
384       registration_mode_ = GetDeviceModeFromString(mode);
385   } else if (ReadMapKey(attr_map,
386                         kAttrConsumerKioskEnabled,
387                         &consumer_kiosk_enabled) &&
388              consumer_kiosk_enabled == "true") {
389     registration_mode_ = DEVICE_MODE_CONSUMER_KIOSK_AUTOLAUNCH;
390   } else if (enterprise_user.empty() && enterprise_owned != "true") {
391     // |registration_user_| is empty on consumer devices.
392     registration_mode_ = DEVICE_MODE_CONSUMER;
393   }
394 }
395
396 }  // namespace policy