Created
March 25, 2024 01:13
-
-
Save ryancdotorg/a90d66c83aa3b925c95f3515074b86ab to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Binary files dropbear.orig/.git/index and dropbear/.git/index differ | |
diff -ruN dropbear.orig/Makefile.in dropbear/Makefile.in | |
--- dropbear.orig/Makefile.in 2023-12-21 13:53:06.474210019 +0000 | |
+++ dropbear/Makefile.in 2023-12-21 18:43:15.890803869 +0000 | |
@@ -50,7 +50,7 @@ | |
cli-authpubkey.o cli-tcpfwd.o cli-channel.o cli-authinteract.o \ | |
cli-agentfwd.o | |
-CLISVROBJS=common-session.o packet.o common-algo.o common-kex.o \ | |
+CLISVROBJS=common-session.o packet.o common-algo.o common-kex.o common-ident.o \ | |
common-channel.o common-chansession.o termcodes.o loginrec.o \ | |
tcp-accept.o listener.o process-packet.o dh_groups.o \ | |
common-runopts.o circbuffer.o list.o netio.o chachapoly.o gcm.o | |
diff -ruN dropbear.orig/common-ident.c dropbear/common-ident.c | |
--- dropbear.orig/common-ident.c 1970-01-01 01:00:00.000000000 +0100 | |
+++ dropbear/common-ident.c 2023-12-22 02:43:07.517459121 +0000 | |
@@ -0,0 +1,79 @@ | |
+#include "includes.h" | |
+#include "dbutil.h" | |
+#include "ident.h" | |
+ | |
+#if DROPBEAR_RUNTIME_IDENT | |
+/* RFC 4253 § 4.2 says the identificatin string MUST be | |
+ * SSH-protoversion-softwareversion SP comments CR LF | |
+ * MUST NOT contain a null, and MUST be at most 253 characters | |
+ */ | |
+static unsigned int ssh_ident_len = 8; | |
+static char ssh_ident[253] = {'S','S','H','-','2','.','0','-'}; | |
+ | |
+/* not thread safe */ | |
+int set_ssh_ident(char *software_version, char *comments) { | |
+ ssh_ident_len = 8; | |
+ unsigned int new_ident_len = ssh_ident_len; | |
+ size_t avail = sizeof(ssh_ident) - new_ident_len; | |
+ | |
+ if (software_version == NULL) { | |
+ software_version = (char *)((uintptr_t)(LOCAL_IDENT) + 8); | |
+ } | |
+ | |
+ for (int i = 0;;) { | |
+ char c = software_version[i++]; | |
+ | |
+ if (c == '\0') { | |
+ break; | |
+ } else if (avail == 0 || c <= 0x20 || c >= 0x7F || c == '-') { | |
+ return -1; /* out of space or invalid character */ | |
+ } | |
+ | |
+ ssh_ident[new_ident_len++] = c; | |
+ --avail; | |
+ } | |
+ | |
+ if (comments != NULL) { | |
+ if (new_ident_len == sizeof(ssh_ident)) { | |
+ return -1; /* out of space */ | |
+ } | |
+ | |
+ ssh_ident[new_ident_len++] = ' '; | |
+ --avail; | |
+ | |
+ for (int i = 0;;) { | |
+ char c = comments[i++]; | |
+ | |
+ if (c == '\0') { | |
+ break; | |
+ } else if (avail == 0 || c == '\n') { | |
+ return -1; /* out of space or invalid character */ | |
+ } | |
+ | |
+ ssh_ident[new_ident_len++] = c; | |
+ --avail; | |
+ } | |
+ } | |
+ | |
+ ssh_ident_len = new_ident_len; | |
+ return 0; | |
+} | |
+ | |
+unsigned int get_ssh_ident(char *buf, size_t n) { | |
+ if (ssh_ident_len > 253) { | |
+ __builtin_unreachable(); | |
+ } else if (n < ssh_ident_len) { | |
+ dropbear_exit("Local ident does not fit in buffer"); | |
+ __builtin_unreachable(); | |
+ } else if (ssh_ident_len <= 8) { | |
+ size_t len = strlen(LOCAL_IDENT); | |
+ memcpy(buf, LOCAL_IDENT, len); | |
+ return (unsigned int)len; | |
+ } else { | |
+ memcpy(buf, ssh_ident, ssh_ident_len); | |
+ return (unsigned int)ssh_ident_len; | |
+ } | |
+ | |
+ return 0; | |
+} | |
+#endif | |
diff -ruN dropbear.orig/common-kex.c dropbear/common-kex.c | |
--- dropbear.orig/common-kex.c 2023-12-21 13:53:06.478209618 +0000 | |
+++ dropbear/common-kex.c 2023-12-21 19:16:03.651993561 +0000 | |
@@ -38,6 +38,7 @@ | |
#include "ecc.h" | |
#include "curve25519.h" | |
#include "crypto_desc.h" | |
+#include "ident.h" | |
static void kexinitialise(void); | |
static void gen_new_keys(void); | |
@@ -475,7 +476,13 @@ | |
unsigned int kexhashbuf_len = 0; | |
unsigned int remote_ident_len = 0; | |
- unsigned int local_ident_len = 0; | |
+#if DROPBEAR_RUNTIME_IDENT | |
+ char local_ident[253]; | |
+ unsigned int local_ident_len = get_ssh_ident(local_ident, sizeof(local_ident)); | |
+#else | |
+ char *local_ident = LOCAL_IDENT; | |
+ unsigned int local_ident_len = strlen(LOCAL_IDENT); | |
+#endif | |
TRACE(("<- KEXINIT")) | |
TRACE(("enter recv_msg_kexinit")) | |
@@ -493,7 +500,6 @@ | |
} | |
/* start the kex hash */ | |
- local_ident_len = strlen(LOCAL_IDENT); | |
remote_ident_len = strlen(ses.remoteident); | |
kexhashbuf_len = local_ident_len + remote_ident_len | |
@@ -508,7 +514,7 @@ | |
read_kex_algos(); | |
/* V_C, the client's version string (CR and NL excluded) */ | |
- buf_putstring(ses.kexhashbuf, LOCAL_IDENT, local_ident_len); | |
+ buf_putstring(ses.kexhashbuf, local_ident, local_ident_len); | |
/* V_S, the server's version string (CR and NL excluded) */ | |
buf_putstring(ses.kexhashbuf, ses.remoteident, remote_ident_len); | |
@@ -529,7 +535,7 @@ | |
/* V_C, the client's version string (CR and NL excluded) */ | |
buf_putstring(ses.kexhashbuf, ses.remoteident, remote_ident_len); | |
/* V_S, the server's version string (CR and NL excluded) */ | |
- buf_putstring(ses.kexhashbuf, LOCAL_IDENT, local_ident_len); | |
+ buf_putstring(ses.kexhashbuf, local_ident, local_ident_len); | |
/* I_C, the payload of the client's SSH_MSG_KEXINIT */ | |
buf_setpos(ses.payload, ses.payload_beginning); | |
diff -ruN dropbear.orig/common-session.c dropbear/common-session.c | |
--- dropbear.orig/common-session.c 2023-12-21 13:53:06.478209618 +0000 | |
+++ dropbear/common-session.c 2023-12-21 19:22:43.575532046 +0000 | |
@@ -35,6 +35,7 @@ | |
#include "channel.h" | |
#include "runopts.h" | |
#include "netio.h" | |
+#include "ident.h" | |
static void checktimeouts(void); | |
static long select_timeout(void); | |
@@ -358,8 +359,12 @@ | |
} | |
void send_session_identification() { | |
- buffer *writebuf = buf_new(strlen(LOCAL_IDENT "\r\n") + 1); | |
- buf_putbytes(writebuf, (const unsigned char *) LOCAL_IDENT "\r\n", strlen(LOCAL_IDENT "\r\n")); | |
+ char local_ident[255]; | |
+ unsigned int local_ident_len = get_ssh_ident(local_ident, sizeof(local_ident) - 2); | |
+ local_ident[local_ident_len++] = '\r'; | |
+ local_ident[local_ident_len++] = '\n'; | |
+ buffer *writebuf = buf_new(local_ident_len + 1); | |
+ buf_putbytes(writebuf, (const unsigned char *) local_ident, local_ident_len); | |
writebuf_enqueue(writebuf); | |
} | |
diff -ruN dropbear.orig/ident.h dropbear/ident.h | |
--- dropbear.orig/ident.h 1970-01-01 01:00:00.000000000 +0100 | |
+++ dropbear/ident.h 2023-12-21 19:10:43.908414764 +0000 | |
@@ -0,0 +1,13 @@ | |
+#ifndef DROPBEAR_IDENT_H_ | |
+#define DROPBEAR_IDENT_H_ | |
+#include "includes.h" | |
+ | |
+/* not thread safe */ | |
+int set_ssh_ident(char *software_version, char *comments); | |
+unsigned int get_ssh_ident(char *buf, size_t n); | |
+ | |
+#ifndef DROPBEAR_RUNTIME_IDENT | |
+#define DROPBEAR_RUNTIME_IDENT 1 | |
+#endif | |
+ | |
+#endif | |
diff -ruN dropbear.orig/svr-runopts.c dropbear/svr-runopts.c | |
--- dropbear.orig/svr-runopts.c 2023-12-21 16:29:20.213431783 +0000 | |
+++ dropbear/svr-runopts.c 2023-12-22 02:35:54.077140433 +0000 | |
@@ -29,6 +29,7 @@ | |
#include "dbutil.h" | |
#include "algo.h" | |
#include "ecdsa.h" | |
+#include "ident.h" | |
#include <grp.h> | |
@@ -106,6 +107,10 @@ | |
"-A <authplugin>[,<options>]\n" | |
" Enable external public key auth through <authplugin>\n" | |
#endif | |
+#if DROPBEAR_RUNTIME_IDENT | |
+ "-Z <version> Override SSH software version string\n" | |
+ "-C <comments> Set identification string comments\n" | |
+#endif | |
"-V Version\n" | |
#if DEBUG_TRACE | |
"-v verbose (repeat for more verbose)\n" | |
@@ -140,6 +145,10 @@ | |
char* reexec_fd_arg = NULL; | |
char* keyfile = NULL; | |
char c; | |
+#if DROPBEAR_RUNTIME_IDENT | |
+ char* software_version = NULL; | |
+ char* comments = NULL; | |
+#endif | |
#if DROPBEAR_PLUGIN | |
char* pubkey_plugin = NULL; | |
#endif | |
@@ -310,6 +319,14 @@ | |
next = &pubkey_plugin; | |
break; | |
#endif | |
+#if DROPBEAR_RUNTIME_IDENT | |
+ case 'Z': | |
+ next = &software_version; | |
+ break; | |
+ case 'C': | |
+ next = &comments; | |
+ break; | |
+#endif | |
#if DEBUG_TRACE | |
case 'v': | |
debug_trace++; | |
@@ -355,6 +372,12 @@ | |
addhostkey(keyfile); | |
keyfile = NULL; | |
} | |
+ | |
+#if DROPBEAR_RUNTIME_IDENT | |
+ if (set_ssh_ident(software_version, comments) != 0) { | |
+ dropbear_exit("Invalid ident argument"); | |
+ } | |
+#endif | |
} | |
} | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment