| 181 | } |
| 182 | |
| 183 | bool validateWireGuardConfig(const std::string &clientIpAddress, |
| 184 | const std::string &clientDnsAddressList, |
| 185 | const std::vector<std::string> &allowedIps, |
| 186 | const std::string &peerEndpoint) |
| 187 | { |
| 188 | // clientIpAddress may be a comma-separated dual-stack list (v4 + v6) when |
| 189 | // the WireGuard server pushes both families, e.g. "10.245.6.78/32, fd00:abcd::1/128". |
| 190 | if (!isValidIpCidrList(clientIpAddress)) { |
| 191 | spdlog::error("Validation: invalid client IP address: \"{}\"", clientIpAddress); |
| 192 | return false; |
| 193 | } |
| 194 | |
| 195 | if (!isValidIpList(clientDnsAddressList)) { |
| 196 | spdlog::error("Validation: invalid DNS address list: \"{}\"", clientDnsAddressList); |
| 197 | return false; |
| 198 | } |
| 199 | |
| 200 | // AllowedIPs may legitimately contain IPv6 entries (e.g. "::/0", "fd00::/64") for |
| 201 | // custom configs and dual-stack server pushes; isValidIpCidr accepts both families. |
| 202 | for (const auto &ip : allowedIps) { |
| 203 | if (!isValidIpCidr(ip)) { |
| 204 | spdlog::error("Validation: invalid AllowedIP entry: \"{}\"", ip); |
| 205 | return false; |
| 206 | } |
| 207 | } |
| 208 | |
| 209 | // peerEndpoint is intentionally restricted to IPv4: DefaultRouteMonitor on |
| 210 | // Linux/macOS still hardcodes `ip route add <host>/32 via <gw>`, which would |
| 211 | // fail for IPv6 hosts. Revisit if the monitor learns to handle IPv6 peers. |
| 212 | if (!isValidPeerEndpoint(peerEndpoint)) { |
| 213 | spdlog::error("Validation: invalid peer endpoint: \"{}\"", peerEndpoint); |
| 214 | return false; |
| 215 | } |
| 216 | |
| 217 | return true; |
| 218 | } |
| 219 | |
| 220 | bool isValidDomain(const std::string &address) |
| 221 | { |
no test coverage detected