From 3619cf121b5b496ede1a0588f77b44f9bdb8386b Mon Sep 17 00:00:00 2001
From: Pacien TRAN-GIRARD
Date: Sat, 1 Jul 2017 15:27:20 +0200
Subject: Refactor VPN interface configuration loading

---
 .../org/pacien/tincapp/service/TincVpnService.kt   |  4 +-
 .../tincapp/service/VpnInterfaceConfiguraton.kt    | 56 ++++++++++++++++++++++
 .../tincapp/service/VpnServiceBuilderExtensions.kt | 49 +++++++++----------
 .../java/org/pacien/tincapp/utils/Functions.kt     | 11 +++++
 4 files changed, 94 insertions(+), 26 deletions(-)
 create mode 100644 app/src/main/java/org/pacien/tincapp/service/VpnInterfaceConfiguraton.kt
 create mode 100644 app/src/main/java/org/pacien/tincapp/utils/Functions.kt

(limited to 'app/src/main')

diff --git a/app/src/main/java/org/pacien/tincapp/service/TincVpnService.kt b/app/src/main/java/org/pacien/tincapp/service/TincVpnService.kt
index 06213df..c5e1c51 100644
--- a/app/src/main/java/org/pacien/tincapp/service/TincVpnService.kt
+++ b/app/src/main/java/org/pacien/tincapp/service/TincVpnService.kt
@@ -7,6 +7,7 @@ import org.pacien.tincapp.BuildConfig
 import org.pacien.tincapp.commands.Tinc
 import org.pacien.tincapp.commands.Tincd
 import org.pacien.tincapp.context.AppPaths
+import org.pacien.tincapp.utils.applyIgnoringException
 import java.io.IOException
 
 /**
@@ -20,7 +21,7 @@ class TincVpnService : VpnService() {
         this.netName = intent.getStringExtra(INTENT_EXTRA_NET_NAME)
 
         val net = Builder().setSession(this.netName)
-        VpnInterfaceConfigurator.applyConfiguration(net, AppPaths.netConfFile(this, this.netName))
+        net.apply(VpnInterfaceConfiguration(AppPaths.netConfFile(this, this.netName)))
         applyIgnoringException(net::addDisallowedApplication, BuildConfig.APPLICATION_ID)
 
         try {
@@ -42,7 +43,6 @@ class TincVpnService : VpnService() {
     }
 
     companion object {
-
         val INTENT_EXTRA_NET_NAME = "netName"
     }
 
diff --git a/app/src/main/java/org/pacien/tincapp/service/VpnInterfaceConfiguraton.kt b/app/src/main/java/org/pacien/tincapp/service/VpnInterfaceConfiguraton.kt
new file mode 100644
index 0000000..520d68c
--- /dev/null
+++ b/app/src/main/java/org/pacien/tincapp/service/VpnInterfaceConfiguraton.kt
@@ -0,0 +1,56 @@
+package org.pacien.tincapp.service
+
+/**
+ * @author pacien
+ */
+
+import org.apache.commons.configuration2.Configuration
+import org.apache.commons.configuration2.builder.fluent.Configurations
+import java.io.File
+
+private val KEY_ADDRESSES = "Address"
+private val KEY_ROUTES = "Route"
+private val KEY_DNS_SERVERS = "DNSServer"
+private val KEY_SEARCH_DOMAINS = "SearchDomain"
+private val KEY_ALLOWED_APPLICATIONS = "AllowApplication"
+private val KEY_DISALLOWED_APPLICATIONS = "DisallowApplication"
+private val KEY_ALLOWED_FAMILIES = "AllowFamily"
+private val KEY_ALLOW_BYPASS = "AllowBypass"
+private val KEY_BLOCKING = "Blocking"
+private val KEY_MTU = "MTU"
+
+private fun Configuration.getStringList(key: String): List<String> = getList(String::class.java, key, emptyList())
+private fun Configuration.getCidrList(key: String): List<CidrAddress> = getStringList(key).map { CidrAddress(it) }
+private fun Configuration.getIntList(key: String): List<Int> = getList(Int::class.java, key, emptyList())
+
+data class CidrAddress(val address: String, val prefix: Int) {
+    constructor(slashSeparated: String) :
+            this(slashSeparated.substringBefore("/"), Integer.parseInt(slashSeparated.substringAfter("/")))
+}
+
+data class VpnInterfaceConfiguration(val addresses: List<CidrAddress>,
+                                     val routes: List<CidrAddress>,
+                                     val dnsServers: List<String>,
+                                     val searchDomains: List<String>,
+                                     val allowedApplications: List<String>,
+                                     val disallowedApplications: List<String>,
+                                     val allowedFamilies: List<Int>,
+                                     val allowBypass: Boolean,
+                                     val blocking: Boolean,
+                                     val mtu: Int?) {
+
+    constructor(cfg: Configuration) : this(
+            cfg.getCidrList(KEY_ADDRESSES),
+            cfg.getCidrList(KEY_ROUTES),
+            cfg.getStringList(KEY_DNS_SERVERS),
+            cfg.getStringList(KEY_SEARCH_DOMAINS),
+            cfg.getStringList(KEY_ALLOWED_APPLICATIONS),
+            cfg.getStringList(KEY_DISALLOWED_APPLICATIONS),
+            cfg.getIntList(KEY_ALLOWED_FAMILIES),
+            cfg.getBoolean(KEY_ALLOW_BYPASS, false),
+            cfg.getBoolean(KEY_BLOCKING, false),
+            cfg.getInteger(KEY_MTU, null))
+
+    constructor(cfgFile: File) : this(Configurations().properties(cfgFile))
+
+}
diff --git a/app/src/main/java/org/pacien/tincapp/service/VpnServiceBuilderExtensions.kt b/app/src/main/java/org/pacien/tincapp/service/VpnServiceBuilderExtensions.kt
index d94d64d..22edff9 100644
--- a/app/src/main/java/org/pacien/tincapp/service/VpnServiceBuilderExtensions.kt
+++ b/app/src/main/java/org/pacien/tincapp/service/VpnServiceBuilderExtensions.kt
@@ -1,45 +1,46 @@
 package org.pacien.tincapp.service
 
