mirror of
https://github.com/yuezk/GlobalProtect-openconnect.git
synced 2025-05-20 07:26:58 -04:00
Compare commits
58 Commits
Author | SHA1 | Date | |
---|---|---|---|
|
64e6487e7e | ||
|
e8b2c1606f | ||
|
84f1480653 | ||
|
3175855122 | ||
|
fa8b5c1528 | ||
|
7b9942c7e6 | ||
|
011a1a0dec | ||
|
4a53033023 | ||
|
9c6ea1c4b5 | ||
|
3369ad4c1d | ||
|
25c9f2291a | ||
|
bba3bc7e4f | ||
|
b12b692090 | ||
|
1300a0cc43 | ||
|
165080b476 | ||
|
d6af8a1598 | ||
|
eef92b1d31 | ||
|
946ead24a4 | ||
|
39e57c8598 | ||
|
4e2e423c27 | ||
|
732a62f1ee | ||
|
9f9444a72b | ||
|
6352e1fb2b | ||
|
42cae3ff26 | ||
|
53c8572cf6 | ||
|
3f6467321f | ||
|
563ec48c8c | ||
|
3787ae164c | ||
|
04a24c34e8 | ||
|
fe68248b1f | ||
|
47013033ec | ||
|
05fb9a26bd | ||
|
96962f957c | ||
|
b4f9cfae67 | ||
|
c8942984a8 | ||
|
3907827d0e | ||
|
f089996cdc | ||
|
260b557238 | ||
|
3495dbfe18 | ||
|
cdf193024c | ||
|
76de070d78 | ||
|
420ae27888 | ||
|
6a347746cc | ||
|
624babb380 | ||
|
511b20fdcd | ||
|
abe33c7407 | ||
|
99a82c8641 | ||
|
e5d0acad3c | ||
|
38a1eded19 | ||
|
3e23e7eaae | ||
|
cf46848e63 | ||
|
2e826201d2 | ||
|
adba408dc3 | ||
|
5d613369ee | ||
|
ebd3de6f63 | ||
|
266ab65892 | ||
|
ccaf93ec31 | ||
|
e08d7d7c4d |
30
.github/workflows/main.yml
vendored
Normal file
30
.github/workflows/main.yml
vendored
Normal file
@@ -0,0 +1,30 @@
|
|||||||
|
name: Build
|
||||||
|
|
||||||
|
on:
|
||||||
|
push:
|
||||||
|
branches: [ master ]
|
||||||
|
pull_request:
|
||||||
|
branches: [ master ]
|
||||||
|
workflow_dispatch:
|
||||||
|
|
||||||
|
# A workflow run is made up of one or more jobs that can run sequentially or in parallel
|
||||||
|
jobs:
|
||||||
|
build:
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
|
||||||
|
steps:
|
||||||
|
- name: Install Qt
|
||||||
|
uses: jurplel/install-qt-action@v2
|
||||||
|
with:
|
||||||
|
version: 5.12.11
|
||||||
|
modules: 'qtwebengine qtwebsockets'
|
||||||
|
|
||||||
|
# Checkout repository and submodules
|
||||||
|
- uses: actions/checkout@v2
|
||||||
|
with:
|
||||||
|
submodules: recursive
|
||||||
|
|
||||||
|
- name: Build
|
||||||
|
run: |
|
||||||
|
qmake CONFIG+=release
|
||||||
|
make
|
60
.github/workflows/pre-release.yml
vendored
Normal file
60
.github/workflows/pre-release.yml
vendored
Normal file
@@ -0,0 +1,60 @@
|
|||||||
|
name: Pre Release
|
||||||
|
|
||||||
|
on:
|
||||||
|
workflow_dispatch:
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
pre-release:
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
if: ${{ github.event.workflow_run.conclusion == 'success' }}
|
||||||
|
env:
|
||||||
|
DEBFULLNAME: "Kevin Yue"
|
||||||
|
DEBEMAIL: "yuezk001@gmail.com"
|
||||||
|
|
||||||
|
steps:
|
||||||
|
# Checkout repository and submodules
|
||||||
|
- uses: actions/checkout@v2
|
||||||
|
with:
|
||||||
|
submodules: recursive
|
||||||
|
fetch-depth: 0
|
||||||
|
|
||||||
|
- name: Init variables
|
||||||
|
id: vars
|
||||||
|
run: |
|
||||||
|
TAG=$(git tag --sort=-v:refname --list "v[0-9]*" | head -n 1 | cut -c 2-)
|
||||||
|
echo ::set-output name=VERSION::"${TAG}+SNAPSHOT$(date -u +"%Y%m%d%H%M%S")"
|
||||||
|
echo ::set-output name=TAG::${TAG}
|
||||||
|
|
||||||
|
- name: Update debian/changelog
|
||||||
|
run: |
|
||||||
|
sudo apt install devscripts
|
||||||
|
git log --format="%s" v${{ steps.vars.outputs.TAG }}.. | xargs -L1 dch -v ${{ steps.vars.outputs.VERSION }}-1ppa1
|
||||||
|
|
||||||
|
- name: "Archive all"
|
||||||
|
run: |
|
||||||
|
python -m pip install --upgrade pip
|
||||||
|
pip install git-archive-all
|
||||||
|
git-archive-all \
|
||||||
|
--force-submodules \
|
||||||
|
--prefix=globalprotect-openconnect-${{ steps.vars.outputs.VERSION }}/ \
|
||||||
|
./globalprotect-openconnect-${{ steps.vars.outputs.VERSION }}.full.tar.gz
|
||||||
|
|
||||||
|
- name: "Debian Packaging"
|
||||||
|
run: |
|
||||||
|
sudo apt update
|
||||||
|
sudo apt install qtbase5-dev libqt5websockets5-dev qtwebengine5-dev qttools5-dev debhelper
|
||||||
|
mkdir build-debian && cd build-debian
|
||||||
|
cp ../*.tar.gz globalprotect-openconnect_${{ steps.vars.outputs.VERSION }}.orig.tar.gz
|
||||||
|
tar xf *.tar.gz
|
||||||
|
cd globalprotect-openconnect-${{ steps.vars.outputs.VERSION }}
|
||||||
|
fakeroot dpkg-buildpackage -uc -us -sa
|
||||||
|
|
||||||
|
- uses: "marvinpinto/action-automatic-releases@latest"
|
||||||
|
with:
|
||||||
|
repo_token: "${{ secrets.GITHUB_TOKEN }}"
|
||||||
|
automatic_release_tag: "latest"
|
||||||
|
prerelease: true
|
||||||
|
title: "globalprotect-openconnect_${{ steps.vars.outputs.VERSION }}"
|
||||||
|
files: |
|
||||||
|
*.tar.gz
|
||||||
|
build-debian/*.deb
|
61
.github/workflows/publish.yml
vendored
Normal file
61
.github/workflows/publish.yml
vendored
Normal file
@@ -0,0 +1,61 @@
|
|||||||
|
name: Publish
|
||||||
|
|
||||||
|
on:
|
||||||
|
workflow_dispatch:
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
build:
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
|
||||||
|
steps:
|
||||||
|
- name: Install Qt
|
||||||
|
uses: jurplel/install-qt-action@v2
|
||||||
|
with:
|
||||||
|
version: 5.12.11
|
||||||
|
modules: 'qtwebengine qtwebsockets'
|
||||||
|
|
||||||
|
# Checkout repository and submodules
|
||||||
|
- uses: actions/checkout@v2
|
||||||
|
with:
|
||||||
|
submodules: recursive
|
||||||
|
|
||||||
|
- name: Build
|
||||||
|
run: |
|
||||||
|
qmake CONFIG+=release
|
||||||
|
make
|
||||||
|
|
||||||
|
aur-publish:
|
||||||
|
needs:
|
||||||
|
- build
|
||||||
|
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
|
||||||
|
steps:
|
||||||
|
- uses: actions/checkout@v2
|
||||||
|
with:
|
||||||
|
fetch-depth: 0
|
||||||
|
|
||||||
|
- name: Get latest version
|
||||||
|
id: get-version
|
||||||
|
run: |
|
||||||
|
echo ::set-output name=VERSION::$(git tag --sort=-v:refname --list "v[0-9]*" | head -n 1 | cut -c 2-)
|
||||||
|
|
||||||
|
- name: Get the sha256sum
|
||||||
|
id: get-sha256sum
|
||||||
|
run: |
|
||||||
|
echo ::set-output name=SHA::$(curl -L https://github.com/yuezk/GlobalProtect-openconnect/archive/refs/tags/v${{ steps.get-version.outputs.VERSION }}.tar.gz | sha256sum | cut -f1 -d" ")
|
||||||
|
|
||||||
|
- name: Generate PKGBUILD
|
||||||
|
run: |
|
||||||
|
sed "s/{PKG_VERSION}/${{ steps.get-version.outputs.VERSION }}/g;s/{SOURCE_SHA}/${{ steps.get-sha256sum.outputs.SHA }}/g" PKGBUILD.template > PKGBUILD
|
||||||
|
|
||||||
|
- name: Publish AUR package
|
||||||
|
uses: KSXGitHub/github-actions-deploy-aur@v2.2.4
|
||||||
|
with:
|
||||||
|
pkgname: globalprotect-openconnect
|
||||||
|
pkgbuild: ./PKGBUILD
|
||||||
|
commit_username: ${{ secrets.AUR_USERNAME }}
|
||||||
|
commit_email: ${{ secrets.AUR_EMAIL }}
|
||||||
|
ssh_private_key: ${{ secrets.AUR_SSH_PRIVATE_KEY }}
|
||||||
|
commit_message: 'Release v${{ steps.get-version.outputs.VERSION }}'
|
||||||
|
force_push: true
|
7
.gitignore
vendored
7
.gitignore
vendored
@@ -2,10 +2,17 @@
|
|||||||
gpclient
|
gpclient
|
||||||
gpservice
|
gpservice
|
||||||
|
|
||||||
|
*.rpm
|
||||||
|
*.gz
|
||||||
|
.DS_Store
|
||||||
|
build-debian
|
||||||
|
|
||||||
# Auto generated DBus files
|
# Auto generated DBus files
|
||||||
*_adaptor.cpp
|
*_adaptor.cpp
|
||||||
*_adaptor.h
|
*_adaptor.h
|
||||||
|
|
||||||
|
gpservice_interface.*
|
||||||
|
|
||||||
# C++ objects and libs
|
# C++ objects and libs
|
||||||
*.slo
|
*.slo
|
||||||
*.lo
|
*.lo
|
||||||
|
@@ -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 \
|
||||||
@@ -35,13 +36,15 @@ SOURCES += \
|
|||||||
portalconfigresponse.cpp \
|
portalconfigresponse.cpp \
|
||||||
preloginresponse.cpp \
|
preloginresponse.cpp \
|
||||||
samlloginwindow.cpp \
|
samlloginwindow.cpp \
|
||||||
gpclient.cpp
|
gpclient.cpp \
|
||||||
|
settingsdialog.cpp
|
||||||
|
|
||||||
HEADERS += \
|
HEADERS += \
|
||||||
cdpcommand.h \
|
cdpcommand.h \
|
||||||
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 \
|
||||||
@@ -50,11 +53,13 @@ HEADERS += \
|
|||||||
portalconfigresponse.h \
|
portalconfigresponse.h \
|
||||||
preloginresponse.h \
|
preloginresponse.h \
|
||||||
samlloginwindow.h \
|
samlloginwindow.h \
|
||||||
gpclient.h
|
gpclient.h \
|
||||||
|
settingsdialog.h
|
||||||
|
|
||||||
FORMS += \
|
FORMS += \
|
||||||
gpclient.ui \
|
gpclient.ui \
|
||||||
normalloginwindow.ui
|
normalloginwindow.ui \
|
||||||
|
settingsdialog.ui
|
||||||
|
|
||||||
DBUS_INTERFACES += ../GPService/gpservice.xml
|
DBUS_INTERFACES += ../GPService/gpservice.xml
|
||||||
|
|
||||||
|
@@ -8,3 +8,4 @@ Exec=/usr/bin/gpclient
|
|||||||
Icon=com.yuezk.qt.GPClient
|
Icon=com.yuezk.qt.GPClient
|
||||||
Categories=Network;VPN;Utility;Qt;
|
Categories=Network;VPN;Utility;Qt;
|
||||||
Keywords=GlobalProtect;Openconnect;SAML;connection;VPN;
|
Keywords=GlobalProtect;Openconnect;SAML;connection;VPN;
|
||||||
|
StartupWMClass=gpclient
|
||||||
|
@@ -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 ¶ms)
|
void GatewayAuthenticator::login(const LoginParams ¶ms)
|
||||||
@@ -44,8 +52,9 @@ void GatewayAuthenticator::login(const LoginParams ¶ms)
|
|||||||
void GatewayAuthenticator::onLoginFinished()
|
void GatewayAuthenticator::onLoginFinished()
|
||||||
{
|
{
|
||||||
QNetworkReply *reply = qobject_cast<QNetworkReply*>(sender());
|
QNetworkReply *reply = qobject_cast<QNetworkReply*>(sender());
|
||||||
|
QByteArray response;
|
||||||
|
|
||||||
if (reply->error()) {
|
if (reply->error() || (response = reply->readAll()).contains("Authentication failure")) {
|
||||||
PLOGE << QString("Failed to login the gateway at %1, %2").arg(loginUrl).arg(reply->errorString());
|
PLOGE << QString("Failed to login the gateway at %1, %2").arg(loginUrl).arg(reply->errorString());
|
||||||
|
|
||||||
if (normalLoginWindow) {
|
if (normalLoginWindow) {
|
||||||
@@ -61,7 +70,7 @@ void GatewayAuthenticator::onLoginFinished()
|
|||||||
normalLoginWindow->close();
|
normalLoginWindow->close();
|
||||||
}
|
}
|
||||||
|
|
||||||
const QUrlQuery params = gpclient::helper::parseGatewayResponse(reply->readAll());
|
const QUrlQuery params = gpclient::helper::parseGatewayResponse(response);
|
||||||
emit success(params.toString());
|
emit success(params.toString());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -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);
|
||||||
|
57
GPClient/gatewayauthenticatorparams.cpp
Normal file
57
GPClient/gatewayauthenticatorparams.cpp
Normal 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;
|
||||||
|
}
|
||||||
|
|
33
GPClient/gatewayauthenticatorparams.h
Normal file
33
GPClient/gatewayauthenticatorparams.h
Normal 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
|
@@ -3,6 +3,8 @@
|
|||||||
#include "ui_gpclient.h"
|
#include "ui_gpclient.h"
|
||||||
#include "portalauthenticator.h"
|
#include "portalauthenticator.h"
|
||||||
#include "gatewayauthenticator.h"
|
#include "gatewayauthenticator.h"
|
||||||
|
#include "settingsdialog.h"
|
||||||
|
#include "gatewayauthenticatorparams.h"
|
||||||
|
|
||||||
#include <plog/Log.h>
|
#include <plog/Log.h>
|
||||||
#include <QIcon>
|
#include <QIcon>
|
||||||
@@ -12,12 +14,16 @@ using namespace gpclient::helper;
|
|||||||
GPClient::GPClient(QWidget *parent)
|
GPClient::GPClient(QWidget *parent)
|
||||||
: QMainWindow(parent)
|
: QMainWindow(parent)
|
||||||
, ui(new Ui::GPClient)
|
, ui(new Ui::GPClient)
|
||||||
|
, settingsDialog(new SettingsDialog(this))
|
||||||
{
|
{
|
||||||
ui->setupUi(this);
|
ui->setupUi(this);
|
||||||
|
|
||||||
setWindowTitle("GlobalProtect");
|
setWindowTitle("GlobalProtect");
|
||||||
setFixedSize(width(), height());
|
setFixedSize(width(), height());
|
||||||
gpclient::helper::moveCenter(this);
|
gpclient::helper::moveCenter(this);
|
||||||
|
|
||||||
|
setupSettings();
|
||||||
|
|
||||||
// Restore portal from the previous settings
|
// Restore portal from the previous settings
|
||||||
ui->portalInput->setText(settings::get("portal", "").toString());
|
ui->portalInput->setText(settings::get("portal", "").toString());
|
||||||
|
|
||||||
@@ -25,6 +31,7 @@ GPClient::GPClient(QWidget *parent)
|
|||||||
vpn = new com::yuezk::qt::GPService("com.yuezk.qt.GPService", "/", QDBusConnection::systemBus(), this);
|
vpn = new com::yuezk::qt::GPService("com.yuezk.qt.GPService", "/", QDBusConnection::systemBus(), this);
|
||||||
connect(vpn, &com::yuezk::qt::GPService::connected, this, &GPClient::onVPNConnected);
|
connect(vpn, &com::yuezk::qt::GPService::connected, this, &GPClient::onVPNConnected);
|
||||||
connect(vpn, &com::yuezk::qt::GPService::disconnected, this, &GPClient::onVPNDisconnected);
|
connect(vpn, &com::yuezk::qt::GPService::disconnected, this, &GPClient::onVPNDisconnected);
|
||||||
|
connect(vpn, &com::yuezk::qt::GPService::error, this, &GPClient::onVPNError);
|
||||||
connect(vpn, &com::yuezk::qt::GPService::logAvailable, this, &GPClient::onVPNLogAvailable);
|
connect(vpn, &com::yuezk::qt::GPService::logAvailable, this, &GPClient::onVPNLogAvailable);
|
||||||
|
|
||||||
// Initiallize the context menu of system tray.
|
// Initiallize the context menu of system tray.
|
||||||
@@ -36,6 +43,39 @@ GPClient::~GPClient()
|
|||||||
{
|
{
|
||||||
delete ui;
|
delete ui;
|
||||||
delete vpn;
|
delete vpn;
|
||||||
|
delete settingsDialog;
|
||||||
|
delete settingsButton;
|
||||||
|
}
|
||||||
|
|
||||||
|
void GPClient::setupSettings()
|
||||||
|
{
|
||||||
|
settingsButton = new QPushButton(this);
|
||||||
|
settingsButton->setIcon(QIcon(":/images/settings_icon.png"));
|
||||||
|
settingsButton->setFixedSize(QSize(28, 28));
|
||||||
|
|
||||||
|
QRect rect = this->geometry();
|
||||||
|
settingsButton->setGeometry(
|
||||||
|
rect.width() - settingsButton->width() - 15,
|
||||||
|
15,
|
||||||
|
settingsButton->geometry().width(),
|
||||||
|
settingsButton->geometry().height()
|
||||||
|
);
|
||||||
|
|
||||||
|
connect(settingsButton, &QPushButton::clicked, this, &GPClient::onSettingsButtonClicked);
|
||||||
|
connect(settingsDialog, &QDialog::accepted, this, &GPClient::onSettingsAccepted);
|
||||||
|
}
|
||||||
|
|
||||||
|
void GPClient::onSettingsButtonClicked()
|
||||||
|
{
|
||||||
|
settingsDialog->setExtraArgs(settings::get("extraArgs", "").toString());
|
||||||
|
settingsDialog->setClientos(settings::get("clientos", "Linux").toString());
|
||||||
|
settingsDialog->show();
|
||||||
|
}
|
||||||
|
|
||||||
|
void GPClient::onSettingsAccepted()
|
||||||
|
{
|
||||||
|
settings::save("extraArgs", settingsDialog->extraArgs());
|
||||||
|
settings::save("clientos", settingsDialog->clientos());
|
||||||
}
|
}
|
||||||
|
|
||||||
void GPClient::on_connectButton_clicked()
|
void GPClient::on_connectButton_clicked()
|
||||||
@@ -238,7 +278,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", "Linux").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
|
||||||
@@ -315,7 +355,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", "Linux").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);
|
||||||
@@ -330,7 +373,7 @@ void GPClient::onGatewaySuccess(const QString &authCookie)
|
|||||||
PLOGI << "Gateway login succeeded, got the cookie " << authCookie;
|
PLOGI << "Gateway login succeeded, got the cookie " << authCookie;
|
||||||
|
|
||||||
isQuickConnect = false;
|
isQuickConnect = false;
|
||||||
vpn->connect(currentGateway().address(), portalConfig.username(), authCookie);
|
vpn->connect(currentGateway().address(), portalConfig.username(), authCookie, settings::get("extraArgs", "").toString());
|
||||||
ui->statusLabel->setText("Connecting...");
|
ui->statusLabel->setText("Connecting...");
|
||||||
updateConnectionStatus(VpnStatus::pending);
|
updateConnectionStatus(VpnStatus::pending);
|
||||||
}
|
}
|
||||||
@@ -435,6 +478,12 @@ void GPClient::onVPNDisconnected()
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void GPClient::onVPNError(QString errorMessage)
|
||||||
|
{
|
||||||
|
updateConnectionStatus(VpnStatus::disconnected);
|
||||||
|
openMessageBox("Failed to connect", errorMessage);
|
||||||
|
}
|
||||||
|
|
||||||
void GPClient::onVPNLogAvailable(QString log)
|
void GPClient::onVPNLogAvailable(QString log)
|
||||||
{
|
{
|
||||||
PLOGI << log;
|
PLOGI << log;
|
||||||
|
@@ -3,10 +3,12 @@
|
|||||||
|
|
||||||
#include "gpservice_interface.h"
|
#include "gpservice_interface.h"
|
||||||
#include "portalconfigresponse.h"
|
#include "portalconfigresponse.h"
|
||||||
|
#include "settingsdialog.h"
|
||||||
|
|
||||||
#include <QMainWindow>
|
#include <QMainWindow>
|
||||||
#include <QSystemTrayIcon>
|
#include <QSystemTrayIcon>
|
||||||
#include <QMenu>
|
#include <QMenu>
|
||||||
|
#include <QPushButton>
|
||||||
|
|
||||||
QT_BEGIN_NAMESPACE
|
QT_BEGIN_NAMESPACE
|
||||||
namespace Ui { class GPClient; }
|
namespace Ui { class GPClient; }
|
||||||
@@ -23,6 +25,9 @@ public:
|
|||||||
void activate();
|
void activate();
|
||||||
|
|
||||||
private slots:
|
private slots:
|
||||||
|
void onSettingsButtonClicked();
|
||||||
|
void onSettingsAccepted();
|
||||||
|
|
||||||
void on_connectButton_clicked();
|
void on_connectButton_clicked();
|
||||||
void on_portalInput_returnPressed();
|
void on_portalInput_returnPressed();
|
||||||
void on_portalInput_editingFinished();
|
void on_portalInput_editingFinished();
|
||||||
@@ -40,6 +45,7 @@ private slots:
|
|||||||
|
|
||||||
void onVPNConnected();
|
void onVPNConnected();
|
||||||
void onVPNDisconnected();
|
void onVPNDisconnected();
|
||||||
|
void onVPNError(QString errorMessage);
|
||||||
void onVPNLogAvailable(QString log);
|
void onVPNLogAvailable(QString log);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
@@ -62,10 +68,15 @@ private:
|
|||||||
QAction *clearAction;
|
QAction *clearAction;
|
||||||
QAction *quitAction;
|
QAction *quitAction;
|
||||||
|
|
||||||
|
SettingsDialog *settingsDialog;
|
||||||
|
QPushButton *settingsButton;
|
||||||
|
|
||||||
bool isQuickConnect { false };
|
bool isQuickConnect { false };
|
||||||
bool isSwitchingGateway { false };
|
bool isSwitchingGateway { false };
|
||||||
PortalConfigResponse portalConfig;
|
PortalConfigResponse portalConfig;
|
||||||
|
|
||||||
|
void setupSettings();
|
||||||
|
|
||||||
void initSystemTrayIcon();
|
void initSystemTrayIcon();
|
||||||
void initVpnStatus();
|
void initVpnStatus();
|
||||||
void populateGatewayMenu();
|
void populateGatewayMenu();
|
||||||
|
@@ -7,7 +7,7 @@
|
|||||||
<x>0</x>
|
<x>0</x>
|
||||||
<y>0</y>
|
<y>0</y>
|
||||||
<width>260</width>
|
<width>260</width>
|
||||||
<height>338</height>
|
<height>362</height>
|
||||||
</rect>
|
</rect>
|
||||||
</property>
|
</property>
|
||||||
<property name="windowTitle">
|
<property name="windowTitle">
|
||||||
@@ -36,7 +36,7 @@
|
|||||||
<property name="layoutDirection">
|
<property name="layoutDirection">
|
||||||
<enum>Qt::LeftToRight</enum>
|
<enum>Qt::LeftToRight</enum>
|
||||||
</property>
|
</property>
|
||||||
<layout class="QVBoxLayout" name="verticalLayout_3" stretch="1,0">
|
<layout class="QVBoxLayout" name="verticalLayout_3" stretch="1,0,0">
|
||||||
<property name="leftMargin">
|
<property name="leftMargin">
|
||||||
<number>15</number>
|
<number>15</number>
|
||||||
</property>
|
</property>
|
||||||
@@ -123,6 +123,16 @@
|
|||||||
</item>
|
</item>
|
||||||
</layout>
|
</layout>
|
||||||
</item>
|
</item>
|
||||||
|
<item>
|
||||||
|
<widget class="QLabel" name="label">
|
||||||
|
<property name="text">
|
||||||
|
<string><html><head/><body><p align="center"><a href="https://bit.ly/3g5DHqy"><span style=" text-decoration: underline; color:#4c6b8a;">Report a bug</span></a> / <a href="https://bit.ly/3jQYfEi"><span style=" text-decoration: underline; color:#4c6b8a;">Buy me a coffee</span></a></p></body></html></string>
|
||||||
|
</property>
|
||||||
|
<property name="openExternalLinks">
|
||||||
|
<bool>true</bool>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
</layout>
|
</layout>
|
||||||
</widget>
|
</widget>
|
||||||
</widget>
|
</widget>
|
||||||
|
@@ -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);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@@ -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);
|
||||||
|
@@ -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();
|
||||||
|
@@ -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;
|
||||||
|
|
||||||
|
@@ -6,7 +6,7 @@
|
|||||||
#include <plog/Log.h>
|
#include <plog/Log.h>
|
||||||
#include <plog/Appenders/ColorConsoleAppender.h>
|
#include <plog/Appenders/ColorConsoleAppender.h>
|
||||||
|
|
||||||
static const QString version = "v1.2.5";
|
static const QString version = "v1.3.2";
|
||||||
|
|
||||||
int main(int argc, char *argv[])
|
int main(int argc, char *argv[])
|
||||||
{
|
{
|
||||||
@@ -28,6 +28,8 @@ int main(int argc, char *argv[])
|
|||||||
}
|
}
|
||||||
|
|
||||||
SingleApplication app(argc, argv);
|
SingleApplication app(argc, argv);
|
||||||
|
app.setQuitOnLastWindowClosed(false);
|
||||||
|
|
||||||
GPClient w;
|
GPClient w;
|
||||||
w.show();
|
w.show();
|
||||||
|
|
||||||
|
@@ -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()
|
||||||
|
@@ -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();
|
||||||
|
@@ -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;
|
||||||
}
|
}
|
||||||
|
@@ -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);
|
||||||
|
@@ -6,5 +6,6 @@
|
|||||||
<file>not_connected.png</file>
|
<file>not_connected.png</file>
|
||||||
<file>radio_unselected.png</file>
|
<file>radio_unselected.png</file>
|
||||||
<file>radio_selected.png</file>
|
<file>radio_selected.png</file>
|
||||||
|
<file>settings_icon.png</file>
|
||||||
</qresource>
|
</qresource>
|
||||||
</RCC>
|
</RCC>
|
||||||
|
BIN
GPClient/settings_icon.png
Normal file
BIN
GPClient/settings_icon.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 1.1 KiB |
34
GPClient/settingsdialog.cpp
Normal file
34
GPClient/settingsdialog.cpp
Normal file
@@ -0,0 +1,34 @@
|
|||||||
|
#include "settingsdialog.h"
|
||||||
|
#include "ui_settingsdialog.h"
|
||||||
|
|
||||||
|
SettingsDialog::SettingsDialog(QWidget *parent) :
|
||||||
|
QDialog(parent),
|
||||||
|
ui(new Ui::SettingsDialog)
|
||||||
|
{
|
||||||
|
ui->setupUi(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
SettingsDialog::~SettingsDialog()
|
||||||
|
{
|
||||||
|
delete ui;
|
||||||
|
}
|
||||||
|
|
||||||
|
void SettingsDialog::setExtraArgs(QString extraArgs)
|
||||||
|
{
|
||||||
|
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();
|
||||||
|
}
|
28
GPClient/settingsdialog.h
Normal file
28
GPClient/settingsdialog.h
Normal file
@@ -0,0 +1,28 @@
|
|||||||
|
#ifndef SETTINGSDIALOG_H
|
||||||
|
#define SETTINGSDIALOG_H
|
||||||
|
|
||||||
|
#include <QDialog>
|
||||||
|
|
||||||
|
namespace Ui {
|
||||||
|
class SettingsDialog;
|
||||||
|
}
|
||||||
|
|
||||||
|
class SettingsDialog : public QDialog
|
||||||
|
{
|
||||||
|
Q_OBJECT
|
||||||
|
|
||||||
|
public:
|
||||||
|
explicit SettingsDialog(QWidget *parent = nullptr);
|
||||||
|
~SettingsDialog();
|
||||||
|
|
||||||
|
void setExtraArgs(QString extraArgs);
|
||||||
|
QString extraArgs();
|
||||||
|
|
||||||
|
void setClientos(QString clientos);
|
||||||
|
QString clientos();
|
||||||
|
|
||||||
|
private:
|
||||||
|
Ui::SettingsDialog *ui;
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif // SETTINGSDIALOG_H
|
104
GPClient/settingsdialog.ui
Normal file
104
GPClient/settingsdialog.ui
Normal file
@@ -0,0 +1,104 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<ui version="4.0">
|
||||||
|
<class>SettingsDialog</class>
|
||||||
|
<widget class="QDialog" name="SettingsDialog">
|
||||||
|
<property name="geometry">
|
||||||
|
<rect>
|
||||||
|
<x>0</x>
|
||||||
|
<y>0</y>
|
||||||
|
<width>488</width>
|
||||||
|
<height>177</height>
|
||||||
|
</rect>
|
||||||
|
</property>
|
||||||
|
<property name="sizePolicy">
|
||||||
|
<sizepolicy hsizetype="Preferred" vsizetype="Preferred">
|
||||||
|
<horstretch>0</horstretch>
|
||||||
|
<verstretch>0</verstretch>
|
||||||
|
</sizepolicy>
|
||||||
|
</property>
|
||||||
|
<property name="windowTitle">
|
||||||
|
<string>Settings</string>
|
||||||
|
</property>
|
||||||
|
<property name="windowIcon">
|
||||||
|
<iconset resource="resources.qrc">
|
||||||
|
<normaloff>:/images/connected.png</normaloff>:/images/connected.png</iconset>
|
||||||
|
</property>
|
||||||
|
<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 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="vpn-slice xxx"</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item row="1" column="0">
|
||||||
|
<widget class="QLabel" name="label_2">
|
||||||
|
<property name="text">
|
||||||
|
<string>Value of "clientos":</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>
|
||||||
|
</property>
|
||||||
|
<property name="standardButtons">
|
||||||
|
<set>QDialogButtonBox::Cancel|QDialogButtonBox::Ok</set>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
</layout>
|
||||||
|
</widget>
|
||||||
|
<resources>
|
||||||
|
<include location="resources.qrc"/>
|
||||||
|
</resources>
|
||||||
|
<connections>
|
||||||
|
<connection>
|
||||||
|
<sender>buttonBox</sender>
|
||||||
|
<signal>accepted()</signal>
|
||||||
|
<receiver>SettingsDialog</receiver>
|
||||||
|
<slot>accept()</slot>
|
||||||
|
<hints>
|
||||||
|
<hint type="sourcelabel">
|
||||||
|
<x>248</x>
|
||||||
|
<y>254</y>
|
||||||
|
</hint>
|
||||||
|
<hint type="destinationlabel">
|
||||||
|
<x>157</x>
|
||||||
|
<y>274</y>
|
||||||
|
</hint>
|
||||||
|
</hints>
|
||||||
|
</connection>
|
||||||
|
<connection>
|
||||||
|
<sender>buttonBox</sender>
|
||||||
|
<signal>rejected()</signal>
|
||||||
|
<receiver>SettingsDialog</receiver>
|
||||||
|
<slot>reject()</slot>
|
||||||
|
<hints>
|
||||||
|
<hint type="sourcelabel">
|
||||||
|
<x>316</x>
|
||||||
|
<y>260</y>
|
||||||
|
</hint>
|
||||||
|
<hint type="destinationlabel">
|
||||||
|
<x>286</x>
|
||||||
|
<y>274</y>
|
||||||
|
</hint>
|
||||||
|
</hints>
|
||||||
|
</connection>
|
||||||
|
</connections>
|
||||||
|
</ui>
|
@@ -39,6 +39,47 @@ QString GPService::findBinary()
|
|||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Port from https://github.com/qt/qtbase/blob/11d1dcc6e263c5059f34b44d531c9ccdf7c0b1d6/src/corelib/io/qprocess.cpp#L2115 */
|
||||||
|
QStringList GPService::splitCommand(QStringView command)
|
||||||
|
{
|
||||||
|
QStringList args;
|
||||||
|
QString tmp;
|
||||||
|
int quoteCount = 0;
|
||||||
|
bool inQuote = false;
|
||||||
|
|
||||||
|
// handle quoting. tokens can be surrounded by double quotes
|
||||||
|
// "hello world". three consecutive double quotes represent
|
||||||
|
// the quote character itself.
|
||||||
|
for (int i = 0; i < command.size(); ++i) {
|
||||||
|
if (command.at(i) == QLatin1Char('"')) {
|
||||||
|
++quoteCount;
|
||||||
|
if (quoteCount == 3) {
|
||||||
|
// third consecutive quote
|
||||||
|
quoteCount = 0;
|
||||||
|
tmp += command.at(i);
|
||||||
|
}
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if (quoteCount) {
|
||||||
|
if (quoteCount == 1)
|
||||||
|
inQuote = !inQuote;
|
||||||
|
quoteCount = 0;
|
||||||
|
}
|
||||||
|
if (!inQuote && command.at(i).isSpace()) {
|
||||||
|
if (!tmp.isEmpty()) {
|
||||||
|
args += tmp;
|
||||||
|
tmp.clear();
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
tmp += command.at(i);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (!tmp.isEmpty())
|
||||||
|
args += tmp;
|
||||||
|
|
||||||
|
return args;
|
||||||
|
}
|
||||||
|
|
||||||
void GPService::quit()
|
void GPService::quit()
|
||||||
{
|
{
|
||||||
if (openconnect->state() == QProcess::NotRunning) {
|
if (openconnect->state() == QProcess::NotRunning) {
|
||||||
@@ -49,7 +90,7 @@ void GPService::quit()
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void GPService::connect(QString server, QString username, QString passwd)
|
void GPService::connect(QString server, QString username, QString passwd, QString extraArgs)
|
||||||
{
|
{
|
||||||
if (vpnStatus != GPService::VpnNotConnected) {
|
if (vpnStatus != GPService::VpnNotConnected) {
|
||||||
log("VPN status is: " + QVariant::fromValue(vpnStatus).toString());
|
log("VPN status is: " + QVariant::fromValue(vpnStatus).toString());
|
||||||
@@ -58,17 +99,21 @@ void GPService::connect(QString server, QString username, QString passwd)
|
|||||||
|
|
||||||
QString bin = findBinary();
|
QString bin = findBinary();
|
||||||
if (bin == nullptr) {
|
if (bin == nullptr) {
|
||||||
log("Could not found openconnect binary, make sure openconnect is installed, exiting.");
|
log("Could not find openconnect binary, make sure openconnect is installed, exiting.");
|
||||||
|
emit error("The OpenConect CLI was not found, make sure it has been installed!");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
QStringList args;
|
QStringList args;
|
||||||
args << QCoreApplication::arguments().mid(1)
|
args << QCoreApplication::arguments().mid(1)
|
||||||
<< "--protocol=gp"
|
<< "--protocol=gp"
|
||||||
|
<< splitCommand(extraArgs)
|
||||||
<< "-u" << username
|
<< "-u" << username
|
||||||
<< "-C" << passwd
|
<< "-C" << passwd
|
||||||
<< server;
|
<< server;
|
||||||
|
|
||||||
|
log("Start process with arugments: " + args.join(" "));
|
||||||
|
|
||||||
openconnect->start(bin, args);
|
openconnect->start(bin, args);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -31,10 +31,11 @@ public:
|
|||||||
signals:
|
signals:
|
||||||
void connected();
|
void connected();
|
||||||
void disconnected();
|
void disconnected();
|
||||||
|
void error(QString errorMessage);
|
||||||
void logAvailable(QString log);
|
void logAvailable(QString log);
|
||||||
|
|
||||||
public slots:
|
public slots:
|
||||||
void connect(QString server, QString username, QString passwd);
|
void connect(QString server, QString username, QString passwd, QString extraArgs);
|
||||||
void disconnect();
|
void disconnect();
|
||||||
int status();
|
int status();
|
||||||
void quit();
|
void quit();
|
||||||
@@ -53,6 +54,7 @@ private:
|
|||||||
|
|
||||||
void log(QString msg);
|
void log(QString msg);
|
||||||
static QString findBinary();
|
static QString findBinary();
|
||||||
|
static QStringList splitCommand(QStringView command);
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // GLOBALPROTECTSERVICE_H
|
#endif // GLOBALPROTECTSERVICE_H
|
||||||
|
@@ -8,10 +8,14 @@
|
|||||||
<signal name="logAvailable">
|
<signal name="logAvailable">
|
||||||
<arg name="log" type="s" />
|
<arg name="log" type="s" />
|
||||||
</signal>
|
</signal>
|
||||||
|
<signal name="error">
|
||||||
|
<arg name="errorMessage" type="s" />
|
||||||
|
</signal>
|
||||||
<method name="connect">
|
<method name="connect">
|
||||||
<arg name="server" type="s" direction="in"/>
|
<arg name="server" type="s" direction="in"/>
|
||||||
<arg name="username" type="s" direction="in"/>
|
<arg name="username" type="s" direction="in"/>
|
||||||
<arg name="passwd" type="s" direction="in"/>
|
<arg name="passwd" type="s" direction="in"/>
|
||||||
|
<arg name="extraArgs" type="s" direction="in"/>
|
||||||
</method>
|
</method>
|
||||||
<method name="disconnect">
|
<method name="disconnect">
|
||||||
</method>
|
</method>
|
||||||
|
39
PKGBUILD.template
Normal file
39
PKGBUILD.template
Normal file
@@ -0,0 +1,39 @@
|
|||||||
|
# Maintainer: Keinv Yue <yuezk001@gmail.com>
|
||||||
|
|
||||||
|
pkgname=globalprotect-openconnect
|
||||||
|
_gitname=GlobalProtect-openconnect
|
||||||
|
pkgver={PKG_VERSION}
|
||||||
|
pkgrel=1
|
||||||
|
pkgdesc="A GlobalProtect VPN client (GUI) for Linux based on Openconnect and built with Qt5, supports SAML auth mode."
|
||||||
|
arch=(x86_64 aarch64)
|
||||||
|
url="https://github.com/yuezk/${_gitname}"
|
||||||
|
license=('GPL3')
|
||||||
|
depends=('openconnect>=8.0.0' qt5-base qt5-webengine qt5-websockets)
|
||||||
|
makedepends=()
|
||||||
|
source=(
|
||||||
|
"${_gitname}-${pkgver}.tar.gz::${url}/archive/v${pkgver}.tar.gz"
|
||||||
|
"https://github.com/itay-grudev/SingleApplication/archive/v3.0.19.tar.gz"
|
||||||
|
"https://github.com/SergiusTheBest/plog/archive/1.1.5.tar.gz"
|
||||||
|
)
|
||||||
|
|
||||||
|
sha256sums=(
|
||||||
|
'{SOURCE_SHA}'
|
||||||
|
'9405fd259288b2a862e91e5135bccee936f0438e1b32c13603277132309d15e0'
|
||||||
|
'6c80b4701183d2415bec927e1f5ca9b1761b3b5c65d3e09fb29c743e016d5609'
|
||||||
|
);
|
||||||
|
|
||||||
|
prepare() {
|
||||||
|
mv "$srcdir/SingleApplication-3.0.19" -T "$srcdir/${_gitname}-${pkgver}/singleapplication"
|
||||||
|
mv "$srcdir/plog-1.1.5" -T "$srcdir/${_gitname}-${pkgver}/plog"
|
||||||
|
}
|
||||||
|
|
||||||
|
build() {
|
||||||
|
cd "$srcdir/${_gitname}-${pkgver}"
|
||||||
|
qmake CONFIG+=release "${srcdir}/${_gitname}-${pkgver}/GlobalProtect-openconnect.pro"
|
||||||
|
make
|
||||||
|
}
|
||||||
|
|
||||||
|
package() {
|
||||||
|
cd "$srcdir/${_gitname}-${pkgver}"
|
||||||
|
make INSTALL_ROOT="$pkgdir/" install
|
||||||
|
}
|
65
README.md
65
README.md
@@ -12,6 +12,32 @@ A GlobalProtect VPN client (GUI) for Linux based on Openconnect and built with Q
|
|||||||
- Supports automatically selecting the preferred gateway from the multiple gateways.
|
- Supports automatically selecting the preferred gateway from the multiple gateways.
|
||||||
- Supports switching gateway from the system tray menu manually.
|
- Supports switching gateway from the system tray menu manually.
|
||||||
|
|
||||||
|
## Future plan
|
||||||
|
|
||||||
|
- [ ] Improve the release process
|
||||||
|
- [ ] Process bugs and feature requests
|
||||||
|
- [ ] Support for bypassing the `gpclient` parameters
|
||||||
|
- [ ] Support the CLI mode
|
||||||
|
|
||||||
|
## 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/130319209-744be02b-d657-4f49-a76d-d2c81b5c46d5.png" />
|
||||||
|
<p>
|
||||||
|
|
||||||
|
## Display the system tray icon on Gnome 40
|
||||||
|
|
||||||
|
Install the [AppIndicator and KStatusNotifierItem Support](https://extensions.gnome.org/extension/615/appindicator-support/) extension and you will see the system try icon (Restart the system after the installation).
|
||||||
|
|
||||||
|
<p align="center">
|
||||||
|
<img src="https://user-images.githubusercontent.com/3297602/130831022-b93492fd-46dd-4a8e-94a4-13b5747120b7.png" />
|
||||||
|
<p>
|
||||||
|
|
||||||
## Prerequisites
|
## Prerequisites
|
||||||
|
|
||||||
- Openconnect v8.x
|
- Openconnect v8.x
|
||||||
@@ -20,12 +46,27 @@ A GlobalProtect VPN client (GUI) for Linux based on Openconnect and built with Q
|
|||||||
### Ubuntu
|
### Ubuntu
|
||||||
1. Install openconnect v8.x
|
1. Install openconnect v8.x
|
||||||
|
|
||||||
|
```sh
|
||||||
|
sudo apt install openconnect
|
||||||
|
openconnect --version
|
||||||
|
```
|
||||||
|
|
||||||
For Ubuntu 18.04 you might need to [build the latest openconnect from source code](https://gist.github.com/yuezk/ab9a4b87a9fa0182bdb2df41fab5f613).
|
For Ubuntu 18.04 you might need to [build the latest openconnect from source code](https://gist.github.com/yuezk/ab9a4b87a9fa0182bdb2df41fab5f613).
|
||||||
|
|
||||||
2. Install the Qt dependencies
|
2. Install the Qt dependencies
|
||||||
|
|
||||||
|
For Ubuntu 20, this should work.
|
||||||
|
|
||||||
```sh
|
```sh
|
||||||
sudo apt install qt5-default libqt5websockets5-dev qtwebengine5-dev
|
sudo apt install qtbase5-dev libqt5websockets5-dev qtwebengine5-dev qttools5-dev debhelper
|
||||||
```
|
```
|
||||||
|
|
||||||
|
For Ubuntu 21, you need to install the base pieces separately as QT5 is the default.
|
||||||
|
|
||||||
|
```sh
|
||||||
|
sudo apt install qtbase5-dev qtchooser qt5-qmake qtbase5-dev-tools libqt5websockets5-dev qtwebengine5-dev qttools5-dev debhelper
|
||||||
|
```
|
||||||
|
|
||||||
### OpenSUSE
|
### OpenSUSE
|
||||||
Install the Qt dependencies
|
Install the Qt dependencies
|
||||||
|
|
||||||
@@ -33,6 +74,13 @@ Install the Qt dependencies
|
|||||||
sudo zypper install libqt5-qtbase-devel libqt5-qtwebsockets-devel libqt5-qtwebengine-devel
|
sudo zypper install libqt5-qtbase-devel libqt5-qtwebsockets-devel libqt5-qtwebengine-devel
|
||||||
```
|
```
|
||||||
|
|
||||||
|
### Fedora
|
||||||
|
Install the Qt dependencies:
|
||||||
|
|
||||||
|
```sh
|
||||||
|
sudo dnf install qt5-qtbase-devel qt5-qtwebengine-devel qt5-qtwebsockets-devel
|
||||||
|
```
|
||||||
|
|
||||||
## Install
|
## Install
|
||||||
|
|
||||||
### Install from AUR (Arch/Manjaro)
|
### Install from AUR (Arch/Manjaro)
|
||||||
@@ -76,15 +124,28 @@ Relatively manual process for now:
|
|||||||
git-archive-all --force-submodules --prefix=globalprotect-openconnect-1.3.0/ ../globalprotect-openconnect_1.3.0.orig.tar.gz
|
git-archive-all --force-submodules --prefix=globalprotect-openconnect-1.3.0/ ../globalprotect-openconnect_1.3.0.orig.tar.gz
|
||||||
```
|
```
|
||||||
|
|
||||||
* Finally extract the source tree and build the debian package.
|
* Finally extract the source tree, build the debian package, and install it.
|
||||||
|
|
||||||
```
|
```
|
||||||
cd ..
|
cd ..
|
||||||
tar -xzvf globalprotect-openconnect_1.3.0.orig.tar.gz
|
tar -xzvf globalprotect-openconnect_1.3.0.orig.tar.gz
|
||||||
cd globalprotect-openconnect-1.3.0
|
cd globalprotect-openconnect-1.3.0
|
||||||
fakeroot dpkg-buildpackage -uc -us -sa 2>&1 | tee ../build.log
|
fakeroot dpkg-buildpackage -uc -us -sa 2>&1 | tee ../build.log
|
||||||
|
sudo dpkg -i globalprotect-openconnect_1.3.0-1ppa1_amd64.deb
|
||||||
```
|
```
|
||||||
|
|
||||||
|
### NixOS
|
||||||
|
In `configuration.nix`:
|
||||||
|
|
||||||
|
```
|
||||||
|
services.globalprotect = {
|
||||||
|
enable = true;
|
||||||
|
# if you need a Host Integrity Protection report
|
||||||
|
csdWrapper = "${pkgs.openconnect}/libexec/openconnect/hipreport.sh";
|
||||||
|
};
|
||||||
|
|
||||||
|
environment.systemPackages = [ globalprotect-openconnect ];
|
||||||
|
```
|
||||||
|
|
||||||
|
|
||||||
## [License](./LICENSE)
|
## [License](./LICENSE)
|
||||||
|
2
debian/control
vendored
2
debian/control
vendored
@@ -2,7 +2,7 @@ Source: globalprotect-openconnect
|
|||||||
Section: net
|
Section: net
|
||||||
Priority: optional
|
Priority: optional
|
||||||
Maintainer: Kevin Yue <k3vinyue@gmail.com>
|
Maintainer: Kevin Yue <k3vinyue@gmail.com>
|
||||||
Build-Depends: debhelper (>=11~), qt5-default (>=5.9), qttools5-dev (>=5.9), libqt5websockets5-dev (>=5.9), qtwebengine5-dev (>=5.9)
|
Build-Depends: debhelper (>=11~), qtbase5-dev, qttools5-dev (>=5.9), libqt5websockets5-dev (>=5.9), qtwebengine5-dev (>=5.9)
|
||||||
Standards-Version: 4.1.4
|
Standards-Version: 4.1.4
|
||||||
Homepage: https://github.com/yuezk/GlobalProtect-openconnect
|
Homepage: https://github.com/yuezk/GlobalProtect-openconnect
|
||||||
|
|
||||||
|
5
packaging/rpm/README.md
Normal file
5
packaging/rpm/README.md
Normal file
@@ -0,0 +1,5 @@
|
|||||||
|
## Command
|
||||||
|
|
||||||
|
```sh
|
||||||
|
docker run --rm -it -v ${PWD}:/rpm --workdir=/rpm --entrypoint ./entrypoint.sh centos:8
|
||||||
|
```
|
21
packaging/rpm/entrypoint.sh
Executable file
21
packaging/rpm/entrypoint.sh
Executable file
@@ -0,0 +1,21 @@
|
|||||||
|
#!/bin/bash -e
|
||||||
|
|
||||||
|
# Install the build tools
|
||||||
|
dnf install -y epel-release
|
||||||
|
rpm --import http://download.fedoraproject.org/pub/epel/RPM-GPG-KEY-EPEL-8
|
||||||
|
dnf install -y make rpm-build rpm-devel rpmlint rpmdevtools
|
||||||
|
|
||||||
|
# Install the build dependencies
|
||||||
|
dnf install -y qt5-qtbase-devel qt5-qtwebengine-devel qt5-qtwebsockets-devel
|
||||||
|
|
||||||
|
# Prepare the RPM build environment
|
||||||
|
rpmdev-setuptree
|
||||||
|
cp *.spec $HOME/rpmbuild/SPECS/
|
||||||
|
cp *.tar.gz $HOME/rpmbuild/SOURCES/
|
||||||
|
|
||||||
|
# Build
|
||||||
|
rpmbuild -ba $HOME/rpmbuild/SPECS/globalprotect-openconnect.spec
|
||||||
|
|
||||||
|
# Copy the package to the current directory
|
||||||
|
cp $HOME/rpmbuild/RPMS/x86_64/globalprotect-openconnect-*.rpm .
|
||||||
|
cp $HOME/rpmbuild/SRPMS/globalprotect-openconnect-*.src.rpm .
|
39
packaging/rpm/globalprotect-openconnect.spec
Normal file
39
packaging/rpm/globalprotect-openconnect.spec
Normal file
@@ -0,0 +1,39 @@
|
|||||||
|
Name: globalprotect-openconnect
|
||||||
|
Version: 1.3.0+SNAPSHOT20210829120923
|
||||||
|
Release: 1
|
||||||
|
Summary: A GlobalProtect VPN client
|
||||||
|
|
||||||
|
License: GPLv3
|
||||||
|
URL: https://github.com/yuezk/GlobalProtect-openconnect
|
||||||
|
Source0: %{url}/releases/download/latest/globalprotect-openconnect_%{version}.full.tar.gz
|
||||||
|
|
||||||
|
BuildRequires: qt5-qtbase-devel qt5-qtwebengine-devel qt5-qtwebsockets-devel
|
||||||
|
Requires: qt5-qtbase >= 5.12 qt5-qtwebengine >= 5.12 qt5-qtwebsockets >= 5.12 openconnect >= 8.0
|
||||||
|
|
||||||
|
%global debug_package %{nil}
|
||||||
|
|
||||||
|
%description
|
||||||
|
A GlobalProtect VPN client (GUI) for Linux based on OpenConnect and built with Qt5, supports SAML auth mode.
|
||||||
|
|
||||||
|
|
||||||
|
%prep
|
||||||
|
%autosetup
|
||||||
|
|
||||||
|
|
||||||
|
%build
|
||||||
|
qmake-qt5 CONFIG+=release
|
||||||
|
%make_build
|
||||||
|
|
||||||
|
|
||||||
|
%install
|
||||||
|
INSTALL_ROOT=${RPM_BUILD_ROOT} %make_install
|
||||||
|
|
||||||
|
|
||||||
|
%files
|
||||||
|
/etc/systemd/system/gpservice.service
|
||||||
|
/usr/bin/gpclient
|
||||||
|
/usr/bin/gpservice
|
||||||
|
/usr/share/applications/com.yuezk.qt.gpclient.desktop
|
||||||
|
/usr/share/dbus-1/system-services/com.yuezk.qt.GPService.service
|
||||||
|
/usr/share/dbus-1/system.d/com.yuezk.qt.GPService.conf
|
||||||
|
/usr/share/pixmaps/com.yuezk.qt.GPClient.svg
|
Reference in New Issue
Block a user