[PATCH] New pinentry-tty version for dumb terminals.

Serge Voilokov serge0x76 at gmail.com
Fri Aug 8 21:52:27 CEST 2014


Hi,
I added version of pinentry tool for dumb terminals (pinentry-tty).
Please consider adding this to pinentry project.
Thanks,
Serge

>8-----------------------------------------------8<

    * .gitignore(insert): added pinentry-tty related files.
    * Makefile.am(insert): added pinentry-tty.
    * NEWS(insert): added news about pinentry-tty.
    * README(insert): added readme.
    * configure.ac(insert): added tty/Makefile.
    * tty/Makefile.am(add): am for pinentry-tty.
    * tty/pinentry-tty.c(add): dumb console version.
---
 .gitignore         |   2 +
 Makefile.am        |   8 ++-
 NEWS               |   2 +
 README             |   1 +
 configure.ac       |  20 ++++++
 tty/Makefile.am    |  31 +++++++++
 tty/pinentry-tty.c | 193 +++++++++++++++++++++++++++++++++++++++++++++++++++++
 7 files changed, 256 insertions(+), 1 deletion(-)
 create mode 100644 tty/Makefile.am
 create mode 100644 tty/pinentry-tty.c

diff --git a/.gitignore b/.gitignore
index 575e011..9395e3c 100644
--- a/.gitignore
+++ b/.gitignore
@@ -34,6 +34,8 @@ secmem/Makefile.in
 secmem/Makefile
 w32/Makefile.in
 w32/Makefile
+tty/Makefile.in
+tty/Makefile
 
 /qt4/pinentryconfirm.moc
 /qt4/pinentrydialog.moc
diff --git a/Makefile.am b/Makefile.am
index f4fa814..a3fa819 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -35,6 +35,12 @@ else
 pinentry_curses =
 endif
 
+if BUILD_PINENTRY_TTY
+pinentry_tty = tty
+else
+pinentry_tty =
+endif
+
 if BUILD_PINENTRY_GTK
 pinentry_gtk = gtk
 else
@@ -65,7 +71,7 @@ else
 pinentry_w32 =
 endif
 
-SUBDIRS = assuan secmem pinentry ${pinentry_curses} \
+SUBDIRS = assuan secmem pinentry ${pinentry_curses} ${pinentry_tty} \
 	${pinentry_gtk} ${pinentry_gtk_2} ${pinentry_qt} ${pinentry_qt4} \
 	${pinentry_w32} doc
 
diff --git a/NEWS b/NEWS
index 5bd874f..28d3c80 100644
--- a/NEWS
+++ b/NEWS
@@ -1,6 +1,8 @@
 Noteworthy changes in version 0.8.4 (unreleased)
 ------------------------------------------------
 
+ * New pinentry-tty version for dump terminals.
+
  * Qt4: New option to enable pasting the passphrase from clipboard
 
  * Qt4: Improved accessiblity
diff --git a/README b/README
index 087208a..6bb0d85 100644
--- a/README
+++ b/README
@@ -17,6 +17,7 @@ GTK+ V2.0	--enable-pinentry-gtk2	 Gimp Toolkit Library, Version 2.0
 					 eg. libgtk-x11-2.0 and libglib-2.0
 Qt		--enable-pinentry-qt	 Qt, eg. libqt or libqt-mt
 Qt4		--enable-pinentry-qt4	 Qt4
+TTY		--enable-pinentry-tty	 Simple TTY version, no dependencies
 
 The GTK+ and Qt pinentries can fall back to the curses mode.  The
 option to enable this is --enable-fallback-curses, but this is also
diff --git a/configure.ac b/configure.ac
index 595c2aa..849f038 100644
--- a/configure.ac
+++ b/configure.ac
@@ -236,6 +236,20 @@ fi
 
 
 dnl
