[git] Poldi - branch, master, updated. release-0.4.1-42-g83891ae

by NIIBE Yutaka cvs at cvs.gnupg.org
Fri Nov 11 09:52:06 CET 2016


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 "PAM for the OpenPGP card".

The branch, master has been updated
       via  83891ae71db2ba6f7d0e48db746fb5caaeba2c4b (commit)
       via  56b759da589bdfa3af31ed95839ba59f12e94fb7 (commit)
      from  16912be8d2685e82a3fe40e94912e90cbb73e47b (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 83891ae71db2ba6f7d0e48db746fb5caaeba2c4b
Author: NIIBE Yutaka <gniibe at fsij.org>
Date:   Fri Nov 11 17:51:36 2016 +0900

    Fix info entry of poldi.texi

diff --git a/doc/poldi.texi b/doc/poldi.texi
index 17fe3b9..f6b3d80 100644
--- a/doc/poldi.texi
+++ b/doc/poldi.texi
@@ -15,7 +15,7 @@
 
 @dircategory GNU Utilities
 @direntry
-* poldi: (poldi) PAM authentication via OpenPGP smartcards.
+* poldi: (poldi).	PAM authentication via OpenPGP smartcards.
 @end direntry
 
 @include version.texi

commit 56b759da589bdfa3af31ed95839ba59f12e94fb7
Author: NIIBE Yutaka <gniibe at fsij.org>
Date:   Fri Nov 11 17:50:12 2016 +0900

    Add "use-agent" PAM option.
    
    * configure.ac (GNUPG_DEFAULT_GPGCONF): New.
    * src/pam/pam_poldi.c (pam_poldi_options_cb): Support the option.
    (pam_sm_authenticate): Call scd_connect with use_agent option.
    * src/scd/scd.c (get_agent_socket_name): New.
    (agent_scd_getinfo_socket_name): Revert the change of removing this
    function.  Clean it up.
    (get_scd_socket_from_agent): New.
    (scd_connect): Clean up and support use_agent.
    --
    
    Using Poldi for su/sudo with gpg-agent is questionable usage.
    However, for backward compatibility, the feature is back.
    
    Signed-off-by: NIIBE Yutaka <gniibe at fsij.org>

diff --git a/NEWS b/NEWS
index a52f269..d3d8c46 100644
--- a/NEWS
+++ b/NEWS
@@ -5,15 +5,23 @@ Changes since version 0.4.1:
 * poldi-ctrl is removed
   Please use gpg-connect-agent instead.
 
-* Poldi always invokes scdaemon to connect it through pipe
+* New "use-agent" PAM option for backward compatibility
+  In GnuPG 2.1, the environment variable GPG_AGENT_INFO is gone.  And
+  now, Poldi's default is invoking scdaemon directly.  Still, there
+  are use cases (like su/sudo) which expect connecting user's
+  gpg-agent.  For this purpose, we now have "use-agent" option.  Don't
+  enable this option for login authentication.
+
+* Poldi invokes scdaemon to connect it through pipe
   Older Poldi has a feature of connecting to scdaemon with help of
   gpg-agent using the GPG_AGENT_INFO enviornment variable.  In GnuPG
-  2.1, the GPG_AGENT_INFO is gone and scdaemon no longer keeps locking
-  the reader after card removal, it is good to always invoke scdaemon
-  for the authentication.  If there is an existing scdaemon with card
-  inserted, a failure is expected and this is safer fallback.  That's
-  because Poldi should not connect to a smartcard which is in use for
-  other purpose and possibly already authenticated.
+  2.1, the environment variable GPG_AGENT_INFO is gone and scdaemon no
+  longer keeps locking the reader after card removal, it is good to
+  always invoke scdaemon for the authentication by default.  If there
+  is an existing scdaemon with card inserted, a failure is expected
+  and this is safer fallback.  That's because Poldi should not connect
+  to a smartcard which is in use for other purpose and possibly
+  already authenticated.
 
 * New option "scdaemon-options"
   Added a new option "scdaemon-options", which can be used to specify
diff --git a/configure.ac b/configure.ac
index 1886e2c..0aba308 100644
--- a/configure.ac
+++ b/configure.ac
@@ -68,6 +68,9 @@ AC_DEFINE_UNQUOTED(NEED_KSBA_VERSION, "$NEED_KSBA_VERSION",
 
 AH_BOTTOM([
 /* Setup the hardwired names of modules. */
+#ifndef GNUPG_DEFAULT_GPGCONF
+#define GNUPG_DEFAULT_GPGCONF    ( GNUPG_BINDIR "/gpgconf" )
+#endif
 #ifndef GNUPG_DEFAULT_SCD
 #define GNUPG_DEFAULT_SCD    ( GNUPG_LIBEXECDIR "/scdaemon" )
 #endif
diff --git a/src/pam/auth-support/ctx.h b/src/pam/auth-support/ctx.h
index 98f1034..3de2407 100644
--- a/src/pam/auth-support/ctx.h
+++ b/src/pam/auth-support/ctx.h
@@ -67,6 +67,7 @@ struct poldi_ctx_s
 				   PAM environment.  */
   int quiet;			/* Be more quiet during PAM
 				   conversation with user. */
+  int use_agent;		/* Use gpg-agent to connect scdaemon.  */
 
   /* Scdaemon. */
   char *scdaemon_program;	/* Path of Scdaemon program to execute.  */
diff --git a/src/pam/pam_poldi.c b/src/pam/pam_poldi.c
index 6ed3cc4..a27a3e9 100644
--- a/src/pam/pam_poldi.c
+++ b/src/pam/pam_poldi.c
@@ -84,7 +84,8 @@ enum opt_ids
     opt_scdaemon_program,
     opt_scdaemon_options,
     opt_modify_environment,
-    opt_quiet
+    opt_quiet,
+    opt_use_agent,
   };
 
 /* Full specifications for options. */
@@ -104,6 +105,8 @@ static simpleparse_opt_spec_t opt_specs[] =
       0, SIMPLEPARSE_ARG_NONE, 0, "Set Poldi related variables in the PAM environment" },
     { opt_quiet, "quiet",
       0, SIMPLEPARSE_ARG_NONE, 0, "Be more quiet during PAM conversation with user" },
+    { opt_use_agent, "use-agent",
+      0, SIMPLEPARSE_ARG_NONE, 0, "Use gpg-agent for scdaemon" },
     { 0 }
   };
 
@@ -202,6 +205,10 @@ pam_poldi_options_cb (void *cookie, simpleparse_opt_spec_t spec, const char *arg
       /* QUIET.  */
       ctx->quiet = 1;
     }
+  else if (!strcmp (spec.long_opt, "use-agent"))
+    {
+      ctx->use_agent = 1;
+    }
 
   return gpg_error (err);
 }
