mirror of https://git.sr.ht/~oppen/ariane
tls config changes
This commit is contained in:
parent
50cf425a5b
commit
ab6635af69
|
@ -11,24 +11,27 @@ object DummyTrustManager {
|
|||
fun get(): Array<TrustManager> {
|
||||
return arrayOf(
|
||||
object : X509TrustManager {
|
||||
@Throws(CertificateException::class)
|
||||
override fun checkClientTrusted(
|
||||
chain: Array<X509Certificate?>?,
|
||||
chain: Array<out X509Certificate>?,
|
||||
authType: String?
|
||||
) {
|
||||
|
||||
}
|
||||
|
||||
@Throws(CertificateException::class)
|
||||
override fun checkServerTrusted(
|
||||
chain: Array<X509Certificate?>?,
|
||||
chain: Array<out X509Certificate>?,
|
||||
authType: String?
|
||||
) {
|
||||
println("checkServerTrusted()")
|
||||
println("checkServerTrusted() authType: $authType")
|
||||
chain?.forEach { cert ->
|
||||
println("checkServerTrusted() cert: ${cert.subjectDN}")
|
||||
}
|
||||
}
|
||||
|
||||
override fun getAcceptedIssuers(): Array<X509Certificate?>? {
|
||||
override fun getAcceptedIssuers(): Array<X509Certificate> {
|
||||
return arrayOf()
|
||||
}
|
||||
}
|
||||
)
|
||||
})
|
||||
}
|
||||
}
|
|
@ -22,7 +22,8 @@ const val GEMINI_SCHEME = "gemini"
|
|||
*
|
||||
*/
|
||||
class GeminiDatasource(
|
||||
private val context: Context): Datasource {
|
||||
private val context: Context
|
||||
): Datasource {
|
||||
|
||||
private val prefs = PreferenceManager.getDefaultSharedPreferences(context)
|
||||
private var last: URI? = null
|
||||
|
@ -38,7 +39,7 @@ class GeminiDatasource(
|
|||
when (uri.scheme) {
|
||||
GEMINI_SCHEME -> {
|
||||
val cached = RuntimeCache.get(uri)
|
||||
if(cached != null){
|
||||
if (cached != null) {
|
||||
last = uri
|
||||
onUpdate(
|
||||
GemState.ResponseGemtext(
|
||||
|
@ -48,7 +49,7 @@ class GeminiDatasource(
|
|||
)
|
||||
)
|
||||
return
|
||||
}else{
|
||||
} else {
|
||||
onUpdate(GemState.Requesting(uri))
|
||||
|
||||
GlobalScope.launch {
|
||||
|
@ -71,7 +72,10 @@ class GeminiDatasource(
|
|||
!address.contains("://") -> {
|
||||
//looks like a relative link
|
||||
val lastAddress = last.toString()
|
||||
val relAddress = "${lastAddress.substring(0, lastAddress.lastIndexOf("/") + 1)}$address"
|
||||
val relAddress = "${lastAddress.substring(
|
||||
0,
|
||||
lastAddress.lastIndexOf("/") + 1
|
||||
)}$address"
|
||||
URI.create(relAddress)
|
||||
}
|
||||
else -> {
|
||||
|
@ -104,26 +108,6 @@ class GeminiDatasource(
|
|||
https://framagit.org/waweic/gemini-client/-/blob/master/app/src/main/java/rocks/ism/decentral/geminiclient/GeminiConnection.kt
|
||||
*
|
||||
*/
|
||||
|
||||
private val trustAllCerts: Array<TrustManager> = arrayOf(object : X509TrustManager {
|
||||
override fun checkClientTrusted(chain: Array<out X509Certificate>?, authType: String?) {
|
||||
|
||||
}
|
||||
|
||||
override fun checkServerTrusted(chain: Array<out X509Certificate>?, authType: String?) {
|
||||
println("checkServerTrusted()")
|
||||
println("checkServerTrusted() authType: $authType")
|
||||
chain?.forEach { cert ->
|
||||
println("checkServerTrusted() cert: ${cert.subjectDN}")
|
||||
}
|
||||
}
|
||||
|
||||
override fun getAcceptedIssuers(): Array<X509Certificate> {
|
||||
return arrayOf()
|
||||
}
|
||||
})
|
||||
|
||||
|
||||
private fun geminiRequest(uri: URI, onUpdate: (state: GemState) -> Unit){
|
||||
last = uri
|
||||
val port = if(uri.port == -1) 1965 else uri.port
|
||||
|
@ -132,23 +116,28 @@ class GeminiDatasource(
|
|||
|
||||
println("REQ_PROTOCOL: $protocol")
|
||||
|
||||
val sslContext = SSLContext.getInstance(protocol)
|
||||
sslContext.init(null, trustAllCerts, SecureRandom())
|
||||
//todo - extract and reuse this
|
||||
val sslContext = if(protocol == "TLS_ALL"){
|
||||
SSLContext.getInstance("TLS")
|
||||
}else{
|
||||
SSLContext.getInstance(protocol)
|
||||
}
|
||||
|
||||
sslContext.init(null, DummyTrustManager.get(), null)
|
||||
val factory: SSLSocketFactory = sslContext.socketFactory
|
||||
|
||||
val socket: SSLSocket?
|
||||
try {
|
||||
socket = factory.createSocket(uri.host, port) as SSLSocket
|
||||
socket.enabledCipherSuites = factory.supportedCipherSuites
|
||||
|
||||
when (protocol) {
|
||||
"TLS" -> socket.enabledProtocols = socket.supportedProtocols
|
||||
"TLS" -> {}//Use default enabled protocols
|
||||
"TLS_ALL" -> socket.enabledProtocols = socket.supportedProtocols
|
||||
else -> socket.enabledProtocols = arrayOf(protocol)
|
||||
}
|
||||
|
||||
socket.startHandshake()
|
||||
}catch(ce: ConnectException){
|
||||
}catch (ce: ConnectException){
|
||||
println("socket error: $ce")
|
||||
onUpdate(
|
||||
GemState.ResponseError(
|
||||
|
@ -159,7 +148,7 @@ class GeminiDatasource(
|
|||
)
|
||||
)
|
||||
return
|
||||
}catch(she: SSLHandshakeException){
|
||||
}catch (she: SSLHandshakeException){
|
||||
println("socket error: $she")
|
||||
onUpdate(
|
||||
GemState.ResponseError(
|
||||
|
@ -209,7 +198,12 @@ class GeminiDatasource(
|
|||
header.code == GeminiResponse.INPUT -> onUpdate(GemState.ResponseInput(uri, header))
|
||||
header.code == GeminiResponse.REDIRECT -> request(URI.create(header.meta), onUpdate)
|
||||
header.code != GeminiResponse.SUCCESS -> onUpdate(GemState.ResponseError(header))
|
||||
header.meta.startsWith("text/gemini") -> getGemtext(bufferedReader, uri, header, onUpdate)
|
||||
header.meta.startsWith("text/gemini") -> getGemtext(
|
||||
bufferedReader,
|
||||
uri,
|
||||
header,
|
||||
onUpdate
|
||||
)
|
||||
header.meta.startsWith("text/") -> getString(socket, uri, header, onUpdate)
|
||||
header.meta.startsWith("image/") -> getBinary(socket, uri, header, onUpdate)
|
||||
header.meta.startsWith("audio/") -> getBinary(socket, uri, header, onUpdate)
|
||||
|
@ -228,7 +222,12 @@ class GeminiDatasource(
|
|||
socket.close()
|
||||
}
|
||||
|
||||
private fun getGemtext(reader: BufferedReader, uri: URI, header: GeminiResponse.Header, onUpdate: (state: GemState) -> Unit){
|
||||
private fun getGemtext(
|
||||
reader: BufferedReader,
|
||||
uri: URI,
|
||||
header: GeminiResponse.Header,
|
||||
onUpdate: (state: GemState) -> Unit
|
||||
){
|
||||
|
||||
val lines = mutableListOf<String>()
|
||||
|
||||
|
@ -243,22 +242,53 @@ class GeminiDatasource(
|
|||
onUpdate(GemState.ResponseGemtext(uri, header, processed))
|
||||
}
|
||||
|
||||
private fun getString(socket: SSLSocket?, uri: URI, header: GeminiResponse.Header, onUpdate: (state: GemState) -> Unit){
|
||||
private fun getString(
|
||||
socket: SSLSocket?,
|
||||
uri: URI,
|
||||
header: GeminiResponse.Header,
|
||||
onUpdate: (state: GemState) -> Unit
|
||||
){
|
||||
val content = socket?.inputStream?.bufferedReader().use { reader -> reader?.readText() }
|
||||
socket?.close()
|
||||
onUpdate(GemState.ResponseText(uri, header, content ?: "Error fetching content"))
|
||||
}
|
||||
|
||||
private fun getBinary(socket: SSLSocket?, uri: URI, header: GeminiResponse.Header, onUpdate: (state: GemState) -> Unit){
|
||||
private fun getBinary(
|
||||
socket: SSLSocket?,
|
||||
uri: URI,
|
||||
header: GeminiResponse.Header,
|
||||
onUpdate: (state: GemState) -> Unit
|
||||
){
|
||||
|
||||
val filenameRegex = Regex("[^A-Za-z0-9]")
|
||||
val cacheFile = File(context.cacheDir, filenameRegex.replace(uri.path, "_"))
|
||||
var filename: String? = null
|
||||
val fileSegmentIndex: Int = uri.path.lastIndexOf('/')
|
||||
if (fileSegmentIndex != -1) {
|
||||
filename = uri.path.substring(fileSegmentIndex + 1)
|
||||
}
|
||||
|
||||
val host = uri.host.replace(".", "_")
|
||||
val cacheName = "${host}_$filename"
|
||||
println("Caching file: $filename from uri: $uri, cacheName: $cacheName")
|
||||
|
||||
val cacheFile = File(context.cacheDir, cacheName)
|
||||
|
||||
when {
|
||||
cacheFile.exists() -> {
|
||||
when {
|
||||
header.meta.startsWith("image/") -> onUpdate(GemState.ResponseImage(uri, header, cacheFile.toUri()))
|
||||
header.meta.startsWith("audio/") -> onUpdate(GemState.ResponseAudio(uri, header, cacheFile.toUri()))
|
||||
header.meta.startsWith("image/") -> onUpdate(
|
||||
GemState.ResponseImage(
|
||||
uri,
|
||||
header,
|
||||
cacheFile.toUri()
|
||||
)
|
||||
)
|
||||
header.meta.startsWith("audio/") -> onUpdate(
|
||||
GemState.ResponseAudio(
|
||||
uri,
|
||||
header,
|
||||
cacheFile.toUri()
|
||||
)
|
||||
)
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -270,8 +300,20 @@ class GeminiDatasource(
|
|||
}
|
||||
|
||||
when {
|
||||
header.meta.startsWith("image/") -> onUpdate(GemState.ResponseImage(uri, header, cacheFile.toUri()))
|
||||
header.meta.startsWith("audio/") -> onUpdate(GemState.ResponseAudio(uri, header, cacheFile.toUri()))
|
||||
header.meta.startsWith("image/") -> onUpdate(
|
||||
GemState.ResponseImage(
|
||||
uri,
|
||||
header,
|
||||
cacheFile.toUri()
|
||||
)
|
||||
)
|
||||
header.meta.startsWith("audio/") -> onUpdate(
|
||||
GemState.ResponseAudio(
|
||||
uri,
|
||||
header,
|
||||
cacheFile.toUri()
|
||||
)
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -19,6 +19,9 @@ class SettingsFragment: PreferenceFragmentCompat(), Preference.OnPreferenceChang
|
|||
val context = preferenceManager.context
|
||||
val screen = preferenceManager.createPreferenceScreen(context)
|
||||
|
||||
/**
|
||||
* TLS Settings
|
||||
*/
|
||||
val tlsCategory = PreferenceCategory(context)
|
||||
tlsCategory.key = "tls_category"
|
||||
tlsCategory.title = "TLS Config"
|
||||
|
@ -30,6 +33,12 @@ class SettingsFragment: PreferenceFragmentCompat(), Preference.OnPreferenceChang
|
|||
tlsDefaultPreference.onPreferenceChangeListener = this
|
||||
tlsCategory.addPreference(tlsDefaultPreference)
|
||||
|
||||
val tlsAllSupportedPreference = SwitchPreferenceCompat(context)
|
||||
tlsAllSupportedPreference.key = "tls_All_Supported"
|
||||
tlsAllSupportedPreference.title = "TLS Enable all supported"
|
||||
tlsAllSupportedPreference.onPreferenceChangeListener = this
|
||||
tlsCategory.addPreference(tlsAllSupportedPreference)
|
||||
|
||||
val sslContext = SSLContext.getInstance("TLS")
|
||||
sslContext.init(null, null, SecureRandom())
|
||||
val factory: SSLSocketFactory = sslContext.socketFactory
|
||||
|
@ -55,6 +64,10 @@ class SettingsFragment: PreferenceFragmentCompat(), Preference.OnPreferenceChang
|
|||
val default = preferenceScreen.findPreference<SwitchPreferenceCompat>("tls_Default")
|
||||
default?.isChecked = false
|
||||
}
|
||||
if(key != "tls_All_Supported"){
|
||||
val default = preferenceScreen.findPreference<SwitchPreferenceCompat>("tls_All_Supported")
|
||||
default?.isChecked = false
|
||||
}
|
||||
protocols.forEach { protocol ->
|
||||
val tlsSwitchKey = "tls_${protocol.toLowerCase(Locale.getDefault())}"
|
||||
if (tlsSwitchKey != key) {
|
||||
|
@ -66,12 +79,13 @@ class SettingsFragment: PreferenceFragmentCompat(), Preference.OnPreferenceChang
|
|||
}
|
||||
}
|
||||
|
||||
val prefTitle = preference.title.toString()
|
||||
|
||||
if(prefTitle.toLowerCase().contains("default")){
|
||||
setTLSProtocol("TLS")
|
||||
}else{
|
||||
setTLSProtocol(prefTitle)
|
||||
when (preference.key) {
|
||||
"tls_Default" -> setTLSProtocol("TLS")
|
||||
"tls_All_Supported" -> setTLSProtocol("TLS_ALL")
|
||||
else -> {
|
||||
val prefTitle = preference.title.toString()
|
||||
setTLSProtocol(prefTitle)
|
||||
}
|
||||
}
|
||||
|
||||
return true
|
||||
|
|
Loading…
Reference in New Issue