improves secret store file format

Sun, 23 Sep 2018 08:13:50 +0200

author
Olaf Wintermann <olaf.wintermann@gmail.com>
date
Sun, 23 Sep 2018 08:13:50 +0200
changeset 474
017a4f09e6fa
parent 473
6740adb5fccd
child 475
52e4171d42ce

improves secret store file format

dav/main.c file | annotate | diff | comparison | revisions
dav/pwd.c file | annotate | diff | comparison | revisions
dav/pwd.h file | annotate | diff | comparison | revisions
--- a/dav/main.c	Thu Sep 20 17:14:55 2018 +0200
+++ b/dav/main.c	Sun Sep 23 08:13:50 2018 +0200
@@ -455,7 +455,7 @@
     return 0;
 }
 
-static int cmp_url_cred_entry(PwdEntry *e1, PwdEntry *e2, void *n) {
+static int cmp_url_cred_entry(PwdIndexEntry *e1, PwdIndexEntry *e2, void *n) {
     return strcmp(e2->location, e1->location);
 }
 
@@ -471,10 +471,10 @@
      */
     UcxList *locations = NULL;
     UCX_FOREACH(elm, secrets->locations) {
-        PwdEntry *e = elm->data;
+        PwdIndexEntry *e = elm->data;
         char *path;
         Repository *r = url2repo(e->location, &path);
-        PwdEntry *urlentry = calloc(1, sizeof(PwdEntry));
+        PwdIndexEntry *urlentry = calloc(1, sizeof(PwdEntry));
         urlentry->id = strdup(e->id);
         urlentry->location = util_concat_path(r->url, path);
         locations = ucx_list_append(locations, urlentry);
@@ -496,7 +496,7 @@
     char *id = NULL;
     int ret = 0;
     UCX_FOREACH(elm, locations) {
-        PwdEntry *cred = elm->data;
+        PwdIndexEntry *cred = elm->data;
         sstr_t cred_url = sstr(cred->location);
         
         // remove protocol prefix
@@ -2198,7 +2198,8 @@
     char *location = assistant_getoptcfg("Location");
     int ret = 1;
     if(user && password) {
-        pwdstore_put(secrets, id, location, user, password);
+        pwdstore_put_index(secrets, id, location);
+        pwdstore_put(secrets, id, user, password);
         int ret = pwdstore_save(secrets);
         if(ret) {
             fprintf(stderr, "Error: saving srcrets store failed.\n");
--- a/dav/pwd.c	Thu Sep 20 17:14:55 2018 +0200
+++ b/dav/pwd.c	Sun Sep 23 08:13:50 2018 +0200
@@ -56,6 +56,8 @@
     PwdStore *p = malloc(sizeof(PwdStore));
     p->ids = ucx_map_new(16);
     p->locations = NULL;
+    p->noloc = NULL;
+    p->index = ucx_map_new(16);
     p->content = buf;
     p->key = NULL;
     p->encoffset = PWDS_HEADER_SIZE;
@@ -72,6 +74,9 @@
 PwdStore* pwdstore_new(void) {
     PwdStore *p = calloc(1, sizeof(PwdStore));
     p->ids = ucx_map_new(16);
+    p->locations = NULL;
+    p->noloc = NULL;
+    p->index = ucx_map_new(16);
     p->content = ucx_buffer_new(NULL, PWDS_HEADER_SIZE, UCX_BUFFER_AUTOEXTEND);
     PWDS_MAGIC(p) = PWDS_MAGIC_CHAR;
     PWDS_VERSION(p) = 1;
@@ -118,7 +123,21 @@
     char *password = NULL;
     
     int res = 0;
+    int ret = 0;
     if((res += readval(in, &id, FALSE)) == 1) {
+        if(index) {
+            if((res += readval(in, &location, TRUE)) == 2) {
+                pwdstore_put_index(p, id, location);
+                ret = 1;
+            }
+        } else {
+            if((res += readval(in, &user, FALSE)) == 2) {
+                if((res += readval(in, &password, FALSE)) == 3) {
+                    pwdstore_put(p, id, user, password);
+                    ret = 1;
+                }
+            }
+        }
         if((res += readval(in, &location, TRUE)) == 2) {
             if(!index) {
                 if((res += readval(in, &user, FALSE)) == 3) {
@@ -128,12 +147,6 @@
         }
     }
     
-    int ret = 0;
-    if((!index && res == 4) || (index && res == 2)) {
-        pwdstore_put(p, id, location, user, password);
-        ret = 1;
-    }
-    
     if(id) free(id);
     if(location) free(location);
     if(user) free(user);
@@ -215,7 +228,6 @@
 
 void pwdstore_free_entry(PwdEntry *e) {
     if(e->id) free(e->id);
-    if(e->location) free(e->location);
     if(e->user) free(e->user);
     if(e->password) free(e->password);
     free(e);
@@ -235,11 +247,7 @@
 }
 
 int pwdstore_has_id(PwdStore *s, const char *id) {
-    return ucx_map_cstr_get(s->ids, id) ? 1 : 0;
-}
-
-int pwdstore_has_location(PwdStore *s, const char *location) {
-    return 0;
+    return ucx_map_cstr_get(s->index, id) ? 1 : 0;
 }
 
 PwdEntry* pwdstore_get(PwdStore *p, const char *id) {
@@ -251,16 +259,44 @@
     }
 }
 
-void pwdstore_put(PwdStore *p, const char *id, const char *location, const char *username, const char *password) {
+void pwdstore_put(PwdStore *p, const char *id, const char *username, const char *password) {
     PwdEntry *entry = malloc(sizeof(PwdEntry));
     entry->id = strdup(id);
-    entry->location = location ? strdup(location) : NULL;
-    entry->user = username ? strdup(username) : NULL;
-    entry->password = password ? strdup(password) : NULL;
+    entry->user = strdup(username);
+    entry->password = strdup(password);
     ucx_map_cstr_put(p->ids, id, entry);
-    
+}
+
+void pwdstore_put_index(PwdStore *p, const char *id, const char *location) {
+    PwdIndexEntry *e = ucx_map_cstr_get(p->index, id);
+    if(e) {
+        return;
+    }
+    PwdIndexEntry *newentry = malloc(sizeof(PwdIndexEntry));
+    newentry->id = strdup(id);
     if(location) {
-        p->locations = ucx_list_append(p->locations, entry);
+        newentry->location = strdup(location);
+        p->locations = ucx_list_append(p->locations, newentry);
+    } else {
+        newentry->location = NULL;
+        p->noloc = ucx_list_append(p->noloc, newentry);
+    }
+    ucx_map_cstr_put(p->index, id, newentry);
+}
+
+void write_index_entry(UcxBuffer *out, PwdIndexEntry *e) {
+    uint32_t idlen = strlen(e->id);
+    uint32_t locationlen = e->location ? strlen(e->location) : 0;
+    uint32_t netidlen = htonl(idlen);
+    uint32_t netlocationlen = htonl(locationlen);
+    
+    ucx_buffer_putc(out, 0); // type
+
+    ucx_buffer_write(&netidlen, 1, sizeof(uint32_t), out);
+    ucx_buffer_write(e->id, 1, idlen, out);
+    ucx_buffer_write(&netlocationlen, 1, sizeof(uint32_t), out);
+    if(e->location) {
+        ucx_buffer_write(e->location, 1, locationlen, out);
     }
 }
 
@@ -272,6 +308,16 @@
     UcxBuffer *index = ucx_buffer_new(NULL, 2048, UCX_BUFFER_AUTOEXTEND);
     UcxBuffer *content = ucx_buffer_new(NULL, 2048, UCX_BUFFER_AUTOEXTEND);
     
+    // create index
+    UCX_FOREACH(elm, p->noloc) {
+        PwdIndexEntry *e = elm->data;
+        write_index_entry(index, e);
+    }
+    UCX_FOREACH(elm, p->locations) {
+        PwdIndexEntry *e = elm->data;
+        write_index_entry(index, e);
+    }
+    
     UcxMapIterator i = ucx_map_iterator(p->ids);
     PwdEntry *value;
     UCX_MAP_FOREACH(key, value, i) {
@@ -280,33 +326,17 @@
         }
         
         uint32_t idlen = strlen(value->id);
-        uint32_t locationlen = value->location ? strlen(value->location) : 0;
         uint32_t ulen = strlen(value->user);
         uint32_t plen = strlen(value->password);
         uint32_t netidlen = htonl(idlen);
-        uint32_t netlocationlen = htonl(locationlen);
         uint32_t netulen = htonl(ulen);
         uint32_t netplen = htonl(plen);
         
-        // index buffer
-        ucx_buffer_putc(index, 0); // type
-        
-        ucx_buffer_write(&netidlen, 1, sizeof(uint32_t), index);
-        ucx_buffer_write(value->id, 1, idlen, index);
-        ucx_buffer_write(&netlocationlen, 1, sizeof(uint32_t), index);
-        if(value->location) {
-            ucx_buffer_write(value->location, 1, locationlen, index);
-        }
-        
         // content buffer
         ucx_buffer_putc(content, 0); // type
         
         ucx_buffer_write(&netidlen, 1, sizeof(uint32_t), content);
         ucx_buffer_write(value->id, 1, idlen, content);
-        ucx_buffer_write(&netlocationlen, 1, sizeof(uint32_t), content);
-        if(value->location) {
-            ucx_buffer_write(value->location, 1, locationlen, content);
-        }
         ucx_buffer_write(&netulen, 1, sizeof(uint32_t), content);
         ucx_buffer_write(value->user, 1, ulen, content);
         ucx_buffer_write(&netplen, 1, sizeof(uint32_t), content);
--- a/dav/pwd.h	Thu Sep 20 17:14:55 2018 +0200
+++ b/dav/pwd.h	Sun Sep 23 08:13:50 2018 +0200
@@ -45,7 +45,7 @@
 /*
  * File Format:
  * 
- * file = header, enc_content
+ * file = header, index, enc_content
  * header = magic, version, enc, pwfunc, salt, indexlen
  * magic = 1 byte
  * version = 1 byte
@@ -53,8 +53,9 @@
  * pwfunc = 1 byte
  * salt = 16 bytes
  * indexlen = uint32
+ * index = { length id length location }
  * content = { entry }
- * entry = length id length location length username length password
+ * entry = length id length username length password
  * length = uint32
  * id = string
  * location = string
@@ -69,8 +70,9 @@
     
 #define PWDS_HEADER_SIZE 24
     
-typedef struct PwdStore PwdStore;
-typedef struct PwdEntry PwdEntry;
+typedef struct PwdStore        PwdStore;
+typedef struct PwdEntry        PwdEntry;
+typedef struct PwdIndexEntry   PwdIndexEntry;
 
 struct PwdStore {
     /*
@@ -82,11 +84,23 @@
     
     /*
      * list of all credentials with location
-     * value is PwdEntry*
+     * value is PwdIndexEntry*
      */
     UcxList *locations;
     
     /*
+     * list of all credentials without location
+     * value is PwdIndexEntry*
+     */
+    UcxList *noloc;
+    
+    /*
+     * index map that contains all elements from the lists
+     * 'locations' and 'noloc'
+     */
+    UcxMap *index;
+    
+    /*
      * a buffer containing the complete file content
      */
     UcxBuffer *content;
@@ -116,11 +130,15 @@
 
 struct PwdEntry {
     char *id;
-    char *location;
     char *user;
     char *password;
 };
 
+struct PwdIndexEntry {
+    char *id;
+    char *location;
+};
+
 /*
  * opens the password store
  * the content is still encrypted and must be decrypted using pwdstore_decrypt
@@ -146,7 +164,8 @@
 
 PwdEntry* pwdstore_get(PwdStore *p, const char *id);
 
-void pwdstore_put(PwdStore *p, const char *id, const char *location, const char *username, const char *password);
+void pwdstore_put(PwdStore *p, const char *id, const char *username, const char *password);
+void pwdstore_put_index(PwdStore *p, const char *id, const char *location);
 
 int pwdstore_store(PwdStore *p, const char *file);
 

mercurial