auth-passwd.c revision 113911
1195609Smp/* 259243Sobrien * Author: Tatu Ylonen <ylo@cs.hut.fi> 359243Sobrien * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland 459243Sobrien * All rights reserved 559243Sobrien * Password authentication. This file contains the functions to check whether 659243Sobrien * the password is valid for the user. 759243Sobrien * 859243Sobrien * As far as I am concerned, the code I have written for this software 959243Sobrien * can be used freely for any purpose. Any derived versions of this 1059243Sobrien * software must be clearly marked as such, and if the derived work is 1159243Sobrien * incompatible with the protocol description in the RFC file, it must be 1259243Sobrien * called by a name other than "ssh" or "Secure Shell". 1359243Sobrien * 1459243Sobrien * Copyright (c) 1999 Dug Song. All rights reserved. 1559243Sobrien * Copyright (c) 2000 Markus Friedl. All rights reserved. 1659243Sobrien * 17100616Smp * Redistribution and use in source and binary forms, with or without 1859243Sobrien * modification, are permitted provided that the following conditions 1959243Sobrien * are met: 2059243Sobrien * 1. Redistributions of source code must retain the above copyright 2159243Sobrien * notice, this list of conditions and the following disclaimer. 2259243Sobrien * 2. Redistributions in binary form must reproduce the above copyright 2359243Sobrien * notice, this list of conditions and the following disclaimer in the 2459243Sobrien * documentation and/or other materials provided with the distribution. 2559243Sobrien * 2659243Sobrien * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 2759243Sobrien * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 2859243Sobrien * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 2959243Sobrien * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 3059243Sobrien * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 3159243Sobrien * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 3259243Sobrien * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 3359243Sobrien * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 3459243Sobrien * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 3559243Sobrien * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 3659243Sobrien */ 3759243Sobrien 3859243Sobrien#include "includes.h" 3959243SobrienRCSID("$OpenBSD: auth-passwd.c,v 1.27 2002/05/24 16:45:16 stevesk Exp $"); 4059243SobrienRCSID("$FreeBSD: head/crypto/openssh/auth-passwd.c 113911 2003-04-23 17:13:13Z des $"); 4159243Sobrien 4269408Sache#include "packet.h" 4359243Sobrien#include "log.h" 4469408Sache#include "servconf.h" 4559243Sobrien#include "auth.h" 46195609Smp 47195609Smp/* 48195609Smp * Do not try to use PAM for password authentication, as it is 49195609Smp * already (and far better) supported by the challenge/response 50195609Smp * authentication mechanism. 5159243Sobrien */ 5259243Sobrien#undef USE_PAM 5359243Sobrien 5459243Sobrien#if !defined(USE_PAM) && !defined(HAVE_OSF_SIA) 5559243Sobrien/* Don't need any of these headers for the PAM or SIA cases */ 5659243Sobrien# ifdef HAVE_CRYPT_H 5759243Sobrien# include <crypt.h> 5859243Sobrien# endif 5959243Sobrien# ifdef WITH_AIXAUTHENTICATE 6059243Sobrien# include <login.h> 61167465Smp# endif 6259243Sobrien# ifdef __hpux 6359243Sobrien# include <hpsecurity.h> 64145479Smp# include <prot.h> 6559243Sobrien# endif 66145479Smp# ifdef HAVE_SECUREWARE 6759243Sobrien# include <sys/security.h> 6859243Sobrien# include <sys/audit.h> 6959243Sobrien# include <prot.h> 7059243Sobrien# endif /* HAVE_SECUREWARE */ 7159243Sobrien# if defined(HAVE_SHADOW_H) && !defined(DISABLE_SHADOW) 7259243Sobrien# include <shadow.h> 7359243Sobrien# endif 7459243Sobrien# if defined(HAVE_GETPWANAM) && !defined(DISABLE_SHADOW) 7559243Sobrien# include <sys/label.h> 7659243Sobrien# include <sys/audit.h> 7759243Sobrien# include <pwdadj.h> 7859243Sobrien# endif 7959243Sobrien# if defined(HAVE_MD5_PASSWORDS) && !defined(HAVE_MD5_CRYPT) 8059243Sobrien# include "md5crypt.h" 8159243Sobrien# endif /* defined(HAVE_MD5_PASSWORDS) && !defined(HAVE_MD5_CRYPT) */ 8259243Sobrien 8359243Sobrien# ifdef HAVE_CYGWIN 8459243Sobrien# undef ERROR 8559243Sobrien# include <windows.h> 8659243Sobrien# include <sys/cygwin.h> 8759243Sobrien# define is_winnt (GetVersion() < 0x80000000) 8859243Sobrien# endif 8959243Sobrien#endif /* !USE_PAM && !HAVE_OSF_SIA */ 9059243Sobrien 9159243Sobrienextern ServerOptions options; 9259243Sobrien#ifdef WITH_AIXAUTHENTICATE 9359243Sobrienextern char *aixloginmsg; 9459243Sobrien#endif 9559243Sobrien 9659243Sobrien/* 9759243Sobrien * Tries to authenticate the user using password. Returns true if 9859243Sobrien * authentication succeeds. 9959243Sobrien */ 10059243Sobrienint 10159243Sobrienauth_password(Authctxt *authctxt, const char *password) 10259243Sobrien{ 10359243Sobrien struct passwd * pw = authctxt->pw; 10459243Sobrien#if !defined(USE_PAM) && !defined(HAVE_OSF_SIA) 10559243Sobrien char *encrypted_password; 10659243Sobrien char *pw_password; 107167465Smp char *salt; 10859243Sobrien# if defined(__hpux) || defined(HAVE_SECUREWARE) 10959243Sobrien struct pr_passwd *spw; 11059243Sobrien# endif /* __hpux || HAVE_SECUREWARE */ 11159243Sobrien# if defined(HAVE_SHADOW_H) && !defined(DISABLE_SHADOW) 11259243Sobrien struct spwd *spw; 11359243Sobrien# endif 11459243Sobrien# if defined(HAVE_GETPWANAM) && !defined(DISABLE_SHADOW) 11559243Sobrien struct passwd_adjunct *spw; 11659243Sobrien# endif 11759243Sobrien# ifdef WITH_AIXAUTHENTICATE 11859243Sobrien char *authmsg; 11959243Sobrien int authsuccess; 12059243Sobrien int reenter = 1; 12159243Sobrien# endif 12259243Sobrien#endif /* !defined(USE_PAM) && !defined(HAVE_OSF_SIA) */ 12359243Sobrien 12459243Sobrien /* deny if no user. */ 125167465Smp if (pw == NULL) 12659243Sobrien return 0; 12759243Sobrien#ifndef HAVE_CYGWIN 12859243Sobrien if (pw->pw_uid == 0 && options.permit_root_login != PERMIT_YES) 12959243Sobrien return 0; 13059243Sobrien#endif 13159243Sobrien if (*password == '\0' && options.permit_empty_passwd == 0) 132167465Smp return 0; 13359243Sobrien 13459243Sobrien#if defined(USE_PAM) 13559243Sobrien return auth_pam_password(authctxt, password); 13683098Smp#elif defined(HAVE_OSF_SIA) 13783098Smp return auth_sia_password(authctxt, password); 13883098Smp#else 13983098Smp# ifdef KRB5 14083098Smp if (options.kerberos_authentication == 1) { 14159243Sobrien int ret = auth_krb5_password(authctxt, password); 142167465Smp if (ret == 1 || ret == 0) 14359243Sobrien return ret; 14459243Sobrien /* Fall back to ordinary passwd authentication. */ 14559243Sobrien } 14659243Sobrien# endif 147167465Smp# ifdef HAVE_CYGWIN 14859243Sobrien if (is_winnt) { 149167465Smp HANDLE hToken = cygwin_logon_user(pw, password); 150167465Smp 151167465Smp if (hToken == INVALID_HANDLE_VALUE) 152167465Smp return 0; 153167465Smp cygwin_set_impersonation_token(hToken); 154167465Smp return 1; 155167465Smp } 15659243Sobrien# endif 15759243Sobrien# ifdef WITH_AIXAUTHENTICATE 15859243Sobrien authsuccess = (authenticate(pw->pw_name,password,&reenter,&authmsg) == 0); 159145479Smp 16059243Sobrien if (authsuccess) 16159243Sobrien /* We don't have a pty yet, so just label the line as "ssh" */ 16259243Sobrien if (loginsuccess(authctxt->user, 16359243Sobrien get_canonical_hostname(options.verify_reverse_mapping), 16459243Sobrien "ssh", &aixloginmsg) < 0) 165145479Smp aixloginmsg = NULL; 166145479Smp 167145479Smp return(authsuccess); 16859243Sobrien# endif 16959243Sobrien# ifdef KRB4 17059243Sobrien if (options.kerberos_authentication == 1) { 171145479Smp int ret = auth_krb4_password(authctxt, password); 172145479Smp if (ret == 1 || ret == 0) 173145479Smp return ret; 17459243Sobrien /* Fall back to ordinary passwd authentication. */ 17559243Sobrien } 17659243Sobrien# endif 17759243Sobrien# ifdef BSD_AUTH 17859243Sobrien if (auth_userokay(pw->pw_name, authctxt->style, "auth-ssh", 17959243Sobrien (char *)password) == 0) 180145479Smp return 0; 18159243Sobrien else 18259243Sobrien return 1; 18359243Sobrien# endif 18459243Sobrien pw_password = pw->pw_passwd; 18559243Sobrien 186167465Smp /* 187167465Smp * Various interfaces to shadow or protected password data 18859243Sobrien */ 18959243Sobrien# if defined(HAVE_SHADOW_H) && !defined(DISABLE_SHADOW) 19059243Sobrien spw = getspnam(pw->pw_name); 19159243Sobrien if (spw != NULL) 19259243Sobrien pw_password = spw->sp_pwdp; 193167465Smp# endif /* defined(HAVE_SHADOW_H) && !defined(DISABLE_SHADOW) */ 19459243Sobrien 19559243Sobrien# if defined(HAVE_GETPWANAM) && !defined(DISABLE_SHADOW) 19659243Sobrien if (issecure() && (spw = getpwanam(pw->pw_name)) != NULL) 19759243Sobrien pw_password = spw->pwa_passwd; 19859243Sobrien# endif /* defined(HAVE_GETPWANAM) && !defined(DISABLE_SHADOW) */ 19959243Sobrien 20059243Sobrien# ifdef HAVE_SECUREWARE 20159243Sobrien if ((spw = getprpwnam(pw->pw_name)) != NULL) 20259243Sobrien pw_password = spw->ufld.fd_encrypt; 20359243Sobrien# endif /* HAVE_SECUREWARE */ 20459243Sobrien 20559243Sobrien# if defined(__hpux) && !defined(HAVE_SECUREWARE) 20659243Sobrien if (iscomsec() && (spw = getprpwnam(pw->pw_name)) != NULL) 20759243Sobrien pw_password = spw->ufld.fd_encrypt; 20859243Sobrien# endif /* defined(__hpux) && !defined(HAVE_SECUREWARE) */ 20959243Sobrien 21059243Sobrien /* Check for users with no password. */ 21159243Sobrien if ((password[0] == '\0') && (pw_password[0] == '\0')) 21259243Sobrien return 1; 21359243Sobrien 21459243Sobrien if (pw_password[0] != '\0') 21559243Sobrien salt = pw_password; 21659243Sobrien else 21759243Sobrien salt = "xx"; 21859243Sobrien 21959243Sobrien# ifdef HAVE_MD5_PASSWORDS 22059243Sobrien if (is_md5_salt(salt)) 22159243Sobrien encrypted_password = md5_crypt(password, salt); 22259243Sobrien else 22359243Sobrien encrypted_password = crypt(password, salt); 224145479Smp# else /* HAVE_MD5_PASSWORDS */ 225145479Smp# if defined(__hpux) && !defined(HAVE_SECUREWARE) 226145479Smp if (iscomsec()) 22759243Sobrien encrypted_password = bigcrypt(password, salt); 22859243Sobrien else 22959243Sobrien encrypted_password = crypt(password, salt); 230100616Smp# else 23159243Sobrien# ifdef HAVE_SECUREWARE 23259243Sobrien encrypted_password = bigcrypt(password, salt); 233145479Smp# else 234145479Smp encrypted_password = crypt(password, salt); 235145479Smp# endif /* HAVE_SECUREWARE */ 236145479Smp# endif /* __hpux && !defined(HAVE_SECUREWARE) */ 237167465Smp# endif /* HAVE_MD5_PASSWORDS */ 238167465Smp 239167465Smp /* Authentication is accepted if the encrypted passwords are identical. */ 240167465Smp return (strcmp(encrypted_password, pw_password) == 0); 241167465Smp#endif /* !USE_PAM && !HAVE_OSF_SIA */ 242145479Smp} 243145479Smp