From 72661b31038ed4e34ebf5d65ac0b18cad96e5a8b Mon Sep 17 00:00:00 2001 From: Avi Vaid Date: Mon, 11 Jul 2016 19:33:35 -0400 Subject: [PATCH] Implemented list functionality for secretservice- linux Signed-off-by: Avi Vaid --- osxkeychain/osxkeychain_darwin.c | 4 +-- secretservice/secretservice_linux.c | 41 +++++++++++++++++++++++ secretservice/secretservice_linux.go | 23 +++++++++++++ secretservice/secretservice_linux.h | 1 + secretservice/secretservice_linux_test.go | 3 ++ 5 files changed, 70 insertions(+), 2 deletions(-) diff --git a/osxkeychain/osxkeychain_darwin.c b/osxkeychain/osxkeychain_darwin.c index 2b4d8d8..6c0240a 100644 --- a/osxkeychain/osxkeychain_darwin.c +++ b/osxkeychain/osxkeychain_darwin.c @@ -140,7 +140,7 @@ char *keychain_list(char *** paths, char *** accts, unsigned int *list_l) { CFStringRef pathTmp = CFDictionaryGetValue(currKey, CFSTR("path")); CFStringRef acctTmp = CFDictionaryGetValue(currKey, CFSTR("acct")); if (acctTmp == NULL) { - acctTmp = CFSTR(""); + acctTmp = CFSTR("account not defined"); } char * path = (char *) malloc(CFStringGetLength(pathTmp)+1); path = CFStringToCharArr(pathTmp); @@ -172,4 +172,4 @@ void freeListData(char *** data, unsigned int length) { free((*data)[i]); } free(*data); -} \ No newline at end of file +} diff --git a/secretservice/secretservice_linux.c b/secretservice/secretservice_linux.c index 13950d3..d713814 100644 --- a/secretservice/secretservice_linux.c +++ b/secretservice/secretservice_linux.c @@ -96,3 +96,44 @@ GError *get(char *server, char **username, char **secret) { } return NULL; } + +GError *list(char *** paths, char *** accts, unsigned int *list_l) { + GList *items; + GError *err = NULL; + SecretService *service; + SecretSearchFlags flags = SECRET_SEARCH_LOAD_SECRETS | SECRET_SEARCH_ALL | SECRET_SEARCH_UNLOCK; + GHashTable *attributes; + g_hash_table_new_full(g_str_hash, g_str_equal, g_free, g_free); + attributes = g_hash_table_new_full(g_str_hash, g_str_equal, g_free, g_free); + service = secret_service_get_sync(SECRET_SERVICE_NONE, NULL, &err); + items = secret_service_search_sync(service, NULL, attributes, flags, NULL, &err); + int numKeys = g_list_length(items); + if (err != NULL) { + return err; + } + *paths = (char **) malloc((int)sizeof(char *)*numKeys); + *accts = (char **) malloc((int)sizeof(char *)*numKeys); + // items now contains our keys from the gnome keyring + // we will now put it in our two lists to return it to go + GList *current; + int listNumber = 0; + for(current = items; current!=NULL; current = current->next) { + char *pathTmp = secret_item_get_label(current->data); + // you cannot have a key without a label in the gnome keyring + char *acctTmp = get_username(current->data); + if (acctTmp==NULL) { + acctTmp = "account not defined"; + } + char *path = (char *) malloc(strlen(pathTmp)); + char *acct = (char *) malloc(strlen(acctTmp)); + path = pathTmp; + acct = acctTmp; + (*paths)[listNumber] = (char *) malloc(sizeof(char)*(strlen(path))); + memcpy((*paths)[listNumber], path, sizeof(char)*(strlen(path))); + (*accts)[listNumber] = (char *) malloc(sizeof(char)*(strlen(acct))); + memcpy((*accts)[listNumber], acct, sizeof(char)*(strlen(acct))); + listNumber = listNumber + 1; + } + *list_l = numKeys; + return NULL; +} diff --git a/secretservice/secretservice_linux.go b/secretservice/secretservice_linux.go index dcd682e..45ab1f5 100644 --- a/secretservice/secretservice_linux.go +++ b/secretservice/secretservice_linux.go @@ -78,3 +78,26 @@ func (h Secretservice) Get(serverURL string) (string, string, error) { } return user, pass, nil } + +func (h Secretservice) List() ([]string, []string, error) { + var pathsC **C.char + defer C.free(unsafe.Pointer(pathsC)) + var acctsC **C.char + defer C.free(unsafe.Pointer(acctsC)) + var listLenC C.uint + err := C.list(&pathsC, &acctsC, &listLenC) + if err != nil { + defer C.free(unsafe.Pointer(err)) + return nil, nil, errors.New("Error from list function in secretservice_linux.c likely due to error in secretservice library") + } + listLen := int(listLenC) + pathTmp := (*[1 << 30]*C.char)(unsafe.Pointer(pathsC))[:listLen:listLen] + acctTmp := (*[1 << 30]*C.char)(unsafe.Pointer(acctsC))[:listLen:listLen] + paths := make([]string, listLen) + accts := make([]string, listLen) + for i := 0; i < listLen; i++ { + paths[i] = C.GoString(pathTmp[i]) + accts[i] = C.GoString(acctTmp[i]) + } + return paths, accts, nil +} diff --git a/secretservice/secretservice_linux.h b/secretservice/secretservice_linux.h index 5e09bed..3635246 100644 --- a/secretservice/secretservice_linux.h +++ b/secretservice/secretservice_linux.h @@ -9,3 +9,4 @@ const SecretSchema *docker_get_schema(void) G_GNUC_CONST; GError *add(char *server, char *username, char *secret); GError *delete(char *server); GError *get(char *server, char **username, char **secret); +GError *list(char *** paths, char *** accts, unsigned int *list_l); diff --git a/secretservice/secretservice_linux_test.go b/secretservice/secretservice_linux_test.go index e6a1664..98c2669 100644 --- a/secretservice/secretservice_linux_test.go +++ b/secretservice/secretservice_linux_test.go @@ -36,6 +36,9 @@ func TestSecretServiceHelper(t *testing.T) { if err := helper.Delete(creds.ServerURL); err != nil { t.Fatal(err) } + if _, _, err := helper.List(); err != nil { + t.Fatal(err) + } } func TestMissingCredentials(t *testing.T) {