From 3eca5f7e424f6b1989e3245567bcdd034a80c92d Mon Sep 17 00:00:00 2001 From: Arne Schwabe Date: Thu, 22 Mar 2018 13:51:07 +0100 Subject: Implement also Connect for the Remote API --- doc/README.txt | 4 +- main/src/main/AndroidManifest.xml | 6 ++ .../openvpn/core/IOpenVPNServiceInternal.aidl | 2 + .../src/main/java/de/blinkt/openvpn/LaunchVPN.java | 2 +- .../de/blinkt/openvpn/api/ExternalAppDatabase.java | 12 ++-- .../java/de/blinkt/openvpn/api/RemoteAction.java | 71 ++++++++++++++++------ .../de/blinkt/openvpn/core/OpenVPNService.java | 13 ++++ .../de/blinkt/openvpn/fragments/FaqFragment.java | 2 + main/src/main/res/values/strings.xml | 4 ++ 9 files changed, 87 insertions(+), 29 deletions(-) diff --git a/doc/README.txt b/doc/README.txt index 736e368b..f629cc72 100644 --- a/doc/README.txt +++ b/doc/README.txt @@ -73,10 +73,10 @@ A: public class StartOpenVPNActivity extends Activity { super.onCreate(savedInstanceState); setContentView(R.layout.main); - final String EXTRA_NAME = "de.blinkt.openvpn.shortcutProfileName"; + final String EXTRA_NAME = "de.blinkt.openvpn.api.profileName"; Intent shortcutIntent = new Intent(Intent.ACTION_MAIN); - shortcutIntent.setClassName("de.blinkt.openvpn", "de.blinkt.openvpn.LaunchVPN"); + shortcutIntent.setClassName("de.blinkt.openvpn", "de.blinkt.openvpn.api.ConnectVPN"); shortcutIntent.putExtra(EXTRA_NAME,"upb ssl"); startActivity(shortcutIntent); } diff --git a/main/src/main/AndroidManifest.xml b/main/src/main/AndroidManifest.xml index 9244ac18..94be45c2 100644 --- a/main/src/main/AndroidManifest.xml +++ b/main/src/main/AndroidManifest.xml @@ -230,6 +230,12 @@ android:exported="true" android:name=".api.DisconnectVPN" android:targetActivity=".api.RemoteAction" /> + + + \ No newline at end of file diff --git a/main/src/main/aidl/de/blinkt/openvpn/core/IOpenVPNServiceInternal.aidl b/main/src/main/aidl/de/blinkt/openvpn/core/IOpenVPNServiceInternal.aidl index 53da4aaf..d583bbbd 100644 --- a/main/src/main/aidl/de/blinkt/openvpn/core/IOpenVPNServiceInternal.aidl +++ b/main/src/main/aidl/de/blinkt/openvpn/core/IOpenVPNServiceInternal.aidl @@ -22,4 +22,6 @@ interface IOpenVPNServiceInternal { boolean stopVPN(boolean replaceConnection); void addAllowedExternalApp(String packagename); + + boolean isAllowedExternalApp(String packagename); } diff --git a/main/src/main/java/de/blinkt/openvpn/LaunchVPN.java b/main/src/main/java/de/blinkt/openvpn/LaunchVPN.java index 7b5d4e28..a6878d92 100644 --- a/main/src/main/java/de/blinkt/openvpn/LaunchVPN.java +++ b/main/src/main/java/de/blinkt/openvpn/LaunchVPN.java @@ -142,7 +142,7 @@ public class LaunchVPN extends Activity { VpnProfile profileToConnect = ProfileManager.get(this, shortcutUUID); if (shortcutName != null && profileToConnect == null) { profileToConnect = ProfileManager.getInstance(this).getProfileByName(shortcutName); - if (!(new ExternalAppDatabase(this).checkRemoteActionPermission(this))) { + if (!(new ExternalAppDatabase(this).checkRemoteActionPermission(this, getCallingPackage()))) { finish(); return; } 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 07d77345..c6cc1beb 100644 --- a/main/src/main/java/de/blinkt/openvpn/api/ExternalAppDatabase.java +++ b/main/src/main/java/de/blinkt/openvpn/api/ExternalAppDatabase.java @@ -19,6 +19,8 @@ import java.util.Set; import de.blinkt.openvpn.core.Preferences; +import static android.content.Intent.FLAG_ACTIVITY_NEW_TASK; + public class ExternalAppDatabase { Context mContext; @@ -89,19 +91,17 @@ public class ExternalAppDatabase { } - public boolean checkRemoteActionPermission(Activity a) { - - String callingPackage = a.getCallingPackage(); - + public boolean checkRemoteActionPermission(Context c, String callingPackage) { if (callingPackage == null) callingPackage = ConfirmDialog.ANONYMOUS_PACKAGE; if (isAllowed(callingPackage)) { return true; } else { - Intent confirmDialog = new Intent(a, ConfirmDialog.class); + Intent confirmDialog = new Intent(c, ConfirmDialog.class); + confirmDialog.addFlags(FLAG_ACTIVITY_NEW_TASK); confirmDialog.putExtra(ConfirmDialog.EXTRA_PACKAGE_NAME, callingPackage); - a.startActivity(confirmDialog); + c.startActivity(confirmDialog); return false; } } diff --git a/main/src/main/java/de/blinkt/openvpn/api/RemoteAction.java b/main/src/main/java/de/blinkt/openvpn/api/RemoteAction.java index 5206d281..ebd2fe44 100644 --- a/main/src/main/java/de/blinkt/openvpn/api/RemoteAction.java +++ b/main/src/main/java/de/blinkt/openvpn/api/RemoteAction.java @@ -13,29 +13,28 @@ import android.content.ServiceConnection; import android.os.Bundle; import android.os.IBinder; import android.os.RemoteException; +import android.widget.Toast; +import de.blinkt.openvpn.LaunchVPN; +import de.blinkt.openvpn.VpnProfile; import de.blinkt.openvpn.core.IOpenVPNServiceInternal; import de.blinkt.openvpn.core.OpenVPNService; +import de.blinkt.openvpn.core.ProfileManager; public class RemoteAction extends Activity { - private ExternalAppDatabase mExtAppDb; - - @Override - protected void onCreate(Bundle savedInstanceState) { - super.onCreate(savedInstanceState); - - mExtAppDb = new ExternalAppDatabase(this); - } - + public static final String EXTRA_NAME = "de.blinkt.openvpn.api.profileName"; + private ExternalAppDatabase mExtAppDb; + private boolean mDoDisconnect; + private IOpenVPNServiceInternal mService; private ServiceConnection mConnection = new ServiceConnection() { @Override public void onServiceConnected(ComponentName className, IBinder service) { - IOpenVPNServiceInternal myservice = IOpenVPNServiceInternal.Stub.asInterface(service); + mService = IOpenVPNServiceInternal.Stub.asInterface(service); try { - myservice.stopVPN(false); + performAction(); } catch (RemoteException e) { e.printStackTrace(); } @@ -48,27 +47,59 @@ public class RemoteAction extends Activity { }; + @Override + protected void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + + mExtAppDb = new ExternalAppDatabase(this); + } @Override protected void onResume() { super.onResume(); - if (mExtAppDb.checkRemoteActionPermission(this)) - performAction(); - finish(); + Intent intent = new Intent(this, OpenVPNService.class); + intent.setAction(OpenVPNService.START_SERVICE); + getApplicationContext().bindService(intent, mConnection, Context.BIND_AUTO_CREATE); } - private void performAction() { - Intent intent = new Intent(this, OpenVPNService.class); - intent.setAction(OpenVPNService.START_SERVICE); + private void performAction() throws RemoteException { + + if (!mService.isAllowedExternalApp(getCallingPackage())) { + finish(); + return; + } - ComponentName component = getIntent().getComponent(); + Intent intent = getIntent(); + setIntent(null); + ComponentName component = intent.getComponent(); if (component.getShortClassName().equals(".api.DisconnectVPN")) { - boolean mDoDisconnect = true; + mService.stopVPN(false); + } else if (component.getShortClassName().equals(".api.ConnectVPN")) { + String vpnName = intent.getStringExtra(EXTRA_NAME); + VpnProfile profile = ProfileManager.getInstance(this).getProfileByName(vpnName); + if (profile == null) { + Toast.makeText(this, String.format("Vpn profile %s from API call not found", vpnName), Toast.LENGTH_LONG).show(); + } else { + Intent startVPN = new Intent(this, LaunchVPN.class); + startVPN.putExtra(LaunchVPN.EXTRA_KEY, profile.getUUID().toString()); + startVPN.setAction(Intent.ACTION_MAIN); + startActivity(startVPN); + } } - getApplicationContext().bindService(intent, mConnection, Context.BIND_AUTO_CREATE); + finish(); + + } + + @Override + public void finish() { + if(mService!=null) { + mService = null; + getApplicationContext().unbindService(mConnection); + } + super.finish(); } } 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 bc41c3d9..5e0016f4 100644 --- a/main/src/main/java/de/blinkt/openvpn/core/OpenVPNService.java +++ b/main/src/main/java/de/blinkt/openvpn/core/OpenVPNService.java @@ -113,6 +113,12 @@ public class OpenVPNService extends VpnService implements StateListener, Callbac OpenVPNService.this.addAllowedExternalApp(packagename); } + @Override + public boolean isAllowedExternalApp(String packagename) throws RemoteException { + return OpenVPNService.this.isAllowedExternalApp(packagename); + + } + }; private String mLastTunCfg; @@ -174,6 +180,13 @@ public class OpenVPNService extends VpnService implements StateListener, Callbac extapps.addApp(packagename); } + @Override + public boolean isAllowedExternalApp(String packagename) throws RemoteException { + ExternalAppDatabase extapps = new ExternalAppDatabase(OpenVPNService.this); + return extapps.checkRemoteActionPermission(this, packagename); + } + + @Override public IBinder onBind(Intent intent) { String action = intent.getAction(); diff --git a/main/src/main/java/de/blinkt/openvpn/fragments/FaqFragment.java b/main/src/main/java/de/blinkt/openvpn/fragments/FaqFragment.java index 0332a713..cac3ddde 100644 --- a/main/src/main/java/de/blinkt/openvpn/fragments/FaqFragment.java +++ b/main/src/main/java/de/blinkt/openvpn/fragments/FaqFragment.java @@ -112,6 +112,8 @@ public class FaqFragment extends Fragment { new FAQEntry(Build.VERSION_CODES.ICE_CREAM_SANDWICH, -1, R.string.faq_howto_title, R.string.faq_howto), + new FAQEntry(Build.VERSION_CODES.ICE_CREAM_SANDWICH, -1, R.string.faq_remote_api_title, R.string.faq_remote_api), + new FAQEntry(Build.VERSION_CODES.ICE_CREAM_SANDWICH, -1, R.string.weakmd_title, R.string.weakmd), new FAQEntry(Build.VERSION_CODES.LOLLIPOP, -1, R.string.samsung_broken_title, R.string.samsung_broken), diff --git a/main/src/main/res/values/strings.xml b/main/src/main/res/values/strings.xml index 96c7920e..de436325 100755 --- a/main/src/main/res/values/strings.xml +++ b/main/src/main/res/values/strings.xml @@ -469,5 +469,9 @@ Proxy None Tor (Orbot) + OpenVPN 3 C++ implementation does not support connecting via Socks proxy + Orbot application cannot be found. Please install Orbot or use manual Socks v5 integration. + Remote API + OpenVPN for Android supports two remote APIs, a sophisticated API using AIDL (remoteEXample in the git repository) and a simple one using Intents. <p>Examples using adb shell and the intents. Replace profilname with your profile name<p><p> adb shell am start-activity -a android.intent.action.MAIN de.blinkt.openvpn/.api.DisconnectVPN<p> adb shell am start-activity -a android.intent.action.MAIN -e de.blinkt.openvpn.api.profileName Blinkt de.blinkt.openvpn/.api.ConnectVPN -- cgit v1.2.3