Merge branch 'android-updates'
This fixes GUI-related compatibility issues with Android 16 and allows (pre-)selecting on-device certificates/keys with managed profiles. Also fixes a typo in the managed config description that prevented split-tunneling settings from working.
This commit is contained in:
@@ -1,16 +1,16 @@
|
||||
apply plugin: 'com.android.application'
|
||||
|
||||
android {
|
||||
namespace 'org.strongswan.android'
|
||||
namespace = 'org.strongswan.android'
|
||||
|
||||
defaultConfig {
|
||||
applicationId "org.strongswan.android"
|
||||
compileSdk 34
|
||||
compileSdk = 36
|
||||
minSdkVersion 21
|
||||
targetSdkVersion 34
|
||||
targetSdkVersion 36
|
||||
|
||||
versionCode 91
|
||||
versionName "2.5.6"
|
||||
versionCode 94
|
||||
versionName "2.6.0"
|
||||
|
||||
externalNativeBuild {
|
||||
ndkBuild {
|
||||
@@ -19,7 +19,7 @@ android {
|
||||
}
|
||||
}
|
||||
|
||||
ndkVersion "27.2.12479018"
|
||||
ndkVersion = "27.3.13750724"
|
||||
|
||||
externalNativeBuild {
|
||||
ndkBuild {
|
||||
@@ -46,10 +46,12 @@ android {
|
||||
|
||||
dependencies {
|
||||
implementation 'androidx.appcompat:appcompat:1.7.1'
|
||||
implementation 'androidx.lifecycle:lifecycle-process:2.9.1'
|
||||
implementation 'androidx.core:core:1.17.0'
|
||||
implementation 'androidx.lifecycle:lifecycle-process:2.9.4'
|
||||
implementation 'androidx.preference:preference:1.2.1'
|
||||
implementation 'com.google.android.material:material:1.12.0'
|
||||
implementation 'androidx.localbroadcastmanager:localbroadcastmanager:1.1.0'
|
||||
implementation 'com.google.android.material:material:1.13.0'
|
||||
testImplementation 'junit:junit:4.13.2'
|
||||
testImplementation 'org.assertj:assertj-core:3.24.2'
|
||||
testImplementation 'org.mockito:mockito-core:5.8.0'
|
||||
testImplementation 'org.assertj:assertj-core:3.27.6'
|
||||
testImplementation 'org.mockito:mockito-core:5.20.0'
|
||||
}
|
||||
|
||||
@@ -36,6 +36,7 @@
|
||||
android:icon="@mipmap/ic_launcher"
|
||||
android:label="@string/app_name"
|
||||
android:theme="@style/ApplicationTheme"
|
||||
android:windowSoftInputMode="adjustResize"
|
||||
android:networkSecurityConfig="@xml/network_security_config"
|
||||
android:enableOnBackInvokedCallback="true"
|
||||
android:allowBackup="false" >
|
||||
|
||||
+5
@@ -38,6 +38,7 @@ public class ManagedVpnProfile extends VpnProfile
|
||||
private static final String KEY_REMOTE_REVOCATION_CRL_FLAG = "remote_revocation_crl";
|
||||
private static final String KEY_REMOTE_REVOCATION_OCSP_FLAG = "remote_revocation_ocsp";
|
||||
private static final String KEY_REMOTE_REVOCATION_STRICT_FLAG = "remote_revocation_strict";
|
||||
private static final String KEY_LOCAL_USER_CERTIFICATE_ALIAS = "user_certificate_alias";
|
||||
private static final String KEY_LOCAL_RSA_PSS_FLAG = "local_rsa_pss";
|
||||
|
||||
private static final String KEY_SPLIT_TUNNELLING_BLOCK_IPV4_FLAG = "split_tunnelling_block_ipv4";
|
||||
@@ -152,6 +153,10 @@ public class ManagedVpnProfile extends VpnProfile
|
||||
userCertificate = new ManagedUserCertificate(uuid.toString(), userCertificateData, userCertificatePassword);
|
||||
setUserCertificateAlias(userCertificate.getAlias());
|
||||
}
|
||||
else
|
||||
{
|
||||
setUserCertificateAlias(getString(local, KEY_LOCAL_USER_CERTIFICATE_ALIAS));
|
||||
}
|
||||
|
||||
flags = addPositiveFlag(flags, local, KEY_LOCAL_RSA_PSS_FLAG, VpnProfile.FLAGS_RSA_PSS);
|
||||
return flags;
|
||||
|
||||
+11
-4
@@ -33,6 +33,7 @@ import java.util.UUID;
|
||||
public class VpnProfileManagedDataSource implements VpnProfileDataSource
|
||||
{
|
||||
private static final String NAME_MANAGED_VPN_PROFILES = "org.strongswan.android.data.VpnProfileManagedDataSource.preferences";
|
||||
private static final String PREFIX_USER_CERT = "usercert:";
|
||||
|
||||
private final ManagedConfigurationService mManagedConfigurationService;
|
||||
private final SharedPreferences mSharedPreferences;
|
||||
@@ -52,11 +53,14 @@ public class VpnProfileManagedDataSource implements VpnProfileDataSource
|
||||
@Override
|
||||
public void close()
|
||||
{
|
||||
/* remove passwords that are no longer referenced by a VPN profile */
|
||||
final Set<String> actualKeys = mManagedConfigurationService.getManagedProfiles().keySet();
|
||||
|
||||
/* remove settings not referenced by a VPN profile */
|
||||
final Set<String> storedKeys = new HashSet<>(mSharedPreferences.getAll().keySet());
|
||||
storedKeys.removeAll(actualKeys);
|
||||
|
||||
for (String uuid : mManagedConfigurationService.getManagedProfiles().keySet())
|
||||
{
|
||||
storedKeys.remove(uuid);
|
||||
storedKeys.remove(PREFIX_USER_CERT + uuid);
|
||||
}
|
||||
|
||||
final SharedPreferences.Editor editor = mSharedPreferences.edit();
|
||||
for (String key : storedKeys)
|
||||
@@ -84,6 +88,7 @@ public class VpnProfileManagedDataSource implements VpnProfileDataSource
|
||||
|
||||
final SharedPreferences.Editor editor = mSharedPreferences.edit();
|
||||
editor.putString(profile.getUUID().toString(), profile.getPassword());
|
||||
editor.putString(PREFIX_USER_CERT + profile.getUUID().toString(), profile.getUserCertificateAlias());
|
||||
return editor.commit();
|
||||
}
|
||||
|
||||
@@ -100,8 +105,10 @@ public class VpnProfileManagedDataSource implements VpnProfileDataSource
|
||||
private VpnProfile prepareVpnProfile(VpnProfile managedProfile)
|
||||
{
|
||||
final String password = mSharedPreferences.getString(managedProfile.getUUID().toString(), managedProfile.getPassword());
|
||||
final String alias = mSharedPreferences.getString(PREFIX_USER_CERT + managedProfile.getUUID().toString(), managedProfile.getUserCertificateAlias());
|
||||
final VpnProfile vpnProfile = managedProfile.clone();
|
||||
vpnProfile.setPassword(password);
|
||||
vpnProfile.setUserCertificateAlias(alias);
|
||||
vpnProfile.setDataSource(this);
|
||||
return vpnProfile;
|
||||
}
|
||||
|
||||
-1
@@ -966,7 +966,6 @@ public class CharonVpnService extends VpnService implements Runnable, VpnStateSe
|
||||
return fd != null ? fd.detachFd() : -1;
|
||||
}
|
||||
|
||||
@TargetApi(Build.VERSION_CODES.LOLLIPOP)
|
||||
public synchronized void establishBlocking()
|
||||
{
|
||||
/* just choose some arbitrary values to block all traffic (except for what's configured in the profile) */
|
||||
|
||||
@@ -26,10 +26,12 @@ import android.widget.Toast;
|
||||
import org.strongswan.android.R;
|
||||
import org.strongswan.android.data.LogContentProvider;
|
||||
import org.strongswan.android.logic.CharonVpnService;
|
||||
import org.strongswan.android.utils.Utils;
|
||||
|
||||
import java.io.File;
|
||||
|
||||
import androidx.appcompat.app.AppCompatActivity;
|
||||
import androidx.core.view.WindowCompat;
|
||||
|
||||
public class LogActivity extends AppCompatActivity
|
||||
{
|
||||
@@ -38,6 +40,8 @@ public class LogActivity extends AppCompatActivity
|
||||
{
|
||||
super.onCreate(savedInstanceState);
|
||||
setContentView(R.layout.log_activity);
|
||||
WindowCompat.enableEdgeToEdge(getWindow());
|
||||
Utils.applyWindowInsetsAsMarginsForLists(findViewById(R.id.layout));
|
||||
|
||||
getSupportActionBar().setDisplayHomeAsUpEnabled(true);
|
||||
}
|
||||
|
||||
@@ -30,6 +30,7 @@ import android.widget.ListView;
|
||||
|
||||
import org.strongswan.android.R;
|
||||
import org.strongswan.android.logic.CharonVpnService;
|
||||
import org.strongswan.android.utils.Utils;
|
||||
|
||||
import java.io.BufferedReader;
|
||||
import java.io.File;
|
||||
@@ -81,6 +82,8 @@ public class LogFragment extends Fragment
|
||||
mLog = view.findViewById(R.id.log);
|
||||
mLog.setAdapter(mLogAdapter);
|
||||
|
||||
Utils.applyWindowInsetsAsPaddingForLists(mLog);
|
||||
|
||||
mScrollPosition = -1;
|
||||
if (savedInstanceState != null)
|
||||
{
|
||||
|
||||
@@ -34,6 +34,7 @@ import org.strongswan.android.data.VpnProfile;
|
||||
import org.strongswan.android.logic.StrongSwanApplication;
|
||||
import org.strongswan.android.logic.TrustedCertificateManager;
|
||||
import org.strongswan.android.ui.VpnProfileListFragment.OnVpnProfileSelectedListener;
|
||||
import org.strongswan.android.utils.Utils;
|
||||
|
||||
import java.io.File;
|
||||
import java.util.ArrayList;
|
||||
@@ -43,6 +44,7 @@ import androidx.appcompat.app.ActionBar;
|
||||
import androidx.appcompat.app.AlertDialog;
|
||||
import androidx.appcompat.app.AppCompatActivity;
|
||||
import androidx.appcompat.app.AppCompatDialogFragment;
|
||||
import androidx.core.view.WindowCompat;
|
||||
import androidx.fragment.app.Fragment;
|
||||
import androidx.fragment.app.FragmentManager;
|
||||
import androidx.fragment.app.FragmentTransaction;
|
||||
@@ -66,6 +68,8 @@ public class MainActivity extends AppCompatActivity implements OnVpnProfileSelec
|
||||
{
|
||||
super.onCreate(savedInstanceState);
|
||||
setContentView(R.layout.main);
|
||||
WindowCompat.enableEdgeToEdge(getWindow());
|
||||
Utils.applyWindowInsetsAsMarginsForLists(findViewById(R.id.layout));
|
||||
|
||||
ActionBar bar = getSupportActionBar();
|
||||
bar.setDisplayShowHomeEnabled(true);
|
||||
|
||||
+3
@@ -18,6 +18,8 @@ package org.strongswan.android.ui;
|
||||
|
||||
import android.os.Bundle;
|
||||
import androidx.appcompat.app.AppCompatActivity;
|
||||
import androidx.core.view.WindowCompat;
|
||||
|
||||
import android.view.MenuItem;
|
||||
|
||||
import org.strongswan.android.R;
|
||||
@@ -33,6 +35,7 @@ public class RemediationInstructionsActivity extends AppCompatActivity implement
|
||||
{
|
||||
super.onCreate(savedInstanceState);
|
||||
setContentView(R.layout.remediation_instructions);
|
||||
WindowCompat.enableEdgeToEdge(getWindow());
|
||||
getSupportActionBar().setDisplayHomeAsUpEnabled(true);
|
||||
|
||||
if (savedInstanceState != null)
|
||||
|
||||
+3
@@ -26,6 +26,7 @@ import androidx.activity.OnBackPressedCallback;
|
||||
import androidx.annotation.Nullable;
|
||||
import androidx.appcompat.app.ActionBar;
|
||||
import androidx.appcompat.app.AppCompatActivity;
|
||||
import androidx.core.view.WindowCompat;
|
||||
import androidx.fragment.app.FragmentManager;
|
||||
|
||||
public class SelectedApplicationsActivity extends AppCompatActivity
|
||||
@@ -37,6 +38,8 @@ public class SelectedApplicationsActivity extends AppCompatActivity
|
||||
protected void onCreate(@Nullable Bundle savedInstanceState)
|
||||
{
|
||||
super.onCreate(savedInstanceState);
|
||||
WindowCompat.enableEdgeToEdge(getWindow());
|
||||
WindowCompat.setDecorFitsSystemWindows(getWindow(), true);
|
||||
|
||||
ActionBar actionBar = getSupportActionBar();
|
||||
actionBar.setDisplayHomeAsUpEnabled(true);
|
||||
|
||||
+3
@@ -20,6 +20,7 @@ import android.os.Bundle;
|
||||
import android.view.MenuItem;
|
||||
|
||||
import androidx.appcompat.app.AppCompatActivity;
|
||||
import androidx.core.view.WindowCompat;
|
||||
|
||||
public class SettingsActivity extends AppCompatActivity
|
||||
{
|
||||
@@ -28,6 +29,8 @@ public class SettingsActivity extends AppCompatActivity
|
||||
protected void onCreate(Bundle savedInstanceState)
|
||||
{
|
||||
super.onCreate(savedInstanceState);
|
||||
WindowCompat.enableEdgeToEdge(getWindow());
|
||||
WindowCompat.setDecorFitsSystemWindows(getWindow(), true);
|
||||
|
||||
getSupportActionBar().setDisplayHomeAsUpEnabled(true);
|
||||
|
||||
|
||||
+1
@@ -41,6 +41,7 @@ import androidx.activity.result.contract.ActivityResultContracts;
|
||||
import androidx.appcompat.app.AlertDialog;
|
||||
import androidx.appcompat.app.AppCompatActivity;
|
||||
import androidx.appcompat.app.AppCompatDialogFragment;
|
||||
import androidx.core.view.WindowCompat;
|
||||
import androidx.fragment.app.FragmentTransaction;
|
||||
|
||||
public class TrustedCertificateImportActivity extends AppCompatActivity
|
||||
|
||||
+3
@@ -33,6 +33,7 @@ import org.strongswan.android.logic.TrustedCertificateManager;
|
||||
import org.strongswan.android.logic.TrustedCertificateManager.TrustedCertificateSource;
|
||||
import org.strongswan.android.security.TrustedCertificateEntry;
|
||||
import org.strongswan.android.ui.CertificateDeleteConfirmationDialog.OnCertificateDeleteListener;
|
||||
import org.strongswan.android.utils.Utils;
|
||||
|
||||
import java.security.KeyStore;
|
||||
|
||||
@@ -41,6 +42,7 @@ import androidx.activity.result.contract.ActivityResultContracts;
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.appcompat.app.ActionBar;
|
||||
import androidx.appcompat.app.AppCompatActivity;
|
||||
import androidx.core.view.WindowCompat;
|
||||
import androidx.fragment.app.Fragment;
|
||||
import androidx.fragment.app.FragmentActivity;
|
||||
import androidx.viewpager2.adapter.FragmentStateAdapter;
|
||||
@@ -71,6 +73,7 @@ public class TrustedCertificatesActivity extends AppCompatActivity implements Tr
|
||||
{
|
||||
super.onCreate(savedInstanceState);
|
||||
setContentView(R.layout.trusted_certificates_activity);
|
||||
WindowCompat.enableEdgeToEdge(getWindow());
|
||||
|
||||
ActionBar actionBar = getSupportActionBar();
|
||||
actionBar.setDisplayHomeAsUpEnabled(true);
|
||||
|
||||
+40
@@ -70,6 +70,7 @@ public class VpnProfileControlActivity extends AppCompatActivity
|
||||
private static final String WAITING_FOR_RESULT = "WAITING_FOR_RESULT";
|
||||
private static final String PROFILE_NAME = "PROFILE_NAME";
|
||||
private static final String PROFILE_REQUIRES_PASSWORD = "REQUIRES_PASSWORD";
|
||||
private static final String PROFILE_CERTIFICATE_MISSING = "CERTIFICATE_MISSING";
|
||||
private static final String PROFILE_RECONNECT = "RECONNECT";
|
||||
private static final String PROFILE_DISCONNECT = "DISCONNECT";
|
||||
private static final String DIALOG_TAG = "Dialog";
|
||||
@@ -332,6 +333,8 @@ public class VpnProfileControlActivity extends AppCompatActivity
|
||||
profileInfo.putString(VpnProfileDataSource.KEY_USERNAME, profile.getUsername());
|
||||
profileInfo.putString(VpnProfileDataSource.KEY_PASSWORD, profile.getPassword());
|
||||
profileInfo.putBoolean(PROFILE_REQUIRES_PASSWORD, profile.getVpnType().has(VpnTypeFeature.USER_PASS));
|
||||
profileInfo.putBoolean(PROFILE_CERTIFICATE_MISSING, profile.getVpnType().has(VpnTypeFeature.CERTIFICATE) &&
|
||||
profile.getUserCertificateAlias() == null);
|
||||
profileInfo.putString(PROFILE_NAME, profile.getName());
|
||||
|
||||
removeFragmentByTag(DIALOG_TAG);
|
||||
@@ -355,6 +358,13 @@ public class VpnProfileControlActivity extends AppCompatActivity
|
||||
*/
|
||||
private void startVpnProfile(Bundle profileInfo)
|
||||
{
|
||||
if (profileInfo.getBoolean(PROFILE_CERTIFICATE_MISSING))
|
||||
{
|
||||
CertificateRequiredDialog dialog = new CertificateRequiredDialog();
|
||||
dialog.setArguments(profileInfo);
|
||||
dialog.show(getSupportFragmentManager(), DIALOG_TAG);
|
||||
return;
|
||||
}
|
||||
if (profileInfo.getBoolean(PROFILE_REQUIRES_PASSWORD) &&
|
||||
profileInfo.getString(VpnProfileDataSource.KEY_PASSWORD) == null)
|
||||
{
|
||||
@@ -621,6 +631,36 @@ public class VpnProfileControlActivity extends AppCompatActivity
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Class that displays a dialog warning about a missing certificate.
|
||||
*/
|
||||
public static class CertificateRequiredDialog extends AppCompatDialogFragment
|
||||
{
|
||||
@Override
|
||||
public Dialog onCreateDialog(Bundle savedInstanceState)
|
||||
{
|
||||
final Bundle profileInfo = getArguments();
|
||||
|
||||
AlertDialog.Builder builder = new AlertDialog.Builder(getActivity())
|
||||
.setTitle(R.string.certificate_required_title)
|
||||
.setMessage(R.string.certificate_required_text)
|
||||
.setNegativeButton(android.R.string.cancel, (dialog, which) -> getActivity().finish())
|
||||
.setPositiveButton(R.string.edit_profile, (dialog, which) -> {
|
||||
Intent editIntent = new Intent(getActivity(), VpnProfileDetailActivity.class);
|
||||
editIntent.putExtra(VpnProfileDataSource.KEY_UUID, profileInfo.getString(VpnProfileDataSource.KEY_UUID));
|
||||
startActivity(editIntent);
|
||||
getActivity().finish();
|
||||
});
|
||||
return builder.create();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onCancel(DialogInterface dialog)
|
||||
{
|
||||
getActivity().finish();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Class that displays a warning before asking the user to add the app to the
|
||||
* device's power whitelist.
|
||||
|
||||
+12
-3
@@ -54,6 +54,7 @@ import android.widget.Spinner;
|
||||
import android.widget.TextView;
|
||||
|
||||
import org.strongswan.android.R;
|
||||
import org.strongswan.android.data.ManagedVpnProfile;
|
||||
import org.strongswan.android.data.VpnProfile;
|
||||
import org.strongswan.android.data.VpnProfile.SelectedAppsHandling;
|
||||
import org.strongswan.android.data.VpnProfileDataSource;
|
||||
@@ -84,6 +85,7 @@ import androidx.appcompat.app.AppCompatActivity;
|
||||
import androidx.appcompat.app.AppCompatDialogFragment;
|
||||
import androidx.appcompat.widget.SwitchCompat;
|
||||
import androidx.core.text.HtmlCompat;
|
||||
import androidx.core.view.WindowCompat;
|
||||
import androidx.localbroadcastmanager.content.LocalBroadcastManager;
|
||||
|
||||
public class VpnProfileDetailActivity extends AppCompatActivity
|
||||
@@ -199,6 +201,7 @@ public class VpnProfileDetailActivity extends AppCompatActivity
|
||||
mDataSource.open();
|
||||
|
||||
setContentView(R.layout.profile_detail_view);
|
||||
WindowCompat.enableEdgeToEdge(getWindow());
|
||||
|
||||
mManagedProfile = findViewById(R.id.managed_profile);
|
||||
|
||||
@@ -815,7 +818,7 @@ public class VpnProfileDetailActivity extends AppCompatActivity
|
||||
alias = mProfile.getCertificateAlias();
|
||||
getSupportActionBar().setTitle(mProfile.getName());
|
||||
|
||||
setReadOnly(mProfile.isReadOnly());
|
||||
setReadOnly(mProfile);
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -880,8 +883,10 @@ public class VpnProfileDetailActivity extends AppCompatActivity
|
||||
}
|
||||
}
|
||||
|
||||
private void setReadOnly(final boolean readOnly)
|
||||
private void setReadOnly(final VpnProfile profile)
|
||||
{
|
||||
final boolean readOnly = profile.isReadOnly();
|
||||
|
||||
mManagedProfile.setVisibility(readOnly ? View.VISIBLE : View.GONE);
|
||||
|
||||
mName.setEnabled(!readOnly);
|
||||
@@ -918,8 +923,12 @@ public class VpnProfileDetailActivity extends AppCompatActivity
|
||||
|
||||
if (readOnly)
|
||||
{
|
||||
ManagedVpnProfile managedProfile = (ManagedVpnProfile)profile;
|
||||
mSelectCert.setOnClickListener(null);
|
||||
mSelectUserCert.setOnClickListener(null);
|
||||
if (managedProfile.getUserCertificate() != null)
|
||||
{
|
||||
mSelectUserCert.setOnClickListener(null);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+2
@@ -78,6 +78,7 @@ import javax.net.ssl.SSLHandshakeException;
|
||||
import androidx.activity.result.ActivityResultLauncher;
|
||||
import androidx.activity.result.contract.ActivityResultContracts;
|
||||
import androidx.appcompat.app.AppCompatActivity;
|
||||
import androidx.core.view.WindowCompat;
|
||||
import androidx.loader.app.LoaderManager;
|
||||
import androidx.loader.content.AsyncTaskLoader;
|
||||
import androidx.loader.content.Loader;
|
||||
@@ -204,6 +205,7 @@ public class VpnProfileImportActivity extends AppCompatActivity
|
||||
mDataSource.open();
|
||||
|
||||
setContentView(R.layout.profile_import_view);
|
||||
WindowCompat.enableEdgeToEdge(getWindow());
|
||||
|
||||
mProgressBar = findViewById(R.id.progress_bar);
|
||||
mExistsWarning = findViewById(R.id.exists_warning);
|
||||
|
||||
+7
-2
@@ -48,6 +48,7 @@ import org.strongswan.android.data.VpnProfileSource;
|
||||
import org.strongswan.android.logic.StrongSwanApplication;
|
||||
import org.strongswan.android.ui.adapter.VpnProfileAdapter;
|
||||
import org.strongswan.android.utils.Constants;
|
||||
import org.strongswan.android.utils.Utils;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashSet;
|
||||
@@ -60,7 +61,6 @@ import java.util.UUID;
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.core.view.MenuProvider;
|
||||
import androidx.fragment.app.Fragment;
|
||||
import androidx.lifecycle.Lifecycle;
|
||||
import androidx.localbroadcastmanager.content.LocalBroadcastManager;
|
||||
|
||||
public class VpnProfileListFragment extends Fragment implements MenuProvider
|
||||
@@ -149,6 +149,8 @@ public class VpnProfileListFragment extends Fragment implements MenuProvider
|
||||
mListView.setEmptyView(view.findViewById(R.id.profile_list_empty));
|
||||
mListView.setOnItemClickListener(mVpnProfileClicked);
|
||||
|
||||
Utils.applyWindowInsetsAsPaddingForLists(mListView);
|
||||
|
||||
if (!mReadOnly)
|
||||
{
|
||||
requireActivity().addMenuProvider(this, getViewLifecycleOwner());
|
||||
@@ -197,7 +199,10 @@ public class VpnProfileListFragment extends Fragment implements MenuProvider
|
||||
public void onSaveInstanceState(Bundle outState)
|
||||
{
|
||||
super.onSaveInstanceState(outState);
|
||||
outState.putIntegerArrayList(SELECTED_KEY, new ArrayList<>(mSelected));
|
||||
if (!mReadOnly)
|
||||
{
|
||||
outState.putIntegerArrayList(SELECTED_KEY, new ArrayList<>(mSelected));
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
+4
@@ -22,11 +22,13 @@ import android.os.Bundle;
|
||||
import org.strongswan.android.R;
|
||||
import org.strongswan.android.data.VpnProfile;
|
||||
import org.strongswan.android.ui.VpnProfileListFragment.OnVpnProfileSelectedListener;
|
||||
import org.strongswan.android.utils.Utils;
|
||||
|
||||
import androidx.appcompat.app.AppCompatActivity;
|
||||
import androidx.core.content.pm.ShortcutInfoCompat;
|
||||
import androidx.core.content.pm.ShortcutManagerCompat;
|
||||
import androidx.core.graphics.drawable.IconCompat;
|
||||
import androidx.core.view.WindowCompat;
|
||||
|
||||
public class VpnProfileSelectActivity extends AppCompatActivity implements OnVpnProfileSelectedListener
|
||||
{
|
||||
@@ -35,6 +37,8 @@ public class VpnProfileSelectActivity extends AppCompatActivity implements OnVpn
|
||||
{
|
||||
super.onCreate(savedInstanceState);
|
||||
setContentView(R.layout.vpn_profile_select);
|
||||
WindowCompat.enableEdgeToEdge(getWindow());
|
||||
Utils.applyWindowInsetsAsMarginsForLists(findViewById(R.id.layout));
|
||||
|
||||
/* we should probably return a result also if the user clicks the back
|
||||
* button before selecting a profile */
|
||||
|
||||
+2
-1
@@ -86,7 +86,8 @@ public class VpnProfileAdapter extends ArrayAdapter<VpnProfile>
|
||||
tv = vpnProfileView.findViewById(R.id.profile_item_certificate);
|
||||
if (profile.getVpnType().has(VpnTypeFeature.CERTIFICATE))
|
||||
{
|
||||
tv.setText(getContext().getString(R.string.profile_user_certificate_label) + ": " + profile.getUserCertificateAlias());
|
||||
String alias = profile.getUserCertificateAlias();
|
||||
tv.setText(getContext().getString(R.string.profile_user_certificate_label) + ": " + (alias != null ? alias : ""));
|
||||
tv.setVisibility(View.VISIBLE);
|
||||
}
|
||||
else
|
||||
|
||||
@@ -17,9 +17,16 @@
|
||||
package org.strongswan.android.utils;
|
||||
|
||||
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
|
||||
import java.net.InetAddress;
|
||||
import java.net.UnknownHostException;
|
||||
|
||||
import androidx.core.graphics.Insets;
|
||||
import androidx.core.view.ViewCompat;
|
||||
import androidx.core.view.WindowInsetsCompat;
|
||||
|
||||
public class Utils
|
||||
{
|
||||
static final char[] HEXDIGITS = "0123456789abcdef".toCharArray();
|
||||
@@ -75,4 +82,39 @@ public class Utils
|
||||
}
|
||||
return InetAddress.getByAddress(bytes);
|
||||
}
|
||||
|
||||
/**
|
||||
* Apply window insets for the system UI as margins except for the bottom,
|
||||
* which is useful if the view ends with a list. WindowInsetsCompat.CONSUMED
|
||||
* is not returned so padding can be applied to the list.
|
||||
*
|
||||
* @param view view to apply margins to
|
||||
*/
|
||||
public static void applyWindowInsetsAsMarginsForLists(View view)
|
||||
{
|
||||
ViewCompat.setOnApplyWindowInsetsListener(view, (v, windowInsets) -> {
|
||||
Insets insets = windowInsets.getInsets(WindowInsetsCompat.Type.systemBars());
|
||||
ViewGroup.MarginLayoutParams mlp = (ViewGroup.MarginLayoutParams)v.getLayoutParams();
|
||||
mlp.topMargin = insets.top;
|
||||
mlp.leftMargin = insets.left;
|
||||
mlp.rightMargin = insets.right;
|
||||
v.setLayoutParams(mlp);
|
||||
return windowInsets;
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Apply bottom inset for the system UI as padding on the given (list) view
|
||||
* so the last item can be scrolled fully into view.
|
||||
*
|
||||
* @param view view to apply padding to
|
||||
*/
|
||||
public static void applyWindowInsetsAsPaddingForLists(View view)
|
||||
{
|
||||
ViewCompat.setOnApplyWindowInsetsListener(view, (v, windowInsets) -> {
|
||||
Insets insets = windowInsets.getInsets(WindowInsetsCompat.Type.systemBars());
|
||||
v.setPaddingRelative(0, 0, 0, insets.bottom);
|
||||
return WindowInsetsCompat.CONSUMED;
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,18 +1,11 @@
|
||||
# 2.6.0 #
|
||||
|
||||
- Erlaubt die Vorauswahl eines Benutzer-Zertifikats via Alias in verwalteten Profilen
|
||||
- Erlaubt die Auswahl von Benutzer-Zertifikaten in verwalteten Profilen, die kein eigenes Zertifikat installieren
|
||||
- Fixt das Lesen von Split-Tunneling Settings in verwalteten Profilen
|
||||
- Anpassungen für die randlose Anzeige, welche erzwungen wird, wenn Android 16 als Ziel-SDK verwendet wird
|
||||
- Ziel-SDK auf Android 16 erhöht
|
||||
|
||||
# 2.5.6 #
|
||||
|
||||
- Unterstützt benutzerdefinierte HTTP Proxy-Server (Android 10+)
|
||||
|
||||
# 2.5.5 #
|
||||
|
||||
- Fixt den Start von verwalteten Profilen als Always-on VPN
|
||||
|
||||
# 2.5.4 #
|
||||
|
||||
- Fixt Probleme beim Wiederherstellen der Verbindung
|
||||
|
||||
# 2.5.3 #
|
||||
|
||||
- Unterstützt die Verteilung von Passwörtern in verwalteten Profilen
|
||||
- Unterstützt den Import von Profil-Dateien mit Passwörtern
|
||||
- Fixt einen Crash beim Ändern des Passworts von verwalteten Profilen
|
||||
- Fixt einen Crash beim Importieren eines bereit existierenden Profils
|
||||
|
||||
@@ -1,18 +1,11 @@
|
||||
# 2.6.0 #
|
||||
|
||||
- Allow pre-selecting a user certificate via alias in managed profiles
|
||||
- Allow selecting a user certificate for managed profiles that don't install their own certificate
|
||||
- Fix reading split-tunneling settings in managed profiles
|
||||
- Adapt to edge-to-edge display, which becomes mandatory when targeting Android 16
|
||||
- Increase target SDK to Android 16
|
||||
|
||||
# 2.5.6 #
|
||||
|
||||
- Add support for custom HTTP proxy server (Android 10+)
|
||||
|
||||
# 2.5.5 #
|
||||
|
||||
- Fix initiating managed profiles as Always-on VPN
|
||||
|
||||
# 2.5.4 #
|
||||
|
||||
- Fix issues when reestablishing the connection
|
||||
|
||||
# 2.5.3 #
|
||||
|
||||
- Add support for distributing passwords in managed profiles
|
||||
- Add support for importing profile files with passwords
|
||||
- Fix crash when editing password of managed profiles
|
||||
- Fix crash when re-importing an already existing profile
|
||||
|
||||
@@ -18,7 +18,8 @@
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:orientation="horizontal"
|
||||
android:baselineAligned="false" >
|
||||
android:baselineAligned="false"
|
||||
android:fitsSystemWindows="true" >
|
||||
|
||||
<fragment
|
||||
class="org.strongswan.android.ui.RemediationInstructionsFragment"
|
||||
|
||||
@@ -16,7 +16,8 @@
|
||||
-->
|
||||
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent" >
|
||||
android:layout_height="match_parent"
|
||||
android:id="@+id/layout" >
|
||||
|
||||
<fragment
|
||||
class="org.strongswan.android.ui.LogFragment"
|
||||
|
||||
@@ -14,23 +14,24 @@
|
||||
or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
for more details.
|
||||
-->
|
||||
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:orientation="vertical" >
|
||||
android:paddingBottom="0dp"
|
||||
android:paddingTop="5dp"
|
||||
android:paddingStart="5dp"
|
||||
android:paddingEnd="5dp" >
|
||||
|
||||
<ListView
|
||||
android:id="@+id/log"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:layout_margin="10dp"
|
||||
android:dividerHeight="0dp"
|
||||
android:divider="@null"
|
||||
android:fadeScrollbars="false"
|
||||
android:scrollbarFadeDuration="0"
|
||||
android:scrollbarAlwaysDrawVerticalTrack="true"
|
||||
android:transcriptMode="normal">
|
||||
android:transcriptMode="normal"
|
||||
android:clipToPadding="false" />
|
||||
|
||||
</ListView>
|
||||
|
||||
</LinearLayout>
|
||||
</FrameLayout>
|
||||
|
||||
@@ -17,7 +17,8 @@
|
||||
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:orientation="vertical" >
|
||||
android:orientation="vertical"
|
||||
android:id="@+id/layout" >
|
||||
|
||||
<fragment
|
||||
class="org.strongswan.android.ui.VpnStateFragment"
|
||||
|
||||
@@ -20,7 +20,8 @@
|
||||
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||
xmlns:tools="http://schemas.android.com/tools"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent">
|
||||
android:layout_height="match_parent"
|
||||
android:fitsSystemWindows="true">
|
||||
|
||||
<TextView
|
||||
android:id="@+id/managed_profile"
|
||||
|
||||
@@ -15,9 +15,10 @@
|
||||
for more details.
|
||||
-->
|
||||
<ScrollView xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent" >
|
||||
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:fitsSystemWindows="true" >
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
|
||||
@@ -17,7 +17,7 @@
|
||||
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:paddingBottom="10dp"
|
||||
android:paddingBottom="0dp"
|
||||
android:paddingTop="10dp"
|
||||
android:paddingStart="5dp"
|
||||
android:paddingEnd="5dp" >
|
||||
@@ -28,9 +28,11 @@
|
||||
android:layout_height="match_parent"
|
||||
android:dividerHeight="1dp"
|
||||
android:divider="?android:attr/listDivider"
|
||||
android:scrollbarAlwaysDrawVerticalTrack="true" />
|
||||
android:overScrollFooter="@android:color/transparent"
|
||||
android:scrollbarAlwaysDrawVerticalTrack="true"
|
||||
android:clipToPadding="false" />
|
||||
|
||||
<TextView android:id="@+id/profile_list_empty"
|
||||
<TextView android:id="@+id/profile_list_empty"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:layout_marginStart="15dp"
|
||||
|
||||
@@ -17,6 +17,7 @@
|
||||
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:fitsSystemWindows="true"
|
||||
android:id="@+id/fragment_container">
|
||||
|
||||
</FrameLayout>
|
||||
</FrameLayout>
|
||||
|
||||
@@ -15,10 +15,11 @@
|
||||
for more details.
|
||||
-->
|
||||
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:orientation="vertical">
|
||||
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:orientation="vertical"
|
||||
android:fitsSystemWindows="true">
|
||||
|
||||
<com.google.android.material.tabs.TabLayout
|
||||
android:id="@+id/tabs"
|
||||
|
||||
@@ -18,7 +18,8 @@
|
||||
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:orientation="vertical" >
|
||||
android:orientation="vertical"
|
||||
android:id="@+id/layout" >
|
||||
|
||||
<fragment
|
||||
class="org.strongswan.android.ui.VpnProfileListFragment"
|
||||
@@ -28,4 +29,4 @@
|
||||
android:layout_weight="1"
|
||||
app:read_only="true" />
|
||||
|
||||
</LinearLayout>
|
||||
</LinearLayout>
|
||||
|
||||
@@ -74,11 +74,11 @@
|
||||
</LinearLayout>
|
||||
</LinearLayout>
|
||||
|
||||
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:background="@drawable/state_background"
|
||||
android:orientation="vertical" >
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:background="@drawable/state_background"
|
||||
android:orientation="vertical" >
|
||||
|
||||
<GridLayout
|
||||
android:layout_width="match_parent"
|
||||
|
||||
@@ -158,7 +158,7 @@
|
||||
<string name="alert_text_no_subnets">Bitte geben Sie mit Leerzeichen getrennte, gültige Subnetzte und/oder IP-Adressen ein</string>
|
||||
<string name="alert_text_no_ips">Bitte geben Sie mit Leerzeichen getrennte, gültige IP-Adressen ein</string>
|
||||
<string name="alert_text_no_proposal">Bitte geben Sie eine mit Bindestrichen getrennte, gültige Liste von Algorithmen ein</string>
|
||||
<string name="alert_text_vpn_profile_read_only">Dieses Profil wird von Ihrem Administrator verwaltet und kann nicht bearbeitet werden. Nur das Passwort kann geändert werden</string>
|
||||
<string name="alert_text_vpn_profile_read_only">Dieses Profil wird von Ihrem Administrator verwaltet und kann nicht bearbeitet werden. Nur das Passwort bzw. Benutzer-Zertifikat kann geändert werden</string>
|
||||
<string name="tnc_notice_title">EAP-TNC kann Ihre Privatsphäre beeinträchtigen</string>
|
||||
<string name="tnc_notice_subtitle">Gerätedaten werden an den Server-Betreiber gesendet</string>
|
||||
<string name="tnc_notice_details"><![CDATA[<p>Trusted Network Connect (TNC) erlaubt Server-Betreibern den Gesundheitszustand von Endgeräten zu prüfen.</p><p>Dazu kann der Betreiber Daten verlangen, wie etwa eine eindeutige Identifikationsnummer, eine Liste der installierten Pakete, Systemeinstellungen oder kryptografische Prüfsummen von Dateien.</p><b>Solche Daten werden nur übermittelt nachdem die Identität des Servers geprüft wurde.</b>]]></string>
|
||||
@@ -234,6 +234,8 @@
|
||||
<string name="cancel_retry">Wiederholen abbrechen</string>
|
||||
<string name="power_whitelist_title">Akku-Optimierung deaktivieren</string>
|
||||
<string name="power_whitelist_text">Bitte den nächsten Dialog bestätigen, um die App auf die weisse Liste für Akku-Optimierung zu setzen, so dass sie NAT keepalives und Rekeyings zeitlich korrekt planen kann, um konstant erreichbar zu bleiben während die VPN-Verbindung besteht.</string>
|
||||
<string name="certificate_required_title">Benutzer-Zertifikat benötigt</string>
|
||||
<string name="certificate_required_text">Bitte bearbeiten Sie das VPN Profil, um eines auszuwählen.</string>
|
||||
|
||||
<!-- Quick Settings tile -->
|
||||
<string name="tile_default">VPN umschalten</string>
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!--
|
||||
Copyright (C) 2025 Tobias Brunner
|
||||
Copyright (C) 2023 Relution GmbH
|
||||
|
||||
Copyright (C) secunet Security Networks AG
|
||||
@@ -93,6 +94,8 @@
|
||||
<string name="managed_config_local_p12_description">Base64-encoded PKCS#12-container with the client certificate and private key and optional certificate chain (the latter might cause warnings on older Android releases, see Android VPN client configuration for details). Not necessary for username/password-based EAP authentication or if the user already has the certificate/key installed as it may be selected while importing the profile</string>
|
||||
<string name="managed_config_local_p12_password_title">User certificate password (Optional)</string>
|
||||
<string name="managed_config_local_p12_password_description">Password required to extract the private key of the PKCS#12-container for installation</string>
|
||||
<string name="managed_config_local_user_certificate_alias_title">User certificate alias (Optional)</string>
|
||||
<string name="managed_config_local_user_certificate_alias_description">Alias of a user certificate/key already installed on the device. The app must be granted access to it by the MDM. Only used if no certificate is distributed with the config. If a certificate is required and this is not set, the user may select a local certificate manually</string>
|
||||
<string name="managed_config_local_rsa_pss_title">@string/profile_rsa_pss_label</string>
|
||||
<string name="managed_config_local_rsa_pss_description">@string/profile_rsa_pss_hint</string>
|
||||
|
||||
|
||||
@@ -160,7 +160,7 @@
|
||||
<string name="alert_text_no_subnets">Please enter valid subnets and/or IP addresses, separated by spaces</string>
|
||||
<string name="alert_text_no_ips">Please enter valid IP addresses, separated by spaces</string>
|
||||
<string name="alert_text_no_proposal">Please enter a valid list of algorithms, separated by hyphens</string>
|
||||
<string name="alert_text_vpn_profile_read_only">This VPN profile is managed by your administrator and can\'t be modified. You can only change the password</string>
|
||||
<string name="alert_text_vpn_profile_read_only">This VPN profile is managed by your administrator and can\'t be modified. You can only change the password or user certificate</string>
|
||||
<string name="tnc_notice_title">EAP-TNC may affect your privacy</string>
|
||||
<string name="tnc_notice_subtitle">Device data is sent to the server operator</string>
|
||||
<string name="tnc_notice_details"><![CDATA[<p>Trusted Network Connect (TNC) allows server operators to assess the health of a client device.</p><p>For that purpose the server operator may request data such as a unique identifier, a list of installed packages, system settings, or cryptographic checksums of files.</p><b>Any data will be sent only after verifying the server\'s identity.</b>]]></string>
|
||||
@@ -236,6 +236,8 @@
|
||||
<string name="cancel_retry">Cancel retry</string>
|
||||
<string name="power_whitelist_title">Disable battery optimizations</string>
|
||||
<string name="power_whitelist_text">Please confirm the next dialog to add the app to the device\'s power whitelist so it can ignore battery optimizations and schedule NAT keep-alives and rekeyings accurately in order to constantly keep reachable while the VPN is established.</string>
|
||||
<string name="certificate_required_title">User certificate required</string>
|
||||
<string name="certificate_required_text">Please edit the VPN profile to select one.</string>
|
||||
|
||||
<!-- Quick Settings tile -->
|
||||
<string name="tile_default">Toggle VPN</string>
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!--
|
||||
Copyright (C) 2025 Tobias Brunner
|
||||
Copyright (C) 2023 Relution GmbH
|
||||
|
||||
Copyright (C) secunet Security Networks AG
|
||||
@@ -93,6 +94,8 @@
|
||||
<string name="managed_config_local_p12_description">Base64-encoded PKCS#12-container with the client certificate and private key and optional certificate chain (the latter might cause warnings on older Android releases, see Android VPN client configuration for details). Not necessary for username/password-based EAP authentication or if the user already has the certificate/key installed as it may be selected while importing the profile</string>
|
||||
<string name="managed_config_local_p12_password_title">User certificate password (Optional)</string>
|
||||
<string name="managed_config_local_p12_password_description">Password required to extract the private key of the PKCS#12-container for installation</string>
|
||||
<string name="managed_config_local_user_certificate_alias_title">User certificate alias (Optional)</string>
|
||||
<string name="managed_config_local_user_certificate_alias_description">Alias of a user certificate/key already installed on the device. The app must be granted access to it by the MDM. Only used if no certificate is distributed with the config. If a certificate is required and this is not set, the user may select a local certificate manually</string>
|
||||
<string name="managed_config_local_rsa_pss_title">@string/profile_rsa_pss_label</string>
|
||||
<string name="managed_config_local_rsa_pss_description">@string/profile_rsa_pss_hint</string>
|
||||
|
||||
|
||||
@@ -154,7 +154,7 @@
|
||||
<string name="alert_text_no_subnets">Please enter valid subnets and/or IP addresses, separated by spaces</string>
|
||||
<string name="alert_text_no_ips">Please enter valid IP addresses, separated by spaces</string>
|
||||
<string name="alert_text_no_proposal">Please enter a valid list of algorithms, separated by hyphens</string>
|
||||
<string name="alert_text_vpn_profile_read_only">This VPN profile is managed by your administrator and can\'t be modified. You can only change the password</string>
|
||||
<string name="alert_text_vpn_profile_read_only">This VPN profile is managed by your administrator and can\'t be modified. You can only change the password or user certificate</string>
|
||||
<string name="tnc_notice_title">EAP-TNC may affect your privacy</string>
|
||||
<string name="tnc_notice_subtitle">Device data is sent to the server operator</string>
|
||||
<string name="tnc_notice_details"><![CDATA[<p>Trusted Network Connect (TNC) allows server operators to assess the health of a client device.</p><p>For that purpose the server operator may request data such as a unique identifier, a list of installed packages, system settings, or cryptographic checksums of files.</p><b>Any data will be sent only after verifying the server\'s identity.</b>]]></string>
|
||||
@@ -230,6 +230,8 @@
|
||||
<string name="cancel_retry">Cancel retry</string>
|
||||
<string name="power_whitelist_title">Disable battery optimizations</string>
|
||||
<string name="power_whitelist_text">Please confirm the next dialog to add the app to the device\'s power whitelist so it can ignore battery optimizations and schedule NAT keep-alives and rekeyings accurately in order to constantly keep reachable while the VPN is established.</string>
|
||||
<string name="certificate_required_title">User certificate required</string>
|
||||
<string name="certificate_required_text">Please edit the VPN profile to select one.</string>
|
||||
|
||||
<!-- Quick Settings tile -->
|
||||
<string name="tile_default">Toggle VPN</string>
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!--
|
||||
Copyright (C) 2025 Tobias Brunner
|
||||
Copyright (C) 2023 Relution GmbH
|
||||
|
||||
Copyright (C) secunet Security Networks AG
|
||||
@@ -93,6 +94,8 @@
|
||||
<string name="managed_config_local_p12_description">Base64-encoded PKCS#12-container with the client certificate and private key and optional certificate chain (the latter might cause warnings on older Android releases, see Android VPN client configuration for details). Not necessary for username/password-based EAP authentication or if the user already has the certificate/key installed as it may be selected while importing the profile</string>
|
||||
<string name="managed_config_local_p12_password_title">User certificate password (Optional)</string>
|
||||
<string name="managed_config_local_p12_password_description">Password required to extract the private key of the PKCS#12-container for installation</string>
|
||||
<string name="managed_config_local_user_certificate_alias_title">User certificate alias (Optional)</string>
|
||||
<string name="managed_config_local_user_certificate_alias_description">Alias of a user certificate/key already installed on the device. The app must be granted access to it by the MDM. Only used if no certificate is distributed with the config. If a certificate is required and this is not set, the user may select a local certificate manually</string>
|
||||
<string name="managed_config_local_rsa_pss_title">@string/profile_rsa_pss_label</string>
|
||||
<string name="managed_config_local_rsa_pss_description">@string/profile_rsa_pss_hint</string>
|
||||
|
||||
|
||||
@@ -155,7 +155,7 @@
|
||||
<string name="alert_text_no_subnets">Please enter valid subnets and/or IP addresses, separated by spaces</string>
|
||||
<string name="alert_text_no_ips">Please enter valid IP addresses, separated by spaces</string>
|
||||
<string name="alert_text_no_proposal">Please enter a valid list of algorithms, separated by hyphens</string>
|
||||
<string name="alert_text_vpn_profile_read_only">This VPN profile is managed by your administrator and can\'t be modified. You can only change the password</string>
|
||||
<string name="alert_text_vpn_profile_read_only">This VPN profile is managed by your administrator and can\'t be modified. You can only change the password or user certificate</string>
|
||||
<string name="tnc_notice_title">EAP-TNC may affect your privacy</string>
|
||||
<string name="tnc_notice_subtitle">Device data is sent to the server operator</string>
|
||||
<string name="tnc_notice_details"><![CDATA[<p>Trusted Network Connect (TNC) allows server operators to assess the health of a client device.</p><p>For that purpose the server operator may request data such as a unique identifier, a list of installed packages, system settings, or cryptographic checksums of files.</p><b>Any data will be sent only after verifying the server\'s identity.</b>]]></string>
|
||||
@@ -231,6 +231,8 @@
|
||||
<string name="cancel_retry">Cancel retry</string>
|
||||
<string name="power_whitelist_title">Disable battery optimizations</string>
|
||||
<string name="power_whitelist_text">Please confirm the next dialog to add the app to the device\'s power whitelist so it can ignore battery optimizations and schedule NAT keep-alives and rekeyings accurately in order to constantly keep reachable while the VPN is established.</string>
|
||||
<string name="certificate_required_title">User certificate required</string>
|
||||
<string name="certificate_required_text">Please edit the VPN profile to select one.</string>
|
||||
|
||||
<!-- Quick Settings tile -->
|
||||
<string name="tile_default">Toggle VPN</string>
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!--
|
||||
Copyright (C) 2025 Tobias Brunner
|
||||
Copyright (C) 2023 Relution GmbH
|
||||
|
||||
Copyright (C) secunet Security Networks AG
|
||||
@@ -93,6 +94,8 @@
|
||||
<string name="managed_config_local_p12_description">Base64-encoded PKCS#12-container with the client certificate and private key and optional certificate chain (the latter might cause warnings on older Android releases, see Android VPN client configuration for details). Not necessary for username/password-based EAP authentication or if the user already has the certificate/key installed as it may be selected while importing the profile</string>
|
||||
<string name="managed_config_local_p12_password_title">User certificate password (Optional)</string>
|
||||
<string name="managed_config_local_p12_password_description">Password required to extract the private key of the PKCS#12-container for installation</string>
|
||||
<string name="managed_config_local_user_certificate_alias_title">User certificate alias (Optional)</string>
|
||||
<string name="managed_config_local_user_certificate_alias_description">Alias of a user certificate/key already installed on the device. The app must be granted access to it by the MDM. Only used if no certificate is distributed with the config. If a certificate is required and this is not set, the user may select a local certificate manually</string>
|
||||
<string name="managed_config_local_rsa_pss_title">@string/profile_rsa_pss_label</string>
|
||||
<string name="managed_config_local_rsa_pss_description">@string/profile_rsa_pss_hint</string>
|
||||
|
||||
|
||||
@@ -1,28 +0,0 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!--
|
||||
Copyright (C) 2016 Tobias Brunner
|
||||
|
||||
Copyright (C) secunet Security Networks AG
|
||||
|
||||
This program is free software; you can redistribute it and/or modify it
|
||||
under the terms of the GNU General Public License as published by the
|
||||
Free Software Foundation; either version 2 of the License, or (at your
|
||||
option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
|
||||
|
||||
This program is distributed in the hope that it will be useful, but
|
||||
WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||
or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
for more details.
|
||||
-->
|
||||
<resources>
|
||||
|
||||
<style name="ApplicationTheme" parent="ApplicationTheme.Base">
|
||||
<item name="android:activatedBackgroundIndicator">@drawable/activated_background</item>
|
||||
<item name="android:selectableItemBackground">@drawable/activated_background</item>
|
||||
</style>
|
||||
|
||||
<style name="AlertDialogTheme" parent="AlertDialogTheme.Base">
|
||||
<item name="android:windowBackground">@android:color/transparent</item>
|
||||
</style>
|
||||
|
||||
</resources>
|
||||
@@ -1,25 +0,0 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!--
|
||||
Copyright (C) 2016 Tobias Brunner
|
||||
|
||||
Copyright (C) secunet Security Networks AG
|
||||
|
||||
This program is free software; you can redistribute it and/or modify it
|
||||
under the terms of the GNU General Public License as published by the
|
||||
Free Software Foundation; either version 2 of the License, or (at your
|
||||
option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
|
||||
|
||||
This program is distributed in the hope that it will be useful, but
|
||||
WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||
or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
for more details.
|
||||
-->
|
||||
<resources>
|
||||
|
||||
<style name="ApplicationTheme" parent="ApplicationTheme.Base">
|
||||
</style>
|
||||
|
||||
<style name="AlertDialogTheme" parent="AlertDialogTheme.Base">
|
||||
</style>
|
||||
|
||||
</resources>
|
||||
@@ -154,7 +154,7 @@
|
||||
<string name="alert_text_no_subnets">请输入有效的子网和/或IP地址,用空格分隔</string>
|
||||
<string name="alert_text_no_ips">请输入有效的IP地址,以空格分隔</string>
|
||||
<string name="alert_text_no_proposal">请输入用连字符分隔的有效算法列表</string>
|
||||
<string name="alert_text_vpn_profile_read_only">This VPN profile is managed by your administrator and can\'t be modified. You can only change the password</string>
|
||||
<string name="alert_text_vpn_profile_read_only">This VPN profile is managed by your administrator and can\'t be modified. You can only change the password or user certificate</string>
|
||||
<string name="tnc_notice_title">EAP-TNC可能会影响您的隐私</string>
|
||||
<string name="tnc_notice_subtitle">设备数据已被发送至服务器管理员</string>
|
||||
<string name="tnc_notice_details"><![CDATA[<p>可信网络连接t (TNC) 允许服务器管理员评定一个用户设备的状况。</p><p>出于此目的,服务器管理员可能要求以下数据如独立ID、已安装软件列表、系统设置、或加密过的文件校验值。</p><b>任何数据都仅将在验证过服务器的身份ID之后被发出。</b>]]></string>
|
||||
@@ -230,6 +230,8 @@
|
||||
<string name="cancel_retry">取消重试</string>
|
||||
<string name="power_whitelist_title">禁用电池优化</string>
|
||||
<string name="power_whitelist_text">请确认下一个对话框,将应用程序添加到设备的电源白名单中,这样它就可以忽略电池优化,并准确地安排NAT保持有效和重新键入,以便在建立VPN时始终保持可访问性。</string>
|
||||
<string name="certificate_required_title">User certificate required</string>
|
||||
<string name="certificate_required_text">Please edit the VPN profile to select one.</string>
|
||||
|
||||
<!-- Quick Settings tile -->
|
||||
<string name="tile_default">切换VPN</string>
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!--
|
||||
Copyright (C) 2025 Tobias Brunner
|
||||
Copyright (C) 2023 Relution GmbH
|
||||
|
||||
Copyright (C) secunet Security Networks AG
|
||||
@@ -93,6 +94,8 @@
|
||||
<string name="managed_config_local_p12_description">Base64-encoded PKCS#12-container with the client certificate and private key and optional certificate chain (the latter might cause warnings on older Android releases, see Android VPN client configuration for details). Not necessary for username/password-based EAP authentication or if the user already has the certificate/key installed as it may be selected while importing the profile</string>
|
||||
<string name="managed_config_local_p12_password_title">User certificate password (Optional)</string>
|
||||
<string name="managed_config_local_p12_password_description">Password required to extract the private key of the PKCS#12-container for installation</string>
|
||||
<string name="managed_config_local_user_certificate_alias_title">User certificate alias (Optional)</string>
|
||||
<string name="managed_config_local_user_certificate_alias_description">Alias of a user certificate/key already installed on the device. The app must be granted access to it by the MDM. Only used if no certificate is distributed with the config. If a certificate is required and this is not set, the user may select a local certificate manually</string>
|
||||
<string name="managed_config_local_rsa_pss_title">@string/profile_rsa_pss_label</string>
|
||||
<string name="managed_config_local_rsa_pss_description">@string/profile_rsa_pss_hint</string>
|
||||
|
||||
|
||||
@@ -154,7 +154,7 @@
|
||||
<string name="alert_text_no_subnets">Please enter valid subnets and/or IP addresses, separated by spaces</string>
|
||||
<string name="alert_text_no_ips">Please enter valid IP addresses, separated by spaces</string>
|
||||
<string name="alert_text_no_proposal">Please enter a valid list of algorithms, separated by hyphens</string>
|
||||
<string name="alert_text_vpn_profile_read_only">This VPN profile is managed by your administrator and can\'t be modified. You can only change the password</string>
|
||||
<string name="alert_text_vpn_profile_read_only">This VPN profile is managed by your administrator and can\'t be modified. You can only change the password or user certificate</string>
|
||||
<string name="tnc_notice_title">EAP-TNC可能會影響您的隱私安全</string>
|
||||
<string name="tnc_notice_subtitle">裝置資料已經發送給伺服器管理者</string>
|
||||
<string name="tnc_notice_details"><![CDATA[<p>Trusted Network Connect (TNC) 可以讓伺服器管理者評估用戶裝置的狀況。</p><p>在這個目的下,伺服器管理者可能會要求以下資料,例如ID、已安裝的App項目、系統設定、或加密檔案驗證值。</p><b>任何資料都只有在驗證伺服器的身分ID之後才會被送出。</b>]]></string>
|
||||
@@ -230,6 +230,8 @@
|
||||
<string name="cancel_retry">Cancel retry</string>
|
||||
<string name="power_whitelist_title">Disable battery optimizations</string>
|
||||
<string name="power_whitelist_text">Please confirm the next dialog to add the app to the device\'s power whitelist so it can ignore battery optimizations and schedule NAT keep-alives and rekeyings accurately in order to constantly keep reachable while the VPN is established.</string>
|
||||
<string name="certificate_required_title">User certificate required</string>
|
||||
<string name="certificate_required_text">Please edit the VPN profile to select one.</string>
|
||||
|
||||
<!-- Quick Settings tile -->
|
||||
<string name="tile_default">Toggle VPN</string>
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!--
|
||||
Copyright (C) 2025 Tobias Brunner
|
||||
Copyright (C) 2023 Relution GmbH
|
||||
|
||||
Copyright (C) secunet Security Networks AG
|
||||
@@ -93,6 +94,8 @@
|
||||
<string name="managed_config_local_p12_description">Base64-encoded PKCS#12-container with the client certificate and private key and optional certificate chain (the latter might cause warnings on older Android releases, see Android VPN client configuration for details). Not necessary for username/password-based EAP authentication or if the user already has the certificate/key installed as it may be selected while importing the profile</string>
|
||||
<string name="managed_config_local_p12_password_title">User certificate password (Optional)</string>
|
||||
<string name="managed_config_local_p12_password_description">Password required to extract the private key of the PKCS#12-container for installation</string>
|
||||
<string name="managed_config_local_user_certificate_alias_title">User certificate alias (Optional)</string>
|
||||
<string name="managed_config_local_user_certificate_alias_description">Alias of a user certificate/key already installed on the device. The app must be granted access to it by the MDM. Only used if no certificate is distributed with the config. If a certificate is required and this is not set, the user may select a local certificate manually</string>
|
||||
<string name="managed_config_local_rsa_pss_title">@string/profile_rsa_pss_label</string>
|
||||
<string name="managed_config_local_rsa_pss_description">@string/profile_rsa_pss_hint</string>
|
||||
|
||||
|
||||
@@ -158,7 +158,7 @@
|
||||
<string name="alert_text_no_subnets">Please enter valid subnets and/or IP addresses, separated by spaces</string>
|
||||
<string name="alert_text_no_ips">Please enter valid IP addresses, separated by spaces</string>
|
||||
<string name="alert_text_no_proposal">Please enter a valid list of algorithms, separated by hyphens</string>
|
||||
<string name="alert_text_vpn_profile_read_only">This VPN profile is managed by your administrator and can\'t be modified. You can only change the password</string>
|
||||
<string name="alert_text_vpn_profile_read_only">This VPN profile is managed by your administrator and can\'t be modified. You can only change the password or user certificate</string>
|
||||
<string name="tnc_notice_title">EAP-TNC may affect your privacy</string>
|
||||
<string name="tnc_notice_subtitle">Device data is sent to the server operator</string>
|
||||
<string name="tnc_notice_details"><![CDATA[<p>Trusted Network Connect (TNC) allows server operators to assess the health of a client device.</p><p>For that purpose the server operator may request data such as a unique identifier, a list of installed packages, system settings, or cryptographic checksums of files.</p><b>Any data will be sent only after verifying the server\'s identity.</b>]]></string>
|
||||
@@ -234,6 +234,8 @@
|
||||
<string name="cancel_retry">Cancel retry</string>
|
||||
<string name="power_whitelist_title">Disable battery optimizations</string>
|
||||
<string name="power_whitelist_text">Please confirm the next dialog to add the app to the device\'s power whitelist so it can ignore battery optimizations and schedule NAT keep-alives and rekeyings accurately in order to constantly keep reachable while the VPN is established.</string>
|
||||
<string name="certificate_required_title">User certificate required</string>
|
||||
<string name="certificate_required_text">Please edit the VPN profile to select one.</string>
|
||||
|
||||
<!-- Quick Settings tile -->
|
||||
<string name="tile_default">Toggle VPN</string>
|
||||
|
||||
@@ -94,6 +94,8 @@
|
||||
<string name="managed_config_local_p12_description">Base64-encoded PKCS#12-container with the client certificate and private key and optional certificate chain (the latter might cause warnings on older Android releases, see Android VPN client configuration for details). Not necessary for username/password-based EAP authentication or if the user already has the certificate/key installed as it may be selected while importing the profile</string>
|
||||
<string name="managed_config_local_p12_password_title">User certificate password (Optional)</string>
|
||||
<string name="managed_config_local_p12_password_description">Password required to extract the private key of the PKCS#12-container for installation</string>
|
||||
<string name="managed_config_local_user_certificate_alias_title">User certificate alias (Optional)</string>
|
||||
<string name="managed_config_local_user_certificate_alias_description">Alias of a user certificate/key already installed on the device. The app must be granted access to it by the MDM. Only used if no certificate is distributed with the config. If a certificate is required and this is not set, the user may select a local certificate manually</string>
|
||||
<string name="managed_config_local_rsa_pss_title">@string/profile_rsa_pss_label</string>
|
||||
<string name="managed_config_local_rsa_pss_description">@string/profile_rsa_pss_hint</string>
|
||||
|
||||
|
||||
@@ -16,7 +16,7 @@
|
||||
-->
|
||||
<resources xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
|
||||
<style name="ApplicationTheme.Base" parent="Theme.AppCompat">
|
||||
<style name="ApplicationTheme" parent="Theme.AppCompat">
|
||||
<item name="colorAccent">@color/accent</item>
|
||||
<item name="colorPrimary">@color/primary</item>
|
||||
<item name="colorPrimaryDark">@color/primary_dark</item>
|
||||
@@ -24,7 +24,7 @@
|
||||
<item name="preferenceTheme">@style/PreferenceThemeOverlay</item>
|
||||
</style>
|
||||
|
||||
<style name="AlertDialogTheme.Base" parent="Theme.AppCompat.Dialog.Alert">
|
||||
<style name="AlertDialogTheme" parent="Theme.AppCompat.Dialog.Alert">
|
||||
<item name="colorAccent">@color/accent</item>
|
||||
</style>
|
||||
|
||||
|
||||
@@ -205,6 +205,13 @@
|
||||
android:restrictionType="string"
|
||||
android:title="@string/managed_config_local_p12_password_title" />
|
||||
|
||||
<restriction
|
||||
android:defaultValue=""
|
||||
android:description="@string/managed_config_local_user_certificate_alias_description"
|
||||
android:key="user_certificate_alias"
|
||||
android:restrictionType="string"
|
||||
android:title="@string/managed_config_local_user_certificate_alias_title" />
|
||||
|
||||
<restriction
|
||||
android:defaultValue="false"
|
||||
android:description="@string/managed_config_local_rsa_pss_description"
|
||||
@@ -272,7 +279,7 @@
|
||||
|
||||
<restriction
|
||||
android:description="@string/managed_config_split_tunneling_bundle_description"
|
||||
android:key="split_tunnelling"
|
||||
android:key="split_tunneling"
|
||||
android:restrictionType="bundle"
|
||||
android:title="@string/managed_config_split_tunneling_bundle_title">
|
||||
|
||||
@@ -324,7 +331,7 @@
|
||||
android:description="@string/managed_config_proxy_port_description"
|
||||
android:key="proxy_port"
|
||||
android:restrictionType="integer"
|
||||
android:title="@string/managed_config_proxy_port_description" />
|
||||
android:title="@string/managed_config_proxy_port_title" />
|
||||
|
||||
<restriction
|
||||
android:defaultValue=""
|
||||
|
||||
@@ -4,7 +4,7 @@ buildscript {
|
||||
google()
|
||||
}
|
||||
dependencies {
|
||||
classpath 'com.android.tools.build:gradle:8.5.1'
|
||||
classpath 'com.android.tools.build:gradle:8.13.0'
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -3,4 +3,4 @@ distributionBase=GRADLE_USER_HOME
|
||||
distributionPath=wrapper/dists
|
||||
zipStoreBase=GRADLE_USER_HOME
|
||||
zipStorePath=wrapper/dists
|
||||
distributionUrl=https\://services.gradle.org/distributions/gradle-8.7-all.zip
|
||||
distributionUrl=https\://services.gradle.org/distributions/gradle-8.13-all.zip
|
||||
|
||||
Reference in New Issue
Block a user