website in tor network container improved

Sponsored by "Теплица социальных технологий", 2021
В рамках работы над задачами по хакатону 2021
This commit is contained in:
pokamest 2021-09-24 13:14:35 +03:00
parent 3bcc12869b
commit b244158b95
25 changed files with 676 additions and 295 deletions

View file

@ -4,6 +4,8 @@ TARGET = AmneziaVPN
TEMPLATE = app TEMPLATE = app
#CONFIG += console #CONFIG += console
CONFIG += qtquickcompiler
ios:CONFIG += static ios:CONFIG += static
DEFINES += QT_DEPRECATED_WARNINGS DEFINES += QT_DEPRECATED_WARNINGS

View file

@ -31,3 +31,24 @@ QString VpnConfigurator::genVpnProtocolConfig(const ServerCredentials &credentia
return ""; 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);
}
}

View file

@ -13,6 +13,10 @@ public:
static QString genVpnProtocolConfig(const ServerCredentials &credentials, DockerContainer container, static QString genVpnProtocolConfig(const ServerCredentials &credentials, DockerContainer container,
const QJsonObject &containerConfig, Protocol proto, ErrorCode *errorCode = nullptr); const QJsonObject &containerConfig, Protocol proto, ErrorCode *errorCode = nullptr);
static void updateContainerConfigAfterInstallation(DockerContainer container,
QJsonObject &containerConfig, const QString &stdOut);
}; };
#endif // VPN_CONFIGURATOR_H #endif // VPN_CONFIGURATOR_H

View file

@ -37,6 +37,9 @@ QVector<amnezia::Protocol> ContainerProps::protocolsForContainer(amnezia::Docker
case DockerContainer::Cloak: case DockerContainer::Cloak:
return { Protocol::OpenVpn, Protocol::ShadowSocks, Protocol::Cloak }; return { Protocol::OpenVpn, Protocol::ShadowSocks, Protocol::Cloak };
case DockerContainer::Dns:
return { };
default: default:
return { defaultProtocol(container) }; return { defaultProtocol(container) };
} }

View file

