diff options
author | pacien | 2020-12-08 16:16:08 +0100 |
---|---|---|
committer | pacien | 2020-12-08 16:16:08 +0100 |
commit | 20ecd9840f1e237dba79674b71e49b43b074902e (patch) | |
tree | 4594947f1faf96e9851d95c9cfc7bfad0c9ff923 | |
parent | b1f98caca2f6960f7abb3ef7f7c27b903e1ef929 (diff) | |
download | tincapp-20ecd9840f1e237dba79674b71e49b43b074902e.tar.gz |
app: add configuration FTP server
This is a ridiculous workaround to make the configuration (and other files) accessible to the user
necessary after the new storage access restriction enforced in Android 11 which prevent other
applications from accessing the supposedly public application's directory.
The app's internal private storage directory is now exposed to the user through an embedded FTP
server that the user can turn on and off from the configuration activity. The user can then play
with the configuration and retrieve logs through a remote or local FTP client application of their
choice.
GitHub: closes #103
-rw-r--r-- | app/build.gradle | 9 | ||||
-rw-r--r-- | app/proguard-rules.pro | 4 | ||||
-rw-r--r-- | app/src/main/AndroidManifest.xml | 4 | ||||
-rw-r--r-- | app/src/main/java/org/pacien/tincapp/activities/configure/ConfigurationFtpServerFragment.kt | 72 | ||||
-rw-r--r-- | app/src/main/java/org/pacien/tincapp/service/ConfigurationFtpService.kt | 128 | ||||
-rw-r--r-- | app/src/main/res/layout/configure_activity.xml | 24 | ||||
-rw-r--r-- | app/src/main/res/layout/configure_tools_configuration_ftp_server_fragment.xml | 86 | ||||
-rw-r--r-- | app/src/main/res/values-nb-rNO/strings.xml | 1 | ||||
-rw-r--r-- | app/src/main/res/values-zh-rCN/strings.xml | 1 | ||||
-rw-r--r-- | app/src/main/res/values-zh-rHK/strings.xml | 1 | ||||
-rw-r--r-- | app/src/main/res/values-zh-rTW/strings.xml | 1 | ||||
-rw-r--r-- | app/src/main/res/values/strings.xml | 8 | ||||
-rw-r--r-- | readme.md | 1 |
13 files changed, 327 insertions, 13 deletions
diff --git a/app/build.gradle b/app/build.gradle index 99e9226..41c75ef 100644 --- a/app/build.gradle +++ b/app/build.gradle | |||
@@ -70,6 +70,14 @@ android { | |||
70 | buildFeatures { | 70 | buildFeatures { |
71 | dataBinding = true | 71 | dataBinding = true |
72 | } | 72 | } |
73 | |||
74 | packagingOptions { | ||
75 | // clashing in dependencies (Apache Mina FtpServer) | ||
76 | exclude 'META-INF/DEPENDENCIES' | ||
77 | exclude 'META-INF/spring.schemas' | ||
78 | exclude 'META-INF/spring.handlers' | ||
79 | exclude 'META-INF/license.txt' | ||
80 | } | ||
73 | } | 81 | } |
74 | 82 | ||
75 | dependencies { | 83 | dependencies { |
@@ -88,6 +96,7 @@ dependencies { | |||
88 | implementation('org.apache.commons:commons-configuration2:2.3') { exclude group: 'commons-logging', module: 'commons-logging' } | 96 | implementation('org.apache.commons:commons-configuration2:2.3') { exclude group: 'commons-logging', module: 'commons-logging' } |
89 | implementation('commons-beanutils:commons-beanutils:1.9.3') { exclude group: 'commons-logging', module: 'commons-logging' } | 97 | implementation('commons-beanutils:commons-beanutils:1.9.3') { exclude group: 'commons-logging', module: 'commons-logging' } |
90 | implementation('commons-io:commons-io:2.6') { exclude group: 'commons-logging', module: 'commons-logging' } | 98 | implementation('commons-io:commons-io:2.6') { exclude group: 'commons-logging', module: 'commons-logging' } |
99 | implementation('org.apache.ftpserver:ftpserver:1.1.1') { exclude group: 'org.slf4j', module: 'slf4j-log4j12' } | ||
91 | } | 100 | } |
92 | 101 | ||
93 | repositories { | 102 | repositories { |
diff --git a/app/proguard-rules.pro b/app/proguard-rules.pro index 5100915..ffbb3e3 100644 --- a/app/proguard-rules.pro +++ b/app/proguard-rules.pro | |||
@@ -1,5 +1,5 @@ | |||
1 | # Tinc App, an Android binding and user interface for the tinc mesh VPN daemon | 1 | # Tinc App, an Android binding and user interface for the tinc mesh VPN daemon |
2 | # Copyright (C) 2017-2019 Pacien TRAN-GIRARD | 2 | # Copyright (C) 2017-2020 Pacien TRAN-GIRARD |
3 | # | 3 | # |
4 | # This program is free software: you can redistribute it and/or modify | 4 | # This program is free software: you can redistribute it and/or modify |
5 | # it under the terms of the GNU General Public License as published by | 5 | # it under the terms of the GNU General Public License as published by |
@@ -15,6 +15,8 @@ | |||
15 | # along with this program. If not, see <https://www.gnu.org/licenses/>. | 15 | # along with this program. If not, see <https://www.gnu.org/licenses/>. |
16 | 16 | ||
17 | -keep class org.apache.commons.** { *; } | 17 | -keep class org.apache.commons.** { *; } |
18 | -keep class org.apache.mina.** { *; } | ||
19 | -keep class org.apache.ftpserver.** { *; } | ||
18 | -keep class org.bouncycastle.** | 20 | -keep class org.bouncycastle.** |
19 | -keep class ch.qos.** { *; } | 21 | -keep class ch.qos.** { *; } |
20 | -keep class org.slf4j.** { *; } | 22 | -keep class org.slf4j.** { *; } |
diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index c86ec8f..020d62d 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml | |||
@@ -81,6 +81,10 @@ | |||
81 | </intent-filter> | 81 | </intent-filter> |
82 | </service> | 82 | </service> |
83 | 83 | ||
84 | <service | ||
85 | android:name="org.pacien.tincapp.service.ConfigurationFtpService"> | ||
86 | </service> | ||
87 | |||
84 | </application> | 88 | </application> |
85 | 89 | ||
86 | </manifest> | 90 | </manifest> |
diff --git a/app/src/main/java/org/pacien/tincapp/activities/configure/ConfigurationFtpServerFragment.kt b/app/src/main/java/org/pacien/tincapp/activities/configure/ConfigurationFtpServerFragment.kt new file mode 100644 index 0000000..b97a15e --- /dev/null +++ b/app/src/main/java/org/pacien/tincapp/activities/configure/ConfigurationFtpServerFragment.kt | |||
@@ -0,0 +1,72 @@ | |||
1 | /* | ||
2 | * Tinc App, an Android binding and user interface for the tinc mesh VPN daemon | ||
3 | * Copyright (C) 2017-2020 Pacien TRAN-GIRARD | ||
4 | * | ||
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 | ||
7 | * the Free Software Foundation, either version 3 of the License, or | ||
8 | * (at your option) any later version. | ||
9 | * | ||
10 | * This program is distributed in the hope that it will be useful, | ||
11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
13 | * GNU General Public License for more details. | ||
14 | * | ||
15 | * You should have received a copy of the GNU General Public License | ||
16 | * along with this program. If not, see <https://www.gnu.org/licenses/>. | ||
17 | */ | ||
18 | |||
19 | package org.pacien.tincapp.activities.configure | ||
20 | |||
21 | import android.content.Intent | ||
22 | import android.os.Bundle | ||
23 | import android.view.LayoutInflater | ||
24 | import android.view.View | ||
25 | import android.view.ViewGroup | ||
26 | import androidx.databinding.Observable | ||
27 | import androidx.databinding.ObservableBoolean | ||
28 | import org.pacien.tincapp.activities.BaseFragment | ||
29 | import org.pacien.tincapp.databinding.ConfigureToolsConfigurationFtpServerFragmentBinding | ||
30 | import org.pacien.tincapp.service.ConfigurationFtpService | ||
31 | |||
32 | /** | ||
33 | * @author pacien | ||
34 | */ | ||
35 | class ConfigurationFtpServerFragment : BaseFragment() { | ||
36 | private val ftpServerStartListener = object : Observable.OnPropertyChangedCallback() { | ||
37 | override fun onPropertyChanged(sender: Observable, propertyId: Int) { | ||
38 | binding.ftpEnabled = (sender as ObservableBoolean).get() | ||
39 | } | ||
40 | } | ||
41 | |||
42 | private lateinit var binding: ConfigureToolsConfigurationFtpServerFragmentBinding | ||
43 | |||
44 | override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View { | ||
45 | binding = ConfigureToolsConfigurationFtpServerFragmentBinding.inflate(inflater, container, false) | ||
46 | binding.ftpUsername = ConfigurationFtpService.FTP_USERNAME | ||
47 | binding.ftpPassword = ConfigurationFtpService.FTP_PASSWORD | ||
48 | binding.ftpPort = ConfigurationFtpService.FTP_PORT | ||
49 | binding.toggleFtpState = { toggleServer() } | ||
50 | return binding.root | ||
51 | } | ||
52 | |||
53 | override fun onResume() { | ||
54 | super.onResume() | ||
55 | ConfigurationFtpService.runningState.addOnPropertyChangedCallback(ftpServerStartListener) | ||
56 | binding.ftpEnabled = ConfigurationFtpService.runningState.get() | ||
57 | } | ||
58 | |||
59 | override fun onPause() { | ||
60 | ConfigurationFtpService.runningState.removeOnPropertyChangedCallback(ftpServerStartListener) | ||
61 | super.onPause() | ||
62 | } | ||
63 | |||
64 | private fun toggleServer() { | ||
65 | val targetServiceIntent = Intent(requireContext(), ConfigurationFtpService::class.java) | ||
66 | |||
67 | if (binding.ftpEnabled) | ||
68 | requireContext().stopService(targetServiceIntent) | ||
69 | else | ||
70 | requireContext().startService(targetServiceIntent) | ||
71 | } | ||
72 | } | ||
diff --git a/app/src/main/java/org/pacien/tincapp/service/ConfigurationFtpService.kt b/app/src/main/java/org/pacien/tincapp/service/ConfigurationFtpService.kt new file mode 100644 index 0000000..c562768 --- /dev/null +++ b/app/src/main/java/org/pacien/tincapp/service/ConfigurationFtpService.kt | |||
@@ -0,0 +1,128 @@ | |||
1 | /* | ||
2 | * Tinc App, an Android binding and user interface for the tinc mesh VPN daemon | ||
3 | * Copyright (C) 2017-2020 Pacien TRAN-GIRARD | ||
4 | * | ||
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 | ||
7 | * the Free Software Foundation, either version 3 of the License, or | ||
8 | * (at your option) any later version. | ||
9 | * | ||
10 | * This program is distributed in the hope that it will be useful, | ||
11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
13 | * GNU General Public License for more details. | ||
14 | * | ||
15 | * You should have received a copy of the GNU General Public License | ||
16 | * along with this program. If not, see <https://www.gnu.org/licenses/>. | ||
17 | */ | ||
18 | |||
19 | package org.pacien.tincapp.service | ||
20 | |||
21 | import android.app.Service | ||
22 | import android.content.Intent | ||
23 | import android.os.IBinder | ||
24 | import androidx.databinding.ObservableBoolean | ||
25 | import org.apache.ftpserver.FtpServer | ||
26 | import org.apache.ftpserver.FtpServerFactory | ||
27 | import org.apache.ftpserver.ftplet.* | ||
28 | import org.apache.ftpserver.listener.ListenerFactory | ||
29 | import org.apache.ftpserver.usermanager.UsernamePasswordAuthentication | ||
30 | import org.apache.ftpserver.usermanager.impl.WritePermission | ||
31 | import org.pacien.tincapp.R | ||
32 | import org.pacien.tincapp.context.App | ||
33 | import org.pacien.tincapp.extensions.Java.defaultMessage | ||
34 | import org.slf4j.LoggerFactory | ||
35 | import java.io.IOException | ||
36 | |||
37 | /** | ||
38 | * FTP server service allowing a remote and local user to access and modify configuration files in | ||
39 | * the application's context. | ||
40 | * | ||
41 | * @author pacien | ||
42 | */ | ||
43 | class ConfigurationFtpService : Service() { | ||
44 | companion object { | ||
45 | const val FTP_PORT = 65521 // tinc port `concat` FTP port | ||