From 4404126501ba18184a8e04f815c21e7a9184414a Mon Sep 17 00:00:00 2001
From: Matt Johnston <matt@ucc.asn.au>
Date: Sun, 14 Apr 2013 22:49:10 +0800
Subject: [PATCH] -y -y to disable hostkey checking fix missing trailing space
 when passing arguments for multihop mode From Hans Harder

---
 cli-kex.c     |  5 +++++
 cli-runopts.c | 31 +++++++++++++++++++++++++++----
 dbclient.1    |  3 ++-
 runopts.h     |  1 +
 4 files changed, 35 insertions(+), 5 deletions(-)

diff --git a/cli-kex.c b/cli-kex.c
index 0d5a9d2c..c47faae9 100644
--- a/cli-kex.c
+++ b/cli-kex.c
@@ -217,6 +217,11 @@ static void checkhostkey(unsigned char* keyblob, unsigned int keybloblen) {
 	buffer * line = NULL;
 	int ret;
 
+	if (cli_opts.no_hostkey_check) {
+		fprintf(stderr, "Caution, skipping hostkey check for %s\n", cli_opts.remotehost);
+		return;
+	}
+
 	hostsfile = open_known_hosts_file(&readonly);
 	if (!hostsfile)	{
 		ask_to_confirm(keyblob, keybloblen);
diff --git a/cli-runopts.c b/cli-runopts.c
index 5ddcc214..d95dad5b 100644
--- a/cli-runopts.c
+++ b/cli-runopts.c
@@ -62,6 +62,7 @@ static void printhelp() {
 					"-N    Don't run a remote command\n"
 					"-f    Run in background after auth\n"
 					"-y    Always accept remote host key if unknown\n"
+					"-y -y Don't perform any remote host key checking (caution)\n"
 					"-s    Request a subsystem (use by external sftp)\n"
 #ifdef ENABLE_CLI_PUBKEY_AUTH
 					"-i <identityfile>   (multiple allowed)\n"
@@ -130,6 +131,7 @@ void cli_getopts(int argc, char ** argv) {
 	cli_opts.backgrounded = 0;
 	cli_opts.wantpty = 9; /* 9 means "it hasn't been touched", gets set later */
 	cli_opts.always_accept_key = 0;
+	cli_opts.no_hostkey_check = 0;
 	cli_opts.is_subsystem = 0;
 #ifdef ENABLE_CLI_PUBKEY_AUTH
 	cli_opts.privkeys = list_new();
@@ -213,6 +215,10 @@ void cli_getopts(int argc, char ** argv) {
 
 			switch (argv[i][1]) {
 				case 'y': /* always accept the remote hostkey */
+					if (cli_opts.always_accept_key) {
+						// twice means no checking at all
+						cli_opts.no_hostkey_check = 1;
+					}
 					cli_opts.always_accept_key = 1;
 					break;
 				case 'p': /* remoteport */
@@ -461,20 +467,31 @@ multihop_passthrough_args() {
 	int total;
 	unsigned int len = 0;
 	m_list_elem *iter;
-	/* Fill out -i and -W options that make sense for all
+	/* Fill out -i, -y, -W options that make sense for all
 	 * the intermediate processes */
 	for (iter = cli_opts.privkeys->first; iter; iter = iter->next)
 	{
 		sign_key * key = (sign_key*)iter->item;
 		len += 3 + strlen(key->filename);
 	}
-	len += 20; // space for -W <size>, terminator.
+	len += 30; // space for -W <size>, terminator.
 	ret = m_malloc(len);
 	total = 0;
 
+	if (cli_opts.no_hostkey_check)
+	{
+		int written = snprintf(ret+total, len-total, "-y -y ");
+		total += written;
+	}
+	else if (cli_opts.always_accept_key)
+	{
+		int written = snprintf(ret+total, len-total, "-y ");
+		total += written;
+	}
+
 	if (opts.recv_window != DEFAULT_RECV_WINDOW)
 	{
-		int written = snprintf(ret+total, len-total, "-W %d", opts.recv_window);
+		int written = snprintf(ret+total, len-total, "-W %d ", opts.recv_window);
 		total += written;
 	}
 
@@ -482,11 +499,17 @@ multihop_passthrough_args() {
 	{
 		sign_key * key = (sign_key*)iter->item;
 		const size_t size = len - total;
-		int written = snprintf(ret+total, size, "-i %s", key->filename);
+		int written = snprintf(ret+total, size, "-i %s ", key->filename);
 		dropbear_assert((unsigned int)written < size);
 		total += written;
 	}
 
+	/* if args where passed, total will be not zero, and it will have a space at the end, so remove that */
+	if (total > 0) 
+	{
+		total--;
+	}
+
 	return ret;
 }
 
diff --git a/dbclient.1 b/dbclient.1
index 69af18a1..29d8cd86 100644
--- a/dbclient.1
+++ b/dbclient.1
@@ -80,7 +80,8 @@ by the ssh server.
 .TP
 .B \-y
 Always accept hostkeys if they are unknown. If a hostkey mismatch occurs the
-connection will abort as normal.
+connection will abort as normal. If specified a second time no host key checking
+is performed at all, this is usually undesirable.
 .TP
 .B \-A
 Forward agent connections to the remote host. dbclient will use any
diff --git a/runopts.h b/runopts.h
index 9cd84d07..0dc30884 100644
--- a/runopts.h
+++ b/runopts.h
@@ -121,6 +121,7 @@ typedef struct cli_runopts {
 	char *cmd;
 	int wantpty;
 	int always_accept_key;
+	int no_hostkey_check;
 	int no_cmd;
 	int backgrounded;
 	int is_subsystem;
-- 
GitLab