From b16e5825ba26739db2f8bc26aff0433466501735 Mon Sep 17 00:00:00 2001 From: Vladislav Grishenko Date: Sun, 5 Apr 2020 17:04:29 +0500 Subject: [PATCH 01/25] dnsmasq: update to 2.81rc5-31-gdb028b0-openssl --- release/src/router/dnsmasq/VERSION | 2 +- release/src/router/dnsmasq/man/dnsmasq.8 | 9 ++++++--- release/src/router/dnsmasq/src/auth.c | 22 +++++++++++++--------- release/src/router/dnsmasq/src/config.h | 1 + release/src/router/dnsmasq/src/dnsmasq.c | 2 +- release/src/router/dnsmasq/src/dnsmasq.h | 3 ++- release/src/router/dnsmasq/src/dnssec.c | 2 +- release/src/router/dnsmasq/src/forward.c | 15 +++++++++------ release/src/router/dnsmasq/src/option.c | 14 +++++++++++--- release/src/router/dnsmasq/src/ubus.c | 3 ++- 10 files changed, 47 insertions(+), 26 deletions(-) diff --git a/release/src/router/dnsmasq/VERSION b/release/src/router/dnsmasq/VERSION index 2dc8af4677d..89bf7940d37 100644 --- a/release/src/router/dnsmasq/VERSION +++ b/release/src/router/dnsmasq/VERSION @@ -1 +1 @@ -2.81rc4-33-g7558f2b +2.81rc5-31-gdb028b0 diff --git a/release/src/router/dnsmasq/man/dnsmasq.8 b/release/src/router/dnsmasq/man/dnsmasq.8 index 2032a374132..3d01655be98 100644 --- a/release/src/router/dnsmasq/man/dnsmasq.8 +++ b/release/src/router/dnsmasq/man/dnsmasq.8 @@ -244,7 +244,7 @@ specified interface. The is the "glue record". It should resolve in the global DNS to an A and/or AAAA record which points to the address dnsmasq is listening on. When an interface is specified, it may be qualified with "/4" or "/6" to specify only the IPv4 or IPv6 -addresses associated with the interface. Since any defined authoritative zones are also available as part of the normal recusive DNS service supplied by dnsmasq, it can make sense to have an --auth-server declaration with no interfaces or address, but simply specifying the glue record. +addresses associated with the interface. Since any defined authoritative zones are also available as part of the normal recusive DNS service supplied by dnsmasq, it can make sense to have an --auth-server declaration with no interfaces or address, but simply specifying the primary external nameserver. .TP .B --local-service Accept DNS queries only from hosts whose address is on a local subnet, @@ -366,10 +366,13 @@ been built with DBus support. If the service name is given, dnsmasq provides service at that name, rather than the default which is .B uk.org.thekelleys.dnsmasq .TP -.B --enable-ubus +.B --enable-ubus[=] Enable dnsmasq UBus interface. It sends notifications via UBus on DHCPACK and DHCPRELEASE events. Furthermore it offers metrics. -Requires that dnsmasq has been built with UBus support. +Requires that dnsmasq has been built with UBus support. If the service +name is given, dnsmasq provides service at that namespace, rather than +the default which is +.B dnsmasq .TP .B \-o, --strict-order By default, dnsmasq will send queries to any of the upstream servers diff --git a/release/src/router/dnsmasq/src/auth.c b/release/src/router/dnsmasq/src/auth.c index 4daae30a760..b2fcd4b6fce 100644 --- a/release/src/router/dnsmasq/src/auth.c +++ b/release/src/router/dnsmasq/src/auth.c @@ -628,16 +628,20 @@ size_t answer_auth(struct dns_header *header, char *limit, size_t qlen, time_t n { struct name_list *secondary; - newoffset = ansp - (unsigned char *)header; - if (add_resource_record(header, limit, &trunc, -offset, &ansp, - daemon->auth_ttl, NULL, T_NS, C_IN, "d", offset == 0 ? authname : NULL, daemon->authserver)) + /* Only include the machine running dnsmasq if it's acting as an auth server */ + if (daemon->authinterface) { - if (offset == 0) - offset = newoffset; - if (ns) - anscount++; - else - authcount++; + newoffset = ansp - (unsigned char *)header; + if (add_resource_record(header, limit, &trunc, -offset, &ansp, + daemon->auth_ttl, NULL, T_NS, C_IN, "d", offset == 0 ? authname : NULL, daemon->authserver)) + { + if (offset == 0) + offset = newoffset; + if (ns) + anscount++; + else + authcount++; + } } if (!subnet) diff --git a/release/src/router/dnsmasq/src/config.h b/release/src/router/dnsmasq/src/config.h index d4954427c57..99dddf59df8 100644 --- a/release/src/router/dnsmasq/src/config.h +++ b/release/src/router/dnsmasq/src/config.h @@ -50,6 +50,7 @@ #define RANDFILE "/dev/urandom" #define DNSMASQ_SERVICE "uk.org.thekelleys.dnsmasq" /* Default - may be overridden by config */ #define DNSMASQ_PATH "/uk/org/thekelleys/dnsmasq" +#define DNSMASQ_UBUS_NAME "dnsmasq" /* Default - may be overridden by config */ #define AUTH_TTL 600 /* default TTL for auth DNS */ #define SOA_REFRESH 1200 /* SOA refresh default */ #define SOA_RETRY 180 /* SOA retry default */ diff --git a/release/src/router/dnsmasq/src/dnsmasq.c b/release/src/router/dnsmasq/src/dnsmasq.c index 5abbcb3eb49..980debf7ae1 100644 --- a/release/src/router/dnsmasq/src/dnsmasq.c +++ b/release/src/router/dnsmasq/src/dnsmasq.c @@ -1693,7 +1693,7 @@ static int set_dns_listeners(time_t now) /* will we be able to get memory? */ if (daemon->port != 0) - get_new_frec(now, &wait, 0); + get_new_frec(now, &wait, NULL); for (serverfdp = daemon->sfds; serverfdp; serverfdp = serverfdp->next) poll_listen(serverfdp->fd, POLLIN); diff --git a/release/src/router/dnsmasq/src/dnsmasq.h b/release/src/router/dnsmasq/src/dnsmasq.h index afc00cf6791..feaa1926886 100644 --- a/release/src/router/dnsmasq/src/dnsmasq.h +++ b/release/src/router/dnsmasq/src/dnsmasq.h @@ -1060,6 +1060,7 @@ extern struct daemon { unsigned int duid_enterprise, duid_config_len; unsigned char *duid_config; char *dbus_name; + char *ubus_name; char *dump_file; int dump_mask; unsigned long soa_sn, soa_refresh, soa_retry, soa_expiry; @@ -1325,7 +1326,7 @@ void receive_query(struct listener *listen, time_t now); unsigned char *tcp_request(int confd, time_t now, union mysockaddr *local_addr, struct in_addr netmask, int auth_dns); void server_gone(struct server *server); -struct frec *get_new_frec(time_t now, int *wait, int force); +struct frec *get_new_frec(time_t now, int *wait, struct frec *force); int send_from(int fd, int nowild, char *packet, size_t len, union mysockaddr *to, union all_addr *source, unsigned int iface); diff --git a/release/src/router/dnsmasq/src/dnssec.c b/release/src/router/dnsmasq/src/dnssec.c index 0b1bbe1b464..a021efd9c6c 100644 --- a/release/src/router/dnsmasq/src/dnssec.c +++ b/release/src/router/dnsmasq/src/dnssec.c @@ -1002,7 +1002,7 @@ int dnssec_validate_ds(time_t now, struct dns_header *header, size_t plen, char cache_end_insert(); - log_query(F_NOEXTRA | F_UPSTREAM, name, NULL, "no DS"); + log_query(F_NOEXTRA | F_UPSTREAM, name, NULL, nons ? "no DS/cut" : "no DS"); } return STAT_OK; diff --git a/release/src/router/dnsmasq/src/forward.c b/release/src/router/dnsmasq/src/forward.c index c74aba167d9..641d6006424 100644 --- a/release/src/router/dnsmasq/src/forward.c +++ b/release/src/router/dnsmasq/src/forward.c @@ -348,7 +348,7 @@ static int forward_query(int udpfd, union mysockaddr *udpaddr, type &= ~SERV_DO_DNSSEC; if (daemon->servers && !flags) - forward = get_new_frec(now, NULL, 0); + forward = get_new_frec(now, NULL, NULL); /* table full - flags == 0, return REFUSED */ if (forward) @@ -1039,7 +1039,9 @@ void reply_query(int fd, int family, time_t now) /* Find the original query that started it all.... */ for (orig = forward; orig->dependent; orig = orig->dependent); - if (--orig->work_counter == 0 || !(new = get_new_frec(now, NULL, 1))) + /* Make sure we don't expire and free the orig frec during the + allocation of a new one. */ + if (--orig->work_counter == 0 || !(new = get_new_frec(now, NULL, orig))) status = STAT_ABANDONED; else { @@ -2251,9 +2253,10 @@ static void free_frec(struct frec *f) else return *wait zero if one available, or *wait is delay to when the oldest in-use record will expire. Impose an absolute limit of 4*TIMEOUT before we wipe things (for random sockets). - If force is set, always return a result, even if we have - to allocate above the limit. */ -struct frec *get_new_frec(time_t now, int *wait, int force) + If force is non-NULL, always return a result, even if we have + to allocate above the limit, and never free the record pointed + to by the force argument. */ +struct frec *get_new_frec(time_t now, int *wait, struct frec *force) { struct frec *f, *oldest, *target; int count; @@ -2270,7 +2273,7 @@ struct frec *get_new_frec(time_t now, int *wait, int force) /* Don't free DNSSEC sub-queries here, as we may end up with dangling references to them. They'll go when their "real" query is freed. */ - if (!f->dependent) + if (!f->dependent && f != force) #endif { if (difftime(now, f->time) >= 4*TIMEOUT) diff --git a/release/src/router/dnsmasq/src/option.c b/release/src/router/dnsmasq/src/option.c index 7081a478773..8561df2d815 100644 --- a/release/src/router/dnsmasq/src/option.c +++ b/release/src/router/dnsmasq/src/option.c @@ -238,7 +238,7 @@ static const struct myoption opts[] = { "caa-record", 1, 0 , LOPT_CAA }, { "dns-rr", 1, 0, LOPT_RR }, { "enable-dbus", 2, 0, '1' }, - { "enable-ubus", 0, 0, LOPT_UBUS }, + { "enable-ubus", 2, 0, LOPT_UBUS }, { "bootp-dynamic", 2, 0, '3' }, { "dhcp-mac", 1, 0, '4' }, { "no-ping", 0, 0, '5' }, @@ -428,7 +428,7 @@ static struct { { 'z', OPT_NOWILD, NULL, gettext_noop("Bind only to interfaces in use."), NULL }, { 'Z', OPT_ETHERS, NULL, gettext_noop("Read DHCP static host information from %s."), ETHERSFILE }, { '1', ARG_ONE, "[=]", gettext_noop("Enable the DBus interface for setting upstream servers, etc."), NULL }, - { LOPT_UBUS, OPT_UBUS, NULL, gettext_noop("Enable the UBus interface."), NULL }, + { LOPT_UBUS, ARG_ONE, "[=]", gettext_noop("Enable the UBus interface."), NULL }, { '2', ARG_DUP, "", gettext_noop("Do not provide DHCP on this interface, only provide DNS."), NULL }, { '3', ARG_DUP, "[=tag:]...", gettext_noop("Enable dynamic address allocation for bootp."), NULL }, { '4', ARG_DUP, "set:,", gettext_noop("Map MAC address (with wildcards) to option set."), NULL }, @@ -1881,7 +1881,15 @@ static int one_opt(int option, char *arg, char *errstr, char *gen_err, int comma else daemon->dbus_name = DNSMASQ_SERVICE; break; - + + case LOPT_UBUS: /* --enable-ubus */ + set_option_bool(OPT_UBUS); + if (arg) + daemon->ubus_name = opt_string_alloc(arg); + else + daemon->ubus_name = DNSMASQ_UBUS_NAME; + break; + case '8': /* --log-facility */ /* may be a filename */ if (strchr(arg, '/') || strcmp (arg, "-") == 0) diff --git a/release/src/router/dnsmasq/src/ubus.c b/release/src/router/dnsmasq/src/ubus.c index c7f6b1995ec..5f812877927 100644 --- a/release/src/router/dnsmasq/src/ubus.c +++ b/release/src/router/dnsmasq/src/ubus.c @@ -38,7 +38,7 @@ static struct ubus_object_type ubus_object_type = UBUS_OBJECT_TYPE("dnsmasq", ubus_object_methods); static struct ubus_object ubus_object = { - .name = "dnsmasq", + .name = NULL, .type = &ubus_object_type, .methods = ubus_object_methods, .n_methods = ARRAY_SIZE(ubus_object_methods), @@ -94,6 +94,7 @@ void ubus_init() return; } + ubus_object.name = daemon->ubus_name; ret = ubus_add_object(ubus, &ubus_object); if (ret) { From 1ec4a87337d584584f4f5c7b60050354f4907a5d Mon Sep 17 00:00:00 2001 From: Vladislav Grishenko Date: Sun, 5 Apr 2020 17:44:48 +0500 Subject: [PATCH 02/25] dropbear: sync accepted ed25519 support from upstream --- release/src/router/dropbear/.travis.yml | 1 + release/src/router/dropbear/FUZZER-NOTES.md | 3 + release/src/router/dropbear/Makefile.in | 7 +- release/src/router/dropbear/default_options.h | 1 + release/src/router/dropbear/fuzz-common.c | 8 + release/src/router/dropbear/fuzz-hostkeys.c | 10 ++ .../router/dropbear/fuzzer-kexcurve25519.c | 72 ++++++++ release/src/router/dropbear/keyimport.c | 158 ++++++++++++++++-- 8 files changed, 244 insertions(+), 16 deletions(-) create mode 100644 release/src/router/dropbear/fuzzer-kexcurve25519.c diff --git a/release/src/router/dropbear/.travis.yml b/release/src/router/dropbear/.travis.yml index 9bcbce48bc0..99499c84070 100644 --- a/release/src/router/dropbear/.travis.yml +++ b/release/src/router/dropbear/.travis.yml @@ -57,6 +57,7 @@ script: - ~/inst/bin/dropbearkey -t ecdsa -f testec256 -s 256 - ~/inst/bin/dropbearkey -t ecdsa -f testec384 -s 384 - ~/inst/bin/dropbearkey -t ecdsa -f testec521 -s 521 + - ~/inst/bin/dropbearkey -t ed25519 -f tested25519 - test -z $DO_FUZZ || ./fuzzers_test.sh branches: diff --git a/release/src/router/dropbear/FUZZER-NOTES.md b/release/src/router/dropbear/FUZZER-NOTES.md index 7b882389cb2..4967eba1170 100644 --- a/release/src/router/dropbear/FUZZER-NOTES.md +++ b/release/src/router/dropbear/FUZZER-NOTES.md @@ -72,3 +72,6 @@ Current fuzzers are - [fuzzer-kexecdh](fuzzer-kexecdh.c) - test Elliptic Curve Diffie-Hellman key exchange like fuzzer-kexdh. This is testing libtommath ECC routines. + +- [fuzzer-kexcurve25519](fuzzer-kexcurve25519.c) - test Curve25519 Elliptic Curve Diffie-Hellman key exchange + like fuzzer-kexecdh. This is testing `dropbear_curve25519_scalarmult()` and other libtommath routines. diff --git a/release/src/router/dropbear/Makefile.in b/release/src/router/dropbear/Makefile.in index 98e942b0215..9f61ace2300 100644 --- a/release/src/router/dropbear/Makefile.in +++ b/release/src/router/dropbear/Makefile.in @@ -256,7 +256,7 @@ tidy: ## Fuzzing targets # list of fuzz targets -FUZZ_TARGETS=fuzzer-preauth fuzzer-pubkey fuzzer-verify fuzzer-preauth_nomaths fuzzer-kexdh fuzzer-kexecdh +FUZZ_TARGETS=fuzzer-preauth fuzzer-pubkey fuzzer-verify fuzzer-preauth_nomaths fuzzer-kexdh fuzzer-kexecdh fuzzer-kexcurve25519 FUZZER_OPTIONS = $(addsuffix .options, $(FUZZ_TARGETS)) @@ -293,6 +293,9 @@ fuzzer-kexdh: fuzzer-kexdh.o $(HEADERS) $(LIBTOM_DEPS) Makefile $(svrfuzzobjs) fuzzer-kexecdh: fuzzer-kexecdh.o $(HEADERS) $(LIBTOM_DEPS) Makefile $(svrfuzzobjs) $(CXX) $(CXXFLAGS) $@.o $(LDFLAGS) $(svrfuzzobjs) -o $@$(EXEEXT) $(LIBTOM_LIBS) $(LIBS) $(FUZZLIB) @CRYPTLIB@ +fuzzer-kexcurve25519: fuzzer-kexcurve25519.o fuzz-harness.o + $(CXX) $(CXXFLAGS) $@.o $(LDFLAGS) $(svrfuzzobjs) -o $@$(EXEEXT) $(LIBTOM_LIBS) $(LIBS) $(FUZZLIB) @CRYPTLIB@ + fuzzer-%.options: Makefile echo "[libfuzzer]" > $@ echo "max_len = 50000" >> $@ @@ -303,7 +306,9 @@ fuzz-hostkeys: dropbearkey -t rsa -f keyr dropbearkey -t dss -f keyd dropbearkey -t ecdsa -size 256 -f keye + dropbearkey -t ed25519 -f keyed25519 echo > hostkeys.c /usr/bin/xxd -i -a keyr >> hostkeys.c /usr/bin/xxd -i -a keye >> hostkeys.c /usr/bin/xxd -i -a keyd >> hostkeys.c + /usr/bin/xxd -i -a keyed25519 >> hostkeys.c diff --git a/release/src/router/dropbear/default_options.h b/release/src/router/dropbear/default_options.h index f89636e1625..5b232dd42f0 100644 --- a/release/src/router/dropbear/default_options.h +++ b/release/src/router/dropbear/default_options.h @@ -125,6 +125,7 @@ IMPORTANT: Some options will require "make clean" after changes */ #define DROPBEAR_DEFAULT_RSA_SIZE 2048 /* DSS is always 1024 */ /* ECDSA defaults to largest size configured, usually 521 */ +/* Ed25519 is always 256 */ /* Add runtime flag "-R" to generate hostkeys as-needed when the first connection using that key type occurs. diff --git a/release/src/router/dropbear/fuzz-common.c b/release/src/router/dropbear/fuzz-common.c index 5c90c45c01a..b1b00f6e1a9 100644 --- a/release/src/router/dropbear/fuzz-common.c +++ b/release/src/router/dropbear/fuzz-common.c @@ -112,6 +112,14 @@ static void load_fixed_hostkeys(void) { dropbear_exit("failed fixed ecdsa hostkey"); } + buf_setlen(b, 0); + buf_putbytes(b, keyed25519, keyed25519_len); + buf_setpos(b, 0); + type = DROPBEAR_SIGNKEY_ED25519; + if (buf_get_priv_key(b, svr_opts.hostkey, &type) == DROPBEAR_FAILURE) { + dropbear_exit("failed fixed ed25519 hostkey"); + } + buf_free(b); } diff --git a/release/src/router/dropbear/fuzz-hostkeys.c b/release/src/router/dropbear/fuzz-hostkeys.c index dc1615d1928..3fff5cbb704 100644 --- a/release/src/router/dropbear/fuzz-hostkeys.c +++ b/release/src/router/dropbear/fuzz-hostkeys.c @@ -127,3 +127,13 @@ unsigned char keyd[] = { 0xf9, 0x39 }; unsigned int keyd_len = 458; +unsigned char keyed25519[] = { + 0x00, 0x00, 0x00, 0x0b, 0x73, 0x73, 0x68, 0x2d, 0x65, 0x64, 0x32, 0x35, + 0x35, 0x31, 0x39, 0x00, 0x00, 0x00, 0x40, 0x10, 0xb3, 0x79, 0x06, 0xe5, + 0x9b, 0xe7, 0xe4, 0x6e, 0xec, 0xfe, 0xa5, 0x39, 0x21, 0x7c, 0xf6, 0x66, + 0x8c, 0x0b, 0x6a, 0x01, 0x09, 0x05, 0xc7, 0x4f, 0x64, 0xa8, 0x24, 0xd2, + 0x8d, 0xbd, 0xdd, 0xc6, 0x3c, 0x99, 0x1b, 0x2d, 0x3e, 0x33, 0x90, 0x19, + 0xa4, 0xd5, 0xe9, 0x23, 0xfe, 0x8e, 0xd6, 0xd4, 0xf9, 0xb1, 0x11, 0x69, + 0x7c, 0x57, 0x52, 0x0e, 0x41, 0xdb, 0x1b, 0x12, 0x87, 0xfa, 0xc9 +}; +unsigned int keyed25519_len = 83; diff --git a/release/src/router/dropbear/fuzzer-kexcurve25519.c b/release/src/router/dropbear/fuzzer-kexcurve25519.c new file mode 100644 index 00000000000..f2eab14aa1b --- /dev/null +++ b/release/src/router/dropbear/fuzzer-kexcurve25519.c @@ -0,0 +1,72 @@ +#include "fuzz.h" +#include "session.h" +#include "fuzz-wrapfd.h" +#include "debug.h" +#include "runopts.h" +#include "algo.h" +#include "bignum.h" + +int LLVMFuzzerTestOneInput(const uint8_t *Data, size_t Size) { + static int once = 0; + static struct key_context* keep_newkeys = NULL; + /* number of generated parameters is limited by the timeout for the first run. + TODO move this to the libfuzzer initialiser function instead if the timeout + doesn't apply there */ + #define NUM_PARAMS 20 + static struct kex_curve25519_param *curve25519_params[NUM_PARAMS]; + + if (!once) { + fuzz_common_setup(); + fuzz_svr_setup(); + + keep_newkeys = (struct key_context*)m_malloc(sizeof(struct key_context)); + keep_newkeys->algo_kex = fuzz_get_algo(sshkex, "curve25519-sha256"); + keep_newkeys->algo_hostkey = DROPBEAR_SIGNKEY_ED25519; + ses.newkeys = keep_newkeys; + + /* Pre-generate parameters */ + int i; + for (i = 0; i < NUM_PARAMS; i++) { + curve25519_params[i] = gen_kexcurve25519_param(); + } + + once = 1; + } + + if (fuzz_set_input(Data, Size) == DROPBEAR_FAILURE) { + return 0; + } + + m_malloc_set_epoch(1); + + if (setjmp(fuzz.jmp) == 0) { + /* Based on recv_msg_kexdh_init()/send_msg_kexdh_reply() + with DROPBEAR_KEX_CURVE25519 */ + ses.newkeys = keep_newkeys; + + /* Choose from the collection of curve25519 params */ + unsigned int e = buf_getint(fuzz.input); + struct kex_curve25519_param *curve25519_param = curve25519_params[e % NUM_PARAMS]; + + buffer * ecdh_qs = buf_getstringbuf(fuzz.input); + + ses.kexhashbuf = buf_new(KEXHASHBUF_MAX_INTS); + kexcurve25519_comb_key(curve25519_param, ecdh_qs, svr_opts.hostkey); + + mp_clear(ses.dh_K); + m_free(ses.dh_K); + buf_free(ecdh_qs); + + buf_free(ses.hash); + buf_free(ses.session_id); + /* kexhashbuf is freed in kexdh_comb_key */ + + m_malloc_free_epoch(1, 0); + } else { + m_malloc_free_epoch(1, 1); + TRACE(("dropbear_exit longjmped")) + /* dropbear_exit jumped here */ + } + + return 0; +} diff --git a/release/src/router/dropbear/keyimport.c b/release/src/router/dropbear/keyimport.c index 7304e58e2eb..ad0c5305df7 100644 --- a/release/src/router/dropbear/keyimport.c +++ b/release/src/router/dropbear/keyimport.c @@ -35,6 +35,15 @@ #include "buffer.h" #include "dbutil.h" #include "ecc.h" +#include "ssh.h" + +static const unsigned char OSSH_PKEY_BLOB[] = + "openssh-key-v1\0" /* AUTH_MAGIC */ + "\0\0\0\4none" /* cipher name*/ + "\0\0\0\4none" /* kdf name */ + "\0\0\0\0" /* kdf */ + "\0\0\0\1"; /* key num */ +#define OSSH_PKEY_BLOBLEN (sizeof(OSSH_PKEY_BLOB) - 1) #if DROPBEAR_ECDSA static const unsigned char OID_SEC256R1_BLOB[] = {0x2a, 0x86, 0x48, 0xce, 0x3d, 0x03, 0x01, 0x07}; @@ -352,7 +361,7 @@ struct mpint_pos { void *start; int bytes; }; * Code to read and write OpenSSH private keys. */ -enum { OSSH_DSA, OSSH_RSA, OSSH_EC }; +enum { OSSH_DSA, OSSH_RSA, OSSH_EC, OSSH_PKEY }; struct openssh_key { int type; int encrypted; @@ -364,11 +373,12 @@ struct openssh_key { static struct openssh_key *load_openssh_key(const char *filename) { struct openssh_key *ret; + buffer *buf = NULL; FILE *fp = NULL; char buffer[256]; char *errmsg = NULL, *p = NULL; int headers_done; - unsigned long len, outlen; + unsigned long len; ret = (struct openssh_key*)m_malloc(sizeof(struct openssh_key)); ret->keyblob = NULL; @@ -397,12 +407,15 @@ static struct openssh_key *load_openssh_key(const char *filename) ret->type = OSSH_DSA; else if (!strcmp(buffer, "-----BEGIN EC PRIVATE KEY-----\n")) ret->type = OSSH_EC; + else if (!strcmp(buffer, "-----BEGIN OPENSSH PRIVATE KEY-----\n")) + ret->type = OSSH_PKEY; else { errmsg = "Unrecognised key type"; goto error; } headers_done = 0; + buf = buf_new(0); while (1) { if (!fgets(buffer, sizeof(buffer), fp)) { errmsg = "Unexpected end of file"; @@ -448,20 +461,31 @@ static struct openssh_key *load_openssh_key(const char *filename) } else { headers_done = 1; len = strlen(buffer); - outlen = len*4/3; - if (ret->keyblob_len + outlen > ret->keyblob_size) { - ret->keyblob_size = ret->keyblob_len + outlen + 256; - ret->keyblob = (unsigned char*)m_realloc(ret->keyblob, - ret->keyblob_size); - } - outlen = ret->keyblob_size - ret->keyblob_len; - if (base64_decode((const unsigned char *)buffer, len, - ret->keyblob + ret->keyblob_len, &outlen) != CRYPT_OK){ - errmsg = "Error decoding base64"; - goto error; - } - ret->keyblob_len += outlen; + buf = buf_resize(buf, buf->size + len); + buf_putbytes(buf, buffer, len); + } + } + + if (buf && buf->len) { + ret->keyblob_size = ret->keyblob_len + buf->len*4/3 + 256; + ret->keyblob = (unsigned char*)m_realloc(ret->keyblob, ret->keyblob_size); + len = ret->keyblob_size; + if (base64_decode((const unsigned char *)buf->data, buf->len, + ret->keyblob, &len) != CRYPT_OK){ + errmsg = "Error decoding base64"; + goto error; + } + ret->keyblob_len = len; + } + + if (ret->type == OSSH_PKEY) { + if (ret->keyblob_len < OSSH_PKEY_BLOBLEN || + memcmp(ret->keyblob, OSSH_PKEY_BLOB, OSSH_PKEY_BLOBLEN)) { + errmsg = "Error decoding OpenSSH key"; + goto error; } + ret->keyblob_len -= OSSH_PKEY_BLOBLEN; + memmove(ret->keyblob, ret->keyblob + OSSH_PKEY_BLOBLEN, ret->keyblob_len); } if (ret->keyblob_len == 0 || !ret->keyblob) { @@ -474,10 +498,18 @@ static struct openssh_key *load_openssh_key(const char *filename) goto error; } + if (buf) { + buf_burn(buf); + buf_free(buf); + } m_burn(buffer, sizeof(buffer)); return ret; error: + if (buf) { + buf_burn(buf); + buf_free(buf); + } m_burn(buffer, sizeof(buffer)); if (ret) { if (ret->keyblob) { @@ -569,6 +601,57 @@ static sign_key *openssh_read(const char *filename, const char * UNUSED(passphra #endif } + /* + * Now we have a decrypted key blob, which contains OpenSSH + * encoded private key. We must now untangle the OpenSSH format. + */ + if (key->type == OSSH_PKEY) { + blobbuf = buf_new(key->keyblob_len); + buf_putbytes(blobbuf, key->keyblob, key->keyblob_len); + buf_setpos(blobbuf, 0); + + /* limit length of private key blob */ + len = buf_getint(blobbuf); + buf_setlen(blobbuf, blobbuf->pos + len); + + type = DROPBEAR_SIGNKEY_ANY; + if (buf_get_pub_key(blobbuf, retkey, &type) + != DROPBEAR_SUCCESS) { + errmsg = "Error parsing OpenSSH key"; + goto ossh_error; + } + + /* restore full length */ + buf_setlen(blobbuf, key->keyblob_len); + + if (type != DROPBEAR_SIGNKEY_NONE) { + retkey->type = type; + /* limit length of private key blob */ + len = buf_getint(blobbuf); + buf_setlen(blobbuf, blobbuf->pos + len); +#if DROPBEAR_ED25519 + if (type == DROPBEAR_SIGNKEY_ED25519) { + buf_incrpos(blobbuf, 8); + buf_eatstring(blobbuf); + buf_eatstring(blobbuf); + buf_incrpos(blobbuf, -SSH_SIGNKEY_ED25519_LEN-4); + if (buf_get_ed25519_priv_key(blobbuf, retkey->ed25519key) + == DROPBEAR_SUCCESS) { + errmsg = NULL; + retval = retkey; + goto error; + } + } +#endif + } + + errmsg = "Unsupported OpenSSH key type"; + ossh_error: + sign_key_free(retkey); + retkey = NULL; + goto error; + } + /* * Now we have a decrypted key blob, which contains an ASN.1 * encoded private key. We must now untangle the ASN.1. @@ -1129,6 +1212,51 @@ static int openssh_write(const char *filename, sign_key *key, } #endif +#if DROPBEAR_ED25519 + if (key->type == DROPBEAR_SIGNKEY_ED25519) { + buffer *buf = buf_new(300); + keyblob = buf_new(100); + extrablob = buf_new(200); + + /* private key blob w/o header */ + buf_put_priv_key(keyblob, key, key->type); + buf_setpos(keyblob, 0); + buf_incrpos(keyblob, buf_getint(keyblob)); + len = buf_getint(keyblob); + + /* header */ + buf_putbytes(buf, OSSH_PKEY_BLOB, OSSH_PKEY_BLOBLEN); + + /* public key */ + buf_put_pub_key(buf, key, key->type); + + /* private key */ + buf_incrwritepos(extrablob, 4); + buf_put_pub_key(extrablob, key, key->type); + buf_putstring(extrablob, buf_getptr(keyblob, len), len); + /* comment */ + buf_putstring(extrablob, "", 0); + /* padding to cipher block length */ + len = (extrablob->len+8) & ~7; + for (i = 1; len - extrablob->len > 0; i++) + buf_putbyte(extrablob, i); + buf_setpos(extrablob, 0); + buf_putbytes(extrablob, "\0\0\0\0\0\0\0\0", 8); + buf_putbufstring(buf, extrablob); + + outlen = len = pos = buf->len; + outblob = (unsigned char*)m_malloc(outlen); + memcpy(outblob, buf->data, buf->len); + + buf_burn(buf); + buf_free(buf); + buf = NULL; + + header = "-----BEGIN OPENSSH PRIVATE KEY-----\n"; + footer = "-----END OPENSSH PRIVATE KEY-----\n"; + } +#endif + /* * Padding on OpenSSH keys is deterministic. The number of * padding bytes is always more than zero, and always at most From 735b52acc8397a881e754cc6772f8ceda3223ec9 Mon Sep 17 00:00:00 2001 From: Eric Sauvageau Date: Mon, 6 Apr 2020 21:38:11 -0400 Subject: [PATCH 03/25] Bumped revision to 384.16_1 --- release/src-rt/version.conf | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/release/src-rt/version.conf b/release/src-rt/version.conf index b91f39fa2ab..e8a8e77c76f 100644 --- a/release/src-rt/version.conf +++ b/release/src-rt/version.conf @@ -1,5 +1,5 @@ KERNEL_VER=3.0 FS_VER=0.4 SERIALNO=384.16 -EXTENDNO=0 +EXTENDNO=1 RCNO=0 From 08ae067e2901bb936293962d43546c0770f8ed86 Mon Sep 17 00:00:00 2001 From: hitched97 Date: Tue, 7 Apr 2020 10:40:03 -0400 Subject: [PATCH 04/25] Make use of all icons in client-list.svg. --- release/src/router/www/QoS_EZQoS.asp | 1 + release/src/router/www/client_function.js | 3 +- .../src/router/www/device-map/device-map.css | 24 ++++++++++++++++ release/src/router/www/index.asp | 28 +++++++++++++++++++ 4 files changed, 55 insertions(+), 1 deletion(-) diff --git a/release/src/router/www/QoS_EZQoS.asp b/release/src/router/www/QoS_EZQoS.asp index c9ffa4d0618..3cda0525a90 100644 --- a/release/src/router/www/QoS_EZQoS.asp +++ b/release/src/router/www/QoS_EZQoS.asp @@ -342,6 +342,7 @@ if(pm_support) { ["10", "iPhone"], ["11", "Apple TV"], ["12", "Set-Top Box"], ["13", ""], ["14", "iMac"], ["15", "ROG"], ["16", ""], ["17", ""], ["18", "Printer"], ["19", "Windows Phone"], ["20", "Android Tablet"], ["21", "iPad"], ["22", "Linux Device"], ["23", "Smart TV"], ["24", "Repeater"], ["25", "Kindle"], ["26", "Scanner"], ["27", "Chromecast"], ["28", "ASUS Smartphone"], ["29", "ASUS Pad"], ["30", "Windows"], ["31", "Android"], ["32", "Mac OS"] + , ["33", "Smartphone"], ["34", "Desktop"], ["35", "Windows Laptop"], ["36", "Linux"], ["37", "ASUS"], ["38", "ASUS Laptop"], ["39", "Smart Watch"], ["40", "Laptop"] ]; var device_type_array = new Array(); diff --git a/release/src/router/www/client_function.js b/release/src/router/www/client_function.js index 7d76b2d2c41..45284200063 100644 --- a/release/src/router/www/client_function.js +++ b/release/src/router/www/client_function.js @@ -580,7 +580,8 @@ function popClientListEditTable(event) { //build device icon list start var clientListIconArray = [["Windows device", "1"], ["Router", "2"], ["NAS/Server", "4"], ["IP Cam", "5"], ["Macbook", "6"], ["Game Console", "7"], ["Android Phone", "9"], ["iPhone", "10"], ["Apple TV", "11"], ["Set-top Box", "12"], ["iMac", "14"], ["ROG", "15"], ["Printer", "18"], ["Windows Phone", "19"], ["Android Tablet", "20"], ["iPad", "21"], ["Linux Device", "22"], - ["Smart TV", "23"], ["Repeater", "24"], ["Kindle", "25"], ["Scanner", "26"], ["Chromecast", "27"], ["ASUS smartphone", "28"], ["ASUS Pad", "29"], ["Windows", "30"], ["Android", "31"], ["Mac OS", "32"]]; + ["Smart TV", "23"], ["Repeater", "24"], ["Kindle", "25"], ["Scanner", "26"], ["Chromecast", "27"], ["ASUS smartphone", "28"], ["ASUS Pad", "29"], ["Windows", "30"], ["Android", "31"], ["Mac OS", "32"], + ["Smartphone", "33"], ["Desktop", "34"], ["Windows Laptop", "35"], ["Linux", "36"], ["ASUS", "37"], ["ASUS Laptop", "38"], ["Smart Watch", "39"], ["Laptop", "40"]]; var eachColCount = 7; var colCount = parseInt(clientListIconArray.length / eachColCount) + 1; diff --git a/release/src/router/www/device-map/device-map.css b/release/src/router/www/device-map/device-map.css index 27bd10aade1..754427eebfb 100644 --- a/release/src/router/www/device-map/device-map.css +++ b/release/src/router/www/device-map/device-map.css @@ -161,6 +161,12 @@ Android 31 Mac OS 32 Smartphone 33 Desktop 34 +Windows Laptop 35 +Linux 36 +ASUS 37 +ASUS Laptop 38 +Smart Watch 39 +Laptop 40 */ .type0{ background-image:url('/images/New_ui/networkmap/client.svg'); @@ -268,6 +274,24 @@ Desktop 34 .type34{ background-position:100% 50%; } +.type35{ + background-position:16.5% 33%; +} +.type36{ + background-position:-0.2% 0%; +} +.type37{ + background-position:66.5% 0%; +} +.type38{ + background-position:66.5% 33%; +} +.type39{ + background-position:83% 67%; +} +.type40{ + background-position:100% 0%; +} .type0:hover{ background-color: #FFFFFF; diff --git a/release/src/router/www/index.asp b/release/src/router/www/index.asp index 028a19b698f..245636d5b9d 100644 --- a/release/src/router/www/index.asp +++ b/release/src/router/www/index.asp @@ -2449,6 +2449,34 @@ function AiMesh_promoteHint() {
+ +
+ + + + +
+ + +
+ + +
+ + +
+ + +
+ + +
+ + +
+ + +