diff --git a/client/amnezia_application.cpp b/client/amnezia_application.cpp index 7d7a0376..38126e43 100644 --- a/client/amnezia_application.cpp +++ b/client/amnezia_application.cpp @@ -315,6 +315,10 @@ void AmneziaApplication::initControllers() m_installController.reset(new InstallController(m_serversModel, m_containersModel, m_settings)); m_engine->rootContext()->setContextProperty("InstallController", m_installController.get()); + connect(m_installController.get(), &InstallController::passphraseRequestStarted, m_pageController.get(), + &PageController::showPassphraseRequestDrawer); + connect(m_pageController.get(), &PageController::passphraseRequestDrawerClosed, m_installController.get(), + &InstallController::setEncryptedPassphrase); m_importController.reset(new ImportController(m_serversModel, m_containersModel, m_settings)); m_engine->rootContext()->setContextProperty("ImportController", m_importController.get()); diff --git a/client/ui/controllers/installController.cpp b/client/ui/controllers/installController.cpp index d6c32fac..49c77708 100644 --- a/client/ui/controllers/installController.cpp +++ b/client/ui/controllers/installController.cpp @@ -1,6 +1,7 @@ #include "installController.h" #include +#include #include #include @@ -396,8 +397,31 @@ void InstallController::mountSftpDrive(const QString &port, const QString &passw bool InstallController::checkSshConnection() { ServerController serverController(m_settings); - ErrorCode errorCode = ErrorCode::NoError; + m_privateKeyPassphrase = ""; + + if (m_currentlyInstalledServerCredentials.secretData.contains("BEGIN") + && m_currentlyInstalledServerCredentials.secretData.contains("PRIVATE KEY")) { + auto passphraseCallback = [this]() { + emit passphraseRequestStarted(); + QEventLoop loop; + QObject::connect(this, &InstallController::passphraseRequestFinished, &loop, &QEventLoop::quit); + loop.exec(); + + return m_privateKeyPassphrase; + }; + + QString decryptedPrivateKey; + errorCode = serverController.getDecryptedPrivateKey(m_currentlyInstalledServerCredentials, decryptedPrivateKey, + passphraseCallback); + if (errorCode == ErrorCode::NoError) { + m_currentlyInstalledServerCredentials.secretData = decryptedPrivateKey; + } else { + emit installationErrorOccurred(errorString(errorCode)); + return false; + } + } + QString output; output = serverController.checkSshConnection(m_currentlyInstalledServerCredentials, &errorCode); @@ -413,3 +437,9 @@ bool InstallController::checkSshConnection() } return true; } + +void InstallController::setEncryptedPassphrase(QString passphrase) +{ + m_privateKeyPassphrase = passphrase; + emit passphraseRequestFinished(); +} diff --git a/client/ui/controllers/installController.h b/client/ui/controllers/installController.h index b25f2082..54bcda31 100644 --- a/client/ui/controllers/installController.h +++ b/client/ui/controllers/installController.h @@ -39,6 +39,8 @@ public slots: bool checkSshConnection(); + void setEncryptedPassphrase(QString passphrase); + signals: void installContainerFinished(QString finishMessage); void installServerFinished(QString finishMessage); @@ -55,6 +57,9 @@ signals: void serverAlreadyExists(int serverIndex); + void passphraseRequestStarted(); + void passphraseRequestFinished(); + private: void installServer(DockerContainer container, QJsonObject &config); void installContainer(DockerContainer container, QJsonObject &config); @@ -68,6 +73,8 @@ private: bool m_shouldCreateServer; + QString m_privateKeyPassphrase; + #ifndef Q_OS_IOS QList> m_sftpMountProcesses; #endif diff --git a/client/ui/controllers/pageController.h b/client/ui/controllers/pageController.h index 4273ed25..8185b525 100644 --- a/client/ui/controllers/pageController.h +++ b/client/ui/controllers/pageController.h @@ -91,6 +91,9 @@ signals: void hideMainWindow(); void raiseMainWindow(); + void showPassphraseRequestDrawer(); + void passphraseRequestDrawerClosed(QString passphrase); + private: QSharedPointer m_serversModel; }; diff --git a/client/ui/models/containers_model.cpp b/client/ui/models/containers_model.cpp index 639cf962..8d24e019 100644 --- a/client/ui/models/containers_model.cpp +++ b/client/ui/models/containers_model.cpp @@ -211,6 +211,11 @@ bool ContainersModel::isAmneziaDnsContainerInstalled(const int serverIndex) return containers.contains(DockerContainer::Dns); } +// bool ContainersModel::isOnlyServicesInstalled(const int serverIndex) +//{ + +//} + QHash ContainersModel::roleNames() const { QHash roles; diff --git a/client/ui/models/containers_model.h b/client/ui/models/containers_model.h index a905890a..8978315c 100644 --- a/client/ui/models/containers_model.h +++ b/client/ui/models/containers_model.h @@ -60,6 +60,8 @@ public slots: bool isAmneziaDnsContainerInstalled(); bool isAmneziaDnsContainerInstalled(const int serverIndex); + // bool isOnlyServicesInstalled(const int serverIndex); + protected: QHash roleNames() const override; diff --git a/client/ui/qml/Components/SettingsContainersListView.qml b/client/ui/qml/Components/SettingsContainersListView.qml index eac473f4..bb578899 100644 --- a/client/ui/qml/Components/SettingsContainersListView.qml +++ b/client/ui/qml/Components/SettingsContainersListView.qml @@ -106,13 +106,17 @@ ListView { break } case ContainerEnum.WireGuard: { - WireGuardConfigModel.updateModel(config) - goToPage(PageEnum.PageProtocolWireGuardSettings) + ProtocolsModel.updateModel(config) + goToPage(PageEnum.PageProtocolRaw) +// WireGuardConfigModel.updateModel(config) +// goToPage(PageEnum.PageProtocolWireGuardSettings) break } case ContainerEnum.Ipsec: { - Ikev2ConfigModel.updateModel(config) - goToPage(PageEnum.PageProtocolIKev2Settings) + ProtocolsModel.updateModel(config) + goToPage(PageEnum.PageProtocolRaw) +// Ikev2ConfigModel.updateModel(config) +// goToPage(PageEnum.PageProtocolIKev2Settings) break } case ContainerEnum.Sftp: { diff --git a/client/ui/qml/Pages2/PageSettingsServerData.qml b/client/ui/qml/Pages2/PageSettingsServerData.qml index 12e66269..7be35cac 100644 --- a/client/ui/qml/Pages2/PageSettingsServerData.qml +++ b/client/ui/qml/Pages2/PageSettingsServerData.qml @@ -134,7 +134,7 @@ PageType { questionDrawer.yesButtonFunction = function() { questionDrawer.visible = false PageController.showBusyIndicator(true) - if (ServersModel.isDefaultServerCurrentlyProcessed && ConnectionController.isConnected) { + if (ServersModel.isDefaultServerCurrentlyProcessed() && ConnectionController.isConnected) { ConnectionController.closeConnection() } InstallController.removeCurrentlyProcessedServer() @@ -165,7 +165,7 @@ PageType { questionDrawer.yesButtonFunction = function() { questionDrawer.visible = false goToPage(PageEnum.PageDeinstalling) - if (ServersModel.isDefaultServerCurrentlyProcessed && ConnectionController.isConnected) { + if (ServersModel.isDefaultServerCurrentlyProcessed() && ConnectionController.isConnected) { ConnectionController.closeVpnConnection() } InstallController.removeAllContainers() diff --git a/client/ui/qml/Pages2/PageStart.qml b/client/ui/qml/Pages2/PageStart.qml index ec29b314..2cc64a91 100644 --- a/client/ui/qml/Pages2/PageStart.qml +++ b/client/ui/qml/Pages2/PageStart.qml @@ -52,7 +52,7 @@ PageType { PageController.showErrorMessage(errorMessage) var needCloseCurrentPage = false - var currentPageName = stackView.currentItem.objectName + var currentPageName = tabBarStackView.currentItem.objectName if (currentPageName === PageController.getPagePath(PageEnum.PageSetupWizardInstalling)) { needCloseCurrentPage = true diff --git a/client/ui/qml/main2.qml b/client/ui/qml/main2.qml index 6b2bee2a..f07bcf5d 100644 --- a/client/ui/qml/main2.qml +++ b/client/ui/qml/main2.qml @@ -75,6 +75,10 @@ Window { popupNotificationMessage.open() popupNotificationTimer.start() } + + function onShowPassphraseRequestDrawer() { + privateKeyPassphraseDrawer.open() + } } Item { @@ -111,4 +115,74 @@ Window { id: popupErrorMessage } } + + Item { + anchors.right: parent.right + anchors.left: parent.left + anchors.bottom: parent.bottom + + implicitHeight: popupErrorMessage.height + + DrawerType { + id: privateKeyPassphraseDrawer + + width: root.width + height: root.height * 0.35 + + onVisibleChanged: { + if (privateKeyPassphraseDrawer.visible) { + passphrase.textFieldText = "" + passphrase.textField.forceActiveFocus() + } + } + onAboutToHide: { + PageController.showBusyIndicator(true) + } + onAboutToShow: { + PageController.showBusyIndicator(false) + } + + ColumnLayout { + anchors.top: parent.top + anchors.left: parent.left + anchors.right: parent.right + anchors.topMargin: 16 + anchors.leftMargin: 16 + anchors.rightMargin: 16 + + TextFieldWithHeaderType { + id: passphrase + + property bool hidePassword: true + + Layout.fillWidth: true + headerText: qsTr("Private key passphrase") + textField.echoMode: hidePassword ? TextInput.Password : TextInput.Normal + buttonImageSource: hidePassword ? "qrc:/images/controls/eye.svg" : "qrc:/images/controls/eye-off.svg" + + clickedFunc: function() { + hidePassword = !hidePassword + } + } + + BasicButtonType { + Layout.fillWidth: true + + defaultColor: "transparent" + hoveredColor: Qt.rgba(1, 1, 1, 0.08) + pressedColor: Qt.rgba(1, 1, 1, 0.12) + disabledColor: "#878B91" + textColor: "#D7D8DB" + borderWidth: 1 + + text: qsTr("Save") + + onClicked: { + privateKeyPassphraseDrawer.close() + PageController.passphraseRequestDrawerClosed(passphrase.textFieldText) + } + } + } + } + } }