From c099f9bcd16d073a5f122000b034604a53c55a18 Mon Sep 17 00:00:00 2001 From: Rob Crittenden Date: May 10 2017 14:35:39 +0000 Subject: When a token is configured in password file only authenticate once There is no need to spam a token with PIN attempts. Some tokens have a limit of auth failures before locking. https://pagure.io/mod_nss/issue/42 --- diff --git a/nss_engine_pphrase.c b/nss_engine_pphrase.c index 5f5498c..c2588bf 100644 --- a/nss_engine_pphrase.c +++ b/nss_engine_pphrase.c @@ -21,8 +21,12 @@ typedef struct { SSLModConfigRec *mc; server_rec *s; PRInt32 retryCount; + PRInt32 retryMax; } pphrase_arg_t; +#define PASSWORD_RETRIES_STANDARD 2 +#define PASSWORD_RETRIES_FILE 0 /* non-obvious but will try once */ + static char * nss_password_prompt(PK11SlotInfo *slot, PRBool retry, void *arg); static char * nss_no_password(PK11SlotInfo *slot, PRBool retry, void *arg); static char * nss_get_password(FILE *input, FILE *output, PK11SlotInfo *slot, PRBool (*ok)(unsigned char *), pphrase_arg_t * parg); @@ -52,8 +56,13 @@ SECStatus nss_Init_Tokens(server_rec *s) parg = (pphrase_arg_t*)malloc(sizeof(*parg)); parg->mc = mc; parg->retryCount = 0; + parg->retryMax = PASSWORD_RETRIES_STANDARD; parg->s = s; + if (parg->mc->pphrase_dialog_type == SSL_PPTYPE_FILE) { + parg->retryMax = PASSWORD_RETRIES_FILE; + } + PK11_SetPasswordFunc(nss_password_prompt); slotList = PK11_GetAllTokens(CKM_INVALID_MECHANISM, PR_FALSE, PR_TRUE, NULL); @@ -135,8 +144,8 @@ static char * nss_password_prompt(PK11SlotInfo *slot, PRBool retry, void *arg) /* should not happen */ passwd = nss_get_password(stdin, stdout, slot, nss_check_password, 0); } else { - if (parg->retryCount > 2) { - passwd = NULL; /* abort after 2 retries (3 failed attempts) */ + if (parg->retryCount > parg->retryMax) { + passwd = NULL; /* abort after n retries (n+1 failed attempts) */ } else { passwd = nss_get_password(stdin, stdout, slot, nss_check_password, parg); } @@ -351,6 +360,11 @@ static char *nss_get_password(FILE *input, FILE *output, if (pwdstr) return pwdstr; + /* The token isn't in the password file, prompt the standard # of times */ + if (parg->mc->pphrase_dialog_type == SSL_PPTYPE_FILE) { + parg->retryMax = PASSWORD_RETRIES_STANDARD; + } + for (;;) { /* Prompt for password */ if (isTTY) {