/*
 * Dropbear - a SSH2 server
 * 
 * Copyright (c) Matt Johnston
 * 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 "session.h"
#include "dbutil.h"
#include "packet.h"
#include "algo.h"
#include "buffer.h"
#include "dss.h"
#include "ssh.h"
#include "dbrandom.h"
#include "kex.h"
#include "channel.h"
#include "runopts.h"
#include "netio.h"

static void checktimeouts();
static long select_timeout();
static int ident_readln(int fd, char* buf, int count);
static void read_session_identification();

struct sshsession ses; /* GLOBAL */

/* need to know if the session struct has been initialised, this way isn't the
 * cleanest, but works OK */
int sessinitdone = 0; /* GLOBAL */

/* this is set when we get SIGINT or SIGTERM, the handler is in main.c */
int exitflag = 0; /* GLOBAL */

/* called only at the start of a session, set up initial state */
void common_session_init(int sock_in, int sock_out) {
	time_t now;

#ifdef DEBUG_TRACE
	debug_start_net();
#endif

	TRACE(("enter session_init"))

	ses.sock_in = sock_in;
	ses.sock_out = sock_out;
	ses.maxfd = MAX(sock_in, sock_out);

	if (sock_in >= 0) {
		setnonblocking(sock_in);
	}
	if (sock_out >= 0) {
		setnonblocking(sock_out);
	}

	ses.socket_prio = DROPBEAR_PRIO_DEFAULT;
	/* Sets it to lowdelay */
	update_channel_prio();

	now = monotonic_now();
	ses.connect_time = now;
	ses.last_packet_time_keepalive_recv = now;
	ses.last_packet_time_idle = now;
	ses.last_packet_time_any_sent = 0;
	ses.last_packet_time_keepalive_sent = 0;
	
	if (pipe(ses.signal_pipe) < 0) {
		dropbear_exit("Signal pipe failed");
	}
	setnonblocking(ses.signal_pipe[0]);
	setnonblocking(ses.signal_pipe[1]);

	ses.maxfd = MAX(ses.maxfd, ses.signal_pipe[0]);
	ses.maxfd = MAX(ses.maxfd, ses.signal_pipe[1]);
	
	ses.writepayload = buf_new(TRANS_MAX_PAYLOAD_LEN);
	ses.transseq = 0;

	ses.readbuf = NULL;
	ses.payload = NULL;
	ses.recvseq = 0;

	initqueue(&ses.writequeue);

	ses.requirenext = SSH_MSG_KEXINIT;
	ses.dataallowed = 1; /* we can send data until we actually 
							send the SSH_MSG_KEXINIT */
	ses.ignorenext = 0;
	ses.lastpacket = 0;
	ses.reply_queue_head = NULL;
	ses.reply_queue_tail = NULL;

	/* set all the algos to none */
	ses.keys = (struct key_context*)m_malloc(sizeof(struct key_context));
	ses.newkeys = NULL;
	ses.keys->recv.algo_crypt = &dropbear_nocipher;
	ses.keys->trans.algo_crypt = &dropbear_nocipher;
	ses.keys->recv.crypt_mode = &dropbear_mode_none;
	ses.keys->trans.crypt_mode = &dropbear_mode_none;
	
	ses.keys->recv.algo_mac = &dropbear_nohash;
	ses.keys->trans.algo_mac = &dropbear_nohash;

	ses.keys->algo_kex = NULL;
	ses.keys->algo_hostkey = -1;
	ses.keys->recv.algo_comp = DROPBEAR_COMP_NONE;
	ses.keys->trans.algo_comp = DROPBEAR_COMP_NONE;

#ifndef DISABLE_ZLIB
	ses.keys->recv.zstream = NULL;
	ses.keys->trans.zstream = NULL;
#endif

	/* key exchange buffers */
	ses.session_id = NULL;
	ses.kexhashbuf = NULL;
	ses.transkexinit = NULL;
	ses.dh_K = NULL;
	ses.remoteident = NULL;

	ses.chantypes = NULL;

	ses.allowprivport = 0;

	TRACE(("leave session_init"))
}

