/[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 262 - (show annotations) (download)
Wed Sep 18 23:26:17 2002 UTC (10 years, 8 months ago) by rabbi
File MIME type: text/plain
File size: 12446 byte(s)
Added closing comments for all #ifdef statements. All #endif's, as well as
nested braces, should be commented to reference their start.

We need to provide comments before every function as well.
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.7 2002/09/18 23:26:17 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 /* USE_IDEA */
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 /* USE_NSUB */
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 /* USE_PGP */
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 /* 0 */
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 /* USE_IDEA */
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 /* 0 */
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 /* end of USE_PGP */
377 err = -1;
378 #endif /* Else if not USE_PGP */
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