aboutsummaryrefslogtreecommitdiffstats
path: root/app/src/fil/libre/repwifiapp/helpers/OpenVpnManager.java
diff options
context:
space:
mode:
Diffstat (limited to 'app/src/fil/libre/repwifiapp/helpers/OpenVpnManager.java')
-rw-r--r--app/src/fil/libre/repwifiapp/helpers/OpenVpnManager.java237
1 files changed, 237 insertions, 0 deletions
diff --git a/app/src/fil/libre/repwifiapp/helpers/OpenVpnManager.java b/app/src/fil/libre/repwifiapp/helpers/OpenVpnManager.java
new file mode 100644
index 0000000..5de2501
--- /dev/null
+++ b/app/src/fil/libre/repwifiapp/helpers/OpenVpnManager.java
@@ -0,0 +1,237 @@
+//
+// Copyright 2017 Filippo "Fil" Bergamo <fil.bergamo@riseup.net>
+//
+// This file is part of RepWifiApp.
+// This file is based upon the example file included in
+// de.blinkt.openvpn package by Arne Schwabe.
+//
+// RepWifiApp is free software: you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation, either version 3 of the License, or
+// (at your option) any later version.
+//
+// RepWifiApp is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with RepWifiApp. If not, see <http://www.gnu.org/licenses/>.
+//
+// ********************************************************************
+
+package fil.libre.repwifiapp.helpers;
+
+import android.app.Activity;
+import android.content.ComponentName;
+import android.content.Context;
+import android.content.Intent;
+import android.content.ServiceConnection;
+import android.content.pm.ApplicationInfo;
+import android.content.pm.PackageManager.NameNotFoundException;
+import android.os.IBinder;
+import android.os.RemoteException;
+import java.util.ArrayList;
+import java.util.List;
+import de.blinkt.openvpn.api.APIVpnProfile;
+import de.blinkt.openvpn.api.IOpenVPNAPIService;
+
+public class OpenVpnManager {
+
+ public static final String SERVICE_PACKAGE_NAME = "de.blinkt.openvpn";
+ public static final String APP_COMMON_NAME = "OpenVPN for Android";
+ public static final String PLACEHOLDER_APPNAME = "[VPN_EXT_APP]";
+
+ private static boolean VpnIsConnected;
+ private static OpenVpnManager _currentInstance;
+
+ protected IOpenVPNAPIService _vpnSvc;
+
+ private Activity _caller;
+ private ServiceConnection _svcConnection = new ServiceConnection() {
+ public void onServiceConnected(ComponentName className, IBinder service) {
+ _vpnSvc = IOpenVPNAPIService.Stub.asInterface(service);
+ }
+
+ public void onServiceDisconnected(ComponentName className) {
+ _vpnSvc = null;
+ }
+ };
+
+ private OpenVpnManager(Activity c) throws Exception {
+ this._caller = c;
+ bindService();
+ }
+
+ private void bindService() throws Exception {
+
+ Intent intentGetService = new Intent(IOpenVPNAPIService.class.getName());
+ intentGetService.setPackage(SERVICE_PACKAGE_NAME);
+ if (!_caller.bindService(intentGetService, _svcConnection, Context.BIND_AUTO_CREATE)) {
+ throw new Exception("FAILED to bind to OpenVPN service!");
+ }
+
+ }
+
+ private void unbindService() {
+ _caller.unbindService(_svcConnection);
+ }
+
+ private Intent askApiPermissionsGetIntentInternal() throws RemoteException {
+ return _vpnSvc.prepare(_caller.getPackageName());
+ }
+
+ private boolean startVpnInternal(String profileUuid) {
+
+ if (profileUuid == null) {
+ Utils.logError("Invoked startVpn with null uuid");
+ return false;
+ }
+
+ if (_vpnSvc == null) {
+ Utils.logError("Invoked startVpn but inner service is null.");
+ return false;
+ }
+
+ try {
+
+ _vpnSvc.startProfile(profileUuid);
+ VpnIsConnected = true;
+ return true;
+
+ } catch (RemoteException e) {
+ Utils.logError("Exception while starting vpn.", e);
+ return false;
+ }
+ }
+
+ private boolean disconnectInternal() {
+
+ if (_vpnSvc == null) {
+ Utils.logDebug("Attempted to disconnect from VPN, but inner service is null");
+ VpnIsConnected = false;
+ return true;
+ }
+
+ try {
+ _vpnSvc.disconnect();
+ VpnIsConnected = false;
+ return true;
+ } catch (RemoteException e) {
+ Utils.logError("Exception while disconnecting from vpn.", e);
+ return false;
+ }
+ }
+
+ private List<String> getExistingProfilesInternal(){
+
+ try {
+ List<APIVpnProfile> list = _vpnSvc.getProfiles();
+
+ List<String> ret = new ArrayList<String>();
+ for (APIVpnProfile vp : list) {
+ ret.add(vp.mName);
+ }
+
+ return ret;
+
+ } catch (RemoteException e) {
+ Utils.logError("Exception while retrieving profiles from vpn service.", e);
+ return null;
+ }
+
+ }
+
+ private String getUuidFromNameInternal(String profileName) {
+
+ if (_vpnSvc == null) {
+ Utils.logError("Called getUuidFromName but inner service is null!");
+ return null;
+ }
+
+ try {
+ List<APIVpnProfile> list = _vpnSvc.getProfiles();
+
+ for (APIVpnProfile vp : list) {
+ if (vp.mName.equals(profileName)) {
+ return vp.mUUID;
+ }
+ }
+
+ return null;
+
+ } catch (RemoteException e) {
+ Utils.logError("Exception while retrieving profiles from vpn service.", e);
+ return null;
+ }
+ }
+
+ public void close() {
+ if (_vpnSvc != null) {
+ unbindService();
+
+ }
+
+ }
+
+ public static void initialize(Activity caller){
+
+ if (_currentInstance != null){
+ return;
+ }
+
+ try {
+ _currentInstance = new OpenVpnManager(caller);
+ } catch (Exception e) {
+ Utils.logError("Exception while initializing vpn manager.",e);
+ }
+ }
+
+ public static boolean isExternalAppInstalled(Activity caller) {
+
+ try {
+
+ ApplicationInfo i;
+ i = caller.getPackageManager().getApplicationInfo(SERVICE_PACKAGE_NAME, 0);
+ return (i != null);
+
+ } catch (NameNotFoundException e) {
+ return false;
+ }
+
+ }
+
+ public static boolean startVpn(String profileUuid){
+ if (_currentInstance == null){
+ return false;
+ }
+ return _currentInstance.startVpnInternal(profileUuid);
+ }
+
+ public static boolean disconnect(){
+ if (_currentInstance == null){
+ return false;
+ }
+ return _currentInstance.disconnectInternal();
+ }
+
+ public static boolean isVpnConnected(){
+ return VpnIsConnected;
+ }
+
+ public static String getUuidFromName(String profileName){
+ if (_currentInstance == null){
+ return null;
+ }
+ return _currentInstance.getUuidFromNameInternal(profileName);
+ }
+
+ public static List<String> getExistingProfiles(){
+ return _currentInstance.getExistingProfilesInternal();
+ }
+
+ public static Intent askApiPermissionsGetIntent() throws RemoteException{
+ return _currentInstance.askApiPermissionsGetIntentInternal();
+ }
+
+}