[git] GnuPG - branch, master, updated. gnupg-2.1.0-51-ge1f515b

by Werner Koch cvs at cvs.gnupg.org
Fri Nov 28 21:34:34 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  e1f515b19c7f63b6d0b0253319b9fc41dabed657 (commit)
      from  e59b1cc7471dd161a627b290c645ef7bd0d9d42c (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 e1f515b19c7f63b6d0b0253319b9fc41dabed657
Author: Werner Koch <wk at gnupg.org>
Date:   Fri Nov 28 21:34:35 2014 +0100

    agent: Implement socket redirection.
    
    * agent/gpg-agent.c (ENAMETOOLONG): New.
    (redir_socket_name, redir_socket_name_extra)
    (redir_socket_name_ssh): New.
    (remove_socket): Take care of the redir names.
    (main): Pass the redir names to create_server_socket.
    (create_socket_name): Remove length check - that is anyway done later.
    (create_server_socket): Add arg r_redir_name and implement redirection
    if Libassuan is at least 2.14.

diff --git a/agent/gpg-agent.c b/agent/gpg-agent.c
index e001ad1..3ad2c1d 100644
--- a/agent/gpg-agent.c
+++ b/agent/gpg-agent.c
@@ -129,6 +129,10 @@ enum cmd_and_opt_values
 };
 
 
+#ifndef ENAMETOOLONG
+# define ENAMETOOLONG EINVAL
+#endif
+
 
 static ARGPARSE_OPTS opts[] = {
 
@@ -279,14 +283,19 @@ static int disable_check_own_socket;
 /* It is possible that we are currently running under setuid permissions */
 static int maybe_setuid = 1;
 
-/* Name of the communication socket used for native gpg-agent requests.  */
+/* Name of the communication socket used for native gpg-agent
+   requests. The second variable is either NULL or a malloced string
+   with the real socket name in case it has been redirected.  */
 static char *socket_name;
+static char *redir_socket_name;
 
 /* Name of the optional extra socket used for native gpg-agent requests.  */
 static char *socket_name_extra;
+static char *redir_socket_name_extra;
 
 /* Name of the communication socket used for ssh-agent-emulation.  */
 static char *socket_name_ssh;
+static char *redir_socket_name_ssh;
 
 /* We need to keep track of the server's nonces (these are dummies for
    POSIX systems). */
@@ -328,6 +337,7 @@ static int active_connections;
 
 static char *create_socket_name (char *standard_name, int with_homedir);
 static gnupg_fd_t create_server_socket (char *name, int primary,
+                                        char **r_redir_name,
                                         assuan_sock_nonce_t *nonce);
 static void create_directories (void);
 
@@ -472,14 +482,18 @@ set_debug (void)
 }
 
 
-/* Helper for cleanup to remove one socket with NAME.  */
+/* Helper for cleanup to remove one socket with NAME.  REDIR_NAME is
+   the corresponding real name if the socket has been redirected.  */
 static void
-remove_socket (char *name)
+remove_socket (char *name, char *redir_name)
 {
   if (name && *name)
     {
       char *p;
 
+      if (redir_name)
+        name = redir_name;
+
       gnupg_remove (name);
       p = strrchr (name, '/');
       if (p)
@@ -504,10 +518,10 @@ cleanup (void)
     return;
   done = 1;
   deinitialize_module_cache ();
-  remove_socket (socket_name);
+  remove_socket (socket_name, redir_socket_name);
   if (opt.extra_socket > 1)
-    remove_socket (socket_name_extra);
-  remove_socket (socket_name_ssh);
+    remove_socket (socket_name_extra, redir_socket_name_extra);
+  remove_socket (socket_name_ssh, redir_socket_name_ssh);
 }
 
 
@@ -1098,20 +1112,24 @@ main (int argc, char **argv )
 
       /* Create the sockets.  */
       socket_name = create_socket_name (GPG_AGENT_SOCK_NAME, 1);
-      fd = create_server_socket (socket_name, 1, &socket_nonce);
+      fd = create_server_socket (socket_name, 1,
+                                 &redir_socket_name, &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,
+                                           &redir_socket_name_extra,
                                            &socket_nonce_extra);
         }
 
       if (opt.ssh_support)
         {
           socket_name_ssh = create_socket_name (GPG_AGENT_SSH_SOCK_NAME, 1);
-          fd_ssh = create_server_socket (socket_name_ssh, 0, &socket_nonce_ssh);
+          fd_ssh = create_server_socket (socket_name_ssh, 0,
+                                         &redir_socket_name_ssh,
+                                         &socket_nonce_ssh);
         }
 
       /* If we are going to exec a program in the parent, we record
@@ -1499,11 +1517,6 @@ create_socket_name (char *standard_name, int with_homedir)
       log_error (("'%s' are not allowed in the socket name\n"), PATHSEP_S);
       agent_exit (2);
     }
-  if (strlen (name) + 1 >= DIMof (struct sockaddr_un, sun_path) )
-    {
-      log_error (_("name of socket too long\n"));
-      agent_exit (2);
-    }
   return name;
 }
 
@@ -1512,33 +1525,69 @@ create_socket_name (char *standard_name, int with_homedir)
 /* Create a Unix domain socket with NAME.  Returns the file descriptor
    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.  */
+   by PRIMARY) and only then for the extra and the ssh sockets.  if
+   the soecket has been redirected the name of the real socket is
+   stored as a malloced string at R_REDIR_NAME.  */
 static gnupg_fd_t
