]> git.ipfire.org Git - thirdparty/strongswan.git/commitdiff
android: Support requesting PINs instead of passwords android-pw-callback
authorTobias Brunner <tobias@strongswan.org>
Fri, 27 Mar 2020 09:56:44 +0000 (10:56 +0100)
committerTobias Brunner <tobias@strongswan.org>
Fri, 30 Oct 2020 14:34:07 +0000 (15:34 +0100)
13 files changed:
src/frontends/android/app/src/main/java/org/strongswan/android/logic/CharonVpnService.java
src/frontends/android/app/src/main/java/org/strongswan/android/ui/LoginDialogFragment.java
src/frontends/android/app/src/main/jni/libandroidbridge/backend/android_creds.c
src/frontends/android/app/src/main/jni/libandroidbridge/charonservice.c
src/frontends/android/app/src/main/jni/libandroidbridge/charonservice.h
src/frontends/android/app/src/main/res/layout/login_dialog_pin.xml [new file with mode: 0644]
src/frontends/android/app/src/main/res/values-de/strings.xml
src/frontends/android/app/src/main/res/values-pl/strings.xml
src/frontends/android/app/src/main/res/values-ru/strings.xml
src/frontends/android/app/src/main/res/values-ua/strings.xml
src/frontends/android/app/src/main/res/values-zh-rCN/strings.xml
src/frontends/android/app/src/main/res/values-zh-rTW/strings.xml
src/frontends/android/app/src/main/res/values/strings.xml

index 71635123459d4443e65201e6f16ef9ef1fef768d..dfe548f6060b4414562c376e6a053b569055d2b2 100644 (file)
@@ -51,6 +51,7 @@ import org.strongswan.android.logic.VpnStateService.ErrorState;
 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;
@@ -798,13 +799,14 @@ public class CharonVpnService extends VpnService implements Runnable, VpnStateSe
         *
         * 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;
        }
@@ -1460,12 +1462,13 @@ public class CharonVpnService extends VpnService implements Runnable, VpnStateSe
                }
 
                @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);
 
@@ -1473,7 +1476,7 @@ public class CharonVpnService extends VpnService implements Runnable, VpnStateSe
                                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)
@@ -1484,7 +1487,7 @@ public class CharonVpnService extends VpnService implements Runnable, VpnStateSe
                        if (!publicVersion)
                        {
                                builder.setContentText(mCurrentProfile.getName());
-                               builder.setPublicVersion(buildNotification(true));
+                               builder.setPublicVersion(buildNotification(pin, true));
                        }
 
                        Notification notification = builder.build();
@@ -1495,7 +1498,7 @@ public class CharonVpnService extends VpnService implements Runnable, VpnStateSe
                }
 
                @RequiresApi(api = Build.VERSION_CODES.N)
-               public String getPassword()
+               public String getPassword(boolean pin)
                {
                        synchronized (mLock)
                        {
@@ -1507,7 +1510,7 @@ public class CharonVpnService extends VpnService implements Runnable, VpnStateSe
                        }
 
                        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);
index 2efcc9fc4b6baa348f77a6e320c278139f237b9d..159497a4b5b65f5fd9de7cc144d6fdded34ca4ed 100644 (file)
@@ -33,6 +33,8 @@ import androidx.appcompat.app.AppCompatDialogFragment;
  */
 public class LoginDialogFragment extends AppCompatDialogFragment
 {
+       public static final String REQUEST_PIN = "REQUEST_PIN";
+
        private OnLoginDialogFragmentListener mListener;
 
        /**
@@ -55,15 +57,19 @@ public class LoginDialogFragment extends AppCompatDialogFragment
        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) ->
index 63e97e155cdf3cc0d17fc117dae62a0d1de615bb..3464a85cf63b8d67df7052ecbe3602483a5739bb 100644 (file)
@@ -263,7 +263,7 @@ METHOD(credential_set_t, create_shared_enumerator, enumerator_t*,
        }
        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)));
index 4fe0289bb25e506ef61165b7f466af1a78203699..b1bc625d169826b0c591631bd92eb280310490a5 100644 (file)
@@ -391,7 +391,7 @@ failed:
 }
 
 METHOD(charonservice_t, get_password, char*,
-       private_charonservice_t *this)
+       private_charonservice_t *this, bool pin)
 {
        JNIEnv *env;
        jmethodID method_id;
@@ -401,12 +401,13 @@ METHOD(charonservice_t, get_password, char*,
        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;
index d835b50406df1035657317aa356b4ee1a8086796..09dcb9520eacff8440e5248d351187ab787e80e1 100644 (file)
@@ -146,9 +146,10 @@ struct charonservice_t {
        /**
         * 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
diff --git a/src/frontends/android/app/src/main/res/layout/login_dialog_pin.xml b/src/frontends/android/app/src/main/res/layout/login_dialog_pin.xml
new file mode 100644 (file)
index 0000000..0e79ab7
--- /dev/null
@@ -0,0 +1,38 @@
+<?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>
index 687befe8a1c917f0d13c7d7f90f9b079c8c8ce16..e0af48bfac24247981eaf7ae73e45453cda50ead 100644 (file)
@@ -34,6 +34,7 @@
     <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>
index dbb06f9aff075b3a3b482354f409a8b1f4cf9db4..66b10957f76bac0309d1bd811769a37edd5e1e5b 100644 (file)
@@ -34,6 +34,7 @@
     <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>
index f4925f5ec254bca00ea6e852448cadb03ff86a27..47947128af40c23659739a71998c1822a7d45450 100644 (file)
@@ -31,6 +31,7 @@
     <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>
index 45ded7841c1683e78cbe23ed92e61712f1b71b8d..13d51a3071f093028780ac72fe38aa338649c14f 100644 (file)
@@ -32,6 +32,7 @@
     <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>
index cdb6f79c3b5d48bd6ed7488761fc18572ae9797f..bc433d3b90bd4b1f9c5d1a82e8509dc81c9dc39a 100644 (file)
@@ -31,6 +31,7 @@
     <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>
index 51759fc50aad181b446dbedd4683dd46672f9f5c..ff6136f32285fc6718f51af915fc842fc281325a 100644 (file)
@@ -31,6 +31,7 @@
     <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>
index 22d496bb4ca630f7ab1bd6c0f8acff2e12a25ed7..348cea16552db2edac32d42229a30cc362e51e10 100644 (file)
@@ -34,6 +34,7 @@
     <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>