+dnl Check for tty pinentry program.
+dnl
+AC_ARG_ENABLE(pinentry-tty,
+            AC_HELP_STRING([--enable-pinentry-tty], [build tty pinentry]),
+            pinentry_tty=$enableval, pinentry_tty=maybe)
+AM_CONDITIONAL(BUILD_PINENTRY_TTY, test "$pinentry_tty" = "yes")
+
+if test "$pinentry_tty" = "yes"; then
+  AC_DEFINE(PINENTRY_TTY, 1,
+           [The TTY version of Pinentry is to be build])
+fi
+
+
+dnl
 dnl Check for GTK+ pinentry program.
 dnl
 AC_ARG_ENABLE(pinentry-gtk,
@@ -494,6 +508,9 @@ else
         if test "$pinentry_curses" = "yes"; then
           PINENTRY_DEFAULT=pinentry-curses
         else
+          if test "$pinentry_tty" = "yes"; then
+            PINENTRY_DEFAULT=pinentry-tty
+          else
           if test "$pinentry_w32" = "yes"; then
             PINENTRY_DEFAULT=pinentry-w32
           else
@@ -503,6 +520,7 @@ else
       fi
     fi
   fi
+  fi
 fi
 AC_SUBST(PINENTRY_DEFAULT)
 
@@ -512,6 +530,7 @@ assuan/Makefile
 secmem/Makefile
 pinentry/Makefile
 curses/Makefile
+tty/Makefile
 gtk/Makefile
 gtk+-2/Makefile
 qt/Makefile
@@ -531,6 +550,7 @@ AC_MSG_NOTICE([
 	Platform:  $host
 
 	Curses Pinentry ..: $pinentry_curses
+	TTY Pinentry .....: $pinentry_tty
 	GTK+ Pinentry ....: $pinentry_gtk
 	GTK+-2 Pinentry ..: $pinentry_gtk_2
 	Qt Pinentry ......: $pinentry_qt
diff --git a/tty/Makefile.am b/tty/Makefile.am
new file mode 100644
index 0000000..8224deb
--- /dev/null
+++ b/tty/Makefile.am
@@ -0,0 +1,31 @@
+# Makefile.am - PIN entry curses frontend.
+# Copyright (C) 2002 g10 Code GmbH
+#
+# This file is part of PINENTRY.
+#
+# PINENTRY is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# PINENTRY is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
+
+## Process this file with automake to produce Makefile.in
+
+EXTRA_DIST = Manifest
+
+bin_PROGRAMS = pinentry-tty
+
+AM_CPPFLAGS = -I$(top_srcdir)/pinentry
+LDADD = ../pinentry/libpinentry.a \
+	../assuan/libassuan.a ../secmem/libsecmem.a \
+	$(LIBCAP) $(LIBICONV)
+
+pinentry_tty_SOURCES = pinentry-tty.c
diff --git a/tty/pinentry-tty.c b/tty/pinentry-tty.c
new file mode 100644
index 0000000..24ff8a5
--- /dev/null
+++ b/tty/pinentry-tty.c
@@ -0,0 +1,193 @@
+/* pinentry-curses.c - A secure curses dialog for PIN entry, library version
+   Copyright (C) 2002 g10 Code GmbH
+
+   This file is part of PINENTRY.
+
+   PINENTRY is free software; you can redistribute it and/or modify it
+   under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 2 of the License, or
+   (at your option) any later version.
+
+   PINENTRY is distributed in the hope that it will be useful, but
+   WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   General Public License for more details.
+
+   You should have received a copy of the GNU General Public License
+   along with this program; if not, write to the Free Software
+   Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
+   02111-1307, USA  */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+#include <signal.h>
+#include <fcntl.h>
+#include <unistd.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <errno.h>
+#include <time.h>
+#include <termios.h>
+#ifdef HAVE_UTIME_H
+#include <utime.h>
+#endif /*HAVE_UTIME_H*/
+
+#include <memory.h>
+
+#include "pinentry.h"
+
+#ifndef HAVE_DOSISH_SYSTEM
+static int timed_out;
+#endif
+
+static struct termios n_term;
+static struct termios o_term;
+
+static int
+cbreak(int fd) 
+{
+	if ((tcgetattr(fd, &o_term)) == -1)
+		return -1;
+	n_term = o_term;
+	n_term.c_lflag = n_term.c_lflag & ~(ECHO|ICANON);
+	n_term.c_cc[VMIN] = 1;
+	n_term.c_cc[VTIME]= 0;
+	if ((tcsetattr(fd, TCSAFLUSH, &n_term)) == -1)
+		return -1;
+	return 1;
+}
+
+static int
+read_password(pinentry_t pinentry, const char *tty_name, const char *tty_type)
+{
+	FILE *ttyfi = stdin;
+	FILE *ttyfo = stdout;
+	
+	if (tty_name)
+	{
+		ttyfi = fopen(tty_name, "r");
+		if (!ttyfi)
+			return -1;
+
+		ttyfo = fopen(tty_name, "w");
+		if (!ttyfo)
+		{
+			int err = errno;
+			fclose(ttyfi);
+			errno = err;
+			return -1;
+		}
+	}
+
+	if (cbreak(fileno(ttyfi)) == -1)
+	{
+		int err = errno;
+		fclose(ttyfi);
+		fclose(ttyfo);
+		fprintf(stderr, "cbreak failure, exiting\n");
+		errno = err;
+		return -1;
+	}
+	
+	fprintf(ttyfo, "%s\n%s:\n", pinentry->description, pinentry->prompt);
+	fflush(ttyfo);
+
+	memset(pinentry->pin, 0, pinentry->pin_len);
+
+	int count = 0;
+	while (1)
+	{
+		char c = fgetc(ttyfi);
+		if (c == '\n')
+			break;
+
+		fflush(ttyfo);
+		pinentry->pin[count++] = c;
+		if (count >= pinentry->pin_len)
+			break;
+	}
+
+	tcsetattr(fileno(ttyfi), TCSANOW, &o_term);
+	fclose(ttyfi);
+	fclose(ttyfo);
+	return strlen(pinentry->pin);
+}
+
+
+/* If a touch has been registered, touch that file.  */
+static void
+do_touch_file(pinentry_t pinentry)
+{
+#ifdef HAVE_UTIME_H
+	struct stat st;
+	time_t tim;
+
+	if (!pinentry->touch_file || !*pinentry->touch_file)
+		return;
+
+	if (stat(pinentry->touch_file, &st))
+		return; /* Oops.  */
+
+	/* Make sure that we actually update the mtime.  */
+	while ((tim = time(NULL)) == st.st_mtime)
+		sleep(1);
+
+	/* Update but ignore errors as we can't do anything in that case.
+	   Printing error messages may even clubber the display further. */
+	utime(pinentry->touch_file, NULL);
+#endif /*HAVE_UTIME_H*/
+}
+
+#ifndef HAVE_DOSISH_SYSTEM
+static void
+catchsig(int sig)
+{
+	if (sig == SIGALRM)
+		timed_out = 1;
+}
+#endif
+
+int
+tty_cmd_handler(pinentry_t pinentry)
+{
+	int rc;
+
+#ifndef HAVE_DOSISH_SYSTEM
+	timed_out = 0;
+
+	if (pinentry->timeout)
+	{
+		struct sigaction sa;
+
+		memset(&sa, 0, sizeof(sa));
+		sa.sa_handler = catchsig;
+		sigaction(SIGALRM, &sa, NULL);
+		alarm(pinentry->timeout);
+	}
+#endif
+
+	rc = read_password(pinentry, pinentry->ttyname, pinentry->ttytype);
+	do_touch_file(pinentry);
+	return rc;
+}
+
+pinentry_cmd_handler_t pinentry_cmd_handler = tty_cmd_handler;
+
+int
+main(int argc, char *argv[])
+{
+	pinentry_init("pinentry-tty");
+	
+	/* Consumes all arguments.  */
+	if (pinentry_parse_opts(argc, argv))
+	{
+		printf("pinentry-tty (pinentry) " VERSION "\n");
+		exit(EXIT_SUCCESS);
+	}
+
+	if (pinentry_loop())
+		return 1;
+
+	return 0;
+}
-- 
1.9.0




More information about the Gnupg-devel mailing list