/[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 934 - (hide annotations) (download)
Sat Jun 24 13:40:39 2006 UTC (6 years, 10 months ago) by rabbi
File MIME type: text/plain
File size: 8509 byte(s)
Updated copyright dates.
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     remailer[i].flags.newnym = strfind(flags, " newnym");
81     remailer[i].flags.nym = strfind(flags, " nym");
82     remailer[i].info[1].reliability = 0;
83     remailer[i].info[1].latency = 0;
84     remailer[i].info[1].history[0] = '\0';
85 weaselp 387 remailer[i].flags.star_ex = bufifind(starex, name);
86     }
87 rabbi 1 if (strleft(line,
88     "-----------------------------------------------------------------------"))
89     break;
90     }
91     n++; /* ?? */
92     while (fgets(line, sizeof(line), list) != NULL) {
93     if (strlen(line) >= 72 && strlen(line) <= 73)
94     for (i = 1; i < n; i++)
95     if (strleft(line, remailer[i].name) &&
96     line[strlen(remailer[i].name)] == ' ') {
97     strncpy(remailer[i].info[1].history, line + 42, 12);
98     remailer[i].info[1].history[12] = '\0';
99     remailer[i].info[1].reliability = 10000 * N(line[64])
100     + 1000 * N(line[65]) + 100 * N(line[66])
101     + 10 * N(line[68]) + N(line[69]);
102     remailer[i].info[1].latency = 36000 * N(line[55])
103     + 3600 * N(line[56]) + 600 * N(line[58])
104     + 60 * N(line[59]) + 10 * N(line[61])
105     + N(line[62]);
106     listed++;
107     }
108     }
109     fclose(list);
110 weaselp 500 parse_badchains(badchains, TYPE1LIST, "Broken type-I remailer chains", remailer, n);
111 rabbi 1 if (listed < 4) /* we have no valid reliability info */
112     for (i = 1; i < n; i++)
113     remailer[i].info[1].reliability = 10000;
114    
115     #ifdef USE_PGP
116     pgp_rlist(remailer, n);
117 rabbi 262 #endif /* USE_PGP */
118 weaselp 387 buf_free(starex);
119 rabbi 1 return (n);
120     }
121    
122     int t1_ek(BUFFER *key, BUFFER *seed, int num)
123     {
124     buf_reset(key);
125     buf_appendc(key, (byte) num);
126     buf_cat(key, seed);
127     digest_md5(key, key);
128     encode(key, 0);
129     #ifdef DEBUG
130     fprintf(stderr, "passphrase=%s (%2X%2X%2X%2X %d)\n", key->data,
131     seed->data[0], seed->data[1], seed->data[2], seed->data[3], num);
132 rabbi 262 #endif /* DEBUG */
133 weaselp 332 return (0);
134 rabbi 1 }
135    
136     int t1_encrypt(int type, BUFFER *message, char *chainstr, int latency,
137     BUFFER *ek, BUFFER *feedback)
138     {
139     BUFFER *b, *rem, *dest, *line, *field, *content;
140     REMAILER remailer[MAXREM];
141 weaselp 500 int badchains[MAXREM][MAXREM];
142 rabbi 1 int maxrem, chainlen = 0;
143     int chain[20];
144     int hop;
145     int hashmark = 0;
146     int err = 0;
147    
148     b = buf_new();
149     rem = buf_new();
150     dest = buf_new();
151     line = buf_new();
152     field = buf_new();
153     content = buf_new();
154    
155 weaselp 500 maxrem = t1_rlist(remailer, badchains);
156 rabbi 1 if (maxrem < 1) {
157     clienterr(feedback, "No remailer list!");
158     err = -1;
159     goto end;
160     }
161     chainlen = chain_select(chain, chainstr, maxrem, remailer, 1, line);
162     if (chainlen < 1) {
163     if (line->length)
164     clienterr(feedback, line->data);
165     else
166     clienterr(feedback, "Invalid remailer chain!");
167     err = -1;
168     goto end;
169     }
170     if (chain[0] == 0)
171 weaselp 592 chain[0] = chain_randfinal(type, remailer, badchains, maxrem, 1, chain, chainlen, 0);
172 rabbi 1
173     if (chain[0] == -1) {
174     clienterr(feedback, "Invalid remailer chain!");
175     err = -1;
176     goto end;
177     }
178 weaselp 592 if (chain_rand(remailer, badchains, maxrem, chain, chainlen, 1, 0) == -1) {
179 rabbi 1 clienterr(feedback, "No reliable remailers!");
180     err = -1;
181     goto end;
182     }
183     while (buf_getheader(message, field, content) == 0) {
184     hdr_encode(content, 0);
185     if (type == MSG_POST && bufieq(field, "newsgroups") &&
186     remailer[chain[0]].flags.post) {
187     buf_appendf(dest, "Anon-Post-To: %b\n", content);
188     } else if (type == MSG_MAIL && bufieq(field, "to")) {
189     buf_appendf(dest, "Anon-To: %b\n", content);
190     } else {
191     /* paste header */
192     if (type == MSG_POST && bufieq(field, "newsgroups"))
193     buf_appendf(dest, "Anon-To: %s\n", MAILtoNEWS);
194     if (hashmark == 0) {
195     buf_appends(b, "##\n");
196     hashmark = 1;
197     }
198     buf_appendheader(b, field, content);
199     }
200     }
201     buf_nl(b);
202     buf_rest(b, message);
203     buf_move(message, b);
204    
205     if (type != MSG_NULL && dest->length == 0) {
206     clienterr(feedback, "No destination address!");
207     err = -1;
208     goto end;
209     }
210     if (type == MSG_NULL) {
211     buf_sets(dest, "Null:\n");
212     }
213     for (hop = 0; hop < chainlen; hop++) {
214     if (hop == 0) {
215     buf_sets(b, "::\n");
216     buf_cat(b, dest);
217     } else {
218     buf_sets(b, "::\nAnon-To: ");
219     buf_appends(b, remailer[chain[hop - 1]].addr);
220     buf_nl(b);
221     }
222     if (remailer[chain[hop]].flags.latent && latency > 0)
223     buf_appendf(b, "Latent-Time: +%d:00r\n", latency);
224     if (ek && remailer[chain[hop]].flags.ek) {
225     t1_ek(line, ek, hop);
226     buf_appendf(b, "Encrypt-Key: %b\n", line);
227     }
228     buf_nl(b);
229     buf_cat(b, message);
230     #ifdef USE_PGP
231     if (remailer[chain[hop]].flags.pgp) {
232     buf_clear(message);
233     buf_clear(rem);
234     buf_setf(rem, "<%s>", remailer[chain[hop]].addr);
235     err = pgp_encrypt(PGP_ENCRYPT | PGP_REMAIL | PGP_TEXT, b, rem,
236     NULL, NULL, NULL, NULL);
237     if (err < 0) {
238     buf_setf(line, "No PGP key for remailer %s!\n",
239     remailer[chain[hop]].name);
240     clienterr(feedback, line->data);
241     goto end;
242     }
243     buf_appends(message, "::\nEncrypted: PGP\n\n");
244     buf_cat(message, b);
245     } else
246 rabbi 262 #endif /* USE_PGP */
247 rabbi 1 {
248     if (remailer[chain[hop]].flags.pgponly) {
249     buf_setf(line, "PGP encryption needed for remailer %s!\n",
250     remailer[chain[hop]].name);
251     clienterr(feedback, line->data);
252     goto end;
253     }
254     buf_move(message, b);
255     }
256     if (ek && remailer[chain[hop]].flags.ek)
257     buf_appends(message, "\n**\n");
258     }
259     buf_clear(b);
260     if (chainlen == 0) {
261     buf_appends(b, "::\n");
262     buf_cat(b, dest);
263     } else {
264 rabbi 40 buf_appendf(b, "%s: %s\n", ek ? "::\nAnon-To" : "To",
265 rabbi 1 remailer[chain[chainlen - 1]].addr);
266     }
267     buf_nl(b);
268     buf_cat(b, message);
269     buf_move(message, b);
270     end:
271     buf_free(b);
272     buf_free(rem);
273     buf_free(dest);
274     buf_free(line);
275     buf_free(field);
276     buf_free(content);
277     return (err);
278     }
279    
280     #ifdef USE_PGP
281     int t1_getreply(BUFFER *msg, BUFFER *ek, int len)
282     {
283     BUFFER *key, *decrypt;
284     int err = -1;
285     int hop = 0;
286    
287     key = buf_new();
288     decrypt = buf_new();
289    
290     do {
291     t1_ek(key, ek, hop);
292     buf_set(decrypt, msg);
293     if (pgp_decrypt(decrypt, key, NULL, NULL, NULL) == 0
294     && decrypt->data != NULL)
295     err = 0, buf_move(msg, decrypt);
296     }
297     while (hop++ < len);
298     return (err);
299     }
300    
301 rabbi 262 #endif /* USE_PGP */

Properties

Name Value
svn:keywords Id

  ViewVC Help
Powered by ViewVC 1.1.5