Curl_setopt: handle arbitrary-length username and password
libcurl truncates usernames, passwords, and options set with curl_easy_setopt to 255 (= MAX_CURL_PASSWORD_LENGTH - 1) characters. This doesn't affect the return value from curl_easy_setopt(), so from the caller's point of view, there is no sign anything strange has happened, except that authentication fails. For example: # Prepare a long (300-char) password. s=0123456789; s=$s$s$s$s$s$s$s$s$s$s; s=$s$s$s; # Start a server. nc -l -p 8888 | tee out & pid=$! # Tell curl to pass the password to the server. curl --user me:$s http://localhost:8888 & sleep 1; kill $pid # Extract the password. userpass=$( awk '/Authorization: Basic/ {print $3}' <out | tr -d '\r' | base64 -d ) password=${userpass#me:} echo ${#password} Expected result: 300 Actual result: 255 The fix is simple: allocate appropriately sized buffers on the heap instead of trying to squeeze the provided values into fixed-size on-stack buffers. Bug: http://bugs.debian.org/719856 Reported-by: Colby Ranger
This commit is contained in:
parent
36585b5395
commit
15f76bf7bb
29
lib/url.c
29
lib/url.c
@ -4793,23 +4793,29 @@ static CURLcode parse_remote_port(struct SessionHandle *data,
|
||||
* Override the login details from the URL with that in the CURLOPT_USERPWD
|
||||
* option or a .netrc file, if applicable.
|
||||
*/
|
||||
static void override_login(struct SessionHandle *data,
|
||||
struct connectdata *conn,
|
||||
char **userp, char **passwdp, char **optionsp)
|
||||
static int override_login(struct SessionHandle *data,
|
||||
struct connectdata *conn,
|
||||
char **userp, char **passwdp, char **optionsp)
|
||||
{
|
||||
if(data->set.str[STRING_USERNAME]) {
|
||||
strncpy(*userp, data->set.str[STRING_USERNAME], MAX_CURL_USER_LENGTH);
|
||||
(*userp)[MAX_CURL_USER_LENGTH - 1] = '\0'; /* To be on safe side */
|
||||
free(*userp);
|
||||
*userp = strdup(data->set.str[STRING_USERNAME]);
|
||||
if(!*userp)
|
||||
return CURLE_OUT_OF_MEMORY;
|
||||
}
|
||||
|
||||
if(data->set.str[STRING_PASSWORD]) {
|
||||
strncpy(*passwdp, data->set.str[STRING_PASSWORD], MAX_CURL_PASSWORD_LENGTH);
|
||||
(*passwdp)[MAX_CURL_PASSWORD_LENGTH - 1] = '\0'; /* To be on safe side */
|
||||
free(*passwdp);
|
||||
*passwdp = strdup(data->set.str[STRING_PASSWORD]);
|
||||
if(!*passwdp)
|
||||
return CURLE_OUT_OF_MEMORY;
|
||||
}
|
||||
|
||||
if(data->set.str[STRING_OPTIONS]) {
|
||||
strncpy(*optionsp, data->set.str[STRING_OPTIONS], MAX_CURL_OPTIONS_LENGTH);
|
||||
(*optionsp)[MAX_CURL_OPTIONS_LENGTH - 1] = '\0'; /* To be on safe side */
|
||||
free(*optionsp);
|
||||
*optionsp = strdup(data->set.str[STRING_OPTIONS]);
|
||||
if(!*optionsp)
|
||||
return CURLE_OUT_OF_MEMORY;
|
||||
}
|
||||
|
||||
conn->bits.netrc = FALSE;
|
||||
@ -4830,6 +4836,7 @@ static void override_login(struct SessionHandle *data,
|
||||
conn->bits.user_passwd = TRUE; /* enable user+password */
|
||||
}
|
||||
}
|
||||
return CURLE_OK;
|
||||
}
|
||||
|
||||
/*
|
||||
@ -5278,7 +5285,9 @@ static CURLcode create_conn(struct SessionHandle *data,
|
||||
|
||||
/* Check for overridden login details and set them accordingly so they
|
||||
they are known when protocol->setup_connection is called! */
|
||||
override_login(data, conn, &user, &passwd, &options);
|
||||
result = override_login(data, conn, &user, &passwd, &options);
|
||||
if(result != CURLE_OK)
|
||||
goto out;
|
||||
result = set_login(conn, user, passwd, options);
|
||||
if(result != CURLE_OK)
|
||||
goto out;
|
||||
|
Loading…
x
Reference in New Issue
Block a user