/*
 * Copyright (c) 2000 Markus Friedl.  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"
RCSID("$OpenBSD: auth2.c,v 1.14 2000/09/07 20:27:49 deraadt Exp $");

#include <openssl/dsa.h>
#include <openssl/rsa.h>
#include <openssl/evp.h>

#include "xmalloc.h"
#include "rsa.h"
#include "ssh.h"
#include "pty.h"
#include "packet.h"
#include "buffer.h"
#include "cipher.h"
#include "servconf.h"
#include "compat.h"
#include "channels.h"
#include "bufaux.h"
#include "ssh2.h"
#include "auth.h"
#include "session.h"
#include "dispatch.h"
#include "auth.h"
#include "key.h"
#include "kex.h"

#include "dsa.h"
#include "uidswap.h"
#include "auth-options.h"

#ifdef HAVE_OSF_SIA
# include <sia.h>
# include <siad.h>
#endif

/* import */
extern ServerOptions options;
extern unsigned char *session_id2;
extern int session_id2_len;

/* protocol */

void	input_service_request(int type, int plen);
void	input_userauth_request(int type, int plen);
void	protocol_error(int type, int plen);

/* auth */
int	ssh2_auth_none(struct passwd *pw);
int	ssh2_auth_password(struct passwd *pw);
int  	ssh2_auth_pubkey(struct passwd *pw, char *service);

/* helper */
struct passwd*	 auth_set_user(char *u, char *s);
int	user_dsa_key_allowed(struct passwd *pw, Key *key);

typedef struct Authctxt Authctxt;
struct Authctxt {
	char *user;
	char *service;
	struct passwd pw;
	int valid;
};
static Authctxt	*authctxt = NULL;
static int userauth_success = 0;

/*
 * loop until userauth_success == TRUE
 */

void
do_authentication2()
{
	/* turn off skey/kerberos, not supported by SSH2 */
#ifdef SKEY
	options.skey_authentication = 0;
#endif
#ifdef KRB4
	options.kerberos_authentication = 0;
#endif

	dispatch_init(&protocol_error);
	dispatch_set(SSH2_MSG_SERVICE_REQUEST, &input_service_request);
	dispatch_run(DISPATCH_BLOCK, &userauth_success);
	do_authenticated2();
}

void
protocol_error(int type, int plen)
{
	log("auth: protocol error: type %d plen %d", type, plen);
	packet_start(SSH2_MSG_UNIMPLEMENTED);
	packet_put_int(0);
	packet_send();
	packet_write_wait();
}

void
input_service_request(int type, int plen)
{
	unsigned int len;
	int accept = 0;
	char *service = packet_get_string(&len);
	packet_done();

	if (strcmp(service, "ssh-userauth") == 0) {
		if (!userauth_success) {
			accept = 1;
			/* now we can handle user-auth requests */
			dispatch_set(SSH2_MSG_USERAUTH_REQUEST, &input_userauth_request);
		}
	}
	/* XXX all other service requests are denied */

	if (accept) {
		packet_start(SSH2_MSG_SERVICE_ACCEPT);
		packet_put_cstring(service);
		packet_send();
		packet_write_wait();
	} else {
		debug("bad service request %s", service);
		packet_disconnect("bad service request %s", service);
	}
	xfree(service);
}

