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