1
0
mirror of https://github.com/SoftEtherVPN/SoftEtherVPN.git synced 2024-11-23 01:49:53 +03:00

Merge PR #1014: Addressing the OpenVPN UDP reflection amplification attack

This commit is contained in:
Davide Beatrici 2019-10-22 09:42:08 +02:00 committed by GitHub
commit 79a60bc5f0
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 23 additions and 9 deletions

View File

@ -821,7 +821,7 @@ void OvsProcessRecvControlPacket(OPENVPN_SERVER *s, OPENVPN_SESSION *se, OPENVPN
case OPENVPN_P_CONTROL_HARD_RESET_CLIENT_V2: case OPENVPN_P_CONTROL_HARD_RESET_CLIENT_V2:
// New connection (hard reset) // New connection (hard reset)
OvsSendControlPacket(c, OPENVPN_P_CONTROL_HARD_RESET_SERVER_V2, NULL, 0); OvsSendControlPacketEx(c, OPENVPN_P_CONTROL_HARD_RESET_SERVER_V2, NULL, 0, true);
c->Status = OPENVPN_CHANNEL_STATUS_TLS_WAIT_CLIENT_KEY; c->Status = OPENVPN_CHANNEL_STATUS_TLS_WAIT_CLIENT_KEY;
break; break;
@ -1552,6 +1552,10 @@ void OvsSendControlPacketWithAutoSplit(OPENVPN_CHANNEL *c, UCHAR opcode, UCHAR *
// Send the control packet // Send the control packet
void OvsSendControlPacket(OPENVPN_CHANNEL *c, UCHAR opcode, UCHAR *data, UINT data_size) void OvsSendControlPacket(OPENVPN_CHANNEL *c, UCHAR opcode, UCHAR *data, UINT data_size)
{
OvsSendControlPacketEx(c, opcode, data, data_size, false);
}
void OvsSendControlPacketEx(OPENVPN_CHANNEL *c, UCHAR opcode, UCHAR *data, UINT data_size, bool no_resend)
{ {
OPENVPN_CONTROL_PACKET *p; OPENVPN_CONTROL_PACKET *p;
// Validate arguments // Validate arguments
@ -1562,6 +1566,8 @@ void OvsSendControlPacket(OPENVPN_CHANNEL *c, UCHAR opcode, UCHAR *data, UINT da
p = ZeroMalloc(sizeof(OPENVPN_CONTROL_PACKET)); p = ZeroMalloc(sizeof(OPENVPN_CONTROL_PACKET));
p->NoResend = no_resend;
p->OpCode = opcode; p->OpCode = opcode;
p->PacketId = c->NextSendPacketId++; p->PacketId = c->NextSendPacketId++;
@ -2559,20 +2565,25 @@ void OvsRecvPacket(OPENVPN_SERVER *s, LIST *recv_packet_list)
if (cp->NextSendTime <= s->Now) if (cp->NextSendTime <= s->Now)
{ {
OPENVPN_PACKET *p; if (cp->NoResend == false || cp->NumSent == 0) // To address the UDP reflection amplification attack: https://github.com/SoftEtherVPN/SoftEtherVPN/issues/1001
{
OPENVPN_PACKET *p;
num = OvsGetAckReplyList(c, acks); cp->NumSent++;
p = OvsNewControlPacket(cp->OpCode, j, se->ServerSessionId, num, acks, num = OvsGetAckReplyList(c, acks);
se->ClientSessionId, cp->PacketId, cp->DataSize, cp->Data);
OvsSendPacketNow(s, se, p); p = OvsNewControlPacket(cp->OpCode, j, se->ServerSessionId, num, acks,
se->ClientSessionId, cp->PacketId, cp->DataSize, cp->Data);
OvsFreePacket(p); OvsSendPacketNow(s, se, p);
cp->NextSendTime = s->Now + (UINT64)OPENVPN_CONTROL_PACKET_RESEND_INTERVAL; OvsFreePacket(p);
AddInterrupt(s->Interrupt, cp->NextSendTime); cp->NextSendTime = s->Now + (UINT64)OPENVPN_CONTROL_PACKET_RESEND_INTERVAL;
AddInterrupt(s->Interrupt, cp->NextSendTime);
}
} }
} }

View File

@ -108,6 +108,8 @@ struct OPENVPN_CONTROL_PACKET
UINT DataSize; // Data size UINT DataSize; // Data size
UCHAR *Data; // Data body UCHAR *Data; // Data body
UINT64 NextSendTime; // Scheduled next transmission time UINT64 NextSendTime; // Scheduled next transmission time
bool NoResend; // Disable re-sending
UINT NumSent; // How many times we have sent this packet
}; };
// OpenVPN packet // OpenVPN packet
@ -260,6 +262,7 @@ void OvsSendPacketRawNow(OPENVPN_SERVER *s, OPENVPN_SESSION *se, void *data, UIN
void OvsProcessRecvControlPacket(OPENVPN_SERVER *s, OPENVPN_SESSION *se, OPENVPN_CHANNEL *c, OPENVPN_PACKET *p); void OvsProcessRecvControlPacket(OPENVPN_SERVER *s, OPENVPN_SESSION *se, OPENVPN_CHANNEL *c, OPENVPN_PACKET *p);
void OvsSendControlPacket(OPENVPN_CHANNEL *c, UCHAR opcode, UCHAR *data, UINT data_size); void OvsSendControlPacket(OPENVPN_CHANNEL *c, UCHAR opcode, UCHAR *data, UINT data_size);
void OvsSendControlPacketEx(OPENVPN_CHANNEL *c, UCHAR opcode, UCHAR *data, UINT data_size, bool no_resend);
void OvsSendControlPacketWithAutoSplit(OPENVPN_CHANNEL *c, UCHAR opcode, UCHAR *data, UINT data_size); void OvsSendControlPacketWithAutoSplit(OPENVPN_CHANNEL *c, UCHAR opcode, UCHAR *data, UINT data_size);
void OvsFreeControlPacket(OPENVPN_CONTROL_PACKET *p); void OvsFreeControlPacket(OPENVPN_CONTROL_PACKET *p);
void OvsDeleteFromSendingControlPacketList(OPENVPN_CHANNEL *c, UINT num_acks, UINT *acks); void OvsDeleteFromSendingControlPacketList(OPENVPN_CHANNEL *c, UINT num_acks, UINT *acks);