Ludovic Rousseau wrote:
2010/4/26 Viktor TARASOV <viktor.tara...@opentrust.com>:
Ludovic Rousseau wrote:
2010/4/15 Andreas Jellinghaus <a...@dungeon.inka.de>:

Am Donnerstag 15 April 2010 19:41:45 schrieb OpenSC:

#120: pkcs15-init needs to accept ctrl-c
--------------------+------------------------------------------------------
- Reporter:  aj      |       Owner:  opensc-de...@…
     Type:  defect  |      Status:  new
 Priority:  normal  |   Milestone:  0.12.0
Component:  tools   |     Version:  0.11.1
 Severity:  normal  |    Keywords:
--------------------+------------------------------------------------------
-

Comment(by viktor.tara...@…):

 I propose to implement local version of getpass() sensible to Ctrl-C .

 Any objections?


can you test attached patch? it is incomplete, but replaces getpass
with out own code. it uses the recommended replacement for getpass -
turn off echo with termios.

like getline it will allocate space and the caller needs to free
that space (and for PINs and passwords: cleanse it). because of
that interface change the difference is quite big.

getline() is a GNU extension.
>From getline(3) on Debian:
CONFORMING TO
       Both  getline()  and  getdelim()  were originally GNU extensions.  They
       were standardized in POSIX.1-2008.

And on Mac OS X Snow Leopard I do not have getline().

Maybe a correct solution is to test for the presence of getline in
configure.ac and use
#ifdef HAVE_GETLINE
#else
/* Windows and Mac OS X */
#endif

I've applied your proposals, thanks.

I'm not sure about availability on MacOS of getchar() or _getch().
Can you check r4266, please?

Compilation fails with:
Undefined symbols:
  "__getch", referenced from:
      _util_getpass in util.o

Mac OS X does not have _getch().

On Mac OS X util_getpass() should use the tcsetattr() dance as
described in 
http://www.opensc-project.org/opensc/attachment/ticket/120/opensc-getpass.patch

I've tested the attached patch on linux and windows.
Can you try it on MacOS, please?

Kind wishes,
Viktor.

--
Viktor Tarasov  <viktor.tara...@opentrust.com>

diff --git a/src/tools/util.c b/src/tools/util.c
index 88c2d5c..6647d2e 100644
--- a/src/tools/util.c
+++ b/src/tools/util.c
@@ -5,6 +5,8 @@
 #include <stdarg.h>
 #ifndef _WIN32
 #include <termios.h>
+#else
+#include <conio.h>
 #endif
 #include <ctype.h>
 #include "util.h"
@@ -283,66 +285,64 @@ util_warn(const char *fmt, ...)
 	va_end(ap);
 }
 
-int util_getpass (char **lineptr, size_t *len, FILE *stream)
+int 
+util_getpass (char **lineptr, size_t *len, FILE *stream)
 {
-#ifndef HAVE_GETLINE
 #define MAX_PASS_SIZE	128
 	char *buf;
 	int i;
+#ifndef _WIN32
+	struct termios old, new;
+
+	fflush(stdout);
+	if (tcgetattr (fileno (stdout), &old) != 0)
+		return -1;
+	new = old;
+	new.c_lflag &= ~ECHO;
+	if (tcsetattr (fileno (stdout), TCSAFLUSH, &new) != 0)
+		return -1;
+#endif
 
 	buf = calloc(1, MAX_PASS_SIZE);
 	if (!buf)
 		return -1;
 
 	for (i = 0; i < MAX_PASS_SIZE - 1; i++) {
+#ifndef _WIN32
+		buf[i] = getchar();
+#else
 		buf[i] = _getch();
+#endif
 		if (buf[i] == 0 || buf[i] == 3)
-			return -1;
+			break;
 		if (buf[i] == '\n' || buf[i] == '\r')
 			break;
 	}
+#ifndef _WIN32
+	tcsetattr (fileno (stdout), TCSAFLUSH, &old);
+	fputs("\n", stdout);
+#endif
+	if (buf[i] == 0 || buf[i] == 3)   {
+		free(buf);
+		return -1;
+	}
+
 	buf[i] = 0;
 
+	if (*lineptr && (!len || *len < i+1))   {
+		free(*lineptr);
+		*lineptr = NULL;
+	}
+
 	if (*lineptr) {
-		if (*len < i+1) {
-			free(*lineptr);
-			*lineptr=buf;
-			*len = MAX_PASS_SIZE;
-		} else {
-			memcpy(*lineptr,buf,i+1);
-			memset(buf, 0, MAX_PASS_SIZE);
-			free(buf);
-		}
+		memcpy(*lineptr,buf,i+1);
+		memset(buf, 0, MAX_PASS_SIZE);
+		free(buf);
 	} else {
 		*lineptr = buf;
 		if (len)
 			*len = MAX_PASS_SIZE;
 	}
 	return i;
-#else
-	struct termios old, new;
-	int nread;
-
-	/* Turn echoing off and fail if we can't. */
-	if (tcgetattr (fileno (stream), &old) != 0)
-		return -1;
-	new = old;
-	new.c_lflag &= ~ECHO;
-	if (tcsetattr (fileno (stream), TCSAFLUSH, &new) != 0)
-		return -1;
-
-	/* Read the password. */
-	nread = getline (lineptr, len, stream);
-	if (nread < 0)
-		return -1;
-
-	/* Remove trailing CR */
-	if (*(*lineptr + nread - 1) == '\n' || *(*lineptr + nread - 1) == '\r')
-		*(*lineptr + --nread) = '\0';
-
-	/* Restore terminal. */
-	(void) tcsetattr (fileno (stream), TCSAFLUSH, &old);
-	return nread;
-#endif
 }
 
_______________________________________________
opensc-devel mailing list
opensc-devel@lists.opensc-project.org
http://www.opensc-project.org/mailman/listinfo/opensc-devel

Reply via email to