diff options
Diffstat (limited to 'crypto/openssh/auth.c')
-rw-r--r-- | crypto/openssh/auth.c | 98 |
1 files changed, 79 insertions, 19 deletions
diff --git a/crypto/openssh/auth.c b/crypto/openssh/auth.c index 02f9175..2917414 100644 --- a/crypto/openssh/auth.c +++ b/crypto/openssh/auth.c @@ -1,4 +1,4 @@ -/* $OpenBSD: auth.c,v 1.80 2008/11/04 07:58:09 djm Exp $ */ +/* $OpenBSD: auth.c,v 1.86 2010/03/05 02:58:11 djm Exp $ */ /* * Copyright (c) 2000 Markus Friedl. All rights reserved. * @@ -70,6 +70,7 @@ __RCSID("$FreeBSD$"); #ifdef GSSAPI #include "ssh-gss.h" #endif +#include "authfile.h" #include "monitor_wrap.h" /* import */ @@ -96,7 +97,6 @@ allowed_user(struct passwd * pw) { struct stat st; const char *hostname = NULL, *ipaddr = NULL, *passwd = NULL; - char *shell; u_int i; #ifdef USE_SHADOW struct spwd *spw = NULL; @@ -154,22 +154,28 @@ allowed_user(struct passwd * pw) } /* - * Get the shell from the password data. An empty shell field is - * legal, and means /bin/sh. + * Deny if shell does not exist or is not executable unless we + * are chrooting. */ - shell = (pw->pw_shell[0] == '\0') ? _PATH_BSHELL : pw->pw_shell; - - /* deny if shell does not exists or is not executable */ - if (stat(shell, &st) != 0) { - logit("User %.100s not allowed because shell %.100s does not exist", - pw->pw_name, shell); - return 0; - } - if (S_ISREG(st.st_mode) == 0 || - (st.st_mode & (S_IXOTH|S_IXUSR|S_IXGRP)) == 0) { - logit("User %.100s not allowed because shell %.100s is not executable", - pw->pw_name, shell); - return 0; + if (options.chroot_directory == NULL || + strcasecmp(options.chroot_directory, "none") == 0) { + char *shell = xstrdup((pw->pw_shell[0] == '\0') ? + _PATH_BSHELL : pw->pw_shell); /* empty = /bin/sh */ + + if (stat(shell, &st) != 0) { + logit("User %.100s not allowed because shell %.100s " + "does not exist", pw->pw_name, shell); + xfree(shell); + return 0; + } + if (S_ISREG(st.st_mode) == 0 || + (st.st_mode & (S_IXOTH|S_IXUSR|S_IXGRP)) == 0) { + logit("User %.100s not allowed because shell %.100s " + "is not executable", pw->pw_name, shell); + xfree(shell); + return 0; + } + xfree(shell); } if (options.num_deny_users > 0 || options.num_allow_users > 0 || @@ -456,7 +462,7 @@ secure_filename(FILE *f, const char *file, struct passwd *pw, return -1; } - /* If are passed the homedir then we can stop */ + /* If are past the homedir then we can stop */ if (comparehome && strcmp(homedir, buf) == 0) { debug3("secure_filename: terminating check at '%s'", buf); @@ -484,8 +490,12 @@ auth_openkeyfile(const char *file, struct passwd *pw, int strict_modes) * Open the file containing the authorized keys * Fail quietly if file does not exist */ - if ((fd = open(file, O_RDONLY|O_NONBLOCK)) == -1) + if ((fd = open(file, O_RDONLY|O_NONBLOCK)) == -1) { + if (errno != ENOENT) + debug("Could not open keyfile '%s': %s", file, + strerror(errno)); return NULL; + } if (fstat(fd, &st) < 0) { close(fd); @@ -526,7 +536,28 @@ getpwnamallow(const char *user) parse_server_match_config(&options, user, get_canonical_hostname(options.use_dns), get_remote_ipaddr()); +#if defined(_AIX) && defined(HAVE_SETAUTHDB) + aix_setauthdb(user); +#endif + pw = getpwnam(user); + +#if defined(_AIX) && defined(HAVE_SETAUTHDB) + aix_restoreauthdb(); +#endif +#ifdef HAVE_CYGWIN + /* + * Windows usernames are case-insensitive. To avoid later problems + * when trying to match the username, the user is only allowed to + * login if the username is given in the same case as stored in the + * user database. + */ + if (pw != NULL && strcmp(user, pw->pw_name) != 0) { + logit("Login name %.100s does not match stored username %.100s", + user, pw->pw_name); + pw = NULL; + } +#endif if (pw == NULL) { logit("Invalid user %.100s from %.100s", user, get_remote_ipaddr()); @@ -561,6 +592,35 @@ getpwnamallow(const char *user) return (NULL); } +/* Returns 1 if key is revoked by revoked_keys_file, 0 otherwise */ +int +auth_key_is_revoked(Key *key) +{ + char *key_fp; + + if (options.revoked_keys_file == NULL) + return 0; + + switch (key_in_file(key, options.revoked_keys_file, 0)) { + case 0: + /* key not revoked */ + return 0; + case -1: + /* Error opening revoked_keys_file: refuse all keys */ + error("Revoked keys file is unreadable: refusing public key " + "authentication"); + return 1; + case 1: + /* Key revoked */ + key_fp = key_fingerprint(key, SSH_FP_MD5, SSH_FP_HEX); + error("WARNING: authentication attempt with a revoked " + "%s key %s ", key_type(key), key_fp); + xfree(key_fp); + return 1; + } + fatal("key_in_file returned junk"); +} + void auth_debug_add(const char *fmt,...) { |