Search in sources :

Example 16 with VpnConfig

use of com.android.internal.net.VpnConfig in project android_frameworks_base by ResurrectionRemix.

the class SecurityControllerImpl method updateState.

private void updateState() {
    // Find all users with an active VPN
    SparseArray<VpnConfig> vpns = new SparseArray<>();
    try {
        for (UserInfo user : mUserManager.getUsers()) {
            VpnConfig cfg = mConnectivityManagerService.getVpnConfig(user.id);
            if (cfg == null) {
                continue;
            } else if (cfg.legacy) {
                // Legacy VPNs should do nothing if the network is disconnected. Third-party
                // VPN warnings need to continue as traffic can still go to the app.
                LegacyVpnInfo legacyVpn = mConnectivityManagerService.getLegacyVpnInfo(user.id);
                if (legacyVpn == null || legacyVpn.state != LegacyVpnInfo.STATE_CONNECTED) {
                    continue;
                }
            }
            vpns.put(user.id, cfg);
        }
    } catch (RemoteException rme) {
        // Roll back to previous state
        Log.e(TAG, "Unable to list active VPNs", rme);
        return;
    }
    mCurrentVpns = vpns;
}
Also used : SparseArray(android.util.SparseArray) VpnConfig(com.android.internal.net.VpnConfig) LegacyVpnInfo(com.android.internal.net.LegacyVpnInfo) UserInfo(android.content.pm.UserInfo) RemoteException(android.os.RemoteException)

Example 17 with VpnConfig

use of com.android.internal.net.VpnConfig in project android_frameworks_base by ResurrectionRemix.

the class LockdownVpnTracker method handleStateChangedLocked.

/**
     * Watch for state changes to both active egress network, kicking off a VPN
     * connection when ready, or setting firewall rules once VPN is connected.
     */
private void handleStateChangedLocked() {
    final NetworkInfo egressInfo = mConnService.getActiveNetworkInfoUnfiltered();
    final LinkProperties egressProp = mConnService.getActiveLinkProperties();
    final NetworkInfo vpnInfo = mVpn.getNetworkInfo();
    final VpnConfig vpnConfig = mVpn.getLegacyVpnConfig();
    // Restart VPN when egress network disconnected or changed
    final boolean egressDisconnected = egressInfo == null || State.DISCONNECTED.equals(egressInfo.getState());
    final boolean egressChanged = egressProp == null || !TextUtils.equals(mAcceptedEgressIface, egressProp.getInterfaceName());
    final String egressTypeName = (egressInfo == null) ? null : ConnectivityManager.getNetworkTypeName(egressInfo.getType());
    final String egressIface = (egressProp == null) ? null : egressProp.getInterfaceName();
    Slog.d(TAG, "handleStateChanged: egress=" + egressTypeName + " " + mAcceptedEgressIface + "->" + egressIface);
    if (egressDisconnected || egressChanged) {
        clearSourceRulesLocked();
        mAcceptedEgressIface = null;
        mVpn.stopLegacyVpnPrivileged();
    }
    if (egressDisconnected) {
        hideNotification();
        return;
    }
    final int egressType = egressInfo.getType();
    if (vpnInfo.getDetailedState() == DetailedState.FAILED) {
        EventLogTags.writeLockdownVpnError(egressType);
    }
    if (mErrorCount > MAX_ERROR_COUNT) {
        showNotification(R.string.vpn_lockdown_error, R.drawable.vpn_disconnected);
    } else if (egressInfo.isConnected() && !vpnInfo.isConnectedOrConnecting()) {
        if (mProfile.isValidLockdownProfile()) {
            Slog.d(TAG, "Active network connected; starting VPN");
            EventLogTags.writeLockdownVpnConnecting(egressType);
            showNotification(R.string.vpn_lockdown_connecting, R.drawable.vpn_disconnected);
            mAcceptedEgressIface = egressProp.getInterfaceName();
            try {
                // Use the privileged method because Lockdown VPN is initiated by the system, so
                // no additional permission checks are necessary.
                mVpn.startLegacyVpnPrivileged(mProfile, KeyStore.getInstance(), egressProp);
            } catch (IllegalStateException e) {
                mAcceptedEgressIface = null;
                Slog.e(TAG, "Failed to start VPN", e);
                showNotification(R.string.vpn_lockdown_error, R.drawable.vpn_disconnected);
            }
        } else {
            Slog.e(TAG, "Invalid VPN profile; requires IP-based server and DNS");
            showNotification(R.string.vpn_lockdown_error, R.drawable.vpn_disconnected);
        }
    } else if (vpnInfo.isConnected() && vpnConfig != null) {
        final String iface = vpnConfig.interfaze;
        final List<LinkAddress> sourceAddrs = vpnConfig.addresses;
        if (TextUtils.equals(iface, mAcceptedIface) && sourceAddrs.equals(mAcceptedSourceAddr)) {
            return;
        }
        Slog.d(TAG, "VPN connected using iface=" + iface + ", sourceAddr=" + sourceAddrs.toString());
        EventLogTags.writeLockdownVpnConnected(egressType);
        showNotification(R.string.vpn_lockdown_connected, R.drawable.vpn_connected);
        try {
            clearSourceRulesLocked();
            mNetService.setFirewallInterfaceRule(iface, true);
            for (LinkAddress addr : sourceAddrs) {
                setFirewallEgressSourceRule(addr, true);
            }
            mNetService.setFirewallUidRule(FIREWALL_CHAIN_NONE, ROOT_UID, FIREWALL_RULE_ALLOW);
            mNetService.setFirewallUidRule(FIREWALL_CHAIN_NONE, Os.getuid(), FIREWALL_RULE_ALLOW);
            mErrorCount = 0;
            mAcceptedIface = iface;
            mAcceptedSourceAddr = sourceAddrs;
        } catch (RemoteException e) {
            throw new RuntimeException("Problem setting firewall rules", e);
        }
        final NetworkInfo clone = new NetworkInfo(egressInfo);
        augmentNetworkInfo(clone);
        mConnService.sendConnectedBroadcast(clone);
    }
}
Also used : LinkAddress(android.net.LinkAddress) VpnConfig(com.android.internal.net.VpnConfig) NetworkInfo(android.net.NetworkInfo) RemoteException(android.os.RemoteException) LinkProperties(android.net.LinkProperties)

