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)
This commit is contained in:
Yonatan Goldschmidt 2020-05-11 00:03:39 +03:00 committed by Andreas Kling
parent b03fefd9f8
commit c377e6af29
Notes: sideshowbarker 2024-07-19 06:44:06 +09:00
16 changed files with 384 additions and 1 deletions

View file

@ -86,6 +86,7 @@ chmod 400 mnt/res/kernel.map
chmod 660 mnt/etc/WindowServer/WindowServer.ini
chown $window_uid:$window_gid mnt/etc/WindowServer/WindowServer.ini
echo "/bin/sh" > mnt/etc/shells
echo "done"

View file

@ -116,7 +116,7 @@ else
$SERENITY_COMMON_QEMU_ARGS \
$SERENITY_KVM_ARG \
$SERENITY_PACKET_LOGGING_ARG \
-netdev user,id=breh,hostfwd=tcp:127.0.0.1:8888-10.0.2.15:8888,hostfwd=tcp:127.0.0.1:8823-10.0.2.15:23,hostfwd=tcp:127.0.0.1:8000-10.0.2.15:8000 \
-netdev user,id=breh,hostfwd=tcp:127.0.0.1:8888-10.0.2.15:8888,hostfwd=tcp:127.0.0.1:8823-10.0.2.15:23,hostfwd=tcp:127.0.0.1:8000-10.0.2.15:8000,hostfwd=tcp:127.0.0.1:2222-10.0.2.15:22 \
-device e1000,netdev=breh \
-kernel kernel \
-append "${SERENITY_KERNEL_CMDLINE}"

16
Ports/dropbear/package.sh Executable file
View file

@ -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"

View file

@ -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).

View file

@ -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"

View file

@ -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* \

View file

@ -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>

View file

@ -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);

View file

@ -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:

View file

@ -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) {

View file

@ -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++;

View file

@ -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));

View file

@ -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;
}

View file

@ -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 */

View file

@ -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.

View file

@ -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 */
}