@TargetApi(Build.VERSION_CODES.LOLLIPOP)
  private void setAllowedVpnPackages(Builder builder) {
    boolean atLeastOneAllowedApp = false;
    for (String pkg : mProfile.mAllowedAppsVpn) {
      try {
        if (mProfile.mAllowedAppsVpnAreDisallowed) {
          builder.addDisallowedApplication(pkg);
        } else {
          builder.addAllowedApplication(pkg);
          atLeastOneAllowedApp = true;
        }
      } catch (PackageManager.NameNotFoundException e) {
        mProfile.mAllowedAppsVpn.remove(pkg);
        VpnStatus.logInfo(R.string.app_no_longer_exists, pkg);
      }
    }

    if (!mProfile.mAllowedAppsVpnAreDisallowed && !atLeastOneAllowedApp) {
      VpnStatus.logDebug(R.string.no_allowed_app, getPackageName());
      try {
        builder.addAllowedApplication(getPackageName());
      } catch (PackageManager.NameNotFoundException e) {
        VpnStatus.logError("This should not happen: " + e.getLocalizedMessage());
      }
    }

    if (mProfile.mAllowedAppsVpnAreDisallowed) {
      VpnStatus.logDebug(
          R.string.disallowed_vpn_apps_info, TextUtils.join(", ", mProfile.mAllowedAppsVpn));
    } else {
      VpnStatus.logDebug(
          R.string.allowed_vpn_apps_info, TextUtils.join(", ", mProfile.mAllowedAppsVpn));
    }
  }
Exemple #2
0
  private ParcelFileDescriptor startVPN() {
    Log.i(TAG, "Starting");

    // Check state
    boolean wifi = Util.isWifiActive(this);
    boolean metered = Util.isMetered(this);
    boolean interactive = Util.isInteractive(this);
    Log.i(
        TAG,
        "wifi="
            + wifi
            + " metered="
            + metered
            + " roaming="
            + last_roaming
            + " interactive="
            + interactive);

    // Build VPN service
    final Builder builder = new Builder();
    builder.setSession(getString(R.string.app_name));
    // TODO: make tunnel parameters configurable
    builder.addAddress("10.1.10.1", 32);
    builder.addAddress("fd00:1:fd00:1:fd00:1:fd00:1", 64);
    builder.addRoute("0.0.0.0", 0);
    builder.addRoute("0:0:0:0:0:0:0:0", 0);

    // Add list of allowed applications
    for (Rule rule : Rule.getRules(true, TAG, this)) {
      boolean blocked = (metered ? rule.other_blocked : rule.wifi_blocked);
      if ((!blocked || (rule.unused && interactive))
          && (!metered || !(rule.roaming && last_roaming))) {
        if (debug) Log.i(TAG, "Allowing " + rule.info.packageName);
        try {
          builder.addDisallowedApplication(rule.info.packageName);
        } catch (PackageManager.NameNotFoundException ex) {
          Log.e(TAG, ex.toString() + "\n" + Log.getStackTraceString(ex));
        }
      }
    }

    // Build configure intent
    Intent configure = new Intent(this, ActivityMain.class);
    PendingIntent pi =
        PendingIntent.getActivity(this, 0, configure, PendingIntent.FLAG_UPDATE_CURRENT);
    builder.setConfigureIntent(pi);

    if (debug) builder.setBlocking(true);

    // Start VPN service
    try {
      return builder.establish();

    } catch (Throwable ex) {
      Log.e(TAG, ex.toString() + "\n" + Log.getStackTraceString(ex));

      // Disable firewall
      SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(this);
      prefs.edit().putBoolean("enabled", false).apply();

      // Feedback
      Util.toast(ex.toString(), Toast.LENGTH_LONG, this);
      Widget.updateWidgets(this);

      return null;
    }
  }
  private ParcelFileDescriptor startVPN() {
    SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(this);

    // Check state
    boolean wifi = Util.isWifiActive(this);
    boolean metered = Util.isMeteredNetwork(this);
    boolean useMetered = prefs.getBoolean("use_metered", false);
    Set<String> ssidHomes = prefs.getStringSet("wifi_homes", new HashSet<String>());
    String ssidNetwork = Util.getWifiSSID(this);
    String generation = Util.getNetworkGeneration(this);
    boolean unmetered_2g = prefs.getBoolean("unmetered_2g", false);
    boolean unmetered_3g = prefs.getBoolean("unmetered_3g", false);
    boolean unmetered_4g = prefs.getBoolean("unmetered_4g", false);
    boolean roaming = Util.isRoaming(SinkholeService.this);
    boolean national = prefs.getBoolean("national_roaming", false);
    boolean telephony = Util.hasTelephony(this);

    // Update connected state
    last_connected = Util.isConnected(SinkholeService.this);

    // Update metered state
    if (wifi && (!useMetered || !telephony)) metered = false;
    if (wifi && ssidHomes.size() > 0 && !ssidHomes.contains(ssidNetwork)) metered = true;
    if (unmetered_2g && "2G".equals(generation)) metered = false;
    if (unmetered_3g && "3G".equals(generation)) metered = false;
    if (unmetered_4g && "4G".equals(generation)) metered = false;
    if (!last_connected) metered = true;
    last_metered = metered;

    // Update roaming state
    if (roaming && national) roaming = Util.isInternational(this);

    Log.i(
        TAG,
        "Starting connected="
            + last_connected
            + " wifi="
            + wifi
            + " metered="
            + metered
            + " telephony="
            + telephony
            + " generation="
            + generation
            + " roaming="
            + roaming
            + " interactive="
            + last_interactive);

    // Build VPN service
    final Builder builder = new Builder();
    builder.setSession(getString(R.string.app_name) + " session");
    // TODO: make tunnel parameters configurable
    builder.addAddress("10.1.10.1", 32);
    builder.addAddress("fd00:1:fd00:1:fd00:1:fd00:1", 64);
    builder.addRoute("0.0.0.0", 0);
    builder.addRoute("0:0:0:0:0:0:0:0", 0);

    // Add list of allowed applications
    int nAllowed = 0;
    int nBlocked = 0;
    for (Rule rule : Rule.getRules(true, TAG, this)) {
      boolean blocked = (metered ? rule.other_blocked : rule.wifi_blocked);
      boolean screen = (metered ? rule.screen_other : rule.screen_wifi);
      if ((!blocked || (screen && last_interactive)) && (!metered || !(rule.roaming && roaming))) {
        nAllowed++;
        if (debug) Log.i(TAG, "Allowing " + rule.info.packageName);
        try {
          builder.addDisallowedApplication(rule.info.packageName);
        } catch (PackageManager.NameNotFoundException ex) {
          Log.e(TAG, ex.toString() + "\n" + Log.getStackTraceString(ex));
          Util.sendCrashReport(ex, this);
        }
      } else nBlocked++;
    }
    Log.i(TAG, "Allowed=" + nAllowed + " blocked=" + nBlocked);

    // Update notification
    Notification notification = getForegroundNotification(nAllowed, nBlocked);
    NotificationManager nm = (NotificationManager) getSystemService(NOTIFICATION_SERVICE);
    nm.notify(NOTIFY_FOREGROUND, notification);

    // Build configure intent
    Intent configure = new Intent(this, ActivityMain.class);
    PendingIntent pi =
        PendingIntent.getActivity(this, 0, configure, PendingIntent.FLAG_UPDATE_CURRENT);
    builder.setConfigureIntent(pi);

    if (debug) builder.setBlocking(true);

    // Start VPN service
    return builder.establish();
  }