[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[PATCH] config: Parse KexAlgorithms, MACs, improve Include
[Thread Prev] | [Thread Next]
- Subject: [PATCH] config: Parse KexAlgorithms, MACs, improve Include
- From: Jakub Jelen <jjelen@xxxxxxxxxx>
- Reply-to: libssh@xxxxxxxxxx
- Date: Tue, 07 Nov 2017 14:28:31 +0100
- To: libssh@xxxxxxxxxx
Hello, the attached patch contains a series of patches improving a support for ssh_config parsing by adding a support for KexAlgorithms and MACs options. It is also enhancing Include directive parsing to support glob as it is currently supported in OpenSSH. Regards, -- Jakub Jelen Software Engineer Security Technologies Red Hat, Inc.
From 3ecf156ecf7afe0cd623063defd2f075b8dfb426 Mon Sep 17 00:00:00 2001 From: Stefan Dordevic <sdordevi@xxxxxxxxxx> Date: Mon, 23 Oct 2017 14:32:41 +0200 Subject: [PATCH 1/5] config: Parse KexAlgorithms option Signed-off-by: Jakub Jelen <jjelen@xxxxxxxxxx> --- src/config.c | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/src/config.c b/src/config.c index 25d64998..1429f751 100644 --- a/src/config.c +++ b/src/config.c @@ -43,6 +43,7 @@ enum ssh_config_opcode_e { SOC_USERNAME, SOC_IDENTITY, SOC_CIPHERS, + SOC_KEXALGORITHMS, SOC_COMPRESSION, SOC_TIMEOUT, SOC_PROTOCOL, @@ -69,6 +70,7 @@ static struct ssh_config_keyword_table_s ssh_config_keyword_table[] = { { "user", SOC_USERNAME }, { "identityfile", SOC_IDENTITY }, { "ciphers", SOC_CIPHERS }, + { "kexalgorithms", SOC_KEXALGORITHMS }, { "compression", SOC_COMPRESSION }, { "connecttimeout", SOC_TIMEOUT }, { "protocol", SOC_PROTOCOL }, @@ -325,6 +327,12 @@ static int ssh_config_parse_line(ssh_session session, const char *line, ssh_options_set(session, SSH_OPTIONS_CIPHERS_S_C, p); } break; + case SOC_KEXALGORITHMS: + p = ssh_config_get_str_tok(&s, NULL); + if (p && *parsing) { + ssh_options_set(session, SSH_OPTIONS_KEY_EXCHANGE, p); + } + break; case SOC_COMPRESSION: i = ssh_config_get_yesno(&s, -1); if (i >= 0 && *parsing) { -- 2.13.6 From c19e78d0e0c7008c2c35a55ff1e2c187b8ac1840 Mon Sep 17 00:00:00 2001 From: Jakub Jelen <jjelen@xxxxxxxxxx> Date: Mon, 23 Oct 2017 14:53:55 +0200 Subject: [PATCH 2/5] torture_options: Verify Key exchange algorithms are set properly Signed-off-by: Jakub Jelen <jjelen@xxxxxxxxxx> --- tests/unittests/torture_options.c | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) diff --git a/tests/unittests/torture_options.c b/tests/unittests/torture_options.c index f3197b8f..79b58a3a 100644 --- a/tests/unittests/torture_options.c +++ b/tests/unittests/torture_options.c @@ -59,6 +59,25 @@ static void torture_options_set_ciphers(void **state) { assert_false(rc == 0); } +static void torture_options_set_key_exchange(void **state) { + ssh_session session = *state; + int rc; + + /* Test known kexes */ + rc = ssh_options_set(session, SSH_OPTIONS_KEY_EXCHANGE, "curve25519-sha256@xxxxxxxxxx,ecdh-sha2-nistp256,diffie-hellman-group14-sha1"); + assert_true(rc == 0); + assert_string_equal(session->opts.wanted_methods[SSH_KEX], "curve25519-sha256@xxxxxxxxxx,ecdh-sha2-nistp256,diffie-hellman-group14-sha1"); + + /* Test one unknown kex */ + rc = ssh_options_set(session, SSH_OPTIONS_KEY_EXCHANGE, "curve25519-sha256@xxxxxxxxxx,unknown-crap@xxxxxxxxxxx,diffie-hellman-group14-sha1"); + assert_true(rc == 0); + assert_string_equal(session->opts.wanted_methods[SSH_KEX], "curve25519-sha256@xxxxxxxxxx,diffie-hellman-group14-sha1"); + + /* Test all unknown kexes */ + rc = ssh_options_set(session, SSH_OPTIONS_KEY_EXCHANGE, "unknown-crap@xxxxxxxxxxx,more-crap@xxxxxxxxxxx"); + assert_false(rc == 0); +} + static void torture_options_set_macs(void **state) { ssh_session session = *state; int rc; @@ -303,6 +322,7 @@ int torture_run_tests(void) { cmocka_unit_test_setup_teardown(torture_options_get_identity, setup, teardown), cmocka_unit_test_setup_teardown(torture_options_proxycommand, setup, teardown), cmocka_unit_test_setup_teardown(torture_options_set_ciphers, setup, teardown), + cmocka_unit_test_setup_teardown(torture_options_set_key_exchange, setup, teardown), cmocka_unit_test_setup_teardown(torture_options_set_macs, setup, teardown), }; -- 2.13.6 From 721c2101641607fa6ba0a727a23832e26ed93fba Mon Sep 17 00:00:00 2001 From: Jakub Jelen <jjelen@xxxxxxxxxx> Date: Mon, 23 Oct 2017 15:06:12 +0200 Subject: [PATCH 3/5] torture_config: KexAlgorithms parsing in ssh_config Signed-off-by: Jakub Jelen <jjelen@xxxxxxxxxx> --- tests/unittests/torture_config.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/tests/unittests/torture_config.c b/tests/unittests/torture_config.c index 0b17a7ab..ec0dde53 100644 --- a/tests/unittests/torture_config.c +++ b/tests/unittests/torture_config.c @@ -4,6 +4,7 @@ #include "torture.h" #include "libssh/options.h" +#include "libssh/session.h" #define LIBSSH_TESTCONFIG1 "libssh_testconfig1.tmp" #define LIBSSH_TESTCONFIG2 "libssh_testconfig2.tmp" @@ -13,6 +14,7 @@ #define USERNAME "testuser" #define PROXYCMD "ssh -q -W %h:%p gateway.example.com" #define ID_FILE "/etc/xxx" +#define KEXALGORITHMS "ecdh-sha2-nistp521,diffie-hellman-group14-sha1" static int setup_config_files(void **state) { @@ -29,7 +31,8 @@ static int setup_config_files(void **state) "Include "LIBSSH_TESTCONFIG3"\n" "ProxyCommand "PROXYCMD"\n\n"); torture_write_file(LIBSSH_TESTCONFIG3, - "\n\nIdentityFile "ID_FILE"\n"); + "\n\nIdentityFile "ID_FILE"\n" + "\n\nKexAlgorithms "KEXALGORITHMS"\n"); /* Multiple Port settings -> parsing returns early. */ torture_write_file(LIBSSH_TESTCONFIG4, @@ -85,6 +88,7 @@ static void torture_config_from_file(void **state) { assert_string_equal(v, USERNAME); ssh_string_free_char(v); + assert_string_equal(session->opts.wanted_methods[SSH_KEX], KEXALGORITHMS); } /** -- 2.13.6 From c9fce1bf48e1c9c89dab1ac31f0be9bf0da41015 Mon Sep 17 00:00:00 2001 From: Jakub Jelen <jjelen@xxxxxxxxxx> Date: Mon, 23 Oct 2017 16:33:28 +0200 Subject: [PATCH 4/5] config: support for MACs Signed-off-by: Jakub Jelen <jjelen@xxxxxxxxxx> --- src/config.c | 9 +++++++++ tests/unittests/torture_config.c | 7 ++++++- tests/unittests/torture_options.c | 5 +++++ 3 files changed, 20 insertions(+), 1 deletion(-) diff --git a/src/config.c b/src/config.c index 1429f751..553d21bd 100644 --- a/src/config.c +++ b/src/config.c @@ -44,6 +44,7 @@ enum ssh_config_opcode_e { SOC_IDENTITY, SOC_CIPHERS, SOC_KEXALGORITHMS, + SOC_MACS, SOC_COMPRESSION, SOC_TIMEOUT, SOC_PROTOCOL, @@ -71,6 +72,7 @@ static struct ssh_config_keyword_table_s ssh_config_keyword_table[] = { { "identityfile", SOC_IDENTITY }, { "ciphers", SOC_CIPHERS }, { "kexalgorithms", SOC_KEXALGORITHMS }, + { "macs", SOC_MACS }, { "compression", SOC_COMPRESSION }, { "connecttimeout", SOC_TIMEOUT }, { "protocol", SOC_PROTOCOL }, @@ -333,6 +335,13 @@ static int ssh_config_parse_line(ssh_session session, const char *line, ssh_options_set(session, SSH_OPTIONS_KEY_EXCHANGE, p); } break; + case SOC_MACS: + p = ssh_config_get_str_tok(&s, NULL); + if (p && *parsing) { + ssh_options_set(session, SSH_OPTIONS_HMAC_C_S, p); + ssh_options_set(session, SSH_OPTIONS_HMAC_S_C, p); + } + break; case SOC_COMPRESSION: i = ssh_config_get_yesno(&s, -1); if (i >= 0 && *parsing) { diff --git a/tests/unittests/torture_config.c b/tests/unittests/torture_config.c index ec0dde53..a0b40239 100644 --- a/tests/unittests/torture_config.c +++ b/tests/unittests/torture_config.c @@ -15,6 +15,7 @@ #define PROXYCMD "ssh -q -W %h:%p gateway.example.com" #define ID_FILE "/etc/xxx" #define KEXALGORITHMS "ecdh-sha2-nistp521,diffie-hellman-group14-sha1" +#define MACS "hmac-sha1,hmac-sha2-256" static int setup_config_files(void **state) { @@ -32,7 +33,8 @@ static int setup_config_files(void **state) "ProxyCommand "PROXYCMD"\n\n"); torture_write_file(LIBSSH_TESTCONFIG3, "\n\nIdentityFile "ID_FILE"\n" - "\n\nKexAlgorithms "KEXALGORITHMS"\n"); + "\n\nKexAlgorithms "KEXALGORITHMS"\n" + "\n\nMACs "MACS"\n"); /* Multiple Port settings -> parsing returns early. */ torture_write_file(LIBSSH_TESTCONFIG4, @@ -89,6 +91,9 @@ static void torture_config_from_file(void **state) { ssh_string_free_char(v); assert_string_equal(session->opts.wanted_methods[SSH_KEX], KEXALGORITHMS); + + assert_string_equal(session->opts.wanted_methods[SSH_MAC_C_S], MACS); + assert_string_equal(session->opts.wanted_methods[SSH_MAC_S_C], MACS); } /** diff --git a/tests/unittests/torture_options.c b/tests/unittests/torture_options.c index 79b58a3a..3c1121bb 100644 --- a/tests/unittests/torture_options.c +++ b/tests/unittests/torture_options.c @@ -87,6 +87,11 @@ static void torture_options_set_macs(void **state) { assert_true(rc == 0); assert_string_equal(session->opts.wanted_methods[SSH_MAC_S_C], "hmac-sha1"); + /* Test multiple known MACs */ + rc = ssh_options_set(session, SSH_OPTIONS_HMAC_S_C, "hmac-sha1,hmac-sha2-256"); + assert_true(rc == 0); + assert_string_equal(session->opts.wanted_methods[SSH_MAC_S_C], "hmac-sha1,hmac-sha2-256"); + /* Test unknown MACs */ rc = ssh_options_set(session, SSH_OPTIONS_HMAC_S_C, "unknown-crap@xxxxxxxxxxx,hmac-sha1,unknown@xxxxxxxxxxx"); assert_true(rc == 0); -- 2.13.6 From 8cced50a32dc7579100e2d024c184115205403ff Mon Sep 17 00:00:00 2001 From: NoName115 <robert.kolcun@xxxxxxxxx> Date: Wed, 25 Oct 2017 14:20:52 +0200 Subject: [PATCH 5/5] config: glob support for include with test Signed-off-by: Jakub Jelen <jjelen@xxxxxxxxxx> --- src/config.c | 28 +++++++++++++++++++++++++++- tests/unittests/torture_config.c | 40 ++++++++++++++++++++++++++++++++++++++++ 2 files changed, 67 insertions(+), 1 deletion(-) diff --git a/src/config.c b/src/config.c index 553d21bd..ff646c3d 100644 --- a/src/config.c +++ b/src/config.c @@ -27,6 +27,7 @@ #include <stdio.h> #include <string.h> #include <stdlib.h> +#include <glob.h> #include "libssh/priv.h" #include "libssh/session.h" @@ -221,6 +222,31 @@ static void local_parse_file(ssh_session session, const char *filename, int *par return; } +static void local_parse_glob(ssh_session session, const char *fileglob, int *parsing, int seen[]) { + glob_t globbuf; + int rt; + u_int i; + + memset(&globbuf, 0, sizeof(globbuf)); + rt = glob(fileglob, GLOB_TILDE, NULL, &globbuf); + if (rt == GLOB_NOMATCH) { + globfree(&globbuf); + return; + } + else if (rt != 0) { + SSH_LOG(SSH_LOG_RARE, "Glob error: %s", + fileglob); + globfree(&globbuf); + return; + } + + for (i = 0; i < globbuf.gl_pathc; i++) { + local_parse_file(session, globbuf.gl_pathv[i], parsing, seen); + } + + globfree(&globbuf); +} + static int ssh_config_parse_line(ssh_session session, const char *line, unsigned int count, int *parsing, int seen[]) { enum ssh_config_opcode_e opcode; @@ -266,7 +292,7 @@ static int ssh_config_parse_line(ssh_session session, const char *line, p = ssh_config_get_str_tok(&s, NULL); if (p && *parsing) { - local_parse_file(session, p, parsing, seen); + local_parse_glob(session, p, parsing, seen); } break; case SOC_HOST: { diff --git a/tests/unittests/torture_config.c b/tests/unittests/torture_config.c index a0b40239..8ca097c7 100644 --- a/tests/unittests/torture_config.c +++ b/tests/unittests/torture_config.c @@ -10,6 +10,9 @@ #define LIBSSH_TESTCONFIG2 "libssh_testconfig2.tmp" #define LIBSSH_TESTCONFIG3 "libssh_testconfig3.tmp" #define LIBSSH_TESTCONFIG4 "libssh_testconfig4.tmp" +#define LIBSSH_TESTCONFIG5 "libssh_testconfig5.tmp" +#define LIBSSH_TESTCONFIG6 "libssh_testconfig6.tmp" +#define LIBSSH_TESTCONFIGGLOB "libssh_testc*[36].tmp" #define USERNAME "testuser" #define PROXYCMD "ssh -q -W %h:%p gateway.example.com" @@ -25,6 +28,8 @@ static int setup_config_files(void **state) unlink(LIBSSH_TESTCONFIG2); unlink(LIBSSH_TESTCONFIG3); unlink(LIBSSH_TESTCONFIG4); + unlink(LIBSSH_TESTCONFIG5); + unlink(LIBSSH_TESTCONFIG6); torture_write_file(LIBSSH_TESTCONFIG1, "User "USERNAME"\nInclude "LIBSSH_TESTCONFIG2"\n\n"); @@ -40,6 +45,13 @@ static int setup_config_files(void **state) torture_write_file(LIBSSH_TESTCONFIG4, "Port 123\nPort 456\n"); + /* Testing glob include */ + torture_write_file(LIBSSH_TESTCONFIG5, + "User "USERNAME"\nInclude "LIBSSH_TESTCONFIGGLOB"\n\n"); + + torture_write_file(LIBSSH_TESTCONFIG6, + "ProxyCommand "PROXYCMD"\n\n"); + session = ssh_new(); *state = session; @@ -52,6 +64,8 @@ static int teardown(void **state) unlink(LIBSSH_TESTCONFIG2); unlink(LIBSSH_TESTCONFIG3); unlink(LIBSSH_TESTCONFIG4); + unlink(LIBSSH_TESTCONFIG5); + unlink(LIBSSH_TESTCONFIG6); ssh_free(*state); @@ -105,6 +119,29 @@ static void torture_config_double_ports(void **state) { assert_true(ret == 0); } +static void torture_config_glob(void **state) { + ssh_session session = *state; + int ret; + char *v; + + ret = ssh_config_parse_file(session, LIBSSH_TESTCONFIG5); + assert_true(ret == 0); + + /* Test the variable presence */ + + ret = ssh_options_get(session, SSH_OPTIONS_PROXYCOMMAND, &v); + assert_true(ret == 0); + + assert_string_equal(v, PROXYCMD); + ssh_string_free_char(v); + + ret = ssh_options_get(session, SSH_OPTIONS_IDENTITY, &v); + assert_true(ret == 0); + + assert_string_equal(v, ID_FILE); + ssh_string_free_char(v); +} + int torture_run_tests(void) { int rc; struct CMUnitTest tests[] = { @@ -114,6 +151,9 @@ int torture_run_tests(void) { cmocka_unit_test_setup_teardown(torture_config_double_ports, setup_config_files, teardown), + cmocka_unit_test_setup_teardown(torture_config_glob, + setup_config_files, + teardown), }; -- 2.13.6
Re: [PATCH] config: Parse KexAlgorithms, MACs, improve Include | Jakub Jelen <jjelen@xxxxxxxxxx> |