/[pkg-mixmaster]/trunk/Mix/Src/chain1.c
ViewVC logotype

Contents of /trunk/Mix/Src/chain1.c

Parent Directory Parent Directory | Revision Log Revision Log


Revision 1012 - (hide annotations) (download)
Fri Dec 11 19:47:17 2009 UTC (3 years, 5 months ago) by zax-guest
File MIME type: text/plain
File size: 8565 byte(s)
Add hsub capability.  One less IDEA dependency!
1 rabbi 934 /* Mixmaster version 3.0 -- (C) 1999 - 2006 Anonymizer Inc. and others.
2 rabbi 1
3     Mixmaster may be redistributed and modified under certain conditions.
4     This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF
5     ANY KIND, either express or implied. See the file COPYRIGHT for
6     details.
7    
8     Encrypt message for Cypherpunk remailer chain
9 weasel 647 $Id$ */
10 rabbi 1
11    
12     #include "mix3.h"
13     #include "pgp.h"
14     #include <string.h>
15     #include <ctype.h>
16    
17     #define N(X) (isdigit(X) ? (X)-'0' : 0)
18    
19 weaselp 500 int t1_rlist(REMAILER remailer[], int badchains[MAXREM][MAXREM])
20 rabbi 1 {
21 weaselp 387 FILE *list, *excl;
22 rabbi 1 int i, listed = 0;
23     int n = 0;
24     char line[2 * LINELEN], l2[LINELEN], name[LINELEN], *flags;
25 weaselp 387 BUFFER *starex;
26 rabbi 1
27 weaselp 387 starex = buf_new();
28     excl = mix_openfile(STAREX, "r");
29     if (excl != NULL) {
30     buf_read(starex, excl);
31     fclose(excl);
32     }
33    
34 rabbi 1 list = mix_openfile(TYPE1LIST, "r");
35 weaselp 387 if (list == NULL) {
36     buf_free(starex);
37 rabbi 1 return (-1);
38 weaselp 387 }
39    
40 rabbi 1 while (fgets(line, sizeof(line), list) != NULL && n < MAXREM) {
41     if (strleft(line, "$remailer") &&
42     strchr(line, '<') && strchr(line, '>') &&
43     strchr(line, '{') && strchr(line, '{') + 4 < strchr(line, '}')) {
44     if (line[strlen(line) - 1] == '\n')
45     line[strlen(line) - 1] = '\0';
46     if (line[strlen(line) - 1] == '\r')
47     line[strlen(line) - 1] = '\0';
48     while (line[strlen(line) - 1] == ' ')
49     line[strlen(line) - 1] = '\0';
50     if (line[strlen(line) - 1] != ';'
51     && fgets(l2, sizeof(l2), list) != NULL)
52     strcatn(line, l2, LINELEN);
53     flags = strchr(line, '>');
54     strncpy(name, strchr(line, '{') + 2,
55     strchr(line, '}') - strchr(line, '{') - 3);
56     name[strchr(line, '}') - strchr(line, '{') - 3] = '\0';
57     name[20] = '\0';
58    
59     for (i = 1; i <= n; i++)
60     if (streq(name, remailer[i].name))
61     break;
62     if (i > n) {
63     /* not in mix list */
64     n++;
65     strcpy(remailer[i].name, name);
66     strncpy(remailer[i].addr, strchr(line, '<') + 1,
67     strchr(line, '>') - strchr(line, '<'));
68     remailer[i].addr[strchr(line, '>') - strchr(line, '<') - 1]
69     = '\0';
70     remailer[i].flags.mix = 0;
71     remailer[i].flags.post = strifind(flags, " post");
72     }
73     remailer[i].flags.cpunk = strfind(flags, " cpunk");
74     remailer[i].flags.pgp = strfind(flags, " pgp");
75     remailer[i].flags.pgponly = strfind(flags, " pgponly");
76     remailer[i].flags.latent = strfind(flags, " latent");
77     remailer[i].flags.middle = strfind(flags, " middle");
78     remailer[i].flags.ek = strfind(flags, " ek");
79     remailer[i].flags.esub = strfind(flags, " esub");
80 zax-guest 1012 remailer[i].flags.hsub = strfind(flags, " hsub");
81 rabbi 1 remailer[i].flags.newnym = strfind(flags, " newnym");
82     remailer[i].flags.nym = strfind(flags, " nym");
83     remailer[i].info[1].reliability = 0;
84     remailer[i].info[1].latency = 0;
85     remailer[i].info[1].history[0] = '\0';
86 weaselp 387 remailer[i].flags.star_ex = bufifind(starex, name);
87     }
88 rabbi 1 if (strleft(line,
89     "-----------------------------------------------------------------------"))
90     break;
91     }
92     n++; /* ?? */
93     while (fgets(line, sizeof(line), list) != NULL) {
94     if (strlen(line) >= 72 && strlen(line) <= 73)
95     for (i = 1; i < n; i++)
96     if (strleft(line, remailer[i].name) &&
97     line[strlen(remailer[i].name)] == ' ') {
98     strncpy(remailer[i].info[1].history, line + 42, 12);
99     remailer[i].info[1].history[12] = '\0';
100     remailer[i].info[1].reliability = 10000 * N(line[64])
101     + 1000 * N(line[65]) + 100 * N(line[66])
102     + 10 * N(line[68]) + N(line[69]);
103     remailer[i].info[1].latency = 36000 * N(line[55])
104     + 3600 * N(line[56]) + 600 * N(line[58])
105     + 60 * N(line[59]) + 10 * N(line[61])
106     + N(line[62]);
107     listed++;
108     }
109     }
110     fclose(list);
111 weaselp 500 parse_badchains(badchains, TYPE1LIST, "Broken type-I remailer chains", remailer, n);
112 rabbi 1 if (listed < 4) /* we have no valid reliability info */
113     for (i = 1; i < n; i++)
114     remailer[i].info[1].reliability = 10000;
115    
116     #ifdef USE_PGP
117     pgp_rlist(remailer, n);
118 rabbi 262 #endif /* USE_PGP */
119 weaselp 387 buf_free(starex);
120 rabbi 1 return (n);
121     }
122    
123     int t1_ek(BUFFER *key, BUFFER *seed, int num)
124     {
125     buf_reset(key);
126     buf_appendc(key, (byte) num);
127     buf_cat(key, seed);
128     digest_md5(key, key);
129     encode(key, 0);
130     #ifdef DEBUG
131     fprintf(stderr, "passphrase=%s (%2X%2X%2X%2X %d)\n", key->data,
132     seed->data[0], seed->data[1], seed->data[2], seed->data[3], num);
133 rabbi 262 #endif /* DEBUG */
134 weaselp 332 return (0);
135 rabbi 1 }
136    
137     int t1_encrypt(int type, BUFFER *message, char *chainstr, int latency,
138     BUFFER *ek, BUFFER *feedback)
139     {
140     BUFFER *b, *rem, *dest, *line, *field, *content;
141     REMAILER remailer[MAXREM];
142 weaselp 500 int badchains[MAXREM][MAXREM];
143 rabbi 1 int maxrem, chainlen = 0;
144     int chain[20];
145     int hop;
146     int hashmark = 0;
147     int err = 0;
148    
149     b = buf_new();
150     rem = buf_new();
151     dest = buf_new();
152     line = buf_new();
153     field = buf_new();
154     content = buf_new();
155    
156 weaselp 500 maxrem = t1_rlist(remailer, badchains);
157 rabbi 1 if (maxrem < 1) {
158     clienterr(feedback, "No remailer list!");
159     err = -1;
160     goto end;
161     }
162     chainlen = chain_select(chain, chainstr, maxrem, remailer, 1, line);
163     if (chainlen < 1) {
164     if (line->length)
165     clienterr(feedback, line->data);
166     else
167     clienterr(feedback, "Invalid remailer chain!");
168     err = -1;
169     goto end;
170     }
171     if (chain[0] == 0)
172 weaselp 592 chain[0] = chain_randfinal(type, remailer, badchains, maxrem, 1, chain, chainlen, 0);
173 rabbi 1
174     if (chain[0] == -1) {
175     clienterr(feedback, "Invalid remailer chain!");
176     err = -1;
177     goto end;
178     }
179 weaselp 592 if (chain_rand(remailer, badchains, maxrem, chain, chainlen, 1, 0) == -1) {
180 rabbi 1 clienterr(feedback, "No reliable remailers!");
181     err = -1;
182     goto end;
183     }
184     while (buf_getheader(message, field, content) == 0) {
185     hdr_encode(content, 0);
186     if (type == MSG_POST && bufieq(field, "newsgroups") &&
187     remailer[chain[0]].flags.post) {
188     buf_appendf(dest, "Anon-Post-To: %b\n", content);
189     } else if (type == MSG_MAIL && bufieq(field, "to")) {
190     buf_appendf(dest, "Anon-To: %b\n", content);
191     } else {
192     /* paste header */
193     if (type == MSG_POST && bufieq(field, "newsgroups"))
194     buf_appendf(dest, "Anon-To: %s\n", MAILtoNEWS);
195     if (hashmark == 0) {
196     buf_appends(b, "##\n");
197     hashmark = 1;
198     }
199     buf_appendheader(b, field, content);
200     }
201     }
202     buf_nl(b);
203     buf_rest(b, message);
204     buf_move(message, b);
205    
206     if (type != MSG_NULL && dest->length == 0) {
207     clienterr(feedback, "No destination address!");
208     err = -1;
209     goto end;
210     }
211     if (type == MSG_NULL) {
212     buf_sets(dest, "Null:\n");
213     }
214     for (hop = 0; hop < chainlen; hop++) {
215     if (hop == 0) {
216     buf_sets(b, "::\n");
217     buf_cat(b, dest);
218     } else {
219     buf_sets(b, "::\nAnon-To: ");
220     buf_appends(b, remailer[chain[hop - 1]].addr);
221     buf_nl(b);
222     }
223     if (remailer[chain[hop]].flags.latent && latency > 0)
224     buf_appendf(b, "Latent-Time: +%d:00r\n", latency);
225     if (ek && remailer[chain[hop]].flags.ek) {
226     t1_ek(line, ek, hop);
227     buf_appendf(b, "Encrypt-Key: %b\n", line);
228     }
229     buf_nl(b);
230     buf_cat(b, message);
231     #ifdef USE_PGP
232     if (remailer[chain[hop]].flags.pgp) {
233     buf_clear(message);
234     buf_clear(rem);
235     buf_setf(rem, "<%s>", remailer[chain[hop]].addr);
236     err = pgp_encrypt(PGP_ENCRYPT | PGP_REMAIL | PGP_TEXT, b, rem,
237     NULL, NULL, NULL, NULL);
238     if (err < 0) {
239     buf_setf(line, "No PGP key for remailer %s!\n",
240     remailer[chain[hop]].name);
241     clienterr(feedback, line->data);
242     goto end;
243     }
244     buf_appends(message, "::\nEncrypted: PGP\n\n");
245     buf_cat(message, b);
246     } else
247 rabbi 262 #endif /* USE_PGP */
248 rabbi 1 {
249     if (remailer[chain[hop]].flags.pgponly) {
250     buf_setf(line, "PGP encryption needed for remailer %s!\n",
251     remailer[chain[hop]].name);
252     clienterr(feedback, line->data);
253     goto end;
254     }
255     buf_move(message, b);
256     }
257     if (ek && remailer[chain[hop]].flags.ek)
258     buf_appends(message, "\n**\n");
259     }
260     buf_clear(b);
261     if (chainlen == 0) {
262     buf_appends(b, "::\n");
263     buf_cat(b, dest);
264     } else {
265 rabbi 40 buf_appendf(b, "%s: %s\n", ek ? "::\nAnon-To" : "To",
266 rabbi 1 remailer[chain[chainlen - 1]].addr);
267     }
268     buf_nl(b);
269     buf_cat(b, message);
270     buf_move(message, b);
271     end:
272     buf_free(b);
273     buf_free(rem);
274     buf_free(dest);
275     buf_free(line);
276     buf_free(field);
277     buf_free(content);
278     return (err);
279     }
280    
281     #ifdef USE_PGP
282     int t1_getreply(BUFFER *msg, BUFFER *ek, int len)
283     {
284     BUFFER *key, *decrypt;
285     int err = -1;
286     int hop = 0;
287    
288     key = buf_new();
289     decrypt = buf_new();
290    
291     do {
292     t1_ek(key, ek, hop);
293     buf_set(decrypt, msg);
294     if (pgp_decrypt(decrypt, key, NULL, NULL, NULL) == 0
295     && decrypt->data != NULL)
296     err = 0, buf_move(msg, decrypt);
297     }
298     while (hop++ < len);
299     return (err);
300     }
301    
302 rabbi 262 #endif /* USE_PGP */

Properties

Name Value
svn:keywords Id

  ViewVC Help
Powered by ViewVC 1.1.5