/*
 * Dropbear SSH
 * 
 * Copyright (c) 2002,2003 Matt Johnston
 * Copyright (c) 2004 by Mihnea Stoenescu
 * 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. */

#include "includes.h"
#include "packet.h"
#include "buffer.h"
#include "session.h"
#include "dbutil.h"
#include "channel.h"
#include "ssh.h"
#include "runopts.h"
#include "termcodes.h"
#include "chansession.h"
#include "agentfwd.h"

static void cli_closechansess(struct Channel *channel);
static int cli_initchansess(struct Channel *channel);
static void cli_chansessreq(struct Channel *channel);

static void send_chansess_pty_req(struct Channel *channel);
static void send_chansess_shell_req(struct Channel *channel);

static void cli_tty_setup();

const struct ChanType clichansess = {
	0, /* sepfds */
	"session", /* name */
	cli_initchansess, /* inithandler */
	NULL, /* checkclosehandler */
	cli_chansessreq, /* reqhandler */
	cli_closechansess, /* closehandler */
};

static void cli_chansessreq(struct Channel *channel) {

	unsigned char* type = NULL;
	int wantreply;

	TRACE(("enter cli_chansessreq"))

	type = buf_getstring(ses.payload, NULL);
	wantreply = buf_getbool(ses.payload);

	if (strcmp(type, "exit-status") == 0) {
		cli_ses.retval = buf_getint(ses.payload);
		TRACE(("got exit-status of '%d'", cli_ses.retval))
	} else if (strcmp(type, "exit-signal") == 0) {
		TRACE(("got exit-signal, ignoring it"))
	} else {
		TRACE(("unknown request '%s'", type))
		send_msg_channel_failure(channel);
		goto out;
	}
		
out:
	m_free(type);
}
	

/* If the main session goes, we close it up */
static void cli_closechansess(struct Channel *UNUSED(channel)) {

	/* This channel hasn't gone yet, so we have > 1 */
	if (ses.chancount > 1) {
		dropbear_log(LOG_INFO, "Waiting for other channels to close...");
	}

	cli_tty_cleanup(); /* Restore tty modes etc */

}

void cli_start_send_channel_request(struct Channel *channel, 
		unsigned char *type) {

	CHECKCLEARTOWRITE();
	buf_putbyte(ses.writepayload, SSH_MSG_CHANNEL_REQUEST);
	buf_putint(ses.writepayload, channel->remotechan);

	buf_putstring(ses.writepayload, type, strlen(type));

}

/* Taken from OpenSSH's sshtty.c:
 * RCSID("OpenBSD: sshtty.c,v 1.5 2003/09/19 17:43:35 markus Exp "); */
static void cli_tty_setup() {

	struct termios tio;

	TRACE(("enter cli_pty_setup"))

	if (cli_ses.tty_raw_mode == 1) {
		TRACE(("leave cli_tty_setup: already in raw mode!"))
		return;
	}

	if (tcgetattr(STDIN_FILENO, &tio) == -1) {
		dropbear_exit("Failed to set raw TTY mode");
	}

	/* make a copy */
	cli_ses.saved_tio = tio;

	tio.c_iflag |= IGNPAR;
	tio.c_iflag &= ~(ISTRIP | INLCR | IGNCR | ICRNL | IXON | IXANY | IXOFF);
#ifdef IUCLC
	tio.c_iflag &= ~IUCLC;
#endif
	tio.c_lflag &= ~(ISIG | ICANON | ECHO | ECHOE | ECHOK | ECHONL);
#ifdef IEXTEN
	tio.c_lflag &= ~IEXTEN;
#endif
	tio.c_oflag &= ~OPOST;
	tio.c_cc[VMIN] = 1;
	tio.c_cc[VTIME] = 0;
	if (tcsetattr(STDIN_FILENO, TCSADRAIN, &tio) == -1) {
		dropbear_exit("Failed to set raw TTY mode");
	}

	cli_ses.tty_raw_mode = 1;
	TRACE(("leave cli_tty_setup"))
}

