| 1 |
#import "MVKeyChain.h" |
|---|
| 2 |
|
|---|
| 3 |
#define MVStringByteLength(a) (( [a UTF8String] ? strlen( [a UTF8String] ) : 0 )) |
|---|
| 4 |
|
|---|
| 5 |
static MVKeyChain *sharedInstance = nil; |
|---|
| 6 |
|
|---|
| 7 |
@implementation MVKeyChain |
|---|
| 8 |
+ (MVKeyChain *) defaultKeyChain { |
|---|
| 9 |
return ( sharedInstance ? sharedInstance : ( sharedInstance = [[self alloc] init] ) ); |
|---|
| 10 |
} |
|---|
| 11 |
|
|---|
| 12 |
- (void) dealloc { |
|---|
| 13 |
if( sharedInstance == self ) sharedInstance = nil; |
|---|
| 14 |
[super dealloc]; |
|---|
| 15 |
} |
|---|
| 16 |
|
|---|
| 17 |
- (void) setGenericPassword:(NSString *) password forService:(NSString *) service account:(NSString *) account { |
|---|
| 18 |
NSParameterAssert( service ); |
|---|
| 19 |
NSParameterAssert( account ); |
|---|
| 20 |
|
|---|
| 21 |
if( ! [password length] ) { |
|---|
| 22 |
[self removeGenericPasswordForService:service account:account]; |
|---|
| 23 |
} else if( ! [[self genericPasswordForService:service account:account] isEqualToString:password] ) { |
|---|
| 24 |
[self removeGenericPasswordForService:service account:account]; |
|---|
| 25 |
SecKeychainAddGenericPassword( NULL, MVStringByteLength( service ), [service UTF8String], MVStringByteLength( account ), [account UTF8String], MVStringByteLength( password ), (void *) [password UTF8String], NULL ); |
|---|
| 26 |
} |
|---|
| 27 |
} |
|---|
| 28 |
|
|---|
| 29 |
- (NSString *) genericPasswordForService:(NSString *) service account:(NSString *) account { |
|---|
| 30 |
OSStatus ret = 0; |
|---|
| 31 |
unsigned long len = 0; |
|---|
| 32 |
void *p = NULL; |
|---|
| 33 |
NSString *string = nil; |
|---|
| 34 |
|
|---|
| 35 |
ret = SecKeychainFindGenericPassword( NULL, MVStringByteLength( service ), [service UTF8String], MVStringByteLength( account ), [account UTF8String], &len, &p, NULL ); |
|---|
| 36 |
if( ret == noErr ) string = [[NSString allocWithZone:nil] initWithBytes:(const void *) p length:len encoding:NSUTF8StringEncoding]; |
|---|
| 37 |
SecKeychainItemFreeContent( NULL, p ); |
|---|
| 38 |
|
|---|
| 39 |
return [string autorelease]; |
|---|
| 40 |
} |
|---|
| 41 |
|
|---|
| 42 |
- (void) removeGenericPasswordForService:(NSString *) service account:(NSString *) account { |
|---|
| 43 |
OSStatus ret = 0; |
|---|
| 44 |
SecKeychainItemRef itemref = NULL; |
|---|
| 45 |
|
|---|
| 46 |
NSParameterAssert( service ); |
|---|
| 47 |
NSParameterAssert( account ); |
|---|
| 48 |
|
|---|
| 49 |
ret = SecKeychainFindGenericPassword( NULL, MVStringByteLength( service ), [service UTF8String], MVStringByteLength( account ), [account UTF8String], NULL, NULL, &itemref ); |
|---|
| 50 |
if( ret == noErr ) SecKeychainItemDelete( itemref ); |
|---|
| 51 |
} |
|---|
| 52 |
|
|---|
| 53 |
- (void) setInternetPassword:(NSString *) password forServer:(NSString *) server securityDomain:(NSString *) domain account:(NSString *) account path:(NSString *) path port:(unsigned short) port protocol:(MVKeyChainProtocol) protocol authenticationType:(MVKeyChainAuthenticationType) authType { |
|---|
| 54 |
NSParameterAssert( server || account ); |
|---|
| 55 |
|
|---|
| 56 |
if( ! [password length] ) { |
|---|
| 57 |
[self removeInternetPasswordForServer:server securityDomain:domain account:account path:nil port:port protocol:protocol authenticationType:authType]; |
|---|
| 58 |
} else if( ! [[self internetPasswordForServer:server securityDomain:domain account:account path:nil port:port protocol:protocol authenticationType:authType] isEqualToString:password] ) { |
|---|
| 59 |
[self removeInternetPasswordForServer:server securityDomain:domain account:account path:nil port:port protocol:protocol authenticationType:authType]; |
|---|
| 60 |
SecKeychainAddInternetPassword( NULL, MVStringByteLength( server ), [server UTF8String], MVStringByteLength( domain ), [domain UTF8String], MVStringByteLength( account ), [account UTF8String], MVStringByteLength( path ), [path UTF8String], port, protocol, authType, MVStringByteLength( password ), (void *) [password UTF8String], NULL ); |
|---|
| 61 |
} |
|---|
| 62 |
} |
|---|
| 63 |
|
|---|
| 64 |
- (NSString *) internetPasswordForServer:(NSString *) server securityDomain:(NSString *) domain account:(NSString *) account path:(NSString *) path port:(unsigned short) port protocol:(MVKeyChainProtocol) protocol authenticationType:(MVKeyChainAuthenticationType) authType { |
|---|
| 65 |
OSStatus ret = 0; |
|---|
| 66 |
unsigned long len = 0; |
|---|
| 67 |
void *p = NULL; |
|---|
| 68 |
NSString *string = nil; |
|---|
| 69 |
|
|---|
| 70 |
ret = SecKeychainFindInternetPassword( NULL, MVStringByteLength( server ), [server UTF8String], MVStringByteLength( domain ), [domain UTF8String], MVStringByteLength( account ), [account UTF8String], MVStringByteLength( path ), [path UTF8String], port, protocol, authType, &len, &p, NULL ); |
|---|
| 71 |
if( ret == noErr ) string = [[NSString allocWithZone:nil] initWithBytes:(const void *) p length:len encoding:NSUTF8StringEncoding]; |
|---|
| 72 |
SecKeychainItemFreeContent( NULL, p ); |
|---|
| 73 |
|
|---|
| 74 |
return [string autorelease]; |
|---|
| 75 |
} |
|---|
| 76 |
|
|---|
| 77 |
- (void) removeInternetPasswordForServer:(NSString *) server securityDomain:(NSString *) domain account:(NSString *) account path:(NSString *) path port:(unsigned short) port protocol:(MVKeyChainProtocol) protocol authenticationType:(MVKeyChainAuthenticationType) authType { |
|---|
| 78 |
OSStatus ret = 0; |
|---|
| 79 |
SecKeychainItemRef itemref = NULL; |
|---|
| 80 |
|
|---|
| 81 |
NSParameterAssert( server || account ); |
|---|
| 82 |
|
|---|
| 83 |
ret = SecKeychainFindInternetPassword( NULL, MVStringByteLength( server ), [server UTF8String], MVStringByteLength( domain ), [domain UTF8String], MVStringByteLength( account ), [account UTF8String], MVStringByteLength( path ), [path UTF8String], port, protocol, authType, NULL, NULL, &itemref ); |
|---|
| 84 |
if( ret == noErr ) SecKeychainItemDelete( itemref ); |
|---|
| 85 |
} |
|---|
| 86 |
@end |
|---|