[git] Pinentry - branch, master, updated. pinentry-0.9.2-15-g4549998

by Neal H. Walfield cvs at cvs.gnupg.org
Wed May 13 23:17:25 CEST 2015


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 standard pinentry collection".

The branch, master has been updated
       via  4549998627ee04e74f8d1c94aef55e3ed17f14d9 (commit)
       via  c68a6854aadaf8c271648f369f14b4943e684ecf (commit)
       via  960317ec86c06bc737e1ff3c1b571dc8f4194763 (commit)
       via  dd0307be51587a9a7866981ce00eed474bee6e14 (commit)
      from  496235af8dfd373b54e5610f86bf1cada175ac23 (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 4549998627ee04e74f8d1c94aef55e3ed17f14d9
Author: Neal H. Walfield <neal at gnu.org>
Date:   Wed May 13 23:13:30 2015 +0200

    tty: Handle the case where the user needs to repeat the passphrase.
    
    * tty/pinentry-tty.c: Include "memory.h".
    (read_password): Break into two functions: read_password and password.
    (read_password): Just read the password from the terminal and return
    it in secure memory (or NULL if the user canceled the entry or there
    was an error).
    (password): Improve output.  Handle the repeat passphrase case (i.e.,
    when pinentry->repeat_passphrase is set).
    * tty/Makefile.am (AM_CPPFLAGS): Add "-I$(top_srcdir)/secmem".

diff --git a/tty/Makefile.am b/tty/Makefile.am
index aa805b2..ca6406f 100644
--- a/tty/Makefile.am
+++ b/tty/Makefile.am
@@ -20,7 +20,7 @@
 
 bin_PROGRAMS = pinentry-tty
 
-AM_CPPFLAGS = $(COMMON_CFLAGS) -I$(top_srcdir)/pinentry
+AM_CPPFLAGS = $(COMMON_CFLAGS) -I$(top_srcdir)/secmem -I$(top_srcdir)/pinentry
 LDADD = ../pinentry/libpinentry.a \
 	../assuan/libassuan.a ../secmem/libsecmem.a \
 	$(COMMON_LIBS) $(LIBCAP) $(LIBICONV)
diff --git a/tty/pinentry-tty.c b/tty/pinentry-tty.c
index c13ed04..82eab87 100644
--- a/tty/pinentry-tty.c
+++ b/tty/pinentry-tty.c
@@ -39,6 +39,7 @@
 #include <ctype.h>
 
 #include "pinentry.h"
+#include "memory.h"
 
 #ifndef HAVE_DOSISH_SYSTEM
 static int timed_out;
@@ -237,43 +238,52 @@ confirm (pinentry_t pinentry, FILE *ttyfi, FILE *ttyfo)
   return ret;
 }
 
