[g13] Add RECIPEINT and CREATE command.
authorWerner Koch <wk@gnupg.org>
Mon, 19 Oct 2009 09:18:46 +0000 (09:18 +0000)
committerWerner Koch <wk@gnupg.org>
Mon, 19 Oct 2009 09:18:46 +0000 (09:18 +0000)
[sm] Chnage --include-certs default

16 files changed:
doc/gpgsm.texi
g10/ChangeLog
g10/mainproc.c
g10/options.h
g10/server.c
g13/call-gpg.c
g13/call-gpg.h
g13/create.c
g13/create.h
g13/g13.c
g13/server.c
jnlib/ChangeLog
jnlib/strlist.c
jnlib/strlist.h
sm/ChangeLog
sm/gpgsm.c

index a2b3db0..5835c72 100644 (file)
@@ -560,7 +560,7 @@ Using @var{n} of -2 includes all certificate except for the root cert,
 -1 includes all certs, 0 does not include any certs, 1 includes only
 the signers cert (this is the default) and all other positive
 values include up to @var{n} certificates starting with the signer cert.
-
+The default is -2.
 
 @item --cipher-algo @var{oid}
 @opindex cipher-algo
index 11e13fb..dfe54e7 100644 (file)
@@ -1,3 +1,9 @@
+2009-10-19  Werner Koch  <wk@g10code.com>
+
+       * options.h (glo_ctrl): Add field LASTERR.
+       * mainproc.c (proc_encrypted): Set LASTERR.
+       * server.c (cmd_decrypt): Check LASTERR.
+
 2009-10-02  Werner Koch  <wk@g10code.com>
 
        * server.c (cmd_encrypt, cmd_decrypt): Implement.
index 4a8df6f..c3d082c 100644 (file)
@@ -581,6 +581,7 @@ proc_encrypted( CTX c, PACKET *pkt )
          }
     }
     else if( result == G10ERR_BAD_SIGN ) {
+        glo_ctrl.lasterr = result;
        log_error(_("WARNING: encrypted message has been manipulated!\n"));
        write_status( STATUS_BADMDC );
        write_status( STATUS_DECRYPTION_FAILED );
@@ -593,6 +594,7 @@ proc_encrypted( CTX c, PACKET *pkt )
                      c->dek->s2k_cacheid);
            passphrase_clear_cache (NULL, c->dek->s2k_cacheid, 0);
          }
+        glo_ctrl.lasterr = result;
        write_status( STATUS_DECRYPTION_FAILED );
        log_error(_("decryption failed: %s\n"), g10_errstr(result));
        /* Hmmm: does this work when we have encrypted using multiple
index 3a2a68e..b6e7e55 100644 (file)
@@ -257,6 +257,11 @@ EXTERN_UNLESS_MAIN_MODULE
 struct {
   int in_auto_key_retrieve; /* True if we are doing an
                                auto_key_retrieve. */
+  /* Hack to store the last error.  We currently need it because the
+     proc_packet machinery is not able to reliabale return error
+     codes.  Thus for the --server purposes we store some of the error
+     codes here.  FIXME! */
+  gpg_error_t lasterr;
 } glo_ctrl;
 
 #define DBG_PACKET_VALUE  1    /* debug packet reading/writing */
index 478c0ec..657091b 100644 (file)
@@ -362,7 +362,10 @@ cmd_decrypt (assuan_context_t ctx, char *line)
   if (out_fd == -1)
     return set_error (GPG_ERR_ASS_NO_OUTPUT, NULL);
 
+  glo_ctrl.lasterr = 0;
   err = decrypt_message_fd (inp_fd, out_fd);
+  if (!err)
+    err = glo_ctrl.lasterr;
 
   /* Close and reset the fds. */
   close_message_fd (ctrl);
index 6e5c55f..c6b0abe 100644 (file)
@@ -43,7 +43,7 @@ start_gpg (ctrl_t ctrl, int input_fd, int output_fd, assuan_context_t *r_ctx)
   gpg_error_t err;
   assuan_context_t ctx = NULL;
   const char *pgmname;
-  const char *argv[7];
+  const char *argv[10];
   int no_close_list[5];
   int i;
   char line[ASSUAN_LINELENGTH];
@@ -86,6 +86,8 @@ start_gpg (ctrl_t ctrl, int input_fd, int output_fd, assuan_context_t *r_ctx)
     argv[i++] = "--debug=1024";
   argv[i++] = "-z";
   argv[i++] = "0";