@ -19,6 +19,8 @@
#include "scripts_registry.h" #include "scripts_registry.h"
#include "utils.h" #include "utils.h"
#include <configurators/vpn_configurator.h>
using namespace QSsh; using namespace QSsh;
@ -361,7 +363,7 @@ ErrorCode ServerController::removeContainer(const ServerCredentials &credentials
genVarsForScript(credentials, container))); 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() << "ServerController::setupContainer" << ContainerProps::containerToString(container);
//qDebug().noquote() << QJsonDocument(config).toJson(); //qDebug().noquote() << QJsonDocument(config).toJson();
@ -397,7 +399,7 @@ ErrorCode ServerController::setupContainer(const ServerCredentials &credentials,
} }
ErrorCode ServerController::updateContainer(const ServerCredentials &credentials, DockerContainer container, 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); bool reinstallRequred = isReinstallContainerRequred(container, oldConfig, newConfig);
qDebug() << "ServerController::updateContainer for container" << container << "reinstall required is" << reinstallRequred; qDebug() << "ServerController::updateContainer for container" << container << "reinstall required is" << reinstallRequred;
@ -518,7 +520,7 @@ ErrorCode ServerController::buildContainerWorker(const ServerCredentials &creden
genVarsForScript(credentials, container, config))); 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; QString stdOut;
auto cbReadStdOut = [&](const QString &data, QSharedPointer<QSsh::SshRemoteProcess> proc) { auto cbReadStdOut = [&](const QString &data, QSharedPointer<QSsh::SshRemoteProcess> proc) {
@ -540,11 +542,25 @@ ErrorCode ServerController::runContainerWorker(const ServerCredentials &credenti
return e; 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<QSsh::SshRemoteProcess> proc) {
stdOut += data + "\n";
};
auto cbReadStdErr = [&](const QString &data, QSharedPointer<QSsh::SshRemoteProcess> proc) {
stdOut += data + "\n";
};
ErrorCode e = runScript(sshParams(credentials),
replaceVars(amnezia::scriptData(ProtocolScriptType::configure_container, container), 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) ErrorCode ServerController::startupContainerWorker(const ServerCredentials &credentials, DockerContainer container, const QJsonObject &config)
@ -620,6 +636,8 @@ ServerController::Vars ServerController::genVarsForScript(const ServerCredential
// Sftp vars // Sftp vars
vars.append({{"$SFTP_PORT", sftpConfig.value(config_key::port).toString(QString::number(ProtocolProps::defaultPort(Protocol::Sftp))) }}); 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); QString serverIp = Utils::getIPAddress(credentials.hostName);

View file

@ -28,9 +28,9 @@ public:
static ErrorCode removeAllContainers(const ServerCredentials &credentials); static ErrorCode removeAllContainers(const ServerCredentials &credentials);
static ErrorCode removeContainer(const ServerCredentials &credentials, DockerContainer container); 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, 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 // create initial config - generate passwords, etc
static QJsonObject createContainerInitialConfig(DockerContainer container, int port, TransportProto tp); static QJsonObject createContainerInitialConfig(DockerContainer container, int port, TransportProto tp);
@ -67,8 +67,8 @@ private:
static ErrorCode installDockerWorker(const ServerCredentials &credentials, DockerContainer container); static ErrorCode installDockerWorker(const ServerCredentials &credentials, DockerContainer container);
static ErrorCode prepareHostWorker(const ServerCredentials &credentials, DockerContainer container, const QJsonObject &config = QJsonObject()); 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 buildContainerWorker(const ServerCredentials &credentials, DockerContainer container, const QJsonObject &config = QJsonObject());
static ErrorCode runContainerWorker(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, const QJsonObject &config = QJsonObject()); static ErrorCode configureContainerWorker(const ServerCredentials &credentials, DockerContainer container, QJsonObject &config);
static ErrorCode startupContainerWorker(const ServerCredentials &credentials, DockerContainer container, const QJsonObject &config = QJsonObject()); static ErrorCode startupContainerWorker(const ServerCredentials &credentials, DockerContainer container, const QJsonObject &config = QJsonObject());
}; };

View file

@ -103,7 +103,7 @@ int ProtocolProps::defaultPort(Protocol p)
case Protocol::Cloak : return 443; case Protocol::Cloak : return 443;
case Protocol::ShadowSocks : return 6789; case Protocol::ShadowSocks : return 6789;
case Protocol::WireGuard : return 51820; case Protocol::WireGuard : return 51820;
case Protocol::TorWebSite : return 443; case Protocol::TorWebSite : return -1;
case Protocol::Dns : return 53; case Protocol::Dns : return 53;
case Protocol::FileShare : return 139; case Protocol::FileShare : return 139;
case Protocol::Sftp : return 222; case Protocol::Sftp : return 222;

View file

@ -121,5 +121,6 @@
<file>server_scripts/sftp/Dockerfile</file> <file>server_scripts/sftp/Dockerfile</file>
<file>server_scripts/sftp/run_container.sh</file> <file>server_scripts/sftp/run_container.sh</file>
<file>ui/qml/Pages/Protocols/PageProtoSftp.qml</file> <file>ui/qml/Pages/Protocols/PageProtoSftp.qml</file>
<file>ui/qml/Pages/Protocols/PageProtoTorWebSite.qml</file>
</qresource> </qresource>
</RCC> </RCC>

View file

@ -0,0 +1,2 @@
sleep 5
sudo docker exec -i amnezia-tor onions

View file

@ -1,3 +1,3 @@
# Run container # Run container
sudo docker run -d -p 80:80 --restart always --name amnezia-wp-tor tutum/wordpress sudo docker run -d -p 80:80 --restart always --name $CONTAINER_NAME tutum/wordpress
sudo docker run -d --link amnezia-wp-tor --name amnezia-tor goldy/tor-hidden-service sudo docker run -d --link $CONTAINER_NAME --name amnezia-tor goldy/tor-hidden-service

View file

@ -74,8 +74,8 @@ void ServerContainersLogic::onPushButtonContinueClicked(DockerContainer c, int p
emit uiLogic()->goToPage(Page::ServerConfiguringProgress); emit uiLogic()->goToPage(Page::ServerConfiguringProgress);
qApp->processEvents(); qApp->processEvents();
ErrorCode e = uiLogic()->serverConfiguringProgressLogic()->doInstallAction([this, c](){ ErrorCode e = uiLogic()->serverConfiguringProgressLogic()->doInstallAction([this, c, &config](){
return ServerController::setupContainer(m_settings.serverCredentials(uiLogic()->selectedServerIndex), c); return ServerController::setupContainer(m_settings.serverCredentials(uiLogic()->selectedServerIndex), c, config);
}); });
if (!e) { if (!e) {

View file

@ -51,7 +51,8 @@ QMap<DockerContainer, QJsonObject> WizardLogic::getInstallConfigsFromWizardPage(
void WizardLogic::onPushButtonVpnModeFinishClicked() void WizardLogic::onPushButtonVpnModeFinishClicked()
{ {
uiLogic()->installServer(getInstallConfigsFromWizardPage()); auto containers = getInstallConfigsFromWizardPage();
uiLogic()->installServer(containers);
if (checkBoxVpnModeChecked()) { if (checkBoxVpnModeChecked()) {
m_settings.setRouteMode(Settings::VpnOnlyForwardSites); m_settings.setRouteMode(Settings::VpnOnlyForwardSites);
} else { } else {
@ -61,5 +62,6 @@ void WizardLogic::onPushButtonVpnModeFinishClicked()
void WizardLogic::onPushButtonLowFinishClicked() void WizardLogic::onPushButtonLowFinishClicked()
{ {
uiLogic()->installServer(getInstallConfigsFromWizardPage()); auto containers = getInstallConfigsFromWizardPage();
uiLogic()->installServer(containers);
} }

View file

@ -88,7 +88,7 @@ void CloakLogic::onPushButtonProtoCloakSaveClicked()
return progressBarProtoCloakResetMaximium(); 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); return ServerController::updateContainer(m_settings.serverCredentials(uiLogic()->selectedServerIndex), uiLogic()->selectedDockerContainer, containerConfig, newContainerConfig);
}, },
page_proto_cloak, progressBar_proto_cloak_reset, page_proto_cloak, progressBar_proto_cloak_reset,

View file

@ -125,7 +125,7 @@ void OpenVpnLogic::onPushButtonProtoOpenVpnSaveClicked()
return progressBarProtoOpenVpnResetMaximium(); 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); return ServerController::updateContainer(m_settings.serverCredentials(uiLogic()->selectedServerIndex), uiLogic()->selectedDockerContainer, containerConfig, newContainerConfig);
}, },
page_proto_openvpn, progressBar_proto_openvpn_reset, page_proto_openvpn, progressBar_proto_openvpn_reset,

View file

@ -1,7 +1,15 @@
#include <QDesktopServices>
#include <QTimer>
#include <QProcess>
#include <QStorageInfo>
#include "OtherProtocolsLogic.h" #include "OtherProtocolsLogic.h"
#include "core/servercontroller.h" #include "core/servercontroller.h"
#include <functional> #include <functional>
#include "../../uilogic.h" #include "../../uilogic.h"
#include "utils.h"
#include <Windows.h>
using namespace amnezia; using namespace amnezia;
using namespace PageEnumNS; 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) void OtherProtocolsLogic::updateProtocolPage(const QJsonObject &config, DockerContainer container, bool haveAuthData)
{ {
set_labelTftpUserNameText(config.value(config_key::userName).toString()); set_labelTftpUserNameText(config.value(config_key::userName).toString());
set_labelTftpPasswordText(config.value(config_key::password).toString(protocols::sftp::defaultUserName)); 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) //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()
{ {
} }

View file

@ -3,6 +3,8 @@
#include "PageProtocolLogicBase.h" #include "PageProtocolLogicBase.h"
#include <QProcess>
class UiLogic; class UiLogic;
class OtherProtocolsLogic : public PageProtocolLogicBase class OtherProtocolsLogic : public PageProtocolLogicBase
@ -12,13 +14,18 @@ class OtherProtocolsLogic : public PageProtocolLogicBase
AUTO_PROPERTY(QString, labelTftpUserNameText) AUTO_PROPERTY(QString, labelTftpUserNameText)
AUTO_PROPERTY(QString, labelTftpPasswordText) AUTO_PROPERTY(QString, labelTftpPasswordText)
AUTO_PROPERTY(QString, labelTftpPortText) AUTO_PROPERTY(QString, labelTftpPortText)
AUTO_PROPERTY(bool, pushButtonSftpMountEnabled)
AUTO_PROPERTY(bool, checkBoxSftpRestoreChecked)
AUTO_PROPERTY(QString, labelTorWebSiteAddressText)
public: public:
Q_INVOKABLE void onPushButtonProtoShadowSocksSaveClicked(); Q_INVOKABLE void onPushButtonSftpMountDriveClicked();
Q_INVOKABLE void checkBoxSftpRestoreClicked();
public: public:
explicit OtherProtocolsLogic(UiLogic *uiLogic, QObject *parent = nullptr); explicit OtherProtocolsLogic(UiLogic *uiLogic, QObject *parent = nullptr);
~OtherProtocolsLogic() = default; ~OtherProtocolsLogic();
void updateProtocolPage(const QJsonObject &config, DockerContainer container, bool haveAuthData) override; void updateProtocolPage(const QJsonObject &config, DockerContainer container, bool haveAuthData) override;
//QJsonObject getProtocolConfigFromPage(QJsonObject oldConfig) override; //QJsonObject getProtocolConfigFromPage(QJsonObject oldConfig) override;
@ -27,5 +34,7 @@ private:
Settings m_settings; Settings m_settings;
UiLogic *m_uiLogic; UiLogic *m_uiLogic;
QList <QProcess *> m_sftpMpuntProcesses;
}; };
#endif // OTHER_PROTOCOLS_LOGIC_H #endif // OTHER_PROTOCOLS_LOGIC_H

View file

@ -82,7 +82,7 @@ void ShadowSocksLogic::onPushButtonProtoShadowSocksSaveClicked()
return progressBarProtoShadowSocksResetMaximium(); 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); return ServerController::updateContainer(m_settings.serverCredentials(uiLogic()->selectedServerIndex), uiLogic()->selectedDockerContainer, containerConfig, newContainerConfig);
}, },
page_proto_shadowsocks, progressBar_proto_shadowsocks_reset, page_proto_shadowsocks, progressBar_proto_shadowsocks_reset,