-
-static int
-read_password (pinentry_t pinentry, FILE *ttyfi, FILE *ttyfo)
+static char *
+read_password (FILE *ttyfi, FILE *ttyfo)
 {
-  int count;
-  int done;
-  char *prompt = NULL;
+  int done = 0;
+  int len = 128;
+  int count = 0;
+  char *buffer;
 
   if (cbreak (fileno (ttyfi)) == -1)
     {
       int err = errno;
       fprintf (stderr, "cbreak failure, exiting\n");
       errno = err;
-      return -1;
+      return NULL;
     }
 
-  prompt = pinentry->prompt;
-  if (! prompt || !*prompt)
-    prompt = "PIN";
-
-  fprintf (ttyfo, "%s\n%s%s ",
-           pinentry->description? pinentry->description:"",
-           prompt,
-	   /* Make sure the prompt ends in a : or a question mark.  */
-	   (prompt[strlen(prompt) - 1] == ':'
-	    || prompt[strlen(prompt) - 1] == '?') ? "" : ":");
-  fflush (ttyfo);
-
-  memset (pinentry->pin, 0, pinentry->pin_len);
+  buffer = secmem_malloc (len);
+  if (! buffer)
+    return NULL;
 
-  done = count = 0;
-  while (!done && count < pinentry->pin_len - 1)
+  while (!done)
     {
-      char c = fgetc (ttyfi);
+      int c;
 
+      if (count == len - 1)
+	/* Double the buffer's size.  Note: we check if count is len -
+	   1 and not len so that we always have space for the NUL
+	   character.  */
+	{
+	  char *tmp = secmem_realloc (buffer, 2 * len);
+	  if (! tmp)
+	    {
+	      secmem_free (tmp);
+	      return NULL;
+	    }
+	  buffer = tmp;
+	}
+
+      c = fgetc (ttyfi);
       switch (c)
 	{
+	case 0x4: case EOF:
+	  /* Control-d (i.e., end of file) or a real EOF.  */
+	  done = -1;
+	  break;
+
 	case '\n':
 	  done = 1;
 	  break;
@@ -285,15 +295,102 @@ read_password (pinentry_t pinentry, FILE *ttyfi, FILE *ttyfo)
 	  break;
 
 	default:
-	  pinentry->pin[count ++] = c;
+	  buffer[count ++] = c;
 	  break;
 	}
     }
-  pinentry->pin[count] = '\0';
-  fputc('\n', stdout);
+  buffer[count] = '\0';
 
   tcsetattr (fileno(ttyfi), TCSANOW, &o_term);
-  return strlen (pinentry->pin);
+
+  if (done == -1)
+    {
+      secmem_free (buffer);
+      return NULL;
+    }
+
+  return buffer;
+}
+
+
+static int
+password (pinentry_t pinentry, FILE *ttyfi, FILE *ttyfo)
+{
+  char *msg;
+  int done = 0;
+
+  msg = pinentry->description;
+  if (! msg)
+    msg = pinentry->title;
+  if (! msg)
+    msg = "Enter your passphrase.";
+
+  fprintf (ttyfo, "%s\n ", msg);
+
+  while (! done)
+    {
+      char *passphrase;
+
+      char *prompt = pinentry->prompt;
+      if (! prompt || !*prompt)
+	prompt = "PIN";
+
+      fprintf (ttyfo, "%s%s ",
+	       prompt,
+	       /* Make sure the prompt ends in a : or a question mark.  */
+	       (prompt[strlen(prompt) - 1] == ':'
+		|| prompt[strlen(prompt) - 1] == '?') ? "" : ":");
+      fflush (ttyfo);
+
+      passphrase = read_password (ttyfi, ttyfo);
+      fputc ('\n', ttyfo);
+      if (! passphrase)
+	{
+	  done = -1;
+	  break;
+	}
+
+      if (! pinentry->repeat_passphrase)
+	done = 1;
+      else
+	{
+	  char *passphrase2;
+
+	  prompt = pinentry->repeat_passphrase;
+	  fprintf (ttyfo, "%s%s ",
+		   prompt,
+		   /* Make sure the prompt ends in a : or a question mark.  */
+		   (prompt[strlen(prompt) - 1] == ':'
+		    || prompt[strlen(prompt) - 1] == '?') ? "" : ":");
+	  fflush (ttyfo);
+
+	  passphrase2 = read_password (ttyfi, ttyfo);
+	  fputc ('\n', ttyfo);
+	  if (! passphrase2)
+	    {
+	      done = -1;
+	      break;
+	    }
+
+	  if (strcmp (passphrase, passphrase2) == 0)
+	    done = 1;
+	  else
+	    fprintf (ttyfo, "*** %s%s%s ***\n",
+		     ALERT_START,
+		     pinentry->repeat_error_string
+		     ?: "Passphrases don't match.",
+		     NORMAL_RESTORE);
+
+	  secmem_free (passphrase2);
+	}
+
+      if (done == 1)
+	pinentry_setbuffer_use (pinentry, passphrase, 0);
+      else
+	secmem_free (passphrase);
+    }
+
+  return done;
 }
 
 
@@ -372,7 +469,7 @@ tty_cmd_handler(pinentry_t pinentry)
   if (! rc)
     {
       if (pinentry->pin)
-	rc = read_password (pinentry, ttyfi, ttyfo);
+	rc = password (pinentry, ttyfi, ttyfo);
       else
 	rc = confirm (pinentry, ttyfi, ttyfo);
     }

commit c68a6854aadaf8c271648f369f14b4943e684ecf
Author: Neal H. Walfield <neal at gnu.org>
Date:   Wed May 13 23:09:46 2015 +0200

    Add a new helper function, pinentry_setbuffer_use.
    
    * pinentry/pinentry.c (pinentry_setbuffer_use): New function.
    * pinentry/pinentry.h (pinentry_setbuffer_use): New declaration.

diff --git a/pinentry/pinentry.c b/pinentry/pinentry.c
index 836ee14..eb70ae7 100644
--- a/pinentry/pinentry.c
+++ b/pinentry/pinentry.c
@@ -405,6 +405,28 @@ pinentry_setbuffer_init (pinentry_t pin)
   pinentry_setbufferlen (pin, 0);
 }
 
+/* passphrase better be alloced with secmem_alloc.  */
+void
+pinentry_setbuffer_use (pinentry_t pin, char *passphrase, int len)
+{
+  if (! passphrase)
+    {
+      assert (len == 0);
+      pinentry_setbuffer_clear (pin);
+
+      return;
+    }
+
+  if (passphrase && len == 0)
+    len = strlen (passphrase) + 1;
+
+  if (pin->pin)
+    secmem_free (pin->pin);
+
+  pin->pin = passphrase;
+  pin->pin_len = len;
+}
+
 /* Initialize the secure memory subsystem, drop privileges and return.
    Must be called early. */
 void
