/[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 - (hide 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 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     MIME functions
9 rabbi 41 $Id: mime.c,v 1.2 2001/12/12 19:29:52 rabbi Exp $ */
10 rabbi 1
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 rabbi 41 /*
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 rabbi 1 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