int pgp_rlist(REMAILER remailer[], int n) /* verify that keys are available */ { BUFFER *keyring, *p; int i, type, pgpkey[MAXREM]; keyring = buf_new(); p = buf_new(); for (i = 1; i < n; i++) pgpkey[i] = 0; if (pgp_readkeyring(keyring, PGPREMPUBASC) == -1) pgp_readkeyring(keyring, PGPREMPUBRING); while ((type = pgp_getpacket(keyring, p)) != -1) if (type == PGP_USERID) for (i = 1; i < n; i++) if (remailer[i].flags.pgp && bufifind(p, remailer[i].name)) pgpkey[i] = 1; for (i = 1; i < n; i++) remailer[i].flags.pgp = pgpkey[i]; buf_free(p); buf_free(keyring); 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 pgpdb_getnext(KEYRING *keydb, BUFFER *key, BUFFER *keyid, BUFFER *userid) /* store next key from keydb with specified keyid/userid in key. */ { int found = 0; int type; long ptr; int tempbuf = 0; BUFFER *p, *i, *thisid; p = buf_new(); i = buf_new(); thisid = buf_new(); if (key == NULL) { tempbuf = 1; key = buf_new(); } assert(key != keyid); while (!found) { buf_clear(key); type = pgp_getpacket(keydb->db, key); if (type == -1) break; if (type != PGP_PUBKEY && type != PGP_SECKEY) continue; if ((keyid == NULL || keyid->length == 0) && (userid == NULL || userid->length == 0)) found = 1; if (keyid && keyid->length > 0) { pgp_keyid(key, thisid); if (buf_eq(keyid, thisid)) found = 1; } pgp_packet(key, type); while ((ptr = keydb->db->ptr, type = pgp_getpacket(keydb->db, p)) > 0) { switch (type) { case PGP_SECKEY: case PGP_PUBKEY: keydb->db->ptr = ptr; goto nextkey; case PGP_PUBSUBKEY: case PGP_SECSUBKEY: if (keyid && keyid->length > 0) { pgp_keyid(p, thisid); if (buf_eq(keyid, thisid)) found = 1; } break; case PGP_USERID: #ifdef DEBUG printf("%s\n", p->data); #endif /* DEBUG */ if (userid && userid->length > 0 && bufifind(p, userid->data)) found = 1; break; } pgp_packet(p, type); buf_cat(key, p); } nextkey: ; } if (tempbuf) buf_free(key); buf_free(p); buf_free(i); buf_free(thisid); return (found ? 0 : -1); }
int t1_rlist(REMAILER remailer[], int badchains[MAXREM][MAXREM]) { FILE *list, *excl; int i, listed = 0; int n = 0; char line[2 * LINELEN], l2[LINELEN], name[LINELEN], *flags; BUFFER *starex; starex = buf_new(); excl = mix_openfile(STAREX, "r"); if (excl != NULL) { buf_read(starex, excl); fclose(excl); } list = mix_openfile(TYPE1LIST, "r"); if (list == NULL) { buf_free(starex); return (-1); } while (fgets(line, sizeof(line), list) != NULL && n < MAXREM) { if (strleft(line, "$remailer") && strchr(line, '<') && strchr(line, '>') && strchr(line, '{') && strchr(line, '{') + 4 < strchr(line, '}')) { if (line[strlen(line) - 1] == '\n') line[strlen(line) - 1] = '\0'; if (line[strlen(line) - 1] == '\r') line[strlen(line) - 1] = '\0'; while (line[strlen(line) - 1] == ' ') line[strlen(line) - 1] = '\0'; if (line[strlen(line) - 1] != ';' && fgets(l2, sizeof(l2), list) != NULL) strcatn(line, l2, LINELEN); flags = strchr(line, '>'); strncpy(name, strchr(line, '{') + 2, strchr(line, '}') - strchr(line, '{') - 3); name[strchr(line, '}') - strchr(line, '{') - 3] = '\0'; name[20] = '\0'; for (i = 1; i <= n; i++) if (streq(name, remailer[i].name)) break; if (i > n) { /* not in mix list */ n++; strcpy(remailer[i].name, name); strncpy(remailer[i].addr, strchr(line, '<') + 1, strchr(line, '>') - strchr(line, '<')); remailer[i].addr[strchr(line, '>') - strchr(line, '<') - 1] = '\0'; remailer[i].flags.mix = 0; remailer[i].flags.post = strifind(flags, " post"); } remailer[i].flags.cpunk = strfind(flags, " cpunk"); remailer[i].flags.pgp = strfind(flags, " pgp"); remailer[i].flags.pgponly = strfind(flags, " pgponly"); remailer[i].flags.latent = strfind(flags, " latent"); remailer[i].flags.middle = strfind(flags, " middle"); remailer[i].flags.ek = strfind(flags, " ek"); remailer[i].flags.esub = strfind(flags, " esub"); remailer[i].flags.hsub = strfind(flags, " hsub"); remailer[i].flags.newnym = strfind(flags, " newnym"); remailer[i].flags.nym = strfind(flags, " nym"); remailer[i].info[1].reliability = 0; remailer[i].info[1].latency = 0; remailer[i].info[1].history[0] = '\0'; remailer[i].flags.star_ex = bufifind(starex, name); } if (strleft(line, "-----------------------------------------------------------------------")) break; } n++; /* ?? */ while (fgets(line, sizeof(line), list) != NULL) { if (strlen(line) >= 72 && strlen(line) <= 73) for (i = 1; i < n; i++) if (strleft(line, remailer[i].name) && line[strlen(remailer[i].name)] == ' ') { strncpy(remailer[i].info[1].history, line + 42, 12); remailer[i].info[1].history[12] = '\0'; remailer[i].info[1].reliability = 10000 * N(line[64]) + 1000 * N(line[65]) + 100 * N(line[66]) + 10 * N(line[68]) + N(line[69]); remailer[i].info[1].latency = 36000 * N(line[55]) + 3600 * N(line[56]) + 600 * N(line[58]) + 60 * N(line[59]) + 10 * N(line[61]) + N(line[62]); listed++; } } fclose(list); parse_badchains(badchains, TYPE1LIST, "Broken type-I remailer chains", remailer, n); if (listed < 4) /* we have no valid reliability info */ for (i = 1; i < n; i++) remailer[i].info[1].reliability = 10000; #ifdef USE_PGP pgp_rlist(remailer, n); #endif /* USE_PGP */ buf_free(starex); return (n); }