Prebuilt binaries for third-party submodules (#252)

* Add prebuilt submodule
* Remove Android native library
* Add links for Android prebuilt library
* Update OpenSSL to prebuilt binaries
* Setup links for prebuilt OpenSSL
* Set correct OpenSSL header dir
* Update prebuilt submodule
* Use static OpenSSL for linux build
* Use prebuilt binary from 3rd-prebuilt for Win installer
* Use prebuilt binary from 3rd-prebuilt for Linux installer
* Use prebuilt binary from 3rd-prebuilt for MacOS installer
* Use Android prebuilt openvpn libs
* Cleanup some unneeded code
* Add new maven repo for gradle-versions-plugin
* Use jitpack version of jsocks
* Fix some unnecessary header copy
* Fix issue with package name of original WG libs
* Change submodule path to https (3rd-prebuilt)
* Fix windows installer
* MacOS deploy fixes
* NetworkChange detection for OpenVPN protocol (#256)
* NetworkChange detection for OpenVPN protocol
* Update android native libs
* Always on VPN mode for OpenVPN, Cloak+OpenVPN
* Set foregroundService type
* Android 14 require to set foregroundServiceType
* Remove unused code and cleanup submodules
* Cleanup gradle build script
* Fix start button status
* Pull OpenSSL prebuilt for MacOS, iOS
* Update links for OpenSSL MacOS, iOS prebuilt
* Update OpenSSL binaries path
* Refactor some OpenSSL includes
* Update MacOS OpenVPN binary with statically linked dependency
* Use prebilt for LibSSH
* Android resources cleanup
* Set static runtime linux
* Use shared LibSSH for Android
* Update SS Android lib name
* Fix Linux install path and file permissions
* Feature/iOS GitHub actions (#265)
* Move Android cpp code to openvpn-pt-android repo
* Remove unused OpenVPN2 Android Libs
* Cleanup Gemfile

---------

Co-authored-by: Mazay B <pokamest@gmail.com>
This commit is contained in:
Mykola Baibuz 2023-08-04 20:35:43 +03:00 committed by GitHub
parent 9bd8c774ab
commit f58a16ca9d
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
327 changed files with 500 additions and 45808 deletions

View file

@ -0,0 +1,19 @@
package com.wireguard.android.backend;
public final class GoBackend {
private static final String TAG = "WireGuard/GoBackend";
public static native String wgGetConfig(int handle);
public static native int wgGetSocketV4(int handle);
public static native int wgGetSocketV6(int handle);
public static native void wgTurnOff(int handle);
public static native int wgTurnOn(String ifName, int tunFd, String settings);
public static native String wgVersion();
}

View file

@ -0,0 +1,195 @@
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
package org.amnezia.vpn
import android.content.Context
import android.content.Intent
import android.os.*
import android.net.*
import android.system.ErrnoException
import android.net.NetworkCapabilities
import android.net.NetworkCapabilities.NET_CAPABILITY_CAPTIVE_PORTAL
import android.net.NetworkCapabilities.NET_CAPABILITY_DUN
import android.net.NetworkCapabilities.NET_CAPABILITY_FOREGROUND
import android.net.NetworkCapabilities.NET_CAPABILITY_FOTA
import android.net.NetworkCapabilities.NET_CAPABILITY_IA
import android.net.NetworkCapabilities.NET_CAPABILITY_IMS
import android.net.NetworkCapabilities.NET_CAPABILITY_INTERNET
import android.net.NetworkCapabilities.NET_CAPABILITY_MCX
import android.net.NetworkCapabilities.NET_CAPABILITY_MMS
import android.net.NetworkCapabilities.NET_CAPABILITY_NOT_CONGESTED
import android.net.NetworkCapabilities.NET_CAPABILITY_NOT_METERED
import android.net.NetworkCapabilities.NET_CAPABILITY_NOT_ROAMING
import android.net.NetworkCapabilities.NET_CAPABILITY_NOT_SUSPENDED
import android.net.NetworkCapabilities.NET_CAPABILITY_NOT_VPN
import android.net.NetworkCapabilities.NET_CAPABILITY_SUPL
import android.net.NetworkCapabilities.NET_CAPABILITY_TEMPORARILY_NOT_METERED
import android.net.NetworkCapabilities.NET_CAPABILITY_TRUSTED
import android.net.NetworkCapabilities.NET_CAPABILITY_VALIDATED
import android.net.NetworkCapabilities.NET_CAPABILITY_WIFI_P2P
import android.net.NetworkCapabilities.NET_CAPABILITY_XCAP
import android.net.NetworkCapabilities.TRANSPORT_BLUETOOTH
import android.net.NetworkCapabilities.TRANSPORT_CELLULAR
import android.net.NetworkCapabilities.TRANSPORT_ETHERNET
import android.net.NetworkCapabilities.TRANSPORT_LOWPAN
import android.net.NetworkCapabilities.TRANSPORT_USB
import android.net.NetworkCapabilities.TRANSPORT_VPN
import android.net.NetworkCapabilities.TRANSPORT_WIFI
import android.net.NetworkCapabilities.TRANSPORT_WIFI_AWARE
import java.io.Closeable
import java.util.EnumSet
import java.io.File
import androidx.core.app.ActivityCompat
import androidx.core.content.ContextCompat
import java.io.FileDescriptor
import java.io.IOException
import java.lang.Exception
class NetworkState(var service: VPNService) {
private var mService: VPNService = service
var mCurrentContext: Context = service
private val tag = "NetworkState"
private var active = false
private var listeningForDefaultNetwork = false
private var metered = false
enum class Transport(val systemConstant: Int) {
BLUETOOTH(TRANSPORT_BLUETOOTH),
CELLULAR(TRANSPORT_CELLULAR),
ETHERNET(TRANSPORT_ETHERNET),
VPN(TRANSPORT_VPN),
WIFI(TRANSPORT_WIFI),
WIFI_AWARE(if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) TRANSPORT_WIFI_AWARE else UNSUPPORTED_TRANSPORT),
LOWPAN(if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O_MR1) TRANSPORT_LOWPAN else UNSUPPORTED_TRANSPORT),
USB(if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.S) TRANSPORT_USB else UNSUPPORTED_TRANSPORT)
}
companion object {
private const val UNSUPPORTED_TRANSPORT: Int = -1 // The TRANSPORT_* constants are non-negative.
private const val NOT_VPN = "NOT_VPN"
private val defaultNetworkRequest = NetworkRequest.Builder()
.addCapability(NetworkCapabilities.NET_CAPABILITY_INTERNET)
.addCapability(NetworkCapabilities.NET_CAPABILITY_NOT_RESTRICTED)
.build()
}
private data class NetworkTransports(
val network: Network,
val transports: Set<Transport>
)
private fun getTransports(networkCapabilities: NetworkCapabilities): EnumSet<Transport> =
Transport.values().mapNotNullTo(EnumSet.noneOf(Transport::class.java)) {
if (networkCapabilities.hasTransport(it.systemConstant)) it else null
}
private var defaultNetworkCapabilities: Map<String, Boolean> = LinkedHashMap()
private var defaultNetwork: NetworkTransports? = null
val defaultNetworkTransports: Set<Transport>
get() = defaultNetwork?.transports ?: emptySet()
private val capabilitiesConstantMap = mutableMapOf(
"MMS" to NET_CAPABILITY_MMS,
"SUPL" to NET_CAPABILITY_SUPL,
"DUN" to NET_CAPABILITY_DUN,
"FOTA" to NET_CAPABILITY_FOTA,
"IMS" to NET_CAPABILITY_IMS,
"WIFI_P2P" to NET_CAPABILITY_WIFI_P2P,
"IA" to NET_CAPABILITY_IA,
"XCAP" to NET_CAPABILITY_XCAP,
"NOT_METERED" to NET_CAPABILITY_NOT_METERED,
"INTERNET" to NET_CAPABILITY_INTERNET,
NOT_VPN to NET_CAPABILITY_NOT_VPN,
"TRUSTED" to NET_CAPABILITY_TRUSTED,
"TEMP NOT METERED" to NET_CAPABILITY_TEMPORARILY_NOT_METERED,
"NOT SUSPENDED" to NET_CAPABILITY_MCX,
).apply {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
put("VALIDATED", NET_CAPABILITY_VALIDATED)
put("CAPTIVE PORTAL", NET_CAPABILITY_CAPTIVE_PORTAL)
}
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.P) {
put("NOT ROAMING", NET_CAPABILITY_NOT_ROAMING)
put("TRUSTED", NET_CAPABILITY_FOREGROUND)
put("NOT CONGESTED", NET_CAPABILITY_NOT_CONGESTED)
put("NOT SUSPENDED", NET_CAPABILITY_NOT_SUSPENDED)
}
} as Map<String, Int>
private val connectivity by lazy { mCurrentContext.getSystemService(Context.CONNECTIVITY_SERVICE) as ConnectivityManager }
private var mLastNetworkCapabilities: String? = null
private val defaultNetworkCallback = object : ConnectivityManager.NetworkCallback() {
override fun onAvailable(network: Network) {
super.onAvailable(network)
Log.i(tag, "onAvailable $network")
}
override fun onCapabilitiesChanged(network: Network, networkCapabilities: NetworkCapabilities) {
val newCapabilities = capabilitiesConstantMap.mapValues {
networkCapabilities.hasCapability(it.value)
}
val newTransports = getTransports(networkCapabilities)
val capabilitiesChanged = defaultNetworkCapabilities != newCapabilities
if (defaultNetwork?.network != network ||
defaultNetwork?.transports != newTransports ||
capabilitiesChanged
) {
Log.i(
tag,
"default network: $network; transports: ${newTransports.joinToString(", ")}; " +
"capabilities: $newCapabilities"
)
defaultNetwork = NetworkTransports(network, newTransports)
}
if (capabilitiesChanged) {
mService.networkChange()
Log.i(tag, "onCapabilitiesChanged capabilitiesChanged $network $networkCapabilities")
defaultNetworkCapabilities = newCapabilities
}
super.onCapabilitiesChanged(network, networkCapabilities)
}
override fun onBlockedStatusChanged(network: Network, blocked: Boolean) {
super.onBlockedStatusChanged(network, blocked)
Log.i(tag, "onBlockedStatusChanged $network $blocked")
}
override fun onLost(network: Network) {
super.onLost(network)
Log.i(tag, "onLost")
}
}
fun bindNetworkListener() {
if (Build.VERSION.SDK_INT >= 28) {
// we want REQUEST here instead of LISTEN
connectivity.requestNetwork(defaultNetworkRequest, defaultNetworkCallback)
listeningForDefaultNetwork = true
}
}
fun unBindNetworkListener() {
if (Build.VERSION.SDK_INT >= 28) {
connectivity.unregisterNetworkCallback(defaultNetworkCallback)
listeningForDefaultNetwork = false
}
}
}

