浏览代码

enable ICMP in windows firewall

travis laduke 2 年之前
父节点
当前提交
4959d8079b

+ 172 - 0
osdep/WinFWHelper.cpp

@@ -0,0 +1,172 @@
+#include "WinFWHelper.hpp"
+
+
+namespace ZeroTier {
+
+
+
+void ZeroTier::WinFWHelper::newICMPRule(const InetAddress& ip, uint64_t nwid)
+{
+	char nwString[32] = { 0 };
+	char ipbuf[64];
+
+	sprintf(nwString, "%.16llx", nwid);
+	std::string nwString2 = { nwString };
+	
+	ip.toString(ipbuf);
+
+	if (ip.isV4()) {
+		WinFWHelper::newICMPv4Rule(ipbuf, nwid);
+	}
+	else {
+		WinFWHelper::newICMPv6Rule(ipbuf, nwid);
+	}
+}
+
+void ZeroTier::WinFWHelper::removeICMPRule(const InetAddress& ip, uint64_t nwid)
+{
+	char nwString[32] = { 0 };
+	char ipbuf[64];
+
+	sprintf(nwString, "%.16llx", nwid);
+	std::string nwString2 = { nwString };
+
+	ip.toString(ipbuf);
+
+	if (ip.isV4()) {
+		WinFWHelper::removeICMPv4Rule(ipbuf, nwid);
+	}
+	else {
+		WinFWHelper::removeICMPv6Rule(ipbuf, nwid);
+	}
+}
+
+
+void WinFWHelper::newICMPv4Rule(std::string address, uint64_t nwid)
+{
+	// allows icmp, scoped to a specific ip address and interface name
+
+	char nwString[32] = { 0 };
+	sprintf(nwString, "%.16llx", nwid);
+	std::string nwString2 = { nwString };
+
+		std::string cmd = R"(C:\Windows\System32\WindowsPowershell\v1.0\powershell.exe "New-NetFirewallRule -DisplayName zerotier-icmpv4-)" + nwString2 + address +
+			R"( -InterfaceAlias 'ZeroTier One `[)" + nwString2 + R"(`]')" + 
+			" -Protocol ICMPv4 -Action Allow" + 
+			" -LocalAddress " + address + "\"\r\n";
+		
+		_run(cmd);
+}
+
+void WinFWHelper::newICMPv6Rule(std::string address, uint64_t nwid)
+{
+		// allows icmp, scoped to a specific ip address and interface name
+
+		char nwString[32] = { 0 };
+		sprintf(nwString, "%.16llx", nwid);
+		std::string nwString2 = { nwString };
+
+		std::string cmd = R"(C:\Windows\System32\WindowsPowershell\v1.0\powershell.exe "New-NetFirewallRule -DisplayName zerotier-icmpv6-)" + nwString2 + address +
+			R"( -InterfaceAlias 'ZeroTier One `[)" + nwString2 + R"(`]')" + 
+			" -Protocol ICMPv6 -Action Allow" + 
+			" -LocalAddress " + address + "\"\r\n";
+
+		_run(cmd);
+}
+
+void WinFWHelper::removeICMPv4Rule(std::string addr, uint64_t nwid)
+{
+		// removes 1 icmp firewall rule
+
+		char nwString[32] = { 0 };
+		sprintf(nwString, "%.16llx", nwid);
+		std::string nwString2 = { nwString };
+
+		std::string cmd = R"(C:\Windows\System32\WindowsPowershell\v1.0\powershell.exe "Remove-NetFirewallRule -DisplayName zerotier-icmpv4-)" + nwString2 + addr +
+		 "\"\r\n";
+
+		_run(cmd);
+}
+
+void WinFWHelper::removeICMPv6Rule(std::string addr, uint64_t nwid)
+{
+		// removes 1 icmp firewall rule
+
+		char nwString[32] = { 0 };
+		sprintf(nwString, "%.16llx", nwid);
+		std::string nwString2 = { nwString };
+
+		std::string cmd = R"(C:\Windows\System32\WindowsPowershell\v1.0\powershell.exe "Remove-NetFirewallRule -DisplayName zerotier-icmpv6-)" + nwString2 + addr +
+		 "\"\r\n";
+
+		_run(cmd);
+}
+
+void WinFWHelper::removeICMPv4Rules(uint64_t nwid)
+{
+		// removes all icmp firewall rules for this network id
+
+		char nwString[32] = { 0 };
+		sprintf(nwString, "%.16llx", nwid);
+		std::string nwString2 = { nwString };
+
+		std::string cmd = R"(C:\Windows\System32\WindowsPowershell\v1.0\powershell.exe "Remove-NetFirewallRule -DisplayName zerotier-icmpv4-)" + nwString2 + "*\" \r\n";
+		
+		_run(cmd);
+}
+
+void WinFWHelper::removeICMPv6Rules(uint64_t nwid)
+{
+		// removes all icmp firewall rules for this network id
+
+		char nwString[32] = { 0 };
+		sprintf(nwString, "%.16llx", nwid);
+		std::string nwString2 = { nwString };
+
+		std::string cmd = R"(C:\Windows\System32\WindowsPowershell\v1.0\powershell.exe "Remove-NetFirewallRule -DisplayName zerotier-icmpv6-)" + nwString2 + "*\" \r\n";
+
+		_run(cmd);
+}
+
+void WinFWHelper::removeICMPRules()
+{
+		// removes all icmp firewall rules for all networks
+
+		std::string cmd = R"(C:\Windows\System32\WindowsPowershell\v1.0\powershell.exe "Remove-NetFirewallRule -DisplayName zerotier-icmp*)" + std::string("\r\n");
+
+		_run(cmd);
+}
+
+void WinFWHelper::removeICMPRules(uint64_t nwid)
+{
+		// removes all icmp firewall rules for this network
+		WinFWHelper::removeICMPv4Rules(nwid);
+		WinFWHelper::removeICMPv6Rules(nwid);
+}
+
+
+
+void WinFWHelper::_run(std::string cmd)
+{
+		
+		#ifdef ZT_DEBUG
+				fprintf(stderr, cmd.c_str());
+		#endif
+
+		STARTUPINFOA startupInfo;
+		PROCESS_INFORMATION processInfo;
+		startupInfo.cb = sizeof(startupInfo);
+		memset(&startupInfo, 0, sizeof(STARTUPINFOA));
+		memset(&processInfo, 0, sizeof(PROCESS_INFORMATION));
+
+		if (CreateProcessA(NULL, (LPSTR)cmd.c_str(), NULL, NULL, FALSE, CREATE_NO_WINDOW, NULL, NULL, &startupInfo, &processInfo)) {
+			WaitForSingleObject(processInfo.hProcess, INFINITE);
+
+			CloseHandle(processInfo.hProcess);
+			CloseHandle(processInfo.hThread);
+		}
+}
+
+
+
+}	// namespace ZeroTier

