From 0ef59c9b911c45f1b90a5590b8682b790c0d6174 Mon Sep 17 00:00:00 2001 From: Amine Date: Fri, 4 Aug 2017 21:39:45 +0200 Subject: [PATCH] Added a quick fix for accepting self signed certificates. --- .../bou/readerforselfoss/AddSourceActivity.kt | 4 +- .../bou/readerforselfoss/HomeActivity.kt | 3 +- .../bou/readerforselfoss/LoginActivity.kt | 13 +++++- .../bou/readerforselfoss/SourcesActivity.kt | 6 ++- .../api/selfoss/SelfossApi.kt | 46 +++++++++++++++++-- app/src/main/res/layout/activity_login.xml | 14 ++++++ app/src/main/res/values-fr/strings.xml | 2 + app/src/main/res/values-nl/strings.xml | 2 + app/src/main/res/values/strings.xml | 2 + 9 files changed, 85 insertions(+), 7 deletions(-) diff --git a/app/src/main/java/apps/amine/bou/readerforselfoss/AddSourceActivity.kt b/app/src/main/java/apps/amine/bou/readerforselfoss/AddSourceActivity.kt index 4b4483d..a9a3f44 100644 --- a/app/src/main/java/apps/amine/bou/readerforselfoss/AddSourceActivity.kt +++ b/app/src/main/java/apps/amine/bou/readerforselfoss/AddSourceActivity.kt @@ -2,6 +2,7 @@ package apps.amine.bou.readerforselfoss import android.content.Intent import android.os.Bundle +import android.preference.PreferenceManager import android.support.constraint.ConstraintLayout import android.support.v7.app.AppCompatActivity import android.support.v7.widget.Toolbar @@ -43,7 +44,8 @@ class AddSourceActivity : AppCompatActivity() { var api: SelfossApi? = null try { - api = SelfossApi(this, this@AddSourceActivity) + val prefs = PreferenceManager.getDefaultSharedPreferences(this) + api = SelfossApi(this, this@AddSourceActivity, prefs.getBoolean("isSelfSignedCert", false)) } catch (e: IllegalArgumentException) { mustLoginToAddSource() } diff --git a/app/src/main/java/apps/amine/bou/readerforselfoss/HomeActivity.kt b/app/src/main/java/apps/amine/bou/readerforselfoss/HomeActivity.kt index aa5df59..77a2508 100644 --- a/app/src/main/java/apps/amine/bou/readerforselfoss/HomeActivity.kt +++ b/app/src/main/java/apps/amine/bou/readerforselfoss/HomeActivity.kt @@ -139,7 +139,8 @@ class HomeActivity : AppCompatActivity(), SearchView.OnQueryTextListener { customTabActivityHelper = CustomTabActivityHelper() - api = SelfossApi(this, this@HomeActivity) + val dirtyPref = PreferenceManager.getDefaultSharedPreferences(this) + api = SelfossApi(this, this@HomeActivity, dirtyPref.getBoolean("isSelfSignedCert", false)) items = ArrayList() appColors = AppColors(this@HomeActivity) diff --git a/app/src/main/java/apps/amine/bou/readerforselfoss/LoginActivity.kt b/app/src/main/java/apps/amine/bou/readerforselfoss/LoginActivity.kt index ace8d29..0e99549 100644 --- a/app/src/main/java/apps/amine/bou/readerforselfoss/LoginActivity.kt +++ b/app/src/main/java/apps/amine/bou/readerforselfoss/LoginActivity.kt @@ -37,6 +37,7 @@ import io.fabric.sdk.android.Fabric class LoginActivity : AppCompatActivity() { private var inValidCount: Int = 0 + private var isWithSelfSignedCert = false private var isWithLogin = false private var isWithHTTPLogin = false @@ -101,6 +102,15 @@ class LoginActivity : AppCompatActivity() { val mPasswordLayout: TextInputLayout = findViewById(R.id.passwordLayout) val mHTTPPasswordLayout: TextInputLayout = findViewById(R.id.httpPasswordInput) val mEmailSignInButton: Button = findViewById(R.id.email_sign_in_button) + val selfHostedSwitch: Switch = findViewById(R.id.withSelfhostedCert) + val warningTextview: TextView = findViewById(R.id.warningText) + + selfHostedSwitch.setOnCheckedChangeListener {_, b -> + isWithSelfSignedCert = !isWithSelfSignedCert + val visi: Int = if (b) View.VISIBLE else View.GONE + + warningTextview.visibility = visi + } mPasswordView.setOnEditorActionListener(TextView.OnEditorActionListener { _, id, _ -> if (id == R.id.login || id == EditorInfo.IME_NULL) { @@ -196,9 +206,10 @@ class LoginActivity : AppCompatActivity() { editor.putString("httpUserName", httpLogin) editor.putString("password", password) editor.putString("httpPassword", httpPassword) + editor.putBoolean("isSelfSignedCert", isWithSelfSignedCert) editor.apply() - val api = SelfossApi(this, this@LoginActivity) + val api = SelfossApi(this, this@LoginActivity, isWithSelfSignedCert) api.login().enqueue(object : Callback { private fun preferenceError(t: Throwable) { editor.remove("url") diff --git a/app/src/main/java/apps/amine/bou/readerforselfoss/SourcesActivity.kt b/app/src/main/java/apps/amine/bou/readerforselfoss/SourcesActivity.kt index c020457..6bb2283 100644 --- a/app/src/main/java/apps/amine/bou/readerforselfoss/SourcesActivity.kt +++ b/app/src/main/java/apps/amine/bou/readerforselfoss/SourcesActivity.kt @@ -2,6 +2,7 @@ package apps.amine.bou.readerforselfoss import android.content.Intent import android.os.Bundle +import android.preference.PreferenceManager import android.support.v7.app.AppCompatActivity import android.support.v7.widget.LinearLayoutManager import android.support.v7.widget.RecyclerView @@ -36,7 +37,10 @@ class SourcesActivity : AppCompatActivity() { val mFab: FloatingActionButton = findViewById(R.id.fab) val mRecyclerView: RecyclerView = findViewById(R.id.activity_sources) val mLayoutManager = LinearLayoutManager(this) - val api = SelfossApi(this, this@SourcesActivity) + + val prefs = PreferenceManager.getDefaultSharedPreferences(this) + + val api = SelfossApi(this, this@SourcesActivity, prefs.getBoolean("isSelfSignedCert", false)) var items: ArrayList = ArrayList() mFab.attachToRecyclerView(mRecyclerView) diff --git a/app/src/main/java/apps/amine/bou/readerforselfoss/api/selfoss/SelfossApi.kt b/app/src/main/java/apps/amine/bou/readerforselfoss/api/selfoss/SelfossApi.kt index 2f1a66c..7063ea3 100644 --- a/app/src/main/java/apps/amine/bou/readerforselfoss/api/selfoss/SelfossApi.kt +++ b/app/src/main/java/apps/amine/bou/readerforselfoss/api/selfoss/SelfossApi.kt @@ -23,26 +23,66 @@ import retrofit2.Retrofit import retrofit2.converter.gson.GsonConverterFactory import apps.amine.bou.readerforselfoss.utils.Config +import java.security.cert.CertificateException +import java.security.cert.X509Certificate +import javax.net.ssl.* // codebeat:disable[ARITY,TOO_MANY_FUNCTIONS] -class SelfossApi(c: Context, callingActivity: Activity) { +class SelfossApi(c: Context, callingActivity: Activity, isWithSelfSignedCert: Boolean) { private lateinit var service: SelfossService private val config: Config = Config(c) private val userName: String private val password: String + fun OkHttpClient.Builder.maybeWithSelfSigned(isWithSelfSignedCert: Boolean): OkHttpClient.Builder = + if (isWithSelfSignedCert) { + try { + // Create a trust manager that does not validate certificate chains + val trustAllCerts = arrayOf(object : X509TrustManager { + override fun getAcceptedIssuers(): Array = + arrayOf() + + @Throws(CertificateException::class) + override fun checkClientTrusted(chain: Array, authType: String) { + } + + @Throws(CertificateException::class) + override fun checkServerTrusted(chain: Array, authType: String) { + } + + }) + + // Install the all-trusting trust manager + val sslContext = SSLContext.getInstance("SSL") + sslContext.init(null, trustAllCerts, java.security.SecureRandom()) + + val sslSocketFactory = sslContext.socketFactory + + OkHttpClient.Builder() + .sslSocketFactory(sslSocketFactory, trustAllCerts[0] as X509TrustManager) + .hostnameVerifier { _, _ -> true } + + } catch (e: Exception) { + throw RuntimeException(e) + } + + } else { + this + } + fun Credentials.createAuthenticator(): DispatchingAuthenticator = DispatchingAuthenticator.Builder() .with("digest", DigestAuthenticator(this)) .with("basic", BasicAuthenticator(this)) .build() - fun DispatchingAuthenticator.getHttpClien(): OkHttpClient { + fun DispatchingAuthenticator.getHttpClien(isWithSelfSignedCert: Boolean): OkHttpClient { val authCache = ConcurrentHashMap() return OkHttpClient .Builder() + .maybeWithSelfSigned(isWithSelfSignedCert) .authenticator(CachingAuthenticatorDecorator(this, authCache)) .addInterceptor(AuthenticationCacheInterceptor(authCache)) .build() @@ -71,7 +111,7 @@ class SelfossApi(c: Context, callingActivity: Activity) { Retrofit .Builder() .baseUrl(config.baseUrl) - .client(authenticator.getHttpClien()) + .client(authenticator.getHttpClien(isWithSelfSignedCert)) .addConverterFactory(GsonConverterFactory.create(gson)) .build() service = retrofit.create(SelfossService::class.java) diff --git a/app/src/main/res/layout/activity_login.xml b/app/src/main/res/layout/activity_login.xml index fb9da16..2642d6b 100644 --- a/app/src/main/res/layout/activity_login.xml +++ b/app/src/main/res/layout/activity_login.xml @@ -138,6 +138,20 @@ android:hint="@string/prompt_http_password" /> + + + +