Mercurial > dropbear
changeset 1355:3fdd8c5a0195 fuzz
merge main to fuzz
author | Matt Johnston <matt@ucc.asn.au> |
---|---|
date | Thu, 18 May 2017 23:45:10 +0800 |
parents | 7618759e9327 (current diff) bbc0a0ee3843 (diff) |
children | 3677a510f545 |
files | Makefile.in buffer.c common-kex.c dbrandom.c netio.c runopts.h svr-auth.c svr-runopts.c svr-session.c |
diffstat | 88 files changed, 2149 insertions(+), 1606 deletions(-) [+] |
line wrap: on
line diff
--- a/.hgsigs Thu May 18 23:38:30 2017 +0800 +++ b/.hgsigs Thu May 18 23:45:10 2017 +0800 @@ -20,3 +20,6 @@ 5bb5976e6902a0c9fba974a880c68c9487ee1e77 0 iQIcBAABCgAGBQJWVyIKAAoJEESTFJTynGdzQosP/0k5bVTerpUKZLjyNuMU8o0eyc7njkX8EyMOyGbtcArKpzO2opSBTRsuCT9Zsk1iiQ1GMTY1quKD7aNr86Hipqo4th/+ZXmLe9mmaCDukKjD0ZYC4dBVUy6RSUAMvdkDP9sZs7CMTO/22a9SqOsKTv3s2NN6XnsBGnmNbvVx5hkAk5hMVNFrjKIaexzI/7bWQIDRo2HQCaWaL06JvWEDSEQd2mynGSXxT/+m4hBnuGg6qxn2pd4XfG0g10tDAFx64HQkWgZqSB+F8z71Cvfjondy1zjJYgtABqNlwCKQJZhRUW2+PblqQnz08TUy83XN2vtisOju4avGcHSaBgBbMvg8Wx4ZtM7sPP9pLrhhOTd5ceERHeTceTJy+iI1SQFvccjrRfs5aJ0zAQX5q6f4bV0zp5SmxkvnZUEkZIoetkM8VrPOYugqx31LtHAWfVT9NM+VkV/rrxLhk6J0giIQvC9MPWxRDileFVDszPiOgTLcxWjOziOLT+xijcj7dtx1b/f2bNCduN5G7i+icjjTlCNtyRPRqhBqn705W7F+xESP2gsscM/1BjQ7TGidU5m1njdkUjbrqm3+Qic6iqkG7SfETHmQB9mHqpJ0hACRPvZlhwB7oimNHllkrlw8UJw9f0SiuLjfERIgVS2EOp+mAia0RU7MlTt19o017M1ffEYL 926e7275cef4f4f2a4251597ee4814748394824c 0 iQIcBAABCgAGBQJWYES4AAoJEESTFJTynGdzdT0P/0O/1frevtr698DwMe6kmJx35P6Bqq8szntMxYucv0HROTfr85JRcCCSvl/2SflDS215QmOxdvYLGLUWPJNz/gURCLpzsT88KLF68Y1tC72nl4Fj+LGIOlsWsvwEqQqw0v4iQkHIfcxI6q7g1r9Hfldf/ju4bzQ4HnKLxm6KNcLLoAsuehVpQ+njHpLmlLAGHU5a84B7xeXHFR+U/EBPxSdm637rNhmpLpkuK2Mym/Mzv7BThKDstpB8lhFHIwAVNqi3Cy4nGYxFZOJpooUN9pDornqAwuzHmOAMs9+49L8GZ1de5PBRGyFKibzjBIUWPEU9EIkfJVaVwTlqYK8Q/IRi9HjITPx6GpE8cZhdSvAibrQdb6BbIDrZ8eCvD9vnod6Uk0Jb9/ui6nCF9x+CN/3Qez4epV5+JCMYsqCiXFkVPm9Lab6L2eGZis7Q2TXImA/sSV+E4BGfH2urpkKlnuXTTtDp4XRG+lOISkIBXgjVY+uy8soVKNdx1gv+LeY8hu/oQ2NyOlaOeL47aSQ3who4Pk6pVRUOl6zfcKo9Vs6xDWm35A3Z6x/mrAENaXasB0JrfY5nIbefJUpbeSmi76fYldU98HdQNHPHCSeiKVYl7v/B6gi2JXp5xngLZz/5VVAurago7sRmpIp7G/AqU6LNE85IUzG8aQz8AfR0d1dW fd1981f41c626a969f07b4823848deaefef3c8aa 0 iQIcBAABCgAGBQJW4W2TAAoJEESTFJTynGdzuOcP/j6tvB2WRwSj39KoJuRcRebFWWv4ZHiQXYMXWa3X0Ppzz52r9W0cXDjjlp5FyGdovCQsK+IXmjPo5cCvWBrZJYA6usFr9ssnUtTC+45lvPxPYwj47ZGPngCXDt7LD+v08XhqCu4LsctXIP/zejd30KVS1eR2RHI+tnEyaIKC0Xaa0igcv74MZX7Q8/U+B730QMX5adfYAHoeyRhoctRWaxVV3To7Vadd9jNXP45MRY5auhRcK7XyQcS85vJeCRoysfDUas4ERRQWYkX+68GyzO9GrkYFle931Akw2K6ZZfUuiC2TrF5xv1eRP1Zm2GX481U4ZGFTI8IzZL8sVQ6tvzq2Mxsecu589JNui9aB2d8Gp2Su/E2zn0h0ShIRmviGzf2HiBt+Bnji5X2h/fJKWbLaWge0MdOU5Jidfyh9k0YT7xo4piJLJYSaZ3nv+j4jTYnTfL7uYvuWbYkJ1T32aQVCan7Eup3BFAgQjzbWYi1XQVg6fvu8uHPpS3tNNA9EAMeeyTyg1l6zI2EIU5gPfd/dKmdyotY2lZBkFZNJqFkKRZuzjWekcw7hAxS+Bd68GKklt/DGrQiVycAgimqwXrfkzzQagawq2fXL2uXB8ghlsyxKLSQPnAtBF2Jcn5FH2z7HOQ+e18ZrFfNy0cYa/4OdH6K5aK1igTzhZZP2Urn0 +70705edee9dd29cd3d410f19fbd15cc3489313e2 0 iQIcBAABCgAGBQJW7CQRAAoJEESTFJTynGdzTj0QAJL38CKSZthBAeI9c6B+IlwIeT6kPZaPqk1pkycCTWOe87NiNU9abrsF+JrjTuRQiO1EpM2IvfQEIXTijUcMxvld3PnzrZDDv6UvBLtOkn3i++HSVRO0MOuTKI8gFDEPUxRtcaCKXEbqYnf1OTK25FT09Vb//qP9mK1thvlLJmbV+D2a9MkMK66rom1d1h+347IsuwsM+ycHjB80VVAQLA7VYLC5YIwmL17dSmcQLvetfikAMwwmUE+KES4qiLSaqOcAWcKcU67RZzgMMv5o0rESlQmv1nj0mHZtHoUR71sd21emPaRXLOr0oT5YogWUphKq2qVthRn2B06+vd3hPdtn92CmJw9j7zT2jl4OeSjNm9qfAajsRzHIANssFxkGAb7w/LxcMoO29JC+01iUUJMdOVm+4Ns6wGI7qxssWPKdB+VbQUDlHrXLR+sopO524uhkYoWB6DVfTj4R6tImaHtj5/VXON0lsYaLGj8cSH60emL6nNQ0lYV/bSlk6l0s+0x3uXGZnp9oKA+vqMzHfG3vJeMm6KUqtFVjUsYx+q8nHm5/SlWxj1EwnkH8s8ELKZAUXjd76nWEwJ7JFRNRSQWvjOUh3/rsOo4JopzZXPsjCjm+Vql9TG0X6hB21noai32oD5RvfhtR/NX6sXNS5TKZz/j/cMsMnAAsSKb6W7Jm +9030ffdbe5625e35ed7189ab84a41dfc8d413e9c 0 iQIcBAABCgAGBQJXkOg0AAoJEESTFJTynGdzc1kP/3vSKCnhOOvjCjnpTQadYcCUq8vTNnfLHYVu0R4ItPa/jT6RmxoaYP+lZnLnnBx9+aX7kzwHsa9BUX3MbMEyLrOzX2I+bDJbNPhQyupyCuPYlf5Q9KVcO9YlpbsC4q5XBzCn3j2+pT8kSfi9uD8fgY3TgE4w9meINrfQAealfjwMLT8S/I49/ni0r+usSfk/dnSShJYDUO7Ja0VWbJea/GkkZTu30bCnMUZPjRApipU3hPP63WFjkSMT1rp2mAXbWqyr9lf8z32yxzM9nMSjq4ViRFzFlkGtE3EVRJ4PwkO7JuiWAMPJpiQcEr+r52cCsmWhiGyHuINo01MwoMO9/n6uL1WVa3mJcE9se3xBOvfgDu2FRFGCAdm1tef+AGVo9EG1uJXi0sX2yUc6DMeuYaRWrXMMlZh7zp9cuNU9Y/lLui9RFmq66yeXG3Z2B72doju3Ig5QGrNNw2AOsSzeHdAtOp6ychqPcl9QfIeJQG18KyPSefZKM3G8YRKBRIwXFEH6iZJe5ZIP4iXrHDMn2JqtTRtDqKR8VNDAgb9z4Ffx8QRxFyj5JzTTMM1GddHb9udLvTQlO0ULYG7hCSMRNzvUBE2aTw8frjLRyfyyg3QpDu/hz8op8s1ecE8rTCD8RuX9DiiylNozypPtGNS+UDbAmkc1PCWaRpPVl+9K6787 +5c9207ceedaea794f958224c19214d66af6e2d56 0 iQIzBAABCgAdFiEE9zR+8u4uB6JnYoypRJMUlPKcZ3MFAlkdtooACgkQRJMUlPKcZ3P6ZxAAmLy/buZB/d96DJF/pViRWt/fWdjQFC4MqWfeSLW02OZ8Qkm1vPL3ln6WPHC2thy3xZWVg2uan3pLk/XXnsIFu8Q7r1EAfFFpvlMUmdl7asE8V6ilaeqmiI7bIvGMFbf4cZkQliLjiFkJX56tFHRCNi+rb7WgRuru3/GzPXUq2AvXZvFpFJgik0B72TxVlmCKeBRZq1FvP0UhAH48RJWYJksdEyzh2paMfjX9ZO5Q2SFFrmPw6k2ArdJFC1AYcgceZC84y06RKJ0WiSntUPlEUXgQbQVVWbtQDhjfJXMr/beuroNdT/vsRraLVkAzvhaDXNnHlAJNLQxci+AcLpnzZhxMW+ax7RRtrpXGxRN4cs0lBGUcSkaDybFqMYXwEjXAE8w6fdJRWCIlxctkAW/iNEO4kAG97hI2Qwcw5oU2Ymnv09zyGR+XJE35pJqPulJHExdwanJHvmjH0QF7TNFS82yxS5dKnP954cj3Lu9SWGYWjxQJRmLtOwb+lqqol4VTxG7Ois4uef9/Tpp9skeMZXVeNlpn2wrp6iFcX3uiiVDg9VKkl3ig6UqCiqQSuiIN87RXwUOeHXlCnW3adz3Xei0ziBrwLSql7lBIHGEAlUUNmJ3CrR8IwQtcynGEMKfNIeZ/XK+uNlm9cJIqZf1fzqc8KexlyS9AS0i/kiYZTr4=
--- a/.hgtags Thu May 18 23:38:30 2017 +0800 +++ b/.hgtags Thu May 18 23:45:10 2017 +0800 @@ -52,3 +52,6 @@ 79a6ef02307d05cb9dda10465cb5b807baa8f62e DROPBEAR_2015.70 9a944a243f08be6b22d32f166a0690eb4872462b DROPBEAR_2015.71 78b12b6549be08b0bea3da329b2578060a76ca31 DROPBEAR_2016.72 +309e1c4a87682b6ca7d80b8555a1db416c3cb7ac DROPBEAR_2016.73 +0ed3d2bbf956cb8a9bf0f4b5a86b7dd9688205cb DROPBEAR_2016.74 +c31276613181c5cff7854e7ef586ace03424e55e DROPBEAR_2017.75
--- a/.travis.yml Thu May 18 23:38:30 2017 +0800 +++ b/.travis.yml Thu May 18 23:45:10 2017 +0800 @@ -41,7 +41,9 @@ script: - autoconf && autoheader && ./configure "$BUNDLEDLIBTOM" CFLAGS="-O2 -Wall -Wno-pointer-sign $WEXTRAFLAGS" --prefix="$HOME/inst" - if [ "$NOWRITEV" = "1" ]; then sed -i -e s/HAVE_WRITEV/DONT_HAVE_WRITEV/ config.h ; fi - - make -j3 install + - make -j3 + # avoid concurrent install, osx/freebsd is racey (https://bugs.freebsd.org/bugzilla/show_bug.cgi?id=208093) + - make install after_success: - ~/inst/bin/dropbearkey -t rsa -f testrsa
--- a/CHANGES Thu May 18 23:38:30 2017 +0800 +++ b/CHANGES Thu May 18 23:45:10 2017 +0800 @@ -1,3 +1,28 @@ +2017.75 - 18 May 2017 + +- Security: Fix double-free in server TCP listener cleanup + A double-free in the server could be triggered by an authenticated user if + dropbear is running with -a (Allow connections to forwarded ports from any host) + This could potentially allow arbitrary code execution as root by an authenticated user. + Affects versions 2013.56 to 2016.74. Thanks to Mark Shepard for reporting the crash. + +- Security: Fix information disclosure with ~/.ssh/authorized_keys symlink. + Dropbear parsed authorized_keys as root, even if it were a symlink. The fix + is to switch to user permissions when opening authorized_keys + + A user could symlink their ~/.ssh/authorized_keys to a root-owned file they + couldn't normally read. If they managed to get that file to contain valid + authorized_keys with command= options it might be possible to read other + contents of that file. + This information disclosure is to an already authenticated user. + Thanks to Jann Horn of Google Project Zero for reporting this. + +- Generate hostkeys with dropbearkey atomically and flush to disk with fsync + Thanks to Andrei Gherzan for a patch + +- Fix out of tree builds with bundled libtom + Thanks to Henrik Nordström and Peter Krefting for patches. + 2016.74 - 21 July 2016 - Security: Message printout was vulnerable to format string injection. @@ -9,16 +34,24 @@ A dbclient user who can control username or host arguments could potentially run arbitrary code as the dbclient user. This could be a problem if scripts or webpages pass untrusted input to the dbclient program. + CVE-2016-7406 + https://secure.ucc.asn.au/hg/dropbear/rev/b66a483f3dcb - Security: dropbearconvert import of OpenSSH keys could run arbitrary code as the local dropbearconvert user when parsing malicious key files + CVE-2016-7407 + https://secure.ucc.asn.au/hg/dropbear/rev/34e6127ef02e - Security: dbclient could run arbitrary code as the local dbclient user if particular -m or -c arguments are provided. This could be an issue where dbclient is used in scripts. + CVE-2016-7408 + https://secure.ucc.asn.au/hg/dropbear/rev/eed9376a4ad6 - Security: dbclient or dropbear server could expose process memory to the running user if compiled with DEBUG_TRACE and running with -v + CVE-2016-7409 + https://secure.ucc.asn.au/hg/dropbear/rev/6a14b1f6dc04 The security issues were reported by an anonymous researcher working with Beyond Security's SecuriTeam Secure Disclosure www.beyondsecurity.com/ssd.html @@ -64,6 +97,7 @@ - Validate X11 forwarding input. Could allow bypass of authorized_keys command= restrictions, found by github.com/tintinweb. Thanks for Damien Miller for a patch. CVE-2016-3116 + https://secure.ucc.asn.au/hg/dropbear/rev/a3e8389e01ff 2015.71 - 3 December 2015 @@ -342,9 +376,11 @@ - Limit the size of decompressed payloads, avoids memory exhaustion denial of service Thanks to Logan Lamb for reporting and investigating it. CVE-2013-4421 + https://secure.ucc.asn.au/hg/dropbear/rev/0bf76f54de6f - Avoid disclosing existence of valid users through inconsistent delays Thanks to Logan Lamb for reporting. CVE-2013-4434 + https://secure.ucc.asn.au/hg/dropbear/rev/d7784616409a - Update config.guess and config.sub for newer architectures @@ -447,6 +483,7 @@ This bug affects releases 0.52 onwards. Ref CVE-2012-0920. Thanks to Danny Fullerton of Mantor Organization for reporting the bug. + https://secure.ucc.asn.au/hg/dropbear/rev/818108bf7749 - Compile fix, only apply IPV6 socket options if they are available in headers Thanks to Gustavo Zacarias for the patch
--- a/Makefile.in Thu May 18 23:38:30 2017 +0800 +++ b/Makefile.in Thu May 18 23:45:10 2017 +0800 @@ -24,6 +24,10 @@ LIBTOM_LIBS=$(STATIC_LTC) $(STATIC_LTM) endif +ifneq ($(wildcard localoptions.h),) +CFLAGS+=-DLOCALOPTIONS_H_EXISTS +endif + COMMONOBJS=dbutil.o buffer.o dbhelpers.o \ dss.o bignum.o \ signkey.o rsa.o dbrandom.o \ @@ -76,6 +80,8 @@ sbindir=@sbindir@ mandir=@mandir@ +.DELETE_ON_ERROR: + CC=@CC@ AR=@AR@ RANLIB=@RANLIB@ @@ -155,7 +161,6 @@ inst_dropbearmulti: $(addprefix insmulti, $(PROGRAMS)) - # for some reason the rule further down doesn't like $($@objs) as a prereq. dropbear: $(dropbearobjs) dbclient: $(dbclientobjs) @@ -195,18 +200,18 @@ -ln -s dropbearmulti$(EXEEXT) $*$(EXEEXT) $(STATIC_LTC): options.h - cd libtomcrypt && $(MAKE) + $(MAKE) -C libtomcrypt $(STATIC_LTM): options.h - cd libtommath && $(MAKE) + $(MAKE) -C libtommath .PHONY : clean sizes thisclean distclean tidy ltc-clean ltm-clean ltc-clean: - cd libtomcrypt && $(MAKE) clean + $(MAKE) -C libtomcrypt clean ltm-clean: - cd libtommath && $(MAKE) clean + $(MAKE) -C libtommath clean sizes: dropbear objdump -t dropbear|grep ".text"|cut -d "." -f 2|sort -rn @@ -224,6 +229,14 @@ tidy: -rm -f *~ *.gcov */*~ +# default_options.h is stored in version control, could not find a workaround +# for parallel "make -j" and dependency rules. +default_options.h: default_options.h.in + echo "# > > > Generated from $^, edit that file instead !" > [email protected] + echo >> [email protected] + $(srcdir)/ifndef_wrapper.sh < $^ > [email protected] + mv [email protected] $@ + ## Fuzzing targets # list of fuzz targets @@ -257,4 +270,3 @@ /usr/bin/xxd -i -a keyr >> hostkeys.c /usr/bin/xxd -i -a keye >> hostkeys.c /usr/bin/xxd -i -a keyd >> hostkeys.c -
--- a/agentfwd.h Thu May 18 23:38:30 2017 +0800 +++ b/agentfwd.h Thu May 18 23:45:10 2017 +0800 @@ -30,7 +30,7 @@ #include "auth.h" #include "list.h" -#ifdef ENABLE_CLI_AGENTFWD +#if DROPBEAR_CLI_AGENTFWD /* An agent reply can be reasonably large, as it can * contain a list of all public keys held by the agent. @@ -50,14 +50,14 @@ extern const struct ChanType cli_chan_agent; -#endif /* ENABLE_CLI_AGENTFWD */ +#endif /* DROPBEAR_CLI_AGENTFWD */ -#ifdef ENABLE_SVR_AGENTFWD +#if DROPBEAR_SVR_AGENTFWD int svr_agentreq(struct ChanSess * chansess); void svr_agentcleanup(struct ChanSess * chansess); void svr_agentset(struct ChanSess *chansess); -#endif /* ENABLE_SVR_AGENTFWD */ +#endif /* DROPBEAR_SVR_AGENTFWD */ #endif /* DROPBEAR_AGENTFWD_H_ */
--- a/algo.h Thu May 18 23:38:30 2017 +0800 +++ b/algo.h Thu May 18 23:45:10 2017 +0800 @@ -83,9 +83,15 @@ }; enum dropbear_kex_mode { +#if DROPBEAR_NORMAL_DH DROPBEAR_KEX_NORMAL_DH, +#endif +#if DROPBEAR_ECDH DROPBEAR_KEX_ECDH, +#endif +#if DROPBEAR_CURVE25519 DROPBEAR_KEX_CURVE25519, +#endif }; struct dropbear_kex { @@ -96,7 +102,7 @@ const int dh_p_len; /* elliptic curve DH KEX */ -#ifdef DROPBEAR_ECDH +#if DROPBEAR_ECDH const struct dropbear_ecc_curve *ecc_curve; #else const void* dummy; @@ -122,7 +128,7 @@ algo_type * buf_match_algo(buffer* buf, algo_type localalgos[], enum kexguess2_used *kexguess2, int *goodguess); -#ifdef ENABLE_USER_ALGO_LIST +#if DROPBEAR_USER_ALGO_LIST int check_user_algos(const char* user_algo_list, algo_type * algos, const char *algo_desc); char * algolist_string(algo_type algos[]);
--- a/atomicio.c Thu May 18 23:38:30 2017 +0800 +++ b/atomicio.c Thu May 18 23:45:10 2017 +0800 @@ -1,6 +1,8 @@ +/* $OpenBSD: atomicio.c,v 1.17 2006/04/01 05:51:34 djm Exp $ */ /* - * Copied from OpenSSH 3.6.1p2. + * Copied from OpenSSH/OpenBSD. * + * Copyright (c) 2005 Anil Madhavapeddy. All rights reserved. * Copyright (c) 1995,1999 Theo de Raadt. All rights reserved. * All rights reserved. * @@ -25,39 +27,32 @@ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -/* RCSID("OpenBSD: atomicio.c,v 1.10 2001/05/08 22:48:07 markus Exp "); */ +#include "includes.h" #include "atomicio.h" /* - * ensure all of data on socket comes through. f==read || f==write + * ensure all of data on socket comes through. f==read || f==vwrite */ -ssize_t -atomicio(f, fd, _s, n) - ssize_t (*f) (); - int fd; - void *_s; - size_t n; +size_t +atomicio(ssize_t (*f) (int, void *, size_t), int fd, void *_s, size_t n) { char *s = _s; + size_t pos = 0; ssize_t res; - size_t pos = 0; while (n > pos) { res = (f) (fd, s + pos, n - pos); switch (res) { case -1: -#ifdef EWOULDBLOCK - if (errno == EINTR || errno == EAGAIN || errno == EWOULDBLOCK) -#else if (errno == EINTR || errno == EAGAIN) -#endif continue; - /* FALLTHROUGH */ + return 0; case 0: - return (res); + errno = EPIPE; + return pos; default: - pos += res; + pos += (size_t)res; } } return (pos);
--- a/atomicio.h Thu May 18 23:38:30 2017 +0800 +++ b/atomicio.h Thu May 18 23:45:10 2017 +0800 @@ -1,8 +1,7 @@ +/* $OpenBSD: atomicio.h,v 1.7 2006/03/25 22:22:42 djm Exp $ */ /* - * Copied from OpenSSH 3.6.1p2, required for loginrec.c - * - * $OpenBSD: atomicio.h,v 1.4 2001/06/26 06:32:46 itojun Exp $ + * Copied from OpenSSH/OpenBSD, required for loginrec.c * * Copyright (c) 1995,1999 Theo de Raadt. All rights reserved. * All rights reserved. @@ -28,9 +27,9 @@ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -#include "includes.h" +/* + * Ensure all of data on socket comes through. f==read || f==vwrite + */ +size_t atomicio(ssize_t (*)(int, void *, size_t), int, void *, size_t); -/* - * Ensure all of data on socket comes through. f==read || f==write - */ -ssize_t atomicio(ssize_t (*)(), int, void *, size_t); +#define vwrite (ssize_t (*)(int, void *, size_t))write
--- a/auth.h Thu May 18 23:38:30 2017 +0800 +++ b/auth.h Thu May 18 23:45:10 2017 +0800 @@ -41,7 +41,7 @@ void svr_auth_pubkey(void); void svr_auth_pam(void); -#ifdef ENABLE_SVR_PUBKEY_OPTIONS +#if DROPBEAR_SVR_PUBKEY_OPTIONS_BUILT int svr_pubkey_allows_agentfwd(void); int svr_pubkey_allows_tcpfwd(void); int svr_pubkey_allows_x11fwd(void); @@ -119,12 +119,12 @@ char *pw_shell; char *pw_name; char *pw_passwd; -#ifdef ENABLE_SVR_PUBKEY_OPTIONS +#if DROPBEAR_SVR_PUBKEY_OPTIONS_BUILT struct PubKeyOptions* pubkey_options; #endif }; -#ifdef ENABLE_SVR_PUBKEY_OPTIONS +#if DROPBEAR_SVR_PUBKEY_OPTIONS_BUILT struct PubKeyOptions; struct PubKeyOptions { /* Flags */
--- a/buffer.c Thu May 18 23:38:30 2017 +0800 +++ b/buffer.c Thu May 18 23:45:10 2017 +0800 @@ -109,7 +109,7 @@ dropbear_exit("Bad buf_setlen"); } buf->len = len; - buf->pos = 0; + buf->pos = MIN(buf->pos, buf->len); } /* Increment the length of the buffer */
--- a/channel.h Thu May 18 23:38:30 2017 +0800 +++ b/channel.h Thu May 18 23:45:10 2017 +0800 @@ -126,11 +126,11 @@ void common_recv_msg_channel_data(struct Channel *channel, int fd, circbuffer * buf); -#ifdef DROPBEAR_CLIENT +#if DROPBEAR_CLIENT extern const struct ChanType clichansess; #endif -#if defined(USING_LISTENERS) || defined(DROPBEAR_CLIENT) +#if DROPBEAR_LISTENERS || DROPBEAR_CLIENT int send_msg_channel_open_init(int fd, const struct ChanType *type); void recv_msg_channel_open_confirmation(void); void recv_msg_channel_open_failure(void);
--- a/chansession.h Thu May 18 23:38:30 2017 +0800 +++ b/chansession.h Thu May 18 23:45:10 2017 +0800 @@ -58,7 +58,7 @@ /* Used to set $SSH_CLIENT in the child session. */ char *client_string; -#ifndef DISABLE_X11FWD +#if DROPBEAR_X11FWD struct Listener * x11listener; int x11port; char * x11authprot; @@ -67,13 +67,13 @@ unsigned char x11singleconn; #endif -#ifdef ENABLE_SVR_AGENTFWD +#if DROPBEAR_SVR_AGENTFWD struct Listener * agentlistener; char * agentfile; char * agentdir; #endif -#ifdef ENABLE_SVR_PUBKEY_OPTIONS +#if DROPBEAR_SVR_PUBKEY_OPTIONS_BUILT char *original_command; #endif }; @@ -89,7 +89,7 @@ void cli_send_chansess_request(void); void cli_tty_cleanup(void); void cli_chansess_winchange(void); -#ifdef ENABLE_CLI_NETCAT +#if DROPBEAR_CLI_NETCAT void cli_send_netcat_request(void); #endif
--- a/cli-agentfwd.c Thu May 18 23:38:30 2017 +0800 +++ b/cli-agentfwd.c Thu May 18 23:45:10 2017 +0800 @@ -24,7 +24,7 @@ #include "includes.h" -#ifdef ENABLE_CLI_AGENTFWD +#if DROPBEAR_CLI_AGENTFWD #include "agentfwd.h" #include "session.h" @@ -130,7 +130,7 @@ } buf_setpos(payload, 0); - ret = atomicio(write, fd, buf_getptr(payload, payload->len), payload->len); + ret = atomicio(vwrite, fd, buf_getptr(payload, payload->len), payload->len); if ((size_t)ret != payload->len) { TRACE(("write failed fd %d for agent_request, %s", fd, strerror(errno))) goto out;
--- a/cli-auth.c Thu May 18 23:38:30 2017 +0800 +++ b/cli-auth.c Thu May 18 23:45:10 2017 +0800 @@ -51,7 +51,7 @@ encrypt_packet(); -#ifdef DROPBEAR_CLI_IMMEDIATE_AUTH +#if DROPBEAR_CLI_IMMEDIATE_AUTH /* We can't haven't two auth requests in-flight with delayed zlib mode since if the first one succeeds then the remote side will expect the second one to be compressed. @@ -78,6 +78,7 @@ char* banner = NULL; unsigned int bannerlen; unsigned int i, linecount; + int truncated = 0; TRACE(("enter recv_msg_userauth_banner")) if (ses.authstate.authdone) { @@ -90,26 +91,29 @@ if (bannerlen > MAX_BANNER_SIZE) { TRACE(("recv_msg_userauth_banner: bannerlen too long: %d", bannerlen)) - goto out; + truncated = 1; + } else { + cleantext(banner); + + /* Limit to 24 lines */ + linecount = 1; + for (i = 0; i < bannerlen; i++) { + if (banner[i] == '\n') { + if (linecount >= MAX_BANNER_LINES) { + banner[i] = '\0'; + truncated = 1; + break; + } + linecount++; + } + } + fprintf(stderr, "%s\n", banner); } - cleantext(banner); - - /* Limit to 25 lines */ - linecount = 1; - for (i = 0; i < bannerlen; i++) { - if (banner[i] == '\n') { - if (linecount >= MAX_BANNER_LINES) { - banner[i] = '\0'; - break; - } - linecount++; - } + if (truncated) { + fprintf(stderr, "[Banner from the server is too long]\n"); } - fprintf(stderr, "%s\n", banner); - -out: m_free(banner); TRACE(("leave recv_msg_userauth_banner")) } @@ -121,21 +125,21 @@ * SSH_MSG_USERAUTH_INFO_REQUEST. */ void recv_msg_userauth_specific_60() { -#ifdef ENABLE_CLI_PUBKEY_AUTH +#if DROPBEAR_CLI_PUBKEY_AUTH if (cli_ses.lastauthtype == AUTH_TYPE_PUBKEY) { recv_msg_userauth_pk_ok(); return; } #endif -#ifdef ENABLE_CLI_INTERACT_AUTH +#if DROPBEAR_CLI_INTERACT_AUTH if (cli_ses.lastauthtype == AUTH_TYPE_INTERACT) { recv_msg_userauth_info_request(); return; } #endif -#ifdef ENABLE_CLI_PASSWORD_AUTH +#if DROPBEAR_CLI_PASSWORD_AUTH if (cli_ses.lastauthtype == AUTH_TYPE_PASSWORD) { /* Eventually there could be proper password-changing * support. However currently few servers seem to @@ -179,7 +183,7 @@ TRACE(("leave recv_msg_userauth_failure, ignored response, state set to USERAUTH_REQ_SENT")); return; } else { -#ifdef ENABLE_CLI_PUBKEY_AUTH +#if DROPBEAR_CLI_PUBKEY_AUTH /* If it was a pubkey auth request, we should cross that key * off the list. */ if (cli_ses.lastauthtype == AUTH_TYPE_PUBKEY) { @@ -187,7 +191,7 @@ } #endif -#ifdef ENABLE_CLI_INTERACT_AUTH +#if DROPBEAR_CLI_INTERACT_AUTH /* If we get a failure message for keyboard interactive without * receiving any request info packet, then we don't bother trying * keyboard interactive again */ @@ -227,19 +231,19 @@ for (i = 0; i <= methlen; i++) { if (methods[i] == '\0') { TRACE(("auth method '%s'", tok)) -#ifdef ENABLE_CLI_PUBKEY_AUTH +#if DROPBEAR_CLI_PUBKEY_AUTH if (strncmp(AUTH_METHOD_PUBKEY, tok, AUTH_METHOD_PUBKEY_LEN) == 0) { ses.authstate.authtypes |= AUTH_TYPE_PUBKEY; } #endif -#ifdef ENABLE_CLI_INTERACT_AUTH +#if DROPBEAR_CLI_INTERACT_AUTH if (strncmp(AUTH_METHOD_INTERACT, tok, AUTH_METHOD_INTERACT_LEN) == 0) { ses.authstate.authtypes |= AUTH_TYPE_INTERACT; } #endif -#ifdef ENABLE_CLI_PASSWORD_AUTH +#if DROPBEAR_CLI_PASSWORD_AUTH if (strncmp(AUTH_METHOD_PASSWORD, tok, AUTH_METHOD_PASSWORD_LEN) == 0) { ses.authstate.authtypes |= AUTH_TYPE_PASSWORD; @@ -267,7 +271,7 @@ cli_ses.state = USERAUTH_SUCCESS_RCVD; cli_ses.lastauthtype = AUTH_TYPE_NONE; -#ifdef ENABLE_CLI_PUBKEY_AUTH +#if DROPBEAR_CLI_PUBKEY_AUTH cli_auth_pubkey_cleanup(); #endif } @@ -281,14 +285,14 @@ /* Order to try is pubkey, interactive, password. * As soon as "finished" is set for one, we don't do any more. */ -#ifdef ENABLE_CLI_PUBKEY_AUTH +#if DROPBEAR_CLI_PUBKEY_AUTH if (ses.authstate.authtypes & AUTH_TYPE_PUBKEY) { finished = cli_auth_pubkey(); cli_ses.lastauthtype = AUTH_TYPE_PUBKEY; } #endif -#ifdef ENABLE_CLI_PASSWORD_AUTH +#if DROPBEAR_CLI_PASSWORD_AUTH if (!finished && (ses.authstate.authtypes & AUTH_TYPE_PASSWORD)) { if (ses.keys->trans.algo_crypt->cipherdesc == NULL) { fprintf(stderr, "Sorry, I won't let you use password auth unencrypted.\n"); @@ -300,7 +304,7 @@ } #endif -#ifdef ENABLE_CLI_INTERACT_AUTH +#if DROPBEAR_CLI_INTERACT_AUTH if (!finished && (ses.authstate.authtypes & AUTH_TYPE_INTERACT)) { if (ses.keys->trans.algo_crypt->cipherdesc == NULL) { fprintf(stderr, "Sorry, I won't let you use interactive auth unencrypted.\n"); @@ -324,7 +328,7 @@ return DROPBEAR_FAILURE; } -#if defined(ENABLE_CLI_PASSWORD_AUTH) || defined(ENABLE_CLI_INTERACT_AUTH) +#if DROPBEAR_CLI_PASSWORD_AUTH || DROPBEAR_CLI_INTERACT_AUTH /* A helper for getpass() that exits if the user cancels. The returned * password is statically allocated by getpass() */ char* getpass_or_cancel(char* prompt)
--- a/cli-authinteract.c Thu May 18 23:38:30 2017 +0800 +++ b/cli-authinteract.c Thu May 18 23:45:10 2017 +0800 @@ -29,7 +29,7 @@ #include "ssh.h" #include "runopts.h" -#ifdef ENABLE_CLI_INTERACT_AUTH +#if DROPBEAR_CLI_INTERACT_AUTH static char* get_response(char* prompt) { @@ -172,4 +172,4 @@ TRACE(("leave cli_auth_interactive")) } -#endif /* ENABLE_CLI_INTERACT_AUTH */ +#endif /* DROPBEAR_CLI_INTERACT_AUTH */
--- a/cli-authpasswd.c Thu May 18 23:38:30 2017 +0800 +++ b/cli-authpasswd.c Thu May 18 23:45:10 2017 +0800 @@ -29,9 +29,9 @@ #include "ssh.h" #include "runopts.h" -#ifdef ENABLE_CLI_PASSWORD_AUTH +#if DROPBEAR_CLI_PASSWORD_AUTH -#ifdef ENABLE_CLI_ASKPASS_HELPER +#if DROPBEAR_CLI_ASKPASS_HELPER /* Returns 1 if we want to use the askpass program, 0 otherwise */ static int want_askpass() { @@ -113,7 +113,7 @@ TRACE(("leave gui_getpass")) return(buf); } -#endif /* ENABLE_CLI_ASKPASS_HELPER */ +#endif /* DROPBEAR_CLI_ASKPASS_HELPER */ void cli_auth_password() { @@ -125,7 +125,7 @@ snprintf(prompt, sizeof(prompt), "%s@%s's password: ", cli_opts.username, cli_opts.remotehost); -#ifdef ENABLE_CLI_ASKPASS_HELPER +#if DROPBEAR_CLI_ASKPASS_HELPER if (want_askpass()) { password = gui_getpass(prompt); @@ -158,4 +158,4 @@ TRACE(("leave cli_auth_password")) } -#endif /* ENABLE_CLI_PASSWORD_AUTH */ +#endif /* DROPBEAR_CLI_PASSWORD_AUTH */
--- a/cli-authpubkey.c Thu May 18 23:38:30 2017 +0800 +++ b/cli-authpubkey.c Thu May 18 23:45:10 2017 +0800 @@ -32,7 +32,7 @@ #include "auth.h" #include "agentfwd.h" -#ifdef ENABLE_CLI_PUBKEY_AUTH +#if DROPBEAR_CLI_PUBKEY_AUTH static void send_msg_userauth_pubkey(sign_key *key, int type, int realsign); /* Called when we receive a SSH_MSG_USERAUTH_FAILURE for a pubkey request. @@ -122,7 +122,7 @@ void cli_buf_put_sign(buffer* buf, sign_key *key, int type, buffer *data_buf) { -#ifdef ENABLE_CLI_AGENTFWD +#if DROPBEAR_CLI_AGENTFWD if (key->source == SIGNKEY_SOURCE_AGENT) { /* Format the agent signature ourselves, as buf_put_sign would. */ buffer *sigblob; @@ -131,7 +131,7 @@ buf_putbufstring(buf, sigblob); buf_free(sigblob); } else -#endif /* ENABLE_CLI_AGENTFWD */ +#endif /* DROPBEAR_CLI_AGENTFWD */ { buf_put_sign(buf, key, type, data_buf); } @@ -185,7 +185,7 @@ TRACE(("enter cli_auth_pubkey")) -#ifdef ENABLE_CLI_AGENTFWD +#if DROPBEAR_CLI_AGENTFWD if (!cli_opts.agent_keys_loaded) { /* get the list of available keys from the agent */ cli_load_agent_keys(cli_opts.privkeys); @@ -209,7 +209,7 @@ void cli_auth_pubkey_cleanup() { -#ifdef ENABLE_CLI_AGENTFWD +#if DROPBEAR_CLI_AGENTFWD m_close(cli_opts.agent_fd); cli_opts.agent_fd = -1; #endif
--- a/cli-chansession.c Thu May 18 23:38:30 2017 +0800 +++ b/cli-chansession.c Thu May 18 23:45:10 2017 +0800 @@ -355,7 +355,7 @@ cli_init_stdpipe_sess(channel); -#ifdef ENABLE_CLI_AGENTFWD +#if DROPBEAR_CLI_AGENTFWD if (cli_opts.agent_fwd) { cli_setup_agent(channel); } @@ -379,7 +379,7 @@ return 0; /* Success */ } -#ifdef ENABLE_CLI_NETCAT +#if DROPBEAR_CLI_NETCAT static const struct ChanType cli_chan_netcat = { 0, /* sepfds */
--- a/cli-kex.c Thu May 18 23:38:30 2017 +0800 +++ b/cli-kex.c Thu May 18 23:45:10 2017 +0800 @@ -48,6 +48,7 @@ CHECKCLEARTOWRITE(); buf_putbyte(ses.writepayload, SSH_MSG_KEXDH_INIT); switch (ses.newkeys->algo_kex->mode) { +#if DROPBEAR_NORMAL_DH case DROPBEAR_KEX_NORMAL_DH: if (ses.newkeys->algo_kex != cli_ses.param_kex_algo || !cli_ses.dh_param) { @@ -58,8 +59,9 @@ } buf_putmpint(ses.writepayload, &cli_ses.dh_param->pub); break; +#endif +#if DROPBEAR_ECDH case DROPBEAR_KEX_ECDH: -#ifdef DROPBEAR_ECDH if (ses.newkeys->algo_kex != cli_ses.param_kex_algo || !cli_ses.ecdh_param) { if (cli_ses.ecdh_param) { @@ -68,9 +70,9 @@ cli_ses.ecdh_param = gen_kexecdh_param(); } buf_put_ecc_raw_pubkey_string(ses.writepayload, &cli_ses.ecdh_param->key); + break; #endif - break; -#ifdef DROPBEAR_CURVE25519 +#if DROPBEAR_CURVE25519 case DROPBEAR_KEX_CURVE25519: if (ses.newkeys->algo_kex != cli_ses.param_kex_algo || !cli_ses.curve25519_param) { @@ -80,8 +82,8 @@ cli_ses.curve25519_param = gen_kexcurve25519_param(); } buf_putstring(ses.writepayload, (const char*)cli_ses.curve25519_param->pub, CURVE25519_LEN); + break; #endif - break; } cli_ses.param_kex_algo = ses.newkeys->algo_kex; @@ -118,6 +120,7 @@ } switch (ses.newkeys->algo_kex->mode) { +#if DROPBEAR_NORMAL_DH case DROPBEAR_KEX_NORMAL_DH: { DEF_MP_INT(dh_f); @@ -131,37 +134,38 @@ mp_clear(&dh_f); } break; +#endif +#if DROPBEAR_ECDH case DROPBEAR_KEX_ECDH: -#ifdef DROPBEAR_ECDH { buffer *ecdh_qs = buf_getstringbuf(ses.payload); kexecdh_comb_key(cli_ses.ecdh_param, ecdh_qs, hostkey); buf_free(ecdh_qs); } + break; #endif - break; -#ifdef DROPBEAR_CURVE25519 +#if DROPBEAR_CURVE25519 case DROPBEAR_KEX_CURVE25519: { buffer *ecdh_qs = buf_getstringbuf(ses.payload); kexcurve25519_comb_key(cli_ses.curve25519_param, ecdh_qs, hostkey); buf_free(ecdh_qs); } + break; #endif - break; } if (cli_ses.dh_param) { free_kexdh_param(cli_ses.dh_param); cli_ses.dh_param = NULL; } -#ifdef DROPBEAR_ECDH +#if DROPBEAR_ECDH if (cli_ses.ecdh_param) { free_kexecdh_param(cli_ses.ecdh_param); cli_ses.ecdh_param = NULL; } #endif -#ifdef DROPBEAR_CURVE25519 +#if DROPBEAR_CURVE25519 if (cli_ses.curve25519_param) { free_kexcurve25519_param(cli_ses.curve25519_param); cli_ses.curve25519_param = NULL;
--- a/cli-main.c Thu May 18 23:38:30 2017 +0800 +++ b/cli-main.c Thu May 18 23:45:10 2017 +0800 @@ -35,13 +35,13 @@ static void cli_dropbear_exit(int exitcode, const char* format, va_list param) ATTRIB_NORETURN; static void cli_dropbear_log(int priority, const char* format, va_list param); -#ifdef ENABLE_CLI_PROXYCMD +#if DROPBEAR_CLI_PROXYCMD static void cli_proxy_cmd(int *sock_in, int *sock_out, pid_t *pid_out); static void kill_proxy_sighandler(int signo); #endif -#if defined(DBMULTI_dbclient) || !defined(DROPBEAR_MULTI) -#if defined(DBMULTI_dbclient) && defined(DROPBEAR_MULTI) +#if defined(DBMULTI_dbclient) || !DROPBEAR_MULTI +#if defined(DBMULTI_dbclient) && DROPBEAR_MULTI int cli_main(int argc, char ** argv) { #else int main(int argc, char ** argv) { @@ -74,7 +74,7 @@ } pid_t proxy_cmd_pid = 0; -#ifdef ENABLE_CLI_PROXYCMD +#if DROPBEAR_CLI_PROXYCMD if (cli_opts.proxycmd) { cli_proxy_cmd(&sock_in, &sock_out, &proxy_cmd_pid); m_free(cli_opts.proxycmd); @@ -151,7 +151,7 @@ dropbear_exit("Failed to run '%s'\n", cmd); } -#ifdef ENABLE_CLI_PROXYCMD +#if DROPBEAR_CLI_PROXYCMD static void cli_proxy_cmd(int *sock_in, int *sock_out, pid_t *pid_out) { char * ex_cmd = NULL; size_t ex_cmdlen; @@ -176,4 +176,4 @@ kill_proxy_command(); _exit(1); } -#endif /* ENABLE_CLI_PROXYCMD */ +#endif /* DROPBEAR_CLI_PROXYCMD */
--- a/cli-runopts.c Thu May 18 23:38:30 2017 +0800 +++ b/cli-runopts.c Thu May 18 23:45:10 2017 +0800 @@ -37,13 +37,13 @@ static void parse_hostname(const char* orighostarg); static void parse_multihop_hostname(const char* orighostarg, const char* argv0); static void fill_own_user(void); -#ifdef ENABLE_CLI_PUBKEY_AUTH +#if DROPBEAR_CLI_PUBKEY_AUTH static void loadidentityfile(const char* filename, int warnfail); #endif -#ifdef ENABLE_CLI_ANYTCPFWD +#if DROPBEAR_CLI_ANYTCPFWD static void addforward(const char* str, m_list *fwdlist); #endif -#ifdef ENABLE_CLI_NETCAT +#if DROPBEAR_CLI_NETCAT static void add_netcat(const char *str); #endif static void add_extendedopt(const char *str); @@ -51,7 +51,7 @@ static void printhelp() { fprintf(stderr, "Dropbear SSH client v%s https://matt.ucc.asn.au/dropbear/dropbear.html\n" -#ifdef ENABLE_CLI_MULTIHOP +#if DROPBEAR_CLI_MULTIHOP "Usage: %s [options] [user@]host[/port][,[user@]host/port],...] [command]\n" #else "Usage: %s [options] [user@]host[/port] [command]\n" @@ -66,38 +66,38 @@ "-y -y Don't perform any remote host key checking (caution)\n" "-s Request a subsystem (use by external sftp)\n" "-o option Set option in OpenSSH-like format ('-o help' to list options)\n" -#ifdef ENABLE_CLI_PUBKEY_AUTH +#if DROPBEAR_CLI_PUBKEY_AUTH "-i <identityfile> (multiple allowed, default %s)\n" #endif -#ifdef ENABLE_CLI_AGENTFWD +#if DROPBEAR_CLI_AGENTFWD "-A Enable agent auth forwarding\n" #endif -#ifdef ENABLE_CLI_LOCALTCPFWD +#if DROPBEAR_CLI_LOCALTCPFWD "-L <[listenaddress:]listenport:remotehost:remoteport> Local port forwarding\n" "-g Allow remote hosts to connect to forwarded ports\n" #endif -#ifdef ENABLE_CLI_REMOTETCPFWD +#if DROPBEAR_CLI_REMOTETCPFWD "-R <[listenaddress:]listenport:remotehost:remoteport> Remote port forwarding\n" #endif "-W <receive_window_buffer> (default %d, larger may be faster, max 1MB)\n" "-K <keepalive> (0 is never, default %d)\n" "-I <idle_timeout> (0 is never, default %d)\n" -#ifdef ENABLE_CLI_NETCAT +#if DROPBEAR_CLI_NETCAT "-B <endhost:endport> Netcat-alike forwarding\n" #endif -#ifdef ENABLE_CLI_PROXYCMD +#if DROPBEAR_CLI_PROXYCMD "-J <proxy_program> Use program pipe rather than TCP connection\n" #endif -#ifdef ENABLE_USER_ALGO_LIST +#if DROPBEAR_USER_ALGO_LIST "-c <cipher list> Specify preferred ciphers ('-c help' to list options)\n" "-m <MAC list> Specify preferred MACs for packet verification (or '-m help')\n" #endif "-V Version\n" -#ifdef DEBUG_TRACE +#if DEBUG_TRACE "-v verbose (compiled with DEBUG_TRACE)\n" #endif ,DROPBEAR_VERSION, cli_opts.progname, -#ifdef ENABLE_CLI_PUBKEY_AUTH +#if DROPBEAR_CLI_PUBKEY_AUTH DROPBEAR_DEFAULT_CLI_AUTHKEY, #endif DEFAULT_RECV_WINDOW, DEFAULT_KEEPALIVE, DEFAULT_IDLE_TIMEOUT); @@ -109,16 +109,16 @@ char ** next = 0; enum { OPT_EXTENDED_OPTIONS, -#ifdef ENABLE_CLI_PUBKEY_AUTH +#if DROPBEAR_CLI_PUBKEY_AUTH OPT_AUTHKEY, #endif -#ifdef ENABLE_CLI_LOCALTCPFWD +#if DROPBEAR_CLI_LOCALTCPFWD OPT_LOCALTCPFWD, #endif -#ifdef ENABLE_CLI_REMOTETCPFWD +#if DROPBEAR_CLI_REMOTETCPFWD OPT_REMOTETCPFWD, #endif -#ifdef ENABLE_CLI_NETCAT +#if DROPBEAR_CLI_NETCAT OPT_NETCAT, #endif /* a flag (no arg) if 'next' is NULL, a string-valued option otherwise */ @@ -145,31 +145,31 @@ cli_opts.always_accept_key = 0; cli_opts.no_hostkey_check = 0; cli_opts.is_subsystem = 0; -#ifdef ENABLE_CLI_PUBKEY_AUTH +#if DROPBEAR_CLI_PUBKEY_AUTH cli_opts.privkeys = list_new(); #endif -#ifdef ENABLE_CLI_ANYTCPFWD +#if DROPBEAR_CLI_ANYTCPFWD cli_opts.exit_on_fwd_failure = 0; #endif -#ifdef ENABLE_CLI_LOCALTCPFWD +#if DROPBEAR_CLI_LOCALTCPFWD cli_opts.localfwds = list_new(); opts.listen_fwd_all = 0; #endif -#ifdef ENABLE_CLI_REMOTETCPFWD +#if DROPBEAR_CLI_REMOTETCPFWD cli_opts.remotefwds = list_new(); #endif -#ifdef ENABLE_CLI_AGENTFWD +#if DROPBEAR_CLI_AGENTFWD cli_opts.agent_fwd = 0; cli_opts.agent_fd = -1; cli_opts.agent_keys_loaded = 0; #endif -#ifdef ENABLE_CLI_PROXYCMD +#if DROPBEAR_CLI_PROXYCMD cli_opts.proxycmd = NULL; #endif #ifndef DISABLE_ZLIB opts.compress_mode = DROPBEAR_COMPRESS_ON; #endif -#ifdef ENABLE_USER_ALGO_LIST +#if DROPBEAR_USER_ALGO_LIST opts.cipher_list = NULL; opts.mac_list = NULL; #endif @@ -213,7 +213,7 @@ case 'p': /* remoteport */ next = &cli_opts.remoteport; break; -#ifdef ENABLE_CLI_PUBKEY_AUTH +#if DROPBEAR_CLI_PUBKEY_AUTH case 'i': /* an identityfile */ opt = OPT_AUTHKEY; break; @@ -236,7 +236,7 @@ case 'o': opt = OPT_EXTENDED_OPTIONS; break; -#ifdef ENABLE_CLI_LOCALTCPFWD +#if DROPBEAR_CLI_LOCALTCPFWD case 'L': opt = OPT_LOCALTCPFWD; break; @@ -244,17 +244,17 @@ opts.listen_fwd_all = 1; break; #endif -#ifdef ENABLE_CLI_REMOTETCPFWD +#if DROPBEAR_CLI_REMOTETCPFWD case 'R': opt = OPT_REMOTETCPFWD; break; #endif -#ifdef ENABLE_CLI_NETCAT +#if DROPBEAR_CLI_NETCAT case 'B': opt = OPT_NETCAT; break; #endif -#ifdef ENABLE_CLI_PROXYCMD +#if DROPBEAR_CLI_PROXYCMD case 'J': next = &cli_opts.proxycmd; break; @@ -278,12 +278,12 @@ case 'I': next = &idle_timeout_arg; break; -#ifdef ENABLE_CLI_AGENTFWD +#if DROPBEAR_CLI_AGENTFWD case 'A': cli_opts.agent_fwd = 1; break; #endif -#ifdef ENABLE_USER_ALGO_LIST +#if DROPBEAR_USER_ALGO_LIST case 'c': next = &opts.cipher_list; break; @@ -291,22 +291,22 @@ next = &opts.mac_list; break; #endif -#ifdef DEBUG_TRACE +#if DEBUG_TRACE case 'v': debug_trace = 1; break; #endif case 'F': case 'e': -#ifndef ENABLE_USER_ALGO_LIST +#if !DROPBEAR_USER_ALGO_LIST case 'c': case 'm': #endif case 'D': -#ifndef ENABLE_CLI_REMOTETCPFWD +#ifndef DROPBEAR_CLI_REMOTETCPFWD case 'R': #endif -#ifndef ENABLE_CLI_LOCALTCPFWD +#ifndef DROPBEAR_CLI_LOCALTCPFWD case 'L': #endif case 'V': @@ -338,28 +338,28 @@ add_extendedopt(&argv[i][j]); } else -#ifdef ENABLE_CLI_PUBKEY_AUTH +#if DROPBEAR_CLI_PUBKEY_AUTH if (opt == OPT_AUTHKEY) { TRACE(("opt authkey")) loadidentityfile(&argv[i][j], 1); } else #endif -#ifdef ENABLE_CLI_REMOTETCPFWD +#if DROPBEAR_CLI_REMOTETCPFWD if (opt == OPT_REMOTETCPFWD) { TRACE(("opt remotetcpfwd")) addforward(&argv[i][j], cli_opts.remotefwds); } else #endif -#ifdef ENABLE_CLI_LOCALTCPFWD +#if DROPBEAR_CLI_LOCALTCPFWD if (opt == OPT_LOCALTCPFWD) { TRACE(("opt localtcpfwd")) addforward(&argv[i][j], cli_opts.localfwds); } else #endif -#ifdef ENABLE_CLI_NETCAT +#if DROPBEAR_CLI_NETCAT if (opt == OPT_NETCAT) { TRACE(("opt netcat")) add_netcat(&argv[i][j]); @@ -405,11 +405,11 @@ /* And now a few sanity checks and setup */ -#ifdef ENABLE_USER_ALGO_LIST +#if DROPBEAR_USER_ALGO_LIST parse_ciphers_macs(); #endif -#ifdef ENABLE_CLI_PROXYCMD +#if DROPBEAR_CLI_PROXYCMD if (cli_opts.proxycmd) { /* To match the common path of m_freeing it */ cli_opts.proxycmd = m_strdup(cli_opts.proxycmd); @@ -457,13 +457,13 @@ opts.idle_timeout_secs = val; } -#ifdef ENABLE_CLI_NETCAT +#if DROPBEAR_CLI_NETCAT if (cli_opts.cmd && cli_opts.netcat_host) { dropbear_log(LOG_INFO, "Ignoring command '%s' in netcat mode", cli_opts.cmd); } #endif -#if defined(DROPBEAR_DEFAULT_CLI_AUTHKEY) && defined(ENABLE_CLI_PUBKEY_AUTH) +#if (DROPBEAR_CLI_PUBKEY_AUTH) { char *expand_path = expand_homedir_path(DROPBEAR_DEFAULT_CLI_AUTHKEY); loadidentityfile(expand_path, 0); @@ -474,14 +474,14 @@ /* The hostname gets set up last, since * in multi-hop mode it will require knowledge * of other flags such as -i */ -#ifdef ENABLE_CLI_MULTIHOP +#if DROPBEAR_CLI_MULTIHOP parse_multihop_hostname(host_arg, argv[0]); #else parse_hostname(host_arg); #endif } -#ifdef ENABLE_CLI_PUBKEY_AUTH +#if DROPBEAR_CLI_PUBKEY_AUTH static void loadidentityfile(const char* filename, int warnfail) { sign_key *key; enum signkey_type keytype; @@ -504,7 +504,7 @@ } #endif -#ifdef ENABLE_CLI_MULTIHOP +#if DROPBEAR_CLI_MULTIHOP static char* multihop_passthrough_args() { @@ -514,13 +514,13 @@ m_list_elem *iter; /* Fill out -i, -y, -W options that make sense for all * the intermediate processes */ -#ifdef ENABLE_CLI_PUBKEY_AUTH +#if DROPBEAR_CLI_PUBKEY_AUTH for (iter = cli_opts.privkeys->first; iter; iter = iter->next) { sign_key * key = (sign_key*)iter->item; len += 3 + strlen(key->filename); } -#endif /* ENABLE_CLI_PUBKEY_AUTH */ +#endif /* DROPBEAR_CLI_PUBKEY_AUTH */ len += 30; /* space for -W <size>, terminator. */ ret = m_malloc(len); @@ -543,7 +543,7 @@ total += written; } -#ifdef ENABLE_CLI_PUBKEY_AUTH +#if DROPBEAR_CLI_PUBKEY_AUTH for (iter = cli_opts.privkeys->first; iter; iter = iter->next) { sign_key * key = (sign_key*)iter->item; @@ -552,7 +552,7 @@ dropbear_assert((unsigned int)written < size); total += written; } -#endif /* ENABLE_CLI_PUBKEY_AUTH */ +#endif /* DROPBEAR_CLI_PUBKEY_AUTH */ /* if args were passed, total will be not zero, and it will have a space at the end, so remove that */ if (total > 0) @@ -636,7 +636,7 @@ } m_free(hostbuf); } -#endif /* !ENABLE_CLI_MULTIHOP */ +#endif /* !DROPBEAR_CLI_MULTIHOP */ /* Parses a [user@]hostname[/port] argument. */ static void parse_hostname(const char* orighostarg) { @@ -675,7 +675,7 @@ } } -#ifdef ENABLE_CLI_NETCAT +#if DROPBEAR_CLI_NETCAT static void add_netcat(const char* origstr) { char *portstr = NULL; @@ -728,7 +728,7 @@ } -#ifdef ENABLE_CLI_ANYTCPFWD +#if DROPBEAR_CLI_ANYTCPFWD /* Turn a "[listenaddr:]listenport:remoteaddr:remoteport" string into into a forwarding * set, and add it to the forwarding list */ static void addforward(const char* origstr, m_list *fwdlist) { @@ -870,7 +870,7 @@ if (strcmp(origstr, "help") == 0) { dropbear_log(LOG_INFO, "Available options:\n" -#ifdef ENABLE_CLI_ANYTCPFWD +#if DROPBEAR_CLI_ANYTCPFWD "\tExitOnForwardFailure\n" #endif #ifndef DISABLE_SYSLOG @@ -880,7 +880,7 @@ exit(EXIT_SUCCESS); } -#ifdef ENABLE_CLI_ANYTCPFWD +#if DROPBEAR_CLI_ANYTCPFWD if (match_extendedopt(&optstr, "ExitOnForwardFailure") == DROPBEAR_SUCCESS) { cli_opts.exit_on_fwd_failure = parse_flag_value(optstr); return;
--- a/cli-session.c Thu May 18 23:38:30 2017 +0800 +++ b/cli-session.c Thu May 18 23:45:10 2017 +0800 @@ -73,7 +73,7 @@ {SSH_MSG_GLOBAL_REQUEST, recv_msg_global_request_cli}, {SSH_MSG_CHANNEL_SUCCESS, ignore_recv_response}, {SSH_MSG_CHANNEL_FAILURE, ignore_recv_response}, -#ifdef ENABLE_CLI_REMOTETCPFWD +#if DROPBEAR_CLI_REMOTETCPFWD {SSH_MSG_REQUEST_SUCCESS, cli_recv_msg_request_success}, /* client */ {SSH_MSG_REQUEST_FAILURE, cli_recv_msg_request_failure}, /* client */ #else @@ -85,10 +85,10 @@ }; static const struct ChanType *cli_chantypes[] = { -#ifdef ENABLE_CLI_REMOTETCPFWD +#if DROPBEAR_CLI_REMOTETCPFWD &cli_chan_tcpremote, #endif -#ifdef ENABLE_CLI_AGENTFWD +#if DROPBEAR_CLI_AGENTFWD &cli_chan_agent, #endif NULL /* Null termination */ @@ -133,7 +133,7 @@ } -#ifdef USE_KEX_FIRST_FOLLOWS +#if DROPBEAR_KEX_FIRST_FOLLOWS static void cli_send_kex_first_guess() { send_msg_kexdh_init(); } @@ -165,7 +165,7 @@ cli_ses.lastprivkey = NULL; cli_ses.lastauthtype = 0; -#ifdef DROPBEAR_NONE_CIPHER +#if DROPBEAR_NONE_CIPHER cli_ses.cipher_none_after_auth = get_algo_usable(sshciphers, "none"); set_algo_usable(sshciphers, "none", 0); #else @@ -182,7 +182,7 @@ ses.isserver = 0; -#ifdef USE_KEX_FIRST_FOLLOWS +#if DROPBEAR_KEX_FIRST_FOLLOWS ses.send_kex_first_guess = cli_send_kex_first_guess; #endif @@ -275,7 +275,7 @@ } #endif -#ifdef DROPBEAR_NONE_CIPHER +#if DROPBEAR_NONE_CIPHER if (cli_ses.cipher_none_after_auth) { set_algo_usable(sshciphers, "none", 1); @@ -299,7 +299,7 @@ } } -#ifdef ENABLE_CLI_NETCAT +#if DROPBEAR_CLI_NETCAT if (cli_opts.netcat_host) { cli_send_netcat_request(); } else @@ -308,10 +308,10 @@ cli_send_chansess_request(); } -#ifdef ENABLE_CLI_LOCALTCPFWD +#if DROPBEAR_CLI_LOCALTCPFWD setup_localtcp(); #endif -#ifdef ENABLE_CLI_REMOTETCPFWD +#if DROPBEAR_CLI_REMOTETCPFWD setup_remotetcp(); #endif
--- a/cli-tcpfwd.c Thu May 18 23:38:30 2017 +0800 +++ b/cli-tcpfwd.c Thu May 18 23:45:10 2017 +0800 @@ -32,7 +32,7 @@ #include "ssh.h" #include "netio.h" -#ifdef ENABLE_CLI_REMOTETCPFWD +#if DROPBEAR_CLI_REMOTETCPFWD static int newtcpforwarded(struct Channel * channel); const struct ChanType cli_chan_tcpremote = { @@ -45,7 +45,7 @@ }; #endif -#ifdef ENABLE_CLI_LOCALTCPFWD +#if DROPBEAR_CLI_LOCALTCPFWD static int cli_localtcp(const char* listenaddr, unsigned int listenport, const char* remoteaddr, @@ -60,7 +60,7 @@ }; #endif -#ifdef ENABLE_CLI_ANYTCPFWD +#if DROPBEAR_CLI_ANYTCPFWD static void fwd_failed(const char* format, ...) ATTRIB_PRINTF(1,2); static void fwd_failed(const char* format, ...) { @@ -77,7 +77,7 @@ } #endif -#ifdef ENABLE_CLI_LOCALTCPFWD +#if DROPBEAR_CLI_LOCALTCPFWD void setup_localtcp() { m_list_elem *iter; int ret; @@ -144,9 +144,9 @@ TRACE(("leave cli_localtcp: %d", ret)) return ret; } -#endif /* ENABLE_CLI_LOCALTCPFWD */ +#endif /* DROPBEAR_CLI_LOCALTCPFWD */ -#ifdef ENABLE_CLI_REMOTETCPFWD +#if DROPBEAR_CLI_REMOTETCPFWD static void send_msg_global_request_remotetcp(const char *addr, int port) { TRACE(("enter send_msg_global_request_remotetcp")) @@ -234,7 +234,7 @@ char *origaddr = NULL; unsigned int origport; m_list_elem * iter = NULL; - struct TCPFwdEntry *fwd; + struct TCPFwdEntry *fwd = NULL; char portstring[NI_MAXSERV]; int err = SSH_OPEN_ADMINISTRATIVELY_PROHIBITED; @@ -265,7 +265,7 @@ } - if (iter == NULL) { + if (iter == NULL || fwd == NULL) { /* We didn't request forwarding on that port */ cleantext(origaddr); dropbear_log(LOG_INFO, "Server sent unrequested forward from \"%s:%d\"", @@ -285,4 +285,4 @@ TRACE(("leave newtcpdirect: err %d", err)) return err; } -#endif /* ENABLE_CLI_REMOTETCPFWD */ +#endif /* DROPBEAR_CLI_REMOTETCPFWD */
--- a/common-algo.c Thu May 18 23:38:30 2017 +0800 +++ b/common-algo.c Thu May 18 23:45:10 2017 +0800 @@ -53,27 +53,27 @@ /* Remember to add new ciphers/hashes to regciphers/reghashes too */ -#ifdef DROPBEAR_AES256 +#if DROPBEAR_AES256 static const struct dropbear_cipher dropbear_aes256 = {&aes_desc, 32, 16}; #endif -#ifdef DROPBEAR_AES128 +#if DROPBEAR_AES128 static const struct dropbear_cipher dropbear_aes128 = {&aes_desc, 16, 16}; #endif -#ifdef DROPBEAR_BLOWFISH +#if DROPBEAR_BLOWFISH static const struct dropbear_cipher dropbear_blowfish = {&blowfish_desc, 16, 8}; #endif -#ifdef DROPBEAR_TWOFISH256 +#if DROPBEAR_TWOFISH256 static const struct dropbear_cipher dropbear_twofish256 = {&twofish_desc, 32, 16}; #endif -#ifdef DROPBEAR_TWOFISH128 +#if DROPBEAR_TWOFISH128 static const struct dropbear_cipher dropbear_twofish128 = {&twofish_desc, 16, 16}; #endif -#ifdef DROPBEAR_3DES +#if DROPBEAR_3DES static const struct dropbear_cipher dropbear_3des = {&des3_desc, 24, 8}; #endif @@ -84,7 +84,7 @@ /* A few void* s are required to silence warnings * about the symmetric_CBC vs symmetric_CTR cipher_state pointer */ -#ifdef DROPBEAR_ENABLE_CBC_MODE +#if DROPBEAR_ENABLE_CBC_MODE const struct dropbear_cipher_mode dropbear_mode_cbc = {(void*)cbc_start, (void*)cbc_encrypt, (void*)cbc_decrypt}; #endif /* DROPBEAR_ENABLE_CBC_MODE */ @@ -92,7 +92,7 @@ const struct dropbear_cipher_mode dropbear_mode_none = {void_start, void_cipher, void_cipher}; -#ifdef DROPBEAR_ENABLE_CTR_MODE +#if DROPBEAR_ENABLE_CTR_MODE /* a wrapper to make ctr_start and cbc_start look the same */ static int dropbear_big_endian_ctr_start(int cipher, const unsigned char *IV, @@ -107,23 +107,23 @@ /* Mapping of ssh hashes to libtomcrypt hashes, including keysize etc. {&hash_desc, keysize, hashsize} */ -#ifdef DROPBEAR_SHA1_HMAC +#if DROPBEAR_SHA1_HMAC static const struct dropbear_hash dropbear_sha1 = {&sha1_desc, 20, 20}; #endif -#ifdef DROPBEAR_SHA1_96_HMAC +#if DROPBEAR_SHA1_96_HMAC static const struct dropbear_hash dropbear_sha1_96 = {&sha1_desc, 20, 12}; #endif -#ifdef DROPBEAR_SHA2_256_HMAC +#if DROPBEAR_SHA2_256_HMAC static const struct dropbear_hash dropbear_sha2_256 = {&sha256_desc, 32, 32}; #endif -#ifdef DROPBEAR_SHA2_512_HMAC +#if DROPBEAR_SHA2_512_HMAC static const struct dropbear_hash dropbear_sha2_512 = {&sha512_desc, 64, 64}; #endif -#ifdef DROPBEAR_MD5_HMAC +#if DROPBEAR_MD5_HMAC static const struct dropbear_hash dropbear_md5 = {&md5_desc, 16, 16}; #endif @@ -137,73 +137,70 @@ * that is also supported by the server will get used. */ algo_type sshciphers[] = { -#ifdef DROPBEAR_ENABLE_CTR_MODE -#ifdef DROPBEAR_AES128 +#if DROPBEAR_ENABLE_CTR_MODE +#if DROPBEAR_AES128 {"aes128-ctr", 0, &dropbear_aes128, 1, &dropbear_mode_ctr}, #endif -#ifdef DROPBEAR_AES256 +#if DROPBEAR_AES256 {"aes256-ctr", 0, &dropbear_aes256, 1, &dropbear_mode_ctr}, #endif -#ifdef DROPBEAR_TWOFISH_CTR +#if DROPBEAR_TWOFISH_CTR /* twofish ctr is conditional as it hasn't been tested for interoperability, see options.h */ -#ifdef DROPBEAR_TWOFISH256 +#if DROPBEAR_TWOFISH256 {"twofish256-ctr", 0, &dropbear_twofish256, 1, &dropbear_mode_ctr}, #endif -#ifdef DROPBEAR_TWOFISH128 +#if DROPBEAR_TWOFISH128 {"twofish128-ctr", 0, &dropbear_twofish128, 1, &dropbear_mode_ctr}, #endif #endif /* DROPBEAR_TWOFISH_CTR */ #endif /* DROPBEAR_ENABLE_CTR_MODE */ -#ifdef DROPBEAR_ENABLE_CBC_MODE -#ifdef DROPBEAR_AES128 +#if DROPBEAR_ENABLE_CBC_MODE +#if DROPBEAR_AES128 {"aes128-cbc", 0, &dropbear_aes128, 1, &dropbear_mode_cbc}, #endif -#ifdef DROPBEAR_AES256 +#if DROPBEAR_AES256 {"aes256-cbc", 0, &dropbear_aes256, 1, &dropbear_mode_cbc}, #endif -#ifdef DROPBEAR_TWOFISH256 +#if DROPBEAR_TWOFISH256 {"twofish256-cbc", 0, &dropbear_twofish256, 1, &dropbear_mode_cbc}, {"twofish-cbc", 0, &dropbear_twofish256, 1, &dropbear_mode_cbc}, #endif -#ifdef DROPBEAR_TWOFISH128 +#if DROPBEAR_TWOFISH128 {"twofish128-cbc", 0, &dropbear_twofish128, 1, &dropbear_mode_cbc}, #endif -#ifdef DROPBEAR_3DES +#if DROPBEAR_3DES {"3des-ctr", 0, &dropbear_3des, 1, &dropbear_mode_ctr}, #endif -#ifdef DROPBEAR_3DES +#if DROPBEAR_3DES {"3des-cbc", 0, &dropbear_3des, 1, &dropbear_mode_cbc}, #endif -#ifdef DROPBEAR_BLOWFISH +#if DROPBEAR_BLOWFISH {"blowfish-cbc", 0, &dropbear_blowfish, 1, &dropbear_mode_cbc}, #endif #endif /* DROPBEAR_ENABLE_CBC_MODE */ -#ifdef DROPBEAR_NONE_CIPHER +#if DROPBEAR_NONE_CIPHER {"none", 0, (void*)&dropbear_nocipher, 1, &dropbear_mode_none}, #endif {NULL, 0, NULL, 0, NULL} }; algo_type sshhashes[] = { -#ifdef DROPBEAR_SHA1_96_HMAC +#if DROPBEAR_SHA1_96_HMAC {"hmac-sha1-96", 0, &dropbear_sha1_96, 1, NULL}, #endif -#ifdef DROPBEAR_SHA1_HMAC +#if DROPBEAR_SHA1_HMAC {"hmac-sha1", 0, &dropbear_sha1, 1, NULL}, #endif -#ifdef DROPBEAR_SHA2_256_HMAC +#if DROPBEAR_SHA2_256_HMAC {"hmac-sha2-256", 0, &dropbear_sha2_256, 1, NULL}, #endif -#ifdef DROPBEAR_SHA2_512_HMAC +#if DROPBEAR_SHA2_512_HMAC {"hmac-sha2-512", 0, &dropbear_sha2_512, 1, NULL}, #endif -#ifdef DROPBEAR_MD5_HMAC +#if DROPBEAR_MD5_HMAC {"hmac-md5", 0, (void*)&dropbear_md5, 1, NULL}, #endif -#ifdef DROPBEAR_NONE_INTEGRITY - {"none", 0, (void*)&dropbear_nohash, 1, NULL}, -#endif {NULL, 0, NULL, 0, NULL} }; @@ -228,21 +225,21 @@ }; algo_type sshhostkey[] = { -#ifdef DROPBEAR_ECDSA -#ifdef DROPBEAR_ECC_256 +#if DROPBEAR_ECDSA +#if DROPBEAR_ECC_256 {"ecdsa-sha2-nistp256", DROPBEAR_SIGNKEY_ECDSA_NISTP256, NULL, 1, NULL}, #endif -#ifdef DROPBEAR_ECC_384 +#if DROPBEAR_ECC_384 {"ecdsa-sha2-nistp384", DROPBEAR_SIGNKEY_ECDSA_NISTP384, NULL, 1, NULL}, #endif -#ifdef DROPBEAR_ECC_521 +#if DROPBEAR_ECC_521 {"ecdsa-sha2-nistp521", DROPBEAR_SIGNKEY_ECDSA_NISTP521, NULL, 1, NULL}, #endif #endif -#ifdef DROPBEAR_RSA +#if DROPBEAR_RSA {"ssh-rsa", DROPBEAR_SIGNKEY_RSA, NULL, 1, NULL}, #endif -#ifdef DROPBEAR_DSS +#if DROPBEAR_DSS {"ssh-dss", DROPBEAR_SIGNKEY_DSS, NULL, 1, NULL}, #endif {NULL, 0, NULL, 0, NULL} @@ -251,63 +248,63 @@ #if DROPBEAR_DH_GROUP1 static const struct dropbear_kex kex_dh_group1 = {DROPBEAR_KEX_NORMAL_DH, dh_p_1, DH_P_1_LEN, NULL, &sha1_desc }; #endif -#if DROPBEAR_DH_GROUP14 +#if DROPBEAR_DH_GROUP14_SHA1 static const struct dropbear_kex kex_dh_group14_sha1 = {DROPBEAR_KEX_NORMAL_DH, dh_p_14, DH_P_14_LEN, NULL, &sha1_desc }; -#if DROPBEAR_DH_GROUP14_256 +#endif +#if DROPBEAR_DH_GROUP14_SHA256 static const struct dropbear_kex kex_dh_group14_sha256 = {DROPBEAR_KEX_NORMAL_DH, dh_p_14, DH_P_14_LEN, NULL, &sha256_desc }; #endif -#endif #if DROPBEAR_DH_GROUP16 static const struct dropbear_kex kex_dh_group16_sha512 = {DROPBEAR_KEX_NORMAL_DH, dh_p_16, DH_P_16_LEN, NULL, &sha512_desc }; #endif /* These can't be const since dropbear_ecc_fill_dp() fills out ecc_curve at runtime */ -#ifdef DROPBEAR_ECDH -#ifdef DROPBEAR_ECC_256 +#if DROPBEAR_ECDH +#if DROPBEAR_ECC_256 static const struct dropbear_kex kex_ecdh_nistp256 = {DROPBEAR_KEX_ECDH, NULL, 0, &ecc_curve_nistp256, &sha256_desc }; #endif -#ifdef DROPBEAR_ECC_384 +#if DROPBEAR_ECC_384 static const struct dropbear_kex kex_ecdh_nistp384 = {DROPBEAR_KEX_ECDH, NULL, 0, &ecc_curve_nistp384, &sha384_desc }; #endif -#ifdef DROPBEAR_ECC_521 +#if DROPBEAR_ECC_521 static const struct dropbear_kex kex_ecdh_nistp521 = {DROPBEAR_KEX_ECDH, NULL, 0, &ecc_curve_nistp521, &sha512_desc }; #endif #endif /* DROPBEAR_ECDH */ -#ifdef DROPBEAR_CURVE25519 +#if DROPBEAR_CURVE25519 /* Referred to directly */ static const struct dropbear_kex kex_curve25519 = {DROPBEAR_KEX_CURVE25519, NULL, 0, NULL, &sha256_desc }; #endif algo_type sshkex[] = { -#ifdef DROPBEAR_CURVE25519 +#if DROPBEAR_CURVE25519 {"[email protected]", 0, &kex_curve25519, 1, NULL}, #endif -#ifdef DROPBEAR_ECDH -#ifdef DROPBEAR_ECC_521 +#if DROPBEAR_ECDH +#if DROPBEAR_ECC_521 {"ecdh-sha2-nistp521", 0, &kex_ecdh_nistp521, 1, NULL}, #endif -#ifdef DROPBEAR_ECC_384 +#if DROPBEAR_ECC_384 {"ecdh-sha2-nistp384", 0, &kex_ecdh_nistp384, 1, NULL}, #endif -#ifdef DROPBEAR_ECC_256 +#if DROPBEAR_ECC_256 {"ecdh-sha2-nistp256", 0, &kex_ecdh_nistp256, 1, NULL}, #endif #endif -#if DROPBEAR_DH_GROUP14 -#if DROPBEAR_DH_GROUP14_256 +#if DROPBEAR_DH_GROUP14_SHA1 + {"diffie-hellman-group14-sha1", 0, &kex_dh_group14_sha1, 1, NULL}, +#endif +#if DROPBEAR_DH_GROUP14_SHA256 {"diffie-hellman-group14-sha256", 0, &kex_dh_group14_sha256, 1, NULL}, #endif - {"diffie-hellman-group14-sha1", 0, &kex_dh_group14_sha1, 1, NULL}, -#endif #if DROPBEAR_DH_GROUP1 {"diffie-hellman-group1-sha1", 0, &kex_dh_group1, 1, NULL}, #endif #if DROPBEAR_DH_GROUP16 {"diffie-hellman-group16-sha512", 0, &kex_dh_group16_sha512, 1, NULL}, #endif -#ifdef USE_KEXGUESS2 +#if DROPBEAR_KEXGUESS2 {KEXGUESS2_ALGO_NAME, KEXGUESS2_ALGO_ID, NULL, 1, NULL}, #endif {NULL, 0, NULL, 0, NULL} @@ -349,6 +346,7 @@ } } buf_putstring(buf, (const char*)algolist->data, algolist->len); + TRACE(("algolist add '%*s'", algolist->len, algolist->data)) buf_free(algolist); } @@ -468,7 +466,7 @@ return ret; } -#ifdef DROPBEAR_NONE_CIPHER +#if DROPBEAR_NONE_CIPHER void set_algo_usable(algo_type algos[], const char * algo_name, int usable) @@ -500,7 +498,7 @@ #endif /* DROPBEAR_NONE_CIPHER */ -#ifdef ENABLE_USER_ALGO_LIST +#if DROPBEAR_USER_ALGO_LIST char * algolist_string(algo_type algos[]) @@ -577,4 +575,4 @@ memcpy(algos, new_algos, sizeof(*new_algos) * (n+1)); return n; } -#endif /* ENABLE_USER_ALGO_LIST */ +#endif /* DROPBEAR_USER_ALGO_LIST */
--- a/common-channel.c Thu May 18 23:38:30 2017 +0800 +++ b/common-channel.c Thu May 18 23:45:10 2017 +0800 @@ -32,7 +32,6 @@ #include "circbuffer.h" #include "dbutil.h" #include "channel.h" -#include "ssh.h" #include "listener.h" #include "runopts.h" #include "netio.h" @@ -78,7 +77,7 @@ ses.chantypes = chantypes; -#ifdef USING_LISTENERS +#if DROPBEAR_LISTENERS listeners_initialise(); #endif @@ -255,7 +254,7 @@ } } -#ifdef USING_LISTENERS +#if DROPBEAR_LISTENERS handle_listeners(readfds); #endif } @@ -595,7 +594,7 @@ } /* foreach channel */ -#ifdef USING_LISTENERS +#if DROPBEAR_LISTENERS set_listener_fds(readfds); #endif @@ -1114,7 +1113,7 @@ } -#if defined(USING_LISTENERS) || defined(DROPBEAR_CLIENT) +#if (DROPBEAR_LISTENERS) || (DROPBEAR_CLIENT) /* Create a new channel, and start the open request. This is intended * for X11, agent, tcp forwarding, and should be filled with channel-specific * options, with the calling function calling encrypt_packet() after @@ -1210,7 +1209,7 @@ remove_channel(channel); } -#endif /* USING_LISTENERS */ +#endif /* DROPBEAR_LISTENERS */ void send_msg_request_success() { CHECKCLEARTOWRITE();
--- a/common-kex.c Thu May 18 23:38:30 2017 +0800 +++ b/common-kex.c Thu May 18 23:45:10 2017 +0800 @@ -640,7 +640,7 @@ finish_kexhashbuf(); } -#ifdef DROPBEAR_ECDH +#if DROPBEAR_ECDH struct kex_ecdh_param *gen_kexecdh_param() { struct kex_ecdh_param *param = m_malloc(sizeof(*param)); if (ecc_make_key_ex(NULL, dropbear_ltc_prng, @@ -692,7 +692,7 @@ } #endif /* DROPBEAR_ECDH */ -#ifdef DROPBEAR_CURVE25519 +#if DROPBEAR_CURVE25519 struct kex_curve25519_param *gen_kexcurve25519_param () { /* Per http://cr.yp.to/ecdh.html */ struct kex_curve25519_param *param = m_malloc(sizeof(*param)); @@ -774,7 +774,7 @@ hash_desc->done(&hs, buf_getwriteptr(ses.hash, hash_desc->hashsize)); buf_setlen(ses.hash, hash_desc->hashsize); -#if defined(DEBUG_KEXHASH) && defined(DEBUG_TRACE) +#if (DEBUG_KEXHASH) && (DEBUG_TRACE) if (!debug_trace) { printhex("kexhashbuf", ses.kexhashbuf->data, ses.kexhashbuf->len); printhex("kexhash", ses.hash->data, ses.hash->len); @@ -814,7 +814,7 @@ int allgood = 1; /* we AND this with each goodguess and see if its still true after */ -#ifdef USE_KEXGUESS2 +#if DROPBEAR_KEXGUESS2 enum kexguess2_used kexguess2 = KEXGUESS2_LOOK; #else enum kexguess2_used kexguess2 = KEXGUESS2_NO;
--- a/common-runopts.c Thu May 18 23:38:30 2017 +0800 +++ b/common-runopts.c Thu May 18 23:45:10 2017 +0800 @@ -62,7 +62,7 @@ return ret; } -#ifdef ENABLE_USER_ALGO_LIST +#if DROPBEAR_USER_ALGO_LIST void parse_ciphers_macs() {
--- a/common-session.c Thu May 18 23:38:30 2017 +0800 +++ b/common-session.c Thu May 18 23:45:10 2017 +0800 @@ -54,7 +54,7 @@ void common_session_init(int sock_in, int sock_out) { time_t now; -#ifdef DEBUG_TRACE +#if DEBUG_TRACE debug_start_net(); #endif @@ -295,7 +295,7 @@ } /* After these are freed most functions will fail */ -#ifdef DROPBEAR_CLEANUP +#if DROPBEAR_CLEANUP /* listeners call cleanup functions, this should occur before other session state is freed. */ remove_all_listeners();
--- a/compat.c Thu May 18 23:38:30 2017 +0800 +++ b/compat.c Thu May 18 23:45:10 2017 +0800 @@ -114,8 +114,8 @@ #endif /* HAVE_STRLCPY */ #ifndef HAVE_STRLCAT -/* taken from openbsd-compat for OpenSSH 3.6.1p1 */ -/* "$OpenBSD: strlcat.c,v 1.8 2001/05/13 15:40:15 deraadt Exp $" +/* taken from openbsd-compat for OpenSSH 7.2p2 */ +/* "$OpenBSD: strlcat.c,v 1.13 2005/08/08 08:05:37 espie Exp $" * * Appends src to string dst of size siz (unlike strncat, siz is the * full size of dst, not space left). At most siz-1 characters @@ -123,15 +123,12 @@ * Returns strlen(src) + MIN(siz, strlen(initial dst)). * If retval >= siz, truncation occurred. */ - size_t -strlcat(dst, src, siz) - char *dst; - const char *src; - size_t siz; +size_t +strlcat(char *dst, const char *src, size_t siz) { - register char *d = dst; - register const char *s = src; - register size_t n = siz; + char *d = dst; + const char *s = src; + size_t n = siz; size_t dlen; /* Find the end of dst and adjust bytes left but don't go past end */
--- a/crypto_desc.c Thu May 18 23:38:30 2017 +0800 +++ b/crypto_desc.c Thu May 18 23:45:10 2017 +0800 @@ -4,7 +4,7 @@ #include "ltc_prng.h" #include "ecc.h" -#ifdef DROPBEAR_LTC_PRNG +#if DROPBEAR_LTC_PRNG int dropbear_ltc_prng = -1; #endif @@ -14,16 +14,16 @@ void crypto_init() { const struct ltc_cipher_descriptor *regciphers[] = { -#ifdef DROPBEAR_AES +#if DROPBEAR_AES &aes_desc, #endif -#ifdef DROPBEAR_BLOWFISH +#if DROPBEAR_BLOWFISH &blowfish_desc, #endif -#ifdef DROPBEAR_TWOFISH +#if DROPBEAR_TWOFISH &twofish_desc, #endif -#ifdef DROPBEAR_3DES +#if DROPBEAR_3DES &des3_desc, #endif NULL @@ -32,16 +32,16 @@ const struct ltc_hash_descriptor *reghashes[] = { /* we need sha1 for hostkey stuff regardless */ &sha1_desc, -#ifdef DROPBEAR_MD5_HMAC +#if DROPBEAR_MD5_HMAC &md5_desc, #endif -#ifdef DROPBEAR_SHA256 +#if DROPBEAR_SHA256 &sha256_desc, #endif -#ifdef DROPBEAR_SHA384 +#if DROPBEAR_SHA384 &sha384_desc, #endif -#ifdef DROPBEAR_SHA512 +#if DROPBEAR_SHA512 &sha512_desc, #endif NULL @@ -60,14 +60,14 @@ } } -#ifdef DROPBEAR_LTC_PRNG +#if DROPBEAR_LTC_PRNG dropbear_ltc_prng = register_prng(&dropbear_prng_desc); if (dropbear_ltc_prng == -1) { dropbear_exit("Error registering crypto"); } #endif -#ifdef DROPBEAR_ECC +#if DROPBEAR_ECC ltc_mp = ltm_desc; dropbear_ecc_fill_dp(); #endif
--- a/dbrandom.c Thu May 18 23:38:30 2017 +0800 +++ b/dbrandom.c Thu May 18 23:45:10 2017 +0800 @@ -61,7 +61,7 @@ unsigned int readcount; int ret = DROPBEAR_FAILURE; -#ifdef DROPBEAR_PRNGD_SOCKET +#if DROPBEAR_PRNGD_SOCKET if (prngd) { readfd = connect_unix(filename); @@ -109,7 +109,7 @@ wantread = MIN(sizeof(readbuf), len-readcount); } -#ifdef DROPBEAR_PRNGD_SOCKET +#if DROPBEAR_PRNGD_SOCKET if (prngd) { char egdcmd[2]; @@ -216,7 +216,7 @@ /* existing state */ sha1_process(&hs, (void*)hashpool, sizeof(hashpool)); -#ifdef DROPBEAR_PRNGD_SOCKET +#if DROPBEAR_PRNGD_SOCKET if (process_file(&hs, DROPBEAR_PRNGD_SOCKET, INIT_SEED_SIZE, 1) != DROPBEAR_SUCCESS) { dropbear_exit("Failure reading random device %s",
--- a/dbutil.c Thu May 18 23:38:30 2017 +0800 +++ b/dbutil.c Thu May 18 23:45:10 2017 +0800 @@ -79,7 +79,7 @@ void (*_dropbear_log)(int priority, const char* format, va_list param) = generic_dropbear_log; -#ifdef DEBUG_TRACE +#if DEBUG_TRACE int debug_trace = 0; #endif @@ -149,7 +149,7 @@ } -#ifdef DEBUG_TRACE +#if DEBUG_TRACE static double debug_start_time = -1; @@ -262,7 +262,7 @@ return DROPBEAR_FAILURE; } -#ifdef USE_VFORK +#if DROPBEAR_VFORK pid = vfork(); #else pid = fork(); @@ -371,7 +371,7 @@ execv(usershell, argv); } -#ifdef DEBUG_TRACE +#if DEBUG_TRACE void printhex(const char * label, const unsigned char * buf, int len) { int i; @@ -465,7 +465,7 @@ * authkeys file. * Will return DROPBEAR_SUCCESS if data is read, or DROPBEAR_FAILURE on EOF.*/ /* Only used for ~/.ssh/known_hosts and ~/.ssh/authorized_keys */ -#if defined(DROPBEAR_CLIENT) || defined(ENABLE_SVR_PUBKEY_AUTH) +#if DROPBEAR_CLIENT || DROPBEAR_SVR_PUBKEY_AUTH int buf_getline(buffer * line, FILE * authfile) { int c = EOF; @@ -681,4 +681,21 @@ return time(NULL); } +void fsync_parent_dir(const char* fn) { +#ifdef HAVE_LIBGEN_H + char *fn_dir = m_strdup(fn); + char *dir = dirname(fn_dir); + int dirfd = open(dir, O_RDONLY); + if (dirfd != -1) { + if (fsync(dirfd) != 0) { + TRACE(("fsync of directory %s failed: %s", dir, strerror(errno))) + } + m_close(dirfd); + } else { + TRACE(("error opening directory %s for fsync: %s", dir, strerror(errno))) + } + + free(fn_dir); +#endif +}
--- a/dbutil.h Thu May 18 23:38:30 2017 +0800 +++ b/dbutil.h Thu May 18 23:45:10 2017 +0800 @@ -45,7 +45,7 @@ void fail_assert(const char* expr, const char* file, int line) ATTRIB_NORETURN; -#ifdef DEBUG_TRACE +#if DEBUG_TRACE void dropbear_trace(const char* format, ...) ATTRIB_PRINTF(1,2); void dropbear_trace2(const char* format, ...) ATTRIB_PRINTF(1,2); void printhex(const char * label, const unsigned char * buf, int len); @@ -89,4 +89,6 @@ char * expand_homedir_path(const char *inpath); +void fsync_parent_dir(const char* fn); + #endif /* DROPBEAR_DBUTIL_H_ */
--- a/debian/changelog Thu May 18 23:38:30 2017 +0800 +++ b/debian/changelog Thu May 18 23:45:10 2017 +0800 @@ -1,3 +1,9 @@ +dropbear (2017.75-0.1) unstable; urgency=low + + * New upstream release. + + -- Matt Johnston <[email protected]> Thu, 18 May 2017 22:51:57 +0800 + dropbear (2016.74-0.1) unstable; urgency=low * New upstream release.
--- a/debug.h Thu May 18 23:38:30 2017 +0800 +++ b/debug.h Thu May 18 23:45:10 2017 +0800 @@ -39,7 +39,9 @@ * Caution: Don't use this in an unfriendly environment (ie unfirewalled), * since the printing may not sanitise strings etc. This will add a reasonable * amount to your executable size. */ -/*#define DEBUG_TRACE*/ +#ifndef DEBUG_TRACE +#define DEBUG_TRACE 0 +#endif /* All functions writing to the cleartext payload buffer call * CHECKCLEARTOWRITE() before writing. This is only really useful if you're @@ -61,7 +63,7 @@ /*#define DEBUG_RSA*/ /* you don't need to touch this block */ -#ifdef DEBUG_TRACE +#if DEBUG_TRACE #define TRACE(X) dropbear_trace X; #define TRACE2(X) dropbear_trace2 X; #else /*DEBUG_TRACE*/
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/default_options.h Thu May 18 23:45:10 2017 +0800 @@ -0,0 +1,458 @@ +#ifndef DROPBEAR_DEFAULT_OPTIONS_H_ +#define DROPBEAR_DEFAULT_OPTIONS_H_ +/* + > > > Read This < < < + +default_options.h.in (this file) documents compile-time options, and provides +default values. + +Local customisation should be added to localoptions.h which is +used if it exists. Options defined there will override any options in this +file (#ifndef guards added by ifndef_wrapper.sh). + +Options can also be defined with -DDROPBEAR_XXX Makefile CFLAGS + +IMPORTANT: Many options will require "make clean" after changes */ + +#ifndef DROPBEAR_DEFPORT +#define DROPBEAR_DEFPORT "22" +#endif + +/* Listen on all interfaces */ +#ifndef DROPBEAR_DEFADDRESS +#define DROPBEAR_DEFADDRESS "" +#endif + +/* Default hostkey paths - these can be specified on the command line */ +#ifndef DSS_PRIV_FILENAME +#define DSS_PRIV_FILENAME "/etc/dropbear/dropbear_dss_host_key" +#endif +#ifndef RSA_PRIV_FILENAME +#define RSA_PRIV_FILENAME "/etc/dropbear/dropbear_rsa_host_key" +#endif +#ifndef ECDSA_PRIV_FILENAME +#define ECDSA_PRIV_FILENAME "/etc/dropbear/dropbear_ecdsa_host_key" +#endif + +/* Set NON_INETD_MODE if you require daemon functionality (ie Dropbear listens + * on chosen ports and keeps accepting connections. This is the default. + * + * Set INETD_MODE if you want to be able to run Dropbear with inetd (or + * similar), where it will use stdin/stdout for connections, and each process + * lasts for a single connection. Dropbear should be invoked with the -i flag + * for inetd, and can only accept IPv4 connections. + * + * Both of these flags can be defined at once, don't compile without at least + * one of them. */ +#ifndef NON_INETD_MODE +#define NON_INETD_MODE 1 +#endif +#ifndef INETD_MODE +#define INETD_MODE 1 +#endif + +/* Setting this disables the fast exptmod bignum code. It saves ~5kB, but is + * perhaps 20% slower for pubkey operations (it is probably worth experimenting + * 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 and hashes +slower, perhaps by 50%. Recommended for small systems that aren't doing +much traffic. */ +#ifndef DROPBEAR_SMALL_CODE +#define DROPBEAR_SMALL_CODE 1 +#endif + +/* Enable X11 Forwarding - server only */ +#ifndef DROPBEAR_X11FWD +#define DROPBEAR_X11FWD 1 +#endif + +/* Enable TCP Fowarding */ +/* 'Local' is "-L" style (client listening port forwarded via server) + * 'Remote' is "-R" style (server listening port forwarded via client) */ + +#ifndef DROPBEAR_CLI_LOCALTCPFWD +#define DROPBEAR_CLI_LOCALTCPFWD 1 +#endif +#ifndef DROPBEAR_CLI_REMOTETCPFWD +#define DROPBEAR_CLI_REMOTETCPFWD 1 +#endif + +#ifndef DROPBEAR_SVR_LOCALTCPFWD +#define DROPBEAR_SVR_LOCALTCPFWD 1 +#endif +#ifndef DROPBEAR_SVR_REMOTETCPFWD +#define DROPBEAR_SVR_REMOTETCPFWD 1 +#endif + +/* Enable Authentication Agent Forwarding */ +#ifndef DROPBEAR_SVR_AGENTFWD +#define DROPBEAR_SVR_AGENTFWD 1 +#endif +#ifndef DROPBEAR_CLI_AGENTFWD +#define DROPBEAR_CLI_AGENTFWD 1 +#endif + + +/* Note: Both DROPBEAR_CLI_PROXYCMD and DROPBEAR_CLI_NETCAT must be set to + * allow multihop dbclient connections */ + +/* Allow using -J <proxycommand> to run the connection through a + pipe to a program, rather the normal TCP connection */ +#ifndef DROPBEAR_CLI_PROXYCMD +#define DROPBEAR_CLI_PROXYCMD 1 +#endif + +/* Enable "Netcat mode" option. This will forward standard input/output + * to a remote TCP-forwarded connection */ +#ifndef DROPBEAR_CLI_NETCAT +#define DROPBEAR_CLI_NETCAT 1 +#endif + +/* Whether to support "-c" and "-m" flags to choose ciphers/MACs at runtime */ +#ifndef ENABLE_USER_ALGO_LIST +#define ENABLE_USER_ALGO_LIST 1 +#endif + +/* Encryption - at least one required. + * Protocol RFC requires 3DES and recommends AES128 for interoperability. + * Including multiple keysize variants the same cipher + * (eg AES256 as well as AES128) will result in a minimal size increase.*/ +#ifndef DROPBEAR_AES128 +#define DROPBEAR_AES128 1 +#endif +#ifndef DROPBEAR_3DES +#define DROPBEAR_3DES 1 +#endif +#ifndef DROPBEAR_AES256 +#define DROPBEAR_AES256 1 +#endif +/* Compiling in Blowfish will add ~6kB to runtime heap memory usage */ +/*#define DROPBEAR_BLOWFISH*/ +#ifndef DROPBEAR_TWOFISH256 +#define DROPBEAR_TWOFISH256 1 +#endif +#ifndef DROPBEAR_TWOFISH128 +#define DROPBEAR_TWOFISH128 1 +#endif + +/* Enable CBC mode for ciphers. This has security issues though + * is the most compatible with older SSH implementations */ +#ifndef DROPBEAR_ENABLE_CBC_MODE +#define DROPBEAR_ENABLE_CBC_MODE 1 +#endif + +/* Enable "Counter Mode" for ciphers. This is more secure than normal + * CBC mode against certain attacks. It is recommended for security + * and forwards compatibility */ +#ifndef DROPBEAR_ENABLE_CTR_MODE +#define DROPBEAR_ENABLE_CTR_MODE 1 +#endif + +/* Twofish counter mode is disabled by default because it +has not been tested for interoperability with other SSH implementations. +If you test it please contact the Dropbear author */ +#ifndef DROPBEAR_TWOFISH_CTR +#define DROPBEAR_TWOFISH_CTR 0 +#endif + +/* Message integrity. sha2-256 is recommended as a default, + sha1 for compatibility */ +#ifndef DROPBEAR_SHA1_HMAC +#define DROPBEAR_SHA1_HMAC 1 +#endif +#ifndef DROPBEAR_SHA1_96_HMAC +#define DROPBEAR_SHA1_96_HMAC 1 +#endif +#ifndef DROPBEAR_SHA2_256_HMAC +#define DROPBEAR_SHA2_256_HMAC 1 +#endif +/* Default is to include it is sha512 is being compiled in for ECDSA */ +#ifndef DROPBEAR_SHA2_512_HMAC +#define DROPBEAR_SHA2_512_HMAC (DROPBEAR_ECDSA) +#endif + +/* XXX needed for fingerprints */ +#ifndef DROPBEAR_MD5_HMAC +#define DROPBEAR_MD5_HMAC 0 +#endif + +/* Hostkey/public key algorithms - at least one required, these are used + * for hostkey as well as for verifying signatures with pubkey auth. + * Removing either of these won't save very much space. + * RSA is recommended + * DSS may be necessary to connect to some systems though + is not recommended for new keys */ +#ifndef DROPBEAR_RSA +#define DROPBEAR_RSA 1 +#endif +#ifndef DROPBEAR_DSS +#define DROPBEAR_DSS 1 +#endif +/* ECDSA is significantly faster than RSA or DSS. Compiling in ECC + * code (either ECDSA or ECDH) increases binary size - around 30kB + * on x86-64 */ +#ifndef DROPBEAR_ECDSA +#define DROPBEAR_ECDSA 1 +#endif + +/* Add runtime flag "-R" to generate hostkeys as-needed when the first + connection using that key type occurs. + This avoids the need to otherwise run "dropbearkey" and avoids some problems + with badly seeded /dev/urandom when systems first boot. */ +#ifndef DROPBEAR_DELAY_HOSTKEY +#define DROPBEAR_DELAY_HOSTKEY 1 +#endif + +/* Enable Curve25519 for key exchange. This is another elliptic + * curve method with good security properties. Increases binary size + * by ~8kB on x86-64 */ +#ifndef DROPBEAR_CURVE25519 +#define DROPBEAR_CURVE25519 1 +#endif + +/* Enable elliptic curve Diffie Hellman key exchange, see note about + * ECDSA above */ +#ifndef DROPBEAR_ECDH +#define DROPBEAR_ECDH 1 +#endif + +/* Key exchange algorithm. + * group14_sha1 - 2048 bit, sha1 + * group14_sha256 - 2048 bit, sha2-256 + * group16 - 4096 bit, sha2-512 + * group1 - 1024 bit, sha1 + * + * group14 is supported by most implementations. + * group16 provides a greater strength level but is slower and increases binary size + * group1 is too small for security though is necessary if you need + compatibility with some implementations such as Dropbear versions < 0.53 + */ +#ifndef DROPBEAR_DH_GROUP1 +#define DROPBEAR_DH_GROUP1 1 +#endif +#ifndef DROPBEAR_DH_GROUP14_SHA1 +#define DROPBEAR_DH_GROUP14_SHA1 1 +#endif +#ifndef DROPBEAR_DH_GROUP14_SHA256 +#define DROPBEAR_DH_GROUP14_SHA256 1 +#endif +#ifndef DROPBEAR_DH_GROUP16 +#define DROPBEAR_DH_GROUP16 0 +#endif + +/* Control the memory/performance/compression tradeoff for zlib. + * Set windowBits=8 for least memory usage, see your system's + * zlib.h for full details. + * Default settings (windowBits=15) will use 256kB for compression + * windowBits=8 will use 129kB for compression. + * Both modes will use ~35kB for decompression (using windowBits=15 for + * interoperability) */ +#ifndef DROPBEAR_ZLIB_WINDOW_BITS +#define DROPBEAR_ZLIB_WINDOW_BITS 15 +#endif + +/* Whether to do reverse DNS lookups. */ +#ifndef DO_HOST_LOOKUP +#define DO_HOST_LOOKUP 0 +#endif + +/* Whether to print the message of the day (MOTD). */ +#ifndef DO_MOTD +#define DO_MOTD 0 +#endif + +/* The MOTD file path */ +#ifndef MOTD_FILENAME +#define MOTD_FILENAME "/etc/motd" +#endif + +/* Authentication Types - at least one required. + RFC Draft requires pubkey auth, and recommends password */ + +/* Note: PAM auth is quite simple and only works for PAM modules which just do + * a simple "Login: " "Password: " (you can edit the strings in svr-authpam.c). + * It's useful for systems like OS X where standard password crypts don't work + * but there's an interface via a PAM module. It won't work for more complex + * PAM challenge/response. + * You can't enable both PASSWORD and PAM. */ + +/* This requires crypt() */ +#ifdef HAVE_CRYPT +#ifndef DROPBEAR_SVR_PASSWORD_AUTH +#define DROPBEAR_SVR_PASSWORD_AUTH 1 +#endif +#else +#ifndef DROPBEAR_SVR_PASSWORD_AUTH +#define DROPBEAR_SVR_PASSWORD_AUTH 0 +#endif +#endif +/* PAM requires ./configure --enable-pam */ +#ifndef DROPBEAR_SVR_PAM_AUTH +#define DROPBEAR_SVR_PAM_AUTH 0 +#endif +#ifndef DROPBEAR_SVR_PUBKEY_AUTH +#define DROPBEAR_SVR_PUBKEY_AUTH 1 +#endif + +/* Whether to take public key options in + * authorized_keys file into account */ +#ifndef DROPBEAR_SVR_PUBKEY_OPTIONS +#define DROPBEAR_SVR_PUBKEY_OPTIONS 1 +#endif + +/* This requires getpass. */ +#ifdef HAVE_GETPASS +#ifndef DROPBEAR_CLI_PASSWORD_AUTH +#define DROPBEAR_CLI_PASSWORD_AUTH 1 +#endif +#ifndef DROPBEAR_CLI_INTERACT_AUTH +#define DROPBEAR_CLI_INTERACT_AUTH 1 +#endif +#endif +#ifndef DROPBEAR_CLI_PUBKEY_AUTH +#define DROPBEAR_CLI_PUBKEY_AUTH 1 +#endif + +/* A default argument for dbclient -i <privatekey>. +Homedir is prepended unless path begins with / */ +#ifndef DROPBEAR_DEFAULT_CLI_AUTHKEY +#define DROPBEAR_DEFAULT_CLI_AUTHKEY ".ssh/id_dropbear" +#endif + +/* This variable can be used to set a password for client + * authentication on the commandline. Beware of platforms + * that don't protect environment variables of processes etc. Also + * note that it will be provided for all "hidden" client-interactive + * style prompts - if you want something more sophisticated, use + * SSH_ASKPASS instead. Comment out this var to remove this functionality.*/ +#ifndef DROPBEAR_PASSWORD_ENV +#define DROPBEAR_PASSWORD_ENV "DROPBEAR_PASSWORD" +#endif + +/* Define this (as well as DROPBEAR_CLI_PASSWORD_AUTH) to allow the use of + * a helper program for the ssh client. The helper program should be + * specified in the SSH_ASKPASS environment variable, and dbclient + * should be run with DISPLAY set and no tty. The program should + * return the password on standard output */ +#ifndef DROPBEAR_CLI_ASKPASS_HELPER +#define DROPBEAR_CLI_ASKPASS_HELPER 0 +#endif + +/* Save a network roundtrip by sendng a real auth request immediately after + * sending a query for the available methods. It is at the expense of < 100 + * bytes of extra network traffic. This is not yet enabled by default since it + * could cause problems with non-compliant servers */ +#ifndef DROPBEAR_CLI_IMMEDIATE_AUTH +#define DROPBEAR_CLI_IMMEDIATE_AUTH 0 +#endif + +/* Source for randomness. This must be able to provide hundreds of bytes per SSH + * connection without blocking. In addition /dev/random is used for seeding + * rsa/dss key generation */ +#ifndef DROPBEAR_URANDOM_DEV +#define DROPBEAR_URANDOM_DEV "/dev/urandom" +#endif + +/* Set this to use PRNGD or EGD instead of /dev/urandom or /dev/random */ +/*#define DROPBEAR_PRNGD_SOCKET "/var/run/dropbear-rng"*/ + + +/* Specify the number of clients we will allow to be connected but + * not yet authenticated. After this limit, connections are rejected */ +/* The first setting is per-IP, to avoid denial of service */ +#ifndef MAX_UNAUTH_PER_IP +#define MAX_UNAUTH_PER_IP 5 +#endif + +/* And then a global limit to avoid chewing memory if connections + * come from many IPs */ +#ifndef MAX_UNAUTH_CLIENTS +#define MAX_UNAUTH_CLIENTS 30 +#endif + +/* Maximum number of failed authentication tries (server option) */ +#ifndef MAX_AUTH_TRIES +#define MAX_AUTH_TRIES 10 +#endif + +/* The default file to store the daemon's process ID, for shutdown + scripts etc. This can be overridden with the -P flag */ +#ifndef DROPBEAR_PIDFILE +#define DROPBEAR_PIDFILE "/var/run/dropbear.pid" +#endif + +/* The command to invoke for xauth when using X11 forwarding. + * "-q" for quiet */ +#ifndef XAUTH_COMMAND +#define XAUTH_COMMAND "/usr/bin/xauth -q" +#endif + +/* if you want to enable running an sftp server (such as the one included with + * OpenSSH), set the path below. If the path isn't defined, sftp will not + * be enabled */ +#ifndef SFTPSERVER_PATH +#define SFTPSERVER_PATH "/usr/libexec/sftp-server" +#endif + +/* This is used by the scp binary when used as a client binary. If you're + * not using the Dropbear client, you'll need to change it */ +#ifndef DROPBEAR_PATH_SSH_PROGRAM +#define DROPBEAR_PATH_SSH_PROGRAM "/usr/bin/dbclient" +#endif + +/* Whether to log commands executed by a client. This only logs the + * (single) command sent to the server, not what a user did in a + * shell/sftp session etc. */ +#ifndef LOG_COMMANDS +#define LOG_COMMANDS 0 +#endif + +/* Window size limits. These tend to be a trade-off between memory + usage and network performance: */ +/* Size of the network receive window. This amount of memory is allocated + as a per-channel receive buffer. Increasing this value can make a + significant difference to network performance. 24kB was empirically + chosen for a 100mbit ethernet network. The value can be altered at + runtime with the -W argument. */ +#ifndef DEFAULT_RECV_WINDOW +#define DEFAULT_RECV_WINDOW 24576 +#endif +/* Maximum size of a received SSH data packet - this _MUST_ be >= 32768 + in order to interoperate with other implementations */ +#ifndef RECV_MAX_PAYLOAD_LEN +#define RECV_MAX_PAYLOAD_LEN 32768 +#endif +/* Maximum size of a transmitted data packet - this can be any value, + though increasing it may not make a significant difference. */ +#ifndef TRANS_MAX_PAYLOAD_LEN +#define TRANS_MAX_PAYLOAD_LEN 16384 +#endif + +/* Ensure that data is transmitted every KEEPALIVE seconds. This can +be overridden at runtime with -K. 0 disables keepalives */ +#ifndef DEFAULT_KEEPALIVE +#define DEFAULT_KEEPALIVE 0 +#endif + +/* If this many KEEPALIVES are sent with no packets received from the +other side, exit. Not run-time configurable - if you have a need +for runtime configuration please mail the Dropbear list */ +#ifndef DEFAULT_KEEPALIVE_LIMIT +#define DEFAULT_KEEPALIVE_LIMIT 3 +#endif + +/* Ensure that data is received within IDLE_TIMEOUT seconds. This can +be overridden at runtime with -I. 0 disables idle timeouts */ +#ifndef DEFAULT_IDLE_TIMEOUT +#define DEFAULT_IDLE_TIMEOUT 0 +#endif + +/* The default path. This will often get replaced by the shell */ +#ifndef DEFAULT_PATH +#define DEFAULT_PATH "/usr/bin:/bin" +#endif + +#endif /* DROPBEAR_DEFAULT_OPTIONS_H_ */
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/default_options.h.in Thu May 18 23:45:10 2017 +0800 @@ -0,0 +1,312 @@ +#ifndef DROPBEAR_DEFAULT_OPTIONS_H_ +#define DROPBEAR_DEFAULT_OPTIONS_H_ +/* + > > > Read This < < < + +default_options.h.in (this file) documents compile-time options, and provides +default values. + +Local customisation should be added to localoptions.h which is +used if it exists. Options defined there will override any options in this +file (#ifndef guards added by ifndef_wrapper.sh). + +Options can also be defined with -DDROPBEAR_XXX Makefile CFLAGS + +IMPORTANT: Many options will require "make clean" after changes */ + +#define DROPBEAR_DEFPORT "22" + +/* Listen on all interfaces */ +#define DROPBEAR_DEFADDRESS "" + +/* Default hostkey paths - these can be specified on the command line */ +#define DSS_PRIV_FILENAME "/etc/dropbear/dropbear_dss_host_key" +#define RSA_PRIV_FILENAME "/etc/dropbear/dropbear_rsa_host_key" +#define ECDSA_PRIV_FILENAME "/etc/dropbear/dropbear_ecdsa_host_key" + +/* Set NON_INETD_MODE if you require daemon functionality (ie Dropbear listens + * on chosen ports and keeps accepting connections. This is the default. + * + * Set INETD_MODE if you want to be able to run Dropbear with inetd (or + * similar), where it will use stdin/stdout for connections, and each process + * lasts for a single connection. Dropbear should be invoked with the -i flag + * for inetd, and can only accept IPv4 connections. + * + * Both of these flags can be defined at once, don't compile without at least + * one of them. */ +#define NON_INETD_MODE 1 +#define INETD_MODE 1 + +/* Setting this disables the fast exptmod bignum code. It saves ~5kB, but is + * perhaps 20% slower for pubkey operations (it is probably worth experimenting + * 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 and hashes +slower, perhaps by 50%. Recommended for small systems that aren't doing +much traffic. */ +#define DROPBEAR_SMALL_CODE 1 + +/* Enable X11 Forwarding - server only */ +#define DROPBEAR_X11FWD 1 + +/* Enable TCP Fowarding */ +/* 'Local' is "-L" style (client listening port forwarded via server) + * 'Remote' is "-R" style (server listening port forwarded via client) */ + +#define DROPBEAR_CLI_LOCALTCPFWD 1 +#define DROPBEAR_CLI_REMOTETCPFWD 1 + +#define DROPBEAR_SVR_LOCALTCPFWD 1 +#define DROPBEAR_SVR_REMOTETCPFWD 1 + +/* Enable Authentication Agent Forwarding */ +#define DROPBEAR_SVR_AGENTFWD 1 +#define DROPBEAR_CLI_AGENTFWD 1 + + +/* Note: Both DROPBEAR_CLI_PROXYCMD and DROPBEAR_CLI_NETCAT must be set to + * allow multihop dbclient connections */ + +/* Allow using -J <proxycommand> to run the connection through a + pipe to a program, rather the normal TCP connection */ +#define DROPBEAR_CLI_PROXYCMD 1 + +/* Enable "Netcat mode" option. This will forward standard input/output + * to a remote TCP-forwarded connection */ +#define DROPBEAR_CLI_NETCAT 1 + +/* Whether to support "-c" and "-m" flags to choose ciphers/MACs at runtime */ +#define ENABLE_USER_ALGO_LIST 1 + +/* Encryption - at least one required. + * Protocol RFC requires 3DES and recommends AES128 for interoperability. + * Including multiple keysize variants the same cipher + * (eg AES256 as well as AES128) will result in a minimal size increase.*/ +#define DROPBEAR_AES128 1 +#define DROPBEAR_3DES 1 +#define DROPBEAR_AES256 1 +/* Compiling in Blowfish will add ~6kB to runtime heap memory usage */ +/*#define DROPBEAR_BLOWFISH*/ +#define DROPBEAR_TWOFISH256 1 +#define DROPBEAR_TWOFISH128 1 + +/* Enable CBC mode for ciphers. This has security issues though + * is the most compatible with older SSH implementations */ +#define DROPBEAR_ENABLE_CBC_MODE 1 + +/* Enable "Counter Mode" for ciphers. This is more secure than normal + * CBC mode against certain attacks. It is recommended for security + * and forwards compatibility */ +#define DROPBEAR_ENABLE_CTR_MODE 1 + +/* Twofish counter mode is disabled by default because it +has not been tested for interoperability with other SSH implementations. +If you test it please contact the Dropbear author */ +#define DROPBEAR_TWOFISH_CTR 0 + +/* Message integrity. sha2-256 is recommended as a default, + sha1 for compatibility */ +#define DROPBEAR_SHA1_HMAC 1 +#define DROPBEAR_SHA1_96_HMAC 1 +#define DROPBEAR_SHA2_256_HMAC 1 +/* Default is to include it is sha512 is being compiled in for ECDSA */ +#define DROPBEAR_SHA2_512_HMAC (DROPBEAR_ECDSA) + +/* XXX needed for fingerprints */ +#define DROPBEAR_MD5_HMAC 0 + +/* Hostkey/public key algorithms - at least one required, these are used + * for hostkey as well as for verifying signatures with pubkey auth. + * Removing either of these won't save very much space. + * RSA is recommended + * DSS may be necessary to connect to some systems though + is not recommended for new keys */ +#define DROPBEAR_RSA 1 +#define DROPBEAR_DSS 1 +/* ECDSA is significantly faster than RSA or DSS. Compiling in ECC + * code (either ECDSA or ECDH) increases binary size - around 30kB + * on x86-64 */ +#define DROPBEAR_ECDSA 1 + +/* Add runtime flag "-R" to generate hostkeys as-needed when the first + connection using that key type occurs. + This avoids the need to otherwise run "dropbearkey" and avoids some problems + with badly seeded /dev/urandom when systems first boot. */ +#define DROPBEAR_DELAY_HOSTKEY 1 + +/* Enable Curve25519 for key exchange. This is another elliptic + * curve method with good security properties. Increases binary size + * by ~8kB on x86-64 */ +#define DROPBEAR_CURVE25519 1 + +/* Enable elliptic curve Diffie Hellman key exchange, see note about + * ECDSA above */ +#define DROPBEAR_ECDH 1 + +/* Key exchange algorithm. + * group14_sha1 - 2048 bit, sha1 + * group14_sha256 - 2048 bit, sha2-256 + * group16 - 4096 bit, sha2-512 + * group1 - 1024 bit, sha1 + * + * group14 is supported by most implementations. + * group16 provides a greater strength level but is slower and increases binary size + * group1 is too small for security though is necessary if you need + compatibility with some implementations such as Dropbear versions < 0.53 + */ +#define DROPBEAR_DH_GROUP1 1 +#define DROPBEAR_DH_GROUP14_SHA1 1 +#define DROPBEAR_DH_GROUP14_SHA256 1 +#define DROPBEAR_DH_GROUP16 0 + +/* Control the memory/performance/compression tradeoff for zlib. + * Set windowBits=8 for least memory usage, see your system's + * zlib.h for full details. + * Default settings (windowBits=15) will use 256kB for compression + * windowBits=8 will use 129kB for compression. + * Both modes will use ~35kB for decompression (using windowBits=15 for + * interoperability) */ +#define DROPBEAR_ZLIB_WINDOW_BITS 15 + +/* Whether to do reverse DNS lookups. */ +#define DO_HOST_LOOKUP 0 + +/* Whether to print the message of the day (MOTD). */ +#define DO_MOTD 0 + +/* The MOTD file path */ +#define MOTD_FILENAME "/etc/motd" + +/* Authentication Types - at least one required. + RFC Draft requires pubkey auth, and recommends password */ + +/* Note: PAM auth is quite simple and only works for PAM modules which just do + * a simple "Login: " "Password: " (you can edit the strings in svr-authpam.c). + * It's useful for systems like OS X where standard password crypts don't work + * but there's an interface via a PAM module. It won't work for more complex + * PAM challenge/response. + * You can't enable both PASSWORD and PAM. */ + +/* This requires crypt() */ +#ifdef HAVE_CRYPT +#define DROPBEAR_SVR_PASSWORD_AUTH 1 +#else +#define DROPBEAR_SVR_PASSWORD_AUTH 0 +#endif +/* PAM requires ./configure --enable-pam */ +#define DROPBEAR_SVR_PAM_AUTH 0 +#define DROPBEAR_SVR_PUBKEY_AUTH 1 + +/* Whether to take public key options in + * authorized_keys file into account */ +#define DROPBEAR_SVR_PUBKEY_OPTIONS 1 + +/* This requires getpass. */ +#ifdef HAVE_GETPASS +#define DROPBEAR_CLI_PASSWORD_AUTH 1 +#define DROPBEAR_CLI_INTERACT_AUTH 1 +#endif +#define DROPBEAR_CLI_PUBKEY_AUTH 1 + +/* A default argument for dbclient -i <privatekey>. +Homedir is prepended unless path begins with / */ +#define DROPBEAR_DEFAULT_CLI_AUTHKEY ".ssh/id_dropbear" + +/* This variable can be used to set a password for client + * authentication on the commandline. Beware of platforms + * that don't protect environment variables of processes etc. Also + * note that it will be provided for all "hidden" client-interactive + * style prompts - if you want something more sophisticated, use + * SSH_ASKPASS instead. Comment out this var to remove this functionality.*/ +#define DROPBEAR_PASSWORD_ENV "DROPBEAR_PASSWORD" + +/* Define this (as well as DROPBEAR_CLI_PASSWORD_AUTH) to allow the use of + * a helper program for the ssh client. The helper program should be + * specified in the SSH_ASKPASS environment variable, and dbclient + * should be run with DISPLAY set and no tty. The program should + * return the password on standard output */ +#define DROPBEAR_CLI_ASKPASS_HELPER 0 + +/* Save a network roundtrip by sendng a real auth request immediately after + * sending a query for the available methods. It is at the expense of < 100 + * bytes of extra network traffic. This is not yet enabled by default since it + * could cause problems with non-compliant servers */ +#define DROPBEAR_CLI_IMMEDIATE_AUTH 0 + +/* Source for randomness. This must be able to provide hundreds of bytes per SSH + * connection without blocking. In addition /dev/random is used for seeding + * rsa/dss key generation */ +#define DROPBEAR_URANDOM_DEV "/dev/urandom" + +/* Set this to use PRNGD or EGD instead of /dev/urandom or /dev/random */ +/*#define DROPBEAR_PRNGD_SOCKET "/var/run/dropbear-rng"*/ + + +/* Specify the number of clients we will allow to be connected but + * not yet authenticated. After this limit, connections are rejected */ +/* The first setting is per-IP, to avoid denial of service */ +#define MAX_UNAUTH_PER_IP 5 + +/* And then a global limit to avoid chewing memory if connections + * come from many IPs */ +#define MAX_UNAUTH_CLIENTS 30 + +/* Maximum number of failed authentication tries (server option) */ +#define MAX_AUTH_TRIES 10 + +/* The default file to store the daemon's process ID, for shutdown + scripts etc. This can be overridden with the -P flag */ +#define DROPBEAR_PIDFILE "/var/run/dropbear.pid" + +/* The command to invoke for xauth when using X11 forwarding. + * "-q" for quiet */ +#define XAUTH_COMMAND "/usr/bin/xauth -q" + +/* if you want to enable running an sftp server (such as the one included with + * OpenSSH), set the path below. If the path isn't defined, sftp will not + * be enabled */ +#define SFTPSERVER_PATH "/usr/libexec/sftp-server" + +/* This is used by the scp binary when used as a client binary. If you're + * not using the Dropbear client, you'll need to change it */ +#define DROPBEAR_PATH_SSH_PROGRAM "/usr/bin/dbclient" + +/* Whether to log commands executed by a client. This only logs the + * (single) command sent to the server, not what a user did in a + * shell/sftp session etc. */ +#define LOG_COMMANDS 0 + +/* Window size limits. These tend to be a trade-off between memory + usage and network performance: */ +/* Size of the network receive window. This amount of memory is allocated + as a per-channel receive buffer. Increasing this value can make a + significant difference to network performance. 24kB was empirically + chosen for a 100mbit ethernet network. The value can be altered at + runtime with the -W argument. */ +#define DEFAULT_RECV_WINDOW 24576 +/* Maximum size of a received SSH data packet - this _MUST_ be >= 32768 + in order to interoperate with other implementations */ +#define RECV_MAX_PAYLOAD_LEN 32768 +/* Maximum size of a transmitted data packet - this can be any value, + though increasing it may not make a significant difference. */ +#define TRANS_MAX_PAYLOAD_LEN 16384 + +/* Ensure that data is transmitted every KEEPALIVE seconds. This can +be overridden at runtime with -K. 0 disables keepalives */ +#define DEFAULT_KEEPALIVE 0 + +/* If this many KEEPALIVES are sent with no packets received from the +other side, exit. Not run-time configurable - if you have a need +for runtime configuration please mail the Dropbear list */ +#define DEFAULT_KEEPALIVE_LIMIT 3 + +/* Ensure that data is received within IDLE_TIMEOUT seconds. This can +be overridden at runtime with -I. 0 disables idle timeouts */ +#define DEFAULT_IDLE_TIMEOUT 0 + +/* The default path. This will often get replaced by the shell */ +#define DEFAULT_PATH "/usr/bin:/bin" + +#endif /* DROPBEAR_DEFAULT_OPTIONS_H_ */
--- a/dropbear.8 Thu May 18 23:38:30 2017 +0800 +++ b/dropbear.8 Thu May 18 23:45:10 2017 +0800 @@ -91,6 +91,10 @@ .B \-I \fIidle_timeout Disconnect the session if no traffic is transmitted or received for \fIidle_timeout\fR seconds. .TP +.B \-c \fIforced_command +Disregard the command provided by the user and always run \fIforced_command\fR. This also +overrides any authorized_keys command= option. +.TP .B \-V Print the version @@ -129,6 +133,7 @@ .TP .B command=\fR"\fIforced_command\fR" Disregard the command provided by the user and always run \fIforced_command\fR. +The -c command line option overrides this. The authorized_keys file and its containing ~/.ssh directory must only be writable by the user, otherwise Dropbear will not allow a login using public
--- a/dropbearconvert.c Thu May 18 23:38:30 2017 +0800 +++ b/dropbearconvert.c Thu May 18 23:45:10 2017 +0800 @@ -53,8 +53,8 @@ progname); } -#if defined(DBMULTI_dropbearconvert) || !defined(DROPBEAR_MULTI) -#if defined(DBMULTI_dropbearconvert) && defined(DROPBEAR_MULTI) +#if defined(DBMULTI_dropbearconvert) || !DROPBEAR_MULTI +#if defined(DBMULTI_dropbearconvert) && DROPBEAR_MULTI int dropbearconvert_main(int argc, char ** argv) { #else int main(int argc, char ** argv) { @@ -67,7 +67,7 @@ crypto_init(); seedrandom(); -#ifdef DEBUG_TRACE +#if DEBUG_TRACE /* It's hard for it to get in the way _too_ much */ debug_trace = 1; #endif
--- a/dropbearkey.c Thu May 18 23:38:30 2017 +0800 +++ b/dropbearkey.c Thu May 18 23:45:10 2017 +0800 @@ -67,36 +67,36 @@ fprintf(stderr, "Usage: %s -t <type> -f <filename> [-s bits]\n" "-t type Type of key to generate. One of:\n" -#ifdef DROPBEAR_RSA +#if DROPBEAR_RSA " rsa\n" #endif -#ifdef DROPBEAR_DSS +#if DROPBEAR_DSS " dss\n" #endif -#ifdef DROPBEAR_ECDSA +#if DROPBEAR_ECDSA " ecdsa\n" #endif "-f filename Use filename for the secret key.\n" " ~/.ssh/id_dropbear is recommended for client keys.\n" "-s bits Key size in bits, should be a multiple of 8 (optional)\n" -#ifdef DROPBEAR_DSS +#if DROPBEAR_DSS " DSS has a fixed size of 1024 bits\n" #endif -#ifdef DROPBEAR_ECDSA +#if DROPBEAR_ECDSA " ECDSA has sizes " -#ifdef DROPBEAR_ECC_256 +#if DROPBEAR_ECC_256 "256 " #endif -#ifdef DROPBEAR_ECC_384 +#if DROPBEAR_ECC_384 "384 " #endif -#ifdef DROPBEAR_ECC_521 +#if DROPBEAR_ECC_521 "521 " #endif "\n" #endif "-y Just print the publickey and fingerprint for the\n private key in <filename>.\n" -#ifdef DEBUG_TRACE +#if DEBUG_TRACE "-v verbose\n" #endif ,progname); @@ -106,7 +106,7 @@ static void check_signkey_bits(enum signkey_type type, int bits) { switch (type) { -#ifdef DROPBEAR_RSA +#if DROPBEAR_RSA case DROPBEAR_SIGNKEY_RSA: if (bits < 512 || bits > 4096 || (bits % 8 != 0)) { dropbear_exit("Bits must satisfy 512 <= bits <= 4096, and be a" @@ -126,8 +126,8 @@ } } -#if defined(DBMULTI_dropbearkey) || !defined(DROPBEAR_MULTI) -#if defined(DBMULTI_dropbearkey) && defined(DROPBEAR_MULTI) +#if defined(DBMULTI_dropbearkey) || !DROPBEAR_MULTI +#if defined(DBMULTI_dropbearkey) && DROPBEAR_MULTI int dropbearkey_main(int argc, char ** argv) { #else int main(int argc, char ** argv) { @@ -174,7 +174,7 @@ printhelp(argv[0]); exit(EXIT_SUCCESS); break; -#ifdef DEBUG_TRACE +#if DEBUG_TRACE case 'v': debug_trace = 1; break; @@ -206,19 +206,19 @@ exit(EXIT_FAILURE); } -#ifdef DROPBEAR_RSA +#if DROPBEAR_RSA if (strcmp(typetext, "rsa") == 0) { keytype = DROPBEAR_SIGNKEY_RSA; } #endif -#ifdef DROPBEAR_DSS +#if DROPBEAR_DSS if (strcmp(typetext, "dss") == 0) { keytype = DROPBEAR_SIGNKEY_DSS; } #endif -#ifdef DROPBEAR_ECDSA +#if DROPBEAR_ECDSA if (strcmp(typetext, "ecdsa") == 0) { keytype = DROPBEAR_SIGNKEY_ECDSA_KEYGEN; @@ -241,7 +241,7 @@ } fprintf(stderr, "Generating key, this may take a while...\n"); - if (signkey_generate(keytype, bits, filename) == DROPBEAR_FAILURE) + if (signkey_generate(keytype, bits, filename, 0) == DROPBEAR_FAILURE) { dropbear_exit("Failed to generate key.\n"); }
--- a/dss.c Thu May 18 23:38:30 2017 +0800 +++ b/dss.c Thu May 18 23:45:10 2017 +0800 @@ -37,7 +37,7 @@ * See FIPS186 or the Handbook of Applied Cryptography for details of the * algorithm */ -#ifdef DROPBEAR_DSS +#if DROPBEAR_DSS /* Load a dss key from a buffer, initialising the values. * The key will have the same format as buf_put_dss_key. @@ -153,7 +153,7 @@ } -#ifdef DROPBEAR_SIGNKEY_VERIFY +#if DROPBEAR_SIGNKEY_VERIFY /* Verify a DSS signature (in buf) made on data by the key given. * returns DROPBEAR_SUCCESS or DROPBEAR_FAILURE */ int buf_dss_verify(buffer* buf, dropbear_dss_key *key, buffer *data_buf) {
--- a/dss.h Thu May 18 23:38:30 2017 +0800 +++ b/dss.h Thu May 18 23:45:10 2017 +0800 @@ -28,7 +28,7 @@ #include "includes.h" #include "buffer.h" -#ifdef DROPBEAR_DSS +#if DROPBEAR_DSS typedef struct { @@ -42,7 +42,7 @@ } dropbear_dss_key; void buf_put_dss_sign(buffer* buf, dropbear_dss_key *key, buffer *data_buf); -#ifdef DROPBEAR_SIGNKEY_VERIFY +#if DROPBEAR_SIGNKEY_VERIFY int buf_dss_verify(buffer* buf, dropbear_dss_key *key, buffer *data_buf); #endif int buf_get_dss_pub_key(buffer* buf, dropbear_dss_key *key);
--- a/ecc.c Thu May 18 23:38:30 2017 +0800 +++ b/ecc.c Thu May 18 23:45:10 2017 +0800 @@ -4,10 +4,10 @@ #include "dbutil.h" #include "bignum.h" -#ifdef DROPBEAR_ECC +#if DROPBEAR_ECC /* .dp members are filled out by dropbear_ecc_fill_dp() at startup */ -#ifdef DROPBEAR_ECC_256 +#if DROPBEAR_ECC_256 struct dropbear_ecc_curve ecc_curve_nistp256 = { 32, /* .ltc_size */ NULL, /* .dp */ @@ -15,7 +15,7 @@ "nistp256" /* .name */ }; #endif -#ifdef DROPBEAR_ECC_384 +#if DROPBEAR_ECC_384 struct dropbear_ecc_curve ecc_curve_nistp384 = { 48, /* .ltc_size */ NULL, /* .dp */ @@ -23,7 +23,7 @@ "nistp384" /* .name */ }; #endif -#ifdef DROPBEAR_ECC_521 +#if DROPBEAR_ECC_521 struct dropbear_ecc_curve ecc_curve_nistp521 = { 66, /* .ltc_size */ NULL, /* .dp */ @@ -33,13 +33,13 @@ #endif struct dropbear_ecc_curve *dropbear_ecc_curves[] = { -#ifdef DROPBEAR_ECC_256 +#if DROPBEAR_ECC_256 &ecc_curve_nistp256, #endif -#ifdef DROPBEAR_ECC_384 +#if DROPBEAR_ECC_384 &ecc_curve_nistp384, #endif -#ifdef DROPBEAR_ECC_521 +#if DROPBEAR_ECC_521 &ecc_curve_nistp521, #endif NULL
--- a/ecc.h Thu May 18 23:38:30 2017 +0800 +++ b/ecc.h Thu May 18 23:45:10 2017 +0800 @@ -6,7 +6,7 @@ #include "buffer.h" -#ifdef DROPBEAR_ECC +#if DROPBEAR_ECC struct dropbear_ecc_curve { int ltc_size; /* to match the byte sizes in ltc_ecc_sets[] */
--- a/ecdsa.c Thu May 18 23:38:30 2017 +0800 +++ b/ecdsa.c Thu May 18 23:45:10 2017 +0800 @@ -6,7 +6,7 @@ #include "ecdsa.h" #include "signkey.h" -#ifdef DROPBEAR_ECDSA +#if DROPBEAR_ECDSA int signkey_is_ecdsa(enum signkey_type type) { @@ -16,17 +16,17 @@ } enum signkey_type ecdsa_signkey_type(ecc_key * key) { -#ifdef DROPBEAR_ECC_256 +#if DROPBEAR_ECC_256 if (key->dp == ecc_curve_nistp256.dp) { return DROPBEAR_SIGNKEY_ECDSA_NISTP256; } #endif -#ifdef DROPBEAR_ECC_384 +#if DROPBEAR_ECC_384 if (key->dp == ecc_curve_nistp384.dp) { return DROPBEAR_SIGNKEY_ECDSA_NISTP384; } #endif -#ifdef DROPBEAR_ECC_521 +#if DROPBEAR_ECC_521 if (key->dp == ecc_curve_nistp521.dp) { return DROPBEAR_SIGNKEY_ECDSA_NISTP521; } @@ -38,17 +38,17 @@ const ltc_ecc_set_type *dp = NULL; /* curve domain parameters */ ecc_key *new_key = NULL; switch (bit_size) { -#ifdef DROPBEAR_ECC_256 +#if DROPBEAR_ECC_256 case 256: dp = ecc_curve_nistp256.dp; break; #endif -#ifdef DROPBEAR_ECC_384 +#if DROPBEAR_ECC_384 case 384: dp = ecc_curve_nistp384.dp; break; #endif -#ifdef DROPBEAR_ECC_521 +#if DROPBEAR_ECC_521 case 521: dp = ecc_curve_nistp521.dp; break; @@ -56,13 +56,13 @@ } if (!dp) { dropbear_exit("Key size %d isn't valid. Try " -#ifdef DROPBEAR_ECC_256 +#if DROPBEAR_ECC_256 "256 " #endif -#ifdef DROPBEAR_ECC_384 +#if DROPBEAR_ECC_384 "384 " #endif -#ifdef DROPBEAR_ECC_521 +#if DROPBEAR_ECC_521 "521 " #endif , bit_size);
--- a/ecdsa.h Thu May 18 23:38:30 2017 +0800 +++ b/ecdsa.h Thu May 18 23:45:10 2017 +0800 @@ -5,14 +5,14 @@ #include "buffer.h" #include "signkey.h" -#ifdef DROPBEAR_ECDSA +#if DROPBEAR_ECDSA /* Prefer the larger size - it's fast anyway */ -#if defined(DROPBEAR_ECC_521) +#if DROPBEAR_ECC_521 #define ECDSA_DEFAULT_SIZE 521 -#elif defined(DROPBEAR_ECC_384) +#elif DROPBEAR_ECC_384 #define ECDSA_DEFAULT_SIZE 384 -#elif defined(DROPBEAR_ECC_256) +#elif DROPBEAR_ECC_256 #define ECDSA_DEFAULT_SIZE 256 #else #define ECDSA_DEFAULT_SIZE 0
--- a/gendss.c Thu May 18 23:38:30 2017 +0800 +++ b/gendss.c Thu May 18 23:45:10 2017 +0800 @@ -35,7 +35,7 @@ /* This is just a test */ -#ifdef DROPBEAR_DSS +#if DROPBEAR_DSS static void getq(dropbear_dss_key *key); static void getp(dropbear_dss_key *key, unsigned int size);
--- a/gendss.h Thu May 18 23:38:30 2017 +0800 +++ b/gendss.h Thu May 18 23:45:10 2017 +0800 @@ -27,7 +27,7 @@ #include "dss.h" -#ifdef DROPBEAR_DSS +#if DROPBEAR_DSS dropbear_dss_key * gen_dss_priv_key(unsigned int size);
--- a/genrsa.c Thu May 18 23:38:30 2017 +0800 +++ b/genrsa.c Thu May 18 23:45:10 2017 +0800 @@ -31,7 +31,7 @@ #define RSA_E 65537 -#ifdef DROPBEAR_RSA +#if DROPBEAR_RSA static void getrsaprime(mp_int* prime, mp_int *primeminus, mp_int* rsa_e, unsigned int size_bytes);
--- a/genrsa.h Thu May 18 23:38:30 2017 +0800 +++ b/genrsa.h Thu May 18 23:45:10 2017 +0800 @@ -27,7 +27,7 @@ #include "rsa.h" -#ifdef DROPBEAR_RSA +#if DROPBEAR_RSA dropbear_rsa_key * gen_rsa_priv_key(unsigned int size);
--- a/gensignkey.c Thu May 18 23:38:30 2017 +0800 +++ b/gensignkey.c Thu May 18 23:45:10 2017 +0800 @@ -53,15 +53,15 @@ static int get_default_bits(enum signkey_type keytype) { switch (keytype) { -#ifdef DROPBEAR_RSA +#if DROPBEAR_RSA case DROPBEAR_SIGNKEY_RSA: return RSA_DEFAULT_SIZE; #endif -#ifdef DROPBEAR_DSS +#if DROPBEAR_DSS case DROPBEAR_SIGNKEY_DSS: return DSS_DEFAULT_SIZE; #endif -#ifdef DROPBEAR_ECDSA +#if DROPBEAR_ECDSA case DROPBEAR_SIGNKEY_ECDSA_KEYGEN: return ECDSA_DEFAULT_SIZE; case DROPBEAR_SIGNKEY_ECDSA_NISTP521: @@ -76,10 +76,12 @@ } } -int signkey_generate(enum signkey_type keytype, int bits, const char* filename) +/* if skip_exist is set it will silently return if the key file exists */ +int signkey_generate(enum signkey_type keytype, int bits, const char* filename, int skip_exist) { sign_key * key = NULL; buffer *buf = NULL; + char *fn_temp = NULL; int ret = DROPBEAR_FAILURE; if (bits == 0) { @@ -92,17 +94,17 @@ seedrandom(); switch(keytype) { -#ifdef DROPBEAR_RSA +#if DROPBEAR_RSA case DROPBEAR_SIGNKEY_RSA: key->rsakey = gen_rsa_priv_key(bits); break; #endif -#ifdef DROPBEAR_DSS +#if DROPBEAR_DSS case DROPBEAR_SIGNKEY_DSS: key->dsskey = gen_dss_priv_key(bits); break; #endif -#ifdef DROPBEAR_ECDSA +#if DROPBEAR_ECDSA case DROPBEAR_SIGNKEY_ECDSA_KEYGEN: case DROPBEAR_SIGNKEY_ECDSA_NISTP521: case DROPBEAR_SIGNKEY_ECDSA_NISTP384: @@ -126,10 +128,37 @@ sign_key_free(key); key = NULL; buf_setpos(buf, 0); - ret = buf_writefile(buf, filename); + + fn_temp = m_malloc(strlen(filename) + 30); + snprintf(fn_temp, strlen(filename)+30, "%s.tmp%d", filename, getpid()); + ret = buf_writefile(buf, fn_temp); + + if (ret == DROPBEAR_FAILURE) { + goto out; + } - buf_burn(buf); - buf_free(buf); - buf = NULL; + if (link(fn_temp, filename) < 0) { + /* If generating keys on connection (skipexist) it's OK to get EEXIST + - we probably just lost a race with another connection to generate the key */ + if (!(skip_exist && errno == EEXIST)) { + dropbear_log(LOG_ERR, "Failed moving key file to %s: %s", filename, + strerror(errno)); + /* XXX fallback to non-atomic copy for some filesystems? */ + ret = DROPBEAR_FAILURE; + goto out; + } + } + +out: + if (buf) { + buf_burn(buf); + buf_free(buf); + } + + if (fn_temp) { + unlink(fn_temp); + m_free(fn_temp); + } + return ret; }
--- a/gensignkey.h Thu May 18 23:38:30 2017 +0800 +++ b/gensignkey.h Thu May 18 23:45:10 2017 +0800 @@ -3,6 +3,6 @@ #include "signkey.h" -int signkey_generate(enum signkey_type type, int bits, const char* filename); +int signkey_generate(enum signkey_type type, int bits, const char* filename, int skip_exist); #endif
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/ifndef_wrapper.sh Thu May 18 23:45:10 2017 +0800 @@ -0,0 +1,7 @@ +#!/bin/sh + +# Wrap all "#define X Y" with a #ifndef X...#endif" + +sed -E 's/^(#define ([^ ]+) .*)/#ifndef \2\ +\1\ +#endif/'
--- a/kex.h Thu May 18 23:38:30 2017 +0800 +++ b/kex.h Thu May 18 23:45:10 2017 +0800 @@ -40,14 +40,14 @@ void kexdh_comb_key(struct kex_dh_param *param, mp_int *dh_pub_them, sign_key *hostkey); -#ifdef DROPBEAR_ECDH +#if DROPBEAR_ECDH struct kex_ecdh_param *gen_kexecdh_param(void); void free_kexecdh_param(struct kex_ecdh_param *param); void kexecdh_comb_key(struct kex_ecdh_param *param, buffer *pub_them, sign_key *hostkey); #endif -#ifdef DROPBEAR_CURVE25519 +#if DROPBEAR_CURVE25519 struct kex_curve25519_param *gen_kexcurve25519_param(void); void free_kexcurve25519_param(struct kex_curve25519_param *param); void kexcurve25519_comb_key(struct kex_curve25519_param *param, buffer *pub_them, @@ -88,13 +88,13 @@ mp_int priv; /* x */ }; -#ifdef DROPBEAR_ECDH +#if DROPBEAR_ECDH struct kex_ecdh_param { ecc_key key; }; #endif -#ifdef DROPBEAR_CURVE25519 +#if DROPBEAR_CURVE25519 #define CURVE25519_LEN 32 struct kex_curve25519_param { unsigned char priv[CURVE25519_LEN];
--- a/keyimport.c Thu May 18 23:38:30 2017 +0800 +++ b/keyimport.c Thu May 18 23:45:10 2017 +0800 @@ -36,9 +36,11 @@ #include "dbutil.h" #include "ecc.h" +#if DROPBEAR_ECDSA static const unsigned char OID_SEC256R1_BLOB[] = {0x2a, 0x86, 0x48, 0xce, 0x3d, 0x03, 0x01, 0x07}; static const unsigned char OID_SEC384R1_BLOB[] = {0x2b, 0x81, 0x04, 0x00, 0x22}; static const unsigned char OID_SEC521R1_BLOB[] = {0x2b, 0x81, 0x04, 0x00, 0x23}; +#endif #define PUT_32BIT(cp, value) do { \ (cp)[3] = (unsigned char)(value); \ @@ -71,11 +73,11 @@ int import_encrypted(const char* filename, int filetype) { - if (filetype == KEYFILE_OPENSSH) { - return openssh_encrypted(filename); + if (filetype == KEYFILE_OPENSSH) { + return openssh_encrypted(filename); #if 0 - } else if (filetype == KEYFILE_SSHCOM) { - return sshcom_encrypted(filename, NULL); + } else if (filetype == KEYFILE_SSHCOM) { + return sshcom_encrypted(filename, NULL); #endif } return 0; @@ -83,101 +85,101 @@ sign_key *import_read(const char *filename, char *passphrase, int filetype) { - if (filetype == KEYFILE_OPENSSH) { - return openssh_read(filename, passphrase); - } else if (filetype == KEYFILE_DROPBEAR) { - return dropbear_read(filename); + if (filetype == KEYFILE_OPENSSH) { + return openssh_read(filename, passphrase); + } else if (filetype == KEYFILE_DROPBEAR) { + return dropbear_read(filename); #if 0 - } else if (filetype == KEYFILE_SSHCOM) { - return sshcom_read(filename, passphrase); + } else if (filetype == KEYFILE_SSHCOM) { + return sshcom_read(filename, passphrase); #endif - } + } return NULL; } int import_write(const char *filename, sign_key *key, char *passphrase, - int filetype) { + int filetype) { - if (filetype == KEYFILE_OPENSSH) { - return openssh_write(filename, key, passphrase); - } else if (filetype == KEYFILE_DROPBEAR) { - return dropbear_write(filename, key); + if (filetype == KEYFILE_OPENSSH) { + return openssh_write(filename, key, passphrase); + } else if (filetype == KEYFILE_DROPBEAR) { + return dropbear_write(filename, key); #if 0 - } else if (filetype == KEYFILE_SSHCOM) { - return sshcom_write(filename, key, passphrase); + } else if (filetype == KEYFILE_SSHCOM) { + return sshcom_write(filename, key, passphrase); #endif - } + } return 0; } static sign_key *dropbear_read(const char* filename) { - buffer * buf = NULL; - sign_key *ret = NULL; - enum signkey_type type; + buffer * buf = NULL; + sign_key *ret = NULL; + enum signkey_type type; - buf = buf_new(MAX_PRIVKEY_SIZE); - if (buf_readfile(buf, filename) == DROPBEAR_FAILURE) { - goto error; - } + buf = buf_new(MAX_PRIVKEY_SIZE); + if (buf_readfile(buf, filename) == DROPBEAR_FAILURE) { + goto error; + } - buf_setpos(buf, 0); - ret = new_sign_key(); + buf_setpos(buf, 0); + ret = new_sign_key(); - type = DROPBEAR_SIGNKEY_ANY; - if (buf_get_priv_key(buf, ret, &type) == DROPBEAR_FAILURE){ - goto error; - } - buf_free(buf); + type = DROPBEAR_SIGNKEY_ANY; + if (buf_get_priv_key(buf, ret, &type) == DROPBEAR_FAILURE){ + goto error; + } + buf_free(buf); - ret->type = type; + ret->type = type; - return ret; + return ret; error: - if (buf) { - buf_free(buf); - } - if (ret) { - sign_key_free(ret); - } - return NULL; + if (buf) { + buf_free(buf); + } + if (ret) { + sign_key_free(ret); + } + return NULL; } /* returns 0 on fail, 1 on success */ static int dropbear_write(const char*filename, sign_key * key) { - buffer * buf; - FILE*fp; - int len; - int ret; + buffer * buf; + FILE*fp; + int len; + int ret; - buf = buf_new(MAX_PRIVKEY_SIZE); - buf_put_priv_key(buf, key, key->type); + buf = buf_new(MAX_PRIVKEY_SIZE); + buf_put_priv_key(buf, key, key->type); - fp = fopen(filename, "w"); - if (!fp) { - ret = 0; - goto out; - } + fp = fopen(filename, "w"); + if (!fp) { + ret = 0; + goto out; + } - buf_setpos(buf, 0); - do { - len = fwrite(buf_getptr(buf, buf->len - buf->pos), - 1, buf->len - buf->pos, fp); - buf_incrpos(buf, len); - } while (len > 0 && buf->len != buf->pos); + buf_setpos(buf, 0); + do { + len = fwrite(buf_getptr(buf, buf->len - buf->pos), + 1, buf->len - buf->pos, fp); + buf_incrpos(buf, len); + } while (len > 0 && buf->len != buf->pos); - fclose(fp); + fclose(fp); - if (buf->pos != buf->len) { - ret = 0; - } else { - ret = 1; - } + if (buf->pos != buf->len) { + ret = 0; + } else { + ret = 1; + } out: - buf_free(buf); - return ret; + buf_free(buf); + return ret; } @@ -185,7 +187,7 @@ * Helper routines. (The base64 ones are defined in sshpubk.c.) */ -#define isbase64(c) ( ((c) >= 'A' && (c) <= 'Z') || \ +#define isbase64(c) ( ((c) >= 'A' && (c) <= 'Z') || \ ((c) >= 'a' && (c) <= 'z') || \ ((c) >= '0' && (c) <= '9') || \ (c) == '+' || (c) == '/' || (c) == '=' \ @@ -193,24 +195,24 @@ /* cpl has to be less than 100 */ static void base64_encode_fp(FILE * fp, unsigned char *data, - int datalen, int cpl) + int datalen, int cpl) { - unsigned char out[100]; - int n; - unsigned long outlen; - int rawcpl; - rawcpl = cpl * 3 / 4; - dropbear_assert((unsigned int)cpl < sizeof(out)); + unsigned char out[100]; + int n; + unsigned long outlen; + int rawcpl; + rawcpl = cpl * 3 / 4; + dropbear_assert((unsigned int)cpl < sizeof(out)); - while (datalen > 0) { - n = (datalen < rawcpl ? datalen : rawcpl); - outlen = sizeof(out); - base64_encode(data, n, out, &outlen); - data += n; - datalen -= n; - fwrite(out, 1, outlen, fp); - fputc('\n', fp); - } + while (datalen > 0) { + n = (datalen < rawcpl ? datalen : rawcpl); + outlen = sizeof(out); + base64_encode(data, n, out, &outlen); + data += n; + datalen -= n; + fwrite(out, 1, outlen, fp); + fputc('\n', fp); + } } /* * Read an ASN.1/BER identifier and length pair. @@ -222,14 +224,14 @@ */ /* ASN.1 tag classes. */ -#define ASN1_CLASS_UNIVERSAL (0 << 6) -#define ASN1_CLASS_APPLICATION (1 << 6) +#define ASN1_CLASS_UNIVERSAL (0 << 6) +#define ASN1_CLASS_APPLICATION (1 << 6) #define ASN1_CLASS_CONTEXT_SPECIFIC (2 << 6) -#define ASN1_CLASS_PRIVATE (3 << 6) -#define ASN1_CLASS_MASK (3 << 6) +#define ASN1_CLASS_PRIVATE (3 << 6) +#define ASN1_CLASS_MASK (3 << 6) /* Primitive versus constructed bit. */ -#define ASN1_CONSTRUCTED (1 << 5) +#define ASN1_CONSTRUCTED (1 << 5) static int ber_read_id_len(void *source, int sourcelen, int *id, int *length, int *flags) @@ -309,7 +311,7 @@ len++; if (d) *d++ = 0x1F | flags; for (n = 1; (id >> (7*n)) > 0; n++) - continue; /* count the bytes */ + continue; /* count the bytes */ while (n--) { len++; if (d) *d++ = (n ? 0x80 : 0) | ((id >> (7*n)) & 0x7F); @@ -330,7 +332,7 @@ * encode the actual length. */ for (n = 1; (length >> (8*n)) > 0; n++) - continue; /* count the bytes */ + continue; /* count the bytes */ len++; if (d) *d++ = 0x80 | n; while (n--) { @@ -356,29 +358,29 @@ int encrypted; char iv[32]; unsigned char *keyblob; - unsigned int keyblob_len, keyblob_size; + unsigned int keyblob_len, keyblob_size; }; static struct openssh_key *load_openssh_key(const char *filename) { struct openssh_key *ret; - FILE *fp = NULL; + FILE *fp = NULL; char buffer[256]; - char *errmsg = NULL, *p = NULL; + char *errmsg = NULL, *p = NULL; int headers_done; - unsigned long len, outlen; + unsigned long len, outlen; - ret = (struct openssh_key*)m_malloc(sizeof(struct openssh_key)); + ret = (struct openssh_key*)m_malloc(sizeof(struct openssh_key)); ret->keyblob = NULL; ret->keyblob_len = ret->keyblob_size = 0; ret->encrypted = 0; memset(ret->iv, 0, sizeof(ret->iv)); - if (strlen(filename) == 1 && filename[0] == '-') { - fp = stdin; - } else { - fp = fopen(filename, "r"); - } + if (strlen(filename) == 1 && filename[0] == '-') { + fp = stdin; + } else { + fp = fopen(filename, "r"); + } if (!fp) { errmsg = "Unable to open key file"; goto error; @@ -393,8 +395,8 @@ ret->type = OSSH_RSA; else if (!strcmp(buffer, "-----BEGIN DSA PRIVATE KEY-----\n")) ret->type = OSSH_DSA; - else if (!strcmp(buffer, "-----BEGIN EC PRIVATE KEY-----\n")) - ret->type = OSSH_EC; + else if (!strcmp(buffer, "-----BEGIN EC PRIVATE KEY-----\n")) + ret->type = OSSH_EC; else { errmsg = "Unrecognised key type"; goto error; @@ -408,7 +410,7 @@ } if (0 == strncmp(buffer, "-----END ", 9) && 0 == strcmp(buffer+strlen(buffer)-17, "PRIVATE KEY-----\n")) - break; /* done */ + break; /* done */ if ((p = strchr(buffer, ':')) != NULL) { if (headers_done) { errmsg = "Header found in body of key data"; @@ -445,22 +447,22 @@ } } else { headers_done = 1; - len = strlen(buffer); - outlen = len*4/3; - if (ret->keyblob_len + outlen > ret->keyblob_size) { - ret->keyblob_size = ret->keyblob_len + outlen + 256; - ret->keyblob = (unsigned char*)m_realloc(ret->keyblob, - ret->keyblob_size); - } - outlen = ret->keyblob_size - ret->keyblob_len; - if (base64_decode((const unsigned char *)buffer, len, - ret->keyblob + ret->keyblob_len, &outlen) != CRYPT_OK){ - errmsg = "Error decoding base64"; - goto error; - } - ret->keyblob_len += outlen; - } + len = strlen(buffer); + outlen = len*4/3; + if (ret->keyblob_len + outlen > ret->keyblob_size) { + ret->keyblob_size = ret->keyblob_len + outlen + 256; + ret->keyblob = (unsigned char*)m_realloc(ret->keyblob, + ret->keyblob_size); + } + outlen = ret->keyblob_size - ret->keyblob_len; + if (base64_decode((const unsigned char *)buffer, len, + ret->keyblob + ret->keyblob_len, &outlen) != CRYPT_OK){ + errmsg = "Error decoding base64"; + goto error; + } + ret->keyblob_len += outlen; } + } if (ret->keyblob_len == 0 || !ret->keyblob) { errmsg = "Key body not present"; @@ -509,31 +511,31 @@ static sign_key *openssh_read(const char *filename, char * UNUSED(passphrase)) { - struct openssh_key *key; + struct openssh_key *key; unsigned char *p; int ret, id, len, flags; - int i, num_integers = 0; - sign_key *retval = NULL; + int i, num_integers = 0; + sign_key *retval = NULL; char *errmsg; - unsigned char *modptr = NULL; - int modlen = -9999; - enum signkey_type type; + unsigned char *modptr = NULL; + int modlen = -9999; + enum signkey_type type; - sign_key *retkey; - buffer * blobbuf = NULL; + sign_key *retkey; + buffer * blobbuf = NULL; - retkey = new_sign_key(); + retkey = new_sign_key(); - key = load_openssh_key(filename); + key = load_openssh_key(filename); if (!key) return NULL; if (key->encrypted) { - errmsg = "encrypted keys not supported currently"; - goto error; + errmsg = "encrypted keys not supported currently"; + goto error; #if 0 - /* matt TODO */ + /* matt TODO */ /* * Derive encryption key from passphrase and iv/salt: * @@ -578,11 +580,11 @@ * depends on the key type: * * - For RSA, we expect the integers to be 0, n, e, d, p, q, - * dmp1, dmq1, iqmp in that order. (The last three are d mod - * (p-1), d mod (q-1), inverse of q mod p respectively.) + * dmp1, dmq1, iqmp in that order. (The last three are d mod + * (p-1), d mod (q-1), inverse of q mod p respectively.) * * - For DSA, we expect them to be 0, p, q, g, y, x in that - * order. + * order. */ p = key->keyblob; @@ -601,25 +603,25 @@ num_integers = 9; else if (key->type == OSSH_DSA) num_integers = 6; - else if (key->type == OSSH_EC) - num_integers = 1; + else if (key->type == OSSH_EC) + num_integers = 1; /* * Space to create key blob in. */ - blobbuf = buf_new(3000); + blobbuf = buf_new(3000); -#ifdef DROPBEAR_DSS - if (key->type == OSSH_DSA) { - buf_putstring(blobbuf, "ssh-dss", 7); - retkey->type = DROPBEAR_SIGNKEY_DSS; - } +#if DROPBEAR_DSS + if (key->type == OSSH_DSA) { + buf_putstring(blobbuf, "ssh-dss", 7); + retkey->type = DROPBEAR_SIGNKEY_DSS; + } #endif -#ifdef DROPBEAR_RSA - if (key->type == OSSH_RSA) { - buf_putstring(blobbuf, "ssh-rsa", 7); - retkey->type = DROPBEAR_SIGNKEY_RSA; - } +#if DROPBEAR_RSA + if (key->type == OSSH_RSA) { + buf_putstring(blobbuf, "ssh-rsa", 7); + retkey->type = DROPBEAR_SIGNKEY_RSA; + } #endif for (i = 0; i < num_integers; i++) { @@ -633,160 +635,160 @@ } if (i == 0) { - /* First integer is a version indicator */ - int expected = -1; - switch (key->type) { - case OSSH_RSA: - case OSSH_DSA: - expected = 0; - break; - case OSSH_EC: - expected = 1; - break; - } - if (len != 1 || p[0] != expected) { + /* First integer is a version indicator */ + int expected = -1; + switch (key->type) { + case OSSH_RSA: + case OSSH_DSA: + expected = 0; + break; + case OSSH_EC: + expected = 1; + break; + } + if (len != 1 || p[0] != expected) { errmsg = "Version number mismatch"; goto error; } } else if (key->type == OSSH_RSA) { /* - * OpenSSH key order is n, e, d, p, q, dmp1, dmq1, iqmp - * but we want e, n, d, p, q + * OpenSSH key order is n, e, d, p, q, dmp1, dmq1, iqmp + * but we want e, n, d, p, q */ if (i == 1) { /* Save the details for after we deal with number 2. */ - modptr = p; + modptr = p; modlen = len; - } else if (i >= 2 && i <= 5) { - buf_putstring(blobbuf, (const char*)p, len); + } else if (i >= 2 && i <= 5) { + buf_putstring(blobbuf, (const char*)p, len); if (i == 2) { - buf_putstring(blobbuf, (const char*)modptr, modlen); + buf_putstring(blobbuf, (const char*)modptr, modlen); } } } else if (key->type == OSSH_DSA) { /* - * OpenSSH key order is p, q, g, y, x, - * we want the same. + * OpenSSH key order is p, q, g, y, x, + * we want the same. */ - buf_putstring(blobbuf, (const char*)p, len); + buf_putstring(blobbuf, (const char*)p, len); } /* Skip past the number. */ p += len; } -#ifdef DROPBEAR_ECDSA - if (key->type == OSSH_EC) { - unsigned char* private_key_bytes = NULL; - int private_key_len = 0; - unsigned char* public_key_bytes = NULL; - int public_key_len = 0; - ecc_key *ecc = NULL; - const struct dropbear_ecc_curve *curve = NULL; +#if DROPBEAR_ECDSA + if (key->type == OSSH_EC) { + unsigned char* private_key_bytes = NULL; + int private_key_len = 0; + unsigned char* public_key_bytes = NULL; + int public_key_len = 0; + ecc_key *ecc = NULL; + const struct dropbear_ecc_curve *curve = NULL; - /* See SEC1 v2, Appendix C.4 */ - /* OpenSSL (so OpenSSH) seems to include the optional parts. */ + /* See SEC1 v2, Appendix C.4 */ + /* OpenSSL (so OpenSSH) seems to include the optional parts. */ - /* privateKey OCTET STRING, */ - ret = ber_read_id_len(p, key->keyblob+key->keyblob_len-p, - &id, &len, &flags); - p += ret; - /* id==4 for octet string */ + /* privateKey OCTET STRING, */ + ret = ber_read_id_len(p, key->keyblob+key->keyblob_len-p, + &id, &len, &flags); + p += ret; + /* id==4 for octet string */ if (ret < 0 || id != 4 || len < 0 || - key->keyblob+key->keyblob_len-p < len) { - errmsg = "ASN.1 decoding failure"; - goto error; - } - private_key_bytes = p; - private_key_len = len; - p += len; + key->keyblob+key->keyblob_len-p < len) { + errmsg = "ASN.1 decoding failure"; + goto error; + } + private_key_bytes = p; + private_key_len = len; + p += len; - /* parameters [0] ECDomainParameters {{ SECGCurveNames }} OPTIONAL, */ - ret = ber_read_id_len(p, key->keyblob+key->keyblob_len-p, - &id, &len, &flags); - p += ret; - /* id==0 */ + /* parameters [0] ECDomainParameters {{ SECGCurveNames }} OPTIONAL, */ + ret = ber_read_id_len(p, key->keyblob+key->keyblob_len-p, + &id, &len, &flags); + p += ret; + /* id==0 */ if (ret < 0 || id != 0 || len < 0) { - errmsg = "ASN.1 decoding failure"; - goto error; - } + errmsg = "ASN.1 decoding failure"; + goto error; + } - ret = ber_read_id_len(p, key->keyblob+key->keyblob_len-p, - &id, &len, &flags); - p += ret; - /* id==6 for object */ + ret = ber_read_id_len(p, key->keyblob+key->keyblob_len-p, + &id, &len, &flags); + p += ret; + /* id==6 for object */ if (ret < 0 || id != 6 || len < 0 || - key->keyblob+key->keyblob_len-p < len) { - errmsg = "ASN.1 decoding failure"; - goto error; - } + key->keyblob+key->keyblob_len-p < len) { + errmsg = "ASN.1 decoding failure"; + goto error; + } - if (0) {} -#ifdef DROPBEAR_ECC_256 - else if (len == sizeof(OID_SEC256R1_BLOB) - && memcmp(p, OID_SEC256R1_BLOB, len) == 0) { - retkey->type = DROPBEAR_SIGNKEY_ECDSA_NISTP256; - curve = &ecc_curve_nistp256; - } + if (0) {} +#if DROPBEAR_ECC_256 + else if (len == sizeof(OID_SEC256R1_BLOB) + && memcmp(p, OID_SEC256R1_BLOB, len) == 0) { + retkey->type = DROPBEAR_SIGNKEY_ECDSA_NISTP256; + curve = &ecc_curve_nistp256; + } #endif -#ifdef DROPBEAR_ECC_384 - else if (len == sizeof(OID_SEC384R1_BLOB) - && memcmp(p, OID_SEC384R1_BLOB, len) == 0) { - retkey->type = DROPBEAR_SIGNKEY_ECDSA_NISTP384; - curve = &ecc_curve_nistp384; - } +#if DROPBEAR_ECC_384 + else if (len == sizeof(OID_SEC384R1_BLOB) + && memcmp(p, OID_SEC384R1_BLOB, len) == 0) { + retkey->type = DROPBEAR_SIGNKEY_ECDSA_NISTP384; + curve = &ecc_curve_nistp384; + } #endif -#ifdef DROPBEAR_ECC_521 - else if (len == sizeof(OID_SEC521R1_BLOB) - && memcmp(p, OID_SEC521R1_BLOB, len) == 0) { - retkey->type = DROPBEAR_SIGNKEY_ECDSA_NISTP521; - curve = &ecc_curve_nistp521; - } +#if DROPBEAR_ECC_521 + else if (len == sizeof(OID_SEC521R1_BLOB) + && memcmp(p, OID_SEC521R1_BLOB, len) == 0) { + retkey->type = DROPBEAR_SIGNKEY_ECDSA_NISTP521; + curve = &ecc_curve_nistp521; + } #endif - else { - errmsg = "Unknown ECC key type"; - goto error; - } - p += len; + else { + errmsg = "Unknown ECC key type"; + goto error; + } + p += len; - /* publicKey [1] BIT STRING OPTIONAL */ - ret = ber_read_id_len(p, key->keyblob+key->keyblob_len-p, - &id, &len, &flags); - p += ret; - /* id==1 */ + /* publicKey [1] BIT STRING OPTIONAL */ + ret = ber_read_id_len(p, key->keyblob+key->keyblob_len-p, + &id, &len, &flags); + p += ret; + /* id==1 */ if (ret < 0 || id != 1 || len < 0) { - errmsg = "ASN.1 decoding failure"; - goto error; - } + errmsg = "ASN.1 decoding failure"; + goto error; + } - ret = ber_read_id_len(p, key->keyblob+key->keyblob_len-p, - &id, &len, &flags); - p += ret; - /* id==3 for bit string */ + ret = ber_read_id_len(p, key->keyblob+key->keyblob_len-p, + &id, &len, &flags); + p += ret; + /* id==3 for bit string */ if (ret < 0 || id != 3 || len < 0 || - key->keyblob+key->keyblob_len-p < len) { - errmsg = "ASN.1 decoding failure"; - goto error; - } - public_key_bytes = p+1; - public_key_len = len-1; - p += len; + key->keyblob+key->keyblob_len-p < len) { + errmsg = "ASN.1 decoding failure"; + goto error; + } + public_key_bytes = p+1; + public_key_len = len-1; + p += len; - buf_putbytes(blobbuf, public_key_bytes, public_key_len); - ecc = buf_get_ecc_raw_pubkey(blobbuf, curve); - if (!ecc) { - errmsg = "Error parsing ECC key"; - goto error; - } - m_mp_alloc_init_multi((mp_int**)&ecc->k, NULL); - if (mp_read_unsigned_bin(ecc->k, private_key_bytes, private_key_len) - != MP_OKAY) { - errmsg = "Error parsing ECC key"; - goto error; - } + buf_putbytes(blobbuf, public_key_bytes, public_key_len); + ecc = buf_get_ecc_raw_pubkey(blobbuf, curve); + if (!ecc) { + errmsg = "Error parsing ECC key"; + goto error; + } + m_mp_alloc_init_multi((mp_int**)&ecc->k, NULL); + if (mp_read_unsigned_bin(ecc->k, private_key_bytes, private_key_len) + != MP_OKAY) { + errmsg = "Error parsing ECC key"; + goto error; + } - *signkey_key_ptr(retkey, retkey->type) = ecc; - } + *signkey_key_ptr(retkey, retkey->type) = ecc; + } #endif /* DROPBEAR_ECDSA */ /* @@ -795,19 +797,19 @@ * functions; this is a bit faffy but it does mean we get all * the sanity checks for free. */ - if (key->type == OSSH_RSA || key->type == OSSH_DSA) { - buf_setpos(blobbuf, 0); - type = DROPBEAR_SIGNKEY_ANY; - if (buf_get_priv_key(blobbuf, retkey, &type) - != DROPBEAR_SUCCESS) { - errmsg = "unable to create key structure"; - sign_key_free(retkey); - retkey = NULL; - goto error; + if (key->type == OSSH_RSA || key->type == OSSH_DSA) { + buf_setpos(blobbuf, 0); + type = DROPBEAR_SIGNKEY_ANY; + if (buf_get_priv_key(blobbuf, retkey, &type) + != DROPBEAR_SUCCESS) { + errmsg = "unable to create key structure"; + sign_key_free(retkey); + retkey = NULL; + goto error; + } } - } - errmsg = NULL; /* no error */ + errmsg = NULL; /* no error */ retval = retkey; error: @@ -828,301 +830,301 @@ static int openssh_write(const char *filename, sign_key *key, char *passphrase) { - buffer * keyblob = NULL; - buffer * extrablob = NULL; /* used for calculated values to write */ - unsigned char *outblob = NULL; - int outlen = -9999; + buffer * keyblob = NULL; + buffer * extrablob = NULL; /* used for calculated values to write */ + unsigned char *outblob = NULL; + int outlen = -9999; struct mpint_pos numbers[9]; - int nnumbers = -1, pos = 0, len = 0, seqlen, i; - char *header = NULL, *footer = NULL; + int nnumbers = -1, pos = 0, len = 0, seqlen, i; + char *header = NULL, *footer = NULL; char zero[1]; int ret = 0; FILE *fp; -#ifdef DROPBEAR_RSA - mp_int dmp1, dmq1, iqmp, tmpval; /* for rsa */ +#if DROPBEAR_RSA + mp_int dmp1, dmq1, iqmp, tmpval; /* for rsa */ #endif - if ( -#ifdef DROPBEAR_RSA - key->type == DROPBEAR_SIGNKEY_RSA || + if ( +#if DROPBEAR_RSA + key->type == DROPBEAR_SIGNKEY_RSA || #endif -#ifdef DROPBEAR_DSS - key->type == DROPBEAR_SIGNKEY_DSS || +#if DROPBEAR_DSS + key->type == DROPBEAR_SIGNKEY_DSS || #endif - 0) - { - /* - * Fetch the key blobs. - */ - keyblob = buf_new(3000); - buf_put_priv_key(keyblob, key, key->type); + 0) + { + /* + * Fetch the key blobs. + */ + keyblob = buf_new(3000); + buf_put_priv_key(keyblob, key, key->type); - buf_setpos(keyblob, 0); - /* skip the "ssh-rsa" or "ssh-dss" header */ - buf_incrpos(keyblob, buf_getint(keyblob)); + buf_setpos(keyblob, 0); + /* skip the "ssh-rsa" or "ssh-dss" header */ + buf_incrpos(keyblob, buf_getint(keyblob)); - /* - * Find the sequence of integers to be encoded into the OpenSSH - * key blob, and also decide on the header line. - */ - numbers[0].start = zero; numbers[0].bytes = 1; zero[0] = '\0'; + /* + * Find the sequence of integers to be encoded into the OpenSSH + * key blob, and also decide on the header line. + */ + numbers[0].start = zero; numbers[0].bytes = 1; zero[0] = '\0'; - #ifdef DROPBEAR_RSA - if (key->type == DROPBEAR_SIGNKEY_RSA) { + #ifdef DROPBEAR_RSA + if (key->type == DROPBEAR_SIGNKEY_RSA) { - if (key->rsakey->p == NULL || key->rsakey->q == NULL) { - fprintf(stderr, "Pre-0.33 Dropbear keys cannot be converted to OpenSSH keys.\n"); - goto error; - } - - /* e */ - numbers[2].bytes = buf_getint(keyblob); - numbers[2].start = buf_getptr(keyblob, numbers[2].bytes); - buf_incrpos(keyblob, numbers[2].bytes); - - /* n */ - numbers[1].bytes = buf_getint(keyblob); - numbers[1].start = buf_getptr(keyblob, numbers[1].bytes); - buf_incrpos(keyblob, numbers[1].bytes); + if (key->rsakey->p == NULL || key->rsakey->q == NULL) { + fprintf(stderr, "Pre-0.33 Dropbear keys cannot be converted to OpenSSH keys.\n"); + goto error; + } - /* d */ - numbers[3].bytes = buf_getint(keyblob); - numbers[3].start = buf_getptr(keyblob, numbers[3].bytes); - buf_incrpos(keyblob, numbers[3].bytes); + /* e */ + numbers[2].bytes = buf_getint(keyblob); + numbers[2].start = buf_getptr(keyblob, numbers[2].bytes); + buf_incrpos(keyblob, numbers[2].bytes); + + /* n */ + numbers[1].bytes = buf_getint(keyblob); + numbers[1].start = buf_getptr(keyblob, numbers[1].bytes); + buf_incrpos(keyblob, numbers[1].bytes); + + /* d */ + numbers[3].bytes = buf_getint(keyblob); + numbers[3].start = buf_getptr(keyblob, numbers[3].bytes); + buf_incrpos(keyblob, numbers[3].bytes); + + /* p */ + numbers[4].bytes = buf_getint(keyblob); + numbers[4].start = buf_getptr(keyblob, numbers[4].bytes); + buf_incrpos(keyblob, numbers[4].bytes); + + /* q */ + numbers[5].bytes = buf_getint(keyblob); + numbers[5].start = buf_getptr(keyblob, numbers[5].bytes); + buf_incrpos(keyblob, numbers[5].bytes); - /* p */ - numbers[4].bytes = buf_getint(keyblob); - numbers[4].start = buf_getptr(keyblob, numbers[4].bytes); - buf_incrpos(keyblob, numbers[4].bytes); - - /* q */ - numbers[5].bytes = buf_getint(keyblob); - numbers[5].start = buf_getptr(keyblob, numbers[5].bytes); - buf_incrpos(keyblob, numbers[5].bytes); - - /* now calculate some extra parameters: */ - m_mp_init(&tmpval); - m_mp_init(&dmp1); - m_mp_init(&dmq1); - m_mp_init(&iqmp); + /* now calculate some extra parameters: */ + m_mp_init(&tmpval); + m_mp_init(&dmp1); + m_mp_init(&dmq1); + m_mp_init(&iqmp); - /* dmp1 = d mod (p-1) */ - if (mp_sub_d(key->rsakey->p, 1, &tmpval) != MP_OKAY) { - fprintf(stderr, "Bignum error for p-1\n"); - goto error; - } - if (mp_mod(key->rsakey->d, &tmpval, &dmp1) != MP_OKAY) { - fprintf(stderr, "Bignum error for dmp1\n"); - goto error; - } + /* dmp1 = d mod (p-1) */ + if (mp_sub_d(key->rsakey->p, 1, &tmpval) != MP_OKAY) { + fprintf(stderr, "Bignum error for p-1\n"); + goto error; + } + if (mp_mod(key->rsakey->d, &tmpval, &dmp1) != MP_OKAY) { + fprintf(stderr, "Bignum error for dmp1\n"); + goto error; + } - /* dmq1 = d mod (q-1) */ - if (mp_sub_d(key->rsakey->q, 1, &tmpval) != MP_OKAY) { - fprintf(stderr, "Bignum error for q-1\n"); - goto error; - } - if (mp_mod(key->rsakey->d, &tmpval, &dmq1) != MP_OKAY) { - fprintf(stderr, "Bignum error for dmq1\n"); - goto error; - } + /* dmq1 = d mod (q-1) */ + if (mp_sub_d(key->rsakey->q, 1, &tmpval) != MP_OKAY) { + fprintf(stderr, "Bignum error for q-1\n"); + goto error; + } + if (mp_mod(key->rsakey->d, &tmpval, &dmq1) != MP_OKAY) { + fprintf(stderr, "Bignum error for dmq1\n"); + goto error; + } - /* iqmp = (q^-1) mod p */ - if (mp_invmod(key->rsakey->q, key->rsakey->p, &iqmp) != MP_OKAY) { - fprintf(stderr, "Bignum error for iqmp\n"); - goto error; - } + /* iqmp = (q^-1) mod p */ + if (mp_invmod(key->rsakey->q, key->rsakey->p, &iqmp) != MP_OKAY) { + fprintf(stderr, "Bignum error for iqmp\n"); + goto error; + } - extrablob = buf_new(2000); - buf_putmpint(extrablob, &dmp1); - buf_putmpint(extrablob, &dmq1); - buf_putmpint(extrablob, &iqmp); - buf_setpos(extrablob, 0); - mp_clear(&dmp1); - mp_clear(&dmq1); - mp_clear(&iqmp); - mp_clear(&tmpval); - - /* dmp1 */ - numbers[6].bytes = buf_getint(extrablob); - numbers[6].start = buf_getptr(extrablob, numbers[6].bytes); - buf_incrpos(extrablob, numbers[6].bytes); - - /* dmq1 */ - numbers[7].bytes = buf_getint(extrablob); - numbers[7].start = buf_getptr(extrablob, numbers[7].bytes); - buf_incrpos(extrablob, numbers[7].bytes); - - /* iqmp */ - numbers[8].bytes = buf_getint(extrablob); - numbers[8].start = buf_getptr(extrablob, numbers[8].bytes); - buf_incrpos(extrablob, numbers[8].bytes); + extrablob = buf_new(2000); + buf_putmpint(extrablob, &dmp1); + buf_putmpint(extrablob, &dmq1); + buf_putmpint(extrablob, &iqmp); + buf_setpos(extrablob, 0); + mp_clear(&dmp1); + mp_clear(&dmq1); + mp_clear(&iqmp); + mp_clear(&tmpval); + + /* dmp1 */ + numbers[6].bytes = buf_getint(extrablob); + numbers[6].start = buf_getptr(extrablob, numbers[6].bytes); + buf_incrpos(extrablob, numbers[6].bytes); + + /* dmq1 */ + numbers[7].bytes = buf_getint(extrablob); + numbers[7].start = buf_getptr(extrablob, numbers[7].bytes); + buf_incrpos(extrablob, numbers[7].bytes); + + /* iqmp */ + numbers[8].bytes = buf_getint(extrablob); + numbers[8].start = buf_getptr(extrablob, numbers[8].bytes); + buf_incrpos(extrablob, numbers[8].bytes); - nnumbers = 9; - header = "-----BEGIN RSA PRIVATE KEY-----\n"; - footer = "-----END RSA PRIVATE KEY-----\n"; - } - #endif /* DROPBEAR_RSA */ + nnumbers = 9; + header = "-----BEGIN RSA PRIVATE KEY-----\n"; + footer = "-----END RSA PRIVATE KEY-----\n"; + } + #endif /* DROPBEAR_RSA */ - #ifdef DROPBEAR_DSS - if (key->type == DROPBEAR_SIGNKEY_DSS) { + #ifdef DROPBEAR_DSS + if (key->type == DROPBEAR_SIGNKEY_DSS) { - /* p */ - numbers[1].bytes = buf_getint(keyblob); - numbers[1].start = buf_getptr(keyblob, numbers[1].bytes); - buf_incrpos(keyblob, numbers[1].bytes); + /* p */ + numbers[1].bytes = buf_getint(keyblob); + numbers[1].start = buf_getptr(keyblob, numbers[1].bytes); + buf_incrpos(keyblob, numbers[1].bytes); - /* q */ - numbers[2].bytes = buf_getint(keyblob); - numbers[2].start = buf_getptr(keyblob, numbers[2].bytes); - buf_incrpos(keyblob, numbers[2].bytes); + /* q */ + numbers[2].bytes = buf_getint(keyblob); + numbers[2].start = buf_getptr(keyblob, numbers[2].bytes); + buf_incrpos(keyblob, numbers[2].bytes); - /* g */ - numbers[3].bytes = buf_getint(keyblob); - numbers[3].start = buf_getptr(keyblob, numbers[3].bytes); - buf_incrpos(keyblob, numbers[3].bytes); + /* g */ + numbers[3].bytes = buf_getint(keyblob); + numbers[3].start = buf_getptr(keyblob, numbers[3].bytes); + buf_incrpos(keyblob, numbers[3].bytes); - /* y */ - numbers[4].bytes = buf_getint(keyblob); - numbers[4].start = buf_getptr(keyblob, numbers[4].bytes); - buf_incrpos(keyblob, numbers[4].bytes); + /* y */ + numbers[4].bytes = buf_getint(keyblob); + numbers[4].start = buf_getptr(keyblob, numbers[4].bytes); + buf_incrpos(keyblob, numbers[4].bytes); - /* x */ - numbers[5].bytes = buf_getint(keyblob); - numbers[5].start = buf_getptr(keyblob, numbers[5].bytes); - buf_incrpos(keyblob, numbers[5].bytes); + /* x */ + numbers[5].bytes = buf_getint(keyblob); + numbers[5].start = buf_getptr(keyblob, numbers[5].bytes); + buf_incrpos(keyblob, numbers[5].bytes); - nnumbers = 6; - header = "-----BEGIN DSA PRIVATE KEY-----\n"; - footer = "-----END DSA PRIVATE KEY-----\n"; - } - #endif /* DROPBEAR_DSS */ + nnumbers = 6; + header = "-----BEGIN DSA PRIVATE KEY-----\n"; + footer = "-----END DSA PRIVATE KEY-----\n"; + } + #endif /* DROPBEAR_DSS */ - /* - * Now count up the total size of the ASN.1 encoded integers, - * so as to determine the length of the containing SEQUENCE. - */ - len = 0; - for (i = 0; i < nnumbers; i++) { - len += ber_write_id_len(NULL, 2, numbers[i].bytes, 0); - len += numbers[i].bytes; - } - seqlen = len; - /* Now add on the SEQUENCE header. */ - len += ber_write_id_len(NULL, 16, seqlen, ASN1_CONSTRUCTED); - /* Round up to the cipher block size, ensuring we have at least one - * byte of padding (see below). */ - outlen = len; - if (passphrase) - outlen = (outlen+8) &~ 7; + /* + * Now count up the total size of the ASN.1 encoded integers, + * so as to determine the length of the containing SEQUENCE. + */ + len = 0; + for (i = 0; i < nnumbers; i++) { + len += ber_write_id_len(NULL, 2, numbers[i].bytes, 0); + len += numbers[i].bytes; + } + seqlen = len; + /* Now add on the SEQUENCE header. */ + len += ber_write_id_len(NULL, 16, seqlen, ASN1_CONSTRUCTED); + /* Round up to the cipher block size, ensuring we have at least one + * byte of padding (see below). */ + outlen = len; + if (passphrase) + outlen = (outlen+8) &~ 7; - /* - * Now we know how big outblob needs to be. Allocate it. - */ - outblob = (unsigned char*)m_malloc(outlen); + /* + * Now we know how big outblob needs to be. Allocate it. + */ + outblob = (unsigned char*)m_malloc(outlen); - /* - * And write the data into it. - */ - pos = 0; - pos += ber_write_id_len(outblob+pos, 16, seqlen, ASN1_CONSTRUCTED); - for (i = 0; i < nnumbers; i++) { - pos += ber_write_id_len(outblob+pos, 2, numbers[i].bytes, 0); - memcpy(outblob+pos, numbers[i].start, numbers[i].bytes); - pos += numbers[i].bytes; - } - } /* end RSA and DSS handling */ + /* + * And write the data into it. + */ + pos = 0; + pos += ber_write_id_len(outblob+pos, 16, seqlen, ASN1_CONSTRUCTED); + for (i = 0; i < nnumbers; i++) { + pos += ber_write_id_len(outblob+pos, 2, numbers[i].bytes, 0); + memcpy(outblob+pos, numbers[i].start, numbers[i].bytes); + pos += numbers[i].bytes; + } + } /* end RSA and DSS handling */ -#ifdef DROPBEAR_ECDSA - if (key->type == DROPBEAR_SIGNKEY_ECDSA_NISTP256 - || key->type == DROPBEAR_SIGNKEY_ECDSA_NISTP384 - || key->type == DROPBEAR_SIGNKEY_ECDSA_NISTP521) { +#if DROPBEAR_ECDSA + if (key->type == DROPBEAR_SIGNKEY_ECDSA_NISTP256 + || key->type == DROPBEAR_SIGNKEY_ECDSA_NISTP384 + || key->type == DROPBEAR_SIGNKEY_ECDSA_NISTP521) { - /* SEC1 V2 appendix c.4 - ECPrivateKey ::= SEQUENCE { - version INTEGER { ecPrivkeyVer1(1) } (ecPrivkeyVer1), - privateKey OCTET STRING, - parameters [0] ECDomainParameters {{ SECGCurveNames }} OPTIONAL, - publicKey [1] BIT STRING OPTIONAL - } - */ - buffer *seq_buf = buf_new(400); - ecc_key **eck = (ecc_key**)signkey_key_ptr(key, key->type); - const long curve_size = (*eck)->dp->size; - int curve_oid_len = 0; - const void* curve_oid = NULL; - unsigned long pubkey_size = 2*curve_size+1; - int k_size; - int err = 0; + /* SEC1 V2 appendix c.4 + ECPrivateKey ::= SEQUENCE { + version INTEGER { ecPrivkeyVer1(1) } (ecPrivkeyVer1), + privateKey OCTET STRING, + parameters [0] ECDomainParameters {{ SECGCurveNames }} OPTIONAL, + publicKey [1] BIT STRING OPTIONAL + } + */ + buffer *seq_buf = buf_new(400); + ecc_key **eck = (ecc_key**)signkey_key_ptr(key, key->type); + const long curve_size = (*eck)->dp->size; + int curve_oid_len = 0; + const void* curve_oid = NULL; + unsigned long pubkey_size = 2*curve_size+1; + int k_size; + int err = 0; - /* version. less than 10 bytes */ - buf_incrwritepos(seq_buf, - ber_write_id_len(buf_getwriteptr(seq_buf, 10), 2, 1, 0)); - buf_putbyte(seq_buf, 1); + /* version. less than 10 bytes */ + buf_incrwritepos(seq_buf, + ber_write_id_len(buf_getwriteptr(seq_buf, 10), 2, 1, 0)); + buf_putbyte(seq_buf, 1); - /* privateKey */ - k_size = mp_unsigned_bin_size((*eck)->k); - dropbear_assert(k_size <= curve_size); - buf_incrwritepos(seq_buf, - ber_write_id_len(buf_getwriteptr(seq_buf, 10), 4, k_size, 0)); - mp_to_unsigned_bin((*eck)->k, buf_getwriteptr(seq_buf, k_size)); - buf_incrwritepos(seq_buf, k_size); + /* privateKey */ + k_size = mp_unsigned_bin_size((*eck)->k); + dropbear_assert(k_size <= curve_size); + buf_incrwritepos(seq_buf, + ber_write_id_len(buf_getwriteptr(seq_buf, 10), 4, k_size, 0)); + mp_to_unsigned_bin((*eck)->k, buf_getwriteptr(seq_buf, k_size)); + buf_incrwritepos(seq_buf, k_size); - /* SECGCurveNames */ - switch (key->type) - { - case DROPBEAR_SIGNKEY_ECDSA_NISTP256: - curve_oid_len = sizeof(OID_SEC256R1_BLOB); - curve_oid = OID_SEC256R1_BLOB; - break; - case DROPBEAR_SIGNKEY_ECDSA_NISTP384: - curve_oid_len = sizeof(OID_SEC384R1_BLOB); - curve_oid = OID_SEC384R1_BLOB; - break; - case DROPBEAR_SIGNKEY_ECDSA_NISTP521: - curve_oid_len = sizeof(OID_SEC521R1_BLOB); - curve_oid = OID_SEC521R1_BLOB; - break; - default: - dropbear_exit("Internal error"); - } + /* SECGCurveNames */ + switch (key->type) + { + case DROPBEAR_SIGNKEY_ECDSA_NISTP256: + curve_oid_len = sizeof(OID_SEC256R1_BLOB); + curve_oid = OID_SEC256R1_BLOB; + break; + case DROPBEAR_SIGNKEY_ECDSA_NISTP384: + curve_oid_len = sizeof(OID_SEC384R1_BLOB); + curve_oid = OID_SEC384R1_BLOB; + break; + case DROPBEAR_SIGNKEY_ECDSA_NISTP521: + curve_oid_len = sizeof(OID_SEC521R1_BLOB); + curve_oid = OID_SEC521R1_BLOB; + break; + default: + dropbear_exit("Internal error"); + } - buf_incrwritepos(seq_buf, - ber_write_id_len(buf_getwriteptr(seq_buf, 10), 0, 2+curve_oid_len, 0xa0)); - /* object == 6 */ - buf_incrwritepos(seq_buf, - ber_write_id_len(buf_getwriteptr(seq_buf, 10), 6, curve_oid_len, 0)); - buf_putbytes(seq_buf, curve_oid, curve_oid_len); + buf_incrwritepos(seq_buf, + ber_write_id_len(buf_getwriteptr(seq_buf, 10), 0, 2+curve_oid_len, 0xa0)); + /* object == 6 */ + buf_incrwritepos(seq_buf, + ber_write_id_len(buf_getwriteptr(seq_buf, 10), 6, curve_oid_len, 0)); + buf_putbytes(seq_buf, curve_oid, curve_oid_len); - buf_incrwritepos(seq_buf, - ber_write_id_len(buf_getwriteptr(seq_buf, 10), 1, 2+1+pubkey_size, 0xa0)); - buf_incrwritepos(seq_buf, - ber_write_id_len(buf_getwriteptr(seq_buf, 10), 3, 1+pubkey_size, 0)); - buf_putbyte(seq_buf, 0); - err = ecc_ansi_x963_export(*eck, buf_getwriteptr(seq_buf, pubkey_size), &pubkey_size); - if (err != CRYPT_OK) { - dropbear_exit("ECC error"); - } - buf_incrwritepos(seq_buf, pubkey_size); + buf_incrwritepos(seq_buf, + ber_write_id_len(buf_getwriteptr(seq_buf, 10), 1, 2+1+pubkey_size, 0xa0)); + buf_incrwritepos(seq_buf, + ber_write_id_len(buf_getwriteptr(seq_buf, 10), 3, 1+pubkey_size, 0)); + buf_putbyte(seq_buf, 0); + err = ecc_ansi_x963_export(*eck, buf_getwriteptr(seq_buf, pubkey_size), &pubkey_size); + if (err != CRYPT_OK) { + dropbear_exit("ECC error"); + } + buf_incrwritepos(seq_buf, pubkey_size); - buf_setpos(seq_buf, 0); - - outblob = (unsigned char*)m_malloc(1000); + buf_setpos(seq_buf, 0); + + outblob = (unsigned char*)m_malloc(1000); - pos = 0; - pos += ber_write_id_len(outblob+pos, 16, seq_buf->len, ASN1_CONSTRUCTED); - memcpy(&outblob[pos], seq_buf->data, seq_buf->len); - pos += seq_buf->len; - len = pos; - outlen = len; + pos = 0; + pos += ber_write_id_len(outblob+pos, 16, seq_buf->len, ASN1_CONSTRUCTED); + memcpy(&outblob[pos], seq_buf->data, seq_buf->len); + pos += seq_buf->len; + len = pos; + outlen = len; - buf_burn(seq_buf); - buf_free(seq_buf); - seq_buf = NULL; + buf_burn(seq_buf); + buf_free(seq_buf); + seq_buf = NULL; - header = "-----BEGIN EC PRIVATE KEY-----\n"; - footer = "-----END EC PRIVATE KEY-----\n"; - } + header = "-----BEGIN EC PRIVATE KEY-----\n"; + footer = "-----END EC PRIVATE KEY-----\n"; + } #endif /* @@ -1142,7 +1144,7 @@ * with the same value. Those are all removed and the rest is * returned. */ - dropbear_assert(pos == len); + dropbear_assert(pos == len); while (pos < outlen) { outblob[pos++] = outlen - len; } @@ -1151,25 +1153,25 @@ * Encrypt the key. */ if (passphrase) { - fprintf(stderr, "Encrypted keys aren't supported currently\n"); - goto error; + fprintf(stderr, "Encrypted keys aren't supported currently\n"); + goto error; } /* * And save it. We'll use Unix line endings just in case it's * subsequently transferred in binary mode. */ - if (strlen(filename) == 1 && filename[0] == '-') { - fp = stdout; - } else { - fp = fopen(filename, "wb"); /* ensure Unix line endings */ - } - if (!fp) { - fprintf(stderr, "Failed opening output file\n"); + if (strlen(filename) == 1 && filename[0] == '-') { + fp = stdout; + } else { + fp = fopen(filename, "wb"); /* ensure Unix line endings */ + } + if (!fp) { + fprintf(stderr, "Failed opening output file\n"); goto error; - } + } fputs(header, fp); - base64_encode_fp(fp, outblob, outlen, 64); + base64_encode_fp(fp, outblob, outlen, 64); fputs(footer, fp); fclose(fp); ret = 1; @@ -1205,10 +1207,10 @@ * * So. The blob contains: * - * - uint32 0x3f6ff9eb (magic number) - * - uint32 size (total blob size) - * - string key-type (see below) - * - string cipher-type (tells you if key is encrypted) + * - uint32 0x3f6ff9eb (magic number) + * - uint32 size (total blob size) + * - string key-type (see below) + * - string cipher-type (tells you if key is encrypted) * - string encrypted-blob * * (The first size field includes the size field itself and the @@ -1264,13 +1266,13 @@ * - first 16 bytes are MD5(passphrase) * - next 16 bytes are MD5(passphrase || first 16 bytes) * - if there were more, they'd be MD5(passphrase || first 32), - * and so on. + * and so on. */ #define SSHCOM_MAGIC_NUMBER 0x3f6ff9eb struct sshcom_key { - char comment[256]; /* allowing any length is overkill */ + char comment[256]; /* allowing any length is overkill */ unsigned char *keyblob; int keyblob_len, keyblob_size; }; @@ -1291,7 +1293,7 @@ ret->keyblob = NULL; ret->keyblob_len = ret->keyblob_size = 0; - fp = fopen(filename, "r"); + fp = fopen(filename, "r"); if (!fp) { errmsg = "Unable to open key file"; goto error; @@ -1309,7 +1311,7 @@ goto error; } if (!strcmp(buffer, "---- END SSH2 ENCRYPTED PRIVATE KEY ----\n")) - break; /* done */ + break; /* done */ if ((p = strchr(buffer, ':')) != NULL) { if (headers_done) { errmsg = "Header found in body of key data"; @@ -1386,10 +1388,10 @@ if (ret) { if (ret->keyblob) { memset(ret->keyblob, 0, ret->keyblob_size); - m_free(ret->keyblob); + m_free(ret->keyblob); } memset(ret, 0, sizeof(*ret)); - m_free(ret); + m_free(ret); } return NULL; } @@ -1407,7 +1409,7 @@ * Check magic number. */ if (GET_32BIT(key->keyblob) != 0x3f6ff9eb) - return 0; /* key is invalid */ + return 0; /* key is invalid */ /* * Find the cipher-type string. @@ -1415,23 +1417,23 @@ answer = 0; pos = 8; if (key->keyblob_len < pos+4) - goto done; /* key is far too short */ + goto done; /* key is far too short */ len = toint(GET_32BIT(key->keyblob + pos)); if (len < 0 || len > key->keyblob_len - pos - 4) - goto done; /* key is far too short */ + goto done; /* key is far too short */ pos += 4 + len; /* skip key type */ len = toint(GET_32BIT(key->keyblob + pos)); /* find cipher-type length */ if (len < 0 || len > key->keyblob_len - pos - 4) - goto done; /* cipher type string is incomplete */ + goto done; /* cipher type string is incomplete */ if (len != 4 || 0 != memcmp(key->keyblob + pos + 4, "none", 4)) answer = 1; done: *comment = dupstr(key->comment); memset(key->keyblob, 0, key->keyblob_size); - m_free(key->keyblob); + m_free(key->keyblob); memset(key, 0, sizeof(*key)); - m_free(key); + m_free(key); return answer; } @@ -1455,7 +1457,7 @@ error: ret->start = NULL; ret->bytes = -1; - return len; /* ensure further calls fail as well */ + return len; /* ensure further calls fail as well */ } static int sshcom_put_mpint(void *target, void *data, int len) @@ -1681,13 +1683,13 @@ } else return NULL; - dropbear_assert(privlen > 0); /* should have bombed by now if not */ + dropbear_assert(privlen > 0); /* should have bombed by now if not */ retkey = snew(struct ssh2_userkey); retkey->alg = alg; retkey->data = alg->createkey(blob, publen, blob+publen, privlen); if (!retkey->data) { - m_free(retkey); + m_free(retkey); errmsg = "unable to create key data structure"; goto error; } @@ -1699,12 +1701,12 @@ error: if (blob) { memset(blob, 0, blobsize); - m_free(blob); + m_free(blob); } memset(key->keyblob, 0, key->keyblob_size); - m_free(key->keyblob); + m_free(key->keyblob); memset(key, 0, sizeof(*key)); - m_free(key); + m_free(key); return ret; } @@ -1747,7 +1749,7 @@ pos += ssh2_read_mpint(privblob+pos, privlen-pos, &q); pos += ssh2_read_mpint(privblob+pos, privlen-pos, &iqmp); - dropbear_assert(e.start && iqmp.start); /* can't go wrong */ + dropbear_assert(e.start && iqmp.start); /* can't go wrong */ numbers[0] = e; numbers[1] = d; @@ -1771,7 +1773,7 @@ pos = 0; pos += ssh2_read_mpint(privblob+pos, privlen-pos, &x); - dropbear_assert(y.start && x.start); /* can't go wrong */ + dropbear_assert(y.start && x.start); /* can't go wrong */ numbers[0] = p; numbers[1] = g; @@ -1783,7 +1785,7 @@ initial_zero = 1; type = "dl-modp{sign{dsa-nist-sha1},dh{plain}}"; } else { - dropbear_assert(0); /* zoinks! */ + dropbear_assert(0); /* zoinks! */ } /* @@ -1801,15 +1803,15 @@ */ pos = 0; PUT_32BIT(outblob+pos, SSHCOM_MAGIC_NUMBER); pos += 4; - pos += 4; /* length field, fill in later */ + pos += 4; /* length field, fill in later */ pos += put_string(outblob+pos, type, strlen(type)); { char *ciphertype = passphrase ? "3des-cbc" : "none"; pos += put_string(outblob+pos, ciphertype, strlen(ciphertype)); } - lenpos = pos; /* remember this position */ - pos += 4; /* encrypted-blob size */ - pos += 4; /* encrypted-payload size */ + lenpos = pos; /* remember this position */ + pos += 4; /* encrypted-blob size */ + pos += 4; /* encrypted-payload size */ if (initial_zero) { PUT_32BIT(outblob+pos, 0); pos += 4; @@ -1827,13 +1829,13 @@ } ciphertext = (char *)outblob+lenpos+4; cipherlen = pos - (lenpos+4); - dropbear_assert(!passphrase || cipherlen % 8 == 0); + dropbear_assert(!passphrase || cipherlen % 8 == 0); /* Wrap up the encrypted blob string. */ PUT_32BIT(outblob+lenpos, cipherlen); /* And finally fill in the total length field. */ PUT_32BIT(outblob+4, pos); - dropbear_assert(pos < outlen); + dropbear_assert(pos < outlen); /* * Encrypt the key. @@ -1874,7 +1876,7 @@ * And save it. We'll use Unix line endings just in case it's * subsequently transferred in binary mode. */ - fp = fopen(filename, "wb"); /* ensure Unix line endings */ + fp = fopen(filename, "wb"); /* ensure Unix line endings */ if (!fp) goto error; fputs("---- BEGIN SSH2 ENCRYPTED PRIVATE KEY ----\n", fp); @@ -1886,16 +1888,16 @@ * Don't ask me, I didn't design it. */ { - int slen = 60; /* starts at 60 due to "Comment: " */ + int slen = 60; /* starts at 60 due to "Comment: " */ char *c = key->comment; while ((int)strlen(c) > slen) { fprintf(fp, "%.*s\\\n", slen, c); c += slen; - slen = 70; /* allow 70 chars on subsequent lines */ + slen = 70; /* allow 70 chars on subsequent lines */ } fprintf(fp, "%s\"\n", c); } - base64_encode_fp(fp, outblob, pos, 70); + base64_encode_fp(fp, outblob, pos, 70); fputs("---- END SSH2 ENCRYPTED PRIVATE KEY ----\n", fp); fclose(fp); ret = 1; @@ -1903,15 +1905,15 @@ error: if (outblob) { memset(outblob, 0, outlen); - m_free(outblob); + m_free(outblob); } if (privblob) { memset(privblob, 0, privlen); - m_free(privblob); + m_free(privblob); } if (pubblob) { memset(pubblob, 0, publen); - m_free(pubblob); + m_free(pubblob); } return ret; }
--- a/libtomcrypt/Makefile.in Thu May 18 23:38:30 2017 +0800 +++ b/libtomcrypt/Makefile.in Thu May 18 23:45:10 2017 +0800 @@ -19,7 +19,7 @@ # Compilation flags. Note the += does not write over the user's CFLAGS! # The rest of the flags come from the parent Dropbear makefile -CFLAGS += -c -I$(srcdir)/src/headers/ -I$(srcdir)/../ -DLTC_SOURCE -I$(srcdir)/../libtommath/ +CFLAGS += -c -Isrc/headers/ -I$(srcdir)/src/headers/ -I../ -I$(srcdir)/../ -DLTC_SOURCE -I../libtommath/ -I$(srcdir)/../libtommath/ # additional warnings (newer GCC 3.4 and higher) ifdef GCC_34
--- a/libtommath/Makefile.in Thu May 18 23:38:30 2017 +0800 +++ b/libtommath/Makefile.in Thu May 18 23:45:10 2017 +0800 @@ -9,7 +9,7 @@ srcdir=@srcdir@ # So that libtommath can include Dropbear headers for options and m_burn() -CFLAGS += -I$(srcdir)/../libtomcrypt/src/headers/ -I$(srcdir)/../ +CFLAGS += -I. -I$(srcdir) -I../libtomcrypt/src/headers/ -I$(srcdir)/../libtomcrypt/src/headers/ -I../ -I$(srcdir)/../ ifndef IGNORE_SPEED
--- a/loginrec.c Thu May 18 23:38:30 2017 +0800 +++ b/loginrec.c Thu May 18 23:45:10 2017 +0800 @@ -706,7 +706,7 @@ } (void)lseek(fd, (off_t)(tty * sizeof(struct utmp)), SEEK_SET); - if (atomicio(write, fd, ut, sizeof(*ut)) != sizeof(*ut)) + if (atomicio(vwrite, fd, ut, sizeof(*ut)) != sizeof(*ut)) dropbear_log(LOG_WARNING, "utmp_write_direct: error writing %s: %s", UTMP_FILE, strerror(errno)); @@ -895,7 +895,7 @@ return 0; } if (fstat(fd, &buf) == 0) - if (atomicio(write, fd, ut, sizeof(*ut)) != sizeof(*ut)) { + if (atomicio(vwrite, fd, ut, sizeof(*ut)) != sizeof(*ut)) { ftruncate(fd, buf.st_size); dropbear_log(LOG_WARNING, "wtmp_write: problem writing %s: %s", WTMP_FILE, strerror(errno)); @@ -1062,7 +1062,7 @@ } if (fstat(fd, &buf) == 0) - if (atomicio(write, fd, utx, sizeof(*utx)) != sizeof(*utx)) { + if (atomicio(vwrite, fd, utx, sizeof(*utx)) != sizeof(*utx)) { ftruncate(fd, buf.st_size); dropbear_log(LOG_WARNING, "wtmpx_write: problem writing %s: %s", WTMPX_FILE, strerror(errno)); @@ -1351,7 +1351,7 @@ return(0); /* write the entry */ - if (atomicio(write, fd, &last, sizeof(last)) != sizeof(last)) { + if (atomicio(vwrite, fd, &last, sizeof(last)) != sizeof(last)) { close(fd); dropbear_log(LOG_WARNING, "lastlog_write_filemode: Error writing to %s: %s", LASTLOG_FILE, strerror(errno));
--- a/ltc_prng.c Thu May 18 23:38:30 2017 +0800 +++ b/ltc_prng.c Thu May 18 23:45:10 2017 +0800 @@ -26,7 +26,7 @@ * in the various other functions. */ -#ifdef DROPBEAR_LTC_PRNG +#if DROPBEAR_LTC_PRNG /** Start the PRNG
--- a/ltc_prng.h Thu May 18 23:38:30 2017 +0800 +++ b/ltc_prng.h Thu May 18 23:45:10 2017 +0800 @@ -4,7 +4,7 @@ #include "options.h" #include "includes.h" -#ifdef DROPBEAR_LTC_PRNG +#if DROPBEAR_LTC_PRNG extern const struct ltc_prng_descriptor dropbear_prng_desc;
--- a/netio.c Thu May 18 23:38:30 2017 +0800 +++ b/netio.c Thu May 18 23:45:10 2017 +0800 @@ -53,7 +53,7 @@ struct addrinfo *r; int res = 0; int fastopen = 0; -#ifdef DROPBEAR_CLIENT_TCP_FAST_OPEN +#if DROPBEAR_CLIENT_TCP_FAST_OPEN struct msghdr message; #endif @@ -70,7 +70,7 @@ set_sock_nodelay(c->sock); setnonblocking(c->sock); -#ifdef DROPBEAR_CLIENT_TCP_FAST_OPEN +#if DROPBEAR_CLIENT_TCP_FAST_OPEN fastopen = (c->writequeue != NULL); if (fastopen) { @@ -290,7 +290,7 @@ setsockopt(sock, IPPROTO_TCP, TCP_NODELAY, (void*)&val, sizeof(val)); } -#ifdef DROPBEAR_SERVER_TCP_FAST_OPEN +#if DROPBEAR_SERVER_TCP_FAST_OPEN void set_listen_fast_open(int sock) { int qlen = MAX(MAX_UNAUTH_PER_IP, 5); if (setsockopt(sock, SOL_TCP, TCP_FASTOPEN, &qlen, sizeof(qlen)) != 0) {
--- a/netio.h Thu May 18 23:38:30 2017 +0800 +++ b/netio.h Thu May 18 23:45:10 2017 +0800 @@ -48,7 +48,7 @@ void packet_queue_to_iovec(struct Queue *queue, struct iovec *iov, unsigned int *iov_count); void packet_queue_consume(struct Queue *queue, ssize_t written); -#ifdef DROPBEAR_SERVER_TCP_FAST_OPEN +#if DROPBEAR_SERVER_TCP_FAST_OPEN /* Try for any Linux builds, will fall back if the kernel doesn't support it */ void set_listen_fast_open(int sock); /* Define values which may be supported by the kernel even if the libc is too old */
--- a/options.h Thu May 18 23:38:30 2017 +0800 +++ b/options.h Thu May 18 23:45:10 2017 +0800 @@ -1,356 +1,19 @@ -/* Dropbear SSH - * Copyright (c) 2002,2003 Matt Johnston - * All rights reserved. See LICENSE for the license. */ - -#ifndef DROPBEAR_OPTIONS_H_ -#define DROPBEAR_OPTIONS_H_ - -/* Define compile-time options below - the "#ifndef DROPBEAR_XXX .... #endif" - * parts are to allow for commandline -DDROPBEAR_XXX options etc. */ - -/* IMPORTANT: Many options will require "make clean" after changes */ +#ifndef DROPBEAR_OPTIONS_H +#define DROPBEAR_OPTIONS_H -#ifndef DROPBEAR_DEFPORT -#define DROPBEAR_DEFPORT "22" -#endif - -#ifndef DROPBEAR_DEFADDRESS -/* Listen on all interfaces */ -#define DROPBEAR_DEFADDRESS "" -#endif +/* +Local compile-time configuration should be defined in localoptions.h +See default_options.h.in for a description of the available options. +*/ -/* Default hostkey paths - these can be specified on the command line */ -#ifndef DSS_PRIV_FILENAME -#define DSS_PRIV_FILENAME "/etc/dropbear/dropbear_dss_host_key" -#endif -#ifndef RSA_PRIV_FILENAME -#define RSA_PRIV_FILENAME "/etc/dropbear/dropbear_rsa_host_key" -#endif -#ifndef ECDSA_PRIV_FILENAME -#define ECDSA_PRIV_FILENAME "/etc/dropbear/dropbear_ecdsa_host_key" +#ifdef LOCALOPTIONS_H_EXISTS +#include "localoptions.h" #endif -/* Set NON_INETD_MODE if you require daemon functionality (ie Dropbear listens - * on chosen ports and keeps accepting connections. This is the default. - * - * Set INETD_MODE if you want to be able to run Dropbear with inetd (or - * similar), where it will use stdin/stdout for connections, and each process - * lasts for a single connection. Dropbear should be invoked with the -i flag - * for inetd, and can only accept IPv4 connections. - * - * Both of these flags can be defined at once, don't compile without at least - * one of them. */ -#define NON_INETD_MODE -#define INETD_MODE - -/* Setting this disables the fast exptmod bignum code. It saves ~5kB, but is - * perhaps 20% slower for pubkey operations (it is probably worth experimenting - * 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 and hashes -slower, perhaps by 50%. Recommended for small systems that aren't doing -much traffic. */ -#define DROPBEAR_SMALL_CODE - -/* Enable X11 Forwarding - server only */ -#define ENABLE_X11FWD - -/* Enable TCP Fowarding */ -/* 'Local' is "-L" style (client listening port forwarded via server) - * 'Remote' is "-R" style (server listening port forwarded via client) */ - -#define ENABLE_CLI_LOCALTCPFWD -#define ENABLE_CLI_REMOTETCPFWD - -#define ENABLE_SVR_LOCALTCPFWD -#define ENABLE_SVR_REMOTETCPFWD - -/* Enable Authentication Agent Forwarding */ -#define ENABLE_SVR_AGENTFWD -#define ENABLE_CLI_AGENTFWD - - -/* Note: Both ENABLE_CLI_PROXYCMD and ENABLE_CLI_NETCAT must be set to - * allow multihop dbclient connections */ - -/* Allow using -J <proxycommand> to run the connection through a - pipe to a program, rather the normal TCP connection */ -#define ENABLE_CLI_PROXYCMD - -/* Enable "Netcat mode" option. This will forward standard input/output - * to a remote TCP-forwarded connection */ -#define ENABLE_CLI_NETCAT - -/* Whether to support "-c" and "-m" flags to choose ciphers/MACs at runtime */ -#define ENABLE_USER_ALGO_LIST - -/* Encryption - at least one required. - * Protocol RFC requires 3DES and recommends AES128 for interoperability. - * Including multiple keysize variants the same cipher - * (eg AES256 as well as AES128) will result in a minimal size increase.*/ -#define DROPBEAR_AES128 -#define DROPBEAR_3DES -#define DROPBEAR_AES256 -/* Compiling in Blowfish will add ~6kB to runtime heap memory usage */ -/*#define DROPBEAR_BLOWFISH*/ -#define DROPBEAR_TWOFISH256 -#define DROPBEAR_TWOFISH128 - -/* Enable CBC mode for ciphers. This has security issues though - * is the most compatible with older SSH implementations */ -#define DROPBEAR_ENABLE_CBC_MODE - -/* Enable "Counter Mode" for ciphers. This is more secure than normal - * CBC mode against certain attacks. It is recommended for security - * and forwards compatibility */ -#define DROPBEAR_ENABLE_CTR_MODE - -/* Twofish counter mode is disabled by default because it -has not been tested for interoperability with other SSH implementations. -If you test it please contact the Dropbear author */ -/* #define DROPBEAR_TWOFISH_CTR */ - -/* You can compile with no encryption if you want. In some circumstances - * this could be safe security-wise, though make sure you know what - * you're doing. Anyone can see everything that goes over the wire, so - * the only safe auth method is public key. */ -/* #define DROPBEAR_NONE_CIPHER */ - -/* Message Integrity - at least one required. - * Protocol RFC requires sha1 and recommends sha1-96. - * sha1-96 is of use for slow links as it has a smaller overhead. - * - * There's no reason to disable sha1 or sha1-96 to save space since it's - * used for the random number generator and public-key cryptography anyway. - * Disabling it here will just stop it from being used as the integrity portion - * of the ssh protocol. - * - * These hashes are also used for public key fingerprints in logs. - * If you disable MD5, Dropbear will fall back to SHA1 fingerprints, - * which are not the standard form. */ -#define DROPBEAR_SHA1_HMAC -#define DROPBEAR_SHA1_96_HMAC -#define DROPBEAR_SHA2_256_HMAC -#define DROPBEAR_SHA2_512_HMAC -#define DROPBEAR_MD5_HMAC - -/* You can also disable integrity. Don't bother disabling this if you're - * still using a cipher, it's relatively cheap. If you disable this it's dead - * simple for an attacker to run arbitrary commands on the remote host. Beware. */ -/* #define DROPBEAR_NONE_INTEGRITY */ - -/* Hostkey/public key algorithms - at least one required, these are used - * for hostkey as well as for verifying signatures with pubkey auth. - * Removing either of these won't save very much space. - * SSH2 RFC Draft requires dss, recommends rsa */ -#define DROPBEAR_RSA -#define DROPBEAR_DSS -/* ECDSA is significantly faster than RSA or DSS. Compiling in ECC - * code (either ECDSA or ECDH) increases binary size - around 30kB - * on x86-64 */ -#define DROPBEAR_ECDSA - -/* Generate hostkeys as-needed when the first connection using that key type occurs. - This avoids the need to otherwise run "dropbearkey" and avoids some problems - with badly seeded /dev/urandom when systems first boot. - This also requires a runtime flag "-R". This adds ~4kB to binary size (or hardly - anything if dropbearkey is linked in a "dropbearmulti" binary) */ -#define DROPBEAR_DELAY_HOSTKEY - -/* Enable Curve25519 for key exchange. This is another elliptic - * curve method with good security properties. Increases binary size - * by ~8kB on x86-64 */ -#define DROPBEAR_CURVE25519 - -/* Enable elliptic curve Diffie Hellman key exchange, see note about - * ECDSA above */ -#define DROPBEAR_ECDH - -/* Group14 (2048 bit) is recommended. Group1 is less secure (1024 bit) though - is the only option for interoperability with some older SSH programs */ -#define DROPBEAR_DH_GROUP1 1 -#define DROPBEAR_DH_GROUP14 1 - -/* Control the memory/performance/compression tradeoff for zlib. - * Set windowBits=8 for least memory usage, see your system's - * zlib.h for full details. - * Default settings (windowBits=15) will use 256kB for compression - * windowBits=8 will use 129kB for compression. - * Both modes will use ~35kB for decompression (using windowBits=15 for - * interoperability) */ -#ifndef DROPBEAR_ZLIB_WINDOW_BITS -#define DROPBEAR_ZLIB_WINDOW_BITS 15 -#endif - -/* Server won't allow zlib compression until after authentication. Prevents - flaws in the zlib library being unauthenticated exploitable flaws. - Some old ssh clients may not support the alternative [email protected] method */ -#define DROPBEAR_SERVER_DELAY_ZLIB 1 +#include "default_options.h" -/* Whether to do reverse DNS lookups. */ -/*#define DO_HOST_LOOKUP */ - -/* Whether to print the message of the day (MOTD). This doesn't add much code - * size */ -#define DO_MOTD - -/* The MOTD file path */ -#ifndef MOTD_FILENAME -#define MOTD_FILENAME "/etc/motd" -#endif - -/* Authentication Types - at least one required. - RFC Draft requires pubkey auth, and recommends password */ - -/* Note: PAM auth is quite simple and only works for PAM modules which just do - * a simple "Login: " "Password: " (you can edit the strings in svr-authpam.c). - * It's useful for systems like OS X where standard password crypts don't work - * but there's an interface via a PAM module. It won't work for more complex - * PAM challenge/response. - * You can't enable both PASSWORD and PAM. */ - -/* This requires crypt() */ -#ifdef HAVE_CRYPT -#define ENABLE_SVR_PASSWORD_AUTH -#endif -/* PAM requires ./configure --enable-pam */ -/*#define ENABLE_SVR_PAM_AUTH */ -#define ENABLE_SVR_PUBKEY_AUTH - -/* Whether to take public key options in - * authorized_keys file into account */ -#ifdef ENABLE_SVR_PUBKEY_AUTH -#define ENABLE_SVR_PUBKEY_OPTIONS -#endif - -/* This requires getpass. */ -#ifdef HAVE_GETPASS -#define ENABLE_CLI_PASSWORD_AUTH -#define ENABLE_CLI_INTERACT_AUTH -#endif -#define ENABLE_CLI_PUBKEY_AUTH - -/* A default argument for dbclient -i <privatekey>. -Homedir is prepended unless path begins with / */ -#define DROPBEAR_DEFAULT_CLI_AUTHKEY ".ssh/id_dropbear" - -/* This variable can be used to set a password for client - * authentication on the commandline. Beware of platforms - * that don't protect environment variables of processes etc. Also - * note that it will be provided for all "hidden" client-interactive - * style prompts - if you want something more sophisticated, use - * SSH_ASKPASS instead. Comment out this var to remove this functionality.*/ -#define DROPBEAR_PASSWORD_ENV "DROPBEAR_PASSWORD" - -/* Define this (as well as ENABLE_CLI_PASSWORD_AUTH) to allow the use of - * a helper program for the ssh client. The helper program should be - * specified in the SSH_ASKPASS environment variable, and dbclient - * should be run with DISPLAY set and no tty. The program should - * return the password on standard output */ -/*#define ENABLE_CLI_ASKPASS_HELPER*/ - -/* Save a network roundtrip by sendng a real auth request immediately after - * sending a query for the available methods. It is at the expense of < 100 - * bytes of extra network traffic. This is not yet enabled by default since it - * could cause problems with non-compliant servers */ -/* #define DROPBEAR_CLI_IMMEDIATE_AUTH */ - -/* Source for randomness. This must be able to provide hundreds of bytes per SSH - * connection without blocking. In addition /dev/random is used for seeding - * rsa/dss key generation */ -#define DROPBEAR_URANDOM_DEV "/dev/urandom" - -/* Set this to use PRNGD or EGD instead of /dev/urandom or /dev/random */ -/*#define DROPBEAR_PRNGD_SOCKET "/var/run/dropbear-rng"*/ - - -/* Specify the number of clients we will allow to be connected but - * not yet authenticated. After this limit, connections are rejected */ -/* The first setting is per-IP, to avoid denial of service */ -#ifndef MAX_UNAUTH_PER_IP -#define MAX_UNAUTH_PER_IP 5 -#endif - -/* And then a global limit to avoid chewing memory if connections - * come from many IPs */ -#ifndef MAX_UNAUTH_CLIENTS -#define MAX_UNAUTH_CLIENTS 30 -#endif - -/* Maximum number of failed authentication tries (server option) */ -#ifndef MAX_AUTH_TRIES -#define MAX_AUTH_TRIES 10 -#endif - -/* The default file to store the daemon's process ID, for shutdown - scripts etc. This can be overridden with the -P flag */ -#ifndef DROPBEAR_PIDFILE -#define DROPBEAR_PIDFILE "/var/run/dropbear.pid" -#endif - -/* The command to invoke for xauth when using X11 forwarding. - * "-q" for quiet */ -#ifndef XAUTH_COMMAND -#define XAUTH_COMMAND "/usr/bin/xauth -q" -#endif - -/* if you want to enable running an sftp server (such as the one included with - * OpenSSH), set the path below. If the path isn't defined, sftp will not - * be enabled */ -#ifndef SFTPSERVER_PATH -#define SFTPSERVER_PATH "/usr/libexec/sftp-server" -#endif - -/* This is used by the scp binary when used as a client binary. If you're - * not using the Dropbear client, you'll need to change it */ -#define DROPBEAR_PATH_SSH_PROGRAM "/usr/bin/dbclient" - -/* Whether to log commands executed by a client. This only logs the - * (single) command sent to the server, not what a user did in a - * shell/sftp session etc. */ -/* #define LOG_COMMANDS */ - -/* Window size limits. These tend to be a trade-off between memory - usage and network performance: */ -/* Size of the network receive window. This amount of memory is allocated - as a per-channel receive buffer. Increasing this value can make a - significant difference to network performance. 24kB was empirically - chosen for a 100mbit ethernet network. The value can be altered at - runtime with the -W argument. */ -#ifndef DEFAULT_RECV_WINDOW -#define DEFAULT_RECV_WINDOW 24576 -#endif -/* Maximum size of a received SSH data packet - this _MUST_ be >= 32768 - in order to interoperate with other implementations */ -#ifndef RECV_MAX_PAYLOAD_LEN -#define RECV_MAX_PAYLOAD_LEN 32768 -#endif -/* Maximum size of a transmitted data packet - this can be any value, - though increasing it may not make a significant difference. */ -#ifndef TRANS_MAX_PAYLOAD_LEN -#define TRANS_MAX_PAYLOAD_LEN 16384 -#endif - -/* Ensure that data is transmitted every KEEPALIVE seconds. This can -be overridden at runtime with -K. 0 disables keepalives */ -#define DEFAULT_KEEPALIVE 0 - -/* If this many KEEPALIVES are sent with no packets received from the -other side, exit. Not run-time configurable - if you have a need -for runtime configuration please mail the Dropbear list */ -#define DEFAULT_KEEPALIVE_LIMIT 3 - -/* Ensure that data is received within IDLE_TIMEOUT seconds. This can -be overridden at runtime with -I. 0 disables idle timeouts */ -#define DEFAULT_IDLE_TIMEOUT 0 - -/* The default path. This will often get replaced by the shell */ -#define DEFAULT_PATH "/usr/bin:/bin" - -/* Some other defines (that mostly should be left alone) are defined +/* Some other defines that mostly should be left alone are defined * in sysoptions.h */ #include "sysoptions.h" -#endif /* DROPBEAR_OPTIONS_H_ */ +#endif /* DROPBEAR_OPTIONS_H */
--- a/rsa.c Thu May 18 23:38:30 2017 +0800 +++ b/rsa.c Thu May 18 23:45:10 2017 +0800 @@ -36,7 +36,7 @@ #include "ssh.h" #include "dbrandom.h" -#ifdef DROPBEAR_RSA +#if DROPBEAR_RSA static void rsa_pad_em(dropbear_rsa_key * key, buffer *data_buf, mp_int * rsa_em); @@ -204,7 +204,7 @@ } -#ifdef DROPBEAR_SIGNKEY_VERIFY +#if DROPBEAR_SIGNKEY_VERIFY /* Verify a signature in buf, made on data by the key given. * Returns DROPBEAR_SUCCESS or DROPBEAR_FAILURE */ int buf_rsa_verify(buffer * buf, dropbear_rsa_key *key, buffer *data_buf) { @@ -279,7 +279,7 @@ /* the actual signing of the padded data */ -#ifdef RSA_BLINDING +#if DROPBEAR_RSA_BLINDING /* With blinding, s = (r^(-1))((em)*r^e)^d mod n */ @@ -322,7 +322,7 @@ dropbear_exit("RSA error"); } -#endif /* RSA_BLINDING */ +#endif /* DROPBEAR_RSA_BLINDING */ mp_clear_multi(&rsa_tmp1, &rsa_tmp2, &rsa_tmp3, NULL);
--- a/rsa.h Thu May 18 23:38:30 2017 +0800 +++ b/rsa.h Thu May 18 23:45:10 2017 +0800 @@ -28,7 +28,7 @@ #include "includes.h" #include "buffer.h" -#ifdef DROPBEAR_RSA +#if DROPBEAR_RSA #define RSA_SIGNATURE_SIZE (4+7+4+40) @@ -44,7 +44,7 @@ } dropbear_rsa_key; void buf_put_rsa_sign(buffer* buf, dropbear_rsa_key *key, buffer *data_buf); -#ifdef DROPBEAR_SIGNKEY_VERIFY +#if DROPBEAR_SIGNKEY_VERIFY int buf_rsa_verify(buffer * buf, dropbear_rsa_key *key, buffer *data_buf); #endif int buf_get_rsa_pub_key(buffer* buf, dropbear_rsa_key *key);
--- a/runopts.h Thu May 18 23:38:30 2017 +0800 +++ b/runopts.h Thu May 18 23:45:10 2017 +0800 @@ -33,8 +33,8 @@ typedef struct runopts { -#if defined(ENABLE_SVR_REMOTETCPFWD) || defined(ENABLE_CLI_LOCALTCPFWD) \ - || defined(ENABLE_CLI_REMOTETCPFWD) +#if DROPBEAR_SVR_REMOTETCPFWD || DROPBEAR_CLI_LOCALTCPFWD \ + || DROPBEAR_CLI_REMOTETCPFWD int listen_fwd_all; #endif unsigned int recv_window; @@ -53,7 +53,7 @@ } compress_mode; #endif -#ifdef ENABLE_USER_ALGO_LIST +#if DROPBEAR_USER_ALGO_LIST char *cipher_list; char *mac_list; #endif @@ -97,10 +97,10 @@ int norootpass; int allowblankpass; -#ifdef ENABLE_SVR_REMOTETCPFWD +#if DROPBEAR_SVR_REMOTETCPFWD int noremotetcp; #endif -#ifdef ENABLE_SVR_LOCALTCPFWD +#if DROPBEAR_SVR_LOCALTCPFWD int nolocaltcp; #endif @@ -114,6 +114,8 @@ buffer * banner; char * pidfile; + char * forced_command; + } svr_runopts; extern svr_runopts svr_opts; @@ -137,19 +139,19 @@ int no_cmd; int backgrounded; int is_subsystem; -#ifdef ENABLE_CLI_PUBKEY_AUTH +#if DROPBEAR_CLI_PUBKEY_AUTH m_list *privkeys; /* Keys to use for public-key auth */ #endif -#ifdef ENABLE_CLI_ANYTCPFWD +#if DROPBEAR_CLI_ANYTCPFWD int exit_on_fwd_failure; #endif -#ifdef ENABLE_CLI_REMOTETCPFWD +#if DROPBEAR_CLI_REMOTETCPFWD m_list * remotefwds; #endif -#ifdef ENABLE_CLI_LOCALTCPFWD +#if DROPBEAR_CLI_LOCALTCPFWD m_list * localfwds; #endif -#ifdef ENABLE_CLI_AGENTFWD +#if DROPBEAR_CLI_AGENTFWD int agent_fwd; int agent_keys_loaded; /* whether pubkeys has been populated with a list of keys held by the agent */ @@ -157,11 +159,11 @@ agent sessions have their own file descriptors */ #endif -#ifdef ENABLE_CLI_NETCAT +#if DROPBEAR_CLI_NETCAT char *netcat_host; unsigned int netcat_port; #endif -#ifdef ENABLE_CLI_PROXYCMD +#if DROPBEAR_CLI_PROXYCMD char *proxycmd; #endif } cli_runopts; @@ -169,7 +171,7 @@ extern cli_runopts cli_opts; void cli_getopts(int argc, char ** argv); -#ifdef ENABLE_USER_ALGO_LIST +#if DROPBEAR_USER_ALGO_LIST void parse_ciphers_macs(void); #endif
--- a/scp.c Thu May 18 23:38:30 2017 +0800 +++ b/scp.c Thu May 18 23:45:10 2017 +0800 @@ -133,7 +133,7 @@ fprintf(stderr, " %s", a->list[i]); fprintf(stderr, "\n"); } -#ifdef USE_VFORK +#if DROPBEAR_VFORK pid = vfork(); #else pid = fork(); @@ -144,7 +144,7 @@ if (pid == 0) { execvp(a->list[0], a->list); perror(a->list[0]); -#ifdef USE_VFORK +#if DROPBEAR_VFORK _exit(1); #else exit(1); @@ -213,12 +213,12 @@ /* uClinux needs to build the args here before vforking, otherwise we do it later on. */ -#ifdef USE_VFORK +#if DROPBEAR_VFORK arg_setup(host, remuser, cmd); #endif /* Fork a child to execute the command on the remote host using ssh. */ -#ifdef USE_VFORK +#if DROPBEAR_VFORK do_cmd_pid = vfork(); #else do_cmd_pid = fork(); @@ -233,13 +233,13 @@ close(pin[0]); close(pout[1]); -#ifndef USE_VFORK +#if !DROPBEAR_VFORK arg_setup(host, remuser, cmd); #endif execvp(ssh_program, args.list); perror(ssh_program); -#ifdef USE_VFORK +#if DROPBEAR_VFORK _exit(1); #else exit(1); @@ -248,7 +248,7 @@ fatal("fork: %s", strerror(errno)); } -#ifdef USE_VFORK +#if DROPBEAR_VFORK /* clean up command */ /* pop cmd */ xfree(args.list[args.num-1]); @@ -304,8 +304,8 @@ void toremote(char *, int, char *[]); void usage(void); -#if defined(DBMULTI_scp) || !defined(DROPBEAR_MULTI) -#if defined(DBMULTI_scp) && defined(DROPBEAR_MULTI) +#if defined(DBMULTI_scp) || !DROPBEAR_MULTI +#if defined(DBMULTI_scp) && DROPBEAR_MULTI int scp_main(int argc, char **argv) #else int
--- a/scpmisc.h Thu May 18 23:38:30 2017 +0800 +++ b/scpmisc.h Thu May 18 23:45:10 2017 +0800 @@ -12,9 +12,6 @@ * called by a name other than "ssh" or "Secure Shell". */ -/* actually from atomicio, but is only used in scp code */ -#define vwrite (ssize_t (*)(int, void *, size_t))write - char *chop(char *); char *strdelim(char **); void set_nonblock(int);
--- a/session.h Thu May 18 23:38:30 2017 +0800 +++ b/session.h Thu May 18 23:45:10 2017 +0800 @@ -79,7 +79,7 @@ /* actual keys */ union { symmetric_CBC cbc; -#ifdef DROPBEAR_ENABLE_CTR_MODE +#if DROPBEAR_ENABLE_CTR_MODE symmetric_CTR ctr; #endif } cipher_state; @@ -237,7 +237,7 @@ /* The resolved remote address, used for lastlog etc */ char *remotehost; -#ifdef USE_VFORK +#if DROPBEAR_VFORK pid_t server_pid; #endif @@ -288,7 +288,7 @@ int lastauthtype; /* either AUTH_TYPE_PUBKEY or AUTH_TYPE_PASSWORD, for the last type of auth we tried */ int ignore_next_auth_response; -#ifdef ENABLE_CLI_INTERACT_AUTH +#if DROPBEAR_CLI_INTERACT_AUTH int auth_interact_failed; /* flag whether interactive auth can still be used */ int interact_request_received; /* flag whether we've received an @@ -311,11 +311,11 @@ /* Global structs storing the state */ extern struct sshsession ses; -#ifdef DROPBEAR_SERVER +#if DROPBEAR_SERVER extern struct serversession svr_ses; #endif /* DROPBEAR_SERVER */ -#ifdef DROPBEAR_CLIENT +#if DROPBEAR_CLIENT extern struct clientsession cli_ses; #endif /* DROPBEAR_CLIENT */
--- a/signkey.c Thu May 18 23:38:30 2017 +0800 +++ b/signkey.c Thu May 18 23:45:10 2017 +0800 @@ -30,13 +30,13 @@ #include "ecdsa.h" static const char * const signkey_names[DROPBEAR_SIGNKEY_NUM_NAMED] = { -#ifdef DROPBEAR_RSA +#if DROPBEAR_RSA "ssh-rsa", #endif -#ifdef DROPBEAR_DSS +#if DROPBEAR_DSS "ssh-dss", #endif -#ifdef DROPBEAR_ECDSA +#if DROPBEAR_ECDSA "ecdsa-sha2-nistp256", "ecdsa-sha2-nistp384", "ecdsa-sha2-nistp521" @@ -75,7 +75,7 @@ if (namelen == strlen(fixed_name) && memcmp(fixed_name, name, namelen) == 0) { -#ifdef DROPBEAR_ECDSA +#if DROPBEAR_ECDSA /* Some of the ECDSA key sizes are defined even if they're not compiled in */ if (0 #ifndef DROPBEAR_ECC_256 @@ -106,25 +106,25 @@ void ** signkey_key_ptr(sign_key *key, enum signkey_type type) { switch (type) { -#ifdef DROPBEAR_ECDSA -#ifdef DROPBEAR_ECC_256 +#if DROPBEAR_ECDSA +#if DROPBEAR_ECC_256 case DROPBEAR_SIGNKEY_ECDSA_NISTP256: return (void**)&key->ecckey256; #endif -#ifdef DROPBEAR_ECC_384 +#if DROPBEAR_ECC_384 case DROPBEAR_SIGNKEY_ECDSA_NISTP384: return (void**)&key->ecckey384; #endif -#ifdef DROPBEAR_ECC_521 +#if DROPBEAR_ECC_521 case DROPBEAR_SIGNKEY_ECDSA_NISTP521: return (void**)&key->ecckey521; #endif #endif /* DROPBEAR_ECDSA */ -#ifdef DROPBEAR_RSA +#if DROPBEAR_RSA case DROPBEAR_SIGNKEY_RSA: return (void**)&key->rsakey; #endif -#ifdef DROPBEAR_DSS +#if DROPBEAR_DSS case DROPBEAR_SIGNKEY_DSS: return (void**)&key->dsskey; #endif @@ -161,7 +161,7 @@ /* Rewind the buffer back before "ssh-rsa" etc */ buf_incrpos(buf, -len - 4); -#ifdef DROPBEAR_DSS +#if DROPBEAR_DSS if (keytype == DROPBEAR_SIGNKEY_DSS) { dss_key_free(key->dsskey); key->dsskey = m_malloc(sizeof(*key->dsskey)); @@ -171,7 +171,7 @@ } } #endif -#ifdef DROPBEAR_RSA +#if DROPBEAR_RSA if (keytype == DROPBEAR_SIGNKEY_RSA) { rsa_key_free(key->rsakey); key->rsakey = m_malloc(sizeof(*key->rsakey)); @@ -181,7 +181,7 @@ } } #endif -#ifdef DROPBEAR_ECDSA +#if DROPBEAR_ECDSA if (signkey_is_ecdsa(keytype)) { ecc_key **eck = (ecc_key**)signkey_key_ptr(key, keytype); if (eck) { @@ -230,7 +230,7 @@ /* Rewind the buffer back before "ssh-rsa" etc */ buf_incrpos(buf, -len - 4); -#ifdef DROPBEAR_DSS +#if DROPBEAR_DSS if (keytype == DROPBEAR_SIGNKEY_DSS) { dss_key_free(key->dsskey); key->dsskey = m_malloc(sizeof(*key->dsskey)); @@ -240,7 +240,7 @@ } } #endif -#ifdef DROPBEAR_RSA +#if DROPBEAR_RSA if (keytype == DROPBEAR_SIGNKEY_RSA) { rsa_key_free(key->rsakey); key->rsakey = m_malloc(sizeof(*key->rsakey)); @@ -250,7 +250,7 @@ } } #endif -#ifdef DROPBEAR_ECDSA +#if DROPBEAR_ECDSA if (signkey_is_ecdsa(keytype)) { ecc_key **eck = (ecc_key**)signkey_key_ptr(key, keytype); if (eck) { @@ -281,17 +281,17 @@ TRACE2(("enter buf_put_pub_key")) pubkeys = buf_new(MAX_PUBKEY_SIZE); -#ifdef DROPBEAR_DSS +#if DROPBEAR_DSS if (type == DROPBEAR_SIGNKEY_DSS) { buf_put_dss_pub_key(pubkeys, key->dsskey); } #endif -#ifdef DROPBEAR_RSA +#if DROPBEAR_RSA if (type == DROPBEAR_SIGNKEY_RSA) { buf_put_rsa_pub_key(pubkeys, key->rsakey); } #endif -#ifdef DROPBEAR_ECDSA +#if DROPBEAR_ECDSA if (signkey_is_ecdsa(type)) { ecc_key **eck = (ecc_key**)signkey_key_ptr(key, type); if (eck) { @@ -314,21 +314,21 @@ TRACE(("enter buf_put_priv_key")) TRACE(("type is %d", type)) -#ifdef DROPBEAR_DSS +#if DROPBEAR_DSS if (type == DROPBEAR_SIGNKEY_DSS) { buf_put_dss_priv_key(buf, key->dsskey); TRACE(("leave buf_put_priv_key: dss done")) return; } #endif -#ifdef DROPBEAR_RSA +#if DROPBEAR_RSA if (type == DROPBEAR_SIGNKEY_RSA) { buf_put_rsa_priv_key(buf, key->rsakey); TRACE(("leave buf_put_priv_key: rsa done")) return; } #endif -#ifdef DROPBEAR_ECDSA +#if DROPBEAR_ECDSA if (signkey_is_ecdsa(type)) { ecc_key **eck = (ecc_key**)signkey_key_ptr(key, type); if (eck) { @@ -345,30 +345,30 @@ TRACE2(("enter sign_key_free")) -#ifdef DROPBEAR_DSS +#if DROPBEAR_DSS dss_key_free(key->dsskey); key->dsskey = NULL; #endif -#ifdef DROPBEAR_RSA +#if DROPBEAR_RSA rsa_key_free(key->rsakey); key->rsakey = NULL; #endif -#ifdef DROPBEAR_ECDSA -#ifdef DROPBEAR_ECC_256 +#if DROPBEAR_ECDSA +#if DROPBEAR_ECC_256 if (key->ecckey256) { ecc_free(key->ecckey256); m_free(key->ecckey256); key->ecckey256 = NULL; } #endif -#ifdef DROPBEAR_ECC_384 +#if DROPBEAR_ECC_384 if (key->ecckey384) { ecc_free(key->ecckey384); m_free(key->ecckey384); key->ecckey384 = NULL; } #endif -#ifdef DROPBEAR_ECC_521 +#if DROPBEAR_ECC_521 if (key->ecckey521) { ecc_free(key->ecckey521); m_free(key->ecckey521); @@ -395,7 +395,7 @@ /* Since we're not sure if we'll have md5 or sha1, we present both. * MD5 is used in preference, but sha1 could still be useful */ -#ifdef DROPBEAR_MD5_HMAC +#if DROPBEAR_MD5_HMAC static char * sign_key_md5_fingerprint(unsigned char* keyblob, unsigned int keybloblen) { @@ -470,7 +470,7 @@ * in either sha1 or md5 */ char * sign_key_fingerprint(unsigned char* keyblob, unsigned int keybloblen) { -#ifdef DROPBEAR_MD5_HMAC +#if DROPBEAR_MD5_HMAC return sign_key_md5_fingerprint(keyblob, keybloblen); #else return sign_key_sha1_fingerprint(keyblob, keybloblen); @@ -482,17 +482,17 @@ buffer *sigblob; sigblob = buf_new(MAX_PUBKEY_SIZE); -#ifdef DROPBEAR_DSS +#if DROPBEAR_DSS if (type == DROPBEAR_SIGNKEY_DSS) { buf_put_dss_sign(sigblob, key->dsskey, data_buf); } #endif -#ifdef DROPBEAR_RSA +#if DROPBEAR_RSA if (type == DROPBEAR_SIGNKEY_RSA) { buf_put_rsa_sign(sigblob, key->rsakey, data_buf); } #endif -#ifdef DROPBEAR_ECDSA +#if DROPBEAR_ECDSA if (signkey_is_ecdsa(type)) { ecc_key **eck = (ecc_key**)signkey_key_ptr(key, type); if (eck) { @@ -508,7 +508,7 @@ } -#ifdef DROPBEAR_SIGNKEY_VERIFY +#if DROPBEAR_SIGNKEY_VERIFY /* Return DROPBEAR_SUCCESS or DROPBEAR_FAILURE. * If FAILURE is returned, the position of * buf is undefined. If SUCCESS is returned, buf will be positioned after the @@ -526,7 +526,7 @@ type = signkey_type_from_name(type_name, type_name_len); m_free(type_name); -#ifdef DROPBEAR_DSS +#if DROPBEAR_DSS if (type == DROPBEAR_SIGNKEY_DSS) { if (key->dsskey == NULL) { dropbear_exit("No DSS key to verify signature"); @@ -535,7 +535,7 @@ } #endif -#ifdef DROPBEAR_RSA +#if DROPBEAR_RSA if (type == DROPBEAR_SIGNKEY_RSA) { if (key->rsakey == NULL) { dropbear_exit("No RSA key to verify signature"); @@ -543,7 +543,7 @@ return buf_rsa_verify(buf, key->rsakey, data_buf); } #endif -#ifdef DROPBEAR_ECDSA +#if DROPBEAR_ECDSA if (signkey_is_ecdsa(type)) { ecc_key **eck = (ecc_key**)signkey_key_ptr(key, type); if (eck) { @@ -557,7 +557,7 @@ } #endif /* DROPBEAR_SIGNKEY_VERIFY */ -#ifdef DROPBEAR_KEY_LINES /* ie we're using authorized_keys or known_hosts */ +#if DROPBEAR_KEY_LINES /* ie we're using authorized_keys or known_hosts */ /* Returns DROPBEAR_SUCCESS or DROPBEAR_FAILURE when given a buffer containing * a key, a key, and a type. The buffer is positioned at the start of the
--- a/signkey.h Thu May 18 23:38:30 2017 +0800 +++ b/signkey.h Thu May 18 23:45:10 2017 +0800 @@ -30,13 +30,13 @@ #include "rsa.h" enum signkey_type { -#ifdef DROPBEAR_RSA +#if DROPBEAR_RSA DROPBEAR_SIGNKEY_RSA, #endif -#ifdef DROPBEAR_DSS +#if DROPBEAR_DSS DROPBEAR_SIGNKEY_DSS, #endif -#ifdef DROPBEAR_ECDSA +#if DROPBEAR_ECDSA DROPBEAR_SIGNKEY_ECDSA_NISTP256, DROPBEAR_SIGNKEY_ECDSA_NISTP384, DROPBEAR_SIGNKEY_ECDSA_NISTP521, @@ -61,20 +61,20 @@ signkey_source source; char *filename; -#ifdef DROPBEAR_DSS +#if DROPBEAR_DSS dropbear_dss_key * dsskey; #endif -#ifdef DROPBEAR_RSA +#if DROPBEAR_RSA dropbear_rsa_key * rsakey; #endif -#ifdef DROPBEAR_ECDSA -#ifdef DROPBEAR_ECC_256 +#if DROPBEAR_ECDSA +#if DROPBEAR_ECC_256 ecc_key * ecckey256; #endif -#ifdef DROPBEAR_ECC_384 +#if DROPBEAR_ECC_384 ecc_key * ecckey384; #endif -#ifdef DROPBEAR_ECC_521 +#if DROPBEAR_ECC_521 ecc_key * ecckey521; #endif #endif @@ -91,7 +91,7 @@ void buf_put_priv_key(buffer* buf, sign_key *key, enum signkey_type type); void sign_key_free(sign_key *key); void buf_put_sign(buffer* buf, sign_key *key, enum signkey_type type, buffer *data_buf); -#ifdef DROPBEAR_SIGNKEY_VERIFY +#if DROPBEAR_SIGNKEY_VERIFY int buf_verify(buffer * buf, sign_key *key, buffer *data_buf); char * sign_key_fingerprint(unsigned char* keyblob, unsigned int keybloblen); #endif
--- a/svr-agentfwd.c Thu May 18 23:38:30 2017 +0800 +++ b/svr-agentfwd.c Thu May 18 23:45:10 2017 +0800 @@ -27,7 +27,7 @@ #include "includes.h" -#ifdef ENABLE_SVR_AGENTFWD +#if DROPBEAR_SVR_AGENTFWD #include "agentfwd.h" #include "session.h"
--- a/svr-auth.c Thu May 18 23:38:30 2017 +0800 +++ b/svr-auth.c Thu May 18 23:45:10 2017 +0800 @@ -56,10 +56,10 @@ static void authclear() { memset(&ses.authstate, 0, sizeof(ses.authstate)); -#ifdef ENABLE_SVR_PUBKEY_AUTH +#if DROPBEAR_SVR_PUBKEY_AUTH ses.authstate.authtypes |= AUTH_TYPE_PUBKEY; #endif -#if defined(ENABLE_SVR_PASSWORD_AUTH) || defined(ENABLE_SVR_PAM_AUTH) +#if DROPBEAR_SVR_PASSWORD_AUTH || DROPBEAR_SVR_PAM_AUTH if (!svr_opts.noauthpass) { ses.authstate.authtypes |= AUTH_TYPE_PASSWORD; } @@ -169,7 +169,7 @@ } } -#ifdef ENABLE_SVR_PASSWORD_AUTH +#if DROPBEAR_SVR_PASSWORD_AUTH if (!svr_opts.noauthpass && !(svr_opts.norootpass && ses.authstate.pw_uid == 0) ) { /* user wants to try password auth */ @@ -184,7 +184,7 @@ } #endif -#ifdef ENABLE_SVR_PAM_AUTH +#if DROPBEAR_SVR_PAM_AUTH if (!svr_opts.noauthpass && !(svr_opts.norootpass && ses.authstate.pw_uid == 0) ) { /* user wants to try password auth */ @@ -199,7 +199,7 @@ } #endif -#ifdef ENABLE_SVR_PUBKEY_AUTH +#if DROPBEAR_SVR_PUBKEY_AUTH /* user wants to try pubkey auth */ if (methodlen == AUTH_METHOD_PUBKEY_LEN && strncmp(methodname, AUTH_METHOD_PUBKEY,
--- a/svr-authpam.c Thu May 18 23:38:30 2017 +0800 +++ b/svr-authpam.c Thu May 18 23:45:10 2017 +0800 @@ -31,7 +31,7 @@ #include "dbutil.h" #include "auth.h" -#ifdef ENABLE_SVR_PAM_AUTH +#if DROPBEAR_SVR_PAM_AUTH #if defined(HAVE_SECURITY_PAM_APPL_H) #include <security/pam_appl.h> @@ -270,4 +270,4 @@ } } -#endif /* ENABLE_SVR_PAM_AUTH */ +#endif /* DROPBEAR_SVR_PAM_AUTH */
--- a/svr-authpasswd.c Thu May 18 23:38:30 2017 +0800 +++ b/svr-authpasswd.c Thu May 18 23:45:10 2017 +0800 @@ -31,7 +31,7 @@ #include "auth.h" #include "runopts.h" -#ifdef ENABLE_SVR_PASSWORD_AUTH +#if DROPBEAR_SVR_PASSWORD_AUTH /* not constant time when strings are differing lengths. string content isn't leaked, and crypt hashes are predictable length. */
--- a/svr-authpubkey.c Thu May 18 23:38:30 2017 +0800 +++ b/svr-authpubkey.c Thu May 18 23:45:10 2017 +0800 @@ -65,7 +65,7 @@ #include "packet.h" #include "algo.h" -#ifdef ENABLE_SVR_PUBKEY_AUTH +#if DROPBEAR_SVR_PUBKEY_AUTH #define MIN_AUTHKEYS_LINE 10 /* "ssh-rsa AB" - short but doesn't matter */ #define MAX_AUTHKEYS_LINE 4200 /* max length of a line in authkeys */ @@ -201,6 +201,8 @@ unsigned int len, pos; buffer * options_buf = NULL; int line_num; + uid_t origuid; + gid_t origgid; TRACE(("enter checkpubkey")) @@ -227,8 +229,21 @@ snprintf(filename, len + 22, "%s/.ssh/authorized_keys", ses.authstate.pw_dir); - /* open the file */ + /* open the file as the authenticating user. */ + origuid = getuid(); + origgid = getgid(); + if ((setegid(ses.authstate.pw_gid)) < 0 || + (seteuid(ses.authstate.pw_uid)) < 0) { + dropbear_exit("Failed to set euid"); + } + authfile = fopen(filename, "r"); + + if ((seteuid(origuid)) < 0 || + (setegid(origgid)) < 0) { + dropbear_exit("Failed to revert euid"); + } + if (authfile == NULL) { goto out; }
--- a/svr-authpubkeyoptions.c Thu May 18 23:38:30 2017 +0800 +++ b/svr-authpubkeyoptions.c Thu May 18 23:45:10 2017 +0800 @@ -47,7 +47,7 @@ #include "signkey.h" #include "auth.h" -#ifdef ENABLE_SVR_PUBKEY_OPTIONS +#if DROPBEAR_SVR_PUBKEY_OPTIONS_BUILT /* Returns 1 if pubkey allows agent forwarding, * 0 otherwise */ @@ -95,6 +95,7 @@ if (chansess->cmd) { /* original_command takes ownership */ chansess->original_command = chansess->cmd; + chansess->cmd = NULL; } else { chansess->original_command = m_strdup(""); } @@ -108,6 +109,9 @@ /* Free potential public key options */ void svr_pubkey_options_cleanup() { if (ses.authstate.pubkey_options) { + if (ses.authstate.pubkey_options->forced_command) { + m_free(ses.authstate.pubkey_options->forced_command); + } m_free(ses.authstate.pubkey_options); ses.authstate.pubkey_options = NULL; } @@ -143,14 +147,14 @@ ses.authstate.pubkey_options->no_port_forwarding_flag = 1; goto next_option; } -#ifdef ENABLE_SVR_AGENTFWD +#if DROPBEAR_SVR_AGENTFWD if (match_option(options_buf, "no-agent-forwarding") == DROPBEAR_SUCCESS) { dropbear_log(LOG_WARNING, "Agent forwarding disabled."); ses.authstate.pubkey_options->no_agent_forwarding_flag = 1; goto next_option; } #endif -#ifdef ENABLE_X11FWD +#if DROPBEAR_X11FWD if (match_option(options_buf, "no-X11-forwarding") == DROPBEAR_SUCCESS) { dropbear_log(LOG_WARNING, "X11 forwarding disabled."); ses.authstate.pubkey_options->no_x11_forwarding_flag = 1; @@ -200,8 +204,7 @@ bad_option: ret = DROPBEAR_FAILURE; - m_free(ses.authstate.pubkey_options); - ses.authstate.pubkey_options = NULL; + svr_pubkey_options_cleanup(); dropbear_log(LOG_WARNING, "Bad public key options at %s:%d", filename, line_num); end:
--- a/svr-chansession.c Thu May 18 23:38:30 2017 +0800 +++ b/svr-chansession.c Thu May 18 23:45:10 2017 +0800 @@ -254,13 +254,13 @@ channel->typedata = chansess; -#ifndef DISABLE_X11FWD +#if DROPBEAR_X11FWD chansess->x11listener = NULL; chansess->x11authprot = NULL; chansess->x11authcookie = NULL; #endif -#ifdef ENABLE_SVR_AGENTFWD +#if DROPBEAR_SVR_AGENTFWD chansess->agentlistener = NULL; chansess->agentfile = NULL; chansess->agentdir = NULL; @@ -301,7 +301,7 @@ m_free(chansess->cmd); m_free(chansess->term); -#ifdef ENABLE_SVR_PUBKEY_OPTIONS +#if DROPBEAR_SVR_PUBKEY_OPTIONS_BUILT m_free(chansess->original_command); #endif @@ -315,11 +315,11 @@ m_free(chansess->tty); } -#ifndef DISABLE_X11FWD +#if DROPBEAR_X11FWD x11cleanup(chansess); #endif -#ifdef ENABLE_SVR_AGENTFWD +#if DROPBEAR_SVR_AGENTFWD svr_agentcleanup(chansess); #endif @@ -373,11 +373,11 @@ ret = sessioncommand(channel, chansess, 1, 0); } else if (strcmp(type, "subsystem") == 0) { ret = sessioncommand(channel, chansess, 1, 1); -#ifndef DISABLE_X11FWD +#if DROPBEAR_X11FWD } else if (strcmp(type, "x11-req") == 0) { ret = x11req(chansess); #endif -#ifdef ENABLE_SVR_AGENTFWD +#if DROPBEAR_SVR_AGENTFWD } else if (strcmp(type, "[email protected]") == 0) { ret = svr_agentreq(chansess); #endif @@ -603,7 +603,7 @@ return DROPBEAR_SUCCESS; } -#ifndef USE_VFORK +#if !DROPBEAR_VFORK static void make_connection_string(struct ChanSess *chansess) { char *local_ip, *local_port, *remote_ip, *remote_port; size_t len; @@ -634,7 +634,7 @@ static int sessioncommand(struct Channel *channel, struct ChanSess *chansess, int iscmd, int issubsys) { - unsigned int cmdlen; + unsigned int cmdlen = 0; int ret; TRACE(("enter sessioncommand")) @@ -671,8 +671,16 @@ } } - /* take public key option 'command' into account */ - svr_pubkey_set_forced_command(chansess); + + /* take global command into account */ + if (svr_opts.forced_command) { + chansess->original_command = chansess->cmd ? : m_strdup(""); + chansess->cmd = m_strdup(svr_opts.forced_command); + } else { + /* take public key option 'command' into account */ + svr_pubkey_set_forced_command(chansess); + } + #ifdef LOG_COMMANDS if (chansess->cmd) { @@ -686,7 +694,7 @@ /* uClinux will vfork(), so there'll be a race as connection_string is freed below. */ -#ifndef USE_VFORK +#if !DROPBEAR_VFORK make_connection_string(chansess); #endif @@ -702,7 +710,7 @@ ret = ptycommand(channel, chansess); } -#ifndef USE_VFORK +#if !DROPBEAR_VFORK m_free(chansess->connection_string); m_free(chansess->client_string); #endif @@ -776,7 +784,7 @@ return DROPBEAR_FAILURE; } -#ifdef USE_VFORK +#if DROPBEAR_VFORK pid = vfork(); #else pid = fork(); @@ -896,7 +904,7 @@ /* with uClinux we'll have vfork()ed, so don't want to overwrite the * hostkey. can't think of a workaround to clear it */ -#ifndef USE_VFORK +#if !DROPBEAR_VFORK /* wipe the hostkey */ sign_key_free(svr_opts.hostkey); svr_opts.hostkey = NULL; @@ -965,7 +973,7 @@ addnewvar("SSH_CLIENT", chansess->client_string); } -#ifdef ENABLE_SVR_PUBKEY_OPTIONS +#if DROPBEAR_SVR_PUBKEY_OPTIONS_BUILT if (chansess->original_command) { addnewvar("SSH_ORIGINAL_COMMAND", chansess->original_command); } @@ -976,11 +984,11 @@ dropbear_exit("Error changing directory"); } -#ifndef DISABLE_X11FWD +#if DROPBEAR_X11FWD /* set up X11 forwarding if enabled */ x11setauth(chansess); #endif -#ifdef ENABLE_SVR_AGENTFWD +#if DROPBEAR_SVR_AGENTFWD /* set up agent env variable */ svr_agentset(chansess); #endif
--- a/svr-kex.c Thu May 18 23:38:30 2017 +0800 +++ b/svr-kex.c Thu May 18 23:45:10 2017 +0800 @@ -54,18 +54,24 @@ } switch (ses.newkeys->algo_kex->mode) { +#if DROPBEAR_NORMAL_DH case DROPBEAR_KEX_NORMAL_DH: m_mp_init(&dh_e); if (buf_getmpint(ses.payload, &dh_e) != DROPBEAR_SUCCESS) { dropbear_exit("Bad kex value"); } break; +#endif +#if DROPBEAR_ECDH case DROPBEAR_KEX_ECDH: +#endif +#if DROPBEAR_CURVE25519 case DROPBEAR_KEX_CURVE25519: -#if defined(DROPBEAR_ECDH) || defined(DROPBEAR_CURVE25519) +#endif +#if DROPBEAR_ECDH || DROPBEAR_CURVE25519 ecdh_qs = buf_getstringbuf(ses.payload); + break; #endif - break; } if (ses.payload->pos != ses.payload->len) { dropbear_exit("Bad kex value"); @@ -85,31 +91,11 @@ } -#ifdef DROPBEAR_DELAY_HOSTKEY - -static void fsync_parent_dir(const char* fn) { -#ifdef HAVE_LIBGEN_H - char *fn_dir = m_strdup(fn); - char *dir = dirname(fn_dir); - int dirfd = open(dir, O_RDONLY); - - if (dirfd != -1) { - if (fsync(dirfd) != 0) { - TRACE(("fsync of directory %s failed: %s", dir, strerror(errno))) - } - m_close(dirfd); - } else { - TRACE(("error opening directory %s for fsync: %s", dir, strerror(errno))) - } - - free(fn_dir); -#endif -} +#if DROPBEAR_DELAY_HOSTKEY static void svr_ensure_hostkey() { const char* fn = NULL; - char *fn_temp = NULL; enum signkey_type type = ses.newkeys->algo_hostkey; void **hostkey = signkey_key_ptr(svr_opts.hostkey, type); int ret = DROPBEAR_FAILURE; @@ -120,17 +106,17 @@ switch (type) { -#ifdef DROPBEAR_RSA +#if DROPBEAR_RSA case DROPBEAR_SIGNKEY_RSA: fn = RSA_PRIV_FILENAME; break; #endif -#ifdef DROPBEAR_DSS +#if DROPBEAR_DSS case DROPBEAR_SIGNKEY_DSS: fn = DSS_PRIV_FILENAME; break; #endif -#ifdef DROPBEAR_ECDSA +#if DROPBEAR_ECDSA case DROPBEAR_SIGNKEY_ECDSA_NISTP256: case DROPBEAR_SIGNKEY_ECDSA_NISTP384: case DROPBEAR_SIGNKEY_ECDSA_NISTP521: @@ -145,28 +131,10 @@ return; } - fn_temp = m_malloc(strlen(fn) + 20); - snprintf(fn_temp, strlen(fn)+20, "%s.tmp%d", fn, getpid()); - - if (signkey_generate(type, 0, fn_temp) == DROPBEAR_FAILURE) { + if (signkey_generate(type, 0, fn, 1) == DROPBEAR_FAILURE) { goto out; } - - if (link(fn_temp, fn) < 0) { - /* It's OK to get EEXIST - we probably just lost a race - with another connection to generate the key */ - if (errno != EEXIST) { - dropbear_log(LOG_ERR, "Failed moving key file to %s: %s", fn, - strerror(errno)); - /* XXX fallback to non-atomic copy for some filesystems? */ - goto out; - } - } - - /* ensure directory update is flushed to disk, otherwise we can end up - with zero-byte hostkey files if the power goes off */ - fsync_parent_dir(fn); - + ret = readhostkey(fn, svr_opts.hostkey, &type); if (ret == DROPBEAR_SUCCESS) { @@ -184,11 +152,6 @@ } out: - if (fn_temp) { - unlink(fn_temp); - m_free(fn_temp); - } - if (ret == DROPBEAR_FAILURE) { dropbear_exit("Couldn't read or generate hostkey %s", fn); @@ -209,7 +172,7 @@ /* we can start creating the kexdh_reply packet */ CHECKCLEARTOWRITE(); -#ifdef DROPBEAR_DELAY_HOSTKEY +#if DROPBEAR_DELAY_HOSTKEY if (svr_opts.delay_hostkey) { svr_ensure_hostkey(); @@ -221,6 +184,7 @@ ses.newkeys->algo_hostkey); switch (ses.newkeys->algo_kex->mode) { +#if DROPBEAR_NORMAL_DH case DROPBEAR_KEX_NORMAL_DH: { struct kex_dh_param * dh_param = gen_kexdh_param(); @@ -231,8 +195,9 @@ free_kexdh_param(dh_param); } break; +#endif +#if DROPBEAR_ECDH case DROPBEAR_KEX_ECDH: -#ifdef DROPBEAR_ECDH { struct kex_ecdh_param *ecdh_param = gen_kexecdh_param(); kexecdh_comb_key(ecdh_param, ecdh_qs, svr_opts.hostkey); @@ -240,18 +205,18 @@ buf_put_ecc_raw_pubkey_string(ses.writepayload, &ecdh_param->key); free_kexecdh_param(ecdh_param); } + break; #endif - break; +#if DROPBEAR_CURVE25519 case DROPBEAR_KEX_CURVE25519: -#ifdef DROPBEAR_CURVE25519 { struct kex_curve25519_param *param = gen_kexcurve25519_param(); kexcurve25519_comb_key(param, ecdh_qs, svr_opts.hostkey); buf_putstring(ses.writepayload, (const char*)param->pub, CURVE25519_LEN); free_kexcurve25519_param(param); } + break; #endif - break; } /* calc the signature */
--- a/svr-main.c Thu May 18 23:38:30 2017 +0800 +++ b/svr-main.c Thu May 18 23:45:10 2017 +0800 @@ -43,8 +43,8 @@ #endif static void commonsetup(void); -#if defined(DBMULTI_dropbear) || !defined(DROPBEAR_MULTI) -#if defined(DBMULTI_dropbear) && defined(DROPBEAR_MULTI) +#if defined(DBMULTI_dropbear) || !DROPBEAR_MULTI +#if defined(DBMULTI_dropbear) && DROPBEAR_MULTI int dropbear_main(int argc, char ** argv) #else int main(int argc, char ** argv) @@ -144,7 +144,7 @@ /* fork */ if (svr_opts.forkbg) { int closefds = 0; -#ifndef DEBUG_TRACE +#if !DEBUG_TRACE if (!opts.usingsyslog) { closefds = 1; } @@ -429,7 +429,7 @@ for (n = 0; n < (unsigned int)nsock; n++) { int sock = socks[sockpos + n]; set_sock_priority(sock, DROPBEAR_PRIO_LOWDELAY); -#ifdef DROPBEAR_SERVER_TCP_FAST_OPEN +#if DROPBEAR_SERVER_TCP_FAST_OPEN set_listen_fast_open(sock); #endif }
--- a/svr-runopts.c Thu May 18 23:38:30 2017 +0800 +++ b/svr-runopts.c Thu May 18 23:45:10 2017 +0800 @@ -46,16 +46,16 @@ " (default: none)\n" "-r keyfile Specify hostkeys (repeatable)\n" " defaults: \n" -#ifdef DROPBEAR_DSS +#if DROPBEAR_DSS " dss %s\n" #endif -#ifdef DROPBEAR_RSA +#if DROPBEAR_RSA " rsa %s\n" #endif -#ifdef DROPBEAR_ECDSA +#if DROPBEAR_ECDSA " ecdsa %s\n" #endif -#ifdef DROPBEAR_DELAY_HOSTKEY +#if DROPBEAR_DELAY_HOSTKEY "-R Create hostkeys as required\n" #endif "-F Don't fork into background\n" @@ -68,17 +68,18 @@ "-m Don't display the motd on login\n" #endif "-w Disallow root logins\n" -#if defined(ENABLE_SVR_PASSWORD_AUTH) || defined(ENABLE_SVR_PAM_AUTH) +#if DROPBEAR_SVR_PASSWORD_AUTH || DROPBEAR_SVR_PAM_AUTH "-s Disable password logins\n" "-g Disable password logins for root\n" "-B Allow blank password logins\n" #endif -#ifdef ENABLE_SVR_LOCALTCPFWD +#if DROPBEAR_SVR_LOCALTCPFWD "-j Disable local port forwarding\n" #endif -#ifdef ENABLE_SVR_REMOTETCPFWD +#if DROPBEAR_SVR_REMOTETCPFWD "-k Disable remote port forwarding\n" "-a Allow connections to forwarded ports from any host\n" + "-c command Force executed command\n" #endif "-p [address:]port\n" " Listen on specified tcp port (and optionally address),\n" @@ -93,17 +94,17 @@ "-K <keepalive> (0 is never, default %d, in seconds)\n" "-I <idle_timeout> (0 is never, default %d, in seconds)\n" "-V Version\n" -#ifdef DEBUG_TRACE +#if DEBUG_TRACE "-v verbose (compiled with DEBUG_TRACE)\n" #endif ,DROPBEAR_VERSION, progname, -#ifdef DROPBEAR_DSS +#if DROPBEAR_DSS DSS_PRIV_FILENAME, #endif -#ifdef DROPBEAR_RSA +#if DROPBEAR_RSA RSA_PRIV_FILENAME, #endif -#ifdef DROPBEAR_ECDSA +#if DROPBEAR_ECDSA ECDSA_PRIV_FILENAME, #endif DROPBEAR_MAX_PORTS, DROPBEAR_DEFPORT, DROPBEAR_PIDFILE, @@ -125,6 +126,7 @@ /* see printhelp() for options */ svr_opts.bannerfile = NULL; svr_opts.banner = NULL; + svr_opts.forced_command = NULL; svr_opts.forkbg = 1; svr_opts.norootlogin = 0; svr_opts.noauthpass = 0; @@ -135,19 +137,15 @@ svr_opts.hostkey = NULL; svr_opts.delay_hostkey = 0; svr_opts.pidfile = DROPBEAR_PIDFILE; -#ifdef ENABLE_SVR_LOCALTCPFWD +#if DROPBEAR_SVR_LOCALTCPFWD svr_opts.nolocaltcp = 0; #endif -#ifdef ENABLE_SVR_REMOTETCPFWD +#if DROPBEAR_SVR_REMOTETCPFWD svr_opts.noremotetcp = 0; #endif #ifndef DISABLE_ZLIB -#if DROPBEAR_SERVER_DELAY_ZLIB opts.compress_mode = DROPBEAR_COMPRESS_DELAYED; -#else - opts.compress_mode = DROPBEAR_COMPRESS_ON; -#endif #endif /* not yet @@ -164,7 +162,7 @@ opts.keepalive_secs = DEFAULT_KEEPALIVE; opts.idle_timeout_secs = DEFAULT_IDLE_TIMEOUT; -#ifdef ENABLE_SVR_REMOTETCPFWD +#if DROPBEAR_SVR_REMOTETCPFWD opts.listen_fwd_all = 0; #endif @@ -177,6 +175,9 @@ case 'b': next = &svr_opts.bannerfile; break; + case 'c': + next = &svr_opts.forced_command; + break; case 'd': case 'r': next = &keyfile; @@ -192,12 +193,12 @@ opts.usingsyslog = 0; break; #endif -#ifdef ENABLE_SVR_LOCALTCPFWD +#if DROPBEAR_SVR_LOCALTCPFWD case 'j': svr_opts.nolocaltcp = 1; break; #endif -#ifdef ENABLE_SVR_REMOTETCPFWD +#if DROPBEAR_SVR_REMOTETCPFWD case 'k': svr_opts.noremotetcp = 1; break; @@ -234,7 +235,7 @@ case 'I': next = &idle_timeout_arg; break; -#if defined(ENABLE_SVR_PASSWORD_AUTH) || defined(ENABLE_SVR_PAM_AUTH) +#if DROPBEAR_SVR_PASSWORD_AUTH || DROPBEAR_SVR_PAM_AUTH case 's': svr_opts.noauthpass = 1; break; @@ -252,7 +253,7 @@ case 'u': /* backwards compatibility with old urandom option */ break; -#ifdef DEBUG_TRACE +#if DEBUG_TRACE case 'v': debug_trace = 1; break; @@ -346,6 +347,10 @@ } opts.idle_timeout_secs = val; } + + if (svr_opts.forced_command) { + dropbear_log(LOG_INFO, "Forced command set to '%s'", svr_opts.forced_command); + } } static void addportandaddress(const char* spec) { @@ -434,30 +439,30 @@ } } -#ifdef DROPBEAR_RSA +#if DROPBEAR_RSA if (type == DROPBEAR_SIGNKEY_RSA) { loadhostkey_helper("RSA", (void**)&read_key->rsakey, (void**)&svr_opts.hostkey->rsakey, fatal_duplicate); } #endif -#ifdef DROPBEAR_DSS +#if DROPBEAR_DSS if (type == DROPBEAR_SIGNKEY_DSS) { loadhostkey_helper("DSS", (void**)&read_key->dsskey, (void**)&svr_opts.hostkey->dsskey, fatal_duplicate); } #endif -#ifdef DROPBEAR_ECDSA -#ifdef DROPBEAR_ECC_256 +#if DROPBEAR_ECDSA +#if DROPBEAR_ECC_256 if (type == DROPBEAR_SIGNKEY_ECDSA_NISTP256) { loadhostkey_helper("ECDSA256", (void**)&read_key->ecckey256, (void**)&svr_opts.hostkey->ecckey256, fatal_duplicate); } #endif -#ifdef DROPBEAR_ECC_384 +#if DROPBEAR_ECC_384 if (type == DROPBEAR_SIGNKEY_ECDSA_NISTP384) { loadhostkey_helper("ECDSA384", (void**)&read_key->ecckey384, (void**)&svr_opts.hostkey->ecckey384, fatal_duplicate); } #endif -#ifdef DROPBEAR_ECC_521 +#if DROPBEAR_ECC_521 if (type == DROPBEAR_SIGNKEY_ECDSA_NISTP521) { loadhostkey_helper("ECDSA521", (void**)&read_key->ecckey521, (void**)&svr_opts.hostkey->ecckey521, fatal_duplicate); } @@ -489,25 +494,25 @@ m_free(hostkey_file); } -#ifdef DROPBEAR_RSA +#if DROPBEAR_RSA loadhostkey(RSA_PRIV_FILENAME, 0); #endif -#ifdef DROPBEAR_DSS +#if DROPBEAR_DSS loadhostkey(DSS_PRIV_FILENAME, 0); #endif -#ifdef DROPBEAR_ECDSA +#if DROPBEAR_ECDSA loadhostkey(ECDSA_PRIV_FILENAME, 0); #endif -#ifdef DROPBEAR_DELAY_HOSTKEY +#if DROPBEAR_DELAY_HOSTKEY if (svr_opts.delay_hostkey) { disable_unset_keys = 0; } #endif -#ifdef DROPBEAR_RSA +#if DROPBEAR_RSA if (disable_unset_keys && !svr_opts.hostkey->rsakey) { disablekey(DROPBEAR_SIGNKEY_RSA); } else { @@ -515,7 +520,7 @@ } #endif -#ifdef DROPBEAR_DSS +#if DROPBEAR_DSS if (disable_unset_keys && !svr_opts.hostkey->dsskey) { disablekey(DROPBEAR_SIGNKEY_DSS); } else { @@ -524,8 +529,8 @@ #endif -#ifdef DROPBEAR_ECDSA -#ifdef DROPBEAR_ECC_256 +#if DROPBEAR_ECDSA +#if DROPBEAR_ECC_256 if ((disable_unset_keys || ECDSA_DEFAULT_SIZE != 256) && !svr_opts.hostkey->ecckey256) { disablekey(DROPBEAR_SIGNKEY_ECDSA_NISTP256); @@ -534,7 +539,7 @@ } #endif -#ifdef DROPBEAR_ECC_384 +#if DROPBEAR_ECC_384 if ((disable_unset_keys || ECDSA_DEFAULT_SIZE != 384) && !svr_opts.hostkey->ecckey384) { disablekey(DROPBEAR_SIGNKEY_ECDSA_NISTP384); @@ -543,7 +548,7 @@ } #endif -#ifdef DROPBEAR_ECC_521 +#if DROPBEAR_ECC_521 if ((disable_unset_keys || ECDSA_DEFAULT_SIZE != 521) && !svr_opts.hostkey->ecckey521) { disablekey(DROPBEAR_SIGNKEY_ECDSA_NISTP521);
--- a/svr-session.c Thu May 18 23:38:30 2017 +0800 +++ b/svr-session.c Thu May 18 23:45:10 2017 +0800 @@ -63,7 +63,7 @@ {SSH_MSG_CHANNEL_FAILURE, ignore_recv_response}, {SSH_MSG_REQUEST_FAILURE, ignore_recv_response}, /* for keepalive */ {SSH_MSG_REQUEST_SUCCESS, ignore_recv_response}, /* client */ -#ifdef USING_LISTENERS +#if DROPBEAR_LISTENERS {SSH_MSG_CHANNEL_OPEN_CONFIRMATION, recv_msg_channel_open_confirmation}, {SSH_MSG_CHANNEL_OPEN_FAILURE, recv_msg_channel_open_failure}, #endif @@ -72,7 +72,7 @@ static const struct ChanType *svr_chantypes[] = { &svrchansess, -#ifdef ENABLE_SVR_LOCALTCPFWD +#if DROPBEAR_SVR_LOCALTCPFWD &svr_chan_tcpdirect, #endif NULL /* Null termination is mandatory. */ @@ -97,7 +97,7 @@ /* Initialise server specific parts of the session */ svr_ses.childpipe = childpipe; -#ifdef USE_VFORK +#if DROPBEAR_VFORK svr_ses.server_pid = getpid(); #endif svr_authinitialise(); @@ -173,7 +173,7 @@ dropbear_log(LOG_INFO, "%s", fullmsg); -#ifdef USE_VFORK +#if DROPBEAR_VFORK /* For uclinux only the main server process should cleanup - we don't want * forked children doing that */ if (svr_ses.server_pid == getpid()) @@ -222,7 +222,7 @@ /* if we are using DEBUG_TRACE, we want to print to stderr even if * syslog is used, so it is included in error reports */ -#ifdef DEBUG_TRACE +#if DEBUG_TRACE havetrace = debug_trace; #endif
--- a/svr-tcpfwd.c Thu May 18 23:38:30 2017 +0800 +++ b/svr-tcpfwd.c Thu May 18 23:45:10 2017 +0800 @@ -35,7 +35,7 @@ #include "auth.h" #include "netio.h" -#ifndef ENABLE_SVR_REMOTETCPFWD +#ifndef DROPBEAR_SVR_REMOTETCPFWD /* This is better than SSH_MSG_UNIMPLEMENTED */ void recv_msg_global_request_remotetcp() { @@ -44,13 +44,13 @@ } /* */ -#endif /* !ENABLE_SVR_REMOTETCPFWD */ +#endif /* !DROPBEAR_SVR_REMOTETCPFWD */ static int svr_cancelremotetcp(void); static int svr_remotetcpreq(void); static int newtcpdirect(struct Channel * channel); -#ifdef ENABLE_SVR_REMOTETCPFWD +#if DROPBEAR_SVR_REMOTETCPFWD static const struct ChanType svr_chan_tcpremote = { 1, /* sepfds */ "forwarded-tcpip", @@ -199,7 +199,7 @@ } else { - tcpinfo->listenaddr = request_addr; + tcpinfo->listenaddr = m_strdup(request_addr); } ret = listen_tcpfwd(tcpinfo); @@ -215,9 +215,9 @@ return ret; } -#endif /* ENABLE_SVR_REMOTETCPFWD */ +#endif /* DROPBEAR_SVR_REMOTETCPFWD */ -#ifdef ENABLE_SVR_LOCALTCPFWD +#if DROPBEAR_SVR_LOCALTCPFWD const struct ChanType svr_chan_tcpdirect = { 1, /* sepfds */ @@ -283,4 +283,4 @@ return err; } -#endif /* ENABLE_SVR_LOCALTCPFWD */ +#endif /* DROPBEAR_SVR_LOCALTCPFWD */
--- a/svr-x11fwd.c Thu May 18 23:38:30 2017 +0800 +++ b/svr-x11fwd.c Thu May 18 23:45:10 2017 +0800 @@ -24,7 +24,7 @@ #include "includes.h" -#ifndef DISABLE_X11FWD +#if DROPBEAR_X11FWD #include "x11fwd.h" #include "session.h" #include "ssh.h"
--- a/sysoptions.h Thu May 18 23:38:30 2017 +0800 +++ b/sysoptions.h Thu May 18 23:45:10 2017 +0800 @@ -4,7 +4,7 @@ *******************************************************************/ #ifndef DROPBEAR_VERSION -#define DROPBEAR_VERSION "2016.74" +#define DROPBEAR_VERSION "2017.75" #endif #define LOCAL_IDENT "SSH-2.0-dropbear_" DROPBEAR_VERSION @@ -23,14 +23,20 @@ #define AUTH_TIMEOUT 300 /* we choose 5 minutes */ #endif + #define DROPBEAR_SVR_PUBKEY_OPTIONS_BUILT ((DROPBEAR_SVR_PUBKEY_AUTH) && (DROPBEAR_SVR_PUBKEY_OPTIONS)) + /* A client should try and send an initial key exchange packet guessing * the algorithm that will match - saves a round trip connecting, has little * overhead if the guess was "wrong". */ -#define USE_KEX_FIRST_FOLLOWS +#ifndef DROPBEAR_KEX_FIRST_FOLLOWS +#define DROPBEAR_KEX_FIRST_FOLLOWS 1 +#endif /* Use protocol extension to allow "first follows" to succeed more frequently. * This is currently Dropbear-specific but will gracefully fallback when connecting * to other implementations. */ -#define USE_KEXGUESS2 +#ifndef DROPBEAR_KEXGUESS2 +#define DROPBEAR_KEXGUESS2 1 +#endif /* Minimum key sizes for DSS and RSA */ #ifndef MIN_DSS_KEYLEN @@ -68,11 +74,11 @@ /* success/failure defines */ #define DROPBEAR_SUCCESS 0 #define DROPBEAR_FAILURE -1 + +#define DROPBEAR_PASSWORD_ENV "DROPBEAR_PASSWORD" /* Required for pubkey auth */ -#if defined(ENABLE_SVR_PUBKEY_AUTH) || defined(DROPBEAR_CLIENT) -#define DROPBEAR_SIGNKEY_VERIFY -#endif +#define DROPBEAR_SIGNKEY_VERIFY ((DROPBEAR_SVR_PUBKEY_AUTH) || (DROPBEAR_CLIENT)) #define SHA1_HASH_SIZE 20 #define MD5_HASH_SIZE 16 @@ -81,56 +87,45 @@ #define MAX_KEY_LEN 32 /* 256 bits for aes256 etc */ #define MAX_IV_LEN 20 /* must be same as max blocksize, */ -#if defined(DROPBEAR_SHA2_512_HMAC) +#if DROPBEAR_SHA2_512_HMAC #define MAX_MAC_LEN 64 -#elif defined(DROPBEAR_SHA2_256_HMAC) +#elif DROPBEAR_SHA2_256_HMAC #define MAX_MAC_LEN 32 #else #define MAX_MAC_LEN 20 #endif -#if defined(DROPBEAR_ECDH) || defined (DROPBEAR_ECDSA) -#define DROPBEAR_ECC + +#define DROPBEAR_ECC ((DROPBEAR_ECDH) || (DROPBEAR_ECDSA)) + /* Debian doesn't define this in system headers */ -#ifndef LTM_DESC -#define LTM_DESC -#endif +#if !defined(LTM_DESC) && (DROPBEAR_ECC) +#define LTM_DESC #endif -#ifdef DROPBEAR_ECC -#define DROPBEAR_ECC_256 -#define DROPBEAR_ECC_384 -#define DROPBEAR_ECC_521 -#endif +#define DROPBEAR_ECC_256 (DROPBEAR_ECC) +#define DROPBEAR_ECC_384 (DROPBEAR_ECC) +#define DROPBEAR_ECC_521 (DROPBEAR_ECC) -#ifdef DROPBEAR_ECC -#define DROPBEAR_LTC_PRNG -#endif +#define DROPBEAR_LTC_PRNG (DROPBEAR_ECC) /* RSA can be vulnerable to timing attacks which use the time required for * signing to guess the private key. Blinding avoids this attack, though makes * signing operations slightly slower. */ -#define RSA_BLINDING +#define DROPBEAR_RSA_BLINDING 1 /* hashes which will be linked and registered */ -#if defined(DROPBEAR_SHA2_256_HMAC) || defined(DROPBEAR_ECC_256) || defined(DROPBEAR_CURVE25519) || DROPBEAR_DH_GROUP14 -#define DROPBEAR_SHA256 -#endif -#if defined(DROPBEAR_ECC_384) -#define DROPBEAR_SHA384 -#endif +#define DROPBEAR_SHA256 ((DROPBEAR_SHA2_256_HMAC) || (DROPBEAR_ECC_256) \ + || (DROPBEAR_CURVE25519) || (DROPBEAR_DH_GROUP14_SHA256)) +#define DROPBEAR_SHA384 (DROPBEAR_ECC_384) /* LTC SHA384 depends on SHA512 */ -#if defined(DROPBEAR_SHA2_512_HMAC) || defined(DROPBEAR_ECC_521) || defined(DROPBEAR_ECC_384) || DROPBEAR_DH_GROUP16 -#define DROPBEAR_SHA512 -#endif -#if defined(DROPBEAR_MD5_HMAC) -#define DROPBEAR_MD5 -#endif +#define DROPBEAR_SHA512 ((DROPBEAR_SHA2_512_HMAC) || (DROPBEAR_ECC_521) \ + || (DROPBEAR_SHA384) || (DROPBEAR_DH_GROUP16)) +#define DROPBEAR_MD5 (DROPBEAR_MD5_HMAC) -/* These are disabled in Dropbear 2016.73 by default since the spec - draft-ietf-curdle-ssh-kex-sha2-02 is under development. */ -#define DROPBEAR_DH_GROUP14_256 0 -#define DROPBEAR_DH_GROUP16 0 +#define DROPBEAR_DH_GROUP14 ((DROPBEAR_DH_GROUP14_SHA256) || (DROPBEAR_DH_GROUP14_SHA1)) + +#define DROPBEAR_NORMAL_DH ((DROPBEAR_DH_GROUP1) || (DROPBEAR_DH_GROUP14) || (DROPBEAR_DH_GROUP16)) /* roughly 2x 521 bits */ #define MAX_ECC_SIZE 140 @@ -182,65 +177,47 @@ auth */ -#if defined(DROPBEAR_AES256) || defined(DROPBEAR_AES128) -#define DROPBEAR_AES -#endif +#define DROPBEAR_AES ((DROPBEAR_AES256) || (DROPBEAR_AES128)) -#if defined(DROPBEAR_TWOFISH256) || defined(DROPBEAR_TWOFISH128) -#define DROPBEAR_TWOFISH -#endif +#define DROPBEAR_TWOFISH ((DROPBEAR_TWOFISH256) || (DROPBEAR_TWOFISH128)) -#ifndef ENABLE_X11FWD -#define DISABLE_X11FWD -#endif +#define DROPBEAR_CLI_ANYTCPFWD ((DROPBEAR_CLI_REMOTETCPFWD) || (DROPBEAR_CLI_LOCALTCPFWD)) -#if defined(ENABLE_CLI_REMOTETCPFWD) || defined(ENABLE_CLI_LOCALTCPFWD) -#define ENABLE_CLI_ANYTCPFWD -#endif +#define DROPBEAR_TCP_ACCEPT ((DROPBEAR_CLI_LOCALTCPFWD) || (DROPBEAR_SVR_REMOTETCPFWD)) -#if defined(ENABLE_CLI_LOCALTCPFWD) || defined(ENABLE_SVR_REMOTETCPFWD) -#define DROPBEAR_TCP_ACCEPT -#endif - -#if defined(ENABLE_CLI_REMOTETCPFWD) || defined(ENABLE_CLI_LOCALTCPFWD) || \ - defined(ENABLE_SVR_REMOTETCPFWD) || defined(ENABLE_SVR_LOCALTCPFWD) || \ - defined(ENABLE_SVR_AGENTFWD) || defined(ENABLE_X11FWD) -#define USING_LISTENERS -#endif +#define DROPBEAR_LISTENERS \ + ((DROPBEAR_CLI_REMOTETCPFWD) || (DROPBEAR_CLI_LOCALTCPFWD) || \ + (DROPBEAR_SVR_REMOTETCPFWD) || (DROPBEAR_SVR_LOCALTCPFWD) || \ + (DROPBEAR_SVR_AGENTFWD) || (DROPBEAR_X11FWD)) -#if defined(ENABLE_CLI_NETCAT) && defined(ENABLE_CLI_PROXYCMD) -#define ENABLE_CLI_MULTIHOP -#endif +#define DROPBEAR_CLI_MULTIHOP ((DROPBEAR_CLI_NETCAT) && (DROPBEAR_CLI_PROXYCMD)) -#if defined(ENABLE_CLI_AGENTFWD) || defined(DROPBEAR_PRNGD_SOCKET) -#define ENABLE_CONNECT_UNIX -#endif +#define ENABLE_CONNECT_UNIX ((DROPBEAR_CLI_AGENTFWD) || (DROPBEAR_PRNGD_SOCKET)) -#if defined(DROPBEAR_CLIENT) || defined(ENABLE_SVR_PUBKEY_AUTH) -#define DROPBEAR_KEY_LINES /* ie we're using authorized_keys or known_hosts */ -#endif +/* if we're using authorized_keys or known_hosts */ +#define DROPBEAR_KEY_LINES ((DROPBEAR_CLIENT) || (DROPBEAR_SVR_PUBKEY_AUTH)) /* Changing this is inadvisable, it appears to have problems * with flushing compressed data */ #define DROPBEAR_ZLIB_MEM_LEVEL 8 -#if defined(ENABLE_SVR_PASSWORD_AUTH) && defined(ENABLE_SVR_PAM_AUTH) +#if (DROPBEAR_SVR_PASSWORD_AUTH) && (DROPBEAR_SVR_PAM_AUTH) #error "You can't turn on PASSWORD and PAM auth both at once. Fix it in options.h" #endif /* We use dropbear_client and dropbear_server as shortcuts to avoid redundant * code, if we're just compiling as client or server */ -#if defined(DROPBEAR_SERVER) && defined(DROPBEAR_CLIENT) +#if (DROPBEAR_SERVER) && (DROPBEAR_CLIENT) #define IS_DROPBEAR_SERVER (ses.isserver == 1) #define IS_DROPBEAR_CLIENT (ses.isserver == 0) -#elif defined(DROPBEAR_SERVER) +#elif DROPBEAR_SERVER #define IS_DROPBEAR_SERVER 1 #define IS_DROPBEAR_CLIENT 0 -#elif defined(DROPBEAR_CLIENT) +#elif DROPBEAR_CLIENT #define IS_DROPBEAR_SERVER 0 #define IS_DROPBEAR_CLIENT 1 @@ -252,9 +229,11 @@ #endif /* neither DROPBEAR_SERVER nor DROPBEAR_CLIENT */ -#ifndef HAVE_FORK -#define USE_VFORK -#endif /* don't HAVE_FORK */ +#ifdef HAVE_FORK +#define DROPBEAR_VFORK 0 +#else +#define DROPBEAR_VFORK 1 +#endif #if MAX_UNAUTH_CLIENTS > MAX_CHANNELS #define DROPBEAR_LISTEN_BACKLOG MAX_UNAUTH_CLIENTS @@ -262,8 +241,12 @@ #define DROPBEAR_LISTEN_BACKLOG MAX_CHANNELS #endif +#ifndef DROPBEAR_NONE_CIPHER +#define DROPBEAR_NONE_CIPHER 0 +#endif + /* free memory before exiting */ -#define DROPBEAR_CLEANUP +#define DROPBEAR_CLEANUP 1 /* Use this string since some implementations might special-case it */ #define DROPBEAR_KEEPALIVE_STRING "[email protected]" @@ -272,8 +255,11 @@ * Currently server is enabled but client is disabled by default until there * is further compatibility testing */ #ifdef __linux__ -#define DROPBEAR_SERVER_TCP_FAST_OPEN -/* #define DROPBEAR_CLIENT_TCP_FAST_OPEN */ +#define DROPBEAR_SERVER_TCP_FAST_OPEN 1 +#define DROPBEAR_CLIENT_TCP_FAST_OPEN 0 +#else +#define DROPBEAR_SERVER_TCP_FAST_OPEN 0 +#define DROPBEAR_CLIENT_TCP_FAST_OPEN 0 #endif /* no include guard for this file */