From 21fccd6b022366711e2336038626635c73bbc7d7 Mon Sep 17 00:00:00 2001 From: Torsten Grote Date: Wed, 2 Aug 2023 15:41:05 +0200 Subject: [PATCH] Catch IOExceptions from TorWrapper --- .../org/onionshare/android/ShareManager.kt | 16 ++++++++++--- .../org/onionshare/android/tor/TorManager.kt | 24 ++++++++++++++++--- 2 files changed, 34 insertions(+), 6 deletions(-) diff --git a/app/src/main/java/org/onionshare/android/ShareManager.kt b/app/src/main/java/org/onionshare/android/ShareManager.kt index 2085d746..38e1b593 100644 --- a/app/src/main/java/org/onionshare/android/ShareManager.kt +++ b/app/src/main/java/org/onionshare/android/ShareManager.kt @@ -26,6 +26,7 @@ import org.onionshare.android.tor.TorState import org.onionshare.android.ui.OnionNotificationManager import org.onionshare.android.ui.share.ShareUiState import org.slf4j.LoggerFactory.getLogger +import java.io.IOException import javax.inject.Inject import javax.inject.Singleton @@ -114,8 +115,13 @@ class ShareManager @Inject constructor( when (val zipResult = fileTask.await()) { is ZipResult.Zipped -> { val port = webserverManager.start(zipResult.sendPage) - torManager.publishOnionService(port) - observerTask.await() + try { + torManager.publishOnionService(port) + observerTask.await() + } catch (e: IOException) { + LOG.error("Error publishing onion service: ", e) + stopOnError(ShareUiState.ErrorStarting()) + } } is ZipResult.Error -> { @@ -149,7 +155,11 @@ class ShareManager @Inject constructor( ShareUiState.ErrorStarting(true) } - TorState.Stopping -> error("Still observing TorState after calling stop().") + TorState.Stopping -> { + // Somebody is stopping Tor. It wasn't us, because we would have stopped collected its state. + // So go to stopping state for now until Tor has stopped and we'll show the error below. + ShareUiState.Stopping + } TorState.Stopped -> { ShareUiState.ErrorStarting(errorMsg = "Tor stopped unexpectedly.") diff --git a/app/src/main/java/org/onionshare/android/tor/TorManager.kt b/app/src/main/java/org/onionshare/android/tor/TorManager.kt index 147f31d3..fd153c65 100644 --- a/app/src/main/java/org/onionshare/android/tor/TorManager.kt +++ b/app/src/main/java/org/onionshare/android/tor/TorManager.kt @@ -135,7 +135,11 @@ class TorManager( LOG.info("Stopping...") startCheckJob?.cancel() startCheckJob = null - tor.stop() + try { + tor.stop() + } catch (e: Exception) { + LOG.warn("Error stopping Tor: ", e) + } Intent(app, ShareService::class.java).also { intent -> app.stopService(intent) } @@ -148,6 +152,7 @@ class TorManager( else if (s == STOPPED) updateTorState(null, TorState.Stopped) } + @Throws(IOException::class) fun publishOnionService(port: Int) { LOG.info("Starting hidden service...") tor.publishHiddenService(port, 80, null) @@ -191,7 +196,13 @@ class TorManager( // try bridges we got from Moat, if any if (!bridges.isNullOrEmpty()) { LOG.info("Using bridges from Moat...") - useBridges(bridges) + try { + useBridges(bridges) + } catch (e: IOException) { + LOG.error("Error setting bridges: ", e) + stop() + return + } if (waitForTorToStart()) return } else { LOG.info("No bridges received from Moat. Continuing...") @@ -202,7 +213,13 @@ class TorManager( val builtInBridges = circumventionProvider.getSuitableBridgeTypes(countryCode).flatMap { type -> circumventionProvider.getBridges(type, countryCode, SDK_INT >= 25) } - useBridges(builtInBridges) + try { + useBridges(builtInBridges) + } catch (e: IOException) { + LOG.error("Error setting bridges: ", e) + stop() + return + } if (waitForTorToStart()) return LOG.info("Could not connect to Tor") updateTorState(TorState.Starting::class, TorState.FailedToConnect) @@ -259,6 +276,7 @@ class TorManager( } } + @Throws(IOException::class) private fun useBridges(bridges: List) { if (LOG.isInfoEnabled) { LOG.info("Using bridges:")