diff options
author | Colin Watson <cjwatson@debian.org> | 2010-03-31 00:48:57 +0100 |
---|---|---|
committer | Colin Watson <cjwatson@debian.org> | 2010-03-31 00:48:57 +0100 |
commit | d1a87e462e1db89f19cd960588d0c6b287cb5ccc (patch) | |
tree | f0d13e1687800f36a3c4322b94ac5230ad17bdbf /auth.c | |
parent | 964476f91b66c475d5b8fa1e8b28d39a97a1b56e (diff) | |
parent | 004a7fb9c6a00b13dc98f56599918a54a3506d10 (diff) |
merge 5.4p1
Diffstat (limited to 'auth.c')
-rw-r--r-- | auth.c | 98 |
1 files changed, 79 insertions, 19 deletions
@@ -1,4 +1,4 @@ | |||
1 | /* $OpenBSD: auth.c,v 1.80 2008/11/04 07:58:09 djm Exp $ */ | 1 | /* $OpenBSD: auth.c,v 1.86 2010/03/05 02:58:11 djm Exp $ */ |
2 | /* | 2 | /* |
3 | * Copyright (c) 2000 Markus Friedl. All rights reserved. | 3 | * Copyright (c) 2000 Markus Friedl. All rights reserved. |
4 | * | 4 | * |
@@ -69,6 +69,7 @@ | |||
69 | #ifdef GSSAPI | 69 | #ifdef GSSAPI |
70 | #include "ssh-gss.h" | 70 | #include "ssh-gss.h" |
71 | #endif | 71 | #endif |
72 | #include "authfile.h" | ||
72 | #include "monitor_wrap.h" | 73 | #include "monitor_wrap.h" |
73 | 74 | ||
74 | /* import */ | 75 | /* import */ |
@@ -95,7 +96,6 @@ allowed_user(struct passwd * pw) | |||
95 | { | 96 | { |
96 | struct stat st; | 97 | struct stat st; |
97 | const char *hostname = NULL, *ipaddr = NULL, *passwd = NULL; | 98 | const char *hostname = NULL, *ipaddr = NULL, *passwd = NULL; |
98 | char *shell; | ||
99 | u_int i; | 99 | u_int i; |
100 | #ifdef USE_SHADOW | 100 | #ifdef USE_SHADOW |
101 | struct spwd *spw = NULL; | 101 | struct spwd *spw = NULL; |
@@ -153,22 +153,28 @@ allowed_user(struct passwd * pw) | |||
153 | } | 153 | } |
154 | 154 | ||
155 | /* | 155 | /* |
156 | * Get the shell from the password data. An empty shell field is | 156 | * Deny if shell does not exist or is not executable unless we |
157 | * legal, and means /bin/sh. | 157 | * are chrooting. |
158 | */ | 158 | */ |
159 | shell = (pw->pw_shell[0] == '\0') ? _PATH_BSHELL : pw->pw_shell; | 159 | if (options.chroot_directory == NULL || |
160 | 160 | strcasecmp(options.chroot_directory, "none") == 0) { | |
161 | /* deny if shell does not exists or is not executable */ | 161 | char *shell = xstrdup((pw->pw_shell[0] == '\0') ? |
162 | if (stat(shell, &st) != 0) { | 162 | _PATH_BSHELL : pw->pw_shell); /* empty = /bin/sh */ |
163 | logit("User %.100s not allowed because shell %.100s does not exist", | 163 | |
164 | pw->pw_name, shell); | 164 | if (stat(shell, &st) != 0) { |
165 | return 0; | 165 | logit("User %.100s not allowed because shell %.100s " |
166 | } | 166 | "does not exist", pw->pw_name, shell); |
167 | if (S_ISREG(st.st_mode) == 0 || | 167 | xfree(shell); |
168 | (st.st_mode & (S_IXOTH|S_IXUSR|S_IXGRP)) == 0) { | 168 | return 0; |
169 | logit("User %.100s not allowed because shell %.100s is not executable", | 169 | } |
170 | pw->pw_name, shell); | 170 | if (S_ISREG(st.st_mode) == 0 || |
171 | return 0; | 171 | (st.st_mode & (S_IXOTH|S_IXUSR|S_IXGRP)) == 0) { |
172 | logit("User %.100s not allowed because shell %.100s " | ||
173 | "is not executable", pw->pw_name, shell); | ||
174 | xfree(shell); | ||
175 | return 0; | ||
176 | } | ||
177 | xfree(shell); | ||
172 | } | 178 | } |
173 | 179 | ||
174 | if (options.num_deny_users > 0 || options.num_allow_users > 0 || | 180 | if (options.num_deny_users > 0 || options.num_allow_users > 0 || |
@@ -455,7 +461,7 @@ secure_filename(FILE *f, const char *file, struct passwd *pw, | |||
455 | return -1; | 461 | return -1; |
456 | } | 462 | } |
457 | 463 | ||
458 | /* If are passed the homedir then we can stop */ | 464 | /* If are past the homedir then we can stop */ |
459 | if (comparehome && strcmp(homedir, buf) == 0) { | 465 | if (comparehome && strcmp(homedir, buf) == 0) { |
460 | debug3("secure_filename: terminating check at '%s'", | 466 | debug3("secure_filename: terminating check at '%s'", |
461 | buf); | 467 | buf); |
@@ -483,8 +489,12 @@ auth_openkeyfile(const char *file, struct passwd *pw, int strict_modes) | |||
483 | * Open the file containing the authorized keys | 489 | * Open the file containing the authorized keys |
484 | * Fail quietly if file does not exist | 490 | * Fail quietly if file does not exist |
485 | */ | 491 | */ |
486 | if ((fd = open(file, O_RDONLY|O_NONBLOCK)) == -1) | 492 | if ((fd = open(file, O_RDONLY|O_NONBLOCK)) == -1) { |
493 | if (errno != ENOENT) | ||
494 | debug("Could not open keyfile '%s': %s", file, | ||
495 | strerror(errno)); | ||
487 | return NULL; | 496 | return NULL; |
497 | } | ||
488 | 498 | ||
489 | if (fstat(fd, &st) < 0) { | 499 | if (fstat(fd, &st) < 0) { |
490 | close(fd); | 500 | close(fd); |
@@ -525,7 +535,28 @@ getpwnamallow(const char *user) | |||
525 | parse_server_match_config(&options, user, | 535 | parse_server_match_config(&options, user, |
526 | get_canonical_hostname(options.use_dns), get_remote_ipaddr()); | 536 | get_canonical_hostname(options.use_dns), get_remote_ipaddr()); |
527 | 537 | ||
538 | #if defined(_AIX) && defined(HAVE_SETAUTHDB) | ||
539 | aix_setauthdb(user); | ||
540 | #endif | ||
541 | |||
528 | pw = getpwnam(user); | 542 | pw = getpwnam(user); |
543 | |||
544 | #if defined(_AIX) && defined(HAVE_SETAUTHDB) | ||
545 | aix_restoreauthdb(); | ||
546 | #endif | ||
547 | #ifdef HAVE_CYGWIN | ||
548 | /* | ||
549 | * Windows usernames are case-insensitive. To avoid later problems | ||
550 | * when trying to match the username, the user is only allowed to | ||
551 | * login if the username is given in the same case as stored in the | ||
552 | * user database. | ||
553 | */ | ||
554 | if (pw != NULL && strcmp(user, pw->pw_name) != 0) { | ||
555 | logit("Login name %.100s does not match stored username %.100s", | ||
556 | user, pw->pw_name); | ||
557 | pw = NULL; | ||
558 | } | ||
559 | #endif | ||
529 | if (pw == NULL) { | 560 | if (pw == NULL) { |
530 | logit("Invalid user %.100s from %.100s", | 561 | logit("Invalid user %.100s from %.100s", |
531 | user, get_remote_ipaddr()); | 562 | user, get_remote_ipaddr()); |
@@ -560,6 +591,35 @@ getpwnamallow(const char *user) | |||
560 | return (NULL); | 591 | return (NULL); |
561 | } | 592 | } |
562 | 593 | ||
594 | /* Returns 1 if key is revoked by revoked_keys_file, 0 otherwise */ | ||
595 | int | ||
596 | auth_key_is_revoked(Key *key) | ||
597 | { | ||
598 | char *key_fp; | ||
599 | |||
600 | if (options.revoked_keys_file == NULL) | ||
601 | return 0; | ||
602 | |||
603 | switch (key_in_file(key, options.revoked_keys_file, 0)) { | ||
604 | case 0: | ||
605 | /* key not revoked */ | ||
606 | return 0; | ||
607 | case -1: | ||
608 | /* Error opening revoked_keys_file: refuse all keys */ | ||
609 | error("Revoked keys file is unreadable: refusing public key " | ||
610 | "authentication"); | ||
611 | return 1; | ||
612 | case 1: | ||
613 | /* Key revoked */ | ||
614 | key_fp = key_fingerprint(key, SSH_FP_MD5, SSH_FP_HEX); | ||
615 | error("WARNING: authentication attempt with a revoked " | ||
616 | "%s key %s ", key_type(key), key_fp); | ||
617 | xfree(key_fp); | ||
618 | return 1; | ||
619 | } | ||
620 | fatal("key_in_file returned junk"); | ||
621 | } | ||
622 | |||
563 | void | 623 | void |
564 | auth_debug_add(const char *fmt,...) | 624 | auth_debug_add(const char *fmt,...) |
565 | { | 625 | { |