ASR_BASE
Change-Id: Icf3719cc0afe3eeb3edc7fa80a2eb5199ca9dda1
diff --git a/package/network/services/dropbear/patches/100-pubkey_path.patch b/package/network/services/dropbear/patches/100-pubkey_path.patch
new file mode 100644
index 0000000..0ecca90
--- /dev/null
+++ b/package/network/services/dropbear/patches/100-pubkey_path.patch
@@ -0,0 +1,106 @@
+--- a/src/svr-authpubkey.c
++++ b/src/svr-authpubkey.c
+@@ -78,6 +78,13 @@ static void send_msg_userauth_pk_ok(cons
+ const unsigned char* keyblob, unsigned int keybloblen);
+ static int checkfileperm(char * filename);
+
++static const char * const global_authkeys_dir = "/etc/dropbear";
++static const int n_global_authkeys_dir = 14; /* + 1 extra byte */
++static const char * const user_authkeys_dir = ".ssh";
++static const int n_user_authkeys_dir = 5; /* + 1 extra byte */
++static const char * const authkeys_file = "authorized_keys";
++static const int n_authkeys_file = 16; /* + 1 extra byte */
++
+ /* process a pubkey auth request, sending success or failure message as
+ * appropriate */
+ void svr_auth_pubkey(int valid_user) {
+@@ -462,14 +469,21 @@ static int checkpubkey(const char* keyal
+ if (checkpubkeyperms() == DROPBEAR_FAILURE) {
+ TRACE(("bad authorized_keys permissions, or file doesn't exist"))
+ } else {
+- /* we don't need to check pw and pw_dir for validity, since
+- * its been done in checkpubkeyperms. */
+- len = strlen(ses.authstate.pw_dir);
+- /* allocate max required pathname storage,
+- * = path + "/.ssh/authorized_keys" + '\0' = pathlen + 22 */
+- filename = m_malloc(len + 22);
+- snprintf(filename, len + 22, "%s/.ssh/authorized_keys",
+- ses.authstate.pw_dir);
++ if (ses.authstate.pw_uid == 0) {
++ len = n_global_authkeys_dir + n_authkeys_file;
++ filename = m_malloc(len);
++ snprintf(filename, len, "%s/%s", global_authkeys_dir, authkeys_file);
++ } else {
++ /* we don't need to check pw and pw_dir for validity, since
++ * its been done in checkpubkeyperms. */
++ len = strlen(ses.authstate.pw_dir);
++ /* allocate max required pathname storage,
++ * = path + "/.ssh/authorized_keys" + '\0' = pathlen + 22 */
++ len += n_user_authkeys_dir + n_authkeys_file + 1;
++ filename = m_malloc(len);
++ snprintf(filename, len, "%s/%s/%s", ses.authstate.pw_dir,
++ user_authkeys_dir, authkeys_file);
++ }
+
+ authfile = fopen(filename, "r");
+ if (!authfile) {
+@@ -543,27 +557,41 @@ static int checkpubkeyperms() {
+ goto out;
+ }
+
+- /* allocate max required pathname storage,
+- * = path + "/.ssh/authorized_keys" + '\0' = pathlen + 22 */
+- len += 22;
+- filename = m_malloc(len);
+- strlcpy(filename, ses.authstate.pw_dir, len);
++ if (ses.authstate.pw_uid == 0) {
++ if (checkfileperm(global_authkeys_dir) != DROPBEAR_SUCCESS) {
++ goto out;
++ }
+
+- /* check ~ */
+- if (checkfileperm(filename) != DROPBEAR_SUCCESS) {
+- goto out;
+- }
++ len = n_global_authkeys_dir + n_authkeys_file;
++ filename = m_malloc(len);
+
+- /* check ~/.ssh */
+- strlcat(filename, "/.ssh", len);
+- if (checkfileperm(filename) != DROPBEAR_SUCCESS) {
+- goto out;
+- }
++ snprintf(filename, len, "%s/%s", global_authkeys_dir, authkeys_file);
++ if (checkfileperm(filename) != DROPBEAR_SUCCESS) {
++ goto out;
++ }
++ } else {
++ /* check ~ */
++ if (checkfileperm(ses.authstate.pw_dir) != DROPBEAR_SUCCESS) {
++ goto out;
++ }
+
+- /* now check ~/.ssh/authorized_keys */
+- strlcat(filename, "/authorized_keys", len);
+- if (checkfileperm(filename) != DROPBEAR_SUCCESS) {
+- goto out;
++ /* allocate max required pathname storage,
++ * = path + "/.ssh/authorized_keys" + '\0' = pathlen + 22 */
++ len += n_user_authkeys_dir + n_authkeys_file + 1;
++ filename = m_malloc(len);
++
++ /* check ~/.ssh */
++ snprintf(filename, len, "%s/%s", ses.authstate.pw_dir, user_authkeys_dir);
++ if (checkfileperm(filename) != DROPBEAR_SUCCESS) {
++ goto out;
++ }
++
++ /* now check ~/.ssh/authorized_keys */
++ snprintf(filename, len, "%s/%s/%s", ses.authstate.pw_dir,
++ user_authkeys_dir, authkeys_file);
++ if (checkfileperm(filename) != DROPBEAR_SUCCESS) {
++ goto out;
++ }
+ }
+
+ /* file looks ok, return success */
diff --git a/package/network/services/dropbear/patches/110-change_user.patch b/package/network/services/dropbear/patches/110-change_user.patch
new file mode 100644
index 0000000..9ef8f0c
--- /dev/null
+++ b/package/network/services/dropbear/patches/110-change_user.patch
@@ -0,0 +1,18 @@
+--- a/src/svr-chansession.c
++++ b/src/svr-chansession.c
+@@ -984,12 +984,12 @@ static void execchild(const void *user_d
+ /* We can only change uid/gid as root ... */
+ if (getuid() == 0) {
+
+- if ((setgid(ses.authstate.pw_gid) < 0) ||
++ if ((ses.authstate.pw_gid != 0) && ((setgid(ses.authstate.pw_gid) < 0) ||
+ (initgroups(ses.authstate.pw_name,
+- ses.authstate.pw_gid) < 0)) {
++ ses.authstate.pw_gid) < 0))) {
+ dropbear_exit("Error changing user group");
+ }
+- if (setuid(ses.authstate.pw_uid) < 0) {
++ if ((ses.authstate.pw_uid != 0) && (setuid(ses.authstate.pw_uid) < 0)) {
+ dropbear_exit("Error changing user");
+ }
+ } else {
diff --git a/package/network/services/dropbear/patches/130-ssh_ignore_x_args.patch b/package/network/services/dropbear/patches/130-ssh_ignore_x_args.patch
new file mode 100644
index 0000000..de0e5f2
--- /dev/null
+++ b/package/network/services/dropbear/patches/130-ssh_ignore_x_args.patch
@@ -0,0 +1,13 @@
+--- a/src/cli-runopts.c
++++ b/src/cli-runopts.c
+@@ -340,6 +340,10 @@ void cli_getopts(int argc, char ** argv)
+ case 'z':
+ opts.disable_ip_tos = 1;
+ break;
++ case 'x':
++ /* compatibility with openssh cli
++ * ("-x" disables X11 forwarding) */
++ break;
+ default:
+ fprintf(stderr,
+ "WARNING: Ignoring unknown option -%c\n", c);
diff --git a/package/network/services/dropbear/patches/140-disable_assert.patch b/package/network/services/dropbear/patches/140-disable_assert.patch
new file mode 100644
index 0000000..eb590a3
--- /dev/null
+++ b/package/network/services/dropbear/patches/140-disable_assert.patch
@@ -0,0 +1,15 @@
+--- a/src/dbutil.h
++++ b/src/dbutil.h
+@@ -80,7 +80,11 @@ int m_snprintf(char *str, size_t size, c
+ #define DEF_MP_INT(X) mp_int X = {0, 0, 0, NULL}
+
+ /* Dropbear assertion */
+-#define dropbear_assert(X) do { if (!(X)) { fail_assert(#X, __FILE__, __LINE__); } } while (0)
++#ifndef DROPBEAR_ASSERT_ENABLED
++#define DROPBEAR_ASSERT_ENABLED 0
++#endif
++
++#define dropbear_assert(X) do { if (DROPBEAR_ASSERT_ENABLED && !(X)) { fail_assert(#X, __FILE__, __LINE__); } } while (0)
+
+ /* Returns 0 if a and b have the same contents */
+ int constant_time_memcmp(const void* a, const void *b, size_t n);
diff --git a/package/network/services/dropbear/patches/160-lto-jobserver.patch b/package/network/services/dropbear/patches/160-lto-jobserver.patch
new file mode 100644
index 0000000..1f3b298
--- /dev/null
+++ b/package/network/services/dropbear/patches/160-lto-jobserver.patch
@@ -0,0 +1,33 @@
+--- a/Makefile.in
++++ b/Makefile.in
+@@ -220,17 +220,17 @@ dropbearkey: $(dropbearkeyobjs)
+ dropbearconvert: $(dropbearconvertobjs)
+
+ dropbear: $(HEADERS) $(LIBTOM_DEPS) Makefile
+- $(CC) $(LDFLAGS) -o $@$(EXEEXT) $($@objs) $(LIBTOM_LIBS) $(LIBS) @CRYPTLIB@ $(PLUGIN_LIBS)
++ +$(CC) $(LDFLAGS) -o $@$(EXEEXT) $($@objs) $(LIBTOM_LIBS) $(LIBS) @CRYPTLIB@ $(PLUGIN_LIBS)
+
+ dbclient: $(HEADERS) $(LIBTOM_DEPS) Makefile
+- $(CC) $(LDFLAGS) -o $@$(EXEEXT) $($@objs) $(LIBTOM_LIBS) $(LIBS)
++ +$(CC) $(LDFLAGS) -o $@$(EXEEXT) $($@objs) $(LIBTOM_LIBS) $(LIBS)
+
+ dropbearkey dropbearconvert: $(HEADERS) $(LIBTOM_DEPS) Makefile
+- $(CC) $(LDFLAGS) -o $@$(EXEEXT) $($@objs) $(LIBTOM_LIBS) $(LIBS)
++ +$(CC) $(LDFLAGS) -o $@$(EXEEXT) $($@objs) $(LIBTOM_LIBS) $(LIBS)
+
+ # scp doesn't use the libs so is special.
+ scp: $(SCPOBJS) $(HEADERS) Makefile
+- $(CC) $(LDFLAGS) -o $@$(EXEEXT) $(SCPOBJS)
++ +$(CC) $(LDFLAGS) -o $@$(EXEEXT) $(SCPOBJS)
+
+
+ # multi-binary compilation.
+@@ -241,7 +241,7 @@ ifeq ($(MULTI),1)
+ endif
+
+ dropbearmulti$(EXEEXT): $(HEADERS) $(MULTIOBJS) $(LIBTOM_DEPS) Makefile
+- $(CC) $(LDFLAGS) -o $@ $(MULTIOBJS) $(LIBTOM_LIBS) $(LIBS) @CRYPTLIB@
++ +$(CC) $(LDFLAGS) -o $@ $(MULTIOBJS) $(LIBTOM_LIBS) $(LIBS) @CRYPTLIB@
+
+ multibinary: dropbearmulti$(EXEEXT)
+
diff --git a/package/network/services/dropbear/patches/600-allow-blank-root-password.patch b/package/network/services/dropbear/patches/600-allow-blank-root-password.patch
new file mode 100644
index 0000000..e72458d
--- /dev/null
+++ b/package/network/services/dropbear/patches/600-allow-blank-root-password.patch
@@ -0,0 +1,11 @@
+--- a/src/svr-auth.c
++++ b/src/svr-auth.c
+@@ -124,7 +124,7 @@ void recv_msg_userauth_request() {
+ AUTH_METHOD_NONE_LEN) == 0) {
+ TRACE(("recv_msg_userauth_request: 'none' request"))
+ if (valid_user
+- && svr_opts.allowblankpass
++ && (svr_opts.allowblankpass || !strcmp(ses.authstate.pw_name, "root"))
+ && !svr_opts.noauthpass
+ && !(svr_opts.norootpass && ses.authstate.pw_uid == 0)
+ && ses.authstate.pw_passwd[0] == '\0')
diff --git a/package/network/services/dropbear/patches/900-configure-hardening.patch b/package/network/services/dropbear/patches/900-configure-hardening.patch
new file mode 100644
index 0000000..746694f
--- /dev/null
+++ b/package/network/services/dropbear/patches/900-configure-hardening.patch
@@ -0,0 +1,57 @@
+--- a/configure.ac
++++ b/configure.ac
+@@ -86,54 +86,6 @@ AC_ARG_ENABLE(harden,
+
+ if test "$hardenbuild" -eq 1; then
+ AC_MSG_NOTICE(Checking for available hardened build flags:)
+- # relocation flags don't make sense for static builds
+- if test "$STATIC" -ne 1; then
+- # pie
+- DB_TRYADDCFLAGS([-fPIE])
+-
+- OLDLDFLAGS="$LDFLAGS"
+- TESTFLAGS="-Wl,-pie"
+- LDFLAGS="$TESTFLAGS $LDFLAGS"
+- AC_LINK_IFELSE([AC_LANG_PROGRAM([])],
+- [AC_MSG_NOTICE([Setting $TESTFLAGS])],
+- [
+- LDFLAGS="$OLDLDFLAGS"
+- TESTFLAGS="-pie"
+- LDFLAGS="$TESTFLAGS $LDFLAGS"
+- AC_LINK_IFELSE([AC_LANG_PROGRAM([])],
+- [AC_MSG_NOTICE([Setting $TESTFLAGS])],
+- [AC_MSG_NOTICE([Not setting $TESTFLAGS]); LDFLAGS="$OLDLDFLAGS" ]
+- )
+- ]
+- )
+- # readonly elf relocation sections (relro)
+- OLDLDFLAGS="$LDFLAGS"
+- TESTFLAGS="-Wl,-z,now -Wl,-z,relro"
+- LDFLAGS="$TESTFLAGS $LDFLAGS"
+- AC_LINK_IFELSE([AC_LANG_PROGRAM([])],
+- [AC_MSG_NOTICE([Setting $TESTFLAGS])],
+- [AC_MSG_NOTICE([Not setting $TESTFLAGS]); LDFLAGS="$OLDLDFLAGS" ]
+- )
+- fi # non-static
+- # stack protector. -strong is good but only in gcc 4.9 or later
+- OLDCFLAGS="$CFLAGS"
+- TESTFLAGS="-fstack-protector-strong"
+- CFLAGS="$TESTFLAGS $CFLAGS"
+- AC_LINK_IFELSE([AC_LANG_PROGRAM([])],
+- [AC_MSG_NOTICE([Setting $TESTFLAGS])],
+- [
+- CFLAGS="$OLDCFLAGS"
+- TESTFLAGS="-fstack-protector --param=ssp-buffer-size=4"
+- CFLAGS="$TESTFLAGS $CFLAGS"
+- AC_LINK_IFELSE([AC_LANG_PROGRAM([])],
+- [AC_MSG_NOTICE([Setting $TESTFLAGS])],
+- [AC_MSG_NOTICE([Not setting $TESTFLAGS]); CFLAGS="$OLDCFLAGS" ]
+- )
+- ]
+- )
+- # FORTIFY_SOURCE
+- DB_TRYADDCFLAGS([-D_FORTIFY_SOURCE=2])
+-
+ # Spectre v2 mitigations
+ DB_TRYADDCFLAGS([-mfunction-return=thunk])
+ DB_TRYADDCFLAGS([-mindirect-branch=thunk])
diff --git a/package/network/services/dropbear/patches/901-bundled-libs-cflags.patch b/package/network/services/dropbear/patches/901-bundled-libs-cflags.patch
new file mode 100644
index 0000000..4da01c9
--- /dev/null
+++ b/package/network/services/dropbear/patches/901-bundled-libs-cflags.patch
@@ -0,0 +1,29 @@
+--- a/configure.ac
++++ b/configure.ac
+@@ -44,11 +44,8 @@ fi
+ # LTM_CFLAGS is given to ./configure by the user,
+ # DROPBEAR_LTM_CFLAGS is substituted in the LTM Makefile.in
+ DROPBEAR_LTM_CFLAGS="$LTM_CFLAGS"
+-if test -z "$DROPBEAR_LTM_CFLAGS"; then
+- DROPBEAR_LTM_CFLAGS="-O3 -funroll-loops -fomit-frame-pointer"
+-fi
+-AC_MSG_NOTICE(Setting LTM_CFLAGS to $DROPBEAR_LTM_CFLAGS)
+-AC_ARG_VAR(LTM_CFLAGS, CFLAGS for bundled libtommath. Default -O3 -funroll-loops -fomit-frame-pointer)
++AC_MSG_NOTICE(Setting LTM_CFLAGS to '$DROPBEAR_LTM_CFLAGS')
++AC_ARG_VAR(LTM_CFLAGS, CFLAGS for bundled libtommath. Defaults to empty string)
+ AC_SUBST(DROPBEAR_LTM_CFLAGS)
+
+ AC_MSG_NOTICE([Checking if compiler '$CC' supports -Wno-pointer-sign])
+--- a/libtomcrypt/src/headers/tomcrypt_dropbear.h
++++ b/libtomcrypt/src/headers/tomcrypt_dropbear.h
+@@ -7,8 +7,10 @@
+
+ /* Use small code where possible */
+ #if DROPBEAR_SMALL_CODE
++#ifndef LTC_SMALL_CODE
+ #define LTC_SMALL_CODE
+ #endif
++#endif
+
+ /* Fewer entries needed */
+ #define TAB_SIZE 5
diff --git a/package/network/services/dropbear/patches/910-signkey-fix-use-of-rsa-sha2-256-pubkeys.patch b/package/network/services/dropbear/patches/910-signkey-fix-use-of-rsa-sha2-256-pubkeys.patch
new file mode 100644
index 0000000..43dd142
--- /dev/null
+++ b/package/network/services/dropbear/patches/910-signkey-fix-use-of-rsa-sha2-256-pubkeys.patch
@@ -0,0 +1,44 @@
+From 667d9b75df86ec9ee1205f9101beb8dbbe4a00ae Mon Sep 17 00:00:00 2001
+From: =?UTF-8?q?Petr=20=C5=A0tetiar?= <ynezz@true.cz>
+Date: Wed, 1 Jul 2020 11:38:33 +0200
+Subject: [PATCH] signkey: fix use of rsa-sha2-256 pubkeys
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+Commit 972d723484d8 ("split signkey_type and signature_type for RSA sha1
+vs sha256") has added strict checking of pubkey algorithms which made
+keys with SHA-256 hashing algorithm unusable as they still reuse the
+`ssh-rsa` public key format. So fix this by disabling the check for
+rsa-sha2-256 pubkeys.
+
+Ref: https://tools.ietf.org/html/rfc8332#section-3
+Fixes: 972d723484d8 ("split signkey_type and signature_type for RSA sha1 vs sha256")
+Signed-off-by: Petr Štetiar <ynezz@true.cz>
+---
+ signkey.c | 8 ++++++--
+ 1 file changed, 6 insertions(+), 2 deletions(-)
+
+--- a/src/signkey.c
++++ b/src/signkey.c
+@@ -652,10 +652,18 @@ int buf_verify(buffer * buf, sign_key *k
+ sigtype = signature_type_from_name(type_name, type_name_len);
+ m_free(type_name);
+
+- if (expect_sigtype != sigtype) {
+- dropbear_exit("Non-matching signing type");
++ if (sigtype == DROPBEAR_SIGNATURE_NONE) {
++ dropbear_exit("No signature type");
+ }
+
++#if DROPBEAR_RSA
++#if DROPBEAR_RSA_SHA256
++ if ((expect_sigtype != DROPBEAR_SIGNATURE_RSA_SHA256) && (expect_sigtype != sigtype)) {
++ dropbear_exit("Non-matching signing type");
++ }
++#endif
++#endif
++
+ keytype = signkey_type_from_signature(sigtype);
+ #if DROPBEAR_DSS
+ if (keytype == DROPBEAR_SIGNKEY_DSS) {