* server.c (gpgsm_server): Add arg DEFAULT_RECPLIST.
authorWerner Koch <wk@gnupg.org>
Wed, 17 Dec 2003 17:12:14 +0000 (17:12 +0000)
committerWerner Koch <wk@gnupg.org>
Wed, 17 Dec 2003 17:12:14 +0000 (17:12 +0000)
(cmd_encrypt): Add all enrypt-to marked certs to the list.
* encrypt.c (gpgsm_encrypt): Check that real recipients are
available.
* gpgsm.c (main): Make the --encrypt-to and --no-encrypt-to
options work.  Pass the list of recients to gpgsm_server.
* gpgsm.h (certlist_s): Add field IS_ENCRYPT_TO.
(opt): Add NO_ENCRYPT_TO.
* certlist.c (gpgsm_add_to_certlist): New arg IS_ENCRYPT_TO.
Changed all callers and ignore duplicate entries.
(is_cert_in_certlist): New.
(gpgsm_add_cert_to_certlist): New.

NEWS
sm/ChangeLog
sm/certlist.c
sm/encrypt.c
sm/gpgsm.c
sm/gpgsm.h
sm/server.c

diff --git a/NEWS b/NEWS
index ce966b7..8a381ea 100644 (file)
--- a/NEWS
+++ b/NEWS
@@ -1,8 +1,8 @@
 Noteworthy changes in version 1.9.3 (unreleased)
 ------------------------------------------------
 
- * New options --{enable,disable}-ocsp to validate keys using OCSP
-   This requires a not yet released DirMngr 0.5.1.  Default is
+ * New gpgsm options --{enable,disable}-ocsp to validate keys using
+   OCSP. This requires a not yet released DirMngr 0.5.1.  Default is
    disabled.
 
  * The --log-file option may now be used to print logs to a socket.
@@ -10,6 +10,11 @@ Noteworthy changes in version 1.9.3 (unreleased)
    not work on all systems and falls back to stderr if there is a
    problem with the socket.
 
+ * The options --encrypt-to and --no-encrypt-to now work the same in
+   gpgsm as in gpg.  Note, they are also used in server mode.
+
+ * Duplicated recipients are now silently removed in gpgsm.
+
 
 Noteworthy changes in version 1.9.2 (2003-11-17)
 ------------------------------------------------
index 62505fe..e3329b6 100644 (file)
@@ -1,5 +1,18 @@
 2003-12-17  Werner Koch  <wk@gnupg.org>
 
+       * server.c (gpgsm_server): Add arg DEFAULT_RECPLIST.
+       (cmd_encrypt): Add all enrypt-to marked certs to the list.
+       * encrypt.c (gpgsm_encrypt): Check that real recipients are
+       available.
+       * gpgsm.c (main): Make the --encrypt-to and --no-encrypt-to
+       options work.  Pass the list of recients to gpgsm_server.
+       * gpgsm.h (certlist_s): Add field IS_ENCRYPT_TO.
+       (opt): Add NO_ENCRYPT_TO.
+       * certlist.c (gpgsm_add_to_certlist): New arg IS_ENCRYPT_TO.
+       Changed all callers and ignore duplicate entries.
+       (is_cert_in_certlist): New.
+       (gpgsm_add_cert_to_certlist): New.
+
        * certdump.c (gpgsm_print_serial): Cleaned up cast use in strtoul.
        (gpgsm_dump_serial): Ditto.
 
index fe28309..b61f0f6 100644 (file)
@@ -131,14 +131,54 @@ same_subject_issuer (const char *subject, const char *issuer, ksba_cert_t cert)
   return tmp;
 }
 
