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 #include "ftp_var.h"
40
41 static FILE *cfile;
42
43 static int rnetrc(char *host, char **aname, char **apass, char **aacct);
44 static int token(void);
45
46 int
ruserpass(char * host,char ** aname,char ** apass,char ** aacct)47 ruserpass(char *host, char **aname, char **apass, char **aacct)
48 {
49 #if 0
50 renv(host, aname, apass, aacct);
51 if (*aname == 0 || *apass == 0)
52 #endif
53 return (rnetrc(host, aname, apass, aacct));
54 }
55
56 #define DEFAULT 1
57 #define LOGIN 2
58 #define PASSWD 3
59 #define ACCOUNT 4
60 #define MACDEF 5
61 #define SKIPSYST 6
62 #define ID 10
63 #define MACHINE 11
64
65 static char tokval[100];
66
67 static struct toktab {
68 char *tokstr;
69 int tval;
70 } toktab[] = {
71 "default", DEFAULT,
72 "login", LOGIN,
73 "password", PASSWD,
74 "account", ACCOUNT,
75 "machine", MACHINE,
76 "macdef", MACDEF,
77 "skipsyst", SKIPSYST,
78 0, 0
79 };
80
81 static int
rnetrc(char * host,char ** aname,char ** apass,char ** aacct)82 rnetrc(char *host, char **aname, char **apass, char **aacct)
83 {
84 char *hdir, buf[PATH_MAX+1], *tmp;
85 int t, i, c;
86 struct stat stb;
87 extern int errno;
88
89 hdir = getenv("HOME");
90 if (hdir == NULL)
91 hdir = ".";
92 if (snprintf(buf, sizeof (buf), "%s/.netrc", hdir) >= sizeof (buf)) {
93 fprintf(stderr, ".netrc: %s\n", strerror(ENAMETOOLONG));
94 exit(1);
95 }
96
97 cfile = fopen(buf, "r");
98 if (cfile == NULL) {
99 if (errno != ENOENT)
100 perror(buf);
101 return (0);
102 }
103 next:
104 while ((t = token()))
105 switch (t) {
106
107 case MACHINE:
108 if (token() != ID || strcmp(host, tokval))
109 continue;
110 /* "machine name" matches host */
111 /* FALLTHROUGH */
112
113 case DEFAULT:
114 /* "default" matches any host */
115 while (((t = token()) != 0) && t != MACHINE && t != DEFAULT)
116 switch (t) {
117
118 case LOGIN:
119 if (token())
120 if (*aname == 0) {
121 *aname = malloc((unsigned)
122 strlen(tokval) + 1);
123 if (*aname == NULL) {
124 fprintf(stderr,
125 "Error - out of VM\n");
126 exit(1);
127 }
128 (void) strcpy(*aname, tokval);
129 } else {
130 if (strcmp(*aname, tokval))
131 goto next;
132 }
133 break;
134 case PASSWD:
135 if (fstat(fileno(cfile), &stb) >= 0 &&
136 (stb.st_mode & 077) != 0) {
137 fprintf(stderr, "Error - .netrc file not "
138 "correct mode.\n");
139 fprintf(stderr, "Remove password or correct "
140 "mode.\n");
141 return (-1);
142 }
143 if (token() && *apass == 0) {
144 *apass = malloc((unsigned)strlen(tokval) + 1);
145 if (*apass == NULL) {
146 fprintf(stderr, "Error - out of VM\n");
147 exit(1);
148 }
149 (void) strcpy(*apass, tokval);
150 }
151 break;
152 case ACCOUNT:
153 if (fstat(fileno(cfile), &stb) >= 0 &&
154 (stb.st_mode & 077) != 0) {
155 fprintf(stderr, "Error - .netrc file not "
156 "correct mode.\n");
157 fprintf(stderr, "Remove account or correct "
158 "mode.\n");
159 return (-1);
160 }
161 if (token() && *aacct == 0) {
162 *aacct = malloc((unsigned)strlen(tokval) + 1);
163 if (*aacct == NULL) {
164 fprintf(stderr, "Error - out of VM\n");
165 exit(1);
166 }
167 (void) strcpy(*aacct, tokval);
168 }
169 break;
170 case MACDEF:
171 if (proxy) {
172 return (0);
173 }
174 while ((c = getc(cfile)) != EOF && c == ' ' ||
175 c == '\t');
176 if (c == EOF || c == '\n') {
177 printf("Missing macdef name argument.\n");
178 return (-1);
179 }
180 if (macnum == 16) {
181 printf("Limit of 16 macros have already "
182 "been defined\n");
183 return (-1);
184 }
185 tmp = macros[macnum].mac_name;
186 *tmp++ = c;
187 for (i = 0; i < 8 && (c = getc(cfile)) != EOF &&
188 !isspace(c); ++i) {
189 *tmp++ = c;
190 }
191 if (c == EOF) {
192 printf("Macro definition for `%s` missing "
193 "null line terminator.\n",
194 macros[macnum].mac_name);
195 return (-1);
196 }
197 *tmp = '\0';
198 if (c != '\n') {
199 while ((c = getc(cfile)) != EOF && c != '\n');
200 }
201 if (c == EOF) {
202 printf("Macro definition for `%s` missing "
203 "null line terminator.\n",
204 macros[macnum].mac_name);
205 return (-1);
206 }
207 if (macnum == 0) {
208 macros[macnum].mac_start = macbuf;
209 } else {
210 macros[macnum].mac_start =
211 macros[macnum-1].mac_end + 1;
212 }
213 tmp = macros[macnum].mac_start;
214 while (tmp != macbuf + 4096) {
215 if ((c = getc(cfile)) == EOF) {
216 printf("Macro definition for `%s` missing "
217 "null line terminator.\n",
218 macros[macnum].mac_name);
219 return (-1);
220 }
221 *tmp = c;
222 if (*tmp == '\n') {
223 if (*(tmp-1) == '\0') {
224 macros[macnum++].mac_end =
225 tmp - 1;
226 break;
227 }
228 *tmp = '\0';
229 }
230 tmp++;
231 }
232 if (tmp == macbuf + 4096) {
233 printf("4K macro buffer exceeded\n");
234 return (-1);
235 }
236 if (*macros[macnum - 1].mac_start == '\n') {
237 printf("Macro definition for `%s` is empty, "
238 "macro not stored.\n",
239 macros[--macnum].mac_name);
240 }
241 break;
242 case SKIPSYST:
243 skipsyst = 1;
244 break;
245 default:
246 fprintf(stderr, "Unknown .netrc keyword %s\n", tokval);
247 break;
248 }
249 goto done;
250 }
251 done:
252 (void) fclose(cfile);
253 return (0);
254 }
255
256 static int
token(void)257 token(void)
258 {
259 char *cp;
260 int c;
261 struct toktab *t;
262 int len;
263
264 if (feof(cfile))
265 return (0);
266 while ((c = fgetwc(cfile)) != EOF &&
267 (c == '\n' || c == '\t' || c == ' ' || c == ','))
268 continue;
269 if (c == EOF)
270 return (0);
271 cp = tokval;
272 if (c == '"') {
273 while ((c = fgetwc(cfile)) != EOF && c != '"') {
274 if (c == '\\')
275 c = fgetwc(cfile);
276 if ((len = wctomb(cp, c)) <= 0) {
277 len = 1;
278 *cp = (unsigned char)c;
279 }
280 cp += len;
281 }
282 } else {
283 if ((len = wctomb(cp, c)) <= 0) {
284 *cp = (unsigned char)c;
285 len = 1;
286 }
287 cp += len;
288 while ((c = fgetwc(cfile)) != EOF && c != '\n' && c != '\t' &&
289 c != ' ' && c != ',') {
290 if (c == '\\')
291 c = fgetwc(cfile);
292 if ((len = wctomb(cp, c)) <= 0) {
293 len = 1;
294 *cp = (unsigned char)c;
295 }
296 cp += len;
297 }
298 }
299 *cp = 0;
300 if (tokval[0] == 0)
301 return (0);
302 for (t = toktab; t->tokstr; t++)
303 if (strcmp(t->tokstr, tokval) == 0)
304 return (t->tval);
305 return (ID);
306 }
307