aboutsummaryrefslogtreecommitdiff
path: root/app/src/main/java/org/pacien/tincapp/service/TincVpnService.kt
diff options
context:
space:
mode:
authorpacien2018-02-10 14:16:15 +0100
committerpacien2018-02-10 14:16:15 +0100
commit87ec3620d2259064831356c2f4000ae591756fd2 (patch)
tree9312da1d357fdd3790d5b80af221653696b23089 /app/src/main/java/org/pacien/tincapp/service/TincVpnService.kt
parentd1c39ba87bb32308c2d3a7a749abffeb773541ef (diff)
downloadtincapp-87ec3620d2259064831356c2f4000ae591756fd2.tar.gz
Reformat code
Diffstat (limited to 'app/src/main/java/org/pacien/tincapp/service/TincVpnService.kt')
-rw-r--r--app/src/main/java/org/pacien/tincapp/service/TincVpnService.kt210
1 files changed, 105 insertions, 105 deletions
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 601ffbb..278d20a 100644
--- a/app/src/main/java/org/pacien/tincapp/service/TincVpnService.kt
+++ b/app/src/main/java/org/pacien/tincapp/service/TincVpnService.kt
@@ -29,122 +29,122 @@ import java.io.IOException
29 */ 29 */
30class TincVpnService : VpnService() { 30class TincVpnService : VpnService() {
31 31
32 override fun onDestroy() { 32 override fun onDestroy() {
33 stopVpn() 33 stopVpn()
34 super.onDestroy() 34 super.onDestroy()
35 }
36
37 override fun onStartCommand(intent: Intent, flags: Int, startId: Int): Int {
38 if (isConnected()) stopVpn()
39 startVpn(intent.data.schemeSpecificPart, intent.data.fragment)
40 return Service.START_REDELIVER_INTENT
41 }
42
43 private fun startVpn(netName: String, passphrase: String? = null) {
44 if (netName.isBlank())
45 return reportError(resources.getString(R.string.message_no_network_name_provided), docTopic = "intent-api")
46
47 if (!AppPaths.storageAvailable())
48 return reportError(resources.getString(R.string.message_storage_unavailable))
49
50 if (!AppPaths.confDir(netName).exists())
51 return reportError(resources.getString(R.string.message_no_configuration_for_network_format, netName), docTopic = "configuration")
52
53 Log.i(TAG, "Starting tinc daemon for network \"$netName\".")
54
55 val interfaceCfg = try {
56 VpnInterfaceConfiguration.fromIfaceConfiguration(AppPaths.existing(AppPaths.netConfFile(netName)))
57 } catch (e: FileNotFoundException) {
58 return reportError(resources.getString(R.string.message_network_config_not_found_format, e.message!!), e, "configuration")
59 } catch (e: ConversionException) {
60 return reportError(resources.getString(R.string.message_network_config_invalid_format, e.message!!), e, "network-interface")
35 } 61 }
36 62
37 override fun onStartCommand(intent: Intent, flags: Int, startId: Int): Int { 63 val deviceFd = try {
38 if (isConnected()) stopVpn() 64 Builder().setSession(netName)
39 startVpn(intent.data.schemeSpecificPart, intent.data.fragment) 65 .applyCfg(interfaceCfg)
40 return Service.START_REDELIVER_INTENT 66 .also { applyIgnoringException(it::addDisallowedApplication, BuildConfig.APPLICATION_ID) }
67 .establish()
68 } catch (e: IllegalArgumentException) {
69 return reportError(resources.getString(R.string.message_network_config_invalid_format, e.message!!), e, "network-interface")
41 } 70 }
42 71
43 private fun startVpn(netName: String, passphrase: String? = null) { 72 val privateKeys = try {
44 if (netName.isBlank()) 73 val tincCfg = TincConfiguration.fromTincConfiguration(AppPaths.existing(AppPaths.tincConfFile(netName)))
45 return reportError(resources.getString(R.string.message_no_network_name_provided), docTopic = "intent-api") 74
46 75 Pair(
47 if (!AppPaths.storageAvailable()) 76 openPrivateKey(tincCfg.ed25519PrivateKeyFile ?: AppPaths.defaultEd25519PrivateKeyFile(netName), passphrase),
48 return reportError(resources.getString(R.string.message_storage_unavailable)) 77 openPrivateKey(tincCfg.privateKeyFile ?: AppPaths.defaultRsaPrivateKeyFile(netName), passphrase)
49 78 )
50 if (!AppPaths.confDir(netName).exists()) 79 } catch (e: FileNotFoundException) {
51 return reportError(resources.getString(R.string.message_no_configuration_for_network_format, netName), docTopic = "configuration") 80 Pair(null, null)
52 81 } catch (e: PEMException) {
53 Log.i(TAG, "Starting tinc daemon for network \"$netName\".") 82 return reportError(resources.getString(R.string.message_could_not_decrypt_private_keys_format, e.message))
54
55 val interfaceCfg = try {
56 VpnInterfaceConfiguration.fromIfaceConfiguration(AppPaths.existing(AppPaths.netConfFile(netName)))
57 } catch (e: FileNotFoundException) {
58 return reportError(resources.getString(R.string.message_network_config_not_found_format, e.message!!), e, "configuration")
59 } catch (e: ConversionException) {
60 return reportError(resources.getString(R.string.message_network_config_invalid_format, e.message!!), e, "network-interface")
61 }
62
63 val deviceFd = try {
64 Builder().setSession(netName)
65 .applyCfg(interfaceCfg)
66 .also { applyIgnoringException(it::addDisallowedApplication, BuildConfig.APPLICATION_ID) }
67 .establish()
68 } catch (e: IllegalArgumentException) {
69 return reportError(resources.getString(R.string.message_network_config_invalid_format, e.message!!), e, "network-interface")
70 }
71
72 val privateKeys = try {
73 val tincCfg = TincConfiguration.fromTincConfiguration(AppPaths.existing(AppPaths.tincConfFile(netName)))
74
75 Pair(
76 openPrivateKey(tincCfg.ed25519PrivateKeyFile ?: AppPaths.defaultEd25519PrivateKeyFile(netName), passphrase),
77 openPrivateKey(tincCfg.privateKeyFile ?: AppPaths.defaultRsaPrivateKeyFile(netName), passphrase)
78 )
79 } catch (e: FileNotFoundException) {
80 Pair(null, null)
81 } catch (e: PEMException) {
82 return reportError(resources.getString(R.string.message_could_not_decrypt_private_keys_format, e.message))
83 }
84
85 Tincd.start(netName, deviceFd!!.fd, privateKeys.first?.fd, privateKeys.second?.fd)
86 setState(true, netName, interfaceCfg, deviceFd)
87 Log.i(TAG, "tinc daemon started.")
88 } 83 }
89 84
90 private fun openPrivateKey(f: File?, passphrase: String?): ParcelFileDescriptor? { 85 Tincd.start(netName, deviceFd!!.fd, privateKeys.first?.fd, privateKeys.second?.fd)
91 if (f == null || !f.exists() || passphrase == null) return null 86 setState(true, netName, interfaceCfg, deviceFd)
92 87 Log.i(TAG, "tinc daemon started.")
93 val pipe = ParcelFileDescriptor.createPipe() 88 }
94 val decryptedKey = PemUtils.decrypt(PemUtils.read(f), passphrase) 89
95 val outputStream = ParcelFileDescriptor.AutoCloseOutputStream(pipe[1]) 90 private fun openPrivateKey(f: File?, passphrase: String?): ParcelFileDescriptor? {
96 PemUtils.write(decryptedKey, outputStream.writer()) 91 if (f == null || !f.exists() || passphrase == null) return null
97 return pipe[0] 92
93 val pipe = ParcelFileDescriptor.createPipe()
94 val decryptedKey = PemUtils.decrypt(PemUtils.read(f), passphrase)
95 val outputStream = ParcelFileDescriptor.AutoCloseOutputStream(pipe[1])
96 PemUtils.write(decryptedKey, outputStream.writer())
97 return pipe[0]
98 }
99
100 private fun reportError(msg: String, e: Throwable? = null, docTopic: String? = null) {
101 if (e != null)
102 Log.e(TAG, msg, e)
103 else
104 Log.e(TAG, msg)
105
106 App.alert(R.string.title_unable_to_start_tinc, msg,
107 if (docTopic != null) resources.getString(R.string.app_doc_url_format, docTopic) else null)
108 }
109
110 companion object {
111
112 val TAG = this::class.java.canonicalName!!
113
114 private var connected: Boolean = false
115 private var netName: String? = null
116 private var interfaceCfg: VpnInterfaceConfiguration? = null
117 private var fd: ParcelFileDescriptor? = null
118
119 private fun setState(connected: Boolean, netName: String?, interfaceCfg: VpnInterfaceConfiguration?, fd: ParcelFileDescriptor?) {
120 TincVpnService.connected = connected
121 TincVpnService.netName = netName
122 TincVpnService.interfaceCfg = interfaceCfg
123 TincVpnService.fd = fd
98 } 124 }
99 125
100 private fun reportError(msg: String, e: Throwable? = null, docTopic: String? = null) { 126 fun startVpn(netName: String, passphrase: String? = null) {
101 if (e != null) 127 App.getContext().startService(Intent(App.getContext(), TincVpnService::class.java)
102 Log.e(TAG, msg, e) 128 .setData(Uri.Builder().scheme(TINC_SCHEME).opaquePart(netName).fragment(passphrase).build()))
103 else 129 }
104 Log.e(TAG, msg)
105 130
106 App.alert(R.string.title_unable_to_start_tinc, msg, 131 fun stopVpn() {
107 if (docTopic != null) resources.getString(R.string.app_doc_url_format, docTopic) else null) 132 try {
133 Log.i(TAG, "Stopping any running tinc daemon.")
134 if (netName != null) Tinc.stop(netName!!)
135 fd?.close()
136 Log.i(TAG, "All tinc daemons stopped.")
137 } catch (e: IOException) {
138 Log.wtf(TAG, e)
139 } finally {
140 setState(false, null, null, null)
141 }
108 } 142 }
109 143
110 companion object { 144 fun getCurrentNetName() = netName
111 145 fun getCurrentInterfaceCfg() = interfaceCfg
112 val TAG = this::class.java.canonicalName!! 146 fun isConnected() = connected
113
114 private var connected: Boolean = false
115 private var netName: String? = null
116 private var interfaceCfg: VpnInterfaceConfiguration? = null
117 private var fd: ParcelFileDescriptor? = null
118
119 private fun setState(connected: Boolean, netName: String?, interfaceCfg: VpnInterfaceConfiguration?, fd: ParcelFileDescriptor?) {
120 TincVpnService.connected = connected
121 TincVpnService.netName = netName
122 TincVpnService.interfaceCfg = interfaceCfg
123 TincVpnService.fd = fd