man getpass:
       This function is obsolete.  Do not use it.

also this function reads from /dev/tty. why? it would
be much easier if it read from stdin, so we can passwords
from a script. (command line options are visible to other
users and stay in the shell history file, so putting a
secret pin or password in a parameter is not a good idea.)

and in some bug users complain, that we cannot abort pkcs15-init
with ctrl-c. maybe switching the input code will help here too.

attached is a patch that replaced getpass with example code
from glibc documentation. it doesn't compile on mingw yet
(mingw doesn't have termios, so we will need some #ifdef),
and I replaced only 3 of 20 getpass() calls so far.

please have a look and let me know if this is a good direction.

Regards, Andreas
diff -udrNPp --exclude=.svn opensc.orig/src/tools/pkcs11-tool.c opensc/src/tools/pkcs11-tool.c
--- opensc.orig/src/tools/pkcs11-tool.c	2010-02-01 08:03:21.000000000 +0100
+++ opensc/src/tools/pkcs11-tool.c	2010-02-04 08:17:10.000000000 +0100
@@ -24,7 +24,6 @@
 
 #include <opensc/pkcs11.h>
 #include <opensc/pkcs11-opensc.h>
-#include <compat_getpass.h>
 #include "util.h"
 
 #ifdef ENABLE_OPENSSL
@@ -848,6 +847,8 @@ static void list_objects(CK_SESSION_HAND
 static int login(CK_SESSION_HANDLE session, int login_type)
 {
 	char		*pin = NULL;
+	size_t		len;
+	int		pin_allocated = 0, r;
 	CK_TOKEN_INFO	info;
 	CK_RV		rv;
 
@@ -867,12 +868,16 @@ static int login(CK_SESSION_HANDLE sessi
 
 	if (!pin && (info.flags & CKF_LOGIN_REQUIRED) 
 			&& !(info.flags & CKF_PROTECTED_AUTHENTICATION_PATH))   {
-		if (login_type == CKU_SO)
-			pin = getpass("Please enter SO PIN: ");
+		if (login_type == CKU_SO) 
+			printf("Please enter SO PIN: ");
 		else if (login_type == CKU_USER)
-			pin = getpass("Please enter User PIN: ");
+			printf("Please enter User PIN: ");
 		else if (login_type == CKU_CONTEXT_SPECIFIC)
-			pin = getpass("Please enter Specific Context Secret Code: ");
+			printf("Please enter Specific Context Secret Code: ");
+		r = util_getpass(&pin,&len,stdin);
+		if (r < 0)
+			util_fatal("No PIN entered, exiting!\n");
+		pin_allocated = 1;
 	}
 	
 	if (!(info.flags & CKF_PROTECTED_AUTHENTICATION_PATH)
@@ -884,6 +889,8 @@ static int login(CK_SESSION_HANDLE sessi
 			(CK_UTF8CHAR *) pin, pin == NULL ? 0 : strlen(pin));
 	if (rv != CKR_OK)
 		p11_fatal("C_Login", rv);
+	if (pin_allocated)
+		free(pin);
 
 	return 0;
 }
@@ -892,6 +899,8 @@ static void init_token(CK_SLOT_ID slot)
 {
 	unsigned char token_label[33];
 	char new_buf[21], *new_pin = NULL;
+	size_t len;
+	int pin_allocated = 0, r;
 	CK_TOKEN_INFO	info;
 	CK_RV rv;
 
@@ -903,15 +912,22 @@ static void init_token(CK_SLOT_ID slot)
 	get_token_info(slot, &info);
 	if (!(info.flags & CKF_PROTECTED_AUTHENTICATION_PATH)) {
 		if (opt_so_pin == NULL) {
-			new_pin = getpass("Please enter the new SO PIN: ");
+			printf("Please enter the new SO PIN: ");
+			r = util_getpass(&new_pin,&len,stdin);
+			if (r < 0)
+				util_fatal("No PIN entered, exiting\n");
 			if (!new_pin || !*new_pin || strlen(new_pin) > 20)
 				util_fatal("Invalid SO PIN\n");
 			strcpy(new_buf, new_pin);
-			new_pin = getpass("Please enter the new SO PIN "
-					"(again): ");
+			free(new_pin); new_pin = NULL;
+			printf("Please enter the new SO PIN (again): ");
+			r = util_getpass(&new_pin,&len,stdin);
+			if (r < 0)
+				util_fatal("No PIN entered, exiting\n");
 			if (!new_pin || !*new_pin ||
 					strcmp(new_buf, new_pin) != 0)
 				util_fatal("Different new SO PINs, exiting\n");
+			pin_allocated = 1;
 		} else {
 			new_pin = opt_so_pin;
 		}
@@ -924,6 +940,9 @@ static void init_token(CK_SLOT_ID slot)
 	if (rv != CKR_OK)
 		p11_fatal("C_InitToken", rv);
 	printf("Token successfully initialized\n");
+
+	if (pin_allocated)
+		free(new_pin);
 }
 
 static void init_pin(CK_SLOT_ID slot, CK_SESSION_HANDLE sess)
diff -udrNPp --exclude=.svn opensc.orig/src/tools/util.c opensc/src/tools/util.c
--- opensc.orig/src/tools/util.c	2010-02-04 08:19:42.000000000 +0100
+++ opensc/src/tools/util.c	2010-02-04 07:39:37.000000000 +0100
@@ -5,6 +5,7 @@
 #include <stdlib.h>
 #include <stdarg.h>
 #include <ctype.h>
+#include <termios.h>
 #include "util.h"
 
 int util_connect_card(sc_context_t *ctx, sc_card_t **cardp,
@@ -281,3 +282,25 @@ util_warn(const char *fmt, ...)
 	va_end(ap);
 }
 
+ssize_t util_getpass (char **lineptr, size_t *n, FILE *stream)
+{
+	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, n, stream);
+
+	/* Restore terminal. */
+	(void) tcsetattr (fileno (stream), TCSAFLUSH, &old);
+
+	return nread;
+}
+
diff -udrNPp --exclude=.svn opensc.orig/src/tools/util.h opensc/src/tools/util.h
--- opensc.orig/src/tools/util.h	2010-02-01 08:03:21.000000000 +0100
+++ opensc/src/tools/util.h	2010-02-04 07:39:59.000000000 +0100
@@ -35,6 +35,8 @@ void util_fatal(const char *fmt, ...);
 /* All singing all dancing card connect routine */
 int util_connect_card(struct sc_context *, struct sc_card **, char *reader_id, int wait, int verbose);
 
+ssize_t util_getpass (char **lineptr, size_t *n, FILE *stream);
+
 #ifdef __cplusplus
 }
 #endif
_______________________________________________
opensc-devel mailing list
[email protected]
http://www.opensc-project.org/mailman/listinfo/opensc-devel

Reply via email to