370 lines
14 KiB
C++
370 lines
14 KiB
C++
#include <QApplication>
|
|
#include <QBuffer>
|
|
#include <QClipboard>
|
|
#include <QFileDialog>
|
|
#include <QTimer>
|
|
#include <QSaveFile>
|
|
#include <QStandardPaths>
|
|
|
|
#include "ShareConnectionLogic.h"
|
|
|
|
#include "configurators/cloak_configurator.h"
|
|
#include "configurators/vpn_configurator.h"
|
|
#include "configurators/openvpn_configurator.h"
|
|
#include "configurators/shadowsocks_configurator.h"
|
|
#include "configurators/ssh_configurator.h"
|
|
|
|
#include "defines.h"
|
|
#include <functional>
|
|
|
|
#include "../uilogic.h"
|
|
|
|
ShareConnectionLogic::ShareConnectionLogic(UiLogic *logic, QObject *parent):
|
|
PageLogicBase(logic, parent),
|
|
m_pageShareAmneziaVisible{true},
|
|
m_pageShareOpenvpnVisible{true},
|
|
m_pageShareShadowsocksVisible{true},
|
|
m_pageShareCloakVisible{true},
|
|
m_pageShareFullAccessVisible{true},
|
|
m_textEditShareOpenvpnCodeText{},
|
|
m_pushButtonShareOpenvpnCopyEnabled{false},
|
|
m_pushButtonShareOpenvpnSaveEnabled{false},
|
|
m_toolBoxShareConnectionCurrentIndex{-1},
|
|
m_pushButtonShareSsCopyEnabled{false},
|
|
m_lineEditShareSsStringText{},
|
|
m_labelShareSsQrCodeText{},
|
|
m_labelShareSsServerText{},
|
|
m_labelShareSsPortText{},
|
|
m_labelShareSsMethodText{},
|
|
m_labelShareSsPasswordText{},
|
|
m_plainTextEditShareCloakText{},
|
|
m_pushButtonShareCloakCopyEnabled{false},
|
|
m_textEditShareFullCodeText{},
|
|
m_textEditShareAmneziaCodeText{},
|
|
m_pushButtonShareFullCopyText{tr("Copy")},
|
|
m_pushButtonShareAmneziaCopyText{tr("Copy")},
|
|
m_pushButtonShareOpenvpnCopyText{tr("Copy")},
|
|
m_pushButtonShareSsCopyText{tr("Copy")},
|
|
m_pushButtonShareCloakCopyText{tr("Copy")},
|
|
m_pushButtonShareAmneziaGenerateEnabled{true},
|
|
m_pushButtonShareAmneziaCopyEnabled{true},
|
|
m_pushButtonShareAmneziaGenerateText{tr("Generate config")},
|
|
m_pushButtonShareOpenvpnGenerateEnabled{true},
|
|
m_pushButtonShareOpenvpnGenerateText{tr("Generate config")}
|
|
{
|
|
// TODO consider move to Component.onCompleted
|
|
updateSharingPage(uiLogic()->selectedServerIndex, m_settings.serverCredentials(uiLogic()->selectedServerIndex), uiLogic()->selectedDockerContainer);
|
|
}
|
|
|
|
|
|
void ShareConnectionLogic::onPushButtonShareFullCopyClicked()
|
|
{
|
|
QGuiApplication::clipboard()->setText(textEditShareFullCodeText());
|
|
set_pushButtonShareFullCopyText(tr("Copied"));
|
|
|
|
QTimer::singleShot(3000, this, [this]() {
|
|
set_pushButtonShareFullCopyText(tr("Copy"));
|
|
});
|
|
}
|
|
|
|
void ShareConnectionLogic::onPushButtonShareFullSaveClicked()
|
|
{
|
|
if (textEditShareFullCodeText().isEmpty()) return;
|
|
|
|
QString fileName = QFileDialog::getSaveFileName(nullptr, tr("Save AmneziaVPN config"),
|
|
QStandardPaths::writableLocation(QStandardPaths::DocumentsLocation), "*.amnezia");
|
|
QSaveFile save(fileName);
|
|
save.open(QIODevice::WriteOnly);
|
|
save.write(textEditShareFullCodeText().toUtf8());
|
|
save.commit();
|
|
}
|
|
|
|
void ShareConnectionLogic::onPushButtonShareAmneziaCopyClicked()
|
|
{
|
|
if (textEditShareAmneziaCodeText().isEmpty()) return;
|
|
|
|
QGuiApplication::clipboard()->setText(textEditShareAmneziaCodeText());
|
|
set_pushButtonShareAmneziaCopyText(tr("Copied"));
|
|
|
|
QTimer::singleShot(3000, this, [this]() {
|
|
set_pushButtonShareAmneziaCopyText(tr("Copy"));
|
|
});
|
|
}
|
|
|
|
void ShareConnectionLogic::onPushButtonShareAmneziaSaveClicked()
|
|
{
|
|
if (textEditShareAmneziaCodeText().isEmpty()) return;
|
|
|
|
QString fileName = QFileDialog::getSaveFileName(nullptr, tr("Save AmneziaVPN config"),
|
|
QStandardPaths::writableLocation(QStandardPaths::DocumentsLocation), "*.amnezia");
|
|
QSaveFile save(fileName);
|
|
save.open(QIODevice::WriteOnly);
|
|
save.write(textEditShareAmneziaCodeText().toUtf8());
|
|
save.commit();
|
|
}
|
|
|
|
void ShareConnectionLogic::onPushButtonShareOpenvpnCopyClicked()
|
|
{
|
|
QGuiApplication::clipboard()->setText(textEditShareOpenvpnCodeText());
|
|
set_pushButtonShareOpenvpnCopyText(tr("Copied"));
|
|
|
|
QTimer::singleShot(3000, this, [this]() {
|
|
set_pushButtonShareOpenvpnCopyText(tr("Copy"));
|
|
});
|
|
}
|
|
|
|
void ShareConnectionLogic::onPushButtonShareSsCopyClicked()
|
|
{
|
|
QGuiApplication::clipboard()->setText(lineEditShareSsStringText());
|
|
set_pushButtonShareSsCopyText(tr("Copied"));
|
|
|
|
QTimer::singleShot(3000, this, [this]() {
|
|
set_pushButtonShareSsCopyText(tr("Copy"));
|
|
});
|
|
}
|
|
|
|
void ShareConnectionLogic::onPushButtonShareCloakCopyClicked()
|
|
{
|
|
QGuiApplication::clipboard()->setText(plainTextEditShareCloakText());
|
|
set_pushButtonShareCloakCopyText(tr("Copied"));
|
|
|
|
QTimer::singleShot(3000, this, [this]() {
|
|
set_pushButtonShareCloakCopyText(tr("Copy"));
|
|
});
|
|
}
|
|
|
|
void ShareConnectionLogic::onPushButtonShareAmneziaGenerateClicked()
|
|
{
|
|
set_pushButtonShareAmneziaGenerateEnabled(false);
|
|
set_pushButtonShareAmneziaCopyEnabled(false);
|
|
set_pushButtonShareAmneziaGenerateText(tr("Generating..."));
|
|
qApp->processEvents();
|
|
|
|
ServerCredentials credentials = m_settings.serverCredentials(uiLogic()->selectedServerIndex);
|
|
QJsonObject containerConfig = m_settings.containerConfig(uiLogic()->selectedServerIndex, uiLogic()->selectedDockerContainer);
|
|
containerConfig.insert(config_key::container, containerToString(uiLogic()->selectedDockerContainer));
|
|
|
|
ErrorCode e = ErrorCode::NoError;
|
|
for (Protocol p: amnezia::protocolsForContainer(uiLogic()->selectedDockerContainer)) {
|
|
QJsonObject protoConfig = m_settings.protocolConfig(uiLogic()->selectedServerIndex, uiLogic()->selectedDockerContainer, p);
|
|
|
|
QString cfg = VpnConfigurator::genVpnProtocolConfig(credentials, uiLogic()->selectedDockerContainer, containerConfig, p, &e);
|
|
if (e) {
|
|
cfg = "Error generating config";
|
|
break;
|
|
}
|
|
protoConfig.insert(config_key::last_config, cfg);
|
|
|
|
containerConfig.insert(protoToString(p), protoConfig);
|
|
}
|
|
|
|
QByteArray ba;
|
|
if (!e) {
|
|
QJsonObject serverConfig = m_settings.server(uiLogic()->selectedServerIndex);
|
|
serverConfig.remove(config_key::userName);
|
|
serverConfig.remove(config_key::password);
|
|
serverConfig.remove(config_key::port);
|
|
serverConfig.insert(config_key::containers, QJsonArray {containerConfig});
|
|
serverConfig.insert(config_key::defaultContainer, containerToString(uiLogic()->selectedDockerContainer));
|
|
|
|
|
|
ba = QJsonDocument(serverConfig).toJson().toBase64(QByteArray::Base64UrlEncoding | QByteArray::OmitTrailingEquals);
|
|
set_textEditShareAmneziaCodeText(QString("vpn://%1").arg(QString(ba)));
|
|
}
|
|
else {
|
|
set_textEditShareAmneziaCodeText(tr("Error while generating connection profile"));
|
|
}
|
|
|
|
set_pushButtonShareAmneziaGenerateEnabled(true);
|
|
set_pushButtonShareAmneziaCopyEnabled(true);
|
|
set_pushButtonShareAmneziaGenerateText(tr("Generate config"));
|
|
}
|
|
|
|
void ShareConnectionLogic::onPushButtonShareOpenvpnGenerateClicked()
|
|
{
|
|
set_pushButtonShareOpenvpnGenerateEnabled(false);
|
|
set_pushButtonShareOpenvpnCopyEnabled(false);
|
|
set_pushButtonShareOpenvpnSaveEnabled(false);
|
|
set_pushButtonShareOpenvpnGenerateText(tr("Generating..."));
|
|
|
|
ServerCredentials credentials = m_settings.serverCredentials(uiLogic()->selectedServerIndex);
|
|
const QJsonObject &containerConfig = m_settings.containerConfig(uiLogic()->selectedServerIndex, uiLogic()->selectedDockerContainer);
|
|
|
|
ErrorCode e = ErrorCode::NoError;
|
|
QString cfg = OpenVpnConfigurator::genOpenVpnConfig(credentials, uiLogic()->selectedDockerContainer, containerConfig, &e);
|
|
cfg = OpenVpnConfigurator::processConfigWithExportSettings(cfg);
|
|
|
|
set_textEditShareOpenvpnCodeText(cfg);
|
|
|
|
set_pushButtonShareOpenvpnGenerateEnabled(true);
|
|
set_pushButtonShareOpenvpnCopyEnabled(true);
|
|
set_pushButtonShareOpenvpnSaveEnabled(true);
|
|
set_pushButtonShareOpenvpnGenerateText(tr("Generate config"));
|
|
}
|
|
|
|
void ShareConnectionLogic::onPushButtonShareOpenvpnSaveClicked()
|
|
{
|
|
QString fileName = QFileDialog::getSaveFileName(nullptr, tr("Save OpenVPN config"),
|
|
QStandardPaths::writableLocation(QStandardPaths::DocumentsLocation), "*.ovpn");
|
|
|
|
QSaveFile save(fileName);
|
|
save.open(QIODevice::WriteOnly);
|
|
save.write(textEditShareOpenvpnCodeText().toUtf8());
|
|
save.commit();
|
|
}
|
|
|
|
|
|
void ShareConnectionLogic::updateSharingPage(int serverIndex, const ServerCredentials &credentials,
|
|
DockerContainer container)
|
|
{
|
|
uiLogic()->selectedDockerContainer = container;
|
|
uiLogic()->selectedServerIndex = serverIndex;
|
|
|
|
//const QJsonObject &containerConfig = m_settings.containerConfig(serverIndex, container);
|
|
|
|
set_pageShareAmneziaVisible(false);
|
|
set_pageShareOpenvpnVisible(false);
|
|
set_pageShareShadowsocksVisible(false);
|
|
set_pageShareCloakVisible(false);
|
|
set_pageShareFullAccessVisible(false);
|
|
|
|
enum currentWidget {
|
|
full_access = 0,
|
|
share_amezia,
|
|
share_openvpn,
|
|
share_shadowshock,
|
|
share_cloak
|
|
};
|
|
|
|
if (container == DockerContainer::OpenVpn) {
|
|
set_pageShareAmneziaVisible(true);
|
|
set_pageShareOpenvpnVisible(true);
|
|
|
|
QString cfg = tr("Press Generate config");
|
|
set_textEditShareOpenvpnCodeText(cfg);
|
|
set_pushButtonShareOpenvpnCopyEnabled(false);
|
|
set_pushButtonShareOpenvpnSaveEnabled(false);
|
|
|
|
set_toolBoxShareConnectionCurrentIndex(share_openvpn);
|
|
}
|
|
|
|
if (container == DockerContainer::OpenVpnOverShadowSocks ||
|
|
container == DockerContainer::OpenVpnOverCloak) {
|
|
set_pageShareAmneziaVisible(true);
|
|
set_pageShareShadowsocksVisible(true);
|
|
|
|
QJsonObject protoConfig = m_settings.protocolConfig(serverIndex, container, Protocol::ShadowSocks);
|
|
QString cfg = protoConfig.value(config_key::last_config).toString();
|
|
|
|
if (cfg.isEmpty()) {
|
|
const QJsonObject &containerConfig = m_settings.containerConfig(serverIndex, container);
|
|
|
|
ErrorCode e = ErrorCode::NoError;
|
|
cfg = ShadowSocksConfigurator::genShadowSocksConfig(credentials, container, containerConfig, &e);
|
|
|
|
set_pushButtonShareSsCopyEnabled(true);
|
|
}
|
|
|
|
QJsonObject ssConfig = QJsonDocument::fromJson(cfg.toUtf8()).object();
|
|
|
|
QString ssString = QString("%1:%2@%3:%4")
|
|
.arg(ssConfig.value("method").toString())
|
|
.arg(ssConfig.value("password").toString())
|
|
.arg(ssConfig.value("server").toString())
|
|
.arg(ssConfig.value("server_port").toString());
|
|
|
|
ssString = "ss://" + ssString.toUtf8().toBase64();
|
|
set_lineEditShareSsStringText(ssString);
|
|
updateQRCodeImage(ssString, [this](const QString& labelText) ->void {
|
|
set_labelShareSsQrCodeText(labelText);
|
|
});
|
|
|
|
set_labelShareSsServerText(ssConfig.value("server").toString());
|
|
set_labelShareSsPortText(ssConfig.value("server_port").toString());
|
|
set_labelShareSsMethodText(ssConfig.value("method").toString());
|
|
set_labelShareSsPasswordText(ssConfig.value("password").toString());
|
|
|
|
set_toolBoxShareConnectionCurrentIndex(share_shadowshock);
|
|
}
|
|
|
|
if (container == DockerContainer::OpenVpnOverCloak) {
|
|
//ui->toolBox_share_connection->addItem(ui->page_share_amnezia, tr(" Share for Amnezia client"));
|
|
set_pageShareCloakVisible(true);
|
|
set_plainTextEditShareCloakText(QString(""));
|
|
|
|
QJsonObject protoConfig = m_settings.protocolConfig(serverIndex, container, Protocol::Cloak);
|
|
QString cfg = protoConfig.value(config_key::last_config).toString();
|
|
|
|
if (cfg.isEmpty()) {
|
|
const QJsonObject &containerConfig = m_settings.containerConfig(serverIndex, container);
|
|
|
|
ErrorCode e = ErrorCode::NoError;
|
|
cfg = CloakConfigurator::genCloakConfig(credentials, container, containerConfig, &e);
|
|
|
|
set_pushButtonShareCloakCopyEnabled(true);
|
|
}
|
|
|
|
QJsonObject cloakConfig = QJsonDocument::fromJson(cfg.toUtf8()).object();
|
|
cloakConfig.remove(config_key::transport_proto);
|
|
cloakConfig.insert("ProxyMethod", "shadowsocks");
|
|
|
|
set_plainTextEditShareCloakText(QJsonDocument(cloakConfig).toJson());
|
|
}
|
|
|
|
// Full access
|
|
if (container == DockerContainer::None) {
|
|
set_pageShareFullAccessVisible(true);
|
|
|
|
const QJsonObject &server = m_settings.server(uiLogic()->selectedServerIndex);
|
|
|
|
QByteArray ba = QJsonDocument(server).toJson().toBase64(QByteArray::Base64UrlEncoding | QByteArray::OmitTrailingEquals);
|
|
|
|
set_textEditShareFullCodeText(QString("vpn://%1").arg(QString(ba)));
|
|
set_toolBoxShareConnectionCurrentIndex(full_access);
|
|
}
|
|
|
|
//ui->toolBox_share_connection->addItem(ui->page_share_amnezia, tr(" Share for Amnezia client"));
|
|
|
|
// Amnezia sharing
|
|
// QJsonObject exportContainer;
|
|
// for (Protocol p: protocolsForContainer(container)) {
|
|
// QJsonObject protocolConfig = containerConfig.value(protoToString(p)).toObject();
|
|
// protocolConfig.remove(config_key::last_config);
|
|
// exportContainer.insert(protoToString(p), protocolConfig);
|
|
// }
|
|
// exportContainer.insert(config_key::container, containerToString(container));
|
|
|
|
// ui->textEdit_share_amnezia_code->setPlainText(QJsonDocument(exportContainer).toJson());
|
|
|
|
set_textEditShareAmneziaCodeText(tr(""));
|
|
}
|
|
|
|
|
|
void ShareConnectionLogic::updateQRCodeImage(const QString &text, const std::function<void(const QString&)>& set_labelFunc)
|
|
{
|
|
int levelIndex = 1;
|
|
int versionIndex = 0;
|
|
bool bExtent = true;
|
|
int maskIndex = -1;
|
|
|
|
m_qrEncode.EncodeData( levelIndex, versionIndex, bExtent, maskIndex, text.toUtf8().data() );
|
|
|
|
int qrImageSize = m_qrEncode.m_nSymbleSize;
|
|
|
|
int encodeImageSize = qrImageSize + ( QR_MARGIN * 2 );
|
|
QImage encodeImage( encodeImageSize, encodeImageSize, QImage::Format_Mono );
|
|
|
|
encodeImage.fill( 1 );
|
|
|
|
for ( int i = 0; i < qrImageSize; i++ )
|
|
for ( int j = 0; j < qrImageSize; j++ )
|
|
if ( m_qrEncode.m_byModuleData[i][j] )
|
|
encodeImage.setPixel( i + QR_MARGIN, j + QR_MARGIN, 0 );
|
|
|
|
QByteArray byteArray;
|
|
QBuffer buffer(&byteArray);
|
|
encodeImage.save(&buffer, "PNG"); // writes the image in PNG format inside the buffer
|
|
QString iconBase64 = QString::fromLatin1(byteArray.toBase64().data());
|
|
|
|
set_labelFunc(iconBase64);
|
|
}
|