- 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
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,
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

View File

@ -45,6 +45,7 @@ This release includes the following bugfixes:
o use SOCKS proxy with the multi interface
o fixed the Curl_getoff_all_pipelines SIGSEGV
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:
@ -58,6 +59,6 @@ advice from friends like these:
Kamil Dudka, Jim Freeman, Daniel Johnson, Toshio Kuratomi, Martin Storsjo,
Pramod Sharma, Gisle Vanem, Lenaic Lefever, Rainer Koenig, Sven Wegener,
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)

View File

@ -84,11 +84,6 @@ volatile int initialized = 0;
#define HANDSHAKE_TIMEOUT 30
typedef struct {
PRInt32 retryCount;
struct SessionHandle *data;
} pphrase_arg_t;
typedef struct {
const char *name;
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_OBJECT_CLASS objClass = CKO_PRIVATE_KEY;
CK_SLOT_ID slotID;
pphrase_arg_t *parg = NULL;
char slotname[SLOTSIZE];
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);
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() */
if(PK11_Authenticate(slot, PR_TRUE, parg) != SECSuccess) {
free(parg);
if(PK11_Authenticate(slot, PR_TRUE,
conn->data->set.str[STRING_KEY_PASSWD]) != SECSuccess) {
PK11_FreeSlot(slot);
return 0;
}
free(parg);
PK11_FreeSlot(slot);
return 1;
@ -588,25 +578,11 @@ static int cert_stuff(struct connectdata *conn,
static char * nss_get_password(PK11SlotInfo * slot, PRBool retry, void *arg)
{
pphrase_arg_t *parg;
parg = (pphrase_arg_t *) arg;
(void)slot; /* unused */
if(retry > 2)
if(retry || NULL == arg)
return NULL;
if(parg->data->set.str[STRING_KEY_PASSWD])
return (char *)PORT_Strdup((char *)parg->data->set.str[STRING_KEY_PASSWD]);
else
return NULL;
}
/* 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;
return (char *)PORT_Strdup((char *)arg);
}
static SECStatus nss_Init_Tokens(struct connectdata * conn)
@ -614,14 +590,6 @@ static SECStatus nss_Init_Tokens(struct connectdata * conn)
PK11SlotList *slotList;
PK11SlotListElement *listEntry;
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);
@ -644,7 +612,8 @@ static SECStatus nss_Init_Tokens(struct connectdata * conn)
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(PR_GetError() == SEC_ERROR_BAD_PASSWORD)
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;
break;
}
parg->retryCount = 0; /* reset counter to 0 for the next token */
PK11_FreeSlot(slot);
}
free(parg);
return status;
}
@ -1220,8 +1186,6 @@ CURLcode Curl_nss_connect(struct connectdata *conn, int sockindex)
curlerr = CURLE_SSL_CERTPROBLEM;
goto error;
}
PK11_SetPasswordFunc(nss_no_password);
}
else
connssl->client_nickname = NULL;