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;
}
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);
}
}
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);
}
}
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);
}
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);
}
Aggregations