/*
 * Copyright (c) 2000 Damien Miller.  All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in the
 *    documentation and/or other materials provided with the distribution.
 *
 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 */

#include "includes.h"

#ifdef USE_PAM
#include "ssh.h"
#include "xmalloc.h"
#include "log.h"
#include "auth-pam.h"
#include "servconf.h"
#include "canohost.h"
#include "readpass.h"

RCSID("$Id: auth-pam.c,v 1.29 2001/02/15 00:51:32 djm Exp $");

#define NEW_AUTHTOK_MSG \
	"Warning: Your password has expired, please change it now"

static int do_pam_conversation(int num_msg, const struct pam_message **msg,
	struct pam_response **resp, void *appdata_ptr);

/* module-local variables */
static struct pam_conv conv = {
	do_pam_conversation,
	NULL
};
static char *__pam_msg = NULL;
static pam_handle_t *__pamh = NULL;
static const char *__pampasswd = NULL;

/* states for do_pam_conversation() */
enum { INITIAL_LOGIN, OTHER } pamstate = INITIAL_LOGIN;
/* remember whether pam_acct_mgmt() returned PAM_NEWAUTHTOK_REQD */
static int password_change_required = 0;
/* remember whether the last pam_authenticate() succeeded or not */
static int was_authenticated = 0;

/* Remember what has been initialised */
static int session_opened = 0;
static int creds_set = 0;

/* accessor which allows us to switch conversation structs according to
 * the authentication method being used */
void do_pam_set_conv(struct pam_conv *conv)
{
	pam_set_item(__pamh, PAM_CONV, conv);
}

/* start an authentication run */
int do_pam_authenticate(int flags)
{
	int retval = pam_authenticate(__pamh, flags);
	was_authenticated = (retval == PAM_SUCCESS);
	return retval;
}

/*
 * PAM conversation function.
 * There are two states this can run in.
 *
 * INITIAL_LOGIN mode simply feeds the password from the client into
 * PAM in response to PAM_PROMPT_ECHO_OFF, and collects output
 * messages with into __pam_msg.  This is used during initial
 * authentication to bypass the normal PAM password prompt.
 *
 * OTHER mode handles PAM_PROMPT_ECHO_OFF with read_passphrase(prompt, 1)
 * and outputs messages to stderr. This mode is used if pam_chauthtok()
 * is called to update expired passwords.
 */
static int do_pam_conversation(int num_msg, const struct pam_message **msg,
	struct pam_response **resp, void *appdata_ptr)
{
	struct pam_response *reply;
	int count;
	char buf[1024];

	/* PAM will free this later */
	reply = malloc(num_msg * sizeof(*reply));
	if (reply == NULL)
		return PAM_CONV_ERR;

	for (count = 0; count < num_msg; count++) {
		if (pamstate == INITIAL_LOGIN) {
			/*
			 * We can't use stdio yet, queue messages for 
			 * printing later
			 */
			switch(PAM_MSG_MEMBER(msg, count, msg_style)) {
			case PAM_PROMPT_ECHO_ON:
				free(reply);
				return PAM_CONV_ERR;
			case PAM_PROMPT_ECHO_OFF:
				if (__pampasswd == NULL) {
					free(reply);
					return PAM_CONV_ERR;
				}
				reply[count].resp = xstrdup(__pampasswd);
				reply[count].resp_retcode = PAM_SUCCESS;
				break;
			case PAM_ERROR_MSG:
			case PAM_TEXT_INFO:
				if ((*msg)[count].msg != NULL) {
					message_cat(&__pam_msg, 
					    PAM_MSG_MEMBER(msg, count, msg));
				}
				reply[count].resp = xstrdup("");
				reply[count].resp_retcode = PAM_SUCCESS;
				break;
			default:
				free(reply);
				return PAM_CONV_ERR;
			}
		} else {
			/*
			 * stdio is connected, so interact directly
			 */
			switch(PAM_MSG_MEMBER(msg, count, msg_style)) {
			case PAM_PROMPT_ECHO_ON:
				fputs(PAM_MSG_MEMBER(msg, count, msg), stderr);
				fgets(buf, sizeof(buf), stdin);
				reply[count].resp = xstrdup(buf);
				reply[count].resp_retcode = PAM_SUCCESS;
				break;
			case PAM_PROMPT_ECHO_OFF:
				reply[count].resp = xstrdup(
				    read_passphrase(PAM_MSG_MEMBER(msg, count, 
				    msg), 1));
				reply[count].resp_retcode = PAM_SUCCESS;
				break;
			case PAM_ERROR_MSG:
			case PAM_TEXT_INFO:
				if ((*msg)[count].msg != NULL)
					fprintf(stderr, "%s\n", 
					    PAM_MSG_MEMBER(msg, count, msg));
				reply[count].resp = xstrdup("");
				reply[count].resp_retcode = PAM_SUCCESS;
				break;
			default:
				free(reply);
				return PAM_CONV_ERR;
			}
		}
	}

