support of --acme-redirect <URL>
This commit is contained in:
parent
9b1cca1fbe
commit
7e525c8e1c
@ -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 = "<html><head><title>301 Moved Permanently</title></head><body><h1>301 Moved Permanently</h1></body></html>";
|
||||
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)
|
||||
|
||||
@ -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> 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);
|
||||
}
|
||||
|
||||
@ -219,6 +219,7 @@ typedef struct _turn_params_ {
|
||||
int do_not_use_config_file;
|
||||
|
||||
char pidfile[1025];
|
||||
char acme_redirect[1025];
|
||||
|
||||
//////////////// Listener server /////////////////
|
||||
|
||||
|
||||
@ -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) {
|
||||
|
||||
@ -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);
|
||||
|
||||
///////////////////////////////////////
|
||||
|
||||
|
||||
@ -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);
|
||||
|
||||
|
||||
@ -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);
|
||||
|
||||
Loading…
Reference in New Issue
Block a user