+/* Return true if CERT is already contained in CERTLIST. */
+static int
+is_cert_in_certlist (ksba_cert_t cert, certlist_t certlist)
+{
+  const unsigned char *img_a, *img_b;
+  size_t len_a, len_b;
+
+  img_a = ksba_cert_get_image (cert, &len_a);
+  if (img_a)
+    {
+      for ( ; certlist; certlist = certlist->next)
+        {
+          img_b = ksba_cert_get_image (certlist->cert, &len_b);
+          if (img_b && len_a == len_b && !memcmp (img_a, img_b, len_a))
+            return 1; /* Already contained. */
+        }
+    }
+  return 0;
+}
 
 
+/* Add CERT to the list of certificates at CERTADDR but avoid
+   duplicates. */
+int 
+gpgsm_add_cert_to_certlist (ctrl_t ctrl, ksba_cert_t cert,
+                            certlist_t *listaddr, int is_encrypt_to)
+{
+  if (!is_cert_in_certlist (cert, *listaddr))
+    {
+      certlist_t cl = xtrycalloc (1, sizeof *cl);
+      if (!cl)
+        return OUT_OF_CORE (errno);
+      cl->cert = cert;
+      ksba_cert_ref (cert);
+      cl->next = *listaddr;
+      cl->is_encrypt_to = is_encrypt_to;
+      *listaddr = cl;
+    }
+   return 0;
+}
+
 /* Add a certificate to a list of certificate and make sure that it is
    a valid certificate.  With SECRET set to true a secret key must be
-   available for the certificate. */
+   available for the certificate. IS_ENCRYPT_TO sets the corresponding
+   flag in the new create LISTADDR item.  */
 int
 gpgsm_add_to_certlist (CTRL ctrl, const char *name, int secret,
-                       CERTLIST *listaddr)
+                       CERTLIST *listaddr, int is_encrypt_to)
 {
   int rc;
   KEYDB_SEARCH_DESC desc;
@@ -224,31 +264,35 @@ gpgsm_add_to_certlist (CTRL ctrl, const char *name, int secret,
           xfree (subject);
           xfree (issuer);
 
-          if (!rc && secret) 
+          if (!rc && !is_cert_in_certlist (cert, *listaddr))
             {
-              char *p;
-
-              rc = gpg_error (GPG_ERR_NO_SECKEY);
-              p = gpgsm_get_keygrip_hexstring (cert);
-              if (p)
+              if (!rc && secret) 
                 {
-                  if (!gpgsm_agent_havekey (p))
-                    rc = 0;
-                  xfree (p);
+                  char *p;
+                  
+                  rc = gpg_error (GPG_ERR_NO_SECKEY);
+                  p = gpgsm_get_keygrip_hexstring (cert);
+                  if (p)
+                    {
+                      if (!gpgsm_agent_havekey (p))
+                        rc = 0;
+                      xfree (p);
+                    }
                 }
-            }
-          if (!rc)
-            rc = gpgsm_validate_chain (ctrl, cert, NULL);
-          if (!rc)
-            {
-              CERTLIST cl = xtrycalloc (1, sizeof *cl);
-              if (!cl)
-                rc = OUT_OF_CORE (errno);
-              else 
+              if (!rc)
+                rc = gpgsm_validate_chain (ctrl, cert, NULL);
+              if (!rc)
                 {
-                  cl->cert = cert; cert = NULL;
-                  cl->next = *listaddr;
-                  *listaddr = cl;
+                  CERTLIST cl = xtrycalloc (1, sizeof *cl);
+                  if (!cl)
+                    rc = OUT_OF_CORE (errno);
+                  else 
+                    {
+                      cl->cert = cert; cert = NULL;
+                      cl->next = *listaddr;
+                      cl->is_encrypt_to = is_encrypt_to;
+                      *listaddr = cl;
+                    }
                 }
             }
         }
index f31391e..8f2c26b 100644 (file)
@@ -306,7 +306,13 @@ gpgsm_encrypt (CTRL ctrl, CERTLIST recplist, int data_fd, FILE *out_fp)
 
   memset (&encparm, 0, sizeof encparm);
 
-  if (!recplist)
+  /* Check that the certificate list is not empty and that at least
+     one certificate is not flagged as encrypt_to; i.e. is a real
+     recipient. */
+  for (cl = recplist; cl; cl = cl->next)
+    if (!cl->is_encrypt_to)
+      break;
+  if (!cl)
     {
       log_error(_("no valid recipients given\n"));
       gpgsm_status (ctrl, STATUS_NO_RECP, "0");
@@ -412,7 +418,7 @@ gpgsm_encrypt (CTRL ctrl, CERTLIST recplist, int data_fd, FILE *out_fp)
       goto leave;
     }
 
-  /* gather certificates of recipients, encrypt the session key for
+  /* Gather certificates of recipients, encrypt the session key for
      each and store them in the CMS object */
   for (recpno = 0, cl = recplist; cl; recpno++, cl = cl->next)
     {
@@ -447,7 +453,7 @@ gpgsm_encrypt (CTRL ctrl, CERTLIST recplist, int data_fd, FILE *out_fp)
         }
   }
 
