]> diplodocus.org Git - nmh/blob - sbr/ruserpass.c
Another pass at cleaning up (some of) the manpages.
[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 * Portions of this code are Copyright (c) 2013, by the authors of
19 * nmh. See the COPYRIGHT file in the root directory of the nmh
20 * distribution for complete copyright information.
21 */
22
23 #include <h/mh.h>
24 #include <h/utils.h>
25 #include <pwd.h>
26
27 static FILE *cfile;
28
29 #define DEFAULT 1
30 #define LOGIN 2
31 #define PASSWD 3
32 #define ACCOUNT 4
33 #define MACDEF 5
34 #define ID 10
35 #define MACH 11
36
37 #define MAX_TOKVAL_SIZE 1024
38
39 struct toktab {
40 char *tokstr;
41 int tval;
42 };
43
44 static struct toktab toktabs[] = {
45 { "default", DEFAULT },
46 { "login", LOGIN },
47 { "password", PASSWD },
48 { "passwd", PASSWD },
49 { "account", ACCOUNT },
50 { "machine", MACH },
51 { "macdef", MACDEF },
52 { 0, 0 }
53 };
54
55 /*
56 * prototypes
57 */
58 static int token(char *);
59
60
61 void
62 ruserpass(char *host, char **aname, char **apass)
63 {
64 int t, usedefault = 0;
65 struct stat stb;
66
67 init_credentials_file ();
68
69 cfile = fopen (credentials_file, "r");
70 if (cfile == NULL) {
71 if (errno != ENOENT)
72 perror (credentials_file);
73 } else {
74 char tokval[MAX_TOKVAL_SIZE];
75 tokval[0] = '\0';
76
77 while ((t = token(tokval))) {
78 switch(t) {
79 case DEFAULT:
80 usedefault = 1;
81 /* FALL THROUGH */
82
83 case MACH:
84 if (!usedefault) {
85 if (token(tokval) != ID)
86 continue;
87 /*
88 * Allow match either for user's host name.
89 */
90 if (strcasecmp(host, tokval) == 0)
91 goto match;
92 continue;
93 }
94 match:
95 while ((t = token(tokval)) && t != MACH && t != DEFAULT) {
96 switch(t) {
97 case LOGIN:
98 if (token(tokval) && *aname == 0) {
99 *aname = mh_xmalloc((size_t) strlen(tokval) + 1);
100 strcpy(*aname, tokval);
101 }
102 break;
103
104 case PASSWD:
105 if (fstat(fileno(cfile), &stb) >= 0 &&
106 (stb.st_mode & 077) != 0) {
107 /* We make this a fatal error to force the
108 user to correct it. */
109 advise(NULL, "Error - file %s must not be world or "
110 "group readable.", credentials_file);
111 adios(NULL, "Remove password or correct file "
112 "permissions.");
113 }
114 if (token(tokval) && *apass == 0) {
115 *apass = mh_xmalloc((size_t) strlen(tokval) + 1);
116 strcpy(*apass, tokval);
117 }
118 break;
119
120 case ACCOUNT:
121 break;
122
123 case MACDEF:
124 fclose(cfile);
125 return;
126
127 default:
128 fprintf(stderr,
129 "Unknown keyword %s in credentials file %s\n",
130 tokval, credentials_file);
131 break;
132 }
133 }
134 return;
135 }
136 }
137 }
138
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 if (fgets(tmp, sizeof(tmp) - 1, stdin) == NULL) {
152 advise ("tmp", "fgets");
153 }
154 tmp[strlen(tmp) - 1] = '\0';
155 if (*tmp != '\0' || myname == NULL) {
156 myname = tmp;
157 }
158
159 *aname = mh_xmalloc((size_t) strlen(myname) + 1);
160 strcpy (*aname, myname);
161 }
162
163 if (!*apass) {
164 char prompt[256];
165 char *mypass;
166
167 snprintf(prompt, sizeof(prompt), "Password (%s:%s): ", host, *aname);
168 mypass = nmh_getpass(prompt);
169
170 if (*mypass == '\0') {
171 mypass = *aname;
172 }
173
174 *apass = mh_xmalloc((size_t) strlen(mypass) + 1);
175 strcpy (*apass, mypass);
176 }
177
178 }
179
180 static int
181 token(char *tokval)
182 {
183 char *cp;
184 int c;
185 struct toktab *t;
186
187 if (feof(cfile))
188 return (0);
189 while ((c = getc(cfile)) != EOF &&
190 (c == '\n' || c == '\t' || c == ' ' || c == ','))
191 continue;
192 if (c == EOF)
193 return (0);
194 cp = tokval;
195 if (c == '"') {
196 while ((c = getc(cfile)) != EOF && c != '"') {
197 if (c == '\\')
198 c = getc(cfile);
199 *cp++ = c;
200 if (cp - tokval > MAX_TOKVAL_SIZE-1) {
201 adios(NULL, "credential tokens restricted to length %d",
202 MAX_TOKVAL_SIZE - 1);
203 }
204 }
205 } else {
206 *cp++ = c;
207 while ((c = getc(cfile)) != EOF
208 && c != '\n' && c != '\t' && c != ' ' && c != ',') {
209 if (c == '\\')
210 c = getc(cfile);
211 *cp++ = c;
212 if (cp - tokval > MAX_TOKVAL_SIZE-1) {
213 adios(NULL, "credential tokens restricted to length %d",
214 MAX_TOKVAL_SIZE - 1);
215 }
216 }
217 }
218 *cp = 0;
219 if (tokval[0] == 0)
220 return (0);
221 for (t = toktabs; t->tokstr; t++)
222 if (!strcmp(t->tokstr, tokval))
223 return (t->tval);
224 return (ID);
225 }