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