extended the validation of the contents of the imported file (#670)
Extended the validation of the contents of the imported file
This commit is contained in:
parent
0a90fd110d
commit
c5a5bfde69
8 changed files with 109 additions and 58 deletions
|
@ -18,7 +18,9 @@ namespace
|
||||||
enum class ConfigTypes {
|
enum class ConfigTypes {
|
||||||
Amnezia,
|
Amnezia,
|
||||||
OpenVpn,
|
OpenVpn,
|
||||||
WireGuard
|
WireGuard,
|
||||||
|
Backup,
|
||||||
|
Invalid
|
||||||
};
|
};
|
||||||
|
|
||||||
ConfigTypes checkConfigFormat(const QString &config)
|
ConfigTypes checkConfigFormat(const QString &config)
|
||||||
|
@ -32,7 +34,15 @@ namespace
|
||||||
const QString wireguardConfigPatternSectionInterface = "[Interface]";
|
const QString wireguardConfigPatternSectionInterface = "[Interface]";
|
||||||
const QString wireguardConfigPatternSectionPeer = "[Peer]";
|
const QString wireguardConfigPatternSectionPeer = "[Peer]";
|
||||||
|
|
||||||
if (config.contains(openVpnConfigPatternCli)
|
const QString amneziaConfigPattern = "containers";
|
||||||
|
const QString amneziaFreeConfigPattern = "api_key";
|
||||||
|
const QString backupPattern = "Servers/serversList";
|
||||||
|
|
||||||
|
if (config.contains(backupPattern)) {
|
||||||
|
return ConfigTypes::Backup;
|
||||||
|
} else if (config.contains(amneziaConfigPattern) || config.contains(amneziaFreeConfigPattern)) {
|
||||||
|
return ConfigTypes::Amnezia;
|
||||||
|
} else if (config.contains(openVpnConfigPatternCli)
|
||||||
&& (config.contains(openVpnConfigPatternProto1) || config.contains(openVpnConfigPatternProto2))
|
&& (config.contains(openVpnConfigPatternProto1) || config.contains(openVpnConfigPatternProto2))
|
||||||
&& (config.contains(openVpnConfigPatternDriver1) || config.contains(openVpnConfigPatternDriver2))) {
|
&& (config.contains(openVpnConfigPatternDriver1) || config.contains(openVpnConfigPatternDriver2))) {
|
||||||
return ConfigTypes::OpenVpn;
|
return ConfigTypes::OpenVpn;
|
||||||
|
@ -40,7 +50,7 @@ namespace
|
||||||
&& config.contains(wireguardConfigPatternSectionPeer)) {
|
&& config.contains(wireguardConfigPatternSectionPeer)) {
|
||||||
return ConfigTypes::WireGuard;
|
return ConfigTypes::WireGuard;
|
||||||
}
|
}
|
||||||
return ConfigTypes::Amnezia;
|
return ConfigTypes::Invalid;
|
||||||
}
|
}
|
||||||
|
|
||||||
#if defined Q_OS_ANDROID
|
#if defined Q_OS_ANDROID
|
||||||
|
@ -58,34 +68,65 @@ ImportController::ImportController(const QSharedPointer<ServersModel> &serversMo
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
void ImportController::extractConfigFromFile(const QString &fileName)
|
bool ImportController::extractConfigFromFile(const QString &fileName)
|
||||||
{
|
{
|
||||||
QFile file(fileName);
|
QFile file(fileName);
|
||||||
|
|
||||||
if (file.open(QIODevice::ReadOnly)) {
|
if (file.open(QIODevice::ReadOnly)) {
|
||||||
QString data = file.readAll();
|
QString data = file.readAll();
|
||||||
|
|
||||||
extractConfigFromData(data);
|
|
||||||
m_configFileName = QFileInfo(file.fileName()).fileName();
|
m_configFileName = QFileInfo(file.fileName()).fileName();
|
||||||
|
return extractConfigFromData(data);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
emit importErrorOccurred(tr("Unable to open file"));
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
void ImportController::extractConfigFromData(QString data)
|
bool ImportController::extractConfigFromData(QString data)
|
||||||
{
|
{
|
||||||
auto configFormat = checkConfigFormat(data);
|
QString config = data;
|
||||||
if (configFormat == ConfigTypes::OpenVpn) {
|
auto configFormat = checkConfigFormat(config);
|
||||||
m_config = extractOpenVpnConfig(data);
|
if (configFormat == ConfigTypes::Invalid) {
|
||||||
} else if (configFormat == ConfigTypes::WireGuard) {
|
data.replace("vpn://", "");
|
||||||
m_config = extractWireGuardConfig(data);
|
QByteArray ba =
|
||||||
|
QByteArray::fromBase64(data.toUtf8(), QByteArray::Base64UrlEncoding | QByteArray::OmitTrailingEquals);
|
||||||
|
QByteArray ba_uncompressed = qUncompress(ba);
|
||||||
|
if (!ba_uncompressed.isEmpty()) {
|
||||||
|
ba = ba_uncompressed;
|
||||||
|
}
|
||||||
|
|
||||||
|
config = ba;
|
||||||
|
configFormat = checkConfigFormat(config);
|
||||||
|
}
|
||||||
|
|
||||||
|
switch (configFormat) {
|
||||||
|
case ConfigTypes::OpenVpn: {
|
||||||
|
m_config = extractOpenVpnConfig(config);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
case ConfigTypes::WireGuard: {
|
||||||
|
m_config = extractWireGuardConfig(config);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
case ConfigTypes::Amnezia: {
|
||||||
|
m_config = QJsonDocument::fromJson(config.toUtf8()).object();
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
case ConfigTypes::Backup: {
|
||||||
|
if (!m_serversModel->getServersCount()) {
|
||||||
|
emit restoreAppConfig(config.toUtf8());
|
||||||
} else {
|
} else {
|
||||||
m_config = extractAmneziaConfig(data);
|
emit importErrorOccurred(tr("Invalid configuration file"));
|
||||||
}
|
}
|
||||||
}
|
break;
|
||||||
|
}
|
||||||
void ImportController::extractConfigFromCode(QString code)
|
case ConfigTypes::Invalid: {
|
||||||
{
|
emit importErrorOccurred(tr("Invalid configuration file"));
|
||||||
m_config = extractAmneziaConfig(code);
|
break;
|
||||||
m_configFileName = "";
|
}
|
||||||
|
}
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool ImportController::extractConfigFromQr(const QByteArray &data)
|
bool ImportController::extractConfigFromQr(const QByteArray &data)
|
||||||
|
@ -139,28 +180,13 @@ void ImportController::importConfig()
|
||||||
} else {
|
} else {
|
||||||
qDebug() << "Failed to import profile";
|
qDebug() << "Failed to import profile";
|
||||||
qDebug().noquote() << QJsonDocument(m_config).toJson();
|
qDebug().noquote() << QJsonDocument(m_config).toJson();
|
||||||
emit importErrorOccurred(errorString(ErrorCode::ImportInvalidConfigError));
|
emit importErrorOccurred(errorString(ErrorCode::ImportInvalidConfigError), false);
|
||||||
}
|
}
|
||||||
|
|
||||||
m_config = {};
|
m_config = {};
|
||||||
m_configFileName.clear();
|
m_configFileName.clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
QJsonObject ImportController::extractAmneziaConfig(QString &data)
|
|
||||||
{
|
|
||||||
data.replace("vpn://", "");
|
|
||||||
QByteArray ba = QByteArray::fromBase64(data.toUtf8(), QByteArray::Base64UrlEncoding | QByteArray::OmitTrailingEquals);
|
|
||||||
|
|
||||||
QByteArray ba_uncompressed = qUncompress(ba);
|
|
||||||
if (!ba_uncompressed.isEmpty()) {
|
|
||||||
ba = ba_uncompressed;
|
|
||||||
}
|
|
||||||
|
|
||||||
QJsonObject config = QJsonDocument::fromJson(ba).object();
|
|
||||||
|
|
||||||
return config;
|
|
||||||
}
|
|
||||||
|
|
||||||
QJsonObject ImportController::extractOpenVpnConfig(const QString &data)
|
QJsonObject ImportController::extractOpenVpnConfig(const QString &data)
|
||||||
{
|
{
|
||||||
QJsonObject openVpnConfig;
|
QJsonObject openVpnConfig;
|
||||||
|
@ -229,8 +255,8 @@ QJsonObject ImportController::extractWireGuardConfig(const QString &data)
|
||||||
if (hostNameAndPortMatch.hasCaptured(1)) {
|
if (hostNameAndPortMatch.hasCaptured(1)) {
|
||||||
hostName = hostNameAndPortMatch.captured(1);
|
hostName = hostNameAndPortMatch.captured(1);
|
||||||
} else {
|
} else {
|
||||||
qDebug() << "Failed to import profile";
|
qDebug() << "Key parameter 'Endpoint' is missing";
|
||||||
emit importErrorOccurred(errorString(ErrorCode::ImportInvalidConfigError));
|
emit importErrorOccurred(errorString(ErrorCode::ImportInvalidConfigError), false);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (hostNameAndPortMatch.hasCaptured(2)) {
|
if (hostNameAndPortMatch.hasCaptured(2)) {
|
||||||
|
@ -242,10 +268,11 @@ QJsonObject ImportController::extractWireGuardConfig(const QString &data)
|
||||||
lastConfig[config_key::hostName] = hostName;
|
lastConfig[config_key::hostName] = hostName;
|
||||||
lastConfig[config_key::port] = port.toInt();
|
lastConfig[config_key::port] = port.toInt();
|
||||||
|
|
||||||
// if (!configMap.value("PrivateKey").isEmpty() && !configMap.value("Address").isEmpty()
|
if (!configMap.value("PrivateKey").isEmpty() && !configMap.value("Address").isEmpty()
|
||||||
// && !configMap.value("PresharedKey").isEmpty() && !configMap.value("PublicKey").isEmpty()) {
|
&& !configMap.value("PublicKey").isEmpty()) {
|
||||||
lastConfig[config_key::client_priv_key] = configMap.value("PrivateKey");
|
lastConfig[config_key::client_priv_key] = configMap.value("PrivateKey");
|
||||||
lastConfig[config_key::client_ip] = configMap.value("Address");
|
lastConfig[config_key::client_ip] = configMap.value("Address");
|
||||||
|
|
||||||
if (!configMap.value("PresharedKey").isEmpty()) {
|
if (!configMap.value("PresharedKey").isEmpty()) {
|
||||||
lastConfig[config_key::psk_key] = configMap.value("PresharedKey");
|
lastConfig[config_key::psk_key] = configMap.value("PresharedKey");
|
||||||
} else if (!configMap.value("PreSharedKey").isEmpty()) {
|
} else if (!configMap.value("PreSharedKey").isEmpty()) {
|
||||||
|
@ -253,11 +280,11 @@ QJsonObject ImportController::extractWireGuardConfig(const QString &data)
|
||||||
}
|
}
|
||||||
|
|
||||||
lastConfig[config_key::server_pub_key] = configMap.value("PublicKey");
|
lastConfig[config_key::server_pub_key] = configMap.value("PublicKey");
|
||||||
// } else {
|
} else {
|
||||||
// qDebug() << "Failed to import profile";
|
qDebug() << "One of the key parameters is missing (PrivateKey, Address, PublicKey)";
|
||||||
// emit importErrorOccurred(errorString(ErrorCode::ImportInvalidConfigError));
|
emit importErrorOccurred(errorString(ErrorCode::ImportInvalidConfigError));
|
||||||
// return QJsonObject();
|
return QJsonObject();
|
||||||
// }
|
}
|
||||||
|
|
||||||
QJsonArray allowedIpsJsonArray = QJsonArray::fromStringList(configMap.value("AllowedIPs").split(","));
|
QJsonArray allowedIpsJsonArray = QJsonArray::fromStringList(configMap.value("AllowedIPs").split(","));
|
||||||
|
|
||||||
|
|
|
@ -18,9 +18,8 @@ public:
|
||||||
|
|
||||||
public slots:
|
public slots:
|
||||||
void importConfig();
|
void importConfig();
|
||||||
void extractConfigFromFile(const QString &fileName);
|
bool extractConfigFromFile(const QString &fileName);
|
||||||
void extractConfigFromData(QString data);
|
bool extractConfigFromData(QString data);
|
||||||
void extractConfigFromCode(QString code);
|
|
||||||
bool extractConfigFromQr(const QByteArray &data);
|
bool extractConfigFromQr(const QByteArray &data);
|
||||||
QString getConfig();
|
QString getConfig();
|
||||||
QString getConfigFileName();
|
QString getConfigFileName();
|
||||||
|
@ -39,12 +38,14 @@ public slots:
|
||||||
|
|
||||||
signals:
|
signals:
|
||||||
void importFinished();
|
void importFinished();
|
||||||
void importErrorOccurred(const QString &errorMessage, bool goToPageHome = false);
|
void importErrorOccurred(const QString &errorMessage, bool goToPageHome);
|
||||||
|
void importErrorOccurred(const QString &errorMessage);
|
||||||
|
|
||||||
void qrDecodingFinished();
|
void qrDecodingFinished();
|
||||||
|
|
||||||
|
void restoreAppConfig(const QByteArray &data);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
QJsonObject extractAmneziaConfig(QString &data);
|
|
||||||
QJsonObject extractOpenVpnConfig(const QString &data);
|
QJsonObject extractOpenVpnConfig(const QString &data);
|
||||||
QJsonObject extractWireGuardConfig(const QString &data);
|
QJsonObject extractWireGuardConfig(const QString &data);
|
||||||
|
|
||||||
|
|
|
@ -113,6 +113,11 @@ void SettingsController::restoreAppConfig(const QString &fileName)
|
||||||
|
|
||||||
QByteArray data = file.readAll();
|
QByteArray data = file.readAll();
|
||||||
|
|
||||||
|
restoreAppConfigFromData(data);
|
||||||
|
}
|
||||||
|
|
||||||
|
void SettingsController::restoreAppConfigFromData(const QByteArray &data)
|
||||||
|
{
|
||||||
bool ok = m_settings->restoreAppConfig(data);
|
bool ok = m_settings->restoreAppConfig(data);
|
||||||
if (ok) {
|
if (ok) {
|
||||||
m_serversModel->resetModel();
|
m_serversModel->resetModel();
|
||||||
|
|
|
@ -41,6 +41,7 @@ public slots:
|
||||||
|
|
||||||
void backupAppConfig(const QString &fileName);
|
void backupAppConfig(const QString &fileName);
|
||||||
void restoreAppConfig(const QString &fileName);
|
void restoreAppConfig(const QString &fileName);
|
||||||
|
void restoreAppConfigFromData(const QByteArray &data);
|
||||||
|
|
||||||
QString getAppVersion();
|
QString getAppVersion();
|
||||||
|
|
||||||
|
|
|
@ -73,12 +73,7 @@ PageType {
|
||||||
"Config files (*.vpn *.ovpn *.conf)"
|
"Config files (*.vpn *.ovpn *.conf)"
|
||||||
var fileName = SystemController.getFileName(qsTr("Open config file"), nameFilter)
|
var fileName = SystemController.getFileName(qsTr("Open config file"), nameFilter)
|
||||||
if (fileName !== "") {
|
if (fileName !== "") {
|
||||||
if (fileName.indexOf(".backup") !== -1 && !ServersModel.getServersCount()) {
|
if (ImportController.extractConfigFromFile(fileName)) {
|
||||||
PageController.showBusyIndicator(true)
|
|
||||||
SettingsController.restoreAppConfig(fileName)
|
|
||||||
PageController.showBusyIndicator(false)
|
|
||||||
} else {
|
|
||||||
ImportController.extractConfigFromFile(fileName)
|
|
||||||
PageController.goToPage(PageEnum.PageSetupWizardViewConfig)
|
PageController.goToPage(PageEnum.PageSetupWizardViewConfig)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -81,6 +81,20 @@ PageType {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Connections {
|
||||||
|
target: ImportController
|
||||||
|
|
||||||
|
function onRestoreAppConfig(data) {
|
||||||
|
PageController.showBusyIndicator(true)
|
||||||
|
SettingsController.restoreAppConfigFromData(data)
|
||||||
|
PageController.showBusyIndicator(false)
|
||||||
|
}
|
||||||
|
|
||||||
|
function onImportErrorOccurred(errorMessage) {
|
||||||
|
PageController.showErrorMessage(errorMessage)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
FlickableType {
|
FlickableType {
|
||||||
id: fl
|
id: fl
|
||||||
anchors.top: parent.top
|
anchors.top: parent.top
|
||||||
|
|
|
@ -77,7 +77,7 @@ PageType {
|
||||||
text: qsTr("Continue")
|
text: qsTr("Continue")
|
||||||
|
|
||||||
clickedFunc: function() {
|
clickedFunc: function() {
|
||||||
ImportController.extractConfigFromCode(textKey.textFieldText)
|
ImportController.extractConfigFromData(textKey.textFieldText)
|
||||||
PageController.goToPage(PageEnum.PageSetupWizardViewConfig)
|
PageController.goToPage(PageEnum.PageSetupWizardViewConfig)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -121,6 +121,14 @@ PageType {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Connections {
|
||||||
|
target: ImportController
|
||||||
|
|
||||||
|
function onImportErrorOccurred(errorMessage) {
|
||||||
|
PageController.showErrorMessage(errorMessage)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
StackViewType {
|
StackViewType {
|
||||||
id: tabBarStackView
|
id: tabBarStackView
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue