Changeset 537d9b9 for storage_xml.c
- Timestamp:
- 2016-11-20T08:40:36Z (8 years ago)
- Children:
- 3f44e43
- Parents:
- ba52ac5 (diff), 9f03c47 (diff)
Note: this is a merge changeset, the changes displayed below correspond to the merge itself.
Use the(diff)
links above to see all the changes relative to each parent. - File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
storage_xml.c
rba52ac5 r537d9b9 34 34 35 35 typedef enum { 36 XML_PASS_CHECK_ONLY = -1, 37 XML_PASS_UNKNOWN = 0, 38 XML_PASS_WRONG, 39 XML_PASS_OK 40 } xml_pass_st; 36 XML_PASS_CHECK = 0, 37 XML_LOAD 38 } xml_action; 41 39 42 40 /* To make it easier later when extending the format: */ … … 65 63 { 66 64 struct xt_node *c; 65 struct set *s; 67 66 68 67 for (c = node->children; (c = xt_find_node(c, "setting")); c = c->next) { 69 68 char *name = xt_find_attr(c, "name"); 69 char *locked = xt_find_attr(c, "locked"); 70 70 71 71 if (!name) { … … 80 80 } 81 81 set_setstr(head, name, c->text); 82 if (locked && !g_strcasecmp(locked, "true")) { 83 s = set_find(head, name); 84 if (s) { 85 s->flags |= SET_LOCKED; 86 } 87 } 82 88 } 83 89 } … … 105 111 { 106 112 struct xml_parsedata *xd = data; 107 char *protocol, *handle, *server, *password = NULL, *autoconnect, *tag ;113 char *protocol, *handle, *server, *password = NULL, *autoconnect, *tag, *locked; 108 114 char *pass_b64 = NULL; 109 115 unsigned char *pass_cr = NULL; … … 118 124 autoconnect = xt_find_attr(node, "autoconnect"); 119 125 tag = xt_find_attr(node, "tag"); 126 locked = xt_find_attr(node, "locked"); 120 127 121 128 protocol = xt_find_attr(node, "protocol"); … … 130 137 if (!handle || !pass_b64 || !protocol || !prpl) { 131 138 return XT_ABORT; 132 } else if ((pass_len = base64_decode(pass_b64, (unsigned char **) &pass_cr)) && 133 arc_decode(pass_cr, pass_len, &password, xd->given_pass) >= 0) { 134 acc = account_add(xd->irc->b, prpl, handle, password); 135 if (server) { 136 set_setstr(&acc->set, "server", server); 137 } 138 if (autoconnect) { 139 set_setstr(&acc->set, "auto_connect", autoconnect); 140 } 141 if (tag) { 142 set_setstr(&acc->set, "tag", tag); 143 } 144 if (prpl == &protocol_missing) { 145 set_t *s = set_add(&acc->set, "_protocol_name", protocol, NULL, NULL); 146 s->flags |= SET_HIDDEN | SET_NOSAVE | 147 ACC_SET_OFFLINE_ONLY | ACC_SET_ONLINE_ONLY; 148 } 139 } 140 141 pass_len = base64_decode(pass_b64, (unsigned char **) &pass_cr); 142 if (xd->irc->auth_backend) { 143 password = g_strdup((char *)pass_cr); 149 144 } else { 150 g_free(pass_cr); 151 g_free(password); 152 return XT_ABORT; 145 pass_len = arc_decode(pass_cr, pass_len, &password, xd->given_pass); 146 if (pass_len < 0) { 147 g_free(pass_cr); 148 g_free(password); 149 return XT_ABORT; 150 } 151 } 152 153 acc = account_add(xd->irc->b, prpl, handle, password); 154 if (server) { 155 set_setstr(&acc->set, "server", server); 156 } 157 if (autoconnect) { 158 set_setstr(&acc->set, "auto_connect", autoconnect); 159 } 160 if (tag) { 161 set_setstr(&acc->set, "tag", tag); 162 } 163 if (locked && !g_strcasecmp(locked, "true")) { 164 acc->flags |= ACC_FLAG_LOCKED; 165 } 166 if (prpl == &protocol_missing) { 167 set_t *s = set_add(&acc->set, "_protocol_name", protocol, NULL, NULL); 168 s->flags |= SET_HIDDEN | SET_NOSAVE | 169 ACC_SET_OFFLINE_ONLY | ACC_SET_ONLINE_ONLY; 153 170 } 154 171 … … 210 227 }; 211 228 212 static storage_status_t xml_load_real(irc_t *irc, const char *my_nick, const char *password, xml_ pass_staction)229 static storage_status_t xml_load_real(irc_t *irc, const char *my_nick, const char *password, xml_action action) 213 230 { 214 231 struct xml_parsedata xd[1]; … … 252 269 } 253 270 254 {271 if (action == XML_PASS_CHECK) { 255 272 char *nick = xt_find_attr(node, "nick"); 256 273 char *pass = xt_find_attr(node, "password"); 257 258 if (!nick || !pass) { 274 char *backend = xt_find_attr(node, "auth_backend"); 275 276 if (!nick || !(pass || backend)) { 259 277 goto error; 278 } 279 280 if (backend) { 281 g_free(xd->irc->auth_backend); 282 xd->irc->auth_backend = g_strdup(backend); 283 ret = STORAGE_CHECK_BACKEND; 260 284 } else if ((st = md5_verify_password(xd->given_pass, pass)) != 0) { 261 285 ret = STORAGE_INVALID_PASSWORD; 262 goto error; 263 } 264 } 265 266 if (action == XML_PASS_CHECK_ONLY) { 267 ret = STORAGE_OK; 268 goto error; 269 } 270 271 /* DO NOT call xt_handle() before verifying the password! */ 286 } else { 287 ret = STORAGE_OK; 288 } 289 goto error; 290 } 291 272 292 if (xt_handle(xp, NULL, 1) == XT_HANDLED) { 273 293 ret = STORAGE_OK; … … 284 304 static storage_status_t xml_load(irc_t *irc, const char *password) 285 305 { 286 return xml_load_real(irc, irc->user->nick, password, XML_ PASS_UNKNOWN);287 } 288 289 static storage_status_t xml_check_pass( const char *my_nick, const char *password)290 { 291 return xml_load_real( NULL, my_nick, password, XML_PASS_CHECK_ONLY);306 return xml_load_real(irc, irc->user->nick, password, XML_LOAD); 307 } 308 309 static storage_status_t xml_check_pass(irc_t *irc, const char *my_nick, const char *password) 310 { 311 return xml_load_real(irc, my_nick, password, XML_PASS_CHECK); 292 312 } 293 313 … … 304 324 struct xt_node *root, *cur; 305 325 306 /* Generate a salted md5sum of the password. Use 5 bytes for the salt307 (to prevent dictionary lookups of passwords) to end up with a 21-308 byte password hash, more convenient for base64 encoding. */309 random_bytes(pass_md5 + 16, 5);310 md5_init(&md5_state);311 md5_append(&md5_state, (md5_byte_t *) irc->password, strlen(irc->password));312 md5_append(&md5_state, pass_md5 + 16, 5); /* Add the salt. */313 md5_finish(&md5_state, pass_md5);314 /* Save the hash in base64-encoded form. */315 pass_buf = base64_encode(pass_md5, 21);316 317 326 root = cur = xt_new_node("user", NULL, NULL); 327 if (irc->auth_backend) { 328 xt_add_attr(cur, "auth_backend", irc->auth_backend); 329 } else { 330 /* Generate a salted md5sum of the password. Use 5 bytes for the salt 331 (to prevent dictionary lookups of passwords) to end up with a 21- 332 byte password hash, more convenient for base64 encoding. */ 333 random_bytes(pass_md5 + 16, 5); 334 md5_init(&md5_state); 335 md5_append(&md5_state, (md5_byte_t *) irc->password, strlen(irc->password)); 336 md5_append(&md5_state, pass_md5 + 16, 5); /* Add the salt. */ 337 md5_finish(&md5_state, pass_md5); 338 /* Save the hash in base64-encoded form. */ 339 pass_buf = base64_encode(pass_md5, 21); 340 xt_add_attr(cur, "password", pass_buf); 341 g_free(pass_buf); 342 } 343 318 344 xt_add_attr(cur, "nick", irc->user->nick); 319 xt_add_attr(cur, "password", pass_buf);320 345 xt_add_attr(cur, "version", XML_FORMAT_VERSION); 321 322 g_free(pass_buf);323 346 324 347 xml_generate_settings(cur, &irc->b->set); … … 331 354 int pass_len; 332 355 333 pass_len = arc_encode(acc->pass, strlen(acc->pass), (unsigned char **) &pass_cr, irc->password, 12); 334 pass_b64 = base64_encode(pass_cr, pass_len); 335 g_free(pass_cr); 356 if(irc->auth_backend) { 357 /* If we don't "own" the password, it may change without us 358 * knowing, so we cannot encrypt the data, as we then may not be 359 * able to decrypt it */ 360 pass_b64 = base64_encode((unsigned char *)acc->pass, strlen(acc->pass)); 361 } else { 362 pass_len = arc_encode(acc->pass, strlen(acc->pass), (unsigned char **) &pass_cr, irc->password, 12); 363 pass_b64 = base64_encode(pass_cr, pass_len); 364 g_free(pass_cr); 365 } 336 366 337 367 cur = xt_new_node("account", NULL, NULL); … … 348 378 xt_add_attr(cur, "server", acc->server); 349 379 } 380 if (acc->flags & ACC_FLAG_LOCKED) { 381 xt_add_attr(cur, "locked", "true"); 382 } 350 383 351 384 g_free(pass_b64); … … 392 425 xt_add_child(cur, xset = xt_new_node("setting", set->value, NULL)); 393 426 xt_add_attr(xset, "name", set->key); 427 if (set->flags & SET_LOCKED) { 428 xt_add_attr(xset, "locked", "true"); 429 } 394 430 } 395 431 } … … 450 486 451 487 452 static storage_status_t xml_remove(const char *nick , const char *password)488 static storage_status_t xml_remove(const char *nick) 453 489 { 454 490 char s[512], *lc; 455 storage_status_t status;456 457 status = xml_check_pass(nick, password);458 if (status != STORAGE_OK) {459 return status;460 }461 491 462 492 lc = g_strdup(nick);
Note: See TracChangeset
for help on using the changeset viewer.