diff options
author | Matthew Heon <matthew.heon@gmail.com> | 2017-11-01 11:24:59 -0400 |
---|---|---|
committer | Matthew Heon <matthew.heon@gmail.com> | 2017-11-01 11:24:59 -0400 |
commit | a031b83a09a8628435317a03f199cdc18b78262f (patch) | |
tree | bc017a96769ce6de33745b8b0b1304ccf38e9df0 /vendor/github.com/docker/docker-credential-helpers/osxkeychain/osxkeychain_darwin.c | |
parent | 2b74391cd5281f6fdf391ff8ad50fd1490f6bf89 (diff) | |
download | podman-a031b83a09a8628435317a03f199cdc18b78262f.tar.gz podman-a031b83a09a8628435317a03f199cdc18b78262f.tar.bz2 podman-a031b83a09a8628435317a03f199cdc18b78262f.zip |
Initial checkin from CRI-O repo
Signed-off-by: Matthew Heon <matthew.heon@gmail.com>
Diffstat (limited to 'vendor/github.com/docker/docker-credential-helpers/osxkeychain/osxkeychain_darwin.c')
-rw-r--r-- | vendor/github.com/docker/docker-credential-helpers/osxkeychain/osxkeychain_darwin.c | 228 |
1 files changed, 228 insertions, 0 deletions
diff --git a/vendor/github.com/docker/docker-credential-helpers/osxkeychain/osxkeychain_darwin.c b/vendor/github.com/docker/docker-credential-helpers/osxkeychain/osxkeychain_darwin.c new file mode 100644 index 000000000..f84d61ee5 --- /dev/null +++ b/vendor/github.com/docker/docker-credential-helpers/osxkeychain/osxkeychain_darwin.c @@ -0,0 +1,228 @@ +#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); +} |