void cli_tty_cleanup() {

	TRACE(("enter cli_tty_cleanup"))

	if (cli_ses.tty_raw_mode == 0) {
		TRACE(("leave cli_tty_cleanup: not in raw mode"))
		return;
	}

	if (tcsetattr(STDIN_FILENO, TCSADRAIN, &cli_ses.saved_tio) == -1) {
		dropbear_log(LOG_WARNING, "Failed restoring TTY");
	} else {
		cli_ses.tty_raw_mode = 0; 
	}

	TRACE(("leave cli_tty_cleanup"))
}

static void put_termcodes() {

	struct termios tio;
	unsigned int sshcode;
	const struct TermCode *termcode;
	unsigned int value;
	unsigned int mapcode;

	unsigned int bufpos1, bufpos2;

	TRACE(("enter put_termcodes"))

	if (tcgetattr(STDIN_FILENO, &tio) == -1) {
		dropbear_log(LOG_WARNING, "Failed reading termmodes");
		buf_putint(ses.writepayload, 1); /* Just the terminator */
		buf_putbyte(ses.writepayload, 0); /* TTY_OP_END */
		return;
	}

	bufpos1 = ses.writepayload->pos;
	buf_putint(ses.writepayload, 0); /* A placeholder for the final length */

	/* As with Dropbear server, we ignore baud rates for now */
	for (sshcode = 1; sshcode < MAX_TERMCODE; sshcode++) {

		termcode = &termcodes[sshcode];
		mapcode = termcode->mapcode;

		switch (termcode->type) {

			case TERMCODE_NONE:
				continue;

			case TERMCODE_CONTROLCHAR:
				value = tio.c_cc[mapcode];
				break;

			case TERMCODE_INPUT:
				value = tio.c_iflag & mapcode;
				break;

			case TERMCODE_OUTPUT:
				value = tio.c_oflag & mapcode;
				break;

			case TERMCODE_LOCAL:
				value = tio.c_lflag & mapcode;
				break;

			case TERMCODE_CONTROL:
				value = tio.c_cflag & mapcode;
				break;

			default:
				continue;

		}

		/* If we reach here, we have something to say */
		buf_putbyte(ses.writepayload, sshcode);
		buf_putint(ses.writepayload, value);
	}

	buf_putbyte(ses.writepayload, 0); /* THE END, aka TTY_OP_END */

	/* Put the string length at the start of the buffer */
	bufpos2 = ses.writepayload->pos;

	buf_setpos(ses.writepayload, bufpos1); /* Jump back */
	buf_putint(ses.writepayload, bufpos2 - bufpos1 - 4); /* len(termcodes) */
	buf_setpos(ses.writepayload, bufpos2); /* Back where we were */

	TRACE(("leave put_termcodes"))
}

static void put_winsize() {

	struct winsize ws;

	if (ioctl(STDIN_FILENO, TIOCGWINSZ, &ws) < 0) {
		/* Some sane defaults */
		ws.ws_row = 25;
		ws.ws_col = 80;
		ws.ws_xpixel = 0;
		ws.ws_ypixel = 0;
	}

	buf_putint(ses.writepayload, ws.ws_col); /* Cols */
	buf_putint(ses.writepayload, ws.ws_row); /* Rows */
	buf_putint(ses.writepayload, ws.ws_xpixel); /* Width */
	buf_putint(ses.writepayload, ws.ws_ypixel); /* Height */

}

static void sigwinch_handler(int UNUSED(unused)) {

	cli_ses.winchange = 1;

}

void cli_chansess_winchange() {

	unsigned int i;
	struct Channel *channel = NULL;

	for (i = 0; i < ses.chansize; i++) {
		channel = ses.channels[i];
		if (channel != NULL && channel->type == &clichansess) {
			CHECKCLEARTOWRITE();
			buf_putbyte(ses.writepayload, SSH_MSG_CHANNEL_REQUEST);
			buf_putint(ses.writepayload, channel->remotechan);
			buf_putstring(ses.writepayload, "window-change", 13);
			buf_putbyte(ses.writepayload, 0); /* FALSE says the spec */
			put_winsize();
			encrypt_packet();
		}
	}
	cli_ses.winchange = 0;
}

