diff options
author | pacien | 2020-12-16 23:16:00 +0100 |
---|---|---|
committer | pacien | 2020-12-16 23:16:00 +0100 |
commit | 3b545dc2221e2ff094e2a5e15a8b5d077da89404 (patch) | |
tree | c28e513d1f810723531a867f2bfbec9842bfcea1 /app/src | |
parent | 83663817f5404073f8de11ace4d75ef1b0bb2029 (diff) | |
download | tincapp-3b545dc2221e2ff094e2a5e15a8b5d077da89404.tar.gz |
ConfigurationAccessService: make FTP connection parameters persistent and configurable
GitHub: see https://github.com/pacien/tincapp/issues/103#issuecomment-741025439
Diffstat (limited to 'app/src')
-rw-r--r-- | app/src/main/java/org/pacien/tincapp/activities/configure/ConfigurationAccessServerFragment.kt | 11 | ||||
-rw-r--r-- | app/src/main/java/org/pacien/tincapp/service/ConfigurationAccessService.kt | 37 |
2 files changed, 33 insertions, 15 deletions
diff --git a/app/src/main/java/org/pacien/tincapp/activities/configure/ConfigurationAccessServerFragment.kt b/app/src/main/java/org/pacien/tincapp/activities/configure/ConfigurationAccessServerFragment.kt index 9fee749..c90299a 100644 --- a/app/src/main/java/org/pacien/tincapp/activities/configure/ConfigurationAccessServerFragment.kt +++ b/app/src/main/java/org/pacien/tincapp/activities/configure/ConfigurationAccessServerFragment.kt | |||
@@ -43,15 +43,14 @@ class ConfigurationAccessServerFragment : BaseFragment() { | |||
43 | 43 | ||
44 | override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View { | 44 | override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View { |
45 | binding = ConfigureToolsConfigurationAccessFragmentBinding.inflate(inflater, container, false) | 45 | binding = ConfigureToolsConfigurationAccessFragmentBinding.inflate(inflater, container, false) |
46 | binding.ftpUsername = ConfigurationAccessService.FTP_USERNAME | ||
47 | binding.ftpPassword = ConfigurationAccessService.FTP_PASSWORD | ||
48 | binding.ftpPort = ConfigurationAccessService.FTP_PORT | ||
49 | binding.toggleFtpState = { toggleServer() } | 46 | binding.toggleFtpState = { toggleServer() } |
47 | setConnectionInfo() | ||
50 | return binding.root | 48 | return binding.root |
51 | } | 49 | } |
52 | 50 | ||
53 | override fun onResume() { | 51 | override fun onResume() { |
54 | super.onResume() | 52 | super.onResume() |
53 | setConnectionInfo() | ||
55 | ConfigurationAccessService.runningState.addOnPropertyChangedCallback(ftpServerStartListener) | 54 | ConfigurationAccessService.runningState.addOnPropertyChangedCallback(ftpServerStartListener) |
56 | binding.ftpEnabled = ConfigurationAccessService.runningState.get() | 55 | binding.ftpEnabled = ConfigurationAccessService.runningState.get() |
57 | } | 56 | } |
@@ -61,6 +60,12 @@ class ConfigurationAccessServerFragment : BaseFragment() { | |||
61 | super.onPause() | 60 | super.onPause() |
62 | } | 61 | } |
63 | 62 | ||
63 | private fun setConnectionInfo() { | ||
64 | binding.ftpUsername = ConfigurationAccessService.getFtpUsername() | ||
65 | binding.ftpPassword = ConfigurationAccessService.getFtpPassword() | ||
66 | binding.ftpPort = ConfigurationAccessService.getFtpPort() | ||
67 | } | ||
68 | |||
64 | private fun toggleServer() { | 69 | private fun toggleServer() { |
65 | val targetServiceIntent = Intent(requireContext(), ConfigurationAccessService::class.java) | 70 | val targetServiceIntent = Intent(requireContext(), ConfigurationAccessService::class.java) |
66 | 71 | ||
diff --git a/app/src/main/java/org/pacien/tincapp/service/ConfigurationAccessService.kt b/app/src/main/java/org/pacien/tincapp/service/ConfigurationAccessService.kt index 32f74fc..1708243 100644 --- a/app/src/main/java/org/pacien/tincapp/service/ConfigurationAccessService.kt +++ b/app/src/main/java/org/pacien/tincapp/service/ConfigurationAccessService.kt | |||
@@ -20,6 +20,7 @@ package org.pacien.tincapp.service | |||
20 | 20 | ||
21 | import android.app.PendingIntent | 21 | import android.app.PendingIntent |
22 | import android.app.Service | 22 | import android.app.Service |
23 | import android.content.Context | ||
23 | import android.content.Intent | 24 | import android.content.Intent |
24 | import android.os.IBinder | 25 | import android.os.IBinder |
25 | import androidx.databinding.ObservableBoolean | 26 | import androidx.databinding.ObservableBoolean |
@@ -54,14 +55,26 @@ class ConfigurationAccessService : Service() { | |||
54 | @Suppress("unused") | 55 | @Suppress("unused") |
55 | private val MINA_FTP_LOGGER_OVERRIDER = MinaLoggerOverrider(Level.WARN) | 56 | private val MINA_FTP_LOGGER_OVERRIDER = MinaLoggerOverrider(Level.WARN) |
56 | 57 | ||
57 | const val FTP_PORT = 65521 // tinc port `concat` FTP port | 58 | private val context by lazy { App.getContext() } |
58 | val FTP_DATA_PORT_RANGE = FTP_PORT + 1..FTP_PORT + 11 | 59 | private val store by lazy { context.getSharedPreferences("${this::class.java.`package`!!.name}.ftp", Context.MODE_PRIVATE)!! } |
59 | const val FTP_USERNAME = "tincapp" | ||
60 | val FTP_HOME_DIR = App.getContext().applicationInfo.dataDir!! | ||
61 | val FTP_PASSWORD = generateRandomString(8) | ||
62 | |||
63 | val runningState = ObservableBoolean(false) | 60 | val runningState = ObservableBoolean(false) |
64 | 61 | ||
62 | fun getFtpHomeDir(): String = context.applicationInfo.dataDir!! | ||
63 | fun getFtpUsername() = storeGetOrInsertString("username") { "tincapp" } | ||
64 | fun getFtpPassword() = storeGetOrInsertString("password") { generateRandomString(8) } | ||
65 | fun getFtpPort() = storeGetOrInsertInt("port") { 65521 } // tinc port `concat` FTP port | ||
66 | fun getFtpPassiveDataPorts() = storeGetOrInsertString("passive-range") { "65522-65532" } | ||
67 | |||
68 | private fun storeGetOrInsertString(key: String, defaultGenerator: () -> String): String = synchronized(store) { | ||
69 | if (!store.contains(key)) store.edit().putString(key, defaultGenerator()).apply() | ||
70 | return store.getString(key, null)!! | ||
71 | } | ||
72 | |||
73 | private fun storeGetOrInsertInt(key: String, defaultGenerator: () -> Int): Int = synchronized(store) { | ||
74 | if (!store.contains(key)) store.edit().putInt(key, defaultGenerator()).apply() | ||
75 | return store.getInt(key, 0) | ||
76 | } | ||
77 | |||
65 | private fun generateRandomString(length: Int): String { | 78 | private fun generateRandomString(length: Int): String { |
66 | val alphabet = ('a'..'z') + ('A'..'Z') + ('0'..'9') | 79 | val alphabet = ('a'..'z') + ('A'..'Z') + ('0'..'9') |
67 | return List(length) { alphabet.random() }.joinToString("") | 80 | return List(length) { alphabet.random() }.joinToString("") |
@@ -83,12 +96,12 @@ class ConfigurationAccessService : Service() { | |||
83 | } | 96 | } |
84 | 97 | ||
85 | override fun onStartCommand(intent: Intent, flags: Int, startId: Int): Int { | 98 | override fun onStartCommand(intent: Intent, flags: Int, startId: Int): Int { |
86 | val ftpUser = StaticFtpUser(FTP_USERNAME, FTP_PASSWORD, FTP_HOME_DIR, listOf(WritePermission())) | 99 | val ftpUser = StaticFtpUser(getFtpUsername(), getFtpPassword(), getFtpHomeDir(), listOf(WritePermission())) |
87 | sftpServer = setupSingleUserServer(ftpUser).also { | 100 | sftpServer = setupSingleUserServer(ftpUser, getFtpPort(), getFtpPassiveDataPorts()).also { |
88 | try { | 101 | try { |
89 | it.start() | 102 | it.start() |
90 | runningState.set(true) | 103 | runningState.set(true) |
91 | log.info("Started FTP server on port {}", FTP_PORT) | 104 | log.info("Started FTP server on port {}", getFtpPort()) |
92 | pinInForeground() | 105 | pinInForeground() |
93 | } catch (e: IOException) { | 106 | } catch (e: IOException) { |
94 | log.error("Could not start FTP server", e) | 107 | log.error("Could not start FTP server", e) |
@@ -118,7 +131,7 @@ class ConfigurationAccessService : Service() { | |||
118 | ) | 131 | ) |
119 | } | 132 | } |
120 | 133 | ||
121 | private fun setupSingleUserServer(ftpUser: User): FtpServer = | 134 | private fun setupSingleUserServer(ftpUser: User, ftpPort: Int, ftpPassivePorts: String): FtpServer = |
122 | FtpServerFactory() | 135 | FtpServerFactory() |
123 | .apply { | 136 | .apply { |
124 | addListener("default", ListenerFactory() | 137 | addListener("default", ListenerFactory() |
@@ -127,10 +140,10 @@ class ConfigurationAccessService : Service() { | |||
127 | .apply { maxThreads = 1 } // library has issues with multiple threads | 140 | .apply { maxThreads = 1 } // library has issues with multiple threads |
128 | .createConnectionConfig() | 141 | .createConnectionConfig() |
129 | } | 142 | } |
130 | .apply { port = FTP_PORT } | 143 | .apply { port = ftpPort } |
131 | .apply { | 144 | .apply { |
132 | dataConnectionConfiguration = DataConnectionConfigurationFactory() | 145 | dataConnectionConfiguration = DataConnectionConfigurationFactory() |
133 | .apply { passivePorts = "${FTP_DATA_PORT_RANGE.first}-${FTP_DATA_PORT_RANGE.last}" } | 146 | .apply { passivePorts = ftpPassivePorts } |
134 | .createDataConnectionConfiguration() | 147 | .createDataConnectionConfiguration() |
135 | } | 148 | } |
136 | .createListener() | 149 | .createListener() |