Merge branch 'dev' into wireguard_embedded

This commit is contained in:
pokamest 2021-10-26 22:50:52 +03:00
commit 83256de752
353 changed files with 182964 additions and 13459 deletions

View file

@ -58,7 +58,7 @@ AndroidVpnProtocol* AndroidVpnProtocol::instance() {
return s_instance;
}
void AndroidVpnProtocol::initialize()
bool AndroidVpnProtocol::initialize()
{
qDebug() << "Initializing";
@ -81,55 +81,63 @@ void AndroidVpnProtocol::initialize()
"(Landroid/content/Context;)V", appContext.object());
// Start the VPN Service (if not yet) and Bind to it
QtAndroid::bindService(
const bool bindResult = QtAndroid::bindService(
QAndroidIntent(appContext.object(), "org.amnezia.vpn.VPNService"),
*this, QtAndroid::BindFlag::AutoCreate);
qDebug() << "Binding to the service..." << bindResult;
return bindResult;
}
ErrorCode AndroidVpnProtocol::start()
{
//qDebug().noquote() << "AndroidVpnProtocol::start" << QJsonDocument(m_rawConfig).toJson();
qDebug() << "Prompting for VPN permission";
auto appContext = QtAndroid::androidActivity().callObjectMethod(
"getApplicationContext", "()Landroid/content/Context;");
"getApplicationContext", "()Landroid/content/Context;");
QAndroidJniObject::callStaticMethod<void>(
PERMISSIONHELPER_CLASS, "startService", "(Landroid/content/Context;)V",
appContext.object());
PERMISSIONHELPER_CLASS, "startService", "(Landroid/content/Context;)V",
appContext.object());
// QJsonObject jServer;
// jServer["ipv4AddrIn"] = server.ipv4AddrIn();
// jServer["ipv4Gateway"] = server.ipv4Gateway();
// jServer["ipv6AddrIn"] = server.ipv6AddrIn();
// jServer["ipv6Gateway"] = server.ipv6Gateway();
// jServer["publicKey"] = server.publicKey();
// jServer["port"] = (int)server.choosePort();
// QJsonObject jServer;
// jServer["ipv4AddrIn"] = server.ipv4AddrIn();
// jServer["ipv4Gateway"] = server.ipv4Gateway();
// jServer["ipv6AddrIn"] = server.ipv6AddrIn();
// jServer["ipv6Gateway"] = server.ipv6Gateway();
// jServer["publicKey"] = server.publicKey();
// jServer["port"] = (int)server.choosePort();
// QJsonArray allowedIPs;
// foreach (auto item, allowedIPAddressRanges) {
// QJsonValue val;
// val = item.toString();
// allowedIPs.append(val);
// }
// QJsonArray allowedIPs;
// foreach (auto item, allowedIPAddressRanges) {
// QJsonValue val;
// val = item.toString();
// allowedIPs.append(val);
// }
// QJsonArray excludedApps;
// foreach (auto appID, vpnDisabledApps) {
// excludedApps.append(QJsonValue(appID));
// }
// QJsonArray excludedApps;
// foreach (auto appID, vpnDisabledApps) {
// excludedApps.append(QJsonValue(appID));
// }
// QJsonObject args;
// args["device"] = jDevice;
// args["keys"] = jKeys;
// args["server"] = jServer;
// args["reason"] = (int)reason;
// args["allowedIPs"] = allowedIPs;
// args["excludedApps"] = excludedApps;
// args["dns"] = dns.toString();
// QJsonObject args;
// args["device"] = jDevice;
// args["keys"] = jKeys;
// args["server"] = jServer;
// args["reason"] = (int)reason;
// args["allowedIPs"] = allowedIPs;
// args["excludedApps"] = excludedApps;
// args["dns"] = dns.toString();
QAndroidParcel sendData;
sendData.writeData(QJsonDocument(m_rawConfig).toJson());
m_serviceBinder.transact(ACTION_ACTIVATE, sendData, nullptr);
return NoError;
bool activateResult = false;
while (!activateResult){
activateResult = m_serviceBinder.transact(ACTION_ACTIVATE, sendData, nullptr);
}
return activateResult ? NoError : UnknownError;
}
// Activates the tunnel that is currently set
@ -212,7 +220,7 @@ void AndroidVpnProtocol::cleanupBackendLogs() {
void AndroidVpnProtocol::onServiceConnected(
const QString& name, const QAndroidBinder& serviceBinder) {
qDebug() << "Server connected";
qDebug() << "Server " + name + " connected";
Q_UNUSED(name);

View file

@ -22,7 +22,7 @@ public:
virtual ~AndroidVpnProtocol() override = default;
void initialize();
bool initialize();
virtual ErrorCode start() override;
virtual void stop() override;

View file

@ -1,18 +1,29 @@
#include <QCoreApplication>
#include <QFileInfo>
#include <QProcess>
#include <QRegularExpression>
#include <QTcpSocket>
//#include <QRegularExpression>
//#include <QTcpSocket>
#include <QThread>
#include <chrono>
#include "debug.h"
#include "ikev2_vpn_protocol.h"
#include "utils.h"
static Ikev2Protocol* self = nullptr;
static std::mutex rasDialFuncMutex;
extern "C" {
static void WINAPI RasDialFuncCallback(UINT unMsg,
RASCONNSTATE rasconnstate,
DWORD dwError );
}
Ikev2Protocol::Ikev2Protocol(const QJsonObject &configuration, QObject* parent) :
VpnProtocol(configuration, parent)
{
self = this;
//m_configFile.setFileTemplate(QDir::tempPath() + QDir::separator() + serviceName() + ".conf");
readIkev2Configuration(configuration);
}
@ -20,34 +31,214 @@ Ikev2Protocol::Ikev2Protocol(const QJsonObject &configuration, QObject* parent)
Ikev2Protocol::~Ikev2Protocol()
{
qDebug() << "IpsecProtocol::~IpsecProtocol()";
#ifdef Q_OS_WIN
disconnect_vpn();
#endif
Ikev2Protocol::stop();
QThread::msleep(200);
}
void Ikev2Protocol::stop()
{
setConnectionState(VpnProtocol::Disconnecting);
#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);
if (! disconnect_vpn() ){
qDebug()<<"We don't disconnect";
setConnectionState(VpnProtocol::Error);
}
else {
setConnectionState(VpnProtocol::Disconnected);
}
}
#endif
}
void Ikev2Protocol::newConnectionStateEventReceived(UINT unMsg, tagRASCONNSTATE rasconnstate, DWORD dwError)
{
Q_UNUSED(unMsg);
qDebug()<<"Recive the new event "<<static_cast<int>(rasconnstate);
switch (rasconnstate)
{
case RASCS_OpenPort:
qDebug()<<__FUNCTION__ << __LINE__;
setConnectionState(Preparing);
//printf ("RASCS_OpenPort = %d\n", _connection_state);
//printf ("Opening port...\n");
break;
case RASCS_PortOpened:
qDebug()<<__FUNCTION__ << __LINE__;
setConnectionState(Preparing);
//printf ("RASCS_PortOpened = %d\n", _connection_state);
//printf ("Port opened.\n");
break;
case RASCS_ConnectDevice:
qDebug()<<__FUNCTION__ << __LINE__;
setConnectionState(Preparing);
//printf ("RASCS_ConnectDevice = %d\n", _connection_state);
//printf ("Connecting device...\n");
break;
case RASCS_DeviceConnected:
qDebug()<<__FUNCTION__ << __LINE__;
setConnectionState(Preparing);
//printf ("RASCS_DeviceConnected = %d\n", _connection_state);
//printf ("Device connected.\n");
break;
case RASCS_AllDevicesConnected:
qDebug()<<__FUNCTION__ << __LINE__;
setConnectionState(Preparing);
//printf ("RASCS_AllDevicesConnected = %d\n", _connection_state);
//printf ("All devices connected.\n");
break;
case RASCS_Authenticate:
qDebug()<<__FUNCTION__ << __LINE__;
setConnectionState(Preparing);
//printf ("RASCS_Authenticate = %d\n", _connection_state);
// printf ("Authenticating...\n");
break;
case RASCS_AuthNotify:
qDebug()<<__FUNCTION__ << __LINE__;
if (dwError != 0) {
qDebug() << "have error" << dwError;
setConnectionState(Disconnected);
} else {
qDebug() << "RASCS_AuthNotify but no error" << dwError;
}
//printf ("RASCS_AuthNotify = %d\n", _connection_state);
// printf ("Authentication notify.\n");
break;
case RASCS_AuthRetry:
qDebug()<<__FUNCTION__ << __LINE__;
setConnectionState(Preparing);
//printf ("RASCS_AuthRetry = %d\n", _connection_state);
//printf ("Retrying authentication...\n");
break;
case RASCS_AuthCallback:
qDebug()<<__FUNCTION__ << __LINE__;
//printf ("RASCS_AuthCallback = %d\n", _connection_state);
//printf ("Authentication callback...\n");
break;
case RASCS_AuthChangePassword:
qDebug()<<__FUNCTION__ << __LINE__;
// printf ("RASCS_AuthChangePassword = %d\n", _connection_state);
//printf ("Change password...\n");
break;
case RASCS_AuthProject:
qDebug()<<__FUNCTION__ << __LINE__;
//printf ("RASCS_AuthProject = %d\n", _connection_state);
//printf ("Projection phase started...\n");
break;
case RASCS_AuthLinkSpeed:
qDebug()<<__FUNCTION__ << __LINE__;
//printf ("RASCS_AuthLinkSpeed = %d\n", _connection_state);
//printf ("Negoting speed...\n");
break;
case RASCS_AuthAck:
qDebug()<<__FUNCTION__ << __LINE__;
//printf ("RASCS_AuthAck = %d\n", _connection_state);
//printf ("Authentication acknowledge...\n");
break;
case RASCS_ReAuthenticate:
qDebug()<<__FUNCTION__ << __LINE__;
//printf ("RASCS_ReAuthenticate = %d\n", _connection_state);
//printf ("Retrying Authentication...\n");
break;
case RASCS_Authenticated:
qDebug()<<__FUNCTION__ << __LINE__;
//printf ("RASCS_Authenticated = %d\n", _connection_state);
//printf ("Authentication complete.\n");
break;
case RASCS_PrepareForCallback:
qDebug()<<__FUNCTION__ << __LINE__;
//printf ("RASCS_PrepareForCallback = %d\n", _connection_state);
//printf ("Preparing for callback...\n");
break;
case RASCS_WaitForModemReset:
qDebug()<<__FUNCTION__ << __LINE__;
//printf ("RASCS_WaitForModemReset = %d\n", _connection_state);
// printf ("Waiting for modem reset...\n");
break;
case RASCS_WaitForCallback:
qDebug()<<__FUNCTION__ << __LINE__;
//printf ("RASCS_WaitForCallback = %d\n", _connection_state);
//printf ("Waiting for callback...\n");
break;
case RASCS_Projected:
qDebug()<<__FUNCTION__ << __LINE__;
//printf ("RASCS_Projected = %d\n", _connection_state);
//printf ("Projection completed.\n");
break;
#if (WINVER >= 0x400)
case RASCS_StartAuthentication: // Windows 95 only
qDebug()<<__FUNCTION__ << __LINE__;
//printf ("RASCS_StartAuthentication = %d\n", _connection_state);
//printf ("Starting authentication...\n");
break;
case RASCS_CallbackComplete: // Windows 95 only
qDebug()<<__FUNCTION__ << __LINE__;
//printf ("RASCS_CallbackComplete = %d\n", rasconnstate);
//printf ("Callback complete.\n");
break;
case RASCS_LogonNetwork: // Windows 95 only
qDebug()<<__FUNCTION__ << __LINE__;
//printf ("RASCS_LogonNetwork = %d\n", _connection_state);
//printf ("Login to the network.\n");
break;
#endif
case RASCS_SubEntryConnected:
qDebug()<<__FUNCTION__ << __LINE__;
//printf ("RASCS_SubEntryConnected = %d\n", _connection_state);
//printf ("Subentry connected.\n");
break;
case RASCS_SubEntryDisconnected:
qDebug()<<__FUNCTION__ << __LINE__;
//printf ("RASCS_SubEntryDisconnected = %d\n", _connection_state);
//printf ("Subentry disconnected.\n");
break;
//PAUSED STATES:
case RASCS_Interactive:
qDebug()<<__FUNCTION__ << __LINE__;
//printf ("RASCS_Interactive = %d\n", _connection_state);
//printf ("In Paused state: Interactive mode.\n");
break;
case RASCS_RetryAuthentication:
qDebug()<<__FUNCTION__ << __LINE__;
//printf ("RASCS_RetryAuthentication = %d\n", _connection_state);
//printf ("In Paused state: Retry Authentication...\n");
break;
case RASCS_CallbackSetByCaller:
qDebug()<<__FUNCTION__ << __LINE__;
//printf ("RASCS_CallbackSetByCaller = %d\n", _connection_state);
//printf ("In Paused state: Callback set by Caller.\n");
break;
case RASCS_PasswordExpired:
setConnectionState(Error);
qDebug()<<__FUNCTION__ << __LINE__;
//printf ("RASCS_PasswordExpired = %d\n", _connection_state);
//printf ("In Paused state: Password has expired...\n");
break;
case RASCS_Connected: // = RASCS_DONE:
setConnectionState(Connected);
qDebug()<<__FUNCTION__ << __LINE__;
//printf ("RASCS_Connected = %d\n", _connection_state);
//printf ("Connection completed.\n");
//SetEvent(gEvent_handle);
break;
case RASCS_Disconnected:
setConnectionState(Disconnected);
qDebug()<<__FUNCTION__ << __LINE__;
//printf ("RASCS_Disconnected = %d\n", _connection_state);
//printf ("Disconnecting...\n");
break;
default:
qDebug()<<__FUNCTION__ << __LINE__;
//printf ("Unknown Status = %d\n", _connection_state);
//printf ("What are you going to do about it?\n");
break;
}
}
void Ikev2Protocol::readIkev2Configuration(const QJsonObject &configuration)
{
m_config = configuration.value(ProtocolProps::key_proto_config_data(Protocol::Ikev2)).toObject();
@ -57,7 +248,7 @@ ErrorCode Ikev2Protocol::start()
{
#ifdef Q_OS_WINDOWS
QByteArray cert = QByteArray::fromBase64(m_config[config_key::cert].toString().toUtf8());
setConnectionState(ConnectionState::Connecting);
setConnectionState(Connecting);
QTemporaryFile certFile;
certFile.setAutoRemove(false);
@ -65,7 +256,6 @@ ErrorCode Ikev2Protocol::start()
certFile.write(cert);
certFile.close();
{
auto certInstallProcess = IpcClient::CreatePrivilegedProcess();
@ -87,64 +277,71 @@ ErrorCode Ikev2Protocol::start()
});
certInstallProcess->setArguments(arguments);
// qDebug() << arguments.join(" ");
// connect(certInstallProcess.data(), &IpcProcessInterfaceReplica::errorOccurred, [certInstallProcess](QProcess::ProcessError error) {
// qDebug() << "IpcProcessInterfaceReplica errorOccurred" << error;
// });
// 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::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();
// });
// connect(certInstallProcess.data(), &IpcProcessInterfaceReplica::readyRead, [certInstallProcess]() {
// auto req = certInstallProcess->readAll();
// req.waitForFinished();
// qDebug() << "IpcProcessInterfaceReplica readyRead" << req.returnValue();
// });
certInstallProcess->start();
}
// /*
{
auto adapterRemoveProcess = new QProcess;
// auto adapterRemoveProcess = new QProcess;
adapterRemoveProcess->setProgram("powershell");
QString arguments = QString("-command \"Remove-VpnConnection -Name '%1' -Force\"").arg(tunnelName());
adapterRemoveProcess->setNativeArguments(arguments);
// adapterRemoveProcess->setProgram("powershell");
// QString arguments = QString("-command \"Remove-VpnConnection -Name '%1' -Force\"").arg(tunnelName());
// adapterRemoveProcess->setNativeArguments(arguments);
adapterRemoveProcess->start();
adapterRemoveProcess->waitForFinished(5000);
// adapterRemoveProcess->start();
// adapterRemoveProcess->waitForFinished(5000);
if ( disconnect_vpn()){
qDebug()<<"VPN was disconnected";
}
if ( delete_vpn_connection (tunnelName())){
qDebug()<<"VPN was deleted";
}
}
{
auto adapterInstallProcess = new QProcess;
{
if ( !create_new_vpn(tunnelName(), m_config[config_key::hostName].toString())){
qDebug() <<"Can't create the VPN connect";
}
}
// 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);
// 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);
// adapterInstallProcess->start();
// adapterInstallProcess->waitForFinished(5000);
}
{
auto adapterConfigProcess = new QProcess;
adapterConfigProcess->setProgram("powershell");
QString arguments = QString("-command \"Set-VpnConnectionIPsecConfiguration\ "
"-ConnectionName '%1'\ "
QString arguments = QString("-command \"Set-VpnConnectionIPsecConfiguration\" "
"-ConnectionName '%1' "
"-AuthenticationTransformConstants GCMAES128 "
"-CipherTransformConstants GCMAES128 "
"-EncryptionMethod AES256 "
@ -152,67 +349,98 @@ ErrorCode Ikev2Protocol::start()
"-PfsGroup None "
"-DHGroup Group14 "
"-PassThru -Force\"")
.arg(tunnelName());
.arg(tunnelName());
adapterConfigProcess->setNativeArguments(arguments);
// connect(adapterConfigProcess, &QProcess::readyRead, [adapterConfigProcess]() {
// qDebug().noquote() << "adapterConfigProcess readyRead" << adapterConfigProcess->readAll();
// });
// 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;
#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;
if (!connect_to_vpn(tunnelName())) {
qDebug()<<"We can't connect to VPN";
}
return 1;
}
//setConnectionState(Connecting);
return ErrorCode::NoError;
#else
return ErrorCode::NoError;
#endif
}
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
#ifdef Q_OS_WINDOWS
bool Ikev2Protocol::create_new_vpn(const QString & vpn_name,
const QString & serv_addr){
if ( RasValidateEntryName(nullptr, vpn_name.toStdWString().c_str()) != ERROR_SUCCESS)
return false;
DWORD size = 0;
::RasGetEntryProperties(nullptr, L"", nullptr, &size, nullptr, nullptr);
LPRASENTRY pras = static_cast<LPRASENTRY>(malloc(size));
memset(pras, 0, size);
pras->dwSize = size;
pras->dwType = RASET_Vpn;
pras->dwRedialCount = 1;
pras->dwRedialPause = 60;
pras->dwfNetProtocols = RASNP_Ip|RASNP_Ipv6;
pras->dwEncryptionType = ET_RequireMax;
wcscpy_s(pras->szLocalPhoneNumber, serv_addr.toStdWString().c_str());
wcscpy_s(pras->szDeviceType, RASDT_Vpn);
pras->dwfOptions = RASEO_RemoteDefaultGateway;
pras->dwfOptions |= RASEO_RequireDataEncryption;
pras->dwfOptions2 |= RASEO2_RequireMachineCertificates;
pras->dwVpnStrategy = VS_Ikev2Only;
const auto nRet = ::RasSetEntryProperties(nullptr, vpn_name.toStdWString().c_str(), pras, pras->dwSize, NULL, 0);
free(pras);
if (nRet == ERROR_SUCCESS)
return true;
return false;
}
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
bool Ikev2Protocol::delete_vpn_connection(const QString &vpn_name){
if ( RasDeleteEntry(nullptr, vpn_name.toStdWString().c_str()) == ERROR_SUCCESS){
return true;
}
return false;
}
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
bool Ikev2Protocol::connect_to_vpn(const QString & vpn_name){
RASDIALPARAMS RasDialParams;
memset(&RasDialParams, 0x0, sizeof(RASDIALPARAMS));
RasDialParams.dwSize = sizeof(RASDIALPARAMS);
wcscpy_s(RasDialParams.szEntryName, vpn_name.toStdWString().c_str());
auto ret = RasDial(NULL, NULL, &RasDialParams, 0,
&RasDialFuncCallback,
&hRasConn);
if (ret == ERROR_SUCCESS){
return true;
}
return false;
}
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
bool Ikev2Protocol::disconnect_vpn(){
if ( hRasConn != nullptr ){
if ( RasHangUp(hRasConn) != ERROR_SUCCESS)
return false;
}
QThread::msleep(3000);
return true;
}
void WINAPI RasDialFuncCallback(UINT unMsg,
RASCONNSTATE rasconnstate,
DWORD dwError ){
std::lock_guard<std::mutex> guard(rasDialFuncMutex);
if (self) {
self->newConnectionStateEventReceived(unMsg, rasconnstate, dwError);
}
}
#endif

View file

@ -11,20 +11,26 @@
#include "core/ipcclient.h"
#ifdef Q_OS_WIN
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <string>
#include <memory>
#include <atomic>
#include <thread>
#include <condition_variable>
#include <mutex>
#include <stdio.h>
#include <windows.h>
#include <ras.h>
#include <Ras.h>
#include <raserror.h>
#include <shlwapi.h>
#include <wincrypt.h>
#pragma comment(lib, "shlwapi.lib")
#pragma comment(lib, "rasapi32.lib")
#pragma comment(lib, "Crypt32.lib")
#define RASBUFFER 0x1000
#define RASMAXENUM 0x100
#endif
class Ikev2Protocol : public VpnProtocol
@ -40,17 +46,32 @@ public:
static QString tunnelName() { return "AmneziaVPN IKEv2"; }
public:
void newConnectionStateEventReceived(UINT unMsg,
RASCONNSTATE rasconnstate,
DWORD dwError);
private:
void readIkev2Configuration(const QJsonObject &configuration);
#ifdef Q_OS_WIN
//certificates variables
#endif
private:
QJsonObject m_config;
#ifdef Q_OS_WIN
HRASCONN g_h;
int g_done = 0;
//RAS functions and parametrs
HRASCONN hRasConn{nullptr};
bool create_new_vpn(const QString & vpn_name,
const QString & serv_addr);
bool delete_vpn_connection(const QString &vpn_name);
bool connect_to_vpn(const QString & vpn_name);
bool disconnect_vpn();
#endif
};
#ifdef Q_OS_WIN

View file

@ -34,6 +34,13 @@ constexpr char hash[] = "hash";
constexpr char ncp_disable[] = "ncp_disable";
constexpr char tls_auth[] = "tls_auth";
constexpr char client_priv_key[] = "client_priv_key";
constexpr char client_pub_key[] = "client_pub_key";
constexpr char server_priv_key[] = "server_priv_key";
constexpr char server_pub_key[] = "server_pub_key";
constexpr char psk_key[] = "psk_key";
constexpr char site[] = "site";
constexpr char block_outside_dns[] = "block_outside_dns";

View file

@ -4,11 +4,13 @@
#include "vpnprotocol.h"
#include "core/errorstrings.h"
#if defined(Q_OS_WINDOWS) || defined(Q_OS_MACX) || (defined(Q_OS_LINUX) && !defined(Q_OS_ANDROID))
#include "openvpnprotocol.h"
#include "shadowsocksvpnprotocol.h"
#include "openvpnovercloakprotocol.h"
#include "wireguardprotocol.h"
#include "ikev2_vpn_protocol.h"
#endif
VpnProtocol::VpnProtocol(const QJsonObject &configuration, QObject* parent)
@ -98,12 +100,13 @@ QString VpnProtocol::vpnGateway() const
VpnProtocol *VpnProtocol::factory(DockerContainer container, const QJsonObject& configuration)
{
switch (container) {
#if defined(Q_OS_WINDOWS) || defined(Q_OS_MACX) || (defined(Q_OS_LINUX) && !defined(Q_OS_ANDROID))
case DockerContainer::OpenVpn: return new OpenVpnProtocol(configuration);
case DockerContainer::Cloak: return new OpenVpnOverCloakProtocol(configuration);
case DockerContainer::ShadowSocks: return new ShadowSocksVpnProtocol(configuration);
case DockerContainer::WireGuard: return new WireguardProtocol(configuration);
case DockerContainer::Ipsec: return new Ikev2Protocol(configuration);
#endif
default: return nullptr;
}
}