From 2765afc92e13d9e751a036d53736bf42978e5b87 Mon Sep 17 00:00:00 2001 From: Arne Schwabe Date: Fri, 13 Aug 2021 14:48:01 +0200 Subject: Add WEB_AUTH pending auth support --- .../main/java/de/blinkt/openvpn/VpnProfile.java | 2 +- .../de/blinkt/openvpn/core/OpenVPNService.java | 107 +++++++++++++-------- .../openvpn/core/OpenVpnManagementThread.java | 3 +- .../java/de/blinkt/openvpn/core/VariantConfig.java | 2 +- .../de/blinkt/openvpn/core/OpenVPNThreadv3.java | 5 +- .../java/de/blinkt/openvpn/core/VariantConfig.java | 7 +- 6 files changed, 77 insertions(+), 49 deletions(-) diff --git a/main/src/main/java/de/blinkt/openvpn/VpnProfile.java b/main/src/main/java/de/blinkt/openvpn/VpnProfile.java index b32d17ad..4f66edae 100644 --- a/main/src/main/java/de/blinkt/openvpn/VpnProfile.java +++ b/main/src/main/java/de/blinkt/openvpn/VpnProfile.java @@ -354,7 +354,7 @@ public class VpnProfile implements Serializable, Cloneable { cfg.append("management-hold\n\n"); cfg.append(String.format("setenv IV_GUI_VER %s \n", openVpnEscape(getVersionEnvString(context)))); - cfg.append("setenv IV_SSO openurl,crtext\n"); + cfg.append("setenv IV_SSO openurl,webauth,crtext\n"); String versionString = getPlatformVersionEnvString(); cfg.append(String.format("setenv IV_PLAT_VER %s\n", openVpnEscape(versionString))); } else { 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 22d451eb..c98bb127 100644 --- a/main/src/main/java/de/blinkt/openvpn/core/OpenVPNService.java +++ b/main/src/main/java/de/blinkt/openvpn/core/OpenVPNService.java @@ -75,12 +75,10 @@ public class OpenVPNService extends VpnService implements StateListener, Callbac 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"; - private static final String RESUME_VPN = "de.blinkt.openvpn.RESUME_VPN"; - public static final String EXTRA_CHALLENGE_TXT = "de.blinkt.openvpn.core.CR_TEXT_CHALLENGE"; public static final String EXTRA_CHALLENGE_OPENURL = "de.blinkt.openvpn.core.OPENURL_CHALLENGE"; - + private static final String PAUSE_VPN = "de.blinkt.openvpn.PAUSE_VPN"; + private static final String RESUME_VPN = "de.blinkt.openvpn.RESUME_VPN"; private static final int PRIORITY_MIN = -2; private static final int PRIORITY_DEFAULT = 0; private static final int PRIORITY_MAX = 2; @@ -203,7 +201,7 @@ public class OpenVPNService extends VpnService implements StateListener, Callbac @Override public void challengeResponse(String response) throws RemoteException { - if(mManagement != null) { + if (mManagement != null) { String b64response = Base64.encodeToString(response.getBytes(Charset.forName("UTF-8")), Base64.DEFAULT); mManagement.sendCRResponse(b64response); } @@ -640,9 +638,7 @@ public class OpenVPNService extends VpnService implements StateListener, Callbac mOpenVPNThread = processThread; } - synchronized (mProcessLock) - - { + synchronized (mProcessLock) { mProcessThread = new Thread(processThread, "OpenVPNProcessThread"); mProcessThread.start(); } @@ -703,7 +699,6 @@ public class OpenVPNService extends VpnService implements StateListener, Callbac } - @Override public IBinder asBinder() { return mBinder; @@ -956,12 +951,9 @@ public class OpenVPNService extends VpnService implements StateListener, Callbac } private void setHttpProxy(Builder builder) { - if (mProxyInfo != null && Build.VERSION.SDK_INT >= 29) - { + if (mProxyInfo != null && Build.VERSION.SDK_INT >= 29) { builder.setHttpProxy(mProxyInfo); - } - else if (mProxyInfo != null) - { + } else if (mProxyInfo != null) { VpnStatus.logWarning("HTTP Proxy needs Android 10 or later."); } } @@ -983,8 +975,7 @@ public class OpenVPNService extends VpnService implements StateListener, Callbac } private void addLocalNetworksToRoutes() { - for (String net: NetworkUtils.getLocalNetworks(this, false)) - { + for (String net : NetworkUtils.getLocalNetworks(this, false)) { String[] netparts = net.split("/"); String ipAddr = netparts[0]; int netMask = Integer.parseInt(netparts[1]); @@ -1001,7 +992,8 @@ public class OpenVPNService extends VpnService implements StateListener, Callbac // IPv6 is Lollipop+ only so we can skip the lower than KITKAT case if (mProfile.mAllowLocalLAN) { for (String net : NetworkUtils.getLocalNetworks(this, true)) { - addRoutev6(net, false);; + addRoutev6(net, false); + ; } } @@ -1092,8 +1084,7 @@ public class OpenVPNService extends VpnService implements StateListener, Callbac try { mProxyInfo = ProxyInfo.buildDirectProxy(proxy, port); - } catch (Exception e) - { + } catch (Exception e) { VpnStatus.logError("Could not set proxy" + e.getLocalizedMessage()); return false; } @@ -1308,6 +1299,18 @@ public class OpenVPNService extends VpnService implements StateListener, Callbac } + private Intent getWebAuthIntent(String url, boolean external, Notification.Builder nbuilder) + { + int reason = R.string.openurl_requested; + nbuilder.setContentTitle(getString(reason)); + + nbuilder.setContentText(url); + Intent intent = VariantConfig.getOpenUrlIntent(this, external); + intent.setData(Uri.parse(url)); + intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); + return intent; + } + public void trigger_sso(String info) { String channel = NOTIFICATION_CHANNEL_USERREQ_ID; String method = info.split(":", 2)[0]; @@ -1320,31 +1323,51 @@ public class OpenVPNService extends VpnService implements StateListener, Callbac nbuilder.setSmallIcon(icon); Intent intent; - int reason; - if (method.equals("OPEN_URL")) { - String url = info.split(":", 2)[1]; - reason = R.string.openurl_requested; - nbuilder.setContentTitle(getString(reason)); - - nbuilder.setContentText(url); - intent = VariantConfig.getOpenUrlIntent(this); - intent.setData(Uri.parse(url)); - intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); - } else if (method.equals("CR_TEXT")) { - String challenge = info.split(":", 2)[1]; - reason = R.string.crtext_requested; - nbuilder.setContentTitle(getString(reason)); - nbuilder.setContentText(challenge); - - intent = new Intent(); - intent.setComponent(new ComponentName(this, getPackageName() + ".activities.CredentialsPopup")); - - intent.putExtra(EXTRA_CHALLENGE_TXT, challenge); - } else { - VpnStatus.logError("Unknown SSO method found: " + method); - return; + switch (method) { + case "OPEN_URL": { + reason = R.string.openurl_requested; + String url = info.split(":", 2)[1]; + intent = getWebAuthIntent(url, false, nbuilder); + + break; + } + case "WEB_AUTH": { + reason = R.string.openurl_requested; + String[] parts = info.split(":", 3); + if (parts.length < 3) { + VpnStatus.logError("WEB_AUTH method with invalid argument found"); + return; + } + String url = parts[2]; + String[] flags = parts[1].split(","); + boolean external = false; + for (String flag : flags) { + if (flag.equals("external")) { + external = true; + break; + } + } + + intent = getWebAuthIntent(url, external, nbuilder); + break; + } + case "CR_TEXT": + String challenge = info.split(":", 2)[1]; + reason = R.string.crtext_requested; + nbuilder.setContentTitle(getString(reason)); + nbuilder.setContentText(challenge); + + intent = new Intent(); + intent.setComponent(new ComponentName(this, getPackageName() + ".activities.CredentialsPopup")); + + intent.putExtra(EXTRA_CHALLENGE_TXT, challenge); + + break; + default: + VpnStatus.logError("Unknown SSO method found: " + method); + return; } // updateStateString trigger the notification of the VPN to be refreshed, save this intent 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 8228ccc2..0f15eec2 100644 --- a/main/src/main/java/de/blinkt/openvpn/core/OpenVpnManagementThread.java +++ b/main/src/main/java/de/blinkt/openvpn/core/OpenVpnManagementThread.java @@ -341,7 +341,8 @@ public class OpenVpnManagementThread implements Runnable, OpenVPNManagement { private void processInfoMessage(String info) { - if (info.startsWith("OPEN_URL:") || info.startsWith("CR_TEXT:")) + if (info.startsWith("OPEN_URL:") || info.startsWith("CR_TEXT:") + || info.startsWith("WEB_AUTH:")) { mOpenVPNService.trigger_sso(info); } diff --git a/main/src/skeleton/java/de/blinkt/openvpn/core/VariantConfig.java b/main/src/skeleton/java/de/blinkt/openvpn/core/VariantConfig.java index bbebc2af..ef59ae16 100644 --- a/main/src/skeleton/java/de/blinkt/openvpn/core/VariantConfig.java +++ b/main/src/skeleton/java/de/blinkt/openvpn/core/VariantConfig.java @@ -9,7 +9,7 @@ import android.content.Context; import android.content.Intent; public class VariantConfig { - static Intent getOpenUrlIntent(Context c) { + static Intent getOpenUrlIntent(Context c, bool external) { return new Intent(Intent.ACTION_VIEW); } diff --git a/main/src/ui/java/de/blinkt/openvpn/core/OpenVPNThreadv3.java b/main/src/ui/java/de/blinkt/openvpn/core/OpenVPNThreadv3.java index 419f49e2..1d81da1a 100644 --- a/main/src/ui/java/de/blinkt/openvpn/core/OpenVPNThreadv3.java +++ b/main/src/ui/java/de/blinkt/openvpn/core/OpenVPNThreadv3.java @@ -172,7 +172,7 @@ public class OpenVPNThreadv3 extends ClientAPI_OpenVPNClient implements Runnable config.setContent(vpnconfig); config.setTunPersist(mVp.mPersistTun); config.setGuiVersion(mVp.getVersionEnvString(mService)); - config.setSsoMethods("openurl,crtext"); + config.setSsoMethods("openurl,webauth,`crtext"); config.setPlatformVersion(mVp.getPlatformVersionEnvString()); config.setExternalPkiAlias("extpki"); config.setCompressionMode("asym"); @@ -303,7 +303,8 @@ public class OpenVPNThreadv3 extends ClientAPI_OpenVPNClient implements Runnable String name = event.getName(); String info = event.getInfo(); if (name.equals("INFO")) { - if (info.startsWith("OPEN_URL:") || info.startsWith("CR_TEXT:")) { + if (info.startsWith("OPEN_URL:") || info.startsWith("CR_TEXT:") + || info.startsWith("WEB_AUTH:")) { mService.trigger_sso(info); } else { VpnStatus.logInfo(R.string.info_from_server, info); diff --git a/main/src/ui/java/de/blinkt/openvpn/core/VariantConfig.java b/main/src/ui/java/de/blinkt/openvpn/core/VariantConfig.java index 5db8382c..bc7df548 100644 --- a/main/src/ui/java/de/blinkt/openvpn/core/VariantConfig.java +++ b/main/src/ui/java/de/blinkt/openvpn/core/VariantConfig.java @@ -12,7 +12,10 @@ import de.blinkt.openvpn.activities.InternalWebView; public class VariantConfig { /** Return the normal webview or internal webview depending what is available */ - static Intent getOpenUrlIntent(Context c) { - return new Intent(c, InternalWebView.class); + static Intent getOpenUrlIntent(Context c, boolean external) { + if (external) + return new Intent(Intent.ACTION_VIEW); + else + return new Intent(c, InternalWebView.class); } } -- cgit v1.2.3