-
Notifications
You must be signed in to change notification settings - Fork 0
/
SSGenericKeychainItem.m
130 lines (95 loc) · 4.29 KB
/
SSGenericKeychainItem.m
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
//
// SSGenericKeychainItem.m
// SSKeychain
//
// Created by Sam Soffes on 4/6/10.
// Copyright 2010 Sam Soffes. All rights reserved.
//
#import "SSGenericKeychainItem.h"
#import <Security/Security.h>
@interface SSGenericKeychainItem (PrivateMethods)
- (void)_setCoreKeychainItemAttributeWithTag:(SecItemAttr)attributeTag toString:(NSString *)stringValue;
@end
@implementation SSGenericKeychainItem
@synthesize serviceName;
#pragma mark -
#pragma mark Class Methods
#pragma mark -
+ (SSGenericKeychainItem *)genericKeychainItem:(SecKeychainItemRef)item forServiceName:(NSString *)aServiceName username:(NSString *)aUsername password:(NSString *)aPassword {
return [[[self alloc] initWithCoreKeychainItem:item serviceName:aServiceName username:aUsername password:aPassword] autorelease];
}
+ (SSGenericKeychainItem *)createGenericKeychainItemForServiceName:(NSString *)aServiceName withUsername:(NSString *)aUsername password:(NSString *)aPassword {
if (!aUsername || [aUsername length] == 0 || !aServiceName || [aServiceName length] == 0) {
return nil;
}
const char *serviceNameCString = [aServiceName UTF8String];
const char *usernameCString = [aUsername UTF8String];
const char *passwordCString = [aPassword UTF8String];
SecKeychainItemRef item = nil;
OSStatus returnStatus = SecKeychainAddGenericPassword(NULL, strlen(serviceNameCString), serviceNameCString, strlen(usernameCString), usernameCString, strlen(passwordCString), (void *)passwordCString, &item);
if (returnStatus != noErr || !item) {
return nil;
}
return [self genericKeychainItem:item forServiceName:aServiceName username:aUsername password:aPassword];
}
+ (SSGenericKeychainItem *)genericKeychainItemForServiceName:(NSString *)aServiceName withUsername:(NSString *)aUsername {
if (!aUsername || [aUsername length] == 0) {
return nil;
}
const char *serviceNameCString = [aServiceName UTF8String];
const char *usernameCString = [aUsername UTF8String];
UInt32 passwordLength = 0;
char *passwordCString = nil;
SecKeychainItemRef item = nil;
OSStatus returnStatus = SecKeychainFindGenericPassword(NULL, strlen(serviceNameCString), serviceNameCString, strlen(usernameCString), usernameCString, &passwordLength, (void **)&passwordCString, &item);
if (returnStatus != noErr || !item) {
return nil;
}
char buf[1024];
if (passwordLength>1023) passwordLength = 1023; //TODO I'm Lazy!!
memcpy(buf, passwordCString, passwordLength);
buf[passwordLength]=0;
NSString *passwordString = [NSString stringWithCString:buf encoding:NSUTF8StringEncoding];
// NSString *passwordString = [NSString stringWithCString:passwordCString length:passwordLength];
// NSString *passwordString = [NSString stringWithCString:passwordCString encoding:NSUTF8StringEncoding];
SecKeychainItemFreeContent(NULL, passwordCString);
return [self genericKeychainItem:item forServiceName:aServiceName username:aUsername password:passwordString];
}
+ (NSString *)passwordForUsername:(NSString *)aUsername serviceName:(NSString*)aServiceName {
return [[self genericKeychainItemForServiceName:aServiceName withUsername:aUsername] password];
}
+ (void)setPassword:(NSString *)aPassword forUsername:(NSString *)aUsername serviceName:(NSString *)aServiceName {
SSKeychainItem *item = [self genericKeychainItemForServiceName:aServiceName withUsername:aUsername];
if (item == nil) {
[self createGenericKeychainItemForServiceName:aServiceName withUsername:aUsername password:aPassword];
} else {
item.password = aPassword;
}
}
#pragma mark -
#pragma mark NSObject
#pragma mark -
- (void)dealloc {
[serviceName release];
[super dealloc];
}
#pragma mark -
#pragma mark Initializers
#pragma mark -
- (id)initWithCoreKeychainItem:(SecKeychainItemRef)aCoreKeychainItem serviceName:(NSString *)aServiceName username:(NSString *)aUsername password:(NSString *)aPassword {
if ((self = [super initWithCoreKeychainItem:aCoreKeychainItem username:aUsername password:aPassword])) {
self.serviceName = aServiceName;
}
return self;
}
#pragma mark -
#pragma mark Setters
#pragma mark -
- (void)setServiceName:(NSString *)newServiceName {
[self willChangeValueForKey:@"serviceName"];
[serviceName release];
serviceName = [newServiceName copy];
[self didChangeValueForKey:@"serviceName"];
[self _setCoreKeychainItemAttributeWithTag:kSecServiceItemAttr toString:serviceName];
}
@end