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

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

Parent Directory Parent Directory | Revision Log Revision Log


Revision 41 - (show annotations) (download)
Wed Dec 12 19:29:52 2001 UTC (11 years, 5 months ago) by rabbi
File MIME type: text/plain
File size: 19548 byte(s)
Added quoted-printable decoding of non-multipart mime messages (cf. bug
#478380) by Scott Renfro.
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 MIME functions
9 $Id: mime.c,v 1.2 2001/12/12 19:29:52 rabbi Exp $ */
10
11
12 #include "mix3.h"
13 #include <ctype.h>
14
15 #define hex(i) (isdigit(i) ? (i) - '0' : tolower(i) - 'a' + 10)
16
17 #define hexdigit(i) ((byte)(i < 10 ? i + '0' : i - 10 + 'A'))
18
19 static void encode_word(BUFFER *in)
20 {
21 BUFFER *out;
22 int i;
23
24 out = buf_new();
25 for (i = 0; i < in->length; i++)
26 if (in->data[i] < 32 || in->data[i] >= 127 || in->data[i] == '='
27 || in->data[i] == '?' || in->data[i] == '_') {
28 buf_appendc(out, '=');
29 buf_appendc(out, hexdigit(in->data[i] / 16));
30 buf_appendc(out, hexdigit(in->data[i] % 16));
31 } else if (in->data[i] == ' ')
32 buf_appendc(out, '_');
33 else
34 buf_appendc(out, in->data[i]);
35 buf_move(in, out);
36 buf_free(out);
37 }
38
39 void body_encode(BUFFER *in, int transport, BUFFER *hdr)
40 {
41 BUFFER *out;
42 int c, l=0, encoding = 0;
43 out = buf_new();
44
45 buf_clear(hdr);
46
47 l = in->ptr;
48 while ((c = buf_getc(in)) != -1 && encoding != 2) {
49 if (c >= 160)
50 encoding = 1;
51 else if (c == ' ') {
52 if (buf_getc(in) == '\n')
53 encoding = 1;
54 buf_ungetc(in);
55 } else if ((c < 32 && c != ' ' && c != '\n' && c != '\t') ||
56 (c >= 127 && c < 160)) {
57 encoding = 2;
58 }
59 }
60 in->ptr = l;
61
62 if (encoding == 2) {
63 buf_sets(hdr, "Content-Transfer-Encoding: base64\n");
64 encode(in, 76);
65 } else {
66
67 #if 0
68 if (encoding == 0)
69 buf_sets(hdr, "Content-Transfer-Encoding: 7bit\n");
70 #endif
71 if (encoding != 0 && transport == MIME_8BIT)
72 buf_sets(hdr, "Content-Transfer-Encoding: 8bit\n");
73 if (encoding == 0 || transport == MIME_8BIT) {
74 buf_rest(out, in); /* transparent */
75 buf_move(in, out);
76 } else {
77 buf_sets(hdr, "Content-Transfer-Encoding: quoted-printable\n");
78 l = 0;
79 while ((c = buf_getc(in)) != -1) {
80 if (c == '\n') {
81 buf_nl(out);
82 l = 0;
83 }
84 else if (c < 32 || c >= 127 || c == '=') {
85 if (l > 73) {
86 buf_appends(out, "=\n");
87 l = 0;
88 }
89 buf_appendc(out, '=');
90 buf_appendc(out, hexdigit(c / 16));
91 buf_appendc(out, hexdigit(c % 16));
92 l += 3;
93 } else if (c == ' ') {
94 if (buf_getc(in) == '\n') {
95 buf_appendc(out, '=');
96 buf_appendc(out, hexdigit(c / 16));
97 buf_appendc(out, hexdigit(c % 16));
98 buf_nl(out);
99 l = 0;
100 } else {
101 buf_appendc(out, c);
102 buf_ungetc(in);
103 l++;
104 }
105 } else {
106 buf_appendc(out, c);
107 l++;
108 }
109 }
110 buf_move(in, out);
111 }
112 }
113 buf_free(out);
114 }
115
116 int mail_encode(BUFFER *in, int encoding)
117 {
118 BUFFER *out, *line, *tmp;
119
120 out = buf_new();
121 line = buf_new();
122 tmp = buf_new();
123
124 while (buf_getline(in, line) == 0) {
125 hdr_encode(line, 255);
126 buf_cat(out, line);
127 buf_nl(out);
128 }
129 if (in->ptr < in->length) {
130 /* no newline if only encoding header lines */
131 if (encoding == 0) {
132 buf_nl(out);
133 buf_rest(out, in);
134 }
135 else {
136 body_encode(in, encoding, line);
137 buf_cat(out, line);
138 buf_nl(out);
139 buf_cat(out, in);
140 }
141 }
142 buf_move(in, out);
143 buf_free(line);
144 buf_free(tmp);
145 buf_free(out);
146 return (0);
147 }
148
149 int hdr_encode(BUFFER *in, int n)
150 {
151 int i;
152 int encodeword = 0, encode = 0;
153 BUFFER *out, *word, *space;
154
155 out = buf_new();
156 word = buf_new();
157 space = buf_new();
158 for (i = 0; i <= in->length; i++) {
159 if (isspace(in->data[i]) || in->data[i] == '\0') {
160 if (word->length) {
161 if (encodeword) {
162 if (encode == 0) {
163 buf_cat(out, space);
164 buf_clear(space);
165 buf_appends(out, "=?");
166 buf_appends(out, MIMECHARSET);
167 buf_appends(out, "?Q?");
168 encode = 1;
169 } else {
170 buf_cat(space, word);
171 buf_move(word, space);
172 }
173 encode_word(word);
174 }
175 if (encode && !encodeword) {
176 encode = 0;
177 buf_appends(out, "?=");
178 }
179 buf_cat(out, space);
180 buf_cat(out, word);
181 encodeword = 0;
182 buf_clear(space);
183 buf_clear(word);
184 }
185 buf_appendc(space, in->data[i]);
186 } else {
187 if (in->data[i] < 32 || in->data[i] >= 127)
188 encodeword = 1;
189 buf_appendc(word, in->data[i]);
190 }
191 }
192 if (encode)
193 buf_appends(out, "?=");
194
195 buf_move(in, out);
196 while (n > 0 && in->length - in->ptr > n) {
197 for (i = 1; i < in->length - in->ptr; i++)
198 if (isspace(in->data[in->length - i]))
199 break;
200 buf_get(in, out, in->length - i);
201 buf_appends(out, "\n\t");
202 }
203 buf_rest(out, in);
204 buf_move(in, out);
205 buf_free(out);
206 buf_free(space);
207 buf_free(word);
208 return (0);
209 }
210
211 void addprintable(BUFFER *out, int c)
212 {
213 if (c == '\n')
214 buf_appendc(out, (char) c);
215 else if (c == '\t')
216 buf_appends(out, " ");
217 else if (c == '\014')
218 buf_appends(out, "^L");
219 else if (c == '\r') ;
220 else if (c <= 31 || (c >= 128 && c <= 128 + 31))
221 buf_appendc(out, '?');
222 else
223 buf_appendc(out, (char) c);
224 }
225
226 void addprintablebuf(BUFFER *out, BUFFER *in)
227 {
228 int c;
229
230 while ((c = buf_getc(in)) != -1)
231 addprintable(out, c);
232 }
233
234 int decode_line(BUFFER *line)
235 {
236 BUFFER *out;
237 unsigned int i;
238 int c, softbreak = 0;
239
240 out = buf_new();
241 for (i = 0; line->data[i] != '\0'; i++) {
242 if (line->data[i] == '=') {
243 if (isxdigit(line->data[i + 1]) && isxdigit(line->data[i + 2])) {
244 c = hex(line->data[i + 1]) * 16 + hex(line->data[i + 2]);
245 i += 2;
246 addprintable(out, c);
247 } else if (line->data[i + 1] == '\0') {
248 softbreak = 1;
249 break;
250 }
251 } else
252 addprintable(out, line->data[i]);
253 }
254
255 buf_move(line, out);
256 buf_free(out);
257 return (softbreak);
258 }
259
260 int decode_header(BUFFER *in)
261 {
262 int encoded = 0;
263 int c;
264 int err = 0;
265 int last = 0;
266 BUFFER *out;
267
268 out = buf_new();
269 for (in->ptr = 0; in->data[in->ptr] != '\0'; in->ptr++) {
270 if (encoded == 'q' && in->data[in->ptr] == '=' &&
271 isxdigit(in->data[in->ptr + 1])
272 && isxdigit(in->data[in->ptr + 2])) {
273 c = hex(in->data[in->ptr + 1]) * 16 + hex(in->data[in->ptr + 2]);
274 in->ptr += 2;
275 addprintable(out, c);
276 } else if (encoded == 'q' && in->data[in->ptr] == '_')
277 buf_appendc(out, ' ');
278 else if (in->data[in->ptr] == '=' && in->data[in->ptr + 1] == '?' &&
279 in->data[in->ptr + 2] != '\0') {
280 if (last > 0 && out->length > last) {
281 out->data[last] = '\0';
282 out->length = last;
283 }
284 in->ptr++;
285 while (in->data[++in->ptr] != '?')
286 if (in->data[in->ptr] == 0) {
287 err = -1;
288 goto end;
289 }
290 if (in->data[in->ptr + 1] != '\0' && in->data[in->ptr + 2] == '?') {
291 encoded = tolower(in->data[in->ptr + 1]);
292 in->ptr += 2;
293 if (encoded == 'b') {
294 BUFFER *tmp;
295
296 tmp = buf_new();
297 decode(in, tmp);
298 addprintablebuf(out, tmp);
299 last = out->length;
300 buf_free(tmp);
301 } else if (encoded != 'q')
302 err = 1;
303 } else {
304 err = -1;
305 goto end;
306 }
307 } else if (encoded && in->data[in->ptr] == '?' &&
308 in->data[in->ptr + 1] == '=') {
309 in->ptr++;
310 last = out->length;
311 encoded = 0;
312 } else {
313 addprintable(out, in->data[in->ptr]);
314 if (!encoded || !isspace(in->data[in->ptr]))
315 last = out->length;
316 }
317 }
318 end:
319 if (err == -1)
320 buf_set(out, in);
321
322 buf_move(in, out);
323 buf_free(out);
324 return (err);
325 }
326
327 #define delimclose 2
328
329 int boundary(BUFFER *line, BUFFER *boundary)
330 {
331 int c;
332
333 if (boundary->length == 0 || !bufleft(line, "--") ||
334 !strleft(line->data + 2, boundary->data))
335 return (0);
336 line->ptr = boundary->length + 2;
337 for (;;) {
338 c = buf_getc(line);
339 if (c == -1)
340 return (1);
341 if (c == '-' && buf_getc(line) == '-')
342 return (delimclose);
343 if (!isspace(c))
344 return (0);
345 }
346 }
347
348 #define pgpenc 1
349 #define pgpsig 2
350
351 /*
352 * decodes non-multipart quoted printable message
353 */
354 int qp_decode_message(BUFFER *msg)
355 {
356 BUFFER *out, *line, *field, *content;
357 out = buf_new();
358 line = buf_new();
359 field = buf_new();
360 content = buf_new();
361
362 buf_rewind(msg);
363
364 /* copy over headers without decoding */
365 while (buf_getheader(msg, field, content) == 0) {
366 if (bufieq(field, "content-transfer-encoding")
367 && bufieq(content, "quoted-printable")) {
368 continue; /* no longer quoted-printable */
369 } else {
370 buf_appendheader(out, field, content);
371 }
372 }
373
374 buf_nl(out);
375
376 /* copy over body, quoted-printable decoding as we go */
377 while (buf_getline(msg, line) != -1) {
378 int softbreak;
379 softbreak = decode_line(line);
380 buf_cat(out, line);
381 if (!softbreak)
382 buf_nl(out);
383 }
384 buf_move(msg, out);
385 buf_free(out);
386 buf_free(line);
387 buf_free(field);
388 buf_free(content);
389 return 0;
390 }
391
392
393 int entity_decode(BUFFER *msg, int message, int mptype, BUFFER *data)
394 {
395 BUFFER *out, *line, *field, *content, *type, *subtype, *disposition,
396 *mboundary, *part, *sigdata;
397 int ret = 0, ptype = 0, partno = 0;
398 int p, encoded = 0;
399
400 out = buf_new();
401 line = buf_new();
402 field = buf_new();
403 content = buf_new();
404 type = buf_new();
405 subtype = buf_new();
406 disposition = buf_new();
407 mboundary = buf_new();
408 part = buf_new();
409 sigdata = buf_new();
410
411 if (message && bufileft(msg, "From ")) {
412 buf_getline(msg, out); /* envelope from */
413 buf_nl(out);
414 }
415
416 while (buf_getheader(msg, field, content) == 0) {
417 if (bufieq(field, "content-transfer-encoding") &&
418 bufieq(content, "quoted-printable"))
419 encoded = 'q';
420 if (bufieq(field, "content-type")) {
421 get_type(content, type, subtype);
422 if (bufieq(type, "multipart"))
423 get_parameter(content, "boundary", mboundary);
424 if (bufieq(type, "multipart") && bufieq(subtype, "encrypted")) {
425 get_parameter(content, "protocol", line);
426 if (bufieq(line, "application/pgp-encrypted"))
427 ptype = pgpenc;
428 }
429 if (bufieq(type, "multipart") && bufieq(subtype, "signed")) {
430 get_parameter(content, "protocol", line);
431 if (bufieq(line, "application/pgp-signature"))
432 ptype = pgpsig;
433 }
434 }
435 if (bufieq(field, "content-disposition"))
436 buf_set(disposition, content);
437 if (message) {
438 decode_header(content);
439 buf_appendheader(out, field, content);
440 }
441 }
442
443 if (message)
444 buf_nl(out);
445
446 if (bufifind(disposition, "attachment")) {
447 buf_appendf(out, "[-- %b attachment", type);
448 get_parameter(disposition, "filename", line);
449 if (line->length)
450 buf_appendf(out, " (%b)", line);
451 buf_appends(out, " --]\n");
452 }
453
454 if (mboundary->length) {
455 /* multipart */
456 while (buf_getline(msg, line) > -1 && !boundary(line, mboundary))
457 ; /* ignore preamble */
458 while (buf_getline(msg, line) != -1) {
459 p = boundary(line, mboundary);
460 if (p) {
461 if (part->data[part->length - 1] == '\n')
462 part->data[--(part->length)] = '\0';
463 partno++;
464 if (ptype == pgpsig && partno == 1)
465 buf_set(sigdata, part);
466 ret += entity_decode(part, 0, ptype, sigdata);
467 buf_cat(out, part);
468 buf_clear(part);
469 if (p == delimclose)
470 break;
471 if (bufieq(subtype, "alternative") && ret > 0)
472 break;
473 if (bufieq(subtype, "mixed"))
474 buf_appends(out,
475 "[-------------------------------------------------------------------------]\n");
476 } else {
477 buf_cat(part, line);
478 buf_nl(part);
479 }
480 }
481 } else if (mptype == pgpenc && bufieq(type, "application") &&
482 bufieq(subtype, "pgp-encrypted")) {
483 /* application/pgp-encrypted part of multipart/encrypted */
484 ; /* skip */
485 } else if (mptype == pgpenc && bufieq(type, "application") &&
486 bufieq(subtype, "octet-stream")) {
487 /* application/octet-stream part of multipart/encrypted */
488 int ok = 0;
489 buf_getline(msg, line);
490 if (bufleft(line, info_beginpgp)) {
491 if (buffind(line, "(SIGNED)")) {
492 buf_getline(msg, line);
493 buf_appends(out, "[-- OpenPGP message with signature --]\n");
494 if (bufleft(line, info_pgpsig))
495 buf_appendf(out, "[%s]\n",
496 line->data + sizeof(info_pgpsig) - 1);
497 else
498 buf_appends(out, "[Signature invalid]\n");
499 } else
500 buf_appends(out, "[-- OpenPGP message --]\n");
501 while (buf_getline(msg, line) != -1) {
502 if (bufleft(line, info_endpgp)) {
503 ret += entity_decode(part, 0, 0, NULL);
504 buf_cat(out, part);
505 buf_appends(out, "[-- End OpenPGP message --]\n");
506 ok = 1, ret++;
507 break;
508 }
509 buf_cat(part, line);
510 buf_nl(part);
511 }
512 }
513 if (!ok) {
514 buf_appends(out, "[-- Bad OpenPGP message --]\n");
515 buf_cat(out, msg);
516 }
517 } else if (mptype == pgpsig && bufeq(type, "application") &&
518 bufieq(subtype, "pgp-signature")) {
519 buf_rest(part, msg);
520 if (pgp_decrypt(part, NULL, data, PGPPUBRING, NULL) == PGP_SIGOK)
521 buf_appendf(out, "[-- OpenPGP signature from:\n %b --]\n", data);
522 else
523 buf_appends(out, "[-- Invalid OpenPGP signature --]\n");
524 } else if (type->length == 0 || bufieq(type, "text")) {
525 while (buf_getline(msg, line) != -1) {
526 int softbreak;
527 softbreak = encoded ? decode_line(line) : 0;
528 buf_cat(out, line);
529 if (!softbreak)
530 buf_nl(out);
531 }
532 ret++;
533 } else {
534 buf_appendf(out, "[-- %b/%b message part --]\n", type, subtype);
535 buf_cat(out, msg);
536 }
537
538 buf_move(msg, out);
539 buf_free(line);
540 buf_free(out);
541 buf_free(field);
542 buf_free(content);
543 buf_free(type);
544 buf_free(subtype);
545 buf_free(disposition);
546 buf_free(mboundary);
547 buf_free(part);
548 buf_free(sigdata);
549 return (0);
550 }
551
552 void mimedecode(BUFFER *msg)
553 {
554 entity_decode(msg, 1, 0, NULL);
555 }
556
557 int attachfile(BUFFER *message, BUFFER *filename)
558 {
559 BUFFER *type, *attachment;
560 FILE *f;
561 int ret = -1;
562
563 type = buf_new();
564 attachment = buf_new();
565
566 if ((bufiright(filename, ".txt") || !bufifind(filename, ".")) &&(strlen(DEFLTENTITY) != 0))
567 buf_sets(type, DEFLTENTITY);
568 else if (bufiright(filename, ".htm") || bufiright(filename, ".html"))
569 buf_sets(type, "text/html");
570 else if (bufiright(filename, ".jpeg"))
571 buf_sets(type, "image/jpeg");
572 else if (bufiright(filename, ".gif"))
573 buf_sets(type, "image/gif");
574 else if (bufiright(filename, ".pcm"))
575 buf_sets(type, "audio/basic");
576 else if (bufiright(filename, ".mpg") || bufiright(filename, ".mpeg"))
577 buf_sets(type, "video/mpeg");
578 else if (bufiright(filename, ".ps"))
579 buf_sets(type, "application/postscript");
580 else
581 buf_sets(type, "application/octet-stream");
582
583 f = fopen(filename->data, "r");
584 if (f) {
585 buf_read(attachment, f);
586 fclose(f);
587 ret = mime_attach(message, attachment, type);
588 }
589
590 buf_free(attachment);
591 buf_free(type);
592 return(ret);
593 }
594
595 int mime_attach(BUFFER *message, BUFFER *attachment, BUFFER *attachtype)
596 {
597 BUFFER *out, *part, *line, *type, *subtype, *mboundary, *field, *content;
598 int mimeheader = 0, multipart = 0, versionheader = 0;
599
600 out = buf_new();
601 line = buf_new();
602 part = buf_new();
603 type = buf_new();
604 subtype = buf_new();
605 mboundary = buf_new();
606 field = buf_new();
607 content = buf_new();
608
609 buf_rewind(message);
610 while (buf_getheader(message, field, content) == 0) {
611 if (bufieq(field, "mime-version"))
612 versionheader = 1;
613 if (bufieq(field, "content-type")) {
614 get_type(content, type, subtype);
615 if (bufieq(type, "multipart") && bufieq(subtype, "mixed")) {
616 multipart = 1;
617 get_parameter(content, "boundary", mboundary);
618 }
619 }
620 if (bufileft(field, "content-"))
621 mimeheader = 1;
622 }
623
624 if (mimeheader && !multipart) {
625 buf_rewind(message);
626 while (buf_getheader(message, field, content) == 0) {
627 if (bufileft(field, "content-"))
628 buf_appendheader(part, field, content);
629 else
630 buf_appendheader(out, field, content);
631 }
632 } else {
633 buf_ungetc(message);
634 buf_append(out, message->data, message->ptr);
635 buf_getc(message);
636 }
637
638 if (!versionheader)
639 buf_appends(out, "MIME-Version: 1.0\n");
640
641 if (!multipart) {
642 buf_setrnd(mboundary, 18);
643 encode(mboundary, 0);
644 buf_appendf(out, "Content-Type: multipart/mixed; boundary=\"%b\"\n",
645 mboundary);
646 }
647 buf_nl(out);
648
649 if (multipart) {
650 while (buf_getline(message, line) != -1) {
651 if (boundary(line, mboundary) == delimclose)
652 break;
653 buf_cat(out, line);
654 buf_nl(out);
655 }
656 } else {
657 buf_appendf(out, "--%b\n", mboundary);
658 if (part->length) {
659 buf_cat(out, part); /* body part header */
660 }
661 else {
662 if (strlen(DEFLTENTITY))
663 buf_appendf(out, "Content-Type: %s\n", DEFLTENTITY);
664 }
665
666 buf_nl(out);
667 buf_cat(out, message);
668 buf_nl(out);
669 }
670
671 buf_appendf(out, "--%b\n", mboundary);
672 buf_appendf(out, "Content-Type: %b\n", attachtype);
673
674 body_encode(attachment, MIME_8BIT, line);
675 buf_cat(out, line);
676 buf_nl(out);
677 buf_cat(out, attachment);
678 buf_appendf(out, "\n--%b--\n", mboundary);
679
680 buf_move(message, out);
681
682 buf_free(out);
683 buf_free(line);
684 buf_free(part);
685 buf_free(type);
686 buf_free(subtype);
687 buf_free(mboundary);
688 buf_free(field);
689 buf_free(content);
690 return (1);
691 }
692
693 static int entity_encode(BUFFER *message, BUFFER *out, BUFFER *messagehdr,
694 int encoding)
695 {
696 BUFFER *field, *content, *mboundary, *part, *line, *line2, *tmp;
697
698 field = buf_new();
699 content = buf_new();
700 mboundary = buf_new();
701 part = buf_new();
702 line = buf_new();
703 line2 = buf_new();
704 tmp = buf_new();
705
706 buf_rewind(message);
707 buf_clear(out);
708 buf_clear(messagehdr);
709
710 while (buf_getheader(message, field, content) == 0) {
711 if (bufileft(field, "content-"))
712 buf_appendheader(out, field, content);
713 else if (messagehdr)
714 buf_appendheader(messagehdr, field, content);
715
716 if (bufieq(field, "content-type")) {
717 get_type(content, line, tmp);
718 if (bufieq(line, "multipart"))
719 get_parameter(content, "boundary", mboundary);
720 }
721 }
722
723 buf_nl(out);
724 if (mboundary->length) {
725 while (buf_getline(message, line) != -1) {
726 buf_cat(out, line);
727 buf_nl(out);
728 if (boundary(line, mboundary))
729 break;
730 }
731 while (buf_getline(message, line) != -1) {
732 if (boundary(line, mboundary)) {
733 entity_encode(part, tmp, line2, encoding);
734 buf_cat(out, line2);
735 buf_cat(out, tmp);
736 buf_cat(out, line);
737 buf_nl(out);
738 buf_clear(part);
739 if (boundary(line, mboundary) == delimclose)
740 break;
741 } else {
742 buf_cat(part, line);
743 buf_nl(part);
744 }
745 }
746 } else
747 buf_rest(out, message);
748 buf_rewind(out);
749 mail_encode(out, encoding);
750
751 buf_free(field);
752 buf_free(content);
753 buf_free(mboundary);
754 buf_free(part);
755 buf_free(line);
756 buf_free(line2);
757 buf_free(tmp);
758 return (1);
759 }
760
761 int pgpmime_sign(BUFFER *message, BUFFER *uid, BUFFER *pass, char *secring)
762 {
763 BUFFER *out, *body, *mboundary, *algo;
764 int err;
765
766 out = buf_new();
767 body = buf_new();
768 mboundary = buf_new();
769 algo = buf_new();
770
771 pgp_signhashalgo(algo, uid, secring, pass);
772
773 entity_encode(message, body, out, MIME_7BIT);
774
775 buf_setrnd(mboundary, 18);
776 encode(mboundary, 0);
777 buf_appendf(out, "Content-Type: multipart/signed; boundary=\"%b\";\n",
778 mboundary);
779 buf_appendf(out,
780 "\tmicalg=pgp-%b; protocol=\"application/pgp-signature\"\n",
781 algo);
782 buf_nl(out);
783
784 buf_appendf(out, "--%b\n", mboundary);
785 buf_cat(out, body);
786 buf_nl(out);
787 buf_appendf(out, "--%b\n", mboundary);
788
789 err = pgp_encrypt(PGP_SIGN | PGP_TEXT | PGP_DETACHEDSIG, body, NULL,
790 uid, pass, NULL, secring);
791
792 buf_appends(out, "Content-Type: application/pgp-signature\n");
793 buf_nl(out);
794 buf_cat(out, body);
795 buf_nl(out);
796 buf_appendf(out, "--%b--\n", mboundary);
797 if (err == 0)
798 buf_move(message, out);
799
800 buf_free(out);
801 buf_free(body);
802 buf_free(mboundary);
803 buf_free(algo);
804 return (err);
805 }

  ViewVC Help
Powered by ViewVC 1.1.5