mirror of
https://github.com/yuezk/GlobalProtect-openconnect.git
synced 2025-04-02 18:31:50 -04:00
Add a scripting mode to GPClient (#110)
This commit is contained in:
parent
dd81ed9519
commit
9d6ec84c14
2
3rdparty/plog
vendored
2
3rdparty/plog
vendored
@ -1 +1 @@
|
|||||||
Subproject commit f4c22b03d5d3aa753cca8e716636ac4eb29b0917
|
Subproject commit 914e799d2b08d790f5d04d1c46928586b3a41250
|
@ -33,6 +33,8 @@ add_executable(gpclient
|
|||||||
gpclient.ui
|
gpclient.ui
|
||||||
normalloginwindow.ui
|
normalloginwindow.ui
|
||||||
settingsdialog.ui
|
settingsdialog.ui
|
||||||
|
vpn_dbus.cpp
|
||||||
|
vpn_json.cpp
|
||||||
resources.qrc
|
resources.qrc
|
||||||
${gpclient_GENERATED_SOURCES}
|
${gpclient_GENERATED_SOURCES}
|
||||||
)
|
)
|
||||||
@ -52,7 +54,7 @@ add_3rdparty(
|
|||||||
add_3rdparty(
|
add_3rdparty(
|
||||||
plog
|
plog
|
||||||
GIT_REPOSITORY https://github.com/SergiusTheBest/plog.git
|
GIT_REPOSITORY https://github.com/SergiusTheBest/plog.git
|
||||||
GIT_TAG 1.1.5
|
GIT_TAG master
|
||||||
CMAKE_ARGS
|
CMAKE_ARGS
|
||||||
-DPLOG_BUILD_SAMPLES=OFF
|
-DPLOG_BUILD_SAMPLES=OFF
|
||||||
-DCMAKE_BUILD_TYPE=${CMAKE_BUILD_TYPE}
|
-DCMAKE_BUILD_TYPE=${CMAKE_BUILD_TYPE}
|
||||||
|
@ -11,9 +11,10 @@
|
|||||||
|
|
||||||
using namespace gpclient::helper;
|
using namespace gpclient::helper;
|
||||||
|
|
||||||
GPClient::GPClient(QWidget *parent)
|
GPClient::GPClient(QWidget *parent, IVpn *vpn)
|
||||||
: QMainWindow(parent)
|
: QMainWindow(parent)
|
||||||
, ui(new Ui::GPClient)
|
, ui(new Ui::GPClient)
|
||||||
|
, vpn(vpn)
|
||||||
, settingsDialog(new SettingsDialog(this))
|
, settingsDialog(new SettingsDialog(this))
|
||||||
{
|
{
|
||||||
ui->setupUi(this);
|
ui->setupUi(this);
|
||||||
@ -25,14 +26,14 @@ GPClient::GPClient(QWidget *parent)
|
|||||||
setupSettings();
|
setupSettings();
|
||||||
|
|
||||||
// Restore portal from the previous settings
|
// Restore portal from the previous settings
|
||||||
ui->portalInput->setText(settings::get("portal", "").toString());
|
this->portal(settings::get("portal", "").toString());
|
||||||
|
|
||||||
// DBus service setup
|
// DBus service setup
|
||||||
vpn = new com::yuezk::qt::GPService("com.yuezk.qt.GPService", "/", QDBusConnection::systemBus(), this);
|
QObject *ov = dynamic_cast<QObject*>(vpn);
|
||||||
connect(vpn, &com::yuezk::qt::GPService::connected, this, &GPClient::onVPNConnected);
|
connect(ov, SIGNAL(connected()), this, SLOT(onVPNConnected()));
|
||||||
connect(vpn, &com::yuezk::qt::GPService::disconnected, this, &GPClient::onVPNDisconnected);
|
connect(ov, SIGNAL(disconnected()), this, SLOT(onVPNDisconnected()));
|
||||||
connect(vpn, &com::yuezk::qt::GPService::error, this, &GPClient::onVPNError);
|
connect(ov, SIGNAL(error(const &QString)), this, SLOT(onVPNError(const QString&)));
|
||||||
connect(vpn, &com::yuezk::qt::GPService::logAvailable, this, &GPClient::onVPNLogAvailable);
|
connect(ov, SIGNAL(logAvailable(const &QString)), this, SLOT(onVPNLogAvailable(const QString&)));
|
||||||
|
|
||||||
// Initiallize the context menu of system tray.
|
// Initiallize the context menu of system tray.
|
||||||
initSystemTrayIcon();
|
initSystemTrayIcon();
|
||||||
@ -373,7 +374,11 @@ 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, settings::get("extraArgs", "").toString());
|
QList<QString> gatewayAddresses;
|
||||||
|
for (GPGateway &gw : allGateways()) {
|
||||||
|
gatewayAddresses.push_back(gw.address());
|
||||||
|
}
|
||||||
|
vpn->connect(currentGateway().address(), gatewayAddresses, portalConfig.username(), authCookie, settings::get("extraArgs", "").toString());
|
||||||
ui->statusLabel->setText("Connecting...");
|
ui->statusLabel->setText("Connecting...");
|
||||||
updateConnectionStatus(VpnStatus::pending);
|
updateConnectionStatus(VpnStatus::pending);
|
||||||
}
|
}
|
||||||
@ -410,6 +415,11 @@ QString GPClient::portal() const
|
|||||||
return input;
|
return input;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void GPClient::portal(QString p)
|
||||||
|
{
|
||||||
|
ui->portalInput->setText(p);
|
||||||
|
}
|
||||||
|
|
||||||
bool GPClient::connected() const
|
bool GPClient::connected() const
|
||||||
{
|
{
|
||||||
const QString statusText = ui->statusLabel->text();
|
const QString statusText = ui->statusLabel->text();
|
||||||
|
@ -6,9 +6,9 @@
|
|||||||
#include <QtWidgets/QMenu>
|
#include <QtWidgets/QMenu>
|
||||||
#include <QtWidgets/QPushButton>
|
#include <QtWidgets/QPushButton>
|
||||||
|
|
||||||
#include "gpserviceinterface.h"
|
|
||||||
#include "portalconfigresponse.h"
|
#include "portalconfigresponse.h"
|
||||||
#include "settingsdialog.h"
|
#include "settingsdialog.h"
|
||||||
|
#include "vpn.h"
|
||||||
|
|
||||||
QT_BEGIN_NAMESPACE
|
QT_BEGIN_NAMESPACE
|
||||||
namespace Ui { class GPClient; }
|
namespace Ui { class GPClient; }
|
||||||
@ -19,12 +19,20 @@ class GPClient : public QMainWindow
|
|||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
|
|
||||||
public:
|
public:
|
||||||
GPClient(QWidget *parent = nullptr);
|
GPClient(QWidget *parent, IVpn *vpn);
|
||||||
~GPClient();
|
~GPClient();
|
||||||
|
|
||||||
void activate();
|
void activate();
|
||||||
void quit();
|
void quit();
|
||||||
|
|
||||||
|
QString portal() const;
|
||||||
|
void portal(QString);
|
||||||
|
|
||||||
|
GPGateway currentGateway() const;
|
||||||
|
void setCurrentGateway(const GPGateway gateway);
|
||||||
|
|
||||||
|
void doConnect();
|
||||||
|
|
||||||
private slots:
|
private slots:
|
||||||
void onSettingsButtonClicked();
|
void onSettingsButtonClicked();
|
||||||
void onSettingsAccepted();
|
void onSettingsAccepted();
|
||||||
@ -58,7 +66,7 @@ private:
|
|||||||
};
|
};
|
||||||
|
|
||||||
Ui::GPClient *ui;
|
Ui::GPClient *ui;
|
||||||
com::yuezk::qt::GPService *vpn;
|
IVpn *vpn;
|
||||||
|
|
||||||
QSystemTrayIcon *systemTrayIcon;
|
QSystemTrayIcon *systemTrayIcon;
|
||||||
QMenu *contextMenu;
|
QMenu *contextMenu;
|
||||||
@ -83,20 +91,15 @@ private:
|
|||||||
void populateGatewayMenu();
|
void populateGatewayMenu();
|
||||||
void updateConnectionStatus(const VpnStatus &status);
|
void updateConnectionStatus(const VpnStatus &status);
|
||||||
|
|
||||||
void doConnect();
|
|
||||||
void portalLogin();
|
void portalLogin();
|
||||||
void tryGatewayLogin();
|
void tryGatewayLogin();
|
||||||
void gatewayLogin();
|
void gatewayLogin();
|
||||||
|
|
||||||
QString portal() const;
|
|
||||||
bool connected() const;
|
bool connected() const;
|
||||||
|
|
||||||
QList<GPGateway> allGateways() const;
|
QList<GPGateway> allGateways() const;
|
||||||
void setAllGateways(QList<GPGateway> gateways);
|
void setAllGateways(QList<GPGateway> gateways);
|
||||||
|
|
||||||
GPGateway currentGateway() const;
|
|
||||||
void setCurrentGateway(const GPGateway gateway);
|
|
||||||
|
|
||||||
void clearSettings();
|
void clearSettings();
|
||||||
};
|
};
|
||||||
#endif // GPCLIENT_H
|
#endif // GPCLIENT_H
|
||||||
|
@ -3,24 +3,22 @@
|
|||||||
#include <QtCore/QDir>
|
#include <QtCore/QDir>
|
||||||
#include <QtCore/QStandardPaths>
|
#include <QtCore/QStandardPaths>
|
||||||
#include <plog/Log.h>
|
#include <plog/Log.h>
|
||||||
|
#include <plog/Init.h>
|
||||||
#include <plog/Appenders/ColorConsoleAppender.h>
|
#include <plog/Appenders/ColorConsoleAppender.h>
|
||||||
|
#include <plog/Formatters/TxtFormatter.h>
|
||||||
|
|
||||||
#include "singleapplication.h"
|
#include "singleapplication.h"
|
||||||
#include "gpclient.h"
|
#include "gpclient.h"
|
||||||
|
#include "vpn_dbus.h"
|
||||||
|
#include "vpn_json.h"
|
||||||
#include "enhancedwebview.h"
|
#include "enhancedwebview.h"
|
||||||
#include "sigwatch.h"
|
#include "sigwatch.h"
|
||||||
#include "version.h"
|
#include "version.h"
|
||||||
|
|
||||||
int main(int argc, char *argv[])
|
int main(int argc, char *argv[])
|
||||||
{
|
{
|
||||||
const QDir path = QStandardPaths::writableLocation(QStandardPaths::GenericCacheLocation) + "/GlobalProtect-openconnect";
|
plog::ColorConsoleAppender<plog::TxtFormatter> consoleAppender(plog::streamStdErr);
|
||||||
const QString logFile = path.path() + "/gpclient.log";
|
plog::init(plog::debug, &consoleAppender);
|
||||||
if (!path.exists()) {
|
|
||||||
path.mkpath(".");
|
|
||||||
}
|
|
||||||
|
|
||||||
static plog::ColorConsoleAppender<plog::TxtFormatter> consoleAppender;
|
|
||||||
plog::init(plog::debug, logFile.toUtf8()).addAppender(&consoleAppender);
|
|
||||||
|
|
||||||
PLOGI << "GlobalProtect started, version: " << VERSION;
|
PLOGI << "GlobalProtect started, version: " << VERSION;
|
||||||
|
|
||||||
@ -33,9 +31,35 @@ int main(int argc, char *argv[])
|
|||||||
SingleApplication app(argc, argv);
|
SingleApplication app(argc, argv);
|
||||||
app.setQuitOnLastWindowClosed(false);
|
app.setQuitOnLastWindowClosed(false);
|
||||||
|
|
||||||
GPClient w;
|
QCommandLineParser parser;
|
||||||
|
parser.addHelpOption();
|
||||||
|
parser.addVersionOption();
|
||||||
|
parser.addPositionalArgument("server", "The URL of the VPN server. Optional.");
|
||||||
|
parser.addPositionalArgument("gateway", "The URL of the specific VPN gateway. Optional.");
|
||||||
|
parser.addOptions({
|
||||||
|
{"json", "Write the result of the handshake with the GlobalConnect server to stdout as JSON and terminate. Useful for scripting."},
|
||||||
|
{"now", "Do not show the dialog with the connect button; connect immediately instead."},
|
||||||
|
});
|
||||||
|
parser.process(app);
|
||||||
|
|
||||||
|
const QStringList positional = parser.positionalArguments();
|
||||||
|
|
||||||
|
IVpn *vpn = parser.isSet("json") // yes it leaks, but this is cleared on exit anyway
|
||||||
|
? static_cast<IVpn*>(new VpnJson(nullptr)) // Print to stdout and exit
|
||||||
|
: static_cast<IVpn*>(new VpnDbus(nullptr)); // Contact GPService daemon via dbus
|
||||||
|
GPClient w(nullptr, vpn);
|
||||||
w.show();
|
w.show();
|
||||||
|
|
||||||
|
if (positional.size() > 0) {
|
||||||
|
w.portal(positional.at(0));
|
||||||
|
}
|
||||||
|
if (positional.size() > 1) {
|
||||||
|
GPGateway gw;
|
||||||
|
gw.setName(positional.at(1));
|
||||||
|
gw.setAddress(positional.at(1));
|
||||||
|
w.setCurrentGateway(gw);
|
||||||
|
}
|
||||||
|
|
||||||
QObject::connect(&app, &SingleApplication::instanceStarted, &w, &GPClient::activate);
|
QObject::connect(&app, &SingleApplication::instanceStarted, &w, &GPClient::activate);
|
||||||
|
|
||||||
UnixSignalWatcher sigwatch;
|
UnixSignalWatcher sigwatch;
|
||||||
@ -45,5 +69,12 @@ int main(int argc, char *argv[])
|
|||||||
sigwatch.watchForSignal(SIGHUP);
|
sigwatch.watchForSignal(SIGHUP);
|
||||||
QObject::connect(&sigwatch, &UnixSignalWatcher::unixSignal, &w, &GPClient::quit);
|
QObject::connect(&sigwatch, &UnixSignalWatcher::unixSignal, &w, &GPClient::quit);
|
||||||
|
|
||||||
|
if (parser.isSet("now")) {
|
||||||
|
w.doConnect();
|
||||||
|
}
|
||||||
|
if (parser.isSet("json")) {
|
||||||
|
QObject::connect(static_cast<VpnJson*>(vpn), &VpnJson::connected, &w, &GPClient::quit);
|
||||||
|
}
|
||||||
|
|
||||||
return app.exec();
|
return app.exec();
|
||||||
}
|
}
|
||||||
|
24
GPClient/vpn.h
Normal file
24
GPClient/vpn.h
Normal file
@ -0,0 +1,24 @@
|
|||||||
|
#ifndef VPN_H
|
||||||
|
#define VPN_H
|
||||||
|
#include <QtCore/QObject>
|
||||||
|
#include <QtCore/QString>
|
||||||
|
|
||||||
|
class IVpn
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
virtual ~IVpn() = default;
|
||||||
|
|
||||||
|
virtual void connect(const QString &preferredServer, const QList<QString> &servers, const QString &username, const QString &passwd, const QString &extraArgs) = 0;
|
||||||
|
virtual void disconnect() = 0;
|
||||||
|
virtual int status() = 0;
|
||||||
|
|
||||||
|
// signals: // SIGNALS
|
||||||
|
// virtual void connected();
|
||||||
|
// virtual void disconnected();
|
||||||
|
// virtual void error(const QString &errorMessage);
|
||||||
|
// virtual void logAvailable(const QString &log);
|
||||||
|
};
|
||||||
|
|
||||||
|
Q_DECLARE_INTERFACE(IVpn, "IVpn") // define this out of namespace scope
|
||||||
|
|
||||||
|
#endif
|
13
GPClient/vpn_dbus.cpp
Normal file
13
GPClient/vpn_dbus.cpp
Normal file
@ -0,0 +1,13 @@
|
|||||||
|
#include "vpn_dbus.h"
|
||||||
|
|
||||||
|
void VpnDbus::connect(const QString &preferredServer, const QList<QString> &servers, const QString &username, const QString &passwd, const QString &extraArgs) {
|
||||||
|
inner->connect(preferredServer, username, passwd, extraArgs);
|
||||||
|
}
|
||||||
|
|
||||||
|
void VpnDbus::disconnect() {
|
||||||
|
inner->disconnect();
|
||||||
|
}
|
||||||
|
|
||||||
|
int VpnDbus::status() {
|
||||||
|
return inner->status();
|
||||||
|
}
|
33
GPClient/vpn_dbus.h
Normal file
33
GPClient/vpn_dbus.h
Normal file
@ -0,0 +1,33 @@
|
|||||||
|
#ifndef VPN_DBUS_H
|
||||||
|
#define VPN_DBUS_H
|
||||||
|
#include "vpn.h"
|
||||||
|
#include "gpserviceinterface.h"
|
||||||
|
|
||||||
|
class VpnDbus : public QObject, public IVpn
|
||||||
|
{
|
||||||
|
Q_OBJECT
|
||||||
|
Q_INTERFACES(IVpn)
|
||||||
|
|
||||||
|
private:
|
||||||
|
com::yuezk::qt::GPService *inner;
|
||||||
|
|
||||||
|
public:
|
||||||
|
VpnDbus(QObject *parent) : QObject(parent) {
|
||||||
|
inner = new com::yuezk::qt::GPService("com.yuezk.qt.GPService", "/", QDBusConnection::systemBus(), this);
|
||||||
|
QObject::connect(inner, &com::yuezk::qt::GPService::connected, this, &VpnDbus::connected);
|
||||||
|
QObject::connect(inner, &com::yuezk::qt::GPService::disconnected, this, &VpnDbus::disconnected);
|
||||||
|
QObject::connect(inner, &com::yuezk::qt::GPService::error, this, &VpnDbus::error);
|
||||||
|
QObject::connect(inner, &com::yuezk::qt::GPService::logAvailable, this, &VpnDbus::logAvailable);
|
||||||
|
}
|
||||||
|
|
||||||
|
void connect(const QString &preferredServer, const QList<QString> &servers, const QString &username, const QString &passwd, const QString &extraArgs);
|
||||||
|
void disconnect();
|
||||||
|
int status();
|
||||||
|
|
||||||
|
signals: // SIGNALS
|
||||||
|
void connected();
|
||||||
|
void disconnected();
|
||||||
|
void error(const QString &errorMessage);
|
||||||
|
void logAvailable(const QString &log);
|
||||||
|
};
|
||||||
|
#endif
|
24
GPClient/vpn_json.cpp
Normal file
24
GPClient/vpn_json.cpp
Normal file
@ -0,0 +1,24 @@
|
|||||||
|
#include "vpn_json.h"
|
||||||
|
#include <QTextStream>
|
||||||
|
#include <QJsonDocument>
|
||||||
|
#include <QJsonObject>
|
||||||
|
#include <QJsonArray>
|
||||||
|
|
||||||
|
void VpnJson::connect(const QString &preferredServer, const QList<QString> &servers, const QString &username, const QString &passwd, const QString &extraArgs) {
|
||||||
|
QJsonArray sl;
|
||||||
|
for (const QString &srv : servers) {
|
||||||
|
sl.push_back(QJsonValue(srv));
|
||||||
|
}
|
||||||
|
QJsonObject j;
|
||||||
|
j["server"] = preferredServer;
|
||||||
|
j["availableServers"] = sl;
|
||||||
|
j["cookie"] = passwd;
|
||||||
|
QTextStream(stdout) << QJsonDocument(j).toJson(QJsonDocument::Compact) << "\n";
|
||||||
|
emit connected();
|
||||||
|
}
|
||||||
|
|
||||||
|
void VpnJson::disconnect() { /* nop */ }
|
||||||
|
|
||||||
|
int VpnJson::status() {
|
||||||
|
return 4; // disconnected
|
||||||
|
}
|
23
GPClient/vpn_json.h
Normal file
23
GPClient/vpn_json.h
Normal file
@ -0,0 +1,23 @@
|
|||||||
|
#ifndef VPN_JSON_H
|
||||||
|
#define VPN_JSON_H
|
||||||
|
#include "vpn.h"
|
||||||
|
|
||||||
|
class VpnJson : public QObject, public IVpn
|
||||||
|
{
|
||||||
|
Q_OBJECT
|
||||||
|
Q_INTERFACES(IVpn)
|
||||||
|
|
||||||
|
public:
|
||||||
|
VpnJson(QObject *parent) : QObject(parent) {}
|
||||||
|
|
||||||
|
void connect(const QString &preferredServer, const QList<QString> &servers, const QString &username, const QString &passwd, const QString &extraArgs);
|
||||||
|
void disconnect();
|
||||||
|
int status();
|
||||||
|
|
||||||
|
signals: // SIGNALS
|
||||||
|
void connected();
|
||||||
|
void disconnected();
|
||||||
|
void error(const QString &errorMessage);
|
||||||
|
void logAvailable(const QString &log);
|
||||||
|
};
|
||||||
|
#endif
|
Loading…
Reference in New Issue
Block a user