1
0
mirror of https://github.com/docker/docker-credential-helpers.git synced 2026-06-14 16:31:45 +05:30

Full implementation for OSX ready

Signed-off-by: avaid96 <avaid1996@gmail.com>
This commit is contained in:
avaid96
2016-07-11 10:50:44 -07:00
parent 5128fa1bad
commit 5a8fb214ed
7 changed files with 170 additions and 3 deletions
+77
View File
@@ -1,4 +1,7 @@
#include "osxkeychain_darwin.h"
#include <CoreFoundation/CoreFoundation.h>
#include <stdio.h>
#include <string.h>
char *get_error(OSStatus status) {
char *buf = malloc(128);
@@ -96,3 +99,77 @@ char *keychain_delete(struct Server *server) {
}
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 *** paths, char *** accts, unsigned int *list_l) {
CFMutableDictionaryRef query = CFDictionaryCreateMutable (NULL, 1, NULL, NULL);
CFDictionaryAddValue(query, kSecClass, kSecClassInternetPassword);
CFDictionaryAddValue(query, kSecReturnAttributes, kCFBooleanTrue);
CFDictionaryAddValue(query, kSecMatchLimit, kSecMatchLimitAll);
//Use this query dictionary
CFTypeRef result= NULL;
OSStatus status = SecItemCopyMatching(
query,
&result);
//Ran a search and store the results in result
if (status) {
return get_error(status);
}
int numKeys = CFArrayGetCount(result);
*paths = (char **) malloc((int)sizeof(char *)*numKeys);
*accts = (char **) malloc((int)sizeof(char *)*numKeys);
//result is of type CFArray
for(int i=0; i<numKeys; i++) {
CFDictionaryRef currKey = CFArrayGetValueAtIndex(result,i);
if (CFDictionaryContainsKey(currKey, CFSTR("path"))) {
//Even if a key is stored without an account, Apple defaults it to null so these arrays will be of the same length
CFStringRef pathTmp = CFDictionaryGetValue(currKey, CFSTR("path"));
CFStringRef acctTmp = CFDictionaryGetValue(currKey, CFSTR("acct"));
if (acctTmp == NULL) {
acctTmp = CFSTR("<unknown>");
}
char * path = (char *) malloc(CFStringGetLength(pathTmp)+1);
path = CFStringToCharArr(pathTmp);
path[strlen(path)] = '\0';
char * acct = (char *) malloc(CFStringGetLength(acctTmp)+1); //<- problem line in 38th iteration
acct = CFStringToCharArr(acctTmp);
acct[strlen(acct)] = '\0';
//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));
}
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)));
}
}
*list_l = numKeys;
return NULL;
}
void freeListData(char *** data, unsigned int length) {
for(int i=0; i<length; i++) {
free((*data)[i]);
}
free(*data);
}