# HG changeset patch # User Olaf Wintermann # Date 1540635386 -7200 # Node ID fb69eae42ef0bc57421e26aa2248bb7f9d9c64b9 # Parent 29b979ca8750ab722c1f5afbb61d806f46f036d6 credentials can have multiple locations now diff -r 29b979ca8750 -r fb69eae42ef0 dav/main.c --- 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; } diff -r 29b979ca8750 -r fb69eae42ef0 dav/pwd.c --- 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) { diff -r 29b979ca8750 -r fb69eae42ef0 dav/pwd.h --- 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);