From d93be76505b5ae2d7d1aefa90f40829066dc27a3 Mon Sep 17 00:00:00 2001 From: Mykola Baibuz Date: Mon, 19 Sep 2022 12:27:33 +0300 Subject: [PATCH] Add auth protection for ssh key export We use a builtin keyguard for ssh key export protection on Android. This protection works only if some protection is set on the phone. https://developer.android.com/reference/android/app/KeyguardManager#isDeviceSecure() --- .../src/org/amnezia/vpn/AuthHelper.java | 24 ++++++++++++ client/ui/pages_logic/ServerSettingsLogic.cpp | 39 +++++++++++++++++++ client/ui/pages_logic/ServerSettingsLogic.h | 25 ++++++++++++ 3 files changed, 88 insertions(+) create mode 100644 client/android/src/org/amnezia/vpn/AuthHelper.java diff --git a/client/android/src/org/amnezia/vpn/AuthHelper.java b/client/android/src/org/amnezia/vpn/AuthHelper.java new file mode 100644 index 00000000..b30aa8f5 --- /dev/null +++ b/client/android/src/org/amnezia/vpn/AuthHelper.java @@ -0,0 +1,24 @@ +package org.amnezia.vpn; + +import android.content.Context; +import android.app.KeyguardManager; +import android.content.Intent; +import org.qtproject.qt5.android.bindings.QtActivity; + + +import static android.content.Context.KEYGUARD_SERVICE; + +public class AuthHelper extends QtActivity { + + static final String TAG = "AuthHelper"; + + public static Intent getAuthIntent(Context context) { + KeyguardManager mKeyguardManager = (KeyguardManager)context.getSystemService(KEYGUARD_SERVICE); + if (mKeyguardManager.isDeviceSecure()) { + return mKeyguardManager.createConfirmDeviceCredentialIntent(null, null); + } else { + return null; + } + } + +} diff --git a/client/ui/pages_logic/ServerSettingsLogic.cpp b/client/ui/pages_logic/ServerSettingsLogic.cpp index bd954c88..3b123174 100644 --- a/client/ui/pages_logic/ServerSettingsLogic.cpp +++ b/client/ui/pages_logic/ServerSettingsLogic.cpp @@ -10,6 +10,12 @@ #include #include +#if defined(Q_OS_ANDROID) +#include +#include +#include +#endif + ServerSettingsLogic::ServerSettingsLogic(UiLogic *logic, QObject *parent): PageLogicBase(logic, parent), m_labelWaitInfoVisible{true}, @@ -126,8 +132,41 @@ void ServerSettingsLogic::onLineEditDescriptionEditingFinished() uiLogic()->onUpdateAllPages(); } +#if defined(Q_OS_ANDROID) +/* Auth result handler for Android */ +void authResultReceiver::handleActivityResult(int receiverRequestCode, int resultCode, const QAndroidJniObject &data) +{ + qDebug() << "receiverRequestCode" << receiverRequestCode << "resultCode" << resultCode; + + if (resultCode == -1) { //ResultOK + uiLogic()->pageLogic()->updateSharingPage(m_serverIndex, DockerContainer::None); + emit uiLogic()->goToShareProtocolPage(Proto::Any); + } +} +#endif + void ServerSettingsLogic::onPushButtonShareFullClicked() { +#if defined(Q_OS_ANDROID) +/* We use builtin keyguard for ssh key export protection on Android */ + auto appContext = QtAndroid::androidActivity().callObjectMethod( + "getApplicationContext", "()Landroid/content/Context;"); + if (appContext.isValid()) { + QAndroidActivityResultReceiver *receiver = new authResultReceiver(uiLogic(), uiLogic()->selectedServerIndex); + auto intent = QAndroidJniObject::callStaticObjectMethod( + "org/amnezia/vpn/AuthHelper", "getAuthIntent", + "(Landroid/content/Context;)Landroid/content/Intent;", appContext.object()); + if (intent.isValid()) { + if (intent.object() != nullptr) { + QtAndroid::startActivity(intent.object(), 1, receiver); + } + } else { + uiLogic()->pageLogic()->updateSharingPage(uiLogic()->selectedServerIndex, DockerContainer::None); + emit uiLogic()->goToShareProtocolPage(Proto::Any); + } + } +#else uiLogic()->pageLogic()->updateSharingPage(uiLogic()->selectedServerIndex, DockerContainer::None); emit uiLogic()->goToShareProtocolPage(Proto::Any); +#endif } diff --git a/client/ui/pages_logic/ServerSettingsLogic.h b/client/ui/pages_logic/ServerSettingsLogic.h index 282b90ea..e2d57422 100644 --- a/client/ui/pages_logic/ServerSettingsLogic.h +++ b/client/ui/pages_logic/ServerSettingsLogic.h @@ -3,6 +3,10 @@ #include "PageLogicBase.h" +#if defined(Q_OS_ANDROID) +#include +#endif + class UiLogic; class ServerSettingsLogic : public PageLogicBase @@ -34,4 +38,25 @@ public: ~ServerSettingsLogic() = default; }; + +#if defined(Q_OS_ANDROID) +/* Auth result handler for Android */ +class authResultReceiver final : public PageLogicBase, public QAndroidActivityResultReceiver +{ +Q_OBJECT + +public: + authResultReceiver(UiLogic *uiLogic, int serverIndex , QObject *parent = nullptr) : PageLogicBase(uiLogic, parent) { + m_serverIndex = serverIndex; + } + ~authResultReceiver() {} + +public: + void handleActivityResult(int receiverRequestCode, int resultCode, const QAndroidJniObject &data) override; + +private: + int m_serverIndex; +}; +#endif + #endif // SERVER_SETTINGS_LOGIC_H