int pgp_latestkeys(BUFFER* outtxt, int algo) /* returns our latest key from pgpkey.txt in the buffer outtxt * with pgp key header, ascii armored * * Can probably be extended to do this for all keys if we pass * the keyring file and the userid * * IN: algo: PGP_ANY, PGP_ES_RSA, PGP_E_ELG, PGP_S_DSA * OUT: outtxt */ { int err = -1; long expires_found = 0, expires; BUFFER *key, *userid, *tmptxt; KEYRING *keys; key = buf_new(); userid = buf_new(); buf_sets(userid, REMAILERNAME); tmptxt = buf_new(); keys = pgpdb_open(PGPKEY, NULL, 0, PGP_TYPE_PUBLIC); if (keys != NULL) { while (pgpdb_getnext(keys, key, NULL, userid) != -1) { buf_clear(tmptxt); if (pgp_makekeyheader(PGP_PUBKEY, key, tmptxt, NULL, algo) == 0) { buf_rewind(key); pgp_getkey(PK_VERIFY, algo, NULL, NULL, &expires, key, NULL, NULL, NULL, NULL); if (expires == 0 || (expires_found <= expires)) { err = 0; buf_clear(outtxt); buf_appends(outtxt, "Type Bits/KeyID Date User ID\n"); buf_cat(outtxt, tmptxt); buf_nl(outtxt); pgp_armor(key, PGP_ARMOR_KEY); buf_cat(outtxt, key); buf_nl(outtxt); expires_found = expires; } } } pgpdb_close(keys); } buf_free(key); buf_free(userid); buf_free(tmptxt); return (err); }
static int pgp_readkeyring(BUFFER *keys, char *filename) { FILE *keyfile; BUFFER *armored, *line, *tmp; int err = -1; if ((keyfile = mix_openfile(filename, "rb")) == NULL) return (err); armored = buf_new(); buf_read(armored, keyfile); fclose(keyfile); if (pgp_ispacket(armored)) { err = 0; buf_move(keys, armored); } else { line = buf_new(); tmp = buf_new(); while (1) { do if (buf_getline(armored, line) == -1) { goto end_greedy_dearmor; } while (!bufleft(line, begin_pgp)) ; buf_clear(tmp); buf_cat(tmp, line); buf_appends(tmp, "\n"); do { if (buf_getline(armored, line) == -1) { goto end_greedy_dearmor; } buf_cat(tmp, line); buf_appends(tmp, "\n"); } while (!bufleft(line, end_pgp)) ; if (pgp_dearmor(tmp, tmp) == 0) { err = ARMORED; buf_cat(keys, tmp); } } end_greedy_dearmor: buf_free(line); buf_free(tmp); } buf_free(armored); return (err); }
int pgpdb_append(KEYRING *keydb, BUFFER *p) { assert(keydb->lock); #ifdef DEBUG assert(keydb->writer); #endif buf_cat(keydb->db, p); keydb->modified = 1; return (0); }
int t1_ek(BUFFER *key, BUFFER *seed, int num) { buf_reset(key); buf_appendc(key, (byte) num); buf_cat(key, seed); digest_md5(key, key); encode(key, 0); #ifdef DEBUG fprintf(stderr, "passphrase=%s (%2X%2X%2X%2X %d)\n", key->data, seed->data[0], seed->data[1], seed->data[2], seed->data[3], num); #endif /* DEBUG */ return (0); }
static int search_spell(const char *filename, unsigned parnum, unsigned pos) { struct rfc2045 *rfcp, *textp; struct buf newtext, current_line; off_t start_pos, end_pos, start_body; int made_replacements, has_misspelling; char *new_line; unsigned paragraph; const char *ignoreword=""; const char *replacefrom=""; const char *replaceto=""; int checked=0; off_t dummy; FILE *fp=0; int x; x=maildir_safeopen(filename, O_RDONLY, 0); if (x >= 0) if ((fp=fdopen(x, "r")) == 0) close(x); if (!fp) return (0); rfcp=rfc2045_fromfp(fp); if (!rfcp) enomem(); textp=findtext(rfcp); if (!textp) { rfc2045_free(rfcp); fclose(fp); return (0); } buf_init(&newtext); buf_init(¤t_line); rfc2045_mimepos(textp, &start_pos, &end_pos, &start_body, &dummy, &dummy); if (fseek(fp, start_body, SEEK_SET) == -1) enomem(); made_replacements=0; has_misspelling=0; paragraph=0; for ( ; start_body < end_pos; start_body++) { int c=getc(fp); if (c < 0) enomem(); if (c != '\n') { buf_append(¤t_line, c); continue; } buf_append(¤t_line, '\0'); if (parnum) { --parnum; buf_cat(&newtext, current_line.ptr); buf_cat(&newtext, "\n"); current_line.cnt=0; ++paragraph; continue; } if (!checked) { int l; checked=1; if ((l=strlen(cgi("word"))) > 0) { /* Ok, what should we do? */ const char *newword=cgi("REPLACE"); if (!*newword || strcmp(newword, "#other") == 0) newword=cgi("OTHER"); /* ** Perhaps they entered the word without ** checking this checkmark. */ else if (*newword == '#') newword=""; if (*newword && pos + l <= strlen(current_line.ptr)) { struct buf tempbuf; buf_init(&tempbuf); buf_cpyn(&tempbuf, current_line.ptr, pos); buf_cat(&tempbuf, newword); buf_cat(&tempbuf, current_line.ptr+pos+l); pos += strlen(newword); if (*cgi("REPLACEALL")) { replacefrom=cgi("word"); replaceto=newword; } buf_append(&tempbuf, '\0'); buf_cpy(¤t_line, tempbuf.ptr); buf_append(¤t_line, '\0'); buf_free(&tempbuf); made_replacements=1; } else { pos += l; if (strcmp(cgi("REPLACE"), "#ignoreall") == 0) ignoreword=cgi("word"); } if (strcmp(cgi("REPLACE"), "#insert") == 0) { spelladd(cgi("word")); } } } if (*current_line.ptr == '>') { buf_cat(&newtext, current_line.ptr); buf_cat(&newtext, "\n"); pos=0; current_line.cnt=0; ++paragraph; continue; } if (!has_misspelling) { new_line=spell_check(current_line.ptr, paragraph, pos, ignoreword, replacefrom, replaceto, &has_misspelling); if (new_line) { buf_cat(&newtext, new_line); free(new_line); made_replacements=1; } else buf_cat(&newtext, current_line.ptr); } else buf_cat(&newtext, current_line.ptr); buf_cat(&newtext, "\n"); pos=0; current_line.cnt=0; ++paragraph; } if (current_line.cnt) buf_cat(&newtext, "\n"); rfc2045_free(rfcp); fclose(fp); if (made_replacements) { char *p=newmsg_createdraft_do(filename, newtext.ptr, NEWMSG_SQISPELL); if (p) free(p); if (*cgi("error")) { has_misspelling=0; /* Abort spell checking */ } } buf_free(&newtext); buf_free(¤t_line); if (*ignoreword) { static char *p=0; if (p) free(p); p=malloc(strlen(cgi("globignore")) + 2 + strlen(ignoreword)); if (!p) enomem(); strcpy(p, cgi("globignore")); if (*p) strcat(p, ":"); strcat(p, ignoreword); cgi_put("globignore", p); } if (*replacefrom) { static char *p=0; if (p) free(p); p=malloc(strlen(cgi("globreplace"))+3 +strlen(replacefrom)+strlen(replaceto)); if (!p) enomem(); strcpy(p, cgi("globreplace")); if (*p) strcat(p, ":"); strcat(strcat(strcat(p, replacefrom), ":"), replaceto); cgi_put("globreplace", p); free(p); } if (has_misspelling) return (1); return (0); }
int v2body(BUFFER *body) { int i, n; BUFFER *to, *newsgroups; BUFFER *temp, *out; BUFFER *line; int type = MSG_MAIL; int subject = 0; line = buf_new(); to = buf_new(); newsgroups = buf_new(); temp = buf_new(); out = buf_new(); n = buf_getc(body); for (i = 0; i < n; i++) { buf_get(body, line, 80); buf_chop(line); if (bufileft(line, "null:")) goto end; if (bufileft(line, "post:")) { type = MSG_POST; if (line->length > 5) { int j = 5; while (j < line->length && isspace(line->data[j])) j++; if (newsgroups->length > 0) buf_appends(newsgroups, ","); buf_append(newsgroups, line->data + j, line->length - j); } } else { if (to->length > 0) buf_appends(to, ","); buf_cat(to, line); } } if (to->length > 0) { buf_appends(out, "To: "); buf_cat(out, to); buf_nl(out); } if (newsgroups->length > 0) { buf_appends(out, "Newsgroups: "); buf_cat(out, newsgroups); buf_nl(out); } n = buf_getc(body); for (i = 0; i < n; i++) { buf_get(body, line, 80); buf_chop(line); if (bufileft(line, "Subject:")) subject = 1; buf_cat(out, line); buf_nl(out); } buf_rest(temp, body); buf_uncompress(temp); buf_set(body, temp); buf_reset(temp); if (buf_lookahead(body, line) == 0 && isline(line, HASHMARK)) { buf_getline(body, line); while (buf_getline(body, line) == 0) { if (bufileft(line, "subject:")) subject = 1; buf_cat(out, line); buf_nl(out); } } if (type == MSG_POST && !subject) buf_appends(out, "Subject: (no subject)\n"); buf_nl(out); buf_rest(out, body); buf_reset(body); mix_pool(out, type, -1); end: buf_free(line); buf_free(to); buf_free(newsgroups); buf_free(temp); buf_free(out); return (0); }
int mix2_decrypt(BUFFER *m) /* 0: ok * -1: error * -2: old message */ { int err = 0; int i,rsalen,rsalen_as_byte; BUFFER *privkey; BUFFER *keyid; BUFFER *dec, *deskey; BUFFER *packetid, *mid, *digest, *addr, *temp, *iv, *ivvec; int type, packet = 0, numpackets = 0, timestamp = 0; BUFFER *body; BUFFER *header, *out; BUFFER *otherdigest, *bodydigest, *antitag, *extract; BUFFER *ttedigest, *hkey, *aes_pre_key, *aes_header_key, *aes_body_key, *aes_tte_key, *aes_iv; BUFFER *trail; privkey = buf_new(); keyid = buf_new(); dec = buf_new(); deskey = buf_new(); packetid = buf_new(); mid = buf_new(); digest = buf_new(); addr = buf_new(); temp = buf_new(); iv = buf_new(); ivvec = buf_new(); body = buf_new(); header = buf_new(); out = buf_new(); otherdigest = buf_new(); bodydigest = buf_new(); antitag = buf_new(); extract = buf_new(); ttedigest = buf_new(); hkey = buf_new(); aes_pre_key = buf_new(); aes_header_key = buf_new(); aes_body_key = buf_new(); aes_tte_key = buf_new(); aes_iv = buf_new(); trail=buf_new(); aes_pre_key->sensitive=1; aes_body_key->sensitive=1; aes_tte_key->sensitive=1; dec->sensitive=1; deskey->sensitive=1; extract->sensitive=1; hkey->sensitive=1; privkey->sensitive=1; buf_get(m, keyid, 16); err = db_getseckey(keyid->data, privkey); if (err == -1) { errlog(WARNING, "rem2.c mix2_decrypt not found keyid %s\n", showdata(keyid,0)); goto end; } rsalen_as_byte=buf_getc(m); switch(rsalen_as_byte) { case 128: /* legacy 1024-bit */ rsalen_as_byte=1; rsalen=128; break; case 2: rsalen_as_byte=2; rsalen=256; break; case 3: rsalen_as_byte=3; rsalen=384; break; case 4: rsalen_as_byte=4; rsalen=512; break; default: err = -1; errlog(NOTICE, "problem with RSA key size encoded as %d\n", rsalen_as_byte); goto end; break; } assert(128==rsalen || 256==rsalen || 384==rsalen || 512==rsalen); buf_get(m, extract, rsalen); /* 3DES key and maybe more */ err = pk_decrypt(extract, privkey); if (err == -1) { err = -1; errlog(NOTICE, "Cannot decrypt message.\n"); goto end; } buf_append(body, m->data + 20 * 512, 10240); buf_get(m, iv, 8); buf_get(m, dec, 328); if (128==rsalen) { if (extract->length != 24) { err = -1; errlog(NOTICE, "Cannot decrypt message - RSA 1024 data has wrong length %d not 24.\n", extract->length); /* If this length is greater someone may have wrongly sent digests under 1k RSA. */ goto end; } buf_cat(deskey, extract); } else { if (extract->length != 216) { err = -1; errlog(NOTICE, "Cannot decrypt message - RSA (large key) data has wrong length %d.\n", extract->length); /* supposed to be: * 3DES * hmac key * hmac-sha256(18*512 headers) * hmac-sha256(body) * hmac-sha256(328-block) * aes_pre_key */ goto end; } /* antitagging measure */ buf_get(extract, deskey, 24); buf_get(extract, hkey, 64); buf_get(extract, otherdigest, 32); buf_get(extract, bodydigest, 32); buf_get(extract, ttedigest, 32); buf_get(extract, aes_pre_key, 32); buf_reset(temp); hmac_sha256(body, hkey, temp); if (!buf_eq(bodydigest, temp)) { errlog(NOTICE, "Antitagging test - wrong digest on body.\n"); err = -1; goto end; } buf_reset(temp); hmac_sha256(dec, hkey, temp); if (!buf_eq(ttedigest, temp)) { errlog(NOTICE, "Antitagging test - wrong digest on 328-block.\n"); err = -1; goto end; } /* There is one more test applicable if packet type is 0. */ derive_aes_keys(aes_pre_key, hkey, aes_header_key, aes_body_key, aes_tte_key, aes_iv); buf_aescrypt(dec, aes_tte_key, aes_iv, DECRYPT); } buf_crypt(dec, deskey, iv, DECRYPT); buf_get(dec, packetid, 16); buf_get(dec, deskey, 24); type = buf_getc(dec); switch (type) { case 0: if (rsalen>=256) { buf_append(antitag, m->data + 2*512, 2*512); buf_reset(temp); hmac_sha256(antitag, hkey, temp); if (!buf_eq(otherdigest, temp)) { errlog(NOTICE, "Antitagging test - wrong digest on later header\n"); err = -1; goto end; } } buf_get(dec, ivvec, 152); buf_get(dec, addr, 80); break; case 1: buf_get(dec, mid, 16); buf_get(dec, iv, 8); break; case 2: packet = buf_getc(dec); numpackets = buf_getc(dec); buf_get(dec, mid, 16); buf_get(dec, iv, 8); break; default: errlog(WARNING, "Unknown message type.\n"); err = -1; goto end; } if (dec->data[dec->ptr] == '0' && dec->data[dec->ptr + 1] == '0' && dec->data[dec->ptr + 2] == '0' && dec->data[dec->ptr + 3] == '0' && dec->data[dec->ptr + 4] == '\0') { dec->ptr += 5; timestamp = buf_geti_lo(dec); } else { errlog(LOG, "Ignoring message without timestamp.\n"); err = -1; goto end; } buf_get(dec, digest, 16); /* digest of this block, but not so far as to include the digest */ dec->length = dec->ptr - 16; /* ignore digest */ dec->ptr = dec->length; /* If using 1024-bit RSA this is the only integrity protection. (It is still present but less important with larger key sizes.) if (!isdigest_md5(dec, digest)) { errlog(NOTICE, "Message digest does not match.\n"); err = -1; goto end; } /* Statistics are gathered in the isnewid() function. */ switch (isnewid(packetid, rsalen_as_byte, timestamp * SECONDSPERDAY)) { case 0: err = -2; /* redundant message */ goto end; case -1: err = -1; /* future timestamp */ goto end; } if (rsalen == 128) { /* skip either 1 or 2 blocks of 512 bytes */ buf_append(trail, m->data + 512, 19*512); } else { /* and AES */ buf_aescrypt(body, aes_body_key, aes_iv, DECRYPT); buf_append(trail, m->data + 2*512, 19*512); buf_aescrypt(trail, aes_header_key, aes_iv, DECRYPT); } switch (type) { case 0: buf_chop(addr); buf_cat(out, addr); buf_nl(out); for (i = 0; i < 19; i++) { buf_reset(header); buf_append(header, trail->data + i * 512, 512); buf_reset(iv); buf_append(iv, ivvec->data + i * 8, 8); buf_crypt(header, deskey, iv, DECRYPT); buf_cat(out, header); } buf_reset(header); buf_pad(header, 512); /* one block of 512 random data regardless of RSA key size */ buf_cat(out, header); buf_reset(iv); buf_append(iv, ivvec->data + 144, 8); buf_crypt(body, deskey, iv, DECRYPT); buf_cat(out, body); mix_pool(out, INTERMEDIATE, -1); break; case 1: buf_crypt(body, deskey, iv, DECRYPT); err = v2body_setlen(body); if (err == -1) goto end; assert(body->ptr == 4); v2body(body); break; case 2: buf_crypt(body, deskey, iv, DECRYPT); v2partial(body, mid, packet, numpackets); break; } end: buf_free(addr); buf_free(aes_body_key); buf_free(aes_header_key); buf_free(aes_iv); buf_free(aes_pre_key); buf_free(aes_tte_key); buf_free(antitag); buf_free(body); buf_free(bodydigest); buf_free(dec); buf_free(deskey); buf_free(digest); buf_free(extract); buf_free(header); buf_free(hkey); buf_free(iv); buf_free(ivvec); buf_free(keyid); buf_free(mid); buf_free(otherdigest); buf_free(out); buf_free(packetid); buf_free(privkey); buf_free(temp); buf_free(trail); buf_free(ttedigest); return (err); }
int pgp_keymgt(int force) { FILE *f = NULL; BUFFER *key, *keybak, *userid, *out, *outkey, *outtxt, *pass, *secout; KEYRING *keys; int err = 0, res, recreate_pubring = 0, dsa_ok = 0; #ifdef USE_IDEA int rsa_ok = 0; #endif /* USE_IDEA */ long expires; LOCK *seclock; key = buf_new(); out = buf_new(); keybak = buf_new(); secout = buf_new(); userid = buf_new(); buf_sets(userid, REMAILERNAME); pass = buf_new(); buf_sets(pass, PASSPHRASE); outtxt = buf_new(); outkey = buf_new(); /* We only want to build RSA keys if we also can do IDEA * This is to not lose any mail should users try our RSA key * with IDEA. */ #ifdef USE_IDEA /* FIXME: pgpdb_getky returns the expiration date from the last key in the keyring * which probably works most of the time if the keys are in the correct order * it doesn't return the latest expiration date (or 0) if the key in question * is before another matching key in the keyring tho */ res = pgpdb_getkey(PK_DECRYPT, PGP_ES_RSA, NULL, NULL, &expires, NULL, NULL, NULL, NULL, NULL, pass); if (force == 2 || res < 0 || (expires > 0 && expires - KEYOVERLAPPERIOD < time(NULL))) { rsa_ok = -1; pgp_keygen(PGP_ES_RSA, 0, userid, pass, PGPKEY, PGPREMSECRING, 0); }; if (force == 0 && (pgpdb_getkey(PK_ENCRYPT, PGP_ES_RSA, NULL, NULL, NULL, NULL, NULL, NULL, NULL, PGPKEY, NULL) < 0) && rsa_ok == 0) rsa_ok = 1; #endif /* USE_IDEA */ /* FIXME: pgpdb_getky returns the expiration date from the last key in the keyring * which probably works most of the time if the keys are in the correct order * it doesn't return the latest expiration date (or 0) if the key in question * is before another matching key in the keyring tho */ res = pgpdb_getkey(PK_DECRYPT, PGP_E_ELG, NULL, NULL, &expires, NULL, NULL, NULL, NULL, NULL, pass); if (force == 2 || res < 0 || (expires > 0 && expires - KEYOVERLAPPERIOD < time(NULL))) { dsa_ok = -1; pgp_keygen(PGP_E_ELG, 0, userid, pass, PGPKEY, PGPREMSECRING, 0); } if (force == 0 && (pgpdb_getkey(PK_ENCRYPT, PGP_E_ELG, NULL, NULL, NULL, NULL, NULL, NULL, NULL, PGPKEY, NULL) > 0) && dsa_ok == 0) dsa_ok = 1; /* No need to rewrite the files - we didn't change a thing */ if ( #ifdef USE_IDEA rsa_ok == 1 && #endif /* USE_IDEA */ dsa_ok == 1) goto end; /* write keys one key per armor to make hand editing easy and old PGP * versions happy */ err = -1; keys = pgpdb_open(PGPKEY, NULL, 0, PGP_TYPE_PUBLIC); if (keys == NULL) recreate_pubring = 1; else { while (pgpdb_getnext(keys, key, NULL, userid) != -1) { buf_clear(outtxt); if (pgp_makekeyheader(PGP_PUBKEY, key, outtxt, NULL, PGP_ANY) == 0) { err = 0; buf_appends(out, "Type Bits/KeyID Date User ID\n"); buf_cat(out, outtxt); buf_nl(out); pgp_armor(key, PGP_ARMOR_KEY); buf_cat(out, key); buf_nl(out); } } pgpdb_close(keys); } if (err != 0) recreate_pubring = 1; err = -1; keys = pgpdb_open(PGPREMSECRING, NULL, 0, PGP_TYPE_PRIVATE); if (keys == NULL) goto end; while (pgpdb_getnext(keys, key, NULL, userid) != -1) { buf_clear(outtxt); buf_clear(outkey); buf_clear(keybak); buf_cat(keybak, key); if (pgp_makekeyheader(PGP_SECKEY, key, outtxt, pass, PGP_ANY) == 0) { err = 0; buf_appends(secout, "Type Bits/KeyID Date User ID\n"); buf_cat(secout, outtxt); buf_nl(secout); pgp_armor(key, PGP_ARMOR_SECKEY); buf_cat(secout, key); buf_nl(secout); } buf_clear(outtxt); if (recreate_pubring && pgp_makepubkey(keybak, outtxt, outkey, pass, PGP_ANY) == 0) { buf_appends(out, "Type Bits/KeyID Date User ID\n"); buf_cat(out, outtxt); buf_nl(out); pgp_armor(outkey, PGP_ARMOR_KEY); buf_cat(out, outkey); buf_nl(out); } } pgpdb_close(keys); seclock = lockfile(PGPREMSECRING); if (err == 0 && (f = mix_openfile(PGPREMSECRING, "w")) != NULL) { buf_write(secout, f); fclose(f); } else err = -1; unlockfile(seclock); if (err == 0 && (f = mix_openfile(PGPKEY, "w")) != NULL) { buf_write(out, f); fclose(f); } else err = -1; end: buf_free(key); buf_free(keybak); buf_free(out); buf_free(userid); buf_free(pass); buf_free(outtxt); buf_free(outkey); buf_free(secout); return (err); }
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_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); }
void motopp_freeFrame(MotoPP *ppenv) { MotoPPFrame *frame; Enumeration *e; if (stack_size(ppenv->frames) <= 1) { frame = stack_pop(ppenv->frames); buf_cat(ppenv->out, frame->out); ppenv->frame = NULL; } else { MotoPPVal *val; MotoPPFrame *pframe; SymbolTable *macros; MotoMacro *m; char *catstr; int catstrlen; frame = stack_pop(ppenv->frames); pframe = stack_peek(ppenv->frames); switch (frame->type) { case MACRO_FRAME: m = frame->macro; val = motopp_createVal(ppenv); if (ppenv->flags & MACRO_DEBUG_FLAG) { buf_printf(frame->out, LINE_FMT_2, pframe->filename, pframe->lineno); } val->sval = buf_toString(frame->out); stack_push(pframe->opstack, val); macros = stack_pop(ppenv->macrostack); e = stab_getKeys(macros); while (enum_hasNext(e)) { char *name = (char *)enum_next(e); MotoMacro *m = (MotoMacro *)stab_get(macros, name); motopp_freeMacro(m); } stab_free(macros); enum_free(e); break; case INCLUDE_FRAME: catstr = buf_data(frame->out); catstrlen = strlen(catstr); if (catstr[catstrlen - 1] == '\n') { catstr[catstrlen - 1] = '\0'; } buf_puts(pframe->out, catstr); if (ppenv->flags & MACRO_DEBUG_FLAG) { buf_printf(pframe->out, LINE_FMT_2, pframe->filename, pframe->lineno); } break; default: buf_cat(pframe->out, frame->out); break; } /* reset pplineno */ pplineno = pframe->lineno; /* reset frame */ ppenv->frame = pframe; } if (frame->yybuf != NULL) { if (shared_check(frame->yybuf)) { motopp_freeYYBuffer(frame->yybuf); } } if (frame->yybufmem != NULL) { free(frame->yybufmem); } buf_free(frame->out); stack_free(frame->opstack); free(frame->filename); free(frame->relative_root); free(frame); }
void moto_freeFrame(MotoEnv *env) { MotoFrame *frame = env->frame; MotoFrame *pframe = NULL; StringBuffer *pout = NULL; Enumeration *e; /* Append declarations if in compiler mode and not in a function frame*/ if (env->mode == COMPILER_MODE && frame->type != FN_FRAME) { if (frame->type == MAIN_FRAME) pout = env->out; else if(frame->type == SUB_FRAME) pout = ((MotoFrame *)vec_get(env->frames, env->frameindex - 1))->out; e = stab_getKeys(frame->symtab); while (enum_hasNext(e)) { int indent = env->frameindex+1; char* n = (char*)enum_next(e); MotoVar* mv = (MotoVar*)stab_get(frame->symtab,n); while (--indent >= 0) buf_puts(pout, " "); buf_printf(pout,"%s %s=%s;\n", moto_valToCType(mv->vs), n,moto_defaultValForCType(mv->vs)); } enum_free(e); buf_puts(pout, "\n"); if (frame->type == MAIN_FRAME) /* FIXME : big hack to get out buffer set for functions */ buf_printf(pout,"out = outputBuffer;\n"); } switch (frame->type) { case MAIN_FRAME: /* append buffer from frame to env main buffer */ pout = env->out; buf_cat(pout, frame->out); break; case FN_FRAME: if (env->mode != COMPILER_MODE) { /* append buffer from frame current function buffer */ pframe = (MotoFrame *)vec_get(env->frames, env->frameindex - 1); buf_cat(pframe->out, frame->out); } else { /* append buffer from frame current function buffer */ buf_cat(env->fcodebuffer, frame->out); } break; case SUB_FRAME: default: /* append buffer from frame to buffer in parent frame */ pframe = (MotoFrame *)vec_get(env->frames, env->frameindex - 1); buf_cat(pframe->out, frame->out); break; } /* Release the frame's output buffer */ opool_release(env->bufpool,frame->out); /* Free frame structure */ opool_release(env->stkpool,frame->opstack); /* Free vars and associated vals */ e = stab_getKeys(frame->symtab); while (enum_hasNext(e)) { char* n = (char*)enum_next(e); MotoVar* var = (MotoVar*)stab_get(frame->symtab,n); /* Do not free vars that are class member vars */ if(env->mode != COMPILER_MODE) { moto_freeVal(env,var->vs); } else { opool_release(env->valpool,var->vs); } free(var); } enum_free(e); stab_free(frame->symtab); /* set new frame */ vec_removeAt(env->frames, env->frameindex); env->frameindex = env->frameindex - 1; if(env->frameindex < 0) env->frame = NULL; else env->frame = vec_get(env->frames, env->frameindex); free(frame); }