/*
 * 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 "servconf.h"
#include "canohost.h"
#include "readpass.h"

RCSID("$Id: auth-pam.c,v 1.22 2001/01/22 05:34:40 mouring Exp $");

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

/* Callbacks */
static int pamconv(int num_msg, const struct pam_message **msg,
	  struct pam_response **resp, void *appdata_ptr);
void pam_cleanup_proc(void *context);
void pam_msg_cat(const char *msg);

/* module-local variables */
static struct pam_conv conv = {
	pamconv,
	NULL
};
static pam_handle_t *pamh = NULL;
static const char *pampasswd = NULL;
static char *pam_msg = NULL;

/* states for pamconv() */
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;

/* accessor which allows us to switch conversation structs according to
 * the authentication method being used */
void 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 pam_msg_cat().  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 pamconv(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++) {
		switch(PAM_MSG_MEMBER(msg, count, msg_style)) {
			case PAM_PROMPT_ECHO_ON:
				if (pamstate == INITIAL_LOGIN) {
					free(reply);
					return PAM_CONV_ERR;
				} else {
					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:
				if (pamstate == INITIAL_LOGIN) {
					if (pampasswd == NULL) {
						free(reply);
						return PAM_CONV_ERR;
					}
					reply[count].resp = xstrdup(pampasswd);
				} else {
					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) {
					if (pamstate == INITIAL_LOGIN)
						pam_msg_cat(PAM_MSG_MEMBER(msg, count, msg));
					else {
						fputs(PAM_MSG_MEMBER(msg, count, msg), stderr);
						fputs("\n", stderr);
					}
				}
				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 pam_cleanup_proc(void *context)
{
	int pam_retval;

	if (pamh != NULL)
	{
		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));
		}

		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));
		}

		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;

	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;
	
	debug("PAM setting rhost to \"%.200s\"", get_canonical_hostname());
	pam_retval = pam_set_item(pamh, PAM_RHOST, 
		get_canonical_hostname());
	if (pam_retval != PAM_SUCCESS) {
		fatal("PAM set rhost failed[%d]: %.200s", 
			pam_retval, PAM_STRERROR(pamh, pam_retval));
	}

	if (remote_user != NULL) {
		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:
			pam_msg_cat(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));
	}
}

/* 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));
		}
	}
}

/* accessor function for file scope static variable */
int 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)
{
	pam_cleanup_proc(NULL);
	fatal_remove_cleanup(&pam_cleanup_proc, NULL);
}

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

	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));
	}

#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(&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 the PAM message buffer */
void pam_msg_cat(const char *msg)
{
	char *p;
	size_t new_msg_len;
	size_t pam_msg_len;
	
	new_msg_len = strlen(msg);
	
	if (pam_msg) {
		pam_msg_len = strlen(pam_msg);
		pam_msg = xrealloc(pam_msg, new_msg_len + pam_msg_len + 2);
		p = pam_msg + pam_msg_len;
	} else {
		pam_msg = p = xmalloc(new_msg_len + 2);
	}

	memcpy(p, msg, new_msg_len);
	p[new_msg_len] = '\n';
	p[new_msg_len + 1] = '\0';
}

#endif /* USE_PAM */