diff --git a/pinentry/pinentry.h b/pinentry/pinentry.h
index 7112637..19fdb55 100644
--- a/pinentry/pinentry.h
+++ b/pinentry/pinentry.h
@@ -240,6 +240,12 @@ int pinentry_inq_quality (pinentry_t pin,
    PIN.  Returns new buffer on success and 0 on failure.  */
 char *pinentry_setbufferlen (pinentry_t pin, int len);
 
+/* Use the buffer at BUFFER for PIN->PIN.  BUFFER must be NULL or
+   allocated using secmem_alloc.  LEN is the size of the buffer.  If
+   it is unknown, but BUFFER is a NUL terminated string, you pass 0 to
+   just use strlen(buffer)+1.  */
+void pinentry_setbuffer_use (pinentry_t pin, char *buffer, int len);
+
 /* Initialize the secure memory subsystem, drop privileges and
    return.  Must be called early.  */
 void pinentry_init (const char *pgmname);

commit 960317ec86c06bc737e1ff3c1b571dc8f4194763
Author: Neal H. Walfield <neal at gnu.org>
Date:   Wed May 13 22:12:59 2015 +0200

    tty: Always call do_touch_file if we (potentially) touched the screen.
    
    * tty/pinentry-tty.c (tty_cmd_handler): Always call do_touch_file.

diff --git a/tty/pinentry-tty.c b/tty/pinentry-tty.c
index 08dfe61..c13ed04 100644
--- a/tty/pinentry-tty.c
+++ b/tty/pinentry-tty.c
@@ -375,10 +375,10 @@ tty_cmd_handler(pinentry_t pinentry)
 	rc = read_password (pinentry, ttyfi, ttyfo);
       else
 	rc = confirm (pinentry, ttyfi, ttyfo);
-
-      do_touch_file (pinentry);
     }
 
+  do_touch_file (pinentry);
+
   if (pinentry->ttyname)
     {
       fclose (ttyfi);

commit dd0307be51587a9a7866981ce00eed474bee6e14
Author: Neal H. Walfield <neal at gnu.org>
Date:   Wed May 13 22:09:15 2015 +0200

    tty: Improve confirmation mode functionality.
    
    * tty/pinentry-tty.c: Include <ctype.h>.
    (UNDERLINE_START): Define.
    (ALERT_START): Define.
    (NORMAL_RESTORE): Define.
    (button): New function.
    (confirm): Rewrite to include all confirmation mode functionality.
    (tty_cmd_handler): Don't include any confirmation mode functionality.
    Just call confirm.

diff --git a/tty/pinentry-tty.c b/tty/pinentry-tty.c
index 8c15eac..08dfe61 100644
--- a/tty/pinentry-tty.c
+++ b/tty/pinentry-tty.c
@@ -36,6 +36,7 @@
 #endif /*HAVE_UTIME_H*/
 #include <sys/types.h>
 #include <sys/stat.h>
+#include <ctype.h>
 
 #include "pinentry.h"
 
@@ -60,21 +61,180 @@ cbreak (int fd)
   return 1;
 }
 
