From b244158b95f64cfed1b45fe5232e3afde6964be9 Mon Sep 17 00:00:00 2001 From: pokamest Date: Fri, 24 Sep 2021 13:14:35 +0300 Subject: [PATCH] =?UTF-8?q?website=20in=20tor=20network=20container=20impr?= =?UTF-8?q?oved=20Sponsored=20by=20"=D0=A2=D0=B5=D0=BF=D0=BB=D0=B8=D1=86?= =?UTF-8?q?=D0=B0=20=D1=81=D0=BE=D1=86=D0=B8=D0=B0=D0=BB=D1=8C=D0=BD=D1=8B?= =?UTF-8?q?=D1=85=20=D1=82=D0=B5=D1=85=D0=BD=D0=BE=D0=BB=D0=BE=D0=B3=D0=B8?= =?UTF-8?q?=D0=B9",=202021=20=D0=92=20=D1=80=D0=B0=D0=BC=D0=BA=D0=B0=D1=85?= =?UTF-8?q?=20=D1=80=D0=B0=D0=B1=D0=BE=D1=82=D1=8B=20=D0=BD=D0=B0=D0=B4=20?= =?UTF-8?q?=D0=B7=D0=B0=D0=B4=D0=B0=D1=87=D0=B0=D0=BC=D0=B8=20=D0=BF=D0=BE?= =?UTF-8?q?=20=D1=85=D0=B0=D0=BA=D0=B0=D1=82=D0=BE=D0=BD=D1=83=202021?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- client/client.pro | 2 + client/configurators/vpn_configurator.cpp | 21 + client/configurators/vpn_configurator.h | 4 + client/containers/containers_defs.cpp | 3 + client/core/servercontroller.cpp | 30 +- client/core/servercontroller.h | 8 +- client/protocols/protocols_defs.cpp | 2 +- client/resources.qrc | 1 + .../website_tor/configure_container.sh | 2 + .../website_tor/run_container.sh | 4 +- .../ui/pages_logic/ServerContainersLogic.cpp | 4 +- client/ui/pages_logic/WizardLogic.cpp | 6 +- .../ui/pages_logic/protocols/CloakLogic.cpp | 2 +- .../ui/pages_logic/protocols/OpenVpnLogic.cpp | 2 +- .../protocols/OtherProtocolsLogic.cpp | 101 ++- .../protocols/OtherProtocolsLogic.h | 15 +- .../protocols/ShadowSocksLogic.cpp | 2 +- client/ui/qml/Pages/PageServerContainers.qml | 8 +- .../qml/Pages/Protocols/PageProtoOpenVPN.qml | 614 ++++++++++-------- .../ui/qml/Pages/Protocols/PageProtoSftp.qml | 60 +- .../Pages/Protocols/PageProtoTorWebSite.qml | 58 ++ client/ui/uilogic.cpp | 9 +- client/ui/uilogic.h | 10 +- client/utils.cpp | 1 + deploy/build_windows.bat | 2 +- 25 files changed, 676 insertions(+), 295 deletions(-) create mode 100644 client/ui/qml/Pages/Protocols/PageProtoTorWebSite.qml diff --git a/client/client.pro b/client/client.pro index c5d615f3..efc9708b 100644 --- a/client/client.pro +++ b/client/client.pro @@ -4,6 +4,8 @@ TARGET = AmneziaVPN TEMPLATE = app #CONFIG += console +CONFIG += qtquickcompiler + ios:CONFIG += static DEFINES += QT_DEPRECATED_WARNINGS diff --git a/client/configurators/vpn_configurator.cpp b/client/configurators/vpn_configurator.cpp index 35bbfbce..cb67c351 100644 --- a/client/configurators/vpn_configurator.cpp +++ b/client/configurators/vpn_configurator.cpp @@ -31,3 +31,24 @@ QString VpnConfigurator::genVpnProtocolConfig(const ServerCredentials &credentia return ""; } } + +void VpnConfigurator::updateContainerConfigAfterInstallation(DockerContainer container, QJsonObject &containerConfig, + const QString &stdOut) +{ + Protocol mainProto = ContainerProps::defaultProtocol(container); + + if (container == DockerContainer::TorWebSite) { + QJsonObject protocol = containerConfig.value(ProtocolProps::protoToString(mainProto)).toObject(); + + qDebug() << "amnezia-tor onions" << stdOut; + + QStringList l = stdOut.split(","); + for (QString s : l) { + if (s.contains(":80")) { + protocol.insert(config_key::site, s); + } + } + + containerConfig.insert(ProtocolProps::protoToString(mainProto), protocol); + } +} diff --git a/client/configurators/vpn_configurator.h b/client/configurators/vpn_configurator.h index 02f410a2..d6b4c5d8 100644 --- a/client/configurators/vpn_configurator.h +++ b/client/configurators/vpn_configurator.h @@ -13,6 +13,10 @@ public: static QString genVpnProtocolConfig(const ServerCredentials &credentials, DockerContainer container, const QJsonObject &containerConfig, Protocol proto, ErrorCode *errorCode = nullptr); + + static void updateContainerConfigAfterInstallation(DockerContainer container, + QJsonObject &containerConfig, const QString &stdOut); + }; #endif // VPN_CONFIGURATOR_H diff --git a/client/containers/containers_defs.cpp b/client/containers/containers_defs.cpp index ade42a21..f3319310 100644 --- a/client/containers/containers_defs.cpp +++ b/client/containers/containers_defs.cpp @@ -37,6 +37,9 @@ QVector ContainerProps::protocolsForContainer(amnezia::Docker case DockerContainer::Cloak: return { Protocol::OpenVpn, Protocol::ShadowSocks, Protocol::Cloak }; + case DockerContainer::Dns: + return { }; + default: return { defaultProtocol(container) }; } diff --git a/client/core/servercontroller.cpp b/client/core/servercontroller.cpp index 4bc9d157..782c4fec 100644 --- a/client/core/servercontroller.cpp +++ b/client/core/servercontroller.cpp @@ -19,6 +19,8 @@ #include "scripts_registry.h" #include "utils.h" +#include + using namespace QSsh; @@ -361,7 +363,7 @@ ErrorCode ServerController::removeContainer(const ServerCredentials &credentials genVarsForScript(credentials, container))); } -ErrorCode ServerController::setupContainer(const ServerCredentials &credentials, DockerContainer container, const QJsonObject &config) +ErrorCode ServerController::setupContainer(const ServerCredentials &credentials, DockerContainer container, QJsonObject &config) { qDebug().noquote() << "ServerController::setupContainer" << ContainerProps::containerToString(container); //qDebug().noquote() << QJsonDocument(config).toJson(); @@ -397,7 +399,7 @@ ErrorCode ServerController::setupContainer(const ServerCredentials &credentials, } ErrorCode ServerController::updateContainer(const ServerCredentials &credentials, DockerContainer container, - const QJsonObject &oldConfig, const QJsonObject &newConfig) + const QJsonObject &oldConfig, QJsonObject &newConfig) { bool reinstallRequred = isReinstallContainerRequred(container, oldConfig, newConfig); qDebug() << "ServerController::updateContainer for container" << container << "reinstall required is" << reinstallRequred; @@ -518,7 +520,7 @@ ErrorCode ServerController::buildContainerWorker(const ServerCredentials &creden genVarsForScript(credentials, container, config))); } -ErrorCode ServerController::runContainerWorker(const ServerCredentials &credentials, DockerContainer container, const QJsonObject &config) +ErrorCode ServerController::runContainerWorker(const ServerCredentials &credentials, DockerContainer container, QJsonObject &config) { QString stdOut; auto cbReadStdOut = [&](const QString &data, QSharedPointer proc) { @@ -540,11 +542,25 @@ ErrorCode ServerController::runContainerWorker(const ServerCredentials &credenti return e; } -ErrorCode ServerController::configureContainerWorker(const ServerCredentials &credentials, DockerContainer container, const QJsonObject &config) +ErrorCode ServerController::configureContainerWorker(const ServerCredentials &credentials, DockerContainer container, QJsonObject &config) { - return runScript(sshParams(credentials), + QString stdOut; + auto cbReadStdOut = [&](const QString &data, QSharedPointer proc) { + stdOut += data + "\n"; + }; + auto cbReadStdErr = [&](const QString &data, QSharedPointer proc) { + stdOut += data + "\n"; + }; + + + ErrorCode e = runScript(sshParams(credentials), replaceVars(amnezia::scriptData(ProtocolScriptType::configure_container, container), - genVarsForScript(credentials, container, config))); + genVarsForScript(credentials, container, config)), + cbReadStdOut, cbReadStdErr); + + VpnConfigurator::updateContainerConfigAfterInstallation(container, config, stdOut); + + return e; } ErrorCode ServerController::startupContainerWorker(const ServerCredentials &credentials, DockerContainer container, const QJsonObject &config) @@ -620,6 +636,8 @@ ServerController::Vars ServerController::genVarsForScript(const ServerCredential // Sftp vars vars.append({{"$SFTP_PORT", sftpConfig.value(config_key::port).toString(QString::number(ProtocolProps::defaultPort(Protocol::Sftp))) }}); + vars.append({{"$SFTP_USER", sftpConfig.value(config_key::userName).toString() }}); + vars.append({{"$SFTP_PASSWORD", sftpConfig.value(config_key::password).toString() }}); QString serverIp = Utils::getIPAddress(credentials.hostName); diff --git a/client/core/servercontroller.h b/client/core/servercontroller.h index d0462773..7116df41 100644 --- a/client/core/servercontroller.h +++ b/client/core/servercontroller.h @@ -28,9 +28,9 @@ public: static ErrorCode removeAllContainers(const ServerCredentials &credentials); static ErrorCode removeContainer(const ServerCredentials &credentials, DockerContainer container); - static ErrorCode setupContainer(const ServerCredentials &credentials, DockerContainer container, const QJsonObject &config = QJsonObject()); + static ErrorCode setupContainer(const ServerCredentials &credentials, DockerContainer container, QJsonObject &config); static ErrorCode updateContainer(const ServerCredentials &credentials, DockerContainer container, - const QJsonObject &oldConfig, const QJsonObject &newConfig = QJsonObject()); + const QJsonObject &oldConfig, QJsonObject &newConfig); // create initial config - generate passwords, etc static QJsonObject createContainerInitialConfig(DockerContainer container, int port, TransportProto tp); @@ -67,8 +67,8 @@ private: static ErrorCode installDockerWorker(const ServerCredentials &credentials, DockerContainer container); static ErrorCode prepareHostWorker(const ServerCredentials &credentials, DockerContainer container, const QJsonObject &config = QJsonObject()); static ErrorCode buildContainerWorker(const ServerCredentials &credentials, DockerContainer container, const QJsonObject &config = QJsonObject()); - static ErrorCode runContainerWorker(const ServerCredentials &credentials, DockerContainer container, const QJsonObject &config = QJsonObject()); - static ErrorCode configureContainerWorker(const ServerCredentials &credentials, DockerContainer container, const QJsonObject &config = QJsonObject()); + static ErrorCode runContainerWorker(const ServerCredentials &credentials, DockerContainer container, QJsonObject &config); + static ErrorCode configureContainerWorker(const ServerCredentials &credentials, DockerContainer container, QJsonObject &config); static ErrorCode startupContainerWorker(const ServerCredentials &credentials, DockerContainer container, const QJsonObject &config = QJsonObject()); }; diff --git a/client/protocols/protocols_defs.cpp b/client/protocols/protocols_defs.cpp index 4536a5bd..ed316c8d 100644 --- a/client/protocols/protocols_defs.cpp +++ b/client/protocols/protocols_defs.cpp @@ -103,7 +103,7 @@ int ProtocolProps::defaultPort(Protocol p) case Protocol::Cloak : return 443; case Protocol::ShadowSocks : return 6789; case Protocol::WireGuard : return 51820; - case Protocol::TorWebSite : return 443; + case Protocol::TorWebSite : return -1; case Protocol::Dns : return 53; case Protocol::FileShare : return 139; case Protocol::Sftp : return 222; diff --git a/client/resources.qrc b/client/resources.qrc index 366b1de6..202b2060 100644 --- a/client/resources.qrc +++ b/client/resources.qrc @@ -121,5 +121,6 @@ server_scripts/sftp/Dockerfile server_scripts/sftp/run_container.sh ui/qml/Pages/Protocols/PageProtoSftp.qml + ui/qml/Pages/Protocols/PageProtoTorWebSite.qml diff --git a/client/server_scripts/website_tor/configure_container.sh b/client/server_scripts/website_tor/configure_container.sh index e69de29b..d49d418f 100644 --- a/client/server_scripts/website_tor/configure_container.sh +++ b/client/server_scripts/website_tor/configure_container.sh @@ -0,0 +1,2 @@ +sleep 5 +sudo docker exec -i amnezia-tor onions diff --git a/client/server_scripts/website_tor/run_container.sh b/client/server_scripts/website_tor/run_container.sh index 8be442ea..11adb569 100644 --- a/client/server_scripts/website_tor/run_container.sh +++ b/client/server_scripts/website_tor/run_container.sh @@ -1,3 +1,3 @@ # Run container -sudo docker run -d -p 80:80 --restart always --name amnezia-wp-tor tutum/wordpress -sudo docker run -d --link amnezia-wp-tor --name amnezia-tor goldy/tor-hidden-service +sudo docker run -d -p 80:80 --restart always --name $CONTAINER_NAME tutum/wordpress +sudo docker run -d --link $CONTAINER_NAME --name amnezia-tor goldy/tor-hidden-service diff --git a/client/ui/pages_logic/ServerContainersLogic.cpp b/client/ui/pages_logic/ServerContainersLogic.cpp index fbf36653..23fd1880 100644 --- a/client/ui/pages_logic/ServerContainersLogic.cpp +++ b/client/ui/pages_logic/ServerContainersLogic.cpp @@ -74,8 +74,8 @@ void ServerContainersLogic::onPushButtonContinueClicked(DockerContainer c, int p emit uiLogic()->goToPage(Page::ServerConfiguringProgress); qApp->processEvents(); - ErrorCode e = uiLogic()->serverConfiguringProgressLogic()->doInstallAction([this, c](){ - return ServerController::setupContainer(m_settings.serverCredentials(uiLogic()->selectedServerIndex), c); + ErrorCode e = uiLogic()->serverConfiguringProgressLogic()->doInstallAction([this, c, &config](){ + return ServerController::setupContainer(m_settings.serverCredentials(uiLogic()->selectedServerIndex), c, config); }); if (!e) { diff --git a/client/ui/pages_logic/WizardLogic.cpp b/client/ui/pages_logic/WizardLogic.cpp index e1ddb537..aeffc21b 100644 --- a/client/ui/pages_logic/WizardLogic.cpp +++ b/client/ui/pages_logic/WizardLogic.cpp @@ -51,7 +51,8 @@ QMap WizardLogic::getInstallConfigsFromWizardPage( void WizardLogic::onPushButtonVpnModeFinishClicked() { - uiLogic()->installServer(getInstallConfigsFromWizardPage()); + auto containers = getInstallConfigsFromWizardPage(); + uiLogic()->installServer(containers); if (checkBoxVpnModeChecked()) { m_settings.setRouteMode(Settings::VpnOnlyForwardSites); } else { @@ -61,5 +62,6 @@ void WizardLogic::onPushButtonVpnModeFinishClicked() void WizardLogic::onPushButtonLowFinishClicked() { - uiLogic()->installServer(getInstallConfigsFromWizardPage()); + auto containers = getInstallConfigsFromWizardPage(); + uiLogic()->installServer(containers); } diff --git a/client/ui/pages_logic/protocols/CloakLogic.cpp b/client/ui/pages_logic/protocols/CloakLogic.cpp index c99bbe96..73632892 100644 --- a/client/ui/pages_logic/protocols/CloakLogic.cpp +++ b/client/ui/pages_logic/protocols/CloakLogic.cpp @@ -88,7 +88,7 @@ void CloakLogic::onPushButtonProtoCloakSaveClicked() return progressBarProtoCloakResetMaximium(); }; - ErrorCode e = uiLogic()->doInstallAction([this, containerConfig, newContainerConfig](){ + ErrorCode e = uiLogic()->doInstallAction([this, containerConfig, &newContainerConfig](){ return ServerController::updateContainer(m_settings.serverCredentials(uiLogic()->selectedServerIndex), uiLogic()->selectedDockerContainer, containerConfig, newContainerConfig); }, page_proto_cloak, progressBar_proto_cloak_reset, diff --git a/client/ui/pages_logic/protocols/OpenVpnLogic.cpp b/client/ui/pages_logic/protocols/OpenVpnLogic.cpp index fd7e069e..910211c6 100644 --- a/client/ui/pages_logic/protocols/OpenVpnLogic.cpp +++ b/client/ui/pages_logic/protocols/OpenVpnLogic.cpp @@ -125,7 +125,7 @@ void OpenVpnLogic::onPushButtonProtoOpenVpnSaveClicked() return progressBarProtoOpenVpnResetMaximium(); }; - ErrorCode e = uiLogic()->doInstallAction([this, containerConfig, newContainerConfig](){ + ErrorCode e = uiLogic()->doInstallAction([this, containerConfig, &newContainerConfig](){ return ServerController::updateContainer(m_settings.serverCredentials(uiLogic()->selectedServerIndex), uiLogic()->selectedDockerContainer, containerConfig, newContainerConfig); }, page_proto_openvpn, progressBar_proto_openvpn_reset, diff --git a/client/ui/pages_logic/protocols/OtherProtocolsLogic.cpp b/client/ui/pages_logic/protocols/OtherProtocolsLogic.cpp index 41ae2ec3..6b6ea53c 100644 --- a/client/ui/pages_logic/protocols/OtherProtocolsLogic.cpp +++ b/client/ui/pages_logic/protocols/OtherProtocolsLogic.cpp @@ -1,7 +1,15 @@ +#include +#include +#include +#include + #include "OtherProtocolsLogic.h" #include "core/servercontroller.h" #include #include "../../uilogic.h" +#include "utils.h" + +#include using namespace amnezia; using namespace PageEnumNS; @@ -12,11 +20,23 @@ OtherProtocolsLogic::OtherProtocolsLogic(UiLogic *logic, QObject *parent): } +OtherProtocolsLogic::~OtherProtocolsLogic() +{ + for (QProcess *p: m_sftpMpuntProcesses) { + if (p) Utils::signalCtrl(p->processId(), CTRL_C_EVENT); + if (p) p->kill(); + if (p) p->waitForFinished(); + if (p) delete p; + } +} + 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)); + set_labelTftpPortText(config.value(config_key::port).toString()); + + set_labelTorWebSiteAddressText(config.value(config_key::site).toString()); } //QJsonObject OtherProtocolsLogic::getProtocolConfigFromPage(QJsonObject oldConfig) @@ -24,7 +44,84 @@ void OtherProtocolsLogic::updateProtocolPage(const QJsonObject &config, DockerCo //} -void OtherProtocolsLogic::onPushButtonProtoShadowSocksSaveClicked() + +void OtherProtocolsLogic::onPushButtonSftpMountDriveClicked() +{ +#ifdef Q_OS_WINDOWS + QProcess drivesProc; + drivesProc.start("wmic logicaldisk get caption"); + drivesProc.waitForFinished(); + QString drives = drivesProc.readAll(); + qDebug() << drives; + + + QString letters = "CFGHIJKLMNOPQRSTUVWXYZ"; + QString letter; + for (int i = letters.size() - 1; i > 0; i--) { + letter = letters.at(i); + if (!drives.contains(letter + ":")) break; + } + if (letter == "C:") { + // set err info + qDebug() << "Can't find free drive letter"; + return; + } + + + set_pushButtonSftpMountEnabled(false); + QProcess *p = new QProcess; + m_sftpMpuntProcesses.append(p); + p->setProcessChannelMode(QProcess::MergedChannels); + + connect(p, &QProcess::readyRead, this, [this, p, letter](){ + QString s = p->readAll(); + if (s.contains("The service sshfs has been started")) { + QDesktopServices::openUrl(QUrl("file:///" + letter + ":")); + set_pushButtonSftpMountEnabled(true); + } + }); + +// QString cmd = QString("net use \\\\sshfs\\%1@51.77.32.168!%2 /USER:%1 %3") +// .arg(labelTftpUserNameText()) +// .arg(labelTftpPortText()) +// .arg(labelTftpPasswordText()); + + p->setProgram("C:\\Program Files1\\SSHFS-Win\\bin\\sshfs.exe"); + + QString host = m_settings.serverCredentials(uiLogic()->selectedServerIndex).hostName; + QString args = QString( + "%1@%2:/ %3: " + "-o port=%4 " + "-f " + "-o reconnect" + "-orellinks " + "-ofstypename=SSHFS " + "-o ssh_command=/usr/bin/ssh.exe " + "-oUserKnownHostsFile=/dev/null " + "-oStrictHostKeyChecking=no " + "-o password_stdin") + .arg(labelTftpUserNameText()) + .arg(host) + .arg(letter) + .arg(labelTftpPortText()); + + + p->setNativeArguments(args); + p->start(); + p->waitForStarted(50); + if (p->state() != QProcess::Running) { + qDebug() << "onPushButtonSftpMountDriveClicked process not started"; + } + else { + p->write((labelTftpPasswordText() + "\n").toUtf8()); + } + + //qDebug().noquote() << "onPushButtonSftpMountDriveClicked" << args; + +#endif +} + +void OtherProtocolsLogic::checkBoxSftpRestoreClicked() { } diff --git a/client/ui/pages_logic/protocols/OtherProtocolsLogic.h b/client/ui/pages_logic/protocols/OtherProtocolsLogic.h index a70bc698..0612b936 100644 --- a/client/ui/pages_logic/protocols/OtherProtocolsLogic.h +++ b/client/ui/pages_logic/protocols/OtherProtocolsLogic.h @@ -3,6 +3,8 @@ #include "PageProtocolLogicBase.h" +#include + class UiLogic; class OtherProtocolsLogic : public PageProtocolLogicBase @@ -12,13 +14,18 @@ class OtherProtocolsLogic : public PageProtocolLogicBase AUTO_PROPERTY(QString, labelTftpUserNameText) AUTO_PROPERTY(QString, labelTftpPasswordText) AUTO_PROPERTY(QString, labelTftpPortText) + AUTO_PROPERTY(bool, pushButtonSftpMountEnabled) + AUTO_PROPERTY(bool, checkBoxSftpRestoreChecked) + + AUTO_PROPERTY(QString, labelTorWebSiteAddressText) + public: - Q_INVOKABLE void onPushButtonProtoShadowSocksSaveClicked(); - + Q_INVOKABLE void onPushButtonSftpMountDriveClicked(); + Q_INVOKABLE void checkBoxSftpRestoreClicked(); public: explicit OtherProtocolsLogic(UiLogic *uiLogic, QObject *parent = nullptr); - ~OtherProtocolsLogic() = default; + ~OtherProtocolsLogic(); void updateProtocolPage(const QJsonObject &config, DockerContainer container, bool haveAuthData) override; //QJsonObject getProtocolConfigFromPage(QJsonObject oldConfig) override; @@ -27,5 +34,7 @@ private: Settings m_settings; UiLogic *m_uiLogic; + QList m_sftpMpuntProcesses; + }; #endif // OTHER_PROTOCOLS_LOGIC_H diff --git a/client/ui/pages_logic/protocols/ShadowSocksLogic.cpp b/client/ui/pages_logic/protocols/ShadowSocksLogic.cpp index f2e57660..c00d8ae9 100644 --- a/client/ui/pages_logic/protocols/ShadowSocksLogic.cpp +++ b/client/ui/pages_logic/protocols/ShadowSocksLogic.cpp @@ -82,7 +82,7 @@ void ShadowSocksLogic::onPushButtonProtoShadowSocksSaveClicked() return progressBarProtoShadowSocksResetMaximium(); }; - ErrorCode e = uiLogic()->doInstallAction([this, containerConfig, newContainerConfig](){ + ErrorCode e = uiLogic()->doInstallAction([this, containerConfig, &newContainerConfig](){ return ServerController::updateContainer(m_settings.serverCredentials(uiLogic()->selectedServerIndex), uiLogic()->selectedDockerContainer, containerConfig, newContainerConfig); }, page_proto_shadowsocks, progressBar_proto_shadowsocks_reset, diff --git a/client/ui/qml/Pages/PageServerContainers.qml b/client/ui/qml/Pages/PageServerContainers.qml index 8b02cb7c..c79d9351 100644 --- a/client/ui/qml/Pages/PageServerContainers.qml +++ b/client/ui/qml/Pages/PageServerContainers.qml @@ -43,7 +43,13 @@ PageBase { onContainerSelected: { var containerProto = ContainerProps.defaultProtocol(c_index) - tf_port_num.text = ProtocolProps.defaultPort(containerProto) + + if (ProtocolProps.defaultPort(containerProto) < 0) { + tf_port_num.enabled = false + tf_port_num.text = qsTr("Default") + } + else tf_port_num.text = ProtocolProps.defaultPort(containerProto) + cb_port_proto.currentIndex = ProtocolProps.defaultTransportProto(containerProto) tf_port_num.enabled = ProtocolProps.defaultPortChangeable(containerProto) diff --git a/client/ui/qml/Pages/Protocols/PageProtoOpenVPN.qml b/client/ui/qml/Pages/Protocols/PageProtoOpenVPN.qml index 1284594e..d40dda1c 100644 --- a/client/ui/qml/Pages/Protocols/PageProtoOpenVPN.qml +++ b/client/ui/qml/Pages/Protocols/PageProtoOpenVPN.qml @@ -19,294 +19,386 @@ PageProtocolBase { text: qsTr("OpenVPN Settings") } - Item { - enabled: logic.pageEnabled + Flickable { + id: fl + width: root.width anchors.top: caption.bottom + anchors.topMargin: 20 anchors.bottom: parent.bottom - width: parent.width + anchors.bottomMargin: 20 + anchors.left: root.left + anchors.leftMargin: 30 + anchors.right: root.right + anchors.rightMargin: 30 - LabelType { - id: lb_subnet - x: 30 + contentHeight: content.height + clip: true + + ColumnLayout { + id: content + enabled: logic.pageEnabled anchors.top: parent.top - width: parent.width - height: 21 - text: qsTr("VPN Addresses Subnet") - } - TextFieldType { - id: tf_subnet - x: 30 - anchors.top: lb_subnet.bottom - - width: parent.width - 60 - height: 31 - text: logic.lineEditProtoOpenVpnSubnetText - onEditingFinished: { - logic.lineEditProtoOpenVpnSubnetText = text - } - } - - // - 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 - anchors.top: lb_proto.bottom - width: parent.width - 60 - height: 71 - border.width: 1 - border.color: "lightgray" - radius: 2 - RadioButtonType { - x: 10 - y: 40 - width: 171 - height: 19 - text: qsTr("TCP") - enabled: logic.radioButtonProtoOpenVpnTcpEnabled - checked: logic.radioButtonProtoOpenVpnTcpChecked - onCheckedChanged: { - UiLogic.radioButtonProtoOpenVpnTcpChecked = checked - } - } - RadioButtonType { - x: 10 - y: 10 - width: 171 - height: 19 - text: qsTr("UDP") - checked: logic.radioButtonProtoOpenVpnUdpChecked - onCheckedChanged: { - logic.radioButtonProtoOpenVpnUdpChecked = checked - } - enabled: logic.radioButtonProtoOpenVpnUdpEnabled - } - } - - // - LabelType { - id: lb_port - anchors.top: rect_proto.bottom - anchors.topMargin: 20 - - x: 30 - width: root.width / 2 - 10 - height: 31 - text: qsTr("Port") - } - TextFieldType { - id: tf_port - anchors.top: rect_proto.bottom - anchors.topMargin: 20 - - anchors.left: parent.horizontalCenter + anchors.left: parent.left anchors.right: parent.right - anchors.rightMargin: 30 - height: 31 - text: logic.lineEditProtoOpenVpnPortText - onEditingFinished: { - logic.lineEditProtoOpenVpnPortText = text + + LabelType { + id: lb_subnet + height: 21 + text: qsTr("VPN Addresses Subnet") } - enabled: logic.lineEditProtoOpenVpnPortEnabled - } + TextFieldType { + id: tf_subnet - // - CheckBoxType { - id: check_auto_enc - anchors.top: lb_port.bottom - anchors.topMargin: 20 - x: 30 - width: parent.width - height: 21 - text: qsTr("Auto-negotiate encryption") - checked: logic.checkBoxProtoOpenVpnAutoEncryptionChecked - onCheckedChanged: { - logic.checkBoxProtoOpenVpnAutoEncryptionChecked = checked + implicitWidth: parent.width + height: 31 + text: logic.lineEditProtoOpenVpnSubnetText + onEditingFinished: { + logic.lineEditProtoOpenVpnSubnetText = text + } } - onClicked: { - logic.checkBoxProtoOpenVpnAutoEncryptionClicked() + + // + LabelType { + id: lb_proto + Layout.topMargin: 20 + height: 21 + text: qsTr("Network protocol") } - } - - - // - 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 + Rectangle { + id: rect_proto + implicitWidth: root.width - 60 + height: 71 + border.width: 1 + border.color: "lightgray" + radius: 2 + RadioButtonType { + x: 10 + y: 40 + width: 171 + height: 19 + text: qsTr("TCP") + enabled: logic.radioButtonProtoOpenVpnTcpEnabled + checked: logic.radioButtonProtoOpenVpnTcpChecked + onCheckedChanged: { + UiLogic.radioButtonProtoOpenVpnTcpChecked = checked } } - return -1 + RadioButtonType { + x: 10 + y: 10 + width: 171 + height: 19 + text: qsTr("UDP") + checked: logic.radioButtonProtoOpenVpnUdpChecked + onCheckedChanged: { + logic.radioButtonProtoOpenVpnUdpChecked = checked + } + enabled: logic.radioButtonProtoOpenVpnUdpEnabled + } } - onCurrentTextChanged: { - logic.comboBoxProtoOpenVpnCipherText = currentText + + // + RowLayout { + Layout.topMargin: 10 + Layout.fillWidth: true + LabelType { + id: lb_port + height: 31 + text: qsTr("Port") + Layout.preferredWidth: root.width / 2 - 10 + } + TextFieldType { + id: tf_port + Layout.fillWidth: true + + height: 31 + text: logic.lineEditProtoOpenVpnPortText + onEditingFinished: { + logic.lineEditProtoOpenVpnPortText = text + } + enabled: logic.lineEditProtoOpenVpnPortEnabled + } } - 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 + + // + CheckBoxType { + id: check_auto_enc + + implicitWidth: parent.width + height: 21 + text: qsTr("Auto-negotiate encryption") + checked: logic.checkBoxProtoOpenVpnAutoEncryptionChecked + onCheckedChanged: { + logic.checkBoxProtoOpenVpnAutoEncryptionChecked = checked + } + onClicked: { + logic.checkBoxProtoOpenVpnAutoEncryptionClicked() + } + } + + // + LabelType { + id: lb_cipher + height: 21 + text: qsTr("Cipher") + } + + ComboBoxType { + id: cb_cipher + implicitWidth: parent.width + + 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 + height: 21 + Layout.topMargin: 20 + text: qsTr("Hash") + } + ComboBoxType { + id: cb_hash + height: 31 + implicitWidth: parent.width + 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 + implicitWidth: parent.width + Layout.topMargin: 20 + height: 21 + text: qsTr("Enable TLS auth") + checked: logic.checkBoxProtoOpenVpnTlsAuthChecked + onCheckedChanged: { + logic.checkBoxProtoOpenVpnTlsAuthChecked = checked + } + + } + + CheckBoxType { + id: check_block_dns + implicitWidth: parent.width + height: 21 + text: qsTr("Block DNS requests outside of VPN") + checked: logic.checkBoxProtoOpenVpnBlockDnsChecked + onCheckedChanged: { + logic.checkBoxProtoOpenVpnBlockDnsChecked = checked + } + } + + + BasicButtonType { + id: pb_client_config + + implicitWidth: parent.width + height: 21 + text: qsTr("Additional client config commands →") + background: Item { + anchors.fill: parent + } + + contentItem: Text { + anchors.fill: parent + font.family: "Lato" + font.styleName: "normal" + font.pixelSize: 16 + color: "#15CDCB"; + text: pb_client_config.text + horizontalAlignment: Text.AlignLeft + verticalAlignment: Text.AlignVCenter + } + antialiasing: true + checkable: true + checked: StartPageLogic.pushButtonConnectKeyChecked + } + + Rectangle { + id: rect_client_conf + implicitWidth: root.width - 60 + height: 101 + border.width: 1 + border.color: "lightgray" + radius: 2 + visible: pb_client_config.checked + + ScrollView { + anchors.fill: parent + TextArea { + id: te_client_config + font.family: "Lato" + font.styleName: "normal" + font.pixelSize: 16 + color: "#181922" + } } - 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 - } - } + BasicButtonType { + id: pb_server_config - - - -// LabelType { -// id: label_proto_openvpn_info -// x: 30 -// y: 550 -// width: 321 -// height: 41 -// visible: logic.labelProtoOpenVpnInfoVisible -// text: logic.labelProtoOpenVpnInfoText -// } - - - ProgressBar { - id: progress_save - anchors.horizontalCenter: parent.horizontalCenter - y: 500 - width: 321 - height: 40 - from: 0 - to: logic.progressBarProtoOpenVpnResetMaximium - value: logic.progressBarProtoOpenVpnResetValue - visible: logic.progressBarProtoOpenVpnResetVisible - background: Rectangle { implicitWidth: parent.width - implicitHeight: parent.height - color: "#100A44" - radius: 4 - } - - contentItem: Item { - implicitWidth: parent.width - implicitHeight: parent.height - Rectangle { - width: progress_save.visualPosition * parent.width - height: parent.height - radius: 4 - color: Qt.rgba(255, 255, 255, 0.15); + height: 21 + text: qsTr("Additional client config commands →") + background: Item { + anchors.fill: parent } + + contentItem: Text { + anchors.fill: parent + font.family: "Lato" + font.styleName: "normal" + font.pixelSize: 16 + color: "#15CDCB"; + text: pb_client_config.text + horizontalAlignment: Text.AlignLeft + verticalAlignment: Text.AlignVCenter + } + antialiasing: true + checkable: true + checked: StartPageLogic.pushButtonConnectKeyChecked } - } - BlueButtonType { - id: pb_save - anchors.horizontalCenter: parent.horizontalCenter - anchors.bottom: parent.bottom - anchors.bottomMargin: 20 - x: 30 - width: parent.width - 60 - height: 40 - text: qsTr("Save and restart VPN") - visible: logic.pushButtonOpenvpnSaveVisible - onClicked: { - logic.onPushButtonProtoOpenVpnSaveClicked() + + Rectangle { + id: rect_server_conf + implicitWidth: root.width - 60 + height: 101 + border.width: 1 + border.color: "lightgray" + radius: 2 + visible: pb_server_config.checked + + ScrollView { + anchors.fill: parent + TextArea { + id: te_server_config + font.family: "Lato" + font.styleName: "normal" + font.pixelSize: 16 + color: "#181922" + + } + } + + } + + + + + LabelType { + id: label_proto_openvpn_info + + height: 41 + visible: logic.labelProtoOpenVpnInfoVisible + text: logic.labelProtoOpenVpnInfoText + } + + + + Rectangle { + id: it_save + implicitWidth: parent.width + Layout.topMargin: 20 + height: 40 + + BlueButtonType { + id: pb_save + z: 1 + height: 40 + text: qsTr("Save and restart VPN") + width: parent.width + visible: logic.pushButtonOpenvpnSaveVisible + onClicked: { + logic.onPushButtonProtoOpenVpnSaveClicked() + } + } + + ProgressBar { + id: progress_save + anchors.fill: pb_save + from: 0 + to: logic.progressBarProtoOpenVpnResetMaximium + value: logic.progressBarProtoOpenVpnResetValue + visible: logic.progressBarProtoOpenVpnResetVisible + background: Rectangle { + implicitWidth: parent.width + implicitHeight: parent.height + color: "#100A44" + radius: 4 + } + + contentItem: Item { + implicitWidth: parent.width + implicitHeight: parent.height + Rectangle { + width: progress_save.visualPosition * parent.width + height: parent.height + radius: 4 + color: Qt.rgba(255, 255, 255, 0.15); + } + } + } + + } + } + } + } diff --git a/client/ui/qml/Pages/Protocols/PageProtoSftp.qml b/client/ui/qml/Pages/Protocols/PageProtoSftp.qml index 16c5b472..04b60e26 100644 --- a/client/ui/qml/Pages/Protocols/PageProtoSftp.qml +++ b/client/ui/qml/Pages/Protocols/PageProtoSftp.qml @@ -37,7 +37,8 @@ PageProtocolBase { horizontalItemAlignment: Grid.AlignHCenter verticalItemAlignment: Grid.AlignVCenter topPadding: 5 - leftPadding: 10 + leftPadding: 30 + rightPadding: 30 spacing: 5 @@ -76,4 +77,61 @@ PageProtocolBase { } } + LabelType { + anchors.bottom: check_persist.top + anchors.bottomMargin: 10 + width: parent.width - 60 + x: 30 + font.pixelSize: 14 + textFormat: Text.RichText + + MouseArea { + anchors.fill: parent + cursorShape: parent.hoveredLink ? Qt.PointingHandCursor : Qt.ArrowCursor + acceptedButtons: Qt.NoButton + } + +// text: "In order to mount remote SFTP folder as local drive, perform following steps: +//- Install the latest version of WinFsp [https://github.com/billziss-gh/winfsp/releases/latest]. +//- Install the latest version of SSHFS-Win. Choose the x64 or x86 installer according to your computer's architecture [https://github.com/billziss-gh/sshfs-win/releases]" + onLinkActivated: Qt.openUrlExternally(link) + + text:"In order to mount remote SFTP folder as local drive, perform following steps: +
    +
  • Install the latest version of WinFsp.
  • +
  • Install the latest version of SSHFS-Win. Choose the x64 or x86 installer according to your computer's architecture.
  • +
