/[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 - (show 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 /* 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 $Id: rem1.c,v 1.6 2002/07/24 07:48:50 rabbi Exp $ */
10
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 int remix = 0, repgp = 0;
103 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 remix = 1; repgp = 0;
139 buf_set(remixto, content);
140 if (type == -1)
141 type = MSG_MAIL;
142 } else if (bufieq(field, "encrypt-to")) {
143 repgp = remix = 1;
144 buf_set(remixto, content);
145 if (type == -1)
146 type = MSG_MAIL;
147 } 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 repgp = remix = 0;
153 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 buf_sets(pass, PASSPHRASE);
259 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 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 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