/* $OpenBSD: roaming_client.c,v 1.3 2010/01/18 01:50:27 dtucker Exp $ */
/*
 * Copyright (c) 2004-2009 AppGate Network Security AB
 *
 * Permission to use, copy, modify, and distribute this software for any
 * purpose with or without fee is hereby granted, provided that the above
 * copyright notice and this permission notice appear in all copies.
 *
 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
 */

#include "includes.h"

#include "openbsd-compat/sys-queue.h"
#include <sys/types.h>
#include <sys/socket.h>

#ifdef HAVE_INTTYPES_H
#include <inttypes.h>
#endif
#include <signal.h>
#include <string.h>
#include <unistd.h>

#include <openssl/crypto.h>
#include <openssl/sha.h>

#include "xmalloc.h"
#include "buffer.h"
#include "channels.h"
#include "cipher.h"
#include "dispatch.h"
#include "clientloop.h"
#include "log.h"
#include "match.h"
#include "misc.h"
#include "packet.h"
#include "ssh.h"
#include "key.h"
#include "kex.h"
#include "readconf.h"
#include "roaming.h"
#include "ssh2.h"
#include "sshconnect.h"

/* import */
extern Options options;
extern char *host;
extern struct sockaddr_storage hostaddr;
extern int session_resumed;

static u_int32_t roaming_id;
static u_int64_t cookie;
static u_int64_t lastseenchall;
static u_int64_t key1, key2, oldkey1, oldkey2;

void
roaming_reply(int type, u_int32_t seq, void *ctxt)
{
	if (type == SSH2_MSG_REQUEST_FAILURE) {
		logit("Server denied roaming");
		return;
	}
	verbose("Roaming enabled");
	roaming_id = packet_get_int();
	cookie = packet_get_int64();
	key1 = oldkey1 = packet_get_int64();
	key2 = oldkey2 = packet_get_int64();
	set_out_buffer_size(packet_get_int() +  get_snd_buf_size());
	roaming_enabled = 1;
}

void
request_roaming(void)
{
	packet_start(SSH2_MSG_GLOBAL_REQUEST);
	packet_put_cstring(ROAMING_REQUEST);
	packet_put_char(1);
	packet_put_int(get_recv_buf_size());
	packet_send();
	client_register_global_confirm(roaming_reply, NULL);
}

static void
roaming_auth_required(void)
{
	u_char digest[SHA_DIGEST_LENGTH];
	EVP_MD_CTX md;
	Buffer b;
	const EVP_MD *evp_md = EVP_sha1();
	u_int64_t chall, oldchall;

	chall = packet_get_int64();
	oldchall = packet_get_int64();
	if (oldchall != lastseenchall) {
		key1 = oldkey1;
		key2 = oldkey2;
	}
	lastseenchall = chall;

	buffer_init(&b);
	buffer_put_int64(&b, cookie);
	buffer_put_int64(&b, chall);
	EVP_DigestInit(&md, evp_md);
	EVP_DigestUpdate(&md, buffer_ptr(&b), buffer_len(&b));
	EVP_DigestFinal(&md, digest, NULL);
	buffer_free(&b);

	packet_start(SSH2_MSG_KEX_ROAMING_AUTH);
	packet_put_int64(key1 ^ get_recv_bytes());
	packet_put_raw(digest, sizeof(digest));
	packet_send();

	oldkey1 = key1;
	oldkey2 = key2;
	calculate_new_key(&key1, cookie, chall);
	calculate_new_key(&key2, cookie, chall);

	debug("Received %llu bytes", (unsigned long long)get_recv_bytes());
	debug("Sent roaming_auth packet");
}

int
resume_kex(void)
{
	/*
	 * This should not happen - if the client sends the kex method
	 * resume@appgate.com then the kex is done in roaming_resume().
	 */
	return 1;
}

