mirror of
https://gitlab.com/openconnect/ocserv.git
synced 2026-02-10 00:37:00 +08:00
Merge branch 'tmp-ignore-broken-dtls' into 'master'
Prevent clients with a broken GnuTLS version from connecting using DTLS Closes #277 See merge request openconnect/ocserv!157
This commit is contained in:
@@ -19,7 +19,10 @@ Debian:
|
||||
script:
|
||||
- chmod -R o-w tests/data/raddb
|
||||
- git submodule update --init && autoreconf -fvi &&
|
||||
./configure --without-nuttcp-tests --without-docker-tests --enable-oidc-auth && make -j$JOBS && make check -j$JOBS
|
||||
./configure --without-nuttcp-tests --without-docker-tests --enable-oidc-auth
|
||||
- make -j$JOBS
|
||||
- export OCSERV_ALLOW_BROKEN_CLIENTS=1
|
||||
- make check -j$JOBS
|
||||
tags:
|
||||
- shared
|
||||
- linux
|
||||
@@ -87,6 +90,7 @@ Centos8:
|
||||
- chmod og-w tests/data/raddb
|
||||
- chmod og-w tests/data/raddb/*
|
||||
- make -j$JOBS
|
||||
- export OCSERV_ALLOW_BROKEN_CLIENTS=1
|
||||
- make check VERBOSE=1 -j$JOBS
|
||||
tags:
|
||||
- shared
|
||||
@@ -180,6 +184,7 @@ RPM/epel8:
|
||||
- sha512sum --tag ocserv-$NEWVERSION.tar.xz >>sources.tmp
|
||||
- mv sources.tmp sources
|
||||
- touch ocserv-$NEWVERSION.tar.xz.sig
|
||||
- export OCSERV_ALLOW_BROKEN_CLIENTS=1
|
||||
- fedpkg --release el8 local
|
||||
- cd $CURDIR
|
||||
- find /usr/local/rpms/ocserv -name '*.rpm' -exec cp '{}' ./ ';'
|
||||
|
||||
2
NEWS
2
NEWS
@@ -1,4 +1,6 @@
|
||||
* Version 1.0.1 (unreleased)
|
||||
- Prevent clients that use broken versions of gnutls from
|
||||
connecting using DTLS (#277)
|
||||
- occtl: added machine-readable output for json output (#271)
|
||||
|
||||
|
||||
|
||||
37
src/main.c
37
src/main.c
@@ -79,6 +79,7 @@ static void listen_watcher_cb (EV_P_ ev_io *w, int revents);
|
||||
int syslog_open = 0;
|
||||
sigset_t sig_default_set;
|
||||
struct ev_loop *loop = NULL;
|
||||
static unsigned allow_broken_clients = 0;
|
||||
|
||||
/* EV watchers */
|
||||
ev_io ctl_watcher;
|
||||
@@ -639,6 +640,7 @@ void clear_lists(main_server_st *s)
|
||||
#define TLS_EXT_APP_ID 48018
|
||||
#define RECORD_PAYLOAD_POS 13
|
||||
#define HANDSHAKE_SESSION_ID_POS 46
|
||||
#define HANDSHAKE_RANDOM_POS 14
|
||||
|
||||
/* This returns either the application-specific ID extension contents,
|
||||
* or the session ID contents. The former is used on the new protocol,
|
||||
@@ -733,6 +735,30 @@ unsigned get_session_id(main_server_st* s, uint8_t *buffer, size_t buffer_size,
|
||||
return 1;
|
||||
}
|
||||
|
||||
static
|
||||
unsigned has_broken_random(main_server_st* s, uint8_t *buffer, size_t buffer_size)
|
||||
{
|
||||
size_t pos,i;
|
||||
|
||||
if (allow_broken_clients)
|
||||
return 0;
|
||||
|
||||
if (buffer_size < RECORD_PAYLOAD_POS+HANDSHAKE_RANDOM_POS+32)
|
||||
return 0;
|
||||
|
||||
/* check whether the client hello contains a random value of all zeros;
|
||||
* if that's the case it indicates a broken DTLS client. Relates to:
|
||||
* https://gitlab.com/gnutls/gnutls/-/issues/960 */
|
||||
pos = RECORD_PAYLOAD_POS+HANDSHAKE_RANDOM_POS;
|
||||
|
||||
for (i=0;i<32;i++) {
|
||||
if (buffer[pos+i] != 0)
|
||||
return 0;
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* A UDP fd will not be forwarded to worker process before this number of
|
||||
* seconds has passed. That is to prevent a duplicate message messing the worker.
|
||||
*/
|
||||
@@ -803,6 +829,12 @@ int sfd = -1;
|
||||
if (GETPCONFIG(s)->unix_conn_file)
|
||||
goto fail;
|
||||
} else {
|
||||
if (has_broken_random(s, s->msg_buffer, buffer_size)) {
|
||||
mslog(s, NULL, LOG_INFO, "%s: detected broken DTLS client hello (no randomness); ignoring",
|
||||
human_addr((struct sockaddr*)&cli_addr, cli_addr_size, tbuf, sizeof(tbuf)));
|
||||
goto fail;
|
||||
}
|
||||
|
||||
if (!get_session_id(s, s->msg_buffer, buffer_size, &session_id, &session_id_size)) {
|
||||
mslog(s, NULL, LOG_INFO, "%s: too short handshake packet",
|
||||
human_addr((struct sockaddr*)&cli_addr, cli_addr_size, tbuf, sizeof(tbuf)));
|
||||
@@ -1272,6 +1304,7 @@ int main(int argc, char** argv)
|
||||
void *worker_pool;
|
||||
void *main_pool, *config_pool;
|
||||
main_server_st *s;
|
||||
char *str;
|
||||
|
||||
#ifdef DEBUG_LEAKS
|
||||
talloc_enable_leak_report_full();
|
||||
@@ -1309,6 +1342,10 @@ int main(int argc, char** argv)
|
||||
exit(1);
|
||||
}
|
||||
|
||||
str = getenv("OCSERV_ALLOW_BROKEN_CLIENTS");
|
||||
if (str && str[0] == '1' && str[1] == 0)
|
||||
allow_broken_clients = 1;
|
||||
|
||||
list_head_init(&s->proc_list.head);
|
||||
list_head_init(&s->script_list.head);
|
||||
ip_lease_init(&s->ip_leases);
|
||||
|
||||
Reference in New Issue
Block a user