diff options
| author | 2012-08-24 11:32:59 -0700 | |
|---|---|---|
| committer | 2012-08-24 11:33:00 -0700 | |
| commit | 34f863125865664af058ab4dff44ebec570e2234 (patch) | |
| tree | 520a3a74893506596e59c531d03f7d69e49e3c08 /services/java | |
| parent | 96702ad6d736fd2b145968843d5d83615b104a16 (diff) | |
| parent | 82f8521d386f3109147c477d04e5e90e5c715fa0 (diff) | |
Merge "Migrate legacy VPN arguments to system_server." into jb-mr1-dev
Diffstat (limited to 'services/java')
| -rw-r--r-- | services/java/com/android/server/ConnectivityService.java | 22 | ||||
| -rw-r--r-- | services/java/com/android/server/connectivity/Vpn.java | 135 |
2 files changed, 141 insertions, 16 deletions
diff --git a/services/java/com/android/server/ConnectivityService.java b/services/java/com/android/server/ConnectivityService.java index d0db0d2e0690..3c2ab163acbb 100644 --- a/services/java/com/android/server/ConnectivityService.java +++ b/services/java/com/android/server/ConnectivityService.java @@ -31,6 +31,8 @@ import static android.net.ConnectivityManager.isNetworkTypeValid; import static android.net.NetworkPolicyManager.RULE_ALLOW_ALL; import static android.net.NetworkPolicyManager.RULE_REJECT_METERED; +import android.app.NotificationManager; +import android.app.PendingIntent; import android.bluetooth.BluetoothTetheringDataTracker; import android.content.ContentResolver; import android.content.Context; @@ -78,6 +80,7 @@ import android.os.ServiceManager; import android.os.SystemClock; import android.os.SystemProperties; import android.provider.Settings; +import android.security.KeyStore; import android.text.TextUtils; import android.util.EventLog; import android.util.Slog; @@ -85,8 +88,10 @@ import android.util.SparseIntArray; import com.android.internal.net.LegacyVpnInfo; import com.android.internal.net.VpnConfig; +import com.android.internal.net.VpnProfile; import com.android.internal.telephony.Phone; import com.android.internal.telephony.PhoneConstants; +import com.android.internal.util.Preconditions; import com.android.server.am.BatteryStatsService; import com.android.server.connectivity.Tethering; import com.android.server.connectivity.Vpn; @@ -137,6 +142,8 @@ public class ConnectivityService extends IConnectivityManager.Stub { private Tethering mTethering; private boolean mTetheringConfigValid = false; + private final KeyStore mKeyStore; + private Vpn mVpn; private VpnCallback mVpnCallback = new VpnCallback(); @@ -371,6 +378,7 @@ public class ConnectivityService extends IConnectivityManager.Stub { mContext = checkNotNull(context, "missing Context"); mNetd = checkNotNull(netManager, "missing INetworkManagementService"); mPolicyManager = checkNotNull(policyManager, "missing INetworkPolicyManager"); + mKeyStore = KeyStore.getInstance(); try { mPolicyManager.registerListener(mPolicyListener); @@ -3124,14 +3132,16 @@ public class ConnectivityService extends IConnectivityManager.Stub { } /** - * Start legacy VPN and return an intent to VpnDialogs. This method is - * used by VpnSettings and not available in ConnectivityManager. - * Permissions are checked in Vpn class. - * @hide + * Start legacy VPN, controlling native daemons as needed. Creates a + * secondary thread to perform connection work, returning quickly. */ @Override - public void startLegacyVpn(VpnConfig config, String[] racoon, String[] mtpd) { - mVpn.startLegacyVpn(config, racoon, mtpd); + public void startLegacyVpn(VpnProfile profile) { + final LinkProperties egress = getActiveLinkProperties(); + if (egress == null) { + throw new IllegalStateException("Missing active network connection"); + } + mVpn.startLegacyVpn(profile, mKeyStore, egress); } /** diff --git a/services/java/com/android/server/connectivity/Vpn.java b/services/java/com/android/server/connectivity/Vpn.java index d490f240ab82..d96bd0dab52a 100644 --- a/services/java/com/android/server/connectivity/Vpn.java +++ b/services/java/com/android/server/connectivity/Vpn.java @@ -34,9 +34,11 @@ import android.graphics.drawable.Drawable; import android.net.BaseNetworkStateTracker; import android.net.ConnectivityManager; import android.net.INetworkManagementEventObserver; +import android.net.LinkProperties; import android.net.LocalSocket; import android.net.LocalSocketAddress; import android.net.NetworkInfo; +import android.net.RouteInfo; import android.net.NetworkInfo.DetailedState; import android.os.Binder; import android.os.FileUtils; @@ -48,11 +50,15 @@ import android.os.Process; import android.os.RemoteException; import android.os.SystemClock; import android.os.SystemService; +import android.security.Credentials; +import android.security.KeyStore; import android.util.Log; +import android.widget.Toast; import com.android.internal.R; import com.android.internal.net.LegacyVpnInfo; import com.android.internal.net.VpnConfig; +import com.android.internal.net.VpnProfile; import com.android.internal.util.Preconditions; import com.android.server.ConnectivityService.VpnCallback; import com.android.server.net.BaseNetworkObserver; @@ -60,6 +66,8 @@ import com.android.server.net.BaseNetworkObserver; import java.io.File; import java.io.InputStream; import java.io.OutputStream; +import java.net.Inet4Address; +import java.net.InetAddress; import java.nio.charset.Charsets; import java.util.Arrays; @@ -430,20 +438,127 @@ public class Vpn extends BaseNetworkStateTracker { private native int jniCheck(String interfaze); private native void jniProtect(int socket, String interfaze); + private static String findLegacyVpnGateway(LinkProperties prop) { + for (RouteInfo route : prop.getRoutes()) { + // Currently legacy VPN only works on IPv4. + if (route.isDefaultRoute() && route.getGateway() instanceof Inet4Address) { + return route.getGateway().getHostAddress(); + } + } + + throw new IllegalStateException("Unable to find suitable gateway"); + } + /** - * Start legacy VPN. This method stops the daemons and restart them - * if arguments are not null. Heavy things are offloaded to another - * thread, so callers will not be blocked for a long time. - * - * @param config The parameters to configure the network. - * @param racoon The arguments to be passed to racoon. - * @param mtpd The arguments to be passed to mtpd. + * Start legacy VPN, controlling native daemons as needed. Creates a + * secondary thread to perform connection work, returning quickly. */ - public synchronized void startLegacyVpn(VpnConfig config, String[] racoon, String[] mtpd) { - stopLegacyVpn(); + public void startLegacyVpn(VpnProfile profile, KeyStore keyStore, LinkProperties egress) { + if (keyStore.state() != KeyStore.State.UNLOCKED) { + throw new IllegalStateException("KeyStore isn't unlocked"); + } + + final String iface = egress.getInterfaceName(); + final String gateway = findLegacyVpnGateway(egress); + + // Load certificates. + String privateKey = ""; + String userCert = ""; + String caCert = ""; + String serverCert = ""; + if (!profile.ipsecUserCert.isEmpty()) { + privateKey = Credentials.USER_PRIVATE_KEY + profile.ipsecUserCert; + byte[] value = keyStore.get(Credentials.USER_CERTIFICATE + profile.ipsecUserCert); + userCert = (value == null) ? null : new String(value, Charsets.UTF_8); + } + if (!profile.ipsecCaCert.isEmpty()) { + byte[] value = keyStore.get(Credentials.CA_CERTIFICATE + profile.ipsecCaCert); + caCert = (value == null) ? null : new String(value, Charsets.UTF_8); + } + if (!profile.ipsecServerCert.isEmpty()) { + byte[] value = keyStore.get(Credentials.USER_CERTIFICATE + profile.ipsecServerCert); + serverCert = (value == null) ? null : new String(value, Charsets.UTF_8); + } + if (privateKey == null || userCert == null || caCert == null || serverCert == null) { + throw new IllegalStateException("Cannot load credentials"); + } + + // Prepare arguments for racoon. + String[] racoon = null; + switch (profile.type) { + case VpnProfile.TYPE_L2TP_IPSEC_PSK: + racoon = new String[] { + iface, profile.server, "udppsk", profile.ipsecIdentifier, + profile.ipsecSecret, "1701", + }; + break; + case VpnProfile.TYPE_L2TP_IPSEC_RSA: + racoon = new String[] { + iface, profile.server, "udprsa", privateKey, userCert, + caCert, serverCert, "1701", + }; + break; + case VpnProfile.TYPE_IPSEC_XAUTH_PSK: + racoon = new String[] { + iface, profile.server, "xauthpsk", profile.ipsecIdentifier, + profile.ipsecSecret, profile.username, profile.password, "", gateway, + }; + break; + case VpnProfile.TYPE_IPSEC_XAUTH_RSA: + racoon = new String[] { + iface, profile.server, "xauthrsa", privateKey, userCert, + caCert, serverCert, profile.username, profile.password, "", gateway, + }; + break; + case VpnProfile.TYPE_IPSEC_HYBRID_RSA: + racoon = new String[] { + iface, profile.server, "hybridrsa", + caCert, serverCert, profile.username, profile.password, "", gateway, + }; + break; + } + + // Prepare arguments for mtpd. + String[] mtpd = null; + switch (profile.type) { + case VpnProfile.TYPE_PPTP: + mtpd = new String[] { + iface, "pptp", profile.server, "1723", + "name", profile.username, "password", profile.password, + "linkname", "vpn", "refuse-eap", "nodefaultroute", + "usepeerdns", "idle", "1800", "mtu", "1400", "mru", "1400", + (profile.mppe ? "+mppe" : "nomppe"), + }; + break; + case VpnProfile.TYPE_L2TP_IPSEC_PSK: + case VpnProfile.TYPE_L2TP_IPSEC_RSA: + mtpd = new String[] { + iface, "l2tp", profile.server, "1701", profile.l2tpSecret, + "name", profile.username, "password", profile.password, + "linkname", "vpn", "refuse-eap", "nodefaultroute", + "usepeerdns", "idle", "1800", "mtu", "1400", "mru", "1400", + }; + break; + } - // TODO: move legacy definition to settings + VpnConfig config = new VpnConfig(); config.legacy = true; + config.user = profile.key; + config.interfaze = iface; + config.session = profile.name; + config.routes = profile.routes; + if (!profile.dnsServers.isEmpty()) { + config.dnsServers = Arrays.asList(profile.dnsServers.split(" +")); + } + if (!profile.searchDomains.isEmpty()) { + config.searchDomains = Arrays.asList(profile.searchDomains.split(" +")); + } + + startLegacyVpn(config, racoon, mtpd); + } + + private synchronized void startLegacyVpn(VpnConfig config, String[] racoon, String[] mtpd) { + stopLegacyVpn(); // Prepare for the new request. This also checks the caller. prepare(null, VpnConfig.LEGACY_VPN); |