1 /* 2 * Copyright (c) 1985 Regents of the University of California. 3 * All rights reserved. 4 * 5 * %sccs.include.redist.c% 6 */ 7 8 #ifndef lint 9 static char sccsid[] = "@(#)ruserpass.c 5.3 (Berkeley) 03/01/91"; 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 not correct mode.\n"); 122 fprintf(stderr, "Remove password or correct mode.\n"); 123 goto bad; 124 } 125 if (token() && *apass == 0) { 126 *apass = malloc((unsigned) strlen(tokval) + 1); 127 (void) strcpy(*apass, tokval); 128 } 129 break; 130 case ACCOUNT: 131 if (fstat(fileno(cfile), &stb) >= 0 132 && (stb.st_mode & 077) != 0) { 133 fprintf(stderr, "Error - .netrc file not correct mode.\n"); 134 fprintf(stderr, "Remove account or correct mode.\n"); 135 goto bad; 136 } 137 if (token() && *aacct == 0) { 138 *aacct = malloc((unsigned) strlen(tokval) + 1); 139 (void) strcpy(*aacct, tokval); 140 } 141 break; 142 case MACDEF: 143 if (proxy) { 144 (void) fclose(cfile); 145 return(0); 146 } 147 while ((c=getc(cfile)) != EOF && c == ' ' || c == '\t'); 148 if (c == EOF || c == '\n') { 149 printf("Missing macdef name argument.\n"); 150 goto bad; 151 } 152 if (macnum == 16) { 153 printf("Limit of 16 macros have already been defined\n"); 154 goto bad; 155 } 156 tmp = macros[macnum].mac_name; 157 *tmp++ = c; 158 for (i=0; i < 8 && (c=getc(cfile)) != EOF && 159 !isspace(c); ++i) { 160 *tmp++ = c; 161 } 162 if (c == EOF) { 163 printf("Macro definition missing null line terminator.\n"); 164 goto bad; 165 } 166 *tmp = '\0'; 167 if (c != '\n') { 168 while ((c=getc(cfile)) != EOF && c != '\n'); 169 } 170 if (c == EOF) { 171 printf("Macro definition missing null line terminator.\n"); 172 goto bad; 173 } 174 if (macnum == 0) { 175 macros[macnum].mac_start = macbuf; 176 } 177 else { 178 macros[macnum].mac_start = macros[macnum-1].mac_end + 1; 179 } 180 tmp = macros[macnum].mac_start; 181 while (tmp != macbuf + 4096) { 182 if ((c=getc(cfile)) == EOF) { 183 printf("Macro definition missing null line terminator.\n"); 184 goto bad; 185 } 186 *tmp = c; 187 if (*tmp == '\n') { 188 if (*(tmp-1) == '\0') { 189 macros[macnum++].mac_end = tmp - 1; 190 break; 191 } 192 *tmp = '\0'; 193 } 194 tmp++; 195 } 196 if (tmp == macbuf + 4096) { 197 printf("4K macro buffer exceeded\n"); 198 goto bad; 199 } 200 break; 201 default: 202 fprintf(stderr, "Unknown .netrc keyword %s\n", tokval); 203 break; 204 } 205 goto done; 206 } 207 done: 208 (void) fclose(cfile); 209 return(0); 210 bad: 211 (void) fclose(cfile); 212 return(-1); 213 } 214 215 static 216 token() 217 { 218 char *cp; 219 int c; 220 struct toktab *t; 221 222 if (feof(cfile)) 223 return (0); 224 while ((c = getc(cfile)) != EOF && 225 (c == '\n' || c == '\t' || c == ' ' || c == ',')) 226 continue; 227 if (c == EOF) 228 return (0); 229 cp = tokval; 230 if (c == '"') { 231 while ((c = getc(cfile)) != EOF && c != '"') { 232 if (c == '\\') 233 c = getc(cfile); 234 *cp++ = c; 235 } 236 } else { 237 *cp++ = c; 238 while ((c = getc(cfile)) != EOF 239 && c != '\n' && c != '\t' && c != ' ' && c != ',') { 240 if (c == '\\') 241 c = getc(cfile); 242 *cp++ = c; 243 } 244 } 245 *cp = 0; 246 if (tokval[0] == 0) 247 return (0); 248 for (t = toktab; t->tokstr; t++) 249 if (!strcmp(t->tokstr, tokval)) 250 return (t->tval); 251 return (ID); 252 } 253