# HG changeset patch # User Olaf Wintermann # Date 1537683230 -7200 # Node ID 017a4f09e6fac30497fa084f8394e581fd768ef4 # Parent 6740adb5fccdb440c5a38070c257942251b0c36d improves secret store file format diff -r 6740adb5fccd -r 017a4f09e6fa dav/main.c --- 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"); diff -r 6740adb5fccd -r 017a4f09e6fa dav/pwd.c --- 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); diff -r 6740adb5fccd -r 017a4f09e6fa dav/pwd.h --- 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);