static int
roaming_resume(void)
{
	u_int64_t recv_bytes;
	char *str = NULL, *kexlist = NULL, *c;
	int i, type;
	int timeout_ms = options.connection_timeout * 1000;
	u_int len;
	u_int32_t rnd = 0;

	resume_in_progress = 1;

	/* Exchange banners */
	ssh_exchange_identification(timeout_ms);
	packet_set_nonblocking();

	/* Send a kexinit message with resume@appgate.com as only kex algo */
	packet_start(SSH2_MSG_KEXINIT);
	for (i = 0; i < KEX_COOKIE_LEN; i++) {
		if (i % 4 == 0)
			rnd = arc4random();
		packet_put_char(rnd & 0xff);
		rnd >>= 8;
	}
	packet_put_cstring(KEX_RESUME);
	for (i = 1; i < PROPOSAL_MAX; i++) {
		/* kex algorithm added so start with i=1 and not 0 */
		packet_put_cstring(""); /* Not used when we resume */
	}
	packet_put_char(1); /* first kex_packet follows */
	packet_put_int(0); /* reserved */
	packet_send();

	/* Assume that resume@appgate.com will be accepted */
	packet_start(SSH2_MSG_KEX_ROAMING_RESUME);
	packet_put_int(roaming_id);
	packet_send();

	/* Read the server's kexinit and check for resume@appgate.com */
	if ((type = packet_read()) != SSH2_MSG_KEXINIT) {
		debug("expected kexinit on resume, got %d", type);
		goto fail;
	}
	for (i = 0; i < KEX_COOKIE_LEN; i++)
		(void)packet_get_char();
	kexlist = packet_get_string(&len);
	if (!kexlist
	    || (str = match_list(KEX_RESUME, kexlist, NULL)) == NULL) {
		debug("server doesn't allow resume");
		goto fail;
	}
	xfree(str);
	for (i = 1; i < PROPOSAL_MAX; i++) {
		/* kex algorithm taken care of so start with i=1 and not 0 */
		xfree(packet_get_string(&len));
	}
	i = packet_get_char(); /* first_kex_packet_follows */
	if (i && (c = strchr(kexlist, ',')))
		*c = 0;
	if (i && strcmp(kexlist, KEX_RESUME)) {
		debug("server's kex guess (%s) was wrong, skipping", kexlist);
		(void)packet_read(); /* Wrong guess - discard packet */
	}

	/*
	 * Read the ROAMING_AUTH_REQUIRED challenge from the server and
	 * send ROAMING_AUTH
	 */
	if ((type = packet_read()) != SSH2_MSG_KEX_ROAMING_AUTH_REQUIRED) {
		debug("expected roaming_auth_required, got %d", type);
		goto fail;
	}
	roaming_auth_required();

	/* Read ROAMING_AUTH_OK from the server */
	if ((type = packet_read()) != SSH2_MSG_KEX_ROAMING_AUTH_OK) {
		debug("expected roaming_auth_ok, got %d", type);
		goto fail;
	}
	recv_bytes = packet_get_int64() ^ oldkey2;
	debug("Peer received %llu bytes", (unsigned long long)recv_bytes);
	resend_bytes(packet_get_connection_out(), &recv_bytes);

	resume_in_progress = 0;

	session_resumed = 1; /* Tell clientloop */

	return 0;

fail:
	if (kexlist)
		xfree(kexlist);
	if (packet_get_connection_in() == packet_get_connection_out())
		close(packet_get_connection_in());
	else {
		close(packet_get_connection_in());
		close(packet_get_connection_out());
	}
	return 1;
}

int
wait_for_roaming_reconnect(void)
{
	static int reenter_guard = 0;
	int timeout_ms = options.connection_timeout * 1000;
	int c;

	if (reenter_guard != 0)
		fatal("Server refused resume, roaming timeout may be exceeded");
	reenter_guard = 1;

	fprintf(stderr, "[connection suspended, press return to resume]");
	fflush(stderr);
	packet_backup_state();
	/* TODO Perhaps we should read from tty here */
	while ((c = fgetc(stdin)) != EOF) {
		if (c == 'Z' - 64) {
			kill(getpid(), SIGTSTP);
			continue;
		}
		if (c != '\n' && c != '\r')
			continue;

		if (ssh_connect(host, &hostaddr, options.port,
		    options.address_family, 1, &timeout_ms,
		    options.tcp_keep_alive, options.use_privileged_port,
		    options.proxy_command) == 0 && roaming_resume() == 0) {
			packet_restore_state();
			reenter_guard = 0;
			fprintf(stderr, "[connection resumed]\n");
			fflush(stderr);
			return 0;
		}

		fprintf(stderr, "[reconnect failed, press return to retry]");
		fflush(stderr);
	}
	fprintf(stderr, "[exiting]\n");
	fflush(stderr);
	exit(0);
}
