1*6236dae4SAndroid Build Coastguard Worker /***************************************************************************
2*6236dae4SAndroid Build Coastguard Worker * _ _ ____ _
3*6236dae4SAndroid Build Coastguard Worker * Project ___| | | | _ \| |
4*6236dae4SAndroid Build Coastguard Worker * / __| | | | |_) | |
5*6236dae4SAndroid Build Coastguard Worker * | (__| |_| | _ <| |___
6*6236dae4SAndroid Build Coastguard Worker * \___|\___/|_| \_\_____|
7*6236dae4SAndroid Build Coastguard Worker *
8*6236dae4SAndroid Build Coastguard Worker * Copyright (C) Daniel Stenberg, <[email protected]>, et al.
9*6236dae4SAndroid Build Coastguard Worker *
10*6236dae4SAndroid Build Coastguard Worker * This software is licensed as described in the file COPYING, which
11*6236dae4SAndroid Build Coastguard Worker * you should have received as part of this distribution. The terms
12*6236dae4SAndroid Build Coastguard Worker * are also available at https://curl.se/docs/copyright.html.
13*6236dae4SAndroid Build Coastguard Worker *
14*6236dae4SAndroid Build Coastguard Worker * You may opt to use, copy, modify, merge, publish, distribute and/or sell
15*6236dae4SAndroid Build Coastguard Worker * copies of the Software, and permit persons to whom the Software is
16*6236dae4SAndroid Build Coastguard Worker * furnished to do so, under the terms of the COPYING file.
17*6236dae4SAndroid Build Coastguard Worker *
18*6236dae4SAndroid Build Coastguard Worker * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
19*6236dae4SAndroid Build Coastguard Worker * KIND, either express or implied.
20*6236dae4SAndroid Build Coastguard Worker *
21*6236dae4SAndroid Build Coastguard Worker * SPDX-License-Identifier: curl
22*6236dae4SAndroid Build Coastguard Worker *
23*6236dae4SAndroid Build Coastguard Worker ***************************************************************************/
24*6236dae4SAndroid Build Coastguard Worker
25*6236dae4SAndroid Build Coastguard Worker #include "curl_setup.h"
26*6236dae4SAndroid Build Coastguard Worker #ifndef CURL_DISABLE_NETRC
27*6236dae4SAndroid Build Coastguard Worker
28*6236dae4SAndroid Build Coastguard Worker #ifdef HAVE_PWD_H
29*6236dae4SAndroid Build Coastguard Worker #include <pwd.h>
30*6236dae4SAndroid Build Coastguard Worker #endif
31*6236dae4SAndroid Build Coastguard Worker
32*6236dae4SAndroid Build Coastguard Worker #include <curl/curl.h>
33*6236dae4SAndroid Build Coastguard Worker #include "netrc.h"
34*6236dae4SAndroid Build Coastguard Worker #include "strcase.h"
35*6236dae4SAndroid Build Coastguard Worker #include "curl_get_line.h"
36*6236dae4SAndroid Build Coastguard Worker
37*6236dae4SAndroid Build Coastguard Worker /* The last 3 #include files should be in this order */
38*6236dae4SAndroid Build Coastguard Worker #include "curl_printf.h"
39*6236dae4SAndroid Build Coastguard Worker #include "curl_memory.h"
40*6236dae4SAndroid Build Coastguard Worker #include "memdebug.h"
41*6236dae4SAndroid Build Coastguard Worker
42*6236dae4SAndroid Build Coastguard Worker /* Get user and password from .netrc when given a machine name */
43*6236dae4SAndroid Build Coastguard Worker
44*6236dae4SAndroid Build Coastguard Worker enum host_lookup_state {
45*6236dae4SAndroid Build Coastguard Worker NOTHING,
46*6236dae4SAndroid Build Coastguard Worker HOSTFOUND, /* the 'machine' keyword was found */
47*6236dae4SAndroid Build Coastguard Worker HOSTVALID, /* this is "our" machine! */
48*6236dae4SAndroid Build Coastguard Worker MACDEF
49*6236dae4SAndroid Build Coastguard Worker };
50*6236dae4SAndroid Build Coastguard Worker
51*6236dae4SAndroid Build Coastguard Worker enum found_state {
52*6236dae4SAndroid Build Coastguard Worker NONE,
53*6236dae4SAndroid Build Coastguard Worker LOGIN,
54*6236dae4SAndroid Build Coastguard Worker PASSWORD
55*6236dae4SAndroid Build Coastguard Worker };
56*6236dae4SAndroid Build Coastguard Worker
57*6236dae4SAndroid Build Coastguard Worker #define NETRC_FILE_MISSING 1
58*6236dae4SAndroid Build Coastguard Worker #define NETRC_FAILED -1
59*6236dae4SAndroid Build Coastguard Worker #define NETRC_SUCCESS 0
60*6236dae4SAndroid Build Coastguard Worker
61*6236dae4SAndroid Build Coastguard Worker #define MAX_NETRC_LINE 4096
62*6236dae4SAndroid Build Coastguard Worker #define MAX_NETRC_FILE (64*1024)
63*6236dae4SAndroid Build Coastguard Worker #define MAX_NETRC_TOKEN 128
64*6236dae4SAndroid Build Coastguard Worker
file2memory(const char * filename,struct dynbuf * filebuf)65*6236dae4SAndroid Build Coastguard Worker static CURLcode file2memory(const char *filename, struct dynbuf *filebuf)
66*6236dae4SAndroid Build Coastguard Worker {
67*6236dae4SAndroid Build Coastguard Worker CURLcode result = CURLE_OK;
68*6236dae4SAndroid Build Coastguard Worker FILE *file = fopen(filename, FOPEN_READTEXT);
69*6236dae4SAndroid Build Coastguard Worker struct dynbuf linebuf;
70*6236dae4SAndroid Build Coastguard Worker Curl_dyn_init(&linebuf, MAX_NETRC_LINE);
71*6236dae4SAndroid Build Coastguard Worker
72*6236dae4SAndroid Build Coastguard Worker if(file) {
73*6236dae4SAndroid Build Coastguard Worker while(Curl_get_line(&linebuf, file)) {
74*6236dae4SAndroid Build Coastguard Worker const char *line = Curl_dyn_ptr(&linebuf);
75*6236dae4SAndroid Build Coastguard Worker /* skip comments on load */
76*6236dae4SAndroid Build Coastguard Worker while(ISBLANK(*line))
77*6236dae4SAndroid Build Coastguard Worker line++;
78*6236dae4SAndroid Build Coastguard Worker if(*line == '#')
79*6236dae4SAndroid Build Coastguard Worker continue;
80*6236dae4SAndroid Build Coastguard Worker result = Curl_dyn_add(filebuf, line);
81*6236dae4SAndroid Build Coastguard Worker if(result)
82*6236dae4SAndroid Build Coastguard Worker goto done;
83*6236dae4SAndroid Build Coastguard Worker }
84*6236dae4SAndroid Build Coastguard Worker }
85*6236dae4SAndroid Build Coastguard Worker done:
86*6236dae4SAndroid Build Coastguard Worker Curl_dyn_free(&linebuf);
87*6236dae4SAndroid Build Coastguard Worker if(file)
88*6236dae4SAndroid Build Coastguard Worker fclose(file);
89*6236dae4SAndroid Build Coastguard Worker return result;
90*6236dae4SAndroid Build Coastguard Worker }
91*6236dae4SAndroid Build Coastguard Worker
92*6236dae4SAndroid Build Coastguard Worker /*
93*6236dae4SAndroid Build Coastguard Worker * Returns zero on success.
94*6236dae4SAndroid Build Coastguard Worker */
parsenetrc(struct store_netrc * store,const char * host,char ** loginp,char ** passwordp,const char * netrcfile)95*6236dae4SAndroid Build Coastguard Worker static int parsenetrc(struct store_netrc *store,
96*6236dae4SAndroid Build Coastguard Worker const char *host,
97*6236dae4SAndroid Build Coastguard Worker char **loginp,
98*6236dae4SAndroid Build Coastguard Worker char **passwordp,
99*6236dae4SAndroid Build Coastguard Worker const char *netrcfile)
100*6236dae4SAndroid Build Coastguard Worker {
101*6236dae4SAndroid Build Coastguard Worker int retcode = NETRC_FILE_MISSING;
102*6236dae4SAndroid Build Coastguard Worker char *login = *loginp;
103*6236dae4SAndroid Build Coastguard Worker char *password = *passwordp;
104*6236dae4SAndroid Build Coastguard Worker bool specific_login = (login && *login != 0);
105*6236dae4SAndroid Build Coastguard Worker bool login_alloc = FALSE;
106*6236dae4SAndroid Build Coastguard Worker bool password_alloc = FALSE;
107*6236dae4SAndroid Build Coastguard Worker enum host_lookup_state state = NOTHING;
108*6236dae4SAndroid Build Coastguard Worker enum found_state found = NONE;
109*6236dae4SAndroid Build Coastguard Worker bool our_login = TRUE; /* With specific_login, found *our* login name (or
110*6236dae4SAndroid Build Coastguard Worker login-less line) */
111*6236dae4SAndroid Build Coastguard Worker bool done = FALSE;
112*6236dae4SAndroid Build Coastguard Worker char *netrcbuffer;
113*6236dae4SAndroid Build Coastguard Worker struct dynbuf token;
114*6236dae4SAndroid Build Coastguard Worker struct dynbuf *filebuf = &store->filebuf;
115*6236dae4SAndroid Build Coastguard Worker Curl_dyn_init(&token, MAX_NETRC_TOKEN);
116*6236dae4SAndroid Build Coastguard Worker
117*6236dae4SAndroid Build Coastguard Worker if(!store->loaded) {
118*6236dae4SAndroid Build Coastguard Worker if(file2memory(netrcfile, filebuf))
119*6236dae4SAndroid Build Coastguard Worker return NETRC_FAILED;
120*6236dae4SAndroid Build Coastguard Worker store->loaded = TRUE;
121*6236dae4SAndroid Build Coastguard Worker }
122*6236dae4SAndroid Build Coastguard Worker
123*6236dae4SAndroid Build Coastguard Worker netrcbuffer = Curl_dyn_ptr(filebuf);
124*6236dae4SAndroid Build Coastguard Worker
125*6236dae4SAndroid Build Coastguard Worker while(!done) {
126*6236dae4SAndroid Build Coastguard Worker char *tok = netrcbuffer;
127*6236dae4SAndroid Build Coastguard Worker while(tok) {
128*6236dae4SAndroid Build Coastguard Worker char *tok_end;
129*6236dae4SAndroid Build Coastguard Worker bool quoted;
130*6236dae4SAndroid Build Coastguard Worker Curl_dyn_reset(&token);
131*6236dae4SAndroid Build Coastguard Worker while(ISBLANK(*tok))
132*6236dae4SAndroid Build Coastguard Worker tok++;
133*6236dae4SAndroid Build Coastguard Worker /* tok is first non-space letter */
134*6236dae4SAndroid Build Coastguard Worker if(state == MACDEF) {
135*6236dae4SAndroid Build Coastguard Worker if((*tok == '\n') || (*tok == '\r'))
136*6236dae4SAndroid Build Coastguard Worker state = NOTHING; /* end of macro definition */
137*6236dae4SAndroid Build Coastguard Worker }
138*6236dae4SAndroid Build Coastguard Worker
139*6236dae4SAndroid Build Coastguard Worker if(!*tok || (*tok == '\n'))
140*6236dae4SAndroid Build Coastguard Worker /* end of line */
141*6236dae4SAndroid Build Coastguard Worker break;
142*6236dae4SAndroid Build Coastguard Worker
143*6236dae4SAndroid Build Coastguard Worker /* leading double-quote means quoted string */
144*6236dae4SAndroid Build Coastguard Worker quoted = (*tok == '\"');
145*6236dae4SAndroid Build Coastguard Worker
146*6236dae4SAndroid Build Coastguard Worker tok_end = tok;
147*6236dae4SAndroid Build Coastguard Worker if(!quoted) {
148*6236dae4SAndroid Build Coastguard Worker size_t len = 0;
149*6236dae4SAndroid Build Coastguard Worker while(!ISSPACE(*tok_end)) {
150*6236dae4SAndroid Build Coastguard Worker tok_end++;
151*6236dae4SAndroid Build Coastguard Worker len++;
152*6236dae4SAndroid Build Coastguard Worker }
153*6236dae4SAndroid Build Coastguard Worker if(!len || Curl_dyn_addn(&token, tok, len)) {
154*6236dae4SAndroid Build Coastguard Worker retcode = NETRC_FAILED;
155*6236dae4SAndroid Build Coastguard Worker goto out;
156*6236dae4SAndroid Build Coastguard Worker }
157*6236dae4SAndroid Build Coastguard Worker }
158*6236dae4SAndroid Build Coastguard Worker else {
159*6236dae4SAndroid Build Coastguard Worker bool escape = FALSE;
160*6236dae4SAndroid Build Coastguard Worker bool endquote = FALSE;
161*6236dae4SAndroid Build Coastguard Worker tok_end++; /* pass the leading quote */
162*6236dae4SAndroid Build Coastguard Worker while(*tok_end) {
163*6236dae4SAndroid Build Coastguard Worker char s = *tok_end;
164*6236dae4SAndroid Build Coastguard Worker if(escape) {
165*6236dae4SAndroid Build Coastguard Worker escape = FALSE;
166*6236dae4SAndroid Build Coastguard Worker switch(s) {
167*6236dae4SAndroid Build Coastguard Worker case 'n':
168*6236dae4SAndroid Build Coastguard Worker s = '\n';
169*6236dae4SAndroid Build Coastguard Worker break;
170*6236dae4SAndroid Build Coastguard Worker case 'r':
171*6236dae4SAndroid Build Coastguard Worker s = '\r';
172*6236dae4SAndroid Build Coastguard Worker break;
173*6236dae4SAndroid Build Coastguard Worker case 't':
174*6236dae4SAndroid Build Coastguard Worker s = '\t';
175*6236dae4SAndroid Build Coastguard Worker break;
176*6236dae4SAndroid Build Coastguard Worker }
177*6236dae4SAndroid Build Coastguard Worker }
178*6236dae4SAndroid Build Coastguard Worker else if(s == '\\') {
179*6236dae4SAndroid Build Coastguard Worker escape = TRUE;
180*6236dae4SAndroid Build Coastguard Worker tok_end++;
181*6236dae4SAndroid Build Coastguard Worker continue;
182*6236dae4SAndroid Build Coastguard Worker }
183*6236dae4SAndroid Build Coastguard Worker else if(s == '\"') {
184*6236dae4SAndroid Build Coastguard Worker tok_end++; /* pass the ending quote */
185*6236dae4SAndroid Build Coastguard Worker endquote = TRUE;
186*6236dae4SAndroid Build Coastguard Worker break;
187*6236dae4SAndroid Build Coastguard Worker }
188*6236dae4SAndroid Build Coastguard Worker if(Curl_dyn_addn(&token, &s, 1)) {
189*6236dae4SAndroid Build Coastguard Worker retcode = NETRC_FAILED;
190*6236dae4SAndroid Build Coastguard Worker goto out;
191*6236dae4SAndroid Build Coastguard Worker }
192*6236dae4SAndroid Build Coastguard Worker tok_end++;
193*6236dae4SAndroid Build Coastguard Worker }
194*6236dae4SAndroid Build Coastguard Worker if(escape || !endquote) {
195*6236dae4SAndroid Build Coastguard Worker /* bad syntax, get out */
196*6236dae4SAndroid Build Coastguard Worker retcode = NETRC_FAILED;
197*6236dae4SAndroid Build Coastguard Worker goto out;
198*6236dae4SAndroid Build Coastguard Worker }
199*6236dae4SAndroid Build Coastguard Worker }
200*6236dae4SAndroid Build Coastguard Worker
201*6236dae4SAndroid Build Coastguard Worker if((login && *login) && (password && *password)) {
202*6236dae4SAndroid Build Coastguard Worker done = TRUE;
203*6236dae4SAndroid Build Coastguard Worker break;
204*6236dae4SAndroid Build Coastguard Worker }
205*6236dae4SAndroid Build Coastguard Worker
206*6236dae4SAndroid Build Coastguard Worker tok = Curl_dyn_ptr(&token);
207*6236dae4SAndroid Build Coastguard Worker
208*6236dae4SAndroid Build Coastguard Worker switch(state) {
209*6236dae4SAndroid Build Coastguard Worker case NOTHING:
210*6236dae4SAndroid Build Coastguard Worker if(strcasecompare("macdef", tok))
211*6236dae4SAndroid Build Coastguard Worker /* Define a macro. A macro is defined with the specified name; its
212*6236dae4SAndroid Build Coastguard Worker contents begin with the next .netrc line and continue until a
213*6236dae4SAndroid Build Coastguard Worker null line (consecutive new-line characters) is encountered. */
214*6236dae4SAndroid Build Coastguard Worker state = MACDEF;
215*6236dae4SAndroid Build Coastguard Worker else if(strcasecompare("machine", tok))
216*6236dae4SAndroid Build Coastguard Worker /* the next tok is the machine name, this is in itself the delimiter
217*6236dae4SAndroid Build Coastguard Worker that starts the stuff entered for this machine, after this we
218*6236dae4SAndroid Build Coastguard Worker need to search for 'login' and 'password'. */
219*6236dae4SAndroid Build Coastguard Worker state = HOSTFOUND;
220*6236dae4SAndroid Build Coastguard Worker else if(strcasecompare("default", tok)) {
221*6236dae4SAndroid Build Coastguard Worker state = HOSTVALID;
222*6236dae4SAndroid Build Coastguard Worker retcode = NETRC_SUCCESS; /* we did find our host */
223*6236dae4SAndroid Build Coastguard Worker }
224*6236dae4SAndroid Build Coastguard Worker break;
225*6236dae4SAndroid Build Coastguard Worker case MACDEF:
226*6236dae4SAndroid Build Coastguard Worker if(!*tok)
227*6236dae4SAndroid Build Coastguard Worker state = NOTHING;
228*6236dae4SAndroid Build Coastguard Worker break;
229*6236dae4SAndroid Build Coastguard Worker case HOSTFOUND:
230*6236dae4SAndroid Build Coastguard Worker if(strcasecompare(host, tok)) {
231*6236dae4SAndroid Build Coastguard Worker /* and yes, this is our host! */
232*6236dae4SAndroid Build Coastguard Worker state = HOSTVALID;
233*6236dae4SAndroid Build Coastguard Worker retcode = NETRC_SUCCESS; /* we did find our host */
234*6236dae4SAndroid Build Coastguard Worker }
235*6236dae4SAndroid Build Coastguard Worker else
236*6236dae4SAndroid Build Coastguard Worker /* not our host */
237*6236dae4SAndroid Build Coastguard Worker state = NOTHING;
238*6236dae4SAndroid Build Coastguard Worker break;
239*6236dae4SAndroid Build Coastguard Worker case HOSTVALID:
240*6236dae4SAndroid Build Coastguard Worker /* we are now parsing sub-keywords concerning "our" host */
241*6236dae4SAndroid Build Coastguard Worker if(found == LOGIN) {
242*6236dae4SAndroid Build Coastguard Worker if(specific_login) {
243*6236dae4SAndroid Build Coastguard Worker our_login = !Curl_timestrcmp(login, tok);
244*6236dae4SAndroid Build Coastguard Worker }
245*6236dae4SAndroid Build Coastguard Worker else if(!login || Curl_timestrcmp(login, tok)) {
246*6236dae4SAndroid Build Coastguard Worker if(login_alloc)
247*6236dae4SAndroid Build Coastguard Worker free(login);
248*6236dae4SAndroid Build Coastguard Worker login = strdup(tok);
249*6236dae4SAndroid Build Coastguard Worker if(!login) {
250*6236dae4SAndroid Build Coastguard Worker retcode = NETRC_FAILED; /* allocation failed */
251*6236dae4SAndroid Build Coastguard Worker goto out;
252*6236dae4SAndroid Build Coastguard Worker }
253*6236dae4SAndroid Build Coastguard Worker login_alloc = TRUE;
254*6236dae4SAndroid Build Coastguard Worker }
255*6236dae4SAndroid Build Coastguard Worker found = NONE;
256*6236dae4SAndroid Build Coastguard Worker }
257*6236dae4SAndroid Build Coastguard Worker else if(found == PASSWORD) {
258*6236dae4SAndroid Build Coastguard Worker if((our_login || !specific_login) &&
259*6236dae4SAndroid Build Coastguard Worker (!password || Curl_timestrcmp(password, tok))) {
260*6236dae4SAndroid Build Coastguard Worker if(password_alloc)
261*6236dae4SAndroid Build Coastguard Worker free(password);
262*6236dae4SAndroid Build Coastguard Worker password = strdup(tok);
263*6236dae4SAndroid Build Coastguard Worker if(!password) {
264*6236dae4SAndroid Build Coastguard Worker retcode = NETRC_FAILED; /* allocation failed */
265*6236dae4SAndroid Build Coastguard Worker goto out;
266*6236dae4SAndroid Build Coastguard Worker }
267*6236dae4SAndroid Build Coastguard Worker password_alloc = TRUE;
268*6236dae4SAndroid Build Coastguard Worker }
269*6236dae4SAndroid Build Coastguard Worker found = NONE;
270*6236dae4SAndroid Build Coastguard Worker }
271*6236dae4SAndroid Build Coastguard Worker else if(strcasecompare("login", tok))
272*6236dae4SAndroid Build Coastguard Worker found = LOGIN;
273*6236dae4SAndroid Build Coastguard Worker else if(strcasecompare("password", tok))
274*6236dae4SAndroid Build Coastguard Worker found = PASSWORD;
275*6236dae4SAndroid Build Coastguard Worker else if(strcasecompare("machine", tok)) {
276*6236dae4SAndroid Build Coastguard Worker /* ok, there is machine here go => */
277*6236dae4SAndroid Build Coastguard Worker state = HOSTFOUND;
278*6236dae4SAndroid Build Coastguard Worker found = NONE;
279*6236dae4SAndroid Build Coastguard Worker }
280*6236dae4SAndroid Build Coastguard Worker break;
281*6236dae4SAndroid Build Coastguard Worker } /* switch (state) */
282*6236dae4SAndroid Build Coastguard Worker tok = ++tok_end;
283*6236dae4SAndroid Build Coastguard Worker }
284*6236dae4SAndroid Build Coastguard Worker if(!done) {
285*6236dae4SAndroid Build Coastguard Worker char *nl = NULL;
286*6236dae4SAndroid Build Coastguard Worker if(tok)
287*6236dae4SAndroid Build Coastguard Worker nl = strchr(tok, '\n');
288*6236dae4SAndroid Build Coastguard Worker if(!nl)
289*6236dae4SAndroid Build Coastguard Worker break;
290*6236dae4SAndroid Build Coastguard Worker /* point to next line */
291*6236dae4SAndroid Build Coastguard Worker netrcbuffer = &nl[1];
292*6236dae4SAndroid Build Coastguard Worker }
293*6236dae4SAndroid Build Coastguard Worker } /* while !done */
294*6236dae4SAndroid Build Coastguard Worker
295*6236dae4SAndroid Build Coastguard Worker out:
296*6236dae4SAndroid Build Coastguard Worker Curl_dyn_free(&token);
297*6236dae4SAndroid Build Coastguard Worker if(!retcode) {
298*6236dae4SAndroid Build Coastguard Worker /* success */
299*6236dae4SAndroid Build Coastguard Worker if(login_alloc) {
300*6236dae4SAndroid Build Coastguard Worker free(*loginp);
301*6236dae4SAndroid Build Coastguard Worker *loginp = login;
302*6236dae4SAndroid Build Coastguard Worker }
303*6236dae4SAndroid Build Coastguard Worker if(password_alloc) {
304*6236dae4SAndroid Build Coastguard Worker free(*passwordp);
305*6236dae4SAndroid Build Coastguard Worker *passwordp = password;
306*6236dae4SAndroid Build Coastguard Worker }
307*6236dae4SAndroid Build Coastguard Worker }
308*6236dae4SAndroid Build Coastguard Worker else {
309*6236dae4SAndroid Build Coastguard Worker Curl_dyn_free(filebuf);
310*6236dae4SAndroid Build Coastguard Worker if(login_alloc)
311*6236dae4SAndroid Build Coastguard Worker free(login);
312*6236dae4SAndroid Build Coastguard Worker if(password_alloc)
313*6236dae4SAndroid Build Coastguard Worker free(password);
314*6236dae4SAndroid Build Coastguard Worker }
315*6236dae4SAndroid Build Coastguard Worker
316*6236dae4SAndroid Build Coastguard Worker return retcode;
317*6236dae4SAndroid Build Coastguard Worker }
318*6236dae4SAndroid Build Coastguard Worker
319*6236dae4SAndroid Build Coastguard Worker /*
320*6236dae4SAndroid Build Coastguard Worker * @unittest: 1304
321*6236dae4SAndroid Build Coastguard Worker *
322*6236dae4SAndroid Build Coastguard Worker * *loginp and *passwordp MUST be allocated if they are not NULL when passed
323*6236dae4SAndroid Build Coastguard Worker * in.
324*6236dae4SAndroid Build Coastguard Worker */
Curl_parsenetrc(struct store_netrc * store,const char * host,char ** loginp,char ** passwordp,char * netrcfile)325*6236dae4SAndroid Build Coastguard Worker int Curl_parsenetrc(struct store_netrc *store, const char *host,
326*6236dae4SAndroid Build Coastguard Worker char **loginp, char **passwordp,
327*6236dae4SAndroid Build Coastguard Worker char *netrcfile)
328*6236dae4SAndroid Build Coastguard Worker {
329*6236dae4SAndroid Build Coastguard Worker int retcode = 1;
330*6236dae4SAndroid Build Coastguard Worker char *filealloc = NULL;
331*6236dae4SAndroid Build Coastguard Worker
332*6236dae4SAndroid Build Coastguard Worker if(!netrcfile) {
333*6236dae4SAndroid Build Coastguard Worker #if defined(HAVE_GETPWUID_R) && defined(HAVE_GETEUID)
334*6236dae4SAndroid Build Coastguard Worker char pwbuf[1024];
335*6236dae4SAndroid Build Coastguard Worker #endif
336*6236dae4SAndroid Build Coastguard Worker char *home = NULL;
337*6236dae4SAndroid Build Coastguard Worker char *homea = curl_getenv("HOME"); /* portable environment reader */
338*6236dae4SAndroid Build Coastguard Worker if(homea) {
339*6236dae4SAndroid Build Coastguard Worker home = homea;
340*6236dae4SAndroid Build Coastguard Worker #if defined(HAVE_GETPWUID_R) && defined(HAVE_GETEUID)
341*6236dae4SAndroid Build Coastguard Worker }
342*6236dae4SAndroid Build Coastguard Worker else {
343*6236dae4SAndroid Build Coastguard Worker struct passwd pw, *pw_res;
344*6236dae4SAndroid Build Coastguard Worker if(!getpwuid_r(geteuid(), &pw, pwbuf, sizeof(pwbuf), &pw_res)
345*6236dae4SAndroid Build Coastguard Worker && pw_res) {
346*6236dae4SAndroid Build Coastguard Worker home = pw.pw_dir;
347*6236dae4SAndroid Build Coastguard Worker }
348*6236dae4SAndroid Build Coastguard Worker #elif defined(HAVE_GETPWUID) && defined(HAVE_GETEUID)
349*6236dae4SAndroid Build Coastguard Worker }
350*6236dae4SAndroid Build Coastguard Worker else {
351*6236dae4SAndroid Build Coastguard Worker struct passwd *pw;
352*6236dae4SAndroid Build Coastguard Worker pw = getpwuid(geteuid());
353*6236dae4SAndroid Build Coastguard Worker if(pw) {
354*6236dae4SAndroid Build Coastguard Worker home = pw->pw_dir;
355*6236dae4SAndroid Build Coastguard Worker }
356*6236dae4SAndroid Build Coastguard Worker #elif defined(_WIN32)
357*6236dae4SAndroid Build Coastguard Worker }
358*6236dae4SAndroid Build Coastguard Worker else {
359*6236dae4SAndroid Build Coastguard Worker homea = curl_getenv("USERPROFILE");
360*6236dae4SAndroid Build Coastguard Worker if(homea) {
361*6236dae4SAndroid Build Coastguard Worker home = homea;
362*6236dae4SAndroid Build Coastguard Worker }
363*6236dae4SAndroid Build Coastguard Worker #endif
364*6236dae4SAndroid Build Coastguard Worker }
365*6236dae4SAndroid Build Coastguard Worker
366*6236dae4SAndroid Build Coastguard Worker if(!home)
367*6236dae4SAndroid Build Coastguard Worker return retcode; /* no home directory found (or possibly out of
368*6236dae4SAndroid Build Coastguard Worker memory) */
369*6236dae4SAndroid Build Coastguard Worker
370*6236dae4SAndroid Build Coastguard Worker filealloc = aprintf("%s%s.netrc", home, DIR_CHAR);
371*6236dae4SAndroid Build Coastguard Worker if(!filealloc) {
372*6236dae4SAndroid Build Coastguard Worker free(homea);
373*6236dae4SAndroid Build Coastguard Worker return -1;
374*6236dae4SAndroid Build Coastguard Worker }
375*6236dae4SAndroid Build Coastguard Worker retcode = parsenetrc(store, host, loginp, passwordp, filealloc);
376*6236dae4SAndroid Build Coastguard Worker free(filealloc);
377*6236dae4SAndroid Build Coastguard Worker #ifdef _WIN32
378*6236dae4SAndroid Build Coastguard Worker if(retcode == NETRC_FILE_MISSING) {
379*6236dae4SAndroid Build Coastguard Worker /* fallback to the old-style "_netrc" file */
380*6236dae4SAndroid Build Coastguard Worker filealloc = aprintf("%s%s_netrc", home, DIR_CHAR);
381*6236dae4SAndroid Build Coastguard Worker if(!filealloc) {
382*6236dae4SAndroid Build Coastguard Worker free(homea);
383*6236dae4SAndroid Build Coastguard Worker return -1;
384*6236dae4SAndroid Build Coastguard Worker }
385*6236dae4SAndroid Build Coastguard Worker retcode = parsenetrc(store, host, loginp, passwordp, filealloc);
386*6236dae4SAndroid Build Coastguard Worker free(filealloc);
387*6236dae4SAndroid Build Coastguard Worker }
388*6236dae4SAndroid Build Coastguard Worker #endif
389*6236dae4SAndroid Build Coastguard Worker free(homea);
390*6236dae4SAndroid Build Coastguard Worker }
391*6236dae4SAndroid Build Coastguard Worker else
392*6236dae4SAndroid Build Coastguard Worker retcode = parsenetrc(store, host, loginp, passwordp, netrcfile);
393*6236dae4SAndroid Build Coastguard Worker return retcode;
394*6236dae4SAndroid Build Coastguard Worker }
395*6236dae4SAndroid Build Coastguard Worker
Curl_netrc_init(struct store_netrc * s)396*6236dae4SAndroid Build Coastguard Worker void Curl_netrc_init(struct store_netrc *s)
397*6236dae4SAndroid Build Coastguard Worker {
398*6236dae4SAndroid Build Coastguard Worker Curl_dyn_init(&s->filebuf, MAX_NETRC_FILE);
399*6236dae4SAndroid Build Coastguard Worker s->loaded = FALSE;
400*6236dae4SAndroid Build Coastguard Worker }
Curl_netrc_cleanup(struct store_netrc * s)401*6236dae4SAndroid Build Coastguard Worker void Curl_netrc_cleanup(struct store_netrc *s)
402*6236dae4SAndroid Build Coastguard Worker {
403*6236dae4SAndroid Build Coastguard Worker Curl_dyn_free(&s->filebuf);
404*6236dae4SAndroid Build Coastguard Worker s->loaded = FALSE;
405*6236dae4SAndroid Build Coastguard Worker }
406*6236dae4SAndroid Build Coastguard Worker #endif
407