mirror of
https://github.com/yuezk/GlobalProtect-openconnect.git
synced 2025-04-02 18:31:50 -04:00
Add 2FA support (#112)
This commit is contained in:
parent
9d6ec84c14
commit
8f27c92e7b
130
.github/workflows/build.yml
vendored
130
.github/workflows/build.yml
vendored
@ -67,62 +67,19 @@ jobs:
|
|||||||
name: snapshot-source-code
|
name: snapshot-source-code
|
||||||
path: artifacts
|
path: artifacts
|
||||||
|
|
||||||
- name: Import GPG key
|
- name: Extract source code
|
||||||
id: import_gpg
|
run: |
|
||||||
uses: crazy-max/ghaction-import-gpg@v4
|
cd $GITHUB_WORKSPACE/artifacts
|
||||||
|
mkdir deb-build && cp *.tar.gz deb-build && cd deb-build
|
||||||
|
tar xf *.tar.gz
|
||||||
|
|
||||||
|
- name: Publish PPA
|
||||||
|
uses: yuezk/publish-ppa-package@develop
|
||||||
with:
|
with:
|
||||||
|
repository: 'ppa:yuezk/globalprotect-openconnect-snapshot'
|
||||||
gpg_private_key: ${{ secrets.PPA_GPG_PRIVATE_KEY }}
|
gpg_private_key: ${{ secrets.PPA_GPG_PRIVATE_KEY }}
|
||||||
passphrase: ${{ secrets.PPA_GPG_PASSPHRASE }}
|
gpg_passphrase: ${{ secrets.PPA_GPG_PASSPHRASE }}
|
||||||
|
pkgdir: '${{ github.workspace }}/artifacts/deb-build/globalprotect-openconnect*/'
|
||||||
- name: Install dependencies
|
|
||||||
run: |
|
|
||||||
sudo apt update
|
|
||||||
sudo apt install debmake debhelper cmake \
|
|
||||||
libqt5websockets5-dev qtbase5-dev qtwebengine5-dev
|
|
||||||
|
|
||||||
- name: Build deb package for 18.04
|
|
||||||
run: |
|
|
||||||
cd $GITHUB_WORKSPACE/artifacts
|
|
||||||
mkdir build-18.04
|
|
||||||
cp *.tar.gz build-18.04 && cd build-18.04
|
|
||||||
tar xf *.tar.gz
|
|
||||||
cd globalprotect-openconnect-*/
|
|
||||||
|
|
||||||
PPA_GPG_PASSPHRASE=${{ secrets.PPA_GPG_PASSPHRASE }} \
|
|
||||||
PPA_GPG_KEYID=${{ steps.import_gpg.outputs.keyid }} ./scripts/ppa-publish.sh 18.04
|
|
||||||
|
|
||||||
- name: Build deb package for 20.04
|
|
||||||
run: |
|
|
||||||
cd $GITHUB_WORKSPACE/artifacts
|
|
||||||
mkdir build-20.04
|
|
||||||
cp *.tar.gz build-20.04 && cd build-20.04
|
|
||||||
tar xf *.tar.gz
|
|
||||||
cd globalprotect-openconnect-*/
|
|
||||||
|
|
||||||
PPA_GPG_PASSPHRASE=${{ secrets.PPA_GPG_PASSPHRASE }} \
|
|
||||||
PPA_GPG_KEYID=${{ steps.import_gpg.outputs.keyid }} ./scripts/ppa-publish.sh 20.04
|
|
||||||
|
|
||||||
- name: Build deb package for 21.04
|
|
||||||
run: |
|
|
||||||
cd $GITHUB_WORKSPACE/artifacts
|
|
||||||
mkdir build-21.04
|
|
||||||
cp *.tar.gz build-21.04 && cd build-21.04
|
|
||||||
tar xf *.tar.gz
|
|
||||||
cd globalprotect-openconnect-*/
|
|
||||||
|
|
||||||
PPA_GPG_PASSPHRASE=${{ secrets.PPA_GPG_PASSPHRASE }} \
|
|
||||||
PPA_GPG_KEYID=${{ steps.import_gpg.outputs.keyid }} ./scripts/ppa-publish.sh 21.04
|
|
||||||
|
|
||||||
- name: Build deb package for 21.10
|
|
||||||
run: |
|
|
||||||
cd $GITHUB_WORKSPACE/artifacts
|
|
||||||
mkdir build-21.10
|
|
||||||
cp *.tar.gz build-21.10 && cd build-21.10
|
|
||||||
tar xf *.tar.gz
|
|
||||||
cd globalprotect-openconnect-*/
|
|
||||||
|
|
||||||
PPA_GPG_PASSPHRASE=${{ secrets.PPA_GPG_PASSPHRASE }} \
|
|
||||||
PPA_GPG_KEYID=${{ steps.import_gpg.outputs.keyid }} ./scripts/ppa-publish.sh 21.10
|
|
||||||
|
|
||||||
snapshot-aur:
|
snapshot-aur:
|
||||||
if: ${{ github.event_name != 'pull_request' && github.ref == 'refs/heads/develop' }}
|
if: ${{ github.event_name != 'pull_request' && github.ref == 'refs/heads/develop' }}
|
||||||
@ -233,62 +190,19 @@ jobs:
|
|||||||
name: release-source-code
|
name: release-source-code
|
||||||
path: artifacts
|
path: artifacts
|
||||||
|
|
||||||
- name: Import GPG key
|
- name: Extract source code
|
||||||
id: import_gpg
|
run: |
|
||||||
uses: crazy-max/ghaction-import-gpg@v4
|
cd $GITHUB_WORKSPACE/artifacts
|
||||||
|
mkdir deb-build && cp *.tar.gz deb-build && cd deb-build
|
||||||
|
tar xf *.tar.gz
|
||||||
|
|
||||||
|
- name: Publish PPA
|
||||||
|
uses: yuezk/publish-ppa-package@develop
|
||||||
with:
|
with:
|
||||||
|
repository: 'ppa:yuezk/globalprotect-openconnect'
|
||||||
gpg_private_key: ${{ secrets.PPA_GPG_PRIVATE_KEY }}
|
gpg_private_key: ${{ secrets.PPA_GPG_PRIVATE_KEY }}
|
||||||
passphrase: ${{ secrets.PPA_GPG_PASSPHRASE }}
|
gpg_passphrase: ${{ secrets.PPA_GPG_PASSPHRASE }}
|
||||||
|
pkgdir: '${{ github.workspace }}/artifacts/deb-build/globalprotect-openconnect*/'
|
||||||
- name: Install dependencies
|
|
||||||
run: |
|
|
||||||
sudo apt update
|
|
||||||
sudo apt install debmake debhelper cmake \
|
|
||||||
libqt5websockets5-dev qtbase5-dev qtwebengine5-dev
|
|
||||||
|
|
||||||
- name: Build deb package for 18.04
|
|
||||||
run: |
|
|
||||||
cd $GITHUB_WORKSPACE/artifacts
|
|
||||||
mkdir build-18.04
|
|
||||||
cp *.tar.gz build-18.04 && cd build-18.04
|
|
||||||
tar xf *.tar.gz
|
|
||||||
cd globalprotect-openconnect-*/
|
|
||||||
|
|
||||||
PPA_GPG_PASSPHRASE=${{ secrets.PPA_GPG_PASSPHRASE }} \
|
|
||||||
PPA_GPG_KEYID=${{ steps.import_gpg.outputs.keyid }} ./scripts/ppa-publish.sh 18.04 --stable
|
|
||||||
|
|
||||||
- name: Build deb package for 20.04
|
|
||||||
run: |
|
|
||||||
cd $GITHUB_WORKSPACE/artifacts
|
|
||||||
mkdir build-20.04
|
|
||||||
cp *.tar.gz build-20.04 && cd build-20.04
|
|
||||||
tar xf *.tar.gz
|
|
||||||
cd globalprotect-openconnect-*/
|
|
||||||
|
|
||||||
PPA_GPG_PASSPHRASE=${{ secrets.PPA_GPG_PASSPHRASE }} \
|
|
||||||
PPA_GPG_KEYID=${{ steps.import_gpg.outputs.keyid }} ./scripts/ppa-publish.sh 20.04 --stable
|
|
||||||
|
|
||||||
- name: Build deb package for 21.04
|
|
||||||
run: |
|
|
||||||
cd $GITHUB_WORKSPACE/artifacts
|
|
||||||
mkdir build-21.04
|
|
||||||
cp *.tar.gz build-21.04 && cd build-21.04
|
|
||||||
tar xf *.tar.gz
|
|
||||||
cd globalprotect-openconnect-*/
|
|
||||||
|
|
||||||
PPA_GPG_PASSPHRASE=${{ secrets.PPA_GPG_PASSPHRASE }} \
|
|
||||||
PPA_GPG_KEYID=${{ steps.import_gpg.outputs.keyid }} ./scripts/ppa-publish.sh 21.04 --stable
|
|
||||||
|
|
||||||
- name: Build deb package for 21.10
|
|
||||||
run: |
|
|
||||||
cd $GITHUB_WORKSPACE/artifacts
|
|
||||||
mkdir build-21.10
|
|
||||||
cp *.tar.gz build-21.10 && cd build-21.10
|
|
||||||
tar xf *.tar.gz
|
|
||||||
cd globalprotect-openconnect-*/
|
|
||||||
|
|
||||||
PPA_GPG_PASSPHRASE=${{ secrets.PPA_GPG_PASSPHRASE }} \
|
|
||||||
PPA_GPG_KEYID=${{ steps.import_gpg.outputs.keyid }} ./scripts/ppa-publish.sh 21.10 --stable
|
|
||||||
|
|
||||||
release-aur:
|
release-aur:
|
||||||
if: startsWith(github.ref, 'refs/tags/v')
|
if: startsWith(github.ref, 'refs/tags/v')
|
||||||
|
@ -33,6 +33,9 @@ add_executable(gpclient
|
|||||||
gpclient.ui
|
gpclient.ui
|
||||||
normalloginwindow.ui
|
normalloginwindow.ui
|
||||||
settingsdialog.ui
|
settingsdialog.ui
|
||||||
|
challengedialog.h
|
||||||
|
challengedialog.cpp
|
||||||
|
challengedialog.ui
|
||||||
vpn_dbus.cpp
|
vpn_dbus.cpp
|
||||||
vpn_json.cpp
|
vpn_json.cpp
|
||||||
resources.qrc
|
resources.qrc
|
||||||
|
38
GPClient/challengedialog.cpp
Normal file
38
GPClient/challengedialog.cpp
Normal file
@ -0,0 +1,38 @@
|
|||||||
|
#include <QtWidgets/QDialogButtonBox>
|
||||||
|
#include <QtWidgets/QPushButton>
|
||||||
|
|
||||||
|
#include "challengedialog.h"
|
||||||
|
#include "ui_challengedialog.h"
|
||||||
|
|
||||||
|
ChallengeDialog::ChallengeDialog(QWidget *parent) :
|
||||||
|
QDialog(parent),
|
||||||
|
ui(new Ui::ChallengeDialog)
|
||||||
|
{
|
||||||
|
ui->setupUi(this);
|
||||||
|
ui->buttonBox->button(QDialogButtonBox::Ok)->setDisabled(true);
|
||||||
|
}
|
||||||
|
|
||||||
|
ChallengeDialog::~ChallengeDialog()
|
||||||
|
{
|
||||||
|
delete ui;
|
||||||
|
}
|
||||||
|
|
||||||
|
void ChallengeDialog::setMessage(const QString &message)
|
||||||
|
{
|
||||||
|
ui->challengeMessage->setText(message);
|
||||||
|
}
|
||||||
|
|
||||||
|
const QString ChallengeDialog::getChallenge()
|
||||||
|
{
|
||||||
|
return ui->challengeInput->text();
|
||||||
|
}
|
||||||
|
|
||||||
|
void ChallengeDialog::on_challengeInput_textChanged(const QString &value)
|
||||||
|
{
|
||||||
|
QPushButton *okBtn = ui->buttonBox->button(QDialogButtonBox::Ok);
|
||||||
|
if (value.isEmpty()) {
|
||||||
|
okBtn->setDisabled(true);
|
||||||
|
} else {
|
||||||
|
okBtn->setEnabled(true);
|
||||||
|
}
|
||||||
|
}
|
28
GPClient/challengedialog.h
Normal file
28
GPClient/challengedialog.h
Normal file
@ -0,0 +1,28 @@
|
|||||||
|
#ifndef CHALLENGEDIALOG_H
|
||||||
|
#define CHALLENGEDIALOG_H
|
||||||
|
|
||||||
|
#include <QDialog>
|
||||||
|
|
||||||
|
namespace Ui {
|
||||||
|
class ChallengeDialog;
|
||||||
|
}
|
||||||
|
|
||||||
|
class ChallengeDialog : public QDialog
|
||||||
|
{
|
||||||
|
Q_OBJECT
|
||||||
|
|
||||||
|
public:
|
||||||
|
explicit ChallengeDialog(QWidget *parent = nullptr);
|
||||||
|
~ChallengeDialog();
|
||||||
|
|
||||||
|
void setMessage(const QString &message);
|
||||||
|
const QString getChallenge();
|
||||||
|
|
||||||
|
private slots:
|
||||||
|
void on_challengeInput_textChanged(const QString &arg1);
|
||||||
|
|
||||||
|
private:
|
||||||
|
Ui::ChallengeDialog *ui;
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif // CHALLENGEDIALOG_H
|
111
GPClient/challengedialog.ui
Normal file
111
GPClient/challengedialog.ui
Normal file
@ -0,0 +1,111 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<ui version="4.0">
|
||||||
|
<class>ChallengeDialog</class>
|
||||||
|
<widget class="QDialog" name="ChallengeDialog">
|
||||||
|
<property name="geometry">
|
||||||
|
<rect>
|
||||||
|
<x>0</x>
|
||||||
|
<y>0</y>
|
||||||
|
<width>405</width>
|
||||||
|
<height>200</height>
|
||||||
|
</rect>
|
||||||
|
</property>
|
||||||
|
<property name="windowTitle">
|
||||||
|
<string>GlobalProtect Challenge</string>
|
||||||
|
</property>
|
||||||
|
<property name="modal">
|
||||||
|
<bool>true</bool>
|
||||||
|
</property>
|
||||||
|
<layout class="QVBoxLayout" name="verticalLayout">
|
||||||
|
<item>
|
||||||
|
<layout class="QVBoxLayout" name="verticalLayout_2" stretch="1,1">
|
||||||
|
<item>
|
||||||
|
<widget class="QLabel" name="label">
|
||||||
|
<property name="font">
|
||||||
|
<font>
|
||||||
|
<pointsize>14</pointsize>
|
||||||
|
<weight>50</weight>
|
||||||
|
<bold>false</bold>
|
||||||
|
</font>
|
||||||
|
</property>
|
||||||
|
<property name="text">
|
||||||
|
<string>Sign In</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<widget class="QLabel" name="challengeMessage">
|
||||||
|
<property name="text">
|
||||||
|
<string>Duo two-factor login for [redacted] Enter a passcode or select one of the following options: 1. Duo Push to XXX-XXX-[redacted] 2. SMS passcodes to XXX-XXX-[redacted] Passcode or option (1-2): </string>
|
||||||
|
</property>
|
||||||
|
<property name="alignment">
|
||||||
|
<set>Qt::AlignLeading|Qt::AlignLeft|Qt::AlignTop</set>
|
||||||
|
</property>
|
||||||
|
<property name="wordWrap">
|
||||||
|
<bool>true</bool>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
</layout>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<widget class="QLineEdit" name="challengeInput">
|
||||||
|
<property name="echoMode">
|
||||||
|
<enum>QLineEdit::Password</enum>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<widget class="QDialogButtonBox" name="buttonBox">
|
||||||
|
<property name="layoutDirection">
|
||||||
|
<enum>Qt::LeftToRight</enum>
|
||||||
|
</property>
|
||||||
|
<property name="orientation">
|
||||||
|
<enum>Qt::Horizontal</enum>
|
||||||
|
</property>
|
||||||
|
<property name="standardButtons">
|
||||||
|
<set>QDialogButtonBox::Cancel|QDialogButtonBox::Ok</set>
|
||||||
|
</property>
|
||||||
|
<property name="centerButtons">
|
||||||
|
<bool>false</bool>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
</layout>
|
||||||
|
</widget>
|
||||||
|
<resources/>
|
||||||
|
<connections>
|
||||||
|
<connection>
|
||||||
|
<sender>buttonBox</sender>
|
||||||
|
<signal>accepted()</signal>
|
||||||
|
<receiver>ChallengeDialog</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>ChallengeDialog</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>
|
@ -1,14 +1,17 @@
|
|||||||
#include <QtNetwork/QNetworkReply>
|
#include <QtNetwork/QNetworkReply>
|
||||||
|
#include <QtCore/QRegularExpression>
|
||||||
|
#include <QtCore/QRegularExpressionMatch>
|
||||||
#include <plog/Log.h>
|
#include <plog/Log.h>
|
||||||
|
|
||||||
#include "gatewayauthenticator.h"
|
#include "gatewayauthenticator.h"
|
||||||
#include "gphelper.h"
|
#include "gphelper.h"
|
||||||
#include "loginparams.h"
|
#include "loginparams.h"
|
||||||
#include "preloginresponse.h"
|
#include "preloginresponse.h"
|
||||||
|
#include "challengedialog.h"
|
||||||
|
|
||||||
using namespace gpclient::helper;
|
using namespace gpclient::helper;
|
||||||
|
|
||||||
GatewayAuthenticator::GatewayAuthenticator(const QString& gateway, const GatewayAuthenticatorParams params)
|
GatewayAuthenticator::GatewayAuthenticator(const QString& gateway, GatewayAuthenticatorParams params)
|
||||||
: QObject()
|
: QObject()
|
||||||
, gateway(gateway)
|
, gateway(gateway)
|
||||||
, params(params)
|
, params(params)
|
||||||
@ -33,6 +36,7 @@ void GatewayAuthenticator::authenticate()
|
|||||||
loginParams.setUser(params.username());
|
loginParams.setUser(params.username());
|
||||||
loginParams.setPassword(params.password());
|
loginParams.setPassword(params.password());
|
||||||
loginParams.setUserAuthCookie(params.userAuthCookie());
|
loginParams.setUserAuthCookie(params.userAuthCookie());
|
||||||
|
loginParams.setInputStr(params.inputStr());
|
||||||
|
|
||||||
login(loginParams);
|
login(loginParams);
|
||||||
}
|
}
|
||||||
@ -48,10 +52,10 @@ void GatewayAuthenticator::login(const LoginParams &loginParams)
|
|||||||
void GatewayAuthenticator::onLoginFinished()
|
void GatewayAuthenticator::onLoginFinished()
|
||||||
{
|
{
|
||||||
QNetworkReply *reply = qobject_cast<QNetworkReply*>(sender());
|
QNetworkReply *reply = qobject_cast<QNetworkReply*>(sender());
|
||||||
QByteArray response;
|
QByteArray response = reply->readAll();
|
||||||
|
|
||||||
if (reply->error() || (response = reply->readAll()).contains("Authentication failure")) {
|
if (reply->error() || response.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, reply->errorString());
|
||||||
|
|
||||||
if (normalLoginWindow) {
|
if (normalLoginWindow) {
|
||||||
normalLoginWindow->setProcessing(false);
|
normalLoginWindow->setProcessing(false);
|
||||||
@ -62,6 +66,13 @@ void GatewayAuthenticator::onLoginFinished()
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 2FA
|
||||||
|
if (response.contains("Challenge")) {
|
||||||
|
PLOGI << "The server need input the challenge...";
|
||||||
|
showChallenge(response);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
if (normalLoginWindow) {
|
if (normalLoginWindow) {
|
||||||
normalLoginWindow->close();
|
normalLoginWindow->close();
|
||||||
}
|
}
|
||||||
@ -83,7 +94,7 @@ void GatewayAuthenticator::onPreloginFinished()
|
|||||||
QNetworkReply *reply = qobject_cast<QNetworkReply*>(sender());
|
QNetworkReply *reply = qobject_cast<QNetworkReply*>(sender());
|
||||||
|
|
||||||
if (reply->error()) {
|
if (reply->error()) {
|
||||||
PLOGE << QString("Failed to prelogin the gateway at %1, %2").arg(preloginUrl).arg(reply->errorString());
|
PLOGE << QString("Failed to prelogin the gateway at %1, %2").arg(preloginUrl, reply->errorString());
|
||||||
|
|
||||||
emit fail("Error occurred on the gateway prelogin interface.");
|
emit fail("Error occurred on the gateway prelogin interface.");
|
||||||
return;
|
return;
|
||||||
@ -98,7 +109,7 @@ void GatewayAuthenticator::onPreloginFinished()
|
|||||||
} else if (response.hasNormalAuthFields()) {
|
} else if (response.hasNormalAuthFields()) {
|
||||||
normalAuth(response.labelUsername(), response.labelPassword(), response.authMessage());
|
normalAuth(response.labelUsername(), response.labelPassword(), response.authMessage());
|
||||||
} else {
|
} else {
|
||||||
PLOGE << QString("Unknown prelogin response for %1, got %2").arg(preloginUrl).arg(QString::fromUtf8(response.rawResponse()));
|
PLOGE << QString("Unknown prelogin response for %1, got %2").arg(preloginUrl, QString::fromUtf8(response.rawResponse()));
|
||||||
emit fail("Unknown response for gateway prelogin interface.");
|
emit fail("Unknown response for gateway prelogin interface.");
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -107,7 +118,7 @@ void GatewayAuthenticator::onPreloginFinished()
|
|||||||
|
|
||||||
void GatewayAuthenticator::normalAuth(QString labelUsername, QString labelPassword, QString authMessage)
|
void GatewayAuthenticator::normalAuth(QString labelUsername, QString labelPassword, QString authMessage)
|
||||||
{
|
{
|
||||||
PLOGI << QString("Trying to perform the normal login with %1 / %2 credentials").arg(labelUsername).arg(labelPassword);
|
PLOGI << QString("Trying to perform the normal login with %1 / %2 credentials").arg(labelUsername, labelPassword);
|
||||||
|
|
||||||
normalLoginWindow = new NormalLoginWindow;
|
normalLoginWindow = new NormalLoginWindow;
|
||||||
normalLoginWindow->setPortalAddress(gateway);
|
normalLoginWindow->setPortalAddress(gateway);
|
||||||
@ -128,11 +139,10 @@ void GatewayAuthenticator::onPerformNormalLogin(const QString &username, const Q
|
|||||||
PLOGI << "Start to perform normal login...";
|
PLOGI << "Start to perform normal login...";
|
||||||
|
|
||||||
normalLoginWindow->setProcessing(true);
|
normalLoginWindow->setProcessing(true);
|
||||||
LoginParams loginParams { params.clientos() };
|
params.setUsername(username);
|
||||||
loginParams.setUser(username);
|
params.setPassword(password);
|
||||||
loginParams.setPassword(password);
|
|
||||||
|
|
||||||
login(loginParams);
|
authenticate();
|
||||||
}
|
}
|
||||||
|
|
||||||
void GatewayAuthenticator::onLoginWindowRejected()
|
void GatewayAuthenticator::onLoginWindowRejected()
|
||||||
@ -179,3 +189,38 @@ void GatewayAuthenticator::onSAMLLoginFail(const QString msg)
|
|||||||
{
|
{
|
||||||
emit fail(msg);
|
emit fail(msg);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void GatewayAuthenticator::showChallenge(const QString &responseText)
|
||||||
|
{
|
||||||
|
QRegularExpression re("\"(.*?)\";");
|
||||||
|
QRegularExpressionMatchIterator i = re.globalMatch(responseText);
|
||||||
|
|
||||||
|
i.next(); // Skip the status value
|
||||||
|
QString message = i.next().captured(1);
|
||||||
|
QString inputStr = i.next().captured(1);
|
||||||
|
// update the inputSrc field
|
||||||
|
params.setInputStr(inputStr);
|
||||||
|
|
||||||
|
challengeDialog = new ChallengeDialog;
|
||||||
|
challengeDialog->setMessage(message);
|
||||||
|
|
||||||
|
connect(challengeDialog, &ChallengeDialog::accepted, this, [this] {
|
||||||
|
params.setPassword(challengeDialog->getChallenge());
|
||||||
|
PLOGI << "Challenge submitted, try to re-authenticate...";
|
||||||
|
authenticate();
|
||||||
|
});
|
||||||
|
|
||||||
|
connect(challengeDialog, &ChallengeDialog::rejected, this, [this] {
|
||||||
|
if (normalLoginWindow) {
|
||||||
|
normalLoginWindow->close();
|
||||||
|
}
|
||||||
|
emit fail();
|
||||||
|
});
|
||||||
|
|
||||||
|
connect(challengeDialog, &ChallengeDialog::finished, this, [this] {
|
||||||
|
delete challengeDialog;
|
||||||
|
challengeDialog = nullptr;
|
||||||
|
});
|
||||||
|
|
||||||
|
challengeDialog->show();
|
||||||
|
}
|
||||||
|
@ -4,6 +4,7 @@
|
|||||||
#include <QtCore/QObject>
|
#include <QtCore/QObject>
|
||||||
|
|
||||||
#include "normalloginwindow.h"
|
#include "normalloginwindow.h"
|
||||||
|
#include "challengedialog.h"
|
||||||
#include "loginparams.h"
|
#include "loginparams.h"
|
||||||
#include "gatewayauthenticatorparams.h"
|
#include "gatewayauthenticatorparams.h"
|
||||||
|
|
||||||
@ -11,7 +12,7 @@ class GatewayAuthenticator : public QObject
|
|||||||
{
|
{
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
public:
|
public:
|
||||||
explicit GatewayAuthenticator(const QString& gateway, const GatewayAuthenticatorParams params);
|
explicit GatewayAuthenticator(const QString& gateway, GatewayAuthenticatorParams params);
|
||||||
~GatewayAuthenticator();
|
~GatewayAuthenticator();
|
||||||
|
|
||||||
void authenticate();
|
void authenticate();
|
||||||
@ -31,16 +32,18 @@ private slots:
|
|||||||
|
|
||||||
private:
|
private:
|
||||||
QString gateway;
|
QString gateway;
|
||||||
const GatewayAuthenticatorParams params;
|
GatewayAuthenticatorParams params;
|
||||||
QString preloginUrl;
|
QString preloginUrl;
|
||||||
QString loginUrl;
|
QString loginUrl;
|
||||||
|
|
||||||
NormalLoginWindow *normalLoginWindow{ nullptr };
|
NormalLoginWindow *normalLoginWindow{ nullptr };
|
||||||
|
ChallengeDialog *challengeDialog{ nullptr };
|
||||||
|
|
||||||
void login(const LoginParams& loginParams);
|
void login(const LoginParams& loginParams);
|
||||||
void doAuth();
|
void doAuth();
|
||||||
void normalAuth(QString labelUsername, QString labelPassword, QString authMessage);
|
void normalAuth(QString labelUsername, QString labelPassword, QString authMessage);
|
||||||
void samlAuth(QString samlMethod, QString samlRequest, QString preloginUrl = "");
|
void samlAuth(QString samlMethod, QString samlRequest, QString preloginUrl = "");
|
||||||
|
void showChallenge(const QString &responseText);
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // GATEWAYAUTHENTICATOR_H
|
#endif // GATEWAYAUTHENTICATOR_H
|
||||||
|
@ -55,3 +55,13 @@ void GatewayAuthenticatorParams::setClientos(const QString &newClientos)
|
|||||||
m_clientos = newClientos;
|
m_clientos = newClientos;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const QString &GatewayAuthenticatorParams::inputStr() const
|
||||||
|
{
|
||||||
|
return m_inputStr;
|
||||||
|
}
|
||||||
|
|
||||||
|
void GatewayAuthenticatorParams::setInputStr(const QString &inputStr)
|
||||||
|
{
|
||||||
|
m_inputStr = inputStr;
|
||||||
|
}
|
||||||
|
|
||||||
|
@ -24,11 +24,15 @@ public:
|
|||||||
const QString &clientos() const;
|
const QString &clientos() const;
|
||||||
void setClientos(const QString &newClientos);
|
void setClientos(const QString &newClientos);
|
||||||
|
|
||||||
|
const QString &inputStr() const;
|
||||||
|
void setInputStr(const QString &inputStr);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
QString m_username;
|
QString m_username;
|
||||||
QString m_password;
|
QString m_password;
|
||||||
QString m_userAuthCookie;
|
QString m_userAuthCookie;
|
||||||
QString m_clientos;
|
QString m_clientos;
|
||||||
|
QString m_inputStr;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // GATEWAYAUTHENTICATORPARAMS_H
|
#endif // GATEWAYAUTHENTICATORPARAMS_H
|
||||||
|
@ -6,7 +6,7 @@ LoginParams::LoginParams(const QString clientos)
|
|||||||
{
|
{
|
||||||
params.addQueryItem("prot", QUrl::toPercentEncoding("https:"));
|
params.addQueryItem("prot", QUrl::toPercentEncoding("https:"));
|
||||||
params.addQueryItem("server", "");
|
params.addQueryItem("server", "");
|
||||||
params.addQueryItem("inputSrc", "");
|
params.addQueryItem("inputStr", "");
|
||||||
params.addQueryItem("jnlpReady", "jnlpReady");
|
params.addQueryItem("jnlpReady", "jnlpReady");
|
||||||
params.addQueryItem("user", "");
|
params.addQueryItem("user", "");
|
||||||
params.addQueryItem("passwd", "");
|
params.addQueryItem("passwd", "");
|
||||||
@ -61,6 +61,11 @@ void LoginParams::setPreloginCookie(const QString cookie)
|
|||||||
updateQueryItem("prelogin-cookie", cookie);
|
updateQueryItem("prelogin-cookie", cookie);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void LoginParams::setInputStr(const QString inputStr)
|
||||||
|
{
|
||||||
|
updateQueryItem("inputStr", inputStr);
|
||||||
|
}
|
||||||
|
|
||||||
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 setInputStr(const QString inputStr);
|
||||||
|
|
||||||
QByteArray toUtf8() const;
|
QByteArray toUtf8() const;
|
||||||
|
|
||||||
|
@ -41,7 +41,7 @@ void PortalAuthenticator::onPreloginFinished()
|
|||||||
QNetworkReply *reply = qobject_cast<QNetworkReply*>(sender());
|
QNetworkReply *reply = qobject_cast<QNetworkReply*>(sender());
|
||||||
|
|
||||||
if (reply->error()) {
|
if (reply->error()) {
|
||||||
PLOGE << QString("Error occurred while accessing %1, %2").arg(preloginUrl).arg(reply->errorString());
|
PLOGE << QString("Error occurred while accessing %1, %2").arg(preloginUrl, reply->errorString());
|
||||||
emit preloginFailed("Error occurred on the portal prelogin interface.");
|
emit preloginFailed("Error occurred on the portal prelogin interface.");
|
||||||
delete reply;
|
delete reply;
|
||||||
return;
|
return;
|
||||||
|
2
debian/source/format
vendored
2
debian/source/format
vendored
@ -1 +1 @@
|
|||||||
3.0 (quilt)
|
3.0 (native)
|
Loading…
Reference in New Issue
Block a user