]> diplodocus.org Git - nmh/blob - sbr/ruserpass.c
Cope with sasl_decode64() returning SASL_CONTINUE as well as SASL_OK.
[nmh] / sbr / ruserpass.c
1 /*
2 * Portions of this code are
3 * Copyright (c) 1985 Regents of the University of California.
4 * All rights reserved.
5 *
6 * Redistribution and use in source and binary forms are permitted
7 * provided that the above copyright notice and this paragraph are
8 * duplicated in all such forms and that any documentation,
9 * advertising materials, and other materials related to such
10 * distribution and use acknowledge that the software was developed
11 * by the University of California, Berkeley. The name of the
12 * University may not be used to endorse or promote products derived
13 * from this software without specific prior written permission.
14 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
15 * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
16 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
17 *
18 * $Id$
19 */
20
21 #include <h/mh.h>
22 #include <h/utils.h>
23 #include <pwd.h>
24 #include <errno.h>
25
26 static FILE *cfile;
27
28 #ifndef MAXHOSTNAMELEN
29 # define MAXHOSTNAMELEN 64
30 #endif
31
32 #define DEFAULT 1
33 #define LOGIN 2
34 #define PASSWD 3
35 #define ACCOUNT 4
36 #define MACDEF 5
37 #define ID 10
38 #define MACH 11
39
40 static char tokval[100];
41
42 struct toktab {
43 char *tokstr;
44 int tval;
45 };
46
47 static struct toktab toktabs[] = {
48 { "default", DEFAULT },
49 { "login", LOGIN },
50 { "password", PASSWD },
51 { "passwd", PASSWD },
52 { "account", ACCOUNT },
53 { "machine", MACH },
54 { "macdef", MACDEF },
55 { 0, 0 }
56 };
57
58 /*
59 * prototypes
60 */
61 static int token(void);
62
63
64 int
65 ruserpass(char *host, char **aname, char **apass)
66 {
67 char *hdir, buf[BUFSIZ];
68 int t, usedefault = 0;
69 struct stat stb;
70
71 hdir = getenv("HOME");
72 if (hdir == NULL)
73 hdir = ".";
74 snprintf(buf, sizeof(buf), "%s/.netrc", hdir);
75 cfile = fopen(buf, "r");
76 if (cfile == NULL) {
77 if (errno != ENOENT)
78 perror(buf);
79 goto done;
80 }
81
82 while ((t = token())) {
83 switch(t) {
84 case DEFAULT:
85 usedefault = 1;
86 /* FALL THROUGH */
87
88 case MACH:
89 if (!usedefault) {
90 if (token() != ID)
91 continue;
92 /*
93 * Allow match either for user's host name.
94 */
95 if (mh_strcasecmp(host, tokval) == 0)
96 goto match;
97 continue;
98 }
99 match:
100 while ((t = token()) && t != MACH && t != DEFAULT) {
101 switch(t) {
102 case LOGIN:
103 if (token() && *aname == 0) {
104 *aname = mh_xmalloc((size_t) strlen(tokval) + 1);
105 strcpy(*aname, tokval);
106 }
107 break;
108 case PASSWD:
109 if (fstat(fileno(cfile), &stb) >= 0 &&
110 (stb.st_mode & 077) != 0) {
111 fprintf(stderr, "Error - .netrc file not correct mode.\n");
112 fprintf(stderr, "Remove password or correct mode.\n");
113 goto bad;
114 }
115 if (token() && *apass == 0) {
116 *apass = mh_xmalloc((size_t) strlen(tokval) + 1);
117 strcpy(*apass, tokval);
118 }
119 break;
120 case ACCOUNT:
121 break;
122
123 case MACDEF:
124 goto done_close;
125 break;
126 default:
127 fprintf(stderr, "Unknown .netrc keyword %s\n", tokval);
128 break;
129 }
130 }
131 goto done;
132 }
133 }
134
135 done_close:
136 fclose(cfile);
137
138 done:
139 if (!*aname) {
140 char tmp[80];
141 char *myname;
142
143 if ((myname = getlogin()) == NULL) {
144 struct passwd *pp;
145
146 if ((pp = getpwuid (getuid())) != NULL)
147 myname = pp->pw_name;
148 }
149 printf("Name (%s:%s): ", host, myname);
150
151 fgets(tmp, sizeof(tmp) - 1, stdin);
152 tmp[strlen(tmp) - 1] = '\0';
153 if (*tmp != '\0') {
154 myname = tmp;
155 }
156
157 *aname = mh_xmalloc((size_t) strlen(myname) + 1);
158 strcpy (*aname, myname);
159 }
160
161 if (!*apass) {
162 char prompt[256];
163 char *mypass;
164
165 snprintf(prompt, sizeof(prompt), "Password (%s:%s): ", host, *aname);
166 mypass = nmh_getpass(prompt);
167
168 if (*mypass == '\0') {
169 mypass = *aname;
170 }
171
172 *apass = mh_xmalloc((size_t) strlen(mypass) + 1);
173 strcpy (*apass, mypass);
174 }
175
176 return(0);
177 bad:
178 fclose(cfile);
179 return(-1);
180 }
181
182 static int
183 token(void)
184 {
185 char *cp;
186 int c;
187 struct toktab *t;
188
189 if (feof(cfile))
190 return (0);
191 while ((c = getc(cfile)) != EOF &&
192 (c == '\n' || c == '\t' || c == ' ' || c == ','))
193 continue;
194 if (c == EOF)
195 return (0);
196 cp = tokval;
197 if (c == '"') {
198 while ((c = getc(cfile)) != EOF && c != '"') {
199 if (c == '\\')
200 c = getc(cfile);
201 *cp++ = c;
202 }
203 } else {
204 *cp++ = c;
205 while ((c = getc(cfile)) != EOF
206 && c != '\n' && c != '\t' && c != ' ' && c != ',') {
207 if (c == '\\')
208 c = getc(cfile);
209 *cp++ = c;
210 }
211 }
212 *cp = 0;
213 if (tokval[0] == 0)
214 return (0);
215 for (t = toktabs; t->tokstr; t++)
216 if (!strcmp(t->tokstr, tokval))
217 return (t->tval);
218 return (ID);
219 }