changeset 743:09c5eb71ec96 kexguess

merge from head roundtrip changes
author Matt Johnston <matt@ucc.asn.au>
date Mon, 01 Apr 2013 00:13:41 +0800
parents cd201dc2da9a (current diff) 9a5438271556 (diff)
children 504f33c684b5
files Makefile.in cli-kex.c cli-service.c cli-session.c debug.h session.h
diffstat 23 files changed, 157 insertions(+), 163 deletions(-) [+]
line wrap: on
line diff
--- a/Makefile.in	Sun Mar 31 00:41:15 2013 +0800
+++ b/Makefile.in	Mon Apr 01 00:13:41 2013 +0800
@@ -34,7 +34,7 @@
 		svr-tcpfwd.o svr-authpam.o
 
 CLIOBJS=cli-main.o cli-auth.o cli-authpasswd.o cli-kex.o \
-		cli-session.o cli-service.o cli-runopts.o cli-chansession.o \
+		cli-session.o cli-runopts.o cli-chansession.o \
 		cli-authpubkey.o cli-tcpfwd.o cli-channel.o cli-authinteract.o \
 		cli-agentfwd.o list.o
 
--- a/buffer.c	Sun Mar 31 00:41:15 2013 +0800
+++ b/buffer.c	Mon Apr 01 00:13:41 2013 +0800
@@ -282,7 +282,7 @@
 void buf_putmpint(buffer* buf, mp_int * mp) {
 
 	unsigned int len, pad = 0;
-	TRACE(("enter buf_putmpint"))
+	TRACE2(("enter buf_putmpint"))
 
 	dropbear_assert(mp != NULL);
 
@@ -318,7 +318,7 @@
 		buf_incrwritepos(buf, len-pad);
 	}
 
