[git] GnuPG - branch, master, updated. gnupg-2.1.0-48-gf173cdc

by Мирослав Николић cvs at cvs.gnupg.org
Thu Nov 27 20:41:15 CET 2014


This is an automated email from the git hooks/post-receive script. It was
generated because a ref change was pushed to the repository containing
the project "The GNU Privacy Guard".

The branch, master has been updated
       via  f173cdcdfbfd083b035516a406c2c754f38a0ace (commit)
       via  ccee34736b57a42ec4bdcb0d3181bdc6a08b0fff (commit)
       via  68a7ccc0c870cce6ab9fefb1aa6fd100e1de129b (commit)
      from  1c2140346d6ef9c35e303099d2d15be57869b4d5 (commit)

Those revisions listed above that are new to this repository have
not appeared on any other notification email; so we list those
revisions in full, below.

- Log -----------------------------------------------------------------
commit f173cdcdfbfd083b035516a406c2c754f38a0ace
Author: Мирослав Николић <wk at gnupg.org>
Date:   Thu Nov 27 20:41:37 2014 +0100

    gpg-agent: Add restricted connection feature.
    
    * agent/agent.h (opt): Add field extra_socket.
    (server_control_s): Add field restricted.
    * agent/command.c: Check restricted flag on many commands.
    * agent/gpg-agent.c (oExtraSocket): New.
    (opts): Add option --extra-socket.
    (socket_name_extra): New.
    (cleanup): Cleanup that socket name.
    (main): Implement oExtraSocket.
    (create_socket_name): Add arg homedir and change all callers.
    (create_server_socket): Rename arg is_ssh to primary and change
    callers.
    (start_connection_thread): Take ctrl as arg.
    (start_connection_thread_std): New.
    (start_connection_thread_extra): New.
    (handle_connections): Add arg listen_fd_extra and replace the
    connection starting code by parameterized loop.
    * common/asshelp.c (start_new_gpg_agent): Detect the use of the
    restricted mode and don't fail on sending the pinentry environment.
    
    * common/util.h (GPG_ERR_FORBIDDEN): New.

diff --git a/agent/agent.h b/agent/agent.h
index b80c6a0..0c83b27 100644
--- a/agent/agent.h
+++ b/agent/agent.h
@@ -130,6 +130,11 @@ struct
 
   /* This global option enables the ssh-agent subsystem.  */
   int ssh_support;
+
+  /* This global options indicates the use of an extra socket. Note
+     that we use a hack for cleanup handling in gpg-agent.c: If the
+     value is less than 2 the name has not yet been malloced. */
+  int extra_socket;
 } opt;
 
 
@@ -171,6 +176,9 @@ struct server_control_s
     gnupg_fd_t fd;
   } thread_startup;
 
+  /* Flag indicating the connection is run in restricted mode.  */
+  int restricted;
+
   /* Private data of the server (command.c). */
   struct server_local_s *server_local;
 
diff --git a/agent/command.c b/agent/command.c
index 11bfbeb..3e80663 100644
--- a/agent/command.c
+++ b/agent/command.c
@@ -502,6 +502,9 @@ cmd_geteventcounter (assuan_context_t ctx, char *line)
 
   (void)line;
 
