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

Side by Side Diff: chrome/browser/password_manager/password_store_mac.cc

Issue 151164: Remove a bunch of low-level keychain helper tests that are now redundant with... (Closed) Base URL: svn://chrome-svn/chrome/trunk/src/
Patch Set: '' Created 11 years, 5 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 | « no previous file | chrome/browser/password_manager/password_store_mac_internal.h » ('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 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2009 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 "chrome/browser/password_manager/password_store_mac.h" 5 #include "chrome/browser/password_manager/password_store_mac.h"
6 #include "chrome/browser/password_manager/password_store_mac_internal.h" 6 #include "chrome/browser/password_manager/password_store_mac_internal.h"
7 7
8 #include <CoreServices/CoreServices.h> 8 #include <CoreServices/CoreServices.h>
9 #include <string> 9 #include <string>
10 #include <vector> 10 #include <vector>
11 11
12 #include "base/logging.h" 12 #include "base/logging.h"
13 #include "base/stl_util-inl.h" 13 #include "base/stl_util-inl.h"
14 #include "base/string_util.h" 14 #include "base/string_util.h"
15 #include "base/time.h" 15 #include "base/time.h"
16 #include "chrome/browser/keychain_mac.h" 16 #include "chrome/browser/keychain_mac.h"
17 #include "chrome/browser/password_manager/login_database_mac.h" 17 #include "chrome/browser/password_manager/login_database_mac.h"
18 18
19 using webkit_glue::PasswordForm; 19 using webkit_glue::PasswordForm;
20 20
21 namespace internal_keychain_helpers {
22
23 // Utility class to handle the details of constructing and running a keychain 21 // Utility class to handle the details of constructing and running a keychain
24 // search from a set of attributes. 22 // search from a set of attributes.
25 class KeychainSearch { 23 class KeychainSearch {
26 public: 24 public:
27 KeychainSearch(const MacKeychain& keychain); 25 KeychainSearch(const MacKeychain& keychain);
28 ~KeychainSearch(); 26 ~KeychainSearch();
29 27
30 // Sets up a keycahin search based on an non "null" (NULL for char*, 28 // Sets up a keycahin search based on an non "null" (NULL for char*,
31 // The appropriate "Any" entry for other types) arguments. 29 // The appropriate "Any" entry for other types) arguments.
32 // 30 //
(...skipping 113 matching lines...) Expand 10 before | Expand all | Expand 10 after
146 // Consumer is responsible for deleting the forms when they are done. 144 // Consumer is responsible for deleting the forms when they are done.
147 items->push_back(keychain_item); 145 items->push_back(keychain_item);
148 } 146 }
149 147
150 keychain_->Free(search_ref_); 148 keychain_->Free(search_ref_);
151 search_ref_ = NULL; 149 search_ref_ = NULL;
152 } 150 }
153 151
154 #pragma mark - 152 #pragma mark -
155 153
154 // TODO(stuartmorgan): Convert most of this to private helpers in
155 // MacKeychainPaswordFormAdapter once it has sufficient higher-level public
156 // methods to provide test coverage.
157 namespace internal_keychain_helpers {
158
159 // Takes a PasswordForm's signon_realm and parses it into its component parts,
160 // which are returned though the appropriate out parameters.
161 // Returns true if it can be successfully parsed, in which case all out params
162 // that are non-NULL will be set. If there is no port, port will be 0.
163 // If the return value is false, the state of the our params is undefined.
164 //
156 // TODO(stuartmorgan): signon_realm for proxies is not yet supported. 165 // TODO(stuartmorgan): signon_realm for proxies is not yet supported.
157 bool ExtractSignonRealmComponents(const std::string& signon_realm, 166 bool ExtractSignonRealmComponents(const std::string& signon_realm,
158 std::string* server, int* port, 167 std::string* server, int* port,
159 bool* is_secure, 168 bool* is_secure,
160 std::string* security_domain) { 169 std::string* security_domain) {
161 // The signon_realm will be the Origin portion of a URL for an HTML form, 170 // The signon_realm will be the Origin portion of a URL for an HTML form,
162 // and the same but with the security domain as a path for HTTP auth. 171 // and the same but with the security domain as a path for HTTP auth.
163 GURL realm_as_url(signon_realm); 172 GURL realm_as_url(signon_realm);
164 if (!realm_as_url.is_valid()) { 173 if (!realm_as_url.is_valid()) {
165 return false; 174 return false;
166 } 175 }
167 176
168 if (server) 177 if (server)
169 *server = realm_as_url.host(); 178 *server = realm_as_url.host();
170 if (is_secure) 179 if (is_secure)
171 *is_secure = realm_as_url.SchemeIsSecure(); 180 *is_secure = realm_as_url.SchemeIsSecure();
172 if (port) 181 if (port)
173 *port = realm_as_url.has_port() ? atoi(realm_as_url.port().c_str()) : 0; 182 *port = realm_as_url.has_port() ? atoi(realm_as_url.port().c_str()) : 0;
174 if (security_domain) { 183 if (security_domain) {
175 // Strip the leading '/' off of the path to get the security domain. 184 // Strip the leading '/' off of the path to get the security domain.
176 *security_domain = realm_as_url.path().substr(1); 185 *security_domain = realm_as_url.path().substr(1);
177 } 186 }
178 return true; 187 return true;
179 } 188 }
180 189
190 // Returns a URL built from the given components. To create a URL without a
191 // port, pass kAnyPort for the |port| parameter.
181 GURL URLFromComponents(bool is_secure, const std::string& host, int port, 192 GURL URLFromComponents(bool is_secure, const std::string& host, int port,
182 const std::string& path) { 193 const std::string& path) {
183 GURL::Replacements url_components; 194 GURL::Replacements url_components;
184 std::string scheme(is_secure ? "https" : "http"); 195 std::string scheme(is_secure ? "https" : "http");
185 url_components.SetSchemeStr(scheme); 196 url_components.SetSchemeStr(scheme);
186 url_components.SetHostStr(host); 197 url_components.SetHostStr(host);
187 std::string port_string; // Must remain in scope until after we do replacing. 198 std::string port_string; // Must remain in scope until after we do replacing.
188 if (port != kAnyPort) { 199 if (port != kAnyPort) {
189 std::ostringstream port_stringstream; 200 std::ostringstream port_stringstream;
190 port_stringstream << port; 201 port_stringstream << port;
191 port_string = port_stringstream.str(); 202 port_string = port_stringstream.str();
192 url_components.SetPortStr(port_string); 203 url_components.SetPortStr(port_string);
193 } 204 }
194 url_components.SetPathStr(path); 205 url_components.SetPathStr(path);
195 206
196 GURL url("http://dummy.com"); // ReplaceComponents needs a valid URL. 207 GURL url("http://dummy.com"); // ReplaceComponents needs a valid URL.
197 return url.ReplaceComponents(url_components); 208 return url.ReplaceComponents(url_components);
198 } 209 }
199 210
200 // The time string is of the form "yyyyMMddHHmmss'Z", in UTC time. 211 // Converts a Keychain time string to a Time object, returning true if
212 // time_string_bytes was parsable. If the return value is false, the value of
213 // |time| is unchanged.
201 bool TimeFromKeychainTimeString(const char* time_string_bytes, 214 bool TimeFromKeychainTimeString(const char* time_string_bytes,
202 unsigned int byte_length, 215 unsigned int byte_length,
203 base::Time* time) { 216 base::Time* time) {
204 DCHECK(time); 217 DCHECK(time);
205 218
206 char* time_string = static_cast<char*>(malloc(byte_length + 1)); 219 char* time_string = static_cast<char*>(malloc(byte_length + 1));
207 memcpy(time_string, time_string_bytes, byte_length); 220 memcpy(time_string, time_string_bytes, byte_length);
208 time_string[byte_length] = '\0'; 221 time_string[byte_length] = '\0';
209 base::Time::Exploded exploded_time; 222 base::Time::Exploded exploded_time;
210 bzero(&exploded_time, sizeof(exploded_time)); 223 bzero(&exploded_time, sizeof(exploded_time));
224 // The time string is of the form "yyyyMMddHHmmss'Z", in UTC time.
211 int assignments = sscanf(time_string, "%4d%2d%2d%2d%2d%2dZ", 225 int assignments = sscanf(time_string, "%4d%2d%2d%2d%2d%2dZ",
212 &exploded_time.year, &exploded_time.month, 226 &exploded_time.year, &exploded_time.month,
213 &exploded_time.day_of_month, &exploded_time.hour, 227 &exploded_time.day_of_month, &exploded_time.hour,
214 &exploded_time.minute, &exploded_time.second); 228 &exploded_time.minute, &exploded_time.second);
215 free(time_string); 229 free(time_string);
216 230
217 if (assignments == 6) { 231 if (assignments == 6) {
218 *time = base::Time::FromUTCExploded(exploded_time); 232 *time = base::Time::FromUTCExploded(exploded_time);
219 return true; 233 return true;
220 } 234 }
221 return false; 235 return false;
222 } 236 }
223 237
238 // Returns the Keychain SecAuthenticationType type corresponding to |scheme|.
224 SecAuthenticationType AuthTypeForScheme(PasswordForm::Scheme scheme) { 239 SecAuthenticationType AuthTypeForScheme(PasswordForm::Scheme scheme) {
225 switch (scheme) { 240 switch (scheme) {
226 case PasswordForm::SCHEME_HTML: return kSecAuthenticationTypeHTMLForm; 241 case PasswordForm::SCHEME_HTML: return kSecAuthenticationTypeHTMLForm;
227 case PasswordForm::SCHEME_BASIC: return kSecAuthenticationTypeHTTPBasic; 242 case PasswordForm::SCHEME_BASIC: return kSecAuthenticationTypeHTTPBasic;
228 case PasswordForm::SCHEME_DIGEST: return kSecAuthenticationTypeHTTPDigest; 243 case PasswordForm::SCHEME_DIGEST: return kSecAuthenticationTypeHTTPDigest;
229 case PasswordForm::SCHEME_OTHER: return kSecAuthenticationTypeDefault; 244 case PasswordForm::SCHEME_OTHER: return kSecAuthenticationTypeDefault;
230 } 245 }
231 NOTREACHED(); 246 NOTREACHED();
232 return kSecAuthenticationTypeDefault; 247 return kSecAuthenticationTypeDefault;
233 } 248 }
234 249
250 // Returns the PasswordForm Scheme corresponding to |auth_type|.
235 PasswordForm::Scheme SchemeForAuthType(SecAuthenticationType auth_type) { 251 PasswordForm::Scheme SchemeForAuthType(SecAuthenticationType auth_type) {
236 switch (auth_type) { 252 switch (auth_type) {
237 case kSecAuthenticationTypeHTMLForm: return PasswordForm::SCHEME_HTML; 253 case kSecAuthenticationTypeHTMLForm: return PasswordForm::SCHEME_HTML;
238 case kSecAuthenticationTypeHTTPBasic: return PasswordForm::SCHEME_BASIC; 254 case kSecAuthenticationTypeHTTPBasic: return PasswordForm::SCHEME_BASIC;
239 case kSecAuthenticationTypeHTTPDigest: return PasswordForm::SCHEME_DIGEST; 255 case kSecAuthenticationTypeHTTPDigest: return PasswordForm::SCHEME_DIGEST;
240 default: return PasswordForm::SCHEME_OTHER; 256 default: return PasswordForm::SCHEME_OTHER;
241 } 257 }
242 } 258 }
243 259
244 // Searches |keychain| for all items usable for the given signon_realm, and 260 SecKeychainItemRef MatchingKeychainItem(const MacKeychain& keychain,
245 // puts them in |items|. The caller is responsible for calling keychain->Free 261 const PasswordForm& form) {
246 // on each of them when it is finished with them.
247 void FindMatchingKeychainItems(const MacKeychain& keychain,
248 const std::string& signon_realm,
249 PasswordForm::Scheme scheme,
250 std::vector<SecKeychainItemRef>* items) {
251 // Construct a keychain search based on the signon_realm and scheme.
252 std::string server;
253 std::string security_domain;
254 int port;
255 bool is_secure;
256 if (!ExtractSignonRealmComponents(signon_realm, &server, &port, &is_secure,
257 &security_domain)) {
258 // TODO(stuartmorgan): Proxies will currently fail here, since their
259 // signon_realm is not a URL. We need to detect the proxy case and handle
260 // it specially.
261 return;
262 }
263
264 SecProtocolType protocol = is_secure ? kSecProtocolTypeHTTPS
265 : kSecProtocolTypeHTTP;
266 SecAuthenticationType auth_type = AuthTypeForScheme(scheme);
267
268 KeychainSearch keychain_search(keychain);
269 keychain_search.Init(server.c_str(), port, protocol, auth_type,
270 (scheme == PasswordForm::SCHEME_HTML) ?
271 NULL : security_domain.c_str(),
272 NULL, NULL);
273 keychain_search.FindMatchingItems(items);
274 }
275
276 SecKeychainItemRef FindMatchingKeychainItem(const MacKeychain& keychain,
277 const PasswordForm& form) {
278 // We don't store blacklist entries in the keychain, so the answer to "what 262 // We don't store blacklist entries in the keychain, so the answer to "what
279 // Keychain item goes with this form" is always "nothing" for blacklists. 263 // Keychain item goes with this form" is always "nothing" for blacklists.
280 if (form.blacklisted_by_user) { 264 if (form.blacklisted_by_user) {
281 return NULL; 265 return NULL;
282 } 266 }
283 267
284 // Construct a keychain search based on all the unique attributes. 268 // Construct a keychain search based on all the unique attributes.
285 std::string server; 269 std::string server;
286 std::string security_domain; 270 std::string security_domain;
287 int port; 271 int port;
(...skipping 138 matching lines...) Expand 10 before | Expand all | Expand 10 after
426 form->origin = URLFromComponents(form->ssl_valid, server, port, path); 410 form->origin = URLFromComponents(form->ssl_valid, server, port, path);
427 // TODO(stuartmorgan): Handle proxies, which need a different signon_realm 411 // TODO(stuartmorgan): Handle proxies, which need a different signon_realm
428 // format. 412 // format.
429 form->signon_realm = form->origin.GetOrigin().spec(); 413 form->signon_realm = form->origin.GetOrigin().spec();
430 if (form->scheme != PasswordForm::SCHEME_HTML) { 414 if (form->scheme != PasswordForm::SCHEME_HTML) {
431 form->signon_realm.append(security_domain); 415 form->signon_realm.append(security_domain);
432 } 416 }
433 return true; 417 return true;
434 } 418 }
435 419
436 bool AddKeychainEntryForForm(const MacKeychain& keychain,
437 const PasswordForm& form) {
438 std::string server;
439 std::string security_domain;
440 int port;
441 bool is_secure;
442 if (!ExtractSignonRealmComponents(form.signon_realm, &server, &port,
443 &is_secure, &security_domain)) {
444 return false;
445 }
446 std::string username = WideToUTF8(form.username_value);
447 std::string password = WideToUTF8(form.password_value);
448 std::string path = form.origin.path();
449 SecProtocolType protocol = is_secure ? kSecProtocolTypeHTTPS
450 : kSecProtocolTypeHTTP;
451 OSStatus result = keychain.AddInternetPassword(
452 NULL, server.size(), server.c_str(),
453 security_domain.size(), security_domain.c_str(),
454 username.size(), username.c_str(),
455 path.size(), path.c_str(),
456 port, protocol, AuthTypeForScheme(form.scheme),
457 password.size(), password.c_str(), NULL);
458
459 // If we collide with an existing item, find and update it instead.
460 if (result == errSecDuplicateItem) {
461 SecKeychainItemRef existing_item = FindMatchingKeychainItem(keychain, form);
462 if (!existing_item) {
463 return false;
464 }
465 bool changed = SetKeychainItemPassword(keychain, existing_item, password);
466 keychain.Free(existing_item);
467 return changed;
468 }
469
470 return (result == noErr);
471 }
472
473 bool SetKeychainItemPassword(const MacKeychain& keychain,
474 const SecKeychainItemRef& keychain_item,
475 const std::string& password) {
476 OSStatus result = keychain.ItemModifyAttributesAndData(keychain_item, NULL,
477 password.size(),
478 password.c_str());
479 return (result == noErr);
480 }
481
482 bool FormsMatchForMerge(const PasswordForm& form_a, const PasswordForm& form_b, 420 bool FormsMatchForMerge(const PasswordForm& form_a, const PasswordForm& form_b,
483 bool* path_matches) { 421 bool* path_matches) {
484 // We never merge blacklist entries between our store and the keychain. 422 // We never merge blacklist entries between our store and the keychain.
485 if (form_a.blacklisted_by_user || form_b.blacklisted_by_user) { 423 if (form_a.blacklisted_by_user || form_b.blacklisted_by_user) {
486 return false; 424 return false;
487 } 425 }
488 bool matches = form_a.scheme == form_b.scheme && 426 bool matches = form_a.scheme == form_b.scheme &&
489 form_a.signon_realm == form_b.signon_realm && 427 form_a.signon_realm == form_b.signon_realm &&
490 form_a.username_value == form_b.username_value; 428 form_a.username_value == form_b.username_value;
491 if (matches && path_matches) { 429 if (matches && path_matches) {
(...skipping 63 matching lines...) Expand 10 before | Expand all | Expand 10 after
555 } else { 493 } else {
556 if (used_keychain_forms.find(keychain_form) == used_keychain_forms.end()) 494 if (used_keychain_forms.find(keychain_form) == used_keychain_forms.end())
557 merged_forms->push_back(keychain_form); 495 merged_forms->push_back(keychain_form);
558 else 496 else
559 delete keychain_form; 497 delete keychain_form;
560 i = keychain_forms->erase(i); 498 i = keychain_forms->erase(i);
561 } 499 }
562 } 500 }
563 } 501 }
564 502
565 // Returns PasswordForms constructed from the given Keychain items. 503 } // namespace internal_keychain_helpers
504
505 #pragma mark -
506
507 MacKeychainPasswordFormAdapter::MacKeychainPasswordFormAdapter(
508 MacKeychain* keychain) : keychain_(keychain) {
509 }
510
511 // Returns PasswordForms for each keychain entry matching |form|.
566 // Caller is responsible for deleting the returned forms. 512 // Caller is responsible for deleting the returned forms.
567 std::vector<PasswordForm*> CreateFormsFromKeychainItems( 513 std::vector<PasswordForm*>
568 const MacKeychain& keychain, 514 MacKeychainPasswordFormAdapter::PasswordsMatchingForm(
569 const std::vector<SecKeychainItemRef>& items) { 515 const PasswordForm& query_form) {
516 std::vector<SecKeychainItemRef> keychain_items =
517 MatchingKeychainItems(query_form.signon_realm, query_form.scheme);
518
519 std::vector<PasswordForm*> keychain_forms =
520 CreateFormsFromKeychainItems(keychain_items);
521 for (std::vector<SecKeychainItemRef>::iterator i = keychain_items.begin();
522 i != keychain_items.end(); ++i) {
523 keychain_->Free(*i);
524 }
525 return keychain_forms;
526 }
527
528 bool MacKeychainPasswordFormAdapter::AddLogin(const PasswordForm& form) {
529 std::string server;
530 std::string security_domain;
531 int port;
532 bool is_secure;
533 if (!internal_keychain_helpers::ExtractSignonRealmComponents(
534 form.signon_realm, &server, &port, &is_secure, &security_domain)) {
535 return false;
536 }
537 std::string username = WideToUTF8(form.username_value);
538 std::string password = WideToUTF8(form.password_value);
539 std::string path = form.origin.path();
540 SecProtocolType protocol = is_secure ? kSecProtocolTypeHTTPS
541 : kSecProtocolTypeHTTP;
542 OSStatus result = keychain_->AddInternetPassword(
543 NULL, server.size(), server.c_str(),
544 security_domain.size(), security_domain.c_str(),
545 username.size(), username.c_str(),
546 path.size(), path.c_str(),
547 port, protocol, internal_keychain_helpers::AuthTypeForScheme(form.scheme),
548 password.size(), password.c_str(), NULL);
549
550 // If we collide with an existing item, find and update it instead.
551 if (result == errSecDuplicateItem) {
552 SecKeychainItemRef existing_item =
553 internal_keychain_helpers::MatchingKeychainItem(*keychain_, form);
554 if (!existing_item) {
555 return false;
556 }
557 bool changed = SetKeychainItemPassword(existing_item, password);
558 keychain_->Free(existing_item);
559 return changed;
560 }
561
562 return (result == noErr);
563 }
564
565 std::vector<PasswordForm*>
566 MacKeychainPasswordFormAdapter::CreateFormsFromKeychainItems(
567 const std::vector<SecKeychainItemRef>& items) {
570 std::vector<PasswordForm*> keychain_forms; 568 std::vector<PasswordForm*> keychain_forms;
571 for (std::vector<SecKeychainItemRef>::const_iterator i = items.begin(); 569 for (std::vector<SecKeychainItemRef>::const_iterator i = items.begin();
572 i != items.end(); ++i) { 570 i != items.end(); ++i) {
573 PasswordForm* form = new PasswordForm(); 571 PasswordForm* form = new PasswordForm();
574 if (FillPasswordFormFromKeychainItem(keychain, *i, form)) { 572 if (internal_keychain_helpers::FillPasswordFormFromKeychainItem(*keychain_,
573 *i, form)) {
575 keychain_forms.push_back(form); 574 keychain_forms.push_back(form);
576 } 575 }
577 } 576 }
578 return keychain_forms; 577 return keychain_forms;
579 } 578 }
580 579
581 // Returns PasswordForms for each keychain entry matching |form|. 580 // Searches |keychain| for all items usable for the given signon_realm, and
582 // Caller is responsible for deleting the returned forms. 581 // returns them. The caller is responsible for calling keychain->Free
583 std::vector<PasswordForm*> KeychainFormsMatchingForm( 582 // on each of them when it is finished with them.
584 const MacKeychain& keychain, const PasswordForm& query_form) { 583 std::vector<SecKeychainItemRef>
585 std::vector<SecKeychainItemRef> keychain_items; 584 MacKeychainPasswordFormAdapter::MatchingKeychainItems(
586 FindMatchingKeychainItems(keychain, query_form.signon_realm, 585 const std::string& signon_realm, PasswordForm::Scheme scheme) {
587 query_form.scheme, &keychain_items); 586 std::vector<SecKeychainItemRef> matches;
587 // Construct a keychain search based on the signon_realm and scheme.
588 std::string server;
589 std::string security_domain;
590 int port;
591 bool is_secure;
592 if (!internal_keychain_helpers::ExtractSignonRealmComponents(
593 signon_realm, &server, &port, &is_secure, &security_domain)) {
594 // TODO(stuartmorgan): Proxies will currently fail here, since their
595 // signon_realm is not a URL. We need to detect the proxy case and handle
596 // it specially.
597 return matches;
598 }
588 599
589 std::vector<PasswordForm*> keychain_forms = 600 SecProtocolType protocol = is_secure ? kSecProtocolTypeHTTPS
590 CreateFormsFromKeychainItems(keychain, keychain_items); 601 : kSecProtocolTypeHTTP;
591 for (std::vector<SecKeychainItemRef>::iterator i = keychain_items.begin(); 602 SecAuthenticationType auth_type =
592 i != keychain_items.end(); ++i) { 603 internal_keychain_helpers::AuthTypeForScheme(scheme);
593 keychain.Free(*i); 604
594 } 605 KeychainSearch keychain_search(*keychain_);
595 return keychain_forms; 606 keychain_search.Init(server.c_str(), port, protocol, auth_type,
607 (scheme == PasswordForm::SCHEME_HTML) ?
608 NULL : security_domain.c_str(),
609 NULL, NULL);
610 keychain_search.FindMatchingItems(&matches);
611 return matches;
596 } 612 }
597 613
598 } // namespace internal_keychain_helpers 614 bool MacKeychainPasswordFormAdapter::SetKeychainItemPassword(
615 const SecKeychainItemRef& keychain_item, const std::string& password) {
616 OSStatus result = keychain_->ItemModifyAttributesAndData(keychain_item, NULL,
617 password.size(),
618 password.c_str());
619 return (result == noErr);
620 }
599 621
600 #pragma mark - 622 #pragma mark -
601 623
602 PasswordStoreMac::PasswordStoreMac(MacKeychain* keychain, 624 PasswordStoreMac::PasswordStoreMac(MacKeychain* keychain,
603 LoginDatabaseMac* login_db) 625 LoginDatabaseMac* login_db)
604 : keychain_(keychain), login_metadata_db_(login_db) { 626 : keychain_(keychain), login_metadata_db_(login_db) {
605 DCHECK(keychain_.get()); 627 DCHECK(keychain_.get());
606 DCHECK(login_metadata_db_.get()); 628 DCHECK(login_metadata_db_.get());
607 } 629 }
608 630
609 PasswordStoreMac::~PasswordStoreMac() {} 631 PasswordStoreMac::~PasswordStoreMac() {}
610 632
611 void PasswordStoreMac::AddLoginImpl(const PasswordForm& form) { 633 void PasswordStoreMac::AddLoginImpl(const PasswordForm& form) {
612 NOTIMPLEMENTED(); 634 NOTIMPLEMENTED();
613 } 635 }
614 636
615 void PasswordStoreMac::UpdateLoginImpl(const PasswordForm& form) { 637 void PasswordStoreMac::UpdateLoginImpl(const PasswordForm& form) {
616 NOTIMPLEMENTED(); 638 NOTIMPLEMENTED();
617 } 639 }
618 640
619 void PasswordStoreMac::RemoveLoginImpl(const PasswordForm& form) { 641 void PasswordStoreMac::RemoveLoginImpl(const PasswordForm& form) {
620 NOTIMPLEMENTED(); 642 NOTIMPLEMENTED();
621 } 643 }
622 644
623 void PasswordStoreMac::GetLoginsImpl(GetLoginsRequest* request) { 645 void PasswordStoreMac::GetLoginsImpl(GetLoginsRequest* request) {
646 MacKeychainPasswordFormAdapter keychainAdapter(keychain_.get());
624 std::vector<PasswordForm*> keychain_forms = 647 std::vector<PasswordForm*> keychain_forms =
625 internal_keychain_helpers::KeychainFormsMatchingForm(*keychain_, 648 keychainAdapter.PasswordsMatchingForm(request->form);
626 request->form);
627 649
628 std::vector<PasswordForm*> database_forms; 650 std::vector<PasswordForm*> database_forms;
629 login_metadata_db_->GetLogins(request->form, &database_forms); 651 login_metadata_db_->GetLogins(request->form, &database_forms);
630 652
631 std::vector<PasswordForm*> merged_forms; 653 std::vector<PasswordForm*> merged_forms;
632 internal_keychain_helpers::MergePasswordForms(&keychain_forms, 654 internal_keychain_helpers::MergePasswordForms(&keychain_forms,
633 &database_forms, 655 &database_forms,
634 &merged_forms); 656 &merged_forms);
635 657
636 // Clean up any orphaned database entries. 658 // Clean up any orphaned database entries.
637 for (std::vector<PasswordForm*>::iterator i = database_forms.begin(); 659 for (std::vector<PasswordForm*>::iterator i = database_forms.begin();
638 i != database_forms.end(); ++i) { 660 i != database_forms.end(); ++i) {
639 login_metadata_db_->RemoveLogin(**i); 661 login_metadata_db_->RemoveLogin(**i);
640 } 662 }
641 // Delete the forms we aren't returning. 663 // Delete the forms we aren't returning.
642 STLDeleteElements(&database_forms); 664 STLDeleteElements(&database_forms);
643 STLDeleteElements(&keychain_forms); 665 STLDeleteElements(&keychain_forms);
644 666
645 NotifyConsumer(request, merged_forms); 667 NotifyConsumer(request, merged_forms);
646 } 668 }
OLDNEW
« no previous file with comments | « no previous file | chrome/browser/password_manager/password_store_mac_internal.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698