void
input_userauth_request(int type, int plen)
{
	static void (*authlog) (const char *fmt,...) = verbose;
	static int attempt = 0;
	unsigned int len;
	int authenticated = 0;
	char *user, *service, *method, *authmsg = NULL;
	struct passwd *pw;
#ifdef WITH_AIXAUTHENTICATE
	extern char *aixloginmsg;
#endif /* WITH_AIXAUTHENTICATE */

	user = packet_get_string(&len);
	service = packet_get_string(&len);
	method = packet_get_string(&len);
	if (++attempt == AUTH_FAIL_MAX) {
#ifdef WITH_AIXAUTHENTICATE 
		loginfailed(user,get_canonical_hostname(),"ssh");
#endif /* WITH_AIXAUTHENTICATE */
		packet_disconnect("too many failed userauth_requests");
	}
	debug("userauth-request for user %s service %s method %s", user, service, method);

	/* XXX we only allow the ssh-connection service */
	pw = auth_set_user(user, service);
	if (pw && strcmp(service, "ssh-connection")==0) {
		if (strcmp(method, "none") == 0) {
			authenticated =	ssh2_auth_none(pw);
		} else if (strcmp(method, "password") == 0) {
			authenticated =	ssh2_auth_password(pw);
		} else if (strcmp(method, "publickey") == 0) {
			authenticated =	ssh2_auth_pubkey(pw, service);
		}
	}

#ifdef HAVE_CYGWIN
	if (authenticated && !check_nt_auth(strcmp(method, "password") == 0, pw->pw_uid)) {
		packet_disconnect("Authentication rejected for uid %d.",
				  (int) pw->pw_uid);
		authenticated = 0;
	}
#endif

	if (authenticated && pw && pw->pw_uid == 0 && !options.permit_root_login) {
		authenticated = 0;
		log("ROOT LOGIN REFUSED FROM %.200s",
		    get_canonical_hostname());
	}

#ifdef USE_PAM
	if (authenticated && !do_pam_account(pw->pw_name, NULL))
		authenticated = 0;
#endif /* USE_PAM */

	/* Raise logging level */
	if (authenticated == 1 ||
	    attempt == AUTH_FAIL_LOG ||
	    strcmp(method, "password") == 0)
		authlog = log;

	/* Log before sending the reply */
	if (authenticated == 1) {
		authmsg = "Accepted";
	} else if (authenticated == 0) {
		authmsg = "Failed";
	} else {
		authmsg = "Postponed";
	}
	authlog("%s %s for %.200s from %.200s port %d ssh2",
		authmsg,
		method,
		pw && pw->pw_uid == 0 ? "ROOT" : user,
		get_remote_ipaddr(),
		get_remote_port());

	/* XXX todo: check if multiple auth methods are needed */
	if (authenticated == 1) {
#ifdef WITH_AIXAUTHENTICATE
		/* We don't have a pty yet, so just label the line as "ssh" */
		if (loginsuccess(user,get_canonical_hostname(),"ssh",
				&aixloginmsg) < 0)
			aixloginmsg = NULL;
#endif /* WITH_AIXAUTHENTICATE */
		/* turn off userauth */
		dispatch_set(SSH2_MSG_USERAUTH_REQUEST, &protocol_error);
		packet_start(SSH2_MSG_USERAUTH_SUCCESS);
		packet_send();
		packet_write_wait();
		/* now we can break out */
		userauth_success = 1;
	} else if (authenticated == 0) {
		packet_start(SSH2_MSG_USERAUTH_FAILURE);
		packet_put_cstring("publickey,password");	/* XXX dynamic */
		packet_put_char(0);				/* XXX partial success, unused */
		packet_send();
		packet_write_wait();
	}

	xfree(service);
	xfree(user);
	xfree(method);
}

int
ssh2_auth_none(struct passwd *pw)
{
#ifdef HAVE_OSF_SIA
	extern int saved_argc;
	extern char **saved_argv;
#endif

	packet_done();

#ifdef USE_PAM
	return auth_pam_password(pw, "");
#elif defined(HAVE_OSF_SIA)
	return(sia_validate_user(NULL, saved_argc, saved_argv, 
		get_canonical_hostname(), pw->pw_name, NULL, 0, NULL, 
		"") == SIASUCCESS);
#else /* !HAVE_OSF_SIA && !USE_PAM */
	return auth_password(pw, "");
#endif /* USE_PAM */
}
int
ssh2_auth_password(struct passwd *pw)
{
	char *password;
	int authenticated = 0;
	int change;
	unsigned int len;
#ifdef HAVE_OSF_SIA
	extern int saved_argc;
	extern char **saved_argv;
#endif
	change = packet_get_char();
	if (change)
		log("password change not supported");
	password = packet_get_string(&len);
	packet_done();
	if (options.password_authentication &&
#ifdef USE_PAM
	    auth_pam_password(pw, password) == 1)
#elif defined(HAVE_OSF_SIA)
	    sia_validate_user(NULL, saved_argc, saved_argv, 
		 	get_canonical_hostname(), pw->pw_name, NULL, 0, 
			NULL, password) == SIASUCCESS)
