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