From b853140626a54a22688e7efa794a9d54f114b92e Mon Sep 17 00:00:00 2001 From: Davide Beatrici Date: Sun, 19 Jul 2020 23:45:12 +0200 Subject: [PATCH] Cedar: use Proto API for protocol options --- src/Cedar/Admin.c | 5 +--- src/Cedar/Proto.c | 4 ++-- src/Cedar/Proto_OpenVPN.c | 50 +++++++++++++++++++++++++++++---------- src/Cedar/Proto_OpenVPN.h | 10 ++++---- src/Cedar/Proto_SSTP.c | 9 ------- src/Cedar/Proto_SSTP.h | 1 - src/Cedar/Protocol.c | 4 +--- 7 files changed, 47 insertions(+), 36 deletions(-) diff --git a/src/Cedar/Admin.c b/src/Cedar/Admin.c index 789881c0..62632ea9 100644 --- a/src/Cedar/Admin.c +++ b/src/Cedar/Admin.c @@ -2113,7 +2113,6 @@ UINT StMakeOpenVpnConfigFile(ADMIN *a, RPC_READ_LOG_FILE *t) BUF *readme_buf; BUF *readme_pdf_buf; BUF *sample_buf; - OPENVPN_SSTP_CONFIG config; LIST *port_list; char my_hostname[MAX_SIZE]; @@ -2124,9 +2123,7 @@ UINT StMakeOpenVpnConfigFile(ADMIN *a, RPC_READ_LOG_FILE *t) return ERR_NOT_SUPPORTED; } - SiGetOpenVPNAndSSTPConfig(s, &config); - - if (config.EnableOpenVPN == false) + if (ProtoEnabled(s->Proto, "OpenVPN") == false) { return ERR_OPENVPN_IS_NOT_ENABLED; } diff --git a/src/Cedar/Proto.c b/src/Cedar/Proto.c index 2bb33c91..3bb35592 100644 --- a/src/Cedar/Proto.c +++ b/src/Cedar/Proto.c @@ -308,9 +308,9 @@ const PROTO_CONTAINER *ProtoDetect(const PROTO *proto, const PROTO_MODE mode, co const PROTO_CONTAINER *container = LIST_DATA(proto->Containers, i); const PROTO_IMPL *impl = container->Impl; - if (StrCmp(impl->Name(), "OpenVPN") == 0 && proto->Cedar->Server->DisableOpenVPNServer) + if (ProtoEnabled(proto, container->Name) == false) { - Debug("ProtoDetect(): OpenVPN detected, but it's disabled\n"); + Debug("ProtoDetect(): skipping %s because it's disabled\n", container->Name); continue; } diff --git a/src/Cedar/Proto_OpenVPN.c b/src/Cedar/Proto_OpenVPN.c index f03a9c09..682de411 100644 --- a/src/Cedar/Proto_OpenVPN.c +++ b/src/Cedar/Proto_OpenVPN.c @@ -58,7 +58,7 @@ bool OvsInit(void **param, const LIST *options, CEDAR *cedar, INTERRUPT_MANAGER Debug("OvsInit(): cipher: %s, hostname: %s\n", cipher, hostname); - *param = NewOpenVpnServer(cedar, im, se); + *param = NewOpenVpnServer(options, cedar, im, se); return true; } @@ -577,7 +577,7 @@ void OvsProceccRecvPacket(OPENVPN_SERVER *s, UDPPACKET *p, UINT protocol) // Detect obfuscation mode and save it for the next packets in the same session if (se->ObfuscationMode == INFINITE) { - se->ObfuscationMode = OvsDetectObfuscation(p->Data, p->Size, s->Cedar->OpenVPNObfuscationMask); + se->ObfuscationMode = OvsDetectObfuscation(p->Data, p->Size, s->ObfuscationMask); if (se->ObfuscationMode != INFINITE) { Debug("OvsProceccRecvPacket(): detected packet obfuscation/scrambling mode: %u\n", se->ObfuscationMode); @@ -595,7 +595,7 @@ void OvsProceccRecvPacket(OPENVPN_SERVER *s, UDPPACKET *p, UINT protocol) case OPENVPN_SCRAMBLE_MODE_DISABLED: break; case OPENVPN_SCRAMBLE_MODE_XORMASK: - OvsDataXorMask(p->Data, p->Size, s->Cedar->OpenVPNObfuscationMask, StrLen(s->Cedar->OpenVPNObfuscationMask)); + OvsDataXorMask(p->Data, p->Size, s->ObfuscationMask, StrLen(s->ObfuscationMask)); break; case OPENVPN_SCRAMBLE_MODE_XORPTRPOS: OvsDataXorPtrPos(p->Data, p->Size); @@ -604,7 +604,7 @@ void OvsProceccRecvPacket(OPENVPN_SERVER *s, UDPPACKET *p, UINT protocol) OvsDataReverse(p->Data, p->Size); break; case OPENVPN_SCRAMBLE_MODE_OBFUSCATE: - OvsDataXorMask(p->Data, p->Size, s->Cedar->OpenVPNObfuscationMask, StrLen(s->Cedar->OpenVPNObfuscationMask)); + OvsDataXorMask(p->Data, p->Size, s->ObfuscationMask, StrLen(s->ObfuscationMask)); OvsDataXorPtrPos(p->Data, p->Size); OvsDataReverse(p->Data, p->Size); OvsDataXorPtrPos(p->Data, p->Size); @@ -1195,7 +1195,7 @@ void OvsSetupSessionParameters(OPENVPN_SERVER *s, OPENVPN_SESSION *se, OPENVPN_C StrCpy(opt_str, sizeof(opt_str), data->OptionString); if (s->Cedar != NULL && (IsEmptyStr(opt_str) || StartWith(opt_str, "V0 UNDEF") || InStr(opt_str, ",") == false)) { - StrCpy(opt_str, sizeof(opt_str), s->Cedar->OpenVPNDefaultClientOption); + StrCpy(opt_str, sizeof(opt_str), s->DefaultClientOption); } o = NewEntryList(opt_str, ",", " \t"); @@ -2121,7 +2121,7 @@ OPENVPN_SESSION *OvsNewSession(OPENVPN_SERVER *s, IP *server_ip, UINT server_por Copy(&se->ServerIp, server_ip, sizeof(IP)); se->ServerPort = server_port; - se->ObfuscationMode = s->Cedar->OpenVPNObfuscation ? INFINITE : OPENVPN_SCRAMBLE_MODE_DISABLED; + se->ObfuscationMode = s->Obfuscation ? INFINITE : OPENVPN_SCRAMBLE_MODE_DISABLED; se->LastCommTick = s->Now; @@ -2486,8 +2486,7 @@ void OvsRecvPacket(OPENVPN_SERVER *s, LIST *recv_packet_list, UINT protocol) // on Linux, the TAP device must be up after the OpenVPN client is connected. // However there is no direct push instruction to do so to OpenVPN client. // Therefore we push the dummy IPv4 address (RFC7600) to the OpenVPN client. - - if (s->Cedar->OpenVPNPushDummyIPv4AddressOnL2Mode) + if (s->PushDummyIPv4AddressOnL2Mode) { StrCat(option_str, sizeof(option_str), ",ifconfig 192.0.0.8 255.255.255.240"); } @@ -2836,7 +2835,7 @@ void OvsSendPacketRawNow(OPENVPN_SERVER *s, OPENVPN_SESSION *se, void *data, UIN case OPENVPN_SCRAMBLE_MODE_DISABLED: break; case OPENVPN_SCRAMBLE_MODE_XORMASK: - OvsDataXorMask(data, size, s->Cedar->OpenVPNObfuscationMask, StrLen(s->Cedar->OpenVPNObfuscationMask)); + OvsDataXorMask(data, size, s->ObfuscationMask, StrLen(s->ObfuscationMask)); break; case OPENVPN_SCRAMBLE_MODE_XORPTRPOS: OvsDataXorPtrPos(data, size); @@ -2848,7 +2847,7 @@ void OvsSendPacketRawNow(OPENVPN_SERVER *s, OPENVPN_SESSION *se, void *data, UIN OvsDataXorPtrPos(data, size); OvsDataReverse(data, size); OvsDataXorPtrPos(data, size); - OvsDataXorMask(data, size, s->Cedar->OpenVPNObfuscationMask, StrLen(s->Cedar->OpenVPNObfuscationMask)); + OvsDataXorMask(data, size, s->ObfuscationMask, StrLen(s->ObfuscationMask)); } u = NewUdpPacket(&se->ServerIp, se->ServerPort, &se->ClientIp, se->ClientPort, @@ -2937,17 +2936,39 @@ int OvsCompareSessionList(void *p1, void *p2) } // Create a new OpenVPN server -OPENVPN_SERVER *NewOpenVpnServer(CEDAR *cedar, INTERRUPT_MANAGER *interrupt, SOCK_EVENT *sock_event) +OPENVPN_SERVER *NewOpenVpnServer(const LIST *options, CEDAR *cedar, INTERRUPT_MANAGER *interrupt, SOCK_EVENT *sock_event) { + UINT i; OPENVPN_SERVER *s; - // Validate arguments - if (cedar == NULL) + + if (options == NULL || cedar == NULL || interrupt == NULL || sock_event == NULL) { return NULL; } s = ZeroMalloc(sizeof(OPENVPN_SERVER)); + for (i = 0; i < LIST_NUM(options); ++i) + { + const PROTO_OPTION *option = LIST_DATA(options, i); + if (StrCmp(option->Name, "DefaultClientOption") == 0) + { + s->DefaultClientOption = CopyStr(option->String); + } + else if (StrCmp(option->Name, "Obfuscation") == 0) + { + s->Obfuscation = option->Bool; + } + else if (StrCmp(option->Name, "ObfuscationMask") == 0) + { + s->ObfuscationMask = CopyStr(option->String); + } + else if (StrCmp(option->Name, "PushDummyIPv4AddressOnL2Mode") == 0) + { + s->PushDummyIPv4AddressOnL2Mode = option->Bool; + } + } + s->Cedar = cedar; s->Interrupt = interrupt; s->SockEvent = sock_event; @@ -3009,5 +3030,8 @@ void FreeOpenVpnServer(OPENVPN_SERVER *s) DhFree(s->Dh); + Free(s->DefaultClientOption); + Free(s->ObfuscationMask); + Free(s); } diff --git a/src/Cedar/Proto_OpenVPN.h b/src/Cedar/Proto_OpenVPN.h index c468d587..8a5c111d 100644 --- a/src/Cedar/Proto_OpenVPN.h +++ b/src/Cedar/Proto_OpenVPN.h @@ -202,11 +202,13 @@ struct OPENVPN_SERVER UINT NextSessionId; // Next session ID DH_CTX *Dh; // DH key UINT SessionEstablishedCount; // Number of session establishment + // Options + char *DefaultClientOption; // Default option string to push to client + bool Obfuscation; // Obfuscation enabled/disabled + char *ObfuscationMask; // String (mask) for XOR obfuscation + bool PushDummyIPv4AddressOnL2Mode; // Push a dummy IPv4 address in L2 mode }; -// OpenVPN Default Client Option String -#define OVPN_DEF_CLIENT_OPTION_STRING "dev-type tun,link-mtu 1500,tun-mtu 1500,cipher AES-128-CBC,auth SHA1,keysize 128,key-method 2,tls-client" - //// Function prototype const PROTO_IMPL *OvsGetProtoImpl(); const char *OvsName(); @@ -219,7 +221,7 @@ bool OvsProcessDatagrams(void *param, LIST *in, LIST *out); bool OvsIsOk(void *param); UINT OvsEstablishedSessions(void *param); -OPENVPN_SERVER *NewOpenVpnServer(CEDAR *cedar, INTERRUPT_MANAGER *interrupt, SOCK_EVENT *sock_event); +OPENVPN_SERVER *NewOpenVpnServer(const LIST *options, CEDAR *cedar, INTERRUPT_MANAGER *interrupt, SOCK_EVENT *sock_event); void FreeOpenVpnServer(OPENVPN_SERVER *s); void OvsRecvPacket(OPENVPN_SERVER *s, LIST *recv_packet_list, UINT protocol); void OvsProceccRecvPacket(OPENVPN_SERVER *s, UDPPACKET *p, UINT protocol); diff --git a/src/Cedar/Proto_SSTP.c b/src/Cedar/Proto_SSTP.c index 5391e36c..514ddeda 100644 --- a/src/Cedar/Proto_SSTP.c +++ b/src/Cedar/Proto_SSTP.c @@ -7,15 +7,6 @@ #include "CedarPch.h" -static bool g_no_sstp = false; - -// Get the SSTP disabling flag -bool GetNoSstp() -{ - - return g_no_sstp; -} - const PROTO_IMPL *SstpGetProtoImpl() { static const PROTO_IMPL impl = diff --git a/src/Cedar/Proto_SSTP.h b/src/Cedar/Proto_SSTP.h index 44e167c2..adb0347a 100644 --- a/src/Cedar/Proto_SSTP.h +++ b/src/Cedar/Proto_SSTP.h @@ -154,6 +154,5 @@ SSTP_PACKET *SstpNewDataPacket(UCHAR *data, UINT size); SSTP_PACKET *SstpNewControlPacket(USHORT message_type); SSTP_PACKET *SstpNewControlPacketWithAnAttribute(USHORT message_type, SSTP_ATTRIBUTE *a); void SstpSendPacket(SSTP_SERVER *s, SSTP_PACKET *p); -bool GetNoSstp(); #endif // PROTO_SSTP_H diff --git a/src/Cedar/Protocol.c b/src/Cedar/Protocol.c index a34515cb..24707635 100644 --- a/src/Cedar/Protocol.c +++ b/src/Cedar/Protocol.c @@ -5878,9 +5878,7 @@ bool ServerDownloadSignature(CONNECTION *c, char **error_detail_str) } } } - else if (StrCmpi(h->Method, "SSTP_DUPLEX_POST") == 0 && (server->DisableSSTPServer == false || s->IsReverseAcceptedSocket - ) && - GetServerCapsBool(server, "b_support_sstp") && GetNoSstp() == false) + else if (StrCmpi(h->Method, "SSTP_DUPLEX_POST") == 0 && (ProtoEnabled(server->Proto, "SSTP") || s->IsReverseAcceptedSocket) && GetServerCapsBool(server, "b_support_sstp")) { // SSTP client is connected c->WasSstp = true;