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 "chromeos/dbus/session_manager_client.h" 6 7 #include <map> 8 9 #include "base/bind.h" 10 #include "base/callback.h" 11 #include "base/file_util.h" 12 #include "base/files/file_path.h" 13 #include "base/location.h" 14 #include "base/path_service.h" 15 #include "base/strings/string_util.h" 16 #include "base/threading/worker_pool.h" 17 #include "chromeos/chromeos_paths.h" 18 #include "chromeos/dbus/blocking_method_caller.h" 19 #include "chromeos/dbus/cryptohome_client.h" 20 #include "dbus/bus.h" 21 #include "dbus/message.h" 22 #include "dbus/object_path.h" 23 #include "dbus/object_proxy.h" 24 #include "third_party/cros_system_api/dbus/service_constants.h" 25 26 namespace chromeos { 27 28 // The SessionManagerClient implementation used in production. 29 class SessionManagerClientImpl : public SessionManagerClient { 30 public: 31 explicit SessionManagerClientImpl(dbus::Bus* bus) 32 : session_manager_proxy_(bus->GetObjectProxy( 33 login_manager::kSessionManagerServiceName, 34 dbus::ObjectPath(login_manager::kSessionManagerServicePath))), 35 blocking_method_caller_(bus, session_manager_proxy_), 36 weak_ptr_factory_(this) { 37 // Signals emitted on Chromium's interface. Many of these ought to be 38 // method calls instead. 39 session_manager_proxy_->ConnectToSignal( 40 chromium::kChromiumInterface, 41 chromium::kOwnerKeySetSignal, 42 base::Bind(&SessionManagerClientImpl::OwnerKeySetReceived, 43 weak_ptr_factory_.GetWeakPtr()), 44 base::Bind(&SessionManagerClientImpl::SignalConnected, 45 weak_ptr_factory_.GetWeakPtr())); 46 session_manager_proxy_->ConnectToSignal( 47 chromium::kChromiumInterface, 48 chromium::kPropertyChangeCompleteSignal, 49 base::Bind(&SessionManagerClientImpl::PropertyChangeCompleteReceived, 50 weak_ptr_factory_.GetWeakPtr()), 51 base::Bind(&SessionManagerClientImpl::SignalConnected, 52 weak_ptr_factory_.GetWeakPtr())); 53 session_manager_proxy_->ConnectToSignal( 54 chromium::kChromiumInterface, 55 chromium::kLockScreenSignal, 56 base::Bind(&SessionManagerClientImpl::ScreenLockReceived, 57 weak_ptr_factory_.GetWeakPtr()), 58 base::Bind(&SessionManagerClientImpl::SignalConnected, 59 weak_ptr_factory_.GetWeakPtr())); 60 session_manager_proxy_->ConnectToSignal( 61 chromium::kChromiumInterface, 62 chromium::kUnlockScreenSignal, 63 base::Bind(&SessionManagerClientImpl::ScreenUnlockReceived, 64 weak_ptr_factory_.GetWeakPtr()), 65 base::Bind(&SessionManagerClientImpl::SignalConnected, 66 weak_ptr_factory_.GetWeakPtr())); 67 session_manager_proxy_->ConnectToSignal( 68 chromium::kChromiumInterface, 69 chromium::kLivenessRequestedSignal, 70 base::Bind(&SessionManagerClientImpl::LivenessRequestedReceived, 71 weak_ptr_factory_.GetWeakPtr()), 72 base::Bind(&SessionManagerClientImpl::SignalConnected, 73 weak_ptr_factory_.GetWeakPtr())); 74 75 // Signals emitted on the session manager's interface. 76 session_manager_proxy_->ConnectToSignal( 77 login_manager::kSessionManagerInterface, 78 login_manager::kScreenIsLockedSignal, 79 base::Bind(&SessionManagerClientImpl::ScreenIsLockedReceived, 80 weak_ptr_factory_.GetWeakPtr()), 81 base::Bind(&SessionManagerClientImpl::SignalConnected, 82 weak_ptr_factory_.GetWeakPtr())); 83 session_manager_proxy_->ConnectToSignal( 84 login_manager::kSessionManagerInterface, 85 login_manager::kScreenIsUnlockedSignal, 86 base::Bind(&SessionManagerClientImpl::ScreenIsUnlockedReceived, 87 weak_ptr_factory_.GetWeakPtr()), 88 base::Bind(&SessionManagerClientImpl::SignalConnected, 89 weak_ptr_factory_.GetWeakPtr())); 90 } 91 92 virtual ~SessionManagerClientImpl() { 93 } 94 95 // SessionManagerClient overrides: 96 virtual void AddObserver(Observer* observer) OVERRIDE { 97 observers_.AddObserver(observer); 98 } 99 100 virtual void RemoveObserver(Observer* observer) OVERRIDE { 101 observers_.RemoveObserver(observer); 102 } 103 104 virtual bool HasObserver(Observer* observer) OVERRIDE { 105 return observers_.HasObserver(observer); 106 } 107 108 virtual void EmitLoginPromptReady() OVERRIDE { 109 SimpleMethodCallToSessionManager( 110 login_manager::kSessionManagerEmitLoginPromptReady); 111 } 112 113 virtual void EmitLoginPromptVisible() OVERRIDE { 114 SimpleMethodCallToSessionManager( 115 login_manager::kSessionManagerEmitLoginPromptVisible); 116 } 117 118 virtual void RestartJob(int pid, const std::string& command_line) OVERRIDE { 119 dbus::MethodCall method_call(login_manager::kSessionManagerInterface, 120 login_manager::kSessionManagerRestartJob); 121 dbus::MessageWriter writer(&method_call); 122 writer.AppendInt32(pid); 123 writer.AppendString(command_line); 124 session_manager_proxy_->CallMethod( 125 &method_call, 126 dbus::ObjectProxy::TIMEOUT_USE_DEFAULT, 127 base::Bind(&SessionManagerClientImpl::OnRestartJob, 128 weak_ptr_factory_.GetWeakPtr())); 129 } 130 131 virtual void RestartEntd() OVERRIDE { 132 SimpleMethodCallToSessionManager(login_manager::kSessionManagerRestartEntd); 133 } 134 135 virtual void StartSession(const std::string& user_email) OVERRIDE { 136 dbus::MethodCall method_call(login_manager::kSessionManagerInterface, 137 login_manager::kSessionManagerStartSession); 138 dbus::MessageWriter writer(&method_call); 139 writer.AppendString(user_email); 140 writer.AppendString(""); // Unique ID is deprecated 141 session_manager_proxy_->CallMethod( 142 &method_call, 143 dbus::ObjectProxy::TIMEOUT_USE_DEFAULT, 144 base::Bind(&SessionManagerClientImpl::OnStartSession, 145 weak_ptr_factory_.GetWeakPtr())); 146 } 147 148 virtual void StopSession() OVERRIDE { 149 dbus::MethodCall method_call(login_manager::kSessionManagerInterface, 150 login_manager::kSessionManagerStopSession); 151 dbus::MessageWriter writer(&method_call); 152 writer.AppendString(""); // Unique ID is deprecated 153 session_manager_proxy_->CallMethod( 154 &method_call, 155 dbus::ObjectProxy::TIMEOUT_USE_DEFAULT, 156 base::Bind(&SessionManagerClientImpl::OnStopSession, 157 weak_ptr_factory_.GetWeakPtr())); 158 } 159 160 virtual void StartDeviceWipe() OVERRIDE { 161 dbus::MethodCall method_call(login_manager::kSessionManagerInterface, 162 login_manager::kSessionManagerStartDeviceWipe); 163 session_manager_proxy_->CallMethod( 164 &method_call, 165 dbus::ObjectProxy::TIMEOUT_USE_DEFAULT, 166 base::Bind(&SessionManagerClientImpl::OnDeviceWipe, 167 weak_ptr_factory_.GetWeakPtr())); 168 } 169 170 virtual void RequestLockScreen() OVERRIDE { 171 SimpleMethodCallToSessionManager(login_manager::kSessionManagerLockScreen); 172 } 173 174 virtual void NotifyLockScreenShown() OVERRIDE { 175 SimpleMethodCallToSessionManager( 176 login_manager::kSessionManagerHandleLockScreenShown); 177 } 178 179 virtual void RequestUnlockScreen() OVERRIDE { 180 SimpleMethodCallToSessionManager( 181 login_manager::kSessionManagerUnlockScreen); 182 } 183 184 virtual void NotifyLockScreenDismissed() OVERRIDE { 185 SimpleMethodCallToSessionManager( 186 login_manager::kSessionManagerHandleLockScreenDismissed); 187 } 188 189 virtual void RetrieveActiveSessions( 190 const ActiveSessionsCallback& callback) OVERRIDE { 191 dbus::MethodCall method_call( 192 login_manager::kSessionManagerInterface, 193 login_manager::kSessionManagerRetrieveActiveSessions); 194 195 session_manager_proxy_->CallMethod( 196 &method_call, 197 dbus::ObjectProxy::TIMEOUT_USE_DEFAULT, 198 base::Bind(&SessionManagerClientImpl::OnRetrieveActiveSessions, 199 weak_ptr_factory_.GetWeakPtr(), 200 login_manager::kSessionManagerRetrieveActiveSessions, 201 callback)); 202 } 203 204 virtual void RetrieveDevicePolicy( 205 const RetrievePolicyCallback& callback) OVERRIDE { 206 dbus::MethodCall method_call(login_manager::kSessionManagerInterface, 207 login_manager::kSessionManagerRetrievePolicy); 208 session_manager_proxy_->CallMethod( 209 &method_call, 210 dbus::ObjectProxy::TIMEOUT_USE_DEFAULT, 211 base::Bind(&SessionManagerClientImpl::OnRetrievePolicy, 212 weak_ptr_factory_.GetWeakPtr(), 213 login_manager::kSessionManagerRetrievePolicy, 214 callback)); 215 } 216 217 virtual void RetrievePolicyForUser( 218 const std::string& username, 219 const RetrievePolicyCallback& callback) OVERRIDE { 220 CallRetrievePolicyByUsername( 221 login_manager::kSessionManagerRetrievePolicyForUser, 222 username, 223 callback); 224 } 225 226 virtual std::string BlockingRetrievePolicyForUser( 227 const std::string& username) OVERRIDE { 228 dbus::MethodCall method_call( 229 login_manager::kSessionManagerInterface, 230 login_manager::kSessionManagerRetrievePolicyForUser); 231 dbus::MessageWriter writer(&method_call); 232 writer.AppendString(username); 233 scoped_ptr<dbus::Response> response = 234 blocking_method_caller_.CallMethodAndBlock(&method_call); 235 std::string policy; 236 ExtractString(login_manager::kSessionManagerRetrievePolicyForUser, 237 response.get(), 238 &policy); 239 return policy; 240 } 241 242 virtual void RetrieveDeviceLocalAccountPolicy( 243 const std::string& account_name, 244 const RetrievePolicyCallback& callback) OVERRIDE { 245 CallRetrievePolicyByUsername( 246 login_manager::kSessionManagerRetrieveDeviceLocalAccountPolicy, 247 account_name, 248 callback); 249 } 250 251 virtual void StoreDevicePolicy(const std::string& policy_blob, 252 const StorePolicyCallback& callback) OVERRIDE { 253 dbus::MethodCall method_call(login_manager::kSessionManagerInterface, 254 login_manager::kSessionManagerStorePolicy); 255 dbus::MessageWriter writer(&method_call); 256 // static_cast does not work due to signedness. 257 writer.AppendArrayOfBytes( 258 reinterpret_cast<const uint8*>(policy_blob.data()), policy_blob.size()); 259 session_manager_proxy_->CallMethod( 260 &method_call, 261 dbus::ObjectProxy::TIMEOUT_USE_DEFAULT, 262 base::Bind(&SessionManagerClientImpl::OnStorePolicy, 263 weak_ptr_factory_.GetWeakPtr(), 264 login_manager::kSessionManagerStorePolicy, 265 callback)); 266 } 267 268 virtual void StorePolicyForUser( 269 const std::string& username, 270 const std::string& policy_blob, 271 const std::string& ignored_policy_key, 272 const StorePolicyCallback& callback) OVERRIDE { 273 CallStorePolicyByUsername(login_manager::kSessionManagerStorePolicyForUser, 274 username, 275 policy_blob, 276 callback); 277 } 278 279 virtual void StoreDeviceLocalAccountPolicy( 280 const std::string& account_name, 281 const std::string& policy_blob, 282 const StorePolicyCallback& callback) OVERRIDE { 283 CallStorePolicyByUsername( 284 login_manager::kSessionManagerStoreDeviceLocalAccountPolicy, 285 account_name, 286 policy_blob, 287 callback); 288 } 289 290 virtual void SetFlagsForUser(const std::string& username, 291 const std::vector<std::string>& flags) OVERRIDE { 292 dbus::MethodCall method_call(login_manager::kSessionManagerInterface, 293 login_manager::kSessionManagerSetFlagsForUser); 294 dbus::MessageWriter writer(&method_call); 295 writer.AppendString(username); 296 writer.AppendArrayOfStrings(flags); 297 session_manager_proxy_->CallMethod( 298 &method_call, 299 dbus::ObjectProxy::TIMEOUT_USE_DEFAULT, 300 dbus::ObjectProxy::EmptyResponseCallback()); 301 } 302 303 private: 304 // Makes a method call to the session manager with no arguments and no 305 // response. 306 void SimpleMethodCallToSessionManager(const std::string& method_name) { 307 dbus::MethodCall method_call(login_manager::kSessionManagerInterface, 308 method_name); 309 session_manager_proxy_->CallMethod( 310 &method_call, 311 dbus::ObjectProxy::TIMEOUT_USE_DEFAULT, 312 dbus::ObjectProxy::EmptyResponseCallback()); 313 } 314 315 // Helper for RetrieveDeviceLocalAccountPolicy and RetrievePolicyForUser. 316 void CallRetrievePolicyByUsername(const std::string& method_name, 317 const std::string& username, 318 const RetrievePolicyCallback& callback) { 319 dbus::MethodCall method_call(login_manager::kSessionManagerInterface, 320 method_name); 321 dbus::MessageWriter writer(&method_call); 322 writer.AppendString(username); 323 session_manager_proxy_->CallMethod( 324 &method_call, 325 dbus::ObjectProxy::TIMEOUT_USE_DEFAULT, 326 base::Bind( 327 &SessionManagerClientImpl::OnRetrievePolicy, 328 weak_ptr_factory_.GetWeakPtr(), 329 method_name, 330 callback)); 331 } 332 333 void CallStorePolicyByUsername(const std::string& method_name, 334 const std::string& username, 335 const std::string& policy_blob, 336 const StorePolicyCallback& callback) { 337 dbus::MethodCall method_call(login_manager::kSessionManagerInterface, 338 method_name); 339 dbus::MessageWriter writer(&method_call); 340 writer.AppendString(username); 341 // static_cast does not work due to signedness. 342 writer.AppendArrayOfBytes( 343 reinterpret_cast<const uint8*>(policy_blob.data()), policy_blob.size()); 344 session_manager_proxy_->CallMethod( 345 &method_call, 346 dbus::ObjectProxy::TIMEOUT_USE_DEFAULT, 347 base::Bind( 348 &SessionManagerClientImpl::OnStorePolicy, 349 weak_ptr_factory_.GetWeakPtr(), 350 method_name, 351 callback)); 352 } 353 354 // Called when kSessionManagerRestartJob method is complete. 355 void OnRestartJob(dbus::Response* response) { 356 LOG_IF(ERROR, !response) 357 << "Failed to call " 358 << login_manager::kSessionManagerRestartJob; 359 } 360 361 // Called when kSessionManagerStartSession method is complete. 362 void OnStartSession(dbus::Response* response) { 363 LOG_IF(ERROR, !response) 364 << "Failed to call " 365 << login_manager::kSessionManagerStartSession; 366 } 367 368 // Called when kSessionManagerStopSession method is complete. 369 void OnStopSession(dbus::Response* response) { 370 LOG_IF(ERROR, !response) 371 << "Failed to call " 372 << login_manager::kSessionManagerStopSession; 373 } 374 375 // Called when kSessionManagerStopSession method is complete. 376 void OnDeviceWipe(dbus::Response* response) { 377 LOG_IF(ERROR, !response) 378 << "Failed to call " 379 << login_manager::kSessionManagerStartDeviceWipe; 380 } 381 382 // Called when kSessionManagerRetrieveActiveSessions method is complete. 383 void OnRetrieveActiveSessions(const std::string& method_name, 384 const ActiveSessionsCallback& callback, 385 dbus::Response* response) { 386 ActiveSessionsMap sessions; 387 bool success = false; 388 if (!response) { 389 LOG(ERROR) << "Failed to call " << method_name; 390 callback.Run(sessions, success); 391 return; 392 } 393 394 dbus::MessageReader reader(response); 395 dbus::MessageReader array_reader(NULL); 396 397 if (!reader.PopArray(&array_reader)) { 398 LOG(ERROR) << method_name << " response is incorrect: " 399 << response->ToString(); 400 } else { 401 while (array_reader.HasMoreData()) { 402 dbus::MessageReader dict_entry_reader(NULL); 403 std::string key; 404 std::string value; 405 if (!array_reader.PopDictEntry(&dict_entry_reader) || 406 !dict_entry_reader.PopString(&key) || 407 !dict_entry_reader.PopString(&value)) { 408 LOG(ERROR) << method_name << " response is incorrect: " 409 << response->ToString(); 410 } else { 411 sessions[key] = value; 412 } 413 } 414 success = true; 415 } 416 callback.Run(sessions, success); 417 } 418 419 void ExtractString(const std::string& method_name, 420 dbus::Response* response, 421 std::string* extracted) { 422 if (!response) { 423 LOG(ERROR) << "Failed to call " << method_name; 424 return; 425 } 426 dbus::MessageReader reader(response); 427 uint8* values = NULL; 428 size_t length = 0; 429 if (!reader.PopArrayOfBytes(&values, &length)) { 430 LOG(ERROR) << "Invalid response: " << response->ToString(); 431 return; 432 } 433 // static_cast does not work due to signedness. 434 extracted->assign(reinterpret_cast<char*>(values), length); 435 } 436 437 // Called when kSessionManagerRetrievePolicy or 438 // kSessionManagerRetrievePolicyForUser method is complete. 439 void OnRetrievePolicy(const std::string& method_name, 440 const RetrievePolicyCallback& callback, 441 dbus::Response* response) { 442 std::string serialized_proto; 443 ExtractString(method_name, response, &serialized_proto); 444 callback.Run(serialized_proto); 445 } 446 447 // Called when kSessionManagerStorePolicy or kSessionManagerStorePolicyForUser 448 // method is complete. 449 void OnStorePolicy(const std::string& method_name, 450 const StorePolicyCallback& callback, 451 dbus::Response* response) { 452 bool success = false; 453 if (!response) { 454 LOG(ERROR) << "Failed to call " << method_name; 455 } else { 456 dbus::MessageReader reader(response); 457 if (!reader.PopBool(&success)) 458 LOG(ERROR) << "Invalid response: " << response->ToString(); 459 } 460 callback.Run(success); 461 } 462 463 // Called when the owner key set signal is received. 464 void OwnerKeySetReceived(dbus::Signal* signal) { 465 dbus::MessageReader reader(signal); 466 std::string result_string; 467 if (!reader.PopString(&result_string)) { 468 LOG(ERROR) << "Invalid signal: " << signal->ToString(); 469 return; 470 } 471 const bool success = StartsWithASCII(result_string, "success", false); 472 FOR_EACH_OBSERVER(Observer, observers_, OwnerKeySet(success)); 473 } 474 475 // Called when the property change complete signal is received. 476 void PropertyChangeCompleteReceived(dbus::Signal* signal) { 477 dbus::MessageReader reader(signal); 478 std::string result_string; 479 if (!reader.PopString(&result_string)) { 480 LOG(ERROR) << "Invalid signal: " << signal->ToString(); 481 return; 482 } 483 const bool success = StartsWithASCII(result_string, "success", false); 484 FOR_EACH_OBSERVER(Observer, observers_, PropertyChangeComplete(success)); 485 } 486 487 void ScreenLockReceived(dbus::Signal* signal) { 488 FOR_EACH_OBSERVER(Observer, observers_, LockScreen()); 489 } 490 491 void ScreenUnlockReceived(dbus::Signal* signal) { 492 FOR_EACH_OBSERVER(Observer, observers_, UnlockScreen()); 493 } 494 495 void LivenessRequestedReceived(dbus::Signal* signal) { 496 SimpleMethodCallToSessionManager( 497 login_manager::kSessionManagerHandleLivenessConfirmed); 498 } 499 500 void ScreenIsLockedReceived(dbus::Signal* signal) { 501 FOR_EACH_OBSERVER(Observer, observers_, ScreenIsLocked()); 502 } 503 504 void ScreenIsUnlockedReceived(dbus::Signal* signal) { 505 FOR_EACH_OBSERVER(Observer, observers_, ScreenIsUnlocked()); 506 } 507 508 // Called when the object is connected to the signal. 509 void SignalConnected(const std::string& interface_name, 510 const std::string& signal_name, 511 bool success) { 512 LOG_IF(ERROR, !success) << "Failed to connect to " << signal_name; 513 } 514 515 dbus::ObjectProxy* session_manager_proxy_; 516 BlockingMethodCaller blocking_method_caller_; 517 ObserverList<Observer> observers_; 518 519 // Note: This should remain the last member so it'll be destroyed and 520 // invalidate its weak pointers before any other members are destroyed. 521 base::WeakPtrFactory<SessionManagerClientImpl> weak_ptr_factory_; 522 523 DISALLOW_COPY_AND_ASSIGN(SessionManagerClientImpl); 524 }; 525 526 // The SessionManagerClient implementation used on Linux desktop, 527 // which does nothing. 528 class SessionManagerClientStubImpl : public SessionManagerClient { 529 public: 530 SessionManagerClientStubImpl() { 531 // Make sure that there are no keys left over from a previous browser run. 532 base::FilePath user_policy_key_dir; 533 if (PathService::Get(chromeos::DIR_USER_POLICY_KEYS, 534 &user_policy_key_dir)) { 535 base::WorkerPool::PostTask( 536 FROM_HERE, 537 base::Bind(base::IgnoreResult(&base::DeleteFile), 538 user_policy_key_dir, true), 539 false); 540 } 541 } 542 virtual ~SessionManagerClientStubImpl() {} 543 544 // SessionManagerClient overrides. 545 virtual void AddObserver(Observer* observer) OVERRIDE { 546 observers_.AddObserver(observer); 547 } 548 virtual void RemoveObserver(Observer* observer) OVERRIDE { 549 observers_.RemoveObserver(observer); 550 } 551 virtual bool HasObserver(Observer* observer) OVERRIDE { 552 return observers_.HasObserver(observer); 553 } 554 virtual void EmitLoginPromptReady() OVERRIDE {} 555 virtual void EmitLoginPromptVisible() OVERRIDE {} 556 virtual void RestartJob(int pid, const std::string& command_line) OVERRIDE {} 557 virtual void RestartEntd() OVERRIDE {} 558 virtual void StartSession(const std::string& user_email) OVERRIDE {} 559 virtual void StopSession() OVERRIDE {} 560 virtual void StartDeviceWipe() OVERRIDE {} 561 virtual void RequestLockScreen() OVERRIDE { 562 FOR_EACH_OBSERVER(Observer, observers_, LockScreen()); 563 } 564 virtual void NotifyLockScreenShown() OVERRIDE { 565 FOR_EACH_OBSERVER(Observer, observers_, ScreenIsLocked()); 566 } 567 virtual void RequestUnlockScreen() OVERRIDE { 568 FOR_EACH_OBSERVER(Observer, observers_, UnlockScreen()); 569 } 570 virtual void NotifyLockScreenDismissed() OVERRIDE { 571 FOR_EACH_OBSERVER(Observer, observers_, ScreenIsUnlocked()); 572 } 573 virtual void RetrieveActiveSessions( 574 const ActiveSessionsCallback& callback) OVERRIDE {} 575 virtual void RetrieveDevicePolicy( 576 const RetrievePolicyCallback& callback) OVERRIDE { 577 callback.Run(device_policy_); 578 } 579 virtual void RetrievePolicyForUser( 580 const std::string& username, 581 const RetrievePolicyCallback& callback) OVERRIDE { 582 callback.Run(user_policies_[username]); 583 } 584 virtual std::string BlockingRetrievePolicyForUser( 585 const std::string& username) OVERRIDE { 586 return user_policies_[username]; 587 } 588 virtual void RetrieveDeviceLocalAccountPolicy( 589 const std::string& account_name, 590 const RetrievePolicyCallback& callback) OVERRIDE { 591 callback.Run(user_policies_[account_name]); 592 } 593 virtual void StoreDevicePolicy(const std::string& policy_blob, 594 const StorePolicyCallback& callback) OVERRIDE { 595 device_policy_ = policy_blob; 596 callback.Run(true); 597 } 598 virtual void StorePolicyForUser( 599 const std::string& username, 600 const std::string& policy_blob, 601 const std::string& policy_key, 602 const StorePolicyCallback& callback) OVERRIDE { 603 if (policy_key.empty()) { 604 user_policies_[username] = policy_blob; 605 callback.Run(true); 606 return; 607 } 608 // The session manager writes the user policy key to a well-known 609 // location. Do the same with the stub impl, so that user policy works and 610 // can be tested on desktop builds. 611 // TODO(joaodasilva): parse the PolicyFetchResponse in |policy_blob| to get 612 // the policy key directly, after moving the policy protobufs to a top-level 613 // directory. The |policy_key| argument to this method can then be removed. 614 // http://crbug.com/240269 615 base::FilePath key_path; 616 if (!PathService::Get(chromeos::DIR_USER_POLICY_KEYS, &key_path)) { 617 callback.Run(false); 618 return; 619 } 620 const std::string sanitized = 621 CryptohomeClient::GetStubSanitizedUsername(username); 622 key_path = key_path.AppendASCII(sanitized).AppendASCII("policy.pub"); 623 // Assume that the key write is successful. 624 user_policies_[username] = policy_blob; 625 base::WorkerPool::PostTaskAndReply( 626 FROM_HERE, 627 base::Bind(&SessionManagerClientStubImpl::StoreFileInBackground, 628 key_path, policy_key), 629 base::Bind(callback, true), 630 false); 631 } 632 virtual void StoreDeviceLocalAccountPolicy( 633 const std::string& account_name, 634 const std::string& policy_blob, 635 const StorePolicyCallback& callback) OVERRIDE { 636 user_policies_[account_name] = policy_blob; 637 callback.Run(true); 638 } 639 virtual void SetFlagsForUser(const std::string& username, 640 const std::vector<std::string>& flags) OVERRIDE { 641 } 642 643 static void StoreFileInBackground(const base::FilePath& path, 644 const std::string& data) { 645 const int size = static_cast<int>(data.size()); 646 if (!file_util::CreateDirectory(path.DirName()) || 647 file_util::WriteFile(path, data.data(), size) != size) { 648 LOG(WARNING) << "Failed to write policy key to " << path.value(); 649 } 650 } 651 652 private: 653 ObserverList<Observer> observers_; 654 std::string device_policy_; 655 std::map<std::string, std::string> user_policies_; 656 657 DISALLOW_COPY_AND_ASSIGN(SessionManagerClientStubImpl); 658 }; 659 660 SessionManagerClient::SessionManagerClient() { 661 } 662 663 SessionManagerClient::~SessionManagerClient() { 664 } 665 666 SessionManagerClient* SessionManagerClient::Create( 667 DBusClientImplementationType type, 668 dbus::Bus* bus) { 669 if (type == REAL_DBUS_CLIENT_IMPLEMENTATION) 670 return new SessionManagerClientImpl(bus); 671 DCHECK_EQ(STUB_DBUS_CLIENT_IMPLEMENTATION, type); 672 return new SessionManagerClientStubImpl(); 673 } 674 675 } // namespace chromeos 676