summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMatt Johnston <matt@ucc.asn.au>2013-10-20 21:07:05 +0800
committerMatt Johnston <matt@ucc.asn.au>2013-10-20 21:07:05 +0800
commit86122772ba844bc9cff67396ed68e6c71b9490f8 (patch)
treed047e86b7978c2e48f749ecb005a33fd8af3a4d0
parent27c6967547013c03024153fbbbbbb42f5f6bd807 (diff)
parent89d87577014cbc02a0e755bd1158005a5dbe0ada (diff)
downloaddropbear-86122772ba844bc9cff67396ed68e6c71b9490f8.tar.gz
merge
-rw-r--r--.hgsigs3
-rw-r--r--CHANGES50
-rw-r--r--LICENSE2
-rw-r--r--MULTI4
-rw-r--r--Makefile.in42
-rw-r--r--README2
-rw-r--r--auth.h1
-rw-r--r--cli-chansession.c4
-rw-r--r--cli-runopts.c7
-rw-r--r--common-channel.c5
-rw-r--r--configure.ac18
-rw-r--r--dbclient.111
-rw-r--r--dbutil.c13
-rw-r--r--dbutil.h3
-rw-r--r--debian/changelog13
-rwxr-xr-xdebian/rules19
-rw-r--r--dropbear.813
-rw-r--r--dropbearconvert.150
-rw-r--r--dropbearkey.1 (renamed from dropbearkey.8)13
-rw-r--r--packet.c2
-rw-r--r--random.c13
-rw-r--r--svr-auth.c63
-rw-r--r--svr-authpam.c24
-rw-r--r--svr-authpasswd.c13
-rw-r--r--svr-chansession.c2
-rw-r--r--sysoptions.h2
26 files changed, 282 insertions, 110 deletions
diff --git a/.hgsigs b/.hgsigs
index 5c5eb40..79b9f6f 100644
--- a/.hgsigs
+++ b/.hgsigs
@@ -4,3 +4,6 @@ aa2f51a6b81d33de5e9898a7f27c792a173d9b26 0 iD8DBQBOuADmjPn4sExkf7wRAv/fAJ9FJFvjD
9b80981212fe6c01b7c16b3ca7c4e66af56f12f1 0 iEYEABECAAYFAlFLKKcACgkQjPn4sExkf7xK7wCfcioCmJPsysSbQO6+4qZMVe0mmLwAn2/o+wRf4MrUXlohrr7aXEF9vdSB
095b46180bbc412b029420587736a6185afc17e1 0 iEYEABECAAYFAlFsCnkACgkQjPn4sExkf7xLrwCfeMWjUaSmfU/fvseT5TdrYRqBEVQAoLz5SFLEA40C5f8zE8Ma/vgVJVIC
f168962bab857ca030829e4cd73d9b32c868c874 0 iEYEABECAAYFAlFwDNwACgkQjPn4sExkf7wJ6QCePVovn/avKXUyNwNBYCcov6JLYqkAnRCPQdkXgv20N3t10r6PRMBBo1/S
+deb211f75ca194e2fcf0d2e5f71c60474e42ec95 0 iEYEABECAAYFAlJO01cACgkQjPn4sExkf7yDqACaA/P+Yl/K2Cv3OC5G0b7ck2Kb75EAoIeW7qpCyclzJLWwk95koED+4lxD
+025237c9f0a1a60a616f984d82fb2a9270d3b0ea 0 iEYEABECAAYFAlJeqDYACgkQjPn4sExkf7y5nQCfW6t+TJySBTTo+gCfDUBPRVxvNe8AoIn/15aWfqH/A2G9uikfoVtWK3pd
+a50a1dc743317fad9b3737bc68fbca640659bb6d 0 iEYEABECAAYFAlJeqL0ACgkQjPn4sExkf7yVqACg6IP0fU29+Feh/TDeemDA+2XAzrIAoIdZfMDvVYlDoWotZD8ACFnf5H1P
diff --git a/CHANGES b/CHANGES
index 65d237b..c9a7eda 100644
--- a/CHANGES
+++ b/CHANGES
@@ -1,3 +1,45 @@
+2013.60 - Wednesday 16 October 2013
+
+- Fix "make install" so that it doesn't always install to /bin and /sbin
+
+- Fix "make install MULTI=1", installing manpages failed
+
+- Fix "make install" when scp is included since it has no manpage
+
+- Make --disable-bundled-libtom work
+
+2013.59 - Friday 4 October 2013
+
+- Fix crash from -J command
+ Thanks to LluĂ­s Batlle i Rossell and Arnaud Mouiche for patches
+
+- Avoid reading too much from /proc/net/rt_cache since that causes
+ system slowness.
+
+- Improve EOF handling for half-closed connections
+ Thanks to Catalin Patulea
+
+- Send a banner message to report PAM error messages intended for the user
+ Patch from Martin Donnelly
+
+- Limit the size of decompressed payloads, avoids memory exhaustion denial
+ of service
+ Thanks to Logan Lamb for reporting and investigating it. CVE-2013-4421
+
+- Avoid disclosing existence of valid users through inconsistent delays
+ Thanks to Logan Lamb for reporting. CVE-2013-4434
+
+- Update config.guess and config.sub for newer architectures
+
+- Avoid segfault in server for locked accounts
+
+- "make install" now installs manpages
+ dropbearkey.8 has been renamed to dropbearkey.1
+ manpage added for dropbearconvert
+
+- Get rid of one second delay when running non-interactive commands
+
+
2013.58 - Thursday 18 April 2013
- Fix building with Zlib disabled, thanks to Hans Harder and cuma@freetz
@@ -286,7 +328,7 @@ https://secure.ucc.asn.au/hg/dropbear/graph/default
- Security: dbclient previously would prompt to confirm a
mismatching hostkey but wouldn't warn loudly. It will now
- exit upon a mismatch.
+ exit upon a mismatch. CVE-2007-1099
- Compile fixes, make sure that all variable definitions are at the start
of a scope.
@@ -348,7 +390,7 @@ https://secure.ucc.asn.au/hg/dropbear/graph/default
(thanks to Tomas Vanek for helping track it down)
- Implement per-IP pre-authentication connection limits
- (after some poking from Pablo Fernandez)
+ (after some poking from Pablo Fernandez) CVE-2006-1206
- Exit gracefully if trying to connect to as SSH v1 server
(reported by Rushi Lala)
@@ -369,7 +411,7 @@ https://secure.ucc.asn.au/hg/dropbear/graph/default
- SECURITY: fix for buffer allocation error in server code, could potentially
allow authenticated users to gain elevated privileges. All multi-user systems
running the server should upgrade (or apply the patch available on the
- Dropbear webpage).
+ Dropbear webpage). CVE-2005-4178
- Fix channel handling code so that redirecting to /dev/null doesn't use
100% CPU.
@@ -576,7 +618,7 @@ https://secure.ucc.asn.au/hg/dropbear/graph/default
- SECURITY: Don't try to free() uninitialised variables in DSS verification
code. Thanks to Arne Bernin for pointing out this bug. This is possibly
exploitable, all users with DSS and pubkey-auth compiled in are advised to
- upgrade.
+ upgrade. CVE-2004-2486
- Clean up agent forwarding socket files correctly, patch from Gerrit Pape.
diff --git a/LICENSE b/LICENSE
index ba11d4f..65af084 100644
--- a/LICENSE
+++ b/LICENSE
@@ -8,7 +8,7 @@ The majority of code is written by Matt Johnston, under the license below.
Portions of the client-mode work are (c) 2004 Mihnea Stoenescu, under the
same license:
-Copyright (c) 2002-2008 Matt Johnston
+Copyright (c) 2002-2013 Matt Johnston
Portions copyright (c) 2004 Mihnea Stoenescu
All rights reserved.
diff --git a/MULTI b/MULTI
index a50e30e..606f815 100644
--- a/MULTI
+++ b/MULTI
@@ -20,7 +20,3 @@ etc
then execute as normal:
./dropbear <options here>
-
-"make install" doesn't currently work for multi-binary configuration, though
-in most situations where it is being used, the target and build systems will
-differ.
diff --git a/Makefile.in b/Makefile.in
index 4f13d1d..fa88f61 100644
--- a/Makefile.in
+++ b/Makefile.in
@@ -67,9 +67,11 @@ VPATH=@srcdir@
srcdir=@srcdir@
prefix=@prefix@
-exec_prefix=${prefix}
-bindir=${exec_prefix}/bin
-sbindir=${exec_prefix}/sbin
+exec_prefix=@exec_prefix@
+datarootdir = @datarootdir@
+bindir=@bindir@
+sbindir=@sbindir@
+mandir=@mandir@
CC=@CC@
AR=@AR@
@@ -121,36 +123,34 @@ strip: $(TARGETS)
install: $(addprefix inst_, $(TARGETS))
-installdropbearmulti: insdbmulti $(addprefix insmulti, $(PROGRAMS))
-
-insdbmulti: dropbearmulti
- $(INSTALL) -d -m 755 $(DESTDIR)$(bindir)
- $(INSTALL) -m 755 dropbearmulti$(EXEEXT) $(DESTDIR)$(bindir)
- -chown root $(DESTDIR)$(bindir)/dropbearmulti$(EXEEXT)
- -chgrp 0 $(DESTDIR)$(bindir)/dropbearmulti$(EXEEXT)
-
insmultidropbear: dropbearmulti
- $(INSTALL) -d -m 755 $(DESTDIR)$(sbindir)
+ $(INSTALL) -d $(DESTDIR)$(sbindir)
-rm -f $(DESTDIR)$(sbindir)/dropbear$(EXEEXT)
-ln -s $(bindir)/dropbearmulti$(EXEEXT) $(DESTDIR)$(sbindir)/dropbear$(EXEEXT)
+ $(INSTALL) -d $(DESTDIR)$(mandir)/man8
+ $(INSTALL) -m 644 dropbear.8 $(DESTDIR)$(mandir)/man8/dropbear.8
insmulti%: dropbearmulti
- $(INSTALL) -d -m 755 $(DESTDIR)$(bindir)
+ $(INSTALL) -d $(DESTDIR)$(bindir)
-rm -f $(DESTDIR)$(bindir)/$*$(EXEEXT)
-ln -s $(bindir)/dropbearmulti$(EXEEXT) $(DESTDIR)$(bindir)/$*$(EXEEXT)
+ $(INSTALL) -d $(DESTDIR)$(mandir)/man1
+ $(INSTALL) -m 644 $*.1 $(DESTDIR)$(mandir)/man1/$*.1
# dropbear should go in sbin, so it needs a seperate rule
inst_dropbear: dropbear
- $(INSTALL) -d -m 755 $(DESTDIR)$(sbindir)
- $(INSTALL) -m 755 dropbear$(EXEEXT) $(DESTDIR)$(sbindir)
- -chown root $(DESTDIR)$(sbindir)/dropbear$(EXEEXT)
- -chgrp 0 $(DESTDIR)$(sbindir)/dropbear$(EXEEXT)
+ $(INSTALL) -d $(DESTDIR)$(sbindir)
+ $(INSTALL) dropbear$(EXEEXT) $(DESTDIR)$(sbindir)
+ $(INSTALL) -d $(DESTDIR)$(mandir)/man8
+ $(INSTALL) -m 644 dropbear.8 $(DESTDIR)$(mandir)/man8/dropbear.8
inst_%: $*
- $(INSTALL) -d -m 755 $(DESTDIR)$(bindir)
- $(INSTALL) -m 755 $*$(EXEEXT) $(DESTDIR)$(bindir)
- -chown root $(DESTDIR)$(bindir)/$*$(EXEEXT)
- -chgrp 0 $(DESTDIR)$(bindir)/$*$(EXEEXT)
+ $(INSTALL) -d $(DESTDIR)$(bindir)
+ $(INSTALL) $*$(EXEEXT) $(DESTDIR)$(bindir)
+ $(INSTALL) -d $(DESTDIR)$(mandir)/man1
+ if test -e $*.1; then $(INSTALL) -m 644 $*.1 $(DESTDIR)$(mandir)/man1/$*.1; fi
+
+inst_dropbearmulti: $(addprefix insmulti, $(PROGRAMS))
# for some reason the rule further down doesn't like $($@objs) as a prereq.
diff --git a/README b/README
index a8ebda3..b569283 100644
--- a/README
+++ b/README
@@ -1,4 +1,4 @@
-This is Dropbear, a smallish SSH 2 server and client.
+This is Dropbear, a smallish SSH server and client.
https://matt.ucc.asn.au/dropbear/dropbear.html
INSTALL has compilation instructions.
diff --git a/auth.h b/auth.h
index df6634e..3aed57b 100644
--- a/auth.h
+++ b/auth.h
@@ -36,6 +36,7 @@ void cli_authinitialise();
void recv_msg_userauth_request();
void send_msg_userauth_failure(int partial, int incrfail);
void send_msg_userauth_success();
+void send_msg_userauth_banner(buffer *msg);
void svr_auth_password();
void svr_auth_pubkey();
void svr_auth_pam();
diff --git a/cli-chansession.c b/cli-chansession.c
index 37aa13d..b30fe43 100644
--- a/cli-chansession.c
+++ b/cli-chansession.c
@@ -71,7 +71,9 @@ static void cli_chansessreq(struct Channel *channel) {
TRACE(("got exit-signal, ignoring it"))
} else {
TRACE(("unknown request '%s'", type))
- send_msg_channel_failure(channel);
+ if (wantreply) {
+ send_msg_channel_failure(channel);
+ }
goto out;
}
diff --git a/cli-runopts.c b/cli-runopts.c
index 91a2f42..b8d304f 100644
--- a/cli-runopts.c
+++ b/cli-runopts.c
@@ -383,6 +383,13 @@ void cli_getopts(int argc, char ** argv) {
exit(EXIT_FAILURE);
}
+#ifdef ENABLE_CLI_PROXYCMD
+ if (cli_opts.proxycmd) {
+ /* To match the common path of m_freeing it */
+ cli_opts.proxycmd = m_strdup(cli_opts.proxycmd);
+ }
+#endif
+
if (cli_opts.remoteport == NULL) {
cli_opts.remoteport = "22";
}
diff --git a/common-channel.c b/common-channel.c
index 8b7369c..2068904 100644
--- a/common-channel.c
+++ b/common-channel.c
@@ -307,7 +307,9 @@ static void check_close(struct Channel *channel) {
return;
}
- if (channel->recv_eof && !write_pending(channel)) {
+ if ((channel->recv_eof && !write_pending(channel))
+ /* have a server "session" and child has exited */
+ || (channel->type->check_close && close_allowed)) {
close_chan_fd(channel, channel->writefd, SHUT_WR);
}
@@ -336,6 +338,7 @@ static void check_close(struct Channel *channel) {
/* And if we can't receive any more data from them either, close up */
if (channel->readfd == FD_CLOSED
+ && channel->writefd == FD_CLOSED
&& (ERRFD_IS_WRITE(channel) || channel->errfd == FD_CLOSED)
&& !channel->sent_close
&& close_allowed
diff --git a/configure.ac b/configure.ac
index 6f82450..e5bbaf9 100644
--- a/configure.ac
+++ b/configure.ac
@@ -364,10 +364,20 @@ AC_CHECK_FUNCS(setutxent utmpxname)
AC_CHECK_FUNCS(logout updwtmp logwtmp)
AC_ARG_ENABLE(bundled-libtom,
- [ --enable-bundled-libtom Use bundled libtomcrypt/libtommath even if a system version exists],
- [
- BUNDLED_LIBTOM=1
- AC_MSG_NOTICE(Forcing bundled libtom*)
+[ --enable-bundled-libtom Force using bundled libtomcrypt/libtommath even if a system version exists.
+ --disable-bundled-libtom Force using system libtomcrypt/libtommath, fail if it does not exist.
+ Default is to use system if available, otherwise bundled.],
+ [
+ if test "x$enableval" = "xyes"; then
+ BUNDLED_LIBTOM=1
+ AC_MSG_NOTICE(Forcing bundled libtom*)
+ else
+ BUNDLED_LIBTOM=0
+ AC_CHECK_LIB(tomcrypt, register_cipher, ,
+ [AC_MSG_ERROR([Missing system libtomcrypt and --disable-bundled-libtom was specified])] )
+ AC_CHECK_LIB(tommath, mp_exptmod, ,
+ [AC_MSG_ERROR([Missing system libtomcrypt and --disable-bundled-libtom was specified])] )
+ fi
],
[
BUNDLED_LIBTOM=0
diff --git a/dbclient.1 b/dbclient.1
index 7ad550f..4839982 100644
--- a/dbclient.1
+++ b/dbclient.1
@@ -1,6 +1,6 @@
.TH dbclient 1
.SH NAME
-dbclient \- lightweight SSH2 client
+dbclient \- lightweight SSH client
.SH SYNOPSIS
.B dbclient
[\-Tt] [\-p
@@ -19,7 +19,7 @@ dbclient \- lightweight SSH2 client
.SH DESCRIPTION
.B dbclient
-is a SSH 2 client designed to be small enough to be used in small memory
+is a SSH client designed to be small enough to be used in small memory
environments, while still being functional and secure enough for general use.
.SH OPTIONS
.TP
@@ -31,9 +31,10 @@ Default is 22.
.TP
.B \-i \fIidfile
Identity file.
-Read the identity from file
+Read the identity key from file
.I idfile
-(multiple allowed).
+(multiple allowed). This file is created with dropbearkey(1) or converted
+from OpenSSH with dropbearconvert(1).
.TP
.B \-L [\fIlistenaddress\fR]:\fIlistenport\fR:\fIhost\fR:\fIport\fR
Local port forwarding.
@@ -161,6 +162,6 @@ Mihnea Stoenescu wrote initial Dropbear client support
.br
Gerrit Pape (pape@smarden.org) wrote this manual page.
.SH SEE ALSO
-dropbear(8), dropbearkey(8)
+dropbear(8), dropbearkey(1)
.P
https://matt.ucc.asn.au/dropbear/dropbear.html
diff --git a/dbutil.c b/dbutil.c
index bdeb10c..b194e3d 100644
--- a/dbutil.c
+++ b/dbutil.c
@@ -892,3 +892,16 @@ int m_str_to_uint(const char* str, unsigned int *val) {
return DROPBEAR_SUCCESS;
}
}
+
+int constant_time_memcmp(const void* a, const void *b, size_t n)
+{
+ const char *xa = a, *xb = b;
+ uint8_t c = 0;
+ size_t i;
+ for (i = 0; i < n; i++)
+ {
+ c |= (xa[i] ^ xb[i]);
+ }
+ return c;
+}
+
diff --git a/dbutil.h b/dbutil.h
index e13ed13..7c7435c 100644
--- a/dbutil.h
+++ b/dbutil.h
@@ -95,4 +95,7 @@ int m_str_to_uint(const char* str, unsigned int *val);
/* Dropbear assertion */
#define dropbear_assert(X) do { if (!(X)) { fail_assert(#X, __FILE__, __LINE__); } } while (0)
+/* Returns 0 if a and b have the same contents */
+int constant_time_memcmp(const void* a, const void *b, size_t n);
+
#endif /* _DBUTIL_H_ */
diff --git a/debian/changelog b/debian/changelog
index d6aeeb8..cc869f5 100644
--- a/debian/changelog
+++ b/debian/changelog
@@ -1,3 +1,16 @@
+dropbear (2013.60-0.1) unstable; urgency=low
+
+ * New upstream release.
+
+ -- Matt Johnston <matt@ucc.asn.au> Wed, 16 Oct 2013 22:54:00 +0800
+
+dropbear (2013.59-0.1) unstable; urgency=low
+
+ * New upstream release.
+ * Build with DEB_BUILD_MAINT_OPTIONS = hardening=+all
+
+ -- Matt Johnston <matt@ucc.asn.au> Fri, 4 Oct 2013 22:54:00 +0800
+
dropbear (2013.58-0.1) unstable; urgency=low
* New upstream release.
diff --git a/debian/rules b/debian/rules
index 605754e..c6b2e85 100755
--- a/debian/rules
+++ b/debian/rules
@@ -1,5 +1,9 @@
#!/usr/bin/make -f
+export DEB_BUILD_MAINT_OPTIONS = hardening=+all
+DPKG_EXPORT_BUILDFLAGS = 1
+include /usr/share/dpkg/buildflags.mk
+
#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)
@@ -9,13 +13,6 @@ ifneq (,$(findstring nostrip,$(DEB_BUILD_OPTIONS)))
STRIP =: nostrip
endif
-CFLAGS =-Wall -g
-ifneq (,$(findstring noopt,$(DEB_BUILD_OPTIONS)))
- CFLAGS +=-O0
-else
- CFLAGS +=-O2
-endif
-
CONFFLAGS =
CC =gcc
ifneq (,$(findstring diet,$(DEB_BUILD_OPTIONS)))
@@ -79,12 +76,12 @@ install: deb-checkdir deb-checkuid build-stamp
ln -s /var/log/dropbear '$(DIR)'/etc/dropbear/log/main
# 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; \
+ install -d -m0755 '$(DIR)'/usr/share/man/man1
+ install -m644 dropbear.8 '$(DIR)'/usr/share/man/man8/
+ for i in dbclient.1 dropbearkey.1 dropbearconvert.1; do \
+ install -m644 $$i '$(DIR)'/usr/share/man/man1/ || exit 1; \
done
gzip -9 '$(DIR)'/usr/share/man/man8/*.8
- install -d -m0755 '$(DIR)'/usr/share/man/man1
- install -m644 dbclient.1 '$(DIR)'/usr/share/man/man1/
gzip -9 '$(DIR)'/usr/share/man/man1/*.1
# copyright, changelog
cat debian/copyright.in LICENSE >debian/copyright
diff --git a/dropbear.8 b/dropbear.8
index cdcfb0b..f1ad576 100644
--- a/dropbear.8
+++ b/dropbear.8
@@ -1,6 +1,6 @@
.TH dropbear 8
.SH NAME
-dropbear \- lightweight SSH2 server
+dropbear \- lightweight SSH server
.SH SYNOPSIS
.B dropbear
[\-FEmwsgjki] [\-b
@@ -10,7 +10,7 @@ dropbear \- lightweight SSH2 server
.IR [address:]port ]
.SH DESCRIPTION
.B dropbear
-is a SSH 2 server designed to be small enough to be used in small memory
+is a SSH server designed to be small enough to be used in small memory
environments, while still being functional and secure enough for general use.
.SH OPTIONS
.TP
@@ -29,7 +29,7 @@ Note that
some SSH implementations
use the term "DSA" rather than "DSS", they mean the same thing.
This file is generated with
-.BR dropbearkey (8).
+.BR dropbearkey (1).
.TP
.B \-r \fIrsakey
rsakeyfile.
@@ -37,7 +37,7 @@ Use the contents of the file
.I rsakey
for the rsa host key (default: /etc/dropbear/dropbear_rsa_host_key).
This file is generated with
-.BR dropbearkey (8).
+.BR dropbearkey (1).
.TP
.B \-F
Don't fork into background.
@@ -180,13 +180,14 @@ in this variable. If a shell was requested this is set to an empty value.
.B SSH_AUTH_SOCK
Set to a forwarded ssh-agent connection.
-
+.SH NOTES
+Dropbear only supports SSH protocol version 2.
.SH AUTHOR
Matt Johnston (matt@ucc.asn.au).
.br
Gerrit Pape (pape@smarden.org) wrote this manual page.
.SH SEE ALSO
-dropbearkey(8), dbclient(1)
+dropbearkey(1), dbclient(1), dropbearconvert(1)
.P
https://matt.ucc.asn.au/dropbear/dropbear.html
diff --git a/dropbearconvert.1 b/dropbearconvert.1
new file mode 100644
index 0000000..4643f5f
--- /dev/null
+++ b/dropbearconvert.1
@@ -0,0 +1,50 @@
+.TH dropbearconvert 1
+.SH NAME
+dropbearconvert \- convert between Dropbear and OpenSSH private key formats
+.SH SYNOPSIS
+.B dropbearconvert
+.I input_type
+.I output_type
+.I input_file
+.I output_file
+.SH DESCRIPTION
+.B Dropbear
+and
+.B OpenSSH
+SSH implementations have different private key formats.
+.B dropbearconvert
+can convert between the two.
+.P
+Dropbear uses the same SSH public key format as OpenSSH, it can be extracted
+from a private key by using
+.B dropbearkey \-y
+.P
+Encrypted private keys are not supported, use ssh-keygen(1) to decrypt them
+first.
+.SH OPTIONS
+.TP
+.B input type
+Either
+.I dropbear
+or
+.I openssh
+.TP
+.B output type
+Either
+.I dropbear
+or
+.I openssh
+.TP
+.B input file
+An existing Dropbear or OpenSSH private key file
+.TP
+.B output file
+The path to write the converted private key file
+.SH EXAMPLE
+ # dropbearconvert openssh dropbear ~/.ssh/id_rsa ~/.ssh/dropbear_priv
+.SH AUTHOR
+Matt Johnston (matt@ucc.asn.au).
+.SH SEE ALSO
+ dropbearkey(1), ssh-keygen(1)
+.P
+https://matt.ucc.asn.au/dropbear/dropbear.html
diff --git a/dropbearkey.8 b/dropbearkey.1
index 953e02a..945d4da 100644
--- a/dropbearkey.8
+++ b/dropbearkey.1
@@ -1,6 +1,6 @@
-.TH dropbearkey 8
+.TH dropbearkey 1
.SH NAME
-dropbearkey \- create private keys for the use with dropbear(8)
+dropbearkey \- create private keys for the use with dropbear(8) or dbclient(1)
.SH SYNOPSIS
.B dropbearkey
\-t
@@ -16,8 +16,7 @@ generates a
or
.I DSS
format SSH private key, and saves it to a file for the use with the
-.BR dropbear (8)
-SSH 2 server.
+Dropbear client or server.
Note that
some SSH implementations
use the term "DSA" rather than "DSS", they mean the same thing.
@@ -38,6 +37,10 @@ Write the secret key to the file
Set the key size to
.I bits
bits, should be multiple of 8 (optional).
+.SH NOTES
+The program dropbearconvert(1) can be used to convert between Dropbear and OpenSSH key formats.
+.P
+Dropbear does not support encrypted keys.
.SH EXAMPLE
# dropbearkey -t rsa -f /etc/dropbear/dropbear_rsa_host_key
.SH AUTHOR
@@ -45,6 +48,6 @@ Matt Johnston (matt@ucc.asn.au).
.br
Gerrit Pape (pape@smarden.org) wrote this manual page.
.SH SEE ALSO
-dropbear(8), dbclient(1)
+dropbear(8), dbclient(1), dropbearconvert(1)
.P
https://matt.ucc.asn.au/dropbear/dropbear.html
diff --git a/packet.c b/packet.c
index d458ccf..4ebd0d7 100644
--- a/packet.c
+++ b/packet.c
@@ -376,7 +376,7 @@ static int checkmac() {
/* compare the hash */
buf_setpos(ses.readbuf, contents_len);
- if (memcmp(mac_bytes, buf_getptr(ses.readbuf, mac_size), mac_size) != 0) {
+ if (constant_time_memcmp(mac_bytes, buf_getptr(ses.readbuf, mac_size), mac_size) != 0) {
return DROPBEAR_FAILURE;
} else {
return DROPBEAR_SUCCESS;
diff --git a/random.c b/random.c
index 17e3086..88c8327 100644
--- a/random.c
+++ b/random.c
@@ -78,7 +78,7 @@ process_file(hash_state *hs, const char *filename,
while (len == 0 || readcount < len)
{
int readlen, wantread;
- unsigned char readbuf[2048];
+ unsigned char readbuf[4096];
if (!already_blocked)
{
int ret;
@@ -209,12 +209,13 @@ void seedrandom() {
process_file(&hs, "/proc/loadavg", 0, 0);
process_file(&hs, "/proc/sys/kernel/random/entropy_avail", 0, 0);
- /* Mostly network visible but useful in some situations */
- process_file(&hs, "/proc/net/netstat", 0, 0);
- process_file(&hs, "/proc/net/dev", 0, 0);
- process_file(&hs, "/proc/net/tcp", 0, 0);
+ /* Mostly network visible but useful in some situations.
+ * Limit size to avoid slowdowns on systems with lots of routes */
+ process_file(&hs, "/proc/net/netstat", 4096, 0);
+ process_file(&hs, "/proc/net/dev", 4096, 0);
+ process_file(&hs, "/proc/net/tcp", 4096, 0);
/* Also includes interface lo */
- process_file(&hs, "/proc/net/rt_cache", 0, 0);
+ process_file(&hs, "/proc/net/rt_cache", 4096, 0);
process_file(&hs, "/proc/vmstat", 0, 0);
#endif
diff --git a/svr-auth.c b/svr-auth.c
index acac6f8..8666108 100644
--- a/svr-auth.c
+++ b/svr-auth.c
@@ -37,7 +37,6 @@
static void authclear();
static int checkusername(unsigned char *username, unsigned int userlen);
-static void send_msg_userauth_banner();
/* initialise the first time for a session, resetting all parameters */
void svr_authinitialise() {
@@ -82,23 +81,17 @@ static void authclear() {
/* Send a banner message if specified to the client. The client might
* ignore this, but possibly serves as a legal "no trespassing" sign */
-static void send_msg_userauth_banner() {
+void send_msg_userauth_banner(buffer *banner) {
TRACE(("enter send_msg_userauth_banner"))
- if (svr_opts.banner == NULL) {
- TRACE(("leave send_msg_userauth_banner: banner is NULL"))
- return;
- }
CHECKCLEARTOWRITE();
buf_putbyte(ses.writepayload, SSH_MSG_USERAUTH_BANNER);
- buf_putbufstring(ses.writepayload, svr_opts.banner);
+ buf_putbufstring(ses.writepayload, banner);
buf_putstring(ses.writepayload, "en", 2);
encrypt_packet();
- buf_free(svr_opts.banner);
- svr_opts.banner = NULL;
TRACE(("leave send_msg_userauth_banner"))
}
@@ -109,6 +102,7 @@ void recv_msg_userauth_request() {
unsigned char *username = NULL, *servicename = NULL, *methodname = NULL;
unsigned int userlen, servicelen, methodlen;
+ int valid_user = 0;
TRACE(("enter recv_msg_userauth_request"))
@@ -120,10 +114,11 @@ void recv_msg_userauth_request() {
/* send the banner if it exists, it will only exist once */
if (svr_opts.banner) {
- send_msg_userauth_banner();
+ send_msg_userauth_banner(svr_opts.banner);
+ buf_free(svr_opts.banner);
+ svr_opts.banner = NULL;
}
-
username = buf_getstring(ses.payload, &userlen);
servicename = buf_getstring(ses.payload, &servicelen);
methodname = buf_getstring(ses.payload, &methodlen);
@@ -140,12 +135,12 @@ void recv_msg_userauth_request() {
dropbear_exit("unknown service in auth");
}
- /* check username is good before continuing */
- if (checkusername(username, userlen) == DROPBEAR_FAILURE) {
- /* username is invalid/no shell/etc - send failure */
- TRACE(("sending checkusername failure"))
- send_msg_userauth_failure(0, 1);
- goto out;
+ /* check username is good before continuing.
+ * the 'incrfail' varies depending on the auth method to
+ * avoid giving away which users exist on the system through
+ * the time delay. */
+ if (checkusername(username, userlen) == DROPBEAR_SUCCESS) {
+ valid_user = 1;
}
/* user wants to know what methods are supported */
@@ -153,7 +148,8 @@ void recv_msg_userauth_request() {
strncmp(methodname, AUTH_METHOD_NONE,
AUTH_METHOD_NONE_LEN) == 0) {
TRACE(("recv_msg_userauth_request: 'none' request"))
- if (svr_opts.allowblankpass
+ if (valid_user
+ && svr_opts.allowblankpass
&& !svr_opts.noauthpass
&& !(svr_opts.norootpass && ses.authstate.pw_uid == 0)
&& ses.authstate.pw_passwd[0] == '\0')
@@ -167,6 +163,7 @@ void recv_msg_userauth_request() {
}
else
{
+ /* 'none' has no failure delay */
send_msg_userauth_failure(0, 0);
goto out;
}
@@ -179,8 +176,10 @@ void recv_msg_userauth_request() {
if (methodlen == AUTH_METHOD_PASSWORD_LEN &&
strncmp(methodname, AUTH_METHOD_PASSWORD,
AUTH_METHOD_PASSWORD_LEN) == 0) {
- svr_auth_password();
- goto out;
+ if (valid_user) {
+ svr_auth_password();
+ goto out;
+ }
}
}
#endif
@@ -192,8 +191,10 @@ void recv_msg_userauth_request() {
if (methodlen == AUTH_METHOD_PASSWORD_LEN &&
strncmp(methodname, AUTH_METHOD_PASSWORD,
AUTH_METHOD_PASSWORD_LEN) == 0) {
- svr_auth_pam();
- goto out;
+ if (valid_user) {
+ svr_auth_pam();
+ goto out;
+ }
}
}
#endif
@@ -203,12 +204,17 @@ void recv_msg_userauth_request() {
if (methodlen == AUTH_METHOD_PUBKEY_LEN &&
strncmp(methodname, AUTH_METHOD_PUBKEY,
AUTH_METHOD_PUBKEY_LEN) == 0) {
- svr_auth_pubkey();
+ if (valid_user) {
+ svr_auth_pubkey();
+ } else {
+ /* pubkey has no failure delay */
+ send_msg_userauth_failure(0, 0);
+ }
goto out;
}
#endif
- /* nothing matched, we just fail */
+ /* nothing matched, we just fail with a delay */
send_msg_userauth_failure(0, 1);
out:
@@ -251,7 +257,6 @@ static int checkusername(unsigned char *username, unsigned int userlen) {
dropbear_log(LOG_WARNING,
"Login attempt for nonexistent user from %s",
svr_ses.addrstring);
- send_msg_userauth_failure(0, 1);
return DROPBEAR_FAILURE;
}
@@ -263,7 +268,6 @@ static int checkusername(unsigned char *username, unsigned int userlen) {
"Login attempt with wrong user %s from %s",
ses.authstate.pw_name,
svr_ses.addrstring);
- send_msg_userauth_failure(0, 1);
return DROPBEAR_FAILURE;
}
@@ -271,7 +275,6 @@ static int checkusername(unsigned char *username, unsigned int userlen) {
if (svr_opts.norootlogin && ses.authstate.pw_uid == 0) {
TRACE(("leave checkusername: root login disabled"))
dropbear_log(LOG_WARNING, "root login rejected");
- send_msg_userauth_failure(0, 1);
return DROPBEAR_FAILURE;
}
@@ -300,7 +303,6 @@ static int checkusername(unsigned char *username, unsigned int userlen) {
TRACE(("no matching shell"))
dropbear_log(LOG_WARNING, "User '%s' has invalid shell, rejected",
ses.authstate.pw_name);
- send_msg_userauth_failure(0, 1);
return DROPBEAR_FAILURE;
goodshell:
@@ -310,7 +312,6 @@ goodshell:
TRACE(("uid = %d", ses.authstate.pw_uid))
TRACE(("leave checkusername"))
return DROPBEAR_SUCCESS;
-
}
/* Send a failure message to the client, in responds to a userauth_request.
@@ -355,8 +356,8 @@ void send_msg_userauth_failure(int partial, int incrfail) {
if (incrfail) {
unsigned int delay;
genrandom((unsigned char*)&delay, sizeof(delay));
- /* We delay for 300ms +- 50ms, 0.1ms granularity */
- delay = 250000 + (delay % 1000)*100;
+ /* We delay for 300ms +- 50ms */
+ delay = 250000 + (delay % 100000);
usleep(delay);
ses.authstate.failcount++;
}
diff --git a/svr-authpam.c b/svr-authpam.c
index e84f076..0b1d69f 100644
--- a/svr-authpam.c
+++ b/svr-authpam.c
@@ -142,6 +142,22 @@ pamConvFunc(int num_msg,
(*respp) = resp;
break;
+ case PAM_ERROR_MSG:
+ case PAM_TEXT_INFO:
+
+ if (msg_len > 0) {
+ buffer * pam_err = buf_new(msg_len + 4);
+ buf_setpos(pam_err, 0);
+ buf_putbytes(pam_err, "\r\n", 2);
+ buf_putbytes(pam_err, (*msg)->msg, msg_len);
+ buf_putbytes(pam_err, "\r\n", 2);
+ buf_setpos(pam_err, 0);
+
+ send_msg_userauth_banner(pam_err);
+ buf_free(pam_err);
+ }
+ break;
+
default:
TRACE(("Unknown message type"))
rc = PAM_CONV_ERR;
@@ -196,14 +212,14 @@ void svr_auth_pam() {
/* Init pam */
if ((rc = pam_start("sshd", NULL, &pamConv, &pamHandlep)) != PAM_SUCCESS) {
- dropbear_log(LOG_WARNING, "pam_start() failed, rc=%d, %s\n",
+ dropbear_log(LOG_WARNING, "pam_start() failed, rc=%d, %s",
rc, pam_strerror(pamHandlep, rc));
goto cleanup;
}
/* just to set it to something */
if ((rc = pam_set_item(pamHandlep, PAM_TTY, "ssh") != PAM_SUCCESS)) {
- dropbear_log(LOG_WARNING, "pam_set_item() failed, rc=%d, %s\n",
+ dropbear_log(LOG_WARNING, "pam_set_item() failed, rc=%d, %s",
rc, pam_strerror(pamHandlep, rc));
goto cleanup;
}
@@ -216,7 +232,7 @@ void svr_auth_pam() {
/* (void) pam_set_item(pamHandlep, PAM_FAIL_DELAY, (void*) pamDelayFunc); */
if ((rc = pam_authenticate(pamHandlep, 0)) != PAM_SUCCESS) {
- dropbear_log(LOG_WARNING, "pam_authenticate() failed, rc=%d, %s\n",
+ dropbear_log(LOG_WARNING, "pam_authenticate() failed, rc=%d, %s",
rc, pam_strerror(pamHandlep, rc));
dropbear_log(LOG_WARNING,
"Bad PAM password attempt for '%s' from %s",
@@ -227,7 +243,7 @@ void svr_auth_pam() {
}
if ((rc = pam_acct_mgmt(pamHandlep, 0)) != PAM_SUCCESS) {
- dropbear_log(LOG_WARNING, "pam_acct_mgmt() failed, rc=%d, %s\n",
+ dropbear_log(LOG_WARNING, "pam_acct_mgmt() failed, rc=%d, %s",
rc, pam_strerror(pamHandlep, rc));
dropbear_log(LOG_WARNING,
"Bad PAM password attempt for '%s' from %s",
diff --git a/svr-authpasswd.c b/svr-authpasswd.c
index 17dd2a1..7a5a121 100644
--- a/svr-authpasswd.c
+++ b/svr-authpasswd.c
@@ -33,6 +33,17 @@
#ifdef ENABLE_SVR_PASSWORD_AUTH
+static int constant_time_strcmp(const char* a, const char* b) {
+ size_t la = strlen(a);
+ size_t lb = strlen(b);
+
+ if (la != lb) {
+ return 1;
+ }
+
+ return constant_time_memcmp(a, b, la);
+}
+
/* Process a password auth request, sending success or failure messages as
* appropriate */
void svr_auth_password() {
@@ -82,7 +93,7 @@ void svr_auth_password() {
return;
}
- if (strcmp(testcrypt, passwdcrypt) == 0) {
+ if (constant_time_strcmp(testcrypt, passwdcrypt) == 0) {
/* successful authentication */
dropbear_log(LOG_NOTICE,
"Password auth succeeded for '%s' from %s",
diff --git a/svr-chansession.c b/svr-chansession.c
index 88a4b85..5dd5540 100644
--- a/svr-chansession.c
+++ b/svr-chansession.c
@@ -699,8 +699,6 @@ static int noptycommand(struct Channel *channel, struct ChanSess *chansess) {
ses.maxfd = MAX(ses.maxfd, channel->readfd);
ses.maxfd = MAX(ses.maxfd, channel->errfd);
- sleep(1);
-
addchildpid(chansess, chansess->pid);
if (svr_ses.lastexit.exitpid != -1) {
diff --git a/sysoptions.h b/sysoptions.h
index c36ab8b..21b153b 100644
--- a/sysoptions.h
+++ b/sysoptions.h
@@ -4,7 +4,7 @@
*******************************************************************/
#ifndef DROPBEAR_VERSION
-#define DROPBEAR_VERSION "2013.58"
+#define DROPBEAR_VERSION "2013.60"
#endif
#define LOCAL_IDENT "SSH-2.0-dropbear_" DROPBEAR_VERSION