| 81 | } |
| 82 | |
| 83 | bool writeOVPNFile(const std::string &dnsScript, unsigned int port, const std::string &config, const std::string &httpProxy, |
| 84 | unsigned int httpPort, const std::string &socksProxy, unsigned int socksPort) |
| 85 | { |
| 86 | // open()'s mode is ignored on pre-existing files; unlink first to force the intended perms. |
| 87 | // Unlinking before filterConfig also ensures a rejected config never leaves a stale file behind. |
| 88 | unlink(WS_LINUX_RUN_DIR "/config.ovpn"); |
| 89 | |
| 90 | std::string filtered; |
| 91 | if (!OvpnDirectiveWhitelist::filterConfig(rewriteForDco(config), filtered)) { |
| 92 | return false; |
| 93 | } |
| 94 | |
| 95 | int fd = open(WS_LINUX_RUN_DIR "/config.ovpn", O_CREAT | O_WRONLY | O_TRUNC, S_IRUSR | S_IWUSR); |
| 96 | if (fd < 0) { |
| 97 | spdlog::error("Could not open config for writing"); |
| 98 | return false; |
| 99 | } |
| 100 | |
| 101 | if (!IO::writeAll(fd, filtered)) { |
| 102 | spdlog::error("Could not write openvpn config: {}", IO::strerror(errno)); |
| 103 | close(fd); |
| 104 | return false; |
| 105 | } |
| 106 | |
| 107 | // add our own up/down scripts |
| 108 | const std::string upScript = \ |
| 109 | "--script-security 2\n" \ |
| 110 | "up " + dnsScript + "\n" \ |
| 111 | "down " + dnsScript + "\n" \ |
| 112 | "down-pre\n" \ |
| 113 | "dhcp-option DOMAIN-ROUTE .\n"; // prevent DNS leakage and without it doesn't work update-systemd-resolved script |
| 114 | if (!IO::writeAll(fd, upScript)) { |
| 115 | spdlog::error("Could not write openvpn config: {}", IO::strerror(errno)); |
| 116 | close(fd); |
| 117 | return false; |
| 118 | } |
| 119 | |
| 120 | // add management and other options |
| 121 | std::string opts = \ |
| 122 | "dev tun\n" \ |
| 123 | "management 127.0.0.1 " + std::to_string(port) + "\n" \ |
| 124 | "management-query-passwords\n" \ |
| 125 | "management-hold\n" \ |
| 126 | "verb 3\n"; |
| 127 | |
| 128 | if (!s_useDco) { |
| 129 | opts += "disable-dco\n"; |
| 130 | spdlog::info("Appended disable-dco to OpenVPN config"); |
| 131 | } |
| 132 | |
| 133 | if (httpProxy.length() > 0) { |
| 134 | opts += "http-proxy " + httpProxy + " " + std::to_string(httpPort) + " auto\n"; |
| 135 | } else if (socksProxy.length() > 0) { |
| 136 | opts += "socks-proxy " + socksProxy + " " + std::to_string(socksPort) + "\n"; |
| 137 | } |
| 138 | |
| 139 | if (!IO::writeAll(fd, opts)) { |
| 140 | spdlog::error("Could not write additional options: {}", IO::strerror(errno)); |
no test coverage detected