xref: /csrg-svn/usr.bin/ftp/ruserpass.c (revision 35631)
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