-  /* main control loop for encryption */
+  /* Main control loop for encryption. */
   recpno = 0;
   do 
     {
index 497df04..c8d76af 100644 (file)
@@ -277,10 +277,10 @@ static ARGPARSE_OPTS opts[] = {
     { oDefRecipientSelf, "default-recipient-self" ,0,
                                N_("use the default key as default recipient")},
     { oNoDefRecipient, "no-default-recipient", 0, "@" },
+#endif
     { oEncryptTo, "encrypt-to", 2, "@" },
     { oNoEncryptTo, "no-encrypt-to", 0, "@" },
 
-#endif
     { oUser, "local-user",2, N_("use this user-id to sign or decrypt")},
 
 #if 0
@@ -585,6 +585,31 @@ set_cmd (enum cmd_and_opt_values *ret_cmd, enum cmd_and_opt_values new_cmd)
 }
 
 
+/* Helper to add recipients to a list. */
+static void
+do_add_recipient (ctrl_t ctrl, const char *name,
+                  certlist_t *recplist, int is_encrypt_to)
+{
+  int rc = gpgsm_add_to_certlist (ctrl, name, 0, recplist, is_encrypt_to);
+  if (rc)
+    {
+      log_error (_("can't encrypt to `%s': %s\n"), name, gpg_strerror (rc));
+      gpgsm_status2 (ctrl, STATUS_INV_RECP,
+                     gpg_err_code (rc) == -1?                         "1":
+                     gpg_err_code (rc) == GPG_ERR_NO_PUBKEY?          "1":
+                     gpg_err_code (rc) == GPG_ERR_AMBIGUOUS_NAME?     "2":
+                     gpg_err_code (rc) == GPG_ERR_WRONG_KEY_USAGE?    "3":
+                     gpg_err_code (rc) == GPG_ERR_CERT_REVOKED?       "4":
+                     gpg_err_code (rc) == GPG_ERR_CERT_EXPIRED?       "5":
+                     gpg_err_code (rc) == GPG_ERR_NO_CRL_KNOWN?       "6":
+                     gpg_err_code (rc) == GPG_ERR_CRL_TOO_OLD?        "7":
+                     gpg_err_code (rc) == GPG_ERR_NO_POLICY_MATCH?    "8":
+                     "0",
+                     name, NULL);
+    }
+}
+
+
 int
 main ( int argc, char **argv)
 {
@@ -953,8 +978,8 @@ main ( int argc, char **argv)
 
         case oSkipVerify: opt.skip_verify=1; break;
 
-        case oNoEncryptTo: /*fixme: opt.no_encrypt_to = 1;*/ break;
-        case oEncryptTo: /* store the recipient in the second list */
+        case oNoEncryptTo: opt.no_encrypt_to = 1; break;
+        case oEncryptTo: /* Store the recipient in the second list */
           sl = add_to_strlist (&remusr, pargs.r.ret_str);
           sl->flags = 1;
           break;
@@ -1107,7 +1132,7 @@ main ( int argc, char **argv)
 
   for (sl = locusr; sl; sl = sl->next)
     {
-      int rc = gpgsm_add_to_certlist (&ctrl, sl->d, 1, &signerlist);
+      int rc = gpgsm_add_to_certlist (&ctrl, sl->d, 1, &signerlist, 0);
       if (rc)
         {
           log_error (_("can't sign using `%s': %s\n"),
@@ -1127,27 +1152,22 @@ main ( int argc, char **argv)
                          sl->d, NULL);
         }
     }
+
+  /* Build the recipient list.  We first add the regular ones and then
+     the encrypt-to ones because the underlying function will silenty
+     ignore duplicates and we can't allow to keep a duplicate which is
+     flagged as encrypt-to as the actually encrypt function would then
+     complain about no (regular) recipients. */
   for (sl = remusr; sl; sl = sl->next)
+    if (!(sl->flags & 1))
+      do_add_recipient (&ctrl, sl->d, &recplist, 0);
+  if (!opt.no_encrypt_to)
     {
-      int rc = gpgsm_add_to_certlist (&ctrl, sl->d, 0, &recplist);
-      if (rc)
-        {
-          log_error (_("can't encrypt to `%s': %s\n"),
-                     sl->d, gpg_strerror (rc));
-          gpgsm_status2 (&ctrl, STATUS_INV_RECP,
-                         gpg_err_code (rc) == -1?                         "1":
-                         gpg_err_code (rc) == GPG_ERR_NO_PUBKEY?          "1":
-                         gpg_err_code (rc) == GPG_ERR_AMBIGUOUS_NAME?     "2":
-                         gpg_err_code (rc) == GPG_ERR_WRONG_KEY_USAGE?    "3":
-                         gpg_err_code (rc) == GPG_ERR_CERT_REVOKED?       "4":
-                         gpg_err_code (rc) == GPG_ERR_CERT_EXPIRED?       "5":
-                         gpg_err_code (rc) == GPG_ERR_NO_CRL_KNOWN?       "6":
-                         gpg_err_code (rc) == GPG_ERR_CRL_TOO_OLD?        "7":
-                         gpg_err_code (rc) == GPG_ERR_NO_POLICY_MATCH?    "8":
-                         "0",
-                         sl->d, NULL);
-        }
-  }
+      for (sl = remusr; sl; sl = sl->next)
+        if ((sl->flags & 1))
+          do_add_recipient (&ctrl, sl->d, &recplist, 1);
+    }
   if (log_get_errorcount(0))
     gpgsm_exit(1); /* must stop for invalid recipients */
   
@@ -1165,7 +1185,7 @@ main ( int argc, char **argv)
           sleep (debug_wait);
           log_debug ("... okay\n");
          }