void session_loop(void(*loophandler)()) {

	fd_set readfd, writefd;
	struct timeval timeout;
	int val;

	/* main loop, select()s for all sockets in use */
	for(;;) {
		const int writequeue_has_space = (ses.writequeue_len <= 2*TRANS_MAX_PAYLOAD_LEN);

		timeout.tv_sec = select_timeout();
		timeout.tv_usec = 0;
		FD_ZERO(&writefd);
		FD_ZERO(&readfd);
		dropbear_assert(ses.payload == NULL);

		/* We get woken up when signal handlers write to this pipe.
		   SIGCHLD in svr-chansession is the only one currently. */
		FD_SET(ses.signal_pipe[0], &readfd);
		ses.channel_signal_pending = 0;

		/* set up for channels which can be read/written */
		setchannelfds(&readfd, &writefd, writequeue_has_space);

		/* Pending connections to test */
		set_connect_fds(&writefd);

		/* We delay reading from the input socket during initial setup until
		after we have written out our initial KEXINIT packet (empty writequeue). 
		This means our initial packet can be in-flight while we're doing a blocking
		read for the remote ident.
		We also avoid reading from the socket if the writequeue is full, that avoids
		replies backing up */
		if (ses.sock_in != -1 
			&& (ses.remoteident || isempty(&ses.writequeue)) 
			&& writequeue_has_space) {
			FD_SET(ses.sock_in, &readfd);
		}

		/* Ordering is important, this test must occur after any other function
		might have queued packets (such as connection handlers) */
		if (ses.sock_out != -1 && !isempty(&ses.writequeue)) {
			FD_SET(ses.sock_out, &writefd);
		}

		val = select(ses.maxfd+1, &readfd, &writefd, NULL, &timeout);

		if (exitflag) {
			dropbear_exit("Terminated by signal");
		}
		
		if (val < 0 && errno != EINTR) {
			dropbear_exit("Error in select");
		}

		if (val <= 0) {
			/* If we were interrupted or the select timed out, we still
			 * want to iterate over channels etc for reading, to handle
			 * server processes exiting etc. 
			 * We don't want to read/write FDs. */
			FD_ZERO(&writefd);
			FD_ZERO(&readfd);
		}
		
		/* We'll just empty out the pipe if required. We don't do
		any thing with the data, since the pipe's purpose is purely to
		wake up the select() above. */
		if (FD_ISSET(ses.signal_pipe[0], &readfd)) {
			char x;
			TRACE(("signal pipe set"))
			while (read(ses.signal_pipe[0], &x, 1) > 0) {}
			ses.channel_signal_pending = 1;
		}

		/* check for auth timeout, rekeying required etc */
		checktimeouts();

		/* process session socket's incoming data */
		if (ses.sock_in != -1) {
			if (FD_ISSET(ses.sock_in, &readfd)) {
				if (!ses.remoteident) {
					/* blocking read of the version string */
					read_session_identification();
				} else {
					read_packet();
				}
			}
			
			/* Process the decrypted packet. After this, the read buffer
			 * will be ready for a new packet */
			if (ses.payload != NULL) {
				process_packet();
			}
		}

		/* if required, flush out any queued reply packets that
		were being held up during a KEX */
		maybe_flush_reply_queue();

		handle_connect_fds(&writefd);

		/* process pipes etc for the channels, ses.dataallowed == 0
		 * during rekeying ) */
		channelio(&readfd, &writefd);

		/* process session socket's outgoing data */
		if (ses.sock_out != -1) {
			if (!isempty(&ses.writequeue)) {
				write_packet();
			}
		}


		if (loophandler) {
			loophandler();
		}

	} /* for(;;) */
	
	/* Not reached */
}

static void cleanup_buf(buffer **buf) {
	if (!*buf) {
		return;
	}
	buf_burn(*buf);
	buf_free(*buf);
	*buf = NULL;
}

