| OLD | NEW |
| 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> |
| (...skipping 125 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 136 OSStatus result = keychain_->SearchCreateFromAttributes( | 136 OSStatus result = keychain_->SearchCreateFromAttributes( |
| 137 NULL, kSecInternetPasswordItemClass, &search_attributes_, &search_ref_); | 137 NULL, kSecInternetPasswordItemClass, &search_attributes_, &search_ref_); |
| 138 | 138 |
| 139 if (result != noErr) { | 139 if (result != noErr) { |
| 140 LOG(ERROR) << "Keychain lookup failed with error " << result; | 140 LOG(ERROR) << "Keychain lookup failed with error " << result; |
| 141 return; | 141 return; |
| 142 } | 142 } |
| 143 | 143 |
| 144 SecKeychainItemRef keychain_item; | 144 SecKeychainItemRef keychain_item; |
| 145 while (keychain_->SearchCopyNext(search_ref_, &keychain_item) == noErr) { | 145 while (keychain_->SearchCopyNext(search_ref_, &keychain_item) == noErr) { |
| 146 // Consumer is responsible for deleting the forms when they are done. | 146 // Consumer is responsible for freeing the items. |
| 147 items->push_back(keychain_item); | 147 items->push_back(keychain_item); |
| 148 } | 148 } |
| 149 | 149 |
| 150 keychain_->Free(search_ref_); | 150 keychain_->Free(search_ref_); |
| 151 search_ref_ = NULL; | 151 search_ref_ = NULL; |
| 152 } | 152 } |
| 153 | 153 |
| 154 #pragma mark - | 154 #pragma mark - |
| 155 | 155 |
| 156 // TODO(stuartmorgan): Convert most of this to private helpers in | 156 // TODO(stuartmorgan): Convert most of this to private helpers in |
| 157 // MacKeychainPaswordFormAdapter once it has sufficient higher-level public | 157 // MacKeychainPaswordFormAdapter once it has sufficient higher-level public |
| 158 // methods to provide test coverage. | 158 // methods to provide test coverage. |
| 159 namespace internal_keychain_helpers { | 159 namespace internal_keychain_helpers { |
| 160 | 160 |
| 161 // Takes a PasswordForm's signon_realm and parses it into its component parts, | |
| 162 // which are returned though the appropriate out parameters. | |
| 163 // Returns true if it can be successfully parsed, in which case all out params | |
| 164 // that are non-NULL will be set. If there is no port, port will be 0. | |
| 165 // If the return value is false, the state of the our params is undefined. | |
| 166 // | |
| 167 // TODO(stuartmorgan): signon_realm for proxies is not yet supported. | |
| 168 bool ExtractSignonRealmComponents(const std::string& signon_realm, | |
| 169 std::string* server, int* port, | |
| 170 bool* is_secure, | |
| 171 std::string* security_domain) { | |
| 172 // The signon_realm will be the Origin portion of a URL for an HTML form, | |
| 173 // and the same but with the security domain as a path for HTTP auth. | |
| 174 GURL realm_as_url(signon_realm); | |
| 175 if (!realm_as_url.is_valid()) { | |
| 176 return false; | |
| 177 } | |
| 178 | |
| 179 if (server) | |
| 180 *server = realm_as_url.host(); | |
| 181 if (is_secure) | |
| 182 *is_secure = realm_as_url.SchemeIsSecure(); | |
| 183 if (port) | |
| 184 *port = realm_as_url.has_port() ? atoi(realm_as_url.port().c_str()) : 0; | |
| 185 if (security_domain) { | |
| 186 // Strip the leading '/' off of the path to get the security domain. | |
| 187 *security_domain = realm_as_url.path().substr(1); | |
| 188 } | |
| 189 return true; | |
| 190 } | |
| 191 | |
| 192 // Returns a URL built from the given components. To create a URL without a | 161 // Returns a URL built from the given components. To create a URL without a |
| 193 // port, pass kAnyPort for the |port| parameter. | 162 // port, pass kAnyPort for the |port| parameter. |
| 194 GURL URLFromComponents(bool is_secure, const std::string& host, int port, | 163 GURL URLFromComponents(bool is_secure, const std::string& host, int port, |
| 195 const std::string& path) { | 164 const std::string& path) { |
| 196 GURL::Replacements url_components; | 165 GURL::Replacements url_components; |
| 197 std::string scheme(is_secure ? "https" : "http"); | 166 std::string scheme(is_secure ? "https" : "http"); |
| 198 url_components.SetSchemeStr(scheme); | 167 url_components.SetSchemeStr(scheme); |
| 199 url_components.SetHostStr(host); | 168 url_components.SetHostStr(host); |
| 200 std::string port_string; // Must remain in scope until after we do replacing. | 169 std::string port_string; // Must remain in scope until after we do replacing. |
| 201 if (port != kAnyPort) { | 170 if (port != kAnyPort) { |
| (...skipping 28 matching lines...) Expand all Loading... |
| 230 &exploded_time.minute, &exploded_time.second); | 199 &exploded_time.minute, &exploded_time.second); |
| 231 free(time_string); | 200 free(time_string); |
| 232 | 201 |
| 233 if (assignments == 6) { | 202 if (assignments == 6) { |
| 234 *time = base::Time::FromUTCExploded(exploded_time); | 203 *time = base::Time::FromUTCExploded(exploded_time); |
| 235 return true; | 204 return true; |
| 236 } | 205 } |
| 237 return false; | 206 return false; |
| 238 } | 207 } |
| 239 | 208 |
| 240 // Returns the Keychain SecAuthenticationType type corresponding to |scheme|. | |
| 241 SecAuthenticationType AuthTypeForScheme(PasswordForm::Scheme scheme) { | |
| 242 switch (scheme) { | |
| 243 case PasswordForm::SCHEME_HTML: return kSecAuthenticationTypeHTMLForm; | |
| 244 case PasswordForm::SCHEME_BASIC: return kSecAuthenticationTypeHTTPBasic; | |
| 245 case PasswordForm::SCHEME_DIGEST: return kSecAuthenticationTypeHTTPDigest; | |
| 246 case PasswordForm::SCHEME_OTHER: return kSecAuthenticationTypeDefault; | |
| 247 } | |
| 248 NOTREACHED(); | |
| 249 return kSecAuthenticationTypeDefault; | |
| 250 } | |
| 251 | |
| 252 // Returns the PasswordForm Scheme corresponding to |auth_type|. | 209 // Returns the PasswordForm Scheme corresponding to |auth_type|. |
| 253 PasswordForm::Scheme SchemeForAuthType(SecAuthenticationType auth_type) { | 210 PasswordForm::Scheme SchemeForAuthType(SecAuthenticationType auth_type) { |
| 254 switch (auth_type) { | 211 switch (auth_type) { |
| 255 case kSecAuthenticationTypeHTMLForm: return PasswordForm::SCHEME_HTML; | 212 case kSecAuthenticationTypeHTMLForm: return PasswordForm::SCHEME_HTML; |
| 256 case kSecAuthenticationTypeHTTPBasic: return PasswordForm::SCHEME_BASIC; | 213 case kSecAuthenticationTypeHTTPBasic: return PasswordForm::SCHEME_BASIC; |
| 257 case kSecAuthenticationTypeHTTPDigest: return PasswordForm::SCHEME_DIGEST; | 214 case kSecAuthenticationTypeHTTPDigest: return PasswordForm::SCHEME_DIGEST; |
| 258 default: return PasswordForm::SCHEME_OTHER; | 215 default: return PasswordForm::SCHEME_OTHER; |
| 259 } | 216 } |
| 260 } | 217 } |
| 261 | 218 |
| 262 SecKeychainItemRef MatchingKeychainItem(const MacKeychain& keychain, | |
| 263 const PasswordForm& form) { | |
| 264 // We don't store blacklist entries in the keychain, so the answer to "what | |
| 265 // Keychain item goes with this form" is always "nothing" for blacklists. | |
| 266 if (form.blacklisted_by_user) { | |
| 267 return NULL; | |
| 268 } | |
| 269 | |
| 270 // Construct a keychain search based on all the unique attributes. | |
| 271 std::string server; | |
| 272 std::string security_domain; | |
| 273 int port; | |
| 274 bool is_secure; | |
| 275 if (!ExtractSignonRealmComponents(form.signon_realm, &server, &port, | |
| 276 &is_secure, &security_domain)) { | |
| 277 // TODO(stuartmorgan): Proxies will currently fail here, since their | |
| 278 // signon_realm is not a URL. We need to detect the proxy case and handle | |
| 279 // it specially. | |
| 280 return NULL; | |
| 281 } | |
| 282 | |
| 283 SecProtocolType protocol = is_secure ? kSecProtocolTypeHTTPS | |
| 284 : kSecProtocolTypeHTTP; | |
| 285 SecAuthenticationType auth_type = AuthTypeForScheme(form.scheme); | |
| 286 std::string path = form.origin.path(); | |
| 287 std::string username = WideToUTF8(form.username_value); | |
| 288 | |
| 289 KeychainSearch keychain_search(keychain); | |
| 290 keychain_search.Init(server.c_str(), port, protocol, auth_type, | |
| 291 (form.scheme == PasswordForm::SCHEME_HTML) ? | |
| 292 NULL : security_domain.c_str(), | |
| 293 path.c_str(), username.c_str()); | |
| 294 | |
| 295 std::vector<SecKeychainItemRef> matches; | |
| 296 keychain_search.FindMatchingItems(&matches); | |
| 297 | |
| 298 if (matches.size() == 0) { | |
| 299 return NULL; | |
| 300 } | |
| 301 // Free all items after the first, since we won't be returning them. | |
| 302 for (std::vector<SecKeychainItemRef>::iterator i = matches.begin() + 1; | |
| 303 i != matches.end(); ++i) { | |
| 304 keychain.Free(*i); | |
| 305 } | |
| 306 return matches[0]; | |
| 307 } | |
| 308 | |
| 309 bool FillPasswordFormFromKeychainItem(const MacKeychain& keychain, | 219 bool FillPasswordFormFromKeychainItem(const MacKeychain& keychain, |
| 310 const SecKeychainItemRef& keychain_item, | 220 const SecKeychainItemRef& keychain_item, |
| 311 PasswordForm* form) { | 221 PasswordForm* form) { |
| 312 DCHECK(form); | 222 DCHECK(form); |
| 313 | 223 |
| 314 SecKeychainAttributeInfo attrInfo; | 224 SecKeychainAttributeInfo attrInfo; |
| 315 UInt32 tags[] = { kSecAccountItemAttr, | 225 UInt32 tags[] = { kSecAccountItemAttr, |
| 316 kSecServerItemAttr, | 226 kSecServerItemAttr, |
| 317 kSecPortItemAttr, | 227 kSecPortItemAttr, |
| 318 kSecPathItemAttr, | 228 kSecPathItemAttr, |
| (...skipping 184 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 503 } | 413 } |
| 504 | 414 |
| 505 } // namespace internal_keychain_helpers | 415 } // namespace internal_keychain_helpers |
| 506 | 416 |
| 507 #pragma mark - | 417 #pragma mark - |
| 508 | 418 |
| 509 MacKeychainPasswordFormAdapter::MacKeychainPasswordFormAdapter( | 419 MacKeychainPasswordFormAdapter::MacKeychainPasswordFormAdapter( |
| 510 MacKeychain* keychain) : keychain_(keychain) { | 420 MacKeychain* keychain) : keychain_(keychain) { |
| 511 } | 421 } |
| 512 | 422 |
| 513 // Returns PasswordForms for each keychain entry matching |form|. | |
| 514 // Caller is responsible for deleting the returned forms. | |
| 515 std::vector<PasswordForm*> | 423 std::vector<PasswordForm*> |
| 516 MacKeychainPasswordFormAdapter::PasswordsMatchingForm( | 424 MacKeychainPasswordFormAdapter::PasswordsMatchingForm( |
| 517 const PasswordForm& query_form) { | 425 const PasswordForm& query_form) { |
| 518 std::vector<SecKeychainItemRef> keychain_items = | 426 std::vector<SecKeychainItemRef> keychain_items = |
| 519 MatchingKeychainItems(query_form.signon_realm, query_form.scheme); | 427 KeychainItemsForFillingForm(query_form); |
| 520 | 428 |
| 521 std::vector<PasswordForm*> keychain_forms = | 429 std::vector<PasswordForm*> keychain_forms = |
| 522 CreateFormsFromKeychainItems(keychain_items); | 430 CreateFormsFromKeychainItems(keychain_items); |
| 523 for (std::vector<SecKeychainItemRef>::iterator i = keychain_items.begin(); | 431 for (std::vector<SecKeychainItemRef>::iterator i = keychain_items.begin(); |
| 524 i != keychain_items.end(); ++i) { | 432 i != keychain_items.end(); ++i) { |
| 525 keychain_->Free(*i); | 433 keychain_->Free(*i); |
| 526 } | 434 } |
| 527 return keychain_forms; | 435 return keychain_forms; |
| 528 } | 436 } |
| 529 | 437 |
| 438 PasswordForm* MacKeychainPasswordFormAdapter::PasswordExactlyMatchingForm( |
| 439 const PasswordForm& query_form) { |
| 440 SecKeychainItemRef keychain_item = KeychainItemForForm(query_form); |
| 441 if (keychain_item) { |
| 442 PasswordForm* form = new PasswordForm(); |
| 443 internal_keychain_helpers::FillPasswordFormFromKeychainItem(*keychain_, |
| 444 keychain_item, |
| 445 form); |
| 446 keychain_->Free(keychain_item); |
| 447 return form; |
| 448 } |
| 449 return NULL; |
| 450 } |
| 451 |
| 530 bool MacKeychainPasswordFormAdapter::AddLogin(const PasswordForm& form) { | 452 bool MacKeychainPasswordFormAdapter::AddLogin(const PasswordForm& form) { |
| 531 std::string server; | 453 std::string server; |
| 532 std::string security_domain; | 454 std::string security_domain; |
| 533 int port; | 455 int port; |
| 534 bool is_secure; | 456 bool is_secure; |
| 535 if (!internal_keychain_helpers::ExtractSignonRealmComponents( | 457 if (!ExtractSignonRealmComponents(form.signon_realm, &server, &port, |
| 536 form.signon_realm, &server, &port, &is_secure, &security_domain)) { | 458 &is_secure, &security_domain)) { |
| 537 return false; | 459 return false; |
| 538 } | 460 } |
| 539 std::string username = WideToUTF8(form.username_value); | 461 std::string username = WideToUTF8(form.username_value); |
| 540 std::string password = WideToUTF8(form.password_value); | 462 std::string password = WideToUTF8(form.password_value); |
| 541 std::string path = form.origin.path(); | 463 std::string path = form.origin.path(); |
| 542 SecProtocolType protocol = is_secure ? kSecProtocolTypeHTTPS | 464 SecProtocolType protocol = is_secure ? kSecProtocolTypeHTTPS |
| 543 : kSecProtocolTypeHTTP; | 465 : kSecProtocolTypeHTTP; |
| 544 SecKeychainItemRef new_item = NULL; | 466 SecKeychainItemRef new_item = NULL; |
| 545 OSStatus result = keychain_->AddInternetPassword( | 467 OSStatus result = keychain_->AddInternetPassword( |
| 546 NULL, server.size(), server.c_str(), | 468 NULL, server.size(), server.c_str(), |
| 547 security_domain.size(), security_domain.c_str(), | 469 security_domain.size(), security_domain.c_str(), |
| 548 username.size(), username.c_str(), | 470 username.size(), username.c_str(), |
| 549 path.size(), path.c_str(), | 471 path.size(), path.c_str(), |
| 550 port, protocol, internal_keychain_helpers::AuthTypeForScheme(form.scheme), | 472 port, protocol, AuthTypeForScheme(form.scheme), |
| 551 password.size(), password.c_str(), &new_item); | 473 password.size(), password.c_str(), &new_item); |
| 552 | 474 |
| 553 if (result == noErr) { | 475 if (result == noErr) { |
| 554 SetKeychainItemCreatorCode(new_item, kChromeKeychainCreatorCode); | 476 SetKeychainItemCreatorCode(new_item, kChromeKeychainCreatorCode); |
| 555 keychain_->Free(new_item); | 477 keychain_->Free(new_item); |
| 556 } else if (result == errSecDuplicateItem) { | 478 } else if (result == errSecDuplicateItem) { |
| 557 // If we collide with an existing item, find and update it instead. | 479 // If we collide with an existing item, find and update it instead. |
| 558 SecKeychainItemRef existing_item = | 480 SecKeychainItemRef existing_item = KeychainItemForForm(form); |
| 559 internal_keychain_helpers::MatchingKeychainItem(*keychain_, form); | |
| 560 if (!existing_item) { | 481 if (!existing_item) { |
| 561 return false; | 482 return false; |
| 562 } | 483 } |
| 563 bool changed = SetKeychainItemPassword(existing_item, password); | 484 bool changed = SetKeychainItemPassword(existing_item, password); |
| 564 keychain_->Free(existing_item); | 485 keychain_->Free(existing_item); |
| 565 return changed; | 486 return changed; |
| 566 } | 487 } |
| 567 | 488 |
| 568 return result == noErr; | 489 return result == noErr; |
| 569 } | 490 } |
| 570 | 491 |
| 571 std::vector<PasswordForm*> | 492 std::vector<PasswordForm*> |
| 572 MacKeychainPasswordFormAdapter::CreateFormsFromKeychainItems( | 493 MacKeychainPasswordFormAdapter::CreateFormsFromKeychainItems( |
| 573 const std::vector<SecKeychainItemRef>& items) { | 494 const std::vector<SecKeychainItemRef>& items) { |
| 574 std::vector<PasswordForm*> keychain_forms; | 495 std::vector<PasswordForm*> keychain_forms; |
| 575 for (std::vector<SecKeychainItemRef>::const_iterator i = items.begin(); | 496 for (std::vector<SecKeychainItemRef>::const_iterator i = items.begin(); |
| 576 i != items.end(); ++i) { | 497 i != items.end(); ++i) { |
| 577 PasswordForm* form = new PasswordForm(); | 498 PasswordForm* form = new PasswordForm(); |
| 578 if (internal_keychain_helpers::FillPasswordFormFromKeychainItem(*keychain_, | 499 if (internal_keychain_helpers::FillPasswordFormFromKeychainItem(*keychain_, |
| 579 *i, form)) { | 500 *i, form)) { |
| 580 keychain_forms.push_back(form); | 501 keychain_forms.push_back(form); |
| 581 } | 502 } |
| 582 } | 503 } |
| 583 return keychain_forms; | 504 return keychain_forms; |
| 584 } | 505 } |
| 585 | 506 |
| 586 // Searches |keychain| for all items usable for the given signon_realm, and | 507 std::vector<SecKeychainItemRef> |
| 587 // returns them. The caller is responsible for calling keychain->Free | 508 MacKeychainPasswordFormAdapter::KeychainItemsForFillingForm( |
| 588 // on each of them when it is finished with them. | 509 const PasswordForm& form) { |
| 510 return MatchingKeychainItems(form.signon_realm, form.scheme, NULL, NULL); |
| 511 } |
| 512 |
| 513 SecKeychainItemRef MacKeychainPasswordFormAdapter::KeychainItemForForm( |
| 514 const PasswordForm& form) { |
| 515 // We don't store blacklist entries in the keychain, so the answer to "what |
| 516 // Keychain item goes with this form" is always "nothing" for blacklists. |
| 517 if (form.blacklisted_by_user) { |
| 518 return NULL; |
| 519 } |
| 520 |
| 521 std::string path = form.origin.path(); |
| 522 std::string username = WideToUTF8(form.username_value); |
| 523 std::vector<SecKeychainItemRef> matches = MatchingKeychainItems( |
| 524 form.signon_realm, form.scheme, path.c_str(), username.c_str()); |
| 525 |
| 526 if (matches.size() == 0) { |
| 527 return NULL; |
| 528 } |
| 529 // Free all items after the first, since we won't be returning them. |
| 530 for (std::vector<SecKeychainItemRef>::iterator i = matches.begin() + 1; |
| 531 i != matches.end(); ++i) { |
| 532 keychain_->Free(*i); |
| 533 } |
| 534 return matches[0]; |
| 535 } |
| 536 |
| 589 std::vector<SecKeychainItemRef> | 537 std::vector<SecKeychainItemRef> |
| 590 MacKeychainPasswordFormAdapter::MatchingKeychainItems( | 538 MacKeychainPasswordFormAdapter::MatchingKeychainItems( |
| 591 const std::string& signon_realm, PasswordForm::Scheme scheme) { | 539 const std::string& signon_realm, |
| 540 webkit_glue::PasswordForm::Scheme scheme, |
| 541 const char* path, const char* username) { |
| 592 std::vector<SecKeychainItemRef> matches; | 542 std::vector<SecKeychainItemRef> matches; |
| 593 // Construct a keychain search based on the signon_realm and scheme. | 543 |
| 594 std::string server; | 544 std::string server; |
| 595 std::string security_domain; | 545 std::string security_domain; |
| 596 int port; | 546 int port; |
| 597 bool is_secure; | 547 bool is_secure; |
| 598 if (!internal_keychain_helpers::ExtractSignonRealmComponents( | 548 if (!ExtractSignonRealmComponents(signon_realm, &server, &port, |
| 599 signon_realm, &server, &port, &is_secure, &security_domain)) { | 549 &is_secure, &security_domain)) { |
| 600 // TODO(stuartmorgan): Proxies will currently fail here, since their | 550 // TODO(stuartmorgan): Proxies will currently fail here, since their |
| 601 // signon_realm is not a URL. We need to detect the proxy case and handle | 551 // signon_realm is not a URL. We need to detect the proxy case and handle |
| 602 // it specially. | 552 // it specially. |
| 603 return matches; | 553 return matches; |
| 604 } | 554 } |
| 605 | |
| 606 SecProtocolType protocol = is_secure ? kSecProtocolTypeHTTPS | 555 SecProtocolType protocol = is_secure ? kSecProtocolTypeHTTPS |
| 607 : kSecProtocolTypeHTTP; | 556 : kSecProtocolTypeHTTP; |
| 608 SecAuthenticationType auth_type = | 557 SecAuthenticationType auth_type = AuthTypeForScheme(scheme); |
| 609 internal_keychain_helpers::AuthTypeForScheme(scheme); | 558 const char* auth_domain = (scheme == PasswordForm::SCHEME_HTML) ? |
| 559 NULL : security_domain.c_str(); |
| 610 | 560 |
| 611 KeychainSearch keychain_search(*keychain_); | 561 KeychainSearch keychain_search(*keychain_); |
| 612 keychain_search.Init(server.c_str(), port, protocol, auth_type, | 562 keychain_search.Init(server.c_str(), port, protocol, auth_type, |
| 613 (scheme == PasswordForm::SCHEME_HTML) ? | 563 auth_domain, path, username); |
| 614 NULL : security_domain.c_str(), | |
| 615 NULL, NULL); | |
| 616 keychain_search.FindMatchingItems(&matches); | 564 keychain_search.FindMatchingItems(&matches); |
| 617 return matches; | 565 return matches; |
| 618 } | 566 } |
| 619 | 567 |
| 568 // TODO(stuartmorgan): signon_realm for proxies is not yet supported. |
| 569 bool MacKeychainPasswordFormAdapter::ExtractSignonRealmComponents( |
| 570 const std::string& signon_realm, std::string* server, int* port, |
| 571 bool* is_secure, std::string* security_domain) { |
| 572 // The signon_realm will be the Origin portion of a URL for an HTML form, |
| 573 // and the same but with the security domain as a path for HTTP auth. |
| 574 GURL realm_as_url(signon_realm); |
| 575 if (!realm_as_url.is_valid()) { |
| 576 return false; |
| 577 } |
| 578 |
| 579 if (server) |
| 580 *server = realm_as_url.host(); |
| 581 if (is_secure) |
| 582 *is_secure = realm_as_url.SchemeIsSecure(); |
| 583 if (port) |
| 584 *port = realm_as_url.has_port() ? atoi(realm_as_url.port().c_str()) : 0; |
| 585 if (security_domain) { |
| 586 // Strip the leading '/' off of the path to get the security domain. |
| 587 *security_domain = realm_as_url.path().substr(1); |
| 588 } |
| 589 return true; |
| 590 } |
| 591 |
| 592 // Returns the Keychain SecAuthenticationType type corresponding to |scheme|. |
| 593 SecAuthenticationType MacKeychainPasswordFormAdapter::AuthTypeForScheme( |
| 594 PasswordForm::Scheme scheme) { |
| 595 switch (scheme) { |
| 596 case PasswordForm::SCHEME_HTML: return kSecAuthenticationTypeHTMLForm; |
| 597 case PasswordForm::SCHEME_BASIC: return kSecAuthenticationTypeHTTPBasic; |
| 598 case PasswordForm::SCHEME_DIGEST: return kSecAuthenticationTypeHTTPDigest; |
| 599 case PasswordForm::SCHEME_OTHER: return kSecAuthenticationTypeDefault; |
| 600 } |
| 601 NOTREACHED(); |
| 602 return kSecAuthenticationTypeDefault; |
| 603 } |
| 604 |
| 620 bool MacKeychainPasswordFormAdapter::SetKeychainItemPassword( | 605 bool MacKeychainPasswordFormAdapter::SetKeychainItemPassword( |
| 621 const SecKeychainItemRef& keychain_item, const std::string& password) { | 606 const SecKeychainItemRef& keychain_item, const std::string& password) { |
| 622 OSStatus result = keychain_->ItemModifyAttributesAndData(keychain_item, NULL, | 607 OSStatus result = keychain_->ItemModifyAttributesAndData(keychain_item, NULL, |
| 623 password.size(), | 608 password.size(), |
| 624 password.c_str()); | 609 password.c_str()); |
| 625 return result == noErr; | 610 return result == noErr; |
| 626 } | 611 } |
| 627 | 612 |
| 628 bool MacKeychainPasswordFormAdapter::SetKeychainItemCreatorCode( | 613 bool MacKeychainPasswordFormAdapter::SetKeychainItemCreatorCode( |
| 629 const SecKeychainItemRef& keychain_item, OSType creator_code) { | 614 const SecKeychainItemRef& keychain_item, OSType creator_code) { |
| (...skipping 59 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 689 for (std::vector<PasswordForm*>::iterator i = database_forms.begin(); | 674 for (std::vector<PasswordForm*>::iterator i = database_forms.begin(); |
| 690 i != database_forms.end(); ++i) { | 675 i != database_forms.end(); ++i) { |
| 691 login_metadata_db_->RemoveLogin(**i); | 676 login_metadata_db_->RemoveLogin(**i); |
| 692 } | 677 } |
| 693 // Delete the forms we aren't returning. | 678 // Delete the forms we aren't returning. |
| 694 STLDeleteElements(&database_forms); | 679 STLDeleteElements(&database_forms); |
| 695 STLDeleteElements(&keychain_forms); | 680 STLDeleteElements(&keychain_forms); |
| 696 | 681 |
| 697 NotifyConsumer(request, merged_forms); | 682 NotifyConsumer(request, merged_forms); |
| 698 } | 683 } |
| OLD | NEW |