-	TRACE(("leave buf_putmpint"))
+	TRACE2(("leave buf_putmpint"))
 }
 
 /* Retrieve an mp_int from the buffer.
--- a/cli-auth.c	Sun Mar 31 00:41:15 2013 +0800
+++ b/cli-auth.c	Mon Apr 01 00:13:41 2013 +0800
@@ -40,11 +40,12 @@
 
 /* Send a "none" auth request to get available methods */
 void cli_auth_getmethods() {
-
 	TRACE(("enter cli_auth_getmethods"))
-
+#ifdef CLI_IMMEDIATE_AUTH
+	ses.authstate.authtypes = AUTH_TYPE_PUBKEY | AUTH_TYPE_PASSWORD | AUTH_TYPE_INTERACT;
+	cli_auth_try();
+#else
 	CHECKCLEARTOWRITE();
-
 	buf_putbyte(ses.writepayload, SSH_MSG_USERAUTH_REQUEST);
 	buf_putstring(ses.writepayload, cli_opts.username, 
 			strlen(cli_opts.username));
@@ -53,8 +54,8 @@
 	buf_putstring(ses.writepayload, "none", 4); /* 'none' method */
 
 	encrypt_packet();
+#endif
 	TRACE(("leave cli_auth_getmethods"))
-
 }
 
 void recv_msg_userauth_banner() {
--- a/cli-kex.c	Sun Mar 31 00:41:15 2013 +0800
+++ b/cli-kex.c	Mon Apr 01 00:13:41 2013 +0800
@@ -247,7 +247,7 @@
 		/* Compare hostnames */
 		if (strncmp(cli_opts.remotehost, buf_getptr(line, hostlen),
 					hostlen) != 0) {
-			TRACE(("hosts don't match"))
+			TRACE2(("hosts don't match"))
 			continue;
 		}
 
--- a/cli-service.c	Sun Mar 31 00:41:15 2013 +0800
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,85 +0,0 @@
-/*
- * 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 "service.h"
-#include "dbutil.h"
-#include "packet.h"
-#include "buffer.h"
-#include "session.h"
-#include "ssh.h"
-
-void send_msg_service_request(char* servicename) {
-
-	TRACE(("enter send_msg_service_request: servicename='%s'", servicename))
-
-	CHECKCLEARTOWRITE();
-
-	buf_putbyte(ses.writepayload, SSH_MSG_SERVICE_REQUEST);
-	buf_putstring(ses.writepayload, servicename, strlen(servicename));
-
-	encrypt_packet();
-	TRACE(("leave send_msg_service_request"))
-}
-
-/* This just sets up the state variables right for the main client session loop
- * to deal with */
-void recv_msg_service_accept() {
-
-	unsigned char* servicename;
-	unsigned int len;
-
-	TRACE(("enter recv_msg_service_accept"))
-
-	servicename = buf_getstring(ses.payload, &len);
-
-	/* ssh-userauth */
-	if (cli_ses.state == SERVICE_AUTH_REQ_SENT
-			&& len == SSH_SERVICE_USERAUTH_LEN
-			&& strncmp(SSH_SERVICE_USERAUTH, servicename, len) == 0) {
-
-		cli_ses.state = SERVICE_AUTH_ACCEPT_RCVD;
-		m_free(servicename);
-		TRACE(("leave recv_msg_service_accept: done ssh-userauth"))
-		return;
-	}
-
-	/* ssh-connection */
-	if (cli_ses.state == SERVICE_CONN_REQ_SENT
-			&& len == SSH_SERVICE_CONNECTION_LEN 
-			&& strncmp(SSH_SERVICE_CONNECTION, servicename, len) == 0) {
-
-		if (ses.authstate.authdone != 1) {
-			dropbear_exit("Request for connection before auth");
-		}
-
-		cli_ses.state = SERVICE_CONN_ACCEPT_RCVD;
-		m_free(servicename);
-		TRACE(("leave recv_msg_service_accept: done ssh-connection"))
-		return;
-	}
-
-	dropbear_exit("Unrecognised service accept");
-}
--- a/cli-session.c	Sun Mar 31 00:41:15 2013 +0800
+++ b/cli-session.c	Mon Apr 01 00:13:41 2013 +0800
@@ -41,6 +41,7 @@
 static void cli_sessionloop();
 static void cli_session_init();
 static void cli_finished();
+static void recv_msg_service_accept(void);
 
 struct clientsession cli_ses; /* GLOBAL */
 
@@ -158,11 +159,28 @@
 
 }
 
+static void send_msg_service_request(char* servicename) {
+
+	TRACE(("enter send_msg_service_request: servicename='%s'", servicename))
+
+	CHECKCLEARTOWRITE();
+
+	buf_putbyte(ses.writepayload, SSH_MSG_SERVICE_REQUEST);
+	buf_putstring(ses.writepayload, servicename, strlen(servicename));
+
+	encrypt_packet();
+	TRACE(("leave send_msg_service_request"))
+}
+
+static void recv_msg_service_accept(void) {
+	// do nothing, if it failed then the server MUST have disconnected
+}
+
 /* This function drives the progress of the session - it initiates KEX,
  * service, userauth and channel requests */
 static void cli_sessionloop() {
 
-	TRACE(("enter cli_sessionloop"))
+	TRACE2(("enter cli_sessionloop"))
 
 	if (ses.lastpacket == SSH_MSG_KEXINIT && cli_ses.kex_state == KEX_NOTHING) {
 		/* We initiate the KEXDH. If DH wasn't the correct type, the KEXINIT
@@ -201,12 +219,6 @@
 			/* We've got the transport layer sorted, we now need to request
 			 * userauth */
 			send_msg_service_request(SSH_SERVICE_USERAUTH);
-			cli_ses.state = SERVICE_AUTH_REQ_SENT;
-			TRACE(("leave cli_sessionloop: sent userauth service req"))
-			return;
-
-		/* userauth code */
-		case SERVICE_AUTH_ACCEPT_RCVD:
 			cli_auth_getmethods();
 			cli_ses.state = USERAUTH_REQ_SENT;
 			TRACE(("leave cli_sessionloop: sent userauth methods req"))
@@ -280,7 +292,7 @@
 		break;
 	}
 
-	TRACE(("leave cli_sessionloop: fell out"))
+	TRACE2(("leave cli_sessionloop: fell out"))
 
 }
 
