|
@@ -1,228 +0,0 @@
|
|
-#include "osxkeychain_darwin.h"
|
|
|
|
-#include <CoreFoundation/CoreFoundation.h>
|
|
|
|
-#include <Foundation/NSValue.h>
|
|
|
|
-#include <stdio.h>
|
|
|
|
-#include <string.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(struct Server *server, char *label, char *username, char *secret) {
|
|
|
|
- SecKeychainItemRef item;
|
|
|
|
-
|
|
|
|
- OSStatus status = SecKeychainAddInternetPassword(
|
|
|
|
- NULL,
|
|
|
|
- strlen(server->host), server->host,
|
|
|
|
- 0, NULL,
|
|
|
|
- strlen(username), username,
|
|
|
|
- strlen(server->path), server->path,
|
|
|
|
- server->port,
|
|
|
|
- server->proto,
|
|
|
|
- kSecAuthenticationTypeDefault,
|
|
|
|
- strlen(secret), secret,
|
|
|
|
- &item
|
|
|
|
- );
|
|
|
|
-
|
|
|
|
- if (status) {
|
|
|
|
- return get_error(status);
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- SecKeychainAttribute attribute;
|
|
|
|
- SecKeychainAttributeList attrs;
|
|
|
|
- attribute.tag = kSecLabelItemAttr;
|
|
|
|
- attribute.data = label;
|
|
|
|
- attribute.length = strlen(label);
|
|
|
|
- attrs.count = 1;
|
|
|
|
- attrs.attr = &attribute;
|
|
|
|
-
|
|
|
|
- status = SecKeychainItemModifyContent(item, &attrs, 0, NULL);
|
|
|
|
-
|
|
|
|
- if (status) {
|
|
|
|
- return get_error(status);
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- return NULL;
|
|
|
|
-}
|
|
|
|
-
|
|
|
|
-char *keychain_get(struct Server *server, unsigned int *username_l, char **username, unsigned int *secret_l, char **secret) {
|
|
|
|
- char *tmp;
|
|
|
|
- SecKeychainItemRef item;
|
|
|
|
-
|
|
|
|
- OSStatus status = SecKeychainFindInternetPassword(
|
|
|
|
- NULL,
|
|
|
|
- strlen(server->host), server->host,
|
|
|
|
- 0, NULL,
|
|
|
|
- 0, NULL,
|
|
|
|
- strlen(server->path), server->path,
|
|
|
|
- server->port,
|
|
|
|
- server->proto,
|
|
|
|
- kSecAuthenticationTypeDefault,
|
|
|
|
- secret_l, (void **)&tmp,
|
|
|
|
- &item);
|
|
|
|
-
|
|
|
|
- if (status) {
|
|
|
|
- return get_error(status);
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- *secret = strdup(tmp);
|
|
|
|
- SecKeychainItemFreeContent(NULL, tmp);
|
|
|
|
-
|
|
|
|
- SecKeychainAttributeList list;
|
|
|
|
- SecKeychainAttribute attr;
|
|
|
|
-
|
|
|
|
- list.count = 1;
|
|
|
|
- list.attr = &attr;
|
|
|
|
- attr.tag = kSecAccountItemAttr;
|
|
|
|
-
|
|
|
|
- status = SecKeychainItemCopyContent(item, NULL, &list, NULL, NULL);
|
|
|
|
- if (status) {
|
|
|
|
- return get_error(status);
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- *username = strdup(attr.data);
|
|
|
|
- *username_l = attr.length;
|
|
|
|
- SecKeychainItemFreeContent(&list, NULL);
|
|
|
|
-
|
|
|
|
- return NULL;
|
|
|
|
-}
|
|
|
|
-
|
|
|
|
-char *keychain_delete(struct Server *server) {
|
|
|
|
- SecKeychainItemRef item;
|
|
|
|
-
|
|
|
|
- OSStatus status = SecKeychainFindInternetPassword(
|
|
|
|
- NULL,
|
|
|
|
- strlen(server->host), server->host,
|
|
|
|
- 0, NULL,
|
|
|
|
- 0, NULL,
|
|
|
|
- strlen(server->path), server->path,
|
|
|
|
- server->port,
|
|
|
|
- server->proto,
|
|
|
|
- kSecAuthenticationTypeDefault,
|
|
|
|
- 0, NULL,
|
|
|
|
- &item);
|
|
|
|
-
|
|
|
|
- if (status) {
|
|
|
|
- return get_error(status);
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- status = SecKeychainItemDelete(item);
|
|
|
|
- if (status) {
|
|
|
|
- return get_error(status);
|
|
|
|
- }
|
|
|
|
- return NULL;
|
|
|
|
-}
|
|
|
|
-
|
|
|
|
-char * CFStringToCharArr(CFStringRef aString) {
|
|
|
|
- if (aString == NULL) {
|
|
|
|
- return NULL;
|
|
|
|
- }
|
|
|
|
- CFIndex length = CFStringGetLength(aString);
|
|
|
|
- CFIndex maxSize =
|
|
|
|
- CFStringGetMaximumSizeForEncoding(length, kCFStringEncodingUTF8) + 1;
|
|
|
|
- char *buffer = (char *)malloc(maxSize);
|
|
|
|
- if (CFStringGetCString(aString, buffer, maxSize,
|
|
|
|
- kCFStringEncodingUTF8)) {
|
|
|
|
- return buffer;
|
|
|
|
- }
|
|
|
|
- return NULL;
|
|
|
|
-}
|
|
|
|
-
|
|
|
|
-char *keychain_list(char *credsLabel, char *** paths, char *** accts, unsigned int *list_l) {
|
|
|
|
- CFStringRef credsLabelCF = CFStringCreateWithCString(NULL, credsLabel, kCFStringEncodingUTF8);
|
|
|
|
- CFMutableDictionaryRef query = CFDictionaryCreateMutable (NULL, 1, NULL, NULL);
|
|
|
|
- CFDictionaryAddValue(query, kSecClass, kSecClassInternetPassword);
|
|
|
|
- CFDictionaryAddValue(query, kSecReturnAttributes, kCFBooleanTrue);
|
|
|
|
- CFDictionaryAddValue(query, kSecMatchLimit, kSecMatchLimitAll);
|
|
|
|
- CFDictionaryAddValue(query, kSecAttrLabel, credsLabelCF);
|
|
|
|
- //Use this query dictionary
|
|
|
|
- CFTypeRef result= NULL;
|
|
|
|
- OSStatus status = SecItemCopyMatching(
|
|
|
|
- query,
|
|
|
|
- &result);
|
|
|
|
-
|
|
|
|
- CFRelease(credsLabelCF);
|
|
|
|
-
|
|
|
|
- //Ran a search and store the results in result
|
|
|
|
- if (status) {
|
|
|
|
- return get_error(status);
|
|
|
|
- }
|
|
|
|
- CFIndex numKeys = CFArrayGetCount(result);
|
|
|
|
- *paths = (char **) malloc((int)sizeof(char *)*numKeys);
|
|
|
|
- *accts = (char **) malloc((int)sizeof(char *)*numKeys);
|
|
|
|
- //result is of type CFArray
|
|
|
|
- for(CFIndex i=0; i<numKeys; i++) {
|
|
|
|
- CFDictionaryRef currKey = CFArrayGetValueAtIndex(result,i);
|
|
|
|
-
|
|
|
|
- CFStringRef protocolTmp = CFDictionaryGetValue(currKey, CFSTR("ptcl"));
|
|
|
|
- if (protocolTmp != NULL) {
|
|
|
|
- CFStringRef protocolStr = CFStringCreateWithFormat(NULL, NULL, CFSTR("%@"), protocolTmp);
|
|
|
|
- if (CFStringCompare(protocolStr, CFSTR("htps"), 0) == kCFCompareEqualTo) {
|
|
|
|
- protocolTmp = CFSTR("https://");
|
|
|
|
- }
|
|
|
|
- else {
|
|
|
|
- protocolTmp = CFSTR("http://");
|
|
|
|
- }
|
|
|
|
- CFRelease(protocolStr);
|
|
|
|
- }
|
|
|
|
- else {
|
|
|
|
- char * path = "0";
|
|
|
|
- char * acct = "0";
|
|
|
|
- (*paths)[i] = (char *) malloc(sizeof(char)*(strlen(path)));
|
|
|
|
- memcpy((*paths)[i], path, sizeof(char)*(strlen(path)));
|
|
|
|
- (*accts)[i] = (char *) malloc(sizeof(char)*(strlen(acct)));
|
|
|
|
- memcpy((*accts)[i], acct, sizeof(char)*(strlen(acct)));
|
|
|
|
- continue;
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- CFMutableStringRef str = CFStringCreateMutableCopy(NULL, 0, protocolTmp);
|
|
|
|
- CFStringRef serverTmp = CFDictionaryGetValue(currKey, CFSTR("srvr"));
|
|
|
|
- if (serverTmp != NULL) {
|
|
|
|
- CFStringAppend(str, serverTmp);
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- CFStringRef pathTmp = CFDictionaryGetValue(currKey, CFSTR("path"));
|
|
|
|
- if (pathTmp != NULL) {
|
|
|
|
- CFStringAppend(str, pathTmp);
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- const NSNumber * portTmp = CFDictionaryGetValue(currKey, CFSTR("port"));
|
|
|
|
- if (portTmp != NULL && portTmp.integerValue != 0) {
|
|
|
|
- CFStringRef portStr = CFStringCreateWithFormat(NULL, NULL, CFSTR("%@"), portTmp);
|
|
|
|
- CFStringAppend(str, CFSTR(":"));
|
|
|
|
- CFStringAppend(str, portStr);
|
|
|
|
- CFRelease(portStr);
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- CFStringRef acctTmp = CFDictionaryGetValue(currKey, CFSTR("acct"));
|
|
|
|
- if (acctTmp == NULL) {
|
|
|
|
- acctTmp = CFSTR("account not defined");
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- char * path = CFStringToCharArr(str);
|
|
|
|
- char * acct = CFStringToCharArr(acctTmp);
|
|
|
|
-
|
|
|
|
- //We now have all we need, username and servername. Now export this to .go
|
|
|
|
- (*paths)[i] = (char *) malloc(sizeof(char)*(strlen(path)+1));
|
|
|
|
- memcpy((*paths)[i], path, sizeof(char)*(strlen(path)+1));
|
|
|
|
- (*accts)[i] = (char *) malloc(sizeof(char)*(strlen(acct)+1));
|
|
|
|
- memcpy((*accts)[i], acct, sizeof(char)*(strlen(acct)+1));
|
|
|
|
-
|
|
|
|
- CFRelease(str);
|
|
|
|
- }
|
|
|
|
- *list_l = (int)numKeys;
|
|
|
|
- return NULL;
|
|
|
|
-}
|
|
|
|
-
|
|
|
|
-void freeListData(char *** data, unsigned int length) {
|
|
|
|
- for(int i=0; i<length; i++) {
|
|
|
|
- free((*data)[i]);
|
|
|
|
- }
|
|
|
|
- free(*data);
|
|
|
|
-}
|
|
|