dependencies {
implementation 'com.android.support:appcompat-v7:26.0.2'
implementation 'com.android.support:design:26.0.2'
+ implementation 'com.android.support:preference-v7:26.0.2'
implementation 'com.android.support:support-v4:26.0.2'
testImplementation 'junit:junit:4.12'
}
<?xml version="1.0" encoding="utf-8"?>
<!--
- Copyright (C) 2012-2015 Tobias Brunner
+ Copyright (C) 2012-2018 Tobias Brunner
Copyright (C) 2012 Giuliano Grassi
Copyright (C) 2012 Ralf Sager
HSR Hochschule fuer Technik Rapperswil
<activity
android:name=".ui.LogActivity"
android:label="@string/log_title" >
+ </activity>
+ <activity
+ android:name=".ui.SettingsActivity"
+ android:label="@string/pref_title">
</activity>
<activity
android:name=".ui.RemediationInstructionsActivity"
return profile;
}
+ /**
+ * Get a single VPN profile from the database by its UUID as String.
+ * @param uuid the UUID of the VPN profile as String
+ * @return the profile or null, if not found
+ */
+ public VpnProfile getVpnProfile(String uuid)
+ {
+ try
+ {
+ if (uuid != null)
+ {
+ return getVpnProfile(UUID.fromString(uuid));
+ }
+ return null;
+ }
+ catch (IllegalArgumentException e)
+ {
+ e.printStackTrace();
+ return null;
+ }
+ }
+
/**
* Get a list of all VPN profiles stored in the database.
* @return list of VPN profiles
Intent logIntent = new Intent(this, LogActivity.class);
startActivity(logIntent);
return true;
+ case R.id.menu_settings:
+ Intent settingsIntent = new Intent(this, SettingsActivity.class);
+ startActivity(settingsIntent);
+ return true;
default:
return super.onOptionsItemSelected(item);
}
--- /dev/null
+/*
+ * Copyright (C) 2018 Tobias Brunner
+ * HSR Hochschule fuer Technik Rapperswil
+ *
+ * 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.
+ */
+
+package org.strongswan.android.ui;
+
+import android.os.Bundle;
+import android.support.v7.app.AppCompatActivity;
+import android.view.MenuItem;
+
+public class SettingsActivity extends AppCompatActivity
+{
+
+ @Override
+ protected void onCreate(Bundle savedInstanceState)
+ {
+ super.onCreate(savedInstanceState);
+
+ getSupportActionBar().setDisplayHomeAsUpEnabled(true);
+
+ getSupportFragmentManager().beginTransaction()
+ .replace(android.R.id.content, new SettingsFragment())
+ .commit();
+ }
+
+ @Override
+ public boolean onOptionsItemSelected(MenuItem item)
+ {
+ switch (item.getItemId())
+ {
+ case android.R.id.home:
+ finish();
+ return true;
+ default:
+ return super.onOptionsItemSelected(item);
+ }
+ }
+}
--- /dev/null
+/*
+ * Copyright (C) 2018 Tobias Brunner
+ * HSR Hochschule fuer Technik Rapperswil
+ *
+ * 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.
+ */
+
+package org.strongswan.android.ui;
+
+import android.content.SharedPreferences;
+import android.os.Build;
+import android.os.Bundle;
+import android.support.v7.preference.ListPreference;
+import android.support.v7.preference.Preference;
+import android.support.v7.preference.PreferenceFragmentCompat;
+import android.support.v7.preference.PreferenceManager;
+
+import org.strongswan.android.R;
+import org.strongswan.android.data.VpnProfile;
+import org.strongswan.android.data.VpnProfileDataSource;
+
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.Comparator;
+import java.util.List;
+
+import static org.strongswan.android.utils.Constants.PREF_DEFAULT_VPN_PROFILE;
+import static org.strongswan.android.utils.Constants.PREF_DEFAULT_VPN_PROFILE_MRU;
+
+public class SettingsFragment extends PreferenceFragmentCompat implements Preference.OnPreferenceChangeListener
+{
+ private ListPreference mDefaultVPNProfile;
+
+ @Override
+ public void onCreatePreferences(Bundle bundle, String s)
+ {
+ setPreferencesFromResource(R.xml.settings, s);
+
+ mDefaultVPNProfile = (ListPreference)findPreference(PREF_DEFAULT_VPN_PROFILE);
+ mDefaultVPNProfile.setOnPreferenceChangeListener(this);
+ if (Build.VERSION.SDK_INT < Build.VERSION_CODES.N)
+ {
+ mDefaultVPNProfile.setEnabled(false);
+ }
+ }
+
+ @Override
+ public void onResume()
+ {
+ super.onResume();
+
+ VpnProfileDataSource profiles = new VpnProfileDataSource(getActivity());
+ profiles.open();
+
+ List<VpnProfile> all = profiles.getAllVpnProfiles();
+ Collections.sort(all, new Comparator<VpnProfile>() {
+ @Override
+ public int compare(VpnProfile lhs, VpnProfile rhs)
+ {
+ return lhs.getName().compareToIgnoreCase(rhs.getName());
+ }
+ });
+
+ ArrayList<CharSequence> entries = new ArrayList<>();
+ ArrayList<CharSequence> entryvalues = new ArrayList<>();
+
+ entries.add(getString(R.string.pref_default_vpn_profile_mru));
+ entryvalues.add(PREF_DEFAULT_VPN_PROFILE_MRU);
+
+ for (VpnProfile profile : all)
+ {
+ entries.add(profile.getName());
+ entryvalues.add(profile.getUUID().toString());
+ }
+ profiles.close();
+
+ if (entries.size() <= 1)
+ {
+ mDefaultVPNProfile.setEnabled(false);
+ }
+ else
+ {
+ mDefaultVPNProfile.setEnabled(true);
+ mDefaultVPNProfile.setEntries(entries.toArray(new CharSequence[0]));
+ mDefaultVPNProfile.setEntryValues(entryvalues.toArray(new CharSequence[0]));
+ }
+
+ SharedPreferences pref = PreferenceManager.getDefaultSharedPreferences(getActivity());
+ setCurrentProfileName(pref.getString(PREF_DEFAULT_VPN_PROFILE, PREF_DEFAULT_VPN_PROFILE_MRU));
+ }
+
+ @Override
+ public boolean onPreferenceChange(Preference preference, Object newValue)
+ {
+ if (preference == mDefaultVPNProfile)
+ {
+ setCurrentProfileName((String)newValue);
+ }
+ return true;
+ }
+
+ private void setCurrentProfileName(String uuid)
+ {
+ VpnProfileDataSource profiles = new VpnProfileDataSource(getActivity());
+ profiles.open();
+
+ if (!uuid.equals(PREF_DEFAULT_VPN_PROFILE_MRU))
+ {
+ VpnProfile current = profiles.getVpnProfile(uuid);
+ if (current != null)
+ {
+ mDefaultVPNProfile.setSummary(current.getName());
+ }
+ else
+ {
+ mDefaultVPNProfile.setSummary(R.string.profile_not_found);
+ }
+ }
+ else
+ {
+ mDefaultVPNProfile.setSummary(R.string.pref_default_vpn_profile_mru);
+ }
+ profiles.close();
+ }
+}
import org.strongswan.android.logic.VpnStateService;
import org.strongswan.android.logic.VpnStateService.State;
-import java.util.UUID;
-
public class VpnProfileControlActivity extends AppCompatActivity
{
public static final String START_PROFILE = "org.strongswan.android.action.START_PROFILE";
String profileUUID = intent.getStringExtra(EXTRA_VPN_PROFILE_ID);
if (profileUUID != null)
{
- try
- {
- profile = dataSource.getVpnProfile(UUID.fromString(profileUUID));
- }
- catch (Exception e)
- { /* invalid UUID */
- e.printStackTrace();
- }
+ profile = dataSource.getVpnProfile(profileUUID);
}
else
{
/*
- * Copyright (C) 2016 Tobias Brunner
+ * Copyright (C) 2016-2018 Tobias Brunner
* HSR Hochschule fuer Technik Rapperswil
*
* This program is free software; you can redistribute it and/or modify it
*/
public static final int NAT_KEEPALIVE_MAX = 120;
public static final int NAT_KEEPALIVE_MIN = 10;
+
+ /**
+ * Preference key for default VPN profile
+ */
+ public static final String PREF_DEFAULT_VPN_PROFILE = "pref_default_vpn_profile";
+
+ /**
+ * Value used to signify that the most recently used profile should be used as default
+ */
+ public static final String PREF_DEFAULT_VPN_PROFILE_MRU = "pref_default_vpn_profile_mru";
}
android:title="@string/show_log"
app:showAsAction="withText" />
+ <item
+ android:id="@+id/menu_settings"
+ android:title="@string/pref_title"
+ app:showAsAction="withText" />
+
</menu>
<string name="permanent_notification_name">VPN Verbindungsstatus</string>
<string name="permanent_notification_description">Zeigt Informationen zum Verbindungsstatus der VPN Verbindung und dient als permanente Notification dazu, den VPN Dienst im Hintergrund am Laufen zu halten.</string>
+ <!-- Settings -->
+ <string name="pref_title">Einstellungen</string>
+ <string name="pref_default_vpn_profile">Voreingestelltes VPN Profil</string>
+ <string name="pref_default_vpn_profile_mru">Verbinden mit zuletzt verwendetem Profil</string>
+
<!-- Log view -->
<string name="log_title">Log</string>
<string name="send_log">Logdatei senden</string>
<string name="profile_advanced_label">Erweiterte Einstellungen</string>
<string name="profile_show_advanced_label">Erweiterte Einstellungen anzeigen</string>
<string name="profile_remote_id_label">Server-Identität</string>
- <string name="profile_remote_id_hint">Standardwert ist der konfigurierte Server. Eigene Werte werden explizit and den Server gesendet und während der Authentifizierung erzwungen</string>
- <string name="profile_remote_id_hint_gateway">Standardwert ist \"%1$s\". Eigene Werte werden explizit and den Server gesendet und während der Authentifizierung erzwungen</string>
+ <string name="profile_remote_id_hint">Standardwert ist der konfigurierte Server. Eigene Werte werden explizit an den Server gesendet und während der Authentifizierung erzwungen</string>
+ <string name="profile_remote_id_hint_gateway">Standardwert ist \"%1$s\". Eigene Werte werden explizit an den Server gesendet und während der Authentifizierung erzwungen</string>
<string name="profile_mtu_label">MTU des VPN Tunnel-Device</string>
<string name="profile_mtu_hint">Falls der Standardwert in einem bestimmten Netzwerk nicht geeignet ist</string>
<string name="profile_port_label">Server Port</string>
<string name="profile_proposals_ike_hint">Für non-AEAD/klassische Verschlüsselungsalgorithmen wird ein Integritätsalgorithmus, eine pseudozufällige Funktion (PRF, optional, ansonsten wird eine auf dem Integritätsalgorithmus basierende verwendet) und eine Diffie-Hellman Gruppe benötigt (z.B. aes256-sha256-ecp256). Für kombinierte/AEAD Algorithmen wird der Integritätsalgorithmus weggelassen aber eine PRF wird benötigt (z.B. aes256gcm16-prfsha256-ecp256).</string>
<string name="profile_proposals_esp_label">IPsec/ESP Algorithmen</string>
<string name="profile_proposals_esp_hint">Für non-AEAD/klassische Verschlüsselungsalgorithmen wird ein Integritätsalgorithmus benötigt, eine Diffie-Hellman Gruppe ist optional (z.B. aes256-sha256 oder aes256-sha256-ecp256). Für kombinierte/AEAD Algorithmen wird der Integritätsalgorithmus weggelassen (z.B. aes256gcm16 oder aes256gcm16-ecp256). Falls eine DH Gruppe angegeben wird, kommt während dem IPsec SA Rekeying ein DH Schlüsselaustausch zur Anwendung. Beim initialen Verbindungsaufbau hat eine DH Gruppe hier keinen Einfluss, weil die Schlüssel dort von der IKE SA abgeleitet werden. Deshalb wird eine Fehlkonfiguration mit dem Server erst später während dem Rekeying zu einem Fehler führen.</string>
- <string name="profile_import">VPN Profile importieren</string>
+ <string name="profile_import">VPN Profil importieren</string>
<string name="profile_import_failed">VPN Profil-Import fehlgeschlagen</string>
<string name="profile_import_failed_detail">VPN Profil-Import fehlgeschlagen: %1$s</string>
<string name="profile_import_failed_not_found">Datei nicht gefunden</string>
<string name="permanent_notification_name">VPN connection state</string>
<string name="permanent_notification_description">Provides information about the VPN connection state and serves as permanent notification to keep the VPN service running in the background.</string>
+ <!-- Settings -->
+ <string name="pref_title">Settings</string>
+ <string name="pref_default_vpn_profile">Default VPN profile</string>
+ <string name="pref_default_vpn_profile_mru">Connect to most recently used profile</string>
+
<!-- Log view -->
<string name="log_title">Log</string>
<string name="send_log">Prześlij log</string>
<string name="permanent_notification_name">VPN connection state</string>
<string name="permanent_notification_description">Provides information about the VPN connection state and serves as permanent notification to keep the VPN service running in the background.</string>
+ <!-- Settings -->
+ <string name="pref_title">Settings</string>
+ <string name="pref_default_vpn_profile">Default VPN profile</string>
+ <string name="pref_default_vpn_profile_mru">Connect to most recently used profile</string>
+
<!-- Log view -->
<string name="log_title">Журнал</string>
<string name="send_log">Отправить журнал</string>
<string name="permanent_notification_name">VPN connection state</string>
<string name="permanent_notification_description">Provides information about the VPN connection state and serves as permanent notification to keep the VPN service running in the background.</string>
+ <!-- Settings -->
+ <string name="pref_title">Settings</string>
+ <string name="pref_default_vpn_profile">Default VPN profile</string>
+ <string name="pref_default_vpn_profile_mru">Connect to most recently used profile</string>
+
<!-- Log view -->
<string name="log_title">Журнал</string>
<string name="send_log">Відправити файл журналу</string>
<string name="permanent_notification_name">VPN connection state</string>
<string name="permanent_notification_description">Provides information about the VPN connection state and serves as permanent notification to keep the VPN service running in the background.</string>
+ <!-- Settings -->
+ <string name="pref_title">Settings</string>
+ <string name="pref_default_vpn_profile">Default VPN profile</string>
+ <string name="pref_default_vpn_profile_mru">Connect to most recently used profile</string>
+
<!-- Log view -->
<string name="log_title">日志</string>
<string name="send_log">发送日志文件</string>
<string name="permanent_notification_name">VPN connection state</string>
<string name="permanent_notification_description">Provides information about the VPN connection state and serves as permanent notification to keep the VPN service running in the background.</string>
+ <!-- Settings -->
+ <string name="pref_title">Settings</string>
+ <string name="pref_default_vpn_profile">Default VPN profile</string>
+ <string name="pref_default_vpn_profile_mru">Connect to most recently used profile</string>
+
<!-- Log view -->
<string name="log_title">日誌</string>
<string name="send_log">發送日誌檔</string>
<string name="permanent_notification_name">VPN connection state</string>
<string name="permanent_notification_description">Provides information about the VPN connection state and serves as permanent notification to keep the VPN service running in the background.</string>
+ <!-- Settings -->
+ <string name="pref_title">Settings</string>
+ <string name="pref_default_vpn_profile">Default VPN profile</string>
+ <string name="pref_default_vpn_profile_mru">Connect to most recently used profile</string>
+
<!-- Log view -->
<string name="log_title">Log</string>
<string name="send_log">Send log file</string>
<item name="colorPrimary">@color/primary</item>
<item name="colorPrimaryDark">@color/primary_dark</item>
<item name="android:alertDialogTheme">@style/AlertDialogTheme</item>
+ <item name="preferenceTheme">@style/PreferenceThemeOverlay</item>
</style>
<style name="AlertDialogTheme.Base" parent="Theme.AppCompat.Dialog.Alert">
--- /dev/null
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ Copyright (C) 2018 Tobias Brunner
+ HSR Hochschule fuer Technik Rapperswil
+
+ 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.
+-->
+<PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android">
+
+ <ListPreference
+ android:key="pref_default_vpn_profile"
+ android:title="@string/pref_default_vpn_profile"
+ android:summary="@string/pref_default_vpn_profile_mru" />
+
+</PreferenceScreen>