diff --git a/ChangeLog b/ChangeLog index 041d556..6dfb8b5 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,6 +1,7 @@ 12/09/2014 Oleg Moskalenko 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 Version 4.3.1.3 'Tolomei': diff --git a/README.turnserver b/README.turnserver index 31c2b5d..06fe32d 100644 --- a/README.turnserver +++ b/README.turnserver @@ -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: diff --git a/TODO b/TODO index 6bd108a..49ef28c 100644 --- a/TODO +++ b/TODO @@ -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. ================================================================== diff --git a/examples/etc/turnserver.conf b/examples/etc/turnserver.conf index 5d35de8..efd9622 100644 --- a/examples/etc/turnserver.conf +++ b/examples/etc/turnserver.conf @@ -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 diff --git a/man/man1/turnadmin.1 b/man/man1/turnadmin.1 index d460331..6b1d34f 100644 --- a/man/man1/turnadmin.1 +++ b/man/man1/turnadmin.1 @@ -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 diff --git a/man/man1/turnserver.1 b/man/man1/turnserver.1 index b12d631..5882842 100644 --- a/man/man1/turnserver.1 +++ b/man/man1/turnserver.1 @@ -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. diff --git a/man/man1/turnutils.1 b/man/man1/turnutils.1 index ecd87d7..61851d7 100644 --- a/man/man1/turnutils.1 +++ b/man/man1/turnutils.1 @@ -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 diff --git a/src/apps/relay/mainrelay.c b/src/apps/relay/mainrelay.c index df31650..bc4ff64 100644 --- a/src/apps/relay/mainrelay.c +++ b/src/apps/relay/mainrelay.c @@ -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 diff --git a/src/apps/uclient/startuclient.c b/src/apps/uclient/startuclient.c index 791d704..40dcd7f 100644 --- a/src/apps/uclient/startuclient.c +++ b/src/apps/uclient/startuclient.c @@ -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 { diff --git a/src/ns_turn_defs.h b/src/ns_turn_defs.h index 3a259ce..8ad2eae 100644 --- a/src/ns_turn_defs.h +++ b/src/ns_turn_defs.h @@ -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