1#include <string.h>
2#include <stdlib.h>
3#include "secretservice.h"
4
5const SecretSchema *docker_get_schema(void)
6{
7 static const SecretSchema docker_schema = {
8 "io.docker.Credentials", SECRET_SCHEMA_NONE,
9 {
10 { "label", SECRET_SCHEMA_ATTRIBUTE_STRING },
11 { "server", SECRET_SCHEMA_ATTRIBUTE_STRING },
12 { "username", SECRET_SCHEMA_ATTRIBUTE_STRING },
13 { "docker_cli", SECRET_SCHEMA_ATTRIBUTE_STRING },
14 { "NULL", 0 },
15 }
16 };
17 return &docker_schema;
18}
19
20GError *add(char *label, char *server, char *username, char *secret) {
21 GError *err = NULL;
22
23 secret_password_store_sync (DOCKER_SCHEMA, SECRET_COLLECTION_DEFAULT,
24 server, secret, NULL, &err,
25 "label", label,
26 "server", server,
27 "username", username,
28 "docker_cli", "1",
29 NULL);
30 return err;
31}
32
33GError *delete(char *server) {
34 GError *err = NULL;
35
36 secret_password_clear_sync(DOCKER_SCHEMA, NULL, &err,
37 "server", server,
38 "docker_cli", "1",
39 NULL);
40 if (err != NULL)
41 return err;
42 return NULL;
43}
44
45char *get_attribute(const char *attribute, SecretItem *item) {
46 GHashTable *attributes;
47 GHashTableIter iter;
48 gchar *value, *key;
49
50 attributes = secret_item_get_attributes(item);
51 g_hash_table_iter_init(&iter, attributes);
52 while (g_hash_table_iter_next(&iter, (void **)&key, (void **)&value)) {
53 if (strncmp(key, attribute, strlen(key)) == 0)
54 return (char *)value;
55 }
56 g_hash_table_unref(attributes);
57 return NULL;
58}
59
60GError *get(char *server, char **username, char **secret) {
61 GError *err = NULL;
62 GHashTable *attributes;
63 SecretService *service;
64 GList *items, *l;
65 SecretSearchFlags flags = SECRET_SEARCH_LOAD_SECRETS | SECRET_SEARCH_ALL | SECRET_SEARCH_UNLOCK;
66 SecretValue *secretValue;
67 gsize length;
68 gchar *value;
69
70 attributes = g_hash_table_new_full(g_str_hash, g_str_equal, g_free, g_free);
71 g_hash_table_insert(attributes, g_strdup("server"), g_strdup(server));
72 g_hash_table_insert(attributes, g_strdup("docker_cli"), g_strdup("1"));
73
74 service = secret_service_get_sync(SECRET_SERVICE_NONE, NULL, &err);
75 if (err == NULL) {
76 items = secret_service_search_sync(service, DOCKER_SCHEMA, attributes, flags, NULL, &err);
77 if (err == NULL) {
78 for (l = items; l != NULL; l = g_list_next(l)) {
79 value = secret_item_get_schema_name(l->data);
80 if (strncmp(value, "io.docker.Credentials", strlen(value)) != 0) {
81 g_free(value);
82 continue;
83 }
84 g_free(value);
85 secretValue = secret_item_get_secret(l->data);
86 if (secret != NULL) {
87 *secret = strdup(secret_value_get(secretValue, &length));
88 secret_value_unref(secretValue);
89 }
90 *username = get_attribute("username", l->data);
91 }
92 g_list_free_full(items, g_object_unref);
93 }
94 g_object_unref(service);
95 }
96 g_hash_table_unref(attributes);
97 if (err != NULL) {
98 return err;
99 }
100 return NULL;
101}
102
103GError *list(char *ref_label, char *** paths, char *** accts, unsigned int *list_l) {
104 GList *items;
105 GError *err = NULL;
106 SecretService *service;
107 SecretSearchFlags flags = SECRET_SEARCH_LOAD_SECRETS | SECRET_SEARCH_ALL | SECRET_SEARCH_UNLOCK;
108 GHashTable *attributes = g_hash_table_new_full(g_str_hash, g_str_equal, g_free, g_free);
109
110 // List credentials with the right label only
111 g_hash_table_insert(attributes, g_strdup("label"), g_strdup(ref_label));
112
113 service = secret_service_get_sync(SECRET_SERVICE_NONE, NULL, &err);
114 if (err != NULL) {
115 return err;
116 }
117
118 items = secret_service_search_sync(service, NULL, attributes, flags, NULL, &err);
119 int numKeys = g_list_length(items);
120 if (err != NULL) {
121 return err;
122 }
123
124 char **tmp_paths = (char **) calloc(1,(int)sizeof(char *)*numKeys);
125 char **tmp_accts = (char **) calloc(1,(int)sizeof(char *)*numKeys);
126
127 // items now contains our keys from the gnome keyring
128 // we will now put it in our two lists to return it to go
129 GList *current;
130 int listNumber = 0;
131 for(current = items; current!=NULL; current = current->next) {
132 char *pathTmp = secret_item_get_label(current->data);
133 // you cannot have a key without a label in the gnome keyring
134 char *acctTmp = get_attribute("username",current->data);
135 if (acctTmp==NULL) {
136 acctTmp = "account not defined";
137 }
138
139 tmp_paths[listNumber] = (char *) calloc(1, sizeof(char)*(strlen(pathTmp)+1));
140 tmp_accts[listNumber] = (char *) calloc(1, sizeof(char)*(strlen(acctTmp)+1));
141
142 memcpy(tmp_paths[listNumber], pathTmp, sizeof(char)*(strlen(pathTmp)+1));
143 memcpy(tmp_accts[listNumber], acctTmp, sizeof(char)*(strlen(acctTmp)+1));
144
145 listNumber = listNumber + 1;
146 }
147
148 *paths = (char **) realloc(tmp_paths, (int)sizeof(char *)*listNumber);
149 *accts = (char **) realloc(tmp_accts, (int)sizeof(char *)*listNumber);
150
151 *list_l = listNumber;
152
153 return NULL;
154}
155
156void freeListData(char *** data, unsigned int length) {
157 int i;
158 for(i=0; i<length; i++) {
159 free((*data)[i]);
160 }
161}
View as plain text