Loading lib/memdebug.c +3 −1 Original line number Diff line number Diff line Loading @@ -49,7 +49,9 @@ struct memdebug { int size; char mem[1]; double mem[1]; /* I'm hoping this is the thing with the strictest alignment * requirements. That also means we waste some space :-( */ }; /* Loading lib/netrc.c +46 −6 Original line number Diff line number Diff line Loading @@ -79,11 +79,14 @@ int Curl_parsenetrc(char *host, char netrcbuffer[256]; int retcode=1; int specific_login = (login[0] != 0); char *home = NULL; int state=NOTHING; char state_login=0; char state_password=0; char state_login=0; /* Found a login keyword */ char state_password=0; /* Found a password keyword */ char state_our_login=0; /* With specific_login, found *our* login name */ #define NETRC DOT_CHAR "netrc" Loading Loading @@ -116,6 +119,30 @@ int Curl_parsenetrc(char *host, sprintf(netrcbuffer, "%s%s%s", home, DIR_CHAR, NETRC); #ifdef MALLOCDEBUG { /* This is a hack to allow testing. * If compiled with --enable-debug and CURL_DEBUG_NETRC is defined, * then it's the path to a substitute .netrc for testing purposes *only* */ char *override = curl_getenv("CURL_DEBUG_NETRC"); if (override != NULL) { printf("NETRC: overridden .netrc file: %s\n", home); if (strlen(override)+1 > sizeof(netrcbuffer)) { free(override); if(NULL==pw) free(home); return -1; } strcpy(netrcbuffer, override); free(override); } } #endif /* MALLOCDEBUG */ file = fopen(netrcbuffer, "r"); if(file) { char *tok; Loading @@ -123,6 +150,10 @@ int Curl_parsenetrc(char *host, while(fgets(netrcbuffer, sizeof(netrcbuffer), file)) { tok=strtok_r(netrcbuffer, " \t\n", &tok_buf); while(tok) { if (login[0] && password[0]) goto done; switch(state) { case NOTHING: if(strequal("machine", tok)) { Loading @@ -149,17 +180,23 @@ int Curl_parsenetrc(char *host, case HOSTVALID: /* we are now parsing sub-keywords concerning "our" host */ if(state_login) { if (specific_login) { state_our_login = strequal(login, tok); }else{ strncpy(login, tok, LOGINSIZE-1); #ifdef _NETRC_DEBUG printf("LOGIN: %s\n", login); #endif } state_login=0; } else if(state_password) { if (state_our_login || !specific_login) { strncpy(password, tok, PASSWORDSIZE-1); #ifdef _NETRC_DEBUG printf("PASSWORD: %s\n", password); #endif } state_password=0; } else if(strequal("login", tok)) Loading @@ -169,13 +206,16 @@ int Curl_parsenetrc(char *host, else if(strequal("machine", tok)) { /* ok, there's machine here go => */ state = HOSTFOUND; state_our_login = 0; } break; } /* switch (state) */ tok = strtok_r(NULL, " \t\n", &tok_buf); } /* while (tok) */ } /* while fgets() */ done: fclose(file); } Loading lib/netrc.h +5 −0 Original line number Diff line number Diff line Loading @@ -25,4 +25,9 @@ int Curl_parsenetrc(char *host, char *login, char *password); /* Assume: password[0]=0, host[0] != 0. * If login[0] = 0, search for login and password within a machine section * in the netrc. * If login[0] != 0, search for password within machine and login. */ #endif lib/url.c +162 −131 Original line number Diff line number Diff line Loading @@ -441,7 +441,7 @@ CURLcode Curl_setopt(struct SessionHandle *data, CURLoption option, ...) /* * Parse the $HOME/.netrc file */ data->set.use_netrc = va_arg(param, long)?TRUE:FALSE; data->set.use_netrc = va_arg(param, long); break; case CURLOPT_FOLLOWLOCATION: /* Loading Loading @@ -1351,7 +1351,6 @@ static CURLcode CreateConnection(struct SessionHandle *data, char resumerange[40]=""; struct connectdata *conn; struct connectdata *conn_temp; char endbracket; int urllen; Curl_addrinfo *hostaddr; #ifdef HAVE_ALARM Loading Loading @@ -1533,35 +1532,12 @@ static CURLcode CreateConnection(struct SessionHandle *data, buf = data->state.buffer; /* this is our buffer */ /************************************************************* * Take care of user and password authentication stuff *************************************************************/ if(conn->bits.user_passwd && !data->set.use_netrc) { data->state.user[0] =0; data->state.passwd[0]=0; if(*data->set.userpwd != ':') { /* the name is given, get user+password */ sscanf(data->set.userpwd, "%127[^:]:%127[^\n]", data->state.user, data->state.passwd); } else /* no name given, get the password only */ sscanf(data->set.userpwd+1, "%127[^\n]", data->state.passwd); /* check for password, if no ask for one */ if( !data->state.passwd[0] ) { if(!data->set.fpasswd || data->set.fpasswd(data->set.passwd_client, "password:", data->state.passwd, sizeof(data->state.passwd))) { failf(data, "Bad password from password callback"); return CURLE_BAD_PASSWORD_ENTERED; } } } /* * So if the URL was A://B/C, * conn->protostr is A * conn->gname is B * conn->path is /C */ /************************************************************* * Take care of proxy authentication stuff Loading Loading @@ -1843,7 +1819,7 @@ static CURLcode CreateConnection(struct SessionHandle *data, } if(type) { char command; *type=0; *type=0; /* it was in the middle of the hostname */ command = toupper(type[6]); switch(command) { case 'A': /* ASCII mode */ Loading Loading @@ -1911,86 +1887,6 @@ static CURLcode CreateConnection(struct SessionHandle *data, return CURLE_UNSUPPORTED_PROTOCOL; } /************************************************************* * .netrc scanning coming up *************************************************************/ if(data->set.use_netrc) { if(Curl_parsenetrc(conn->hostname, data->state.user, data->state.passwd)) { infof(data, "Couldn't find host %s in the .netrc file, using defaults", conn->hostname); } else conn->bits.user_passwd = 1; /* enable user+password */ /* weather we failed or not, we don't know which fields that were filled in anyway */ if(!data->state.user[0]) strcpy(data->state.user, CURL_DEFAULT_USER); if(!data->state.passwd[0]) strcpy(data->state.passwd, CURL_DEFAULT_PASSWORD); } else if(!(conn->bits.user_passwd) && (conn->protocol & (PROT_FTP|PROT_HTTP)) ) { /* This is a FTP or HTTP URL, and we haven't got the user+password in * the extra parameter, we will now try to extract the possible * user+password pair in a string like: * ftp://user:password@ftp.my.site:8021/README */ char *ptr=NULL; /* assign to remove possible warnings */ if((ptr=strchr(conn->name, '@'))) { /* there's a user+password given here, to the left of the @ */ data->state.user[0] =0; data->state.passwd[0]=0; if(*conn->name != ':') { /* the name is given, get user+password */ sscanf(conn->name, "%127[^:@]:%127[^@]", data->state.user, data->state.passwd); } else /* no name given, get the password only */ sscanf(conn->name+1, "%127[^@]", data->state.passwd); if(data->state.user[0]) { char *newname=curl_unescape(data->state.user, 0); if(strlen(newname) < sizeof(data->state.user)) { strcpy(data->state.user, newname); } /* if the new name is longer than accepted, then just use the unconverted name, it'll be wrong but what the heck */ free(newname); } /* check for password, if no ask for one */ if( !data->state.passwd[0] ) { if(!data->set.fpasswd || data->set.fpasswd(data->set.passwd_client, "password:", data->state.passwd, sizeof(data->state.passwd))) { failf(data, "Bad password from password callback"); return CURLE_BAD_PASSWORD_ENTERED; } } else { /* we have a password found in the URL, decode it! */ char *newpasswd=curl_unescape(data->state.passwd, 0); if(strlen(newpasswd) < sizeof(data->state.passwd)) { strcpy(data->state.passwd, newpasswd); } free(newpasswd); } conn->name = ++ptr; conn->bits.user_passwd=TRUE; /* enable user+password */ } else { strcpy(data->state.user, CURL_DEFAULT_USER); strcpy(data->state.passwd, CURL_DEFAULT_PASSWORD); } } /************************************************************* * Figure out the remote port number * Loading @@ -1999,29 +1895,32 @@ static CURLcode CreateConnection(struct SessionHandle *data, * * To be able to detect port number flawlessly, we must not confuse them * IPv6-specified addresses in the [0::1] style. (RFC2732) * * The conn->name is currently [user:passwd@]host[:port] where host could * be a hostname, IPv4 address or IPv6 address. *************************************************************/ if((1 == sscanf(conn->name, "[%*39[0-9a-fA-F:.]%c", &endbracket)) && (']' == endbracket)) { /* This is a (IPv6-style) specified IP-address. We support _any_ IP within brackets to be really generic. */ conn->name++; /* pass the starting bracket */ tmp = strrchr(conn->name, ':'); tmp = strchr(conn->name, ']'); *tmp = 0; /* zero terminate */ if (tmp) { char *rest; unsigned long port; tmp++; /* pass the ending bracket */ if(':' != *tmp) tmp = NULL; /* no port number available */ } else { /* traditional IPv4-style port-extracting */ tmp = strchr(conn->name, ':'); port=strtoul(tmp+1, &rest, 10); /* Port number must be decimal */ if (rest != (tmp+1) && *rest == '\0') { /* The colon really did have only digits after it, * so it is either a port number or a mistake */ if (port > 0xffff) { /* Single unix standard says port numbers are * 16 bits long */ failf(data, "Port number too large: %lu", port); return CURLE_URL_MALFORMAT; } if (tmp) { *tmp++ = '\0'; /* cut off the name there */ conn->remote_port = atoi(tmp); *tmp = '\0'; /* cut off the name there */ conn->remote_port = port; } } if(data->change.proxy) { Loading Loading @@ -2075,6 +1974,138 @@ static CURLcode CreateConnection(struct SessionHandle *data, free(proxydup); /* free the duplicate pointer and not the modified */ } /************************************************************* * Take care of user and password authentication stuff *************************************************************/ /* * Inputs: data->set.userpwd (CURLOPT_USERPWD) * data->set.fpasswd (CURLOPT_PASSWDFUNCTION) * data->set.use_netrc (CURLOPT_NETRC) * conn->hostname * netrc file * hard-coded defaults * * Outputs: (almost :- all currently undefined) * conn->bits.user_passwd - non-zero if non-default passwords exist * conn->state.user - non-zero length if defined * conn->state.passwd - ditto * conn->hostname - remove user name and password */ /* At this point, we're hoping all the other special cases have * been taken care of, so conn->hostname is at most * [user[:password]]@]hostname * * We need somewhere to put the embedded details, so do that first. */ data->state.user[0] =0; /* to make everything well-defined */ data->state.passwd[0]=0; if (conn->protocol & (PROT_FTP|PROT_HTTP)) { /* This is a FTP or HTTP URL, we will now try to extract the possible * user+password pair in a string like: * ftp://user:password@ftp.my.site:8021/README */ char *ptr=strchr(conn->name, '@'); char *userpass = conn->name; if(ptr != NULL) { /* there's a user+password given here, to the left of the @ */ conn->name = conn->hostname = ++ptr; /* So the hostname is sane. Only bother interpreting the * results if we could care. It could still be wasted * work because it might be overtaken by the programmatically * set user/passwd, but doing that first adds more cases here :-( */ if (data->set.use_netrc != CURL_NETRC_REQUIRED) { /* We could use the one in the URL */ conn->bits.user_passwd = 1; /* enable user+password */ if(*userpass != ':') { /* the name is given, get user+password */ sscanf(userpass, "%127[^:@]:%127[^@]", data->state.user, data->state.passwd); } else /* no name given, get the password only */ sscanf(userpass, ":%127[^@]", data->state.passwd); if(data->state.user[0]) { char *newname=curl_unescape(data->state.user, 0); if(strlen(newname) < sizeof(data->state.user)) { strcpy(data->state.user, newname); } /* if the new name is longer than accepted, then just use the unconverted name, it'll be wrong but what the heck */ free(newname); } if (data->state.passwd[0]) { /* we have a password found in the URL, decode it! */ char *newpasswd=curl_unescape(data->state.passwd, 0); if(strlen(newpasswd) < sizeof(data->state.passwd)) { strcpy(data->state.passwd, newpasswd); } free(newpasswd); } } } } /* Programmatically set password: * - always applies, if available * - takes precedence over the values we just set above * so scribble it over the top. * User-supplied passwords are assumed not to need unescaping. * * user_password is set in "inherite initial knowledge' above, * so it doesn't have to be set in this block */ if (data->set.userpwd != NULL) { if(*data->set.userpwd != ':') { /* the name is given, get user+password */ sscanf(data->set.userpwd, "%127[^:]:%127[^\n]", data->state.user, data->state.passwd); } else /* no name given, get the password only */ sscanf(data->set.userpwd+1, "%127[^\n]", data->state.passwd); } if (data->set.use_netrc != CURL_NETRC_IGNORED && data->state.passwd[0] == '\0' ) { /* need passwd */ if(Curl_parsenetrc(conn->hostname, data->state.user, data->state.passwd)) { infof(data, "Couldn't find host %s in the .netrc file, using defaults", conn->hostname); } else conn->bits.user_passwd = 1; /* enable user+password */ } /* if we have a user but no password, ask for one */ if(conn->bits.user_passwd && !data->state.passwd[0] ) { if(!data->set.fpasswd || data->set.fpasswd(data->set.passwd_client, "password:", data->state.passwd, sizeof(data->state.passwd))) return CURLE_BAD_PASSWORD_ENTERED; } /* So we could have a password but no user; that's just too bad. */ /* If our protocol needs a password and we have none, use the defaults */ if ( (conn->protocol & (PROT_FTP|PROT_HTTP)) && !conn->bits.user_passwd) { strcpy(data->state.user, CURL_DEFAULT_USER); strcpy(data->state.passwd, CURL_DEFAULT_PASSWORD); /* This is the default password, so DON'T set conn->bits.user_passwd */ } /************************************************************* * Check the current list of connections to see if we can * re-use an already existing one or if we have to create a Loading lib/urldata.h +2 −1 Original line number Diff line number Diff line Loading @@ -650,7 +650,8 @@ struct UserDefined { bool no_body; bool set_port; bool upload; bool use_netrc; enum CURL_NETRC_OPTION use_netrc; /* defined in include/curl.h */ bool verbose; bool krb4; /* kerberos4 connection requested */ bool reuse_forbid; /* forbidden to be reused, close after use */ Loading Loading
lib/memdebug.c +3 −1 Original line number Diff line number Diff line Loading @@ -49,7 +49,9 @@ struct memdebug { int size; char mem[1]; double mem[1]; /* I'm hoping this is the thing with the strictest alignment * requirements. That also means we waste some space :-( */ }; /* Loading
lib/netrc.c +46 −6 Original line number Diff line number Diff line Loading @@ -79,11 +79,14 @@ int Curl_parsenetrc(char *host, char netrcbuffer[256]; int retcode=1; int specific_login = (login[0] != 0); char *home = NULL; int state=NOTHING; char state_login=0; char state_password=0; char state_login=0; /* Found a login keyword */ char state_password=0; /* Found a password keyword */ char state_our_login=0; /* With specific_login, found *our* login name */ #define NETRC DOT_CHAR "netrc" Loading Loading @@ -116,6 +119,30 @@ int Curl_parsenetrc(char *host, sprintf(netrcbuffer, "%s%s%s", home, DIR_CHAR, NETRC); #ifdef MALLOCDEBUG { /* This is a hack to allow testing. * If compiled with --enable-debug and CURL_DEBUG_NETRC is defined, * then it's the path to a substitute .netrc for testing purposes *only* */ char *override = curl_getenv("CURL_DEBUG_NETRC"); if (override != NULL) { printf("NETRC: overridden .netrc file: %s\n", home); if (strlen(override)+1 > sizeof(netrcbuffer)) { free(override); if(NULL==pw) free(home); return -1; } strcpy(netrcbuffer, override); free(override); } } #endif /* MALLOCDEBUG */ file = fopen(netrcbuffer, "r"); if(file) { char *tok; Loading @@ -123,6 +150,10 @@ int Curl_parsenetrc(char *host, while(fgets(netrcbuffer, sizeof(netrcbuffer), file)) { tok=strtok_r(netrcbuffer, " \t\n", &tok_buf); while(tok) { if (login[0] && password[0]) goto done; switch(state) { case NOTHING: if(strequal("machine", tok)) { Loading @@ -149,17 +180,23 @@ int Curl_parsenetrc(char *host, case HOSTVALID: /* we are now parsing sub-keywords concerning "our" host */ if(state_login) { if (specific_login) { state_our_login = strequal(login, tok); }else{ strncpy(login, tok, LOGINSIZE-1); #ifdef _NETRC_DEBUG printf("LOGIN: %s\n", login); #endif } state_login=0; } else if(state_password) { if (state_our_login || !specific_login) { strncpy(password, tok, PASSWORDSIZE-1); #ifdef _NETRC_DEBUG printf("PASSWORD: %s\n", password); #endif } state_password=0; } else if(strequal("login", tok)) Loading @@ -169,13 +206,16 @@ int Curl_parsenetrc(char *host, else if(strequal("machine", tok)) { /* ok, there's machine here go => */ state = HOSTFOUND; state_our_login = 0; } break; } /* switch (state) */ tok = strtok_r(NULL, " \t\n", &tok_buf); } /* while (tok) */ } /* while fgets() */ done: fclose(file); } Loading
lib/netrc.h +5 −0 Original line number Diff line number Diff line Loading @@ -25,4 +25,9 @@ int Curl_parsenetrc(char *host, char *login, char *password); /* Assume: password[0]=0, host[0] != 0. * If login[0] = 0, search for login and password within a machine section * in the netrc. * If login[0] != 0, search for password within machine and login. */ #endif
lib/url.c +162 −131 Original line number Diff line number Diff line Loading @@ -441,7 +441,7 @@ CURLcode Curl_setopt(struct SessionHandle *data, CURLoption option, ...) /* * Parse the $HOME/.netrc file */ data->set.use_netrc = va_arg(param, long)?TRUE:FALSE; data->set.use_netrc = va_arg(param, long); break; case CURLOPT_FOLLOWLOCATION: /* Loading Loading @@ -1351,7 +1351,6 @@ static CURLcode CreateConnection(struct SessionHandle *data, char resumerange[40]=""; struct connectdata *conn; struct connectdata *conn_temp; char endbracket; int urllen; Curl_addrinfo *hostaddr; #ifdef HAVE_ALARM Loading Loading @@ -1533,35 +1532,12 @@ static CURLcode CreateConnection(struct SessionHandle *data, buf = data->state.buffer; /* this is our buffer */ /************************************************************* * Take care of user and password authentication stuff *************************************************************/ if(conn->bits.user_passwd && !data->set.use_netrc) { data->state.user[0] =0; data->state.passwd[0]=0; if(*data->set.userpwd != ':') { /* the name is given, get user+password */ sscanf(data->set.userpwd, "%127[^:]:%127[^\n]", data->state.user, data->state.passwd); } else /* no name given, get the password only */ sscanf(data->set.userpwd+1, "%127[^\n]", data->state.passwd); /* check for password, if no ask for one */ if( !data->state.passwd[0] ) { if(!data->set.fpasswd || data->set.fpasswd(data->set.passwd_client, "password:", data->state.passwd, sizeof(data->state.passwd))) { failf(data, "Bad password from password callback"); return CURLE_BAD_PASSWORD_ENTERED; } } } /* * So if the URL was A://B/C, * conn->protostr is A * conn->gname is B * conn->path is /C */ /************************************************************* * Take care of proxy authentication stuff Loading Loading @@ -1843,7 +1819,7 @@ static CURLcode CreateConnection(struct SessionHandle *data, } if(type) { char command; *type=0; *type=0; /* it was in the middle of the hostname */ command = toupper(type[6]); switch(command) { case 'A': /* ASCII mode */ Loading Loading @@ -1911,86 +1887,6 @@ static CURLcode CreateConnection(struct SessionHandle *data, return CURLE_UNSUPPORTED_PROTOCOL; } /************************************************************* * .netrc scanning coming up *************************************************************/ if(data->set.use_netrc) { if(Curl_parsenetrc(conn->hostname, data->state.user, data->state.passwd)) { infof(data, "Couldn't find host %s in the .netrc file, using defaults", conn->hostname); } else conn->bits.user_passwd = 1; /* enable user+password */ /* weather we failed or not, we don't know which fields that were filled in anyway */ if(!data->state.user[0]) strcpy(data->state.user, CURL_DEFAULT_USER); if(!data->state.passwd[0]) strcpy(data->state.passwd, CURL_DEFAULT_PASSWORD); } else if(!(conn->bits.user_passwd) && (conn->protocol & (PROT_FTP|PROT_HTTP)) ) { /* This is a FTP or HTTP URL, and we haven't got the user+password in * the extra parameter, we will now try to extract the possible * user+password pair in a string like: * ftp://user:password@ftp.my.site:8021/README */ char *ptr=NULL; /* assign to remove possible warnings */ if((ptr=strchr(conn->name, '@'))) { /* there's a user+password given here, to the left of the @ */ data->state.user[0] =0; data->state.passwd[0]=0; if(*conn->name != ':') { /* the name is given, get user+password */ sscanf(conn->name, "%127[^:@]:%127[^@]", data->state.user, data->state.passwd); } else /* no name given, get the password only */ sscanf(conn->name+1, "%127[^@]", data->state.passwd); if(data->state.user[0]) { char *newname=curl_unescape(data->state.user, 0); if(strlen(newname) < sizeof(data->state.user)) { strcpy(data->state.user, newname); } /* if the new name is longer than accepted, then just use the unconverted name, it'll be wrong but what the heck */ free(newname); } /* check for password, if no ask for one */ if( !data->state.passwd[0] ) { if(!data->set.fpasswd || data->set.fpasswd(data->set.passwd_client, "password:", data->state.passwd, sizeof(data->state.passwd))) { failf(data, "Bad password from password callback"); return CURLE_BAD_PASSWORD_ENTERED; } } else { /* we have a password found in the URL, decode it! */ char *newpasswd=curl_unescape(data->state.passwd, 0); if(strlen(newpasswd) < sizeof(data->state.passwd)) { strcpy(data->state.passwd, newpasswd); } free(newpasswd); } conn->name = ++ptr; conn->bits.user_passwd=TRUE; /* enable user+password */ } else { strcpy(data->state.user, CURL_DEFAULT_USER); strcpy(data->state.passwd, CURL_DEFAULT_PASSWORD); } } /************************************************************* * Figure out the remote port number * Loading @@ -1999,29 +1895,32 @@ static CURLcode CreateConnection(struct SessionHandle *data, * * To be able to detect port number flawlessly, we must not confuse them * IPv6-specified addresses in the [0::1] style. (RFC2732) * * The conn->name is currently [user:passwd@]host[:port] where host could * be a hostname, IPv4 address or IPv6 address. *************************************************************/ if((1 == sscanf(conn->name, "[%*39[0-9a-fA-F:.]%c", &endbracket)) && (']' == endbracket)) { /* This is a (IPv6-style) specified IP-address. We support _any_ IP within brackets to be really generic. */ conn->name++; /* pass the starting bracket */ tmp = strrchr(conn->name, ':'); tmp = strchr(conn->name, ']'); *tmp = 0; /* zero terminate */ if (tmp) { char *rest; unsigned long port; tmp++; /* pass the ending bracket */ if(':' != *tmp) tmp = NULL; /* no port number available */ } else { /* traditional IPv4-style port-extracting */ tmp = strchr(conn->name, ':'); port=strtoul(tmp+1, &rest, 10); /* Port number must be decimal */ if (rest != (tmp+1) && *rest == '\0') { /* The colon really did have only digits after it, * so it is either a port number or a mistake */ if (port > 0xffff) { /* Single unix standard says port numbers are * 16 bits long */ failf(data, "Port number too large: %lu", port); return CURLE_URL_MALFORMAT; } if (tmp) { *tmp++ = '\0'; /* cut off the name there */ conn->remote_port = atoi(tmp); *tmp = '\0'; /* cut off the name there */ conn->remote_port = port; } } if(data->change.proxy) { Loading Loading @@ -2075,6 +1974,138 @@ static CURLcode CreateConnection(struct SessionHandle *data, free(proxydup); /* free the duplicate pointer and not the modified */ } /************************************************************* * Take care of user and password authentication stuff *************************************************************/ /* * Inputs: data->set.userpwd (CURLOPT_USERPWD) * data->set.fpasswd (CURLOPT_PASSWDFUNCTION) * data->set.use_netrc (CURLOPT_NETRC) * conn->hostname * netrc file * hard-coded defaults * * Outputs: (almost :- all currently undefined) * conn->bits.user_passwd - non-zero if non-default passwords exist * conn->state.user - non-zero length if defined * conn->state.passwd - ditto * conn->hostname - remove user name and password */ /* At this point, we're hoping all the other special cases have * been taken care of, so conn->hostname is at most * [user[:password]]@]hostname * * We need somewhere to put the embedded details, so do that first. */ data->state.user[0] =0; /* to make everything well-defined */ data->state.passwd[0]=0; if (conn->protocol & (PROT_FTP|PROT_HTTP)) { /* This is a FTP or HTTP URL, we will now try to extract the possible * user+password pair in a string like: * ftp://user:password@ftp.my.site:8021/README */ char *ptr=strchr(conn->name, '@'); char *userpass = conn->name; if(ptr != NULL) { /* there's a user+password given here, to the left of the @ */ conn->name = conn->hostname = ++ptr; /* So the hostname is sane. Only bother interpreting the * results if we could care. It could still be wasted * work because it might be overtaken by the programmatically * set user/passwd, but doing that first adds more cases here :-( */ if (data->set.use_netrc != CURL_NETRC_REQUIRED) { /* We could use the one in the URL */ conn->bits.user_passwd = 1; /* enable user+password */ if(*userpass != ':') { /* the name is given, get user+password */ sscanf(userpass, "%127[^:@]:%127[^@]", data->state.user, data->state.passwd); } else /* no name given, get the password only */ sscanf(userpass, ":%127[^@]", data->state.passwd); if(data->state.user[0]) { char *newname=curl_unescape(data->state.user, 0); if(strlen(newname) < sizeof(data->state.user)) { strcpy(data->state.user, newname); } /* if the new name is longer than accepted, then just use the unconverted name, it'll be wrong but what the heck */ free(newname); } if (data->state.passwd[0]) { /* we have a password found in the URL, decode it! */ char *newpasswd=curl_unescape(data->state.passwd, 0); if(strlen(newpasswd) < sizeof(data->state.passwd)) { strcpy(data->state.passwd, newpasswd); } free(newpasswd); } } } } /* Programmatically set password: * - always applies, if available * - takes precedence over the values we just set above * so scribble it over the top. * User-supplied passwords are assumed not to need unescaping. * * user_password is set in "inherite initial knowledge' above, * so it doesn't have to be set in this block */ if (data->set.userpwd != NULL) { if(*data->set.userpwd != ':') { /* the name is given, get user+password */ sscanf(data->set.userpwd, "%127[^:]:%127[^\n]", data->state.user, data->state.passwd); } else /* no name given, get the password only */ sscanf(data->set.userpwd+1, "%127[^\n]", data->state.passwd); } if (data->set.use_netrc != CURL_NETRC_IGNORED && data->state.passwd[0] == '\0' ) { /* need passwd */ if(Curl_parsenetrc(conn->hostname, data->state.user, data->state.passwd)) { infof(data, "Couldn't find host %s in the .netrc file, using defaults", conn->hostname); } else conn->bits.user_passwd = 1; /* enable user+password */ } /* if we have a user but no password, ask for one */ if(conn->bits.user_passwd && !data->state.passwd[0] ) { if(!data->set.fpasswd || data->set.fpasswd(data->set.passwd_client, "password:", data->state.passwd, sizeof(data->state.passwd))) return CURLE_BAD_PASSWORD_ENTERED; } /* So we could have a password but no user; that's just too bad. */ /* If our protocol needs a password and we have none, use the defaults */ if ( (conn->protocol & (PROT_FTP|PROT_HTTP)) && !conn->bits.user_passwd) { strcpy(data->state.user, CURL_DEFAULT_USER); strcpy(data->state.passwd, CURL_DEFAULT_PASSWORD); /* This is the default password, so DON'T set conn->bits.user_passwd */ } /************************************************************* * Check the current list of connections to see if we can * re-use an already existing one or if we have to create a Loading
lib/urldata.h +2 −1 Original line number Diff line number Diff line Loading @@ -650,7 +650,8 @@ struct UserDefined { bool no_body; bool set_port; bool upload; bool use_netrc; enum CURL_NETRC_OPTION use_netrc; /* defined in include/curl.h */ bool verbose; bool krb4; /* kerberos4 connection requested */ bool reuse_forbid; /* forbidden to be reused, close after use */ Loading