wks: Make sure that the draft 2 request is correctly detected.
[gnupg.git] / tools / mime-parser.c
1 /* mime-parser.c - Parse MIME structures (high level rfc822 parser).
2  * Copyright (C) 2016 g10 Code GmbH
3  *
4  * This file is part of GnuPG.
5  *
6  * GnuPG is free software; you can redistribute it and/or modify
7  * it under the terms of the GNU General Public License as published by
8  * the Free Software Foundation; either version 3 of the License, or
9  * (at your option) any later version.
10  *
11  * GnuPG is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14  * GNU General Public License for more details.
15  *
16  * You should have received a copy of the GNU General Public License
17  * along with this program; if not, see <https://www.gnu.org/licenses/>.
18  */
19
20 #include <config.h>
21 #include <stdio.h>
22 #include <stdlib.h>
23 #include <string.h>
24
25 #include "util.h"
26 #include "rfc822parse.h"
27 #include "mime-parser.h"
28
29
30 enum pgpmime_states
31   {
32     PGPMIME_NONE = 0,
33     PGPMIME_WAIT_ENCVERSION,
34     PGPMIME_IN_ENCVERSION,
35     PGPMIME_WAIT_ENCDATA,
36     PGPMIME_IN_ENCDATA,
37     PGPMIME_GOT_ENCDATA,
38     PGPMIME_WAIT_SIGNEDDATA,
39     PGPMIME_IN_SIGNEDDATA,
40     PGPMIME_WAIT_SIGNATURE,
41     PGPMIME_IN_SIGNATURE,
42     PGPMIME_GOT_SIGNATURE,
43     PGPMIME_INVALID
44   };
45
46
47 /* Definition of the mime parser object.  */
48 struct mime_parser_context_s
49 {
50   void *cookie;                /* Cookie passed to all callbacks.  */
51
52   /* The callback to announce the transation from header to body.  */
53   gpg_error_t (*t2body) (void *cookie, int level);
54
55   /* The callback to announce a new part.  */
56   gpg_error_t (*new_part) (void *cookie,
57                            const char *mediatype,
58                            const char *mediasubtype);
59   /* The callback to return data of a part.  */
60   gpg_error_t (*part_data) (void *cookie,
61                             const void *data,
62                             size_t datalen);
63   /* The callback to collect encrypted data.  */
64   gpg_error_t (*collect_encrypted) (void *cookie, const char *data);
65   /* The callback to collect signed data.  */
66   gpg_error_t (*collect_signeddata) (void *cookie, const char *data);
67   /* The callback to collect a signature.  */
68   gpg_error_t (*collect_signature) (void *cookie, const char *data);
69
70   /* The RFC822 parser context is stored here during callbacks.  */
71   rfc822parse_t msg;
72
73   /* Helper to convey error codes from user callbacks.  */
74   gpg_error_t err;
75
76   int nesting_level;           /* The current nesting level.  */
77   int hashing_at_level;        /* The nesting level at which we are hashing. */
78   enum pgpmime_states pgpmime; /* Current PGP/MIME state.  */
79   unsigned int delay_hashing:1;/* Helper for PGPMIME_IN_SIGNEDDATA. */
80   unsigned int want_part:1;    /* Return the current part.  */
81   unsigned int decode_part:2;  /* Decode the part.  1 = QP, 2 = Base64. */
82
83   unsigned int verbose:1;      /* Enable verbose mode.  */
84   unsigned int debug:1;        /* Enable debug mode.  */
85
86   /* Flags to help with debug output.  */
87   struct {
88     unsigned int n_skip;         /* Skip showing these number of lines.  */
89     unsigned int header:1;       /* Show the header lines.  */
90     unsigned int data:1;         /* Show the data lines.  */
91     unsigned int as_note:1;      /* Show the next data line as a note.  */
92     unsigned int boundary : 1;
93   } show;
94
95   struct b64state *b64state;     /* NULL or malloced Base64 decoder state.  */
96
97   /* A buffer for reading a mail line,  */
98   char line[5000];
99 };
100
101
102 /* Print the event received by the parser for debugging.  */
103 static void
104 show_message_parser_event (rfc822parse_event_t event)
105 {
106   const char *s;
107
108   switch (event)
109     {
110     case RFC822PARSE_OPEN: s= "Open"; break;
111     case RFC822PARSE_CLOSE: s= "Close"; break;
112     case RFC822PARSE_CANCEL: s= "Cancel"; break;
113     case RFC822PARSE_T2BODY: s= "T2Body"; break;
114     case RFC822PARSE_FINISH: s= "Finish"; break;
115     case RFC822PARSE_RCVD_SEEN: s= "Rcvd_Seen"; break;
116     case RFC822PARSE_LEVEL_DOWN: s= "Level_Down"; break;
117     case RFC822PARSE_LEVEL_UP: s= "Level_Up"; break;
118     case RFC822PARSE_BOUNDARY: s= "Boundary"; break;
119     case RFC822PARSE_LAST_BOUNDARY: s= "Last_Boundary"; break;
120     case RFC822PARSE_BEGIN_HEADER: s= "Begin_Header"; break;
121     case RFC822PARSE_PREAMBLE: s= "Preamble"; break;
122     case RFC822PARSE_EPILOGUE: s= "Epilogue"; break;
123     default: s= "[unknown event]"; break;
124     }
125   log_debug ("*** RFC822 event %s\n", s);
126 }
127
128
129 /* Do in-place decoding of quoted-printable data of LENGTH in BUFFER.
130    Returns the new length of the buffer and stores true at R_SLBRK if
131    the line ended with a soft line break; false is stored if not.
132    This function asssumes that a complete line is passed in
133    buffer.  */
134 static size_t
135 qp_decode (char *buffer, size_t length, int *r_slbrk)
136 {
137   char *d, *s;
138
139   if (r_slbrk)
140     *r_slbrk = 0;
141
142   /* Fixme:  We should remove trailing white space first.  */
143   for (s=d=buffer; length; length--)
144     {
145       if (*s == '=')
146         {
147           if (length > 2 && hexdigitp (s+1) && hexdigitp (s+2))
148             {
149               s++;
150               *(unsigned char*)d++ = xtoi_2 (s);
151               s += 2;
152               length -= 2;
153             }
154           else if (length > 2 && s[1] == '\r' && s[2] == '\n')
155             {
156               /* Soft line break.  */
157               s += 3;
158               length -= 2;
159               if (r_slbrk && length == 1)
160                 *r_slbrk = 1;
161             }
162           else if (length > 1 && s[1] == '\n')
163             {
164               /* Soft line break with only a Unix line terminator. */
165               s += 2;
166               length -= 1;
167               if (r_slbrk && length == 1)
168                 *r_slbrk = 1;
169             }
170           else if (length == 1)
171             {
172               /* Soft line break at the end of the line. */
173               s += 1;
174               if (r_slbrk)
175                 *r_slbrk = 1;
176             }
177           else
178             *d++ = *s++;
179         }
180       else
181         *d++ = *s++;
182     }
183
184   return d - buffer;
185 }
186
187
188 /* This function is called by parse_mail to communicate events.  This
189  * callback communicates with the caller using a structure passed in
190  * OPAQUE.  Should return 0 on success or set ERRNO and return -1. */
191 static int
192 parse_message_cb (void *opaque, rfc822parse_event_t event, rfc822parse_t msg)
193 {
194   mime_parser_t ctx = opaque;
195   const char *s;
196   int rc = 0;
197
198   /* Make the RFC822 parser context availabale for callbacks.  */
199   ctx->msg = msg;
200
201   if (ctx->debug)
202     show_message_parser_event (event);
203
204   if (event == RFC822PARSE_BEGIN_HEADER || event == RFC822PARSE_T2BODY)
205     {
206       /* We need to check here whether to start collecting signed data
207        * because attachments might come without header lines and thus
208        * we won't see the BEGIN_HEADER event.  */
209       if (ctx->pgpmime == PGPMIME_WAIT_SIGNEDDATA)
210         {
211           if (ctx->debug)
212             log_debug ("begin_hash\n");
213           ctx->hashing_at_level = ctx->nesting_level;
214           ctx->pgpmime = PGPMIME_IN_SIGNEDDATA;
215           ctx->delay_hashing = 0;
216         }
217     }
218
219   if (event == RFC822PARSE_OPEN)
220     {
221       /* Initialize for a new message. */
222       ctx->show.header = 1;
223     }
224   else if (event == RFC822PARSE_T2BODY)
225     {
226       rfc822parse_field_t field;
227
228       ctx->want_part = 0;
229       ctx->decode_part = 0;
230
231       if (ctx->t2body)
232         {
233           rc = ctx->t2body (ctx->cookie, ctx->nesting_level);
234           if (rc)
235             goto t2body_leave;
236         }
237
238       field = rfc822parse_parse_field (msg, "Content-Type", -1);
239       if (field)
240         {
241           const char *s1, *s2;
242
243           s1 = rfc822parse_query_media_type (field, &s2);
244           if (s1)
245             {
246               if (ctx->verbose)
247                 log_debug ("h media: %*s%s %s\n",
248                            ctx->nesting_level*2, "", s1, s2);
249               if (ctx->pgpmime == PGPMIME_WAIT_ENCVERSION)
250                 {
251                   if (!strcmp (s1, "application")
252                       && !strcmp (s2, "pgp-encrypted"))
253                     {
254                       if (ctx->debug)
255                         log_debug ("c begin_encversion\n");
256                       ctx->pgpmime = PGPMIME_IN_ENCVERSION;
257                     }
258                   else
259                     {
260                       log_error ("invalid PGP/MIME structure;"
261                                  " expected '%s', got '%s/%s'\n",
262                                  "application/pgp-encrypted", s1, s2);
263                       ctx->pgpmime = PGPMIME_INVALID;
264                     }
265                 }
266               else if (ctx->pgpmime == PGPMIME_WAIT_ENCDATA)
267                 {
268                   if (!strcmp (s1, "application")
269                       && !strcmp (s2, "octet-stream"))
270                     {
271                       if (ctx->debug)
272                         log_debug ("c begin_encdata\n");
273                       ctx->pgpmime = PGPMIME_IN_ENCDATA;
274                     }
275                   else
276                     {
277                       log_error ("invalid PGP/MIME structure;"
278                                  " expected '%s', got '%s/%s'\n",
279                                  "application/octet-stream", s1, s2);
280                       ctx->pgpmime = PGPMIME_INVALID;
281                     }
282                 }
283               else if (ctx->pgpmime == PGPMIME_WAIT_SIGNATURE)
284                 {
285                   if (!strcmp (s1, "application")
286                       && !strcmp (s2, "pgp-signature"))
287                     {
288                       if (ctx->debug)
289                         log_debug ("c begin_signature\n");
290                       ctx->pgpmime = PGPMIME_IN_SIGNATURE;
291                     }
292                   else
293                     {
294                       log_error ("invalid PGP/MIME structure;"
295                                  " expected '%s', got '%s/%s'\n",
296                                  "application/pgp-signature", s1, s2);
297                       ctx->pgpmime = PGPMIME_INVALID;
298                     }
299                 }
300               else if (!strcmp (s1, "multipart")
301                        && !strcmp (s2, "encrypted"))
302                 {
303                   s = rfc822parse_query_parameter (field, "protocol", 0);
304                   if (s)
305                     {
306                       if (ctx->debug)
307                         log_debug ("h encrypted.protocol: %s\n", s);
308                       if (!strcmp (s, "application/pgp-encrypted"))
309                         {
310                           if (ctx->pgpmime)
311                             log_error ("note: "
312                                        "ignoring nested PGP/MIME signature\n");
313                           else
314                             ctx->pgpmime = PGPMIME_WAIT_ENCVERSION;
315                         }
316                       else if (ctx->verbose)
317                         log_debug ("# this protocol is not supported\n");
318                     }
319                 }
320               else if (!strcmp (s1, "multipart")
321                        && !strcmp (s2, "signed"))
322                 {
323                   s = rfc822parse_query_parameter (field, "protocol", 1);
324                   if (s)
325                     {
326                       if (ctx->debug)
327                         log_debug ("h signed.protocol: %s\n", s);
328                       if (!strcmp (s, "application/pgp-signature"))
329                         {
330                           if (ctx->pgpmime)
331                             log_error ("note: "
332                                        "ignoring nested PGP/MIME signature\n");
333                           else
334                             ctx->pgpmime = PGPMIME_WAIT_SIGNEDDATA;
335                         }
336                       else if (ctx->verbose)
337                         log_debug ("# this protocol is not supported\n");
338                     }
339                 }
340               else if (ctx->new_part)
341                 {
342                   ctx->err = ctx->new_part (ctx->cookie, s1, s2);
343                   if (!ctx->err)
344                     ctx->want_part = 1;
345                   else if (gpg_err_code (ctx->err) == GPG_ERR_FALSE)
346                     ctx->err = 0;
347                   else if (gpg_err_code (ctx->err) == GPG_ERR_TRUE)
348                     {
349                       ctx->want_part = ctx->decode_part = 1;
350                       ctx->err = 0;
351                     }
352                 }
353             }
354           else
355             {
356               if (ctx->debug)
357                 log_debug ("h media: %*s none\n", ctx->nesting_level*2, "");
358               if (ctx->new_part)
359                 {
360                   ctx->err = ctx->new_part (ctx->cookie, "", "");
361                   if (!ctx->err)
362                     ctx->want_part = 1;
363                   else if (gpg_err_code (ctx->err) == GPG_ERR_FALSE)
364                     ctx->err = 0;
365                   else if (gpg_err_code (ctx->err) == GPG_ERR_TRUE)
366                     {
367                       ctx->want_part = ctx->decode_part = 1;
368                       ctx->err = 0;
369                     }
370                 }
371             }
372
373           rfc822parse_release_field (field);
374         }
375       else
376         {
377           if (ctx->verbose)
378             log_debug ("h media: %*stext plain [assumed]\n",
379                        ctx->nesting_level*2, "");
380           if (ctx->new_part)
381             {
382               ctx->err = ctx->new_part (ctx->cookie, "text", "plain");
383               if (!ctx->err)
384                 ctx->want_part = 1;
385               else if (gpg_err_code (ctx->err) == GPG_ERR_FALSE)
386                 ctx->err = 0;
387               else if (gpg_err_code (ctx->err) == GPG_ERR_TRUE)
388                 {
389                   ctx->want_part = ctx->decode_part = 1;
390                   ctx->err = 0;
391                 }
392             }
393         }
394
395       /* Figure out the encoding if needed.  */
396       if (ctx->decode_part)
397         {
398           char *value;
399           size_t valueoff;
400
401           ctx->decode_part = 0; /* Fallback for unknown encoding.  */
402           value = rfc822parse_get_field (msg, "Content-Transfer-Encoding", -1,
403                                          &valueoff);
404           if (value)
405             {
406               if (!stricmp (value+valueoff, "quoted-printable"))
407                 ctx->decode_part = 1;
408               else if (!stricmp (value+valueoff, "base64"))
409                 {
410                   ctx->decode_part = 2;
411                   if (ctx->b64state)
412                     b64dec_finish (ctx->b64state); /* Reuse state.  */
413                   else
414                     {
415                       ctx->b64state = xtrymalloc (sizeof *ctx->b64state);
416                       if (!ctx->b64state)
417                         rc = gpg_error_from_syserror ();
418                     }
419                   if (!rc)
420                     rc = b64dec_start (ctx->b64state, NULL);
421                 }
422               free (value); /* Right, we need a plain free.  */
423             }
424         }
425
426     t2body_leave:
427       ctx->show.header = 0;
428       ctx->show.data = 1;
429       ctx->show.n_skip = 1;
430     }
431   else if (event == RFC822PARSE_PREAMBLE)
432     ctx->show.as_note = 1;
433   else if (event == RFC822PARSE_LEVEL_DOWN)
434     {
435       if (ctx->debug)
436         log_debug ("b down\n");
437       ctx->nesting_level++;
438     }
439   else if (event == RFC822PARSE_LEVEL_UP)
440     {
441       if (ctx->debug)
442         log_debug ("b up\n");
443       if (ctx->nesting_level)
444         ctx->nesting_level--;
445       else
446         log_error ("invalid structure (bad nesting level)\n");
447     }
448   else if (event == RFC822PARSE_BOUNDARY || event == RFC822PARSE_LAST_BOUNDARY)
449     {
450       ctx->show.data = 0;
451       ctx->show.boundary = 1;
452       if (event == RFC822PARSE_BOUNDARY)
453         {
454           ctx->show.header = 1;
455           ctx->show.n_skip = 1;
456           if (ctx->debug)
457             log_debug ("b part\n");
458         }
459       else if (ctx->debug)
460         log_debug ("b last\n");
461
462       if (ctx->pgpmime == PGPMIME_IN_ENCDATA)
463         {
464           if (ctx->debug)
465             log_debug ("c end_encdata\n");
466           ctx->pgpmime = PGPMIME_GOT_ENCDATA;
467           /* FIXME: We should assert (event == LAST_BOUNDARY).  */
468         }
469       else if (ctx->pgpmime == PGPMIME_IN_SIGNEDDATA
470                && ctx->nesting_level == ctx->hashing_at_level)
471         {
472           if (ctx->debug)
473             log_debug ("c end_hash\n");
474           ctx->pgpmime = PGPMIME_WAIT_SIGNATURE;
475           if (ctx->collect_signeddata)
476             ctx->err = ctx->collect_signeddata (ctx->cookie, NULL);
477         }
478       else if (ctx->pgpmime == PGPMIME_IN_SIGNATURE)
479         {
480           if (ctx->debug)
481             log_debug ("c end_signature\n");
482           ctx->pgpmime = PGPMIME_GOT_SIGNATURE;
483           /* FIXME: We should assert (event == LAST_BOUNDARY).  */
484         }
485       else if (ctx->want_part)
486         {
487           if (ctx->part_data)
488             {
489               /* FIXME: We may need to flush things.  */
490               ctx->err = ctx->part_data (ctx->cookie, NULL, 0);
491             }
492           ctx->want_part = 0;
493         }
494     }
495
496   ctx->msg = NULL;
497
498   return rc;
499 }
500
501
502 /* Create a new mime parser object.  COOKIE is a values which will be
503  * used as first argument for all callbacks registered with this
504  * parser object.  */
505 gpg_error_t
506 mime_parser_new (mime_parser_t *r_parser, void *cookie)
507 {
508   mime_parser_t ctx;
509
510   *r_parser = NULL;
511
512   ctx = xtrycalloc (1, sizeof *ctx);
513   if (!ctx)
514     return gpg_error_from_syserror ();
515   ctx->cookie = cookie;
516
517   *r_parser = ctx;
518   return 0;
519 }
520
521
522 /* Release a mime parser object.  */
523 void
524 mime_parser_release (mime_parser_t ctx)
525 {
526   if (!ctx)
527     return;
528
529   if (ctx->b64state)
530     {
531       b64dec_finish (ctx->b64state);
532       xfree (ctx->b64state);
533     }
534   xfree (ctx);
535 }
536
537
538 /* Set verbose and debug mode.  */
539 void
540 mime_parser_set_verbose (mime_parser_t ctx, int level)
541 {
542   if (!level)
543     {
544       ctx->verbose = 0;
545       ctx->debug = 0;
546     }
547   else
548     {
549       ctx->verbose = 1;
550       if (level > 10)
551         ctx->debug = 1;
552     }
553 }
554
555
556 /* Set a callback for the transition from header to body.  LEVEL is
557  * the current nesting level, starting with 0.  This callback can be
558  * used to evaluate headers before any other action is done.  Note
559  * that if a new NEW_PART callback needs to be called it is done after
560  * this T2BODY callback.  */
561 void
562 mime_parser_set_t2body (mime_parser_t ctx,
563                         gpg_error_t (*fnc) (void *cookie, int level))
564 {
565   ctx->t2body = fnc;
566 }
567
568
569 /* Set the callback used to announce a new part.  It will be called
570  * with the media type and media subtype of the part.  If no
571  * Content-type header was given both values are the empty string.
572  * The callback should return 0 on success or an error code.  The
573  * error code GPG_ERR_FALSE indicates that the caller is not
574  * interested in the part and data shall not be returned via a
575  * registered part_data callback.  The error code GPG_ERR_TRUE
576  * indicates that the parts shall be redurned in decoded format
577  * (i.e. base64 or QP encoding is removed).  */
578 void
579 mime_parser_set_new_part (mime_parser_t ctx,
580                           gpg_error_t (*fnc) (void *cookie,
581                                               const char *mediatype,
582                                               const char *mediasubtype))
583 {
584   ctx->new_part = fnc;
585 }
586
587
588 /* Set the callback used to return the data of a part to the caller.
589  * The end of the part is indicated by passing NUL for DATA.  */
590 void
591 mime_parser_set_part_data (mime_parser_t ctx,
592                            gpg_error_t (*fnc) (void *cookie,
593                                                const void *data,
594                                                size_t datalen))
595 {
596   ctx->part_data = fnc;
597 }
598
599
600 /* Set the callback to collect encrypted data.  A NULL passed to the
601  * callback indicates the end of the encrypted data; the callback may
602  * then decrypt the collected data.  */
603 void
604 mime_parser_set_collect_encrypted (mime_parser_t ctx,
605                                    gpg_error_t (*fnc) (void *cookie,
606                                                        const char *data))
607 {
608   ctx->collect_encrypted = fnc;
609 }
610
611
612 /* Set the callback to collect signed data.  A NULL passed to the
613  * callback indicates the end of the signed data.  */
614 void
615 mime_parser_set_collect_signeddata (mime_parser_t ctx,
616                                     gpg_error_t (*fnc) (void *cookie,
617                                                         const char *data))
618 {
619   ctx->collect_signeddata = fnc;
620 }
621
622
623 /* Set the callback to collect the signature.  A NULL passed to the
624  * callback indicates the end of the signature; the callback may the
625  * verify the signature.  */
626 void
627 mime_parser_set_collect_signature (mime_parser_t ctx,
628                                    gpg_error_t (*fnc) (void *cookie,
629                                                        const char *data))
630 {
631   ctx->collect_signature = fnc;
632 }
633
634
635 /* Return the RFC888 parser context.  This is only available inside a
636  * callback.  */
637 rfc822parse_t
638 mime_parser_rfc822parser (mime_parser_t ctx)
639 {
640   return ctx->msg;
641 }
642
643
644 /* Helper for mime_parser_parse.  */
645 static gpg_error_t
646 process_part_data (mime_parser_t ctx, char *line, size_t *length)
647 {
648   gpg_error_t err;
649   size_t nbytes;
650
651   if (!ctx->want_part)
652     return 0;
653   if (!ctx->part_data)
654     return 0;
655
656   if (ctx->decode_part == 1)
657     {
658       *length = qp_decode (line, *length, NULL);
659     }
660   else if (ctx->decode_part == 2)
661     {
662       log_assert (ctx->b64state);
663       err = b64dec_proc (ctx->b64state, line, *length, &nbytes);
664       if (err)
665         return err;
666       *length = nbytes;
667     }
668
669   return ctx->part_data (ctx->cookie, line, *length);
670 }
671
672
673 /* Read and parse a message from FP and call the appropriate
674  * callbacks.  */
675 gpg_error_t
676 mime_parser_parse (mime_parser_t ctx, estream_t fp)
677 {
678   gpg_error_t err;
679   rfc822parse_t msg = NULL;
680   unsigned int lineno = 0;
681   size_t length;
682   char *line;
683
684   line = ctx->line;
685
686   msg = rfc822parse_open (parse_message_cb, ctx);
687   if (!msg)
688     {
689       err = gpg_error_from_syserror ();
690       log_error ("can't open mail parser: %s", gpg_strerror (err));
691       goto leave;
692     }
693
694   /* Fixme: We should not use fgets because it can't cope with
695      embedded nul characters. */
696   while (es_fgets (ctx->line, sizeof (ctx->line), fp))
697     {
698       lineno++;
699       if (lineno == 1 && !strncmp (line, "From ", 5))
700         continue;  /* We better ignore a leading From line. */
701
702       length = strlen (line);
703       if (length && line[length - 1] == '\n')
704         line[--length] = 0;
705       else
706         log_error ("mail parser detected too long or"
707                    " non terminated last line (lnr=%u)\n", lineno);
708       if (length && line[length - 1] == '\r')
709         line[--length] = 0;
710
711       ctx->err = 0;
712       if (rfc822parse_insert (msg, line, length))
713         {
714           err = gpg_error_from_syserror ();
715           log_error ("mail parser failed: %s", gpg_strerror (err));
716           goto leave;
717         }
718       if (ctx->err)
719         {
720           /* Error from a callback detected.  */
721           err = ctx->err;
722           goto leave;
723         }
724
725
726       /* Debug output.  Note that the boundary is shown before n_skip
727        * is evaluated.  */
728       if (ctx->show.boundary)
729         {
730           if (ctx->debug)
731             log_debug ("# Boundary: %s\n", line);
732           ctx->show.boundary = 0;
733         }
734       if (ctx->show.n_skip)
735         ctx->show.n_skip--;
736       else if (ctx->show.data)
737         {
738           if (ctx->show.as_note)
739             {
740               if (ctx->verbose)
741                 log_debug ("# Note: %s\n", line);
742               ctx->show.as_note = 0;
743             }
744           else if (ctx->debug)
745             log_debug ("# Data: %s\n", line);
746         }
747       else if (ctx->show.header && ctx->verbose)
748         log_debug ("# Header: %s\n", line);
749
750       if (ctx->pgpmime == PGPMIME_IN_ENCVERSION)
751         {
752           trim_trailing_spaces (line);
753           if (!*line)
754             ;  /* Skip empty lines.  */
755           else if (!strcmp (line, "Version: 1"))
756             ctx->pgpmime = PGPMIME_WAIT_ENCDATA;
757           else
758             {
759               log_error ("invalid PGP/MIME structure;"
760                          " garbage in pgp-encrypted part ('%s')\n", line);
761               ctx->pgpmime = PGPMIME_INVALID;
762             }
763         }
764       else if (ctx->pgpmime == PGPMIME_IN_ENCDATA)
765         {
766           if (ctx->collect_encrypted)
767             {
768               err = ctx->collect_encrypted (ctx->cookie, line);
769               if (!err)
770                 err = ctx->collect_encrypted (ctx->cookie, "\r\n");
771               if (err)
772                 goto leave;
773             }
774         }
775       else if (ctx->pgpmime == PGPMIME_GOT_ENCDATA)
776         {
777           ctx->pgpmime = PGPMIME_NONE;
778           if (ctx->collect_encrypted)
779             ctx->collect_encrypted (ctx->cookie, NULL);
780         }
781       else if (ctx->pgpmime == PGPMIME_IN_SIGNEDDATA)
782         {
783           /* If we are processing signed data, store the signed data.
784            * We need to delay the hashing of the CR/LF because the
785            * last line ending belongs to the next boundary.  This is
786            * the reason why we can't use the PGPMIME state as a
787            * condition.  */
788           if (ctx->debug)
789             log_debug ("# hashing %s'%s'\n",
790                        ctx->delay_hashing? "CR,LF+":"", line);
791           if (ctx->collect_signeddata)
792             {
793               if (ctx->delay_hashing)
794                 ctx->collect_signeddata (ctx->cookie, "\r\n");
795               ctx->collect_signeddata (ctx->cookie, line);
796             }
797           ctx->delay_hashing = 1;
798
799           err = process_part_data (ctx, line, &length);
800           if (err)
801             goto leave;
802         }
803       else if (ctx->pgpmime == PGPMIME_IN_SIGNATURE)
804         {
805           if (ctx->collect_signeddata)
806             {
807               ctx->collect_signature (ctx->cookie, line);
808               ctx->collect_signature (ctx->cookie, "\r\n");
809             }
810         }
811       else if (ctx->pgpmime == PGPMIME_GOT_SIGNATURE)
812         {
813           ctx->pgpmime = PGPMIME_NONE;
814           if (ctx->collect_signeddata)
815             ctx->collect_signature (ctx->cookie, NULL);
816         }
817       else
818         {
819           err = process_part_data (ctx, line, &length);
820           if (err)
821             goto leave;
822         }
823     }
824
825   rfc822parse_close (msg);
826   msg = NULL;
827   err = 0;
828
829  leave:
830   rfc822parse_cancel (msg);
831   return err;
832 }