mirror of
https://github.com/Corewala/Buran
synced 2025-03-11 22:53:08 +00:00
Added signature system for sites which do not require certs
Also broke a bunch of things, but we'll get there I swear.
This commit is contained in:
parent
29fe06ba54
commit
da4702b1a0
9 changed files with 53 additions and 20 deletions
|
@ -10,6 +10,7 @@ sealed class GemState {
|
|||
data class NotGeminiRequest(val uri: URI) : GemState()
|
||||
data class ResponseGemtext(val uri: URI, val header: GeminiResponse.Header, val lines: List<String>) : GemState()
|
||||
data class ResponseInput(val uri: URI, val header: GeminiResponse.Header) : GemState()
|
||||
class Redirect(val uri: String) : GemState()
|
||||
data class ResponseText(val uri: URI, val header: GeminiResponse.Header, val content: String) : GemState()
|
||||
data class ResponseImage(val uri: URI, val header: GeminiResponse.Header, val cacheUri: Uri) : GemState()
|
||||
data class ResponseBinary(val uri: URI, val header: GeminiResponse.Header, val cacheUri: Uri) : GemState()
|
||||
|
|
|
@ -8,7 +8,6 @@ import java.net.URI
|
|||
interface Datasource {
|
||||
fun request(address: String, forceDownload: Boolean, clientCertPassword: String?, onUpdate: (state: GemState) -> Unit)
|
||||
fun canGoBack(): Boolean
|
||||
fun goBack(onUpdate: (state: GemState) -> Unit)
|
||||
|
||||
companion object{
|
||||
fun factory(context: Context, history: BuranHistory): Datasource {
|
||||
|
|
|
@ -8,6 +8,7 @@ import corewala.buran.OppenURI
|
|||
import corewala.buran.io.GemState
|
||||
import corewala.buran.io.database.history.BuranHistory
|
||||
import corewala.buran.io.keymanager.BuranKeyManager
|
||||
import corewala.toURI
|
||||
import corewala.toUri
|
||||
import java.io.*
|
||||
import java.lang.IllegalStateException
|
||||
|
@ -30,7 +31,7 @@ class GeminiDatasource(private val context: Context, val history: BuranHistory):
|
|||
|
||||
private var socketFactory: SSLSocketFactory? = null
|
||||
|
||||
override fun request(address: String, forceDownload: Boolean, clientCertPassword: String?, onUpdate: (state: GemState) -> Unit) {
|
||||
override fun request(address: String, forceDownload: Boolean, clientCertPassword: String?, onUpdate: (state: GemState) -> Unit) {
|
||||
this.forceDownload = forceDownload
|
||||
|
||||
this.onUpdate = onUpdate
|
||||
|
@ -113,7 +114,7 @@ class GeminiDatasource(private val context: Context, val history: BuranHistory):
|
|||
|
||||
when {
|
||||
header.code == GeminiResponse.INPUT -> onUpdate(GemState.ResponseInput(uri, header))
|
||||
header.code == GeminiResponse.REDIRECT -> request(resolve(uri.host, header.meta), false, null, onUpdate)
|
||||
header.code == GeminiResponse.REDIRECT -> onUpdate(GemState.Redirect(resolve(uri.host, header.meta)))
|
||||
header.code == GeminiResponse.CLIENT_CERTIFICATE_REQUIRED -> onUpdate(GemState.ClientCertRequired(uri, header))
|
||||
header.code != GeminiResponse.SUCCESS -> onUpdate(GemState.ResponseError(header))
|
||||
header.meta.startsWith("text/gemini") -> getGemtext(bufferedReader, uri, header, onUpdate)
|
||||
|
@ -217,11 +218,6 @@ class GeminiDatasource(private val context: Context, val history: BuranHistory):
|
|||
|
||||
override fun canGoBack(): Boolean = runtimeHistory.isEmpty() || runtimeHistory.size > 1
|
||||
|
||||
override fun goBack(onUpdate: (state: GemState) -> Unit) {
|
||||
runtimeHistory.removeLast()
|
||||
request(runtimeHistory.last().toString(), false, null, onUpdate)
|
||||
}
|
||||
|
||||
//This just forces the factory to rebuild before the next request
|
||||
fun invalidate() {
|
||||
socketFactory = null
|
||||
|
|
|
@ -20,8 +20,7 @@ class BuranKeyManager(val context: Context, val onKeyError: (error: String) -> U
|
|||
|
||||
//If the user has a key loaded load it here - or else return null
|
||||
fun getFactory(clientCertPassword: String?): KeyManagerFactory? {
|
||||
return when {
|
||||
clientCertPassword != null -> {
|
||||
return when { !clientCertPassword.isNullOrEmpty() -> {
|
||||
lastCallUsedKey = true
|
||||
val keyStore: KeyStore = KeyStore.getInstance("pkcs12")
|
||||
|
||||
|
|
|
@ -17,6 +17,7 @@ import android.view.WindowManager
|
|||
import android.view.inputmethod.EditorInfo
|
||||
import android.widget.EditText
|
||||
import androidx.activity.viewModels
|
||||
import androidx.annotation.Nullable
|
||||
import androidx.appcompat.app.AlertDialog
|
||||
import androidx.appcompat.app.AppCompatActivity
|
||||
import androidx.appcompat.app.AppCompatDelegate
|
||||
|
@ -48,6 +49,7 @@ import corewala.buran.ui.modals_menus.about.AboutDialog
|
|||
import corewala.buran.ui.modals_menus.history.HistoryDialog
|
||||
import corewala.buran.ui.modals_menus.overflow.OverflowPopup
|
||||
import corewala.buran.ui.settings.SettingsActivity
|
||||
import kotlinx.android.synthetic.main.bookmark.*
|
||||
import java.io.File
|
||||
import java.io.FileInputStream
|
||||
import java.io.FileOutputStream
|
||||
|
@ -115,8 +117,13 @@ class GemActivity : AppCompatActivity() {
|
|||
private val inlineImage: (link: URI, adapterPosition: Int) -> Unit = { uri, position: Int ->
|
||||
if(getInternetStatus()){
|
||||
omniTerm.imageAddress(uri.toString())
|
||||
val clientCertPassword = if(isHostSigned(uri)){
|
||||
certPassword
|
||||
}else{
|
||||
null
|
||||
}
|
||||
omniTerm.uri.let{
|
||||
model.requestInlineImage(URI.create(it.toString())){ imageUri ->
|
||||
model.requestInlineImage(URI.create(it.toString()), clientCertPassword){ imageUri ->
|
||||
imageUri?.let{
|
||||
runOnUiThread {
|
||||
loadImage(position, imageUri)
|
||||
|
@ -249,6 +256,20 @@ class GemActivity : AppCompatActivity() {
|
|||
binding.addressEdit.requestFocus()
|
||||
inSearch = true
|
||||
}
|
||||
R.id.overflow_menu_sign -> {
|
||||
if(prefs.getBoolean("use_biometrics", false) and certPassword.isNullOrEmpty()){
|
||||
biometricSecureRequest(binding.addressEdit.text.toString())
|
||||
}else{
|
||||
if(certPassword.isNullOrEmpty()){
|
||||
certPassword = prefs.getString(
|
||||
Buran.PREF_KEY_CLIENT_CERT_PASSWORD,
|
||||
null
|
||||
)
|
||||
}
|
||||
gemRequest(binding.addressEdit.text.toString())
|
||||
}
|
||||
}
|
||||
|
||||
R.id.overflow_menu_bookmark -> {
|
||||
val name = adapter.inferTitle()
|
||||
BookmarkDialog(
|
||||
|
@ -407,6 +428,8 @@ class GemActivity : AppCompatActivity() {
|
|||
.show()
|
||||
}
|
||||
|
||||
is GemState.Redirect -> gemRequest(state.uri)
|
||||
|
||||
is GemState.ClientCertRequired -> runOnUiThread {
|
||||
loadingView(false)
|
||||
val builder = AlertDialog.Builder(this, R.style.AppDialogTheme)
|
||||
|
@ -463,12 +486,17 @@ class GemActivity : AppCompatActivity() {
|
|||
val download = getString(R.string.download)
|
||||
|
||||
if(getInternetStatus()) {
|
||||
val clientCertPassword = if(isHostSigned(state.uri)){
|
||||
certPassword
|
||||
}else{
|
||||
null
|
||||
}
|
||||
AlertDialog.Builder(this, R.style.AppDialogTheme)
|
||||
.setTitle("$download: ${state.header.meta}")
|
||||
.setMessage("${state.uri}")
|
||||
.setPositiveButton(getString(R.string.download).toUpperCase()) { _, _ ->
|
||||
loadingView(true)
|
||||
model.requestBinaryDownload(state.uri)
|
||||
model.requestBinaryDownload(state.uri, clientCertPassword)
|
||||
}
|
||||
.setNegativeButton(getString(R.string.cancel).toUpperCase()) { _, _ -> }
|
||||
.show()
|
||||
|
@ -755,11 +783,16 @@ class GemActivity : AppCompatActivity() {
|
|||
return false
|
||||
}
|
||||
|
||||
private fun gemRequest(address: String){
|
||||
if(address.toURI().host != omniTerm.getCurrent().toURI().host) {
|
||||
certPassword = null
|
||||
private fun isHostSigned(uri: URI): Boolean{
|
||||
if((uri.host != omniTerm.getCurrent().toURI().host) && !certPassword.isNullOrEmpty()) {
|
||||
return false
|
||||
}
|
||||
println(certPassword)
|
||||
return true
|
||||
}
|
||||
|
||||
private fun gemRequest(address: String){
|
||||
val clientCertAllowed = isHostSigned(address.toURI())
|
||||
if(!clientCertAllowed) certPassword = null
|
||||
|
||||
if(getInternetStatus()){
|
||||
if(initialised){
|
||||
|
|
|
@ -28,15 +28,15 @@ class GemViewModel: ViewModel() {
|
|||
}
|
||||
}
|
||||
|
||||
fun requestBinaryDownload(uri: URI) {
|
||||
gemini.request(uri.toString(), true, null){ state ->
|
||||
fun requestBinaryDownload(uri: URI, clientCertPassword: String?) {
|
||||
gemini.request(uri.toString(), true, clientCertPassword){ state ->
|
||||
onState(state)
|
||||
}
|
||||
}
|
||||
|
||||
//todo - same action as above... refactor
|
||||
fun requestInlineImage(uri: URI, onImageReady: (cacheUri: Uri?) -> Unit){
|
||||
gemini.request(uri.toString(), false, null){ state ->
|
||||
fun requestInlineImage(uri: URI, clientCertPassword: String?, onImageReady: (cacheUri: Uri?) -> Unit){
|
||||
gemini.request(uri.toString(), false, clientCertPassword){ state ->
|
||||
when (state) {
|
||||
is GemState.ResponseImage -> onImageReady(state.cacheUri)
|
||||
else -> onState(state)
|
||||
|
|
|
@ -4,6 +4,9 @@
|
|||
<item
|
||||
android:id="@+id/overflow_menu_search"
|
||||
android:title="@string/search"/>
|
||||
<item
|
||||
android:id="@+id/overflow_menu_sign"
|
||||
android:title="@string/sign"/>
|
||||
<item
|
||||
android:id="@+id/overflow_menu_bookmark"
|
||||
android:title="@string/add_bookmark"/>
|
||||
|
|
|
@ -73,6 +73,7 @@
|
|||
<string name="confirm_your_identity">Confirmez votre identité</string>
|
||||
<string name="use_biometric_unlock">Utilisez vos informations biométriques pour continuer</string>
|
||||
<string name="biometric_cert_verification">Certificat Client biométrique</string>
|
||||
<string name="sign">Certifier</string>
|
||||
<string name="set_home_capsule">Choisir comme capsule d\'accueil</string>
|
||||
<string name="check_for_updates">Rechercher des nouvelles versions</string>
|
||||
<string name="new_version_available">Nouvelle version disponible</string>
|
||||
|
|
|
@ -73,6 +73,7 @@
|
|||
<string name="confirm_your_identity">Confirm your identity</string>
|
||||
<string name="use_biometric_unlock">Verify your biometric credentials to continue</string>
|
||||
<string name="biometric_cert_verification">Client Certificate biometrics</string>
|
||||
<string name="sign">Sign</string>
|
||||
<string name="set_home_capsule">Set home capsule</string>
|
||||
<string name="check_for_updates">Check for updates</string>
|
||||
<string name="new_version_available">New version available</string>
|
||||
|
|
Loading…
Add table
Reference in a new issue