/*
 * Author: Tatu Ylonen <ylo@cs.hut.fi>
 * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
 *                    All rights reserved
 * Created: Sat Mar 18 05:11:38 1995 ylo
 * Password authentication.  This file contains the functions to check whether
 * the password is valid for the user.
 */

#include "includes.h"

#ifndef HAVE_PAM

RCSID("$Id: auth-passwd.c,v 1.7 1999/11/25 00:54:57 damien Exp $");

#include "packet.h"
#include "ssh.h"
#include "servconf.h"
#include "xmalloc.h"

#ifdef HAVE_SHADOW_H
#include <shadow.h>
#endif

#ifdef HAVE_MD5_PASSWORDS
#include "md5crypt.h"
#endif

/*
 * Tries to authenticate the user using password.  Returns true if
 * authentication succeeds.
 */
int 
auth_password(struct passwd * pw, const char *password)
{
	extern ServerOptions options;
	char *encrypted_password;
#ifdef HAVE_SHADOW_H
	struct spwd *spw;
#endif

	if (pw->pw_uid == 0 && options.permit_root_login == 2)
		return 0;
	if (*password == '\0' && options.permit_empty_passwd == 0)
		return 0;
	/* deny if no user. */
	if (pw == NULL)
		return 0;

#ifdef SKEY
	if (options.skey_authentication == 1) {
		if (strncasecmp(password, "s/key", 5) == 0) {
			char *skeyinfo = skey_keyinfo(pw->pw_name);
			if (skeyinfo == NULL) {
				debug("generating fake skeyinfo for %.100s.",
				    pw->pw_name);
				skeyinfo = skey_fake_keyinfo(pw->pw_name);
			}
			if (skeyinfo != NULL)
				packet_send_debug(skeyinfo);
			/* Try again. */
			return 0;
		} else if (skey_haskey(pw->pw_name) == 0 &&
			   skey_passcheck(pw->pw_name, (char *) password) != -1) {
			/* Authentication succeeded. */
			return 1;
		}
		/* Fall back to ordinary passwd authentication. */
	}
#endif

#if defined(KRB4)
	/*
	 * Support for Kerberos v4 authentication
	 * - Dug Song <dugsong@UMICH.EDU>
	 */
	if (options.kerberos_authentication) {
		AUTH_DAT adata;
		KTEXT_ST tkt;
		struct hostent *hp;
		unsigned long faddr;
		char localhost[MAXHOSTNAMELEN];
		char phost[INST_SZ];
		char realm[REALM_SZ];
		int r;

		/*
		 * Try Kerberos password authentication only for non-root
		 * users and only if Kerberos is installed.
		 */
		if (pw->pw_uid != 0 && krb_get_lrealm(realm, 1) == KSUCCESS) {

			/* Set up our ticket file. */
			if (!krb4_init(pw->pw_uid)) {
				log("Couldn't initialize Kerberos ticket file for %s!",
				    pw->pw_name);
				goto kerberos_auth_failure;
			}
			/* Try to get TGT using our password. */
			r = krb_get_pw_in_tkt((char *) pw->pw_name, "",
			    realm, "krbtgt", realm,
			    DEFAULT_TKT_LIFE, (char *) password);
			if (r != INTK_OK) {
				packet_send_debug("Kerberos V4 password "
				    "authentication for %s failed: %s",
				    pw->pw_name, krb_err_txt[r]);
				goto kerberos_auth_failure;
			}
			/* Successful authentication. */
			chown(tkt_string(), pw->pw_uid, pw->pw_gid);

			/*
			 * Now that we have a TGT, try to get a local
			 * "rcmd" ticket to ensure that we are not talking
			 * to a bogus Kerberos server.
			 */
			(void) gethostname(localhost, sizeof(localhost));
			(void) strlcpy(phost, (char *) krb_get_phost(localhost),
			    INST_SZ);
			r = krb_mk_req(&tkt, KRB4_SERVICE_NAME, phost, realm, 33);

			if (r == KSUCCESS) {
				if (!(hp = gethostbyname(localhost))) {
					log("Couldn't get local host address!");
					goto kerberos_auth_failure;
				}
				memmove((void *) &faddr, (void *) hp->h_addr,
				    sizeof(faddr));

				/* Verify our "rcmd" ticket. */
				r = krb_rd_req(&tkt, KRB4_SERVICE_NAME, phost,
				    faddr, &adata, "");
				if (r == RD_AP_UNDEC) {
					/*
					 * Probably didn't have a srvtab on
					 * localhost. Allow login.
					 */
					log("Kerberos V4 TGT for %s unverifiable, "
					    "no srvtab installed? krb_rd_req: %s",
					    pw->pw_name, krb_err_txt[r]);
				} else if (r != KSUCCESS) {
					log("Kerberos V4 %s ticket unverifiable: %s",
					    KRB4_SERVICE_NAME, krb_err_txt[r]);
					goto kerberos_auth_failure;
				}
			} else if (r == KDC_PR_UNKNOWN) {
				/*
				 * Allow login if no rcmd service exists, but
				 * log the error.
				 */
				log("Kerberos V4 TGT for %s unverifiable: %s; %s.%s "
				    "not registered, or srvtab is wrong?", pw->pw_name,
				krb_err_txt[r], KRB4_SERVICE_NAME, phost);
			} else {
				/*
				 * TGT is bad, forget it. Possibly spoofed!
				 */
				packet_send_debug("WARNING: Kerberos V4 TGT "
				    "possibly spoofed for %s: %s",
				    pw->pw_name, krb_err_txt[r]);
				goto kerberos_auth_failure;
			}

			/* Authentication succeeded. */
			return 1;

	kerberos_auth_failure:
			krb4_cleanup_proc(NULL);

			if (!options.kerberos_or_local_passwd)
				return 0;
		} else {
			/* Logging in as root or no local Kerberos realm. */
			packet_send_debug("Unable to authenticate to Kerberos.");
		}
		/* Fall back to ordinary passwd authentication. */
	}
#endif				/* KRB4 */

	/* Check for users with no password. */
	if (strcmp(password, "") == 0 && strcmp(pw->pw_passwd, "") == 0)
		return 1;

#ifdef HAVE_SHADOW_H
	spw = getspnam(pw->pw_name);
	if (spw == NULL)
		return(0);

	if ((spw->sp_namp == NULL) || (strcmp(pw->pw_name, spw->sp_namp) != 0))
		fatal("Shadow lookup returned garbage.");

	if (strlen(spw->sp_pwdp) < 3)
		return(0);

	/* Encrypt the candidate password using the proper salt. */
#ifdef HAVE_MD5_PASSWORDS
	if (is_md5_salt(spw->sp_pwdp))
		encrypted_password = md5_crypt(password, spw->sp_pwdp);
	else
		encrypted_password = crypt(password, spw->sp_pwdp);
#else /* HAVE_MD5_PASSWORDS */    
	encrypted_password = crypt(password, spw->sp_pwdp);
#endif /* HAVE_MD5_PASSWORDS */    
	/* Authentication is accepted if the encrypted passwords are identical. */
	return (strcmp(encrypted_password, spw->sp_pwdp) == 0);
#else /* !HAVE_SHADOW_H */
	encrypted_password = crypt(password,
	    (pw->pw_passwd[0] && pw->pw_passwd[1]) ? pw->pw_passwd : "xx");

	/* Authentication is accepted if the encrypted passwords are identical. */
	return (strcmp(encrypted_password, pw->pw_passwd) == 0);
#endif /* !HAVE_SHADOW_H */
}
#endif /* !HAVE_PAM */
