Home | History | Annotate | Download | only in ftp
      1 /*
      2  * CDDL HEADER START
      3  *
      4  * The contents of this file are subject to the terms of the
      5  * Common Development and Distribution License (the "License").
      6  * You may not use this file except in compliance with the License.
      7  *
      8  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
      9  * or http://www.opensolaris.org/os/licensing.
     10  * See the License for the specific language governing permissions
     11  * and limitations under the License.
     12  *
     13  * When distributing Covered Code, include this CDDL HEADER in each
     14  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
     15  * If applicable, add the following below this CDDL HEADER, with the
     16  * fields enclosed by brackets "[]" replaced with your own identifying
     17  * information: Portions Copyright [yyyy] [name of copyright owner]
     18  *
     19  * CDDL HEADER END
     20  */
     21 /*
     22  *	Copyright 2006 Sun Microsystems, Inc.  All rights reserved.
     23  *	Use is subject to license terms.
     24  */
     25 
     26 /*	Copyright (c) 1983, 1984, 1985, 1986, 1987, 1988, 1989 AT&T	*/
     27 /*	All Rights Reserved  	*/
     28 
     29 /*
     30  *	University Copyright- Copyright (c) 1982, 1986, 1988
     31  *	The Regents of the University of California
     32  *	All Rights Reserved
     33  *
     34  *	University Acknowledgment- Portions of this document are derived from
     35  *	software developed by the University of California, Berkeley, and its
     36  *	contributors.
     37  */
     38 
     39 #pragma ident	"%Z%%M%	%I%	%E% SMI"
     40 
     41 #include "ftp_var.h"
     42 
     43 static	FILE *cfile;
     44 
     45 static int rnetrc(char *host, char **aname, char **apass, char **aacct);
     46 static int token(void);
     47 
     48 int
     49 ruserpass(char *host, char **aname, char **apass, char **aacct)
     50 {
     51 #if 0
     52 	renv(host, aname, apass, aacct);
     53 	if (*aname == 0 || *apass == 0)
     54 #endif
     55 		return (rnetrc(host, aname, apass, aacct));
     56 }
     57 
     58 #define	DEFAULT	1
     59 #define	LOGIN	2
     60 #define	PASSWD	3
     61 #define	ACCOUNT 4
     62 #define	MACDEF	5
     63 #define	SKIPSYST	6
     64 #define	ID	10
     65 #define	MACHINE	11
     66 
     67 static char tokval[100];
     68 
     69 static struct toktab {
     70 	char *tokstr;
     71 	int tval;
     72 } toktab[] = {
     73 	"default",	DEFAULT,
     74 	"login",	LOGIN,
     75 	"password",	PASSWD,
     76 	"account",	ACCOUNT,
     77 	"machine",	MACHINE,
     78 	"macdef",	MACDEF,
     79 	"skipsyst",	SKIPSYST,
     80 	0,		0
     81 };
     82 
     83 static int
     84 rnetrc(char *host, char **aname, char **apass, char **aacct)
     85 {
     86 	char *hdir, buf[PATH_MAX+1], *tmp;
     87 	int t, i, c;
     88 	struct stat stb;
     89 	extern int errno;
     90 
     91 	hdir = getenv("HOME");
     92 	if (hdir == NULL)
     93 		hdir = ".";
     94 	if (snprintf(buf, sizeof (buf), "%s/.netrc", hdir) >= sizeof (buf)) {
     95 		fprintf(stderr, ".netrc: %s\n", strerror(ENAMETOOLONG));
     96 		exit(1);
     97 	}
     98 
     99 	cfile = fopen(buf, "r");
    100 	if (cfile == NULL) {
    101 		if (errno != ENOENT)
    102 			perror(buf);
    103 		return (0);
    104 	}
    105 next:
    106 	while ((t = token()))
    107 		switch (t) {
    108 
    109 	case MACHINE:
    110 		if (token() != ID || strcmp(host, tokval))
    111 			continue;
    112 		/* "machine name" matches host */
    113 		/* FALLTHROUGH */
    114 
    115 	case DEFAULT:
    116 		/* "default" matches any host */
    117 		while (((t = token()) != 0) && t != MACHINE && t != DEFAULT)
    118 			switch (t) {
    119 
    120 		case LOGIN:
    121 			if (token())
    122 				if (*aname == 0) {
    123 					*aname = malloc((unsigned)
    124 					    strlen(tokval) + 1);
    125 					if (*aname == NULL) {
    126 						fprintf(stderr,
    127 						    "Error - out of VM\n");
    128 						exit(1);
    129 					}
    130 					(void) strcpy(*aname, tokval);
    131 				} else {
    132 					if (strcmp(*aname, tokval))
    133 						goto next;
    134 				}
    135 			break;
    136 		case PASSWD:
    137 			if (fstat(fileno(cfile), &stb) >= 0 &&
    138 			    (stb.st_mode & 077) != 0) {
    139 				fprintf(stderr, "Error - .netrc file not "
    140 				    "correct mode.\n");
    141 				fprintf(stderr, "Remove password or correct "
    142 				    "mode.\n");
    143 				return (-1);
    144 			}
    145 			if (token() && *apass == 0) {
    146 				*apass = malloc((unsigned)strlen(tokval) + 1);
    147 				if (*apass == NULL) {
    148 					fprintf(stderr, "Error - out of VM\n");
    149 					exit(1);
    150 				}
    151 				(void) strcpy(*apass, tokval);
    152 			}
    153 			break;
    154 		case ACCOUNT:
    155 			if (fstat(fileno(cfile), &stb) >= 0 &&
    156 			    (stb.st_mode & 077) != 0) {
    157 				fprintf(stderr, "Error - .netrc file not "
    158 				    "correct mode.\n");
    159 				fprintf(stderr, "Remove account or correct "
    160 				    "mode.\n");
    161 				return (-1);
    162 			}
    163 			if (token() && *aacct == 0) {
    164 				*aacct = malloc((unsigned)strlen(tokval) + 1);
    165 				if (*aacct == NULL) {
    166 					fprintf(stderr, "Error - out of VM\n");
    167 					exit(1);
    168 				}
    169 				(void) strcpy(*aacct, tokval);
    170 			}
    171 			break;
    172 		case MACDEF:
    173 			if (proxy) {
    174 				return (0);
    175 			}
    176 			while ((c = getc(cfile)) != EOF && c == ' ' ||
    177 			    c == '\t');
    178 			if (c == EOF || c == '\n') {
    179 				printf("Missing macdef name argument.\n");
    180 				return (-1);
    181 			}
    182 			if (macnum == 16) {
    183 				printf("Limit of 16 macros have already "
    184 				    "been defined\n");
    185 				return (-1);
    186 			}
    187 			tmp = macros[macnum].mac_name;
    188 			*tmp++ = c;
    189 			for (i = 0; i < 8 && (c = getc(cfile)) != EOF &&
    190 			    !isspace(c); ++i) {
    191 				*tmp++ = c;
    192 			}
    193 			if (c == EOF) {
    194 				printf("Macro definition for `%s` missing "
    195 				    "null line terminator.\n",
    196 				    macros[macnum].mac_name);
    197 				return (-1);
    198 			}
    199 			*tmp = '\0';
    200 			if (c != '\n') {
    201 				while ((c = getc(cfile)) != EOF && c != '\n');
    202 			}
    203 			if (c == EOF) {
    204 				printf("Macro definition for `%s` missing "
    205 				    "null line terminator.\n",
    206 				    macros[macnum].mac_name);
    207 				return (-1);
    208 			}
    209 			if (macnum == 0) {
    210 				macros[macnum].mac_start = macbuf;
    211 			} else {
    212 				macros[macnum].mac_start =
    213 				    macros[macnum-1].mac_end + 1;
    214 			}
    215 			tmp = macros[macnum].mac_start;
    216 			while (tmp != macbuf + 4096) {
    217 				if ((c = getc(cfile)) == EOF) {
    218 				printf("Macro definition for `%s` missing "
    219 				    "null line terminator.\n",
    220 				    macros[macnum].mac_name);
    221 					return (-1);
    222 				}
    223 				*tmp = c;
    224 				if (*tmp == '\n') {
    225 					if (*(tmp-1) == '\0') {
    226 						macros[macnum++].mac_end =
    227 						    tmp - 1;
    228 						break;
    229 					}
    230 					*tmp = '\0';
    231 				}
    232 				tmp++;
    233 			}
    234 			if (tmp == macbuf + 4096) {
    235 				printf("4K macro buffer exceeded\n");
    236 				return (-1);
    237 			}
    238 			if (*macros[macnum - 1].mac_start == '\n') {
    239 				printf("Macro definition for `%s` is empty, "
    240 				    "macro not stored.\n",
    241 					macros[--macnum].mac_name);
    242 			}
    243 			break;
    244 		case SKIPSYST:
    245 			skipsyst = 1;
    246 			break;
    247 		default:
    248 			fprintf(stderr, "Unknown .netrc keyword %s\n", tokval);
    249 			break;
    250 		}
    251 		goto done;
    252 	}
    253 done:
    254 	(void) fclose(cfile);
    255 	return (0);
    256 }
    257 
    258 static int
    259 token(void)
    260 {
    261 	char *cp;
    262 	int c;
    263 	struct toktab *t;
    264 	int	len;
    265 
    266 	if (feof(cfile))
    267 		return (0);
    268 	while ((c = fgetwc(cfile)) != EOF &&
    269 	    (c == '\n' || c == '\t' || c == ' ' || c == ','))
    270 		continue;
    271 	if (c == EOF)
    272 		return (0);
    273 	cp = tokval;
    274 	if (c == '"') {
    275 		while ((c = fgetwc(cfile)) != EOF && c != '"') {
    276 			if (c == '\\')
    277 				c = fgetwc(cfile);
    278 			if ((len = wctomb(cp, c)) <= 0) {
    279 				len = 1;
    280 				*cp = (unsigned char)c;
    281 			}
    282 			cp += len;
    283 		}
    284 	} else {
    285 		if ((len = wctomb(cp, c)) <= 0) {
    286 			*cp = (unsigned char)c;
    287 			len = 1;
    288 		}
    289 		cp += len;
    290 		while ((c = fgetwc(cfile)) != EOF && c != '\n' && c != '\t' &&
    291 		    c != ' ' && c != ',') {
    292 			if (c == '\\')
    293 				c = fgetwc(cfile);
    294 			if ((len = wctomb(cp, c)) <= 0) {
    295 				len = 1;
    296 				*cp = (unsigned char)c;
    297 			}
    298 			cp += len;
    299 		}
    300 	}
    301 	*cp = 0;
    302 	if (tokval[0] == 0)
    303 		return (0);
    304 	for (t = toktab; t->tokstr; t++)
    305 		if (strcmp(t->tokstr, tokval) == 0)
    306 			return (t->tval);
    307 	return (ID);
    308 }
    309