aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorStanislav Zidek <szidek@redhat.com>2020-10-31 22:13:33 +0100
committerAnderson Toshiyuki Sasaki <ansasaki@redhat.com>2020-11-03 18:23:47 +0100
commit51f220fd414b4014aef68d133f1e0517e6f1d6ff (patch)
tree3a4fa541112eccae3cbf2c4fedb091e96d9576c3
parentb25feb3386a1435d78d3918742cff1df291cfcdb (diff)
downloadlibssh-master.tar.gz
libssh-master.tar.xz
libssh-master.zip
tests for parsing configuration string; rework and many fixesHEADmaster
Signed-off-by: Stanislav Zidek <szidek@redhat.com> Reviewed-by: Jakub Jelen <jjelen@redhat.com> Reviewed-by: Anderson Toshiyuki Sasaki <ansasaki@redhat.com>
-rw-r--r--tests/unittests/torture_config.c1238
1 files changed, 815 insertions, 423 deletions
diff --git a/tests/unittests/torture_config.c b/tests/unittests/torture_config.c
index 671e88c2..7ae846a4 100644
--- a/tests/unittests/torture_config.c
+++ b/tests/unittests/torture_config.c
@@ -10,6 +10,18 @@
extern LIBSSH_THREAD int ssh_log_level;
+#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-group16-sha512,diffie-hellman-group18-sha512,diffie-hellman-group14-sha1"
+#define HOSTKEYALGORITHMS "ssh-ed25519,ecdsa-sha2-nistp521,ssh-rsa"
+#define PUBKEYACCEPTEDTYPES "rsa-sha2-512,ssh-rsa,ecdsa-sha2-nistp521"
+#define MACS "hmac-sha1,hmac-sha2-256,hmac-sha2-512,hmac-sha1-etm@openssh.com,hmac-sha2-256-etm@openssh.com,hmac-sha2-512-etm@openssh.com"
+#define USER_KNOWN_HOSTS "%d/my_known_hosts"
+#define GLOBAL_KNOWN_HOSTS "/etc/ssh/my_ssh_known_hosts"
+#define BIND_ADDRESS "::1"
+
+
#define LIBSSH_TESTCONFIG1 "libssh_testconfig1.tmp"
#define LIBSSH_TESTCONFIG2 "libssh_testconfig2.tmp"
#define LIBSSH_TESTCONFIG3 "libssh_testconfig3.tmp"
@@ -23,25 +35,177 @@ extern LIBSSH_THREAD int ssh_log_level;
#define LIBSSH_TESTCONFIG11 "libssh_testconfig11.tmp"
#define LIBSSH_TESTCONFIG12 "libssh_testconfig12.tmp"
#define LIBSSH_TESTCONFIGGLOB "libssh_testc*[36].tmp"
-#define LIBSSH_TEST_PUBKEYACCEPTEDKEYTYPES "libssh_test_PubkeyAcceptedKeyTypes.tmp"
+#define LIBSSH_TEST_PUBKEYTYPES "libssh_test_PubkeyAcceptedKeyTypes.tmp"
+#define LIBSSH_TEST_NONEWLINEEND "libssh_test_NoNewLineEnd.tmp"
+#define LIBSSH_TEST_NONEWLINEONELINE "libssh_test_NoNewLineOneline.tmp"
+
+#define LIBSSH_TESTCONFIG_STRING1 \
+ "User "USERNAME"\nInclude "LIBSSH_TESTCONFIG2"\n\n"
+
+#define LIBSSH_TESTCONFIG_STRING2 \
+ "Include "LIBSSH_TESTCONFIG3"\n" \
+ "ProxyCommand "PROXYCMD"\n\n"
+
+#define LIBSSH_TESTCONFIG_STRING3 \
+ "\n\nIdentityFile "ID_FILE"\n" \
+ "\n\nKexAlgorithms "KEXALGORITHMS"\n" \
+ "\n\nHostKeyAlgorithms "HOSTKEYALGORITHMS"\n" \
+ "\n\nPubkeyAcceptedTypes "PUBKEYACCEPTEDTYPES"\n" \
+ "\n\nMACs "MACS"\n"
+
+/* Multiple Port settings -> parsing returns early. */
+#define LIBSSH_TESTCONFIG_STRING4 \
+ "Port 123\nPort 456\n"
+
+/* Testing glob include */
+#define LIBSSH_TESTCONFIG_STRING5 \
+ "User "USERNAME"\nInclude "LIBSSH_TESTCONFIGGLOB"\n\n" \
+
+#define LIBSSH_TESTCONFIG_STRING6 \
+ "ProxyCommand "PROXYCMD"\n\n"
+
+/* new options */
+#define LIBSSH_TESTCONFIG_STRING7 \
+ "\tBindAddress "BIND_ADDRESS"\n" \
+ "\tConnectTimeout 30\n" \
+ "\tLogLevel DEBUG3\n" \
+ "\tGlobalKnownHostsFile "GLOBAL_KNOWN_HOSTS"\n" \
+ "\tCompression yes\n" \
+ "\tStrictHostkeyChecking no\n" \
+ "\tGSSAPIDelegateCredentials yes\n" \
+ "\tGSSAPIServerIdentity example.com\n" \
+ "\tGSSAPIClientIdentity home.sweet\n" \
+ "\tUserKnownHostsFile "USER_KNOWN_HOSTS"\n"
+
+/* authentication methods */
+#define LIBSSH_TESTCONFIG_STRING8 \
+ "Host gss\n" \
+ "\tGSSAPIAuthentication yes\n" \
+ "Host kbd\n" \
+ "\tKbdInteractiveAuthentication yes\n" \
+ "Host pass\n" \
+ "\tPasswordAuthentication yes\n" \
+ "Host pubkey\n" \
+ "\tPubkeyAuthentication yes\n" \
+ "Host nogss\n" \
+ "\tGSSAPIAuthentication no\n" \
+ "Host nokbd\n" \
+ "\tKbdInteractiveAuthentication no\n" \
+ "Host nopass\n" \
+ "\tPasswordAuthentication no\n" \
+ "Host nopubkey\n" \
+ "\tPubkeyAuthentication no\n"
+
+/* unsupported options and corner cases */
+#define LIBSSH_TESTCONFIG_STRING9 \
+ "\n" /* empty line */ \
+ "# comment line\n" \
+ " # comment line not starting with hash\n" \
+ "UnknownConfigurationOption yes\n" \
+ "GSSAPIKexAlgorithms yes\n" \
+ "ControlMaster auto\n" /* SOC_NA */ \
+ "VisualHostkey yes\n" /* SOC_UNSUPPORTED */ \
+ "HostName =equal.sign\n" /* valid */ \
+ "ProxyJump = many-spaces.com\n" /* valid */
+
+/* Match keyword */
+#define LIBSSH_TESTCONFIG_STRING10 \
+ "Match host example\n" \
+ "\tHostName example.com\n" \
+ "Match host example1,example2\n" \
+ "\tHostName exampleN\n" \
+ "Match user guest\n" \
+ "\tHostName guest.com\n" \
+ "Match user tester host testhost\n" \
+ "\tHostName testhost.com\n" \
+ "Match !user tester host testhost\n" \
+ "\tHostName nonuser-testhost.com\n" \
+ "Match all\n" \
+ "\tHostName all-matched.com\n" \
+ /* Unsupported options */ \
+ "Match originalhost example\n" \
+ "\tHostName original-example.com\n" \
+ "Match localuser guest\n" \
+ "\tHostName local-guest.com\n"
+
+/* ProxyJump */
+#define LIBSSH_TESTCONFIG_STRING11 \
+ "Host simple\n" \
+ "\tProxyJump jumpbox\n" \
+ "Host user\n" \
+ "\tProxyJump user@jumpbox\n" \
+ "Host port\n" \
+ "\tProxyJump jumpbox:2222\n" \
+ "Host two-step\n" \
+ "\tProxyJump u1@first:222,u2@second:33\n" \
+ "Host none\n" \
+ "\tProxyJump none\n" \
+ "Host only-command\n" \
+ "\tProxyCommand "PROXYCMD"\n" \
+ "\tProxyJump jumpbox\n" \
+ "Host only-jump\n" \
+ "\tProxyJump jumpbox\n" \
+ "\tProxyCommand "PROXYCMD"\n" \
+ "Host ipv6\n" \
+ "\tProxyJump [2620:52:0::fed]\n"
+
+/* RekeyLimit combinations */
+#define LIBSSH_TESTCONFIG_STRING12 \
+ "Host default\n" \
+ "\tRekeyLimit default none\n" \
+ "Host data1\n" \
+ "\tRekeyLimit 42G\n" \
+ "Host data2\n" \
+ "\tRekeyLimit 31M\n" \
+ "Host data3\n" \
+ "\tRekeyLimit 521K\n" \
+ "Host time1\n" \
+ "\tRekeyLimit default 3D\n" \
+ "Host time2\n" \
+ "\tRekeyLimit default 2h\n" \
+ "Host time3\n" \
+ "\tRekeyLimit default 160m\n" \
+ "Host time4\n" \
+ "\tRekeyLimit default 9600\n"
+
+#define LIBSSH_TEST_PUBKEYTYPES_STRING \
+ "PubkeyAcceptedKeyTypes "PUBKEYACCEPTEDTYPES"\n"
+
+#define LIBSSH_TEST_NONEWLINEEND_STRING \
+ "ConnectTimeout 30\n" \
+ "LogLevel DEBUG3"
+
+#define LIBSSH_TEST_NONEWLINEONELINE_STRING \
+ "ConnectTimeout 30"
-#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-group16-sha512,diffie-hellman-group18-sha512,diffie-hellman-group14-sha1"
-#define HOSTKEYALGORITHMS "ssh-ed25519,ecdsa-sha2-nistp521,ssh-rsa"
-#define PUBKEYACCEPTEDTYPES "rsa-sha2-512,ssh-rsa,ecdsa-sha2-nistp521"
-#define MACS "hmac-sha1,hmac-sha2-256,hmac-sha2-512,hmac-sha1-etm@openssh.com,hmac-sha2-256-etm@openssh.com,hmac-sha2-512-etm@openssh.com"
-#define USER_KNOWN_HOSTS "%d/my_known_hosts"
-#define GLOBAL_KNOWN_HOSTS "/etc/ssh/my_ssh_known_hosts"
-#define BIND_ADDRESS "::1"
+/**
+ * @brief helper function loading configuration from either file or string
+ */
+static void _parse_config(ssh_session session,
+ const char *file, const char *string, int expected)
+{
+ int ret = -1;
+ /* make sure either config file or config string is given,
+ * not both */
+ assert_int_not_equal(file == NULL, string == NULL);
+ if (file != NULL) {
+ ret = ssh_config_parse_file(session, file);
+ } else if (string != NULL) {
+ ret = ssh_config_parse_string(session, string);
+ } else {
+ /* should not happen */
+ fail();
+ }
+
+ /* make sure parsing went as expected */
+ assert_ssh_return_code_equal(session, ret, expected);
+}
static int setup_config_files(void **state)
{
- ssh_session session;
- int verbosity;
+ (void) state; /* unused */
unlink(LIBSSH_TESTCONFIG1);
unlink(LIBSSH_TESTCONFIG2);
@@ -55,154 +219,68 @@ static int setup_config_files(void **state)
unlink(LIBSSH_TESTCONFIG10);
unlink(LIBSSH_TESTCONFIG11);
unlink(LIBSSH_TESTCONFIG12);
- unlink(LIBSSH_TEST_PUBKEYACCEPTEDKEYTYPES);
+ unlink(LIBSSH_TEST_PUBKEYTYPES);
+ unlink(LIBSSH_TEST_NONEWLINEEND);
+ unlink(LIBSSH_TEST_NONEWLINEONELINE);
torture_write_file(LIBSSH_TESTCONFIG1,
- "User "USERNAME"\nInclude "LIBSSH_TESTCONFIG2"\n\n");
+ LIBSSH_TESTCONFIG_STRING1);
torture_write_file(LIBSSH_TESTCONFIG2,
- "Include "LIBSSH_TESTCONFIG3"\n"
- "ProxyCommand "PROXYCMD"\n\n");
+ LIBSSH_TESTCONFIG_STRING2);
torture_write_file(LIBSSH_TESTCONFIG3,
- "\n\nIdentityFile "ID_FILE"\n"
- "\n\nKexAlgorithms "KEXALGORITHMS"\n"
- "\n\nHostKeyAlgorithms "HOSTKEYALGORITHMS"\n"
- "\n\nPubkeyAcceptedTypes "PUBKEYACCEPTEDTYPES"\n"
- "\n\nMACs "MACS"\n");
+ LIBSSH_TESTCONFIG_STRING3);
/* Multiple Port settings -> parsing returns early. */
torture_write_file(LIBSSH_TESTCONFIG4,
- "Port 123\nPort 456\n");
+ LIBSSH_TESTCONFIG_STRING4);
/* Testing glob include */
torture_write_file(LIBSSH_TESTCONFIG5,
- "User "USERNAME"\nInclude "LIBSSH_TESTCONFIGGLOB"\n\n");
+ LIBSSH_TESTCONFIG_STRING5);
torture_write_file(LIBSSH_TESTCONFIG6,
- "ProxyCommand "PROXYCMD"\n\n");
+ LIBSSH_TESTCONFIG_STRING6);
/* new options */
torture_write_file(LIBSSH_TESTCONFIG7,
- "\tBindAddress "BIND_ADDRESS"\n"
- "\tConnectTimeout 30\n"
- "\tLogLevel DEBUG3\n"
- "\tGlobalKnownHostsFile "GLOBAL_KNOWN_HOSTS"\n"
- "\tCompression yes\n"
- "\tStrictHostkeyChecking no\n"
- "\tGSSAPIDelegateCredentials yes\n"
- "\tGSSAPIServerIdentity example.com\n"
- "\tGSSAPIClientIdentity home.sweet\n"
- "\tUserKnownHostsFile "USER_KNOWN_HOSTS"\n");
+ LIBSSH_TESTCONFIG_STRING7);
/* authentication methods */
torture_write_file(LIBSSH_TESTCONFIG8,
- "Host gss\n"
- "\tGSSAPIAuthentication yes\n"
- "Host kbd\n"
- "\tKbdInteractiveAuthentication yes\n"
- "Host pass\n"
- "\tPasswordAuthentication yes\n"
- "Host pubkey\n"
- "\tPubkeyAuthentication yes\n"
- "Host nogss\n"
- "\tGSSAPIAuthentication no\n"
- "Host nokbd\n"
- "\tKbdInteractiveAuthentication no\n"
- "Host nopass\n"
- "\tPasswordAuthentication no\n"
- "Host nopubkey\n"
- "\tPubkeyAuthentication no\n");
+ LIBSSH_TESTCONFIG_STRING8);
/* unsupported options and corner cases */
torture_write_file(LIBSSH_TESTCONFIG9,
- "\n" /* empty line */
- "# comment line\n"
- " # comment line not starting with hash\n"
- "UnknownConfigurationOption yes\n"
- "GSSAPIKexAlgorithms yes\n"
- "ControlMaster auto\n" /* SOC_NA */
- "VisualHostkey yes\n" /* SOC_UNSUPPORTED */
- "HostName =equal.sign\n" /* valid */
- "ProxyJump = many-spaces.com\n" /* valid */
- "");
+ LIBSSH_TESTCONFIG_STRING9);
/* Match keyword */
torture_write_file(LIBSSH_TESTCONFIG10,
- "Match host example\n"
- "\tHostName example.com\n"
- "Match host example1,example2\n"
- "\tHostName exampleN\n"
- "Match user guest\n"
- "\tHostName guest.com\n"
- "Match user tester host testhost\n"
- "\tHostName testhost.com\n"
- "Match !user tester host testhost\n"
- "\tHostName nonuser-testhost.com\n"
- "Match all\n"
- "\tHostName all-matched.com\n"
- /* Unsupported options */
- "Match originalhost example\n"
- "\tHostName original-example.com\n"
- "Match localuser guest\n"
- "\tHostName local-guest.com\n"
- "");
+ LIBSSH_TESTCONFIG_STRING10);
/* ProxyJump */
torture_write_file(LIBSSH_TESTCONFIG11,
- "Host simple\n"
- "\tProxyJump jumpbox\n"
- "Host user\n"
- "\tProxyJump user@jumpbox\n"
- "Host port\n"
- "\tProxyJump jumpbox:2222\n"
- "Host two-step\n"
- "\tProxyJump u1@first:222,u2@second:33\n"
- "Host none\n"
- "\tProxyJump none\n"
- "Host only-command\n"
- "\tProxyCommand "PROXYCMD"\n"
- "\tProxyJump jumpbox\n"
- "Host only-jump\n"
- "\tProxyJump jumpbox\n"
- "\tProxyCommand "PROXYCMD"\n"
- "Host ipv6\n"
- "\tProxyJump [2620:52:0::fed]\n"
- "");
+ LIBSSH_TESTCONFIG_STRING11);
/* RekeyLimit combinations */
torture_write_file(LIBSSH_TESTCONFIG12,
- "Host default\n"
- "\tRekeyLimit default none\n"
- "Host data1\n"
- "\tRekeyLimit 42G\n"
- "Host data2\n"
- "\tRekeyLimit 31M\n"
- "Host data3\n"
- "\tRekeyLimit 521K\n"
- "Host time1\n"
- "\tRekeyLimit default 3D\n"
- "Host time2\n"
- "\tRekeyLimit default 2h\n"
- "Host time3\n"
- "\tRekeyLimit default 160m\n"
- "Host time4\n"
- "\tRekeyLimit default 9600\n"
- "");
-
- torture_write_file(LIBSSH_TEST_PUBKEYACCEPTEDKEYTYPES,
- "PubkeyAcceptedKeyTypes "PUBKEYACCEPTEDTYPES"\n");
+ LIBSSH_TESTCONFIG_STRING12);
- session = ssh_new();
+ torture_write_file(LIBSSH_TEST_PUBKEYTYPES,
+ LIBSSH_TEST_PUBKEYTYPES_STRING);
- verbosity = torture_libssh_verbosity();
- ssh_options_set(session, SSH_OPTIONS_LOG_VERBOSITY, &verbosity);
+ torture_write_file(LIBSSH_TEST_NONEWLINEEND,
+ LIBSSH_TEST_NONEWLINEEND_STRING);
- *state = session;
+ torture_write_file(LIBSSH_TEST_NONEWLINEONELINE,
+ LIBSSH_TEST_NONEWLINEONELINE_STRING);
return 0;
}
-static int teardown(void **state)
+static int teardown_config_files(void **state)
{
+ (void) state; /* unused */
+
unlink(LIBSSH_TESTCONFIG1);
unlink(LIBSSH_TESTCONFIG2);
unlink(LIBSSH_TESTCONFIG3);
@@ -215,27 +293,47 @@ static int teardown(void **state)
unlink(LIBSSH_TESTCONFIG10);
unlink(LIBSSH_TESTCONFIG11);
unlink(LIBSSH_TESTCONFIG12);
- unlink(LIBSSH_TEST_PUBKEYACCEPTEDKEYTYPES);
+ unlink(LIBSSH_TEST_PUBKEYTYPES);
+ return 0;
+}
+
+static int setup(void **state)
+{
+ ssh_session session = NULL;
+ int verbosity;
+
+ session = ssh_new();
+
+ verbosity = torture_libssh_verbosity();
+ ssh_options_set(session, SSH_OPTIONS_LOG_VERBOSITY, &verbosity);
+
+ *state = session;
+
+ return 0;
+}
+
+static int teardown(void **state)
+{
ssh_free(*state);
return 0;
}
/**
- * @brief tests ssh_config_parse_file with Include directives
+ * @brief tests ssh config parsing with Include directives
*/
-static void torture_config_from_file(void **state) {
- ssh_session session = *state;
+static void torture_config_include(void **state,
+ const char *file, const char *string)
+{
int ret;
char *v = NULL;
char *fips_algos = NULL;
+ ssh_session session = *state;
- ret = ssh_config_parse_file(session, LIBSSH_TESTCONFIG1);
- assert_true(ret == 0);
+ _parse_config(session, file, string, SSH_OK);
/* Test the variable presence */
-
ret = ssh_options_get(session, SSH_OPTIONS_PROXYCOMMAND, &v);
assert_true(ret == 0);
assert_non_null(v);
@@ -264,7 +362,8 @@ static void torture_config_from_file(void **state) {
SAFE_FREE(fips_algos);
fips_algos = ssh_keep_fips_algos(SSH_HOSTKEYS, HOSTKEYALGORITHMS);
assert_non_null(fips_algos);
- assert_string_equal(session->opts.wanted_methods[SSH_HOSTKEYS], fips_algos);
+ assert_string_equal(session->opts.wanted_methods[SSH_HOSTKEYS],
+ fips_algos);
SAFE_FREE(fips_algos);
fips_algos = ssh_keep_fips_algos(SSH_HOSTKEYS, PUBKEYACCEPTEDTYPES);
assert_non_null(fips_algos);
@@ -272,19 +371,24 @@ static void torture_config_from_file(void **state) {
SAFE_FREE(fips_algos);
fips_algos = ssh_keep_fips_algos(SSH_MAC_C_S, MACS);
assert_non_null(fips_algos);
- assert_string_equal(session->opts.wanted_methods[SSH_MAC_C_S], fips_algos);
+ assert_string_equal(session->opts.wanted_methods[SSH_MAC_C_S],
+ fips_algos);
SAFE_FREE(fips_algos);
fips_algos = ssh_keep_fips_algos(SSH_MAC_S_C, MACS);
assert_non_null(fips_algos);
- assert_string_equal(session->opts.wanted_methods[SSH_MAC_S_C], fips_algos);
+ assert_string_equal(session->opts.wanted_methods[SSH_MAC_S_C],
+ fips_algos);
SAFE_FREE(fips_algos);
} else {
assert_non_null(session->opts.wanted_methods[SSH_KEX]);
- assert_string_equal(session->opts.wanted_methods[SSH_KEX], KEXALGORITHMS);
+ assert_string_equal(session->opts.wanted_methods[SSH_KEX],
+ KEXALGORITHMS);
assert_non_null(session->opts.wanted_methods[SSH_HOSTKEYS]);
- assert_string_equal(session->opts.wanted_methods[SSH_HOSTKEYS], HOSTKEYALGORITHMS);
+ assert_string_equal(session->opts.wanted_methods[SSH_HOSTKEYS],
+ HOSTKEYALGORITHMS);
assert_non_null(session->opts.pubkey_accepted_types);
- assert_string_equal(session->opts.pubkey_accepted_types, PUBKEYACCEPTEDTYPES);
+ assert_string_equal(session->opts.pubkey_accepted_types,
+ PUBKEYACCEPTEDTYPES);
assert_non_null(session->opts.wanted_methods[SSH_MAC_S_C]);
assert_string_equal(session->opts.wanted_methods[SSH_MAC_C_S], MACS);
assert_non_null(session->opts.wanted_methods[SSH_MAC_S_C]);
@@ -293,27 +397,49 @@ static void torture_config_from_file(void **state) {
}
/**
+ * @brief tests ssh_config_parse_file with Include directives from file
+ */
+static void torture_config_include_file(void **state)
+{
+ torture_config_include(state, LIBSSH_TESTCONFIG1, NULL);
+}
+
+/**
+ * @brief tests ssh_config_parse_string with Include directives from string
+ */
+static void torture_config_include_string(void **state)
+{
+ torture_config_include(state, NULL, LIBSSH_TESTCONFIG_STRING1);
+}
+
+/**
* @brief tests ssh_config_parse_file with multiple Port settings.
*/
-static void torture_config_double_ports(void **state) {
- ssh_session session = *state;
- int ret = ssh_config_parse_file(session, LIBSSH_TESTCONFIG4);
- assert_true(ret == 0);
+static void torture_config_double_ports_file(void **state)
+{
+ _parse_config(*state, LIBSSH_TESTCONFIG4, NULL, SSH_OK);
}
-static void torture_config_glob(void **state) {
- ssh_session session = *state;
- int ret;
+/**
+ * @brief tests ssh_config_parse_string with multiple Port settings.
+ */
+static void torture_config_double_ports_string(void **state)
+{
+ _parse_config(*state, NULL, LIBSSH_TESTCONFIG_STRING4, SSH_OK);
+}
+
+static void torture_config_glob(void **state,
+ const char *file, const char *string)
+{
#if defined(HAVE_GLOB) && defined(HAVE_GLOB_GL_FLAGS_MEMBER)
+ int ret;
char *v;
-#endif /* HAVE_GLOB && HAVE_GLOB_GL_FLAGS_MEMBER */
+ ssh_session session = *state;
- ret = ssh_config_parse_file(session, LIBSSH_TESTCONFIG5);
- assert_true(ret == 0); /* non-existing files should not error */
+ _parse_config(session, file, string, SSH_OK);
/* Test the variable presence */
-#if defined(HAVE_GLOB) && defined(HAVE_GLOB_GL_FLAGS_MEMBER)
ret = ssh_options_get(session, SSH_OPTIONS_PROXYCOMMAND, &v);
assert_true(ret == 0);
assert_non_null(v);
@@ -330,16 +456,25 @@ static void torture_config_glob(void **state) {
#endif /* HAVE_GLOB && HAVE_GLOB_GL_FLAGS_MEMBER */
}
+static void torture_config_glob_file(void **state)
+{
+ torture_config_glob(state, LIBSSH_TESTCONFIG5, NULL);
+}
+
+static void torture_config_glob_string(void **state)
+{
+ torture_config_glob(state, NULL, LIBSSH_TESTCONFIG_STRING5);
+}
+
/**
* @brief Verify the new options are passed from configuration
*/
-static void torture_config_new(void **state)
+static void torture_config_new(void ** state,
+ const char *file, const char *string)
{
ssh_session session = *state;
- int ret = 0;
- ret = ssh_config_parse_file(session, LIBSSH_TESTCONFIG7);
- assert_true(ret == 0);
+ _parse_config(session, file, string, SSH_OK);
assert_string_equal(session->opts.knownhosts, USER_KNOWN_HOSTS);
assert_string_equal(session->opts.global_knownhosts, GLOBAL_KNOWN_HOSTS);
@@ -363,33 +498,40 @@ static void torture_config_new(void **state)
assert_int_equal(session->common.log_verbosity, SSH_LOG_TRACE);
}
+static void torture_config_new_file(void **state)
+{
+ torture_config_new(state, LIBSSH_TESTCONFIG7, NULL);
+}
+
+static void torture_config_new_string(void **state)
+{
+ torture_config_new(state, NULL, LIBSSH_TESTCONFIG_STRING7);
+}
+
/**
* @brief Verify the authentication methods from configuration are effective
*/
-static void torture_config_auth_methods(void **state) {
+static void torture_config_auth_methods(void **state,
+ const char *file, const char *string)
+{
ssh_session session = *state;
- int ret = 0;
/* gradually disable all the methods based on different hosts */
ssh_options_set(session, SSH_OPTIONS_HOST, "nogss");
- ret = ssh_config_parse_file(session, LIBSSH_TESTCONFIG8);
- assert_true(ret == 0);
+ _parse_config(session, file, string, SSH_OK);
assert_false(session->opts.flags & SSH_OPT_FLAG_GSSAPI_AUTH);
assert_true(session->opts.flags & SSH_OPT_FLAG_KBDINT_AUTH);
ssh_options_set(session, SSH_OPTIONS_HOST, "nokbd");
- ret = ssh_config_parse_file(session, LIBSSH_TESTCONFIG8);
- assert_true(ret == 0);
+ _parse_config(session, file, string, SSH_OK);
assert_false(session->opts.flags & SSH_OPT_FLAG_KBDINT_AUTH);
ssh_options_set(session, SSH_OPTIONS_HOST, "nopass");
- ret = ssh_config_parse_file(session, LIBSSH_TESTCONFIG8);
- assert_true(ret == 0);
+ _parse_config(session, file, string, SSH_OK);
assert_false(session->opts.flags & SSH_OPT_FLAG_PASSWORD_AUTH);
ssh_options_set(session, SSH_OPTIONS_HOST, "nopubkey");
- ret = ssh_config_parse_file(session, LIBSSH_TESTCONFIG8);
- assert_true(ret == 0);
+ _parse_config(session, file, string, SSH_OK);
assert_false(session->opts.flags & SSH_OPT_FLAG_PUBKEY_AUTH);
/* no method should be left enabled */
@@ -398,39 +540,55 @@ static void torture_config_auth_methods(void **state) {
/* gradually enable them again */
torture_reset_config(session);
ssh_options_set(session, SSH_OPTIONS_HOST, "gss");
- ret = ssh_config_parse_file(session, LIBSSH_TESTCONFIG8);
- assert_true(ret == 0);
+ _parse_config(session, file, string, SSH_OK);
assert_true(session->opts.flags & SSH_OPT_FLAG_GSSAPI_AUTH);
assert_false(session->opts.flags & SSH_OPT_FLAG_KBDINT_AUTH);
ssh_options_set(session, SSH_OPTIONS_HOST, "kbd");
- ret = ssh_config_parse_file(session, LIBSSH_TESTCONFIG8);
- assert_true(ret == 0);
+ _parse_config(session, file, string, SSH_OK);
assert_true(session->opts.flags & SSH_OPT_FLAG_KBDINT_AUTH);
ssh_options_set(session, SSH_OPTIONS_HOST, "pass");
- ret = ssh_config_parse_file(session, LIBSSH_TESTCONFIG8);
- assert_true(ret == 0);
+ _parse_config(session, file, string, SSH_OK);
assert_true(session->opts.flags & SSH_OPT_FLAG_PASSWORD_AUTH);
ssh_options_set(session, SSH_OPTIONS_HOST, "pubkey");
- ret = ssh_config_parse_file(session, LIBSSH_TESTCONFIG8);
- assert_true(ret == 0);
+ _parse_config(session, file, string, SSH_OK);
assert_true(session->opts.flags & SSH_OPT_FLAG_PUBKEY_AUTH);
}
/**
+ * @brief Verify the authentication methods from configuration file
+ * are effective
+ */
+static void torture_config_auth_methods_file(void **state)
+{
+ torture_config_auth_methods(state, LIBSSH_TESTCONFIG8, NULL);
+}
+
+/**
+ * @brief Verify the authentication methods from configuration string
+ * are effective
+ */
+static void torture_config_auth_methods_string(void **state)
+{
+ torture_config_auth_methods(state, NULL, LIBSSH_TESTCONFIG_STRING8);
+}
+
+/**
* @brief Verify the configuration parser does not choke on unknown
* or unsupported configuration options
*/
-static void torture_config_unknown(void **state) {
+static void torture_config_unknown(void **state,
+ const char *file, const char *string)
+{
ssh_session session = *state;
int ret = 0;
/* test corner cases */
- ret = ssh_config_parse_file(session, LIBSSH_TESTCONFIG9);
- assert_true(ret == 0);
- assert_string_equal(session->opts.ProxyCommand, "ssh -W [%h]:%p many-spaces.com");
+ _parse_config(session, file, string, SSH_OK);
+ assert_string_equal(session->opts.ProxyCommand,
+ "ssh -W [%h]:%p many-spaces.com");
assert_string_equal(session->opts.host, "equal.sign");
ret = ssh_config_parse_file(session, "/etc/ssh/ssh_config");
@@ -439,128 +597,155 @@ static void torture_config_unknown(void **state) {
assert_true(ret == 0);
}
+/**
+ * @brief Verify the configuration parser does not choke on unknown
+ * or unsupported configuration options in configuration file
+ */
+static void torture_config_unknown_file(void **state)
+{
+ torture_config_unknown(state, LIBSSH_TESTCONFIG9, NULL);
+}
+
+/**
+ * @brief Verify the configuration parser does not choke on unknown
+ * or unsupported configuration options in configuration string
+ */
+static void torture_config_unknown_string(void **state)
+{
+ torture_config_unknown(state, NULL, LIBSSH_TESTCONFIG_STRING9);
+}
/**
* @brief Verify the configuration parser accepts Match keyword with
* full OpenSSH syntax.
*/
-static void torture_config_match(void **state)
+static void torture_config_match(void **state,
+ const char *file, const char *string)
{
ssh_session session = *state;
char *localuser = NULL;
- char config[1024];
- int ret = 0;
+ const char *config;
+ char config_string[1024];
/* Without any settings we should get all-matched.com hostname */
torture_reset_config(session);
ssh_options_set(session, SSH_OPTIONS_HOST, "unmatched");
- ret = ssh_config_parse_file(session, LIBSSH_TESTCONFIG10);
- assert_ssh_return_code(session, ret);
+ _parse_config(session, file, string, SSH_OK);
assert_string_equal(session->opts.host, "all-matched.com");
/* Hostname example does simple hostname matching */
torture_reset_config(session);
ssh_options_set(session, SSH_OPTIONS_HOST, "example");
- ret = ssh_config_parse_file(session, LIBSSH_TESTCONFIG10);
- assert_ssh_return_code(session, ret);
+ _parse_config(session, file, string, SSH_OK);
assert_string_equal(session->opts.host, "example.com");
/* We can match also both hosts from a comma separated list */
torture_reset_config(session);
ssh_options_set(session, SSH_OPTIONS_HOST, "example1");
- ret = ssh_config_parse_file(session, LIBSSH_TESTCONFIG10);
- assert_ssh_return_code(session, ret);
+ _parse_config(session, file, string, SSH_OK);
assert_string_equal(session->opts.host, "exampleN");
torture_reset_config(session);
ssh_options_set(session, SSH_OPTIONS_HOST, "example2");
- ret = ssh_config_parse_file(session, LIBSSH_TESTCONFIG10);
- assert_ssh_return_code(session, ret);
+ _parse_config(session, file, string, SSH_OK);
assert_string_equal(session->opts.host, "exampleN");
/* We can match by user */
torture_reset_config(session);
ssh_options_set(session, SSH_OPTIONS_USER, "guest");
- ret = ssh_config_parse_file(session, LIBSSH_TESTCONFIG10);
- assert_ssh_return_code(session, ret);
+ _parse_config(session, file, string, SSH_OK);
assert_string_equal(session->opts.host, "guest.com");
/* We can combine two options on a single line to match both of them */
torture_reset_config(session);
ssh_options_set(session, SSH_OPTIONS_USER, "tester");
ssh_options_set(session, SSH_OPTIONS_HOST, "testhost");
- ret = ssh_config_parse_file(session, LIBSSH_TESTCONFIG10);
- assert_ssh_return_code(session, ret);
+ _parse_config(session, file, string, SSH_OK);
assert_string_equal(session->opts.host, "testhost.com");
/* We can also negate conditions */
torture_reset_config(session);
ssh_options_set(session, SSH_OPTIONS_USER, "not-tester");
ssh_options_set(session, SSH_OPTIONS_HOST, "testhost");
- ret = ssh_config_parse_file(session, LIBSSH_TESTCONFIG10);
- assert_ssh_return_code(session, ret);
+ _parse_config(session, file, string, SSH_OK);
assert_string_equal(session->opts.host, "nonuser-testhost.com");
+ /* In this part, we try various other config files and strings. */
+
/* Match final is not completely supported, but should do quite much the
* same as "match all". The trailing "all" is not mandatory. */
- torture_write_file(LIBSSH_TESTCONFIG10,
- "Match final all\n"
- "\tHostName final-all.com\n"
- "");
+ config = "Match final all\n"
+ "\tHostName final-all.com\n";
+ if (file != NULL) {
+ torture_write_file(file, config);
+ } else {
+ string = config;
+ }
torture_reset_config(session);
- ret = ssh_config_parse_file(session, LIBSSH_TESTCONFIG10);
- assert_ssh_return_code(session, ret);
+ _parse_config(session, file, string, SSH_OK);
assert_string_equal(session->opts.host, "final-all.com");
- torture_write_file(LIBSSH_TESTCONFIG10,
- "Match final\n"
- "\tHostName final.com\n"
- "");
+ config = "Match final\n"
+ "\tHostName final.com\n";
+ if (file != NULL) {
+ torture_write_file(file, config);
+ } else {
+ string = config;
+ }
torture_reset_config(session);
- ret = ssh_config_parse_file(session, LIBSSH_TESTCONFIG10);
- assert_ssh_return_code(session, ret);
+ _parse_config(session, file, string, SSH_OK);
assert_string_equal(session->opts.host, "final.com");
- /* Match canonical is not completely supported, but should do quite much the
- * same as "match all". The trailing "all" is not mandatory. */
- torture_write_file(LIBSSH_TESTCONFIG10,
- "Match canonical all\n"
- "\tHostName canonical-all.com\n"
- "");
+ /* Match canonical is not completely supported, but should do quite
+ * much the same as "match all". The trailing "all" is not mandatory. */
+ config = "Match canonical all\n"
+ "\tHostName canonical-all.com\n";
+ if (file != NULL) {
+ torture_write_file(file, config);
+ } else {
+ string = config;
+ }
torture_reset_config(session);
- ret = ssh_config_parse_file(session, LIBSSH_TESTCONFIG10);
- assert_ssh_return_code(session, ret);
+ _parse_config(session, file, string, SSH_OK);
assert_string_equal(session->opts.host, "canonical-all.com");
- torture_write_file(LIBSSH_TESTCONFIG10,
- "Match canonical all\n"
- "\tHostName canonical.com\n"
- "");
+ config = "Match canonical all\n"
+ "\tHostName canonical.com\n";
+ if (file != NULL) {
+ torture_write_file(file, config);
+ } else {
+ string = config;
+ }
torture_reset_config(session);
- ret = ssh_config_parse_file(session, LIBSSH_TESTCONFIG10);
- assert_ssh_return_code(session, ret);
+ _parse_config(session, file, string, SSH_OK);
assert_string_equal(session->opts.host, "canonical.com");
localuser = ssh_get_local_username();
assert_non_null(localuser);
- snprintf(config, sizeof(config),
+ snprintf(config_string, sizeof(config_string),
"Match localuser %s\n"
- "\tHostName otherhost\n"
- "", localuser);
+ "\tHostName otherhost\n",
+ localuser);
+ config = config_string;
free(localuser);
- torture_write_file(LIBSSH_TESTCONFIG10, config);
+ if (file != NULL) {
+ torture_write_file(file, config);
+ } else {
+ string = config;
+ }
torture_reset_config(session);
- ret = ssh_config_parse_file(session, LIBSSH_TESTCONFIG10);
- assert_ssh_return_code(session, ret);
+ _parse_config(session, file, string, SSH_OK);
assert_string_equal(session->opts.host, "otherhost");
- torture_write_file(LIBSSH_TESTCONFIG10,
- "Match exec true\n"
- "\tHostName execed-true.com\n"
- "");
+ config = "Match exec true\n"
+ "\tHostName execed-true.com\n";
+ if (file != NULL) {
+ torture_write_file(file, config);
+ } else {
+ string = config;
+ }
torture_reset_config(session);
- ret = ssh_config_parse_file(session, LIBSSH_TESTCONFIG10);
- assert_ssh_return_code(session, ret);
+ _parse_config(session, file, string, SSH_OK);
#ifdef _WIN32
/* The match exec is not supported on windows at this moment */
assert_string_equal(session->opts.host, "otherhost");
@@ -568,13 +753,15 @@ static void torture_config_match(void **state)
assert_string_equal(session->opts.host, "execed-true.com");
#endif
- torture_write_file(LIBSSH_TESTCONFIG10,
- "Match !exec false\n"
- "\tHostName execed-false.com\n"
- "");
+ config = "Match !exec false\n"
+ "\tHostName execed-false.com\n";
+ if (file != NULL) {
+ torture_write_file(file, config);
+ } else {
+ string = config;
+ }
torture_reset_config(session);
- ret = ssh_config_parse_file(session, LIBSSH_TESTCONFIG10);
- assert_ssh_return_code(session, ret);
+ _parse_config(session, file, string, SSH_OK);
#ifdef _WIN32
/* The match exec is not supported on windows at this moment */
assert_string_equal(session->opts.host, "otherhost");
@@ -582,13 +769,15 @@ static void torture_config_match(void **state)
assert_string_equal(session->opts.host, "execed-false.com");
#endif
- torture_write_file(LIBSSH_TESTCONFIG10,
- "Match exec \"test 1 -eq 1\"\n"
- "\tHostName execed-arguments.com\n"
- "");
+ config = "Match exec \"test 1 -eq 1\"\n"
+ "\tHostName execed-arguments.com\n";
+ if (file != NULL) {
+ torture_write_file(file, config);
+ } else {
+ string = config;
+ }
torture_reset_config(session);
- ret = ssh_config_parse_file(session, LIBSSH_TESTCONFIG10);
- assert_ssh_return_code(session, ret);
+ _parse_config(session, file, string, SSH_OK);
#ifdef _WIN32
/* The match exec is not supported on windows at this moment */
assert_string_equal(session->opts.host, "otherhost");
@@ -598,355 +787,435 @@ static void torture_config_match(void **state)
/* Try to create some invalid configurations */
/* Missing argument to Match*/
- torture_write_file(LIBSSH_TESTCONFIG10,
- "Match\n"
- "\tHost missing.com\n"
- "");
+ config = "Match\n"
+ "\tHost missing.com\n";
+ if (file != NULL) {
+ torture_write_file(file, config);
+ } else {
+ string = config;
+ }
torture_reset_config(session);
- ret = ssh_config_parse_file(session, LIBSSH_TESTCONFIG10);
- assert_ssh_return_code_equal(session, ret, SSH_ERROR);
+ _parse_config(session, file, string, SSH_ERROR);
/* Missing argument to unsupported option originalhost */
- torture_write_file(LIBSSH_TESTCONFIG10,
- "Match originalhost\n"
- "\tHost originalhost.com\n"
- "");
+ config = "Match originalhost\n"
+ "\tHost originalhost.com\n";
+ if (file != NULL) {
+ torture_write_file(file, config);
+ } else {
+ string = config;
+ }
torture_reset_config(session);
- ret = ssh_config_parse_file(session, LIBSSH_TESTCONFIG10);
- assert_ssh_return_code_equal(session, ret, SSH_ERROR);
+ _parse_config(session, file, string, SSH_ERROR);
/* Missing argument to option localuser */
- torture_write_file(LIBSSH_TESTCONFIG10,
- "Match localuser\n"
- "\tUser localuser2\n"
- "");
+ config = "Match localuser\n"
+ "\tUser localuser2\n";
+ if (file != NULL) {
+ torture_write_file(file, config);
+ } else {
+ string = config;
+ }
torture_reset_config(session);
- ret = ssh_config_parse_file(session, LIBSSH_TESTCONFIG10);
- assert_ssh_return_code_equal(session, ret, SSH_ERROR);
+ _parse_config(session, file, string, SSH_ERROR);
/* Missing argument to option user */
- torture_write_file(LIBSSH_TESTCONFIG10,
- "Match user\n"
- "\tUser user2\n"
- "");
+ config = "Match user\n"
+ "\tUser user2\n";
+ if (file != NULL) {
+ torture_write_file(file, config);
+ } else {
+ string = config;
+ }
torture_reset_config(session);
- ret = ssh_config_parse_file(session, LIBSSH_TESTCONFIG10);
- assert_ssh_return_code_equal(session, ret, SSH_ERROR);
+ _parse_config(session, file, string, SSH_ERROR);
/* Missing argument to option host */
- torture_write_file(LIBSSH_TESTCONFIG10,
- "Match host\n"
- "\tUser host2\n"
- "");
+ config = "Match host\n"
+ "\tUser host2\n";
+ if (file != NULL) {
+ torture_write_file(file, config);
+ } else {
+ string = config;
+ }
torture_reset_config(session);
- ret = ssh_config_parse_file(session, LIBSSH_TESTCONFIG10);
- assert_ssh_return_code_equal(session, ret, SSH_ERROR);
+ _parse_config(session, file, string, SSH_ERROR);
/* Missing argument to option exec */
- torture_write_file(LIBSSH_TESTCONFIG10,
- "Match exec\n"
- "\tUser exec\n"
- "");
+ config = "Match exec\n"
+ "\tUser exec\n";
+ if (file != NULL) {
+ torture_write_file(file, config);
+ } else {
+ string = config;
+ }
torture_reset_config(session);
- ret = ssh_config_parse_file(session, LIBSSH_TESTCONFIG10);
- assert_ssh_return_code_equal(session, ret, SSH_ERROR);
+ _parse_config(session, file, string, SSH_ERROR);
+}
+
+/**
+ * @brief Verify the configuration parser accepts Match keyword with
+ * full OpenSSH syntax through configuration file.
+ */
+static void torture_config_match_file(void **state)
+{
+ torture_config_match(state, LIBSSH_TESTCONFIG10, NULL);
+}
+
+/**
+ * @brief Verify the configuration parser accepts Match keyword with
+ * full OpenSSH syntax through configuration string.
+ */
+static void torture_config_match_string(void **state)
+{
+ torture_config_match(state, NULL, LIBSSH_TESTCONFIG_STRING10);
}
/**
* @brief Verify we can parse ProxyJump configuration option
*/
-static void torture_config_proxyjump(void **state) {
+static void torture_config_proxyjump(void **state,
+ const char *file, const char *string)
+{
ssh_session session = *state;
- int ret = 0;
+ const char *config;
/* Simplest version with just a hostname */
torture_reset_config(session);
ssh_options_set(session, SSH_OPTIONS_HOST, "simple");
- ret = ssh_config_parse_file(session, LIBSSH_TESTCONFIG11);
- assert_ssh_return_code(session, ret);
+ _parse_config(session, file, string, SSH_OK);
assert_string_equal(session->opts.ProxyCommand, "ssh -W [%h]:%p jumpbox");
/* With username */
torture_reset_config(session);
ssh_options_set(session, SSH_OPTIONS_HOST, "user");
- ret = ssh_config_parse_file(session, LIBSSH_TESTCONFIG11);
- assert_ssh_return_code(session, ret);
+ _parse_config(session, file, string, SSH_OK);
assert_string_equal(session->opts.ProxyCommand,
"ssh -l user -W [%h]:%p jumpbox");
/* With port */
torture_reset_config(session);
ssh_options_set(session, SSH_OPTIONS_HOST, "port");
- ret = ssh_config_parse_file(session, LIBSSH_TESTCONFIG11);
- assert_ssh_return_code(session, ret);
+ _parse_config(session, file, string, SSH_OK);
assert_string_equal(session->opts.ProxyCommand,
"ssh -p 2222 -W [%h]:%p jumpbox");
/* Two step jump */
torture_reset_config(session);
ssh_options_set(session, SSH_OPTIONS_HOST, "two-step");
- ret = ssh_config_parse_file(session, LIBSSH_TESTCONFIG11);
- assert_ssh_return_code(session, ret);
+ _parse_config(session, file, string, SSH_OK);
assert_string_equal(session->opts.ProxyCommand,
"ssh -l u1 -p 222 -J u2@second:33 -W [%h]:%p first");
/* none */
torture_reset_config(session);
ssh_options_set(session, SSH_OPTIONS_HOST, "none");
- ret = ssh_config_parse_file(session, LIBSSH_TESTCONFIG11);
- assert_ssh_return_code(session, ret);
+ _parse_config(session, file, string, SSH_OK);
assert_true(session->opts.ProxyCommand == NULL);
/* If also ProxyCommand is specifed, the first is applied */
torture_reset_config(session);
ssh_options_set(session, SSH_OPTIONS_HOST, "only-command");
- ret = ssh_config_parse_file(session, LIBSSH_TESTCONFIG11);
- assert_ssh_return_code(session, ret);
+ _parse_config(session, file, string, SSH_OK);
assert_string_equal(session->opts.ProxyCommand, PROXYCMD);
/* If also ProxyCommand is specifed, the first is applied */
torture_reset_config(session);
ssh_options_set(session, SSH_OPTIONS_HOST, "only-jump");
- ret = ssh_config_parse_file(session, LIBSSH_TESTCONFIG11);
- assert_ssh_return_code(session, ret);
+ _parse_config(session, file, string, SSH_OK);
assert_string_equal(session->opts.ProxyCommand,
"ssh -W [%h]:%p jumpbox");
/* IPv6 address */
torture_reset_config(session);
ssh_options_set(session, SSH_OPTIONS_HOST, "ipv6");
- ret = ssh_config_parse_file(session, LIBSSH_TESTCONFIG11);
- assert_ssh_return_code(session, ret);
+ _parse_config(session, file, string, SSH_OK);
assert_string_equal(session->opts.ProxyCommand,
"ssh -W [%h]:%p 2620:52:0::fed");
+ /* In this part, we try various other config files and strings. */
+
/* Try to create some invalid configurations */
/* Non-numeric port */
- torture_write_file(LIBSSH_TESTCONFIG11,
- "Host bad-port\n"
- "\tProxyJump jumpbox:22bad22\n"
- "");
+ config = "Host bad-port\n"
+ "\tProxyJump jumpbox:22bad22\n";
+ if (file != NULL) {
+ torture_write_file(file, config);
+ } else {
+ string = config;
+ }
torture_reset_config(session);
ssh_options_set(session, SSH_OPTIONS_HOST, "bad-port");
- ret = ssh_config_parse_file(session, LIBSSH_TESTCONFIG11);
- assert_ssh_return_code_equal(session, ret, SSH_ERROR);
+ _parse_config(session, file, string, SSH_ERROR);
/* Too many @ */
- torture_write_file(LIBSSH_TESTCONFIG11,
- "Host bad-hostname\n"
- "\tProxyJump user@principal.com@jumpbox:22\n"
- "");
+ config = "Host bad-hostname\n"
+ "\tProxyJump user@principal.com@jumpbox:22\n";
+ if (file != NULL) {
+ torture_write_file(file, config);
+ } else {
+ string = config;
+ }
torture_reset_config(session);
ssh_options_set(session, SSH_OPTIONS_HOST, "bad-hostname");
- ret = ssh_config_parse_file(session, LIBSSH_TESTCONFIG11);
- assert_ssh_return_code_equal(session, ret, SSH_ERROR);
+ _parse_config(session, file, string, SSH_ERROR);
/* Braces mismatch in hostname */
- torture_write_file(LIBSSH_TESTCONFIG11,
- "Host mismatch\n"
- "\tProxyJump [::1\n"
- "");
+ config = "Host mismatch\n"
+ "\tProxyJump [::1\n";
+ if (file != NULL) {
+ torture_write_file(file, config);
+ } else {
+ string = config;
+ }
torture_reset_config(session);
ssh_options_set(session, SSH_OPTIONS_HOST, "mismatch");
- ret = ssh_config_parse_file(session, LIBSSH_TESTCONFIG11);
- assert_ssh_return_code_equal(session, ret, SSH_ERROR);
+ _parse_config(session, file, string, SSH_ERROR);
/* Bad host-port separator */
- torture_write_file(LIBSSH_TESTCONFIG11,
- "Host beef\n"
- "\tProxyJump [dead::beef]::22\n"
- "");
+ config = "Host beef\n"
+ "\tProxyJump [dead::beef]::22\n";
+ if (file != NULL) {
+ torture_write_file(file, config);
+ } else {
+ string = config;
+ }
torture_reset_config(session);
ssh_options_set(session, SSH_OPTIONS_HOST, "beef");
- ret = ssh_config_parse_file(session, LIBSSH_TESTCONFIG11);
- assert_ssh_return_code_equal(session, ret, SSH_ERROR);
+ _parse_config(session, file, string, SSH_ERROR);
/* Missing hostname */
- torture_write_file(LIBSSH_TESTCONFIG11,
- "Host no-host\n"
- "\tProxyJump user@:22\n"
- "");
+ config = "Host no-host\n"
+ "\tProxyJump user@:22\n";
+ if (file != NULL) {
+ torture_write_file(file, config);
+ } else {
+ string = config;
+ }
torture_reset_config(session);
ssh_options_set(session, SSH_OPTIONS_HOST, "no-host");
- ret = ssh_config_parse_file(session, LIBSSH_TESTCONFIG11);
- assert_ssh_return_code_equal(session, ret, SSH_ERROR);
+ _parse_config(session, file, string, SSH_ERROR);
/* Missing user */
- torture_write_file(LIBSSH_TESTCONFIG11,
- "Host no-user\n"
- "\tProxyJump @host:22\n"
- "");
+ config = "Host no-user\n"
+ "\tProxyJump @host:22\n";
+ if (file != NULL) {
+ torture_write_file(file, config);
+ } else {
+ string = config;
+ }
torture_reset_config(session);
ssh_options_set(session, SSH_OPTIONS_HOST, "no-user");
- ret = ssh_config_parse_file(session, LIBSSH_TESTCONFIG11);
- assert_ssh_return_code_equal(session, ret, SSH_ERROR);
+ _parse_config(session, file, string, SSH_ERROR);
/* Missing port */
- torture_write_file(LIBSSH_TESTCONFIG11,
- "Host no-port\n"
- "\tProxyJump host:\n"
- "");
+ config = "Host no-port\n"
+ "\tProxyJump host:\n";
+ if (file != NULL) {
+ torture_write_file(file, config);
+ } else {
+ string = config;
+ }
torture_reset_config(session);
ssh_options_set(session, SSH_OPTIONS_HOST, "no-port");
- ret = ssh_config_parse_file(session, LIBSSH_TESTCONFIG11);
- assert_ssh_return_code_equal(session, ret, SSH_ERROR);
+ _parse_config(session, file, string, SSH_ERROR);
/* Non-numeric port in second jump */
- torture_write_file(LIBSSH_TESTCONFIG11,
- "Host bad-port-2\n"
- "\tProxyJump localhost,jumpbox:22bad22\n"
- "");
+ config = "Host bad-port-2\n"
+ "\tProxyJump localhost,jumpbox:22bad22\n";
+ if (file != NULL) {
+ torture_write_file(file, config);
+ } else {
+ string = config;
+ }
torture_reset_config(session);
ssh_options_set(session, SSH_OPTIONS_HOST, "bad-port-2");
- ret = ssh_config_parse_file(session, LIBSSH_TESTCONFIG11);
- assert_ssh_return_code_equal(session, ret, SSH_ERROR);
+ _parse_config(session, file, string, SSH_ERROR);
/* Too many @ in second jump */
- torture_write_file(LIBSSH_TESTCONFIG11,
- "Host bad-hostname\n"
- "\tProxyJump localhost,user@principal.com@jumpbox:22\n"
- "");
+ config = "Host bad-hostname\n"
+ "\tProxyJump localhost,user@principal.com@jumpbox:22\n";
+ if (file != NULL) {
+ torture_write_file(file, config);
+ } else {
+ string = config;
+ }
torture_reset_config(session);
ssh_options_set(session, SSH_OPTIONS_HOST, "bad-hostname");
- ret = ssh_config_parse_file(session, LIBSSH_TESTCONFIG11);
- assert_ssh_return_code_equal(session, ret, SSH_ERROR);
+ _parse_config(session, file, string, SSH_ERROR);
/* Braces mismatch in second jump */
- torture_write_file(LIBSSH_TESTCONFIG11,
- "Host mismatch\n"
- "\tProxyJump localhost,[::1:20\n"
- "");
+ config = "Host mismatch\n"
+ "\tProxyJump localhost,[::1:20\n";
+ if (file != NULL) {
+ torture_write_file(file, config);
+ } else {
+ string = config;
+ }
torture_reset_config(session);
ssh_options_set(session, SSH_OPTIONS_HOST, "mismatch");
- ret = ssh_config_parse_file(session, LIBSSH_TESTCONFIG11);
- assert_ssh_return_code_equal(session, ret, SSH_ERROR);
+ _parse_config(session, file, string, SSH_ERROR);
/* Bad host-port separator in second jump */
- torture_write_file(LIBSSH_TESTCONFIG11,
- "Host beef\n"
- "\tProxyJump localhost,[dead::beef]::22\n"
- "");
+ config = "Host beef\n"
+ "\tProxyJump localhost,[dead::beef]::22\n";
+ if (file != NULL) {
+ torture_write_file(file, config);
+ } else {
+ string = config;
+ }
torture_reset_config(session);
ssh_options_set(session, SSH_OPTIONS_HOST, "beef");
- ret = ssh_config_parse_file(session, LIBSSH_TESTCONFIG11);
- assert_ssh_return_code_equal(session, ret, SSH_ERROR);
+ _parse_config(session, file, string, SSH_ERROR);
/* Missing hostname in second jump */
- torture_write_file(LIBSSH_TESTCONFIG11,
- "Host no-host\n"
- "\tProxyJump localhost,user@:22\n"
- "");
+ config = "Host no-host\n"
+ "\tProxyJump localhost,user@:22\n";
+ if (file != NULL) {
+ torture_write_file(file, config);
+ } else {
+ string = config;
+ }
torture_reset_config(session);
ssh_options_set(session, SSH_OPTIONS_HOST, "no-host");
- ret = ssh_config_parse_file(session, LIBSSH_TESTCONFIG11);
- assert_ssh_return_code_equal(session, ret, SSH_ERROR);
+ _parse_config(session, file, string, SSH_ERROR);
/* Missing user in second jump */
- torture_write_file(LIBSSH_TESTCONFIG11,
- "Host no-user\n"
- "\tProxyJump localhost,@host:22\n"
- "");
+ config = "Host no-user\n"
+ "\tProxyJump localhost,@host:22\n";
+ if (file != NULL) {
+ torture_write_file(file, config);
+ } else {
+ string = config;
+ }
torture_reset_config(session);
ssh_options_set(session, SSH_OPTIONS_HOST, "no-user");
- ret = ssh_config_parse_file(session, LIBSSH_TESTCONFIG11);
- assert_ssh_return_code_equal(session, ret, SSH_ERROR);
+ _parse_config(session, file, string, SSH_ERROR);
/* Missing port in second jump */
- torture_write_file(LIBSSH_TESTCONFIG11,
- "Host no-port\n"
- "\tProxyJump localhost,host:\n"
- "");
+ config = "Host no-port\n"
+ "\tProxyJump localhost,host:\n";
+ if (file != NULL) {
+ torture_write_file(file, config);
+ } else {
+ string = config;
+ }
torture_reset_config(session);
ssh_options_set(session, SSH_OPTIONS_HOST, "no-port");
- ret = ssh_config_parse_file(session, LIBSSH_TESTCONFIG11);
- assert_ssh_return_code_equal(session, ret, SSH_ERROR);
+ _parse_config(session, file, string, SSH_ERROR);
+}
+
+/**
+ * @brief Verify we can parse ProxyJump configuration option from file
+ */
+static void torture_config_proxyjump_file(void **state)
+{
+ torture_config_proxyjump(state, LIBSSH_TESTCONFIG11, NULL);
+}
+
+/**
+ * @brief Verify we can parse ProxyJump configuration option from string
+ */
+static void torture_config_proxyjump_string(void **state)
+{
+ torture_config_proxyjump(state, NULL, LIBSSH_TESTCONFIG_STRING11);
}
/**
* @brief Verify the configuration parser handles all the possible
* versions of RekeyLimit configuration option.
*/
-static void torture_config_rekey(void **state)
+static void torture_config_rekey(void **state,
+ const char *file, const char *string)
{
ssh_session session = *state;
- int ret = 0;
/* Default values */
ssh_options_set(session, SSH_OPTIONS_HOST, "default");
- ret = ssh_config_parse_file(session, LIBSSH_TESTCONFIG12);
- assert_ssh_return_code(session, ret);
+ _parse_config(session, file, string, SSH_OK);
assert_int_equal(session->opts.rekey_data, 0);
assert_int_equal(session->opts.rekey_time, 0);
/* 42 GB */
torture_reset_config(session);
ssh_options_set(session, SSH_OPTIONS_HOST, "data1");
- ret = ssh_config_parse_file(session, LIBSSH_TESTCONFIG12);
- assert_ssh_return_code(session, ret);
- assert_int_equal(session->opts.rekey_data, (uint64_t) 42 * 1024 * 1024 * 1024);
+ _parse_config(session, file, string, SSH_OK);
+ assert_int_equal(session->opts.rekey_data,
+ (uint64_t) 42 * 1024 * 1024 * 1024);
assert_int_equal(session->opts.rekey_time, 0);
/* 41 MB */
torture_reset_config(session);
ssh_options_set(session, SSH_OPTIONS_HOST, "data2");
- ret = ssh_config_parse_file(session, LIBSSH_TESTCONFIG12);
- assert_ssh_return_code(session, ret);
+ _parse_config(session, file, string, SSH_OK);
assert_int_equal(session->opts.rekey_data, 31 * 1024 * 1024);
assert_int_equal(session->opts.rekey_time, 0);
/* 521 KB */
torture_reset_config(session);
ssh_options_set(session, SSH_OPTIONS_HOST, "data3");
- ret = ssh_config_parse_file(session, LIBSSH_TESTCONFIG12);
- assert_ssh_return_code(session, ret);
+ _parse_config(session, file, string, SSH_OK);
assert_int_equal(session->opts.rekey_data, 521 * 1024);
assert_int_equal(session->opts.rekey_time, 0);
/* default 3D */
torture_reset_config(session);
ssh_options_set(session, SSH_OPTIONS_HOST, "time1");
- ret = ssh_config_parse_file(session, LIBSSH_TESTCONFIG12);
- assert_ssh_return_code(session, ret);
+ _parse_config(session, file, string, SSH_OK);
assert_int_equal(session->opts.rekey_data, 0);
assert_int_equal(session->opts.rekey_time, 3 * 24 * 60 * 60 * 1000);
/* default 2h */
torture_reset_config(session);
ssh_options_set(session, SSH_OPTIONS_HOST, "time2");
- ret = ssh_config_parse_file(session, LIBSSH_TESTCONFIG12);
- assert_ssh_return_code(session, ret);
+ _parse_config(session, file, string, SSH_OK);
assert_int_equal(session->opts.rekey_data, 0);
assert_int_equal(session->opts.rekey_time, 2 * 60 * 60 * 1000);
/* default 160m */
torture_reset_config(session);
ssh_options_set(session, SSH_OPTIONS_HOST, "time3");
- ret = ssh_config_parse_file(session, LIBSSH_TESTCONFIG12);
- assert_ssh_return_code(session, ret);
+ _parse_config(session, file, string, SSH_OK);
assert_int_equal(session->opts.rekey_data, 0);
assert_int_equal(session->opts.rekey_time, 160 * 60 * 1000);
/* default 9600 [s] */
torture_reset_config(session);
ssh_options_set(session, SSH_OPTIONS_HOST, "time4");
- ret = ssh_config_parse_file(session, LIBSSH_TESTCONFIG12);
- assert_ssh_return_code(session, ret);
+ _parse_config(session, file, string, SSH_OK);
assert_int_equal(session->opts.rekey_data, 0);
assert_int_equal(session->opts.rekey_time, 9600 * 1000);
}
/**
- * @brief test ssh_config_parse_file with PubkeyAcceptedKeyTypes
+ * @brief Verify the configuration parser handles all the possible
+ * versions of RekeyLimit configuration option in file
+ */
+static void torture_config_rekey_file(void **state)
+{
+ torture_config_rekey(state, LIBSSH_TESTCONFIG12, NULL);
+}
+
+/**
+ * @brief Verify the configuration parser handles all the possible
+ * versions of RekeyLimit configuration option in string
+ */
+static void torture_config_rekey_string(void **state)
+{
+ torture_config_rekey(state, NULL, LIBSSH_TESTCONFIG_STRING12);
+}
+
+/**
+ * @brief test PubkeyAcceptedKeyTypes helper function
*/
-static void torture_config_pubkeyacceptedkeytypes(void **state)
+static void torture_config_pubkeytypes(void **state,
+ const char *file, const char *string)
{
ssh_session session = *state;
- int rc;
char *fips_algos;
- rc = ssh_config_parse_file(session, LIBSSH_TEST_PUBKEYACCEPTEDKEYTYPES);
- assert_int_equal(rc, SSH_OK);
+ _parse_config(session, file, string, SSH_OK);
if (ssh_fips_mode()) {
fips_algos = ssh_keep_fips_algos(SSH_HOSTKEYS, PUBKEYACCEPTEDTYPES);
@@ -954,10 +1223,85 @@ static void torture_config_pubkeyacceptedkeytypes(void **state)
assert_string_equal(session->opts.pubkey_accepted_types, fips_algos);
SAFE_FREE(fips_algos);
} else {
- assert_string_equal(session->opts.pubkey_accepted_types, PUBKEYACCEPTEDTYPES);
+ assert_string_equal(session->opts.pubkey_accepted_types,
+ PUBKEYACCEPTEDTYPES);
}
}
+/**
+ * @brief test parsing PubkeyAcceptedKeyTypes from file
+ */
+static void torture_config_pubkeytypes_file(void **state)
+{
+ torture_config_pubkeytypes(state, LIBSSH_TEST_PUBKEYTYPES, NULL);
+}
+
+/**
+ * @brief test parsing PubkeyAcceptedKeyTypes from string
+ */
+static void torture_config_pubkeytypes_string(void **state)
+{
+ torture_config_pubkeytypes(state, NULL, LIBSSH_TEST_PUBKEYTYPES_STRING);
+}
+
+/**
+ * @brief Verify the configuration parser handles
+ * missing newline in the end
+ */
+static void torture_config_nonewlineend(void **state,
+ const char *file, const char *string)
+{
+ _parse_config(*state, file, string, SSH_OK);
+}
+
+/**
+ * @brief Verify the configuration parser handles
+ * missing newline in the end of file
+ */
+static void torture_config_nonewlineend_file(void **state)
+{
+ torture_config_nonewlineend(state, LIBSSH_TEST_NONEWLINEEND, NULL);
+}
+
+/**
+ * @brief Verify the configuration parser handles
+ * missing newline in the end of string
+ */
+static void torture_config_nonewlineend_string(void **state)
+{
+ torture_config_nonewlineend(state, NULL, LIBSSH_TEST_NONEWLINEEND_STRING);
+}
+
+/**
+ * @brief Verify the configuration parser handles
+ * missing newline in the end
+ */
+static void torture_config_nonewlineoneline(void **state,
+ const char *file,
+ const char *string)
+{
+ _parse_config(*state, file, string, SSH_OK);
+}
+
+/**
+ * @brief Verify the configuration parser handles
+ * missing newline in the end of file
+ */
+static void torture_config_nonewlineoneline_file(void **state)
+{
+ torture_config_nonewlineend(state, LIBSSH_TEST_NONEWLINEONELINE, NULL);
+}
+
+/**
+ * @brief Verify the configuration parser handles
+ * missing newline in the end of string
+ */
+static void torture_config_nonewlineoneline_string(void **state)
+{
+ torture_config_nonewlineoneline(state,
+ NULL, LIBSSH_TEST_NONEWLINEONELINE_STRING);
+}
+
/* ssh_config_get_cmd() does three things:
* * Strips leading whitespace
* * Terminate the characted on the end of next quotes-enclosed string
@@ -994,7 +1338,8 @@ static void torture_config_parser_get_cmd(void **state)
assert_string_equal(tok, "something");
assert_int_equal(*p, '\0');
- /* But it does not split tokens by whitespace if they are not quoted, which is weird */
+ /* But it does not split tokens by whitespace
+ * if they are not quoted, which is weird */
strncpy(data, "multi string something\n", sizeof(data));
p = data;
tok = ssh_config_get_cmd(&p);
@@ -1004,7 +1349,8 @@ static void torture_config_parser_get_cmd(void **state)
/* ssh_config_get_token() should behave as expected
* * Strip leading whitespace
- * * Return first token separated by whitespace or equal sign, respecting quotes!
+ * * Return first token separated by whitespace or equal sign,
+ * respecting quotes!
*/
static void torture_config_parser_get_token(void **state)
{
@@ -1206,7 +1552,8 @@ static void torture_config_match_pattern(void **state)
assert_int_equal(rv, 1);
rv = match_pattern("aa", "?", MAX_MATCH_RECURSION);
assert_int_equal(rv, 0);
- rv = match_pattern("?", "a", MAX_MATCH_RECURSION); /* Wildcard in search string */
+ /* Wildcard in search string */
+ rv = match_pattern("?", "a", MAX_MATCH_RECURSION);
assert_int_equal(rv, 0);
rv = match_pattern("?", "?", MAX_MATCH_RECURSION);
assert_int_equal(rv, 1);
@@ -1216,7 +1563,8 @@ static void torture_config_match_pattern(void **state)
assert_int_equal(rv, 1);
rv = match_pattern("aa", "*", MAX_MATCH_RECURSION);
assert_int_equal(rv, 1);
- rv = match_pattern("*", "a", MAX_MATCH_RECURSION); /* Wildcard in search string */
+ /* Wildcard in search string */
+ rv = match_pattern("*", "a", MAX_MATCH_RECURSION);
assert_int_equal(rv, 0);
rv = match_pattern("*", "*", MAX_MATCH_RECURSION);
assert_int_equal(rv, 1);
@@ -1256,34 +1604,78 @@ static void torture_config_match_pattern(void **state)
/* Limit the maximum recursion */
rv = match_pattern("hostname", "*p*a*t*t*e*r*n*", 5);
assert_int_equal(rv, 0);
- rv = match_pattern("pattern", "*p*a*t*t*e*r*n*", 5); /* Too much recursion */
+ /* Too much recursion */
+ rv = match_pattern("pattern", "*p*a*t*t*e*r*n*", 5);
assert_int_equal(rv, 0);
}
-int torture_run_tests(void) {
+int torture_run_tests(void)
+{
int rc;
struct CMUnitTest tests[] = {
- cmocka_unit_test(torture_config_from_file),
- cmocka_unit_test(torture_config_double_ports),
- cmocka_unit_test(torture_config_glob),
- cmocka_unit_test(torture_config_new),
- cmocka_unit_test(torture_config_auth_methods),
- cmocka_unit_test(torture_config_unknown),
- cmocka_unit_test(torture_config_match),
- cmocka_unit_test(torture_config_proxyjump),
- cmocka_unit_test(torture_config_rekey),
- cmocka_unit_test(torture_config_pubkeyacceptedkeytypes),
- cmocka_unit_test(torture_config_parser_get_cmd),
- cmocka_unit_test(torture_config_parser_get_token),
- cmocka_unit_test(torture_config_match_pattern),
+ cmocka_unit_test_setup_teardown(torture_config_include_file,
+ setup, teardown),
+ cmocka_unit_test_setup_teardown(torture_config_include_string,
+ setup, teardown),
+ cmocka_unit_test_setup_teardown(torture_config_double_ports_file,
+ setup, teardown),
+ cmocka_unit_test_setup_teardown(torture_config_double_ports_string,
+ setup, teardown),
+ cmocka_unit_test_setup_teardown(torture_config_glob_file,
+ setup, teardown),
+ cmocka_unit_test_setup_teardown(torture_config_glob_string,
+ setup, teardown),
+ cmocka_unit_test_setup_teardown(torture_config_new_file,
+ setup, teardown),
+ cmocka_unit_test_setup_teardown(torture_config_new_string,
+ setup, teardown),
+ cmocka_unit_test_setup_teardown(torture_config_auth_methods_file,
+ setup, teardown),
+ cmocka_unit_test_setup_teardown(torture_config_auth_methods_string,
+ setup, teardown),
+ cmocka_unit_test_setup_teardown(torture_config_unknown_file,
+ setup, teardown),
+ cmocka_unit_test_setup_teardown(torture_config_unknown_string,
+ setup, teardown),
+ cmocka_unit_test_setup_teardown(torture_config_match_file,
+ setup, teardown),
+ cmocka_unit_test_setup_teardown(torture_config_match_string,
+ setup, teardown),
+ cmocka_unit_test_setup_teardown(torture_config_proxyjump_file,
+ setup, teardown),
+ cmocka_unit_test_setup_teardown(torture_config_proxyjump_string,
+ setup, teardown),
+ cmocka_unit_test_setup_teardown(torture_config_rekey_file,
+ setup, teardown),
+ cmocka_unit_test_setup_teardown(torture_config_rekey_string,
+ setup, teardown),
+ cmocka_unit_test_setup_teardown(torture_config_pubkeytypes_file,
+ setup, teardown),
+ cmocka_unit_test_setup_teardown(torture_config_pubkeytypes_string,
+ setup, teardown),
+ cmocka_unit_test_setup_teardown(torture_config_nonewlineend_file,
+ setup, teardown),
+ cmocka_unit_test_setup_teardown(torture_config_nonewlineend_string,
+ setup, teardown),
+ cmocka_unit_test_setup_teardown(torture_config_nonewlineoneline_file,
+ setup, teardown),
+ cmocka_unit_test_setup_teardown(torture_config_nonewlineoneline_string,
+ setup, teardown),
+ cmocka_unit_test_setup_teardown(torture_config_parser_get_cmd,
+ setup, teardown),
+ cmocka_unit_test_setup_teardown(torture_config_parser_get_token,
+ setup, teardown),
+ cmocka_unit_test_setup_teardown(torture_config_match_pattern,
+ setup, teardown),
};
ssh_init();
torture_filter_tests(tests);
- rc = cmocka_run_group_tests(tests, setup_config_files, teardown);
+ rc = cmocka_run_group_tests(tests,
+ setup_config_files, teardown_config_files);
ssh_finalize();
return rc;
}