--- a/common-channel.c	Sun Mar 31 00:41:15 2013 +0800
+++ b/common-channel.c	Mon Apr 01 00:13:41 2013 +0800
@@ -273,10 +273,10 @@
 static void check_close(struct Channel *channel) {
 	int close_allowed = 0;
 
-	TRACE(("check_close: writefd %d, readfd %d, errfd %d, sent_close %d, recv_close %d",
+	TRACE2(("check_close: writefd %d, readfd %d, errfd %d, sent_close %d, recv_close %d",
 				channel->writefd, channel->readfd,
 				channel->errfd, channel->sent_close, channel->recv_close))
-	TRACE(("writebuf size %d extrabuf size %d",
+	TRACE2(("writebuf size %d extrabuf size %d",
 				channel->writebuf ? cbuf_getused(channel->writebuf) : 0,
 				channel->extrabuf ? cbuf_getused(channel->extrabuf) : 0))
 
--- a/configure.ac	Sun Mar 31 00:41:15 2013 +0800
+++ b/configure.ac	Mon Apr 01 00:13:41 2013 +0800
@@ -211,7 +211,7 @@
 # Checks for header files.
 AC_HEADER_STDC
 AC_HEADER_SYS_WAIT
-AC_CHECK_HEADERS([fcntl.h limits.h netinet/in.h netinet/tcp.h stdlib.h string.h sys/socket.h sys/time.h termios.h unistd.h crypt.h pty.h ioctl.h libutil.h libgen.h inttypes.h stropts.h utmp.h utmpx.h lastlog.h paths.h util.h netdb.h security/pam_appl.h pam/pam_appl.h netinet/in_systm.h])
+AC_CHECK_HEADERS([fcntl.h limits.h netinet/in.h netinet/tcp.h stdlib.h string.h sys/socket.h sys/time.h termios.h unistd.h crypt.h pty.h ioctl.h libutil.h libgen.h inttypes.h stropts.h utmp.h utmpx.h lastlog.h paths.h util.h netdb.h security/pam_appl.h pam/pam_appl.h netinet/in_systm.h, sys/uio.h])
 
 # Checks for typedefs, structures, and compiler characteristics.
 AC_C_CONST
@@ -616,7 +616,7 @@
 AC_FUNC_MEMCMP
 AC_FUNC_SELECT_ARGTYPES
 AC_TYPE_SIGNAL
-AC_CHECK_FUNCS([dup2 getspnam getusershell memset putenv select socket strdup clearenv strlcpy strlcat daemon basename _getpty getaddrinfo freeaddrinfo getnameinfo fork])
+AC_CHECK_FUNCS([dup2 getspnam getusershell memset putenv select socket strdup clearenv strlcpy strlcat daemon basename _getpty getaddrinfo freeaddrinfo getnameinfo fork writev])
 
 AC_SEARCH_LIBS(basename, gen, AC_DEFINE(HAVE_BASENAME))
 
--- a/dbutil.c	Sun Mar 31 00:41:15 2013 +0800
+++ b/dbutil.c	Mon Apr 01 00:13:41 2013 +0800
@@ -151,6 +151,20 @@
 	fprintf(stderr, "\n");
 	va_end(param);
 }
+void dropbear_trace2(const char* format, ...) {
+
+	va_list param;
+
+	if (!(debug_trace && getenv("DROPBEAR_TRACE2"))) {
+		return;
+	}
+
+	va_start(param, format);
+	fprintf(stderr, "TRACE2 (%d): ", getpid());
+	vfprintf(stderr, format, param);
+	fprintf(stderr, "\n");
+	va_end(param);
+}
 #endif /* DEBUG_TRACE */
 
 static void set_sock_priority(int sock) {
@@ -725,7 +739,7 @@
 
 	int c = EOF;
 
-	TRACE(("enter buf_getline"))
+	TRACE2(("enter buf_getline"))
 
 	buf_setpos(line, 0);
 	buf_setlen(line, 0);
@@ -750,10 +764,10 @@
 
 	/* if we didn't read anything before EOF or error, exit */
 	if (c == EOF && line->pos == 0) {
-		TRACE(("leave buf_getline: failure"))
+		TRACE2(("leave buf_getline: failure"))
 		return DROPBEAR_FAILURE;
 	} else {
-		TRACE(("leave buf_getline: success"))
+		TRACE2(("leave buf_getline: success"))
 		buf_setpos(line, 0);
 		return DROPBEAR_SUCCESS;
 	}
--- a/dbutil.h	Sun Mar 31 00:41:15 2013 +0800
+++ b/dbutil.h	Mon Apr 01 00:13:41 2013 +0800
@@ -57,6 +57,7 @@
 
 #ifdef DEBUG_TRACE
 void dropbear_trace(const char* format, ...) ATTRIB_PRINTF(1,2);
+void dropbear_trace2(const char* format, ...) ATTRIB_PRINTF(1,2);
 void printhex(const char * label, const unsigned char * buf, int len);
 extern int debug_trace;
 #endif
--- a/debug.h	Sun Mar 31 00:41:15 2013 +0800
+++ b/debug.h	Mon Apr 01 00:13:41 2013 +0800
@@ -39,7 +39,7 @@
  * Caution: Don't use this in an unfriendly environment (ie unfirewalled),
  * since the printing may not sanitise strings etc. This will add a reasonable
  * amount to your executable size. */
-#define DEBUG_TRACE
+/* #define DEBUG_TRACE */
 
 /* All functions writing to the cleartext payload buffer call
  * CHECKCLEARTOWRITE() before writing. This is only really useful if you're
@@ -63,8 +63,10 @@
 /* you don't need to touch this block */
 #ifdef DEBUG_TRACE
 #define TRACE(X) dropbear_trace X;
+#define TRACE2(X) dropbear_trace2 X;
 #else /*DEBUG_TRACE*/
 #define TRACE(X)
+#define TRACE2(X)
 #endif /*DEBUG_TRACE*/
 
 /* To debug with GDB it is easier to run with no forking of child processes.
--- a/dss.c	Sun Mar 31 00:41:15 2013 +0800
+++ b/dss.c	Mon Apr 01 00:13:41 2013 +0800
@@ -101,9 +101,9 @@
 /* Clear and free the memory used by a public or private key */
 void dss_key_free(dropbear_dss_key *key) {
 
-	TRACE(("enter dsa_key_free"))
+	TRACE2(("enter dsa_key_free"))
 	if (key == NULL) {
-		TRACE(("enter dsa_key_free: key == NULL"))
+		TRACE2(("enter dsa_key_free: key == NULL"))
 		return;
 	}
 	if (key->p) {
@@ -127,7 +127,7 @@
 		m_free(key->x);
 	}
 	m_free(key);
-	TRACE(("leave dsa_key_free"))
+	TRACE2(("leave dsa_key_free"))
 }
 
 /* put the dss public key into the buffer in the required format:
--- a/includes.h	Sun Mar 31 00:41:15 2013 +0800
+++ b/includes.h	Mon Apr 01 00:13:41 2013 +0800
@@ -120,6 +120,10 @@
 #include <libgen.h>
 #endif
 
+#ifdef HAVE_SYS_UIO_H
+#include <sys/uio.h>
+#endif
+
 #ifdef BUNDLED_LIBTOM
 #include "libtomcrypt/src/headers/tomcrypt.h"
 #include "libtommath/tommath.h"
--- a/packet.c	Sun Mar 31 00:41:15 2013 +0800
+++ b/packet.c	Mon Apr 01 00:13:41 2013 +0800
@@ -55,10 +55,60 @@
 	buffer * writebuf = NULL;
 	time_t now;
 	unsigned packet_type;
+	int all_ignore = 1;
+#ifdef HAVE_WRITEV
+	struct iovec *iov = NULL;
+	int i;
+	struct Link *l;
+#endif
 	
-	TRACE(("enter write_packet"))
+	TRACE2(("enter write_packet"))
 	dropbear_assert(!isempty(&ses.writequeue));
 
+#ifdef HAVE_WRITEV
+	iov = m_malloc(sizeof(*iov) * ses.writequeue.count);
+	for (l = ses.writequeue.head, i = 0; l; l = l->link, i++)
+	{
+		writebuf = (buffer*)l->item;
+		packet_type = writebuf->data[writebuf->len-1];
+		len = writebuf->len - 1 - writebuf->pos;
+		dropbear_assert(len > 0);
+		all_ignore &= (packet_type == SSH_MSG_IGNORE);
+		iov[i].iov_base = buf_getptr(writebuf, len);
+		iov[i].iov_len = len;
+	}
+	written = writev(ses.sock_out, iov, ses.writequeue.count);
+	if (written < 0) {
+		if (errno == EINTR) {
+			m_free(iov);
+			TRACE2(("leave writepacket: EINTR"))
+			return;
+		} else {
+			dropbear_exit("Error writing");
+		}
+	} 
+
+	if (written == 0) {
+		ses.remoteclosed();
+	}
+
+	while (written > 0) {
+		writebuf = (buffer*)examine(&ses.writequeue);
+		len = writebuf->len - 1 - writebuf->pos;
+		if (len > written) {
+			// partial buffer write
+			buf_incrpos(writebuf, written);
+			written = 0;
+		} else {
+			written -= len;
+			dequeue(&ses.writequeue);
+			buf_free(writebuf);
+		}
+	}
+
+	m_free(iov);
+
+#else
 	/* Get the next buffer in the queue of encrypted packets to write*/
 	writebuf = (buffer*)examine(&ses.writequeue);
 
@@ -72,19 +122,13 @@
 
 	if (written < 0) {
 		if (errno == EINTR) {
-			TRACE(("leave writepacket: EINTR"))
+			TRACE2(("leave writepacket: EINTR"))
 			return;
 		} else {
 			dropbear_exit("Error writing");
 		}
 	} 
-	
-	now = time(NULL);
-	ses.last_trx_packet_time = now;
-
-	if (packet_type != SSH_MSG_IGNORE) {
-		ses.last_packet_time = now;
-	}
+	all_ignore = (packet_type == SSH_MSG_IGNORE);
 
 	if (written == 0) {
 		ses.remoteclosed();
@@ -100,7 +144,15 @@
 		buf_incrpos(writebuf, written);
 	}
 
-	TRACE(("leave write_packet"))
+#endif
+	now = time(NULL);
+	ses.last_trx_packet_time = now;
+
+	if (!all_ignore) {
+		ses.last_packet_time = now;
+	}
+
+	TRACE2(("leave write_packet"))
 }
 
 /* Non-blocking function reading available portion of a packet into the
@@ -112,7 +164,7 @@
 	unsigned int maxlen;
 	unsigned char blocksize;
 
-	TRACE(("enter read_packet"))
+	TRACE2(("enter read_packet"))
 	blocksize = ses.keys->recv.algo_crypt->blocksize;
 	
 	if (ses.readbuf == NULL || ses.readbuf->len < blocksize) {
@@ -125,7 +177,7 @@
 
 		if (ret == DROPBEAR_FAILURE) {
 			/* didn't read enough to determine the length */
-			TRACE(("leave read_packet: packetinit done"))
+			TRACE2(("leave read_packet: packetinit done"))
 			return;
 		}
 	}
@@ -147,7 +199,7 @@
 
 		if (len < 0) {
 			if (errno == EINTR || errno == EAGAIN) {
-				TRACE(("leave read_packet: EINTR or EAGAIN"))
+				TRACE2(("leave read_packet: EINTR or EAGAIN"))
 				return;
 			} else {
 				dropbear_exit("Error reading: %s", strerror(errno));
@@ -163,7 +215,7 @@
 		/* The main select() loop process_packet() to
 		 * handle the packet contents... */
 	}
-	TRACE(("leave read_packet"))
+	TRACE2(("leave read_packet"))
 }
 
 /* Function used to read the initial portion of a packet, and determine the
@@ -197,7 +249,7 @@
 	}
 	if (slen < 0) {
 		if (errno == EINTR) {
-			TRACE(("leave read_packet_init: EINTR"))
+			TRACE2(("leave read_packet_init: EINTR"))
 			return DROPBEAR_FAILURE;
 		}
 		dropbear_exit("Error reading: %s", strerror(errno));
@@ -221,7 +273,7 @@
 	}
 	len = buf_getint(ses.readbuf) + 4 + macsize;
 
-	TRACE(("packet size is %d, block %d mac %d", len, blocksize, macsize))
+	TRACE2(("packet size is %d, block %d mac %d", len, blocksize, macsize))
 
 
 	/* check packet length */
@@ -247,7 +299,7 @@
 	unsigned int padlen;
 	unsigned int len;
 
-	TRACE(("enter decrypt_packet"))
+	TRACE2(("enter decrypt_packet"))
 	blocksize = ses.keys->recv.algo_crypt->blocksize;
 	macsize = ses.keys->recv.algo_mac->hashsize;
 
@@ -304,7 +356,7 @@
 
 	ses.recvseq++;
 
-	TRACE(("leave decrypt_packet"))
+	TRACE2(("leave decrypt_packet"))
 }
 
 /* Checks the mac at the end of a decrypted readbuf.
@@ -403,7 +455,7 @@
 		ses.reply_queue_head = new_item;
 	}
 	ses.reply_queue_tail = new_item;
-	TRACE(("leave enqueue_reply_packet"))
+	TRACE2(("leave enqueue_reply_packet"))
 }
 
 void maybe_flush_reply_queue() {
@@ -440,13 +492,13 @@
 	unsigned int len, encrypt_buf_size;
 	unsigned char mac_bytes[MAX_MAC_LEN];
 	
-	TRACE(("enter encrypt_packet()"))
+	TRACE2(("enter encrypt_packet()"))
 
 	buf_setpos(ses.writepayload, 0);
 	packet_type = buf_getbyte(ses.writepayload);
 	buf_setpos(ses.writepayload, 0);
 
-	TRACE(("encrypt_packet type is %d", packet_type))
+	TRACE2(("encrypt_packet type is %d", packet_type))
 	
 	if ((!ses.dataallowed && !packet_is_okay_kex(packet_type))
 			|| ses.kexstate.sentnewkeys) {
@@ -559,7 +611,7 @@
 	ses.kexstate.datatrans += writebuf->len;
 	ses.transseq++;
 
-	TRACE(("leave encrypt_packet()"))
+	TRACE2(("leave encrypt_packet()"))
 }
 
 
@@ -572,8 +624,6 @@
 	unsigned long bufsize;
 	hmac_state hmac;
 
-	TRACE(("enter writemac"))
-
 	if (key_state->algo_mac->hashsize > 0) {
 		/* calculate the mac */
 		if (hmac_init(&hmac, 
@@ -602,7 +652,7 @@
 			dropbear_exit("HMAC error");
 		}
 	}
-	TRACE(("leave writemac"))
+	TRACE2(("leave writemac"))
 }
 
 #ifndef DISABLE_ZLIB
