import org.strongswan.android.logic.VpnStateService.State;
import org.strongswan.android.logic.imc.ImcState;
import org.strongswan.android.logic.imc.RemediationInstruction;
+import org.strongswan.android.ui.LoginDialogFragment;
import org.strongswan.android.ui.MainActivity;
import org.strongswan.android.ui.VpnLoginActivity;
import org.strongswan.android.ui.VpnProfileControlActivity;
*
* Note that this method is called from a thread of charon's thread pool.
*
+ * @param pin whether a PIN or a password is requested
* @return the password
*/
- private String getPassword()
+ private String getPassword(boolean pin)
{
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N)
{
- return mPasswordPrompt.getPassword();
+ return mPasswordPrompt.getPassword(pin);
}
return null;
}
}
@RequiresApi(api = Build.VERSION_CODES.KITKAT)
- private Notification buildNotification(boolean publicVersion)
+ private Notification buildNotification(boolean pin, boolean publicVersion)
{
CharonVpnService service = CharonVpnService.this;
Intent intent = new Intent(service, VpnLoginActivity.class);
intent.putExtra(VpnProfileDataSource.KEY_USERNAME, mCurrentProfile.getUsername());
+ intent.putExtra(LoginDialogFragment.REQUEST_PIN, pin);
PendingIntent pending = PendingIntent.getActivity(service, 0, intent,
PendingIntent.FLAG_UPDATE_CURRENT);
new NotificationCompat.Builder(service, PASSWORD_CHANNEL)
.setSmallIcon(R.drawable.ic_notification_warning)
.setColor(ContextCompat.getColor(service, R.color.warning_text))
- .setContentTitle(getString(R.string.password_notification_prompt))
+ .setContentTitle(getString(pin ? R.string.password_notification_prompt_pin : R.string.password_notification_prompt))
.setTimeoutAfter(PASSWORD_TIMEOUT * 1000)
.setWhen(System.currentTimeMillis() + PASSWORD_TIMEOUT * 1000)
.setUsesChronometer(true)
if (!publicVersion)
{
builder.setContentText(mCurrentProfile.getName());
- builder.setPublicVersion(buildNotification(true));
+ builder.setPublicVersion(buildNotification(pin, true));
}
Notification notification = builder.build();
}
@RequiresApi(api = Build.VERSION_CODES.N)
- public String getPassword()
+ public String getPassword(boolean pin)
{
synchronized (mLock)
{
}
NotificationManagerCompat manager = NotificationManagerCompat.from(CharonVpnService.this);
- manager.notify(PASSWORD_NOTIFICATION_ID, buildNotification(false));
+ manager.notify(PASSWORD_NOTIFICATION_ID, buildNotification(pin, false));
try
{
return mPassword.get(PASSWORD_TIMEOUT, TimeUnit.SECONDS);
*/
public class LoginDialogFragment extends AppCompatDialogFragment
{
+ public static final String REQUEST_PIN = "REQUEST_PIN";
+
private OnLoginDialogFragmentListener mListener;
/**
public Dialog onCreateDialog(Bundle savedInstanceState)
{
final Bundle profileInfo = getArguments();
+ final boolean pin = profileInfo.getBoolean(REQUEST_PIN);
LayoutInflater inflater = getActivity().getLayoutInflater();
- View view = inflater.inflate(R.layout.login_dialog, null);
- EditText username = view.findViewById(R.id.username);
- username.setText(profileInfo.getString(VpnProfileDataSource.KEY_USERNAME));
+ View view = inflater.inflate(pin ? R.layout.login_dialog_pin : R.layout.login_dialog, null);
final EditText password = view.findViewById(R.id.password);
+ if (!pin)
+ {
+ EditText username = view.findViewById(R.id.username);
+ username.setText(profileInfo.getString(VpnProfileDataSource.KEY_USERNAME));
+ }
AlertDialog.Builder adb = new AlertDialog.Builder(getActivity());
adb.setView(view);
- adb.setTitle(getString(R.string.login_title));
+ adb.setTitle(getString(pin ? R.string.login_title_pin : R.string.login_title));
adb.setPositiveButton(R.string.login_confirm, (dialog, which) ->
mListener.onLoginDialogDismissed(password.getText().toString().trim()));
adb.setNegativeButton(android.R.string.cancel, (dialog, which) ->
}
else
{
- pwd = charonservice->get_password(charonservice);
+ pwd = charonservice->get_password(charonservice, type == SHARED_PIN);
if (pwd)
{
shared = shared_key_create(type, chunk_clone(chunk_from_str(pwd)));
}
METHOD(charonservice_t, get_password, char*,
- private_charonservice_t *this)
+ private_charonservice_t *this, bool pin)
{
JNIEnv *env;
jmethodID method_id;
androidjni_attach_thread(&env);
method_id = (*env)->GetMethodID(env, android_charonvpnservice_class,
- "getPassword", "()Ljava/lang/String;");
+ "getPassword", "(Z)Ljava/lang/String;");
if (!method_id)
{
goto failed;
}
- jpassword = (*env)->CallObjectMethod(env, this->vpn_service, method_id);
+ jpassword = (*env)->CallObjectMethod(env, this->vpn_service, method_id,
+ pin);
if (androidjni_exception_occurred(env) || !jpassword)
{
goto failed;
/**
* Get a password from the user via JNI
*
+ * @param pin whether to request a PIN instead of a password
* @return allocated password, NULL on failure
*/
- char *(*get_password)(charonservice_t *this);
+ char *(*get_password)(charonservice_t *this, bool pin);
/**
* Get the current vpnservice_builder_t object
--- /dev/null
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ Copyright (C) 2020 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.
+-->
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+ android:layout_height="match_parent"
+ android:layout_width="match_parent"
+ android:orientation="vertical"
+ android:padding="10dp" >
+
+ <com.google.android.material.textfield.TextInputLayout
+ android:id="@+id/password_wrap"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:layout_marginTop="4dp" >
+
+ <com.google.android.material.textfield.TextInputEditText
+ android:id="@+id/password"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:singleLine="true"
+ android:inputType="textPassword|textNoSuggestions"
+ android:hint="@string/login_pin" />
+
+ </com.google.android.material.textfield.TextInputLayout>
+
+</LinearLayout>
<string name="password_notification_name">VPN Passwort</string>
<string name="password_notification_description">Wird verwendet, um vom Benutzer ein Passwort zu verlangen.</string>
<string name="password_notification_prompt">Password benötigt</string>
+ <string name="password_notification_prompt_pin">PIN benötigt</string>
<!-- Settings -->
<string name="pref_title">Einstellungen</string>
<string name="remediation_instructions_title">Korrekturanweisungen</string>
<!-- Dialogs -->
- <string name="login_title">Passwort eingeben um zu verbinden</string>
+ <string name="login_title">Passwort eingeben, um zu verbinden</string>
+ <string name="login_title_pin">PIN eingeben, um zu verbinden</string>
<string name="login_username">Benutzername</string>
<string name="login_password">Passwort</string>
+ <string name="login_pin">PIN</string>
<string name="login_confirm">Verbinden</string>
<string name="error_format">Fehler beim Aufsetzen des VPN: %1$s.</string>
<string name="error_lookup_failed">Server-Adresse konnte nicht aufgelöst werden</string>
<string name="password_notification_name">VPN password</string>
<string name="password_notification_description">Used to request a password from the user.</string>
<string name="password_notification_prompt">Password required</string>
+ <string name="password_notification_prompt_pin">PIN required</string>
<!-- Settings -->
<string name="pref_title">Settings</string>
<!-- Dialogs -->
<string name="login_title">Wprowadż hasło</string>
+ <string name="login_title_pin">Enter PIN to connect</string>
<string name="login_username">Użytkownik</string>
<string name="login_password">Hasło</string>
+ <string name="login_pin">PIN</string>
<string name="login_confirm">Połącz</string>
<string name="error_format">Nie udało się utworzyć tunelu VPN: %1$s.</string>
<string name="error_lookup_failed">Nie znaleziono adresu serwer</string>
<string name="password_notification_name">VPN password</string>
<string name="password_notification_description">Used to request a password from the user.</string>
<string name="password_notification_prompt">Password required</string>
+ <string name="password_notification_prompt_pin">PIN required</string>
<!-- Settings -->
<string name="pref_title">Settings</string>
<!-- Dialogs -->
<string name="login_title">Введите пароль для соединения</string>
+ <string name="login_title_pin">Enter PIN to connect</string>
<string name="login_username">Логин</string>
<string name="login_password">Пароль</string>
+ <string name="login_pin">PIN</string>
<string name="login_confirm">Соединить</string>
<string name="error_format">Ошибка подключения к VPN: %1$s.</string>
<string name="error_lookup_failed">Не найден адрес сервер</string>
<string name="password_notification_name">VPN password</string>
<string name="password_notification_description">Used to request a password from the user.</string>
<string name="password_notification_prompt">Password required</string>
+ <string name="password_notification_prompt_pin">PIN required</string>
<!-- Settings -->
<string name="pref_title">Settings</string>
<!-- Dialogs -->
<string name="login_title">Введіть пароль для з\'єднання</string>
+ <string name="login_title_pin">Enter PIN to connect</string>
<string name="login_username">Логін</string>
<string name="login_password">Пароль</string>
+ <string name="login_pin">PIN</string>
<string name="login_confirm">Підключити</string>
<string name="error_format">Помилка підлючення VPN: %1$s.</string>
<string name="error_lookup_failed">Помилка пошуку адреси сервер</string>
<string name="password_notification_name">VPN password</string>
<string name="password_notification_description">Used to request a password from the user.</string>
<string name="password_notification_prompt">Password required</string>
+ <string name="password_notification_prompt_pin">PIN required</string>
<!-- Settings -->
<string name="pref_title">Settings</string>
<!-- Dialogs -->
<string name="login_title">输入密码用于连接</string>
+ <string name="login_title_pin">Enter PIN to connect</string>
<string name="login_username">用户名</string>
<string name="login_password">密码</string>
+ <string name="login_pin">PIN</string>
<string name="login_confirm">连接</string>
<string name="error_format">无法建立VPN:%1$s。</string>
<string name="error_lookup_failed">服务器地址查找失败</string>
<string name="password_notification_name">VPN password</string>
<string name="password_notification_description">Used to request a password from the user.</string>
<string name="password_notification_prompt">Password required</string>
+ <string name="password_notification_prompt_pin">PIN required</string>
<!-- Settings -->
<string name="pref_title">Settings</string>
<!-- Dialogs -->
<string name="login_title">輸入密碼進行連線</string>
+ <string name="login_title_pin">Enter PIN to connect</string>
<string name="login_username">用戶名稱</string>
<string name="login_password">密碼</string>
+ <string name="login_pin">PIN</string>
<string name="login_confirm">連線</string>
<string name="error_format">無法建立VPN:%1$s。</string>
<string name="error_lookup_failed">伺服器位置查詢失敗</string>
<string name="password_notification_name">VPN password</string>
<string name="password_notification_description">Used to request a password from the user.</string>
<string name="password_notification_prompt">Password required</string>
+ <string name="password_notification_prompt_pin">PIN required</string>
<!-- Settings -->
<string name="pref_title">Settings</string>
<!-- Dialogs -->
<string name="login_title">Enter password to connect</string>
+ <string name="login_title_pin">Enter PIN to connect</string>
<string name="login_username">Username</string>
<string name="login_password">Password</string>
+ <string name="login_pin">PIN</string>
<string name="login_confirm">Connect</string>
<string name="error_format">Failed to establish VPN: %1$s.</string>
<string name="error_lookup_failed">Server address lookup failed</string>