From 3147abc9bca82d3a7cf6ee1440370e8a4188569e Mon Sep 17 00:00:00 2001 From: vemax78 Date: Mon, 21 Oct 2013 18:44:37 +0200 Subject: [PATCH] Before create new session check if receive DTLS Client Hello --- src/ac/ac_execute.c | 31 +++++++++++++++++-------------- src/common/capwap_dtls.c | 24 ++++++++++++++++++++++++ src/common/capwap_dtls.h | 2 ++ 3 files changed, 43 insertions(+), 14 deletions(-) diff --git a/src/ac/ac_execute.c b/src/ac/ac_execute.c index 05ae1e1..f94fcbf 100644 --- a/src/ac/ac_execute.c +++ b/src/ac/ac_execute.c @@ -591,20 +591,23 @@ int ac_execute(void) { } } } else if (check == CAPWAP_DTLS_PACKET) { - /* Need create a new sessione for check if it is a valid DTLS handshake */ - if (ac_backend_isconnect() && (sessioncount < g_ac.descriptor.maxwtp)) { - /* TODO prevent dos attack add filtering ip for multiple error */ - - /* Retrive socket info */ - capwap_get_network_socket(&g_ac.net, &ctrlsock, fds[index].fd); - - /* Create a new session */ - session = ac_create_session(&recvfromaddr, &recvtoaddr, &ctrlsock); - if (session) { - ac_session_add_packet(session, buffer, buffersize, isctrlsocket, 0); - - /* Release reference */ - ac_session_release_reference(session); + /* Before create new session check if receive DTLS Client Hello */ + if (capwap_sanity_check_dtls_clienthello(&((char*)buffer)[sizeof(struct capwap_dtls_header)], buffersize - sizeof(struct capwap_dtls_header))) { + /* Need create a new session for check if it is a valid DTLS handshake */ + if (ac_backend_isconnect() && (sessioncount < g_ac.descriptor.maxwtp)) { + /* TODO prevent dos attack add filtering ip for multiple error */ + + /* Retrive socket info */ + capwap_get_network_socket(&g_ac.net, &ctrlsock, fds[index].fd); + + /* Create a new session */ + session = ac_create_session(&recvfromaddr, &recvtoaddr, &ctrlsock); + if (session) { + ac_session_add_packet(session, buffer, buffersize, isctrlsocket, 0); + + /* Release reference */ + ac_session_release_reference(session); + } } } } diff --git a/src/common/capwap_dtls.c b/src/common/capwap_dtls.c index 79ad8c0..e78b3b1 100644 --- a/src/common/capwap_dtls.c +++ b/src/common/capwap_dtls.c @@ -974,3 +974,27 @@ int capwap_decrypt_packet(struct capwap_dtls* dtls, void* encrybuffer, int size, return result; } + +/* */ +#define SIZEOF_DTLS_LAYERS 14 +#define DTLS_RECORD_LAYER_HANDSHAKE_CONTENT_TYPE 22 +#define DTLS_1_0_VERSION 0xfeff +#define DTLS_1_2_VERSION 0xfefd +#define DTLS_HANDSHAKE_LAYER_CLIENT_HELLO 1 + +/* */ +int capwap_sanity_check_dtls_clienthello(void* buffer, int buffersize) { + unsigned char* dtlsdata = (unsigned char*)buffer; + + /* Read DTLS packet in RAW mode */ + if ((buffer != NULL) && (buffersize > SIZEOF_DTLS_LAYERS)) { + if (dtlsdata[0] == DTLS_RECORD_LAYER_HANDSHAKE_CONTENT_TYPE) { + uint16_t version = ntohs(*(uint16_t*)(dtlsdata + 1)); + if (((version == DTLS_1_0_VERSION) || (version == DTLS_1_2_VERSION)) && (dtlsdata[13] == DTLS_HANDSHAKE_LAYER_CLIENT_HELLO)) { + return 1; + } + } + } + + return 0; +} diff --git a/src/common/capwap_dtls.h b/src/common/capwap_dtls.h index 50446a8..6fea12f 100644 --- a/src/common/capwap_dtls.h +++ b/src/common/capwap_dtls.h @@ -115,4 +115,6 @@ int capwap_crypt_sendto(struct capwap_dtls* dtls, int sock, void* buffer, int si int capwap_crypt_sendto_fragmentpacket(struct capwap_dtls* dtls, int sock, struct capwap_list* fragmentlist, struct sockaddr_storage* sendfromaddr, struct sockaddr_storage* sendtoaddr); int capwap_decrypt_packet(struct capwap_dtls* dtls, void* encrybuffer, int size, void* plainbuffer, int maxsize); +int capwap_sanity_check_dtls_clienthello(void* buffer, int buffersize); + #endif /* __CAPWAP_DTLS_HEADER__ */