xref: /csrg-svn/usr.bin/ftp/ruserpass.c (revision 34901)
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
6*34901Sbostic  * provided that the above copyright notice and this paragraph are
7*34901Sbostic  * duplicated in all such forms and that any documentation,
8*34901Sbostic  * advertising materials, and other materials related to such
9*34901Sbostic  * distribution and use acknowledge that the software was developed
10*34901Sbostic  * by the University of California, Berkeley.  The name of the
11*34901Sbostic  * University may not be used to endorse or promote products derived
12*34901Sbostic  * from this software without specific prior written permission.
13*34901Sbostic  * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
14*34901Sbostic  * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
15*34901Sbostic  * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
1626053Sminshall  */
1726053Sminshall 
1826053Sminshall #ifndef lint
19*34901Sbostic static char sccsid[] = "@(#)ruserpass.c	1.5 (Berkeley) 06/29/88";
2033737Sbostic #endif /* not lint */
2126053Sminshall 
2226053Sminshall struct macel {
2326053Sminshall 	char mac_name[9];	/* macro name */
2426053Sminshall 	char *mac_start;	/* start of macro in macbuf */
2526053Sminshall 	char *mac_end;		/* end of macro in macbuf */
2626053Sminshall };
2726053Sminshall 
2826053Sminshall extern int macnum, proxy;			/* number of defined macros */
2926053Sminshall extern struct macel macros[16], *macpt;
3026053Sminshall extern char macbuf[4096];
3126053Sminshall 
3226053Sminshall #include <stdio.h>
3326053Sminshall #include <utmp.h>
3426053Sminshall #include <ctype.h>
3526053Sminshall #include <sys/types.h>
3626053Sminshall #include <sys/stat.h>
3726053Sminshall #include <errno.h>
3826053Sminshall 
3926053Sminshall char	*renvlook(), *malloc(), *index(), *getenv(), *getpass(), *getlogin();
4026498Sminshall char	*strcpy();
4126053Sminshall struct	utmp *getutmp();
4226053Sminshall static	FILE *cfile;
4326053Sminshall 
4426053Sminshall ruserpass(host, aname, apass, aacct)
4526053Sminshall 	char *host, **aname, **apass, **aacct;
4626053Sminshall {
4726053Sminshall 
4826053Sminshall 	/* renv(host, aname, apass, aacct);
4926053Sminshall 	if (*aname == 0 || *apass == 0) */
5026053Sminshall 		return(rnetrc(host, aname, apass, aacct));
5126053Sminshall }
5226053Sminshall 
5326053Sminshall #define	DEFAULT	1
5426053Sminshall #define	LOGIN	2
5526053Sminshall #define	PASSWD	3
5626053Sminshall #define	ACCOUNT 4
5726053Sminshall #define MACDEF  5
5826053Sminshall #define	ID	10
5926053Sminshall #define	MACHINE	11
6026053Sminshall 
6126053Sminshall static char tokval[100];
6226053Sminshall 
6326053Sminshall static struct toktab {
6426053Sminshall 	char *tokstr;
6526053Sminshall 	int tval;
6626053Sminshall } toktab[]= {
6726053Sminshall 	"default",	DEFAULT,
6826053Sminshall 	"login",	LOGIN,
6926053Sminshall 	"password",	PASSWD,
7026053Sminshall 	"account",	ACCOUNT,
7126053Sminshall 	"machine",	MACHINE,
7226053Sminshall 	"macdef",	MACDEF,
7326053Sminshall 	0,		0
7426053Sminshall };
7526053Sminshall 
7626053Sminshall static
7726053Sminshall rnetrc(host, aname, apass, aacct)
7826053Sminshall 	char *host, **aname, **apass, **aacct;
7926053Sminshall {
8026498Sminshall 	char *hdir, buf[BUFSIZ], *tmp;
8126498Sminshall 	int t, i, c;
8226053Sminshall 	struct stat stb;
8326053Sminshall 	extern int errno;
8426053Sminshall 
8526053Sminshall 	hdir = getenv("HOME");
8626053Sminshall 	if (hdir == NULL)
8726053Sminshall 		hdir = ".";
8826498Sminshall 	(void) sprintf(buf, "%s/.netrc", hdir);
8926053Sminshall 	cfile = fopen(buf, "r");
9026053Sminshall 	if (cfile == NULL) {
9126053Sminshall 		if (errno != ENOENT)
9226053Sminshall 			perror(buf);
9326053Sminshall 		return(0);
9426053Sminshall 	}
9526053Sminshall next:
9626053Sminshall 	while ((t = token())) switch(t) {
9726053Sminshall 
9826053Sminshall 	case DEFAULT:
9926053Sminshall 		(void) token();
10026053Sminshall 		continue;
10126053Sminshall 
10226053Sminshall 	case MACHINE:
10326053Sminshall 		if (token() != ID || strcmp(host, tokval))
10426053Sminshall 			continue;
10526053Sminshall 		while ((t = token()) && t != MACHINE) switch(t) {
10626053Sminshall 
10726053Sminshall 		case LOGIN:
10826053Sminshall 			if (token())
10926053Sminshall 				if (*aname == 0) {
11026498Sminshall 					*aname = malloc((unsigned) strlen(tokval) + 1);
11126498Sminshall 					(void) strcpy(*aname, tokval);
11226053Sminshall 				} else {
11326053Sminshall 					if (strcmp(*aname, tokval))
11426053Sminshall 						goto next;
11526053Sminshall 				}
11626053Sminshall 			break;
11726053Sminshall 		case PASSWD:
11826053Sminshall 			if (fstat(fileno(cfile), &stb) >= 0
11926053Sminshall 			    && (stb.st_mode & 077) != 0) {
12026054Sminshall 	fprintf(stderr, "Error - .netrc file not correct mode.\n");
12126053Sminshall 	fprintf(stderr, "Remove password or correct mode.\n");
12226053Sminshall 				return(-1);
12326053Sminshall 			}
12426053Sminshall 			if (token() && *apass == 0) {
12526498Sminshall 				*apass = malloc((unsigned) strlen(tokval) + 1);
12626498Sminshall 				(void) strcpy(*apass, tokval);
12726053Sminshall 			}
12826053Sminshall 			break;
12926053Sminshall 		case ACCOUNT:
13026053Sminshall 			if (fstat(fileno(cfile), &stb) >= 0
13126053Sminshall 			    && (stb.st_mode & 077) != 0) {
13226054Sminshall 	fprintf(stderr, "Error - .netrc file not correct mode.\n");
13326053Sminshall 	fprintf(stderr, "Remove account or correct mode.\n");
13426053Sminshall 				return(-1);
13526053Sminshall 			}
13626053Sminshall 			if (token() && *aacct == 0) {
13726498Sminshall 				*aacct = malloc((unsigned) strlen(tokval) + 1);
13826498Sminshall 				(void) strcpy(*aacct, tokval);
13926053Sminshall 			}
14026053Sminshall 			break;
14126053Sminshall 		case MACDEF:
14226053Sminshall 			if (proxy) {
14326053Sminshall 				return(0);
14426053Sminshall 			}
14526053Sminshall 			while ((c=getc(cfile)) != EOF && c == ' ' || c == '\t');
14626053Sminshall 			if (c == EOF || c == '\n') {
14726053Sminshall 				printf("Missing macdef name argument.\n");
14826053Sminshall 				return(-1);
14926053Sminshall 			}
15026053Sminshall 			if (macnum == 16) {
15126053Sminshall 				printf("Limit of 16 macros have already been defined\n");
15226053Sminshall 				return(-1);
15326053Sminshall 			}
15426053Sminshall 			tmp = macros[macnum].mac_name;
15526053Sminshall 			*tmp++ = c;
15626053Sminshall 			for (i=0; i < 8 && (c=getc(cfile)) != EOF &&
15726053Sminshall 			    !isspace(c); ++i) {
15826053Sminshall 				*tmp++ = c;
15926053Sminshall 			}
16026053Sminshall 			if (c == EOF) {
16126053Sminshall 				printf("Macro definition missing null line terminator.\n");
16226053Sminshall 				return(-1);
16326053Sminshall 			}
16426053Sminshall 			*tmp = '\0';
16526053Sminshall 			if (c != '\n') {
16626053Sminshall 				while ((c=getc(cfile)) != EOF && c != '\n');
16726053Sminshall 			}
16826053Sminshall 			if (c == EOF) {
16926053Sminshall 				printf("Macro definition missing null line terminator.\n");
17026053Sminshall 				return(-1);
17126053Sminshall 			}
17226053Sminshall 			if (macnum == 0) {
17326053Sminshall 				macros[macnum].mac_start = macbuf;
17426053Sminshall 			}
17526053Sminshall 			else {
17626053Sminshall 				macros[macnum].mac_start = macros[macnum-1].mac_end + 1;
17726053Sminshall 			}
17826053Sminshall 			tmp = macros[macnum].mac_start;
17926053Sminshall 			while (tmp != macbuf + 4096) {
18026053Sminshall 				if ((c=getc(cfile)) == EOF) {
18126053Sminshall 				printf("Macro definition missing null line terminator.\n");
18226053Sminshall 					return(-1);
18326053Sminshall 				}
18426053Sminshall 				*tmp = c;
18526053Sminshall 				if (*tmp == '\n') {
18626053Sminshall 					if (*(tmp-1) == '\0') {
18726053Sminshall 					   macros[macnum++].mac_end = tmp - 1;
18826053Sminshall 					   break;
18926053Sminshall 					}
19026053Sminshall 					*tmp = '\0';
19126053Sminshall 				}
19226053Sminshall 				tmp++;
19326053Sminshall 			}
19426053Sminshall 			if (tmp == macbuf + 4096) {
19526053Sminshall 				printf("4K macro buffer exceeded\n");
19626053Sminshall 				return(-1);
19726053Sminshall 			}
19826053Sminshall 			break;
19926053Sminshall 		default:
20026054Sminshall 	fprintf(stderr, "Unknown .netrc keyword %s\n", tokval);
20126053Sminshall 			break;
20226053Sminshall 		}
20326053Sminshall 		goto done;
20426053Sminshall 	}
20526053Sminshall done:
20626498Sminshall 	(void) fclose(cfile);
20726498Sminshall 	return(0);
20826053Sminshall }
20926053Sminshall 
21026053Sminshall static
21126053Sminshall token()
21226053Sminshall {
21326053Sminshall 	char *cp;
21426053Sminshall 	int c;
21526053Sminshall 	struct toktab *t;
21626053Sminshall 
21726053Sminshall 	if (feof(cfile))
21826053Sminshall 		return (0);
21926053Sminshall 	while ((c = getc(cfile)) != EOF &&
22026053Sminshall 	    (c == '\n' || c == '\t' || c == ' ' || c == ','))
22126053Sminshall 		continue;
22226053Sminshall 	if (c == EOF)
22326053Sminshall 		return (0);
22426053Sminshall 	cp = tokval;
22526053Sminshall 	if (c == '"') {
22626053Sminshall 		while ((c = getc(cfile)) != EOF && c != '"') {
22726053Sminshall 			if (c == '\\')
22826053Sminshall 				c = getc(cfile);
22926053Sminshall 			*cp++ = c;
23026053Sminshall 		}
23126053Sminshall 	} else {
23226053Sminshall 		*cp++ = c;
23326053Sminshall 		while ((c = getc(cfile)) != EOF
23426053Sminshall 		    && c != '\n' && c != '\t' && c != ' ' && c != ',') {
23526053Sminshall 			if (c == '\\')
23626053Sminshall 				c = getc(cfile);
23726053Sminshall 			*cp++ = c;
23826053Sminshall 		}
23926053Sminshall 	}
24026053Sminshall 	*cp = 0;
24126053Sminshall 	if (tokval[0] == 0)
24226053Sminshall 		return (0);
24326053Sminshall 	for (t = toktab; t->tokstr; t++)
24426053Sminshall 		if (!strcmp(t->tokstr, tokval))
24526053Sminshall 			return (t->tval);
24626053Sminshall 	return (ID);
24726053Sminshall }
248