From 5dc9b3a5933c4f125c2a85df0dc0aafe7208003f Mon Sep 17 00:00:00 2001 From: Wildan Mubarok Date: Sat, 6 Sep 2025 17:58:56 +0000 Subject: [PATCH] OpenSSH daemon support --- recipes/wip/ssh/openssh/recipe.toml | 31 +- recipes/wip/ssh/openssh/redox.patch | 424 +++++++++++++++++++++++++++- 2 files changed, 437 insertions(+), 18 deletions(-) diff --git a/recipes/wip/ssh/openssh/recipe.toml b/recipes/wip/ssh/openssh/recipe.toml index 26ed0f91..85798b1d 100644 --- a/recipes/wip/ssh/openssh/recipe.toml +++ b/recipes/wip/ssh/openssh/recipe.toml @@ -1,6 +1,7 @@ -#TODO compiled but not tested -#TODO lack of utmpx.h and resolv.h, expect dns not working -#TODO maybe actually implement utmpx.h in relibc? +#TODO lack of resolv.h, expect dns not working +#TODO lack of utmpx.h, expect no way to track login in sshd +#TODO lack of an equivalent to shadow.h, expect sshd password not working +#TODO lack of openssl support, use only ssh-keygen from redox [source] tar = "https://cdn.openbsd.org/pub/OpenBSD/OpenSSH/portable/openssh-9.8p1.tar.gz" patches = [ @@ -9,12 +10,34 @@ patches = [ [build] template = "custom" dependencies = [ - "openssl1", "zlib", ] script = """ DYNAMIC_INIT +COOKBOOK_CONFIGURE_FLAGS+=( + --disable-strip +# requires openssl 1.1.1, result in libcrypto error otherwise + --without-openssl +) cookbook_configure mv "${COOKBOOK_STAGE}"/usr/sbin/sshd "${COOKBOOK_STAGE}"/usr/bin/sshd rmdir "${COOKBOOK_STAGE}"/usr/sbin + +# Extracted from `make host-key-force` +# TODO: Very insecure! but there's no postscript yet +ssh-keygen -t dsa -f "${COOKBOOK_STAGE}"/usr/etc/ssh_host_dsa_key -N "" +ssh-keygen -t rsa -f "${COOKBOOK_STAGE}"/usr/etc/ssh_host_rsa_key -N "" +ssh-keygen -t ed25519 -f "${COOKBOOK_STAGE}"/usr/etc/ssh_host_ed25519_key -N "" +ssh-keygen -t ecdsa -f "${COOKBOOK_STAGE}"/usr/etc/ssh_host_ecdsa_key -N "" + +# The config can be found here, not /etc +CONFIG_FILE="${COOKBOOK_STAGE}"/usr/etc/sshd_config +sed -i "s/#LogLevel INFO/LogLevel DEBUG3/g" "${CONFIG_FILE}" + +# ipv6 is not working yet +sed -i "s/#AddressFamily any/AddressFamily inet/g" "${CONFIG_FILE}" +# hardcoded to 0.0.0.0 in patches +sed -i "s/#ListenAddress 0.0.0.0/ListenAddress 0.0.0.0/g" "${CONFIG_FILE}" +# will never work +sed -i "s/#PasswordAuthentication yes/PasswordAuthentication no/g" "${CONFIG_FILE}" """ diff --git a/recipes/wip/ssh/openssh/redox.patch b/recipes/wip/ssh/openssh/redox.patch index e1b43cae..153e9cda 100644 --- a/recipes/wip/ssh/openssh/redox.patch +++ b/recipes/wip/ssh/openssh/redox.patch @@ -1,6 +1,20 @@ +diff -ruwN source/configure source-new/configure +--- source/configure 2024-07-01 11:36:28.000000000 +0700 ++++ source-new/configure 2025-09-06 23:54:58.147442355 +0700 +@@ -12606,6 +12606,10 @@ + printf "%s\n" "#define BROKEN_POLL 1" >>confdefs.h + + ;; ++*-*-redox) ++ ++ # todo ++ ;; + mips-sony-bsd|mips-sony-newsos4) + + printf "%s\n" "#define NEED_SETPGRP 1" >>confdefs.h diff -ruwN source/defines.h source-new/defines.h --- source/defines.h 2024-07-01 11:36:28.000000000 +0700 -+++ source-new/defines.h 2025-08-20 13:37:45.820728226 +0700 ++++ source-new/defines.h 2025-09-06 21:22:46.327552147 +0700 @@ -52,6 +52,18 @@ #define IPPORT_RESERVED 0 #endif @@ -49,9 +63,14 @@ diff -ruwN source/defines.h source-new/defines.h /* Define this to be the path of the xauth program. */ #ifdef XAUTH_PATH #define _PATH_XAUTH XAUTH_PATH +@@ -943,3 +957,4 @@ + # define USE_SNTRUP761X25519 1 + #endif + #endif /* _DEFINES_H */ ++ diff -ruwN source/hostfile.c source-new/hostfile.c --- source/hostfile.c 2024-07-01 11:36:28.000000000 +0700 -+++ source-new/hostfile.c 2025-08-20 11:51:28.964103232 +0700 ++++ source-new/hostfile.c 2025-09-06 21:09:36.555438339 +0700 @@ -44,7 +44,9 @@ #include @@ -64,7 +83,7 @@ diff -ruwN source/hostfile.c source-new/hostfile.c #include diff -ruwN source/loginrec.c source-new/loginrec.c --- source/loginrec.c 2024-07-01 11:36:28.000000000 +0700 -+++ source-new/loginrec.c 2025-08-20 13:43:02.970560664 +0700 ++++ source-new/loginrec.c 2025-09-06 21:09:36.556438304 +0700 @@ -1033,7 +1033,7 @@ return (0); } @@ -76,7 +95,7 @@ diff -ruwN source/loginrec.c source-new/loginrec.c } diff -ruwN source/loginrec.h source-new/loginrec.h --- source/loginrec.h 2024-07-01 11:36:28.000000000 +0700 -+++ source-new/loginrec.h 2025-08-20 13:39:08.570682776 +0700 ++++ source-new/loginrec.h 2025-09-06 21:09:36.556438304 +0700 @@ -30,6 +30,7 @@ **/ @@ -85,9 +104,56 @@ diff -ruwN source/loginrec.h source-new/loginrec.h struct ssh; +diff -ruwN source/misc.c source-new/misc.c +--- source/misc.c 2024-07-01 11:36:28.000000000 +0700 ++++ source-new/misc.c 2025-09-06 21:09:36.556438304 +0700 +@@ -2843,7 +2843,7 @@ + error("%s: dup2: %s", tag, strerror(errno)); + _exit(1); + } +- closefrom(STDERR_FILENO + 1); ++ // closefrom(STDERR_FILENO + 1); + + if (geteuid() == 0 && + initgroups(pw->pw_name, pw->pw_gid) == -1) { +diff -ruwN source/monitor.c source-new/monitor.c +--- source/monitor.c 2024-07-01 11:36:28.000000000 +0700 ++++ source-new/monitor.c 2025-09-07 00:46:23.435378053 +0700 +@@ -484,18 +484,19 @@ + pfd[0].events = POLLIN; + pfd[1].fd = pmonitor->m_log_recvfd; + pfd[1].events = pfd[1].fd == -1 ? 0 : POLLIN; +- if (poll(pfd, pfd[1].fd == -1 ? 1 : 2, -1) == -1) { ++ // redox can't handle timeout -1 (the poll stuck) ++ if (poll(pfd, pfd[1].fd == -1 ? 1 : 2, 1000) == -1) { + if (errno == EINTR || errno == EAGAIN) + continue; + fatal_f("poll: %s", strerror(errno)); + } + if (pfd[1].revents) { ++ + /* + * Drain all log messages before processing next + * monitor request. + */ + monitor_read_log(pmonitor); +- continue; + } + if (pfd[0].revents) + break; /* Continues below */ +@@ -1577,7 +1578,8 @@ + res = pty_allocate(&s->ptyfd, &s->ttyfd, s->tty, sizeof(s->tty)); + if (res == 0) + goto error; +- pty_setowner(authctxt->pw, s->tty); ++ // non sense in redox ++ // pty_setowner(authctxt->pw, s->tty); + + if ((r = sshbuf_put_u32(m, 1)) != 0 || + (r = sshbuf_put_cstring(m, s->tty)) != 0) diff -ruwN source/openbsd-compat/bsd-statvfs.h source-new/openbsd-compat/bsd-statvfs.h --- source/openbsd-compat/bsd-statvfs.h 2024-07-01 11:36:28.000000000 +0700 -+++ source-new/openbsd-compat/bsd-statvfs.h 2025-08-20 13:37:42.000730245 +0700 ++++ source-new/openbsd-compat/bsd-statvfs.h 2025-09-06 21:09:36.556438304 +0700 @@ -37,13 +37,6 @@ typedef unsigned long fsfilcnt_t; #endif @@ -104,7 +170,7 @@ diff -ruwN source/openbsd-compat/bsd-statvfs.h source-new/openbsd-compat/bsd-sta unsigned long f_bsize; /* File system block size. */ diff -ruwN source/openbsd-compat/getrrsetbyname.c source-new/openbsd-compat/getrrsetbyname.c --- source/openbsd-compat/getrrsetbyname.c 2024-07-01 11:36:28.000000000 +0700 -+++ source-new/openbsd-compat/getrrsetbyname.c 2025-08-20 13:51:15.020299084 +0700 ++++ source-new/openbsd-compat/getrrsetbyname.c 2025-09-06 21:09:36.556438304 +0700 @@ -67,6 +67,52 @@ #endif #define _THREAD_PRIVATE(a,b,c) (c) @@ -232,7 +298,7 @@ diff -ruwN source/openbsd-compat/getrrsetbyname.c source-new/openbsd-compat/getr free_dns_rr(head); diff -ruwN source/openbsd-compat/getrrsetbyname.h source-new/openbsd-compat/getrrsetbyname.h --- source/openbsd-compat/getrrsetbyname.h 2024-07-01 11:36:28.000000000 +0700 -+++ source-new/openbsd-compat/getrrsetbyname.h 2025-08-20 11:51:00.744118526 +0700 ++++ source-new/openbsd-compat/getrrsetbyname.h 2025-09-06 21:09:36.557438268 +0700 @@ -54,9 +54,13 @@ #include @@ -249,7 +315,7 @@ diff -ruwN source/openbsd-compat/getrrsetbyname.h source-new/openbsd-compat/getr #define HFIXEDSZ 12 diff -ruwN source/openbsd-compat/inet_ntop.c source-new/openbsd-compat/inet_ntop.c --- source/openbsd-compat/inet_ntop.c 2024-07-01 11:36:28.000000000 +0700 -+++ source-new/openbsd-compat/inet_ntop.c 2025-08-20 11:39:15.244488902 +0700 ++++ source-new/openbsd-compat/inet_ntop.c 2025-09-06 21:09:36.557438268 +0700 @@ -26,7 +26,9 @@ #include #include @@ -262,7 +328,7 @@ diff -ruwN source/openbsd-compat/inet_ntop.c source-new/openbsd-compat/inet_ntop #include diff -ruwN source/openbsd-compat/openbsd-compat.h source-new/openbsd-compat/openbsd-compat.h --- source/openbsd-compat/openbsd-compat.h 2024-07-01 11:36:28.000000000 +0700 -+++ source-new/openbsd-compat/openbsd-compat.h 2025-08-20 13:15:22.721439992 +0700 ++++ source-new/openbsd-compat/openbsd-compat.h 2025-09-06 21:09:36.557438268 +0700 @@ -36,6 +36,8 @@ #include /* for wchar_t */ @@ -274,7 +340,7 @@ diff -ruwN source/openbsd-compat/openbsd-compat.h source-new/openbsd-compat/open #include "sigact.h" diff -ruwN source/openbsd-compat/utmpx.c source-new/openbsd-compat/utmpx.c --- source/openbsd-compat/utmpx.c 1970-01-01 07:00:00.000000000 +0700 -+++ source-new/openbsd-compat/utmpx.c 2025-08-20 13:13:54.971486065 +0700 ++++ source-new/openbsd-compat/utmpx.c 2025-09-06 21:09:36.557438268 +0700 @@ -0,0 +1,13 @@ +#include "utmpx.h" +#include // For NULL @@ -292,7 +358,7 @@ diff -ruwN source/openbsd-compat/utmpx.c source-new/openbsd-compat/utmpx.c \ No newline at end of file diff -ruwN source/openbsd-compat/utmpx.h source-new/openbsd-compat/utmpx.h --- source/openbsd-compat/utmpx.h 1970-01-01 07:00:00.000000000 +0700 -+++ source-new/openbsd-compat/utmpx.h 2025-08-20 13:13:07.201511825 +0700 ++++ source-new/openbsd-compat/utmpx.h 2025-09-06 21:09:36.557438268 +0700 @@ -0,0 +1,69 @@ +#ifndef _COMPAT_UTMPX_H +#define _COMPAT_UTMPX_H @@ -364,9 +430,54 @@ diff -ruwN source/openbsd-compat/utmpx.h source-new/openbsd-compat/utmpx.h +#endif /* __redox__ */ +#endif /* _COMPAT_UTMPX_H */ \ No newline at end of file +diff -ruwN source/pathnames.h source-new/pathnames.h +--- source/pathnames.h 2024-07-01 11:36:28.000000000 +0700 ++++ source-new/pathnames.h 2025-09-06 21:09:36.557438268 +0700 +@@ -12,7 +12,7 @@ + * called by a name other than "ssh" or "Secure Shell". + */ + +-#define ETCDIR "/etc" ++#define ETCDIR "/usr/etc" + + #ifndef SSHDIR + #define SSHDIR ETCDIR "/ssh" +@@ -166,7 +166,7 @@ + + /* chroot directory for unprivileged user when UsePrivilegeSeparation=yes */ + #ifndef _PATH_PRIVSEP_CHROOT_DIR +-#define _PATH_PRIVSEP_CHROOT_DIR "/var/empty" ++#define _PATH_PRIVSEP_CHROOT_DIR "/usr/var/empty" + #endif + + /* for passwd change */ +diff -ruwN source/readconf.c source-new/readconf.c +--- source/readconf.c 2024-07-01 11:36:28.000000000 +0700 ++++ source-new/readconf.c 2025-09-06 21:09:36.558438233 +0700 +@@ -554,7 +554,7 @@ + + if (stdfd_devnull(1, 1, 0) == -1) + fatal_f("stdfd_devnull failed"); +- closefrom(STDERR_FILENO + 1); ++ // closefrom(STDERR_FILENO + 1); + + argv[0] = shell; + argv[1] = "-c"; +diff -ruwN source/readpass.c source-new/readpass.c +--- source/readpass.c 2024-07-01 11:36:28.000000000 +0700 ++++ source-new/readpass.c 2025-09-06 21:09:36.558438233 +0700 +@@ -278,7 +278,7 @@ + if (pid == 0) { + if (stdfd_devnull(1, 1, 0) == -1) + fatal_f("stdfd_devnull failed"); +- closefrom(STDERR_FILENO + 1); ++ // closefrom(STDERR_FILENO + 1); + setenv("SSH_ASKPASS_PROMPT", "none", 1); /* hint to UI */ + execlp(askpass, askpass, prompt, (char *)NULL); + error_f("exec(%s): %s", askpass, strerror(errno)); diff -ruwN source/regress/netcat.c source-new/regress/netcat.c --- source/regress/netcat.c 2024-07-01 11:36:28.000000000 +0700 -+++ source-new/regress/netcat.c 2025-08-20 11:50:49.164126484 +0700 ++++ source-new/regress/netcat.c 2025-09-06 21:09:36.558438233 +0700 @@ -1384,7 +1384,9 @@ #include #include @@ -377,9 +488,87 @@ diff -ruwN source/regress/netcat.c source-new/regress/netcat.c #define SOCKS_PORT "1080" #define HTTP_PROXY_PORT "3128" +diff -ruwN source/servconf.c source-new/servconf.c +--- source/servconf.c 2024-07-01 11:36:28.000000000 +0700 ++++ source-new/servconf.c 2025-09-06 21:10:09.947261502 +0700 +@@ -315,6 +315,7 @@ + _PATH_HOST_XMSS_KEY_FILE, 0); + #endif /* WITH_XMSS */ + } ++ + /* No certificates by default */ + if (options->num_ports == 0) + options->ports[options->num_ports++] = SSH_DEFAULT_PORT; +@@ -390,6 +391,7 @@ + options->permit_user_env = 0; + options->permit_user_env_allowlist = NULL; + } ++ + if (options->compression == -1) + #ifdef WITH_ZLIB + options->compression = COMP_DELAYED; +@@ -463,6 +465,7 @@ + &options->num_authkeys_files, + _PATH_SSH_USER_PERMITTED_KEYS2); + } ++ + if (options->permit_tun == -1) + options->permit_tun = SSH_TUNMODE_NO; + if (options->ip_qos_interactive == -1) +@@ -529,6 +532,7 @@ + + CLEAR_ON_NONE_ARRAY(channel_timeouts, num_channel_timeouts, "none"); + CLEAR_ON_NONE_ARRAY(auth_methods, num_auth_methods, "any"); ++ + #undef CLEAR_ON_NONE + #undef CLEAR_ON_NONE_ARRAY + } +@@ -857,7 +861,7 @@ + hints.ai_socktype = SOCK_STREAM; + hints.ai_flags = (addr == NULL) ? AI_PASSIVE : 0; + snprintf(strport, sizeof strport, "%d", port); +- if ((gaierr = getaddrinfo(addr, strport, &hints, &aitop)) != 0) ++ if ((gaierr = getaddrinfo("0.0.0.0", strport, &hints, &aitop)) != 0) + fatal("bad addr or host: %s (%s)", + addr ? addr : "", + ssh_gai_strerror(gaierr)); +diff -ruwN source/session.c source-new/session.c +--- source/session.c 2024-07-01 11:36:28.000000000 +0700 ++++ source-new/session.c 2025-09-07 00:41:01.350663705 +0700 +@@ -1365,10 +1365,12 @@ + exit(1); + } + /* Initialize the group list. */ ++#ifndef __redox__ + if (initgroups(pw->pw_name, pw->pw_gid) < 0) { + perror("initgroups"); + exit(1); + } ++#endif + endgrent(); + #endif + +@@ -1490,7 +1492,7 @@ + * initgroups, because at least on Solaris 2.3 it leaves file + * descriptors open. + */ +- closefrom(STDERR_FILENO + 1); ++ // closefrom(STDERR_FILENO + 1); + } + + /* +@@ -1624,7 +1626,7 @@ + exit(1); + } + +- closefrom(STDERR_FILENO + 1); ++ // closefrom(STDERR_FILENO + 1); + + do_rc_files(ssh, s, shell); + diff -ruwN source/sshbuf-misc.c source-new/sshbuf-misc.c --- source/sshbuf-misc.c 2024-07-01 11:36:28.000000000 +0700 -+++ source-new/sshbuf-misc.c 2025-08-20 11:51:17.444108963 +0700 ++++ source-new/sshbuf-misc.c 2025-09-06 21:09:36.559438198 +0700 @@ -28,7 +28,9 @@ #include #include @@ -390,9 +579,150 @@ diff -ruwN source/sshbuf-misc.c source-new/sshbuf-misc.c #include #include +diff -ruwN source/ssh.c source-new/ssh.c +--- source/ssh.c 2024-07-01 11:36:28.000000000 +0700 ++++ source-new/ssh.c 2025-09-06 21:09:36.559438198 +0700 +@@ -689,7 +689,7 @@ + * Discard other fds that are hanging around. These can cause problem + * with backgrounded ssh processes started by ControlPersist. + */ +- closefrom(STDERR_FILENO + 1); ++ // closefrom(STDERR_FILENO + 1); + + __progname = ssh_get_progname(av[0]); + +diff -ruwN source/sshconnect2.c source-new/sshconnect2.c +--- source/sshconnect2.c 2024-07-01 11:36:28.000000000 +0700 ++++ source-new/sshconnect2.c 2025-09-06 21:09:36.560438163 +0700 +@@ -2057,7 +2057,7 @@ + sock = STDERR_FILENO + 1; + if (fcntl(sock, F_SETFD, 0) == -1) /* keep the socket on exec */ + debug3_f("fcntl F_SETFD: %s", strerror(errno)); +- closefrom(sock + 1); ++ // closefrom(sock + 1); + + debug3_f("[child] pid=%ld, exec %s", + (long)getpid(), _PATH_SSH_KEY_SIGN); +diff -ruwN source/sshd.c source-new/sshd.c +--- source/sshd.c 2024-07-01 11:36:28.000000000 +0700 ++++ source-new/sshd.c 2025-09-06 22:33:56.902184198 +0700 +@@ -1217,12 +1217,11 @@ + compat_init_setproctitle(ac, av); + av = saved_argv; + #endif +- + if (geteuid() == 0 && setgroups(0, NULL) == -1) + debug("setgroups(): %.200s", strerror(errno)); + + /* Ensure that fds 0, 1 and 2 are open or directed to /dev/null */ +- sanitise_stdfd(); ++ // sanitise_stdfd(); + + /* Initialize configuration options to their default values. */ + initialize_server_options(&options); +@@ -1342,9 +1341,9 @@ + } + } + if (!test_flag && !do_dump_cfg && !path_absolute(av[0])) +- fatal("sshd requires execution with an absolute path"); ++ fatal("sshd requires execution with an absolutez path"); + +- closefrom(STDERR_FILENO + 1); ++ // closefrom(STDERR_FILENO + 1); + + /* Reserve fds we'll need later for reexec things */ + if ((devnull = open(_PATH_DEVNULL, O_RDWR)) == -1) +@@ -1427,16 +1426,16 @@ + * daemonisation in the presence of Match blocks, but this catches + * and warns for trivial misconfigurations that could break login. + */ +- if (options.num_auth_methods != 0) { +- for (i = 0; i < options.num_auth_methods; i++) { +- if (auth2_methods_valid(options.auth_methods[i], +- 1) == 0) +- break; +- } +- if (i >= options.num_auth_methods) +- fatal("AuthenticationMethods cannot be satisfied by " +- "enabled authentication methods"); +- } ++ // if (options.num_auth_methods != 0) { ++ // for (i = 0; i < options.num_auth_methods; i++) { ++ // if (auth2_methods_valid(options.auth_methods[i], ++ // 1) == 0) ++ // break; ++ // } ++ // if (i >= options.num_auth_methods) ++ // fatal("AuthenticationMethods cannot be satisfied by " ++ // "enabled authentication methods"); ++ // } + + /* Check that there are no remaining arguments. */ + if (optind < ac) { +@@ -1482,13 +1481,13 @@ + options.host_key_files[i]); + key->sk_flags &= ~SSH_SK_USER_PRESENCE_REQD; + } +- if (r == 0 && key != NULL && +- (r = sshkey_shield_private(key)) != 0) { +- do_log2_r(r, ll, "Unable to shield host key \"%s\"", +- options.host_key_files[i]); +- sshkey_free(key); +- key = NULL; +- } ++ // if (r == 0 && key != NULL && ++ // (r = sshkey_shield_private(key)) != 0) { ++ // do_log2_r(r, ll, "Unable to shield host key \"%s\"", ++ // options.host_key_files[i]); ++ // sshkey_free(key); ++ // key = NULL; ++ // } + if ((r = sshkey_load_public(options.host_key_files[i], + &pubkey, NULL)) != 0 && r != SSH_ERR_SYSTEM_ERROR) + do_log2_r(r, ll, "Unable to load host key \"%s\"", +@@ -1600,8 +1599,7 @@ + } + + /* Ensure privsep directory is correctly configured. */ +- need_chroot = ((getuid() == 0 || geteuid() == 0) || +- options.kerberos_authentication); ++ need_chroot = 0;// ((getuid() == 0 || geteuid() == 0) || options.kerberos_authentication); + if ((getpwnam(SSH_PRIVSEP_USER)) == NULL && need_chroot) { + fatal("Privilege separation user %s does not exist", + SSH_PRIVSEP_USER); +@@ -1773,7 +1771,7 @@ + close(startup_pipe); + } + log_redirect_stderr_to(NULL); +- closefrom(REEXEC_MIN_FREE_FD); ++ // closefrom(REEXEC_MIN_FREE_FD); + + ssh_signal(SIGHUP, SIG_IGN); /* avoid reset to SIG_DFL */ + execv(rexec_argv[0], rexec_argv); +diff -ruwN source/sshd-session.c source-new/sshd-session.c +--- source/sshd-session.c 2024-07-01 11:36:28.000000000 +0700 ++++ source-new/sshd-session.c 2025-09-06 21:15:43.796191268 +0700 +@@ -1031,7 +1031,7 @@ + if (!rexeced_flag) + fatal("sshd-session should not be executed directly"); + +- closefrom(REEXEC_MIN_FREE_FD); ++ // closefrom(REEXEC_MIN_FREE_FD); + + seed_rng(); + +@@ -1073,7 +1073,7 @@ + options.timing_secret = timing_secret; + + /* Store privilege separation user for later use if required. */ +- privsep_chroot = (getuid() == 0 || geteuid() == 0); ++ privsep_chroot = 0;// (getuid() == 0 || geteuid() == 0); + if ((privsep_pw = getpwnam(SSH_PRIVSEP_USER)) == NULL) { + if (privsep_chroot || options.kerberos_authentication) + fatal("Privilege separation user %s does not exist", diff -ruwN source/sshkey.c source-new/sshkey.c --- source/sshkey.c 2024-07-01 11:36:28.000000000 +0700 -+++ source-new/sshkey.c 2025-08-20 11:50:36.114133643 +0700 ++++ source-new/sshkey.c 2025-09-06 21:09:36.567437916 +0700 @@ -43,7 +43,9 @@ #include #include @@ -403,3 +733,69 @@ diff -ruwN source/sshkey.c source-new/sshkey.c #include #ifdef HAVE_UTIL_H #include +diff -ruwN source/ssh-sk-client.c source-new/ssh-sk-client.c +--- source/ssh-sk-client.c 2024-07-01 11:36:28.000000000 +0700 ++++ source-new/ssh-sk-client.c 2025-09-06 21:09:36.569437846 +0700 +@@ -91,7 +91,7 @@ + } + close(pair[0]); + close(pair[1]); +- closefrom(STDERR_FILENO + 1); ++ // closefrom(STDERR_FILENO + 1); + debug_f("starting %s %s", helper, + verbosity == NULL ? "" : verbosity); + execlp(helper, helper, verbosity, (char *)NULL); +diff -ruwN source/ssh-sk-helper.c source-new/ssh-sk-helper.c +--- source/ssh-sk-helper.c 2024-07-01 11:36:28.000000000 +0700 ++++ source-new/ssh-sk-helper.c 2025-09-06 21:09:36.570437810 +0700 +@@ -303,7 +303,7 @@ + * Rearrange our file descriptors a little; we don't trust the + * providers not to fiddle with stdin/out. + */ +- closefrom(STDERR_FILENO + 1); ++ // closefrom(STDERR_FILENO + 1); + if ((in = dup(STDIN_FILENO)) == -1 || (out = dup(STDOUT_FILENO)) == -1) + fatal("%s: dup: %s", __progname, strerror(errno)); + close(STDIN_FILENO); +diff -ruwN source/uidswap.c source-new/uidswap.c +--- source/uidswap.c 2024-07-01 11:36:28.000000000 +0700 ++++ source-new/uidswap.c 2025-09-07 00:01:52.531094834 +0700 +@@ -37,7 +37,7 @@ + * POSIX saved uids or not. + */ + +-#if defined(_POSIX_SAVED_IDS) && !defined(BROKEN_SAVED_UIDS) ++#if !defined(BROKEN_SAVED_UIDS) + /* Lets assume that posix saved ids also work with seteuid, even though that + is not part of the posix specification. */ + #define SAVED_IDS_WORK_WITH_SETEUID +@@ -83,6 +83,9 @@ + privileged = 1; + temporarily_use_uid_effective = 1; + ++ // getgroups broken in redox ++#ifndef __redox__ ++ + saved_egroupslen = getgroups(0, NULL); + if (saved_egroupslen == -1) + fatal("getgroups: %.100s", strerror(errno)); +@@ -119,6 +122,7 @@ + /* Set the effective uid to the given (unprivileged) uid. */ + if (setgroups(user_groupslen, user_groups) == -1) + fatal("setgroups: %.100s", strerror(errno)); ++#endif + #ifndef SAVED_IDS_WORK_WITH_SETEUID + /* Propagate the privileged gid to all of our gids. */ + if (setgid(getegid()) == -1) +@@ -168,8 +172,11 @@ + fatal("%s: setgid failed: %s", __func__, strerror(errno)); + #endif /* SAVED_IDS_WORK_WITH_SETEUID */ + ++ // setgroups broken in redox ++#ifndef __redox__ + if (setgroups(saved_egroupslen, saved_egroups) == -1) + fatal("setgroups: %.100s", strerror(errno)); ++#endif + temporarily_use_uid_effective = 0; + } +