1d059297112922cabb0c674840589be8db821fd9aAdam Langley/* $OpenBSD: auth.c,v 1.110 2015/02/25 17:29:38 djm Exp $ */ 2bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman/* 3bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman * Copyright (c) 2000 Markus Friedl. All rights reserved. 4bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman * 5bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman * Redistribution and use in source and binary forms, with or without 6bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman * modification, are permitted provided that the following conditions 7bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman * are met: 8bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman * 1. Redistributions of source code must retain the above copyright 9bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman * notice, this list of conditions and the following disclaimer. 10bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman * 2. Redistributions in binary form must reproduce the above copyright 11bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman * notice, this list of conditions and the following disclaimer in the 12bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman * documentation and/or other materials provided with the distribution. 13bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman * 14bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 15bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 16bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 17bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 18bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 19bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 20bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 21bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 22bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 23bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 24bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman */ 25bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman 26bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman#include "includes.h" 27bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman 28bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman#include <sys/types.h> 29bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman#include <sys/stat.h> 30bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman 31bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman#include <netinet/in.h> 32bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman 33bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman#include <errno.h> 34bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman#include <fcntl.h> 35bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman#ifdef HAVE_PATHS_H 36bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman# include <paths.h> 37bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman#endif 38bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman#include <pwd.h> 39bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman#ifdef HAVE_LOGIN_H 40bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman#include <login.h> 41bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman#endif 42bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman#ifdef USE_SHADOW 43bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman#include <shadow.h> 44bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman#endif 45bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman#ifdef HAVE_LIBGEN_H 46bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman#include <libgen.h> 47bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman#endif 48bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman#include <stdarg.h> 49bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman#include <stdio.h> 50bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman#include <string.h> 51bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman#include <unistd.h> 52d059297112922cabb0c674840589be8db821fd9aAdam Langley#include <limits.h> 53bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman 54bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman#include "xmalloc.h" 55bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman#include "match.h" 56bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman#include "groupaccess.h" 57bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman#include "log.h" 58bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman#include "buffer.h" 59d059297112922cabb0c674840589be8db821fd9aAdam Langley#include "misc.h" 60bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman#include "servconf.h" 61bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman#include "key.h" 62bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman#include "hostfile.h" 63bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman#include "auth.h" 64bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman#include "auth-options.h" 65bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman#include "canohost.h" 66bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman#include "uidswap.h" 67bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman#include "packet.h" 68bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman#include "loginrec.h" 69bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman#ifdef GSSAPI 70bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman#include "ssh-gss.h" 71bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman#endif 72bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman#include "authfile.h" 73bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman#include "monitor_wrap.h" 74d059297112922cabb0c674840589be8db821fd9aAdam Langley#include "authfile.h" 75d059297112922cabb0c674840589be8db821fd9aAdam Langley#include "ssherr.h" 76d059297112922cabb0c674840589be8db821fd9aAdam Langley#include "compat.h" 77bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman 78bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman/* import */ 79bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartmanextern ServerOptions options; 80bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartmanextern int use_privsep; 81bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartmanextern Buffer loginmsg; 82bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartmanextern struct passwd *privsep_pw; 83bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman 84bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman/* Debugging messages */ 85bd77cf78387b72b7b3ea870459077672bf75c3b5Greg HartmanBuffer auth_debug; 86bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartmanint auth_debug_init; 87bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman 88bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman/* 89bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman * Check if the user is allowed to log in via ssh. If user is listed 90bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman * in DenyUsers or one of user's groups is listed in DenyGroups, false 91bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman * will be returned. If AllowUsers isn't empty and user isn't listed 92bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman * there, or if AllowGroups isn't empty and one of user's groups isn't 93bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman * listed there, false will be returned. 94bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman * If the user's shell is not executable, false will be returned. 95bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman * Otherwise true is returned. 96bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman */ 97bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartmanint 98bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartmanallowed_user(struct passwd * pw) 99bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman{ 100bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman struct stat st; 101bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman const char *hostname = NULL, *ipaddr = NULL, *passwd = NULL; 102bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman u_int i; 103bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman#ifdef USE_SHADOW 104bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman struct spwd *spw = NULL; 105bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman#endif 106bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman 107bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman /* Shouldn't be called if pw is NULL, but better safe than sorry... */ 108bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman if (!pw || !pw->pw_name) 109bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman return 0; 110bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman 111bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman#ifdef USE_SHADOW 112bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman if (!options.use_pam) 113bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman spw = getspnam(pw->pw_name); 114bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman#ifdef HAS_SHADOW_EXPIRE 115bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman if (!options.use_pam && spw != NULL && auth_shadow_acctexpired(spw)) 116bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman return 0; 117bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman#endif /* HAS_SHADOW_EXPIRE */ 118bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman#endif /* USE_SHADOW */ 119bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman 120bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman /* grab passwd field for locked account check */ 121bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman passwd = pw->pw_passwd; 122bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman#ifdef USE_SHADOW 123bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman if (spw != NULL) 124bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman#ifdef USE_LIBIAF 125bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman passwd = get_iaf_password(pw); 126bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman#else 127bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman passwd = spw->sp_pwdp; 128bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman#endif /* USE_LIBIAF */ 129bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman#endif 130bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman 131bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman /* check for locked account */ 132bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman if (!options.use_pam && passwd && *passwd) { 133bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman int locked = 0; 134bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman 135bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman#ifdef LOCKED_PASSWD_STRING 136bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman if (strcmp(passwd, LOCKED_PASSWD_STRING) == 0) 137bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman locked = 1; 138bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman#endif 139bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman#ifdef LOCKED_PASSWD_PREFIX 140bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman if (strncmp(passwd, LOCKED_PASSWD_PREFIX, 141bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman strlen(LOCKED_PASSWD_PREFIX)) == 0) 142bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman locked = 1; 143bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman#endif 144bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman#ifdef LOCKED_PASSWD_SUBSTR 145bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman if (strstr(passwd, LOCKED_PASSWD_SUBSTR)) 146bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman locked = 1; 147bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman#endif 148bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman#ifdef USE_LIBIAF 149bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman free((void *) passwd); 150bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman#endif /* USE_LIBIAF */ 151bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman if (locked) { 152bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman logit("User %.100s not allowed because account is locked", 153bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman pw->pw_name); 154bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman return 0; 155bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman } 156bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman } 157bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman 158bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman /* 159bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman * Deny if shell does not exist or is not executable unless we 160bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman * are chrooting. 161bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman */ 162bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman if (options.chroot_directory == NULL || 163bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman strcasecmp(options.chroot_directory, "none") == 0) { 164bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman char *shell = xstrdup((pw->pw_shell[0] == '\0') ? 165bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman _PATH_BSHELL : pw->pw_shell); /* empty = /bin/sh */ 166bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman 167bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman if (stat(shell, &st) != 0) { 168bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman logit("User %.100s not allowed because shell %.100s " 169bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman "does not exist", pw->pw_name, shell); 170d059297112922cabb0c674840589be8db821fd9aAdam Langley free(shell); 171bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman return 0; 172bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman } 173bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman if (S_ISREG(st.st_mode) == 0 || 174bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman (st.st_mode & (S_IXOTH|S_IXUSR|S_IXGRP)) == 0) { 175bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman logit("User %.100s not allowed because shell %.100s " 176bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman "is not executable", pw->pw_name, shell); 177d059297112922cabb0c674840589be8db821fd9aAdam Langley free(shell); 178bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman return 0; 179bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman } 180d059297112922cabb0c674840589be8db821fd9aAdam Langley free(shell); 181bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman } 182bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman 183bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman if (options.num_deny_users > 0 || options.num_allow_users > 0 || 184bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman options.num_deny_groups > 0 || options.num_allow_groups > 0) { 185bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman hostname = get_canonical_hostname(options.use_dns); 186bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman ipaddr = get_remote_ipaddr(); 187bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman } 188bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman 189bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman /* Return false if user is listed in DenyUsers */ 190bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman if (options.num_deny_users > 0) { 191bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman for (i = 0; i < options.num_deny_users; i++) 192bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman if (match_user(pw->pw_name, hostname, ipaddr, 193bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman options.deny_users[i])) { 194bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman logit("User %.100s from %.100s not allowed " 195bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman "because listed in DenyUsers", 196bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman pw->pw_name, hostname); 197bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman return 0; 198bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman } 199bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman } 200bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman /* Return false if AllowUsers isn't empty and user isn't listed there */ 201bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman if (options.num_allow_users > 0) { 202bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman for (i = 0; i < options.num_allow_users; i++) 203bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman if (match_user(pw->pw_name, hostname, ipaddr, 204bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman options.allow_users[i])) 205bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman break; 206bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman /* i < options.num_allow_users iff we break for loop */ 207bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman if (i >= options.num_allow_users) { 208bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman logit("User %.100s from %.100s not allowed because " 209bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman "not listed in AllowUsers", pw->pw_name, hostname); 210bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman return 0; 211bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman } 212bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman } 213bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman if (options.num_deny_groups > 0 || options.num_allow_groups > 0) { 214bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman /* Get the user's group access list (primary and supplementary) */ 215bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman if (ga_init(pw->pw_name, pw->pw_gid) == 0) { 216bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman logit("User %.100s from %.100s not allowed because " 217bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman "not in any group", pw->pw_name, hostname); 218bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman return 0; 219bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman } 220bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman 221bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman /* Return false if one of user's groups is listed in DenyGroups */ 222bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman if (options.num_deny_groups > 0) 223bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman if (ga_match(options.deny_groups, 224bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman options.num_deny_groups)) { 225bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman ga_free(); 226bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman logit("User %.100s from %.100s not allowed " 227bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman "because a group is listed in DenyGroups", 228bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman pw->pw_name, hostname); 229bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman return 0; 230bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman } 231bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman /* 232bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman * Return false if AllowGroups isn't empty and one of user's groups 233bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman * isn't listed there 234bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman */ 235bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman if (options.num_allow_groups > 0) 236bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman if (!ga_match(options.allow_groups, 237bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman options.num_allow_groups)) { 238bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman ga_free(); 239bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman logit("User %.100s from %.100s not allowed " 240bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman "because none of user's groups are listed " 241bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman "in AllowGroups", pw->pw_name, hostname); 242bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman return 0; 243bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman } 244bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman ga_free(); 245bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman } 246bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman 247bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman#ifdef CUSTOM_SYS_AUTH_ALLOWED_USER 248bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman if (!sys_auth_allowed_user(pw, &loginmsg)) 249bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman return 0; 250bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman#endif 251bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman 252bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman /* We found no reason not to let this user try to log on... */ 253bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman return 1; 254bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman} 255bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman 256bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartmanvoid 257d059297112922cabb0c674840589be8db821fd9aAdam Langleyauth_info(Authctxt *authctxt, const char *fmt, ...) 258d059297112922cabb0c674840589be8db821fd9aAdam Langley{ 259d059297112922cabb0c674840589be8db821fd9aAdam Langley va_list ap; 260d059297112922cabb0c674840589be8db821fd9aAdam Langley int i; 261d059297112922cabb0c674840589be8db821fd9aAdam Langley 262d059297112922cabb0c674840589be8db821fd9aAdam Langley free(authctxt->info); 263d059297112922cabb0c674840589be8db821fd9aAdam Langley authctxt->info = NULL; 264d059297112922cabb0c674840589be8db821fd9aAdam Langley 265d059297112922cabb0c674840589be8db821fd9aAdam Langley va_start(ap, fmt); 266d059297112922cabb0c674840589be8db821fd9aAdam Langley i = vasprintf(&authctxt->info, fmt, ap); 267d059297112922cabb0c674840589be8db821fd9aAdam Langley va_end(ap); 268d059297112922cabb0c674840589be8db821fd9aAdam Langley 269d059297112922cabb0c674840589be8db821fd9aAdam Langley if (i < 0 || authctxt->info == NULL) 270d059297112922cabb0c674840589be8db821fd9aAdam Langley fatal("vasprintf failed"); 271d059297112922cabb0c674840589be8db821fd9aAdam Langley} 272d059297112922cabb0c674840589be8db821fd9aAdam Langley 273d059297112922cabb0c674840589be8db821fd9aAdam Langleyvoid 274d059297112922cabb0c674840589be8db821fd9aAdam Langleyauth_log(Authctxt *authctxt, int authenticated, int partial, 275d059297112922cabb0c674840589be8db821fd9aAdam Langley const char *method, const char *submethod) 276bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman{ 277bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman void (*authlog) (const char *fmt,...) = verbose; 278bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman char *authmsg; 279bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman 280bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman if (use_privsep && !mm_is_monitor() && !authctxt->postponed) 281bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman return; 282bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman 283bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman /* Raise logging level */ 284bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman if (authenticated == 1 || 285bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman !authctxt->valid || 286bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman authctxt->failures >= options.max_authtries / 2 || 287bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman strcmp(method, "password") == 0) 288bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman authlog = logit; 289bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman 290bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman if (authctxt->postponed) 291bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman authmsg = "Postponed"; 292d059297112922cabb0c674840589be8db821fd9aAdam Langley else if (partial) 293d059297112922cabb0c674840589be8db821fd9aAdam Langley authmsg = "Partial"; 294bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman else 295bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman authmsg = authenticated ? "Accepted" : "Failed"; 296bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman 297d059297112922cabb0c674840589be8db821fd9aAdam Langley authlog("%s %s%s%s for %s%.100s from %.200s port %d %s%s%s", 298bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman authmsg, 299bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman method, 300d059297112922cabb0c674840589be8db821fd9aAdam Langley submethod != NULL ? "/" : "", submethod == NULL ? "" : submethod, 301bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman authctxt->valid ? "" : "invalid user ", 302bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman authctxt->user, 303bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman get_remote_ipaddr(), 304bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman get_remote_port(), 305d059297112922cabb0c674840589be8db821fd9aAdam Langley compat20 ? "ssh2" : "ssh1", 306d059297112922cabb0c674840589be8db821fd9aAdam Langley authctxt->info != NULL ? ": " : "", 307d059297112922cabb0c674840589be8db821fd9aAdam Langley authctxt->info != NULL ? authctxt->info : ""); 308d059297112922cabb0c674840589be8db821fd9aAdam Langley free(authctxt->info); 309d059297112922cabb0c674840589be8db821fd9aAdam Langley authctxt->info = NULL; 310bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman 311bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman#ifdef CUSTOM_FAILED_LOGIN 312bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman if (authenticated == 0 && !authctxt->postponed && 313bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman (strcmp(method, "password") == 0 || 314bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman strncmp(method, "keyboard-interactive", 20) == 0 || 315bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman strcmp(method, "challenge-response") == 0)) 316bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman record_failed_login(authctxt->user, 317bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman get_canonical_hostname(options.use_dns), "ssh"); 318bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman# ifdef WITH_AIXAUTHENTICATE 319bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman if (authenticated) 320bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman sys_auth_record_login(authctxt->user, 321bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman get_canonical_hostname(options.use_dns), "ssh", &loginmsg); 322bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman# endif 323bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman#endif 324bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman#ifdef SSH_AUDIT_EVENTS 325bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman if (authenticated == 0 && !authctxt->postponed) 326bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman audit_event(audit_classify_auth(method)); 327bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman#endif 328bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman} 329bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman 330d059297112922cabb0c674840589be8db821fd9aAdam Langley 331d059297112922cabb0c674840589be8db821fd9aAdam Langleyvoid 332d059297112922cabb0c674840589be8db821fd9aAdam Langleyauth_maxtries_exceeded(Authctxt *authctxt) 333d059297112922cabb0c674840589be8db821fd9aAdam Langley{ 334d059297112922cabb0c674840589be8db821fd9aAdam Langley error("maximum authentication attempts exceeded for " 335d059297112922cabb0c674840589be8db821fd9aAdam Langley "%s%.100s from %.200s port %d %s", 336d059297112922cabb0c674840589be8db821fd9aAdam Langley authctxt->valid ? "" : "invalid user ", 337d059297112922cabb0c674840589be8db821fd9aAdam Langley authctxt->user, 338d059297112922cabb0c674840589be8db821fd9aAdam Langley get_remote_ipaddr(), 339d059297112922cabb0c674840589be8db821fd9aAdam Langley get_remote_port(), 340d059297112922cabb0c674840589be8db821fd9aAdam Langley compat20 ? "ssh2" : "ssh1"); 341d059297112922cabb0c674840589be8db821fd9aAdam Langley packet_disconnect("Too many authentication failures"); 342d059297112922cabb0c674840589be8db821fd9aAdam Langley /* NOTREACHED */ 343d059297112922cabb0c674840589be8db821fd9aAdam Langley} 344d059297112922cabb0c674840589be8db821fd9aAdam Langley 345bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman/* 346bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman * Check whether root logins are disallowed. 347bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman */ 348bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartmanint 349d059297112922cabb0c674840589be8db821fd9aAdam Langleyauth_root_allowed(const char *method) 350bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman{ 351bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman switch (options.permit_root_login) { 352bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman case PERMIT_YES: 353bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman return 1; 354bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman case PERMIT_NO_PASSWD: 355bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman if (strcmp(method, "password") != 0) 356bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman return 1; 357bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman break; 358bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman case PERMIT_FORCED_ONLY: 359bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman if (forced_command) { 360bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman logit("Root login accepted for forced command."); 361bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman return 1; 362bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman } 363bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman break; 364bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman } 365bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman logit("ROOT LOGIN REFUSED FROM %.200s", get_remote_ipaddr()); 366bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman return 0; 367bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman} 368bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman 369bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman 370bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman/* 371bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman * Given a template and a passwd structure, build a filename 372bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman * by substituting % tokenised options. Currently, %% becomes '%', 373bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman * %h becomes the home directory and %u the username. 374bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman * 375bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman * This returns a buffer allocated by xmalloc. 376bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman */ 377bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartmanchar * 378bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartmanexpand_authorized_keys(const char *filename, struct passwd *pw) 379bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman{ 380d059297112922cabb0c674840589be8db821fd9aAdam Langley char *file, ret[PATH_MAX]; 381bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman int i; 382bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman 383bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman file = percent_expand(filename, "h", pw->pw_dir, 384bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman "u", pw->pw_name, (char *)NULL); 385bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman 386bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman /* 387bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman * Ensure that filename starts anchored. If not, be backward 388bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman * compatible and prepend the '%h/' 389bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman */ 390bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman if (*file == '/') 391bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman return (file); 392bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman 393bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman i = snprintf(ret, sizeof(ret), "%s/%s", pw->pw_dir, file); 394bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman if (i < 0 || (size_t)i >= sizeof(ret)) 395bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman fatal("expand_authorized_keys: path too long"); 396d059297112922cabb0c674840589be8db821fd9aAdam Langley free(file); 397bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman return (xstrdup(ret)); 398bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman} 399bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman 400bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartmanchar * 401bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartmanauthorized_principals_file(struct passwd *pw) 402bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman{ 403d059297112922cabb0c674840589be8db821fd9aAdam Langley if (options.authorized_principals_file == NULL || 404d059297112922cabb0c674840589be8db821fd9aAdam Langley strcasecmp(options.authorized_principals_file, "none") == 0) 405bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman return NULL; 406bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman return expand_authorized_keys(options.authorized_principals_file, pw); 407bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman} 408bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman 409bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman/* return ok if key exists in sysfile or userfile */ 410bd77cf78387b72b7b3ea870459077672bf75c3b5Greg HartmanHostStatus 411bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartmancheck_key_in_hostfiles(struct passwd *pw, Key *key, const char *host, 412bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman const char *sysfile, const char *userfile) 413bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman{ 414bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman char *user_hostfile; 415bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman struct stat st; 416bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman HostStatus host_status; 417bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman struct hostkeys *hostkeys; 418bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman const struct hostkey_entry *found; 419bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman 420bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman hostkeys = init_hostkeys(); 421bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman load_hostkeys(hostkeys, host, sysfile); 422bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman if (userfile != NULL) { 423bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman user_hostfile = tilde_expand_filename(userfile, pw->pw_uid); 424bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman if (options.strict_modes && 425bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman (stat(user_hostfile, &st) == 0) && 426bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman ((st.st_uid != 0 && st.st_uid != pw->pw_uid) || 427bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman (st.st_mode & 022) != 0)) { 428bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman logit("Authentication refused for %.100s: " 429bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman "bad owner or modes for %.200s", 430bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman pw->pw_name, user_hostfile); 431bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman auth_debug_add("Ignored %.200s: bad ownership or modes", 432bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman user_hostfile); 433bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman } else { 434bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman temporarily_use_uid(pw); 435bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman load_hostkeys(hostkeys, host, user_hostfile); 436bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman restore_uid(); 437bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman } 438d059297112922cabb0c674840589be8db821fd9aAdam Langley free(user_hostfile); 439bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman } 440bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman host_status = check_key_in_hostkeys(hostkeys, key, &found); 441bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman if (host_status == HOST_REVOKED) 442bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman error("WARNING: revoked key for %s attempted authentication", 443bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman found->host); 444bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman else if (host_status == HOST_OK) 445bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman debug("%s: key for %s found at %s:%ld", __func__, 446bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman found->host, found->file, found->line); 447bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman else 448bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman debug("%s: key for host %s not found", __func__, host); 449bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman 450bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman free_hostkeys(hostkeys); 451bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman 452bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman return host_status; 453bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman} 454bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman 455bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman/* 456d059297112922cabb0c674840589be8db821fd9aAdam Langley * Check a given path for security. This is defined as all components 457bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman * of the path to the file must be owned by either the owner of 458bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman * of the file or root and no directories must be group or world writable. 459bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman * 460bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman * XXX Should any specific check be done for sym links ? 461bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman * 462d059297112922cabb0c674840589be8db821fd9aAdam Langley * Takes a file name, its stat information (preferably from fstat() to 463d059297112922cabb0c674840589be8db821fd9aAdam Langley * avoid races), the uid of the expected owner, their home directory and an 464bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman * error buffer plus max size as arguments. 465bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman * 466bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman * Returns 0 on success and -1 on failure 467bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman */ 468d059297112922cabb0c674840589be8db821fd9aAdam Langleyint 469d059297112922cabb0c674840589be8db821fd9aAdam Langleyauth_secure_path(const char *name, struct stat *stp, const char *pw_dir, 470d059297112922cabb0c674840589be8db821fd9aAdam Langley uid_t uid, char *err, size_t errlen) 471bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman{ 472d059297112922cabb0c674840589be8db821fd9aAdam Langley char buf[PATH_MAX], homedir[PATH_MAX]; 473bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman char *cp; 474bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman int comparehome = 0; 475bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman struct stat st; 476bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman 477d059297112922cabb0c674840589be8db821fd9aAdam Langley if (realpath(name, buf) == NULL) { 478d059297112922cabb0c674840589be8db821fd9aAdam Langley snprintf(err, errlen, "realpath %s failed: %s", name, 479bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman strerror(errno)); 480bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman return -1; 481bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman } 482d059297112922cabb0c674840589be8db821fd9aAdam Langley if (pw_dir != NULL && realpath(pw_dir, homedir) != NULL) 483bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman comparehome = 1; 484bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman 485d059297112922cabb0c674840589be8db821fd9aAdam Langley if (!S_ISREG(stp->st_mode)) { 486d059297112922cabb0c674840589be8db821fd9aAdam Langley snprintf(err, errlen, "%s is not a regular file", buf); 487d059297112922cabb0c674840589be8db821fd9aAdam Langley return -1; 488d059297112922cabb0c674840589be8db821fd9aAdam Langley } 489d059297112922cabb0c674840589be8db821fd9aAdam Langley if ((!platform_sys_dir_uid(stp->st_uid) && stp->st_uid != uid) || 490d059297112922cabb0c674840589be8db821fd9aAdam Langley (stp->st_mode & 022) != 0) { 491d059297112922cabb0c674840589be8db821fd9aAdam Langley#if defined(ANDROID) 492d059297112922cabb0c674840589be8db821fd9aAdam Langley /* needed to allow root login on Android. */ 493bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman if (getuid() != 0) 494bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman#endif 495d059297112922cabb0c674840589be8db821fd9aAdam Langley { 496d059297112922cabb0c674840589be8db821fd9aAdam Langley snprintf(err, errlen, "bad ownership or modes for file %s", 497d059297112922cabb0c674840589be8db821fd9aAdam Langley buf); 498d059297112922cabb0c674840589be8db821fd9aAdam Langley return -1; 499bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman } 500bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman } 501bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman 502bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman /* for each component of the canonical path, walking upwards */ 503bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman for (;;) { 504bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman if ((cp = dirname(buf)) == NULL) { 505bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman snprintf(err, errlen, "dirname() failed"); 506bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman return -1; 507bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman } 508bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman strlcpy(buf, cp, sizeof(buf)); 509bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman 510d059297112922cabb0c674840589be8db821fd9aAdam Langley#if !defined(ANDROID) 511d059297112922cabb0c674840589be8db821fd9aAdam Langley /* /data is owned by system user, which causes this check to fail */ 512bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman if (stat(buf, &st) < 0 || 513d059297112922cabb0c674840589be8db821fd9aAdam Langley (!platform_sys_dir_uid(st.st_uid) && st.st_uid != uid) || 514bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman (st.st_mode & 022) != 0) { 515bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman snprintf(err, errlen, 516bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman "bad ownership or modes for directory %s", buf); 517bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman return -1; 518bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman } 519bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman#endif 520d059297112922cabb0c674840589be8db821fd9aAdam Langley 521bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman /* If are past the homedir then we can stop */ 522bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman if (comparehome && strcmp(homedir, buf) == 0) 523bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman break; 524bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman 525bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman /* 526bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman * dirname should always complete with a "/" path, 527bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman * but we can be paranoid and check for "." too 528bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman */ 529bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman if ((strcmp("/", buf) == 0) || (strcmp(".", buf) == 0)) 530bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman break; 531bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman } 532bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman return 0; 533bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman} 534bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman 535d059297112922cabb0c674840589be8db821fd9aAdam Langley/* 536d059297112922cabb0c674840589be8db821fd9aAdam Langley * Version of secure_path() that accepts an open file descriptor to 537d059297112922cabb0c674840589be8db821fd9aAdam Langley * avoid races. 538d059297112922cabb0c674840589be8db821fd9aAdam Langley * 539d059297112922cabb0c674840589be8db821fd9aAdam Langley * Returns 0 on success and -1 on failure 540d059297112922cabb0c674840589be8db821fd9aAdam Langley */ 541d059297112922cabb0c674840589be8db821fd9aAdam Langleystatic int 542d059297112922cabb0c674840589be8db821fd9aAdam Langleysecure_filename(FILE *f, const char *file, struct passwd *pw, 543d059297112922cabb0c674840589be8db821fd9aAdam Langley char *err, size_t errlen) 544d059297112922cabb0c674840589be8db821fd9aAdam Langley{ 545d059297112922cabb0c674840589be8db821fd9aAdam Langley struct stat st; 546d059297112922cabb0c674840589be8db821fd9aAdam Langley 547d059297112922cabb0c674840589be8db821fd9aAdam Langley /* check the open file to avoid races */ 548d059297112922cabb0c674840589be8db821fd9aAdam Langley if (fstat(fileno(f), &st) < 0) { 549d059297112922cabb0c674840589be8db821fd9aAdam Langley snprintf(err, errlen, "cannot stat file %s: %s", 550d059297112922cabb0c674840589be8db821fd9aAdam Langley file, strerror(errno)); 551d059297112922cabb0c674840589be8db821fd9aAdam Langley return -1; 552d059297112922cabb0c674840589be8db821fd9aAdam Langley } 553d059297112922cabb0c674840589be8db821fd9aAdam Langley return auth_secure_path(file, &st, pw->pw_dir, pw->pw_uid, err, errlen); 554d059297112922cabb0c674840589be8db821fd9aAdam Langley} 555d059297112922cabb0c674840589be8db821fd9aAdam Langley 556bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartmanstatic FILE * 557bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartmanauth_openfile(const char *file, struct passwd *pw, int strict_modes, 558bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman int log_missing, char *file_type) 559bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman{ 560bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman char line[1024]; 561bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman struct stat st; 562bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman int fd; 563bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman FILE *f; 564bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman 565bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman if ((fd = open(file, O_RDONLY|O_NONBLOCK)) == -1) { 566bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman if (log_missing || errno != ENOENT) 567bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman debug("Could not open %s '%s': %s", file_type, file, 568bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman strerror(errno)); 569bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman return NULL; 570bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman } 571bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman 572bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman if (fstat(fd, &st) < 0) { 573bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman close(fd); 574bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman return NULL; 575bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman } 576bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman if (!S_ISREG(st.st_mode)) { 577bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman logit("User %s %s %s is not a regular file", 578bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman pw->pw_name, file_type, file); 579bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman close(fd); 580bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman return NULL; 581bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman } 582bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman unset_nonblock(fd); 583bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman if ((f = fdopen(fd, "r")) == NULL) { 584bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman close(fd); 585bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman return NULL; 586bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman } 587bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman if (strict_modes && 588bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman secure_filename(f, file, pw, line, sizeof(line)) != 0) { 589bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman fclose(f); 590bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman logit("Authentication refused: %s", line); 591bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman auth_debug_add("Ignored %s: %s", file_type, line); 592bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman return NULL; 593bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman } 594bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman 595bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman return f; 596bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman} 597bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman 598bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman 599bd77cf78387b72b7b3ea870459077672bf75c3b5Greg HartmanFILE * 600bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartmanauth_openkeyfile(const char *file, struct passwd *pw, int strict_modes) 601bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman{ 602bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman return auth_openfile(file, pw, strict_modes, 1, "authorized keys"); 603bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman} 604bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman 605bd77cf78387b72b7b3ea870459077672bf75c3b5Greg HartmanFILE * 606bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartmanauth_openprincipals(const char *file, struct passwd *pw, int strict_modes) 607bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman{ 608bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman return auth_openfile(file, pw, strict_modes, 0, 609bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman "authorized principals"); 610bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman} 611bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman 612bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartmanstruct passwd * 613bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartmangetpwnamallow(const char *user) 614bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman{ 615bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman#ifdef HAVE_LOGIN_CAP 616bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman extern login_cap_t *lc; 617bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman#ifdef BSD_AUTH 618bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman auth_session_t *as; 619bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman#endif 620bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman#endif 621bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman struct passwd *pw; 622d059297112922cabb0c674840589be8db821fd9aAdam Langley struct connection_info *ci = get_connection_info(1, options.use_dns); 623bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman 624d059297112922cabb0c674840589be8db821fd9aAdam Langley ci->user = user; 625d059297112922cabb0c674840589be8db821fd9aAdam Langley parse_server_match_config(&options, ci); 626bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman 627bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman#if defined(_AIX) && defined(HAVE_SETAUTHDB) 628bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman aix_setauthdb(user); 629bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman#endif 630bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman 631bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman pw = getpwnam(user); 632bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman 633bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman#if defined(_AIX) && defined(HAVE_SETAUTHDB) 634bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman aix_restoreauthdb(); 635bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman#endif 636bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman#ifdef HAVE_CYGWIN 637bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman /* 638bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman * Windows usernames are case-insensitive. To avoid later problems 639bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman * when trying to match the username, the user is only allowed to 640bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman * login if the username is given in the same case as stored in the 641bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman * user database. 642bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman */ 643bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman if (pw != NULL && strcmp(user, pw->pw_name) != 0) { 644bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman logit("Login name %.100s does not match stored username %.100s", 645bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman user, pw->pw_name); 646bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman pw = NULL; 647bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman } 648bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman#endif 649bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman if (pw == NULL) { 650bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman logit("Invalid user %.100s from %.100s", 651bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman user, get_remote_ipaddr()); 652bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman#ifdef CUSTOM_FAILED_LOGIN 653bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman record_failed_login(user, 654bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman get_canonical_hostname(options.use_dns), "ssh"); 655bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman#endif 656bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman#ifdef SSH_AUDIT_EVENTS 657bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman audit_event(SSH_INVALID_USER); 658bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman#endif /* SSH_AUDIT_EVENTS */ 659bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman return (NULL); 660bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman } 661bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman if (!allowed_user(pw)) 662bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman return (NULL); 663bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman#ifdef HAVE_LOGIN_CAP 664bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman if ((lc = login_getclass(pw->pw_class)) == NULL) { 665bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman debug("unable to get login class: %s", user); 666bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman return (NULL); 667bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman } 668bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman#ifdef BSD_AUTH 669bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman if ((as = auth_open()) == NULL || auth_setpwd(as, pw) != 0 || 670bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman auth_approval(as, lc, pw->pw_name, "ssh") <= 0) { 671bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman debug("Approval failure for %s", user); 672bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman pw = NULL; 673bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman } 674bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman if (as != NULL) 675bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman auth_close(as); 676bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman#endif 677bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman#endif 678bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman if (pw != NULL) 679bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman return (pwcopy(pw)); 680bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman return (NULL); 681bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman} 682bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman 683bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman/* Returns 1 if key is revoked by revoked_keys_file, 0 otherwise */ 684bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartmanint 685bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartmanauth_key_is_revoked(Key *key) 686bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman{ 687d059297112922cabb0c674840589be8db821fd9aAdam Langley char *fp = NULL; 688d059297112922cabb0c674840589be8db821fd9aAdam Langley int r; 689bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman 690bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman if (options.revoked_keys_file == NULL) 691bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman return 0; 692d059297112922cabb0c674840589be8db821fd9aAdam Langley if ((fp = sshkey_fingerprint(key, options.fingerprint_hash, 693d059297112922cabb0c674840589be8db821fd9aAdam Langley SSH_FP_DEFAULT)) == NULL) { 694d059297112922cabb0c674840589be8db821fd9aAdam Langley r = SSH_ERR_ALLOC_FAIL; 695d059297112922cabb0c674840589be8db821fd9aAdam Langley error("%s: fingerprint key: %s", __func__, ssh_err(r)); 696d059297112922cabb0c674840589be8db821fd9aAdam Langley goto out; 697d059297112922cabb0c674840589be8db821fd9aAdam Langley } 698bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman 699d059297112922cabb0c674840589be8db821fd9aAdam Langley r = sshkey_check_revoked(key, options.revoked_keys_file); 700d059297112922cabb0c674840589be8db821fd9aAdam Langley switch (r) { 701bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman case 0: 702d059297112922cabb0c674840589be8db821fd9aAdam Langley break; /* not revoked */ 703d059297112922cabb0c674840589be8db821fd9aAdam Langley case SSH_ERR_KEY_REVOKED: 704d059297112922cabb0c674840589be8db821fd9aAdam Langley error("Authentication key %s %s revoked by file %s", 705d059297112922cabb0c674840589be8db821fd9aAdam Langley sshkey_type(key), fp, options.revoked_keys_file); 706d059297112922cabb0c674840589be8db821fd9aAdam Langley goto out; 707d059297112922cabb0c674840589be8db821fd9aAdam Langley default: 708d059297112922cabb0c674840589be8db821fd9aAdam Langley error("Error checking authentication key %s %s in " 709d059297112922cabb0c674840589be8db821fd9aAdam Langley "revoked keys file %s: %s", sshkey_type(key), fp, 710d059297112922cabb0c674840589be8db821fd9aAdam Langley options.revoked_keys_file, ssh_err(r)); 711d059297112922cabb0c674840589be8db821fd9aAdam Langley goto out; 712bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman } 713d059297112922cabb0c674840589be8db821fd9aAdam Langley 714d059297112922cabb0c674840589be8db821fd9aAdam Langley /* Success */ 715d059297112922cabb0c674840589be8db821fd9aAdam Langley r = 0; 716d059297112922cabb0c674840589be8db821fd9aAdam Langley 717d059297112922cabb0c674840589be8db821fd9aAdam Langley out: 718d059297112922cabb0c674840589be8db821fd9aAdam Langley free(fp); 719d059297112922cabb0c674840589be8db821fd9aAdam Langley return r == 0 ? 0 : 1; 720bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman} 721bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman 722bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartmanvoid 723bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartmanauth_debug_add(const char *fmt,...) 724bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman{ 725bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman char buf[1024]; 726bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman va_list args; 727bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman 728bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman if (!auth_debug_init) 729bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman return; 730bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman 731bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman va_start(args, fmt); 732bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman vsnprintf(buf, sizeof(buf), fmt, args); 733bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman va_end(args); 734bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman buffer_put_cstring(&auth_debug, buf); 735bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman} 736bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman 737bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartmanvoid 738bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartmanauth_debug_send(void) 739bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman{ 740bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman char *msg; 741bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman 742bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman if (!auth_debug_init) 743bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman return; 744bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman while (buffer_len(&auth_debug)) { 745bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman msg = buffer_get_string(&auth_debug, NULL); 746bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman packet_send_debug("%s", msg); 747d059297112922cabb0c674840589be8db821fd9aAdam Langley free(msg); 748bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman } 749bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman} 750bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman 751bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartmanvoid 752bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartmanauth_debug_reset(void) 753bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman{ 754bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman if (auth_debug_init) 755bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman buffer_clear(&auth_debug); 756bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman else { 757bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman buffer_init(&auth_debug); 758bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman auth_debug_init = 1; 759bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman } 760bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman} 761bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman 762bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartmanstruct passwd * 763bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartmanfakepw(void) 764bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman{ 765bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman static struct passwd fake; 766bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman 767bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman memset(&fake, 0, sizeof(fake)); 768bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman fake.pw_name = "NOUSER"; 769bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman fake.pw_passwd = 770bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman "$2a$06$r3.juUaHZDlIbQaO2dS9FuYxL1W9M81R1Tc92PoSNmzvpEqLkLGrK"; 771d059297112922cabb0c674840589be8db821fd9aAdam Langley#ifdef HAVE_STRUCT_PASSWD_PW_GECOS 772bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman fake.pw_gecos = "NOUSER"; 773bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman#endif 774bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman fake.pw_uid = privsep_pw == NULL ? (uid_t)-1 : privsep_pw->pw_uid; 775bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman fake.pw_gid = privsep_pw == NULL ? (gid_t)-1 : privsep_pw->pw_gid; 776d059297112922cabb0c674840589be8db821fd9aAdam Langley#ifdef HAVE_STRUCT_PASSWD_PW_CLASS 777bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman fake.pw_class = ""; 778bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman#endif 779bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman fake.pw_dir = "/nonexist"; 780bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman fake.pw_shell = "/nonexist"; 781bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman 782bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman return (&fake); 783bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman} 784