+  argv[i++] = "--trust-model";
+  argv[i++] = "always";
   argv[i++] = NULL;
   
   i = 0;
@@ -326,7 +328,7 @@ start_reader (int fd, membuf_t *mb, pth_t *r_tid, gpg_error_t *err_addr)
  */
 gpg_error_t
 gpg_encrypt_blob (ctrl_t ctrl, const void *plain, size_t plainlen,
-                  void **r_ciph, size_t *r_ciphlen)
+                  strlist_t keys, void **r_ciph, size_t *r_ciphlen)
 {
   gpg_error_t err;
   assuan_context_t ctx;
@@ -336,6 +338,8 @@ gpg_encrypt_blob (ctrl_t ctrl, const void *plain, size_t plainlen,
   pth_t reader_tid = NULL;
   gpg_error_t writer_err, reader_err;
   membuf_t reader_mb;
+  char line[ASSUAN_LINELENGTH];
+  strlist_t sl;
 
   *r_ciph = NULL;
   *r_ciphlen = 0;
@@ -376,13 +380,16 @@ gpg_encrypt_blob (ctrl_t ctrl, const void *plain, size_t plainlen,
   outbound_fds[0] = -1;  /* The thread owns the FD now.  */
 
   /* Run the encryption.  */
-  err = assuan_transact (ctx, "RECIPIENT alpha@example.net",
-                         NULL, NULL, NULL, NULL, NULL, NULL);
-  if (err)
+  for (sl = keys; sl; sl = sl->next)
     {
-      log_error ("the engine's RECIPIENT command failed: %s <%s>\n",
+      snprintf (line, sizeof line, "RECIPIENT -- %s", sl->d);
+      err = assuan_transact (ctx, line, NULL, NULL, NULL, NULL, NULL, NULL);
+      if (err)
+        {
+          log_error ("the engine's RECIPIENT command failed: %s <%s>\n",
                  gpg_strerror (err), gpg_strsource (err));
-      goto leave;
+          goto leave;
+        }
     }
 
   err = assuan_transact (ctx, "ENCRYPT", NULL, NULL, NULL, NULL, NULL, NULL);
index ffc5f29..339544d 100644 (file)
@@ -22,6 +22,7 @@
 
 gpg_error_t gpg_encrypt_blob (ctrl_t ctrl,
                               const void *plain, size_t plainlen,
+                              strlist_t keys,
                               void **r_ciph, size_t *r_ciphlen);
 gpg_error_t gpg_decrypt_blob (ctrl_t ctrl, const void *ciph, size_t ciphlen,
                               void **r_plain, size_t *r_plainlen);
index 9de9edc..bde6757 100644 (file)
@@ -106,12 +106,13 @@ create_new_keyblob (ctrl_t ctrl, int is_detached,
    concatenation of both with the CMS packet being the last.  */
 static gpg_error_t
 encrypt_keyblob (ctrl_t ctrl, void *keyblob, size_t keybloblen,
+                 strlist_t keys,
                  void **r_encblob, size_t *r_encbloblen)
 {
   gpg_error_t err;
 
   /* FIXME:  For now we only implement OpenPGP.  */
-  err = gpg_encrypt_blob (ctrl, keyblob, keybloblen,
+  err = gpg_encrypt_blob (ctrl, keyblob, keybloblen, keys,
                           r_encblob, r_encbloblen);
 
   return err;
@@ -217,10 +218,11 @@ write_keyblob (const char *filename,
 
 
 /* Create a new container under the name FILENAME and intialize it
-   using the current settings.  If the file already exists an error is
-   returned. */
+   using the current settings.  KEYS is a list of public keys to which
+   the container will be encrypted.  If the file already exists an
+   error is returned.  */
 gpg_error_t
-g13_create_container (ctrl_t ctrl, const char *filename)
+g13_create_container (ctrl_t ctrl, const char *filename, strlist_t keys)
 {
   gpg_error_t err;
   dotlock_t lock;
@@ -233,6 +235,9 @@ g13_create_container (ctrl_t ctrl, const char *filename)
   tupledesc_t tuples = NULL;
   unsigned int dummy_rid;
 
+  if (!keys)
+    return gpg_error (GPG_ERR_NO_PUBKEY);
+
   /* A quick check to see that no container with that name already
      exists.  */
   if (!access (filename, F_OK))
@@ -284,7 +289,7 @@ g13_create_container (ctrl_t ctrl, const char *filename)
     goto leave;
 
   /* Encrypt that keyblob.  */
-  err = encrypt_keyblob (ctrl, keyblob, keybloblen,
+  err = encrypt_keyblob (ctrl, keyblob, keybloblen, keys,
                          &enckeyblob, &enckeybloblen);
   if (err)
     goto leave;
index d533c08..cc4ddfd 100644 (file)
@@ -20,7 +20,8 @@
 #ifndef G13_CREATE_H
 #define G13_CREATE_H
 
-gpg_error_t g13_create_container (ctrl_t ctrl, const char *filename);
+gpg_error_t g13_create_container (ctrl_t ctrl, const char *filename,
+                                  strlist_t keys);
 
 
 #endif /*G13_CREATE_H*/
index 5838b13..754371d 100644 (file)
--- a/g13/g13.c
+++ b/g13/g13.c
@@ -47,6 +47,7 @@ enum cmd_and_opt_values {
   aNull = 0,
   oQuiet       = 'q',
   oVerbose     = 'v',
+  oRecipient   = 'r',
 
   aGPGConfList  = 500,
   aGPGConfTest,
@@ -91,8 +92,6 @@ enum cmd_and_opt_values {
   oDryRun,
   oNoDetach,
 
-  oRecipient,
-
   oNoRandomSeedFile,
   oFakedSystemTime
  };
@@ -308,30 +307,6 @@ set_cmd (enum cmd_and_opt_values *ret_cmd, enum cmd_and_opt_values new_cmd)
 }
 
 
-/* Helper to add recipients to a list. */
-static int
-add_encryption_key (ctrl_t ctrl, const char *name,
-                    void /*FIXME*/ *keylist, int is_cms)
-{
-  /* FIXME: Decide whether to add a CMS or OpenPGP key and then add
-     the key to a list.  */
-  /* int rc = foo_add_to_certlist (ctrl, name, 0, recplist, is_encrypt_to); */
-  /* if (rc) */
-  /*   { */
-  /*     if (recp_required) */
-  /*       { */
-  /*         log_error ("can't encrypt to `%s': %s\n", name, gpg_strerror (rc)); */
-  /*         gpgsm_status2 (ctrl, STATUS_INV_RECP, */
-  /*                        get_inv_recpsgnr_code (rc), name, NULL); */
-  /*       } */
-  /*     else */
-  /*       log_info (_("NOTE: won't be able to encrypt to `%s': %s\n"), */
-  /*                 name, gpg_strerror (rc)); */
-  /*   } */
-  return 0; /* Key is good.  */
-}
-
-
 int
 main ( int argc, char **argv)
 {
@@ -664,18 +639,20 @@ main ( int argc, char **argv)
 
   /* Parse all given encryption keys.  This does a lookup of the keys
      and stops if any of the given keys was not found. */
+#if 0 /* Currently not implemented.  */  
   if (!nokeysetup)
     {
       strlist_t sl;
       int failed = 0;
       
       for (sl = recipients; sl; sl = sl->next)
-        if (add_encryption_key (&ctrl, sl->d, NULL /* FIXME*/, 0))
+        if (check_encryption_key ())
           failed = 1;
       if (failed)
         g13_exit (1);
     }
-  
+#endif /*0*/ 
   /* Dispatch command.  */
   switch (cmd)
     {
@@ -715,7 +692,7 @@ main ( int argc, char **argv)
         if (argc != 1) 
           wrong_args ("--create filename");
         start_idle_task ();
-        err = g13_create_container (&ctrl, argv[0]);
+        err = g13_create_container (&ctrl, argv[0], recipients);
         if (err)
           log_error ("error creating a new container: %s <%s>\n",
                      gpg_strerror (err), gpg_strsource (err));
index 585b9e7..e9b9a0a 100644 (file)
@@ -29,9 +29,9 @@
 #include <assuan.h>
 #include "i18n.h"
 #include "keyblob.h"
-#include "./server.h"
-#include "./mount.h"
-
+#include "server.h"
+#include "mount.h"
+#include "create.h"
 
 /* Local data for this server module.  A pointer to this is stored in
    the CTRL object of each connection.  */
@@ -42,6 +42,7 @@ struct server_local_s
 
   char *containername;  /* Malloced active containername.  */
 
+  strlist_t recipients; /* List of recipients.  */
 };
 
 
@@ -187,6 +188,8 @@ reset_notify (assuan_context_t ctx)
   xfree (ctrl->server_local->containername);
   ctrl->server_local->containername = NULL;
 
+  FREE_STRLIST (ctrl->server_local->recipients);
+
   assuan_close_input_fd (ctx);
   assuan_close_output_fd (ctx);
 }
@@ -359,17 +362,12 @@ static gpg_error_t
 cmd_recipient (assuan_context_t ctx, char *line)
 {
   ctrl_t ctrl = assuan_get_pointer (ctx);
-  gpg_error_t err;
+  gpg_error_t err = 0;
 
-  (void)ctrl;
-  err = gpg_error (GPG_ERR_NOT_IMPLEMENTED);
-  /* err = gpgsm_add_to_certlist (ctrl, line, 0, */
-  /*                              &ctrl->server_local->recplist, 0); */
-  /* if (err) */
-  /*   { */
-  /*     gpgsm_status2 (ctrl, STATUS_INV_RECP, */
-  /*                    get_inv_recpsgnr_code (rc), line, NULL); */
-  /*   } */
+  line = skip_options (line);
+
+  if (!add_to_strlist_try (&ctrl->server_local->recipients, line))
+    err = gpg_error_from_syserror ();
 
   return leave_cmd (ctx, err);
 }
@@ -386,6 +384,7 @@ cmd_signer (assuan_context_t ctx, char *line)
   gpg_error_t err;
 
   (void)ctrl;
+  (void)line;
 
   err = gpg_error (GPG_ERR_NOT_IMPLEMENTED);
   return leave_cmd (ctx, err);
@@ -402,16 +401,50 @@ cmd_create (assuan_context_t ctx, char *line)
 {
   ctrl_t ctrl = assuan_get_pointer (ctx);
   gpg_error_t err;
-
-  (void)ctrl;
+  char *p, *pend;
+  size_t len;
 
   /* First we close the active container.  */
   xfree (ctrl->server_local->containername);
   ctrl->server_local->containername = NULL;
 
+  /* Parse the line.  */
+  line = skip_options (line);
+  for (p=line; *p && !spacep (p); p++)
+    ;
+  pend = p;
+  while (spacep(p))
+    p++;
+  if (*p || pend == line)
+    {
+      err = gpg_error (GPG_ERR_ASS_SYNTAX);
+      goto leave;
+    }
+  *pend = 0;
+
+  /* Unescape the line and check for embedded Nul bytes.  */
+  len = percent_plus_unescape_inplace (line, 0);
+  line[len] = 0;
+  if (!len || memchr (line, 0, len))
+    {
+      err = gpg_error (GPG_ERR_INV_NAME);
+      goto leave;
+    }
 
+  /* Create container.  */
+  err = g13_create_container (ctrl, line, ctrl->server_local->recipients);
 
-  err = gpg_error (GPG_ERR_NOT_IMPLEMENTED);
+  if (!err)
+    {
+      FREE_STRLIST (ctrl->server_local->recipients);
+  
+      /* Store the filename.  */
+      ctrl->server_local->containername = xtrystrdup (line);
+      if (!ctrl->server_local->containername)
+        err = gpg_error_from_syserror ();
+
+    }
+ leave:
   return leave_cmd (ctx, err);
 }
 
@@ -617,6 +650,7 @@ g13_server (ctrl_t ctrl)
     log_info ("Assuan accept problem: %s\n", gpg_strerror (err));
   
  leave:
+  reset_notify (ctx);  /* Release all items hold by SERVER_LOCAL.  */
   if (ctrl->server_local)
     {
       xfree (ctrl->server_local);
index 84e37c5..5498493 100644 (file)
@@ -1,3 +1,7 @@
+2009-10-19  Werner Koch  <wk@g10code.com>
+
+       * strlist.c (add_to_strlist_try): New.
+
 2009-09-22  Werner Koch  <wk@g10code.com>
 
        * dotlock.h (DOTLOCK): Rename to dotlock_t.  Change all users.
index d45a164..b31e621 100644 (file)
@@ -57,6 +57,25 @@ add_to_strlist( strlist_t *list, const char *string )
 }
 
 
+/* Add STRING to the LIST at the front.  This function returns NULL
+   and sets ERRNO on memory shortage.  */
+strlist_t
+add_to_strlist_try (strlist_t *list, const char *string)
+{
+  strlist_t sl;
+  
+  sl = jnlib_malloc (sizeof *sl + strlen (string));
+  if (sl)
+    {
+      sl->flags = 0;
+      strcpy (sl->d, string);
+      sl->next = *list;
+      *list = sl;
+    }
+  return sl;
+}
+
+
 /* Same as add_to_strlist() but if IS_UTF8 is *not* set, a conversion
    to UTF-8 is done.  This function terminates the process on memory
    shortage.  */
index 4191624..1e2ffa8 100644 (file)
@@ -30,6 +30,7 @@ typedef struct string_list *strlist_t;
 
 void    free_strlist (strlist_t sl);
 strlist_t add_to_strlist (strlist_t *list, const char *string);
+strlist_t add_to_strlist_try (strlist_t *list, const char *string);
 
 strlist_t add_to_strlist2( strlist_t *list, const char *string, int is_utf8);
 
index e68d5a7..f7c7359 100644 (file)
@@ -1,3 +1,9 @@
+2009-10-16  Werner Koch  <wk@g10code.com>
+
+       * gpgsm.c (default_include_certs): Change to -2.
+       (DEFAULT_INCLUDE_CERTS): New.
+       (DEFAULT_CIPHER_ALGO): New.  Use instead of hardcoded "3DES".
+
 2009-09-30  Werner Koch  <wk@g10code.com>
 
        * gpgsm.c (main): Remove obsolete GCRYCTL_DISABLE_INTERNAL_LOCKING.
index 17cc78b..adfe6cd 100644 (file)
@@ -402,12 +402,25 @@ static unsigned int debug_value;
 /* Option --enable-special-filenames */
 static int allow_special_filenames;
 
-/* Default value for include-certs. */
-static int default_include_certs = 1; /* Only include the signer's cert. */
+/* Default value for include-certs.  We need an extra macro for
+   gpgconf-list because the variable will be changed by the command
+   line option.  
+
+   It is often cumbersome to locate intermediate certificates, thus by
+   default we include all certificates in the chain.  However we leave
+   out the root certificate because that would make it too easy for
+   the recipient to import that root certificate.  A root certificate
+   should be installed only after due checks and thus it won't help to
+   send it along with each message.  */
+#define DEFAULT_INCLUDE_CERTS -2 /* Include all certs but root. */
+static int default_include_certs = DEFAULT_INCLUDE_CERTS; 
 
 /* Whether the chain mode shall be used for validation.  */
 static int default_validation_model;
 
+/* The default cipher algo.  */
+#define DEFAULT_CIPHER_ALGO "3DES"  /*des-EDE3-CBC*/
+
 
 static char *build_list (const char *text,
                         const char *(*mapf)(int), int (*chkf)(int));
@@ -897,7 +910,7 @@ main ( int argc, char **argv)
 
   /* Note: If you change this default cipher algorithm , please
      remember to update the Gpgconflist entry as well.  */
-  opt.def_cipher_algoid = "3DES";  /*des-EDE3-CBC*/
+  opt.def_cipher_algoid = DEFAULT_CIPHER_ALGO; 
 
   opt.homedir = default_homedir ();
 
@@ -1606,14 +1619,16 @@ main ( int argc, char **argv)
         printf ("disable-crl-checks:%lu:\n", GC_OPT_FLAG_NONE);
         printf ("disable-trusted-cert-crl-check:%lu:\n", GC_OPT_FLAG_NONE);
         printf ("enable-ocsp:%lu:\n", GC_OPT_FLAG_NONE);
-        printf ("include-certs:%lu:1:\n", GC_OPT_FLAG_DEFAULT);
+        printf ("include-certs:%lu:%d:\n", GC_OPT_FLAG_DEFAULT,
+                DEFAULT_INCLUDE_CERTS);
         printf ("disable-policy-checks:%lu:\n", GC_OPT_FLAG_NONE);
         printf ("auto-issuer-key-retrieve:%lu:\n", GC_OPT_FLAG_NONE);
         printf ("disable-dirmngr:%lu:\n", GC_OPT_FLAG_NONE);
 #ifndef HAVE_W32_SYSTEM
         printf ("prefer-system-dirmngr:%lu:\n", GC_OPT_FLAG_NONE);
 #endif
-        printf ("cipher-algo:%lu:\"3DES:\n", GC_OPT_FLAG_DEFAULT);
+        printf ("cipher-algo:%lu:\"%s:\n", GC_OPT_FLAG_DEFAULT,
+                DEFAULT_CIPHER_ALGO);
         printf ("p12-charset:%lu:\n", GC_OPT_FLAG_DEFAULT);
         printf ("default-key:%lu:\n", GC_OPT_FLAG_DEFAULT);
         printf ("encrypt-to:%lu:\n", GC_OPT_FLAG_DEFAULT);