+ 31 - 0
osdep/WinFWHelper.hpp

@@ -0,0 +1,31 @@
+#ifndef WIN_FW_HELPER_H_
+#define WIN_FW_HELPER_H_
+
+#include "../node/InetAddress.hpp"
+
+#include <cstdint>
+#include <vector>
+
+namespace ZeroTier {
+
+class WinFWHelper {
+  public:
+	static void newICMPRule(const InetAddress& ip, uint64_t nwid);
+	static void removeICMPRule(const InetAddress& ip, uint64_t nwid);
+	static void removeICMPRules(uint64_t nwid);
+	static void removeICMPRules();
+
+
+  private:
+	static void _run(std::string cmd);
+	static void newICMPv4Rule(std::string address, uint64_t nwid);
+	static void newICMPv6Rule(std::string address, uint64_t nwid);
+	static void removeICMPv4Rule(std::string address, uint64_t nwid);
+	static void removeICMPv6Rule(std::string address, uint64_t nwid);
+	static void removeICMPv4Rules(uint64_t nwid);
+	static void removeICMPv6Rules(uint64_t nwid);
+};
+
+}	// namespace ZeroTier
+
+#endif

+ 18 - 1
service/OneService.cpp

@@ -78,6 +78,7 @@
 #include "../osdep/MacDNSHelper.hpp"
 #include "../osdep/MacDNSHelper.hpp"
 #elif defined(__WINDOWS__)
 #elif defined(__WINDOWS__)
 #include "../osdep/WinDNSHelper.hpp"
 #include "../osdep/WinDNSHelper.hpp"
