netrc.c
Go to the documentation of this file.
1 /***************************************************************************
2  * _ _ ____ _
3  * Project ___| | | | _ \| |
4  * / __| | | | |_) | |
5  * | (__| |_| | _ <| |___
6  * \___|\___/|_| \_\_____|
7  *
8  * Copyright (C) 1998 - 2017, Daniel Stenberg, <daniel@haxx.se>, et al.
9  *
10  * This software is licensed as described in the file COPYING, which
11  * you should have received as part of this distribution. The terms
12  * are also available at https://curl.haxx.se/docs/copyright.html.
13  *
14  * You may opt to use, copy, modify, merge, publish, distribute and/or sell
15  * copies of the Software, and permit persons to whom the Software is
16  * furnished to do so, under the terms of the COPYING file.
17  *
18  * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
19  * KIND, either express or implied.
20  *
21  ***************************************************************************/
22 
23 #include "curl_setup.h"
24 
25 #ifdef HAVE_PWD_H
26 #include <pwd.h>
27 #endif
28 
29 #include <curl/curl.h>
30 #include "netrc.h"
31 #include "strtok.h"
32 #include "strcase.h"
33 
34 /* The last 3 #include files should be in this order */
35 #include "curl_printf.h"
36 #include "curl_memory.h"
37 #include "memdebug.h"
38 
39 /* Get user and password from .netrc when given a machine name */
40 
43  HOSTFOUND, /* the 'machine' keyword was found */
44  HOSTVALID /* this is "our" machine! */
45 };
46 
47 /*
48  * @unittest: 1304
49  *
50  * *loginp and *passwordp MUST be allocated if they aren't NULL when passed
51  * in.
52  */
53 int Curl_parsenetrc(const char *host,
54  char **loginp,
55  char **passwordp,
56  char *netrcfile)
57 {
58  FILE *file;
59  int retcode = 1;
60  int specific_login = (*loginp && **loginp != 0);
61  bool netrc_alloc = FALSE;
63 
64  char state_login = 0; /* Found a login keyword */
65  char state_password = 0; /* Found a password keyword */
66  int state_our_login = FALSE; /* With specific_login, found *our* login
67  name */
68 
69 #define NETRC DOT_CHAR "netrc"
70 
71  if(!netrcfile) {
72  bool home_alloc = FALSE;
73  char *home = curl_getenv("HOME"); /* portable environment reader */
74  if(home) {
75  home_alloc = TRUE;
76 #if defined(HAVE_GETPWUID_R) && defined(HAVE_GETEUID)
77  }
78  else {
79  struct passwd pw, *pw_res;
80  char pwbuf[1024];
81  if(!getpwuid_r(geteuid(), &pw, pwbuf, sizeof(pwbuf), &pw_res)
82  && pw_res) {
83  home = strdup(pw.pw_dir);
84  if(!home)
85  return CURLE_OUT_OF_MEMORY;
86  home_alloc = TRUE;
87  }
88 #elif defined(HAVE_GETPWUID) && defined(HAVE_GETEUID)
89  }
90  else {
91  struct passwd *pw;
92  pw = getpwuid(geteuid());
93  if(pw) {
94  home = pw->pw_dir;
95  }
96 #endif
97  }
98 
99  if(!home)
100  return retcode; /* no home directory found (or possibly out of memory) */
101 
102  netrcfile = curl_maprintf("%s%s%s", home, DIR_CHAR, NETRC);
103  if(home_alloc)
104  free(home);
105  if(!netrcfile) {
106  return -1;
107  }
108  netrc_alloc = TRUE;
109  }
110 
111  file = fopen(netrcfile, FOPEN_READTEXT);
112  if(netrc_alloc)
113  free(netrcfile);
114  if(file) {
115  char *tok;
116  char *tok_buf;
117  bool done = FALSE;
118  char netrcbuffer[256];
119  int netrcbuffsize = (int)sizeof(netrcbuffer);
120 
121  while(!done && fgets(netrcbuffer, netrcbuffsize, file)) {
122  tok = strtok_r(netrcbuffer, " \t\n", &tok_buf);
123  if(tok && *tok == '#')
124  /* treat an initial hash as a comment line */
125  continue;
126  while(!done && tok) {
127 
128  if((*loginp && **loginp) && (*passwordp && **passwordp)) {
129  done = TRUE;
130  break;
131  }
132 
133  switch(state) {
134  case NOTHING:
135  if(strcasecompare("machine", tok)) {
136  /* the next tok is the machine name, this is in itself the
137  delimiter that starts the stuff entered for this machine,
138  after this we need to search for 'login' and
139  'password'. */
140  state = HOSTFOUND;
141  }
142  else if(strcasecompare("default", tok)) {
143  state = HOSTVALID;
144  retcode = 0; /* we did find our host */
145  }
146  break;
147  case HOSTFOUND:
148  if(strcasecompare(host, tok)) {
149  /* and yes, this is our host! */
150  state = HOSTVALID;
151  retcode = 0; /* we did find our host */
152  }
153  else
154  /* not our host */
155  state = NOTHING;
156  break;
157  case HOSTVALID:
158  /* we are now parsing sub-keywords concerning "our" host */
159  if(state_login) {
160  if(specific_login) {
161  state_our_login = strcasecompare(*loginp, tok);
162  }
163  else {
164  free(*loginp);
165  *loginp = strdup(tok);
166  if(!*loginp) {
167  retcode = -1; /* allocation failed */
168  goto out;
169  }
170  }
171  state_login = 0;
172  }
173  else if(state_password) {
174  if(state_our_login || !specific_login) {
175  free(*passwordp);
176  *passwordp = strdup(tok);
177  if(!*passwordp) {
178  retcode = -1; /* allocation failed */
179  goto out;
180  }
181  }
182  state_password = 0;
183  }
184  else if(strcasecompare("login", tok))
185  state_login = 1;
186  else if(strcasecompare("password", tok))
187  state_password = 1;
188  else if(strcasecompare("machine", tok)) {
189  /* ok, there's machine here go => */
190  state = HOSTFOUND;
191  state_our_login = FALSE;
192  }
193  break;
194  } /* switch (state) */
195 
196  tok = strtok_r(NULL, " \t\n", &tok_buf);
197  } /* while(tok) */
198  } /* while fgets() */
199 
200  out:
201  fclose(file);
202  }
203 
204  return retcode;
205 }
#define free(ptr)
Definition: curl_memory.h:130
#define state(x, y)
Definition: ftp.c:100
Definition: netrc.c:42
int Curl_parsenetrc(const char *host, char **loginp, char **passwordp, char *netrcfile)
Definition: netrc.c:53
#define strdup(ptr)
Definition: curl_memory.h:122
#define strcasecompare(a, b)
Definition: strcase.h:35
CURL_EXTERN char * curl_getenv(const char *variable)
Definition: getenv.c:51
#define getpwuid
Definition: setup-vms.h:53
#define FOPEN_READTEXT
Definition: curl_setup.h:732
#define FALSE
#define strtok_r
Definition: strtok.h:29
host_lookup_state
Definition: netrc.c:41
#define NETRC
#define TRUE
#define DIR_CHAR
Definition: curl_setup.h:465
CURL_EXTERN char * curl_maprintf(const char *format,...)
Definition: mprintf.c:1066


rc_tagdetect_client
Author(s): Monika Florek-Jasinska , Raphael Schaller
autogenerated on Sat Feb 13 2021 03:42:16