int pgp_rkeylist(REMAILER remailer[], int keyid[], int n) /* Step through all remailers and get keyid */ { BUFFER *userid; BUFFER *id; int i, err; userid = buf_new(); id = buf_new(); for (i = 1; i < n; i++) { buf_clear(userid); buf_setf(userid, "<%s>", remailer[i].addr); keyid[i]=0; if (remailer[i].flags.pgp) { buf_clear(id); err = pgpdb_getkey(PK_VERIFY, PGP_ANY, NULL, NULL, NULL, NULL, userid, NULL, id, NULL, NULL); if (id->length == 8) { /* printf("%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x %s\n", id->data[0], id->data[1], id->data[2], id->data[3], id->data[4], id->data[5], id->data[6], id->data[7], id->data[8], remailer[i].addr); */ keyid[i] = (((((id->data[4] << 8) + id->data[5]) << 8) + id->data[6]) << 8) + id->data[7]; } } } buf_free(userid); return (0); }
void menu_nym(char *nnym) { char nym[maxnym][LINELEN]; char pending[maxnym][LINELEN]; int c, i, num = 0, numpending = 0, select = -1; int edit = 0; BUFFER *nymlist; int s; int pass = 0; char reliability[9]; /* When printing information about a chain, this variable stores the reliability. */ nymlist = buf_new(); strcpy(nym[0], NONANON); strcatn(nym[0], " (", sizeof(nym[0])); strcatn(nym[0], NAME, sizeof(nym[0])); strcatn(nym[0], ")", sizeof(nym[0])); strcpy(nym[1], ANON); num = 2; if (nymlist_read(nymlist) == -1) { user_delpass(); mix_status(""); } else pass = 1; while (nymlist_get(nymlist, nym[num], NULL, NULL, NULL, NULL, NULL, &s) >= 0) { if (s == NYM_OK) { if (num < maxnym) num++; } else if (s == NYM_WAITING) { if (numpending < maxnym) strncpy(pending[numpending++], nym[num], LINELEN); } } buf_free(nymlist); nymselect: clear(); standout(); printw("Select nym:\n\n"); standend(); #ifdef USE_PGP if (pass) printw("c)reate new nym\ne)dit nym\nd)elete nym\n\n"); else printw("[nym passphrase is invalid]\n\n"); #endif /* USE_PGP */ for (i = 0; i < num; i++) printw("%d) %s\n", i, nym[i]); if (numpending > 0) { printw("\n\nWaiting for confirmation: "); for (i = 0; i < numpending; i++) printw("%s ", pending[i]); printw("\n"); } select: if (select != -1) printw("\r%d", select); else printw("\r \r"); refresh(); c = getch(); if (c == erasechar()) c = KEY_BACKSPACE; if (c >= '0' && c <= '9') { if (select == -1) select = c - '0'; else select = 10 * select + c - '0'; if (edit ? select == 0 || select >= num + numpending - 1 : select >= num) { beep(); select = -1; } refresh(); goto select; } else switch (c) { case KEY_BACKSPACE: select /= 10; if (select < 1) select = -1; goto select; case 'q': if (edit) { edit = 0; select = -1; goto nymselect; } break; #ifdef USE_PGP case 'e': if (pass) { if (edit || num + numpending < 3) { edit = 0; select = -1; goto nymselect; } else { clear(); standout(); printw("Edit nym:\n\n"); standend(); for (i = 2; i < num + numpending; i++) printw("%d) %s\n", i - 1, i < num ? nym[i] : pending[i - num]); printw("\n"); select = -1; edit = NYM_MODIFY; goto select; } } break; case 'd': if (pass) { if (edit || num + numpending < 3) { edit = 0; select = -1; goto nymselect; } else { clear(); standout(); printw("Delete nym:\n\n"); standend(); for (i = 2; i < num + numpending; i++) printw("%d) %s\n", i - 1, i < num ? nym[i] : pending[i - num]); printw("\n"); select = -1; edit = NYM_DELETE; goto select; } } break; case '\r': case '\n': if (select == -1 || (edit && select == 0)) { beep(); edit = 0; select = -1; goto nymselect; } if (!edit) { strncpy(nnym, nym[select], LINELEN); return; } /* fallthru */ case 'c': if (pass) { char nymserv[LINELEN] = "*"; char replyblock[5][CHAINMAX], dest[10][LINELEN]; int latent[5], desttype[5]; char mdest[LINELEN], pdest[LINELEN] = "alt.anonymous.messages", psub[LINELEN] = ""; int deflatent = 0, defdesttype = MSG_MAIL; char alias[LINELEN] = ""; BUFFER *name, *opt; char sendchain[CHAINMAX]; int sendnumcopies = 1, rnum = 1; int i; char line[LINELEN]; int acksend = 0, signsend = 0, fixedsize = 0, disable = 0, fingerkey = 1; name = buf_new(); opt = buf_new(); strncpy(sendchain, CHAIN, CHAINMAX); strncpy(mdest, ADDRESS, LINELEN); if (edit) strncpy(alias, select + 1 < num ? nym[select + 1] : pending[select + 1 - num], LINELEN); if (edit == NYM_MODIFY) { nymlist_getnym(alias, NULL, NULL, opt, name, NULL); acksend = bufifind(opt, "+acksend"); signsend = bufifind(opt, "+signsend"); fixedsize = bufifind(opt, "+fixedsize"); disable = bufifind(opt, "+disable"); fingerkey = bufifind(opt, "+fingerkey"); rnum = -1; } newnym: if (!edit) { clear(); standout(); printw("Create a nym:"); standend(); mvprintw(3, 0, "Alias address: "); echo(); wgetnstr(stdscr, alias, LINELEN); noecho(); if (alias[0] == '\0') goto end; for (i = 0; alias[i] > ' ' && alias[i] != '@'; i++) ; alias[i] = '\0'; if (i == 0) goto newnym; mvprintw(4, 0, "Pseudonym: "); echo(); wgetnstr(stdscr, line, LINELEN); noecho(); buf_sets(name, line); menu_chain(nymserv, 2, 0); } if (edit != NYM_DELETE) { for (i = 0; i < 5; i++) { desttype[i] = defdesttype; latent[i] = deflatent; dest[i][0] = '\0'; strcpy(replyblock[i], "*,*,*,*"); } if (rnum != -1) { menu_replychain(&defdesttype, &deflatent, mdest, pdest, psub, replyblock[0]); desttype[0] = defdesttype; latent[0] = deflatent; strncpy(dest[0], desttype[0] == MSG_POST ? pdest : mdest, LINELEN); } } redraw: clear(); standout(); switch (edit) { case NYM_DELETE: printw("Delete nym:"); break; case NYM_MODIFY: printw("Edit nym:"); break; default: printw("Create a nym:"); break; } standend(); loop: { if (!edit) { cl(2, 0); printw("Nym: a)lias address: %s", alias); cl(3, 0); printw(" nym s)erver: %s", nymserv); } if (edit != NYM_DELETE) { cl(4, 0); printw(" p)seudonym: %s", name->data); if (edit) mvprintw(6, 0, "Nym modification:"); else mvprintw(6, 0, "Nym creation:"); } cl(7, 0); chain_reliability(sendchain, 0, reliability); /* chaintype 0=mix */ printw(" c)hain to nym server: %-30s (reliability: %s)", sendchain, reliability); cl(8, 0); printw(" n)umber of redundant copies: %d", sendnumcopies); if (edit != NYM_DELETE) { mvprintw(10, 0, "Configuration:\n"); printw(" A)cknowledge sending: %s\n", acksend ? "yes" : "no"); printw(" S)erver signatures: %s\n", signsend ? "yes" : "no"); printw(" F)ixed size replies: %s\n", fixedsize ? "yes" : "no"); printw(" D)isable: %s\n", disable ? "yes" : "no"); printw(" Finger K)ey: %s\n", fingerkey ? "yes" : "no"); mvprintw(17, 0, "Reply chains:"); cl(18, 0); if (rnum == -1) printw(" create new r)eply block"); else { printw(" number of r)eply chains: %2d reliability", rnum); for (i = 0; i < rnum; i++) { cl(i + 19, 0); chain_reliability(replyblock[i], 1, reliability); /* 1=ek */ printw(" %d) %30s %-31s [%s]", i + 1, desttype[i] == MSG_NULL ? "(cover traffic)" : dest[i], replyblock[i], reliability); } } } move(LINES - 1, COLS - 1); refresh(); c = getch(); if (edit != NYM_DELETE && c >= '1' && c <= '9' && c - '1' < rnum) { menu_replychain(&defdesttype, &deflatent, mdest, pdest, psub, replyblock[c - '1']); desttype[c - '1'] = defdesttype; latent[c - '1'] = deflatent; strncpy(dest[c - '1'], desttype[c - '1'] == MSG_POST ? pdest : mdest, LINELEN); goto redraw; } switch (c) { case 'A': acksend = !acksend; goto redraw; case 'S': signsend = !signsend; goto redraw; case 'F': fixedsize = !fixedsize; goto redraw; case 'D': disable = !disable; goto redraw; case 'K': fingerkey = !fingerkey; goto redraw; case 'q': edit = 0; select = -1; goto nymselect; case '\014': goto redraw; case 'a': cl(2, 0); printw("Nym: a)lias address: "); echo(); wgetnstr(stdscr, alias, LINELEN); noecho(); for (i = 0; alias[i] > ' ' && alias[i] != '@'; i++) ; alias[i] = '\0'; if (i == 0) goto nymselect; goto redraw; case 'p': cl(4, 0); printw(" p)seudonym: "); echo(); wgetnstr(stdscr, line, LINELEN); noecho(); if (line[0] != '\0') buf_sets(name, line); goto redraw; case 'c': menu_chain(sendchain, 0, 0); goto redraw; case 'n': cl(8, 0); printw(" n)umber of redundant copies: "); echo(); wgetnstr(stdscr, line, LINELEN); noecho(); sendnumcopies = strtol(line, NULL, 10); if (sendnumcopies < 1 || sendnumcopies > 10) sendnumcopies = 1; goto redraw; case 'r': cl(18, 0); printw(" number of r)eply chains: "); echo(); wgetnstr(stdscr, line, LINELEN); noecho(); i = rnum; rnum = strtol(line, NULL, 10); if (rnum < 1) rnum = 1; if (rnum > 5) rnum = 5; for (; i < rnum; i++) if (dest[i][0] == '\0') { desttype[i] = defdesttype; latent[i] = deflatent; strncpy(dest[i], defdesttype == MSG_POST ? pdest : mdest, LINELEN); } goto redraw; case 's': menu_chain(nymserv, 2, 0); goto redraw; case '\n': case '\r': { BUFFER *chains; int err; if (rnum == -1) chains = NULL; else { chains = buf_new(); for (i = 0; i < rnum; i++) if (replyblock[i][0] != '\0') { if (desttype[i] == MSG_POST) buf_appendf(chains, "Subject: %s\n", psub); if (desttype[i] == MSG_MAIL) buf_appends(chains, "To: "); else if (desttype[i] == MSG_POST) buf_appends(chains, "Newsgroups: "); else buf_appends(chains, "Null:"); buf_appendf(chains, "%s\n", dest[i]); buf_appendf(chains, "Chain: %s\n", replyblock[i]); buf_appendf(chains, "Latency: %d\n\n", latent[i]); } } create: clear(); buf_setf(opt, " %cacksend %csignsend +cryptrecv %cfixedsize %cdisable %cfingerkey", acksend ? '+' : '-', signsend ? '+' : '-', fixedsize ? '+' : '-', disable ? '+' : '-', fingerkey ? '+' : '-'); if (edit) { mix_status("Preparing nymserver configuration message..."); err = nym_config(edit, alias, NULL, name, sendchain, sendnumcopies, chains, opt); } else { mix_status("Preparing nym creation request..."); err = nym_config(edit, alias, nymserv, name, sendchain, sendnumcopies, chains, opt); } if (err == -3) { beep(); mix_status("Bad passphrase!"); getch(); goto create; } if (err != 0) { mix_genericerror(); beep(); refresh(); } else { if (edit) mix_status("Nymserver configuration message completed."); else mix_status("Nym creation request completed."); } if (chains) buf_free(chains); goto end; } default: beep(); goto loop; } } end: buf_free(name); buf_free(opt); return; } #endif /* USE_PGP */ default: beep(); goto select; } }
int t1_encrypt(int type, BUFFER *message, char *chainstr, int latency, BUFFER *ek, BUFFER *feedback) { BUFFER *b, *rem, *dest, *line, *field, *content; REMAILER remailer[MAXREM]; int badchains[MAXREM][MAXREM]; int maxrem, chainlen = 0; int chain[20]; int hop; int hashmark = 0; int err = 0; b = buf_new(); rem = buf_new(); dest = buf_new(); line = buf_new(); field = buf_new(); content = buf_new(); maxrem = t1_rlist(remailer, badchains); if (maxrem < 1) { clienterr(feedback, "No remailer list!"); err = -1; goto end; } chainlen = chain_select(chain, chainstr, maxrem, remailer, 1, line); if (chainlen < 1) { if (line->length) clienterr(feedback, line->data); else clienterr(feedback, "Invalid remailer chain!"); err = -1; goto end; } if (chain[0] == 0) chain[0] = chain_randfinal(type, remailer, badchains, maxrem, 1, chain, chainlen, 0); if (chain[0] == -1) { clienterr(feedback, "Invalid remailer chain!"); err = -1; goto end; } if (chain_rand(remailer, badchains, maxrem, chain, chainlen, 1, 0) == -1) { clienterr(feedback, "No reliable remailers!"); err = -1; goto end; } while (buf_getheader(message, field, content) == 0) { hdr_encode(content, 0); if (type == MSG_POST && bufieq(field, "newsgroups") && remailer[chain[0]].flags.post) { buf_appendf(dest, "Anon-Post-To: %b\n", content); } else if (type == MSG_MAIL && bufieq(field, "to")) { buf_appendf(dest, "Anon-To: %b\n", content); } else { /* paste header */ if (type == MSG_POST && bufieq(field, "newsgroups")) buf_appendf(dest, "Anon-To: %s\n", MAILtoNEWS); if (hashmark == 0) { buf_appends(b, "##\n"); hashmark = 1; } buf_appendheader(b, field, content); } } buf_nl(b); buf_rest(b, message); buf_move(message, b); if (type != MSG_NULL && dest->length == 0) { clienterr(feedback, "No destination address!"); err = -1; goto end; } if (type == MSG_NULL) { buf_sets(dest, "Null:\n"); } for (hop = 0; hop < chainlen; hop++) { if (hop == 0) { buf_sets(b, "::\n"); buf_cat(b, dest); } else { buf_sets(b, "::\nAnon-To: "); buf_appends(b, remailer[chain[hop - 1]].addr); buf_nl(b); } if (remailer[chain[hop]].flags.latent && latency > 0) buf_appendf(b, "Latent-Time: +%d:00r\n", latency); if (ek && remailer[chain[hop]].flags.ek) { t1_ek(line, ek, hop); buf_appendf(b, "Encrypt-Key: %b\n", line); } buf_nl(b); buf_cat(b, message); #ifdef USE_PGP if (remailer[chain[hop]].flags.pgp) { buf_clear(message); buf_clear(rem); buf_setf(rem, "<%s>", remailer[chain[hop]].addr); err = pgp_encrypt(PGP_ENCRYPT | PGP_REMAIL | PGP_TEXT, b, rem, NULL, NULL, NULL, NULL); if (err < 0) { buf_setf(line, "No PGP key for remailer %s!\n", remailer[chain[hop]].name); clienterr(feedback, line->data); goto end; } buf_appends(message, "::\nEncrypted: PGP\n\n"); buf_cat(message, b); } else #endif /* USE_PGP */ { if (remailer[chain[hop]].flags.pgponly) { buf_setf(line, "PGP encryption needed for remailer %s!\n", remailer[chain[hop]].name); clienterr(feedback, line->data); goto end; } buf_move(message, b); } if (ek && remailer[chain[hop]].flags.ek) buf_appends(message, "\n**\n"); } buf_clear(b); if (chainlen == 0) { buf_appends(b, "::\n"); buf_cat(b, dest); } else { buf_appendf(b, "%s: %s\n", ek ? "::\nAnon-To" : "To", remailer[chain[chainlen - 1]].addr); } buf_nl(b); buf_cat(b, message); buf_move(message, b); end: buf_free(b); buf_free(rem); buf_free(dest); buf_free(line); buf_free(field); buf_free(content); return (err); }