float chain_reliability(char *chain, int chaintype, char *reliability_string){ float acc_reliability = 1; /* Accumulated reliablity */ char *name_start, *name_end; /* temporary pointers used in string scanning */ char remailer_name[20]; /* The length of the array is taken from mix3.h. */ int error = 0; int maxrem; int i; int previous = -1; REMAILER remailer[MAXREM]; int badchains[MAXREM][MAXREM]; /* chaintype 0=mix 1=ek 2=newnym */ assert((chaintype == 0) || (chaintype == 1)); maxrem = (chaintype == 0 ? mix2_rlist(remailer, badchains) : t1_rlist(remailer, badchains)); /* Dissect chain */ name_start = chain; name_end = chain; while(*name_end != '\0'){ /* While string not scanned completely */ do /* Get next remailer */ name_end+=sizeof(char); while( (*name_end != ',') && (*name_end != '\0')); strncpy(remailer_name, name_start, (name_end - name_start) / sizeof(char) + 1*sizeof(char)); remailer_name[name_end-name_start]='\0'; /* Lookup reliablity for remailer remailer_name */ for(i=0; (i < maxrem) && (strcmp(remailer[i].name, remailer_name) != 0); i++); if(!strcmp(remailer[i].name, remailer_name)) { /* Found it! */ acc_reliability *= ((float) remailer[i].info[chaintype].reliability) / 10000; if (previous != -1) { if (badchains[previous][i] || badchains[0][i]) acc_reliability = 0; } previous = i; } else error = 1; /* Did not find this remailer. We can't calculate the reliablity for the whole chain. */ name_start = name_end+sizeof(char); } if(error || (name_start==name_end)) acc_reliability = -1; /* Convert reliability into string, if appropriate */ if(reliability_string){ if(acc_reliability < 0) sprintf(reliability_string, " n/a "); else{ sprintf(reliability_string, "%6.2f", acc_reliability*100); *(reliability_string+6*sizeof(char)) = '%'; } } return acc_reliability; }
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); }