+#define UNDERLINE_START "\033[4m"
+/* Bold, red.  */
+#define ALERT_START "\033[1;31m"
+#define NORMAL_RESTORE "\033[0m"
+
+static char
+button (char *text, char *default_text, FILE *ttyfo)
+{
+  char *highlight;
+
+  if (! text)
+    return 0;
+
+  /* Skip any leading white space.  */
+  while (*text == ' ')
+    text ++;
+
+  highlight = text;
+  while ((highlight = strchr (highlight, '_')))
+    {
+      highlight = highlight + 1;
+      if (*highlight == '_')
+	/* Escaped underscore.  */
+	continue;
+      else
+	break;
+    }
+
+  if (! highlight)
+    /* Not accelerator.  Take the first alpha-numeric character.  */
+    {
+      highlight = text;
+      while (*highlight && !isalnum (*highlight))
+	highlight ++;
+    }
+
+  if (! highlight)
+    /* Hmm, no alpha-num characters.  */
+    {
+      if (! default_text)
+	return 0;
+      text = highlight = default_text;
+    }
+
+  fputs ("  ", ttyfo);
+  for (; *text; text ++)
+    {
+      /* Skip accelerator prefix.  */
+      if (*text == '_')
+	continue;
+
+      if (text == highlight)
+	fputs (UNDERLINE_START, ttyfo);
+      fputc (*text, ttyfo);
+      if (text == highlight)
+	fputs (NORMAL_RESTORE, ttyfo);
+    }
+  fputc ('\n', ttyfo);
+
+  return *highlight;
+}
+
 static int
 confirm (pinentry_t pinentry, FILE *ttyfi, FILE *ttyfo)
 {
-  char buf[32], *ret;
-  pinentry->canceled = 1;
-  fprintf (ttyfo, "%s [y/N]? ", pinentry->ok ? pinentry->ok : "OK");
+  char *msg;
+
+  char ok = 0;
+  char notok = 0;
+  char cancel = 0;
+
+  int ret;
+
+  if (pinentry->error)
+    fprintf (ttyfo, "*** %s%s%s ***\n",
+	     ALERT_START, pinentry->error, NORMAL_RESTORE);
+
+  msg = pinentry->description;
+  if (! msg)
+    /* If there is no description, fallback to the title.  */
+    msg = pinentry->title;
+  if (! msg)
+    msg = "Confirm:";
+
+  if (msg)
+    {
+      fputs (msg, ttyfo);
+      fputc ('\n', ttyfo);
+    }
+
   fflush (ttyfo);
-  buf[0] = '\0';
-  ret = fgets (buf, sizeof(buf), ttyfi);
-  if (ret && (buf[0] == 'y' || buf[0] == 'Y'))
+
+  if (pinentry->default_ok)
+    ok = button (pinentry->default_ok, "OK", ttyfo);
+  else if (pinentry->ok)
+    ok = button (pinentry->ok, "OK", ttyfo);
+  else
+    ok = button ("OK", NULL, ttyfo);
+
+  if (! pinentry->one_button)
     {
-      pinentry->canceled = 0;
-      return 1;
+      if (pinentry->default_cancel)
+	cancel = button (pinentry->default_cancel, "Cancel", ttyfo);
+      else if (pinentry->cancel)
+	cancel = button (pinentry->cancel, "Cancel", ttyfo);
+
+      if (pinentry->notok)
+	notok = button (pinentry->notok, NULL, ttyfo);
     }
-  return 0;
+
+  if (cbreak (fileno (ttyfi)) == -1)
+    {
+      int err = errno;
+      fprintf (stderr, "cbreak failure, exiting\n");
+      errno = err;
+      return -1;
+    }
+
+  if (pinentry->one_button)
+    fprintf (ttyfo, "Press any key to continue.");
+  else
+    {
+      fputc ('[', ttyfo);
+      if (ok)
+	fputc (tolower (ok), ttyfo);
+      if (cancel)
+	fputc (tolower (cancel), ttyfo);
+      if (notok)
+	fputc (tolower (notok), ttyfo);
+      fputs("]? ", ttyfo);
+    }
+
+  while (1)
+    {
+      int input = fgetc (ttyfi);
+      if (input == EOF || input == 0x4)
+	/* End of file or control-d (= end of file).  */
+	{
+	  pinentry->close_button = 1;
+
+	  pinentry->canceled = 1;
+	  ret = 0;
+	  break;
+	}
+
+      if (pinentry->one_button)
+	{
+	  ret = 1;
+	  break;
+	}
+
+      if (cancel && (input == toupper (cancel) || input == tolower (cancel)))
+	{
+	  pinentry->canceled = 1;
+	  ret = 0;
+	  break;
+	}
+      else if (notok && (input == toupper (notok) || input == tolower (notok)))
+	{
+	  ret = 0;
+	  break;
+	}
+      else if (ok && (input == toupper (ok) || input == tolower (ok)))
+	{
+	  ret = 1;
+	  break;
+	}
+    }
+
+  fputc('\n', ttyfo);
+
+  tcsetattr (fileno(ttyfi), TCSANOW, &o_term);
+
+  return ret;
 }
 
 
@@ -209,23 +369,13 @@ tty_cmd_handler(pinentry_t pinentry)
         }
     }
 
-  if (rc == 0)
+  if (! rc)
     {
       if (pinentry->pin)
-        rc = read_password (pinentry, ttyfi, ttyfo);
+	rc = read_password (pinentry, ttyfi, ttyfo);
       else
-        {
-          fprintf (ttyfo, "%s\n",
-                   pinentry->description? pinentry->description:"");
-          fflush (ttyfo);
-
-	  /* If pinentry->one_button is set, then
-	     pinentry->description contains an informative message,
-	     which the user needs to dismiss.  Since we are showing
-	     this in a terminal, there is no window to dismiss.  */
-          if (! pinentry->one_button)
-            rc = confirm (pinentry, ttyfi, ttyfo);
-        }
+	rc = confirm (pinentry, ttyfi, ttyfo);
+
       do_touch_file (pinentry);
     }
 

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

Summary of changes:
 pinentry/pinentry.c |  22 ++++
 pinentry/pinentry.h |   6 +
 tty/Makefile.am     |   2 +-
 tty/pinentry-tty.c  | 347 ++++++++++++++++++++++++++++++++++++++++++++--------
 4 files changed, 326 insertions(+), 51 deletions(-)


hooks/post-receive
-- 
The standard pinentry collection
http://git.gnupg.org




More information about the Gnupg-commits mailing list