Поддержка протокола Sftp (File Sharing) по ТЗ по гранту от Теплицы

социальных технологий (2021 год)
+ небольшой рефакторинг
This commit is contained in:
pokamest 2021-09-22 14:49:08 +03:00
parent 6ee203a21d
commit 3bcc12869b
45 changed files with 645 additions and 338 deletions

View file

@ -12,6 +12,9 @@ QString amnezia::scriptFolder(amnezia::DockerContainer container)
case DockerContainer::ShadowSocks: return QLatin1String("openvpn_shadowsocks");
case DockerContainer::WireGuard: return QLatin1String("wireguard");
case DockerContainer::TorWebSite: return QLatin1String("website_tor");
case DockerContainer::Dns: return QLatin1String("dns");
case DockerContainer::FileShare: return QLatin1String("file_share");
case DockerContainer::Sftp: return QLatin1String("sftp");
default: return "";
}
}
@ -46,12 +49,12 @@ QString amnezia::scriptData(amnezia::SharedScriptType type)
QString fileName = QString(":/server_scripts/%1").arg(amnezia::scriptName(type));
QFile file(fileName);
if (! file.open(QIODevice::ReadOnly)) {
qDebug() << "Error opening script" << fileName;
qDebug() << "Warning: script missing" << fileName;
return "";
}
QByteArray ba = file.readAll();
if (ba.isEmpty()) {
qDebug() << "Error, script is empty" << fileName;
qDebug() << "Warning: script is empty" << fileName;
}
return ba;
}
@ -61,7 +64,7 @@ QString amnezia::scriptData(amnezia::ProtocolScriptType type, DockerContainer co
QString fileName = QString(":/server_scripts/%1/%2").arg(amnezia::scriptFolder(container), amnezia::scriptName(type));
QFile file(fileName);
if (! file.open(QIODevice::ReadOnly)) {
qDebug() << "Error opening script" << fileName;
qDebug() << "Warning: script missing" << fileName;
return "";
}
QByteArray data = file.readAll();

View file

@ -413,6 +413,29 @@ ErrorCode ServerController::updateContainer(const ServerCredentials &credentials
}
}
QJsonObject ServerController::createContainerInitialConfig(DockerContainer container, int port, TransportProto tp)
{
Protocol mainProto = ContainerProps::defaultProtocol(container);
QJsonObject config {
{ config_key::container, ContainerProps::containerToString(container) }
};
QJsonObject protoConfig;
protoConfig.insert(config_key::port, QString::number(port));
protoConfig.insert(config_key::transport_proto, ProtocolProps::transportProtoToString(tp, mainProto));
if (container == DockerContainer::Sftp) {
protoConfig.insert(config_key::userName, protocols::sftp::defaultUserName);
protoConfig.insert(config_key::password, Utils::getRandomString(10));
}
config.insert(ProtocolProps::protoToString(mainProto), protoConfig);
return config;
}
bool ServerController::isReinstallContainerRequred(DockerContainer container, const QJsonObject &oldConfig, const QJsonObject &newConfig)
{
const QJsonObject &oldProtoConfig = oldConfig[ContainerProps::containerToString(container)].toObject();
@ -512,6 +535,7 @@ ErrorCode ServerController::runContainerWorker(const ServerCredentials &credenti
if (stdOut.contains("address already in use")) return ErrorCode::ServerPortAlreadyAllocatedError;
if (stdOut.contains("is already in use by container")) return ErrorCode::ServerPortAlreadyAllocatedError;
if (stdOut.contains("invalid publish")) return ErrorCode::ServerDockerFailedError;
return e;
}
@ -525,10 +549,15 @@ ErrorCode ServerController::configureContainerWorker(const ServerCredentials &cr
ErrorCode ServerController::startupContainerWorker(const ServerCredentials &credentials, DockerContainer container, const QJsonObject &config)
{
QString script = amnezia::scriptData(ProtocolScriptType::container_startup, container);
if (script.isEmpty()) {
return ErrorCode::NoError;
}
ErrorCode e = uploadTextFileToContainer(container, credentials,
replaceVars(amnezia::scriptData(ProtocolScriptType::container_startup, container),
genVarsForScript(credentials, container, config)),
"/opt/amnezia/start.sh");
replaceVars(script, genVarsForScript(credentials, container, config)),
"/opt/amnezia/start.sh");
if (e) return e;
return runScript(sshParams(credentials),
@ -542,6 +571,7 @@ ServerController::Vars ServerController::genVarsForScript(const ServerCredential
const QJsonObject &cloakConfig = config.value(ProtocolProps::protoToString(Protocol::Cloak)).toObject();
const QJsonObject &ssConfig = config.value(ProtocolProps::protoToString(Protocol::ShadowSocks)).toObject();
const QJsonObject &wireguarConfig = config.value(ProtocolProps::protoToString(Protocol::WireGuard)).toObject();
const QJsonObject &sftpConfig = config.value(ProtocolProps::protoToString(Protocol::Sftp)).toObject();
//
Vars vars;
@ -588,6 +618,9 @@ ServerController::Vars ServerController::genVarsForScript(const ServerCredential
vars.append({{"$WIREGUARD_SERVER_PORT", wireguarConfig.value(config_key::port).toString(protocols::wireguard::defaultPort) }});
// Sftp vars
vars.append({{"$SFTP_PORT", sftpConfig.value(config_key::port).toString(QString::number(ProtocolProps::defaultPort(Protocol::Sftp))) }});
QString serverIp = Utils::getIPAddress(credentials.hostName);
if (!serverIp.isEmpty()) {

View file

@ -32,6 +32,9 @@ public:
static ErrorCode updateContainer(const ServerCredentials &credentials, DockerContainer container,
const QJsonObject &oldConfig, const QJsonObject &newConfig = QJsonObject());
// create initial config - generate passwords, etc
static QJsonObject createContainerInitialConfig(DockerContainer container, int port, TransportProto tp);
static bool isReinstallContainerRequred(DockerContainer container, const QJsonObject &oldConfig, const QJsonObject &newConfig);
static ErrorCode checkOpenVpnServer(DockerContainer container, const ServerCredentials &credentials);