/*
 * Dropbear - a SSH2 server
 * 
 * Copyright (c) 2002,2003 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 "packet.h"
#include "session.h"
#include "dbutil.h"
#include "ssh.h"
#include "algo.h"
#include "buffer.h"
#include "kex.h"
#include "dbrandom.h"
#include "service.h"
#include "auth.h"
#include "channel.h"
#include "netio.h"

static int read_packet_init(void);
static void make_mac(unsigned int seqno, const struct key_context_directional * key_state,
		buffer * clear_buf, unsigned int clear_len, 
		unsigned char *output_mac);
static int checkmac(void);

/* For exact details see http://www.zlib.net/zlib_tech.html
 * 5 bytes per 16kB block, plus 6 bytes for the stream.
 * We might allocate 5 unnecessary bytes here if it's an
 * exact multiple. */
#define ZLIB_COMPRESS_EXPANSION (((RECV_MAX_PAYLOAD_LEN/16384)+1)*5 + 6)
#define ZLIB_DECOMPRESS_INCR 1024
#ifndef DISABLE_ZLIB
static buffer* buf_decompress(buffer* buf, unsigned int len);
static void buf_compress(buffer * dest, buffer * src, unsigned int len);
#endif

/* non-blocking function writing out a current encrypted packet */
void write_packet() {

	ssize_t written;
#ifdef HAVE_WRITEV
	/* 50 is somewhat arbitrary */
	unsigned int iov_count = 50;
	struct iovec iov[50];
#else
	int len;
	buffer* writebuf;
	int packet_type;
#endif
	
	TRACE2(("enter write_packet"))
	dropbear_assert(!isempty(&ses.writequeue));

#if defined(HAVE_WRITEV) && (defined(IOV_MAX) || defined(UIO_MAXIOV))

	packet_queue_to_iovec(&ses.writequeue, iov, &iov_count);
	/* This may return EAGAIN. The main loop sometimes
	calls write_packet() without bothering to test with select() since
	it's likely to be necessary */
	written = writev(ses.sock_out, iov, iov_count);
	if (written < 0) {
		if (errno == EINTR || errno == EAGAIN) {
			TRACE2(("leave write_packet: EINTR"))
			return;
		} else {
			dropbear_exit("Error writing: %s", strerror(errno));
		}
	}

	packet_queue_consume(&ses.writequeue, written);
	ses.writequeue_len -= written;

	if (written == 0) {
		ses.remoteclosed();
	}

#else /* No writev () */
	/* Get the next buffer in the queue of encrypted packets to write*/
	writebuf = (buffer*)examine(&ses.writequeue);

	/* The last byte of the buffer is not to be transmitted, but is 
	 * a cleartext packet_type indicator */
	packet_type = writebuf->data[writebuf->len-1];
	len = writebuf->len - 1 - writebuf->pos;
	TRACE2(("write_packet type %d len %d/%d", packet_type,
			len, writebuf->len-1))
	dropbear_assert(len > 0);
	/* Try to write as much as possible */
	written = write(ses.sock_out, buf_getptr(writebuf, len), len);

	if (written < 0) {
		if (errno == EINTR || errno == EAGAIN) {
			TRACE2(("leave writepacket: EINTR"))
			return;
		} else {
			dropbear_exit("Error writing: %s", strerror(errno));
		}
	} 

	if (written == 0) {
		ses.remoteclosed();
	}

	ses.writequeue_len -= written;

	if (written == len) {
		/* We've finished with the packet, free it */
		dequeue(&ses.writequeue);
		buf_free(writebuf);
		writebuf = NULL;
	} else {
		/* More packet left to write, leave it in the queue for later */
		buf_incrpos(writebuf, written);
	}
#endif /* writev */

	TRACE2(("leave write_packet"))
}

/* Non-blocking function reading available portion of a packet into the
 * ses's buffer, decrypting the length if encrypted, decrypting the
 * full portion if possible */
