1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
23:
24:
25:
26:
27:
28:
29:
30: #if defined(LIBC_SCCS) && !defined(lint)
31: static char sccsid[] = "@(#)ruserpass.c 8.3 (Berkeley) 4/2/94";
32: #endif
33:
34: #include <sys/types.h>
35: #include <sys/stat.h>
36:
37: #include <ctype.h>
38: #include <err.h>
39: #include <errno.h>
40: #include <netdb.h>
41: #include <stdio.h>
42: #include <stdio_ext.h>
43: #include <stdlib.h>
44: #include <string.h>
45: #include <unistd.h>
46: #include <libintl.h>
47:
48:
49:
50: static int token (void);
51: static FILE *cfile;
52:
53: #define DEFAULT 1
54: #define LOGIN 2
55: #define PASSWD 3
56: #define ACCOUNT 4
57: #define MACDEF 5
58: #define ID 10
59: #define MACHINE 11
60:
61: static char tokval[100];
62:
63: static const char tokstr[] =
64: {
65: #define TOK_DEFAULT_IDX 0
66: "default\0"
67: #define TOK_LOGIN_IDX (TOK_DEFAULT_IDX + sizeof "default")
68: "login\0"
69: #define TOK_PASSWORD_IDX (TOK_LOGIN_IDX + sizeof "login")
70: "password\0"
71: #define TOK_PASSWD_IDX (TOK_PASSWORD_IDX + sizeof "password")
72: "passwd\0"
73: #define TOK_ACCOUNT_IDX (TOK_PASSWD_IDX + sizeof "passwd")
74: "account\0"
75: #define TOK_MACHINE_IDX (TOK_ACCOUNT_IDX + sizeof "account")
76: "machine\0"
77: #define TOK_MACDEF_IDX (TOK_MACHINE_IDX + sizeof "machine")
78: "macdef"
79: };
80:
81: static const struct toktab {
82: int tokstr_off;
83: int tval;
84: } toktab[]= {
85: { TOK_DEFAULT_IDX, DEFAULT },
86: { TOK_LOGIN_IDX, LOGIN },
87: { TOK_PASSWORD_IDX, PASSWD },
88: { TOK_PASSWD_IDX, PASSWD },
89: { TOK_ACCOUNT_IDX, ACCOUNT },
90: { TOK_MACHINE_IDX, MACHINE },
91: { TOK_MACDEF_IDX, MACDEF }
92: };
93:
94:
95:
96: int
97: ruserpass(host, aname, apass)
98: const char *host, **aname, **apass;
99: {
100: char *hdir, *buf, *tmp;
101: char myname[1024], *mydomain;
102: int t, usedefault = 0;
103: struct stat64 stb;
104:
105: hdir = __secure_getenv("HOME");
106: if (hdir == NULL) {
107:
108:
109:
110:
111: return -1;
112: }
113:
114: buf = alloca (strlen (hdir) + 8);
115:
116: __stpcpy (__stpcpy (buf, hdir), "/.netrc");
117: cfile = fopen(buf, "rc");
118: if (cfile == NULL) {
119: if (errno != ENOENT)
120: warn("%s", buf);
121: return (0);
122: }
123:
124: __fsetlocking (cfile, FSETLOCKING_BYCALLER);
125: if (__gethostname(myname, sizeof(myname)) < 0)
126: myname[0] = '\0';
127: mydomain = __strchrnul(myname, '.');
128: next:
129: while ((t = token())) switch(t) {
130:
131: case DEFAULT:
132: usedefault = 1;
133:
134:
135: case MACHINE:
136: if (!usedefault) {
137: if (token() != ID)
138: continue;
139:
140:
141:
142:
143:
144: if (__strcasecmp(host, tokval) == 0)
145: goto match;
146:
147:
148:
149:
150:
151:
152:
153: if ((tmp = strchr(host, '.')) != NULL &&
154: __strcasecmp(tmp, mydomain) == 0 &&
155: __strncasecmp(host, tokval, tmp - host) == 0 &&
156: tokval[tmp - host] == '\0')
157: goto match;
158: continue;
159: }
160: match:
161: while ((t = token()) && t != MACHINE && t != DEFAULT) switch(t) {
162:
163: case LOGIN:
164: if (token()) {
165: if (*aname == 0) {
166: char *newp;
167: newp = malloc((unsigned) strlen(tokval) + 1);
168: if (newp == NULL)
169: {
170: warnx(_("out of memory"));
171: goto bad;
172: }
173: *aname = strcpy(newp, tokval);
174: } else {
175: if (strcmp(*aname, tokval))
176: goto next;
177: }
178: }
179: break;
180: case PASSWD:
181: if (strcmp(*aname, "anonymous") &&
182: fstat64(fileno(cfile), &stb) >= 0 &&
183: (stb.st_mode & 077) != 0) {
184: warnx(_("Error: .netrc file is readable by others."));
185: warnx(_("Remove password or make file unreadable by others."));
186: goto bad;
187: }
188: if (token() && *apass == 0) {
189: char *newp;
190: newp = malloc((unsigned) strlen(tokval) + 1);
191: if (newp == NULL)
192: {
193: warnx(_("out of memory"));
194: goto bad;
195: }
196: *apass = strcpy(newp, tokval);
197: }
198: break;
199: case ACCOUNT:
200: #if 0
201: if (fstat64(fileno(cfile), &stb) >= 0
202: && (stb.st_mode & 077) != 0) {
203: warnx("Error: .netrc file is readable by others.");
204: warnx("Remove account or make file unreadable by others.");
205: goto bad;
206: }
207: if (token() && *aacct == 0) {
208: *aacct = malloc((unsigned) strlen(tokval) + 1);
209: (void) strcpy(*aacct, tokval);
210: }
211: #endif
212: break;
213: case MACDEF:
214: #if 0
215: if (proxy) {
216: (void) fclose(cfile);
217: return (0);
218: }
219: while ((c=getc_unlocked(cfile)) != EOF && c == ' '
220: || c == '\t');
221: if (c == EOF || c == '\n') {
222: printf("Missing macdef name argument.\n");
223: goto bad;
224: }
225: if (macnum == 16) {
226: printf("Limit of 16 macros have already been defined\n");
227: goto bad;
228: }
229: tmp = macros[macnum].mac_name;
230: *tmp++ = c;
231: for (i=0; i < 8 && (c=getc_unlocked(cfile)) != EOF &&
232: !isspace(c); ++i) {
233: *tmp++ = c;
234: }
235: if (c == EOF) {
236: printf("Macro definition missing null line terminator.\n");
237: goto bad;
238: }
239: *tmp = '\0';
240: if (c != '\n') {
241: while ((c=getc_unlocked(cfile)) != EOF
242: && c != '\n');
243: }
244: if (c == EOF) {
245: printf("Macro definition missing null line terminator.\n");
246: goto bad;
247: }
248: if (macnum == 0) {
249: macros[macnum].mac_start = macbuf;
250: }
251: else {
252: macros[macnum].mac_start = macros[macnum-1].mac_end + 1;
253: }
254: tmp = macros[macnum].mac_start;
255: while (tmp != macbuf + 4096) {
256: if ((c=getc_unlocked(cfile)) == EOF) {
257: printf("Macro definition missing null line terminator.\n");
258: goto bad;
259: }
260: *tmp = c;
261: if (*tmp == '\n') {
262: if (*(tmp-1) == '\0') {
263: macros[macnum++].mac_end = tmp - 1;
264: break;
265: }
266: *tmp = '\0';
267: }
268: tmp++;
269: }
270: if (tmp == macbuf + 4096) {
271: printf("4K macro buffer exceeded\n");
272: goto bad;
273: }
274: #endif
275: break;
276: default:
277: warnx(_("Unknown .netrc keyword %s"), tokval);
278: break;
279: }
280: goto done;
281: }
282: done:
283: (void) fclose(cfile);
284: return (0);
285: bad:
286: (void) fclose(cfile);
287: return (-1);
288: }
289: libc_hidden_def (ruserpass)
290:
291: static int
292: token()
293: {
294: char *cp;
295: int c;
296: int i;
297:
298: if (feof_unlocked(cfile) || ferror_unlocked(cfile))
299: return (0);
300: while ((c = getc_unlocked(cfile)) != EOF &&
301: (c == '\n' || c == '\t' || c == ' ' || c == ','))
302: continue;
303: if (c == EOF)
304: return (0);
305: cp = tokval;
306: if (c == '"') {
307: while ((c = getc_unlocked(cfile)) != EOF && c != '"') {
308: if (c == '\\')
309: c = getc_unlocked(cfile);
310: *cp++ = c;
311: }
312: } else {
313: *cp++ = c;
314: while ((c = getc_unlocked(cfile)) != EOF
315: && c != '\n' && c != '\t' && c != ' ' && c != ',') {
316: if (c == '\\')
317: c = getc_unlocked(cfile);
318: *cp++ = c;
319: }
320: }
321: *cp = 0;
322: if (tokval[0] == 0)
323: return (0);
324: for (i = 0; i < (int) (sizeof (toktab) / sizeof (toktab[0])); ++i)
325: if (!strcmp(&tokstr[toktab[i].tokstr_off], tokval))
326: return toktab[i].tval;
327: return (ID);
328: }