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
ruserpass(char * host,char ** aname,char ** apass,char ** aacct)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
rnetrc(char * host,char ** aname,char ** apass,char ** aacct)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
token(void)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