From 6352e1fb2b9a68455da398061b4e76475b894cb6 Mon Sep 17 00:00:00 2001 From: Kevin Yue Date: Sat, 21 Aug 2021 18:44:16 +0800 Subject: [PATCH] Make the `clientos` configurable and improve Reset Settings (#80) * Set the gateway * Make clientos configurable * Update readme.md * Update README.md --- GPClient/GPClient.pro | 2 + GPClient/gatewayauthenticator.cpp | 24 +++++++---- GPClient/gatewayauthenticator.h | 7 ++- GPClient/gatewayauthenticatorparams.cpp | 57 +++++++++++++++++++++++++ GPClient/gatewayauthenticatorparams.h | 33 ++++++++++++++ GPClient/gpclient.cpp | 10 ++++- GPClient/gphelper.cpp | 8 +++- GPClient/gphelper.h | 1 + GPClient/loginparams.cpp | 6 ++- GPClient/loginparams.h | 1 + GPClient/portalauthenticator.cpp | 7 ++- GPClient/portalauthenticator.h | 2 +- GPClient/portalconfigresponse.cpp | 26 +++++------ GPClient/portalconfigresponse.h | 14 +++--- GPClient/settingsdialog.cpp | 16 +++++-- GPClient/settingsdialog.h | 5 ++- GPClient/settingsdialog.ui | 32 +++++++++++--- README.md | 6 ++- 18 files changed, 205 insertions(+), 52 deletions(-) create mode 100644 GPClient/gatewayauthenticatorparams.cpp create mode 100644 GPClient/gatewayauthenticatorparams.h diff --git a/GPClient/GPClient.pro b/GPClient/GPClient.pro index 0be925e..ec6f90b 100644 --- a/GPClient/GPClient.pro +++ b/GPClient/GPClient.pro @@ -26,6 +26,7 @@ SOURCES += \ cdpcommandmanager.cpp \ enhancedwebview.cpp \ gatewayauthenticator.cpp \ + gatewayauthenticatorparams.cpp \ gpgateway.cpp \ gphelper.cpp \ loginparams.cpp \ @@ -43,6 +44,7 @@ HEADERS += \ cdpcommandmanager.h \ enhancedwebview.h \ gatewayauthenticator.h \ + gatewayauthenticatorparams.h \ gpgateway.h \ gphelper.h \ loginparams.h \ diff --git a/GPClient/gatewayauthenticator.cpp b/GPClient/gatewayauthenticator.cpp index 222af78..915a67b 100644 --- a/GPClient/gatewayauthenticator.cpp +++ b/GPClient/gatewayauthenticator.cpp @@ -8,12 +8,16 @@ using namespace gpclient::helper; -GatewayAuthenticator::GatewayAuthenticator(const QString& gateway, const PortalConfigResponse& portalConfig) +GatewayAuthenticator::GatewayAuthenticator(const QString& gateway, const GatewayAuthenticatorParams& params) : QObject() - , preloginUrl("https://" + gateway + "/ssl-vpn/prelogin.esp?tmp=tmp&kerberos-support=yes&ipv6-support=yes&clientVer=4100&clientos=Linux") + , gateway(gateway) + , params(params) + , preloginUrl("https://" + gateway + "/ssl-vpn/prelogin.esp?tmp=tmp&kerberos-support=yes&ipv6-support=yes&clientVer=4100") , loginUrl("https://" + gateway + "/ssl-vpn/login.esp") - , portalConfig(portalConfig) { + if (!params.clientos().isEmpty()) { + preloginUrl = preloginUrl + "&clientos=" + params.clientos(); + } } GatewayAuthenticator::~GatewayAuthenticator() @@ -25,12 +29,16 @@ void GatewayAuthenticator::authenticate() { PLOGI << "Start gateway authentication..."; - LoginParams params; - params.setUser(portalConfig.username()); - params.setPassword(portalConfig.password()); - params.setUserAuthCookie(portalConfig.userAuthCookie()); + LoginParams loginParams; + loginParams.setUser(params.username()); + loginParams.setPassword(params.password()); + loginParams.setUserAuthCookie(params.userAuthCookie()); - login(params); + if (!params.clientos().isEmpty()) { + loginParams.setClientos(params.clientos()); + } + + login(loginParams); } void GatewayAuthenticator::login(const LoginParams ¶ms) diff --git a/GPClient/gatewayauthenticator.h b/GPClient/gatewayauthenticator.h index 4c676fb..1cfddb9 100644 --- a/GPClient/gatewayauthenticator.h +++ b/GPClient/gatewayauthenticator.h @@ -1,16 +1,16 @@ #ifndef GATEWAYAUTHENTICATOR_H #define GATEWAYAUTHENTICATOR_H -#include "portalconfigresponse.h" #include "normalloginwindow.h" #include "loginparams.h" +#include "gatewayauthenticatorparams.h" #include class GatewayAuthenticator : public QObject { Q_OBJECT public: - explicit GatewayAuthenticator(const QString& gateway, const PortalConfigResponse& portalConfig); + explicit GatewayAuthenticator(const QString& gateway, const GatewayAuthenticatorParams& params); ~GatewayAuthenticator(); void authenticate(); @@ -30,11 +30,10 @@ private slots: private: QString gateway; + const GatewayAuthenticatorParams& params; QString preloginUrl; QString loginUrl; - const PortalConfigResponse& portalConfig; - NormalLoginWindow *normalLoginWindow{ nullptr }; void login(const LoginParams& params); diff --git a/GPClient/gatewayauthenticatorparams.cpp b/GPClient/gatewayauthenticatorparams.cpp new file mode 100644 index 0000000..4db1a74 --- /dev/null +++ b/GPClient/gatewayauthenticatorparams.cpp @@ -0,0 +1,57 @@ +#include "gatewayauthenticatorparams.h" + +GatewayAuthenticatorParams::GatewayAuthenticatorParams() +{ + +} + +GatewayAuthenticatorParams GatewayAuthenticatorParams::fromPortalConfigResponse(const PortalConfigResponse &portalConfig) +{ + GatewayAuthenticatorParams params; + params.setUsername(portalConfig.username()); + params.setPassword(portalConfig.password()); + params.setUserAuthCookie(portalConfig.userAuthCookie()); + + return params; +} + +const QString &GatewayAuthenticatorParams::username() const +{ + return m_username; +} + +void GatewayAuthenticatorParams::setUsername(const QString &newUsername) +{ + m_username = newUsername; +} + +const QString &GatewayAuthenticatorParams::password() const +{ + return m_password; +} + +void GatewayAuthenticatorParams::setPassword(const QString &newPassword) +{ + m_password = newPassword; +} + +const QString &GatewayAuthenticatorParams::userAuthCookie() const +{ + return m_userAuthCookie; +} + +void GatewayAuthenticatorParams::setUserAuthCookie(const QString &newUserAuthCookie) +{ + m_userAuthCookie = newUserAuthCookie; +} + +const QString &GatewayAuthenticatorParams::clientos() const +{ + return m_clientos; +} + +void GatewayAuthenticatorParams::setClientos(const QString &newClientos) +{ + m_clientos = newClientos; +} + diff --git a/GPClient/gatewayauthenticatorparams.h b/GPClient/gatewayauthenticatorparams.h new file mode 100644 index 0000000..cb25eae --- /dev/null +++ b/GPClient/gatewayauthenticatorparams.h @@ -0,0 +1,33 @@ +#ifndef GATEWAYAUTHENTICATORPARAMS_H +#define GATEWAYAUTHENTICATORPARAMS_H + +#include +#include "portalconfigresponse.h" + +class GatewayAuthenticatorParams +{ +public: + GatewayAuthenticatorParams(); + + static GatewayAuthenticatorParams fromPortalConfigResponse(const PortalConfigResponse &portalConfig); + + const QString &username() const; + void setUsername(const QString &newUsername); + + const QString &password() const; + void setPassword(const QString &newPassword); + + const QString &userAuthCookie() const; + void setUserAuthCookie(const QString &newUserAuthCookie); + + const QString &clientos() const; + void setClientos(const QString &newClientos); + +private: + QString m_username; + QString m_password; + QString m_userAuthCookie; + QString m_clientos; +}; + +#endif // GATEWAYAUTHENTICATORPARAMS_H diff --git a/GPClient/gpclient.cpp b/GPClient/gpclient.cpp index 89d36cd..f5cb42c 100644 --- a/GPClient/gpclient.cpp +++ b/GPClient/gpclient.cpp @@ -4,6 +4,7 @@ #include "portalauthenticator.h" #include "gatewayauthenticator.h" #include "settingsdialog.h" +#include "gatewayauthenticatorparams.h" #include #include @@ -66,12 +67,14 @@ void GPClient::setupSettings() void GPClient::onSettingsButtonClicked() { settingsDialog->setExtraArgs(settings::get("extraArgs", "").toString()); + settingsDialog->setClientos(settings::get("clientos", "").toString()); settingsDialog->show(); } void GPClient::onSettingsAccepted() { settings::save("extraArgs", settingsDialog->extraArgs()); + settings::save("clientos", settingsDialog->clientos()); } void GPClient::on_connectButton_clicked() @@ -274,7 +277,7 @@ void GPClient::doConnect() // Login to the portal interface to get the portal config and preferred gateway void GPClient::portalLogin() { - PortalAuthenticator *portalAuth = new PortalAuthenticator(portal()); + PortalAuthenticator *portalAuth = new PortalAuthenticator(portal(), settings::get("clientos", "").toString()); connect(portalAuth, &PortalAuthenticator::success, this, &GPClient::onPortalSuccess); // Prelogin failed on the portal interface, try to treat the portal as a gateway interface @@ -351,7 +354,10 @@ void GPClient::gatewayLogin() { PLOGI << "Performing gateway login..."; - GatewayAuthenticator *gatewayAuth = new GatewayAuthenticator(currentGateway().address(), portalConfig); + GatewayAuthenticatorParams params = GatewayAuthenticatorParams::fromPortalConfigResponse(portalConfig); + params.setClientos(settings::get("clientos", "").toString()); + + GatewayAuthenticator *gatewayAuth = new GatewayAuthenticator(currentGateway().address(), params); connect(gatewayAuth, &GatewayAuthenticator::success, this, &GPClient::onGatewaySuccess); connect(gatewayAuth, &GatewayAuthenticator::fail, this, &GPClient::onGatewayFail); diff --git a/GPClient/gphelper.cpp b/GPClient/gphelper.cpp index 63debcb..4b6b5bd 100644 --- a/GPClient/gphelper.cpp +++ b/GPClient/gphelper.cpp @@ -116,7 +116,13 @@ void gpclient::helper::settings::save(const QString &key, const QVariant &value) _settings->setValue(key, value); } + void gpclient::helper::settings::clear() { - _settings->clear(); + QStringList keys = _settings->allKeys(); + for (const auto &key : qAsConst(keys)) { + if (!reservedKeys.contains(key)) { + _settings->remove(key); + } + } } diff --git a/GPClient/gphelper.h b/GPClient/gphelper.h index 9d9664e..66aa63a 100644 --- a/GPClient/gphelper.h +++ b/GPClient/gphelper.h @@ -31,6 +31,7 @@ namespace gpclient { namespace settings { extern QSettings *_settings; + static const QStringList reservedKeys {"extraArgs", "clientos"}; QVariant get(const QString &key, const QVariant &defaultValue = QVariant()); void save(const QString &key, const QVariant &value); diff --git a/GPClient/loginparams.cpp b/GPClient/loginparams.cpp index 18c7112..be796d5 100644 --- a/GPClient/loginparams.cpp +++ b/GPClient/loginparams.cpp @@ -15,7 +15,6 @@ LoginParams::LoginParams() params.addQueryItem("direct", "yes"); params.addQueryItem("clientVer", "4100"); params.addQueryItem("os-version", QUrl::toPercentEncoding(QSysInfo::prettyProductName())); - params.addQueryItem("clientos", "Linux"); params.addQueryItem("portal-userauthcookie", ""); params.addQueryItem("portal-prelogonuserauthcookie", ""); params.addQueryItem("prelogin-cookie", ""); @@ -56,6 +55,11 @@ void LoginParams::setPreloginCookie(const QString cookie) updateQueryItem("prelogin-cookie", cookie); } +void LoginParams::setClientos(const QString clientos) +{ + updateQueryItem("clientos", clientos); +} + QByteArray LoginParams::toUtf8() const { return params.toString().toUtf8(); diff --git a/GPClient/loginparams.h b/GPClient/loginparams.h index 45277fe..b84d8fb 100644 --- a/GPClient/loginparams.h +++ b/GPClient/loginparams.h @@ -15,6 +15,7 @@ public: void setUserAuthCookie(const QString cookie); void setPrelogonAuthCookie(const QString cookie); void setPreloginCookie(const QString cookie); + void setClientos(const QString clientos); QByteArray toUtf8() const; diff --git a/GPClient/portalauthenticator.cpp b/GPClient/portalauthenticator.cpp index 450e3b9..21f560f 100644 --- a/GPClient/portalauthenticator.cpp +++ b/GPClient/portalauthenticator.cpp @@ -12,11 +12,14 @@ using namespace gpclient::helper; -PortalAuthenticator::PortalAuthenticator(const QString& portal) : QObject() +PortalAuthenticator::PortalAuthenticator(const QString& portal, const QString& clientos) : QObject() , portal(portal) - , preloginUrl("https://" + portal + "/global-protect/prelogin.esp?tmp=tmp&kerberos-support=yes&ipv6-support=yes&clientVer=4100&clientos=Linux") + , preloginUrl("https://" + portal + "/global-protect/prelogin.esp?tmp=tmp&kerberos-support=yes&ipv6-support=yes&clientVer=4100") , configUrl("https://" + portal + "/global-protect/getconfig.esp") { + if (!clientos.isEmpty()) { + preloginUrl = preloginUrl + "&clientos=" + clientos; + } } PortalAuthenticator::~PortalAuthenticator() diff --git a/GPClient/portalauthenticator.h b/GPClient/portalauthenticator.h index c74fa5f..5bebf5b 100644 --- a/GPClient/portalauthenticator.h +++ b/GPClient/portalauthenticator.h @@ -12,7 +12,7 @@ class PortalAuthenticator : public QObject { Q_OBJECT public: - explicit PortalAuthenticator(const QString& portal); + explicit PortalAuthenticator(const QString& portal, const QString& clientos); ~PortalAuthenticator(); void authenticate(); diff --git a/GPClient/portalconfigresponse.cpp b/GPClient/portalconfigresponse.cpp index 9db5c56..790056d 100644 --- a/GPClient/portalconfigresponse.cpp +++ b/GPClient/portalconfigresponse.cpp @@ -46,17 +46,17 @@ PortalConfigResponse PortalConfigResponse::parse(const QByteArray xml) const QByteArray PortalConfigResponse::rawResponse() const { - return _rawResponse; + return m_rawResponse; } -QString PortalConfigResponse::username() const +const QString &PortalConfigResponse::username() const { - return _username; + return m_username; } QString PortalConfigResponse::password() const { - return _password; + return m_password; } QList PortalConfigResponse::parseGateways(QXmlStreamReader &xmlReader) @@ -134,45 +134,45 @@ QString PortalConfigResponse::parseGatewayName(QXmlStreamReader &xmlReader) QString PortalConfigResponse::userAuthCookie() const { - return _userAuthCookie; + return m_userAuthCookie; } QString PortalConfigResponse::prelogonUserAuthCookie() const { - return _prelogonAuthCookie; + return m_prelogonAuthCookie; } QList PortalConfigResponse::allGateways() const { - return _gateways; + return m_gateways; } void PortalConfigResponse::setAllGateways(QList gateways) { - _gateways = gateways; + m_gateways = gateways; } void PortalConfigResponse::setRawResponse(const QByteArray response) { - _rawResponse = response; + m_rawResponse = response; } void PortalConfigResponse::setUsername(const QString username) { - _username = username; + m_username = username; } void PortalConfigResponse::setPassword(const QString password) { - _password = password; + m_password = password; } void PortalConfigResponse::setUserAuthCookie(const QString cookie) { - _userAuthCookie = cookie; + m_userAuthCookie = cookie; } void PortalConfigResponse::setPrelogonUserAuthCookie(const QString cookie) { - _prelogonAuthCookie = cookie; + m_prelogonAuthCookie = cookie; } diff --git a/GPClient/portalconfigresponse.h b/GPClient/portalconfigresponse.h index 2424daa..c79dae0 100644 --- a/GPClient/portalconfigresponse.h +++ b/GPClient/portalconfigresponse.h @@ -16,7 +16,7 @@ public: static PortalConfigResponse parse(const QByteArray xml); const QByteArray rawResponse() const; - QString username() const; + const QString &username() const; QString password() const; QString userAuthCookie() const; QString prelogonUserAuthCookie() const; @@ -31,13 +31,13 @@ private: static QString xmlPrelogonUserAuthCookie; static QString xmlGateways; - QByteArray _rawResponse; - QString _username; - QString _password; - QString _userAuthCookie; - QString _prelogonAuthCookie; + QByteArray m_rawResponse; + QString m_username; + QString m_password; + QString m_userAuthCookie; + QString m_prelogonAuthCookie; - QList _gateways; + QList m_gateways; void setRawResponse(const QByteArray response); void setUserAuthCookie(const QString cookie); diff --git a/GPClient/settingsdialog.cpp b/GPClient/settingsdialog.cpp index b36a729..e2e28d4 100644 --- a/GPClient/settingsdialog.cpp +++ b/GPClient/settingsdialog.cpp @@ -6,8 +6,6 @@ SettingsDialog::SettingsDialog(QWidget *parent) : ui(new Ui::SettingsDialog) { ui->setupUi(this); - - ui->extraArgsInput->setPlaceholderText("e.g. --name=value"); } SettingsDialog::~SettingsDialog() @@ -15,12 +13,22 @@ SettingsDialog::~SettingsDialog() delete ui; } -void SettingsDialog::setExtraArgs(QString args) +void SettingsDialog::setExtraArgs(QString extraArgs) { - ui->extraArgsInput->setPlainText(args); + ui->extraArgsInput->setPlainText(extraArgs); } QString SettingsDialog::extraArgs() { return ui->extraArgsInput->toPlainText().trimmed(); } + +void SettingsDialog::setClientos(QString clientos) +{ + ui->clientosInput->setText(clientos); +} + +QString SettingsDialog::clientos() +{ + return ui->clientosInput->text(); +} diff --git a/GPClient/settingsdialog.h b/GPClient/settingsdialog.h index 9208a9c..234db96 100644 --- a/GPClient/settingsdialog.h +++ b/GPClient/settingsdialog.h @@ -15,9 +15,12 @@ public: explicit SettingsDialog(QWidget *parent = nullptr); ~SettingsDialog(); - void setExtraArgs(QString); + void setExtraArgs(QString extraArgs); QString extraArgs(); + void setClientos(QString clientos); + QString clientos(); + private: Ui::SettingsDialog *ui; }; diff --git a/GPClient/settingsdialog.ui b/GPClient/settingsdialog.ui index b601d9e..4d140dc 100644 --- a/GPClient/settingsdialog.ui +++ b/GPClient/settingsdialog.ui @@ -6,8 +6,8 @@ 0 0 - 470 - 183 + 488 + 177 @@ -23,18 +23,36 @@ :/images/connected.png:/images/connected.png - - + + Custom Parameters: - - + + + + e.g. --name=value --script="vpn-slice xxx" + + - + + + + Value of "clientos": + + + + + + + e.g., Windows + + + + Qt::Horizontal diff --git a/README.md b/README.md index 480de06..045c8e6 100644 --- a/README.md +++ b/README.md @@ -22,8 +22,12 @@ A GlobalProtect VPN client (GUI) for Linux based on Openconnect and built with Q ## Passing the Custom Parameters to `OpenConnect` CLI Custom parameters can be appended to the `OpenConnect` CLI with the following settings. + +> Tokens with spaces can be surrounded by double quotes; three consecutive double quotes represent the quote character itself. + +

- +

## Prerequisites