void read_packet() {

	int len;
	unsigned int maxlen;
	unsigned char blocksize;

	TRACE2(("enter read_packet"))
	blocksize = ses.keys->recv.algo_crypt->blocksize;
	
	if (ses.readbuf == NULL || ses.readbuf->len < blocksize) {
		int ret;
		/* In the first blocksize of a packet */

		/* Read the first blocksize of the packet, so we can decrypt it and
		 * find the length of the whole packet */
		ret = read_packet_init();

		if (ret == DROPBEAR_FAILURE) {
			/* didn't read enough to determine the length */
			TRACE2(("leave read_packet: packetinit done"))
			return;
		}
	}

	/* Attempt to read the remainder of the packet, note that there
	 * mightn't be any available (EAGAIN) */
	maxlen = ses.readbuf->len - ses.readbuf->pos;
	if (maxlen == 0) {
		/* Occurs when the packet is only a single block long and has all
		 * been read in read_packet_init().  Usually means that MAC is disabled
		 */
		len = 0;
	} else {
		len = read(ses.sock_in, buf_getptr(ses.readbuf, maxlen), maxlen);

		if (len == 0) {
			ses.remoteclosed();
		}

		if (len < 0) {
			if (errno == EINTR || errno == EAGAIN) {
				TRACE2(("leave read_packet: EINTR or EAGAIN"))
				return;
			} else {
				dropbear_exit("Error reading: %s", strerror(errno));
			}
		}

		buf_incrpos(ses.readbuf, len);
	}

	if ((unsigned int)len == maxlen) {
		/* The whole packet has been read */
		decrypt_packet();
		/* The main select() loop process_packet() to
		 * handle the packet contents... */
	}
	TRACE2(("leave read_packet"))
}

/* Function used to read the initial portion of a packet, and determine the
 * length. Only called during the first BLOCKSIZE of a packet. */
/* Returns DROPBEAR_SUCCESS if the length is determined, 
 * DROPBEAR_FAILURE otherwise */
static int read_packet_init() {

	unsigned int maxlen;
	int slen;
	unsigned int len;
	unsigned int blocksize;
	unsigned int macsize;


	blocksize = ses.keys->recv.algo_crypt->blocksize;
	macsize = ses.keys->recv.algo_mac->hashsize;

	if (ses.readbuf == NULL) {
		/* start of a new packet */
		ses.readbuf = buf_new(INIT_READBUF);
	}

	maxlen = blocksize - ses.readbuf->pos;
			
	/* read the rest of the packet if possible */
	slen = read(ses.sock_in, buf_getwriteptr(ses.readbuf, maxlen),
			maxlen);
	if (slen == 0) {
		ses.remoteclosed();
	}
	if (slen < 0) {
		if (errno == EINTR || errno == EAGAIN) {
			TRACE2(("leave read_packet_init: EINTR"))
			return DROPBEAR_FAILURE;
		}
		dropbear_exit("Error reading: %s", strerror(errno));
	}

	buf_incrwritepos(ses.readbuf, slen);

	if ((unsigned int)slen != maxlen) {
		/* don't have enough bytes to determine length, get next time */
		return DROPBEAR_FAILURE;
	}

	/* now we have the first block, need to get packet length, so we decrypt
	 * the first block (only need first 4 bytes) */
	buf_setpos(ses.readbuf, 0);
	if (ses.keys->recv.crypt_mode->decrypt(buf_getptr(ses.readbuf, blocksize), 
				buf_getwriteptr(ses.readbuf, blocksize),
				blocksize,
				&ses.keys->recv.cipher_state) != CRYPT_OK) {
		dropbear_exit("Error decrypting");
	}
	len = buf_getint(ses.readbuf) + 4 + macsize;

	TRACE2(("packet size is %u, block %u mac %u", len, blocksize, macsize))


	/* check packet length */
	if ((len > RECV_MAX_PACKET_LEN) ||
		(len < MIN_PACKET_LEN + macsize) ||
		((len - macsize) % blocksize != 0)) {
		dropbear_exit("Integrity error (bad packet size %u)", len);
	}

	if (len > ses.readbuf->size) {
		ses.readbuf = buf_resize(ses.readbuf, len);		
	}
	buf_setlen(ses.readbuf, len);
	buf_setpos(ses.readbuf, blocksize);
	return DROPBEAR_SUCCESS;
}

