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

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

Parent Directory Parent Directory | Revision Log Revision Log


Revision 710 - (show annotations) (download)
Wed Jan 21 00:47:21 2004 UTC (9 years, 4 months ago) by rabbi
File MIME type: text/plain
File size: 20424 byte(s)
Updated copyright dates, doc issues, misc fixes.
1 /* Mixmaster version 3.0 -- (C) 1999 - 2004 Anonymizer Inc. and others.
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 Encrypt message for Mixmaster chain
9 $Id$ */
10
11
12 #include "mix3.h"
13 #include <string.h>
14 #include <stdlib.h>
15 #include <time.h>
16 #include <ctype.h>
17 #include <assert.h>
18
19 #define N(X) (isdigit(X) ? (X)-'0' : 0)
20
21 int prepare_type2list(BUFFER *out)
22 {
23 FILE *list;
24 char line[LINELEN], name[LINELEN], addr[LINELEN], keyid[LINELEN],
25 version[LINELEN], flags[LINELEN], createdstr[LINELEN], expiresstr[LINELEN];
26 int assigned;
27 time_t created, expires;
28
29 list = mix_openfile(TYPE2LIST, "r");
30 if (list == NULL) {
31 list = mix_openfile(PUBRING, "r");
32 if (list == NULL)
33 return (-1);
34 }
35 while (fgets(line, sizeof(line), list) != NULL) {
36 if (strleft(line, begin_key)) {
37 while (fgets(line, sizeof(line), list) != NULL &&
38 !strleft(line, end_key)) ;
39 } else if (strlen(line) > 36 && line[0] != '#') {
40 assigned = sscanf(line, "%127s %127s %127s %127s %127s %127s %127s",
41 name, addr, keyid, version, flags, createdstr, expiresstr);
42 if (assigned < 4)
43 continue;
44 if (assigned >= 6) {
45 created = parse_yearmonthday(createdstr);
46 if (created == 0 || created == -1) {
47 errlog(WARNING, "Cannot parse creation date of key %s.\n", keyid);
48 continue;
49 };
50 if (created > time(NULL)) {
51 errlog(WARNING, "Key %s created in the future.\n", keyid);
52 continue;
53 };
54 }
55 if (assigned >= 7) {
56 expires = parse_yearmonthday(expiresstr);
57 if (expires == 0 || expires == -1) {
58 errlog(WARNING, "Cannot parse expiration date of key %s.\n", keyid);
59 continue;
60 };
61 if (expires < time(NULL)) {
62 errlog(WARNING, "Key %s has expired.\n", keyid);
63 continue;
64 };
65 }
66 buf_appends(out, line);
67 }
68 }
69 fclose(list);
70 return (0);
71 }
72
73 int mix2_rlist(REMAILER remailer[], int badchains[MAXREM][MAXREM])
74 {
75 FILE *list, *excl;
76 int n, i, listed = 0;
77
78 char line[LINELEN], name[LINELEN], addr[LINELEN], keyid[LINELEN],
79 version[LINELEN], flags[LINELEN], createdstr[LINELEN], expiresstr[LINELEN];
80 int assigned;
81 time_t created, expires;
82 BUFFER *starex;
83
84 starex = buf_new();
85 excl = mix_openfile(STAREX, "r");
86 if (excl != NULL) {
87 buf_read(starex, excl);
88 fclose(excl);
89 }
90
91 list = mix_openfile(TYPE2LIST, "r");
92 if (list == NULL) {
93 list = mix_openfile(PUBRING, "r");
94 if (list == NULL) {
95 buf_free(starex);
96 return (-1);
97 }
98 }
99 for (n = 1; fgets(line, sizeof(line), list) != NULL && n < MAXREM;)
100 if (strleft(line, begin_key)) {
101 while (fgets(line, sizeof(line), list) != NULL &&
102 !strleft(line, end_key)) ;
103 } else if (strlen(line) > 36 && line[0] != '#') {
104 flags[0] = '\0';
105 assigned = sscanf(line, "%127s %127s %127s %127s %127s %127s %127s",
106 name, addr, keyid, version, flags, createdstr, expiresstr);
107 if (assigned < 4)
108 continue;
109 if (assigned >= 6) {
110 created = parse_yearmonthday(createdstr);
111 if (created == 0 || created == -1) {
112 errlog(WARNING, "Cannot parse creation date of key %s.\n", keyid);
113 continue;
114 };
115 if (created > time(NULL)) {
116 errlog(WARNING, "Key %s created in the future.\n", keyid);
117 continue;
118 };
119 }
120 if (assigned >= 7) {
121 expires = parse_yearmonthday(expiresstr);
122 if (expires == 0 || expires == -1) {
123 errlog(WARNING, "Cannot parse expiration date of key %s.\n", keyid);
124 continue;
125 };
126 if (expires < time(NULL)) {
127 errlog(WARNING, "Key %s has expired.\n", keyid);
128 continue;
129 };
130 }
131 strncpy(remailer[n].name, name, sizeof(remailer[n].name));
132 remailer[n].name[sizeof(remailer[n].name) - 1] = '\0';
133 strncpy(remailer[n].addr, addr, sizeof(remailer[n].addr));
134 remailer[n].addr[sizeof(remailer[n].addr) - 1] = '\0';
135 remailer[n].flags.mix = 1;
136 remailer[n].flags.cpunk = 0;
137 remailer[n].flags.nym = 0;
138 remailer[n].flags.newnym = 0;
139 id_decode(keyid, remailer[n].keyid);
140 remailer[n].version = N(version[0]);
141 remailer[n].flags.compress = strfind(flags, "C");
142 remailer[n].flags.post = strfind(flags, "N");
143 remailer[n].flags.middle = strfind(flags, "M");
144 remailer[n].info[0].reliability = 0;
145 remailer[n].info[0].latency = 0;
146 remailer[n].info[0].history[0] = '\0';
147 remailer[n].flags.star_ex = bufifind(starex, name);
148 n++;
149 }
150 fclose(list);
151 list = mix_openfile(TYPE2REL, "r");
152 if (list != NULL) {
153 while (fgets(line, sizeof(line), list) != NULL &&
154 !strleft(line, "--------------------------------------------")) {
155 if (strleft(line, "Last update:")) {
156 int generated;
157 int now = time(NULL);
158 char *tmp = line + strlen("Last update:") + 1;
159 generated = parsedate(tmp);
160 if (generated == -1) {
161 /* For some weird reason, this isn't rfc822 */
162 if (strleft(tmp, "Mon") ||
163 strleft(tmp, "Tue") ||
164 strleft(tmp, "Wed") ||
165 strleft(tmp, "Thu") ||
166 strleft(tmp, "Fri") ||
167 strleft(tmp, "Sat") ||
168 strleft(tmp, "Sun"))
169 tmp += 3;
170 generated = parsedate(tmp);
171 }
172 now = time(NULL);
173 if (generated != -1 && generated < now - SECONDSPERDAY)
174 errlog(WARNING, "Remailer Reliability Statistics are older than one day (check your clock?).\n");
175 if (generated != -1 && generated > now)
176 errlog(WARNING, "Remailer Reliability Statistics are from the future (check your clock?).\n");
177 }
178 };
179 while (fgets(line, sizeof(line), list) != NULL &&
180 !strleft(line, "</PRE>"))
181 if (strlen(line) >= 44 && strlen(line) <= 46)
182 for (i = 1; i < n; i++)
183 if (strleft(line, remailer[i].name) &&
184 line[strlen(remailer[i].name)] == ' ') {
185 strncpy(remailer[i].info[0].history, line + 15, 12);
186 remailer[i].info[0].history[12] = '\0';
187 remailer[i].info[0].reliability = 10000 * N(line[37])
188 + 1000 * N(line[38]) + 100 * N(line[39])
189 + 10 * N(line[41]) + N(line[42]);
190 remailer[i].info[0].latency = 36000 * N(line[28])
191 + 3600 * N(line[29]) + 600 * N(line[31])
192 + 60 * N(line[32]) + 10 * N(line[34])
193 + N(line[35]);
194 listed++;
195 }
196 fclose(list);
197 }
198
199 parse_badchains(badchains, TYPE2REL, "Broken type-II remailer chains", remailer, n);
200 if (listed < 4) /* we have no valid reliability info */
201 for (i = 1; i < n; i++)
202 remailer[i].info[0].reliability = 10000;
203 buf_free(starex);
204 return (n);
205 }
206
207 static int send_packet(int numcopies, BUFFER *packet, int chain[],
208 int chainlen, int packetnum, int numpackets,
209 BUFFER *mid, REMAILER remailer[], int badchains[MAXREM][MAXREM],
210 int maxrem, char *redirect_to, int ignore_constraints_if_necessary,
211 BUFFER *feedback)
212 /*
213 * Puts a mix packet in the pool.
214 *
215 * numcopies ... how often to put this packet into the pool
216 * i.e. send it. required that random remailers are in the chain.
217 * packet ... the payload, 10240 bytes in size.
218 * chain ... the chain to send this message along
219 * chainlen ... length of the chain
220 * packetnum ... in multi-packet messages (fragmented) the serial of this packet
221 * numpackets ... the total number of packets
222 * mid ... the message ID (required for fragmented packets
223 * remailer ... information about remailers, their reliabilities, capabilities, etc.
224 * badchains ... broken chain information
225 * maxrem ... the number of remailers in remailer[] and badchains[]
226 * redirect_to ... if this is not-null it needs to be an email address.
227 * in this case packet needs to be not only the body, but a
228 * complete mixmaster packet of 20480 bytes in size (20 headers + body).
229 * the chain given is prepended to the one already encrypted in
230 * the existing message. If this exceeds the allowed 20 hops in total
231 * the message is corrupted, the last node will realize this.
232 * This is useful if you want to reroute an existing mixmaster message
233 * that has foo as the next hop via a chain so that the packet will
234 * actually flow hop1,hop2,hop3,foo,....
235 * ignore_constraints_if_necessary .. to be used when randhopping messages.
236 * if a chain can not be constructed otherwhise, maxlat and
237 * minrel are ignored.
238 * feedback ... a buffer to write feedback to
239 */
240 {
241 BUFFER *pid, *out, *header, *other, *encrypted, *key, *body;
242 BUFFER *iv, *ivarray, *temp;
243 BUFFER *pubkey;
244 char addr[LINELEN];
245 int thischain[20];
246 int hop;
247 int c, i;
248 int timestamp = 0;
249 int israndom = 0;
250 int err = 1;
251
252 body = buf_new();
253 pid = buf_new();
254 out = buf_new();
255 header = buf_new();
256 other = buf_new();
257 key = buf_new();
258 encrypted = buf_new();
259 iv = buf_new();
260 ivarray = buf_new();
261 temp = buf_new();
262
263 if (redirect_to != NULL) {
264 assert(packet->length == 20480);
265 buf_append(header, packet->data, 10240);
266 buf_append(temp, packet->data + 10240, 10240);
267 buf_clear(packet);
268 buf_cat(packet, temp);
269 } else
270 assert(packet->length == 10240);
271
272 buf_setrnd(pid, 16);
273
274 for (c = 0; c < numcopies; c++) {
275 buf_set(body, packet);
276
277 for (hop = 0; hop < chainlen; hop++)
278 thischain[hop] = chain[hop];
279
280 israndom = chain_rand(remailer, badchains, maxrem, thischain, chainlen, 0, ignore_constraints_if_necessary);
281 if (israndom == -1) {
282 err = -1;
283 clienterr(feedback, "No reliable remailers!");
284 }
285 if ((numcopies > 1 || numpackets > 1) && !israndom && (chainlen != 1)) {
286 clienterr(feedback,
287 "Multi-packet message without random remailers!");
288 err = -1;
289 goto end;
290 }
291 for (hop = 0; hop < chainlen; hop++) {
292 switch (remailer[thischain[hop]].version) {
293 case 2:
294 case 3: /* not implemented yet; fall back to version 2 */
295 /* create header chart to be encrypted with the session key */
296 if (numcopies > 1 && hop == 0 && redirect_to == NULL)
297 buf_set(encrypted, pid); /* same ID only at final hop */
298 else
299 buf_setrnd(encrypted, 16);
300 buf_setrnd(key, 24); /* key for encrypting the body */
301 buf_cat(encrypted, key);
302 buf_setrnd(iv, 8); /* IV for encrypting the body */
303
304 if (hop > 0 || redirect_to != NULL) {
305 /* IVs for header chart encryption */
306 buf_setrnd(ivarray, 18 * 8);
307 buf_cat(ivarray, iv); /* 19th IV equals the body IV */
308
309 buf_appendc(encrypted, 0);
310 buf_cat(encrypted, ivarray);
311 memset(addr, 0, 80);
312 if (hop == 0) {
313 assert(redirect_to != NULL);
314 strncpy(addr, redirect_to, 80);
315 } else {
316 assert(hop > 0);
317 strcpy(addr, remailer[thischain[hop - 1]].addr);
318 };
319 buf_append(encrypted, addr, 80);
320 } else {
321 if (numpackets == 1)
322 buf_appendc(encrypted, 1);
323 else {
324 buf_appendc(encrypted, 2);
325 buf_appendc(encrypted, (byte) packetnum);
326 buf_appendc(encrypted, (byte) numpackets);
327 }
328 buf_cat(encrypted, mid);
329 buf_cat(encrypted, iv); /* body encryption IV */
330 }
331
332 /* timestamp */
333 buf_appends(encrypted, "0000");
334 buf_appendc(encrypted, '\0'); /* timestamp magic */
335 timestamp = time(NULL) / SECONDSPERDAY - rnd_number(4);
336 buf_appendi_lo(encrypted, timestamp);
337
338 /* message digest for this header */
339 digest_md5(encrypted, temp);
340 buf_cat(encrypted, temp);
341 buf_pad(encrypted, 328);
342
343 /* encrypt message body */
344 buf_crypt(body, key, iv, ENCRYPT);
345
346 if (hop > 0 || redirect_to != NULL) {
347 /* encrypt the other header charts */
348 buf_clear(other);
349 for (i = 0; i < 19; i++) {
350 buf_clear(iv);
351 buf_clear(temp);
352 buf_append(iv, ivarray->data + 8 * i, 8);
353 buf_append(temp, header->data + 512 * i, 512);
354 buf_crypt(temp, key, iv, ENCRYPT);
355 buf_cat(other, temp);
356 }
357 } else
358 buf_setrnd(other, 19 * 512); /* fill with random data */
359
360 /* create session key and IV to encrypt the header ... */
361 buf_setrnd(key, 24);
362 buf_setrnd(iv, 8);
363 buf_crypt(encrypted, key, iv, ENCRYPT);
364 pubkey = buf_new();
365 err = db_getpubkey(remailer[thischain[hop]].keyid, pubkey);
366 if (err == -1)
367 goto end;
368 err = pk_encrypt(key, pubkey); /* ... and encrypt the
369 session key */
370 buf_free(pubkey);
371 if (err == -1 || key->length != 128) {
372 clienterr(feedback, "Encryption failed!");
373 err = -1;
374 goto end;
375 }
376 /* now build the new header */
377 buf_clear(header);
378 buf_append(header, remailer[thischain[hop]].keyid, 16);
379 buf_appendc(header, 128);
380 buf_cat(header, key);
381 buf_cat(header, iv);
382 buf_cat(header, encrypted);
383 buf_pad(header, 512);
384 buf_cat(header, other);
385 break;
386 default:
387 err = -1;
388 goto end;
389 }
390 }
391
392 /* build the message */
393 buf_sets(out, remailer[thischain[chainlen - 1]].addr);
394 buf_nl(out);
395 buf_cat(out, header);
396 buf_cat(out, body);
397 assert(header->length == 10240 && body->length == 10240);
398 mix_pool(out, INTERMEDIATE, -1);
399
400 if (feedback) {
401 for (hop = chainlen - 1; hop >= 0; hop--) {
402 buf_appends(feedback, remailer[thischain[hop]].name);
403 if (hop > 0)
404 buf_appendc(feedback, ',');
405 }
406 buf_nl(feedback);
407 }
408 }
409 end:
410 buf_free(pid);
411 buf_free(body);
412 buf_free(out);
413 buf_free(header);
414 buf_free(temp);
415 buf_free(other);
416 buf_free(key);
417 buf_free(encrypted);
418 buf_free(iv);
419 buf_free(ivarray);
420 return (err);
421 }
422
423 int redirect_message(BUFFER *sendmsg, char *chainstr, int numcopies, BUFFER *feedback)
424 {
425 BUFFER *field;
426 BUFFER *content;
427 BUFFER *line;
428 char recipient[80] = "";
429 int num = 0;
430 int err = 0;
431 int c;
432 int hop;
433
434 REMAILER remailer[MAXREM];
435 int chain[20];
436 int thischain[20];
437 int chainlen;
438 int badchains[MAXREM][MAXREM];
439 int maxrem;
440 int tempchain[20];
441 int tempchainlen;
442 int israndom;
443
444 field = buf_new();
445 content = buf_new();
446 line = buf_new();
447
448 if (numcopies == 0)
449 numcopies = NUMCOPIES;
450 if (numcopies > 10)
451 numcopies = 10;
452
453 /* Find the recipient */
454 while (buf_getheader(sendmsg, field, content) == 0)
455 if (bufieq(field, "to")) {
456 strncpy(recipient, content->data, sizeof(recipient));
457 num++;
458 };
459 if (num != 1) {
460 clienterr(feedback, "Did not find exactly one To: address!");
461 err = -1;
462 goto end;
463 };
464
465 /* Dearmor the message */
466 err = mix_dearmor(sendmsg, sendmsg);
467 if (err == -1)
468 goto end;
469 assert (sendmsg->length == 20480);
470
471 /* Check the chain */
472 maxrem = mix2_rlist(remailer, badchains);
473 if (maxrem < 1) {
474 clienterr(feedback, "No remailer list!");
475 err = -1;
476 goto end;
477 }
478 chainlen = chain_select(chain, chainstr, maxrem, remailer, 0, line);
479 if (chainlen < 1) {
480 if (line->length)
481 clienterr(feedback, line->data);
482 else
483 clienterr(feedback, "Invalid remailer chain!");
484 err = -1;
485 goto end;
486 } else if (chainlen >= 20) {
487 clienterr(feedback, "A chainlength of 20 will certainly destroy the message!");
488 err = -1;
489 goto end;
490 };
491
492
493 for (c = 0; c < numcopies; c++) {
494 /* if our recipient is a remailer we want to make sure we're not using a known broken chain.
495 * therefore we need to pick the final remailer with care */
496 for (hop = 0; hop < chainlen; hop++)
497 thischain[hop] = chain[hop];
498 if (thischain[0] == 0) {
499 /* Find out, if recipient is a remailer */
500 tempchainlen = chain_select(tempchain, recipient, maxrem, remailer, 0, line);
501 if (tempchainlen < 1 && line->length == 0) {
502 /* recipient is apparently not a remailer we know about */
503 ;
504 } else {
505 /* Build a new chain, based on the one we already selected but
506 * with the recipient as the final hop.
507 * This is so that chain_rand properly selects nodes based on
508 * broken chains and DISTANCE */
509 assert(chainlen < 20);
510 for (hop = 0; hop < chainlen; hop++)
511 thischain[hop+1] = thischain[hop];
512 thischain[0] = tempchain[0];
513
514 israndom = chain_rand(remailer, badchains, maxrem, thischain, chainlen + 1, 0, 0);
515 if (israndom == -1) {
516 err = -1;
517 clienterr(feedback, "No reliable remailers!");
518 goto end;
519 }
520
521 /* Remove the added recipient hop */
522 for (hop = 0; hop < chainlen; hop++)
523 thischain[hop] = thischain[hop + 1];
524 };
525 };
526
527 /* queue the packet */
528 if (send_packet(1, sendmsg, thischain, chainlen,
529 -1, -1, NULL,
530 remailer, badchains, maxrem, recipient, 0, feedback) == -1)
531 err = -1;
532 };
533
534 end:
535 buf_free(field);
536 buf_free(content);
537 buf_free(line);
538 return (err);
539 }
540
541 int mix2_encrypt(int type, BUFFER *message, char *chainstr, int numcopies,
542 int ignore_constraints_if_necessary,
543 BUFFER *feedback)
544 {
545 /* returns 0 on success, -1 on error. feedback contains the selected
546 remailer chain or an error message
547
548 ignore_constraints_if_necessary .. to be used when randhopping messages.
549 if a chain can not be constructed otherwhise,
550 maxlat and minrel are ignored.
551 */
552
553 REMAILER remailer[MAXREM];
554 int badchains[MAXREM][MAXREM];
555 int maxrem;
556 BUFFER *line, *field, *content, *header, *msgdest, *msgheader, *body,
557 *temp, *mid;
558 byte numdest = 0, numhdr = 0;
559 char hdrline[LINELEN];
560 BUFFER *packet;
561 int chain[20];
562 int chainlen;
563 int i;
564 int err = 0;
565
566 mix_init(NULL);
567 packet = buf_new();
568 line = buf_new();
569 field = buf_new();
570 content = buf_new();
571 msgheader = buf_new();
572 msgdest = buf_new();
573 body = buf_new();
574 temp = buf_new();
575 mid = buf_new();
576 header = buf_new();
577 if (feedback)
578 buf_reset(feedback);
579
580 if (numcopies == 0)
581 numcopies = NUMCOPIES;
582 if (numcopies > 10)
583 numcopies = 10;
584
585 maxrem = mix2_rlist(remailer, badchains);
586 if (maxrem < 1) {
587 clienterr(feedback, "No remailer list!");
588 err = -1;
589 goto end;
590 }
591 chainlen = chain_select(chain, chainstr, maxrem, remailer, 0, line);
592 if (chainlen < 1) {
593 if (line->length)
594 clienterr(feedback, line->data);
595 else
596 clienterr(feedback, "Invalid remailer chain!");
597 err = -1;
598 goto end;
599 }
600 if (chain[0] == 0)
601 chain[0] = chain_randfinal(type, remailer, badchains, maxrem, 0, chain, chainlen, ignore_constraints_if_necessary);
602
603 if (chain[0] == -1) {
604 clienterr(feedback, "No reliable remailers!");
605 err = -1;
606 goto end;
607 }
608 switch (remailer[chain[0]].version) {
609 case 2:
610 if (type == MSG_NULL) {
611 memset(hdrline, 0, 80);
612 strcpy(hdrline, "null:");
613 buf_append(msgdest, hdrline, 80);
614 numdest++;
615 } else
616 while (buf_getheader(message, field, content) == 0) {
617 if (bufieq(field, "to")) {
618 memset(hdrline, 0, 80);
619 strncpy(hdrline, content->data, 80);
620 buf_append(msgdest, hdrline, 80);
621 numdest++;
622 } else if (type == MSG_POST && bufieq(field, "newsgroups")) {
623 memset(hdrline, 0, 80);
624 strcpy(hdrline, "post: ");
625 strcatn(hdrline, content->data, 80);
626 buf_append(msgdest, hdrline, 80);
627 numdest++;
628 } else {
629 buf_clear(header);
630 buf_appendheader(header, field, content);
631 hdr_encode(header, 80);
632 while (buf_getline(header, line) == 0) {
633 /* paste in encoded header entry */
634 memset(hdrline, 0, 80);
635 strncpy(hdrline, line->data, 80);
636 buf_append(msgheader, hdrline, 80);
637 numhdr++;
638 }
639 }
640 }
641 buf_appendc(body, numdest);
642 buf_cat(body, msgdest);
643 buf_appendc(body, numhdr);
644 buf_cat(body, msgheader);
645
646 if (type != MSG_NULL) {
647 buf_rest(temp, message);
648 if (temp->length > 10236 && remailer[chain[0]].flags.compress)
649 buf_compress(temp);
650 buf_cat(body, temp);
651 buf_reset(temp);
652 }
653 buf_setrnd(mid, 16); /* message ID */
654 for (i = 0; i <= body->length / 10236; i++) {
655 long length;
656
657 length = body->length - i * 10236;
658 if (length > 10236)
659 length = 10236;
660 buf_clear(packet);
661 buf_appendl_lo(packet, length);
662 buf_append(packet, body->data + i * 10236, length);
663 buf_pad(packet, 10240);
664 if (send_packet(numcopies, packet, chain, chainlen,
665 i + 1, body->length / 10236 + 1,
666 mid, remailer, badchains, maxrem, NULL, ignore_constraints_if_necessary, feedback) == -1)
667 err = -1;
668 }
669 break;
670 case 3:
671 NOT_IMPLEMENTED;
672 break;
673 default:
674 fprintf(stderr, "%d\n", chain[0]);
675 clienterr(feedback, "Unknown remailer version!");
676 err = -1;
677 }
678
679 end:
680 buf_free(packet);
681 buf_free(line);
682 buf_free(field);
683 buf_free(content);
684 buf_free(header);
685 buf_free(msgheader);
686 buf_free(msgdest);
687 buf_free(body);
688 buf_free(temp);
689 buf_free(mid);
690 return (err);
691 }

Properties

Name Value
svn:keywords Id

  ViewVC Help
Powered by ViewVC 1.1.5