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()
This commit is contained in:
Mykola Baibuz 2022-09-19 12:27:33 +03:00
parent 5fff65db5a
commit d93be76505
3 changed files with 88 additions and 0 deletions

View file

@ -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;
}
}
}

View file

@ -10,6 +10,12 @@
#include <core/servercontroller.h> #include <core/servercontroller.h>
#include <QTimer> #include <QTimer>
#if defined(Q_OS_ANDROID)
#include <QAndroidJniObject>
#include <QAndroidJniEnvironment>
#include <QtAndroid>
#endif
ServerSettingsLogic::ServerSettingsLogic(UiLogic *logic, QObject *parent): ServerSettingsLogic::ServerSettingsLogic(UiLogic *logic, QObject *parent):
PageLogicBase(logic, parent), PageLogicBase(logic, parent),
m_labelWaitInfoVisible{true}, m_labelWaitInfoVisible{true},
@ -126,8 +132,41 @@ void ServerSettingsLogic::onLineEditDescriptionEditingFinished()
uiLogic()->onUpdateAllPages(); 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<ShareConnectionLogic>()->updateSharingPage(m_serverIndex, DockerContainer::None);
emit uiLogic()->goToShareProtocolPage(Proto::Any);
}
}
#endif
void ServerSettingsLogic::onPushButtonShareFullClicked() 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<jobject>() != nullptr) {
QtAndroid::startActivity(intent.object<jobject>(), 1, receiver);
}
} else {
uiLogic()->pageLogic<ShareConnectionLogic>()->updateSharingPage(uiLogic()->selectedServerIndex, DockerContainer::None);
emit uiLogic()->goToShareProtocolPage(Proto::Any);
}
}
#else
uiLogic()->pageLogic<ShareConnectionLogic>()->updateSharingPage(uiLogic()->selectedServerIndex, DockerContainer::None); uiLogic()->pageLogic<ShareConnectionLogic>()->updateSharingPage(uiLogic()->selectedServerIndex, DockerContainer::None);
emit uiLogic()->goToShareProtocolPage(Proto::Any); emit uiLogic()->goToShareProtocolPage(Proto::Any);
#endif
} }

View file

@ -3,6 +3,10 @@
#include "PageLogicBase.h" #include "PageLogicBase.h"
#if defined(Q_OS_ANDROID)
#include <QAndroidActivityResultReceiver>
#endif
class UiLogic; class UiLogic;
class ServerSettingsLogic : public PageLogicBase class ServerSettingsLogic : public PageLogicBase
@ -34,4 +38,25 @@ public:
~ServerSettingsLogic() = default; ~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 #endif // SERVER_SETTINGS_LOGIC_H