/* clean up a session on exit */
void session_cleanup() {
	
	TRACE(("enter session_cleanup"))
	
	/* we can't cleanup if we don't know the session state */
	if (!sessinitdone) {
		TRACE(("leave session_cleanup: !sessinitdone"))
		return;
	}

	/* BEWARE of changing order of functions here. */

	/* Must be before extra_session_cleanup() */
	chancleanup();

	if (ses.extra_session_cleanup) {
		ses.extra_session_cleanup();
	}

	/* After these are freed most functions will fail */
#ifdef DROPBEAR_CLEANUP
	/* listeners call cleanup functions, this should occur before
	other session state is freed. */
	remove_all_listeners();

	remove_connect_pending();

	while (!isempty(&ses.writequeue)) {
		buf_free(dequeue(&ses.writequeue));
	}

	m_free(ses.remoteident);
	m_free(ses.authstate.pw_dir);
	m_free(ses.authstate.pw_name);
	m_free(ses.authstate.pw_shell);
	m_free(ses.authstate.pw_passwd);
	m_free(ses.authstate.username);
#endif

	cleanup_buf(&ses.session_id);
	cleanup_buf(&ses.hash);
	cleanup_buf(&ses.payload);
	cleanup_buf(&ses.readbuf);
	cleanup_buf(&ses.writepayload);
	cleanup_buf(&ses.kexhashbuf);
	cleanup_buf(&ses.transkexinit);
	if (ses.dh_K) {
		mp_clear(ses.dh_K);
	}
	m_free(ses.dh_K);

	m_burn(ses.keys, sizeof(struct key_context));
	m_free(ses.keys);

	TRACE(("leave session_cleanup"))
}

void send_session_identification() {
	buffer *writebuf = buf_new(strlen(LOCAL_IDENT "\r\n") + 1);
	buf_putbytes(writebuf, (const unsigned char *) LOCAL_IDENT "\r\n", strlen(LOCAL_IDENT "\r\n"));
	writebuf_enqueue(writebuf, 0);
}

static void read_session_identification() {
	/* max length of 255 chars */
	char linebuf[256];
	int len = 0;
	char done = 0;
	int i;
	/* If they send more than 50 lines, something is wrong */
	for (i = 0; i < 50; i++) {
		len = ident_readln(ses.sock_in, linebuf, sizeof(linebuf));

		if (len < 0 && errno != EINTR) {
			/* It failed */
			break;
		}

		if (len >= 4 && memcmp(linebuf, "SSH-", 4) == 0) {
			/* start of line matches */
			done = 1;
			break;
		}
	}

	if (!done) {
		TRACE(("err: %s for '%s'\n", strerror(errno), linebuf))
		ses.remoteclosed();
	} else {
		/* linebuf is already null terminated */
		ses.remoteident = m_malloc(len);
		memcpy(ses.remoteident, linebuf, len);
	}

	/* Shall assume that 2.x will be backwards compatible. */
	if (strncmp(ses.remoteident, "SSH-2.", 6) != 0
			&& strncmp(ses.remoteident, "SSH-1.99-", 9) != 0) {
		dropbear_exit("Incompatible remote version '%s'", ses.remoteident);
	}

	TRACE(("remoteident: %s", ses.remoteident))

}

/* returns the length including null-terminating zero on success,
 * or -1 on failure */
static int ident_readln(int fd, char* buf, int count) {
	
	char in;
	int pos = 0;
	int num = 0;
	fd_set fds;
	struct timeval timeout;

	TRACE(("enter ident_readln"))

	if (count < 1) {
		return -1;
	}

	FD_ZERO(&fds);

	/* select since it's a non-blocking fd */
	
	/* leave space to null-terminate */
	while (pos < count-1) {

		FD_SET(fd, &fds);

		timeout.tv_sec = 1;
		timeout.tv_usec = 0;
		if (select(fd+1, &fds, NULL, NULL, &timeout) < 0) {
			if (errno == EINTR) {
				continue;
			}
			TRACE(("leave ident_readln: select error"))
			return -1;
		}

		checktimeouts();
		
		/* Have to go one byte at a time, since we don't want to read past
		 * the end, and have to somehow shove bytes back into the normal
		 * packet reader */
		if (FD_ISSET(fd, &fds)) {
			num = read(fd, &in, 1);
			/* a "\n" is a newline, "\r" we want to read in and keep going
			 * so that it won't be read as part of the next line */
			if (num < 0) {
				/* error */
				if (errno == EINTR) {
					continue; /* not a real error */
				}
				TRACE(("leave ident_readln: read error"))
				return -1;
			}
			if (num == 0) {
				/* EOF */
				TRACE(("leave ident_readln: EOF"))
				return -1;
			}
			if (in == '\n') {
				/* end of ident string */
				break;
			}
			/* we don't want to include '\r's */
			if (in != '\r') {
				buf[pos] = in;
				pos++;
			}
		}
	}

	buf[pos] = '\0';
	TRACE(("leave ident_readln: return %d", pos+1))
	return pos+1;
}

