15ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen/*************************************************************************** 25ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen * _ _ ____ _ 35ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen * Project ___| | | | _ \| | 45ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen * / __| | | | |_) | | 55ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen * | (__| |_| | _ <| |___ 65ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen * \___|\___/|_| \_\_____| 75ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen * 88f1a214b8a21b66f33454790dfba97ae2f818289Alex Deymo * Copyright (C) 1998 - 2016, Daniel Stenberg, <daniel@haxx.se>, et al. 95ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen * 105ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen * This software is licensed as described in the file COPYING, which 115ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen * you should have received as part of this distribution. The terms 128f1a214b8a21b66f33454790dfba97ae2f818289Alex Deymo * are also available at https://curl.haxx.se/docs/copyright.html. 135ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen * 145ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen * You may opt to use, copy, modify, merge, publish, distribute and/or sell 155ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen * copies of the Software, and permit persons to whom the Software is 165ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen * furnished to do so, under the terms of the COPYING file. 175ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen * 185ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY 195ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen * KIND, either express or implied. 205ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen * 215ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen ***************************************************************************/ 225ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen 23e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET#include "curl_setup.h" 245ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen 255ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen#ifdef HAVE_PWD_H 265ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen#include <pwd.h> 275ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen#endif 285ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen 295ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen#include <curl/curl.h> 305ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen#include "netrc.h" 315ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen 325ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen#include "strequal.h" 335ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen#include "strtok.h" 345ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen#include "rawstr.h" 355ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen 368f1a214b8a21b66f33454790dfba97ae2f818289Alex Deymo/* The last 3 #include files should be in this order */ 378f1a214b8a21b66f33454790dfba97ae2f818289Alex Deymo#include "curl_printf.h" 38e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET#include "curl_memory.h" 395ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen#include "memdebug.h" 405ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen 415ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen/* Get user and password from .netrc when given a machine name */ 425ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen 43e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNETenum host_lookup_state { 445ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen NOTHING, 455ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen HOSTFOUND, /* the 'machine' keyword was found */ 46e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET HOSTVALID /* this is "our" machine! */ 475ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen}; 485ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen 49e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET/* 50e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET * @unittest: 1304 51e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET * 52e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET * *loginp and *passwordp MUST be allocated if they aren't NULL when passed 53e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET * in. 54e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET */ 555ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsenint Curl_parsenetrc(const char *host, 56e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET char **loginp, 57e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET char **passwordp, 585ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen char *netrcfile) 595ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen{ 605ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen FILE *file; 615ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen int retcode=1; 62e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET int specific_login = (*loginp && **loginp != 0); 635ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen bool netrc_alloc = FALSE; 64e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET enum host_lookup_state state=NOTHING; 655ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen 665ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen char state_login=0; /* Found a login keyword */ 675ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen char state_password=0; /* Found a password keyword */ 685ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen int state_our_login=FALSE; /* With specific_login, found *our* login name */ 695ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen 705ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen#define NETRC DOT_CHAR "netrc" 715ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen 725ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen if(!netrcfile) { 73e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET bool home_alloc = FALSE; 74e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET char *home = curl_getenv("HOME"); /* portable environment reader */ 755ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen if(home) { 765ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen home_alloc = TRUE; 77e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET#if defined(HAVE_GETPWUID_R) && defined(HAVE_GETEUID) 78e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET } 79e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET else { 80e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET struct passwd pw, *pw_res; 81e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET char pwbuf[1024]; 82e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET if(!getpwuid_r(geteuid(), &pw, pwbuf, sizeof(pwbuf), &pw_res) 83e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET && pw_res) { 84e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET home = strdup(pw.pw_dir); 85e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET if(!home) 86e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET return CURLE_OUT_OF_MEMORY; 87e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET home_alloc = TRUE; 88e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET } 89e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET#elif defined(HAVE_GETPWUID) && defined(HAVE_GETEUID) 905ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen } 915ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen else { 925ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen struct passwd *pw; 935ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen pw= getpwuid(geteuid()); 945ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen if(pw) { 955ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen home = pw->pw_dir; 965ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen } 975ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen#endif 985ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen } 995ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen 1005ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen if(!home) 101e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET return retcode; /* no home directory found (or possibly out of memory) */ 1025ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen 1035ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen netrcfile = curl_maprintf("%s%s%s", home, DIR_CHAR, NETRC); 104e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET if(home_alloc) 105e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET free(home); 1065ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen if(!netrcfile) { 1075ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen return -1; 1085ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen } 1095ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen netrc_alloc = TRUE; 1105ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen } 1115ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen 112e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET file = fopen(netrcfile, FOPEN_READTEXT); 113e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET if(netrc_alloc) 114e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET free(netrcfile); 1155ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen if(file) { 1165ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen char *tok; 1175ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen char *tok_buf; 1185ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen bool done=FALSE; 1195ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen char netrcbuffer[256]; 1205ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen int netrcbuffsize = (int)sizeof(netrcbuffer); 1215ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen 1225ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen while(!done && fgets(netrcbuffer, netrcbuffsize, file)) { 1235ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen tok=strtok_r(netrcbuffer, " \t\n", &tok_buf); 1245ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen while(!done && tok) { 1255ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen 126e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET if((*loginp && **loginp) && (*passwordp && **passwordp)) { 1275ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen done=TRUE; 1285ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen break; 1295ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen } 1305ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen 1315ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen switch(state) { 1325ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen case NOTHING: 1335ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen if(Curl_raw_equal("machine", tok)) { 1345ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen /* the next tok is the machine name, this is in itself the 1355ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen delimiter that starts the stuff entered for this machine, 1365ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen after this we need to search for 'login' and 1375ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen 'password'. */ 1385ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen state=HOSTFOUND; 1395ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen } 140e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET else if(Curl_raw_equal("default", tok)) { 141e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET state=HOSTVALID; 142e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET retcode=0; /* we did find our host */ 143e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET } 1445ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen break; 1455ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen case HOSTFOUND: 1465ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen if(Curl_raw_equal(host, tok)) { 1475ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen /* and yes, this is our host! */ 1485ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen state=HOSTVALID; 1495ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen retcode=0; /* we did find our host */ 1505ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen } 1515ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen else 1525ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen /* not our host */ 1535ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen state=NOTHING; 1545ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen break; 1555ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen case HOSTVALID: 1565ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen /* we are now parsing sub-keywords concerning "our" host */ 1575ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen if(state_login) { 1585ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen if(specific_login) { 159e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET state_our_login = Curl_raw_equal(*loginp, tok); 1605ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen } 1615ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen else { 162e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET free(*loginp); 163e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET *loginp = strdup(tok); 164e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET if(!*loginp) { 165e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET retcode = -1; /* allocation failed */ 166e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET goto out; 167e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET } 1685ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen } 1695ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen state_login=0; 1705ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen } 1715ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen else if(state_password) { 1725ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen if(state_our_login || !specific_login) { 173e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET free(*passwordp); 174e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET *passwordp = strdup(tok); 175e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET if(!*passwordp) { 176e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET retcode = -1; /* allocation failed */ 177e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET goto out; 178e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET } 1795ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen } 1805ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen state_password=0; 1815ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen } 1825ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen else if(Curl_raw_equal("login", tok)) 1835ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen state_login=1; 1845ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen else if(Curl_raw_equal("password", tok)) 1855ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen state_password=1; 1865ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen else if(Curl_raw_equal("machine", tok)) { 1875ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen /* ok, there's machine here go => */ 1885ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen state = HOSTFOUND; 1895ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen state_our_login = FALSE; 1905ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen } 1915ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen break; 1925ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen } /* switch (state) */ 1935ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen 1945ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen tok = strtok_r(NULL, " \t\n", &tok_buf); 1955ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen } /* while(tok) */ 1965ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen } /* while fgets() */ 1975ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen 198e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET out: 1995ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen fclose(file); 2005ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen } 2015ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen 2025ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen return retcode; 2035ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen} 204