+  if (ctrl->restricted)
+    return leave_cmd (ctx, gpg_error (GPG_ERR_FORBIDDEN));
+
   return agent_print_status (ctrl, "EVENTCOUNTER", "%u %u %u",
                              eventcounter.any,
                              eventcounter.key,
@@ -577,10 +580,14 @@ static const char hlp_listtrusted[] =
 static gpg_error_t
 cmd_listtrusted (assuan_context_t ctx, char *line)
 {
+  ctrl_t ctrl = assuan_get_pointer (ctx);
   int rc;
 
   (void)line;
 
+  if (ctrl->restricted)
+    return leave_cmd (ctx, gpg_error (GPG_ERR_FORBIDDEN));
+
   rc = agent_listtrusted (ctx);
   return leave_cmd (ctx, rc);
 }
@@ -599,6 +606,9 @@ cmd_marktrusted (assuan_context_t ctx, char *line)
   char fpr[41];
   int flag;
 
+  if (ctrl->restricted)
+    return leave_cmd (ctx, gpg_error (GPG_ERR_FORBIDDEN));
+
   /* parse the fingerprint value */
   for (p=line,n=0; hexdigitp (p); p++, n++)
     ;
@@ -718,7 +728,12 @@ cmd_setkeydesc (assuan_context_t ctx, char *line)
   plus_to_blank (desc);
 
   xfree (ctrl->server_local->keydesc);
-  ctrl->server_local->keydesc = xtrystrdup (desc);
+
+  if (ctrl->restricted)
+    ctrl->server_local->keydesc = strconcat
+      ("Note: Request from a remote site.\n\n", desc, NULL);
+  else
+    ctrl->server_local->keydesc = xtrystrdup (desc);
   if (!ctrl->server_local->keydesc)
     return out_of_core ();
   return 0;
@@ -928,6 +943,9 @@ cmd_genkey (assuan_context_t ctx, char *line)
   int opt_preset;
   char *p;
 
+  if (ctrl->restricted)
+    return leave_cmd (ctx, gpg_error (GPG_ERR_FORBIDDEN));
+
   opt_preset = has_option (line, "--preset");
   no_protection = has_option (line, "--no-protection");
   line = skip_options (line);
@@ -974,6 +992,9 @@ cmd_readkey (assuan_context_t ctx, char *line)
   unsigned char grip[20];
   gcry_sexp_t s_pkey = NULL;
 
+  if (ctrl->restricted)
+    return leave_cmd (ctx, gpg_error (GPG_ERR_FORBIDDEN));
+
   rc = parse_keygrip (ctx, line, grip);
   if (rc)
     return rc; /* Return immediately as this is already an Assuan error code.*/
@@ -1199,6 +1220,9 @@ cmd_keyinfo (assuan_context_t ctx, char *line)
   char hexgrip[41];
   int disabled, ttl, confirm, is_ssh;
 
+  if (ctrl->restricted)
+    return leave_cmd (ctx, gpg_error (GPG_ERR_FORBIDDEN));
+
   if (has_option (line, "--ssh-list"))
     list_mode = 2;
   else
@@ -1376,6 +1400,9 @@ cmd_get_passphrase (assuan_context_t ctx, char *line)
   int opt_repeat = 0;
   char *repeat_errtext = NULL;
 
+  if (ctrl->restricted)
+    return leave_cmd (ctx, gpg_error (GPG_ERR_FORBIDDEN));
+
   opt_data = has_option (line, "--data");
   opt_check = has_option (line, "--check");
   opt_no_ask = has_option (line, "--no-ask");
@@ -1515,10 +1542,14 @@ static const char hlp_clear_passphrase[] =
 static gpg_error_t
 cmd_clear_passphrase (assuan_context_t ctx, char *line)
 {
+  ctrl_t ctrl = assuan_get_pointer (ctx);
   char *cacheid = NULL;
   char *p;
   int opt_normal;
 
+  if (ctrl->restricted)
+    return leave_cmd (ctx, gpg_error (GPG_ERR_FORBIDDEN));
+
   opt_normal = has_option (line, "--mode=normal");
   line = skip_options (line);
 
@@ -1557,6 +1588,9 @@ cmd_get_confirmation (assuan_context_t ctx, char *line)
   char *desc = NULL;
   char *p;
 
+  if (ctrl->restricted)
+    return leave_cmd (ctx, gpg_error (GPG_ERR_FORBIDDEN));
+
   /* parse the stuff */
   for (p=line; *p == ' '; p++)
     ;
@@ -1595,6 +1629,9 @@ cmd_learn (assuan_context_t ctx, char *line)
   ctrl_t ctrl = assuan_get_pointer (ctx);
   int rc;
 
+  if (ctrl->restricted)
+    return leave_cmd (ctx, gpg_error (GPG_ERR_FORBIDDEN));
+
   rc = agent_handle_learn (ctrl, has_option (line, "--send")? ctx : NULL);
   return leave_cmd (ctx, rc);
 }
@@ -1621,6 +1658,9 @@ cmd_passwd (assuan_context_t ctx, char *line)
   char *pend;
   int opt_preset;
 
+  if (ctrl->restricted)
+    return leave_cmd (ctx, gpg_error (GPG_ERR_FORBIDDEN));
+
   opt_preset = has_option (line, "--preset");
   cache_nonce = option_value (line, "--cache-nonce");
   if (cache_nonce)
@@ -1756,6 +1796,7 @@ static const char hlp_preset_passphrase[] =
 static gpg_error_t
 cmd_preset_passphrase (assuan_context_t ctx, char *line)
 {
+  ctrl_t ctrl = assuan_get_pointer (ctx);
   int rc;
   char *grip_clear = NULL;
   unsigned char *passphrase = NULL;
@@ -1763,6 +1804,9 @@ cmd_preset_passphrase (assuan_context_t ctx, char *line)
   size_t len;
   int opt_inquire;
 
+  if (ctrl->restricted)
+    return leave_cmd (ctx, gpg_error (GPG_ERR_FORBIDDEN));
+
   if (!opt.allow_preset_passphrase)
     return set_error (GPG_ERR_NOT_SUPPORTED, "no --allow-preset-passphrase");
 
@@ -1847,6 +1891,9 @@ cmd_scd (assuan_context_t ctx, char *line)
   ctrl_t ctrl = assuan_get_pointer (ctx);
   int rc;
 
+  if (ctrl->restricted)
+    return leave_cmd (ctx, gpg_error (GPG_ERR_FORBIDDEN));
+
   rc = divert_generic_cmd (ctrl, line, ctx);
 
   return rc;
@@ -1876,6 +1923,8 @@ cmd_keywrap_key (assuan_context_t ctx, char *line)
   gpg_error_t err = 0;
   int clearopt = has_option (line, "--clear");
 
+  if (ctrl->restricted)
+    return leave_cmd (ctx, gpg_error (GPG_ERR_FORBIDDEN));
 
   assuan_begin_confidential (ctx);
   if (has_option (line, "--import"))
@@ -1940,6 +1989,9 @@ cmd_import_key (assuan_context_t ctx, char *line)
   char *cache_nonce = NULL;
   char *p;
 
+  if (ctrl->restricted)
+    return leave_cmd (ctx, gpg_error (GPG_ERR_FORBIDDEN));
+
   if (!ctrl->server_local->import_key)
     {
       err = gpg_error (GPG_ERR_MISSING_KEY);
@@ -2129,6 +2181,9 @@ cmd_export_key (assuan_context_t ctx, char *line)
   char *pend;
   int c;
 
+  if (ctrl->restricted)
+    return leave_cmd (ctx, gpg_error (GPG_ERR_FORBIDDEN));
+
   openpgp = has_option (line, "--openpgp");
   cache_nonce = option_value (line, "--cache-nonce");
   if (cache_nonce)
@@ -2280,6 +2335,9 @@ cmd_delete_key (assuan_context_t ctx, char *line)
   gpg_error_t err;
   unsigned char grip[20];
 
+  if (ctrl->restricted)
+    return leave_cmd (ctx, gpg_error (GPG_ERR_FORBIDDEN));
+
   line = skip_options (line);
 
   err = parse_keygrip (ctx, line, grip);
@@ -2318,6 +2376,9 @@ cmd_keytocard (assuan_context_t ctx, char *line)
   unsigned char *shdkey;
   time_t timestamp;
 
+  if (ctrl->restricted)
+    return leave_cmd (ctx, gpg_error (GPG_ERR_FORBIDDEN));
+
   force = has_option (line, "--force");
   line = skip_options (line);
 
@@ -2434,6 +2495,8 @@ cmd_keytocard (assuan_context_t ctx, char *line)
  leave:
   return leave_cmd (ctx, err);
 }
+
+
 

 static const char hlp_getval[] =
   "GETVAL <key>\n"
@@ -2443,11 +2506,15 @@ static const char hlp_getval[] =
 static gpg_error_t
 cmd_getval (assuan_context_t ctx, char *line)
 {
+  ctrl_t ctrl = assuan_get_pointer (ctx);
   int rc = 0;
   char *key = NULL;
   char *p;
   struct putval_item_s *vl;
 
+  if (ctrl->restricted)
+    return leave_cmd (ctx, gpg_error (GPG_ERR_FORBIDDEN));
+
   for (p=line; *p == ' '; p++)
     ;
   key = p;
@@ -2498,6 +2565,7 @@ static const char hlp_putval[] =
 static gpg_error_t
 cmd_putval (assuan_context_t ctx, char *line)
 {
+  ctrl_t ctrl = assuan_get_pointer (ctx);
   int rc = 0;
   char *key = NULL;
   char *value = NULL;
@@ -2505,6 +2573,9 @@ cmd_putval (assuan_context_t ctx, char *line)
   char *p;
   struct putval_item_s *vl, *vlprev;
 
+  if (ctrl->restricted)
+    return leave_cmd (ctx, gpg_error (GPG_ERR_FORBIDDEN));
+
   for (p=line; *p == ' '; p++)
     ;
   key = p;
@@ -2583,6 +2654,9 @@ cmd_updatestartuptty (assuan_context_t ctx, char *line)
 
   (void)line;
 
+  if (ctrl->restricted)
+    return leave_cmd (ctx, gpg_error (GPG_ERR_FORBIDDEN));
+
   se = session_env_new ();
   if (!se)
     err = gpg_error_from_syserror ();
@@ -2634,6 +2708,9 @@ cmd_killagent (assuan_context_t ctx, char *line)
 
   (void)line;
 
+  if (ctrl->restricted)
+    return leave_cmd (ctx, gpg_error (GPG_ERR_FORBIDDEN));
+
   ctrl->server_local->stopme = 1;
   assuan_set_flag (ctx, ASSUAN_FORCE_CLOSE, 1);
   return 0;
@@ -2648,9 +2725,13 @@ static const char hlp_reloadagent[] =
 static gpg_error_t
 cmd_reloadagent (assuan_context_t ctx, char *line)
 {
-  (void)ctx;
+  ctrl_t ctrl = assuan_get_pointer (ctx);
+
   (void)line;
 
+  if (ctrl->restricted)
+    return leave_cmd (ctx, gpg_error (GPG_ERR_FORBIDDEN));
+
   agent_sighup_action ();
   return 0;
 }
@@ -2672,7 +2753,8 @@ static const char hlp_getinfo[] =
   "  std_session_env - List the standard session environment.\n"
   "  std_startup_env - List the standard startup environment.\n"
   "  cmd_has_option\n"
-  "              - Returns OK if the command CMD implements the option OPT\n.";
+  "              - Returns OK if the command CMD implements the option OPT.\n"
+  "  restricted  - Returns OK if the connection is in restricted mode.\n";
 static gpg_error_t
 cmd_getinfo (assuan_context_t ctx, char *line)
 {
@@ -2684,6 +2766,54 @@ cmd_getinfo (assuan_context_t ctx, char *line)
       const char *s = VERSION;
       rc = assuan_send_data (ctx, s, strlen (s));
     }
+  else if (!strncmp (line, "cmd_has_option", 14)
+           && (line[14] == ' ' || line[14] == '\t' || !line[14]))
+    {
+      char *cmd, *cmdopt;
+      line += 14;
+      while (*line == ' ' || *line == '\t')
+        line++;
+      if (!*line)
+        rc = gpg_error (GPG_ERR_MISSING_VALUE);
+      else
+        {
+          cmd = line;
+          while (*line && (*line != ' ' && *line != '\t'))
+            line++;
+          if (!*line)
+            rc = gpg_error (GPG_ERR_MISSING_VALUE);
+          else
+            {
+              *line++ = 0;
+              while (*line == ' ' || *line == '\t')
+                line++;
+              if (!*line)
+                rc = gpg_error (GPG_ERR_MISSING_VALUE);
+              else
+                {
+                  cmdopt = line;
+                  if (!command_has_option (cmd, cmdopt))
+                    rc = gpg_error (GPG_ERR_GENERAL);
+                }
+            }
+        }
+    }
+  else if (!strcmp (line, "s2k_count"))
+    {
+      char numbuf[50];
+
+      snprintf (numbuf, sizeof numbuf, "%lu", get_standard_s2k_count ());
+      rc = assuan_send_data (ctx, numbuf, strlen (numbuf));
+    }
+  else if (!strcmp (line, "restricted"))
+    {
+      rc = ctrl->restricted? 0 : gpg_error (GPG_ERR_GENERAL);
+    }
+  else if (ctrl->restricted)
+    {
+      rc = gpg_error (GPG_ERR_FORBIDDEN);
+    }
+  /* All sub-commands below are not allowed in restricted mode.  */
   else if (!strcmp (line, "pid"))
     {
       char numbuf[50];
@@ -2713,13 +2843,6 @@ cmd_getinfo (assuan_context_t ctx, char *line)
     {
       rc = agent_scd_check_running ()? 0 : gpg_error (GPG_ERR_GENERAL);
     }
-  else if (!strcmp (line, "s2k_count"))
-    {
-      char numbuf[50];
-
-      snprintf (numbuf, sizeof numbuf, "%lu", get_standard_s2k_count ());
-      rc = assuan_send_data (ctx, numbuf, strlen (numbuf));
-    }
   else if (!strcmp (line, "std_session_env")
            || !strcmp (line, "std_startup_env"))
     {
@@ -2748,38 +2871,6 @@ cmd_getinfo (assuan_context_t ctx, char *line)
             }
         }
     }
-  else if (!strncmp (line, "cmd_has_option", 14)
-           && (line[14] == ' ' || line[14] == '\t' || !line[14]))
-    {
-      char *cmd, *cmdopt;
-      line += 14;
-      while (*line == ' ' || *line == '\t')
-        line++;
-      if (!*line)
-        rc = gpg_error (GPG_ERR_MISSING_VALUE);
-      else
-        {
-          cmd = line;
-          while (*line && (*line != ' ' && *line != '\t'))
-            line++;
-          if (!*line)
-            rc = gpg_error (GPG_ERR_MISSING_VALUE);
-          else
-            {
-              *line++ = 0;
-              while (*line == ' ' || *line == '\t')
-                line++;
-              if (!*line)
-                rc = gpg_error (GPG_ERR_MISSING_VALUE);
-              else
-                {
-                  cmdopt = line;
-                  if (!command_has_option (cmd, cmdopt))
-                    rc = gpg_error (GPG_ERR_GENERAL);
-                }
-            }
-        }
-    }
   else
     rc = set_error (GPG_ERR_ASS_PARAMETER, "unknown value for WHAT");
   return rc;
@@ -2802,6 +2893,11 @@ option_handler (assuan_context_t ctx, const char *key, const char *value)
       ctrl->server_local->allow_fully_canceled =
         gnupg_compare_version (value, "2.1.0");
     }
+  else if (ctrl->restricted)
+    {
+      err = gpg_error (GPG_ERR_FORBIDDEN);
+    }
+  /* All options below are not allowed in restricted mode.  */
   else if (!strcmp (key, "putenv"))
     {
       /* Change the session's environment to be used for the
diff --git a/agent/gpg-agent.c b/agent/gpg-agent.c
index 23d6ee2..e001ad1 100644
--- a/agent/gpg-agent.c
+++ b/agent/gpg-agent.c
@@ -111,6 +111,7 @@ enum cmd_and_opt_values
   oEnablePassphraseHistory,
   oUseStandardSocket,
   oNoUseStandardSocket,
+  oExtraSocket,
   oFakedSystemTime,
 
   oIgnoreCacheForSigning,
@@ -209,6 +210,7 @@ static ARGPARSE_OPTS opts[] = {
                 /* */           "@"
 #endif
                 ),
+  ARGPARSE_s_s (oExtraSocket, "extra-socket", "@"),
 
   /* Dummy options for backward compatibility.  */
   ARGPARSE_o_s (oWriteEnvFile, "write-env-file", "@"),
@@ -280,12 +282,16 @@ static int maybe_setuid = 1;
 /* Name of the communication socket used for native gpg-agent requests.  */
 static char *socket_name;
 
+/* Name of the optional extra socket used for native gpg-agent requests.  */
+static char *socket_name_extra;
+
 /* Name of the communication socket used for ssh-agent-emulation.  */
 static char *socket_name_ssh;
 
 /* We need to keep track of the server's nonces (these are dummies for
    POSIX systems). */
 static assuan_sock_nonce_t socket_nonce;
+static assuan_sock_nonce_t socket_nonce_extra;
 static assuan_sock_nonce_t socket_nonce_ssh;
 
 
@@ -320,8 +326,8 @@ static int active_connections;
    Local prototypes.
  */
 
-static char *create_socket_name (char *standard_name);
-static gnupg_fd_t create_server_socket (char *name, int is_ssh,
+static char *create_socket_name (char *standard_name, int with_homedir);
+static gnupg_fd_t create_server_socket (char *name, int primary,
                                         assuan_sock_nonce_t *nonce);
 static void create_directories (void);
 
@@ -329,6 +335,7 @@ static void agent_init_default_ctrl (ctrl_t ctrl);
 static void agent_deinit_default_ctrl (ctrl_t ctrl);
 
 static void handle_connections (gnupg_fd_t listen_fd,
+                                gnupg_fd_t listen_fd_extra,
                                 gnupg_fd_t listen_fd_ssh);
 static void check_own_socket (void);
 static int check_for_running_agent (int silent);
@@ -498,6 +505,8 @@ cleanup (void)
   done = 1;
   deinitialize_module_cache ();
   remove_socket (socket_name);
+  if (opt.extra_socket > 1)
+    remove_socket (socket_name_extra);
   remove_socket (socket_name_ssh);
 }
 
@@ -860,6 +869,11 @@ main (int argc, char **argv )
 #        endif
           break;
 
+        case oExtraSocket:
+          opt.extra_socket = 1;  /* (1 = points into argv)  */
+          socket_name_extra = pargs.r.ret_str;
+          break;
+
         case oDebugQuickRandom:
           /* Only used by the first stage command line parser.  */
           break;
@@ -1067,7 +1081,8 @@ main (int argc, char **argv )
   else
     { /* Regular server mode */
       gnupg_fd_t fd;
-      gnupg_fd_t fd_ssh;
+      gnupg_fd_t fd_extra = GNUPG_INVALID_FD;
+      gnupg_fd_t fd_ssh = GNUPG_INVALID_FD;
       pid_t pid;
 
       /* Remove the DISPLAY variable so that a pinentry does not
@@ -1081,17 +1096,23 @@ main (int argc, char **argv )
         gnupg_unsetenv ("DISPLAY");
 #endif
 
-
       /* Create the sockets.  */
-      socket_name = create_socket_name (GPG_AGENT_SOCK_NAME);
-      fd = create_server_socket (socket_name, 0, &socket_nonce);
+      socket_name = create_socket_name (GPG_AGENT_SOCK_NAME, 1);
+      fd = create_server_socket (socket_name, 1, &socket_nonce);
+
+      if (opt.extra_socket)
+        {
+          socket_name_extra = create_socket_name (socket_name_extra, 0);
+          opt.extra_socket = 2; /* Indicate that it has been malloced.  */
+          fd_extra = create_server_socket (socket_name_extra, 0,
+                                           &socket_nonce_extra);
+        }
+
       if (opt.ssh_support)
         {
-          socket_name_ssh = create_socket_name (GPG_AGENT_SSH_SOCK_NAME);
-          fd_ssh = create_server_socket (socket_name_ssh, 1, &socket_nonce_ssh);
+          socket_name_ssh = create_socket_name (GPG_AGENT_SSH_SOCK_NAME, 1);
+          fd_ssh = create_server_socket (socket_name_ssh, 0, &socket_nonce_ssh);
         }
-      else
-	fd_ssh = GNUPG_INVALID_FD;
 
       /* If we are going to exec a program in the parent, we record
          the PID, so that the child may check whether the program is
@@ -1154,6 +1175,8 @@ main (int argc, char **argv )
 
           *socket_name = 0; /* Don't let cleanup() remove the socket -
                                the child should do this from now on */
+	  if (opt.extra_socket)
+	    *socket_name_extra = 0;
 	  if (opt.ssh_support)
 	    *socket_name_ssh = 0;
 
@@ -1264,7 +1287,7 @@ main (int argc, char **argv )
 #endif /*!HAVE_W32_SYSTEM*/
 
       log_info ("%s %s started\n", strusage(11), strusage(13) );
-      handle_connections (fd, opt.ssh_support ? fd_ssh : GNUPG_INVALID_FD);
+      handle_connections (fd, fd_extra, fd_ssh);
       assuan_sock_close (fd);
     }
 
@@ -1304,7 +1327,7 @@ agent_exit (int rc)
    structure usually identified by an argument named CTRL.  This
    function is called immediately after allocating the control
    structure.  Its purpose is to setup the default values for that
-   structure.  */
+   structure.  Note that some values may have already been set.  */
 static void
 agent_init_default_ctrl (ctrl_t ctrl)
 {
@@ -1463,11 +1486,14 @@ get_agent_scd_notify_event (void)
    Pointer to an allocated string with the absolute name of the socket
    used.  */
 static char *
-create_socket_name (char *standard_name)
+create_socket_name (char *standard_name, int with_homedir)
 {
   char *name;
 
-  name = make_filename (opt.homedir, standard_name, NULL);
+  if (with_homedir)
+    name = make_filename (opt.homedir, standard_name, NULL);
+  else
+    name = make_filename (standard_name, NULL);
   if (strchr (name, PATHSEP_C))
     {
       log_error (("'%s' are not allowed in the socket name\n"), PATHSEP_S);
@@ -1484,11 +1510,11 @@ create_socket_name (char *standard_name)
 
 
 /* Create a Unix domain socket with NAME.  Returns the file descriptor
-   or terminates the process in case of an error.  Not that this
-   function needs to be used for the regular socket first and only
-   then for the ssh socket.  */
+   or terminates the process in case of an error.  Note that this
+   function needs to be used for the regular socket first (indicated
+   by PRIMARY) and only then for the extra and the ssh sockets.  */
 static gnupg_fd_t
-create_server_socket (char *name, int is_ssh, assuan_sock_nonce_t *nonce)
+create_server_socket (char *name, int primary, assuan_sock_nonce_t *nonce)
 {
   struct sockaddr_un *serv_addr;
   socklen_t len;
@@ -1531,7 +1557,7 @@ create_server_socket (char *name, int is_ssh, assuan_sock_nonce_t *nonce)
          know the new Assuan socket, the Assuan server and thus the
          ssh-agent server is not yet operational.  This would lead to
          a hang.  */
-      if (!is_ssh && !check_for_running_agent (1))
+      if (primary && !check_for_running_agent (1))
         {
           log_set_prefix (NULL, JNLIB_LOG_WITH_PREFIX);
           log_set_file (NULL);
@@ -1980,12 +2006,9 @@ putty_message_thread (void *arg)
 #endif /*HAVE_W32_SYSTEM*/
 
 
-/* This is the standard connection thread's main function.  */
 static void *
-start_connection_thread (void *arg)
+start_connection_thread (ctrl_t ctrl)
 {
-  ctrl_t ctrl = arg;
-
   if (check_nonce (ctrl, &socket_nonce))
     {
       log_error ("handler 0x%lx nonce check FAILED\n",
@@ -2009,6 +2032,27 @@ start_connection_thread (void *arg)
 }
 
 
+/* This is the standard connection thread's main function.  */
+static void *
+start_connection_thread_std (void *arg)
+{
+  ctrl_t ctrl = arg;
+
+  return start_connection_thread (ctrl);
+}
+
+
+/* This is the extra socket connection thread's main function.  */
+static void *
+start_connection_thread_extra (void *arg)
+{
+  ctrl_t ctrl = arg;
+
+  ctrl->restricted = 1;
+  return start_connection_thread (ctrl);
+}
+
+
 /* This is the ssh connection thread's main function.  */
 static void *
 start_connection_thread_ssh (void *arg)
@@ -2037,7 +2081,9 @@ start_connection_thread_ssh (void *arg)
 /* Connection handler loop.  Wait for connection requests and spawn a
    thread after accepting a connection.  */
 static void
-handle_connections (gnupg_fd_t listen_fd, gnupg_fd_t listen_fd_ssh)
+handle_connections (gnupg_fd_t listen_fd,
+                    gnupg_fd_t listen_fd_extra,
+                    gnupg_fd_t listen_fd_ssh)
 {
   npth_attr_t tattr;
   struct sockaddr_un paddr;
@@ -2054,6 +2100,16 @@ handle_connections (gnupg_fd_t listen_fd, gnupg_fd_t listen_fd_ssh)
   HANDLE events[2];
   unsigned int events_set;
 #endif
+  struct {
+    const char *name;
+    void *(*func) (void *arg);
+    gnupg_fd_t l_fd;
+  } listentbl[] = {
+    { "std",  start_connection_thread_std   },
+    { "extra",start_connection_thread_extra },
+    { "ssh",  start_connection_thread_ssh   }
+  };
+
 
   ret = npth_attr_init(&tattr);
   if (ret)
@@ -2103,6 +2159,12 @@ handle_connections (gnupg_fd_t listen_fd, gnupg_fd_t listen_fd_ssh)
   FD_ZERO (&fdset);
   FD_SET (FD2INT (listen_fd), &fdset);
   nfd = FD2INT (listen_fd);
+  if (listen_fd_extra != GNUPG_INVALID_FD)
+    {
+      FD_SET ( FD2INT(listen_fd_extra), &fdset);
+      if (FD2INT (listen_fd_extra) > nfd)
+        nfd = FD2INT (listen_fd_extra);
+    }
   if (listen_fd_ssh != GNUPG_INVALID_FD)
     {
       FD_SET ( FD2INT(listen_fd_ssh), &fdset);
@@ -2110,6 +2172,10 @@ handle_connections (gnupg_fd_t listen_fd, gnupg_fd_t listen_fd_ssh)
         nfd = FD2INT (listen_fd_ssh);
     }
 
+  listentbl[0].l_fd = listen_fd;
+  listentbl[1].l_fd = listen_fd_extra;
+  listentbl[2].l_fd = listen_fd_ssh;
+
   npth_clock_gettime (&abstime);
   abstime.tv_sec += TIMERTICK_INTERVAL;
 
@@ -2172,92 +2238,56 @@ handle_connections (gnupg_fd_t listen_fd, gnupg_fd_t listen_fd_ssh)
 	   next timeout.  */
 	continue;
 
-      if (!shutdown_pending && FD_ISSET (FD2INT (listen_fd), &read_fdset))
-	{
+      if (!shutdown_pending)
+        {
+          int idx;
           ctrl_t ctrl;
+          npth_t thread;
 
-          plen = sizeof paddr;
-	  fd = INT2FD (npth_accept (FD2INT(listen_fd),
-				    (struct sockaddr *)&paddr, &plen));
-	  if (fd == GNUPG_INVALID_FD)
-	    {
-	      log_error ("accept failed: %s\n", strerror (errno));
-	    }
-          else if ( !(ctrl = xtrycalloc (1, sizeof *ctrl)) )
-            {
-              log_error ("error allocating connection control data: %s\n",
-                         strerror (errno) );
-              assuan_sock_close (fd);
-            }
-          else if ( !(ctrl->session_env = session_env_new ()) )
+          for (idx=0; idx < DIM(listentbl); idx++)
             {
-              log_error ("error allocating session environment block: %s\n",
-                         strerror (errno) );
-              xfree (ctrl);
-              assuan_sock_close (fd);
-            }
-          else
-            {
-	      npth_t thread;
-
-              ctrl->thread_startup.fd = fd;
-	      ret = npth_create (&thread, &tattr,
-                                 start_connection_thread, ctrl);
-              if (ret)
+              if (listentbl[idx].l_fd == GNUPG_INVALID_FD)
+                continue;
+              if (!FD_ISSET (FD2INT (listentbl[idx].l_fd), &read_fdset))
+                continue;
+
+              plen = sizeof paddr;
+              fd = INT2FD (npth_accept (FD2INT(listentbl[idx].l_fd),
+                                        (struct sockaddr *)&paddr, &plen));
+              if (fd == GNUPG_INVALID_FD)
                 {
-                  log_error ("error spawning connection handler: %s\n",
-			     strerror (ret));
-                  assuan_sock_close (fd);
-                  xfree (ctrl);
+                  log_error ("accept failed for %s: %s\n",
+                             listentbl[idx].name, strerror (errno));
                 }
-
-            }
-          fd = GNUPG_INVALID_FD;
-	}
-
-      if (!shutdown_pending && listen_fd_ssh != GNUPG_INVALID_FD
-          && FD_ISSET ( FD2INT (listen_fd_ssh), &read_fdset))
-	{
-          ctrl_t ctrl;
-
-          plen = sizeof paddr;
-	  fd = INT2FD(npth_accept (FD2INT(listen_fd_ssh),
-				   (struct sockaddr *)&paddr, &plen));
-	  if (fd == GNUPG_INVALID_FD)
-	    {
-	      log_error ("accept failed for ssh: %s\n", strerror (errno));
-	    }
-          else if ( !(ctrl = xtrycalloc (1, sizeof *ctrl)) )
-            {
-              log_error ("error allocating connection control data: %s\n",
-                         strerror (errno) );
-              assuan_sock_close (fd);
-            }
-          else if ( !(ctrl->session_env = session_env_new ()) )
-            {
-              log_error ("error allocating session environment block: %s\n",
-                         strerror (errno) );
-              xfree (ctrl);
-              assuan_sock_close (fd);
-            }
-          else
-            {
-	      npth_t thread;
-
-              agent_init_default_ctrl (ctrl);
-              ctrl->thread_startup.fd = fd;
-              ret = npth_create (&thread, &tattr,
-                                 start_connection_thread_ssh, ctrl);
-	      if (ret)
+              else if ( !(ctrl = xtrycalloc (1, sizeof *ctrl)))
                 {
-                  log_error ("error spawning ssh connection handler: %s\n",
-			     strerror (ret));
+                  log_error ("error allocating connection data for %s: %s\n",
+                             listentbl[idx].name, strerror (errno) );
                   assuan_sock_close (fd);
+                }
+              else if ( !(ctrl->session_env = session_env_new ()))
+                {
+                  log_error ("error allocating session env block for %s: %s\n",
+                             listentbl[idx].name, strerror (errno) );
                   xfree (ctrl);
+                  assuan_sock_close (fd);
+                }
+              else
+                {
+                  ctrl->thread_startup.fd = fd;
+                  ret = npth_create (&thread, &tattr,
+                                     listentbl[idx].func, ctrl);
+                  if (ret)
+                    {
+                      log_error ("error spawning connection handler for %s:"
+                                 " %s\n", listentbl[idx].name, strerror (ret));
+                      assuan_sock_close (fd);
+                      xfree (ctrl);
+                    }
                 }
+              fd = GNUPG_INVALID_FD;
             }
-          fd = GNUPG_INVALID_FD;
-	}
+        }
     }
 
   cleanup ();
diff --git a/common/asshelp.c b/common/asshelp.c
index e675fda..51ef172 100644
--- a/common/asshelp.c
+++ b/common/asshelp.c
@@ -504,9 +504,23 @@ start_new_gpg_agent (assuan_context_t *r_ctx,
   err = assuan_transact (ctx, "RESET",
                          NULL, NULL, NULL, NULL, NULL, NULL);
   if (!err)
-    err = send_pinentry_environment (ctx, errsource,
-                                     opt_lc_ctype, opt_lc_messages,
-                                     session_env);
+    {
+      err = send_pinentry_environment (ctx, errsource,
+                                       opt_lc_ctype, opt_lc_messages,
+                                       session_env);
+      if (gpg_err_code (err) == GPG_ERR_FORBIDDEN
+          && gpg_err_source (err) == GPG_ERR_SOURCE_GPGAGENT)
+        {
+          /* Check whether we are in restricted mode.  */
+          if (!assuan_transact (ctx, "GETINFO restricted",
+                                NULL, NULL, NULL, NULL, NULL, NULL))
+            {
+              if (verbose)
+                log_info (_("connection to agent is in restricted mode\n"));
+              err = 0;
+            }
+        }
+    }
   if (err)
     {
       assuan_release (ctx);
diff --git a/common/util.h b/common/util.h
index dd5fdb1..a6f8606 100644
--- a/common/util.h
+++ b/common/util.h
@@ -35,6 +35,12 @@
 #include <errno.h>  /* We need errno.  */
 #include <gpg-error.h> /* We need gpg_error_t and estream. */
 
+/* These error codes are used but not defined in the required
+   libgpg-error version.  Define them here. */
+#if GPG_ERROR_VERSION_NUMBER < 0x011200  /* 1.18 */
+# define GPG_ERR_FORBIDDEN    251
+#endif
+
 
 /* Hash function used with libksba. */
 #define HASH_FNC ((void (*)(void *, const void*,size_t))gcry_md_write)
diff --git a/doc/gpg-agent.texi b/doc/gpg-agent.texi
index a4079d7..7523043 100644
--- a/doc/gpg-agent.texi
+++ b/doc/gpg-agent.texi
@@ -532,6 +532,19 @@ Ignore requests to change the current @code{tty} or X window system's
 @code{DISPLAY} variable respectively.  This is useful to lock the
 pinentry to pop up at the @code{tty} or display you started the agent.
 
+
+ at anchor{option --extra-socket}
+ at item --extra-socket @var{name}
+ at opindex extra-socket
+Also listen on native gpg-agent connections on the given socket.  The
+intended use for this extra socket is to setup a Unix domain socket
+forwarding from a remote machine to this socket on the local machine.
+A @command{gpg} running on the remote machine may then connect to the
+local gpg-agent and use its private keys.  This allows to decrypt or
+sign data on a remote machine without exposing the private keys to the
+remote machine.
+
+
 @anchor{option --enable-ssh-support}
 @item --enable-ssh-support
 @opindex enable-ssh-support

commit ccee34736b57a42ec4bdcb0d3181bdc6a08b0fff
Author: Мирослав Николић <wk at gnupg.org>
Date:   Thu Nov 27 17:28:00 2014 +0100

    agent: Make auditing of the option list easier.
    
    * agent/gpg-agent.c (opts): Use ARGPARSE_ macros.

diff --git a/agent/gpg-agent.c b/agent/gpg-agent.c
index 5960fe3..23d6ee2 100644
--- a/agent/gpg-agent.c
+++ b/agent/gpg-agent.c
@@ -131,83 +131,91 @@ enum cmd_and_opt_values
 
 static ARGPARSE_OPTS opts[] = {
 
-  { aGPGConfList, "gpgconf-list", 256, "@" },
-  { aGPGConfTest, "gpgconf-test", 256, "@" },
-  { aUseStandardSocketP, "use-standard-socket-p", 256, "@" },
-
-  { 301, NULL, 0, N_("@Options:\n ") },
-
-  { oDaemon,   "daemon",     0, N_("run in daemon mode (background)") },
-  { oServer,   "server",     0, N_("run in server mode (foreground)") },
-  { oVerbose, "verbose",     0, N_("verbose") },
-  { oQuiet,	"quiet",     0, N_("be somewhat more quiet") },
-  { oSh,	"sh",        0, N_("sh-style command output") },
-  { oCsh,	"csh",       0, N_("csh-style command output") },
-  { oOptions, "options"  , 2, N_("|FILE|read options from FILE")},
-  { oDebug,	"debug"     ,4|16, "@"},
-  { oDebugAll, "debug-all"     ,0, "@"},
-  { oDebugLevel, "debug-level" ,2, "@"},
-  { oDebugWait,"debug-wait",1, "@"},
+  ARGPARSE_c (aGPGConfList, "gpgconf-list", "@"),
+  ARGPARSE_c (aGPGConfTest, "gpgconf-test", "@"),
+  ARGPARSE_c (aUseStandardSocketP, "use-standard-socket-p", "@"),
+
+  ARGPARSE_group (301, N_("@Options:\n ")),
+
+  ARGPARSE_s_n (oDaemon,  "daemon", N_("run in daemon mode (background)")),
+  ARGPARSE_s_n (oServer,  "server", N_("run in server mode (foreground)")),
+  ARGPARSE_s_n (oVerbose, "verbose", N_("verbose")),
+  ARGPARSE_s_n (oQuiet,	  "quiet",     N_("be somewhat more quiet")),
+  ARGPARSE_s_n (oSh,	  "sh",        N_("sh-style command output")),
+  ARGPARSE_s_n (oCsh,	  "csh",       N_("csh-style command output")),
+  ARGPARSE_s_s (oOptions, "options", N_("|FILE|read options from FILE")),
+
+  ARGPARSE_s_u (oDebug,	     "debug",       "@"),
+  ARGPARSE_s_n (oDebugAll,   "debug-all",   "@"),
+  ARGPARSE_s_s (oDebugLevel, "debug-level", "@"),
+  ARGPARSE_s_i (oDebugWait,"  debug-wait",  "@"),
   ARGPARSE_s_n (oDebugQuickRandom, "debug-quick-random", "@"),
-  { oNoDetach, "no-detach" ,0, N_("do not detach from the console")},
-  { oNoGrab, "no-grab"     ,0, N_("do not grab keyboard and mouse")},
-  { oLogFile, "log-file"   ,2, N_("use a log file for the server")},
-  { oUseStandardSocket, "use-standard-socket", 0, "@"},      /* dummy */
-  { oNoUseStandardSocket, "no-use-standard-socket", 0, "@"}, /* dummy */
-  { oPinentryProgram, "pinentry-program", 2 ,
-                               N_("|PGM|use PGM as the PIN-Entry program") },
-  { oPinentryTouchFile, "pinentry-touch-file", 2 , "@" },
-  { oScdaemonProgram, "scdaemon-program", 2 ,
-                               N_("|PGM|use PGM as the SCdaemon program") },
-  { oDisableScdaemon, "disable-scdaemon", 0, N_("do not use the SCdaemon") },
-  { oDisableCheckOwnSocket, "disable-check-own-socket", 0, "@" },
-  { oFakedSystemTime, "faked-system-time", 2, "@" }, /* (epoch time) */
-
-  { oBatch,      "batch",       0, "@" },
-  { oHomedir,    "homedir",     2, "@"},
-
-  { oDisplay,    "display",     2, "@" },
-  { oTTYname,    "ttyname",     2, "@" },
-  { oTTYtype,    "ttytype",     2, "@" },
-  { oLCctype,    "lc-ctype",    2, "@" },
-  { oLCmessages, "lc-messages", 2, "@" },
-  { oXauthority, "xauthority",  2, "@" },
-  { oKeepTTY,    "keep-tty",    0,  N_("ignore requests to change the TTY")},
-  { oKeepDISPLAY, "keep-display",
-                          0, N_("ignore requests to change the X display")},
-
-  { oDefCacheTTL, "default-cache-ttl", 4,
-                               N_("|N|expire cached PINs after N seconds")},
-  { oDefCacheTTLSSH, "default-cache-ttl-ssh", 4, "@" },
-  { oMaxCacheTTL, "max-cache-ttl", 4, "@" },
-  { oMaxCacheTTLSSH, "max-cache-ttl-ssh", 4, "@" },
-
-  { oEnforcePassphraseConstraints, "enforce-passphrase-constraints", 0, "@"},
-  { oMinPassphraseLen, "min-passphrase-len", 4, "@" },
-  { oMinPassphraseNonalpha, "min-passphrase-nonalpha", 4, "@" },
-  { oCheckPassphrasePattern, "check-passphrase-pattern", 2, "@" },
-  { oMaxPassphraseDays, "max-passphrase-days", 4, "@" },
-  { oEnablePassphraseHistory, "enable-passphrase-history", 0, "@" },
-
-  { oIgnoreCacheForSigning, "ignore-cache-for-signing", 0,
-                               N_("do not use the PIN cache when signing")},
-  { oNoAllowMarkTrusted, "no-allow-mark-trusted", 0,
-                            N_("disallow clients to mark keys as \"trusted\"")},
-  { oAllowMarkTrusted, "allow-mark-trusted", 0, "@"},
-  { oAllowPresetPassphrase, "allow-preset-passphrase", 0,
-                             N_("allow presetting passphrase")},
-  { oAllowLoopbackPinentry, "allow-loopback-pinentry", 0,
-                             N_("allow presetting passphrase")},
-  { oSSHSupport, "enable-ssh-support", 0, N_("enable ssh support") },
-  { oPuttySupport, "enable-putty-support", 0,
+
+  ARGPARSE_s_n (oNoDetach,  "no-detach", N_("do not detach from the console")),
+  ARGPARSE_s_n (oNoGrab,    "no-grab",   N_("do not grab keyboard and mouse")),
+  ARGPARSE_s_s (oLogFile,   "log-file",  N_("use a log file for the server")),
+  ARGPARSE_s_s (oPinentryProgram, "pinentry-program",
+                /* */             N_("|PGM|use PGM as the PIN-Entry program")),
+  ARGPARSE_s_s (oPinentryTouchFile, "pinentry-touch-file", "@"),
+  ARGPARSE_s_s (oScdaemonProgram, "scdaemon-program",
+                /* */             N_("|PGM|use PGM as the SCdaemon program") ),
+  ARGPARSE_s_n (oDisableScdaemon, "disable-scdaemon",
+                /* */             N_("do not use the SCdaemon") ),
+  ARGPARSE_s_n (oDisableCheckOwnSocket, "disable-check-own-socket", "@"),
+  ARGPARSE_s_s (oFakedSystemTime, "faked-system-time", "@"),
+
+  ARGPARSE_s_n (oBatch,      "batch",        "@"),
+  ARGPARSE_s_s (oHomedir,    "homedir",      "@"),
+
+  ARGPARSE_s_s (oDisplay,    "display",     "@"),
+  ARGPARSE_s_s (oTTYname,    "ttyname",     "@"),
+  ARGPARSE_s_s (oTTYtype,    "ttytype",     "@"),
+  ARGPARSE_s_s (oLCctype,    "lc-ctype",    "@"),
+  ARGPARSE_s_s (oLCmessages, "lc-messages", "@"),
+  ARGPARSE_s_s (oXauthority, "xauthority",  "@"),
+  ARGPARSE_s_n (oKeepTTY,    "keep-tty",
+                /* */        N_("ignore requests to change the TTY")),
+  ARGPARSE_s_n (oKeepDISPLAY, "keep-display",
+                /* */        N_("ignore requests to change the X display")),
+
+  ARGPARSE_s_u (oDefCacheTTL,    "default-cache-ttl",
+                                 N_("|N|expire cached PINs after N seconds")),
+  ARGPARSE_s_u (oDefCacheTTLSSH, "default-cache-ttl-ssh", "@" ),
+  ARGPARSE_s_u (oMaxCacheTTL,    "max-cache-ttl",         "@" ),
+  ARGPARSE_s_u (oMaxCacheTTLSSH, "max-cache-ttl-ssh",     "@" ),
+
+  ARGPARSE_s_n (oEnforcePassphraseConstraints, "enforce-passphrase-constraints",
+                /* */                          "@"),
+  ARGPARSE_s_u (oMinPassphraseLen,        "min-passphrase-len", "@"),
+  ARGPARSE_s_u (oMinPassphraseNonalpha,   "min-passphrase-nonalpha", "@"),
+  ARGPARSE_s_s (oCheckPassphrasePattern,  "check-passphrase-pattern", "@"),
+  ARGPARSE_s_u (oMaxPassphraseDays,       "max-passphrase-days", "@"),
+  ARGPARSE_s_n (oEnablePassphraseHistory, "enable-passphrase-history", "@"),
+
+  ARGPARSE_s_n (oIgnoreCacheForSigning, "ignore-cache-for-signing",
+                /* */    N_("do not use the PIN cache when signing")),
+  ARGPARSE_s_n (oNoAllowMarkTrusted, "no-allow-mark-trusted",
+                /* */    N_("disallow clients to mark keys as \"trusted\"")),
+  ARGPARSE_s_n (oAllowMarkTrusted,   "allow-mark-trusted", "@"),
+  ARGPARSE_s_n (oAllowPresetPassphrase, "allow-preset-passphrase",
+                /* */                    N_("allow presetting passphrase")),
+  ARGPARSE_s_n (oAllowLoopbackPinentry, "allow-loopback-pinentry",
+                                        N_("allow presetting passphrase")),
+  ARGPARSE_s_n (oSSHSupport,   "enable-ssh-support", N_("enable ssh support")),
+  ARGPARSE_s_n (oPuttySupport, "enable-putty-support",
 #ifdef HAVE_W32_SYSTEM
-      N_("enable putty support")
+                /* */           N_("enable putty support")
 #else
-      "@"
+                /* */           "@"
 #endif
-  },
-  { oWriteEnvFile, "write-env-file", 2|8, "@" }, /* dummy */
-  {0}
+                ),
+
+  /* Dummy options for backward compatibility.  */
+  ARGPARSE_o_s (oWriteEnvFile, "write-env-file", "@"),
+  ARGPARSE_s_n (oUseStandardSocket, "use-standard-socket", "@"),
+  ARGPARSE_s_n (oNoUseStandardSocket, "no-use-standard-socket", "@"),
+
+  {0} /* End of list */
 };
 
 

commit 68a7ccc0c870cce6ab9fefb1aa6fd100e1de129b
Author: Kristian Fiskerstrand <kf at sumptuouscapital.com>
Date:   Tue Nov 25 19:24:18 2014 +0100

    dirmngr: Only report hkps scheme when available
    
    * dirmngr/ks-engine-hkp.c (ks_hkp_help): Make use of TLS macros.
    
    --
    Only report support for the hkps scheme when GnuPG / dirmngr
    has been built with a TLS library.
    
    This helps debuging and enable the user to detect whether support
    for hkps is included by doing a
    `gpg-connect-agent --dirmngr 'keyserver --help' /bye`.
    Currently hkps will be listed as a supported scheme but trying to
    add a keyserver using it will silently fail.
    
    As a digression, https is never listed as a valid scheme.

diff --git a/dirmngr/ks-engine-hkp.c b/dirmngr/ks-engine-hkp.c
index 12b1778..83e878a 100644
--- a/dirmngr/ks-engine-hkp.c
+++ b/dirmngr/ks-engine-hkp.c
@@ -767,12 +767,20 @@ ks_hkp_help (ctrl_t ctrl, parsed_uri_t uri)
   const char const data[] =
     "Handler for HKP URLs:\n"
     "  hkp://\n"
+#if  HTTP_USE_GNUTLS || HTTP_USE_NTBTLS
     "  hkps://\n"
+#endif
     "Supported methods: search, get, put\n";
   gpg_error_t err;
 
+#if  HTTP_USE_GNUTLS || HTTP_USE_NTBTLS
+  const char data2[] = "  hkp\n  hkps";
+#else
+  const char data2[] = "  hkp";
+#endif
+
   if (!uri)
-    err = ks_print_help (ctrl, "  hkp\n  hkps");
+    err = ks_print_help (ctrl, data2);
   else if (uri->is_http && (!strcmp (uri->scheme, "hkp")
                             || !strcmp (uri->scheme, "hkps")))
     err = ks_print_help (ctrl, data);

-----------------------------------------------------------------------

Summary of changes:
 agent/agent.h           |    8 +
 agent/command.c         |  180 ++++++++++++++++------
 agent/gpg-agent.c       |  384 ++++++++++++++++++++++++++---------------------
 common/asshelp.c        |   20 ++-
 common/util.h           |    6 +
 dirmngr/ks-engine-hkp.c |   10 +-
 doc/gpg-agent.texi      |   13 ++
 7 files changed, 402 insertions(+), 219 deletions(-)


hooks/post-receive
-- 
The GNU Privacy Guard
http://git.gnupg.org




More information about the Gnupg-commits mailing list