" + } + + CheckBoxType { + id: check_persist + anchors.bottom: pb_mount.top + anchors.bottomMargin: 10 + x: 30 + width: parent.width + height: 21 + text: qsTr("Restore drive after restart") + checked: logic.checkBoxSftpRestoreChecked + onCheckedChanged: { + logic.checkBoxSftpRestoreChecked = checked + } + onClicked: { + logic.checkBoxSftpRestoreClicked() + } + } + + BlueButtonType { + id: pb_mount + enabled: logic.pushButtonSftpMountEnabled + anchors.horizontalCenter: parent.horizontalCenter + anchors.bottom: parent.bottom + anchors.bottomMargin: 20 + x: 30 + width: parent.width - 60 + height: 40 + text: qsTr("Mount drive") + onClicked: { + logic.onPushButtonSftpMountDriveClicked() + } + } } diff --git a/client/ui/qml/Pages/Protocols/PageProtoTorWebSite.qml b/client/ui/qml/Pages/Protocols/PageProtoTorWebSite.qml new file mode 100644 index 00000000..9959e5fa --- /dev/null +++ b/client/ui/qml/Pages/Protocols/PageProtoTorWebSite.qml @@ -0,0 +1,58 @@ +import QtQuick 2.12 +import QtQuick.Controls 2.12 +import ProtocolEnum 1.0 +import "../" +import "../../Controls" +import "../../Config" + +PageProtocolBase { + id: root + protocol: ProtocolEnum.TorWebSite + logic: UiLogic.protocolLogic(protocol) + + BackButton { + id: back + } + + Caption { + id: caption + text: qsTr("TOR Web site 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: 30 + rightPadding: 30 + spacing: 5 + + + LabelType { + width: 130 + text: qsTr("Web site onion address") + } + TextFieldType { + id: tf_site_address + width: parent.width - 130 - parent.spacing - parent.leftPadding * 2 + text: logic.labelTorWebSiteAddressText + readOnly: true + } + + } + } +} diff --git a/client/ui/uilogic.cpp b/client/ui/uilogic.cpp index 86719951..3e2276c3 100644 --- a/client/ui/uilogic.cpp +++ b/client/ui/uilogic.cpp @@ -100,6 +100,7 @@ UiLogic::UiLogic(QObject *parent) : m_protocolLogicMap.insert(Protocol::Dns, new OtherProtocolsLogic(this)); m_protocolLogicMap.insert(Protocol::Sftp, new OtherProtocolsLogic(this)); + m_protocolLogicMap.insert(Protocol::TorWebSite, new OtherProtocolsLogic(this)); } @@ -138,7 +139,7 @@ void UiLogic::initalizeUiLogic() selectedServerIndex = m_settings.defaultServerIndex(); //goToPage(Page::ServerContainers, true, false); //goToPage(Page::NewServerProtocols, true, false); - onGotoProtocolPage(Protocol::OpenVpn); + //onGotoProtocolPage(Protocol::OpenVpn); //ui->pushButton_general_settings_exit->hide(); @@ -399,7 +400,7 @@ QString UiLogic::containerDesc(int container) -void UiLogic::installServer(const QMap &containers) +void UiLogic::installServer(QMap &containers) { if (containers.isEmpty()) return; @@ -473,7 +474,7 @@ void UiLogic::installServer(const QMap &containers } bool UiLogic::installContainers(ServerCredentials credentials, - const QMap &containers, + QMap &containers, const PageFunc &page, const ProgressFunc &progress, const ButtonFunc &button, @@ -496,7 +497,7 @@ bool UiLogic::installContainers(ServerCredentials credentials, } int cnt = 0; - for (QMap::const_iterator i = containers.constBegin(); i != containers.constEnd(); i++, cnt++) { + for (QMap::iterator i = containers.begin(); i != containers.end(); i++, cnt++) { QTimer timer; connect(&timer, &QTimer::timeout, [progress](){ progress.setValueFunc(progress.getValueFunc() + 1); diff --git a/client/ui/uilogic.h b/client/ui/uilogic.h index 17edad40..320f7af1 100644 --- a/client/ui/uilogic.h +++ b/client/ui/uilogic.h @@ -35,6 +35,8 @@ class OpenVpnLogic; class ShadowSocksLogic; class CloakLogic; +class OtherProtocolsLogic; + class VpnConnection; @@ -78,6 +80,8 @@ public: friend class ShadowSocksLogic; friend class CloakLogic; + friend class OtherProtocolsLogic; + Q_INVOKABLE void initalizeUiLogic(); Q_INVOKABLE void onCloseWindow(); @@ -128,7 +132,9 @@ private: QString m_dialogConnectErrorText; private slots: - void installServer(const QMap &containers); + // containers - INOUT arg + void installServer(QMap &containers); + void setTrayState(VpnProtocol::ConnectionState state); private: @@ -153,7 +159,7 @@ private: }; bool installContainers(ServerCredentials credentials, - const QMap &containers, + QMap &containers, const PageFunc& page, const ProgressFunc& progress, const ButtonFunc& button, diff --git a/client/utils.cpp b/client/utils.cpp index d839ba25..046d582c 100644 --- a/client/utils.cpp +++ b/client/utils.cpp @@ -248,4 +248,5 @@ bool Utils::signalCtrl(DWORD dwProcessId, DWORD dwCtrlEvent) } return success; } + #endif diff --git a/deploy/build_windows.bat b/deploy/build_windows.bat index 5bb8a0ba..bd83e9dc 100644 --- a/deploy/build_windows.bat +++ b/deploy/build_windows.bat @@ -76,7 +76,7 @@ echo "Signing exe" cd %OUT_APP_DIR% signtool sign /v /sm /s My /n "Privacy Technologies OU" /fd sha256 /tr http://timestamp.comodoca.com/?td=sha256 /td sha256 *.exe -"%QT_BIN_DIR:"=%\windeployqt" --release --force --no-translations "%OUT_APP_DIR:"=%\%APP_FILENAME:"=%" +"%QT_BIN_DIR:"=%\windeployqt" --release --qmldir "%PROJECT_DIR:"=%\client" --force --no-translations "%OUT_APP_DIR:"=%\%APP_FILENAME:"=%" signtool sign /v /sm /s My /n "Privacy Technologies OU" /fd sha256 /tr http://timestamp.comodoca.com/?td=sha256 /td sha256 *.dll