@@ -613,7 +663,7 @@
 	unsigned int endpos = src->pos + len;
 	int result;
 
-	TRACE(("enter buf_compress"))
+	TRACE2(("enter buf_compress"))
 
 	while (1) {
 
@@ -647,6 +697,6 @@
 		buf_resize(dest, dest->size + ZLIB_COMPRESS_INCR);
 
 	}
-	TRACE(("leave buf_compress"))
+	TRACE2(("leave buf_compress"))
 }
 #endif
--- a/process-packet.c	Sun Mar 31 00:41:15 2013 +0800
+++ b/process-packet.c	Mon Apr 01 00:13:41 2013 +0800
@@ -45,7 +45,7 @@
 	unsigned char type;
 	unsigned int i;
 
-	TRACE(("enter process_packet"))
+	TRACE2(("enter process_packet"))
 
 	type = buf_getbyte(ses.payload);
 	TRACE(("process_packet: packet type = %d", type))
@@ -123,7 +123,7 @@
 	buf_free(ses.payload);
 	ses.payload = NULL;
 
-	TRACE(("leave process_packet"))
+	TRACE2(("leave process_packet"))
 }
 
 
--- a/queue.c	Sun Mar 31 00:41:15 2013 +0800
+++ b/queue.c	Mon Apr 01 00:13:41 2013 +0800
@@ -70,7 +70,6 @@
 
 	struct Link* newlink;
 