View file

@ -26,6 +26,8 @@ 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.lang.StringBuilder
class OpenVPNThreadv3(var service: VPNService): ClientAPI_OpenVPNClient(), Runnable {
@ -58,6 +60,12 @@ class OpenVPNThreadv3(var service: VPNService): ClientAPI_OpenVPNClient(), Runna
return stats_value(bytesOutIndex)
}
override fun reconnect(seconds :Int) {
Log.v(tag, "reconnect")
super.reconnect(seconds)
}
override fun run() {
val config: ClientAPI_Config = ClientAPI_Config()

View file

@ -20,6 +20,7 @@ import androidx.core.content.FileProvider
import com.wireguard.android.util.SharedLibraryLoader
import com.wireguard.config.*
import com.wireguard.crypto.Key
import com.wireguard.android.backend.GoBackend
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.delay
import kotlinx.coroutines.launch
@ -48,6 +49,7 @@ import android.net.VpnService as BaseVpnService
class VPNService : BaseVpnService(), LocalDnsService.Interface {
override val data = BaseService.Data(this)
override val tag: String get() = "VPNService"
// override fun createNotification(profileName: String): ServiceNotification =
// ServiceNotification(this, profileName, "service-vpn")
@ -56,6 +58,7 @@ class VPNService : BaseVpnService(), LocalDnsService.Interface {
private var worker: ProtectWorker? = null
private var active = false
private var metered = false
private var mNetworkState = NetworkState(this)
private var underlyingNetwork: Network? = null
set(value) {
field = value
@ -121,23 +124,6 @@ class VPNService : BaseVpnService(), LocalDnsService.Interface {
})
}
@JvmStatic
private external fun wgGetConfig(handle: Int): String?
@JvmStatic
private external fun wgGetSocketV4(handle: Int): Int
@JvmStatic
private external fun wgGetSocketV6(handle: Int): Int
@JvmStatic
private external fun wgTurnOff(handle: Int)
@JvmStatic
private external fun wgTurnOn(ifName: String, tunFd: Int, settings: String): Int
@JvmStatic
private external fun wgVersion(): String?
}
private var mBinder: VPNServiceBinder = VPNServiceBinder(this)
@ -162,7 +148,7 @@ class VPNService : BaseVpnService(), LocalDnsService.Interface {
SharedLibraryLoader.loadSharedLibrary(this, "wg-go")
SharedLibraryLoader.loadSharedLibrary(this, "ovpn3")
Log.i(tag, "Loaded libs")
Log.e(tag, "Wireguard Version ${wgVersion()}")
Log.e(tag, "Wireguard Version ${GoBackend.wgVersion()}")
mOpenVPNThreadv3 = OpenVPNThreadv3(this)
mAlreadyInitialised = true
}
@ -241,6 +227,10 @@ class VPNService : BaseVpnService(), LocalDnsService.Interface {
mProtocol = mConfig!!.getString("protocol")
Log.e(tag, "mProtocol: $mProtocol")
if (mProtocol.equals("cloak", true) || (mProtocol.equals("openvpn", true))) {
startOpenVpn()
mNetworkState.bindNetworkListener()
}
if (mProtocol.equals("shadowsocks", true)) {
if (DataStore.serviceMode == modeVpn) {
if (prepare(this) != null) {
@ -266,7 +256,7 @@ class VPNService : BaseVpnService(), LocalDnsService.Interface {
// At this moment, the VPN interface is already deactivated by the system.
override fun onRevoke() {
Log.v(tag, "Aman: onRevoke....................")
this.turnOff()
//this.turnOff()
super.onRevoke()
}
@ -379,7 +369,15 @@ class VPNService : BaseVpnService(), LocalDnsService.Interface {
when (mProtocol) {
"cloak",
"openvpn" -> {
startOpenVpn()
startOpenVpn()
// Store the config in case the service gets
// asked boot vpn from the OS
val prefs = Prefs.get(this)
prefs.edit()
.putString("lastConf", mConfig.toString())
.apply()
mNetworkState.bindNetworkListener()
}
"wireguard" -> {
startWireGuard()
@ -428,6 +426,14 @@ class VPNService : BaseVpnService(), LocalDnsService.Interface {
mbuilder.addRoute(ip, 32)
}
}
fun networkChange() {
Log.i(tag, "mProtocol $mProtocol")
if (isUp){
mbuilder = Builder()
mOpenVPNThreadv3?.reconnect(0)
}
}
fun setSessionName(name: String) {
Log.v(tag, "mbuilder.setSession($name)")
@ -452,11 +458,12 @@ class VPNService : BaseVpnService(), LocalDnsService.Interface {
Log.v(tag, "Aman: turnOff....................")
when (mProtocol) {
"wireguard" -> {
wgTurnOff(currentTunnelHandle)
GoBackend.wgTurnOff(currentTunnelHandle)
}
"cloak",
"openvpn" -> {
ovpnTurnOff()
mNetworkState.unBindNetworkListener()
}
"shadowsocks" -> {
stopRunner(false)
@ -517,7 +524,7 @@ class VPNService : BaseVpnService(), LocalDnsService.Interface {
if (!isUp) {
return null
}
val config = wgGetConfig(currentTunnelHandle) ?: return null
val config = GoBackend.wgGetConfig(currentTunnelHandle) ?: return null
val lines = config.split("\n")
for (line in lines) {
val parts = line.split("=")
@ -715,7 +722,7 @@ class VPNService : BaseVpnService(), LocalDnsService.Interface {
if (currentTunnelHandle != -1) {
Log.e(tag, "Tunnel already up")
// Turn the tunnel down because this might be a switch
wgTurnOff(currentTunnelHandle)
GoBackend.wgTurnOff(currentTunnelHandle)
}
val wgConfig: String = wireguard_conf.toWgUserspaceString()
val builder = Builder()
@ -723,16 +730,15 @@ class VPNService : BaseVpnService(), LocalDnsService.Interface {
builder.setSession("Amnezia")
builder.establish().use { tun ->
if (tun == null) return
Log.i(tag, "Go backend " + wgVersion())
currentTunnelHandle = wgTurnOn("Amnezia", tun.detachFd(), wgConfig)
currentTunnelHandle = GoBackend.wgTurnOn("Amnezia", tun.detachFd(), wgConfig)
}
if (currentTunnelHandle < 0) {
Log.e(tag, "Activation Error Code -> $currentTunnelHandle")
isUp = false
return
}
protect(wgGetSocketV4(currentTunnelHandle))
protect(wgGetSocketV6(currentTunnelHandle))
protect(GoBackend.wgGetSocketV4(currentTunnelHandle))
protect(GoBackend.wgGetSocketV6(currentTunnelHandle))
isUp = true
// Store the config in case the service gets