credentials can have multiple locations now

Sat, 27 Oct 2018 12:16:26 +0200

author
Olaf Wintermann <olaf.wintermann@gmail.com>
date
Sat, 27 Oct 2018 12:16:26 +0200
changeset 489
fb69eae42ef0
parent 488
29b979ca8750
child 490
d94c4fd35c21

credentials can have multiple locations now

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	Sat Oct 20 13:46:32 2018 +0200
+++ b/dav/main.c	Sat Oct 27 12:16:26 2018 +0200
@@ -466,10 +466,21 @@
     return 0;
 }
 
-static int cmp_url_cred_entry(PwdIndexEntry *e1, PwdIndexEntry *e2, void *n) {
+typedef struct CredLocation {
+    char *id;
+    char *location;
+} CredLocation;
+
+static int cmp_url_cred_entry(CredLocation *e1, CredLocation *e2, void *n) {
     return strcmp(e2->location, e1->location);
 }
 
+static void free_cred_location(CredLocation *c) {
+    // c->id is not a copy, therefore we don't have to free it
+    free(c->location);
+    free(c);
+}
+
 static int get_location_credentials(CmdArgs *a, Repository *repo, char *path, char **user, char **password) {
     PwdStore *secrets = get_pwdstore();
     if(!secrets) {
@@ -483,12 +494,15 @@
     UcxList *locations = NULL;
     UCX_FOREACH(elm, secrets->locations) {
         PwdIndexEntry *e = elm->data;
-        char *path;
-        Repository *r = url2repo(e->location, &path);
-        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);
+        
+        UCX_FOREACH(loc, e->locations) {
+            char *path;
+            Repository *r = url2repo(loc->data, &path);
+            CredLocation *urlentry = calloc(1, sizeof(CredLocation));
+            urlentry->id = e->id;
+            urlentry->location = util_concat_path(r->url, path);
+            locations = ucx_list_append(locations, urlentry);
+        }
     }
     // the list must be sorted
     locations = ucx_list_sort(locations, (cmp_func)cmp_url_cred_entry, NULL);
@@ -507,7 +521,7 @@
     char *id = NULL;
     int ret = 0;
     UCX_FOREACH(elm, locations) {
-        PwdIndexEntry *cred = elm->data;
+        CredLocation *cred = elm->data;
         sstr_t cred_url = sstr(cred->location);
         
         // remove protocol prefix
@@ -533,7 +547,8 @@
     }
     
     free(req_url_proto.ptr);
-    ucx_list_free_content(locations, (ucx_destructor)pwdstore_free_entry);
+    ucx_list_free_content(locations, (ucx_destructor)free_cred_location);
+    ucx_list_free(locations);
     
     return ret;
 }
@@ -2428,9 +2443,10 @@
     char *user = assistant_getcfg("User");
     char *password = util_password_input("Password: ");
     char *location = assistant_getoptcfg("Location");
+    UcxList *locations = location ? ucx_list_append(NULL, location) : NULL;
     int ret = 1;
     if(user && password) {
-        pwdstore_put_index(secrets, id, location);
+        pwdstore_put_index(secrets, id, locations);
         pwdstore_put(secrets, id, user, password);
         int ret = pwdstore_save(secrets);
         if(ret) {
@@ -2443,6 +2459,7 @@
     if(user) free(user);
     if(password) free(password);
     if(location) free(location);
+    if(locations) ucx_list_free(locations);
     
     return ret;
 }
--- a/dav/pwd.c	Sat Oct 20 13:46:32 2018 +0200
+++ b/dav/pwd.c	Sat Oct 27 12:16:26 2018 +0200
@@ -95,7 +95,14 @@
         return 0;
     }
     length = ntohl(length);
-    if((length == 0 && !allowzero) || length > PWDSTORE_MAX_LEN) {
+    if(length == 0) {
+        if(allowzero) {
+            return 1;
+        } else {
+            return 0;
+        }
+    }
+    if(length > PWDSTORE_MAX_LEN) {
         return 0;
     }
     
@@ -110,7 +117,39 @@
     return 1;
 }
 
-static int read_pwdentry(PwdStore *p, UcxBuffer *in, int index) {
+static int read_indexentry(PwdStore *p, UcxBuffer *in) {
+    int type = ucx_buffer_getc(in);
+    if(type == EOF || type != 0) {
+        // only type 0 supported yet
+        return 0;
+    }
+    
+    char *id = NULL;
+    UcxList *locations = NULL;
+    
+    int ret = 0;
+    if(readval(in, &id, FALSE)) {
+        ret = 1;
+        char *location = NULL;
+        while((ret = readval(in, &location, TRUE)) == 1) {
+            if(!location) {
+                break;
+            }
+            locations = ucx_list_append(locations, location);
+        }
+    }
+    
+    if(ret) {
+        pwdstore_put_index(p, id, locations);
+    } else {
+        if(id) free(id);
+        ucx_list_free_content(locations, free);
+    }
+    
+    return ret;
+}
+
+static int read_pwdentry(PwdStore *p, UcxBuffer *in) {
     int type = ucx_buffer_getc(in);
     if(type == EOF || type != 0) {
         // only type 0 supported yet
@@ -122,28 +161,13 @@
     char *user = NULL;
     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);
+    if(readval(in, &id, FALSE)) {
+        if(readval(in, &user, FALSE)) {
+            if(readval(in, &password, FALSE)) {
+                pwdstore_put(p, id, user, password);
                 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) {
-                    res += readval(in, &password, FALSE);
-                }
-            }
         }
     }
     
@@ -153,7 +177,6 @@
     if(password) free(password);
     
     return ret;
-    
 }
 
 int pwdstore_getindex(PwdStore *s) {
@@ -173,7 +196,7 @@
     
     UcxBuffer *index = ucx_buffer_new(s->content->space+PWDS_HEADER_SIZE, indexlen, 0);
     index->size = indexlen;
-    while(read_pwdentry(s, index, 1)) {}
+    while(read_indexentry(s, index)) {}
     
     ucx_buffer_free(index);
     
@@ -199,7 +222,7 @@
         return 1;
     }
     
-    while(read_pwdentry(p, content, 0)) {}
+    while(read_pwdentry(p, content)) {}
     
     ucx_buffer_free(content);
     
@@ -267,18 +290,18 @@
     ucx_map_cstr_put(p->ids, id, entry);
 }
 
