Various fixes
This commit is contained in:
parent
cb21991efa
commit
505c9c6218
5 changed files with 306 additions and 295 deletions
|
@ -37,12 +37,13 @@ class VPNService : android.net.VpnService() {
|
||||||
SharedLibraryLoader.loadSharedLibrary(this, "ovpn3")
|
SharedLibraryLoader.loadSharedLibrary(this, "ovpn3")
|
||||||
Log.i(tag, "Loaded libs")
|
Log.i(tag, "Loaded libs")
|
||||||
Log.e(tag, "Wireguard Version ${wgVersion()}")
|
Log.e(tag, "Wireguard Version ${wgVersion()}")
|
||||||
mOpenVPNThreadv3 = OpenVPNThreadv3 (this)
|
mOpenVPNThreadv3 = OpenVPNThreadv3(this)
|
||||||
mAlreadyInitialised = true
|
mAlreadyInitialised = true
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun onUnbind(intent: Intent?): Boolean {
|
override fun onUnbind(intent: Intent?): Boolean {
|
||||||
|
Log.v(tag, "Got Unbind request")
|
||||||
if (!isUp) {
|
if (!isUp) {
|
||||||
// If the Qt Client got closed while we were not connected
|
// If the Qt Client got closed while we were not connected
|
||||||
// we do not need to stay as a foreground service.
|
// we do not need to stay as a foreground service.
|
||||||
|
@ -52,9 +53,9 @@ class VPNService : android.net.VpnService() {
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* EntryPoint for the Service, gets Called when AndroidController.cpp
|
* EntryPoint for the Service, gets Called when AndroidController.cpp
|
||||||
* calles bindService. Returns the [VPNServiceBinder] so QT can send Requests to it.
|
* calles bindService. Returns the [VPNServiceBinder] so QT can send Requests to it.
|
||||||
*/
|
*/
|
||||||
override fun onBind(intent: Intent?): IBinder? {
|
override fun onBind(intent: Intent?): IBinder? {
|
||||||
Log.v(tag, "Got Bind request")
|
Log.v(tag, "Got Bind request")
|
||||||
init()
|
init()
|
||||||
|
@ -62,10 +63,10 @@ class VPNService : android.net.VpnService() {
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Might be the entryPoint if the Service gets Started via an
|
* Might be the entryPoint if the Service gets Started via an
|
||||||
* Service Intent: Might be from Always-On-Vpn from Settings
|
* Service Intent: Might be from Always-On-Vpn from Settings
|
||||||
* or from Booting the device and having "connect on boot" enabled.
|
* or from Booting the device and having "connect on boot" enabled.
|
||||||
*/
|
*/
|
||||||
override fun onStartCommand(intent: Intent?, flags: Int, startId: Int): Int {
|
override fun onStartCommand(intent: Intent?, flags: Int, startId: Int): Int {
|
||||||
init()
|
init()
|
||||||
intent?.let {
|
intent?.let {
|
||||||
|
@ -84,28 +85,28 @@ class VPNService : android.net.VpnService() {
|
||||||
Log.e(
|
Log.e(
|
||||||
tag,
|
tag,
|
||||||
"VPN service was triggered without defining a Server or having a tunnel"
|
"VPN service was triggered without defining a Server or having a tunnel"
|
||||||
)
|
)
|
||||||
return super.onStartCommand(intent, flags, startId)
|
return super.onStartCommand(intent, flags, startId)
|
||||||
}
|
|
||||||
this.mConfig = JSONObject(lastConfString)
|
|
||||||
}
|
}
|
||||||
|
this.mConfig = JSONObject(lastConfString)
|
||||||
return super.onStartCommand(intent, flags, startId)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Invoked when the application is revoked.
|
return super.onStartCommand(intent, flags, startId)
|
||||||
// At this moment, the VPN interface is already deactivated by the system.
|
}
|
||||||
override fun onRevoke() {
|
|
||||||
this.turnOff()
|
|
||||||
super.onRevoke()
|
|
||||||
}
|
|
||||||
|
|
||||||
var connectionTime: Long = 0
|
// Invoked when the application is revoked.
|
||||||
|
// At this moment, the VPN interface is already deactivated by the system.
|
||||||
|
override fun onRevoke() {
|
||||||
|
this.turnOff()
|
||||||
|
super.onRevoke()
|
||||||
|
}
|
||||||
|
|
||||||
|
var connectionTime: Long = 0
|
||||||
get() {
|
get() {
|
||||||
return mConnectionTime
|
return mConnectionTime
|
||||||
}
|
}
|
||||||
|
|
||||||
var isUp: Boolean
|
var isUp: Boolean
|
||||||
get() {
|
get() {
|
||||||
return currentTunnelHandle >= 0
|
return currentTunnelHandle >= 0
|
||||||
}
|
}
|
||||||
|
@ -118,7 +119,7 @@ class VPNService : android.net.VpnService() {
|
||||||
mBinder.dispatchEvent(VPNServiceBinder.EVENTS.disconnected, "")
|
mBinder.dispatchEvent(VPNServiceBinder.EVENTS.disconnected, "")
|
||||||
mConnectionTime = 0
|
mConnectionTime = 0
|
||||||
}
|
}
|
||||||
val status: JSONObject
|
val status: JSONObject
|
||||||
get() {
|
get() {
|
||||||
val deviceIpv4: String = ""
|
val deviceIpv4: String = ""
|
||||||
return JSONObject().apply {
|
return JSONObject().apply {
|
||||||
|
@ -128,299 +129,308 @@ class VPNService : android.net.VpnService() {
|
||||||
putOpt("deviceIpv4", mConfig?.getJSONObject("device")?.getString("ipv4Address"))
|
putOpt("deviceIpv4", mConfig?.getJSONObject("device")?.getString("ipv4Address"))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
/*
|
|
||||||
* Checks if the VPN Permission is given.
|
|
||||||
* If the permission is given, returns true
|
|
||||||
* Requests permission and returns false if not.
|
|
||||||
*/
|
|
||||||
fun checkPermissions(): Boolean {
|
|
||||||
// See https://developer.android.com/guide/topics/connectivity/vpn#connect_a_service
|
|
||||||
// Call Prepare, if we get an Intent back, we dont have the VPN Permission
|
|
||||||
// from the user. So we need to pass this to our main Activity and exit here.
|
|
||||||
val intent = prepare(this)
|
|
||||||
if (intent == null) {
|
|
||||||
Log.e(tag, "VPN Permission Already Present")
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
Log.e(tag, "Requesting VPN Permission")
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
|
|
||||||
fun turnOn(json: JSONObject?): Int {
|
/*
|
||||||
if (!checkPermissions()) {
|
* Checks if the VPN Permission is given.
|
||||||
Log.e(tag, "turn on was called without no permissions present!")
|
* If the permission is given, returns true
|
||||||
isUp = false
|
* Requests permission and returns false if not.
|
||||||
return 0
|
*/
|
||||||
}
|
fun checkPermissions(): Boolean {
|
||||||
Log.i(tag, "Permission okay")
|
// See https://developer.android.com/guide/topics/connectivity/vpn#connect_a_service
|
||||||
mConfig = json!!
|
// Call Prepare, if we get an Intent back, we dont have the VPN Permission
|
||||||
mProtocol = mConfig!!.getString("protocol")
|
// from the user. So we need to pass this to our main Activity and exit here.
|
||||||
when (mProtocol) {
|
val intent = prepare(this)
|
||||||
"openvpn" -> startOpenVpn()
|
if (intent == null) {
|
||||||
"wireguard" -> startWireGuard()
|
Log.e(tag, "VPN Permission Already Present")
|
||||||
else -> {
|
|
||||||
Log.e(tag, "No protocol")
|
|
||||||
return 0
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return 1
|
|
||||||
}
|
|
||||||
|
|
||||||
fun establish(): ParcelFileDescriptor? {
|
|
||||||
mbuilder.allowFamily(OsConstants.AF_INET)
|
|
||||||
mbuilder.allowFamily(OsConstants.AF_INET6)
|
|
||||||
|
|
||||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) mbuilder.setMetered(false)
|
|
||||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) setUnderlyingNetworks(null)
|
|
||||||
|
|
||||||
return mbuilder.establish()
|
|
||||||
}
|
|
||||||
|
|
||||||
fun setMtu(mtu: Int) {
|
|
||||||
mbuilder.setMtu(mtu)
|
|
||||||
}
|
|
||||||
|
|
||||||
fun addAddress(ip: String, len: Int){
|
|
||||||
Log.v(tag, "mbuilder.addAddress($ip, $len)")
|
|
||||||
mbuilder.addAddress(ip, len)
|
|
||||||
}
|
|
||||||
|
|
||||||
fun addRoute(ip: String, len: Int){
|
|
||||||
Log.v(tag, "mbuilder.addRoute($ip, $len)")
|
|
||||||
mbuilder.addRoute(ip, len)
|
|
||||||
}
|
|
||||||
|
|
||||||
fun addDNS(ip: String){
|
|
||||||
Log.v(tag, "mbuilder.addDnsServer($ip)")
|
|
||||||
mbuilder.addDnsServer(ip)
|
|
||||||
if ("samsung".equals(Build.BRAND) && Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP){
|
|
||||||
mbuilder.addRoute(ip, 32)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fun setSessionName(name: String){
|
|
||||||
Log.v(tag, "mbuilder.setSession($name)")
|
|
||||||
mbuilder.setSession(name)
|
|
||||||
}
|
|
||||||
|
|
||||||
fun addHttpProxy(host: String, port: Int): Boolean{
|
|
||||||
val proxyInfo = ProxyInfo.buildDirectProxy(host, port)
|
|
||||||
Log.v(tag, "mbuilder.addHttpProxy($host, $port)")
|
|
||||||
mbuilder.setHttpProxy(proxyInfo)
|
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
|
Log.e(tag, "Requesting VPN Permission")
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
fun setDomain(domain: String) {
|
fun turnOn(json: JSONObject?): Int {
|
||||||
Log.v(tag, "mbuilder.setDomain($domain)")
|
if (!checkPermissions()) {
|
||||||
mbuilder.addSearchDomain(domain)
|
Log.e(tag, "turn on was called without no permissions present!")
|
||||||
}
|
|
||||||
|
|
||||||
fun turnOff() {
|
|
||||||
Log.v(tag, "Try to disable tunnel")
|
|
||||||
when(mProtocol){
|
|
||||||
"wireguard" -> wgTurnOff(currentTunnelHandle)
|
|
||||||
"openvpn" -> ovpnTurnOff()
|
|
||||||
else -> {
|
|
||||||
Log.e(tag, "No protocol")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
currentTunnelHandle = -1
|
|
||||||
stopForeground(true)
|
|
||||||
|
|
||||||
isUp = false
|
isUp = false
|
||||||
stopSelf();
|
return 0
|
||||||
}
|
}
|
||||||
|
Log.i(tag, "Permission okay")
|
||||||
|
mConfig = json!!
|
||||||
|
mProtocol = mConfig!!.getString("protocol")
|
||||||
|
when (mProtocol) {
|
||||||
|
"openvpn" -> startOpenVpn()
|
||||||
|
"wireguard" -> startWireGuard()
|
||||||
|
else -> {
|
||||||
|
Log.e(tag, "No protocol")
|
||||||
|
return 0
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return 1
|
||||||
|
}
|
||||||
|
|
||||||
|
fun establish(): ParcelFileDescriptor? {
|
||||||
|
mbuilder.allowFamily(OsConstants.AF_INET)
|
||||||
|
mbuilder.allowFamily(OsConstants.AF_INET6)
|
||||||
|
|
||||||
|
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) mbuilder.setMetered(false)
|
||||||
|
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) setUnderlyingNetworks(null)
|
||||||
|
|
||||||
|
return mbuilder.establish()
|
||||||
|
}
|
||||||
|
|
||||||
|
fun setMtu(mtu: Int) {
|
||||||
|
mbuilder.setMtu(mtu)
|
||||||
|
}
|
||||||
|
|
||||||
|
fun addAddress(ip: String, len: Int) {
|
||||||
|
Log.v(tag, "mbuilder.addAddress($ip, $len)")
|
||||||
|
mbuilder.addAddress(ip, len)
|
||||||
|
}
|
||||||
|
|
||||||
|
fun addRoute(ip: String, len: Int) {
|
||||||
|
Log.v(tag, "mbuilder.addRoute($ip, $len)")
|
||||||
|
mbuilder.addRoute(ip, len)
|
||||||
|
}
|
||||||
|
|
||||||
|
fun addDNS(ip: String) {
|
||||||
|
Log.v(tag, "mbuilder.addDnsServer($ip)")
|
||||||
|
mbuilder.addDnsServer(ip)
|
||||||
|
if ("samsung".equals(Build.BRAND) && Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
|
||||||
|
mbuilder.addRoute(ip, 32)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fun setSessionName(name: String) {
|
||||||
|
Log.v(tag, "mbuilder.setSession($name)")
|
||||||
|
mbuilder.setSession(name)
|
||||||
|
}
|
||||||
|
|
||||||
|
fun addHttpProxy(host: String, port: Int): Boolean {
|
||||||
|
val proxyInfo = ProxyInfo.buildDirectProxy(host, port)
|
||||||
|
Log.v(tag, "mbuilder.addHttpProxy($host, $port)")
|
||||||
|
mbuilder.setHttpProxy(proxyInfo)
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
|
fun setDomain(domain: String) {
|
||||||
|
Log.v(tag, "mbuilder.setDomain($domain)")
|
||||||
|
mbuilder.addSearchDomain(domain)
|
||||||
|
}
|
||||||
|
|
||||||
|
fun turnOff() {
|
||||||
|
Log.v(tag, "Try to disable tunnel")
|
||||||
|
when (mProtocol) {
|
||||||
|
"wireguard" -> wgTurnOff(currentTunnelHandle)
|
||||||
|
"openvpn" -> ovpnTurnOff()
|
||||||
|
else -> {
|
||||||
|
Log.e(tag, "No protocol")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
currentTunnelHandle = -1
|
||||||
|
stopForeground(true)
|
||||||
|
|
||||||
|
isUp = false
|
||||||
|
stopSelf();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
private fun ovpnTurnOff() {
|
private fun ovpnTurnOff() {
|
||||||
mOpenVPNThreadv3?.stop()
|
mOpenVPNThreadv3?.stop()
|
||||||
mOpenVPNThreadv3 = null
|
mOpenVPNThreadv3 = null
|
||||||
Log.e(tag, "mOpenVPNThreadv3 stop!")
|
Log.e(tag, "mOpenVPNThreadv3 stop!")
|
||||||
}
|
}
|
||||||
/**
|
|
||||||
* Configures an Android VPN Service Tunnel
|
/**
|
||||||
* with a given Wireguard Config
|
* Configures an Android VPN Service Tunnel
|
||||||
*/
|
* with a given Wireguard Config
|
||||||
private fun setupBuilder(config: Config, builder: Builder) {
|
*/
|
||||||
// Setup Split tunnel
|
private fun setupBuilder(config: Config, builder: Builder) {
|
||||||
for (excludedApplication in config.`interface`.excludedApplications)
|
// Setup Split tunnel
|
||||||
|
for (excludedApplication in config.`interface`.excludedApplications)
|
||||||
builder.addDisallowedApplication(excludedApplication)
|
builder.addDisallowedApplication(excludedApplication)
|
||||||
|
|
||||||
// Device IP
|
// Device IP
|
||||||
for (addr in config.`interface`.addresses) builder.addAddress(addr.address, addr.mask)
|
for (addr in config.`interface`.addresses) builder.addAddress(addr.address, addr.mask)
|
||||||
// DNS
|
// DNS
|
||||||
for (addr in config.`interface`.dnsServers) builder.addDnsServer(addr.hostAddress)
|
for (addr in config.`interface`.dnsServers) builder.addDnsServer(addr.hostAddress)
|
||||||
// Add All routes the VPN may route tos
|
// Add All routes the VPN may route tos
|
||||||
for (peer in config.peers) {
|
for (peer in config.peers) {
|
||||||
for (addr in peer.allowedIps) {
|
for (addr in peer.allowedIps) {
|
||||||
builder.addRoute(addr.address, addr.mask)
|
builder.addRoute(addr.address, addr.mask)
|
||||||
}
|
|
||||||
}
|
}
|
||||||
builder.allowFamily(OsConstants.AF_INET)
|
|
||||||
builder.allowFamily(OsConstants.AF_INET6)
|
|
||||||
builder.setMtu(config.`interface`.mtu.orElse(1280))
|
|
||||||
|
|
||||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) builder.setMetered(false)
|
|
||||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) setUnderlyingNetworks(null)
|
|
||||||
|
|
||||||
builder.setBlocking(true)
|
|
||||||
}
|
}
|
||||||
|
builder.allowFamily(OsConstants.AF_INET)
|
||||||
|
builder.allowFamily(OsConstants.AF_INET6)
|
||||||
|
builder.setMtu(config.`interface`.mtu.orElse(1280))
|
||||||
|
|
||||||
/**
|
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) builder.setMetered(false)
|
||||||
* Gets config value for {key} from the Current
|
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) setUnderlyingNetworks(null)
|
||||||
* running Wireguard tunnel
|
|
||||||
*/
|
builder.setBlocking(true)
|
||||||
private fun getConfigValue(key: String): String? {
|
}
|
||||||
if (!isUp) {
|
|
||||||
return null
|
/**
|
||||||
}
|
* Gets config value for {key} from the Current
|
||||||
val config = wgGetConfig(currentTunnelHandle) ?: return null
|
* running Wireguard tunnel
|
||||||
val lines = config.split("\n")
|
*/
|
||||||
for (line in lines) {
|
private fun getConfigValue(key: String): String? {
|
||||||
val parts = line.split("=")
|
if (!isUp) {
|
||||||
val k = parts.first()
|
|
||||||
val value = parts.last()
|
|
||||||
if (key == k) {
|
|
||||||
return value
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return null
|
return null
|
||||||
}
|
}
|
||||||
|
val config = wgGetConfig(currentTunnelHandle) ?: return null
|
||||||
|
val lines = config.split("\n")
|
||||||
|
for (line in lines) {
|
||||||
|
val parts = line.split("=")
|
||||||
|
val k = parts.first()
|
||||||
|
val value = parts.last()
|
||||||
|
if (key == k) {
|
||||||
|
return value
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return null
|
||||||
|
}
|
||||||
|
|
||||||
private fun parseConfigData(data: String): Map<String, Map<String, String>> {
|
private fun parseConfigData(data: String): Map<String, Map<String, String>> {
|
||||||
val parseData = mutableMapOf<String, Map<String, String>>()
|
val parseData = mutableMapOf<String, Map<String, String>>()
|
||||||
var currentSection: Pair<String, MutableMap<String, String>>? = null
|
var currentSection: Pair<String, MutableMap<String, String>>? = null
|
||||||
data.lines().forEach { line ->
|
data.lines().forEach { line ->
|
||||||
if (line.isNotEmpty()) {
|
if (line.isNotEmpty()) {
|
||||||
if (line.startsWith('[')) {
|
if (line.startsWith('[')) {
|
||||||
currentSection?.let {
|
currentSection?.let {
|
||||||
parseData.put(it.first, it.second)
|
parseData.put(it.first, it.second)
|
||||||
}
|
|
||||||
currentSection = line.substring(1, line.indexOfLast { it == ']' }) to mutableMapOf()
|
|
||||||
} else {
|
|
||||||
val parameter = line.split("=", limit = 2)
|
|
||||||
currentSection!!.second.put(parameter.first().trim(), parameter.last().trim())
|
|
||||||
}
|
}
|
||||||
|
currentSection =
|
||||||
|
line.substring(1, line.indexOfLast { it == ']' }) to mutableMapOf()
|
||||||
|
} else {
|
||||||
|
val parameter = line.split("=", limit = 2)
|
||||||
|
currentSection!!.second.put(parameter.first().trim(), parameter.last().trim())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
currentSection?.let {
|
}
|
||||||
parseData.put(it.first, it.second)
|
currentSection?.let {
|
||||||
|
parseData.put(it.first, it.second)
|
||||||
|
}
|
||||||
|
return parseData
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create a Wireguard [Config] from a [json] string -
|
||||||
|
* The [json] will be created in AndroidVpnProtocol.cpp
|
||||||
|
*/
|
||||||
|
private fun buildWireugardConfig(obj: JSONObject): Config {
|
||||||
|
val confBuilder = Config.Builder()
|
||||||
|
val wireguardConfigData = obj.getJSONObject("wireguard_config_data")
|
||||||
|
val config = parseConfigData(wireguardConfigData.getString("config"))
|
||||||
|
val peerBuilder = Peer.Builder()
|
||||||
|
val peerConfig = config["Peer"]!!
|
||||||
|
peerBuilder.setPublicKey(Key.fromBase64(peerConfig["PublicKey"]))
|
||||||
|
peerConfig["PresharedKey"]?.let {
|
||||||
|
peerBuilder.setPreSharedKey(Key.fromBase64(it))
|
||||||
|
}
|
||||||
|
val allowedIPList = peerConfig["AllowedIPs"]?.split(",") ?: emptyList()
|
||||||
|
if (allowedIPList.isEmpty()) {
|
||||||
|
val internet = InetNetwork.parse("0.0.0.0/0") // aka The whole internet.
|
||||||
|
peerBuilder.addAllowedIp(internet)
|
||||||
|
} else {
|
||||||
|
allowedIPList.forEach {
|
||||||
|
val network = InetNetwork.parse(it.trim())
|
||||||
|
peerBuilder.addAllowedIp(network)
|
||||||
}
|
}
|
||||||
return parseData
|
}
|
||||||
|
peerBuilder.setEndpoint(InetEndpoint.parse(peerConfig["Endpoint"]))
|
||||||
|
peerConfig["PersistentKeepalive"]?.let {
|
||||||
|
peerBuilder.setPersistentKeepalive(it.toInt())
|
||||||
|
}
|
||||||
|
confBuilder.addPeer(peerBuilder.build())
|
||||||
|
|
||||||
|
val ifaceBuilder = Interface.Builder()
|
||||||
|
val ifaceConfig = config["Interface"]!!
|
||||||
|
ifaceBuilder.parsePrivateKey(ifaceConfig["PrivateKey"])
|
||||||
|
ifaceBuilder.addAddress(InetNetwork.parse(ifaceConfig["Address"]))
|
||||||
|
ifaceConfig["DNS"]!!.split(",").forEach {
|
||||||
|
ifaceBuilder.addDnsServer(InetNetwork.parse(it.trim()).address)
|
||||||
|
}
|
||||||
|
/*val jExcludedApplication = obj.getJSONArray("excludedApps")
|
||||||
|
(0 until jExcludedApplication.length()).toList().forEach {
|
||||||
|
val appName = jExcludedApplication.get(it).toString()
|
||||||
|
ifaceBuilder.excludeApplication(appName)
|
||||||
|
}*/
|
||||||
|
confBuilder.setInterface(ifaceBuilder.build())
|
||||||
|
|
||||||
|
return confBuilder.build()
|
||||||
|
}
|
||||||
|
|
||||||
|
fun getVpnConfig(): JSONObject {
|
||||||
|
return mConfig!!
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun startOpenVpn() {
|
||||||
|
mOpenVPNThreadv3 = OpenVPNThreadv3(this)
|
||||||
|
Thread({
|
||||||
|
mOpenVPNThreadv3?.run()
|
||||||
|
}).start()
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun startWireGuard() {
|
||||||
|
val wireguard_conf = buildWireugardConfig(mConfig!!)
|
||||||
|
if (currentTunnelHandle != -1) {
|
||||||
|
Log.e(tag, "Tunnel already up")
|
||||||
|
// Turn the tunnel down because this might be a switch
|
||||||
|
wgTurnOff(currentTunnelHandle)
|
||||||
|
}
|
||||||
|
val wgConfig: String = wireguard_conf!!.toWgUserspaceString()
|
||||||
|
val builder = Builder()
|
||||||
|
setupBuilder(wireguard_conf, builder)
|
||||||
|
builder.setSession("avpn0")
|
||||||
|
builder.establish().use { tun ->
|
||||||
|
if (tun == null) return
|
||||||
|
Log.i(tag, "Go backend " + wgVersion())
|
||||||
|
currentTunnelHandle = wgTurnOn("avpn0", tun.detachFd(), wgConfig)
|
||||||
|
}
|
||||||
|
if (currentTunnelHandle < 0) {
|
||||||
|
Log.e(tag, "Activation Error Code -> $currentTunnelHandle")
|
||||||
|
isUp = false
|
||||||
|
return
|
||||||
|
}
|
||||||
|
protect(wgGetSocketV4(currentTunnelHandle))
|
||||||
|
protect(wgGetSocketV6(currentTunnelHandle))
|
||||||
|
isUp = true
|
||||||
|
|
||||||
|
// 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()
|
||||||
|
|
||||||
|
NotificationUtil.show(this) // Go foreground
|
||||||
|
}
|
||||||
|
|
||||||
|
companion object {
|
||||||
|
@JvmStatic
|
||||||
|
fun startService(c: Context) {
|
||||||
|
c.applicationContext.startService(
|
||||||
|
Intent(c.applicationContext, VPNService::class.java).apply {
|
||||||
|
putExtra("startOnly", true)
|
||||||
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
@JvmStatic
|
||||||
* Create a Wireguard [Config] from a [json] string -
|
private external fun wgGetConfig(handle: Int): String?
|
||||||
* The [json] will be created in AndroidVpnProtocol.cpp
|
|
||||||
*/
|
|
||||||
private fun buildWireugardConfig(obj: JSONObject): Config {
|
|
||||||
val confBuilder = Config.Builder()
|
|
||||||
val wireguardConfigData = obj.getJSONObject("wireguard_config_data")
|
|
||||||
val config = parseConfigData(wireguardConfigData.getString("config"))
|
|
||||||
val peerBuilder = Peer.Builder()
|
|
||||||
val peerConfig = config["Peer"]!!
|
|
||||||
peerBuilder.setPublicKey(Key.fromBase64(peerConfig["PublicKey"]))
|
|
||||||
peerConfig["PresharedKey"]?.let {
|
|
||||||
peerBuilder.setPreSharedKey(Key.fromBase64(it))
|
|
||||||
}
|
|
||||||
val allowedIPList = peerConfig["AllowedIPs"]?.split(",") ?: emptyList()
|
|
||||||
if (allowedIPList.isEmpty()) {
|
|
||||||
val internet = InetNetwork.parse("0.0.0.0/0") // aka The whole internet.
|
|
||||||
peerBuilder.addAllowedIp(internet)
|
|
||||||
} else {
|
|
||||||
allowedIPList.forEach {
|
|
||||||
val network = InetNetwork.parse(it.trim())
|
|
||||||
peerBuilder.addAllowedIp(network)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
peerBuilder.setEndpoint(InetEndpoint.parse(peerConfig["Endpoint"]))
|
|
||||||
peerConfig["PersistentKeepalive"]?.let {
|
|
||||||
peerBuilder.setPersistentKeepalive(it.toInt())
|
|
||||||
}
|
|
||||||
confBuilder.addPeer(peerBuilder.build())
|
|
||||||
|
|
||||||
val ifaceBuilder = Interface.Builder()
|
@JvmStatic
|
||||||
val ifaceConfig = config["Interface"]!!
|
private external fun wgGetSocketV4(handle: Int): Int
|
||||||
ifaceBuilder.parsePrivateKey(ifaceConfig["PrivateKey"])
|
|
||||||
ifaceBuilder.addAddress(InetNetwork.parse(ifaceConfig["Address"]))
|
|
||||||
ifaceConfig["DNS"]!!.split(",").forEach {
|
|
||||||
ifaceBuilder.addDnsServer(InetNetwork.parse(it.trim()).address)
|
|
||||||
}
|
|
||||||
/*val jExcludedApplication = obj.getJSONArray("excludedApps")
|
|
||||||
(0 until jExcludedApplication.length()).toList().forEach {
|
|
||||||
val appName = jExcludedApplication.get(it).toString()
|
|
||||||
ifaceBuilder.excludeApplication(appName)
|
|
||||||
}*/
|
|
||||||
confBuilder.setInterface(ifaceBuilder.build())
|
|
||||||
|
|
||||||
return confBuilder.build()
|
@JvmStatic
|
||||||
}
|
private external fun wgGetSocketV6(handle: Int): Int
|
||||||
|
|
||||||
fun getVpnConfig(): JSONObject {
|
@JvmStatic
|
||||||
return mConfig!!
|
private external fun wgTurnOff(handle: Int)
|
||||||
}
|
|
||||||
|
|
||||||
private fun startOpenVpn() {
|
@JvmStatic
|
||||||
mOpenVPNThreadv3 = OpenVPNThreadv3 (this)
|
private external fun wgTurnOn(ifName: String, tunFd: Int, settings: String): Int
|
||||||
Thread ({
|
|
||||||
mOpenVPNThreadv3?.run()
|
|
||||||
}).start()
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun startWireGuard(){
|
@JvmStatic
|
||||||
val wireguard_conf = buildWireugardConfig(mConfig!!)
|
private external fun wgVersion(): String?
|
||||||
if (currentTunnelHandle != -1) {
|
}
|
||||||
Log.e(tag, "Tunnel already up")
|
}
|
||||||
// Turn the tunnel down because this might be a switch
|
|
||||||
wgTurnOff(currentTunnelHandle)
|
|
||||||
}
|
|
||||||
val wgConfig: String = wireguard_conf!!.toWgUserspaceString()
|
|
||||||
val builder = Builder()
|
|
||||||
setupBuilder(wireguard_conf, builder)
|
|
||||||
builder.setSession("avpn0")
|
|
||||||
builder.establish().use { tun ->
|
|
||||||
if (tun == null)return
|
|
||||||
Log.i(tag, "Go backend " + wgVersion())
|
|
||||||
currentTunnelHandle = wgTurnOn("avpn0", tun.detachFd(), wgConfig)
|
|
||||||
}
|
|
||||||
if (currentTunnelHandle < 0) {
|
|
||||||
Log.e(tag, "Activation Error Code -> $currentTunnelHandle")
|
|
||||||
isUp = false
|
|
||||||
return
|
|
||||||
}
|
|
||||||
protect(wgGetSocketV4(currentTunnelHandle))
|
|
||||||
protect(wgGetSocketV6(currentTunnelHandle))
|
|
||||||
isUp = true
|
|
||||||
|
|
||||||
// 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()
|
|
||||||
|
|
||||||
NotificationUtil.show(this) // Go foreground
|
|
||||||
}
|
|
||||||
companion object {
|
|
||||||
@JvmStatic
|
|
||||||
fun startService(c: Context) {
|
|
||||||
c.applicationContext.startService(
|
|
||||||
Intent(c.applicationContext, VPNService::class.java).apply {
|
|
||||||
putExtra("startOnly", true)
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
@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?
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
QT += widgets core gui network xml remoteobjects quick
|
QT += widgets core gui network xml remoteobjects quick svg
|
||||||
|
|
||||||
TARGET = AmneziaVPN
|
TARGET = AmneziaVPN
|
||||||
TEMPLATE = app
|
TEMPLATE = app
|
||||||
|
|
|
@ -38,8 +38,6 @@ void QrDecoderLogic::onDetectedQrCode(const QString &code)
|
||||||
|
|
||||||
|
|
||||||
if (magic == amnezia::qrMagicCode) {
|
if (magic == amnezia::qrMagicCode) {
|
||||||
qDebug() << "QrDecoderLogic::onDetectedQrCode magic code detected" << magic << ba.size();
|
|
||||||
|
|
||||||
quint8 chunksCount; s >> chunksCount;
|
quint8 chunksCount; s >> chunksCount;
|
||||||
if (totalChunksCount() != chunksCount) {
|
if (totalChunksCount() != chunksCount) {
|
||||||
m_chunks.clear();
|
m_chunks.clear();
|
||||||
|
|
|
@ -12,6 +12,7 @@ BasicButtonType {
|
||||||
anchors.left: parent.left
|
anchors.left: parent.left
|
||||||
anchors.verticalCenter: parent.verticalCenter
|
anchors.verticalCenter: parent.verticalCenter
|
||||||
svg.source: root.icon.source
|
svg.source: root.icon.source
|
||||||
|
color: "#100A44"
|
||||||
width: 25
|
width: 25
|
||||||
height: 25
|
height: 25
|
||||||
}
|
}
|
||||||
|
|
|
@ -112,6 +112,7 @@ UiLogic::~UiLogic()
|
||||||
{
|
{
|
||||||
emit hide();
|
emit hide();
|
||||||
|
|
||||||
|
#ifdef AMNEZIA_DESKTOP
|
||||||
if (m_vpnConnection->connectionState() != VpnProtocol::VpnConnectionState::Disconnected) {
|
if (m_vpnConnection->connectionState() != VpnProtocol::VpnConnectionState::Disconnected) {
|
||||||
m_vpnConnection->disconnectFromVpn();
|
m_vpnConnection->disconnectFromVpn();
|
||||||
for (int i = 0; i < 50; i++) {
|
for (int i = 0; i < 50; i++) {
|
||||||
|
@ -122,6 +123,7 @@ UiLogic::~UiLogic()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
m_vpnConnection->deleteLater();
|
m_vpnConnection->deleteLater();
|
||||||
m_vpnConnectionThread.quit();
|
m_vpnConnectionThread.quit();
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue