ikev2 impl for windows
This commit is contained in:
parent
8084b2764a
commit
64e5e02744
2 changed files with 196 additions and 8 deletions
|
@ -9,6 +9,7 @@
|
||||||
#include "ikev2_vpn_protocol.h"
|
#include "ikev2_vpn_protocol.h"
|
||||||
#include "utils.h"
|
#include "utils.h"
|
||||||
|
|
||||||
|
|
||||||
Ikev2Protocol::Ikev2Protocol(const QJsonObject &configuration, QObject* parent) :
|
Ikev2Protocol::Ikev2Protocol(const QJsonObject &configuration, QObject* parent) :
|
||||||
VpnProtocol(configuration, parent)
|
VpnProtocol(configuration, parent)
|
||||||
{
|
{
|
||||||
|
@ -25,34 +26,193 @@ Ikev2Protocol::~Ikev2Protocol()
|
||||||
|
|
||||||
void Ikev2Protocol::stop()
|
void Ikev2Protocol::stop()
|
||||||
{
|
{
|
||||||
#ifndef Q_OS_IOS
|
#ifdef Q_OS_WINDOWS
|
||||||
|
{
|
||||||
|
setConnectionState(Disconnecting);
|
||||||
|
|
||||||
|
auto disconnectProcess = new QProcess;
|
||||||
|
|
||||||
|
disconnectProcess->setProgram("rasdial");
|
||||||
|
QString arguments = QString("\"%1\" /disconnect")
|
||||||
|
.arg(tunnelName());
|
||||||
|
disconnectProcess->setNativeArguments(arguments);
|
||||||
|
|
||||||
|
// connect(connectProcess, &QProcess::readyRead, [connectProcess]() {
|
||||||
|
// qDebug().noquote() << "connectProcess readyRead" << connectProcess->readAll();
|
||||||
|
// });
|
||||||
|
|
||||||
|
disconnectProcess->start();
|
||||||
|
disconnectProcess->waitForFinished(5000);
|
||||||
|
setConnectionState(Disconnected);
|
||||||
|
}
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
void Ikev2Protocol::readIkev2Configuration(const QJsonObject &configuration)
|
void Ikev2Protocol::readIkev2Configuration(const QJsonObject &configuration)
|
||||||
{
|
{
|
||||||
QString cfgData = configuration.value(ProtocolProps::key_proto_config_data(Protocol::Ikev2)).toString();
|
m_config = configuration.value(ProtocolProps::key_proto_config_data(Protocol::Ikev2)).toObject();
|
||||||
m_config = QJsonDocument::fromJson(cfgData.toUtf8()).object();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
ErrorCode Ikev2Protocol::start()
|
ErrorCode Ikev2Protocol::start()
|
||||||
{
|
{
|
||||||
#ifndef Q_OS_IOS
|
#ifdef Q_OS_WINDOWS
|
||||||
|
|
||||||
QByteArray cert = QByteArray::fromBase64(m_config[config_key::cert].toString().toUtf8());
|
QByteArray cert = QByteArray::fromBase64(m_config[config_key::cert].toString().toUtf8());
|
||||||
qDebug() << "Ikev2Protocol::start()" << cert;
|
setConnectionState(ConnectionState::Connecting);
|
||||||
|
|
||||||
QTemporaryFile certFile;
|
QTemporaryFile certFile;
|
||||||
|
certFile.setAutoRemove(false);
|
||||||
certFile.open();
|
certFile.open();
|
||||||
certFile.write(cert);
|
certFile.write(cert);
|
||||||
certFile.close();
|
certFile.close();
|
||||||
|
|
||||||
|
|
||||||
|
{
|
||||||
|
auto certInstallProcess = IpcClient::CreatePrivilegedProcess();
|
||||||
|
|
||||||
|
if (!certInstallProcess) {
|
||||||
|
setLastError(ErrorCode::AmneziaServiceConnectionFailed);
|
||||||
|
return ErrorCode::AmneziaServiceConnectionFailed;
|
||||||
|
}
|
||||||
|
|
||||||
|
certInstallProcess->waitForSource(1000);
|
||||||
|
if (!certInstallProcess->isInitialized()) {
|
||||||
|
qWarning() << "IpcProcess replica is not connected!";
|
||||||
|
setLastError(ErrorCode::AmneziaServiceConnectionFailed);
|
||||||
|
return ErrorCode::AmneziaServiceConnectionFailed;
|
||||||
|
}
|
||||||
|
certInstallProcess->setProgram("certutil");
|
||||||
|
QStringList arguments({"-f" , "-importpfx",
|
||||||
|
"-p", m_config[config_key::password].toString(),
|
||||||
|
certFile.fileName(), "NoExport"
|
||||||
|
});
|
||||||
|
certInstallProcess->setArguments(arguments);
|
||||||
|
|
||||||
|
// qDebug() << arguments.join(" ");
|
||||||
|
// connect(certInstallProcess.data(), &IpcProcessInterfaceReplica::errorOccurred, [certInstallProcess](QProcess::ProcessError error) {
|
||||||
|
// qDebug() << "IpcProcessInterfaceReplica errorOccurred" << error;
|
||||||
|
// });
|
||||||
|
|
||||||
|
// connect(certInstallProcess.data(), &IpcProcessInterfaceReplica::stateChanged, [certInstallProcess](QProcess::ProcessState newState) {
|
||||||
|
// qDebug() << "IpcProcessInterfaceReplica stateChanged" << newState;
|
||||||
|
// });
|
||||||
|
|
||||||
|
// connect(certInstallProcess.data(), &IpcProcessInterfaceReplica::readyRead, [certInstallProcess]() {
|
||||||
|
// auto req = certInstallProcess->readAll();
|
||||||
|
// req.waitForFinished();
|
||||||
|
// qDebug() << "IpcProcessInterfaceReplica readyRead" << req.returnValue();
|
||||||
|
// });
|
||||||
|
|
||||||
|
|
||||||
|
certInstallProcess->start();
|
||||||
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
auto adapterRemoveProcess = new QProcess;
|
||||||
|
|
||||||
|
adapterRemoveProcess->setProgram("powershell");
|
||||||
|
QString arguments = QString("-command \"Remove-VpnConnection -Name '%1' -Force\"").arg(tunnelName());
|
||||||
|
adapterRemoveProcess->setNativeArguments(arguments);
|
||||||
|
|
||||||
|
adapterRemoveProcess->start();
|
||||||
|
adapterRemoveProcess->waitForFinished(5000);
|
||||||
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
auto adapterInstallProcess = new QProcess;
|
||||||
|
|
||||||
|
adapterInstallProcess->setProgram("powershell");
|
||||||
|
QString arguments = QString("-command \"Add-VpnConnection "
|
||||||
|
"-ServerAddress '%1' "
|
||||||
|
"-Name '%2' "
|
||||||
|
"-TunnelType IKEv2 "
|
||||||
|
"-AuthenticationMethod MachineCertificate "
|
||||||
|
"-EncryptionLevel Required "
|
||||||
|
"-PassThru\"")
|
||||||
|
.arg(m_config[config_key::hostName].toString())
|
||||||
|
.arg(tunnelName());
|
||||||
|
adapterInstallProcess->setNativeArguments(arguments);
|
||||||
|
// connect(adapterInstallProcess, &QProcess::readyRead, [adapterInstallProcess]() {
|
||||||
|
// qDebug().noquote() << "adapterInstallProcess readyRead" << adapterInstallProcess->readAll();
|
||||||
|
// });
|
||||||
|
|
||||||
|
adapterInstallProcess->start();
|
||||||
|
adapterInstallProcess->waitForFinished(5000);
|
||||||
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
auto adapterConfigProcess = new QProcess;
|
||||||
|
|
||||||
|
adapterConfigProcess->setProgram("powershell");
|
||||||
|
QString arguments = QString("-command \"Set-VpnConnectionIPsecConfiguration\ "
|
||||||
|
"-ConnectionName '%1'\ "
|
||||||
|
"-AuthenticationTransformConstants GCMAES128 "
|
||||||
|
"-CipherTransformConstants GCMAES128 "
|
||||||
|
"-EncryptionMethod AES256 "
|
||||||
|
"-IntegrityCheckMethod SHA256 "
|
||||||
|
"-PfsGroup None "
|
||||||
|
"-DHGroup Group14 "
|
||||||
|
"-PassThru -Force\"")
|
||||||
|
.arg(tunnelName());
|
||||||
|
adapterConfigProcess->setNativeArguments(arguments);
|
||||||
|
|
||||||
|
// connect(adapterConfigProcess, &QProcess::readyRead, [adapterConfigProcess]() {
|
||||||
|
// qDebug().noquote() << "adapterConfigProcess readyRead" << adapterConfigProcess->readAll();
|
||||||
|
// });
|
||||||
|
|
||||||
|
adapterConfigProcess->start();
|
||||||
|
adapterConfigProcess->waitForFinished(5000);
|
||||||
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
// char buf[RASBUFFER]= {0};
|
||||||
|
// DWORD err = 0;
|
||||||
|
// RASDIALPARAMSA *param = (RASDIALPARAMSA *)buf;
|
||||||
|
// param->dwSize = 1064;
|
||||||
|
// strcpy(param->szEntryName, tunnelName().toStdString().c_str());
|
||||||
|
// err = RasDialA(NULL, NULL, param, 0, (LPVOID)rasCallback, &g_h);
|
||||||
|
// qDebug() << "Ikev2Protocol::start() ret" << err;
|
||||||
|
|
||||||
|
|
||||||
|
auto connectProcess = new QProcess;
|
||||||
|
|
||||||
|
connectProcess->setProgram("rasdial");
|
||||||
|
QString arguments = QString("\"%1\"")
|
||||||
|
.arg(tunnelName());
|
||||||
|
connectProcess->setNativeArguments(arguments);
|
||||||
|
|
||||||
|
connect(connectProcess, &QProcess::readyRead, [connectProcess]() {
|
||||||
|
qDebug().noquote() << "connectProcess readyRead" << connectProcess->readAll();
|
||||||
|
});
|
||||||
|
|
||||||
|
connectProcess->start();
|
||||||
|
connectProcess->waitForFinished(5000);
|
||||||
|
}
|
||||||
|
|
||||||
|
setConnectionState(Connected);
|
||||||
return ErrorCode::NoError;
|
return ErrorCode::NoError;
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
return ErrorCode::NoError;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef Q_OS_WINDOWS
|
||||||
|
DWORD CALLBACK rasCallback(UINT msg, RASCONNSTATE rascs, DWORD err)
|
||||||
|
{
|
||||||
|
if(err != 0) {
|
||||||
|
printf("Error: %d\n", err);
|
||||||
|
fflush(stdout);
|
||||||
|
//g_done = 1;
|
||||||
|
return 0; // stop the connection.
|
||||||
|
} else {
|
||||||
|
//printf("%s\n", rasState(rascs));
|
||||||
|
fflush(stdout);
|
||||||
|
if(rascs == RASCS_Connected) {
|
||||||
|
printf("Success: Connected\n");
|
||||||
|
fflush(stdout);
|
||||||
|
//g_done = 1;
|
||||||
|
}
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
|
@ -10,6 +10,23 @@
|
||||||
#include "vpnprotocol.h"
|
#include "vpnprotocol.h"
|
||||||
#include "core/ipcclient.h"
|
#include "core/ipcclient.h"
|
||||||
|
|
||||||
|
#ifdef Q_OS_WIN
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
|
#include <windows.h>
|
||||||
|
#include <ras.h>
|
||||||
|
#include <raserror.h>
|
||||||
|
#include <shlwapi.h>
|
||||||
|
|
||||||
|
#pragma comment(lib, "shlwapi.lib")
|
||||||
|
#pragma comment(lib, "rasapi32.lib")
|
||||||
|
|
||||||
|
#define RASBUFFER 0x1000
|
||||||
|
#define RASMAXENUM 0x100
|
||||||
|
#endif
|
||||||
|
|
||||||
class Ikev2Protocol : public VpnProtocol
|
class Ikev2Protocol : public VpnProtocol
|
||||||
{
|
{
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
|
@ -21,12 +38,23 @@ public:
|
||||||
ErrorCode start() override;
|
ErrorCode start() override;
|
||||||
void stop() override;
|
void stop() override;
|
||||||
|
|
||||||
|
static QString tunnelName() { return "AmneziaVPN IKEv2"; }
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void readIkev2Configuration(const QJsonObject &configuration);
|
void readIkev2Configuration(const QJsonObject &configuration);
|
||||||
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
QJsonObject m_config;
|
QJsonObject m_config;
|
||||||
|
|
||||||
|
#ifdef Q_OS_WIN
|
||||||
|
HRASCONN g_h;
|
||||||
|
int g_done = 0;
|
||||||
|
#endif
|
||||||
};
|
};
|
||||||
|
|
||||||
|
#ifdef Q_OS_WIN
|
||||||
|
DWORD CALLBACK rasCallback(UINT msg, RASCONNSTATE rascs, DWORD err);
|
||||||
|
#endif
|
||||||
|
|
||||||
#endif // IPSEC_PROTOCOL_H
|
#endif // IPSEC_PROTOCOL_H
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue