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.
not sure if it is such a good idea to change this interface.
but the old interface with a pointer to some static data
isn't great either.
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-16 10:38:01.000000000 +0100
+++ opensc/src/tools/pkcs11-tool.c 2010-02-26 10:58:12.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,33 +940,56 @@ 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)
{
- char new_buf[21], *new_pin = NULL;
+ char *pin;
+ char *new_pin1 = NULL;
+ char *new_pin2 = NULL;
+ size_t len1, len2;
+ ssize_t r;
CK_TOKEN_INFO info;
CK_RV rv;
get_token_info(slot, &info);
- new_pin = opt_pin ? opt_pin : opt_new_pin;
-
if (!(info.flags & CKF_PROTECTED_AUTHENTICATION_PATH)) {
- if (new_pin == NULL) {
- new_pin = getpass("Please enter the new PIN: ");
- if (!new_pin || !*new_pin || strlen(new_pin) > 20)
+ if (! opt_pin && !opt_new_pin) {
+ printf("Please enter the new PIN: ");
+ r = util_getpass(&new_pin1,&len1,stdin);
+ if (r < 0)
+ util_fatal("No PIN entered, aborting.\n");
+ if (!new_pin1 || !*new_pin1 || strlen(new_pin1) > 20)
util_fatal("Invalid User PIN\n");
- strcpy(new_buf, new_pin);
- new_pin = getpass("Please enter the new PIN again: ");
- if (!new_pin || !*new_pin ||
- strcmp(new_buf, new_pin) != 0)
+ printf("Please enter the new PIN again: ");
+ r = util_getpass(&new_pin2,&len2,stdin);
+ if (r < 0)
+ util_fatal("No PIN entered, aborting.\n");
+ if (!new_pin2 || !*new_pin2 ||
+ strcmp(new_pin1, new_pin2) != 0)
util_fatal("Different new User PINs, exiting\n");
}
}
+
+ pin = opt_pin;
+ if (!pin) pin = opt_new_pin;
+ if (!pin) pin = new_pin1;
+
+ rv = p11->C_InitPIN(sess, (CK_UTF8CHAR *) pin, pin == NULL ? 0 : strlen(pin));
+
+ if (new_pin1) {
+ bzero(new_pin1,len1);
+ free(new_pin1);
+ }
+ if (new_pin2) {
+ bzero(new_pin2,len2);
+ free(new_pin2);
+ }
- rv = p11->C_InitPIN(sess,
- (CK_UTF8CHAR *) new_pin, new_pin == NULL ? 0 : strlen(new_pin));
if (rv != CKR_OK)
p11_fatal("C_InitPIN", rv);
printf("User PIN successfully initialized\n");
diff -udrNPp --exclude=.svn opensc.orig/src/tools/util.c opensc/src/tools/util.c
--- opensc.orig/src/tools/util.c 2010-02-16 10:38:01.000000000 +0100
+++ opensc/src/tools/util.c 2010-02-26 10:43:01.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,60 @@ util_warn(const char *fmt, ...)
va_end(ap);
}
+ssize_t util_getpass (char **lineptr, size_t *len, FILE *stream)
+{
+#ifdef _WIN32
+#define MAX_PASS_SIZE 128
+ char *buf;
+ size_t i,n;
+
+ buf = malloc(MAX_PASS_SIZE);
+ if (!buf)
+ return -1;
+ bzero(buf,MAX_PASS_SIZE);
+
+ for (i = 0; i < MAX_PASS_SIZE - 1; i++) {
+ buf[i] = _getch();
+ if (buf[i] == '\n' || buf[i] == 0)
+ break;
+ }
+ buf[i] = 0;
+
+ if (*lineptr) {
+ if (*len < i+1) {
+ free(*lineptr);
+ *lineptr=buf;
+ *len = MAX_PASS_SIZE;
+ } else {
+ memcpy(*lineptr,buf,i+1);
+ bzero(buf,MAX_PASS_SIZE);
+ free(buf);
+ }
+ } else {
+ *lineptr = buf;
+ if (len)
+ *len = MAX_PASS_SIZE;
+ }
+ return i;
+}
+#else
+ struct termios old, new;
+ ssize_t 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);
+
+ /* Restore terminal. */
+ (void) tcsetattr (fileno (stream), TCSAFLUSH, &old);
+ return nread;
+#endif
+}
+
diff -udrNPp --exclude=.svn opensc.orig/src/tools/util.h opensc/src/tools/util.h
--- opensc.orig/src/tools/util.h 2010-02-16 10:38:01.000000000 +0100
+++ opensc/src/tools/util.h 2010-02-26 10:19:04.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