-	TRACE(("enter enqueue"))
 	newlink = (struct Link*)m_malloc(sizeof(struct Link));
 
 	newlink->item = item;
@@ -85,5 +84,4 @@
 		queue->head = newlink;
 	}
 	queue->count++;
-	TRACE(("leave enqueue"))
 }
--- a/queue.h	Sun Mar 31 00:41:15 2013 +0800
+++ b/queue.h	Mon Apr 01 00:13:41 2013 +0800
@@ -36,7 +36,7 @@
 
 	struct Link* head;
 	struct Link* tail;
-	unsigned int count; /* safety value */
+	unsigned int count;
 
 };
 
--- a/rsa.c	Sun Mar 31 00:41:15 2013 +0800
+++ b/rsa.c	Mon Apr 01 00:13:41 2013 +0800
@@ -139,10 +139,10 @@
 /* Clear and free the memory used by a public or private key */
 void rsa_key_free(dropbear_rsa_key *key) {
 
-	TRACE(("enter rsa_key_free"))
+	TRACE2(("enter rsa_key_free"))
 
 	if (key == NULL) {
-		TRACE(("leave rsa_key_free: key == NULL"))
+		TRACE2(("leave rsa_key_free: key == NULL"))
 		return;
 	}
 	if (key->d) {
@@ -166,7 +166,7 @@
 		m_free(key->q);
 	}
 	m_free(key);
-	TRACE(("leave rsa_key_free"))
+	TRACE2(("leave rsa_key_free"))
 }
 
 /* Put the public rsa key into the buffer in the required format:
--- a/scp.c	Sun Mar 31 00:41:15 2013 +0800
+++ b/scp.c	Mon Apr 01 00:13:41 2013 +0800
@@ -230,7 +230,7 @@
 		close(pin[0]);
 		close(pout[1]);
 
-#ifdef USE_VFORK
+#ifndef USE_VFORK
 		arg_setup(host, remuser, cmd);
 #endif
 
--- a/service.h	Sun Mar 31 00:41:15 2013 +0800
+++ b/service.h	Mon Apr 01 00:13:41 2013 +0800
@@ -26,7 +26,5 @@
 #define _SERVICE_H_
 
 void recv_msg_service_request(); /* Server */
