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

Side by Side Diff: session_manager_service.cc

Issue 6793055: [login_manager] Allow new owner keys to be pushed with StorePolicy (Closed) Base URL: http://git.chromium.org/git/login_manager.git@master
Patch Set: remove some debugging code 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
« no previous file with comments | « session_manager_service.h ('k') | session_manager_unittest.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright (c) 2009-2010 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>
11 #include <secder.h> 11 #include <secder.h>
(...skipping 531 matching lines...) Expand 10 before | Expand all | Expand 10 after
543 } else { 543 } else {
544 if (WIFSIGNALED(status)) 544 if (WIFSIGNALED(status))
545 LOG(ERROR) << "keygen exited on signal " << WTERMSIG(status); 545 LOG(ERROR) << "keygen exited on signal " << WTERMSIG(status);
546 else 546 else
547 LOG(ERROR) << "keygen exited with exit code " << WEXITSTATUS(status); 547 LOG(ERROR) << "keygen exited with exit code " << WEXITSTATUS(status);
548 } 548 }
549 } 549 }
550 550
551 void SessionManagerService::ValidateAndStoreOwnerKey(const std::string& buf) { 551 void SessionManagerService::ValidateAndStoreOwnerKey(const std::string& buf) {
552 std::vector<uint8> pub_key; 552 std::vector<uint8> pub_key;
553 NssUtil::KeyFromBuffer(buf, &pub_key); 553 NssUtil::BlobFromBuffer(buf, &pub_key);
554 554
555 if (!CurrentUserHasOwnerKey(pub_key, NULL)) { 555 if (!CurrentUserHasOwnerKey(pub_key, NULL)) {
556 SendSignal(chromium::kOwnerKeySetSignal, false); 556 SendSignal(chromium::kOwnerKeySetSignal, false);
557 return; 557 return;
558 } 558 }
559 559
560 if (!key_->PopulateFromBuffer(pub_key)) { 560 if (!key_->PopulateFromBuffer(pub_key)) {
561 SendSignal(chromium::kOwnerKeySetSignal, false); 561 SendSignal(chromium::kOwnerKeySetSignal, false);
562 return; 562 return;
563 } 563 }
(...skipping 174 matching lines...) Expand 10 before | Expand all | Expand 10 after
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 GError* error = NULL;
749 enterprise_management::PolicyFetchResponse policy; 748 enterprise_management::PolicyFetchResponse policy;
750 if (!policy.ParseFromString(policy_str) || 749 if (!policy.ParseFromString(policy_str) ||
751 !policy.has_policy_data() || 750 !policy.has_policy_data() ||
752 !policy.has_policy_data_signature()) { 751 !policy.has_policy_data_signature()) {
753 const char msg[] = "Unable to parse policy protobuf."; 752 const char msg[] = "Unable to parse policy protobuf.";
754 LOG(ERROR) << msg; 753 LOG(ERROR) << msg;
755 SetGError(&error, CHROMEOS_LOGIN_ERROR_DECODE_FAIL, msg); 754 SetAndSendGError(CHROMEOS_LOGIN_ERROR_DECODE_FAIL, context, msg);
756 dbus_g_method_return_error(context, error);
757 g_error_free(error);
758 return FALSE; 755 return FALSE;
759 } 756 }
757
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.
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_|.
762 std::vector<uint8> der;
763 nss_->BlobFromBuffer(policy.new_public_key(), &der);
764
765 if (session_started_) {
766 bool rotated = false;
767 if (policy.has_new_public_key_signature()) {
768 // Graceful key rotation.
769 std::vector<uint8> sig;
770 nss_->BlobFromBuffer(policy.new_public_key_signature(), &sig);
771 rotated = key_->Rotate(der, sig);
772 }
773 if (!rotated) {
774 const char msg[] = "Failed attempted key rotation!";
775 LOG(ERROR) << msg;
776 SetAndSendGError(CHROMEOS_LOGIN_ERROR_ILLEGAL_PUBKEY, context, msg);
777 return FALSE;
778 }
779 } else {
780 // Force a new key, regardless of whether we have one or not.
781 if (key_->IsPopulated()) {
782 key_->ClobberCompromisedKey(der);
783 LOG(INFO) << "Clobbered existing key outside of session";
784 } else {
785 CHECK(key_->PopulateFromBuffer(der)); // Should be unable to fail.
786 LOG(INFO) << "Setting key outside of session";
787 }
788 }
789 // If here, need to persit new key to disk. Already loaded key into memory.
790 io_thread_.message_loop()->PostTask(
791 FROM_HERE, NewRunnableMethod(this, &SessionManagerService::PersistKey));
792 }
793
794 // Validate signature on policy and persist to disk
760 const std::string& sig = policy.policy_data_signature(); 795 const std::string& sig = policy.policy_data_signature();
761 SessionManagerService::SigReturnCode verify_result = 796 SessionManagerService::SigReturnCode verify_result =
762 VerifyHelper(policy.policy_data(), sig.c_str(), sig.length()); 797 VerifyHelper(policy.policy_data(), sig.c_str(), sig.length());
763 if (verify_result == NO_KEY) { 798 if (verify_result == NO_KEY) {
764 const char msg[] = "Attempt to store policy before owner's key is set."; 799 NOTREACHED() << "Should have set the key earlier in this function!";
765 LOG(ERROR) << msg;
766 SetGError(&error, CHROMEOS_LOGIN_ERROR_NO_OWNER_KEY, msg);
767 return FALSE; 800 return FALSE;
768 } else if (verify_result == SIGNATURE_FAIL) { 801 } else if (verify_result == SIGNATURE_FAIL) {
769 const char msg[] = "Signature could not be verified in StorePolicy."; 802 const char msg[] = "Signature could not be verified in StorePolicy.";
770 LOG(ERROR) << msg; 803 LOG(ERROR) << msg;
771 SetGError(&error, CHROMEOS_LOGIN_ERROR_VERIFY_FAIL, msg); 804 SetAndSendGError(CHROMEOS_LOGIN_ERROR_VERIFY_FAIL, context, msg);
772 return FALSE; 805 return FALSE;
773 } 806 }
774 policy_->Set(policy); 807 policy_->Set(policy);
775 io_thread_.message_loop()->PostTask( 808 io_thread_.message_loop()->PostTask(
776 FROM_HERE, NewRunnableMethod(this, &SessionManagerService::PersistPolicy, 809 FROM_HERE, NewRunnableMethod(this, &SessionManagerService::PersistPolicy,
777 context)); 810 context));
778 return TRUE; 811 return TRUE;
779 } 812 }
780 813
781 gboolean SessionManagerService::RetrievePolicy(GArray** OUT_policy_blob, 814 gboolean SessionManagerService::RetrievePolicy(GArray** OUT_policy_blob,
(...skipping 211 matching lines...) Expand 10 before | Expand all | Expand 10 after
993 what_happened)); 1026 what_happened));
994 } 1027 }
995 1028
996 // static 1029 // static
997 void SessionManagerService::SetGError(GError** error, 1030 void SessionManagerService::SetGError(GError** error,
998 ChromeOSLoginError code, 1031 ChromeOSLoginError code,
999 const char* message) { 1032 const char* message) {
1000 g_set_error(error, CHROMEOS_LOGIN_ERROR, code, "Login error: %s", message); 1033 g_set_error(error, CHROMEOS_LOGIN_ERROR, code, "Login error: %s", message);
1001 } 1034 }
1002 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 }
1003 1045
1004 /////////////////////////////////////////////////////////////////////////////// 1046 ///////////////////////////////////////////////////////////////////////////////
1005 // Utility Methods 1047 // Utility Methods
1006 1048
1007 // This can probably be more efficient, if it needs to be. 1049 // This can probably be more efficient, if it needs to be.
1008 // static 1050 // static
1009 bool SessionManagerService::ValidateEmail(const string& email_address) { 1051 bool SessionManagerService::ValidateEmail(const string& email_address) {
1010 if (email_address.find_first_not_of(kLegalCharacters) != string::npos) 1052 if (email_address.find_first_not_of(kLegalCharacters) != string::npos)
1011 return false; 1053 return false;
1012 1054
(...skipping 82 matching lines...) Expand 10 before | Expand all | Expand 10 after
1095 } 1137 }
1096 1138
1097 gboolean SessionManagerService::CurrentUserIsOwner(GError** error) { 1139 gboolean SessionManagerService::CurrentUserIsOwner(GError** error) {
1098 std::string value; 1140 std::string value;
1099 std::string decoded; 1141 std::string decoded;
1100 if (!GetPropertyHelper(kDeviceOwnerPref, &value, &decoded, error)) 1142 if (!GetPropertyHelper(kDeviceOwnerPref, &value, &decoded, error))
1101 return FALSE; 1143 return FALSE;
1102 std::string was_signed = base::StringPrintf("%s=%s", 1144 std::string was_signed = base::StringPrintf("%s=%s",
1103 kDeviceOwnerPref, 1145 kDeviceOwnerPref,
1104 value.c_str()); 1146 value.c_str());
1105 if (!key_->Verify(was_signed.c_str(), 1147 if (VerifyHelper(was_signed, decoded.c_str(), decoded.length()) != SUCCESS) {
1106 was_signed.length(),
1107 decoded.c_str(),
1108 decoded.length())) {
1109 const char msg[] = "Owner pref signature could not be verified."; 1148 const char msg[] = "Owner pref signature could not be verified.";
1110 LOG(ERROR) << msg; 1149 LOG(ERROR) << msg;
1111 SetGError(error, CHROMEOS_LOGIN_ERROR_VERIFY_FAIL, msg); 1150 SetGError(error, CHROMEOS_LOGIN_ERROR_VERIFY_FAIL, msg);
1112 return FALSE; 1151 return FALSE;
1113 } 1152 }
1114 return value == current_user_; 1153 return value == current_user_;
1115 } 1154 }
1116 1155
1117 gboolean SessionManagerService::CurrentUserHasOwnerKey( 1156 gboolean SessionManagerService::CurrentUserHasOwnerKey(
1118 const std::vector<uint8>& pub_key, 1157 const std::vector<uint8>& pub_key,
(...skipping 77 matching lines...) Expand 10 before | Expand all | Expand 10 after
1196 } 1235 }
1197 1236
1198 gboolean SessionManagerService::SignAndStoreProperty(const std::string& name, 1237 gboolean SessionManagerService::SignAndStoreProperty(const std::string& name,
1199 const std::string& value, 1238 const std::string& value,
1200 const std::string& err_msg, 1239 const std::string& err_msg,
1201 GError** error) { 1240 GError** error) {
1202 std::vector<uint8> signature; 1241 std::vector<uint8> signature;
1203 std::string to_sign = base::StringPrintf("%s=%s", 1242 std::string to_sign = base::StringPrintf("%s=%s",
1204 kDeviceOwnerPref, 1243 kDeviceOwnerPref,
1205 current_user_.c_str()); 1244 current_user_.c_str());
1206 if (!key_->Sign(to_sign.c_str(), to_sign.length(), &signature)) { 1245 const uint8* data = reinterpret_cast<const uint8*>(to_sign.c_str());
1246 if (!key_->Sign(data, to_sign.length(), &signature)) {
1207 LOG_IF(ERROR, error) << err_msg; 1247 LOG_IF(ERROR, error) << err_msg;
1208 LOG_IF(WARNING, !error) << err_msg; 1248 LOG_IF(WARNING, !error) << err_msg;
1209 SetGError(error, CHROMEOS_LOGIN_ERROR_ILLEGAL_PUBKEY, err_msg.c_str()); 1249 SetGError(error, CHROMEOS_LOGIN_ERROR_ILLEGAL_PUBKEY, err_msg.c_str());
1210 return FALSE; 1250 return FALSE;
1211 } 1251 }
1212 std::string signature_string(reinterpret_cast<const char*>(&signature[0]), 1252 std::string signature_string(reinterpret_cast<const char*>(&signature[0]),
1213 signature.size()); 1253 signature.size());
1214 return SetPropertyHelper(kDeviceOwnerPref, 1254 return SetPropertyHelper(kDeviceOwnerPref,
1215 current_user_, 1255 current_user_,
1216 signature_string, 1256 signature_string,
1217 error); 1257 error);
1218 } 1258 }
1219 1259
1220 gboolean SessionManagerService::SignAndWhitelist(const std::string& email, 1260 gboolean SessionManagerService::SignAndWhitelist(const std::string& email,
1221 const std::string& err_msg, 1261 const std::string& err_msg,
1222 GError** error) { 1262 GError** error) {
1223 std::vector<uint8> signature; 1263 std::vector<uint8> signature;
1224 if (!key_->Sign(current_user_.c_str(), current_user_.length(), &signature)) { 1264 const uint8* data = reinterpret_cast<const uint8*>(current_user_.c_str());
1265 if (!key_->Sign(data, current_user_.length(), &signature)) {
1225 LOG_IF(ERROR, error) << err_msg; 1266 LOG_IF(ERROR, error) << err_msg;
1226 LOG_IF(WARNING, !error) << err_msg; 1267 LOG_IF(WARNING, !error) << err_msg;
1227 SetGError(error, CHROMEOS_LOGIN_ERROR_ILLEGAL_PUBKEY, err_msg.c_str()); 1268 SetGError(error, CHROMEOS_LOGIN_ERROR_ILLEGAL_PUBKEY, err_msg.c_str());
1228 return FALSE; 1269 return FALSE;
1229 } 1270 }
1230 std::string signature_string(reinterpret_cast<const char*>(&signature[0]), 1271 std::string signature_string(reinterpret_cast<const char*>(&signature[0]),
1231 signature.size()); 1272 signature.size());
1232 return WhitelistHelper(current_user_, signature_string, error); 1273 return WhitelistHelper(current_user_, signature_string, error);
1233 } 1274 }
1234 1275
(...skipping 18 matching lines...) Expand all
1253 SessionManagerService::VerifyHelperArray(const std::string& data, GArray* sig) { 1294 SessionManagerService::VerifyHelperArray(const std::string& data, GArray* sig) {
1254 return VerifyHelper(data, sig->data, sig->len); 1295 return VerifyHelper(data, sig->data, sig->len);
1255 } 1296 }
1256 1297
1257 SessionManagerService::SigReturnCode 1298 SessionManagerService::SigReturnCode
1258 SessionManagerService::VerifyHelper(const std::string& data, 1299 SessionManagerService::VerifyHelper(const std::string& data,
1259 const char* sig, 1300 const char* sig,
1260 uint32 sig_len) { 1301 uint32 sig_len) {
1261 if (!key_->IsPopulated()) 1302 if (!key_->IsPopulated())
1262 return NO_KEY; 1303 return NO_KEY;
1263 if (!key_->Verify(data.c_str(), data.length(), sig, sig_len)) 1304 if (!key_->Verify(reinterpret_cast<const uint8*>(data.c_str()),
1305 data.length(),
1306 reinterpret_cast<const uint8*>(sig),
1307 sig_len)) {
1264 return SIGNATURE_FAIL; 1308 return SIGNATURE_FAIL;
1309 }
1265 return SUCCESS; 1310 return SUCCESS;
1266 } 1311 }
1267 1312
1268 gboolean SessionManagerService::WhitelistHelper(const std::string& email, 1313 gboolean SessionManagerService::WhitelistHelper(const std::string& email,
1269 const std::string& signature, 1314 const std::string& signature,
1270 GError** error) { 1315 GError** error) {
1271 std::string encoded; 1316 std::string encoded;
1272 if (!base::Base64Encode(signature, &encoded)) { 1317 if (!base::Base64Encode(signature, &encoded)) {
1273 const char msg[] = "Signature could not be encoded."; 1318 const char msg[] = "Signature could not be encoded.";
1274 LOG(ERROR) << msg; 1319 LOG(ERROR) << msg;
(...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after
1324 arg_list.push_back(args[i_arg]); 1369 arg_list.push_back(args[i_arg]);
1325 } 1370 }
1326 } 1371 }
1327 if (arg_list.size()) { 1372 if (arg_list.size()) {
1328 arg_lists.push_back(arg_list); 1373 arg_lists.push_back(arg_list);
1329 } 1374 }
1330 return arg_lists; 1375 return arg_lists;
1331 } 1376 }
1332 1377
1333 } // namespace login_manager 1378 } // namespace login_manager
OLDNEW
« no previous file with comments | « session_manager_service.h ('k') | session_manager_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698