Changes in storage_xml.c [d628339:64b4263]
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
storage_xml.c
rd628339 r64b4263 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 } 83 } 84 85 /* Use for unsupported/not-found protocols. Save settings as-is but don't allow changes. */ 86 static void handle_settings_raw(struct xt_node *node, set_t **head) 87 { 88 struct xt_node *c; 89 90 for (c = node->children; (c = xt_find_node(c, "setting")); c = c->next) { 91 char *name = xt_find_attr(c, "name"); 92 93 if (!name) { 94 continue; 95 } 96 97 set_t *s = set_add(head, name, NULL, NULL, NULL); 98 set_setstr(head, name, c->text); 99 s->flags |= SET_HIDDEN | 100 ACC_SET_OFFLINE_ONLY | ACC_SET_ONLINE_ONLY; 82 if (locked && !g_strcasecmp(locked, "true")) { 83 s = set_find(head, name); 84 if (s) { 85 s->flags |= SET_LOCKED; 86 } 87 } 101 88 } 102 89 } … … 105 92 { 106 93 struct xml_parsedata *xd = data; 107 char *protocol, *handle, *server, *password = NULL, *autoconnect, *tag ;94 char *protocol, *handle, *server, *password = NULL, *autoconnect, *tag, *locked; 108 95 char *pass_b64 = NULL; 109 96 unsigned char *pass_cr = NULL; 110 int pass_len ;97 int pass_len, local = 0; 111 98 struct prpl *prpl = NULL; 112 99 account_t *acc; … … 118 105 autoconnect = xt_find_attr(node, "autoconnect"); 119 106 tag = xt_find_attr(node, "tag"); 107 locked = xt_find_attr(node, "locked"); 120 108 121 109 protocol = xt_find_attr(node, "protocol"); … … 123 111 prpl = find_protocol(protocol); 124 112 if (!prpl) { 125 irc_rootmsg(xd->irc, "Warning: Protocol not found: `%s'", protocol); 126 prpl = (struct prpl*) &protocol_missing; 127 } 113 irc_rootmsg(xd->irc, "Error loading user config: Protocol not found: `%s'", protocol); 114 return XT_ABORT; 115 } 116 local = protocol_account_islocal(protocol); 128 117 } 129 118 130 119 if (!handle || !pass_b64 || !protocol || !prpl) { 131 120 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 } 121 } 122 123 pass_len = base64_decode(pass_b64, (unsigned char **) &pass_cr); 124 if (xd->irc->auth_backend) { 125 password = g_strdup((char *)pass_cr); 149 126 } else { 150 g_free(pass_cr); 151 g_free(password); 152 return XT_ABORT; 127 pass_len = arc_decode(pass_cr, pass_len, &password, xd->given_pass); 128 if (pass_len < 0) { 129 g_free(pass_cr); 130 g_free(password); 131 return XT_ABORT; 132 } 133 } 134 135 acc = account_add(xd->irc->b, prpl, handle, password); 136 if (server) { 137 set_setstr(&acc->set, "server", server); 138 } 139 if (autoconnect) { 140 set_setstr(&acc->set, "auto_connect", autoconnect); 141 } 142 if (tag) { 143 set_setstr(&acc->set, "tag", tag); 144 } 145 if (local) { 146 acc->flags |= ACC_FLAG_LOCAL; 147 } 148 if (locked && !g_strcasecmp(locked, "true")) { 149 acc->flags |= ACC_FLAG_LOCKED; 153 150 } 154 151 … … 156 153 g_free(password); 157 154 158 if (prpl == &protocol_missing) { 159 handle_settings_raw(node, &acc->set); 160 } else { 161 handle_settings(node, &acc->set); 162 } 155 handle_settings(node, &acc->set); 163 156 164 157 for (c = node->children; (c = xt_find_node(c, "buddy")); c = c->next) { … … 210 203 }; 211 204 212 static storage_status_t xml_load_real(irc_t *irc, const char *my_nick, const char *password, xml_ pass_staction)205 static storage_status_t xml_load_real(irc_t *irc, const char *my_nick, const char *password, xml_action action) 213 206 { 214 207 struct xml_parsedata xd[1]; … … 252 245 } 253 246 254 {247 if (action == XML_PASS_CHECK) { 255 248 char *nick = xt_find_attr(node, "nick"); 256 249 char *pass = xt_find_attr(node, "password"); 257 258 if (!nick || !pass) { 250 char *backend = xt_find_attr(node, "auth_backend"); 251 252 if (!nick || !(pass || backend)) { 259 253 goto error; 254 } 255 256 if (backend) { 257 g_free(xd->irc->auth_backend); 258 xd->irc->auth_backend = g_strdup(backend); 259 ret = STORAGE_CHECK_BACKEND; 260 260 } else if ((st = md5_verify_password(xd->given_pass, pass)) != 0) { 261 261 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! */ 262 } else { 263 ret = STORAGE_OK; 264 } 265 goto error; 266 } 267 272 268 if (xt_handle(xp, NULL, 1) == XT_HANDLED) { 273 269 ret = STORAGE_OK; … … 284 280 static storage_status_t xml_load(irc_t *irc, const char *password) 285 281 { 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);282 return xml_load_real(irc, irc->user->nick, password, XML_LOAD); 283 } 284 285 static storage_status_t xml_check_pass(irc_t *irc, const char *my_nick, const char *password) 286 { 287 return xml_load_real(irc, my_nick, password, XML_PASS_CHECK); 292 288 } 293 289 … … 304 300 struct xt_node *root, *cur; 305 301 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 302 root = cur = xt_new_node("user", NULL, NULL); 303 if (irc->auth_backend) { 304 xt_add_attr(cur, "auth_backend", irc->auth_backend); 305 } else { 306 /* Generate a salted md5sum of the password. Use 5 bytes for the salt 307 (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 xt_add_attr(cur, "password", pass_buf); 317 g_free(pass_buf); 318 } 319 318 320 xt_add_attr(cur, "nick", irc->user->nick); 319 xt_add_attr(cur, "password", pass_buf);320 321 xt_add_attr(cur, "version", XML_FORMAT_VERSION); 321 322 g_free(pass_buf);323 322 324 323 xml_generate_settings(cur, &irc->b->set); … … 331 330 int pass_len; 332 331 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); 332 if(irc->auth_backend) { 333 /* If we don't "own" the password, it may change without us 334 * knowing, so we cannot encrypt the data, as we then may not be 335 * able to decrypt it */ 336 pass_b64 = base64_encode((unsigned char *)acc->pass, strlen(acc->pass)); 337 } else { 338 pass_len = arc_encode(acc->pass, strlen(acc->pass), (unsigned char **) &pass_cr, irc->password, 12); 339 pass_b64 = base64_encode(pass_cr, pass_len); 340 g_free(pass_cr); 341 } 336 342 337 343 cur = xt_new_node("account", NULL, NULL); 338 if (acc->prpl == &protocol_missing) { 339 xt_add_attr(cur, "protocol", set_getstr(&acc->set, "_protocol_name")); 340 } else { 341 xt_add_attr(cur, "protocol", acc->prpl->name); 342 } 344 xt_add_attr(cur, "protocol", acc->prpl->name); 343 345 xt_add_attr(cur, "handle", acc->user); 344 346 xt_add_attr(cur, "password", pass_b64); … … 348 350 xt_add_attr(cur, "server", acc->server); 349 351 } 352 if (acc->flags & ACC_FLAG_LOCKED) { 353 xt_add_attr(cur, "locked", "true"); 354 } 350 355 351 356 g_free(pass_b64); … … 392 397 xt_add_child(cur, xset = xt_new_node("setting", set->value, NULL)); 393 398 xt_add_attr(xset, "name", set->key); 399 if (set->flags & SET_LOCKED) { 400 xt_add_attr(xset, "locked", "true"); 401 } 394 402 } 395 403 } … … 450 458 451 459 452 static storage_status_t xml_remove(const char *nick , const char *password)460 static storage_status_t xml_remove(const char *nick) 453 461 { 454 462 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 463 462 464 lc = g_strdup(nick);
Note: See TracChangeset
for help on using the changeset viewer.