Do not take IP address as SNI parameter

This commit is contained in:
Gerhard Rieger 2023-06-12 19:23:09 +02:00
parent d355da98bc
commit 3678757fed
4 changed files with 79 additions and 1 deletions

View file

@ -45,6 +45,10 @@ Corrections:
Thanks to Gordon W.Ross for reporting and fixing this issue. Thanks to Gordon W.Ross for reporting and fixing this issue.
Test: RESTORE_TTY Test: RESTORE_TTY
The OpenSSL client SNI parameter, when not explicitely specified, is
derived from option commonname or rom target server name. This is not
useful with IP addresses, which Socat now checks and avoids.
Features: Features:
VSOCK, VSOCK-L support options pf, socktype, prototype (currently VSOCK, VSOCK-L support options pf, socktype, prototype (currently
useless) useless)

View file

@ -457,6 +457,72 @@ char *sockaddr_inet6_info(const struct sockaddr_in6 *sa, char *buff, size_t blen
} }
#endif /* WITH_IP6 */ #endif /* WITH_IP6 */
#if WITH_IP4
/* Checks if the given string is an IPv4 address.
Returns 0 when it is an address.
Returns 1 when it is not an address.
Returns -1 when an error occurred (bad regex - internal) */
int check_ip4addr(
const char *address)
{
#if HAVE_REGEX_H
regex_t preg;
if (regcomp(&preg, "^(25[0-5]|(2[0-4]|1[0-9]|[1-9]?)[0-9])\\.(25[0-5]|(2[0-4]|1[0-9]|[1-9]?)[0-9])\\.(25[0-5]|(2[0-4]|1[0-9]|[1-9]?)[0-9])\\.(25[0-5]|(2[0-4]|1[0-9]|[1-9]?)[0-9])$", REG_EXTENDED|REG_NOSUB)
!= 0) {
return -1; /* do not handle, just state that no match */
}
if (regexec(&preg, address, 0, NULL, 0) == 0) {
return 0;
}
#endif /* HAVE_REGEX_H */
/* Fallback when no regexec() compiled in */
return 1;
}
#endif /* WITH_IP4 */
#if WITH_IP6
/* Checks if the given string is an IPv6 address.
Currently a hack, just checks a few criteria.
Returns 0 when it is an address.
Returns 1 when it is not an address.
Returns -1 when an error occurred (bad regex - internal) */
int check_ip6addr(
const char *address)
{
#if HAVE_REGEX_H
regex_t preg;
if (regcomp(&preg, "^\\[[0-9a-fA-F:]*\\]$", REG_EXTENDED|REG_NOSUB)
!= 0) {
return -1; /* do not handle, just state that no match */
}
if (regexec(&preg, address, 0, NULL, 0) == 0) {
return 0;
}
#endif /* HAVE_REGEX_H */
/* Fallback when no regexec() compiled in */
return 1;
}
#endif /* WITH_IP6 */
/* Checks if the given string is an IPv6 address.
Currently a hack, just checks a few criteria.
Returns 0 when it is an address.
Returns 1 when it is not an address or on error. */
int check_ipaddr(
const char *address)
{
int res4, res6;
if ((res4 = check_ip4addr(address)) == 0) {
return 0;
}
if ((res6 = check_ip6addr(address)) == 0) {
return 0;
}
return 1;
}
#if HAVE_GETGROUPLIST || (defined(HAVE_SETGRENT) && defined(HAVE_GETGRENT) && defined(HAVE_ENDGRENT)) #if HAVE_GETGROUPLIST || (defined(HAVE_SETGRENT) && defined(HAVE_GETGRENT) && defined(HAVE_ENDGRENT))
/* fills the list with the supplementary group ids of user. /* fills the list with the supplementary group ids of user.
caller passes size of list in ngroups, function returns number of groups in caller passes size of list in ngroups, function returns number of groups in

View file

@ -80,6 +80,9 @@ extern int sockaddr_vm_parse(struct sockaddr_vm *sa, const char *cid_str,
extern const char *inet_ntop(int pf, const void *binaddr, extern const char *inet_ntop(int pf, const void *binaddr,
char *addrtext, socklen_t textlen); char *addrtext, socklen_t textlen);
#endif #endif
extern int check_ip4addr(const char *address);
extern int check_ip6addr(const char *address);
extern int check_ipaddr(const char *address);
#if defined(HAVE_SETGRENT) && defined(HAVE_GETGRENT) && defined(HAVE_ENDGRENT) #if defined(HAVE_SETGRENT) && defined(HAVE_GETGRENT) && defined(HAVE_ENDGRENT)
extern int getusergroups(const char *user, gid_t *list, int *ngroups); extern int getusergroups(const char *user, gid_t *list, int *ngroups);

View file

@ -270,7 +270,11 @@ static int
} }
#if defined(HAVE_SSL_set_tlsext_host_name) || defined(SSL_set_tlsext_host_name) #if defined(HAVE_SSL_set_tlsext_host_name) || defined(SSL_set_tlsext_host_name)
if (opt_snihost == NULL) { if (opt_snihost != NULL) {
if (check_ipaddr(opt_snihost) == 0) {
Warn1("specified SNI host \"%s\" is an IP address", opt_snihost);
}
} else if (check_ipaddr(opt_commonname) != 0) {
opt_snihost = strdup(opt_commonname); opt_snihost = strdup(opt_commonname);
if (opt_snihost == NULL) { if (opt_snihost == NULL) {
Error1("strdup("F_Zu"): out of memory", strlen(opt_commonname)+1); Error1("strdup("F_Zu"): out of memory", strlen(opt_commonname)+1);
@ -444,6 +448,7 @@ int _xioopen_openssl_connect(struct single *xfd,
#if defined(HAVE_SSL_set_tlsext_host_name) || defined(SSL_set_tlsext_host_name) #if defined(HAVE_SSL_set_tlsext_host_name) || defined(SSL_set_tlsext_host_name)
if (!no_sni) { if (!no_sni) {
/*Warn1("_xioopen_openssl_connect(): calling SSL_set_tlsext_host_name(snihost=\"%s\")", snihost?snihost:"NULL");*/
if (!SSL_set_tlsext_host_name(ssl, snihost)) { if (!SSL_set_tlsext_host_name(ssl, snihost)) {
Error1("Failed to set SNI host \"%s\"", snihost); Error1("Failed to set SNI host \"%s\"", snihost);
sycSSL_free(xfd->para.openssl.ssl); sycSSL_free(xfd->para.openssl.ssl);