Changeset dc9797f
- Timestamp:
- 2008-02-16T13:24:44Z (17 years ago)
- Branches:
- master
- Children:
- 3064ea4
- Parents:
- 27db433
- Files:
-
- 4 edited
Legend:
- Unmodified
- Added
- Removed
-
irc.c
r27db433 rdc9797f 134 134 conf_loaddefaults( irc ); 135 135 136 irc->otr_us = otrl_userstate_create(); 137 irc->otr_keygen = 0; 138 irc->otr_to = NULL; 139 irc->otr_from = NULL; 140 irc->otr_ntodo = 0; 136 irc->otr = otr_new(); 141 137 142 138 return( irc ); … … 290 286 } 291 287 292 otrl_userstate_free(irc->otr_us); 293 if(irc->otr_keygen) { 294 kill(irc->otr_keygen, SIGTERM); 295 waitpid(irc->otr_keygen, NULL, 0); 296 /* TODO: remove stale keygen tempfiles */ 297 } 288 otr_free(irc->otr); 298 289 299 290 g_free(irc); -
irc.h
r27db433 rdc9797f 98 98 gint ping_source_id; 99 99 100 OtrlUserState otr_us; 101 pid_t otr_keygen; /* pid of keygen slave */ 102 FILE *otr_to; /* pipe to keygen slave */ 103 FILE *otr_from; /* pipe from keygen slave */ 104 int otr_ntodo; /* number of keys left to generate */ 100 otr_t *otr; /* OTR state and book keeping */ 105 101 } irc_t; 106 102 -
otr.c
r27db433 rdc9797f 45 45 #include <sys/wait.h> 46 46 #include <unistd.h> 47 #include <assert.h> 47 48 48 49 … … 103 104 104 105 /** misc. helpers/subroutines: **/ 106 107 /* check whether we are already generating a key for a given account */ 108 int keygen_in_progress(irc_t *irc, const char *handle, const char *protocol); 105 109 106 110 /* start background process to generate a (new) key for a given account */ … … 191 195 } 192 196 197 otr_t *otr_new(void) 198 { 199 otr_t *otr = g_new0(otr_t, 1); 200 201 otr->us = otrl_userstate_create(); 202 203 return otr; 204 } 205 206 void otr_free(otr_t *otr) 207 { 208 otrl_userstate_free(otr->us); 209 if(otr->keygen) { 210 kill(otr->keygen, SIGTERM); 211 waitpid(otr->keygen, NULL, 0); 212 /* TODO: remove stale keygen tempfiles */ 213 } 214 if(otr->to) 215 fclose(otr->to); 216 if(otr->from) 217 fclose(otr->from); 218 while(otr->todo) { 219 kg_t *p = otr->todo; 220 otr->todo = p->next; 221 g_free(p); 222 } 223 g_free(otr); 224 } 225 193 226 void otr_load(irc_t *irc) 194 227 { … … 201 234 202 235 g_snprintf(s, 511, "%s%s.otr_keys", global.conf->configdir, irc->nick); 203 e = otrl_privkey_read(irc->otr _us, s);236 e = otrl_privkey_read(irc->otr->us, s); 204 237 if(e && e!=enoent) { 205 238 irc_usermsg(irc, "otr load: %s: %s", s, gcry_strerror(e)); 206 239 } 207 240 g_snprintf(s, 511, "%s%s.otr_fprints", global.conf->configdir, irc->nick); 208 e = otrl_privkey_read_fingerprints(irc->otr _us, s, NULL, NULL);241 e = otrl_privkey_read_fingerprints(irc->otr->us, s, NULL, NULL); 209 242 if(e && e!=enoent) { 210 243 irc_usermsg(irc, "otr load: %s: %s", s, gcry_strerror(e)); … … 225 258 226 259 g_snprintf(s, 511, "%s%s.otr_fprints", global.conf->configdir, irc->nick); 227 e = otrl_privkey_write_fingerprints(irc->otr _us, s);260 e = otrl_privkey_write_fingerprints(irc->otr->us, s); 228 261 if(e) { 229 262 irc_usermsg(irc, "otr save: %s: %s", s, gcry_strerror(e)); … … 263 296 OtrlPrivKey *k; 264 297 265 k = otrl_privkey_find(irc->otr _us, a->user, a->prpl->name);298 k = otrl_privkey_find(irc->otr->us, a->user, a->prpl->name); 266 299 if(k) { 267 irc_usermsg(irc, "otr: %s/%s ready", 268 a->user, a->prpl->name); 300 irc_usermsg(irc, "otr: %s/%s ready", a->user, a->prpl->name); 301 } if(keygen_in_progress(irc, a->user, a->prpl->name)) { 302 irc_usermsg(irc, "otr: keygen for %s/%s in progress", a->user, a->prpl->name); 269 303 } else { 270 304 otr_keygen(irc, a->user, a->prpl->name); … … 279 313 char *colormsg; 280 314 281 ignore_msg = otrl_message_receiving(ic->irc->otr _us, &global.otr_ops, ic,315 ignore_msg = otrl_message_receiving(ic->irc->otr->us, &global.otr_ops, ic, 282 316 ic->acc->user, ic->acc->prpl->name, handle, msg, &newmsg, 283 317 &tlvs, NULL, NULL); … … 293 327 } else { 294 328 /* OTR has processed this message */ 295 ConnContext *context = otrl_context_find(ic->irc->otr _us, handle,329 ConnContext *context = otrl_context_find(ic->irc->otr->us, handle, 296 330 ic->acc->user, ic->acc->prpl->name, 0, NULL, NULL, NULL); 297 331 if(context && context->msgstate == OTRL_MSGSTATE_ENCRYPTED && … … 319 353 ConnContext *ctx = NULL; 320 354 321 st = otrl_message_sending(ic->irc->otr _us, &global.otr_ops, ic,355 st = otrl_message_sending(ic->irc->otr->us, &global.otr_ops, ic, 322 356 ic->acc->user, ic->acc->prpl->name, handle, 323 357 msg, NULL, &otrmsg, NULL, NULL); … … 326 360 } 327 361 328 ctx = otrl_context_find(ic->irc->otr _us,362 ctx = otrl_context_find(ic->irc->otr->us, 329 363 handle, ic->acc->user, ic->acc->prpl->name, 330 364 1, NULL, NULL, NULL); … … 384 418 struct im_connection *ic = check_imc(opdata, context->accountname, context->protocol); 385 419 const char *p; 420 421 log_message(LOGLVL_DEBUG, "op_policy '%s' '%s'", context->accountname, context->protocol); 422 423 /* policy override during keygen: if we're missing the key for context but are currently 424 generating it, then that's as much as we can do. => temporarily return NEVER. */ 425 if(keygen_in_progress(ic->irc, context->accountname, context->protocol) && 426 !otrl_privkey_find(ic->irc->otr->us, context->accountname, context->protocol)) 427 return OTRL_POLICY_NEVER; 386 428 387 429 p = set_getstr(&ic->irc->set, "otr_policy"); … … 402 444 { 403 445 struct im_connection *ic = check_imc(opdata, accountname, protocol); 404 char *s;405 446 406 447 log_message(LOGLVL_DEBUG, "op_create_privkey '%s' '%s'", accountname, protocol); 407 448 408 s = g_strdup_printf("oops, no otr privkey for %s - generate one now?", 409 accountname); 410 query_add(ic->irc, ic, s, yes_keygen, NULL, ic->acc); 449 /* will fail silently if keygen already in progress */ 450 otr_keygen(ic->irc, accountname, protocol); 411 451 } 412 452 … … 596 636 } 597 637 598 otrl_message_disconnect(irc->otr _us, &global.otr_ops,638 otrl_message_disconnect(irc->otr->us, &global.otr_ops, 599 639 u->ic, u->ic->acc->user, u->ic->acc->prpl->name, u->handle); 600 640 … … 602 642 if(u->encrypted) { 603 643 ConnContext *ctx; 604 ctx = otrl_context_find(irc->otr _us, u->handle, u->ic->acc->user,644 ctx = otrl_context_find(irc->otr->us, u->handle, u->ic->acc->user, 605 645 u->ic->acc->prpl->name, 0, NULL, NULL, NULL); 606 646 if(ctx) … … 643 683 } 644 684 645 ctx = otrl_context_find(irc->otr _us, u->handle,685 ctx = otrl_context_find(irc->otr->us, u->handle, 646 686 u->ic->acc->user, u->ic->acc->prpl->name, 1, NULL, NULL, NULL); 647 687 if(!ctx) { … … 654 694 "SMP already in phase %d, sending abort before reinitiating", 655 695 ctx->smstate->nextExpected+1); 656 otrl_message_abort_smp(irc->otr _us, &global.otr_ops, u->ic, ctx);696 otrl_message_abort_smp(irc->otr->us, &global.otr_ops, u->ic, ctx); 657 697 otrl_sm_state_free(ctx->smstate); 658 698 } … … 662 702 if(ctx->smstate->secret == NULL) { 663 703 irc_usermsg(irc, "smp: initiating with %s...", u->nick); 664 otrl_message_initiate_smp(irc->otr _us, &global.otr_ops,704 otrl_message_initiate_smp(irc->otr->us, &global.otr_ops, 665 705 u->ic, ctx, (unsigned char *)args[2], strlen(args[2])); 666 706 /* smp is now in EXPECT2 */ … … 669 709 received the SMP1, so let's issue a response */ 670 710 irc_usermsg(irc, "smp: responding to %s...", u->nick); 671 otrl_message_respond_smp(irc->otr _us, &global.otr_ops,711 otrl_message_respond_smp(irc->otr->us, &global.otr_ops, 672 712 u->ic, ctx, (unsigned char *)args[2], strlen(args[2])); 673 713 /* smp is now in EXPECT3 */ … … 689 729 } 690 730 691 ctx = otrl_context_find(irc->otr _us, u->handle,731 ctx = otrl_context_find(irc->otr->us, u->handle, 692 732 u->ic->acc->user, u->ic->acc->prpl->name, 0, NULL, NULL, NULL); 693 733 if(!ctx) { … … 753 793 *(myhandle++) = '\0'; 754 794 handle = arg; 755 ctx = otrl_context_find(irc->otr _us, handle, myhandle, protocol, 0, NULL, NULL, NULL);795 ctx = otrl_context_find(irc->otr->us, handle, myhandle, protocol, 0, NULL, NULL, NULL); 756 796 if(!ctx) { 757 797 irc_usermsg(irc, "no such context"); … … 766 806 return; 767 807 } 768 ctx = otrl_context_find(irc->otr _us, u->handle, u->ic->acc->user,808 ctx = otrl_context_find(irc->otr->us, u->handle, u->ic->acc->user, 769 809 u->ic->acc->prpl->name, 0, NULL, NULL, NULL); 770 810 if(!ctx) { … … 803 843 } 804 844 805 if(otrl_privkey_find(irc->otr_us, a->user, a->prpl->name)) { 845 if(keygen_in_progress(irc, a->user, a->prpl->name)) { 846 irc_usermsg(irc, "keygen for account %d already in progress", n); 847 return; 848 } 849 850 if(otrl_privkey_find(irc->otr->us, a->user, a->prpl->name)) { 806 851 char *s = g_strdup_printf("account %d already has a key, replace it?", n); 807 852 query_add(irc, NULL, s, yes_keygen, NULL, a); … … 871 916 } 872 917 873 ctx = otrl_context_find(irc->otr _us, u->handle, u->ic->acc->user,918 ctx = otrl_context_find(irc->otr->us, u->handle, u->ic->acc->user, 874 919 u->ic->acc->prpl->name, 0, NULL, NULL, NULL); 875 920 if(!ctx) { … … 907 952 } 908 953 909 ctx = otrl_context_find(irc->otr _us, u->handle, u->ic->acc->user,954 ctx = otrl_context_find(irc->otr->us, u->handle, u->ic->acc->user, 910 955 u->ic->acc->prpl->name, 0, NULL, NULL, NULL); 911 956 if(!ctx) { … … 958 1003 { 959 1004 irc_t *irc = ic->irc; 960 OtrlUserState us = irc->otr _us;1005 OtrlUserState us = irc->otr->us; 961 1006 OtrlMessageAppOps *ops = &global.otr_ops; 962 1007 OtrlTLV *tlv = NULL; … … 1307 1352 /* find first key which matches the given prefix */ 1308 1353 n = strlen(prefix); 1309 for(k=irc->otr _us->privkey_root; k; k=k->next) {1310 p = otrl_privkey_fingerprint(irc->otr _us, human, k->accountname, k->protocol);1354 for(k=irc->otr->us->privkey_root; k; k=k->next) { 1355 p = otrl_privkey_fingerprint(irc->otr->us, human, k->accountname, k->protocol); 1311 1356 if(!p) /* gah! :-P */ 1312 1357 continue; … … 1321 1366 /* make sure the match, if any, is unique */ 1322 1367 for(k2=k->next; k2; k2=k2->next) { 1323 p = otrl_privkey_fingerprint(irc->otr _us, human, k2->accountname, k2->protocol);1368 p = otrl_privkey_fingerprint(irc->otr->us, human, k2->accountname, k2->protocol); 1324 1369 if(!p) /* gah! :-P */ 1325 1370 continue; … … 1343 1388 /* list all privkeys */ 1344 1389 irc_usermsg(irc, "\x1fprivate keys:\x1f"); 1345 for(key=irc->otr _us->privkey_root; key; key=key->next) {1390 for(key=irc->otr->us->privkey_root; key; key=key->next) { 1346 1391 const char *hash; 1347 1392 … … 1358 1403 account/protocol, but libotr currently doesn't provide a direct routine 1359 1404 for hashing a given 'OtrlPrivKey'... */ 1360 hash = otrl_privkey_fingerprint(irc->otr _us, human, key->accountname, key->protocol);1405 hash = otrl_privkey_fingerprint(irc->otr->us, human, key->accountname, key->protocol); 1361 1406 if(hash) /* should always succeed */ 1362 1407 irc_usermsg(irc, " %s", human); … … 1366 1411 irc_usermsg(irc, "%s", ""); 1367 1412 irc_usermsg(irc, "\x1f" "connection contexts:\x1f (bold=currently encrypted)"); 1368 for(ctx=irc->otr _us->context_root; ctx; ctx=ctx->next) {\1413 for(ctx=irc->otr->us->context_root; ctx; ctx=ctx->next) {\ 1369 1414 user_t *u; 1370 1415 char *userstring; … … 1425 1470 } 1426 1471 1472 int keygen_in_progress(irc_t *irc, const char *handle, const char *protocol) 1473 { 1474 kg_t *kg; 1475 1476 log_message(LOGLVL_DEBUG, "keygen_in_progress '%s' '%s'", handle, protocol); 1477 1478 if(!irc->otr->sent_accountname || !irc->otr->sent_protocol) 1479 return 0; 1480 1481 /* are we currently working on this key? */ 1482 if(!strcmp(handle, irc->otr->sent_accountname) && 1483 !strcmp(protocol, irc->otr->sent_protocol)) 1484 return 1; 1485 1486 /* do we have it queued for later? */ 1487 for(kg=irc->otr->todo; kg; kg=kg->next) { 1488 if(!strcmp(handle, kg->accountname) && 1489 !strcmp(protocol, kg->protocol)) 1490 return 1; 1491 } 1492 1493 return 0; 1494 } 1495 1427 1496 void otr_keygen(irc_t *irc, const char *handle, const char *protocol) 1428 1497 { 1498 /* do nothing if a key for the requested account is already being generated */ 1499 if(keygen_in_progress(irc, handle, protocol)) 1500 return; 1501 1429 1502 irc_usermsg(irc, "generating new private key for %s/%s...", handle, protocol); 1430 1503 1431 1504 /* see if we already have a keygen child running. if not, start one and put a 1432 1505 handler on its output. */ 1433 if(!irc->otr _keygen || waitpid(irc->otr_keygen, NULL, WNOHANG)) {1506 if(!irc->otr->keygen || waitpid(irc->otr->keygen, NULL, WNOHANG)) { 1434 1507 pid_t p; 1435 1508 int to[2], from[2]; … … 1457 1530 /* child process */ 1458 1531 signal(SIGTERM, exit); 1459 keygen_child_main(irc->otr _us, to[0], from[1]);1532 keygen_child_main(irc->otr->us, to[0], from[1]); 1460 1533 exit(0); 1461 1534 } 1462 1535 1463 irc->otr_keygen = p; 1464 irc->otr_to = tof; 1465 irc->otr_from = fromf; 1466 irc->otr_ntodo = 0; 1536 irc->otr->keygen = p; 1537 irc->otr->to = tof; 1538 irc->otr->from = fromf; 1539 irc->otr->sent_accountname = NULL; 1540 irc->otr->sent_protocol = NULL; 1541 irc->otr->todo = NULL; 1467 1542 b_input_add(from[0], GAIM_INPUT_READ, keygen_finish_handler, irc); 1468 1543 } 1469 1544 1470 /* send accountname and protocol for the new key to our keygen slave */ 1471 fprintf(irc->otr_to, "%s\n%s\n", handle, protocol); 1472 fflush(irc->otr_to); 1473 irc->otr_ntodo++; 1545 /* is the keygen slave currently working? */ 1546 if(irc->otr->sent_accountname) { 1547 /* enqueue our job for later transmission */ 1548 log_message(LOGLVL_DEBUG, "enqueueing keygen for %s/%s", handle, protocol); 1549 kg_t **kg = &irc->otr->todo; 1550 while(*kg) 1551 kg=&((*kg)->next); 1552 *kg = g_new0(kg_t, 1); 1553 (*kg)->accountname = handle; 1554 (*kg)->protocol = protocol; 1555 } else { 1556 /* send our job over and remember it */ 1557 log_message(LOGLVL_DEBUG, "slave: generate for %s/%s!", handle, protocol); 1558 fprintf(irc->otr->to, "%s\n%s\n", handle, protocol); 1559 fflush(irc->otr->to); 1560 irc->otr->sent_accountname = handle; 1561 irc->otr->sent_protocol = protocol; 1562 } 1474 1563 } 1475 1564 … … 1515 1604 log_message(LOGLVL_DEBUG, "keygen_finish_handler cond=%d", cond); 1516 1605 1517 myfgets(filename, 512, irc->otr _from);1518 myfgets(msg, 512, irc->otr _from);1606 myfgets(filename, 512, irc->otr->from); 1607 myfgets(msg, 512, irc->otr->from); 1519 1608 1520 1609 log_message(LOGLVL_DEBUG, "filename='%s'", filename); … … 1528 1617 unlink(filename); 1529 1618 rename(tmp,kf); 1530 otrl_privkey_read(irc->otr _us, kf);1619 otrl_privkey_read(irc->otr->us, kf); 1531 1620 g_free(kf); 1532 1621 g_free(tmp); 1533 1622 } 1534 1535 irc->otr_ntodo--; 1536 if(irc->otr_ntodo < 1) { 1537 /* okay, we think the slave is idle now, so kill him */ 1623 1624 /* forget this job */ 1625 irc->otr->sent_accountname = NULL; 1626 irc->otr->sent_protocol = NULL; 1627 1628 /* see if there are any more in the queue */ 1629 if(irc->otr->todo) { 1630 kg_t *p = irc->otr->todo; 1631 /* send the next one over */ 1632 log_message(LOGLVL_DEBUG, "slave: keygen for %s/%s!", p->accountname, p->protocol); 1633 fprintf(irc->otr->to, "%s\n%s\n", p->accountname, p->protocol); 1634 fflush(irc->otr->to); 1635 irc->otr->sent_accountname = p->accountname; 1636 irc->otr->sent_protocol = p->protocol; 1637 irc->otr->todo = p->next; 1638 g_free(p); 1639 return TRUE; /* keep watching */ 1640 } else { 1641 /* okay, the slave is idle now, so kill him */ 1538 1642 log_message(LOGLVL_DEBUG, "all keys done. die, slave!"); 1539 fclose(irc->otr _from);1540 fclose(irc->otr _to);1541 kill(irc->otr _keygen, SIGTERM);1542 waitpid(irc->otr _keygen, NULL, 0);1543 irc->otr _keygen = 0;1643 fclose(irc->otr->from); 1644 fclose(irc->otr->to); 1645 kill(irc->otr->keygen, SIGTERM); 1646 waitpid(irc->otr->keygen, NULL, 0); 1647 irc->otr->keygen = 0; 1544 1648 return FALSE; /* unregister ourselves */ 1545 } else {1546 return TRUE; /* slave still working, keep watching */1547 1649 } 1548 1650 } … … 1581 1683 account_t *acc = (account_t *)data; 1582 1684 1583 otr_keygen(acc->irc, acc->user, acc->prpl->name); 1685 if(keygen_in_progress(acc->irc, acc->user, acc->prpl->name)) { 1686 irc_usermsg(acc->irc, "keygen for %s/%s already in progress", 1687 acc->user, acc->prpl->name); 1688 } else { 1689 otr_keygen(acc->irc, acc->user, acc->prpl->name); 1690 } 1584 1691 } 1585 1692 -
otr.h
r27db433 rdc9797f 49 49 #include <libotr/privkey.h> 50 50 51 /* representing a keygen job */ 52 typedef struct kg { 53 const char *accountname; 54 const char *protocol; 55 56 struct kg *next; 57 } kg_t; 58 59 /* struct to encapsulate our book keeping stuff */ 60 typedef struct otr { 61 OtrlUserState us; 62 pid_t keygen; /* pid of keygen slave (0 if none) */ 63 FILE *to; /* pipe to keygen slave */ 64 FILE *from; /* pipe from keygen slave */ 65 66 /* active keygen job (NULL if none) */ 67 const char *sent_accountname; 68 const char *sent_protocol; 69 70 /* keygen jobs waiting to be sent to slave */ 71 kg_t *todo; 72 } otr_t; 73 51 74 /* called from main() */ 52 75 void otr_init(void); 76 77 /* called from irc_new()/irc_free() */ 78 otr_t *otr_new(); 79 void otr_free(otr_t *otr); 53 80 54 81 /* called by storage_* functions */ … … 71 98 #else 72 99 73 typedef void *OtrlUserState;100 typedef void otr_t; 74 101 typedef void *OtrlMessageAppOps; 75 102 76 #define otrl_userstate_create() (NULL)77 #define otrl_userstate_free(us) {}78 79 103 #define otr_init() {} 104 #define otr_new() (NULL) 105 #define otr_free(otr) {} 80 106 #define otr_load(irc) {} 81 107 #define otr_save(irc) {}
Note: See TracChangeset
for help on using the changeset viewer.