gpg: New option --mimemode.
authorWerner Koch <wk@gnupg.org>
Wed, 13 Jul 2016 11:31:12 +0000 (13:31 +0200)
committerWerner Koch <wk@gnupg.org>
Wed, 13 Jul 2016 11:31:12 +0000 (13:31 +0200)
* g10/gpg.c (oMimemode): New.
(opts): Add --mimemode.
(main): Use --mimemode only in rfc4880bis compliance mode.
* g10/options.h (struct opt): Add field "mimemode".
* g10/build-packet.c (do_plaintext): Allow for mode 'm'.
* g10/encrypt.c (encrypt_simple, encrypt_crypt): Use 'm' if requested.
* g10/plaintext.c (handle_plaintext): Handle 'm' mode.
* g10/sign.c (write_plaintext_packet): Handle 'm' mode.
(sign_file, sign_symencrypt_file): Use 'm' if requested.
--

Thsi patch prepares for a proposed change in RFC4880bis to support a
MIME flag.  A literal data packet with the mime flag set is handled
like a 't' or 'u' but CR are not removed.  The PLAINTEXT status line
will also indicate a MIME content.

If --mimemode is used without --rfc4880bis 't' will be used.

Signed-off-by: Werner Koch <wk@gnupg.org>
g10/build-packet.c
g10/encrypt.c
g10/gpg.c
g10/options.h
g10/plaintext.c
g10/sign.c

index 21cd004..86d42ef 100644 (file)
@@ -635,6 +635,7 @@ do_plaintext( IOBUF out, int ctb, PKT_plaintext *pt )
 
     write_header(out, ctb, calc_plaintext( pt ) );
     log_assert (pt->mode == 'b' || pt->mode == 't' || pt->mode == 'u'
+                || pt->mode == 'm'
                 || pt->mode == 'l' || pt->mode == '1');
     iobuf_put(out, pt->mode );
     iobuf_put(out, pt->namelen );
