secretservice_linux.c 4.7 KB

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