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 \
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 \

View File

@ -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 &params)

View File

@ -1,16 +1,16 @@
#ifndef GATEWAYAUTHENTICATOR_H
#define GATEWAYAUTHENTICATOR_H
#include "portalconfigresponse.h"
#include "normalloginwindow.h"
#include "loginparams.h"
#include "gatewayauthenticatorparams.h"
#include <QObject>
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);

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 "gatewayauthenticator.h"
#include "settingsdialog.h"
#include "gatewayauthenticatorparams.h"
#include <plog/Log.h>
#include <QIcon>
@ -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);

View File

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

View File

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

View File

@ -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();

View File

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

View File

@ -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()

View File

@ -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();

View File

@ -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<GPGateway> 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<GPGateway> PortalConfigResponse::allGateways() const
{
return _gateways;
return m_gateways;
}
void PortalConfigResponse::setAllGateways(QList<GPGateway> 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;
}

View File

@ -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<GPGateway> _gateways;
QList<GPGateway> m_gateways;
void setRawResponse(const QByteArray response);
void setUserAuthCookie(const QString cookie);

View File

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

View File

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

View File

@ -6,8 +6,8 @@
<rect>
<x>0</x>
<y>0</y>
<width>470</width>
<height>183</height>
<width>488</width>
<height>177</height>
</rect>
</property>
<property name="sizePolicy">
@ -23,18 +23,36 @@
<iconset resource="resources.qrc">
<normaloff>:/images/connected.png</normaloff>:/images/connected.png</iconset>
</property>
<layout class="QVBoxLayout" name="verticalLayout">
<item>
<layout class="QFormLayout" name="formLayout_3">
<item row="0" column="0">
<widget class="QLabel" name="label">
<property name="text">
<string>Custom Parameters:</string>
</property>
</widget>
</item>
<item>
<widget class="QPlainTextEdit" name="extraArgsInput"/>
<item row="0" column="1">
<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 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">
<property name="orientation">
<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
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">
<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>
## Prerequisites