netrc.c
Go to the documentation of this file.
00001 /***************************************************************************
00002  *                                  _   _ ____  _
00003  *  Project                     ___| | | |  _ \| |
00004  *                             / __| | | | |_) | |
00005  *                            | (__| |_| |  _ <| |___
00006  *                             \___|\___/|_| \_\_____|
00007  *
00008  * Copyright (C) 1998 - 2016, Daniel Stenberg, <daniel@haxx.se>, et al.
00009  *
00010  * This software is licensed as described in the file COPYING, which
00011  * you should have received as part of this distribution. The terms
00012  * are also available at https://curl.haxx.se/docs/copyright.html.
00013  *
00014  * You may opt to use, copy, modify, merge, publish, distribute and/or sell
00015  * copies of the Software, and permit persons to whom the Software is
00016  * furnished to do so, under the terms of the COPYING file.
00017  *
00018  * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
00019  * KIND, either express or implied.
00020  *
00021  ***************************************************************************/
00022 
00023 #include "curl_setup.h"
00024 
00025 #ifdef HAVE_PWD_H
00026 #include <pwd.h>
00027 #endif
00028 
00029 #include <curl/curl.h>
00030 #include "netrc.h"
00031 #include "strtok.h"
00032 #include "strcase.h"
00033 
00034 /* The last 3 #include files should be in this order */
00035 #include "curl_printf.h"
00036 #include "curl_memory.h"
00037 #include "memdebug.h"
00038 
00039 /* Get user and password from .netrc when given a machine name */
00040 
00041 enum host_lookup_state {
00042   NOTHING,
00043   HOSTFOUND,    /* the 'machine' keyword was found */
00044   HOSTVALID     /* this is "our" machine! */
00045 };
00046 
00047 /*
00048  * @unittest: 1304
00049  *
00050  * *loginp and *passwordp MUST be allocated if they aren't NULL when passed
00051  * in.
00052  */
00053 int Curl_parsenetrc(const char *host,
00054                     char **loginp,
00055                     char **passwordp,
00056                     char *netrcfile)
00057 {
00058   FILE *file;
00059   int retcode=1;
00060   int specific_login = (*loginp && **loginp != 0);
00061   bool netrc_alloc = FALSE;
00062   enum host_lookup_state state=NOTHING;
00063 
00064   char state_login=0;      /* Found a login keyword */
00065   char state_password=0;   /* Found a password keyword */
00066   int state_our_login=FALSE;  /* With specific_login, found *our* login name */
00067 
00068 #define NETRC DOT_CHAR "netrc"
00069 
00070   if(!netrcfile) {
00071     bool home_alloc = FALSE;
00072     char *home = curl_getenv("HOME"); /* portable environment reader */
00073     if(home) {
00074       home_alloc = TRUE;
00075 #if defined(HAVE_GETPWUID_R) && defined(HAVE_GETEUID)
00076     }
00077     else {
00078       struct passwd pw, *pw_res;
00079       char pwbuf[1024];
00080       if(!getpwuid_r(geteuid(), &pw, pwbuf, sizeof(pwbuf), &pw_res)
00081          && pw_res) {
00082         home = strdup(pw.pw_dir);
00083         if(!home)
00084           return CURLE_OUT_OF_MEMORY;
00085         home_alloc = TRUE;
00086       }
00087 #elif defined(HAVE_GETPWUID) && defined(HAVE_GETEUID)
00088     }
00089     else {
00090       struct passwd *pw;
00091       pw= getpwuid(geteuid());
00092       if(pw) {
00093         home = pw->pw_dir;
00094       }
00095 #endif
00096     }
00097 
00098     if(!home)
00099       return retcode; /* no home directory found (or possibly out of memory) */
00100 
00101     netrcfile = curl_maprintf("%s%s%s", home, DIR_CHAR, NETRC);
00102     if(home_alloc)
00103       free(home);
00104     if(!netrcfile) {
00105       return -1;
00106     }
00107     netrc_alloc = TRUE;
00108   }
00109 
00110   file = fopen(netrcfile, FOPEN_READTEXT);
00111   if(netrc_alloc)
00112     free(netrcfile);
00113   if(file) {
00114     char *tok;
00115     char *tok_buf;
00116     bool done=FALSE;
00117     char netrcbuffer[256];
00118     int  netrcbuffsize = (int)sizeof(netrcbuffer);
00119 
00120     while(!done && fgets(netrcbuffer, netrcbuffsize, file)) {
00121       tok=strtok_r(netrcbuffer, " \t\n", &tok_buf);
00122       while(!done && tok) {
00123 
00124         if((*loginp && **loginp) && (*passwordp && **passwordp)) {
00125           done=TRUE;
00126           break;
00127         }
00128 
00129         switch(state) {
00130         case NOTHING:
00131           if(strcasecompare("machine", tok)) {
00132             /* the next tok is the machine name, this is in itself the
00133                delimiter that starts the stuff entered for this machine,
00134                after this we need to search for 'login' and
00135                'password'. */
00136             state=HOSTFOUND;
00137           }
00138           else if(strcasecompare("default", tok)) {
00139             state=HOSTVALID;
00140             retcode=0; /* we did find our host */
00141           }
00142           break;
00143         case HOSTFOUND:
00144           if(strcasecompare(host, tok)) {
00145             /* and yes, this is our host! */
00146             state=HOSTVALID;
00147             retcode=0; /* we did find our host */
00148           }
00149           else
00150             /* not our host */
00151             state=NOTHING;
00152           break;
00153         case HOSTVALID:
00154           /* we are now parsing sub-keywords concerning "our" host */
00155           if(state_login) {
00156             if(specific_login) {
00157               state_our_login = strcasecompare(*loginp, tok);
00158             }
00159             else {
00160               free(*loginp);
00161               *loginp = strdup(tok);
00162               if(!*loginp) {
00163                 retcode = -1; /* allocation failed */
00164                 goto out;
00165               }
00166             }
00167             state_login=0;
00168           }
00169           else if(state_password) {
00170             if(state_our_login || !specific_login) {
00171               free(*passwordp);
00172               *passwordp = strdup(tok);
00173               if(!*passwordp) {
00174                 retcode = -1; /* allocation failed */
00175                 goto out;
00176               }
00177             }
00178             state_password=0;
00179           }
00180           else if(strcasecompare("login", tok))
00181             state_login=1;
00182           else if(strcasecompare("password", tok))
00183             state_password=1;
00184           else if(strcasecompare("machine", tok)) {
00185             /* ok, there's machine here go => */
00186             state = HOSTFOUND;
00187             state_our_login = FALSE;
00188           }
00189           break;
00190         } /* switch (state) */
00191 
00192         tok = strtok_r(NULL, " \t\n", &tok_buf);
00193       } /* while(tok) */
00194     } /* while fgets() */
00195 
00196     out:
00197     fclose(file);
00198   }
00199 
00200   return retcode;
00201 }


rc_visard_driver
Author(s): Heiko Hirschmueller , Christian Emmerich , Felix Ruess
autogenerated on Thu Jun 6 2019 20:43:05