+#include "../osdep/WinFWHelper.hpp"
 #endif
 #endif
 
 
 #ifdef ZT_USE_SYSTEM_HTTP_PARSER
 #ifdef ZT_USE_SYSTEM_HTTP_PARSER
@@ -847,6 +848,9 @@ public:
 
 
 	virtual ~OneServiceImpl()
 	virtual ~OneServiceImpl()
 	{
 	{
+#ifdef __WINDOWS__ 
+		WinFWHelper::removeICMPRules();
+#endif
 		_binder.closeAll(_phy);
 		_binder.closeAll(_phy);
 		_phy.close(_localControlSocket4);
 		_phy.close(_localControlSocket4);
 		_phy.close(_localControlSocket6);
 		_phy.close(_localControlSocket6);
@@ -855,6 +859,8 @@ public:
 		curl_global_cleanup();
 		curl_global_cleanup();
 #endif
 #endif
 
 
+
+
 #ifdef ZT_USE_MINIUPNPC
 #ifdef ZT_USE_MINIUPNPC
 		delete _portMapper;
 		delete _portMapper;
 #endif
 #endif
@@ -899,6 +905,7 @@ public:
 				_node = new Node(this,(void *)0,&cb,OSUtils::now());
 				_node = new Node(this,(void *)0,&cb,OSUtils::now());
 			}
 			}
 
 
+
 			// local.conf
 			// local.conf
 			readLocalSettings();
 			readLocalSettings();
 			applyLocalConfig();
 			applyLocalConfig();
@@ -2262,6 +2269,10 @@ public:
 				if (std::find(newManagedIps.begin(),newManagedIps.end(),*ip) == newManagedIps.end()) {
 				if (std::find(newManagedIps.begin(),newManagedIps.end(),*ip) == newManagedIps.end()) {
 					if (!n.tap()->removeIp(*ip))
 					if (!n.tap()->removeIp(*ip))
 						fprintf(stderr,"ERROR: unable to remove ip address %s" ZT_EOL_S, ip->toString(ipbuf));
 						fprintf(stderr,"ERROR: unable to remove ip address %s" ZT_EOL_S, ip->toString(ipbuf));
+
+					#ifdef __WINDOWS__
+					WinFWHelper::removeICMPRule(*ip, n.config().nwid);
+					#endif
 				}
 				}
 			}
 			}
 
 
@@ -2269,6 +2280,10 @@ public:
 				if (std::find(n.managedIps().begin(),n.managedIps().end(),*ip) == n.managedIps().end()) {
 				if (std::find(n.managedIps().begin(),n.managedIps().end(),*ip) == n.managedIps().end()) {
 					if (!n.tap()->addIp(*ip))
 					if (!n.tap()->addIp(*ip))
 						fprintf(stderr,"ERROR: unable to add ip address %s" ZT_EOL_S, ip->toString(ipbuf));
 						fprintf(stderr,"ERROR: unable to add ip address %s" ZT_EOL_S, ip->toString(ipbuf));
+
+					#ifdef __WINDOWS__
+					WinFWHelper::newICMPRule(*ip, n.config().nwid);
+					#endif
 				}
 				}
 			}
 			}
 
 
@@ -2749,8 +2764,10 @@ public:
 					n.tap().reset();
 					n.tap().reset();
 					_nets.erase(nwid);
 					_nets.erase(nwid);
 #if defined(__WINDOWS__) && !defined(ZT_SDK)
 #if defined(__WINDOWS__) && !defined(ZT_SDK)