Example 18 with VpnConfig

use of com.android.internal.net.VpnConfig in project platform_frameworks_base by android.

the class LockdownVpnTracker method handleStateChangedLocked.

/**
     * Watch for state changes to both active egress network, kicking off a VPN
     * connection when ready, or setting firewall rules once VPN is connected.
     */
private void handleStateChangedLocked() {
    final NetworkInfo egressInfo = mConnService.getActiveNetworkInfoUnfiltered();
    final LinkProperties egressProp = mConnService.getActiveLinkProperties();
    final NetworkInfo vpnInfo = mVpn.getNetworkInfo();
    final VpnConfig vpnConfig = mVpn.getLegacyVpnConfig();
    // Restart VPN when egress network disconnected or changed
    final boolean egressDisconnected = egressInfo == null || State.DISCONNECTED.equals(egressInfo.getState());
    final boolean egressChanged = egressProp == null || !TextUtils.equals(mAcceptedEgressIface, egressProp.getInterfaceName());
    final String egressTypeName = (egressInfo == null) ? null : ConnectivityManager.getNetworkTypeName(egressInfo.getType());
    final String egressIface = (egressProp == null) ? null : egressProp.getInterfaceName();
    Slog.d(TAG, "handleStateChanged: egress=" + egressTypeName + " " + mAcceptedEgressIface + "->" + egressIface);
    if (egressDisconnected || egressChanged) {
        clearSourceRulesLocked();
        mAcceptedEgressIface = null;
        mVpn.stopLegacyVpnPrivileged();
    }
    if (egressDisconnected) {
        hideNotification();
        return;
    }
    final int egressType = egressInfo.getType();
    if (vpnInfo.getDetailedState() == DetailedState.FAILED) {
        EventLogTags.writeLockdownVpnError(egressType);
    }
    if (mErrorCount > MAX_ERROR_COUNT) {
        showNotification(R.string.vpn_lockdown_error, R.drawable.vpn_disconnected);
    } else if (egressInfo.isConnected() && !vpnInfo.isConnectedOrConnecting()) {
        if (mProfile.isValidLockdownProfile()) {
            Slog.d(TAG, "Active network connected; starting VPN");
            EventLogTags.writeLockdownVpnConnecting(egressType);
            showNotification(R.string.vpn_lockdown_connecting, R.drawable.vpn_disconnected);
            mAcceptedEgressIface = egressProp.getInterfaceName();
            try {
                // Use the privileged method because Lockdown VPN is initiated by the system, so
                // no additional permission checks are necessary.
                mVpn.startLegacyVpnPrivileged(mProfile, KeyStore.getInstance(), egressProp);
            } catch (IllegalStateException e) {
                mAcceptedEgressIface = null;
                Slog.e(TAG, "Failed to start VPN", e);
                showNotification(R.string.vpn_lockdown_error, R.drawable.vpn_disconnected);
            }
        } else {
            Slog.e(TAG, "Invalid VPN profile; requires IP-based server and DNS");
            showNotification(R.string.vpn_lockdown_error, R.drawable.vpn_disconnected);
        }
    } else if (vpnInfo.isConnected() && vpnConfig != null) {
        final String iface = vpnConfig.interfaze;
        final List<LinkAddress> sourceAddrs = vpnConfig.addresses;
        if (TextUtils.equals(iface, mAcceptedIface) && sourceAddrs.equals(mAcceptedSourceAddr)) {
            return;
        }
        Slog.d(TAG, "VPN connected using iface=" + iface + ", sourceAddr=" + sourceAddrs.toString());
        EventLogTags.writeLockdownVpnConnected(egressType);
        showNotification(R.string.vpn_lockdown_connected, R.drawable.vpn_connected);
        try {
            clearSourceRulesLocked();
            mNetService.setFirewallInterfaceRule(iface, true);
            for (LinkAddress addr : sourceAddrs) {
                setFirewallEgressSourceRule(addr, true);
            }
            mNetService.setFirewallUidRule(FIREWALL_CHAIN_NONE, ROOT_UID, FIREWALL_RULE_ALLOW);
            mNetService.setFirewallUidRule(FIREWALL_CHAIN_NONE, Os.getuid(), FIREWALL_RULE_ALLOW);
            mErrorCount = 0;
            mAcceptedIface = iface;
            mAcceptedSourceAddr = sourceAddrs;
        } catch (RemoteException e) {
            throw new RuntimeException("Problem setting firewall rules", e);
        }
        final NetworkInfo clone = new NetworkInfo(egressInfo);
        augmentNetworkInfo(clone);
        mConnService.sendConnectedBroadcast(clone);
    }
}
Also used : LinkAddress(android.net.LinkAddress) VpnConfig(com.android.internal.net.VpnConfig) NetworkInfo(android.net.NetworkInfo) RemoteException(android.os.RemoteException) LinkProperties(android.net.LinkProperties)