static void send_chansess_pty_req(struct Channel *channel) {

	unsigned char* term = NULL;

	TRACE(("enter send_chansess_pty_req"))

	cli_start_send_channel_request(channel, "pty-req");

	/* Don't want replies */
	buf_putbyte(ses.writepayload, 0);

	/* Get the terminal */
	term = getenv("TERM");
	if (term == NULL) {
		term = "vt100"; /* Seems a safe default */
	}
	buf_putstring(ses.writepayload, term, strlen(term));

	/* Window size */
	put_winsize();

	/* Terminal mode encoding */
	put_termcodes();

	encrypt_packet();

	/* Set up a window-change handler */
	if (signal(SIGWINCH, sigwinch_handler) == SIG_ERR) {
		dropbear_exit("Signal error");
	}
	TRACE(("leave send_chansess_pty_req"))
}

static void send_chansess_shell_req(struct Channel *channel) {

	unsigned char* reqtype = NULL;

	TRACE(("enter send_chansess_shell_req"))

	if (cli_opts.cmd) {
		if (cli_opts.is_subsystem) {
			reqtype = "subsystem";
		} else {
			reqtype = "exec";
		}
	} else {
		reqtype = "shell";
	}

	cli_start_send_channel_request(channel, reqtype);

	/* XXX TODO */
	buf_putbyte(ses.writepayload, 0); /* Don't want replies */
	if (cli_opts.cmd) {
		buf_putstring(ses.writepayload, cli_opts.cmd, strlen(cli_opts.cmd));
	}

	encrypt_packet();
	TRACE(("leave send_chansess_shell_req"))
}

/* Shared for normal client channel and netcat-alike */
static int cli_init_stdpipe_sess(struct Channel *channel) {
	channel->writefd = STDOUT_FILENO;
	setnonblocking(STDOUT_FILENO);

	channel->readfd = STDIN_FILENO;
	setnonblocking(STDIN_FILENO);

	channel->errfd = STDERR_FILENO;
	setnonblocking(STDERR_FILENO);

	channel->extrabuf = cbuf_new(opts.recv_window);
	return 0;
}

static int cli_initchansess(struct Channel *channel) {

	cli_init_stdpipe_sess(channel);

#ifdef ENABLE_CLI_AGENTFWD
	if (cli_opts.agent_fwd) {
		cli_setup_agent(channel);
	}
#endif

	if (cli_opts.wantpty) {
		send_chansess_pty_req(channel);
	}

	send_chansess_shell_req(channel);

	if (cli_opts.wantpty) {
		cli_tty_setup();
	}

	return 0; /* Success */
}

#ifdef ENABLE_CLI_NETCAT

static const struct ChanType cli_chan_netcat = {
	0, /* sepfds */
	"direct-tcpip",
	cli_init_stdpipe_sess, /* inithandler */
	NULL,
	NULL,
	cli_closechansess
};

void cli_send_netcat_request() {

	const unsigned char* source_host = "127.0.0.1";
	const int source_port = 22;

	cli_opts.wantpty = 0;

	if (send_msg_channel_open_init(STDIN_FILENO, &cli_chan_netcat) 
			== DROPBEAR_FAILURE) {
		dropbear_exit("Couldn't open initial channel");
	}

	buf_putstring(ses.writepayload, cli_opts.netcat_host, 
			strlen(cli_opts.netcat_host));
	buf_putint(ses.writepayload, cli_opts.netcat_port);

	/* originator ip - localhost is accurate enough */
	buf_putstring(ses.writepayload, source_host, strlen(source_host));
	buf_putint(ses.writepayload, source_port);

	encrypt_packet();
	TRACE(("leave cli_send_chansess_request"))
}
#endif

void cli_send_chansess_request() {

	TRACE(("enter cli_send_chansess_request"))

	if (send_msg_channel_open_init(STDIN_FILENO, &clichansess) 
			== DROPBEAR_FAILURE) {
		dropbear_exit("Couldn't open initial channel");
	}

	/* No special channel request data */
	encrypt_packet();
	TRACE(("leave cli_send_chansess_request"))

}
