Andreas Jellinghaus wrote:
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.
'For me works' slightly changed in the win32 part version of your patch.
If no objections
I'll change accordingly the other tools and close this ticket.
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
Kind wishes,
Viktor.
--
Viktor Tarasov <viktor.tara...@opentrust.com>
Index: src/tools/pkcs11-tool.c
===================================================================
--- src/tools/pkcs11-tool.c (révision 4244)
+++ src/tools/pkcs11-tool.c (copie de travail)
@@ -30,7 +30,6 @@
#include "pkcs11/pkcs11.h"
#include "pkcs11/pkcs11-opensc.h"
-#include "common/compat_getpass.h"
#include "util.h"
extern void *C_LoadModule(const char *name, CK_FUNCTION_LIST_PTR_PTR);
@@ -848,6 +847,8 @@
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 @@
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 @@
(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 @@
{
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 @@
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 @@
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;
+ int 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 *) new_pin, new_pin == NULL ? 0 : strlen(new_pin));
+ rv = p11->C_InitPIN(sess, (CK_UTF8CHAR *) pin, pin == NULL ? 0 :
strlen(pin));
+
+ if (new_pin1) {
+ memset(new_pin1, 0, len1);
+ free(new_pin1);
+ }
+ if (new_pin2) {
+ memset(new_pin2,0, len2);
+ free(new_pin2);
+ }
+
if (rv != CKR_OK)
p11_fatal("C_InitPIN", rv);
printf("User PIN successfully initialized\n");
@@ -962,24 +1001,35 @@
char new_buf[21], *new_pin = NULL;
CK_TOKEN_INFO info;
CK_RV rv;
+ int r;
+ size_t len;
get_token_info(slot, &info);
if (!(info.flags & CKF_PROTECTED_AUTHENTICATION_PATH)) {
- old_pin = getpass("Please enter the current PIN: ");
+ printf("Please enter the current PIN: ");
+ r = util_getpass(&old_pin, &len, stdin);
+ if (r < 0)
+ return 1;
if (!old_pin || !*old_pin || strlen(old_pin) > 20)
return 1;
strcpy(old_buf, old_pin);
old_pin = old_buf;
- new_pin = getpass("Please enter the new PIN: ");
+
+ printf("Please enter the new PIN: ");
+ r = util_getpass(&new_pin, &len, stdin);
+ if (r < 0)
+ return 1;
if (!new_pin || !*new_pin || strlen(new_pin) > 20)
return 1;
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(" different new PINs, exiting\n");
- return -1;
- }
+
+ printf("Please enter the new PIN again: ");
+ r = util_getpass(&new_pin, &len, stdin);
+ if (r < 0)
+ return 1;
+ if (!new_pin || !*new_pin || strcmp(new_buf, new_pin) != 0)
+ return 1;
}
rv = p11->C_SetPIN(sess,
@@ -999,6 +1049,8 @@
char new_buf[21], *new_pin = NULL;
CK_TOKEN_INFO info;
CK_RV rv;
+ int r;
+ size_t len;
get_token_info(slot, &info);
@@ -1011,10 +1063,13 @@
if (!(info.flags & CKF_PROTECTED_AUTHENTICATION_PATH) && !unlock_code)
{
if (login_type == CKU_CONTEXT_SPECIFIC)
- unlock_code = getpass("Please enter the 'Change PIN'
context secret code: ");
+ printf("Please enter the 'Change PIN' context secret
code: ");
else if (login_type == -1)
- unlock_code = getpass("Please enter unblock code for
User PIN: ");
+ printf("Please enter unblock code for User PIN: ");
+ r = util_getpass(&unlock_code,&len,stdin);
+ if (r < 0)
+ return 1;
if (!unlock_code || !*unlock_code || strlen(unlock_code) > 20)
return 1;
@@ -1024,9 +1079,16 @@
new_pin = opt_new_pin;
if (!(info.flags & CKF_PROTECTED_AUTHENTICATION_PATH) && !new_pin) {
- new_pin = getpass("Please enter the new PIN: ");
+ printf("Please enter the new PIN: ");
+ r = util_getpass(&new_pin, &len, stdin);
+ if (r < 0)
+ return 1;
strcpy(new_buf, new_pin);
- new_pin = getpass("Please enter the new PIN again: ");
+
+ printf("Please enter the new PIN again: ");
+ r = util_getpass(&new_pin, &len, stdin);
+ if (r < 0)
+ return 1;
if (!new_pin || !*new_pin || strcmp(new_buf, new_pin) != 0) {
printf(" different new PINs, exiting\n");
return -1;
Index: src/tools/util.c
===================================================================
--- src/tools/util.c (révision 4244)
+++ src/tools/util.c (copie de travail)
@@ -3,8 +3,10 @@
#include <stdio.h>
#include <stdlib.h>
#include <stdarg.h>
+#ifndef _WIN32
+#include <termios.h>
+#endif
#include <ctype.h>
-
#include "util.h"
int util_connect_card(sc_context_t *ctx, sc_card_t **cardp,
@@ -281,3 +283,66 @@
va_end(ap);
}
+int util_getpass (char **lineptr, size_t *len, FILE *stream)
+{
+#ifdef _WIN32
+#define MAX_PASS_SIZE 128
+ char *buf;
+ int i;
+
+ buf = calloc(1, MAX_PASS_SIZE);
+ if (!buf)
+ return -1;
+
+ for (i = 0; i < MAX_PASS_SIZE - 1; i++) {
+ buf[i] = _getch();
+ if (buf[i] == 0 || buf[i] == 3)
+ return -1;
+ if (buf[i] == '\n' || buf[i] == '\r')
+ break;
+ }
+ buf[i] = 0;
+
+ 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);
+ }
+ } 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
+}
+
Index: src/tools/util.h
===================================================================
--- src/tools/util.h (révision 4244)
+++ src/tools/util.h (copie de travail)
@@ -35,6 +35,8 @@
/* All singing all dancing card connect routine */
int util_connect_card(struct sc_context *, struct sc_card **, const char
*reader_id, int wait, int verbose);
+int util_getpass (char **lineptr, size_t *n, FILE *stream);
+
#ifdef __cplusplus
}
#endif
_______________________________________________
opensc-devel mailing list
opensc-devel@lists.opensc-project.org
http://www.opensc-project.org/mailman/listinfo/opensc-devel