	*resp = reply;

	return PAM_SUCCESS;
}

/* Called at exit to cleanly shutdown PAM */
void do_pam_cleanup_proc(void *context)
{
	int pam_retval;

	if (__pamh && session_opened) {
		pam_retval = pam_close_session(__pamh, 0);
		if (pam_retval != PAM_SUCCESS)
			log("Cannot close PAM session[%d]: %.200s",
			    pam_retval, PAM_STRERROR(__pamh, pam_retval));
	}

	if (__pamh && creds_set) {
		pam_retval = pam_setcred(__pamh, PAM_DELETE_CRED);
		if (pam_retval != PAM_SUCCESS)
			debug("Cannot delete credentials[%d]: %.200s", 
			    pam_retval, PAM_STRERROR(__pamh, pam_retval));
	}

	if (__pamh) {
		pam_retval = pam_end(__pamh, pam_retval);
		if (pam_retval != PAM_SUCCESS)
			log("Cannot release PAM authentication[%d]: %.200s",
			    pam_retval, PAM_STRERROR(__pamh, pam_retval));
	}
}

/* Attempt password authentation using PAM */
int auth_pam_password(struct passwd *pw, const char *password)
{
	extern ServerOptions options;
	int pam_retval;

	do_pam_set_conv(&conv);

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

	__pampasswd = password;

	pamstate = INITIAL_LOGIN;
	pam_retval = do_pam_authenticate(0);
	if (pam_retval == PAM_SUCCESS) {
		debug("PAM Password authentication accepted for "
		    "user \"%.100s\"", pw->pw_name);
		return 1;
	} else {
		debug("PAM Password authentication for \"%.100s\" "
		    "failed[%d]: %s", pw->pw_name, pam_retval, 
		    PAM_STRERROR(__pamh, pam_retval));
		return 0;
	}
}

/* Do account management using PAM */
int do_pam_account(char *username, char *remote_user)
{
	int pam_retval;

	do_pam_set_conv(&conv);

	if (remote_user) {
		debug("PAM setting ruser to \"%.200s\"", remote_user);
		pam_retval = pam_set_item(__pamh, PAM_RUSER, remote_user);
		if (pam_retval != PAM_SUCCESS)
			fatal("PAM set ruser failed[%d]: %.200s", pam_retval, 
			    PAM_STRERROR(__pamh, pam_retval));
	}

	pam_retval = pam_acct_mgmt(__pamh, 0);
	switch (pam_retval) {
		case PAM_SUCCESS:
			/* This is what we want */
			break;
		case PAM_NEW_AUTHTOK_REQD:
			message_cat(&__pam_msg, NEW_AUTHTOK_MSG);
			/* flag that password change is necessary */
			password_change_required = 1;
			break;
		default:
			log("PAM rejected by account configuration[%d]: "
			    "%.200s", pam_retval, PAM_STRERROR(__pamh, 
			    pam_retval));
			return(0);
	}

	return(1);
}

/* Do PAM-specific session initialisation */
void do_pam_session(char *username, const char *ttyname)
{
	int pam_retval;

	if (ttyname != NULL) {
		debug("PAM setting tty to \"%.200s\"", ttyname);
		pam_retval = pam_set_item(__pamh, PAM_TTY, ttyname);
		if (pam_retval != PAM_SUCCESS)
			fatal("PAM set tty failed[%d]: %.200s",
			    pam_retval, PAM_STRERROR(__pamh, pam_retval));
	}

	pam_retval = pam_open_session(__pamh, 0);
	if (pam_retval != PAM_SUCCESS)
		fatal("PAM session setup failed[%d]: %.200s",
		    pam_retval, PAM_STRERROR(__pamh, pam_retval));
	session_opened = 1;
}

