Sign Up
Log In
Log In
or
Sign Up
Places
All Projects
Status Monitor
Collapse sidebar
openSUSE:Step:15-SP4
libssh
libssh-fix-ipv6-hostname-regression.patch
Overview
Repositories
Revisions
Requests
Users
Attributes
Meta
File libssh-fix-ipv6-hostname-regression.patch of Package libssh
Ported the following with a few extra test functions From 66ac6343b246458a6645ae32f75556a1407031ec Mon Sep 17 00:00:00 2001 From: Jakub Jelen <jjelen@redhat.com> Date: Fri, 22 Dec 2023 10:32:40 +0100 Subject: [PATCH 1/2] Fix regression in IPv6 addresses in hostname parsing Signed-off-by: Jakub Jelen <jjelen@redhat.com> --- include/libssh/config_parser.h | 11 ++++++++--- src/config.c | 4 ++-- src/config_parser.c | 19 ++++++++++++++----- src/options.c | 10 ++-------- 4 files changed, 26 insertions(+), 18 deletions(-) Index: libssh-0.9.8/include/libssh/config_parser.h =================================================================== --- libssh-0.9.8.orig/include/libssh/config_parser.h +++ libssh-0.9.8/include/libssh/config_parser.h @@ -26,6 +26,8 @@ #ifndef CONFIG_PARSER_H_ #define CONFIG_PARSER_H_ +#include <stdbool.h> + char *ssh_config_get_cmd(char **str); char *ssh_config_get_token(char **str); @@ -45,13 +47,16 @@ int ssh_config_get_yesno(char **str, int * be stored or NULL if we do not care about the result. * @param[out] port Pointer to the location, where the new port will * be stored or NULL if we do not care about the result. + * @param[in] ignore_port Set to true if the we should not attempt to parse + * port number. * * @returns SSH_OK if the provided string is in format of SSH URI, * SSH_ERROR on failure */ int ssh_config_parse_uri(const char *tok, - char **username, - char **hostname, - char **port); + char **username, + char **hostname, + char **port, + bool ignore_port); #endif /* LIBSSH_CONFIG_H_ */ Index: libssh-0.9.8/src/config.c =================================================================== --- libssh-0.9.8.orig/src/config.c +++ libssh-0.9.8/src/config.c @@ -324,7 +324,7 @@ ssh_config_parse_proxy_jump(ssh_session } if (parse_entry) { /* We actually care only about the first item */ - rv = ssh_config_parse_uri(cp, &username, &hostname, &port); + rv = ssh_config_parse_uri(cp, &username, &hostname, &port, false); /* The rest of the list needs to be passed on */ if (endp != NULL) { next = strdup(endp + 1); @@ -335,7 +335,7 @@ ssh_config_parse_proxy_jump(ssh_session } } else { /* The rest is just sanity-checked to avoid failures later */ - rv = ssh_config_parse_uri(cp, NULL, NULL, NULL); + rv = ssh_config_parse_uri(cp, NULL, NULL, NULL, false); } if (rv != SSH_OK) { goto out; Index: libssh-0.9.8/src/config_parser.c =================================================================== --- libssh-0.9.8.orig/src/config_parser.c +++ libssh-0.9.8/src/config_parser.c @@ -133,10 +133,14 @@ int ssh_config_get_yesno(char **str, int return notfound; } +/* Parse the URI extracting parts such as a username, hostname and port. + * If the port is NULL, do not expect port present and be more lax for example + * with matching IPv6 address which have the same separators as host:port */ int ssh_config_parse_uri(const char *tok, - char **username, - char **hostname, - char **port) + char **username, + char **hostname, + char **port, + bool ignore_port) { char *endp = NULL; long port_n; @@ -182,12 +186,17 @@ int ssh_config_parse_uri(const char *tok if (endp == NULL) { goto error; } - } else { - /* Hostnames or aliases expand to the last colon or to the end */ + } else if (!ignore_port) { + /* Hostnames or aliases expand to the last colon (if port is requested) + * or to the end */ endp = strrchr(tok, ':'); if (endp == NULL) { endp = strchr(tok, '\0'); } + } else { + /* If no port is requested, expand to the end of line + * (to accommodate the IPv6 addresses) */ + endp = strchr(tok, '\0'); } if (tok == endp) { /* Zero-length hostnames are not valid */ Index: libssh-0.9.8/src/options.c =================================================================== --- libssh-0.9.8.orig/src/options.c +++ libssh-0.9.8/src/options.c @@ -491,17 +491,11 @@ int ssh_options_set(ssh_session session, ssh_set_error_invalid(session); return -1; } else { - char *username = NULL, *hostname = NULL, *port = NULL; - rc = ssh_config_parse_uri(value, &username, &hostname, &port); + char *username = NULL, *hostname = NULL; + rc = ssh_config_parse_uri(value, &username, &hostname, NULL, true); if (rc != SSH_OK) { return -1; } - if (port != NULL) { - SAFE_FREE(username); - SAFE_FREE(hostname); - SAFE_FREE(port); - return -1; - } if (username != NULL) { SAFE_FREE(session->opts.username); session->opts.username = username; Index: libssh-0.9.8/tests/unittests/torture_config.c =================================================================== --- libssh-0.9.8.orig/tests/unittests/torture_config.c +++ libssh-0.9.8/tests/unittests/torture_config.c @@ -7,6 +7,7 @@ #include "libssh/session.h" #include "libssh/config_parser.h" #include "match.c" +#include <errno.h> extern LIBSSH_THREAD int ssh_log_level; @@ -199,7 +200,7 @@ static int setup_config_files(void **sta return 0; } -static int teardown(void **state) +static int teardown_config_files(void **state) { unlink(LIBSSH_TESTCONFIG1); unlink(LIBSSH_TESTCONFIG2); @@ -220,6 +221,32 @@ static int teardown(void **state) return 0; } +static int setup(void **state) +{ + ssh_session session = NULL; + char *wd = NULL; + int verbosity; + + session = ssh_new(); + + verbosity = torture_libssh_verbosity(); + ssh_options_set(session, SSH_OPTIONS_LOG_VERBOSITY, &verbosity); + wd = torture_get_current_working_dir(); + ssh_options_set(session, SSH_OPTIONS_SSH_DIR, wd); + free(wd); + + *state = session; + + return 0; +} + +static int teardown(void **state) +{ + ssh_free(*state); + + return 0; +} + /** * @brief tests ssh_config_parse_file with Include directives */ @@ -997,6 +1024,52 @@ static void torture_config_match_pattern } +static void torture_config_parse_uri(void **state) +{ + char *username = NULL; + char *hostname = NULL; + char *port = NULL; + int rc; + + (void)state; /* unused */ + + rc = ssh_config_parse_uri("localhost", &username, &hostname, &port, false); + assert_return_code(rc, errno); + assert_null(username); + assert_string_equal(hostname, "localhost"); + SAFE_FREE(hostname); + assert_null(port); + + rc = ssh_config_parse_uri("1.2.3.4", &username, &hostname, &port, false); + assert_return_code(rc, errno); + assert_null(username); + assert_string_equal(hostname, "1.2.3.4"); + SAFE_FREE(hostname); + assert_null(port); + + rc = ssh_config_parse_uri("1.2.3.4:2222", &username, &hostname, &port, false); + assert_return_code(rc, errno); + assert_null(username); + assert_string_equal(hostname, "1.2.3.4"); + SAFE_FREE(hostname); + assert_string_equal(port, "2222"); + SAFE_FREE(port); + + rc = ssh_config_parse_uri("[1:2:3::4]:2222", &username, &hostname, &port, false); + assert_return_code(rc, errno); + assert_null(username); + assert_string_equal(hostname, "1:2:3::4"); + SAFE_FREE(hostname); + assert_string_equal(port, "2222"); + SAFE_FREE(port); + + /* do not want port */ + rc = ssh_config_parse_uri("1:2:3::4", &username, &hostname, NULL, true); + assert_return_code(rc, errno); + assert_null(username); + assert_string_equal(hostname, "1:2:3::4"); + SAFE_FREE(hostname); +} int torture_run_tests(void) { int rc; @@ -1012,12 +1085,14 @@ int torture_run_tests(void) { cmocka_unit_test(torture_config_rekey), cmocka_unit_test(torture_config_pubkeyacceptedkeytypes), cmocka_unit_test(torture_config_match_pattern), + cmocka_unit_test_setup_teardown(torture_config_parse_uri, + 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; } Index: libssh-0.9.8/tests/unittests/torture_options.c =================================================================== --- libssh-0.9.8.orig/tests/unittests/torture_options.c +++ libssh-0.9.8/tests/unittests/torture_options.c @@ -59,6 +59,20 @@ static void torture_options_set_host(voi assert_non_null(session->opts.host); assert_string_equal(session->opts.host, "localhost"); + /* IPv4 address */ + rc = ssh_options_set(session, SSH_OPTIONS_HOST, "127.1.1.1"); + assert_true(rc == 0); + assert_non_null(session->opts.host); + assert_string_equal(session->opts.host, "127.1.1.1"); + assert_null(session->opts.username); + + /* IPv6 address */ + rc = ssh_options_set(session, SSH_OPTIONS_HOST, "::1"); + assert_true(rc == 0); + assert_non_null(session->opts.host); + assert_string_equal(session->opts.host, "::1"); + assert_null(session->opts.username); + rc = ssh_options_set(session, SSH_OPTIONS_HOST, "guru@meditation"); assert_true(rc == 0); assert_non_null(session->opts.host);
Locations
Projects
Search
Status Monitor
Help
OpenBuildService.org
Documentation
API Documentation
Code of Conduct
Contact
Support
@OBShq
Terms
openSUSE Build Service is sponsored by
The Open Build Service is an
openSUSE project
.
Sign Up
Log In
Places
Places
All Projects
Status Monitor