//Authors: Mohammad Tirtashi mo3b.com
// Phillip Vitorino philv.com
//Last changed: December 9th 2006
//keychain.cpp
#include "keychain.h"
// TODO: make thread safe
// TODO: change ChangeInternetPassword: add the serverNameLength to the attribute list in order to avoid collisions when searching keychain items.
keychain* keychain::inst = NULL;
// default constructor - serves no purpose for now
keychain::keychain(){};
keychain::~keychain(){
delete inst; //deletes a temporary instance of a keychain object in memory.
};
// returns an instance of the curret keychain object in memory. If none exist then one is created.
keychain* keychain::getInstance(){
if (inst == NULL) {
inst = new keychain;
}
return inst;
}
/* adds an internet keychain entry to the keychain database.
see http://developer.apple.com/documentation/Security/Reference/keychainservices/Reference/reference.html#//apple_ref/doc/uid/TP30000898-CH5g-95690
for return codes*/
int keychain::AddInternetPassword (
SecKeychainRef keychain/* a reference to the keychain where the entry
will be added to. If NULL then the default keychain is used. */,
int serverNameLength, const char *serverName /* eg. www.google.com */,
int securityDomainLength, const char *securityDomain,
int accountNameLength, const char *accountName /* username */, int pathLength,
const char *path /* the path to the login form eg. www.google.com'/dir' */,
int port /* the port by which the connection is made to the server: 80,443. etc... etc... */,
SecProtocolType protocol /* protocol type (ftp, http and so on) */
/* http://developer.apple.com/documentation/Security/Reference/keychainservices/Reference/reference.html#//apple_ref/doc/c_ref/SecProtocolType */,
SecAuthenticationType authenticationType /* authentication type idetifier */
/* http://developer.apple.com/documentation/Security/Reference/keychainservices/Reference/reference.html#//apple_ref/doc/c_ref/SecAuthenticationType */,
int passwordLength, const void *passwordData /* A pointer to a buffer containing the password data to be stored in
the keychain */,
SecKeychainItemRef *itemRef /* a reference to a keychain item */) {
int rc = 0;
rc = SecKeychainAddInternetPassword (keychain , serverNameLength, serverName, securityDomainLength,
securityDomain, accountNameLength, accountName, pathLength, path, port, protocol, authenticationType,
passwordLength, passwordData, itemRef);
return rc;
}
/* retrieves a keychain item from the keychain database.
see http://developer.apple.com/documentation/Security/Reference/keychainservices/Reference/reference.html#//apple_ref/doc/uid/TP30000898-CH5g-95690
for return codes */
int keychain::RetrieveInternetPassword (
SecKeychainRef keychain/* a reference to the keychain where the entry will be added to. If NULL then the
default keychain is used. */,
int serverNameLength, const char *serverName, int securityDomainLength,
const char *securityDomain,int pathLength,
const char *path, int port, SecProtocolType protocol, SecAuthenticationType authenticationType,
UInt32 *passwordLength,/* pointer to the length of the password data in buffer */
void **passwordData,/* a pointer to a buffer containing the password */
SecKeychainItemRef *itemRef){
int rc = 0;
rc = SecKeychainFindInternetPassword (keychain, serverNameLength, serverName, securityDomainLength,securityDomain,
NULL, NULL, pathLength, path, port, protocol, authenticationType, passwordLength, passwordData, itemRef);
return rc;
}
// modifies an existing keychain entry's password attribute
int keychain::ChangeInternetPassword (SecKeychainItemRef itemRef /* a reference to the keychain item that will have its password changed */,
int accountNameLength, const char *accountName,
int passwordLength, const void *passwordData) {
int rc = 0;
if (accountName && passwordData) {
// creating an attribute vector.
// in this case since we're searching the keychain items by using the username as the keyword, we're only creating the Account attribute.
SecKeychainAttribute attrs[] = {{ kSecAccountItemAttr, accountNameLength, (char *)accountName }};
// creating a list of attributes
const SecKeychainAttributeList attributes = { sizeof(attrs) / sizeof(attrs[0]) /* determining the number of attributes. In our case this is 1*/,
attrs /* the vector with the username attribute in it */ };
/* updating the keychain item with the new password attribute that we just created */
rc = SecKeychainItemModifyAttributesAndData (itemRef, &attributes, passwordLength, passwordData);
}
return rc;
}