-void send_msg_service_request(); /* Client */
-void recv_msg_service_accept(); /* Client */
 
 #endif /* _SERVICE_H_ */
--- a/session.h	Sun Mar 31 00:41:15 2013 +0800
+++ b/session.h	Mon Apr 01 00:13:41 2013 +0800
@@ -232,10 +232,6 @@
 
 typedef enum {
 	STATE_NOTHING,
-	SERVICE_AUTH_REQ_SENT,
-	SERVICE_AUTH_ACCEPT_RCVD,
-	SERVICE_CONN_REQ_SENT,
-	SERVICE_CONN_ACCEPT_RCVD,
 	USERAUTH_REQ_SENT,
 	USERAUTH_FAIL_RCVD,
 	USERAUTH_SUCCESS_RCVD,
--- a/signkey.c	Sun Mar 31 00:41:15 2013 +0800
+++ b/signkey.c	Mon Apr 01 00:13:41 2013 +0800
@@ -98,7 +98,7 @@
 	int keytype;
 	int ret = DROPBEAR_FAILURE;
 
-	TRACE(("enter buf_get_pub_key"))
+	TRACE2(("enter buf_get_pub_key"))
 
 	ident = buf_getstring(buf, &len);
 	keytype = signkey_type_from_name(ident, len);
@@ -109,7 +109,7 @@
 		return DROPBEAR_FAILURE;
 	}
 	
