From 1a02364b5107a4125ea3cb76fcdb6beabaebf3be Mon Sep 17 00:00:00 2001 From: Jakub Jelen Date: Fri, 22 Dec 2023 10:32:40 +0100 Subject: [PATCH] Fix regression in IPv6 addresses in hostname parsing Signed-off-by: Jakub Jelen Reviewed-by: Andreas Schneider (cherry picked from commit 4f997aee7c7d7ea346b3e8ba505da0b7601ff318) CVE: CVE-2023-6004 Upstream-Status: Backport [https://gitlab.com/libssh/libssh-mirror/-/commit/1a02364b5107a4125ea3cb76fcdb6beabaebf3be] Signed-off-by: nikhil r Comment: Removed 1 hunk from config_parser.c as the function was intoduced in later version --- include/libssh/config_parser.h | 11 ++++++++--- src/config.c | 4 ++-- src/config_parser.c | 16 +++++++++++----- src/options.c | 10 ++-------- 4 files changed, 23 insertions(+), 18 deletions(-) diff --git a/include/libssh/config_parser.h b/include/libssh/config_parser.h index a7dd42a2c..ca353432b 100644 --- a/include/libssh/config_parser.h +++ b/include/libssh/config_parser.h @@ -26,6 +26,8 @@ #ifndef CONFIG_PARSER_H_ #define CONFIG_PARSER_H_ +#include + 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 notfound); * 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_ */ diff --git a/src/config_parser.c b/src/config_parser.c index b8b94611a..d4b2d2c3b 100644 --- a/src/config_parser.c +++ b/src/config_parser.c @@ -162,9 +162,10 @@ int ssh_config_get_yesno(char **str, int notfound) } 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; @@ -210,12 +211,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 */ diff --git a/src/options.c b/src/options.c index 385114555..b3ecffe15 100644 --- a/src/options.c +++ b/src/options.c @@ -416,17 +416,11 @@ int ssh_options_set(ssh_session session, enum ssh_options_e type, 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;