/* handle the received packet */
void decrypt_packet() {

	unsigned char blocksize;
	unsigned char macsize;
	unsigned int padlen;
	unsigned int len;

	TRACE2(("enter decrypt_packet"))
	blocksize = ses.keys->recv.algo_crypt->blocksize;
	macsize = ses.keys->recv.algo_mac->hashsize;

	ses.kexstate.datarecv += ses.readbuf->len;

	/* we've already decrypted the first blocksize in read_packet_init */
	buf_setpos(ses.readbuf, blocksize);

	/* decrypt it in-place */
	len = ses.readbuf->len - macsize - ses.readbuf->pos;
	if (ses.keys->recv.crypt_mode->decrypt(
				buf_getptr(ses.readbuf, len), 
				buf_getwriteptr(ses.readbuf, len),
				len,
				&ses.keys->recv.cipher_state) != CRYPT_OK) {
		dropbear_exit("Error decrypting");
	}
	buf_incrpos(ses.readbuf, len);

	/* check the hmac */
	if (checkmac() != DROPBEAR_SUCCESS) {
		dropbear_exit("Integrity error");
	}

	/* get padding length */
	buf_setpos(ses.readbuf, PACKET_PADDING_OFF);
	padlen = buf_getbyte(ses.readbuf);
		
	/* payload length */
	/* - 4 - 1 is for LEN and PADLEN values */
	len = ses.readbuf->len - padlen - 4 - 1 - macsize;
	if ((len > RECV_MAX_PAYLOAD_LEN+ZLIB_COMPRESS_EXPANSION) || (len < 1)) {
		dropbear_exit("Bad packet size %u", len);
	}

	buf_setpos(ses.readbuf, PACKET_PAYLOAD_OFF);

#ifndef DISABLE_ZLIB
	if (is_compress_recv()) {
		/* decompress */
		ses.payload = buf_decompress(ses.readbuf, len);
		buf_setpos(ses.payload, 0);
		ses.payload_beginning = 0;
		buf_free(ses.readbuf);
	} else 
#endif
	{
		ses.payload = ses.readbuf;
		ses.payload_beginning = ses.payload->pos;
		buf_setlen(ses.payload, ses.payload->pos + len);
		/* copy payload */
		//ses.payload = buf_new(len);
		//memcpy(ses.payload->data, buf_getptr(ses.readbuf, len), len);
		//buf_incrlen(ses.payload, len);
	}
	ses.readbuf = NULL;

	ses.recvseq++;

	TRACE2(("leave decrypt_packet"))
}

/* Checks the mac at the end of a decrypted readbuf.
 * Returns DROPBEAR_SUCCESS or DROPBEAR_FAILURE */
static int checkmac() {

	unsigned char mac_bytes[MAX_MAC_LEN];
	unsigned int mac_size, contents_len;
	
	mac_size = ses.keys->recv.algo_mac->hashsize;
	contents_len = ses.readbuf->len - mac_size;

	buf_setpos(ses.readbuf, 0);
	make_mac(ses.recvseq, &ses.keys->recv, ses.readbuf, contents_len, mac_bytes);

	/* compare the hash */
	buf_setpos(ses.readbuf, contents_len);
	if (constant_time_memcmp(mac_bytes, buf_getptr(ses.readbuf, mac_size), mac_size) != 0) {
		return DROPBEAR_FAILURE;
	} else {
		return DROPBEAR_SUCCESS;
	}
}