-      gpgsm_server ();
+      gpgsm_server (recplist);
       break;
 
     case aCallDirmngr:
index 8c71c34..e8cdd93 100644 (file)
@@ -72,6 +72,8 @@ struct {
   char *def_recipient;    /* userID of the default recipient */
   int def_recipient_self; /* The default recipient is the default key */
 
+  int no_encrypt_to;      /* Ignore all as encrypt to marked recipients. */
+
   char *local_user;       /* NULL or argument to -u */
 
   int always_trust;       /* Trust the given keys even if there is no
@@ -135,6 +137,7 @@ struct server_control_s {
   int use_ocsp;       /* Set to true if OCSP should be used. */
 };
 typedef struct server_control_s *CTRL;
+typedef struct server_control_s *ctrl_t;
 
 /* data structure used in base64.c */
 typedef struct base64_context_s *Base64Context;
@@ -143,22 +146,26 @@ typedef struct base64_context_s *Base64Context;
 struct certlist_s {
   struct certlist_s *next;
   ksba_cert_t cert;
+  int is_encrypt_to; /* True if the certificate has been set through
+                        the --encrypto-to option. */
 };
 typedef struct certlist_s *CERTLIST;
+typedef struct certlist_s *certlist_t;
 
 /*-- gpgsm.c --*/
 void gpgsm_exit (int rc);
 void gpgsm_init_default_ctrl (struct server_control_s *ctrl);
 
 /*-- server.c --*/
