summaryrefslogtreecommitdiff
path: root/main
diff options
context:
space:
mode:
authorArne Schwabe <arne@rfc2549.org>2023-05-08 22:45:38 +0200
committerArne Schwabe <arne@rfc2549.org>2023-05-09 12:22:56 +0200
commit2bb04a1f0cad2570845a96db4d1e30c441b16d09 (patch)
treecaa72cde85284274871192d6f8f77283c6ecec61 /main
parent8bb986f5149f1efdece68eec329b693795d8cf75 (diff)
Allow setting remote control apps via managed configuration
Closes ##1610 Signed-off-by: Arne Schwabe <arne@rfc2549.org>
Diffstat (limited to 'main')
-rw-r--r--main/src/main/java/de/blinkt/openvpn/api/AppRestrictions.java67
-rw-r--r--main/src/main/java/de/blinkt/openvpn/api/ExternalAppDatabase.java48
-rw-r--r--main/src/main/java/de/blinkt/openvpn/core/OpenVPNService.java6
-rw-r--r--main/src/main/res/values/untranslatable.xml5
-rw-r--r--main/src/main/res/xml/app_restrictions.xml66
-rw-r--r--main/src/ui/java/de/blinkt/openvpn/fragments/GeneralSettings.kt4
6 files changed, 152 insertions, 44 deletions
diff --git a/main/src/main/java/de/blinkt/openvpn/api/AppRestrictions.java b/main/src/main/java/de/blinkt/openvpn/api/AppRestrictions.java
index bdab3be3..8a5d1c71 100644
--- a/main/src/main/java/de/blinkt/openvpn/api/AppRestrictions.java
+++ b/main/src/main/java/de/blinkt/openvpn/api/AppRestrictions.java
@@ -14,6 +14,7 @@ import android.text.TextUtils;
import de.blinkt.openvpn.VpnProfile;
import de.blinkt.openvpn.core.ConfigParser;
+import de.blinkt.openvpn.core.OpenVPNService;
import de.blinkt.openvpn.core.Preferences;
import de.blinkt.openvpn.core.ProfileManager;
import de.blinkt.openvpn.core.VpnStatus;
@@ -93,12 +94,61 @@ public class AppRestrictions {
VpnStatus.logError(String.format(Locale.US, "App restriction version %s does not match expected version %d", configVersion, CONFIG_VERSION));
return;
}
- Parcelable[] profileList = restrictions.getParcelableArray(("vpn_configuration_list"));
+ Parcelable[] profileList = restrictions.getParcelableArray("vpn_configuration_list");
if (profileList == null) {
VpnStatus.logError("App restriction does not contain a profile list (vpn_configuration_list)");
return;
}
+ importVPNProfiles(c, restrictions, profileList);
+ setAllowedRemoteControl(c, restrictions);
+
+ setMiscSettings(c, restrictions);
+ }
+
+ private void setAllowedRemoteControl(Context c, Bundle restrictions) {
+ Parcelable[] allowedApps = restrictions.getParcelableArray("allowed_remote_access");
+ ExternalAppDatabase extapps = new ExternalAppDatabase(c);
+
+ if (allowedApps == null)
+ {
+ extapps.setFlagManagedConfiguration(false);
+ return;
+ }
+
+ HashSet<String> restrictionApps = new HashSet<>();
+
+ for (Parcelable allowedApp: allowedApps) {
+ if (!(allowedApp instanceof Bundle)) {
+ VpnStatus.logError("App restriction allowed app has wrong type");
+ continue;
+ }
+ String package_name = ((Bundle) allowedApp).getString("package_name");
+ restrictionApps.add(package_name);
+ }
+
+ extapps.setFlagManagedConfiguration(true);
+ extapps.clearAllApiApps();
+
+ if(!extapps.getExtAppList().equals(restrictionApps))
+ {
+ extapps.setAllowedApps(restrictionApps);
+ }
+ }
+
+ private static void setMiscSettings(Context c, Bundle restrictions) {
+ SharedPreferences defaultPrefs = Preferences.getDefaultSharedPreferences(c);
+
+ if(restrictions.containsKey("screenoffpausevpn"))
+ {
+ boolean pauseVPN = restrictions.getBoolean("screenoffpausevpn");
+ SharedPreferences.Editor editor = defaultPrefs.edit();
+ editor.putBoolean("screenoff", pauseVPN);
+ editor.apply();
+ }
+ }
+
+ private void importVPNProfiles(Context c, Bundle restrictions, Parcelable[] profileList) {
Set<String> provisionedUuids = new HashSet<>();
String defaultprofile = restrictions.getString("defaultprofile", null);
@@ -117,7 +167,7 @@ public class AppRestrictions {
String name = p.getString("name");
String certAlias = p.getString("certificate_alias");
- if (uuid == null || ovpn == null || name == null) {
+ if (TextUtils.isEmpty(uuid) || TextUtils.isEmpty(ovpn) || TextUtils.isEmpty(name)) {
VpnStatus.logError("App restriction profile misses uuid, ovpn or name key");
continue;
}
@@ -125,6 +175,8 @@ public class AppRestrictions {
/* we always use lower case uuid since Android UUID class will use present
* them that way */
uuid = uuid.toLowerCase(Locale.US);
+ if (defaultprofile != null)
+ defaultprofile = defaultprofile.toLowerCase(Locale.US);
if (uuid.equals(defaultprofile))
defaultprofileProvisioned = true;
@@ -178,14 +230,6 @@ public class AppRestrictions {
}
}
}
-
- if(restrictions.containsKey("screenoffpausevpn"))
- {
- boolean pauseVPN = restrictions.getBoolean("screenoffpausevpn");
- SharedPreferences.Editor editor = defaultPrefs.edit();
- editor.putBoolean("screenoff", pauseVPN);
- editor.apply();
- }
}
/**
@@ -196,6 +240,9 @@ public class AppRestrictions {
if (vpnProfile == null)
return;
+ if (certAlias == null)
+ certAlias = "";
+
int oldType = vpnProfile.mAuthenticationType;
String oldAlias = vpnProfile.mAlias;
diff --git a/main/src/main/java/de/blinkt/openvpn/api/ExternalAppDatabase.java b/main/src/main/java/de/blinkt/openvpn/api/ExternalAppDatabase.java
index 57e82778..fe0afdb6 100644
--- a/main/src/main/java/de/blinkt/openvpn/api/ExternalAppDatabase.java
+++ b/main/src/main/java/de/blinkt/openvpn/api/ExternalAppDatabase.java
@@ -13,11 +13,13 @@ import android.content.SharedPreferences.Editor;
import android.content.pm.ApplicationInfo;
import android.content.pm.PackageManager;
import android.os.Binder;
+import android.widget.Toast;
import java.util.HashSet;
import java.util.Set;
import de.blinkt.openvpn.core.Preferences;
+import de.blinkt.openvpn.core.VpnStatus;
import static android.content.Intent.FLAG_ACTIVITY_NEW_TASK;
@@ -30,12 +32,34 @@ public class ExternalAppDatabase {
}
private final static String PREFERENCES_KEY = "allowed_apps";
+ private final static String PREFERENCES_KEY_MANAGED_CONFIG = "allowed_apps_managed";
+
+ public void setFlagManagedConfiguration(boolean managed)
+ {
+ SharedPreferences prefs = Preferences.getDefaultSharedPreferences(mContext);
+ Editor prefedit = prefs.edit();
+
+ prefedit.putBoolean(PREFERENCES_KEY_MANAGED_CONFIG, managed);
+ increaseWorkaroundCounter(prefs, prefedit);
+ prefedit.apply();
+ }
+
+ public boolean isManagedConfiguration()
+ {
+ SharedPreferences prefs = Preferences.getDefaultSharedPreferences(mContext);
+ return prefs.getBoolean(PREFERENCES_KEY_MANAGED_CONFIG, false);
+ }
+
+ private static void increaseWorkaroundCounter(SharedPreferences prefs, Editor prefedit) {
+ // Workaround for bug
+ int counter = prefs.getInt("counter", 0);
+ prefedit.putInt("counter", counter + 1);
+ }
boolean isAllowed(String packagename) {
Set<String> allowedapps = getExtAppList();
- return allowedapps.contains(packagename);
-
+ return allowedapps.contains(packagename);
}
public Set<String> getExtAppList() {
@@ -50,14 +74,22 @@ public class ExternalAppDatabase {
saveExtAppList(allowedapps);
}
+ public boolean checkAllowingModifyingRemoteControl(Context c) {
+ if (isManagedConfiguration()) {
+ Toast.makeText(c, "Remote control apps are manged by managed configuration, cannot change", Toast.LENGTH_LONG).show();
+ VpnStatus.logError("Remote control apps are manged by managed configuration, cannot change");
+ return false;
+ }
+ return true;
+ }
+
private void saveExtAppList( Set<String> allowedapps) {
SharedPreferences prefs = Preferences.getDefaultSharedPreferences(mContext);
Editor prefedit = prefs.edit();
// Workaround for bug
prefedit.putStringSet(PREFERENCES_KEY, allowedapps);
- int counter = prefs.getInt("counter", 0);
- prefedit.putInt("counter", counter + 1);
+ increaseWorkaroundCounter(prefs, prefedit);
prefedit.apply();
}
@@ -83,9 +115,9 @@ public class ExternalAppDatabase {
}
} catch (PackageManager.NameNotFoundException e) {
// App not found. Remove it from the list
- removeApp(appPackage);
+ if (!isManagedConfiguration())
+ removeApp(appPackage);
}
-
}
throw new SecurityException("Unauthorized OpenVPN API Caller");
}
@@ -105,4 +137,8 @@ public class ExternalAppDatabase {
return false;
}
}
+
+ public void setAllowedApps(Set<String> restrictionApps) {
+ saveExtAppList(restrictionApps);
+ }
}
diff --git a/main/src/main/java/de/blinkt/openvpn/core/OpenVPNService.java b/main/src/main/java/de/blinkt/openvpn/core/OpenVPNService.java
index 88c253ec..115d6319 100644
--- a/main/src/main/java/de/blinkt/openvpn/core/OpenVPNService.java
+++ b/main/src/main/java/de/blinkt/openvpn/core/OpenVPNService.java
@@ -180,10 +180,14 @@ public class OpenVPNService extends VpnService implements StateListener, Callbac
}
}
+
+
@Override
public void addAllowedExternalApp(String packagename) throws RemoteException {
ExternalAppDatabase extapps = new ExternalAppDatabase(OpenVPNService.this);
- extapps.addApp(packagename);
+ if(extapps.checkAllowingModifyingRemoteControl(this)) {
+ extapps.addApp(packagename);
+ }
}
@Override
diff --git a/main/src/main/res/values/untranslatable.xml b/main/src/main/res/values/untranslatable.xml
index 651af1d3..9da7f522 100644
--- a/main/src/main/res/values/untranslatable.xml
+++ b/main/src/main/res/values/untranslatable.xml
@@ -85,6 +85,11 @@
<string name="faq_title_ncp">Failed to negotiate cipher with server</string>
<string name="import_from_URL">URL</string>
<string name="restriction_pausevpn">Pause VPN when screen is off and less than 64 kB transferred data in 60s</string>
+ <string name="apprest_aidl_list">List of apps that are allowed to use the remote AIDL. If this list is in the restrictions, the app will not allowe any changes to the list by the user.</string>
+ <string name="apprest_remoteapi_package">Package name of the allow app (e.g. de.blinkt.openvpn.remoteapp)</string>
+ <string name="apprest_remoteapi_package_title">Package</string>
+ <string name="apprest_allowed_aidl_app">Allowed remote access app</string>
+ <string name="apprest_remoteaidl">Remote API access</string>
<string-array name="tls_profile_values" translatable="false">
<item>insecure</item>
diff --git a/main/src/main/res/xml/app_restrictions.xml b/main/src/main/res/xml/app_restrictions.xml
index 0451fd25..55bc6888 100644
--- a/main/src/main/res/xml/app_restrictions.xml
+++ b/main/src/main/res/xml/app_restrictions.xml
@@ -1,5 +1,4 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
+<?xml version="1.0" encoding="utf-8"?><!--
~ Copyright (c) 2012-2018 Arne Schwabe
~ Distributed under the GNU GPL v2 with additional terms. For full terms see the file doc/LICENSE.txt
-->
@@ -7,49 +6,47 @@
<restrictions xmlns:android="http://schemas.android.com/apk/res/android">
<restriction
+ android:defaultValue="1"
android:key="version"
- android:title="@string/apprest_ver"
android:restrictionType="string"
- android:defaultValue="1"
- />
+ android:title="@string/apprest_ver" />
<restriction
android:key="vpn_configuration_list"
- android:title="@string/apprest_vpnlist"
- android:restrictionType="bundle_array">
+ android:restrictionType="bundle_array"
+ android:title="@string/apprest_vpnlist">
<restriction
- android:title="@string/apprest_vpnconf"
android:key="vpn_configuration"
- android:restrictionType="bundle">
+ android:restrictionType="bundle"
+ android:title="@string/apprest_vpnconf">
<restriction
+ android:description="@string/apprest_uuid_desc"
android:key="uuid"
android:restrictionType="string"
- android:description="@string/apprest_uuid_desc"
- android:title="@string/apprest_uuid"
- />
+ android:title="@string/apprest_uuid" />
<restriction
+ android:description="@string/apprest_name_desc"
android:key="name"
android:restrictionType="string"
android:title="@string/apprest_name"
- android:description="@string/apprest_name_desc"
- />
+ />
<restriction
- android:key="ovpn"
- android:title="@string/apprest_ovpn"
android:description="@string/apprest_ovpn_desc"
- android:restrictionType="string"/>
+ android:key="ovpn"
+ android:restrictionType="string"
+ android:title="@string/apprest_ovpn" />
<restriction
- android:key="certificate_alias"
- android:title="@string/apprest_certalias"
android:defaultValue=""
android:description="@string/apprest_certalias_desc"
- android:restrictionType="string"/>
+ android:key="certificate_alias"
+ android:restrictionType="string"
+ android:title="@string/apprest_certalias" />
<!--
<restriction
android:key="ovpn_list"
@@ -67,14 +64,29 @@
</restriction>
<restriction
+ android:defaultValue=""
android:key="defaultprofile"
- android:title="@string/apprest_defprof"
android:restrictionType="string"
- android:defaultValue=""
- />
+ android:title="@string/apprest_defprof" />
<restriction
- android:key="screenoffpausevpn"
- android:title="@string/restriction_pausevpn"
- android:restrictionType="bool"
- />
+ android:key="screenoffpausevpn"
+ android:restrictionType="bool"
+ android:title="@string/restriction_pausevpn" />
+ <restriction
+ android:description="@string/apprest_aidl_list"
+ android:key="allowed_remote_access"
+ android:restrictionType="bundle_array"
+ android:title="@string/apprest_remoteaidl">
+ <restriction
+ android:key="allowed_app"
+ android:restrictionType="bundle"
+ android:title="@string/apprest_allowed_aidl_app">
+ <restriction
+ android:description="@string/apprest_remoteapi_package"
+ android:key="package_name"
+ android:restrictionType="string"
+ android:title="@string/apprest_remoteapi_package_title" />
+ </restriction>
+
+ </restriction>
</restrictions> \ No newline at end of file
diff --git a/main/src/ui/java/de/blinkt/openvpn/fragments/GeneralSettings.kt b/main/src/ui/java/de/blinkt/openvpn/fragments/GeneralSettings.kt
index 7db8cba6..3c878d4d 100644
--- a/main/src/ui/java/de/blinkt/openvpn/fragments/GeneralSettings.kt
+++ b/main/src/ui/java/de/blinkt/openvpn/fragments/GeneralSettings.kt
@@ -176,6 +176,10 @@ class GeneralSettings : PreferenceFragmentCompat(), Preference.OnPreferenceClick
File("/system/lib/modules/tun.ko").length() > 10
override fun onPreferenceClick(preference: Preference): Boolean {
+ if (!mExtapp.checkAllowingModifyingRemoteControl(requireContext()))
+ {
+ return false;
+ }
if (preference.key == "clearapi") {
val builder = AlertDialog.Builder(
requireContext()