/*
 * Dropbear - a SSH2 server
 * 
 * Copyright (c) 2008 Frederic Moulins
 * All rights reserved.
 * 
 * Permission is hereby granted, free of charge, to any person obtaining a copy
 * of this software and associated documentation files (the "Software"), to deal
 * in the Software without restriction, including without limitation the rights
 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
 * copies of the Software, and to permit persons to whom the Software is
 * furnished to do so, subject to the following conditions:
 * 
 * The above copyright notice and this permission notice shall be included in
 * all copies or substantial portions of the Software.
 * 
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
 * SOFTWARE. 
 *
 * This file incorporates work covered by the following copyright and  
 * permission notice:
 *
 * 	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".
 *
 * This copyright and permission notice applies to the code parsing public keys
 * options string which can also be found in OpenSSH auth-options.c file 
 * (auth_parse_options).
 *
 */

/* Process pubkey options during a pubkey auth request */
#include "includes.h"
#include "session.h"
#include "dbutil.h"
#include "signkey.h"
#include "auth.h"

#if DROPBEAR_SVR_PUBKEY_OPTIONS_BUILT

/* Returns 1 if pubkey allows agent forwarding,
 * 0 otherwise */
int svr_pubkey_allows_agentfwd() {
	if (ses.authstate.pubkey_options 
		&& ses.authstate.pubkey_options->no_agent_forwarding_flag) {
		return 0;
	}
	return 1;
}

/* Returns 1 if pubkey allows tcp forwarding,
 * 0 otherwise */
int svr_pubkey_allows_tcpfwd() {
	if (ses.authstate.pubkey_options 
		&& ses.authstate.pubkey_options->no_port_forwarding_flag) {
		return 0;
	}
	return 1;
}

/* Returns 1 if pubkey allows x11 forwarding,
 * 0 otherwise */
int svr_pubkey_allows_x11fwd() {
	if (ses.authstate.pubkey_options 
		&& ses.authstate.pubkey_options->no_x11_forwarding_flag) {
		return 0;
	}
	return 1;
}

/* Returns 1 if pubkey allows pty, 0 otherwise */
int svr_pubkey_allows_pty() {
	if (ses.authstate.pubkey_options 
		&& ses.authstate.pubkey_options->no_pty_flag) {
		return 0;
	}
	return 1;
}

/* Set chansession command to the one forced 
 * by any 'command' public key option. */
void svr_pubkey_set_forced_command(struct ChanSess *chansess) {
	if (ses.authstate.pubkey_options && ses.authstate.pubkey_options->forced_command) {
		if (chansess->cmd) {
			/* original_command takes ownership */
			chansess->original_command = chansess->cmd;
		} else {
			chansess->original_command = m_strdup("");
		}
		chansess->cmd = m_strdup(ses.authstate.pubkey_options->forced_command);
#ifdef LOG_COMMANDS
		dropbear_log(LOG_INFO, "Command forced to '%s'", chansess->original_command);
#endif
	}
}

/* Free potential public key options */
void svr_pubkey_options_cleanup() {
	if (ses.authstate.pubkey_options) {
		m_free(ses.authstate.pubkey_options);
		ses.authstate.pubkey_options = NULL;
	}
}

/* helper for svr_add_pubkey_options. returns DROPBEAR_SUCCESS if the option is matched,
   and increments the options_buf */
static int match_option(buffer *options_buf, const char *opt_name) {
	const unsigned int len = strlen(opt_name);
	if (options_buf->len - options_buf->pos < len) {
		return DROPBEAR_FAILURE;
	}
	if (strncasecmp((const char *) buf_getptr(options_buf, len), opt_name, len) == 0) {
		buf_incrpos(options_buf, len);
		return DROPBEAR_SUCCESS;
	}
	return DROPBEAR_FAILURE;
}

/* Parse pubkey options and set ses.authstate.pubkey_options accordingly.
 * Returns DROPBEAR_SUCCESS if key is ok for auth, DROPBEAR_FAILURE otherwise */
int svr_add_pubkey_options(buffer *options_buf, int line_num, const char* filename) {
	int ret = DROPBEAR_FAILURE;

	TRACE(("enter addpubkeyoptions"))

	ses.authstate.pubkey_options = (struct PubKeyOptions*)m_malloc(sizeof( struct PubKeyOptions ));

	buf_setpos(options_buf, 0);
	while (options_buf->pos < options_buf->len) {
		if (match_option(options_buf, "no-port-forwarding") == DROPBEAR_SUCCESS) {
			dropbear_log(LOG_WARNING, "Port forwarding disabled.");
			ses.authstate.pubkey_options->no_port_forwarding_flag = 1;
			goto next_option;
		}
#if DROPBEAR_SVR_AGENTFWD
		if (match_option(options_buf, "no-agent-forwarding") == DROPBEAR_SUCCESS) {
			dropbear_log(LOG_WARNING, "Agent forwarding disabled.");
			ses.authstate.pubkey_options->no_agent_forwarding_flag = 1;
			goto next_option;
		}
#endif
#if DROPBEAR_X11FWD
		if (match_option(options_buf, "no-X11-forwarding") == DROPBEAR_SUCCESS) {
			dropbear_log(LOG_WARNING, "X11 forwarding disabled.");
			ses.authstate.pubkey_options->no_x11_forwarding_flag = 1;
			goto next_option;
		}
#endif
		if (match_option(options_buf, "no-pty") == DROPBEAR_SUCCESS) {
			dropbear_log(LOG_WARNING, "Pty allocation disabled.");
			ses.authstate.pubkey_options->no_pty_flag = 1;
			goto next_option;
		}
		if (match_option(options_buf, "command=\"") == DROPBEAR_SUCCESS) {
			int escaped = 0;
			const unsigned char* command_start = buf_getptr(options_buf, 0);
			while (options_buf->pos < options_buf->len) {
				const char c = buf_getbyte(options_buf);
				if (!escaped && c == '"') {
					const int command_len = buf_getptr(options_buf, 0) - command_start;
					ses.authstate.pubkey_options->forced_command = m_malloc(command_len);
					memcpy(ses.authstate.pubkey_options->forced_command,
							command_start, command_len-1);
					ses.authstate.pubkey_options->forced_command[command_len-1] = '\0';
					dropbear_log(LOG_WARNING, "Forced command '%s'", 
						ses.authstate.pubkey_options->forced_command);
					goto next_option;
				}
				escaped = (!escaped && c == '\\');
			}
			dropbear_log(LOG_WARNING, "Badly formatted command= authorized_keys option");
			goto bad_option;
		}

next_option:
		/*
		 * Skip the comma, and move to the next option
		 * (or break out if there are no more).
		 */
		if (options_buf->pos < options_buf->len 
				&& buf_getbyte(options_buf) != ',') {
			goto bad_option;
		}
		/* Process the next option. */
	}
	/* parsed all options with no problem */
	ret = DROPBEAR_SUCCESS;
	goto end;

bad_option:
	ret = DROPBEAR_FAILURE;
	m_free(ses.authstate.pubkey_options);
	ses.authstate.pubkey_options = NULL;
	dropbear_log(LOG_WARNING, "Bad public key options at %s:%d", filename, line_num);

end:
	TRACE(("leave addpubkeyoptions"))
	return ret;
}

#endif
