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