Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(171)

Side by Side Diff: session_manager_service.cc

Issue 6815021: [login_manager] Code to add the owner to the whitelist in a device policy (Closed) Base URL: http://git.chromium.org/git/login_manager.git@master
Patch Set: Created 9 years, 8 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
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
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
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
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
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
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
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
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
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
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
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
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
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698