-void gpgsm_server (void);
-void gpgsm_status (CTRL ctrl, int no, const char *text);
-void gpgsm_status2 (CTRL ctrl, int no, ...);
-void gpgsm_status_with_err_code (CTRL ctrl, int no, const char *text,
+void gpgsm_server (certlist_t default_recplist);
+void gpgsm_status (ctrl_t ctrl, int no, const char *text);
+void gpgsm_status2 (ctrl_t ctrl, int no, ...);
+void gpgsm_status_with_err_code (ctrl_t ctrl, int no, const char *text,
                                  gpg_err_code_t ec);
 
 /*-- fingerprint --*/
-char *gpgsm_get_fingerprint (ksba_cert_t cert, int algo, char *array, int *r_len);
+char *gpgsm_get_fingerprint (ksba_cert_t cert, int algo,
+                             char *array, int *r_len);
 char *gpgsm_get_fingerprint_string (ksba_cert_t cert, int algo);
 char *gpgsm_get_fingerprint_hexstring (ksba_cert_t cert, int algo);
 unsigned long gpgsm_get_short_fingerprint (ksba_cert_t cert);
@@ -169,10 +176,10 @@ char *gpgsm_get_certid (ksba_cert_t cert);
 
 /*-- base64.c --*/
 int  gpgsm_create_reader (Base64Context *ctx,
-                          CTRL ctrl, FILE *fp, ksba_reader_t *r_reader);
+                          ctrl_t ctrl, FILE *fp, ksba_reader_t *r_reader);
 void gpgsm_destroy_reader (Base64Context ctx);
 int  gpgsm_create_writer (Base64Context *ctx,
-                          CTRL ctrl, FILE *fp, ksba_writer_t *r_writer);
+                          ctrl_t ctrl, FILE *fp, ksba_writer_t *r_writer);
 int  gpgsm_finish_writer (Base64Context ctx);
 void gpgsm_destroy_writer (Base64Context ctx);
 