#ifndef DISABLE_ZLIB
/* returns a pointer to a newly created buffer */
static buffer* buf_decompress(buffer* buf, unsigned int len) {

	int result;
	buffer * ret;
	z_streamp zstream;

	zstream = ses.keys->recv.zstream;
	ret = buf_new(len);

	zstream->avail_in = len;
	zstream->next_in = buf_getptr(buf, len);

	/* decompress the payload, incrementally resizing the output buffer */
	while (1) {

		zstream->avail_out = ret->size - ret->pos;
		zstream->next_out = buf_getwriteptr(ret, zstream->avail_out);

		result = inflate(zstream, Z_SYNC_FLUSH);

		buf_setlen(ret, ret->size - zstream->avail_out);
		buf_setpos(ret, ret->len);

		if (result != Z_BUF_ERROR && result != Z_OK) {
			dropbear_exit("zlib error");
		}

		if (zstream->avail_in == 0 &&
		   		(zstream->avail_out != 0 || result == Z_BUF_ERROR)) {
			/* we can only exit if avail_out hasn't all been used,
			 * and there's no remaining input */
			return ret;
		}

		if (zstream->avail_out == 0) {
			int new_size = 0;
			if (ret->size >= RECV_MAX_PAYLOAD_LEN) {
				/* Already been increased as large as it can go,
				 * yet didn't finish up the decompression */
				dropbear_exit("bad packet, oversized decompressed");
			}
			new_size = MIN(RECV_MAX_PAYLOAD_LEN, ret->size + ZLIB_DECOMPRESS_INCR);
			ret = buf_resize(ret, new_size);
		}
	}
}
#endif


/* returns 1 if the packet is a valid type during kex (see 7.1 of rfc4253) */
static int packet_is_okay_kex(unsigned char type) {
	if (type >= SSH_MSG_USERAUTH_REQUEST) {
		return 0;
	}
	if (type == SSH_MSG_SERVICE_REQUEST || type == SSH_MSG_SERVICE_ACCEPT) {
		return 0;
	}
	if (type == SSH_MSG_KEXINIT) {
		/* XXX should this die horribly if !dataallowed ?? */
		return 0;
	}
	return 1;
}

static void enqueue_reply_packet() {
	struct packetlist * new_item = NULL;
	new_item = m_malloc(sizeof(struct packetlist));
	new_item->next = NULL;
	
	new_item->payload = buf_newcopy(ses.writepayload);
	buf_setpos(ses.writepayload, 0);
	buf_setlen(ses.writepayload, 0);
	
	if (ses.reply_queue_tail) {
		ses.reply_queue_tail->next = new_item;
	} else {
		ses.reply_queue_head = new_item;
	}
	ses.reply_queue_tail = new_item;
}

void maybe_flush_reply_queue() {
	struct packetlist *tmp_item = NULL, *curr_item = NULL;
	if (!ses.dataallowed)
	{
		TRACE(("maybe_empty_reply_queue - no data allowed"))
		return;
	}
		
	for (curr_item = ses.reply_queue_head; curr_item; ) {
		CHECKCLEARTOWRITE();
		buf_putbytes(ses.writepayload,
			curr_item->payload->data, curr_item->payload->len);
			
		buf_free(curr_item->payload);
		tmp_item = curr_item;
		curr_item = curr_item->next;
		m_free(tmp_item);
		encrypt_packet();
	}
	ses.reply_queue_head = ses.reply_queue_tail = NULL;
}
	
/* encrypt the writepayload, putting into writebuf, ready for write_packet()
 * to put on the wire */
