* keygen.c (proc_parameter_file): Default key and subkey usage flags to
[gnupg.git] / g10 / encode.c
index 29b3997..5bbe7cf 100644 (file)
@@ -1,6 +1,6 @@
 /* encode.c - encode data
- * Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003,
- *               2004 Free Software Foundation, Inc.
+ * Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003, 2004,
+ *               2005 Free Software Foundation, Inc.
  *
  * This file is part of GnuPG.
  *
@@ -16,7 +16,8 @@
  *
  * You should have received a copy of the GNU General Public License
  * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
+ * USA.
  */
 
 #include <config.h>
@@ -71,7 +72,7 @@ encode_seskey( DEK *dek, DEK **seskey, byte *enckey )
     assert ( dek->keylen <= 32 );
     if(!*seskey)
       {
-       *seskey=m_alloc_clear(sizeof(DEK));
+       *seskey=xmalloc_clear(sizeof(DEK));
        (*seskey)->keylen=dek->keylen;
        (*seskey)->algo=dek->algo;
        make_session_key(*seskey);
@@ -170,9 +171,18 @@ encode_simple( const char *filename, int mode, int use_seskey )
     init_packet(&pkt);
     
     /* prepare iobufs */
-    if( !(inp = iobuf_open(filename)) ) {
-       log_error(_("%s: can't open: %s\n"), filename? filename: "[stdin]",
-                                       strerror(errno) );
+    inp = iobuf_open(filename);
+    if (inp)
+      iobuf_ioctl (inp,3,1,NULL); /* disable fd caching */
+    if (inp && is_secured_file (iobuf_get_fd (inp)))
+      {
+        iobuf_close (inp);
+        inp = NULL;
+        errno = EPERM;
+      }
+    if( !inp ) {
+       log_error(_("can't open `%s': %s\n"), filename? filename: "[stdin]",
+                  strerror(errno) );
        return G10ERR_OPEN_FILE;
     }
 
@@ -189,7 +199,7 @@ encode_simple( const char *filename, int mode, int use_seskey )
     
     cfx.dek = NULL;
     if( mode ) {
-       s2k = m_alloc_clear( sizeof *s2k );
+       s2k = xmalloc_clear( sizeof *s2k );
        s2k->mode = RFC1991? 0:opt.s2k_mode;
        s2k->hash_algo=S2K_DIGEST_ALGO;
        cfx.dek = passphrase_to_dek( NULL, 0,
@@ -197,8 +207,8 @@ encode_simple( const char *filename, int mode, int use_seskey )
                                      NULL, NULL);
        if( !cfx.dek || !cfx.dek->keylen ) {
            rc = G10ERR_PASSPHRASE;
-           m_free(cfx.dek);
-           m_free(s2k);
+           xfree(cfx.dek);
+           xfree(s2k);
            iobuf_close(inp);
            log_error(_("error creating passphrase: %s\n"), g10_errstr(rc) );
            return rc;
@@ -214,7 +224,7 @@ encode_simple( const char *filename, int mode, int use_seskey )
            DEK *dek = NULL;
             seskeylen = cipher_get_keylen( default_cipher_algo() ) / 8;
             encode_seskey( cfx.dek, &dek, enckey );
-            m_free( cfx.dek ); cfx.dek = dek;
+            xfree( cfx.dek ); cfx.dek = dek;
          }
 
        if(opt.verbose)
@@ -234,23 +244,16 @@ encode_simple( const char *filename, int mode, int use_seskey )
 
     if( rc || (rc = open_outfile( filename, opt.armor? 1:0, &out )) ) {
        iobuf_cancel(inp);
-       m_free(cfx.dek);
-       m_free(s2k);
+       xfree(cfx.dek);
+       xfree(s2k);
        return rc;
     }
 
     if( opt.armor )
        iobuf_push_filter( out, armor_filter, &afx );
-#ifdef ENABLE_COMMENT_PACKETS
-    else {
-       write_comment( out, "#created by GNUPG v" VERSION " ("
-                                           PRINTABLE_OS_NAME ")");
-       if( opt.comment_string )
-           write_comment( out, opt.comment_string );
-    }
-#endif
+
     if( s2k && !RFC1991 ) {
-       PKT_symkey_enc *enc = m_alloc_clear( sizeof *enc + seskeylen + 1 );
+       PKT_symkey_enc *enc = xmalloc_clear( sizeof *enc + seskeylen + 1 );
        enc->version = 4;
        enc->cipher_algo = cfx.dek->algo;
        enc->s2k = *s2k;
@@ -262,7 +265,7 @@ encode_simple( const char *filename, int mode, int use_seskey )
        pkt.pkt.symkey_enc = enc;
        if( (rc = build_packet( out, &pkt )) )
            log_error("build symkey packet failed: %s\n", g10_errstr(rc) );
-       m_free(enc);
+       xfree(enc);
     }
 
     if (!opt.no_literal) {
@@ -271,13 +274,13 @@ encode_simple( const char *filename, int mode, int use_seskey )
            char *s = make_basename( opt.set_filename ? opt.set_filename
                                                      : filename,
                                     iobuf_get_real_fname( inp ) );
-           pt = m_alloc( sizeof *pt + strlen(s) - 1 );
+           pt = xmalloc( sizeof *pt + strlen(s) - 1 );
            pt->namelen = strlen(s);
            memcpy(pt->name, s, pt->namelen );
-           m_free(s);
+           xfree(s);
        }
        else { /* no filename */
-           pt = m_alloc( sizeof *pt - 1 );
+           pt = xmalloc( sizeof *pt - 1 );
            pt->namelen = 0;
        }
     }
@@ -293,12 +296,14 @@ encode_simple( const char *filename, int mode, int use_seskey )
        either partial length or fixed length with the new style
        messages. */
 
-    if (filename && *filename && !(*filename == '-' && !filename[1])
-        && !opt.textmode ) {
+    if ( !iobuf_is_pipe_filename (filename) && *filename && !opt.textmode )
+      {
         off_t tmpsize;
+        int overflow;
 
-       if ( !(tmpsize = iobuf_get_filelength(inp)) )
-          log_info(_("%s: WARNING: empty file\n"), filename );
+       if ( !(tmpsize = iobuf_get_filelength(inp, &overflow))
+             && !overflow )
+          log_info(_("WARNING: `%s' is an empty file\n"), filename );
         /* We can't encode the length of very large files because
            OpenPGP uses only 32 bit for file sizes.  So if the the
            size of a file is larger than 2^32 minus some bytes for
@@ -307,9 +312,9 @@ encode_simple( const char *filename, int mode, int use_seskey )
           filesize = tmpsize;
         else
           filesize = 0;
-    }
+      }
     else
-       filesize = opt.set_filesize ? opt.set_filesize : 0; /* stdin */
+      filesize = opt.set_filesize ? opt.set_filesize : 0; /* stdin */
 
     if (!opt.no_literal) {
        pt->timestamp = make_timestamp();
@@ -370,15 +375,15 @@ encode_simple( const char *filename, int mode, int use_seskey )
     if (pt)
        pt->buf = NULL;
     free_packet(&pkt);
-    m_free(cfx.dek);
-    m_free(s2k);
+    xfree(cfx.dek);
+    xfree(s2k);
     return rc;
 }
 
 int
 setup_symkey(STRING2KEY **symkey_s2k,DEK **symkey_dek)
 {
-  *symkey_s2k=m_alloc_clear(sizeof(STRING2KEY));
+  *symkey_s2k=xmalloc_clear(sizeof(STRING2KEY));
   (*symkey_s2k)->mode = opt.s2k_mode;
   (*symkey_s2k)->hash_algo = S2K_DIGEST_ALGO;
 
@@ -386,8 +391,8 @@ setup_symkey(STRING2KEY **symkey_s2k,DEK **symkey_dek)
                                *symkey_s2k,2,NULL,NULL);
   if(!*symkey_dek || !(*symkey_dek)->keylen)
     {
-      m_free(*symkey_dek);
-      m_free(*symkey_s2k);
+      xfree(*symkey_dek);
+      xfree(*symkey_s2k);
       return G10ERR_PASSPHRASE;
     }
 
@@ -403,7 +408,7 @@ write_symkey_enc(STRING2KEY *symkey_s2k,DEK *symkey_dek,DEK *dek,IOBUF out)
   byte enckey[33];
   PACKET pkt;
 
-  enc=m_alloc_clear(sizeof(PKT_symkey_enc)+seskeylen+1);
+  enc=xmalloc_clear(sizeof(PKT_symkey_enc)+seskeylen+1);
   encode_seskey(symkey_dek,&dek,enckey);
 
   enc->version = 4;
@@ -418,7 +423,7 @@ write_symkey_enc(STRING2KEY *symkey_s2k,DEK *symkey_dek,DEK *dek,IOBUF out)
   if((rc=build_packet(out,&pkt)))
     log_error("build symkey_enc packet failed: %s\n",g10_errstr(rc));
 
-  m_free(enc);
+  xfree(enc);
   return rc;
 }
 
@@ -470,8 +475,17 @@ encode_crypt( const char *filename, STRLIST remusr, int use_symkey )
     }
 
     /* prepare iobufs */
-    if( !(inp = iobuf_open(filename)) ) {
-       log_error(_("can't open %s: %s\n"), filename? filename: "[stdin]",
+    inp = iobuf_open(filename);
+    if (inp)
+      iobuf_ioctl (inp,3,1,NULL); /* disable fd caching */
+    if (inp && is_secured_file (iobuf_get_fd (inp)))
+      {
+        iobuf_close (inp);
+        inp = NULL;
+        errno = EPERM;
+      }
+    if( !inp ) {
+       log_error(_("can't open `%s': %s\n"), filename? filename: "[stdin]",
                                        strerror(errno) );
        rc = G10ERR_OPEN_FILE;
        goto leave;
@@ -487,19 +501,11 @@ encode_crypt( const char *filename, STRLIST remusr, int use_symkey )
     if( (rc = open_outfile( filename, opt.armor? 1:0, &out )) )
        goto leave;
 
-
     if( opt.armor )
        iobuf_push_filter( out, armor_filter, &afx );
-#ifdef ENABLE_COMMENT_PACKETS
-    else {
-       write_comment( out, "#created by GNUPG v" VERSION " ("
-                                           PRINTABLE_OS_NAME ")");
-       if( opt.comment_string )
-           write_comment( out, opt.comment_string );
-    }
-#endif
+
     /* create a session key */
-    cfx.dek = m_alloc_secure_clear (sizeof *cfx.dek);
+    cfx.dek = xmalloc_secure_clear (sizeof *cfx.dek);
     if( !opt.def_cipher_algo ) { /* try to get it from the prefs */
        cfx.dek->algo = select_algo_from_prefs(pk_list,PREFTYPE_SYM,-1,NULL);
        /* The only way select_algo_from_prefs can fail here is when
@@ -571,34 +577,36 @@ encode_crypt( const char *filename, STRLIST remusr, int use_symkey )
            char *s = make_basename( opt.set_filename ? opt.set_filename
                                                      : filename,
                                     iobuf_get_real_fname( inp ) );
-           pt = m_alloc( sizeof *pt + strlen(s) - 1 );
+           pt = xmalloc( sizeof *pt + strlen(s) - 1 );
            pt->namelen = strlen(s);
            memcpy(pt->name, s, pt->namelen );
-           m_free(s);
+           xfree(s);
        }
        else { /* no filename */
-           pt = m_alloc( sizeof *pt - 1 );
+           pt = xmalloc( sizeof *pt - 1 );
            pt->namelen = 0;
        }
     }
 
-    if (filename && *filename && !(*filename == '-' && !filename[1])
-        && !opt.textmode ) {
+    if (!iobuf_is_pipe_filename (filename) && *filename && !opt.textmode )
+      {
         off_t tmpsize;
+        int overflow;
 
-       if ( !(tmpsize = iobuf_get_filelength(inp)) )
-          log_info(_("%s: WARNING: empty file\n"), filename );
+       if ( !(tmpsize = iobuf_get_filelength(inp, &overflow))
+             && !overflow )
+          log_info(_("WARNING: `%s' is an empty file\n"), filename );
         /* We can't encode the length of very large files because
            OpenPGP uses only 32 bit for file sizes.  So if the the
            size of a file is larger than 2^32 minus some bytes for
            packet headers, we switch to partial length encoding. */
-        if ( tmpsize < (IOBUF_FILELENGTH_LIMIT - 65536) )
+        if (tmpsize < (IOBUF_FILELENGTH_LIMIT - 65536) )
           filesize = tmpsize;
         else
           filesize = 0;
-    }
+      }
     else
-       filesize = opt.set_filesize ? opt.set_filesize : 0; /* stdin */
+      filesize = opt.set_filesize ? opt.set_filesize : 0; /* stdin */
 
     if (!opt.no_literal) {
        pt->timestamp = make_timestamp();
@@ -676,9 +684,9 @@ encode_crypt( const char *filename, STRLIST remusr, int use_symkey )
     if( pt )
        pt->buf = NULL;
     free_packet(&pkt);
-    m_free(cfx.dek);
-    m_free(symkey_dek);
-    m_free(symkey_s2k);
+    xfree(cfx.dek);
+    xfree(symkey_dek);
+    xfree(symkey_s2k);
     release_pk_list( pk_list );
     return rc;
 }
@@ -702,7 +710,7 @@ encrypt_filter( void *opaque, int control,
     }
     else if( control == IOBUFCTRL_FLUSH ) { /* encrypt */
        if( !efx->header_okay ) {
-           efx->cfx.dek = m_alloc_secure_clear( sizeof *efx->cfx.dek );
+           efx->cfx.dek = xmalloc_secure_clear( sizeof *efx->cfx.dek );
 
            if( !opt.def_cipher_algo  ) { /* try to get it from the prefs */
                efx->cfx.dek->algo =
@@ -754,8 +762,8 @@ encrypt_filter( void *opaque, int control,
     }
     else if( control == IOBUFCTRL_FREE )
       {
-       m_free(efx->symkey_dek);
-       m_free(efx->symkey_s2k);
+       xfree(efx->symkey_dek);
+       xfree(efx->symkey_s2k);
       }
     else if( control == IOBUFCTRL_DESC ) {
        *(char**)buf = "encrypt_filter";
@@ -781,7 +789,7 @@ write_pubkey_enc_from_list( PK_LIST pk_list, DEK *dek, IOBUF out )
        pk = pk_list->pk;
 
        print_pubkey_algo_note( pk->pubkey_algo );
-       enc = m_alloc_clear( sizeof *enc );
+       enc = xmalloc_clear( sizeof *enc );
        enc->pubkey_algo = pk->pubkey_algo;
        keyid_from_pk( pk, enc->keyid );
        enc->throw_keyid = (opt.throw_keyid || (pk_list->flags&1));
@@ -818,7 +826,7 @@ write_pubkey_enc_from_list( PK_LIST pk_list, DEK *dek, IOBUF out )
                log_info(_("%s/%s encrypted for: \"%s\"\n"),
                    pubkey_algo_to_string(enc->pubkey_algo),
                    cipher_algo_to_string(dek->algo), ustr );
-               m_free(ustr);
+               xfree(ustr);
            }
            /* and write it */
            init_packet(&pkt);
@@ -861,7 +869,7 @@ encode_crypt_files(int nfiles, char **files, STRLIST remusr)
           line[strlen(line)-1] = '\0';
           print_file_status(STATUS_FILE_START, line, 2);
           if ( (rc = encode_crypt(line, remusr, 0)) )
-            log_error("%s: encryption failed: %s\n",
+            log_error("encryption of `%s' failed: %s\n",
                       print_fname_stdin(line), g10_errstr(rc) );
           write_status( STATUS_FILE_DONE );
         }
@@ -872,7 +880,7 @@ encode_crypt_files(int nfiles, char **files, STRLIST remusr)
         {
           print_file_status(STATUS_FILE_START, *files, 2);
           if ( (rc = encode_crypt(*files, remusr, 0)) )
-            log_error("%s: encryption failed: %s\n",
+            log_error("encryption of `%s' failed: %s\n",
                       print_fname_stdin(*files), g10_errstr(rc) );
           write_status( STATUS_FILE_DONE );
           files++;