| OLD | NEW |
| 1 // Copyright (c) 2010 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2010 The Chromium 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 <errno.h> | 5 #include <errno.h> |
| 6 #include <string> | 6 #include <string> |
| 7 #include <vector> | 7 #include <vector> |
| 8 #include <time.h> | 8 #include <time.h> |
| 9 | 9 |
| 10 #include "base/logging.h" | 10 #include "base/logging.h" |
| (...skipping 29 matching lines...) Expand all Loading... |
| 40 const char GoogleAuthenticator::kFormat[] = | 40 const char GoogleAuthenticator::kFormat[] = |
| 41 "Email=%s&" | 41 "Email=%s&" |
| 42 "Passwd=%s&" | 42 "Passwd=%s&" |
| 43 "PersistentCookie=%s&" | 43 "PersistentCookie=%s&" |
| 44 "accountType=%s&" | 44 "accountType=%s&" |
| 45 "source=%s&"; | 45 "source=%s&"; |
| 46 const char GoogleAuthenticator::kCookiePersistence[] = "true"; | 46 const char GoogleAuthenticator::kCookiePersistence[] = "true"; |
| 47 const char GoogleAuthenticator::kAccountType[] = "HOSTED_OR_GOOGLE"; | 47 const char GoogleAuthenticator::kAccountType[] = "HOSTED_OR_GOOGLE"; |
| 48 const char GoogleAuthenticator::kSource[] = "chromeos"; | 48 const char GoogleAuthenticator::kSource[] = "chromeos"; |
| 49 const int GoogleAuthenticator::kHttpSuccess = 200; | 49 const int GoogleAuthenticator::kHttpSuccess = 200; |
| 50 const int kPassHashLen = 32; |
| 50 | 51 |
| 51 // Chromium OS system salt stored here | 52 // Chromium OS system salt stored here |
| 52 const char GoogleAuthenticator::kSystemSalt[] = "/home/.shadow/salt"; | 53 const char GoogleAuthenticator::kSystemSalt[] = "/home/.shadow/salt"; |
| 53 | 54 |
| 54 // String that appears at the start of OpenSSL cipher text with embedded salt | 55 // String that appears at the start of OpenSSL cipher text with embedded salt |
| 55 const char GoogleAuthenticator::kOpenSSLMagic[] = "Salted__"; | 56 const char GoogleAuthenticator::kOpenSSLMagic[] = "Salted__"; |
| 56 | 57 |
| 57 bool GoogleAuthenticator::Authenticate(const std::string& username, | 58 bool GoogleAuthenticator::Authenticate(const std::string& username, |
| 58 const std::string& password) { | 59 const std::string& password) { |
| 59 FilePath user_data_dir; | 60 FilePath user_data_dir; |
| (...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 95 if (client_login_handler_->CanHandle(url)) { | 96 if (client_login_handler_->CanHandle(url)) { |
| 96 fetcher_.reset(client_login_handler_->Handle(data, this)); | 97 fetcher_.reset(client_login_handler_->Handle(data, this)); |
| 97 } else if (issue_handler_->CanHandle(url)) { | 98 } else if (issue_handler_->CanHandle(url)) { |
| 98 fetcher_.reset(issue_handler_->Handle(data, this)); | 99 fetcher_.reset(issue_handler_->Handle(data, this)); |
| 99 } else { | 100 } else { |
| 100 LOG(INFO) << "Online login successful!"; | 101 LOG(INFO) << "Online login successful!"; |
| 101 ChromeThread::PostTask( | 102 ChromeThread::PostTask( |
| 102 ChromeThread::UI, FROM_HERE, | 103 ChromeThread::UI, FROM_HERE, |
| 103 NewRunnableFunction(GoogleAuthenticator::OnLoginSuccess, | 104 NewRunnableFunction(GoogleAuthenticator::OnLoginSuccess, |
| 104 consumer_, | 105 consumer_, |
| 105 library_, | |
| 106 username_, | 106 username_, |
| 107 ascii_hash_, | 107 ascii_hash_, |
| 108 cookies)); | 108 cookies)); |
| 109 } | 109 } |
| 110 } else if (!status.is_success()) { | 110 } else if (!status.is_success()) { |
| 111 LOG(INFO) << "Network fail"; | 111 LOG(INFO) << "Network fail"; |
| 112 // The fetch failed for network reasons, try offline login. | 112 // The fetch failed for network reasons, try offline login. |
| 113 ChromeThread::PostTask( | 113 ChromeThread::PostTask( |
| 114 ChromeThread::UI, FROM_HERE, | 114 ChromeThread::UI, FROM_HERE, |
| 115 NewRunnableFunction(GoogleAuthenticator::CheckOffline, | 115 NewRunnableFunction(GoogleAuthenticator::CheckOffline, |
| 116 consumer_, | 116 consumer_, |
| 117 library_, | |
| 118 username_, | 117 username_, |
| 119 ascii_hash_, | 118 ascii_hash_, |
| 120 status)); | 119 status)); |
| 121 } else { | 120 } else { |
| 122 std::string error; | 121 std::string error; |
| 123 if (status.is_success()) { | 122 if (status.is_success()) { |
| 124 // The fetch succeeded, but ClientLogin said no. | 123 // The fetch succeeded, but ClientLogin said no. |
| 125 error.assign(data); | 124 error.assign(data); |
| 126 } else { | 125 } else { |
| 127 // We couldn't hit the network, and offline login failed. | 126 // We couldn't hit the network, and offline login failed. |
| 128 error.assign(strerror(status.os_error())); | 127 error.assign(strerror(status.os_error())); |
| 129 } | 128 } |
| 130 ChromeThread::PostTask( | 129 ChromeThread::PostTask( |
| 131 ChromeThread::UI, FROM_HERE, | 130 ChromeThread::UI, FROM_HERE, |
| 132 NewRunnableFunction( | 131 NewRunnableFunction( |
| 133 GoogleAuthenticator::OnLoginFailure, consumer_, error)); | 132 GoogleAuthenticator::OnLoginFailure, consumer_, error)); |
| 134 } | 133 } |
| 135 } | 134 } |
| 136 | 135 |
| 137 // static | 136 // static |
| 138 void GoogleAuthenticator::OnLoginSuccess(LoginStatusConsumer* consumer, | 137 void GoogleAuthenticator::OnLoginSuccess(LoginStatusConsumer* consumer, |
| 139 CryptohomeLibrary* library, | |
| 140 const std::string& username, | 138 const std::string& username, |
| 141 const std::string& passhash, | 139 const std::string& passhash, |
| 142 const ResponseCookies& cookies) { | 140 const ResponseCookies& cookies) { |
| 143 if (library->Mount(username.c_str(), passhash.c_str())) | 141 if (CrosLibrary::Get()->GetCryptohomeLibrary()->Mount(username.c_str(), |
| 142 passhash.c_str())) |
| 144 consumer->OnLoginSuccess(username, cookies); | 143 consumer->OnLoginSuccess(username, cookies); |
| 145 else | 144 else |
| 146 GoogleAuthenticator::OnLoginFailure(consumer, "Could not mount cryptohome"); | 145 GoogleAuthenticator::OnLoginFailure(consumer, "Could not mount cryptohome"); |
| 147 } | 146 } |
| 148 | 147 |
| 149 // static | 148 // static |
| 150 void GoogleAuthenticator::CheckOffline(LoginStatusConsumer* consumer, | 149 void GoogleAuthenticator::CheckOffline(LoginStatusConsumer* consumer, |
| 151 CryptohomeLibrary* library, | |
| 152 const std::string& username, | 150 const std::string& username, |
| 153 const std::string& passhash, | 151 const std::string& passhash, |
| 154 const URLRequestStatus& status) { | 152 const URLRequestStatus& status) { |
| 155 if (library->CheckKey(username.c_str(), passhash.c_str())) { | 153 if (CrosLibrary::Get()->GetCryptohomeLibrary()->CheckKey(username.c_str(), |
| 154 passhash.c_str())) { |
| 156 // The fetch didn't succeed, but offline login did. | 155 // The fetch didn't succeed, but offline login did. |
| 157 LOG(INFO) << "Offline login successful!"; | 156 LOG(INFO) << "Offline login successful!"; |
| 158 ResponseCookies cookies; | 157 ResponseCookies cookies; |
| 159 GoogleAuthenticator::OnLoginSuccess(consumer, | 158 GoogleAuthenticator::OnLoginSuccess(consumer, |
| 160 library, | |
| 161 username, | 159 username, |
| 162 passhash, | 160 passhash, |
| 163 cookies); | 161 cookies); |
| 164 } else { | 162 } else { |
| 165 // We couldn't hit the network, and offline login failed. | 163 // We couldn't hit the network, and offline login failed. |
| 166 GoogleAuthenticator::OnLoginFailure(consumer, strerror(status.os_error())); | 164 GoogleAuthenticator::OnLoginFailure(consumer, strerror(status.os_error())); |
| 167 } | 165 } |
| 168 } | 166 } |
| 169 | 167 |
| 170 // static | 168 // static |
| (...skipping 18 matching lines...) Expand all Loading... |
| 189 int data_read = ReadFile(path, salt, file_size); | 187 int data_read = ReadFile(path, salt, file_size); |
| 190 | 188 |
| 191 CHECK_EQ(data_read % 2, 0); | 189 CHECK_EQ(data_read % 2, 0); |
| 192 system_salt_.assign(salt, salt + data_read); | 190 system_salt_.assign(salt, salt + data_read); |
| 193 } | 191 } |
| 194 | 192 |
| 195 std::string GoogleAuthenticator::SaltAsAscii() { | 193 std::string GoogleAuthenticator::SaltAsAscii() { |
| 196 FilePath salt_path(kSystemSalt); | 194 FilePath salt_path(kSystemSalt); |
| 197 LoadSystemSalt(salt_path); | 195 LoadSystemSalt(salt_path); |
| 198 unsigned int salt_len = system_salt_.size(); | 196 unsigned int salt_len = system_salt_.size(); |
| 199 char ascii_salt[2 * salt_len]; | 197 char ascii_salt[2 * salt_len + 1]; |
| 200 if (GoogleAuthenticator::BinaryToHex(system_salt_, | 198 if (GoogleAuthenticator::BinaryToHex(system_salt_, |
| 201 salt_len, | 199 salt_len, |
| 202 ascii_salt, | 200 ascii_salt, |
| 203 sizeof(ascii_salt))) { | 201 sizeof(ascii_salt))) { |
| 204 return std::string(ascii_salt, sizeof(ascii_salt)); | 202 return std::string(ascii_salt, sizeof(ascii_salt) - 1); |
| 205 } else { | 203 } else { |
| 206 return std::string(); | 204 return std::string(); |
| 207 } | 205 } |
| 208 } | 206 } |
| 209 | 207 |
| 210 void GoogleAuthenticator::StoreHashedPassword(const std::string& password) { | 208 void GoogleAuthenticator::StoreHashedPassword(const std::string& password) { |
| 211 // Get salt, ascii encode, update sha with that, then update with ascii | 209 // Get salt, ascii encode, update sha with that, then update with ascii |
| 212 // of password, then end. | 210 // of password, then end. |
| 213 std::string ascii_salt = SaltAsAscii(); | 211 std::string ascii_salt = SaltAsAscii(); |
| 214 unsigned char passhash_buf[32]; | 212 unsigned char passhash_buf[kPassHashLen]; |
| 215 char ascii_buf[32]; | 213 char ascii_buf[kPassHashLen + 1]; |
| 216 | 214 |
| 217 // Hash salt and password | 215 // Hash salt and password |
| 218 SHA256Context ctx; | 216 SHA256Context ctx; |
| 219 SHA256_Begin(&ctx); | 217 SHA256_Begin(&ctx); |
| 220 SHA256_Update(&ctx, | 218 SHA256_Update(&ctx, |
| 221 reinterpret_cast<const unsigned char*>(ascii_salt.data()), | 219 reinterpret_cast<const unsigned char*>(ascii_salt.data()), |
| 222 static_cast<unsigned int>(ascii_salt.length())); | 220 static_cast<unsigned int>(ascii_salt.length())); |
| 223 SHA256_Update(&ctx, | 221 SHA256_Update(&ctx, |
| 224 reinterpret_cast<const unsigned char*>(password.data()), | 222 reinterpret_cast<const unsigned char*>(password.data()), |
| 225 static_cast<unsigned int>(password.length())); | 223 static_cast<unsigned int>(password.length())); |
| 226 SHA256_End(&ctx, | 224 SHA256_End(&ctx, |
| 227 passhash_buf, | 225 passhash_buf, |
| 228 NULL, | 226 NULL, |
| 229 static_cast<unsigned int>(sizeof(passhash_buf))); | 227 static_cast<unsigned int>(sizeof(passhash_buf))); |
| 230 | 228 |
| 231 std::vector<unsigned char> passhash(passhash_buf, | 229 std::vector<unsigned char> passhash(passhash_buf, |
| 232 passhash_buf + sizeof(passhash_buf)); | 230 passhash_buf + sizeof(passhash_buf)); |
| 233 BinaryToHex(passhash, | 231 BinaryToHex(passhash, |
| 234 passhash.size() / 2, // only want top half, at least for now. | 232 passhash.size() / 2, // only want top half, at least for now. |
| 235 ascii_buf, | 233 ascii_buf, |
| 236 sizeof(ascii_buf)); | 234 sizeof(ascii_buf)); |
| 237 ascii_hash_.assign(ascii_buf, sizeof(ascii_buf)); | 235 ascii_hash_.assign(ascii_buf, sizeof(ascii_buf) - 1); |
| 238 } | 236 } |
| 239 | 237 |
| 240 // static | 238 // static |
| 241 bool GoogleAuthenticator::BinaryToHex(const std::vector<unsigned char>& binary, | 239 bool GoogleAuthenticator::BinaryToHex(const std::vector<unsigned char>& binary, |
| 242 const unsigned int binary_len, | 240 const unsigned int binary_len, |
| 243 char* hex_string, | 241 char* hex_string, |
| 244 const unsigned int len) { | 242 const unsigned int len) { |
| 245 if (len < 2*binary_len) | 243 if (len < 2*binary_len) |
| 246 return false; | 244 return false; |
| 247 memset(hex_string, 0, len); | 245 memset(hex_string, 0, len); |
| 248 for (uint i = 0, j = 0; i < binary_len; i++, j+=2) | 246 for (uint i = 0, j = 0; i < binary_len; i++, j+=2) |
| 249 sprintf(hex_string + j, "%02x", binary[i]); | 247 snprintf(hex_string + j, len - j, "%02x", binary[i]); |
| 250 return true; | 248 return true; |
| 251 } | 249 } |
| OLD | NEW |