forked from Freetz/freetz
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
dropbear: YourFritz specific patches
- adjust patches to 2019.78 version
- Loading branch information
Showing
5 changed files
with
479 additions
and
4 deletions.
There are no files selected for viewing
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
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
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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,280 @@ | ||
--- cli-runopts.c | ||
+++ cli-runopts.c | ||
@@ -67,8 +67,10 @@ | ||
"-s Request a subsystem (use by external sftp)\n" | ||
"-o option Set option in OpenSSH-like format ('-o help' to list options)\n" | ||
#if DROPBEAR_CLI_PUBKEY_AUTH | ||
+#ifndef DROPBEAR_YOURFRITZ | ||
"-i <identityfile> (multiple allowed, default %s)\n" | ||
#endif | ||
+#endif | ||
#if DROPBEAR_CLI_AGENTFWD | ||
"-A Enable agent auth forwarding\n" | ||
#endif | ||
@@ -97,6 +99,20 @@ | ||
#if DEBUG_TRACE | ||
"-v verbose (compiled with DEBUG_TRACE)\n" | ||
#endif | ||
+#ifdef DROPBEAR_YOURFRITZ | ||
+ "\nThis is a special version created from the Freetz trunk and it's\n" | ||
+ "stripped down to the really needed functions to be usable on a FRITZ!Box\n" | ||
+ "device with the RSA key stored there. It supports only a limited set of\n" | ||
+ "KEX and CIPHER algorithms and isn't backward compatible to older SSH\n" | ||
+ "clients (by intention). It allows only root user logins with public key\n" | ||
+ "authentication, no other user(s) and/or methods will be accepted.\n" | ||
+ "It's not optimized for size and the usually disabled TRACE output option\n" | ||
+ "is explicitly enabled.\n" | ||
+ "The FRITZ!Box key (" DROPBEAR_DEFAULT_CLI_AUTHKEY ") is the only supported\n" | ||
+ "RSA key file for both server and client usage and it will be read only\n" | ||
+ "from this location with automatic decryption.\n\n" | ||
+#endif | ||
+ | ||
,DROPBEAR_VERSION, cli_opts.progname, | ||
#if DROPBEAR_CLI_PUBKEY_AUTH | ||
DROPBEAR_DEFAULT_CLI_AUTHKEY, | ||
--- common-runopts.c | ||
+++ common-runopts.c | ||
@@ -31,8 +31,128 @@ | ||
#include "algo.h" | ||
#include "dbrandom.h" | ||
|
||
+#ifdef DROPBEAR_YOURFRITZ | ||
+ | ||
+// it's possible to use OpenSSL libraries here, because we're on an AVM | ||
+// router, where the OpenSSL library libcrypto.so is almost ever available | ||
+// and it's even used to store the encrypted RSA key file ... so we can | ||
+// use it without any scruple for the "lean SSH server" too | ||
+ | ||
+// libtomcrypt contains own versions of the SHAx defines, we don't need them | ||
+// here really and so we'll simply remove the previous definitions | ||
+#undef SHA1 | ||
+#undef SHA256 | ||
+#undef SHA512 | ||
+ | ||
+// OpenSSL definitions and reading of device-specific password for the key file | ||
+#include <openssl/pem.h> | ||
+#include <openssl/bn.h> | ||
+#include <openssl/err.h> | ||
+#include <openssl/evp.h> | ||
+#include <privatekeypassword/privatekeypassword.h> | ||
+ | ||
+#endif | ||
+ | ||
runopts opts; /* GLOBAL */ | ||
|
||
+int buf_readdevicekey(buffer* buf, const char* filename) { | ||
+ int ret = DROPBEAR_FAILURE; | ||
+ | ||
+ char *password = getPrivateKeyPassword(); | ||
+ if (password == NULL) { | ||
+ TRACE(("error reading device specific password")) | ||
+ return ret; | ||
+ } | ||
+ | ||
+ FILE *fp = fopen(filename, "rb"); | ||
+ if (fp == NULL) { | ||
+ TRACE(("error opening RSA key file %s", filename)) | ||
+ return ret; | ||
+ } | ||
+ | ||
+ OpenSSL_add_all_algorithms(); | ||
+ | ||
+ RSA *boxRSA = RSA_new(); | ||
+ if (boxRSA == NULL) { | ||
+ fclose(fp); | ||
+ TRACE(("error allocating RSA structure")) | ||
+ EVP_cleanup(); | ||
+ return ret; | ||
+ } | ||
+ | ||
+ if (PEM_read_RSAPrivateKey(fp, &boxRSA, NULL, (void *) password) == NULL) { | ||
+ unsigned long osslErr = ERR_get_error(); | ||
+ RSA_free(boxRSA); | ||
+ fclose(fp); | ||
+ TRACE(("error reading RSA key\n%s", ERR_error_string(osslErr, NULL))) | ||
+ EVP_cleanup(); | ||
+ return ret; | ||
+ } | ||
+ | ||
+ fclose(fp); | ||
+ TRACE2(("box key read successfully, extracting key components")) | ||
+ | ||
+// copy RSA key components to buffer, it's the simplest way to exchange data | ||
+// we need e, n, d, p, q in this order, preceded by a "ssh-rsa" string | ||
+ buf_putstring(buf, "ssh-rsa", 7); | ||
+ | ||
+ BIGNUM ** numbers[6]; | ||
+ int len = 0, i = 0; | ||
+ unsigned char * p; | ||
+ BIGNUM *** current; | ||
+ | ||
+// this list is the source of components and the order to copy them | ||
+ numbers[0] = &boxRSA->e; | ||
+ numbers[1] = &boxRSA->n; | ||
+ numbers[2] = &boxRSA->d; | ||
+ numbers[3] = &boxRSA->p; | ||
+ numbers[4] = &boxRSA->q; | ||
+ numbers[5] = NULL; | ||
+ | ||
+// determine needed conversion buffer size | ||
+ current = numbers; | ||
+ while (*current != NULL) { | ||
+ int newlen = BN_bn2mpi(**current, NULL); | ||
+ if (newlen > len) len = newlen; | ||
+ current++; | ||
+ } | ||
+ | ||
+// allocate a structure able to contain a serialized mp_int | ||
+ struct { | ||
+ int len; | ||
+ unsigned char data[]; | ||
+ } * mp = malloc(len); | ||
+ if (mp == NULL) { | ||
+ TRACE(("unable to allocate memory to convert from BIGNUM to buffer")) | ||
+ RSA_free(boxRSA); | ||
+ EVP_cleanup(); | ||
+ return ret; | ||
+ } | ||
+ | ||
+// we use a temporary buffer, because both BIGNUM implementations want an unsigned | ||
+// char pointer and the internal structures of "mp_int" and "BIGNUM" are different | ||
+// ... so we'll convert BIGNUM to mpi (4 byte length + variable size data) and write | ||
+// the result to our buffer | ||
+ current = numbers; | ||
+ while (*current != NULL) { | ||
+ BN_bn2mpi(**current, (unsigned char *) mp); | ||
+ buf_putstring(buf, mp->data, mp->len); | ||
+ current++; | ||
+ } | ||
+ for (i = 0, p = (unsigned char *) mp; i < len; i++, p++) *p = '\0'; | ||
+ free(mp); | ||
+ | ||
+// shutdown OpenSSL routines | ||
+ TRACE2(("freeing OpenSSL RSA structure")) | ||
+ RSA_free(boxRSA); | ||
+ TRACE2(("calling EVP_cleanup")) | ||
+ EVP_cleanup(); | ||
+ | ||
+ ret = DROPBEAR_SUCCESS; | ||
+ TRACE(("using device key file from %s", filename)) | ||
+ return ret; | ||
+} | ||
+ | ||
/* returns success or failure, and the keytype in *type. If we want | ||
* to restrict the type, type can contain a type to return */ | ||
int readhostkey(const char * filename, sign_key * hostkey, | ||
@@ -43,7 +163,11 @@ | ||
|
||
buf = buf_new(MAX_PRIVKEY_SIZE); | ||
|
||
+#ifdef DROPBEAR_YOURFRITZ | ||
+ if (buf_readdevicekey(buf, filename) == DROPBEAR_FAILURE) { | ||
+#else | ||
if (buf_readfile(buf, filename) == DROPBEAR_FAILURE) { | ||
+#endif | ||
goto out; | ||
} | ||
buf_setpos(buf, 0); | ||
--- svr-runopts.c | ||
+++ svr-runopts.c | ||
@@ -43,6 +43,7 @@ | ||
|
||
fprintf(stderr, "Dropbear server v%s https://matt.ucc.asn.au/dropbear/dropbear.html\n" | ||
"Usage: %s [options]\n" | ||
+#ifndef DROPBEAR_YOURFRITZ | ||
"-b bannerfile Display the contents of bannerfile" | ||
" before user login\n" | ||
" (default: none)\n" | ||
@@ -60,6 +61,7 @@ | ||
#if DROPBEAR_DELAY_HOSTKEY | ||
"-R Create hostkeys as required\n" | ||
#endif | ||
+#endif | ||
#ifdef DROPBEAR_SFTPSERVER | ||
"-S sftpserver Set path to sftp server\n" | ||
" (default: %s)\n" | ||
@@ -73,8 +75,10 @@ | ||
#if DO_MOTD | ||
"-m Don't display the motd on login\n" | ||
#endif | ||
+#ifndef DROPBEAR_YOURFRITZ | ||
"-w Disallow root logins\n" | ||
"-0 Allow only root logins\n" | ||
+#endif | ||
#ifdef HAVE_GETGROUPLIST | ||
"-G Restrict logins to members of specified group\n" | ||
#endif | ||
@@ -110,7 +114,21 @@ | ||
#if DEBUG_TRACE | ||
"-v verbose (compiled with DEBUG_TRACE)\n" | ||
#endif | ||
+#ifdef DROPBEAR_YOURFRITZ | ||
+ "\nThis is a special version created from the Freetz trunk and it's\n" | ||
+ "stripped down to the really needed functions to be usable on a FRITZ!Box\n" | ||
+ "device with the RSA key stored there. It supports only a limited set of\n" | ||
+ "KEX and CIPHER algorithms and isn't backward compatible to older SSH\n" | ||
+ "clients (by intention). It allows only root user logins with public key\n" | ||
+ "authentication, no other user(s) and/or methods will be accepted.\n" | ||
+ "It's not optimized for size and the usually disabled TRACE output option\n" | ||
+ "is explicitly enabled.\n" | ||
+ "The FRITZ!Box key (" RSA_PRIV_FILENAME ") is the only supported\n" | ||
+ "RSA key file for both server and client usage and it will be read only\n" | ||
+ "from this location with automatic decryption.\n\n" | ||
+#endif | ||
,DROPBEAR_VERSION, progname, | ||
+#ifndef DROPBEAR_YOURFRITZ | ||
#if DROPBEAR_DSS | ||
DSS_PRIV_FILENAME, | ||
#endif | ||
@@ -120,6 +138,7 @@ | ||
#if DROPBEAR_ECDSA | ||
ECDSA_PRIV_FILENAME, | ||
#endif | ||
+#endif | ||
#ifdef DROPBEAR_SFTPSERVER | ||
SFTPSERVER_PATH, | ||
#endif | ||
@@ -191,6 +210,11 @@ | ||
opts.keepalive_secs = DEFAULT_KEEPALIVE; | ||
opts.idle_timeout_secs = DEFAULT_IDLE_TIMEOUT; | ||
|
||
+#ifdef DROPBEAR_YOURFRITZ | ||
+ svr_opts.rootonlylogin = 1; | ||
+ svr_opts.noauthpass = 1; | ||
+#endif | ||
+ | ||
#if DROPBEAR_SVR_REMOTETCPFWD | ||
opts.listen_fwd_all = 0; | ||
#endif | ||
@@ -201,6 +225,7 @@ | ||
|
||
for (j = 1; (c = argv[i][j]) != '\0' && !next && !nextisport; j++) { | ||
switch (c) { | ||
+#ifndef DROPBEAR_YOURFRITZ | ||
case 'b': | ||
next = &svr_opts.bannerfile; | ||
break; | ||
@@ -214,6 +239,7 @@ | ||
case 'R': | ||
svr_opts.delay_hostkey = 1; | ||
break; | ||
+#endif | ||
#ifdef DROPBEAR_SFTPSERVER | ||
case 'S': | ||
next = &svr_opts.sftppath; | ||
@@ -260,6 +286,7 @@ | ||
svr_opts.domotd = 0; | ||
break; | ||
#endif | ||
+#ifndef DROPBEAR_YOURFRITZ | ||
case 'w': | ||
svr_opts.norootlogin = 1; | ||
break; | ||
@@ -271,6 +298,7 @@ | ||
next = &svr_opts.restrict_group; | ||
break; | ||
#endif | ||
+#endif | ||
case 'W': | ||
next = &recv_window_arg; | ||
break; |
Oops, something went wrong.