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 this notice is preserved and that due credit is given 7 * to the University of California at Berkeley. The name of the University 8 * may not be used to endorse or promote products derived from this 9 * software without specific prior written permission. This software 10 * is provided ``as is'' without express or implied warranty. 11 */ 12 13 #ifndef lint 14 static char sccsid[] = "@(#)ruserpass.c 1.4 (Berkeley) 03/14/88"; 15 #endif /* not lint */ 16 17 struct macel { 18 char mac_name[9]; /* macro name */ 19 char *mac_start; /* start of macro in macbuf */ 20 char *mac_end; /* end of macro in macbuf */ 21 }; 22 23 extern int macnum, proxy; /* number of defined macros */ 24 extern struct macel macros[16], *macpt; 25 extern char macbuf[4096]; 26 27 #include <stdio.h> 28 #include <utmp.h> 29 #include <ctype.h> 30 #include <sys/types.h> 31 #include <sys/stat.h> 32 #include <errno.h> 33 34 char *renvlook(), *malloc(), *index(), *getenv(), *getpass(), *getlogin(); 35 char *strcpy(); 36 struct utmp *getutmp(); 37 static FILE *cfile; 38 39 ruserpass(host, aname, apass, aacct) 40 char *host, **aname, **apass, **aacct; 41 { 42 43 /* renv(host, aname, apass, aacct); 44 if (*aname == 0 || *apass == 0) */ 45 return(rnetrc(host, aname, apass, aacct)); 46 } 47 48 #define DEFAULT 1 49 #define LOGIN 2 50 #define PASSWD 3 51 #define ACCOUNT 4 52 #define MACDEF 5 53 #define ID 10 54 #define MACHINE 11 55 56 static char tokval[100]; 57 58 static struct toktab { 59 char *tokstr; 60 int tval; 61 } toktab[]= { 62 "default", DEFAULT, 63 "login", LOGIN, 64 "password", PASSWD, 65 "account", ACCOUNT, 66 "machine", MACHINE, 67 "macdef", MACDEF, 68 0, 0 69 }; 70 71 static 72 rnetrc(host, aname, apass, aacct) 73 char *host, **aname, **apass, **aacct; 74 { 75 char *hdir, buf[BUFSIZ], *tmp; 76 int t, i, c; 77 struct stat stb; 78 extern int errno; 79 80 hdir = getenv("HOME"); 81 if (hdir == NULL) 82 hdir = "."; 83 (void) sprintf(buf, "%s/.netrc", hdir); 84 cfile = fopen(buf, "r"); 85 if (cfile == NULL) { 86 if (errno != ENOENT) 87 perror(buf); 88 return(0); 89 } 90 next: 91 while ((t = token())) switch(t) { 92 93 case DEFAULT: 94 (void) token(); 95 continue; 96 97 case MACHINE: 98 if (token() != ID || strcmp(host, tokval)) 99 continue; 100 while ((t = token()) && t != MACHINE) switch(t) { 101 102 case LOGIN: 103 if (token()) 104 if (*aname == 0) { 105 *aname = malloc((unsigned) strlen(tokval) + 1); 106 (void) strcpy(*aname, tokval); 107 } else { 108 if (strcmp(*aname, tokval)) 109 goto next; 110 } 111 break; 112 case PASSWD: 113 if (fstat(fileno(cfile), &stb) >= 0 114 && (stb.st_mode & 077) != 0) { 115 fprintf(stderr, "Error - .netrc file not correct mode.\n"); 116 fprintf(stderr, "Remove password or correct mode.\n"); 117 return(-1); 118 } 119 if (token() && *apass == 0) { 120 *apass = malloc((unsigned) strlen(tokval) + 1); 121 (void) strcpy(*apass, tokval); 122 } 123 break; 124 case ACCOUNT: 125 if (fstat(fileno(cfile), &stb) >= 0 126 && (stb.st_mode & 077) != 0) { 127 fprintf(stderr, "Error - .netrc file not correct mode.\n"); 128 fprintf(stderr, "Remove account or correct mode.\n"); 129 return(-1); 130 } 131 if (token() && *aacct == 0) { 132 *aacct = malloc((unsigned) strlen(tokval) + 1); 133 (void) strcpy(*aacct, tokval); 134 } 135 break; 136 case MACDEF: 137 if (proxy) { 138 return(0); 139 } 140 while ((c=getc(cfile)) != EOF && c == ' ' || c == '\t'); 141 if (c == EOF || c == '\n') { 142 printf("Missing macdef name argument.\n"); 143 return(-1); 144 } 145 if (macnum == 16) { 146 printf("Limit of 16 macros have already been defined\n"); 147 return(-1); 148 } 149 tmp = macros[macnum].mac_name; 150 *tmp++ = c; 151 for (i=0; i < 8 && (c=getc(cfile)) != EOF && 152 !isspace(c); ++i) { 153 *tmp++ = c; 154 } 155 if (c == EOF) { 156 printf("Macro definition missing null line terminator.\n"); 157 return(-1); 158 } 159 *tmp = '\0'; 160 if (c != '\n') { 161 while ((c=getc(cfile)) != EOF && c != '\n'); 162 } 163 if (c == EOF) { 164 printf("Macro definition missing null line terminator.\n"); 165 return(-1); 166 } 167 if (macnum == 0) { 168 macros[macnum].mac_start = macbuf; 169 } 170 else { 171 macros[macnum].mac_start = macros[macnum-1].mac_end + 1; 172 } 173 tmp = macros[macnum].mac_start; 174 while (tmp != macbuf + 4096) { 175 if ((c=getc(cfile)) == EOF) { 176 printf("Macro definition missing null line terminator.\n"); 177 return(-1); 178 } 179 *tmp = c; 180 if (*tmp == '\n') { 181 if (*(tmp-1) == '\0') { 182 macros[macnum++].mac_end = tmp - 1; 183 break; 184 } 185 *tmp = '\0'; 186 } 187 tmp++; 188 } 189 if (tmp == macbuf + 4096) { 190 printf("4K macro buffer exceeded\n"); 191 return(-1); 192 } 193 break; 194 default: 195 fprintf(stderr, "Unknown .netrc keyword %s\n", tokval); 196 break; 197 } 198 goto done; 199 } 200 done: 201 (void) fclose(cfile); 202 return(0); 203 } 204 205 static 206 token() 207 { 208 char *cp; 209 int c; 210 struct toktab *t; 211 212 if (feof(cfile)) 213 return (0); 214 while ((c = getc(cfile)) != EOF && 215 (c == '\n' || c == '\t' || c == ' ' || c == ',')) 216 continue; 217 if (c == EOF) 218 return (0); 219 cp = tokval; 220 if (c == '"') { 221 while ((c = getc(cfile)) != EOF && c != '"') { 222 if (c == '\\') 223 c = getc(cfile); 224 *cp++ = c; 225 } 226 } else { 227 *cp++ = c; 228 while ((c = getc(cfile)) != EOF 229 && c != '\n' && c != '\t' && c != ' ' && c != ',') { 230 if (c == '\\') 231 c = getc(cfile); 232 *cp++ = c; 233 } 234 } 235 *cp = 0; 236 if (tokval[0] == 0) 237 return (0); 238 for (t = toktab; t->tokstr; t++) 239 if (!strcmp(t->tokstr, tokval)) 240 return (t->tval); 241 return (ID); 242 } 243