CVE-2023-6004: misc: Add ipv6 link-local check for an ip address

Signed-off-by: Norbert Pocs <norbertpocs0@gmail.com>
Reviewed-by: Andreas Schneider <asn@cryptomilk.org>
This commit is contained in:
Norbert Pocs
2023-11-28 15:26:45 +01:00
committed by Andreas Schneider
parent a0dbe0d556
commit cdaec0d627
3 changed files with 49 additions and 14 deletions

View File

@@ -9,13 +9,6 @@ set(LIBSSH_LINK_LIBRARIES
${LIBSSH_REQUIRED_LIBRARIES} ${LIBSSH_REQUIRED_LIBRARIES}
) )
if (WIN32)
set(LIBSSH_LINK_LIBRARIES
${LIBSSH_LINK_LIBRARIES}
ws2_32
)
endif (WIN32)
if (OPENSSL_CRYPTO_LIBRARIES) if (OPENSSL_CRYPTO_LIBRARIES)
set(LIBSSH_PRIVATE_INCLUDE_DIRS set(LIBSSH_PRIVATE_INCLUDE_DIRS
${LIBSSH_PRIVATE_INCLUDE_DIRS} ${LIBSSH_PRIVATE_INCLUDE_DIRS}
@@ -93,6 +86,16 @@ if (MINGW AND Threads_FOUND)
) )
endif() endif()
# This needs to be last for mingw to build
# https://gitlab.com/libssh/libssh-mirror/-/issues/84
if (WIN32)
set(LIBSSH_LINK_LIBRARIES
${LIBSSH_LINK_LIBRARIES}
iphlpapi
ws2_32
)
endif (WIN32)
if (BUILD_STATIC_LIB) if (BUILD_STATIC_LIB)
set(LIBSSH_STATIC_LIBRARY set(LIBSSH_STATIC_LIBRARY
ssh_static ssh_static

View File

@@ -136,7 +136,7 @@ static int getai(const char *host, int port, struct addrinfo **ai)
#endif #endif
} }
if (ssh_is_ipaddr(host)) { if (ssh_is_ipaddr(host) == 1) {
/* this is an IP address */ /* this is an IP address */
SSH_LOG(SSH_LOG_PACKET, "host %s matches an IP address", host); SSH_LOG(SSH_LOG_PACKET, "host %s matches an IP address", host);
hints.ai_flags |= AI_NUMERICHOST; hints.ai_flags |= AI_NUMERICHOST;

View File

@@ -32,6 +32,7 @@
#include <sys/socket.h> #include <sys/socket.h>
#include <netinet/in.h> #include <netinet/in.h>
#include <arpa/inet.h> #include <arpa/inet.h>
#include <net/if.h>
#endif /* _WIN32 */ #endif /* _WIN32 */
@@ -59,6 +60,7 @@
#include <ws2tcpip.h> #include <ws2tcpip.h>
#include <shlobj.h> #include <shlobj.h>
#include <direct.h> #include <direct.h>
#include <netioapi.h>
#ifdef HAVE_IO_H #ifdef HAVE_IO_H
#include <io.h> #include <io.h>
@@ -216,22 +218,37 @@ int ssh_is_ipaddr_v4(const char *str) {
int ssh_is_ipaddr(const char *str) { int ssh_is_ipaddr(const char *str) {
int rc = SOCKET_ERROR; int rc = SOCKET_ERROR;
char *s = strdup(str);
if (strchr(str, ':')) { if (s == NULL) {
return -1;
}
if (strchr(s, ':')) {
struct sockaddr_storage ss; struct sockaddr_storage ss;
int sslen = sizeof(ss); int sslen = sizeof(ss);
char *network_interface = strchr(s, '%');
/* TODO link-local (IP:v6:addr%ifname). */ /* link-local (IP:v6:addr%ifname). */
rc = WSAStringToAddressA((LPSTR) str, if (network_interface != NULL) {
rc = if_nametoindex(network_interface + 1);
if (rc == 0) {
free(s);
return 0;
}
*network_interface = '\0';
}
rc = WSAStringToAddressA((LPSTR) s,
AF_INET6, AF_INET6,
NULL, NULL,
(struct sockaddr*)&ss, (struct sockaddr*)&ss,
&sslen); &sslen);
if (rc == 0) { if (rc == 0) {
free(s);
return 1; return 1;
} }
} }
free(s);
return ssh_is_ipaddr_v4(str); return ssh_is_ipaddr_v4(str);
} }
#else /* _WIN32 */ #else /* _WIN32 */
@@ -335,17 +352,32 @@ int ssh_is_ipaddr_v4(const char *str) {
int ssh_is_ipaddr(const char *str) { int ssh_is_ipaddr(const char *str) {
int rc = -1; int rc = -1;
char *s = strdup(str);
if (strchr(str, ':')) { if (s == NULL) {
return -1;
}
if (strchr(s, ':')) {
struct in6_addr dest6; struct in6_addr dest6;
char *network_interface = strchr(s, '%');
/* TODO link-local (IP:v6:addr%ifname). */ /* link-local (IP:v6:addr%ifname). */
rc = inet_pton(AF_INET6, str, &dest6); if (network_interface != NULL) {
rc = if_nametoindex(network_interface + 1);
if (rc == 0) {
free(s);
return 0;
}
*network_interface = '\0';
}
rc = inet_pton(AF_INET6, s, &dest6);
if (rc > 0) { if (rc > 0) {
free(s);
return 1; return 1;
} }
} }
free(s);
return ssh_is_ipaddr_v4(str); return ssh_is_ipaddr_v4(str);
} }