void encrypt_packet() {

	unsigned char padlen;
	unsigned char blocksize, mac_size;
	buffer * writebuf; /* the packet which will go on the wire. This is 
	                      encrypted in-place. */
	unsigned char packet_type;
	unsigned int len, encrypt_buf_size;
	unsigned char mac_bytes[MAX_MAC_LEN];

	time_t now;
	
	TRACE2(("enter encrypt_packet()"))

	buf_setpos(ses.writepayload, 0);
	packet_type = buf_getbyte(ses.writepayload);
	buf_setpos(ses.writepayload, 0);

	TRACE2(("encrypt_packet type is %d", packet_type))
	
	if ((!ses.dataallowed && !packet_is_okay_kex(packet_type))) {
		/* During key exchange only particular packets are allowed.
			Since this packet_type isn't OK we just enqueue it to send 
			after the KEX, see maybe_flush_reply_queue */
		enqueue_reply_packet();
		return;
	}
		
	blocksize = ses.keys->trans.algo_crypt->blocksize;
	mac_size = ses.keys->trans.algo_mac->hashsize;

	/* Encrypted packet len is payload+5. We need to then make sure
	 * there is enough space for padding or MIN_PACKET_LEN. 
	 * Add extra 3 since we need at least 4 bytes of padding */
	encrypt_buf_size = (ses.writepayload->len+4+1) 
		+ MAX(MIN_PACKET_LEN, blocksize) + 3
	/* add space for the MAC at the end */
				+ mac_size
#ifndef DISABLE_ZLIB
	/* some extra in case 'compression' makes it larger */
				+ ZLIB_COMPRESS_EXPANSION
#endif
	/* and an extra cleartext (stripped before transmission) byte for the
	 * packet type */
				+ 1;

	writebuf = buf_new(encrypt_buf_size);
	buf_setlen(writebuf, PACKET_PAYLOAD_OFF);
	buf_setpos(writebuf, PACKET_PAYLOAD_OFF);

#ifndef DISABLE_ZLIB
	/* compression */
	if (is_compress_trans()) {
		buf_compress(writebuf, ses.writepayload, ses.writepayload->len);
	} else
#endif
	{
		memcpy(buf_getwriteptr(writebuf, ses.writepayload->len),
				buf_getptr(ses.writepayload, ses.writepayload->len),
				ses.writepayload->len);
		buf_incrwritepos(writebuf, ses.writepayload->len);
	}

	/* finished with payload */
	buf_setpos(ses.writepayload, 0);
	buf_setlen(ses.writepayload, 0);

	/* length of padding - packet length must be a multiple of blocksize,
	 * with a minimum of 4 bytes of padding */
	padlen = blocksize - (writebuf->len) % blocksize;
	if (padlen < 4) {
		padlen += blocksize;
	}
	/* check for min packet length */
	if (writebuf->len + padlen < MIN_PACKET_LEN) {
		padlen += blocksize;
	}

	buf_setpos(writebuf, 0);
	/* packet length excluding the packetlength uint32 */
	buf_putint(writebuf, writebuf->len + padlen - 4);

	/* padding len */
	buf_putbyte(writebuf, padlen);
	/* actual padding */
	buf_setpos(writebuf, writebuf->len);
	buf_incrlen(writebuf, padlen);
	genrandom(buf_getptr(writebuf, padlen), padlen);

	make_mac(ses.transseq, &ses.keys->trans, writebuf, writebuf->len, mac_bytes);

	/* do the actual encryption, in-place */
	buf_setpos(writebuf, 0);
	/* encrypt it in-place*/
	len = writebuf->len;
	if (ses.keys->trans.crypt_mode->encrypt(
				buf_getptr(writebuf, len),
				buf_getwriteptr(writebuf, len),
				len,
				&ses.keys->trans.cipher_state) != CRYPT_OK) {
		dropbear_exit("Error encrypting");
	}
	buf_incrpos(writebuf, len);

	/* stick the MAC on it */
	buf_putbytes(writebuf, mac_bytes, mac_size);

	/* Update counts */
	ses.kexstate.datatrans += writebuf->len;

	writebuf_enqueue(writebuf, packet_type);

	/* Update counts */
	ses.transseq++;

	now = monotonic_now();
	ses.last_packet_time_any_sent = now;
	/* idle timeout shouldn't be affected by responses to keepalives.
	send_msg_keepalive() itself also does tricks with 
	ses.last_packet_idle_time - read that if modifying this code */
	if (packet_type != SSH_MSG_REQUEST_FAILURE
		&& packet_type != SSH_MSG_UNIMPLEMENTED
		&& packet_type != SSH_MSG_IGNORE) {
		ses.last_packet_time_idle = now;

	}

	TRACE2(("leave encrypt_packet()"))
}