index 57d24be..54a17c3 100644 (file)
@@ -335,7 +335,7 @@ encrypt_simple (const char *filename, int mode, int use_seskey)
     {
       /* Note that PT has been initialized above in !no_literal mode.  */
       pt->timestamp = make_timestamp();
-      pt->mode = opt.textmode? 't' : 'b';
+      pt->mode = opt.mimemode? 'm' : opt.textmode? 't' : 'b';
       pt->len = filesize;
       pt->new_ctb = !pt->len;
       pt->buf = inp;
@@ -674,7 +674,7 @@ encrypt_crypt (ctrl_t ctrl, int filefd, const char *filename,
   if (!opt.no_literal)
     {
       pt->timestamp = make_timestamp();
-      pt->mode = opt.textmode ? 't' : 'b';
+      pt->mode = opt.mimemode? 'm' : opt.textmode ? 't' : 'b';
       pt->len = filesize;
       pt->new_ctb = !pt->len;
       pt->buf = inp;
index 34009bb..4232a84 100644 (file)
--- a/g10/gpg.c
+++ b/g10/gpg.c
@@ -169,6 +169,7 @@ enum cmd_and_opt_values
     aServer,
     aTOFUPolicy,
 
+    oMimemode,
     oTextmode,
     oNoTextmode,
     oExpert,
@@ -532,7 +533,8 @@ static ARGPARSE_OPTS opts[] = {
   ARGPARSE_s_i (oBZ2CompressLevel, "bzip2-compress-level", "@"),
   ARGPARSE_s_n (oBZ2DecompressLowmem, "bzip2-decompress-lowmem", "@"),
 
-  ARGPARSE_s_n (oTextmodeShort, NULL, "@"),
+  ARGPARSE_s_n (oMimemode, "mimemode", "@"),
+  ARGPARSE_s_n (oTextmode,      "textmode", N_("use canonical text mode")),
   ARGPARSE_s_n (oTextmode,      "textmode", N_("use canonical text mode")),
   ARGPARSE_s_n (oNoTextmode, "no-textmode", "@"),
 
@@ -2887,9 +2889,11 @@ main (int argc, char **argv)
                              pargs.r.ret_str, utf8_strings);
            break;
 
+          case oMimemode: opt.mimemode = opt.textmode = 1; break;
          case oTextmodeShort: opt.textmode = 2; break;
          case oTextmode: opt.textmode=1;  break;
-         case oNoTextmode: opt.textmode=0;  break;
+         case oNoTextmode: opt.textmode=opt.mimemode=0;  break;
+
          case oExpert: opt.expert = 1; break;
          case oNoExpert: opt.expert = 0; break;
          case oDefSigExpire:
@@ -3447,6 +3451,10 @@ main (int argc, char **argv)
 
     if (opt.flags.rfc4880bis)
        log_info ("WARNING: using experimental features from RFC4880bis!\n");
+    else
+      {
+        opt.mimemode = 0; /* This will use text mode instead.  */
+      }
 
     if (eyes_only) {
       if (opt.set_filename)
index 2b3cabd..3c4f0fe 100644 (file)
@@ -57,6 +57,7 @@ struct
   int dry_run;
   int autostart;
   int list_only;
+  int mimemode;
   int textmode;
   int expert;
   const char *def_sig_expire;
index e118f6b..c9fb67c 100644 (file)
@@ -217,11 +217,16 @@ handle_plaintext (PKT_plaintext * pt, md_filter_context_t * mfx,
   static off_t count = 0;
   int err = 0;
   int c;
-  int convert = (pt->mode == 't' || pt->mode == 'u');
+  int convert;
 #ifdef __riscos__
   int filetype = 0xfff;
 #endif
 
+  if (pt->mode == 't' || pt->mode == 'u' || pt->mode == 'm')
+    convert = pt->mode;
+  else
+    convert = 0;
+
   /* Let people know what the plaintext info is. This allows the
      receiving program to try and do something different based on the
      format code (say, recode UTF-8 to local). */
@@ -279,8 +284,10 @@ handle_plaintext (PKT_plaintext * pt, md_filter_context_t * mfx,
              if (mfx->md)
                gcry_md_putc (mfx->md, c);
 #ifndef HAVE_DOSISH_SYSTEM
-             if (c == '\r')    /* convert to native line ending */
-               continue;       /* fixme: this hack might be too simple */
+              /* Convert to native line ending. */
+              /* fixme: this hack might be too simple */
+             if (c == '\r' && convert != 'm')
+               continue;
 #endif
              if (fp)
                {
@@ -354,7 +361,7 @@ handle_plaintext (PKT_plaintext * pt, md_filter_context_t * mfx,
              if (mfx->md)
                gcry_md_putc (mfx->md, c);
 #ifndef HAVE_DOSISH_SYSTEM
-             if (convert && c == '\r')
+             if (c == '\r' && convert != 'm')
                continue;       /* fixme: this hack might be too simple */
 #endif
              if (fp)
index 0f16e96..6a7a87e 100644 (file)
@@ -605,7 +605,7 @@ write_plaintext_packet (IOBUF out, IOBUF inp, const char *fname, int ptmode)
          * data, it is not possible to know the used length
          * without a double read of the file - to avoid that
          * we simple use partial length packets. */
-        if ( ptmode == 't' )
+        if ( ptmode == 't' || ptmode == 'u' || ptmode == 'm')
          filesize = 0;
       }
     else
@@ -1033,7 +1033,8 @@ sign_file (ctrl_t ctrl, strlist_t filenames, int detached, strlist_t locusr,
     }
     else {
         rc = write_plaintext_packet (out, inp, fname,
-                                     opt.textmode && !outfile ? 't':'b');
+                                     opt.textmode && !outfile ?
+                                     (opt.mimemode? 'm':'t'):'b');
     }
 
     /* catch errors from above */
@@ -1337,7 +1338,8 @@ sign_symencrypt_file (ctrl_t ctrl, const char *fname, strlist_t locusr)
 
     /* Pipe data through all filters; i.e. write the signed stuff */
     /*(current filters: zip - encrypt - armor)*/
-    rc = write_plaintext_packet (out, inp, fname, opt.textmode ? 't':'b');
+    rc = write_plaintext_packet (out, inp, fname,
+                                 opt.textmode ? (opt.mimemode?'m':'t'):'b');
     if (rc)
        goto leave;