#else /* !USE_PAM && !HAVE_OSF_SIA */
	    auth_password(pw, password) == 1)
#endif /* USE_PAM */
		authenticated = 1;
	memset(password, 0, len);
	xfree(password);
	return authenticated;
}
int
ssh2_auth_pubkey(struct passwd *pw, char *service)
{
	Buffer b;
	Key *key;
	char *pkalg, *pkblob, *sig;
	unsigned int alen, blen, slen;
	int have_sig;
	int authenticated = 0;

	if (options.dsa_authentication == 0) {
		debug("pubkey auth disabled");
		return 0;
	}
	have_sig = packet_get_char();
	pkalg = packet_get_string(&alen);
	if (strcmp(pkalg, KEX_DSS) != 0) {
		xfree(pkalg);
		log("bad pkalg %s", pkalg);	/*XXX*/
		return 0;
	}
	pkblob = packet_get_string(&blen);
	key = dsa_key_from_blob(pkblob, blen);
	if (key != NULL) {
		if (have_sig) {
			sig = packet_get_string(&slen);
			packet_done();
			buffer_init(&b);
			if (datafellows & SSH_COMPAT_SESSIONID_ENCODING) {
				buffer_put_string(&b, session_id2, session_id2_len);
			} else {
				buffer_append(&b, session_id2, session_id2_len);
			}
			/* reconstruct packet */
			buffer_put_char(&b, SSH2_MSG_USERAUTH_REQUEST);
			buffer_put_cstring(&b, pw->pw_name);
			buffer_put_cstring(&b,
			    datafellows & SSH_BUG_PUBKEYAUTH ?
			    "ssh-userauth" :
			    service);
			buffer_put_cstring(&b, "publickey");
			buffer_put_char(&b, have_sig);
			buffer_put_cstring(&b, KEX_DSS);
			buffer_put_string(&b, pkblob, blen);
#ifdef DEBUG_DSS
			buffer_dump(&b);
#endif
			/* test for correct signature */
			if (user_dsa_key_allowed(pw, key) &&
			    dsa_verify(key, sig, slen, buffer_ptr(&b), buffer_len(&b)) == 1)
				authenticated = 1;
			buffer_clear(&b);
			xfree(sig);
		} else {
			packet_done();
			debug("test key...");
			/* test whether pkalg/pkblob are acceptable */
			/* XXX fake reply and always send PK_OK ? */
			/*
			 * XXX this allows testing whether a user is allowed
			 * to login: if you happen to have a valid pubkey this
			 * message is sent. the message is NEVER sent at all
			 * if a user is not allowed to login. is this an
			 * issue? -markus
			 */
			if (user_dsa_key_allowed(pw, key)) {
				packet_start(SSH2_MSG_USERAUTH_PK_OK);
				packet_put_string(pkalg, alen);
				packet_put_string(pkblob, blen);
				packet_send();
				packet_write_wait();
				authenticated = -1;
			}
		}
		key_free(key);
	}
	xfree(pkalg);
	xfree(pkblob);
	return authenticated;
}

/* set and get current user */

struct passwd*
auth_get_user(void)
{
	return (authctxt != NULL && authctxt->valid) ? &authctxt->pw : NULL;
}

struct passwd*
auth_set_user(char *u, char *s)
{
	struct passwd *pw, *copy;

	if (authctxt == NULL) {
		authctxt = xmalloc(sizeof(*authctxt));
		authctxt->valid = 0;
		authctxt->user = xstrdup(u);
		authctxt->service = xstrdup(s);
		setproctitle("%s", u);
		pw = getpwnam(u);
		if (!pw || !allowed_user(pw)) {
			log("auth_set_user: illegal user %s", u);
			return NULL;
		}
#ifdef USE_PAM
		start_pam(pw);
#endif
		copy = &authctxt->pw;
		memset(copy, 0, sizeof(*copy));
		copy->pw_name = xstrdup(pw->pw_name);
		copy->pw_passwd = xstrdup(pw->pw_passwd);
		copy->pw_uid = pw->pw_uid;
		copy->pw_gid = pw->pw_gid;
#ifdef HAVE_PW_CLASS_IN_PASSWD
		copy->pw_class = xstrdup(pw->pw_class);
#endif
		copy->pw_dir = xstrdup(pw->pw_dir);
		copy->pw_shell = xstrdup(pw->pw_shell);
		authctxt->valid = 1;
	} else {
		if (strcmp(u, authctxt->user) != 0 ||
		    strcmp(s, authctxt->service) != 0) {
			log("auth_set_user: missmatch: (%s,%s)!=(%s,%s)",
			    u, s, authctxt->user, authctxt->service);
			return NULL;
		}
	}
	return auth_get_user();
}

