aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--app/src/main/java/org/pacien/tincapp/context/AppPaths.kt11
-rw-r--r--app/src/main/java/org/pacien/tincapp/service/TincVpnService.kt16
-rw-r--r--app/src/main/java/org/pacien/tincapp/utils/TincKeyring.kt32
3 files changed, 38 insertions, 21 deletions
diff --git a/app/src/main/java/org/pacien/tincapp/context/AppPaths.kt b/app/src/main/java/org/pacien/tincapp/context/AppPaths.kt
index 1efb7cf..2394586 100644
--- a/app/src/main/java/org/pacien/tincapp/context/AppPaths.kt
+++ b/app/src/main/java/org/pacien/tincapp/context/AppPaths.kt
@@ -1,6 +1,6 @@
1/* 1/*
2 * Tinc App, an Android binding and user interface for the tinc mesh VPN daemon 2 * Tinc App, an Android binding and user interface for the tinc mesh VPN daemon
3 * Copyright (C) 2017-2018 Pacien TRAN-GIRARD 3 * Copyright (C) 2017-2020 Pacien TRAN-GIRARD
4 * 4 *
5 * This program is free software: you can redistribute it and/or modify 5 * This program is free software: you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by 6 * it under the terms of the GNU General Public License as published by
@@ -25,7 +25,7 @@ import java.io.FileNotFoundException
25/** 25/**
26 * @author pacien 26 * @author pacien
27 * 27 *
28 * @implNote Logs and PID files are stored in the cache directory for easy clean up. 28 * @implNote Logs and PID files are stored in the cache directory for automatic collection.
29 */ 29 */
30object AppPaths { 30object AppPaths {
31 private const val TINCD_BIN = "libtincd.so" 31 private const val TINCD_BIN = "libtincd.so"
@@ -40,15 +40,16 @@ object AppPaths {
40 private const val NET_TINC_CONF_FILE = "tinc.conf" 40 private const val NET_TINC_CONF_FILE = "tinc.conf"
41 private const val NET_HOSTS_DIR = "hosts" 41 private const val NET_HOSTS_DIR = "hosts"
42 private const val NET_INVITATION_FILE = "invitation-data" 42 private const val NET_INVITATION_FILE = "invitation-data"
43 private const val NET_DEFAULT_ED25519_PRIVATE_KEY_FILE = "ed25519_key.priv" 43
44 private const val NET_DEFAULT_RSA_PRIVATE_KEY_FILE = "rsa_key.priv" 44 const val NET_DEFAULT_ED25519_PRIVATE_KEY_FILE = "ed25519_key.priv"
45 const val NET_DEFAULT_RSA_PRIVATE_KEY_FILE = "rsa_key.priv"
45 46
46 private val context by lazy { App.getContext() } 47 private val context by lazy { App.getContext() }
47 48
48 fun storageAvailable() = 49 fun storageAvailable() =
49 Environment.getExternalStorageState().let { it == Environment.MEDIA_MOUNTED && it != Environment.MEDIA_MOUNTED_READ_ONLY } 50 Environment.getExternalStorageState().let { it == Environment.MEDIA_MOUNTED && it != Environment.MEDIA_MOUNTED_READ_ONLY }
50 51
51 private fun internalCacheDir() = context.cacheDir!! 52 fun internalCacheDir() = context.cacheDir!!
52 fun cacheDir() = context.externalCacheDir!! 53 fun cacheDir() = context.externalCacheDir!!
53 fun confDir() = context.getExternalFilesDir(null)!! 54 fun confDir() = context.getExternalFilesDir(null)!!
54 private fun binDir() = File(context.applicationInfo.nativeLibraryDir) 55 private fun binDir() = File(context.applicationInfo.nativeLibraryDir)
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 48cb1df..c688742 100644
--- a/app/src/main/java/org/pacien/tincapp/service/TincVpnService.kt
+++ b/app/src/main/java/org/pacien/tincapp/service/TincVpnService.kt
@@ -102,12 +102,17 @@ class TincVpnService : VpnService() {
102 log.info("Starting tinc daemon for network \"$netName\".") 102 log.info("Starting tinc daemon for network \"$netName\".")
103 if (isConnected() || getCurrentNetName() != null) stopVpn().join() 103 if (isConnected() || getCurrentNetName() != null) stopVpn().join()
104 104
105 // FIXME: pass decrypted private keys via temp file
106 val privateKeys = try { 105 val privateKeys = try {
107 TincConfiguration.fromTincConfiguration(AppPaths.existing(AppPaths.tincConfFile(netName))).let { tincCfg -> 106 TincConfiguration.fromTincConfiguration(AppPaths.existing(AppPaths.tincConfFile(netName))).let { tincCfg ->
108 Pair( 107 Pair(
109 TincKeyring.openPrivateKey(tincCfg.ed25519PrivateKeyFile ?: AppPaths.defaultEd25519PrivateKeyFile(netName), passphrase), 108 TincKeyring.unlockKey(
110 TincKeyring.openPrivateKey(tincCfg.privateKeyFile ?: AppPaths.defaultRsaPrivateKeyFile(netName), passphrase)) 109 AppPaths.NET_DEFAULT_ED25519_PRIVATE_KEY_FILE,
110 tincCfg.ed25519PrivateKeyFile ?: AppPaths.defaultEd25519PrivateKeyFile(netName),
111 passphrase),
112 TincKeyring.unlockKey(
113 AppPaths.NET_DEFAULT_RSA_PRIVATE_KEY_FILE,
114 tincCfg.privateKeyFile ?: AppPaths.defaultRsaPrivateKeyFile(netName),
115 passphrase))
111 } 116 }
112 } catch (e: FileNotFoundException) { 117 } catch (e: FileNotFoundException) {
113 Pair(null, null) 118 Pair(null, null)
@@ -143,15 +148,12 @@ class TincVpnService : VpnService() {
143 val serverSocket = LocalServerSocket(DEVICE_FD_ABSTRACT_SOCKET) 148 val serverSocket = LocalServerSocket(DEVICE_FD_ABSTRACT_SOCKET)
144 Executor.runAsyncTask { serveDeviceFd(serverSocket, deviceFd) } 149 Executor.runAsyncTask { serveDeviceFd(serverSocket, deviceFd) }
145 150
146 // FIXME: pass decrypted private keys via temp file 151 val daemon = Tincd.start(netName, DEVICE_FD_ABSTRACT_SOCKET, privateKeys.first, privateKeys.second)
147 val daemon = Tincd.start(netName, DEVICE_FD_ABSTRACT_SOCKET, null, null)
148 setState(netName, passphrase, interfaceCfg, deviceFd, daemon) 152 setState(netName, passphrase, interfaceCfg, deviceFd, daemon)
149 153
150 waitForDaemonStartup().whenComplete { _, exception -> 154 waitForDaemonStartup().whenComplete { _, exception ->
151 serverSocket.close() 155 serverSocket.close()
152 deviceFd.close() 156 deviceFd.close()
153 privateKeys.first?.close()
154 privateKeys.second?.close()
155 157
156 if (exception != null) { 158 if (exception != null) {
157 reportError(resources.getString(R.string.notification_error_message_daemon_exited, exception.cause!!.defaultMessage()), exception) 159 reportError(resources.getString(R.string.notification_error_message_daemon_exited, exception.cause!!.defaultMessage()), exception)
diff --git a/app/src/main/java/org/pacien/tincapp/utils/TincKeyring.kt b/app/src/main/java/org/pacien/tincapp/utils/TincKeyring.kt
index bae38ac..89bb246 100644
--- a/app/src/main/java/org/pacien/tincapp/utils/TincKeyring.kt
+++ b/app/src/main/java/org/pacien/tincapp/utils/TincKeyring.kt
@@ -1,6 +1,6 @@
1/* 1/*
2 * Tinc App, an Android binding and user interface for the tinc mesh VPN daemon 2 * Tinc App, an Android binding and user interface for the tinc mesh VPN daemon
3 * Copyright (C) 2017-2018 Pacien TRAN-GIRARD 3 * Copyright (C) 2017-2020 Pacien TRAN-GIRARD
4 * 4 *
5 * This program is free software: you can redistribute it and/or modify 5 * This program is free software: you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by 6 * it under the terms of the GNU General Public License as published by
@@ -18,10 +18,11 @@
18 18
19package org.pacien.tincapp.utils 19package org.pacien.tincapp.utils
20 20
21import android.os.ParcelFileDescriptor
22import org.pacien.tincapp.commands.TincApp 21import org.pacien.tincapp.commands.TincApp
22import org.pacien.tincapp.context.AppPaths
23import java.io.File 23import java.io.File
24import java.io.FileNotFoundException 24import java.io.FileNotFoundException
25import java.io.FileWriter
25 26
26/** 27/**
27 * @author pacien 28 * @author pacien
@@ -33,12 +34,25 @@ object TincKeyring {
33 false 34 false
34 } 35 }
35 36
36 fun openPrivateKey(f: File?, passphrase: String?): ParcelFileDescriptor? { 37 fun unlockKey(target: String, input: File?, passphrase: String?): File? {
37 if (f == null || !f.exists() || passphrase == null) return null 38 if (input == null || !input.exists() || passphrase == null) return null
38 val pipe = ParcelFileDescriptor.createPipe() 39 val decryptedKey = PemUtils.decrypt(PemUtils.read(input), passphrase)
39 val decryptedKey = PemUtils.decrypt(PemUtils.read(f), passphrase) 40 val decryptedFile = tempKey(target)
40 val outputStream = ParcelFileDescriptor.AutoCloseOutputStream(pipe[1]) 41 PemUtils.write(decryptedKey, FileWriter(decryptedFile, false))
41 PemUtils.write(decryptedKey, outputStream.writer()) 42 return decryptedFile
42 return pipe[0] 43 }
44
45 private fun tempKey(name: String): File {
46 val file = File(AppPaths.internalCacheDir(), name)
47 file.createNewFile()
48 file.deleteOnExit()
49 file.makePrivate()
50 return file
51 }
52
53 private fun File.makePrivate() {
54 this.setExecutable(false, false)
55 this.setReadable(true, true)
56 this.setWritable(true, true)
43 } 57 }
44} 58}