-	TRACE(("buf_get_pub_key keytype is %d", keytype))
+	TRACE2(("buf_get_pub_key keytype is %d", keytype))
 
 	*type = keytype;
 
@@ -137,7 +137,7 @@
 	}
 #endif
 
-	TRACE(("leave buf_get_pub_key"))
+	TRACE2(("leave buf_get_pub_key"))
 
 	return ret;
 	
@@ -153,7 +153,7 @@
 	int keytype;
 	int ret = DROPBEAR_FAILURE;
 
-	TRACE(("enter buf_get_priv_key"))
+	TRACE2(("enter buf_get_priv_key"))
 
 	ident = buf_getstring(buf, &len);
 	keytype = signkey_type_from_name(ident, len);
@@ -190,7 +190,7 @@
 	}
 #endif
 
-	TRACE(("leave buf_get_priv_key"))
+	TRACE2(("leave buf_get_priv_key"))
 
 	return ret;
 	
@@ -201,7 +201,7 @@
 
 	buffer *pubkeys;
 
-	TRACE(("enter buf_put_pub_key"))
+	TRACE2(("enter buf_put_pub_key"))
 	pubkeys = buf_new(MAX_PUBKEY_SIZE);
 	
 #ifdef DROPBEAR_DSS
@@ -223,7 +223,7 @@
 			pubkeys->len);
 	
 	buf_free(pubkeys);
