diff --git a/src/misc.c b/src/misc.c index 191a540a..0d702f7b 100644 --- a/src/misc.c +++ b/src/misc.c @@ -1264,6 +1264,7 @@ static char *get_connection_hash(ssh_session session) SHACTX ctx = sha1_init(); char strport[10] = {0}; unsigned int port; + char *username = NULL; int rc; if (session == NULL) { @@ -1286,6 +1287,9 @@ static char *get_connection_hash(ssh_session session) SAFE_FREE(local_hostname); /* Remote hostname %h */ + if (session->opts.host == NULL) { + goto err; + } rc = sha1_update(ctx, session->opts.host, strlen(session->opts.host)); if (rc != SSH_OK) { goto err; @@ -1300,9 +1304,18 @@ static char *get_connection_hash(ssh_session session) } /* The remote username %r */ - rc = sha1_update(ctx, - session->opts.username, - strlen(session->opts.username)); + username = session->opts.username; + if (username == NULL) { + /* fallback to local username: it will be used if not explicitly set */ + username = ssh_get_local_username(); + if (username == NULL) { + goto err; + } + } + rc = sha1_update(ctx, username, strlen(username)); + if (username != session->opts.username) { + free(username); + } if (rc != SSH_OK) { goto err; } diff --git a/tests/client/torture_client_config.c b/tests/client/torture_client_config.c index f532f0df..61b4bedb 100644 --- a/tests/client/torture_client_config.c +++ b/tests/client/torture_client_config.c @@ -238,6 +238,31 @@ static void torture_client_config_suppress(void **state) assert_string_equal(s->ssh.session->opts.username, "bob"); } +static void torture_client_config_expand_bad(void **state) +{ + ssh_session session = ssh_new(); + int ret = 0; + + (void)state; + + assert_non_null(session); + + /* The hash without host fails, but does not crash */ + ssh_options_set(session, SSH_OPTIONS_KNOWNHOSTS, "%C"); + + ret = ssh_options_apply(session); + assert_ssh_return_code_equal(session, ret, SSH_ERROR); + + /* The hash without host fails, but does not crash */ + ssh_options_set(session, SSH_OPTIONS_HOST, TORTURE_SSH_SERVER); + ssh_options_set(session, SSH_OPTIONS_KNOWNHOSTS, "%C"); + + ret = ssh_options_apply(session); + assert_ssh_return_code_equal(session, ret, SSH_OK); + + ssh_free(session); +} + static void torture_client_config_expand(void **state) { struct torture_state *s = *state; @@ -434,8 +459,9 @@ static void torture_client_config_expand(void **state) int torture_run_tests(void) { int rc; struct CMUnitTest tests[] = { - /* Keep this first -- following setup is changing user to bob, which we + /* Keep these first -- following setup is changing user to bob, which we * do not want */ + cmocka_unit_test(torture_client_config_expand_bad), cmocka_unit_test_setup_teardown(torture_client_config_expand, setup_session, teardown_session), @@ -453,7 +479,6 @@ int torture_run_tests(void) { teardown), }; - ssh_init(); torture_filter_tests(tests); rc = cmocka_run_group_tests(tests, sshd_setup, sshd_teardown);