void writebuf_enqueue(buffer * writebuf, unsigned char packet_type) {
	/* The last byte of the buffer stores the cleartext packet_type. It is not
	 * transmitted but is used for transmit timeout purposes */
	buf_putbyte(writebuf, packet_type);
	/* enqueue the packet for sending. It will get freed after transmission. */
	buf_setpos(writebuf, 0);
	enqueue(&ses.writequeue, (void*)writebuf);
	ses.writequeue_len += writebuf->len-1;
}


/* Create the packet mac, and append H(seqno|clearbuf) to the output */
/* output_mac must have ses.keys->trans.algo_mac->hashsize bytes. */
static void make_mac(unsigned int seqno, const struct key_context_directional * key_state,
		buffer * clear_buf, unsigned int clear_len, 
		unsigned char *output_mac) {
	unsigned char seqbuf[4];
	unsigned long bufsize;
	hmac_state hmac;

	if (key_state->algo_mac->hashsize > 0) {
		/* calculate the mac */
		if (hmac_init(&hmac, 
					key_state->hash_index,
					key_state->mackey,
					key_state->algo_mac->keysize) != CRYPT_OK) {
			dropbear_exit("HMAC error");
		}
	
		/* sequence number */
		STORE32H(seqno, seqbuf);
		if (hmac_process(&hmac, seqbuf, 4) != CRYPT_OK) {
			dropbear_exit("HMAC error");
		}
	
		/* the actual contents */
		buf_setpos(clear_buf, 0);
		if (hmac_process(&hmac, 
					buf_getptr(clear_buf, clear_len),
					clear_len) != CRYPT_OK) {
			dropbear_exit("HMAC error");
		}
	
		bufsize = MAX_MAC_LEN;
		if (hmac_done(&hmac, output_mac, &bufsize) != CRYPT_OK) {
			dropbear_exit("HMAC error");
		}
	}
	TRACE2(("leave writemac"))
}

#ifndef DISABLE_ZLIB
/* compresses len bytes from src, outputting to dest (starting from the
 * respective current positions. dest must have sufficient space,
 * len+ZLIB_COMPRESS_EXPANSION */
static void buf_compress(buffer * dest, buffer * src, unsigned int len) {

	unsigned int endpos = src->pos + len;
	int result;

	TRACE2(("enter buf_compress"))

	dropbear_assert(dest->size - dest->pos >= len+ZLIB_COMPRESS_EXPANSION);

	ses.keys->trans.zstream->avail_in = endpos - src->pos;
	ses.keys->trans.zstream->next_in = 
		buf_getptr(src, ses.keys->trans.zstream->avail_in);

	ses.keys->trans.zstream->avail_out = dest->size - dest->pos;
	ses.keys->trans.zstream->next_out =
		buf_getwriteptr(dest, ses.keys->trans.zstream->avail_out);

	result = deflate(ses.keys->trans.zstream, Z_SYNC_FLUSH);

	buf_setpos(src, endpos - ses.keys->trans.zstream->avail_in);
	buf_setlen(dest, dest->size - ses.keys->trans.zstream->avail_out);
	buf_setpos(dest, dest->len);

	if (result != Z_OK) {
		dropbear_exit("zlib error");
	}

	/* fails if destination buffer wasn't large enough */
	dropbear_assert(ses.keys->trans.zstream->avail_in == 0);
	TRACE2(("leave buf_compress"))
}
#endif
