aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorpacien2020-12-08 16:04:48 +0100
committerpacien2020-12-08 16:04:48 +0100
commit69445bffe7a17055ac47a41df5d33fe09b9aff3c (patch)
tree61a00dfe1c0d3085386f40c0c0d8c8cbb427a33b
parent9c0aa8bd9dc694854b5c4b5eb07ef4d8942709a8 (diff)
downloadtincapp-69445bffe7a17055ac47a41df5d33fe09b9aff3c.tar.gz
context: read configuration from and write logs and temp files to private app storage
The external app public storage directory is no longer reliably accessible on Android 11 and above. This makes editing the configuration and accessing the log files impossible in some cases. Let's move to the app private storage, to be made accessible to the user by some other mean. This has the benefit of also protecting the private keys that need to be stored encrypted otherwise. We also split the configuration and cache directory into specialised sub-directories. GitHub: related to #103
-rw-r--r--app/src/main/java/org/pacien/tincapp/activities/start/NetworkListFragment.kt10
-rw-r--r--app/src/main/java/org/pacien/tincapp/context/AppPaths.kt24
-rw-r--r--app/src/main/java/org/pacien/tincapp/service/TincVpnService.kt3
-rw-r--r--app/src/main/java/org/pacien/tincapp/utils/TincKeyring.kt2
-rw-r--r--app/src/main/res/layout/configure_tools_path_info_fragment.xml2
-rw-r--r--app/src/main/res/values-nb-rNO/strings.xml1
-rw-r--r--app/src/main/res/values-zh-rCN/strings.xml1
-rw-r--r--app/src/main/res/values-zh-rHK/strings.xml1
-rw-r--r--app/src/main/res/values-zh-rTW/strings.xml1
-rw-r--r--app/src/main/res/values/strings.xml1
10 files changed, 17 insertions, 29 deletions
diff --git a/app/src/main/java/org/pacien/tincapp/activities/start/NetworkListFragment.kt b/app/src/main/java/org/pacien/tincapp/activities/start/NetworkListFragment.kt
index d3cc803..b0bbddf 100644
--- a/app/src/main/java/org/pacien/tincapp/activities/start/NetworkListFragment.kt
+++ b/app/src/main/java/org/pacien/tincapp/activities/start/NetworkListFragment.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-2019 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
@@ -37,7 +37,6 @@ import org.pacien.tincapp.extensions.setElements
37 * @author pacien 37 * @author pacien
38 */ 38 */
39class NetworkListFragment : BaseFragment() { 39class NetworkListFragment : BaseFragment() {
40 private val appPaths = AppPaths
41 private val networkListViewModel by lazy { NetworkListViewModel() } 40 private val networkListViewModel by lazy { NetworkListViewModel() }
42 private val networkListAdapter by lazy { ArrayAdapter<String>(requireContext(), R.layout.start_network_list_item) } 41 private val networkListAdapter by lazy { ArrayAdapter<String>(requireContext(), R.layout.start_network_list_item) }
43 var connectToNetworkAction = { _: String -> Unit } 42 var connectToNetworkAction = { _: String -> Unit }
@@ -72,13 +71,8 @@ class NetworkListFragment : BaseFragment() {
72 } 71 }
73 72
74 private fun updatePlaceholder() { 73 private fun updatePlaceholder() {
75 val placeholderTextResource = when (appPaths.storageAvailable()) {
76 true -> R.string.start_network_list_empty_none_found
77 false -> R.string.start_network_list_empty_storage_not_available
78 }
79
80 start_network_list_placeholder.post { 74 start_network_list_placeholder.post {
81 start_network_list_placeholder_text?.text = getString(placeholderTextResource) 75 start_network_list_placeholder_text?.text = getString(R.string.start_network_list_empty_none_found)
82 } 76 }
83 } 77 }
84} 78}
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 bd8316a..9aa2037 100644
--- a/app/src/main/java/org/pacien/tincapp/context/AppPaths.kt
+++ b/app/src/main/java/org/pacien/tincapp/context/AppPaths.kt
@@ -18,7 +18,6 @@
18 18
19package org.pacien.tincapp.context 19package org.pacien.tincapp.context
20 20
21import android.os.Environment
22import java.io.File 21import java.io.File
23import java.io.FileNotFoundException 22import java.io.FileNotFoundException
24 23
@@ -28,6 +27,10 @@ import java.io.FileNotFoundException
28 * @implNote Logs and PID files are stored in the cache directory for automatic collection. 27 * @implNote Logs and PID files are stored in the cache directory for automatic collection.
29 */ 28 */
30object AppPaths { 29object AppPaths {
30 private const val APP_LOG_DIR = "log"
31 private const val APP_TINC_RUNTIME_DIR = "run"
32 private const val APP_TINC_NETWORKS_DIR = "networks"
33
31 private const val TINCD_BIN = "libtincd.so" 34 private const val TINCD_BIN = "libtincd.so"
32 private const val TINC_BIN = "libtinc.so" 35 private const val TINC_BIN = "libtinc.so"
33 36
@@ -46,25 +49,24 @@ object AppPaths {
46 49
47 private val context by lazy { App.getContext() } 50 private val context by lazy { App.getContext() }
48 51
49 fun storageAvailable() = 52 private fun cacheDir() = context.cacheDir!!
50 Environment.getExternalStorageState().let { it == Environment.MEDIA_MOUNTED && it != Environment.MEDIA_MOUNTED_READ_ONLY }
51
52 fun internalCacheDir() = context.cacheDir!!
53 fun cacheDir() = context.externalCacheDir ?: internalCacheDir()
54 fun confDir() = context.getExternalFilesDir(null)!!
55 private fun binDir() = File(context.applicationInfo.nativeLibraryDir) 53 private fun binDir() = File(context.applicationInfo.nativeLibraryDir)
54 fun runtimeDir() = withDir(File(cacheDir(), APP_TINC_RUNTIME_DIR))
55 fun logDir() = withDir(File(cacheDir(), APP_LOG_DIR))
56 fun confDir() = withDir(File(context.filesDir!!, APP_TINC_NETWORKS_DIR))
56 57
57 fun confDir(netName: String) = File(confDir(), netName) 58 fun confDir(netName: String) = File(confDir(), netName)
58 fun hostsDir(netName: String) = File(confDir(netName), NET_HOSTS_DIR) 59 fun hostsDir(netName: String) = File(confDir(netName), NET_HOSTS_DIR)
59 fun netConfFile(netName: String) = File(confDir(netName), NET_CONF_FILE) 60 fun netConfFile(netName: String) = File(confDir(netName), NET_CONF_FILE)
60 fun tincConfFile(netName: String) = File(confDir(netName), NET_TINC_CONF_FILE) 61 fun tincConfFile(netName: String) = File(confDir(netName), NET_TINC_CONF_FILE)
61 fun invitationFile(netName: String) = File(confDir(netName), NET_INVITATION_FILE) 62 fun invitationFile(netName: String) = File(confDir(netName), NET_INVITATION_FILE)
62 fun logFile(netName: String) = File(cacheDir(), String.format(LOGFILE_FORMAT, netName)) 63 fun logFile(netName: String) = File(logDir(), String.format(LOGFILE_FORMAT, netName))
63 fun pidFile(netName: String) = File(context.cacheDir, String.format(PIDFILE_FORMAT, netName)) 64 fun pidFile(netName: String) = File(runtimeDir(), String.format(PIDFILE_FORMAT, netName))
64 fun appLogFile() = File(cacheDir(), APPLOG_FILE) 65 fun appLogFile() = File(logDir(), APPLOG_FILE)
65 fun crashFlagFile() = File(internalCacheDir(), CRASHFLAG_FILE) 66 fun crashFlagFile() = File(cacheDir(), CRASHFLAG_FILE)
66 67
67 fun existing(f: File) = f.apply { if (!exists()) throw FileNotFoundException(f.absolutePath) } 68 fun existing(f: File) = f.apply { if (!exists()) throw FileNotFoundException(f.absolutePath) }
69 fun withDir(f: File) = f.apply { if (!exists()) mkdirs() }
68 70
69 fun defaultEd25519PrivateKeyFile(netName: String) = File(confDir(netName), NET_DEFAULT_ED25519_PRIVATE_KEY_FILE) 71 fun defaultEd25519PrivateKeyFile(netName: String) = File(confDir(netName), NET_DEFAULT_ED25519_PRIVATE_KEY_FILE)
70 fun defaultRsaPrivateKeyFile(netName: String) = File(confDir(netName), NET_DEFAULT_RSA_PRIVATE_KEY_FILE) 72 fun defaultRsaPrivateKeyFile(netName: String) = File(confDir(netName), NET_DEFAULT_RSA_PRIVATE_KEY_FILE)
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 c688742..ac68c9f 100644
--- a/app/src/main/java/org/pacien/tincapp/service/TincVpnService.kt
+++ b/app/src/main/java/org/pacien/tincapp/service/TincVpnService.kt
@@ -93,9 +93,6 @@ class TincVpnService : VpnService() {
93 if (TincKeyring.needsPassphrase(netName) && passphrase == null) 93 if (TincKeyring.needsPassphrase(netName) && passphrase == null)
94 return reportError(resources.getString(R.string.notification_error_message_passphrase_not_provided)) 94 return reportError(resources.getString(R.string.notification_error_message_passphrase_not_provided))
95 95
96 if (!AppPaths.storageAvailable())
97 return reportError(resources.getString(R.string.start_network_list_empty_storage_not_available))
98
99 if (!AppPaths.confDir(netName).exists()) 96 if (!AppPaths.confDir(netName).exists())
100 return reportError(resources.getString(R.string.notification_error_message_no_configuration_for_network_format, netName), docTopic = "configuration") 97 return reportError(resources.getString(R.string.notification_error_message_no_configuration_for_network_format, netName), docTopic = "configuration")
101 98
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 89bb246..7d534e6 100644
--- a/app/src/main/java/org/pacien/tincapp/utils/TincKeyring.kt
+++ b/app/src/main/java/org/pacien/tincapp/utils/TincKeyring.kt
@@ -43,7 +43,7 @@ object TincKeyring {
43 } 43 }
44 44
45 private fun tempKey(name: String): File { 45 private fun tempKey(name: String): File {
46 val file = File(AppPaths.internalCacheDir(), name) 46 val file = File(AppPaths.runtimeDir(), name)
47 file.createNewFile() 47 file.createNewFile()
48 file.deleteOnExit() 48 file.deleteOnExit()
49 file.makePrivate() 49 file.makePrivate()
diff --git a/app/src/main/res/layout/configure_tools_path_info_fragment.xml b/app/src/main/res/layout/configure_tools_path_info_fragment.xml
index 376fa3d..c6d9777 100644
--- a/app/src/main/res/layout/configure_tools_path_info_fragment.xml
+++ b/app/src/main/res/layout/configure_tools_path_info_fragment.xml
@@ -51,7 +51,7 @@
51 51
52 <TextView 52 <TextView
53 style="@style/AppTheme.BlockContent" 53 style="@style/AppTheme.BlockContent"
54 android:text="@{appPaths.cacheDir().absolutePath}" 54 android:text="@{appPaths.logDir().absolutePath}"
55 android:textIsSelectable="true"/> 55 android:textIsSelectable="true"/>
56 56
57 </LinearLayout> 57 </LinearLayout>
diff --git a/app/src/main/res/values-nb-rNO/strings.xml b/app/src/main/res/values-nb-rNO/strings.xml
index 67a7404..9c330a7 100644
--- a/app/src/main/res/values-nb-rNO/strings.xml
+++ b/app/src/main/res/values-nb-rNO/strings.xml
@@ -74,7 +74,6 @@
74 <string name="start_activity_menu_configure">Sett opp</string> 74 <string name="start_activity_menu_configure">Sett opp</string>
75 <string name="start_network_list_title">Koble til nettverk</string> 75 <string name="start_network_list_title">Koble til nettverk</string>
76 <string name="start_network_list_empty_none_found">Kunne ikke finne noe nettverksoppsett.</string> 76 <string name="start_network_list_empty_none_found">Kunne ikke finne noe nettverksoppsett.</string>
77 <string name="start_network_list_empty_storage_not_available">Fikk ikke tilgang til lagringsmappe.</string>
78 <string name="start_starting_vpn">Starter VPN…</string> 77 <string name="start_starting_vpn">Starter VPN…</string>
79 78
80 <!-- Configure activity --> 79 <!-- Configure activity -->
diff --git a/app/src/main/res/values-zh-rCN/strings.xml b/app/src/main/res/values-zh-rCN/strings.xml
index 41662bf..b5d12b1 100644
--- a/app/src/main/res/values-zh-rCN/strings.xml
+++ b/app/src/main/res/values-zh-rCN/strings.xml
@@ -74,7 +74,6 @@
74 <string name="start_activity_menu_configure">配置</string> 74 <string name="start_activity_menu_configure">配置</string>
75 <string name="start_network_list_title">连接到网络</string> 75 <string name="start_network_list_title">连接到网络</string>
76 <string name="start_network_list_empty_none_found">未找到网络配置。</string> 76 <string name="start_network_list_empty_none_found">未找到网络配置。</string>
77 <string name="start_network_list_empty_storage_not_available">无法访问存储目录。</string>
78 <string name="start_starting_vpn">正在启动 VPN…</string> 77 <string name="start_starting_vpn">正在启动 VPN…</string>
79 78
80 <!-- Configure activity --> 79 <!-- Configure activity -->
diff --git a/app/src/main/res/values-zh-rHK/strings.xml b/app/src/main/res/values-zh-rHK/strings.xml
index 770ad46..bddb004 100644
--- a/app/src/main/res/values-zh-rHK/strings.xml
+++ b/app/src/main/res/values-zh-rHK/strings.xml
@@ -74,7 +74,6 @@
74 <string name="start_activ