url: given a user in the URL, find pwd for that user in netrc

Add test 380 and 381 to verify, edited test 133

Reported-by: Manfred Schwarb
Fixes #8241
Closes #8243
This commit is contained in:
Daniel Stenberg 2022-01-07 17:44:42 +01:00
parent 919baa5802
commit d1237ac906
No known key found for this signature in database
GPG Key ID: 5CC908FDB71E12C2
6 changed files with 179 additions and 36 deletions

View File

@ -5,7 +5,7 @@
.\" * | (__| |_| | _ <| |___
.\" * \___|\___/|_| \_\_____|
.\" *
.\" * Copyright (C) 1998 - 2021, Daniel Stenberg, <daniel@haxx.se>, et al.
.\" * Copyright (C) 1998 - 2022, Daniel Stenberg, <daniel@haxx.se>, et al.
.\" *
.\" * This software is licensed as described in the file COPYING, which
.\" * you should have received as part of this distribution. The terms
@ -46,24 +46,20 @@ and similar things are not supported).
libcurl does not verify that the file has the correct properties set (as the
standard Unix ftp client does). It should only be readable by user.
\fIlevel\fP should be set to one of the values described below.
.IP CURL_NETRC_OPTIONAL
The use of the \fI~/.netrc\fP file is optional, and information in the URL is
to be preferred. The file will be scanned for the host and user name (to find
the password only) or for the host only, to find the first user name and
password after that \fImachine\fP, which ever information is not specified.
Undefined values of the option will have this effect.
.IP CURL_NETRC_IGNORED
The library will ignore the \fI~/.netrc\fP file.
This is the default.
.IP CURL_NETRC_REQUIRED
The use of the \fI~/.netrc\fP file is required, and information in the URL is
to be ignored. The file will be scanned for the host and user name (to find
\fIlevel\fP is a long that should be set to one of the values described below.
.IP "CURL_NETRC_IGNORED (0)"
The library will ignore the \fI.netrc\fP file. This is the default.
.IP "CURL_NETRC_OPTIONAL (1)"
The use of the \fI.netrc\fP file is optional, and information in the URL is to
be preferred. The file will be scanned for the host and user name (to find
the password only) or for the host only, to find the first user name and
password after that \fImachine\fP, which ever information is not specified.
.IP "CURL_NETRC_REQUIRED (2)"
The use of the \fI.netrc\fP file is required, and any credential information
present in the URL is ignored. The file will be scanned for the host and user
name (to find the password only) or for the host only, to find the first user
name and password after that \fImachine\fP, which ever information is not
specified.
.SH DEFAULT
CURL_NETRC_IGNORED
.SH PROTOCOLS

View File

@ -2942,6 +2942,13 @@ static CURLcode override_login(struct Curl_easy *data,
bool netrc_user_changed = FALSE;
bool netrc_passwd_changed = FALSE;
int ret;
bool url_provided = FALSE;
if(data->state.up.user) {
/* there was a user name in the URL */
userp = &data->state.up.user;
url_provided = TRUE;
}
ret = Curl_parsenetrc(conn->host.name,
userp, passwdp,
@ -2961,27 +2968,36 @@ static CURLcode override_login(struct Curl_easy *data,
conn->bits.netrc = TRUE;
conn->bits.user_passwd = TRUE; /* enable user+password */
}
if(url_provided) {
Curl_safefree(conn->user);
conn->user = strdup(*userp);
if(!conn->user)
return CURLE_OUT_OF_MEMORY;
/* don't update the user name below */
userp = NULL;
}
}
#endif
/* for updated strings, we update them in the URL */
if(*userp) {
CURLcode result = Curl_setstropt(&data->state.aptr.user, *userp);
if(result)
return result;
}
if(data->state.aptr.user) {
uc = curl_url_set(data->state.uh, CURLUPART_USER, data->state.aptr.user,
CURLU_URLENCODE);
if(uc)
return Curl_uc_to_curlcode(uc);
if(!*userp) {
*userp = strdup(data->state.aptr.user);
if(!*userp)
return CURLE_OUT_OF_MEMORY;
if(userp) {
if(*userp) {
CURLcode result = Curl_setstropt(&data->state.aptr.user, *userp);
if(result)
return result;
}
if(data->state.aptr.user) {
uc = curl_url_set(data->state.uh, CURLUPART_USER, data->state.aptr.user,
CURLU_URLENCODE);
if(uc)
return Curl_uc_to_curlcode(uc);
if(!*userp) {
*userp = strdup(data->state.aptr.user);
if(!*userp)
return CURLE_OUT_OF_MEMORY;
}
}
}
if(*passwdp) {
CURLcode result = Curl_setstropt(&data->state.aptr.passwd, *passwdp);
if(result)

View File

@ -63,6 +63,7 @@ test352 test353 test354 test355 test356 test357 test358 test359 test360 \
test361 test362 test363 test364 test365 test366 test367 test368 test369 \
test370 test371 test372 test373 \
\
test380 test381 \
test392 test393 test394 test395 test396 test397 \
\
test400 test401 test402 test403 test404 test405 test406 test407 test408 \

View File

@ -34,7 +34,7 @@ dr-xr-xr-x 5 0 1 512 Oct 1 1997 usr
ftp
</server>
<name>
FTP (compulsory .netrc; ignored user/passwd) dir list PASV
FTP compulsory .netrc; ignore passwd in URL
</name>
<command>
-n --netrc-file log/netrc%TESTNUMBER ftp://mary:mark@%HOSTIP:%FTPPORT/
@ -42,7 +42,7 @@ FTP (compulsory .netrc; ignored user/passwd) dir list PASV
<file name="log/netrc%TESTNUMBER" >
# the following two lines were created while testing curl
machine %HOSTIP login user1 password passwd1
machine %HOSTIP login user2 password passwd2
machine %HOSTIP login mary password drfrank
</file>
</client>
@ -50,8 +50,8 @@ machine %HOSTIP login user2 password passwd2
# Verify data after the test has been "shot"
<verify>
<protocol>
USER user1
PASS passwd1
USER mary
PASS drfrank
PWD
EPSV
TYPE A

63
tests/data/test380 Normal file
View File

@ -0,0 +1,63 @@
<testcase>
<info>
<keywords>
FTP
EPSV
LIST
netrc
</keywords>
</info>
#
# Server-side
<reply>
# When doing LIST, we get the default list output hard-coded in the test
# FTP server
<datacheck mode="text">
total 20
drwxr-xr-x 8 98 98 512 Oct 22 13:06 .
drwxr-xr-x 8 98 98 512 Oct 22 13:06 ..
drwxr-xr-x 2 98 98 512 May 2 1996 .NeXT
-r--r--r-- 1 0 1 35 Jul 16 1996 README
lrwxrwxrwx 1 0 1 7 Dec 9 1999 bin -> usr/bin
dr-xr-xr-x 2 0 1 512 Oct 1 1997 dev
drwxrwxrwx 2 98 98 512 May 29 16:04 download.html
dr-xr-xr-x 2 0 1 512 Nov 30 1995 etc
drwxrwxrwx 2 98 1 512 Oct 30 14:33 pub
dr-xr-xr-x 5 0 1 512 Oct 1 1997 usr
</datacheck>
</reply>
#
# Client-side
<client>
<server>
ftp
</server>
<name>
pick netrc password based on user name in URL
</name>
<command>
--netrc --netrc-file log/netrc%TESTNUMBER ftp://mary@%HOSTIP:%FTPPORT/
</command>
<file name="log/netrc%TESTNUMBER" >
# the following two lines were created while testing curl
machine %HOSTIP login frankenstein password wrongone
machine %HOSTIP login mary password yram
</file>
</client>
#
# Verify data after the test has been "shot"
<verify>
<protocol>
USER mary
PASS yram
PWD
EPSV
TYPE A
LIST
QUIT
</protocol>
</verify>
</testcase>

67
tests/data/test381 Normal file
View File

@ -0,0 +1,67 @@
<testcase>
<info>
<keywords>
FTP
EPSV
LIST
netrc
</keywords>
</info>
#
# Server-side
<reply>
# When doing LIST, we get the default list output hard-coded in the test
# FTP server
<datacheck mode="text">
total 20
drwxr-xr-x 8 98 98 512 Oct 22 13:06 .
drwxr-xr-x 8 98 98 512 Oct 22 13:06 ..
drwxr-xr-x 2 98 98 512 May 2 1996 .NeXT
-r--r--r-- 1 0 1 35 Jul 16 1996 README
lrwxrwxrwx 1 0 1 7 Dec 9 1999 bin -> usr/bin
dr-xr-xr-x 2 0 1 512 Oct 1 1997 dev
drwxrwxrwx 2 98 98 512 May 29 16:04 download.html
dr-xr-xr-x 2 0 1 512 Nov 30 1995 etc
drwxrwxrwx 2 98 1 512 Oct 30 14:33 pub
dr-xr-xr-x 5 0 1 512 Oct 1 1997 usr
</datacheck>
</reply>
#
# Client-side
<client>
<server>
ftp
</server>
# When CURL_NETRC_REQUIRED is set, the password in the URL is ignored and
# using the netrc is mandatory.
#
<name>
netrc-optional lets URL creds override netrc
</name>
<command>
--netrc-optional --netrc-file log/netrc%TESTNUMBER ftp://mary:drfrank@%HOSTIP:%FTPPORT/
</command>
<file name="log/netrc%TESTNUMBER" >
# the following two lines were created while testing curl
machine %HOSTIP login frankenstein password wrongone
machine %HOSTIP login mary password yram
</file>
</client>
#
# Verify data after the test has been "shot"
<verify>
<protocol>
USER mary
PASS drfrank
PWD
EPSV
TYPE A
LIST
QUIT
</protocol>
</verify>
</testcase>