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 |