-import android.net.VpnService
-
 /**
  * @author pacien
  */
 
-data class CidrAddress(val address: String, val prefix: Int) {
-    constructor(slashSeparated: String) :
-            this(slashSeparated.substringBefore("/"), Integer.parseInt(slashSeparated.substringAfter("/")))
-}
-
-
-fun <A, R> applyIgnoringException(f: (A) -> R, x: A, alt: R? = null) = try {
-    f(x)
-} catch (_: Exception) {
-    alt
-}
+import android.net.VpnService
+import org.pacien.tincapp.utils.applyIgnoringException
 
-fun VpnService.Builder.addAddress(cidr: CidrAddress) = addAddress(cidr.address, cidr.prefix)
-fun VpnService.Builder.addRoute(cidr: CidrAddress) = addRoute(cidr.address, cidr.prefix)
-fun VpnService.Builder.allowBypass(allow: Boolean) = if (allow) allowBypass() else this
-fun VpnService.Builder.overrideMtu(mtu: Int?) = if (mtu != null) setMtu(mtu) else this
+fun VpnService.Builder.addAddress(cidr: CidrAddress): VpnService.Builder = addAddress(cidr.address, cidr.prefix)
+fun VpnService.Builder.addRoute(cidr: CidrAddress): VpnService.Builder = addRoute(cidr.address, cidr.prefix)
+fun VpnService.Builder.allowBypass(allow: Boolean): VpnService.Builder = if (allow) allowBypass() else this
+fun VpnService.Builder.overrideMtu(mtu: Int?): VpnService.Builder = if (mtu != null) setMtu(mtu) else this
 
-fun VpnService.Builder.addAddresses(cidrList: List<CidrAddress>) =
+fun VpnService.Builder.addAddresses(cidrList: List<CidrAddress>): VpnService.Builder =
         cidrList.fold(this, { net, cidr -> net.addAddress(cidr) })
 
-fun VpnService.Builder.addRoutes(cidrList: List<CidrAddress>) =
+fun VpnService.Builder.addRoutes(cidrList: List<CidrAddress>): VpnService.Builder =
         cidrList.fold(this, { net, cidr -> net.addRoute(cidr) })
 
-fun VpnService.Builder.addDnsServers(dnsList: List<String>) =
+fun VpnService.Builder.addDnsServers(dnsList: List<String>): VpnService.Builder =
         dnsList.fold(this, { net, dns -> net.addDnsServer(dns) })
 
-fun VpnService.Builder.addSearchDomains(domainList: List<String>) =
+fun VpnService.Builder.addSearchDomains(domainList: List<String>): VpnService.Builder =
         domainList.fold(this, { net, domain -> net.addSearchDomain(domain) })
 
-fun VpnService.Builder.allowFamilies(familyList: List<Int>) =
+fun VpnService.Builder.allowFamilies(familyList: List<Int>): VpnService.Builder =
         familyList.fold(this, { net, family -> net.allowFamily(family) })
 
-fun VpnService.Builder.addAllowedApplications(apps: List<String>) =
+fun VpnService.Builder.addAllowedApplications(apps: List<String>): VpnService.Builder =
         apps.fold(this, { net, app -> applyIgnoringException(net::addAllowedApplication, app, net)!! })
 
-fun VpnService.Builder.addDisallowedApplications(apps: List<String>) =
+fun VpnService.Builder.addDisallowedApplications(apps: List<String>): VpnService.Builder =
         apps.fold(this, { net, app -> applyIgnoringException(net::addDisallowedApplication, app, net)!! })
+
+fun VpnService.Builder.apply(cfg: VpnInterfaceConfiguration): VpnService.Builder = this
+        .addAddresses(cfg.addresses)
+        .addRoutes(cfg.routes)
+        .addDnsServers(cfg.dnsServers)
+        .addSearchDomains(cfg.searchDomains)
+        .addAllowedApplications(cfg.allowedApplications)
+        .addDisallowedApplications(cfg.disallowedApplications)
+        .allowFamilies(cfg.allowedFamilies)
+        .allowBypass(cfg.allowBypass)
+        .setBlocking(cfg.blocking)
+        .overrideMtu(cfg.mtu)
diff --git a/app/src/main/java/org/pacien/tincapp/utils/Functions.kt b/app/src/main/java/org/pacien/tincapp/utils/Functions.kt
new file mode 100644
index 0000000..6ed77ce
--- /dev/null
+++ b/app/src/main/java/org/pacien/tincapp/utils/Functions.kt
@@ -0,0 +1,11 @@
+package org.pacien.tincapp.utils
+
+/**
+ * @author pacien
+ */
+
+fun <A, R> applyIgnoringException(f: (A) -> R, x: A, alt: R? = null) = try {
+    f(x)
+} catch (_: Exception) {
+    alt
+}
-- 
cgit v1.2.3