diff options
Diffstat (limited to 'auth.c')
-rw-r--r-- | auth.c | 94 |
1 files changed, 43 insertions, 51 deletions
@@ -1,3 +1,4 @@ | |||
1 | /* $OpenBSD: auth.c,v 1.75 2006/08/03 03:34:41 deraadt Exp $ */ | ||
1 | /* | 2 | /* |
2 | * Copyright (c) 2000 Markus Friedl. All rights reserved. | 3 | * Copyright (c) 2000 Markus Friedl. All rights reserved. |
3 | * | 4 | * |
@@ -23,39 +24,56 @@ | |||
23 | */ | 24 | */ |
24 | 25 | ||
25 | #include "includes.h" | 26 | #include "includes.h" |
26 | RCSID("$OpenBSD: auth.c,v 1.60 2005/06/17 02:44:32 djm Exp $"); | ||
27 | 27 | ||
28 | #include <sys/types.h> | ||
29 | #include <sys/stat.h> | ||
30 | #include <sys/param.h> | ||
31 | |||
32 | #include <netinet/in.h> | ||
33 | |||
34 | #include <errno.h> | ||
35 | #ifdef HAVE_PATHS_H | ||
36 | # include <paths.h> | ||
37 | #endif | ||
38 | #include <pwd.h> | ||
28 | #ifdef HAVE_LOGIN_H | 39 | #ifdef HAVE_LOGIN_H |
29 | #include <login.h> | 40 | #include <login.h> |
30 | #endif | 41 | #endif |
31 | #ifdef USE_SHADOW | 42 | #ifdef USE_SHADOW |
32 | #include <shadow.h> | 43 | #include <shadow.h> |
33 | #endif | 44 | #endif |
34 | |||
35 | #ifdef HAVE_LIBGEN_H | 45 | #ifdef HAVE_LIBGEN_H |
36 | #include <libgen.h> | 46 | #include <libgen.h> |
37 | #endif | 47 | #endif |
48 | #include <stdarg.h> | ||
49 | #include <stdio.h> | ||
50 | #include <string.h> | ||
38 | 51 | ||
39 | #include "xmalloc.h" | 52 | #include "xmalloc.h" |
40 | #include "match.h" | 53 | #include "match.h" |
41 | #include "groupaccess.h" | 54 | #include "groupaccess.h" |
42 | #include "log.h" | 55 | #include "log.h" |
56 | #include "buffer.h" | ||
43 | #include "servconf.h" | 57 | #include "servconf.h" |
58 | #include "key.h" | ||
59 | #include "hostfile.h" | ||
44 | #include "auth.h" | 60 | #include "auth.h" |
45 | #include "auth-options.h" | 61 | #include "auth-options.h" |
46 | #include "canohost.h" | 62 | #include "canohost.h" |
47 | #include "buffer.h" | ||
48 | #include "bufaux.h" | ||
49 | #include "uidswap.h" | 63 | #include "uidswap.h" |
50 | #include "misc.h" | 64 | #include "misc.h" |
51 | #include "bufaux.h" | ||
52 | #include "packet.h" | 65 | #include "packet.h" |
53 | #include "loginrec.h" | 66 | #include "loginrec.h" |
67 | #ifdef GSSAPI | ||
68 | #include "ssh-gss.h" | ||
69 | #endif | ||
54 | #include "monitor_wrap.h" | 70 | #include "monitor_wrap.h" |
55 | 71 | ||
56 | /* import */ | 72 | /* import */ |
57 | extern ServerOptions options; | 73 | extern ServerOptions options; |
74 | extern int use_privsep; | ||
58 | extern Buffer loginmsg; | 75 | extern Buffer loginmsg; |
76 | extern struct passwd *privsep_pw; | ||
59 | 77 | ||
60 | /* Debugging messages */ | 78 | /* Debugging messages */ |
61 | Buffer auth_debug; | 79 | Buffer auth_debug; |
@@ -231,6 +249,9 @@ auth_log(Authctxt *authctxt, int authenticated, char *method, char *info) | |||
231 | void (*authlog) (const char *fmt,...) = verbose; | 249 | void (*authlog) (const char *fmt,...) = verbose; |
232 | char *authmsg; | 250 | char *authmsg; |
233 | 251 | ||
252 | if (use_privsep && !mm_is_monitor() && !authctxt->postponed) | ||
253 | return; | ||
254 | |||
234 | /* Raise logging level */ | 255 | /* Raise logging level */ |
235 | if (authenticated == 1 || | 256 | if (authenticated == 1 || |
236 | !authctxt->valid || | 257 | !authctxt->valid || |
@@ -259,44 +280,15 @@ auth_log(Authctxt *authctxt, int authenticated, char *method, char *info) | |||
259 | strcmp(method, "challenge-response") == 0)) | 280 | strcmp(method, "challenge-response") == 0)) |
260 | record_failed_login(authctxt->user, | 281 | record_failed_login(authctxt->user, |
261 | get_canonical_hostname(options.use_dns), "ssh"); | 282 | get_canonical_hostname(options.use_dns), "ssh"); |
283 | # ifdef WITH_AIXAUTHENTICATE | ||
284 | if (authenticated) | ||
285 | sys_auth_record_login(authctxt->user, | ||
286 | get_canonical_hostname(options.use_dns), "ssh", &loginmsg); | ||
287 | # endif | ||
262 | #endif | 288 | #endif |
263 | #ifdef SSH_AUDIT_EVENTS | 289 | #ifdef SSH_AUDIT_EVENTS |
264 | if (authenticated == 0 && !authctxt->postponed) { | 290 | if (authenticated == 0 && !authctxt->postponed) |
265 | ssh_audit_event_t event; | 291 | audit_event(audit_classify_auth(method)); |
266 | |||
267 | debug3("audit failed auth attempt, method %s euid %d", | ||
268 | method, (int)geteuid()); | ||
269 | /* | ||
270 | * Because the auth loop is used in both monitor and slave, | ||
271 | * we must be careful to send each event only once and with | ||
272 | * enough privs to write the event. | ||
273 | */ | ||
274 | event = audit_classify_auth(method); | ||
275 | switch(event) { | ||
276 | case SSH_AUTH_FAIL_NONE: | ||
277 | case SSH_AUTH_FAIL_PASSWD: | ||
278 | case SSH_AUTH_FAIL_KBDINT: | ||
279 | if (geteuid() == 0) | ||
280 | audit_event(event); | ||
281 | break; | ||
282 | case SSH_AUTH_FAIL_PUBKEY: | ||
283 | case SSH_AUTH_FAIL_HOSTBASED: | ||
284 | case SSH_AUTH_FAIL_GSSAPI: | ||
285 | /* | ||
286 | * This is required to handle the case where privsep | ||
287 | * is enabled but it's root logging in, since | ||
288 | * use_privsep won't be cleared until after a | ||
289 | * successful login. | ||
290 | */ | ||
291 | if (geteuid() == 0) | ||
292 | audit_event(event); | ||
293 | else | ||
294 | PRIVSEP(audit_event(event)); | ||
295 | break; | ||
296 | default: | ||
297 | error("unknown authentication audit event %d", event); | ||
298 | } | ||
299 | } | ||
300 | #endif | 292 | #endif |
301 | } | 293 | } |
302 | 294 | ||
@@ -309,7 +301,6 @@ auth_root_allowed(char *method) | |||
309 | switch (options.permit_root_login) { | 301 | switch (options.permit_root_login) { |
310 | case PERMIT_YES: | 302 | case PERMIT_YES: |
311 | return 1; | 303 | return 1; |
312 | break; | ||
313 | case PERMIT_NO_PASSWD: | 304 | case PERMIT_NO_PASSWD: |
314 | if (strcmp(method, "password") != 0) | 305 | if (strcmp(method, "password") != 0) |
315 | return 1; | 306 | return 1; |
@@ -336,7 +327,8 @@ auth_root_allowed(char *method) | |||
336 | static char * | 327 | static char * |
337 | expand_authorized_keys(const char *filename, struct passwd *pw) | 328 | expand_authorized_keys(const char *filename, struct passwd *pw) |
338 | { | 329 | { |
339 | char *file, *ret; | 330 | char *file, ret[MAXPATHLEN]; |
331 | int i; | ||
340 | 332 | ||
341 | file = percent_expand(filename, "h", pw->pw_dir, | 333 | file = percent_expand(filename, "h", pw->pw_dir, |
342 | "u", pw->pw_name, (char *)NULL); | 334 | "u", pw->pw_name, (char *)NULL); |
@@ -348,14 +340,11 @@ expand_authorized_keys(const char *filename, struct passwd *pw) | |||
348 | if (*file == '/') | 340 | if (*file == '/') |
349 | return (file); | 341 | return (file); |
350 | 342 | ||
351 | ret = xmalloc(MAXPATHLEN); | 343 | i = snprintf(ret, sizeof(ret), "%s/%s", pw->pw_dir, file); |
352 | if (strlcpy(ret, pw->pw_dir, MAXPATHLEN) >= MAXPATHLEN || | 344 | if (i < 0 || (size_t)i >= sizeof(ret)) |
353 | strlcat(ret, "/", MAXPATHLEN) >= MAXPATHLEN || | ||
354 | strlcat(ret, file, MAXPATHLEN) >= MAXPATHLEN) | ||
355 | fatal("expand_authorized_keys: path too long"); | 345 | fatal("expand_authorized_keys: path too long"); |
356 | |||
357 | xfree(file); | 346 | xfree(file); |
358 | return (ret); | 347 | return (xstrdup(ret)); |
359 | } | 348 | } |
360 | 349 | ||
361 | char * | 350 | char * |
@@ -492,6 +481,9 @@ getpwnamallow(const char *user) | |||
492 | #endif | 481 | #endif |
493 | struct passwd *pw; | 482 | struct passwd *pw; |
494 | 483 | ||
484 | parse_server_match_config(&options, user, | ||
485 | get_canonical_hostname(options.use_dns), get_remote_ipaddr()); | ||
486 | |||
495 | pw = getpwnam(user); | 487 | pw = getpwnam(user); |
496 | if (pw == NULL) { | 488 | if (pw == NULL) { |
497 | logit("Invalid user %.100s from %.100s", | 489 | logit("Invalid user %.100s from %.100s", |
@@ -577,8 +569,8 @@ fakepw(void) | |||
577 | fake.pw_passwd = | 569 | fake.pw_passwd = |
578 | "$2a$06$r3.juUaHZDlIbQaO2dS9FuYxL1W9M81R1Tc92PoSNmzvpEqLkLGrK"; | 570 | "$2a$06$r3.juUaHZDlIbQaO2dS9FuYxL1W9M81R1Tc92PoSNmzvpEqLkLGrK"; |
579 | fake.pw_gecos = "NOUSER"; | 571 | fake.pw_gecos = "NOUSER"; |
580 | fake.pw_uid = (uid_t)-1; | 572 | fake.pw_uid = privsep_pw == NULL ? (uid_t)-1 : privsep_pw->pw_uid; |
581 | fake.pw_gid = (gid_t)-1; | 573 | fake.pw_gid = privsep_pw == NULL ? (gid_t)-1 : privsep_pw->pw_gid; |
582 | #ifdef HAVE_PW_CLASS_IN_PASSWD | 574 | #ifdef HAVE_PW_CLASS_IN_PASSWD |
583 | fake.pw_class = ""; | 575 | fake.pw_class = ""; |
584 | #endif | 576 | #endif |