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