changeset 70:b0316ce64e4b

Merging in the changes from 0.41-0.43 main Dropbear tree
author Matt Johnston <matt@ucc.asn.au>
date Thu, 12 Aug 2004 16:41:58 +0000
parents 59d16db56e9f
children ac96bc733e71
files buffer.c channel.h cli-tcpfwd.c common-channel.c configure.in dbutil.c debian/README.runit debian/changelog debian/control debian/copyright.in debian/dropbear.README.Debian debian/dropbear.conffiles debian/dropbear.docs debian/dropbear.init debian/dropbear.postinst debian/dropbear.postrm debian/dropbear.prerm debian/implicit debian/rules debian/service/log debian/service/run dropbearkey.c dss.c gendss.c includes.h options.h packet.c random.c rsa.c signkey.c svr-agentfwd.c svr-auth.c svr-authpasswd.c svr-authpubkey.c svr-chansession.c svr-tcpfwd.c svr-x11fwd.c
diffstat 37 files changed, 550 insertions(+), 232 deletions(-) [+]
line wrap: on
line diff
--- a/buffer.c	Thu Aug 12 15:41:36 2004 +0000
+++ b/buffer.c	Thu Aug 12 16:41:58 2004 +0000
@@ -34,8 +34,8 @@
 #define BUF_MAX_INCR 1000000000
 #define BUF_MAX_SIZE 1000000000
 
-/* avoid excessively large numbers, > 5000 bit */
-#define BUF_MAX_MPINT (5000 / 8)
+/* avoid excessively large numbers, > ~8192 bits */
+#define BUF_MAX_MPINT (8240 / 8)
 
 /* Create (malloc) a new buffer of size */
 buffer* buf_new(unsigned int size) {
@@ -76,7 +76,8 @@
 
 }
 