@@ -549,7 +556,8 @@ pam_sm_authenticate (pam_handle_t *pam_handle,
 
   /*** Connect to Scdaemon. ***/
 
-  err = scd_connect (&scd_ctx, ctx->scdaemon_program, ctx->scdaemon_options,
+  err = scd_connect (&scd_ctx, ctx->use_agent,
+		     ctx->scdaemon_program, ctx->scdaemon_options,
 		     ctx->loghandle);
   if (err)
     goto out;
diff --git a/src/scd/scd.c b/src/scd/scd.c
index a565f78..06a26d8 100644
--- a/src/scd/scd.c
+++ b/src/scd/scd.c
@@ -94,6 +94,111 @@ static gpg_error_t scd_serialno_internal (assuan_context_t ctx,
 					  char **r_serialno);
 
 

+
+/* Get the socket of GPG-AGENT by gpgconf. */
+static gpg_error_t
+get_agent_socket_name (char **gpg_agent_sockname)
+{
+  gpg_error_t err = 0;
+  FILE *input;
+  char *result;
+  size_t len;
+
+  *gpg_agent_sockname = NULL;
+
+  result = xtrymalloc (256);
+  if (!result)
+    return gpg_error_from_syserror ();
+
+  input = popen ("gpgconf --list-dirs agent-socket", "r");
+  if (input == NULL)
+    {
+      xfree (result);
+      return gpg_error (GPG_ERR_NOT_FOUND);
+    }
+
+  len = fread (result, 1, 256, input);
+  fclose (input);
+
+  if (len)
+    {
+      *gpg_agent_sockname = result;
+      result[len-1] = 0;	/* Chop off the newline.  */
+    }
+  else
+    {
+      xfree (result);
+      err =  gpg_error (GPG_ERR_NOT_FOUND);
+    }
+
+  return err;
+}
+
+/* Helper function for get_scd_socket_from_agent(), which is used by
+   scd_connect().
+
+   Try to retrieve the SCDaemons socket name from the gpg-agent
+   context CTX.  On success, *SOCKET_NAME is filled with a copy ot the
+   socket name.  Return proper error code or zero on success. */
+static gpg_error_t
+agent_scd_getinfo_socket_name (assuan_context_t ctx, char **socket_name)
+{
+  membuf_t data;
+  gpg_error_t err = 0;
+  unsigned char *databuf;
+  size_t datalen;
+
+  init_membuf (&data, 256);
+  *socket_name = NULL;
+
+  err = assuan_transact (ctx, "SCD GETINFO socket_name", membuf_data_cb, &data,
+			 NULL, NULL, NULL, NULL);
+  databuf = get_membuf (&data, &datalen);
+  if (!err)
+    {
+      if (databuf && datalen)
+	{
+	  char *res = xtrymalloc (datalen + 1);
+	  if (!res)
+	    err = gpg_error_from_syserror ();
+	  else
+	    {
+	      memcpy (res, databuf, datalen);
+	      res[datalen] = 0;
+	      *socket_name = res;
+	    }
+	}
+    }
+
+  xfree (databuf);
+
+  return err;
+}
+
+/* Retrieve SCDaemons socket name through a running gpg-agent.  On
+   Success, *SOCKET_NAME contains a copy of the socket name.  Returns
+   proper error code or zero on success.  */
+static gpg_error_t
+get_scd_socket_from_agent (char **socket_name)
+{
+  assuan_context_t ctx = NULL;
+  gpg_error_t err;
+  char *gpg_agent_sockname;
+
+  err = get_agent_socket_name (&gpg_agent_sockname);
+  if (err)
+    return err;
+
+  err = assuan_socket_connect (&ctx, gpg_agent_sockname, 0);
+  xfree (gpg_agent_sockname);
+  if (!err)
+    err = agent_scd_getinfo_socket_name (ctx, socket_name);
+
+  assuan_disconnect (ctx);
+
+  return err;
+}
+
 /* Send a RESTART to SCDaemon.  */
 static void
 restart_scd (scd_context_t ctx)
@@ -107,7 +212,7 @@ restart_scd (scd_context_t ctx)
 /* Fork off scdaemon and work by pipes.  Returns proper error code or
    zero on success.  */
 gpg_error_t
-scd_connect (scd_context_t *scd_ctx, const char *scd_path,
+scd_connect (scd_context_t *scd_ctx, int use_agent, const char *scd_path,
 	     const char *scd_options, log_handle_t loghandle)
 {
   assuan_context_t assuan_ctx;
@@ -116,40 +221,58 @@ scd_connect (scd_context_t *scd_ctx, const char *scd_path,
 
   assuan_ctx = NULL;
 
+  if (fflush (NULL))
+    {
+      rc = gpg_error_from_syserror ();
+      log_msg_error (loghandle,
+		     _("error flushing pending output: %s"),
+		     strerror (errno));
+      return rc;
+    }
+
   ctx = xtrymalloc (sizeof (*ctx));
-  if (! ctx)
+  if (!ctx)
     {
       rc = gpg_error_from_syserror ();
-      goto out;
+      return rc;
     }
 
   ctx->assuan_ctx = NULL;
   ctx->flags = 0;
 
-  if (1)
+  if (use_agent)
     {
-      const char *pgmname;
-      const char *argv[5];
-      int no_close_list[3];
-      int i;
+      /* Retrieve a scdaemon socket name from gpg-agent.  */
+      char *scd_socket_name = NULL;
 
-#if 0
+      rc = get_scd_socket_from_agent (&scd_socket_name);
+      if (!rc)
+	rc = assuan_socket_connect (&assuan_ctx, scd_socket_name, 0);
+
+      if (!rc)
 	log_msg_debug (loghandle,
-		       _("no running scdaemon - starting one"));
-#endif
+		       _("got scdaemon socket name from gpg-agent, "
+			 "connected to socket '%s'"), scd_socket_name);
 
-      if (fflush (NULL))
-        {
-          rc = gpg_error_from_syserror ();
+      xfree (scd_socket_name);
+
+      if (rc)
+	{
 	  log_msg_error (loghandle,
-			 _("error flushing pending output: %s"),
-			 strerror (errno));
-	  goto out;
-        }
+			 _("could not connect to scdaemon: %s"),
+			 gpg_strerror (rc));
+	}
+    }
+  else
+    {
+      const char *pgmname;
+      const char *argv[5];
+      int no_close_list[3];
+      int i;
 
       if (!scd_path || !*scd_path)
         scd_path = GNUPG_DEFAULT_SCD;
-      if ( !(pgmname = strrchr (scd_path, '/')))
+      if (!(pgmname = strrchr (scd_path, '/')))
         pgmname = scd_path;
       else
         pgmname++;
@@ -168,9 +291,9 @@ scd_connect (scd_context_t *scd_ctx, const char *scd_path,
 
       i=0;
 
+#if 0
       /* FIXME! Am I right in assumung that we do not need this?
 	 -mo */
-#if 0
       if (log_get_fd () != -1)
         no_close_list[i++] = log_get_fd ();
 #endif
@@ -181,26 +304,24 @@ scd_connect (scd_context_t *scd_ctx, const char *scd_path,
 
       /* connect to the scdaemon and perform initial handshaking */
       rc = assuan_pipe_connect (&assuan_ctx, scd_path, argv, no_close_list);
-      if (!rc)
+      if (rc)
+	{
+	  log_msg_error (loghandle,
+			 _("could not spawn scdaemon: %s"),
+			 gpg_strerror (rc));
+	}
+      else
 	{
 	  log_msg_debug (loghandle,
 			 _("spawned a new scdaemon (path: '%s')"),
 			 scd_path);
-	  goto out;
 	}
     }
 
-  log_msg_error (loghandle,
-		 _("could not connect to any scdaemon: %s"),
-		 gpg_strerror (rc));
-
- out:
-
   if (rc)
     {
       assuan_disconnect (assuan_ctx);
       xfree (ctx);
-
     }
   else
     {
@@ -212,10 +333,6 @@ scd_connect (scd_context_t *scd_ctx, const char *scd_path,
       ctx->flags = 0;
       ctx->loghandle = loghandle;
       *scd_ctx = ctx;
-#if 0
-	log_msg_debug (loghandle,
-		       _("connection to scdaemon established"));
-#endif
     }
 
   return rc;
diff --git a/src/scd/scd.h b/src/scd/scd.h
index 25680f8..8910497 100644
--- a/src/scd/scd.h
+++ b/src/scd/scd.h
@@ -49,8 +49,9 @@ typedef struct scd_cardinfo scd_cardinfo_t;
 
 /* Fork it off and work by pipes.  Returns proper error code or zero
    on success.  */
-gpg_error_t scd_connect (scd_context_t *scd_ctx, const char *scd_path,
-			 const char *scd_options, log_handle_t loghandle);
+gpg_error_t scd_connect (scd_context_t *scd_ctx, int use_agent,
+			 const char *scd_path, const char *scd_options,
+			 log_handle_t loghandle);
 
 /* Disconnect from SCDaemon; destroy the context SCD_CTX.  */
 void scd_disconnect (scd_context_t scd_ctx);

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

Summary of changes:
 NEWS                       |  22 ++++--
 configure.ac               |   3 +
 doc/poldi.texi             |   2 +-
 src/pam/auth-support/ctx.h |   1 +
 src/pam/pam_poldi.c        |  12 ++-
 src/scd/scd.c              | 183 +++++++++++++++++++++++++++++++++++++--------
 src/scd/scd.h              |   5 +-
 7 files changed, 183 insertions(+), 45 deletions(-)


hooks/post-receive
-- 
PAM for the OpenPGP card
http://git.gnupg.org




More information about the Gnupg-commits mailing list