summaryrefslogtreecommitdiff
path: root/Ports/dropbear
diff options
context:
space:
mode:
authorYonatan Goldschmidt <yon.goldschmidt@gmail.com>2020-05-11 00:03:39 +0300
committerAndreas Kling <kling@serenityos.org>2020-05-11 09:50:42 +0200
commitc377e6af2989c4d583fa0e0d3a1e171347535a90 (patch)
treeaa1db3a603645ed2127aef90aab6ce6fd5399761 /Ports/dropbear
parentb03fefd9f861a21f7b6f8c0e028da644ce7dc573 (diff)
downloadserenity-c377e6af2989c4d583fa0e0d3a1e171347535a90.zip
Ports: Add preliminary dropbear port
This is very basic and doesn't support many features. Instead of describing what it *doesn't* support, I'll describe what I have tested: 1. Public key authentication (password is not supported) 2. Single command execution 3. PTY-less interactive bash shell (/bin/sh doesn't work) 4. Multi-user (i.e you can ssh as 'anon' as well as root)
Diffstat (limited to 'Ports/dropbear')
-rwxr-xr-xPorts/dropbear/package.sh16
-rw-r--r--Ports/dropbear/patches/default-options.patch22
-rw-r--r--Ports/dropbear/patches/disable-ssp.patch84
-rw-r--r--Ports/dropbear/patches/fix-autoconf.patch10
-rw-r--r--Ports/dropbear/patches/fix-includes.patch11
-rw-r--r--Ports/dropbear/patches/fopen-c.patch11
-rw-r--r--Ports/dropbear/patches/install-in-bin.patch12
-rw-r--r--Ports/dropbear/patches/netio.patch42
-rw-r--r--Ports/dropbear/patches/remove-nanosleep.patch11
-rw-r--r--Ports/dropbear/patches/remove-reserved-ports.patch14
-rw-r--r--Ports/dropbear/patches/remove-seteuid-setegid.patch96
-rw-r--r--Ports/dropbear/patches/remove-setrlimit.patch12
-rw-r--r--Ports/dropbear/patches/use-dev-random.patch11
-rw-r--r--Ports/dropbear/patches/winsize-remove-pixels.patch30
14 files changed, 382 insertions, 0 deletions
diff --git a/Ports/dropbear/package.sh b/Ports/dropbear/package.sh
new file mode 100755
index 0000000000..93a47183a8
--- /dev/null
+++ b/Ports/dropbear/package.sh
@@ -0,0 +1,16 @@
+#!/bin/bash ../.port_include.sh
+port=dropbear
+version=2019.78
+files="https://matt.ucc.asn.au/dropbear/releases/dropbear-${version}.tar.bz2 dropbear-${version}.tar.bz2
+https://matt.ucc.asn.au/dropbear/releases/dropbear-${version}.tar.bz2.asc dropbear-${version}.tar.bz2.asc
+https://matt.ucc.asn.au/dropbear/releases/dropbear-key-2015.asc dropbear-key-2015.asc"
+
+auth_type="sig"
+auth_opts="--keyring ./dropbear-key-2015.asc dropbear-${version}.tar.bz2.asc"
+useconfigure=true
+# don't care about zlib, less deps is better
+configopts="--disable-zlib "
+# Serenity's utmp is not fully compatible with what dropbear expects.
+configopts+="--disable-utmp --disable-wtmp --disable-login --disable-lastlog "
+# not added automatically
+configopts+="--enable-static"
diff --git a/Ports/dropbear/patches/default-options.patch b/Ports/dropbear/patches/default-options.patch
new file mode 100644
index 0000000000..2ffc868ace
--- /dev/null
+++ b/Ports/dropbear/patches/default-options.patch
@@ -0,0 +1,22 @@
+--- a/default_options.h.orig
++++ b/default_options.h
+@@ -59,8 +59,8 @@
+ #define DROPBEAR_SVR_REMOTETCPFWD 1
+
+ /* Enable Authentication Agent Forwarding */
+-#define DROPBEAR_SVR_AGENTFWD 1
+-#define DROPBEAR_CLI_AGENTFWD 1
++#define DROPBEAR_SVR_AGENTFWD 0
++#define DROPBEAR_CLI_AGENTFWD 0
+
+ /* Note: Both DROPBEAR_CLI_PROXYCMD and DROPBEAR_CLI_NETCAT must be set to
+ * allow multihop dbclient connections */
+@@ -179,7 +179,7 @@
+
+ /* Authentication Types - at least one required.
+ RFC Draft requires pubkey auth, and recommends password */
+-#define DROPBEAR_SVR_PASSWORD_AUTH 1
++#define DROPBEAR_SVR_PASSWORD_AUTH 0
+
+ /* 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).
diff --git a/Ports/dropbear/patches/disable-ssp.patch b/Ports/dropbear/patches/disable-ssp.patch
new file mode 100644
index 0000000000..bf7dd0ae39
--- /dev/null
+++ b/Ports/dropbear/patches/disable-ssp.patch
@@ -0,0 +1,84 @@
+I patch both configure.ac and configure itself (though only configure is required for the build)
+Serenity's GCC doesn't support SSP, so this is disabled.
+--- a/configure.ac.orig
++++ b/configure.ac
+@@ -99,22 +99,7 @@
+ [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="$CFLAGS $TESTFLAGS"
+- AC_COMPILE_IFELSE([AC_LANG_PROGRAM([])],
+- [AC_MSG_NOTICE([Setting $TESTFLAGS])],
+- [
+- CFLAGS="$OLDCFLAGS"
+- TESTFLAGS="-fstack-protector --param=ssp-buffer-size=4"
+- CFLAGS="$CFLAGS $TESTFLAGS"
+- AC_COMPILE_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])
+
+--- a/configure.orig
++++ b/configure
+@@ -3357,53 +3357,7 @@
+ rm -f core conftest.err conftest.$ac_objext \
+ conftest$ac_exeext conftest.$ac_ext
+ fi # non-static
+- # stack protector. -strong is good but only in gcc 4.9 or later
+- OLDCFLAGS="$CFLAGS"
+- TESTFLAGS="-fstack-protector-strong"
+- CFLAGS="$CFLAGS $TESTFLAGS"
+- cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+-/* end confdefs.h. */
+
+-int
+-main ()
+-{
+-
+- ;
+- return 0;
+-}
+-_ACEOF
+-if ac_fn_c_try_compile "$LINENO"; then :
+- { $as_echo "$as_me:${as_lineno-$LINENO}: Setting $TESTFLAGS" >&5
+-$as_echo "$as_me: Setting $TESTFLAGS" >&6;}
+-else
+-
+- CFLAGS="$OLDCFLAGS"
+- TESTFLAGS="-fstack-protector --param=ssp-buffer-size=4"
+- CFLAGS="$CFLAGS $TESTFLAGS"
+- cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+-/* end confdefs.h. */
+-
+-int
+-main ()
+-{
+-
+- ;
+- return 0;
+-}
+-_ACEOF
+-if ac_fn_c_try_compile "$LINENO"; then :
+- { $as_echo "$as_me:${as_lineno-$LINENO}: Setting $TESTFLAGS" >&5
+-$as_echo "$as_me: Setting $TESTFLAGS" >&6;}
+-else
+- { $as_echo "$as_me:${as_lineno-$LINENO}: Not setting $TESTFLAGS" >&5
+-$as_echo "$as_me: Not setting $TESTFLAGS" >&6;}; CFLAGS="$OLDCFLAGS"
+-
+-fi
+-rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+-
+-
+-fi
+-rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+ # FORTIFY_SOURCE
+ {
+ OLDFLAGS="$CFLAGS"
diff --git a/Ports/dropbear/patches/fix-autoconf.patch b/Ports/dropbear/patches/fix-autoconf.patch
new file mode 100644
index 0000000000..d19d9287c1
--- /dev/null
+++ b/Ports/dropbear/patches/fix-autoconf.patch
@@ -0,0 +1,10 @@
+--- a/config.sub.orig
++++ b/config.sub
+@@ -1339,6 +1339,7 @@
+ # Each alternative MUST end in a * to match a version number.
+ # sysv* is not here because it comes later, after sysvr4.
+ gnu* | bsd* | mach* | minix* | genix* | ultrix* | irix* \
++ | serenity* \
+ | *vms* | esix* | aix* | cnk* | sunos | sunos[34]*\
+ | hpux* | unos* | osf* | luna* | dgux* | auroraux* | solaris* \
+ | sym* | kopensolaris* | plan9* \
diff --git a/Ports/dropbear/patches/fix-includes.patch b/Ports/dropbear/patches/fix-includes.patch
new file mode 100644
index 0000000000..f80f9a64df
--- /dev/null
+++ b/Ports/dropbear/patches/fix-includes.patch
@@ -0,0 +1,11 @@
+Not sure why this is missing, but okay.
+--- a/includes.h.orig
++++ b/includes.h
+@@ -38,6 +38,7 @@
+ #include <sys/un.h>
+ #include <sys/wait.h>
+ #include <sys/resource.h>
++#include <sys/select.h>
+
+ #include <stdio.h>
+ #include <errno.h>
diff --git a/Ports/dropbear/patches/fopen-c.patch b/Ports/dropbear/patches/fopen-c.patch
new file mode 100644
index 0000000000..cd76e100a9
--- /dev/null
+++ b/Ports/dropbear/patches/fopen-c.patch
@@ -0,0 +1,11 @@
+--- a/compat.c
++++ b/compat.c
+@@ -244,7 +244,7 @@
+ if (strings != NULL)
+ free(strings);
+ strings = NULL;
+- if ((fp = fopen("/etc/shells", "rc")) == NULL)
++ if ((fp = fopen("/etc/shells", "r")) == NULL)
+ return (char **) okshells;
+ if (fstat(fileno(fp), &statb) == -1) {
+ (void)fclose(fp);
diff --git a/Ports/dropbear/patches/install-in-bin.patch b/Ports/dropbear/patches/install-in-bin.patch
new file mode 100644
index 0000000000..ebd9524113
--- /dev/null
+++ b/Ports/dropbear/patches/install-in-bin.patch
@@ -0,0 +1,12 @@
+Serenity doesn't use /sbin.
+--- a/Makefile.in.orig
++++ b/Makefile.in
+@@ -87,7 +87,7 @@
+ exec_prefix=@exec_prefix@
+ datarootdir = @datarootdir@
+ bindir=@bindir@
+-sbindir=@sbindir@
++sbindir=$(bindir)
+ mandir=@mandir@
+
+ .DELETE_ON_ERROR:
diff --git a/Ports/dropbear/patches/netio.patch b/Ports/dropbear/patches/netio.patch
new file mode 100644
index 0000000000..e423866554
--- /dev/null
+++ b/Ports/dropbear/patches/netio.patch
@@ -0,0 +1,42 @@
+--- b/netio.c.orig
++++ b/netio.c
+@@ -294,7 +294,7 @@
+ buffer *writebuf;
+
+ #ifndef IOV_MAX
+- #if defined(__CYGWIN__) && !defined(UIO_MAXIOV)
++ #if !defined(UIO_MAXIOV)
+ #define IOV_MAX 1024
+ #else
+ #define IOV_MAX UIO_MAXIOV
+@@ -334,11 +334,7 @@
+ }
+
+ void set_sock_nodelay(int sock) {
+- int val;
+-
+- /* disable nagle */
+- val = 1;
+- setsockopt(sock, IPPROTO_TCP, TCP_NODELAY, (void*)&val, sizeof(val));
++ (void)sock;
+ }
+
+ #if DROPBEAR_SERVER_TCP_FAST_OPEN
+@@ -448,7 +444,6 @@
+ struct addrinfo hints, *res = NULL, *res0 = NULL;
+ int err;
+ unsigned int nsock;
+- struct linger linger;
+ int val;
+ int sock;
+
+@@ -527,9 +522,6 @@
+ val = 1;
+ /* set to reuse, quick timeout */
+ setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, (void*) &val, sizeof(val));
+- linger.l_onoff = 1;
+- linger.l_linger = 5;
+- setsockopt(sock, SOL_SOCKET, SO_LINGER, (void*)&linger, sizeof(linger));
+
+ #if defined(IPPROTO_IPV6) && defined(IPV6_V6ONLY)
+ if (res->ai_family == AF_INET6) {
diff --git a/Ports/dropbear/patches/remove-nanosleep.patch b/Ports/dropbear/patches/remove-nanosleep.patch
new file mode 100644
index 0000000000..e0466f46f1
--- /dev/null
+++ b/Ports/dropbear/patches/remove-nanosleep.patch
@@ -0,0 +1,11 @@
+Hinders security by a little, but I guess we'll just have nanosleep soon enough.
+--- a/svr-auth.c.orig
++++ b/svr-auth.c
+@@ -424,7 +424,6 @@
+ if (!fuzz.fuzzing)
+ #endif
+ {
+- while (nanosleep(&delay, &delay) == -1 && errno == EINTR) { /* Go back to sleep */ }
+ }
+
+ ses.authstate.failcount++;
diff --git a/Ports/dropbear/patches/remove-reserved-ports.patch b/Ports/dropbear/patches/remove-reserved-ports.patch
new file mode 100644
index 0000000000..8b2760baab
--- /dev/null
+++ b/Ports/dropbear/patches/remove-reserved-ports.patch
@@ -0,0 +1,14 @@
+--- a/svr-tcpfwd.c.orig
++++ b/svr-tcpfwd.c
+@@ -186,11 +186,6 @@
+ TRACE(("invalid port: %d", port))
+ goto out;
+ }
+-
+- if (!ses.allowprivport && port < IPPORT_RESERVED) {
+- TRACE(("can't assign port < 1024 for non-root"))
+- goto out;
+- }
+ }
+
+ tcpinfo = (struct TCPListener*)m_malloc(sizeof(struct TCPListener));
diff --git a/Ports/dropbear/patches/remove-seteuid-setegid.patch b/Ports/dropbear/patches/remove-seteuid-setegid.patch
new file mode 100644
index 0000000000..d734033171
--- /dev/null
+++ b/Ports/dropbear/patches/remove-seteuid-setegid.patch
@@ -0,0 +1,96 @@
+Dropbear temporarily drops privilliges to make sure the user has access
+to do various actions (e.g access its authorized_keys file).
+Serenity doesn't implement seteuid/setegid, so we can't drop privilliges and
+regain them this way (at least, not that I know it's possible).
+--- a/svr-authpubkey.c.orig
++++ b/svr-authpubkey.c
+@@ -347,25 +347,8 @@
+ snprintf(filename, len + 22, "%s/.ssh/authorized_keys",
+ ses.authstate.pw_dir);
+
+-#if DROPBEAR_SVR_MULTIUSER
+- /* 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");
+- }
+-#endif
+-
+ authfile = fopen(filename, "r");
+
+-#if DROPBEAR_SVR_MULTIUSER
+- if ((seteuid(origuid)) < 0 ||
+- (setegid(origgid)) < 0) {
+- dropbear_exit("Failed to revert euid");
+- }
+-#endif
+-
+ if (authfile == NULL) {
+ goto out;
+ }
+--- a/svr-agentfwd.c.orig
++++ b/svr-agentfwd.c
+@@ -151,17 +151,6 @@
+
+ if (chansess->agentfile != NULL && chansess->agentdir != NULL) {
+
+-#if DROPBEAR_SVR_MULTIUSER
+- /* Remove the dir as the user. That way they can't cause problems except
+- * for themselves */
+- uid = getuid();
+- gid = getgid();
+- if ((setegid(ses.authstate.pw_gid)) < 0 ||
+- (seteuid(ses.authstate.pw_uid)) < 0) {
+- dropbear_exit("Failed to set euid");
+- }
+-#endif
+-
+ /* 2 for "/" and "\0" */
+ len = strlen(chansess->agentdir) + strlen(chansess->agentfile) + 2;
+
+@@ -172,13 +161,6 @@
+
+ rmdir(chansess->agentdir);
+
+-#if DROPBEAR_SVR_MULTIUSER
+- if ((seteuid(uid)) < 0 ||
+- (setegid(gid)) < 0) {
+- dropbear_exit("Failed to revert euid");
+- }
+-#endif
+-
+ m_free(chansess->agentfile);
+ m_free(chansess->agentdir);
+ }
+@@ -220,16 +202,6 @@
+ gid_t gid;
+ int ret = DROPBEAR_FAILURE;
+
+-#if DROPBEAR_SVR_MULTIUSER
+- /* drop to user privs to make the dir/file */
+- uid = getuid();
+- gid = getgid();
+- if ((setegid(ses.authstate.pw_gid)) < 0 ||
+- (seteuid(ses.authstate.pw_uid)) < 0) {
+- dropbear_exit("Failed to set euid");
+- }
+-#endif
+-
+ memset((void*)&addr, 0x0, sizeof(addr));
+ addr.sun_family = AF_UNIX;
+
+@@ -268,12 +240,6 @@
+
+
+ out:
+-#if DROPBEAR_SVR_MULTIUSER
+- if ((seteuid(uid)) < 0 ||
+- (setegid(gid)) < 0) {
+- dropbear_exit("Failed to revert euid");
+- }
+-#endif
+ return ret;
+ }
+ \ No newline at end of file
diff --git a/Ports/dropbear/patches/remove-setrlimit.patch b/Ports/dropbear/patches/remove-setrlimit.patch
new file mode 100644
index 0000000000..6537111ba8
--- /dev/null
+++ b/Ports/dropbear/patches/remove-setrlimit.patch
@@ -0,0 +1,12 @@
+--- a/dbutil.c.orig
++++ b/dbutil.c
+@@ -553,9 +553,6 @@
+ }
+
+ void disallow_core() {
+- struct rlimit lim;
+- lim.rlim_cur = lim.rlim_max = 0;
+- setrlimit(RLIMIT_CORE, &lim);
+ }
+
+ /* Returns DROPBEAR_SUCCESS or DROPBEAR_FAILURE, with the result in *val */
diff --git a/Ports/dropbear/patches/use-dev-random.patch b/Ports/dropbear/patches/use-dev-random.patch
new file mode 100644
index 0000000000..3f412b6820
--- /dev/null
+++ b/Ports/dropbear/patches/use-dev-random.patch
@@ -0,0 +1,11 @@
+--- a/sysoptions.h
++++ b/sysoptions.h
+@@ -256,7 +256,7 @@
+ /* Source for randomness. This must be able to provide hundreds of bytes per SSH
+ * connection without blocking. */
+ #ifndef DROPBEAR_URANDOM_DEV
+-#define DROPBEAR_URANDOM_DEV "/dev/urandom"
++#define DROPBEAR_URANDOM_DEV "/dev/random"
+ #endif
+
+ /* client keyboard interactive authentication is often used for password auth.
diff --git a/Ports/dropbear/patches/winsize-remove-pixels.patch b/Ports/dropbear/patches/winsize-remove-pixels.patch
new file mode 100644
index 0000000000..97212e1c4d
--- /dev/null
+++ b/Ports/dropbear/patches/winsize-remove-pixels.patch
@@ -0,0 +1,30 @@
+--- a/sshpty.c.orig
++++ b/sshpty.c
+@@ -347,8 +347,6 @@
+
+ w.ws_row = row;
+ w.ws_col = col;
+- w.ws_xpixel = xpixel;
+- w.ws_ypixel = ypixel;
+ (void) ioctl(ptyfd, TIOCSWINSZ, &w);
+ }
+
+--- a/cli-chansession.c.orig
++++ b/cli-chansession.c
+@@ -234,14 +234,12 @@
+ /* Some sane defaults */
+ ws.ws_row = 25;
+ ws.ws_col = 80;
+- ws.ws_xpixel = 0;
+- ws.ws_ypixel = 0;
+ }
+
+ buf_putint(ses.writepayload, ws.ws_col); /* Cols */
+ buf_putint(ses.writepayload, ws.ws_row); /* Rows */
+- buf_putint(ses.writepayload, ws.ws_xpixel); /* Width */
+- buf_putint(ses.writepayload, ws.ws_ypixel); /* Height */
++ buf_putint(ses.writepayload, 0); /* Width */
++ buf_putint(ses.writepayload, 0); /* Height */
+
+ }
+