| 62 FILE *in = fopen(file, "r"); |
62 FILE *in = fopen(file, "r"); |
| 63 if(!in) { |
63 if(!in) { |
| 64 return NULL; |
64 return NULL; |
| 65 } |
65 } |
| 66 |
66 |
| 67 CxBuffer *buf = cxBufferCreate(NULL, 2048, cxDefaultAllocator, CX_BUFFER_FREE_CONTENTS|CX_BUFFER_AUTO_EXTEND); |
67 CxBuffer *buf = cxBufferCreate(cxDefaultAllocator, NULL, 2048, CX_BUFFER_FREE_CONTENTS|CX_BUFFER_AUTO_EXTEND); |
| 68 cx_stream_copy(in, buf, (cx_read_func)fread, (cx_write_func)cxBufferWrite); |
68 cx_stream_copy(in, buf, (cx_read_func)fread, (cx_write_func)cxBufferWrite); |
| 69 fclose(in); |
69 fclose(in); |
| 70 |
70 |
| 71 if(buf->size < PWDS_HEADER_SIZE || buf->space[0] != PWDS_MAGIC_CHAR) { |
71 if(buf->size < PWDS_HEADER_SIZE || buf->space[0] != PWDS_MAGIC_CHAR) { |
| 72 cxBufferFree(buf); |
72 cxBufferFree(buf); |
| 73 return NULL; |
73 return NULL; |
| 74 } |
74 } |
| 75 |
75 |
| 76 PwdStore *p = malloc(sizeof(PwdStore)); |
76 PwdStore *p = malloc(sizeof(PwdStore)); |
| 77 p->ids = cxHashMapCreate(cxDefaultAllocator, CX_STORE_POINTERS, 16); |
77 p->ids = cxHashMapCreate(cxDefaultAllocator, CX_STORE_POINTERS, 16); |
| 78 p->locations = cxLinkedListCreateSimple(CX_STORE_POINTERS); |
78 p->locations = cxLinkedListCreate(NULL, CX_STORE_POINTERS); |
| 79 p->noloc = cxLinkedListCreateSimple(CX_STORE_POINTERS); |
79 p->noloc = cxLinkedListCreate(NULL, CX_STORE_POINTERS); |
| 80 p->index = cxHashMapCreate(cxDefaultAllocator, CX_STORE_POINTERS, 16); |
80 p->index = cxHashMapCreate(cxDefaultAllocator, CX_STORE_POINTERS, 16); |
| 81 p->content = buf; |
81 p->content = buf; |
| 82 p->key = NULL; |
82 p->key = NULL; |
| 83 p->unlock_cmd = NULL; |
83 p->unlock_cmd = NULL; |
| 84 p->lock_cmd = NULL; |
84 p->lock_cmd = NULL; |
| 94 } |
94 } |
| 95 |
95 |
| 96 PwdStore* pwdstore_new(void) { |
96 PwdStore* pwdstore_new(void) { |
| 97 PwdStore *p = calloc(1, sizeof(PwdStore)); |
97 PwdStore *p = calloc(1, sizeof(PwdStore)); |
| 98 p->ids = cxHashMapCreate(cxDefaultAllocator, CX_STORE_POINTERS, 16); |
98 p->ids = cxHashMapCreate(cxDefaultAllocator, CX_STORE_POINTERS, 16); |
| 99 p->locations = cxLinkedListCreateSimple(CX_STORE_POINTERS); |
99 p->locations = cxLinkedListCreate(NULL, CX_STORE_POINTERS); |
| 100 p->noloc = cxLinkedListCreateSimple(CX_STORE_POINTERS); |
100 p->noloc = cxLinkedListCreate(NULL, CX_STORE_POINTERS); |
| 101 p->index = cxHashMapCreate(cxDefaultAllocator, CX_STORE_POINTERS, 16); |
101 p->index = cxHashMapCreate(cxDefaultAllocator, CX_STORE_POINTERS, 16); |
| 102 p->content = cxBufferCreate(NULL, PWDS_HEADER_SIZE, cxDefaultAllocator, CX_BUFFER_FREE_CONTENTS|CX_BUFFER_AUTO_EXTEND); |
102 p->content = cxBufferCreate(cxDefaultAllocator, NULL, PWDS_HEADER_SIZE, CX_BUFFER_FREE_CONTENTS|CX_BUFFER_AUTO_EXTEND); |
| 103 PWDS_MAGIC(p) = PWDS_MAGIC_CHAR; |
103 PWDS_MAGIC(p) = PWDS_MAGIC_CHAR; |
| 104 PWDS_VERSION(p) = 1; |
104 PWDS_VERSION(p) = 1; |
| 105 PWDS_ENC(p) = DAV_KEY_AES256; |
105 PWDS_ENC(p) = DAV_KEY_AES256; |
| 106 PWDS_PWFUNC(p) = DAV_PWFUNC_PBKDF2_SHA256; |
106 PWDS_PWFUNC(p) = DAV_PWFUNC_PBKDF2_SHA256; |
| 107 dav_rand_bytes((unsigned char*)p->content->space+4, 16); |
107 dav_rand_bytes((unsigned char*)p->content->space+4, 16); |
| 126 key->name = NULL; |
126 key->name = NULL; |
| 127 } |
127 } |
| 128 |
128 |
| 129 PwdStore *newp = calloc(1, sizeof(PwdStore)); |
129 PwdStore *newp = calloc(1, sizeof(PwdStore)); |
| 130 newp->ids = cxHashMapCreate(cxDefaultAllocator, CX_STORE_POINTERS, 16); |
130 newp->ids = cxHashMapCreate(cxDefaultAllocator, CX_STORE_POINTERS, 16); |
| 131 newp->locations = cxLinkedListCreateSimple(CX_STORE_POINTERS); |
131 newp->locations = cxLinkedListCreate(NULL, CX_STORE_POINTERS); |
| 132 newp->noloc = cxLinkedListCreateSimple(CX_STORE_POINTERS); |
132 newp->noloc = cxLinkedListCreate(NULL, CX_STORE_POINTERS); |
| 133 newp->index = cxHashMapCreate(cxDefaultAllocator, CX_STORE_POINTERS, 16); |
133 newp->index = cxHashMapCreate(cxDefaultAllocator, CX_STORE_POINTERS, 16); |
| 134 newp->content = newbuffer; |
134 newp->content = newbuffer; |
| 135 newp->key = key; |
135 newp->key = key; |
| 136 newp->unlock_cmd = p->unlock_cmd ? strdup(p->unlock_cmd) : NULL; |
136 newp->unlock_cmd = p->unlock_cmd ? strdup(p->unlock_cmd) : NULL; |
| 137 newp->lock_cmd = p->lock_cmd ? strdup(p->lock_cmd) : NULL; |
137 newp->lock_cmd = p->lock_cmd ? strdup(p->lock_cmd) : NULL; |
| 147 i = cxMapIterator(p->index); |
147 i = cxMapIterator(p->index); |
| 148 cx_foreach(CxMapEntry *, e, i) { |
148 cx_foreach(CxMapEntry *, e, i) { |
| 149 PwdIndexEntry *entry = e->value; |
149 PwdIndexEntry *entry = e->value; |
| 150 CxList *locations = NULL; |
150 CxList *locations = NULL; |
| 151 if(entry->locations) { |
151 if(entry->locations) { |
| 152 locations = cxLinkedListCreateSimple(CX_STORE_POINTERS); |
152 locations = cxLinkedListCreate(NULL, CX_STORE_POINTERS); |
| 153 CxIterator li = cxListIterator(entry->locations); |
153 CxIterator li = cxListIterator(entry->locations); |
| 154 cx_foreach(char *, location, li) { |
154 cx_foreach(char *, location, li) { |
| 155 cxListAdd(locations, strdup(location)); |
155 cxListAdd(locations, strdup(location)); |
| 156 } |
156 } |
| 157 } |
157 } |
| 204 // only type 0 supported yet |
204 // only type 0 supported yet |
| 205 return 0; |
205 return 0; |
| 206 } |
206 } |
| 207 |
207 |
| 208 char *id = NULL; |
208 char *id = NULL; |
| 209 CxList *locations = cxLinkedListCreateSimple(CX_STORE_POINTERS); |
209 CxList *locations = cxLinkedListCreate(NULL, CX_STORE_POINTERS); |
| 210 cxDefineDestructor(locations, free); |
210 cxSetDestructor(locations, free); |
| 211 |
211 |
| 212 // get id (required) |
212 // get id (required) |
| 213 int ret = 0; |
213 int ret = 0; |
| 214 if(readval(in, &id, FALSE)) { |
214 if(readval(in, &id, FALSE)) { |
| 215 // get locations |
215 // get locations |
| 328 } |
328 } |
| 329 // encrypted content starts after the index content |
329 // encrypted content starts after the index content |
| 330 s->encoffset = PWDS_HEADER_SIZE + indexlen; |
330 s->encoffset = PWDS_HEADER_SIZE + indexlen; |
| 331 |
331 |
| 332 // the index starts after the header |
332 // the index starts after the header |
| 333 CxBuffer *index = cxBufferCreate(s->content->space+PWDS_HEADER_SIZE, indexlen, cxDefaultAllocator, 0); |
333 CxBuffer *index = cxBufferCreate(cxDefaultAllocator, s->content->space+PWDS_HEADER_SIZE, indexlen, 0); |
| 334 index->size = indexlen; |
334 index->size = indexlen; |
| 335 |
335 |
| 336 // read index |
336 // read index |
| 337 while(read_indexentry(s, index)) {} |
337 while(read_indexentry(s, index)) {} |
| 338 |
338 |
| 350 return 0; |
350 return 0; |
| 351 } |
351 } |
| 352 |
352 |
| 353 // decrypt contet |
353 // decrypt contet |
| 354 size_t encsz = p->content->size - p->encoffset; |
354 size_t encsz = p->content->size - p->encoffset; |
| 355 CxBuffer *enc = cxBufferCreate(p->content->space + p->encoffset, encsz, cxDefaultAllocator, 0); |
355 CxBuffer *enc = cxBufferCreate(cxDefaultAllocator, p->content->space + p->encoffset, encsz, 0); |
| 356 enc->size = encsz; |
356 enc->size = encsz; |
| 357 enc->size = p->content->size - p->encoffset; |
357 enc->size = p->content->size - p->encoffset; |
| 358 CxBuffer *content = aes_decrypt_buffer(enc, p->key); |
358 CxBuffer *content = aes_decrypt_buffer(enc, p->key); |
| 359 cxBufferFree(enc); |
359 cxBufferFree(enc); |
| 360 if(!content) { |
360 if(!content) { |
| 475 int pwdstore_store(PwdStore *p, const char *file) { |
475 int pwdstore_store(PwdStore *p, const char *file) { |
| 476 if(!p->key) { |
476 if(!p->key) { |
| 477 return 1; |
477 return 1; |
| 478 } |
478 } |
| 479 |
479 |
| 480 CxBuffer *index = cxBufferCreate(NULL, 2048, cxDefaultAllocator, CX_BUFFER_FREE_CONTENTS|CX_BUFFER_AUTO_EXTEND); |
480 CxBuffer *index = cxBufferCreate(cxDefaultAllocator, NULL, 2048, CX_BUFFER_FREE_CONTENTS|CX_BUFFER_AUTO_EXTEND); |
| 481 CxBuffer *content = cxBufferCreate(NULL, 2048, cxDefaultAllocator, CX_BUFFER_FREE_CONTENTS|CX_BUFFER_AUTO_EXTEND); |
481 CxBuffer *content = cxBufferCreate(cxDefaultAllocator, NULL, 2048, CX_BUFFER_FREE_CONTENTS|CX_BUFFER_AUTO_EXTEND); |
| 482 |
482 |
| 483 // create index |
483 // create index |
| 484 CxIterator i = cxListIterator(p->noloc); |
484 CxIterator i = cxListIterator(p->noloc); |
| 485 cx_foreach(PwdIndexEntry*, e, i) { |
485 cx_foreach(PwdIndexEntry*, e, i) { |
| 486 write_index_entry(index, e); |
486 write_index_entry(index, e); |
| 545 return 1; |
545 return 1; |
| 546 } |
546 } |
| 547 |
547 |
| 548 char *ps_password = NULL; |
548 char *ps_password = NULL; |
| 549 if(secrets->unlock_cmd && strlen(secrets->unlock_cmd) > 0) { |
549 if(secrets->unlock_cmd && strlen(secrets->unlock_cmd) > 0) { |
| 550 CxBuffer *cmd_out = cxBufferCreate(NULL, 128, cxDefaultAllocator, CX_BUFFER_FREE_CONTENTS|CX_BUFFER_AUTO_EXTEND); |
550 CxBuffer *cmd_out = cxBufferCreate(cxDefaultAllocator, NULL, 128, CX_BUFFER_FREE_CONTENTS|CX_BUFFER_AUTO_EXTEND); |
| 551 if(!util_exec_command(secrets->unlock_cmd, cmd_out)) { |
551 if(!util_exec_command(secrets->unlock_cmd, cmd_out)) { |
| 552 // command successful, get first line from output without newline |
552 // command successful, get first line from output without newline |
| 553 // and use that as password for the secretstore |
553 // and use that as password for the secretstore |
| 554 size_t len = 0; |
554 size_t len = 0; |
| 555 for(size_t i=0;i<=cmd_out->size;i++) { |
555 for(size_t i=0;i<=cmd_out->size;i++) { |