liminix

Unnamed repository; edit this file 'description' to name the repository.
Log | Files | Refs | README | LICENSE

commit 7f23c5dc0f442de9fe07c076297c3a74f2a34e72
parent c364095c441d8891ac8d942261eccf3fd24b5423
Author: Daniel Barlow <dan@telent.net>
Date:   Wed, 11 Mar 2026 18:22:39 +0000

update dropbear, simplify authorized_keys patch

Diffstat:
Moverlay.nix | 21+++------------------
Mpkgs/dropbear/add-authkeyfile-option.patch | 216+++++++++++--------------------------------------------------------------------
2 files changed, 33 insertions(+), 204 deletions(-)

diff --git a/overlay.nix b/overlay.nix @@ -167,24 +167,9 @@ extraPkgs dropbear = crossOnly prev.dropbear ( d: d.overrideAttrs (o: rec { - # nixpkgs 25.05 contains newer dropbear (2025.87) than this, - # we can drop this override when that's ready - version = "2024.85"; - src = final.fetchurl { - url = "https://matt.ucc.asn.au/dropbear/releases/dropbear-${version}.tar.bz2"; - sha256 = "sha256-hrA2xDOmnYnOUeuuM11lxHc4zPkNE+XrD+qDLlVtpQI="; - }; - patches = - # in 24.11 we need to update nixpkgs patch for new version of dropbear - let - passPath = final.runCommand "pass-path" { } '' - sed < ${builtins.head o.patches} -e 's,svr-chansession.c,src/svr-chansession.c,g' > $out - ''; - in - [ - (if (lib.versionOlder o.version "2024") then passPath else (builtins.head o.patches)) - ./pkgs/dropbear/add-authkeyfile-option.patch - ]; + patches = o.patches ++ [ + ./pkgs/dropbear/add-authkeyfile-option.patch + ]; postPatch = '' (echo '#define DSS_PRIV_FILENAME "/run/dropbear/dropbear_dss_host_key"' echo '#define RSA_PRIV_FILENAME "/run/dropbear/dropbear_rsa_host_key"' diff --git a/pkgs/dropbear/add-authkeyfile-option.patch b/pkgs/dropbear/add-authkeyfile-option.patch @@ -1,31 +1,5 @@ -From 9c0ac9e41a393e0f16a57e36d9369d61d39e9aa5 Mon Sep 17 00:00:00 2001 -From: Daniel Barlow <dan@telent.net> -Date: Fri, 23 Aug 2024 11:33:24 +0100 -Subject: [PATCH] add -U otion to set path to authorized_keys file - -based on https://github.com/mkj/dropbear/pull/35 -by Salvador Fandino sfandino@yahoo.com - -- Allow authorized keys inside dirs with the sticky bit set - -- Add option -U for customizing authorized_keys path - -- Updated for dropbear 2024.85 (source files moved to src/) - -- allow %u, %d, %n "format specifiers" in pathname so that the user's - username/homedir/uid can be embedded into the path ---- - Makefile.in | 2 +- - manpages/dropbear.8 | 3 + - src/pathexpand.c | 149 +++++++++++++++++++++++++++++++++++++++++++ - src/runopts.h | 3 +- - src/svr-authpubkey.c | 86 +++++++++++-------------- - src/svr-runopts.c | 10 +++ - 6 files changed, 203 insertions(+), 50 deletions(-) - create mode 100644 src/pathexpand.c - diff --git a/Makefile.in b/Makefile.in -index 5ebfca2..686fbfb 100644 +index fe63a80..b050be3 100644 --- a/Makefile.in +++ b/Makefile.in @@ -51,7 +51,7 @@ COMMONOBJS = $(patsubst %,$(OBJ_DIR)/%,$(_COMMONOBJS)) @@ -38,7 +12,7 @@ index 5ebfca2..686fbfb 100644 _CLIOBJS=cli-main.o cli-auth.o cli-authpasswd.o cli-kex.o \ diff --git a/manpages/dropbear.8 b/manpages/dropbear.8 -index bdb2ea0..c8d450d 100644 +index 72be0ae..78e0a99 100644 --- a/manpages/dropbear.8 +++ b/manpages/dropbear.8 @@ -29,6 +29,9 @@ or automatically with the '-R' option. See "Host Key Files" below. @@ -207,171 +181,45 @@ index 0000000..07e6955 + return filename; /* caller must free */ +} diff --git a/src/runopts.h b/src/runopts.h -index 1c88b5c..707008f 100644 +index c8072b3..73ffdb1 100644 --- a/src/runopts.h +++ b/src/runopts.h -@@ -128,7 +128,8 @@ typedef struct svr_runopts { +@@ -124,6 +124,7 @@ typedef struct svr_runopts { char * pidfile; - char * forced_command; -- char* interface; -+ char * authkeysfile; -+ char * interface; + char * authorized_keys_dir; ++ char * authorized_keys_file; - #if DROPBEAR_PLUGIN - /* malloced */ + char * forced_command; + char* interface; diff --git a/src/svr-authpubkey.c b/src/svr-authpubkey.c -index 5d298cb..54502f4 100644 +index 94ae728..9da6654 100644 --- a/src/svr-authpubkey.c +++ b/src/svr-authpubkey.c -@@ -73,7 +73,7 @@ +@@ -72,6 +72,7 @@ + #define MAX_AUTHKEYS_LINE 4200 /* max length of a line in authkeys */ + static char * authorized_keys_filepath(void); ++extern char * pathexpand(char *input); static int checkpubkey(const char* keyalgo, unsigned int keyalgolen, const unsigned char* keyblob, unsigned int keybloblen); --static int checkpubkeyperms(void); -+static int checkpubkeyperms(char *filename, char *base); - static void send_msg_userauth_pk_ok(const char* sigalgo, unsigned int sigalgolen, - const unsigned char* keyblob, unsigned int keybloblen); - static int checkfileperm(char * filename); -@@ -431,6 +431,7 @@ out: - return ret; - } - -+extern char *pathexpand(char *input); + static int checkpubkeyperms(void); +@@ -441,6 +442,10 @@ static char *authorized_keys_filepath() { + char *pathname = NULL, *dir = NULL; + const char *filename = "authorized_keys"; - /* Checks whether a specified publickey (and associated algorithm) is an - * acceptable key for authentication */ -@@ -458,19 +459,12 @@ static int checkpubkey(const char* keyalgo, unsigned int keyalgolen, - dropbear_exit("Failed to set euid"); - } - #endif -+ filename = pathexpand(svr_opts.authkeysfile); ++ if(svr_opts.authorized_keys_file) { ++ return pathexpand(svr_opts.authorized_keys_file); ++ }; + - /* check file permissions, also whether file exists */ -- if (checkpubkeyperms() == DROPBEAR_FAILURE) { -- TRACE(("bad authorized_keys permissions, or file doesn't exist")) -+ if (checkpubkeyperms(filename, ses.authstate.pw_dir) == DROPBEAR_FAILURE) { -+ TRACE(("bad authorized keys permissions on %s, or file doesn't exist", filename)) - } 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); -- - authfile = fopen(filename, "r"); - if (!authfile) { - TRACE(("checkpubkey: failed opening %s: %s", filename, strerror(errno))) -@@ -486,7 +480,7 @@ static int checkpubkey(const char* keyalgo, unsigned int keyalgolen, - if (authfile == NULL) { - goto out; - } -- TRACE(("checkpubkey: opened authorized_keys OK")) -+ TRACE(("checkpubkey: opened %s OK", filename)) - - line = buf_new(MAX_AUTHKEYS_LINE); - line_num = 0; -@@ -524,53 +518,47 @@ out: - - /* Returns DROPBEAR_SUCCESS if file permissions for pubkeys are ok, - * DROPBEAR_FAILURE otherwise. -- * Checks that the user's homedir, ~/.ssh, and -- * ~/.ssh/authorized_keys are all owned by either root or the user, and are -+ * Checks filename and its parent directories recursively until the -+ * base directory (usually ~/) or one of its ancestors (up to /) is -+ * reached. -+ * The files and directories must be all owned by root or the user, and be - * g-w, o-w */ --static int checkpubkeyperms() { -- -- char* filename = NULL; -+static int checkpubkeyperms(char *filename, char *base) { -+ char* path = NULL; - int ret = DROPBEAR_FAILURE; - unsigned int len; - -- TRACE(("enter checkpubkeyperms")) -- -- if (ses.authstate.pw_dir == NULL) { -- goto out; -- } -+ TRACE(("enter checkpubkeyperms(%s, %s)", filename, base)) + dir = expand_homedir_path_home(svr_opts.authorized_keys_dir, + ses.authstate.pw_dir); -- if ((len = strlen(ses.authstate.pw_dir)) == 0) { -+ if ((base == NULL) || (base[0] != '/') || -+ (filename == NULL) || (filename[0] != '/')) { -+ /* both filename and base must be absolute paths */ - 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); -+ len = strlen(filename); -+ path = m_strdup(filename); - -- /* check ~ */ -- if (checkfileperm(filename) != DROPBEAR_SUCCESS) { -- goto out; -- } -- -- /* check ~/.ssh */ -- strlcat(filename, "/.ssh", len); -- if (checkfileperm(filename) != DROPBEAR_SUCCESS) { -- goto out; -- } -+ while (checkfileperm(len ? path : "/") == DROPBEAR_SUCCESS) { -+ /* check if we are on base trail and if this is the -+ * case, return success */ -+ if ((strncmp(base, path, len) == 0) && -+ (!len || (base[len] == '\0') || (base[len] == '/'))) { -+ ret = DROPBEAR_SUCCESS; -+ break; -+ } - -- /* now check ~/.ssh/authorized_keys */ -- strlcat(filename, "/authorized_keys", len); -- if (checkfileperm(filename) != DROPBEAR_SUCCESS) { -- goto out; -+ /* look for parent directory */ -+ while (--len) { -+ if (path[len] == '/') { -+ path[len] = '\0'; -+ break; -+ } -+ } - } - -- /* file looks ok, return success */ -- ret = DROPBEAR_SUCCESS; -- - out: -- m_free(filename); -+ m_free(path); - - TRACE(("leave checkpubkeyperms")) - return ret; -@@ -596,7 +584,9 @@ static int checkfileperm(char * filename) { - TRACE(("wrong ownership")) - } - /* check permissions - don't want group or others +w */ -- if (filestat.st_mode & (S_IWGRP | S_IWOTH)) { -+ /* (unless sticky dir, which is allowed) */ -+ if ((filestat.st_mode & (S_IWGRP | S_IWOTH)) && -+ !(S_ISDIR(filestat.st_mode) && (filestat.st_mode & S_ISVTX))) { - badperm = 1; - TRACE(("wrong perms")) - } diff --git a/src/svr-runopts.c b/src/svr-runopts.c -index c4f83c1..faddfa2 100644 +index 8034c50..986c552 100644 --- a/src/svr-runopts.c +++ b/src/svr-runopts.c -@@ -147,6 +147,7 @@ void svr_getopts(int argc, char ** argv) { +@@ -150,6 +150,7 @@ void svr_getopts(int argc, char ** argv) { char* maxauthtries_arg = NULL; char* reexec_fd_arg = NULL; char* keyfile = NULL; @@ -379,16 +227,15 @@ index c4f83c1..faddfa2 100644 char c; #if DROPBEAR_PLUGIN char* pubkey_plugin = NULL; -@@ -173,6 +174,8 @@ void svr_getopts(int argc, char ** argv) { - svr_opts.hostkey = NULL; +@@ -177,6 +178,7 @@ void svr_getopts(int argc, char ** argv) { svr_opts.delay_hostkey = 0; svr_opts.pidfile = expand_homedir_path(DROPBEAR_PIDFILE); -+ svr_opts.authkeysfile = "%d/.ssh/authorized_keys"; -+ + svr_opts.authorized_keys_dir = "~/.ssh"; ++ svr_opts.authorized_keys_file = NULL; #if DROPBEAR_SVR_LOCALANYFWD svr_opts.nolocaltcp = 0; #endif -@@ -322,6 +325,9 @@ void svr_getopts(int argc, char ** argv) { +@@ -344,6 +346,9 @@ void svr_getopts(int argc, char ** argv) { case 'u': /* backwards compatibility with old urandom option */ break; @@ -398,17 +245,14 @@ index c4f83c1..faddfa2 100644 #if DROPBEAR_PLUGIN case 'A': next = &pubkey_plugin; -@@ -372,6 +378,10 @@ void svr_getopts(int argc, char ** argv) { +@@ -394,6 +399,10 @@ void svr_getopts(int argc, char ** argv) { addhostkey(keyfile); keyfile = NULL; } + if (authkeysfile) { -+ svr_opts.authkeysfile = m_strdup(authkeysfile); ++ svr_opts.authorized_keys_file = m_strdup(authkeysfile); + authkeysfile = NULL; + } } } --- -2.47.0 -