xref: /titanic_52/usr/src/lib/libbc/libc/net/ruserpass.c (revision 74e20cfe817b82802b16fac8690dadcda76f54f5)
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, Version 1.0 only
6  * (the "License").  You may not use this file except in compliance
7  * with the License.
8  *
9  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
10  * or http://www.opensolaris.org/os/licensing.
11  * See the License for the specific language governing permissions
12  * and limitations under the License.
13  *
14  * When distributing Covered Code, include this CDDL HEADER in each
15  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
16  * If applicable, add the following below this CDDL HEADER, with the
17  * fields enclosed by brackets "[]" replaced with your own identifying
18  * information: Portions Copyright [yyyy] [name of copyright owner]
19  *
20  * CDDL HEADER END
21  */
22 /*
23  * Copyright 1989 Sun Microsystems, Inc.  All rights reserved.
24  * Use is subject to license terms.
25  */
26 
27 #pragma ident	"%Z%%M%	%I%	%E% SMI"
28 
29 #include <stdio.h>
30 #include <ctype.h>
31 #include <sys/types.h>
32 #include <sys/stat.h>
33 #include <errno.h>
34 #include <malloc.h>
35 #include <strings.h>
36 #include <stdlib.h>
37 #include <unistd.h>
38 
39 char	*getpass();
40 
41 #define	DEFAULT	1
42 #define	LOGIN	2
43 #define	PASSWD	3
44 #define	NOTIFY	4
45 #define	WRITE	5
46 #define	YES	6
47 #define	NO	7
48 #define	COMMAND	8
49 #define	FORCE	9
50 #define	ID	10
51 #define	MACHINE	11
52 
53 #define	MAXTOKEN  11
54 #define NTOKENS	(MAXTOKEN - 1 + 2 + 1)	/* two duplicates and null, minus id */
55 
56 static void	rnetrc(char *, char **, char **);
57 static int	token(void);
58 
59 static struct ruserdata {
60 	char tokval[100];
61 	struct toktab {
62 		char *tokstr;
63 		int tval;
64 	} toktab[NTOKENS];
65 	FILE *cfile;
66 } *ruserdata, *_ruserdata(void);
67 
68 
69 static struct ruserdata *
70 _ruserdata(void)
71 {
72 	struct ruserdata *d = ruserdata;
73 	struct toktab *t;
74 
75 	if (d == 0) {
76 		if ((d = (struct ruserdata *)
77 			calloc(1, sizeof(struct ruserdata))) == NULL) {
78 				return(NULL);
79 		}
80 		ruserdata = d;
81 		t = d->toktab;
82 		t->tokstr = "default";  t++->tval = DEFAULT;
83 		t->tokstr = "login";    t++->tval = LOGIN;
84 		t->tokstr = "password"; t++->tval = PASSWD;
85 		t->tokstr = "notify";   t++->tval = NOTIFY;
86 		t->tokstr = "write";    t++->tval = WRITE;
87 		t->tokstr = "yes";      t++->tval = YES;
88 		t->tokstr = "y";        t++->tval = YES;
89 		t->tokstr = "no";       t++->tval = NO;
90 		t->tokstr = "n";        t++->tval = NO;
91 		t->tokstr = "command";  t++->tval = COMMAND;
92 		t->tokstr = "force";    t++->tval = FORCE;
93 		t->tokstr = "machine";  t++->tval = MACHINE;
94 		t->tokstr = 0;          t->tval = 0;
95 	}
96 	return(d);
97 }
98 
99 void
100 _ruserpass(char *host, char **aname, char **apass)
101 {
102 
103 	if (*aname == 0 || *apass == 0)
104 		rnetrc(host, aname, apass);
105 	if (*aname == 0) {
106 		char *myname = getlogin();
107 		*aname = malloc(16);
108 		printf("Name (%s:%s): ", host, myname);
109 		fflush(stdout);
110 		if (read(2, *aname, 16) <= 0)
111 			exit(1);
112 		if ((*aname)[0] == '\n')
113 			*aname = myname;
114 		else
115 			if (index(*aname, '\n'))
116 				*index(*aname, '\n') = 0;
117 	}
118 	if (*aname && *apass == 0) {
119 		printf("Password (%s:%s): ", host, *aname);
120 		fflush(stdout);
121 		*apass = getpass("");
122 	}
123 }
124 
125 
126 static void
127 rnetrc(char *host, char **aname, char **apass)
128 {
129 	struct ruserdata *d = _ruserdata();
130 	char *hdir, buf[BUFSIZ];
131 	int t;
132 	struct stat stb;
133 
134 	if (d == 0)
135 		return;
136 
137 	hdir = getenv("HOME");
138 	if (hdir == NULL)
139 		hdir = ".";
140 	sprintf(buf, "%s/.netrc", hdir);
141 	d->cfile = fopen(buf, "r");
142 	if (d->cfile == NULL) {
143 		if (errno != ENOENT)
144 			perror(buf);
145 		return;
146 	}
147 next:
148 	while ((t = token())) switch(t) {
149 
150 	case DEFAULT:
151 		(void) token();
152 		continue;
153 
154 	case MACHINE:
155 		if (token() != ID || strcmp(host, d->tokval))
156 			continue;
157 		while ((t = token()) && t != MACHINE) switch(t) {
158 
159 		case LOGIN:
160 			if (token())
161 				if (*aname == 0) {
162 					*aname = malloc(strlen(d->tokval) + 1);
163 					strcpy(*aname, d->tokval);
164 				} else {
165 					if (strcmp(*aname, d->tokval))
166 						goto next;
167 				}
168 			break;
169 		case PASSWD:
170 			if (fstat(fileno(d->cfile), &stb) >= 0
171 			    && (stb.st_mode & 077) != 0) {
172 	fprintf(stderr, "Error - .netrc file not correct mode.\n");
173 	fprintf(stderr, "Remove password or correct mode.\n");
174 				exit(1);
175 			}
176 			if (token() && *apass == 0) {
177 				*apass = malloc(strlen(d->tokval) + 1);
178 				strcpy(*apass, d->tokval);
179 			}
180 			break;
181 		case COMMAND:
182 		case NOTIFY:
183 		case WRITE:
184 		case FORCE:
185 			(void) token();
186 			break;
187 		default:
188 	fprintf(stderr, "Unknown .netrc option %s\n", d->tokval);
189 			break;
190 		}
191 		goto done;
192 	}
193 done:
194 	fclose(d->cfile);
195 }
196 
197 static int
198 token(void)
199 {
200 	struct ruserdata *d = _ruserdata();
201 	char *cp;
202 	int c;
203 	struct toktab *t;
204 
205 	if (d == 0)
206 		return(0);
207 
208 	if (feof(d->cfile))
209 		return (0);
210 	while ((c = getc(d->cfile)) != EOF &&
211 	    (c == '\n' || c == '\t' || c == ' ' || c == ','))
212 		continue;
213 	if (c == EOF)
214 		return (0);
215 	cp = d->tokval;
216 	if (c == '"') {
217 		while ((c = getc(d->cfile)) != EOF && c != '"') {
218 			if (c == '\\')
219 				c = getc(d->cfile);
220 			*cp++ = c;
221 		}
222 	} else {
223 		*cp++ = c;
224 		while ((c = getc(d->cfile)) != EOF
225 		    && c != '\n' && c != '\t' && c != ' ' && c != ',') {
226 			if (c == '\\')
227 				c = getc(d->cfile);
228 			*cp++ = c;
229 		}
230 	}
231 	*cp = 0;
232 	if (d->tokval[0] == 0)
233 		return (0);
234 	for (t = d->toktab; t->tokstr; t++)
235 		if (!strcmp(t->tokstr, d->tokval))
236 			return (t->tval);
237 	return (ID);
238 }
239