0
0
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:
Arne Schwabe 2021-10-08 02:22:07 +02:00
parent 34be3fa975
commit 9ca2ff6f06
3 changed files with 93 additions and 12 deletions

View File

@ -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)
}
}

View File

@ -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})")
}
}
}

View File

@ -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);
}