aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJakub Jelen <jjelen@redhat.com>2018-10-30 12:55:19 +0100
committerAndreas Schneider <asn@cryptomilk.org>2018-11-02 11:16:38 +0100
commit6eb43fcbf3757f24325e7a0432f0ba02cfe4757f (patch)
tree14440cc3741a7604481e4c3a67e4f49f3b0c1ecd
parent9aa47fef99504fdc59ea50b44c87e0b23c4cf1af (diff)
downloadlibssh-6eb43fcbf3757f24325e7a0432f0ba02cfe4757f.tar.gz
libssh-6eb43fcbf3757f24325e7a0432f0ba02cfe4757f.tar.xz
libssh-6eb43fcbf3757f24325e7a0432f0ba02cfe4757f.zip
tests: Verify the configuration reparsing with real client
This tests verifies that the only the first seen option is applied throughout all the configuration files processed. It also verifies that the configuration files are parsed automatically and that this behavior can be overridden by configuration option. Signed-off-by: Jakub Jelen <jjelen@redhat.com> Reviewed-by: Andreas Schneider <asn@cryptomilk.org>
-rw-r--r--tests/client/CMakeLists.txt1
-rw-r--r--tests/client/torture_client_config.c204
2 files changed, 205 insertions, 0 deletions
diff --git a/tests/client/CMakeLists.txt b/tests/client/CMakeLists.txt
index ad82a3e1..6916bfc6 100644
--- a/tests/client/CMakeLists.txt
+++ b/tests/client/CMakeLists.txt
@@ -4,6 +4,7 @@ find_package(socket_wrapper)
set(LIBSSH_CLIENT_TESTS
torture_algorithms
+ torture_client_config
torture_connect
torture_hostkey
torture_auth
diff --git a/tests/client/torture_client_config.c b/tests/client/torture_client_config.c
new file mode 100644
index 00000000..113b4c3f
--- /dev/null
+++ b/tests/client/torture_client_config.c
@@ -0,0 +1,204 @@
+#include "config.h"
+
+#define LIBSSH_STATIC
+
+#include <pwd.h>
+#include <errno.h>
+#include "torture.h"
+#include "libssh/session.h"
+#include "libssh/misc.h"
+
+#define LIBSSH_SSH_CONFIG "libssh_config"
+
+#define TORTURE_CONFIG_USER "test-user"
+
+#define CIPHERS "aes256-gcm@openssh.com,chacha20-poly1305@openssh.com"
+#define CIPHERS2 "aes256-cbc,aes128-ctr"
+
+static int sshd_setup(void **state)
+{
+ torture_setup_sshd_server(state);
+
+ return 0;
+}
+
+static int sshd_teardown(void **state) {
+ torture_teardown_sshd_server(state);
+
+ return 0;
+}
+
+static int setup_config_files(void **state)
+{
+ struct torture_state *s = *state;
+ int verbosity;
+ struct passwd *pwd;
+ char *filename = NULL;
+ int rc;
+
+ /* Work under the bob's UID to be able to load his configuration file */
+ pwd = getpwnam("bob");
+ assert_non_null(pwd);
+
+ rc = setuid(pwd->pw_uid);
+ assert_return_code(rc, errno);
+
+ s->ssh.session = ssh_new();
+ assert_non_null(s->ssh.session);
+
+ filename = ssh_path_expand_tilde("~/.ssh/config");
+ torture_write_file(filename, "Ciphers "CIPHERS"\nTestBogus1\nUser "TORTURE_CONFIG_USER);
+ free(filename);
+
+ torture_write_file(LIBSSH_SSH_CONFIG, "Ciphers "CIPHERS2"\nTestBogus2\n");
+
+ verbosity = torture_libssh_verbosity();
+ ssh_options_set(s->ssh.session, SSH_OPTIONS_LOG_VERBOSITY, &verbosity);
+ ssh_options_set(s->ssh.session, SSH_OPTIONS_HOST, TORTURE_SSH_SERVER);
+
+ return 0;
+}
+
+static int teardown(void **state)
+{
+ struct torture_state *s = *state;
+ char *filename;
+
+ filename = ssh_path_expand_tilde("~/.ssh/config");
+ unlink(filename);
+ free(filename);
+
+ unlink(LIBSSH_SSH_CONFIG);
+
+ ssh_disconnect(s->ssh.session);
+ ssh_free(s->ssh.session);
+
+ return 0;
+}
+
+/* This tests makes sure that parsing both system-wide and per-user
+ * configuration files retains OpenSSH semantics (the per-user overrides
+ * the system-wide values).
+ * This function ssh_options_parse_config() has hardcoded path to the
+ * system-wide configuration file so this might not test anything at all
+ * if this system-wide file does not overwrite this option.
+ */
+static void torture_client_config_system(void **state)
+{
+ struct torture_state *s = *state;
+ int ret = 0;
+
+ assert_true(s->ssh.session->opts.options_seen == NULL);
+
+ /* The first tests assumes there is system-wide configuration file
+ * setting Ciphers to some non-default value. We do not have any control
+ * of that in this test case.
+ */
+ ret = ssh_options_parse_config(s->ssh.session, NULL);
+ assert_return_code(s->ssh.session, ret);
+
+ assert_string_equal(s->ssh.session->opts.wanted_methods[SSH_CRYPT_C_S], CIPHERS);
+ assert_string_equal(s->ssh.session->opts.wanted_methods[SSH_CRYPT_S_C], CIPHERS);
+
+ /* Make sure the configuration was processed and user modified */
+ assert_string_equal(s->ssh.session->opts.username, TORTURE_CONFIG_USER);
+}
+
+/* This tests makes sure that parsing both system-wide and per-user
+ * configuration files retains OpenSSH semantics (the per-user overrides
+ * the system-wide values).
+ * The function ssh_options_parse_config() has hardcoded path to the
+ * system-wide configuraion file so we try to emmulate the behavior by parsing
+ * the files separately in the same order.
+ */
+static void torture_client_config_emulate(void **state)
+{
+ struct torture_state *s = *state;
+ char *filename = NULL;
+ int ret = 0;
+
+ assert_true(s->ssh.session->opts.options_seen == NULL);
+
+ /* The first tests assumes there is system-wide configuration file
+ * setting Ciphers to some non-default value. We do not have any control
+ * of that in this test case
+ */
+ filename = ssh_path_expand_tilde("~/.ssh/config");
+ ret = ssh_options_parse_config(s->ssh.session, filename);
+ free(filename);
+ assert_return_code(s->ssh.session, ret);
+
+ ret = ssh_options_parse_config(s->ssh.session, LIBSSH_SSH_CONFIG);
+ assert_return_code(s->ssh.session, ret);
+
+ assert_non_null(s->ssh.session->opts.wanted_methods[SSH_CRYPT_C_S]);
+ assert_string_equal(s->ssh.session->opts.wanted_methods[SSH_CRYPT_C_S], CIPHERS);
+ assert_non_null(s->ssh.session->opts.wanted_methods[SSH_CRYPT_S_C]);
+ assert_string_equal(s->ssh.session->opts.wanted_methods[SSH_CRYPT_S_C], CIPHERS);
+
+ /* Make sure the configuration was processed and user modified */
+ assert_string_equal(s->ssh.session->opts.username, TORTURE_CONFIG_USER);
+}
+
+/* This verifies that configuration files are parsed by default.
+ */
+static void torture_client_config_autoparse(void **state)
+{
+ struct torture_state *s = *state;
+ int ret = 0;
+
+ assert_true(s->ssh.session->opts.options_seen == NULL);
+
+ ret = ssh_connect(s->ssh.session);
+ assert_return_code(s->ssh.session, ret);
+
+ /* Make sure the configuration was processed and user modified */
+ assert_string_equal(s->ssh.session->opts.username, TORTURE_CONFIG_USER);
+}
+
+/* This verifies that we are able to suppress parsing of the configuration files
+ * on connect using an option.
+ */
+static void torture_client_config_suppress(void **state)
+{
+ struct torture_state *s = *state;
+ bool b = false;
+ int ret = 0;
+
+ assert_true(s->ssh.session->opts.options_seen == NULL);
+
+ ret = ssh_options_set(s->ssh.session, SSH_OPTIONS_PROCESS_CONFIG, &b);
+ assert_return_code(s->ssh.session, ret);
+
+ ret = ssh_connect(s->ssh.session);
+ assert_return_code(s->ssh.session, ret);
+
+ /* Make sure the configuration was not processed and user modified */
+ assert_string_equal(s->ssh.session->opts.username, "bob");
+}
+
+
+int torture_run_tests(void) {
+ int rc;
+ struct CMUnitTest tests[] = {
+ cmocka_unit_test_setup_teardown(torture_client_config_system,
+ setup_config_files,
+ teardown),
+ cmocka_unit_test_setup_teardown(torture_client_config_emulate,
+ setup_config_files,
+ teardown),
+ cmocka_unit_test_setup_teardown(torture_client_config_autoparse,
+ setup_config_files,
+ teardown),
+ cmocka_unit_test_setup_teardown(torture_client_config_suppress,
+ setup_config_files,
+ teardown),
+ };
+
+
+ ssh_init();
+ torture_filter_tests(tests);
+ rc = cmocka_run_group_tests(tests, sshd_setup, sshd_teardown);
+ ssh_finalize();
+ return rc;
+}