2026-04-30 14:53:03 +08:00
|
|
|
#include "ikev2Configurator.h"
|
2023-08-31 16:00:41 +05:00
|
|
|
|
|
|
|
|
#include <QDebug>
|
|
|
|
|
#include <QJsonDocument>
|
2021-10-04 19:07:49 +03:00
|
|
|
#include <QProcess>
|
|
|
|
|
#include <QString>
|
|
|
|
|
#include <QTemporaryDir>
|
|
|
|
|
#include <QTemporaryFile>
|
2021-11-15 18:17:28 +03:00
|
|
|
#include <QUuid>
|
2021-10-04 19:07:49 +03:00
|
|
|
|
2026-04-30 14:53:03 +08:00
|
|
|
#include "core/utils/containerEnum.h"
|
|
|
|
|
#include "core/utils/containers/containerUtils.h"
|
|
|
|
|
#include "core/utils/protocolEnum.h"
|
|
|
|
|
#include "core/utils/selfhosted/sshSession.h"
|
|
|
|
|
#include "core/utils/selfhosted/scriptsRegistry.h"
|
|
|
|
|
#include "core/utils/utilities.h"
|
|
|
|
|
#include "core/models/protocols/ikev2ProtocolConfig.h"
|
2022-10-15 19:46:26 +03:00
|
|
|
|
2026-04-30 14:53:03 +08:00
|
|
|
Ikev2Configurator::Ikev2Configurator(SshSession* sshSession, QObject *parent)
|
|
|
|
|
: ConfiguratorBase(sshSession, parent)
|
2022-08-25 17:35:28 +03:00
|
|
|
{
|
|
|
|
|
}
|
2021-10-04 19:07:49 +03:00
|
|
|
|
2024-04-12 20:00:21 +05:00
|
|
|
Ikev2Configurator::ConnectionData Ikev2Configurator::prepareIkev2Config(const ServerCredentials &credentials, DockerContainer container,
|
2024-05-09 20:56:52 +03:00
|
|
|
ErrorCode &errorCode)
|
2021-10-04 19:07:49 +03:00
|
|
|
{
|
|
|
|
|
Ikev2Configurator::ConnectionData connData;
|
|
|
|
|
connData.host = credentials.hostName;
|
|
|
|
|
connData.clientId = Utils::getRandomString(16);
|
2021-11-15 18:17:28 +03:00
|
|
|
connData.password = "";
|
2021-10-04 19:07:49 +03:00
|
|
|
|
|
|
|
|
QString certFileName = "/opt/amnezia/ikev2/clients/" + connData.clientId + ".p12";
|
|
|
|
|
|
2023-08-31 16:00:41 +05:00
|
|
|
QString scriptCreateCert = QString("certutil -z <(head -c 1024 /dev/urandom) "
|
|
|
|
|
"-S -c \"IKEv2 VPN CA\" -n \"%1\" "
|
|
|
|
|
"-s \"O=IKEv2 VPN,CN=%1\" "
|
|
|
|
|
"-k rsa -g 3072 -v 120 "
|
|
|
|
|
"-d sql:/etc/ipsec.d -t \",,\" "
|
|
|
|
|
"--keyUsage digitalSignature,keyEncipherment "
|
|
|
|
|
"--extKeyUsage serverAuth,clientAuth -8 \"%1\"")
|
|
|
|
|
.arg(connData.clientId);
|
2021-10-04 19:07:49 +03:00
|
|
|
|
2026-04-30 14:53:03 +08:00
|
|
|
errorCode = m_sshSession->runContainerScript(credentials, container, scriptCreateCert);
|
2021-10-04 19:07:49 +03:00
|
|
|
|
2024-04-12 20:00:21 +05:00
|
|
|
QString scriptExportCert =
|
|
|
|
|
QString("pk12util -W \"%1\" -d sql:/etc/ipsec.d -n \"%2\" -o \"%3\"").arg(connData.password).arg(connData.clientId).arg(certFileName);
|
2026-04-30 14:53:03 +08:00
|
|
|
errorCode = m_sshSession->runContainerScript(credentials, container, scriptExportCert);
|
2021-10-04 19:07:49 +03:00
|
|
|
|
2026-04-30 14:53:03 +08:00
|
|
|
connData.clientCert = m_sshSession->getTextFileFromContainer(container, credentials, certFileName, errorCode);
|
|
|
|
|
connData.caCert = m_sshSession->getTextFileFromContainer(container, credentials, "/etc/ipsec.d/ca_cert_base64.p12", errorCode);
|
2021-11-15 18:17:28 +03:00
|
|
|
|
|
|
|
|
qDebug() << "Ikev2Configurator::ConnectionData client cert size:" << connData.clientCert.size();
|
|
|
|
|
qDebug() << "Ikev2Configurator::ConnectionData ca cert size:" << connData.caCert.size();
|
2021-10-04 19:07:49 +03:00
|
|
|
|
|
|
|
|
return connData;
|
|
|
|
|
}
|
|
|
|
|
|
2026-04-30 14:53:03 +08:00
|
|
|
ProtocolConfig Ikev2Configurator::createConfig(const ServerCredentials &credentials, DockerContainer container, const ContainerConfig &containerConfig,
|
|
|
|
|
const DnsSettings &dnsSettings,
|
|
|
|
|
ErrorCode &errorCode)
|
2021-10-04 19:07:49 +03:00
|
|
|
{
|
2026-04-30 14:53:03 +08:00
|
|
|
const Ikev2ServerConfig* serverConfig = nullptr;
|
|
|
|
|
if (auto* ikev2Config = containerConfig.protocolConfig.as<Ikev2ProtocolConfig>()) {
|
|
|
|
|
serverConfig = &ikev2Config->serverConfig;
|
|
|
|
|
}
|
2021-11-15 18:17:28 +03:00
|
|
|
|
2021-10-04 19:07:49 +03:00
|
|
|
ConnectionData connData = prepareIkev2Config(credentials, container, errorCode);
|
2024-04-01 20:20:02 +07:00
|
|
|
if (errorCode != ErrorCode::NoError) {
|
2026-04-30 14:53:03 +08:00
|
|
|
return Ikev2ProtocolConfig{};
|
2021-10-04 19:07:49 +03:00
|
|
|
}
|
|
|
|
|
|
2026-04-30 14:53:03 +08:00
|
|
|
QString configJson = genIkev2Config(connData);
|
|
|
|
|
QJsonDocument doc = QJsonDocument::fromJson(configJson.toUtf8());
|
|
|
|
|
QJsonObject configObj = doc.object();
|
|
|
|
|
|
|
|
|
|
Ikev2ProtocolConfig protocolConfig;
|
|
|
|
|
if (serverConfig) {
|
|
|
|
|
protocolConfig.serverConfig = *serverConfig;
|
|
|
|
|
} else {
|
|
|
|
|
protocolConfig.serverConfig.hostName = connData.host;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
Ikev2ClientConfig clientConfig;
|
|
|
|
|
clientConfig.nativeConfig = configJson;
|
|
|
|
|
clientConfig.hostName = connData.host;
|
|
|
|
|
clientConfig.userName = connData.clientId;
|
|
|
|
|
clientConfig.cert = QString(connData.clientCert.toBase64());
|
|
|
|
|
clientConfig.password = connData.password;
|
|
|
|
|
clientConfig.clientId = connData.clientId;
|
|
|
|
|
|
|
|
|
|
protocolConfig.setClientConfig(clientConfig);
|
|
|
|
|
|
|
|
|
|
return protocolConfig;
|
2021-11-15 18:17:28 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
QString Ikev2Configurator::genIkev2Config(const ConnectionData &connData)
|
|
|
|
|
{
|
2021-10-04 19:07:49 +03:00
|
|
|
QJsonObject config;
|
2026-04-30 14:53:03 +08:00
|
|
|
config[configKey::hostName] = connData.host;
|
|
|
|
|
config[configKey::userName] = connData.clientId;
|
|
|
|
|
config[configKey::cert] = QString(connData.clientCert.toBase64());
|
|
|
|
|
config[configKey::password] = connData.password;
|
2021-10-04 19:07:49 +03:00
|
|
|
|
|
|
|
|
return QJsonDocument(config).toJson();
|
|
|
|
|
}
|
|
|
|
|
|
2021-11-15 18:17:28 +03:00
|
|
|
QString Ikev2Configurator::genMobileConfig(const ConnectionData &connData)
|
|
|
|
|
{
|
|
|
|
|
QFile file(":/server_scripts/ipsec/mobileconfig.plist");
|
|
|
|
|
file.open(QIODevice::ReadOnly);
|
|
|
|
|
QString config = QString(file.readAll());
|
|
|
|
|
|
|
|
|
|
config.replace("$CLIENT_NAME", connData.clientId);
|
|
|
|
|
config.replace("$UUID1", QUuid::createUuid().toString());
|
|
|
|
|
config.replace("$SERVER_ADDR", connData.host);
|
|
|
|
|
|
|
|
|
|
QString subStr("$(UUID_GEN)");
|
|
|
|
|
while (config.indexOf(subStr) > 0) {
|
|
|
|
|
config.replace(config.indexOf(subStr), subStr.size(), QUuid::createUuid().toString());
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
config.replace("$P12_BASE64", connData.clientCert.toBase64());
|
|
|
|
|
config.replace("$CA_BASE64", connData.caCert.toBase64());
|
|
|
|
|
|
|
|
|
|
return config;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
QString Ikev2Configurator::genStrongSwanConfig(const ConnectionData &connData)
|
|
|
|
|
{
|
|
|
|
|
QFile file(":/server_scripts/ipsec/strongswan.profile");
|
|
|
|
|
file.open(QIODevice::ReadOnly);
|
|
|
|
|
QString config = QString(file.readAll());
|
|
|
|
|
|
|
|
|
|
config.replace("$CLIENT_NAME", connData.clientId);
|
|
|
|
|
config.replace("$UUID", QUuid::createUuid().toString());
|
|
|
|
|
config.replace("$SERVER_ADDR", connData.host);
|
|
|
|
|
|
|
|
|
|
QByteArray cert = connData.clientCert.toBase64();
|
|
|
|
|
cert.replace("\r", "").replace("\n", "");
|
|
|
|
|
config.replace("$P12_BASE64", cert);
|
|
|
|
|
|
|
|
|
|
return config;
|
|
|
|
|
}
|