-
-
Notifications
You must be signed in to change notification settings - Fork 9
/
Copy pathkeychain_darwin.c
62 lines (57 loc) · 1.64 KB
/
keychain_darwin.c
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
#import <Foundation/Foundation.h>
#import <Security/Security.h>
char *get_error(OSStatus status) {
char *buf = malloc(128);
CFStringRef str = SecCopyErrorMessageString(status, NULL);
int success = CFStringGetCString(str, buf, 128, kCFStringEncodingUTF8);
if (!success) {
strncpy(buf, "Unknown error", 128);
}
return buf;
}
char *keychain_add(char *service, char *account, char *pass) {
OSStatus status = SecKeychainAddGenericPassword(
NULL,
strlen(service), service,
strlen(account), account,
strlen(pass), pass,
NULL
);
if (status) return get_error(status);
return NULL;
}
char *keychain_find(char *service, char *account, unsigned int *length, char **password) {
if (length == NULL || password == NULL) {
return strdup("length == NULL || password == NULL");
}
SecKeychainItemRef item;
char *tmp;
OSStatus status = SecKeychainFindGenericPassword(
NULL,
strlen(service), service,
strlen(account), account,
length, (void **)&tmp,
NULL
);
if (status) {
*length = 0;
return get_error(status);
}
*password = strdup(tmp);
SecKeychainItemFreeContent(NULL, tmp);
return NULL;
}
char *keychain_remove(char *service, char *account) {
SecKeychainItemRef item;
OSStatus status = SecKeychainFindGenericPassword(
NULL,
strlen(service), service,
strlen(account), account,
NULL, NULL,
&item
);
if (status) return get_error(status);
status = SecKeychainItemDelete(item);
if (status) return get_error(status);
return NULL;
}