mirror of
https://github.com/schwabe/ics-openvpn.git
synced 2024-09-19 19:42:29 +02:00
Add red warnings if a profile uses deprecated/insecure options
This commit is contained in:
parent
34be3fa975
commit
9ca2ff6f06
@ -1,3 +1,4 @@
|
||||
import de.blinkt.openvpn.VpnProfile
|
||||
import de.blinkt.openvpn.fragments.Utils
|
||||
import org.junit.Assert
|
||||
import org.junit.Test
|
||||
@ -9,4 +10,16 @@ class TestUiUtils {
|
||||
Assert.assertEquals(0, Utils.mapCompatVer(20707))
|
||||
Assert.assertEquals(3, Utils.mapCompatVer(11723))
|
||||
}
|
||||
|
||||
@Test
|
||||
fun testWarnings() {
|
||||
val vp = VpnProfile("unittest")
|
||||
vp.mUseCustomConfig = true;
|
||||
vp.mCustomConfigOptions = "\ntls-cipher DEFAULT:@SECLEVEL=0\n"
|
||||
|
||||
val warnings = mutableListOf<String>()
|
||||
Utils.addSoftWarnings(warnings, vp)
|
||||
Assert.assertTrue(warnings.size >= 1)
|
||||
|
||||
}
|
||||
}
|
@ -8,10 +8,16 @@ import android.annotation.TargetApi
|
||||
import android.content.Context
|
||||
import android.content.Intent
|
||||
import android.content.pm.PackageManager
|
||||
import android.graphics.Color
|
||||
import android.os.Build
|
||||
import android.provider.OpenableColumns
|
||||
import android.text.SpannableString
|
||||
import android.text.SpannableStringBuilder
|
||||
import android.text.TextUtils
|
||||
import android.text.style.ForegroundColorSpan
|
||||
import android.util.Base64
|
||||
import android.webkit.MimeTypeMap
|
||||
import de.blinkt.openvpn.R
|
||||
import kotlin.Throws
|
||||
import de.blinkt.openvpn.VpnProfile
|
||||
import de.blinkt.openvpn.core.Preferences
|
||||
@ -258,4 +264,54 @@ object Utils {
|
||||
else -> return 0
|
||||
}
|
||||
}
|
||||
|
||||
val seclevleregex = Regex("tls-cipher.*@SECLEVEL=0")
|
||||
|
||||
@JvmStatic
|
||||
fun getWarningText(c:Context, vp:VpnProfile): SpannableStringBuilder {
|
||||
val warnings = mutableListOf<String>()
|
||||
|
||||
val errorId = vp.checkProfile(c)
|
||||
if (errorId != R.string.no_error_found)
|
||||
{
|
||||
warnings.add(c.resources.getString(errorId))
|
||||
}
|
||||
|
||||
addSoftWarnings(warnings, vp)
|
||||
val builder = SpannableStringBuilder()
|
||||
if (warnings.size > 0) {
|
||||
val warnSpan = SpannableString( warnings.joinToString(separator = ", "))
|
||||
warnSpan.setSpan(ForegroundColorSpan(Color.RED), 0, warnSpan.length, 0)
|
||||
builder.append(warnSpan)
|
||||
}
|
||||
|
||||
return builder
|
||||
}
|
||||
|
||||
val weakCiphers = listOf<String>("BF-CBC", "DES-CBC", "NONE")
|
||||
|
||||
@JvmStatic
|
||||
fun addSoftWarnings(warnings:MutableList<String>, vp:VpnProfile) {
|
||||
if (vp.mUseLegacyProvider)
|
||||
warnings.add("legacy Provider enabled")
|
||||
if (vp.mAuthenticationType == VpnProfile.TYPE_STATICKEYS)
|
||||
warnings.add("deprecated static key (--secret) mode")
|
||||
if (vp.mUseCustomConfig && vp.mCustomConfigOptions.contains(seclevleregex))
|
||||
warnings.add("low security (@SECLEVEL=0)")
|
||||
if (vp.mCompatMode > 0 )
|
||||
warnings.add("compat mode enabled")
|
||||
|
||||
var cipher= vp.mCipher.toUpperCase(Locale.ROOT)
|
||||
if (TextUtils.isEmpty(cipher))
|
||||
cipher = "BF-CBC";
|
||||
|
||||
for (weakCipher in weakCiphers) {
|
||||
if ((vp.mDataCiphers != null && vp.mDataCiphers.toUpperCase(Locale.ROOT)
|
||||
.contains(weakCipher))
|
||||
|| (vp.mCompatMode in 1..20399 && (cipher == weakCipher))
|
||||
)
|
||||
warnings.add("weak cipher (${weakCipher})")
|
||||
}
|
||||
}
|
||||
|
||||
}
|
@ -20,11 +20,14 @@ import android.os.Build;
|
||||
import android.os.Bundle;
|
||||
import android.os.PersistableBundle;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.annotation.RequiresApi;
|
||||
import androidx.fragment.app.ListFragment;
|
||||
|
||||
import android.text.Html;
|
||||
import android.text.Html.ImageGetter;
|
||||
import android.text.SpannableString;
|
||||
import android.text.SpannableStringBuilder;
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.Menu;
|
||||
import android.view.MenuInflater;
|
||||
@ -81,6 +84,7 @@ public class VPNProfileList extends ListFragment implements OnClickListener, Vpn
|
||||
private String mLastStatusMessage;
|
||||
private ArrayAdapter<VpnProfile> mArrayadapter;
|
||||
private Intent mLastIntent;
|
||||
private VpnProfile defaultVPN;
|
||||
|
||||
@Override
|
||||
public void updateState(String state, String logmessage, final int localizedResId, ConnectionStatus level, Intent intent) {
|
||||
@ -246,6 +250,7 @@ public class VPNProfileList extends ListFragment implements OnClickListener, Vpn
|
||||
updateDynamicShortcuts();
|
||||
}
|
||||
VpnStatus.addStateListener(this);
|
||||
defaultVPN = ProfileManager.getAlwaysOnVPN(requireContext());
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -286,7 +291,7 @@ public class VPNProfileList extends ListFragment implements OnClickListener, Vpn
|
||||
}
|
||||
|
||||
private void populateVpnList() {
|
||||
boolean sortByLRU = Preferences.getDefaultSharedPreferences(getActivity()).getBoolean(PREF_SORT_BY_LRU, false);
|
||||
boolean sortByLRU = Preferences.getDefaultSharedPreferences(requireActivity()).getBoolean(PREF_SORT_BY_LRU, false);
|
||||
Collection<VpnProfile> allvpn = getPM().getProfiles();
|
||||
TreeSet<VpnProfile> sortedset;
|
||||
if (sortByLRU)
|
||||
@ -303,7 +308,7 @@ public class VPNProfileList extends ListFragment implements OnClickListener, Vpn
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
|
||||
public void onCreateOptionsMenu(Menu menu, @NonNull MenuInflater inflater) {
|
||||
menu.add(0, MENU_ADD_PROFILE, 0, R.string.menu_add_profile)
|
||||
.setIcon(R.drawable.ic_menu_add)
|
||||
.setAlphabeticShortcut('a')
|
||||
@ -589,30 +594,37 @@ public class VPNProfileList extends ListFragment implements OnClickListener, Vpn
|
||||
super(context, resource, textViewResourceId);
|
||||
}
|
||||
|
||||
@NonNull
|
||||
@Override
|
||||
public View getView(final int position, View convertView, ViewGroup parent) {
|
||||
public View getView(final int position, View convertView, @NonNull ViewGroup parent) {
|
||||
View v = super.getView(position, convertView, parent);
|
||||
|
||||
final VpnProfile profile = (VpnProfile) getListAdapter().getItem(position);
|
||||
|
||||
View titleview = v.findViewById(R.id.vpn_list_item_left);
|
||||
titleview.setOnClickListener(new OnClickListener() {
|
||||
@Override
|
||||
public void onClick(View v) {
|
||||
startOrStopVPN(profile);
|
||||
}
|
||||
});
|
||||
titleview.setOnClickListener(v1 -> startOrStopVPN(profile));
|
||||
|
||||
View settingsview = v.findViewById(R.id.quickedit_settings);
|
||||
settingsview.setOnClickListener(view -> editVPN(profile));
|
||||
|
||||
TextView subtitle = (TextView) v.findViewById(R.id.vpn_item_subtitle);
|
||||
TextView subtitle = v.findViewById(R.id.vpn_item_subtitle);
|
||||
SpannableStringBuilder warningText = Utils.getWarningText(requireContext(), profile);
|
||||
|
||||
if (profile == defaultVPN) {
|
||||
if (warningText.length() > 0)
|
||||
warningText.append(" ");
|
||||
warningText.append(new SpannableString("Default VPN"));
|
||||
}
|
||||
|
||||
if (profile.getUUIDString().equals(VpnStatus.getLastConnectedVPNProfile())) {
|
||||
subtitle.setText(mLastStatusMessage);
|
||||
subtitle.setVisibility(View.VISIBLE);
|
||||
} else {
|
||||
subtitle.setText("");
|
||||
subtitle.setVisibility(View.GONE);
|
||||
subtitle.setText(warningText);
|
||||
if (warningText.length() > 0)
|
||||
subtitle.setVisibility(View.VISIBLE);
|
||||
else
|
||||
subtitle.setVisibility(View.GONE);
|
||||
}
|
||||
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user