tunnel: support IncludedApplications as whitelist
Signed-off-by: Jason A. Donenfeld <Jason@zx2c4.com>
This commit is contained in:
		
							parent
							
								
									1ca4dbf1a2
								
							
						
					
					
						commit
						e424765a61
					
				@ -193,6 +193,9 @@ public final class GoBackend implements Backend {
 | 
				
			|||||||
            for (final String excludedApplication : config.getInterface().getExcludedApplications())
 | 
					            for (final String excludedApplication : config.getInterface().getExcludedApplications())
 | 
				
			||||||
                builder.addDisallowedApplication(excludedApplication);
 | 
					                builder.addDisallowedApplication(excludedApplication);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            for (final String includedApplication : config.getInterface().getIncludedApplications())
 | 
				
			||||||
 | 
					                builder.addAllowedApplication(includedApplication);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            for (final InetNetwork addr : config.getInterface().getAddresses())
 | 
					            for (final InetNetwork addr : config.getInterface().getAddresses())
 | 
				
			||||||
                builder.addAddress(addr.getAddress(), addr.getMask());
 | 
					                builder.addAddress(addr.getAddress(), addr.getMask());
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
				
			|||||||
@ -72,6 +72,7 @@ public class BadConfigException extends Exception {
 | 
				
			|||||||
        DNS("DNS"),
 | 
					        DNS("DNS"),
 | 
				
			||||||
        ENDPOINT("Endpoint"),
 | 
					        ENDPOINT("Endpoint"),
 | 
				
			||||||
        EXCLUDED_APPLICATIONS("ExcludedApplications"),
 | 
					        EXCLUDED_APPLICATIONS("ExcludedApplications"),
 | 
				
			||||||
 | 
					        INCLUDED_APPLICATIONS("IncludedApplications"),
 | 
				
			||||||
        LISTEN_PORT("ListenPort"),
 | 
					        LISTEN_PORT("ListenPort"),
 | 
				
			||||||
        MTU("MTU"),
 | 
					        MTU("MTU"),
 | 
				
			||||||
        PERSISTENT_KEEPALIVE("PersistentKeepalive"),
 | 
					        PERSISTENT_KEEPALIVE("PersistentKeepalive"),
 | 
				
			||||||
 | 
				
			|||||||
@ -43,6 +43,7 @@ public final class Interface {
 | 
				
			|||||||
    private final Set<InetNetwork> addresses;
 | 
					    private final Set<InetNetwork> addresses;
 | 
				
			||||||
    private final Set<InetAddress> dnsServers;
 | 
					    private final Set<InetAddress> dnsServers;
 | 
				
			||||||
    private final Set<String> excludedApplications;
 | 
					    private final Set<String> excludedApplications;
 | 
				
			||||||
 | 
					    private final Set<String> includedApplications;
 | 
				
			||||||
    private final KeyPair keyPair;
 | 
					    private final KeyPair keyPair;
 | 
				
			||||||
    private final Optional<Integer> listenPort;
 | 
					    private final Optional<Integer> listenPort;
 | 
				
			||||||
    private final Optional<Integer> mtu;
 | 
					    private final Optional<Integer> mtu;
 | 
				
			||||||
@ -52,6 +53,7 @@ public final class Interface {
 | 
				
			|||||||
        addresses = Collections.unmodifiableSet(new LinkedHashSet<>(builder.addresses));
 | 
					        addresses = Collections.unmodifiableSet(new LinkedHashSet<>(builder.addresses));
 | 
				
			||||||
        dnsServers = Collections.unmodifiableSet(new LinkedHashSet<>(builder.dnsServers));
 | 
					        dnsServers = Collections.unmodifiableSet(new LinkedHashSet<>(builder.dnsServers));
 | 
				
			||||||
        excludedApplications = Collections.unmodifiableSet(new LinkedHashSet<>(builder.excludedApplications));
 | 
					        excludedApplications = Collections.unmodifiableSet(new LinkedHashSet<>(builder.excludedApplications));
 | 
				
			||||||
 | 
					        includedApplications = Collections.unmodifiableSet(new LinkedHashSet<>(builder.includedApplications));
 | 
				
			||||||
        keyPair = Objects.requireNonNull(builder.keyPair, "Interfaces must have a private key");
 | 
					        keyPair = Objects.requireNonNull(builder.keyPair, "Interfaces must have a private key");
 | 
				
			||||||
        listenPort = builder.listenPort;
 | 
					        listenPort = builder.listenPort;
 | 
				
			||||||
        mtu = builder.mtu;
 | 
					        mtu = builder.mtu;
 | 
				
			||||||
@ -81,6 +83,9 @@ public final class Interface {
 | 
				
			|||||||
                case "excludedapplications":
 | 
					                case "excludedapplications":
 | 
				
			||||||
                    builder.parseExcludedApplications(attribute.getValue());
 | 
					                    builder.parseExcludedApplications(attribute.getValue());
 | 
				
			||||||
                    break;
 | 
					                    break;
 | 
				
			||||||
 | 
					                case "includedapplications":
 | 
				
			||||||
 | 
					                    builder.parseIncludedApplications(attribute.getValue());
 | 
				
			||||||
 | 
					                    break;
 | 
				
			||||||
                case "listenport":
 | 
					                case "listenport":
 | 
				
			||||||
                    builder.parseListenPort(attribute.getValue());
 | 
					                    builder.parseListenPort(attribute.getValue());
 | 
				
			||||||
                    break;
 | 
					                    break;
 | 
				
			||||||
@ -106,6 +111,7 @@ public final class Interface {
 | 
				
			|||||||
        return addresses.equals(other.addresses)
 | 
					        return addresses.equals(other.addresses)
 | 
				
			||||||
                && dnsServers.equals(other.dnsServers)
 | 
					                && dnsServers.equals(other.dnsServers)
 | 
				
			||||||
                && excludedApplications.equals(other.excludedApplications)
 | 
					                && excludedApplications.equals(other.excludedApplications)
 | 
				
			||||||
 | 
					                && includedApplications.equals(other.includedApplications)
 | 
				
			||||||
                && keyPair.equals(other.keyPair)
 | 
					                && keyPair.equals(other.keyPair)
 | 
				
			||||||
                && listenPort.equals(other.listenPort)
 | 
					                && listenPort.equals(other.listenPort)
 | 
				
			||||||
                && mtu.equals(other.mtu);
 | 
					                && mtu.equals(other.mtu);
 | 
				
			||||||
@ -141,6 +147,16 @@ public final class Interface {
 | 
				
			|||||||
        return excludedApplications;
 | 
					        return excludedApplications;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /**
 | 
				
			||||||
 | 
					     * Returns the set of applications included exclusively for using the interface.
 | 
				
			||||||
 | 
					     *
 | 
				
			||||||
 | 
					     * @return a set of package names
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
 | 
					    public Set<String> getIncludedApplications() {
 | 
				
			||||||
 | 
					        // The collection is already immutable.
 | 
				
			||||||
 | 
					        return includedApplications;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    /**
 | 
					    /**
 | 
				
			||||||
     * Returns the public/private key pair used by the interface.
 | 
					     * Returns the public/private key pair used by the interface.
 | 
				
			||||||
     *
 | 
					     *
 | 
				
			||||||
@ -174,6 +190,7 @@ public final class Interface {
 | 
				
			|||||||
        hash = 31 * hash + addresses.hashCode();
 | 
					        hash = 31 * hash + addresses.hashCode();
 | 
				
			||||||
        hash = 31 * hash + dnsServers.hashCode();
 | 
					        hash = 31 * hash + dnsServers.hashCode();
 | 
				
			||||||
        hash = 31 * hash + excludedApplications.hashCode();
 | 
					        hash = 31 * hash + excludedApplications.hashCode();
 | 
				
			||||||
 | 
					        hash = 31 * hash + includedApplications.hashCode();
 | 
				
			||||||
        hash = 31 * hash + keyPair.hashCode();
 | 
					        hash = 31 * hash + keyPair.hashCode();
 | 
				
			||||||
        hash = 31 * hash + listenPort.hashCode();
 | 
					        hash = 31 * hash + listenPort.hashCode();
 | 
				
			||||||
        hash = 31 * hash + mtu.hashCode();
 | 
					        hash = 31 * hash + mtu.hashCode();
 | 
				
			||||||
@ -213,6 +230,8 @@ public final class Interface {
 | 
				
			|||||||
        }
 | 
					        }
 | 
				
			||||||
        if (!excludedApplications.isEmpty())
 | 
					        if (!excludedApplications.isEmpty())
 | 
				
			||||||
            sb.append("ExcludedApplications = ").append(Attribute.join(excludedApplications)).append('\n');
 | 
					            sb.append("ExcludedApplications = ").append(Attribute.join(excludedApplications)).append('\n');
 | 
				
			||||||
 | 
					        if (!includedApplications.isEmpty())
 | 
				
			||||||
 | 
					            sb.append("IncludedApplications = ").append(Attribute.join(includedApplications)).append('\n');
 | 
				
			||||||
        listenPort.ifPresent(lp -> sb.append("ListenPort = ").append(lp).append('\n'));
 | 
					        listenPort.ifPresent(lp -> sb.append("ListenPort = ").append(lp).append('\n'));
 | 
				
			||||||
        mtu.ifPresent(m -> sb.append("MTU = ").append(m).append('\n'));
 | 
					        mtu.ifPresent(m -> sb.append("MTU = ").append(m).append('\n'));
 | 
				
			||||||
        sb.append("PrivateKey = ").append(keyPair.getPrivateKey().toBase64()).append('\n');
 | 
					        sb.append("PrivateKey = ").append(keyPair.getPrivateKey().toBase64()).append('\n');
 | 
				
			||||||
@ -240,6 +259,8 @@ public final class Interface {
 | 
				
			|||||||
        private final Set<InetAddress> dnsServers = new LinkedHashSet<>();
 | 
					        private final Set<InetAddress> dnsServers = new LinkedHashSet<>();
 | 
				
			||||||
        // Defaults to an empty set.
 | 
					        // Defaults to an empty set.
 | 
				
			||||||
        private final Set<String> excludedApplications = new LinkedHashSet<>();
 | 
					        private final Set<String> excludedApplications = new LinkedHashSet<>();
 | 
				
			||||||
 | 
					        // Defaults to an empty set.
 | 
				
			||||||
 | 
					        private final Set<String> includedApplications = new LinkedHashSet<>();
 | 
				
			||||||
        // No default; must be provided before building.
 | 
					        // No default; must be provided before building.
 | 
				
			||||||
        @Nullable private KeyPair keyPair;
 | 
					        @Nullable private KeyPair keyPair;
 | 
				
			||||||
        // Defaults to not present.
 | 
					        // Defaults to not present.
 | 
				
			||||||
@ -271,6 +292,9 @@ public final class Interface {
 | 
				
			|||||||
            if (keyPair == null)
 | 
					            if (keyPair == null)
 | 
				
			||||||
                throw new BadConfigException(Section.INTERFACE, Location.PRIVATE_KEY,
 | 
					                throw new BadConfigException(Section.INTERFACE, Location.PRIVATE_KEY,
 | 
				
			||||||
                        Reason.MISSING_ATTRIBUTE, null);
 | 
					                        Reason.MISSING_ATTRIBUTE, null);
 | 
				
			||||||
 | 
					            if (!includedApplications.isEmpty() && !excludedApplications.isEmpty())
 | 
				
			||||||
 | 
					                throw new BadConfigException(Section.INTERFACE, Location.INCLUDED_APPLICATIONS,
 | 
				
			||||||
 | 
					                        Reason.INVALID_KEY, null);
 | 
				
			||||||
            return new Interface(this);
 | 
					            return new Interface(this);
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -284,6 +308,16 @@ public final class Interface {
 | 
				
			|||||||
            return this;
 | 
					            return this;
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        public Builder includeApplication(final String application) {
 | 
				
			||||||
 | 
					            includedApplications.add(application);
 | 
				
			||||||
 | 
					            return this;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        public Builder includeApplications(final Collection<String> applications) {
 | 
				
			||||||
 | 
					            includedApplications.addAll(applications);
 | 
				
			||||||
 | 
					            return this;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        public Builder parseAddresses(final CharSequence addresses) throws BadConfigException {
 | 
					        public Builder parseAddresses(final CharSequence addresses) throws BadConfigException {
 | 
				
			||||||
            try {
 | 
					            try {
 | 
				
			||||||
                for (final String address : Attribute.split(addresses))
 | 
					                for (final String address : Attribute.split(addresses))
 | 
				
			||||||
@ -308,6 +342,10 @@ public final class Interface {
 | 
				
			|||||||
            return excludeApplications(Lists.of(Attribute.split(apps)));
 | 
					            return excludeApplications(Lists.of(Attribute.split(apps)));
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        public Builder parseIncludedApplications(final CharSequence apps) {
 | 
				
			||||||
 | 
					            return includeApplications(Lists.of(Attribute.split(apps)));
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        public Builder parseListenPort(final String listenPort) throws BadConfigException {
 | 
					        public Builder parseListenPort(final String listenPort) throws BadConfigException {
 | 
				
			||||||
            try {
 | 
					            try {
 | 
				
			||||||
                return setListenPort(Integer.parseInt(listenPort));
 | 
					                return setListenPort(Integer.parseInt(listenPort));
 | 
				
			||||||
 | 
				
			|||||||
@ -1 +1 @@
 | 
				
			|||||||
Subproject commit a8063adc8ae9b4fc9848500e93f94bee8ad2e585
 | 
					Subproject commit e189f9942d54b6900f7140c1f4a41312cb6889eb
 | 
				
			||||||
		Loading…
	
		Reference in New Issue
	
	Block a user