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/files/file_path.h" 10#include "base/files/file_util.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 28namespace chromeos { 29 30namespace { 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. 35base::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. 45std::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. 53void 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. 65class 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 bool first_run = false; 529 if (!response) { 530 LOG(ERROR) << "Failed to call " 531 << login_manager::kSessionManagerStartSession; 532 } else { 533 dbus::MessageReader reader(response); 534 dbus::MessageReader array_reader(NULL); 535 536 if (!reader.PopArray(&array_reader)) { 537 LOG(ERROR) << "Bad response: " << response->ToString(); 538 } else { 539 while (array_reader.HasMoreData()) { 540 const uint8* data = NULL; 541 size_t size = 0; 542 if (!array_reader.PopArrayOfBytes(&data, &size)) { 543 LOG(ERROR) << "Bad response: " << response->ToString(); 544 state_keys.clear(); 545 break; 546 } 547 state_keys.push_back( 548 std::string(reinterpret_cast<const char*>(data), size)); 549 } 550 } 551 if (!reader.PopBool(&first_run)) { 552 // TODO(tnagel): After 2014-11-19 turn this warning into an error. 553 LOG(WARNING) << "Chrome OS is too old. Defaulting to first_run=false."; 554 } 555 } 556 557 if (!callback.is_null()) 558 callback.Run(state_keys, first_run); 559 } 560 561 562 dbus::ObjectProxy* session_manager_proxy_; 563 scoped_ptr<BlockingMethodCaller> blocking_method_caller_; 564 ObserverList<Observer> observers_; 565 566 // Note: This should remain the last member so it'll be destroyed and 567 // invalidate its weak pointers before any other members are destroyed. 568 base::WeakPtrFactory<SessionManagerClientImpl> weak_ptr_factory_; 569 570 DISALLOW_COPY_AND_ASSIGN(SessionManagerClientImpl); 571}; 572 573// The SessionManagerClient implementation used on Linux desktop, 574// which does nothing. 575class SessionManagerClientStubImpl : public SessionManagerClient { 576 public: 577 SessionManagerClientStubImpl() : delegate_(NULL) {} 578 virtual ~SessionManagerClientStubImpl() {} 579 580 // SessionManagerClient overrides 581 virtual void Init(dbus::Bus* bus) OVERRIDE {} 582 virtual void SetStubDelegate(StubDelegate* delegate) OVERRIDE { 583 delegate_ = delegate; 584 } 585 virtual void AddObserver(Observer* observer) OVERRIDE { 586 observers_.AddObserver(observer); 587 } 588 virtual void RemoveObserver(Observer* observer) OVERRIDE { 589 observers_.RemoveObserver(observer); 590 } 591 virtual bool HasObserver(Observer* observer) OVERRIDE { 592 return observers_.HasObserver(observer); 593 } 594 virtual void EmitLoginPromptVisible() OVERRIDE {} 595 virtual void RestartJob(int pid, const std::string& command_line) OVERRIDE {} 596 virtual void StartSession(const std::string& user_email) OVERRIDE {} 597 virtual void StopSession() OVERRIDE {} 598 virtual void StartDeviceWipe() OVERRIDE {} 599 virtual void RequestLockScreen() OVERRIDE { 600 if (delegate_) 601 delegate_->LockScreenForStub(); 602 } 603 virtual void NotifyLockScreenShown() OVERRIDE { 604 FOR_EACH_OBSERVER(Observer, observers_, ScreenIsLocked()); 605 } 606 virtual void NotifyLockScreenDismissed() OVERRIDE { 607 FOR_EACH_OBSERVER(Observer, observers_, ScreenIsUnlocked()); 608 } 609 virtual void RetrieveActiveSessions( 610 const ActiveSessionsCallback& callback) OVERRIDE {} 611 virtual void RetrieveDevicePolicy( 612 const RetrievePolicyCallback& callback) OVERRIDE { 613 base::FilePath owner_key_path; 614 if (!PathService::Get(chromeos::FILE_OWNER_KEY, &owner_key_path)) { 615 callback.Run(""); 616 return; 617 } 618 base::FilePath device_policy_path = 619 owner_key_path.DirName().AppendASCII("stub_device_policy"); 620 base::PostTaskAndReplyWithResult( 621 base::WorkerPool::GetTaskRunner(false).get(), 622 FROM_HERE, 623 base::Bind(&GetFileContent, device_policy_path), 624 callback); 625 } 626 virtual void RetrievePolicyForUser( 627 const std::string& username, 628 const RetrievePolicyCallback& callback) OVERRIDE { 629 base::PostTaskAndReplyWithResult( 630 base::WorkerPool::GetTaskRunner(false).get(), 631 FROM_HERE, 632 base::Bind(&GetFileContent, GetUserFilePath(username, "stub_policy")), 633 callback); 634 } 635 virtual std::string BlockingRetrievePolicyForUser( 636 const std::string& username) OVERRIDE { 637 return GetFileContent(GetUserFilePath(username, "stub_policy")); 638 } 639 virtual void RetrieveDeviceLocalAccountPolicy( 640 const std::string& account_name, 641 const RetrievePolicyCallback& callback) OVERRIDE { 642 RetrievePolicyForUser(account_name, callback); 643 } 644 virtual void StoreDevicePolicy(const std::string& policy_blob, 645 const StorePolicyCallback& callback) OVERRIDE { 646 enterprise_management::PolicyFetchResponse response; 647 base::FilePath owner_key_path; 648 if (!response.ParseFromString(policy_blob) || 649 !PathService::Get(chromeos::FILE_OWNER_KEY, &owner_key_path)) { 650 callback.Run(false); 651 return; 652 } 653 654 if (response.has_new_public_key()) { 655 base::WorkerPool::PostTask( 656 FROM_HERE, 657 base::Bind(&StoreFile, owner_key_path, response.new_public_key()), 658 false); 659 } 660 661 // Chrome will attempt to retrieve the device policy right after storing 662 // during enrollment, so make sure it's written before signaling 663 // completion. 664 // Note also that the owner key will be written before the device policy, 665 // if it was present in the blob. 666 base::FilePath device_policy_path = 667 owner_key_path.DirName().AppendASCII("stub_device_policy"); 668 base::WorkerPool::PostTaskAndReply( 669 FROM_HERE, 670 base::Bind(&StoreFile, device_policy_path, policy_blob), 671 base::Bind(callback, true), 672 false); 673 } 674 virtual void StorePolicyForUser( 675 const std::string& username, 676 const std::string& policy_blob, 677 const StorePolicyCallback& callback) OVERRIDE { 678 // The session manager writes the user policy key to a well-known 679 // location. Do the same with the stub impl, so that user policy works and 680 // can be tested on desktop builds. 681 enterprise_management::PolicyFetchResponse response; 682 if (!response.ParseFromString(policy_blob)) { 683 callback.Run(false); 684 return; 685 } 686 687 if (response.has_new_public_key()) { 688 base::FilePath key_path = GetUserFilePath(username, "policy.pub"); 689 base::WorkerPool::PostTask( 690 FROM_HERE, 691 base::Bind(&StoreFile, key_path, response.new_public_key()), 692 false); 693 } 694 695 // This file isn't read directly by Chrome, but is used by this class to 696 // reload the user policy across restarts. 697 base::FilePath stub_policy_path = GetUserFilePath(username, "stub_policy"); 698 base::WorkerPool::PostTaskAndReply( 699 FROM_HERE, 700 base::Bind(&StoreFile, stub_policy_path, policy_blob), 701 base::Bind(callback, true), 702 false); 703 } 704 virtual void StoreDeviceLocalAccountPolicy( 705 const std::string& account_name, 706 const std::string& policy_blob, 707 const StorePolicyCallback& callback) OVERRIDE { 708 StorePolicyForUser(account_name, policy_blob, callback); 709 } 710 virtual void SetFlagsForUser(const std::string& username, 711 const std::vector<std::string>& flags) OVERRIDE { 712 } 713 714 virtual void GetServerBackedStateKeys(const StateKeysCallback& callback) 715 OVERRIDE { 716 std::vector<std::string> state_keys; 717 for (int i = 0; i < 5; ++i) 718 state_keys.push_back(crypto::SHA256HashString(base::IntToString(i))); 719 720 if (!callback.is_null()) 721 callback.Run(state_keys, false); 722 } 723 724 private: 725 StubDelegate* delegate_; // Weak pointer; may be NULL. 726 ObserverList<Observer> observers_; 727 std::string device_policy_; 728 729 DISALLOW_COPY_AND_ASSIGN(SessionManagerClientStubImpl); 730}; 731 732SessionManagerClient::SessionManagerClient() { 733} 734 735SessionManagerClient::~SessionManagerClient() { 736} 737 738SessionManagerClient* SessionManagerClient::Create( 739 DBusClientImplementationType type) { 740 if (type == REAL_DBUS_CLIENT_IMPLEMENTATION) 741 return new SessionManagerClientImpl(); 742 DCHECK_EQ(STUB_DBUS_CLIENT_IMPLEMENTATION, type); 743 return new SessionManagerClientStubImpl(); 744} 745 746} // namespace chromeos 747