mirror of
https://github.com/coturn/coturn.git
synced 2025-10-25 21:11:00 +02:00
fix acme wrt. security, redundancy, consistency
This commit is contained in:
parent
8dc5bbcb3b
commit
8c99505614
11
configure
vendored
11
configure
vendored
@ -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
|
||||
###########################
|
||||
|
||||
@ -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,
|
||||
"<html><head><title>301 Moved Permanently</title></head>\
|
||||
<body><h1>301 Moved Permanently</h1></body></html>";
|
||||
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;
|
||||
}
|
||||
|
||||
@ -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);
|
||||
|
||||
///////////////////////////////////////
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user