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

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

Parent Directory Parent Directory | Revision Log Revision Log


Revision 1 - (hide annotations) (download)
Wed Oct 31 08:19:51 2001 UTC (11 years, 6 months ago) by rabbi
File MIME type: text/plain
File size: 9771 byte(s)
Initial revision
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 Mixmaster remailer messages
9     $Id: rem2.c,v 1.1 2001/10/31 08:19:53 rabbi Exp $ */
10    
11    
12     #include "mix3.h"
13     #include <string.h>
14     #include <time.h>
15     #include <ctype.h>
16     #include <sys/types.h>
17     #include <sys/stat.h>
18     #ifdef POSIX
19     #include <unistd.h>
20     #else
21     #include <io.h>
22     #endif
23     #ifndef _MSC
24     #include <dirent.h>
25     #endif
26     #include <assert.h>
27    
28     int mix_dearmor(BUFFER *in, BUFFER *out)
29     {
30     BUFFER *line, *md;
31     int tempbuf = 0;
32     int err = 0;
33    
34     line = buf_new();
35     md = buf_new();
36    
37     if (in == out) {
38     tempbuf = 1;
39     out = buf_new();
40     }
41     do {
42     err = buf_getline(in, line);
43     if (err == -1)
44     goto end;
45     }
46     while (!bufeq(line, begin_remailer));
47    
48     do {
49     /* skip lines before message digest */
50     if (buf_getline(in, md) == -1)
51     break;
52     } while (strlen(md->data) != 24);
53    
54     decode(in, out);
55    
56     err = buf_getline(in, line);
57     if (err != 0 || !bufeq(line, end_remailer))
58     err = -1;
59     else {
60     digest_md5(out, line);
61     encode(line, 0);
62     if (!buf_eq(md, line))
63     err = -1;
64     if (out->length != 20480)
65     err = -1;
66     }
67    
68     end:
69     if (err == -1)
70     errlog(NOTICE, "Malformatted message.\n");
71    
72     if (tempbuf) {
73     buf_move(in, out);
74     buf_free(out);
75     }
76     buf_free(line);
77     buf_free(md);
78     return (err);
79     }
80    
81     #ifdef USE_RSA
82    
83     static int isnewid(BUFFER *id, long timestamp)
84     {
85     FILE *f;
86     char idstr[33], line[LINELEN];
87     int ret = 1;
88     long now, old = 0;
89     LOCK *i = NULL;
90    
91     now = time(NULL);
92     id_encode(id->data, idstr);
93    
94     if ((f = mix_openfile(IDLOG, "r+")) != NULL)
95     fscanf(f, "%*s %ld", &old);
96     else {
97     if (IDEXP == 0) {
98     if (timestamp > 0 && timestamp <= now - 7 * SECONDSPERDAY) {
99     errlog(LOG, "Ignoring old message.\n");
100     return (0);
101     }
102     } else {
103     if ((f = mix_openfile(IDLOG, "w")) != NULL) {
104     fprintf(f, "new %ld\n%s %ld\n", now, idstr, now);
105     fclose(f);
106     errlog(NOTICE, "Creating %s\n", IDLOG);
107     } else {
108     errlog(ERRORMSG, "Can't create %s\n", IDLOG);
109     }
110     return (1);
111     }
112     }
113    
114     if (now - old < 5 * SECONDSPERDAY) /* never reject messages less than */
115     old = now - 5 * SECONDSPERDAY; /* 5 days old (== minimum IDEXP) */
116    
117     if (timestamp > 0 && timestamp <= old) {
118     errlog(LOG, "Ignoring old message.\n");
119     ret = 0;
120     goto end;
121     }
122     i = lockfile(IDLOG);
123     while (fgets(line, sizeof(line), f) != NULL) {
124     if (strleft(line, idstr)) {
125     errlog(LOG, "Ignoring redundant message.\n");
126     ret = 0;
127     goto end;
128     }
129     }
130     fprintf(f, "%s %ld\n", idstr, now);
131     end:
132     if (i)
133     unlockfile(i);
134     fclose(f);
135     return (ret);
136     }
137    
138     int mix2_decrypt(BUFFER *m)
139     /* 0: ok -1: error -2: old message */
140     {
141     int err = 0;
142     int i;
143     BUFFER *privkey;
144     BUFFER *keyid;
145     BUFFER *dec, *deskey;
146     BUFFER *packetid, *mid, *digest, *addr, *temp, *iv, *ivvec;
147     int type, packet = 0, numpackets = 0, timestamp = 0;
148     BUFFER *body;
149     BUFFER *header, *out;
150    
151     privkey = buf_new();
152     keyid = buf_new();
153     dec = buf_new();
154     deskey = buf_new();
155     packetid = buf_new();
156     mid = buf_new();
157     digest = buf_new();
158     addr = buf_new();
159     temp = buf_new();
160     iv = buf_new();
161     ivvec = buf_new();
162     body = buf_new();
163     header = buf_new();
164     out = buf_new();
165    
166     buf_get(m, keyid, 16);
167     err = db_getseckey(keyid->data, privkey);
168     if (err == -1)
169     goto end;
170     buf_get(m, deskey, buf_getc(m));
171     err = pk_decrypt(deskey, privkey);
172     if (err == -1 || deskey->length != 24) {
173     err = -1;
174     errlog(NOTICE, "Cannot decrypt message.\n");
175     goto end;
176     }
177     buf_get(m, iv, 8);
178     buf_get(m, dec, 328);
179     buf_crypt(dec, deskey, iv, DECRYPT);
180     buf_get(dec, packetid, 16);
181     buf_get(dec, deskey, 24);
182     type = buf_getc(dec);
183     switch (type) {
184     case 0:
185     buf_get(dec, ivvec, 152);
186     buf_get(dec, addr, 80);
187     break;
188     case 1:
189     buf_get(dec, mid, 16);
190     buf_get(dec, iv, 8);
191     break;
192     case 2:
193     packet = buf_getc(dec);
194     numpackets = buf_getc(dec);
195     buf_get(dec, mid, 16);
196     buf_get(dec, iv, 8);
197     break;
198     default:
199     errlog(WARNING, "Unknown message type.\n");
200     err = -1;
201     goto end;
202     }
203     if (dec->data[dec->ptr] == '0' && dec->data[dec->ptr + 1] == '0' &&
204     dec->data[dec->ptr + 2] == '0' && dec->data[dec->ptr + 3] == '0' &&
205     dec->data[dec->ptr + 4] == '\0') {
206     dec->ptr += 5;
207     timestamp = buf_geti_lo(dec);
208     }
209     buf_get(dec, digest, 16);
210    
211     dec->length = dec->ptr - 16; /* ignore digest */
212     dec->ptr = dec->length;
213    
214     if (!isdigest_md5(dec, digest)) {
215     errlog(NOTICE, "Message digest does not match.\n");
216     err = -1;
217     goto end;
218     }
219     if (!isnewid(packetid, timestamp * SECONDSPERDAY)) {
220     err = -2;
221     goto end;
222     }
223     buf_append(body, m->data + 20 * 512, 10240);
224    
225     switch (type) {
226     case 0:
227     buf_chop(addr);
228     buf_cat(out, addr);
229     buf_nl(out);
230     for (i = 0; i < 19; i++) {
231     buf_reset(header);
232     buf_append(header, m->data + (i + 1) * 512, 512);
233     buf_reset(iv);
234     buf_append(iv, ivvec->data + i * 8, 8);
235     buf_crypt(header, deskey, iv, DECRYPT);
236     buf_cat(out, header);
237     }
238     buf_reset(header);
239     buf_pad(header, 512);
240     buf_cat(out, header);
241     buf_reset(iv);
242     buf_append(iv, ivvec->data + 144, 8);
243     buf_crypt(body, deskey, iv, DECRYPT);
244     buf_cat(out, body);
245     mix_pool(out, INTERMEDIATE, -1);
246     break;
247     case 1:
248     buf_crypt(body, deskey, iv, DECRYPT);
249     err = v2body_setlen(body);
250     if (err == -1)
251     goto end;
252     assert(body->ptr == 4);
253     v2body(body);
254     break;
255     case 2:
256     buf_crypt(body, deskey, iv, DECRYPT);
257     v2partial(body, mid, packet, numpackets);
258     break;
259     }
260     end:
261     buf_free(privkey);
262     buf_free(keyid);
263     buf_free(dec);
264     buf_free(deskey);
265     buf_free(packetid);
266     buf_free(mid);
267     buf_free(digest);
268     buf_free(addr);
269     buf_free(temp);
270     buf_free(iv);
271     buf_free(ivvec);
272     buf_free(body);
273     buf_free(header);
274     buf_free(out);
275    
276     return (err);
277     }
278    
279     int v2body_setlen(BUFFER *body)
280     {
281     long length;
282    
283     length = buf_getl_lo(body);
284     if (length < 0 || length > body->length)
285     return (-1);
286     body->length = length + 4;
287     return (0);
288     }
289    
290     int v2body(BUFFER *body)
291     {
292     int i, n;
293     BUFFER *to, *newsgroups;
294     BUFFER *temp, *out;
295     BUFFER *line;
296     int type = MSG_MAIL;
297     int subject = 0;
298    
299     line = buf_new();
300     to = buf_new();
301     newsgroups = buf_new();
302     temp = buf_new();
303     out = buf_new();
304    
305     n = buf_getc(body);
306     for (i = 0; i < n; i++) {
307     buf_get(body, line, 80);
308     buf_chop(line);
309     if (bufileft(line, "null:"))
310     goto end;
311     if (bufileft(line, "post:")) {
312     type = MSG_POST;
313     if (line->length > 5) {
314     int j = 5;
315    
316     while (j < line->length && isspace(line->data[j]))
317     j++;
318     if (newsgroups->length > 0)
319     buf_appends(newsgroups, ",");
320     buf_append(newsgroups, line->data + j, line->length - j);
321     }
322     } else {
323     if (to->length > 0)
324     buf_appends(to, ",");
325     buf_cat(to, line);
326     }
327     }
328     if (to->length > 0) {
329     buf_appends(out, "To: ");
330     buf_cat(out, to);
331     buf_nl(out);
332     }
333     if (newsgroups->length > 0) {
334     buf_appends(out, "Newsgroups: ");
335     buf_cat(out, newsgroups);
336     buf_nl(out);
337     }
338     n = buf_getc(body);
339     for (i = 0; i < n; i++) {
340     buf_get(body, line, 80);
341     buf_chop(line);
342     if (bufileft(line, "Subject:"))
343     subject = 1;
344     buf_cat(out, line);
345     buf_nl(out);
346     }
347    
348     buf_rest(temp, body);
349     buf_uncompress(temp);
350     buf_set(body, temp);
351     buf_reset(temp);
352    
353     if (buf_lookahead(body, line) == 0 && isline(line, HASHMARK)) {
354     buf_getline(body, line);
355     while (buf_getline(body, line) == 0) {
356     if (bufileft(line, "subject:"))
357     subject = 1;
358     buf_cat(out, line);
359     buf_nl(out);
360     }
361     }
362     if (type == MSG_POST && !subject)
363     buf_appends(out, "Subject: (no subject)\n");
364    
365     buf_nl(out);
366     buf_rest(out, body);
367     buf_reset(body);
368     mix_pool(out, type, -1);
369    
370     end:
371     buf_free(line);
372     buf_free(to);
373     buf_free(newsgroups);
374     buf_free(temp);
375     buf_free(out);
376     return (0);
377     }
378    
379     int v2_merge(BUFFER *mid)
380     {
381     char fname[PATHMAX], line[LINELEN];
382     BUFFER *temp, *msg;
383     FILE *l, *f;
384     int i, numpackets;
385     struct stat sb;
386     long d;
387     int n;
388     int err = -1;
389    
390     temp = buf_new();
391     msg = buf_new();
392     pool_packetfile(fname, mid, 0);
393     l = fopen(fname, "a+");
394     if (l != NULL)
395     lock(l);
396    
397     pool_packetfile(fname, mid, 1);
398     f = fopen(fname, "rb");
399     if (f == NULL)
400     goto end;
401     fscanf(f, "%32s %ld %d %d\n", line, &d, &i, &numpackets);
402     fclose(f);
403    
404     /* do we have all packets? */
405     for (i = 1; i <= numpackets; i++) {
406     pool_packetfile(fname, mid, i);
407     if (stat(fname, &sb) != 0)
408     goto end;
409     }
410     errlog(LOG, "Reassembling multipart message.\n");
411     for (i = 1; i <= numpackets; i++) {
412     pool_packetfile(fname, mid, i);
413     f = fopen(fname, "rb");
414     if (f == NULL)
415     goto end;
416     fscanf(f, "%32s %ld %d %d\n", line, &d, &n, &n);
417     buf_clear(temp);
418     buf_read(temp, f);
419     v2body_setlen(temp);
420     buf_append(msg, temp->data + 4, temp->length - 4);
421     fclose(f);
422     unlink(fname);
423     }
424     err = v2body(msg);
425    
426     end:
427     if (l != NULL)
428     fclose(l);
429     pool_packetfile(fname, mid, 0);
430     unlink(fname);
431     buf_free(temp);
432     buf_free(msg);
433     return (err);
434     }
435    
436     int v2partial(BUFFER *m, BUFFER *mid, int packet, int numpackets)
437     {
438     char fname[PATHMAX], idstr[33];
439     FILE *f;
440     int err = 1;
441    
442     pool_packetfile(fname, mid, packet);
443     f = fopen(fname, "wb");
444     if (f == NULL) {
445     err = -1;
446     goto end;
447     }
448     id_encode(mid->data, idstr);
449     fprintf(f, "%s %ld %d %d\n", idstr, (long) time(NULL), packet,
450     numpackets);
451     buf_write(m, f);
452     buf_reset(m);
453     fclose(f);
454     v2_merge(mid);
455     end:
456     return (err);
457     }
458    
459     #else
460    
461     int mix2_decrypt(BUFFER *m)
462     {
463     return (-1);
464     }
465     #endif

  ViewVC Help
Powered by ViewVC 1.1.5