1 /* 2 * Copyright (c) 1985, 1993 3 * The Regents of the University of California. All rights reserved. 4 * 5 * %sccs.include.redist.c% 6 */ 7 8 #ifndef lint 9 static char sccsid[] = "@(#)ruserpass.c 8.1 (Berkeley) 06/06/93"; 10 #endif /* not lint */ 11 12 #include <sys/types.h> 13 #include <stdio.h> 14 #include <utmp.h> 15 #include <ctype.h> 16 #include <sys/stat.h> 17 #include <errno.h> 18 #include "ftp_var.h" 19 20 char *renvlook(), *malloc(), *index(), *getenv(), *getpass(), *getlogin(); 21 char *strcpy(); 22 struct utmp *getutmp(); 23 static FILE *cfile; 24 25 #define DEFAULT 1 26 #define LOGIN 2 27 #define PASSWD 3 28 #define ACCOUNT 4 29 #define MACDEF 5 30 #define ID 10 31 #define MACH 11 32 33 static char tokval[100]; 34 35 static struct toktab { 36 char *tokstr; 37 int tval; 38 } toktab[]= { 39 "default", DEFAULT, 40 "login", LOGIN, 41 "password", PASSWD, 42 "passwd", PASSWD, 43 "account", ACCOUNT, 44 "machine", MACH, 45 "macdef", MACDEF, 46 0, 0 47 }; 48 49 ruserpass(host, aname, apass, aacct) 50 char *host, **aname, **apass, **aacct; 51 { 52 char *hdir, buf[BUFSIZ], *tmp; 53 char myname[MAXHOSTNAMELEN], *mydomain; 54 int t, i, c, usedefault = 0; 55 struct stat stb; 56 static int token(); 57 58 hdir = getenv("HOME"); 59 if (hdir == NULL) 60 hdir = "."; 61 (void) sprintf(buf, "%s/.netrc", hdir); 62 cfile = fopen(buf, "r"); 63 if (cfile == NULL) { 64 if (errno != ENOENT) 65 perror(buf); 66 return(0); 67 } 68 if (gethostname(myname, sizeof(myname)) < 0) 69 myname[0] = '\0'; 70 if ((mydomain = index(myname, '.')) == NULL) 71 mydomain = ""; 72 next: 73 while ((t = token())) switch(t) { 74 75 case DEFAULT: 76 usedefault = 1; 77 /* FALL THROUGH */ 78 79 case MACH: 80 if (!usedefault) { 81 if (token() != ID) 82 continue; 83 /* 84 * Allow match either for user's input host name 85 * or official hostname. Also allow match of 86 * incompletely-specified host in local domain. 87 */ 88 if (strcasecmp(host, tokval) == 0) 89 goto match; 90 if (strcasecmp(hostname, tokval) == 0) 91 goto match; 92 if ((tmp = index(hostname, '.')) != NULL && 93 strcasecmp(tmp, mydomain) == 0 && 94 strncasecmp(hostname, tokval, tmp-hostname) == 0 && 95 tokval[tmp - hostname] == '\0') 96 goto match; 97 if ((tmp = index(host, '.')) != NULL && 98 strcasecmp(tmp, mydomain) == 0 && 99 strncasecmp(host, tokval, tmp - host) == 0 && 100 tokval[tmp - host] == '\0') 101 goto match; 102 continue; 103 } 104 match: 105 while ((t = token()) && t != MACH && t != DEFAULT) switch(t) { 106 107 case LOGIN: 108 if (token()) 109 if (*aname == 0) { 110 *aname = malloc((unsigned) strlen(tokval) + 1); 111 (void) strcpy(*aname, tokval); 112 } else { 113 if (strcmp(*aname, tokval)) 114 goto next; 115 } 116 break; 117 case PASSWD: 118 if (strcmp(*aname, "anonymous") && 119 fstat(fileno(cfile), &stb) >= 0 && 120 (stb.st_mode & 077) != 0) { 121 fprintf(stderr, "Error: .netrc file is readable by others.\n"); 122 fprintf(stderr, 123 "Remove password or make file unreadable by others.\n\n"); 124 goto bad; 125 } 126 if (token() && *apass == 0) { 127 *apass = malloc((unsigned) strlen(tokval) + 1); 128 (void) strcpy(*apass, tokval); 129 } 130 break; 131 case ACCOUNT: 132 if (fstat(fileno(cfile), &stb) >= 0 133 && (stb.st_mode & 077) != 0) { 134 fprintf(stderr, "Error: .netrc file is readable by others.\n"); 135 fprintf(stderr, 136 "Remove account or make file unreadable by others.\n\n"); 137 goto bad; 138 } 139 if (token() && *aacct == 0) { 140 *aacct = malloc((unsigned) strlen(tokval) + 1); 141 (void) strcpy(*aacct, tokval); 142 } 143 break; 144 case MACDEF: 145 if (proxy) { 146 (void) fclose(cfile); 147 return(0); 148 } 149 while ((c=getc(cfile)) != EOF && c == ' ' || c == '\t'); 150 if (c == EOF || c == '\n') { 151 printf("Missing macdef name argument.\n"); 152 goto bad; 153 } 154 if (macnum == 16) { 155 printf("Limit of 16 macros have already been defined\n"); 156 goto bad; 157 } 158 tmp = macros[macnum].mac_name; 159 *tmp++ = c; 160 for (i=0; i < 8 && (c=getc(cfile)) != EOF && 161 !isspace(c); ++i) { 162 *tmp++ = c; 163 } 164 if (c == EOF) { 165 printf("Macro definition missing null line terminator.\n"); 166 goto bad; 167 } 168 *tmp = '\0'; 169 if (c != '\n') { 170 while ((c=getc(cfile)) != EOF && c != '\n'); 171 } 172 if (c == EOF) { 173 printf("Macro definition missing null line terminator.\n"); 174 goto bad; 175 } 176 if (macnum == 0) { 177 macros[macnum].mac_start = macbuf; 178 } 179 else { 180 macros[macnum].mac_start = macros[macnum-1].mac_end + 1; 181 } 182 tmp = macros[macnum].mac_start; 183 while (tmp != macbuf + 4096) { 184 if ((c=getc(cfile)) == EOF) { 185 printf("Macro definition missing null line terminator.\n"); 186 goto bad; 187 } 188 *tmp = c; 189 if (*tmp == '\n') { 190 if (*(tmp-1) == '\0') { 191 macros[macnum++].mac_end = tmp - 1; 192 break; 193 } 194 *tmp = '\0'; 195 } 196 tmp++; 197 } 198 if (tmp == macbuf + 4096) { 199 printf("4K macro buffer exceeded\n"); 200 goto bad; 201 } 202 break; 203 default: 204 fprintf(stderr, "Unknown .netrc keyword %s\n", tokval); 205 break; 206 } 207 goto done; 208 } 209 done: 210 (void) fclose(cfile); 211 return(0); 212 bad: 213 (void) fclose(cfile); 214 return(-1); 215 } 216 217 static 218 token() 219 { 220 char *cp; 221 int c; 222 struct toktab *t; 223 224 if (feof(cfile) || ferror(cfile)) 225 return (0); 226 while ((c = getc(cfile)) != EOF && 227 (c == '\n' || c == '\t' || c == ' ' || c == ',')) 228 continue; 229 if (c == EOF) 230 return (0); 231 cp = tokval; 232 if (c == '"') { 233 while ((c = getc(cfile)) != EOF && c != '"') { 234 if (c == '\\') 235 c = getc(cfile); 236 *cp++ = c; 237 } 238 } else { 239 *cp++ = c; 240 while ((c = getc(cfile)) != EOF 241 && c != '\n' && c != '\t' && c != ' ' && c != ',') { 242 if (c == '\\') 243 c = getc(cfile); 244 *cp++ = c; 245 } 246 } 247 *cp = 0; 248 if (tokval[0] == 0) 249 return (0); 250 for (t = toktab; t->tokstr; t++) 251 if (!strcmp(t->tokstr, tokval)) 252 return (t->tval); 253 return (ID); 254 } 255