diff options
author | pacien | 2020-12-08 16:04:48 +0100 |
---|---|---|
committer | pacien | 2020-12-08 16:04:48 +0100 |
commit | 69445bffe7a17055ac47a41df5d33fe09b9aff3c (patch) | |
tree | 61a00dfe1c0d3085386f40c0c0d8c8cbb427a33b | |
parent | 9c0aa8bd9dc694854b5c4b5eb07ef4d8942709a8 (diff) | |
download | tincapp-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
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 | */ |
39 | class NetworkListFragment : BaseFragment() { | 39 | class 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 | ||
19 | package org.pacien.tincapp.context | 19 | package org.pacien.tincapp.context |
20 | 20 | ||
21 | import android.os.Environment | ||
22 | import java.io.File | 21 | import java.io.File |
23 | import java.io.FileNotFoundException | 22 | import 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 | */ |
30 | object AppPaths { | 29 | object 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 |