From a47ea011b1320b5a8df0cac7b9e74bb97043b16c Mon Sep 17 00:00:00 2001 From: Jiacheng Guo Date: Sat, 11 Apr 2020 03:26:53 +0800 Subject: [PATCH] [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. --- Android.mk | 1 + src/core/config/ip6.h | 17 +++++++++++++++++ src/core/net/ip6.cpp | 36 ++++++++++++++++++++++++++++++++++++ src/core/net/ip6_filter.cpp | 18 ++++++++++++++++++ src/core/net/ip6_filter.hpp | 10 ++++++++++ 5 files changed, 82 insertions(+) diff --git a/Android.mk b/Android.mk index b7a9f78fb..fec4ed1a0 100644 --- a/Android.mk +++ b/Android.mk @@ -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 diff --git a/src/core/config/ip6.h b/src/core/config/ip6.h index 56320dbe3..0db4a805d 100644 --- a/src/core/config/ip6.h +++ b/src/core/config/ip6.h @@ -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_ diff --git a/src/core/net/ip6.cpp b/src/core/net/ip6.cpp index 24f93fa7b..4d2170845 100644 --- a/src/core/net/ip6.cpp +++ b/src/core/net/ip6.cpp @@ -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().IsUnsecurePort(dstPort)) + { + Get().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().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().SendMessage(aMessage)); } diff --git a/src/core/net/ip6_filter.cpp b/src/core/net/ip6_filter.cpp index 60e4776ee..68942e9bb 100644 --- a/src/core/net/ip6_filter.cpp +++ b/src/core/net/ip6_filter.cpp @@ -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)); diff --git a/src/core/net/ip6_filter.hpp b/src/core/net/ip6_filter.hpp index 0e4ec145b..d3fea8560 100644 --- a/src/core/net/ip6_filter.hpp +++ b/src/core/net/ip6_filter.hpp @@ -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. *