From: Tobias Brunner Date: Wed, 21 Jun 2017 15:21:30 +0000 (+0200) Subject: android: Exclude configured subnets from the VPN X-Git-Tag: 5.6.0dr1~24^2~22 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=72b7c289addad31007eefd4a14643659b4c283af;p=thirdparty%2Fstrongswan.git android: Exclude configured subnets from the VPN --- diff --git a/src/frontends/android/app/src/main/java/org/strongswan/android/logic/CharonVpnService.java b/src/frontends/android/app/src/main/java/org/strongswan/android/logic/CharonVpnService.java index 6256392a08..34ba2534e5 100644 --- a/src/frontends/android/app/src/main/java/org/strongswan/android/logic/CharonVpnService.java +++ b/src/frontends/android/app/src/main/java/org/strongswan/android/logic/CharonVpnService.java @@ -47,6 +47,8 @@ import org.strongswan.android.logic.VpnStateService.State; import org.strongswan.android.logic.imc.ImcState; import org.strongswan.android.logic.imc.RemediationInstruction; import org.strongswan.android.ui.MainActivity; +import org.strongswan.android.utils.IPRange; +import org.strongswan.android.utils.IPRangeSet; import org.strongswan.android.utils.SettingsWriter; import java.io.File; @@ -238,7 +240,8 @@ public class CharonVpnService extends VpnService implements Runnable, VpnStateSe mIsDisconnecting = false; addNotification(); - BuilderAdapter builder = new BuilderAdapter(mCurrentProfile.getName(), mCurrentProfile.getSplitTunneling()); + BuilderAdapter builder = new BuilderAdapter(mCurrentProfile.getName(), mCurrentProfile.getExcludedSubnets(), + mCurrentProfile.getSplitTunneling()); if (initializeCharon(builder, mLogFile, mCurrentProfile.getVpnType().has(VpnTypeFeature.BYOD))) { Log.i(TAG, "charon started"); @@ -649,17 +652,19 @@ public class CharonVpnService extends VpnService implements Runnable, VpnStateSe public class BuilderAdapter { private final String mName; + private final String mExcludedSubnets; private final Integer mSplitTunneling; private VpnService.Builder mBuilder; private BuilderCache mCache; private BuilderCache mEstablishedCache; - public BuilderAdapter(String name, Integer splitTunneling) + public BuilderAdapter(String name, String excludedSubnets, Integer splitTunneling) { mName = name; + mExcludedSubnets = excludedSubnets; mSplitTunneling = splitTunneling; mBuilder = createBuilder(name); - mCache = new BuilderCache(mSplitTunneling); + mCache = new BuilderCache(mExcludedSubnets, mSplitTunneling); } private VpnService.Builder createBuilder(String name) @@ -764,7 +769,7 @@ public class CharonVpnService extends VpnService implements Runnable, VpnStateSe * builder anymore, but we might need another when reestablishing */ mBuilder = createBuilder(mName); mEstablishedCache = mCache; - mCache = new BuilderCache(mSplitTunneling); + mCache = new BuilderCache(mExcludedSubnets, mSplitTunneling); return fd.detachFd(); } @@ -801,22 +806,31 @@ public class CharonVpnService extends VpnService implements Runnable, VpnStateSe */ public class BuilderCache { - private final List mAddresses = new ArrayList(); - private final List mRoutesIPv4 = new ArrayList(); - private final List mRoutesIPv6 = new ArrayList(); + private final List mAddresses = new ArrayList<>(); + private final List mRoutesIPv4 = new ArrayList<>(); + private final List mRoutesIPv6 = new ArrayList<>(); + private final IPRangeSet mExcludedSubnets; private final int mSplitTunneling; private int mMtu; private boolean mIPv4Seen, mIPv6Seen; - public BuilderCache(Integer splitTunneling) + public BuilderCache(String excludedSubnets, Integer splitTunneling) { + mExcludedSubnets = IPRangeSet.fromString(excludedSubnets); mSplitTunneling = splitTunneling != null ? splitTunneling : 0; } public void addAddress(String address, int prefixLength) { - mAddresses.add(new PrefixedAddress(address, prefixLength)); - recordAddressFamily(address); + try + { + mAddresses.add(new IPRange(address, prefixLength)); + recordAddressFamily(address); + } + catch (UnknownHostException ex) + { + ex.printStackTrace(); + } } public void addRoute(String address, int prefixLength) @@ -825,11 +839,11 @@ public class CharonVpnService extends VpnService implements Runnable, VpnStateSe { if (isIPv6(address)) { - mRoutesIPv6.add(new PrefixedAddress(address, prefixLength)); + mRoutesIPv6.add(new IPRange(address, prefixLength)); } else { - mRoutesIPv4.add(new PrefixedAddress(address, prefixLength)); + mRoutesIPv4.add(new IPRange(address, prefixLength)); } } catch (UnknownHostException ex) @@ -865,19 +879,22 @@ public class CharonVpnService extends VpnService implements Runnable, VpnStateSe @TargetApi(Build.VERSION_CODES.LOLLIPOP) public void applyData(VpnService.Builder builder) { - for (PrefixedAddress address : mAddresses) + for (IPRange address : mAddresses) { - builder.addAddress(address.mAddress, address.mPrefix); + builder.addAddress(address.getFrom(), address.getPrefix()); } /* add routes depending on whether split tunneling is allowed or not, * that is, whether we have to handle and block non-VPN traffic */ if ((mSplitTunneling & VpnProfile.SPLIT_TUNNELING_BLOCK_IPV4) == 0) { if (mIPv4Seen) - { /* split tunneling is used depending on the routes */ - for (PrefixedAddress route : mRoutesIPv4) + { /* split tunneling is used depending on the routes and configuration */ + IPRangeSet ranges = new IPRangeSet(); + ranges.addAll(mRoutesIPv4); + ranges.remove(mExcludedSubnets); + for (IPRange subnet : ranges.subnets()) { - builder.addRoute(route.mAddress, route.mPrefix); + builder.addRoute(subnet.getFrom(), subnet.getPrefix()); } } else if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) @@ -895,9 +912,12 @@ public class CharonVpnService extends VpnService implements Runnable, VpnStateSe { if (mIPv6Seen) { - for (PrefixedAddress route : mRoutesIPv6) + IPRangeSet ranges = new IPRangeSet(); + ranges.addAll(mRoutesIPv6); + ranges.remove(mExcludedSubnets); + for (IPRange subnet : ranges.subnets()) { - builder.addRoute(route.mAddress, route.mPrefix); + builder.addRoute(subnet.getFrom(), subnet.getPrefix()); } } else if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) @@ -925,18 +945,6 @@ public class CharonVpnService extends VpnService implements Runnable, VpnStateSe } return false; } - - private class PrefixedAddress - { - public String mAddress; - public int mPrefix; - - public PrefixedAddress(String address, int prefix) - { - this.mAddress = address; - this.mPrefix = prefix; - } - } } /**