summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorArne Schwabe <arne@rfc2549.org>2021-10-16 04:22:31 +0200
committerArne Schwabe <arne@rfc2549.org>2021-10-16 04:22:31 +0200
commit9296124d0b89b4bb8534216c935ecb05f0cd620b (patch)
tree99ee912f415c7c1ea9812a68b95df79be1208ff5
parente0b23dfaedf15d2ab7753189c02c3cb29748a644 (diff)
Add TLS Profile to config converter and remove AsyncTask
-rw-r--r--main/src/main/res/values/arrays.xml2
-rw-r--r--main/src/ui/java/de/blinkt/openvpn/activities/ConfigConverter.kt232
-rw-r--r--main/src/ui/res/layout/config_converter.xml165
3 files changed, 237 insertions, 162 deletions
diff --git a/main/src/main/res/values/arrays.xml b/main/src/main/res/values/arrays.xml
index d5e21f3a..3d6512c1 100644
--- a/main/src/main/res/values/arrays.xml
+++ b/main/src/main/res/values/arrays.xml
@@ -46,6 +46,6 @@
<item>insecure (not recommend, allows insecure crypto)</item>
<item>legacy (default)</item>
<item>preferred (recommended but limited compabbility)</item>
- <item>Suite B</item>
+ <item>Suite B (only NIST approved elliptic curves)</item>
</string-array>
</resources>
diff --git a/main/src/ui/java/de/blinkt/openvpn/activities/ConfigConverter.kt b/main/src/ui/java/de/blinkt/openvpn/activities/ConfigConverter.kt
index 13538aa4..fa786dcb 100644
--- a/main/src/ui/java/de/blinkt/openvpn/activities/ConfigConverter.kt
+++ b/main/src/ui/java/de/blinkt/openvpn/activities/ConfigConverter.kt
@@ -14,7 +14,6 @@ import android.content.Intent
import android.content.pm.PackageManager
import android.database.Cursor
import android.net.Uri
-import android.os.AsyncTask
import android.os.Build
import android.os.Bundle
import android.os.Environment
@@ -28,6 +27,7 @@ import android.view.MenuItem
import android.view.View
import android.view.ViewGroup
import android.widget.*
+import androidx.lifecycle.lifecycleScope
import de.blinkt.openvpn.R
import de.blinkt.openvpn.VpnProfile
import de.blinkt.openvpn.core.ConfigParser
@@ -36,6 +36,9 @@ import de.blinkt.openvpn.core.ProfileManager
import de.blinkt.openvpn.fragments.Utils
import de.blinkt.openvpn.views.FileSelectLayout
import de.blinkt.openvpn.views.FileSelectLayout.FileSelectCallback
+import kotlinx.coroutines.Dispatchers
+import kotlinx.coroutines.launch
+import kotlinx.coroutines.withContext
import java.io.*
import java.net.URLDecoder
import java.util.*
@@ -57,7 +60,8 @@ class ConfigConverter : BaseActivity(), FileSelectCallback, View.OnClickListener
private lateinit var mProfilename: EditText
private lateinit var mCompatmode: Spinner
private lateinit var mCompatmodeLabel: TextView
- private var mImportTask: AsyncTask<Void, Void, Int>? = null
+ private lateinit var mTLSProfile: Spinner
+ private lateinit var mTLSProfileLabel: TextView
private lateinit var mLogLayout: LinearLayout
private lateinit var mProfilenameLabel: TextView
@@ -74,7 +78,11 @@ class ConfigConverter : BaseActivity(), FileSelectCallback, View.OnClickListener
requestPermissions(arrayOf(Manifest.permission.READ_EXTERNAL_STORAGE), requestCode)
}
- override fun onRequestPermissionsResult(requestCode: Int, permissions: Array<String>, grantResults: IntArray) {
+ override fun onRequestPermissionsResult(
+ requestCode: Int,
+ permissions: Array<String>,
+ grantResults: IntArray
+ ) {
super.onRequestPermissionsResult(requestCode, permissions, grantResults);
// Permission declined, do nothing
if (grantResults.size == 0 || grantResults[0] == PackageManager.PERMISSION_DENIED)
@@ -127,10 +135,15 @@ class ConfigConverter : BaseActivity(), FileSelectCallback, View.OnClickListener
}
mResult!!.mCompatMode = Utils.mapCompatMode(mCompatmode.selectedItemPosition)
- /* If you need compability with such an old version there is a high chance that
- the legacy provider is needed as well
- */
- if (mResult!!.mCompatMode in 1..20400)
+
+ val selectedTLSProfile = translSelectionToProfileName(mTLSProfile.selectedItemPosition)
+ if (selectedTLSProfile != "legacy" || !mResult!!.mTlSCertProfile.isNullOrEmpty()) {
+ mResult!!.mTlSCertProfile = selectedTLSProfile
+ }
+
+ /* If you need compability with such an old version or such a low security profile
+ * there is a high chance that the legacy provider is needed as well */
+ if (mResult!!.mCompatMode in 1..20400 || selectedTLSProfile == "insecure")
mResult!!.mUseLegacyProvider = true;
val intent = installPKCS12()
@@ -212,16 +225,18 @@ class ConfigConverter : BaseActivity(), FileSelectCallback, View.OnClickListener
fun showCertDialog() {
try {
- KeyChain.choosePrivateKeyAlias(this,
- { alias ->
- // Credential alias selected. Remember the alias selection for future use.
- mResult!!.mAlias = alias
- saveProfile()
- },
- arrayOf("RSA", "EC"), null, // issuer, null for any
- mResult!!.mServerName, // host name of server requesting the cert, null if unavailable
- -1, // port of server requesting the cert, -1 if unavailable
- mAliasName)// List of acceptable key types. null for any
+ KeyChain.choosePrivateKeyAlias(
+ this,
+ { alias ->
+ // Credential alias selected. Remember the alias selection for future use.
+ mResult!!.mAlias = alias
+ saveProfile()
+ },
+ arrayOf("RSA", "EC"), null, // issuer, null for any
+ mResult!!.mServerName, // host name of server requesting the cert, null if unavailable
+ -1, // port of server requesting the cert, -1 if unavailable
+ mAliasName
+ )// List of acceptable key types. null for any
// alias to preselect, null if unavailable
} catch (anf: ActivityNotFoundException) {
val ab = AlertDialog.Builder(this)
@@ -307,7 +322,11 @@ class ConfigConverter : BaseActivity(), FileSelectCallback, View.OnClickListener
return true
}
- private fun embedFile(filename: String?, type: Utils.FileType, onlyFindFileAndNullonNotFound: Boolean): String? {
+ private fun embedFile(
+ filename: String?,
+ type: Utils.FileType,
+ onlyFindFileAndNullonNotFound: Boolean
+ ): String? {
if (filename == null)
return null
@@ -400,10 +419,14 @@ class ConfigConverter : BaseActivity(), FileSelectCallback, View.OnClickListener
val fileDialogInfo = getFileDialogInfo(type!!)
- val isCert = type == Utils.FileType.CA_CERTIFICATE || type == Utils.FileType.CLIENT_CERTIFICATE
+ val isCert =
+ type == Utils.FileType.CA_CERTIFICATE || type == Utils.FileType.CLIENT_CERTIFICATE
val fl = FileSelectLayout(this, getString(fileDialogInfo.first), isCert, false)
fileSelectMap[type] = fl
- fl.layoutParams = LinearLayout.LayoutParams(LinearLayout.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT)
+ fl.layoutParams = LinearLayout.LayoutParams(
+ LinearLayout.LayoutParams.MATCH_PARENT,
+ ViewGroup.LayoutParams.WRAP_CONTENT
+ )
(findViewById<View>(R.id.config_convert_root) as LinearLayout).addView(fl, 2)
findViewById<View>(R.id.files_missing_hint).visibility = View.VISIBLE
@@ -549,11 +572,16 @@ class ConfigConverter : BaseActivity(), FileSelectCallback, View.OnClickListener
}
- mResult!!.mCaFilename = embedFile(mResult!!.mCaFilename, Utils.FileType.CA_CERTIFICATE, false)
- mResult!!.mClientCertFilename = embedFile(mResult!!.mClientCertFilename, Utils.FileType.CLIENT_CERTIFICATE, false)
- mResult!!.mClientKeyFilename = embedFile(mResult!!.mClientKeyFilename, Utils.FileType.KEYFILE, false)
- mResult!!.mTLSAuthFilename = embedFile(mResult!!.mTLSAuthFilename, Utils.FileType.TLS_AUTH_FILE, false)
- mResult!!.mPKCS12Filename = embedFile(mResult!!.mPKCS12Filename, Utils.FileType.PKCS12, false)
+ mResult!!.mCaFilename =
+ embedFile(mResult!!.mCaFilename, Utils.FileType.CA_CERTIFICATE, false)
+ mResult!!.mClientCertFilename =
+ embedFile(mResult!!.mClientCertFilename, Utils.FileType.CLIENT_CERTIFICATE, false)
+ mResult!!.mClientKeyFilename =
+ embedFile(mResult!!.mClientKeyFilename, Utils.FileType.KEYFILE, false)
+ mResult!!.mTLSAuthFilename =
+ embedFile(mResult!!.mTLSAuthFilename, Utils.FileType.TLS_AUTH_FILE, false)
+ mResult!!.mPKCS12Filename =
+ embedFile(mResult!!.mPKCS12Filename, Utils.FileType.PKCS12, false)
mResult!!.mCrlFilename = embedFile(mResult!!.mCrlFilename, Utils.FileType.CRL_FILE, true)
if (cp != null) {
mEmbeddedPwFile = cp.authUserPassFile
@@ -568,6 +596,25 @@ class ConfigConverter : BaseActivity(), FileSelectCallback, View.OnClickListener
}
}
+ private fun translateTLSProfileToSelection(tlsprofile: String?): Int {
+ return when (tlsprofile) {
+ "insecure" -> 0
+ "legacy" -> 1
+ "preferred" -> 2
+ "suiteb" -> 3
+ else -> 1
+ }
+ }
+
+ private fun translSelectionToProfileName(selection: Int): String {
+ return when (selection) {
+ 0 -> "insecure"
+ 1 -> "legacy"
+ 2 -> "preferred"
+ 3 -> "suiteb"
+ else -> "legacy"
+ }
+ }
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
@@ -588,6 +635,8 @@ class ConfigConverter : BaseActivity(), FileSelectCallback, View.OnClickListener
mCompatmode = findViewById(R.id.compatmode) as Spinner
mCompatmodeLabel = findViewById(R.id.compatmode_label) as TextView
+ mTLSProfile = findViewById(R.id.tls_profile) as Spinner
+ mTLSProfileLabel = findViewById(R.id.tls_profile_label) as TextView
if (savedInstanceState != null && savedInstanceState.containsKey(VPNPROFILE)) {
mResult = savedInstanceState.getSerializable(VPNPROFILE) as VpnProfile?
@@ -596,6 +645,7 @@ class ConfigConverter : BaseActivity(), FileSelectCallback, View.OnClickListener
mSourceUri = savedInstanceState.getParcelable("mSourceUri")
mProfilename.setText(mResult!!.mName)
mCompatmode.setSelection(Utils.mapCompatVer(mResult!!.mCompatMode))
+ mTLSProfile.setSelection(translateTLSProfileToSelection(mResult?.mTlSCertProfile))
if (savedInstanceState.containsKey("logentries")) {
@@ -625,8 +675,11 @@ class ConfigConverter : BaseActivity(), FileSelectCallback, View.OnClickListener
val data = intent.getStringExtra(Intent.EXTRA_TEXT)
if (data != null) {
- startImportTask(Uri.fromParts("inline", "inlinetext", null),
- "imported profiles from AS", data);
+ lifecycleScope.launch {
+ startImportTask(
+ Uri.fromParts("inline", "inlinetext", null),
+ "imported profiles from AS", data)
+ }
}
} else if (intent.action.equals(IMPORT_PROFILE) || intent.action.equals(Intent.ACTION_VIEW)) {
val data = intent.data
@@ -642,7 +695,10 @@ class ConfigConverter : BaseActivity(), FileSelectCallback, View.OnClickListener
//log(R.string.import_experimental);
log(R.string.importing_config, data.toString())
var possibleName: String? = null
- if (data.scheme != null && data.scheme == "file" || data.lastPathSegment != null && (data.lastPathSegment!!.endsWith(".ovpn") || data.lastPathSegment!!.endsWith(".conf"))) {
+ if (data.scheme != null && data.scheme == "file" || data.lastPathSegment != null && (data.lastPathSegment!!.endsWith(
+ ".ovpn"
+ ) || data.lastPathSegment!!.endsWith(".conf"))
+ ) {
possibleName = data.lastPathSegment
if (possibleName!!.lastIndexOf('/') != -1)
possibleName = possibleName.substring(possibleName.lastIndexOf('/') + 1)
@@ -651,7 +707,7 @@ class ConfigConverter : BaseActivity(), FileSelectCallback, View.OnClickListener
mPathsegments = data.pathSegments
- var cursor:Cursor? = null
+ var cursor: Cursor? = null
try {
cursor = contentResolver.query(data, null, null, null, null)
@@ -668,8 +724,7 @@ class ConfigConverter : BaseActivity(), FileSelectCallback, View.OnClickListener
log("Mime type: " + cursor.getString(columnIndex))
}
}
- }
- catch (se:SecurityException) {
+ } catch (se: SecurityException) {
log("Importing failed: ${se.localizedMessage}")
} finally {
cursor?.close()
@@ -679,69 +734,72 @@ class ConfigConverter : BaseActivity(), FileSelectCallback, View.OnClickListener
possibleName = possibleName.replace(".conf", "")
}
- startImportTask(data, possibleName, "")
-
-
+ lifecycleScope.launch {
+ startImportTask(data, possibleName, "")
+ }
}
- private fun startImportTask(data: Uri, possibleName: String?, inlineData: String) {
- mImportTask = object : AsyncTask<Void, Void, Int>() {
- private var mProgress: ProgressBar? = null
-
- override fun onPreExecute() {
- mProgress = ProgressBar(this@ConfigConverter)
- addViewToLog(mProgress)
- }
+ private suspend fun startImportTask(data: Uri, possibleName: String?, inlineData: String) {
+ val mProgress: ProgressBar
+ withContext(Dispatchers.Main)
+ {
+ mProgress = ProgressBar(this@ConfigConverter)
+ addViewToLog(mProgress)
+ }
+ var errorCode = 0
+ withContext(Dispatchers.IO)
+ {
- override fun doInBackground(vararg params: Void): Int? {
- try {
- var inputStream: InputStream?
- if (data.scheme.equals("inline")) {
- inputStream = inlineData.byteInputStream()
- } else {
- inputStream = contentResolver.openInputStream(data)
- }
-
- if (inputStream != null) {
- doImport(inputStream)
- }
- if (mResult == null)
- return -3
- } catch (se: IOException) {
- log(R.string.import_content_resolve_error.toString() + ":" + se.localizedMessage)
- if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M)
- checkMarschmallowFileImportError(data)
- return -2
- } catch (se: SecurityException) {
- log(R.string.import_content_resolve_error.toString() + ":" + se.localizedMessage)
- if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M)
- checkMarschmallowFileImportError(data)
- return -2
+ try {
+ val inputStream: InputStream?
+ if (data.scheme.equals("inline")) {
+ inputStream = inlineData.byteInputStream()
+ } else {
+ inputStream = contentResolver.openInputStream(data)
}
- return 0
- }
-
- override fun onPostExecute(errorCode: Int?) {
- mLogLayout.removeView(mProgress)
- addMissingFileDialogs()
- updateFileSelectDialogs()
-
- if (errorCode == 0) {
- displayWarnings()
- mResult!!.mName = getUniqueProfileName(possibleName)
- mProfilename.visibility = View.VISIBLE
- mProfilenameLabel.visibility = View.VISIBLE
- mProfilename.setText(mResult!!.name)
-
- mCompatmode.visibility = View.VISIBLE
- mCompatmodeLabel.visibility = View.VISIBLE
- mCompatmode.setSelection(Utils.mapCompatVer(mResult!!.mCompatMode))
-
- log(R.string.import_done)
+ if (inputStream != null) {
+ doImport(inputStream)
}
+ if (mResult == null)
+ errorCode = -3
+ } catch (se: IOException) {
+ log(R.string.import_content_resolve_error.toString() + ":" + se.localizedMessage)
+ if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M)
+ checkMarschmallowFileImportError(data)
+ errorCode = -2
+ } catch (se: SecurityException) {
+ log(R.string.import_content_resolve_error.toString() + ":" + se.localizedMessage)
+ if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M)
+ checkMarschmallowFileImportError(data)
+ errorCode = -2
}
- }.execute()
+ }
+ withContext(Dispatchers.Main)
+ {
+ mLogLayout.removeView(mProgress)
+ addMissingFileDialogs()
+ updateFileSelectDialogs()
+
+ if (errorCode == 0) {
+ displayWarnings()
+ val result = mResult!!
+ result.mName = getUniqueProfileName(possibleName)
+ mProfilename.visibility = View.VISIBLE
+ mProfilenameLabel.visibility = View.VISIBLE
+ mProfilename.setText(result.name)
+
+ mCompatmode.visibility = View.VISIBLE
+ mCompatmodeLabel.visibility = View.VISIBLE
+ mCompatmode.setSelection(Utils.mapCompatVer(result.mCompatMode))
+
+ mTLSProfile.visibility = View.VISIBLE
+ mTLSProfileLabel.visibility = View.VISIBLE
+ mTLSProfile.setSelection(translateTLSProfileToSelection(result.mTlSCertProfile))
+
+ log(R.string.import_done)
+ }
+ }
}
diff --git a/main/src/ui/res/layout/config_converter.xml b/main/src/ui/res/layout/config_converter.xml
index b980dc59..d4e1f820 100644
--- a/main/src/ui/res/layout/config_converter.xml
+++ b/main/src/ui/res/layout/config_converter.xml
@@ -1,95 +1,112 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
+<?xml version="1.0" encoding="utf-8"?><!--
~ Copyright (c) 2012-2016 Arne Schwabe
~ Distributed under the GNU GPL v2 with additional terms. For full terms see the file doc/LICENSE.txt
-->
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:tools="http://schemas.android.com/tools"
- android:layout_width="match_parent"
- android:layout_height="match_parent">
+ xmlns:tools="http://schemas.android.com/tools"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent">
-<ScrollView android:layout_width="match_parent"
+ <ScrollView
+ android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_margin="@dimen/stdpadding"
android:orientation="vertical">
- <LinearLayout
- android:orientation="vertical"
- android:layout_width="match_parent"
- android:id="@+id/config_convert_root"
- android:layout_height="wrap_content">
+ <LinearLayout
+ android:id="@+id/config_convert_root"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:orientation="vertical">
- <TextView
- android:visibility="gone"
- android:id="@+id/profilename_label"
- style="@style/item"
- android:labelFor="@id/profilename"
- android:text="@string/profilename"
- android:textAppearance="?android:attr/textAppearanceSmall"
- />
+ <TextView
+ android:id="@+id/profilename_label"
+ style="@style/item"
+ android:labelFor="@id/profilename"
+ android:text="@string/profilename"
+ android:textAppearance="?android:attr/textAppearanceSmall"
+ android:visibility="gone" />
- <EditText
- android:visibility="gone"
- android:id="@+id/profilename"
- style="@style/item"
- android:inputType="text" />
+ <EditText
+ android:id="@+id/profilename"
+ style="@style/item"
+ android:inputType="text"
+ android:visibility="gone" />
- <TextView
- style="@style/item"
- android:id="@+id/compatmode_label"
- android:text="@string/compat_mode_label"
- android:visibility="gone"
- android:textAppearance="?android:attr/textAppearanceSmall" />
- <Spinner
- android:id="@+id/compatmode"
- style="@style/item"
- android:visibility="gone"
- android:prompt="@string/compatmode"
- android:entries="@array/compat_mode"
- />
+ <TextView
+ android:id="@+id/compatmode_label"
+ style="@style/item"
+ android:text="@string/compat_mode_label"
+ android:textAppearance="?android:attr/textAppearanceSmall"
+ android:visibility="gone"
+ tools:visibility="visible" />
- <TextView
- android:layout_width="match_parent"
- android:layout_height="wrap_content"
- android:text="@string/files_missing_hint"
- android:visibility="gone"
- android:id="@+id/files_missing_hint"
- tools:visibilty="visible"/>
+ <Spinner
+ android:id="@+id/compatmode"
+ style="@style/item"
+ android:entries="@array/compat_mode"
+ android:prompt="@string/compatmode"
+ android:visibility="gone"
+ tools:visibility="visible" />
- <TextView
- android:text="@string/query_permissions_sdcard"
- android:layout_width="match_parent"
- android:layout_height="wrap_content"
- tools:visibility="visible"
- android:visibility="gone"
- android:id="@+id/permssion_hint"
- android:padding="5dp"
- android:textStyle="bold" />
+ <TextView
+ android:id="@+id/tls_profile_label"
+ style="@style/item"
+ android:text="@string/tls_profile"
+ android:textAppearance="?android:attr/textAppearanceSmall"
+ android:visibility="gone"
+ tools:visibility="visible" />
+ <Spinner
+ android:id="@+id/tls_profile"
+ style="@style/item"
+ android:entries="@array/tls_profile_entries"
+ android:prompt="@string/compatmode"
+ android:visibility="gone"
+ tools:visibility="visible" />
+ <TextView
+ android:id="@+id/files_missing_hint"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:text="@string/files_missing_hint"
+ android:visibility="gone"
+ tools:visibilty="visible" />
- <CheckBox
- android:id="@+id/importpkcs12"
- android:layout_width="fill_parent"
- android:layout_height="wrap_content"
- android:checked="true"
- tools:visibilty="visible"
- android:text="@string/importpkcs12fromconfig"
- android:visibility="gone"/>
+ <TextView
+ android:id="@+id/permssion_hint"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:padding="5dp"
+ android:text="@string/query_permissions_sdcard"
+ android:textStyle="bold"
+ android:visibility="gone"
+ tools:visibility="visible" />
- <TextView
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:layout_margin="10dp"
- android:textAppearance="?android:attr/textAppearanceMedium"
- android:text="@string/import_log"
- android:id="@+id/textView"/>
- <Space
- android:id="@+id/fab_footerspace"
- android:visibility="gone"
- android:layout_width="40dp"
- android:layout_height="@dimen/round_button_diameter" />
- </LinearLayout>
+ <CheckBox
+ android:id="@+id/importpkcs12"
+ android:layout_width="fill_parent"
+ android:layout_height="wrap_content"
+ android:checked="true"
+ android:text="@string/importpkcs12fromconfig"
+ android:visibility="gone"
+ tools:visibilty="visible" />
+
+ <TextView
+ android:id="@+id/textView"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:layout_margin="10dp"
+ android:text="@string/import_log"
+ android:textAppearance="?android:attr/textAppearanceMedium" />
+
+ <Space
+ android:id="@+id/fab_footerspace"
+ android:layout_width="40dp"
+ android:layout_height="@dimen/round_button_diameter"
+ android:visibility="gone" />
+ </LinearLayout>
</ScrollView>
+
<include layout="@layout/save_fab" />
</RelativeLayout>