From 08cf6780ba8ea242cb451f07e14bb572079e22cf Mon Sep 17 00:00:00 2001 From: Daniel Stenberg Date: Wed, 8 Oct 2008 10:39:43 +0000 Subject: [PATCH] - Igor Novoseltsev brought a patch that introduced two new options to curl_easy_setopt: CURLOPT_USERNAME and CURLOPT_PASSWORD that sort of deprecates the good old CURLOPT_USERPWD since they allow applications to set the user name and password independently and perhaps more importantly allow both to contain colon(s) which CURLOPT_USERPWD doesn't fully support. --- CHANGES | 7 +++++ RELEASE-NOTES | 6 ++-- docs/KNOWN_BUGS | 8 ++--- docs/libcurl/curl_easy_setopt.3 | 24 ++++++++++++-- include/curl/curl.h | 4 +++ include/curl/typecheck-gcc.h | 2 ++ lib/url.c | 55 ++++++++++++++++++++++++++++----- lib/urldata.h | 3 +- 8 files changed, 92 insertions(+), 17 deletions(-) diff --git a/CHANGES b/CHANGES index 798c97c6e..c6de56ea6 100644 --- a/CHANGES +++ b/CHANGES @@ -6,6 +6,13 @@ Changelog +Daniel Stenberg (8 Oct 2008) +- Igor Novoseltsev brought a patch that introduced two new options to + curl_easy_setopt: CURLOPT_USERNAME and CURLOPT_PASSWORD that sort of + deprecates the good old CURLOPT_USERPWD since they allow applications to set + the user name and password independently and perhaps more importantly allow + both to contain colon(s) which CURLOPT_USERPWD doesn't fully support. + Daniel Fandrich (7 Oct 2008) - Changed the handling of read/write errors in Curl_perform() to allow a a fresh connection to be made in such cases and the request retransmitted. diff --git a/RELEASE-NOTES b/RELEASE-NOTES index 6ee074673..73ebdb74b 100644 --- a/RELEASE-NOTES +++ b/RELEASE-NOTES @@ -2,7 +2,7 @@ Curl and libcurl 7.19.1 Public curl releases: 107 Command line options: 128 - curl_easy_setopt() options: 154 + curl_easy_setopt() options: 156 Public functions in libcurl: 58 Known libcurl bindings: 37 Contributors: 672 @@ -14,6 +14,7 @@ This release includes the following changes: o Added CURLOPT_POSTREDIR o Better detect HTTP 1.0 servers and don't do HTTP 1.1 requests on them o configure --disable-proxy disables proxy + o Added CURLOPT_USERNAME and CURLOPT_PASSWORD This release includes the following bugfixes: @@ -48,6 +49,7 @@ advice from friends like these: Keith Mok, Yang Tse, Daniel Fandrich, Guenter Knauf, Dmitriy Sergeyev, Linus Nielsen Feltzing, Martin Drasar, Stefan Krause, Dmitry Kurochkin, Mike Revi, Andres Garcia, Michael Goffioul, Markus Moeller, Rob Crittenden, - Jamie Lokier, Emanuele Bovisio, Maxim Ivanov, Ian Lynagh, Daniel Egger + Jamie Lokier, Emanuele Bovisio, Maxim Ivanov, Ian Lynagh, Daniel Egger, + Igor Novoseltsev Thanks! (and sorry if I forgot to mention someone) diff --git a/docs/KNOWN_BUGS b/docs/KNOWN_BUGS index 2c263e72c..dcc693cb9 100644 --- a/docs/KNOWN_BUGS +++ b/docs/KNOWN_BUGS @@ -160,10 +160,10 @@ may have been fixed since this was written! doesn't do a HEAD first to get the initial size. This needs to be done manually for HTTP PUT resume to work, and then '-C [index]'. -7. CURLOPT_USERPWD and CURLOPT_PROXYUSERPWD have no way of providing user names - that contain a colon. This can't be fixed easily in a backwards compatible - way without adding new options (and then, they should most probably allow - setting user name and password separately). +7. CURLOPT_PROXYUSERPWD has no way of providing user names that contain a + colon. This can't be fixed easily in a backwards compatible way without + adding new options. CURLOPT_USERPWD was split into CURLOPT_USERNAME and + CURLOPT_PASSWORD for this reason. 6. libcurl ignores empty path parts in FTP URLs, whereas RFC1738 states that such parts should be sent to the server as 'CWD ' (without an argument). diff --git a/docs/libcurl/curl_easy_setopt.3 b/docs/libcurl/curl_easy_setopt.3 index 7d30fa697..36d956d94 100644 --- a/docs/libcurl/curl_easy_setopt.3 +++ b/docs/libcurl/curl_easy_setopt.3 @@ -601,14 +601,34 @@ to prevent accidental information leakage. Pass a char * as parameter, which should be [user name]:[password] to use for the connection to the HTTP proxy. Use \fICURLOPT_PROXYAUTH\fP to decide authentication method. +.IP CURLOPT_USERNAME +Pass a char * as parameter, which should be pointing to the zero terminated +user name to use for the transfer. + +The CURLOPT_USERNAME option should be used in same way as the +\fICURLOPT_USERPWD\fP is used. In comparison to \fICURLOPT_USERPWD\fP the +CURLOPT_USERNAME allows the username to contain colon, like in following +example: "sip:user@example.com". Note the CURLOPT_USERNAME option is an +alternative way to set the user name. There is no meaning to use it together +with the \fICURLOPT_USERPWD\fP option. + +In order to specify the password to be used in conjunction with the user name +use the \fICURLOPT_PASSWORD\fP option. (Added in 7.19.1) +.IP CURLOPT_PASSWORD +Pass a char * as parameter, which should be pointing to the zero terminated +password to use for the transfer. + +The CURLOPT_PASSWORD option should be used in conjunction with +as the \fICURLOPT_USERNAME\fP option. (Added in 7.19.1) .IP CURLOPT_HTTPAUTH Pass a long as parameter, which is set to a bitmask, to tell libcurl what authentication method(s) you want it to use. The available bits are listed below. If more than one bit is set, libcurl will first query the site to see what authentication methods it supports and then pick the best one you allow it to use. For some methods, this will induce an extra network round-trip. Set -the actual name and password with the \fICURLOPT_USERPWD\fP option. (Added in -7.10.6) +the actual name and password with the \fICURLOPT_USERPWD\fP option or +with the \fICURLOPT_USERNAME\fP and the \fICURLOPT_USERPASSWORD\fP options. +(Added in 7.10.6) .RS .IP CURLAUTH_BASIC HTTP Basic authentication. This is the default choice, and the only method diff --git a/include/curl/curl.h b/include/curl/curl.h index d93fd6764..d6db92fb7 100644 --- a/include/curl/curl.h +++ b/include/curl/curl.h @@ -1141,6 +1141,10 @@ typedef enum { working with OpenSSL-powered builds. */ CINIT(CERTINFO, LONG, 172), + /* "name" and "pwd" to use when fetching. */ + CINIT(USERNAME, OBJECTPOINT, 173), + CINIT(PASSWORD, OBJECTPOINT, 174), + CURLOPT_LASTENTRY /* the last unused */ } CURLoption; diff --git a/include/curl/typecheck-gcc.h b/include/curl/typecheck-gcc.h index bd0b0b7bb..33e264771 100644 --- a/include/curl/typecheck-gcc.h +++ b/include/curl/typecheck-gcc.h @@ -196,6 +196,8 @@ _CURL_WARNING(_curl_easy_getinfo_err_curl_slist, (option) == CURLOPT_INTERFACE || \ (option) == CURLOPT_NETRC_FILE || \ (option) == CURLOPT_USERPWD || \ + (option) == CURLOPT_USERNAME || \ + (option) == CURLOPT_PASSWORD || \ (option) == CURLOPT_PROXYUSERPWD || \ (option) == CURLOPT_ENCODING || \ (option) == CURLOPT_REFERER || \ diff --git a/lib/url.c b/lib/url.c index 17b34c68e..a1174a63b 100644 --- a/lib/url.c +++ b/lib/url.c @@ -1500,7 +1500,45 @@ CURLcode Curl_setopt(struct SessionHandle *data, CURLoption option, /* * user:password to use in the operation */ - result = setstropt(&data->set.str[STRING_USERPWD], + { + char* userpwd = va_arg(param, char *); + char* separator = strchr(userpwd, ':'); + if (separator != NULL) { + + /* store username part of option */ + char * p; + size_t username_len = (size_t)(separator-userpwd); + p = malloc(username_len+1); + if(!p) + result = CURLE_OUT_OF_MEMORY; + else { + memcpy(p, userpwd, username_len); + p[username_len] = '\0'; + data->set.str[STRING_USERNAME] = p; + } + + /* store password part of option */ + if (result == CURLE_OK) { + result = setstropt(&data->set.str[STRING_PASSWORD], separator+1); + } + } + else { + result = setstropt(&data->set.str[STRING_USERNAME], userpwd); + } + } + break; + case CURLOPT_USERNAME: + /* + * user:password to use in the operation + */ + result = setstropt(&data->set.str[STRING_USERNAME], + va_arg(param, char *)); + break; + case CURLOPT_PASSWORD: + /* + * user:password to use in the operation + */ + result = setstropt(&data->set.str[STRING_PASSWORD], va_arg(param, char *)); break; case CURLOPT_POSTQUOTE: @@ -3701,12 +3739,13 @@ static void override_userpass(struct SessionHandle *data, struct connectdata *conn, char *user, char *passwd) { - if(data->set.str[STRING_USERPWD] != NULL) { - /* the name is given, get user+password */ - sscanf(data->set.str[STRING_USERPWD], - "%" MAX_CURL_USER_LENGTH_TXT "[^:]:" - "%" MAX_CURL_PASSWORD_LENGTH_TXT "[^\n]", - user, passwd); + if(data->set.str[STRING_USERNAME] != NULL) { + strncpy(user, data->set.str[STRING_USERNAME], MAX_CURL_USER_LENGTH); + user[MAX_CURL_USER_LENGTH-1] = '\0'; /*To be on safe side*/ + } + if(data->set.str[STRING_PASSWORD] != NULL) { + strncpy(passwd, data->set.str[STRING_PASSWORD], MAX_CURL_PASSWORD_LENGTH); + passwd[MAX_CURL_PASSWORD_LENGTH-1] = '\0'; /*To be on safe side*/ } conn->bits.netrc = FALSE; @@ -3985,7 +4024,7 @@ static CURLcode create_conn(struct SessionHandle *data, && (conn->proxytype == CURLPROXY_HTTP)); - conn->bits.user_passwd = (bool)(NULL != data->set.str[STRING_USERPWD]); + conn->bits.user_passwd = (bool)(NULL != data->set.str[STRING_USERNAME]); conn->bits.proxy_user_passwd = (bool)(NULL != data->set.str[STRING_PROXYUSERPWD]); conn->bits.tunnel_proxy = data->set.tunnel_thru_httpproxy; conn->bits.ftp_use_epsv = data->set.ftp_use_epsv; diff --git a/lib/urldata.h b/lib/urldata.h index ee0df8c12..a1a95ef44 100644 --- a/lib/urldata.h +++ b/lib/urldata.h @@ -1334,10 +1334,11 @@ enum dupstring { STRING_SSL_EGDSOCKET, /* path to file containing the EGD daemon socket */ STRING_SSL_RANDOM_FILE, /* path to file containing "random" data */ STRING_USERAGENT, /* User-Agent string */ - STRING_USERPWD, /* , if used */ STRING_SSH_HOST_PUBLIC_KEY_MD5, /* md5 of host public key in ascii hex */ STRING_SSL_CRLFILE, /* crl file to check certificate */ STRING_SSL_ISSUERCERT, /* issuer cert file to check certificate */ + STRING_USERNAME, /* , if used */ + STRING_PASSWORD, /* , if used */ /* -- end of strings -- */ STRING_LAST /* not used, just an end-of-list marker */