-void pwdstore_put_index(PwdStore *p, const char *id, const char *location) {
+void pwdstore_put_index(PwdStore *p, char *id, UcxList *locations) {
     PwdIndexEntry *e = ucx_map_cstr_get(p->index, id);
     if(e) {
         return;
     }
     PwdIndexEntry *newentry = malloc(sizeof(PwdIndexEntry));
-    newentry->id = strdup(id);
-    if(location) {
-        newentry->location = strdup(location);
+    newentry->id = id;
+    if(locations) {
+        newentry->locations = locations;
         p->locations = ucx_list_append(p->locations, newentry);
     } else {
-        newentry->location = NULL;
+        newentry->locations = NULL;
         p->noloc = ucx_list_append(p->noloc, newentry);
     }
     ucx_map_cstr_put(p->index, id, newentry);
@@ -286,18 +309,24 @@
 
 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);
+    
+    UCX_FOREACH(elm, e->locations) {
+        char *location = elm->data;
+        uint32_t locationlen = strlen(location);
+        uint32_t netlocationlen = htonl(locationlen);
+        
+        ucx_buffer_write(&netlocationlen, 1, sizeof(uint32_t), out);
+        ucx_buffer_write(location, 1, locationlen, out);
     }
+    
+    uint32_t terminate = 0;
+    ucx_buffer_write(&terminate, 1, sizeof(uint32_t), out);
 }
 
 int pwdstore_store(PwdStore *p, const char *file) {
--- a/dav/pwd.h	Sat Oct 20 13:46:32 2018 +0200
+++ b/dav/pwd.h	Sat Oct 27 12:16:26 2018 +0200
@@ -53,12 +53,13 @@
  * pwfunc = 1 byte
  * salt = 16 bytes
  * indexlen = uint32
- * index = { length id length location }
+ * index = { length id locations zero }
  * content = { entry }
  * entry = length id length username length password
  * length = uint32
+ * zero = 4 zero bytes
  * id = string
- * location = string
+ * locations = { length string }
  * username = string
  * password = string
  * 
@@ -136,7 +137,7 @@
 
 struct PwdIndexEntry {
     char *id;
-    char *location;
+    UcxList *locations;
 };
 
 /*
@@ -165,7 +166,7 @@
 PwdEntry* pwdstore_get(PwdStore *p, const char *id);
 
 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);
+void pwdstore_put_index(PwdStore *p, char *id, UcxList *locations);
 
 int pwdstore_store(PwdStore *p, const char *file);
 

mercurial