gpg: Fix using --decrypt along with --use-embedded-filename.
[gnupg.git] / tools / mime-maker.c
1 /* mime-maker.c - Create MIME structures
2  * Copyright (C) 2016 g10 Code GmbH
3  * Copyright (C) 2016 Bundesamt für Sicherheit in der Informationstechnik
4  *
5  * This file is part of GnuPG.
6  *
7  * This file is free software; you can redistribute it and/or modify
8  * it under the terms of the GNU Lesser General Public License as
9  * published by the Free Software Foundation; either version 2.1 of
10  * the License, or (at your option) any later version.
11  *
12  * This file is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15  * GNU Lesser General Public License for more details.
16  *
17  * You should have received a copy of the GNU Lesser General Public License
18  * along with this program; if not, see <https://www.gnu.org/licenses/>.
19  */
20
21 #include <config.h>
22 #include <stdio.h>
23 #include <stdlib.h>
24 #include <string.h>
25
26 #include "../common/util.h"
27 #include "../common/zb32.h"
28 #include "rfc822parse.h"
29 #include "mime-maker.h"
30
31
32 /* An object to store an header.  Also used for a list of headers.  */
33 struct header_s
34 {
35   struct header_s *next;
36   char *value;   /* Malloced value.  */
37   char name[1]; /* Name.  */
38 };
39 typedef struct header_s *header_t;
40
41
42 /* An object to store a MIME part.  A part is the header plus the
43  * content (body). */
44 struct part_s
45 {
46   struct part_s *next;  /* Next part in the current container.  */
47   struct part_s *child; /* Child container.  */
48   char *boundary;       /* Malloced boundary string.  */
49   header_t headers;     /* List of headers.  */
50   header_t *headers_tail;/* Address of last header in chain.  */
51   size_t bodylen;       /* Length of BODY.   */
52   char *body;           /* Malloced buffer with the body.  This is the
53                          * non-encoded value.  */
54   unsigned int partid;   /* The part ID.  */
55 };
56 typedef struct part_s *part_t;
57
58
59
60 /* Definition of the mime parser object.  */
61 struct mime_maker_context_s
62 {
63   void *cookie;                /* Cookie passed to all callbacks.  */
64
65   unsigned int verbose:1;      /* Enable verbose mode.  */
66   unsigned int debug:1;        /* Enable debug mode.  */
67
68   part_t mail;                 /* The MIME tree.  */
69   part_t current_part;
70
71   unsigned int partid_counter; /* Counter assign part ids.  */
72
73   int boundary_counter;  /* Used to create easy to read boundaries.  */
74   char *boundary_suffix; /* Random string used in the boundaries.  */
75
76   struct b64state *b64state;     /* NULL or malloced Base64 decoder state.  */
77
78   /* Helper to convey the output stream to recursive functions. */
79   estream_t outfp;
80 };
81
82
83 /* Create a new mime make object.  COOKIE is a values woich will be
84  * used as first argument for all callbacks registered with this
85  * object.  */
86 gpg_error_t
87 mime_maker_new (mime_maker_t *r_maker, void *cookie)
88 {
89   mime_maker_t ctx;
90
91   *r_maker = NULL;
92
93   ctx = xtrycalloc (1, sizeof *ctx);
94   if (!ctx)
95     return gpg_error_from_syserror ();
96   ctx->cookie = cookie;
97
98   *r_maker = ctx;
99   return 0;
100 }
101
102
103 static void
104 release_parts (part_t part)
105 {
106   while (part)
107     {
108       part_t partnext = part->next;
109       while (part->headers)
110         {
111           header_t hdrnext = part->headers->next;
112           xfree (part->headers);
113           part->headers = hdrnext;
114         }
115       release_parts (part->child);
116       xfree (part->boundary);
117       xfree (part->body);
118       xfree (part);
119       part = partnext;
120     }
121 }
122
123
124 /* Release a mime maker object.  */
125 void
126 mime_maker_release (mime_maker_t ctx)
127 {
128   if (!ctx)
129     return;
130
131   release_parts (ctx->mail);
132   xfree (ctx->boundary_suffix);
133   xfree (ctx);
134 }
135
136
137 /* Set verbose and debug mode.  */
138 void
139 mime_maker_set_verbose (mime_maker_t ctx, int level)
140 {
141   if (!level)
142     {
143       ctx->verbose = 0;
144       ctx->debug = 0;
145     }
146   else
147     {
148       ctx->verbose = 1;
149       if (level > 10)
150         ctx->debug = 1;
151     }
152 }
153
154
155 static void
156 dump_parts (part_t part, int level)
157 {
158   header_t hdr;
159
160   for (; part; part = part->next)
161     {
162       log_debug ("%*s[part %u]\n", level*2, "", part->partid);
163       for (hdr = part->headers; hdr; hdr = hdr->next)
164         {
165           log_debug ("%*s%s: %s\n", level*2, "", hdr->name, hdr->value);
166         }
167       if (part->body)
168         log_debug ("%*s[body %zu bytes]\n", level*2, "", part->bodylen);
169       if (part->child)
170         {
171           log_debug ("%*s[container]\n", level*2, "");
172           dump_parts (part->child, level+1);
173         }
174     }
175 }
176
177
178 /* Dump the mime tree for debugging.  */
179 void
180 mime_maker_dump_tree (mime_maker_t ctx)
181 {
182   dump_parts (ctx->mail, 0);
183 }
184
185
186 /* Find the parent node for NEEDLE starting at ROOT.  */
187 static part_t
188 find_parent (part_t root, part_t needle)
189 {
190   part_t node, n;
191
192   for (node = root->child; node; node = node->next)
193     {
194       if (node == needle)
195         return root;
196       if ((n = find_parent (node, needle)))
197         return n;
198     }
199   return NULL;
200 }
201
202 /* Find the part node from the PARTID.  */
203 static part_t
204 find_part (part_t root, unsigned int partid)
205 {
206   part_t node, n;
207
208   for (node = root->child; node; node = node->next)
209     {
210       if (node->partid == partid)
211         return root;
212       if ((n = find_part (node, partid)))
213         return n;
214     }
215   return NULL;
216 }
217
218
219 /* Create a boundary string.  Outr codes is aware of the general
220  * structure of that string (gebins with "=-=") so that
221  * it can protect against accidentally-used boundaries within the
222  * content.   */
223 static char *
224 generate_boundary (mime_maker_t ctx)
225 {
226   if (!ctx->boundary_suffix)
227     {
228       char buffer[12];
229
230       gcry_create_nonce (buffer, sizeof buffer);
231       ctx->boundary_suffix = zb32_encode (buffer, 8 * sizeof buffer);
232       if (!ctx->boundary_suffix)
233         return NULL;
234     }
235
236   ctx->boundary_counter++;
237   return es_bsprintf ("=-=%02d-%s=-=",
238                       ctx->boundary_counter, ctx->boundary_suffix);
239 }
240
241
242 /* Ensure that the context has a MAIL and CURRENT_PART object and
243  * return the parent object if available  */
244 static gpg_error_t
245 ensure_part (mime_maker_t ctx, part_t *r_parent)
246 {
247   if (!ctx->mail)
248     {
249       ctx->mail = xtrycalloc (1, sizeof *ctx->mail);
250       if (!ctx->mail)
251         {
252           if (r_parent)
253             *r_parent = NULL;
254           return gpg_error_from_syserror ();
255         }
256       log_assert (!ctx->current_part);
257       ctx->current_part = ctx->mail;
258       ctx->current_part->headers_tail = &ctx->current_part->headers;
259     }
260   log_assert (ctx->current_part);
261   if (r_parent)
262     *r_parent = find_parent (ctx->mail, ctx->current_part);
263
264   return 0;
265 }
266
267
268 /* Check whether a header with NAME has already been set into PART.
269  * NAME must be in canonical capitalized format.  Return true or
270  * false. */
271 static int
272 have_header (part_t part, const char *name)
273 {
274   header_t hdr;
275
276   for (hdr = part->headers; hdr; hdr = hdr->next)
277     if (!strcmp (hdr->name, name))
278       return 1;
279   return 0;
280 }
281
282
283 /* Helper to add a header to a part.  */
284 static gpg_error_t
285 add_header (part_t part, const char *name, const char *value)
286 {
287   gpg_error_t err;
288   header_t hdr;
289   size_t namelen;
290   const char *s;
291   char *p;
292
293   if (!value)
294     {
295       s = strchr (name, '=');
296       if (!s)
297         return gpg_error (GPG_ERR_INV_ARG);
298       namelen = s - name;
299       value = s+1;
300     }
301   else
302     namelen = strlen (name);
303
304   hdr = xtrymalloc (sizeof *hdr + namelen);
305   if (!hdr)
306     return gpg_error_from_syserror ();
307   hdr->next = NULL;
308   memcpy (hdr->name, name, namelen);
309   hdr->name[namelen] = 0;
310
311   /* Check that the header name is valid.  */
312   if (!rfc822_valid_header_name_p (hdr->name))
313     {
314       xfree (hdr);
315       return gpg_error (GPG_ERR_INV_NAME);
316     }
317
318   rfc822_capitalize_header_name (hdr->name);
319   hdr->value = xtrystrdup (value);
320   if (!hdr->value)
321     {
322       err = gpg_error_from_syserror ();
323       xfree (hdr);
324       return err;
325     }
326
327   for (p = hdr->value + strlen (hdr->value) - 1;
328        (p >= hdr->value
329         && (*p == ' ' || *p == '\t' || *p == '\n' || *p == '\r'));
330        p--)
331     *p = 0;
332   if (!(p >= hdr->value))
333     {
334       xfree (hdr->value);
335       xfree (hdr);
336       return gpg_error (GPG_ERR_INV_VALUE);  /* Only spaces.  */
337     }
338
339   if (part)
340     {
341       *part->headers_tail = hdr;
342       part->headers_tail = &hdr->next;
343     }
344   else
345     xfree (hdr);
346
347   return 0;
348 }
349
350
351 /* Add a header with NAME and VALUE to the current mail.  A LF in the
352  * VALUE will be handled automagically.  If NULL is used for VALUE it
353  * is expected that the NAME has the format "NAME=VALUE" and VALUE is
354  * taken from there.
355  *
356  * If no container has been added, the header will be used for the
357  * regular mail headers and not for a MIME part.  If the current part
358  * is in a container and a body has been added, we append a new part
359  * to the current container.  Thus for a non-MIME mail the caller
360  * needs to call this function followed by a call to add a body.  When
361  * adding a Content-Type the boundary parameter must not be included.
362  */
363 gpg_error_t
364 mime_maker_add_header (mime_maker_t ctx, const char *name, const char *value)
365 {
366   gpg_error_t err;
367   part_t part, parent;
368
369   /* Hack to use this function for a syntax check of NAME and VALUE.  */
370   if (!ctx)
371     return add_header (NULL, name, value);
372
373   err = ensure_part (ctx, &parent);
374   if (err)
375     return err;
376   part = ctx->current_part;
377
378   if ((part->body || part->child) && !parent)
379     {
380       /* We already have a body but no parent.  Adding another part is
381        * thus not possible.  */
382       return gpg_error (GPG_ERR_CONFLICT);
383     }
384   if (part->body || part->child)
385     {
386       /* We already have a body and there is a parent.  We now append
387        * a new part to the current container.  */
388       part = xtrycalloc (1, sizeof *part);
389       if (!part)
390         return gpg_error_from_syserror ();
391       part->partid = ++ctx->partid_counter;
392       part->headers_tail = &part->headers;
393       log_assert (!ctx->current_part->next);
394       ctx->current_part->next = part;
395       ctx->current_part = part;
396     }
397
398   /* If no NAME and no VALUE has been given we do not add a header.
399    * This can be used to create a new part without any header.  */
400   if (!name && !value)
401     return 0;
402
403   /* If we add Content-Type, make sure that we have a MIME-version
404    * header first; this simply looks better.  */
405   if (!ascii_strcasecmp (name, "Content-Type")
406       && !have_header (ctx->mail, "MIME-Version"))
407     {
408       err = add_header (ctx->mail, "MIME-Version", "1.0");
409       if (err)
410         return err;
411     }
412   return add_header (part, name, value);
413 }
414
415
416 /* Helper for mime_maker_add_{body,stream}.  */
417 static gpg_error_t
418 add_body (mime_maker_t ctx, const void *data, size_t datalen)
419 {
420   gpg_error_t err;
421   part_t part, parent;
422
423   err = ensure_part (ctx, &parent);
424   if (err)
425     return err;
426   part = ctx->current_part;
427   if (part->body)
428     return gpg_error (GPG_ERR_CONFLICT);
429
430   part->body = xtrymalloc (datalen? datalen : 1);
431   if (!part->body)
432     return gpg_error_from_syserror ();
433   part->bodylen = datalen;
434   if (data)
435     memcpy (part->body, data, datalen);
436
437   return 0;
438 }
439
440
441 /* Add STRING as body to the mail or the current MIME container.  A
442  * second call to this function or mime_make_add_body_data is not
443  * allowed.
444  *
445  * FIXME: We may want to have an append_body to add more data to a body.
446  */
447 gpg_error_t
448 mime_maker_add_body (mime_maker_t ctx, const char *string)
449 {
450   return add_body (ctx, string, strlen (string));
451 }
452
453
454 /* Add (DATA,DATALEN) as body to the mail or the current MIME
455  * container.  Note that a second call to this function or to
456  * mime_make_add_body is not allowed.  */
457 gpg_error_t
458 mime_maker_add_body_data (mime_maker_t ctx, const void *data, size_t datalen)
459 {
460   return add_body (ctx, data, datalen);
461 }
462
463
464 /* This is the same as mime_maker_add_body but takes a stream as
465  * argument.  As of now the stream is copied to the MIME object but
466  * eventually we may delay that and read the stream only at the time
467  * it is needed.  Note that the address of the stream object must be
468  * passed and that the ownership of the stream is transferred to this
469  * MIME object.  To indicate the latter the function will store NULL
470  * at the ADDR_STREAM so that a caller can't use that object anymore
471  * except for es_fclose which accepts a NULL pointer.  */
472 gpg_error_t
473 mime_maker_add_stream (mime_maker_t ctx, estream_t *stream_addr)
474 {
475   void *data;
476   size_t datalen;
477
478   es_rewind (*stream_addr);
479   if (es_fclose_snatch (*stream_addr, &data, &datalen))
480     return gpg_error_from_syserror ();
481   *stream_addr = NULL;
482   return add_body (ctx, data, datalen);
483 }
484
485
486 /* Add a new MIME container.  A container can be used instead of a
487  * body.  */
488 gpg_error_t
489 mime_maker_add_container (mime_maker_t ctx)
490 {
491   gpg_error_t err;
492   part_t part;
493
494   err = ensure_part (ctx, NULL);
495   if (err)
496     return err;
497   part = ctx->current_part;
498
499   if (part->body)
500     return gpg_error (GPG_ERR_CONFLICT); /* There is already a body. */
501   if (part->child || part->boundary)
502     return gpg_error (GPG_ERR_CONFLICT); /* There is already a container. */
503
504   /* Create a child node.  */
505   part->child = xtrycalloc (1, sizeof *part->child);
506   if (!part->child)
507     return gpg_error_from_syserror ();
508   part->child->headers_tail = &part->child->headers;
509
510   part->boundary = generate_boundary (ctx);
511   if (!part->boundary)
512     {
513       err = gpg_error_from_syserror ();
514       xfree (part->child);
515       part->child = NULL;
516       return err;
517     }
518
519   part = part->child;
520   part->partid = ++ctx->partid_counter;
521   ctx->current_part = part;
522
523   return 0;
524 }
525
526
527 /* Finish the current container.  */
528 gpg_error_t
529 mime_maker_end_container (mime_maker_t ctx)
530 {
531   gpg_error_t err;
532   part_t parent;
533
534   err = ensure_part (ctx, &parent);
535   if (err)
536     return err;
537   if (!parent)
538     return gpg_error (GPG_ERR_CONFLICT); /* No container.  */
539   while (parent->next)
540     parent = parent->next;
541   ctx->current_part = parent;
542   return 0;
543 }
544
545
546 /* Return the part-ID of the current part. */
547 unsigned int
548 mime_maker_get_partid (mime_maker_t ctx)
549 {
550   if (ensure_part (ctx, NULL))
551     return 0; /* Ooops.  */
552   return ctx->current_part->partid;
553 }
554
555
556 /* Write a header and handle emdedded LFs.  If BOUNDARY is not NULL it
557  * is appended to the value.  */
558 /* Fixme: Add automatic line wrapping.  */
559 static gpg_error_t
560 write_header (mime_maker_t ctx, const char *name, const char *value,
561               const char *boundary)
562 {
563   const char *s;
564
565   es_fprintf (ctx->outfp, "%s: ", name);
566
567   /* Note that add_header made sure that VALUE does not end with a LF.
568    * Thus we can assume that a LF is followed by non-whitespace.  */
569   for (s = value; *s; s++)
570     {
571       if (*s == '\n')
572         es_fputs ("\r\n\t", ctx->outfp);
573       else
574         es_fputc (*s, ctx->outfp);
575     }
576   if (boundary)
577     {
578       if (s > value && s[-1] != ';')
579         es_fputc (';', ctx->outfp);
580       es_fprintf (ctx->outfp, "\r\n\tboundary=\"%s\"", boundary);
581     }
582
583   es_fputs ("\r\n", ctx->outfp);
584
585   return es_ferror (ctx->outfp)? gpg_error_from_syserror () : 0;
586 }
587
588
589 static gpg_error_t
590 write_gap (mime_maker_t ctx)
591 {
592   es_fputs ("\r\n", ctx->outfp);
593   return es_ferror (ctx->outfp)? gpg_error_from_syserror () : 0;
594 }
595
596
597 static gpg_error_t
598 write_boundary (mime_maker_t ctx, const char *boundary, int last)
599 {
600   es_fprintf (ctx->outfp, "\r\n--%s%s\r\n", boundary, last?"--":"");
601   return es_ferror (ctx->outfp)? gpg_error_from_syserror () : 0;
602 }
603
604
605 /* Fixme: Apply required encoding.  */
606 static gpg_error_t
607 write_body (mime_maker_t ctx, const void *body, size_t bodylen)
608 {
609   const char *s;
610
611   for (s = body; bodylen; s++, bodylen--)
612     {
613       if (*s == '\n' && !(s > (const char *)body && s[-1] == '\r'))
614         es_fputc ('\r', ctx->outfp);
615       es_fputc (*s, ctx->outfp);
616     }
617
618   return es_ferror (ctx->outfp)? gpg_error_from_syserror () : 0;
619 }
620
621
622 /* Recursive worker for mime_maker_make.  */
623 static gpg_error_t
624 write_tree (mime_maker_t ctx, part_t parent, part_t part)
625 {
626   gpg_error_t err;
627   header_t hdr;
628
629   for (; part; part = part->next)
630     {
631       for (hdr = part->headers; hdr; hdr = hdr->next)
632         {
633           if (part->child && !strcmp (hdr->name, "Content-Type"))
634             err = write_header (ctx, hdr->name, hdr->value, part->boundary);
635           else
636             err = write_header (ctx, hdr->name, hdr->value, NULL);
637           if (err)
638             return err;
639         }
640       err = write_gap (ctx);
641       if (err)
642         return err;
643       if (part->body)
644         {
645           err = write_body (ctx, part->body, part->bodylen);
646           if (err)
647             return err;
648         }
649       if (part->child)
650         {
651           log_assert (part->boundary);
652           err = write_boundary (ctx, part->boundary, 0);
653           if (!err)
654             err = write_tree (ctx, part, part->child);
655           if (!err)
656             err = write_boundary (ctx, part->boundary, 1);
657           if (err)
658             return err;
659         }
660
661       if (part->next)
662         {
663           log_assert (parent && parent->boundary);
664           err = write_boundary (ctx, parent->boundary, 0);
665           if (err)
666             return err;
667         }
668     }
669   return 0;
670 }
671
672
673 /* Add headers we always require.  */
674 static gpg_error_t
675 add_missing_headers (mime_maker_t ctx)
676 {
677   gpg_error_t err;
678
679   if (!ctx->mail)
680     return gpg_error (GPG_ERR_NO_DATA);
681   if (!have_header (ctx->mail, "MIME-Version"))
682     {
683       /* Even if a Content-Type has never been set, we want to
684        * announce that we do MIME.  */
685       err = add_header (ctx->mail, "MIME-Version", "1.0");
686       if (err)
687         goto leave;
688     }
689
690   if (!have_header (ctx->mail, "Date"))
691     {
692       char *p = rfctimestamp (make_timestamp ());
693       if (!p)
694         err = gpg_error_from_syserror ();
695       else
696         err = add_header (ctx->mail, "Date", p);
697       xfree (p);
698       if (err)
699         goto leave;
700     }
701
702   err = 0;
703
704  leave:
705   return err;
706 }
707
708
709 /* Create message from the tree MIME and write it to FP.  Note that
710  * the output uses only a LF and a later called sendmail(1) is
711  * expected to convert them to network line endings.  */
712 gpg_error_t
713 mime_maker_make (mime_maker_t ctx, estream_t fp)
714 {
715   gpg_error_t err;
716
717   err = add_missing_headers (ctx);
718   if (err)
719     return err;
720
721   ctx->outfp = fp;
722   err = write_tree (ctx, NULL, ctx->mail);
723
724   ctx->outfp = NULL;
725   return err;
726 }
727
728
729 /* Create a stream object from the MIME part identified by PARTID and
730  * store it at R_STREAM.  If PARTID identifies a container the entire
731  * tree is returned. Using that function may read stream objects
732  * which have been added as MIME bodies.  The caller must close the
733  * stream object. */
734 gpg_error_t
735 mime_maker_get_part (mime_maker_t ctx, unsigned int partid, estream_t *r_stream)
736 {
737   gpg_error_t err;
738   part_t part;
739   estream_t fp;
740
741   *r_stream = NULL;
742
743   /* When the entire tree is requested, we make sure that all missing
744    * headers are applied.  We don't do that if only a part is
745    * requested because the additional headers (like Date:) will only
746    * be added to part 0 headers anyway. */
747   if (!partid)
748     {
749        err = add_missing_headers (ctx);
750        if (err)
751          return err;
752        part = ctx->mail;
753     }
754   else
755     part = find_part (ctx->mail, partid);
756
757   /* For now we use a memory stream object; however it would also be
758    * possible to create an object created on the fly while the caller
759    * is reading the returned stream.  */
760   fp = es_fopenmem (0, "w+b");
761   if (!fp)
762     return gpg_error_from_syserror ();
763
764   ctx->outfp = fp;
765   err = write_tree (ctx, NULL, part);
766   ctx->outfp = NULL;
767
768   if (!err)
769     {
770       es_rewind (fp);
771       *r_stream = fp;
772     }
773   else
774     es_fclose (fp);
775
776   return err;
777 }