WinFWHelper.cpp 4.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165
  1. /* This Source Code Form is subject to the terms of the Mozilla Public
  2. * License, v. 2.0. If a copy of the MPL was not distributed with this
  3. * file, You can obtain one at https://mozilla.org/MPL/2.0/.
  4. *
  5. * (c) ZeroTier, Inc.
  6. * https://www.zerotier.com/
  7. */
  8. #include "WinFWHelper.hpp"
  9. namespace ZeroTier {
  10. void ZeroTier::WinFWHelper::newICMPRule(const InetAddress& ip, uint64_t nwid)
  11. {
  12. char nwString[32] = { 0 };
  13. char ipbuf[64];
  14. sprintf(nwString, "%.16llx", nwid);
  15. std::string nwString2 = { nwString };
  16. ip.toString(ipbuf);
  17. if (ip.isV4()) {
  18. WinFWHelper::newICMPv4Rule(ipbuf, nwid);
  19. }
  20. else {
  21. WinFWHelper::newICMPv6Rule(ipbuf, nwid);
  22. }
  23. }
  24. void ZeroTier::WinFWHelper::removeICMPRule(const InetAddress& ip, uint64_t nwid)
  25. {
  26. char nwString[32] = { 0 };
  27. char ipbuf[64];
  28. sprintf(nwString, "%.16llx", nwid);
  29. std::string nwString2 = { nwString };
  30. ip.toString(ipbuf);
  31. if (ip.isV4()) {
  32. WinFWHelper::removeICMPv4Rule(ipbuf, nwid);
  33. }
  34. else {
  35. WinFWHelper::removeICMPv6Rule(ipbuf, nwid);
  36. }
  37. }
  38. void WinFWHelper::newICMPv4Rule(std::string address, uint64_t nwid)
  39. {
  40. // allows icmp, scoped to a specific ip address and interface name
  41. char nwString[32] = { 0 };
  42. sprintf(nwString, "%.16llx", nwid);
  43. std::string nwString2 = { nwString };
  44. 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"(`]')"
  45. + " -Protocol ICMPv4 -Action Allow" + " -LocalAddress " + address + "\"\r\n";
  46. _run(cmd);
  47. }
  48. void WinFWHelper::newICMPv6Rule(std::string address, uint64_t nwid)
  49. {
  50. // allows icmp, scoped to a specific ip address and interface name
  51. char nwString[32] = { 0 };
  52. sprintf(nwString, "%.16llx", nwid);
  53. std::string nwString2 = { nwString };
  54. 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"(`]')"
  55. + " -Protocol ICMPv6 -Action Allow" + " -LocalAddress " + address + "\"\r\n";
  56. _run(cmd);
  57. }
  58. void WinFWHelper::removeICMPv4Rule(std::string addr, uint64_t nwid)
  59. {
  60. // removes 1 icmp firewall rule
  61. char nwString[32] = { 0 };
  62. sprintf(nwString, "%.16llx", nwid);
  63. std::string nwString2 = { nwString };
  64. std::string cmd = R"(C:\Windows\System32\WindowsPowershell\v1.0\powershell.exe "Remove-NetFirewallRule -DisplayName zerotier-icmpv4-)" + nwString2 + addr + "\"\r\n";
  65. _run(cmd);
  66. }
  67. void WinFWHelper::removeICMPv6Rule(std::string addr, uint64_t nwid)
  68. {
  69. // removes 1 icmp firewall rule
  70. char nwString[32] = { 0 };
  71. sprintf(nwString, "%.16llx", nwid);
  72. std::string nwString2 = { nwString };
  73. std::string cmd = R"(C:\Windows\System32\WindowsPowershell\v1.0\powershell.exe "Remove-NetFirewallRule -DisplayName zerotier-icmpv6-)" + nwString2 + addr + "\"\r\n";
  74. _run(cmd);
  75. }
  76. void WinFWHelper::removeICMPv4Rules(uint64_t nwid)
  77. {
  78. // removes all icmp firewall rules for this network id
  79. char nwString[32] = { 0 };
  80. sprintf(nwString, "%.16llx", nwid);
  81. std::string nwString2 = { nwString };
  82. std::string cmd = R"(C:\Windows\System32\WindowsPowershell\v1.0\powershell.exe "Remove-NetFirewallRule -DisplayName zerotier-icmpv4-)" + nwString2 + "*\" \r\n";
  83. _run(cmd);
  84. }
  85. void WinFWHelper::removeICMPv6Rules(uint64_t nwid)
  86. {
  87. // removes all icmp firewall rules for this network id
  88. char nwString[32] = { 0 };
  89. sprintf(nwString, "%.16llx", nwid);
  90. std::string nwString2 = { nwString };
  91. std::string cmd = R"(C:\Windows\System32\WindowsPowershell\v1.0\powershell.exe "Remove-NetFirewallRule -DisplayName zerotier-icmpv6-)" + nwString2 + "*\" \r\n";
  92. _run(cmd);
  93. }
  94. void WinFWHelper::removeICMPRules()
  95. {
  96. // removes all icmp firewall rules for all networks
  97. std::string cmd = R"(C:\Windows\System32\WindowsPowershell\v1.0\powershell.exe "Remove-NetFirewallRule -DisplayName zerotier-icmp*)" + std::string("\r\n");
  98. _run(cmd);
  99. }
  100. void WinFWHelper::removeICMPRules(uint64_t nwid)
  101. {
  102. // removes all icmp firewall rules for this network
  103. WinFWHelper::removeICMPv4Rules(nwid);
  104. WinFWHelper::removeICMPv6Rules(nwid);
  105. }
  106. void WinFWHelper::_run(std::string cmd)
  107. {
  108. #ifdef ZT_DEBUG
  109. fprintf(stderr, cmd.c_str());
  110. #endif
  111. STARTUPINFOA startupInfo;
  112. PROCESS_INFORMATION processInfo;
  113. startupInfo.cb = sizeof(startupInfo);
  114. memset(&startupInfo, 0, sizeof(STARTUPINFOA));
  115. memset(&processInfo, 0, sizeof(PROCESS_INFORMATION));
  116. if (CreateProcessA(NULL, (LPSTR)cmd.c_str(), NULL, NULL, FALSE, CREATE_NO_WINDOW, NULL, NULL, &startupInfo, &processInfo)) {
  117. WaitForSingleObject(processInfo.hProcess, INFINITE);
  118. CloseHandle(processInfo.hProcess);
  119. CloseHandle(processInfo.hThread);
  120. }
  121. }
  122. } // namespace ZeroTier