ALPN support added

This commit is contained in:
mom040267 2014-12-10 09:01:15 +00:00
parent 786105a9b4
commit 06389df97c
10 changed files with 122 additions and 18 deletions

View File

@ -1,6 +1,7 @@
12/09/2014 Oleg Moskalenko <mom040267@gmail.com>
Version 4.3.2.1 'Tolomei':
- DTLS v1.2 supported (for OpenSSL 1.0.2+);
- DTLS v1.2 supported (when compiled with OpenSSL 1.0.2+ );
- STUN/TURN ALPN supported (when compiled with OpenSSL 1.0.2+ );
11/29/2014 Oleg Moskalenko <mom040267@gmail.com>
Version 4.3.1.3 'Tolomei':

View File

@ -195,11 +195,11 @@ Flags:
--no-sslv3 Do not allow SSLv3 protocol.
--no-tlsv1 Do not allow TLSv1 protocol.
--no-tlsv1 Do not allow TLSv1/DTLSv1 protocol.
--no-tlsv1_1 Do not allow TLSv1.1 protocol.
--no-tlsv1_2 Do not allow TLSv1.2 protocol.
--no-tlsv1_2 Do not allow TLSv1.2/DTLSv1.2 protocol.
--no-udp Do not start UDP client listeners.
@ -775,7 +775,18 @@ it will set the users for you (see the turnadmin manuals). If you are using SQLi
turnserver or turnadmin will initialize the empty database, for you, when started. The
TURN server installation process creates an empty initialized SQLite database in the default
location (/var/db/turndb or /usr/local/var/db/turndb or /var/lib/turn/turndb, depending on the system).
=================================
ALPN
The server supports ALPNs "stun.turn" and "stun.nat-discovery", when
compiled with OpenSSL 1.0.2 or newer. If the server receives a TLS/DTLS
ClientHello message that contains one or both of those ALPNs, then the
server chooses the first stun.* label and sends it back (in the ServerHello)
in the ALPN extention field. If no stun.* label is found, then the server
does not include the ALPN information into the ServerHello.
=================================
LIBRARIES
@ -786,7 +797,7 @@ The C++ wrapper for the messaging functionality is located in TurnMsgLib.h heade
An example of C++ code can be found in stunclient.c file.
=================================
DOCS
After installation, run the command:

4
TODO
View File

@ -57,9 +57,7 @@
1) For extra difficult NAT/FWs, consider implementing Websockets.
2) ALPN with TLS and DTLS (when OpenSSL 1.0.2 is available).
3) Redirect draft.
2) Redirect draft.
==================================================================

View File

@ -620,7 +620,7 @@
#
#ne=[1|2|3]
# Do not allow an SSL/TLS version of protocol
# Do not allow an SSL/TLS/DTLS version of protocol
#
#no-sslv2
#no-sslv3

View File

@ -1,5 +1,5 @@
.\" Text automatically generated by txt2man
.TH TURN 1 "06 December 2014" "" ""
.TH TURN 1 "10 December 2014" "" ""
.SH GENERAL INFORMATION
\fIturnadmin\fP is a TURN administration tool. This tool can be used to manage

View File

