summaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
-rw-r--r--buffer.c9
-rw-r--r--channel.h3
-rw-r--r--cli-tcpfwd.c9
-rw-r--r--common-channel.c27
-rw-r--r--configure.in2
-rw-r--r--dbutil.c6
-rw-r--r--debian/README.runit46
-rw-r--r--debian/changelog52
-rw-r--r--debian/control24
-rw-r--r--debian/copyright.in6
-rw-r--r--debian/dropbear.README.Debian41
-rw-r--r--debian/dropbear.conffiles3
-rw-r--r--debian/dropbear.docs3
-rw-r--r--debian/dropbear.init60
-rw-r--r--debian/dropbear.postinst68
-rw-r--r--debian/dropbear.postrm12
-rw-r--r--debian/dropbear.prerm11
-rw-r--r--debian/implicit79
-rw-r--r--debian/rules210
-rw-r--r--debian/service/log2
-rw-r--r--debian/service/run3
-rw-r--r--dropbearkey.c1
-rw-r--r--dss.c4
-rw-r--r--gendss.c1
-rw-r--r--includes.h6
-rw-r--r--options.h7
-rw-r--r--packet.c4
-rw-r--r--random.c5
-rw-r--r--rsa.c16
-rw-r--r--signkey.c4
-rw-r--r--svr-agentfwd.c4
-rw-r--r--svr-auth.c4
-rw-r--r--svr-authpasswd.c8
-rw-r--r--svr-authpubkey.c2
-rw-r--r--svr-chansession.c35
-rw-r--r--svr-tcpfwd.c9
-rw-r--r--svr-x11fwd.c4
37 files changed, 554 insertions, 236 deletions
diff --git a/buffer.c b/buffer.c
index 7181fca..df608d9 100644
--- a/buffer.c
+++ b/buffer.c
@@ -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 @@ void buf_burn(buffer* buf) {
}
-/* 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 @@ void buf_incrpos(buffer* buf, int incr) {
/* 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");
}
diff --git a/channel.h b/channel.h
index e1bdae2..2289de1 100644
--- a/channel.h
+++ b/channel.h
@@ -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 */
diff --git a/cli-tcpfwd.c b/cli-tcpfwd.c
index 52268b9..8d8e605 100644
--- a/cli-tcpfwd.c
+++ b/cli-tcpfwd.c
@@ -120,7 +120,7 @@ static int newtcpforwarded(struct Channel * channel) {
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 @@ static int newtcpforwarded(struct Channel * channel) {
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 @@ static int newtcpforwarded(struct Channel * channel) {
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;
}
diff --git a/common-channel.c b/common-channel.c
index 5079031..64ea466 100644
--- a/common-channel.c
+++ b/common-channel.c
@@ -172,6 +172,7 @@ void channelio(fd_set *readfd, fd_set *writefd) {
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 @@ void channelio(fd_set *readfd, fd_set *writefd) {
* 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 @@ void channelio(fd_set *readfd, fd_set *writefd) {
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 @@ static void checkinitdone(struct Channel *channel) {
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 @@ static void removechannel(struct Channel * channel) {
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 @@ static void removechannel(struct Channel * channel) {
if (channel->errfd >= 0) {
close(channel->errfd);
}
+ channel->typedata = NULL;
deletechannel(channel);
@@ -587,6 +600,7 @@ static void send_msg_channel_data(struct Channel *channel, int isextended,
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 @@ static void send_msg_channel_data(struct Channel *channel, int isextended,
buf_putstring(ses.writepayload, buf_getptr(buf, len), len);
buf_free(buf);
+ buf = NULL;
channel->transwindow -= len;
@@ -764,6 +779,10 @@ void recv_msg_channel_open() {
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));
diff --git a/configure.in b/configure.in
index bffd0da..10988c2 100644
--- a/configure.in
+++ b/configure.in
@@ -169,7 +169,7 @@ AC_ARG_ENABLE(shadow,
# 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
diff --git a/dbutil.c b/dbutil.c
index 5436cbb..30b5708 100644
--- a/dbutil.c
+++ b/dbutil.c
@@ -121,7 +121,7 @@ void dropbear_trace(const char* format, ...) {
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 @@ int connect_remote(const char* remotehost, const char* remoteport,
}
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 @@ int connect_remote(const char* remotehost, const char* remoteport,
break; /* Success */
}
- if (sock < 0) {
+ if (sock < 0 && !(errno == EINPROGRESS && nonblocking)) {
/* Failed */
if (errstring != NULL && *errstring == NULL) {
int len;
diff --git a/debian/README.runit b/debian/README.runit
new file mode 100644
index 0000000..4ac2814
--- /dev/null
+++ b/debian/README.runit
@@ -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 <pape@smarden.org>, Sun, 16 May 2004 15:52:34 +0000
diff --git a/debian/changelog b/debian/changelog
index cb7253f..d9da388 100644
--- a/debian/changelog
+++ b/debian/changelog
@@ -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 <matt@ucc.asn.au> Fri, 16 July 2004 17:44:54 +0800
+
+dropbear (0.42-1) unstable; urgency=low
+
+ * New upstream release 0.42
+
+ -- Matt Johnston <matt@ucc.asn.au> 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 <pape@smarden.org> 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 <pape@smarden.org> Sun, 16 May 2004 16:50:55 +0000
+
dropbear (0.41-1) unstable; urgency=low
* Updated to 0.41 release.
diff --git a/debian/control b/debian/control
index e528454..33c717c 100644
--- a/debian/control
+++ b/debian/control
@@ -1,14 +1,20 @@
Source: dropbear
Section: net
-Priority: standard
-Maintainer: Grahame Bowland <grahame@angrygoats.net>
-Build-Depends: debhelper (>> 4.0.0), zlib1g-dev
-Standards-Version: 3.5.8
+Priority: optional
+Maintainer: Gerrit Pape <pape@smarden.org>
+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
diff --git a/debian/copyright.in b/debian/copyright.in
index 015d9ab..79526d3 100644
--- a/debian/copyright.in
+++ b/debian/copyright.in
@@ -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
+<matt@ucc.asn.au>, and was adopted by Gerrit Pape <pape@smarden.org> on
+Sun, 16 May 2004 14:38:33 +0000.
It was downloaded from http://matt.ucc.asn.au/dropbear/
-Upstream Author(s): Matt Johnston <matt@ucc.asn.au>
+Upstream Author: Matt Johnston <matt@ucc.asn.au>
Copyright:
diff --git a/debian/dropbear.README.Debian b/debian/dropbear.README.Debian
new file mode 100644
index 0000000..8cdac38
--- /dev/null
+++ b/debian/dropbear.README.Debian
@@ -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
+
diff --git a/debian/dropbear.conffiles b/debian/dropbear.conffiles
new file mode 100644
index 0000000..6919006
--- /dev/null
+++ b/debian/dropbear.conffiles
@@ -0,0 +1,3 @@
+/etc/init.d/dropbear
+/etc/dropbear/run
+/etc/dropbear/log/run
diff --git a/debian/dropbear.docs b/debian/dropbear.docs
new file mode 100644
index 0000000..599d48c
--- /dev/null
+++ b/debian/dropbear.docs
@@ -0,0 +1,3 @@
+README
+TODO
+debian/README.runit
diff --git a/debian/dropbear.init b/debian/dropbear.init
index 25eda9f..d9578db 100644
--- a/debian/dropbear.init
+++ b/debian/dropbear.init
@@ -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 <miquels@cistron.nl>.
-# Modified for Debian
-# by Ian Murdock <imurdock@gnu.ai.mit.edu>.
-#
-# Version: @(#)skeleton 1.9 26-Feb-2001 miquels@cistron.nl
-#
-
+#!/bin/sh
#
# Do not configure this file. Edit /etc/default/dropbear instead!
#
@@ -22,54 +11,45 @@ DESC="Dropbear SSH server"
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
-
-if [ -z "$DROPBEAR_DSSKEY" ]; then
- DROPBEAR_DSSKEY="/etc/dropbear/dropbear_dss_host_key"
-fi
+set -e
-test "$NO_START" != "0" && exit 0
+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
-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
;;
diff --git a/debian/dropbear.postinst b/debian/dropbear.postinst
new file mode 100644
index 0000000..749ffd1
--- /dev/null
+++ b/debian/dropbear.postinst
@@ -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
diff --git a/debian/dropbear.postrm b/debian/dropbear.postrm
new file mode 100644
index 0000000..d09dab0
--- /dev/null
+++ b/debian/dropbear.postrm
@@ -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
diff --git a/debian/dropbear.prerm b/debian/dropbear.prerm
new file mode 100644
index 0000000..89bb5b6
--- /dev/null
+++ b/debian/dropbear.prerm
@@ -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
diff --git a/debian/implicit b/debian/implicit
new file mode 100644
index 0000000..d28b629
--- /dev/null
+++ b/debian/implicit
@@ -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
diff --git a/debian/rules b/debian/rules
index 4d73093..ee7b14a 100644
--- a/debian/rules
+++ b/debian/rules
@@ -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
+#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)
-# 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
+STRIP =strip
+ifneq (,$(findstring nostrip,$(DEB_BUILD_OPTIONS)))
+ STRIP =: nostrip
+endif
+CFLAGS =-Wall -g
ifneq (,$(findstring noopt,$(DEB_BUILD_OPTIONS)))
- CFLAGS += -O0
+ CFLAGS +=-O0
else
- CFLAGS += -O2
-endif
-ifeq (,$(findstring nostrip,$(DEB_BUILD_OPTIONS)))
- INSTALL_PROGRAM += -s
+ CFLAGS +=-O2
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
-
-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
-
-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
-
-install-arch:
- dh_testdir
- dh_testroot
- dh_clean -k -a
- dh_installdirs -a
- dh_installdirs /etc/dropbear
-
- # Add here commands to install the arch part of the package into
- # debian/tmp.
- $(MAKE) install prefix=$(CURDIR)/debian/dropbear/usr
-
- 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
-
-# Build architecture dependant packages using the common target.
-binary-arch: build-arch install-arch
- $(MAKE) -f debian/rules DH_OPTIONS=-a binary-common
-
-binary: binary-arch #binary-indep
-.PHONY: build clean binary-indep binary-arch binary install install-indep install-arch
+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
+
+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
+
+build: deb-checkdir build-stamp
+build-stamp: config.status
+ $(MAKE) CC="$(CC)" LD="$(CC)"
+ touch build-stamp
+
+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
+
+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
+
+binary-indep:
+
+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
diff --git a/debian/service/log b/debian/service/log
new file mode 100644
index 0000000..2ffb13d
--- /dev/null
+++ b/debian/service/log
@@ -0,0 +1,2 @@
+#!/bin/sh
+exec chpst -udropbearlog svlogd -tt ./main
diff --git a/debian/service/run b/debian/service/run
new file mode 100644
index 0000000..f208085
--- /dev/null
+++ b/debian/service/run
@@ -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
diff --git a/dropbearkey.c b/dropbearkey.c
index eac0823..5d4475b 100644
--- a/dropbearkey.c
+++ b/dropbearkey.c
@@ -45,7 +45,6 @@
*
*/
#include "includes.h"
-#include "runopts.h"
#include "signkey.h"
#include "buffer.h"
#include "dbutil.h"
diff --git a/dss.c b/dss.c
index 74b92c7..9b56f10 100644
--- a/dss.c
+++ b/dss.c
@@ -171,6 +171,8 @@ int buf_dss_verify(buffer* buf, dss_key *key, const unsigned char* data,
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 @@ int buf_dss_verify(buffer* buf, dss_key *key, const unsigned char* data,
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' */
diff --git a/gendss.c b/gendss.c
index 3e9db09..5a440a1 100644
--- a/gendss.c
+++ b/gendss.c
@@ -31,7 +31,6 @@
#include "gendss.h"
#include "dss.h"
-#define PSIZE 128 /* 1024 bit*/
#define QSIZE 20 /* 160 bit */
#ifdef DROPBEAR_DSS
diff --git a/includes.h b/includes.h
index 52c48ed..b37422b 100644
--- a/includes.h
+++ b/includes.h
@@ -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"
diff --git a/options.h b/options.h
index f0831b9..c687a8c 100644
--- a/options.h
+++ b/options.h
@@ -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
diff --git a/packet.c b/packet.c
index 997bc6f..5e8e14d 100644
--- a/packet.c
+++ b/packet.c
@@ -50,7 +50,7 @@ static void buf_compress(buffer * dest, buffer * src, unsigned int len);
void write_packet() {
int len, written;
- buffer * writebuf;
+ buffer * writebuf = NULL;
TRACE(("enter write_packet"));
assert(!isempty(&ses.writequeue));
@@ -80,6 +80,7 @@ void write_packet() {
/* 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 @@ void encrypt_packet() {
/* clearwritebuf is finished with */
buf_free(clearwritebuf);
+ clearwritebuf = NULL;
/* enqueue the packet for sending */
buf_setpos(writebuf, 0);
diff --git a/random.c b/random.c
index 725b29c..65a9c64 100644
--- a/random.c
+++ b/random.c
@@ -60,7 +60,7 @@ static void readrand(unsigned char* buf, unsigned int buflen) {
#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 @@ static void readrand(unsigned char* buf, unsigned int buflen) {
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 */
diff --git a/rsa.c b/rsa.c
index 2d63c02..1130e93 100644
--- a/rsa.c
+++ b/rsa.c
@@ -244,8 +244,11 @@ int buf_rsa_verify(buffer * buf, rsa_key *key, const unsigned char* data,
}
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 @@ void buf_put_rsa_sign(buffer* buf, rsa_key *key, const unsigned char* data,
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);
- /* the actual signing of the padded data */
m_mp_init(&rsa_s);
+
+ /* the actual signing of the padded data */
/* 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 @@ static mp_int * rsa_pad_em(rsa_key * key,
{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);
diff --git a/signkey.c b/signkey.c
index 3efcc2b..7ae08b8 100644
--- a/signkey.c
+++ b/signkey.c
@@ -194,7 +194,7 @@ void buf_put_pub_key(buffer* buf, sign_key *key, int type) {
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 @@ void buf_put_sign(buffer* buf, sign_key *key, int type,
buffer *sigblob;
- sigblob = buf_new(1000);
+ sigblob = buf_new(MAX_PUBKEY_SIZE);
#ifdef DROPBEAR_DSS
if (type == DROPBEAR_SIGNKEY_DSS) {
diff --git a/svr-agentfwd.c b/svr-agentfwd.c
index b588586..4e9aa56 100644
--- a/svr-agentfwd.c
+++ b/svr-agentfwd.c
@@ -64,7 +64,7 @@ int agentreq(struct ChanSess * chansess) {
/* create the unix socket dir and file */
if (bindagent(fd, chansess) == DROPBEAR_FAILURE) {
- return DROPBEAR_FAILURE;
+ goto fail;
}
/* listen */
@@ -146,7 +146,7 @@ void agentcleanup(struct ChanSess * chansess) {
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 */
diff --git a/svr-auth.c b/svr-auth.c
index 314171f..ae7ead2 100644
--- a/svr-auth.c
+++ b/svr-auth.c
@@ -91,7 +91,7 @@ static void send_msg_userauth_banner() {
* 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 @@ goodshell:
* failures */
void send_msg_userauth_failure(int partial, int incrfail) {
- buffer *typebuf;
+ buffer *typebuf = NULL;
TRACE(("enter send_msg_userauth_failure"));
diff --git a/svr-authpasswd.c b/svr-authpasswd.c
index 7c6c7b7..6f7c909 100644
--- a/svr-authpasswd.c
+++ b/svr-authpasswd.c
@@ -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
diff --git a/svr-authpubkey.c b/svr-authpubkey.c
index 9205078..14b5a78 100644
--- a/svr-authpubkey.c
+++ b/svr-authpubkey.c
@@ -53,7 +53,7 @@ void svr_auth_pubkey() {
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;
diff --git a/svr-chansession.c b/svr-chansession.c
index a0e877c..01612f4 100644
--- a/svr-chansession.c
+++ b/svr-chansession.c
@@ -273,7 +273,7 @@ static void closechansess(struct Channel *channel) {
* 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 @@ static void chansessionrequest(struct Channel *channel) {
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 @@ out:
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 @@ static int sessioncommand(struct Channel *channel, struct ChanSess *chansess,
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 @@ static int sessioncommand(struct Channel *channel, struct ChanSess *chansess,
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 @@ static int sessioncommand(struct Channel *channel, struct ChanSess *chansess,
} else
#endif
{
+ m_free(chansess->cmd);
return DROPBEAR_FAILURE;
}
}
@@ -559,11 +564,16 @@ static int sessioncommand(struct Channel *channel, struct ChanSess *chansess,
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 noptycommand(struct Channel *channel, struct ChanSess *chansess) {
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 addchildpid(struct ChanSess *chansess, pid_t pid) {
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 @@ static void execchild(struct ChanSess *chansess) {
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 @@ void svr_chansessinitialise() {
/* 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);
diff --git a/svr-tcpfwd.c b/svr-tcpfwd.c
index 0eccae4..0f22a23 100644
--- a/svr-tcpfwd.c
+++ b/svr-tcpfwd.c
@@ -208,7 +208,7 @@ static int newtcpdirect(struct Channel * channel) {
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 @@ static int newtcpdirect(struct Channel * channel) {
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 @@ static int newtcpdirect(struct Channel * channel) {
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
diff --git a/svr-x11fwd.c b/svr-x11fwd.c
index 0f4f71e..a8d1cd5 100644
--- a/svr-x11fwd.c
+++ b/svr-x11fwd.c
@@ -131,7 +131,7 @@ static void x11accept(struct Listener* listener, int sock) {
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 const struct ChanType chan_x11 = {
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);