From 3bcc12869bbf558e5eaabc7b68eebe9c134eb70f Mon Sep 17 00:00:00 2001 From: pokamest Date: Wed, 22 Sep 2021 14:49:08 +0300 Subject: [PATCH] =?UTF-8?q?=D0=9F=D0=BE=D0=B4=D0=B4=D0=B5=D1=80=D0=B6?= =?UTF-8?q?=D0=BA=D0=B0=20=D0=BF=D1=80=D0=BE=D1=82=D0=BE=D0=BA=D0=BE=D0=BB?= =?UTF-8?q?=D0=B0=20Sftp=20(File=20Sharing)=20=D0=BF=D0=BE=20=D0=A2=D0=97?= =?UTF-8?q?=20=D0=BF=D0=BE=20=D0=B3=D1=80=D0=B0=D0=BD=D1=82=D1=83=20=D0=BE?= =?UTF-8?q?=D1=82=20=D0=A2=D0=B5=D0=BF=D0=BB=D0=B8=D1=86=D1=8B=20=D1=81?= =?UTF-8?q?=D0=BE=D1=86=D0=B8=D0=B0=D0=BB=D1=8C=D0=BD=D1=8B=D1=85=20=D1=82?= =?UTF-8?q?=D0=B5=D1=85=D0=BD=D0=BE=D0=BB=D0=BE=D0=B3=D0=B8=D0=B9=20(2021?= =?UTF-8?q?=20=D0=B3=D0=BE=D0=B4)=20+=20=D0=BD=D0=B5=D0=B1=D0=BE=D0=BB?= =?UTF-8?q?=D1=8C=D1=88=D0=BE=D0=B9=20=D1=80=D0=B5=D1=84=D0=B0=D0=BA=D1=82?= =?UTF-8?q?=D0=BE=D1=80=D0=B8=D0=BD=D0=B3?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- client/client.pro | 2 + client/containers/containers_defs.cpp | 10 +- client/containers/containers_defs.h | 4 +- client/core/scripts_registry.cpp | 9 +- client/core/servercontroller.cpp | 39 +- client/core/servercontroller.h | 3 + client/protocols/protocols_defs.cpp | 16 +- client/protocols/protocols_defs.h | 17 +- client/resources.qrc | 7 + client/server_scripts/dns/Dockerfile | 3 + .../server_scripts/dns/configure_container.sh | 0 client/server_scripts/dns/run_container.sh | 2 + client/server_scripts/sftp/Dockerfile | 3 + .../sftp/configure_container.sh | 0 client/server_scripts/sftp/run_container.sh | 1 + .../website_tor/configure_container.sh | 13 - client/ui/pages_logic/AppSettingsLogic.cpp | 2 +- client/ui/pages_logic/AppSettingsLogic.h | 2 +- .../ui/pages_logic/GeneralSettingsLogic.cpp | 2 +- client/ui/pages_logic/GeneralSettingsLogic.h | 2 +- .../ui/pages_logic/NetworkSettingsLogic.cpp | 6 +- client/ui/pages_logic/NetworkSettingsLogic.h | 2 +- .../pages_logic/NewServerProtocolsLogic.cpp | 2 +- .../ui/pages_logic/NewServerProtocolsLogic.h | 2 +- client/ui/pages_logic/PageLogicBase.h | 4 +- .../ui/pages_logic/ServerContainersLogic.cpp | 29 +- client/ui/pages_logic/ServerContainersLogic.h | 2 +- client/ui/pages_logic/ServerListLogic.cpp | 4 +- client/ui/pages_logic/ServerListLogic.h | 2 +- client/ui/pages_logic/ServerSettingsLogic.cpp | 6 +- client/ui/pages_logic/ServerSettingsLogic.h | 2 +- client/ui/pages_logic/StartPageLogic.cpp | 2 +- client/ui/pages_logic/StartPageLogic.h | 2 +- client/ui/pages_logic/WizardLogic.cpp | 2 +- client/ui/pages_logic/WizardLogic.h | 2 +- .../protocols/OtherProtocolsLogic.cpp | 30 ++ .../protocols/OtherProtocolsLogic.h | 31 ++ client/ui/qml/Controls/TextFieldType.qml | 34 ++ client/ui/qml/Pages/PageServerContainers.qml | 20 +- client/ui/qml/Pages/PageServerSettings.qml | 2 +- .../qml/Pages/Protocols/PageProtoOpenVPN.qml | 374 ++++++++++-------- .../ui/qml/Pages/Protocols/PageProtoSftp.qml | 79 ++++ client/ui/qml/main.qml | 77 ++-- client/ui/uilogic.cpp | 124 +++--- client/ui/uilogic.h | 6 +- 45 files changed, 645 insertions(+), 338 deletions(-) create mode 100644 client/server_scripts/dns/Dockerfile create mode 100644 client/server_scripts/dns/configure_container.sh create mode 100644 client/server_scripts/dns/run_container.sh create mode 100644 client/server_scripts/sftp/Dockerfile create mode 100644 client/server_scripts/sftp/configure_container.sh create mode 100644 client/server_scripts/sftp/run_container.sh create mode 100644 client/ui/pages_logic/protocols/OtherProtocolsLogic.cpp create mode 100644 client/ui/pages_logic/protocols/OtherProtocolsLogic.h create mode 100644 client/ui/qml/Pages/Protocols/PageProtoSftp.qml diff --git a/client/client.pro b/client/client.pro index 853395c2..c5d615f3 100644 --- a/client/client.pro +++ b/client/client.pro @@ -56,6 +56,7 @@ HEADERS += \ ui/pages_logic/WizardLogic.h \ ui/pages_logic/protocols/CloakLogic.h \ ui/pages_logic/protocols/OpenVpnLogic.h \ + ui/pages_logic/protocols/OtherProtocolsLogic.h \ ui/pages_logic/protocols/PageProtocolLogicBase.h \ ui/pages_logic/protocols/ShadowSocksLogic.h \ ui/property_helper.h \ @@ -107,6 +108,7 @@ SOURCES += \ ui/pages_logic/WizardLogic.cpp \ ui/pages_logic/protocols/CloakLogic.cpp \ ui/pages_logic/protocols/OpenVpnLogic.cpp \ + ui/pages_logic/protocols/OtherProtocolsLogic.cpp \ ui/pages_logic/protocols/PageProtocolLogicBase.cpp \ ui/pages_logic/protocols/ShadowSocksLogic.cpp \ ui/models/servers_model.cpp \ diff --git a/client/containers/containers_defs.cpp b/client/containers/containers_defs.cpp index d14a1840..ade42a21 100644 --- a/client/containers/containers_defs.cpp +++ b/client/containers/containers_defs.cpp @@ -38,7 +38,7 @@ QVector ContainerProps::protocolsForContainer(amnezia::Docker return { Protocol::OpenVpn, Protocol::ShadowSocks, Protocol::Cloak }; default: - return {}; + return { defaultProtocol(container) }; } } @@ -62,7 +62,8 @@ QMap ContainerProps::containerHumanNames() {DockerContainer::WireGuard, "WireGuard"}, {DockerContainer::TorWebSite, QObject::tr("Web site in TOR network")}, {DockerContainer::Dns, QObject::tr("DNS Service")}, - {DockerContainer::FileShare, QObject::tr("File Sharing Service")} + {DockerContainer::FileShare, QObject::tr("SMB file sharing service")}, + {DockerContainer::Sftp, QObject::tr("Sftp file sharing service")} }; } @@ -76,7 +77,8 @@ QMap ContainerProps::containerDescriptions() {DockerContainer::WireGuard, QObject::tr("WireGuard container")}, {DockerContainer::TorWebSite, QObject::tr("Web site in TOR network")}, {DockerContainer::Dns, QObject::tr("DNS Service")}, - {DockerContainer::FileShare, QObject::tr("File Sharing Service")} + {DockerContainer::FileShare, QObject::tr("SMB file sharing service - is Window file sharing protocol")}, + {DockerContainer::Sftp, QObject::tr("Sftp file sharing service - is secure FTP service")} }; } @@ -88,7 +90,7 @@ amnezia::ServiceType ContainerProps::containerService(DockerContainer c) case DockerContainer::Cloak : return ServiceType::Vpn; case DockerContainer::ShadowSocks : return ServiceType::Vpn; case DockerContainer::WireGuard : return ServiceType::Vpn; - case DockerContainer::TorWebSite : return ServiceType::Other; + case DockerContainer::TorWebSite : return ServiceType::Other; case DockerContainer::Dns : return ServiceType::Other; case DockerContainer::FileShare : return ServiceType::Other; default: return ServiceType::Other; diff --git a/client/containers/containers_defs.h b/client/containers/containers_defs.h index 8f5b9ba4..02ac5528 100644 --- a/client/containers/containers_defs.h +++ b/client/containers/containers_defs.h @@ -22,7 +22,8 @@ enum DockerContainer { //non-vpn TorWebSite, Dns, - FileShare + FileShare, + Sftp }; Q_ENUM_NS(DockerContainer) } // namespace ContainerEnumNS @@ -43,6 +44,7 @@ public: Q_INVOKABLE static QMap containerHumanNames(); Q_INVOKABLE static QMap containerDescriptions(); + // these protocols will be displayed in container settings Q_INVOKABLE static QVector protocolsForContainer(DockerContainer container); Q_INVOKABLE static ServiceType containerService(DockerContainer c); diff --git a/client/core/scripts_registry.cpp b/client/core/scripts_registry.cpp index 52350ab4..080bc36c 100644 --- a/client/core/scripts_registry.cpp +++ b/client/core/scripts_registry.cpp @@ -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(); diff --git a/client/core/servercontroller.cpp b/client/core/servercontroller.cpp index c85836e2..4bc9d157 100644 --- a/client/core/servercontroller.cpp +++ b/client/core/servercontroller.cpp @@ -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()) { diff --git a/client/core/servercontroller.h b/client/core/servercontroller.h index 5fdbe60e..d0462773 100644 --- a/client/core/servercontroller.h +++ b/client/core/servercontroller.h @@ -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); diff --git a/client/protocols/protocols_defs.cpp b/client/protocols/protocols_defs.cpp index c21d1596..4536a5bd 100644 --- a/client/protocols/protocols_defs.cpp +++ b/client/protocols/protocols_defs.cpp @@ -70,7 +70,8 @@ QMap ProtocolProps::protocolHumanNames() {Protocol::WireGuard, "WireGuard"}, {Protocol::TorWebSite, "Web site in TOR network"}, {Protocol::Dns, "DNS Service"}, - {Protocol::FileShare, "File Sharing Service"} + {Protocol::FileShare, "File Sharing Service"}, + {Protocol::Sftp, QObject::tr("Sftp service")} }; } @@ -105,6 +106,7 @@ int ProtocolProps::defaultPort(Protocol p) case Protocol::TorWebSite : return 443; case Protocol::Dns : return 53; case Protocol::FileShare : return 139; + case Protocol::Sftp : return 222; default: return -1; } } @@ -132,9 +134,11 @@ TransportProto ProtocolProps::defaultTransportProto(Protocol p) case Protocol::Cloak : return TransportProto::Tcp; case Protocol::ShadowSocks : return TransportProto::Tcp; case Protocol::WireGuard : return TransportProto::Udp; - case Protocol::TorWebSite : return TransportProto::Tcp; + // non-vpn + case Protocol::TorWebSite : return TransportProto::Tcp; case Protocol::Dns : return TransportProto::Udp; - case Protocol::FileShare : return TransportProto::Tcp; + case Protocol::FileShare : return TransportProto::Udp; + case Protocol::Sftp : return TransportProto::Tcp; default: return TransportProto::Udp; } } @@ -147,9 +151,11 @@ bool ProtocolProps::defaultTransportProtoChangeable(Protocol p) case Protocol::Cloak : return false; case Protocol::ShadowSocks : return false; case Protocol::WireGuard : return false; - case Protocol::TorWebSite : return false; + // non-vpn + case Protocol::TorWebSite : return false; case Protocol::Dns : return false; case Protocol::FileShare : return false; - default: return -1; + case Protocol::Sftp : return false; + default: return false; } } diff --git a/client/protocols/protocols_defs.h b/client/protocols/protocols_defs.h index 553a28bb..669682e0 100644 --- a/client/protocols/protocols_defs.h +++ b/client/protocols/protocols_defs.h @@ -100,6 +100,10 @@ constexpr char serverPskKeyPath[] = "/opt/amnezia/wireguard/wireguard_psk.key"; } +namespace sftp { +constexpr char defaultUserName[] = "sftp_user"; + +} // namespace sftp } // namespace protocols @@ -118,9 +122,12 @@ enum Protocol { ShadowSocks, Cloak, WireGuard, + + // non-vpn TorWebSite, Dns, - FileShare + FileShare, + Sftp }; Q_ENUM_NS(Protocol) @@ -177,6 +184,14 @@ static void declareQmlProtocolEnum() { "TransportProto", "Error: only enums" ); + + qmlRegisterUncreatableMetaObject( + ProtocolEnumNS::staticMetaObject, + "ProtocolEnum", + 1, 0, + "ServiceType", + "Error: only enums" + ); } } // namespace amnezia diff --git a/client/resources.qrc b/client/resources.qrc index 9ccd60f7..366b1de6 100644 --- a/client/resources.qrc +++ b/client/resources.qrc @@ -114,5 +114,12 @@ images/delete.png ui/qml/Controls/FadeBehavior.qml ui/qml/Controls/VisibleBehavior.qml + server_scripts/dns/configure_container.sh + server_scripts/dns/Dockerfile + server_scripts/dns/run_container.sh + server_scripts/sftp/configure_container.sh + server_scripts/sftp/Dockerfile + server_scripts/sftp/run_container.sh + ui/qml/Pages/Protocols/PageProtoSftp.qml diff --git a/client/server_scripts/dns/Dockerfile b/client/server_scripts/dns/Dockerfile new file mode 100644 index 00000000..593e2eaf --- /dev/null +++ b/client/server_scripts/dns/Dockerfile @@ -0,0 +1,3 @@ +FROM mvance/unbound:latest + +LABEL maintainer="AmneziaVPN" diff --git a/client/server_scripts/dns/configure_container.sh b/client/server_scripts/dns/configure_container.sh new file mode 100644 index 00000000..e69de29b diff --git a/client/server_scripts/dns/run_container.sh b/client/server_scripts/dns/run_container.sh new file mode 100644 index 00000000..a04ef9a4 --- /dev/null +++ b/client/server_scripts/dns/run_container.sh @@ -0,0 +1,2 @@ +# Run container +sudo docker run -d --restart always --cap-add=NET_ADMIN -p 53:53/udp -p 53:53/tcp --name $CONTAINER_NAME $CONTAINER_NAME diff --git a/client/server_scripts/sftp/Dockerfile b/client/server_scripts/sftp/Dockerfile new file mode 100644 index 00000000..c8c79af5 --- /dev/null +++ b/client/server_scripts/sftp/Dockerfile @@ -0,0 +1,3 @@ +FROM atmoz/sftp + +LABEL maintainer="AmneziaVPN" diff --git a/client/server_scripts/sftp/configure_container.sh b/client/server_scripts/sftp/configure_container.sh new file mode 100644 index 00000000..e69de29b diff --git a/client/server_scripts/sftp/run_container.sh b/client/server_scripts/sftp/run_container.sh new file mode 100644 index 00000000..7184d0be --- /dev/null +++ b/client/server_scripts/sftp/run_container.sh @@ -0,0 +1 @@ +sudo docker run -d --restart always -p $SFTP_PORT:22/tcp --name $CONTAINER_NAME $CONTAINER_NAME $SFTP_USER:$SFTP_PASSWORD:::upload diff --git a/client/server_scripts/website_tor/configure_container.sh b/client/server_scripts/website_tor/configure_container.sh index ecb72e6c..e69de29b 100644 --- a/client/server_scripts/website_tor/configure_container.sh +++ b/client/server_scripts/website_tor/configure_container.sh @@ -1,13 +0,0 @@ -# Wireguard config -sudo docker exec -i $CONTAINER_NAME bash -c '\ -mkdir -p /opt/amnezia/wireguard; \ -cd /opt/amnezia/wireguard || exit 1; \ -WIREGUARD_SERVER_PRIVATE_KEY=$(wg genkey) && echo $WIREGUARD_SERVER_PRIVATE_KEY > /opt/amnezia/wireguard/wireguard_server_private_key.key; \ -WIREGUARD_SERVER_PUBLIC_KEY=$(echo $WIREGUARD_SERVER_PRIVATE_KEY | wg pubkey) && echo $WIREGUARD_SERVER_PUBLIC_KEY > /opt/amnezia/wireguard/wireguard_server_public_key.key; \ -WIREGUARD_PSK=$(wg genpsk) && echo $WIREGUARD_PSK > /opt/amnezia/wireguard/wireguard_psk.key; \ -echo -e "\ -[Interface]\\n\ -PrivateKey = $WIREGUARD_SERVER_PRIVATE_KEY \\n\ -Address = $WIREGUARD_SUBNET_IP/$WIREGUARD_SUBNET_CIDR \\n\ -ListenPort = $WIREGUARD_SERVER_PORT \\n\ -" >/opt/amnezia/wireguard/wg0.conf' diff --git a/client/ui/pages_logic/AppSettingsLogic.cpp b/client/ui/pages_logic/AppSettingsLogic.cpp index 5fca7a0b..2b89dd2c 100644 --- a/client/ui/pages_logic/AppSettingsLogic.cpp +++ b/client/ui/pages_logic/AppSettingsLogic.cpp @@ -16,7 +16,7 @@ AppSettingsLogic::AppSettingsLogic(UiLogic *logic, QObject *parent): } -void AppSettingsLogic::updatePage() +void AppSettingsLogic::onUpdatePage() { set_checkBoxAutostartChecked(Autostart::isAutostart()); set_checkBoxAutoConnectChecked(m_settings.isAutoConnect()); diff --git a/client/ui/pages_logic/AppSettingsLogic.h b/client/ui/pages_logic/AppSettingsLogic.h index 659b7e10..e71f6e98 100644 --- a/client/ui/pages_logic/AppSettingsLogic.h +++ b/client/ui/pages_logic/AppSettingsLogic.h @@ -14,7 +14,7 @@ class AppSettingsLogic : public PageLogicBase AUTO_PROPERTY(QString, labelVersionText) public: - Q_INVOKABLE void updatePage() override; + Q_INVOKABLE void onUpdatePage() override; Q_INVOKABLE void onCheckBoxAutostartToggled(bool checked); Q_INVOKABLE void onCheckBoxAutoconnectToggled(bool checked); diff --git a/client/ui/pages_logic/GeneralSettingsLogic.cpp b/client/ui/pages_logic/GeneralSettingsLogic.cpp index 6bd97310..33d28185 100644 --- a/client/ui/pages_logic/GeneralSettingsLogic.cpp +++ b/client/ui/pages_logic/GeneralSettingsLogic.cpp @@ -9,7 +9,7 @@ GeneralSettingsLogic::GeneralSettingsLogic(UiLogic *logic, QObject *parent): } -void GeneralSettingsLogic::updatePage() +void GeneralSettingsLogic::onUpdatePage() { set_pushButtonGeneralSettingsShareConnectionEnable(m_settings.haveAuthData(m_settings.defaultServerIndex())); } diff --git a/client/ui/pages_logic/GeneralSettingsLogic.h b/client/ui/pages_logic/GeneralSettingsLogic.h index 5f260756..85671590 100644 --- a/client/ui/pages_logic/GeneralSettingsLogic.h +++ b/client/ui/pages_logic/GeneralSettingsLogic.h @@ -12,7 +12,7 @@ class GeneralSettingsLogic : public PageLogicBase AUTO_PROPERTY(bool, pushButtonGeneralSettingsShareConnectionEnable) public: - Q_INVOKABLE void updatePage() override; + Q_INVOKABLE void onUpdatePage() override; Q_INVOKABLE void onPushButtonGeneralSettingsServerSettingsClicked(); Q_INVOKABLE void onPushButtonGeneralSettingsShareConnectionClicked(); diff --git a/client/ui/pages_logic/NetworkSettingsLogic.cpp b/client/ui/pages_logic/NetworkSettingsLogic.cpp index fe643577..a8171a9c 100644 --- a/client/ui/pages_logic/NetworkSettingsLogic.cpp +++ b/client/ui/pages_logic/NetworkSettingsLogic.cpp @@ -10,7 +10,7 @@ NetworkSettingsLogic::NetworkSettingsLogic(UiLogic *logic, QObject *parent): } -void NetworkSettingsLogic::updatePage() +void NetworkSettingsLogic::onUpdatePage() { set_lineEditDns1Text(m_settings.primaryDns()); set_lineEditDns2Text(m_settings.secondaryDns()); @@ -35,13 +35,13 @@ void NetworkSettingsLogic::onLineEditDns2EditFinished(const QString &text) void NetworkSettingsLogic::onPushButtonResetDns1Clicked() { m_settings.setPrimaryDns(m_settings.cloudFlareNs1); - updatePage(); + onUpdatePage(); } void NetworkSettingsLogic::onPushButtonResetDns2Clicked() { m_settings.setSecondaryDns(m_settings.cloudFlareNs2); - updatePage(); + onUpdatePage(); } QString NetworkSettingsLogic::getIpAddressValidatorRegex() const diff --git a/client/ui/pages_logic/NetworkSettingsLogic.h b/client/ui/pages_logic/NetworkSettingsLogic.h index 04eb91ec..089d3868 100644 --- a/client/ui/pages_logic/NetworkSettingsLogic.h +++ b/client/ui/pages_logic/NetworkSettingsLogic.h @@ -14,7 +14,7 @@ class NetworkSettingsLogic : public PageLogicBase READONLY_PROPERTY(QString, ipAddressValidatorRegex) public: - Q_INVOKABLE void updatePage() override; + Q_INVOKABLE void onUpdatePage() override; Q_INVOKABLE void onLineEditDns1EditFinished(const QString& text); Q_INVOKABLE void onLineEditDns2EditFinished(const QString& text); diff --git a/client/ui/pages_logic/NewServerProtocolsLogic.cpp b/client/ui/pages_logic/NewServerProtocolsLogic.cpp index bec89926..0deac81b 100644 --- a/client/ui/pages_logic/NewServerProtocolsLogic.cpp +++ b/client/ui/pages_logic/NewServerProtocolsLogic.cpp @@ -9,7 +9,7 @@ NewServerProtocolsLogic::NewServerProtocolsLogic(UiLogic *logic, QObject *parent } -void NewServerProtocolsLogic::updatePage() +void NewServerProtocolsLogic::onUpdatePage() { set_progressBarConnectionMinimum(0); set_progressBarConnectionMaximum(300); diff --git a/client/ui/pages_logic/NewServerProtocolsLogic.h b/client/ui/pages_logic/NewServerProtocolsLogic.h index c8ac9490..a06e6590 100644 --- a/client/ui/pages_logic/NewServerProtocolsLogic.h +++ b/client/ui/pages_logic/NewServerProtocolsLogic.h @@ -13,7 +13,7 @@ class NewServerProtocolsLogic : public PageLogicBase AUTO_PROPERTY(double, progressBarConnectionMaximum) public: - Q_INVOKABLE void updatePage() override; + Q_INVOKABLE void onUpdatePage() override; Q_INVOKABLE void onPushButtonConfigureClicked(DockerContainer c, int port, TransportProto tp); public: diff --git a/client/ui/pages_logic/PageLogicBase.h b/client/ui/pages_logic/PageLogicBase.h index ddde53c6..26858ee0 100644 --- a/client/ui/pages_logic/PageLogicBase.h +++ b/client/ui/pages_logic/PageLogicBase.h @@ -19,7 +19,7 @@ public: explicit PageLogicBase(UiLogic *uiLogic, QObject *parent = nullptr); ~PageLogicBase() = default; - Q_INVOKABLE virtual void updatePage() {} + Q_INVOKABLE virtual void onUpdatePage() {} protected: UiLogic *uiLogic() const { return m_uiLogic; } @@ -27,5 +27,7 @@ protected: Settings m_settings; UiLogic *m_uiLogic; +signals: + void updatePage(); }; #endif // PAGE_LOGIC_BASE_H diff --git a/client/ui/pages_logic/ServerContainersLogic.cpp b/client/ui/pages_logic/ServerContainersLogic.cpp index 5dc4d0ab..fbf36653 100644 --- a/client/ui/pages_logic/ServerContainersLogic.cpp +++ b/client/ui/pages_logic/ServerContainersLogic.cpp @@ -18,13 +18,15 @@ ServerContainersLogic::ServerContainersLogic(UiLogic *logic, QObject *parent): { } -void ServerContainersLogic::updateServerContainersPage() +void ServerContainersLogic::onUpdatePage() { ContainersModel *c_model = qobject_cast(uiLogic()->containersModel()); c_model->setSelectedServerIndex(uiLogic()->selectedServerIndex); ProtocolsModel *p_model = qobject_cast(uiLogic()->protocolsModel()); p_model->setSelectedServerIndex(uiLogic()->selectedServerIndex); + + emit updatePage(); } void ServerContainersLogic::onPushButtonProtoSettingsClicked(DockerContainer c, Protocol p) @@ -41,7 +43,7 @@ void ServerContainersLogic::onPushButtonProtoSettingsClicked(DockerContainer c, void ServerContainersLogic::onPushButtonDefaultClicked(DockerContainer c) { m_settings.setDefaultContainer(uiLogic()->selectedServerIndex, c); - updateServerContainersPage(); + onUpdatePage(); } void ServerContainersLogic::onPushButtonShareClicked(DockerContainer c) @@ -62,23 +64,12 @@ void ServerContainersLogic::onPushButtonRemoveClicked(DockerContainer container) if (c.isEmpty()) m_settings.setDefaultContainer(uiLogic()->selectedServerIndex, DockerContainer::None); else m_settings.setDefaultContainer(uiLogic()->selectedServerIndex, c.keys().first()); } - updateServerContainersPage(); + onUpdatePage(); } void ServerContainersLogic::onPushButtonContinueClicked(DockerContainer c, int port, TransportProto tp) { - QMap containers; - Protocol mainProto = ContainerProps::defaultProtocol(c); - - QJsonObject config { - { config_key::container, ContainerProps::containerToString(c) }, - { ProtocolProps::protoToString(mainProto), QJsonObject { - { config_key::port, QString::number(port) }, - { config_key::transport_proto, ProtocolProps::transportProtoToString(tp, mainProto) }} - } - }; - - containers.insert(c, config); + QJsonObject config = ServerController::createContainerInitialConfig(c, port, tp); emit uiLogic()->goToPage(Page::ServerConfiguringProgress); qApp->processEvents(); @@ -88,10 +79,12 @@ void ServerContainersLogic::onPushButtonContinueClicked(DockerContainer c, int p }); if (!e) { - m_settings.setContainerConfig(uiLogic()->selectedServerIndex, c, QJsonObject()); - m_settings.setDefaultContainer(uiLogic()->selectedServerIndex, c); + m_settings.setContainerConfig(uiLogic()->selectedServerIndex, c, config); + if (ContainerProps::containerService(c) == ServiceType::Vpn) { + m_settings.setDefaultContainer(uiLogic()->selectedServerIndex, c); + } } - updateServerContainersPage(); + onUpdatePage(); emit uiLogic()->closePage(); } diff --git a/client/ui/pages_logic/ServerContainersLogic.h b/client/ui/pages_logic/ServerContainersLogic.h index ff60efb5..5f49d35b 100644 --- a/client/ui/pages_logic/ServerContainersLogic.h +++ b/client/ui/pages_logic/ServerContainersLogic.h @@ -10,7 +10,7 @@ class ServerContainersLogic : public PageLogicBase Q_OBJECT public: - Q_INVOKABLE void updateServerContainersPage(); + Q_INVOKABLE void onUpdatePage() override; Q_INVOKABLE void onPushButtonProtoSettingsClicked(DockerContainer c, Protocol p); Q_INVOKABLE void onPushButtonDefaultClicked(DockerContainer c); diff --git a/client/ui/pages_logic/ServerListLogic.cpp b/client/ui/pages_logic/ServerListLogic.cpp index 0bfe0c7f..4fac4271 100644 --- a/client/ui/pages_logic/ServerListLogic.cpp +++ b/client/ui/pages_logic/ServerListLogic.cpp @@ -14,7 +14,7 @@ ServerListLogic::ServerListLogic(UiLogic *logic, QObject *parent): void ServerListLogic::onServerListPushbuttonDefaultClicked(int index) { m_settings.setDefaultServer(index); - updatePage(); + onUpdatePage(); } void ServerListLogic::onServerListPushbuttonSettingsClicked(int index) @@ -23,7 +23,7 @@ void ServerListLogic::onServerListPushbuttonSettingsClicked(int index) uiLogic()->goToPage(Page::ServerSettings); } -void ServerListLogic::updatePage() +void ServerListLogic::onUpdatePage() { const QJsonArray &servers = m_settings.serversArray(); int defaultServer = m_settings.defaultServerIndex(); diff --git a/client/ui/pages_logic/ServerListLogic.h b/client/ui/pages_logic/ServerListLogic.h index 94eb5587..2671b97d 100644 --- a/client/ui/pages_logic/ServerListLogic.h +++ b/client/ui/pages_logic/ServerListLogic.h @@ -12,7 +12,7 @@ class ServerListLogic : public PageLogicBase READONLY_PROPERTY(QObject *, serverListModel) public: - Q_INVOKABLE void updatePage() override; + Q_INVOKABLE void onUpdatePage() override; Q_INVOKABLE void onServerListPushbuttonDefaultClicked(int index); Q_INVOKABLE void onServerListPushbuttonSettingsClicked(int index); diff --git a/client/ui/pages_logic/ServerSettingsLogic.cpp b/client/ui/pages_logic/ServerSettingsLogic.cpp index 4b82fd1e..bfb1a075 100644 --- a/client/ui/pages_logic/ServerSettingsLogic.cpp +++ b/client/ui/pages_logic/ServerSettingsLogic.cpp @@ -21,7 +21,7 @@ ServerSettingsLogic::ServerSettingsLogic(UiLogic *logic, QObject *parent): } -void ServerSettingsLogic::updatePage() +void ServerSettingsLogic::onUpdatePage() { set_labelWaitInfoVisible(false); set_labelWaitInfoText(""); @@ -91,7 +91,7 @@ void ServerSettingsLogic::onPushButtonForgetServer() uiLogic()->selectedServerIndex = -1; - uiLogic()->serverListLogic()->updatePage(); + uiLogic()->serverListLogic()->onUpdatePage(); if (m_settings.serversCount() == 0) { uiLogic()->setStartPage(Page::Start); @@ -121,7 +121,7 @@ void ServerSettingsLogic::onLineEditDescriptionEditingFinished() QJsonObject server = m_settings.server(uiLogic()->selectedServerIndex); server.insert(config_key::description, newText); m_settings.editServer(uiLogic()->selectedServerIndex, server); - uiLogic()->serverListLogic()->updatePage(); + uiLogic()->serverListLogic()->onUpdatePage(); } void ServerSettingsLogic::onPushButtonShareFullClicked() diff --git a/client/ui/pages_logic/ServerSettingsLogic.h b/client/ui/pages_logic/ServerSettingsLogic.h index 80812671..282b90ea 100644 --- a/client/ui/pages_logic/ServerSettingsLogic.h +++ b/client/ui/pages_logic/ServerSettingsLogic.h @@ -21,7 +21,7 @@ class ServerSettingsLogic : public PageLogicBase AUTO_PROPERTY(QString, labelCurrentVpnProtocolText) public: - Q_INVOKABLE void updatePage() override; + Q_INVOKABLE void onUpdatePage() override; Q_INVOKABLE void onPushButtonClearServer(); Q_INVOKABLE void onPushButtonForgetServer(); diff --git a/client/ui/pages_logic/StartPageLogic.cpp b/client/ui/pages_logic/StartPageLogic.cpp index ff50e135..394f70c7 100644 --- a/client/ui/pages_logic/StartPageLogic.cpp +++ b/client/ui/pages_logic/StartPageLogic.cpp @@ -21,7 +21,7 @@ StartPageLogic::StartPageLogic(UiLogic *logic, QObject *parent): } -void StartPageLogic::updatePage() +void StartPageLogic::onUpdatePage() { set_lineEditStartExistingCodeText(""); set_textEditSshKeyText(""); diff --git a/client/ui/pages_logic/StartPageLogic.h b/client/ui/pages_logic/StartPageLogic.h index d06ec7a3..61627727 100644 --- a/client/ui/pages_logic/StartPageLogic.h +++ b/client/ui/pages_logic/StartPageLogic.h @@ -23,7 +23,7 @@ class StartPageLogic : public PageLogicBase AUTO_PROPERTY(bool, pushButtonConnectVisible) public: - Q_INVOKABLE void updatePage() override; + Q_INVOKABLE void onUpdatePage() override; Q_INVOKABLE void onPushButtonConnect(); Q_INVOKABLE void onPushButtonImport(); diff --git a/client/ui/pages_logic/WizardLogic.cpp b/client/ui/pages_logic/WizardLogic.cpp index 67dde17b..e1ddb537 100644 --- a/client/ui/pages_logic/WizardLogic.cpp +++ b/client/ui/pages_logic/WizardLogic.cpp @@ -12,7 +12,7 @@ WizardLogic::WizardLogic(UiLogic *logic, QObject *parent): } -void WizardLogic::updatePage() +void WizardLogic::onUpdatePage() { set_lineEditHighWebsiteMaskingText(protocols::cloak::defaultRedirSite); } diff --git a/client/ui/pages_logic/WizardLogic.h b/client/ui/pages_logic/WizardLogic.h index d34a0147..cfba5d2d 100644 --- a/client/ui/pages_logic/WizardLogic.h +++ b/client/ui/pages_logic/WizardLogic.h @@ -16,7 +16,7 @@ class WizardLogic : public PageLogicBase AUTO_PROPERTY(QString, lineEditHighWebsiteMaskingText) public: - Q_INVOKABLE void updatePage() override; + Q_INVOKABLE void onUpdatePage() override; Q_INVOKABLE void onPushButtonVpnModeFinishClicked(); Q_INVOKABLE void onPushButtonLowFinishClicked(); diff --git a/client/ui/pages_logic/protocols/OtherProtocolsLogic.cpp b/client/ui/pages_logic/protocols/OtherProtocolsLogic.cpp new file mode 100644 index 00000000..41ae2ec3 --- /dev/null +++ b/client/ui/pages_logic/protocols/OtherProtocolsLogic.cpp @@ -0,0 +1,30 @@ +#include "OtherProtocolsLogic.h" +#include "core/servercontroller.h" +#include +#include "../../uilogic.h" + +using namespace amnezia; +using namespace PageEnumNS; + +OtherProtocolsLogic::OtherProtocolsLogic(UiLogic *logic, QObject *parent): + PageProtocolLogicBase(logic, parent) +{ + +} + +void OtherProtocolsLogic::updateProtocolPage(const QJsonObject &config, DockerContainer container, bool haveAuthData) +{ + set_labelTftpUserNameText(config.value(config_key::userName).toString()); + set_labelTftpPasswordText(config.value(config_key::password).toString(protocols::sftp::defaultUserName)); + set_labelTftpPortText(config.value(config_key::port).toString(protocols::sftp::defaultUserName)); +} + +//QJsonObject OtherProtocolsLogic::getProtocolConfigFromPage(QJsonObject oldConfig) +//{ + +//} + +void OtherProtocolsLogic::onPushButtonProtoShadowSocksSaveClicked() +{ + +} diff --git a/client/ui/pages_logic/protocols/OtherProtocolsLogic.h b/client/ui/pages_logic/protocols/OtherProtocolsLogic.h new file mode 100644 index 00000000..a70bc698 --- /dev/null +++ b/client/ui/pages_logic/protocols/OtherProtocolsLogic.h @@ -0,0 +1,31 @@ +#ifndef OTHER_PROTOCOLS_LOGIC_H +#define OTHER_PROTOCOLS_LOGIC_H + +#include "PageProtocolLogicBase.h" + +class UiLogic; + +class OtherProtocolsLogic : public PageProtocolLogicBase +{ + Q_OBJECT + + AUTO_PROPERTY(QString, labelTftpUserNameText) + AUTO_PROPERTY(QString, labelTftpPasswordText) + AUTO_PROPERTY(QString, labelTftpPortText) + +public: + Q_INVOKABLE void onPushButtonProtoShadowSocksSaveClicked(); + +public: + explicit OtherProtocolsLogic(UiLogic *uiLogic, QObject *parent = nullptr); + ~OtherProtocolsLogic() = default; + + void updateProtocolPage(const QJsonObject &config, DockerContainer container, bool haveAuthData) override; + //QJsonObject getProtocolConfigFromPage(QJsonObject oldConfig) override; + +private: + Settings m_settings; + UiLogic *m_uiLogic; + +}; +#endif // OTHER_PROTOCOLS_LOGIC_H diff --git a/client/ui/qml/Controls/TextFieldType.qml b/client/ui/qml/Controls/TextFieldType.qml index d6508ab9..a809a3d5 100644 --- a/client/ui/qml/Controls/TextFieldType.qml +++ b/client/ui/qml/Controls/TextFieldType.qml @@ -1,5 +1,6 @@ import QtQuick 2.12 import QtQuick.Controls 2.12 +import Qt.labs.platform 1.0 TextField { id: root @@ -8,6 +9,7 @@ TextField { width: parent.width - 80 height: 40 anchors.topMargin: 5 + selectByMouse: true selectionColor: "darkgray" font.pixelSize: 16 @@ -35,4 +37,36 @@ TextField { return "#A7A7A7" } } + + MouseArea { + anchors.fill: parent + acceptedButtons: Qt.RightButton + onClicked: contextMenu.open() + } + + Menu { + id: contextMenu + + onAboutToShow: console.log("aboutToShow") + onAboutToHide: console.log("aboutToHide") + + MenuItem { + text: qsTr("C&ut") + shortcut: StandardKey.Cut + enabled: root.selectedText + onTriggered: root.cut() + } + MenuItem { + text: qsTr("&Copy") + shortcut: StandardKey.Copy + enabled: root.selectedText + onTriggered: root.copy() + } + MenuItem { + text: qsTr("&Paste") + shortcut: StandardKey.Paste + enabled: root.canPaste + onTriggered: root.paste() + } + } } diff --git a/client/ui/qml/Pages/PageServerContainers.qml b/client/ui/qml/Pages/PageServerContainers.qml index bbe17b41..8b02cb7c 100644 --- a/client/ui/qml/Pages/PageServerContainers.qml +++ b/client/ui/qml/Pages/PageServerContainers.qml @@ -5,6 +5,7 @@ import SortFilterProxyModel 0.2 import ContainerProps 1.0 import ProtocolProps 1.0 import PageEnum 1.0 +import ProtocolEnum 1.0 import "./" import "../Controls" import "../Config" @@ -16,6 +17,18 @@ PageBase { logic: ServerContainersLogic enabled: ServerContainersLogic.pageEnabled + + function resetPage() { + container_selector.selectedIndex = -1 + } + + Connections { + target: logic + function onUpdatePage() { + root.resetPage() + } + } + BackButton { id: back } @@ -174,7 +187,7 @@ PageBase { Caption { id: cap1 - text: qsTr("Installed VPN containers") + text: qsTr("Installed Protocols and Services") font.pixelSize: 20 } @@ -268,16 +281,13 @@ PageBase { else tb_c.currentIndex = index UiLogic.protocolsModel.setSelectedDockerContainer(proxyContainersModel.mapToSource(index)) - //ServerContainersLogic.setSelectedDockerContainer(proxyContainersModel.mapToSource(index)) - - //container_selector.containerSelected(index) - //root.close() } } } ImageButtonType { id: button_default + visible: service_type_role == ProtocolEnum.Vpn Layout.alignment: Qt.AlignRight checkable: true diff --git a/client/ui/qml/Pages/PageServerSettings.qml b/client/ui/qml/Pages/PageServerSettings.qml index 7a476e02..de138d3e 100644 --- a/client/ui/qml/Pages/PageServerSettings.qml +++ b/client/ui/qml/Pages/PageServerSettings.qml @@ -100,7 +100,7 @@ PageBase { y: 210 width: 300 height: 40 - text: qsTr("Protocols and services") + text: qsTr("Protocols and Services") onClicked: { UiLogic.goToPage(PageEnum.ServerContainers) } diff --git a/client/ui/qml/Pages/Protocols/PageProtoOpenVPN.qml b/client/ui/qml/Pages/Protocols/PageProtoOpenVPN.qml index 4f07ffc9..1284594e 100644 --- a/client/ui/qml/Pages/Protocols/PageProtoOpenVPN.qml +++ b/client/ui/qml/Pages/Protocols/PageProtoOpenVPN.qml @@ -1,5 +1,6 @@ import QtQuick 2.12 import QtQuick.Controls 2.12 +import QtQuick.Layouts 1.15 import ProtocolEnum 1.0 import "../" import "../../Controls" @@ -13,113 +14,52 @@ PageProtocolBase { BackButton { id: back } - Item { - x: 0 - y: 40 - width: 380 - height: 600 - enabled: logic.pageEnabled - CheckBoxType { - x: 30 - y: 280 - width: 321 - height: 21 - text: qsTr("Auto-negotiate encryption") - checked: logic.checkBoxProtoOpenVpnAutoEncryptionChecked - onCheckedChanged: { - logic.checkBoxProtoOpenVpnAutoEncryptionChecked = checked - } - onClicked: { - logic.checkBoxProtoOpenVpnAutoEncryptionClicked() - } - } - CheckBoxType { - x: 30 - y: 430 - width: 321 - height: 21 - text: qsTr("Block DNS requests outside of VPN") - checked: logic.checkBoxProtoOpenVpnBlockDnsChecked - onCheckedChanged: { - logic.checkBoxProtoOpenVpnBlockDnsChecked = checked - } - } - CheckBoxType { - x: 30 - y: 390 - width: 321 - height: 21 - text: qsTr("Enable TLS auth") - checked: logic.checkBoxProtoOpenVpnTlsAuthChecked - onCheckedChanged: { - logic.checkBoxProtoOpenVpnTlsAuthChecked = checked - } + Caption { + id: caption + text: qsTr("OpenVPN Settings") + } - } - ComboBoxType { + Item { + enabled: logic.pageEnabled + anchors.top: caption.bottom + anchors.bottom: parent.bottom + width: parent.width + + LabelType { + id: lb_subnet x: 30 - y: 340 - width: 151 - height: 31 - model: [ - qsTr("AES-256-GCM"), - qsTr("AES-192-GCM"), - qsTr("AES-128-GCM"), - qsTr("AES-256-CBC"), - qsTr("AES-192-CBC"), - qsTr("AES-128-CBC"), - qsTr("ChaCha20-Poly1305"), - qsTr("ARIA-256-CBC"), - qsTr("CAMELLIA-256-CBC"), - qsTr("none") - ] - currentIndex: { - for (let i = 0; i < model.length; ++i) { - if (logic.comboBoxProtoOpenVpnCipherText === model[i]) { - return i - } - } - return -1 - } - onCurrentTextChanged: { - logic.comboBoxProtoOpenVpnCipherText = currentText - } - enabled: logic.comboBoxProtoOpenVpnCipherEnabled + anchors.top: parent.top + width: parent.width + height: 21 + text: qsTr("VPN Addresses Subnet") } - ComboBoxType { - x: 200 - y: 340 - width: 151 + TextFieldType { + id: tf_subnet + x: 30 + anchors.top: lb_subnet.bottom + + width: parent.width - 60 height: 31 - model: [ - qsTr("SHA512"), - qsTr("SHA384"), - qsTr("SHA256"), - qsTr("SHA3-512"), - qsTr("SHA3-384"), - qsTr("SHA3-256"), - qsTr("whirlpool"), - qsTr("BLAKE2b512"), - qsTr("BLAKE2s256"), - qsTr("SHA1") - ] - currentIndex: { - for (let i = 0; i < model.length; ++i) { - if (logic.comboBoxProtoOpenVpnHashText === model[i]) { - return i - } - } - return -1 + text: logic.lineEditProtoOpenVpnSubnetText + onEditingFinished: { + logic.lineEditProtoOpenVpnSubnetText = text } - onCurrentTextChanged: { - logic.comboBoxProtoOpenVpnHashText = currentText - } - enabled: logic.comboBoxProtoOpenVpnHashEnabled + } + + // + LabelType { + id: lb_proto + x: 30 + anchors.top: tf_subnet.bottom + width: parent.width + height: 21 + text: qsTr("Network protocol") } Rectangle { + id: rect_proto x: 30 - y: 140 - width: 321 + anchors.top: lb_proto.bottom + width: parent.width - 60 height: 71 border.width: 1 border.color: "lightgray" @@ -149,68 +89,27 @@ PageProtocolBase { enabled: logic.radioButtonProtoOpenVpnUdpEnabled } } + + // LabelType { + id: lb_port + anchors.top: rect_proto.bottom + anchors.topMargin: 20 + x: 30 - y: 110 - width: 151 - height: 21 - text: qsTr("Network protocol") - } - LabelType { - x: 30 - y: 230 - width: 151 + width: root.width / 2 - 10 height: 31 text: qsTr("Port") } - Text { - font.family: "Lato" - font.styleName: "normal" - font.pixelSize: 24 - color: "#100A44" - horizontalAlignment: Text.AlignHCenter - verticalAlignment: Text.AlignVCenter - text: qsTr("OpenVPN Settings") - x: 10 - y: 0 - width: 340 - height: 30 - } - LabelType { - x: 200 - y: 310 - width: 151 - height: 21 - text: qsTr("Hash") - } - LabelType { - x: 30 - y: 40 - width: 291 - height: 21 - text: qsTr("VPN Addresses Subnet") - } - LabelType { - x: 30 - y: 310 - width: 151 - height: 21 - text: qsTr("Cipher") - } - LabelType { - id: label_proto_openvpn_info - x: 30 - y: 550 - width: 321 - height: 41 - visible: logic.labelProtoOpenVpnInfoVisible - text: logic.labelProtoOpenVpnInfoText - } TextFieldType { - id: lineEdit_proto_openvpn_port - x: 200 - y: 230 - width: 151 + id: tf_port + anchors.top: rect_proto.bottom + anchors.topMargin: 20 + + anchors.left: parent.horizontalCenter + anchors.right: parent.right + anchors.rightMargin: 30 + height: 31 text: logic.lineEditProtoOpenVpnPortText onEditingFinished: { @@ -218,19 +117,157 @@ PageProtocolBase { } enabled: logic.lineEditProtoOpenVpnPortEnabled } - TextFieldType { - id: lineEdit_proto_openvpn_subnet + + // + CheckBoxType { + id: check_auto_enc + anchors.top: lb_port.bottom + anchors.topMargin: 20 x: 30 - y: 65 - width: 321 - height: 31 - text: logic.lineEditProtoOpenVpnSubnetText - onEditingFinished: { - logic.lineEditProtoOpenVpnSubnetText = text + width: parent.width + height: 21 + text: qsTr("Auto-negotiate encryption") + checked: logic.checkBoxProtoOpenVpnAutoEncryptionChecked + onCheckedChanged: { + logic.checkBoxProtoOpenVpnAutoEncryptionChecked = checked + } + onClicked: { + logic.checkBoxProtoOpenVpnAutoEncryptionClicked() } } + + + // + LabelType { + id: lb_cipher + x: 30 + anchors.top: check_auto_enc.bottom + anchors.topMargin: 20 + width: parent.width + height: 21 + text: qsTr("Cipher") + } + + ComboBoxType { + id: cb_cipher + x: 30 + anchors.top: lb_cipher.bottom + width: parent.width - 60 + + height: 31 + model: [ + qsTr("AES-256-GCM"), + qsTr("AES-192-GCM"), + qsTr("AES-128-GCM"), + qsTr("AES-256-CBC"), + qsTr("AES-192-CBC"), + qsTr("AES-128-CBC"), + qsTr("ChaCha20-Poly1305"), + qsTr("ARIA-256-CBC"), + qsTr("CAMELLIA-256-CBC"), + qsTr("none") + ] + currentIndex: { + for (let i = 0; i < model.length; ++i) { + if (logic.comboBoxProtoOpenVpnCipherText === model[i]) { + return i + } + } + return -1 + } + onCurrentTextChanged: { + logic.comboBoxProtoOpenVpnCipherText = currentText + } + enabled: logic.comboBoxProtoOpenVpnCipherEnabled + } + + // + LabelType { + id: lb_hash + anchors.top: cb_cipher.bottom + anchors.topMargin: 20 + width: parent.width + + height: 21 + text: qsTr("Hash") + } + ComboBoxType { + id: cb_hash + x: 30 + height: 31 + anchors.top: lb_hash.bottom + width: parent.width - 60 + model: [ + qsTr("SHA512"), + qsTr("SHA384"), + qsTr("SHA256"), + qsTr("SHA3-512"), + qsTr("SHA3-384"), + qsTr("SHA3-256"), + qsTr("whirlpool"), + qsTr("BLAKE2b512"), + qsTr("BLAKE2s256"), + qsTr("SHA1") + ] + currentIndex: { + for (let i = 0; i < model.length; ++i) { + if (logic.comboBoxProtoOpenVpnHashText === model[i]) { + return i + } + } + return -1 + } + onCurrentTextChanged: { + logic.comboBoxProtoOpenVpnHashText = currentText + } + enabled: logic.comboBoxProtoOpenVpnHashEnabled + } + + CheckBoxType { + id: check_tls + x: 30 + anchors.top: cb_hash.bottom + anchors.topMargin: 20 + width: parent.width + height: 21 + text: qsTr("Enable TLS auth") + checked: logic.checkBoxProtoOpenVpnTlsAuthChecked + onCheckedChanged: { + logic.checkBoxProtoOpenVpnTlsAuthChecked = checked + } + + } + + CheckBoxType { + id: check_block_dns + x: 30 + anchors.top: check_tls.bottom + anchors.topMargin: 20 + width: parent.width + height: 21 + text: qsTr("Block DNS requests outside of VPN") + checked: logic.checkBoxProtoOpenVpnBlockDnsChecked + onCheckedChanged: { + logic.checkBoxProtoOpenVpnBlockDnsChecked = checked + } + } + + + + +// LabelType { +// id: label_proto_openvpn_info +// x: 30 +// y: 550 +// width: 321 +// height: 41 +// visible: logic.labelProtoOpenVpnInfoVisible +// text: logic.labelProtoOpenVpnInfoText +// } + + ProgressBar { - id: progressBar_proto_openvpn_reset + id: progress_save anchors.horizontalCenter: parent.horizontalCenter y: 500 width: 321 @@ -250,7 +287,7 @@ PageProtocolBase { implicitWidth: parent.width implicitHeight: parent.height Rectangle { - width: progressBar_proto_openvpn_reset.visualPosition * parent.width + width: progress_save.visualPosition * parent.width height: parent.height radius: 4 color: Qt.rgba(255, 255, 255, 0.15); @@ -258,9 +295,12 @@ PageProtocolBase { } } BlueButtonType { + id: pb_save anchors.horizontalCenter: parent.horizontalCenter - y: 500 - width: 321 + anchors.bottom: parent.bottom + anchors.bottomMargin: 20 + x: 30 + width: parent.width - 60 height: 40 text: qsTr("Save and restart VPN") visible: logic.pushButtonOpenvpnSaveVisible diff --git a/client/ui/qml/Pages/Protocols/PageProtoSftp.qml b/client/ui/qml/Pages/Protocols/PageProtoSftp.qml new file mode 100644 index 00000000..16c5b472 --- /dev/null +++ b/client/ui/qml/Pages/Protocols/PageProtoSftp.qml @@ -0,0 +1,79 @@ +import QtQuick 2.12 +import QtQuick.Controls 2.12 +import ProtocolEnum 1.0 +import "../" +import "../../Controls" +import "../../Config" + +PageProtocolBase { + id: root + protocol: ProtocolEnum.Sftp + logic: UiLogic.protocolLogic(protocol) + + BackButton { + id: back + } + + Caption { + id: caption + text: qsTr("SFTF settings") + } + + Rectangle { + id: frame_settings + width: parent.width + anchors.top: caption.bottom + anchors.topMargin: 10 + + border.width: 1 + border.color: "lightgray" + anchors.bottomMargin: 5 + anchors.horizontalCenter: parent.horizontalCenter + radius: 2 + Grid { + id: grid + anchors.fill: parent + columns: 2 + horizontalItemAlignment: Grid.AlignHCenter + verticalItemAlignment: Grid.AlignVCenter + topPadding: 5 + leftPadding: 10 + spacing: 5 + + + LabelType { + width: 130 + text: qsTr("Port") + } + TextFieldType { + id: tf_port_num + width: parent.width - 130 - parent.spacing - parent.leftPadding * 2 + text: logic.labelTftpPortText + readOnly: true + } + + LabelType { + width: 130 + text: qsTr("User Name") + } + TextFieldType { + id: tf_user_name + width: parent.width - 130 - parent.spacing - parent.leftPadding * 2 + text: logic.labelTftpUserNameText + readOnly: true + } + + LabelType { + width: 130 + text: qsTr("Password") + } + TextFieldType { + id: tf_password + width: parent.width - 130 - parent.spacing - parent.leftPadding * 2 + text: logic.labelTftpPasswordText + readOnly: true + } + } + } + +} diff --git a/client/ui/qml/main.qml b/client/ui/qml/main.qml index 0b77f03e..3792c888 100644 --- a/client/ui/qml/main.qml +++ b/client/ui/qml/main.qml @@ -31,7 +31,7 @@ Window { function gotoPage(page, reset, slide) { if (reset) { if (page === PageEnum.ServerSettings) { - ServerSettingsLogic.updatePage(); + ServerSettingsLogic.onUpdatePage(); } if (page === PageEnum.ShareConnection) { } @@ -39,32 +39,32 @@ Window { WizardLogic.radioButtonMediumChecked = true } if (page === PageEnum.WizardHigh) { - WizardLogic.updatePage(); + WizardLogic.onUpdatePage(); } if (page === PageEnum.ServerConfiguringProgress) { ServerConfiguringProgressLogic.progressBarValue = 0; } if (page === PageEnum.GeneralSettings) { - GeneralSettingsLogic.updatePage(); + GeneralSettingsLogic.onUpdatePage(); } if (page === PageEnum.ServersList) { - ServerListLogic.updatePage(); + ServerListLogic.onUpdatePage(); } if (page === PageEnum.Start) { StartPageLogic.pushButtonBackFromStartVisible = !pageLoader.empty - StartPageLogic.updatePage(); + StartPageLogic.onUpdatePage(); } if (page === PageEnum.NewServerProtocols) { - NewServerProtocolsLogic.updatePage() + NewServerProtocolsLogic.onUpdatePage() } if (page === PageEnum.ServerContainers) { - ServerContainersLogic.updateServerContainersPage() + ServerContainersLogic.onUpdatePage() } if (page === PageEnum.AppSettings) { - AppSettingsLogic.updatePage() + AppSettingsLogic.onUpdatePage() } if (page === PageEnum.NetworkSettings) { - NetworkSettingsLogic.updatePage() + NetworkSettingsLogic.onUpdatePage() } if (page === PageEnum.Sites) { SitesLogic.updateSitesPage() @@ -84,8 +84,8 @@ Window { } function gotoProtocolPage(protocol, reset, slide) { - if (reset) { - protocolPages[protocol].logic.updatePage(); + if (reset && protocolPages[protocol] !== "undefined") { + protocolPages[protocol].logic.onUpdatePage(); } if (slide) { @@ -113,7 +113,7 @@ Window { } if (page === PageEnum.Start) { UiLogic.pushButtonBackFromStartVisible = !pageLoader.empty - UiLogic.updatePage(); + UiLogic.onUpdatePage(); } } @@ -154,26 +154,31 @@ Window { // initialItem: page_servers onCurrentItemChanged: { + console.debug("QML onCurrentItemChanged " + pageLoader.currentItem) UiLogic.currentPageValue = currentItem.page } - Keys.onReleased: { - if (event.key === Qt.Key_Back || event.key === Qt.Key_Escape) { - console.debug("Back button captured") - if (UiLogic.currentPageValue !== PageEnum.VPN && - UiLogic.currentPageValue !== PageEnum.ServerConfiguring && - !(UiLogic.currentPageValue === PageEnum.Start && pageLoader.depth < 2)) { - close_page(); - } +// Keys.onReleased: { +// if (event.key === Qt.Key_Back || event.key === Qt.Key_Escape) { +// console.debug("Back button captured") +// if (UiLogic.currentPageValue !== PageEnum.VPN && +// UiLogic.currentPageValue !== PageEnum.ServerConfiguring && +// !(UiLogic.currentPageValue === PageEnum.Start && pageLoader.depth < 2)) { +// close_page(); +// } - // TODO: fix - //if (ui->stackedWidget_main->currentWidget()->isEnabled()) { - // closePage(); - //} +// // TODO: fix +// //if (ui->stackedWidget_main->currentWidget()->isEnabled()) { +// // closePage(); +// //} - event.accepted = true - } +// event.accepted = true +// } +// } + + Keys.onPressed: { + UiLogic.keyPressEvent(event.key) } } @@ -220,13 +225,9 @@ Window { obj.visible = false if (isProtocol) { protocolPages[obj.protocol] = obj - console.debug("PPP " + obj.protocol + " " + file) - } else { pages[obj.page] = obj - console.debug("AAA " + obj.page + " " + file) - } @@ -246,30 +247,30 @@ Window { Connections { target: UiLogic - onGoToPage: { + function onGoToPage(page, reset, slide) { console.debug("Connections onGoToPage " + page); root.gotoPage(page, reset, slide) } - onGoToProtocolPage: { + function onGoToProtocolPage(protocol, reset, slide) { console.debug("Connections onGoToProtocolPage " + protocol); root.gotoProtocolPage(protocol, reset, slide) } - onClosePage: { + function onClosePage() { root.close_page() } - onSetStartPage: { + function onSetStartPage(page, slide) { root.set_start_page(page, slide) } - onShowPublicKeyWarning: { + function onShowPublicKeyWarning() { publicKeyWarning.visible = true } - onShowConnectErrorDialog: { + function onShowConnectErrorDialog() { connectErrorDialog.visible = true } - onShow: { + function onShow() { root.show() } - onHide: { + function onHide() { root.hide() } } diff --git a/client/ui/uilogic.cpp b/client/ui/uilogic.cpp index e3d35e04..86719951 100644 --- a/client/ui/uilogic.cpp +++ b/client/ui/uilogic.cpp @@ -61,6 +61,7 @@ #include "pages_logic/protocols/CloakLogic.h" #include "pages_logic/protocols/OpenVpnLogic.h" #include "pages_logic/protocols/ShadowSocksLogic.h" +#include "pages_logic/protocols/OtherProtocolsLogic.h" using namespace amnezia; @@ -96,6 +97,10 @@ UiLogic::UiLogic(QObject *parent) : m_protocolLogicMap.insert(Protocol::ShadowSocks, new ShadowSocksLogic(this)); m_protocolLogicMap.insert(Protocol::Cloak, new CloakLogic(this)); //m_protocolLogicMap->insert(Protocol::WireGuard, new WireguardLogic(this)); + + m_protocolLogicMap.insert(Protocol::Dns, new OtherProtocolsLogic(this)); + m_protocolLogicMap.insert(Protocol::Sftp, new OtherProtocolsLogic(this)); + } void UiLogic::initalizeUiLogic() @@ -131,8 +136,9 @@ void UiLogic::initalizeUiLogic() } selectedServerIndex = m_settings.defaultServerIndex(); - goToPage(Page::ServerContainers, true, false); - goToPage(Page::NewServerProtocols, true, false); + //goToPage(Page::ServerContainers, true, false); + //goToPage(Page::NewServerProtocols, true, false); + onGotoProtocolPage(Protocol::OpenVpn); //ui->pushButton_general_settings_exit->hide(); @@ -284,52 +290,53 @@ void UiLogic::showOnStartup() } -//void UiLogic::keyPressEvent(QKeyEvent *event) -//{ -// switch (event->key()) { -// case Qt::Key_L: -// if (!Debug::openLogsFolder()) { -// QMessageBox::warning(this, APPLICATION_NAME, tr("Cannot open logs folder!")); -// } -// break; -//#ifdef QT_DEBUG -// case Qt::Key_Q: -// qApp->quit(); -// break; -// // case Qt::Key_0: -// // *((char*)-1) = 'x'; -// // break; -// case Qt::Key_H: -// selectedServerIndex = m_settings.defaultServerIndex(); -// selectedDockerContainer = m_settings.defaultContainer(selectedServerIndex); +void UiLogic::keyPressEvent(Qt::Key key) +{ + switch (key) { + case Qt::Key_L: + if (!Debug::openLogsFolder()) { + //QMessageBox::warning(this, APPLICATION_NAME, tr("Cannot open logs folder!")); + } + break; +#ifdef QT_DEBUG + case Qt::Key_Q: + qApp->quit(); + break; + // case Qt::Key_0: + // *((char*)-1) = 'x'; + // break; + case Qt::Key_H: + selectedServerIndex = m_settings.defaultServerIndex(); + selectedDockerContainer = m_settings.defaultContainer(selectedServerIndex); -// updateSharingPage(selectedServerIndex, m_settings.serverCredentials(selectedServerIndex), selectedDockerContainer); -// goToPage(Page::ShareConnection); -// break; -//#endif -// case Qt::Key_C: -// qDebug().noquote() << "Def server" << m_settings.defaultServerIndex() << m_settings.defaultContainerName(m_settings.defaultServerIndex()); -// //qDebug().noquote() << QJsonDocument(m_settings.containerConfig(m_settings.defaultServerIndex(), m_settings.defaultContainer(m_settings.defaultServerIndex()))).toJson(); -// qDebug().noquote() << QJsonDocument(m_settings.defaultServer()).toJson(); -// break; -// case Qt::Key_A: -// goToPage(Page::Start); -// break; -// case Qt::Key_S: -// selectedServerIndex = m_settings.defaultServerIndex(); -// goToPage(Page::ServerSettings); -// break; -// case Qt::Key_P: -// selectedServerIndex = m_settings.defaultServerIndex(); -// selectedDockerContainer = m_settings.defaultContainer(selectedServerIndex); -// goToPage(Page::ServerContainers); -// break; -// case Qt::Key_T: -// SshConfigurator::openSshTerminal(m_settings.serverCredentials(m_settings.defaultServerIndex())); -// break; -// case Qt::Key_Escape: -// if (currentPage() == Page::Vpn) break; -// if (currentPage() == Page::ServerConfiguring) break; + //updateSharingPage(selectedServerIndex, m_settings.serverCredentials(selectedServerIndex), selectedDockerContainer); + emit goToPage(Page::ShareConnection); + break; +#endif + case Qt::Key_C: + qDebug().noquote() << "Def server" << m_settings.defaultServerIndex() << m_settings.defaultContainerName(m_settings.defaultServerIndex()); + //qDebug().noquote() << QJsonDocument(m_settings.containerConfig(m_settings.defaultServerIndex(), m_settings.defaultContainer(m_settings.defaultServerIndex()))).toJson(); + qDebug().noquote() << QJsonDocument(m_settings.defaultServer()).toJson(); + break; + case Qt::Key_A: + emit goToPage(Page::Start); + break; + case Qt::Key_S: + selectedServerIndex = m_settings.defaultServerIndex(); + emit goToPage(Page::ServerSettings); + break; + case Qt::Key_P: + selectedServerIndex = m_settings.defaultServerIndex(); + selectedDockerContainer = m_settings.defaultContainer(selectedServerIndex); + emit goToPage(Page::ServerContainers); + break; + case Qt::Key_T: + SshConfigurator::openSshTerminal(m_settings.serverCredentials(m_settings.defaultServerIndex())); + break; + case Qt::Key_Escape: + case Qt::Key_Back: + if (currentPage() == Page::Vpn) break; + if (currentPage() == Page::ServerConfiguringProgress) break; // if (currentPage() == Page::Start && pagesStack.size() < 2) break; // if (currentPage() == Page::Sites && // ui->tableView_sites->selectionModel()->selection().indexes().size() > 0) { @@ -337,13 +344,13 @@ void UiLogic::showOnStartup() // break; // } -// if (! ui->stackedWidget_main->isAnimationRunning() && ui->stackedWidget_main->currentWidget()->isEnabled()) { -// closePage(); -// } -// default: -// ; -// } -//} + //if (! ui->stackedWidget_main->isAnimationRunning() && ui->stackedWidget_main->currentWidget()->isEnabled()) { + emit closePage(); + //} + default: + ; + } +} void UiLogic::onCloseWindow() { @@ -651,6 +658,15 @@ void UiLogic::setTrayIcon(const QString &iconPath) setTrayIconUrl(iconPath); } +PageProtocolLogicBase *UiLogic::protocolLogic(Protocol p) { + PageProtocolLogicBase *logic = m_protocolLogicMap.value(p); + if (logic) return logic; + else { + qDebug() << "UiLogic::protocolLogic Warning: logic missing for" << p; + return new PageProtocolLogicBase(this); + } +} + PageEnumNS::Page UiLogic::currentPage() { return static_cast(getCurrentPageValue()); diff --git a/client/ui/uilogic.h b/client/ui/uilogic.h index fb321ad2..17edad40 100644 --- a/client/ui/uilogic.h +++ b/client/ui/uilogic.h @@ -4,6 +4,7 @@ #include #include #include +#include #include "property_helper.h" #include "pages.h" @@ -86,6 +87,8 @@ public: Q_INVOKABLE void onGotoPage(PageEnumNS::Page p, bool reset = true, bool slide = true) { emit goToPage(p, reset, slide); } Q_INVOKABLE void onGotoProtocolPage(Protocol p, bool reset = true, bool slide = true) { emit goToProtocolPage(p, reset, slide); } + Q_INVOKABLE void keyPressEvent(Qt::Key key); + int getCurrentPageValue() const; void setCurrentPageValue(int currentPageValue); @@ -181,7 +184,7 @@ public: VpnLogic *vpnLogic() { return m_vpnLogic; } WizardLogic *wizardLogic() { return m_wizardLogic; } - Q_INVOKABLE PageProtocolLogicBase *protocolLogic(Protocol p) { return m_protocolLogicMap.value(p); } + Q_INVOKABLE PageProtocolLogicBase *protocolLogic(Protocol p); private: AppSettingsLogic *m_appSettingsLogic; @@ -212,7 +215,6 @@ private: // QPoint offset; // bool needToHideCustomTitlebar = false; - // void keyPressEvent(QKeyEvent* event) override; // void showEvent(QShowEvent *event) override; // void hideEvent(QHideEvent *event) override;