Line | Source | Count |
1 | | - |
2 | | - |
3 | | - |
4 | | - |
5 | | - |
6 | | - |
7 | | - |
8 | | - |
9 | | - |
10 | | - |
11 | | - |
12 | | - |
13 | | - |
14 | | - |
15 | | - |
16 | | - |
17 | #include "includes.h" | - |
18 | | - |
19 | #include <sys/types.h> | - |
20 | #include <sys/stat.h> | - |
21 | | - |
22 | #ifdef HAVE_NETGROUP_H | - |
23 | # include <netgroup.h> | - |
24 | #endif | - |
25 | #include <pwd.h> | - |
26 | #include <stdio.h> | - |
27 | #include <string.h> | - |
28 | #include <stdarg.h> | - |
29 | #include <fcntl.h> | - |
30 | #include <unistd.h> | - |
31 | | - |
32 | #include "packet.h" | - |
33 | #include "uidswap.h" | - |
34 | #include "pathnames.h" | - |
35 | #include "log.h" | - |
36 | #include "misc.h" | - |
37 | #include "sshbuf.h" | - |
38 | #include "sshkey.h" | - |
39 | #include "servconf.h" | - |
40 | #include "canohost.h" | - |
41 | #include "sshkey.h" | - |
42 | #include "hostfile.h" | - |
43 | #include "auth.h" | - |
44 | | - |
45 | | - |
46 | extern ServerOptions options; | - |
47 | extern int use_privsep; | - |
48 | | - |
49 | | - |
50 | | - |
51 | | - |
52 | | - |
53 | | - |
54 | | - |
55 | static int | - |
56 | check_rhosts_file(const char *filename, const char *hostname, | - |
57 | const char *ipaddr, const char *client_user, | - |
58 | const char *server_user) | - |
59 | { | - |
60 | FILE *f; | - |
61 | #define RBUFLN 1024 | - |
62 | char buf[RBUFLN]; | - |
63 | int fd; | - |
64 | struct stat st; | - |
65 | | - |
66 | | - |
67 | if ((fd = open(filename, O_RDONLY|O_NONBLOCK)) == -1)TRUE | never evaluated | FALSE | never evaluated |
| 0 |
68 | return 0; never executed: return 0; | 0 |
69 | if (fstat(fd, &st) == -1) {TRUE | never evaluated | FALSE | never evaluated |
| 0 |
70 | close(fd); | - |
71 | return 0; never executed: return 0; | 0 |
72 | } | - |
73 | if (!S_ISREG(st.st_mode)) {TRUE | never evaluated | FALSE | never evaluated |
| 0 |
74 | logit("User %s hosts file %s is not a regular file", | - |
75 | server_user, filename); | - |
76 | close(fd); | - |
77 | return 0; never executed: return 0; | 0 |
78 | } | - |
79 | unset_nonblock(fd); | - |
80 | if ((f = fdopen(fd, "r")) == NULL) {TRUE | never evaluated | FALSE | never evaluated |
| 0 |
81 | close(fd); | - |
82 | return 0; never executed: return 0; | 0 |
83 | } | - |
84 | while (fgets(buf, sizeof(buf), f)) {TRUE | never evaluated | FALSE | never evaluated |
| 0 |
85 | | - |
86 | char hostbuf[RBUFLN], userbuf[RBUFLN], dummy[RBUFLN]; | - |
87 | char *host, *user, *cp; | - |
88 | int negated; | - |
89 | | - |
90 | for (cp = buf; *cp == ' ' || *cp == '\t'; cp++)TRUE | never evaluated | FALSE | never evaluated |
TRUE | never evaluated | FALSE | never evaluated |
| 0 |
91 | ; never executed: ; | 0 |
92 | if (*cp == '#' || *cp == '\n' || !*cp)TRUE | never evaluated | FALSE | never evaluated |
TRUE | never evaluated | FALSE | never evaluated |
TRUE | never evaluated | FALSE | never evaluated |
| 0 |
93 | continue; never executed: continue; | 0 |
94 | | - |
95 | | - |
96 | | - |
97 | | - |
98 | | - |
99 | if (strncmp(cp, "NO_PLUS", 7) == 0) never executed: __result = (((const unsigned char *) (const char *) ( cp ))[3] - __s2[3]); never executed: end of block never executed: end of block never executed: __result = (((const unsigned char *) (const char *) ( "NO_PLUS" ))[3] - __s2[3]); never executed: end of block never executed: end of block TRUE | never evaluated | FALSE | never evaluated |
TRUE | never evaluated | FALSE | never evaluated |
TRUE | never evaluated | FALSE | never evaluated |
TRUE | never evaluated | FALSE | never evaluated |
TRUE | never evaluated | FALSE | never evaluated |
TRUE | never evaluated | FALSE | never evaluated |
TRUE | never evaluated | FALSE | never evaluated |
TRUE | never evaluated | FALSE | never evaluated |
TRUE | never evaluated | FALSE | never evaluated |
TRUE | never evaluated | FALSE | never evaluated |
TRUE | never evaluated | FALSE | never evaluated |
TRUE | never evaluated | FALSE | never evaluated |
TRUE | never evaluated | FALSE | never evaluated |
TRUE | never evaluated | FALSE | never evaluated |
TRUE | never evaluated | FALSE | never evaluated |
TRUE | never evaluated | FALSE | never evaluated |
TRUE | never evaluated | FALSE | never evaluated |
TRUE | never evaluated | FALSE | never evaluated |
| 0 |
100 | continue; never executed: continue; | 0 |
101 | | - |
102 | | - |
103 | | - |
104 | | - |
105 | | - |
106 | switch (sscanf(buf, "%1023s %1023s %1023s", hostbuf, userbuf, | - |
107 | dummy)) { | - |
108 | case 0: never executed: case 0: | 0 |
109 | auth_debug_add("Found empty line in %.100s.", filename); | - |
110 | continue; never executed: continue; | 0 |
111 | case 1: never executed: case 1: | 0 |
112 | | - |
113 | strlcpy(userbuf, server_user, sizeof(userbuf)); | - |
114 | break; never executed: break; | 0 |
115 | case 2: never executed: case 2: | 0 |
116 | | - |
117 | break; never executed: break; | 0 |
118 | case 3: never executed: case 3: | 0 |
119 | auth_debug_add("Found garbage in %.100s.", filename); | - |
120 | continue; never executed: continue; | 0 |
121 | default: never executed: default: | 0 |
122 | | - |
123 | continue; never executed: continue; | 0 |
124 | } | - |
125 | | - |
126 | host = hostbuf; | - |
127 | user = userbuf; | - |
128 | negated = 0; | - |
129 | | - |
130 | | - |
131 | if (host[0] == '-') {TRUE | never evaluated | FALSE | never evaluated |
| 0 |
132 | negated = 1; | - |
133 | host++; | - |
134 | } else if (host[0] == '+') never executed: end of block TRUE | never evaluated | FALSE | never evaluated |
| 0 |
135 | host++; never executed: host++; | 0 |
136 | | - |
137 | if (user[0] == '-') {TRUE | never evaluated | FALSE | never evaluated |
| 0 |
138 | negated = 1; | - |
139 | user++; | - |
140 | } else if (user[0] == '+') never executed: end of block TRUE | never evaluated | FALSE | never evaluated |
| 0 |
141 | user++; never executed: user++; | 0 |
142 | | - |
143 | | - |
144 | if (!host[0] || !user[0]) {TRUE | never evaluated | FALSE | never evaluated |
TRUE | never evaluated | FALSE | never evaluated |
| 0 |
145 | | - |
146 | auth_debug_add("Ignoring wild host/user names " | - |
147 | "in %.100s.", filename); | - |
148 | continue; never executed: continue; | 0 |
149 | } | - |
150 | | - |
151 | if (host[0] == '@') {TRUE | never evaluated | FALSE | never evaluated |
| 0 |
152 | if (!innetgr(host + 1, hostname, NULL, NULL) &&TRUE | never evaluated | FALSE | never evaluated |
| 0 |
153 | !innetgr(host + 1, ipaddr, NULL, NULL))TRUE | never evaluated | FALSE | never evaluated |
| 0 |
154 | continue; never executed: continue; | 0 |
155 | } else if (strcasecmp(host, hostname) && never executed: end of block TRUE | never evaluated | FALSE | never evaluated |
| 0 |
156 | strcmp(host, ipaddr) != 0) never executed: __result = (((const unsigned char *) (const char *) ( host ))[3] - __s2[3]); never executed: end of block never executed: end of block never executed: __result = (((const unsigned char *) (const char *) ( ipaddr ))[3] - __s2[3]); never executed: end of block never executed: end of block TRUE | never evaluated | FALSE | never evaluated |
TRUE | never evaluated | FALSE | never evaluated |
TRUE | never evaluated | FALSE | never evaluated |
TRUE | never evaluated | FALSE | never evaluated |
TRUE | never evaluated | FALSE | never evaluated |
TRUE | never evaluated | FALSE | never evaluated |
TRUE | never evaluated | FALSE | never evaluated |
TRUE | never evaluated | FALSE | never evaluated |
TRUE | never evaluated | FALSE | never evaluated |
TRUE | never evaluated | FALSE | never evaluated |
TRUE | never evaluated | FALSE | never evaluated |
TRUE | never evaluated | FALSE | never evaluated |
TRUE | never evaluated | FALSE | never evaluated |
| 0 |
157 | continue; never executed: continue; | 0 |
158 | | - |
159 | | - |
160 | if (user[0] == '@') {TRUE | never evaluated | FALSE | never evaluated |
| 0 |
161 | if (!innetgr(user + 1, NULL, client_user, NULL))TRUE | never evaluated | FALSE | never evaluated |
| 0 |
162 | continue; never executed: continue; | 0 |
163 | } else if (strcmp(user, client_user) != 0) never executed: end of block never executed: __result = (((const unsigned char *) (const char *) ( user ))[3] - __s2[3]); never executed: end of block never executed: end of block never executed: __result = (((const unsigned char *) (const char *) ( client_user ))[3] - __s2[3]); never executed: end of block never executed: end of block TRUE | never evaluated | FALSE | never evaluated |
TRUE | never evaluated | FALSE | never evaluated |
TRUE | never evaluated | FALSE | never evaluated |
TRUE | never evaluated | FALSE | never evaluated |
TRUE | never evaluated | FALSE | never evaluated |
TRUE | never evaluated | FALSE | never evaluated |
TRUE | never evaluated | FALSE | never evaluated |
TRUE | never evaluated | FALSE | never evaluated |
TRUE | never evaluated | FALSE | never evaluated |
TRUE | never evaluated | FALSE | never evaluated |
TRUE | never evaluated | FALSE | never evaluated |
TRUE | never evaluated | FALSE | never evaluated |
TRUE | never evaluated | FALSE | never evaluated |
| 0 |
164 | continue; never executed: continue; | 0 |
165 | | - |
166 | | - |
167 | fclose(f); | - |
168 | | - |
169 | | - |
170 | if (negated) {TRUE | never evaluated | FALSE | never evaluated |
| 0 |
171 | auth_debug_add("Matched negative entry in %.100s.", | - |
172 | filename); | - |
173 | return 0; never executed: return 0; | 0 |
174 | } | - |
175 | | - |
176 | return 1; never executed: return 1; | 0 |
177 | } | - |
178 | | - |
179 | | - |
180 | fclose(f); | - |
181 | return 0; never executed: return 0; | 0 |
182 | } | - |
183 | | - |
184 | | - |
185 | | - |
186 | | - |
187 | | - |
188 | | - |
189 | int | - |
190 | auth_rhosts2(struct passwd *pw, const char *client_user, const char *hostname, | - |
191 | const char *ipaddr) | - |
192 | { | - |
193 | char buf[1024]; | - |
194 | struct stat st; | - |
195 | static const char *rhosts_files[] = {".shosts", ".rhosts", NULL}; | - |
196 | u_int rhosts_file_index; | - |
197 | | - |
198 | debug2("auth_rhosts2: clientuser %s hostname %s ipaddr %s", | - |
199 | client_user, hostname, ipaddr); | - |
200 | | - |
201 | | - |
202 | temporarily_use_uid(pw); | - |
203 | | - |
204 | | - |
205 | | - |
206 | | - |
207 | | - |
208 | | - |
209 | for (rhosts_file_index = 0; rhosts_files[rhosts_file_index];TRUE | never evaluated | FALSE | never evaluated |
| 0 |
210 | rhosts_file_index++) { | - |
211 | | - |
212 | snprintf(buf, sizeof buf, "%.500s/%.100s", | - |
213 | pw->pw_dir, rhosts_files[rhosts_file_index]); | - |
214 | if (stat(buf, &st) >= 0)TRUE | never evaluated | FALSE | never evaluated |
| 0 |
215 | break; never executed: break; | 0 |
216 | } never executed: end of block | 0 |
217 | | - |
218 | restore_uid(); | - |
219 | | - |
220 | | - |
221 | | - |
222 | | - |
223 | | - |
224 | if (!rhosts_files[rhosts_file_index] &&TRUE | never evaluated | FALSE | never evaluated |
| 0 |
225 | stat(_PATH_RHOSTS_EQUIV, &st) < 0 &&TRUE | never evaluated | FALSE | never evaluated |
| 0 |
226 | stat(_PATH_SSH_HOSTS_EQUIV, &st) < 0) {TRUE | never evaluated | FALSE | never evaluated |
| 0 |
227 | debug3("%s: no hosts access files exist", __func__); | - |
228 | return 0; never executed: return 0; | 0 |
229 | } | - |
230 | | - |
231 | | - |
232 | | - |
233 | | - |
234 | | - |
235 | if (pw->pw_uid == 0)TRUE | never evaluated | FALSE | never evaluated |
| 0 |
236 | debug3("%s: root user, ignoring system hosts files", __func__); never executed: debug3("%s: root user, ignoring system hosts files", __func__); | 0 |
237 | else { | - |
238 | if (check_rhosts_file(_PATH_RHOSTS_EQUIV, hostname, ipaddr,TRUE | never evaluated | FALSE | never evaluated |
| 0 |
239 | client_user, pw->pw_name)) {TRUE | never evaluated | FALSE | never evaluated |
| 0 |
240 | auth_debug_add("Accepted for %.100s [%.100s] by " | - |
241 | "/etc/hosts.equiv.", hostname, ipaddr); | - |
242 | return 1; never executed: return 1; | 0 |
243 | } | - |
244 | if (check_rhosts_file(_PATH_SSH_HOSTS_EQUIV, hostname, ipaddr,TRUE | never evaluated | FALSE | never evaluated |
| 0 |
245 | client_user, pw->pw_name)) {TRUE | never evaluated | FALSE | never evaluated |
| 0 |
246 | auth_debug_add("Accepted for %.100s [%.100s] by " | - |
247 | "%.100s.", hostname, ipaddr, _PATH_SSH_HOSTS_EQUIV); | - |
248 | return 1; never executed: return 1; | 0 |
249 | } | - |
250 | } never executed: end of block | 0 |
251 | | - |
252 | | - |
253 | | - |
254 | | - |
255 | | - |
256 | if (stat(pw->pw_dir, &st) < 0) {TRUE | never evaluated | FALSE | never evaluated |
| 0 |
257 | logit("Rhosts authentication refused for %.100s: " | - |
258 | "no home directory %.200s", pw->pw_name, pw->pw_dir); | - |
259 | auth_debug_add("Rhosts authentication refused for %.100s: " | - |
260 | "no home directory %.200s", pw->pw_name, pw->pw_dir); | - |
261 | return 0; never executed: return 0; | 0 |
262 | } | - |
263 | if (options.strict_modes &&TRUE | never evaluated | FALSE | never evaluated |
| 0 |
264 | ((st.st_uid != 0 && st.st_uid != pw->pw_uid) ||TRUE | never evaluated | FALSE | never evaluated |
TRUE | never evaluated | FALSE | never evaluated |
| 0 |
265 | (st.st_mode & 022) != 0)) {TRUE | never evaluated | FALSE | never evaluated |
| 0 |
266 | logit("Rhosts authentication refused for %.100s: " | - |
267 | "bad ownership or modes for home directory.", pw->pw_name); | - |
268 | auth_debug_add("Rhosts authentication refused for %.100s: " | - |
269 | "bad ownership or modes for home directory.", pw->pw_name); | - |
270 | return 0; never executed: return 0; | 0 |
271 | } | - |
272 | | - |
273 | temporarily_use_uid(pw); | - |
274 | | - |
275 | | - |
276 | for (rhosts_file_index = 0; rhosts_files[rhosts_file_index];TRUE | never evaluated | FALSE | never evaluated |
| 0 |
277 | rhosts_file_index++) { | - |
278 | | - |
279 | snprintf(buf, sizeof buf, "%.500s/%.100s", | - |
280 | pw->pw_dir, rhosts_files[rhosts_file_index]); | - |
281 | if (stat(buf, &st) < 0)TRUE | never evaluated | FALSE | never evaluated |
| 0 |
282 | continue; never executed: continue; | 0 |
283 | | - |
284 | | - |
285 | | - |
286 | | - |
287 | | - |
288 | | - |
289 | | - |
290 | if (options.strict_modes &&TRUE | never evaluated | FALSE | never evaluated |
| 0 |
291 | ((st.st_uid != 0 && st.st_uid != pw->pw_uid) ||TRUE | never evaluated | FALSE | never evaluated |
TRUE | never evaluated | FALSE | never evaluated |
| 0 |
292 | (st.st_mode & 022) != 0)) {TRUE | never evaluated | FALSE | never evaluated |
| 0 |
293 | logit("Rhosts authentication refused for %.100s: bad modes for %.200s", | - |
294 | pw->pw_name, buf); | - |
295 | auth_debug_add("Bad file modes for %.200s", buf); | - |
296 | continue; never executed: continue; | 0 |
297 | } | - |
298 | | - |
299 | | - |
300 | | - |
301 | | - |
302 | if (options.ignore_rhosts) {TRUE | never evaluated | FALSE | never evaluated |
| 0 |
303 | auth_debug_add("Server has been configured to " | - |
304 | "ignore %.100s.", rhosts_files[rhosts_file_index]); | - |
305 | continue; never executed: continue; | 0 |
306 | } | - |
307 | | - |
308 | if (check_rhosts_file(buf, hostname, ipaddr,TRUE | never evaluated | FALSE | never evaluated |
| 0 |
309 | client_user, pw->pw_name)) {TRUE | never evaluated | FALSE | never evaluated |
| 0 |
310 | auth_debug_add("Accepted by %.100s.", | - |
311 | rhosts_files[rhosts_file_index]); | - |
312 | | - |
313 | restore_uid(); | - |
314 | auth_debug_add("Accepted host %s ip %s client_user " | - |
315 | "%s server_user %s", hostname, ipaddr, | - |
316 | client_user, pw->pw_name); | - |
317 | return 1; never executed: return 1; | 0 |
318 | } | - |
319 | } never executed: end of block | 0 |
320 | | - |
321 | | - |
322 | restore_uid(); | - |
323 | return 0; never executed: return 0; | 0 |
324 | } | - |
| | |