Merge branch 'dev' into wireguard_embedded
This commit is contained in:
commit
83256de752
353 changed files with 182964 additions and 13459 deletions
|
|
@ -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);
|
||||
|
||||
|
|
|
|||
|
|
@ -22,7 +22,7 @@ public:
|
|||
|
||||
virtual ~AndroidVpnProtocol() override = default;
|
||||
|
||||
void initialize();
|
||||
bool initialize();
|
||||
|
||||
virtual ErrorCode start() override;
|
||||
virtual void stop() override;
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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";
|
||||
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue