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