-create_server_socket (char *name, int primary, assuan_sock_nonce_t *nonce)
+create_server_socket (char *name, int primary,
+                      char **r_redir_name, assuan_sock_nonce_t *nonce)
 {
-  struct sockaddr_un *serv_addr;
+  struct sockaddr *addr;
+  struct sockaddr_un *unaddr;
   socklen_t len;
   gnupg_fd_t fd;
   int rc;
 
+  xfree (*r_redir_name);
+  *r_redir_name = NULL;
+
   fd = assuan_sock_new (AF_UNIX, SOCK_STREAM, 0);
   if (fd == ASSUAN_INVALID_FD)
     {
       log_error (_("can't create socket: %s\n"), strerror (errno));
+      *name = 0; /* Inhibit removal of the socket by cleanup(). */
       agent_exit (2);
     }
 
-  serv_addr = xmalloc (sizeof (*serv_addr));
-  memset (serv_addr, 0, sizeof *serv_addr);
-  serv_addr->sun_family = AF_UNIX;
-  if (strlen (name) + 1 >= sizeof (serv_addr->sun_path))
+  unaddr = xmalloc (sizeof *unaddr);
+  addr = (struct sockaddr*)unaddr;
+
+#if ASSUAN_VERSION_NUMBER >= 0x020104 /* >= 2.1.4 */
+  {
+    int redirected;
+
+    if (assuan_sock_set_sockaddr_un (name, addr, &redirected))
+      {
+        if (errno == ENAMETOOLONG)
+          log_error (_("socket name '%s' is too long\n"), name);
+        else
+          log_error ("error preparing socket '%s': %s\n",
+                     name, gpg_strerror (gpg_error_from_syserror ()));
+        *name = 0; /* Inhibit removal of the socket by cleanup(). */
+        agent_exit (2);
+      }
+    if (redirected)
+      {
+        *r_redir_name = xstrdup (unaddr->sun_path);
+        if (opt.verbose)
+          log_info ("redirecting socket '%s' to '%s'\n", name, *r_redir_name);
+      }
+  }
+#else /* Assuan < 2.1.4 */
+  redirected = 0;
+  memset (unaddr, 0, sizeof *unaddr);
+  unaddr->sun_family = AF_UNIX;
+  if (strlen (name) + 1 >= sizeof (unaddr->sun_path))
     {
       log_error (_("socket name '%s' is too long\n"), name);
+      *name = 0; /* Inhibit removal of the socket by cleanup(). */
       agent_exit (2);
     }
-  strcpy (serv_addr->sun_path, name);
-  len = SUN_LEN (serv_addr);
-  rc = assuan_sock_bind (fd, (struct sockaddr*) serv_addr, len);
+  strcpy (unaddr->sun_path, name);
+#endif /* Assuan < 2.1.4 */
+
+  len = SUN_LEN (unaddr);
+  rc = assuan_sock_bind (fd, addr, len);
 
   /* Our error code mapping on W32CE returns EEXIST thus we also test
      for this. */
@@ -1549,14 +1598,13 @@ create_server_socket (char *name, int primary, assuan_sock_nonce_t *nonce)
 #endif
           ))
     {
-      /* Check whether a gpg-agent is already running.
-         We do this test only if this is not the ssh socket.
-         For ssh we assume that a test for gpg-agent has already been
-         done and reuse the requested ssh socket.  Testing the
-         ssh-socket is not possible because at this point, though we
-         know the new Assuan socket, the Assuan server and thus the
-         ssh-agent server is not yet operational.  This would lead to
-         a hang.  */
+      /* Check whether a gpg-agent is already running.  We do this
+         test only if this is the primary socket.  For secondary
+         sockets we assume that a test for gpg-agent has already been
+         done and reuse the requested socket.  Testing the ssh-socket
+         is not possible because at this point, though we 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 (primary && !check_for_running_agent (1))
         {
           log_set_prefix (NULL, JNLIB_LOG_WITH_PREFIX);
@@ -1567,19 +1615,18 @@ create_server_socket (char *name, int primary, assuan_sock_nonce_t *nonce)
           assuan_sock_close (fd);
           agent_exit (2);
         }
-      gnupg_remove (name);
-      rc = assuan_sock_bind (fd, (struct sockaddr*) serv_addr, len);
+      gnupg_remove (unaddr->sun_path);
+      rc = assuan_sock_bind (fd, addr, len);
     }
-  if (rc != -1
-      && (rc=assuan_sock_get_nonce ((struct sockaddr*)serv_addr, len, nonce)))
+  if (rc != -1 && (rc=assuan_sock_get_nonce (addr, len, nonce)))
     log_error (_("error getting nonce for the socket\n"));
   if (rc == -1)
     {
       /* We use gpg_strerror here because it allows us to get strings
          for some W32 socket error codes.  */
       log_error (_("error binding socket to '%s': %s\n"),
-		 serv_addr->sun_path,
-                 gpg_strerror (gpg_error_from_errno (errno)));
+		 unaddr->sun_path,
+                 gpg_strerror (gpg_error_from_syserror ()));
 
       assuan_sock_close (fd);
       *name = 0; /* Inhibit removal of the socket by cleanup(). */
@@ -1589,12 +1636,13 @@ create_server_socket (char *name, int primary, assuan_sock_nonce_t *nonce)
   if (listen (FD2INT(fd), 5 ) == -1)
     {
       log_error (_("listen() failed: %s\n"), strerror (errno));
+      *name = 0; /* Inhibit removal of the socket by cleanup(). */
       assuan_sock_close (fd);
       agent_exit (2);
     }
 
   if (opt.verbose)
-    log_info (_("listening on socket '%s'\n"), serv_addr->sun_path);
+    log_info (_("listening on socket '%s'\n"), unaddr->sun_path);
 
   return fd;
 }

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

Summary of changes:
 agent/gpg-agent.c |  124 +++++++++++++++++++++++++++++++++++++----------------
 1 file changed, 86 insertions(+), 38 deletions(-)


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




More information about the Gnupg-commits mailing list