Custom sites reimplemented
This commit is contained in:
parent
97e918ae72
commit
6c74f30d79
23 changed files with 833 additions and 312 deletions
|
|
@ -34,6 +34,7 @@ HEADERS += \
|
||||||
ui/mainwindow.h \
|
ui/mainwindow.h \
|
||||||
ui/qautostart.h \
|
ui/qautostart.h \
|
||||||
ui/server_widget.h \
|
ui/server_widget.h \
|
||||||
|
ui/sites_model.h \
|
||||||
utils.h \
|
utils.h \
|
||||||
vpnconnection.h \
|
vpnconnection.h \
|
||||||
protocols/vpnprotocol.h \
|
protocols/vpnprotocol.h \
|
||||||
|
|
@ -60,6 +61,7 @@ SOURCES += \
|
||||||
ui/mainwindow.cpp \
|
ui/mainwindow.cpp \
|
||||||
ui/qautostart.cpp \
|
ui/qautostart.cpp \
|
||||||
ui/server_widget.cpp \
|
ui/server_widget.cpp \
|
||||||
|
ui/sites_model.cpp \
|
||||||
utils.cpp \
|
utils.cpp \
|
||||||
vpnconnection.cpp \
|
vpnconnection.cpp \
|
||||||
protocols/vpnprotocol.cpp \
|
protocols/vpnprotocol.cpp \
|
||||||
|
|
|
||||||
|
|
@ -226,7 +226,7 @@ QString OpenVpnConfigurator::processConfigWithLocalSettings(QString config)
|
||||||
config.replace("$PRIMARY_DNS", m_settings().primaryDns());
|
config.replace("$PRIMARY_DNS", m_settings().primaryDns());
|
||||||
config.replace("$SECONDARY_DNS", m_settings().secondaryDns());
|
config.replace("$SECONDARY_DNS", m_settings().secondaryDns());
|
||||||
|
|
||||||
if (m_settings().customRouting()) {
|
if (m_settings().routeMode() == Settings::VpnOnlyForwardSites) {
|
||||||
config.replace("redirect-gateway def1 bypass-dhcp", "");
|
config.replace("redirect-gateway def1 bypass-dhcp", "");
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
|
|
|
||||||
BIN
client/images/folder.png
Normal file
BIN
client/images/folder.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 150 B |
|
|
@ -61,5 +61,6 @@
|
||||||
<file>server_scripts/openvpn_shadowsocks/run_container.sh</file>
|
<file>server_scripts/openvpn_shadowsocks/run_container.sh</file>
|
||||||
<file>server_scripts/openvpn_shadowsocks/start.sh</file>
|
<file>server_scripts/openvpn_shadowsocks/start.sh</file>
|
||||||
<file>server_scripts/openvpn_shadowsocks/template.ovpn</file>
|
<file>server_scripts/openvpn_shadowsocks/template.ovpn</file>
|
||||||
|
<file>images/folder.png</file>
|
||||||
</qresource>
|
</qresource>
|
||||||
</RCC>
|
</RCC>
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,6 @@
|
||||||
#include "defines.h"
|
#include "defines.h"
|
||||||
#include "settings.h"
|
#include "settings.h"
|
||||||
|
#include "utils.h"
|
||||||
|
|
||||||
#include <QDebug>
|
#include <QDebug>
|
||||||
#include "protocols/protocols_defs.h"
|
#include "protocols/protocols_defs.h"
|
||||||
|
|
@ -205,6 +206,127 @@ QString Settings::nextAvailableServerName() const
|
||||||
return tr("Server") + " " + QString::number(i);
|
return tr("Server") + " " + QString::number(i);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
QString Settings::routeModeString(RouteMode mode) const
|
||||||
|
{
|
||||||
|
switch (mode) {
|
||||||
|
case VpnAllSites:
|
||||||
|
return "AllSites";
|
||||||
|
case VpnOnlyForwardSites:
|
||||||
|
return "ForwardSites";
|
||||||
|
case VpnAllExceptSites:
|
||||||
|
return "ExceptSites";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void Settings::addVpnSite(RouteMode mode, const QString &site, const QString &ip)
|
||||||
|
{
|
||||||
|
QVariantMap sites = vpnSites(mode);
|
||||||
|
if (sites.contains(site) && ip.isEmpty()) return;
|
||||||
|
|
||||||
|
sites.insert(site, ip);
|
||||||
|
setVpnSites(mode, sites);
|
||||||
|
|
||||||
|
// QStringList l = sites.value(site).toStringList();
|
||||||
|
// if (!l.contains(ip)) {
|
||||||
|
// if (!ip.isEmpty()) l.append(ip);
|
||||||
|
// //l.append(ip);
|
||||||
|
// sites.insert(site, l);
|
||||||
|
// setVpnSites(mode, sites);
|
||||||
|
// qDebug() << "sites after" << vpnSites(mode);
|
||||||
|
// }
|
||||||
|
}
|
||||||
|
|
||||||
|
QStringList Settings::getVpnIps(RouteMode mode) const
|
||||||
|
{
|
||||||
|
QStringList ips;
|
||||||
|
const QVariantMap &m = vpnSites(mode);
|
||||||
|
for (auto i = m.constBegin(); i != m.constEnd(); ++i) {
|
||||||
|
if (Utils::checkIPFormat(i.key())) {
|
||||||
|
ips.append(i.key());
|
||||||
|
}
|
||||||
|
else if (Utils::checkIPFormat(i.value().toString())) {
|
||||||
|
ips.append(i.value().toString());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
ips.removeDuplicates();
|
||||||
|
return ips;
|
||||||
|
}
|
||||||
|
|
||||||
|
void Settings::removeVpnSite(RouteMode mode, const QString &site)
|
||||||
|
{
|
||||||
|
QVariantMap sites = vpnSites(mode);
|
||||||
|
if (!sites.contains(site)) return;
|
||||||
|
|
||||||
|
sites.remove(site);
|
||||||
|
setVpnSites(mode, sites);
|
||||||
|
}
|
||||||
|
|
||||||
|
void Settings::addVpnIps(RouteMode mode, const QStringList &ips)
|
||||||
|
{
|
||||||
|
QVariantMap sites = vpnSites(mode);
|
||||||
|
for (const QString &ip : ips) {
|
||||||
|
if (ip.isEmpty()) continue;
|
||||||
|
|
||||||
|
sites.insert(ip, "");
|
||||||
|
}
|
||||||
|
|
||||||
|
setVpnSites(mode, sites);
|
||||||
|
}
|
||||||
|
|
||||||
|
void Settings::removeVpnSites(RouteMode mode, const QStringList &sites)
|
||||||
|
{
|
||||||
|
QVariantMap sitesMap = vpnSites(mode);
|
||||||
|
for (const QString &site : sites) {
|
||||||
|
if (site.isEmpty()) continue;
|
||||||
|
|
||||||
|
sitesMap.remove(site);
|
||||||
|
}
|
||||||
|
|
||||||
|
setVpnSites(mode, sitesMap);
|
||||||
|
}
|
||||||
|
|
||||||
|
//void Settings::addVpnForwardSite(const QString &site, const QString &ip)
|
||||||
|
//{
|
||||||
|
// auto sites = vpnForwardSites();
|
||||||
|
// QStringList l = sites.value(site).toStringList();
|
||||||
|
// if (!l.contains(ip)) {
|
||||||
|
// l.append(ip);
|
||||||
|
// setVpnForwardSites(sites);
|
||||||
|
// }
|
||||||
|
//}
|
||||||
|
|
||||||
|
//QStringList Settings::getVpnForwardIps() const
|
||||||
|
//{
|
||||||
|
// QStringList ips;
|
||||||
|
// const QVariantMap &m = vpnForwardSites();
|
||||||
|
// for (const QVariant &v : m) {
|
||||||
|
// ips.append(v.toStringList());
|
||||||
|
// }
|
||||||
|
// ips.removeDuplicates();
|
||||||
|
// return ips;
|
||||||
|
//}
|
||||||
|
|
||||||
|
//void Settings::addVpnExceptSite(const QString &site, const QString &ip)
|
||||||
|
//{
|
||||||
|
// auto sites = vpnExceptSites();
|
||||||
|
// QStringList l = sites.value(site).toStringList();
|
||||||
|
// if (!l.contains(ip)) {
|
||||||
|
// l.append(ip);
|
||||||
|
// setVpnExceptSites(sites);
|
||||||
|
// }
|
||||||
|
//}
|
||||||
|
|
||||||
|
//QStringList Settings::getVpnExceptIps() const
|
||||||
|
//{
|
||||||
|
// QStringList ips;
|
||||||
|
// const QVariantMap &m = vpnExceptSites();
|
||||||
|
// for (const QVariant &v : m) {
|
||||||
|
// ips.append(v.toStringList());
|
||||||
|
// }
|
||||||
|
// ips.removeDuplicates();
|
||||||
|
// return ips;
|
||||||
|
//}
|
||||||
|
|
||||||
QString Settings::primaryDns() const { return m_settings.value("Conf/primaryDns", cloudFlareNs1).toString(); }
|
QString Settings::primaryDns() const { return m_settings.value("Conf/primaryDns", cloudFlareNs1).toString(); }
|
||||||
|
|
||||||
QString Settings::secondaryDns() const { return m_settings.value("Conf/secondaryDns", cloudFlareNs2).toString(); }
|
QString Settings::secondaryDns() const { return m_settings.value("Conf/secondaryDns", cloudFlareNs2).toString(); }
|
||||||
|
|
|
||||||
|
|
@ -67,16 +67,48 @@ public:
|
||||||
bool isStartMinimized() const { return m_settings.value("Conf/startMinimized", false).toBool(); }
|
bool isStartMinimized() const { return m_settings.value("Conf/startMinimized", false).toBool(); }
|
||||||
void setStartMinimized(bool enabled) { m_settings.setValue("Conf/startMinimized", enabled); }
|
void setStartMinimized(bool enabled) { m_settings.setValue("Conf/startMinimized", enabled); }
|
||||||
|
|
||||||
bool customRouting() const { return m_settings.value("Conf/customRouting", false).toBool(); }
|
enum RouteMode {
|
||||||
void setCustomRouting(bool customRouting) { m_settings.setValue("Conf/customRouting", customRouting); }
|
VpnAllSites,
|
||||||
|
VpnOnlyForwardSites,
|
||||||
|
VpnAllExceptSites
|
||||||
|
};
|
||||||
|
Q_ENUM (RouteMode)
|
||||||
|
|
||||||
// list of sites to pass blocking added by user
|
QString routeModeString(RouteMode mode) const;
|
||||||
QStringList customSites() { return m_settings.value("Conf/customSites").toStringList(); }
|
|
||||||
void setCustomSites(const QStringList &customSites) { m_settings.setValue("Conf/customSites", customSites); }
|
|
||||||
|
|
||||||
// list of ips to pass blocking generated from customSites
|
RouteMode routeMode() const { return static_cast<RouteMode>(m_settings.value("Conf/routeMode", 0).toInt()); }
|
||||||
QStringList customIps() { return m_settings.value("Conf/customIps").toStringList(); }
|
void setRouteMode(RouteMode mode) { m_settings.setValue("Conf/routeMode", mode); }
|
||||||
void setCustomIps(const QStringList &customIps) { m_settings.setValue("Conf/customIps", customIps); }
|
// bool customRouting() const { return m_settings.value("Conf/customRouting", false).toBool(); }
|
||||||
|
// void setCustomRouting(bool customRouting) { m_settings.setValue("Conf/customRouting", customRouting); }
|
||||||
|
|
||||||
|
// // list of sites to pass blocking added by user
|
||||||
|
// QStringList customSites() { return m_settings.value("Conf/customSites").toStringList(); }
|
||||||
|
// void setCustomSites(const QStringList &customSites) { m_settings.setValue("Conf/customSites", customSites); }
|
||||||
|
|
||||||
|
// // list of ips to pass blocking generated from customSites
|
||||||
|
// QStringList customIps() { return m_settings.value("Conf/customIps").toStringList(); }
|
||||||
|
// void setCustomIps(const QStringList &customIps) { m_settings.setValue("Conf/customIps", customIps); }
|
||||||
|
|
||||||
|
|
||||||
|
QVariantMap vpnSites(RouteMode mode) const { return m_settings.value("Conf/" + routeModeString(mode)).toMap(); }
|
||||||
|
void setVpnSites(RouteMode mode, const QVariantMap &sites) { m_settings.setValue("Conf/"+ routeModeString(mode), sites); m_settings.sync(); }
|
||||||
|
void addVpnSite(RouteMode mode, const QString &site, const QString &ip= "");
|
||||||
|
QStringList getVpnIps(RouteMode mode) const;
|
||||||
|
void removeVpnSite(RouteMode mode, const QString &site);
|
||||||
|
|
||||||
|
void addVpnIps(RouteMode mode, const QStringList &ip);
|
||||||
|
void removeVpnSites(RouteMode mode, const QStringList &sites);
|
||||||
|
|
||||||
|
|
||||||
|
// QVariantMap vpnForwardSites() const { return m_settings.value("Conf/vpnForwardSites").toMap(); }
|
||||||
|
// void setVpnForwardSites(const QVariantMap &sites) { m_settings.setValue("Conf/vpnForwardSites", sites); }
|
||||||
|
// void addVpnForwardSite(const QString &site, const QString &ip);
|
||||||
|
// QStringList getVpnForwardIps() const;
|
||||||
|
|
||||||
|
// QVariantMap vpnExceptSites() const { return m_settings.value("Conf/vpnExceptSites").toMap(); }
|
||||||
|
// void setVpnExceptSites(const QVariantMap &sites) { m_settings.setValue("Conf/vpnExceptSites", sites); }
|
||||||
|
// void addVpnExceptSite(const QString &site, const QString &ip);
|
||||||
|
// QStringList getVpnExceptIps() const;
|
||||||
|
|
||||||
QString primaryDns() const;
|
QString primaryDns() const;
|
||||||
QString secondaryDns() const;
|
QString secondaryDns() const;
|
||||||
|
|
|
||||||
|
|
@ -4,6 +4,8 @@
|
||||||
#include <QDesktopServices>
|
#include <QDesktopServices>
|
||||||
#include <QFileDialog>
|
#include <QFileDialog>
|
||||||
#include <QHBoxLayout>
|
#include <QHBoxLayout>
|
||||||
|
#include <QHostInfo>
|
||||||
|
#include <QItemSelectionModel>
|
||||||
#include <QJsonDocument>
|
#include <QJsonDocument>
|
||||||
#include <QJsonObject>
|
#include <QJsonObject>
|
||||||
#include <QKeyEvent>
|
#include <QKeyEvent>
|
||||||
|
|
@ -59,6 +61,8 @@ MainWindow::MainWindow(QWidget *parent) :
|
||||||
setupUiConnections();
|
setupUiConnections();
|
||||||
setupNewServerConnections();
|
setupNewServerConnections();
|
||||||
setupWizardConnections();
|
setupWizardConnections();
|
||||||
|
setupVpnPageConnections();
|
||||||
|
setupSitesPageConnections();
|
||||||
setupGeneralSettingsConnections();
|
setupGeneralSettingsConnections();
|
||||||
setupAppSettingsConnections();
|
setupAppSettingsConnections();
|
||||||
setupNetworkSettingsConnections();
|
setupNetworkSettingsConnections();
|
||||||
|
|
@ -74,6 +78,11 @@ MainWindow::MainWindow(QWidget *parent) :
|
||||||
ui->stackedWidget_main->setSpeed(200);
|
ui->stackedWidget_main->setSpeed(200);
|
||||||
ui->stackedWidget_main->setAnimation(QEasingCurve::Linear);
|
ui->stackedWidget_main->setAnimation(QEasingCurve::Linear);
|
||||||
|
|
||||||
|
|
||||||
|
ui->tableView_sites->horizontalHeader()->setSectionResizeMode(QHeaderView::Stretch);
|
||||||
|
// ui->tableView_sites->setColumnWidth(0, 450);
|
||||||
|
// ui->tableView_sites->setColumnWidth(1, 120);
|
||||||
|
|
||||||
if (QOperatingSystemVersion::current() <= QOperatingSystemVersion::Windows7) {
|
if (QOperatingSystemVersion::current() <= QOperatingSystemVersion::Windows7) {
|
||||||
needToHideCustomTitlebar = true;
|
needToHideCustomTitlebar = true;
|
||||||
}
|
}
|
||||||
|
|
@ -96,10 +105,6 @@ MainWindow::MainWindow(QWidget *parent) :
|
||||||
goToPage(Page::Vpn, true, false);
|
goToPage(Page::Vpn, true, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
connect(ui->lineEdit_sites_add_custom, &QLineEdit::returnPressed, [&](){
|
|
||||||
ui->pushButton_sites_add_custom->click();
|
|
||||||
});
|
|
||||||
|
|
||||||
//ui->pushButton_general_settings_exit->hide();
|
//ui->pushButton_general_settings_exit->hide();
|
||||||
updateSharingPage(selectedServerIndex, m_settings.serverCredentials(selectedServerIndex), selectedDockerContainer);
|
updateSharingPage(selectedServerIndex, m_settings.serverCredentials(selectedServerIndex), selectedDockerContainer);
|
||||||
|
|
||||||
|
|
@ -143,6 +148,10 @@ MainWindow::MainWindow(QWidget *parent) :
|
||||||
|
|
||||||
//ui->toolBox_share_connection->removeItem(ui->toolBox_share_connection->indexOf(ui->page_share_shadowsocks));
|
//ui->toolBox_share_connection->removeItem(ui->toolBox_share_connection->indexOf(ui->page_share_shadowsocks));
|
||||||
//ui->page_share_shadowsocks->setVisible(false);
|
//ui->page_share_shadowsocks->setVisible(false);
|
||||||
|
|
||||||
|
|
||||||
|
sitesModels.insert(Settings::VpnOnlyForwardSites, new SitesModel(Settings::VpnOnlyForwardSites));
|
||||||
|
sitesModels.insert(Settings::VpnAllExceptSites, new SitesModel(Settings::VpnAllExceptSites));
|
||||||
}
|
}
|
||||||
|
|
||||||
MainWindow::~MainWindow()
|
MainWindow::~MainWindow()
|
||||||
|
|
@ -351,7 +360,8 @@ void MainWindow::keyPressEvent(QKeyEvent *event)
|
||||||
#endif
|
#endif
|
||||||
case Qt::Key_C:
|
case Qt::Key_C:
|
||||||
qDebug().noquote() << "Def server" << m_settings.defaultServerIndex() << m_settings.defaultContainerName(m_settings.defaultServerIndex());
|
qDebug().noquote() << "Def server" << m_settings.defaultServerIndex() << m_settings.defaultContainerName(m_settings.defaultServerIndex());
|
||||||
qDebug().noquote() << QJsonDocument(m_settings.containerConfig(m_settings.defaultServerIndex(), m_settings.defaultContainer(m_settings.defaultServerIndex()))).toJson();
|
//qDebug().noquote() << QJsonDocument(m_settings.containerConfig(m_settings.defaultServerIndex(), m_settings.defaultContainer(m_settings.defaultServerIndex()))).toJson();
|
||||||
|
qDebug().noquote() << QJsonDocument(m_settings.defaultServer()).toJson();
|
||||||
break;
|
break;
|
||||||
case Qt::Key_A:
|
case Qt::Key_A:
|
||||||
goToPage(Page::Start);
|
goToPage(Page::Start);
|
||||||
|
|
@ -369,6 +379,12 @@ void MainWindow::keyPressEvent(QKeyEvent *event)
|
||||||
if (currentPage() == Page::Vpn) break;
|
if (currentPage() == Page::Vpn) break;
|
||||||
if (currentPage() == Page::ServerConfiguring) break;
|
if (currentPage() == Page::ServerConfiguring) break;
|
||||||
if (currentPage() == Page::Start && pagesStack.size() < 2) break;
|
if (currentPage() == Page::Start && pagesStack.size() < 2) break;
|
||||||
|
if (currentPage() == Page::Sites &&
|
||||||
|
ui->tableView_sites->selectionModel()->selection().indexes().size() > 0) {
|
||||||
|
ui->tableView_sites->clearSelection();
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
if (! ui->stackedWidget_main->isAnimationRunning() && ui->stackedWidget_main->currentWidget()->isEnabled()) {
|
if (! ui->stackedWidget_main->isAnimationRunning() && ui->stackedWidget_main->currentWidget()->isEnabled()) {
|
||||||
closePage();
|
closePage();
|
||||||
}
|
}
|
||||||
|
|
@ -626,6 +642,17 @@ void MainWindow::onPushButtonNewServerImport(bool)
|
||||||
credentials.password = o.value("w").toString();
|
credentials.password = o.value("w").toString();
|
||||||
if (credentials.password.isEmpty()) credentials.password = o.value(config_key::password).toString();
|
if (credentials.password.isEmpty()) credentials.password = o.value(config_key::password).toString();
|
||||||
|
|
||||||
|
if (credentials.isValid()) {
|
||||||
|
o.insert(config_key::hostName, credentials.hostName);
|
||||||
|
o.insert(config_key::port, credentials.port);
|
||||||
|
o.insert(config_key::userName, credentials.userName);
|
||||||
|
o.insert(config_key::password, credentials.password);
|
||||||
|
|
||||||
|
o.remove("h");
|
||||||
|
o.remove("p");
|
||||||
|
o.remove("u");
|
||||||
|
o.remove("w");
|
||||||
|
}
|
||||||
qDebug() << QString("Added server %3@%1:%2").
|
qDebug() << QString("Added server %3@%1:%2").
|
||||||
arg(credentials.hostName).
|
arg(credentials.hostName).
|
||||||
arg(credentials.port).
|
arg(credentials.port).
|
||||||
|
|
@ -901,8 +928,7 @@ void MainWindow::onConnectionStateChanged(VpnProtocol::ConnectionState state)
|
||||||
}
|
}
|
||||||
|
|
||||||
ui->pushButton_connect->setEnabled(pushButtonConnectEnabled);
|
ui->pushButton_connect->setEnabled(pushButtonConnectEnabled);
|
||||||
ui->radioButton_mode_all_sites->setEnabled(radioButtonsModeEnabled);
|
ui->widget_vpn_mode->setEnabled(radioButtonsModeEnabled);
|
||||||
ui->radioButton_mode_selected_sites->setEnabled(radioButtonsModeEnabled);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void MainWindow::onVpnProtocolError(ErrorCode errorCode)
|
void MainWindow::onVpnProtocolError(ErrorCode errorCode)
|
||||||
|
|
@ -1013,27 +1039,6 @@ void MainWindow::setupUiConnections()
|
||||||
connect(b, &QPushButton::clicked, this, [this](){ closePage(); });
|
connect(b, &QPushButton::clicked, this, [this](){ closePage(); });
|
||||||
}
|
}
|
||||||
|
|
||||||
connect(ui->pushButton_sites_add_custom, &QPushButton::clicked, this, [this](){ onPushButtonAddCustomSitesClicked(); });
|
|
||||||
|
|
||||||
connect(ui->radioButton_mode_selected_sites, &QRadioButton::toggled, ui->pushButton_vpn_add_site, &QPushButton::setEnabled);
|
|
||||||
|
|
||||||
connect(ui->radioButton_mode_selected_sites, &QRadioButton::toggled, this, [this](bool toggled) {
|
|
||||||
m_settings.setCustomRouting(toggled);
|
|
||||||
});
|
|
||||||
|
|
||||||
connect(ui->pushButton_servers_add_new, &QPushButton::clicked, this, [this](){ goToPage(Page::Start); });
|
|
||||||
|
|
||||||
connect(ui->lineEdit_server_settings_description, &QLineEdit::editingFinished, this, [this](){
|
|
||||||
const QString &newText = ui->lineEdit_server_settings_description->text();
|
|
||||||
QJsonObject server = m_settings.server(selectedServerIndex);
|
|
||||||
server.insert(config_key::description, newText);
|
|
||||||
m_settings.editServer(selectedServerIndex, server);
|
|
||||||
updateServersListPage();
|
|
||||||
});
|
|
||||||
|
|
||||||
connect(ui->lineEdit_server_settings_description, &QLineEdit::returnPressed, this, [this](){
|
|
||||||
ui->lineEdit_server_settings_description->clearFocus();
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void MainWindow::setupNewServerConnections()
|
void MainWindow::setupNewServerConnections()
|
||||||
|
|
@ -1080,7 +1085,8 @@ void MainWindow::setupWizardConnections()
|
||||||
|
|
||||||
connect(ui->pushButton_setup_wizard_vpn_mode_finish, &QPushButton::clicked, this, [this](){
|
connect(ui->pushButton_setup_wizard_vpn_mode_finish, &QPushButton::clicked, this, [this](){
|
||||||
installServer(getInstallConfigsFromWizardPage());
|
installServer(getInstallConfigsFromWizardPage());
|
||||||
m_settings.setCustomRouting(ui->checkBox_setup_wizard_vpn_mode->isChecked());
|
if (ui->checkBox_setup_wizard_vpn_mode->isChecked()) m_settings.setRouteMode(Settings::VpnOnlyForwardSites);
|
||||||
|
else m_settings.setRouteMode(Settings::VpnAllSites);
|
||||||
});
|
});
|
||||||
|
|
||||||
connect(ui->pushButton_setup_wizard_low_finish, &QPushButton::clicked, this, [this](){
|
connect(ui->pushButton_setup_wizard_low_finish, &QPushButton::clicked, this, [this](){
|
||||||
|
|
@ -1092,6 +1098,86 @@ void MainWindow::setupWizardConnections()
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void MainWindow::setupVpnPageConnections()
|
||||||
|
{
|
||||||
|
connect(ui->radioButton_vpn_mode_all_sites, &QRadioButton::toggled, ui->pushButton_vpn_add_site, &QPushButton::setDisabled);
|
||||||
|
|
||||||
|
connect(ui->radioButton_vpn_mode_all_sites, &QRadioButton::toggled, this, [this](bool toggled) {
|
||||||
|
m_settings.setRouteMode(Settings::VpnAllSites);
|
||||||
|
});
|
||||||
|
|
||||||
|
connect(ui->radioButton_vpn_mode_forward_sites, &QRadioButton::toggled, this, [this](bool toggled) {
|
||||||
|
m_settings.setRouteMode(Settings::VpnOnlyForwardSites);
|
||||||
|
});
|
||||||
|
|
||||||
|
connect(ui->radioButton_vpn_mode_except_sites, &QRadioButton::toggled, this, [this](bool toggled) {
|
||||||
|
m_settings.setRouteMode(Settings::VpnAllExceptSites);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
void MainWindow::setupSitesPageConnections()
|
||||||
|
{
|
||||||
|
connect(ui->pushButton_sites_add_custom, &QPushButton::clicked, this, [this](){ onPushButtonAddCustomSitesClicked(); });
|
||||||
|
|
||||||
|
connect(ui->lineEdit_sites_add_custom, &QLineEdit::returnPressed, [&](){
|
||||||
|
ui->pushButton_sites_add_custom->click();
|
||||||
|
});
|
||||||
|
|
||||||
|
connect(ui->pushButton_sites_delete, &QPushButton::clicked, this, [this](){
|
||||||
|
Settings::RouteMode mode = m_settings.routeMode();
|
||||||
|
|
||||||
|
QItemSelectionModel* selection = ui->tableView_sites->selectionModel();
|
||||||
|
if (!selection) return;
|
||||||
|
|
||||||
|
QModelIndexList indexes = selection->selectedRows();
|
||||||
|
|
||||||
|
QStringList sites;
|
||||||
|
for (const QModelIndex &index : indexes) {
|
||||||
|
sites.append(index.data().toString());
|
||||||
|
}
|
||||||
|
|
||||||
|
m_settings.removeVpnSites(mode, sites);
|
||||||
|
updateSitesPage();
|
||||||
|
|
||||||
|
// if (m_vpnConnection->connectionState() == VpnProtocol::ConnectionState::Connected) {
|
||||||
|
// if (IpcClient::Interface()) IpcClient::Interface()->routeDelete(ipToDelete, "");
|
||||||
|
// if (IpcClient::Interface()) IpcClient::Interface()->flushDns();
|
||||||
|
// }
|
||||||
|
|
||||||
|
|
||||||
|
// if (m_vpnConnection->connectionState() == VpnProtocol::ConnectionState::Connected) {
|
||||||
|
// if (IpcClient::Interface())
|
||||||
|
// IpcClient::Interface()->routeDelete(m_vpnConnection->vpnProtocol()->vpnGateway(),
|
||||||
|
// QStringList() << ip);
|
||||||
|
// }
|
||||||
|
});
|
||||||
|
|
||||||
|
connect(ui->pushButton_sites_import, &QPushButton::clicked, this, [this](){
|
||||||
|
QString fileName = QFileDialog::getOpenFileName(this, tr("Import IP addresses"),
|
||||||
|
QStandardPaths::writableLocation(QStandardPaths::DocumentsLocation));
|
||||||
|
|
||||||
|
QFile file(fileName);
|
||||||
|
if (!file.open(QIODevice::ReadOnly)) return;
|
||||||
|
|
||||||
|
Settings::RouteMode mode = m_settings.routeMode();
|
||||||
|
|
||||||
|
QStringList ips;
|
||||||
|
while (!file.atEnd()) {
|
||||||
|
QString line = file.readLine();
|
||||||
|
|
||||||
|
int pos = 0;
|
||||||
|
QRegExp rx = Utils::ipAddressWithSubnetRegExp();
|
||||||
|
while ((pos = rx.indexIn(line, pos)) != -1) {
|
||||||
|
ips << rx.cap(0);
|
||||||
|
pos += rx.matchedLength();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
m_settings.addVpnIps(mode, ips);
|
||||||
|
updateSitesPage();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
void MainWindow::setupAppSettingsConnections()
|
void MainWindow::setupAppSettingsConnections()
|
||||||
{
|
{
|
||||||
connect(ui->checkBox_app_settings_autostart, &QCheckBox::stateChanged, this, [this](int state){
|
connect(ui->checkBox_app_settings_autostart, &QCheckBox::stateChanged, this, [this](int state){
|
||||||
|
|
@ -1413,7 +1499,13 @@ void MainWindow::setupNewServerPageConnections()
|
||||||
|
|
||||||
void MainWindow::setupServerSettingsPageConnections()
|
void MainWindow::setupServerSettingsPageConnections()
|
||||||
{
|
{
|
||||||
|
connect(ui->pushButton_servers_add_new, &QPushButton::clicked, this, [this](){ goToPage(Page::Start); });
|
||||||
|
|
||||||
connect(ui->pushButton_server_settings_protocols, &QPushButton::clicked, this, [this](){ goToPage(Page::ServerVpnProtocols); });
|
connect(ui->pushButton_server_settings_protocols, &QPushButton::clicked, this, [this](){ goToPage(Page::ServerVpnProtocols); });
|
||||||
|
connect(ui->pushButton_server_settings_share_full, &QPushButton::clicked, this, [this](){
|
||||||
|
updateSharingPage(selectedServerIndex, m_settings.serverCredentials(selectedServerIndex), DockerContainer::None);
|
||||||
|
goToPage(Page::ShareConnection);
|
||||||
|
});
|
||||||
|
|
||||||
connect(ui->pushButton_server_settings_clear, SIGNAL(clicked(bool)), this, SLOT(onPushButtonClearServer(bool)));
|
connect(ui->pushButton_server_settings_clear, SIGNAL(clicked(bool)), this, SLOT(onPushButtonClearServer(bool)));
|
||||||
connect(ui->pushButton_server_settings_forget, SIGNAL(clicked(bool)), this, SLOT(onPushButtonForgetServer(bool)));
|
connect(ui->pushButton_server_settings_forget, SIGNAL(clicked(bool)), this, SLOT(onPushButtonForgetServer(bool)));
|
||||||
|
|
@ -1431,6 +1523,17 @@ void MainWindow::setupServerSettingsPageConnections()
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
connect(ui->lineEdit_server_settings_description, &QLineEdit::editingFinished, this, [this](){
|
||||||
|
const QString &newText = ui->lineEdit_server_settings_description->text();
|
||||||
|
QJsonObject server = m_settings.server(selectedServerIndex);
|
||||||
|
server.insert(config_key::description, newText);
|
||||||
|
m_settings.editServer(selectedServerIndex, server);
|
||||||
|
updateServersListPage();
|
||||||
|
});
|
||||||
|
|
||||||
|
connect(ui->lineEdit_server_settings_description, &QLineEdit::returnPressed, this, [this](){
|
||||||
|
ui->lineEdit_server_settings_description->clearFocus();
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
void MainWindow::setupSharePageConnections()
|
void MainWindow::setupSharePageConnections()
|
||||||
|
|
@ -1683,67 +1786,57 @@ void MainWindow::onTrayActionConnect()
|
||||||
|
|
||||||
void MainWindow::onPushButtonAddCustomSitesClicked()
|
void MainWindow::onPushButtonAddCustomSitesClicked()
|
||||||
{
|
{
|
||||||
|
if (ui->radioButton_vpn_mode_all_sites->isChecked()) return;
|
||||||
|
Settings::RouteMode mode = m_settings.routeMode();
|
||||||
|
|
||||||
QString newSite = ui->lineEdit_sites_add_custom->text();
|
QString newSite = ui->lineEdit_sites_add_custom->text();
|
||||||
|
|
||||||
if (newSite.isEmpty()) return;
|
if (newSite.isEmpty()) return;
|
||||||
if (!newSite.contains(".")) return;
|
if (!newSite.contains(".")) return;
|
||||||
|
|
||||||
// get domain name if it present
|
if (!Utils::ipAddressWithSubnetRegExp().exactMatch(newSite)) {
|
||||||
newSite.replace("https://", "");
|
// get domain name if it present
|
||||||
newSite.replace("http://", "");
|
newSite.replace("https://", "");
|
||||||
newSite.replace("ftp://", "");
|
newSite.replace("http://", "");
|
||||||
|
newSite.replace("ftp://", "");
|
||||||
|
|
||||||
newSite = newSite.split("/", QString::SkipEmptyParts).first();
|
newSite = newSite.split("/", QString::SkipEmptyParts).first();
|
||||||
|
}
|
||||||
|
|
||||||
|
qDebug() << "Adding site" << newSite;
|
||||||
|
|
||||||
QStringList customSites = m_settings.customSites();
|
//qDebug() << "sites:" << m_settings.vpnSites(mode);
|
||||||
if (!customSites.contains(newSite)) {
|
|
||||||
customSites.append(newSite);
|
|
||||||
m_settings.setCustomSites(customSites);
|
|
||||||
|
|
||||||
QString newIp = Utils::getIPAddress(newSite);
|
const auto &cbProcess = [this, mode](const QString &newSite, const QString &ip) {
|
||||||
QStringList customIps = m_settings.customIps();
|
m_settings.addVpnSite(mode, newSite, ip);
|
||||||
if (!newIp.isEmpty() && !customIps.contains(newIp)) {
|
|
||||||
customIps.append(newIp);
|
|
||||||
m_settings.setCustomIps(customIps);
|
|
||||||
|
|
||||||
if (m_vpnConnection->connectionState() == VpnProtocol::ConnectionState::Connected) {
|
if (m_vpnConnection->connectionState() == VpnProtocol::ConnectionState::Connected) {
|
||||||
if (IpcClient::Interface()) IpcClient::Interface()->routeAddList(m_vpnConnection->vpnProtocol()->vpnGateway(),
|
if (IpcClient::Interface())
|
||||||
QStringList() << newIp);
|
IpcClient::Interface()->routeAddList(m_vpnConnection->vpnProtocol()->vpnGateway(),
|
||||||
}
|
QStringList() << ip);
|
||||||
}
|
}
|
||||||
|
|
||||||
updateSitesPage();
|
updateSitesPage();
|
||||||
ui->lineEdit_sites_add_custom->clear();
|
};
|
||||||
}
|
|
||||||
else {
|
|
||||||
qDebug() << "customSites already contains" << newSite;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void MainWindow::onPushButtonDeleteCustomSiteClicked(const QString &siteToDelete)
|
const auto &cbResolv = [this, cbProcess](const QHostInfo &hostInfo){
|
||||||
{
|
const QList<QHostAddress> &addresses = hostInfo.addresses();
|
||||||
if (siteToDelete.isEmpty()) {
|
if (!addresses.isEmpty()) {
|
||||||
|
//qDebug() << "Resolved address for" << hostInfo.hostName() << addresses.first().toString();
|
||||||
|
cbProcess(hostInfo.hostName(), addresses.first().toString());
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
ui->lineEdit_sites_add_custom->clear();
|
||||||
|
|
||||||
|
if (Utils::ipAddressWithSubnetRegExp().exactMatch(newSite)) {
|
||||||
|
cbProcess(newSite, newSite);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
else {
|
||||||
QString ipToDelete = Utils::getIPAddress(siteToDelete);
|
cbProcess(newSite, "");
|
||||||
|
updateSitesPage();
|
||||||
QStringList customSites = m_settings.customSites();
|
int reqId = QHostInfo::lookupHost(newSite, this, cbResolv);
|
||||||
customSites.removeAll(siteToDelete);
|
|
||||||
qDebug() << "Deleted custom site:" << siteToDelete;
|
|
||||||
m_settings.setCustomSites(customSites);
|
|
||||||
|
|
||||||
QStringList customIps = m_settings.customIps();
|
|
||||||
customIps.removeAll(ipToDelete);
|
|
||||||
qDebug() << "Deleted custom ip:" << ipToDelete;
|
|
||||||
m_settings.setCustomIps(customIps);
|
|
||||||
|
|
||||||
updateSitesPage();
|
|
||||||
|
|
||||||
if (m_vpnConnection->connectionState() == VpnProtocol::ConnectionState::Connected) {
|
|
||||||
if (IpcClient::Interface()) IpcClient::Interface()->routeDelete(ipToDelete, "");
|
|
||||||
if (IpcClient::Interface()) IpcClient::Interface()->flushDns();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -1769,16 +1862,20 @@ void MainWindow::updateStartPage()
|
||||||
|
|
||||||
void MainWindow::updateSitesPage()
|
void MainWindow::updateSitesPage()
|
||||||
{
|
{
|
||||||
ui->listWidget_sites->clear();
|
Settings::RouteMode m = m_settings.routeMode();
|
||||||
for (const QString &site : m_settings.customSites()) {
|
if (m == Settings::VpnAllSites) return;
|
||||||
makeSitesListItem(ui->listWidget_sites, site);
|
|
||||||
}
|
ui->tableView_sites->setModel(sitesModels.value(m));
|
||||||
|
sitesModels.value(m)->resetCache();
|
||||||
}
|
}
|
||||||
|
|
||||||
void MainWindow::updateVpnPage()
|
void MainWindow::updateVpnPage()
|
||||||
{
|
{
|
||||||
ui->radioButton_mode_selected_sites->setChecked(m_settings.customRouting());
|
Settings::RouteMode mode = m_settings.routeMode();
|
||||||
ui->pushButton_vpn_add_site->setEnabled(m_settings.customRouting());
|
ui->radioButton_vpn_mode_all_sites->setChecked(mode == Settings::VpnAllSites);
|
||||||
|
ui->radioButton_vpn_mode_forward_sites->setChecked(mode == Settings::VpnOnlyForwardSites);
|
||||||
|
ui->radioButton_vpn_mode_except_sites->setChecked(mode == Settings::VpnAllExceptSites);
|
||||||
|
ui->pushButton_vpn_add_site->setEnabled(mode != Settings::VpnAllSites);
|
||||||
}
|
}
|
||||||
|
|
||||||
void MainWindow::updateAppSettingsPage()
|
void MainWindow::updateAppSettingsPage()
|
||||||
|
|
@ -1868,20 +1965,6 @@ void MainWindow::updateProtocolsPage()
|
||||||
ui->frame_openvpn_settings->setVisible(containers.contains(DockerContainer::OpenVpn));
|
ui->frame_openvpn_settings->setVisible(containers.contains(DockerContainer::OpenVpn));
|
||||||
}
|
}
|
||||||
|
|
||||||
void MainWindow::updateShareCodePage()
|
|
||||||
{
|
|
||||||
// QJsonObject o;
|
|
||||||
// o.insert("h", m_settings.serverName());
|
|
||||||
// o.insert("p", m_settings.serverPort());
|
|
||||||
// o.insert("u", m_settings.userName());
|
|
||||||
// o.insert("w", m_settings.password());
|
|
||||||
|
|
||||||
// QByteArray ba = QJsonDocument(o).toJson().toBase64(QByteArray::Base64UrlEncoding | QByteArray::OmitTrailingEquals);
|
|
||||||
// ui->textEdit_sharing_code->setText(QString("vpn://%1").arg(QString(ba)));
|
|
||||||
|
|
||||||
//qDebug() << "Share code" << QJsonDocument(o).toJson();
|
|
||||||
}
|
|
||||||
|
|
||||||
void MainWindow::updateOpenVpnPage(const QJsonObject &openvpnConfig, DockerContainer container, bool haveAuthData)
|
void MainWindow::updateOpenVpnPage(const QJsonObject &openvpnConfig, DockerContainer container, bool haveAuthData)
|
||||||
{
|
{
|
||||||
ui->widget_proto_openvpn->setEnabled(haveAuthData);
|
ui->widget_proto_openvpn->setEnabled(haveAuthData);
|
||||||
|
|
@ -1968,34 +2051,43 @@ void MainWindow::updateSharingPage(int serverIndex, const ServerCredentials &cre
|
||||||
|
|
||||||
const QJsonObject &containerConfig = m_settings.containerConfig(serverIndex, container);
|
const QJsonObject &containerConfig = m_settings.containerConfig(serverIndex, container);
|
||||||
|
|
||||||
for (QWidget *page : { ui->page_share_openvpn,
|
for (QWidget *page : {
|
||||||
ui->page_share_shadowsocks,
|
ui->page_share_amnezia,
|
||||||
ui->page_share_cloak,
|
ui->page_share_openvpn,
|
||||||
ui->page_share_full_access }) {
|
ui->page_share_shadowsocks,
|
||||||
|
ui->page_share_cloak,
|
||||||
|
ui->page_share_full_access }) {
|
||||||
|
|
||||||
ui->toolBox_share_connection->removeItem(ui->toolBox_share_connection->indexOf(page));
|
ui->toolBox_share_connection->removeItem(ui->toolBox_share_connection->indexOf(page));
|
||||||
page->hide();
|
page->hide();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (container == DockerContainer::OpenVpn) {
|
if (container == DockerContainer::OpenVpn) {
|
||||||
|
ui->toolBox_share_connection->addItem(ui->page_share_amnezia, tr(" Share for Amnezia client"));
|
||||||
ui->toolBox_share_connection->addItem(ui->page_share_openvpn, tr(" Share for OpenVPN client"));
|
ui->toolBox_share_connection->addItem(ui->page_share_openvpn, tr(" Share for OpenVPN client"));
|
||||||
|
|
||||||
QJsonObject protoConfig = m_settings.protocolConfig(serverIndex, container, Protocol::OpenVpn);
|
QString cfg = tr("Press Generate config");
|
||||||
QString cfg = protoConfig.value(config_key::last_config).toString();
|
ui->textEdit_share_openvpn_code->setPlainText(cfg);
|
||||||
if (!cfg.isEmpty()) {
|
ui->pushButton_share_openvpn_copy->setEnabled(false);
|
||||||
// TODO add redirect-gateway def1 bypass-dhcp here and on click Generate config
|
ui->pushButton_share_openvpn_save->setEnabled(false);
|
||||||
ui->textEdit_share_openvpn_code->setPlainText(cfg);
|
|
||||||
}
|
// QJsonObject protoConfig = m_settings.protocolConfig(serverIndex, container, Protocol::OpenVpn);
|
||||||
else {
|
// QString cfg = protoConfig.value(config_key::last_config).toString();
|
||||||
cfg = tr("Press Generate config");
|
// if (!cfg.isEmpty()) {
|
||||||
ui->textEdit_share_openvpn_code->setPlainText(cfg);
|
// // TODO add redirect-gateway def1 bypass-dhcp here and on click Generate config
|
||||||
ui->pushButton_share_openvpn_copy->setEnabled(false);
|
// ui->textEdit_share_openvpn_code->setPlainText(cfg);
|
||||||
ui->pushButton_share_openvpn_save->setEnabled(false);
|
// }
|
||||||
}
|
// else {
|
||||||
|
// cfg = tr("Press Generate config");
|
||||||
|
// ui->textEdit_share_openvpn_code->setPlainText(cfg);
|
||||||
|
// ui->pushButton_share_openvpn_copy->setEnabled(false);
|
||||||
|
// ui->pushButton_share_openvpn_save->setEnabled(false);
|
||||||
|
// }
|
||||||
ui->toolBox_share_connection->setCurrentWidget(ui->page_share_openvpn);
|
ui->toolBox_share_connection->setCurrentWidget(ui->page_share_openvpn);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (container == DockerContainer::OpenVpnOverShadowSocks) {
|
if (container == DockerContainer::OpenVpnOverShadowSocks) {
|
||||||
|
ui->toolBox_share_connection->addItem(ui->page_share_amnezia, tr(" Share for Amnezia client"));
|
||||||
ui->toolBox_share_connection->addItem(ui->page_share_shadowsocks, tr(" Share for ShadowSocks client"));
|
ui->toolBox_share_connection->addItem(ui->page_share_shadowsocks, tr(" Share for ShadowSocks client"));
|
||||||
|
|
||||||
QJsonObject protoConfig = m_settings.protocolConfig(serverIndex, container, Protocol::ShadowSocks);
|
QJsonObject protoConfig = m_settings.protocolConfig(serverIndex, container, Protocol::ShadowSocks);
|
||||||
|
|
@ -2034,6 +2126,24 @@ void MainWindow::updateSharingPage(int serverIndex, const ServerCredentials &cre
|
||||||
ui->toolBox_share_connection->layout()->update();
|
ui->toolBox_share_connection->layout()->update();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (container == DockerContainer::OpenVpnOverCloak) {
|
||||||
|
ui->toolBox_share_connection->addItem(ui->page_share_amnezia, tr(" Share for Amnezia client"));
|
||||||
|
}
|
||||||
|
|
||||||
|
// Full access
|
||||||
|
if (container == DockerContainer::None) {
|
||||||
|
ui->toolBox_share_connection->addItem(ui->page_share_full_access, tr(" Share server full access"));
|
||||||
|
|
||||||
|
const QJsonObject &server = m_settings.server(selectedServerIndex);
|
||||||
|
|
||||||
|
QByteArray ba = QJsonDocument(server).toJson().toBase64(QByteArray::Base64UrlEncoding | QByteArray::OmitTrailingEquals);
|
||||||
|
|
||||||
|
ui->textEdit_share_full_code->setText(QString("vpn://%1").arg(QString(ba)));
|
||||||
|
ui->toolBox_share_connection->setCurrentWidget(ui->page_share_full_access);
|
||||||
|
}
|
||||||
|
|
||||||
|
//ui->toolBox_share_connection->addItem(ui->page_share_amnezia, tr(" Share for Amnezia client"));
|
||||||
|
|
||||||
// Amnezia sharing
|
// Amnezia sharing
|
||||||
// QJsonObject exportContainer;
|
// QJsonObject exportContainer;
|
||||||
// for (Protocol p: protocolsForContainer(container)) {
|
// for (Protocol p: protocolsForContainer(container)) {
|
||||||
|
|
@ -2046,38 +2156,6 @@ void MainWindow::updateSharingPage(int serverIndex, const ServerCredentials &cre
|
||||||
// ui->textEdit_share_amnezia_code->setPlainText(QJsonDocument(exportContainer).toJson());
|
// ui->textEdit_share_amnezia_code->setPlainText(QJsonDocument(exportContainer).toJson());
|
||||||
|
|
||||||
ui->textEdit_share_amnezia_code->setPlainText(tr(""));
|
ui->textEdit_share_amnezia_code->setPlainText(tr(""));
|
||||||
repaint();
|
|
||||||
update();
|
|
||||||
updateGeometry();
|
|
||||||
}
|
|
||||||
|
|
||||||
void MainWindow::makeSitesListItem(QListWidget *listWidget, const QString &address)
|
|
||||||
{
|
|
||||||
QSize size(310, 25);
|
|
||||||
QWidget* widget = new QWidget;
|
|
||||||
widget->resize(size);
|
|
||||||
|
|
||||||
QLabel *label = new QLabel(address, widget);
|
|
||||||
label->resize(size);
|
|
||||||
|
|
||||||
QPushButton* btn = new QPushButton(widget);
|
|
||||||
btn->resize(size);
|
|
||||||
|
|
||||||
QPushButton* btn1 = new QPushButton(widget);
|
|
||||||
btn1->resize(30, 25);
|
|
||||||
btn1->move(280, 0);
|
|
||||||
btn1->setCursor(QCursor(Qt::PointingHandCursor));
|
|
||||||
|
|
||||||
connect(btn1, &QPushButton::clicked, this, [this, label]() {
|
|
||||||
onPushButtonDeleteCustomSiteClicked(label->text());
|
|
||||||
return;
|
|
||||||
});
|
|
||||||
|
|
||||||
QListWidgetItem* item = new QListWidgetItem(listWidget);
|
|
||||||
item->setSizeHint(size);
|
|
||||||
listWidget->setItemWidget(item, widget);
|
|
||||||
|
|
||||||
widget->setStyleSheet(styleSheet());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void MainWindow::makeServersListItem(QListWidget *listWidget, const QJsonObject &server, bool isDefault, int index)
|
void MainWindow::makeServersListItem(QListWidget *listWidget, const QJsonObject &server, bool isDefault, int index)
|
||||||
|
|
|
||||||
|
|
@ -17,6 +17,7 @@
|
||||||
#include "protocols/vpnprotocol.h"
|
#include "protocols/vpnprotocol.h"
|
||||||
|
|
||||||
#include "settings.h"
|
#include "settings.h"
|
||||||
|
#include "sites_model.h"
|
||||||
|
|
||||||
class VpnConnection;
|
class VpnConnection;
|
||||||
|
|
||||||
|
|
@ -63,7 +64,6 @@ private slots:
|
||||||
void onPushButtonForgetServer(bool);
|
void onPushButtonForgetServer(bool);
|
||||||
|
|
||||||
void onPushButtonAddCustomSitesClicked();
|
void onPushButtonAddCustomSitesClicked();
|
||||||
void onPushButtonDeleteCustomSiteClicked(const QString &siteToDelete);
|
|
||||||
|
|
||||||
void onTrayActionConnect(); // connect from context menu
|
void onTrayActionConnect(); // connect from context menu
|
||||||
void setTrayState(VpnProtocol::ConnectionState state);
|
void setTrayState(VpnProtocol::ConnectionState state);
|
||||||
|
|
@ -94,6 +94,8 @@ private:
|
||||||
void setupUiConnections();
|
void setupUiConnections();
|
||||||
void setupNewServerConnections();
|
void setupNewServerConnections();
|
||||||
void setupWizardConnections();
|
void setupWizardConnections();
|
||||||
|
void setupVpnPageConnections();
|
||||||
|
void setupSitesPageConnections();
|
||||||
void setupAppSettingsConnections();
|
void setupAppSettingsConnections();
|
||||||
void setupGeneralSettingsConnections();
|
void setupGeneralSettingsConnections();
|
||||||
void setupNetworkSettingsConnections();
|
void setupNetworkSettingsConnections();
|
||||||
|
|
@ -110,7 +112,6 @@ private:
|
||||||
void updateServerPage();
|
void updateServerPage();
|
||||||
void updateServersListPage();
|
void updateServersListPage();
|
||||||
void updateProtocolsPage();
|
void updateProtocolsPage();
|
||||||
void updateShareCodePage();
|
|
||||||
void updateOpenVpnPage(const QJsonObject &openvpnConfig, DockerContainer container, bool haveAuthData);
|
void updateOpenVpnPage(const QJsonObject &openvpnConfig, DockerContainer container, bool haveAuthData);
|
||||||
void updateShadowSocksPage(const QJsonObject &ssConfig, DockerContainer container, bool haveAuthData);
|
void updateShadowSocksPage(const QJsonObject &ssConfig, DockerContainer container, bool haveAuthData);
|
||||||
void updateCloakPage(const QJsonObject &ckConfig, DockerContainer container, bool haveAuthData);
|
void updateCloakPage(const QJsonObject &ckConfig, DockerContainer container, bool haveAuthData);
|
||||||
|
|
@ -118,7 +119,6 @@ private:
|
||||||
void updateSharingPage(int serverIndex, const ServerCredentials &credentials,
|
void updateSharingPage(int serverIndex, const ServerCredentials &credentials,
|
||||||
DockerContainer container);
|
DockerContainer container);
|
||||||
|
|
||||||
void makeSitesListItem(QListWidget* listWidget, const QString &address);
|
|
||||||
void makeServersListItem(QListWidget* listWidget, const QJsonObject &server, bool isDefault, int index);
|
void makeServersListItem(QListWidget* listWidget, const QJsonObject &server, bool isDefault, int index);
|
||||||
|
|
||||||
void updateQRCodeImage(const QString &text, QLabel *label);
|
void updateQRCodeImage(const QString &text, QLabel *label);
|
||||||
|
|
@ -135,6 +135,8 @@ private:
|
||||||
VpnConnection* m_vpnConnection;
|
VpnConnection* m_vpnConnection;
|
||||||
Settings m_settings;
|
Settings m_settings;
|
||||||
|
|
||||||
|
QMap<Settings::RouteMode, SitesModel *> sitesModels;
|
||||||
|
|
||||||
QAction* m_trayActionConnect;
|
QAction* m_trayActionConnect;
|
||||||
QAction* m_trayActionDisconnect;
|
QAction* m_trayActionDisconnect;
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -11,7 +11,7 @@
|
||||||
</rect>
|
</rect>
|
||||||
</property>
|
</property>
|
||||||
<property name="windowTitle">
|
<property name="windowTitle">
|
||||||
<string/>
|
<string>AmneziaVPN</string>
|
||||||
</property>
|
</property>
|
||||||
<property name="styleSheet">
|
<property name="styleSheet">
|
||||||
<string notr="true">QMainWindow {
|
<string notr="true">QMainWindow {
|
||||||
|
|
@ -120,18 +120,18 @@ border-image: url(:/images/controls/check_on.png);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
QScrollBar:vertical { /* The area behind the scrollbar covering entire height. */
|
QScrollBar:vertical { /* The area behind the scrollbar covering entire height. */
|
||||||
background-color: grey;
|
background-color: rgba(0, 0, 0,0);
|
||||||
opacity: 100;
|
opacity: 100;
|
||||||
width: 7px; /* set width to zero to hide scrollbar entirely. Can look quite clean and scrolling still works with mousewheel. */
|
width: 10px; /* set width to zero to hide scrollbar entirely. Can look quite clean and scrolling still works with mousewheel. */
|
||||||
margin: 0px 0px; /* Takes the height of the buttons + 3 extra pixels to leave some free space between handle and buttons */
|
margin: 10px px; /* Takes the height of the buttons + 3 extra pixels to leave some free space between handle and buttons */
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
QScrollBar::handle:vertical { /* The handle you scroll with */
|
QScrollBar::handle:vertical { /* The handle you scroll with */
|
||||||
image-position: center; /* image is used as a small gripper in the center of the scrollbar.. You can also use background-image to use two images */
|
image-position: center; /* image is used as a small gripper in the center of the scrollbar.. You can also use background-image to use two images */
|
||||||
background-color: rgb(200, 200, 200);
|
background-color: rgb(200, 200, 200);
|
||||||
|
border: 2px solid rgb(240,240,240);
|
||||||
border-radius: 1px;
|
border-radius: 1px;
|
||||||
min-height: 10px;
|
min-height: 10px;
|
||||||
}
|
}
|
||||||
|
|
@ -143,7 +143,7 @@ QScrollBar::handle:vertical:pressed { /* state when you hover over the handle */
|
||||||
}
|
}
|
||||||
QScrollBar::sub-line:vertical { /* button to scroll up */
|
QScrollBar::sub-line:vertical { /* button to scroll up */
|
||||||
background-color: rgb(240,240,240);
|
background-color: rgb(240,240,240);
|
||||||
height: 0px;
|
height: 10px;
|
||||||
subcontrol-position: top;
|
subcontrol-position: top;
|
||||||
subcontrol-origin: margin;
|
subcontrol-origin: margin;
|
||||||
}
|
}
|
||||||
|
|
@ -158,7 +158,8 @@ QScrollBar::up-arrow:vertical { /* arrow to scroll up with */
|
||||||
|
|
||||||
QScrollBar::add-line:vertical { /* Button to scroll down */
|
QScrollBar::add-line:vertical { /* Button to scroll down */
|
||||||
background-color: rgb(240,240,240);
|
background-color: rgb(240,240,240);
|
||||||
height: 0px;
|
height: 10px;
|
||||||
|
padding-top: 2px;
|
||||||
subcontrol-position: bottom;
|
subcontrol-position: bottom;
|
||||||
subcontrol-origin: margin;
|
subcontrol-origin: margin;
|
||||||
}
|
}
|
||||||
|
|
@ -171,27 +172,9 @@ QScrollBar::down-arrow:vertical { /* arrow to scroll down with */
|
||||||
}
|
}
|
||||||
|
|
||||||
QScrollBar::add-page:vertical, QScrollBar::sub-page:vertical {
|
QScrollBar::add-page:vertical, QScrollBar::sub-page:vertical {
|
||||||
background-color: black;
|
background-color: rgb(240,240,240);
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
}</string>
|
||||||
QGroupBox {
|
|
||||||
border: 1px solid lightgray;
|
|
||||||
border-radius: 2px;
|
|
||||||
margin-top: 1ex;
|
|
||||||
}
|
|
||||||
|
|
||||||
QGroupBox::title {
|
|
||||||
font-size: 16px;
|
|
||||||
font-style: normal;
|
|
||||||
font-weight: normal;
|
|
||||||
color: #181922;
|
|
||||||
|
|
||||||
subcontrol-origin: margin;
|
|
||||||
subcontrol-position: top left;
|
|
||||||
padding: 0 3px;
|
|
||||||
}
|
|
||||||
*/</string>
|
|
||||||
</property>
|
</property>
|
||||||
<widget class="QWidget" name="centralWidget">
|
<widget class="QWidget" name="centralWidget">
|
||||||
<property name="styleSheet">
|
<property name="styleSheet">
|
||||||
|
|
@ -291,7 +274,7 @@ QPushButton:hover {
|
||||||
<string notr="true"/>
|
<string notr="true"/>
|
||||||
</property>
|
</property>
|
||||||
<property name="currentIndex">
|
<property name="currentIndex">
|
||||||
<number>1</number>
|
<number>10</number>
|
||||||
</property>
|
</property>
|
||||||
<widget class="QWidget" name="page_start">
|
<widget class="QWidget" name="page_start">
|
||||||
<widget class="QLabel" name="label_25">
|
<widget class="QLabel" name="label_25">
|
||||||
|
|
@ -2720,7 +2703,7 @@ background: #211966;
|
||||||
<property name="geometry">
|
<property name="geometry">
|
||||||
<rect>
|
<rect>
|
||||||
<x>0</x>
|
<x>0</x>
|
||||||
<y>370</y>
|
<y>360</y>
|
||||||
<width>380</width>
|
<width>380</width>
|
||||||
<height>51</height>
|
<height>51</height>
|
||||||
</rect>
|
</rect>
|
||||||
|
|
@ -2826,7 +2809,7 @@ font: 16px "Lato"; </string>
|
||||||
<property name="geometry">
|
<property name="geometry">
|
||||||
<rect>
|
<rect>
|
||||||
<x>20</x>
|
<x>20</x>
|
||||||
<y>550</y>
|
<y>560</y>
|
||||||
<width>341</width>
|
<width>341</width>
|
||||||
<height>40</height>
|
<height>40</height>
|
||||||
</rect>
|
</rect>
|
||||||
|
|
@ -2960,9 +2943,9 @@ color: #181922;
|
||||||
<property name="geometry">
|
<property name="geometry">
|
||||||
<rect>
|
<rect>
|
||||||
<x>20</x>
|
<x>20</x>
|
||||||
<y>450</y>
|
<y>440</y>
|
||||||
<width>281</width>
|
<width>281</width>
|
||||||
<height>31</height>
|
<height>21</height>
|
||||||
</rect>
|
</rect>
|
||||||
</property>
|
</property>
|
||||||
<property name="styleSheet">
|
<property name="styleSheet">
|
||||||
|
|
@ -2983,49 +2966,11 @@ color: #181922;
|
||||||
<set>Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter</set>
|
<set>Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter</set>
|
||||||
</property>
|
</property>
|
||||||
</widget>
|
</widget>
|
||||||
<widget class="QRadioButton" name="radioButton_mode_all_sites">
|
|
||||||
<property name="enabled">
|
|
||||||
<bool>true</bool>
|
|
||||||
</property>
|
|
||||||
<property name="geometry">
|
|
||||||
<rect>
|
|
||||||
<x>20</x>
|
|
||||||
<y>490</y>
|
|
||||||
<width>341</width>
|
|
||||||
<height>19</height>
|
|
||||||
</rect>
|
|
||||||
</property>
|
|
||||||
<property name="text">
|
|
||||||
<string>For all connections</string>
|
|
||||||
</property>
|
|
||||||
<property name="checked">
|
|
||||||
<bool>true</bool>
|
|
||||||
</property>
|
|
||||||
</widget>
|
|
||||||
<widget class="QRadioButton" name="radioButton_mode_selected_sites">
|
|
||||||
<property name="enabled">
|
|
||||||
<bool>true</bool>
|
|
||||||
</property>
|
|
||||||
<property name="geometry">
|
|
||||||
<rect>
|
|
||||||
<x>20</x>
|
|
||||||
<y>520</y>
|
|
||||||
<width>341</width>
|
|
||||||
<height>19</height>
|
|
||||||
</rect>
|
|
||||||
</property>
|
|
||||||
<property name="text">
|
|
||||||
<string>For selected sites</string>
|
|
||||||
</property>
|
|
||||||
<property name="checked">
|
|
||||||
<bool>false</bool>
|
|
||||||
</property>
|
|
||||||
</widget>
|
|
||||||
<widget class="QLabel" name="label_error_text">
|
<widget class="QLabel" name="label_error_text">
|
||||||
<property name="geometry">
|
<property name="geometry">
|
||||||
<rect>
|
<rect>
|
||||||
<x>0</x>
|
<x>0</x>
|
||||||
<y>290</y>
|
<y>280</y>
|
||||||
<width>381</width>
|
<width>381</width>
|
||||||
<height>61</height>
|
<height>61</height>
|
||||||
</rect>
|
</rect>
|
||||||
|
|
@ -3043,10 +2988,77 @@ color: #181922;
|
||||||
<bool>true</bool>
|
<bool>true</bool>
|
||||||
</property>
|
</property>
|
||||||
</widget>
|
</widget>
|
||||||
|
<widget class="QWidget" name="widget_vpn_mode" native="true">
|
||||||
|
<property name="geometry">
|
||||||
|
<rect>
|
||||||
|
<x>20</x>
|
||||||
|
<y>470</y>
|
||||||
|
<width>351</width>
|
||||||
|
<height>91</height>
|
||||||
|
</rect>
|
||||||
|
</property>
|
||||||
|
<widget class="QRadioButton" name="radioButton_vpn_mode_except_sites">
|
||||||
|
<property name="enabled">
|
||||||
|
<bool>true</bool>
|
||||||
|
</property>
|
||||||
|
<property name="geometry">
|
||||||
|
<rect>
|
||||||
|
<x>0</x>
|
||||||
|
<y>60</y>
|
||||||
|
<width>341</width>
|
||||||
|
<height>19</height>
|
||||||
|
</rect>
|
||||||
|
</property>
|
||||||
|
<property name="text">
|
||||||
|
<string>Except selected sites</string>
|
||||||
|
</property>
|
||||||
|
<property name="checked">
|
||||||
|
<bool>false</bool>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
<widget class="QRadioButton" name="radioButton_vpn_mode_forward_sites">
|
||||||
|
<property name="enabled">
|
||||||
|
<bool>true</bool>
|
||||||
|
</property>
|
||||||
|
<property name="geometry">
|
||||||
|
<rect>
|
||||||
|
<x>0</x>
|
||||||
|
<y>30</y>
|
||||||
|
<width>341</width>
|
||||||
|
<height>19</height>
|
||||||
|
</rect>
|
||||||
|
</property>
|
||||||
|
<property name="text">
|
||||||
|
<string>For selected sites</string>
|
||||||
|
</property>
|
||||||
|
<property name="checked">
|
||||||
|
<bool>false</bool>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
<widget class="QRadioButton" name="radioButton_vpn_mode_all_sites">
|
||||||
|
<property name="enabled">
|
||||||
|
<bool>true</bool>
|
||||||
|
</property>
|
||||||
|
<property name="geometry">
|
||||||
|
<rect>
|
||||||
|
<x>0</x>
|
||||||
|
<y>0</y>
|
||||||
|
<width>341</width>
|
||||||
|
<height>19</height>
|
||||||
|
</rect>
|
||||||
|
</property>
|
||||||
|
<property name="text">
|
||||||
|
<string>For all connections</string>
|
||||||
|
</property>
|
||||||
|
<property name="checked">
|
||||||
|
<bool>true</bool>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</widget>
|
||||||
</widget>
|
</widget>
|
||||||
<widget class="QWidget" name="page_sites">
|
<widget class="QWidget" name="page_sites">
|
||||||
<property name="styleSheet">
|
<property name="styleSheet">
|
||||||
<string notr="true">QListView {
|
<string notr="true">/*QListView {
|
||||||
outline: 0;
|
outline: 0;
|
||||||
background: transparent;
|
background: transparent;
|
||||||
border: none;
|
border: none;
|
||||||
|
|
@ -3071,7 +3083,8 @@ QListView::item:selected {
|
||||||
border: none;
|
border: none;
|
||||||
background: rgba(167, 167, 167, 0.1);
|
background: rgba(167, 167, 167, 0.1);
|
||||||
color: #181922;
|
color: #181922;
|
||||||
}</string>
|
}
|
||||||
|
*/</string>
|
||||||
</property>
|
</property>
|
||||||
<widget class="QPushButton" name="pushButton_back_from_sites">
|
<widget class="QPushButton" name="pushButton_back_from_sites">
|
||||||
<property name="geometry">
|
<property name="geometry">
|
||||||
|
|
@ -3160,7 +3173,7 @@ color: #100A44;
|
||||||
<rect>
|
<rect>
|
||||||
<x>20</x>
|
<x>20</x>
|
||||||
<y>140</y>
|
<y>140</y>
|
||||||
<width>281</width>
|
<width>231</width>
|
||||||
<height>31</height>
|
<height>31</height>
|
||||||
</rect>
|
</rect>
|
||||||
</property>
|
</property>
|
||||||
|
|
@ -3191,7 +3204,7 @@ color: #100A44;
|
||||||
<set>Qt::AlignCenter</set>
|
<set>Qt::AlignCenter</set>
|
||||||
</property>
|
</property>
|
||||||
<property name="placeholderText">
|
<property name="placeholderText">
|
||||||
<string>For example, yousite.com or 17.21.111.8</string>
|
<string>yousite.com or IP address</string>
|
||||||
</property>
|
</property>
|
||||||
</widget>
|
</widget>
|
||||||
<widget class="QPushButton" name="pushButton_sites_add_custom">
|
<widget class="QPushButton" name="pushButton_sites_add_custom">
|
||||||
|
|
@ -3200,7 +3213,7 @@ color: #100A44;
|
||||||
</property>
|
</property>
|
||||||
<property name="geometry">
|
<property name="geometry">
|
||||||
<rect>
|
<rect>
|
||||||
<x>310</x>
|
<x>260</x>
|
||||||
<y>140</y>
|
<y>140</y>
|
||||||
<width>51</width>
|
<width>51</width>
|
||||||
<height>31</height>
|
<height>31</height>
|
||||||
|
|
@ -3246,50 +3259,127 @@ line-height: 150%;
|
||||||
color: #333333;</string>
|
color: #333333;</string>
|
||||||
</property>
|
</property>
|
||||||
<property name="text">
|
<property name="text">
|
||||||
<string>Web site or hostname or IP address</string>
|
<string>Web site/Hostname/IP address/Subnet</string>
|
||||||
</property>
|
</property>
|
||||||
</widget>
|
</widget>
|
||||||
<widget class="QListWidget" name="listWidget_sites">
|
<widget class="QTableView" name="tableView_sites">
|
||||||
<property name="geometry">
|
<property name="geometry">
|
||||||
<rect>
|
<rect>
|
||||||
<x>20</x>
|
<x>20</x>
|
||||||
<y>200</y>
|
<y>200</y>
|
||||||
<width>340</width>
|
<width>341</width>
|
||||||
<height>400</height>
|
<height>371</height>
|
||||||
</rect>
|
</rect>
|
||||||
</property>
|
</property>
|
||||||
<property name="styleSheet">
|
<property name="styleSheet">
|
||||||
<string notr="true">QWidget {
|
<string notr="true">QTableView {
|
||||||
margin: 0px;
|
|
||||||
padding: 0px;
|
|
||||||
}
|
|
||||||
|
|
||||||
QPushButton:hover {
|
|
||||||
image: url(:/images/close.png);
|
|
||||||
image-position: right center;
|
|
||||||
}
|
|
||||||
|
|
||||||
QListView {
|
|
||||||
show-decoration-selected: 1; /* make the selection span the entire width of the view */
|
|
||||||
}
|
|
||||||
|
|
||||||
QListView::item:selected:!active {
|
|
||||||
background: transparent;
|
background: transparent;
|
||||||
|
gridline-color: transparent;
|
||||||
|
|
||||||
border: none;
|
border: none;
|
||||||
|
outline: none;
|
||||||
|
show-decoration-selected: 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
QListView::item:selected:active {
|
QTableView::item
|
||||||
background: transparent;
|
{
|
||||||
border: none;
|
padding-left: 5px;
|
||||||
|
border-top: 1px solid lightgray;
|
||||||
|
color: #181922;
|
||||||
}
|
}
|
||||||
|
|
||||||
QListView::item:hover {
|
QTableView::item::selected
|
||||||
background: qlineargradient(x1: 0, y1: 0, x2: 0, y2: 1,
|
{
|
||||||
stop: 0 #FAFBFE, stop: 1 #ECEEFF);
|
border: 0px;
|
||||||
|
padding-left: 5px;
|
||||||
|
background-color: rgb(99, 180, 251);
|
||||||
|
border: : rgb(99, 180, 251);
|
||||||
}</string>
|
}</string>
|
||||||
</property>
|
</property>
|
||||||
<property name="selectionMode">
|
<property name="selectionMode">
|
||||||
<enum>QAbstractItemView::NoSelection</enum>
|
<enum>QAbstractItemView::ExtendedSelection</enum>
|
||||||
|
</property>
|
||||||
|
<property name="selectionBehavior">
|
||||||
|
<enum>QAbstractItemView::SelectRows</enum>
|
||||||
|
</property>
|
||||||
|
<property name="showGrid">
|
||||||
|
<bool>false</bool>
|
||||||
|
</property>
|
||||||
|
<property name="gridStyle">
|
||||||
|
<enum>Qt::NoPen</enum>
|
||||||
|
</property>
|
||||||
|
<property name="cornerButtonEnabled">
|
||||||
|
<bool>false</bool>
|
||||||
|
</property>
|
||||||
|
<attribute name="horizontalHeaderVisible">
|
||||||
|
<bool>false</bool>
|
||||||
|
</attribute>
|
||||||
|
<attribute name="verticalHeaderVisible">
|
||||||
|
<bool>false</bool>
|
||||||
|
</attribute>
|
||||||
|
</widget>
|
||||||
|
<widget class="QPushButton" name="pushButton_sites_delete">
|
||||||
|
<property name="geometry">
|
||||||
|
<rect>
|
||||||
|
<x>80</x>
|
||||||
|
<y>589</y>
|
||||||
|
<width>231</width>
|
||||||
|
<height>31</height>
|
||||||
|
</rect>
|
||||||
|
</property>
|
||||||
|
<property name="cursor">
|
||||||
|
<cursorShape>PointingHandCursor</cursorShape>
|
||||||
|
</property>
|
||||||
|
<property name="styleSheet">
|
||||||
|
<string notr="true">QPushButton {
|
||||||
|
color:rgb(212, 212, 212);
|
||||||
|
border-radius: 4px;
|
||||||
|
|
||||||
|
font-family: Lato;
|
||||||
|
font-style: normal;
|
||||||
|
font-weight: normal;
|
||||||
|
font-size: 16px;
|
||||||
|
line-height: 21px;
|
||||||
|
|
||||||
|
background: #100A44;
|
||||||
|
border-radius: 4px;
|
||||||
|
}
|
||||||
|
QPushButton:hover {
|
||||||
|
background: #211966;
|
||||||
|
}</string>
|
||||||
|
</property>
|
||||||
|
<property name="text">
|
||||||
|
<string>Delete selected</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
<widget class="QPushButton" name="pushButton_sites_import">
|
||||||
|
<property name="enabled">
|
||||||
|
<bool>true</bool>
|
||||||
|
</property>
|
||||||
|
<property name="geometry">
|
||||||
|
<rect>
|
||||||
|
<x>320</x>
|
||||||
|
<y>140</y>
|
||||||
|
<width>51</width>
|
||||||
|
<height>31</height>
|
||||||
|
</rect>
|
||||||
|
</property>
|
||||||
|
<property name="cursor">
|
||||||
|
<cursorShape>PointingHandCursor</cursorShape>
|
||||||
|
</property>
|
||||||
|
<property name="styleSheet">
|
||||||
|
<string notr="true">QPushButton {
|
||||||
|
background: #100A44;
|
||||||
|
border-radius: 4px;
|
||||||
|
padding: 5px;
|
||||||
|
image: url(:/images/folder.png);
|
||||||
|
}
|
||||||
|
QPushButton:hover {
|
||||||
|
background: #211966;
|
||||||
|
}</string>
|
||||||
|
</property>
|
||||||
|
<property name="text">
|
||||||
|
<string/>
|
||||||
</property>
|
</property>
|
||||||
</widget>
|
</widget>
|
||||||
</widget>
|
</widget>
|
||||||
|
|
@ -4471,7 +4561,7 @@ font-weight: bold;
|
||||||
<property name="geometry">
|
<property name="geometry">
|
||||||
<rect>
|
<rect>
|
||||||
<x>40</x>
|
<x>40</x>
|
||||||
<y>220</y>
|
<y>210</y>
|
||||||
<width>300</width>
|
<width>300</width>
|
||||||
<height>40</height>
|
<height>40</height>
|
||||||
</rect>
|
</rect>
|
||||||
|
|
@ -4528,6 +4618,40 @@ font-size: 20px;
|
||||||
<set>Qt::LinksAccessibleByMouse|Qt::TextSelectableByMouse</set>
|
<set>Qt::LinksAccessibleByMouse|Qt::TextSelectableByMouse</set>
|
||||||
</property>
|
</property>
|
||||||
</widget>
|
</widget>
|
||||||
|
<widget class="QPushButton" name="pushButton_server_settings_share_full">
|
||||||
|
<property name="geometry">
|
||||||
|
<rect>
|
||||||
|
<x>40</x>
|
||||||
|
<y>260</y>
|
||||||
|
<width>300</width>
|
||||||
|
<height>40</height>
|
||||||
|
</rect>
|
||||||
|
</property>
|
||||||
|
<property name="cursor">
|
||||||
|
<cursorShape>PointingHandCursor</cursorShape>
|
||||||
|
</property>
|
||||||
|
<property name="styleSheet">
|
||||||
|
<string notr="true">QPushButton {
|
||||||
|
color:rgb(212, 212, 212);
|
||||||
|
border-radius: 4px;
|
||||||
|
|
||||||
|
font-family: Lato;
|
||||||
|
font-style: normal;
|
||||||
|
font-weight: normal;
|
||||||
|
font-size: 16px;
|
||||||
|
line-height: 21px;
|
||||||
|
|
||||||
|
background: #100A44;
|
||||||
|
border-radius: 4px;
|
||||||
|
}
|
||||||
|
QPushButton:hover {
|
||||||
|
background: #211966;
|
||||||
|
}</string>
|
||||||
|
</property>
|
||||||
|
<property name="text">
|
||||||
|
<string>Share Server (FULL ACCESS)</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
<zorder>label_server_settings_wait_info</zorder>
|
<zorder>label_server_settings_wait_info</zorder>
|
||||||
<zorder>label_16</zorder>
|
<zorder>label_16</zorder>
|
||||||
<zorder>label_17</zorder>
|
<zorder>label_17</zorder>
|
||||||
|
|
@ -4539,6 +4663,7 @@ font-size: 20px;
|
||||||
<zorder>pushButton_server_settings_protocols</zorder>
|
<zorder>pushButton_server_settings_protocols</zorder>
|
||||||
<zorder>pushButton_back_from_server_settings</zorder>
|
<zorder>pushButton_back_from_server_settings</zorder>
|
||||||
<zorder>label_server_settings_current_vpn_protocol</zorder>
|
<zorder>label_server_settings_current_vpn_protocol</zorder>
|
||||||
|
<zorder>pushButton_server_settings_share_full</zorder>
|
||||||
</widget>
|
</widget>
|
||||||
<widget class="QWidget" name="page_server_protocols">
|
<widget class="QWidget" name="page_server_protocols">
|
||||||
<property name="styleSheet">
|
<property name="styleSheet">
|
||||||
|
|
@ -5284,7 +5409,30 @@ border-radius: 4px 0px 0px 4px;
|
||||||
</widget>
|
</widget>
|
||||||
<widget class="QWidget" name="page_share_connection">
|
<widget class="QWidget" name="page_share_connection">
|
||||||
<property name="styleSheet">
|
<property name="styleSheet">
|
||||||
<string notr="true"/>
|
<string notr="true">QScrollBar::sub-line:vertical { /* button to scroll up */
|
||||||
|
border-top-right-radius: 3px;
|
||||||
|
background-color: rgb(240,240,240);
|
||||||
|
height: 10px;
|
||||||
|
subcontrol-position: top;
|
||||||
|
subcontrol-origin: margin;
|
||||||
|
margin-top: 3px;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
QScrollBar::add-line:vertical { /* Button to scroll down */
|
||||||
|
border-bottom-right-radius: 3px;
|
||||||
|
background-color: rgb(240,240,240);
|
||||||
|
height: 10px;
|
||||||
|
padding-top: 2px;
|
||||||
|
subcontrol-position: bottom;
|
||||||
|
subcontrol-origin: margin;
|
||||||
|
margin-bottom: 3px;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
QScrollBar::add-page:vertical, QScrollBar::sub-page:vertical {
|
||||||
|
background-color: rgb(240,240,240);
|
||||||
|
}</string>
|
||||||
</property>
|
</property>
|
||||||
<widget class="QPushButton" name="pushButton_back_from_share">
|
<widget class="QPushButton" name="pushButton_back_from_share">
|
||||||
<property name="geometry">
|
<property name="geometry">
|
||||||
|
|
@ -5391,7 +5539,7 @@ QToolBox::tab:hover {
|
||||||
<number>0</number>
|
<number>0</number>
|
||||||
</property>
|
</property>
|
||||||
<property name="currentIndex">
|
<property name="currentIndex">
|
||||||
<number>1</number>
|
<number>0</number>
|
||||||
</property>
|
</property>
|
||||||
<property name="tabSpacing">
|
<property name="tabSpacing">
|
||||||
<number>6</number>
|
<number>6</number>
|
||||||
|
|
@ -5401,8 +5549,8 @@ QToolBox::tab:hover {
|
||||||
<rect>
|
<rect>
|
||||||
<x>0</x>
|
<x>0</x>
|
||||||
<y>0</y>
|
<y>0</y>
|
||||||
<width>100</width>
|
<width>360</width>
|
||||||
<height>30</height>
|
<height>360</height>
|
||||||
</rect>
|
</rect>
|
||||||
</property>
|
</property>
|
||||||
<property name="styleSheet">
|
<property name="styleSheet">
|
||||||
|
|
@ -5725,8 +5873,8 @@ background: #282932;
|
||||||
<rect>
|
<rect>
|
||||||
<x>0</x>
|
<x>0</x>
|
||||||
<y>0</y>
|
<y>0</y>
|
||||||
<width>100</width>
|
<width>360</width>
|
||||||
<height>30</height>
|
<height>360</height>
|
||||||
</rect>
|
</rect>
|
||||||
</property>
|
</property>
|
||||||
<attribute name="label">
|
<attribute name="label">
|
||||||
|
|
@ -5891,8 +6039,8 @@ background: #282932;
|
||||||
<rect>
|
<rect>
|
||||||
<x>0</x>
|
<x>0</x>
|
||||||
<y>0</y>
|
<y>0</y>
|
||||||
<width>100</width>
|
<width>360</width>
|
||||||
<height>30</height>
|
<height>360</height>
|
||||||
</rect>
|
</rect>
|
||||||
</property>
|
</property>
|
||||||
<property name="styleSheet">
|
<property name="styleSheet">
|
||||||
|
|
@ -6115,8 +6263,8 @@ color: #15CDCB;
|
||||||
<rect>
|
<rect>
|
||||||
<x>0</x>
|
<x>0</x>
|
||||||
<y>0</y>
|
<y>0</y>
|
||||||
<width>100</width>
|
<width>360</width>
|
||||||
<height>30</height>
|
<height>360</height>
|
||||||
</rect>
|
</rect>
|
||||||
</property>
|
</property>
|
||||||
<attribute name="label">
|
<attribute name="label">
|
||||||
|
|
|
||||||
72
client/ui/sites_model.cpp
Normal file
72
client/ui/sites_model.cpp
Normal file
|
|
@ -0,0 +1,72 @@
|
||||||
|
#include "sites_model.h"
|
||||||
|
|
||||||
|
SitesModel::SitesModel(Settings::RouteMode mode, QObject *parent)
|
||||||
|
: m_mode(mode),
|
||||||
|
QAbstractTableModel(parent)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
void SitesModel::resetCache()
|
||||||
|
{
|
||||||
|
beginResetModel();
|
||||||
|
m_ipsCache.clear();
|
||||||
|
m_cacheReady = false;
|
||||||
|
endResetModel();
|
||||||
|
}
|
||||||
|
|
||||||
|
QVariant SitesModel::headerData(int section, Qt::Orientation orientation, int role) const
|
||||||
|
{
|
||||||
|
// FIXME: Implement me!
|
||||||
|
return QVariant();
|
||||||
|
}
|
||||||
|
|
||||||
|
int SitesModel::rowCount(const QModelIndex &parent) const
|
||||||
|
{
|
||||||
|
if (!m_cacheReady) genCache();
|
||||||
|
return m_ipsCache.size();
|
||||||
|
}
|
||||||
|
|
||||||
|
int SitesModel::columnCount(const QModelIndex &parent) const
|
||||||
|
{
|
||||||
|
return 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
QVariant SitesModel::data(const QModelIndex &index, int role) const
|
||||||
|
{
|
||||||
|
if (!index.isValid())
|
||||||
|
return QVariant();
|
||||||
|
|
||||||
|
if (!m_cacheReady) genCache();
|
||||||
|
|
||||||
|
if (role == Qt::DisplayRole){
|
||||||
|
if (m_ipsCache.isEmpty()) return QVariant();
|
||||||
|
|
||||||
|
if (index.column() == 0) {
|
||||||
|
return m_ipsCache.at(index.row()).first;
|
||||||
|
}
|
||||||
|
if (index.column() == 1) {
|
||||||
|
return m_ipsCache.at(index.row()).second;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// if (role == Qt::TextAlignmentRole && index.column() == 1) {
|
||||||
|
// return Qt::AlignRight;
|
||||||
|
// }
|
||||||
|
|
||||||
|
return QVariant();
|
||||||
|
}
|
||||||
|
|
||||||
|
void SitesModel::genCache() const
|
||||||
|
{
|
||||||
|
qDebug() << "SitesModel::genCache";
|
||||||
|
m_ipsCache.clear();
|
||||||
|
|
||||||
|
const QVariantMap &sites = m_settings.vpnSites(m_mode);
|
||||||
|
auto i = sites.constBegin();
|
||||||
|
while (i != sites.constEnd()) {
|
||||||
|
m_ipsCache.append(qMakePair(i.key(), i.value().toString()));
|
||||||
|
++i;
|
||||||
|
}
|
||||||
|
|
||||||
|
m_cacheReady= true;
|
||||||
|
}
|
||||||
36
client/ui/sites_model.h
Normal file
36
client/ui/sites_model.h
Normal file
|
|
@ -0,0 +1,36 @@
|
||||||
|
#ifndef SITESMODEL_H
|
||||||
|
#define SITESMODEL_H
|
||||||
|
|
||||||
|
#include <QAbstractTableModel>
|
||||||
|
|
||||||
|
#include "settings.h"
|
||||||
|
|
||||||
|
class SitesModel : public QAbstractTableModel
|
||||||
|
{
|
||||||
|
Q_OBJECT
|
||||||
|
|
||||||
|
public:
|
||||||
|
explicit SitesModel(Settings::RouteMode mode, QObject *parent = nullptr);
|
||||||
|
void resetCache();
|
||||||
|
|
||||||
|
// Header:
|
||||||
|
QVariant headerData(int section, Qt::Orientation orientation, int role = Qt::DisplayRole) const override;
|
||||||
|
|
||||||
|
// Basic functionality:
|
||||||
|
int rowCount(const QModelIndex &parent = QModelIndex()) const override;
|
||||||
|
int columnCount(const QModelIndex &parent = QModelIndex()) const override;
|
||||||
|
|
||||||
|
QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const override;
|
||||||
|
|
||||||
|
private:
|
||||||
|
void genCache() const;
|
||||||
|
|
||||||
|
private:
|
||||||
|
Settings::RouteMode m_mode;
|
||||||
|
Settings m_settings;
|
||||||
|
|
||||||
|
mutable QVector<QPair<QString, QString>> m_ipsCache;
|
||||||
|
mutable bool m_cacheReady = false;
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif // SITESMODEL_H
|
||||||
|
|
@ -146,7 +146,7 @@ bool Utils::checkIPFormat(const QString& ip)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
QStringList list = ip.trimmed().split(".");
|
QStringList list = ip.trimmed().split(".");
|
||||||
foreach(QString it, list) {
|
for (const QString &it : list) {
|
||||||
if(it.toInt() <= 255 && it.toInt() >= 0)
|
if(it.toInt() <= 255 && it.toInt() >= 0)
|
||||||
continue;
|
continue;
|
||||||
return false;
|
return false;
|
||||||
|
|
@ -154,6 +154,18 @@ bool Utils::checkIPFormat(const QString& ip)
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool Utils::checkIpSubnetFormat(const QString &ip)
|
||||||
|
{
|
||||||
|
if (!ip.contains("/")) return checkIPFormat(ip);
|
||||||
|
|
||||||
|
QStringList parts = ip.split("/");
|
||||||
|
if (parts.size() != 2) return false;
|
||||||
|
|
||||||
|
bool ok;
|
||||||
|
if (parts.at(1).toInt(&ok) <= 32 && ok) return checkIPFormat(parts.at(0));
|
||||||
|
else return false;
|
||||||
|
}
|
||||||
|
|
||||||
void Utils::killProcessByName(const QString &name)
|
void Utils::killProcessByName(const QString &name)
|
||||||
{
|
{
|
||||||
qDebug().noquote() << "Kill process" << name;
|
qDebug().noquote() << "Kill process" << name;
|
||||||
|
|
@ -164,6 +176,28 @@ void Utils::killProcessByName(const QString &name)
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
QString Utils::netMaskFromIpWithSubnet(const QString ip)
|
||||||
|
{
|
||||||
|
if (!ip.contains("/")) return "255.255.255.255";
|
||||||
|
|
||||||
|
bool ok;
|
||||||
|
int prefix = ip.split("/").at(1).toInt(&ok);
|
||||||
|
if (!ok) return "255.255.255.255";
|
||||||
|
|
||||||
|
unsigned long mask = (0xFFFFFFFF << (32 - prefix)) & 0xFFFFFFFF;
|
||||||
|
|
||||||
|
return QString("%1.%2.%3.%4")
|
||||||
|
.arg(mask >> 24)
|
||||||
|
.arg((mask >> 16) & 0xFF)
|
||||||
|
.arg((mask >> 8) & 0xFF)
|
||||||
|
.arg( mask & 0xFF);
|
||||||
|
}
|
||||||
|
|
||||||
|
QString Utils::ipAddressFromIpWithSubnet(const QString ip)
|
||||||
|
{
|
||||||
|
return ip.split("/").first();
|
||||||
|
}
|
||||||
|
|
||||||
#ifdef Q_OS_WIN
|
#ifdef Q_OS_WIN
|
||||||
// Inspired from http://stackoverflow.com/a/15281070/1529139
|
// Inspired from http://stackoverflow.com/a/15281070/1529139
|
||||||
// and http://stackoverflow.com/q/40059902/1529139
|
// and http://stackoverflow.com/q/40059902/1529139
|
||||||
|
|
|
||||||
|
|
@ -23,10 +23,14 @@ public:
|
||||||
static QString getIPAddress(const QString& host);
|
static QString getIPAddress(const QString& host);
|
||||||
static QString getStringBetween(const QString& s, const QString& a, const QString& b);
|
static QString getStringBetween(const QString& s, const QString& a, const QString& b);
|
||||||
static bool checkIPFormat(const QString& ip);
|
static bool checkIPFormat(const QString& ip);
|
||||||
|
static bool checkIpSubnetFormat(const QString& ip);
|
||||||
static QRegExp ipAddressRegExp() { return QRegExp("^((25[0-5]|(2[0-4]|1[0-9]|[1-9]|)[0-9])(\\.(?!$)|$)){4}$"); }
|
static QRegExp ipAddressRegExp() { return QRegExp("^((25[0-5]|(2[0-4]|1[0-9]|[1-9]|)[0-9])(\\.(?!$)|$)){4}$"); }
|
||||||
static QRegExp ipAddressPortRegExp() { return QRegExp("^(?:(?:25[0-5]|2[0-4][0-9]|1[0-9][0-9]|[1-9][0-9]|[0-9])\\.){3}"
|
static QRegExp ipAddressPortRegExp() { return QRegExp("^(?:(?:25[0-5]|2[0-4][0-9]|1[0-9][0-9]|[1-9][0-9]|[0-9])\\.){3}"
|
||||||
"(?:25[0-5]|2[0-4][0-9]|1[0-9][0-9]|[1-9][0-9]|[0-9])(\\:[0-9]{1,5}){0,1}$"); }
|
"(?:25[0-5]|2[0-4][0-9]|1[0-9][0-9]|[1-9][0-9]|[0-9])(\\:[0-9]{1,5}){0,1}$"); }
|
||||||
|
|
||||||
|
static QRegExp ipAddressWithSubnetRegExp() { return QRegExp("(?:(?:25[0-5]|2[0-4][0-9]|1[0-9][0-9]|[1-9][0-9]|[0-9])\\.){3}"
|
||||||
|
"(?:25[0-5]|2[0-4][0-9]|1[0-9][0-9]|[1-9][0-9]|[0-9])(\\/[0-9]{1,2}){0,1}"); }
|
||||||
|
|
||||||
static QRegExp ipNetwork24RegExp() { return QRegExp("^(?:(?:25[0-5]|2[0-4][0-9]|1[0-9][0-9]|[1-9][0-9]|[0-9])\\.){3}"
|
static QRegExp ipNetwork24RegExp() { return QRegExp("^(?:(?:25[0-5]|2[0-4][0-9]|1[0-9][0-9]|[1-9][0-9]|[0-9])\\.){3}"
|
||||||
"0$"); }
|
"0$"); }
|
||||||
|
|
||||||
|
|
@ -35,6 +39,9 @@ public:
|
||||||
static bool processIsRunning(const QString& fileName);
|
static bool processIsRunning(const QString& fileName);
|
||||||
static void killProcessByName(const QString &name);
|
static void killProcessByName(const QString &name);
|
||||||
|
|
||||||
|
static QString netMaskFromIpWithSubnet(const QString ip);
|
||||||
|
static QString ipAddressFromIpWithSubnet(const QString ip);
|
||||||
|
|
||||||
#ifdef Q_OS_WIN
|
#ifdef Q_OS_WIN
|
||||||
static bool signalCtrl(DWORD dwProcessId, DWORD dwCtrlEvent);
|
static bool signalCtrl(DWORD dwProcessId, DWORD dwCtrlEvent);
|
||||||
#endif
|
#endif
|
||||||
|
|
|
||||||
|
|
@ -43,22 +43,22 @@ void VpnConnection::onConnectionStateChanged(VpnProtocol::ConnectionState state)
|
||||||
if (state == VpnProtocol::ConnectionState::Connected && IpcClient::Interface()){
|
if (state == VpnProtocol::ConnectionState::Connected && IpcClient::Interface()){
|
||||||
IpcClient::Interface()->flushDns();
|
IpcClient::Interface()->flushDns();
|
||||||
|
|
||||||
if (m_settings.customRouting()) {
|
if (m_settings.routeMode() == Settings::VpnOnlyForwardSites) {
|
||||||
IpcClient::Interface()->routeDelete("0.0.0.0", m_vpnProtocol->vpnGateway());
|
IpcClient::Interface()->routeDelete("0.0.0.0", m_vpnProtocol->vpnGateway());
|
||||||
|
|
||||||
IpcClient::Interface()->routeAddList(m_vpnProtocol->vpnGateway(),
|
IpcClient::Interface()->routeAddList(m_vpnProtocol->vpnGateway(),
|
||||||
QStringList() << m_settings.primaryDns() << m_settings.secondaryDns());
|
QStringList() << m_settings.primaryDns() << m_settings.secondaryDns());
|
||||||
|
|
||||||
const QStringList &black_custom = m_settings.customIps();
|
const QStringList &forwardIps = m_settings.getVpnIps(Settings::VpnOnlyForwardSites);
|
||||||
qDebug() << "VpnConnection::onConnectionStateChanged :: adding custom routes, count:" << black_custom.size();
|
qDebug() << "VpnConnection::onConnectionStateChanged :: adding custom routes, count:" << forwardIps.size();
|
||||||
|
|
||||||
IpcClient::Interface()->routeAddList(m_vpnProtocol->vpnGateway(), black_custom);
|
IpcClient::Interface()->routeAddList(m_vpnProtocol->vpnGateway(), forwardIps);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (state == VpnProtocol::ConnectionState::Error) {
|
else if (state == VpnProtocol::ConnectionState::Error) {
|
||||||
IpcClient::Interface()->flushDns();
|
IpcClient::Interface()->flushDns();
|
||||||
|
|
||||||
if (m_settings.customRouting()) {
|
if (m_settings.routeMode() == Settings::VpnOnlyForwardSites) {
|
||||||
IpcClient::Interface()->clearSavedRoutes();
|
IpcClient::Interface()->clearSavedRoutes();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -199,7 +199,7 @@ ErrorCode VpnConnection::createVpnConfiguration(int serverIndex,
|
||||||
|
|
||||||
ErrorCode VpnConnection::connectToVpn(int serverIndex, const ServerCredentials &credentials, DockerContainer container, const QJsonObject &containerConfig)
|
ErrorCode VpnConnection::connectToVpn(int serverIndex, const ServerCredentials &credentials, DockerContainer container, const QJsonObject &containerConfig)
|
||||||
{
|
{
|
||||||
qDebug() << "СonnectToVpn, CustomRouting is" << m_settings.customRouting();
|
qDebug() << "СonnectToVpn, Route mode is" << m_settings.routeMode();
|
||||||
|
|
||||||
emit connectionStateChanged(VpnProtocol::ConnectionState::Connecting);
|
emit connectionStateChanged(VpnProtocol::ConnectionState::Connecting);
|
||||||
|
|
||||||
|
|
@ -276,7 +276,7 @@ void VpnConnection::disconnectFromVpn()
|
||||||
if (IpcClient::Interface()) {
|
if (IpcClient::Interface()) {
|
||||||
IpcClient::Interface()->flushDns();
|
IpcClient::Interface()->flushDns();
|
||||||
|
|
||||||
if (m_settings.customRouting()) {
|
if (m_settings.routeMode() == Settings::VpnOnlyForwardSites) {
|
||||||
IpcClient::Interface()->clearSavedRoutes();
|
IpcClient::Interface()->clearSavedRoutes();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -7,7 +7,7 @@ class IpcInterface
|
||||||
//SIGNAL(sendMessage(const QByteArray &message));
|
//SIGNAL(sendMessage(const QByteArray &message));
|
||||||
|
|
||||||
// Route functions
|
// Route functions
|
||||||
SLOT( bool routeAdd(const QString &ip, const QString &gw, const QString &mask) );
|
SLOT( bool routeAdd(const QString &ip, const QString &gw) );
|
||||||
SLOT( int routeAddList(const QString &gw, const QStringList &ips) );
|
SLOT( int routeAddList(const QString &gw, const QStringList &ips) );
|
||||||
SLOT( bool clearSavedRoutes() );
|
SLOT( bool clearSavedRoutes() );
|
||||||
SLOT( bool routeDelete(const QString &ip, const QString &gw) );
|
SLOT( bool routeDelete(const QString &ip, const QString &gw) );
|
||||||
|
|
|
||||||
|
|
@ -53,9 +53,9 @@ int IpcServer::createPrivilegedProcess()
|
||||||
return m_localpid;
|
return m_localpid;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool IpcServer::routeAdd(const QString &ip, const QString &gw, const QString &mask)
|
bool IpcServer::routeAdd(const QString &ip, const QString &gw)
|
||||||
{
|
{
|
||||||
return Router::routeAdd(ip, gw, mask);
|
return Router::routeAdd(ip, gw);
|
||||||
}
|
}
|
||||||
|
|
||||||
int IpcServer::routeAddList(const QString &gw, const QStringList &ips)
|
int IpcServer::routeAddList(const QString &gw, const QStringList &ips)
|
||||||
|
|
|
||||||
|
|
@ -15,7 +15,7 @@ public:
|
||||||
explicit IpcServer(QObject *parent = nullptr);
|
explicit IpcServer(QObject *parent = nullptr);
|
||||||
virtual int createPrivilegedProcess() override;
|
virtual int createPrivilegedProcess() override;
|
||||||
|
|
||||||
virtual bool routeAdd(const QString &ip, const QString &gw, const QString &mask = QString()) override;
|
virtual bool routeAdd(const QString &ip, const QString &gw) override;
|
||||||
virtual int routeAddList(const QString &gw, const QStringList &ips) override;
|
virtual int routeAddList(const QString &gw, const QStringList &ips) override;
|
||||||
virtual bool clearSavedRoutes() override;
|
virtual bool clearSavedRoutes() override;
|
||||||
virtual bool routeDelete(const QString &ip, const QString &gw) override;
|
virtual bool routeDelete(const QString &ip, const QString &gw) override;
|
||||||
|
|
|
||||||
|
|
@ -7,12 +7,12 @@
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
bool Router::routeAdd(const QString &ip, const QString &gw, QString mask)
|
bool Router::routeAdd(const QString &ip, const QString &gw)
|
||||||
{
|
{
|
||||||
#ifdef Q_OS_WIN
|
#ifdef Q_OS_WIN
|
||||||
return RouterWin::Instance().routeAdd(ip, gw, mask);
|
return RouterWin::Instance().routeAdd(ip, gw);
|
||||||
#elif defined (Q_OS_MAC)
|
#elif defined (Q_OS_MAC)
|
||||||
return RouterMac::Instance().routeAdd(ip, gw, mask);
|
return RouterMac::Instance().routeAdd(ip, gw);
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -15,7 +15,7 @@ class Router : public QObject
|
||||||
{
|
{
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
public:
|
public:
|
||||||
static bool routeAdd(const QString &ip, const QString &gw, QString mask = QString());
|
static bool routeAdd(const QString &ip, const QString &gw);
|
||||||
static int routeAddList(const QString &gw, const QStringList &ips);
|
static int routeAddList(const QString &gw, const QStringList &ips);
|
||||||
static bool clearSavedRoutes();
|
static bool clearSavedRoutes();
|
||||||
static bool routeDelete(const QString &ip, const QString &gw);
|
static bool routeDelete(const QString &ip, const QString &gw);
|
||||||
|
|
|
||||||
|
|
@ -9,7 +9,7 @@ RouterMac &RouterMac::Instance()
|
||||||
return s;
|
return s;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool RouterMac::routeAdd(const QString &ip, const QString &gw, QString mask)
|
bool RouterMac::routeAdd(const QString &ip, const QString &gw)
|
||||||
{
|
{
|
||||||
int argc = 5;
|
int argc = 5;
|
||||||
char **argv = new char*[argc];
|
char **argv = new char*[argc];
|
||||||
|
|
|
||||||
|
|
@ -18,7 +18,7 @@ class RouterMac : public QObject
|
||||||
public:
|
public:
|
||||||
static RouterMac& Instance();
|
static RouterMac& Instance();
|
||||||
|
|
||||||
bool routeAdd(const QString &ip, const QString &gw, QString mask = QString());
|
bool routeAdd(const QString &ip, const QString &gw);
|
||||||
int routeAddList(const QString &gw, const QStringList &ips);
|
int routeAddList(const QString &gw, const QStringList &ips);
|
||||||
bool clearSavedRoutes();
|
bool clearSavedRoutes();
|
||||||
bool routeDelete(const QString &ip, const QString &gw);
|
bool routeDelete(const QString &ip, const QString &gw);
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,5 @@
|
||||||
#include "router_win.h"
|
#include "router_win.h"
|
||||||
|
#include "../client/utils.h"
|
||||||
|
|
||||||
#include <QProcess>
|
#include <QProcess>
|
||||||
|
|
||||||
|
|
@ -8,20 +9,11 @@ RouterWin &RouterWin::Instance()
|
||||||
return s;
|
return s;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool RouterWin::routeAdd(const QString &ip, const QString &gw, QString mask)
|
bool RouterWin::routeAdd(const QString &ip, const QString &gw)
|
||||||
{
|
{
|
||||||
qDebug().noquote() << QString("ROUTE ADD: IP:%1 %2 GW %3")
|
//qDebug().noquote() << QString("ROUTE ADD: IP:%1 GW %2").arg(ip).arg(gw);
|
||||||
.arg(ip)
|
|
||||||
.arg(mask)
|
|
||||||
.arg(gw);
|
|
||||||
|
|
||||||
if (mask == "") {
|
|
||||||
mask = "255.255.255.255";
|
|
||||||
if (ip.endsWith(".0")) mask = "255.255.255.0";
|
|
||||||
if (ip.endsWith(".0.0")) mask = "255.255.0.0";
|
|
||||||
if (ip.endsWith(".0.0.0")) mask = "255.0.0.0";
|
|
||||||
}
|
|
||||||
|
|
||||||
|
QString mask = Utils::netMaskFromIpWithSubnet(ip);
|
||||||
|
|
||||||
PMIB_IPFORWARDTABLE pIpForwardTable = NULL;
|
PMIB_IPFORWARDTABLE pIpForwardTable = NULL;
|
||||||
MIB_IPFORWARDROW ipfrow;
|
MIB_IPFORWARDROW ipfrow;
|
||||||
|
|
@ -58,7 +50,7 @@ bool RouterWin::routeAdd(const QString &ip, const QString &gw, QString mask)
|
||||||
}
|
}
|
||||||
|
|
||||||
// address
|
// address
|
||||||
ipfrow.dwForwardDest = inet_addr(ip.toStdString().c_str());
|
ipfrow.dwForwardDest = inet_addr(Utils::ipAddressFromIpWithSubnet(ip).toStdString().c_str());
|
||||||
|
|
||||||
// mask
|
// mask
|
||||||
in_addr maskAddr;
|
in_addr maskAddr;
|
||||||
|
|
@ -109,12 +101,12 @@ bool RouterWin::routeAdd(const QString &ip, const QString &gw, QString mask)
|
||||||
|
|
||||||
int RouterWin::routeAddList(const QString &gw, const QStringList &ips)
|
int RouterWin::routeAddList(const QString &gw, const QStringList &ips)
|
||||||
{
|
{
|
||||||
qDebug().noquote() << QString("ROUTE ADD List: IPs size:%1, GW: %2")
|
// qDebug().noquote() << QString("ROUTE ADD List: IPs size:%1, GW: %2")
|
||||||
.arg(ips.size())
|
// .arg(ips.size())
|
||||||
.arg(gw);
|
// .arg(gw);
|
||||||
|
|
||||||
qDebug().noquote() << QString("ROUTE ADD List: IPs:\n%1")
|
// qDebug().noquote() << QString("ROUTE ADD List: IPs:\n%1")
|
||||||
.arg(ips.join("\n"));
|
// .arg(ips.join("\n"));
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -188,15 +180,10 @@ int RouterWin::routeAddList(const QString &gw, const QStringList &ips)
|
||||||
for (int i = 0; i < ips.size(); ++i) {
|
for (int i = 0; i < ips.size(); ++i) {
|
||||||
QString ip = ips.at(i);
|
QString ip = ips.at(i);
|
||||||
if (ip.isEmpty()) continue;
|
if (ip.isEmpty()) continue;
|
||||||
|
QString mask = Utils::netMaskFromIpWithSubnet(ip);
|
||||||
mask = "255.255.255.255";
|
|
||||||
if (ip.endsWith(".0")) mask = "255.255.255.0";
|
|
||||||
if (ip.endsWith(".0.0")) mask = "255.255.0.0";
|
|
||||||
if (ip.endsWith(".0.0.0")) mask = "255.0.0.0";
|
|
||||||
|
|
||||||
// address
|
// address
|
||||||
ipfrow.dwForwardDest = inet_addr(ip.toStdString().c_str());
|
ipfrow.dwForwardDest = inet_addr(Utils::ipAddressFromIpWithSubnet(ip).toStdString().c_str());
|
||||||
|
|
||||||
|
|
||||||
// mask
|
// mask
|
||||||
in_addr maskAddr;
|
in_addr maskAddr;
|
||||||
|
|
@ -280,7 +267,7 @@ bool RouterWin::routeDelete(const QString &ip, const QString &gw)
|
||||||
|
|
||||||
QProcess p;
|
QProcess p;
|
||||||
p.setProcessChannelMode(QProcess::MergedChannels);
|
p.setProcessChannelMode(QProcess::MergedChannels);
|
||||||
QString command = QString("route delete %1 %2").arg(ip).arg(gw);
|
QString command = QString("route delete %1 %2").arg(Utils::ipAddressFromIpWithSubnet(ip)).arg(gw);
|
||||||
|
|
||||||
p.start(command);
|
p.start(command);
|
||||||
p.waitForFinished();
|
p.waitForFinished();
|
||||||
|
|
|
||||||
|
|
@ -38,7 +38,7 @@ class RouterWin : public QObject
|
||||||
public:
|
public:
|
||||||
static RouterWin& Instance();
|
static RouterWin& Instance();
|
||||||
|
|
||||||
bool routeAdd(const QString &ip, const QString &gw, QString mask = QString());
|
bool routeAdd(const QString &ip, const QString &gw);
|
||||||
int routeAddList(const QString &gw, const QStringList &ips);
|
int routeAddList(const QString &gw, const QStringList &ips);
|
||||||
bool clearSavedRoutes();
|
bool clearSavedRoutes();
|
||||||
bool routeDelete(const QString &ip, const QString &gw);
|
bool routeDelete(const QString &ip, const QString &gw);
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue