From 5105dfafd36c2d06f7a4d52310a39155cb5dde6b Mon Sep 17 00:00:00 2001 From: Jens Elkner Date: Mon, 18 May 2020 07:21:56 +0200 Subject: [PATCH 01/55] support of --acme-redirect --- src/apps/relay/http_server.c | 77 ++++++++++++++++++++++++++++++++++++ src/apps/relay/mainrelay.c | 14 ++++++- src/apps/relay/mainrelay.h | 1 + src/apps/relay/netengine.c | 1 + src/server/ns_turn_ioalib.h | 1 + src/server/ns_turn_server.c | 17 +++++--- src/server/ns_turn_server.h | 4 ++ 7 files changed, 108 insertions(+), 7 deletions(-) diff --git a/src/apps/relay/http_server.c b/src/apps/relay/http_server.c index ff8e3992..ca70d77e 100644 --- a/src/apps/relay/http_server.c +++ b/src/apps/relay/http_server.c @@ -99,6 +99,83 @@ const char* get_http_date_header() return buffer_header; } +static int is_acme_req(char *req, size_t len) { + static const char *A = " - 0123456789 ABCDEFGHIJKLMNOPQRSTUVWXYZ _ abcdefghijklmnopqrstuvwxyz "; + int c, i, k; + + // Check first request line. Should be like: GET path HTTP/1.x + if (strncmp(req, "GET /.well-known/acme-challenge/", 32)) + return -1; + // Usually (for LE) the "method path" is 32 + 43 = 55 chars. But other + // implementations may choose longer pathes. We define PATHMAX = 127 chars + // to be prepared for "DoS" attacks (STUN msg size max. is ~ 64K). + len =- 21; // min size of trailing headers + if (len > 131) + len = 131; + for (i=32; i < (int) len; i++) { + // find the end of the path + if (req[i] != ' ') + continue; + // consider path < 10 chars invalid. Also we wanna see a "trailer". + if (i < 42 || strncmp(req + i, " HTTP/1.", 8)) + return -2; + // finally check for allowed chars + for (k=32; k < i; k++) { + c = req[k]; + if ((c > 127) || (A[c] == ' ')) + return -3; + } + // all checks passed: sufficient for us to answer with a redirect + return i; + } + return -4; // end of path not found +} + +int try_acme_redirect(char *req, size_t len, const char *url, + ioa_socket_handle s) +{ + static const char *HTML = "301 Moved Permanently

301 Moved Permanently

"; + char http_response[1024]; + int plen, rlen; + + if (url == NULL || url[0] == '\0' || req == NULL || s == 0 ) + return 1; + if (len < 64 || len > 512 || (plen = is_acme_req(req, len)) < 33) + return 2; + + req[plen] = '\0'; + snprintf(http_response, sizeof(http_response) - 1, + "HTTP/1.1 301 Moved Permanently\r\n" + "Content-Type: text/html\r\n" + "Content-Length: %ld\r\n" + "Connection: close\r\n" + "Location: %s%s\r\n" + "\r\n%s", strlen(HTML), url, req + 32, HTML); + + rlen = strlen(http_response); + + // Variant A: direkt write, no eventbuf stuff + if (write(s->fd, http_response, rlen) == -1) { + perror("Sending redirect failed"); + } else if (((turn_turnserver *)s->session->server)->verbose) { + TURN_LOG_FUNC(TURN_LOG_LEVEL_INFO, "ACME redirect to %s%s\n", + url, req + 32); + } + + req[plen] = ' '; + + // Variant B: via eventbuf does not send anything for whatever reason + /* + set_ioa_socket_app_type(s, HTTP_CLIENT_SOCKET); + ioa_network_buffer_handle nbh = ioa_network_buffer_allocate(s->e); + uint8_t *data = ioa_network_buffer_data(nbh); + bcopy(http_response, data, rlen); + ioa_network_buffer_set_size(nbh, rlen); + send_data_from_ioa_socket_nbh(s, NULL, nbh, TTL_IGNORE, TOS_IGNORE, NULL); + */ + + return 0; +} /////////////////////////////////////////////// static struct headers_list * post_parse(char *data, size_t data_len) diff --git a/src/apps/relay/mainrelay.c b/src/apps/relay/mainrelay.c index 2ac08fcf..56b4c8af 100644 --- a/src/apps/relay/mainrelay.c +++ b/src/apps/relay/mainrelay.c @@ -109,7 +109,7 @@ NULL, PTHREAD_MUTEX_INITIALIZER, //////////////// Common params //////////////////// TURN_VERBOSE_NONE,0,0,0,0, -"/var/run/turnserver.pid", +"/var/run/turnserver.pid","", DEFAULT_STUN_PORT,DEFAULT_STUN_TLS_PORT,0,0,0,1, 0,0,0,0,0, "", @@ -615,6 +615,8 @@ static char Usage[] = "Usage: turnserver [options]\n" " --pidfile <\"pid-file-name\"> File name to store the pid of the process.\n" " Default is /var/run/turnserver.pid (if superuser account is used) or\n" " /var/tmp/turnserver.pid .\n" +" --acme-redirect <\"URL\"> Redirect HTTP GET requests matching '^/.well-known/acme-challenge/(.*)' to '<\"URL\">$1'\n" +" Default is '', i.e. no special handling for such requests.\n" " --secure-stun Require authentication of the STUN Binding request.\n" " By default, the clients are allowed anonymous access to the STUN Binding functionality.\n" " --proc-user User name to run the turnserver process.\n" @@ -793,7 +795,8 @@ enum EXTRA_OPTS { OAUTH_OPT, NO_SOFTWARE_ATTRIBUTE_OPT, NO_HTTP_OPT, - SECRET_KEY_OPT + SECRET_KEY_OPT, + ACME_REDIRECT_OPT }; struct myoption { @@ -922,6 +925,7 @@ static const struct myoption long_options[] = { { "no-tlsv1_2", optional_argument, NULL, NO_TLSV1_2_OPT }, { "secret-key-file", required_argument, NULL, SECRET_KEY_OPT }, { "keep-address-family", optional_argument, NULL, 'K' }, + { "acme-redirect", required_argument, NULL, ACME_REDIRECT_OPT }, { NULL, no_argument, NULL, 0 } }; @@ -1560,6 +1564,9 @@ static void set_option(int c, char *value) case PIDFILE_OPT: STRCPY(turn_params.pidfile,value); break; + case ACME_REDIRECT_OPT: + STRCPY(turn_params.acme_redirect,value); + break; case 'C': if(value && *value) { turn_params.rest_api_separator=*value; @@ -2238,6 +2245,9 @@ int main(int argc, char **argv) TURN_LOG_FUNC(TURN_LOG_LEVEL_INFO, "Domain name: %s\n",turn_params.domain); TURN_LOG_FUNC(TURN_LOG_LEVEL_INFO, "Default realm: %s\n",get_realm(NULL)->options.name); + if(turn_params.acme_redirect[0]) { + TURN_LOG_FUNC(TURN_LOG_LEVEL_INFO, "ACME redirect URL: %s\n",turn_params.acme_redirect); + } if(turn_params.oauth && turn_params.oauth_server_name[0]) { TURN_LOG_FUNC(TURN_LOG_LEVEL_INFO, "oAuth server name: %s\n",turn_params.oauth_server_name); } diff --git a/src/apps/relay/mainrelay.h b/src/apps/relay/mainrelay.h index 4b584f74..75ba63b8 100644 --- a/src/apps/relay/mainrelay.h +++ b/src/apps/relay/mainrelay.h @@ -219,6 +219,7 @@ typedef struct _turn_params_ { int do_not_use_config_file; char pidfile[1025]; + char acme_redirect[1025]; //////////////// Listener server ///////////////// diff --git a/src/apps/relay/netengine.c b/src/apps/relay/netengine.c index ca88056e..20f558cd 100644 --- a/src/apps/relay/netengine.c +++ b/src/apps/relay/netengine.c @@ -1667,6 +1667,7 @@ static void setup_relay_server(struct relay_server *rs, ioa_engine_handle e, int allocate_bps, turn_params.oauth, turn_params.oauth_server_name, + turn_params.acme_redirect, turn_params.keep_address_family); if(to_set_rfc5780) { diff --git a/src/server/ns_turn_ioalib.h b/src/server/ns_turn_ioalib.h index 6737711d..3a25b03e 100644 --- a/src/server/ns_turn_ioalib.h +++ b/src/server/ns_turn_ioalib.h @@ -285,6 +285,7 @@ int get_default_protocol_port(const char* scheme, size_t slen); ///////////// HTTP //////////////////// void handle_http_echo(ioa_socket_handle s); +int try_acme_redirect(char *req, size_t len, const char *url, ioa_socket_handle s); /////////////////////////////////////// diff --git a/src/server/ns_turn_server.c b/src/server/ns_turn_server.c index 38a15134..3d3eaa74 100644 --- a/src/server/ns_turn_server.c +++ b/src/server/ns_turn_server.c @@ -4624,14 +4624,19 @@ static int read_client_connection(turn_turnserver *server, } else { SOCKET_TYPE st = get_ioa_socket_type(ss->client_socket); if(is_stream_socket(st)) { - if(is_http((char*)ioa_network_buffer_data(in_buffer->nbh), ioa_network_buffer_get_size(in_buffer->nbh))) { + char *str = (char*)ioa_network_buffer_data(in_buffer->nbh); + size_t l = ioa_network_buffer_get_size(in_buffer->nbh); + if(is_http(str, l)) { const char *proto = "HTTP"; - ioa_network_buffer_data(in_buffer->nbh)[ioa_network_buffer_get_size(in_buffer->nbh)] = 0; - if (*server->web_admin_listen_on_workers) { + str[l] = 0; + if ((st == TCP_SOCKET) && (try_acme_redirect(str, l, server->acme_redirect, ss->client_socket) == 0)) { + ss->to_be_closed = 1; + return 0; + } else if (*server->web_admin_listen_on_workers) { if(st==TLS_SOCKET) { proto = "HTTPS"; set_ioa_socket_app_type(ss->client_socket,HTTPS_CLIENT_SOCKET); - TURN_LOG_FUNC(TURN_LOG_LEVEL_INFO, "%s: %s (%s %s) request: %s\n", __FUNCTION__, proto, get_ioa_socket_cipher(ss->client_socket), get_ioa_socket_ssl_method(ss->client_socket), (char*)ioa_network_buffer_data(in_buffer->nbh)); + TURN_LOG_FUNC(TURN_LOG_LEVEL_INFO, "%s: %s (%s %s) request: %s\n", __FUNCTION__, proto, get_ioa_socket_cipher(ss->client_socket), get_ioa_socket_ssl_method(ss->client_socket), str); if(server->send_https_socket) { TURN_LOG_FUNC(TURN_LOG_LEVEL_INFO, "%s socket to be detached: 0x%lx, st=%d, sat=%d\n", __FUNCTION__,(long)ss->client_socket, get_ioa_socket_type(ss->client_socket), get_ioa_socket_app_type(ss->client_socket)); ioa_socket_handle new_s = detach_ioa_socket(ss->client_socket); @@ -4644,7 +4649,7 @@ static int read_client_connection(turn_turnserver *server, } else { set_ioa_socket_app_type(ss->client_socket,HTTP_CLIENT_SOCKET); if(server->verbose) { - TURN_LOG_FUNC(TURN_LOG_LEVEL_INFO, "%s: %s request: %s\n", __FUNCTION__, proto, (char*)ioa_network_buffer_data(in_buffer->nbh)); + TURN_LOG_FUNC(TURN_LOG_LEVEL_INFO, "%s: %s request: %s\n", __FUNCTION__, proto, str); } handle_http_echo(ss->client_socket); } @@ -4915,6 +4920,7 @@ void init_turn_server(turn_turnserver* server, allocate_bps_cb allocate_bps_func, int oauth, const char* oauth_server_name, + const char* acme_redirect, int keep_address_family) { if (!server) @@ -4944,6 +4950,7 @@ void init_turn_server(turn_turnserver* server, server->oauth_server_name = oauth_server_name; if(mobility) server->mobile_connections_map = ur_map_create(); + server->acme_redirect = acme_redirect; TURN_LOG_FUNC(TURN_LOG_LEVEL_INFO,"turn server id=%d created\n",(int)id); diff --git a/src/server/ns_turn_server.h b/src/server/ns_turn_server.h index 924a507a..0df99716 100644 --- a/src/server/ns_turn_server.h +++ b/src/server/ns_turn_server.h @@ -171,6 +171,9 @@ struct _turn_turnserver { int oauth; const char* oauth_server_name; + /* ACME redirect URL */ + const char* acme_redirect; + /* Keep Address Family */ int keep_address_family; }; @@ -218,6 +221,7 @@ void init_turn_server(turn_turnserver* server, allocate_bps_cb allocate_bps_func, int oauth, const char* oauth_server_name, + const char* acme_redirect, int keep_address_family); ioa_engine_handle turn_server_get_engine(turn_turnserver *s); From 7e2c98bc1f28f12be9e47834da3a21d41da926f7 Mon Sep 17 00:00:00 2001 From: Jens Elkner Date: Mon, 18 May 2020 17:00:31 +0200 Subject: [PATCH 02/55] acme-redirect: add option to man page, fix help text --- man/man1/turnserver.1 | 7 +++++++ src/apps/relay/mainrelay.c | 2 +- 2 files changed, 8 insertions(+), 1 deletion(-) diff --git a/man/man1/turnserver.1 b/man/man1/turnserver.1 index df298c54..e6a377e1 100644 --- a/man/man1/turnserver.1 +++ b/man/man1/turnserver.1 @@ -770,6 +770,13 @@ File name to store the pid of the process. Default is /var/run/turnserver.pid (if superuser account is used) or /var/tmp/turnserver.pid . .TP +.BI --acme-redirect\ URL +Redirect ACME/RFC8555 (like Let's Encrypt challenge) requests, i.e. +HTTP GET requests matching '^/.well-known/acme-challenge/(.*)' +to \fIURL\fR$1 with $1 == (.*). No validation of \fIURL\fR will be done, +so make sure you do not forget the trailing slash. If \fIURL\fR is an empty +string (the default value), no special handling of such requests will be done. +.TP .B \fB\-\-proc\-user\fP User name to run the process. After the initialization, the \fIturnserver\fP process diff --git a/src/apps/relay/mainrelay.c b/src/apps/relay/mainrelay.c index 56b4c8af..854c080d 100644 --- a/src/apps/relay/mainrelay.c +++ b/src/apps/relay/mainrelay.c @@ -615,7 +615,7 @@ static char Usage[] = "Usage: turnserver [options]\n" " --pidfile <\"pid-file-name\"> File name to store the pid of the process.\n" " Default is /var/run/turnserver.pid (if superuser account is used) or\n" " /var/tmp/turnserver.pid .\n" -" --acme-redirect <\"URL\"> Redirect HTTP GET requests matching '^/.well-known/acme-challenge/(.*)' to '<\"URL\">$1'\n" +" --acme-redirect Redirect ACME, i.e. HTTP GET requests matching '^/.well-known/acme-challenge/(.*)' to '$1'.\n" " Default is '', i.e. no special handling for such requests.\n" " --secure-stun Require authentication of the STUN Binding request.\n" " By default, the clients are allowed anonymous access to the STUN Binding functionality.\n" From 5b6739a793f40749b3354c372a95f4577dc05f78 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?C=C3=A9dric=20Krier?= Date: Sun, 19 Jul 2020 10:48:44 +0200 Subject: [PATCH 03/55] Do not use FIPS and remove hardcode OPENSSL_VERSION_NUMBER with LibreSSL Fix #552 --- src/apps/common/ns_turn_openssl.h | 5 ----- src/apps/relay/ns_ioalib_engine_impl.c | 4 ++-- src/client/ns_turn_msg.c | 4 ++-- 3 files changed, 4 insertions(+), 9 deletions(-) diff --git a/src/apps/common/ns_turn_openssl.h b/src/apps/common/ns_turn_openssl.h index eb33c143..8272f99c 100644 --- a/src/apps/common/ns_turn_openssl.h +++ b/src/apps/common/ns_turn_openssl.h @@ -42,9 +42,4 @@ #include #include -#if (defined LIBRESSL_VERSION_NUMBER && OPENSSL_VERSION_NUMBER == 0x20000000L) -#undef OPENSSL_VERSION_NUMBER -#define OPENSSL_VERSION_NUMBER 0x1000107FL -#endif - #endif //__NST_OPENSSL_LIB__ diff --git a/src/apps/relay/ns_ioalib_engine_impl.c b/src/apps/relay/ns_ioalib_engine_impl.c index 22cc640a..b5721f47 100644 --- a/src/apps/relay/ns_ioalib_engine_impl.c +++ b/src/apps/relay/ns_ioalib_engine_impl.c @@ -1828,7 +1828,7 @@ int ssl_read(evutil_socket_t fd, SSL* ssl, ioa_network_buffer_handle nbh, int ve BIO* rbio = BIO_new_mem_buf(buffer, old_buffer_len); BIO_set_mem_eof_return(rbio, -1); -#if OPENSSL_VERSION_NUMBER < 0x10100000L +#if OPENSSL_VERSION_NUMBER < 0x10100000L || defined LIBRESSL_VERSION_NUMBER ssl->rbio = rbio; #else SSL_set0_rbio(ssl,rbio); @@ -1923,7 +1923,7 @@ int ssl_read(evutil_socket_t fd, SSL* ssl, ioa_network_buffer_handle nbh, int ve if(ret>0) { ioa_network_buffer_add_offset_size(nbh, (uint16_t)buf_size, 0, (size_t)ret); } -#if OPENSSL_VERSION_NUMBER < 0x10100000L +#if OPENSSL_VERSION_NUMBER < 0x10100000L || defined LIBRESSL_VERSION_NUMBER ssl->rbio = NULL; BIO_free(rbio); #else diff --git a/src/client/ns_turn_msg.c b/src/client/ns_turn_msg.c index e9386eb0..d0c8d889 100644 --- a/src/client/ns_turn_msg.c +++ b/src/client/ns_turn_msg.c @@ -244,7 +244,7 @@ int stun_produce_integrity_key_str(const uint8_t *uname, const uint8_t *realm, c unsigned int keylen = 0; EVP_MD_CTX ctx; EVP_MD_CTX_init(&ctx); -#ifdef EVP_MD_CTX_FLAG_NON_FIPS_ALLOW +#if defined EVP_MD_CTX_FLAG_NON_FIPS_ALLOW && !defined(LIBRESSL_VERSION_NUMBER) if (FIPS_mode()) { EVP_MD_CTX_set_flags(&ctx,EVP_MD_CTX_FLAG_NON_FIPS_ALLOW); } @@ -256,7 +256,7 @@ int stun_produce_integrity_key_str(const uint8_t *uname, const uint8_t *realm, c #else unsigned int keylen = 0; EVP_MD_CTX *ctx = EVP_MD_CTX_new(); -#ifdef EVP_MD_CTX_FLAG_NON_FIPS_ALLOW +#if defined EVP_MD_CTX_FLAG_NON_FIPS_ALLOW && ! defined(LIBRESSL_VERSION_NUMBER) if (FIPS_mode()) { EVP_MD_CTX_set_flags(ctx, EVP_MD_CTX_FLAG_NON_FIPS_ALLOW); } From 599a61eea6aa60c8b8e1ecaa027642f5ebe8331c Mon Sep 17 00:00:00 2001 From: Paul Wayper Date: Tue, 25 Aug 2020 21:46:15 +1000 Subject: [PATCH 04/55] Print full date and time in logs Signed-off-by: Paul Wayper --- src/apps/common/ns_turn_utils.c | 17 ++++++----------- 1 file changed, 6 insertions(+), 11 deletions(-) diff --git a/src/apps/common/ns_turn_utils.c b/src/apps/common/ns_turn_utils.c index 04b180c5..274dc438 100644 --- a/src/apps/common/ns_turn_utils.c +++ b/src/apps/common/ns_turn_utils.c @@ -178,17 +178,12 @@ void turn_log_func_default(TURN_LOG_LEVEL level, const char* format, ...) #define MAX_RTPPRINTF_BUFFER_SIZE (1024) char s[MAX_RTPPRINTF_BUFFER_SIZE+1]; #undef MAX_RTPPRINTF_BUFFER_SIZE - if (level == TURN_LOG_LEVEL_ERROR) { - snprintf(s,sizeof(s)-100,"%lu: ERROR: ",(unsigned long)log_time()); - size_t slen = strlen(s); - vsnprintf(s+slen,sizeof(s)-slen-1,format, args); - fwrite(s,strlen(s),1,stdout); - } else if(!no_stdout_log) { - snprintf(s,sizeof(s)-100,"%lu: ",(unsigned long)log_time()); - size_t slen = strlen(s); - vsnprintf(s+slen,sizeof(s)-slen-1,format, args); - fwrite(s,strlen(s),1,stdout); - } + struct tm local_now = localtime(time(NULL)); + strptime(s, sizeof(s)-100, "%Y-%m-%dT%H:%M:%S", &local_now); + snprintf(s + 19,sizeof(s)-100,(level == TURN_LOG_LEVEL_ERROR) ? ": ERROR: " : ": "); + size_t slen = strlen(s); + vsnprintf(s+slen,sizeof(s)-slen-1,format, args); + fwrite(s,strlen(s),1,stdout); #endif va_end(args); } From 762ee2348210a5481e00673e3696d0acf84a1f6d Mon Sep 17 00:00:00 2001 From: Paul Wayper Date: Wed, 26 Aug 2020 21:05:08 +1000 Subject: [PATCH 05/55] Fixing a few errors - C still coming back to me Signed-off-by: Paul Wayper --- src/apps/common/ns_turn_utils.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/apps/common/ns_turn_utils.c b/src/apps/common/ns_turn_utils.c index 274dc438..dde543fd 100644 --- a/src/apps/common/ns_turn_utils.c +++ b/src/apps/common/ns_turn_utils.c @@ -178,8 +178,8 @@ void turn_log_func_default(TURN_LOG_LEVEL level, const char* format, ...) #define MAX_RTPPRINTF_BUFFER_SIZE (1024) char s[MAX_RTPPRINTF_BUFFER_SIZE+1]; #undef MAX_RTPPRINTF_BUFFER_SIZE - struct tm local_now = localtime(time(NULL)); - strptime(s, sizeof(s)-100, "%Y-%m-%dT%H:%M:%S", &local_now); + time_t now = time(NULL); + strftime(s, sizeof(s), "%Y-%m-%dT%H:%M:%S", localtime(&now)); snprintf(s + 19,sizeof(s)-100,(level == TURN_LOG_LEVEL_ERROR) ? ": ERROR: " : ": "); size_t slen = strlen(s); vsnprintf(s+slen,sizeof(s)-slen-1,format, args); From 16eeb53e079c973e0254d5ec97444e000c0ff591 Mon Sep 17 00:00:00 2001 From: Paul Wayper Date: Mon, 31 Aug 2020 22:34:54 +1000 Subject: [PATCH 06/55] Allow new log format to be turned on if required This provides the 'use_new_timestamp_log_format' variable in `ns_turn_utils.h`. By default it is set to 0 and the old 'seconds since daemon was started' timestamp will be emitted. However, if it is set to 1 or any 'true' number the new date and time timestamp format will be used instead. This has also resulted in a small clean-up of some of the string length handling. Signed-off-by: Paul Wayper --- src/apps/common/ns_turn_utils.c | 18 ++++++++++++------ src/apps/common/ns_turn_utils.h | 1 + 2 files changed, 13 insertions(+), 6 deletions(-) diff --git a/src/apps/common/ns_turn_utils.c b/src/apps/common/ns_turn_utils.c index dde543fd..ee3c8bf8 100644 --- a/src/apps/common/ns_turn_utils.c +++ b/src/apps/common/ns_turn_utils.c @@ -158,6 +158,8 @@ void set_no_stdout_log(int val) no_stdout_log = val; } +int use_new_log_timestamp_format = 0; + void turn_log_func_default(TURN_LOG_LEVEL level, const char* format, ...) { #if !defined(TURN_LOG_FUNC_IMPL) @@ -178,12 +180,16 @@ void turn_log_func_default(TURN_LOG_LEVEL level, const char* format, ...) #define MAX_RTPPRINTF_BUFFER_SIZE (1024) char s[MAX_RTPPRINTF_BUFFER_SIZE+1]; #undef MAX_RTPPRINTF_BUFFER_SIZE - time_t now = time(NULL); - strftime(s, sizeof(s), "%Y-%m-%dT%H:%M:%S", localtime(&now)); - snprintf(s + 19,sizeof(s)-100,(level == TURN_LOG_LEVEL_ERROR) ? ": ERROR: " : ": "); - size_t slen = strlen(s); - vsnprintf(s+slen,sizeof(s)-slen-1,format, args); - fwrite(s,strlen(s),1,stdout); + size_t so_far = 0; + if (use_new_log_timestamp_format) { + time_t now = time(NULL); + so_far += strftime(s, sizeof(s), "%Y-%m-%dT%H:%M:%S", localtime(&now)); + } else { + so_far += snprintf(s, sizeof(s), "%lu: ", (unsigned long)log_time()); + } + so_far += snprintf(s + so_far, sizeof(s)-100, (level == TURN_LOG_LEVEL_ERROR) ? ": ERROR: " : ": "); + so_far += vsnprintf(s + so_far,sizeof(s) - (so_far+1), format, args); + fwrite(s, so_far, 1, stdout); #endif va_end(args); } diff --git a/src/apps/common/ns_turn_utils.h b/src/apps/common/ns_turn_utils.h index 77ade9aa..8aabae07 100644 --- a/src/apps/common/ns_turn_utils.h +++ b/src/apps/common/ns_turn_utils.h @@ -69,6 +69,7 @@ void addr_debug_print(int verbose, const ioa_addr *addr, const char* s); extern volatile int _log_time_value_set; extern volatile turn_time_t _log_time_value; +extern int use_new_log_timestamp_format; void rtpprintf(const char *format, ...); int vrtpprintf(TURN_LOG_LEVEL level, const char *format, va_list args); From 5e87c444693b39e11cabc498450dacbef30ec64a Mon Sep 17 00:00:00 2001 From: Paul Wayper Date: Tue, 1 Sep 2020 18:35:01 +1000 Subject: [PATCH 07/55] Merge turn_log_func_default and vrtpprintf The function `turn_log_func_default` calls the function `vrtpprintf` to print to syslog or the log file. The latter does exactly the same string formatting as the former, so here we merge the two functions into one to do the string formatting once. This also makes sure that the log line is consistent on all outputs. Signed-off-by: Paul Wayper --- src/apps/common/ns_turn_utils.c | 73 +++++++++------------------------ 1 file changed, 20 insertions(+), 53 deletions(-) diff --git a/src/apps/common/ns_turn_utils.c b/src/apps/common/ns_turn_utils.c index ee3c8bf8..0007a55a 100644 --- a/src/apps/common/ns_turn_utils.c +++ b/src/apps/common/ns_turn_utils.c @@ -160,41 +160,6 @@ void set_no_stdout_log(int val) int use_new_log_timestamp_format = 0; -void turn_log_func_default(TURN_LOG_LEVEL level, const char* format, ...) -{ -#if !defined(TURN_LOG_FUNC_IMPL) - { - va_list args; - va_start(args,format); - vrtpprintf(level, format, args); - va_end(args); - } -#endif - - { - va_list args; - va_start(args,format); -#if defined(TURN_LOG_FUNC_IMPL) - TURN_LOG_FUNC_IMPL(level,format,args); -#else -#define MAX_RTPPRINTF_BUFFER_SIZE (1024) - char s[MAX_RTPPRINTF_BUFFER_SIZE+1]; -#undef MAX_RTPPRINTF_BUFFER_SIZE - size_t so_far = 0; - if (use_new_log_timestamp_format) { - time_t now = time(NULL); - so_far += strftime(s, sizeof(s), "%Y-%m-%dT%H:%M:%S", localtime(&now)); - } else { - so_far += snprintf(s, sizeof(s), "%lu: ", (unsigned long)log_time()); - } - so_far += snprintf(s + so_far, sizeof(s)-100, (level == TURN_LOG_LEVEL_ERROR) ? ": ERROR: " : ": "); - so_far += vsnprintf(s + so_far,sizeof(s) - (so_far+1), format, args); - fwrite(s, so_far, 1, stdout); -#endif - va_end(args); - } -} - void addr_debug_print(int verbose, const ioa_addr *addr, const char* s) { if (verbose) { @@ -513,20 +478,29 @@ static int get_syslog_level(TURN_LOG_LEVEL level) return LOG_INFO; } -int vrtpprintf(TURN_LOG_LEVEL level, const char *format, va_list args) +void turn_log_func_default(TURN_LOG_LEVEL level, const char* format, ...) { + va_list args; + va_start(args,format); +#if defined(TURN_LOG_FUNC_IMPL) + TURN_LOG_FUNC_IMPL(level,format,args); +#else /* Fix for Issue 24, raised by John Selbie: */ #define MAX_RTPPRINTF_BUFFER_SIZE (1024) char s[MAX_RTPPRINTF_BUFFER_SIZE+1]; #undef MAX_RTPPRINTF_BUFFER_SIZE - - size_t sz; - - snprintf(s, sizeof(s), "%lu: ",(unsigned long)log_time()); - sz=strlen(s); - vsnprintf(s+sz, sizeof(s)-1-sz, format, args); - s[sizeof(s)-1]=0; - + size_t so_far = 0; + if (use_new_log_timestamp_format) { + time_t now = time(NULL); + so_far += strftime(s, sizeof(s), "%Y-%m-%dT%H:%M:%S", localtime(&now)); + } else { + so_far += snprintf(s, sizeof(s), "%lu: ", (unsigned long)log_time()); + } + so_far += snprintf(s + so_far, sizeof(s)-100, (level == TURN_LOG_LEVEL_ERROR) ? ": ERROR: " : ": "); + so_far += vsnprintf(s + so_far,sizeof(s) - (so_far+1), format, args); + /* always write to stdout */ + fwrite(s, so_far, 1, stdout); + /* write to syslog or to log file */ if(to_syslog) { syslog(get_syslog_level(level),"%s",s); } else { @@ -539,16 +513,9 @@ int vrtpprintf(TURN_LOG_LEVEL level, const char *format, va_list args) } log_unlock(); } +#endif + va_end(args); - return 0; -} - -void rtpprintf(const char *format, ...) -{ - va_list args; - va_start (args, format); - vrtpprintf(TURN_LOG_LEVEL_INFO, format, args); - va_end (args); } ///////////// ORIGIN /////////////////// From f59e9f8ad429da71ec2147915ea652e6b9891b9d Mon Sep 17 00:00:00 2001 From: Paul Wayper Date: Tue, 1 Sep 2020 18:43:56 +1000 Subject: [PATCH 08/55] Allow the log timestamp format to be set This allows the timestamp format in log output to be set by a function. Signed-off-by: Paul Wayper --- src/apps/common/ns_turn_utils.c | 10 +++++++++- src/apps/common/ns_turn_utils.h | 2 ++ 2 files changed, 11 insertions(+), 1 deletion(-) diff --git a/src/apps/common/ns_turn_utils.c b/src/apps/common/ns_turn_utils.c index 0007a55a..1f5570d9 100644 --- a/src/apps/common/ns_turn_utils.c +++ b/src/apps/common/ns_turn_utils.c @@ -158,6 +158,14 @@ void set_no_stdout_log(int val) no_stdout_log = val; } +#define MAX_LOG_TIMESTAMP_FORMAT_LEN 48 +static char turn_log_timestamp_format[MAX_LOG_TIMESTAMP_FORMAT_LEN] = "%Y-%m-%dT%H:%M:%S"; + +void set_turn_log_timestamp_format(char* new_format) +{ + strncpy(turn_log_timestamp_format, new_format, MAX_LOG_TIMESTAMP_FORMAT_LEN-1); +} + int use_new_log_timestamp_format = 0; void addr_debug_print(int verbose, const ioa_addr *addr, const char* s) @@ -492,7 +500,7 @@ void turn_log_func_default(TURN_LOG_LEVEL level, const char* format, ...) size_t so_far = 0; if (use_new_log_timestamp_format) { time_t now = time(NULL); - so_far += strftime(s, sizeof(s), "%Y-%m-%dT%H:%M:%S", localtime(&now)); + so_far += strftime(s, sizeof(s), turn_log_timestamp_format, localtime(&now)); } else { so_far += snprintf(s, sizeof(s), "%lu: ", (unsigned long)log_time()); } diff --git a/src/apps/common/ns_turn_utils.h b/src/apps/common/ns_turn_utils.h index 8aabae07..d9e9488d 100644 --- a/src/apps/common/ns_turn_utils.h +++ b/src/apps/common/ns_turn_utils.h @@ -61,6 +61,8 @@ void set_no_stdout_log(int val); void set_log_to_syslog(int val); void set_simple_log(int val); +void set_turn_log_timestamp_format(char* new_format); + void turn_log_func_default(TURN_LOG_LEVEL level, const char* format, ...); void addr_debug_print(int verbose, const ioa_addr *addr, const char* s); From ed88f1605ae6deada2045842a66aafae08fd1578 Mon Sep 17 00:00:00 2001 From: Paul Wayper Date: Tue, 1 Sep 2020 20:57:54 +1000 Subject: [PATCH 09/55] Neater ISO-8601 timestamp format string Signed-off-by: Paul Wayper --- src/apps/common/ns_turn_utils.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/apps/common/ns_turn_utils.c b/src/apps/common/ns_turn_utils.c index 1f5570d9..7022edae 100644 --- a/src/apps/common/ns_turn_utils.c +++ b/src/apps/common/ns_turn_utils.c @@ -159,7 +159,7 @@ void set_no_stdout_log(int val) } #define MAX_LOG_TIMESTAMP_FORMAT_LEN 48 -static char turn_log_timestamp_format[MAX_LOG_TIMESTAMP_FORMAT_LEN] = "%Y-%m-%dT%H:%M:%S"; +static char turn_log_timestamp_format[MAX_LOG_TIMESTAMP_FORMAT_LEN] = "%FT%T%z"; void set_turn_log_timestamp_format(char* new_format) { From c315c288bd2f52155b27598803933aa89238218d Mon Sep 17 00:00:00 2001 From: Paul Wayper Date: Tue, 1 Sep 2020 21:01:28 +1000 Subject: [PATCH 10/55] Add options for new log timestamp and setting timestamp format This adds the `--new-log-timestamp` and `--new-timestamp-format ` options to the `turnserver` program. Setting `--new-log-timestamp` on the command line, or `new-log-timestamp` in the configuration file, will cause all logs to be written with an ISI-8601 timestamp (`YYYY-MM-DDTHH:MM:SSZZZZZ` with `T` being literal and `ZZZZZ` being `+` or `-` and the hour and minute offset from GMT for the local timezone). This replaces the 'number of seconds since daemon was started' format. Setting the `--new-timestamp-format ` option with a given format, or `new-log-timestamp=` in the configuration file, will use this instead of the standard timestamp format. Timestamp format strings up to 48 characters can be accommodated; more will be truncated. This will only be used when the `--new-log-timestamp` option (above) is set. Thanks to Hendrik Huels for the idea and some of the code for setting the log timestamp string. Signed-off-by: Paul Wayper --- src/apps/relay/mainrelay.c | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/src/apps/relay/mainrelay.c b/src/apps/relay/mainrelay.c index 0aabb3b7..d0134f28 100644 --- a/src/apps/relay/mainrelay.c +++ b/src/apps/relay/mainrelay.c @@ -603,6 +603,8 @@ static char Usage[] = "Usage: turnserver [options]\n" " --simple-log This flag means that no log file rollover will be used, and the log file\n" " name will be constructed as-is, without PID and date appendage.\n" " This option can be used, for example, together with the logrotate tool.\n" +" --new-log-timestamp Enable full ISO-8601 timestamp in all logs.\n" +" --new-timestamp_format Set timestamp format (in strftime(1) format)\n" " --stale-nonce[=] Use extra security with nonce value having limited lifetime (default 600 secs).\n" " --max-allocate-lifetime Set the maximum value for the allocation lifetime. Default to 3600 secs.\n" " --channel-lifetime Set the lifetime for channel binding, default to 600 secs.\n" @@ -761,6 +763,8 @@ enum EXTRA_OPTS { NO_STDOUT_LOG_OPT, SYSLOG_OPT, SIMPLE_LOG_OPT, + NEW_LOG_TIMESTAMP_OPT, + NEW_TIMESTAMP_FORMAT_OPT, AUX_SERVER_OPT, UDP_SELF_BALANCE_OPT, ALTERNATE_SERVER_OPT, @@ -899,6 +903,8 @@ static const struct myoption long_options[] = { { "no-stdout-log", optional_argument, NULL, NO_STDOUT_LOG_OPT }, { "syslog", optional_argument, NULL, SYSLOG_OPT }, { "simple-log", optional_argument, NULL, SIMPLE_LOG_OPT }, + { "new-log-timestamp", optional_argument, NULL, NEW_LOG_TIMESTAMP_OPT }, + { "new-timestamp_format", required_argument, NULL, NEW_TIMESTAMP_FORMAT_OPT }, { "aux-server", required_argument, NULL, AUX_SERVER_OPT }, { "udp-self-balance", optional_argument, NULL, UDP_SELF_BALANCE_OPT }, { "alternate-server", required_argument, NULL, ALTERNATE_SERVER_OPT }, @@ -1717,6 +1723,10 @@ static void read_config_file(int argc, char **argv, int pass) set_log_to_syslog(get_bool_value(value)); } else if((pass==0) && (c==SIMPLE_LOG_OPT)) { set_simple_log(get_bool_value(value)); + } else if ((pass==0) && (c==NEW_LOG_TIMESTAMP_OPT)) { + use_new_log_timestamp_format=1; + } else if ((pass==0) && (c==NEW_TIMESTAMP_FORMAT_OPT)) { + set_turn_log_timestamp_format(value); } else if((pass == 0) && (c != 'u')) { set_option(c, value); } else if((pass > 0) && (c == 'u')) { From 315341d204cb8b93ee076ea1935a367b48170e62 Mon Sep 17 00:00:00 2001 From: Samuel Date: Mon, 14 Sep 2020 12:34:04 +0200 Subject: [PATCH 11/55] Fix misleading option in doc While that prometheus exporter was initially enabled by default, it looks like there's been a change of plan, resulting in some inconsistencies in the doc. The `--no-prometheus` option was replaced by a `--prometheus` one -- according to https://github.com/wolmi/coturn/blob/master/src/apps/relay/mainrelay.c#L540 --- README.turnserver | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/README.turnserver b/README.turnserver index 320021e9..a5bf149a 100644 --- a/README.turnserver +++ b/README.turnserver @@ -265,8 +265,8 @@ Flags: check: across the session, all requests must have the same main ORIGIN attribute value (if the ORIGIN was initially used by the session). - --no-prometheus Disable prometheus metrics. By default it is - enabled and listening on port 9641 unther the path /metrics + --prometheus Enable prometheus metrics. By default it is + disabled. Would listen on port 9641 unther the path /metrics also the path / on this port can be used as a health check -h Help. From bd3dd85a762df5192f5d1fea29f62adbf2d76b14 Mon Sep 17 00:00:00 2001 From: ddeka2910 <60925700+ddeka2910@users.noreply.github.com> Date: Tue, 6 Oct 2020 23:42:47 +0530 Subject: [PATCH 12/55] Add architecture ppc64le to travis build --- .travis.yml | 37 ++++++++++++++++++++++++++++++++++++- 1 file changed, 36 insertions(+), 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index 84e024f2..f3199c79 100644 --- a/.travis.yml +++ b/.travis.yml @@ -70,7 +70,42 @@ matrix: osx_image: xcode11.6 - os: osx osx_image: xcode12 - + - os: linux + arch: ppc64le + dist: xenial + sudo: required + addons: + apt: + packages: + - mysql-client + - debhelper + - dpkg-dev + - libssl-dev + - libevent-dev + - sqlite3 + - libsqlite3-dev + - postgresql-client + - libpq-dev + - libmysqlclient-dev + - libhiredis-dev + - os: linux + arch: ppc64le + dist: bionic + sudo: required + addons: + apt: + packages: + - mysql-client + - debhelper + - dpkg-dev + - libssl-dev + - libevent-dev + - sqlite3 + - libsqlite3-dev + - postgresql-client + - libpq-dev + - libmysqlclient-dev + - libhiredis-dev notifications: slack: From 2baacbf89519b35e4dae41223457a7fdaebbba9c Mon Sep 17 00:00:00 2001 From: David Florness Date: Sat, 17 Oct 2020 13:49:07 -0400 Subject: [PATCH 13/55] Delete trailing whitespace in example configuration files --- docker/coturn/turnserver.conf | 188 +++++++++++++++++----------------- examples/etc/turnserver.conf | 186 ++++++++++++++++----------------- 2 files changed, 187 insertions(+), 187 deletions(-) diff --git a/docker/coturn/turnserver.conf b/docker/coturn/turnserver.conf index 00ce8abd..fc9ac1fe 100644 --- a/docker/coturn/turnserver.conf +++ b/docker/coturn/turnserver.conf @@ -1,45 +1,45 @@ # Coturn TURN SERVER configuration file # # Boolean values note: where a boolean value is supposed to be used, -# you can use '0', 'off', 'no', 'false', or 'f' as 'false, -# and you can use '1', 'on', 'yes', 'true', or 't' as 'true' +# you can use '0', 'off', 'no', 'false', or 'f' as 'false, +# and you can use '1', 'on', 'yes', 'true', or 't' as 'true' # If the value is missing, then it means 'true' by default. # # Listener interface device (optional, Linux only). -# NOT RECOMMENDED. +# NOT RECOMMENDED. # #listening-device=eth0 # TURN listener port for UDP and TCP (Default: 3478). -# Note: actually, TLS & DTLS sessions can connect to the +# Note: actually, TLS & DTLS sessions can connect to the # "plain" TCP & UDP port(s), too - if allowed by configuration. # listening-port=3478 # TURN listener port for TLS (Default: 5349). # Note: actually, "plain" TCP & UDP sessions can connect to the TLS & DTLS -# port(s), too - if allowed by configuration. The TURN server +# port(s), too - if allowed by configuration. The TURN server # "automatically" recognizes the type of traffic. Actually, two listening # endpoints (the "plain" one and the "tls" one) are equivalent in terms of # functionality; but Coturn keeps both endpoints to satisfy the RFC 5766 specs. -# For secure TCP connections, Coturn currently supports SSL version 3 and +# For secure TCP connections, Coturn currently supports SSL version 3 and # TLS version 1.0, 1.1 and 1.2. # For secure UDP connections, Coturn supports DTLS version 1. # tls-listening-port=5349 # Alternative listening port for UDP and TCP listeners; -# default (or zero) value means "listening port plus one". +# default (or zero) value means "listening port plus one". # This is needed for RFC 5780 support -# (STUN extension specs, NAT behavior discovery). The TURN Server -# supports RFC 5780 only if it is started with more than one +# (STUN extension specs, NAT behavior discovery). The TURN Server +# supports RFC 5780 only if it is started with more than one # listening IP address of the same family (IPv4 or IPv6). # RFC 5780 is supported only by UDP protocol, other protocols # are listening to that endpoint only for "symmetry". # #alt-listening-port=0 - + # Alternative listening port for TLS and DTLS protocols. # Default (or zero) value means "TLS listening port plus one". # @@ -52,9 +52,9 @@ tls-listening-port=5349 # (https://www.haproxy.org/download/1.8/doc/proxy-protocol.txt) # #tcp-proxy-port=5555 - + # Listener IP address of relay server. Multiple listeners can be specified. -# If no IP(s) specified in the config file or in the command line options, +# If no IP(s) specified in the config file or in the command line options, # then all IPv4 and IPv6 system IPs will be used for listening. # #listening-ip=172.17.19.101 @@ -69,7 +69,7 @@ tls-listening-port=5349 # they do not support STUN RFC 5780 functionality (CHANGE REQUEST). # # 2) Auxiliary servers also are never returning ALTERNATIVE-SERVER reply. -# +# # Valid formats are 1.2.3.4:5555 for IPv4 and [1:2::3:4]:5555 for IPv6. # # There may be multiple aux-server options, each will be used for listening @@ -81,7 +81,7 @@ tls-listening-port=5349 # (recommended for older Linuxes only) # Automatically balance UDP traffic over auxiliary servers (if configured). # The load balancing is using the ALTERNATE-SERVER mechanism. -# The TURN client must support 300 ALTERNATE-SERVER response for this +# The TURN client must support 300 ALTERNATE-SERVER response for this # functionality. # #udp-self-balance @@ -91,13 +91,13 @@ tls-listening-port=5349 # #relay-device=eth1 -# Relay address (the local IP address that will be used to relay the +# Relay address (the local IP address that will be used to relay the # packets to the peer). # Multiple relay addresses may be used. # The same IP(s) can be used as both listening IP(s) and relay IP(s). # # If no relay IP(s) specified, then the turnserver will apply the default -# policy: it will decide itself which relay addresses to be used, and it +# policy: it will decide itself which relay addresses to be used, and it # will always be using the client socket IP address as the relay IP address # of the TURN session (if the requested relay address family is the same # as the family of the client socket). @@ -120,7 +120,7 @@ tls-listening-port=5349 # that option must be used several times, each entry must # have form "-X ", to map all involved addresses. # RFC5780 NAT discovery STUN functionality will work correctly, -# if the addresses are mapped properly, even when the TURN server itself +# if the addresses are mapped properly, even when the TURN server itself # is behind A NAT. # # By default, this value is empty, and no address mapping is used. @@ -135,18 +135,18 @@ external-ip=193.224.22.37 # Number of the relay threads to handle the established connections # (in addition to authentication thread and the listener thread). -# If explicitly set to 0 then application runs relay process in a -# single thread, in the same thread with the listener process +# If explicitly set to 0 then application runs relay process in a +# single thread, in the same thread with the listener process # (the authentication thread will still be a separate thread). # -# If this parameter is not set, then the default OS-dependent +# If this parameter is not set, then the default OS-dependent # thread pattern algorithm will be employed. Usually the default # algorithm is optimal, so you have to change this option -# if you want to make some fine tweaks. +# if you want to make some fine tweaks. # # In the older systems (Linux kernel before 3.9), # the number of UDP threads is always one thread per network listening -# endpoint - including the auxiliary endpoints - unless 0 (zero) or +# endpoint - including the auxiliary endpoints - unless 0 (zero) or # 1 (one) value is set. # #relay-threads=0 @@ -156,15 +156,15 @@ external-ip=193.224.22.37 # min-port=49152 max-port=65535 - + # Uncomment to run TURN server in 'normal' 'moderate' verbose mode. # By default the verbose mode is off. verbose - + # Uncomment to run TURN server in 'extra' verbose mode. # This mode is very annoying and produces lots of output. # Not recommended under normal circumstances. -# +# #Verbose # Uncomment to use fingerprints in the TURN messages. @@ -177,10 +177,10 @@ fingerprint # lt-cred-mech -# This option is the opposite of lt-cred-mech. +# This option is the opposite of lt-cred-mech. # (TURN Server with no-auth option allows anonymous access). # If neither option is defined, and no users are defined, -# then no-auth is default. If at least one user is defined, +# then no-auth is default. If at least one user is defined, # in this file, in command line or in usersdb file, then # lt-cred-mech is default. # @@ -191,11 +191,11 @@ lt-cred-mech # Flag that sets a special authorization option that is based upon authentication secret. # # This feature's purpose is to support "TURN Server REST API", see -# "TURN REST API" link in the project's page +# "TURN REST API" link in the project's page # https://github.com/coturn/coturn/ # # This option is used with timestamp: -# +# # usercombo -> "timestamp:userid" # turn user -> usercombo # turn password -> base64(hmac(secret key, usercombo)) @@ -205,7 +205,7 @@ lt-cred-mech # This option is enabled by turning on secret-based authentication. # The actual value of the secret is defined either by the option static-auth-secret, # or can be found in the turn_secret table in the database (see below). -# +# # Read more about it: # - https://tools.ietf.org/html/draft-uberti-behave-turn-rest-00 # - https://www.ietf.org/proceedings/87/slides/slides-87-behave-10.pdf @@ -217,13 +217,13 @@ lt-cred-mech # # Note that you can use only one auth mechanism at the same time! This is because, # both mechanisms conduct username and password validation in different ways. -# +# # Use either lt-cred-mech or use-auth-secret in the conf # to avoid any confusion. # #use-auth-secret -# 'Static' authentication secret value (a string) for TURN REST API only. +# 'Static' authentication secret value (a string) for TURN REST API only. # If not set, then the turn server # will try to use the 'dynamic' value in the turn_secret table # in the user database (if present). The database-stored value can be changed on-the-fly @@ -243,7 +243,7 @@ lt-cred-mech # 'Static' user accounts for the long term credentials mechanism, only. # This option cannot be used with TURN REST API. -# 'Static' user accounts are NOT dynamically checked by the turnserver process, +# 'Static' user accounts are NOT dynamically checked by the turnserver process, # so they can NOT be changed while the turnserver is running. # #user=username1:key1 @@ -262,7 +262,7 @@ lt-cred-mech # password. If it has 0x then it is a key, otherwise it is a password). # # The corresponding user account entry in the config file will be: -# +# #user=ninefingers:0xbc807ee29df3c9ffa736523fb2c4e8ee # Or, equivalently, with open clear password (less secure): #user=ninefingers:youhavetoberealistic @@ -272,15 +272,15 @@ lt-cred-mech # # The default file name is /var/db/turndb or /usr/local/var/db/turndb or # /var/lib/turn/turndb. -# +# #userdb=/var/db/turndb # PostgreSQL database connection string in the case that you are using PostgreSQL # as the user database. # This database can be used for the long-term credential mechanism -# and it can store the secret value for secret-based timed authentication in TURN REST API. +# and it can store the secret value for secret-based timed authentication in TURN REST API. # See http://www.postgresql.org/docs/8.4/static/libpq-connect.html for 8.x PostgreSQL -# versions connection string format, see +# versions connection string format, see # http://www.postgresql.org/docs/9.2/static/libpq-connect.html#LIBPQ-CONNSTRING # for 9.x and newer connection string formats. # @@ -291,9 +291,9 @@ lt-cred-mech # This database can be used for the long-term credential mechanism # and it can store the secret value for secret-based timed authentication in TURN REST API. # -# Optional connection string parameters for the secure communications (SSL): -# ca, capath, cert, key, cipher -# (see http://dev.mysql.com/doc/refman/5.1/en/ssl-options.html for the +# Optional connection string parameters for the secure communications (SSL): +# ca, capath, cert, key, cipher +# (see http://dev.mysql.com/doc/refman/5.1/en/ssl-options.html for the # command options description). # # Use the string format below (space separated parameters, all optional): @@ -303,7 +303,7 @@ mysql-userdb="host=mysql dbname=coturn user=coturn password=CHANGE_ME port=3306 # If you want to use an encrypted password in the MySQL connection string, # then set the MySQL password encryption secret key file with this option. # -# Warning: If this option is set, then the mysql password must be set in "mysql-userdb" in an encrypted format! +# Warning: If this option is set, then the mysql password must be set in "mysql-userdb" in an encrypted format! # If you want to use a cleartext password then do not set this option! # # This is the file path for the aes encrypted secret key used for password encryption. @@ -313,7 +313,7 @@ mysql-userdb="host=mysql dbname=coturn user=coturn password=CHANGE_ME port=3306 # MongoDB database connection string in the case that you are using MongoDB # as the user database. # This database can be used for long-term credential mechanism -# and it can store the secret value for secret-based timed authentication in TURN REST API. +# and it can store the secret value for secret-based timed authentication in TURN REST API. # Use the string format described at http://hergert.me/docs/mongo-c-driver/mongoc_uri.html # #mongo-userdb="mongodb://[username:password@]host1[:port1][,host2[:port2],...[,hostN[:portN]]][/[database][?options]]" @@ -321,7 +321,7 @@ mysql-userdb="host=mysql dbname=coturn user=coturn password=CHANGE_ME port=3306 # Redis database connection string in the case that you are using Redis # as the user database. # This database can be used for long-term credential mechanism -# and it can store the secret value for secret-based timed authentication in TURN REST API. +# and it can store the secret value for secret-based timed authentication in TURN REST API. # Use the string format below (space separated parameters, all optional): # #redis-userdb="ip= dbname= password= port= connect_timeout=" @@ -329,15 +329,15 @@ mysql-userdb="host=mysql dbname=coturn user=coturn password=CHANGE_ME port=3306 # Redis status and statistics database connection string, if used (default - empty, no Redis stats DB used). # This database keeps allocations status information, and it can be also used for publishing # and delivering traffic and allocation event notifications. -# The connection string has the same parameters as redis-userdb connection string. +# The connection string has the same parameters as redis-userdb connection string. # Use the string format below (space separated parameters, all optional): # #redis-statsdb="ip= dbname= password= port= connect_timeout=" -# The default realm to be used for the users when no explicit +# The default realm to be used for the users when no explicit # origin/realm relationship is found in the database, or if the TURN # server is not using any database (just the commands-line settings -# and the userdb file). Must be used with long-term credentials +# and the userdb file). Must be used with long-term credentials # mechanism or with TURN REST API. # # Note: If the default realm is not specified, then realm falls back to the host domain name. @@ -345,7 +345,7 @@ mysql-userdb="host=mysql dbname=coturn user=coturn password=CHANGE_ME port=3306 # realm=example.org -# This flag sets the origin consistency +# This flag sets the origin consistency # check. Across the session, all requests must have the same # main ORIGIN attribute value (if the ORIGIN was # initially used by the session). @@ -412,9 +412,9 @@ realm=example.org # Uncomment if extra security is desired, # with nonce value having a limited lifetime. # By default, the nonce value is unique for a session, -# and has an unlimited lifetime. -# Set this option to limit the nonce lifetime. -# It defaults to 600 secs (10 min) if no value is provided. After that delay, +# and has an unlimited lifetime. +# Set this option to limit the nonce lifetime. +# It defaults to 600 secs (10 min) if no value is provided. After that delay, # the client will get 438 error and will have to re-authenticate itself. # #stale-nonce=600 @@ -440,14 +440,14 @@ realm=example.org #permission-lifetime=300 # Certificate file. -# Use an absolute path or path relative to the +# Use an absolute path or path relative to the # configuration file. # Use PEM file format. # cert=/etc/ssl/certs/cert.pem # Private key file. -# Use an absolute path or path relative to the +# Use an absolute path or path relative to the # configuration file. # Use PEM file format. # @@ -463,7 +463,7 @@ pkey=/etc/ssl/private/privkey.pem # #cipher-list="DEFAULT" -# CA file in OpenSSL format. +# CA file in OpenSSL format. # Forces TURN server to verify the client SSL certificates. # By default this is not set: there is no default value and the client # certificate is not checked. @@ -471,8 +471,8 @@ pkey=/etc/ssl/private/privkey.pem # Example: #CA-file=/etc/ssh/id_rsa.cert -# Curve name for EC ciphers, if supported by OpenSSL -# library (TLS and DTLS). The default value is prime256v1, +# Curve name for EC ciphers, if supported by OpenSSL +# library (TLS and DTLS). The default value is prime256v1, # if pre-OpenSSL 1.0.2 is used. With OpenSSL 1.0.2+, # an optimal curve will be automatically calculated, if not defined # by this option. @@ -493,21 +493,21 @@ pkey=/etc/ssl/private/privkey.pem #dh-file= # Flag to prevent stdout log messages. -# By default, all log messages go to both stdout and to -# the configured log file. With this option everything will +# By default, all log messages go to both stdout and to +# the configured log file. With this option everything will # go to the configured log only (unless the log file itself is stdout). # #no-stdout-log # Option to set the log file name. -# By default, the turnserver tries to open a log file in +# By default, the turnserver tries to open a log file in # /var/log, /var/tmp, /tmp and the current directory # (Whichever file open operation succeeds first will be used). # With this option you can set the definite log file name. -# The special names are "stdout" and "-" - they will force everything +# The special names are "stdout" and "-" - they will force everything # to the stdout. Also, the "syslog" name will force everything to -# the system log (syslog). -# In the runtime, the logfile can be reset with the SIGHUP signal +# the system log (syslog). +# In the runtime, the logfile can be reset with the SIGHUP signal # to the turnserver process. # #log-file=/var/tmp/turn.log @@ -523,40 +523,40 @@ syslog #simple-log # Option to set the "redirection" mode. The value of this option -# will be the address of the alternate server for UDP & TCP service in the form of +# will be the address of the alternate server for UDP & TCP service in the form of # [:]. The server will send this value in the attribute # ALTERNATE-SERVER, with error 300, on ALLOCATE request, to the client. # Client will receive only values with the same address family -# as the client network endpoint address family. -# See RFC 5389 and RFC 5766 for the description of ALTERNATE-SERVER functionality. +# as the client network endpoint address family. +# See RFC 5389 and RFC 5766 for the description of ALTERNATE-SERVER functionality. # The client must use the obtained value for subsequent TURN communications. # If more than one --alternate-server option is provided, then the functionality -# can be more accurately described as "load-balancing" than a mere "redirection". -# If the port number is omitted, then the default port +# can be more accurately described as "load-balancing" than a mere "redirection". +# If the port number is omitted, then the default port # number 3478 for the UDP/TCP protocols will be used. -# Colon (:) characters in IPv6 addresses may conflict with the syntax of -# the option. To alleviate this conflict, literal IPv6 addresses are enclosed -# in square brackets in such resource identifiers, for example: -# [2001:db8:85a3:8d3:1319:8a2e:370:7348]:3478 . +# Colon (:) characters in IPv6 addresses may conflict with the syntax of +# the option. To alleviate this conflict, literal IPv6 addresses are enclosed +# in square brackets in such resource identifiers, for example: +# [2001:db8:85a3:8d3:1319:8a2e:370:7348]:3478 . # Multiple alternate servers can be set. They will be used in the -# round-robin manner. All servers in the pool are considered of equal weight and -# the load will be distributed equally. For example, if you have 4 alternate servers, -# then each server will receive 25% of ALLOCATE requests. A alternate TURN server -# address can be used more than one time with the alternate-server option, so this +# round-robin manner. All servers in the pool are considered of equal weight and +# the load will be distributed equally. For example, if you have 4 alternate servers, +# then each server will receive 25% of ALLOCATE requests. A alternate TURN server +# address can be used more than one time with the alternate-server option, so this # can emulate "weighting" of the servers. # -# Examples: +# Examples: #alternate-server=1.2.3.4:5678 #alternate-server=11.22.33.44:56789 #alternate-server=5.6.7.8 #alternate-server=[2001:db8:85a3:8d3:1319:8a2e:370:7348]:3478 - -# Option to set alternative server for TLS & DTLS services in form of -# :. If the port number is omitted, then the default port -# number 5349 for the TLS/DTLS protocols will be used. See the previous + +# Option to set alternative server for TLS & DTLS services in form of +# :. If the port number is omitted, then the default port +# number 5349 for the TLS/DTLS protocols will be used. See the previous # option for the functionality description. # -# Examples: +# Examples: #tls-alternate-server=1.2.3.4:5678 #tls-alternate-server=11.22.33.44:56789 #tls-alternate-server=[2001:db8:85a3:8d3:1319:8a2e:370:7348]:3478 @@ -584,7 +584,7 @@ syslog # This is the timestamp/username separator symbol (character) in TURN REST API. # The default value is ':'. -# rest-api-separator=: +# rest-api-separator=: # Flag that can be used to allow peers on the loopback addresses (127.x.x.x and ::1). # This is an extra security measure. @@ -592,9 +592,9 @@ syslog # (To avoid any security issue that allowing loopback access may raise, # the no-loopback-peers option is replaced by allow-loopback-peers.) # -# Allow it only for testing in a development environment! -# In production it adds a possible security vulnerability, so for security reasons -# it is not allowed using it together with empty cli-password. +# Allow it only for testing in a development environment! +# In production it adds a possible security vulnerability, so for security reasons +# it is not allowed using it together with empty cli-password. # #allow-loopback-peers @@ -603,18 +603,18 @@ syslog # #no-multicast-peers -# Option to set the max time, in seconds, allowed for full allocation establishment. +# Option to set the max time, in seconds, allowed for full allocation establishment. # Default is 60 seconds. # #max-allocate-timeout=60 -# Option to allow or ban specific ip addresses or ranges of ip addresses. -# If an ip address is specified as both allowed and denied, then the ip address is -# considered to be allowed. This is useful when you wish to ban a range of ip +# Option to allow or ban specific ip addresses or ranges of ip addresses. +# If an ip address is specified as both allowed and denied, then the ip address is +# considered to be allowed. This is useful when you wish to ban a range of ip # addresses, except for a few specific ips within that range. # # This can be used when you do not want users of the turn server to be able to access -# machines reachable by the turn server, but would otherwise be unreachable from the +# machines reachable by the turn server, but would otherwise be unreachable from the # internet (e.g. when the turn server is sitting behind a NAT) # # Examples: @@ -636,8 +636,8 @@ syslog # #mobility -# Allocate Address Family according -# If enabled then TURN server allocates address family according the TURN +# Allocate Address Family according +# If enabled then TURN server allocates address family according the TURN # Client <=> Server communication address family. # (By default Coturn works according RFC 6156.) # !!Warning: Enabling this option breaks RFC6156 section-4.2 (violates use default IPv4)!! @@ -701,10 +701,10 @@ cli-password=CHANGE_ME # #web-admin-listen-on-workers -# Server relay. NON-STANDARD AND DANGEROUS OPTION. -# Only for those applications when you want to run +# Server relay. NON-STANDARD AND DANGEROUS OPTION. +# Only for those applications when you want to run # server applications on the relay endpoints. -# This option eliminates the IP permissions check on +# This option eliminates the IP permissions check on # the packets incoming to the relay endpoints. # #server-relay diff --git a/examples/etc/turnserver.conf b/examples/etc/turnserver.conf index 515ed131..3af6845c 100644 --- a/examples/etc/turnserver.conf +++ b/examples/etc/turnserver.conf @@ -1,25 +1,25 @@ # Coturn TURN SERVER configuration file # # Boolean values note: where a boolean value is supposed to be used, -# you can use '0', 'off', 'no', 'false', or 'f' as 'false, -# and you can use '1', 'on', 'yes', 'true', or 't' as 'true' +# you can use '0', 'off', 'no', 'false', or 'f' as 'false, +# and you can use '1', 'on', 'yes', 'true', or 't' as 'true' # If the value is missing, then it means 'true' by default. # # Listener interface device (optional, Linux only). -# NOT RECOMMENDED. +# NOT RECOMMENDED. # #listening-device=eth0 # TURN listener port for UDP and TCP (Default: 3478). -# Note: actually, TLS & DTLS sessions can connect to the +# Note: actually, TLS & DTLS sessions can connect to the # "plain" TCP & UDP port(s), too - if allowed by configuration. # #listening-port=3478 # TURN listener port for TLS (Default: 5349). # Note: actually, "plain" TCP & UDP sessions can connect to the TLS & DTLS -# port(s), too - if allowed by configuration. The TURN server +# port(s), too - if allowed by configuration. The TURN server # "automatically" recognizes the type of traffic. Actually, two listening # endpoints (the "plain" one and the "tls" one) are equivalent in terms of # functionality; but Coturn keeps both endpoints to satisfy the RFC 5766 specs. @@ -30,16 +30,16 @@ #tls-listening-port=5349 # Alternative listening port for UDP and TCP listeners; -# default (or zero) value means "listening port plus one". +# default (or zero) value means "listening port plus one". # This is needed for RFC 5780 support -# (STUN extension specs, NAT behavior discovery). The TURN Server -# supports RFC 5780 only if it is started with more than one +# (STUN extension specs, NAT behavior discovery). The TURN Server +# supports RFC 5780 only if it is started with more than one # listening IP address of the same family (IPv4 or IPv6). # RFC 5780 is supported only by UDP protocol, other protocols # are listening to that endpoint only for "symmetry". # #alt-listening-port=0 - + # Alternative listening port for TLS and DTLS protocols. # Default (or zero) value means "TLS listening port plus one". # @@ -52,9 +52,9 @@ # (https://www.haproxy.org/download/1.8/doc/proxy-protocol.txt) # #tcp-proxy-port=5555 - + # Listener IP address of relay server. Multiple listeners can be specified. -# If no IP(s) specified in the config file or in the command line options, +# If no IP(s) specified in the config file or in the command line options, # then all IPv4 and IPv6 system IPs will be used for listening. # #listening-ip=172.17.19.101 @@ -69,7 +69,7 @@ # they do not support STUN RFC 5780 functionality (CHANGE REQUEST). # # 2) Auxiliary servers also are never returning ALTERNATIVE-SERVER reply. -# +# # Valid formats are 1.2.3.4:5555 for IPv4 and [1:2::3:4]:5555 for IPv6. # # There may be multiple aux-server options, each will be used for listening @@ -81,7 +81,7 @@ # (recommended for older Linuxes only) # Automatically balance UDP traffic over auxiliary servers (if configured). # The load balancing is using the ALTERNATE-SERVER mechanism. -# The TURN client must support 300 ALTERNATE-SERVER response for this +# The TURN client must support 300 ALTERNATE-SERVER response for this # functionality. # #udp-self-balance @@ -91,13 +91,13 @@ # #relay-device=eth1 -# Relay address (the local IP address that will be used to relay the +# Relay address (the local IP address that will be used to relay the # packets to the peer). # Multiple relay addresses may be used. # The same IP(s) can be used as both listening IP(s) and relay IP(s). # # If no relay IP(s) specified, then the turnserver will apply the default -# policy: it will decide itself which relay addresses to be used, and it +# policy: it will decide itself which relay addresses to be used, and it # will always be using the client socket IP address as the relay IP address # of the TURN session (if the requested relay address family is the same # as the family of the client socket). @@ -120,7 +120,7 @@ # that option must be used several times, each entry must # have form "-X ", to map all involved addresses. # RFC5780 NAT discovery STUN functionality will work correctly, -# if the addresses are mapped properly, even when the TURN server itself +# if the addresses are mapped properly, even when the TURN server itself # is behind A NAT. # # By default, this value is empty, and no address mapping is used. @@ -135,18 +135,18 @@ # Number of the relay threads to handle the established connections # (in addition to authentication thread and the listener thread). -# If explicitly set to 0 then application runs relay process in a -# single thread, in the same thread with the listener process +# If explicitly set to 0 then application runs relay process in a +# single thread, in the same thread with the listener process # (the authentication thread will still be a separate thread). # -# If this parameter is not set, then the default OS-dependent +# If this parameter is not set, then the default OS-dependent # thread pattern algorithm will be employed. Usually the default # algorithm is optimal, so you have to change this option -# if you want to make some fine tweaks. +# if you want to make some fine tweaks. # # In the older systems (Linux kernel before 3.9), # the number of UDP threads is always one thread per network listening -# endpoint - including the auxiliary endpoints - unless 0 (zero) or +# endpoint - including the auxiliary endpoints - unless 0 (zero) or # 1 (one) value is set. # #relay-threads=0 @@ -156,15 +156,15 @@ # #min-port=49152 #max-port=65535 - + # Uncomment to run TURN server in 'normal' 'moderate' verbose mode. # By default the verbose mode is off. #verbose - + # Uncomment to run TURN server in 'extra' verbose mode. # This mode is very annoying and produces lots of output. # Not recommended under normal circumstances. -# +# #Verbose # Uncomment to use fingerprints in the TURN messages. @@ -177,10 +177,10 @@ # #lt-cred-mech -# This option is the opposite of lt-cred-mech. +# This option is the opposite of lt-cred-mech. # (TURN Server with no-auth option allows anonymous access). # If neither option is defined, and no users are defined, -# then no-auth is default. If at least one user is defined, +# then no-auth is default. If at least one user is defined, # in this file, in command line or in usersdb file, then # lt-cred-mech is default. # @@ -203,11 +203,11 @@ # Flag that sets a special authorization option that is based upon authentication secret. # # This feature's purpose is to support "TURN Server REST API", see -# "TURN REST API" link in the project's page +# "TURN REST API" link in the project's page # https://github.com/coturn/coturn/ # # This option is used with timestamp: -# +# # usercombo -> "timestamp:userid" # turn user -> usercombo # turn password -> base64(hmac(secret key, usercombo)) @@ -217,7 +217,7 @@ # This option is enabled by turning on secret-based authentication. # The actual value of the secret is defined either by the option static-auth-secret, # or can be found in the turn_secret table in the database (see below). -# +# # Read more about it: # - https://tools.ietf.org/html/draft-uberti-behave-turn-rest-00 # - https://www.ietf.org/proceedings/87/slides/slides-87-behave-10.pdf @@ -229,13 +229,13 @@ # # Note that you can use only one auth mechanism at the same time! This is because, # both mechanisms conduct username and password validation in different ways. -# +# # Use either lt-cred-mech or use-auth-secret in the conf # to avoid any confusion. # #use-auth-secret -# 'Static' authentication secret value (a string) for TURN REST API only. +# 'Static' authentication secret value (a string) for TURN REST API only. # If not set, then the turn server # will try to use the 'dynamic' value in the turn_secret table # in the user database (if present). The database-stored value can be changed on-the-fly @@ -255,7 +255,7 @@ # 'Static' user accounts for the long term credentials mechanism, only. # This option cannot be used with TURN REST API. -# 'Static' user accounts are NOT dynamically checked by the turnserver process, +# 'Static' user accounts are NOT dynamically checked by the turnserver process, # so they can NOT be changed while the turnserver is running. # #user=username1:key1 @@ -274,7 +274,7 @@ # password. If it has 0x then it is a key, otherwise it is a password). # # The corresponding user account entry in the config file will be: -# +# #user=ninefingers:0xbc807ee29df3c9ffa736523fb2c4e8ee # Or, equivalently, with open clear password (less secure): #user=ninefingers:youhavetoberealistic @@ -284,15 +284,15 @@ # # The default file name is /var/db/turndb or /usr/local/var/db/turndb or # /var/lib/turn/turndb. -# +# #userdb=/var/db/turndb # PostgreSQL database connection string in the case that you are using PostgreSQL # as the user database. # This database can be used for the long-term credential mechanism -# and it can store the secret value for secret-based timed authentication in TURN REST API. +# and it can store the secret value for secret-based timed authentication in TURN REST API. # See http://www.postgresql.org/docs/8.4/static/libpq-connect.html for 8.x PostgreSQL -# versions connection string format, see +# versions connection string format, see # http://www.postgresql.org/docs/9.2/static/libpq-connect.html#LIBPQ-CONNSTRING # for 9.x and newer connection string formats. # @@ -303,9 +303,9 @@ # This database can be used for the long-term credential mechanism # and it can store the secret value for secret-based timed authentication in TURN REST API. # -# Optional connection string parameters for the secure communications (SSL): -# ca, capath, cert, key, cipher -# (see http://dev.mysql.com/doc/refman/5.1/en/ssl-options.html for the +# Optional connection string parameters for the secure communications (SSL): +# ca, capath, cert, key, cipher +# (see http://dev.mysql.com/doc/refman/5.1/en/ssl-options.html for the # command options description). # # Use the string format below (space separated parameters, all optional): @@ -315,7 +315,7 @@ # If you want to use an encrypted password in the MySQL connection string, # then set the MySQL password encryption secret key file with this option. # -# Warning: If this option is set, then the mysql password must be set in "mysql-userdb" in an encrypted format! +# Warning: If this option is set, then the mysql password must be set in "mysql-userdb" in an encrypted format! # If you want to use a cleartext password then do not set this option! # # This is the file path for the aes encrypted secret key used for password encryption. @@ -325,7 +325,7 @@ # MongoDB database connection string in the case that you are using MongoDB # as the user database. # This database can be used for long-term credential mechanism -# and it can store the secret value for secret-based timed authentication in TURN REST API. +# and it can store the secret value for secret-based timed authentication in TURN REST API. # Use the string format described at http://hergert.me/docs/mongo-c-driver/mongoc_uri.html # #mongo-userdb="mongodb://[username:password@]host1[:port1][,host2[:port2],...[,hostN[:portN]]][/[database][?options]]" @@ -333,7 +333,7 @@ # Redis database connection string in the case that you are using Redis # as the user database. # This database can be used for long-term credential mechanism -# and it can store the secret value for secret-based timed authentication in TURN REST API. +# and it can store the secret value for secret-based timed authentication in TURN REST API. # Use the string format below (space separated parameters, all optional): # #redis-userdb="ip= dbname= password= port= connect_timeout=" @@ -341,15 +341,15 @@ # Redis status and statistics database connection string, if used (default - empty, no Redis stats DB used). # This database keeps allocations status information, and it can be also used for publishing # and delivering traffic and allocation event notifications. -# The connection string has the same parameters as redis-userdb connection string. +# The connection string has the same parameters as redis-userdb connection string. # Use the string format below (space separated parameters, all optional): # #redis-statsdb="ip= dbname= password= port= connect_timeout=" -# The default realm to be used for the users when no explicit +# The default realm to be used for the users when no explicit # origin/realm relationship is found in the database, or if the TURN # server is not using any database (just the commands-line settings -# and the userdb file). Must be used with long-term credentials +# and the userdb file). Must be used with long-term credentials # mechanism or with TURN REST API. # # Note: If the default realm is not specified, then realm falls back to the host domain name. @@ -357,7 +357,7 @@ # #realm=mycompany.org -# This flag sets the origin consistency +# This flag sets the origin consistency # check. Across the session, all requests must have the same # main ORIGIN attribute value (if the ORIGIN was # initially used by the session). @@ -424,9 +424,9 @@ # Uncomment if extra security is desired, # with nonce value having a limited lifetime. # By default, the nonce value is unique for a session, -# and has an unlimited lifetime. -# Set this option to limit the nonce lifetime. -# It defaults to 600 secs (10 min) if no value is provided. After that delay, +# and has an unlimited lifetime. +# Set this option to limit the nonce lifetime. +# It defaults to 600 secs (10 min) if no value is provided. After that delay, # the client will get 438 error and will have to re-authenticate itself. # #stale-nonce=600 @@ -452,14 +452,14 @@ #permission-lifetime=300 # Certificate file. -# Use an absolute path or path relative to the +# Use an absolute path or path relative to the # configuration file. # Use PEM file format. # #cert=/usr/local/etc/turn_server_cert.pem # Private key file. -# Use an absolute path or path relative to the +# Use an absolute path or path relative to the # configuration file. # Use PEM file format. # @@ -475,7 +475,7 @@ # #cipher-list="DEFAULT" -# CA file in OpenSSL format. +# CA file in OpenSSL format. # Forces TURN server to verify the client SSL certificates. # By default this is not set: there is no default value and the client # certificate is not checked. @@ -483,8 +483,8 @@ # Example: #CA-file=/etc/ssh/id_rsa.cert -# Curve name for EC ciphers, if supported by OpenSSL -# library (TLS and DTLS). The default value is prime256v1, +# Curve name for EC ciphers, if supported by OpenSSL +# library (TLS and DTLS). The default value is prime256v1, # if pre-OpenSSL 1.0.2 is used. With OpenSSL 1.0.2+, # an optimal curve will be automatically calculated, if not defined # by this option. @@ -505,21 +505,21 @@ #dh-file= # Flag to prevent stdout log messages. -# By default, all log messages go to both stdout and to -# the configured log file. With this option everything will +# By default, all log messages go to both stdout and to +# the configured log file. With this option everything will # go to the configured log only (unless the log file itself is stdout). # #no-stdout-log # Option to set the log file name. -# By default, the turnserver tries to open a log file in +# By default, the turnserver tries to open a log file in # /var/log, /var/tmp, /tmp and the current directory # (Whichever file open operation succeeds first will be used). # With this option you can set the definite log file name. -# The special names are "stdout" and "-" - they will force everything +# The special names are "stdout" and "-" - they will force everything # to the stdout. Also, the "syslog" name will force everything to -# the system log (syslog). -# In the runtime, the logfile can be reset with the SIGHUP signal +# the system log (syslog). +# In the runtime, the logfile can be reset with the SIGHUP signal # to the turnserver process. # #log-file=/var/tmp/turn.log @@ -535,40 +535,40 @@ #simple-log # Option to set the "redirection" mode. The value of this option -# will be the address of the alternate server for UDP & TCP service in the form of +# will be the address of the alternate server for UDP & TCP service in the form of # [:]. The server will send this value in the attribute # ALTERNATE-SERVER, with error 300, on ALLOCATE request, to the client. # Client will receive only values with the same address family -# as the client network endpoint address family. -# See RFC 5389 and RFC 5766 for the description of ALTERNATE-SERVER functionality. +# as the client network endpoint address family. +# See RFC 5389 and RFC 5766 for the description of ALTERNATE-SERVER functionality. # The client must use the obtained value for subsequent TURN communications. # If more than one --alternate-server option is provided, then the functionality -# can be more accurately described as "load-balancing" than a mere "redirection". -# If the port number is omitted, then the default port +# can be more accurately described as "load-balancing" than a mere "redirection". +# If the port number is omitted, then the default port # number 3478 for the UDP/TCP protocols will be used. -# Colon (:) characters in IPv6 addresses may conflict with the syntax of -# the option. To alleviate this conflict, literal IPv6 addresses are enclosed -# in square brackets in such resource identifiers, for example: -# [2001:db8:85a3:8d3:1319:8a2e:370:7348]:3478 . +# Colon (:) characters in IPv6 addresses may conflict with the syntax of +# the option. To alleviate this conflict, literal IPv6 addresses are enclosed +# in square brackets in such resource identifiers, for example: +# [2001:db8:85a3:8d3:1319:8a2e:370:7348]:3478 . # Multiple alternate servers can be set. They will be used in the -# round-robin manner. All servers in the pool are considered of equal weight and -# the load will be distributed equally. For example, if you have 4 alternate servers, -# then each server will receive 25% of ALLOCATE requests. A alternate TURN server -# address can be used more than one time with the alternate-server option, so this +# round-robin manner. All servers in the pool are considered of equal weight and +# the load will be distributed equally. For example, if you have 4 alternate servers, +# then each server will receive 25% of ALLOCATE requests. A alternate TURN server +# address can be used more than one time with the alternate-server option, so this # can emulate "weighting" of the servers. # -# Examples: +# Examples: #alternate-server=1.2.3.4:5678 #alternate-server=11.22.33.44:56789 #alternate-server=5.6.7.8 #alternate-server=[2001:db8:85a3:8d3:1319:8a2e:370:7348]:3478 - -# Option to set alternative server for TLS & DTLS services in form of -# :. If the port number is omitted, then the default port -# number 5349 for the TLS/DTLS protocols will be used. See the previous + +# Option to set alternative server for TLS & DTLS services in form of +# :. If the port number is omitted, then the default port +# number 5349 for the TLS/DTLS protocols will be used. See the previous # option for the functionality description. # -# Examples: +# Examples: #tls-alternate-server=1.2.3.4:5678 #tls-alternate-server=11.22.33.44:56789 #tls-alternate-server=[2001:db8:85a3:8d3:1319:8a2e:370:7348]:3478 @@ -596,7 +596,7 @@ # This is the timestamp/username separator symbol (character) in TURN REST API. # The default value is ':'. -# rest-api-separator=: +# rest-api-separator=: # Flag that can be used to allow peers on the loopback addresses (127.x.x.x and ::1). # This is an extra security measure. @@ -604,9 +604,9 @@ # (To avoid any security issue that allowing loopback access may raise, # the no-loopback-peers option is replaced by allow-loopback-peers.) # -# Allow it only for testing in a development environment! -# In production it adds a possible security vulnerability, so for security reasons -# it is not allowed using it together with empty cli-password. +# Allow it only for testing in a development environment! +# In production it adds a possible security vulnerability, so for security reasons +# it is not allowed using it together with empty cli-password. # #allow-loopback-peers @@ -615,18 +615,18 @@ # #no-multicast-peers -# Option to set the max time, in seconds, allowed for full allocation establishment. +# Option to set the max time, in seconds, allowed for full allocation establishment. # Default is 60 seconds. # #max-allocate-timeout=60 -# Option to allow or ban specific ip addresses or ranges of ip addresses. -# If an ip address is specified as both allowed and denied, then the ip address is -# considered to be allowed. This is useful when you wish to ban a range of ip +# Option to allow or ban specific ip addresses or ranges of ip addresses. +# If an ip address is specified as both allowed and denied, then the ip address is +# considered to be allowed. This is useful when you wish to ban a range of ip # addresses, except for a few specific ips within that range. # # This can be used when you do not want users of the turn server to be able to access -# machines reachable by the turn server, but would otherwise be unreachable from the +# machines reachable by the turn server, but would otherwise be unreachable from the # internet (e.g. when the turn server is sitting behind a NAT) # # Examples: @@ -648,8 +648,8 @@ # #mobility -# Allocate Address Family according -# If enabled then TURN server allocates address family according the TURN +# Allocate Address Family according +# If enabled then TURN server allocates address family according the TURN # Client <=> Server communication address family. # (By default Coturn works according RFC 6156.) # !!Warning: Enabling this option breaks RFC6156 section-4.2 (violates use default IPv4)!! @@ -713,10 +713,10 @@ # #web-admin-listen-on-workers -# Server relay. NON-STANDARD AND DANGEROUS OPTION. -# Only for those applications when you want to run +# Server relay. NON-STANDARD AND DANGEROUS OPTION. +# Only for those applications when you want to run # server applications on the relay endpoints. -# This option eliminates the IP permissions check on +# This option eliminates the IP permissions check on # the packets incoming to the relay endpoints. # #server-relay From a83bffd9426baf033b57ea01261b712a3e5480df Mon Sep 17 00:00:00 2001 From: Robert Tupelo-Schneck Date: Fri, 30 Oct 2020 12:34:31 -0400 Subject: [PATCH 14/55] Allow RFC6062 TCP relay data to look like TLS; fixes #605 --- src/apps/relay/ns_ioalib_engine_impl.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/apps/relay/ns_ioalib_engine_impl.c b/src/apps/relay/ns_ioalib_engine_impl.c index ba1e387f..de31bf42 100644 --- a/src/apps/relay/ns_ioalib_engine_impl.c +++ b/src/apps/relay/ns_ioalib_engine_impl.c @@ -3374,7 +3374,7 @@ int register_callback_on_ioa_socket(ioa_engine_handle e, ioa_socket_handle s, in } } else { #if TLS_SUPPORTED - if(check_tentative_tls(s->fd)) { + if((s->sat != TCP_CLIENT_DATA_SOCKET) && (s->sat != TCP_RELAY_DATA_SOCKET) && check_tentative_tls(s->fd)) { s->tobeclosed = 1; return -1; } From c00d69e67f7161ab96b5df4fa35970d44bad3e0e Mon Sep 17 00:00:00 2001 From: Peter Linss Date: Wed, 18 Nov 2020 16:43:24 -0800 Subject: [PATCH 15/55] Add support for proxy protocol V1 --- src/apps/relay/ns_ioalib_engine_impl.c | 107 ++++++++++++++++++++++++- 1 file changed, 106 insertions(+), 1 deletion(-) diff --git a/src/apps/relay/ns_ioalib_engine_impl.c b/src/apps/relay/ns_ioalib_engine_impl.c index ba1e387f..2eb1b30b 100644 --- a/src/apps/relay/ns_ioalib_engine_impl.c +++ b/src/apps/relay/ns_ioalib_engine_impl.c @@ -2166,6 +2166,101 @@ static TURN_TLS_TYPE check_tentative_tls(ioa_socket_raw fd) } #endif + +static size_t proxy_string_field(char *field, size_t max, uint8_t *buf, size_t index, size_t len) +{ + size_t count = 0; + while((index < len) && (count < max)) { + if((0x20 == buf[index]) || (0x0D == buf[index])) { + field[count] = 0x00; + return ++index; + } + field[count++] = buf[index++]; + } + return 0; +} + +static ssize_t socket_parse_proxy_v1(ioa_socket_handle s, uint8_t *buf, size_t len) +{ + if(len < 11) { + return 0 ; + } + + /* Check for proxy-v1 magic field */ + char magic[] = {0x50, 0x52, 0x4F, 0x58, 0x59, 0x20}; + if(memcmp(magic, buf, sizeof(magic))) { + return -1; + } + + /* Read family */ + char tcp4[] = {0x54, 0x43, 0x50, 0x34, 0x20}; + char tcp6[] = {0x54, 0x43, 0x50, 0x36, 0x20}; + int family; + if(0 == memcmp(tcp4, &buf[6], sizeof(tcp4))) { /* IPv4 */ + family = AF_INET; + } else if(0 == memcmp(tcp6, &buf[6], sizeof(tcp6))) { /* IPv6 */ + family = AF_INET6; + } else { + return -1; + } + + char saddr[40]; + char daddr[40]; + char sport[6]; + char dport[6]; + + size_t tlen = 11; + /* Read source address */ + tlen = proxy_string_field(saddr, sizeof(saddr), buf, tlen, len); + if(0 == tlen) return -1; + + /* Read dest address */ + tlen = proxy_string_field(daddr, sizeof(daddr), buf, tlen, len); + if(0 == tlen) return -1; + + /* Read source port */ + tlen = proxy_string_field(sport, sizeof(sport), buf, tlen, len); + if(0 == tlen) return -1; + + /* Read dest port */ + tlen = proxy_string_field(dport, sizeof(dport), buf, tlen, len); + if(0 == tlen) return -1; + + /* Final line feed */ + if ((len <= tlen) || (0x0A != buf[tlen])) return -1; + + tlen++; + + int sport_int = atoi(sport); + int dport_int = atoi(dport); + if((sport_int < 0) || (0xFFFF < sport_int)) return -1; + if((dport_int < 0) || (0xFFFF < dport_int)) return -1; + + if (AF_INET == family) { + struct sockaddr_in remote, local; + remote.sin_family = local.sin_family = AF_INET; + if(1 != inet_pton(AF_INET, saddr, &remote.sin_addr.s_addr)) return -1; + if(1 != inet_pton(AF_INET, daddr, &local.sin_addr.s_addr)) return -1; + remote.sin_port = htons((uint16_t)sport_int); + local.sin_port = htons((uint16_t)dport_int); + + addr_cpy4(&(s->local_addr), &local); + addr_cpy4(&(s->remote_addr), &remote); + + } else { + struct sockaddr_in6 remote, local; + remote.sin6_family = local.sin6_family = AF_INET6; + if(1 != inet_pton(AF_INET6, saddr, &remote.sin6_addr.s6_addr)) return -1; + if(1 != inet_pton(AF_INET6, daddr, &local.sin6_addr.s6_addr)) return -1; + remote.sin6_port = htons((uint16_t)sport_int); + local.sin6_port = htons((uint16_t)dport_int); + + addr_cpy6(&(s->local_addr), &local); + addr_cpy6(&(s->remote_addr), &remote); + } + return tlen; +} + static ssize_t socket_parse_proxy_v2(ioa_socket_handle s, uint8_t *buf, size_t len) { if(len < 16){ @@ -2227,6 +2322,16 @@ static ssize_t socket_parse_proxy_v2(ioa_socket_handle s, uint8_t *buf, size_t l return tlen; } +static ssize_t socket_parse_proxy(ioa_socket_handle s, uint8_t *buf, size_t len) +{ + ssize_t tlen = socket_parse_proxy_v2(s, buf, len); + if(-1 == tlen) { + tlen = socket_parse_proxy_v1(s, buf, len); + } + + return tlen; +} + static int socket_input_worker(ioa_socket_handle s) { int len = 0; @@ -2450,7 +2555,7 @@ static int socket_input_worker(ioa_socket_handle s) blen=(ev_ssize_t)STUN_BUFFER_SIZE; if(s->st == TCP_SOCKET_PROXY){ - ssize_t tlen = socket_parse_proxy_v2(s, buf_elem->buf.buf, blen); + ssize_t tlen = socket_parse_proxy(s, buf_elem->buf.buf, blen); blen = 0; if (tlen < 0){ s->tobeclosed = 1; From 3b3c5849cc276da9447287a1548a1f63bc0265e3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?M=C3=A9sz=C3=A1ros=20Mih=C3=A1ly?= Date: Mon, 7 Dec 2020 15:26:00 +0100 Subject: [PATCH 16/55] bump version --- examples/scripts/pack.sh | 2 +- rpm/build.settings.sh | 2 +- rpm/turnserver.spec | 2 +- src/ns_turn_defs.h | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/examples/scripts/pack.sh b/examples/scripts/pack.sh index d86f10df..4d3cc98e 100755 --- a/examples/scripts/pack.sh +++ b/examples/scripts/pack.sh @@ -2,7 +2,7 @@ # Run it from the root of the coturn source tree -V=4.5.1.3 +V=4.5.2 PACKDIR=`pwd`/../coturn-releases/ SRCDIR=`pwd` diff --git a/rpm/build.settings.sh b/rpm/build.settings.sh index 19a39c12..7d3397af 100755 --- a/rpm/build.settings.sh +++ b/rpm/build.settings.sh @@ -2,7 +2,7 @@ # Common settings script. -TURNVERSION=4.5.1.3 +TURNVERSION=4.5.2 BUILDDIR=~/rpmbuild ARCH=`uname -p` diff --git a/rpm/turnserver.spec b/rpm/turnserver.spec index e6748ede..09ea214b 100644 --- a/rpm/turnserver.spec +++ b/rpm/turnserver.spec @@ -1,5 +1,5 @@ Name: turnserver -Version: 4.5.1.3 +Version: 4.5.2 Release: 0%{dist} Summary: Coturn TURN Server diff --git a/src/ns_turn_defs.h b/src/ns_turn_defs.h index a3f45bf5..336e0485 100644 --- a/src/ns_turn_defs.h +++ b/src/ns_turn_defs.h @@ -31,7 +31,7 @@ #ifndef __IOADEFS__ #define __IOADEFS__ -#define TURN_SERVER_VERSION "4.5.1.3" +#define TURN_SERVER_VERSION "4.5.2" #define TURN_SERVER_VERSION_NAME "dan Eider" #define TURN_SOFTWARE "Coturn-" TURN_SERVER_VERSION " '" TURN_SERVER_VERSION_NAME "'" From 2bc61f483e503fa8cd48066e085233830dc43897 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?M=C3=A9sz=C3=A1ros=20Mih=C3=A1ly?= Date: Mon, 7 Dec 2020 15:26:40 +0100 Subject: [PATCH 17/55] Add changelog to merged PRs --- ChangeLog | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/ChangeLog b/ChangeLog index 1ac72709..04e133d2 100644 --- a/ChangeLog +++ b/ChangeLog @@ -3,6 +3,13 @@ Version 4.5.2 'dan Eider': - fix null pointer dereference in case of out of memory. (thanks to Thomas Moeller for the report) - merge PR #517 (by wolmi) * add prometheus metrics + - merge PR #637 (by David Florness) + * Delete trailing whitespace in example configuration files + - merge PR #631 (by Debabrata Deka) + * Add architecture ppc64le to travis build + - merge PR #627 (by Samuel) + * Fix misleading option in doc (prometheus) + 24/06/2020 Oleg Moskalenko Mihály Mészáros Version 4.5.1.3 'dan Eider': - merge PR #575: (by osterik) From 29d5c66263510c2f907d765e99f9a02cc690180e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?M=C3=A9sz=C3=A1ros=20Mih=C3=A1ly?= Date: Mon, 7 Dec 2020 15:28:05 +0100 Subject: [PATCH 18/55] Update man after README change --- man/man1/turnadmin.1 | 2 +- man/man1/turnserver.1 | 8 ++++---- man/man1/turnutils.1 | 2 +- 3 files changed, 6 insertions(+), 6 deletions(-) diff --git a/man/man1/turnadmin.1 b/man/man1/turnadmin.1 index 5ef28f7a..2faea944 100644 --- a/man/man1/turnadmin.1 +++ b/man/man1/turnadmin.1 @@ -1,5 +1,5 @@ .\" Text automatically generated by txt2man -.TH TURN 1 "03 August 2020" "" "" +.TH TURN 1 "07 December 2020" "" "" .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 5b19c10f..b7fe4a15 100644 --- a/man/man1/turnserver.1 +++ b/man/man1/turnserver.1 @@ -1,5 +1,5 @@ .\" Text automatically generated by txt2man -.TH TURN 1 "03 August 2020" "" "" +.TH TURN 1 "07 December 2020" "" "" .SH GENERAL INFORMATION The \fBTURN Server\fP project contains the source code of a TURN server and TURN client @@ -400,9 +400,9 @@ initially used by the session). .RS .TP .B -\fB\-\-no\-prometheus\fP -Disable prometheus metrics. By default it is -enabled and listening on port 9641 unther the path /metrics +\fB\-\-prometheus\fP +Enable prometheus metrics. By default it is +disabled. Would listen on port 9641 unther the path /metrics also the path / on this port can be used as a health check .RE .TP diff --git a/man/man1/turnutils.1 b/man/man1/turnutils.1 index d379b923..e6d0e9c7 100644 --- a/man/man1/turnutils.1 +++ b/man/man1/turnutils.1 @@ -1,5 +1,5 @@ .\" Text automatically generated by txt2man -.TH TURN 1 "03 August 2020" "" "" +.TH TURN 1 "07 December 2020" "" "" .SH GENERAL INFORMATION A set of turnutils_* programs provides some utility functionality to be used From 032d35271638e69eadfc9a679dd5b7d73374d40d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?M=C3=A9sz=C3=A1ros=20Mih=C3=A1ly?= Date: Tue, 8 Dec 2020 08:35:07 +0100 Subject: [PATCH 19/55] Changelog for PR#643 --- ChangeLog | 2 ++ 1 file changed, 2 insertions(+) diff --git a/ChangeLog b/ChangeLog index 04e133d2..ae6cd83d 100644 --- a/ChangeLog +++ b/ChangeLog @@ -9,6 +9,8 @@ Version 4.5.2 'dan Eider': * Add architecture ppc64le to travis build - merge PR #627 (by Samuel) * Fix misleading option in doc (prometheus) + - merge PR #643 (by tupelo-schneck) + * Allow RFC6062 TCP relay data to look like TLS 24/06/2020 Oleg Moskalenko Mihály Mészáros Version 4.5.1.3 'dan Eider': From b13cc41a825809c7f2d147bc293c58b161b23a05 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?M=C3=A9sz=C3=A1ros=20Mih=C3=A1ly?= Date: Tue, 8 Dec 2020 08:49:51 +0100 Subject: [PATCH 20/55] Add to changelog PR #655 #618 #599 --- ChangeLog | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/ChangeLog b/ChangeLog index ae6cd83d..2a10aa16 100644 --- a/ChangeLog +++ b/ChangeLog @@ -8,9 +8,15 @@ Version 4.5.2 'dan Eider': - merge PR #631 (by Debabrata Deka) * Add architecture ppc64le to travis build - merge PR #627 (by Samuel) - * Fix misleading option in doc (prometheus) + * Fix misleading option in doc (prometheus) - merge PR #643 (by tupelo-schneck) - * Allow RFC6062 TCP relay data to look like TLS + * Allow RFC6062 TCP relay data to look like TLS + - merge PR #655 (by plinss) + * Add support for proxy protocol V1 + - merge PR #618 (by Paul Wayper) + * Print full date and time in logs + - merge PR #599 (by Cédric Krier) + * Do not use FIPS and remove hardcode OPENSSL_VERSION_NUMBER with LibreSSL 24/06/2020 Oleg Moskalenko Mihály Mészáros Version 4.5.1.3 'dan Eider': From 9c354943515fb52eb6bccf2b6debff98d30ad391 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?M=C3=A9sz=C3=A1ros=20Mih=C3=A1ly?= Date: Tue, 8 Dec 2020 09:37:45 +0100 Subject: [PATCH 21/55] Update Docker MongoDB libs and fix systemctl --- ChangeLog | 1 + docker/coturn/Dockerfile | 9 ++++++--- 2 files changed, 7 insertions(+), 3 deletions(-) diff --git a/ChangeLog b/ChangeLog index 2a10aa16..3bdf5a6f 100644 --- a/ChangeLog +++ b/ChangeLog @@ -17,6 +17,7 @@ Version 4.5.2 'dan Eider': * Print full date and time in logs - merge PR #599 (by Cédric Krier) * Do not use FIPS and remove hardcode OPENSSL_VERSION_NUMBER with LibreSSL + - update Docker mongoDB and fix with workaround the missing systemctl 24/06/2020 Oleg Moskalenko Mihály Mészáros Version 4.5.1.3 'dan Eider': diff --git a/docker/coturn/Dockerfile b/docker/coturn/Dockerfile index b8fd207f..0a18362b 100644 --- a/docker/coturn/Dockerfile +++ b/docker/coturn/Dockerfile @@ -34,14 +34,17 @@ COPY --from=coturn-build ${BUILD_PREFIX}/coturn/turndb ${INSTALL_PREFIX}/turndb # Install lib dependencies RUN export DEBIAN_FRONTEND=noninteractive && \ apt-get update && \ - apt-get install -y libc6>=2.15 libevent-core-2.1-6>=libevent-core-2.1-6 libevent-extra-2.1-6>=2.1.8-stable-4 libevent-openssl-2.1-6>=2.1.8-stable-4 libevent-pthreads-2.1-6>=2.1.8-stable-4 libhiredis0.14>=0.14.0 libmariadbclient-dev>=10.3.17 libpq5>=8.4~ libsqlite3-0>=3.6.0 libssl1.1>=1.1.0 libmongoc-1.0 libbson-1.0 + apt-get install -y libc6 libevent-core-2.1-6 libevent-extra-2.1-6 libevent-openssl-2.1-6 libevent-pthreads-2.1-6 libhiredis0.14 libmariadbclient-dev libpq5 libsqlite3-0 libssl1.1 libmongoc-1.0-0 libbson-1.0-0 RUN apt-get install -y default-mysql-client postgresql-client redis-tools +# Workaround for MongoDB +RUN ln -s /bin/echo /bin/systemctl + # Install MongoDB RUN apt-get update && \ apt-get install -y wget gnupg && \ - wget -qO - https://www.mongodb.org/static/pgp/server-4.0.asc | apt-key add - && \ - echo "deb http://repo.mongodb.org/apt/debian stretch/mongodb-org/4.0 main" | tee /etc/apt/sources.list.d/mongodb-org-4.0.list && \ + wget -qO - https://www.mongodb.org/static/pgp/server-4.4.asc | apt-key add - && \ + echo "deb http://repo.mongodb.org/apt/debian stretch/mongodb-org/4.4 main" | tee /etc/apt/sources.list.d/mongodb-org-4.4.list && \ echo "deb http://deb.debian.org/debian/ stretch main" | tee /etc/apt/sources.list.d/debian-stretch.list && \ apt-get update && \ apt-get install -y libcurl3 mongodb-org mongodb-org-server mongodb-org From 3c7021979872fb1c3e16d841c172fa2778135ded Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?M=C3=A9sz=C3=A1ros=20Mih=C3=A1ly?= Date: Tue, 8 Dec 2020 09:45:56 +0100 Subject: [PATCH 22/55] Fix docker lint warn: workdir need to be absolute --- docker/coturn/Dockerfile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docker/coturn/Dockerfile b/docker/coturn/Dockerfile index 0a18362b..fc109980 100644 --- a/docker/coturn/Dockerfile +++ b/docker/coturn/Dockerfile @@ -13,7 +13,7 @@ WORKDIR ${BUILD_PREFIX} RUN git clone https://github.com/coturn/coturn.git # Build Coturn -WORKDIR coturn +WORKDIR ${BUILD_PREFIX}/coturn RUN ./configure RUN make From 50f789ab5ad4ac5b7db2eb977de8ceabeea22065 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?M=C3=A9sz=C3=A1ros=20Mih=C3=A1ly?= Date: Tue, 8 Dec 2020 10:44:40 +0100 Subject: [PATCH 23/55] Add new timestamp options to the README and man --- ChangeLog | 1 + README.turnserver | 4 ++++ man/man1/turnadmin.1 | 2 +- man/man1/turnserver.1 | 10 +++++++++- man/man1/turnutils.1 | 2 +- 5 files changed, 16 insertions(+), 3 deletions(-) diff --git a/ChangeLog b/ChangeLog index 3bdf5a6f..31fe1b79 100644 --- a/ChangeLog +++ b/ChangeLog @@ -15,6 +15,7 @@ Version 4.5.2 'dan Eider': * Add support for proxy protocol V1 - merge PR #618 (by Paul Wayper) * Print full date and time in logs + * Add new options: "new-log-timestamp" and "new-timestamp_format" - merge PR #599 (by Cédric Krier) * Do not use FIPS and remove hardcode OPENSSL_VERSION_NUMBER with LibreSSL - update Docker mongoDB and fix with workaround the missing systemctl diff --git a/README.turnserver b/README.turnserver index a5bf149a..4e773c1d 100644 --- a/README.turnserver +++ b/README.turnserver @@ -225,6 +225,10 @@ Flags: name will be constructed as-is, without PID and date appendage. This option can be used, for example, together with the logrotate tool. +--new-log-timestamp Enable full ISO-8601 timestamp in all logs. + +--new-timestamp_format Set timestamp format (in strftime(1) format) + --secure-stun Require authentication of the STUN Binding request. By default, the clients are allowed anonymous access to the STUN Binding functionality. diff --git a/man/man1/turnadmin.1 b/man/man1/turnadmin.1 index 2faea944..8fcdfd54 100644 --- a/man/man1/turnadmin.1 +++ b/man/man1/turnadmin.1 @@ -1,5 +1,5 @@ .\" Text automatically generated by txt2man -.TH TURN 1 "07 December 2020" "" "" +.TH TURN 1 "08 December 2020" "" "" .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 b7fe4a15..6a8941ef 100644 --- a/man/man1/turnserver.1 +++ b/man/man1/turnserver.1 @@ -1,5 +1,5 @@ .\" Text automatically generated by txt2man -.TH TURN 1 "07 December 2020" "" "" +.TH TURN 1 "08 December 2020" "" "" .SH GENERAL INFORMATION The \fBTURN Server\fP project contains the source code of a TURN server and TURN client @@ -338,6 +338,14 @@ name will be constructed as\-is, without PID and date appendage. This option can be used, for example, together with the logrotate tool. .TP .B +\fB\-\-new\-log\-timestamp\fP +Enable full ISO\-8601 timestamp in all logs. +.TP +.B +\fB\-\-new\-timestamp_format\fP + Set timestamp format (in \fBstrftime\fP(1) format) +.TP +.B \fB\-\-secure\-stun\fP Require authentication of the STUN Binding request. By default, the clients are allowed anonymous access to the STUN Binding functionality. diff --git a/man/man1/turnutils.1 b/man/man1/turnutils.1 index e6d0e9c7..24bcf6e0 100644 --- a/man/man1/turnutils.1 +++ b/man/man1/turnutils.1 @@ -1,5 +1,5 @@ .\" Text automatically generated by txt2man -.TH TURN 1 "07 December 2020" "" "" +.TH TURN 1 "08 December 2020" "" "" .SH GENERAL INFORMATION A set of turnutils_* programs provides some utility functionality to be used From 9a0d9d8c5da8665a80226164df650b2eb50e3749 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?M=C3=A9sz=C3=A1ros=20Mih=C3=A1ly?= Date: Tue, 8 Dec 2020 11:07:53 +0100 Subject: [PATCH 24/55] Replace new-timestamp_format=>new-timestamp-format --- ChangeLog | 2 +- README.turnserver | 2 +- man/man1/turnserver.1 | 2 +- src/apps/relay/mainrelay.c | 4 ++-- 4 files changed, 5 insertions(+), 5 deletions(-) diff --git a/ChangeLog b/ChangeLog index 31fe1b79..7c0acdbb 100644 --- a/ChangeLog +++ b/ChangeLog @@ -15,7 +15,7 @@ Version 4.5.2 'dan Eider': * Add support for proxy protocol V1 - merge PR #618 (by Paul Wayper) * Print full date and time in logs - * Add new options: "new-log-timestamp" and "new-timestamp_format" + * Add new options: "new-log-timestamp" and "new-timestamp-format" - merge PR #599 (by Cédric Krier) * Do not use FIPS and remove hardcode OPENSSL_VERSION_NUMBER with LibreSSL - update Docker mongoDB and fix with workaround the missing systemctl diff --git a/README.turnserver b/README.turnserver index 4e773c1d..0468a091 100644 --- a/README.turnserver +++ b/README.turnserver @@ -227,7 +227,7 @@ Flags: --new-log-timestamp Enable full ISO-8601 timestamp in all logs. ---new-timestamp_format Set timestamp format (in strftime(1) format) +--new-timestamp-format Set timestamp format (in strftime(1) format) --secure-stun Require authentication of the STUN Binding request. By default, the clients are allowed anonymous access to the STUN Binding functionality. diff --git a/man/man1/turnserver.1 b/man/man1/turnserver.1 index 6a8941ef..7464114b 100644 --- a/man/man1/turnserver.1 +++ b/man/man1/turnserver.1 @@ -342,7 +342,7 @@ This option can be used, for example, together with the logrotate tool. Enable full ISO\-8601 timestamp in all logs. .TP .B -\fB\-\-new\-timestamp_format\fP +\fB\-\-new\-timestamp\-format\fP Set timestamp format (in \fBstrftime\fP(1) format) .TP .B diff --git a/src/apps/relay/mainrelay.c b/src/apps/relay/mainrelay.c index d0134f28..ff357299 100644 --- a/src/apps/relay/mainrelay.c +++ b/src/apps/relay/mainrelay.c @@ -604,7 +604,7 @@ static char Usage[] = "Usage: turnserver [options]\n" " name will be constructed as-is, without PID and date appendage.\n" " This option can be used, for example, together with the logrotate tool.\n" " --new-log-timestamp Enable full ISO-8601 timestamp in all logs.\n" -" --new-timestamp_format Set timestamp format (in strftime(1) format)\n" +" --new-timestamp-format Set timestamp format (in strftime(1) format)\n" " --stale-nonce[=] Use extra security with nonce value having limited lifetime (default 600 secs).\n" " --max-allocate-lifetime Set the maximum value for the allocation lifetime. Default to 3600 secs.\n" " --channel-lifetime Set the lifetime for channel binding, default to 600 secs.\n" @@ -904,7 +904,7 @@ static const struct myoption long_options[] = { { "syslog", optional_argument, NULL, SYSLOG_OPT }, { "simple-log", optional_argument, NULL, SIMPLE_LOG_OPT }, { "new-log-timestamp", optional_argument, NULL, NEW_LOG_TIMESTAMP_OPT }, - { "new-timestamp_format", required_argument, NULL, NEW_TIMESTAMP_FORMAT_OPT }, + { "new-timestamp-format", required_argument, NULL, NEW_TIMESTAMP_FORMAT_OPT }, { "aux-server", required_argument, NULL, AUX_SERVER_OPT }, { "udp-self-balance", optional_argument, NULL, UDP_SELF_BALANCE_OPT }, { "alternate-server", required_argument, NULL, ALTERNATE_SERVER_OPT }, From 37b61993e501eaaeb88cf489ef329de25fa82e25 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?M=C3=A9sz=C3=A1ros=20Mih=C3=A1ly?= Date: Tue, 8 Dec 2020 11:10:15 +0100 Subject: [PATCH 25/55] Add new log options to config file --- examples/etc/turnserver.conf | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/examples/etc/turnserver.conf b/examples/etc/turnserver.conf index 3af6845c..028d59b6 100644 --- a/examples/etc/turnserver.conf +++ b/examples/etc/turnserver.conf @@ -534,6 +534,12 @@ # #simple-log +# Enable full ISO-8601 timestamp in all logs. +#new-log-timestamp + +# Set timestamp format (in strftime(1) format) +#new-timestamp-format "%FT%T%z" + # Option to set the "redirection" mode. The value of this option # will be the address of the alternate server for UDP & TCP service in the form of # [:]. The server will send this value in the attribute From b0fb4a9a0a97a243f47c874282e4ca0bfcec501a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?M=C3=A9sz=C3=A1ros=20Mih=C3=A1ly?= Date: Tue, 8 Dec 2020 11:48:54 +0100 Subject: [PATCH 26/55] Rename new timestamp options, and fix these cli handling --- ChangeLog | 2 +- README.turnserver | 2 +- examples/etc/turnserver.conf | 2 +- man/man1/turnserver.1 | 2 +- src/apps/relay/mainrelay.c | 15 +++++++++++---- 5 files changed, 15 insertions(+), 8 deletions(-) diff --git a/ChangeLog b/ChangeLog index 7c0acdbb..808632a6 100644 --- a/ChangeLog +++ b/ChangeLog @@ -15,7 +15,7 @@ Version 4.5.2 'dan Eider': * Add support for proxy protocol V1 - merge PR #618 (by Paul Wayper) * Print full date and time in logs - * Add new options: "new-log-timestamp" and "new-timestamp-format" + * Add new options: "new-log-timestamp" and "new-log-timestamp-format" - merge PR #599 (by Cédric Krier) * Do not use FIPS and remove hardcode OPENSSL_VERSION_NUMBER with LibreSSL - update Docker mongoDB and fix with workaround the missing systemctl diff --git a/README.turnserver b/README.turnserver index 0468a091..77b205b9 100644 --- a/README.turnserver +++ b/README.turnserver @@ -227,7 +227,7 @@ Flags: --new-log-timestamp Enable full ISO-8601 timestamp in all logs. ---new-timestamp-format Set timestamp format (in strftime(1) format) +--new-log-timestamp-format Set timestamp format (in strftime(1) format) --secure-stun Require authentication of the STUN Binding request. By default, the clients are allowed anonymous access to the STUN Binding functionality. diff --git a/examples/etc/turnserver.conf b/examples/etc/turnserver.conf index 028d59b6..aa919642 100644 --- a/examples/etc/turnserver.conf +++ b/examples/etc/turnserver.conf @@ -538,7 +538,7 @@ #new-log-timestamp # Set timestamp format (in strftime(1) format) -#new-timestamp-format "%FT%T%z" +#new-log-timestamp-format "%FT%T%z" # Option to set the "redirection" mode. The value of this option # will be the address of the alternate server for UDP & TCP service in the form of diff --git a/man/man1/turnserver.1 b/man/man1/turnserver.1 index 7464114b..e3bd3251 100644 --- a/man/man1/turnserver.1 +++ b/man/man1/turnserver.1 @@ -342,7 +342,7 @@ This option can be used, for example, together with the logrotate tool. Enable full ISO\-8601 timestamp in all logs. .TP .B -\fB\-\-new\-timestamp\-format\fP +\fB\-\-new\-log\-timestamp\-format\fP Set timestamp format (in \fBstrftime\fP(1) format) .TP .B diff --git a/src/apps/relay/mainrelay.c b/src/apps/relay/mainrelay.c index ff357299..7da6d1b9 100644 --- a/src/apps/relay/mainrelay.c +++ b/src/apps/relay/mainrelay.c @@ -604,7 +604,7 @@ static char Usage[] = "Usage: turnserver [options]\n" " name will be constructed as-is, without PID and date appendage.\n" " This option can be used, for example, together with the logrotate tool.\n" " --new-log-timestamp Enable full ISO-8601 timestamp in all logs.\n" -" --new-timestamp-format Set timestamp format (in strftime(1) format)\n" +" --new-log-timestamp-format Set timestamp format (in strftime(1) format)\n" " --stale-nonce[=] Use extra security with nonce value having limited lifetime (default 600 secs).\n" " --max-allocate-lifetime Set the maximum value for the allocation lifetime. Default to 3600 secs.\n" " --channel-lifetime Set the lifetime for channel binding, default to 600 secs.\n" @@ -764,7 +764,7 @@ enum EXTRA_OPTS { SYSLOG_OPT, SIMPLE_LOG_OPT, NEW_LOG_TIMESTAMP_OPT, - NEW_TIMESTAMP_FORMAT_OPT, + NEW_LOG_TIMESTAMP_FORMAT_OPT, AUX_SERVER_OPT, UDP_SELF_BALANCE_OPT, ALTERNATE_SERVER_OPT, @@ -904,7 +904,7 @@ static const struct myoption long_options[] = { { "syslog", optional_argument, NULL, SYSLOG_OPT }, { "simple-log", optional_argument, NULL, SIMPLE_LOG_OPT }, { "new-log-timestamp", optional_argument, NULL, NEW_LOG_TIMESTAMP_OPT }, - { "new-timestamp-format", required_argument, NULL, NEW_TIMESTAMP_FORMAT_OPT }, + { "new-log-timestamp-format", required_argument, NULL, NEW_LOG_TIMESTAMP_FORMAT_OPT }, { "aux-server", required_argument, NULL, AUX_SERVER_OPT }, { "udp-self-balance", optional_argument, NULL, UDP_SELF_BALANCE_OPT }, { "alternate-server", required_argument, NULL, ALTERNATE_SERVER_OPT }, @@ -1592,6 +1592,13 @@ static void set_option(int c, char *value) turn_params.rest_api_separator=*value; } break; + case NEW_LOG_TIMESTAMP_OPT: + use_new_log_timestamp_format=1; + break; + case NEW_LOG_TIMESTAMP_FORMAT_OPT: + set_turn_log_timestamp_format(value); + break; + /* these options have been already taken care of before: */ case 'l': case NO_STDOUT_LOG_OPT: @@ -1725,7 +1732,7 @@ static void read_config_file(int argc, char **argv, int pass) set_simple_log(get_bool_value(value)); } else if ((pass==0) && (c==NEW_LOG_TIMESTAMP_OPT)) { use_new_log_timestamp_format=1; - } else if ((pass==0) && (c==NEW_TIMESTAMP_FORMAT_OPT)) { + } else if ((pass==0) && (c==NEW_LOG_TIMESTAMP_FORMAT_OPT)) { set_turn_log_timestamp_format(value); } else if((pass == 0) && (c != 'u')) { set_option(c, value); From 08bb62ea8871c09f7961388d0fad9c9c50b2ee37 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?M=C3=A9sz=C3=A1ros=20Mih=C3=A1ly?= Date: Tue, 8 Dec 2020 13:40:49 +0100 Subject: [PATCH 27/55] Update README to fix #658 --- README.md | 3 ++- README.turnadmin | 6 +++++- README.turnserver | 6 +++++- README.turnutils | 6 +++++- man/man1/turnadmin.1 | 5 ++++- man/man1/turnserver.1 | 6 +++++- man/man1/turnutils.1 | 5 ++++- 7 files changed, 30 insertions(+), 7 deletions(-) diff --git a/README.md b/README.md index 448df3f3..59997efb 100644 --- a/README.md +++ b/README.md @@ -121,7 +121,8 @@ Contact information: https://groups.google.com/forum/#!forum/turn-server-project-rfc5766-turn-server -email:mom040267@gmail.com +email:misi@majd.eu + mom040267@gmail.com ### Feedback is very welcome (bugs, issues, suggestions, stories, questions). ### diff --git a/README.turnadmin b/README.turnadmin index 4b64583d..8e177010 100644 --- a/README.turnadmin +++ b/README.turnadmin @@ -271,4 +271,8 @@ to see the man page. Bradley T. Hughes - Mihaly Meszaros + Mihály Mészáros + + ACTIVE MAINTAINERS + + Mihály Mészáros \ No newline at end of file diff --git a/README.turnserver b/README.turnserver index 77b205b9..5969ba6d 100644 --- a/README.turnserver +++ b/README.turnserver @@ -1001,4 +1001,8 @@ https://groups.google.com/forum/?fromgroups=#!forum/turn-server-project-rfc5766- Bradley T. Hughes - Mihaly Meszaros + Mihály Mészáros + + ACTIVE MAINTAINERS + + Mihály Mészáros diff --git a/README.turnutils b/README.turnutils index ab2dd832..da89c5dd 100644 --- a/README.turnutils +++ b/README.turnutils @@ -474,4 +474,8 @@ SEE ALSO Bradley T. Hughes - Mihaly Meszaros + Mihály Mészáros + + ACTIVE MAINTAINERS + + Mihály Mészáros \ No newline at end of file diff --git a/man/man1/turnadmin.1 b/man/man1/turnadmin.1 index 8fcdfd54..dc2982c2 100644 --- a/man/man1/turnadmin.1 +++ b/man/man1/turnadmin.1 @@ -373,4 +373,7 @@ Federico Pinna .PP Bradley T. Hughes .PP -Mihaly Meszaros +Mihály Mészáros +.SS ACTIVE MAINTAINERS + +Mihály Mészáros diff --git a/man/man1/turnserver.1 b/man/man1/turnserver.1 index e3bd3251..3a9131bd 100644 --- a/man/man1/turnserver.1 +++ b/man/man1/turnserver.1 @@ -1274,5 +1274,9 @@ Mutsutoshi Yoshimoto Federico Pinna .PP Bradley T. Hughes +.RE .PP -Mihaly Meszaros +Mihály Mészáros +.SS ACTIVE MAINTAINERS + +Mihály Mészáros diff --git a/man/man1/turnutils.1 b/man/man1/turnutils.1 index 24bcf6e0..93a03ef3 100644 --- a/man/man1/turnutils.1 +++ b/man/man1/turnutils.1 @@ -667,4 +667,7 @@ Federico Pinna .PP Bradley T. Hughes .PP -Mihaly Meszaros +Mihály Mészáros +.SS ACTIVE MAINTAINERS + +Mihály Mészáros From 0880d7cd0fe9641d65f42100d6012f46c3878759 Mon Sep 17 00:00:00 2001 From: Camden Narzt Date: Wed, 9 Dec 2020 16:15:40 -0700 Subject: [PATCH 28/55] fix compilation on macOS Big Sur You must define `__APPLE_USE_RFC_3542` in order to use the `IPV6_DONTFRAG` sockopt: https://opensource.apple.com/source/xnu/xnu-6153.141.1/bsd/netinet6/in6.h.auto.html ``` * To use the new IPv6 Sockets options introduced by RFC 3542 * the constant __APPLE_USE_RFC_3542 must be defined before * including ``` --- src/ns_turn_defs.h | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/ns_turn_defs.h b/src/ns_turn_defs.h index 336e0485..461ceccd 100644 --- a/src/ns_turn_defs.h +++ b/src/ns_turn_defs.h @@ -39,6 +39,10 @@ #include #endif +#if defined(__APPLE__) || defined(__DARWIN__) || defined(__MACH__) +#define __APPLE_USE_RFC_3542 +#endif + #include #include #include From 9b1cca1fbe909e7cc7c7ac28865f9c190af3515b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?M=C3=A9sz=C3=A1ros=20Mih=C3=A1ly?= Date: Thu, 10 Dec 2020 11:11:40 +0100 Subject: [PATCH 29/55] Add PR#660 to changelog --- ChangeLog | 2 ++ 1 file changed, 2 insertions(+) diff --git a/ChangeLog b/ChangeLog index 808632a6..85ffb0aa 100644 --- a/ChangeLog +++ b/ChangeLog @@ -19,6 +19,8 @@ Version 4.5.2 'dan Eider': - merge PR #599 (by Cédric Krier) * Do not use FIPS and remove hardcode OPENSSL_VERSION_NUMBER with LibreSSL - update Docker mongoDB and fix with workaround the missing systemctl + - merge PR #660 (by Camden Narzt) + * fix compilation on macOS Big Sur 24/06/2020 Oleg Moskalenko Mihály Mészáros Version 4.5.1.3 'dan Eider': From 7e525c8e1c09c0055fb00fbcac091c4d87d19937 Mon Sep 17 00:00:00 2001 From: Jens Elkner Date: Mon, 18 May 2020 07:21:56 +0200 Subject: [PATCH 30/55] support of --acme-redirect --- src/apps/relay/http_server.c | 77 ++++++++++++++++++++++++++++++++++++ src/apps/relay/mainrelay.c | 14 ++++++- src/apps/relay/mainrelay.h | 1 + src/apps/relay/netengine.c | 1 + src/server/ns_turn_ioalib.h | 1 + src/server/ns_turn_server.c | 17 +++++--- src/server/ns_turn_server.h | 4 ++ 7 files changed, 108 insertions(+), 7 deletions(-) diff --git a/src/apps/relay/http_server.c b/src/apps/relay/http_server.c index ff8e3992..ca70d77e 100644 --- a/src/apps/relay/http_server.c +++ b/src/apps/relay/http_server.c @@ -99,6 +99,83 @@ const char* get_http_date_header() return buffer_header; } +static int is_acme_req(char *req, size_t len) { + static const char *A = " - 0123456789 ABCDEFGHIJKLMNOPQRSTUVWXYZ _ abcdefghijklmnopqrstuvwxyz "; + int c, i, k; + + // Check first request line. Should be like: GET path HTTP/1.x + if (strncmp(req, "GET /.well-known/acme-challenge/", 32)) + return -1; + // Usually (for LE) the "method path" is 32 + 43 = 55 chars. But other + // implementations may choose longer pathes. We define PATHMAX = 127 chars + // to be prepared for "DoS" attacks (STUN msg size max. is ~ 64K). + len =- 21; // min size of trailing headers + if (len > 131) + len = 131; + for (i=32; i < (int) len; i++) { + // find the end of the path + if (req[i] != ' ') + continue; + // consider path < 10 chars invalid. Also we wanna see a "trailer". + if (i < 42 || strncmp(req + i, " HTTP/1.", 8)) + return -2; + // finally check for allowed chars + for (k=32; k < i; k++) { + c = req[k]; + if ((c > 127) || (A[c] == ' ')) + return -3; + } + // all checks passed: sufficient for us to answer with a redirect + return i; + } + return -4; // end of path not found +} + +int try_acme_redirect(char *req, size_t len, const char *url, + ioa_socket_handle s) +{ + static const char *HTML = "301 Moved Permanently

301 Moved Permanently

"; + char http_response[1024]; + int plen, rlen; + + if (url == NULL || url[0] == '\0' || req == NULL || s == 0 ) + return 1; + if (len < 64 || len > 512 || (plen = is_acme_req(req, len)) < 33) + return 2; + + req[plen] = '\0'; + snprintf(http_response, sizeof(http_response) - 1, + "HTTP/1.1 301 Moved Permanently\r\n" + "Content-Type: text/html\r\n" + "Content-Length: %ld\r\n" + "Connection: close\r\n" + "Location: %s%s\r\n" + "\r\n%s", strlen(HTML), url, req + 32, HTML); + + rlen = strlen(http_response); + + // Variant A: direkt write, no eventbuf stuff + if (write(s->fd, http_response, rlen) == -1) { + perror("Sending redirect failed"); + } else if (((turn_turnserver *)s->session->server)->verbose) { + TURN_LOG_FUNC(TURN_LOG_LEVEL_INFO, "ACME redirect to %s%s\n", + url, req + 32); + } + + req[plen] = ' '; + + // Variant B: via eventbuf does not send anything for whatever reason + /* + set_ioa_socket_app_type(s, HTTP_CLIENT_SOCKET); + ioa_network_buffer_handle nbh = ioa_network_buffer_allocate(s->e); + uint8_t *data = ioa_network_buffer_data(nbh); + bcopy(http_response, data, rlen); + ioa_network_buffer_set_size(nbh, rlen); + send_data_from_ioa_socket_nbh(s, NULL, nbh, TTL_IGNORE, TOS_IGNORE, NULL); + */ + + return 0; +} /////////////////////////////////////////////// static struct headers_list * post_parse(char *data, size_t data_len) diff --git a/src/apps/relay/mainrelay.c b/src/apps/relay/mainrelay.c index 7da6d1b9..2baa7705 100644 --- a/src/apps/relay/mainrelay.c +++ b/src/apps/relay/mainrelay.c @@ -114,7 +114,7 @@ NULL, PTHREAD_MUTEX_INITIALIZER, //////////////// Common params //////////////////// TURN_VERBOSE_NONE,0,0,0,0, -"/var/run/turnserver.pid", +"/var/run/turnserver.pid","", DEFAULT_STUN_PORT,DEFAULT_STUN_TLS_PORT,0,0,0,1, 0,0,0,0,0, "", @@ -629,6 +629,8 @@ static char Usage[] = "Usage: turnserver [options]\n" " --pidfile <\"pid-file-name\"> File name to store the pid of the process.\n" " Default is /var/run/turnserver.pid (if superuser account is used) or\n" " /var/tmp/turnserver.pid .\n" +" --acme-redirect <\"URL\"> Redirect HTTP GET requests matching '^/.well-known/acme-challenge/(.*)' to '<\"URL\">$1'\n" +" Default is '', i.e. no special handling for such requests.\n" " --secure-stun Require authentication of the STUN Binding request.\n" " By default, the clients are allowed anonymous access to the STUN Binding functionality.\n" " --proc-user User name to run the turnserver process.\n" @@ -810,7 +812,8 @@ enum EXTRA_OPTS { OAUTH_OPT, NO_SOFTWARE_ATTRIBUTE_OPT, NO_HTTP_OPT, - SECRET_KEY_OPT + SECRET_KEY_OPT, + ACME_REDIRECT_OPT }; struct myoption { @@ -944,6 +947,7 @@ static const struct myoption long_options[] = { { "no-tlsv1_2", optional_argument, NULL, NO_TLSV1_2_OPT }, { "secret-key-file", required_argument, NULL, SECRET_KEY_OPT }, { "keep-address-family", optional_argument, NULL, 'K' }, + { "acme-redirect", required_argument, NULL, ACME_REDIRECT_OPT }, { NULL, no_argument, NULL, 0 } }; @@ -1587,6 +1591,9 @@ static void set_option(int c, char *value) case PIDFILE_OPT: STRCPY(turn_params.pidfile,value); break; + case ACME_REDIRECT_OPT: + STRCPY(turn_params.acme_redirect,value); + break; case 'C': if(value && *value) { turn_params.rest_api_separator=*value; @@ -2276,6 +2283,9 @@ int main(int argc, char **argv) TURN_LOG_FUNC(TURN_LOG_LEVEL_INFO, "Domain name: %s\n",turn_params.domain); TURN_LOG_FUNC(TURN_LOG_LEVEL_INFO, "Default realm: %s\n",get_realm(NULL)->options.name); + if(turn_params.acme_redirect[0]) { + TURN_LOG_FUNC(TURN_LOG_LEVEL_INFO, "ACME redirect URL: %s\n",turn_params.acme_redirect); + } if(turn_params.oauth && turn_params.oauth_server_name[0]) { TURN_LOG_FUNC(TURN_LOG_LEVEL_INFO, "oAuth server name: %s\n",turn_params.oauth_server_name); } diff --git a/src/apps/relay/mainrelay.h b/src/apps/relay/mainrelay.h index 106f25a2..0bcdbbd4 100644 --- a/src/apps/relay/mainrelay.h +++ b/src/apps/relay/mainrelay.h @@ -219,6 +219,7 @@ typedef struct _turn_params_ { int do_not_use_config_file; char pidfile[1025]; + char acme_redirect[1025]; //////////////// Listener server ///////////////// diff --git a/src/apps/relay/netengine.c b/src/apps/relay/netengine.c index ca88056e..20f558cd 100644 --- a/src/apps/relay/netengine.c +++ b/src/apps/relay/netengine.c @@ -1667,6 +1667,7 @@ static void setup_relay_server(struct relay_server *rs, ioa_engine_handle e, int allocate_bps, turn_params.oauth, turn_params.oauth_server_name, + turn_params.acme_redirect, turn_params.keep_address_family); if(to_set_rfc5780) { diff --git a/src/server/ns_turn_ioalib.h b/src/server/ns_turn_ioalib.h index 6737711d..3a25b03e 100644 --- a/src/server/ns_turn_ioalib.h +++ b/src/server/ns_turn_ioalib.h @@ -285,6 +285,7 @@ int get_default_protocol_port(const char* scheme, size_t slen); ///////////// HTTP //////////////////// void handle_http_echo(ioa_socket_handle s); +int try_acme_redirect(char *req, size_t len, const char *url, ioa_socket_handle s); /////////////////////////////////////// diff --git a/src/server/ns_turn_server.c b/src/server/ns_turn_server.c index 38a15134..3d3eaa74 100644 --- a/src/server/ns_turn_server.c +++ b/src/server/ns_turn_server.c @@ -4624,14 +4624,19 @@ static int read_client_connection(turn_turnserver *server, } else { SOCKET_TYPE st = get_ioa_socket_type(ss->client_socket); if(is_stream_socket(st)) { - if(is_http((char*)ioa_network_buffer_data(in_buffer->nbh), ioa_network_buffer_get_size(in_buffer->nbh))) { + char *str = (char*)ioa_network_buffer_data(in_buffer->nbh); + size_t l = ioa_network_buffer_get_size(in_buffer->nbh); + if(is_http(str, l)) { const char *proto = "HTTP"; - ioa_network_buffer_data(in_buffer->nbh)[ioa_network_buffer_get_size(in_buffer->nbh)] = 0; - if (*server->web_admin_listen_on_workers) { + str[l] = 0; + if ((st == TCP_SOCKET) && (try_acme_redirect(str, l, server->acme_redirect, ss->client_socket) == 0)) { + ss->to_be_closed = 1; + return 0; + } else if (*server->web_admin_listen_on_workers) { if(st==TLS_SOCKET) { proto = "HTTPS"; set_ioa_socket_app_type(ss->client_socket,HTTPS_CLIENT_SOCKET); - TURN_LOG_FUNC(TURN_LOG_LEVEL_INFO, "%s: %s (%s %s) request: %s\n", __FUNCTION__, proto, get_ioa_socket_cipher(ss->client_socket), get_ioa_socket_ssl_method(ss->client_socket), (char*)ioa_network_buffer_data(in_buffer->nbh)); + TURN_LOG_FUNC(TURN_LOG_LEVEL_INFO, "%s: %s (%s %s) request: %s\n", __FUNCTION__, proto, get_ioa_socket_cipher(ss->client_socket), get_ioa_socket_ssl_method(ss->client_socket), str); if(server->send_https_socket) { TURN_LOG_FUNC(TURN_LOG_LEVEL_INFO, "%s socket to be detached: 0x%lx, st=%d, sat=%d\n", __FUNCTION__,(long)ss->client_socket, get_ioa_socket_type(ss->client_socket), get_ioa_socket_app_type(ss->client_socket)); ioa_socket_handle new_s = detach_ioa_socket(ss->client_socket); @@ -4644,7 +4649,7 @@ static int read_client_connection(turn_turnserver *server, } else { set_ioa_socket_app_type(ss->client_socket,HTTP_CLIENT_SOCKET); if(server->verbose) { - TURN_LOG_FUNC(TURN_LOG_LEVEL_INFO, "%s: %s request: %s\n", __FUNCTION__, proto, (char*)ioa_network_buffer_data(in_buffer->nbh)); + TURN_LOG_FUNC(TURN_LOG_LEVEL_INFO, "%s: %s request: %s\n", __FUNCTION__, proto, str); } handle_http_echo(ss->client_socket); } @@ -4915,6 +4920,7 @@ void init_turn_server(turn_turnserver* server, allocate_bps_cb allocate_bps_func, int oauth, const char* oauth_server_name, + const char* acme_redirect, int keep_address_family) { if (!server) @@ -4944,6 +4950,7 @@ void init_turn_server(turn_turnserver* server, server->oauth_server_name = oauth_server_name; if(mobility) server->mobile_connections_map = ur_map_create(); + server->acme_redirect = acme_redirect; TURN_LOG_FUNC(TURN_LOG_LEVEL_INFO,"turn server id=%d created\n",(int)id); diff --git a/src/server/ns_turn_server.h b/src/server/ns_turn_server.h index 924a507a..0df99716 100644 --- a/src/server/ns_turn_server.h +++ b/src/server/ns_turn_server.h @@ -171,6 +171,9 @@ struct _turn_turnserver { int oauth; const char* oauth_server_name; + /* ACME redirect URL */ + const char* acme_redirect; + /* Keep Address Family */ int keep_address_family; }; @@ -218,6 +221,7 @@ void init_turn_server(turn_turnserver* server, allocate_bps_cb allocate_bps_func, int oauth, const char* oauth_server_name, + const char* acme_redirect, int keep_address_family); ioa_engine_handle turn_server_get_engine(turn_turnserver *s); From 9b0dd4380cb0e2c68c22cbbad9d03bd62b3b6deb Mon Sep 17 00:00:00 2001 From: Jens Elkner Date: Mon, 18 May 2020 17:00:31 +0200 Subject: [PATCH 31/55] acme-redirect: add option to man page, fix help text --- man/man1/turnserver.1 | 7 +++++++ src/apps/relay/mainrelay.c | 2 +- 2 files changed, 8 insertions(+), 1 deletion(-) diff --git a/man/man1/turnserver.1 b/man/man1/turnserver.1 index 3a9131bd..4fbd2673 100644 --- a/man/man1/turnserver.1 +++ b/man/man1/turnserver.1 @@ -787,6 +787,13 @@ File name to store the pid of the process. Default is /var/run/turnserver.pid (if superuser account is used) or /var/tmp/turnserver.pid . .TP +.BI --acme-redirect\ URL +Redirect ACME/RFC8555 (like Let's Encrypt challenge) requests, i.e. +HTTP GET requests matching '^/.well-known/acme-challenge/(.*)' +to \fIURL\fR$1 with $1 == (.*). No validation of \fIURL\fR will be done, +so make sure you do not forget the trailing slash. If \fIURL\fR is an empty +string (the default value), no special handling of such requests will be done. +.TP .B \fB\-\-proc\-user\fP User name to run the process. After the initialization, the \fIturnserver\fP process diff --git a/src/apps/relay/mainrelay.c b/src/apps/relay/mainrelay.c index 2baa7705..2343a1cd 100644 --- a/src/apps/relay/mainrelay.c +++ b/src/apps/relay/mainrelay.c @@ -629,7 +629,7 @@ static char Usage[] = "Usage: turnserver [options]\n" " --pidfile <\"pid-file-name\"> File name to store the pid of the process.\n" " Default is /var/run/turnserver.pid (if superuser account is used) or\n" " /var/tmp/turnserver.pid .\n" -" --acme-redirect <\"URL\"> Redirect HTTP GET requests matching '^/.well-known/acme-challenge/(.*)' to '<\"URL\">$1'\n" +" --acme-redirect Redirect ACME, i.e. HTTP GET requests matching '^/.well-known/acme-challenge/(.*)' to '$1'.\n" " Default is '', i.e. no special handling for such requests.\n" " --secure-stun Require authentication of the STUN Binding request.\n" " By default, the clients are allowed anonymous access to the STUN Binding functionality.\n" From d4686750eee289f05e24e9fdcc99c88d4fb217f2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?M=C3=A9sz=C3=A1ros=20Mih=C3=A1ly?= Date: Sat, 8 Aug 2020 22:47:41 +0200 Subject: [PATCH 32/55] Move acme to new file --- ChangeLog | 4 +- Makefile.in | 2 +- man/man1/turnserver.1 | 7 --- src/apps/relay/acme.c | 111 +++++++++++++++++++++++++++++++++++ src/apps/relay/acme.h | 57 ++++++++++++++++++ src/apps/relay/http_server.c | 77 ------------------------ src/server/ns_turn_ioalib.h | 3 + src/server/ns_turn_server.c | 19 +++--- 8 files changed, 187 insertions(+), 93 deletions(-) create mode 100644 src/apps/relay/acme.c create mode 100644 src/apps/relay/acme.h diff --git a/ChangeLog b/ChangeLog index 85ffb0aa..95f10a8f 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,7 +1,7 @@ 24/06/2020 Oleg Moskalenko Mihály Mészáros Version 4.5.2 'dan Eider': - fix null pointer dereference in case of out of memory. (thanks to Thomas Moeller for the report) - - merge PR #517 (by wolmi) + - merge PR #517 (by wolmi) * add prometheus metrics - merge PR #637 (by David Florness) * Delete trailing whitespace in example configuration files @@ -21,6 +21,8 @@ Version 4.5.2 'dan Eider': - update Docker mongoDB and fix with workaround the missing systemctl - merge PR #660 (by Camden Narzt) * fix compilation on macOS Big Sur + - merge PR #546 (by jelmd) + * Add ACME redirect url 24/06/2020 Oleg Moskalenko Mihály Mészáros Version 4.5.1.3 'dan Eider': diff --git a/Makefile.in b/Makefile.in index a4479e15..b869d0e6 100755 --- a/Makefile.in +++ b/Makefile.in @@ -21,7 +21,7 @@ COMMON_MODS = src/apps/common/apputils.c src/apps/common/ns_turn_utils.c src/app COMMON_DEPS = ${LIBCLIENTTURN_DEPS} ${COMMON_MODS} ${COMMON_HEADERS} IMPL_HEADERS = src/apps/relay/ns_ioalib_impl.h src/apps/relay/ns_sm.h src/apps/relay/turn_ports.h -IMPL_MODS = src/apps/relay/ns_ioalib_engine_impl.c src/apps/relay/turn_ports.c src/apps/relay/http_server.c +IMPL_MODS = src/apps/relay/ns_ioalib_engine_impl.c src/apps/relay/turn_ports.c src/apps/relay/http_server.c src/apps/relay/acme.c IMPL_DEPS = ${COMMON_DEPS} ${IMPL_HEADERS} ${IMPL_MODS} HIREDIS_HEADERS = src/apps/common/hiredis_libevent2.h diff --git a/man/man1/turnserver.1 b/man/man1/turnserver.1 index 4fbd2673..3a9131bd 100644 --- a/man/man1/turnserver.1 +++ b/man/man1/turnserver.1 @@ -787,13 +787,6 @@ File name to store the pid of the process. Default is /var/run/turnserver.pid (if superuser account is used) or /var/tmp/turnserver.pid . .TP -.BI --acme-redirect\ URL -Redirect ACME/RFC8555 (like Let's Encrypt challenge) requests, i.e. -HTTP GET requests matching '^/.well-known/acme-challenge/(.*)' -to \fIURL\fR$1 with $1 == (.*). No validation of \fIURL\fR will be done, -so make sure you do not forget the trailing slash. If \fIURL\fR is an empty -string (the default value), no special handling of such requests will be done. -.TP .B \fB\-\-proc\-user\fP User name to run the process. After the initialization, the \fIturnserver\fP process diff --git a/src/apps/relay/acme.c b/src/apps/relay/acme.c new file mode 100644 index 00000000..3e6d0c5e --- /dev/null +++ b/src/apps/relay/acme.c @@ -0,0 +1,111 @@ + +/* + * Copyright (C) 2011, 2012, 2013, 2014 Citrix Systems + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the project nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#include "acme.h" +#include "ns_ioalib_impl.h" + +static int is_acme_req(char *req, size_t len) { + static const char *A = " - 0123456789 ABCDEFGHIJKLMNOPQRSTUVWXYZ _ abcdefghijklmnopqrstuvwxyz "; + int c, i, k; + + // Check first request line. Should be like: GET path HTTP/1.x + if (strncmp(req, "GET /.well-known/acme-challenge/", 32)) + return -1; + // Usually (for LE) the "method path" is 32 + 43 = 55 chars. But other + // implementations may choose longer pathes. We define PATHMAX = 127 chars + // to be prepared for "DoS" attacks (STUN msg size max. is ~ 64K). + len =- 21; // min size of trailing headers + if (len > 131) + len = 131; + for (i=32; i < (int) len; i++) { + // find the end of the path + if (req[i] != ' ') + continue; + // consider path < 10 chars invalid. Also we wanna see a "trailer". + if (i < 42 || strncmp(req + i, " HTTP/1.", 8)) + return -2; + // finally check for allowed chars + for (k=32; k < i; k++) { + c = req[k]; + if ((c > 127) || (A[c] == ' ')) + return -3; + } + // all checks passed: sufficient for us to answer with a redirect + return i; + } + return -4; // end of path not found +} + +int try_acme_redirect(char *req, size_t len, const char *url, + ioa_socket_handle s) +{ + static const char *HTML = "301 Moved Permanently

301 Moved Permanently

"; + char http_response[1024]; + size_t plen, rlen; + + if (url == NULL || url[0] == '\0' || req == NULL || s == 0 ) + return 1; + if (len < 64 || len > 512 || (plen = is_acme_req(req, len)) < 33) + return 2; + + + snprintf(http_response, sizeof(http_response) - 1, + "HTTP/1.1 301 Moved Permanently\r\n" + "Content-Type: text/html\r\n" + "Content-Length: %ld\r\n" + "Connection: close\r\n" + "Location: %s%s\r\n" + "\r\n%s", strlen(HTML), url, req + 32, HTML); + + rlen = strlen(http_response); + + // Variant A: direkt write, no eventbuf stuff + /* + if (write(s->fd, http_response, rlen) == -1) { + perror("Sending redirect failed"); + } else if (((turn_turnserver *)s->session->server)->verbose) { + TURN_LOG_FUNC(TURN_LOG_LEVEL_INFO, "ACME redirect to %s%s\n", + url, req + 32); + } + + req[plen] = ' '; + */ + // Variant B: via eventbuf does not send anything for whatever reason + + //set_ioa_socket_app_type(s, HTTP_CLIENT_SOCKET); + ioa_network_buffer_handle nbh_acme = ioa_network_buffer_allocate(s->e); + uint8_t *data = ioa_network_buffer_data(nbh_acme); + bcopy(http_response, data, rlen); + ioa_network_buffer_set_size(nbh_acme, rlen); + send_data_from_ioa_socket_nbh(s, NULL, nbh_acme, TTL_IGNORE, TOS_IGNORE, NULL); + + return 0; +} diff --git a/src/apps/relay/acme.h b/src/apps/relay/acme.h new file mode 100644 index 00000000..133c22d1 --- /dev/null +++ b/src/apps/relay/acme.h @@ -0,0 +1,57 @@ +/* + * Copyright (C) 2011, 2012, 2013, 2014 Citrix Systems + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the project nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#ifndef __TURN_ACME__ +#define __TURN_ACME__ + +#include "ns_turn_utils.h" +#include "ns_turn_server.h" +#include "apputils.h" + +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + +///////////// ACME ///////////////////// + +int try_acme_redirect(char *req, size_t len, const char *url, ioa_socket_handle s); + +/////////////////////////////////////// + +#ifdef __cplusplus +} +#endif + +#endif +/// __TURN_ACME__ /// + diff --git a/src/apps/relay/http_server.c b/src/apps/relay/http_server.c index ca70d77e..ff8e3992 100644 --- a/src/apps/relay/http_server.c +++ b/src/apps/relay/http_server.c @@ -99,83 +99,6 @@ const char* get_http_date_header() return buffer_header; } -static int is_acme_req(char *req, size_t len) { - static const char *A = " - 0123456789 ABCDEFGHIJKLMNOPQRSTUVWXYZ _ abcdefghijklmnopqrstuvwxyz "; - int c, i, k; - - // Check first request line. Should be like: GET path HTTP/1.x - if (strncmp(req, "GET /.well-known/acme-challenge/", 32)) - return -1; - // Usually (for LE) the "method path" is 32 + 43 = 55 chars. But other - // implementations may choose longer pathes. We define PATHMAX = 127 chars - // to be prepared for "DoS" attacks (STUN msg size max. is ~ 64K). - len =- 21; // min size of trailing headers - if (len > 131) - len = 131; - for (i=32; i < (int) len; i++) { - // find the end of the path - if (req[i] != ' ') - continue; - // consider path < 10 chars invalid. Also we wanna see a "trailer". - if (i < 42 || strncmp(req + i, " HTTP/1.", 8)) - return -2; - // finally check for allowed chars - for (k=32; k < i; k++) { - c = req[k]; - if ((c > 127) || (A[c] == ' ')) - return -3; - } - // all checks passed: sufficient for us to answer with a redirect - return i; - } - return -4; // end of path not found -} - -int try_acme_redirect(char *req, size_t len, const char *url, - ioa_socket_handle s) -{ - static const char *HTML = "301 Moved Permanently

301 Moved Permanently

"; - char http_response[1024]; - int plen, rlen; - - if (url == NULL || url[0] == '\0' || req == NULL || s == 0 ) - return 1; - if (len < 64 || len > 512 || (plen = is_acme_req(req, len)) < 33) - return 2; - - req[plen] = '\0'; - snprintf(http_response, sizeof(http_response) - 1, - "HTTP/1.1 301 Moved Permanently\r\n" - "Content-Type: text/html\r\n" - "Content-Length: %ld\r\n" - "Connection: close\r\n" - "Location: %s%s\r\n" - "\r\n%s", strlen(HTML), url, req + 32, HTML); - - rlen = strlen(http_response); - - // Variant A: direkt write, no eventbuf stuff - if (write(s->fd, http_response, rlen) == -1) { - perror("Sending redirect failed"); - } else if (((turn_turnserver *)s->session->server)->verbose) { - TURN_LOG_FUNC(TURN_LOG_LEVEL_INFO, "ACME redirect to %s%s\n", - url, req + 32); - } - - req[plen] = ' '; - - // Variant B: via eventbuf does not send anything for whatever reason - /* - set_ioa_socket_app_type(s, HTTP_CLIENT_SOCKET); - ioa_network_buffer_handle nbh = ioa_network_buffer_allocate(s->e); - uint8_t *data = ioa_network_buffer_data(nbh); - bcopy(http_response, data, rlen); - ioa_network_buffer_set_size(nbh, rlen); - send_data_from_ioa_socket_nbh(s, NULL, nbh, TTL_IGNORE, TOS_IGNORE, NULL); - */ - - return 0; -} /////////////////////////////////////////////// static struct headers_list * post_parse(char *data, size_t data_len) diff --git a/src/server/ns_turn_ioalib.h b/src/server/ns_turn_ioalib.h index 3a25b03e..da3e7c5a 100644 --- a/src/server/ns_turn_ioalib.h +++ b/src/server/ns_turn_ioalib.h @@ -285,6 +285,9 @@ int get_default_protocol_port(const char* scheme, size_t slen); ///////////// HTTP //////////////////// void handle_http_echo(ioa_socket_handle s); + +///////////// ACME ///////////////////// + int try_acme_redirect(char *req, size_t len, const char *url, ioa_socket_handle s); /////////////////////////////////////// diff --git a/src/server/ns_turn_server.c b/src/server/ns_turn_server.c index 3d3eaa74..dafe26ee 100644 --- a/src/server/ns_turn_server.c +++ b/src/server/ns_turn_server.c @@ -4624,19 +4624,24 @@ static int read_client_connection(turn_turnserver *server, } else { SOCKET_TYPE st = get_ioa_socket_type(ss->client_socket); if(is_stream_socket(st)) { - char *str = (char*)ioa_network_buffer_data(in_buffer->nbh); - size_t l = ioa_network_buffer_get_size(in_buffer->nbh); - if(is_http(str, l)) { + if(is_http((char*)ioa_network_buffer_data(in_buffer->nbh), + ioa_network_buffer_get_size(in_buffer->nbh))) { + const char *proto = "HTTP"; - str[l] = 0; - if ((st == TCP_SOCKET) && (try_acme_redirect(str, l, server->acme_redirect, ss->client_socket) == 0)) { + if ((st == TCP_SOCKET) && + ( + try_acme_redirect((char*)ioa_network_buffer_data(in_buffer->nbh), + ioa_network_buffer_get_size(in_buffer->nbh), + server->acme_redirect, ss->client_socket) == 0 + ) + ) { ss->to_be_closed = 1; return 0; } else if (*server->web_admin_listen_on_workers) { if(st==TLS_SOCKET) { proto = "HTTPS"; set_ioa_socket_app_type(ss->client_socket,HTTPS_CLIENT_SOCKET); - TURN_LOG_FUNC(TURN_LOG_LEVEL_INFO, "%s: %s (%s %s) request: %s\n", __FUNCTION__, proto, get_ioa_socket_cipher(ss->client_socket), get_ioa_socket_ssl_method(ss->client_socket), str); + TURN_LOG_FUNC(TURN_LOG_LEVEL_INFO, "%s: %s (%s %s) request: %s\n", __FUNCTION__, proto, get_ioa_socket_cipher(ss->client_socket), get_ioa_socket_ssl_method(ss->client_socket), ioa_network_buffer_get_size(in_buffer->nbh)); if(server->send_https_socket) { TURN_LOG_FUNC(TURN_LOG_LEVEL_INFO, "%s socket to be detached: 0x%lx, st=%d, sat=%d\n", __FUNCTION__,(long)ss->client_socket, get_ioa_socket_type(ss->client_socket), get_ioa_socket_app_type(ss->client_socket)); ioa_socket_handle new_s = detach_ioa_socket(ss->client_socket); @@ -4649,7 +4654,7 @@ static int read_client_connection(turn_turnserver *server, } else { set_ioa_socket_app_type(ss->client_socket,HTTP_CLIENT_SOCKET); if(server->verbose) { - TURN_LOG_FUNC(TURN_LOG_LEVEL_INFO, "%s: %s request: %s\n", __FUNCTION__, proto, str); + TURN_LOG_FUNC(TURN_LOG_LEVEL_INFO, "%s: %s request: %s\n", __FUNCTION__, proto, ioa_network_buffer_get_size(in_buffer->nbh)); } handle_http_echo(ss->client_socket); } From 12c7d19a472d29bdeef4a37ccd5075b02ebbc517 Mon Sep 17 00:00:00 2001 From: Jens Elkner Date: Mon, 18 May 2020 07:21:56 +0200 Subject: [PATCH 33/55] support of --acme-redirect --- src/apps/relay/http_server.c | 77 +++++++ src/apps/relay/mainrelay.c | 392 +++++++++++++++++------------------ src/server/ns_turn_ioalib.h | 1 + 3 files changed, 274 insertions(+), 196 deletions(-) diff --git a/src/apps/relay/http_server.c b/src/apps/relay/http_server.c index ff8e3992..ca70d77e 100644 --- a/src/apps/relay/http_server.c +++ b/src/apps/relay/http_server.c @@ -99,6 +99,83 @@ const char* get_http_date_header() return buffer_header; } +static int is_acme_req(char *req, size_t len) { + static const char *A = " - 0123456789 ABCDEFGHIJKLMNOPQRSTUVWXYZ _ abcdefghijklmnopqrstuvwxyz "; + int c, i, k; + + // Check first request line. Should be like: GET path HTTP/1.x + if (strncmp(req, "GET /.well-known/acme-challenge/", 32)) + return -1; + // Usually (for LE) the "method path" is 32 + 43 = 55 chars. But other + // implementations may choose longer pathes. We define PATHMAX = 127 chars + // to be prepared for "DoS" attacks (STUN msg size max. is ~ 64K). + len =- 21; // min size of trailing headers + if (len > 131) + len = 131; + for (i=32; i < (int) len; i++) { + // find the end of the path + if (req[i] != ' ') + continue; + // consider path < 10 chars invalid. Also we wanna see a "trailer". + if (i < 42 || strncmp(req + i, " HTTP/1.", 8)) + return -2; + // finally check for allowed chars + for (k=32; k < i; k++) { + c = req[k]; + if ((c > 127) || (A[c] == ' ')) + return -3; + } + // all checks passed: sufficient for us to answer with a redirect + return i; + } + return -4; // end of path not found +} + +int try_acme_redirect(char *req, size_t len, const char *url, + ioa_socket_handle s) +{ + static const char *HTML = "301 Moved Permanently

301 Moved Permanently

"; + char http_response[1024]; + int plen, rlen; + + if (url == NULL || url[0] == '\0' || req == NULL || s == 0 ) + return 1; + if (len < 64 || len > 512 || (plen = is_acme_req(req, len)) < 33) + return 2; + + req[plen] = '\0'; + snprintf(http_response, sizeof(http_response) - 1, + "HTTP/1.1 301 Moved Permanently\r\n" + "Content-Type: text/html\r\n" + "Content-Length: %ld\r\n" + "Connection: close\r\n" + "Location: %s%s\r\n" + "\r\n%s", strlen(HTML), url, req + 32, HTML); + + rlen = strlen(http_response); + + // Variant A: direkt write, no eventbuf stuff + if (write(s->fd, http_response, rlen) == -1) { + perror("Sending redirect failed"); + } else if (((turn_turnserver *)s->session->server)->verbose) { + TURN_LOG_FUNC(TURN_LOG_LEVEL_INFO, "ACME redirect to %s%s\n", + url, req + 32); + } + + req[plen] = ' '; + + // Variant B: via eventbuf does not send anything for whatever reason + /* + set_ioa_socket_app_type(s, HTTP_CLIENT_SOCKET); + ioa_network_buffer_handle nbh = ioa_network_buffer_allocate(s->e); + uint8_t *data = ioa_network_buffer_data(nbh); + bcopy(http_response, data, rlen); + ioa_network_buffer_set_size(nbh, rlen); + send_data_from_ioa_socket_nbh(s, NULL, nbh, TTL_IGNORE, TOS_IGNORE, NULL); + */ + + return 0; +} /////////////////////////////////////////////// static struct headers_list * post_parse(char *data, size_t data_len) diff --git a/src/apps/relay/mainrelay.c b/src/apps/relay/mainrelay.c index 2343a1cd..e6462d9d 100644 --- a/src/apps/relay/mainrelay.c +++ b/src/apps/relay/mainrelay.c @@ -1673,25 +1673,25 @@ static void read_config_file(int argc, char **argv, int pass) if(pass == 0) { - if (argv) { - int i = 0; - for (i = 0; i < argc; i++) { - if (!strcmp(argv[i], "-c")) { - if (i < argc - 1) { - STRCPY(config_file, argv[i + 1]); - } else { - TURN_LOG_FUNC(TURN_LOG_LEVEL_WARNING, "Wrong usage of -c option\n"); + if (argv) { + int i = 0; + for (i = 0; i < argc; i++) { + if (!strcmp(argv[i], "-c")) { + if (i < argc - 1) { + STRCPY(config_file, argv[i + 1]); + } else { + TURN_LOG_FUNC(TURN_LOG_LEVEL_WARNING, "Wrong usage of -c option\n"); + } + } else if (!strcmp(argv[i], "-n")) { + turn_params.do_not_use_config_file = 1; + config_file[0]=0; + return; + } else if (!strcmp(argv[i], "-h")) { + printf("\n%s\n",Usage); + exit(0); + } + } } - } else if (!strcmp(argv[i], "-n")) { - turn_params.do_not_use_config_file = 1; - config_file[0]=0; - return; - } else if (!strcmp(argv[i], "-h")) { - printf("\n%s\n",Usage); - exit(0); - } - } - } } if (!turn_params.do_not_use_config_file && config_file[0]) { @@ -1728,7 +1728,7 @@ static void read_config_file(int argc, char **argv, int pass) STRCPY(sarg, s); if (parse_arg_string(sarg, &c, &value) < 0) { TURN_LOG_FUNC(TURN_LOG_LEVEL_WARNING, "Bad configuration format: %s\n", - sarg); + sarg); } else if((pass == 0) && (c == 'l')) { set_logfile(value); } else if((pass==0) && (c==NO_STDOUT_LOG_OPT)) { @@ -1742,9 +1742,9 @@ static void read_config_file(int argc, char **argv, int pass) } else if ((pass==0) && (c==NEW_LOG_TIMESTAMP_FORMAT_OPT)) { set_turn_log_timestamp_format(value); } else if((pass == 0) && (c != 'u')) { - set_option(c, value); + set_option(c, value); } else if((pass > 0) && (c == 'u')) { - set_option(c, value); + set_option(c, value); } if (s[slen - 1] == 59) { TURN_LOG_FUNC(TURN_LOG_LEVEL_WARNING, "Check config! The following line ends with semicolon: \"%s\" \n",s); @@ -1757,7 +1757,7 @@ static void read_config_file(int argc, char **argv, int pass) } else TURN_LOG_FUNC(TURN_LOG_LEVEL_WARNING, "WARNING: Cannot find config file: %s. Default and command-line settings will be used.\n", - config_file); + config_file); if (full_path_to_config_file) { free(full_path_to_config_file); @@ -1770,7 +1770,7 @@ static int disconnect_database(void) { const turn_dbdriver_t * dbd = get_dbdriver(); if (dbd && dbd->disconnect) { - dbd->disconnect(); + dbd->disconnect(); } return 0; } @@ -1801,183 +1801,183 @@ static int adminmain(int argc, char **argv) while (((c = getopt_long(argc, argv, ADMIN_OPTIONS, uo.u.o, NULL)) != -1)) { switch (c){ - case 'P': - if(pwd[0]) { - char result[257]; - generate_new_enc_password((char*)pwd, result); - printf("%s\n",result); - exit(0); - } - print_enc_password = 1; - break; - case 'E': - print_enc_aes_password = 1; - break; - case 'g': - ct = TA_SET_REALM_OPTION; - break; - case 'G': - ct = TA_LIST_REALM_OPTIONS; - break; - case ADMIN_USER_QUOTA_OPT: - po.user_quota = (vint)atoi(optarg); - break; - case ADMIN_TOTAL_QUOTA_OPT: - po.total_quota = (vint)atoi(optarg); - break; - case ADMIN_MAX_BPS_OPT: - po.max_bps = (vint)atoi(optarg); - break; - case 'O': - ct = TA_ADD_ORIGIN; - break; - case 'R': - ct = TA_DEL_ORIGIN; - break; - case 'I': - ct = TA_LIST_ORIGINS; - break; - case 'o': - STRCPY(origin,optarg); - break; - case 'k': - ct = TA_PRINT_KEY; - break; - case 'a': - ct = TA_UPDATE_USER; - break; - case 'd': - ct = TA_DELETE_USER; - break; - case 'A': - ct = TA_UPDATE_USER; - is_admin = 1; - break; - case 'D': - ct = TA_DELETE_USER; - is_admin = 1; - break; - case 'l': - ct = TA_LIST_USERS; - break; - case 'L': - ct = TA_LIST_USERS; - is_admin = 1; - break; - case 's': - ct = TA_SET_SECRET; - STRCPY(secret,optarg); - break; - case 'S': - ct = TA_SHOW_SECRET; - break; - case 'X': - ct = TA_DEL_SECRET; - if(optarg) - STRCPY(secret,optarg); - break; - case DEL_ALL_AUTH_SECRETS_OPT: - ct = TA_DEL_SECRET; - break; + case 'P': + if(pwd[0]) { + char result[257]; + generate_new_enc_password((char*)pwd, result); + printf("%s\n",result); + exit(0); + } + print_enc_password = 1; + break; + case 'E': + print_enc_aes_password = 1; + break; + case 'g': + ct = TA_SET_REALM_OPTION; + break; + case 'G': + ct = TA_LIST_REALM_OPTIONS; + break; + case ADMIN_USER_QUOTA_OPT: + po.user_quota = (vint)atoi(optarg); + break; + case ADMIN_TOTAL_QUOTA_OPT: + po.total_quota = (vint)atoi(optarg); + break; + case ADMIN_MAX_BPS_OPT: + po.max_bps = (vint)atoi(optarg); + break; + case 'O': + ct = TA_ADD_ORIGIN; + break; + case 'R': + ct = TA_DEL_ORIGIN; + break; + case 'I': + ct = TA_LIST_ORIGINS; + break; + case 'o': + STRCPY(origin,optarg); + break; + case 'k': + ct = TA_PRINT_KEY; + break; + case 'a': + ct = TA_UPDATE_USER; + break; + case 'd': + ct = TA_DELETE_USER; + break; + case 'A': + ct = TA_UPDATE_USER; + is_admin = 1; + break; + case 'D': + ct = TA_DELETE_USER; + is_admin = 1; + break; + case 'l': + ct = TA_LIST_USERS; + break; + case 'L': + ct = TA_LIST_USERS; + is_admin = 1; + break; + case 's': + ct = TA_SET_SECRET; + STRCPY(secret,optarg); + break; + case 'S': + ct = TA_SHOW_SECRET; + break; + case 'X': + ct = TA_DEL_SECRET; + if(optarg) + STRCPY(secret,optarg); + break; + case DEL_ALL_AUTH_SECRETS_OPT: + ct = TA_DEL_SECRET; + break; #if !defined(TURN_NO_SQLITE) - case 'b': - STRCPY(turn_params.default_users_db.persistent_users_db.userdb,optarg); - turn_params.default_users_db.userdb_type = TURN_USERDB_TYPE_SQLITE; - break; + case 'b': + STRCPY(turn_params.default_users_db.persistent_users_db.userdb,optarg); + turn_params.default_users_db.userdb_type = TURN_USERDB_TYPE_SQLITE; + break; #endif #if !defined(TURN_NO_PQ) - case 'e': - STRCPY(turn_params.default_users_db.persistent_users_db.userdb,optarg); - turn_params.default_users_db.userdb_type = TURN_USERDB_TYPE_PQ; - break; + case 'e': + STRCPY(turn_params.default_users_db.persistent_users_db.userdb,optarg); + turn_params.default_users_db.userdb_type = TURN_USERDB_TYPE_PQ; + break; #endif #if !defined(TURN_NO_MYSQL) - case 'M': - STRCPY(turn_params.default_users_db.persistent_users_db.userdb,optarg); - turn_params.default_users_db.userdb_type = TURN_USERDB_TYPE_MYSQL; - break; + case 'M': + STRCPY(turn_params.default_users_db.persistent_users_db.userdb,optarg); + turn_params.default_users_db.userdb_type = TURN_USERDB_TYPE_MYSQL; + break; #endif #if !defined(TURN_NO_MONGO) - case 'J': - STRCPY(turn_params.default_users_db.persistent_users_db.userdb,optarg); - turn_params.default_users_db.userdb_type = TURN_USERDB_TYPE_MONGO; - break; + case 'J': + STRCPY(turn_params.default_users_db.persistent_users_db.userdb,optarg); + turn_params.default_users_db.userdb_type = TURN_USERDB_TYPE_MONGO; + break; #endif #if !defined(TURN_NO_HIREDIS) - case 'N': - STRCPY(turn_params.default_users_db.persistent_users_db.userdb,optarg); - turn_params.default_users_db.userdb_type = TURN_USERDB_TYPE_REDIS; - break; + case 'N': + STRCPY(turn_params.default_users_db.persistent_users_db.userdb,optarg); + turn_params.default_users_db.userdb_type = TURN_USERDB_TYPE_REDIS; + break; #endif - case 'u': - STRCPY(user,optarg); - if(!is_secure_string((uint8_t*)user,1)) { - TURN_LOG_FUNC(TURN_LOG_LEVEL_ERROR, "Wrong user name structure or symbols, choose another name: %s\n",user); - exit(-1); - } - if(SASLprep((uint8_t*)user)<0) { - TURN_LOG_FUNC(TURN_LOG_LEVEL_ERROR, "Wrong user name: %s\n",user); - exit(-1); - } - break; - case 'r': - set_default_realm_name(optarg); - STRCPY(realm,optarg); - if(SASLprep((uint8_t*)realm)<0) { - TURN_LOG_FUNC(TURN_LOG_LEVEL_ERROR, "Wrong realm: %s\n",realm); - exit(-1); - } - break; - case 'p': - STRCPY(pwd,optarg); - if(SASLprep((uint8_t*)pwd)<0) { - TURN_LOG_FUNC(TURN_LOG_LEVEL_ERROR, "Wrong password: %s\n",pwd); - exit(-1); - } - if(print_enc_password) { - char result[257]; - generate_new_enc_password((char*)pwd, result); - printf("%s\n",result); - exit(0); - } - if(print_enc_aes_password){ - encrypt_aes_128(pwd, generated_key); - exit(0); - } - break; - case 'x': - generate_aes_128_key(optarg, generated_key); - exit(0); - break; - case 'f': - fptr = fopen((char*)optarg, "r"); - if(fptr == NULL){ - printf("No such file like %s\n", (char*)optarg); - } - else{ - fseek (fptr, 0, SEEK_SET); - rc = fread(generated_key, sizeof(char), 16, fptr); - if( rc == 0 ){ - TURN_LOG_FUNC(TURN_LOG_LEVEL_ERROR, "%s: ERROR: Secret-Key file is empty\n",__FUNCTION__); + case 'u': + STRCPY(user,optarg); + if(!is_secure_string((uint8_t*)user,1)) { + TURN_LOG_FUNC(TURN_LOG_LEVEL_ERROR, "Wrong user name structure or symbols, choose another name: %s\n",user); + exit(-1); + } + if(SASLprep((uint8_t*)user)<0) { + TURN_LOG_FUNC(TURN_LOG_LEVEL_ERROR, "Wrong user name: %s\n",user); + exit(-1); + } + break; + case 'r': + set_default_realm_name(optarg); + STRCPY(realm,optarg); + if(SASLprep((uint8_t*)realm)<0) { + TURN_LOG_FUNC(TURN_LOG_LEVEL_ERROR, "Wrong realm: %s\n",realm); + exit(-1); + } + break; + case 'p': + STRCPY(pwd,optarg); + if(SASLprep((uint8_t*)pwd)<0) { + TURN_LOG_FUNC(TURN_LOG_LEVEL_ERROR, "Wrong password: %s\n",pwd); + exit(-1); + } + if(print_enc_password) { + char result[257]; + generate_new_enc_password((char*)pwd, result); + printf("%s\n",result); + exit(0); + } + if(print_enc_aes_password){ + encrypt_aes_128(pwd, generated_key); + exit(0); + } + break; + case 'x': + generate_aes_128_key(optarg, generated_key); + exit(0); + break; + case 'f': + fptr = fopen((char*)optarg, "r"); + if(fptr == NULL){ + printf("No such file like %s\n", (char*)optarg); } else{ - if( rc != 16 ){ - TURN_LOG_FUNC(TURN_LOG_LEVEL_ERROR, "%s: ERROR: Secret-Key length is not enough\n",__FUNCTION__); + fseek (fptr, 0, SEEK_SET); + rc = fread(generated_key, sizeof(char), 16, fptr); + if( rc == 0 ){ + TURN_LOG_FUNC(TURN_LOG_LEVEL_ERROR, "%s: ERROR: Secret-Key file is empty\n",__FUNCTION__); } + else{ + if( rc != 16 ){ + TURN_LOG_FUNC(TURN_LOG_LEVEL_ERROR, "%s: ERROR: Secret-Key length is not enough\n",__FUNCTION__); + } + } + fclose (fptr); } - fclose (fptr); - } - break; - case 'v': - decrypt_aes_128((char*)optarg, generated_key); - exit(0); - case 'h': - printf("\n%s\n", AdminUsage); - exit(0); - break; - default: - fprintf(stderr,"\n%s\n", AdminUsage); - exit(-1); + break; + case 'v': + decrypt_aes_128((char*)optarg, generated_key); + exit(0); + case 'h': + printf("\n%s\n", AdminUsage); + exit(0); + break; + default: + fprintf(stderr,"\n%s\n", AdminUsage); + exit(-1); } } @@ -2021,16 +2021,16 @@ static void print_features(unsigned long mfn) TURN_LOG_FUNC(TURN_LOG_LEVEL_INFO, "\n\n==== Show him the instruments, Practical Frost: ====\n\n"); -/* - Frost stepped forward and opened the polished case with a theatrical - flourish. It was a masterful piece of craftsmanship. As the lid was - pulled back, the many trays inside lifted and fanned out, displaying - Glokta’s tools in all their gruesome glory. There were blades of every - size and shape, needles curved and straight, bottles of oil and acid, - nails and screws, clamps and pliers, saws, hammers, chisels. Metal, wood - and glass glittered in the bright lamplight, all polished to mirror - brightness and honed to a murderous sharpness. -*/ + /* + Frost stepped forward and opened the polished case with a theatrical + flourish. It was a masterful piece of craftsmanship. As the lid was + pulled back, the many trays inside lifted and fanned out, displaying + Glokta’s tools in all their gruesome glory. There were blades of every + size and shape, needles curved and straight, bottles of oil and acid, + nails and screws, clamps and pliers, saws, hammers, chisels. Metal, wood + and glass glittered in the bright lamplight, all polished to mirror + brightness and honed to a murderous sharpness. + */ #if !TLS_SUPPORTED TURN_LOG_FUNC(TURN_LOG_LEVEL_INFO, "TLS is not supported\n"); diff --git a/src/server/ns_turn_ioalib.h b/src/server/ns_turn_ioalib.h index da3e7c5a..4b9f38ad 100644 --- a/src/server/ns_turn_ioalib.h +++ b/src/server/ns_turn_ioalib.h @@ -285,6 +285,7 @@ int get_default_protocol_port(const char* scheme, size_t slen); ///////////// HTTP //////////////////// void handle_http_echo(ioa_socket_handle s); +int try_acme_redirect(char *req, size_t len, const char *url, ioa_socket_handle s); ///////////// ACME ///////////////////// From 02d62e828dfcbfab351039f2719d443605460a33 Mon Sep 17 00:00:00 2001 From: Jens Elkner Date: Mon, 18 May 2020 17:00:31 +0200 Subject: [PATCH 34/55] acme-redirect: add option to man page, fix help text --- man/man1/turnserver.1 | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/man/man1/turnserver.1 b/man/man1/turnserver.1 index 3a9131bd..4fbd2673 100644 --- a/man/man1/turnserver.1 +++ b/man/man1/turnserver.1 @@ -787,6 +787,13 @@ File name to store the pid of the process. Default is /var/run/turnserver.pid (if superuser account is used) or /var/tmp/turnserver.pid . .TP +.BI --acme-redirect\ URL +Redirect ACME/RFC8555 (like Let's Encrypt challenge) requests, i.e. +HTTP GET requests matching '^/.well-known/acme-challenge/(.*)' +to \fIURL\fR$1 with $1 == (.*). No validation of \fIURL\fR will be done, +so make sure you do not forget the trailing slash. If \fIURL\fR is an empty +string (the default value), no special handling of such requests will be done. +.TP .B \fB\-\-proc\-user\fP User name to run the process. After the initialization, the \fIturnserver\fP process From fa01cfeed6ceb7a0a16cb7144d4549a4a2d3f710 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?M=C3=A9sz=C3=A1ros=20Mih=C3=A1ly?= Date: Sat, 8 Aug 2020 22:47:41 +0200 Subject: [PATCH 35/55] Move acme to new file --- ChangeLog | 2 + man/man1/turnserver.1 | 7 ---- src/apps/relay/http_server.c | 77 ------------------------------------ src/server/ns_turn_ioalib.h | 3 ++ 4 files changed, 5 insertions(+), 84 deletions(-) diff --git a/ChangeLog b/ChangeLog index 95f10a8f..f2210baa 100644 --- a/ChangeLog +++ b/ChangeLog @@ -23,6 +23,8 @@ Version 4.5.2 'dan Eider': * fix compilation on macOS Big Sur - merge PR #546 (by jelmd) * Add ACME redirect url + - merge PR #551 (by jelmd) + * support of --acme-redirect 24/06/2020 Oleg Moskalenko Mihály Mészáros Version 4.5.1.3 'dan Eider': diff --git a/man/man1/turnserver.1 b/man/man1/turnserver.1 index 4fbd2673..3a9131bd 100644 --- a/man/man1/turnserver.1 +++ b/man/man1/turnserver.1 @@ -787,13 +787,6 @@ File name to store the pid of the process. Default is /var/run/turnserver.pid (if superuser account is used) or /var/tmp/turnserver.pid . .TP -.BI --acme-redirect\ URL -Redirect ACME/RFC8555 (like Let's Encrypt challenge) requests, i.e. -HTTP GET requests matching '^/.well-known/acme-challenge/(.*)' -to \fIURL\fR$1 with $1 == (.*). No validation of \fIURL\fR will be done, -so make sure you do not forget the trailing slash. If \fIURL\fR is an empty -string (the default value), no special handling of such requests will be done. -.TP .B \fB\-\-proc\-user\fP User name to run the process. After the initialization, the \fIturnserver\fP process diff --git a/src/apps/relay/http_server.c b/src/apps/relay/http_server.c index ca70d77e..ff8e3992 100644 --- a/src/apps/relay/http_server.c +++ b/src/apps/relay/http_server.c @@ -99,83 +99,6 @@ const char* get_http_date_header() return buffer_header; } -static int is_acme_req(char *req, size_t len) { - static const char *A = " - 0123456789 ABCDEFGHIJKLMNOPQRSTUVWXYZ _ abcdefghijklmnopqrstuvwxyz "; - int c, i, k; - - // Check first request line. Should be like: GET path HTTP/1.x - if (strncmp(req, "GET /.well-known/acme-challenge/", 32)) - return -1; - // Usually (for LE) the "method path" is 32 + 43 = 55 chars. But other - // implementations may choose longer pathes. We define PATHMAX = 127 chars - // to be prepared for "DoS" attacks (STUN msg size max. is ~ 64K). - len =- 21; // min size of trailing headers - if (len > 131) - len = 131; - for (i=32; i < (int) len; i++) { - // find the end of the path - if (req[i] != ' ') - continue; - // consider path < 10 chars invalid. Also we wanna see a "trailer". - if (i < 42 || strncmp(req + i, " HTTP/1.", 8)) - return -2; - // finally check for allowed chars - for (k=32; k < i; k++) { - c = req[k]; - if ((c > 127) || (A[c] == ' ')) - return -3; - } - // all checks passed: sufficient for us to answer with a redirect - return i; - } - return -4; // end of path not found -} - -int try_acme_redirect(char *req, size_t len, const char *url, - ioa_socket_handle s) -{ - static const char *HTML = "301 Moved Permanently

301 Moved Permanently

"; - char http_response[1024]; - int plen, rlen; - - if (url == NULL || url[0] == '\0' || req == NULL || s == 0 ) - return 1; - if (len < 64 || len > 512 || (plen = is_acme_req(req, len)) < 33) - return 2; - - req[plen] = '\0'; - snprintf(http_response, sizeof(http_response) - 1, - "HTTP/1.1 301 Moved Permanently\r\n" - "Content-Type: text/html\r\n" - "Content-Length: %ld\r\n" - "Connection: close\r\n" - "Location: %s%s\r\n" - "\r\n%s", strlen(HTML), url, req + 32, HTML); - - rlen = strlen(http_response); - - // Variant A: direkt write, no eventbuf stuff - if (write(s->fd, http_response, rlen) == -1) { - perror("Sending redirect failed"); - } else if (((turn_turnserver *)s->session->server)->verbose) { - TURN_LOG_FUNC(TURN_LOG_LEVEL_INFO, "ACME redirect to %s%s\n", - url, req + 32); - } - - req[plen] = ' '; - - // Variant B: via eventbuf does not send anything for whatever reason - /* - set_ioa_socket_app_type(s, HTTP_CLIENT_SOCKET); - ioa_network_buffer_handle nbh = ioa_network_buffer_allocate(s->e); - uint8_t *data = ioa_network_buffer_data(nbh); - bcopy(http_response, data, rlen); - ioa_network_buffer_set_size(nbh, rlen); - send_data_from_ioa_socket_nbh(s, NULL, nbh, TTL_IGNORE, TOS_IGNORE, NULL); - */ - - return 0; -} /////////////////////////////////////////////// static struct headers_list * post_parse(char *data, size_t data_len) diff --git a/src/server/ns_turn_ioalib.h b/src/server/ns_turn_ioalib.h index 4b9f38ad..e592055f 100644 --- a/src/server/ns_turn_ioalib.h +++ b/src/server/ns_turn_ioalib.h @@ -285,6 +285,9 @@ int get_default_protocol_port(const char* scheme, size_t slen); ///////////// HTTP //////////////////// void handle_http_echo(ioa_socket_handle s); + +///////////// ACME ///////////////////// + int try_acme_redirect(char *req, size_t len, const char *url, ioa_socket_handle s); ///////////// ACME ///////////////////// From 1300021c6f6d828240b88784338539e4738d22cb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?M=C3=A9sz=C3=A1ros=20Mih=C3=A1ly?= Date: Tue, 15 Dec 2020 13:35:21 +0000 Subject: [PATCH 36/55] Correct acme-redirect man and readme --- README.turnserver | 6 +++ man/man1/turnadmin.1 | 32 ++++++++-------- man/man1/turnserver.1 | 87 ++++++++++++++++++++++++------------------- man/man1/turnutils.1 | 61 +++++++++++++++--------------- 4 files changed, 103 insertions(+), 83 deletions(-) diff --git a/README.turnserver b/README.turnserver index 5969ba6d..df74704b 100644 --- a/README.turnserver +++ b/README.turnserver @@ -547,6 +547,12 @@ Options with values: Default is /var/run/turnserver.pid (if superuser account is used) or /var/tmp/turnserver.pid . +--acme-redirect Redirect ACME/RFC8555 (like Let's Encrypt challenge) requests, i.e. + HTTP GET requests matching '^/.well-known/acme-challenge/(.*)' + to $1 with $1 == (.*). No validation of will be done, + so make sure you do not forget the trailing slash. If is an empty + string (the default value), no special handling of such requests will be done. + --proc-user User name to run the process. After the initialization, the turnserver process will make an attempt to change the current user ID to that user. diff --git a/man/man1/turnadmin.1 b/man/man1/turnadmin.1 index dc2982c2..8540085b 100644 --- a/man/man1/turnadmin.1 +++ b/man/man1/turnadmin.1 @@ -1,5 +1,5 @@ .\" Text automatically generated by txt2man -.TH TURN 1 "08 December 2020" "" "" +.TH TURN 1 "15 December 2020" "" "" .SH GENERAL INFORMATION \fIturnadmin\fP is a TURN administration tool. This tool can be used to manage @@ -48,8 +48,8 @@ is equivalent to: .fi You have always the use the \fB\-r\fP option with commands for long term credentials \- because data for multiple realms can be stored in the same database. -.SH ===================================== - +.PP +===================================== .SS NAME \fB \fBturnadmin \fP\- a TURN relay administration tool. @@ -288,8 +288,8 @@ $ \fIturnadmin\fP \fB\-\-file\-key\-path\fP \fB\-v\fP Help: .PP $ \fIturnadmin\fP \fB\-h\fP -.SH ======================================= - +.PP +======================================= .SS DOCS After installation, run the \fIcommand\fP: @@ -301,8 +301,8 @@ or in the project root directory: $ man \fB\-M\fP man \fIturnadmin\fP .PP to see the man page. -.SH ===================================== - +.PP +===================================== .SS FILES /etc/turnserver.conf @@ -314,8 +314,8 @@ to see the man page. /var/lib/turn/turndb .PP /usr/local/etc/turnserver.conf -.SH ===================================== - +.PP +===================================== .SS DIRECTORIES /usr/local/share/\fIturnserver\fP @@ -323,13 +323,14 @@ to see the man page. /usr/local/share/doc/\fIturnserver\fP .PP /usr/local/share/examples/\fIturnserver\fP -.SH ====================================== - +.PP +====================================== .SS SEE ALSO \fIturnserver\fP, \fIturnutils\fP -.SH ====================================== - +.RE +.PP +====================================== .SS WEB RESOURCES project page: @@ -343,8 +344,9 @@ https://github.com/coturn/coturn/wiki forum: .PP https://groups.google.com/forum/?fromgroups=#!forum/turn\-server\-project\-rfc5766\-turn\-server/ -.SH ====================================== - +.RE +.PP +====================================== .SS AUTHORS Oleg Moskalenko diff --git a/man/man1/turnserver.1 b/man/man1/turnserver.1 index 3a9131bd..f52a25c5 100644 --- a/man/man1/turnserver.1 +++ b/man/man1/turnserver.1 @@ -1,5 +1,5 @@ .\" Text automatically generated by txt2man -.TH TURN 1 "08 December 2020" "" "" +.TH TURN 1 "15 December 2020" "" "" .SH GENERAL INFORMATION The \fBTURN Server\fP project contains the source code of a TURN server and TURN client @@ -78,8 +78,7 @@ is equivalent to: .fam T .fi -.SH ===================================== - +===================================== .SS NAME \fB \fBturnserver \fP\- a TURN relay server implementation. @@ -788,6 +787,14 @@ Default is /var/run/turnserver.pid (if superuser account is used) or /var/tmp/turnserver.pid . .TP .B +\fB\-\-acme\-redirect\fP + Redirect ACME/RFC8555 (like Let's Encrypt challenge) requests, i.e. +HTTP GET requests matching '^/.well\-known/acme\-challenge/(.*)' +to $1 with $1 == (.*). No validation of will be done, +so make sure you do not forget the trailing slash. If is an empty +string (the default value), no special handling of such requests will be done. +.TP +.B \fB\-\-proc\-user\fP User name to run the process. After the initialization, the \fIturnserver\fP process will make an attempt to change the current user ID to that user. @@ -848,15 +855,15 @@ By default it is disabled for security resons! .B \fB\-\-ne\fP=[1|2|3] Set network engine type for the process (for internal purposes). -.SH ================================== - +.PP +================================== .SH LOAD BALANCE AND PERFORMANCE TUNING This topic is covered in the wiki page: .PP https://github.com/coturn/coturn/wiki/turn_performance_and_load_balance -.SH =================================== - +.PP +=================================== .SH WEBRTC USAGE This is a set of notes for the WebRTC users: @@ -893,8 +900,8 @@ Usually WebRTC uses fingerprinting (\fB\-f\fP). .IP 5) 4 \fB\-\-min\-port\fP and \fB\-\-max\-port\fP may be needed if you want to limit the relay endpoints ports number range. -.SH =================================== - +.PP +=================================== .SH TURN REST API In WebRTC, the browser obtains the TURN connection information from the web @@ -1032,8 +1039,8 @@ examples/scripts/restapi/shared_secret_maintainer.pl . .PP A very important thing is that the nonce must be totally random and it must be different for different clients and different sessions. -.SH =================================== - +.PP +=================================== .SH DATABASES For the user database, the \fIturnserver\fP has the following \fIoptions\fP: @@ -1096,8 +1103,8 @@ it will set the users for you (see the \fIturnadmin\fP manuals). If you are usin \fIturnserver\fP or \fIturnadmin\fP 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). -.SH ================================= - +.PP +================================= .SH ALPN The server supports ALPNs "stun.turn" and "stun.nat\-discovery", when @@ -1106,16 +1113,16 @@ 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 extension field. If no stun.* label is found, then the server does not include the ALPN information into the ServerHello. -.SH ================================= - +.PP +================================= .SH LIBRARIES In the lib/ sub\-directory the build process will create TURN client messaging library. In the include/ sub\-directory, the necessary include files will be placed. The C++ wrapper for the messaging functionality is located in TurnMsgLib.h header. An example of C++ code can be found in stunclient.c file. -.SH ================================= - +.PP +================================= .SH DOCS After installation, run the command: @@ -1130,8 +1137,8 @@ to see the man page. .PP In the docs/html subdirectory of the original archive tree, you will find the client library reference. After the installation, it will be placed in PREFIX/share/doc/\fIturnserver\fP/html. -.SH ================================= - +.PP +================================= .SH LOGS When the \fBTURN Server\fP starts, it makes efforts to create a log file turn_.log @@ -1154,8 +1161,8 @@ log messages are sent only to the standard output of the process. .PP This behavior can be controlled by \fB\-\-log\-file\fP, \fB\-\-syslog\fP and \fB\-\-no\-stdout\-log\fP \fIoptions\fP. -.SH ================================= - +.PP +================================= .SH HTTPS MANAGEMENT INTERFACE The \fIturnserver\fP process provides an HTTPS Web access as statistics and basic @@ -1168,8 +1175,8 @@ populated with the admin user \fBaccount\fP(s). An admin user can be a superuser (if not assigned to a particular realm) or a restricted user (if assigned to a realm). The restricted admin users can perform only limited actions, within their corresponding realms. -.SH ================================= - +.PP +================================= .SH TELNET CLI The \fIturnserver\fP process provides a telnet CLI access as statistics and basic management @@ -1177,8 +1184,8 @@ interface. By default, the \fIturnserver\fP starts a telnet CLI listener on IP 1 port 5766. That can be changed by the command\-cline \fIoptions\fP of the \fIturnserver\fP process (see \fB\-\-cli\-ip\fP and \fB\-\-cli\-port\fP \fIoptions\fP). The full list of telnet CLI commands is provided in "help" command output in the telnet CLI. -.SH ================================= - +.PP +================================= .SH CLUSTERS \fBTURN Server\fP can be a part of the cluster installation. But, to support the "even port" functionality @@ -1187,8 +1194,8 @@ in "help" command output in the telnet CLI. the RTP and RTCP relaying endpoints must be allocated on the same relay IP. It would be possible to design a scheme with the application\-level requests forwarding (and we may do that later) but it would affect the performance. -.SH ================================= - +.PP +================================= .SH FILES /etc/turnserver.conf @@ -1200,8 +1207,8 @@ it would affect the performance. /var/lib/turn/turndb .PP /usr/local/etc/turnserver.conf -.SH ================================= - +.PP +================================= .SH DIRECTORIES /usr/local/share/\fIturnserver\fP @@ -1209,15 +1216,16 @@ it would affect the performance. /usr/local/share/doc/\fIturnserver\fP .PP /usr/local/share/examples/\fIturnserver\fP -.SH ================================= - +.PP +================================= .SH STANDARDS obsolete STUN RFC 3489 .PP new STUN RFC 5389 -.SH TURN RFC 5766 - +.PP +TURN RFC 5766 +.PP TURN\-TCP extension RFC 6062 .PP TURN IPv6 extension RFC 6156 @@ -1225,13 +1233,14 @@ TURN IPv6 extension RFC 6156 STUN/TURN test vectors RFC 5769 .PP STUN NAT behavior discovery RFC 5780 -.SH ================================= - +.PP +================================= .SH SEE ALSO \fIturnadmin\fP, \fIturnutils\fP -.SH ====================================== - +.RE +.PP +====================================== .SS WEB RESOURCES project page: @@ -1245,8 +1254,8 @@ https://github.com/coturn/coturn/wiki forum: .PP https://groups.google.com/forum/?fromgroups=#!forum/turn\-server\-project\-rfc5766\-turn\-server -.SH ====================================== - +.PP +====================================== .SS AUTHORS Oleg Moskalenko diff --git a/man/man1/turnutils.1 b/man/man1/turnutils.1 index 93a03ef3..809f83a4 100644 --- a/man/man1/turnutils.1 +++ b/man/man1/turnutils.1 @@ -1,5 +1,5 @@ .\" Text automatically generated by txt2man -.TH TURN 1 "08 December 2020" "" "" +.TH TURN 1 "15 December 2020" "" "" .SH GENERAL INFORMATION A set of turnutils_* programs provides some utility functionality to be used @@ -63,8 +63,8 @@ script in examples/scripts/oauth.sh. .RE .PP -.SH ===================================== - +.RS +===================================== .SS NAME \fB \fBturnutils_uclient \fP\- this client emulation application is supplied for the test purposes only. @@ -276,8 +276,8 @@ the ORIGIN STUN attribute value. Bandwidth for the bandwidth request in ALLOCATE. The default value is zero. .PP See the examples in the "examples/scripts" directory. -.SH ====================================== - +.PP +====================================== .SS NAME \fB \fBturnutils_peer \fP\- a simple UDP\-only echo backend server. @@ -314,8 +314,8 @@ If no listener \fBaddress\fP(es) defined, then it listens on all IPv4 and IPv6 a .B \fB\-v\fP Verbose -.SH ======================================== - +.PP +======================================== .SS NAME \fB \fBturnutils_stunclient \fP\- a basic STUN client. @@ -354,8 +354,8 @@ and if it finds that the STUN server supports RFC 5780 requests with different parameters, to demonstrate the NAT discovery capabilities. .PP This utility does not support the "old" "classic" STUN protocol (RFC 3489). -.SH ===================================== - +.PP +===================================== .SS NAME \fB \fBturnutils_rfc5769check \fP\- a utility that tests the correctness of STUN protocol implementation. @@ -380,8 +380,8 @@ check procedure, it is not copied to the installation destination. Usage: .PP $ \fIturnutils_rfc5769check\fP -.SH ===================================== - +.PP +===================================== .SS NAME \fB \fBturnutils_natdiscovery \fP\- a utility that discovers NAT mapping and filtering @@ -462,8 +462,8 @@ Used by mapping lifetime behavior discovery Usage: .PP $ \fIturnutils_natdiscovery\fP \fB\-m\fP \fB\-f\fP stun.example.com -.SH ===================================== - +.PP +===================================== .SS NAME \fB \fBturnutils_oauth \fP\- a utility that helps OAuth access_token generation/encryption and validation/decyption @@ -568,8 +568,8 @@ stun client hmac algorithm Usage: .PP $ \fIturnutils_natdiscovery\fP -.SH =================================== - +.PP +=================================== .SH DOCS After installation, run the command: @@ -581,8 +581,8 @@ or in the project root directory: $ man \fB\-M\fP man \fIturnutils\fP .PP to see the man page. -.SH ===================================== - +.PP +===================================== .SH FILES /etc/turnserver.conf @@ -594,8 +594,8 @@ to see the man page. /var/lib/turn/turndb .PP /usr/local/etc/turnserver.conf -.SH ================================= - +.PP +================================= .SH DIRECTORIES /usr/local/share/\fIturnserver\fP @@ -603,13 +603,14 @@ to see the man page. /usr/local/share/doc/\fIturnserver\fP .PP /usr/local/share/examples/\fIturnserver\fP -.SH =================================== - +.PP +=================================== .SH STANDARDS new STUN RFC 5389 -.SH TURN RFC 5766 - +.PP +TURN RFC 5766 +.PP TURN\-TCP extension RFC 6062 .PP TURN IPv6 extension RFC 6156 @@ -617,13 +618,14 @@ TURN IPv6 extension RFC 6156 STUN/TURN test vectors RFC 5769 .PP STUN NAT behavior discovery RFC 5780 -.SH ==================================== - +.PP +==================================== .SH SEE ALSO \fIturnserver\fP, \fIturnadmin\fP -.SH ====================================== - +.RE +.PP +====================================== .SS WEB RESOURCES project page: @@ -637,8 +639,9 @@ https://github.com/coturn/coturn/wiki forum: .PP https://groups.google.com/forum/?fromgroups=#!forum/turn\-server\-project\-rfc5766\-turn\-server/ -.SH ====================================== - +.RE +.PP +====================================== .SS AUTHORS Oleg Moskalenko From 174d039c73a055f168005ac0d5a9296445f0b493 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?M=C3=A9sz=C3=A1ros=20Mih=C3=A1ly?= Date: Tue, 15 Dec 2020 13:56:21 +0000 Subject: [PATCH 37/55] fix acme-redirect help --- src/apps/relay/mainrelay.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/apps/relay/mainrelay.c b/src/apps/relay/mainrelay.c index e6462d9d..73505663 100644 --- a/src/apps/relay/mainrelay.c +++ b/src/apps/relay/mainrelay.c @@ -629,8 +629,8 @@ static char Usage[] = "Usage: turnserver [options]\n" " --pidfile <\"pid-file-name\"> File name to store the pid of the process.\n" " Default is /var/run/turnserver.pid (if superuser account is used) or\n" " /var/tmp/turnserver.pid .\n" -" --acme-redirect Redirect ACME, i.e. HTTP GET requests matching '^/.well-known/acme-challenge/(.*)' to '$1'.\n" -" Default is '', i.e. no special handling for such requests.\n" +" --acme-redirect Redirect ACME, i.e. HTTP GET requests matching '^/.well-known/acme-challenge/(.*)' to '$1'.\n" +" Default is '', i.e. no special handling for such requests.\n" " --secure-stun Require authentication of the STUN Binding request.\n" " By default, the clients are allowed anonymous access to the STUN Binding functionality.\n" " --proc-user User name to run the turnserver process.\n" From d73a8e85d7ac205f142cb991ff5beee470481465 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?M=C3=A9sz=C3=A1ros=20Mih=C3=A1ly?= Date: Fri, 18 Dec 2020 08:05:19 +0000 Subject: [PATCH 38/55] Add acme to config file --- examples/etc/turnserver.conf | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/examples/etc/turnserver.conf b/examples/etc/turnserver.conf index aa919642..906a4b98 100644 --- a/examples/etc/turnserver.conf +++ b/examples/etc/turnserver.conf @@ -719,6 +719,10 @@ # #web-admin-listen-on-workers +#acme-redirect=http://redirectserver/.well-known/acme-challenge/ +# Redirect ACME, i.e. HTTP GET requests matching '^/.well-known/acme-challenge/(.*)' to '$1'. +# Default is '', i.e. no special handling for such requests. + # Server relay. NON-STANDARD AND DANGEROUS OPTION. # Only for those applications when you want to run # server applications on the relay endpoints. From 377e8f76871621634adc182b035d878c09baefd1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?M=C3=A9sz=C3=A1ros=20Mih=C3=A1ly?= Date: Fri, 18 Dec 2020 08:05:56 +0000 Subject: [PATCH 39/55] Ugly Hack: Parse HTTP request --- src/apps/relay/acme.c | 44 ++++++++++++++++++++++++++----------------- src/apps/relay/acme.h | 2 ++ 2 files changed, 29 insertions(+), 17 deletions(-) diff --git a/src/apps/relay/acme.c b/src/apps/relay/acme.c index 3e6d0c5e..c1109383 100644 --- a/src/apps/relay/acme.c +++ b/src/apps/relay/acme.c @@ -67,8 +67,33 @@ static int is_acme_req(char *req, size_t len) { int try_acme_redirect(char *req, size_t len, const char *url, ioa_socket_handle s) { - static const char *HTML = "301 Moved Permanently

301 Moved Permanently

"; + static const char *HTML = + "301 Moved Permanently\ +

301 Moved Permanently

"; char http_response[1024]; + char req_url[600]; + char *req_url_end_space, *req_url_end_tab; + int path_length; + strcpy(req_url, req + GET_WELLKNOWN_ACMECHALLANGE_URL_PREFIX_LENGTH); + req_url_end_space=strchr(req_url,' '); + req_url_end_tab=strchr(req_url,'\t'); + if (req_url_end_space != NULL && req_url_end_tab != NULL) { + if (req_url_end_space - req_url_end_tab > 0 ){ + path_length=req_url_end_space - req_url; + req_url[path_length]='\0'; + } else { + path_length=req_url_end_tab - req_url; + req_url[req_url_end_tab - req_url]='\0'; + } + } else if(req_url_end_space != NULL) { + path_length=req_url_end_space - req_url; + req_url[path_length]='\0'; + } + else if(req_url_end_tab != NULL) { + path_length=req_url_end_tab - req_url; + req_url[path_length]='\0'; + } + size_t plen, rlen; if (url == NULL || url[0] == '\0' || req == NULL || s == 0 ) @@ -76,31 +101,16 @@ int try_acme_redirect(char *req, size_t len, const char *url, if (len < 64 || len > 512 || (plen = is_acme_req(req, len)) < 33) return 2; - snprintf(http_response, sizeof(http_response) - 1, "HTTP/1.1 301 Moved Permanently\r\n" "Content-Type: text/html\r\n" "Content-Length: %ld\r\n" "Connection: close\r\n" "Location: %s%s\r\n" - "\r\n%s", strlen(HTML), url, req + 32, HTML); + "\r\n%s", strlen(HTML), url, req_url, HTML); rlen = strlen(http_response); - // Variant A: direkt write, no eventbuf stuff - /* - if (write(s->fd, http_response, rlen) == -1) { - perror("Sending redirect failed"); - } else if (((turn_turnserver *)s->session->server)->verbose) { - TURN_LOG_FUNC(TURN_LOG_LEVEL_INFO, "ACME redirect to %s%s\n", - url, req + 32); - } - - req[plen] = ' '; - */ - // Variant B: via eventbuf does not send anything for whatever reason - - //set_ioa_socket_app_type(s, HTTP_CLIENT_SOCKET); ioa_network_buffer_handle nbh_acme = ioa_network_buffer_allocate(s->e); uint8_t *data = ioa_network_buffer_data(nbh_acme); bcopy(http_response, data, rlen); diff --git a/src/apps/relay/acme.h b/src/apps/relay/acme.h index 133c22d1..a927dc56 100644 --- a/src/apps/relay/acme.h +++ b/src/apps/relay/acme.h @@ -44,6 +44,8 @@ extern "C" { ///////////// ACME ///////////////////// +#define GET_WELLKNOWN_ACMECHALLANGE_URL_PREFIX_LENGTH 32 + int try_acme_redirect(char *req, size_t len, const char *url, ioa_socket_handle s); /////////////////////////////////////// From 2f790ec18bb2c1bc6fcfc0586c81a2bd63a73225 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?M=C3=A9sz=C3=A1ros=20Mih=C3=A1ly?= Date: Fri, 18 Dec 2020 08:06:25 +0000 Subject: [PATCH 40/55] Tidy acme code --- src/server/ns_turn_server.c | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/src/server/ns_turn_server.c b/src/server/ns_turn_server.c index dafe26ee..f9e8f89b 100644 --- a/src/server/ns_turn_server.c +++ b/src/server/ns_turn_server.c @@ -4630,9 +4630,12 @@ static int read_client_connection(turn_turnserver *server, const char *proto = "HTTP"; if ((st == TCP_SOCKET) && ( - try_acme_redirect((char*)ioa_network_buffer_data(in_buffer->nbh), - ioa_network_buffer_get_size(in_buffer->nbh), - server->acme_redirect, ss->client_socket) == 0 + try_acme_redirect( + (char*)ioa_network_buffer_data(in_buffer->nbh), + ioa_network_buffer_get_size(in_buffer->nbh), + server->acme_redirect, + ss->client_socket + ) == 0 ) ) { ss->to_be_closed = 1; From ae541958cd4c818e5d44d06d6ec75a7f1944ade6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?M=C3=A9sz=C3=A1ros=20Mih=C3=A1ly?= Date: Fri, 18 Dec 2020 08:22:02 +0000 Subject: [PATCH 41/55] Tidy: remoe trailing space --- src/apps/relay/acme.c | 2 +- src/server/ns_turn_server.c | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/apps/relay/acme.c b/src/apps/relay/acme.c index c1109383..13023d7d 100644 --- a/src/apps/relay/acme.c +++ b/src/apps/relay/acme.c @@ -86,7 +86,7 @@ int try_acme_redirect(char *req, size_t len, const char *url, req_url[req_url_end_tab - req_url]='\0'; } } else if(req_url_end_space != NULL) { - path_length=req_url_end_space - req_url; + path_length=req_url_end_space - req_url; req_url[path_length]='\0'; } else if(req_url_end_tab != NULL) { diff --git a/src/server/ns_turn_server.c b/src/server/ns_turn_server.c index f9e8f89b..340b1fe7 100644 --- a/src/server/ns_turn_server.c +++ b/src/server/ns_turn_server.c @@ -4624,16 +4624,16 @@ static int read_client_connection(turn_turnserver *server, } else { SOCKET_TYPE st = get_ioa_socket_type(ss->client_socket); if(is_stream_socket(st)) { - if(is_http((char*)ioa_network_buffer_data(in_buffer->nbh), + if(is_http((char*)ioa_network_buffer_data(in_buffer->nbh), ioa_network_buffer_get_size(in_buffer->nbh))) { const char *proto = "HTTP"; - if ((st == TCP_SOCKET) && + if ((st == TCP_SOCKET) && ( try_acme_redirect( (char*)ioa_network_buffer_data(in_buffer->nbh), ioa_network_buffer_get_size(in_buffer->nbh), - server->acme_redirect, + server->acme_redirect, ss->client_socket ) == 0 ) From 6101ebd51b6731464ab346ae70159e8312d0b3c6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?M=C3=A9sz=C3=A1ros=20Mih=C3=A1ly?= Date: Tue, 22 Dec 2020 16:55:31 +0000 Subject: [PATCH 42/55] external-ip private part to white list fixes#584 --- src/apps/relay/mainrelay.c | 1 + 1 file changed, 1 insertion(+) diff --git a/src/apps/relay/mainrelay.c b/src/apps/relay/mainrelay.c index 73505663..472e316e 100644 --- a/src/apps/relay/mainrelay.c +++ b/src/apps/relay/mainrelay.c @@ -1372,6 +1372,7 @@ static void set_option(int c, char *value) TURN_LOG_FUNC(TURN_LOG_LEVEL_ERROR,"-X : Wrong address format: %s\n",div); } else { ioa_addr_add_mapping(&apub,&apriv); + if (add_ip_list_range((const char *)div, NULL, &turn_params.ip_whitelist) == 0) TURN_LOG_FUNC(TURN_LOG_LEVEL_INFO, "Whitelisting external-ip private part: %s\n", div); } } free(nval); From 8dc5bbcb3b7f2ef561293df8b920cb21b0eaf081 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?M=C3=A9sz=C3=A1ros=20Mih=C3=A1ly?= Date: Tue, 22 Dec 2020 17:05:42 +0000 Subject: [PATCH 43/55] Tidy: too long line length --- src/apps/relay/mainrelay.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/apps/relay/mainrelay.c b/src/apps/relay/mainrelay.c index 472e316e..102b8f1d 100644 --- a/src/apps/relay/mainrelay.c +++ b/src/apps/relay/mainrelay.c @@ -1372,7 +1372,8 @@ static void set_option(int c, char *value) TURN_LOG_FUNC(TURN_LOG_LEVEL_ERROR,"-X : Wrong address format: %s\n",div); } else { ioa_addr_add_mapping(&apub,&apriv); - if (add_ip_list_range((const char *)div, NULL, &turn_params.ip_whitelist) == 0) TURN_LOG_FUNC(TURN_LOG_LEVEL_INFO, "Whitelisting external-ip private part: %s\n", div); + if (add_ip_list_range((const char *)div, NULL, &turn_params.ip_whitelist) == 0) + TURN_LOG_FUNC(TURN_LOG_LEVEL_INFO, "Whitelisting external-ip private part: %s\n", div); } } free(nval); From 8c9950561488f99f6530040deef6ebf8122800b2 Mon Sep 17 00:00:00 2001 From: Jens Elkner Date: Thu, 31 Dec 2020 16:39:00 +0100 Subject: [PATCH 44/55] fix acme wrt. security, redundancy, consistency --- configure | 11 ++++++ src/apps/relay/acme.c | 81 ++++++++++++++----------------------------- src/apps/relay/acme.h | 2 -- 3 files changed, 37 insertions(+), 57 deletions(-) diff --git a/configure b/configure index 38227c6e..b85a65ca 100755 --- a/configure +++ b/configure @@ -556,6 +556,17 @@ if [ "${SYSTEM}" = "NetBSD" ] ; then fi fi +# If acme_redirect does not work, send_data_from_ioa_socket_nbh() probably +# does not work. Set LIBEV_OK=1 to use a workaround for it. +if [ -z "${LIBEV_OK}" ]; then + LIBEV_OK=1 + if [ "${SYSTEM}" = "Linux" ]; then + OS=$( lsb_release -si 2>/dev/null ) + [ "${OS}" = "Ubuntu" ] || LIBEV_OK=0 + fi +fi +[ "${LIBEV_OK}" = "1" ] && OSCFLAGS="${OSCFLAGS} -DLIBEV_OK" + ########################### # Install shell commands ########################### diff --git a/src/apps/relay/acme.c b/src/apps/relay/acme.c index 13023d7d..f713d348 100644 --- a/src/apps/relay/acme.c +++ b/src/apps/relay/acme.c @@ -1,43 +1,22 @@ /* - * Copyright (C) 2011, 2012, 2013, 2014 Citrix Systems + * Copyright (C) 2020 Jens Elkner. All rights reserved. * - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the project nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. + * License: MIT - see https://opensource.org/licenses/MIT */ #include "acme.h" #include "ns_ioalib_impl.h" +#define GET_ACME_PREFIX "GET /.well-known/acme-challenge/" +#define GET_ACME_PREFIX_LEN 32 + static int is_acme_req(char *req, size_t len) { static const char *A = " - 0123456789 ABCDEFGHIJKLMNOPQRSTUVWXYZ _ abcdefghijklmnopqrstuvwxyz "; int c, i, k; // Check first request line. Should be like: GET path HTTP/1.x - if (strncmp(req, "GET /.well-known/acme-challenge/", 32)) + if (strncmp(req, GET_ACME_PREFIX, GET_ACME_PREFIX_LEN)) return -1; // Usually (for LE) the "method path" is 32 + 43 = 55 chars. But other // implementations may choose longer pathes. We define PATHMAX = 127 chars @@ -45,15 +24,15 @@ static int is_acme_req(char *req, size_t len) { len =- 21; // min size of trailing headers if (len > 131) len = 131; - for (i=32; i < (int) len; i++) { + for (i=GET_ACME_PREFIX_LEN; i < (int) len; i++) { // find the end of the path if (req[i] != ' ') continue; // consider path < 10 chars invalid. Also we wanna see a "trailer". - if (i < 42 || strncmp(req + i, " HTTP/1.", 8)) + if (i < (GET_ACME_PREFIX_LEN + 10) || strncmp(req + i, " HTTP/1.", 8)) return -2; // finally check for allowed chars - for (k=32; k < i; k++) { + for (k=GET_ACME_PREFIX_LEN; k < i; k++) { c = req[k]; if ((c > 127) || (A[c] == ' ')) return -3; @@ -71,51 +50,43 @@ int try_acme_redirect(char *req, size_t len, const char *url, "301 Moved Permanently\

301 Moved Permanently

"; char http_response[1024]; - char req_url[600]; - char *req_url_end_space, *req_url_end_tab; - int path_length; - strcpy(req_url, req + GET_WELLKNOWN_ACMECHALLANGE_URL_PREFIX_LENGTH); - req_url_end_space=strchr(req_url,' '); - req_url_end_tab=strchr(req_url,'\t'); - if (req_url_end_space != NULL && req_url_end_tab != NULL) { - if (req_url_end_space - req_url_end_tab > 0 ){ - path_length=req_url_end_space - req_url; - req_url[path_length]='\0'; - } else { - path_length=req_url_end_tab - req_url; - req_url[req_url_end_tab - req_url]='\0'; - } - } else if(req_url_end_space != NULL) { - path_length=req_url_end_space - req_url; - req_url[path_length]='\0'; - } - else if(req_url_end_tab != NULL) { - path_length=req_url_end_tab - req_url; - req_url[path_length]='\0'; - } - size_t plen, rlen; if (url == NULL || url[0] == '\0' || req == NULL || s == 0 ) return 1; - if (len < 64 || len > 512 || (plen = is_acme_req(req, len)) < 33) + if (len < (GET_ACME_PREFIX_LEN + 32) || len > (512 - GET_ACME_PREFIX_LEN) + || (plen = is_acme_req(req, len)) < (GET_ACME_PREFIX_LEN + 1)) return 2; + req[plen] = '\0'; + snprintf(http_response, sizeof(http_response) - 1, "HTTP/1.1 301 Moved Permanently\r\n" "Content-Type: text/html\r\n" "Content-Length: %ld\r\n" "Connection: close\r\n" "Location: %s%s\r\n" - "\r\n%s", strlen(HTML), url, req_url, HTML); + "\r\n%s", strlen(HTML), url, req + GET_ACME_PREFIX_LEN, HTML); rlen = strlen(http_response); +#ifdef LIBEV_OK ioa_network_buffer_handle nbh_acme = ioa_network_buffer_allocate(s->e); uint8_t *data = ioa_network_buffer_data(nbh_acme); bcopy(http_response, data, rlen); ioa_network_buffer_set_size(nbh_acme, rlen); send_data_from_ioa_socket_nbh(s, NULL, nbh_acme, TTL_IGNORE, TOS_IGNORE, NULL); +#else + if (write(s->fd, http_response, rlen) == -1) { + TURN_LOG_FUNC(TURN_LOG_LEVEL_WARNING, + "Sending redirect to '%s%s' failed",url, req + GET_ACME_PREFIX_LEN); + } else if (((turn_turnserver *)s->session->server)->verbose) { + TURN_LOG_FUNC(TURN_LOG_LEVEL_INFO, "ACME redirected to %s%s\n", + url, req + GET_ACME_PREFIX_LEN); + } +#endif + + req[plen] = ' '; return 0; } diff --git a/src/apps/relay/acme.h b/src/apps/relay/acme.h index a927dc56..133c22d1 100644 --- a/src/apps/relay/acme.h +++ b/src/apps/relay/acme.h @@ -44,8 +44,6 @@ extern "C" { ///////////// ACME ///////////////////// -#define GET_WELLKNOWN_ACMECHALLANGE_URL_PREFIX_LENGTH 32 - int try_acme_redirect(char *req, size_t len, const char *url, ioa_socket_handle s); /////////////////////////////////////// From 36481cc396f993350b1e9d86ea86379891d4c795 Mon Sep 17 00:00:00 2001 From: Jens Elkner Date: Thu, 31 Dec 2020 19:06:46 +0100 Subject: [PATCH 45/55] configure fix --- configure | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/configure b/configure index b85a65ca..226adb6c 100755 --- a/configure +++ b/configure @@ -1,5 +1,7 @@ #!/bin/sh +set -x + # Proprietary configure script of Coturn project cleanup() { @@ -562,7 +564,7 @@ if [ -z "${LIBEV_OK}" ]; then LIBEV_OK=1 if [ "${SYSTEM}" = "Linux" ]; then OS=$( lsb_release -si 2>/dev/null ) - [ "${OS}" = "Ubuntu" ] || LIBEV_OK=0 + [ "${OS}" = "Ubuntu" ] && LIBEV_OK=0 fi fi [ "${LIBEV_OK}" = "1" ] && OSCFLAGS="${OSCFLAGS} -DLIBEV_OK" From 619305a43ca0a8cc0b34dffcad0b1e623a306f3a Mon Sep 17 00:00:00 2001 From: Jens Elkner Date: Thu, 31 Dec 2020 19:08:57 +0100 Subject: [PATCH 46/55] configure: disable debug --- configure | 2 -- 1 file changed, 2 deletions(-) diff --git a/configure b/configure index 226adb6c..4933830c 100755 --- a/configure +++ b/configure @@ -1,7 +1,5 @@ #!/bin/sh -set -x - # Proprietary configure script of Coturn project cleanup() { From 86b78aa6fac8bd868a6fa616f4c2b52516fb08ee Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?M=C3=A9sz=C3=A1ros=20Mih=C3=A1ly?= Date: Tue, 5 Jan 2021 07:44:58 +0000 Subject: [PATCH 47/55] Tidy: fix spacing --- src/server/ns_turn_server.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/server/ns_turn_server.c b/src/server/ns_turn_server.c index 340b1fe7..4ed12d44 100644 --- a/src/server/ns_turn_server.c +++ b/src/server/ns_turn_server.c @@ -4914,7 +4914,7 @@ void init_turn_server(turn_turnserver* server, vintp stun_only, vintp no_stun, vintp no_software_attribute, - vintp web_admin_listen_on_workers, + vintp web_admin_listen_on_workers, turn_server_addrs_list_t *alternate_servers_list, turn_server_addrs_list_t *tls_alternate_servers_list, turn_server_addrs_list_t *aux_servers_list, From 27b261eb58116e1dd395124e90ccbcc09d13b135 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?M=C3=A9sz=C3=A1ros=20Mih=C3=A1ly?= Date: Tue, 5 Jan 2021 09:55:55 +0000 Subject: [PATCH 48/55] Disable binding logging to avoid DoS attack * Add new option log-binding --- ChangeLog | 2 ++ README.turnserver | 2 ++ examples/etc/turnserver.conf | 4 ++++ man/man1/turnadmin.1 | 2 +- man/man1/turnserver.1 | 6 +++++- man/man1/turnutils.1 | 2 +- src/apps/relay/dtls_listener.c | 2 +- src/apps/relay/mainrelay.c | 13 +++++++++++-- src/apps/relay/mainrelay.h | 2 ++ src/apps/relay/netengine.c | 3 ++- src/server/ns_turn_server.c | 11 +++++++---- src/server/ns_turn_server.h | 6 +++++- 12 files changed, 43 insertions(+), 12 deletions(-) diff --git a/ChangeLog b/ChangeLog index f2210baa..9d647154 100644 --- a/ChangeLog +++ b/ChangeLog @@ -25,6 +25,8 @@ Version 4.5.2 'dan Eider': * Add ACME redirect url - merge PR #551 (by jelmd) * support of --acme-redirect + - Disable binding request logging to avoid DoS attacks. (Breaking change!) + * Add new --log-binding option to enable binding request logging 24/06/2020 Oleg Moskalenko Mihály Mészáros Version 4.5.1.3 'dan Eider': diff --git a/README.turnserver b/README.turnserver index df74704b..46e3bbc3 100644 --- a/README.turnserver +++ b/README.turnserver @@ -229,6 +229,8 @@ Flags: --new-log-timestamp-format Set timestamp format (in strftime(1) format) +--log-binding Log STUN binding request. It is now disabled by default to avoid DoS attacks. + --secure-stun Require authentication of the STUN Binding request. By default, the clients are allowed anonymous access to the STUN Binding functionality. diff --git a/examples/etc/turnserver.conf b/examples/etc/turnserver.conf index 906a4b98..d5e39ea4 100644 --- a/examples/etc/turnserver.conf +++ b/examples/etc/turnserver.conf @@ -540,6 +540,10 @@ # Set timestamp format (in strftime(1) format) #new-log-timestamp-format "%FT%T%z" +# Disabled by default binding logging in verbose log mode to avoid DoS attacks. +# Enable binding logging and UDP endpoint logs in verbose log mode. +#log-binding + # Option to set the "redirection" mode. The value of this option # will be the address of the alternate server for UDP & TCP service in the form of # [:]. The server will send this value in the attribute diff --git a/man/man1/turnadmin.1 b/man/man1/turnadmin.1 index 8540085b..d19ce74d 100644 --- a/man/man1/turnadmin.1 +++ b/man/man1/turnadmin.1 @@ -1,5 +1,5 @@ .\" Text automatically generated by txt2man -.TH TURN 1 "15 December 2020" "" "" +.TH TURN 1 "05 January 2021" "" "" .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 f52a25c5..9286e018 100644 --- a/man/man1/turnserver.1 +++ b/man/man1/turnserver.1 @@ -1,5 +1,5 @@ .\" Text automatically generated by txt2man -.TH TURN 1 "15 December 2020" "" "" +.TH TURN 1 "05 January 2021" "" "" .SH GENERAL INFORMATION The \fBTURN Server\fP project contains the source code of a TURN server and TURN client @@ -345,6 +345,10 @@ Enable full ISO\-8601 timestamp in all logs. Set timestamp format (in \fBstrftime\fP(1) format) .TP .B +\fB\-\-log\-binding\fP +Log STUN binding request. It is now disabled by default to avoid DoS attacks. +.TP +.B \fB\-\-secure\-stun\fP Require authentication of the STUN Binding request. By default, the clients are allowed anonymous access to the STUN Binding functionality. diff --git a/man/man1/turnutils.1 b/man/man1/turnutils.1 index 809f83a4..26b98805 100644 --- a/man/man1/turnutils.1 +++ b/man/man1/turnutils.1 @@ -1,5 +1,5 @@ .\" Text automatically generated by txt2man -.TH TURN 1 "15 December 2020" "" "" +.TH TURN 1 "05 January 2021" "" "" .SH GENERAL INFORMATION A set of turnutils_* programs provides some utility functionality to be used diff --git a/src/apps/relay/dtls_listener.c b/src/apps/relay/dtls_listener.c index 08a17e7d..7689a134 100644 --- a/src/apps/relay/dtls_listener.c +++ b/src/apps/relay/dtls_listener.c @@ -456,7 +456,7 @@ static int handle_udp_packet(dtls_listener_relay_server_type *server, sm->m.sm.s = s; if (s) { - if(verbose) { + if(verbose && turn_params.log_binding) { uint8_t saddr[129]; uint8_t rsaddr[129]; addr_to_string(get_local_addr_from_ioa_socket(s),saddr); diff --git a/src/apps/relay/mainrelay.c b/src/apps/relay/mainrelay.c index 102b8f1d..42213019 100644 --- a/src/apps/relay/mainrelay.c +++ b/src/apps/relay/mainrelay.c @@ -168,7 +168,9 @@ DEFAULT_CPUS_NUMBER, 0, /* keep_address_family */ 0, /* no_auth_pings */ 0, /* no_dynamic_ip_list */ -0 /* no_dynamic_realms */ +0, /* no_dynamic_realms */ + +0 /* log_binding */ }; //////////////// OpenSSL Init ////////////////////// @@ -605,6 +607,7 @@ static char Usage[] = "Usage: turnserver [options]\n" " This option can be used, for example, together with the logrotate tool.\n" " --new-log-timestamp Enable full ISO-8601 timestamp in all logs.\n" " --new-log-timestamp-format Set timestamp format (in strftime(1) format)\n" +" --log-binding Log STUN binding request. It is now disabled by default to avoid DoS attacks.\n" " --stale-nonce[=] Use extra security with nonce value having limited lifetime (default 600 secs).\n" " --max-allocate-lifetime Set the maximum value for the allocation lifetime. Default to 3600 secs.\n" " --channel-lifetime Set the lifetime for channel binding, default to 600 secs.\n" @@ -813,7 +816,8 @@ enum EXTRA_OPTS { NO_SOFTWARE_ATTRIBUTE_OPT, NO_HTTP_OPT, SECRET_KEY_OPT, - ACME_REDIRECT_OPT + ACME_REDIRECT_OPT, + LOG_BINDING_OPT }; struct myoption { @@ -948,6 +952,8 @@ static const struct myoption long_options[] = { { "secret-key-file", required_argument, NULL, SECRET_KEY_OPT }, { "keep-address-family", optional_argument, NULL, 'K' }, { "acme-redirect", required_argument, NULL, ACME_REDIRECT_OPT }, + { "log-binding", optional_argument, NULL, LOG_BINDING_OPT }, + { NULL, no_argument, NULL, 0 } }; @@ -1607,6 +1613,9 @@ static void set_option(int c, char *value) case NEW_LOG_TIMESTAMP_FORMAT_OPT: set_turn_log_timestamp_format(value); break; + case LOG_BINDING_OPT: + turn_params.log_binding = get_bool_value(value); + break; /* these options have been already taken care of before: */ case 'l': diff --git a/src/apps/relay/mainrelay.h b/src/apps/relay/mainrelay.h index 0bcdbbd4..5b6f7cdd 100644 --- a/src/apps/relay/mainrelay.h +++ b/src/apps/relay/mainrelay.h @@ -333,6 +333,8 @@ typedef struct _turn_params_ { int no_dynamic_ip_list; int no_dynamic_realms; + vint log_binding; + } turn_params_t; extern turn_params_t turn_params; diff --git a/src/apps/relay/netengine.c b/src/apps/relay/netengine.c index 20f558cd..6a456f6a 100644 --- a/src/apps/relay/netengine.c +++ b/src/apps/relay/netengine.c @@ -1668,7 +1668,8 @@ static void setup_relay_server(struct relay_server *rs, ioa_engine_handle e, int turn_params.oauth, turn_params.oauth_server_name, turn_params.acme_redirect, - turn_params.keep_address_family); + turn_params.keep_address_family, + &turn_params.log_binding); if(to_set_rfc5780) { set_rfc5780(&(rs->server), get_alt_addr, send_message_from_listener_to_client); diff --git a/src/server/ns_turn_server.c b/src/server/ns_turn_server.c index 4ed12d44..3d9034f3 100644 --- a/src/server/ns_turn_server.c +++ b/src/server/ns_turn_server.c @@ -3832,13 +3832,13 @@ static int handle_turn_command(turn_turnserver *server, ts_ur_super_session *ss, &dest_changed, &response_destination, 0, 0); - if(server->verbose) { + if(server->verbose && server->log_binding) { log_method(ss, "BINDING", err_code, reason); } if(*resp_constructed && !err_code && (origin_changed || dest_changed)) { - if (server->verbose) { + if (server->verbose && server->log_binding) { TURN_LOG_FUNC(TURN_LOG_LEVEL_INFO, "RFC 5780 request successfully processed\n"); } @@ -4014,7 +4014,7 @@ static int handle_old_stun_command(turn_turnserver *server, ts_ur_super_session &dest_changed, &response_destination, cookie,1); - if(server->verbose) { + if(server->verbose && *(server->log_binding)) { log_method(ss, "OLD BINDING", err_code, reason); } @@ -4929,7 +4929,8 @@ void init_turn_server(turn_turnserver* server, int oauth, const char* oauth_server_name, const char* acme_redirect, - int keep_address_family) { + int keep_address_family, + vintp log_binding) { if (!server) return; @@ -5001,6 +5002,8 @@ void init_turn_server(turn_turnserver* server, server->keep_address_family = keep_address_family; set_ioa_timer(server->e, 1, 0, timer_timeout_handler, server, 1, "timer_timeout_handler"); + + server->log_binding = log_binding; } ioa_engine_handle turn_server_get_engine(turn_turnserver *s) { diff --git a/src/server/ns_turn_server.h b/src/server/ns_turn_server.h index 0df99716..aab33e36 100644 --- a/src/server/ns_turn_server.h +++ b/src/server/ns_turn_server.h @@ -176,6 +176,9 @@ struct _turn_turnserver { /* Keep Address Family */ int keep_address_family; + + /* Log Binding Requrest */ + vintp log_binding; }; const char * get_version(turn_turnserver *server); @@ -222,7 +225,8 @@ void init_turn_server(turn_turnserver* server, int oauth, const char* oauth_server_name, const char* acme_redirect, - int keep_address_family); + int keep_address_family, + vintp log_binding); ioa_engine_handle turn_server_get_engine(turn_turnserver *s); From 6ce463e8e23c53e9ad9674faf7b2a1f0ac2e1f93 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?M=C3=A9sz=C3=A1ros=20Mih=C3=A1ly?= Date: Tue, 5 Jan 2021 09:57:16 +0000 Subject: [PATCH 49/55] Removed wiki, due it was outdated and redundant. --- src/apps/relay/mainrelay.c | 4 ---- 1 file changed, 4 deletions(-) diff --git a/src/apps/relay/mainrelay.c b/src/apps/relay/mainrelay.c index 42213019..884c5018 100644 --- a/src/apps/relay/mainrelay.c +++ b/src/apps/relay/mainrelay.c @@ -669,10 +669,6 @@ static char Usage[] = "Usage: turnserver [options]\n" " This value can be changed on-the-fly in CLI. The default value is 256.\n" " --ne=[1|2|3] Set network engine type for the process (for internal purposes).\n" " -h Help\n" -"\n" -" For more information, see the wiki pages:\n" -"\n" -" https://github.com/coturn/coturn/wiki/\n" "\n"; static char AdminUsage[] = "Usage: turnadmin [command] [options]\n" From 14f1630ec6086a93056327c76faa3789c480c591 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?M=C3=A9sz=C3=A1ros=20Mih=C3=A1ly?= Date: Tue, 5 Jan 2021 10:25:10 +0000 Subject: [PATCH 50/55] Fix stale-nonce documentation Resolves #604 --- ChangeLog | 1 + README.turnserver | 1 + docker/coturn/turnserver.conf | 4 ++-- examples/etc/turnserver.conf | 4 ++-- man/man1/turnserver.1 | 1 + 5 files changed, 7 insertions(+), 4 deletions(-) diff --git a/ChangeLog b/ChangeLog index 9d647154..572e360e 100644 --- a/ChangeLog +++ b/ChangeLog @@ -27,6 +27,7 @@ Version 4.5.2 'dan Eider': * support of --acme-redirect - Disable binding request logging to avoid DoS attacks. (Breaking change!) * Add new --log-binding option to enable binding request logging + - Fix stale-nonce documentation. Resolves #604 24/06/2020 Oleg Moskalenko Mihály Mészáros Version 4.5.1.3 'dan Eider': diff --git a/README.turnserver b/README.turnserver index 46e3bbc3..ba3ad28a 100644 --- a/README.turnserver +++ b/README.turnserver @@ -281,6 +281,7 @@ Options with values: --stale-nonce[=] Use extra security with nonce value having limited lifetime, in seconds (default 600 secs). + Set it to 0 for unlimited nonce lifetime. --max-allocate-lifetime Set the maximum value for the allocation lifetime. Default to 3600 secs. diff --git a/docker/coturn/turnserver.conf b/docker/coturn/turnserver.conf index fc9ac1fe..ea40824a 100644 --- a/docker/coturn/turnserver.conf +++ b/docker/coturn/turnserver.conf @@ -411,9 +411,9 @@ realm=example.org # Uncomment if extra security is desired, # with nonce value having a limited lifetime. -# By default, the nonce value is unique for a session, -# and has an unlimited lifetime. +# The nonce value is unique for a session. # Set this option to limit the nonce lifetime. +# Set it to 0 for unlimited lifetime. # It defaults to 600 secs (10 min) if no value is provided. After that delay, # the client will get 438 error and will have to re-authenticate itself. # diff --git a/examples/etc/turnserver.conf b/examples/etc/turnserver.conf index d5e39ea4..b01fb059 100644 --- a/examples/etc/turnserver.conf +++ b/examples/etc/turnserver.conf @@ -423,9 +423,9 @@ # Uncomment if extra security is desired, # with nonce value having a limited lifetime. -# By default, the nonce value is unique for a session, -# and has an unlimited lifetime. +# The nonce value is unique for a session. # Set this option to limit the nonce lifetime. +# Set it to 0 for unlimited lifetime. # It defaults to 600 secs (10 min) if no value is provided. After that delay, # the client will get 438 error and will have to re-authenticate itself. # diff --git a/man/man1/turnserver.1 b/man/man1/turnserver.1 index 9286e018..02bfd5da 100644 --- a/man/man1/turnserver.1 +++ b/man/man1/turnserver.1 @@ -427,6 +427,7 @@ Options with values: \fB\-\-stale\-nonce\fP[=] Use extra security with nonce value having limited lifetime, in seconds (default 600 secs). +Set it to 0 for unlimited nonce lifetime. .TP .B \fB\-\-max\-allocate\-lifetime\fP From 1600b07bb37e7430fae7510e5934883f248def59 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?M=C3=A9sz=C3=A1ros=20Mih=C3=A1ly?= Date: Tue, 5 Jan 2021 10:45:17 +0000 Subject: [PATCH 51/55] merge PR#672 --- ChangeLog | 2 ++ 1 file changed, 2 insertions(+) diff --git a/ChangeLog b/ChangeLog index 572e360e..5e626ff8 100644 --- a/ChangeLog +++ b/ChangeLog @@ -25,6 +25,8 @@ Version 4.5.2 'dan Eider': * Add ACME redirect url - merge PR #551 (by jelmd) * support of --acme-redirect + - merge PR #672 further acme fixes (by jemld) + * fix acme security, redundancy, consistency - Disable binding request logging to avoid DoS attacks. (Breaking change!) * Add new --log-binding option to enable binding request logging - Fix stale-nonce documentation. Resolves #604 From 7fe2808d432df4a898b3e2f9f304cc80a757414b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?M=C3=A9sz=C3=A1ros=20Mih=C3=A1ly?= Date: Tue, 5 Jan 2021 10:46:28 +0000 Subject: [PATCH 52/55] Use SemVer 2.0 version numbering --- ChangeLog | 1 + 1 file changed, 1 insertion(+) diff --git a/ChangeLog b/ChangeLog index 5e626ff8..fda25517 100644 --- a/ChangeLog +++ b/ChangeLog @@ -30,6 +30,7 @@ Version 4.5.2 'dan Eider': - Disable binding request logging to avoid DoS attacks. (Breaking change!) * Add new --log-binding option to enable binding request logging - Fix stale-nonce documentation. Resolves #604 + - Version number is changed to semver 2.0 24/06/2020 Oleg Moskalenko Mihály Mészáros Version 4.5.1.3 'dan Eider': From 30c1a2076ba4129e7d7a2520fb70fe7b03de9a74 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?M=C3=A9sz=C3=A1ros=20Mih=C3=A1ly?= Date: Tue, 5 Jan 2021 12:18:18 +0000 Subject: [PATCH 53/55] Comment out fialing travis check on osx xcode11.6 --- .travis.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.travis.yml b/.travis.yml index f3199c79..baf01ce9 100644 --- a/.travis.yml +++ b/.travis.yml @@ -66,8 +66,8 @@ matrix: - libhiredis-dev - os: osx osx_image: xcode11.3 - - os: osx - osx_image: xcode11.6 + # - os: osx + # osx_image: xcode11.6 - os: osx osx_image: xcode12 - os: linux From 50ebef7a3fcf03f116b2673a8e9ab99264e0d78d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?M=C3=A9sz=C3=A1ros=20Mih=C3=A1ly?= Date: Tue, 5 Jan 2021 21:47:50 +0000 Subject: [PATCH 54/55] Fix g++ 2 errors and many warnings Resolves #661 #654 --- src/apps/relay/dbdrivers/dbd_mongo.c | 2 +- src/apps/relay/dbdrivers/dbd_mysql.c | 2 +- src/apps/relay/dbdrivers/dbd_pgsql.c | 2 +- src/apps/relay/dbdrivers/dbd_redis.c | 2 +- src/apps/relay/dbdrivers/dbd_sqlite.c | 2 +- src/apps/relay/mainrelay.c | 8 +-- src/client++/TurnMsgLib.h | 96 ++++++++++++--------------- 7 files changed, 50 insertions(+), 64 deletions(-) diff --git a/src/apps/relay/dbdrivers/dbd_mongo.c b/src/apps/relay/dbdrivers/dbd_mongo.c index d84e4ee0..8891456b 100644 --- a/src/apps/relay/dbdrivers/dbd_mongo.c +++ b/src/apps/relay/dbdrivers/dbd_mongo.c @@ -1124,7 +1124,7 @@ static void mongo_reread_realms(secrets_list_t * realms_list) { ur_string_map_value_type value = (ur_string_map_value_type) (rval); ur_string_map_put(o_to_realm_new, - (const ur_string_map_key_type) _origin, + (ur_string_map_key_type) _origin, value); free(_origin); } diff --git a/src/apps/relay/dbdrivers/dbd_mysql.c b/src/apps/relay/dbdrivers/dbd_mysql.c index dd702e82..0371a1cb 100644 --- a/src/apps/relay/dbdrivers/dbd_mysql.c +++ b/src/apps/relay/dbdrivers/dbd_mysql.c @@ -1048,7 +1048,7 @@ static void mysql_reread_realms(secrets_list_t * realms_list) { char *rval=strdup(row[1]); get_realm(rval); ur_string_map_value_type value = (ur_string_map_value_type)rval; - ur_string_map_put(o_to_realm_new, (const ur_string_map_key_type) oval, value); + ur_string_map_put(o_to_realm_new, (ur_string_map_key_type) oval, value); } } } diff --git a/src/apps/relay/dbdrivers/dbd_pgsql.c b/src/apps/relay/dbdrivers/dbd_pgsql.c index 0af09977..67b6f0cd 100644 --- a/src/apps/relay/dbdrivers/dbd_pgsql.c +++ b/src/apps/relay/dbdrivers/dbd_pgsql.c @@ -758,7 +758,7 @@ static void pgsql_reread_realms(secrets_list_t * realms_list) { if(rval) { get_realm(rval); ur_string_map_value_type value = strdup(rval); - ur_string_map_put(o_to_realm_new, (const ur_string_map_key_type) oval, value); + ur_string_map_put(o_to_realm_new, (ur_string_map_key_type) oval, value); } } } diff --git a/src/apps/relay/dbdrivers/dbd_redis.c b/src/apps/relay/dbdrivers/dbd_redis.c index ec23ffed..5c8f40de 100644 --- a/src/apps/relay/dbdrivers/dbd_redis.c +++ b/src/apps/relay/dbdrivers/dbd_redis.c @@ -1161,7 +1161,7 @@ static void redis_reread_realms(secrets_list_t * realms_list) { } else { get_realm(rget->str); ur_string_map_value_type value = strdup(rget->str); - ur_string_map_put(o_to_realm_new, (const ur_string_map_key_type) origin, value); + ur_string_map_put(o_to_realm_new, (ur_string_map_key_type) origin, value); } turnFreeRedisReply(rget); } diff --git a/src/apps/relay/dbdrivers/dbd_sqlite.c b/src/apps/relay/dbdrivers/dbd_sqlite.c index 305a60b8..06da7c1b 100644 --- a/src/apps/relay/dbdrivers/dbd_sqlite.c +++ b/src/apps/relay/dbdrivers/dbd_sqlite.c @@ -1038,7 +1038,7 @@ static void sqlite_reread_realms(secrets_list_t * realms_list) get_realm(rval); ur_string_map_value_type value = rval; - ur_string_map_put(o_to_realm_new, (const ur_string_map_key_type) oval, value); + ur_string_map_put(o_to_realm_new, (ur_string_map_key_type) oval, value); free(oval); diff --git a/src/apps/relay/mainrelay.c b/src/apps/relay/mainrelay.c index 884c5018..9553548b 100644 --- a/src/apps/relay/mainrelay.c +++ b/src/apps/relay/mainrelay.c @@ -1173,7 +1173,7 @@ static void set_option(int c, char *value) STRCPY(turn_params.oauth_server_name,value); break; case OAUTH_OPT: - if(!ENC_ALG_NUM) { + if( ENC_ALG_NUM == 0) { TURN_LOG_FUNC(TURN_LOG_LEVEL_WARNING, "WARNING: option --oauth is not supported; ignored.\n"); } else { turn_params.oauth = get_bool_value(value); @@ -2062,7 +2062,7 @@ static void print_features(unsigned long mfn) TURN_LOG_FUNC(TURN_LOG_LEVEL_INFO, "TURN/STUN ALPN is not supported\n"); #endif - if(!ENC_ALG_NUM) { + if(ENC_ALG_NUM == 0) { TURN_LOG_FUNC(TURN_LOG_LEVEL_INFO, "Third-party authorization (oAuth) is not supported\n"); } else { TURN_LOG_FUNC(TURN_LOG_LEVEL_INFO, "Third-party authorization (oAuth) supported\n"); @@ -2588,7 +2588,7 @@ static int THREAD_setup(void) { mutex_buf_initialized = 1; -#if OPENSSL_VERSION_NUMBER >= 0x10000000L +#if OPENSSL_VERSION_NUMBER >= 0x10000000L && OPENSSL_VERSION_NUMBER <= OPENSSL_VERSION_1_1_1 CRYPTO_THREADID_set_callback(coturn_id_function); #else CRYPTO_set_id_callback(coturn_id_function); @@ -2610,7 +2610,7 @@ int THREAD_cleanup(void) { if (!mutex_buf_initialized) return 0; -#if OPENSSL_VERSION_NUMBER >= 0x10000000L +#if OPENSSL_VERSION_NUMBER >= 0x10000000L && OPENSSL_VERSION_NUMBER <= OPENSSL_VERSION_1_1_1 CRYPTO_THREADID_set_callback(NULL); #else CRYPTO_set_id_callback(NULL); diff --git a/src/client++/TurnMsgLib.h b/src/client++/TurnMsgLib.h index 9c4a6279..93ae8c0d 100644 --- a/src/client++/TurnMsgLib.h +++ b/src/client++/TurnMsgLib.h @@ -75,7 +75,7 @@ public: /** * Iterator constructor: creates iterator on raw messagebuffer. */ - StunAttrIterator(uint8_t *buf, size_t sz) throw (WrongStunBufferFormatException) : + StunAttrIterator(uint8_t *buf, size_t sz) : _buf(buf), _sz(sz) { if(!stun_is_command_message_str(_buf, _sz)) { throw WrongStunBufferFormatException(); @@ -87,7 +87,7 @@ public: * Iterator constructor: create iterator over message. */ template - StunAttrIterator(T &msg) throw (WrongStunBufferFormatException) : + StunAttrIterator(T &msg) : _buf(msg.getRawBuffer()), _sz(msg.getSize()) { if(!stun_is_command_message_str(_buf, _sz)) { throw WrongStunBufferFormatException(); @@ -99,7 +99,7 @@ public: * Iterator constructor: creates iterator over raw buffer, starting from first * location of an attribute of particular type. */ - StunAttrIterator(uint8_t *buf, size_t sz, uint16_t attr_type) throw (WrongStunBufferFormatException) : + StunAttrIterator(uint8_t *buf, size_t sz, uint16_t attr_type) : _buf(buf), _sz(sz) { if(!stun_is_command_message_str(_buf, _sz)) { throw WrongStunBufferFormatException(); @@ -112,7 +112,7 @@ public: * location of an attribute of particular type. */ template - StunAttrIterator(T &msg, uint16_t attr_type) throw (WrongStunBufferFormatException) : + StunAttrIterator(T &msg, uint16_t attr_type) : _buf(msg.getRawBuffer()), _sz(msg.getSize()) { if(!stun_is_command_message_str(_buf, _sz)) { throw WrongStunBufferFormatException(); @@ -123,7 +123,7 @@ public: /** * Moves iterator to next attribute location */ - void next() throw(EndOfStunMsgException) { + void next() { if(!_sar) { throw EndOfStunMsgException(); } @@ -167,7 +167,7 @@ public: * Return raw memroy field of the attribute value. * If the attribute value length is zero (0), then return NULL. */ - const uint8_t *getRawBuffer(size_t &sz) const throw(WrongStunAttrFormatException) { + const uint8_t *getRawBuffer(size_t &sz) const { int len = stun_attr_get_len(_sar); if(len<0) throw WrongStunAttrFormatException(); @@ -196,7 +196,7 @@ public: /** * Constructs attribute from iterator */ - StunAttr(const StunAttrIterator &iter) throw(WrongStunAttrFormatException, EndOfStunMsgException) { + StunAttr(const StunAttrIterator &iter) { if(iter.eof()) { throw EndOfStunMsgException(); } @@ -219,7 +219,7 @@ public: */ virtual ~StunAttr() { if(_value) - free(_value,_sz); + free(_value); } /** @@ -233,11 +233,11 @@ public: /** * Set raw data value */ - void setRawValue(uint8_t *value, size_t sz) throw(WrongStunAttrFormatException) { + void setRawValue(uint8_t *value, size_t sz) { if(sz>0xFFFF) throw WrongStunAttrFormatException(); if(_value) - free(_value,_sz); + free(_value); _sz = sz; _value=(uint8_t*)malloc(_sz); if(value) @@ -262,7 +262,7 @@ public: * Add attribute to a message */ template - int addToMsg(T &msg) throw(WrongStunAttrFormatException, WrongStunBufferFormatException) { + int addToMsg(T &msg) { if(!_attr_type) throw WrongStunAttrFormatException(); uint8_t *buffer = msg.getRawBuffer(); @@ -281,7 +281,7 @@ protected: /** * Virtual function member to add attribute to a raw buffer */ - virtual int addToBuffer(uint8_t *buffer, size_t &sz) throw(WrongStunAttrFormatException, WrongStunBufferFormatException) { + virtual int addToBuffer(uint8_t *buffer, size_t &sz) { if(buffer) { if(!_value) throw WrongStunAttrFormatException(); @@ -313,8 +313,7 @@ public: StunAttrChannelNumber() : _cn(0) { setType(STUN_ATTRIBUTE_CHANNEL_NUMBER); } - StunAttrChannelNumber(const StunAttrIterator &iter) - throw(WrongStunAttrFormatException, EndOfStunMsgException) : + StunAttrChannelNumber(const StunAttrIterator &iter) : StunAttr(iter) { if(iter.eof()) @@ -331,7 +330,7 @@ public: _cn = cn; } protected: - virtual int addToBuffer(uint8_t *buffer, size_t &sz) throw(WrongStunAttrFormatException, WrongStunBufferFormatException) { + virtual int addToBuffer(uint8_t *buffer, size_t &sz) { return stun_attr_add_channel_number_str(buffer,&sz,_cn); } private: @@ -346,8 +345,7 @@ public: StunAttrEvenPort() : _ep(0) { setType(STUN_ATTRIBUTE_EVEN_PORT); } - StunAttrEvenPort(const StunAttrIterator &iter) - throw(WrongStunAttrFormatException, EndOfStunMsgException) : + StunAttrEvenPort(const StunAttrIterator &iter) : StunAttr(iter) { if(iter.eof()) @@ -362,7 +360,7 @@ public: _ep = ep; } protected: - virtual int addToBuffer(uint8_t *buffer, size_t &sz) throw(WrongStunAttrFormatException, WrongStunBufferFormatException) { + virtual int addToBuffer(uint8_t *buffer, size_t &sz) { return stun_attr_add_str(buffer, &sz, STUN_ATTRIBUTE_EVEN_PORT, &_ep, 1); } private: @@ -377,8 +375,7 @@ public: StunAttrReservationToken() : _rt(0) { setType(STUN_ATTRIBUTE_RESERVATION_TOKEN); } - StunAttrReservationToken(const StunAttrIterator &iter) - throw(WrongStunAttrFormatException, EndOfStunMsgException) : + StunAttrReservationToken(const StunAttrIterator &iter) : StunAttr(iter) { if(iter.eof()) @@ -393,7 +390,7 @@ public: _rt = rt; } protected: - virtual int addToBuffer(uint8_t *buffer, size_t &sz) throw(WrongStunAttrFormatException, WrongStunBufferFormatException) { + virtual int addToBuffer(uint8_t *buffer, size_t &sz) { uint64_t reservation_token = ioa_ntoh64(_rt); return stun_attr_add_str(buffer, &sz, STUN_ATTRIBUTE_RESERVATION_TOKEN, (uint8_t*) (&reservation_token), 8); } @@ -410,8 +407,7 @@ public: addr_set_any(&_addr); setType(attr_type); } - StunAttrAddr(const StunAttrIterator &iter) - throw(WrongStunAttrFormatException, EndOfStunMsgException) : + StunAttrAddr(const StunAttrIterator &iter) : StunAttr(iter) { if(iter.eof()) @@ -430,7 +426,7 @@ public: addr_cpy(&_addr,&addr); } protected: - virtual int addToBuffer(uint8_t *buffer, size_t &sz) throw(WrongStunAttrFormatException, WrongStunBufferFormatException) { + virtual int addToBuffer(uint8_t *buffer, size_t &sz) { return stun_attr_add_addr_str(buffer, &sz, getType(), &_addr); } private: @@ -445,8 +441,7 @@ public: StunAttrChangeRequest() : _changeIp(0), _changePort(0) { setType(STUN_ATTRIBUTE_CHANGE_REQUEST); } - StunAttrChangeRequest(const StunAttrIterator &iter) - throw(WrongStunAttrFormatException, EndOfStunMsgException) : + StunAttrChangeRequest(const StunAttrIterator &iter) : StunAttr(iter) { if(iter.eof()) @@ -476,7 +471,7 @@ public: _changePort = 0; } protected: - virtual int addToBuffer(uint8_t *buffer, size_t &sz) throw(WrongStunAttrFormatException, WrongStunBufferFormatException) { + virtual int addToBuffer(uint8_t *buffer, size_t &sz) { return stun_attr_add_change_request_str(buffer, &sz, _changeIp, _changePort); } private: @@ -492,8 +487,7 @@ public: StunAttrResponsePort() : _rp(0) { setType(STUN_ATTRIBUTE_RESPONSE_PORT); } - StunAttrResponsePort(const StunAttrIterator &iter) - throw(WrongStunAttrFormatException, EndOfStunMsgException) : + StunAttrResponsePort(const StunAttrIterator &iter) : StunAttr(iter) { if(iter.eof()) @@ -513,7 +507,7 @@ public: _rp = p; } protected: - virtual int addToBuffer(uint8_t *buffer, size_t &sz) throw(WrongStunAttrFormatException, WrongStunBufferFormatException) { + virtual int addToBuffer(uint8_t *buffer, size_t &sz) { return stun_attr_add_response_port_str(buffer, &sz, _rp); } private: @@ -528,8 +522,7 @@ public: StunAttrPadding() : _p(0) { setType(STUN_ATTRIBUTE_PADDING); } - StunAttrPadding(const StunAttrIterator &iter) - throw(WrongStunAttrFormatException, EndOfStunMsgException) : + StunAttrPadding(const StunAttrIterator &iter) : StunAttr(iter) { if(iter.eof()) @@ -552,7 +545,7 @@ public: _p = p; } protected: - virtual int addToBuffer(uint8_t *buffer, size_t &sz) throw(WrongStunAttrFormatException, WrongStunBufferFormatException) { + virtual int addToBuffer(uint8_t *buffer, size_t &sz) { return stun_attr_add_padding_str(buffer, &sz, _p); } private: @@ -588,7 +581,7 @@ public: */ virtual ~StunMsg() { if(_deallocate && _buffer) { - free(_buffer, _allocated_sz); + free(_buffer); } } @@ -623,7 +616,7 @@ public: /** * Set message size */ - void setSize(size_t sz) throw(WrongStunBufferFormatException) { + void setSize(size_t sz) { if(sz>_allocated_sz) throw WrongStunBufferFormatException(); _sz = sz; @@ -700,14 +693,14 @@ public: /** * Add attribute to the message */ - int addAttr(StunAttr &attr) throw(WrongStunAttrFormatException, WrongStunBufferFormatException) { + int addAttr(StunAttr &attr) { return attr.addToMsg(*this); } /** * Get transaction ID */ - virtual stun_tid getTid() const throw(WrongStunBufferFormatException) { + virtual stun_tid getTid() const { if(!_constructed || !isCommand()) throw WrongStunBufferFormatException(); stun_tid tid; @@ -718,7 +711,7 @@ public: /** * Set transaction ID */ - virtual void setTid(stun_tid &tid) throw(WrongStunBufferFormatException) { + virtual void setTid(stun_tid &tid) { if(!_constructed || !isCommand()) throw WrongStunBufferFormatException(); stun_tid_message_cpy(_buffer, &tid); @@ -727,7 +720,7 @@ public: /** * Add fingerprint to the message */ - void addFingerprint() throw(WrongStunBufferFormatException) { + void addFingerprint() { if(!_constructed || !isCommand()) throw WrongStunBufferFormatException(); stun_attr_add_fingerprint_str(_buffer,&_sz); @@ -736,8 +729,7 @@ public: /** * Check message integrity, in secure communications. */ - bool checkMessageIntegrity(turn_credential_type ct, std::string &uname, std::string &realm, std::string &upwd) const - throw(WrongStunBufferFormatException) { + bool checkMessageIntegrity(turn_credential_type ct, std::string &uname, std::string &realm, std::string &upwd) const { if(!_constructed || !isCommand()) throw WrongStunBufferFormatException(); uint8_t *suname=(uint8_t*)strdup(uname.c_str()); @@ -754,8 +746,7 @@ public: /** * Adds long-term message integrity data to the message. */ - void addLTMessageIntegrity(std::string &uname, std::string &realm, std::string &upwd, std::string &nonce) - throw(WrongStunBufferFormatException) { + void addLTMessageIntegrity(std::string &uname, std::string &realm, std::string &upwd, std::string &nonce) { if(!_constructed || !isCommand()) throw WrongStunBufferFormatException(); @@ -776,8 +767,7 @@ public: /** * Adds short-term message integrity data to the message. */ - void addSTMessageIntegrity(std::string &uname, std::string &upwd) - throw(WrongStunBufferFormatException) { + void addSTMessageIntegrity(std::string &uname, std::string &upwd) { if(!_constructed || !isCommand()) throw WrongStunBufferFormatException(); @@ -808,8 +798,7 @@ protected: class StunMsgRequest : public StunMsg { public: StunMsgRequest(uint16_t method) : _method(method) {}; - StunMsgRequest(uint8_t *buffer, size_t total_sz, size_t sz, bool constructed) - throw(WrongStunBufferFormatException) : + StunMsgRequest(uint8_t *buffer, size_t total_sz, size_t sz, bool constructed) : StunMsg(buffer,total_sz,sz,constructed),_method(0) { if(constructed) { @@ -893,8 +882,7 @@ public: _method(method), _err(error_code), _reason(reason), _tid(tid) { }; - StunMsgResponse(uint8_t *buffer, size_t total_sz, size_t sz, bool constructed) - throw(WrongStunBufferFormatException) : + StunMsgResponse(uint8_t *buffer, size_t total_sz, size_t sz, bool constructed) : StunMsg(buffer,total_sz,sz,constructed),_method(0),_err(0),_reason("") { if(constructed) { @@ -949,14 +937,14 @@ public: /** * Set transaction ID */ - void setTid(stun_tid &tid) throw(WrongStunBufferFormatException) { + void setTid(stun_tid &tid) { _tid = tid; } /** * Get transaction ID */ - virtual stun_tid getTid() const throw(WrongStunBufferFormatException) { + virtual stun_tid getTid() const { return _tid; } @@ -1074,8 +1062,7 @@ private: class StunMsgIndication : public StunMsg { public: StunMsgIndication(uint16_t method) : _method(method) {}; - StunMsgIndication(uint8_t *buffer, size_t total_sz, size_t sz, bool constructed) - throw(WrongStunBufferFormatException) : + StunMsgIndication(uint8_t *buffer, size_t total_sz, size_t sz, bool constructed) : StunMsg(buffer,total_sz,sz,constructed),_method(0) { if(constructed) { @@ -1123,8 +1110,7 @@ private: class StunMsgChannel : public StunMsg { public: StunMsgChannel(uint16_t cn, int length) : _cn(cn), _len(length) {}; - StunMsgChannel(uint8_t *buffer, size_t total_sz, size_t sz, bool constructed) - throw(WrongStunBufferFormatException) : + StunMsgChannel(uint8_t *buffer, size_t total_sz, size_t sz, bool constructed) : StunMsg(buffer,total_sz,sz,constructed),_cn(0) { if(constructed) { From 5b13fdd37b57de99414048c34751fea8454a712d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?M=C3=A9sz=C3=A1ros=20Mih=C3=A1ly?= Date: Thu, 7 Jan 2021 10:33:14 +0000 Subject: [PATCH 55/55] Fix: Read log options in first pass. Fixes #602 --- src/apps/relay/mainrelay.c | 25 +++++++++++++++---------- 1 file changed, 15 insertions(+), 10 deletions(-) diff --git a/src/apps/relay/mainrelay.c b/src/apps/relay/mainrelay.c index 9553548b..2c3c7e13 100644 --- a/src/apps/relay/mainrelay.c +++ b/src/apps/relay/mainrelay.c @@ -1603,12 +1603,6 @@ static void set_option(int c, char *value) turn_params.rest_api_separator=*value; } break; - case NEW_LOG_TIMESTAMP_OPT: - use_new_log_timestamp_format=1; - break; - case NEW_LOG_TIMESTAMP_FORMAT_OPT: - set_turn_log_timestamp_format(value); - break; case LOG_BINDING_OPT: turn_params.log_binding = get_bool_value(value); break; @@ -1618,6 +1612,8 @@ static void set_option(int c, char *value) case NO_STDOUT_LOG_OPT: case SYSLOG_OPT: case SIMPLE_LOG_OPT: + case NEW_LOG_TIMESTAMP_OPT: + case NEW_LOG_TIMESTAMP_FORMAT_OPT: case 'c': case 'n': case 'h': @@ -1748,9 +1744,9 @@ static void read_config_file(int argc, char **argv, int pass) use_new_log_timestamp_format=1; } else if ((pass==0) && (c==NEW_LOG_TIMESTAMP_FORMAT_OPT)) { set_turn_log_timestamp_format(value); - } else if((pass == 0) && (c != 'u')) { + } else if((pass == 1) && (c != 'u')) { set_option(c, value); - } else if((pass > 0) && (c == 'u')) { + } else if((pass == 2) && (c == 'u')) { set_option(c, value); } if (s[slen - 1] == 59) { @@ -2228,6 +2224,12 @@ int main(int argc, char **argv) case SIMPLE_LOG_OPT: set_simple_log(get_bool_value(optarg)); break; + case NEW_LOG_TIMESTAMP_OPT: + use_new_log_timestamp_format=1; + break; + case NEW_LOG_TIMESTAMP_FORMAT_OPT: + set_turn_log_timestamp_format(optarg); + break; default: ; } @@ -2264,8 +2266,10 @@ int main(int argc, char **argv) if(strstr(argv[0],"turnadmin")) return adminmain(argc,argv); - + // Zero pass apply the log options. read_config_file(argc,argv,0); + // First pass read other config options + read_config_file(argc,argv,1); struct uoptions uo; uo.u.m = long_options; @@ -2275,7 +2279,8 @@ int main(int argc, char **argv) set_option(c,optarg); } - read_config_file(argc,argv,1); + // Second pass read -u options + read_config_file(argc,argv,2); { unsigned long mfn = set_system_parameters(1);