WinFWHelper.cpp 4.5 KB

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