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

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

Parent Directory Parent Directory | Revision Log Revision Log


Revision 102 - (hide annotations) (download)
Wed Jul 24 07:48:50 2002 UTC (10 years, 10 months ago) by rabbi
File MIME type: text/plain
File size: 12324 byte(s)
We have changed the compile-time option PASSPHRASE to be named
COMPILEDPASS. We have changed the configuration file option PASS_PHRASE to
be named PASSPHRASE. We have added documentation for the new configuration
file option and made changes in the man page to reflect the name change.

This was done to avoid confusion due to the similarity in names of the
options.
1 rabbi 1 /* Mixmaster version 3 -- (C) 1999 Anonymizer Inc.
2    
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     Process Cypherpunk remailer messages
9 rabbi 102 $Id: rem1.c,v 1.6 2002/07/24 07:48:50 rabbi Exp $ */
10 rabbi 1
11    
12     #include "mix3.h"
13     #include <ctype.h>
14     #include <time.h>
15     #include <string.h>
16    
17     static int t1msg(BUFFER *in, int hdr);
18    
19     int isline(BUFFER *line, char *text)
20     {
21     int i;
22    
23     if (!bufileft(line, text))
24     return (0);
25    
26     for (i = strlen(text); i < line->length; i++)
27     if (!isspace(line->data[i]))
28     return(0);
29     return(1);
30     }
31    
32     int t1_decrypt(BUFFER *in)
33     {
34     int ret;
35    
36     buf_rewind(in);
37     if (TYPE1[0] == '\0')
38     ret = t1msg(in, 1);
39     else {
40     FILE *f;
41    
42     f = openpipe(TYPE1);
43     if (f == NULL)
44     return -1;
45     buf_write(in, f);
46     ret = closepipe(f);
47     }
48     if (ret == 0)
49     stats_log(1);
50     return (ret);
51     }
52    
53     #ifdef USE_IDEA
54     void t1_esub(BUFFER *esub, BUFFER *subject)
55     {
56     BUFFER *iv, *out;
57     char hex[33];
58    
59     iv = buf_new();
60     out = buf_new();
61    
62     buf_appendrnd(iv, 8);
63     id_encode(iv->data, hex);
64     buf_append(out, hex, 16);
65    
66     digest_md5(esub, esub);
67     digest_md5(subject, subject);
68     buf_ideacrypt(subject, esub, iv, ENCRYPT);
69     id_encode(subject->data, hex);
70     buf_appends(out, hex);
71     buf_move(subject, out);
72     buf_free(iv);
73     buf_free(out);
74     }
75     #endif
76    
77     #define N(X) (isdigit(X) ? (X)-'0' : 0)
78    
79     static int readnum(BUFFER *b, int f)
80     {
81     int num = 0;
82    
83     if (b->length > 0)
84     sscanf(b->data, "%d", &num);
85     num *= f;
86     if (strchr(b->data, 'r'))
87     num = rnd_number(num) + 1;
88     return (num);
89     }
90    
91     static int t1msg(BUFFER *in, int hdr)
92     /* hdr = 1: mail header, hdr = 2: pasted header, hdr = 0: ignore */
93     {
94     BUFFER *field, *content, *line;
95     BUFFER *cutmarks, *to, *newsgroups, *ek, *ekdes, *ekcast, *esub, *subject;
96     BUFFER *temp, *header, *out;
97     BUFFER *test, *testto, *remixto;
98     int err = 0;
99     int encrypted = 0;
100     int type = -1;
101     int latent = 0;
102 rabbi 62 int remix = 0, repgp = 0;
103 rabbi 1 int inflate = 0;
104    
105     field = buf_new();
106     content = buf_new();
107     line = buf_new();
108     to = buf_new();
109     remixto = buf_new();
110     cutmarks = buf_new();
111     newsgroups = buf_new();
112     ek = buf_new();
113     ekdes = buf_new();
114     ekcast = buf_new();
115     esub = buf_new();
116     subject = buf_new();
117     temp = buf_new();
118     header = buf_new();
119     out = buf_new();
120     test = buf_new();
121     testto = buf_new();
122    
123     if (REMIX == 1)
124     remix = 2;
125     if (!UNENCRYPTED)
126     encrypted = -1;
127    
128     header:
129     while (buf_getheader(in, field, content) == 0) {
130     if (header->length == 0 && bufieq(content, ":")) /* HDRMARK */
131     hdr = 2;
132    
133     if (bufieq(field, "test-to"))
134     buf_set(testto, content);
135     else if (PGP && bufieq(field, "encrypted"))
136     encrypted = 1;
137     else if (bufieq(field, "remix-to")) {
138 rabbi 62 remix = 1; repgp = 0;
139 rabbi 1 buf_set(remixto, content);
140     if (type == -1)
141     type = MSG_MAIL;
142 rabbi 62 } else if (bufieq(field, "encrypt-to")) {
143     repgp = remix = 1;
144     buf_set(remixto, content);
145     if (type == -1)
146     type = MSG_MAIL;
147 rabbi 1 } else if (bufieq(field, "anon-to") ||
148     bufieq(field, "request-remailing-to") ||
149     bufieq(field, "remail-to") ||
150     bufieq(field, "anon-send-to")) {
151     if (bufieq(field, "remail-to"))
152 rabbi 62 repgp = remix = 0;
153 rabbi 1 if (to->length > 0)
154     buf_appendc(to, ',');
155     buf_cat(to, content);
156     if (type == -1)
157     type = MSG_MAIL;
158     } else if (bufieq(field, "anon-post-to") || bufieq(field, "post-to")) {
159     if (newsgroups->length > 0)
160     buf_appendc(newsgroups, ',');
161     buf_cat(newsgroups, content);
162     type = MSG_POST;
163     } else if (bufieq(field, "cutmarks"))
164     buf_set(cutmarks, content);
165     else if (bufieq(field, "latent-time")) {
166     byte *q;
167     int l;
168    
169     q = content->data;
170     l = strlen(q);
171     latent = 0;
172     if (q[0] == '+')
173     q++;
174     if (l >= 5 && q[2] == ':')
175     latent = 600 * N(q[0]) + 60 * N(q[1]) + 10 * N(q[3]) + N(q[4]);
176     else if (l >= 4 && q[1] == ':')
177     latent = 60 * N(q[0]) + 10 * N(q[2]) + N(q[3]);
178     else if (l >= 3 && q[0] == ':')
179     latent = 10 * N(q[1]) + N(q[2]);
180     if (!bufleft(content, "+")) {
181     time_t now;
182    
183     time(&now);
184     latent -= localtime(&now)->tm_hour * 60;
185     if (latent < 0)
186     latent += 24 * 60;
187     }
188     if (q[l - 1] == 'r')
189     latent = rnd_number(latent);
190     } else if (bufieq(field, "null"))
191     type = MSG_NULL;
192     else if (bufieq(field, "encrypt-key") || bufieq(field, "encrypt-idea"))
193     buf_set(ek, content);
194     else if (bufieq(field, "encrypt-des") || bufieq(field, "encrypt-3des"))
195     buf_set(ekdes, content);
196     else if (bufieq(field, "encrypt-cast") || bufieq(field, "encrypt-cast5"))
197     buf_set(ekcast, content);
198     else if (bufieq(field, "encrypt-subject"))
199     buf_set(esub, content);
200     else if (bufieq(field, "inflate")) {
201     inflate = readnum(content, 1024);
202     if (inflate > INFLATEMAX * 1024)
203     inflate = INFLATEMAX * 1024;
204     } else if (bufieq(field, "rand-hop")) {
205     int randhops, i;
206     randhops = readnum(content, 1);
207     if (randhops > MAXRANDHOPS)
208     randhops = MAXRANDHOPS;
209     buf_clear(temp);
210     if (remixto->length)
211     buf_move(temp, remixto);
212     for (i = 0; i < randhops; i++) {
213     if (remixto->length > 0)
214     buf_appendc(remixto, ',');
215     buf_appendc(remixto, '*');
216     }
217     if (temp->length) {
218     buf_appendc(remixto, ',');
219     buf_cat(remixto, temp);
220     }
221     }
222     #if USE_NSUB
223     else if (bufieq(field, "subject"))
224     buf_set(subject, content);
225     #endif
226     }
227    
228     if (cutmarks->length > 0) {
229     BUFFER *cut;
230    
231     cut = buf_new();
232     buf_clear(temp);
233    
234     while ((err = buf_getline(in, line)) != -1 && !buf_eq(line, cutmarks)) {
235     buf_cat(temp, line);
236     buf_nl(temp);
237     }
238     while (err != -1) {
239     err = buf_getline(in, line);
240     if (err == -1 || buf_eq(line, cutmarks)) {
241     t1msg(cut, 0);
242     buf_clear(cut);
243     } else {
244     buf_cat(cut, line);
245     buf_nl(cut);
246     }
247     }
248     buf_move(in, temp);
249     buf_clear(cutmarks);
250     }
251     if (encrypted == 1) {
252     #ifdef USE_PGP
253     err = pgp_dearmor(in, temp);
254     if (err == 0) {
255     BUFFER *pass;
256    
257     pass = buf_new();
258 rabbi 102 buf_sets(pass, PASSPHRASE);
259 rabbi 1 err = pgp_decrypt(temp, pass, NULL, NULL, NULL);
260     buf_free(pass);
261     }
262     if (err != -1 && temp->length == 0) {
263     errlog(ERRORMSG, "Empty PGP message.\n");
264     err = -1;
265     goto end;
266     }
267     if (err != -1) {
268     buf_rest(temp, in); /* dangerous, but required for reply blocks */
269     buf_move(in, temp);
270     encrypted = 0;
271     hdr = 0;
272     goto header;
273     }
274     #endif
275     if (testto->length == 0)
276     errlog(ERRORMSG, "Can't decrypt PGP message.\n");
277     buf_appends(test, "Can't decrypt PGP message.\n");
278     }
279     while ((err = buf_lookahead(in, line)) == 1)
280     buf_getline(in, line);
281     #if 0
282     if (err == -1)
283     goto end;
284     #endif
285    
286     if (isline(line, HDRMARK) && (hdr == 0 || hdr == 1)) {
287     buf_getline(in, NULL);
288     hdr = 2;
289     goto header;
290     } else if (isline(line, HASHMARK)) {
291     buf_getline(in, NULL);
292     for (;;) {
293     if (buf_lookahead(in, line) == 0 && bufileft(line, "subject:")) {
294     buf_getheader(in, field, content);
295     buf_set(subject, content);
296     }
297     if (buf_getline(in, line) != 0)
298     break;
299     buf_cat(header, line);
300     buf_nl(header);
301     }
302     }
303     if (encrypted == -1) {
304     if (testto->length == 0)
305     errlog(LOG, "Unencrypted message detected.\n");
306     buf_appends(test, "Unencrypted message detected.\n");
307     err = -2;
308     goto end;
309     }
310     if (type == MSG_POST && subject->length == 0)
311     buf_sets(subject, "(no subject)");
312    
313     if (to->length > 0)
314     buf_appendf(out, "To: %b\n", to);
315     else if (remixto->length > 0)
316     buf_appendf(out, "To: %b\n", remixto);
317     if (newsgroups->length > 0)
318     buf_appendf(out, "Newsgroups: %b\n", newsgroups);
319     if (subject->length > 0) {
320     #ifdef USE_IDEA
321     if (esub->length > 0)
322     t1_esub(esub, subject);
323     #endif
324     buf_appendf(out, "Subject: %b\n", subject);
325     }
326     buf_cat(out, header);
327     buf_nl(out);
328    
329     #if 0
330     inflate -= in->length;
331     #endif
332     if (inflate > 0) {
333     buf_setrnd(temp, inflate * 3 / 4);
334     encode(temp, 64);
335     buf_appends(in, "\n-----BEGIN GARBAGE-----\n");
336     buf_cat(in, temp);
337     buf_appends(in, "-----END GARBAGE-----\n");
338     }
339    
340     if (!(ek->length || ekdes->length || ekcast->length))
341     buf_rest(out, in);
342     else {
343     err = 0;
344     buf_clear(temp);
345     while (buf_getline(in, line) != -1) {
346     if (isline(line, EKMARK)) {
347     buf_cat(out, temp);
348     buf_clear(temp);
349     buf_rest(temp, in);
350     break;
351     }
352     else {
353     buf_cat(temp, line);
354     buf_nl(temp);
355     }
356     }
357     #ifdef USE_PGP
358     if (ekcast->length) {
359     err = pgp_encrypt(PGP_CONVCAST | PGP_TEXT, temp, ekcast, NULL, NULL,
360     NULL, NULL);
361     buf_clear(ekcast);
362     }
363     if (ekdes->length) {
364     err = pgp_encrypt(PGP_CONV3DES | PGP_TEXT, temp, ekdes, NULL, NULL,
365     NULL, NULL);
366     buf_clear(ekdes);
367     }
368     if (ek->length) {
369     err = pgp_encrypt(PGP_CONVENTIONAL | PGP_TEXT, temp, ek, NULL, NULL,
370     NULL, NULL);
371     buf_clear(ek);
372     }
373     buf_appends(out, EKMARK);
374     buf_nl(out);
375     buf_cat(out, temp);
376     #else
377     err = -1;
378     #endif
379     }
380    
381     if (type == -1) {
382     buf_appends(test, "No destination.\n");
383     err = -1;
384     }
385    
386     end:
387     if (testto->length) {
388     BUFFER *report;
389     int i;
390    
391     report = buf_new();
392     buf_sets(report,
393     "Subject: remailer test report\n\nThis is an automated response to the test message you sent to ");
394     buf_appends(report, SHORTNAME);
395     buf_appends(report, ".\nYour test message results follow:\n\n");
396     buf_appends(report, remailer_type);
397     buf_appends(report, VERSION);
398     buf_appends(report, "\n\n");
399     if (err == 0) {
400     err = filtermsg(out);
401     if (err == -1)
402     buf_appends(report, "This remailer cannot deliver the message.\n\n");
403     else {
404     buf_appends(report, "Valid ");
405     buf_appends(report, type == MSG_POST ? "Usenet" : "mail");
406     buf_appends(report, " message.\n");
407     if (remixto->length) {
408     if (remix && MIX)
409     buf_appends(report, "Delivery via Mixmaster: ");
410     else if (remix)
411     buf_appends(report, "Error! Can't remix: ");
412     else
413     buf_appends(report, "Delivery via Cypherpunk remailer: ");
414     buf_cat(report, remixto);
415     buf_nl(report);
416     }
417     else if (type == MSG_POST && strchr(NEWS, '@') && !strchr(NEWS, ' ')) {
418     buf_appendf(report, "News gateway: %s\n", NEWS);
419     }
420     buf_appends(report,
421     "\n=========================================================================\nThe first 20 lines of the message follow:\n");
422     if (err != 1)
423     buf_appendf(report, "From: %s\n", ANONNAME);
424     if (type == MSG_POST && ORGANIZATION[0] != '\0')
425     buf_appendf(report, "Organization: %s\n", ORGANIZATION);
426     }
427     for (i = 0; i < 20 && buf_getline(out, test) != -1; i++)
428     buf_cat(report, test), buf_nl(report);
429     } else {
430     buf_appends(report, "The remailer message is invalid.\n\n");
431     if (test->length) {
432     buf_appends(report, "The following error occurred: ");
433     buf_cat(report, test);
434     buf_nl(report);
435     }
436     }
437     buf_appends(report,
438     "=========================================================================\nThe first 20 lines of your message to the remailer follow:\n");
439     buf_rewind(in);
440     for (i = 0; i < 20 && buf_getline(in, test) != -1; i++)
441     buf_cat(report, test), buf_nl(report);
442    
443     sendmail(report, REMAILERNAME, testto);
444     err = 0;
445     buf_free(report);
446     } else if (err == 0 && type != MSG_NULL) {
447     err = 1;
448     if (bufieq(to, REMAILERADDR)) /* don't remix to ourselves */
449     remix = 0;
450 rabbi 62 if (remix && remixto->length == 0)
451     buf_set(remixto, to);
452     if (remix && !repgp)
453     err = mix_encrypt(type, out, remixto->data, 1, line);
454     if (err != 0) {
455     if (remix == 1 && !repgp)
456     errlog(NOTICE, "Can't remix -- %b\n", line);
457     else {
458     if (remixto->length)
459     err = t1_encrypt(type, out, remixto->data, 0, 0, line);
460     if (err != 0 && repgp)
461     errlog(NOTICE, "Can't repgp -- %b\n", line);
462     else
463 rabbi 1 err = mix_pool(out, type, latent * 60);
464     }
465     }
466     }
467    
468     buf_free(field);
469     buf_free(content);
470     buf_free(line);
471     buf_free(to);
472     buf_free(remixto);
473     buf_free(newsgroups);
474     buf_free(subject);
475     buf_free(ek);
476     buf_free(ekcast);
477     buf_free(ekdes);
478     buf_free(esub);
479     buf_free(cutmarks);
480     buf_free(temp);
481     buf_free(out);
482     buf_free(header);
483     buf_free(test);
484     buf_free(testto);
485     return (err);
486     }

  ViewVC Help
Powered by ViewVC 1.1.5