/* Set PAM credentials */
void do_pam_setcred(void)
{
	int pam_retval;

	debug("PAM establishing creds");
	pam_retval = pam_setcred(__pamh, PAM_ESTABLISH_CRED);
	if (pam_retval != PAM_SUCCESS) {
		if (was_authenticated)
			fatal("PAM setcred failed[%d]: %.200s",
			    pam_retval, PAM_STRERROR(__pamh, pam_retval));
		else
			debug("PAM setcred failed[%d]: %.200s",
			    pam_retval, PAM_STRERROR(__pamh, pam_retval));
	} else
		creds_set = 1;
}

/* accessor function for file scope static variable */
int is_pam_password_change_required(void)
{
	return password_change_required;
}

/*
 * Have user change authentication token if pam_acct_mgmt() indicated
 * it was expired.  This needs to be called after an interactive
 * session is established and the user's pty is connected to
 * stdin/stout/stderr.
 */
void do_pam_chauthtok(void)
{
	int pam_retval;

	if (password_change_required) {
		pamstate = OTHER;
		/* XXX: should we really loop forever? */
		do {
			pam_retval = pam_chauthtok(__pamh, 
			    PAM_CHANGE_EXPIRED_AUTHTOK);
			if (pam_retval != PAM_SUCCESS)
				log("PAM pam_chauthtok failed[%d]: %.200s",
				    pam_retval, PAM_STRERROR(__pamh, pam_retval));
		} while (pam_retval != PAM_SUCCESS);
	}
}

/* Cleanly shutdown PAM */
void finish_pam(void)
{
	do_pam_cleanup_proc(NULL);
	fatal_remove_cleanup(&do_pam_cleanup_proc, NULL);
}

/* Start PAM authentication for specified account */
void start_pam(const char *user)
{
	int pam_retval;
	extern ServerOptions options;

	debug("Starting up PAM with username \"%.200s\"", user);

	pam_retval = pam_start(SSHD_PAM_SERVICE, user, &conv, &__pamh);

	if (pam_retval != PAM_SUCCESS)
		fatal("PAM initialisation failed[%d]: %.200s",
		    pam_retval, PAM_STRERROR(__pamh, pam_retval));

	debug("PAM setting rhost to \"%.200s\"",
	    get_canonical_hostname(options.reverse_mapping_check));
	pam_retval = pam_set_item(__pamh, PAM_RHOST,
		get_canonical_hostname(options.reverse_mapping_check));
	if (pam_retval != PAM_SUCCESS)
		fatal("PAM set rhost failed[%d]: %.200s", pam_retval,
		    PAM_STRERROR(__pamh, pam_retval));
#ifdef PAM_TTY_KLUDGE
	/*
	 * Some PAM modules (e.g. pam_time) require a TTY to operate,
	 * and will fail in various stupid ways if they don't get one.
	 * sshd doesn't set the tty until too late in the auth process and may
	 * not even need one (for tty-less connections)
	 * Kludge: Set a fake PAM_TTY
	 */
	pam_retval = pam_set_item(__pamh, PAM_TTY, "ssh");
	if (pam_retval != PAM_SUCCESS)
		fatal("PAM set tty failed[%d]: %.200s",
		    pam_retval, PAM_STRERROR(__pamh, pam_retval));
#endif /* PAM_TTY_KLUDGE */

	fatal_add_cleanup(&do_pam_cleanup_proc, NULL);
}

/* Return list of PAM enviornment strings */
char **fetch_pam_environment(void)
{
#ifdef HAVE_PAM_GETENVLIST
	return(pam_getenvlist(__pamh));
#else /* HAVE_PAM_GETENVLIST */
	return(NULL);
#endif /* HAVE_PAM_GETENVLIST */
}

/* Print any messages that have been generated during authentication */
/* or account checking to stderr */
void print_pam_messages(void)
{
	if (__pam_msg != NULL)
		fputs(__pam_msg, stderr);
}

/* Append a message to buffer */
void message_cat(char **p, const char *a)
{
	char *cp;
	size_t new_len;

	new_len = strlen(a);

	if (*p) {
		size_t len = strlen(*p);

		*p = xrealloc(*p, new_len + len + 2);
		cp = *p + len;
	} else
		*p = cp = xmalloc(new_len + 2);

	memcpy(cp, a, new_len);
	cp[new_len] = '\n';
	cp[new_len + 1] = '\0';
}

#endif /* USE_PAM */
