[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> |