diff options
Diffstat (limited to 'central/src/main/java/moe/yuuta/dn42peering/manage/ManagementUI.java')
-rw-r--r-- | central/src/main/java/moe/yuuta/dn42peering/manage/ManagementUI.java | 308 |
1 files changed, 155 insertions, 153 deletions
diff --git a/central/src/main/java/moe/yuuta/dn42peering/manage/ManagementUI.java b/central/src/main/java/moe/yuuta/dn42peering/manage/ManagementUI.java index 40a93d7..4f9954b 100644 --- a/central/src/main/java/moe/yuuta/dn42peering/manage/ManagementUI.java +++ b/central/src/main/java/moe/yuuta/dn42peering/manage/ManagementUI.java @@ -2,7 +2,8 @@ package moe.yuuta.dn42peering.manage; import com.wireguard.crypto.Key; import com.wireguard.crypto.KeyFormatException; -import edazdarevic.commons.net.CIDRUtils; +import inet.ipaddr.IPAddress; +import inet.ipaddr.IPAddressString; import io.vertx.core.AsyncResult; import io.vertx.core.Future; import io.vertx.core.Handler; @@ -15,12 +16,10 @@ import moe.yuuta.dn42peering.node.Node; import moe.yuuta.dn42peering.peer.Peer; import moe.yuuta.dn42peering.peer.ProvisionStatus; import moe.yuuta.dn42peering.portal.FormException; -import org.apache.commons.validator.routines.InetAddressValidator; import javax.annotation.Nonnull; import javax.annotation.Nullable; import java.io.IOException; -import java.net.Inet6Address; import java.util.ArrayList; import java.util.HashMap; import java.util.List; @@ -226,183 +225,186 @@ class ManagementUI { int n = nodeId; return Future.<Node>future(f -> nodeService.getNode(n, f)) .compose(node -> { - try { - final List<String> errors = new ArrayList<>(10); - if(node == null) { - errors.add("The node selection is invalid."); - } - Peer.VPNType type = null; - if (form.containsKey("vpn")) { - final String rawVPN = form.getString("vpn"); - if (rawVPN == null) { - errors.add("Tunneling type is not specified."); - } else - switch (rawVPN) { - case "wg": - type = Peer.VPNType.WIREGUARD; - break; - default: - errors.add("Tunneling type is unexpected."); - break; - } - } else { + final List<String> errors = new ArrayList<>(10); + if(node == null) { + errors.add("The node selection is invalid."); + } + Peer.VPNType type = null; + if (form.containsKey("vpn")) { + final String rawVPN = form.getString("vpn"); + if (rawVPN == null) { errors.add("Tunneling type is not specified."); - } - - String ipv4 = null; - if (form.containsKey("ipv4")) { - ipv4 = form.getString("ipv4"); - if (ipv4 == null || ipv4.isEmpty()) { - errors.add("IPv4 address is not specified."); - ipv4 = null; // Non-null but empty values could cause problems. - } else { - if (InetAddressValidator.getInstance().isValidInet4Address(ipv4)) { - if (!new CIDRUtils("172.20.0.0/14").isInRange(ipv4)) { - errors.add("IPv4 address is illegal. It must be a dn42 IPv4 address (172.20.x.x to 172.23.x.x)."); - } - } else - errors.add("IPv4 address is illegal. Cannot parse your address."); + } else + switch (rawVPN) { + case "wg": + type = Peer.VPNType.WIREGUARD; + break; + default: + errors.add("Tunneling type is unexpected."); + break; } - } else { - errors.add("IPv4 address is not specified."); - } + } else { + errors.add("Tunneling type is not specified."); + } - String ipv6 = null; - if (form.containsKey("ipv6")) { - ipv6 = form.getString("ipv6"); - if (ipv6 != null && !ipv6.isEmpty()) { - if (InetAddressValidator.getInstance().isValidInet6Address(ipv6)) { - if (!new CIDRUtils("fd00::/8").isInRange(ipv6) && - !Inet6Address.getByName(ipv6).isLinkLocalAddress()) { - errors.add("IPv6 address is illegal. It must be a dn42 or link-local IPv6 address."); - } - ipv6 = ipv6.replaceAll("((?::0\\b){2,}):?(?!\\S*\\b\\1:0\\b)(\\S*)", "::$2"); - } else - errors.add("IPv6 address is illegal. Cannot parse your address."); - } else { - ipv6 = null; // Non-null but empty values could cause problems. - } + String ipv4 = null; + if (form.containsKey("ipv4")) { + ipv4 = form.getString("ipv4"); + if (ipv4 == null || ipv4.isEmpty()) { + errors.add("IPv4 address is not specified."); + ipv4 = null; // Non-null but empty values could cause problems. + } else { + final IPAddress address = new IPAddressString(ipv4).getHostAddress(); + if (address != null) { + if (!new IPAddressString("172.20.0.0/14").getAddress().contains(address)) { + errors.add("IPv4 address is illegal. It must be a dn42 IPv4 address (172.20.x.x to 172.23.x.x)."); + } + // Remove prefixes + ipv4 = address.toNormalizedString(); + } else + errors.add("IPv4 address is illegal. Cannot parse your address."); } + } else { + errors.add("IPv4 address is not specified."); + } - boolean mpbgp = false; - if (form.containsKey("mpbgp")) { - if (ipv6 == null) { - errors.add("MP-BGP cannot be enabled if you do not have a valid IPv6 address."); - } else { - mpbgp = true; - } + String ipv6 = null; + if (form.containsKey("ipv6")) { + ipv6 = form.getString("ipv6"); + if (ipv6 != null && !ipv6.isEmpty()) { + final IPAddress address = new IPAddressString(ipv6).getHostAddress(); + if (address != null) { + ipv6 = address.toCanonicalString(); + if(!new IPAddressString("fd00::/8").getAddress().contains(address) && + !address.isLinkLocal()) { + errors.add("IPv6 address is illegal. It must be a dn42 or link-local IPv6 address."); + } + } else + errors.add("IPv6 address is illegal. Cannot parse your address."); + } else { + ipv6 = null; // Non-null but empty values could cause problems. } + } - String wgEndpoint = null; - boolean wgEndpointCorrect = false; - if (form.containsKey("wg_endpoint")) { - if (type == Peer.VPNType.WIREGUARD) { - wgEndpoint = form.getString("wg_endpoint"); - if (wgEndpoint != null && !wgEndpoint.isEmpty()) { - if (InetAddressValidator.getInstance().isValidInet4Address(wgEndpoint)) { - if (new CIDRUtils("10.0.0.0/8").isInRange(wgEndpoint) || - new CIDRUtils("192.168.0.0/16").isInRange(wgEndpoint) || - new CIDRUtils("172.16.0.0/23").isInRange(wgEndpoint)) { - errors.add("WireGuard EndPoint is illegal. It must not be an internal address."); - } else { - wgEndpointCorrect = true; - } - } else - errors.add("WireGuard EndPoint is illegal. Cannot parse your address."); - } else { - wgEndpoint = null; // Non-null but empty values could cause problems. - } - } else { - errors.add("WireGuard tunneling is not selected but WireGuard Endpoint configuration appears."); - } + boolean mpbgp = false; + if (form.containsKey("mpbgp")) { + if (ipv6 == null) { + errors.add("MP-BGP cannot be enabled if you do not have a valid IPv6 address."); + } else { + mpbgp = true; } + } - Integer wgEndpointPort = null; - if (form.containsKey("wg_endpoint_port")) { - if (type == Peer.VPNType.WIREGUARD) { - final String rawPort = form.getString("wg_endpoint_port"); - if(rawPort != null && !rawPort.isEmpty()) { - if (wgEndpointCorrect) { - try { - wgEndpointPort = Integer.parseInt(rawPort); - if (wgEndpointPort < 0 || wgEndpointPort > 65535) { - errors.add("WireGuard EndPoint port must be in UDP port range."); - } - } catch (NumberFormatException | NullPointerException ignored) { - errors.add("WireGuard EndPoint port is not valid. It must be a number."); - } + String wgEndpoint = null; + boolean wgEndpointCorrect = false; + if (form.containsKey("wg_endpoint")) { + if (type == Peer.VPNType.WIREGUARD) { + wgEndpoint = form.getString("wg_endpoint"); + if (wgEndpoint != null && !wgEndpoint.isEmpty()) { + final IPAddress address = new IPAddressString(wgEndpoint).getHostAddress(); + if (address != null) { + if(new IPAddressString("10.0.0.0/8").getAddress().contains(address) || + new IPAddressString("192.168.0.0/16").getAddress().contains(address) || + new IPAddressString("172.16.0.0/23").getAddress().contains(address)) { + errors.add("WireGuard EndPoint is illegal. It must not be an internal address."); } else { - errors.add("WireGuard EndPoint IP is not specified or invalid, but port is specified."); + // Remove prefixes + wgEndpoint = address.toNormalizedString(); + wgEndpointCorrect = true; } - } + } else + errors.add("WireGuard EndPoint is illegal. Cannot parse your address."); } else { - errors.add("WireGuard tunneling is not selected but WireGuard Endpoint configuration appears."); + wgEndpoint = null; // Non-null but empty values could cause problems. } + } else { + errors.add("WireGuard tunneling is not selected but WireGuard Endpoint configuration appears."); } + } - // When user specified the endpoint without the port. - if(type == Peer.VPNType.WIREGUARD && - wgEndpointCorrect && - wgEndpointPort == null) { - errors.add("WireGuard EndPoint IP is specified, but the port is missing."); - } - - String wgPubKey = null; - if (form.containsKey("wg_pubkey")) { - if (type == Peer.VPNType.WIREGUARD) { - wgPubKey = form.getString("wg_pubkey"); - if (wgPubKey == null || wgPubKey.isEmpty()) { - errors.add("WireGuard public key is not specified."); - wgPubKey = null; // Non-null but empty values could cause problems. - } else { + Integer wgEndpointPort = null; + if (form.containsKey("wg_endpoint_port")) { + if (type == Peer.VPNType.WIREGUARD) { + final String rawPort = form.getString("wg_endpoint_port"); + if(rawPort != null && !rawPort.isEmpty()) { + if (wgEndpointCorrect) { try { - Key.fromBase64(wgPubKey); - } catch (KeyFormatException e) { - errors.add("WireGuard public key is not valid."); + wgEndpointPort = Integer.parseInt(rawPort); + if (wgEndpointPort < 0 || wgEndpointPort > 65535) { + errors.add("WireGuard EndPoint port must be in UDP port range."); + } + } catch (NumberFormatException | NullPointerException ignored) { + errors.add("WireGuard EndPoint port is not valid. It must be a number."); } + } else { + errors.add("WireGuard EndPoint IP is not specified or invalid, but port is specified."); } - } else { - errors.add("WireGuard tunneling is not selected but WireGuard public key appears."); } } else { - if (type == Peer.VPNType.WIREGUARD) { - errors.add("WireGuard public key is not specified."); - } + errors.add("WireGuard tunneling is not selected but WireGuard Endpoint configuration appears."); } + } - if(node != null && !node.getSupportedVPNTypes().contains(type)) { - errors.add(String.format("Node %s does not support VPN type %s.", node.getName(), - type)); - } + // When user specified the endpoint without the port. + if(type == Peer.VPNType.WIREGUARD && + wgEndpointCorrect && + wgEndpointPort == null) { + errors.add("WireGuard EndPoint IP is specified, but the port is missing."); + } - Peer peer; + String wgPubKey = null; + if (form.containsKey("wg_pubkey")) { if (type == Peer.VPNType.WIREGUARD) { - peer = new Peer(ipv4, ipv6, wgEndpoint, wgEndpointPort, wgPubKey, mpbgp, n); + wgPubKey = form.getString("wg_pubkey"); + if (wgPubKey == null || wgPubKey.isEmpty()) { + errors.add("WireGuard public key is not specified."); + wgPubKey = null; // Non-null but empty values could cause problems. + } else { + try { + Key.fromBase64(wgPubKey); + } catch (KeyFormatException e) { + errors.add("WireGuard public key is not valid."); + } + } } else { - peer = new Peer( - -1, - type, - null, /* ASN: To be filled later */ - ipv4, - ipv6, - wgEndpoint, - wgEndpointPort, - null, /* Self public key: Generate later if needed */ - null, /* Self private key: Generate later if needed */ - wgPubKey, - null /* Preshared Secret: Generate later if needed */, - ProvisionStatus.NOT_PROVISIONED, - mpbgp, - n - ); + errors.add("WireGuard tunneling is not selected but WireGuard public key appears."); } - if(errors.isEmpty()) { - return Future.succeededFuture(peer); - } else { - return Future.failedFuture(new FormException(peer, errors.toArray(new String[]{}))); + } else { + if (type == Peer.VPNType.WIREGUARD) { + errors.add("WireGuard public key is not specified."); } - } catch (IOException e) { - return Future.failedFuture(e); + } + + if(node != null && !node.getSupportedVPNTypes().contains(type)) { + errors.add(String.format("Node %s does not support VPN type %s.", node.getName(), + type)); + } + + Peer peer; + if (type == Peer.VPNType.WIREGUARD) { + peer = new Peer(ipv4, ipv6, wgEndpoint, wgEndpointPort, wgPubKey, mpbgp, n); + } else { + peer = new Peer( + -1, + type, + null, /* ASN: To be filled later */ + ipv4, + ipv6, + wgEndpoint, + wgEndpointPort, + null, /* Self public key: Generate later if needed */ + null, /* Self private key: Generate later if needed */ + wgPubKey, + null /* Preshared Secret: Generate later if needed */, + ProvisionStatus.NOT_PROVISIONED, + mpbgp, + n + ); + } + if(errors.isEmpty()) { + return Future.succeededFuture(peer); + } else { + return Future.failedFuture(new FormException(peer, errors.toArray(new String[]{}))); } }); } |