mirror of
https://repo.or.cz/socat.git
synced 2024-12-22 07:22:34 +00:00
New options openssl-maxfraglen, openssl-maxsendfrag
This commit is contained in:
parent
454a499401
commit
2db04378ae
10 changed files with 181 additions and 1 deletions
7
CHANGES
7
CHANGES
|
@ -25,6 +25,13 @@ Features:
|
|||
Test: PROXY_HTTPVERSION
|
||||
Feature inspired by Robin Palotai.
|
||||
|
||||
New options openssl-maxfraglen and openssl-maxsendfrag for
|
||||
functions/macros SSL_CTX_set_tlsext_max_fragment_length() and
|
||||
SSL_CTX_set_max_send_fragment().
|
||||
Thanks to James Tavares for his contribution.
|
||||
|
||||
Added Info log of resulting OpenSSL max fragment length.
|
||||
|
||||
Corrections:
|
||||
When a sub process (EXEC, SYSTEM) terminated with exit code other than
|
||||
0, its last sent data might have been lost depending on timing of read/
|
||||
|
|
|
@ -532,6 +532,12 @@
|
|||
/* Define if you have the OpenSSL SSL_set_tlsext_host_name define/function */
|
||||
#undef HAVE_SSL_set_tlsext_host_name
|
||||
|
||||
/* Define if you have the OpenSSL SSL_CTX_set_tlsext_max_fragment_length define/function */
|
||||
#undef HAVE_SSL_CTX_set_tlsext_max_fragment_length
|
||||
|
||||
/* Define if you have the OpenSSL SSL_CTX_set_max_send_fragment define/function */
|
||||
#undef HAVE_SSL_CTX_set_max_send_fragment
|
||||
|
||||
/* Define if you have the flock function */
|
||||
#undef HAVE_FLOCK
|
||||
|
||||
|
|
17
configure.ac
17
configure.ac
|
@ -1578,6 +1578,23 @@ AC_CHECK_FUNC(ASN1_STRING_get0_data, AC_DEFINE(HAVE_ASN1_STRING_get0_data), AC_C
|
|||
AC_CHECK_FUNC(RAND_status, AC_DEFINE(HAVE_RAND_status))
|
||||
AC_CHECK_FUNC(SSL_CTX_clear_mode, AC_DEFINE(HAVE_SSL_CTX_clear_mode))
|
||||
AC_CHECK_FUNC(SSL_set_tlsext_host_name, AC_DEFINE(HAVE_SSL_set_tlsext_host_name))
|
||||
AC_CHECK_FUNC(SSL_CTX_set_tlsext_max_fragment_length, AC_DEFINE(HAVE_SSL_CTX_set_tlsext_max_fragment_length))
|
||||
|
||||
AC_MSG_CHECKING(if SSL_CTX_set_max_send_fragment exists)
|
||||
AC_CACHE_VAL(ac_cv_have_SSL_CTX_set_max_send_fragment,
|
||||
[AC_TRY_COMPILE([#include <openssl/ssl.h>],[
|
||||
#ifndef SSL_CTX_set_max_send_fragment
|
||||
#error "SSL_CTX_set_max_send_fragment not found"
|
||||
#endif
|
||||
],
|
||||
[ac_cv_have_SSL_CTX_set_max_send_fragment=yes],
|
||||
[ac_cv_have_SSL_CTX_set_max_send_fragment=no])]
|
||||
)
|
||||
if test $ac_cv_have_SSL_CTX_set_max_send_fragment = yes; then
|
||||
AC_DEFINE(HAVE_SSL_CTX_set_max_send_fragment)
|
||||
fi
|
||||
AC_MSG_RESULT($ac_cv_have_SSL_CTX_set_max_send_fragment)
|
||||
|
||||
AC_CHECK_FUNC(SSL_library_init, AC_DEFINE(HAVE_SSL_library_init))
|
||||
AC_CHECK_FUNC(ERR_error_string, AC_DEFINE(HAVE_ERR_error_string))
|
||||
|
||||
|
|
|
@ -2896,6 +2896,15 @@ label(OPTION_OPENSSL_EGD)dit(bf(tt(egd=<filename>)))
|
|||
On some systems, openssl requires an explicit source of random data. Specify
|
||||
the socket name where an entropy gathering daemon like egd provides random
|
||||
data, e.g. /dev/egd-pool.
|
||||
label(OPTION_OPENSSL_MAXFRAGLEN)dit(bf(tt(maxfraglen=<int>, openssl-maxfraglen=<int>)))
|
||||
For client connections, make a Max Fragment Length Negotiation Request to the server to limit the
|
||||
maximum size fragment the server will send to us. Supported lengths are: 512, 1024, 2048, or
|
||||
4096. Note that this option is not applicable for link(OPENSSL-LISTEN)(ADDRESS_OPENSSL_LISTEN).
|
||||
label(OPTION_OPENSSL_MAXSENDFRAG)dit(bf(tt(maxsendfrag=<int>, openssl-maxsendfrag=<int>)))
|
||||
Limit the maximum size of the fragment we will send to the other side. Supported length range:
|
||||
512 - 16384. Note that under link(OPENSSL-LISTEN)(ADDRESS_OPENSSL_LISTEN), the maximum fragment
|
||||
size may be further limited by the client's Maximum Fragment Length Negotiation Request, if it
|
||||
makes one.
|
||||
label(OPTION_OPENSSL_PSEUDO)dit(bf(tt(pseudo)))
|
||||
On systems where openssl cannot find an entropy source and where no entropy
|
||||
gathering daemon can be utilized, this option activates a mechanism for
|
||||
|
|
20
sslcls.c
20
sslcls.c
|
@ -319,6 +319,26 @@ int sycSSL_CTX_set_tmp_dh(SSL_CTX *ctx, DH *dh) {
|
|||
return result;
|
||||
}
|
||||
|
||||
#if HAVE_SSL_CTX_set_tlsext_max_fragment_length || defined(SSL_CTX_set_tlsext_max_fragment_length)
|
||||
int sycSSL_CTX_set_tlsext_max_fragment_length(SSL_CTX *ctx, uint8_t mode) {
|
||||
int result;
|
||||
Debug2("SSL_CTX_set_tlsext_max_fragment_length(%p, %u)", ctx, mode);
|
||||
result = SSL_CTX_set_tlsext_max_fragment_length(ctx, mode);
|
||||
Debug1("SSL_CTX_set_tlsext_max_fragment_length() -> %d", result);
|
||||
return result;
|
||||
}
|
||||
#endif
|
||||
|
||||
#if HAVE_SSL_CTX_set_max_send_fragment || defined(SSL_CTX_set_max_send_fragment)
|
||||
int sycSSL_CTX_set_max_send_fragment(SSL_CTX *ctx, long msf) {
|
||||
int result;
|
||||
Debug2("SSL_CTX_set_max_send_fragment(%p, %ld)", ctx, msf);
|
||||
result = SSL_CTX_set_max_send_fragment(ctx, msf);
|
||||
Debug1("SSL_CTX_set_max_send_fragment() -> %d", result);
|
||||
return result;
|
||||
}
|
||||
#endif
|
||||
|
||||
int sycSSL_set_cipher_list(SSL *ssl, const char *str) {
|
||||
int result;
|
||||
Debug2("SSL_set_cipher_list(%p, \"%s\")", ssl, str);
|
||||
|
|
12
sslcls.h
12
sslcls.h
|
@ -44,6 +44,12 @@ void sycSSL_CTX_set_verify(SSL_CTX *ctx, int mode,
|
|||
int (*verify_callback)(int, X509_STORE_CTX *));
|
||||
int sycSSL_CTX_set_tmp_dh(SSL_CTX *ctx, DH *dh);
|
||||
int sycSSL_CTX_set_cipher_list(SSL_CTX *ctx, const char *str);
|
||||
#if HAVE_SSL_CTX_set_tlsext_max_fragment_length || defined(SSL_CTX_set_tlsext_max_fragment_length)
|
||||
int sycSSL_CTX_set_tlsext_max_fragment_length(SSL_CTX *ctx, uint8_t mode);
|
||||
#endif
|
||||
#if HAVE_SSL_CTX_set_max_send_fragment || defined(SSL_CTX_set_max_send_fragment)
|
||||
int sycSSL_CTX_set_max_send_fragment(SSL_CTX *ctx, long msf);
|
||||
#endif
|
||||
int sycSSL_set_cipher_list(SSL *ssl, const char *str);
|
||||
long sycSSL_get_verify_result(SSL *ssl);
|
||||
int sycSSL_set_fd(SSL *ssl, int fd);
|
||||
|
@ -108,6 +114,12 @@ const char *sycSSL_COMP_get_name(const COMP_METHOD *comp);
|
|||
#define sycSSL_CTX_set_verify(c,m,v) SSL_CTX_set_verify(c,m,v)
|
||||
#define sycSSL_CTX_set_tmp_dh(c,d) SSL_CTX_set_tmp_dh(c,d)
|
||||
#define sycSSL_CTX_set_cipher_list(c,s) SSL_CTX_set_cipher_list(c,s)
|
||||
#if HAVE_SSL_CTX_set_tlsext_max_fragment_length || defined(SSL_CTX_set_tlsext_max_fragment_length)
|
||||
#define sycSSL_CTX_set_tlsext_max_fragment_length(c,m) SSL_CTX_set_tlsext_max_fragment_length(c, m)
|
||||
#endif
|
||||
#if HAVE_SSL_CTX_set_max_send_fragment || defined(SSL_CTX_set_max_send_fragment)
|
||||
#define sycSSL_CTX_set_max_send_fragment(c,m) SSL_CTX_set_max_send_fragment(c, m)
|
||||
#endif
|
||||
#define sycSSL_set_cipher_list(s,t) SSL_set_cipher_list(s,t)
|
||||
#define sycSSL_get_verify_result(s) SSL_get_verify_result(s)
|
||||
#define sycSSL_set_fd(s,f) SSL_set_fd(s,f)
|
||||
|
|
|
@ -125,6 +125,12 @@ const struct optdesc opt_openssl_dhparam = { "openssl-dhparam", "dh",
|
|||
const struct optdesc opt_openssl_cafile = { "openssl-cafile", "cafile", OPT_OPENSSL_CAFILE, GROUP_OPENSSL, PH_SPEC, TYPE_FILENAME, OFUNC_SPEC };
|
||||
const struct optdesc opt_openssl_capath = { "openssl-capath", "capath", OPT_OPENSSL_CAPATH, GROUP_OPENSSL, PH_SPEC, TYPE_FILENAME, OFUNC_SPEC };
|
||||
const struct optdesc opt_openssl_egd = { "openssl-egd", "egd", OPT_OPENSSL_EGD, GROUP_OPENSSL, PH_SPEC, TYPE_FILENAME, OFUNC_SPEC };
|
||||
#if HAVE_SSL_CTX_set_tlsext_max_fragment_length || defined(SSL_CTX_set_tlsext_max_fragment_length)
|
||||
const struct optdesc opt_openssl_maxfraglen = { "openssl-maxfraglen", "maxfraglen", OPT_OPENSSL_MAXFRAGLEN, GROUP_OPENSSL, PH_SPEC, TYPE_INT, OFUNC_SPEC };
|
||||
#endif
|
||||
#if HAVE_SSL_CTX_set_max_send_fragment || defined(SSL_CTX_set_max_send_fragment)
|
||||
const struct optdesc opt_openssl_maxsendfrag = { "openssl-maxsendfrag", "maxsendfrag", OPT_OPENSSL_MAXSENDFRAG, GROUP_OPENSSL, PH_SPEC, TYPE_INT, OFUNC_SPEC };
|
||||
#endif
|
||||
const struct optdesc opt_openssl_pseudo = { "openssl-pseudo", "pseudo", OPT_OPENSSL_PSEUDO, GROUP_OPENSSL, PH_SPEC, TYPE_BOOL, OFUNC_SPEC };
|
||||
#if OPENSSL_VERSION_NUMBER >= 0x00908000L && !defined(OPENSSL_NO_COMP)
|
||||
const struct optdesc opt_openssl_compress = { "openssl-compress", "compress", OPT_OPENSSL_COMPRESS, GROUP_OPENSSL, PH_SPEC, TYPE_STRING, OFUNC_SPEC };
|
||||
|
@ -138,7 +144,6 @@ const struct optdesc opt_openssl_no_sni = { "openssl-no-sni", "nosni",
|
|||
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.
|
||||
* On forks, the FIPS mode must be reset by a disable, then enable since
|
||||
* FIPS tracks the process ID that initializes things.
|
||||
|
@ -166,6 +171,7 @@ int xio_reset_fips_mode(void) {
|
|||
|
||||
static void openssl_conn_loginfo(SSL *ssl) {
|
||||
const char *string;
|
||||
SSL_SESSION *session;
|
||||
|
||||
string = SSL_get_cipher_version(ssl);
|
||||
Notice1("SSL proto version used: %s", string);
|
||||
|
@ -187,6 +193,31 @@ static void openssl_conn_loginfo(SSL *ssl) {
|
|||
Notice1("SSL connection expansion \"%s\"",
|
||||
expansion?sycSSL_COMP_get_name(expansion):"none");
|
||||
}
|
||||
#endif
|
||||
session = SSL_get_session(ssl);
|
||||
if (session == NULL) {
|
||||
Warn1("SSL_get_session(%p) failed", ssl);
|
||||
return;
|
||||
}
|
||||
#if HAVE_SSL_CTX_set_tlsext_max_fragment_length || defined(SSL_CTX_set_tlsext_max_fragment_length)
|
||||
{
|
||||
uint8_t fragcod;
|
||||
int fraglen = -1;
|
||||
fragcod = SSL_SESSION_get_max_fragment_length(session);
|
||||
switch (fragcod) {
|
||||
case TLSEXT_max_fragment_length_DISABLED: fraglen = 0; break;
|
||||
case TLSEXT_max_fragment_length_512: fraglen = 512; break;
|
||||
case TLSEXT_max_fragment_length_1024: fraglen = 1024; break;
|
||||
case TLSEXT_max_fragment_length_2048: fraglen = 2048; break;
|
||||
case TLSEXT_max_fragment_length_4096: fraglen = 4096; break;
|
||||
default: Warn1("SSL_SESSION_get_max_fragment_length(): unknown code %u",
|
||||
fragcod);
|
||||
break;
|
||||
}
|
||||
if (fraglen > 0) {
|
||||
Info1("OpenSSL: max fragment length is %d", fraglen);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
|
@ -1405,6 +1436,60 @@ cont_out:
|
|||
NULL);
|
||||
}
|
||||
|
||||
#if HAVE_SSL_CTX_set_tlsext_max_fragment_length || defined(SSL_CTX_set_tlsext_max_fragment_length)
|
||||
{
|
||||
/* set client max fragment length negotiation (512, 1024, 2048, or 4096) */
|
||||
|
||||
int opt_maxfraglen = -1;
|
||||
|
||||
retropt_int(opts, OPT_OPENSSL_MAXFRAGLEN, &opt_maxfraglen);
|
||||
|
||||
if (!server) {
|
||||
/* on client connection, ask the server not to send us packets bigger than our inbound buffer */
|
||||
uint8_t mfl_code = TLSEXT_max_fragment_length_DISABLED;
|
||||
if (opt_maxfraglen == -1) {
|
||||
/* max frag length is not specified, leave DISABLED */
|
||||
} else if (opt_maxfraglen == 512) {
|
||||
mfl_code = TLSEXT_max_fragment_length_512;
|
||||
} else if (opt_maxfraglen == 1024) {
|
||||
mfl_code = TLSEXT_max_fragment_length_1024;
|
||||
} else if (opt_maxfraglen == 2048) {
|
||||
mfl_code = TLSEXT_max_fragment_length_2048;
|
||||
} else if (opt_maxfraglen == 4096) {
|
||||
mfl_code = TLSEXT_max_fragment_length_4096;
|
||||
} else {
|
||||
Error1("openssl: maxfraglen %d is not one of 512, 1024, 2048, or 4096", opt_maxfraglen);
|
||||
return STAT_NORETRY;
|
||||
}
|
||||
|
||||
sycSSL_CTX_set_tlsext_max_fragment_length(ctx, mfl_code);
|
||||
} else {
|
||||
if (opt_maxfraglen != -1) {
|
||||
Error("openssl: maxfraglen option not applicable to a server");
|
||||
return STAT_NORETRY;
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
#if HAVE_SSL_CTX_set_max_send_fragment || defined(SSL_CTX_set_max_send_fragment)
|
||||
{
|
||||
/* limit the maximum size of sent packets */
|
||||
const int maxsendfrag_min = 512; /* per OpenSSL documentation */
|
||||
int opt_maxsendfrag = SSL3_RT_MAX_PLAIN_LENGTH;
|
||||
|
||||
retropt_int(opts, OPT_OPENSSL_MAXSENDFRAG, &opt_maxsendfrag);
|
||||
|
||||
if (opt_maxsendfrag < maxsendfrag_min || opt_maxsendfrag > SSL3_RT_MAX_PLAIN_LENGTH) {
|
||||
Error2("openssl: maxsendfrag %d out of range 512 - %d", maxsendfrag_min,
|
||||
SSL3_RT_MAX_PLAIN_LENGTH);
|
||||
return STAT_NORETRY;
|
||||
}
|
||||
|
||||
sycSSL_CTX_set_max_send_fragment(ctx, opt_maxsendfrag);
|
||||
}
|
||||
#endif
|
||||
|
||||
return STAT_OK;
|
||||
}
|
||||
|
||||
|
|
|
@ -26,6 +26,12 @@ extern const struct optdesc opt_openssl_dhparam;
|
|||
extern const struct optdesc opt_openssl_cafile;
|
||||
extern const struct optdesc opt_openssl_capath;
|
||||
extern const struct optdesc opt_openssl_egd;
|
||||
#if HAVE_SSL_CTX_set_tlsext_max_fragment_length || defined(SSL_CTX_set_tlsext_max_fragment_length)
|
||||
extern const struct optdesc opt_openssl_maxfraglen;
|
||||
#endif
|
||||
#if HAVE_SSL_CTX_set_max_send_fragment || defined(SSL_CTX_set_max_send_fragment)
|
||||
extern const struct optdesc opt_openssl_maxsendfrag;
|
||||
#endif
|
||||
extern const struct optdesc opt_openssl_pseudo;
|
||||
#if OPENSSL_VERSION_NUMBER >= 0x00908000L
|
||||
extern const struct optdesc opt_openssl_compress;
|
||||
|
|
12
xioopts.c
12
xioopts.c
|
@ -936,10 +936,16 @@ const struct optname optionnames[] = {
|
|||
IF_OPENSSL("max-version", &opt_openssl_max_proto_version)
|
||||
#endif
|
||||
IF_LISTEN ("maxchildren", &opt_max_children)
|
||||
#if HAVE_SSL_CTX_set_tlsext_max_fragment_length || defined(SSL_CTX_set_tlsext_max_fragment_length)
|
||||
IF_OPENSSL("maxfraglen", &opt_openssl_maxfraglen)
|
||||
#endif
|
||||
#ifdef TCP_MAXSEG
|
||||
IF_TCP ("maxseg", &opt_tcp_maxseg)
|
||||
IF_TCP ("maxseg-late", &opt_tcp_maxseg_late)
|
||||
#endif
|
||||
#if HAVE_SSL_CTX_set_max_send_fragment || defined(SSL_CTX_set_max_send_fragment)
|
||||
IF_OPENSSL("maxsendfrag", &opt_openssl_maxsendfrag)
|
||||
#endif
|
||||
#ifdef TCP_MD5SUM
|
||||
IF_TCP ("md5sig", &opt_tcp_md5sig)
|
||||
#endif
|
||||
|
@ -1190,6 +1196,12 @@ const struct optname optionnames[] = {
|
|||
#if HAVE_SSL_set_max_proto_version || defined(SSL_set_max_proto_version)
|
||||
IF_OPENSSL("openssl-max-proto-version", &opt_openssl_max_proto_version)
|
||||
#endif
|
||||
#if HAVE_SSL_CTX_set_tlsext_max_fragment_length || defined(SSL_CTX_set_tlsext_max_fragment_length)
|
||||
IF_OPENSSL("openssl-maxfraglen", &opt_openssl_maxfraglen)
|
||||
#endif
|
||||
#if HAVE_SSL_CTX_set_max_send_fragment || defined(SSL_CTX_set_max_send_fragment)
|
||||
IF_OPENSSL("openssl-maxsendfrag", &opt_openssl_maxsendfrag)
|
||||
#endif
|
||||
#if WITH_OPENSSL_METHOD
|
||||
IF_OPENSSL("openssl-method", &opt_openssl_method)
|
||||
#endif
|
||||
|
|
|
@ -506,6 +506,12 @@ enum e_optcode {
|
|||
OPT_OPENSSL_EGD,
|
||||
OPT_OPENSSL_FIPS,
|
||||
OPT_OPENSSL_KEY,
|
||||
#if HAVE_SSL_CTX_set_tlsext_max_fragment_length || defined(SSL_CTX_set_tlsext_max_fragment_length)
|
||||
OPT_OPENSSL_MAXFRAGLEN,
|
||||
#endif
|
||||
#if HAVE_SSL_CTX_set_max_send_fragment || defined(SSL_CTX_set_max_send_fragment)
|
||||
OPT_OPENSSL_MAXSENDFRAG,
|
||||
#endif
|
||||
OPT_OPENSSL_MAX_PROTO_VERSION,
|
||||
OPT_OPENSSL_METHOD,
|
||||
OPT_OPENSSL_MIN_PROTO_VERSION,
|
||||
|
|
Loading…
Reference in a new issue