Merge "Don't enforce control permission when preparing consented VPN." into lmp-mr1-dev

This commit is contained in:
Jeff Davidson
2014-11-24 21:19:55 +00:00
committed by Android (Google) Code Review
2 changed files with 50 additions and 55 deletions

View File

@@ -2776,7 +2776,7 @@ public class ConnectivityService extends IConnectivityManager.Stub
} }
/** /**
* Prepare for a VPN application. This method is used by system-privileged apps. * Prepare for a VPN application.
* Permissions are checked in Vpn class. * Permissions are checked in Vpn class.
* @hide * @hide
*/ */

View File

@@ -216,20 +216,11 @@ public class Vpn {
* @return true if the operation is succeeded. * @return true if the operation is succeeded.
*/ */
public synchronized boolean prepare(String oldPackage, String newPackage) { public synchronized boolean prepare(String oldPackage, String newPackage) {
// Return false if the package does not match.
if (oldPackage != null && getAppUid(oldPackage, mUserHandle) != mOwnerUID) { if (oldPackage != null && getAppUid(oldPackage, mUserHandle) != mOwnerUID) {
// The package doesn't match. If this VPN was not previously authorized, return false // The package doesn't match. We return false (to obtain user consent) unless the user
// to force user authorization. Otherwise, revoke the VPN anyway. // has already consented to that VPN package.
if (!oldPackage.equals(VpnConfig.LEGACY_VPN) && isVpnUserPreConsented(oldPackage)) { if (!oldPackage.equals(VpnConfig.LEGACY_VPN) && isVpnUserPreConsented(oldPackage)) {
long token = Binder.clearCallingIdentity(); prepareInternal(oldPackage);
try {
// This looks bizarre, but it is what ConfirmDialog in VpnDialogs is doing when
// the user clicks through to allow the VPN to consent. So we are emulating the
// action of the dialog without actually showing it.
prepare(null, oldPackage);
} finally {
Binder.restoreCallingIdentity(token);
}
return true; return true;
} }
return false; return false;
@@ -244,54 +235,58 @@ public class Vpn {
// Check if the caller is authorized. // Check if the caller is authorized.
enforceControlPermission(); enforceControlPermission();
// Reset the interface. prepareInternal(newPackage);
if (mInterface != null) { return true;
mStatusIntent = null; }
agentDisconnect();
jniReset(mInterface);
mInterface = null;
mVpnUsers = null;
}
// Revoke the connection or stop LegacyVpnRunner.
if (mConnection != null) {
try {
mConnection.mService.transact(IBinder.LAST_CALL_TRANSACTION,
Parcel.obtain(), null, IBinder.FLAG_ONEWAY);
} catch (Exception e) {
// ignore
}
mContext.unbindService(mConnection);
mConnection = null;
} else if (mLegacyVpnRunner != null) {
mLegacyVpnRunner.exit();
mLegacyVpnRunner = null;
}
/** Prepare the VPN for the given package. Does not perform permission checks. */
private void prepareInternal(String newPackage) {
long token = Binder.clearCallingIdentity(); long token = Binder.clearCallingIdentity();
try { try {
mNetd.denyProtect(mOwnerUID); // Reset the interface.
} catch (Exception e) { if (mInterface != null) {
Log.wtf(TAG, "Failed to disallow UID " + mOwnerUID + " to call protect() " + e); mStatusIntent = null;
agentDisconnect();
jniReset(mInterface);
mInterface = null;
mVpnUsers = null;
}
// Revoke the connection or stop LegacyVpnRunner.
if (mConnection != null) {
try {
mConnection.mService.transact(IBinder.LAST_CALL_TRANSACTION,
Parcel.obtain(), null, IBinder.FLAG_ONEWAY);
} catch (Exception e) {
// ignore
}
mContext.unbindService(mConnection);
mConnection = null;
} else if (mLegacyVpnRunner != null) {
mLegacyVpnRunner.exit();
mLegacyVpnRunner = null;
}
try {
mNetd.denyProtect(mOwnerUID);
} catch (Exception e) {
Log.wtf(TAG, "Failed to disallow UID " + mOwnerUID + " to call protect() " + e);
}
Log.i(TAG, "Switched from " + mPackage + " to " + newPackage);
mPackage = newPackage;
mOwnerUID = getAppUid(newPackage, mUserHandle);
try {
mNetd.allowProtect(mOwnerUID);
} catch (Exception e) {
Log.wtf(TAG, "Failed to allow UID " + mOwnerUID + " to call protect() " + e);
}
mConfig = null;
updateState(DetailedState.IDLE, "prepare");
} finally { } finally {
Binder.restoreCallingIdentity(token); Binder.restoreCallingIdentity(token);
} }
Log.i(TAG, "Switched from " + mPackage + " to " + newPackage);
mPackage = newPackage;
mOwnerUID = getAppUid(newPackage, mUserHandle);
token = Binder.clearCallingIdentity();
try {
mNetd.allowProtect(mOwnerUID);
} catch (Exception e) {
Log.wtf(TAG, "Failed to allow UID " + mOwnerUID + " to call protect() " + e);
} finally {
Binder.restoreCallingIdentity(token);
}
mConfig = null;
updateState(DetailedState.IDLE, "prepare");
return true;
} }
/** /**