OLD | NEW |
1 // Copyright (c) 2011 The Chromium OS Authors. All rights reserved. | 1 // Copyright (c) 2011 The Chromium OS Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "login_manager/session_manager_service.h" | 5 #include "login_manager/session_manager_service.h" |
6 | 6 |
7 #include <dbus/dbus-glib-lowlevel.h> | 7 #include <dbus/dbus-glib-lowlevel.h> |
8 #include <errno.h> | 8 #include <errno.h> |
9 #include <glib.h> | 9 #include <glib.h> |
10 #include <grp.h> | 10 #include <grp.h> |
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
42 #include "login_manager/owner_key.h" | 42 #include "login_manager/owner_key.h" |
43 | 43 |
44 // Forcibly namespace the dbus-bindings generated server bindings instead of | 44 // Forcibly namespace the dbus-bindings generated server bindings instead of |
45 // modifying the files afterward. | 45 // modifying the files afterward. |
46 namespace login_manager { // NOLINT | 46 namespace login_manager { // NOLINT |
47 namespace gobject { // NOLINT | 47 namespace gobject { // NOLINT |
48 #include "login_manager/bindings/server.h" | 48 #include "login_manager/bindings/server.h" |
49 } // namespace gobject | 49 } // namespace gobject |
50 } // namespace login_manager | 50 } // namespace login_manager |
51 | 51 |
| 52 namespace em = enterprise_management; |
52 namespace login_manager { | 53 namespace login_manager { |
53 | 54 |
54 using std::make_pair; | 55 using std::make_pair; |
55 using std::pair; | 56 using std::pair; |
56 using std::string; | 57 using std::string; |
57 using std::vector; | 58 using std::vector; |
58 | 59 |
59 // Jacked from chrome base/eintr_wrapper.h | 60 // Jacked from chrome base/eintr_wrapper.h |
60 #define HANDLE_EINTR(x) ({ \ | 61 #define HANDLE_EINTR(x) ({ \ |
61 typeof(x) __eintr_result__; \ | 62 typeof(x) __eintr_result__; \ |
(...skipping 409 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
471 return FALSE; | 472 return FALSE; |
472 } | 473 } |
473 | 474 |
474 gboolean SessionManagerService::StartSession(gchar* email_address, | 475 gboolean SessionManagerService::StartSession(gchar* email_address, |
475 gchar* unique_identifier, | 476 gchar* unique_identifier, |
476 gboolean* OUT_done, | 477 gboolean* OUT_done, |
477 GError** error) { | 478 GError** error) { |
478 if (session_started_) { | 479 if (session_started_) { |
479 const char msg[] = "Can't start session while session is already active."; | 480 const char msg[] = "Can't start session while session is already active."; |
480 LOG(ERROR) << msg; | 481 LOG(ERROR) << msg; |
481 SetGError(error, CHROMEOS_LOGIN_ERROR_SESSION_EXISTS, msg); | 482 system_->SetGError(error, CHROMEOS_LOGIN_ERROR_SESSION_EXISTS, msg); |
482 return *OUT_done = FALSE; | 483 return *OUT_done = FALSE; |
483 } | 484 } |
484 if (!ValidateAndCacheUserEmail(email_address, error)) { | 485 if (!ValidateAndCacheUserEmail(email_address, error)) { |
485 *OUT_done = FALSE; | 486 *OUT_done = FALSE; |
486 return FALSE; | 487 return FALSE; |
487 } | 488 } |
488 // If the current user is the owner, and isn't whitelisted or set | 489 // If the current user is the owner, and isn't whitelisted or set |
489 // as the cros.device.owner pref, then do so. This attempt only succeeds | 490 // as the cros.device.owner pref, then do so. |
490 // if the current user has access to the private half of the owner's | 491 bool can_access_key = CurrentUserHasOwnerKey(key_->public_key_der(), error); |
491 // registered public key. | 492 if (can_access_key) |
492 StoreOwnerProperties(NULL); | 493 StoreOwnerProperties(NULL); |
493 // Now, the flip side...if we believe the current user to be the owner | 494 // Now, the flip side...if we believe the current user to be the owner |
494 // based on the cros.owner.device setting, and he DOESN'T have the private | 495 // based on the cros.owner.device setting, and he DOESN'T have the private |
495 // half of the public key, we must mitigate. | 496 // half of the public key, we must mitigate. |
496 if (CurrentUserIsOwner(error) && | 497 if (CurrentUserIsOwner() && !can_access_key) { |
497 !CurrentUserHasOwnerKey(key_->public_key_der(), error)) { | |
498 if (!(*OUT_done = mitigator_->Mitigate())) | 498 if (!(*OUT_done = mitigator_->Mitigate())) |
499 return FALSE; | 499 return FALSE; |
500 } | 500 } |
501 | 501 |
502 *OUT_done = | 502 *OUT_done = |
503 upstart_signal_emitter_->EmitSignal( | 503 upstart_signal_emitter_->EmitSignal( |
504 "start-user-session", | 504 "start-user-session", |
505 StringPrintf("CHROMEOS_USER=%s", current_user_.c_str()), | 505 StringPrintf("CHROMEOS_USER=%s", current_user_.c_str()), |
506 error); | 506 error); |
507 | 507 |
(...skipping 95 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
603 // the session manager | 603 // the session manager |
604 // child_job_->StopSession(); | 604 // child_job_->StopSession(); |
605 // session_started_ = false; | 605 // session_started_ = false; |
606 return *OUT_done = TRUE; | 606 return *OUT_done = TRUE; |
607 } | 607 } |
608 | 608 |
609 gboolean SessionManagerService::SetOwnerKey(GArray* public_key_der, | 609 gboolean SessionManagerService::SetOwnerKey(GArray* public_key_der, |
610 GError** error) { | 610 GError** error) { |
611 const char msg[] = "The session_manager now sets the Owner's public key."; | 611 const char msg[] = "The session_manager now sets the Owner's public key."; |
612 LOG(ERROR) << msg; | 612 LOG(ERROR) << msg; |
613 SetGError(error, CHROMEOS_LOGIN_ERROR_ILLEGAL_PUBKEY, msg); | 613 system_->SetGError(error, CHROMEOS_LOGIN_ERROR_ILLEGAL_PUBKEY, msg); |
614 // Just to be safe, send back a nACK in addition to returning an error. | 614 // Just to be safe, send back a nACK in addition to returning an error. |
615 SendSignal(chromium::kOwnerKeySetSignal, false); | 615 SendSignal(chromium::kOwnerKeySetSignal, false); |
616 return FALSE; | 616 return FALSE; |
617 } | 617 } |
618 | 618 |
619 gboolean SessionManagerService::Unwhitelist(gchar* email_address, | 619 gboolean SessionManagerService::Unwhitelist(gchar* email_address, |
620 GArray* signature, | 620 GArray* signature, |
621 GError** error) { | 621 GError** error) { |
622 LOG(INFO) << "Unwhitelisting " << email_address; | 622 LOG(INFO) << "Unwhitelisting " << email_address; |
623 SessionManagerService::SigReturnCode verify_result = | 623 SessionManagerService::SigReturnCode verify_result = |
624 VerifyHelperArray(email_address, signature); | 624 VerifyHelperArray(email_address, signature); |
625 if (verify_result == NO_KEY) { | 625 if (verify_result == NO_KEY) { |
626 const char msg[] = "Attempt to unwhitelist before owner's key is set."; | 626 const char msg[] = "Attempt to unwhitelist before owner's key is set."; |
627 LOG(ERROR) << msg; | 627 LOG(ERROR) << msg; |
628 SetGError(error, CHROMEOS_LOGIN_ERROR_NO_OWNER_KEY, msg); | 628 system_->SetGError(error, CHROMEOS_LOGIN_ERROR_NO_OWNER_KEY, msg); |
629 return FALSE; | 629 return FALSE; |
630 } else if (verify_result == SIGNATURE_FAIL) { | 630 } else if (verify_result == SIGNATURE_FAIL) { |
631 const char msg[] = "Signature could not be verified in Unwhitelist."; | 631 const char msg[] = "Signature could not be verified in Unwhitelist."; |
632 LOG(ERROR) << msg; | 632 LOG(ERROR) << msg; |
633 SetGError(error, CHROMEOS_LOGIN_ERROR_VERIFY_FAIL, msg); | 633 system_->SetGError(error, CHROMEOS_LOGIN_ERROR_VERIFY_FAIL, msg); |
634 return FALSE; | 634 return FALSE; |
635 } | 635 } |
636 store_->Unwhitelist(email_address); | 636 store_->Unwhitelist(email_address); |
637 io_thread_.message_loop()->PostTask( | 637 io_thread_.message_loop()->PostTask( |
638 FROM_HERE, | 638 FROM_HERE, |
639 NewRunnableMethod(this, &SessionManagerService::PersistWhitelist)); | 639 NewRunnableMethod(this, &SessionManagerService::PersistWhitelist)); |
640 return TRUE; | 640 return TRUE; |
641 } | 641 } |
642 | 642 |
643 gboolean SessionManagerService::CheckWhitelist(gchar* email_address, | 643 gboolean SessionManagerService::CheckWhitelist(gchar* email_address, |
644 GArray** OUT_signature, | 644 GArray** OUT_signature, |
645 GError** error) { | 645 GError** error) { |
646 std::string encoded; | 646 std::string encoded; |
647 if (!store_->GetFromWhitelist(email_address, &encoded)) { | 647 if (!store_->GetFromWhitelist(email_address, &encoded)) { |
648 const char msg[] = "The user is not whitelisted."; | 648 const char msg[] = "The user is not whitelisted."; |
649 LOG(INFO) << msg; | 649 LOG(INFO) << msg; |
650 SetGError(error, CHROMEOS_LOGIN_ERROR_ILLEGAL_USER, msg); | 650 system_->SetGError(error, CHROMEOS_LOGIN_ERROR_ILLEGAL_USER, msg); |
651 return FALSE; | 651 return FALSE; |
652 } | 652 } |
653 std::string decoded; | 653 std::string decoded; |
654 if (!base::Base64Decode(encoded, &decoded)) { | 654 if (!base::Base64Decode(encoded, &decoded)) { |
655 const char msg[] = "Signature could not be decoded in CheckWhitelist."; | 655 const char msg[] = "Signature could not be decoded in CheckWhitelist."; |
656 LOG(ERROR) << msg; | 656 LOG(ERROR) << msg; |
657 SetGError(error, CHROMEOS_LOGIN_ERROR_DECODE_FAIL, msg); | 657 system_->SetGError(error, CHROMEOS_LOGIN_ERROR_DECODE_FAIL, msg); |
658 return FALSE; | 658 return FALSE; |
659 } | 659 } |
660 | 660 |
661 *OUT_signature = g_array_sized_new(FALSE, FALSE, 1, decoded.length()); | 661 *OUT_signature = g_array_sized_new(FALSE, FALSE, 1, decoded.length()); |
662 g_array_append_vals(*OUT_signature, decoded.c_str(), decoded.length()); | 662 g_array_append_vals(*OUT_signature, decoded.c_str(), decoded.length()); |
663 return TRUE; | 663 return TRUE; |
664 } | 664 } |
665 | 665 |
666 gboolean SessionManagerService::EnumerateWhitelisted(gchar*** OUT_whitelist, | 666 gboolean SessionManagerService::EnumerateWhitelisted(gchar*** OUT_whitelist, |
667 GError** error) { | 667 GError** error) { |
(...skipping 12 matching lines...) Expand all Loading... |
680 | 680 |
681 gboolean SessionManagerService::Whitelist(gchar* email_address, | 681 gboolean SessionManagerService::Whitelist(gchar* email_address, |
682 GArray* signature, | 682 GArray* signature, |
683 GError** error) { | 683 GError** error) { |
684 LOG(INFO) << "Whitelisting " << email_address; | 684 LOG(INFO) << "Whitelisting " << email_address; |
685 SessionManagerService::SigReturnCode verify_result = | 685 SessionManagerService::SigReturnCode verify_result = |
686 VerifyHelperArray(email_address, signature); | 686 VerifyHelperArray(email_address, signature); |
687 if (verify_result == NO_KEY) { | 687 if (verify_result == NO_KEY) { |
688 const char msg[] = "Attempt to whitelist before owner's key is set."; | 688 const char msg[] = "Attempt to whitelist before owner's key is set."; |
689 LOG(ERROR) << msg; | 689 LOG(ERROR) << msg; |
690 SetGError(error, CHROMEOS_LOGIN_ERROR_NO_OWNER_KEY, msg); | 690 system_->SetGError(error, CHROMEOS_LOGIN_ERROR_NO_OWNER_KEY, msg); |
691 return FALSE; | 691 return FALSE; |
692 } else if (verify_result == SIGNATURE_FAIL) { | 692 } else if (verify_result == SIGNATURE_FAIL) { |
693 const char msg[] = "Signature could not be verified in Whitelist."; | 693 const char msg[] = "Signature could not be verified in Whitelist."; |
694 LOG(ERROR) << msg; | 694 LOG(ERROR) << msg; |
695 SetGError(error, CHROMEOS_LOGIN_ERROR_VERIFY_FAIL, msg); | 695 system_->SetGError(error, CHROMEOS_LOGIN_ERROR_VERIFY_FAIL, msg); |
696 return FALSE; | 696 return FALSE; |
697 } | 697 } |
698 std::string data(signature->data, signature->len); | 698 std::string data(signature->data, signature->len); |
699 return WhitelistHelper(email_address, data, error); | 699 return WhitelistHelper(email_address, data, error); |
700 } | 700 } |
701 | 701 |
702 gboolean SessionManagerService::StoreProperty(gchar* name, | 702 gboolean SessionManagerService::StoreProperty(gchar* name, |
703 gchar* value, | 703 gchar* value, |
704 GArray* signature, | 704 GArray* signature, |
705 GError** error) { | 705 GError** error) { |
706 LOG(INFO) << "Setting pref " << name << "=" << value; | 706 LOG(INFO) << "Setting pref " << name << "=" << value; |
707 SessionManagerService::SigReturnCode verify_result = | 707 SessionManagerService::SigReturnCode verify_result = |
708 VerifyHelperArray(base::StringPrintf("%s=%s", name, value), signature); | 708 VerifyHelperArray(base::StringPrintf("%s=%s", name, value), signature); |
709 if (verify_result == NO_KEY) { | 709 if (verify_result == NO_KEY) { |
710 const char msg[] = "Attempt to store property before owner's key is set."; | 710 const char msg[] = "Attempt to store property before owner's key is set."; |
711 LOG(ERROR) << msg; | 711 LOG(ERROR) << msg; |
712 SetGError(error, CHROMEOS_LOGIN_ERROR_NO_OWNER_KEY, msg); | 712 system_->SetGError(error, CHROMEOS_LOGIN_ERROR_NO_OWNER_KEY, msg); |
713 return FALSE; | 713 return FALSE; |
714 } else if (verify_result == SIGNATURE_FAIL) { | 714 } else if (verify_result == SIGNATURE_FAIL) { |
715 const char msg[] = "Signature could not be verified in StoreProperty."; | 715 const char msg[] = "Signature could not be verified in StoreProperty."; |
716 LOG(ERROR) << msg; | 716 LOG(ERROR) << msg; |
717 SetGError(error, CHROMEOS_LOGIN_ERROR_VERIFY_FAIL, msg); | 717 system_->SetGError(error, CHROMEOS_LOGIN_ERROR_VERIFY_FAIL, msg); |
718 return FALSE; | 718 return FALSE; |
719 } | 719 } |
720 std::string data(signature->data, signature->len); | 720 std::string data(signature->data, signature->len); |
721 return SetPropertyHelper(name, value, data, error); | 721 return SetPropertyHelper(name, value, data, error); |
722 } | 722 } |
723 | 723 |
724 gboolean SessionManagerService::RetrieveProperty(gchar* name, | 724 gboolean SessionManagerService::RetrieveProperty(gchar* name, |
725 gchar** OUT_value, | 725 gchar** OUT_value, |
726 GArray** OUT_signature, | 726 GArray** OUT_signature, |
727 GError** error) { | 727 GError** error) { |
(...skipping 10 matching lines...) Expand all Loading... |
738 | 738 |
739 void SessionManagerService::SendBooleanReply(DBusGMethodInvocation* context, | 739 void SessionManagerService::SendBooleanReply(DBusGMethodInvocation* context, |
740 bool succeeded) { | 740 bool succeeded) { |
741 if (context) | 741 if (context) |
742 dbus_g_method_return(context, succeeded); | 742 dbus_g_method_return(context, succeeded); |
743 } | 743 } |
744 | 744 |
745 gboolean SessionManagerService::StorePolicy(GArray* policy_blob, | 745 gboolean SessionManagerService::StorePolicy(GArray* policy_blob, |
746 DBusGMethodInvocation* context) { | 746 DBusGMethodInvocation* context) { |
747 std::string policy_str(policy_blob->data, policy_blob->len); | 747 std::string policy_str(policy_blob->data, policy_blob->len); |
748 enterprise_management::PolicyFetchResponse policy; | 748 em::PolicyFetchResponse policy; |
749 if (!policy.ParseFromString(policy_str) || | 749 if (!policy.ParseFromString(policy_str) || |
750 !policy.has_policy_data() || | 750 !policy.has_policy_data() || |
751 !policy.has_policy_data_signature()) { | 751 !policy.has_policy_data_signature()) { |
752 const char msg[] = "Unable to parse policy protobuf."; | 752 const char msg[] = "Unable to parse policy protobuf."; |
753 LOG(ERROR) << msg; | 753 LOG(ERROR) << msg; |
754 SetAndSendGError(CHROMEOS_LOGIN_ERROR_DECODE_FAIL, context, msg); | 754 system_->SetAndSendGError(CHROMEOS_LOGIN_ERROR_DECODE_FAIL, context, msg); |
755 return FALSE; | 755 return FALSE; |
756 } | 756 } |
757 | 757 |
758 // Determine if the policy has pushed a new owner key and, if so, set it and | 758 // Determine if the policy has pushed a new owner key and, if so, set it and |
759 // schedule a task to persist it to disk. | 759 // schedule a task to persist it to disk. |
760 if (policy.has_new_public_key() && !key_->Equals(policy.new_public_key())) { | 760 if (policy.has_new_public_key() && !key_->Equals(policy.new_public_key())) { |
761 // The policy contains a new key, and it is different from |key_|. | 761 // The policy contains a new key, and it is different from |key_|. |
762 std::vector<uint8> der; | 762 std::vector<uint8> der; |
763 nss_->BlobFromBuffer(policy.new_public_key(), &der); | 763 nss_->BlobFromBuffer(policy.new_public_key(), &der); |
764 | 764 |
765 if (session_started_) { | 765 if (session_started_) { |
766 bool rotated = false; | 766 bool rotated = false; |
767 if (policy.has_new_public_key_signature()) { | 767 if (policy.has_new_public_key_signature()) { |
768 // Graceful key rotation. | 768 // Graceful key rotation. |
769 std::vector<uint8> sig; | 769 std::vector<uint8> sig; |
770 nss_->BlobFromBuffer(policy.new_public_key_signature(), &sig); | 770 nss_->BlobFromBuffer(policy.new_public_key_signature(), &sig); |
771 rotated = key_->Rotate(der, sig); | 771 rotated = key_->Rotate(der, sig); |
772 } | 772 } |
773 if (!rotated) { | 773 if (!rotated) { |
774 const char msg[] = "Failed attempted key rotation!"; | 774 const char msg[] = "Failed attempted key rotation!"; |
775 LOG(ERROR) << msg; | 775 LOG(ERROR) << msg; |
776 SetAndSendGError(CHROMEOS_LOGIN_ERROR_ILLEGAL_PUBKEY, context, msg); | 776 system_->SetAndSendGError(CHROMEOS_LOGIN_ERROR_ILLEGAL_PUBKEY, |
| 777 context, |
| 778 msg); |
777 return FALSE; | 779 return FALSE; |
778 } | 780 } |
779 } else { | 781 } else { |
780 // Force a new key, regardless of whether we have one or not. | 782 // Force a new key, regardless of whether we have one or not. |
781 if (key_->IsPopulated()) { | 783 if (key_->IsPopulated()) { |
782 key_->ClobberCompromisedKey(der); | 784 key_->ClobberCompromisedKey(der); |
783 LOG(INFO) << "Clobbered existing key outside of session"; | 785 LOG(INFO) << "Clobbered existing key outside of session"; |
784 } else { | 786 } else { |
785 CHECK(key_->PopulateFromBuffer(der)); // Should be unable to fail. | 787 CHECK(key_->PopulateFromBuffer(der)); // Should be unable to fail. |
786 LOG(INFO) << "Setting key outside of session"; | 788 LOG(INFO) << "Setting key outside of session"; |
787 } | 789 } |
788 } | 790 } |
789 // If here, need to persit new key to disk. Already loaded key into memory. | 791 // If here, need to persit new key to disk. Already loaded key into memory. |
790 io_thread_.message_loop()->PostTask( | 792 io_thread_.message_loop()->PostTask( |
791 FROM_HERE, NewRunnableMethod(this, &SessionManagerService::PersistKey)); | 793 FROM_HERE, NewRunnableMethod(this, &SessionManagerService::PersistKey)); |
792 } | 794 } |
793 | 795 |
794 // Validate signature on policy and persist to disk | 796 // Validate signature on policy and persist to disk |
795 const std::string& sig = policy.policy_data_signature(); | 797 const std::string& sig = policy.policy_data_signature(); |
796 SessionManagerService::SigReturnCode verify_result = | 798 SessionManagerService::SigReturnCode verify_result = |
797 VerifyHelper(policy.policy_data(), sig.c_str(), sig.length()); | 799 VerifyHelper(policy.policy_data(), sig.c_str(), sig.length()); |
798 if (verify_result == NO_KEY) { | 800 if (verify_result == NO_KEY) { |
799 NOTREACHED() << "Should have set the key earlier in this function!"; | 801 NOTREACHED() << "Should have set the key earlier in this function!"; |
800 return FALSE; | 802 return FALSE; |
801 } else if (verify_result == SIGNATURE_FAIL) { | 803 } else if (verify_result == SIGNATURE_FAIL) { |
802 const char msg[] = "Signature could not be verified in StorePolicy."; | 804 const char msg[] = "Signature could not be verified in StorePolicy."; |
803 LOG(ERROR) << msg; | 805 LOG(ERROR) << msg; |
804 SetAndSendGError(CHROMEOS_LOGIN_ERROR_VERIFY_FAIL, context, msg); | 806 system_->SetAndSendGError(CHROMEOS_LOGIN_ERROR_VERIFY_FAIL, context, msg); |
805 return FALSE; | 807 return FALSE; |
806 } | 808 } |
807 policy_->Set(policy); | 809 policy_->Set(policy); |
808 io_thread_.message_loop()->PostTask( | 810 io_thread_.message_loop()->PostTask( |
809 FROM_HERE, NewRunnableMethod(this, &SessionManagerService::PersistPolicy, | 811 FROM_HERE, NewRunnableMethod(this, &SessionManagerService::PersistPolicy, |
810 context)); | 812 context)); |
811 return TRUE; | 813 return TRUE; |
812 } | 814 } |
813 | 815 |
814 gboolean SessionManagerService::RetrievePolicy(GArray** OUT_policy_blob, | 816 gboolean SessionManagerService::RetrievePolicy(GArray** OUT_policy_blob, |
815 GError** error) { | 817 GError** error) { |
816 std::string polstr; | 818 std::string polstr; |
817 if (!policy_->Get(&polstr)) { | 819 if (!policy_->SerializeToString(&polstr)) { |
818 const char msg[] = "Unable to serialize policy protobuf."; | 820 const char msg[] = "Unable to serialize policy protobuf."; |
819 LOG(ERROR) << msg; | 821 LOG(ERROR) << msg; |
820 SetGError(error, CHROMEOS_LOGIN_ERROR_ENCODE_FAIL, msg); | 822 system_->SetGError(error, CHROMEOS_LOGIN_ERROR_ENCODE_FAIL, msg); |
821 return FALSE; | 823 return FALSE; |
822 } | 824 } |
823 *OUT_policy_blob = g_array_sized_new(FALSE, FALSE, 1, polstr.length()); | 825 *OUT_policy_blob = g_array_sized_new(FALSE, FALSE, 1, polstr.length()); |
824 if (!*OUT_policy_blob) { | 826 if (!*OUT_policy_blob) { |
825 const char msg[] = "Unable to allocate memory for response."; | 827 const char msg[] = "Unable to allocate memory for response."; |
826 LOG(ERROR) << msg; | 828 LOG(ERROR) << msg; |
827 SetGError(error, CHROMEOS_LOGIN_ERROR_DECODE_FAIL, msg); | 829 system_->SetGError(error, CHROMEOS_LOGIN_ERROR_DECODE_FAIL, msg); |
828 return FALSE; | 830 return FALSE; |
829 } | 831 } |
830 g_array_append_vals(*OUT_policy_blob, polstr.c_str(), polstr.length()); | 832 g_array_append_vals(*OUT_policy_blob, polstr.c_str(), polstr.length()); |
831 return TRUE; | 833 return TRUE; |
832 } | 834 } |
833 | 835 |
834 gboolean SessionManagerService::LockScreen(GError** error) { | 836 gboolean SessionManagerService::LockScreen(GError** error) { |
835 screen_locked_ = TRUE; | 837 screen_locked_ = TRUE; |
836 system_->SendSignalToChromium(chromium::kLockScreenSignal, NULL); | 838 system_->SendSignalToChromium(chromium::kLockScreenSignal, NULL); |
837 LOG(INFO) << "LockScreen"; | 839 LOG(INFO) << "LockScreen"; |
(...skipping 15 matching lines...) Expand all Loading... |
853 std::vector<int>::iterator child_pid_it = | 855 std::vector<int>::iterator child_pid_it = |
854 std::find(child_pids_.begin(), child_pids_.end(), child_pid); | 856 std::find(child_pids_.begin(), child_pids_.end(), child_pid); |
855 size_t child_index = child_pid_it - child_pids_.begin(); | 857 size_t child_index = child_pid_it - child_pids_.begin(); |
856 | 858 |
857 if (child_pid_it == child_pids_.end() || | 859 if (child_pid_it == child_pids_.end() || |
858 child_jobs_[child_index]->GetName() != "chrome") { | 860 child_jobs_[child_index]->GetName() != "chrome") { |
859 // If we didn't find the pid, or we don't think that job was chrome... | 861 // If we didn't find the pid, or we don't think that job was chrome... |
860 *OUT_done = FALSE; | 862 *OUT_done = FALSE; |
861 const char msg[] = "Provided pid is unknown."; | 863 const char msg[] = "Provided pid is unknown."; |
862 LOG(ERROR) << msg; | 864 LOG(ERROR) << msg; |
863 SetGError(error, CHROMEOS_LOGIN_ERROR_UNKNOWN_PID, msg); | 865 system_->SetGError(error, CHROMEOS_LOGIN_ERROR_UNKNOWN_PID, msg); |
864 return FALSE; | 866 return FALSE; |
865 } | 867 } |
866 | 868 |
867 // Waiting for Chrome to shutdown takes too much time. | 869 // Waiting for Chrome to shutdown takes too much time. |
868 // We're killing it immediately hoping that data Chrome uses before | 870 // We're killing it immediately hoping that data Chrome uses before |
869 // logging in is not corrupted. | 871 // logging in is not corrupted. |
870 // TODO(avayvod): Remove RestartJob when crosbug.com/6924 is fixed. | 872 // TODO(avayvod): Remove RestartJob when crosbug.com/6924 is fixed. |
871 KillChild(child_jobs_[child_index], child_pid); | 873 KillChild(child_jobs_[child_index], child_pid); |
872 | 874 |
873 char arguments_buffer[kMaxArgumentsSize + 1]; | 875 char arguments_buffer[kMaxArgumentsSize + 1]; |
(...skipping 145 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1019 | 1021 |
1020 void SessionManagerService::PersistWhitelist() { | 1022 void SessionManagerService::PersistWhitelist() { |
1021 LOG(INFO) << "Persisting Whitelist to disk."; | 1023 LOG(INFO) << "Persisting Whitelist to disk."; |
1022 bool what_happened = store_->Persist(); | 1024 bool what_happened = store_->Persist(); |
1023 message_loop_->PostTask( | 1025 message_loop_->PostTask( |
1024 FROM_HERE, NewRunnableMethod(this, &SessionManagerService::SendSignal, | 1026 FROM_HERE, NewRunnableMethod(this, &SessionManagerService::SendSignal, |
1025 chromium::kWhitelistChangeCompleteSignal, | 1027 chromium::kWhitelistChangeCompleteSignal, |
1026 what_happened)); | 1028 what_happened)); |
1027 } | 1029 } |
1028 | 1030 |
1029 // static | |
1030 void SessionManagerService::SetGError(GError** error, | |
1031 ChromeOSLoginError code, | |
1032 const char* message) { | |
1033 g_set_error(error, CHROMEOS_LOGIN_ERROR, code, "Login error: %s", message); | |
1034 } | |
1035 | |
1036 // static | |
1037 void SessionManagerService::SetAndSendGError(ChromeOSLoginError code, | |
1038 DBusGMethodInvocation* context, | |
1039 const char* msg) { | |
1040 GError* error = NULL; | |
1041 SetGError(&error, code, msg); | |
1042 dbus_g_method_return_error(context, error); | |
1043 g_error_free(error); | |
1044 } | |
1045 | |
1046 /////////////////////////////////////////////////////////////////////////////// | 1031 /////////////////////////////////////////////////////////////////////////////// |
1047 // Utility Methods | 1032 // Utility Methods |
1048 | 1033 |
1049 // This can probably be more efficient, if it needs to be. | 1034 // This can probably be more efficient, if it needs to be. |
1050 // static | 1035 // static |
1051 bool SessionManagerService::ValidateEmail(const string& email_address) { | 1036 bool SessionManagerService::ValidateEmail(const string& email_address) { |
1052 if (email_address.find_first_not_of(kLegalCharacters) != string::npos) | 1037 if (email_address.find_first_not_of(kLegalCharacters) != string::npos) |
1053 return false; | 1038 return false; |
1054 | 1039 |
1055 size_t at = email_address.find(kEmailSeparator); | 1040 size_t at = email_address.find(kEmailSeparator); |
(...skipping 73 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1129 // Also handle SIGINT - when the user terminates the browser via Ctrl+C. | 1114 // Also handle SIGINT - when the user terminates the browser via Ctrl+C. |
1130 // If the browser process is being debugged, GDB will catch the SIGINT first. | 1115 // If the browser process is being debugged, GDB will catch the SIGINT first. |
1131 action.sa_handler = SIGINTHandler; | 1116 action.sa_handler = SIGINTHandler; |
1132 CHECK(sigaction(SIGINT, &action, NULL) == 0); | 1117 CHECK(sigaction(SIGINT, &action, NULL) == 0); |
1133 // And SIGHUP, for when the terminal disappears. On shutdown, many Linux | 1118 // And SIGHUP, for when the terminal disappears. On shutdown, many Linux |
1134 // distros send SIGHUP, SIGTERM, and then SIGKILL. | 1119 // distros send SIGHUP, SIGTERM, and then SIGKILL. |
1135 action.sa_handler = SIGHUPHandler; | 1120 action.sa_handler = SIGHUPHandler; |
1136 CHECK(sigaction(SIGHUP, &action, NULL) == 0); | 1121 CHECK(sigaction(SIGHUP, &action, NULL) == 0); |
1137 } | 1122 } |
1138 | 1123 |
1139 gboolean SessionManagerService::CurrentUserIsOwner(GError** error) { | 1124 gboolean SessionManagerService::CurrentUserIsOwner() { |
1140 std::string value; | 1125 std::string value; |
1141 std::string decoded; | 1126 std::string decoded; |
1142 if (!GetPropertyHelper(kDeviceOwnerPref, &value, &decoded, error)) | 1127 if (!GetPropertyHelper(kDeviceOwnerPref, &value, &decoded, NULL)) |
1143 return FALSE; | 1128 return FALSE; |
1144 std::string was_signed = base::StringPrintf("%s=%s", | 1129 std::string was_signed = base::StringPrintf("%s=%s", |
1145 kDeviceOwnerPref, | 1130 kDeviceOwnerPref, |
1146 value.c_str()); | 1131 value.c_str()); |
1147 if (VerifyHelper(was_signed, decoded.c_str(), decoded.length()) != SUCCESS) { | 1132 if (VerifyHelper(was_signed, decoded.c_str(), decoded.length()) != SUCCESS) { |
1148 const char msg[] = "Owner pref signature could not be verified."; | 1133 LOG(ERROR) << "Owner pref signature could not be verified."; |
1149 LOG(ERROR) << msg; | |
1150 SetGError(error, CHROMEOS_LOGIN_ERROR_VERIFY_FAIL, msg); | |
1151 return FALSE; | 1134 return FALSE; |
1152 } | 1135 } |
1153 return value == current_user_; | 1136 return value == current_user_; |
1154 } | 1137 } |
1155 | 1138 |
1156 gboolean SessionManagerService::CurrentUserHasOwnerKey( | 1139 gboolean SessionManagerService::CurrentUserHasOwnerKey( |
1157 const std::vector<uint8>& pub_key, | 1140 const std::vector<uint8>& pub_key, |
1158 GError** error) { | 1141 GError** error) { |
1159 if (!nss_->OpenUserDB()) { | 1142 if (!nss_->OpenUserDB()) { |
1160 const char msg[] = "Could not open the current user's NSS database."; | 1143 const char msg[] = "Could not open the current user's NSS database."; |
1161 LOG(ERROR) << msg; | 1144 LOG(ERROR) << msg; |
1162 SetGError(error, CHROMEOS_LOGIN_ERROR_NO_USER_NSSDB, msg); | 1145 system_->SetGError(error, CHROMEOS_LOGIN_ERROR_NO_USER_NSSDB, msg); |
1163 return FALSE; | 1146 return FALSE; |
1164 } | 1147 } |
1165 if (!nss_->GetPrivateKey(pub_key)) { | 1148 if (!nss_->GetPrivateKey(pub_key)) { |
1166 const char msg[] = "Could not verify that public key belongs to the owner."; | 1149 const char msg[] = "Could not verify that public key belongs to the owner."; |
1167 LOG(WARNING) << msg; | 1150 LOG(WARNING) << msg; |
1168 SetGError(error, CHROMEOS_LOGIN_ERROR_ILLEGAL_PUBKEY, msg); | 1151 system_->SetGError(error, CHROMEOS_LOGIN_ERROR_ILLEGAL_PUBKEY, msg); |
1169 return FALSE; | 1152 return FALSE; |
1170 } | 1153 } |
1171 return TRUE; | 1154 return TRUE; |
1172 } | 1155 } |
1173 | 1156 |
1174 gboolean SessionManagerService::ValidateAndCacheUserEmail( | 1157 gboolean SessionManagerService::ValidateAndCacheUserEmail( |
1175 const gchar* email_address, | 1158 const gchar* email_address, |
1176 GError** error) { | 1159 GError** error) { |
1177 // basic validity checking; avoid buffer overflows here, and | 1160 // basic validity checking; avoid buffer overflows here, and |
1178 // canonicalize the email address a little. | 1161 // canonicalize the email address a little. |
1179 char email[kMaxEmailSize + 1]; | 1162 char email[kMaxEmailSize + 1]; |
1180 snprintf(email, sizeof(email), "%s", email_address); | 1163 snprintf(email, sizeof(email), "%s", email_address); |
1181 email[kMaxEmailSize] = '\0'; // Just to be sure. | 1164 email[kMaxEmailSize] = '\0'; // Just to be sure. |
1182 string email_string(email); | 1165 string email_string(email); |
1183 if (email_string != kIncognitoUser && !ValidateEmail(email_string)) { | 1166 if (email_string != kIncognitoUser && !ValidateEmail(email_string)) { |
1184 const char msg[] = "Provided email address is not valid. ASCII only."; | 1167 const char msg[] = "Provided email address is not valid. ASCII only."; |
1185 LOG(ERROR) << msg; | 1168 LOG(ERROR) << msg; |
1186 SetGError(error, CHROMEOS_LOGIN_ERROR_INVALID_EMAIL, msg); | 1169 system_->SetGError(error, CHROMEOS_LOGIN_ERROR_INVALID_EMAIL, msg); |
1187 return FALSE; | 1170 return FALSE; |
1188 } | 1171 } |
1189 current_user_ = StringToLowerASCII(email_string); | 1172 current_user_ = StringToLowerASCII(email_string); |
1190 return TRUE; | 1173 return TRUE; |
1191 } | 1174 } |
1192 | 1175 |
1193 int SessionManagerService::FindChildByPid(int pid) { | 1176 int SessionManagerService::FindChildByPid(int pid) { |
1194 for (int i = 0; i < child_pids_.size(); ++i) { | 1177 for (int i = 0; i < child_pids_.size(); ++i) { |
1195 if (child_pids_[i] == pid) | 1178 if (child_pids_[i] == pid) |
1196 return i; | 1179 return i; |
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1229 current_user_, | 1212 current_user_, |
1230 "Could not sign owner property.", | 1213 "Could not sign owner property.", |
1231 error)) { | 1214 error)) { |
1232 return FALSE; | 1215 return FALSE; |
1233 } | 1216 } |
1234 return SignAndWhitelist(current_user_, "Could not whitelist owner.", error); | 1217 return SignAndWhitelist(current_user_, "Could not whitelist owner.", error); |
1235 } | 1218 } |
1236 | 1219 |
1237 gboolean SessionManagerService::SignAndStoreProperty(const std::string& name, | 1220 gboolean SessionManagerService::SignAndStoreProperty(const std::string& name, |
1238 const std::string& value, | 1221 const std::string& value, |
1239 const std::string& err_msg, | 1222 const std::string& msg, |
1240 GError** error) { | 1223 GError** error) { |
1241 std::vector<uint8> signature; | 1224 std::vector<uint8> signature; |
1242 std::string to_sign = base::StringPrintf("%s=%s", | 1225 std::string to_sign = base::StringPrintf("%s=%s", |
1243 kDeviceOwnerPref, | 1226 kDeviceOwnerPref, |
1244 current_user_.c_str()); | 1227 current_user_.c_str()); |
1245 const uint8* data = reinterpret_cast<const uint8*>(to_sign.c_str()); | 1228 const uint8* data = reinterpret_cast<const uint8*>(to_sign.c_str()); |
1246 if (!key_->Sign(data, to_sign.length(), &signature)) { | 1229 if (!key_->Sign(data, to_sign.length(), &signature)) { |
1247 LOG_IF(ERROR, error) << err_msg; | 1230 LOG_IF(ERROR, error) << msg; |
1248 LOG_IF(WARNING, !error) << err_msg; | 1231 LOG_IF(WARNING, !error) << msg; |
1249 SetGError(error, CHROMEOS_LOGIN_ERROR_ILLEGAL_PUBKEY, err_msg.c_str()); | 1232 system_->SetGError(error, CHROMEOS_LOGIN_ERROR_ILLEGAL_PUBKEY, msg.c_str()); |
1250 return FALSE; | 1233 return FALSE; |
1251 } | 1234 } |
1252 std::string signature_string(reinterpret_cast<const char*>(&signature[0]), | 1235 std::string signature_string(reinterpret_cast<const char*>(&signature[0]), |
1253 signature.size()); | 1236 signature.size()); |
1254 return SetPropertyHelper(kDeviceOwnerPref, | 1237 return SetPropertyHelper(kDeviceOwnerPref, |
1255 current_user_, | 1238 current_user_, |
1256 signature_string, | 1239 signature_string, |
1257 error); | 1240 error); |
1258 } | 1241 } |
1259 | 1242 |
1260 gboolean SessionManagerService::SignAndWhitelist(const std::string& email, | 1243 gboolean SessionManagerService::SignAndWhitelist(const std::string& email, |
1261 const std::string& err_msg, | 1244 const std::string& msg, |
1262 GError** error) { | 1245 GError** error) { |
1263 std::vector<uint8> signature; | 1246 std::vector<uint8> signature; |
1264 const uint8* data = reinterpret_cast<const uint8*>(current_user_.c_str()); | 1247 const uint8* data = reinterpret_cast<const uint8*>(current_user_.c_str()); |
1265 if (!key_->Sign(data, current_user_.length(), &signature)) { | 1248 if (!key_->Sign(data, current_user_.length(), &signature)) { |
1266 LOG_IF(ERROR, error) << err_msg; | 1249 LOG_IF(ERROR, error) << msg; |
1267 LOG_IF(WARNING, !error) << err_msg; | 1250 LOG_IF(WARNING, !error) << msg; |
1268 SetGError(error, CHROMEOS_LOGIN_ERROR_ILLEGAL_PUBKEY, err_msg.c_str()); | 1251 system_->SetGError(error, CHROMEOS_LOGIN_ERROR_ILLEGAL_PUBKEY, msg.c_str()); |
1269 return FALSE; | 1252 return FALSE; |
1270 } | 1253 } |
1271 std::string signature_string(reinterpret_cast<const char*>(&signature[0]), | 1254 std::string signature_string(reinterpret_cast<const char*>(&signature[0]), |
1272 signature.size()); | 1255 signature.size()); |
1273 return WhitelistHelper(current_user_, signature_string, error); | 1256 return WhitelistHelper(current_user_, signature_string, error); |
1274 } | 1257 } |
1275 | 1258 |
1276 gboolean SessionManagerService::SetPropertyHelper(const std::string& name, | 1259 gboolean SessionManagerService::SetPropertyHelper(const std::string& name, |
1277 const std::string& value, | 1260 const std::string& value, |
1278 const std::string& signature, | 1261 const std::string& signature, |
1279 GError** error) { | 1262 GError** error) { |
1280 std::string encoded; | 1263 std::string encoded; |
1281 if (!base::Base64Encode(signature, &encoded)) { | 1264 if (!base::Base64Encode(signature, &encoded)) { |
1282 const char msg[] = "Signature could not be encoded."; | 1265 const char msg[] = "Signature could not be encoded."; |
1283 LOG(ERROR) << msg; | 1266 LOG(ERROR) << msg; |
1284 SetGError(error, CHROMEOS_LOGIN_ERROR_ENCODE_FAIL, msg); | 1267 system_->SetGError(error, CHROMEOS_LOGIN_ERROR_ENCODE_FAIL, msg); |
1285 return FALSE; | 1268 return FALSE; |
1286 } | 1269 } |
1287 store_->Set(name, value, encoded); | 1270 store_->Set(name, value, encoded); |
1288 io_thread_.message_loop()->PostTask( | 1271 io_thread_.message_loop()->PostTask( |
1289 FROM_HERE, NewRunnableMethod(this, &SessionManagerService::PersistStore)); | 1272 FROM_HERE, NewRunnableMethod(this, &SessionManagerService::PersistStore)); |
1290 return TRUE; | 1273 return TRUE; |
1291 } | 1274 } |
1292 | 1275 |
1293 SessionManagerService::SigReturnCode | 1276 SessionManagerService::SigReturnCode |
1294 SessionManagerService::VerifyHelperArray(const std::string& data, GArray* sig) { | 1277 SessionManagerService::VerifyHelperArray(const std::string& data, GArray* sig) { |
(...skipping 15 matching lines...) Expand all Loading... |
1310 return SUCCESS; | 1293 return SUCCESS; |
1311 } | 1294 } |
1312 | 1295 |
1313 gboolean SessionManagerService::WhitelistHelper(const std::string& email, | 1296 gboolean SessionManagerService::WhitelistHelper(const std::string& email, |
1314 const std::string& signature, | 1297 const std::string& signature, |
1315 GError** error) { | 1298 GError** error) { |
1316 std::string encoded; | 1299 std::string encoded; |
1317 if (!base::Base64Encode(signature, &encoded)) { | 1300 if (!base::Base64Encode(signature, &encoded)) { |
1318 const char msg[] = "Signature could not be encoded."; | 1301 const char msg[] = "Signature could not be encoded."; |
1319 LOG(ERROR) << msg; | 1302 LOG(ERROR) << msg; |
1320 SetGError(error, CHROMEOS_LOGIN_ERROR_ENCODE_FAIL, msg); | 1303 system_->SetGError(error, CHROMEOS_LOGIN_ERROR_ENCODE_FAIL, msg); |
1321 return FALSE; | 1304 return FALSE; |
1322 } | 1305 } |
1323 store_->Whitelist(email, encoded); | 1306 store_->Whitelist(email, encoded); |
1324 io_thread_.message_loop()->PostTask( | 1307 io_thread_.message_loop()->PostTask( |
1325 FROM_HERE, | 1308 FROM_HERE, |
1326 NewRunnableMethod(this, &SessionManagerService::PersistWhitelist)); | 1309 NewRunnableMethod(this, &SessionManagerService::PersistWhitelist)); |
1327 return TRUE; | 1310 return TRUE; |
1328 } | 1311 } |
1329 | 1312 |
1330 gboolean SessionManagerService::GetPropertyHelper(const std::string& name, | 1313 gboolean SessionManagerService::GetPropertyHelper(const std::string& name, |
1331 std::string* OUT_value, | 1314 std::string* OUT_value, |
1332 std::string* OUT_signature, | 1315 std::string* OUT_signature, |
1333 GError** error) { | 1316 GError** err) { |
1334 std::string encoded; | 1317 std::string encoded; |
1335 if (!store_->Get(name, OUT_value, &encoded)) { | 1318 if (!store_->Get(name, OUT_value, &encoded)) { |
1336 std::string error_msg = | 1319 std::string msg = |
1337 base::StringPrintf("The requested property %s is unknown.", | 1320 base::StringPrintf("The requested property %s is unknown.", |
1338 name.c_str()); | 1321 name.c_str()); |
1339 LOG(WARNING) << error_msg; | 1322 LOG(WARNING) << msg; |
1340 SetGError(error, CHROMEOS_LOGIN_ERROR_UNKNOWN_PROPERTY, error_msg.c_str()); | 1323 system_->SetGError(err, CHROMEOS_LOGIN_ERROR_UNKNOWN_PROPERTY, msg.c_str()); |
1341 return FALSE; | 1324 return FALSE; |
1342 } | 1325 } |
1343 if (!base::Base64Decode(encoded, OUT_signature)) { | 1326 if (!base::Base64Decode(encoded, OUT_signature)) { |
1344 const char msg[] = "Signature could not be decoded."; | 1327 const char msg[] = "Signature could not be decoded."; |
1345 LOG(ERROR) << msg; | 1328 LOG(ERROR) << msg; |
1346 SetGError(error, CHROMEOS_LOGIN_ERROR_DECODE_FAIL, msg); | 1329 system_->SetGError(err, CHROMEOS_LOGIN_ERROR_DECODE_FAIL, msg); |
1347 return FALSE; | 1330 return FALSE; |
1348 } | 1331 } |
1349 return TRUE; | 1332 return TRUE; |
1350 } | 1333 } |
1351 | 1334 |
1352 void SessionManagerService::SendSignal(const char signal_name[], | 1335 void SessionManagerService::SendSignal(const char signal_name[], |
1353 bool succeeded) { | 1336 bool succeeded) { |
1354 system_->SendSignalToChromium(signal_name, succeeded ? "success" : "failure"); | 1337 system_->SendSignalToChromium(signal_name, succeeded ? "success" : "failure"); |
1355 } | 1338 } |
1356 | 1339 |
(...skipping 12 matching lines...) Expand all Loading... |
1369 arg_list.push_back(args[i_arg]); | 1352 arg_list.push_back(args[i_arg]); |
1370 } | 1353 } |
1371 } | 1354 } |
1372 if (arg_list.size()) { | 1355 if (arg_list.size()) { |
1373 arg_lists.push_back(arg_list); | 1356 arg_lists.push_back(arg_list); |
1374 } | 1357 } |
1375 return arg_lists; | 1358 return arg_lists; |
1376 } | 1359 } |
1377 | 1360 |
1378 } // namespace login_manager | 1361 } // namespace login_manager |
OLD | NEW |