Annotation of src/usr.bin/ftp/ruserpass.c, Revision 1.23.2.1
1.23.2.1! wrstuden 1: /* $NetBSD: ruserpass.c,v 1.25 1999/10/24 12:31:41 lukem Exp $ */
1.6 tls 2:
1.1 cgd 3: /*
1.3 cgd 4: * Copyright (c) 1985, 1993, 1994
5: * The Regents of the University of California. All rights reserved.
1.1 cgd 6: *
7: * Redistribution and use in source and binary forms, with or without
8: * modification, are permitted provided that the following conditions
9: * are met:
10: * 1. Redistributions of source code must retain the above copyright
11: * notice, this list of conditions and the following disclaimer.
12: * 2. Redistributions in binary form must reproduce the above copyright
13: * notice, this list of conditions and the following disclaimer in the
14: * documentation and/or other materials provided with the distribution.
15: * 3. All advertising materials mentioning features or use of this software
16: * must display the following acknowledgement:
17: * This product includes software developed by the University of
18: * California, Berkeley and its contributors.
19: * 4. Neither the name of the University nor the names of its contributors
20: * may be used to endorse or promote products derived from this software
21: * without specific prior written permission.
22: *
23: * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
24: * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
25: * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
26: * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
27: * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
28: * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
29: * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
30: * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
31: * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
32: * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
33: * SUCH DAMAGE.
34: */
35:
1.14 lukem 36: #include <sys/cdefs.h>
1.1 cgd 37: #ifndef lint
1.11 lukem 38: #if 0
1.6 tls 39: static char sccsid[] = "@(#)ruserpass.c 8.4 (Berkeley) 4/27/95";
1.11 lukem 40: #else
1.23.2.1! wrstuden 41: __RCSID("$NetBSD: ruserpass.c,v 1.25 1999/10/24 12:31:41 lukem Exp $");
1.11 lukem 42: #endif
1.1 cgd 43: #endif /* not lint */
44:
45: #include <sys/types.h>
1.3 cgd 46: #include <sys/stat.h>
47:
1.1 cgd 48: #include <ctype.h>
1.3 cgd 49: #include <err.h>
1.1 cgd 50: #include <errno.h>
1.21 lukem 51: #include <netdb.h>
1.3 cgd 52: #include <stdio.h>
53: #include <stdlib.h>
54: #include <string.h>
55: #include <unistd.h>
56:
1.1 cgd 57: #include "ftp_var.h"
58:
1.3 cgd 59: static int token __P((void));
1.1 cgd 60: static FILE *cfile;
61:
62: #define DEFAULT 1
63: #define LOGIN 2
64: #define PASSWD 3
1.23.2.1! wrstuden 65: #define ACCOUNT 4
! 66: #define MACDEF 5
1.1 cgd 67: #define ID 10
68: #define MACH 11
69:
70: static char tokval[100];
71:
72: static struct toktab {
73: char *tokstr;
74: int tval;
1.17 lukem 75: } toktab[] = {
1.3 cgd 76: { "default", DEFAULT },
77: { "login", LOGIN },
78: { "password", PASSWD },
79: { "passwd", PASSWD },
80: { "account", ACCOUNT },
81: { "machine", MACH },
82: { "macdef", MACDEF },
83: { NULL, 0 }
1.1 cgd 84: };
85:
1.3 cgd 86: int
1.1 cgd 87: ruserpass(host, aname, apass, aacct)
1.8 lukem 88: const char *host;
1.19 mycroft 89: const char **aname, **apass, **aacct;
1.1 cgd 90: {
91: char *hdir, buf[BUFSIZ], *tmp;
1.18 mrg 92: char myname[MAXHOSTNAMELEN + 1], *mydomain;
1.1 cgd 93: int t, i, c, usedefault = 0;
94: struct stat stb;
95:
96: hdir = getenv("HOME");
97: if (hdir == NULL)
98: hdir = ".";
1.23 lukem 99: if (strlcpy(buf, hdir, sizeof(buf)) >= sizeof(buf) ||
100: strlcat(buf, "/.netrc", sizeof(buf)) >= sizeof(buf)) {
1.8 lukem 101: warnx("%s/.netrc: %s", hdir, strerror(ENAMETOOLONG));
102: return (0);
103: }
1.1 cgd 104: cfile = fopen(buf, "r");
105: if (cfile == NULL) {
106: if (errno != ENOENT)
1.3 cgd 107: warn("%s", buf);
108: return (0);
1.1 cgd 109: }
110: if (gethostname(myname, sizeof(myname)) < 0)
111: myname[0] = '\0';
1.18 mrg 112: myname[sizeof(myname) - 1] = '\0';
1.3 cgd 113: if ((mydomain = strchr(myname, '.')) == NULL)
1.1 cgd 114: mydomain = "";
115: next:
116: while ((t = token())) switch(t) {
117:
118: case DEFAULT:
119: usedefault = 1;
120: /* FALL THROUGH */
121:
122: case MACH:
123: if (!usedefault) {
124: if (token() != ID)
125: continue;
126: /*
127: * Allow match either for user's input host name
1.7 lukem 128: * or official hostname. Also allow match of
1.1 cgd 129: * incompletely-specified host in local domain.
130: */
131: if (strcasecmp(host, tokval) == 0)
132: goto match;
133: if (strcasecmp(hostname, tokval) == 0)
134: goto match;
1.3 cgd 135: if ((tmp = strchr(hostname, '.')) != NULL &&
1.1 cgd 136: strcasecmp(tmp, mydomain) == 0 &&
137: strncasecmp(hostname, tokval, tmp-hostname) == 0 &&
138: tokval[tmp - hostname] == '\0')
139: goto match;
1.3 cgd 140: if ((tmp = strchr(host, '.')) != NULL &&
1.1 cgd 141: strcasecmp(tmp, mydomain) == 0 &&
142: strncasecmp(host, tokval, tmp - host) == 0 &&
143: tokval[tmp - host] == '\0')
144: goto match;
145: continue;
146: }
147: match:
148: while ((t = token()) && t != MACH && t != DEFAULT) switch(t) {
149:
150: case LOGIN:
1.16 christos 151: if (token()) {
1.20 lukem 152: if (*aname == NULL)
153: *aname = xstrdup(tokval);
154: else {
1.1 cgd 155: if (strcmp(*aname, tokval))
156: goto next;
157: }
1.16 christos 158: }
1.1 cgd 159: break;
160: case PASSWD:
1.6 tls 161: if ((*aname == NULL || strcmp(*aname, "anonymous")) &&
1.1 cgd 162: fstat(fileno(cfile), &stb) >= 0 &&
163: (stb.st_mode & 077) != 0) {
1.3 cgd 164: warnx("Error: .netrc file is readable by others.");
165: warnx("Remove password or make file unreadable by others.");
1.1 cgd 166: goto bad;
167: }
1.20 lukem 168: if (token() && *apass == NULL)
169: *apass = xstrdup(tokval);
1.1 cgd 170: break;
171: case ACCOUNT:
172: if (fstat(fileno(cfile), &stb) >= 0
173: && (stb.st_mode & 077) != 0) {
1.3 cgd 174: warnx("Error: .netrc file is readable by others.");
175: warnx("Remove account or make file unreadable by others.");
1.1 cgd 176: goto bad;
177: }
1.20 lukem 178: if (token() && *aacct == NULL)
179: *aacct = xstrdup(tokval);
1.1 cgd 180: break;
181: case MACDEF:
182: if (proxy) {
1.12 lukem 183: (void)fclose(cfile);
1.3 cgd 184: return (0);
1.1 cgd 185: }
1.17 lukem 186: while ((c = getc(cfile)) != EOF)
1.11 lukem 187: if (c != ' ' && c != '\t')
188: break;
1.1 cgd 189: if (c == EOF || c == '\n') {
1.17 lukem 190: fputs("Missing macdef name argument.\n",
191: ttyout);
1.1 cgd 192: goto bad;
193: }
194: if (macnum == 16) {
1.17 lukem 195: fputs(
196: "Limit of 16 macros have already been defined.\n",
197: ttyout);
1.1 cgd 198: goto bad;
199: }
200: tmp = macros[macnum].mac_name;
201: *tmp++ = c;
1.17 lukem 202: for (i = 0; i < 8 && (c = getc(cfile)) != EOF &&
1.1 cgd 203: !isspace(c); ++i) {
204: *tmp++ = c;
205: }
206: if (c == EOF) {
1.17 lukem 207: fputs(
208: "Macro definition missing null line terminator.\n",
209: ttyout);
1.1 cgd 210: goto bad;
211: }
212: *tmp = '\0';
213: if (c != '\n') {
1.17 lukem 214: while ((c = getc(cfile)) != EOF && c != '\n');
1.1 cgd 215: }
216: if (c == EOF) {
1.17 lukem 217: fputs(
218: "Macro definition missing null line terminator.\n",
219: ttyout);
1.1 cgd 220: goto bad;
221: }
222: if (macnum == 0) {
223: macros[macnum].mac_start = macbuf;
224: }
225: else {
1.9 lukem 226: macros[macnum].mac_start =
227: macros[macnum-1].mac_end + 1;
1.1 cgd 228: }
229: tmp = macros[macnum].mac_start;
230: while (tmp != macbuf + 4096) {
1.17 lukem 231: if ((c = getc(cfile)) == EOF) {
232: fputs(
233: "Macro definition missing null line terminator.\n",
234: ttyout);
1.1 cgd 235: goto bad;
236: }
237: *tmp = c;
238: if (*tmp == '\n') {
239: if (*(tmp-1) == '\0') {
240: macros[macnum++].mac_end = tmp - 1;
241: break;
242: }
243: *tmp = '\0';
244: }
245: tmp++;
246: }
247: if (tmp == macbuf + 4096) {
1.17 lukem 248: fputs("4K macro buffer exceeded.\n",
249: ttyout);
1.1 cgd 250: goto bad;
251: }
252: break;
253: default:
1.3 cgd 254: warnx("Unknown .netrc keyword %s", tokval);
1.1 cgd 255: break;
256: }
257: goto done;
258: }
259: done:
1.12 lukem 260: (void)fclose(cfile);
1.3 cgd 261: return (0);
1.1 cgd 262: bad:
1.12 lukem 263: (void)fclose(cfile);
1.3 cgd 264: return (-1);
1.1 cgd 265: }
266:
1.3 cgd 267: static int
1.1 cgd 268: token()
269: {
270: char *cp;
271: int c;
272: struct toktab *t;
273:
1.3 cgd 274: if (feof(cfile) || ferror(cfile))
1.1 cgd 275: return (0);
276: while ((c = getc(cfile)) != EOF &&
277: (c == '\n' || c == '\t' || c == ' ' || c == ','))
278: continue;
279: if (c == EOF)
280: return (0);
281: cp = tokval;
282: if (c == '"') {
283: while ((c = getc(cfile)) != EOF && c != '"') {
284: if (c == '\\')
285: c = getc(cfile);
286: *cp++ = c;
287: }
288: } else {
289: *cp++ = c;
290: while ((c = getc(cfile)) != EOF
291: && c != '\n' && c != '\t' && c != ' ' && c != ',') {
292: if (c == '\\')
293: c = getc(cfile);
294: *cp++ = c;
295: }
296: }
297: *cp = 0;
298: if (tokval[0] == 0)
299: return (0);
300: for (t = toktab; t->tokstr; t++)
301: if (!strcmp(t->tokstr, tokval))
302: return (t->tval);
303: return (ID);
304: }
CVSweb <webmaster@jp.NetBSD.org>