@ -1,5 +1,5 @@
.\" Text automatically generated by txt2man
.TH TURN 1 "06 December 2014" "" ""
.TH TURN 1 "10 December 2014" "" ""
.SH GENERAL INFORMATION
The \fBTURN Server\fP project contains the source code of a TURN server and TURN client
@ -291,7 +291,7 @@ Do not allow SSLv3 protocol.
.TP
.B
\fB\-\-no\-tlsv1\fP
Do not allow TLSv1 protocol.
Do not allow TLSv1/DTLSv1 protocol.
.TP
.B
\fB\-\-no\-tlsv1_1\fP
@ -299,7 +299,7 @@ Do not allow TLSv1.1 protocol.
.TP
.B
\fB\-\-no\-tlsv1_2\fP
Do not allow TLSv1.2 protocol.
Do not allow TLSv1.2/DTLSv1.2 protocol.
.TP
.B
\fB\-\-no\-udp\fP
@ -1032,6 +1032,16 @@ TURN server installation process creates an empty initialized SQLite database in
location (/var/db/turndb or /usr/local/var/db/turndb or /var/lib/turn/turndb, depending on the system).
.PP
=================================
.SH ALPN
The server supports ALPNs "stun.turn" and "stun.nat\-discovery", when
compiled with OpenSSL 1.0.2 or newer. If the server receives a TLS/DTLS
ClientHello message that contains one or both of those ALPNs, then the
server chooses the first stun.* label and sends it back (in the ServerHello)
in the ALPN extention field. If no stun.* label is found, then the server
does not include the ALPN information into the ServerHello.
.PP
=================================
.SH LIBRARIES
In the lib/ sub\-directory the build process will create TURN client messaging library.

View File

@ -1,5 +1,5 @@
.\" Text automatically generated by txt2man
.TH TURN 1 "06 December 2014" "" ""
.TH TURN 1 "10 December 2014" "" ""
.SH GENERAL INFORMATION
A set of turnutils_* programs provides some utility functionality to be used

View File

@ -515,9 +515,9 @@ static char Usage[] = "Usage: turnserver [options]\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"
@ -2339,8 +2339,59 @@ static int pem_password_func(char *buf, int size, int rwflag, void *password)
return (strlen(buf));
}
#if OPENSSL_VERSION_NUMBER >= OPENSSL_FIRST_ALPN_VERSION
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((current_len == sa_len) && (memcmp(ptr+1,STUN_ALPN,sa_len)==0)) {
*out = ptr+1;
*outlen = sa_len;
return SSL_TLSEXT_ERR_OK;
}
if((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 OPENSSL_VERSION_NUMBER >= OPENSSL_FIRST_ALPN_VERSION
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);
@ -2437,6 +2488,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 {
@ -2469,6 +2528,16 @@ static void set_ctx(SSL_CTX* ctx, const char *protocol)
op |= SSL_OP_NO_TLSv1_2;
#endif
#if defined(SSL_OP_NO_DTLSv1)
if(turn_params.no_tlsv1)
op |= SSL_OP_NO_DTLSv1;
#endif
#if defined(SSL_OP_NO_DTLSv1_2)
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

View File

@ -50,6 +50,11 @@ static uint64_t current_reservation_token = 0;
static int allocate_rtcp = 0;
static const int never_allocate_rtcp = 0;
#if OPENSSL_VERSION_NUMBER >= OPENSSL_FIRST_ALPN_VERSION
static const unsigned char kALPNProtos[] = "\x09stun.turn\x12stun.nat-discovery";
static const size_t kALPNProtosLen = sizeof(kALPNProtos) - 1;
#endif
/////////////////////////////////////////
int rare_event(void)
@ -86,6 +91,10 @@ static SSL* tls_connect(ioa_socket_raw fd, ioa_addr *remote_addr, int *try_again
ssl = SSL_NEW(root_tls_ctx[ctxtype]);
#if OPENSSL_VERSION_NUMBER >= OPENSSL_FIRST_ALPN_VERSION
SSL_set_alpn_protos(ssl, kALPNProtos, kALPNProtosLen);
#endif
if(use_tcp) {
SSL_set_fd(ssl, fd);
} else {

View File

@ -60,8 +60,6 @@
extern "C" {
#endif
///////////////////////////////////////////
/* NS types: */
#define s08bits char
@ -218,6 +216,14 @@ typedef u32bits turn_time_t;
#define DELETE_TURN_CHANNEL_KERNEL(handler)
#endif
/* ALPN */
#define OPENSSL_FIRST_ALPN_VERSION (0x10002003L)
#define STUN_ALPN "stun.nat-discovery"
#define TURN_ALPN "stun.turn"
#define HTTP_ALPN "http/1.1"
////////////////////////////////////////////////////////
#ifdef __cplusplus