[ip6] disable security for link-local packets from unsecure ports (#4782)

If this feature is enabled, OpenThread will automatically disable
link-level security for packets sent with unsecure source ports. Once
a secure packet is received on the unsecure port, this port will be
removed from the unsecure port list.
This commit is contained in:
Jiacheng Guo
2020-04-10 12:26:53 -07:00
committed by GitHub
parent 03f4a4317e
commit a47ea011b1
5 changed files with 82 additions and 0 deletions
+1
View File
@@ -66,6 +66,7 @@ ifeq ($(USE_OTBR_DAEMON), 1)
OPENTHREAD_PUBLIC_CFLAGS += \
-DOPENTHREAD_CONFIG_PLATFORM_NETIF_ENABLE=1 \
-DOPENTHREAD_CONFIG_PLATFORM_UDP_ENABLE=1 \
-DOPENTHREAD_CONFIG_UNSECURE_TRAFFIC_MANAGED_BY_STACK_ENABLE=1 \
-DOPENTHREAD_POSIX_CONFIG_DAEMON_ENABLE=1 \
$(NULL)
else
+17
View File
@@ -160,4 +160,21 @@
#define OPENTHREAD_CONFIG_MPL_DYNAMIC_INTERVAL_ENABLE 0
#endif
/**
* @def OPENTHREAD_CONFIG_UNSECURE_TRAFFIC_MANAGED_BY_STACK_ENABLE
*
* Define as 1 to enable dynamic unsecure port management
*
* If this feature is enabled, OpenThread will automaitically disable link-level
* security for packets sent with unsecure source ports. Once we receive a secure
* packet sent to the unsecure port, this port will be removed from the unsecure
* port list.
*
* Enable only if you know well about its behavior.
*
*/
#ifndef OPENTHREAD_CONFIG_UNSECURE_TRAFFIC_MANAGED_BY_STACK_ENABLE
#define OPENTHREAD_CONFIG_UNSECURE_TRAFFIC_MANAGED_BY_STACK_ENABLE 0
#endif
#endif // CONFIG_IP6_H_
+36
View File
@@ -42,6 +42,7 @@
#include "common/random.hpp"
#include "net/icmp6.hpp"
#include "net/ip6_address.hpp"
#include "net/ip6_filter.hpp"
#include "net/netif.hpp"
#include "net/udp6.hpp"
#include "thread/mle.hpp"
@@ -1230,6 +1231,23 @@ otError Ip6::HandleDatagram(Message &aMessage, Netif *aNetif, const void *aLinkM
ExitNow(tunnel = true);
}
#if OPENTHREAD_CONFIG_UNSECURE_TRAFFIC_MANAGED_BY_STACK_ENABLE
if (aFromNcpHost && (nextHeader == kProtoTcp || nextHeader == kProtoUdp))
{
uint16_t dstPort;
// TCP/UDP shares header uint16_t srcPort, uint16_t dstPort
VerifyOrExit(aMessage.Read(aMessage.GetOffset() + sizeof(uint16_t), sizeof(dstPort), &dstPort) ==
sizeof(dstPort),
error = OT_ERROR_PARSE);
dstPort = HostSwap16(dstPort);
if (aMessage.IsLinkSecurityEnabled() && Get<ot::Ip6::Filter>().IsUnsecurePort(dstPort))
{
Get<ot::Ip6::Filter>().RemoveUnsecurePort(dstPort);
}
}
#endif
ProcessReceiveCallback(aMessage, messageInfo, nextHeader, aFromNcpHost);
SuccessOrExit(error = HandlePayload(aMessage, messageInfo, nextHeader));
@@ -1268,6 +1286,24 @@ otError Ip6::HandleDatagram(Message &aMessage, Netif *aNetif, const void *aLinkM
hopLimit = header.GetHopLimit();
aMessage.Write(Header::GetHopLimitOffset(), Header::GetHopLimitSize(), &hopLimit);
#if OPENTHREAD_CONFIG_UNSECURE_TRAFFIC_MANAGED_BY_STACK_ENABLE
// check whether source port is an unsecure port
if (aFromNcpHost && (nextHeader == kProtoTcp || nextHeader == kProtoUdp))
{
uint16_t sourcePort;
VerifyOrExit(aMessage.Read(aMessage.GetOffset(), sizeof(sourcePort), &sourcePort) == sizeof(sourcePort),
error = OT_ERROR_PARSE);
sourcePort = HostSwap16(sourcePort);
if (Get<ot::Ip6::Filter>().IsUnsecurePort(sourcePort))
{
aMessage.SetLinkSecurityEnabled(false);
otLogInfoIp6("Disabled link security for packet to %s",
header.GetDestination().ToString().AsCString());
}
}
#endif
// submit aMessage to interface
SuccessOrExit(error = Get<ThreadNetif>().SendMessage(aMessage));
}
+18
View File
@@ -37,6 +37,7 @@
#include "common/code_utils.hpp"
#include "common/instance.hpp"
#include "common/logging.hpp"
#include "meshcop/meshcop.hpp"
#include "net/ip6.hpp"
#include "net/tcp.hpp"
@@ -136,6 +137,7 @@ otError Filter::AddUnsecurePort(uint16_t aPort)
if (mUnsecurePorts[i] == 0)
{
mUnsecurePorts[i] = aPort;
otLogInfoIp6("Added unsecure port %d", aPort);
ExitNow();
}
}
@@ -163,6 +165,7 @@ otError Filter::RemoveUnsecurePort(uint16_t aPort)
// Clear the last port entry.
mUnsecurePorts[i] = 0;
otLogInfoIp6("Removed unsecure port %d", aPort);
ExitNow();
}
}
@@ -173,6 +176,21 @@ exit:
return error;
}
bool Filter::IsUnsecurePort(uint16_t aPort)
{
bool found = false;
for (int i = 0; i < kMaxUnsecurePorts; i++)
{
if (mUnsecurePorts[i] == aPort)
{
found = true;
break;
}
}
return found;
}
void Filter::RemoveAllUnsecurePorts(void)
{
memset(mUnsecurePorts, 0, sizeof(mUnsecurePorts));
+10
View File
@@ -97,6 +97,16 @@ public:
*/
otError RemoveUnsecurePort(uint16_t aPort);
/**
* This method checks whether a port is in the unsecure port list.
*
* @param[in] aPort The port value.
*
* @returns Whether the given port is in the unsecure port list.
*
*/
bool IsUnsecurePort(uint16_t aPort);
/**
* This method removes all ports from the allowed unsecure port list.
*