View file

@ -43,7 +43,13 @@ PageBase {
onContainerSelected: { onContainerSelected: {
var containerProto = ContainerProps.defaultProtocol(c_index) 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) cb_port_proto.currentIndex = ProtocolProps.defaultTransportProto(containerProto)
tf_port_num.enabled = ProtocolProps.defaultPortChangeable(containerProto) tf_port_num.enabled = ProtocolProps.defaultPortChangeable(containerProto)

View file

@ -19,26 +19,38 @@ PageProtocolBase {
text: qsTr("OpenVPN Settings") text: qsTr("OpenVPN Settings")
} }
Item { Flickable {
enabled: logic.pageEnabled id: fl
width: root.width
anchors.top: caption.bottom anchors.top: caption.bottom
anchors.topMargin: 20
anchors.bottom: parent.bottom anchors.bottom: parent.bottom
width: parent.width anchors.bottomMargin: 20
anchors.left: root.left
anchors.leftMargin: 30
anchors.right: root.right
anchors.rightMargin: 30
contentHeight: content.height
clip: true
ColumnLayout {
id: content
enabled: logic.pageEnabled
anchors.top: parent.top
anchors.left: parent.left
anchors.right: parent.right
LabelType { LabelType {
id: lb_subnet id: lb_subnet
x: 30
anchors.top: parent.top
width: parent.width
height: 21 height: 21
text: qsTr("VPN Addresses Subnet") text: qsTr("VPN Addresses Subnet")
} }
TextFieldType { TextFieldType {
id: tf_subnet id: tf_subnet
x: 30
anchors.top: lb_subnet.bottom
width: parent.width - 60 implicitWidth: parent.width
height: 31 height: 31
text: logic.lineEditProtoOpenVpnSubnetText text: logic.lineEditProtoOpenVpnSubnetText
onEditingFinished: { onEditingFinished: {
@ -49,17 +61,13 @@ PageProtocolBase {
// //
LabelType { LabelType {
id: lb_proto id: lb_proto
x: 30 Layout.topMargin: 20
anchors.top: tf_subnet.bottom
width: parent.width
height: 21 height: 21
text: qsTr("Network protocol") text: qsTr("Network protocol")
} }
Rectangle { Rectangle {
id: rect_proto id: rect_proto
x: 30 implicitWidth: root.width - 60
anchors.top: lb_proto.bottom
width: parent.width - 60
height: 71 height: 71
border.width: 1 border.width: 1
border.color: "lightgray" border.color: "lightgray"
@ -91,24 +99,18 @@ PageProtocolBase {
} }
// //
RowLayout {
Layout.topMargin: 10
Layout.fillWidth: true
LabelType { LabelType {
id: lb_port id: lb_port
anchors.top: rect_proto.bottom
anchors.topMargin: 20
x: 30
width: root.width / 2 - 10
height: 31 height: 31
text: qsTr("Port") text: qsTr("Port")
Layout.preferredWidth: root.width / 2 - 10
} }
TextFieldType { TextFieldType {
id: tf_port id: tf_port
anchors.top: rect_proto.bottom Layout.fillWidth: true
anchors.topMargin: 20
anchors.left: parent.horizontalCenter
anchors.right: parent.right
anchors.rightMargin: 30
height: 31 height: 31
text: logic.lineEditProtoOpenVpnPortText text: logic.lineEditProtoOpenVpnPortText
@ -117,14 +119,15 @@ PageProtocolBase {
} }
enabled: logic.lineEditProtoOpenVpnPortEnabled enabled: logic.lineEditProtoOpenVpnPortEnabled
} }
}
// //
CheckBoxType { CheckBoxType {
id: check_auto_enc id: check_auto_enc
anchors.top: lb_port.bottom
anchors.topMargin: 20 implicitWidth: parent.width
x: 30
width: parent.width
height: 21 height: 21
text: qsTr("Auto-negotiate encryption") text: qsTr("Auto-negotiate encryption")
checked: logic.checkBoxProtoOpenVpnAutoEncryptionChecked checked: logic.checkBoxProtoOpenVpnAutoEncryptionChecked
@ -136,23 +139,16 @@ PageProtocolBase {
} }
} }
// //
LabelType { LabelType {
id: lb_cipher id: lb_cipher
x: 30
anchors.top: check_auto_enc.bottom
anchors.topMargin: 20
width: parent.width
height: 21 height: 21
text: qsTr("Cipher") text: qsTr("Cipher")
} }
ComboBoxType { ComboBoxType {
id: cb_cipher id: cb_cipher
x: 30 implicitWidth: parent.width
anchors.top: lb_cipher.bottom
width: parent.width - 60
height: 31 height: 31
model: [ model: [
@ -184,19 +180,14 @@ PageProtocolBase {
// //
LabelType { LabelType {
id: lb_hash id: lb_hash
anchors.top: cb_cipher.bottom
anchors.topMargin: 20
width: parent.width
height: 21 height: 21
Layout.topMargin: 20
text: qsTr("Hash") text: qsTr("Hash")
} }
ComboBoxType { ComboBoxType {
id: cb_hash id: cb_hash
x: 30
height: 31 height: 31
anchors.top: lb_hash.bottom implicitWidth: parent.width
width: parent.width - 60
model: [ model: [
qsTr("SHA512"), qsTr("SHA512"),
qsTr("SHA384"), qsTr("SHA384"),
@ -225,10 +216,8 @@ PageProtocolBase {
CheckBoxType { CheckBoxType {
id: check_tls id: check_tls
x: 30 implicitWidth: parent.width
anchors.top: cb_hash.bottom Layout.topMargin: 20
anchors.topMargin: 20
width: parent.width
height: 21 height: 21
text: qsTr("Enable TLS auth") text: qsTr("Enable TLS auth")
checked: logic.checkBoxProtoOpenVpnTlsAuthChecked checked: logic.checkBoxProtoOpenVpnTlsAuthChecked
@ -240,10 +229,7 @@ PageProtocolBase {
CheckBoxType { CheckBoxType {
id: check_block_dns id: check_block_dns
x: 30 implicitWidth: parent.width
anchors.top: check_tls.bottom
anchors.topMargin: 20
width: parent.width
height: 21 height: 21
text: qsTr("Block DNS requests outside of VPN") text: qsTr("Block DNS requests outside of VPN")
checked: logic.checkBoxProtoOpenVpnBlockDnsChecked checked: logic.checkBoxProtoOpenVpnBlockDnsChecked
@ -253,25 +239,139 @@ PageProtocolBase {
} }
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"
}
}
// LabelType { }
// id: label_proto_openvpn_info
// x: 30
// y: 550
// width: 321
// height: 41
// visible: logic.labelProtoOpenVpnInfoVisible
// text: logic.labelProtoOpenVpnInfoText
// }
BasicButtonType {
id: pb_server_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_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 { ProgressBar {
id: progress_save id: progress_save
anchors.horizontalCenter: parent.horizontalCenter anchors.fill: pb_save
y: 500
width: 321
height: 40
from: 0 from: 0
to: logic.progressBarProtoOpenVpnResetMaximium to: logic.progressBarProtoOpenVpnResetMaximium
value: logic.progressBarProtoOpenVpnResetValue value: logic.progressBarProtoOpenVpnResetValue
@ -294,19 +394,11 @@ PageProtocolBase {
} }
} }
} }
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()
} }
} }
} }
} }

View file

@ -37,7 +37,8 @@ PageProtocolBase {
horizontalItemAlignment: Grid.AlignHCenter horizontalItemAlignment: Grid.AlignHCenter
verticalItemAlignment: Grid.AlignVCenter verticalItemAlignment: Grid.AlignVCenter
topPadding: 5 topPadding: 5
leftPadding: 10 leftPadding: 30
rightPadding: 30
spacing: 5 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:
<ul>
<li>Install the latest version of <a href=\"https://github.com/billziss-gh/winfsp/releases/latest\">WinFsp</a>.</li>
<li>Install the latest version of <a href=\"https://github.com/billziss-gh/sshfs-win/releases\">SSHFS-Win</a>. Choose the x64 or x86 installer according to your computer's architecture.</li>
</ul>"
}
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()
}
}
} }

View file

@ -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
}
}
}
}

View file

@ -100,6 +100,7 @@ UiLogic::UiLogic(QObject *parent) :
m_protocolLogicMap.insert(Protocol::Dns, new OtherProtocolsLogic(this)); m_protocolLogicMap.insert(Protocol::Dns, new OtherProtocolsLogic(this));
m_protocolLogicMap.insert(Protocol::Sftp, 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(); selectedServerIndex = m_settings.defaultServerIndex();
//goToPage(Page::ServerContainers, true, false); //goToPage(Page::ServerContainers, true, false);
//goToPage(Page::NewServerProtocols, true, false); //goToPage(Page::NewServerProtocols, true, false);
onGotoProtocolPage(Protocol::OpenVpn); //onGotoProtocolPage(Protocol::OpenVpn);
//ui->pushButton_general_settings_exit->hide(); //ui->pushButton_general_settings_exit->hide();
@ -399,7 +400,7 @@ QString UiLogic::containerDesc(int container)
void UiLogic::installServer(const QMap<DockerContainer, QJsonObject> &containers) void UiLogic::installServer(QMap<DockerContainer, QJsonObject> &containers)
{ {
if (containers.isEmpty()) return; if (containers.isEmpty()) return;
@ -473,7 +474,7 @@ void UiLogic::installServer(const QMap<DockerContainer, QJsonObject> &containers
} }
bool UiLogic::installContainers(ServerCredentials credentials, bool UiLogic::installContainers(ServerCredentials credentials,
const QMap<DockerContainer, QJsonObject> &containers, QMap<DockerContainer, QJsonObject> &containers,
const PageFunc &page, const PageFunc &page,
const ProgressFunc &progress, const ProgressFunc &progress,
const ButtonFunc &button, const ButtonFunc &button,
@ -496,7 +497,7 @@ bool UiLogic::installContainers(ServerCredentials credentials,
} }
int cnt = 0; int cnt = 0;
for (QMap<DockerContainer, QJsonObject>::const_iterator i = containers.constBegin(); i != containers.constEnd(); i++, cnt++) { for (QMap<DockerContainer, QJsonObject>::iterator i = containers.begin(); i != containers.end(); i++, cnt++) {
QTimer timer; QTimer timer;
connect(&timer, &QTimer::timeout, [progress](){ connect(&timer, &QTimer::timeout, [progress](){
progress.setValueFunc(progress.getValueFunc() + 1); progress.setValueFunc(progress.getValueFunc() + 1);

View file

@ -35,6 +35,8 @@ class OpenVpnLogic;
class ShadowSocksLogic; class ShadowSocksLogic;
class CloakLogic; class CloakLogic;
class OtherProtocolsLogic;
class VpnConnection; class VpnConnection;
@ -78,6 +80,8 @@ public:
friend class ShadowSocksLogic; friend class ShadowSocksLogic;
friend class CloakLogic; friend class CloakLogic;
friend class OtherProtocolsLogic;
Q_INVOKABLE void initalizeUiLogic(); Q_INVOKABLE void initalizeUiLogic();
Q_INVOKABLE void onCloseWindow(); Q_INVOKABLE void onCloseWindow();
@ -128,7 +132,9 @@ private:
QString m_dialogConnectErrorText; QString m_dialogConnectErrorText;
private slots: private slots:
void installServer(const QMap<DockerContainer, QJsonObject> &containers); // containers - INOUT arg
void installServer(QMap<DockerContainer, QJsonObject> &containers);
void setTrayState(VpnProtocol::ConnectionState state); void setTrayState(VpnProtocol::ConnectionState state);
private: private:
@ -153,7 +159,7 @@ private:
}; };
bool installContainers(ServerCredentials credentials, bool installContainers(ServerCredentials credentials,
const QMap<DockerContainer, QJsonObject> &containers, QMap<DockerContainer, QJsonObject> &containers,
const PageFunc& page, const PageFunc& page,
const ProgressFunc& progress, const ProgressFunc& progress,
const ButtonFunc& button, const ButtonFunc& button,

View file

@ -248,4 +248,5 @@ bool Utils::signalCtrl(DWORD dwProcessId, DWORD dwCtrlEvent)
} }
return success; return success;
} }
#endif #endif

View file

@ -76,7 +76,7 @@ echo "Signing exe"
cd %OUT_APP_DIR% 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 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 signtool sign /v /sm /s My /n "Privacy Technologies OU" /fd sha256 /tr http://timestamp.comodoca.com/?td=sha256 /td sha256 *.dll