1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219
|
// Copyright (c) 2012 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifndef CHROME_BROWSER_PASSWORD_MANAGER_PASSWORD_STORE_MAC_INTERNAL_H_
#define CHROME_BROWSER_PASSWORD_MANAGER_PASSWORD_STORE_MAC_INTERNAL_H_
#include <Security/Security.h>
#include <string>
#include <vector>
#include "components/autofill/core/common/password_form.h"
#include "crypto/apple_keychain.h"
using crypto::AppleKeychain;
// Adapter that wraps a AppleKeychain and provides interaction in terms of
// PasswordForms instead of Keychain items.
class MacKeychainPasswordFormAdapter {
public:
// Creates an adapter for |keychain|. This class does not take ownership of
// |keychain|, so the caller must make sure that the keychain outlives the
// created object.
explicit MacKeychainPasswordFormAdapter(const AppleKeychain* keychain);
// Returns PasswordForms for each keychain entry that could be used to fill
// |form|. Caller is responsible for deleting the returned forms.
std::vector<autofill::PasswordForm*> PasswordsFillingForm(
const std::string& signon_realm,
autofill::PasswordForm::Scheme scheme);
// Returns true if there is the Keychain entry that matches |query_form| on
// all of the fields that uniquely identify a Keychain item.
bool HasPasswordExactlyMatchingForm(const autofill::PasswordForm& query_form);
// Returns true if the keychain contains any items that are mergeable with
// |query_form|. This is different from actually extracting the passwords
// and checking the return count, since doing that would require reading the
// passwords from the keychain, thus potentially triggering authorizaiton UI,
// whereas this won't.
bool HasPasswordsMergeableWithForm(
const autofill::PasswordForm& query_form);
// Returns all keychain items of types corresponding to password forms.
std::vector<SecKeychainItemRef> GetAllPasswordFormKeychainItems();
// Returns password data from all keychain items of types corresponding to
// password forms. Caller is responsible for deleting the returned forms.
std::vector<autofill::PasswordForm*> GetAllPasswordFormPasswords();
// Creates a new keychain entry from |form|, or updates the password of an
// existing keychain entry if there is a collision. Returns true if a keychain
// entry was successfully added/updated.
bool AddPassword(const autofill::PasswordForm& form);
// Removes the keychain password matching |form| if any. Returns true if a
// keychain item was found and successfully removed.
bool RemovePassword(const autofill::PasswordForm& form);
// Controls whether or not Chrome will restrict Keychain searches to items
// that it created. Defaults to false.
void SetFindsOnlyOwnedItems(bool finds_only_owned);
private:
// Returns PasswordForms constructed from the given Keychain items, calling
// AppleKeychain::Free on all of the keychain items and clearing the vector.
// Caller is responsible for deleting the returned forms.
std::vector<autofill::PasswordForm*> ConvertKeychainItemsToForms(
std::vector<SecKeychainItemRef>* items);
// Searches |keychain| for the specific keychain entry that corresponds to the
// given form, and returns it (or NULL if no match is found). The caller is
// responsible for calling AppleKeychain::Free on on the returned item.
SecKeychainItemRef KeychainItemForForm(
const autofill::PasswordForm& form);
// Returns the Keychain items matching the given signon_realm, scheme, and
// optionally path and username (either of both can be NULL).
// The caller is responsible for calling AppleKeychain::Free on the
// returned items.
std::vector<SecKeychainItemRef> MatchingKeychainItems(
const std::string& signon_realm,
autofill::PasswordForm::Scheme scheme,
const char* path,
const char* username);
// Returns the Keychain SecAuthenticationType type corresponding to |scheme|.
SecAuthenticationType AuthTypeForScheme(
autofill::PasswordForm::Scheme scheme);
// Changes the password for keychain_item to |password|; returns true if the
// password was successfully changed.
bool SetKeychainItemPassword(const SecKeychainItemRef& keychain_item,
const std::string& password);
// Sets the creator code of keychain_item to creator_code; returns true if the
// creator code was successfully set.
bool SetKeychainItemCreatorCode(const SecKeychainItemRef& keychain_item,
OSType creator_code);
// Returns the creator code to be used for a Keychain search, depending on
// whether this object was instructed to search only for items it created.
// If searches should be restricted in this way, the application-specific
// creator code will be returned. Otherwise, 0 will be returned, indicating
// a search of all items, regardless of creator.
OSType CreatorCodeForSearch();
const AppleKeychain* keychain_;
// If true, Keychain searches are restricted to items created by Chrome.
bool finds_only_owned_;
DISALLOW_COPY_AND_ASSIGN(MacKeychainPasswordFormAdapter);
};
namespace internal_keychain_helpers {
// Pair of pointers to a SecKeychainItemRef and a corresponding PasswordForm.
typedef std::pair<SecKeychainItemRef*, autofill::PasswordForm*> ItemFormPair;
// Sets the fields of |form| based on the keychain data from |keychain_item|.
// Fields that can't be determined from |keychain_item| will be unchanged. If
// |extract_password_data| is true, the password data will be copied from
// |keychain_item| in addition to its attributes, and the |blacklisted_by_user|
// field will be set to true for empty passwords ("" or " ").
// If |extract_password_data| is false, only the password attributes will be
// copied, and the |blacklisted_by_user| field will always be false.
//
// IMPORTANT: If |extract_password_data| is true, this function can cause the OS
// to trigger UI (to allow access to the keychain item if we aren't trusted for
// the item), and block until the UI is dismissed.
//
// If excessive prompting for access to other applications' keychain items
// becomes an issue, the password storage API will need to intially call this
// function with |extract_password_data| set to false, and retrieve the password
// later (accessing other fields doesn't require authorization).
bool FillPasswordFormFromKeychainItem(const AppleKeychain& keychain,
const SecKeychainItemRef& keychain_item,
autofill::PasswordForm* form,
bool extract_password_data);
// Use FormMatchStrictness to configure which forms are considered a match by
// FormsMatchForMerge:
enum FormMatchStrictness {
STRICT_FORM_MATCH, // Match only forms with the same scheme, signon realm and
// username value.
FUZZY_FORM_MATCH, // Also match cases where the first form's
// original_signon_realm is nonempty and matches the
// second form's signon_realm.
};
// Returns true if the two given forms are suitable for merging (see
// MergePasswordForms).
bool FormsMatchForMerge(const autofill::PasswordForm& form_a,
const autofill::PasswordForm& form_b,
FormMatchStrictness strictness);
// Populates merged_forms by combining the password data from keychain_forms and
// the metadata from database_forms, removing used entries from the two source
// lists.
//
// On return, database_forms and keychain_forms will have only unused
// entries; for database_forms that means entries for which no corresponding
// password can be found (and which aren't blacklist entries), and for
// keychain_forms its entries that weren't merged into at least one database
// form.
void MergePasswordForms(
std::vector<autofill::PasswordForm*>* keychain_forms,
std::vector<autofill::PasswordForm*>* database_forms,
std::vector<autofill::PasswordForm*>* merged_forms);
// Fills in the passwords for as many of the forms in |database_forms| as
// possible using entries from |keychain| and returns them. On return,
// |database_forms| will contain only the forms for which no password was found.
std::vector<autofill::PasswordForm*> GetPasswordsForForms(
const AppleKeychain& keychain,
std::vector<autofill::PasswordForm*>* database_forms);
// Loads all items in the system keychain into |keychain_items|, creates for
// each keychain item a corresponding PasswordForm that doesn't contain any
// password data, and returns the two collections as a vector of ItemFormPairs.
// Used by GetPasswordsForForms for optimized matching of keychain items with
// PasswordForms in the database.
// Note: Since no password data is loaded here, the resulting PasswordForms
// will include blacklist entries, which will have to be filtered out later.
// Caller owns the SecKeychainItemRefs and PasswordForms that are returned.
// This operation does not require OS authorization.
std::vector<ItemFormPair> ExtractAllKeychainItemAttributesIntoPasswordForms(
std::vector<SecKeychainItemRef>* keychain_items,
const AppleKeychain& keychain);
// Takes a PasswordForm's signon_realm and parses it into its component parts,
// which are returned though the appropriate out parameters.
// Returns true if it can be successfully parsed, in which case all out params
// that are non-NULL will be set. If there is no port, port will be 0.
// If the return value is false, the state of the out params is undefined.
bool ExtractSignonRealmComponents(const std::string& signon_realm,
std::string* server,
UInt32* port,
bool* is_secure,
std::string* security_domain);
// Returns true if the signon_realm of |query_form| can be successfully parsed
// by ExtractSignonRealmComponents, and if |query_form| matches |other_form|.
bool FormIsValidAndMatchesOtherForm(const autofill::PasswordForm& query_form,
const autofill::PasswordForm& other_form);
// Returns PasswordForms populated with password data for each keychain entry
// in |item_form_pairs| that could be merged with |query_form|.
// Caller is responsible for deleting the returned forms.
std::vector<autofill::PasswordForm*> ExtractPasswordsMergeableWithForm(
const AppleKeychain& keychain,
const std::vector<ItemFormPair>& item_form_pairs,
const autofill::PasswordForm& query_form);
} // namespace internal_keychain_helpers
#endif // CHROME_BROWSER_PASSWORD_MANAGER_PASSWORD_STORE_MAC_INTERNAL_H_
|