/* return 1 if user allows given key */
int
user_dsa_key_allowed(struct passwd *pw, Key *key)
{
	char line[8192], file[1024];
	int found_key = 0;
	unsigned int bits = -1;
	FILE *f;
	unsigned long linenum = 0;
	struct stat st;
	Key *found;

	/* Temporarily use the user's uid. */
	temporarily_use_uid(pw->pw_uid);

	/* The authorized keys. */
	snprintf(file, sizeof file, "%.500s/%.100s", pw->pw_dir,
	    SSH_USER_PERMITTED_KEYS2);

	/* Fail quietly if file does not exist */
	if (stat(file, &st) < 0) {
		/* Restore the privileged uid. */
		restore_uid();
		return 0;
	}
	/* Open the file containing the authorized keys. */
	f = fopen(file, "r");
	if (!f) {
		/* Restore the privileged uid. */
		restore_uid();
		return 0;
	}
	if (options.strict_modes) {
		int fail = 0;
		char buf[1024];
		/* Check open file in order to avoid open/stat races */
		if (fstat(fileno(f), &st) < 0 ||
		    (st.st_uid != 0 && st.st_uid != pw->pw_uid) ||
		    (st.st_mode & 022) != 0) {
			snprintf(buf, sizeof buf, "DSA authentication refused for %.100s: "
			    "bad ownership or modes for '%s'.", pw->pw_name, file);
			fail = 1;
		} else {
			/* Check path to SSH_USER_PERMITTED_KEYS */
			int i;
			static const char *check[] = {
				"", SSH_USER_DIR, NULL
			};
			for (i = 0; check[i]; i++) {
				snprintf(line, sizeof line, "%.500s/%.100s",
				    pw->pw_dir, check[i]);
				if (stat(line, &st) < 0 ||
				    (st.st_uid != 0 && st.st_uid != pw->pw_uid) ||
				    (st.st_mode & 022) != 0) {
					snprintf(buf, sizeof buf,
					    "DSA authentication refused for %.100s: "
					    "bad ownership or modes for '%s'.",
					    pw->pw_name, line);
					fail = 1;
					break;
				}
			}
		}
		if (fail) {
			fclose(f);
			log("%s",buf);
			restore_uid();
			return 0;
		}
	}
	found_key = 0;
	found = key_new(KEY_DSA);

	while (fgets(line, sizeof(line), f)) {
		char *cp, *options = NULL;
		linenum++;
		/* Skip leading whitespace, empty and comment lines. */
		for (cp = line; *cp == ' ' || *cp == '\t'; cp++)
			;
		if (!*cp || *cp == '\n' || *cp == '#')
			continue;

		bits = key_read(found, &cp);
		if (bits == 0) {
			/* no key?  check if there are options for this key */
			int quoted = 0;
			options = cp;
			for (; *cp && (quoted || (*cp != ' ' && *cp != '\t')); cp++) {
				if (*cp == '\\' && cp[1] == '"')
					cp++;	/* Skip both */
				else if (*cp == '"')
					quoted = !quoted;
			}
			/* Skip remaining whitespace. */
			for (; *cp == ' ' || *cp == '\t'; cp++)
				;
			bits = key_read(found, &cp);
			if (bits == 0) {
				/* still no key?  advance to next line*/
				continue;
			}
		}
		if (key_equal(found, key) &&
		    auth_parse_options(pw, options, linenum) == 1) {
			found_key = 1;
			debug("matching key found: file %s, line %ld",
			    file, linenum);
			break;
		}
	}
	restore_uid();
	fclose(f);
	key_free(found);
	return found_key;
}
