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