Changeset 27db433
- Timestamp:
- 2008-02-15T17:36:18Z (17 years ago)
- Branches:
- master
- Children:
- dc9797f
- Parents:
- 522a00f
- Files:
-
- 3 edited
Legend:
- Unmodified
- Added
- Removed
-
irc.c
r522a00f r27db433 136 136 irc->otr_us = otrl_userstate_create(); 137 137 irc->otr_keygen = 0; 138 irc->otr_to = NULL; 139 irc->otr_from = NULL; 138 140 irc->otr_ntodo = 0; 139 141 -
irc.h
r522a00f r27db433 99 99 100 100 OtrlUserState otr_us; 101 pid_t otr_keygen; 102 int otr_ntodo; 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 */ 103 105 } irc_t; 104 106 -
otr.c
r522a00f r27db433 43 43 #include "otr.h" 44 44 #include <sys/types.h> 45 #include <sys/wait.h> 45 46 #include <unistd.h> 46 47 … … 106 107 void otr_keygen(irc_t *irc, const char *handle, const char *protocol); 107 108 109 /* main function for the forked keygen slave */ 110 void keygen_child_main(OtrlUserState us, int infd, int outfd); 111 108 112 /* mainloop handler for when a keygen finishes */ 109 113 gboolean keygen_finish_handler(gpointer data, gint fd, b_input_condition cond); 114 115 /* copy the contents of file a to file b, overwriting it if it exists */ 116 void copyfile(const char *a, const char *b); 117 118 /* read one line of input from a stream, excluding trailing newline */ 119 void myfgets(char *s, int size, FILE *stream); 110 120 111 121 /* some yes/no handlers */ … … 1417 1427 void otr_keygen(irc_t *irc, const char *handle, const char *protocol) 1418 1428 { 1419 1420 1429 irc_usermsg(irc, "generating new private key for %s/%s...", handle, protocol); 1421 irc_usermsg(irc, "n/a: not implemented");1422 return;1423 1430 1424 1431 /* see if we already have a keygen child running. if not, start one and put a 1425 handler on its output. 1426 1427 b_input_add(fd, GAIM_INPUT_READ, keygen_finish_handler, NULL); 1428 1429 generate a fresh temp file name for our new key and save our current keys to it. 1430 send the child filename and accountname/protocol for the new key 1431 increment 'ntodo' */ 1432 1433 /* in the child: 1434 read filename, accountname, protocol from input, and start work: 1435 1436 result = otrl_privkey_generate(kg->irc->otr_us, kg->keyfile, kg->handle, 1437 kg->protocol); 1438 1439 when done, send filename, accountname, and protocol to output. */ 1440 1432 handler on its output. */ 1433 if(!irc->otr_keygen || waitpid(irc->otr_keygen, NULL, WNOHANG)) { 1434 pid_t p; 1435 int to[2], from[2]; 1436 FILE *tof, *fromf; 1437 1438 if(pipe(to) < 0 || pipe(from) < 0) { 1439 irc_usermsg(irc, "otr keygen: couldn't create pipe: %s", strerror(errno)); 1440 return; 1441 } 1442 1443 tof = fdopen(to[1], "w"); 1444 fromf = fdopen(from[0], "r"); 1445 if(!tof || !fromf) { 1446 irc_usermsg(irc, "otr keygen: couldn't streamify pipe: %s", strerror(errno)); 1447 return; 1448 } 1449 1450 p = fork(); 1451 if(p<0) { 1452 irc_usermsg(irc, "otr keygen: couldn't fork: %s", strerror(errno)); 1453 return; 1454 } 1455 1456 if(!p) { 1457 /* child process */ 1458 signal(SIGTERM, exit); 1459 keygen_child_main(irc->otr_us, to[0], from[1]); 1460 exit(0); 1461 } 1462 1463 irc->otr_keygen = p; 1464 irc->otr_to = tof; 1465 irc->otr_from = fromf; 1466 irc->otr_ntodo = 0; 1467 b_input_add(from[0], GAIM_INPUT_READ, keygen_finish_handler, irc); 1468 } 1469 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++; 1474 } 1475 1476 void keygen_child_main(OtrlUserState us, int infd, int outfd) 1477 { 1478 FILE *input, *output; 1479 char filename[128], accountname[512], protocol[512]; 1480 gcry_error_t e; 1481 int tempfd; 1482 1483 input = fdopen(infd, "r"); 1484 output = fdopen(outfd, "w"); 1485 1486 while(!feof(input) && !ferror(input) && !feof(output) && !ferror(output)) { 1487 myfgets(accountname, 512, input); 1488 myfgets(protocol, 512, input); 1489 1490 strncpy(filename, "/tmp/bitlbee-XXXXXX", 128); 1491 tempfd = mkstemp(filename); 1492 close(tempfd); 1493 1494 e = otrl_privkey_generate(us, filename, accountname, protocol); 1495 if(e) { 1496 fprintf(output, "\n"); /* this means failure */ 1497 fprintf(output, "otr keygen: %s\n", gcry_strerror(e)); 1498 unlink(filename); 1499 } else { 1500 fprintf(output, "%s\n", filename); 1501 fprintf(output, "otr keygen for %s/%s complete\n", accountname, protocol); 1502 } 1503 fflush(output); 1504 } 1505 1506 fclose(input); 1507 fclose(output); 1441 1508 } 1442 1509 1443 1510 gboolean keygen_finish_handler(gpointer data, gint fd, b_input_condition cond) 1444 1511 { 1445 /* in the handler: 1446 read filename, accountname, and protocol from child output 1447 print a message to the user 1448 irc_usermsg(kg->irc, "otr keygen for %s/%s complete", kg->handle, kg->protocol); 1449 load the file into userstate 1450 call otr_save. 1451 remove the tempfile. 1452 decrement 'ntodo' 1453 if 'ntodo' reaches zero, send SIGTERM to the child, waitpid for it, return FALSE */ 1454 1455 return TRUE; /* still working, keep watching */ 1512 irc_t *irc = (irc_t *)data; 1513 char filename[512], msg[512]; 1514 1515 log_message(LOGLVL_DEBUG, "keygen_finish_handler cond=%d", cond); 1516 1517 myfgets(filename, 512, irc->otr_from); 1518 myfgets(msg, 512, irc->otr_from); 1519 1520 log_message(LOGLVL_DEBUG, "filename='%s'", filename); 1521 log_message(LOGLVL_DEBUG, "msg='%s'", msg); 1522 1523 irc_usermsg(irc, "%s", msg); 1524 if(filename[0]) { 1525 char *kf = g_strdup_printf("%s%s.otr_keys", global.conf->configdir, irc->nick); 1526 char *tmp = g_strdup_printf("%s.new", kf); 1527 copyfile(filename, tmp); 1528 unlink(filename); 1529 rename(tmp,kf); 1530 otrl_privkey_read(irc->otr_us, kf); 1531 g_free(kf); 1532 g_free(tmp); 1533 } 1534 1535 irc->otr_ntodo--; 1536 if(irc->otr_ntodo < 1) { 1537 /* okay, we think the slave is idle now, so kill him */ 1538 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; 1544 return FALSE; /* unregister ourselves */ 1545 } else { 1546 return TRUE; /* slave still working, keep watching */ 1547 } 1548 } 1549 1550 void copyfile(const char *a, const char *b) 1551 { 1552 int fda, fdb; 1553 int n; 1554 char buf[1024]; 1555 1556 log_message(LOGLVL_DEBUG, "copyfile '%s' '%s'", a, b); 1557 1558 fda = open(a, O_RDONLY); 1559 fdb = open(b, O_WRONLY | O_CREAT | O_TRUNC, 0600); 1560 1561 while((n=read(fda, buf, 1024)) > 0) 1562 write(fdb, buf, n); 1563 1564 close(fda); 1565 close(fdb); 1566 } 1567 1568 void myfgets(char *s, int size, FILE *stream) 1569 { 1570 if(!fgets(s, size, stream)) { 1571 s[0] = '\0'; 1572 } else { 1573 int n = strlen(s); 1574 if(n>0 && s[n-1] == '\n') 1575 s[n-1] = '\0'; 1576 } 1456 1577 } 1457 1578
Note: See TracChangeset
for help on using the changeset viewer.