| 489 | } |
| 490 | |
| 491 | bool FirewallController::disable() |
| 492 | { |
| 493 | // Tear down our own chains and the jumps into the built-in INPUT/OUTPUT chains directly, |
| 494 | // rather than via a client-supplied delete blob, so firewallOff cannot be steered. Jumps must |
| 495 | // be removed before the referenced chain can be deleted. iptables -D/-F/-X are no-ops (non-zero |
| 496 | // exit, ignored) when the rule/chain is already absent, which gives idempotent teardown. |
| 497 | for (const char *tool : {"iptables", "ip6tables"}) { |
| 498 | const bool isV6 = (std::strcmp(tool, "ip6tables") == 0); |
| 499 | |
| 500 | Utils::executeCommand(tool, {"-D", "INPUT", "-j", WS_PRODUCT_NAME_LOWER "_input", "-m", "comment", "--comment", kTag.c_str()}); |
| 501 | Utils::executeCommand(tool, {"-D", "OUTPUT", "-j", WS_PRODUCT_NAME_LOWER "_output", "-m", "comment", "--comment", kTag.c_str()}); |
| 502 | if (!isV6) { |
| 503 | Utils::executeCommand(tool, {"-D", "INPUT", "-j", WS_PRODUCT_NAME_LOWER "_block", "-m", "comment", "--comment", kTag.c_str()}); |
| 504 | Utils::executeCommand(tool, {"-D", "OUTPUT", "-j", WS_PRODUCT_NAME_LOWER "_block", "-m", "comment", "--comment", kTag.c_str()}); |
| 505 | } |
| 506 | |
| 507 | Utils::executeCommand(tool, {"-F", WS_PRODUCT_NAME_LOWER "_input"}); |
| 508 | Utils::executeCommand(tool, {"-F", WS_PRODUCT_NAME_LOWER "_output"}); |
| 509 | Utils::executeCommand(tool, {"-X", WS_PRODUCT_NAME_LOWER "_input"}); |
| 510 | Utils::executeCommand(tool, {"-X", WS_PRODUCT_NAME_LOWER "_output"}); |
| 511 | if (!isV6) { |
| 512 | Utils::executeCommand(tool, {"-F", WS_PRODUCT_NAME_LOWER "_block"}); |
| 513 | Utils::executeCommand(tool, {"-X", WS_PRODUCT_NAME_LOWER "_block"}); |
| 514 | } |
| 515 | } |
| 516 | |
| 517 | std::error_code ec; |
| 518 | std::filesystem::remove(WS_LINUX_RUN_DIR "/rules.v4", ec); |
| 519 | if (ec) { |
| 520 | spdlog::warn("Failed to remove rules.v4: {}", ec.message()); |
| 521 | } |
| 522 | std::filesystem::remove(WS_LINUX_RUN_DIR "/rules.v6", ec); |
| 523 | if (ec) { |
| 524 | spdlog::warn("Failed to remove rules.v6: {}", ec.message()); |
| 525 | } |
| 526 | |
| 527 | // The -D/-F/-X commands above return non-zero for already-absent rules, so their exit codes |
| 528 | // can't distinguish "nothing to do" from "teardown failed". Verify the post-state instead: if a |
| 529 | // jump survived (e.g. xtables lock contention), report failure so firewallOff retries rather |
| 530 | // than latching the baseline to "off" while the kill switch is still up. |
| 531 | return !enabled(); |
| 532 | } |
| 533 | |
| 534 | void FirewallController::probeInterfaceAddresses(const std::string &iface, std::vector<std::string> &v4Addrs, bool &hasNonLinkLocalV6) |
| 535 | { |
nothing calls this directly
no test coverage detected