void ignore_recv_response() {
	/* Do nothing */
	TRACE(("Ignored msg_request_response"))
}

static void send_msg_keepalive() {
	time_t old_time_idle = ses.last_packet_time_idle;
	struct Channel *chan = get_any_ready_channel();

	CHECKCLEARTOWRITE();

	if (chan) {
		/* Channel requests are preferable, more implementations
		handle them than SSH_MSG_GLOBAL_REQUEST */
		TRACE(("keepalive channel request %d", chan->index))
		start_send_channel_request(chan, DROPBEAR_KEEPALIVE_STRING);
	} else {
		TRACE(("keepalive global request"))
		/* Some peers will reply with SSH_MSG_REQUEST_FAILURE, 
		some will reply with SSH_MSG_UNIMPLEMENTED, some will exit. */
		buf_putbyte(ses.writepayload, SSH_MSG_GLOBAL_REQUEST); 
		buf_putstring(ses.writepayload, DROPBEAR_KEEPALIVE_STRING,
			strlen(DROPBEAR_KEEPALIVE_STRING));
	}
	buf_putbyte(ses.writepayload, 1); /* want_reply */
	encrypt_packet();

	ses.last_packet_time_keepalive_sent = monotonic_now();

	/* keepalives shouldn't update idle timeout, reset it back */
	ses.last_packet_time_idle = old_time_idle;
}

/* Check all timeouts which are required. Currently these are the time for
 * user authentication, and the automatic rekeying. */
static void checktimeouts() {

	time_t now;
	now = monotonic_now();
	
	if (IS_DROPBEAR_SERVER && ses.connect_time != 0
		&& now - ses.connect_time >= AUTH_TIMEOUT) {
			dropbear_close("Timeout before auth");
	}

	/* we can't rekey if we haven't done remote ident exchange yet */
	if (ses.remoteident == NULL) {
		return;
	}

	if (!ses.kexstate.sentkexinit
			&& (now - ses.kexstate.lastkextime >= KEX_REKEY_TIMEOUT
			|| ses.kexstate.datarecv+ses.kexstate.datatrans >= KEX_REKEY_DATA)) {
		TRACE(("rekeying after timeout or max data reached"))
		send_msg_kexinit();
	}
	
	if (opts.keepalive_secs > 0 && ses.authstate.authdone) {
		/* Avoid sending keepalives prior to auth - those are
		not valid pre-auth packet types */

		/* Send keepalives if we've been idle */
		if (now - ses.last_packet_time_any_sent >= opts.keepalive_secs) {
			send_msg_keepalive();
		}

		/* Also send an explicit keepalive message to trigger a response
		if the remote end hasn't sent us anything */
		if (now - ses.last_packet_time_keepalive_recv >= opts.keepalive_secs
			&& now - ses.last_packet_time_keepalive_sent >= opts.keepalive_secs) {
			send_msg_keepalive();
		}

		if (now - ses.last_packet_time_keepalive_recv 
			>= opts.keepalive_secs * DEFAULT_KEEPALIVE_LIMIT) {
			dropbear_exit("Keepalive timeout");
		}
	}

	if (opts.idle_timeout_secs > 0 
			&& now - ses.last_packet_time_idle >= opts.idle_timeout_secs) {
		dropbear_close("Idle timeout");
	}
}

static void update_timeout(long limit, long now, long last_event, long * timeout) {
	TRACE2(("update_timeout limit %ld, now %ld, last %ld, timeout %ld",
		limit, now, last_event, *timeout))
	if (last_event > 0 && limit > 0) {
		*timeout = MIN(*timeout, last_event+limit-now);
		TRACE2(("new timeout %ld", *timeout))
	}
}

