/services/java/com/android/server/connectivity/Vpn.java

https://github.com/aizuzi/platform_frameworks_base · Java · 1240 lines · 930 code · 130 blank · 180 comment · 187 complexity · 3eda5165e1d673fe77ff13d7f3148988 MD5 · raw file

  1. /*
  2. * Copyright (C) 2011 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.server.connectivity;
  17. import static android.Manifest.permission.BIND_VPN_SERVICE;
  18. import android.app.AppGlobals;
  19. import android.app.Notification;
  20. import android.app.NotificationManager;
  21. import android.app.PendingIntent;
  22. import android.content.BroadcastReceiver;
  23. import android.content.ComponentName;
  24. import android.content.Context;
  25. import android.content.Intent;
  26. import android.content.IntentFilter;
  27. import android.content.ServiceConnection;
  28. import android.content.pm.ApplicationInfo;
  29. import android.content.pm.IPackageManager;
  30. import android.content.pm.PackageManager;
  31. import android.content.pm.ResolveInfo;
  32. import android.content.pm.UserInfo;
  33. import android.graphics.Bitmap;
  34. import android.graphics.Canvas;
  35. import android.graphics.drawable.Drawable;
  36. import android.net.BaseNetworkStateTracker;
  37. import android.net.ConnectivityManager;
  38. import android.net.IConnectivityManager;
  39. import android.net.INetworkManagementEventObserver;
  40. import android.net.LinkAddress;
  41. import android.net.LinkProperties;
  42. import android.net.LocalSocket;
  43. import android.net.LocalSocketAddress;
  44. import android.net.NetworkInfo;
  45. import android.net.NetworkUtils;
  46. import android.net.RouteInfo;
  47. import android.net.NetworkInfo.DetailedState;
  48. import android.os.Binder;
  49. import android.os.FileUtils;
  50. import android.os.IBinder;
  51. import android.os.INetworkManagementService;
  52. import android.os.Parcel;
  53. import android.os.ParcelFileDescriptor;
  54. import android.os.Process;
  55. import android.os.RemoteException;
  56. import android.os.SystemClock;
  57. import android.os.SystemService;
  58. import android.os.UserHandle;
  59. import android.os.UserManager;
  60. import android.security.Credentials;
  61. import android.security.KeyStore;
  62. import android.util.Log;
  63. import android.util.SparseBooleanArray;
  64. import android.widget.Toast;
  65. import com.android.internal.annotations.GuardedBy;
  66. import com.android.internal.R;
  67. import com.android.internal.net.LegacyVpnInfo;
  68. import com.android.internal.net.VpnConfig;
  69. import com.android.internal.net.VpnProfile;
  70. import com.android.internal.util.Preconditions;
  71. import com.android.server.ConnectivityService.VpnCallback;
  72. import com.android.server.net.BaseNetworkObserver;
  73. import java.io.File;
  74. import java.io.InputStream;
  75. import java.io.OutputStream;
  76. import java.net.InetAddress;
  77. import java.net.Inet4Address;
  78. import java.net.InetAddress;
  79. import java.nio.charset.StandardCharsets;
  80. import java.util.Arrays;
  81. import java.util.List;
  82. import java.util.concurrent.atomic.AtomicInteger;
  83. import libcore.io.IoUtils;
  84. /**
  85. * @hide
  86. */
  87. public class Vpn extends BaseNetworkStateTracker {
  88. private static final String TAG = "Vpn";
  89. private static final boolean LOGD = true;
  90. // TODO: create separate trackers for each unique VPN to support
  91. // automated reconnection
  92. private final VpnCallback mCallback;
  93. private String mPackage = VpnConfig.LEGACY_VPN;
  94. private String mInterface;
  95. private Connection mConnection;
  96. private LegacyVpnRunner mLegacyVpnRunner;
  97. private PendingIntent mStatusIntent;
  98. private volatile boolean mEnableNotif = true;
  99. private volatile boolean mEnableTeardown = true;
  100. private final IConnectivityManager mConnService;
  101. private VpnConfig mConfig;
  102. /* list of users using this VPN. */
  103. @GuardedBy("this")
  104. private SparseBooleanArray mVpnUsers = null;
  105. private BroadcastReceiver mUserIntentReceiver = null;
  106. private final int mUserId;
  107. public Vpn(Context context, VpnCallback callback, INetworkManagementService netService,
  108. IConnectivityManager connService, int userId) {
  109. // TODO: create dedicated TYPE_VPN network type
  110. super(ConnectivityManager.TYPE_DUMMY);
  111. mContext = context;
  112. mCallback = callback;
  113. mConnService = connService;
  114. mUserId = userId;
  115. try {
  116. netService.registerObserver(mObserver);
  117. } catch (RemoteException e) {
  118. Log.wtf(TAG, "Problem registering observer", e);
  119. }
  120. if (userId == UserHandle.USER_OWNER) {
  121. // Owner's VPN also needs to handle restricted users
  122. mUserIntentReceiver = new BroadcastReceiver() {
  123. @Override
  124. public void onReceive(Context context, Intent intent) {
  125. final String action = intent.getAction();
  126. final int userId = intent.getIntExtra(Intent.EXTRA_USER_HANDLE,
  127. UserHandle.USER_NULL);
  128. if (userId == UserHandle.USER_NULL) return;
  129. if (Intent.ACTION_USER_ADDED.equals(action)) {
  130. onUserAdded(userId);
  131. } else if (Intent.ACTION_USER_REMOVED.equals(action)) {
  132. onUserRemoved(userId);
  133. }
  134. }
  135. };
  136. IntentFilter intentFilter = new IntentFilter();
  137. intentFilter.addAction(Intent.ACTION_USER_ADDED);
  138. intentFilter.addAction(Intent.ACTION_USER_REMOVED);
  139. mContext.registerReceiverAsUser(
  140. mUserIntentReceiver, UserHandle.ALL, intentFilter, null, null);
  141. }
  142. }
  143. /**
  144. * Set if this object is responsible for showing its own notifications. When
  145. * {@code false}, notifications are handled externally by someone else.
  146. */
  147. public void setEnableNotifications(boolean enableNotif) {
  148. mEnableNotif = enableNotif;
  149. }
  150. /**
  151. * Set if this object is responsible for watching for {@link NetworkInfo}
  152. * teardown. When {@code false}, teardown is handled externally by someone
  153. * else.
  154. */
  155. public void setEnableTeardown(boolean enableTeardown) {
  156. mEnableTeardown = enableTeardown;
  157. }
  158. @Override
  159. protected void startMonitoringInternal() {
  160. // Ignored; events are sent through callbacks for now
  161. }
  162. @Override
  163. public boolean teardown() {
  164. // TODO: finish migration to unique tracker for each VPN
  165. throw new UnsupportedOperationException();
  166. }
  167. @Override
  168. public boolean reconnect() {
  169. // TODO: finish migration to unique tracker for each VPN
  170. throw new UnsupportedOperationException();
  171. }
  172. @Override
  173. public String getTcpBufferSizesPropName() {
  174. return PROP_TCP_BUFFER_UNKNOWN;
  175. }
  176. /**
  177. * Update current state, dispaching event to listeners.
  178. */
  179. private void updateState(DetailedState detailedState, String reason) {
  180. if (LOGD) Log.d(TAG, "setting state=" + detailedState + ", reason=" + reason);
  181. mNetworkInfo.setDetailedState(detailedState, reason, null);
  182. mCallback.onStateChanged(new NetworkInfo(mNetworkInfo));
  183. }
  184. /**
  185. * Prepare for a VPN application. This method is designed to solve
  186. * race conditions. It first compares the current prepared package
  187. * with {@code oldPackage}. If they are the same, the prepared
  188. * package is revoked and replaced with {@code newPackage}. If
  189. * {@code oldPackage} is {@code null}, the comparison is omitted.
  190. * If {@code newPackage} is the same package or {@code null}, the
  191. * revocation is omitted. This method returns {@code true} if the
  192. * operation is succeeded.
  193. *
  194. * Legacy VPN is handled specially since it is not a real package.
  195. * It uses {@link VpnConfig#LEGACY_VPN} as its package name, and
  196. * it can be revoked by itself.
  197. *
  198. * @param oldPackage The package name of the old VPN application.
  199. * @param newPackage The package name of the new VPN application.
  200. * @return true if the operation is succeeded.
  201. */
  202. public synchronized boolean prepare(String oldPackage, String newPackage) {
  203. // Return false if the package does not match.
  204. if (oldPackage != null && !oldPackage.equals(mPackage)) {
  205. return false;
  206. }
  207. // Return true if we do not need to revoke.
  208. if (newPackage == null ||
  209. (newPackage.equals(mPackage) && !newPackage.equals(VpnConfig.LEGACY_VPN))) {
  210. return true;
  211. }
  212. // Check if the caller is authorized.
  213. enforceControlPermission();
  214. // Reset the interface and hide the notification.
  215. if (mInterface != null) {
  216. final long token = Binder.clearCallingIdentity();
  217. try {
  218. mCallback.restore();
  219. final int size = mVpnUsers.size();
  220. final boolean forwardDns = (mConfig.dnsServers != null &&
  221. mConfig.dnsServers.size() != 0);
  222. for (int i = 0; i < size; i++) {
  223. int user = mVpnUsers.keyAt(i);
  224. mCallback.clearUserForwarding(mInterface, user, forwardDns);
  225. hideNotification(user);
  226. }
  227. mCallback.clearMarkedForwarding(mInterface);
  228. } finally {
  229. Binder.restoreCallingIdentity(token);
  230. }
  231. jniReset(mInterface);
  232. mInterface = null;
  233. mVpnUsers = null;
  234. }
  235. // Revoke the connection or stop LegacyVpnRunner.
  236. if (mConnection != null) {
  237. try {
  238. mConnection.mService.transact(IBinder.LAST_CALL_TRANSACTION,
  239. Parcel.obtain(), null, IBinder.FLAG_ONEWAY);
  240. } catch (Exception e) {
  241. // ignore
  242. }
  243. mContext.unbindService(mConnection);
  244. mConnection = null;
  245. } else if (mLegacyVpnRunner != null) {
  246. mLegacyVpnRunner.exit();
  247. mLegacyVpnRunner = null;
  248. }
  249. Log.i(TAG, "Switched from " + mPackage + " to " + newPackage);
  250. mPackage = newPackage;
  251. mConfig = null;
  252. updateState(DetailedState.IDLE, "prepare");
  253. return true;
  254. }
  255. /**
  256. * Protect a socket from VPN rules by binding it to the main routing table.
  257. * The socket is NOT closed by this method.
  258. *
  259. * @param socket The socket to be bound.
  260. */
  261. public void protect(ParcelFileDescriptor socket) throws Exception {
  262. PackageManager pm = mContext.getPackageManager();
  263. int appUid = pm.getPackageUid(mPackage, mUserId);
  264. if (Binder.getCallingUid() != appUid) {
  265. throw new SecurityException("Unauthorized Caller");
  266. }
  267. // protect the socket from routing rules
  268. final long token = Binder.clearCallingIdentity();
  269. try {
  270. mCallback.protect(socket);
  271. } finally {
  272. Binder.restoreCallingIdentity(token);
  273. }
  274. }
  275. /**
  276. * Establish a VPN network and return the file descriptor of the VPN
  277. * interface. This methods returns {@code null} if the application is
  278. * revoked or not prepared.
  279. *
  280. * @param config The parameters to configure the network.
  281. * @return The file descriptor of the VPN interface.
  282. */
  283. public synchronized ParcelFileDescriptor establish(VpnConfig config) {
  284. // Check if the caller is already prepared.
  285. UserManager mgr = UserManager.get(mContext);
  286. PackageManager pm = mContext.getPackageManager();
  287. ApplicationInfo app = null;
  288. try {
  289. app = AppGlobals.getPackageManager().getApplicationInfo(mPackage, 0, mUserId);
  290. if (Binder.getCallingUid() != app.uid) {
  291. return null;
  292. }
  293. } catch (Exception e) {
  294. return null;
  295. }
  296. // Check if the service is properly declared.
  297. Intent intent = new Intent(VpnConfig.SERVICE_INTERFACE);
  298. intent.setClassName(mPackage, config.user);
  299. long token = Binder.clearCallingIdentity();
  300. try {
  301. // Restricted users are not allowed to create VPNs, they are tied to Owner
  302. UserInfo user = mgr.getUserInfo(mUserId);
  303. if (user.isRestricted()) {
  304. throw new SecurityException("Restricted users cannot establish VPNs");
  305. }
  306. ResolveInfo info = AppGlobals.getPackageManager().resolveService(intent,
  307. null, 0, mUserId);
  308. if (info == null) {
  309. throw new SecurityException("Cannot find " + config.user);
  310. }
  311. if (!BIND_VPN_SERVICE.equals(info.serviceInfo.permission)) {
  312. throw new SecurityException(config.user + " does not require " + BIND_VPN_SERVICE);
  313. }
  314. } catch (RemoteException e) {
  315. throw new SecurityException("Cannot find " + config.user);
  316. } finally {
  317. Binder.restoreCallingIdentity(token);
  318. }
  319. // Save the old config in case we need to go back.
  320. VpnConfig oldConfig = mConfig;
  321. String oldInterface = mInterface;
  322. Connection oldConnection = mConnection;
  323. SparseBooleanArray oldUsers = mVpnUsers;
  324. // Configure the interface. Abort if any of these steps fails.
  325. ParcelFileDescriptor tun = ParcelFileDescriptor.adoptFd(jniCreate(config.mtu));
  326. try {
  327. updateState(DetailedState.CONNECTING, "establish");
  328. String interfaze = jniGetName(tun.getFd());
  329. // TEMP use the old jni calls until there is support for netd address setting
  330. StringBuilder builder = new StringBuilder();
  331. for (LinkAddress address : config.addresses) {
  332. builder.append(" " + address);
  333. }
  334. if (jniSetAddresses(interfaze, builder.toString()) < 1) {
  335. throw new IllegalArgumentException("At least one address must be specified");
  336. }
  337. Connection connection = new Connection();
  338. if (!mContext.bindServiceAsUser(intent, connection, Context.BIND_AUTO_CREATE,
  339. new UserHandle(mUserId))) {
  340. throw new IllegalStateException("Cannot bind " + config.user);
  341. }
  342. mConnection = connection;
  343. mInterface = interfaze;
  344. // Fill more values.
  345. config.user = mPackage;
  346. config.interfaze = mInterface;
  347. config.startTime = SystemClock.elapsedRealtime();
  348. mConfig = config;
  349. // Set up forwarding and DNS rules.
  350. mVpnUsers = new SparseBooleanArray();
  351. token = Binder.clearCallingIdentity();
  352. try {
  353. mCallback.setMarkedForwarding(mInterface);
  354. mCallback.setRoutes(mInterface, config.routes);
  355. mCallback.override(mInterface, config.dnsServers, config.searchDomains);
  356. addVpnUserLocked(mUserId);
  357. // If we are owner assign all Restricted Users to this VPN
  358. if (mUserId == UserHandle.USER_OWNER) {
  359. for (UserInfo user : mgr.getUsers()) {
  360. if (user.isRestricted()) {
  361. try {
  362. addVpnUserLocked(user.id);
  363. } catch (Exception e) {
  364. Log.wtf(TAG, "Failed to add user " + user.id + " to owner's VPN");
  365. }
  366. }
  367. }
  368. }
  369. } finally {
  370. Binder.restoreCallingIdentity(token);
  371. }
  372. if (oldConnection != null) {
  373. mContext.unbindService(oldConnection);
  374. }
  375. if (oldInterface != null && !oldInterface.equals(interfaze)) {
  376. // Remove the old tun's user forwarding rules
  377. // The new tun's user rules have already been added so they will take over
  378. // as rules are deleted. This prevents data leakage as the rules are moved over.
  379. token = Binder.clearCallingIdentity();
  380. try {
  381. final int size = oldUsers.size();
  382. final boolean forwardDns = (oldConfig.dnsServers != null &&
  383. oldConfig.dnsServers.size() != 0);
  384. for (int i = 0; i < size; i++) {
  385. int user = oldUsers.keyAt(i);
  386. mCallback.clearUserForwarding(oldInterface, user, forwardDns);
  387. }
  388. mCallback.clearMarkedForwarding(oldInterface);
  389. } finally {
  390. Binder.restoreCallingIdentity(token);
  391. }
  392. jniReset(oldInterface);
  393. }
  394. } catch (RuntimeException e) {
  395. updateState(DetailedState.FAILED, "establish");
  396. IoUtils.closeQuietly(tun);
  397. // make sure marked forwarding is cleared if it was set
  398. token = Binder.clearCallingIdentity();
  399. try {
  400. mCallback.clearMarkedForwarding(mInterface);
  401. } catch (Exception ingored) {
  402. // ignored
  403. } finally {
  404. Binder.restoreCallingIdentity(token);
  405. }
  406. // restore old state
  407. mConfig = oldConfig;
  408. mConnection = oldConnection;
  409. mVpnUsers = oldUsers;
  410. mInterface = oldInterface;
  411. throw e;
  412. }
  413. Log.i(TAG, "Established by " + config.user + " on " + mInterface);
  414. // TODO: ensure that contract class eventually marks as connected
  415. updateState(DetailedState.AUTHENTICATING, "establish");
  416. return tun;
  417. }
  418. /**
  419. * Check if a given address is covered by the VPN's routing rules.
  420. */
  421. public boolean isAddressCovered(InetAddress address) {
  422. synchronized (Vpn.this) {
  423. if (!isRunningLocked()) {
  424. return false;
  425. }
  426. return RouteInfo.selectBestRoute(mConfig.routes, address) != null;
  427. }
  428. }
  429. private boolean isRunningLocked() {
  430. return mVpnUsers != null;
  431. }
  432. private void addVpnUserLocked(int user) {
  433. enforceControlPermission();
  434. if (!isRunningLocked()) {
  435. throw new IllegalStateException("VPN is not active");
  436. }
  437. final boolean forwardDns = (mConfig.dnsServers != null &&
  438. mConfig.dnsServers.size() != 0);
  439. // add the user
  440. mCallback.addUserForwarding(mInterface, user, forwardDns);
  441. mVpnUsers.put(user, true);
  442. // show the notification
  443. if (!mPackage.equals(VpnConfig.LEGACY_VPN)) {
  444. // Load everything for the user's notification
  445. PackageManager pm = mContext.getPackageManager();
  446. ApplicationInfo app = null;
  447. try {
  448. app = AppGlobals.getPackageManager().getApplicationInfo(mPackage, 0, mUserId);
  449. } catch (RemoteException e) {
  450. throw new IllegalStateException("Invalid application");
  451. }
  452. String label = app.loadLabel(pm).toString();
  453. // Load the icon and convert it into a bitmap.
  454. Drawable icon = app.loadIcon(pm);
  455. Bitmap bitmap = null;
  456. if (icon.getIntrinsicWidth() > 0 && icon.getIntrinsicHeight() > 0) {
  457. int width = mContext.getResources().getDimensionPixelSize(
  458. android.R.dimen.notification_large_icon_width);
  459. int height = mContext.getResources().getDimensionPixelSize(
  460. android.R.dimen.notification_large_icon_height);
  461. icon.setBounds(0, 0, width, height);
  462. bitmap = Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888);
  463. Canvas c = new Canvas(bitmap);
  464. icon.draw(c);
  465. c.setBitmap(null);
  466. }
  467. showNotification(label, bitmap, user);
  468. } else {
  469. showNotification(null, null, user);
  470. }
  471. }
  472. private void removeVpnUserLocked(int user) {
  473. enforceControlPermission();
  474. if (!isRunningLocked()) {
  475. throw new IllegalStateException("VPN is not active");
  476. }
  477. final boolean forwardDns = (mConfig.dnsServers != null &&
  478. mConfig.dnsServers.size() != 0);
  479. mCallback.clearUserForwarding(mInterface, user, forwardDns);
  480. mVpnUsers.delete(user);
  481. hideNotification(user);
  482. }
  483. private void onUserAdded(int userId) {
  484. // If the user is restricted tie them to the owner's VPN
  485. synchronized(Vpn.this) {
  486. UserManager mgr = UserManager.get(mContext);
  487. UserInfo user = mgr.getUserInfo(userId);
  488. if (user.isRestricted()) {
  489. try {
  490. addVpnUserLocked(userId);
  491. } catch (Exception e) {
  492. Log.wtf(TAG, "Failed to add restricted user to owner", e);
  493. }
  494. }
  495. }
  496. }
  497. private void onUserRemoved(int userId) {
  498. // clean up if restricted
  499. synchronized(Vpn.this) {
  500. UserManager mgr = UserManager.get(mContext);
  501. UserInfo user = mgr.getUserInfo(userId);
  502. if (user.isRestricted()) {
  503. try {
  504. removeVpnUserLocked(userId);
  505. } catch (Exception e) {
  506. Log.wtf(TAG, "Failed to remove restricted user to owner", e);
  507. }
  508. }
  509. }
  510. }
  511. /**
  512. * Return the configuration of the currently running VPN.
  513. */
  514. public VpnConfig getVpnConfig() {
  515. enforceControlPermission();
  516. return mConfig;
  517. }
  518. @Deprecated
  519. public synchronized void interfaceStatusChanged(String iface, boolean up) {
  520. try {
  521. mObserver.interfaceStatusChanged(iface, up);
  522. } catch (RemoteException e) {
  523. // ignored; target is local
  524. }
  525. }
  526. private INetworkManagementEventObserver mObserver = new BaseNetworkObserver() {
  527. @Override
  528. public void interfaceStatusChanged(String interfaze, boolean up) {
  529. synchronized (Vpn.this) {
  530. if (!up && mLegacyVpnRunner != null) {
  531. mLegacyVpnRunner.check(interfaze);
  532. }
  533. }
  534. }
  535. @Override
  536. public void interfaceRemoved(String interfaze) {
  537. synchronized (Vpn.this) {
  538. if (interfaze.equals(mInterface) && jniCheck(interfaze) == 0) {
  539. final long token = Binder.clearCallingIdentity();
  540. try {
  541. final int size = mVpnUsers.size();
  542. final boolean forwardDns = (mConfig.dnsServers != null &&
  543. mConfig.dnsServers.size() != 0);
  544. for (int i = 0; i < size; i++) {
  545. int user = mVpnUsers.keyAt(i);
  546. mCallback.clearUserForwarding(mInterface, user, forwardDns);
  547. hideNotification(user);
  548. }
  549. mVpnUsers = null;
  550. mCallback.clearMarkedForwarding(mInterface);
  551. mCallback.restore();
  552. } finally {
  553. Binder.restoreCallingIdentity(token);
  554. }
  555. mInterface = null;
  556. if (mConnection != null) {
  557. mContext.unbindService(mConnection);
  558. mConnection = null;
  559. updateState(DetailedState.DISCONNECTED, "interfaceRemoved");
  560. } else if (mLegacyVpnRunner != null) {
  561. mLegacyVpnRunner.exit();
  562. mLegacyVpnRunner = null;
  563. }
  564. }
  565. }
  566. }
  567. };
  568. private void enforceControlPermission() {
  569. // System user is allowed to control VPN.
  570. if (Binder.getCallingUid() == Process.SYSTEM_UID) {
  571. return;
  572. }
  573. int appId = UserHandle.getAppId(Binder.getCallingUid());
  574. final long token = Binder.clearCallingIdentity();
  575. try {
  576. // System VPN dialogs are also allowed to control VPN.
  577. PackageManager pm = mContext.getPackageManager();
  578. ApplicationInfo app = pm.getApplicationInfo(VpnConfig.DIALOGS_PACKAGE, 0);
  579. if (((app.flags & ApplicationInfo.FLAG_SYSTEM) != 0) && (appId == app.uid)) {
  580. return;
  581. }
  582. } catch (Exception e) {
  583. // ignore
  584. } finally {
  585. Binder.restoreCallingIdentity(token);
  586. }
  587. throw new SecurityException("Unauthorized Caller");
  588. }
  589. private class Connection implements ServiceConnection {
  590. private IBinder mService;
  591. @Override
  592. public void onServiceConnected(ComponentName name, IBinder service) {
  593. mService = service;
  594. }
  595. @Override
  596. public void onServiceDisconnected(ComponentName name) {
  597. mService = null;
  598. }
  599. }
  600. private void showNotification(String label, Bitmap icon, int user) {
  601. if (!mEnableNotif) return;
  602. mStatusIntent = VpnConfig.getIntentForStatusPanel(mContext);
  603. NotificationManager nm = (NotificationManager)
  604. mContext.getSystemService(Context.NOTIFICATION_SERVICE);
  605. if (nm != null) {
  606. String title = (label == null) ? mContext.getString(R.string.vpn_title) :
  607. mContext.getString(R.string.vpn_title_long, label);
  608. String text = (mConfig.session == null) ? mContext.getString(R.string.vpn_text) :
  609. mContext.getString(R.string.vpn_text_long, mConfig.session);
  610. Notification notification = new Notification.Builder(mContext)
  611. .setSmallIcon(R.drawable.vpn_connected)
  612. .setLargeIcon(icon)
  613. .setContentTitle(title)
  614. .setContentText(text)
  615. .setContentIntent(mStatusIntent)
  616. .setDefaults(0)
  617. .setOngoing(true)
  618. .build();
  619. nm.notifyAsUser(null, R.drawable.vpn_connected, notification, new UserHandle(user));
  620. }
  621. }
  622. private void hideNotification(int user) {
  623. if (!mEnableNotif) return;
  624. mStatusIntent = null;
  625. NotificationManager nm = (NotificationManager)
  626. mContext.getSystemService(Context.NOTIFICATION_SERVICE);
  627. if (nm != null) {
  628. nm.cancelAsUser(null, R.drawable.vpn_connected, new UserHandle(user));
  629. }
  630. }
  631. private native int jniCreate(int mtu);
  632. private native String jniGetName(int tun);
  633. private native int jniSetAddresses(String interfaze, String addresses);
  634. private native int jniSetRoutes(String interfaze, String routes);
  635. private native void jniReset(String interfaze);
  636. private native int jniCheck(String interfaze);
  637. private static RouteInfo findIPv4DefaultRoute(LinkProperties prop) {
  638. for (RouteInfo route : prop.getAllRoutes()) {
  639. // Currently legacy VPN only works on IPv4.
  640. if (route.isDefaultRoute() && route.getGateway() instanceof Inet4Address) {
  641. return route;
  642. }
  643. }
  644. throw new IllegalStateException("Unable to find IPv4 default gateway");
  645. }
  646. /**
  647. * Start legacy VPN, controlling native daemons as needed. Creates a
  648. * secondary thread to perform connection work, returning quickly.
  649. */
  650. public void startLegacyVpn(VpnProfile profile, KeyStore keyStore, LinkProperties egress) {
  651. enforceControlPermission();
  652. if (!keyStore.isUnlocked()) {
  653. throw new IllegalStateException("KeyStore isn't unlocked");
  654. }
  655. final RouteInfo ipv4DefaultRoute = findIPv4DefaultRoute(egress);
  656. final String gateway = ipv4DefaultRoute.getGateway().getHostAddress();
  657. final String iface = ipv4DefaultRoute.getInterface();
  658. // Load certificates.
  659. String privateKey = "";
  660. String userCert = "";
  661. String caCert = "";
  662. String serverCert = "";
  663. if (!profile.ipsecUserCert.isEmpty()) {
  664. privateKey = Credentials.USER_PRIVATE_KEY + profile.ipsecUserCert;
  665. byte[] value = keyStore.get(Credentials.USER_CERTIFICATE + profile.ipsecUserCert);
  666. userCert = (value == null) ? null : new String(value, StandardCharsets.UTF_8);
  667. }
  668. if (!profile.ipsecCaCert.isEmpty()) {
  669. byte[] value = keyStore.get(Credentials.CA_CERTIFICATE + profile.ipsecCaCert);
  670. caCert = (value == null) ? null : new String(value, StandardCharsets.UTF_8);
  671. }
  672. if (!profile.ipsecServerCert.isEmpty()) {
  673. byte[] value = keyStore.get(Credentials.USER_CERTIFICATE + profile.ipsecServerCert);
  674. serverCert = (value == null) ? null : new String(value, StandardCharsets.UTF_8);
  675. }
  676. if (privateKey == null || userCert == null || caCert == null || serverCert == null) {
  677. throw new IllegalStateException("Cannot load credentials");
  678. }
  679. // Prepare arguments for racoon.
  680. String[] racoon = null;
  681. switch (profile.type) {
  682. case VpnProfile.TYPE_L2TP_IPSEC_PSK:
  683. racoon = new String[] {
  684. iface, profile.server, "udppsk", profile.ipsecIdentifier,
  685. profile.ipsecSecret, "1701",
  686. };
  687. break;
  688. case VpnProfile.TYPE_L2TP_IPSEC_RSA:
  689. racoon = new String[] {
  690. iface, profile.server, "udprsa", privateKey, userCert,
  691. caCert, serverCert, "1701",
  692. };
  693. break;
  694. case VpnProfile.TYPE_IPSEC_XAUTH_PSK:
  695. racoon = new String[] {
  696. iface, profile.server, "xauthpsk", profile.ipsecIdentifier,
  697. profile.ipsecSecret, profile.username, profile.password, "", gateway,
  698. };
  699. break;
  700. case VpnProfile.TYPE_IPSEC_XAUTH_RSA:
  701. racoon = new String[] {
  702. iface, profile.server, "xauthrsa", privateKey, userCert,
  703. caCert, serverCert, profile.username, profile.password, "", gateway,
  704. };
  705. break;
  706. case VpnProfile.TYPE_IPSEC_HYBRID_RSA:
  707. racoon = new String[] {
  708. iface, profile.server, "hybridrsa",
  709. caCert, serverCert, profile.username, profile.password, "", gateway,
  710. };
  711. break;
  712. }
  713. // Prepare arguments for mtpd.
  714. String[] mtpd = null;
  715. switch (profile.type) {
  716. case VpnProfile.TYPE_PPTP:
  717. mtpd = new String[] {
  718. iface, "pptp", profile.server, "1723",
  719. "name", profile.username, "password", profile.password,
  720. "linkname", "vpn", "refuse-eap", "nodefaultroute",
  721. "usepeerdns", "idle", "1800", "mtu", "1400", "mru", "1400",
  722. (profile.mppe ? "+mppe" : "nomppe"),
  723. };
  724. break;
  725. case VpnProfile.TYPE_L2TP_IPSEC_PSK:
  726. case VpnProfile.TYPE_L2TP_IPSEC_RSA:
  727. mtpd = new String[] {
  728. iface, "l2tp", profile.server, "1701", profile.l2tpSecret,
  729. "name", profile.username, "password", profile.password,
  730. "linkname", "vpn", "refuse-eap", "nodefaultroute",
  731. "usepeerdns", "idle", "1800", "mtu", "1400", "mru", "1400",
  732. };
  733. break;
  734. }
  735. VpnConfig config = new VpnConfig();
  736. config.legacy = true;
  737. config.user = profile.key;
  738. config.interfaze = iface;
  739. config.session = profile.name;
  740. config.addLegacyRoutes(profile.routes);
  741. if (!profile.dnsServers.isEmpty()) {
  742. config.dnsServers = Arrays.asList(profile.dnsServers.split(" +"));
  743. }
  744. if (!profile.searchDomains.isEmpty()) {
  745. config.searchDomains = Arrays.asList(profile.searchDomains.split(" +"));
  746. }
  747. startLegacyVpn(config, racoon, mtpd);
  748. }
  749. private synchronized void startLegacyVpn(VpnConfig config, String[] racoon, String[] mtpd) {
  750. stopLegacyVpn();
  751. // Prepare for the new request. This also checks the caller.
  752. prepare(null, VpnConfig.LEGACY_VPN);
  753. updateState(DetailedState.CONNECTING, "startLegacyVpn");
  754. // Start a new LegacyVpnRunner and we are done!
  755. mLegacyVpnRunner = new LegacyVpnRunner(config, racoon, mtpd);
  756. mLegacyVpnRunner.start();
  757. }
  758. public synchronized void stopLegacyVpn() {
  759. if (mLegacyVpnRunner != null) {
  760. mLegacyVpnRunner.exit();
  761. mLegacyVpnRunner = null;
  762. synchronized (LegacyVpnRunner.TAG) {
  763. // wait for old thread to completely finish before spinning up
  764. // new instance, otherwise state updates can be out of order.
  765. }
  766. }
  767. }
  768. /**
  769. * Return the information of the current ongoing legacy VPN.
  770. */
  771. public synchronized LegacyVpnInfo getLegacyVpnInfo() {
  772. // Check if the caller is authorized.
  773. enforceControlPermission();
  774. if (mLegacyVpnRunner == null) return null;
  775. final LegacyVpnInfo info = new LegacyVpnInfo();
  776. info.key = mConfig.user;
  777. info.state = LegacyVpnInfo.stateFromNetworkInfo(mNetworkInfo);
  778. if (mNetworkInfo.isConnected()) {
  779. info.intent = mStatusIntent;
  780. }
  781. return info;
  782. }
  783. public VpnConfig getLegacyVpnConfig() {
  784. if (mLegacyVpnRunner != null) {
  785. return mConfig;
  786. } else {
  787. return null;
  788. }
  789. }
  790. /**
  791. * Bringing up a VPN connection takes time, and that is all this thread
  792. * does. Here we have plenty of time. The only thing we need to take
  793. * care of is responding to interruptions as soon as possible. Otherwise
  794. * requests will be piled up. This can be done in a Handler as a state
  795. * machine, but it is much easier to read in the current form.
  796. */
  797. private class LegacyVpnRunner extends Thread {
  798. private static final String TAG = "LegacyVpnRunner";
  799. private final String[] mDaemons;
  800. private final String[][] mArguments;
  801. private final LocalSocket[] mSockets;
  802. private final String mOuterInterface;
  803. private final AtomicInteger mOuterConnection =
  804. new AtomicInteger(ConnectivityManager.TYPE_NONE);
  805. private long mTimer = -1;
  806. /**
  807. * Watch for the outer connection (passing in the constructor) going away.
  808. */
  809. private final BroadcastReceiver mBroadcastReceiver = new BroadcastReceiver() {
  810. @Override
  811. public void onReceive(Context context, Intent intent) {
  812. if (!mEnableTeardown) return;
  813. if (intent.getAction().equals(ConnectivityManager.CONNECTIVITY_ACTION)) {
  814. if (intent.getIntExtra(ConnectivityManager.EXTRA_NETWORK_TYPE,
  815. ConnectivityManager.TYPE_NONE) == mOuterConnection.get()) {
  816. NetworkInfo info = (NetworkInfo)intent.getExtra(
  817. ConnectivityManager.EXTRA_NETWORK_INFO);
  818. if (info != null && !info.isConnectedOrConnecting()) {
  819. try {
  820. mObserver.interfaceStatusChanged(mOuterInterface, false);
  821. } catch (RemoteException e) {}
  822. }
  823. }
  824. }
  825. }
  826. };
  827. public LegacyVpnRunner(VpnConfig config, String[] racoon, String[] mtpd) {
  828. super(TAG);
  829. mConfig = config;
  830. mDaemons = new String[] {"racoon", "mtpd"};
  831. // TODO: clear arguments from memory once launched
  832. mArguments = new String[][] {racoon, mtpd};
  833. mSockets = new LocalSocket[mDaemons.length];
  834. // This is the interface which VPN is running on,
  835. // mConfig.interfaze will change to point to OUR
  836. // internal interface soon. TODO - add inner/outer to mconfig
  837. // TODO - we have a race - if the outer iface goes away/disconnects before we hit this
  838. // we will leave the VPN up. We should check that it's still there/connected after
  839. // registering
  840. mOuterInterface = mConfig.interfaze;
  841. try {
  842. mOuterConnection.set(
  843. mConnService.findConnectionTypeForIface(mOuterInterface));
  844. } catch (Exception e) {
  845. mOuterConnection.set(ConnectivityManager.TYPE_NONE);
  846. }
  847. IntentFilter filter = new IntentFilter();
  848. filter.addAction(ConnectivityManager.CONNECTIVITY_ACTION);
  849. mContext.registerReceiver(mBroadcastReceiver, filter);
  850. }
  851. public void check(String interfaze) {
  852. if (interfaze.equals(mOuterInterface)) {
  853. Log.i(TAG, "Legacy VPN is going down with " + interfaze);
  854. exit();
  855. }
  856. }
  857. public void exit() {
  858. // We assume that everything is reset after stopping the daemons.
  859. interrupt();
  860. for (LocalSocket socket : mSockets) {
  861. IoUtils.closeQuietly(socket);
  862. }
  863. updateState(DetailedState.DISCONNECTED, "exit");
  864. try {
  865. mContext.unregisterReceiver(mBroadcastReceiver);
  866. } catch (IllegalArgumentException e) {}
  867. }
  868. @Override
  869. public void run() {
  870. // Wait for the previous thread since it has been interrupted.
  871. Log.v(TAG, "Waiting");
  872. synchronized (TAG) {
  873. Log.v(TAG, "Executing");
  874. execute();
  875. monitorDaemons();
  876. }
  877. }
  878. private void checkpoint(boolean yield) throws InterruptedException {
  879. long now = SystemClock.elapsedRealtime();
  880. if (mTimer == -1) {
  881. mTimer = now;
  882. Thread.sleep(1);
  883. } else if (now - mTimer <= 60000) {
  884. Thread.sleep(yield ? 200 : 1);
  885. } else {
  886. updateState(DetailedState.FAILED, "checkpoint");
  887. throw new IllegalStateException("Time is up");
  888. }
  889. }
  890. private void execute() {
  891. // Catch all exceptions so we can clean up few things.
  892. boolean initFinished = false;
  893. try {
  894. // Initialize the timer.
  895. checkpoint(false);
  896. // Wait for the daemons to stop.
  897. for (String daemon : mDaemons) {
  898. while (!SystemService.isStopped(daemon)) {
  899. checkpoint(true);
  900. }
  901. }
  902. // Clear the previous state.
  903. File state = new File("/data/misc/vpn/state");
  904. state.delete();
  905. if (state.exists()) {
  906. throw new IllegalStateException("Cannot delete the state");
  907. }
  908. new File("/data/misc/vpn/abort").delete();
  909. initFinished = true;
  910. // Check if we need to restart any of the daemons.
  911. boolean restart = false;
  912. for (String[] arguments : mArguments) {
  913. restart = restart || (arguments != null);
  914. }
  915. if (!restart) {
  916. updateState(DetailedState.DISCONNECTED, "execute");
  917. return;
  918. }
  919. updateState(DetailedState.CONNECTING, "execute");
  920. // Start the daemon with arguments.
  921. for (int i = 0; i < mDaemons.length; ++i) {
  922. String[] arguments = mArguments[i];
  923. if (arguments == null) {
  924. continue;
  925. }
  926. // Start the daemon.
  927. String daemon = mDaemons[i];
  928. SystemService.start(daemon);
  929. // Wait for the daemon to start.
  930. while (!SystemService.isRunning(daemon)) {
  931. checkpoint(true);
  932. }
  933. // Create the control socket.
  934. mSockets[i] = new LocalSocket();
  935. LocalSocketAddress address = new LocalSocketAddress(
  936. daemon, LocalSocketAddress.Namespace.RESERVED);
  937. // Wait for the socket to connect.
  938. while (true) {
  939. try {
  940. mSockets[i].connect(address);
  941. break;
  942. } catch (Exception e) {
  943. // ignore
  944. }
  945. checkpoint(true);
  946. }
  947. mSockets[i].setSoTimeout(500);
  948. // Send over the arguments.
  949. OutputStream out = mSockets[i].getOutputStream();
  950. for (String argument : arguments) {
  951. byte[] bytes = argument.getBytes(StandardCharsets.UTF_8);
  952. if (bytes.length >= 0xFFFF) {
  953. throw new IllegalArgumentException("Argument is too large");
  954. }
  955. out.write(bytes.length >> 8);
  956. out.write(bytes.length);
  957. out.write(bytes);
  958. checkpoint(false);
  959. }
  960. out.write(0xFF);
  961. out.write(0xFF);
  962. out.flush();
  963. // Wait for End-of-File.
  964. InputStream in = mSockets[i].getInputStream();
  965. while (true) {
  966. try {
  967. if (in.read() == -1) {
  968. break;
  969. }
  970. } catch (Exception e) {
  971. // ignore
  972. }
  973. checkpoint(true);
  974. }
  975. }
  976. // Wait for the daemons to create the new state.
  977. while (!state.exists()) {
  978. // Check if a running daemon is dead.
  979. for (int i = 0; i < mDaemons.length; ++i) {
  980. String daemon = mDaemons[i];
  981. if (mArguments[i] != null && !SystemService.isRunning(daemon)) {
  982. throw new IllegalStateException(daemon + " is dead");
  983. }
  984. }
  985. checkpoint(true);
  986. }
  987. // Now we are connected. Read and parse the new state.
  988. String[] parameters = FileUtils.readTextFile(state, 0, null).split("\n", -1);
  989. if (parameters.length != 6) {
  990. throw new IllegalStateException("Cannot parse the state");
  991. }
  992. // Set the interface and the addresses in the config.
  993. mConfig.interfaze = parameters[0].trim();
  994. mConfig.addLegacyAddresses(parameters[1]);
  995. // Set the routes if they are not set in the config.
  996. if (mConfig.routes == null || mConfig.routes.isEmpty()) {
  997. mConfig.addLegacyRoutes(parameters[2]);
  998. }
  999. // Set the DNS servers if they are not set in the config.
  1000. if (mConfig.dnsServers == null || mConfig.dnsServers.size() == 0) {
  1001. String dnsServers = parameters[3].trim();
  1002. if (!dnsServers.isEmpty()) {
  1003. mConfig.dnsServers = Arrays.asList(dnsServers.split(" "));
  1004. }
  1005. }
  1006. // Set the search domains if they are not set in the config.
  1007. if (mConfig.searchDomains == null || mConfig.searchDomains.size() == 0) {
  1008. String searchDomains = parameters[4].trim();
  1009. if (!searchDomains.isEmpty()) {
  1010. mConfig.searchDomains = Arrays.asList(searchDomains.split(" "));
  1011. }
  1012. }
  1013. // Set the routes.
  1014. long token = Binder.clearCallingIdentity();
  1015. try {
  1016. mCallback.setMarkedForwarding(mConfig.interfaze);
  1017. mCallback.setRoutes(mConfig.interfaze, mConfig.routes);
  1018. } finally {
  1019. Binder.restoreCallingIdentity(token);
  1020. }
  1021. // Here is the last step and it must be done synchronously.
  1022. synchronized (Vpn.this) {
  1023. // Set the start time
  1024. mConfig.startTime = SystemClock.elapsedRealtime();
  1025. // Check if the thread is interrupted while we are waiting.
  1026. checkpoint(false);
  1027. // Check if the interface is gone while we are waiting.
  1028. if (jniCheck(mConfig.interfaze) == 0) {
  1029. throw new IllegalStateException(mConfig.interfaze + " is gone");
  1030. }
  1031. // Now INetworkManagementEventObserver is watching our back.
  1032. mInterface = mConfig.interfaze;
  1033. mVpnUsers = new SparseBooleanArray();
  1034. token = Binder.clearCallingIdentity();
  1035. try {
  1036. mCallback.override(mInterface, mConfig.dnsServers, mConfig.searchDomains);
  1037. addVpnUserLocked(mUserId);
  1038. } finally {
  1039. Binder.restoreCallingIdentity(token);
  1040. }
  1041. // Assign all restircted users to this VPN
  1042. // (Legacy VPNs are Owner only)
  1043. UserManager mgr = UserManager.get(mContext);
  1044. token = Binder.clearCallingIdentity();
  1045. try {
  1046. for (UserInfo user : mgr.getUsers()) {
  1047. if (user.isRestricted()) {
  1048. try {
  1049. addVpnUserLocked(user.id);
  1050. } catch (Exception e) {
  1051. Log.wtf(TAG, "Failed to add user " + user.id
  1052. + " to owner's VPN");
  1053. }
  1054. }
  1055. }
  1056. } finally {
  1057. Binder.restoreCallingIdentity(token);
  1058. }
  1059. Log.i(TAG, "Connected!");
  1060. updateState(DetailedState.CONNECTED, "execute");
  1061. }
  1062. } catch (Exception e) {
  1063. Log.i(TAG, "Aborting", e);
  1064. // make sure the routing is cleared
  1065. try {
  1066. mCallback.clearMarkedForwarding(mConfig.interfaze);
  1067. } catch (Exception ignored) {
  1068. }
  1069. exit();
  1070. } finally {
  1071. // Kill the daemons if they fail to stop.
  1072. if (!initFinished) {
  1073. for (String daemon : mDaemons) {
  1074. SystemService.stop(daemon);
  1075. }
  1076. }
  1077. // Do not leave an unstable state.
  1078. if (!initFinished || mNetworkInfo.getDetailedState() == DetailedState.CONNECTING) {
  1079. updateState(DetailedState.FAILED, "execute");
  1080. }
  1081. }
  1082. }
  1083. /**
  1084. * Monitor the daemons we started, moving to disconnected state if the
  1085. * underlying services fail.
  1086. */
  1087. private void monitorDaemons() {
  1088. if (!mNetworkInfo.isConnected()) {
  1089. return;
  1090. }
  1091. try {
  1092. while (true) {
  1093. Thread.sleep(2000);
  1094. for (int i = 0; i < mDaemons.length; i++) {
  1095. if (mArguments[i] != null && SystemService.isStopped(mDaemons[i])) {
  1096. return;
  1097. }
  1098. }
  1099. }
  1100. } catch (InterruptedException e) {
  1101. Log.d(TAG, "interrupted during monitorDaemons(); stopping services");
  1102. } finally {
  1103. for (String daemon : mDaemons) {
  1104. SystemService.stop(daemon);
  1105. }
  1106. updateState(DetailedState.DISCONNECTED, "babysit");
  1107. }
  1108. }
  1109. }
  1110. }