diff --git a/app/build.gradle.kts b/app/build.gradle.kts
index 30c64fd..489a5b0 100644
--- a/app/build.gradle.kts
+++ b/app/build.gradle.kts
@@ -526,7 +526,7 @@ dependencies {
implementation("org.jetbrains:annotations-java5:24.0.1")
// debugging
- debugImplementation("com.squareup.leakcanary:leakcanary-android:2.11")
+ debugImplementation("com.squareup.leakcanary:leakcanary-android:2.12")
// desugaring
coreLibraryDesugaring("com.android.tools:desugar_jdk_libs:2.0.3")
diff --git a/app/src/main/kotlin/com/fox2code/mmm/androidacy/AndroidacyActivity.kt b/app/src/main/kotlin/com/fox2code/mmm/androidacy/AndroidacyActivity.kt
index d22871f..de6efe6 100644
--- a/app/src/main/kotlin/com/fox2code/mmm/androidacy/AndroidacyActivity.kt
+++ b/app/src/main/kotlin/com/fox2code/mmm/androidacy/AndroidacyActivity.kt
@@ -300,7 +300,7 @@ class AndroidacyActivity : FoxActivity() {
}
override fun onConsoleMessage(consoleMessage: ConsoleMessage): Boolean {
- if (BuildConfig.DEBUG_HTTP) {
+ return if (BuildConfig.DEBUG) {
when (consoleMessage.messageLevel()) {
MessageLevel.TIP -> Timber.tag("JSLog").i(consoleMessage.message())
MessageLevel.LOG -> Timber.tag("JSLog").d(consoleMessage.message())
@@ -308,8 +308,10 @@ class AndroidacyActivity : FoxActivity() {
MessageLevel.ERROR -> Timber.tag("JSLog").e(consoleMessage.message())
else -> Timber.tag("JSLog").v(consoleMessage.message())
}
+ true
+ } else {
+ false
}
- return true
}
override fun onProgressChanged(view: WebView, newProgress: Int) {
@@ -323,8 +325,8 @@ class AndroidacyActivity : FoxActivity() {
Timber.i("Progress: %d, setting indeterminate to false", newProgress)
prgInd.isIndeterminate = false
}
- prgInd.setProgressCompat(newProgress, true)
- if (newProgress == 100 && prgInd.visibility != View.INVISIBLE) {
+ prgInd.setProgress(newProgress, true)
+ if (newProgress == 100 && prgInd.visibility != View.GONE) {
Timber.i("Progress: %d, hiding progress bar", newProgress)
prgInd.isIndeterminate = true
prgInd.visibility = View.GONE
diff --git a/app/src/main/kotlin/com/fox2code/mmm/utils/io/net/Http.kt b/app/src/main/kotlin/com/fox2code/mmm/utils/io/net/Http.kt
index 402b5c5..1bdc66e 100644
--- a/app/src/main/kotlin/com/fox2code/mmm/utils/io/net/Http.kt
+++ b/app/src/main/kotlin/com/fox2code/mmm/utils/io/net/Http.kt
@@ -73,7 +73,6 @@ enum class Http {;
* can help make the app to work later when the current DNS system
* isn't functional or available.
*
- *
* Note: DNS Cache is stored in user data.
*/
private class FallBackDNS(context: Context, parent: Dns, vararg fallbacks: String?) : Dns {
@@ -429,8 +428,7 @@ enum class Http {;
}
private fun followRedirects(
- builder: OkHttpClient.Builder,
- followRedirects: Boolean
+ builder: OkHttpClient.Builder, followRedirects: Boolean
): OkHttpClient.Builder {
return builder.followRedirects(followRedirects).followSslRedirects(followRedirects)
}
@@ -464,14 +462,11 @@ enum class Http {;
needCaptchaAndroidacyHost = null
}
+ @Suppress("unused")
@JvmStatic
@SuppressLint("RestrictedApi")
@Throws(IOException::class)
fun doHttpGet(url: String, allowCache: Boolean): ByteArray {
- if (BuildConfig.DEBUG_HTTP) {
- // Log, but set all query parameters values to "****" while keeping the keys
- Timber.d("doHttpGet: %s", url.replace("=[^&]*".toRegex(), "=****"))
- }
var response: Response?
response = try {
(if (allowCache) getHttpClientWithCache() else getHttpClient())!!.newCall(
@@ -480,7 +475,16 @@ enum class Http {;
).get().build()
).execute()
} catch (e: IOException) {
- Timber.e(e, "Failed to fetch %s", url.replace("=[^&]*".toRegex(), "=****"))
+ Timber.e(e, "Failed to post %s", url)
+ // detect ssl errors, i.e., cert authority invalid by looking at the message
+ if (e.message != null && e.message!!.contains("_CERT_")) {
+ MainActivity.getFoxActivity(MainApplication.INSTANCE!!).runOnUiThread {
+ // show toast
+ Toast.makeText(
+ MainApplication.INSTANCE, R.string.ssl_error, Toast.LENGTH_LONG
+ ).show()
+ }
+ }
throw HttpException(e.message, 0)
}
if (BuildConfig.DEBUG_HTTP) {
@@ -550,6 +554,7 @@ enum class Http {;
return responseBody?.bytes() ?: ByteArray(0)
}
+ @Suppress("unused")
@JvmStatic
@Throws(IOException::class)
fun doHttpPost(url: String, data: String, allowCache: Boolean): ByteArray {
@@ -560,11 +565,26 @@ enum class Http {;
private fun doHttpPostRaw(url: String, data: String, allowCache: Boolean): Any {
Timber.d("POST %s", url)
var response: Response?
- response = (if (allowCache) getHttpClientWithCache() else getHttpClient())!!.newCall(
- Request.Builder().url(url).post(
- JsonRequestBody.from(data)
- ).header("Content-Type", "application/json").build()
- ).execute()
+ try {
+ response =
+ (if (allowCache) getHttpClientWithCache() else getHttpClient())!!.newCall(
+ Request.Builder().url(url).post(
+ JsonRequestBody.from(data)
+ ).header("Content-Type", "application/json").build()
+ ).execute()
+ } catch (e: IOException) {
+ Timber.e(e, "Failed to post %s", url)
+ // detect ssl errors, i.e., cert authority invalid by looking at the message
+ if (e.message != null && e.message!!.contains("_CERT_")) {
+ MainActivity.getFoxActivity(MainApplication.INSTANCE!!).runOnUiThread {
+ // show toast
+ Toast.makeText(
+ MainApplication.INSTANCE, R.string.ssl_error, Toast.LENGTH_LONG
+ ).show()
+ }
+ }
+ throw HttpException(e.message, 0)
+ }
if (response.isRedirect) {
// follow redirect with same method
Timber.d("doHttpPostRaw: following redirect: %s", response.header("Location"))
@@ -623,8 +643,23 @@ enum class Http {;
@JvmStatic
@Throws(IOException::class)
fun doHttpGet(url: String, progressListener: ProgressListener): ByteArray {
- val response =
- getHttpClient()!!.newCall(Request.Builder().url(url).get().build()).execute()
+ val response: Response
+ try {
+ response =
+ getHttpClient()!!.newCall(Request.Builder().url(url).get().build()).execute()
+ } catch (e: IOException) {
+ Timber.e(e, "Failed to post %s", url)
+ // detect ssl errors, i.e., cert authority invalid by looking at the message
+ if (e.message != null && e.message!!.contains("_CERT_")) {
+ MainActivity.getFoxActivity(MainApplication.INSTANCE!!).runOnUiThread {
+ // show toast
+ Toast.makeText(
+ MainApplication.INSTANCE, R.string.ssl_error, Toast.LENGTH_LONG
+ ).show()
+ }
+ }
+ throw HttpException(e.message, 0)
+ }
if (response.code != 200 && response.code != 204) {
Timber.e("Failed to fetch " + url + ", code: " + response.code)
checkNeedCaptchaAndroidacy(url, response.code)
@@ -733,7 +768,7 @@ enum class Http {;
// are we connected to a network with internet capabilities?
val networkCapabilities =
connectivityManager.getNetworkCapabilities(connectivityManager.activeNetwork)
- val systemSaysYes = networkCapabilities != null && networkCapabilities.hasCapability(
+ val systemSaysYes = networkCapabilities != null && networkCapabilities.hasCapability(
NetworkCapabilities.NET_CAPABILITY_INTERNET
)
Timber.d("System says we have internet: $systemSaysYes")
@@ -757,17 +792,20 @@ enum class Http {;
if (!systemSaysYes) return false
// check ourselves
val hasInternet = try {
- val resp = doHttpGet("https://production-api.androidacy.com/ping", false)
+ val resp = doHttpGet("https://production-api.androidacy.com/cdn-cgi/trace", false)
val respString = String(resp)
Timber.d("Ping response: $respString")
- true
+ // resp should include that scheme is https and h is production-api.androidacy.com
+ respString.contains("scheme=https") && respString.contains("h=production-api.androidacy.com")
} catch (e: HttpException) {
Timber.e(e, "Failed to check internet connection")
false
}
Timber.d("We say we have internet: $hasInternet")
lastConnectivityCheck = System.currentTimeMillis()
- lastConnectivityResult = systemSaysYes && hasInternet
+ @Suppress("KotlinConstantConditions")
+ lastConnectivityResult =
+ systemSaysYes && hasInternet
return lastConnectivityResult
}
}
diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml
index 592e8c0..c1a9e81 100644
--- a/app/src/main/res/values/strings.xml
+++ b/app/src/main/res/values/strings.xml
@@ -386,4 +386,5 @@
Saved logs successfully
Error in opening module notes. Logs may have the reason.
Submit feedback
+ Potential SSL interception detected.