xref: /csrg-svn/usr.bin/ftp/ruserpass.c (revision 36940)
126053Sminshall /*
226053Sminshall  * Copyright (c) 1985 Regents of the University of California.
333737Sbostic  * All rights reserved.
433737Sbostic  *
533737Sbostic  * Redistribution and use in source and binary forms are permitted
634901Sbostic  * provided that the above copyright notice and this paragraph are
734901Sbostic  * duplicated in all such forms and that any documentation,
834901Sbostic  * advertising materials, and other materials related to such
934901Sbostic  * distribution and use acknowledge that the software was developed
1034901Sbostic  * by the University of California, Berkeley.  The name of the
1134901Sbostic  * University may not be used to endorse or promote products derived
1234901Sbostic  * from this software without specific prior written permission.
1334901Sbostic  * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
1434901Sbostic  * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
1536935Skarels  * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
1626053Sminshall  */
1726053Sminshall 
1826053Sminshall #ifndef lint
19*36940Skarels static char sccsid[] = "@(#)ruserpass.c	1.8 (Berkeley) 03/01/89";
2033737Sbostic #endif /* not lint */
2126053Sminshall 
2235631Sbostic #include <sys/types.h>
2326053Sminshall #include <stdio.h>
2426053Sminshall #include <utmp.h>
2526053Sminshall #include <ctype.h>
2626053Sminshall #include <sys/stat.h>
2726053Sminshall #include <errno.h>
28*36940Skarels #include "ftp_var.h"
2926053Sminshall 
3026053Sminshall char	*renvlook(), *malloc(), *index(), *getenv(), *getpass(), *getlogin();
3126498Sminshall char	*strcpy();
3226053Sminshall struct	utmp *getutmp();
3326053Sminshall static	FILE *cfile;
3426053Sminshall 
3526053Sminshall #define	DEFAULT	1
3626053Sminshall #define	LOGIN	2
3726053Sminshall #define	PASSWD	3
3826053Sminshall #define	ACCOUNT 4
3926053Sminshall #define MACDEF  5
4026053Sminshall #define	ID	10
41*36940Skarels #define	MACH	11
4226053Sminshall 
4326053Sminshall static char tokval[100];
4426053Sminshall 
4526053Sminshall static struct toktab {
4626053Sminshall 	char *tokstr;
4726053Sminshall 	int tval;
4826053Sminshall } toktab[]= {
4926053Sminshall 	"default",	DEFAULT,
5026053Sminshall 	"login",	LOGIN,
5126053Sminshall 	"password",	PASSWD,
52*36940Skarels 	"passwd",	PASSWD,
5326053Sminshall 	"account",	ACCOUNT,
54*36940Skarels 	"machine",	MACH,
5526053Sminshall 	"macdef",	MACDEF,
5626053Sminshall 	0,		0
5726053Sminshall };
5826053Sminshall 
59*36940Skarels ruserpass(host, aname, apass, aacct)
6026053Sminshall 	char *host, **aname, **apass, **aacct;
6126053Sminshall {
6226498Sminshall 	char *hdir, buf[BUFSIZ], *tmp;
63*36940Skarels 	char myname[MAXHOSTNAMELEN], *mydomain;
6436935Skarels 	int t, i, c, usedefault = 0;
6526053Sminshall 	struct stat stb;
6626053Sminshall 	extern int errno;
6726053Sminshall 
6826053Sminshall 	hdir = getenv("HOME");
6926053Sminshall 	if (hdir == NULL)
7026053Sminshall 		hdir = ".";
7126498Sminshall 	(void) sprintf(buf, "%s/.netrc", hdir);
7226053Sminshall 	cfile = fopen(buf, "r");
7326053Sminshall 	if (cfile == NULL) {
7426053Sminshall 		if (errno != ENOENT)
7526053Sminshall 			perror(buf);
7626053Sminshall 		return(0);
7726053Sminshall 	}
78*36940Skarels 	if (gethostname(myname, sizeof(myname)) < 0)
79*36940Skarels 		myname[0] = '\0';
80*36940Skarels 	if ((mydomain = index(myname, '.')) == NULL)
81*36940Skarels 		mydomain = "";
8226053Sminshall next:
8326053Sminshall 	while ((t = token())) switch(t) {
8426053Sminshall 
8526053Sminshall 	case DEFAULT:
8636935Skarels 		usedefault = 1;
8736935Skarels 		/* FALL THROUGH */
8826053Sminshall 
89*36940Skarels 	case MACH:
90*36940Skarels 		if (!usedefault) {
91*36940Skarels 			if (token() != ID)
92*36940Skarels 				continue;
93*36940Skarels 			/*
94*36940Skarels 			 * Allow match either for user's input host name
95*36940Skarels 			 * or official hostname.  Also allow match of
96*36940Skarels 			 * incompletely-specified host in local domain.
97*36940Skarels 			 */
98*36940Skarels 			if (strcasecmp(host, tokval) == 0)
99*36940Skarels 				goto match;
100*36940Skarels 			if (strcasecmp(hostname, tokval) == 0)
101*36940Skarels 				goto match;
102*36940Skarels 			if ((tmp = index(hostname, '.')) != NULL &&
103*36940Skarels 			    strcasecmp(tmp, mydomain) == 0 &&
104*36940Skarels 			    strncasecmp(hostname, tokval, tmp-hostname) == 0 &&
105*36940Skarels 			    tokval[tmp - hostname] == '\0')
106*36940Skarels 				goto match;
107*36940Skarels 			if ((tmp = index(host, '.')) != NULL &&
108*36940Skarels 			    strcasecmp(tmp, mydomain) == 0 &&
109*36940Skarels 			    strncasecmp(host, tokval, tmp - host) == 0 &&
110*36940Skarels 			    tokval[tmp - host] == '\0')
111*36940Skarels 				goto match;
11226053Sminshall 			continue;
113*36940Skarels 		}
114*36940Skarels 	match:
115*36940Skarels 		while ((t = token()) && t != MACH && t != DEFAULT) switch(t) {
11626053Sminshall 
11726053Sminshall 		case LOGIN:
11826053Sminshall 			if (token())
11926053Sminshall 				if (*aname == 0) {
12026498Sminshall 					*aname = malloc((unsigned) strlen(tokval) + 1);
12126498Sminshall 					(void) strcpy(*aname, tokval);
12226053Sminshall 				} else {
12326053Sminshall 					if (strcmp(*aname, tokval))
12426053Sminshall 						goto next;
12526053Sminshall 				}
12626053Sminshall 			break;
12726053Sminshall 		case PASSWD:
128*36940Skarels 			if (strcmp(*aname, "anonymous") &&
129*36940Skarels 			    fstat(fileno(cfile), &stb) >= 0 &&
130*36940Skarels 			    (stb.st_mode & 077) != 0) {
13126054Sminshall 	fprintf(stderr, "Error - .netrc file not correct mode.\n");
13226053Sminshall 	fprintf(stderr, "Remove password or correct mode.\n");
133*36940Skarels 				goto bad;
13426053Sminshall 			}
13526053Sminshall 			if (token() && *apass == 0) {
13626498Sminshall 				*apass = malloc((unsigned) strlen(tokval) + 1);
13726498Sminshall 				(void) strcpy(*apass, tokval);
13826053Sminshall 			}
13926053Sminshall 			break;
14026053Sminshall 		case ACCOUNT:
14126053Sminshall 			if (fstat(fileno(cfile), &stb) >= 0
14226053Sminshall 			    && (stb.st_mode & 077) != 0) {
14326054Sminshall 	fprintf(stderr, "Error - .netrc file not correct mode.\n");
14426053Sminshall 	fprintf(stderr, "Remove account or correct mode.\n");
145*36940Skarels 				goto bad;
14626053Sminshall 			}
14726053Sminshall 			if (token() && *aacct == 0) {
14826498Sminshall 				*aacct = malloc((unsigned) strlen(tokval) + 1);
14926498Sminshall 				(void) strcpy(*aacct, tokval);
15026053Sminshall 			}
15126053Sminshall 			break;
15226053Sminshall 		case MACDEF:
15326053Sminshall 			if (proxy) {
154*36940Skarels 				(void) fclose(cfile);
15526053Sminshall 				return(0);
15626053Sminshall 			}
15726053Sminshall 			while ((c=getc(cfile)) != EOF && c == ' ' || c == '\t');
15826053Sminshall 			if (c == EOF || c == '\n') {
15926053Sminshall 				printf("Missing macdef name argument.\n");
160*36940Skarels 				goto bad;
16126053Sminshall 			}
16226053Sminshall 			if (macnum == 16) {
16326053Sminshall 				printf("Limit of 16 macros have already been defined\n");
164*36940Skarels 				goto bad;
16526053Sminshall 			}
16626053Sminshall 			tmp = macros[macnum].mac_name;
16726053Sminshall 			*tmp++ = c;
16826053Sminshall 			for (i=0; i < 8 && (c=getc(cfile)) != EOF &&
16926053Sminshall 			    !isspace(c); ++i) {
17026053Sminshall 				*tmp++ = c;
17126053Sminshall 			}
17226053Sminshall 			if (c == EOF) {
17326053Sminshall 				printf("Macro definition missing null line terminator.\n");
174*36940Skarels 				goto bad;
17526053Sminshall 			}
17626053Sminshall 			*tmp = '\0';
17726053Sminshall 			if (c != '\n') {
17826053Sminshall 				while ((c=getc(cfile)) != EOF && c != '\n');
17926053Sminshall 			}
18026053Sminshall 			if (c == EOF) {
18126053Sminshall 				printf("Macro definition missing null line terminator.\n");
182*36940Skarels 				goto bad;
18326053Sminshall 			}
18426053Sminshall 			if (macnum == 0) {
18526053Sminshall 				macros[macnum].mac_start = macbuf;
18626053Sminshall 			}
18726053Sminshall 			else {
18826053Sminshall 				macros[macnum].mac_start = macros[macnum-1].mac_end + 1;
18926053Sminshall 			}
19026053Sminshall 			tmp = macros[macnum].mac_start;
19126053Sminshall 			while (tmp != macbuf + 4096) {
19226053Sminshall 				if ((c=getc(cfile)) == EOF) {
19326053Sminshall 				printf("Macro definition missing null line terminator.\n");
194*36940Skarels 					goto bad;
19526053Sminshall 				}
19626053Sminshall 				*tmp = c;
19726053Sminshall 				if (*tmp == '\n') {
19826053Sminshall 					if (*(tmp-1) == '\0') {
19926053Sminshall 					   macros[macnum++].mac_end = tmp - 1;
20026053Sminshall 					   break;
20126053Sminshall 					}
20226053Sminshall 					*tmp = '\0';
20326053Sminshall 				}
20426053Sminshall 				tmp++;
20526053Sminshall 			}
20626053Sminshall 			if (tmp == macbuf + 4096) {
20726053Sminshall 				printf("4K macro buffer exceeded\n");
208*36940Skarels 				goto bad;
20926053Sminshall 			}
21026053Sminshall 			break;
21126053Sminshall 		default:
21226054Sminshall 	fprintf(stderr, "Unknown .netrc keyword %s\n", tokval);
21326053Sminshall 			break;
21426053Sminshall 		}
21526053Sminshall 		goto done;
21626053Sminshall 	}
21726053Sminshall done:
21826498Sminshall 	(void) fclose(cfile);
21926498Sminshall 	return(0);
220*36940Skarels bad:
221*36940Skarels 	(void) fclose(cfile);
222*36940Skarels 	return(-1);
22326053Sminshall }
22426053Sminshall 
22526053Sminshall static
22626053Sminshall token()
22726053Sminshall {
22826053Sminshall 	char *cp;
22926053Sminshall 	int c;
23026053Sminshall 	struct toktab *t;
23126053Sminshall 
23226053Sminshall 	if (feof(cfile))
23326053Sminshall 		return (0);
23426053Sminshall 	while ((c = getc(cfile)) != EOF &&
23526053Sminshall 	    (c == '\n' || c == '\t' || c == ' ' || c == ','))
23626053Sminshall 		continue;
23726053Sminshall 	if (c == EOF)
23826053Sminshall 		return (0);
23926053Sminshall 	cp = tokval;
24026053Sminshall 	if (c == '"') {
24126053Sminshall 		while ((c = getc(cfile)) != EOF && c != '"') {
24226053Sminshall 			if (c == '\\')
24326053Sminshall 				c = getc(cfile);
24426053Sminshall 			*cp++ = c;
24526053Sminshall 		}
24626053Sminshall 	} else {
24726053Sminshall 		*cp++ = c;
24826053Sminshall 		while ((c = getc(cfile)) != EOF
24926053Sminshall 		    && c != '\n' && c != '\t' && c != ' ' && c != ',') {
25026053Sminshall 			if (c == '\\')
25126053Sminshall 				c = getc(cfile);
25226053Sminshall 			*cp++ = c;
25326053Sminshall 		}
25426053Sminshall 	}
25526053Sminshall 	*cp = 0;
25626053Sminshall 	if (tokval[0] == 0)
25726053Sminshall 		return (0);
25826053Sminshall 	for (t = toktab; t->tokstr; t++)
25926053Sminshall 		if (!strcmp(t->tokstr, tokval))
26026053Sminshall 			return (t->tval);
26126053Sminshall 	return (ID);
26226053Sminshall }
263