From 6c4ba027035126c689c98b1b92f0aa0695c081be Mon Sep 17 00:00:00 2001 From: Carlo Ramponi Date: Fri, 26 Aug 2022 18:22:01 +0200 Subject: [PATCH] Save credentials in system wallet --- GPClient/CMakeLists.txt | 21 +++++++++++++++++- GPClient/gphelper.cpp | 38 ++++++++++++++++++++++++++++++++ GPClient/gphelper.h | 3 +++ GPClient/standardloginwindow.cpp | 19 ++++++++++++++++ GPClient/standardloginwindow.h | 1 + 5 files changed, 81 insertions(+), 1 deletion(-) diff --git a/GPClient/CMakeLists.txt b/GPClient/CMakeLists.txt index 578e1fd..0c94cd2 100644 --- a/GPClient/CMakeLists.txt +++ b/GPClient/CMakeLists.txt @@ -64,6 +64,17 @@ add_3rdparty( -DCMAKE_CXX_FLAGS_RELEASE=${CMAKE_CXX_FLAGS_RELEASE} ) +add_3rdparty( + qtkeychain + GIT_REPOSITORY https://github.com/frankosterfeld/qtkeychain.git + GIT_TAG master + CMAKE_ARGS + -DCMAKE_BUILD_TYPE=${CMAKE_BUILD_TYPE} + -DCMAKE_CXX_FLAGS_RELEASE=${CMAKE_CXX_FLAGS_RELEASE} + -DCMAKE_FIND_ROOT_PATH=${CMAKE_FIND_ROOT_PATH} + -DCMAKE_PREFIX_PATH=$ENV{CMAKE_PREFIX_PATH} +) + ExternalProject_Get_Property(SingleApplication-${PROJECT_NAME} SOURCE_DIR BINARY_DIR) set(SingleApplication_INCLUDE_DIR ${SOURCE_DIR}) set(SingleApplication_LIBRARY ${BINARY_DIR}/libSingleApplication.a) @@ -71,7 +82,12 @@ set(SingleApplication_LIBRARY ${BINARY_DIR}/libSingleApplication.a) ExternalProject_Get_Property(plog-${PROJECT_NAME} SOURCE_DIR) set(plog_INCLUDE_DIR "${SOURCE_DIR}/include") -add_dependencies(gpclient SingleApplication-${PROJECT_NAME} plog-${PROJECT_NAME}) +ExternalProject_Get_Property(qtkeychain-${PROJECT_NAME} SOURCE_DIR BINARY_DIR) +set(qtkeychain_INCLUDE_DIR "${SOURCE_DIR}") +set(qtkeychain_BINARY_DIR "${BINARY_DIR}") +set(qtkeychain_LIBRARY ${BINARY_DIR}/libqt5keychain.so) + +add_dependencies(gpclient SingleApplication-${PROJECT_NAME} plog-${PROJECT_NAME} qtkeychain-${PROJECT_NAME}) target_include_directories(gpclient PRIVATE ${CMAKE_BINARY_DIR} @@ -79,10 +95,13 @@ target_include_directories(gpclient PRIVATE ${CMAKE_CURRENT_BINARY_DIR} ${SingleApplication_INCLUDE_DIR} ${plog_INCLUDE_DIR} + ${qtkeychain_INCLUDE_DIR} + ${qtkeychain_BINARY_DIR} ) target_link_libraries(gpclient ${SingleApplication_LIBRARY} + ${qtkeychain_LIBRARY} Qt5::Widgets Qt5::Network Qt5::WebSockets diff --git a/GPClient/gphelper.cpp b/GPClient/gphelper.cpp index 08a5152..540b426 100644 --- a/GPClient/gphelper.cpp +++ b/GPClient/gphelper.cpp @@ -9,9 +9,12 @@ #include #include #include +#include #include "gphelper.h" +using namespace QKeychain; + QNetworkAccessManager* gpclient::helper::networkManager = new QNetworkAccessManager; QNetworkReply* gpclient::helper::createRequest(QString url, QByteArray params) @@ -132,3 +135,38 @@ void gpclient::helper::settings::clear() QWebEngineProfile::defaultProfile()->cookieStore()->deleteAllCookies(); } + + +bool gpclient::helper::settings::secureSave(const QString &key, const QString &value) { + WritePasswordJob job( QLatin1String("gpclient") ); + job.setAutoDelete( false ); + job.setKey( key ); + job.setTextData( value ); + QEventLoop loop; + job.connect( &job, SIGNAL(finished(QKeychain::Job*)), &loop, SLOT(quit()) ); + job.start(); + loop.exec(); + if ( job.error() ) { + return false; + } + + return true; +} + +bool gpclient::helper::settings::secureGet(const QString &key, QString &value) { + ReadPasswordJob job( QLatin1String("gpclient") ); + job.setAutoDelete( false ); + job.setKey( key ); + QEventLoop loop; + job.connect( &job, SIGNAL(finished(QKeychain::Job*)), &loop, SLOT(quit()) ); + job.start(); + loop.exec(); + + const QString pw = job.textData(); + if ( job.error() ) { + return false; + } + + value = pw; + return true; +} \ No newline at end of file diff --git a/GPClient/gphelper.h b/GPClient/gphelper.h index fb74899..14565b6 100644 --- a/GPClient/gphelper.h +++ b/GPClient/gphelper.h @@ -36,6 +36,9 @@ namespace gpclient { QVariant get(const QString &key, const QVariant &defaultValue = QVariant()); void save(const QString &key, const QVariant &value); void clear(); + + bool secureSave(const QString &key, const QString &value); + bool secureGet(const QString &key, QString &value); } } } diff --git a/GPClient/standardloginwindow.cpp b/GPClient/standardloginwindow.cpp index bdd9aa4..7964d1c 100644 --- a/GPClient/standardloginwindow.cpp +++ b/GPClient/standardloginwindow.cpp @@ -2,6 +2,9 @@ #include "standardloginwindow.h" #include "ui_standardloginwindow.h" +#include "gphelper.h" + +using namespace gpclient::helper; StandardLoginWindow::StandardLoginWindow(const QString &portalAddress, const QString &labelUsername, const QString &labelPassword, const QString &authMessage) : @@ -13,11 +16,24 @@ StandardLoginWindow::StandardLoginWindow(const QString &portalAddress, const QSt ui->password->setPlaceholderText(labelPassword); ui->authMessage->setText(authMessage); + autocomplete(); + setWindowTitle("GlobalProtect Login"); setFixedSize(width(), height()); setModal(true); } +void StandardLoginWindow::autocomplete() { + QString username, password; + settings::secureGet("username", username); + settings::secureGet("password", password); + + if (!username.isEmpty() && !password.isEmpty()) { + ui->username->setText(username); + ui->password->setText(password); + } +} + void StandardLoginWindow::setProcessing(bool isProcessing) { ui->username->setReadOnly(isProcessing); ui->password->setReadOnly(isProcessing); @@ -32,6 +48,9 @@ void StandardLoginWindow::on_loginButton_clicked() { return; } + settings::secureSave("username", username); + settings::secureSave("password", password); + emit performLogin(username, password); } diff --git a/GPClient/standardloginwindow.h b/GPClient/standardloginwindow.h index 92f5f5d..894e7e3 100644 --- a/GPClient/standardloginwindow.h +++ b/GPClient/standardloginwindow.h @@ -28,6 +28,7 @@ private: Ui::StandardLoginWindow *ui; void closeEvent(QCloseEvent *event); + void autocomplete(); }; #endif // STANDARDLOGINWINDOW_H