- Kamil Dudka provided a fix for libcurl-NSS reported by Michael Cronenworth

at https://bugzilla.redhat.com/show_bug.cgi?id=453612#c12

  If an incorrect password is given while loading a private key, libcurl ends
  up in an infinite loop consuming memory. The bug is critical.
This commit is contained in:
Daniel Stenberg 2009-05-11 09:13:49 +00:00
parent 56dab605f1
commit 6e1632c606
3 changed files with 16 additions and 45 deletions

View File

@ -7,6 +7,12 @@
Changelog Changelog
Daniel Stenberg (11 May 2009) Daniel Stenberg (11 May 2009)
- Kamil Dudka provided a fix for libcurl-NSS reported by Michael Cronenworth
at https://bugzilla.redhat.com/show_bug.cgi?id=453612#c12
If an incorrect password is given while loading a private key, libcurl ends
up in an infinite loop consuming memory. The bug is critical.
- I fixed the problem with doing NTLM, POST and then following a 302 redirect, - I fixed the problem with doing NTLM, POST and then following a 302 redirect,
as reported by Ebenezer Ikonne (on curl-users) and Laurent Rabret (on as reported by Ebenezer Ikonne (on curl-users) and Laurent Rabret (on
curl-library). The transfer was mistakenly marked to get more data to send curl-library). The transfer was mistakenly marked to get more data to send

View File

@ -45,6 +45,7 @@ This release includes the following bugfixes:
o use SOCKS proxy with the multi interface o use SOCKS proxy with the multi interface
o fixed the Curl_getoff_all_pipelines SIGSEGV o fixed the Curl_getoff_all_pipelines SIGSEGV
o POST, NTLM and following a redirect hang o POST, NTLM and following a redirect hang
o libcurl+NSS endless loop on incorrect password for private key
This release includes the following known bugs: This release includes the following known bugs:
@ -58,6 +59,6 @@ advice from friends like these:
Kamil Dudka, Jim Freeman, Daniel Johnson, Toshio Kuratomi, Martin Storsjo, Kamil Dudka, Jim Freeman, Daniel Johnson, Toshio Kuratomi, Martin Storsjo,
Pramod Sharma, Gisle Vanem, Lenaic Lefever, Rainer Koenig, Sven Wegener, Pramod Sharma, Gisle Vanem, Lenaic Lefever, Rainer Koenig, Sven Wegener,
Tim Chen, Constantine Sapuntzakis, David McCreedy, Michael Smith, Tim Chen, Constantine Sapuntzakis, David McCreedy, Michael Smith,
Colin Watson, Ebenezer Ikonne, Laurent Rabret Colin Watson, Ebenezer Ikonne, Laurent Rabret, Michael Cronenworth
Thanks! (and sorry if I forgot to mention someone) Thanks! (and sorry if I forgot to mention someone)

View File

