Loading services/java/com/android/server/connectivity/Vpn.java +51 −26 Original line number Diff line number Diff line Loading @@ -352,6 +352,12 @@ public class Vpn extends BaseNetworkStateTracker { Binder.restoreCallingIdentity(token); } // Save the old config in case we need to go back. VpnConfig oldConfig = mConfig; String oldInterface = mInterface; Connection oldConnection = mConnection; SparseBooleanArray oldUsers = mVpnUsers; // Configure the interface. Abort if any of these steps fails. ParcelFileDescriptor tun = ParcelFileDescriptor.adoptFd(jniCreate(config.mtu)); try { Loading @@ -371,12 +377,7 @@ public class Vpn extends BaseNetworkStateTracker { new UserHandle(mUserId))) { throw new IllegalStateException("Cannot bind " + config.user); } if (mConnection != null) { mContext.unbindService(mConnection); } if (mInterface != null && !mInterface.equals(interfaze)) { jniReset(mInterface); } mConnection = connection; mInterface = interfaze; Loading @@ -385,50 +386,74 @@ public class Vpn extends BaseNetworkStateTracker { config.interfaze = mInterface; config.startTime = SystemClock.elapsedRealtime(); mConfig = config; // Set up forwarding and DNS rules. mVpnUsers = new SparseBooleanArray(); token = Binder.clearCallingIdentity(); try { mCallback.setMarkedForwarding(mInterface); mCallback.setRoutes(interfaze, config.routes); mCallback.setRoutes(mInterface, config.routes); mCallback.override(mInterface, config.dnsServers, config.searchDomains); addVpnUserLocked(mUserId); // If we are owner assign all Restricted Users to this VPN if (mUserId == UserHandle.USER_OWNER) { for (UserInfo user : mgr.getUsers()) { if (user.isRestricted()) { try { addVpnUserLocked(user.id); } catch (Exception e) { Log.wtf(TAG, "Failed to add user " + user.id + " to owner's VPN"); } } } } } finally { Binder.restoreCallingIdentity(token); } if (oldConnection != null) { mContext.unbindService(oldConnection); } if (oldInterface != null && !oldInterface.equals(interfaze)) { // Remove the old tun's user forwarding rules // The new tun's user rules have already been added so they will take over // as rules are deleted. This prevents data leakage as the rules are moved over. token = Binder.clearCallingIdentity(); try { final int size = oldUsers.size(); final boolean forwardDns = (oldConfig.dnsServers != null && oldConfig.dnsServers.size() != 0); for (int i = 0; i < size; i++) { int user = oldUsers.keyAt(i); mCallback.clearUserForwarding(oldInterface, user, forwardDns); } mCallback.clearMarkedForwarding(oldInterface); } finally { Binder.restoreCallingIdentity(token); } jniReset(oldInterface); } } catch (RuntimeException e) { updateState(DetailedState.FAILED, "establish"); IoUtils.closeQuietly(tun); // make sure marked forwarding is cleared if it was set token = Binder.clearCallingIdentity(); try { mCallback.clearMarkedForwarding(mInterface); } catch (Exception ingored) { // ignored } finally { Binder.restoreCallingIdentity(token); } // restore old state mConfig = oldConfig; mConnection = oldConnection; mVpnUsers = oldUsers; mInterface = oldInterface; throw e; } Log.i(TAG, "Established by " + config.user + " on " + mInterface); // If we are owner assign all Restricted Users to this VPN if (mUserId == UserHandle.USER_OWNER) { token = Binder.clearCallingIdentity(); try { for (UserInfo user : mgr.getUsers()) { if (user.isRestricted()) { try { addVpnUserLocked(user.id); } catch (Exception e) { Log.wtf(TAG, "Failed to add user " + user.id + " to owner's VPN"); } } } } finally { Binder.restoreCallingIdentity(token); } } // TODO: ensure that contract class eventually marks as connected updateState(DetailedState.AUTHENTICATING, "establish"); return tun; Loading Loading
services/java/com/android/server/connectivity/Vpn.java +51 −26 Original line number Diff line number Diff line Loading @@ -352,6 +352,12 @@ public class Vpn extends BaseNetworkStateTracker { Binder.restoreCallingIdentity(token); } // Save the old config in case we need to go back. VpnConfig oldConfig = mConfig; String oldInterface = mInterface; Connection oldConnection = mConnection; SparseBooleanArray oldUsers = mVpnUsers; // Configure the interface. Abort if any of these steps fails. ParcelFileDescriptor tun = ParcelFileDescriptor.adoptFd(jniCreate(config.mtu)); try { Loading @@ -371,12 +377,7 @@ public class Vpn extends BaseNetworkStateTracker { new UserHandle(mUserId))) { throw new IllegalStateException("Cannot bind " + config.user); } if (mConnection != null) { mContext.unbindService(mConnection); } if (mInterface != null && !mInterface.equals(interfaze)) { jniReset(mInterface); } mConnection = connection; mInterface = interfaze; Loading @@ -385,50 +386,74 @@ public class Vpn extends BaseNetworkStateTracker { config.interfaze = mInterface; config.startTime = SystemClock.elapsedRealtime(); mConfig = config; // Set up forwarding and DNS rules. mVpnUsers = new SparseBooleanArray(); token = Binder.clearCallingIdentity(); try { mCallback.setMarkedForwarding(mInterface); mCallback.setRoutes(interfaze, config.routes); mCallback.setRoutes(mInterface, config.routes); mCallback.override(mInterface, config.dnsServers, config.searchDomains); addVpnUserLocked(mUserId); // If we are owner assign all Restricted Users to this VPN if (mUserId == UserHandle.USER_OWNER) { for (UserInfo user : mgr.getUsers()) { if (user.isRestricted()) { try { addVpnUserLocked(user.id); } catch (Exception e) { Log.wtf(TAG, "Failed to add user " + user.id + " to owner's VPN"); } } } } } finally { Binder.restoreCallingIdentity(token); } if (oldConnection != null) { mContext.unbindService(oldConnection); } if (oldInterface != null && !oldInterface.equals(interfaze)) { // Remove the old tun's user forwarding rules // The new tun's user rules have already been added so they will take over // as rules are deleted. This prevents data leakage as the rules are moved over. token = Binder.clearCallingIdentity(); try { final int size = oldUsers.size(); final boolean forwardDns = (oldConfig.dnsServers != null && oldConfig.dnsServers.size() != 0); for (int i = 0; i < size; i++) { int user = oldUsers.keyAt(i); mCallback.clearUserForwarding(oldInterface, user, forwardDns); } mCallback.clearMarkedForwarding(oldInterface); } finally { Binder.restoreCallingIdentity(token); } jniReset(oldInterface); } } catch (RuntimeException e) { updateState(DetailedState.FAILED, "establish"); IoUtils.closeQuietly(tun); // make sure marked forwarding is cleared if it was set token = Binder.clearCallingIdentity(); try { mCallback.clearMarkedForwarding(mInterface); } catch (Exception ingored) { // ignored } finally { Binder.restoreCallingIdentity(token); } // restore old state mConfig = oldConfig; mConnection = oldConnection; mVpnUsers = oldUsers; mInterface = oldInterface; throw e; } Log.i(TAG, "Established by " + config.user + " on " + mInterface); // If we are owner assign all Restricted Users to this VPN if (mUserId == UserHandle.USER_OWNER) { token = Binder.clearCallingIdentity(); try { for (UserInfo user : mgr.getUsers()) { if (user.isRestricted()) { try { addVpnUserLocked(user.id); } catch (Exception e) { Log.wtf(TAG, "Failed to add user " + user.id + " to owner's VPN"); } } } } finally { Binder.restoreCallingIdentity(token); } } // TODO: ensure that contract class eventually marks as connected updateState(DetailedState.AUTHENTICATING, "establish"); return tun; Loading