-					if ((op == ZT_VIRTUAL_NETWORK_CONFIG_OPERATION_DESTROY)&&(winInstanceId.length() > 0))
+					if ((op == ZT_VIRTUAL_NETWORK_CONFIG_OPERATION_DESTROY) && (winInstanceId.length() > 0)) {
 						WindowsEthernetTap::deletePersistentTapDevice(winInstanceId.c_str());
 						WindowsEthernetTap::deletePersistentTapDevice(winInstanceId.c_str());
+						WinFWHelper::removeICMPRules(nwid);
+					}
 #endif
 #endif
 					if (op == ZT_VIRTUAL_NETWORK_CONFIG_OPERATION_DESTROY) {
 					if (op == ZT_VIRTUAL_NETWORK_CONFIG_OPERATION_DESTROY) {
 						char nlcpath[256];
 						char nlcpath[256];

+ 2 - 0
windows/ZeroTierOne/ZeroTierOne.vcxproj

@@ -124,6 +124,7 @@
     <ClCompile Include="..\..\osdep\PortMapper.cpp" />
     <ClCompile Include="..\..\osdep\PortMapper.cpp" />
     <ClCompile Include="..\..\osdep\WinDNSHelper.cpp" />
     <ClCompile Include="..\..\osdep\WinDNSHelper.cpp" />
     <ClCompile Include="..\..\osdep\WindowsEthernetTap.cpp" />
     <ClCompile Include="..\..\osdep\WindowsEthernetTap.cpp" />
+    <ClCompile Include="..\..\osdep\WinFWHelper.cpp" />
     <ClCompile Include="..\..\selftest.cpp">
     <ClCompile Include="..\..\selftest.cpp">
       <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</ExcludedFromBuild>
       <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</ExcludedFromBuild>
       <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">true</ExcludedFromBuild>
       <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">true</ExcludedFromBuild>
@@ -241,6 +242,7 @@
     <ClInclude Include="..\..\osdep\Thread.hpp" />
     <ClInclude Include="..\..\osdep\Thread.hpp" />
     <ClInclude Include="..\..\osdep\WinDNSHelper.hpp" />
     <ClInclude Include="..\..\osdep\WinDNSHelper.hpp" />
     <ClInclude Include="..\..\osdep\WindowsEthernetTap.hpp" />
     <ClInclude Include="..\..\osdep\WindowsEthernetTap.hpp" />
+    <ClInclude Include="..\..\osdep\WinFWHelper.hpp" />
     <ClInclude Include="..\..\service\OneService.hpp" />
     <ClInclude Include="..\..\service\OneService.hpp" />
     <ClInclude Include="..\..\service\SoftwareUpdater.hpp" />
     <ClInclude Include="..\..\service\SoftwareUpdater.hpp" />
     <ClInclude Include="..\..\version.h" />
     <ClInclude Include="..\..\version.h" />

+ 6 - 0
windows/ZeroTierOne/ZeroTierOne.vcxproj.filters

@@ -288,6 +288,9 @@
     <ClCompile Include="..\..\node\AES_armcrypto.cpp">
     <ClCompile Include="..\..\node\AES_armcrypto.cpp">
       <Filter>Source Files\node</Filter>
       <Filter>Source Files\node</Filter>
     </ClCompile>
     </ClCompile>
+    <ClCompile Include="..\..\osdep\WinFWHelper.cpp">
+      <Filter>Source Files\osdep</Filter>
+    </ClCompile>
   </ItemGroup>
   </ItemGroup>
   <ItemGroup>
   <ItemGroup>
     <ClInclude Include="resource.h">
     <ClInclude Include="resource.h">
@@ -551,6 +554,9 @@
     <ClInclude Include="..\..\osdep\WinDNSHelper.hpp">
     <ClInclude Include="..\..\osdep\WinDNSHelper.hpp">
       <Filter>Header Files\osdep</Filter>
       <Filter>Header Files\osdep</Filter>
     </ClInclude>
     </ClInclude>
+    <ClInclude Include="..\..\osdep\WinFWHelper.hpp">
+      <Filter>Header Files\osdep</Filter>
+    </ClInclude>
   </ItemGroup>
   </ItemGroup>
   <ItemGroup>
   <ItemGroup>
     <ResourceCompile Include="ZeroTierOne.rc">
     <ResourceCompile Include="ZeroTierOne.rc">