From 378713deb2cf5137c7cffe6227d9d5f43fe3e8b1 Mon Sep 17 00:00:00 2001 From: Daniel Stenberg Date: Mon, 23 Jun 2025 00:09:18 +0200 Subject: [PATCH] netrc: use the NETRC environment variable (first) if set MIME-Version: 1.0 Content-Type: text/plain; charset=utf8 Content-Transfer-Encoding: 8bit Add test 755 to verify. Proposed-by: Berthin Torres Callañaupa URL: https://curl.se/mail/lib-2025-06/0015.html Closes #17712 --- docs/cmdline-opts/netrc.md | 13 ++++--- docs/libcurl/libcurl-env.md | 5 +++ docs/libcurl/opts/CURLOPT_NETRC.md | 3 +- lib/netrc.c | 62 ++++++++++++++++-------------- tests/data/Makefile.am | 2 +- tests/data/test755 | 59 ++++++++++++++++++++++++++++ 6 files changed, 108 insertions(+), 36 deletions(-) create mode 100644 tests/data/test755 diff --git a/docs/cmdline-opts/netrc.md b/docs/cmdline-opts/netrc.md index 261dc196d6..72b5ff935b 100644 --- a/docs/cmdline-opts/netrc.md +++ b/docs/cmdline-opts/netrc.md @@ -23,18 +23,21 @@ and password. This is typically used for FTP on Unix. If used with HTTP, curl enables user authentication. See *netrc(5)* and *ftp(1)* for details on the file format. curl does not complain if that file does not have the right permissions (it should be neither world- nor group-readable). The environment -variable "HOME" is used to find the home directory. +variable `HOME` is used to find the home directory. If the `NETRC` environment +variable is set, that filename is used as the netrc file. (Added in 8.16.0) + +If --netrc-file is used, that overrides all other ways to figure out the file. The netrc file provides credentials for a hostname independent of which protocol and port number that are used. On Windows two filenames in the home directory are checked: *.netrc* and -*_netrc*, preferring the former. Older versions on Windows checked for *_netrc* -only. +*_netrc*, preferring the former. Older versions on Windows checked for +*_netrc* only. A quick and simple example of how to setup a *.netrc* to allow curl to FTP to -the machine host.example.com with username 'myself' and password 'secret' could -look similar to: +the machine host.example.com with username 'myself' and password 'secret' +could look similar to: machine host.example.com login myself diff --git a/docs/libcurl/libcurl-env.md b/docs/libcurl/libcurl-env.md index 3b9a83861f..6ef11ac9a3 100644 --- a/docs/libcurl/libcurl-env.md +++ b/docs/libcurl/libcurl-env.md @@ -66,6 +66,11 @@ When the netrc feature is used (CURLOPT_NETRC(3)), this variable is checked as the secondary way to find the "current" home directory (on Windows only) in which the .netrc file is likely to exist. +## `NETRC` + +The filename used as netrc file when CURLOPT_NETRC(3) is used without +CURLOPT_NETRC_FILE(3). (Added in 8.16.0) + ## `NO_PROXY` This has the same functionality as the CURLOPT_NOPROXY(3) option: it diff --git a/docs/libcurl/opts/CURLOPT_NETRC.md b/docs/libcurl/opts/CURLOPT_NETRC.md index fa41236873..bda7a66c39 100644 --- a/docs/libcurl/opts/CURLOPT_NETRC.md +++ b/docs/libcurl/opts/CURLOPT_NETRC.md @@ -29,7 +29,8 @@ CURLcode curl_easy_setopt(CURL *handle, CURLOPT_NETRC, long level); This parameter controls the preference *level* of libcurl between using usernames and passwords from your *~/.netrc* file, relative to usernames and -passwords in the URL supplied with CURLOPT_URL(3). +passwords in the URL supplied with CURLOPT_URL(3). If the `NETRC` environment +variable is set, that filename is used as the netrc file. (Added in 8.16.0) On Windows, libcurl primarily checks for *.netrc* in *%HOME%*. If *%HOME%* is not set on Windows, libcurl falls back to *%USERPROFILE%*. If the file does diff --git a/lib/netrc.c b/lib/netrc.c index bf53fc01e1..ab068b18e6 100644 --- a/lib/netrc.c +++ b/lib/netrc.c @@ -396,47 +396,51 @@ NETRCcode Curl_parsenetrc(struct store_netrc *store, const char *host, char *filealloc = NULL; if(!netrcfile) { + char *home = NULL; + char *homea = NULL; #if defined(HAVE_GETPWUID_R) && defined(HAVE_GETEUID) char pwbuf[1024]; #endif - char *home = NULL; - char *homea = curl_getenv("HOME"); /* portable environment reader */ - if(homea) { - home = homea; + filealloc = curl_getenv("NETRC"); + if(!filealloc) { + homea = curl_getenv("HOME"); /* portable environment reader */ + if(homea) { + home = homea; #if defined(HAVE_GETPWUID_R) && defined(HAVE_GETEUID) - } - else { - struct passwd pw, *pw_res; - if(!getpwuid_r(geteuid(), &pw, pwbuf, sizeof(pwbuf), &pw_res) - && pw_res) { - home = pw.pw_dir; } + else { + struct passwd pw, *pw_res; + if(!getpwuid_r(geteuid(), &pw, pwbuf, sizeof(pwbuf), &pw_res) + && pw_res) { + home = pw.pw_dir; + } #elif defined(HAVE_GETPWUID) && defined(HAVE_GETEUID) - } - else { - struct passwd *pw; - pw = getpwuid(geteuid()); - if(pw) { - home = pw->pw_dir; } + else { + struct passwd *pw; + pw = getpwuid(geteuid()); + if(pw) { + home = pw->pw_dir; + } #elif defined(_WIN32) - } - else { - homea = curl_getenv("USERPROFILE"); - if(homea) { - home = homea; } + else { + homea = curl_getenv("USERPROFILE"); + if(homea) { + home = homea; + } #endif - } + } - if(!home) - return NETRC_FILE_MISSING; /* no home directory found (or possibly out - of memory) */ + if(!home) + return NETRC_FILE_MISSING; /* no home directory found (or possibly out + of memory) */ - filealloc = aprintf("%s%s.netrc", home, DIR_CHAR); - if(!filealloc) { - free(homea); - return NETRC_OUT_OF_MEMORY; + filealloc = aprintf("%s%s.netrc", home, DIR_CHAR); + if(!filealloc) { + free(homea); + return NETRC_OUT_OF_MEMORY; + } } retcode = parsenetrc(store, host, loginp, passwordp, filealloc); free(filealloc); diff --git a/tests/data/Makefile.am b/tests/data/Makefile.am index 7d8e8c7fc5..d8d0ec5db5 100644 --- a/tests/data/Makefile.am +++ b/tests/data/Makefile.am @@ -108,7 +108,7 @@ test718 test719 test720 test721 test722 test723 test724 test725 test726 \ test727 test728 test729 test730 test731 test732 test733 test734 test735 \ test736 test737 test738 test739 test740 test741 test742 test743 test744 \ test745 test746 test747 test748 test749 test750 test751 test752 test753 \ -test754 \ +test754 test755 \ test780 test781 test782 test783 test784 test785 test786 test787 test788 \ test789 test790 test791 test792 test793 \ \ diff --git a/tests/data/test755 b/tests/data/test755 new file mode 100644 index 0000000000..0e0840be45 --- /dev/null +++ b/tests/data/test755 @@ -0,0 +1,59 @@ + + + +HTTP +netrc + + + +# +# Server-side + + +HTTP/1.1 200 OK +Date: Tue, 09 Nov 2010 14:49:00 GMT +Server: test-server/fake swsclose +Content-Type: text/html +Funny-head: yesyes +Content-Length: 9 + +contents + + + +# +# Client-side + + +http + + +netrc with NETRC pointing out the file + + +machine foo.host login foo password alone-in-the-dark + + +NETRC=%LOGDIR/netrc%TESTNUMBER + + +http://foo.host/%TESTNUMBER --proxy %HOSTIP:%HTTPPORT -A "" --netrc + + +proxy + + + +# +# Verify data after the test has been "shot" + + +GET http://foo.host/%TESTNUMBER HTTP/1.1 +Host: foo.host +Authorization: Basic %b64[foo:alone-in-the-dark]b64% +Accept: */* +Proxy-Connection: Keep-Alive + + + + -- 2.47.2