auth-passwd.c revision 113911
157429Smarkm/* 257429Smarkm * Author: Tatu Ylonen <ylo@cs.hut.fi> 357429Smarkm * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland 457429Smarkm * All rights reserved 557429Smarkm * Password authentication. This file contains the functions to check whether 657429Smarkm * the password is valid for the user. 765674Skris * 865674Skris * As far as I am concerned, the code I have written for this software 965674Skris * can be used freely for any purpose. Any derived versions of this 1065674Skris * software must be clearly marked as such, and if the derived work is 1165674Skris * incompatible with the protocol description in the RFC file, it must be 1265674Skris * called by a name other than "ssh" or "Secure Shell". 1365674Skris * 1465674Skris * Copyright (c) 1999 Dug Song. All rights reserved. 1565674Skris * Copyright (c) 2000 Markus Friedl. All rights reserved. 1665674Skris * 1765674Skris * Redistribution and use in source and binary forms, with or without 1865674Skris * modification, are permitted provided that the following conditions 1965674Skris * are met: 2065674Skris * 1. Redistributions of source code must retain the above copyright 2165674Skris * notice, this list of conditions and the following disclaimer. 2265674Skris * 2. Redistributions in binary form must reproduce the above copyright 2365674Skris * notice, this list of conditions and the following disclaimer in the 2465674Skris * documentation and/or other materials provided with the distribution. 2565674Skris * 2665674Skris * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 2765674Skris * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 2865674Skris * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 2965674Skris * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 3065674Skris * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 3165674Skris * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 3265674Skris * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 3365674Skris * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 3465674Skris * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 3565674Skris * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 3657429Smarkm */ 3757429Smarkm 3857429Smarkm#include "includes.h" 3998684SdesRCSID("$OpenBSD: auth-passwd.c,v 1.27 2002/05/24 16:45:16 stevesk Exp $"); 4099748SdesRCSID("$FreeBSD: head/crypto/openssh/auth-passwd.c 113911 2003-04-23 17:13:13Z des $"); 4157429Smarkm 4257429Smarkm#include "packet.h" 4376262Sgreen#include "log.h" 4457429Smarkm#include "servconf.h" 4576262Sgreen#include "auth.h" 4657429Smarkm 4799748Sdes/* 4899748Sdes * Do not try to use PAM for password authentication, as it is 4999748Sdes * already (and far better) supported by the challenge/response 5099748Sdes * authentication mechanism. 5199748Sdes */ 5299748Sdes#undef USE_PAM 5399748Sdes 5498941Sdes#if !defined(USE_PAM) && !defined(HAVE_OSF_SIA) 5598941Sdes/* Don't need any of these headers for the PAM or SIA cases */ 5698941Sdes# ifdef HAVE_CRYPT_H 5798941Sdes# include <crypt.h> 5898941Sdes# endif 5998941Sdes# ifdef WITH_AIXAUTHENTICATE 6098941Sdes# include <login.h> 6198941Sdes# endif 6298941Sdes# ifdef __hpux 6398941Sdes# include <hpsecurity.h> 6498941Sdes# include <prot.h> 6598941Sdes# endif 6698941Sdes# ifdef HAVE_SECUREWARE 6798941Sdes# include <sys/security.h> 6898941Sdes# include <sys/audit.h> 6998941Sdes# include <prot.h> 7098941Sdes# endif /* HAVE_SECUREWARE */ 7198941Sdes# if defined(HAVE_SHADOW_H) && !defined(DISABLE_SHADOW) 7298941Sdes# include <shadow.h> 7398941Sdes# endif 7498941Sdes# if defined(HAVE_GETPWANAM) && !defined(DISABLE_SHADOW) 7598941Sdes# include <sys/label.h> 7698941Sdes# include <sys/audit.h> 7798941Sdes# include <pwdadj.h> 7898941Sdes# endif 7998941Sdes# if defined(HAVE_MD5_PASSWORDS) && !defined(HAVE_MD5_CRYPT) 8098941Sdes# include "md5crypt.h" 8198941Sdes# endif /* defined(HAVE_MD5_PASSWORDS) && !defined(HAVE_MD5_CRYPT) */ 8276262Sgreen 8398941Sdes# ifdef HAVE_CYGWIN 8498941Sdes# undef ERROR 8598941Sdes# include <windows.h> 8698941Sdes# include <sys/cygwin.h> 8798941Sdes# define is_winnt (GetVersion() < 0x80000000) 8898941Sdes# endif 8998941Sdes#endif /* !USE_PAM && !HAVE_OSF_SIA */ 9098941Sdes 9176262Sgreenextern ServerOptions options; 92106130Sdes#ifdef WITH_AIXAUTHENTICATE 93106130Sdesextern char *aixloginmsg; 94106130Sdes#endif 9576262Sgreen 9657429Smarkm/* 9757429Smarkm * Tries to authenticate the user using password. Returns true if 9857429Smarkm * authentication succeeds. 9957429Smarkm */ 10065674Skrisint 10176262Sgreenauth_password(Authctxt *authctxt, const char *password) 10257429Smarkm{ 10376262Sgreen struct passwd * pw = authctxt->pw; 104113911Sdes#if !defined(USE_PAM) && !defined(HAVE_OSF_SIA) 10598941Sdes char *encrypted_password; 10698941Sdes char *pw_password; 10798941Sdes char *salt; 108113911Sdes# if defined(__hpux) || defined(HAVE_SECUREWARE) 10998941Sdes struct pr_passwd *spw; 110113911Sdes# endif /* __hpux || HAVE_SECUREWARE */ 111113911Sdes# if defined(HAVE_SHADOW_H) && !defined(DISABLE_SHADOW) 11298941Sdes struct spwd *spw; 113113911Sdes# endif 114113911Sdes# if defined(HAVE_GETPWANAM) && !defined(DISABLE_SHADOW) 11598941Sdes struct passwd_adjunct *spw; 116113911Sdes# endif 117113911Sdes# ifdef WITH_AIXAUTHENTICATE 11898941Sdes char *authmsg; 119106130Sdes int authsuccess; 12098941Sdes int reenter = 1; 121113911Sdes# endif 122113911Sdes#endif /* !defined(USE_PAM) && !defined(HAVE_OSF_SIA) */ 12357429Smarkm 12457429Smarkm /* deny if no user. */ 12557429Smarkm if (pw == NULL) 12657429Smarkm return 0; 12798941Sdes#ifndef HAVE_CYGWIN 12898941Sdes if (pw->pw_uid == 0 && options.permit_root_login != PERMIT_YES) 12957429Smarkm return 0; 13098941Sdes#endif 13157429Smarkm if (*password == '\0' && options.permit_empty_passwd == 0) 13257429Smarkm return 0; 133113911Sdes 134113911Sdes#if defined(USE_PAM) 135113911Sdes return auth_pam_password(authctxt, password); 136113911Sdes#elif defined(HAVE_OSF_SIA) 137113911Sdes return auth_sia_password(authctxt, password); 138113911Sdes#else 139113911Sdes# ifdef KRB5 14073400Sassar if (options.kerberos_authentication == 1) { 14192559Sdes int ret = auth_krb5_password(authctxt, password); 14292559Sdes if (ret == 1 || ret == 0) 14392559Sdes return ret; 14457565Smarkm /* Fall back to ordinary passwd authentication. */ 14557565Smarkm } 146113911Sdes# endif 147113911Sdes# ifdef HAVE_CYGWIN 14898941Sdes if (is_winnt) { 14998941Sdes HANDLE hToken = cygwin_logon_user(pw, password); 15098941Sdes 15198941Sdes if (hToken == INVALID_HANDLE_VALUE) 15298941Sdes return 0; 15398941Sdes cygwin_set_impersonation_token(hToken); 15498941Sdes return 1; 15598941Sdes } 156113911Sdes# endif 157113911Sdes# ifdef WITH_AIXAUTHENTICATE 158106130Sdes authsuccess = (authenticate(pw->pw_name,password,&reenter,&authmsg) == 0); 159106130Sdes 160106130Sdes if (authsuccess) 161106130Sdes /* We don't have a pty yet, so just label the line as "ssh" */ 162106130Sdes if (loginsuccess(authctxt->user, 163106130Sdes get_canonical_hostname(options.verify_reverse_mapping), 164106130Sdes "ssh", &aixloginmsg) < 0) 165106130Sdes aixloginmsg = NULL; 166106130Sdes 167106130Sdes return(authsuccess); 168113911Sdes# endif 169113911Sdes# ifdef KRB4 17073400Sassar if (options.kerberos_authentication == 1) { 17192559Sdes int ret = auth_krb4_password(authctxt, password); 17257429Smarkm if (ret == 1 || ret == 0) 17357429Smarkm return ret; 17457429Smarkm /* Fall back to ordinary passwd authentication. */ 17557429Smarkm } 176113911Sdes# endif 177113911Sdes# ifdef BSD_AUTH 17892559Sdes if (auth_userokay(pw->pw_name, authctxt->style, "auth-ssh", 17992559Sdes (char *)password) == 0) 18092559Sdes return 0; 18192559Sdes else 18292559Sdes return 1; 183113911Sdes# endif 18498941Sdes pw_password = pw->pw_passwd; 18598941Sdes 18698941Sdes /* 18798941Sdes * Various interfaces to shadow or protected password data 18898941Sdes */ 189113911Sdes# if defined(HAVE_SHADOW_H) && !defined(DISABLE_SHADOW) 19098941Sdes spw = getspnam(pw->pw_name); 19198941Sdes if (spw != NULL) 19298941Sdes pw_password = spw->sp_pwdp; 193113911Sdes# endif /* defined(HAVE_SHADOW_H) && !defined(DISABLE_SHADOW) */ 19498941Sdes 195113911Sdes# if defined(HAVE_GETPWANAM) && !defined(DISABLE_SHADOW) 19698941Sdes if (issecure() && (spw = getpwanam(pw->pw_name)) != NULL) 19798941Sdes pw_password = spw->pwa_passwd; 198113911Sdes# endif /* defined(HAVE_GETPWANAM) && !defined(DISABLE_SHADOW) */ 19998941Sdes 200113911Sdes# ifdef HAVE_SECUREWARE 20198941Sdes if ((spw = getprpwnam(pw->pw_name)) != NULL) 20298941Sdes pw_password = spw->ufld.fd_encrypt; 203113911Sdes# endif /* HAVE_SECUREWARE */ 20498941Sdes 205113911Sdes# if defined(__hpux) && !defined(HAVE_SECUREWARE) 20698941Sdes if (iscomsec() && (spw = getprpwnam(pw->pw_name)) != NULL) 20798941Sdes pw_password = spw->ufld.fd_encrypt; 208113911Sdes# endif /* defined(__hpux) && !defined(HAVE_SECUREWARE) */ 20998941Sdes 21057429Smarkm /* Check for users with no password. */ 21198941Sdes if ((password[0] == '\0') && (pw_password[0] == '\0')) 21257429Smarkm return 1; 21398941Sdes 21498941Sdes if (pw_password[0] != '\0') 21598941Sdes salt = pw_password; 21698941Sdes else 21798941Sdes salt = "xx"; 21898941Sdes 219113911Sdes# ifdef HAVE_MD5_PASSWORDS 22098941Sdes if (is_md5_salt(salt)) 22198941Sdes encrypted_password = md5_crypt(password, salt); 22298941Sdes else 22398941Sdes encrypted_password = crypt(password, salt); 224113911Sdes# else /* HAVE_MD5_PASSWORDS */ 225113911Sdes# if defined(__hpux) && !defined(HAVE_SECUREWARE) 22698941Sdes if (iscomsec()) 22798941Sdes encrypted_password = bigcrypt(password, salt); 22898941Sdes else 22998941Sdes encrypted_password = crypt(password, salt); 230113911Sdes# else 231113911Sdes# ifdef HAVE_SECUREWARE 23298941Sdes encrypted_password = bigcrypt(password, salt); 233113911Sdes# else 23498941Sdes encrypted_password = crypt(password, salt); 235113911Sdes# endif /* HAVE_SECUREWARE */ 236113911Sdes# endif /* __hpux && !defined(HAVE_SECUREWARE) */ 237113911Sdes# endif /* HAVE_MD5_PASSWORDS */ 23898941Sdes 23998941Sdes /* Authentication is accepted if the encrypted passwords are identical. */ 24098941Sdes return (strcmp(encrypted_password, pw_password) == 0); 24198941Sdes#endif /* !USE_PAM && !HAVE_OSF_SIA */ 24257429Smarkm} 243