static long select_timeout() {
	/* determine the minimum timeout that might be required, so
	as to avoid waking when unneccessary */
	long timeout = LONG_MAX;
	long now = monotonic_now();

	update_timeout(KEX_REKEY_TIMEOUT, now, ses.kexstate.lastkextime, &timeout);

	if (ses.authstate.authdone != 1 && IS_DROPBEAR_SERVER) {
		/* AUTH_TIMEOUT is only relevant before authdone */
		update_timeout(AUTH_TIMEOUT, now, ses.connect_time, &timeout);
	}

	if (ses.authstate.authdone) {
		update_timeout(opts.keepalive_secs, now, 
			MAX(ses.last_packet_time_keepalive_recv, ses.last_packet_time_keepalive_sent),
			&timeout);
	}

	update_timeout(opts.idle_timeout_secs, now, ses.last_packet_time_idle,
		&timeout);

	/* clamp negative timeouts to zero - event has already triggered */
	return MAX(timeout, 0);
}

const char* get_user_shell() {
	/* an empty shell should be interpreted as "/bin/sh" */
	if (ses.authstate.pw_shell[0] == '\0') {
		return "/bin/sh";
	} else {
		return ses.authstate.pw_shell;
	}
}
void fill_passwd(const char* username) {
	struct passwd *pw = NULL;
	if (ses.authstate.pw_name)
		m_free(ses.authstate.pw_name);
	if (ses.authstate.pw_dir)
		m_free(ses.authstate.pw_dir);
	if (ses.authstate.pw_shell)
		m_free(ses.authstate.pw_shell);
	if (ses.authstate.pw_passwd)
		m_free(ses.authstate.pw_passwd);

	pw = getpwnam(username);
	if (!pw) {
		return;
	}
	ses.authstate.pw_uid = pw->pw_uid;
	ses.authstate.pw_gid = pw->pw_gid;
	ses.authstate.pw_name = m_strdup(pw->pw_name);
	ses.authstate.pw_dir = m_strdup(pw->pw_dir);
	ses.authstate.pw_shell = m_strdup(pw->pw_shell);
	{
		char *passwd_crypt = pw->pw_passwd;
#ifdef HAVE_SHADOW_H
		/* get the shadow password if possible */
		struct spwd *spasswd = getspnam(ses.authstate.pw_name);
		if (spasswd && spasswd->sp_pwdp) {
			passwd_crypt = spasswd->sp_pwdp;
		}
#endif
		if (!passwd_crypt) {
			/* android supposedly returns NULL */
			passwd_crypt = "!!";
		}
		ses.authstate.pw_passwd = m_strdup(passwd_crypt);
	}
}

/* Called when channels are modified */
void update_channel_prio() {
	enum dropbear_prio new_prio;
	int any = 0;
	unsigned int i;

	TRACE(("update_channel_prio"))

	if (ses.sock_out < 0) {
		TRACE(("leave update_channel_prio: no socket"))
		return;
	}

	new_prio = DROPBEAR_PRIO_BULK;
	for (i = 0; i < ses.chansize; i++) {
		struct Channel *channel = ses.channels[i];
		if (!channel || channel->prio == DROPBEAR_CHANNEL_PRIO_EARLY) {
			if (channel && channel->prio == DROPBEAR_CHANNEL_PRIO_EARLY) {
				TRACE(("update_channel_prio: early %d", channel->index))
			}
			continue;
		}
		any = 1;
		if (channel->prio == DROPBEAR_CHANNEL_PRIO_INTERACTIVE)
		{
			TRACE(("update_channel_prio: lowdelay %d", channel->index))
			new_prio = DROPBEAR_PRIO_LOWDELAY;
			break;
		} else if (channel->prio == DROPBEAR_CHANNEL_PRIO_UNKNOWABLE
			&& new_prio == DROPBEAR_PRIO_BULK)
		{
			TRACE(("update_channel_prio: unknowable %d", channel->index))
			new_prio = DROPBEAR_PRIO_DEFAULT;
		}
	}

	if (any == 0) {
		/* lowdelay during setup */
		TRACE(("update_channel_prio: not any"))
		new_prio = DROPBEAR_PRIO_LOWDELAY;
	}

	if (new_prio != ses.socket_prio) {
		TRACE(("Dropbear priority transitioning %d -> %d", ses.socket_prio, new_prio))
		set_sock_priority(ses.sock_out, new_prio);
		ses.socket_prio = new_prio;
	}
}

