1340bda7154194d64a719fb5c86a702a4e5773be0Xia Wang/*
2340bda7154194d64a719fb5c86a702a4e5773be0Xia Wang * Copyright (C) 2013 The Android Open Source Project
3340bda7154194d64a719fb5c86a702a4e5773be0Xia Wang *
4340bda7154194d64a719fb5c86a702a4e5773be0Xia Wang * Licensed under the Apache License, Version 2.0 (the "License");
5340bda7154194d64a719fb5c86a702a4e5773be0Xia Wang * you may not use this file except in compliance with the License.
6340bda7154194d64a719fb5c86a702a4e5773be0Xia Wang * You may obtain a copy of the License at
7340bda7154194d64a719fb5c86a702a4e5773be0Xia Wang *
8340bda7154194d64a719fb5c86a702a4e5773be0Xia Wang *      http://www.apache.org/licenses/LICENSE-2.0
9340bda7154194d64a719fb5c86a702a4e5773be0Xia Wang *
10340bda7154194d64a719fb5c86a702a4e5773be0Xia Wang * Unless required by applicable law or agreed to in writing, software
11340bda7154194d64a719fb5c86a702a4e5773be0Xia Wang * distributed under the License is distributed on an "AS IS" BASIS,
12340bda7154194d64a719fb5c86a702a4e5773be0Xia Wang * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13340bda7154194d64a719fb5c86a702a4e5773be0Xia Wang * See the License for the specific language governing permissions and
14340bda7154194d64a719fb5c86a702a4e5773be0Xia Wang * limitations under the License.
15340bda7154194d64a719fb5c86a702a4e5773be0Xia Wang */
16340bda7154194d64a719fb5c86a702a4e5773be0Xia Wang
17340bda7154194d64a719fb5c86a702a4e5773be0Xia Wangpackage com.android.settings.vpn2;
18340bda7154194d64a719fb5c86a702a4e5773be0Xia Wang
19340bda7154194d64a719fb5c86a702a4e5773be0Xia Wangimport android.content.Context;
20340bda7154194d64a719fb5c86a702a4e5773be0Xia Wangimport android.net.IConnectivityManager;
21340bda7154194d64a719fb5c86a702a4e5773be0Xia Wangimport android.os.Bundle;
22340bda7154194d64a719fb5c86a702a4e5773be0Xia Wangimport android.os.Environment;
23340bda7154194d64a719fb5c86a702a4e5773be0Xia Wangimport android.os.RemoteException;
24340bda7154194d64a719fb5c86a702a4e5773be0Xia Wangimport android.os.ServiceManager;
2501b35bcae307907bd8aaaa9cf23fa50f70e5f491Robin Leeimport android.os.UserHandle;
26340bda7154194d64a719fb5c86a702a4e5773be0Xia Wangimport android.security.Credentials;
27340bda7154194d64a719fb5c86a702a4e5773be0Xia Wangimport android.security.KeyStore;
28b009023c76227b6c984652683be7d054033eb935Alex Klyubinimport android.security.NetworkSecurityPolicy;
29340bda7154194d64a719fb5c86a702a4e5773be0Xia Wangimport android.test.InstrumentationTestCase;
30340bda7154194d64a719fb5c86a702a4e5773be0Xia Wangimport android.test.InstrumentationTestRunner;
31340bda7154194d64a719fb5c86a702a4e5773be0Xia Wangimport android.test.suitebuilder.annotation.LargeTest;
32340bda7154194d64a719fb5c86a702a4e5773be0Xia Wangimport android.util.Log;
33340bda7154194d64a719fb5c86a702a4e5773be0Xia Wang
34340bda7154194d64a719fb5c86a702a4e5773be0Xia Wangimport com.android.internal.net.LegacyVpnInfo;
35340bda7154194d64a719fb5c86a702a4e5773be0Xia Wangimport com.android.internal.net.VpnConfig;
36340bda7154194d64a719fb5c86a702a4e5773be0Xia Wangimport com.android.internal.net.VpnProfile;
37340bda7154194d64a719fb5c86a702a4e5773be0Xia Wang
387a250b82882c5ccc93cdd73ab62471470fa43e2cNarayan Kamathimport java.net.HttpURLConnection;
397a250b82882c5ccc93cdd73ab62471470fa43e2cNarayan Kamathimport java.net.URL;
40340bda7154194d64a719fb5c86a702a4e5773be0Xia Wangimport junit.framework.Assert;
41340bda7154194d64a719fb5c86a702a4e5773be0Xia Wang
427a250b82882c5ccc93cdd73ab62471470fa43e2cNarayan Kamathimport libcore.io.Streams;
43340bda7154194d64a719fb5c86a702a4e5773be0Xia Wangimport org.json.JSONException;
44340bda7154194d64a719fb5c86a702a4e5773be0Xia Wangimport org.json.JSONObject;
45340bda7154194d64a719fb5c86a702a4e5773be0Xia Wang
46340bda7154194d64a719fb5c86a702a4e5773be0Xia Wangimport java.io.File;
47340bda7154194d64a719fb5c86a702a4e5773be0Xia Wangimport java.io.FileInputStream;
48340bda7154194d64a719fb5c86a702a4e5773be0Xia Wangimport java.io.IOException;
49340bda7154194d64a719fb5c86a702a4e5773be0Xia Wangimport java.io.InputStream;
50340bda7154194d64a719fb5c86a702a4e5773be0Xia Wangimport java.net.UnknownHostException;
51340bda7154194d64a719fb5c86a702a4e5773be0Xia Wangimport java.nio.charset.StandardCharsets;
52340bda7154194d64a719fb5c86a702a4e5773be0Xia Wangimport java.util.List;
53340bda7154194d64a719fb5c86a702a4e5773be0Xia Wangimport java.util.Map;
54340bda7154194d64a719fb5c86a702a4e5773be0Xia Wang
55340bda7154194d64a719fb5c86a702a4e5773be0Xia Wang/**
56340bda7154194d64a719fb5c86a702a4e5773be0Xia Wang * Legacy VPN connection tests
57340bda7154194d64a719fb5c86a702a4e5773be0Xia Wang *
58340bda7154194d64a719fb5c86a702a4e5773be0Xia Wang * To run the test, use command:
59340bda7154194d64a719fb5c86a702a4e5773be0Xia Wang * adb shell am instrument -e class com.android.settings.vpn2.VpnTests -e profile foo.xml
60340bda7154194d64a719fb5c86a702a4e5773be0Xia Wang * -w com.android.settings.tests/android.test.InstrumentationTestRunner
61340bda7154194d64a719fb5c86a702a4e5773be0Xia Wang *
62340bda7154194d64a719fb5c86a702a4e5773be0Xia Wang * VPN profiles are saved in an xml file and will be loaded through {@link VpnProfileParser}.
63340bda7154194d64a719fb5c86a702a4e5773be0Xia Wang * Push the profile (foo.xml) to the external storage, e.g adb push foo.xml /sdcard/ before running
64340bda7154194d64a719fb5c86a702a4e5773be0Xia Wang * the above command.
65340bda7154194d64a719fb5c86a702a4e5773be0Xia Wang *
66340bda7154194d64a719fb5c86a702a4e5773be0Xia Wang * A typical profile looks like the following:
67340bda7154194d64a719fb5c86a702a4e5773be0Xia Wang * <vpn>
68340bda7154194d64a719fb5c86a702a4e5773be0Xia Wang *   <name></name>
69340bda7154194d64a719fb5c86a702a4e5773be0Xia Wang *   <type></type>
70340bda7154194d64a719fb5c86a702a4e5773be0Xia Wang *   <server></server>
71340bda7154194d64a719fb5c86a702a4e5773be0Xia Wang *   <username></username>
72340bda7154194d64a719fb5c86a702a4e5773be0Xia Wang *   <password></password>
73340bda7154194d64a719fb5c86a702a4e5773be0Xia Wang *   <dnsServers></dnsServers>
74340bda7154194d64a719fb5c86a702a4e5773be0Xia Wang *   <searchDomains></searchDomains>
75340bda7154194d64a719fb5c86a702a4e5773be0Xia Wang *   <routes></routes>
76340bda7154194d64a719fb5c86a702a4e5773be0Xia Wang *   <l2tpSecret></l2tpSecret>
77340bda7154194d64a719fb5c86a702a4e5773be0Xia Wang *   <ipsecIdentifier></ipsecIdentifier>
78340bda7154194d64a719fb5c86a702a4e5773be0Xia Wang *   <ipsecSecret></ipsecSecret>
79340bda7154194d64a719fb5c86a702a4e5773be0Xia Wang *   <ipsecUserCert></ipsecUserCert>
80340bda7154194d64a719fb5c86a702a4e5773be0Xia Wang *   <ipsecCaCert></ipsecCaCert>
81340bda7154194d64a719fb5c86a702a4e5773be0Xia Wang *   <ipsecServerCert></ipsecServerCert>
82340bda7154194d64a719fb5c86a702a4e5773be0Xia Wang * </vpn>
83340bda7154194d64a719fb5c86a702a4e5773be0Xia Wang * VPN types include: TYPE_PPTP, TYPE_L2TP_IPSEC_PSK, TYPE_L2TP_IPSEC_RSA,
84340bda7154194d64a719fb5c86a702a4e5773be0Xia Wang * TYPE_IPSEC_XAUTH_PSK, TYPE_IPSEC_XAUTH_RSA, TYPE_IPSEC_HYBRID_RSA
85340bda7154194d64a719fb5c86a702a4e5773be0Xia Wang */
86340bda7154194d64a719fb5c86a702a4e5773be0Xia Wangpublic class VpnTests extends InstrumentationTestCase {
87340bda7154194d64a719fb5c86a702a4e5773be0Xia Wang    private static final String TAG = "VpnTests";
88340bda7154194d64a719fb5c86a702a4e5773be0Xia Wang    /* Maximum time to wait for VPN connection */
89340bda7154194d64a719fb5c86a702a4e5773be0Xia Wang    private static final long MAX_CONNECTION_TIME = 5 * 60 * 1000;
90ce11881accf5db04e2a54b58176e24de49ef6917Xia Wang    private static final long VPN_STAY_TIME = 60 * 1000;
91340bda7154194d64a719fb5c86a702a4e5773be0Xia Wang    private static final int MAX_DISCONNECTION_TRIES = 3;
92340bda7154194d64a719fb5c86a702a4e5773be0Xia Wang    private static final String EXTERNAL_SERVER =
93340bda7154194d64a719fb5c86a702a4e5773be0Xia Wang            "http://ip2country.sourceforge.net/ip2c.php?format=JSON";
94340bda7154194d64a719fb5c86a702a4e5773be0Xia Wang    private static final String VPN_INTERFACE = "ppp0";
95340bda7154194d64a719fb5c86a702a4e5773be0Xia Wang    private final IConnectivityManager mService = IConnectivityManager.Stub
96340bda7154194d64a719fb5c86a702a4e5773be0Xia Wang        .asInterface(ServiceManager.getService(Context.CONNECTIVITY_SERVICE));
97340bda7154194d64a719fb5c86a702a4e5773be0Xia Wang    private Map<Integer, VpnInfo> mVpnInfoPool = null;
98340bda7154194d64a719fb5c86a702a4e5773be0Xia Wang    private Context mContext;
99340bda7154194d64a719fb5c86a702a4e5773be0Xia Wang    private CertInstallerHelper mCertHelper = null;
100340bda7154194d64a719fb5c86a702a4e5773be0Xia Wang    private KeyStore mKeyStore = KeyStore.getInstance();
101340bda7154194d64a719fb5c86a702a4e5773be0Xia Wang    private String mPreviousIpAddress = null;
102340bda7154194d64a719fb5c86a702a4e5773be0Xia Wang    private boolean DEBUG = false;
103340bda7154194d64a719fb5c86a702a4e5773be0Xia Wang
104340bda7154194d64a719fb5c86a702a4e5773be0Xia Wang    @Override
105340bda7154194d64a719fb5c86a702a4e5773be0Xia Wang    protected void setUp() throws Exception {
106340bda7154194d64a719fb5c86a702a4e5773be0Xia Wang        super.setUp();
107340bda7154194d64a719fb5c86a702a4e5773be0Xia Wang        InputStream in = null;
108340bda7154194d64a719fb5c86a702a4e5773be0Xia Wang        InstrumentationTestRunner mRunner = (InstrumentationTestRunner)getInstrumentation();
109340bda7154194d64a719fb5c86a702a4e5773be0Xia Wang        mContext = mRunner.getContext();
110340bda7154194d64a719fb5c86a702a4e5773be0Xia Wang        Bundle arguments = mRunner.getArguments();
111340bda7154194d64a719fb5c86a702a4e5773be0Xia Wang        String PROFILE_NAME = arguments.getString("profile");
112340bda7154194d64a719fb5c86a702a4e5773be0Xia Wang        Assert.assertNotNull("Push profile to external storage and load with"
113340bda7154194d64a719fb5c86a702a4e5773be0Xia Wang                + "'-e profile <filename>'", PROFILE_NAME);
114340bda7154194d64a719fb5c86a702a4e5773be0Xia Wang        File profileFile = new File(Environment.getExternalStorageDirectory(), PROFILE_NAME);
115340bda7154194d64a719fb5c86a702a4e5773be0Xia Wang        in = new FileInputStream(profileFile);
116340bda7154194d64a719fb5c86a702a4e5773be0Xia Wang        mVpnInfoPool = VpnProfileParser.parse(in);
117340bda7154194d64a719fb5c86a702a4e5773be0Xia Wang        Assert.assertNotNull("no VPN profiles are parsed", mVpnInfoPool);
118340bda7154194d64a719fb5c86a702a4e5773be0Xia Wang        if (DEBUG) {
119340bda7154194d64a719fb5c86a702a4e5773be0Xia Wang            Log.v(TAG, "print out the vpn profiles");
120340bda7154194d64a719fb5c86a702a4e5773be0Xia Wang            for (Map.Entry<Integer, VpnInfo> profileEntrySet: mVpnInfoPool.entrySet()) {
121340bda7154194d64a719fb5c86a702a4e5773be0Xia Wang                VpnInfo vpnInfo = profileEntrySet.getValue();
122340bda7154194d64a719fb5c86a702a4e5773be0Xia Wang                printVpnProfile(vpnInfo.getVpnProfile());
123340bda7154194d64a719fb5c86a702a4e5773be0Xia Wang                if (vpnInfo.getCertificateFile() != null) {
124340bda7154194d64a719fb5c86a702a4e5773be0Xia Wang                    Log.d(TAG, "certificate file for this vpn is " + vpnInfo.getCertificateFile());
125340bda7154194d64a719fb5c86a702a4e5773be0Xia Wang                }
126340bda7154194d64a719fb5c86a702a4e5773be0Xia Wang                if (vpnInfo.getPassword() != null) {
127340bda7154194d64a719fb5c86a702a4e5773be0Xia Wang                    Log.d(TAG, "password for the certificate file is: " + vpnInfo.getPassword());
128340bda7154194d64a719fb5c86a702a4e5773be0Xia Wang                }
129340bda7154194d64a719fb5c86a702a4e5773be0Xia Wang            }
130340bda7154194d64a719fb5c86a702a4e5773be0Xia Wang        }
131340bda7154194d64a719fb5c86a702a4e5773be0Xia Wang        // disconnect existing vpn if there is any
132290784afded5426d5b1d0cb7d71586237445c802Robin Lee        LegacyVpnInfo oldVpn = mService.getLegacyVpnInfo(UserHandle.myUserId());
133340bda7154194d64a719fb5c86a702a4e5773be0Xia Wang        if (oldVpn != null) {
134340bda7154194d64a719fb5c86a702a4e5773be0Xia Wang            Log.v(TAG, "disconnect legacy VPN");
135340bda7154194d64a719fb5c86a702a4e5773be0Xia Wang            disconnect();
136340bda7154194d64a719fb5c86a702a4e5773be0Xia Wang            // wait till the legacy VPN is disconnected.
137340bda7154194d64a719fb5c86a702a4e5773be0Xia Wang            int tries = 0;
138290784afded5426d5b1d0cb7d71586237445c802Robin Lee            while (tries < MAX_DISCONNECTION_TRIES &&
139290784afded5426d5b1d0cb7d71586237445c802Robin Lee                    mService.getLegacyVpnInfo(UserHandle.myUserId()) != null) {
140340bda7154194d64a719fb5c86a702a4e5773be0Xia Wang                tries++;
141340bda7154194d64a719fb5c86a702a4e5773be0Xia Wang                Thread.sleep(10 * 1000);
142340bda7154194d64a719fb5c86a702a4e5773be0Xia Wang                Log.v(TAG, "Wait for legacy VPN to be disconnected.");
143340bda7154194d64a719fb5c86a702a4e5773be0Xia Wang            }
144290784afded5426d5b1d0cb7d71586237445c802Robin Lee            Assert.assertNull("Failed to disconect VPN",
145290784afded5426d5b1d0cb7d71586237445c802Robin Lee                    mService.getLegacyVpnInfo(UserHandle.myUserId()));
146340bda7154194d64a719fb5c86a702a4e5773be0Xia Wang            // wait for 30 seconds after the previous VPN is disconnected.
147340bda7154194d64a719fb5c86a702a4e5773be0Xia Wang            sleep(30 * 1000);
148340bda7154194d64a719fb5c86a702a4e5773be0Xia Wang        }
149340bda7154194d64a719fb5c86a702a4e5773be0Xia Wang        // Create CertInstallerHelper to initialize the keystore
150340bda7154194d64a719fb5c86a702a4e5773be0Xia Wang        mCertHelper = new CertInstallerHelper();
151340bda7154194d64a719fb5c86a702a4e5773be0Xia Wang    }
152340bda7154194d64a719fb5c86a702a4e5773be0Xia Wang
153ce11881accf5db04e2a54b58176e24de49ef6917Xia Wang    @Override
154ce11881accf5db04e2a54b58176e24de49ef6917Xia Wang    protected void tearDown() throws Exception {
155ce11881accf5db04e2a54b58176e24de49ef6917Xia Wang        sleep(VPN_STAY_TIME);
156ce11881accf5db04e2a54b58176e24de49ef6917Xia Wang        super.tearDown();
157ce11881accf5db04e2a54b58176e24de49ef6917Xia Wang    }
158ce11881accf5db04e2a54b58176e24de49ef6917Xia Wang
159340bda7154194d64a719fb5c86a702a4e5773be0Xia Wang    private void printVpnProfile(VpnProfile profile) {
160340bda7154194d64a719fb5c86a702a4e5773be0Xia Wang        Log.v(TAG, "profile: ");
161340bda7154194d64a719fb5c86a702a4e5773be0Xia Wang        Log.v(TAG, "key: " + profile.key);
162340bda7154194d64a719fb5c86a702a4e5773be0Xia Wang        Log.v(TAG, "name: " + profile.name);
163340bda7154194d64a719fb5c86a702a4e5773be0Xia Wang        Log.v(TAG, "type: " + profile.type);
164340bda7154194d64a719fb5c86a702a4e5773be0Xia Wang        Log.v(TAG, "server: " + profile.server);
165340bda7154194d64a719fb5c86a702a4e5773be0Xia Wang        Log.v(TAG, "username: " + profile.username);
166340bda7154194d64a719fb5c86a702a4e5773be0Xia Wang        Log.v(TAG, "password: " + profile.password);
167340bda7154194d64a719fb5c86a702a4e5773be0Xia Wang        Log.v(TAG, "dnsServers: " + profile.dnsServers);
168340bda7154194d64a719fb5c86a702a4e5773be0Xia Wang        Log.v(TAG, "searchDomains: " + profile.searchDomains);
169340bda7154194d64a719fb5c86a702a4e5773be0Xia Wang        Log.v(TAG, "routes: " + profile.routes);
170340bda7154194d64a719fb5c86a702a4e5773be0Xia Wang        Log.v(TAG, "mppe: " + profile.mppe);
171340bda7154194d64a719fb5c86a702a4e5773be0Xia Wang        Log.v(TAG, "l2tpSecret: " + profile.l2tpSecret);
172340bda7154194d64a719fb5c86a702a4e5773be0Xia Wang        Log.v(TAG, "ipsecIdentifier: " + profile.ipsecIdentifier);
173340bda7154194d64a719fb5c86a702a4e5773be0Xia Wang        Log.v(TAG, "ipsecSecret: " + profile.ipsecSecret);
174340bda7154194d64a719fb5c86a702a4e5773be0Xia Wang        Log.v(TAG, "ipsecUserCert: " + profile.ipsecUserCert);
175340bda7154194d64a719fb5c86a702a4e5773be0Xia Wang        Log.v(TAG, "ipsecCaCert: " + profile.ipsecCaCert);
176340bda7154194d64a719fb5c86a702a4e5773be0Xia Wang        Log.v(TAG, "ipsecServerCert: " + profile.ipsecServerCert);
177340bda7154194d64a719fb5c86a702a4e5773be0Xia Wang    }
178340bda7154194d64a719fb5c86a702a4e5773be0Xia Wang
179340bda7154194d64a719fb5c86a702a4e5773be0Xia Wang    private void printKeyStore(VpnProfile profile) {
180340bda7154194d64a719fb5c86a702a4e5773be0Xia Wang        // print out the information from keystore
181340bda7154194d64a719fb5c86a702a4e5773be0Xia Wang        String privateKey = "";
182340bda7154194d64a719fb5c86a702a4e5773be0Xia Wang        String userCert = "";
183340bda7154194d64a719fb5c86a702a4e5773be0Xia Wang        String caCert = "";
184340bda7154194d64a719fb5c86a702a4e5773be0Xia Wang        String serverCert = "";
185340bda7154194d64a719fb5c86a702a4e5773be0Xia Wang        if (!profile.ipsecUserCert.isEmpty()) {
186340bda7154194d64a719fb5c86a702a4e5773be0Xia Wang            privateKey = Credentials.USER_PRIVATE_KEY + profile.ipsecUserCert;
187340bda7154194d64a719fb5c86a702a4e5773be0Xia Wang            byte[] value = mKeyStore.get(Credentials.USER_CERTIFICATE + profile.ipsecUserCert);
188340bda7154194d64a719fb5c86a702a4e5773be0Xia Wang            userCert = (value == null) ? null : new String(value, StandardCharsets.UTF_8);
189340bda7154194d64a719fb5c86a702a4e5773be0Xia Wang        }
190340bda7154194d64a719fb5c86a702a4e5773be0Xia Wang        if (!profile.ipsecCaCert.isEmpty()) {
191340bda7154194d64a719fb5c86a702a4e5773be0Xia Wang            byte[] value = mKeyStore.get(Credentials.CA_CERTIFICATE + profile.ipsecCaCert);
192340bda7154194d64a719fb5c86a702a4e5773be0Xia Wang            caCert = (value == null) ? null : new String(value, StandardCharsets.UTF_8);
193340bda7154194d64a719fb5c86a702a4e5773be0Xia Wang        }
194340bda7154194d64a719fb5c86a702a4e5773be0Xia Wang        if (!profile.ipsecServerCert.isEmpty()) {
195340bda7154194d64a719fb5c86a702a4e5773be0Xia Wang            byte[] value = mKeyStore.get(Credentials.USER_CERTIFICATE + profile.ipsecServerCert);
196340bda7154194d64a719fb5c86a702a4e5773be0Xia Wang            serverCert = (value == null) ? null : new String(value, StandardCharsets.UTF_8);
197340bda7154194d64a719fb5c86a702a4e5773be0Xia Wang        }
198340bda7154194d64a719fb5c86a702a4e5773be0Xia Wang        Log.v(TAG, "privateKey: \n" + ((privateKey == null) ? "" : privateKey));
199340bda7154194d64a719fb5c86a702a4e5773be0Xia Wang        Log.v(TAG, "userCert: \n" + ((userCert == null) ? "" : userCert));
200340bda7154194d64a719fb5c86a702a4e5773be0Xia Wang        Log.v(TAG, "caCert: \n" + ((caCert == null) ? "" : caCert));
201340bda7154194d64a719fb5c86a702a4e5773be0Xia Wang        Log.v(TAG, "serverCert: \n" + ((serverCert == null) ? "" : serverCert));
202340bda7154194d64a719fb5c86a702a4e5773be0Xia Wang    }
203340bda7154194d64a719fb5c86a702a4e5773be0Xia Wang
204340bda7154194d64a719fb5c86a702a4e5773be0Xia Wang    /**
205340bda7154194d64a719fb5c86a702a4e5773be0Xia Wang     * Connect legacy VPN
206340bda7154194d64a719fb5c86a702a4e5773be0Xia Wang     */
207340bda7154194d64a719fb5c86a702a4e5773be0Xia Wang    private void connect(VpnProfile profile) throws Exception {
208340bda7154194d64a719fb5c86a702a4e5773be0Xia Wang        try {
209340bda7154194d64a719fb5c86a702a4e5773be0Xia Wang            mService.startLegacyVpn(profile);
210340bda7154194d64a719fb5c86a702a4e5773be0Xia Wang        } catch (IllegalStateException e) {
211340bda7154194d64a719fb5c86a702a4e5773be0Xia Wang            fail(String.format("start legacy vpn: %s failed: %s", profile.name, e.toString()));
212340bda7154194d64a719fb5c86a702a4e5773be0Xia Wang        }
213340bda7154194d64a719fb5c86a702a4e5773be0Xia Wang    }
214340bda7154194d64a719fb5c86a702a4e5773be0Xia Wang
215340bda7154194d64a719fb5c86a702a4e5773be0Xia Wang    /**
216340bda7154194d64a719fb5c86a702a4e5773be0Xia Wang     * Disconnect legacy VPN
217340bda7154194d64a719fb5c86a702a4e5773be0Xia Wang     */
218340bda7154194d64a719fb5c86a702a4e5773be0Xia Wang    private void disconnect() throws Exception {
219340bda7154194d64a719fb5c86a702a4e5773be0Xia Wang        try {
22001b35bcae307907bd8aaaa9cf23fa50f70e5f491Robin Lee            mService.prepareVpn(VpnConfig.LEGACY_VPN, VpnConfig.LEGACY_VPN, UserHandle.myUserId());
221340bda7154194d64a719fb5c86a702a4e5773be0Xia Wang        } catch (RemoteException e) {
222340bda7154194d64a719fb5c86a702a4e5773be0Xia Wang            Log.e(TAG, String.format("disconnect VPN exception: %s", e.toString()));
223340bda7154194d64a719fb5c86a702a4e5773be0Xia Wang        }
224340bda7154194d64a719fb5c86a702a4e5773be0Xia Wang    }
225340bda7154194d64a719fb5c86a702a4e5773be0Xia Wang
226340bda7154194d64a719fb5c86a702a4e5773be0Xia Wang    /**
227340bda7154194d64a719fb5c86a702a4e5773be0Xia Wang     * Get external IP address
228340bda7154194d64a719fb5c86a702a4e5773be0Xia Wang     */
229340bda7154194d64a719fb5c86a702a4e5773be0Xia Wang    private String getIpAddress() {
230340bda7154194d64a719fb5c86a702a4e5773be0Xia Wang        String ip = null;
2317a250b82882c5ccc93cdd73ab62471470fa43e2cNarayan Kamath        HttpURLConnection urlConnection = null;
232b009023c76227b6c984652683be7d054033eb935Alex Klyubin        // TODO: Rewrite this test to use an HTTPS URL.
233b009023c76227b6c984652683be7d054033eb935Alex Klyubin        // Because this test uses cleartext HTTP, the network security policy of this app needs to
234b009023c76227b6c984652683be7d054033eb935Alex Klyubin        // be temporarily relaxed to permit such traffic.
235b009023c76227b6c984652683be7d054033eb935Alex Klyubin        NetworkSecurityPolicy networkSecurityPolicy = NetworkSecurityPolicy.getInstance();
236b009023c76227b6c984652683be7d054033eb935Alex Klyubin        boolean cleartextTrafficPermittedBeforeTest =
237b009023c76227b6c984652683be7d054033eb935Alex Klyubin                networkSecurityPolicy.isCleartextTrafficPermitted();
238b009023c76227b6c984652683be7d054033eb935Alex Klyubin        networkSecurityPolicy.setCleartextTrafficPermitted(true);
239340bda7154194d64a719fb5c86a702a4e5773be0Xia Wang        try {
2407a250b82882c5ccc93cdd73ab62471470fa43e2cNarayan Kamath            URL url = new URL(EXTERNAL_SERVER);
2417a250b82882c5ccc93cdd73ab62471470fa43e2cNarayan Kamath            urlConnection = (HttpURLConnection) url.openConnection();
2427a250b82882c5ccc93cdd73ab62471470fa43e2cNarayan Kamath            Log.i(TAG, "Response from httpget: " + urlConnection.getResponseCode());
243340bda7154194d64a719fb5c86a702a4e5773be0Xia Wang
2447a250b82882c5ccc93cdd73ab62471470fa43e2cNarayan Kamath            InputStream is = urlConnection.getInputStream();
2457a250b82882c5ccc93cdd73ab62471470fa43e2cNarayan Kamath            String response;
2467a250b82882c5ccc93cdd73ab62471470fa43e2cNarayan Kamath            try {
2477a250b82882c5ccc93cdd73ab62471470fa43e2cNarayan Kamath                response = new String(Streams.readFully(is), StandardCharsets.UTF_8);
2487a250b82882c5ccc93cdd73ab62471470fa43e2cNarayan Kamath            } finally {
2497a250b82882c5ccc93cdd73ab62471470fa43e2cNarayan Kamath                is.close();
2507a250b82882c5ccc93cdd73ab62471470fa43e2cNarayan Kamath            }
2517a250b82882c5ccc93cdd73ab62471470fa43e2cNarayan Kamath
2527a250b82882c5ccc93cdd73ab62471470fa43e2cNarayan Kamath            JSONObject json_data = new JSONObject(response);
253340bda7154194d64a719fb5c86a702a4e5773be0Xia Wang            ip = json_data.getString("ip");
254340bda7154194d64a719fb5c86a702a4e5773be0Xia Wang            Log.v(TAG, "json_data: " + ip);
255340bda7154194d64a719fb5c86a702a4e5773be0Xia Wang        } catch (IllegalArgumentException e) {
256340bda7154194d64a719fb5c86a702a4e5773be0Xia Wang            Log.e(TAG, "exception while getting external IP: " + e.toString());
257340bda7154194d64a719fb5c86a702a4e5773be0Xia Wang        } catch (IOException e) {
258340bda7154194d64a719fb5c86a702a4e5773be0Xia Wang            Log.e(TAG, "IOException while getting IP: " + e.toString());
259340bda7154194d64a719fb5c86a702a4e5773be0Xia Wang        } catch (JSONException e) {
260340bda7154194d64a719fb5c86a702a4e5773be0Xia Wang            Log.e(TAG, "exception while creating JSONObject: " + e.toString());
2617a250b82882c5ccc93cdd73ab62471470fa43e2cNarayan Kamath        } finally {
262b009023c76227b6c984652683be7d054033eb935Alex Klyubin            networkSecurityPolicy.setCleartextTrafficPermitted(cleartextTrafficPermittedBeforeTest);
2637a250b82882c5ccc93cdd73ab62471470fa43e2cNarayan Kamath            if (urlConnection != null) {
2647a250b82882c5ccc93cdd73ab62471470fa43e2cNarayan Kamath                urlConnection.disconnect();
2657a250b82882c5ccc93cdd73ab62471470fa43e2cNarayan Kamath            }
266340bda7154194d64a719fb5c86a702a4e5773be0Xia Wang        }
267340bda7154194d64a719fb5c86a702a4e5773be0Xia Wang        return ip;
268340bda7154194d64a719fb5c86a702a4e5773be0Xia Wang    }
269340bda7154194d64a719fb5c86a702a4e5773be0Xia Wang
270340bda7154194d64a719fb5c86a702a4e5773be0Xia Wang    /**
271340bda7154194d64a719fb5c86a702a4e5773be0Xia Wang     * Verify the vpn connection by checking the VPN state and external IP
272340bda7154194d64a719fb5c86a702a4e5773be0Xia Wang     */
273340bda7154194d64a719fb5c86a702a4e5773be0Xia Wang    private void validateVpnConnection(VpnProfile profile) throws Exception {
274340bda7154194d64a719fb5c86a702a4e5773be0Xia Wang        validateVpnConnection(profile, false);
275340bda7154194d64a719fb5c86a702a4e5773be0Xia Wang    }
276340bda7154194d64a719fb5c86a702a4e5773be0Xia Wang
277340bda7154194d64a719fb5c86a702a4e5773be0Xia Wang    /**
278340bda7154194d64a719fb5c86a702a4e5773be0Xia Wang     * Verify the vpn connection by checking the VPN state, external IP or ping test
279340bda7154194d64a719fb5c86a702a4e5773be0Xia Wang     */
280340bda7154194d64a719fb5c86a702a4e5773be0Xia Wang    private void validateVpnConnection(VpnProfile profile, boolean pingTestFlag) throws Exception {
281290784afded5426d5b1d0cb7d71586237445c802Robin Lee        LegacyVpnInfo legacyVpnInfo = mService.getLegacyVpnInfo(UserHandle.myUserId());
282340bda7154194d64a719fb5c86a702a4e5773be0Xia Wang        Assert.assertTrue(legacyVpnInfo != null);
283340bda7154194d64a719fb5c86a702a4e5773be0Xia Wang
284340bda7154194d64a719fb5c86a702a4e5773be0Xia Wang        long start = System.currentTimeMillis();
285340bda7154194d64a719fb5c86a702a4e5773be0Xia Wang        while (((System.currentTimeMillis() - start)  < MAX_CONNECTION_TIME) &&
286340bda7154194d64a719fb5c86a702a4e5773be0Xia Wang                (legacyVpnInfo.state != LegacyVpnInfo.STATE_CONNECTED)) {
287340bda7154194d64a719fb5c86a702a4e5773be0Xia Wang            Log.v(TAG, "vpn state: " + legacyVpnInfo.state);
288340bda7154194d64a719fb5c86a702a4e5773be0Xia Wang            sleep(10 * 1000);
289290784afded5426d5b1d0cb7d71586237445c802Robin Lee            legacyVpnInfo = mService.getLegacyVpnInfo(UserHandle.myUserId());
290340bda7154194d64a719fb5c86a702a4e5773be0Xia Wang        }
291340bda7154194d64a719fb5c86a702a4e5773be0Xia Wang
292340bda7154194d64a719fb5c86a702a4e5773be0Xia Wang        // the vpn state should be CONNECTED
293340bda7154194d64a719fb5c86a702a4e5773be0Xia Wang        Assert.assertTrue(legacyVpnInfo.state == LegacyVpnInfo.STATE_CONNECTED);
294340bda7154194d64a719fb5c86a702a4e5773be0Xia Wang        if (pingTestFlag) {
295340bda7154194d64a719fb5c86a702a4e5773be0Xia Wang            Assert.assertTrue(pingTest(profile.server));
296340bda7154194d64a719fb5c86a702a4e5773be0Xia Wang        } else {
297340bda7154194d64a719fb5c86a702a4e5773be0Xia Wang            String curIpAddress = getIpAddress();
298340bda7154194d64a719fb5c86a702a4e5773be0Xia Wang            // the outgoing IP address should be the same as the VPN server address
299340bda7154194d64a719fb5c86a702a4e5773be0Xia Wang            Assert.assertEquals(profile.server, curIpAddress);
300340bda7154194d64a719fb5c86a702a4e5773be0Xia Wang        }
301340bda7154194d64a719fb5c86a702a4e5773be0Xia Wang    }
302340bda7154194d64a719fb5c86a702a4e5773be0Xia Wang
303340bda7154194d64a719fb5c86a702a4e5773be0Xia Wang    private boolean pingTest(String server) {
304340bda7154194d64a719fb5c86a702a4e5773be0Xia Wang        final long PING_TIMER = 3 * 60 * 1000; // 3 minutes
305340bda7154194d64a719fb5c86a702a4e5773be0Xia Wang        if (server == null || server.isEmpty()) {
306340bda7154194d64a719fb5c86a702a4e5773be0Xia Wang            return false;
307340bda7154194d64a719fb5c86a702a4e5773be0Xia Wang        }
308340bda7154194d64a719fb5c86a702a4e5773be0Xia Wang        long startTime = System.currentTimeMillis();
309340bda7154194d64a719fb5c86a702a4e5773be0Xia Wang        while ((System.currentTimeMillis() - startTime) < PING_TIMER) {
310340bda7154194d64a719fb5c86a702a4e5773be0Xia Wang            try {
311340bda7154194d64a719fb5c86a702a4e5773be0Xia Wang                Log.v(TAG, "Start ping test, ping " + server);
312340bda7154194d64a719fb5c86a702a4e5773be0Xia Wang                Process p = Runtime.getRuntime().exec("ping -c 10 -w 100 " + server);
313340bda7154194d64a719fb5c86a702a4e5773be0Xia Wang                int status = p.waitFor();
314340bda7154194d64a719fb5c86a702a4e5773be0Xia Wang                if (status == 0) {
315340bda7154194d64a719fb5c86a702a4e5773be0Xia Wang                    // if any of the ping test is successful, return true
316340bda7154194d64a719fb5c86a702a4e5773be0Xia Wang                    return true;
317340bda7154194d64a719fb5c86a702a4e5773be0Xia Wang                }
318340bda7154194d64a719fb5c86a702a4e5773be0Xia Wang            } catch (UnknownHostException e) {
319340bda7154194d64a719fb5c86a702a4e5773be0Xia Wang                Log.e(TAG, "Ping test Fail: Unknown Host");
320340bda7154194d64a719fb5c86a702a4e5773be0Xia Wang            } catch (IOException e) {
321340bda7154194d64a719fb5c86a702a4e5773be0Xia Wang                Log.e(TAG, "Ping test Fail:  IOException");
322340bda7154194d64a719fb5c86a702a4e5773be0Xia Wang            } catch (InterruptedException e) {
323340bda7154194d64a719fb5c86a702a4e5773be0Xia Wang                Log.e(TAG, "Ping test Fail: InterruptedException");
324340bda7154194d64a719fb5c86a702a4e5773be0Xia Wang            }
325340bda7154194d64a719fb5c86a702a4e5773be0Xia Wang        }
326340bda7154194d64a719fb5c86a702a4e5773be0Xia Wang        // ping test timeout
327340bda7154194d64a719fb5c86a702a4e5773be0Xia Wang        return false;
328340bda7154194d64a719fb5c86a702a4e5773be0Xia Wang    }
329340bda7154194d64a719fb5c86a702a4e5773be0Xia Wang
330340bda7154194d64a719fb5c86a702a4e5773be0Xia Wang    /**
331340bda7154194d64a719fb5c86a702a4e5773be0Xia Wang     * Install certificates from a file loaded in external stroage on the device
332340bda7154194d64a719fb5c86a702a4e5773be0Xia Wang     * @param profile vpn profile
333340bda7154194d64a719fb5c86a702a4e5773be0Xia Wang     * @param fileName certificate file name
334340bda7154194d64a719fb5c86a702a4e5773be0Xia Wang     * @param password password to extract certificate file
335340bda7154194d64a719fb5c86a702a4e5773be0Xia Wang     */
336340bda7154194d64a719fb5c86a702a4e5773be0Xia Wang    private void installCertificatesFromFile(VpnProfile profile, String fileName, String password)
337340bda7154194d64a719fb5c86a702a4e5773be0Xia Wang            throws Exception {
338340bda7154194d64a719fb5c86a702a4e5773be0Xia Wang        if (profile == null || fileName == null || password == null) {
339340bda7154194d64a719fb5c86a702a4e5773be0Xia Wang            throw new Exception ("vpn profile, certificate file name and password can not be null");
340340bda7154194d64a719fb5c86a702a4e5773be0Xia Wang        }
341340bda7154194d64a719fb5c86a702a4e5773be0Xia Wang
342340bda7154194d64a719fb5c86a702a4e5773be0Xia Wang        int curUid = mContext.getUserId();
343340bda7154194d64a719fb5c86a702a4e5773be0Xia Wang        mCertHelper.installCertificate(profile, fileName, password);
344340bda7154194d64a719fb5c86a702a4e5773be0Xia Wang
345340bda7154194d64a719fb5c86a702a4e5773be0Xia Wang        if (DEBUG) {
346340bda7154194d64a719fb5c86a702a4e5773be0Xia Wang            printKeyStore(profile);
347340bda7154194d64a719fb5c86a702a4e5773be0Xia Wang        }
348340bda7154194d64a719fb5c86a702a4e5773be0Xia Wang    }
349340bda7154194d64a719fb5c86a702a4e5773be0Xia Wang
350340bda7154194d64a719fb5c86a702a4e5773be0Xia Wang    private void sleep(long time) {
351340bda7154194d64a719fb5c86a702a4e5773be0Xia Wang        try {
352340bda7154194d64a719fb5c86a702a4e5773be0Xia Wang            Thread.sleep(time);
353340bda7154194d64a719fb5c86a702a4e5773be0Xia Wang        } catch (InterruptedException e) {
354340bda7154194d64a719fb5c86a702a4e5773be0Xia Wang            Log.e(TAG, "interrupted: " + e.toString());
355340bda7154194d64a719fb5c86a702a4e5773be0Xia Wang        }
356340bda7154194d64a719fb5c86a702a4e5773be0Xia Wang    }
357340bda7154194d64a719fb5c86a702a4e5773be0Xia Wang
358340bda7154194d64a719fb5c86a702a4e5773be0Xia Wang    /**
359340bda7154194d64a719fb5c86a702a4e5773be0Xia Wang     * Test PPTP VPN connection
360340bda7154194d64a719fb5c86a702a4e5773be0Xia Wang     */
361340bda7154194d64a719fb5c86a702a4e5773be0Xia Wang    @LargeTest
362340bda7154194d64a719fb5c86a702a4e5773be0Xia Wang    public void testPPTPConnection() throws Exception {
363340bda7154194d64a719fb5c86a702a4e5773be0Xia Wang        mPreviousIpAddress = getIpAddress();
364340bda7154194d64a719fb5c86a702a4e5773be0Xia Wang        VpnInfo curVpnInfo = mVpnInfoPool.get(VpnProfile.TYPE_PPTP);
365340bda7154194d64a719fb5c86a702a4e5773be0Xia Wang        VpnProfile vpnProfile = curVpnInfo.getVpnProfile();
366340bda7154194d64a719fb5c86a702a4e5773be0Xia Wang        connect(vpnProfile);
367340bda7154194d64a719fb5c86a702a4e5773be0Xia Wang        validateVpnConnection(vpnProfile);
368340bda7154194d64a719fb5c86a702a4e5773be0Xia Wang    }
369340bda7154194d64a719fb5c86a702a4e5773be0Xia Wang
370340bda7154194d64a719fb5c86a702a4e5773be0Xia Wang    /**
371340bda7154194d64a719fb5c86a702a4e5773be0Xia Wang     * Test L2TP/IPSec PSK VPN connection
372340bda7154194d64a719fb5c86a702a4e5773be0Xia Wang     */
373340bda7154194d64a719fb5c86a702a4e5773be0Xia Wang    @LargeTest
374340bda7154194d64a719fb5c86a702a4e5773be0Xia Wang    public void testL2tpIpsecPskConnection() throws Exception {
375340bda7154194d64a719fb5c86a702a4e5773be0Xia Wang        mPreviousIpAddress = getIpAddress();
376340bda7154194d64a719fb5c86a702a4e5773be0Xia Wang        VpnInfo curVpnInfo = mVpnInfoPool.get(VpnProfile.TYPE_L2TP_IPSEC_PSK);
377340bda7154194d64a719fb5c86a702a4e5773be0Xia Wang        VpnProfile vpnProfile = curVpnInfo.getVpnProfile();
378340bda7154194d64a719fb5c86a702a4e5773be0Xia Wang        connect(vpnProfile);
379340bda7154194d64a719fb5c86a702a4e5773be0Xia Wang        validateVpnConnection(vpnProfile);
380340bda7154194d64a719fb5c86a702a4e5773be0Xia Wang    }
381340bda7154194d64a719fb5c86a702a4e5773be0Xia Wang
382340bda7154194d64a719fb5c86a702a4e5773be0Xia Wang    /**
383340bda7154194d64a719fb5c86a702a4e5773be0Xia Wang     * Test L2TP/IPSec RSA VPN connection
384340bda7154194d64a719fb5c86a702a4e5773be0Xia Wang     */
385340bda7154194d64a719fb5c86a702a4e5773be0Xia Wang    @LargeTest
386340bda7154194d64a719fb5c86a702a4e5773be0Xia Wang    public void testL2tpIpsecRsaConnection() throws Exception {
387340bda7154194d64a719fb5c86a702a4e5773be0Xia Wang        mPreviousIpAddress = getIpAddress();
388340bda7154194d64a719fb5c86a702a4e5773be0Xia Wang        VpnInfo curVpnInfo = mVpnInfoPool.get(VpnProfile.TYPE_L2TP_IPSEC_RSA);
389340bda7154194d64a719fb5c86a702a4e5773be0Xia Wang        VpnProfile vpnProfile = curVpnInfo.getVpnProfile();
390340bda7154194d64a719fb5c86a702a4e5773be0Xia Wang        if (DEBUG) {
391340bda7154194d64a719fb5c86a702a4e5773be0Xia Wang            printVpnProfile(vpnProfile);
392340bda7154194d64a719fb5c86a702a4e5773be0Xia Wang        }
393340bda7154194d64a719fb5c86a702a4e5773be0Xia Wang        String certFile = curVpnInfo.getCertificateFile();
394340bda7154194d64a719fb5c86a702a4e5773be0Xia Wang        String password = curVpnInfo.getPassword();
395340bda7154194d64a719fb5c86a702a4e5773be0Xia Wang        installCertificatesFromFile(vpnProfile, certFile, password);
396340bda7154194d64a719fb5c86a702a4e5773be0Xia Wang        connect(vpnProfile);
397340bda7154194d64a719fb5c86a702a4e5773be0Xia Wang        validateVpnConnection(vpnProfile);
398340bda7154194d64a719fb5c86a702a4e5773be0Xia Wang    }
399340bda7154194d64a719fb5c86a702a4e5773be0Xia Wang
400340bda7154194d64a719fb5c86a702a4e5773be0Xia Wang    /**
401340bda7154194d64a719fb5c86a702a4e5773be0Xia Wang     * Test IPSec Xauth RSA VPN connection
402340bda7154194d64a719fb5c86a702a4e5773be0Xia Wang     */
403340bda7154194d64a719fb5c86a702a4e5773be0Xia Wang    @LargeTest
404340bda7154194d64a719fb5c86a702a4e5773be0Xia Wang    public void testIpsecXauthRsaConnection() throws Exception {
405340bda7154194d64a719fb5c86a702a4e5773be0Xia Wang        mPreviousIpAddress = getIpAddress();
406340bda7154194d64a719fb5c86a702a4e5773be0Xia Wang        VpnInfo curVpnInfo = mVpnInfoPool.get(VpnProfile.TYPE_IPSEC_XAUTH_RSA);
407340bda7154194d64a719fb5c86a702a4e5773be0Xia Wang        VpnProfile vpnProfile = curVpnInfo.getVpnProfile();
408340bda7154194d64a719fb5c86a702a4e5773be0Xia Wang        if (DEBUG) {
409340bda7154194d64a719fb5c86a702a4e5773be0Xia Wang            printVpnProfile(vpnProfile);
410340bda7154194d64a719fb5c86a702a4e5773be0Xia Wang        }
411340bda7154194d64a719fb5c86a702a4e5773be0Xia Wang        String certFile = curVpnInfo.getCertificateFile();
412340bda7154194d64a719fb5c86a702a4e5773be0Xia Wang        String password = curVpnInfo.getPassword();
413340bda7154194d64a719fb5c86a702a4e5773be0Xia Wang        installCertificatesFromFile(vpnProfile, certFile, password);
414340bda7154194d64a719fb5c86a702a4e5773be0Xia Wang        connect(vpnProfile);
415340bda7154194d64a719fb5c86a702a4e5773be0Xia Wang        validateVpnConnection(vpnProfile);
416340bda7154194d64a719fb5c86a702a4e5773be0Xia Wang    }
417340bda7154194d64a719fb5c86a702a4e5773be0Xia Wang
418340bda7154194d64a719fb5c86a702a4e5773be0Xia Wang    /**
419340bda7154194d64a719fb5c86a702a4e5773be0Xia Wang     * Test IPSec Xauth PSK VPN connection
420340bda7154194d64a719fb5c86a702a4e5773be0Xia Wang     */
421340bda7154194d64a719fb5c86a702a4e5773be0Xia Wang    @LargeTest
422340bda7154194d64a719fb5c86a702a4e5773be0Xia Wang    public void testIpsecXauthPskConnection() throws Exception {
423340bda7154194d64a719fb5c86a702a4e5773be0Xia Wang        VpnInfo curVpnInfo = mVpnInfoPool.get(VpnProfile.TYPE_IPSEC_XAUTH_PSK);
424340bda7154194d64a719fb5c86a702a4e5773be0Xia Wang        VpnProfile vpnProfile = curVpnInfo.getVpnProfile();
425340bda7154194d64a719fb5c86a702a4e5773be0Xia Wang        if (DEBUG) {
426340bda7154194d64a719fb5c86a702a4e5773be0Xia Wang            printVpnProfile(vpnProfile);
427340bda7154194d64a719fb5c86a702a4e5773be0Xia Wang        }
428340bda7154194d64a719fb5c86a702a4e5773be0Xia Wang        connect(vpnProfile);
429340bda7154194d64a719fb5c86a702a4e5773be0Xia Wang        validateVpnConnection(vpnProfile, true);
430340bda7154194d64a719fb5c86a702a4e5773be0Xia Wang    }
431340bda7154194d64a719fb5c86a702a4e5773be0Xia Wang
432340bda7154194d64a719fb5c86a702a4e5773be0Xia Wang    /**
433340bda7154194d64a719fb5c86a702a4e5773be0Xia Wang     * Test IPSec Hybrid RSA VPN connection
434340bda7154194d64a719fb5c86a702a4e5773be0Xia Wang     */
435340bda7154194d64a719fb5c86a702a4e5773be0Xia Wang    @LargeTest
436340bda7154194d64a719fb5c86a702a4e5773be0Xia Wang    public void testIpsecHybridRsaConnection() throws Exception {
437340bda7154194d64a719fb5c86a702a4e5773be0Xia Wang        mPreviousIpAddress = getIpAddress();
438340bda7154194d64a719fb5c86a702a4e5773be0Xia Wang        VpnInfo curVpnInfo = mVpnInfoPool.get(VpnProfile.TYPE_IPSEC_HYBRID_RSA);
439340bda7154194d64a719fb5c86a702a4e5773be0Xia Wang        VpnProfile vpnProfile = curVpnInfo.getVpnProfile();
440340bda7154194d64a719fb5c86a702a4e5773be0Xia Wang        if (DEBUG) {
441340bda7154194d64a719fb5c86a702a4e5773be0Xia Wang            printVpnProfile(vpnProfile);
442340bda7154194d64a719fb5c86a702a4e5773be0Xia Wang        }
443340bda7154194d64a719fb5c86a702a4e5773be0Xia Wang        connect(vpnProfile);
444340bda7154194d64a719fb5c86a702a4e5773be0Xia Wang        validateVpnConnection(vpnProfile);
445340bda7154194d64a719fb5c86a702a4e5773be0Xia Wang    }
446340bda7154194d64a719fb5c86a702a4e5773be0Xia Wang}
447