-/* resize a buffer, pos and len will be repositioned if required */
+/* resize a buffer, pos and len will be repositioned if required when
+ * downsizing */
 void buf_resize(buffer *buf, unsigned int newsize) {
 
 	if (newsize > BUF_MAX_SIZE) {
@@ -151,6 +152,8 @@
 /* Get a byte from the buffer and increment the pos */
 unsigned char buf_getbyte(buffer* buf) {
 
+	/* This check is really just ==, but the >= allows us to check for the
+	 * assert()able case of pos > len, which should _never_ happen. */
 	if (buf->pos >= buf->len) {
 		dropbear_exit("bad buf_getbyte");
 	}
--- a/channel.h	Thu Aug 12 15:41:36 2004 +0000
+++ b/channel.h	Thu Aug 12 16:41:58 2004 +0000
@@ -41,6 +41,9 @@
 #define SSH_OPEN_UNKNOWN_CHANNEL_TYPE           3
 #define SSH_OPEN_RESOURCE_SHORTAGE              4
 
+/* Not a real type */
+#define SSH_OPEN_IN_PROGRESS					99
+
 #define MAX_CHANNELS 60 /* simple mem restriction, includes each tcp/x11
 							connection, so can't be _too_ small */
 
--- a/cli-tcpfwd.c	Thu Aug 12 15:41:36 2004 +0000
+++ b/cli-tcpfwd.c	Thu Aug 12 16:41:58 2004 +0000
@@ -120,7 +120,7 @@
 	struct TCPFwdList * iter = NULL;
 	char portstring[NI_MAXSERV];
 	int sock;
-	int ret = DROPBEAR_FAILURE;
+	int err = SSH_OPEN_ADMINISTRATIVELY_PROHIBITED;
 
 	/* We don't care what address they connected to */
 	buf_eatstring(ses.payload);
@@ -148,6 +148,7 @@
 	sock = connect_remote(iter->connectaddr, portstring, 1, NULL);
 	if (sock < 0) {
 		TRACE(("leave newtcpdirect: sock failed"));
+		err = SSH_OPEN_CONNECT_FAILED;
 		goto out;
 	}
 
@@ -160,9 +161,9 @@
 	channel->infd = sock;
 	channel->initconn = 1;
 	
-	ret = DROPBEAR_SUCCESS;
+	err = SSH_OPEN_IN_PROGRESS;
 
 out:
-	TRACE(("leave newtcpdirect: ret %d", ret));
-	return ret;
+	TRACE(("leave newtcpdirect: err %d", err));
+	return err;
 }
--- a/common-channel.c	Thu Aug 12 15:41:36 2004 +0000
+++ b/common-channel.c	Thu Aug 12 16:41:58 2004 +0000
@@ -172,6 +172,7 @@
 
 	struct Channel *channel;
 	unsigned int i;
+	int ret;
 
 	/* iterate through all the possible channels */
 	for (i = 0; i < ses.chansize; i++) {
@@ -196,8 +197,15 @@
 		 * see if it has errors */
 		if (channel->infd >= 0 && channel->infd != channel->outfd
 				&& FD_ISSET(channel->infd, readfd)) {
-			int ret;
-			ret = write(channel->infd, NULL, 0);
+			if (channel->initconn) {
+				/* Handling for "in progress" connection - this is needed
+				 * to avoid spinning 100% CPU when we connect to a server
+				 * which doesn't send anything (tcpfwding) */
+				checkinitdone(channel);
+				continue; /* Important not to use the channel after 
+							 checkinitdone(), as it may be NULL */
+			}
+			ret = write(channel->infd, NULL, 0); /* Fake write */
 			if (ret < 0 && errno != EINTR && errno != EAGAIN) {
 				closeinfd(channel);
 			}
@@ -209,9 +217,8 @@
 				checkinitdone(channel);
 				continue; /* Important not to use the channel after
 							 checkinitdone(), as it may be NULL */
-			} else {
-				writechannel(channel);
 			}
+			writechannel(channel);
 		}
 	
 		/* now handle any of the channel-closing type stuff */
@@ -285,10 +292,14 @@
 
 	if (getsockopt(channel->infd, SOL_SOCKET, SO_ERROR, &val, &vallen)
 			|| val != 0) {
+		send_msg_channel_open_failure(channel->remotechan,
+				SSH_OPEN_CONNECT_FAILED, "", "");
 		close(channel->infd);
 		deletechannel(channel);
 		TRACE(("leave checkinitdone: fail"));
 	} else {
+		send_msg_channel_open_confirmation(channel, channel->recvwindow,
+				channel->recvmaxpacket);
 		channel->outfd = channel->infd;
 		channel->initconn = 0;
 		TRACE(("leave checkinitdone: success"));
@@ -489,6 +500,7 @@
 	TRACE(("channel index is %d", channel->index));
 
 	buf_free(channel->writebuf);
+	channel->writebuf = NULL;
 
 	/* close the FDs in case they haven't been done
 	 * yet (ie they were shutdown etc */
@@ -497,6 +509,7 @@
 	if (channel->errfd >= 0) {
 		close(channel->errfd);
 	}
+	channel->typedata = NULL;
 
 	deletechannel(channel);
 
@@ -587,6 +600,7 @@
 			TRACE(("leave send_msg_channel_data: read err %d", channel->index));
 		}
 		buf_free(buf);
+		buf = NULL;
 		return;
 	}
 	buf_incrlen(buf, len);
@@ -601,6 +615,7 @@
 
 	buf_putstring(ses.writepayload, buf_getptr(buf, len), len);
 	buf_free(buf);
+	buf = NULL;
 
 	channel->transwindow -= len;
 
@@ -764,6 +779,10 @@
 	if (channel->type->inithandler) {
 		ret = channel->type->inithandler(channel);
 		if (ret > 0) {
+			if (ret == SSH_OPEN_IN_PROGRESS) {
+				/* We'll send the confirmation later */
+				goto cleanup;
+			}
 			errtype = ret;
 			deletechannel(channel);
 			TRACE(("inithandler returned failure %d", ret));
--- a/configure.in	Thu Aug 12 15:41:36 2004 +0000
+++ b/configure.in	Thu Aug 12 16:41:58 2004 +0000
@@ -169,7 +169,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 sys/dirent.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])
 
 # Checks for typedefs, structures, and compiler characteristics.
 AC_C_CONST
--- a/dbutil.c	Thu Aug 12 15:41:36 2004 +0000
+++ b/dbutil.c	Thu Aug 12 16:41:58 2004 +0000
@@ -121,7 +121,7 @@
 int dropbear_listen(const char* address, const char* port,
 		int *socks, unsigned int sockcount, char **errstring, int *maxfd) {
 
-	struct addrinfo hints, *res, *res0;
+	struct addrinfo hints, *res = NULL, *res0 = NULL;
 	int err;
 	unsigned int nsock;
 	struct linger linger;
@@ -273,7 +273,7 @@
 		}
 
 		if (connect(sock, res->ai_addr, res->ai_addrlen) < 0) {
-			if (errno == EINPROGRESS) {
+			if (errno == EINPROGRESS && nonblocking) {
 				TRACE(("Connect in progress"));
 				break;
 			} else {
@@ -287,7 +287,7 @@
 		break; /* Success */
 	}
 
-	if (sock < 0) {
+	if (sock < 0 && !(errno == EINPROGRESS && nonblocking)) {
 		/* Failed */
 		if (errstring != NULL && *errstring == NULL) {
 			int len;
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/debian/README.runit	Thu Aug 12 16:41:58 2004 +0000
@@ -0,0 +1,46 @@
+Using the dropbear SSH server with runit's services supervision
+---------------------------------------------------------------
+
+The dropbear SSH server is perfectly suited to be run under runit's
+service supervision, and this package already has prepared an adequate
+service directory.  Follow these steps to enable the dropbear service
+using the runit package.
+
+If not yet installed on your system, install the runit package, and make
+sure its service supervision is enabled (it's by default)
+
+ # apt-get install runit
+
+Make sure the dropbear service normally handled through the sysv init
+script is stopped
+
+ # /etc/init.d/dropbear stop
+
+Create the system user ``dropbearlog'' which will run the logger service,
+and own the logs
+
+ # adduser --system --home /var/log/dropbear --no-create-home dropbearlog
+
+Create the log directory and make the newly created system user the owner
+of this directory
+
+ # mkdir -p /var/log/dropbear && chown dropbearlog /var/log/dropbear
+
+Optionally adjust the configuration of the dropbear service by editing the
+run script
+
+ # vi /etc/dropbear/run
+
+Finally enable the service by linking dropbear's service directory to
+/var/service/.  The service will be started within five seconds, and
+automatically at boot time.  The sysv init script is disabled; see the
+runsvctrl(8) program for information on how to control services handled by
+runit.  See the svlogd(8) program on how to configure the log service.
+
+ # ln -s /etc/dropbear /var/service/
+
+Optionally check the status of the service a few seconds later
+
+ # runsvstat -l /var/service/dropbear
+
+ -- Gerrit Pape <[email protected]>, Sun, 16 May 2004 15:52:34 +0000
--- a/debian/changelog	Thu Aug 12 15:41:36 2004 +0000
+++ b/debian/changelog	Thu Aug 12 16:41:58 2004 +0000
@@ -1,3 +1,55 @@
+dropbear (0.43-1) unstable; urgency=high
+
+  * New upstream release 0.43
+  * SECURITY: Don't attempt to free uninitialised buffers in DSS verification
+    code
+  * Handle portforwarding to servers which don't send any initial data
+    (Closes: #258426)
+
+ -- Matt Johnston <[email protected]>  Fri, 16 July 2004 17:44:54 +0800
+
+dropbear (0.42-1) unstable; urgency=low
+
+  * New upstream release 0.42
+
+ -- Matt Johnston <[email protected]>  Wed, 16 June 2004 12:44:54 +0800
+
+dropbear (0.41-3) unstable; urgency=low
+
+  * 1st upload to the Debian archive (closes: #216553).
+  * debian/diff/cvs-20040520.diff: new; stable cvs snapshot.
+  * debian/rules: new target patch: apply diffs in debian/diff/, reverse
+    apply in target clean; install man pages.
+  * debian/control: Priority: optional.
+
+ -- Gerrit Pape <[email protected]>  Sun, 23 May 2004 08:32:37 +0000
+
+dropbear (0.41-2) unstable; urgency=low
+
+  * new maintainer.
+  * debian/control: no longer Build-Depends: debhelper; Build-Depends:
+    libz-dev; Standards-Version: 3.6.1.0; Suggests: runit; update
+    descriptions.
+  * debian/rules: stop using debhelper, use implicit rules; cleanup;
+    install dropbearconvert into /usr/lib/dropbear/.
+  * debian/impicit: new; implicit rules.
+  * debian/copyright.in: adapt.
+  * debian/dropbear.init: minor adaptions; test for dropbear service
+    directory.
+  * debian/README.runit: new; how to use dropbear with runit.
+  * debian/README.Debian, debian/docs: rename to debian/dropbear.*.
+  * debian/dropbear.docs: add debian/README.runit
+  * debian/conffiles: rename to debian/dropbear.conffiles; add init
+    script, and run scripts.
+  * debian/postinst: rename to debian/dropbear.postinst; adapt; use
+    invloke-rc.d dropbear start.
+  * debian/dropbear.prerm: new; invoke-rc.d dropbear stop.
+  * debian/postrm: rename to debian/dropbear.postrm; adapt; clean up
+    service directories.
+  * debian/compat, debian/dirs, dropbear.default: remove; obsolete.
+
+ -- Gerrit Pape <[email protected]>  Sun, 16 May 2004 16:50:55 +0000
+
 dropbear (0.41-1) unstable; urgency=low
 
   * Updated to 0.41 release.
--- a/debian/control	Thu Aug 12 15:41:36 2004 +0000
+++ b/debian/control	Thu Aug 12 16:41:58 2004 +0000
@@ -1,14 +1,20 @@
 Source: dropbear
 Section: net
-Priority: standard
-Maintainer: Grahame Bowland <[email protected]>
-Build-Depends: debhelper (>> 4.0.0), zlib1g-dev
-Standards-Version: 3.5.8
+Priority: optional
+Maintainer: Gerrit Pape <[email protected]>
+Build-Depends: libz-dev
+Standards-Version: 3.6.1.0
 
 Package: dropbear
 Architecture: any
-Depends: ${shlibs:Depends} ${misc:Depends}
-Suggests: ssh
-Description: a minimal SSH2 server
- A small secure shell version 2 server.
-
+Depends: ${shlibs:Depends}
+Suggests: ssh, runit
+Description: lightweight SSH2 server
+ dropbear is a SSH 2 server designed to be small enough to be used in small
+ memory environments, while still being functional and secure enough for
+ general use.
+ .
+ It implements most required features of the SSH 2 protocol, and other
+ features such as X11 and authentication agent forwarding.
+ .
+ See http://matt.ucc.asn.au/dropbear/dropbear.html
--- a/debian/copyright.in	Thu Aug 12 15:41:36 2004 +0000
+++ b/debian/copyright.in	Thu Aug 12 16:41:58 2004 +0000
@@ -1,9 +1,11 @@
 This package was debianized by Grahame Bowland <grahame.angrygoats.net> on
-Tue, 17 Jun 2003 15:04:47 +0800.
+Tue, 17 Jun 2003 15:04:47 +0800, maintained temporarily by Matt Johnston
+<[email protected]>, and was adopted by Gerrit Pape <[email protected]> on
+Sun, 16 May 2004 14:38:33 +0000.
 
 It was downloaded from http://matt.ucc.asn.au/dropbear/
 
-Upstream Author(s): Matt Johnston <[email protected]>
+Upstream Author: Matt Johnston <[email protected]>
 
 Copyright: 
 
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/debian/dropbear.README.Debian	Thu Aug 12 16:41:58 2004 +0000
@@ -0,0 +1,41 @@
+Dropbear for Debian
+-------------------
+
+This package will attempt to listen on port 22. If the OpenSSH 
+package ("ssh") is installed, the file /etc/default/dropbear 
+will be set up so that the server does not start by default.
+
+You can run Dropbear concurrently with OpenSSH 'sshd' by 
+modifying /etc/default/dropbear so that "NO_START" is set to 
+"0" and changing the port number that Dropbear runs on. Follow 
+the instructions in the file.
+
+This package suggests you install the "ssh" package. This package 
+provides the "ssh" client program, as well as the "/usr/bin/scp" 
+binary you will need to be able to retrieve files from a server 
+running Dropbear via SCP.
+
+Replacing OpenSSH "sshd" with Dropbear
+--------------------------------------
+
+You will still want to have the "ssh" package installed, as it 
+provides the "ssh" and "scp" binaries. When you install this 
+package, it checks for existing OpenSSH host keys and if found, 
+converts them to the Dropbear format.
+
+If this appears to have worked, you should be able to change over 
+by following these steps:
+
+1. Stop the OpenSSH server
+   % /etc/init.d/ssh stop
+2. Prevent the OpenSSH server from starting in the future
+   % touch /etc/ssh/sshd_not_to_be_run
+3. Modify the Dropbear defaults file, set NO_START to 0 and 
+   ensure DROPBEAR_PORT is set to 22.
+   % editor /etc/default/dropbear
+4. Restart the Dropbear server.
+   % /etc/init.d/dropbear restart
+
+See the Dropbear homepage for more information:
+  http://matt.ucc.asn.au/dropbear/dropbear.html
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/debian/dropbear.conffiles	Thu Aug 12 16:41:58 2004 +0000
@@ -0,0 +1,3 @@
+/etc/init.d/dropbear
+/etc/dropbear/run
+/etc/dropbear/log/run
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/debian/dropbear.docs	Thu Aug 12 16:41:58 2004 +0000
@@ -0,0 +1,3 @@
+README
+TODO
+debian/README.runit
--- a/debian/dropbear.init	Thu Aug 12 15:41:36 2004 +0000
+++ b/debian/dropbear.init	Thu Aug 12 16:41:58 2004 +0000
@@ -1,15 +1,4 @@
-#! /bin/sh
-#
-# skeleton	example file to build /etc/init.d/ scripts.
-#		This file should be used to construct scripts for /etc/init.d.
-#
-#		Written by Miquel van Smoorenburg <[email protected]>.
-#		Modified for Debian 
-#		by Ian Murdock <[email protected]>.
-#
-# Version:	@(#)skeleton  1.9  26-Feb-2001  [email protected]
-#
-
+#!/bin/sh
 #
 # Do not configure this file. Edit /etc/default/dropbear instead!
 #
@@ -22,54 +11,45 @@
 DROPBEAR_PORT=22
 DROPBEAR_EXTRA_ARGS=
 NO_START=0
+
 set -e
-test -f /etc/default/dropbear && . /etc/default/dropbear
-
-if [ -n "$DROPBEAR_BANNER" ]; then
-	DROPBEAR_EXTRA_ARGS="$DROPBEAR_EXTRA_ARGS -b $DROPBEAR_BANNER"
-fi
 
-if [ -z "$DROPBEAR_RSAKEY" ]; then
-	DROPBEAR_RSAKEY="/etc/dropbear/dropbear_rsa_host_key"
-fi
+test ! -r /etc/default/dropbear || . /etc/default/dropbear
+test "$NO_START" = "0" || exit 0
+test -x "$DAEMON" || exit 0
+test ! -h /var/service/dropbear || exit 0
 
-if [ -z "$DROPBEAR_DSSKEY" ]; then
-	DROPBEAR_DSSKEY="/etc/dropbear/dropbear_dss_host_key"
-fi
-
-test "$NO_START" != "0" && exit 0
-
-test -x $DAEMON || exit 0
+test -z "$DROPBEAR_BANNER" || \
+  DROPBEAR_EXTRA_ARGS="$DROPBEAR_EXTRA_ARGS -b $DROPBEAR_BANNER"
+test -n "$DROPBEAR_RSAKEY" || \
+  DROPBEAR_RSAKEY="/etc/dropbear/dropbear_rsa_host_key"
+test -n "$DROPBEAR_DSSKEY" || \
+  DROPBEAR_DSSKEY="/etc/dropbear/dropbear_dss_host_key"
 
 case "$1" in
   start)
 	echo -n "Starting $DESC: "
-	start-stop-daemon --start --quiet --pidfile /var/run/$NAME.pid \
-		--exec $DAEMON -- -d $DROPBEAR_DSSKEY -r $DROPBEAR_RSAKEY -p $DROPBEAR_PORT $DROPBEAR_EXTRA_ARGS
+	start-stop-daemon --start --quiet --pidfile /var/run/"$NAME".pid \
+	  --exec "$DAEMON" -- -d "$DROPBEAR_DSSKEY" -r "$DROPBEAR_RSAKEY" \
+	    -p "$DROPBEAR_PORT" $DROPBEAR_EXTRA_ARGS
 	echo "$NAME."
 	;;
   stop)
 	echo -n "Stopping $DESC: "
-	start-stop-daemon --stop --quiet --oknodo --pidfile /var/run/$NAME.pid
+	start-stop-daemon --stop --quiet --oknodo --pidfile /var/run/"$NAME".pid
 	echo "$NAME."
 	;;
   restart|force-reload)
-	#
-	#	If the "reload" option is implemented, move the "force-reload"
-	#	option to the "reload" entry above. If not, "force-reload" is
-	#	just the same as "restart".
-	#
 	echo -n "Restarting $DESC: "
-	start-stop-daemon --stop --quiet --oknodo --pidfile \
-		/var/run/$NAME.pid
+	start-stop-daemon --stop --quiet --oknodo --pidfile /var/run/"$NAME".pid
 	sleep 1
-	start-stop-daemon --start --quiet --pidfile /var/run/$NAME.pid \
-		--exec $DAEMON -- -d $DROPBEAR_DSSKEY -r $DROPBEAR_RSAKEY -p $DROPBEAR_PORT $DROPBEAR_EXTRA_ARGS
+	start-stop-daemon --start --quiet --pidfile /var/run/"$NAME".pid \
+	  --exec "$DAEMON" -- -d "$DROPBEAR_DSSKEY" -r "$DROPBEAR_RSAKEY" \
+	    -p "$DROPBEAR_PORT" $DROPBEAR_EXTRA_ARGS
 	echo "$NAME."
 	;;
   *)
 	N=/etc/init.d/$NAME
-	# echo "Usage: $N {start|stop|restart|reload|force-reload}" >&2
 	echo "Usage: $N {start|stop|restart|force-reload}" >&2
 	exit 1
 	;;
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/debian/dropbear.postinst	Thu Aug 12 16:41:58 2004 +0000
@@ -0,0 +1,68 @@
+#!/bin/sh
+set -e
+
+test "$1" = 'configure' || exit 0
+test -n "$2" || chown log /etc/dropbear/log/main || true
+
+if test ! -e /etc/dropbear/dropbear_rsa_host_key; then
+  if test -f /etc/ssh/ssh_host_rsa_key; then
+    echo "Converting existing OpenSSH RSA host key to Dropbear format."
+    /usr/lib/dropbear/dropbearconvert openssh dropbear \
+      /etc/ssh/ssh_host_rsa_key /etc/dropbear/dropbear_rsa_host_key
+  else
+    echo "Generating Dropbear RSA key. Please wait."
+    dropbearkey -t rsa -f /etc/dropbear/dropbear_rsa_host_key
+  fi
+fi
+if test ! -e /etc/dropbear/dropbear_dss_host_key; then
+  if test -f /etc/ssh/ssh_host_dsa_key; then
+    echo "Converting existing OpenSSH RSA host key to Dropbear format."
+    /usr/lib/dropbear/dropbearconvert openssh dropbear \
+      /etc/ssh/ssh_host_dsa_key /etc/dropbear/dropbear_dss_host_key
+  else
+    echo "Generating Dropbear DSS key. Please wait."
+    dropbearkey -t dss -f /etc/dropbear/dropbear_dss_host_key
+  fi
+fi
+if test ! -s /etc/default/dropbear; then 
+  # check whether OpenSSH seems to be installed.
+  if test -x /usr/sbin/sshd; then
+    cat <<EOT
+OpenSSH appears to be installed.  Setting /etc/default/dropbear so that
+Dropbear will not start by default.  Edit this file to change this behaviour.
+
+EOT
+    cat >>/etc/default/dropbear <<EOT
+# disabled because OpenSSH is installed
+# change to NO_START=0 to enable Dropbear
+NO_START=1
+
+EOT
+  fi
+  cat >>/etc/default/dropbear <<EOT
+# the TCP port that Dropbear listens on
+DROPBEAR_PORT=22
+
+# any additional arguments for Dropbear
+DROPBEAR_EXTRA_ARGS=
+
+# specify an optional banner file containing a message to be
+# sent to clients before they connect, such as "/etc/issue.net"
+DROPBEAR_BANNER=""
+
+# RSA hostkey file (default: /etc/dropbear/dropbear_rsa_host_key)
+#DROPBEAR_RSAKEY="/etc/dropbear/dropbear_rsa_host_key"
+
+# DSS hostkey file (default: /etc/dropbear/dropbear_dss_host_key)
+#DROPBEAR_DSSKEY="/etc/dropbear/dropbear_dss_host_key"
+EOT
+fi
+
+if test -x /etc/init.d/dropbear; then
+  update-rc.d dropbear defaults >/dev/null
+  if test -x /usr/sbin/invoke-rc.d; then
+    invoke-rc.d dropbear start
+  else
+    /etc/init.d/dropbear start
+  fi
+fi
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/debian/dropbear.postrm	Thu Aug 12 16:41:58 2004 +0000
@@ -0,0 +1,12 @@
+#! /bin/sh
+set -e
+
+test "$1" = 'purge' || exit 0
+if test -e /etc/dropbear; then
+  rm -f /etc/dropbear/dropbear_rsa_host_key
+  rm -f /etc/dropbear/dropbear_dss_host_key
+  rmdir --ignore-fail-on-non-empty /etc/dropbear
+fi
+update-rc.d dropbear remove >/dev/null
+rm -f /etc/default/dropbear
+rm -rf /etc/dropbear/supervise /etc/dropbear/log/supervise
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/debian/dropbear.prerm	Thu Aug 12 16:41:58 2004 +0000
@@ -0,0 +1,11 @@
+#!/bin/sh
+set -u
+
+test "$1" = 'remove' || test "$1" = 'deconfigure' || exit 0
+if test -x /etc/init.d/dropbear; then
+  if test -x /usr/sbin/invoke-rc.d; then
+    invoke-rc.d dropbear stop
+  else
+    /etc/init.d/dropbear stop
+  fi
+fi
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/debian/implicit	Thu Aug 12 16:41:58 2004 +0000
@@ -0,0 +1,79 @@
+# $Id: implicit,v 1.1 2004/06/16 05:08:32 matt Exp $
+
+.PHONY: deb-checkdir deb-checkuid
+
+deb-checkdir:
+	@test -e debian/control || sh -cx '! : wrong directory'
+deb-checkuid:
+	@test "`id -u`" -eq 0 || sh -cx '! : need root privileges'
+
+%.deb: %.deb-docs %.deb-DEBIAN
+	@rm -f $*.deb $*.deb-checkdir $*.deb-docs $*.deb-docs-base \
+	  $*.deb-docs-docs $*.deb-docs-examples $*.deb-DEBIAN \
+	  $*.deb-DEBIAN-dir $*.deb-DEBIAN-scripts $*.deb-DEBIAN-md5sums
+
+%.deb-checkdir:
+	@test -d debian/$* || sh -cx '! : directory debian/$* missing'
+	@test "`id -u`" -eq 0 || sh -cx '! : need root privileges'
+
+%.deb-docs-base:
+	: implicit
+	@rm -f debian/$*/usr/share/doc/$*/* || :
+	@install -d -m0755 debian/$*/usr/share/doc/$*
+	: debian/$*/usr/share/doc/$*/
+	@sh -cx 'install -m0644 debian/copyright debian/$*/usr/share/doc/$*/'
+	@sh -cx 'install -m0644 debian/changelog \
+	  debian/$*/usr/share/doc/$*/changelog.Debian'
+	@test ! -r changelog || \
+	  sh -cx 'install -m0644 changelog debian/$*/usr/share/doc/$*/'
+	@test -r debian/$*/usr/share/doc/$*/changelog || \
+	  sh -cx 'mv debian/$*/usr/share/doc/$*/changelog.Debian \
+	    debian/$*/usr/share/doc/$*/changelog'
+	@gzip -9 debian/$*/usr/share/doc/$*/changelog*
+%.deb-docs-docs:
+	@for i in `cat debian/$*.docs 2>/dev/null || :`; do \
+	  sh -cx "install -m0644 $$i debian/$*/usr/share/doc/$*/" || exit 1; \
+	done
+	@test ! -r debian/$*.README.Debian || \
+	  sh -cx 'install -m0644 debian/$*.README.Debian \
+	    debian/$*/usr/share/doc/$*/README.Debian'
+	@if test -r debian/$*.NEWS.Debian; then \
+	  sh -cx 'install -m0644 debian/$*.NEWS.Debian \
+	    debian/$*/usr/share/doc/$*/NEWS.Debian && \
+	      gzip -9 debian/$*/usr/share/doc/$*/NEWS.Debian'; \
+	fi
+%.deb-docs-examples:
+	@rm -rf debian/$*/usr/share/doc/$*/examples
+	: debian/$*/usr/share/doc/$*/examples/
+	@test ! -r debian/$*.examples || \
+	  install -d -m0755 debian/$*/usr/share/doc/$*/examples
+	@for i in `cat debian/$*.examples 2>/dev/null || :`; do \
+	  sh -cx "install -m0644 $$i debian/$*/usr/share/doc/$*/examples/" \
+	    || exit 1; \
+	done
+%.deb-docs: %.deb-checkdir %.deb-docs-base %.deb-docs-docs %.deb-docs-examples
+	: debian/$*/usr/share/doc/$*/ ok
+
+%.deb-DEBIAN-base:
+	@rm -rf debian/$*/DEBIAN
+	: debian/$*/DEBIAN/
+	@install -d -m0755 debian/$*/DEBIAN
+	@for i in conffiles shlibs; do \
+	  test ! -r debian/$*.$$i || \
+	    sh -cx "install -m0644 debian/$*.$$i debian/$*/DEBIAN/$$i" \
+	      || exit 1; \
+	done
+%.deb-DEBIAN-scripts:
+	@for i in preinst prerm postinst postrm; do \
+	  test ! -r debian/$*.$$i || \
+	    sh -cx "install -m0755 debian/$*.$$i debian/$*/DEBIAN/$$i" \
+	      || exit 1; \
+	done
+%.deb-DEBIAN-md5sums:
+	: debian/$*/DEBIAN/md5sums
+	@rm -f debian/$*/DEBIAN/md5sums
+	@cd debian/$* && find * -path 'DEBIAN' -prune -o \
+	  -type f -exec md5sum {} >>DEBIAN/md5sums \;
+%.deb-DEBIAN: %.deb-checkdir %.deb-DEBIAN-base %.deb-DEBIAN-scripts \
+	  %.deb-DEBIAN-md5sums
+	: debian/$*/DEBIAN/ ok
--- a/debian/rules	Thu Aug 12 15:41:36 2004 +0000
+++ b/debian/rules	Thu Aug 12 16:41:58 2004 +0000
@@ -1,134 +1,96 @@
 #!/usr/bin/make -f
-# Sample debian/rules that uses debhelper.
-# GNU copyright 1997 to 1999 by Joey Hess.
-#
-# Modified to make a template file for a multi-binary package with separated
-# build-arch and build-indep targets  by Bill Allombert 2001
-
-# Uncomment this to turn on verbose mode.
-#export DH_VERBOSE=1
-
-# This has to be exported to make some magic below work.
-export DH_OPTIONS
 
-# These are used for cross-compiling and for saving the configure script
-# from having to guess our platform (since we know it already)
-DEB_HOST_GNU_TYPE   ?= $(shell dpkg-architecture -qDEB_HOST_GNU_TYPE)
-DEB_BUILD_GNU_TYPE  ?= $(shell dpkg-architecture -qDEB_BUILD_GNU_TYPE)
-
-
-CFLAGS = -Wall -g
+#export DH_OPTIONS
+DEB_HOST_GNU_TYPE ?=$(shell dpkg-architecture -qDEB_HOST_GNU_TYPE)
+DEB_BUILD_GNU_TYPE ?=$(shell dpkg-architecture -qDEB_BUILD_GNU_TYPE)
 
-ifneq (,$(findstring noopt,$(DEB_BUILD_OPTIONS)))
-	CFLAGS += -O0
-else
-	CFLAGS += -O2
-endif
-ifeq (,$(findstring nostrip,$(DEB_BUILD_OPTIONS)))
-	INSTALL_PROGRAM += -s
+STRIP =strip
+ifneq (,$(findstring nostrip,$(DEB_BUILD_OPTIONS)))
+  STRIP =: nostrip
 endif
 
-config.status: configure
-	dh_testdir
-	# Add here commands to configure the package.
-	CFLAGS='-DSFTPSERVER_PATH="\"/usr/lib/sftp-server\""' ./configure --host=$(DEB_HOST_GNU_TYPE) --build=$(DEB_BUILD_GNU_TYPE) --prefix=/usr --mandir=\$${prefix}/share/man --infodir=\$${prefix}/share/info
-
-
-#Architecture 
-build: build-arch #build-indep
-
-build-arch: build-arch-stamp
-build-arch-stamp:  config.status
-	
-	# Add here commands to compile the arch part of the package.
-	$(MAKE) CC=gcc LD=gcc
+CFLAGS =-Wall -g
+ifneq (,$(findstring noopt,$(DEB_BUILD_OPTIONS)))
+  CFLAGS +=-O0
+else
+  CFLAGS +=-O2
+endif
 
-build-indep: build-indep-stamp
-build-indep-stamp:  config.status
-	
-	# Add here commands to compile the indep part of the package.
-	#$(MAKE) doc
-
-clean:
-	dh_testdir
-	dh_testroot
-	rm -f build-arch-stamp build-indep-stamp config-stamp
-
-	# Add here commands to clean up after the build process.
-	-$(MAKE) clean
-ifneq "$(wildcard /usr/share/misc/config.sub)" ""
-	cp -f /usr/share/misc/config.sub config.sub
-endif
-ifneq "$(wildcard /usr/share/misc/config.guess)" ""
-	cp -f /usr/share/misc/config.guess config.guess
+CC =gcc
+ifneq (,$(findstring diet,$(DEB_BUILD_OPTIONS)))
+  CC =diet -v -Os gcc
 endif
 
-	
-	dh_clean
+DIR=`pwd`/debian/dropbear
+
+patch: deb-checkdir patch-stamp
+patch-stamp:
+#	no patches for now
+#	for i in debian/diff/*.diff; do patch -p0 <$$i || exit 1; done
+	touch patch-stamp
 
-install: install-indep install-arch
-install-indep:
-	dh_testdir
-	dh_testroot
-	dh_clean -k -i
-	dh_installdirs -i
-	
-	# Add here commands to install the indep part of the package into
-	# debian/<package>-doc.
-	#INSTALLDOC#
-	
-	dh_install -i
+config.status: patch-stamp configure
+	CFLAGS="$(CFLAGS)"' -DSFTPSERVER_PATH="\"/usr/lib/sftp-server\""' \
+	  ./configure --host="$(DEB_HOST_GNU_TYPE)" \
+	    --build="$(DEB_BUILD_GNU_TYPE)" --prefix=/usr \
+	    --mandir=\$${prefix}/share/man --infodir=\$${prefix}/share/info
 
-install-arch:
-	dh_testdir
-	dh_testroot
-	dh_clean -k -a
-	dh_installdirs -a
-	dh_installdirs /etc/dropbear
+build: deb-checkdir build-stamp
+build-stamp: config.status
+	$(MAKE) CC="$(CC)" LD="$(CC)"
+	touch build-stamp
 
-	# Add here commands to install the arch part of the package into 
-	# debian/tmp.
-	$(MAKE) install prefix=$(CURDIR)/debian/dropbear/usr
+clean: deb-checkdir deb-checkuid
+	-$(MAKE) distclean
+#	test ! -e patch-stamp || \
+#	  for i in debian/diff/*.diff; do patch -p0 -R <$$i; done
+	rm -f patch-stamp build-stamp config.log config.status
+	rm -rf "$(DIR)"
+	rm -f debian/files debian/substvars debian/copyright changelog
 
-	dh_install -a
-# Must not depend on anything. This is to be called by
-# binary-arch/binary-multi
-# in another 'make' thread.
-binary-common:
-	cat $(CURDIR)/debian/copyright.in $(CURDIR)/LICENSE > $(CURDIR)/debian/copyright
-	dh_testdir
-	dh_testroot
-	dh_installchangelogs CHANGES
-	dh_installdocs
-	dh_installexamples
-#	dh_installmenu
-#	dh_installdebconf	
-#	dh_installlogrotate	
-#	dh_installemacsen
-#	dh_installpam
-#	dh_installmime
-	dh_installinit
-#	dh_installcron
-#	dh_installinfo
-	dh_installman
-	dh_link
-	dh_strip
-	dh_compress 
-	dh_fixperms
-#	dh_perl
-#	dh_python
-	dh_makeshlibs
-	dh_installdeb
-	dh_gencontrol
-	dh_md5sums
-	dh_builddeb
-# Build architecture independant packages using the common target.
-binary-indep: build-indep install-indep
-	$(MAKE) -f debian/rules DH_OPTIONS=-i binary-common
+install: deb-checkdir deb-checkuid build-stamp
+	rm -rf "$(DIR)"
+	install -d -m0755 "$(DIR)"/etc/dropbear
+	# programs
+	install -d -m0755 "$(DIR)"/usr/sbin
+	install -m0755 dropbear "$(DIR)"/usr/sbin/dropbear
+	install -d -m0755 "$(DIR)"/usr/bin
+	install -m0755 dropbearkey "$(DIR)"/usr/bin/dropbearkey
+	install -d -m0755 "$(DIR)"/usr/lib/dropbear
+	install -m0755 dropbearconvert \
+	  "$(DIR)"/usr/lib/dropbear/dropbearconvert
+	$(STRIP) -R .comment -R .note "$(DIR)"/usr/sbin/* \
+	  "$(DIR)"/usr/bin/* "$(DIR)"/usr/lib/dropbear/*
+	# init and run scripts
+	install -d -m0755 "$(DIR)"/etc/init.d
+	install -m0755 debian/dropbear.init "$(DIR)"/etc/init.d/dropbear
+	install -m0755 debian/service/run "$(DIR)"/etc/dropbear/run
+	install -d -m0755 "$(DIR)"/etc/dropbear/log
+	install -m0755 debian/service/log "$(DIR)"/etc/dropbear/log/run
+	ln -s /var/log/dropbear "$(DIR)"/etc/dropbear/log/main
+	ln -s /var/run/dropbear "$(DIR)"/etc/dropbear/supervise
+	ln -s /var/run/dropbear.log "$(DIR)"/etc/dropbear/log/supervise
+	# man pages
+	install -d -m0755 "$(DIR)"/usr/share/man/man8
+	for i in dropbear.8 dropbearkey.8; do \
+	  install -m644 $$i "$(DIR)"/usr/share/man/man8/ || exit 1; \
+	done
+	gzip -9 "$(DIR)"/usr/share/man/man8/*.8
+	# copyright, changelog
+	cat debian/copyright.in LICENSE >debian/copyright
+	ln -s CHANGES changelog
 
-# Build architecture dependant packages using the common target.
-binary-arch: build-arch install-arch
-	$(MAKE) -f debian/rules DH_OPTIONS=-a binary-common
+binary-indep:
 
-binary: binary-arch #binary-indep
-.PHONY: build clean binary-indep binary-arch binary install install-indep install-arch 
+binary-arch: install dropbear.deb
+	test "$(CC)" != 'gcc' || \
+	  dpkg-shlibdeps "$(DIR)"/usr/sbin/* "$(DIR)"/usr/bin/* \
+	    "$(DIR)"/usr/lib/dropbear/*
+	dpkg-gencontrol -isp -pdropbear -P"$(DIR)"
+	dpkg -b "$(DIR)" ..
+
+binary: binary-arch binary-indep
+
+.PHONY: patch build clean install binary-indep binary-arch binary
+
+include debian/implicit
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/debian/service/log	Thu Aug 12 16:41:58 2004 +0000
@@ -0,0 +1,2 @@
+#!/bin/sh
+exec chpst -udropbearlog svlogd -tt ./main
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/debian/service/run	Thu Aug 12 16:41:58 2004 +0000
@@ -0,0 +1,3 @@
+#!/bin/sh
+exec 2>&1
+exec dropbear -d ./dropbear_dss_host_key -r ./dropbear_rsa_host_key -F -E -p 22
--- a/dropbearkey.c	Thu Aug 12 15:41:36 2004 +0000
+++ b/dropbearkey.c	Thu Aug 12 16:41:58 2004 +0000
@@ -45,7 +45,6 @@
  *
  */
 #include "includes.h"
-#include "runopts.h"
 #include "signkey.h"
 #include "buffer.h"
 #include "dbutil.h"
--- a/dss.c	Thu Aug 12 15:41:36 2004 +0000
+++ b/dss.c	Thu Aug 12 16:41:58 2004 +0000
@@ -171,6 +171,8 @@
 	TRACE(("enter buf_dss_verify"));
 	assert(key != NULL);
 
+	m_mp_init_multi(&val1, &val2, &val3, &val4, NULL);
+
 	/* get blob, check length */
 	string = buf_getstring(buf, &stringlen);
 	if (stringlen != 2*SHA1_HASH_SIZE) {
@@ -182,8 +184,6 @@
 	sha1_process(&hs, data, len);
 	sha1_done(&hs, msghash);
 
-	m_mp_init_multi(&val1, &val2, &val3, &val4, NULL);
-
 	/* create the signature - s' and r' are the received signatures in buf */
 	/* w = (s')-1 mod q */
 	/* let val1 = s' */
--- a/gendss.c	Thu Aug 12 15:41:36 2004 +0000
+++ b/gendss.c	Thu Aug 12 16:41:58 2004 +0000
@@ -31,7 +31,6 @@
 #include "gendss.h"
 #include "dss.h"
 
-#define PSIZE 128 /* 1024 bit*/
 #define QSIZE 20 /* 160 bit */
 
 #ifdef DROPBEAR_DSS
--- a/includes.h	Thu Aug 12 15:41:36 2004 +0000
+++ b/includes.h	Thu Aug 12 16:41:58 2004 +0000
@@ -38,7 +38,6 @@
 #include <sys/time.h>
 #include <sys/un.h>
 #include <sys/wait.h>
-#include <sys/dir.h>
 
 #include <stdio.h>
 #include <errno.h>
@@ -56,6 +55,7 @@
 #include <netdb.h>
 #include <ctype.h>
 #include <stdarg.h>
+#include <dirent.h>
 
 #include <arpa/inet.h>
 
@@ -111,10 +111,6 @@
 #include <libgen.h>
 #endif
 
-#ifdef HAVE_SYS_DIRENT_H
-#include <sys/dirent.h>
-#endif
-
 #include "libtomcrypt/mycrypt_custom.h"
 #include "libtommath/tommath.h"
 
--- a/options.h	Thu Aug 12 15:41:36 2004 +0000
+++ b/options.h	Thu Aug 12 16:41:58 2004 +0000
@@ -47,6 +47,11 @@
  * if you want to use this) */
 /*#define NO_FAST_EXPTMOD*/
 
+/* Set this if you want to use the DROPBEAR_SMALL_CODE option. This can save
+several kB in binary size, however will make the symmetrical ciphers (AES, DES
+etc) slower (perhaps by 50%). Recommended for most small systems. */
+#define DROPBEAR_SMALL_CODE
+
 /* Enable X11 Forwarding - server only */
 #define ENABLE_X11FWD
 
@@ -175,7 +180,7 @@
  *******************************************************************/
 
 #ifndef DROPBEAR_VERSION
-#define DROPBEAR_VERSION "0.41-and-client"
+#define DROPBEAR_VERSION "0.45-beta1"
 #endif
 
 #define LOCAL_IDENT "SSH-2.0-dropbear_" DROPBEAR_VERSION
--- a/packet.c	Thu Aug 12 15:41:36 2004 +0000
+++ b/packet.c	Thu Aug 12 16:41:58 2004 +0000
@@ -50,7 +50,7 @@
 void write_packet() {
 
 	int len, written;
-	buffer * writebuf;
+	buffer * writebuf = NULL;
 	
 	TRACE(("enter write_packet"));
 	assert(!isempty(&ses.writequeue));
@@ -80,6 +80,7 @@
 		/* 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);
@@ -503,6 +504,7 @@
 
 	/* clearwritebuf is finished with */
 	buf_free(clearwritebuf);
+	clearwritebuf = NULL;
 
 	/* enqueue the packet for sending */
 	buf_setpos(writebuf, 0);
--- a/random.c	Thu Aug 12 15:41:36 2004 +0000
+++ b/random.c	Thu Aug 12 16:41:58 2004 +0000
@@ -60,7 +60,7 @@
 
 #ifdef DROPBEAR_DEV_URANDOM
 	readfd = open(DEV_URANDOM, O_RDONLY);
-	if (!readfd) {
+	if (readfd < 0) {
 		dropbear_exit("couldn't open random device");
 	}
 #endif
@@ -71,7 +71,8 @@
 	strlcpy(egdsock.sun_path, DROPBEAR_EGD_SOCKET,
 			sizeof(egdsock.sun_path));
 
-	if ((readfd = socket(PF_UNIX, SOCK_STREAM, 0)) < 0) {
+	readfd = socket(PF_UNIX, SOCK_STREAM, 0);
+	if (readfd < 0) {
 		dropbear_exit("couldn't open random device");
 	}
 	/* todo - try various common locations */
--- a/rsa.c	Thu Aug 12 15:41:36 2004 +0000
+++ b/rsa.c	Thu Aug 12 16:41:58 2004 +0000
@@ -244,8 +244,11 @@
 	}
 
 out:
-	mp_clear_multi(rsa_em, &rsa_mdash, &rsa_s, NULL);
-	m_free(rsa_em);
+	if (rsa_em) {
+		mp_clear(rsa_em);
+		m_free(rsa_em);
+	}
+	mp_clear_multi(&rsa_mdash, &rsa_s, NULL);
 	TRACE(("leave buf_rsa_verify: ret %d", ret));
 	return ret;
 
@@ -260,15 +263,16 @@
 	unsigned int nsize, ssize;
 	unsigned int i;
 	mp_int rsa_s;
-	mp_int *rsa_em;
+	mp_int *rsa_em = NULL;
 	
 	TRACE(("enter buf_put_rsa_sign"));
 	assert(key != NULL);
 
 	rsa_em = rsa_pad_em(key, data, len);
 
+	m_mp_init(&rsa_s);
+
 	/* the actual signing of the padded data */
-	m_mp_init(&rsa_s);
 	/* s = em^d mod n */
 	if (mp_exptmod(rsa_em, key->d, key->n, &rsa_s) != MP_OKAY) {
 		dropbear_exit("rsa error");
@@ -322,10 +326,10 @@
 		{0x00, 0x30, 0x21, 0x30, 0x09, 0x06, 0x05, 0x2b, 
 		 0x0e, 0x03, 0x02, 0x1a, 0x05, 0x00, 0x04, 0x14};
 #define RSA_ASN1_MAGIC_LEN 16
-	buffer * rsa_EM;
+	buffer * rsa_EM = NULL;
 	hash_state hs;
 	unsigned int nsize;
-	mp_int * rsa_em;
+	mp_int * rsa_em = NULL;
 	
 	assert(key != NULL);
 	assert(data != NULL);
--- a/signkey.c	Thu Aug 12 15:41:36 2004 +0000
+++ b/signkey.c	Thu Aug 12 16:41:58 2004 +0000
@@ -194,7 +194,7 @@
 	buffer *pubkeys;
 
 	TRACE(("enter buf_put_pub_key"));
-	pubkeys = buf_new(1000);
+	pubkeys = buf_new(MAX_PUBKEY_SIZE);
 	
 #ifdef DROPBEAR_DSS
 	if (type == DROPBEAR_SIGNKEY_DSS) {
@@ -356,7 +356,7 @@
 
 	buffer *sigblob;
 
-	sigblob = buf_new(1000);
+	sigblob = buf_new(MAX_PUBKEY_SIZE);
 
 #ifdef DROPBEAR_DSS
 	if (type == DROPBEAR_SIGNKEY_DSS) {
--- a/svr-agentfwd.c	Thu Aug 12 15:41:36 2004 +0000
+++ b/svr-agentfwd.c	Thu Aug 12 16:41:58 2004 +0000
@@ -64,7 +64,7 @@
 
 	/* create the unix socket dir and file */
 	if (bindagent(fd, chansess) == DROPBEAR_FAILURE) {
-		return DROPBEAR_FAILURE;
+		goto fail;
 	}
 
 	/* listen */
@@ -146,7 +146,7 @@
 		chansess->agentlistener = NULL;
 	}
 
-	if (chansess->agentfile && chansess->agentdir) {
+	if (chansess->agentfile != NULL && chansess->agentdir != NULL) {
 
 		/* Remove the dir as the user. That way they can't cause problems except
 		 * for themselves */
--- a/svr-auth.c	Thu Aug 12 15:41:36 2004 +0000
+++ b/svr-auth.c	Thu Aug 12 16:41:58 2004 +0000
@@ -91,7 +91,7 @@
  * checking, and handle success or failure */
 void recv_msg_userauth_request() {
 
-	unsigned char *username, *servicename, *methodname;
+	unsigned char *username = NULL, *servicename = NULL, *methodname = NULL;
 	unsigned int userlen, servicelen, methodlen;
 
 	TRACE(("enter recv_msg_userauth_request"));
@@ -275,7 +275,7 @@
  * failures */
 void send_msg_userauth_failure(int partial, int incrfail) {
 
-	buffer *typebuf;
+	buffer *typebuf = NULL;
 
 	TRACE(("enter send_msg_userauth_failure"));
 
--- a/svr-authpasswd.c	Thu Aug 12 15:41:36 2004 +0000
+++ b/svr-authpasswd.c	Thu Aug 12 16:41:58 2004 +0000
@@ -37,14 +37,14 @@
 void svr_auth_password() {
 	
 #ifdef HAVE_SHADOW_H
-	struct spwd *spasswd;
+	struct spwd *spasswd = NULL;
 #endif
-	char * passwdcrypt; /* the crypt from /etc/passwd or /etc/shadow */
-	char * testcrypt; /* crypt generated from the user's password sent */
+	char * passwdcrypt = NULL; /* the crypt from /etc/passwd or /etc/shadow */
+	char * testcrypt = NULL; /* crypt generated from the user's password sent */
 	unsigned char * password;
 	unsigned int passwordlen;
 
-	unsigned char changepw;
+	unsigned int changepw;
 
 	passwdcrypt = ses.authstate.pw->pw_passwd;
 #ifdef HAVE_SHADOW_H
--- a/svr-authpubkey.c	Thu Aug 12 15:41:36 2004 +0000
+++ b/svr-authpubkey.c	Thu Aug 12 16:41:58 2004 +0000
@@ -53,7 +53,7 @@
 	unsigned char testkey; /* whether we're just checking if a key is usable */
 	unsigned char* algo = NULL; /* pubkey algo */
 	unsigned int algolen;
-	unsigned char* keyblob;
+	unsigned char* keyblob = NULL;
 	unsigned int keybloblen;
 	buffer * signbuf = NULL;
 	sign_key * key = NULL;
--- a/svr-chansession.c	Thu Aug 12 15:41:36 2004 +0000
+++ b/svr-chansession.c	Thu Aug 12 16:41:58 2004 +0000
@@ -273,7 +273,7 @@
  * or x11/authagent forwarding. These are passed to appropriate handlers */
 static void chansessionrequest(struct Channel *channel) {
 
-	unsigned char * type;
+	unsigned char * type = NULL;
 	unsigned int typelen;
 	unsigned char wantreply;
 	int ret = 1;
@@ -320,7 +320,7 @@
 out:
 
 	if (wantreply) {
-		if (ret == 0) {
+		if (ret == DROPBEAR_SUCCESS) {
 			send_msg_channel_success(channel);
 		} else {
 			send_msg_channel_failure(channel);
@@ -336,7 +336,7 @@
 static int sessionsignal(struct ChanSess *chansess) {
 
 	int sig = 0;
-	unsigned char* signame;
+	unsigned char* signame = NULL;
 	int i;
 
 	if (chansess->pid == 0) {
@@ -528,11 +528,14 @@
 		int iscmd, int issubsys) {
 
 	unsigned int cmdlen;
+	int ret;
 
 	TRACE(("enter sessioncommand"));
 
 	if (chansess->cmd != NULL) {
-		/* TODO - send error - multiple commands? */
+		/* Note that only one command can _succeed_. The client might try
+		 * one command (which fails), then try another. Ie fallback
+		 * from sftp to scp */
 		return DROPBEAR_FAILURE;
 	}
 
@@ -541,6 +544,7 @@
 		chansess->cmd = buf_getstring(ses.payload, &cmdlen);
 
 		if (cmdlen > MAX_CMD_LEN) {
+			m_free(chansess->cmd);
 			/* TODO - send error - too long ? */
 			return DROPBEAR_FAILURE;
 		}
@@ -552,6 +556,7 @@
 			} else 
 #endif
 			{
+				m_free(chansess->cmd);
 				return DROPBEAR_FAILURE;
 			}
 		}
@@ -559,11 +564,16 @@
 
 	if (chansess->term == NULL) {
 		/* no pty */
-		return noptycommand(channel, chansess);
+		ret = noptycommand(channel, chansess);
 	} else {
 		/* want pty */
-		 return ptycommand(channel, chansess);
+		ret = ptycommand(channel, chansess);
 	}
+
+	if (ret == DROPBEAR_FAILURE) {
+		m_free(chansess->cmd);
+	}
+	return ret;
 }
 
 /* Execute a command and set up redirection of stdin/stdout/stderr without a
@@ -650,7 +660,7 @@
 static int ptycommand(struct Channel *channel, struct ChanSess *chansess) {
 
 	pid_t pid;
-	struct logininfo *li;
+	struct logininfo *li = NULL;
 #ifdef DO_MOTD
 	buffer * motdbuf = NULL;
 	int len;
@@ -778,8 +788,8 @@
 static void execchild(struct ChanSess *chansess) {
 
 	char *argv[4];
-	char * usershell;
-	char * baseshell;
+	char * usershell = NULL;
+	char * baseshell = NULL;
 	unsigned int i;
 
 	/* wipe the hostkey */
@@ -863,6 +873,11 @@
 	agentset(chansess);
 #endif
 
+	/* Re-enable SIGPIPE for the executed process */
+	if (signal(SIGPIPE, SIG_DFL) == SIG_ERR) {
+		dropbear_exit("signal() error");
+	}
+
 	baseshell = basename(usershell);
 
 	if (chansess->cmd != NULL) {
@@ -921,7 +936,7 @@
 /* add a new environment variable, allocating space for the entry */
 void addnewvar(const char* param, const char* var) {
 
-	char* newvar;
+	char* newvar = NULL;
 	int plen, vlen;
 
 	plen = strlen(param);
--- a/svr-tcpfwd.c	Thu Aug 12 15:41:36 2004 +0000
+++ b/svr-tcpfwd.c	Thu Aug 12 16:41:58 2004 +0000
@@ -208,7 +208,7 @@
 	char portstring[NI_MAXSERV];
 	int sock;
 	int len;
-	int ret = DROPBEAR_FAILURE;
+	int err = SSH_OPEN_ADMINISTRATIVELY_PROHIBITED;
 
 	if (opts.nolocaltcp) {
 		TRACE(("leave newtcpdirect: local tcp forwarding disabled"));
@@ -240,6 +240,7 @@
 	snprintf(portstring, sizeof(portstring), "%d", destport);
 	sock = connect_remote(desthost, portstring, 1, NULL);
 	if (sock < 0) {
+		err = SSH_OPEN_CONNECT_FAILED;
 		TRACE(("leave newtcpdirect: sock failed"));
 		goto out;
 	}
@@ -253,13 +254,13 @@
 	channel->infd = sock;
 	channel->initconn = 1;
 	
-	ret = DROPBEAR_SUCCESS;
+	err = SSH_OPEN_IN_PROGRESS;
 
 out:
 	m_free(desthost);
 	m_free(orighost);
-	TRACE(("leave newtcpdirect: ret %d", ret));
-	return ret;
+	TRACE(("leave newtcpdirect: err %d", err));
+	return err;
 }
 
 #endif
--- a/svr-x11fwd.c	Thu Aug 12 15:41:36 2004 +0000
+++ b/svr-x11fwd.c	Thu Aug 12 16:41:58 2004 +0000
@@ -131,7 +131,7 @@
 void x11setauth(struct ChanSess *chansess) {
 
 	char display[20]; /* space for "localhost:12345.123" */
-	FILE * authprog;
+	FILE * authprog = NULL;
 	int val;
 
 	if (chansess->x11listener == NULL) {
@@ -187,7 +187,7 @@
 
 static int send_msg_channel_open_x11(int fd, struct sockaddr_in* addr) {
 
-	char* ipstring;
+	char* ipstring = NULL;
 
 	if (send_msg_channel_open_init(fd, &chan_x11) == DROPBEAR_SUCCESS) {
 		ipstring = inet_ntoa(addr->sin_addr);