/*
 * Author: Tatu Ylonen <ylo@cs.hut.fi>
 * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
 *                    All rights reserved
 * As far as I am concerned, the code I have written for this software
 * can be used freely for any purpose.  Any derived versions of this
 * software must be clearly marked as such, and if the derived work is
 * incompatible with the protocol description in the RFC file, it must be
 * called by a name other than "ssh" or "Secure Shell".
 */

#include "includes.h"
RCSID("$OpenBSD: auth-options.c,v 1.11 2001/01/21 19:05:41 markus Exp $");

#include "packet.h"
#include "xmalloc.h"
#include "match.h"
#include "log.h"
#include "canohost.h"
#include "auth-options.h"

/* Flags set authorized_keys flags */
int no_port_forwarding_flag = 0;
int no_agent_forwarding_flag = 0;
int no_x11_forwarding_flag = 0;
int no_pty_flag = 0;

/* "command=" option. */
char *forced_command = NULL;

/* "environment=" options. */
struct envstring *custom_environment = NULL;

void
auth_clear_options(void)
{
	no_agent_forwarding_flag = 0;
	no_port_forwarding_flag = 0;
	no_pty_flag = 0;
	no_x11_forwarding_flag = 0;
	while (custom_environment) {
		struct envstring *ce = custom_environment;
		custom_environment = ce->next;
		xfree(ce->s);
		xfree(ce);
	}
	if (forced_command) {
		xfree(forced_command);
		forced_command = NULL;
	}
}

/*
 * return 1 if access is granted, 0 if not.
 * side effect: sets key option flags
 */
int
auth_parse_options(struct passwd *pw, char *options, char *file, u_long linenum)
{
	const char *cp;
	if (!options)
		return 1;

	/* reset options */
	auth_clear_options();

	while (*options && *options != ' ' && *options != '\t') {
		cp = "no-port-forwarding";
		if (strncasecmp(options, cp, strlen(cp)) == 0) {
			packet_send_debug("Port forwarding disabled.");
			no_port_forwarding_flag = 1;
			options += strlen(cp);
			goto next_option;
		}
		cp = "no-agent-forwarding";
		if (strncasecmp(options, cp, strlen(cp)) == 0) {
			packet_send_debug("Agent forwarding disabled.");
			no_agent_forwarding_flag = 1;
			options += strlen(cp);
			goto next_option;
		}
		cp = "no-X11-forwarding";
		if (strncasecmp(options, cp, strlen(cp)) == 0) {
			packet_send_debug("X11 forwarding disabled.");
			no_x11_forwarding_flag = 1;
			options += strlen(cp);
			goto next_option;
		}
		cp = "no-pty";
		if (strncasecmp(options, cp, strlen(cp)) == 0) {
			packet_send_debug("Pty allocation disabled.");
			no_pty_flag = 1;
			options += strlen(cp);
			goto next_option;
		}
		cp = "command=\"";
		if (strncasecmp(options, cp, strlen(cp)) == 0) {
			int i;
			options += strlen(cp);
			forced_command = xmalloc(strlen(options) + 1);
			i = 0;
			while (*options) {
				if (*options == '"')
					break;
				if (*options == '\\' && options[1] == '"') {
					options += 2;
					forced_command[i++] = '"';
					continue;
				}
				forced_command[i++] = *options++;
			}
			if (!*options) {
				debug("%.100s, line %lu: missing end quote",
				    file, linenum);
				packet_send_debug("%.100s, line %lu: missing end quote",
				    file, linenum);
				continue;
			}
			forced_command[i] = 0;
			packet_send_debug("Forced command: %.900s", forced_command);
			options++;
			goto next_option;
		}
		cp = "environment=\"";
		if (strncasecmp(options, cp, strlen(cp)) == 0) {
			int i;
			char *s;
			struct envstring *new_envstring;
			options += strlen(cp);
			s = xmalloc(strlen(options) + 1);
			i = 0;
			while (*options) {
				if (*options == '"')
					break;
				if (*options == '\\' && options[1] == '"') {
					options += 2;
					s[i++] = '"';
					continue;
				}
				s[i++] = *options++;
			}
			if (!*options) {
				debug("%.100s, line %lu: missing end quote",
				    file, linenum);
				packet_send_debug("%.100s, line %lu: missing end quote",
				    file, linenum);
				continue;
			}
			s[i] = 0;
			packet_send_debug("Adding to environment: %.900s", s);
			debug("Adding to environment: %.900s", s);
			options++;
			new_envstring = xmalloc(sizeof(struct envstring));
			new_envstring->s = s;
			new_envstring->next = custom_environment;
			custom_environment = new_envstring;
			goto next_option;
		}
		cp = "from=\"";
		if (strncasecmp(options, cp, strlen(cp)) == 0) {
			int mname, mip;
			char *patterns = xmalloc(strlen(options) + 1);
			int i;
			options += strlen(cp);
			i = 0;
			while (*options) {
				if (*options == '"')
					break;
				if (*options == '\\' && options[1] == '"') {
					options += 2;
					patterns[i++] = '"';
					continue;
				}
				patterns[i++] = *options++;
			}
			if (!*options) {
				debug("%.100s, line %lu: missing end quote",
				    file, linenum);
				packet_send_debug("%.100s, line %lu: missing end quote",
				    file, linenum);
				continue;
			}
			patterns[i] = 0;
			options++;
			/*
			 * Deny access if we get a negative
			 * match for the hostname or the ip
			 * or if we get not match at all
			 */
			mname = match_hostname(get_canonical_hostname(),
			    patterns, strlen(patterns));
			mip = match_hostname(get_remote_ipaddr(),
			    patterns, strlen(patterns));
			xfree(patterns);
			if (mname == -1 || mip == -1 ||
			    (mname != 1 && mip != 1)) {
				log("Authentication tried for %.100s with correct key but not from a permitted host (host=%.200s, ip=%.200s).",
				    pw->pw_name, get_canonical_hostname(),
				    get_remote_ipaddr());
				packet_send_debug("Your host '%.200s' is not permitted to use this key for login.",
				get_canonical_hostname());
				/* deny access */
				return 0;
			}
			/* Host name matches. */
			goto next_option;
		}
next_option:
		/*
		 * Skip the comma, and move to the next option
		 * (or break out if there are no more).
		 */
		if (!*options)
			fatal("Bugs in auth-options.c option processing.");
		if (*options == ' ' || *options == '\t')
			break;		/* End of options. */
		if (*options != ',')
			goto bad_option;
		options++;
		/* Process the next option. */
	}
	/* grant access */
	return 1;

bad_option:
	log("Bad options in %.100s file, line %lu: %.50s",
	    file, linenum, options);
	packet_send_debug("Bad options in %.100s file, line %lu: %.50s",
	    file, linenum, options);
	/* deny access */
	return 0;
}