Example 19 with VpnConfig

use of com.android.internal.net.VpnConfig in project platform_frameworks_base by android.

the class Vpn method startLegacyVpnPrivileged.

/**
     * Like {@link #startLegacyVpn(VpnProfile, KeyStore, LinkProperties)}, but does not check
     * permissions under the assumption that the caller is the system.
     *
     * Callers are responsible for checking permissions if needed.
     */
public void startLegacyVpnPrivileged(VpnProfile profile, KeyStore keyStore, LinkProperties egress) {
    UserManager mgr = UserManager.get(mContext);
    UserInfo user = mgr.getUserInfo(mUserHandle);
    if (user.isRestricted() || mgr.hasUserRestriction(UserManager.DISALLOW_CONFIG_VPN, new UserHandle(mUserHandle))) {
        throw new SecurityException("Restricted users cannot establish VPNs");
    }
    final RouteInfo ipv4DefaultRoute = findIPv4DefaultRoute(egress);
    final String gateway = ipv4DefaultRoute.getGateway().getHostAddress();
    final String iface = ipv4DefaultRoute.getInterface();
    // 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, StandardCharsets.UTF_8);
    }
    if (!profile.ipsecCaCert.isEmpty()) {
        byte[] value = keyStore.get(Credentials.CA_CERTIFICATE + profile.ipsecCaCert);
        caCert = (value == null) ? null : new String(value, StandardCharsets.UTF_8);
    }
    if (!profile.ipsecServerCert.isEmpty()) {
        byte[] value = keyStore.get(Credentials.USER_CERTIFICATE + profile.ipsecServerCert);
        serverCert = (value == null) ? null : new String(value, StandardCharsets.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;
    }
    VpnConfig config = new VpnConfig();
    config.legacy = true;
    config.user = profile.key;
    config.interfaze = iface;
    config.session = profile.name;
    config.addLegacyRoutes(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);
}
Also used : VpnConfig(com.android.internal.net.VpnConfig) UserManager(android.os.UserManager) UserHandle(android.os.UserHandle) UserInfo(android.content.pm.UserInfo) RouteInfo(android.net.RouteInfo)

Example 20 with VpnConfig

use of com.android.internal.net.VpnConfig in project android_frameworks_base by ParanoidAndroid.

the class Vpn method startLegacyVpn.

/**
     * Start legacy VPN, controlling native daemons as needed. Creates a
     * secondary thread to perform connection work, returning quickly.
     */
public void startLegacyVpn(VpnProfile profile, KeyStore keyStore, LinkProperties egress) {
    enforceControlPermission();
    if (!keyStore.isUnlocked()) {
        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;
    }
    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);
}
Also used : VpnConfig(com.android.internal.net.VpnConfig)

Aggregations

VpnConfig (com.android.internal.net.VpnConfig)32 RemoteException (android.os.RemoteException)16 UserInfo (android.content.pm.UserInfo)15 LinkAddress (android.net.LinkAddress)10 UserHandle (android.os.UserHandle)10 UserManager (android.os.UserManager)10 LinkProperties (android.net.LinkProperties)6 NetworkInfo (android.net.NetworkInfo)6 PendingIntent (android.app.PendingIntent)5 Intent (android.content.Intent)5 ServiceConnection (android.content.ServiceConnection)5 ResolveInfo (android.content.pm.ResolveInfo)5 NetworkAgent (android.net.NetworkAgent)5 NetworkPolicyManager.uidRulesToString (android.net.NetworkPolicyManager.uidRulesToString)5 RouteInfo (android.net.RouteInfo)5 UidRange (android.net.UidRange)5 ParcelFileDescriptor (android.os.ParcelFileDescriptor)5 SparseArray (android.util.SparseArray)5 LegacyVpnInfo (com.android.internal.net.LegacyVpnInfo)5 IOException (java.io.IOException)5