mirror of
https://github.com/amnezia-vpn/amnezia-client.git
synced 2026-06-22 02:01:08 +07:00
39d4c6f1ec
- Validate IP/CIDR values from IPC before passing to Linux firewall - Replace shell interpolation with direct execve in firewall update functions - Block dangerous OpenVPN/WireGuard arguments in sanitizeArguments() - Add programId bounds check in IpcServerProcess::setProgram() - Add SO_PEERCRED peer authentication for IPC connections on Linux
146 lines
3.9 KiB
C++
146 lines
3.9 KiB
C++
#ifndef IPC_H
|
|
#define IPC_H
|
|
|
|
#include <QObject>
|
|
#include <QString>
|
|
#include <QRegularExpression>
|
|
#include <QSet>
|
|
|
|
#include "../client/utilities.h"
|
|
|
|
#define IPC_SERVICE_URL "local:AmneziaVpnIpcInterface"
|
|
|
|
namespace amnezia {
|
|
|
|
enum PermittedProcess {
|
|
Invalid,
|
|
OpenVPN,
|
|
Wireguard,
|
|
Tun2Socks,
|
|
CertUtil,
|
|
_Count
|
|
};
|
|
|
|
inline QString permittedProcessPath(PermittedProcess pid)
|
|
{
|
|
switch (pid) {
|
|
case PermittedProcess::OpenVPN:
|
|
return Utils::openVpnExecPath();
|
|
case PermittedProcess::Wireguard:
|
|
return Utils::wireguardExecPath();
|
|
case PermittedProcess::CertUtil:
|
|
return Utils::certUtilPath();
|
|
case PermittedProcess::Tun2Socks:
|
|
return Utils::tun2socksPath();
|
|
default:
|
|
return "";
|
|
}
|
|
}
|
|
|
|
|
|
inline QString getIpcServiceUrl() {
|
|
#ifdef Q_OS_WIN
|
|
return IPC_SERVICE_URL;
|
|
#else
|
|
return QString("/tmp/%1").arg(IPC_SERVICE_URL);
|
|
#endif
|
|
}
|
|
|
|
inline QString getIpcProcessUrl(int pid) {
|
|
#ifdef Q_OS_WIN
|
|
return QString("%1_%2").arg(IPC_SERVICE_URL).arg(pid);
|
|
#else
|
|
return QString("/tmp/%1_%2").arg(IPC_SERVICE_URL).arg(pid);
|
|
#endif
|
|
}
|
|
|
|
inline QStringList sanitizeArguments(PermittedProcess proc, const QStringList &args) {
|
|
using Validator = std::function<bool(const QString&)>;
|
|
QMap<QString, Validator> namedArgs;
|
|
QList<Validator> positionalArgs;
|
|
|
|
switch (proc) {
|
|
case OpenVPN: {
|
|
static const QSet<QString> blocked = {
|
|
QStringLiteral("--script-security"),
|
|
QStringLiteral("--up"),
|
|
QStringLiteral("--down"),
|
|
QStringLiteral("--route-up"),
|
|
QStringLiteral("--ipchange"),
|
|
QStringLiteral("--tls-verify"),
|
|
QStringLiteral("--plugin"),
|
|
QStringLiteral("--auth-user-pass-verify"),
|
|
QStringLiteral("--learn-address"),
|
|
QStringLiteral("--client-connect"),
|
|
QStringLiteral("--client-disconnect"),
|
|
QStringLiteral("--management"),
|
|
QStringLiteral("--management-external-key")
|
|
};
|
|
QStringList out;
|
|
for (int i = 0; i < args.size(); ++i) {
|
|
if (blocked.contains(args[i])) {
|
|
qWarning() << "IPC: blocked OpenVPN argument:" << args[i];
|
|
++i; // skip following value
|
|
continue;
|
|
}
|
|
out << args[i];
|
|
}
|
|
return out;
|
|
}
|
|
case Wireguard: {
|
|
static const QRegularExpression hookRe(
|
|
QStringLiteral(R"((?i)(PostUp|PreUp|PostDown|PreDown)\s*=)"));
|
|
QStringList out;
|
|
for (const QString& a : args) {
|
|
if (hookRe.match(a).hasMatch()) {
|
|
qWarning() << "IPC: blocked WireGuard hook argument:" << a;
|
|
continue;
|
|
}
|
|
out << a;
|
|
}
|
|
return out;
|
|
}
|
|
case Tun2Socks:
|
|
namedArgs["-device"] = [](const QString& v) { return v.startsWith("tun://"); };
|
|
namedArgs["-proxy"] = [](const QString& v) { return v.startsWith("socks5://"); };
|
|
break;
|
|
case CertUtil:
|
|
return args;
|
|
default:
|
|
return {};
|
|
}
|
|
|
|
QStringList sanitized;
|
|
|
|
for (int i = 0, pos = 0; i < args.size(); i++) {
|
|
const auto& key = args[i];
|
|
|
|
if (const auto found = namedArgs.find(key); found != namedArgs.end()) {
|
|
const auto validator = found.value();
|
|
|
|
if (validator) {
|
|
if (i + 1 < args.size()) {
|
|
const auto& value = args[i+1];
|
|
if (validator(value)) {
|
|
sanitized << key << value;
|
|
i++;
|
|
}
|
|
}
|
|
} else {
|
|
sanitized << key;
|
|
}
|
|
} else if (pos < positionalArgs.size()) {
|
|
if (const auto validator = positionalArgs[pos]; validator && validator(key)) {
|
|
sanitized << key;
|
|
pos++;
|
|
}
|
|
}
|
|
}
|
|
|
|
return sanitized;
|
|
}
|
|
|
|
} // namespace amnezia
|
|
|
|
#endif // IPC_H
|