summaryrefslogtreecommitdiff
path: root/main
diff options
context:
space:
mode:
authorArne Schwabe <arne@rfc2549.org>2018-05-30 11:40:37 +0200
committerArne Schwabe <arne@rfc2549.org>2018-05-30 13:11:24 +0200
commitb47948804f846d68c1dbc39ad4691bf0941cb825 (patch)
tree63f09b3896ce8a82bacc14fb7ef8f4db2f4b0435 /main
parent82400795bdbc60bdb9d3d4ae300b46de0897a055 (diff)
Implement showing an out of band authentication via URL to the user
Diffstat (limited to 'main')
-rw-r--r--main/build.gradle1
-rw-r--r--main/src/main/java/de/blinkt/openvpn/VpnProfile.java13
-rw-r--r--main/src/main/java/de/blinkt/openvpn/core/ICSOpenVPNApplication.java10
-rw-r--r--main/src/main/java/de/blinkt/openvpn/core/OpenVPNService.java111
-rw-r--r--main/src/main/java/de/blinkt/openvpn/core/OpenVpnManagementThread.java11
-rw-r--r--main/src/main/java/de/blinkt/openvpn/core/VpnStatus.java6
-rwxr-xr-xmain/src/main/res/values/strings.xml7
-rw-r--r--main/src/ovpn3/java/de/blinkt/openvpn/core/OpenVPNThreadv3.java16
8 files changed, 132 insertions, 43 deletions
diff --git a/main/build.gradle b/main/build.gradle
index 78f29204..0ddd3590 100644
--- a/main/build.gradle
+++ b/main/build.gradle
@@ -126,7 +126,6 @@ android {
normal {
dimension "implementation"
buildConfigField 'boolean', 'openvpn3', 'true'
-
}
}
diff --git a/main/src/main/java/de/blinkt/openvpn/VpnProfile.java b/main/src/main/java/de/blinkt/openvpn/VpnProfile.java
index 4e391e2e..74c0b595 100644
--- a/main/src/main/java/de/blinkt/openvpn/VpnProfile.java
+++ b/main/src/main/java/de/blinkt/openvpn/VpnProfile.java
@@ -311,13 +311,14 @@ public class VpnProfile implements Serializable, Cloneable {
}
- cfg.append("machine-readable-output\n");
- if (!mIsOpenVPN22)
- cfg.append("allow-recursive-routing\n");
-
- // Users are confused by warnings that are misleading...
- cfg.append("ifconfig-nowarn\n");
+ if (!configForOvpn3) {
+ cfg.append("machine-readable-output\n");
+ if (!mIsOpenVPN22)
+ cfg.append("allow-recursive-routing\n");
+ // Users are confused by warnings that are misleading...
+ cfg.append("ifconfig-nowarn\n");
+ }
boolean useTLSClient = (mAuthenticationType != TYPE_STATICKEYS);
diff --git a/main/src/main/java/de/blinkt/openvpn/core/ICSOpenVPNApplication.java b/main/src/main/java/de/blinkt/openvpn/core/ICSOpenVPNApplication.java
index 53847cbf..1cbd99ef 100644
--- a/main/src/main/java/de/blinkt/openvpn/core/ICSOpenVPNApplication.java
+++ b/main/src/main/java/de/blinkt/openvpn/core/ICSOpenVPNApplication.java
@@ -66,5 +66,15 @@ public class ICSOpenVPNApplication extends Application {
mChannel.setLightColor(Color.BLUE);
mNotificationManager.createNotificationChannel(mChannel);
+
+
+ // Urgent requests, e.g. two factor auth
+ name = getString(R.string.channel_name_userreq);
+ mChannel = new NotificationChannel(OpenVPNService.NOTIFICATION_CHANNEL_USERREQ_ID,
+ name, NotificationManager.IMPORTANCE_HIGH);
+ mChannel.setDescription(getString(R.string.channel_description_userreq));
+ mChannel.enableVibration(true);
+ mChannel.setLightColor(Color.CYAN);
+ mNotificationManager.createNotificationChannel(mChannel);
}
}
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 5e0016f4..b5afbb0e 100644
--- a/main/src/main/java/de/blinkt/openvpn/core/OpenVPNService.java
+++ b/main/src/main/java/de/blinkt/openvpn/core/OpenVPNService.java
@@ -20,6 +20,7 @@ import android.content.pm.ShortcutManager;
import android.content.res.Configuration;
import android.content.res.Resources;
import android.net.ConnectivityManager;
+import android.net.Uri;
import android.net.VpnService;
import android.os.Build;
import android.os.Bundle;
@@ -66,6 +67,8 @@ public class OpenVPNService extends VpnService implements StateListener, Callbac
public static final String DISCONNECT_VPN = "de.blinkt.openvpn.DISCONNECT_VPN";
public static final String NOTIFICATION_CHANNEL_BG_ID = "openvpn_bg";
public static final String NOTIFICATION_CHANNEL_NEWSTATUS_ID = "openvpn_newstat";
+ public static final String NOTIFICATION_CHANNEL_USERREQ_ID = "openvpn_userreq";
+
public static final String VPNSERVICE_TUN = "vpnservice-tun";
public final static String ORBOT_PACKAGE_NAME = "org.torproject.android";
private static final String PAUSE_VPN = "de.blinkt.openvpn.PAUSE_VPN";
@@ -235,6 +238,8 @@ public class OpenVPNService extends VpnService implements StateListener, Callbac
int priority;
if (channel.equals(NOTIFICATION_CHANNEL_BG_ID))
priority = PRIORITY_MIN;
+ else if (channel.equals(NOTIFICATION_CHANNEL_USERREQ_ID))
+ priority = PRIORITY_MAX;
else
priority = PRIORITY_DEFAULT;
@@ -258,12 +263,13 @@ public class OpenVPNService extends VpnService implements StateListener, Callbac
// Try to set the priority available since API 16 (Jellybean)
- if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN)
-
+ if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN) {
jbNotificationExtras(priority, nbuilder);
+ addVpnActionsToNotification(nbuilder);
+ }
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP)
- lpNotificationExtras(nbuilder);
+ lpNotificationExtras(nbuilder, Notification.CATEGORY_SERVICE);
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
//noinspection NewApi
@@ -308,8 +314,8 @@ public class OpenVPNService extends VpnService implements StateListener, Callbac
}
@TargetApi(Build.VERSION_CODES.LOLLIPOP)
- private void lpNotificationExtras(Notification.Builder nbuilder) {
- nbuilder.setCategory(Notification.CATEGORY_SERVICE);
+ private void lpNotificationExtras(Notification.Builder nbuilder, String category) {
+ nbuilder.setCategory(category);
nbuilder.setLocalOnly(true);
}
@@ -354,28 +360,6 @@ public class OpenVPNService extends VpnService implements StateListener, Callbac
}
- Intent disconnectVPN = new Intent(this, DisconnectVPN.class);
- disconnectVPN.setAction(DISCONNECT_VPN);
- PendingIntent disconnectPendingIntent = PendingIntent.getActivity(this, 0, disconnectVPN, 0);
-
- nbuilder.addAction(R.drawable.ic_menu_close_clear_cancel,
- getString(R.string.cancel_connection), disconnectPendingIntent);
-
- Intent pauseVPN = new Intent(this, OpenVPNService.class);
- if (mDeviceStateReceiver == null || !mDeviceStateReceiver.isUserPaused()) {
- pauseVPN.setAction(PAUSE_VPN);
- PendingIntent pauseVPNPending = PendingIntent.getService(this, 0, pauseVPN, 0);
- nbuilder.addAction(R.drawable.ic_menu_pause,
- getString(R.string.pauseVPN), pauseVPNPending);
-
- } else {
- pauseVPN.setAction(RESUME_VPN);
- PendingIntent resumeVPNPending = PendingIntent.getService(this, 0, pauseVPN, 0);
- nbuilder.addAction(R.drawable.ic_menu_play,
- getString(R.string.resumevpn), resumeVPNPending);
- }
-
-
//ignore exception
} catch (NoSuchMethodException | IllegalArgumentException |
InvocationTargetException | IllegalAccessException e) {
@@ -384,6 +368,30 @@ public class OpenVPNService extends VpnService implements StateListener, Callbac
}
+ @RequiresApi(api = Build.VERSION_CODES.JELLY_BEAN)
+ private void addVpnActionsToNotification(Notification.Builder nbuilder) {
+ Intent disconnectVPN = new Intent(this, DisconnectVPN.class);
+ disconnectVPN.setAction(DISCONNECT_VPN);
+ PendingIntent disconnectPendingIntent = PendingIntent.getActivity(this, 0, disconnectVPN, 0);
+
+ nbuilder.addAction(R.drawable.ic_menu_close_clear_cancel,
+ getString(R.string.cancel_connection), disconnectPendingIntent);
+
+ Intent pauseVPN = new Intent(this, OpenVPNService.class);
+ if (mDeviceStateReceiver == null || !mDeviceStateReceiver.isUserPaused()) {
+ pauseVPN.setAction(PAUSE_VPN);
+ PendingIntent pauseVPNPending = PendingIntent.getService(this, 0, pauseVPN, 0);
+ nbuilder.addAction(R.drawable.ic_menu_pause,
+ getString(R.string.pauseVPN), pauseVPNPending);
+
+ } else {
+ pauseVPN.setAction(RESUME_VPN);
+ PendingIntent resumeVPNPending = PendingIntent.getService(this, 0, pauseVPN, 0);
+ nbuilder.addAction(R.drawable.ic_menu_play,
+ getString(R.string.resumevpn), resumeVPNPending);
+ }
+ }
+
PendingIntent getUserInputIntent(String needed) {
Intent intent = new Intent(getApplicationContext(), LaunchVPN.class);
intent.addFlags(Intent.FLAG_ACTIVITY_REORDER_TO_FRONT);
@@ -1106,11 +1114,7 @@ public class OpenVPNService extends VpnService implements StateListener, Callbac
// Display byte count only after being connected
{
- if (level == LEVEL_WAITING_FOR_USER_INPUT) {
- // The user is presented a dialog of some kind, no need to inform the user
- // with a notifcation
- return;
- } else if (level == LEVEL_CONNECTED) {
+ if (level == LEVEL_CONNECTED) {
mDisplayBytecount = true;
mConnecttime = System.currentTimeMillis();
if (!runningOnAndroidTV())
@@ -1190,4 +1194,47 @@ public class OpenVPNService extends VpnService implements StateListener, Callbac
VpnStatus.updateStateString("NEED", "need " + needed, resid, LEVEL_WAITING_FOR_USER_INPUT);
showNotification(getString(resid), getString(resid), NOTIFICATION_CHANNEL_NEWSTATUS_ID, 0, LEVEL_WAITING_FOR_USER_INPUT);
}
+
+ public void trigger_url_open(String info) {
+ String channel = NOTIFICATION_CHANNEL_USERREQ_ID;
+ String url = info.split(":",2)[1];
+
+ NotificationManager mNotificationManager = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
+
+ Notification.Builder nbuilder = new Notification.Builder(this);
+ nbuilder.setContentTitle(getString(R.string.openurl_requested));
+
+ nbuilder.setContentText(url);
+ nbuilder.setAutoCancel(true);
+
+ int icon = android.R.drawable.ic_dialog_info;
+
+ nbuilder.setSmallIcon(icon);
+
+ Intent openUrlIntent = new Intent(Intent.ACTION_VIEW);
+ openUrlIntent.setData(Uri.parse(url));
+ openUrlIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
+
+ nbuilder.setContentIntent(PendingIntent.getActivity(this,0, openUrlIntent, 0));
+
+
+ // Try to set the priority available since API 16 (Jellybean)
+ if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN)
+ jbNotificationExtras(PRIORITY_MAX, nbuilder);
+
+ if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP)
+ lpNotificationExtras(nbuilder, Notification.CATEGORY_STATUS);
+
+ if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
+ //noinspection NewApi
+ nbuilder.setChannelId(channel);
+ }
+
+ @SuppressWarnings("deprecation")
+ Notification notification = nbuilder.getNotification();
+
+ int notificationId = channel.hashCode();
+
+ mNotificationManager.notify(notificationId, notification);
+ }
}
diff --git a/main/src/main/java/de/blinkt/openvpn/core/OpenVpnManagementThread.java b/main/src/main/java/de/blinkt/openvpn/core/OpenVpnManagementThread.java
index e711d8ff..74a2ad05 100644
--- a/main/src/main/java/de/blinkt/openvpn/core/OpenVpnManagementThread.java
+++ b/main/src/main/java/de/blinkt/openvpn/core/OpenVpnManagementThread.java
@@ -312,6 +312,9 @@ public class OpenVpnManagementThread implements Runnable, OpenVPNManagement {
case "PK_SIGN":
processSignCommand(argument);
break;
+ case "INFOMSG":
+ processInfoMessage(argument);
+ break;
default:
VpnStatus.logWarning("MGMT: Got unrecognized command" + command);
Log.i(TAG, "Got unrecognized command" + command);
@@ -330,6 +333,14 @@ public class OpenVpnManagementThread implements Runnable, OpenVPNManagement {
}
}
+ private void processInfoMessage(String info)
+ {
+ if (info.startsWith("OPEN_URL:"))
+ {
+ mOpenVPNService.trigger_url_open(info);
+ }
+ }
+
private void processLogMessage(String argument) {
String[] args = argument.split(",", 4);
// 0 unix time stamp
diff --git a/main/src/main/java/de/blinkt/openvpn/core/VpnStatus.java b/main/src/main/java/de/blinkt/openvpn/core/VpnStatus.java
index 3adf7c88..b87c8864 100644
--- a/main/src/main/java/de/blinkt/openvpn/core/VpnStatus.java
+++ b/main/src/main/java/de/blinkt/openvpn/core/VpnStatus.java
@@ -300,6 +300,8 @@ public class VpnStatus {
return R.string.state_resolve;
case "TCP_CONNECT":
return R.string.state_tcp_connect;
+ case "AUTH_PENDING":
+ return R.string.state_auth_pending;
default:
return R.string.unknown_state;
}
@@ -323,7 +325,7 @@ public class VpnStatus {
private static ConnectionStatus getLevel(String state) {
String[] noreplyet = {"CONNECTING", "WAIT", "RECONNECTING", "RESOLVE", "TCP_CONNECT"};
- String[] reply = {"AUTH", "GET_CONFIG", "ASSIGN_IP", "ADD_ROUTES"};
+ String[] reply = {"AUTH", "GET_CONFIG", "ASSIGN_IP", "ADD_ROUTES", "AUTH_PENDING"};
String[] connected = {"CONNECTED"};
String[] notconnected = {"DISCONNECTED", "EXITING"};
@@ -385,7 +387,7 @@ public class VpnStatus {
for (StateListener sl : stateListener) {
sl.updateState(state, msg, resid, level);
}
- newLogItem(new LogItem((LogLevel.DEBUG), String.format("New OpenVPN Status (%s->%s): %s",state,level.toString(),msg)));
+ //newLogItem(new LogItem((LogLevel.DEBUG), String.format("New OpenVPN Status (%s->%s): %s",state,level.toString(),msg)));
}
public static void logInfo(String message) {
diff --git a/main/src/main/res/values/strings.xml b/main/src/main/res/values/strings.xml
index a7cd6a61..5590acf3 100755
--- a/main/src/main/res/values/strings.xml
+++ b/main/src/main/res/values/strings.xml
@@ -475,4 +475,11 @@
<string name="faq_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. &lt;p>Examples using adb shell and the intents. Replace profilname with your profile name&lt;p>&lt;p> adb shell am start-activity -a android.intent.action.MAIN de.blinkt.openvpn/.api.DisconnectVPN&lt;p> adb shell am start-activity -a android.intent.action.MAIN -e de.blinkt.openvpn.api.profileName Blinkt de.blinkt.openvpn/.api.ConnectVPN</string>
<string name ="enableproxyauth">Enable Proxy Authentication</string>
<string name="error_orbot_and_proxy_options">Cannot use extra http-proxy-option statement and Orbot integration at the same timeO</string>
+ <string name="info_from_server">Info from server: \'%s\'</string>
+ <string name="channel_name_userreq">User interaction required</string>
+ <string name="channel_description_userreq">OpenVPN connection requires a user input, e.g. two factor
+ authentification
+ </string>
+ <string name="openurl_requested">Open URL to continue VPN authentication</string>
+ <string name="state_auth_pending">Authentication pending</string>
</resources>
diff --git a/main/src/ovpn3/java/de/blinkt/openvpn/core/OpenVPNThreadv3.java b/main/src/ovpn3/java/de/blinkt/openvpn/core/OpenVPNThreadv3.java
index b2e8714f..08c84558 100644
--- a/main/src/ovpn3/java/de/blinkt/openvpn/core/OpenVPNThreadv3.java
+++ b/main/src/ovpn3/java/de/blinkt/openvpn/core/OpenVPNThreadv3.java
@@ -1,5 +1,6 @@
package de.blinkt.openvpn.core;
+import de.blinkt.openvpn.R;
import net.openvpn.ovpn3.ClientAPI_Config;
import net.openvpn.ovpn3.ClientAPI_EvalConfig;
import net.openvpn.ovpn3.ClientAPI_Event;
@@ -189,6 +190,7 @@ public class OpenVPNThreadv3 extends ClientAPI_OpenVPNClient implements Runnable
//config.setPlatformVersion(mVp.getPlatformVersionEnvString());
config.setExternalPkiAlias("extpki");
config.setCompressionMode("yes");
+ config.setInfo(true);
ClientAPI_EvalConfig ec = eval_config(config);
if(ec.getExternalPki()) {
@@ -278,9 +280,19 @@ public class OpenVPNThreadv3 extends ClientAPI_OpenVPNClient implements Runnable
@Override
public void event(ClientAPI_Event event) {
- VpnStatus.updateStateString(event.getName(), event.getInfo());
+ String name = event.getName();
+ String info = event.getInfo();
+ if (name.equals("INFO")) {
+ VpnStatus.logInfo(R.string.info_from_server, info);
+ if (info.startsWith("OPEN_URL:"))
+ {
+ mService.trigger_url_open(info);
+ }
+ } else{
+ VpnStatus.updateStateString(name, info);
+ }
if(event.getError())
- VpnStatus.logError(String.format("EVENT(Error): %s: %s",event.getName(),event.getInfo()));
+ VpnStatus.logError(String.format("EVENT(Error): %s: %s", name, info));
}