@@ -201,7 +208,8 @@ int gpgsm_create_cms_signature (ksba_cert_t cert, gcry_md_hd_t md, int mdalgo,
 /*-- certchain.c --*/
 int gpgsm_walk_cert_chain (ksba_cert_t start, ksba_cert_t *r_next);
 int gpgsm_is_root_cert (ksba_cert_t cert);
-int gpgsm_validate_chain (CTRL ctrl, ksba_cert_t cert, ksba_isotime_t r_exptime);
+int gpgsm_validate_chain (ctrl_t ctrl, ksba_cert_t cert,
+                          ksba_isotime_t r_exptime);
 int gpgsm_basic_cert_check (ksba_cert_t cert);
 
 /*-- certlist.c --*/
@@ -210,41 +218,43 @@ int gpgsm_cert_use_encrypt_p (ksba_cert_t cert);
 int gpgsm_cert_use_verify_p (ksba_cert_t cert);
 int gpgsm_cert_use_decrypt_p (ksba_cert_t cert);
 int gpgsm_cert_use_cert_p (ksba_cert_t cert);
-int gpgsm_add_to_certlist (CTRL ctrl, const char *name, int secret,
-                           CERTLIST *listaddr);
-void gpgsm_release_certlist (CERTLIST list);
+int gpgsm_add_cert_to_certlist (ctrl_t ctrl, ksba_cert_t cert,
+                                certlist_t *listaddr, int is_encrypt_to);
+int gpgsm_add_to_certlist (ctrl_t ctrl, const char *name, int secret,
+                           certlist_t *listaddr, int is_encrypt_to);
+void gpgsm_release_certlist (certlist_t list);
 int gpgsm_find_cert (const char *name, ksba_cert_t *r_cert);
 
 /*-- keylist.c --*/
-void gpgsm_list_keys (CTRL ctrl, STRLIST names, FILE *fp, unsigned int mode);
+void gpgsm_list_keys (ctrl_t ctrl, STRLIST names, FILE *fp, unsigned int mode);
 
 /*-- import.c --*/
-int gpgsm_import (CTRL ctrl, int in_fd);
-int gpgsm_import_files (CTRL ctrl, int nfiles, char **files,
+int gpgsm_import (ctrl_t ctrl, int in_fd);
+int gpgsm_import_files (ctrl_t ctrl, int nfiles, char **files,
                         int (*of)(const char *fname));
 
 /*-- export.c --*/
-void gpgsm_export (CTRL ctrl, STRLIST names, FILE *fp);
+void gpgsm_export (ctrl_t ctrl, STRLIST names, FILE *fp);
 
 /*-- delete.c --*/
-int gpgsm_delete (CTRL ctrl, STRLIST names);
+int gpgsm_delete (ctrl_t ctrl, STRLIST names);
 
 /*-- verify.c --*/
-int gpgsm_verify (CTRL ctrl, int in_fd, int data_fd, FILE *out_fp);
+int gpgsm_verify (ctrl_t ctrl, int in_fd, int data_fd, FILE *out_fp);
 
 /*-- sign.c --*/
 int gpgsm_get_default_cert (ksba_cert_t *r_cert);
-int gpgsm_sign (CTRL ctrl, CERTLIST signerlist,
+int gpgsm_sign (ctrl_t ctrl, CERTLIST signerlist,
                 int data_fd, int detached, FILE *out_fp);
 
 /*-- encrypt.c --*/
-int gpgsm_encrypt (CTRL ctrl, CERTLIST recplist, int in_fd, FILE *out_fp);
+int gpgsm_encrypt (ctrl_t ctrl, CERTLIST recplist, int in_fd, FILE *out_fp);
 
 /*-- decrypt.c --*/
-int gpgsm_decrypt (CTRL ctrl, int in_fd, FILE *out_fp);
+int gpgsm_decrypt (ctrl_t ctrl, int in_fd, FILE *out_fp);
 
 /*-- certreqgen.c --*/
-int gpgsm_genkey (CTRL ctrl, int in_fd, FILE *out_fp);
+int gpgsm_genkey (ctrl_t ctrl, int in_fd, FILE *out_fp);
 
 /*-- call-agent.c --*/
 int gpgsm_agent_pksign (const char *keygrip,
@@ -264,9 +274,9 @@ int gpgsm_agent_passwd (const char *hexkeygrip);
 
 /*-- call-dirmngr.c --*/
 int gpgsm_dirmngr_isvalid (ksba_cert_t cert, int use_ocsp);
-int gpgsm_dirmngr_lookup (CTRL ctrl, STRLIST names,
+int gpgsm_dirmngr_lookup (ctrl_t ctrl, STRLIST names,
                           void (*cb)(void*, ksba_cert_t), void *cb_value);
-int gpgsm_dirmngr_run_command (CTRL ctrl, const char *command,
+int gpgsm_dirmngr_run_command (ctrl_t ctrl, const char *command,
                                int argc, char **argv);
 
 
index 20ba513..549c353 100644 (file)
@@ -39,12 +39,13 @@ static FILE *statusfp;
 
 /* Data used to assuciate an Assuan context with local server data */
 struct server_local_s {
-  ASSUAN_CONTEXT assuan_ctx;
+  assuan_context_t assuan_ctx;
   int message_fd;
   int list_internal;
   int list_external;
-  CERTLIST recplist;
-  CERTLIST signerlist;
+  certlist_t recplist;
+  certlist_t signerlist;
+  certlist_t default_recplist; /* As set by main() - don't release. */
 };
 
 
@@ -233,7 +234,7 @@ output_notify (ASSUAN_CONTEXT ctx, const char *line)
   way of specification [we will support this].  If this is a valid and
   trusted recipient the server does respond with OK, otherwise the
   return is an ERR with the reason why the recipient can't be used,
-  the encryption will then not be done for this recipient.  IF the
+  the encryption will then not be done for this recipient.  If the
   policy is not to encrypt at all if not all recipients are valid, the
   client has to take care of this.  All RECIPIENT commands are
   cumulative until a RESET or an successful ENCRYPT command.  */
@@ -243,7 +244,7 @@ cmd_recipient (ASSUAN_CONTEXT ctx, char *line)
   CTRL ctrl = assuan_get_pointer (ctx);
   int rc;
 
-  rc = gpgsm_add_to_certlist (ctrl, line, 0, &ctrl->server_local->recplist);
+  rc = gpgsm_add_to_certlist (ctrl, line, 0, &ctrl->server_local->recplist, 0);
   if (rc)
     {
       gpg_err_code_t r = gpg_err_code (rc);
@@ -286,7 +287,8 @@ cmd_signer (ASSUAN_CONTEXT ctx, char *line)
   CTRL ctrl = assuan_get_pointer (ctx);
   int rc;
 
-  rc = gpgsm_add_to_certlist (ctrl, line, 1, &ctrl->server_local->signerlist);
+  rc = gpgsm_add_to_certlist (ctrl, line, 1,
+                              &ctrl->server_local->signerlist, 0);
   if (rc)
     {
       gpg_err_code_t r = gpg_err_code (rc);
@@ -325,6 +327,7 @@ static int
 cmd_encrypt (ASSUAN_CONTEXT ctx, char *line)
 {
   CTRL ctrl = assuan_get_pointer (ctx);
+  certlist_t cl;
   int inp_fd, out_fd;
   FILE *out_fp;
   int rc;
@@ -339,14 +342,26 @@ cmd_encrypt (ASSUAN_CONTEXT ctx, char *line)
   out_fp = fdopen ( dup(out_fd), "w");
   if (!out_fp)
     return set_error (General_Error, "fdopen() failed");
-  rc = gpgsm_encrypt (assuan_get_pointer (ctx),
-                      ctrl->server_local->recplist,
-                      inp_fd, out_fp);
+  
+  /* Now add all encrypt-to marked recipients from the default
+     list. */
+  rc = 0;
+  if (!opt.no_encrypt_to)
+    {
+      for (cl=ctrl->server_local->recplist; !rc && cl; cl = cl->next)
+        if (cl->is_encrypt_to)
+          rc = gpgsm_add_cert_to_certlist (ctrl, cl->cert,
+                                           &ctrl->server_local->recplist, 1);
+    }
+  if (!rc)
+    rc = gpgsm_encrypt (assuan_get_pointer (ctx),
+                        ctrl->server_local->recplist,
+                        inp_fd, out_fp);
   fclose (out_fp);
 
   gpgsm_release_certlist (ctrl->server_local->recplist);
   ctrl->server_local->recplist = NULL;
-  /* close and reset the fd */
+  /* Close and reset the fd */
   close_message_fd (ctrl);
   assuan_close_input_fd (ctx);
   assuan_close_output_fd (ctx);
@@ -755,9 +770,11 @@ register_commands (ASSUAN_CONTEXT ctx)
   return 0;
 }
 
-/* Startup the server */
+/* Startup the server. DEFAULT_RECPLIST is the list of recipients as
+   set from the command line or config file.  We only require those
+   marked as encrypt-to. */
 void
-gpgsm_server (void)
+gpgsm_server (certlist_t default_recplist)
 {
   int rc;
   int filedes[2];
@@ -799,6 +816,7 @@ gpgsm_server (void)
   ctrl.server_local->message_fd = -1;
   ctrl.server_local->list_internal = 1;
   ctrl.server_local->list_external = 0;
+  ctrl.server_local->default_recplist = default_recplist;
 
   if (DBG_ASSUAN)
     assuan_set_log_stream (ctx, log_get_stream ());