mirror of
https://repo.or.cz/socat.git
synced 2025-07-07 13:26:33 +00:00
Added SNI support to OPENSSL-CONNECT, with options no-sni, snihost
This commit is contained in:
parent
d109e3131b
commit
aa2b9c00b2
9 changed files with 179 additions and 2 deletions
|
@ -131,6 +131,10 @@ const struct optdesc opt_openssl_compress = { "openssl-compress", "compress
|
|||
const struct optdesc opt_openssl_fips = { "openssl-fips", "fips", OPT_OPENSSL_FIPS, GROUP_OPENSSL, PH_SPEC, TYPE_BOOL, OFUNC_SPEC };
|
||||
#endif
|
||||
const struct optdesc opt_openssl_commonname = { "openssl-commonname", "cn", OPT_OPENSSL_COMMONNAME, GROUP_OPENSSL, PH_SPEC, TYPE_STRING, OFUNC_SPEC };
|
||||
#if defined(HAVE_SSL_set_tlsext_host_name) || defined(SSL_set_tlsext_host_name)
|
||||
const struct optdesc opt_openssl_no_sni = { "openssl-no-sni", "nosni", OPT_OPENSSL_NO_SNI, GROUP_OPENSSL, PH_SPEC, TYPE_BOOL, OFUNC_SPEC };
|
||||
const struct optdesc opt_openssl_snihost = { "openssl-snihost", "snihost", OPT_OPENSSL_SNIHOST, GROUP_OPENSSL, PH_SPEC, TYPE_STRING, OFUNC_SPEC };
|
||||
#endif
|
||||
|
||||
|
||||
/* If FIPS is compiled in, we need to track if the user asked for FIPS mode.
|
||||
|
@ -220,6 +224,8 @@ static int
|
|||
bool opt_ver = true; /* verify peer certificate */
|
||||
char *opt_cert = NULL; /* file name of client certificate */
|
||||
const char *opt_commonname = NULL; /* for checking peer certificate */
|
||||
bool opt_no_sni;
|
||||
const char *opt_snihost = NULL; /* for SNI host */
|
||||
int result;
|
||||
|
||||
if (!(xioflags & XIO_MAYCONVERT)) {
|
||||
|
@ -249,11 +255,27 @@ static int
|
|||
|
||||
retropt_string(opts, OPT_OPENSSL_CERTIFICATE, &opt_cert);
|
||||
retropt_string(opts, OPT_OPENSSL_COMMONNAME, (char **)&opt_commonname);
|
||||
#if defined(HAVE_SSL_set_tlsext_host_name) || defined(SSL_set_tlsext_host_name)
|
||||
retropt_bool(opts, OPT_OPENSSL_NO_SNI, &opt_no_sni);
|
||||
retropt_string(opts, OPT_OPENSSL_SNIHOST, (char **)&opt_snihost);
|
||||
#endif
|
||||
|
||||
if (opt_commonname == NULL) {
|
||||
opt_commonname = hostname;
|
||||
opt_commonname = strdup(hostname);
|
||||
if (opt_commonname == NULL) {
|
||||
Error1("strdup("F_Zu"): out of memory", strlen(hostname)+1);
|
||||
}
|
||||
}
|
||||
|
||||
#if defined(HAVE_SSL_set_tlsext_host_name) || defined(SSL_set_tlsext_host_name)
|
||||
if (opt_snihost == NULL) {
|
||||
opt_snihost = strdup(opt_commonname);
|
||||
if (opt_snihost == NULL) {
|
||||
Error1("strdup("F_Zu"): out of memory", strlen(opt_commonname)+1);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
result =
|
||||
_xioopen_openssl_prepare(opts, xfd, false, &opt_ver, opt_cert, &ctx, (bool *)&use_dtls);
|
||||
if (result != STAT_OK) return STAT_NORETRY;
|
||||
|
@ -319,7 +341,8 @@ static int
|
|||
return result;
|
||||
}
|
||||
|
||||
result = _xioopen_openssl_connect(xfd, opt_ver, opt_commonname, ctx, level);
|
||||
result = _xioopen_openssl_connect(xfd, opt_ver, opt_commonname,
|
||||
opt_no_sni, opt_snihost, ctx, level);
|
||||
switch (result) {
|
||||
case STAT_OK: break;
|
||||
#if WITH_RETRY
|
||||
|
@ -376,6 +399,9 @@ static int
|
|||
|
||||
openssl_conn_loginfo(xfd->para.openssl.ssl);
|
||||
|
||||
free((void *)opt_commonname);
|
||||
free((void *)opt_snihost);
|
||||
|
||||
/* fill in the fd structure */
|
||||
return STAT_OK;
|
||||
}
|
||||
|
@ -388,6 +414,8 @@ static int
|
|||
int _xioopen_openssl_connect(struct single *xfd,
|
||||
bool opt_ver,
|
||||
const char *opt_commonname,
|
||||
bool no_sni,
|
||||
const char *snihost,
|
||||
SSL_CTX *ctx,
|
||||
int level) {
|
||||
SSL *ssl;
|
||||
|
@ -412,6 +440,17 @@ int _xioopen_openssl_connect(struct single *xfd,
|
|||
return result;
|
||||
}
|
||||
|
||||
#if defined(HAVE_SSL_set_tlsext_host_name) || defined(SSL_set_tlsext_host_name)
|
||||
if (!no_sni) {
|
||||
if (!SSL_set_tlsext_host_name(ssl, snihost)) {
|
||||
Error1("Failed to set SNI host \"%s\"", snihost);
|
||||
sycSSL_free(xfd->para.openssl.ssl);
|
||||
xfd->para.openssl.ssl = NULL;
|
||||
return STAT_NORETRY;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
result = xioSSL_connect(xfd, opt_commonname, opt_ver, level);
|
||||
if (result != STAT_OK) {
|
||||
sycSSL_free(xfd->para.openssl.ssl);
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue