added checking for dangerous strings in openvpn configuration files
This commit is contained in:
parent
d90685600e
commit
f3cd3d4f06
4 changed files with 90 additions and 3 deletions
|
@ -3,8 +3,8 @@
|
||||||
#include <QFile>
|
#include <QFile>
|
||||||
#include <QFileInfo>
|
#include <QFileInfo>
|
||||||
#include <QQuickItem>
|
#include <QQuickItem>
|
||||||
#include <QStandardPaths>
|
|
||||||
#include <QRandomGenerator>
|
#include <QRandomGenerator>
|
||||||
|
#include <QStandardPaths>
|
||||||
|
|
||||||
#include "core/errorstrings.h"
|
#include "core/errorstrings.h"
|
||||||
#ifdef Q_OS_ANDROID
|
#ifdef Q_OS_ANDROID
|
||||||
|
@ -103,7 +103,11 @@ bool ImportController::extractConfigFromData(QString data)
|
||||||
switch (m_configType) {
|
switch (m_configType) {
|
||||||
case ConfigTypes::OpenVpn: {
|
case ConfigTypes::OpenVpn: {
|
||||||
m_config = extractOpenVpnConfig(config);
|
m_config = extractOpenVpnConfig(config);
|
||||||
return m_config.empty() ? false : true;
|
if (!m_config.empty()) {
|
||||||
|
checkForMaliciousStrings(m_config);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
case ConfigTypes::Awg:
|
case ConfigTypes::Awg:
|
||||||
case ConfigTypes::WireGuard: {
|
case ConfigTypes::WireGuard: {
|
||||||
|
@ -116,7 +120,11 @@ bool ImportController::extractConfigFromData(QString data)
|
||||||
}
|
}
|
||||||
case ConfigTypes::Amnezia: {
|
case ConfigTypes::Amnezia: {
|
||||||
m_config = QJsonDocument::fromJson(config.toUtf8()).object();
|
m_config = QJsonDocument::fromJson(config.toUtf8()).object();
|
||||||
return m_config.empty() ? false : true;
|
if (!m_config.empty()) {
|
||||||
|
checkForMaliciousStrings(m_config);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
case ConfigTypes::Backup: {
|
case ConfigTypes::Backup: {
|
||||||
if (!m_serversModel->getServersCount()) {
|
if (!m_serversModel->getServersCount()) {
|
||||||
|
@ -161,6 +169,11 @@ QString ImportController::getConfigFileName()
|
||||||
return m_configFileName;
|
return m_configFileName;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
QString ImportController::getMaliciousWarningText()
|
||||||
|
{
|
||||||
|
return m_maliciousWarningText;
|
||||||
|
}
|
||||||
|
|
||||||
bool ImportController::isNativeWireGuardConfig()
|
bool ImportController::isNativeWireGuardConfig()
|
||||||
{
|
{
|
||||||
return m_configType == ConfigTypes::WireGuard;
|
return m_configType == ConfigTypes::WireGuard;
|
||||||
|
@ -223,6 +236,7 @@ void ImportController::importConfig()
|
||||||
|
|
||||||
m_config = {};
|
m_config = {};
|
||||||
m_configFileName.clear();
|
m_configFileName.clear();
|
||||||
|
m_maliciousWarningText.clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
QJsonObject ImportController::extractOpenVpnConfig(const QString &data)
|
QJsonObject ImportController::extractOpenVpnConfig(const QString &data)
|
||||||
|
@ -526,3 +540,43 @@ QString ImportController::getQrCodeScanProgressString()
|
||||||
return tr("Scanned %1 of %2.").arg(m_receivedQrCodeChunksCount).arg(m_totalQrCodeChunksCount);
|
return tr("Scanned %1 of %2.").arg(m_receivedQrCodeChunksCount).arg(m_totalQrCodeChunksCount);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
void ImportController::checkForMaliciousStrings(const QJsonObject &serverConfig)
|
||||||
|
{
|
||||||
|
const QJsonArray &containers = serverConfig[config_key::containers].toArray();
|
||||||
|
for (const QJsonValue &container : containers) {
|
||||||
|
auto containerConfig = container.toObject();
|
||||||
|
auto containerName = containerConfig[config_key::container].toString();
|
||||||
|
if ((containerName == ContainerProps::containerToString(DockerContainer::OpenVpn))
|
||||||
|
|| (containerName == ContainerProps::containerToString(DockerContainer::Cloak))
|
||||||
|
|| (containerName == ContainerProps::containerToString(DockerContainer::ShadowSocks))) {
|
||||||
|
QString protocolConfig =
|
||||||
|
containerConfig[ProtocolProps::protoToString(Proto::OpenVpn)].toObject()[config_key::last_config].toString();
|
||||||
|
QString protocolConfigJson = QJsonDocument::fromJson(protocolConfig.toUtf8()).object()[config_key::config].toString();
|
||||||
|
|
||||||
|
const QRegularExpression regExp { "(\\w+-\\w+|\\w+)" };
|
||||||
|
const size_t dangerousTagsMaxCount = 3;
|
||||||
|
|
||||||
|
// https://github.com/OpenVPN/openvpn/blob/master/doc/man-sections/script-options.rst
|
||||||
|
QStringList dangerousTags {
|
||||||
|
"up", "tls-verify", "ipchange", "client-connect", "route-up", "route-pre-down", "client-disconnect", "down", "learn-address", "auth-user-pass-verify"
|
||||||
|
};
|
||||||
|
|
||||||
|
QStringList maliciousStrings;
|
||||||
|
QStringList lines = protocolConfigJson.replace("\r", "").split("\n");
|
||||||
|
for (const QString &l : lines) {
|
||||||
|
QRegularExpressionMatch match = regExp.match(l);
|
||||||
|
if (dangerousTags.contains(match.captured(0))) {
|
||||||
|
maliciousStrings << l;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (maliciousStrings.size() >= dangerousTagsMaxCount) {
|
||||||
|
m_maliciousWarningText = tr("In the imported configuration, potentially dangerous lines were found:");
|
||||||
|
for (const auto &string : maliciousStrings) {
|
||||||
|
m_maliciousWarningText.push_back(QString("<br><i>%1</i>").arg(string));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -34,6 +34,7 @@ public slots:
|
||||||
bool extractConfigFromQr(const QByteArray &data);
|
bool extractConfigFromQr(const QByteArray &data);
|
||||||
QString getConfig();
|
QString getConfig();
|
||||||
QString getConfigFileName();
|
QString getConfigFileName();
|
||||||
|
QString getMaliciousWarningText();
|
||||||
|
|
||||||
#if defined Q_OS_ANDROID || defined Q_OS_IOS
|
#if defined Q_OS_ANDROID || defined Q_OS_IOS
|
||||||
void startDecodingQr();
|
void startDecodingQr();
|
||||||
|
@ -63,6 +64,8 @@ private:
|
||||||
QJsonObject extractWireGuardConfig(const QString &data);
|
QJsonObject extractWireGuardConfig(const QString &data);
|
||||||
QJsonObject extractXrayConfig(const QString &data);
|
QJsonObject extractXrayConfig(const QString &data);
|
||||||
|
|
||||||
|
void checkForMaliciousStrings(const QJsonObject &protocolConfig);
|
||||||
|
|
||||||
#if defined Q_OS_ANDROID || defined Q_OS_IOS
|
#if defined Q_OS_ANDROID || defined Q_OS_IOS
|
||||||
void stopDecodingQr();
|
void stopDecodingQr();
|
||||||
#endif
|
#endif
|
||||||
|
@ -74,6 +77,7 @@ private:
|
||||||
QJsonObject m_config;
|
QJsonObject m_config;
|
||||||
QString m_configFileName;
|
QString m_configFileName;
|
||||||
ConfigTypes m_configType;
|
ConfigTypes m_configType;
|
||||||
|
QString m_maliciousWarningText;
|
||||||
|
|
||||||
#if defined Q_OS_ANDROID || defined Q_OS_IOS
|
#if defined Q_OS_ANDROID || defined Q_OS_IOS
|
||||||
QMap<int, QByteArray> m_qrCodeChunks;
|
QMap<int, QByteArray> m_qrCodeChunks;
|
||||||
|
|
|
@ -1,13 +1,18 @@
|
||||||
import QtQuick
|
import QtQuick
|
||||||
import QtQuick.Controls
|
import QtQuick.Controls
|
||||||
import QtQuick.Layouts
|
import QtQuick.Layouts
|
||||||
|
import Qt5Compat.GraphicalEffects
|
||||||
|
|
||||||
import "TextTypes"
|
import "TextTypes"
|
||||||
|
|
||||||
Rectangle {
|
Rectangle {
|
||||||
|
id: root
|
||||||
|
|
||||||
property string textColor: "#D7D8DB"
|
property string textColor: "#D7D8DB"
|
||||||
property string backGroundColor: "#1C1D21"
|
property string backGroundColor: "#1C1D21"
|
||||||
|
property string imageColor: "#D7D8DB"
|
||||||
property string textString
|
property string textString
|
||||||
|
property int textFormat: Text.PlainText
|
||||||
|
|
||||||
property string iconPath
|
property string iconPath
|
||||||
property real iconWidth: 16
|
property real iconWidth: 16
|
||||||
|
@ -36,6 +41,13 @@ Rectangle {
|
||||||
height: iconHeight
|
height: iconHeight
|
||||||
|
|
||||||
source: iconPath
|
source: iconPath
|
||||||
|
|
||||||
|
layer {
|
||||||
|
enabled: true
|
||||||
|
effect: ColorOverlay {
|
||||||
|
color: imageColor
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
CaptionTextType {
|
CaptionTextType {
|
||||||
|
@ -45,6 +57,7 @@ Rectangle {
|
||||||
Layout.leftMargin: 8
|
Layout.leftMargin: 8
|
||||||
|
|
||||||
text: textString
|
text: textString
|
||||||
|
textFormat: root.textFormat
|
||||||
color: textColor
|
color: textColor
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -125,6 +125,20 @@ PageType {
|
||||||
text: qsTr("Enable WireGuard obfuscation. It may be useful if WireGuard is blocked on your provider.")
|
text: qsTr("Enable WireGuard obfuscation. It may be useful if WireGuard is blocked on your provider.")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
WarningType {
|
||||||
|
Layout.topMargin: 16
|
||||||
|
Layout.fillWidth: true
|
||||||
|
|
||||||
|
textString: ImportController.getMaliciousWarningText()
|
||||||
|
textFormat: Qt.RichText
|
||||||
|
visible: textString !== ""
|
||||||
|
|
||||||
|
iconPath: "qrc:/images/controls/alert-circle.svg"
|
||||||
|
|
||||||
|
textColor: "#EB5757"
|
||||||
|
imageColor: "#EB5757"
|
||||||
|
}
|
||||||
|
|
||||||
WarningType {
|
WarningType {
|
||||||
Layout.topMargin: 16
|
Layout.topMargin: 16
|
||||||
Layout.fillWidth: true
|
Layout.fillWidth: true
|
||||||
|
@ -151,6 +165,8 @@ PageType {
|
||||||
anchors.fill: parent
|
anchors.fill: parent
|
||||||
anchors.margins: 16
|
anchors.margins: 16
|
||||||
|
|
||||||
|
wrapMode: Text.Wrap
|
||||||
|
|
||||||
text: ImportController.getConfig()
|
text: ImportController.getConfig()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue