|
|
|
|
@ -65,28 +65,30 @@ static int anon_credentials = 0; |
|
|
|
|
#define DEFAULT_GENERAL_RELAY_SERVERS_NUMBER (1) |
|
|
|
|
|
|
|
|
|
turn_params_t turn_params = { |
|
|
|
|
|
|
|
|
|
NULL, NULL, |
|
|
|
|
|
|
|
|
|
#if defined(SSL_TXT_TLSV1_1) |
|
|
|
|
#if TLSv1_1_SUPPORTED |
|
|
|
|
NULL, |
|
|
|
|
#if defined(SSL_TXT_TLSV1_2) |
|
|
|
|
#if TLSv1_2_SUPPORTED |
|
|
|
|
NULL, |
|
|
|
|
#endif |
|
|
|
|
#endif |
|
|
|
|
|
|
|
|
|
#if DTLS_SUPPORTED |
|
|
|
|
NULL, |
|
|
|
|
#endif |
|
|
|
|
#if DTLSv1_2_SUPPORTED |
|
|
|
|
NULL, |
|
|
|
|
#endif |
|
|
|
|
|
|
|
|
|
DH_1066, "", DEFAULT_EC_CURVE_NAME, "", |
|
|
|
|
DH_1066, "", "", "", |
|
|
|
|
"turn_server_cert.pem","turn_server_pkey.pem", "", "", |
|
|
|
|
0,0,0,0,0, |
|
|
|
|
#if defined(TURN_NO_TLS) |
|
|
|
|
#if !TLS_SUPPORTED |
|
|
|
|
1, |
|
|
|
|
#else |
|
|
|
|
0, |
|
|
|
|
#endif |
|
|
|
|
|
|
|
|
|
#if defined(TURN_NO_DTLS) |
|
|
|
|
#if !DTLS_SUPPORTED |
|
|
|
|
1, |
|
|
|
|
#else |
|
|
|
|
0, |
|
|
|
|
@ -507,17 +509,20 @@ static char Usage[] = "Usage: turnserver [options]\n" |
|
|
|
|
" --CA-file <filename> CA file in OpenSSL format.\n" |
|
|
|
|
" Forces TURN server to verify the client SSL certificates.\n" |
|
|
|
|
" By default, no CA is set and no client certificate check is performed.\n" |
|
|
|
|
" --ec-curve-name <curve-name> Curve name for EC ciphers, if supported by OpenSSL library\n" |
|
|
|
|
" (TLS and DTLS). The default value is prime256v1.\n" |
|
|
|
|
" --ec-curve-name <curve-name> Curve name for EC ciphers, if supported by OpenSSL\n" |
|
|
|
|
" library (TLS and DTLS). The default value is prime256v1,\n" |
|
|
|
|
" if pre-OpenSSL 1.0.2 is used. With OpenSSL 1.0.2+,\n" |
|
|
|
|
" an optimal curve will be automatically calculated, if not defined\n" |
|
|
|
|
" by this option.\n" |
|
|
|
|
" --dh566 Use 566 bits predefined DH TLS key. Default size of the predefined key is 1066.\n" |
|
|
|
|
" --dh2066 Use 2066 bits predefined DH TLS key. Default size of the predefined key is 1066.\n" |
|
|
|
|
" --dh-file <dh-file-name> Use custom DH TLS key, stored in PEM format in the file.\n" |
|
|
|
|
" Flags --dh566 and --dh2066 are ignored when the DH key is taken from a file.\n" |
|
|
|
|
" --no-sslv2 Do not allow SSLv2 protocol.\n" |
|
|
|
|
" --no-sslv3 Do not allow SSLv3 protocol.\n" |
|
|
|
|
" --no-tlsv1 Do not allow TLSv1 protocol.\n" |
|
|
|
|
" --no-tlsv1 Do not allow TLSv1/DTLSv1 protocol.\n" |
|
|
|
|
" --no-tlsv1_1 Do not allow TLSv1.1 protocol.\n" |
|
|
|
|
" --no-tlsv1_2 Do not allow TLSv1.2 protocol.\n" |
|
|
|
|
" --no-tlsv1_2 Do not allow TLSv1.2/DTLSv1.2 protocol.\n" |
|
|
|
|
" --no-udp Do not start UDP client listeners.\n" |
|
|
|
|
" --no-tcp Do not start TCP client listeners.\n" |
|
|
|
|
" --no-tls Do not start TLS client listeners.\n" |
|
|
|
|
@ -1219,14 +1224,14 @@ static void set_option(int c, char *value) |
|
|
|
|
turn_params.no_tcp_relay = get_bool_value(value); |
|
|
|
|
break; |
|
|
|
|
case NO_TLS_OPT: |
|
|
|
|
#if defined(TURN_NO_TLS) |
|
|
|
|
#if !TLS_SUPPORTED |
|
|
|
|
turn_params.no_tls = 1; |
|
|
|
|
#else |
|
|
|
|
turn_params.no_tls = get_bool_value(value); |
|
|
|
|
#endif |
|
|
|
|
break; |
|
|
|
|
case NO_DTLS_OPT: |
|
|
|
|
#if !defined(TURN_NO_DTLS) |
|
|
|
|
#if DTLS_SUPPORTED |
|
|
|
|
turn_params.no_dtls = get_bool_value(value); |
|
|
|
|
#else |
|
|
|
|
turn_params.no_dtls = 1; |
|
|
|
|
@ -1610,13 +1615,13 @@ static void print_features(unsigned long mfn) |
|
|
|
|
|
|
|
|
|
TURN_LOG_FUNC(TURN_LOG_LEVEL_INFO, "\n\n==== Show him the instruments, Practical Frost: ====\n\n"); |
|
|
|
|
|
|
|
|
|
#if defined(TURN_NO_TLS) |
|
|
|
|
#if !TLS_SUPPORTED |
|
|
|
|
TURN_LOG_FUNC(TURN_LOG_LEVEL_INFO, "TLS is not supported\n"); |
|
|
|
|
#else |
|
|
|
|
TURN_LOG_FUNC(TURN_LOG_LEVEL_INFO, "TLS supported\n"); |
|
|
|
|
#endif |
|
|
|
|
|
|
|
|
|
#if defined(TURN_NO_DTLS) |
|
|
|
|
#if !DTLS_SUPPORTED |
|
|
|
|
TURN_LOG_FUNC(TURN_LOG_LEVEL_INFO, "DTLS is not supported\n"); |
|
|
|
|
#else |
|
|
|
|
TURN_LOG_FUNC(TURN_LOG_LEVEL_INFO, "DTLS supported\n"); |
|
|
|
|
@ -1658,17 +1663,7 @@ static void print_features(unsigned long mfn) |
|
|
|
|
TURN_LOG_FUNC(TURN_LOG_LEVEL_INFO, "MongoDB is not supported\n"); |
|
|
|
|
#endif |
|
|
|
|
|
|
|
|
|
#if defined(OPENSSL_THREADS) |
|
|
|
|
//TURN_LOG_FUNC(TURN_LOG_LEVEL_INFO, "OpenSSL multithreading supported\n");
|
|
|
|
|
#else |
|
|
|
|
TURN_LOG_FUNC(TURN_LOG_LEVEL_WARNING, "OpenSSL multithreading is not supported (?!)\n"); |
|
|
|
|
#endif |
|
|
|
|
|
|
|
|
|
#if OPENSSL_VERSION_NUMBER >= 0x10000000L |
|
|
|
|
TURN_LOG_FUNC(TURN_LOG_LEVEL_INFO, "OpenSSL compile-time version 0x%llx: fresh enough\n",(unsigned long long)OPENSSL_VERSION_NUMBER); |
|
|
|
|
#else |
|
|
|
|
TURN_LOG_FUNC(TURN_LOG_LEVEL_INFO, "OpenSSL compile-time version 0x%llx version: antique\n",(unsigned long long)OPENSSL_VERSION_NUMBER); |
|
|
|
|
#endif |
|
|
|
|
TURN_LOG_FUNC(TURN_LOG_LEVEL_INFO, "OpenSSL compile-time version: %s\n",OPENSSL_VERSION_TEXT); |
|
|
|
|
|
|
|
|
|
TURN_LOG_FUNC(TURN_LOG_LEVEL_INFO, "Default Net Engine version: %d (%s)\n\n=====================================================\n\n", (int)turn_params.net_engine_version, turn_params.net_engine_version_txt[(int)turn_params.net_engine_version]); |
|
|
|
|
|
|
|
|
|
@ -1796,11 +1791,11 @@ int main(int argc, char **argv) |
|
|
|
|
|
|
|
|
|
optind = 0; |
|
|
|
|
|
|
|
|
|
#if defined(TURN_NO_TLS) |
|
|
|
|
#if !TLS_SUPPORTED |
|
|
|
|
turn_params.no_tls = 1; |
|
|
|
|
#endif |
|
|
|
|
|
|
|
|
|
#if defined(TURN_NO_DTLS) |
|
|
|
|
#if !DTLS_SUPPORTED |
|
|
|
|
turn_params.no_dtls = 1; |
|
|
|
|
#endif |
|
|
|
|
|
|
|
|
|
@ -2339,8 +2334,59 @@ static int pem_password_func(char *buf, int size, int rwflag, void *password) |
|
|
|
|
return (strlen(buf)); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
#if ALPN_SUPPORTED |
|
|
|
|
|
|
|
|
|
static int ServerALPNCallback(SSL *s, |
|
|
|
|
const unsigned char **out, |
|
|
|
|
unsigned char *outlen, |
|
|
|
|
const unsigned char *in, |
|
|
|
|
unsigned int inlen, |
|
|
|
|
void *arg) { |
|
|
|
|
|
|
|
|
|
UNUSED_ARG(s); |
|
|
|
|
UNUSED_ARG(arg); |
|
|
|
|
|
|
|
|
|
unsigned char sa_len = (unsigned char)strlen(STUN_ALPN); |
|
|
|
|
unsigned char ta_len = (unsigned char)strlen(TURN_ALPN); |
|
|
|
|
unsigned char ha_len = (unsigned char)strlen(HTTP_ALPN); |
|
|
|
|
|
|
|
|
|
int found_http = 0; |
|
|
|
|
|
|
|
|
|
const unsigned char *ptr = in; |
|
|
|
|
while(ptr < (in+inlen)) { |
|
|
|
|
unsigned char current_len = *ptr; |
|
|
|
|
if(ptr+1+current_len > in+inlen) |
|
|
|
|
break; |
|
|
|
|
if((!turn_params.no_stun) && (current_len == sa_len) && (memcmp(ptr+1,STUN_ALPN,sa_len)==0)) { |
|
|
|
|
*out = ptr+1; |
|
|
|
|
*outlen = sa_len; |
|
|
|
|
return SSL_TLSEXT_ERR_OK; |
|
|
|
|
} |
|
|
|
|
if((!turn_params.stun_only) && (current_len == ta_len) && (memcmp(ptr+1,TURN_ALPN,ta_len)==0)) { |
|
|
|
|
*out = ptr+1; |
|
|
|
|
*outlen = ta_len; |
|
|
|
|
return SSL_TLSEXT_ERR_OK; |
|
|
|
|
} |
|
|
|
|
if((current_len == ha_len) && (memcmp(ptr+1,HTTP_ALPN,ha_len)==0)) { |
|
|
|
|
found_http = 1; |
|
|
|
|
} |
|
|
|
|
ptr += 1 + current_len; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
if(found_http) |
|
|
|
|
return SSL_TLSEXT_ERR_NOACK; |
|
|
|
|
|
|
|
|
|
return SSL_TLSEXT_ERR_NOACK; //???
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
#endif |
|
|
|
|
|
|
|
|
|
static void set_ctx(SSL_CTX* ctx, const char *protocol) |
|
|
|
|
{ |
|
|
|
|
#if ALPN_SUPPORTED |
|
|
|
|
SSL_CTX_set_alpn_select_cb(ctx, ServerALPNCallback, NULL); |
|
|
|
|
#endif |
|
|
|
|
|
|
|
|
|
SSL_CTX_set_default_passwd_cb_userdata(ctx, turn_params.tls_password); |
|
|
|
|
|
|
|
|
|
SSL_CTX_set_default_passwd_cb(ctx, pem_password_func); |
|
|
|
|
@ -2391,23 +2437,47 @@ static void set_ctx(SSL_CTX* ctx, const char *protocol) |
|
|
|
|
|
|
|
|
|
#if !defined(OPENSSL_NO_EC) && defined(OPENSSL_EC_NAMED_CURVE) |
|
|
|
|
{ //Elliptic curve algorithms:
|
|
|
|
|
int nid = NID_X9_62_prime256v1; |
|
|
|
|
int nid = 0; |
|
|
|
|
int set_auto_curve = 0; |
|
|
|
|
|
|
|
|
|
if (turn_params.ec_curve_name[0]) { |
|
|
|
|
nid = OBJ_sn2nid(turn_params.ec_curve_name); |
|
|
|
|
if (nid == 0) { |
|
|
|
|
TURN_LOG_FUNC(TURN_LOG_LEVEL_ERROR,"unknown curve name (%s), using NID_X9_62_prime256v1\n",turn_params.ec_curve_name); |
|
|
|
|
nid = NID_X9_62_prime256v1; |
|
|
|
|
} |
|
|
|
|
const char* curve_name = turn_params.ec_curve_name; |
|
|
|
|
|
|
|
|
|
if (!(curve_name[0])) { |
|
|
|
|
#if !SSL_SESSION_ECDH_AUTO_SUPPORTED |
|
|
|
|
curve_name = DEFAULT_EC_CURVE_NAME; |
|
|
|
|
#endif |
|
|
|
|
set_auto_curve = 1; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
EC_KEY *ecdh = EC_KEY_new_by_curve_name(nid); |
|
|
|
|
if (!ecdh) { |
|
|
|
|
TURN_LOG_FUNC(TURN_LOG_LEVEL_ERROR, |
|
|
|
|
if(curve_name[0]) { |
|
|
|
|
{ |
|
|
|
|
nid = OBJ_sn2nid(curve_name); |
|
|
|
|
if (nid == 0) { |
|
|
|
|
TURN_LOG_FUNC(TURN_LOG_LEVEL_ERROR,"unknown curve name: %s\n",curve_name); |
|
|
|
|
curve_name = DEFAULT_EC_CURVE_NAME; |
|
|
|
|
nid = OBJ_sn2nid(curve_name); |
|
|
|
|
set_auto_curve = 1; |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
{ |
|
|
|
|
EC_KEY *ecdh = EC_KEY_new_by_curve_name(nid); |
|
|
|
|
if (!ecdh) { |
|
|
|
|
TURN_LOG_FUNC(TURN_LOG_LEVEL_ERROR, |
|
|
|
|
"%s: ERROR: allocate EC suite\n",__FUNCTION__); |
|
|
|
|
} else { |
|
|
|
|
SSL_CTX_set_tmp_ecdh(ctx, ecdh); |
|
|
|
|
EC_KEY_free(ecdh); |
|
|
|
|
set_auto_curve = 1; |
|
|
|
|
} else { |
|
|
|
|
SSL_CTX_set_tmp_ecdh(ctx, ecdh); |
|
|
|
|
EC_KEY_free(ecdh); |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
if(set_auto_curve) { |
|
|
|
|
#if SSL_SESSION_ECDH_AUTO_SUPPORTED |
|
|
|
|
SSL_CTX_set_ecdh_auto(ctx,1); |
|
|
|
|
#endif |
|
|
|
|
set_auto_curve = 0; |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
#endif |
|
|
|
|
@ -2437,6 +2507,14 @@ static void set_ctx(SSL_CTX* ctx, const char *protocol) |
|
|
|
|
dh = get_dh1066(); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
|
if(!dh) { |
|
|
|
|
dh = DH_new(); |
|
|
|
|
DH_generate_parameters_ex(dh, 32, DH_GENERATOR_2, 0); |
|
|
|
|
DH_generate_key(dh); |
|
|
|
|
} |
|
|
|
|
*/ |
|
|
|
|
|
|
|
|
|
if(!dh) { |
|
|
|
|
TURN_LOG_FUNC(TURN_LOG_LEVEL_ERROR, "%s: ERROR: cannot allocate DH suite\n",__FUNCTION__); |
|
|
|
|
} else { |
|
|
|
|
@ -2464,11 +2542,22 @@ static void set_ctx(SSL_CTX* ctx, const char *protocol) |
|
|
|
|
if(turn_params.no_tlsv1_1) |
|
|
|
|
op |= SSL_OP_NO_TLSv1_1; |
|
|
|
|
#endif |
|
|
|
|
|
|
|
|
|
#if defined(SSL_OP_NO_TLSv1_2) |
|
|
|
|
if(turn_params.no_tlsv1_2) |
|
|
|
|
op |= SSL_OP_NO_TLSv1_2; |
|
|
|
|
#endif |
|
|
|
|
|
|
|
|
|
#if defined(SSL_OP_NO_DTLSv1) && DTLS_SUPPORTED |
|
|
|
|
if(turn_params.no_tlsv1) |
|
|
|
|
op |= SSL_OP_NO_DTLSv1; |
|
|
|
|
#endif |
|
|
|
|
|
|
|
|
|
#if defined(SSL_OP_NO_DTLSv1_2) && DTLSv1_2_SUPPORTED |
|
|
|
|
if(turn_params.no_tlsv1_2) |
|
|
|
|
op |= SSL_OP_NO_DTLSv1_2; |
|
|
|
|
#endif |
|
|
|
|
|
|
|
|
|
#if defined(SSL_OP_CIPHER_SERVER_PREFERENCE) |
|
|
|
|
op |= SSL_OP_CIPHER_SERVER_PREFERENCE; |
|
|
|
|
#endif |
|
|
|
|
@ -2491,7 +2580,7 @@ static void openssl_setup(void) |
|
|
|
|
SSL_load_error_strings(); |
|
|
|
|
OpenSSL_add_ssl_algorithms(); |
|
|
|
|
|
|
|
|
|
#if defined(TURN_NO_TLS) |
|
|
|
|
#if !TLS_SUPPORTED |
|
|
|
|
if(!turn_params.no_tls) { |
|
|
|
|
TURN_LOG_FUNC(TURN_LOG_LEVEL_ERROR, "WARNING: TLS is not supported\n"); |
|
|
|
|
turn_params.no_tls = 1; |
|
|
|
|
@ -2521,12 +2610,12 @@ static void openssl_setup(void) |
|
|
|
|
turn_params.tls_ctx_v1_0 = SSL_CTX_new(TLSv1_server_method()); |
|
|
|
|
set_ctx(turn_params.tls_ctx_v1_0,"TLS1.0"); |
|
|
|
|
} |
|
|
|
|
#if defined(SSL_TXT_TLSV1_1) |
|
|
|
|
#if TLSv1_1_SUPPORTED |
|
|
|
|
if(!turn_params.no_tlsv1_1) { |
|
|
|
|
turn_params.tls_ctx_v1_1 = SSL_CTX_new(TLSv1_1_server_method()); |
|
|
|
|
set_ctx(turn_params.tls_ctx_v1_1,"TLS1.1"); |
|
|
|
|
} |
|
|
|
|
#if defined(SSL_TXT_TLSV1_2) |
|
|
|
|
#if TLSv1_2_SUPPORTED |
|
|
|
|
if(!turn_params.no_tlsv1_2) { |
|
|
|
|
turn_params.tls_ctx_v1_2 = SSL_CTX_new(TLSv1_2_server_method()); |
|
|
|
|
set_ctx(turn_params.tls_ctx_v1_2,"TLS1.2"); |
|
|
|
|
@ -2537,7 +2626,7 @@ static void openssl_setup(void) |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
if(!turn_params.no_dtls) { |
|
|
|
|
#if defined(TURN_NO_DTLS) |
|
|
|
|
#if !DTLS_SUPPORTED |
|
|
|
|
TURN_LOG_FUNC(TURN_LOG_LEVEL_ERROR, "ERROR: DTLS is not supported.\n"); |
|
|
|
|
#else |
|
|
|
|
if(OPENSSL_VERSION_NUMBER < 0x10000000L) { |
|
|
|
|
@ -2546,7 +2635,15 @@ static void openssl_setup(void) |
|
|
|
|
turn_params.dtls_ctx = SSL_CTX_new(DTLSv1_server_method()); |
|
|
|
|
set_ctx(turn_params.dtls_ctx,"DTLS"); |
|
|
|
|
SSL_CTX_set_read_ahead(turn_params.dtls_ctx, 1); |
|
|
|
|
|
|
|
|
|
#if DTLSv1_2_SUPPORTED |
|
|
|
|
turn_params.dtls_ctx_v1_2 = SSL_CTX_new(DTLSv1_2_server_method()); |
|
|
|
|
set_ctx(turn_params.dtls_ctx_v1_2,"DTLS1,2"); |
|
|
|
|
SSL_CTX_set_read_ahead(turn_params.dtls_ctx_v1_2, 1); |
|
|
|
|
#endif |
|
|
|
|
|
|
|
|
|
TURN_LOG_FUNC(TURN_LOG_LEVEL_INFO, "DTLS cipher suite: %s\n",turn_params.cipher_list); |
|
|
|
|
|
|
|
|
|
#endif |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|