From f9c7ba9096ec29db2536481d8e9ebe314e007f0c Mon Sep 17 00:00:00 2001 From: Daniel Stenberg Date: Fri, 16 Aug 2019 11:30:29 +0200 Subject: [PATCH] netrc: make the code try ".netrc" on Windows as well ... but fall back and try "_netrc" too if the dot version didn't work. Co-Authored-By: Steve Holme --- lib/netrc.c | 146 +++++++++++++++++++++++++++++++--------------------- 1 file changed, 87 insertions(+), 59 deletions(-) diff --git a/lib/netrc.c b/lib/netrc.c index f41636e974..bceca53f26 100644 --- a/lib/netrc.c +++ b/lib/netrc.c @@ -45,27 +45,27 @@ enum host_lookup_state { HOSTVALID /* this is "our" machine! */ }; +#define NETRC_FILE_MISSING 1 +#define NETRC_FAILED -1 +#define NETRC_SUCCESS 0 + /* - * @unittest: 1304 - * - * *loginp and *passwordp MUST be allocated if they aren't NULL when passed - * in. + * Returns zero on success. */ -int Curl_parsenetrc(const char *host, - char **loginp, - char **passwordp, - bool *login_changed, - bool *password_changed, - char *netrcfile) +static int parsenetrc(const char *host, + char **loginp, + char **passwordp, + bool *login_changed, + bool *password_changed, + char *netrcfile) { FILE *file; - int retcode = 1; + int retcode = NETRC_FILE_MISSING; char *login = *loginp; char *password = *passwordp; bool specific_login = (login && *login != 0); bool login_alloc = FALSE; bool password_alloc = FALSE; - bool netrc_alloc = FALSE; enum host_lookup_state state = NOTHING; char state_login = 0; /* Found a login keyword */ @@ -73,51 +73,9 @@ int Curl_parsenetrc(const char *host, int state_our_login = FALSE; /* With specific_login, found *our* login name */ -#define NETRC DOT_CHAR "netrc" - - if(!netrcfile) { - bool home_alloc = FALSE; - char *home = curl_getenv("HOME"); /* portable environment reader */ - if(home) { - home_alloc = TRUE; -#if defined(HAVE_GETPWUID_R) && defined(HAVE_GETEUID) - } - else { - struct passwd pw, *pw_res; - char pwbuf[1024]; - if(!getpwuid_r(geteuid(), &pw, pwbuf, sizeof(pwbuf), &pw_res) - && pw_res) { - home = strdup(pw.pw_dir); - if(!home) - return -1; - home_alloc = TRUE; - } -#elif defined(HAVE_GETPWUID) && defined(HAVE_GETEUID) - } - else { - struct passwd *pw; - pw = getpwuid(geteuid()); - if(pw) { - home = pw->pw_dir; - } -#endif - } - - if(!home) - return retcode; /* no home directory found (or possibly out of memory) */ - - netrcfile = curl_maprintf("%s%s%s", home, DIR_CHAR, NETRC); - if(home_alloc) - free(home); - if(!netrcfile) { - return -1; - } - netrc_alloc = TRUE; - } + DEBUGASSERT(netrcfile); file = fopen(netrcfile, FOPEN_READTEXT); - if(netrc_alloc) - free(netrcfile); if(file) { char *tok; char *tok_buf; @@ -148,14 +106,14 @@ int Curl_parsenetrc(const char *host, } else if(strcasecompare("default", tok)) { state = HOSTVALID; - retcode = 0; /* we did find our host */ + retcode = NETRC_SUCCESS; /* we did find our host */ } break; case HOSTFOUND: if(strcasecompare(host, tok)) { /* and yes, this is our host! */ state = HOSTVALID; - retcode = 0; /* we did find our host */ + retcode = NETRC_SUCCESS; /* we did find our host */ } else /* not our host */ @@ -174,7 +132,7 @@ int Curl_parsenetrc(const char *host, } login = strdup(tok); if(!login) { - retcode = -1; /* allocation failed */ + retcode = NETRC_FAILED; /* allocation failed */ goto out; } login_alloc = TRUE; @@ -190,7 +148,7 @@ int Curl_parsenetrc(const char *host, } password = strdup(tok); if(!password) { - retcode = -1; /* allocation failed */ + retcode = NETRC_FAILED; /* allocation failed */ goto out; } password_alloc = TRUE; @@ -215,6 +173,7 @@ int Curl_parsenetrc(const char *host, out: if(!retcode) { + /* success */ *login_changed = FALSE; *password_changed = FALSE; if(login_alloc) { @@ -242,4 +201,73 @@ int Curl_parsenetrc(const char *host, return retcode; } +/* + * @unittest: 1304 + * + * *loginp and *passwordp MUST be allocated if they aren't NULL when passed + * in. + */ +int Curl_parsenetrc(const char *host, + char **loginp, + char **passwordp, + bool *login_changed, + bool *password_changed, + char *netrcfile) +{ + int retcode = 1; + char *filealloc = NULL; + + if(!netrcfile) { + char *home = curl_getenv("HOME"); /* portable environment reader */ + if(home) { +#if defined(HAVE_GETPWUID_R) && defined(HAVE_GETEUID) + } + else { + struct passwd pw, *pw_res; + char pwbuf[1024]; + if(!getpwuid_r(geteuid(), &pw, pwbuf, sizeof(pwbuf), &pw_res) + && pw_res) { + home = strdup(pw.pw_dir); + if(!home) + return -1; + } +#elif defined(HAVE_GETPWUID) && defined(HAVE_GETEUID) + } + else { + struct passwd *pw; + pw = getpwuid(geteuid()); + if(pw) { + home = pw->pw_dir; + } +#endif + } + + if(!home) + return retcode; /* no home directory found (or possibly out of + memory) */ + + filealloc = curl_maprintf("%s%s.netrc", home, DIR_CHAR); + if(!filealloc) + return -1; + retcode = parsenetrc(host, loginp, passwordp, login_changed, + password_changed, filealloc); + free(filealloc); +#ifdef WIN32 + if(retcode == NETRC_FILE_MISSING) { + /* fallback to the old-style "_netrc" file */ + filealloc = curl_maprintf("%s%s_netrc", home, DIR_CHAR); + if(!filealloc) + return -1; + retcode = parsenetrc(host, loginp, passwordp, login_changed, + password_changed, filealloc); + free(filealloc); + } +#endif + } + else + retcode = parsenetrc(host, loginp, passwordp, login_changed, + password_changed, netrcfile); + return retcode; +} + #endif