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