-	TRACE(("leave buf_put_pub_key"))
+	TRACE2(("leave buf_put_pub_key"))
 }
 
 /* type is either DROPBEAR_SIGNKEY_DSS or DROPBEAR_SIGNKEY_RSA */
@@ -251,7 +251,7 @@
 
 void sign_key_free(sign_key *key) {
 
-	TRACE(("enter sign_key_free"))
+	TRACE2(("enter sign_key_free"))
 
 #ifdef DROPBEAR_DSS
 	dss_key_free(key->dsskey);
@@ -265,7 +265,7 @@
 	m_free(key->filename);
 
 	m_free(key);
-	TRACE(("leave sign_key_free"))
+	TRACE2(("leave sign_key_free"))
 }
 
 static char hexdig(unsigned char x) {
--- a/sysoptions.h	Sun Mar 31 00:41:15 2013 +0800
+++ b/sysoptions.h	Mon Apr 01 00:13:41 2013 +0800
@@ -188,6 +188,9 @@
 #define DROPBEAR_KEY_LINES /* ie we're using authorized_keys or known_hosts */
 #endif
 
+/* Send an auth request straight away rather than trying "none" type to get a list */
+#define CLI_IMMEDIATE_AUTH
+
 /* Changing this is inadvisable, it appears to have problems
  * with flushing compressed data */
 #define DROPBEAR_ZLIB_MEM_LEVEL 8