1 /*
2  * Copyright (C) 2016 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 package com.android.settings.vpn2;
17 
18 import android.content.Context;
19 import android.net.ConnectivityManager;
20 import android.net.IConnectivityManager;
21 import android.os.RemoteException;
22 import android.os.ServiceManager;
23 import android.provider.Settings;
24 import android.security.Credentials;
25 import android.security.KeyStore;
26 import android.util.Log;
27 
28 import com.android.internal.net.LegacyVpnInfo;
29 import com.android.internal.net.VpnConfig;
30 
31 /**
32  * Utility functions for vpn.
33  *
34  * Keystore methods should only be called in system user
35  */
36 public class VpnUtils {
37 
38     private static final String TAG = "VpnUtils";
39 
getLockdownVpn()40     public static String getLockdownVpn() {
41         final byte[] value = KeyStore.getInstance().get(Credentials.LOCKDOWN_VPN);
42         return value == null ? null : new String(value);
43     }
44 
clearLockdownVpn(Context context)45     public static void clearLockdownVpn(Context context) {
46         KeyStore.getInstance().delete(Credentials.LOCKDOWN_VPN);
47         // Always notify ConnectivityManager after keystore update
48         getConnectivityManager(context).updateLockdownVpn();
49     }
50 
setLockdownVpn(Context context, String lockdownKey)51     public static void setLockdownVpn(Context context, String lockdownKey) {
52         KeyStore.getInstance().put(Credentials.LOCKDOWN_VPN, lockdownKey.getBytes(),
53                 KeyStore.UID_SELF, /* flags */ 0);
54         // Always notify ConnectivityManager after keystore update
55         getConnectivityManager(context).updateLockdownVpn();
56     }
57 
isVpnLockdown(String key)58     public static boolean isVpnLockdown(String key) {
59         return key.equals(getLockdownVpn());
60     }
61 
isAnyLockdownActive(Context context)62     public static boolean isAnyLockdownActive(Context context) {
63         final int userId = context.getUserId();
64         if (getLockdownVpn() != null) {
65             return true;
66         }
67         return getConnectivityManager(context).getAlwaysOnVpnPackageForUser(userId) != null
68                 && Settings.Secure.getIntForUser(context.getContentResolver(),
69                         Settings.Secure.ALWAYS_ON_VPN_LOCKDOWN, /* default */ 0, userId) != 0;
70     }
71 
isVpnActive(Context context)72     public static boolean isVpnActive(Context context) throws RemoteException {
73         return getIConnectivityManager().getVpnConfig(context.getUserId()) != null;
74     }
75 
getConnectedPackage(IConnectivityManager service, final int userId)76     public static String getConnectedPackage(IConnectivityManager service, final int userId)
77             throws RemoteException {
78         final VpnConfig config = service.getVpnConfig(userId);
79         return config != null ? config.user : null;
80     }
81 
getConnectivityManager(Context context)82     private static ConnectivityManager getConnectivityManager(Context context) {
83         return context.getSystemService(ConnectivityManager.class);
84     }
85 
getIConnectivityManager()86     private static IConnectivityManager getIConnectivityManager() {
87         return IConnectivityManager.Stub.asInterface(
88                 ServiceManager.getService(Context.CONNECTIVITY_SERVICE));
89     }
90 
isAlwaysOnVpnSet(ConnectivityManagerWrapper cm, final int userId)91     public static boolean isAlwaysOnVpnSet(ConnectivityManagerWrapper cm, final int userId) {
92         return cm.getAlwaysOnVpnPackageForUser(userId) != null;
93     }
94 
disconnectLegacyVpn(Context context)95     public static boolean disconnectLegacyVpn(Context context) {
96         try {
97             int userId = context.getUserId();
98             IConnectivityManager connectivityService = getIConnectivityManager();
99             LegacyVpnInfo currentLegacyVpn = connectivityService.getLegacyVpnInfo(userId);
100             if (currentLegacyVpn != null) {
101                 clearLockdownVpn(context);
102                 connectivityService.prepareVpn(null, VpnConfig.LEGACY_VPN, userId);
103                 return true;
104             }
105         } catch (RemoteException e) {
106             Log.e(TAG, "Legacy VPN could not be disconnected", e);
107         }
108         return false;
109     }
110 }
111