summaryrefslogtreecommitdiffstats
path: root/crypto/mock_keychain_mac.h
diff options
context:
space:
mode:
authorakalin@chromium.org <akalin@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2012-03-17 12:14:50 +0000
committerakalin@chromium.org <akalin@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2012-03-17 12:14:50 +0000
commitb9d3d0028bbef6846b017c3ce8514f012921f65f (patch)
tree1667a362918c39ab52c25c9acb63a68751329630 /crypto/mock_keychain_mac.h
parent236790f7ae982eb6dda025960964a88d4fc538f8 (diff)
downloadchromium_src-b9d3d0028bbef6846b017c3ce8514f012921f65f.zip
chromium_src-b9d3d0028bbef6846b017c3ce8514f012921f65f.tar.gz
chromium_src-b9d3d0028bbef6846b017c3ce8514f012921f65f.tar.bz2
Move *keychain_mac* files to crypto/
This is in preparation for moving password_manager/encryptor* to crypto/. This also fixes an ODR violation; mock_keychain_mac.cc was being compiled in two targets which are linked together. BUG=118564 TEST= Review URL: http://codereview.chromium.org/9699112 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@127358 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'crypto/mock_keychain_mac.h')
-rw-r--r--crypto/mock_keychain_mac.h226
1 files changed, 226 insertions, 0 deletions
diff --git a/crypto/mock_keychain_mac.h b/crypto/mock_keychain_mac.h
new file mode 100644
index 0000000..d52353e
--- /dev/null
+++ b/crypto/mock_keychain_mac.h
@@ -0,0 +1,226 @@
+// 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 CRYPTO_MOCK_KEYCHAIN_MAC_H_
+#define CRYPTO_MOCK_KEYCHAIN_MAC_H_
+#pragma once
+
+#include <map>
+#include <set>
+#include <string>
+#include <vector>
+
+#include "base/compiler_specific.h"
+#include "crypto/keychain_mac.h"
+
+namespace crypto {
+
+// Mock Keychain wrapper for testing code that interacts with the OS X
+// Keychain. Implemented by storing SecKeychainAttributeList and
+// KeychainPasswordData values in separate mutable containers and
+// mapping them to integer keys.
+//
+// Note that "const" is pretty much meaningless for this class; the const-ness
+// of MacKeychain doesn't apply to the actual keychain data, so all of the Mock
+// data is mutable; don't assume that it won't change over the life of tests.
+class MockKeychain : public MacKeychain {
+ public:
+ MockKeychain();
+ virtual ~MockKeychain();
+
+ // MacKeychain implementation.
+ virtual OSStatus ItemCopyAttributesAndData(
+ SecKeychainItemRef itemRef,
+ SecKeychainAttributeInfo* info,
+ SecItemClass* itemClass,
+ SecKeychainAttributeList** attrList,
+ UInt32* length,
+ void** outData) const OVERRIDE;
+ // Pass "fail_me" as the data to get errSecAuthFailed.
+ virtual OSStatus ItemModifyAttributesAndData(
+ SecKeychainItemRef itemRef,
+ const SecKeychainAttributeList* attrList,
+ UInt32 length,
+ const void* data) const OVERRIDE;
+ virtual OSStatus ItemFreeAttributesAndData(SecKeychainAttributeList* attrList,
+ void* data) const OVERRIDE;
+ virtual OSStatus ItemDelete(SecKeychainItemRef itemRef) const OVERRIDE;
+ virtual OSStatus SearchCreateFromAttributes(
+ CFTypeRef keychainOrArray,
+ SecItemClass itemClass,
+ const SecKeychainAttributeList* attrList,
+ SecKeychainSearchRef* searchRef) const OVERRIDE;
+ virtual OSStatus SearchCopyNext(SecKeychainSearchRef searchRef,
+ SecKeychainItemRef* itemRef) const OVERRIDE;
+ // Pass "some.domain.com" as the serverName to get errSecDuplicateItem.
+ virtual OSStatus AddInternetPassword(
+ SecKeychainRef keychain,
+ UInt32 serverNameLength,
+ const char* serverName,
+ UInt32 securityDomainLength,
+ const char* securityDomain,
+ UInt32 accountNameLength,
+ const char* accountName,
+ UInt32 pathLength, const char* path,
+ UInt16 port, SecProtocolType protocol,
+ SecAuthenticationType authenticationType,
+ UInt32 passwordLength,
+ const void* passwordData,
+ SecKeychainItemRef* itemRef) const OVERRIDE;
+ virtual OSStatus FindGenericPassword(
+ CFTypeRef keychainOrArray,
+ UInt32 serviceNameLength,
+ const char* serviceName,
+ UInt32 accountNameLength,
+ const char* accountName,
+ UInt32* passwordLength,
+ void** passwordData,
+ SecKeychainItemRef* itemRef) const OVERRIDE;
+ virtual OSStatus ItemFreeContent(SecKeychainAttributeList* attrList,
+ void* data) const OVERRIDE;
+ virtual OSStatus AddGenericPassword(
+ SecKeychainRef keychain,
+ UInt32 serviceNameLength,
+ const char* serviceName,
+ UInt32 accountNameLength,
+ const char* accountName,
+ UInt32 passwordLength,
+ const void* passwordData,
+ SecKeychainItemRef* itemRef) const OVERRIDE;
+ virtual void Free(CFTypeRef ref) const OVERRIDE;
+
+ // Return the counts of objects returned by Create/Copy functions but never
+ // Free'd as they should have been.
+ int UnfreedSearchCount() const;
+ int UnfreedKeychainItemCount() const;
+ int UnfreedAttributeDataCount() const;
+
+ // Returns true if all items added with AddInternetPassword have a creator
+ // code set.
+ bool CreatorCodesSetForAddedItems() const;
+
+ struct KeychainTestData {
+ const SecAuthenticationType auth_type;
+ const char* server;
+ const SecProtocolType protocol;
+ const char* path;
+ const UInt32 port;
+ const char* security_domain;
+ const char* creation_date;
+ const char* username;
+ const char* password;
+ const bool negative_item;
+ };
+ // Adds a keychain item with the given info to the test set.
+ void AddTestItem(const KeychainTestData& item_data);
+
+ // |FindGenericPassword()| can return different results depending on user
+ // interaction with the system Keychain. For mocking purposes we allow the
+ // user of this class to specify the result code of the
+ // |FindGenericPassword()| call so we can simulate the result of different
+ // user interactions.
+ void set_find_generic_result(OSStatus result) {
+ find_generic_result_ = result;
+ }
+
+ // Returns the true if |AddGenericPassword()| was called.
+ bool called_add_generic() const { return called_add_generic_; }
+
+ // Returns the value of the password set when |AddGenericPassword()| was
+ // called.
+ std::string add_generic_password() const { return add_generic_password_; }
+
+ // Returns the number of allocations - deallocations for password data.
+ int password_data_count() const { return password_data_count_; }
+
+ private:
+ // Returns true if the keychain already contains a password that matches the
+ // attributes provided.
+ bool AlreadyContainsInternetPassword(
+ UInt32 serverNameLength,
+ const char* serverName,
+ UInt32 securityDomainLength,
+ const char* securityDomain,
+ UInt32 accountNameLength,
+ const char* accountName,
+ UInt32 pathLength,
+ const char* path,
+ UInt16 port,
+ SecProtocolType protocol,
+ SecAuthenticationType authenticationType) const;
+ // Initializes storage for keychain data at |key|.
+ void InitializeKeychainData(unsigned int key) const;
+ // Sets the data and length of |tag| in the item-th test item.
+ void SetTestDataBytes(int item, UInt32 tag, const void* data, size_t length);
+ // Sets the data and length of |tag| in the item-th test item based on
+ // |value|. The null-terminator will not be included; the Keychain Services
+ // docs don't indicate whether it is or not, so clients should not assume
+ // that it will be.
+ void SetTestDataString(int item, UInt32 tag, const char* value);
+ // Sets the data of the corresponding attribute of the item-th test item to
+ // |value|. Assumes that the space has alread been allocated, and the length
+ // set.
+ void SetTestDataPort(int item, UInt32 value);
+ void SetTestDataProtocol(int item, SecProtocolType value);
+ void SetTestDataAuthType(int item, SecAuthenticationType value);
+ void SetTestDataNegativeItem(int item, Boolean value);
+ void SetTestDataCreator(int item, OSType value);
+ // Sets the password data and length for the item-th test item.
+ void SetTestDataPasswordBytes(int item, const void* data, size_t length);
+ // Sets the password for the item-th test item. As with SetTestDataString,
+ // the data will not be null-terminated.
+ void SetTestDataPasswordString(int item, const char* value);
+
+ // Returns the address of the attribute in attribute_list with tag |tag|.
+ static SecKeychainAttribute* AttributeWithTag(
+ const SecKeychainAttributeList& attribute_list,
+ UInt32 tag);
+
+ static const int kDummySearchRef = 1000;
+
+ typedef struct KeychainPasswordData {
+ KeychainPasswordData() : data(NULL), length(0) {}
+ void* data;
+ UInt32 length;
+ } KeychainPasswordData;
+
+ // Mutable because the MockKeychain API requires its internal keychain storage
+ // to be modifiable by users of this class.
+ mutable std::map<unsigned int, SecKeychainAttributeList> keychain_attr_list_;
+ mutable std::map<unsigned int, KeychainPasswordData> keychain_data_;
+ mutable unsigned int next_item_key_;
+
+ // Tracks the items that should be returned in subsequent calls to
+ // SearchCopyNext, based on the last call to SearchCreateFromAttributes.
+ // We can't handle multiple active searches, since we don't track the search
+ // ref we return, but we don't need to for our mocking.
+ mutable std::vector<unsigned int> remaining_search_results_;
+
+ // Track copies and releases to make sure they balance. Really these should
+ // be maps to track per item, but this should be good enough to catch
+ // real mistakes.
+ mutable int search_copy_count_;
+ mutable int keychain_item_copy_count_;
+ mutable int attribute_data_copy_count_;
+
+ // Tracks which items (by key) were added with AddInternetPassword.
+ mutable std::set<unsigned int> added_via_api_;
+
+ // Result code for the |FindGenericPassword()| method.
+ OSStatus find_generic_result_;
+
+ // Records whether |AddGenericPassword()| gets called.
+ mutable bool called_add_generic_;
+
+ // Tracks the allocations and frees of password data in |FindGenericPassword|
+ // and |ItemFreeContent|.
+ mutable unsigned int password_data_count_;
+
+ // Records the password being set when |AddGenericPassword()| gets called.
+ mutable std::string add_generic_password_;
+};
+
+} // namespace crypto
+
+#endif // CRYPTO_MOCK_KEYCHAIN_MAC_H_