From e1522e91272caf3d1b22d80dd26f6c000ea89408 Mon Sep 17 00:00:00 2001 From: Arne Schwabe Date: Fri, 20 Dec 2019 16:45:12 +0100 Subject: Change Swig java file generation to a more standard way This also fixes the issues of Android studio not seeing the generated files. --- main/build.gradle.kts | 80 ++--- .../de/blinkt/openvpn/core/OpenVPNThreadv3.java | 372 -------------------- .../de/blinkt/openvpn/core/OpenVPNThreadv3.java | 377 +++++++++++++++++++++ 3 files changed, 419 insertions(+), 410 deletions(-) delete mode 100644 main/src/ovpn3/java/de/blinkt/openvpn/core/OpenVPNThreadv3.java create mode 100644 main/src/ui/java/de/blinkt/openvpn/core/OpenVPNThreadv3.java diff --git a/main/build.gradle.kts b/main/build.gradle.kts index 39a7498c..83c6b9dd 100644 --- a/main/build.gradle.kts +++ b/main/build.gradle.kts @@ -1,3 +1,5 @@ +import com.android.build.gradle.api.ApplicationVariant + /* * Copyright (c) 2012-2016 Arne Schwabe * Distributed under the GNU GPL v2 with additional terms. For full terms see the file doc/LICENSE.txt @@ -36,20 +38,19 @@ android { sourceSets { getByName("main") { assets.srcDirs("src/main/assets", "build/ovpnassets") + } create("ui") { - java.srcDirs("src/ovpn3/java/", getOpenvpn3SwigFiles()) } + create("skeleton") { } getByName("debug") { - } getByName("release") { - } } @@ -111,8 +112,45 @@ android { isUniversalApk = true } } + + +} + +var swigcmd = "swig" +// Workaround for Mac OS X since it otherwise does not find swig and I cannot get +// the Exec task to respect the PATH environment :( +if (File("/usr/local/bin/swig").exists()) + swigcmd = "/usr/local/bin/swig" + + +fun registerGenTask(variantName: String, variantDirName: String): File { + val baseDir = File(buildDir, "generated/source/ovpn3swig/${variantDirName}") + val genDir = File(baseDir, "net/openvpn/ovpn3") + + tasks.register("generateOpenVPN3Swig${variantName}") + { + + doFirst { + mkdir(genDir) + } + commandLine(listOf(swigcmd, "-outdir", genDir, "-outcurrentdir", "-c++", "-java", "-package", "net.openvpn.ovpn3", + "-Isrc/main/cpp/openvpn3/client", "-Isrc/main/cpp/openvpn3/", + "-o", "${genDir}/ovpncli_wrap.cxx", "-oh", "${genDir}/ovpncli_wrap.h", + "src/main/cpp/openvpn3/javacli/ovpncli.i")) + } + return baseDir } +android.applicationVariants.all(object : Action { + override fun execute(variant: ApplicationVariant) { + val sourceDir = registerGenTask(variant.name, variant.baseName.replace("-", "/")) + val task = tasks.named("generateOpenVPN3Swig${variant.name}").get() + + variant.registerJavaGeneratingTask(task, sourceDir) + } +}) + + dependencies { val preferenceVersion = "1.1.0" val coreVersion = "1.1.0" @@ -140,40 +178,6 @@ dependencies { testImplementation("org.jetbrains.kotlin:kotlin-stdlib-jdk7:1.3.61") testImplementation("junit:junit:4.12") - testImplementation("org.mockito:mockito-core:3.2.0") + testImplementation("org.mockito:mockito-core:3.2.4") testImplementation("org.robolectric:robolectric:4.3.1") } - - -/* swig magic for building openvpn3 */ -fun getOpenvpn3SwigFiles(): File { - return File(buildDir, "generated/source/ovpn3swig/ovpn3") -} - -tasks.register("generateOpenVPN3Swig") -{ - var swigcmd = "swig" - // Workaround for Mac OS X since it otherwise does not find swig and I cannot get - // the Exec task to respect the PATH environment :( - if (File("/usr/local/bin/swig").exists()) - swigcmd = "/usr/local/bin/swig" - - doFirst { - mkdir(getOpenvpn3SwigFiles()) - } - commandLine(listOf(swigcmd, "-outdir", getOpenvpn3SwigFiles(), "-outcurrentdir", "-c++", "-java", "-package", "net.openvpn.ovpn3", - "-Isrc/main/cpp/openvpn3/client", "-Isrc/main/cpp/openvpn3/", - "-o", "${getOpenvpn3SwigFiles()}/ovpncli_wrap.cxx", "-oh", "${getOpenvpn3SwigFiles()}/ovpncli_wrap.h", - "src/main/cpp/openvpn3/javacli/ovpncli.i")) -} - -/* Hack-o-rama but it works good enough and documentation is surprisingly sparse */ - -val swigTask = tasks.named("generateOpenVPN3Swig") -val preBuildTask = tasks.getByName("preBuild") -val assembleTask = tasks.getByName("assemble") - -assembleTask.dependsOn(swigTask) -preBuildTask.dependsOn(swigTask) - - diff --git a/main/src/ovpn3/java/de/blinkt/openvpn/core/OpenVPNThreadv3.java b/main/src/ovpn3/java/de/blinkt/openvpn/core/OpenVPNThreadv3.java deleted file mode 100644 index 4c96e4d6..00000000 --- a/main/src/ovpn3/java/de/blinkt/openvpn/core/OpenVPNThreadv3.java +++ /dev/null @@ -1,372 +0,0 @@ -package de.blinkt.openvpn.core; - -import android.annotation.SuppressLint; -import android.content.Context; -import android.provider.Settings; -import android.util.Base64; -import de.blinkt.openvpn.R; -import de.blinkt.openvpn.VpnProfile; -import net.openvpn.ovpn3.*; - -import net.openvpn.ovpn3.ClientAPI_OpenVPNClient; -import net.openvpn.ovpn3.ClientAPI_DynamicChallenge; - -import java.nio.charset.Charset; -import java.nio.charset.StandardCharsets; -import java.util.Locale; - -import static de.blinkt.openvpn.VpnProfile.AUTH_RETRY_NOINTERACT; - -public class OpenVPNThreadv3 extends ClientAPI_OpenVPNClient implements Runnable, OpenVPNManagement { - - final static long EmulateExcludeRoutes = (1 << 16); - - static { - System.loadLibrary("ovpn3"); - } - - private VpnProfile mVp; - private OpenVPNService mService; - - public OpenVPNThreadv3(OpenVPNService openVpnService, VpnProfile vp) { - init_process(); - mVp = vp; - mService = openVpnService; - } - - @Override - public void run() { - String configstr = mVp.getConfigFile((Context) mService, true); - if (!setConfig(configstr)) - return; - setUserPW(); - VpnStatus.logInfo(platform()); - VpnStatus.logInfo(copyright()); - - - StatusPoller statuspoller = new StatusPoller(OpenVPNManagement.mBytecountInterval * 1000); - new Thread(statuspoller, "Status Poller").start(); - - ClientAPI_Status status = connect(); - if (status.getError()) { - VpnStatus.logError(String.format("connect() error: %s: %s", status.getStatus(), status.getMessage())); - } else { - VpnStatus.updateStateString("NOPROCESS", "OpenVPN3 thread finished", R.string.state_noprocess, ConnectionStatus.LEVEL_NOTCONNECTED); - } - statuspoller.stop(); - } - - @Override - public boolean tun_builder_set_remote_address(String address, boolean ipv6) { - mService.setMtu(1500); - return true; - } - - @Override - public boolean tun_builder_set_mtu(int mtu) { - mService.setMtu(mtu); - return true; - } - - @Override - public boolean tun_builder_add_dns_server(String address, boolean ipv6) { - mService.addDNS(address); - return true; - } - - @Override - public boolean tun_builder_add_route(String address, int prefix_length, int metric, boolean ipv6) { - if (address.equals("remote_host")) - return false; - - if (ipv6) - mService.addRoutev6(address + "/" + prefix_length, "tun"); - else - mService.addRoute(new CIDRIP(address, prefix_length), true); - return true; - } - - @Override - public boolean tun_builder_exclude_route(String address, int prefix_length, int metric, boolean ipv6) { - if (ipv6) - mService.addRoutev6(address + "/" + prefix_length, "wifi0"); - else { - CIDRIP route = new CIDRIP(address, prefix_length); - mService.addRoute(route, false); - } - return true; - } - - @Override - public boolean tun_builder_add_search_domain(String domain) { - mService.setDomain(domain); - return true; - } - - @Override - public int tun_builder_establish() { - return mService.openTun().detachFd(); - } - - @Override - public boolean tun_builder_set_session_name(String name) { - VpnStatus.logDebug("We should call this session" + name); - return true; - } - - @Override - public boolean tun_builder_add_address(String address, int prefix_length, String gateway, boolean ipv6, boolean net30) { - if (!ipv6) - mService.setLocalIP(new CIDRIP(address, prefix_length)); - else - mService.setLocalIPv6(address + "/" + prefix_length); - return true; - } - - @Override - public boolean tun_builder_new() { - - return true; - } - - @Override - public boolean tun_builder_set_layer(int layer) { - return layer == 3; - } - - @Override - public boolean tun_builder_reroute_gw(boolean ipv4, boolean ipv6, long flags) { - if ((flags & EmulateExcludeRoutes) != 0) - return true; - if (ipv4) - mService.addRoute("0.0.0.0", "0.0.0.0", "127.0.0.1", OpenVPNService.VPNSERVICE_TUN); - - if (ipv6) - mService.addRoutev6("::/0", OpenVPNService.VPNSERVICE_TUN); - - return true; - } - - private boolean setConfig(String vpnconfig) { - - ClientAPI_Config config = new ClientAPI_Config(); - if (mVp.getPasswordPrivateKey() != null) - config.setPrivateKeyPassword(mVp.getPasswordPrivateKey()); - - config.setContent(vpnconfig); - config.setTunPersist(mVp.mPersistTun); - config.setGuiVersion(mVp.getVersionEnvString(mService)); - config.setSsoMethods("openurl,crtext"); - config.setPlatformVersion(mVp.getPlatformVersionEnvString()); - config.setExternalPkiAlias("extpki"); - config.setCompressionMode("asym"); - - config.setHwAddrOverride(getFakeMacAddrFromSAAID(mService)); - config.setInfo(true); - config.setAllowLocalLanAccess(mVp.mAllowLocalLAN); - boolean retryOnAuthFailed = mVp.mAuthRetry == AUTH_RETRY_NOINTERACT; - config.setRetryOnAuthFailed(retryOnAuthFailed); - - ClientAPI_EvalConfig ec = eval_config(config); - if (ec.getExternalPki()) { - VpnStatus.logDebug("OpenVPN3 core assumes an external PKI config"); - } - if (ec.getError()) { - VpnStatus.logError("OpenVPN config file parse error: " + ec.getMessage()); - return false; - } else { - config.setContent(vpnconfig); - return true; - } - } - - @SuppressLint("HardwareIds") - private String getFakeMacAddrFromSAAID(Context c) { - char[] HEX_ARRAY = "0123456789ABCDEF".toCharArray(); - - String saaid = Settings.Secure.getString(c.getContentResolver(), - Settings.Secure.ANDROID_ID); - - StringBuilder ret = new StringBuilder(); - if (saaid.length() >= 6) { - byte[] sb = saaid.getBytes(); - for (int b = 0; b <= 6; b++) { - if (b != 0) - ret.append(":"); - int v = sb[b] & 0xFF; - ret.append(HEX_ARRAY[v >>> 4]); - ret.append(HEX_ARRAY[v & 0x0F]); - } - } - return ret.toString(); - } - - - @Override - public void external_pki_cert_request(ClientAPI_ExternalPKICertRequest certreq) { - VpnStatus.logDebug("Got external PKI certificate request from OpenVPN core"); - String[] ks = mVp.getExternalCertificates(mService); - if (ks == null) { - certreq.setError(true); - certreq.setErrorText("Error in pki cert request"); - return; - } - - String supcerts = ks[0]; - /* FIXME: How to differentiate between chain and ca certs in OpenVPN 3? */ - if (ks[1] != null) - supcerts += "\n" + ks[1]; - certreq.setSupportingChain(supcerts); - certreq.setCert(ks[2]); - certreq.setError(false); - } - - @Override - public void external_pki_sign_request(ClientAPI_ExternalPKISignRequest signreq) { - VpnStatus.logDebug("Got external PKI signing request from OpenVPN core for algorithm " + signreq.getAlgorithm()); - boolean pkcs1padding; - if (signreq.getAlgorithm().equals("RSA_PKCS1_PADDING")) - pkcs1padding = true; - else if (signreq.getAlgorithm().equals("RSA_NO_PADDING")) - pkcs1padding = false; - else if (signreq.getAlgorithm().equals("ECDSA")) - pkcs1padding = false; - else - throw new IllegalArgumentException("Illegal padding in sign request" + signreq.getAlgorithm()); - signreq.setSig(mVp.getSignedData(mService, signreq.getData(), pkcs1padding)); - } - - void setUserPW() { - if (mVp.isUserPWAuth()) { - ClientAPI_ProvideCreds creds = new ClientAPI_ProvideCreds(); - creds.setCachePassword(true); - creds.setPassword(mVp.getPasswordAuth()); - creds.setUsername(mVp.mUsername); - provide_creds(creds); - } - } - - @Override - public boolean socket_protect(int socket, String remote, boolean ipv6) { - return mService.protect(socket); - - } - - @Override - public boolean stopVPN(boolean replaceConnection) { - stop(); - return false; - } - - @Override - public void networkChange(boolean sameNetwork) { - reconnect(1); - } - - @Override - public void setPauseCallback(PausedStateCallback callback) { - } - - @Override - public void sendCRResponse(String response) { - post_cc_msg("CR_RESPONSE," + response + "\n"); - } - - @Override - public void log(ClientAPI_LogInfo arg0) { - String logmsg = arg0.getText(); - while (logmsg.endsWith("\n")) - logmsg = logmsg.substring(0, logmsg.length() - 1); - - VpnStatus.logInfo(logmsg); - } - - @Override - public void event(ClientAPI_Event event) { - String name = event.getName(); - String info = event.getInfo(); - if (name.equals("INFO")) { - if (info.startsWith("OPEN_URL:") || info.startsWith("CR_TEXT:")) { - mService.trigger_sso(info); - } else { - VpnStatus.logInfo(R.string.info_from_server, info); - } - } else if (name.equals("COMPRESSION_ENABLED")) { - VpnStatus.logInfo(String.format(Locale.US, "%s: %s", name, info)); - } else { - VpnStatus.updateStateString(name, info); - } - /* if (event.name.equals("DYNAMIC_CHALLENGE")) { - ClientAPI_DynamicChallenge challenge = new ClientAPI_DynamicChallenge(); - final boolean status = ClientAPI_OpenVPNClient.parse_dynamic_challenge(event.info, challenge); - - } else */ - if (event.getError()) - VpnStatus.logError(String.format("EVENT(Error): %s: %s", name, info)); - } - - @Override - public net.openvpn.ovpn3.ClientAPI_StringVec tun_builder_get_local_networks(boolean ipv6) { - - net.openvpn.ovpn3.ClientAPI_StringVec nets = new net.openvpn.ovpn3.ClientAPI_StringVec(); - for (String net : NetworkUtils.getLocalNetworks(mService, ipv6)) - nets.add(net); - return nets; - } - - @Override - public boolean pause_on_connection_timeout() { - VpnStatus.logInfo("pause on connection timeout?! "); - return true; - } - - - // When a connection is close to timeout, the core will call this - // method. If it returns false, the core will disconnect with a - // CONNECTION_TIMEOUT event. If true, the core will enter a PAUSE - // state. - - @Override - public void stop() { - super.stop(); - mService.openvpnStopped(); - } - - @Override - public void reconnect() { - reconnect(1); - } - - @Override - public void pause(pauseReason reason) { - super.pause(reason.toString()); - } - - class StatusPoller implements Runnable { - boolean mStopped = false; - private long mSleeptime; - - public StatusPoller(long sleeptime) { - mSleeptime = sleeptime; - } - - public void run() { - while (!mStopped) { - try { - Thread.sleep(mSleeptime); - } catch (InterruptedException e) { - } - ClientAPI_TransportStats t = transport_stats(); - long in = t.getBytesIn(); - long out = t.getBytesOut(); - VpnStatus.updateByteCount(in, out); - } - } - - public void stop() { - mStopped = true; - } - } - - -} diff --git a/main/src/ui/java/de/blinkt/openvpn/core/OpenVPNThreadv3.java b/main/src/ui/java/de/blinkt/openvpn/core/OpenVPNThreadv3.java new file mode 100644 index 00000000..2ddd4ce2 --- /dev/null +++ b/main/src/ui/java/de/blinkt/openvpn/core/OpenVPNThreadv3.java @@ -0,0 +1,377 @@ +package de.blinkt.openvpn.core; + +import android.annotation.SuppressLint; +import android.content.Context; +import android.provider.Settings; + +import net.openvpn.ovpn3.ClientAPI_Config; +import net.openvpn.ovpn3.ClientAPI_EvalConfig; +import net.openvpn.ovpn3.ClientAPI_Event; +import net.openvpn.ovpn3.ClientAPI_ExternalPKICertRequest; +import net.openvpn.ovpn3.ClientAPI_ExternalPKISignRequest; +import net.openvpn.ovpn3.ClientAPI_LogInfo; +import net.openvpn.ovpn3.ClientAPI_OpenVPNClient; +import net.openvpn.ovpn3.ClientAPI_ProvideCreds; +import net.openvpn.ovpn3.ClientAPI_Status; +import net.openvpn.ovpn3.ClientAPI_TransportStats; + +import java.util.Locale; + +import de.blinkt.openvpn.R; +import de.blinkt.openvpn.VpnProfile; + +import static de.blinkt.openvpn.VpnProfile.AUTH_RETRY_NOINTERACT; + +public class OpenVPNThreadv3 extends ClientAPI_OpenVPNClient implements Runnable, OpenVPNManagement { + + final static long EmulateExcludeRoutes = (1 << 16); + + static { + System.loadLibrary("ovpn3"); + } + + private VpnProfile mVp; + private OpenVPNService mService; + + public OpenVPNThreadv3(OpenVPNService openVpnService, VpnProfile vp) { + init_process(); + mVp = vp; + mService = openVpnService; + } + + @Override + public void run() { + String configstr = mVp.getConfigFile((Context) mService, true); + if (!setConfig(configstr)) + return; + setUserPW(); + VpnStatus.logInfo(platform()); + VpnStatus.logInfo(copyright()); + + + StatusPoller statuspoller = new StatusPoller(OpenVPNManagement.mBytecountInterval * 1000); + new Thread(statuspoller, "Status Poller").start(); + + ClientAPI_Status status = connect(); + if (status.getError()) { + VpnStatus.logError(String.format("connect() error: %s: %s", status.getStatus(), status.getMessage())); + } else { + VpnStatus.updateStateString("NOPROCESS", "OpenVPN3 thread finished", R.string.state_noprocess, ConnectionStatus.LEVEL_NOTCONNECTED); + } + statuspoller.stop(); + } + + @Override + public boolean tun_builder_set_remote_address(String address, boolean ipv6) { + mService.setMtu(1500); + return true; + } + + @Override + public boolean tun_builder_set_mtu(int mtu) { + mService.setMtu(mtu); + return true; + } + + @Override + public boolean tun_builder_add_dns_server(String address, boolean ipv6) { + mService.addDNS(address); + return true; + } + + @Override + public boolean tun_builder_add_route(String address, int prefix_length, int metric, boolean ipv6) { + if (address.equals("remote_host")) + return false; + + if (ipv6) + mService.addRoutev6(address + "/" + prefix_length, "tun"); + else + mService.addRoute(new CIDRIP(address, prefix_length), true); + return true; + } + + @Override + public boolean tun_builder_exclude_route(String address, int prefix_length, int metric, boolean ipv6) { + if (ipv6) + mService.addRoutev6(address + "/" + prefix_length, "wifi0"); + else { + CIDRIP route = new CIDRIP(address, prefix_length); + mService.addRoute(route, false); + } + return true; + } + + @Override + public boolean tun_builder_add_search_domain(String domain) { + mService.setDomain(domain); + return true; + } + + @Override + public int tun_builder_establish() { + return mService.openTun().detachFd(); + } + + @Override + public boolean tun_builder_set_session_name(String name) { + VpnStatus.logDebug("We should call this session" + name); + return true; + } + + @Override + public boolean tun_builder_add_address(String address, int prefix_length, String gateway, boolean ipv6, boolean net30) { + if (!ipv6) + mService.setLocalIP(new CIDRIP(address, prefix_length)); + else + mService.setLocalIPv6(address + "/" + prefix_length); + return true; + } + + @Override + public boolean tun_builder_new() { + + return true; + } + + @Override + public boolean tun_builder_set_layer(int layer) { + return layer == 3; + } + + @Override + public boolean tun_builder_reroute_gw(boolean ipv4, boolean ipv6, long flags) { + if ((flags & EmulateExcludeRoutes) != 0) + return true; + if (ipv4) + mService.addRoute("0.0.0.0", "0.0.0.0", "127.0.0.1", OpenVPNService.VPNSERVICE_TUN); + + if (ipv6) + mService.addRoutev6("::/0", OpenVPNService.VPNSERVICE_TUN); + + return true; + } + + private boolean setConfig(String vpnconfig) { + + ClientAPI_Config config = new ClientAPI_Config(); + if (mVp.getPasswordPrivateKey() != null) + config.setPrivateKeyPassword(mVp.getPasswordPrivateKey()); + + config.setContent(vpnconfig); + config.setTunPersist(mVp.mPersistTun); + config.setGuiVersion(mVp.getVersionEnvString(mService)); + config.setSsoMethods("openurl,crtext"); + config.setPlatformVersion(mVp.getPlatformVersionEnvString()); + config.setExternalPkiAlias("extpki"); + config.setCompressionMode("asym"); + + config.setHwAddrOverride(getFakeMacAddrFromSAAID(mService)); + config.setInfo(true); + config.setAllowLocalLanAccess(mVp.mAllowLocalLAN); + boolean retryOnAuthFailed = mVp.mAuthRetry == AUTH_RETRY_NOINTERACT; + config.setRetryOnAuthFailed(retryOnAuthFailed); + + ClientAPI_EvalConfig ec = eval_config(config); + if (ec.getExternalPki()) { + VpnStatus.logDebug("OpenVPN3 core assumes an external PKI config"); + } + if (ec.getError()) { + VpnStatus.logError("OpenVPN config file parse error: " + ec.getMessage()); + return false; + } else { + config.setContent(vpnconfig); + return true; + } + } + + @SuppressLint("HardwareIds") + private String getFakeMacAddrFromSAAID(Context c) { + char[] HEX_ARRAY = "0123456789ABCDEF".toCharArray(); + + String saaid = Settings.Secure.getString(c.getContentResolver(), + Settings.Secure.ANDROID_ID); + + StringBuilder ret = new StringBuilder(); + if (saaid.length() >= 6) { + byte[] sb = saaid.getBytes(); + for (int b = 0; b <= 6; b++) { + if (b != 0) + ret.append(":"); + int v = sb[b] & 0xFF; + ret.append(HEX_ARRAY[v >>> 4]); + ret.append(HEX_ARRAY[v & 0x0F]); + } + } + return ret.toString(); + } + + + @Override + public void external_pki_cert_request(ClientAPI_ExternalPKICertRequest certreq) { + VpnStatus.logDebug("Got external PKI certificate request from OpenVPN core"); + String[] ks = mVp.getExternalCertificates(mService); + if (ks == null) { + certreq.setError(true); + certreq.setErrorText("Error in pki cert request"); + return; + } + + String supcerts = ks[0]; + /* FIXME: How to differentiate between chain and ca certs in OpenVPN 3? */ + if (ks[1] != null) + supcerts += "\n" + ks[1]; + certreq.setSupportingChain(supcerts); + certreq.setCert(ks[2]); + certreq.setError(false); + } + + @Override + public void external_pki_sign_request(ClientAPI_ExternalPKISignRequest signreq) { + VpnStatus.logDebug("Got external PKI signing request from OpenVPN core for algorithm " + signreq.getAlgorithm()); + boolean pkcs1padding; + if (signreq.getAlgorithm().equals("RSA_PKCS1_PADDING")) + pkcs1padding = true; + else if (signreq.getAlgorithm().equals("RSA_NO_PADDING")) + pkcs1padding = false; + else if (signreq.getAlgorithm().equals("ECDSA")) + pkcs1padding = false; + else + throw new IllegalArgumentException("Illegal padding in sign request" + signreq.getAlgorithm()); + signreq.setSig(mVp.getSignedData(mService, signreq.getData(), pkcs1padding)); + } + + void setUserPW() { + if (mVp.isUserPWAuth()) { + ClientAPI_ProvideCreds creds = new ClientAPI_ProvideCreds(); + creds.setCachePassword(true); + creds.setPassword(mVp.getPasswordAuth()); + creds.setUsername(mVp.mUsername); + provide_creds(creds); + } + } + + @Override + public boolean socket_protect(int socket, String remote, boolean ipv6) { + return mService.protect(socket); + + } + + @Override + public boolean stopVPN(boolean replaceConnection) { + stop(); + return false; + } + + @Override + public void networkChange(boolean sameNetwork) { + reconnect(1); + } + + @Override + public void setPauseCallback(PausedStateCallback callback) { + } + + @Override + public void sendCRResponse(String response) { + post_cc_msg("CR_RESPONSE," + response + "\n"); + } + + @Override + public void log(ClientAPI_LogInfo arg0) { + String logmsg = arg0.getText(); + while (logmsg.endsWith("\n")) + logmsg = logmsg.substring(0, logmsg.length() - 1); + + VpnStatus.logInfo(logmsg); + } + + @Override + public void event(ClientAPI_Event event) { + String name = event.getName(); + String info = event.getInfo(); + if (name.equals("INFO")) { + if (info.startsWith("OPEN_URL:") || info.startsWith("CR_TEXT:")) { + mService.trigger_sso(info); + } else { + VpnStatus.logInfo(R.string.info_from_server, info); + } + } else if (name.equals("COMPRESSION_ENABLED")) { + VpnStatus.logInfo(String.format(Locale.US, "%s: %s", name, info)); + } else { + VpnStatus.updateStateString(name, info); + } + /* if (event.name.equals("DYNAMIC_CHALLENGE")) { + ClientAPI_DynamicChallenge challenge = new ClientAPI_DynamicChallenge(); + final boolean status = ClientAPI_OpenVPNClient.parse_dynamic_challenge(event.info, challenge); + + } else */ + if (event.getError()) + VpnStatus.logError(String.format("EVENT(Error): %s: %s", name, info)); + } + + @Override + public net.openvpn.ovpn3.ClientAPI_StringVec tun_builder_get_local_networks(boolean ipv6) { + + net.openvpn.ovpn3.ClientAPI_StringVec nets = new net.openvpn.ovpn3.ClientAPI_StringVec(); + for (String net : NetworkUtils.getLocalNetworks(mService, ipv6)) + nets.add(net); + return nets; + } + + @Override + public boolean pause_on_connection_timeout() { + VpnStatus.logInfo("pause on connection timeout?! "); + return true; + } + + + // When a connection is close to timeout, the core will call this + // method. If it returns false, the core will disconnect with a + // CONNECTION_TIMEOUT event. If true, the core will enter a PAUSE + // state. + + @Override + public void stop() { + super.stop(); + mService.openvpnStopped(); + } + + @Override + public void reconnect() { + reconnect(1); + } + + @Override + public void pause(pauseReason reason) { + super.pause(reason.toString()); + } + + class StatusPoller implements Runnable { + boolean mStopped = false; + private long mSleeptime; + + public StatusPoller(long sleeptime) { + mSleeptime = sleeptime; + } + + public void run() { + while (!mStopped) { + try { + Thread.sleep(mSleeptime); + } catch (InterruptedException e) { + } + ClientAPI_TransportStats t = transport_stats(); + long in = t.getBytesIn(); + long out = t.getBytesOut(); + VpnStatus.updateByteCount(in, out); + } + } + + public void stop() { + mStopped = true; + } + } + + +} -- cgit v1.2.3