@ -84,11 +84,6 @@ volatile int initialized = 0;
#define HANDSHAKE_TIMEOUT 30 #define HANDSHAKE_TIMEOUT 30
typedef struct {
PRInt32 retryCount;
struct SessionHandle *data;
} pphrase_arg_t;
typedef struct { typedef struct {
const char *name; const char *name;
int num; int num;
@ -483,7 +478,6 @@ static int nss_load_key(struct connectdata *conn, int sockindex, char *key_file)
CK_BBOOL cktrue = CK_TRUE; CK_BBOOL cktrue = CK_TRUE;
CK_OBJECT_CLASS objClass = CKO_PRIVATE_KEY; CK_OBJECT_CLASS objClass = CKO_PRIVATE_KEY;
CK_SLOT_ID slotID; CK_SLOT_ID slotID;
pphrase_arg_t *parg = NULL;
char slotname[SLOTSIZE]; char slotname[SLOTSIZE];
struct ssl_connect_data *sslconn = &conn->ssl[sockindex]; struct ssl_connect_data *sslconn = &conn->ssl[sockindex];
@ -516,17 +510,13 @@ static int nss_load_key(struct connectdata *conn, int sockindex, char *key_file)
SECMOD_WaitForAnyTokenEvent(mod, 0, 0); SECMOD_WaitForAnyTokenEvent(mod, 0, 0);
PK11_IsPresent(slot); PK11_IsPresent(slot);
parg = malloc(sizeof(pphrase_arg_t));
if(!parg)
return 0;
parg->retryCount = 0;
parg->data = conn->data;
/* parg is initialized in nss_Init_Tokens() */ /* parg is initialized in nss_Init_Tokens() */
if(PK11_Authenticate(slot, PR_TRUE, parg) != SECSuccess) { if(PK11_Authenticate(slot, PR_TRUE,
free(parg); conn->data->set.str[STRING_KEY_PASSWD]) != SECSuccess) {
PK11_FreeSlot(slot);
return 0; return 0;
} }
free(parg);
PK11_FreeSlot(slot); PK11_FreeSlot(slot);
return 1; return 1;
@ -588,25 +578,11 @@ static int cert_stuff(struct connectdata *conn,
static char * nss_get_password(PK11SlotInfo * slot, PRBool retry, void *arg) static char * nss_get_password(PK11SlotInfo * slot, PRBool retry, void *arg)
{ {
pphrase_arg_t *parg;
parg = (pphrase_arg_t *) arg;
(void)slot; /* unused */ (void)slot; /* unused */
if(retry > 2) if(retry || NULL == arg)
return NULL; return NULL;
if(parg->data->set.str[STRING_KEY_PASSWD])
return (char *)PORT_Strdup((char *)parg->data->set.str[STRING_KEY_PASSWD]);
else else
return NULL; return (char *)PORT_Strdup((char *)arg);
}
/* No longer ask for the password, parg has been freed */
static char * nss_no_password(PK11SlotInfo *slot, PRBool retry, void *arg)
{
(void)slot; /* unused */
(void)retry; /* unused */
(void)arg; /* unused */
return NULL;
} }
static SECStatus nss_Init_Tokens(struct connectdata * conn) static SECStatus nss_Init_Tokens(struct connectdata * conn)
@ -614,14 +590,6 @@ static SECStatus nss_Init_Tokens(struct connectdata * conn)
PK11SlotList *slotList; PK11SlotList *slotList;
PK11SlotListElement *listEntry; PK11SlotListElement *listEntry;
SECStatus ret, status = SECSuccess; SECStatus ret, status = SECSuccess;
pphrase_arg_t *parg = NULL;
parg = malloc(sizeof(pphrase_arg_t));
if(!parg)
return SECFailure;
parg->retryCount = 0;
parg->data = conn->data;
PK11_SetPasswordFunc(nss_get_password); PK11_SetPasswordFunc(nss_get_password);
@ -644,7 +612,8 @@ static SECStatus nss_Init_Tokens(struct connectdata * conn)
continue; continue;
} }
ret = PK11_Authenticate(slot, PR_TRUE, parg); ret = PK11_Authenticate(slot, PR_TRUE,
conn->data->set.str[STRING_KEY_PASSWD]);
if(SECSuccess != ret) { if(SECSuccess != ret) {
if(PR_GetError() == SEC_ERROR_BAD_PASSWORD) if(PR_GetError() == SEC_ERROR_BAD_PASSWORD)
infof(conn->data, "The password for token '%s' is incorrect\n", infof(conn->data, "The password for token '%s' is incorrect\n",
@ -652,12 +621,9 @@ static SECStatus nss_Init_Tokens(struct connectdata * conn)
status = SECFailure; status = SECFailure;
break; break;
} }
parg->retryCount = 0; /* reset counter to 0 for the next token */
PK11_FreeSlot(slot); PK11_FreeSlot(slot);
} }
free(parg);
return status; return status;
} }
@ -1220,8 +1186,6 @@ CURLcode Curl_nss_connect(struct connectdata *conn, int sockindex)
curlerr = CURLE_SSL_CERTPROBLEM; curlerr = CURLE_SSL_CERTPROBLEM;
goto error; goto error;
} }
PK11_SetPasswordFunc(nss_no_password);
} }
else else
connssl->client_nickname = NULL; connssl->client_nickname = NULL;