Make the clientos configurable and improve Reset Settings (#80)

* Set the gateway

* Make clientos configurable

* Update readme.md

* Update README.md
This commit is contained in:
Kevin Yue 2021-08-21 18:44:16 +08:00 committed by GitHub
parent 42cae3ff26
commit 6352e1fb2b
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
18 changed files with 205 additions and 52 deletions

View File

@ -26,6 +26,7 @@ SOURCES += \
cdpcommandmanager.cpp \ cdpcommandmanager.cpp \
enhancedwebview.cpp \ enhancedwebview.cpp \
gatewayauthenticator.cpp \ gatewayauthenticator.cpp \
gatewayauthenticatorparams.cpp \
gpgateway.cpp \ gpgateway.cpp \
gphelper.cpp \ gphelper.cpp \
loginparams.cpp \ loginparams.cpp \
@ -43,6 +44,7 @@ HEADERS += \
cdpcommandmanager.h \ cdpcommandmanager.h \
enhancedwebview.h \ enhancedwebview.h \
gatewayauthenticator.h \ gatewayauthenticator.h \
gatewayauthenticatorparams.h \
gpgateway.h \ gpgateway.h \
gphelper.h \ gphelper.h \
loginparams.h \ loginparams.h \

View File

@ -8,12 +8,16 @@
using namespace gpclient::helper; using namespace gpclient::helper;
GatewayAuthenticator::GatewayAuthenticator(const QString& gateway, const PortalConfigResponse& portalConfig) GatewayAuthenticator::GatewayAuthenticator(const QString& gateway, const GatewayAuthenticatorParams& params)
: QObject() : 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") , loginUrl("https://" + gateway + "/ssl-vpn/login.esp")
, portalConfig(portalConfig)
{ {
if (!params.clientos().isEmpty()) {
preloginUrl = preloginUrl + "&clientos=" + params.clientos();
}
} }
GatewayAuthenticator::~GatewayAuthenticator() GatewayAuthenticator::~GatewayAuthenticator()
@ -25,12 +29,16 @@ void GatewayAuthenticator::authenticate()
{ {
PLOGI << "Start gateway authentication..."; PLOGI << "Start gateway authentication...";
LoginParams params; LoginParams loginParams;
params.setUser(portalConfig.username()); loginParams.setUser(params.username());
params.setPassword(portalConfig.password()); loginParams.setPassword(params.password());
params.setUserAuthCookie(portalConfig.userAuthCookie()); loginParams.setUserAuthCookie(params.userAuthCookie());
login(params); if (!params.clientos().isEmpty()) {
loginParams.setClientos(params.clientos());
}
login(loginParams);
} }
void GatewayAuthenticator::login(const LoginParams &params) void GatewayAuthenticator::login(const LoginParams &params)

View File

@ -1,16 +1,16 @@
#ifndef GATEWAYAUTHENTICATOR_H #ifndef GATEWAYAUTHENTICATOR_H
#define GATEWAYAUTHENTICATOR_H #define GATEWAYAUTHENTICATOR_H
#include "portalconfigresponse.h"
#include "normalloginwindow.h" #include "normalloginwindow.h"
#include "loginparams.h" #include "loginparams.h"
#include "gatewayauthenticatorparams.h"
#include <QObject> #include <QObject>
class GatewayAuthenticator : public QObject class GatewayAuthenticator : public QObject
{ {
Q_OBJECT Q_OBJECT
public: public:
explicit GatewayAuthenticator(const QString& gateway, const PortalConfigResponse& portalConfig); explicit GatewayAuthenticator(const QString& gateway, const GatewayAuthenticatorParams& params);
~GatewayAuthenticator(); ~GatewayAuthenticator();
void authenticate(); void authenticate();
@ -30,11 +30,10 @@ private slots:
private: private:
QString gateway; QString gateway;
const GatewayAuthenticatorParams& params;
QString preloginUrl; QString preloginUrl;
QString loginUrl; QString loginUrl;
const PortalConfigResponse& portalConfig;
NormalLoginWindow *normalLoginWindow{ nullptr }; NormalLoginWindow *normalLoginWindow{ nullptr };
void login(const LoginParams& params); void login(const LoginParams& params);

View File

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

View File

@ -0,0 +1,33 @@
#ifndef GATEWAYAUTHENTICATORPARAMS_H
#define GATEWAYAUTHENTICATORPARAMS_H
#include <QString>
#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

View File

@ -4,6 +4,7 @@
#include "portalauthenticator.h" #include "portalauthenticator.h"
#include "gatewayauthenticator.h" #include "gatewayauthenticator.h"
#include "settingsdialog.h" #include "settingsdialog.h"
#include "gatewayauthenticatorparams.h"
#include <plog/Log.h> #include <plog/Log.h>
#include <QIcon> #include <QIcon>
@ -66,12 +67,14 @@ void GPClient::setupSettings()
void GPClient::onSettingsButtonClicked() void GPClient::onSettingsButtonClicked()
{ {
settingsDialog->setExtraArgs(settings::get("extraArgs", "").toString()); settingsDialog->setExtraArgs(settings::get("extraArgs", "").toString());
settingsDialog->setClientos(settings::get("clientos", "").toString());
settingsDialog->show(); settingsDialog->show();
} }
void GPClient::onSettingsAccepted() void GPClient::onSettingsAccepted()
{ {
settings::save("extraArgs", settingsDialog->extraArgs()); settings::save("extraArgs", settingsDialog->extraArgs());
settings::save("clientos", settingsDialog->clientos());
} }
void GPClient::on_connectButton_clicked() 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 // Login to the portal interface to get the portal config and preferred gateway
void GPClient::portalLogin() void GPClient::portalLogin()
{ {
PortalAuthenticator *portalAuth = new PortalAuthenticator(portal()); PortalAuthenticator *portalAuth = new PortalAuthenticator(portal(), settings::get("clientos", "").toString());
connect(portalAuth, &PortalAuthenticator::success, this, &GPClient::onPortalSuccess); connect(portalAuth, &PortalAuthenticator::success, this, &GPClient::onPortalSuccess);
// Prelogin failed on the portal interface, try to treat the portal as a gateway interface // 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..."; 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::success, this, &GPClient::onGatewaySuccess);
connect(gatewayAuth, &GatewayAuthenticator::fail, this, &GPClient::onGatewayFail); connect(gatewayAuth, &GatewayAuthenticator::fail, this, &GPClient::onGatewayFail);

View File

@ -116,7 +116,13 @@ void gpclient::helper::settings::save(const QString &key, const QVariant &value)
_settings->setValue(key, value); _settings->setValue(key, value);
} }
void gpclient::helper::settings::clear() void gpclient::helper::settings::clear()
{ {
_settings->clear(); QStringList keys = _settings->allKeys();
for (const auto &key : qAsConst(keys)) {
if (!reservedKeys.contains(key)) {
_settings->remove(key);
}
}
} }

View File

@ -31,6 +31,7 @@ namespace gpclient {
namespace settings { namespace settings {
extern QSettings *_settings; extern QSettings *_settings;
static const QStringList reservedKeys {"extraArgs", "clientos"};
QVariant get(const QString &key, const QVariant &defaultValue = QVariant()); QVariant get(const QString &key, const QVariant &defaultValue = QVariant());
void save(const QString &key, const QVariant &value); void save(const QString &key, const QVariant &value);

View File

@ -15,7 +15,6 @@ LoginParams::LoginParams()
params.addQueryItem("direct", "yes"); params.addQueryItem("direct", "yes");
params.addQueryItem("clientVer", "4100"); params.addQueryItem("clientVer", "4100");
params.addQueryItem("os-version", QUrl::toPercentEncoding(QSysInfo::prettyProductName())); params.addQueryItem("os-version", QUrl::toPercentEncoding(QSysInfo::prettyProductName()));
params.addQueryItem("clientos", "Linux");
params.addQueryItem("portal-userauthcookie", ""); params.addQueryItem("portal-userauthcookie", "");
params.addQueryItem("portal-prelogonuserauthcookie", ""); params.addQueryItem("portal-prelogonuserauthcookie", "");
params.addQueryItem("prelogin-cookie", ""); params.addQueryItem("prelogin-cookie", "");
@ -56,6 +55,11 @@ void LoginParams::setPreloginCookie(const QString cookie)
updateQueryItem("prelogin-cookie", cookie); updateQueryItem("prelogin-cookie", cookie);
} }
void LoginParams::setClientos(const QString clientos)
{
updateQueryItem("clientos", clientos);
}
QByteArray LoginParams::toUtf8() const QByteArray LoginParams::toUtf8() const
{ {
return params.toString().toUtf8(); return params.toString().toUtf8();

View File

@ -15,6 +15,7 @@ public:
void setUserAuthCookie(const QString cookie); void setUserAuthCookie(const QString cookie);
void setPrelogonAuthCookie(const QString cookie); void setPrelogonAuthCookie(const QString cookie);
void setPreloginCookie(const QString cookie); void setPreloginCookie(const QString cookie);
void setClientos(const QString clientos);
QByteArray toUtf8() const; QByteArray toUtf8() const;

View File

@ -12,11 +12,14 @@
using namespace gpclient::helper; using namespace gpclient::helper;
PortalAuthenticator::PortalAuthenticator(const QString& portal) : QObject() PortalAuthenticator::PortalAuthenticator(const QString& portal, const QString& clientos) : QObject()
, portal(portal) , 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") , configUrl("https://" + portal + "/global-protect/getconfig.esp")
{ {
if (!clientos.isEmpty()) {
preloginUrl = preloginUrl + "&clientos=" + clientos;
}
} }
PortalAuthenticator::~PortalAuthenticator() PortalAuthenticator::~PortalAuthenticator()

View File

@ -12,7 +12,7 @@ class PortalAuthenticator : public QObject
{ {
Q_OBJECT Q_OBJECT
public: public:
explicit PortalAuthenticator(const QString& portal); explicit PortalAuthenticator(const QString& portal, const QString& clientos);
~PortalAuthenticator(); ~PortalAuthenticator();
void authenticate(); void authenticate();

View File

@ -46,17 +46,17 @@ PortalConfigResponse PortalConfigResponse::parse(const QByteArray xml)
const QByteArray PortalConfigResponse::rawResponse() const 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 QString PortalConfigResponse::password() const
{ {
return _password; return m_password;
} }
QList<GPGateway> PortalConfigResponse::parseGateways(QXmlStreamReader &xmlReader) QList<GPGateway> PortalConfigResponse::parseGateways(QXmlStreamReader &xmlReader)
@ -134,45 +134,45 @@ QString PortalConfigResponse::parseGatewayName(QXmlStreamReader &xmlReader)
QString PortalConfigResponse::userAuthCookie() const QString PortalConfigResponse::userAuthCookie() const
{ {
return _userAuthCookie; return m_userAuthCookie;
} }
QString PortalConfigResponse::prelogonUserAuthCookie() const QString PortalConfigResponse::prelogonUserAuthCookie() const
{ {
return _prelogonAuthCookie; return m_prelogonAuthCookie;
} }
QList<GPGateway> PortalConfigResponse::allGateways() const QList<GPGateway> PortalConfigResponse::allGateways() const
{ {
return _gateways; return m_gateways;
} }
void PortalConfigResponse::setAllGateways(QList<GPGateway> gateways) void PortalConfigResponse::setAllGateways(QList<GPGateway> gateways)
{ {
_gateways = gateways; m_gateways = gateways;
} }
void PortalConfigResponse::setRawResponse(const QByteArray response) void PortalConfigResponse::setRawResponse(const QByteArray response)
{ {
_rawResponse = response; m_rawResponse = response;
} }
void PortalConfigResponse::setUsername(const QString username) void PortalConfigResponse::setUsername(const QString username)
{ {
_username = username; m_username = username;
} }
void PortalConfigResponse::setPassword(const QString password) void PortalConfigResponse::setPassword(const QString password)
{ {
_password = password; m_password = password;
} }
void PortalConfigResponse::setUserAuthCookie(const QString cookie) void PortalConfigResponse::setUserAuthCookie(const QString cookie)
{ {
_userAuthCookie = cookie; m_userAuthCookie = cookie;
} }
void PortalConfigResponse::setPrelogonUserAuthCookie(const QString cookie) void PortalConfigResponse::setPrelogonUserAuthCookie(const QString cookie)
{ {
_prelogonAuthCookie = cookie; m_prelogonAuthCookie = cookie;
} }

View File

@ -16,7 +16,7 @@ public:
static PortalConfigResponse parse(const QByteArray xml); static PortalConfigResponse parse(const QByteArray xml);
const QByteArray rawResponse() const; const QByteArray rawResponse() const;
QString username() const; const QString &username() const;
QString password() const; QString password() const;
QString userAuthCookie() const; QString userAuthCookie() const;
QString prelogonUserAuthCookie() const; QString prelogonUserAuthCookie() const;
@ -31,13 +31,13 @@ private:
static QString xmlPrelogonUserAuthCookie; static QString xmlPrelogonUserAuthCookie;
static QString xmlGateways; static QString xmlGateways;
QByteArray _rawResponse; QByteArray m_rawResponse;
QString _username; QString m_username;
QString _password; QString m_password;
QString _userAuthCookie; QString m_userAuthCookie;
QString _prelogonAuthCookie; QString m_prelogonAuthCookie;
QList<GPGateway> _gateways; QList<GPGateway> m_gateways;
void setRawResponse(const QByteArray response); void setRawResponse(const QByteArray response);
void setUserAuthCookie(const QString cookie); void setUserAuthCookie(const QString cookie);

View File

@ -6,8 +6,6 @@ SettingsDialog::SettingsDialog(QWidget *parent) :
ui(new Ui::SettingsDialog) ui(new Ui::SettingsDialog)
{ {
ui->setupUi(this); ui->setupUi(this);
ui->extraArgsInput->setPlaceholderText("e.g. --name=value");
} }
SettingsDialog::~SettingsDialog() SettingsDialog::~SettingsDialog()
@ -15,12 +13,22 @@ SettingsDialog::~SettingsDialog()
delete ui; delete ui;
} }
void SettingsDialog::setExtraArgs(QString args) void SettingsDialog::setExtraArgs(QString extraArgs)
{ {
ui->extraArgsInput->setPlainText(args); ui->extraArgsInput->setPlainText(extraArgs);
} }
QString SettingsDialog::extraArgs() QString SettingsDialog::extraArgs()
{ {
return ui->extraArgsInput->toPlainText().trimmed(); return ui->extraArgsInput->toPlainText().trimmed();
} }
void SettingsDialog::setClientos(QString clientos)
{
ui->clientosInput->setText(clientos);
}
QString SettingsDialog::clientos()
{
return ui->clientosInput->text();
}

View File

@ -15,9 +15,12 @@ public:
explicit SettingsDialog(QWidget *parent = nullptr); explicit SettingsDialog(QWidget *parent = nullptr);
~SettingsDialog(); ~SettingsDialog();
void setExtraArgs(QString); void setExtraArgs(QString extraArgs);
QString extraArgs(); QString extraArgs();
void setClientos(QString clientos);
QString clientos();
private: private:
Ui::SettingsDialog *ui; Ui::SettingsDialog *ui;
}; };

View File

@ -6,8 +6,8 @@
<rect> <rect>
<x>0</x> <x>0</x>
<y>0</y> <y>0</y>
<width>470</width> <width>488</width>
<height>183</height> <height>177</height>
</rect> </rect>
</property> </property>
<property name="sizePolicy"> <property name="sizePolicy">
@ -23,18 +23,36 @@
<iconset resource="resources.qrc"> <iconset resource="resources.qrc">
<normaloff>:/images/connected.png</normaloff>:/images/connected.png</iconset> <normaloff>:/images/connected.png</normaloff>:/images/connected.png</iconset>
</property> </property>
<layout class="QVBoxLayout" name="verticalLayout"> <layout class="QFormLayout" name="formLayout_3">
<item> <item row="0" column="0">
<widget class="QLabel" name="label"> <widget class="QLabel" name="label">
<property name="text"> <property name="text">
<string>Custom Parameters:</string> <string>Custom Parameters:</string>
</property> </property>
</widget> </widget>
</item> </item>
<item> <item row="0" column="1">
<widget class="QPlainTextEdit" name="extraArgsInput"/> <widget class="QPlainTextEdit" name="extraArgsInput">
<property name="placeholderText">
<string extracomment="Tokens with spaces can be surrounded by double quotes">e.g. --name=value --script=&quot;vpn-slice xxx&quot;</string>
</property>
</widget>
</item> </item>
<item> <item row="1" column="0">
<widget class="QLabel" name="label_2">
<property name="text">
<string>Value of &quot;clientos&quot;:</string>
</property>
</widget>
</item>
<item row="1" column="1">
<widget class="QLineEdit" name="clientosInput">
<property name="placeholderText">
<string>e.g., Windows</string>
</property>
</widget>
</item>
<item row="2" column="1">
<widget class="QDialogButtonBox" name="buttonBox"> <widget class="QDialogButtonBox" name="buttonBox">
<property name="orientation"> <property name="orientation">
<enum>Qt::Horizontal</enum> <enum>Qt::Horizontal</enum>

View File

@ -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 ## Passing the Custom Parameters to `OpenConnect` CLI
Custom parameters can be appended to the `OpenConnect` CLI with the following settings. 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.
<p align="center"> <p align="center">
<img src="https://user-images.githubusercontent.com/3297602/129464304-94eb8a2b-1c4a-47e1-b931-4422fff6eb81.png" /> <img src="https://user-images.githubusercontent.com/3297602/130319209-744be02b-d657-4f49-a76d-d2c81b5c46d5.png" />
<p> <p>
## Prerequisites ## Prerequisites