dav/pwd.c

changeset 472
08d2d1263429
parent 470
6bf798ad3aec
child 473
6740adb5fccd
equal deleted inserted replaced
471:d8e883bd1fd8 472:08d2d1263429
52 ucx_buffer_free(buf); 52 ucx_buffer_free(buf);
53 return NULL; 53 return NULL;
54 } 54 }
55 55
56 PwdStore *p = malloc(sizeof(PwdStore)); 56 PwdStore *p = malloc(sizeof(PwdStore));
57 p->pwds = ucx_map_new(16); 57 p->ids = ucx_map_new(16);
58 p->locations = NULL;
58 p->content = buf; 59 p->content = buf;
59 p->key = NULL; 60 p->key = NULL;
61 p->encoffset = PWDS_HEADER_SIZE;
60 p->isdecrypted = 0; 62 p->isdecrypted = 0;
63
64 if(pwdstore_getindex(p)) {
65 pwdstore_free(p);
66 return NULL;
67 }
61 68
62 return p; 69 return p;
63 } 70 }
64 71
65 PwdStore* pwdstore_new(void) { 72 PwdStore* pwdstore_new(void) {
66 PwdStore *p = calloc(1, sizeof(PwdStore)); 73 PwdStore *p = calloc(1, sizeof(PwdStore));
67 p->pwds = ucx_map_new(16); 74 p->ids = ucx_map_new(16);
68 p->content = ucx_buffer_new(NULL, PWDS_HEADER_SIZE, UCX_BUFFER_AUTOEXTEND); 75 p->content = ucx_buffer_new(NULL, PWDS_HEADER_SIZE, UCX_BUFFER_AUTOEXTEND);
69 PWDS_MAGIC(p) = PWDS_MAGIC_CHAR; 76 PWDS_MAGIC(p) = PWDS_MAGIC_CHAR;
70 PWDS_VERSION(p) = 1; 77 PWDS_VERSION(p) = 1;
71 PWDS_ENC(p) = DAV_KEY_AES256; 78 PWDS_ENC(p) = DAV_KEY_AES256;
72 PWDS_PWFUNC(p) = DAV_PWFUNC_PBKDF2_SHA256; 79 PWDS_PWFUNC(p) = DAV_PWFUNC_PBKDF2_SHA256;
73 dav_rand_bytes(p->content->space+4, 16); 80 dav_rand_bytes(p->content->space+4, 16);
74 return p; 81 return p;
75 } 82 }
76 83
77 static int read_pwdentry(PwdStore *p, UcxBuffer *in) { 84 static int readval(UcxBuffer *in, char **val, int allowzero) {
85 *val = NULL;
86 uint32_t length = 0;
87 if(ucx_buffer_read(&length, 1, sizeof(uint32_t), in) != sizeof(uint32_t)) {
88 return 0;
89 }
90 length = ntohl(length);
91 if((length == 0 && !allowzero) || length > PWDSTORE_MAX_LEN) {
92 return 0;
93 }
94
95 char *value = malloc(length + 1);
96 value[length] = 0;
97 if(ucx_buffer_read(value, 1, length, in) != length) {
98 free(value);
99 return 0;
100 }
101
102 *val = value;
103 return 1;
104 }
105
106 static int read_pwdentry(PwdStore *p, UcxBuffer *in, int index) {
78 int type = ucx_buffer_getc(in); 107 int type = ucx_buffer_getc(in);
79 if(type == EOF || type != 0) { 108 if(type == EOF || type != 0) {
80 // only type 0 supported yet 109 // only type 0 supported yet
81 return 0; 110 return 0;
82 } 111 }
83 112
84 uint32_t ulen = 0; 113 char *id = NULL;
85 uint32_t plen = 0; 114 char *location = NULL;
86 115 char *user = NULL;
87 if(ucx_buffer_read(&ulen, 1, sizeof(uint32_t), in) != sizeof(uint32_t)) { 116 char *password = NULL;
88 return 0; 117
89 } 118 int res = 0;
90 ulen = ntohl(ulen); 119 if((res += readval(in, &id, FALSE)) == 1) {
91 if(ulen == 0 || ulen > PWDSTORE_MAX_LEN) { 120 if((res += readval(in, &location, TRUE)) == 2) {
92 return 0; 121 if((res += readval(in, &user, FALSE)) == 3) {
93 } 122 res += readval(in, &password, FALSE);
94 123 }
95 char *user = malloc(ulen+1); 124 }
96 user[ulen] = 0; 125 }
97 if(ucx_buffer_read(user, 1, ulen, in) != ulen) { 126
98 free(user); 127 int ret = 0;
99 return 0; 128 if((!index && res == 4) || (index && res == 2)) {
100 } 129 pwdstore_put(p, id, location, user, password);
101 130 ret = 1;
102 if(ucx_buffer_read(&plen, 1, sizeof(uint32_t), in) != sizeof(uint32_t)) { 131 }
103 return 0; 132
104 } 133 if(id) free(id);
105 plen = ntohl(plen); 134 if(location) free(location);
106 if(plen == 0 || plen > PWDSTORE_MAX_LEN) { 135 if(user) free(user);
107 return 0; 136 if(password) free(password);
108 } 137
109 char *password = malloc(plen+1); 138 return ret;
110 password[plen] = 0; 139
111 if(ucx_buffer_read(password, 1, plen, in) != plen) { 140 }
112 free(user); 141
113 free(password); 142 int pwdstore_getindex(PwdStore *s) {
114 return 0; 143 uint32_t netindexlen;
115 } 144 s->content->pos = PWDS_HEADER_SIZE - sizeof(uint32_t);
116 145 if(ucx_buffer_read(&netindexlen, 1, sizeof(uint32_t), s->content) != sizeof(uint32_t)) {
117 pwdstore_put(p, user, password); 146 return 1;
118 free(user); 147 }
119 free(password); 148 uint32_t indexlen = ntohl(netindexlen);
120 return 1; 149 if(UINT32_MAX - PWDS_HEADER_SIZE < indexlen) {
121 150 return 1;
151 }
152 if(s->content->size < PWDS_HEADER_SIZE + indexlen) {
153 return 1;
154 }
155 s->encoffset += indexlen;
156
157 UcxBuffer *index = ucx_buffer_new(s->content->space+PWDS_HEADER_SIZE, indexlen, 0);
158 index->size = indexlen;
159 while(read_pwdentry(s, index, 1)) {}
160
161 ucx_buffer_free(index);
162
163 return 0;
122 } 164 }
123 165
124 int pwdstore_decrypt(PwdStore *p) { 166 int pwdstore_decrypt(PwdStore *p) {
125 if(!p->key) { 167 if(!p->key) {
126 return 1; 168 return 1;
127 } 169 }
128 170
129 // decrypt contet 171 // decrypt contet
130 size_t encsz = p->content->size - PWDS_HEADER_SIZE; 172 size_t encsz = p->content->size - p->encoffset;
131 UcxBuffer *enc = ucx_buffer_new(p->content->space + PWDS_HEADER_SIZE, encsz, 0); 173 UcxBuffer *enc = ucx_buffer_new(p->content->space + p->encoffset, encsz, 0);
132 enc->size = encsz; 174 enc->size = encsz;
133 enc->size = p->content->size - PWDS_HEADER_SIZE; 175 enc->size = p->content->size - p->encoffset;
134 UcxBuffer *content = aes_decrypt_buffer(enc, p->key); 176 UcxBuffer *content = aes_decrypt_buffer(enc, p->key);
135 ucx_buffer_free(enc); 177 ucx_buffer_free(enc);
136 if(!content) { 178 if(!content) {
137 return 1; 179 return 1;
138 } 180 }
139 181
140 while(read_pwdentry(p, content)) {} 182 while(read_pwdentry(p, content, 0)) {}
141 183
142 ucx_buffer_free(content); 184 ucx_buffer_free(content);
143 185
144 return 0; 186 return 0;
145 } 187 }
163 PWDS_ENC(p) = enc; 205 PWDS_ENC(p) = enc;
164 PWDS_PWFUNC(p) = pwfunc; 206 PWDS_PWFUNC(p) = pwfunc;
165 } 207 }
166 208
167 static void free_entry(PwdEntry *e) { 209 static void free_entry(PwdEntry *e) {
168 free(e->user); 210 if(e->id) free(e->id);
169 free(e->password); 211 if(e->location) free(e->location);
212 if(e->user) free(e->user);
213 if(e->password) free(e->password);
170 free(e); 214 free(e);
171 } 215 }
172 216
173 void pwdstore_free(PwdStore* p) { 217 void pwdstore_free(PwdStore* p) {
174 ucx_map_free_content(p->pwds, (ucx_destructor)free_entry); 218 ucx_map_free_content(p->ids, (ucx_destructor)free_entry);
175 ucx_map_free(p->pwds); 219 ucx_map_free(p->ids);
220
221 ucx_list_free(p->locations);
176 222
177 if(p->content) { 223 if(p->content) {
178 ucx_buffer_free(p->content); 224 ucx_buffer_free(p->content);
179 } 225 }
180 226
181 free(p); 227 free(p);
182 } 228 }
183 229
184 PwdEntry* pwdstore_get(PwdStore *p, const char *username) { 230 int pwdstore_has_id(PwdStore *s, const char *id) {
185 return ucx_map_cstr_get(p->pwds, username); 231 return ucx_map_cstr_get(s->ids, id) ? 1 : 0;
186 } 232 }
187 233
188 void pwdstore_put(PwdStore *p, const char *username, const char *password) { 234 int pwdstore_has_location(PwdStore *s, const char *location) {
235 return 0;
236 }
237
238 PwdEntry* pwdstore_get(PwdStore *p, const char *id) {
239 PwdEntry *e = ucx_map_cstr_get(p->ids, id);
240 if(e->user && e->password) {
241 return e;
242 } else {
243 return NULL;
244 }
245 }
246
247 void pwdstore_put(PwdStore *p, const char *id, const char *location, const char *username, const char *password) {
189 PwdEntry *entry = malloc(sizeof(PwdEntry)); 248 PwdEntry *entry = malloc(sizeof(PwdEntry));
190 entry->user = strdup(username); 249 entry->id = strdup(id);
191 entry->password = strdup(password); 250 entry->location = location ? strdup(location) : NULL;
192 ucx_map_cstr_put(p->pwds, entry->user, entry); 251 entry->user = username ? strdup(username) : NULL;
252 entry->password = password ? strdup(password) : NULL;
253 ucx_map_cstr_put(p->ids, id, entry);
254
255 if(location) {
256 p->locations = ucx_list_append(p->locations, entry);
257 }
193 } 258 }
194 259
195 int pwdstore_store(PwdStore *p, const char *file) { 260 int pwdstore_store(PwdStore *p, const char *file) {
196 if(!p->key) { 261 if(!p->key) {
197 return 1; 262 return 1;
198 } 263 }
199 264
265 UcxBuffer *index = ucx_buffer_new(NULL, 2048, UCX_BUFFER_AUTOEXTEND);
200 UcxBuffer *content = ucx_buffer_new(NULL, 2048, UCX_BUFFER_AUTOEXTEND); 266 UcxBuffer *content = ucx_buffer_new(NULL, 2048, UCX_BUFFER_AUTOEXTEND);
201 267
202 UcxMapIterator i = ucx_map_iterator(p->pwds); 268 UcxMapIterator i = ucx_map_iterator(p->ids);
203 PwdEntry *value; 269 PwdEntry *value;
204 UCX_MAP_FOREACH(key, value, i) { 270 UCX_MAP_FOREACH(key, value, i) {
205 ucx_buffer_putc(content, 0); // type 271 uint32_t idlen = strlen(value->id);
272 uint32_t locationlen = value->location ? strlen(value->location) : 0;
206 uint32_t ulen = strlen(value->user); 273 uint32_t ulen = strlen(value->user);
207 uint32_t plen = strlen(value->password); 274 uint32_t plen = strlen(value->password);
275 uint32_t netidlen = htonl(idlen);
276 uint32_t netlocationlen = htonl(locationlen);
208 uint32_t netulen = htonl(ulen); 277 uint32_t netulen = htonl(ulen);
209 uint32_t netplen = htonl(plen); 278 uint32_t netplen = htonl(plen);
279
280 // index buffer
281 ucx_buffer_putc(index, 0); // type
282
283 ucx_buffer_write(&netidlen, 1, sizeof(uint32_t), index);
284 ucx_buffer_write(value->id, 1, idlen, index);
285 ucx_buffer_write(&netlocationlen, 1, sizeof(uint32_t), index);
286 if(value->location) {
287 ucx_buffer_write(value->location, 1, locationlen, index);
288 }
289
290 // content buffer
291 ucx_buffer_putc(content, 0); // type
292
293 ucx_buffer_write(&netidlen, 1, sizeof(uint32_t), content);
294 ucx_buffer_write(value->id, 1, idlen, content);
295 ucx_buffer_write(&netlocationlen, 1, sizeof(uint32_t), content);
296 if(value->location) {
297 ucx_buffer_write(value->location, 1, locationlen, content);
298 }
210 ucx_buffer_write(&netulen, 1, sizeof(uint32_t), content); 299 ucx_buffer_write(&netulen, 1, sizeof(uint32_t), content);
211 ucx_buffer_write(value->user, 1, ulen, content); 300 ucx_buffer_write(value->user, 1, ulen, content);
212 ucx_buffer_write(&netplen, 1, sizeof(uint32_t), content); 301 ucx_buffer_write(&netplen, 1, sizeof(uint32_t), content);
213 ucx_buffer_write(value->password, 1, plen, content); 302 ucx_buffer_write(value->password, 1, plen, content);
214 } 303 }
215 304
216 content->pos = 0; 305 content->pos = 0;
217 UcxBuffer *enc = aes_encrypt_buffer(content, p->key); 306 UcxBuffer *enc = aes_encrypt_buffer(content, p->key);
218 307
219 p->content->pos = PWDS_HEADER_SIZE; 308 p->content->pos = PWDS_HEADER_SIZE - sizeof(uint32_t);
220 p->content->size = PWDS_HEADER_SIZE; 309 p->content->size = PWDS_HEADER_SIZE;
310
311 // add index after header
312 uint32_t netindexlen = htonl((uint32_t)index->size);
313 ucx_buffer_write(&netindexlen, 1, sizeof(uint32_t), p->content);
314 ucx_buffer_write(index->space, 1, index->size, p->content);
315
316 // add encrypted buffer
221 ucx_buffer_write(enc->space, 1, enc->size, p->content); 317 ucx_buffer_write(enc->space, 1, enc->size, p->content);
222 318
223 ucx_buffer_free(enc); 319 ucx_buffer_free(enc);
224 320
225 FILE *out = fopen(file, "w"); 321 FILE *out = fopen(file, "w");

mercurial