added wireguard connection implementation for Linux

This commit is contained in:
vladimir.kuznetsov 2023-02-28 17:16:38 +03:00
parent 1dd79d9e31
commit caad670dbf
7 changed files with 133 additions and 37 deletions

View file

@ -47,11 +47,8 @@ void WireguardProtocol::stop()
m_wireguardStopProcess->setProgram(PermittedProcess::Wireguard); m_wireguardStopProcess->setProgram(PermittedProcess::Wireguard);
m_wireguardStopProcess->setArguments(stopArgs());
QStringList arguments({"--remove", configPath()}); qDebug() << stopArgs().join(" ");
m_wireguardStopProcess->setArguments(arguments);
qDebug() << arguments.join(" ");
connect(m_wireguardStopProcess.data(), &PrivilegedProcess::errorOccurred, this, [this](QProcess::ProcessError error) { connect(m_wireguardStopProcess.data(), &PrivilegedProcess::errorOccurred, this, [this](QProcess::ProcessError error) {
qDebug() << "WireguardProtocol::WireguardProtocol Stop errorOccurred" << error; qDebug() << "WireguardProtocol::WireguardProtocol Stop errorOccurred" << error;
@ -62,12 +59,25 @@ void WireguardProtocol::stop()
qDebug() << "WireguardProtocol::WireguardProtocol Stop stateChanged" << newState; qDebug() << "WireguardProtocol::WireguardProtocol Stop stateChanged" << newState;
}); });
#ifdef Q_OS_LINUX
if (IpcClient::Interface()) {
QRemoteObjectPendingReply<bool> result = IpcClient::Interface()->isWireguardRunning();
if (result.returnValue()) {
setConnectionState(VpnProtocol::Disconnected);
return;
}
} else {
qCritical() << "IPC client not initialized";
setConnectionState(VpnProtocol::Disconnected);
return;
}
#endif
m_wireguardStopProcess->start(); m_wireguardStopProcess->start();
m_wireguardStopProcess->waitForFinished(10000); m_wireguardStopProcess->waitForFinished(10000);
setConnectionState(VpnProtocol::Disconnected); setConnectionState(VpnProtocol::Disconnected);
#endif #endif
} }
void WireguardProtocol::writeWireguardConfiguration(const QJsonObject &configuration) void WireguardProtocol::writeWireguardConfiguration(const QJsonObject &configuration)
@ -79,13 +89,28 @@ void WireguardProtocol::writeWireguardConfiguration(const QJsonObject &configura
return; return;
} }
m_isConfigLoaded = true;
m_configFile.write(jConfig.value(config_key::config).toString().toUtf8()); m_configFile.write(jConfig.value(config_key::config).toString().toUtf8());
m_configFile.close(); m_configFile.close();
m_configFileName = m_configFile.fileName();
qDebug().noquote() << QString("Set config data") << m_configFileName; #ifdef Q_OS_LINUX
if (IpcClient::Interface()) {
QRemoteObjectPendingReply<bool> result = IpcClient::Interface()->copyWireguardConfig(m_configFile.fileName());
if (result.returnValue()) {
qCritical() << "Failed to copy wireguard config";
return;
}
} else {
qCritical() << "IPC client not initialized";
return;
}
m_configFileName = "/etc/wireguard/wg99.conf";
#else
m_configFileName = m_configFile.fileName();
#endif
m_isConfigLoaded = true;
qDebug().noquote() << QString("Set config data") << configPath();
qDebug().noquote() << QString("Set config data") << configuration.value(ProtocolProps::key_proto_config_data(Proto::WireGuard)).toString().toUtf8(); qDebug().noquote() << QString("Set config data") << configuration.value(ProtocolProps::key_proto_config_data(Proto::WireGuard)).toString().toUtf8();
} }
@ -120,10 +145,10 @@ ErrorCode WireguardProtocol::start()
return lastError(); return lastError();
} }
if (!QFileInfo::exists(configPath())) { // if (!QFileInfo::exists(configPath())) {
setLastError(ErrorCode::ConfigMissing); // setLastError(ErrorCode::ConfigMissing);
return lastError(); // return lastError();
} // }
setConnectionState(VpnConnectionState::Connecting); setConnectionState(VpnConnectionState::Connecting);
@ -143,11 +168,8 @@ ErrorCode WireguardProtocol::start()
m_wireguardStartProcess->setProgram(PermittedProcess::Wireguard); m_wireguardStartProcess->setProgram(PermittedProcess::Wireguard);
m_wireguardStartProcess->setArguments(startArgs());
QStringList arguments({"--add", configPath()}); qDebug() << startArgs().join(" ");
m_wireguardStartProcess->setArguments(arguments);
qDebug() << arguments.join(" ");
connect(m_wireguardStartProcess.data(), &PrivilegedProcess::errorOccurred, this, [this](QProcess::ProcessError error) { connect(m_wireguardStartProcess.data(), &PrivilegedProcess::errorOccurred, this, [this](QProcess::ProcessError error) {
qDebug() << "WireguardProtocol::WireguardProtocol errorOccurred" << error; qDebug() << "WireguardProtocol::WireguardProtocol errorOccurred" << error;
@ -211,3 +233,26 @@ QString WireguardProtocol::serviceName() const
{ {
return "AmneziaVPN.WireGuard0"; return "AmneziaVPN.WireGuard0";
} }
QStringList WireguardProtocol::stopArgs()
{
#ifdef Q_OS_WIN
return {"--remove", configPath()};
#elif defined Q_OS_LINUX
return {"down", "wg99"};
#else
return {"--remove", configPath()};
#endif
}
QStringList WireguardProtocol::startArgs()
{
#ifdef Q_OS_WIN
return {"--add", configPath()};
#elif defined Q_OS_LINUX
return {"up", "wg99"};
#else
return {"--add", configPath()};
#endif
}

View file

@ -28,7 +28,8 @@ private:
void updateRouteGateway(QString line); void updateRouteGateway(QString line);
void updateVpnGateway(const QString &line); void updateVpnGateway(const QString &line);
QString serviceName() const; QString serviceName() const;
QStringList stopArgs();
QStringList startArgs();
private: private:
QString m_configFileName; QString m_configFileName;
@ -36,6 +37,7 @@ private:
QSharedPointer<PrivilegedProcess> m_wireguardStartProcess; QSharedPointer<PrivilegedProcess> m_wireguardStartProcess;
QSharedPointer<PrivilegedProcess> m_wireguardStopProcess; QSharedPointer<PrivilegedProcess> m_wireguardStopProcess;
IpcClient *m_ipcClient;
bool m_isConfigLoaded = false; bool m_isConfigLoaded = false;

View file

@ -231,7 +231,7 @@ QString Utils::wireguardExecPath()
#ifdef Q_OS_WIN #ifdef Q_OS_WIN
return Utils::executable("wireguard/wireguard-service", true); return Utils::executable("wireguard/wireguard-service", true);
#elif defined Q_OS_LINUX #elif defined Q_OS_LINUX
return Utils::usrExecutable("wg"); return Utils::usrExecutable("wg-quick");
#else #else
return Utils::executable("/wireguard", true); return Utils::executable("/wireguard", true);
#endif #endif

View file

@ -20,13 +20,12 @@ inline QString permittedProcessPath(PermittedProcess pid)
{ {
if (pid == PermittedProcess::OpenVPN) { if (pid == PermittedProcess::OpenVPN) {
return Utils::openVpnExecPath(); return Utils::openVpnExecPath();
} } else if (pid == PermittedProcess::Wireguard) {
if (pid == PermittedProcess::Wireguard) {
return Utils::wireguardExecPath(); return Utils::wireguardExecPath();
} } else if (pid == PermittedProcess::CertUtil) {
else if (pid == PermittedProcess::CertUtil) {
return Utils::certUtilPath(); return Utils::certUtilPath();
} }
return "";
} }

View file

@ -18,5 +18,8 @@ class IpcInterface
SLOT( void cleanUp() ); SLOT( void cleanUp() );
SLOT( void setLogsEnabled(bool enabled) ); SLOT( void setLogsEnabled(bool enabled) );
SLOT( bool copyWireguardConfig(const QString &sourcePath) );
SLOT( bool isWireguardRunning() );
}; };

View file

@ -124,3 +124,48 @@ void IpcServer::setLogsEnabled(bool enabled)
Logger::deinit(); Logger::deinit();
} }
} }
bool IpcServer::copyWireguardConfig(const QString &sourcePath)
{
#ifdef Q_OS_LINUX
QProcess copyWireguardConfigProcess;
bool errorOccurred = false;
connect(&copyWireguardConfigProcess, &QProcess::errorOccurred, this, [&errorOccurred](QProcess::ProcessError error) {
qDebug() << "WireguardProtocol::WireguardProtocol error occured while copying wireguard config: " << error;
errorOccurred = true;
});
copyWireguardConfigProcess.setProgram("/bin/cp");
copyWireguardConfigProcess.setArguments(QStringList{sourcePath, "/etc/wireguard/wg99.conf"});
copyWireguardConfigProcess.start();
copyWireguardConfigProcess.waitForFinished(10000);
return errorOccurred;
#else
return false;
#endif
}
bool IpcServer::isWireguardRunning()
{
#ifdef Q_OS_LINUX
QProcess checkWireguardStatusProcess;
connect(&checkWireguardStatusProcess, &QProcess::errorOccurred, this, [](QProcess::ProcessError error) {
qDebug() << "WireguardProtocol::WireguardProtocol error occured while checking wireguard status: " << error;
});
checkWireguardStatusProcess.setProgram("/bin/wg");
checkWireguardStatusProcess.setArguments(QStringList{"show"});
checkWireguardStatusProcess.start();
checkWireguardStatusProcess.waitForFinished(10000);
QString output = checkWireguardStatusProcess.readAllStandardOutput();
if (!output.isEmpty()) {
return true;
}
return false;
#else
return false;
#endif
}

View file

@ -25,6 +25,8 @@ public:
virtual QStringList getTapList() override; virtual QStringList getTapList() override;
virtual void cleanUp() override; virtual void cleanUp() override;
virtual void setLogsEnabled(bool enabled) override; virtual void setLogsEnabled(bool enabled) override;
virtual bool copyWireguardConfig(const QString &sourcePath) override;
virtual bool isWireguardRunning() override;
private: private:
int m_localpid = 0; int m_localpid = 0;