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