forked from mirror/openwrt
dropbear: relax path permission checks for authorized keys
Check permissions of correct folder for certificates too.
Fixes: bbe4d6ddb2 ("dropbear: bump to 2025.88")
Signed-off-by: Konstantin Demin <rockdrilla@gmail.com>
Link: https://github.com/openwrt/openwrt/pull/19611
Signed-off-by: Hauke Mehrtens <hauke@hauke-m.de>
This commit is contained in:
parent
27baa3c731
commit
68e5f46899
3 changed files with 79 additions and 33 deletions
|
|
@ -9,7 +9,7 @@ include $(TOPDIR)/rules.mk
|
|||
|
||||
PKG_NAME:=dropbear
|
||||
PKG_VERSION:=2025.88
|
||||
PKG_RELEASE:=2
|
||||
PKG_RELEASE:=3
|
||||
|
||||
PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.bz2
|
||||
PKG_SOURCE_URL:= \
|
||||
|
|
|
|||
|
|
@ -1,15 +1,16 @@
|
|||
Author: Konstantin Demin <rockdrilla@gmail.com>
|
||||
From 5cc0127000db5f7567b54d0495fb91a8e452fe09 Mon Sep 17 00:00:00 2001
|
||||
From: Konstantin Demin <rockdrilla@gmail.com>
|
||||
Date: Fri, 9 May 2025 22:39:35 +0300
|
||||
Subject: Fix proxycmd without netcat
|
||||
|
||||
Fixes commit e5a0ef27c227 "Execute multihop commands directly, no shell"
|
||||
fixes e5a0ef27c2 "Execute multihop commands directly, no shell"
|
||||
|
||||
Signed-off-by: Konstantin Demin <rockdrilla@gmail.com>
|
||||
Forwarded: https://github.com/mkj/dropbear/pull/363
|
||||
|
||||
---
|
||||
src/cli-main.c | 12 +++++++++++-
|
||||
1 file changed, 11 insertions(+), 1 deletion(-)
|
||||
|
||||
diff --git a/src/cli-main.c b/src/cli-main.c
|
||||
index 2fafa88900..0a052a3512 100644
|
||||
--- a/src/cli-main.c
|
||||
+++ b/src/cli-main.c
|
||||
@@ -77,7 +77,11 @@ int main(int argc, char ** argv) {
|
||||
|
|
@ -25,7 +26,7 @@ index 2fafa88900..0a052a3512 100644
|
|||
cli_proxy_cmd(&sock_in, &sock_out, &proxy_cmd_pid);
|
||||
if (signal(SIGINT, kill_proxy_sighandler) == SIG_ERR ||
|
||||
signal(SIGTERM, kill_proxy_sighandler) == SIG_ERR ||
|
||||
@@ -110,11 +114,13 @@ static void shell_proxy_cmd(const void *user_data_cmd) {
|
||||
@@ -110,11 +114,13 @@ static void shell_proxy_cmd(const void *
|
||||
dropbear_exit("Failed to run '%s'\n", cmd);
|
||||
}
|
||||
|
||||
|
|
@ -39,7 +40,7 @@ index 2fafa88900..0a052a3512 100644
|
|||
|
||||
static void cli_proxy_cmd(int *sock_in, int *sock_out, pid_t *pid_out) {
|
||||
char * cmd_arg = NULL;
|
||||
@@ -145,9 +151,11 @@ static void cli_proxy_cmd(int *sock_in, int *sock_out, pid_t *pid_out) {
|
||||
@@ -145,9 +151,11 @@ static void cli_proxy_cmd(int *sock_in,
|
||||
cmd_arg = m_malloc(shell_cmdlen);
|
||||
snprintf(cmd_arg, shell_cmdlen, "exec %s", cli_opts.proxycmd);
|
||||
exec_fn = shell_proxy_cmd;
|
||||
|
|
@ -51,7 +52,7 @@ index 2fafa88900..0a052a3512 100644
|
|||
}
|
||||
|
||||
ret = spawn_command(exec_fn, cmd_arg, sock_out, sock_in, NULL, pid_out);
|
||||
@@ -159,6 +167,7 @@ static void cli_proxy_cmd(int *sock_in, int *sock_out, pid_t *pid_out) {
|
||||
@@ -159,6 +167,7 @@ static void cli_proxy_cmd(int *sock_in,
|
||||
cleanup:
|
||||
m_free(cli_opts.proxycmd);
|
||||
m_free(cmd_arg);
|
||||
|
|
|
|||
|
|
@ -1,29 +1,55 @@
|
|||
src/svr-authpubkey.c | 59 ++++++++++++++++++++++++++++++++++++++++++++++++----
|
||||
1 file changed, 55 insertions(+), 4 deletions(-)
|
||||
|
||||
--- a/src/svr-authpubkey.c
|
||||
+++ b/src/svr-authpubkey.c
|
||||
@@ -435,20 +435,45 @@ out:
|
||||
/* Returns the full path to the user's authorized_keys file in an
|
||||
* allocated string which caller must free. */
|
||||
static char *authorized_keys_filepath() {
|
||||
+ static const char * const global_authkeys_dir = "/etc/dropbear";
|
||||
+ /* strlen(global_authkeys_dir) */
|
||||
+ #define n_global_authkeys_dir 13
|
||||
+ static const char * const authkeys_file = "authorized_keys";
|
||||
+ /* strlen(authkeys_file) */
|
||||
+ #define n_authkeys_file 15
|
||||
@@ -79,6 +79,39 @@ 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";
|
||||
+/* strlen(global_authkeys_dir) */
|
||||
+#define n_global_authkeys_dir 13
|
||||
+static const char * const authkeys_file = "authorized_keys";
|
||||
+/* strlen(authkeys_file) */
|
||||
+#define n_authkeys_file 15
|
||||
+
|
||||
+/* OpenWrt-specific:
|
||||
+ use OpenWrt' global authorized keys directory if:
|
||||
+ 1. logging as uid 0 (typically root).
|
||||
+ 2. "svr_opts.authorized_keys_dir" is set to default i.e. no "-D" option was specified
|
||||
+ OR
|
||||
+ "-D" option is specified as homedir-relative path ("~" or "~/...")
|
||||
+ OR
|
||||
+ "-D" option is specified as "/etc/dropbear".
|
||||
+ */
|
||||
+static int is_openwrt_defaults(void) {
|
||||
+ if (ses.authstate.pw_uid != 0) return 0;
|
||||
+ switch (svr_opts.authorized_keys_dir[0]) {
|
||||
+ case '~':
|
||||
+ switch (svr_opts.authorized_keys_dir[1]) {
|
||||
+ case 0:
|
||||
+ return 1;
|
||||
+ case '/':
|
||||
+ return 1;
|
||||
+ }
|
||||
+ break;
|
||||
+ case '/':
|
||||
+ return (strcmp(svr_opts.authorized_keys_dir, global_authkeys_dir) == 0);
|
||||
+ }
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
/* process a pubkey auth request, sending success or failure message as
|
||||
* appropriate */
|
||||
void svr_auth_pubkey(int valid_user) {
|
||||
@@ -439,16 +472,22 @@ out:
|
||||
static char *authorized_keys_filepath() {
|
||||
size_t len = 0;
|
||||
char *pathname = NULL, *dir = NULL;
|
||||
- const char *filename = "authorized_keys";
|
||||
+
|
||||
+ /* OpenWrt-specific:
|
||||
+ use OpenWrt' global authorized keys directory if:
|
||||
+ 1. logging as uid 0 (typically root)
|
||||
+ 2. "svr_opts.authorized_keys_dir" is set to default i.e. no "-D" option was specified
|
||||
+ */
|
||||
+ while (1) {
|
||||
+ if (ses.authstate.pw_uid != 0) break;
|
||||
+ if (svr_opts.authorized_keys_dir[0] == '/') break;
|
||||
+
|
||||
+ if (is_openwrt_defaults()) {
|
||||
+ len = n_global_authkeys_dir + n_authkeys_file + 2;
|
||||
+ pathname = m_malloc(len);
|
||||
+ snprintf(pathname, len, "%s/%s", global_authkeys_dir, authkeys_file);
|
||||
|
|
@ -42,10 +68,29 @@
|
|||
+ snprintf(pathname, len, "%s/%s", dir, authkeys_file);
|
||||
m_free(dir);
|
||||
return pathname;
|
||||
+
|
||||
+ /* not needed anymore */
|
||||
+ #undef n_global_authkeys_dir
|
||||
+ #undef n_authkeys_file
|
||||
}
|
||||
@@ -549,11 +588,23 @@ out:
|
||||
* When this path is inside the user's home dir it checks up to and including
|
||||
* the home dir, otherwise it checks every path component. */
|
||||
static int checkpubkeyperms() {
|
||||
- char *path = authorized_keys_filepath(), *sep = NULL;
|
||||
+ char *path = NULL, *sep = NULL;
|
||||
int ret = DROPBEAR_SUCCESS;
|
||||
|
||||
/* Checks whether a specified publickey (and associated algorithm) is an
|
||||
+ if (is_openwrt_defaults()) {
|
||||
+ TRACE(("enter checkpubkeyperms/openwrt"))
|
||||
+ if (checkfileperm(global_authkeys_dir) != DROPBEAR_SUCCESS) {
|
||||
+ TRACE(("checkpubkeyperms: bad perm on %s", global_authkeys_dir))
|
||||
+ ret = DROPBEAR_FAILURE;
|
||||
+ }
|
||||
+ TRACE(("leave checkpubkeyperms/openwrt"))
|
||||
+ return ret;
|
||||
+ }
|
||||
+
|
||||
TRACE(("enter checkpubkeyperms"))
|
||||
|
||||
+ path = authorized_keys_filepath();
|
||||
+
|
||||
/* Walk back up path checking permissions, stopping at either homedir,
|
||||
* or root if the path is outside of the homedir. */
|
||||
while ((sep = strrchr(path, '/')) != NULL) {
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue