From 8615c24647f773a5e04203c7459512715d698be1 Mon Sep 17 00:00:00 2001
From: Norbert Pocs <norbertpocs0@gmail.com>
Date: Tue, 31 Oct 2023 09:48:52 +0100
Subject: [PATCH] CVE-2023-6004: options: Simplify the hostname parsing in
 ssh_options_set

Using ssh_config_parse_uri can simplify the parsing of the host
parsing inside the function of ssh_options_set

Signed-off-by: Norbert Pocs <norbertpocs0@gmail.com>
Reviewed-by: Andreas Schneider <asn@cryptomilk.org>
Reviewed-by: Jakub Jelen <jjelen@redhat.com>

CVE: CVE-2023-6004
Upstream-Status: Backport [https://gitlab.com/libssh/libssh-mirror/-/commit/8615c24647f773a5e04203c7459512715d698be1]
Signed-off-by: nikhil r <nikhil.r@kpit.com>
Comment: Refreshed hunk 2 from option.c

---
 src/options.c | 40 ++++++++++++++++------------------------
 1 file changed, 16 insertions(+), 24 deletions(-)

diff --git a/src/options.c b/src/options.c
index 6f2c9397e..385114555 100644
--- a/src/options.c
+++ b/src/options.c
@@ -36,6 +36,7 @@
 #include "libssh/session.h"
 #include "libssh/misc.h"
 #include "libssh/options.h"
+#include "libssh/config_parser.h"
 #ifdef WITH_SERVER
 #include "libssh/server.h"
 #include "libssh/bind.h"
@@ -415,33 +416,24 @@ int ssh_options_set(ssh_session session, enum ssh_options_e type,
                 ssh_set_error_invalid(session);
                 return -1;
             } else {
-                q = strdup(value);
-                if (q == NULL) {
-                    ssh_set_error_oom(session);
+                char *username = NULL, *hostname = NULL, *port = NULL;
+                rc = ssh_config_parse_uri(value, &username, &hostname, &port);
+                if (rc != SSH_OK) {
                     return -1;
                 }
-                p = strchr(q, '@');
-
-                SAFE_FREE(session->opts.host);
-
-                if (p) {
-                    *p = '\0';
-                    session->opts.host = strdup(p + 1);
-                    if (session->opts.host == NULL) {
-                        SAFE_FREE(q);
-                        ssh_set_error_oom(session);
-                        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 = strdup(q);
-                    SAFE_FREE(q);
-                    if (session->opts.username == NULL) {
-                        ssh_set_error_oom(session);
-                        return -1;
-                    }
-                } else {
-                    session->opts.host = q;
+                   session->opts.username = username;
+                }
+                if (hostname != NULL) {
+                    SAFE_FREE(session->opts.host);
+                    session->opts.host = hostname;
                 }
             }
             break;
