OS X Keychain integration Keychain.cpp

From CDOT Wiki
Revision as of 22:05, 8 February 2007 by Pcvitori (talk | contribs)
(diff) ← Older revision | Latest revision (diff) | Newer revision → (diff)
Jump to: navigation, search
//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;

}