aboutsummaryrefslogtreecommitdiff
path: root/app/src
diff options
context:
space:
mode:
authorpacien2020-12-16 23:16:00 +0100
committerpacien2020-12-16 23:16:00 +0100
commit3b545dc2221e2ff094e2a5e15a8b5d077da89404 (patch)
treec28e513d1f810723531a867f2bfbec9842bfcea1 /app/src
parent83663817f5404073f8de11ace4d75ef1b0bb2029 (diff)
downloadtincapp-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.kt11
-rw-r--r--app/src/main/java/org/pacien/tincapp/service/ConfigurationAccessService.kt37
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
21import android.app.PendingIntent 21import android.app.PendingIntent
22import android.app.Service 22import android.app.Service
23import android.content.Context
23import android.content.Intent 24import android.content.Intent
24import android.os.IBinder 25import android.os.IBinder
25import androidx.databinding.ObservableBoolean 26import 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()