Bug fixes:
- auto install tap - share connectionState - service crash fix
This commit is contained in:
parent
a50cdd5bc2
commit
953eca6695
25 changed files with 919 additions and 89 deletions
|
@ -14,14 +14,13 @@ HEADERS += \
|
|||
core/defs.h \
|
||||
core/errorstrings.h \
|
||||
core/openvpnconfigurator.h \
|
||||
core/router.h \
|
||||
core/servercontroller.h \
|
||||
debug.h \
|
||||
defines.h \
|
||||
localclient.h \
|
||||
managementserver.h \
|
||||
message.h \
|
||||
protocols/shadowsocksvpnprotocol.h \
|
||||
protocols/shadowsocksvpnprotocol.h \
|
||||
runguard.h \
|
||||
settings.h \
|
||||
ui/Controls/SlidingStackedWidget.h \
|
||||
|
@ -34,14 +33,13 @@ HEADERS += \
|
|||
SOURCES += \
|
||||
communicator.cpp \
|
||||
core/openvpnconfigurator.cpp \
|
||||
core/router.cpp \
|
||||
core/servercontroller.cpp \
|
||||
debug.cpp \
|
||||
localclient.cpp \
|
||||
main.cpp \
|
||||
managementserver.cpp \
|
||||
message.cpp \
|
||||
protocols/shadowsocksvpnprotocol.cpp \
|
||||
protocols/shadowsocksvpnprotocol.cpp \
|
||||
runguard.cpp \
|
||||
settings.cpp \
|
||||
ui/Controls/SlidingStackedWidget.cpp \
|
||||
|
|
|
@ -72,5 +72,8 @@ void Communicator::sendMessage(const Message& message)
|
|||
const QString data = message.toString();
|
||||
bool status = writeData(data + "\n");
|
||||
|
||||
qDebug().noquote() << QString("Send message '%1', status '%2'").arg(data).arg(Utils::toString(status));
|
||||
qDebug().noquote() << QString("Send message '%1',%2 status '%2'").
|
||||
arg(static_cast<int>(message.state())).
|
||||
arg(data).
|
||||
arg(Utils::toString(status));
|
||||
}
|
||||
|
|
|
@ -22,12 +22,22 @@ QString Message::textState() const
|
|||
case State::Started: return "Started";
|
||||
case State::FinishRequest: return "FinishRequest";
|
||||
case State::Finished: return "Finished";
|
||||
case State::RoutesAddRequest: return "RoutesAddRequest";
|
||||
case State::RouteDeleteRequest: return "RouteDeleteRequest";
|
||||
case State::ClearSavedRoutesRequest: return "ClearSavedRoutesRequest";
|
||||
case State::FlushDnsRequest: return "FlushDnsRequest";
|
||||
case State::InstallDriverRequest: return "InstallDriverRequest";
|
||||
default:
|
||||
;
|
||||
}
|
||||
return QString();
|
||||
}
|
||||
|
||||
QString Message::rawData() const
|
||||
{
|
||||
return m_rawData;
|
||||
}
|
||||
|
||||
Message::State Message::state() const
|
||||
{
|
||||
return m_state;
|
||||
|
@ -66,6 +76,7 @@ QString Message::argsToString() const
|
|||
|
||||
Message::Message(const QString& data)
|
||||
{
|
||||
m_rawData = data;
|
||||
m_valid = false;
|
||||
if (data.isEmpty()) {
|
||||
return;
|
||||
|
@ -77,7 +88,7 @@ Message::Message(const QString& data)
|
|||
}
|
||||
|
||||
bool stateFound = false;
|
||||
for (int i = static_cast<int>(State::Unknown); i <= static_cast<int>(State::Finished); i++ ) {
|
||||
for (int i = static_cast<int>(State::Unknown); i <= static_cast<int>(State::InstallDriverRequest); i++ ) {
|
||||
m_state = static_cast<State>(i);
|
||||
if (textState() == dataList.at(0)) {
|
||||
stateFound = true;
|
||||
|
|
|
@ -6,7 +6,8 @@
|
|||
class Message {
|
||||
|
||||
public:
|
||||
enum class State {Unknown, Initialize, StartRequest, Started, FinishRequest, Finished};
|
||||
enum class State {Unknown, Initialize, StartRequest, Started, FinishRequest, Finished,
|
||||
RoutesAddRequest, RouteDeleteRequest, ClearSavedRoutesRequest, FlushDnsRequest, InstallDriverRequest};
|
||||
Message(State state, const QStringList& args);
|
||||
Message(const QString& data);
|
||||
|
||||
|
@ -16,6 +17,7 @@ public:
|
|||
QStringList args() const;
|
||||
State state() const;
|
||||
bool isValid() const;
|
||||
QString rawData() const;
|
||||
|
||||
protected:
|
||||
QString textState() const;
|
||||
|
@ -26,6 +28,7 @@ protected:
|
|||
bool m_valid;
|
||||
State m_state;
|
||||
QStringList m_args;
|
||||
QString m_rawData;
|
||||
};
|
||||
|
||||
#endif // MESSAGE_H
|
||||
|
|
|
@ -1,5 +1,7 @@
|
|||
#include <QCoreApplication>
|
||||
#include <QFileInfo>
|
||||
#include <QProcess>
|
||||
#include <QRegularExpression>
|
||||
#include <QTcpSocket>
|
||||
|
||||
#include "communicator.h"
|
||||
|
@ -106,6 +108,15 @@ void OpenVpnProtocol::writeCommand(const QString& command)
|
|||
}
|
||||
}
|
||||
|
||||
void OpenVpnProtocol::updateRouteGateway(QString line)
|
||||
{
|
||||
line = line.split("ROUTE_GATEWAY", QString::SkipEmptyParts).at(1);
|
||||
if (!line.contains("/")) return;
|
||||
m_routeGateway = line.split("/", QString::SkipEmptyParts).first();
|
||||
m_routeGateway.replace(" ", "");
|
||||
qDebug() << "Set VPN route gateway" << m_routeGateway;
|
||||
}
|
||||
|
||||
QString OpenVpnProtocol::openVpnExecPath() const
|
||||
{
|
||||
#ifdef Q_OS_WIN
|
||||
|
@ -209,6 +220,7 @@ void OpenVpnProtocol::onReadyReadDataFromManagementServer()
|
|||
if (line.contains("CONNECTED,SUCCESS")) {
|
||||
sendByteCount();
|
||||
stopTimeoutTimer();
|
||||
updateVpnGateway();
|
||||
setConnectionState(VpnProtocol::ConnectionState::Connected);
|
||||
continue;
|
||||
} else if (line.contains("EXITING,SIGTER")) {
|
||||
|
@ -220,6 +232,10 @@ void OpenVpnProtocol::onReadyReadDataFromManagementServer()
|
|||
}
|
||||
}
|
||||
|
||||
if (line.contains("ROUTE_GATEWAY")) {
|
||||
updateRouteGateway(line);
|
||||
}
|
||||
|
||||
if (line.contains("FATAL")) {
|
||||
if (line.contains("tap-windows6 adapters on this system are currently in use or disabled")) {
|
||||
emit protocolError(ErrorCode::OpenVpnAdaptersInUseError);
|
||||
|
@ -259,4 +275,46 @@ void OpenVpnProtocol::onOpenVpnProcessFinished(int exitCode)
|
|||
setConnectionState(VpnProtocol::ConnectionState::Disconnected);
|
||||
}
|
||||
|
||||
void OpenVpnProtocol::updateVpnGateway()
|
||||
{
|
||||
QProcess ipconfig;
|
||||
ipconfig.start("ipconfig", QStringList() << "/all");
|
||||
ipconfig.waitForStarted();
|
||||
ipconfig.waitForFinished();
|
||||
|
||||
QString d = ipconfig.readAll();
|
||||
d.replace("\r", "");
|
||||
//qDebug().noquote() << d;
|
||||
|
||||
QStringList adapters = d.split(":\n");
|
||||
|
||||
bool isTapV9Present = false;
|
||||
QString tapV9;
|
||||
for (int i = 0; i < adapters.size(); ++i) {
|
||||
if (adapters.at(i).contains("TAP-Windows Adapter V9")) {
|
||||
isTapV9Present = true;
|
||||
tapV9 = adapters.at(i);
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!isTapV9Present) {
|
||||
m_vpnGateway = "";
|
||||
}
|
||||
|
||||
QStringList lines = tapV9.split("\n");
|
||||
for (int i = 0; i < lines.size(); ++i) {
|
||||
if (!lines.at(i).contains("DHCP")) continue;
|
||||
|
||||
QRegularExpression re("(: )([\\d\\.]+)($)");
|
||||
QRegularExpressionMatch match = re.match(lines.at(i));
|
||||
|
||||
if (match.hasMatch()) {
|
||||
qDebug().noquote() << "Current VPN Gateway IP Address: " << match.captured(0);
|
||||
m_vpnGateway = match.captured(2);
|
||||
return;
|
||||
}
|
||||
else continue;
|
||||
}
|
||||
|
||||
m_vpnGateway = "";
|
||||
}
|
||||
|
|
|
@ -46,6 +46,11 @@ protected:
|
|||
QString m_configFileName;
|
||||
QTimer m_openVpnStateSigTermHandlerTimer;
|
||||
bool m_requestFromUserToStop;
|
||||
|
||||
|
||||
private:
|
||||
void updateRouteGateway(QString line);
|
||||
void updateVpnGateway();
|
||||
};
|
||||
|
||||
#endif // OPENVPNPROTOCOL_H
|
||||
|
|
|
@ -94,6 +94,16 @@ void VpnProtocol::setConnectionState(VpnProtocol::ConnectionState state)
|
|||
emit connectionStateChanged(m_connectionState);
|
||||
}
|
||||
|
||||
QString VpnProtocol::vpnGateway() const
|
||||
{
|
||||
return m_vpnGateway;
|
||||
}
|
||||
|
||||
QString VpnProtocol::routeGateway() const
|
||||
{
|
||||
return m_routeGateway;
|
||||
}
|
||||
|
||||
QString VpnProtocol::textConnectionState(ConnectionState connectionState)
|
||||
{
|
||||
switch (connectionState) {
|
||||
|
|
|
@ -35,6 +35,9 @@ public:
|
|||
QString textConnectionState() const;
|
||||
void setLastError(ErrorCode lastError);
|
||||
|
||||
QString routeGateway() const;
|
||||
QString vpnGateway() const;
|
||||
|
||||
signals:
|
||||
void bytesChanged(quint64 receivedBytes, quint64 sentBytes);
|
||||
void connectionStateChanged(VpnProtocol::ConnectionState state);
|
||||
|
@ -54,12 +57,15 @@ protected:
|
|||
static Communicator* m_communicator;
|
||||
|
||||
ConnectionState m_connectionState;
|
||||
QString m_routeGateway;
|
||||
QString m_vpnGateway;
|
||||
|
||||
private:
|
||||
QTimer* m_timeoutTimer;
|
||||
ErrorCode m_lastError;
|
||||
quint64 m_receivedBytes;
|
||||
quint64 m_sentBytes;
|
||||
|
||||
};
|
||||
|
||||
#endif // VPNPROTOCOL_H
|
||||
|
|
|
@ -1,32 +1,32 @@
|
|||
#include <QSettings>
|
||||
|
||||
#include "defines.h"
|
||||
#include "settings.h"
|
||||
|
||||
Settings::Settings(QObject* parent) : QObject(parent)
|
||||
Settings::Settings(QObject* parent) :
|
||||
QObject(parent),
|
||||
m_settings (ORGANIZATION_NAME, APPLICATION_NAME, this)
|
||||
{
|
||||
m_settings = new QSettings(ORGANIZATION_NAME, APPLICATION_NAME, this);
|
||||
read();
|
||||
}
|
||||
|
||||
void Settings::read()
|
||||
{
|
||||
m_settings->beginGroup("Server");
|
||||
m_userName = m_settings->value("userName", QString()).toString();
|
||||
m_password = m_settings->value("password", QString()).toString();
|
||||
m_serverName = m_settings->value("serverName", QString()).toString();
|
||||
m_serverPort = m_settings->value("serverPort", 22).toInt();
|
||||
m_settings->endGroup();
|
||||
m_settings.beginGroup("Server");
|
||||
m_userName = m_settings.value("userName", QString()).toString();
|
||||
m_password = m_settings.value("password", QString()).toString();
|
||||
m_serverName = m_settings.value("serverName", QString()).toString();
|
||||
m_serverPort = m_settings.value("serverPort", 22).toInt();
|
||||
m_settings.endGroup();
|
||||
}
|
||||
|
||||
void Settings::save()
|
||||
{
|
||||
m_settings->beginGroup("Server");
|
||||
m_settings->setValue("userName", m_userName);
|
||||
m_settings->setValue("password", m_password);
|
||||
m_settings->setValue("serverName", m_serverName);
|
||||
m_settings->setValue("serverPort", m_serverPort);
|
||||
m_settings->endGroup();
|
||||
m_settings.beginGroup("Server");
|
||||
m_settings.setValue("userName", m_userName);
|
||||
m_settings.setValue("password", m_password);
|
||||
m_settings.setValue("serverName", m_serverName);
|
||||
m_settings.setValue("serverPort", m_serverPort);
|
||||
m_settings.endGroup();
|
||||
}
|
||||
|
||||
bool Settings::haveAuthData() const
|
||||
|
|
|
@ -3,6 +3,7 @@
|
|||
|
||||
#include <QObject>
|
||||
#include <QString>
|
||||
#include <QSettings>
|
||||
|
||||
#include "core/defs.h"
|
||||
|
||||
|
@ -35,8 +36,18 @@ public:
|
|||
|
||||
bool haveAuthData() const;
|
||||
|
||||
|
||||
// list of sites to pass blocking added by user
|
||||
QStringList customSites() { return m_settings.value("customSites").toStringList(); }
|
||||
void setCustomSites(const QStringList &customSites) { m_settings.setValue("customSites", customSites); }
|
||||
|
||||
// list of ips to pass blocking generated from customSites
|
||||
QStringList customIps() { return m_settings.value("customIps").toStringList(); }
|
||||
void setCustomIps(const QStringList &customIps) { m_settings.setValue("customIps", customIps); }
|
||||
|
||||
|
||||
protected:
|
||||
QSettings* m_settings;
|
||||
QSettings m_settings;
|
||||
QString m_userName;
|
||||
QString m_password;
|
||||
QString m_serverName;
|
||||
|
|
|
@ -1,5 +1,8 @@
|
|||
#include <QApplication>
|
||||
#include <QClipboard>
|
||||
#include <QDesktopServices>
|
||||
#include <QJsonDocument>
|
||||
#include <QJsonObject>
|
||||
#include <QKeyEvent>
|
||||
#include <QMenu>
|
||||
#include <QMessageBox>
|
||||
|
@ -17,7 +20,6 @@
|
|||
#include "debug.h"
|
||||
#include "defines.h"
|
||||
#include "mainwindow.h"
|
||||
#include "settings.h"
|
||||
#include "ui_mainwindow.h"
|
||||
#include "utils.h"
|
||||
#include "vpnconnection.h"
|
||||
|
@ -33,8 +35,7 @@ MainWindow::MainWindow(QWidget *parent) :
|
|||
QMainWindow(parent),
|
||||
#endif
|
||||
ui(new Ui::MainWindow),
|
||||
m_vpnConnection(nullptr),
|
||||
m_settings(new Settings)
|
||||
m_vpnConnection(nullptr)
|
||||
{
|
||||
ui->setupUi(this);
|
||||
ui->label_error_text->clear();
|
||||
|
@ -43,8 +44,6 @@ MainWindow::MainWindow(QWidget *parent) :
|
|||
ui->stackedWidget_main->setSpeed(200);
|
||||
ui->stackedWidget_main->setAnimation(QEasingCurve::Linear);
|
||||
|
||||
ui->pushButton_blocked_list->setEnabled(false);
|
||||
ui->pushButton_share_connection->setEnabled(false);
|
||||
#ifdef Q_OS_MAC
|
||||
ui->widget_tittlebar->hide();
|
||||
ui->stackedWidget_main->move(0,0);
|
||||
|
@ -53,7 +52,7 @@ MainWindow::MainWindow(QWidget *parent) :
|
|||
|
||||
// Post initialization
|
||||
|
||||
if (m_settings->haveAuthData()) {
|
||||
if (m_settings.haveAuthData()) {
|
||||
goToPage(Page::Vpn, true, false);
|
||||
} else {
|
||||
goToPage(Page::Start, true, false);
|
||||
|
@ -62,12 +61,20 @@ MainWindow::MainWindow(QWidget *parent) :
|
|||
setupTray();
|
||||
setupUiConnections();
|
||||
|
||||
customSitesModel = new QStringListModel();
|
||||
ui->listView_sites_custom->setModel(customSitesModel);
|
||||
|
||||
connect(ui->listView_sites_custom, &QListView::doubleClicked, [&](const QModelIndex &index){
|
||||
QDesktopServices::openUrl("https://" + index.data().toString());
|
||||
});
|
||||
connect(ui->lineEdit_sites_add_custom, &QLineEdit::returnPressed, [&](){
|
||||
ui->pushButton_sites_add_custom->click();
|
||||
});
|
||||
|
||||
initCustomSites();
|
||||
|
||||
ui->pushButton_general_settings_exit->hide();
|
||||
ui->pushButton_share_connection->hide();
|
||||
ui->radioButton_mode_all_sites->hide();
|
||||
ui->radioButton_mode_include_selected_sites->hide();
|
||||
ui->pushButton_blocked_list->hide();
|
||||
ui->label_description->hide();
|
||||
//ui->pushButton_share_connection->hide();
|
||||
|
||||
setFixedSize(width(),height());
|
||||
|
||||
|
@ -119,9 +126,9 @@ void MainWindow::goToPage(Page page, bool reset, bool slide)
|
|||
ui->label_server_settings_wait_info->hide();
|
||||
ui->label_server_settings_wait_info->clear();
|
||||
ui->label_server_settings_server->setText(QString("%1@%2:%3")
|
||||
.arg(m_settings->userName())
|
||||
.arg(m_settings->serverName())
|
||||
.arg(m_settings->serverPort()));
|
||||
.arg(m_settings.userName())
|
||||
.arg(m_settings.serverName())
|
||||
.arg(m_settings.serverPort()));
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -241,8 +248,8 @@ void MainWindow::onPushButtonNewServerConnectWithNewData(bool)
|
|||
ui->label_new_server_wait_info);
|
||||
|
||||
if (ok) {
|
||||
m_settings->setServerCredentials(serverCredentials);
|
||||
m_settings->save();
|
||||
m_settings.setServerCredentials(serverCredentials);
|
||||
m_settings.save();
|
||||
|
||||
goToPage(Page::Vpn);
|
||||
qApp->processEvents();
|
||||
|
@ -251,6 +258,29 @@ void MainWindow::onPushButtonNewServerConnectWithNewData(bool)
|
|||
}
|
||||
}
|
||||
|
||||
void MainWindow::onPushButtonNewServerConnectWithExistingCode(bool)
|
||||
{
|
||||
QString s = ui->lineEdit_start_existing_code->text();
|
||||
s.replace("vpn://", "");
|
||||
QJsonObject o = QJsonDocument::fromJson(QByteArray::fromBase64(s.toUtf8())).object();
|
||||
|
||||
qDebug().noquote() << QByteArray::fromBase64(s.toUtf8());
|
||||
ServerCredentials credentials;
|
||||
credentials.hostName = o.value("h").toString();
|
||||
credentials.port = o.value("p").toInt();
|
||||
credentials.userName = o.value("u").toString();
|
||||
credentials.password = o.value("w").toString();
|
||||
|
||||
m_settings.setServerCredentials(credentials);
|
||||
m_settings.save();
|
||||
|
||||
goToPage(Page::Vpn);
|
||||
qDebug() << QString("Added server %3@%1:%2").
|
||||
arg(credentials.hostName).
|
||||
arg(credentials.port).
|
||||
arg(credentials.userName);
|
||||
}
|
||||
|
||||
bool MainWindow::installServer(ServerCredentials credentials,
|
||||
QWidget *page, QProgressBar *progress, QPushButton *button, QLabel *info)
|
||||
{
|
||||
|
@ -312,7 +342,7 @@ bool MainWindow::installServer(ServerCredentials credentials,
|
|||
void MainWindow::onPushButtonReinstallServer(bool)
|
||||
{
|
||||
onDisconnect();
|
||||
installServer(m_settings->serverCredentials(),
|
||||
installServer(m_settings.serverCredentials(),
|
||||
ui->page_server_settings,
|
||||
ui->progressBar_server_settings_reinstall,
|
||||
ui->pushButton_server_settings_reinstall,
|
||||
|
@ -323,7 +353,7 @@ void MainWindow::onPushButtonClearServer(bool)
|
|||
{
|
||||
onDisconnect();
|
||||
|
||||
ErrorCode e = ServerController::removeServer(m_settings->serverCredentials(), Protocol::Any);
|
||||
ErrorCode e = ServerController::removeServer(m_settings.serverCredentials(), Protocol::Any);
|
||||
if (e) {
|
||||
QMessageBox::warning(this, APPLICATION_NAME,
|
||||
tr("Error occurred while configuring server.") + "\n" +
|
||||
|
@ -342,12 +372,12 @@ void MainWindow::onPushButtonForgetServer(bool)
|
|||
{
|
||||
onDisconnect();
|
||||
|
||||
m_settings->setUserName("");
|
||||
m_settings->setPassword("");
|
||||
m_settings->setServerName("");
|
||||
m_settings->setServerPort();
|
||||
m_settings.setUserName("");
|
||||
m_settings.setPassword("");
|
||||
m_settings.setServerName("");
|
||||
m_settings.setServerPort();
|
||||
|
||||
m_settings->save();
|
||||
m_settings.save();
|
||||
|
||||
goToPage(Page::Start);
|
||||
}
|
||||
|
@ -483,6 +513,7 @@ void MainWindow::setupUiConnections()
|
|||
connect(ui->pushButton_connect, SIGNAL(clicked(bool)), this, SLOT(onPushButtonConnectClicked(bool)));
|
||||
connect(ui->pushButton_new_server_setup, &QPushButton::clicked, this, [this](){ goToPage(Page::NewServer); });
|
||||
connect(ui->pushButton_new_server_connect_with_new_data, SIGNAL(clicked(bool)), this, SLOT(onPushButtonNewServerConnectWithNewData(bool)));
|
||||
connect(ui->pushButton_new_server_connect, SIGNAL(clicked(bool)), this, SLOT(onPushButtonNewServerConnectWithExistingCode(bool)));
|
||||
|
||||
connect(ui->pushButton_server_settings_reinstall, SIGNAL(clicked(bool)), this, SLOT(onPushButtonReinstallServer(bool)));
|
||||
connect(ui->pushButton_server_settings_clear, SIGNAL(clicked(bool)), this, SLOT(onPushButtonClearServer(bool)));
|
||||
|
@ -491,7 +522,19 @@ void MainWindow::setupUiConnections()
|
|||
connect(ui->pushButton_blocked_list, &QPushButton::clicked, this, [this](){ goToPage(Page::Sites); });
|
||||
connect(ui->pushButton_settings, &QPushButton::clicked, this, [this](){ goToPage(Page::GeneralSettings); });
|
||||
connect(ui->pushButton_server_settings, &QPushButton::clicked, this, [this](){ goToPage(Page::ServerSettings); });
|
||||
connect(ui->pushButton_share_connection, &QPushButton::clicked, this, [this](){ goToPage(Page::ShareConnection); });
|
||||
connect(ui->pushButton_share_connection, &QPushButton::clicked, this, [this](){
|
||||
goToPage(Page::ShareConnection);
|
||||
updateShareCode();
|
||||
});
|
||||
|
||||
connect(ui->pushButton_copy_sharing_code, &QPushButton::clicked, this, [this](){
|
||||
QGuiApplication::clipboard()->setText(ui->textEdit_sharing_code->toPlainText());
|
||||
ui->pushButton_copy_sharing_code->setText(tr("Copied"));
|
||||
|
||||
QTimer::singleShot(3000, [this]() {
|
||||
ui->pushButton_copy_sharing_code->setText(tr("Copy"));
|
||||
});
|
||||
});
|
||||
|
||||
|
||||
connect(ui->pushButton_back_from_sites, &QPushButton::clicked, this, [this](){ goToPage(Page::Vpn); });
|
||||
|
@ -500,6 +543,8 @@ void MainWindow::setupUiConnections()
|
|||
connect(ui->pushButton_back_from_server_settings, &QPushButton::clicked, this, [this](){ goToPage(Page::GeneralSettings); });
|
||||
connect(ui->pushButton_back_from_share, &QPushButton::clicked, this, [this](){ goToPage(Page::GeneralSettings); });
|
||||
|
||||
connect(ui->pushButton_sites_add_custom, &QPushButton::clicked, this, [this](){ onPushButtonAddCustomSitesClicked(); });
|
||||
connect(ui->pushButton_sites_delete_custom, &QPushButton::clicked, this, [this](){ onPushButtonDeleteCustomSiteClicked(); });
|
||||
}
|
||||
|
||||
void MainWindow::setTrayState(VpnProtocol::ConnectionState state)
|
||||
|
@ -564,7 +609,7 @@ void MainWindow::onConnect()
|
|||
qApp->processEvents();
|
||||
|
||||
// TODO: Call connectToVpn with restricted server account
|
||||
ServerCredentials credentials = m_settings->serverCredentials();
|
||||
ServerCredentials credentials = m_settings.serverCredentials();
|
||||
|
||||
ErrorCode errorCode = m_vpnConnection->connectToVpn(credentials);
|
||||
if (errorCode) {
|
||||
|
@ -591,3 +636,89 @@ void MainWindow::onTrayActionConnect()
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
void MainWindow::onPushButtonAddCustomSitesClicked()
|
||||
{
|
||||
QString newSite = ui->lineEdit_sites_add_custom->text();
|
||||
|
||||
if (newSite.isEmpty()) return;
|
||||
if (!newSite.contains(".")) return;
|
||||
|
||||
// get domain name if it present
|
||||
newSite.replace("https://", "");
|
||||
newSite.replace("http://", "");
|
||||
newSite.replace("ftp://", "");
|
||||
|
||||
newSite = newSite.split("/", QString::SkipEmptyParts).first();
|
||||
|
||||
|
||||
QStringList customSites = m_settings.customSites();
|
||||
if (!customSites.contains(newSite)) {
|
||||
customSites.append(newSite);
|
||||
m_settings.setCustomSites(customSites);
|
||||
|
||||
QString newIp = Utils::getIPAddress(newSite);
|
||||
QStringList customIps = m_settings.customIps();
|
||||
if (!newIp.isEmpty() && !customIps.contains(newIp)) {
|
||||
customIps.append(newIp);
|
||||
m_settings.setCustomIps(customIps);
|
||||
|
||||
// add to routes immediatelly
|
||||
// if (vpnStatus() == VPNStatusConnected) {
|
||||
// //Router::Instance().routeAdd(newIp, vpnGate());
|
||||
// }
|
||||
}
|
||||
|
||||
initCustomSites();
|
||||
|
||||
ui->lineEdit_sites_add_custom->clear();
|
||||
}
|
||||
else {
|
||||
qDebug() << "customSites already contains" << newSite;
|
||||
}
|
||||
}
|
||||
|
||||
void MainWindow::onPushButtonDeleteCustomSiteClicked()
|
||||
{
|
||||
QModelIndex index = ui->listView_sites_custom->currentIndex();
|
||||
QString siteToDelete = index.data(Qt::DisplayRole).toString();
|
||||
|
||||
if (siteToDelete.isEmpty()) {
|
||||
return;
|
||||
}
|
||||
|
||||
QString ipToDelete = Utils::getIPAddress(siteToDelete);
|
||||
|
||||
QStringList customSites = m_settings.customSites();
|
||||
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);
|
||||
|
||||
|
||||
initCustomSites();
|
||||
|
||||
//Router::Instance().routeDelete(Utils::getIPAddress(ipToDelete));
|
||||
//Router::Instance().flushDns();
|
||||
}
|
||||
|
||||
void MainWindow::initCustomSites()
|
||||
{
|
||||
customSitesModel->setStringList(m_settings.customSites());
|
||||
}
|
||||
|
||||
void MainWindow::updateShareCode()
|
||||
{
|
||||
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)));
|
||||
}
|
||||
|
|
|
@ -5,12 +5,14 @@
|
|||
#include <QMainWindow>
|
||||
#include <QProgressBar>
|
||||
#include <QPushButton>
|
||||
#include <QStringListModel>
|
||||
#include <QSystemTrayIcon>
|
||||
|
||||
#include "framelesswindow.h"
|
||||
#include "protocols/vpnprotocol.h"
|
||||
|
||||
class Settings;
|
||||
#include "settings.h"
|
||||
|
||||
class VpnConnection;
|
||||
|
||||
namespace Ui {
|
||||
|
@ -43,11 +45,15 @@ private slots:
|
|||
|
||||
void onPushButtonConnectClicked(bool checked);
|
||||
void onPushButtonNewServerConnectWithNewData(bool);
|
||||
void onPushButtonNewServerConnectWithExistingCode(bool);
|
||||
|
||||
void onPushButtonReinstallServer(bool);
|
||||
void onPushButtonClearServer(bool);
|
||||
void onPushButtonForgetServer(bool);
|
||||
|
||||
void onPushButtonAddCustomSitesClicked();
|
||||
void onPushButtonDeleteCustomSiteClicked();
|
||||
|
||||
void onTrayActionConnect(); // connect from context menu
|
||||
void setTrayState(VpnProtocol::ConnectionState state);
|
||||
|
||||
|
@ -68,10 +74,14 @@ private:
|
|||
void setTrayIcon(const QString &iconPath);
|
||||
|
||||
void setupUiConnections();
|
||||
void initCustomSites();
|
||||
|
||||
void updateShareCode();
|
||||
|
||||
|
||||
Ui::MainWindow *ui;
|
||||
VpnConnection* m_vpnConnection;
|
||||
Settings* m_settings;
|
||||
Settings m_settings;
|
||||
|
||||
QAction* m_trayActionConnect;
|
||||
QAction* m_trayActionDisconnect;
|
||||
|
@ -79,6 +89,8 @@ private:
|
|||
QSystemTrayIcon m_tray;
|
||||
QMenu* m_menu;
|
||||
|
||||
QStringListModel *customSitesModel = nullptr;
|
||||
|
||||
bool canMove = false;
|
||||
QPoint offset;
|
||||
bool eventFilter(QObject *obj, QEvent *event) override;
|
||||
|
|
|
@ -14,8 +14,7 @@
|
|||
<string/>
|
||||
</property>
|
||||
<property name="styleSheet">
|
||||
<string notr="true">/*----------------------*/
|
||||
|
||||
<string notr="true">
|
||||
QLabel {
|
||||
color: #181922;
|
||||
}
|
||||
|
@ -257,17 +256,10 @@ QPushButton:hover {
|
|||
</rect>
|
||||
</property>
|
||||
<property name="styleSheet">
|
||||
<string notr="true">QStackedWidget#stackedWidget_main{
|
||||
background: transparent;
|
||||
}
|
||||
|
||||
QStackedWidget QWidget {
|
||||
background: transparent;
|
||||
}
|
||||
</string>
|
||||
<string notr="true"/>
|
||||
</property>
|
||||
<property name="currentIndex">
|
||||
<number>2</number>
|
||||
<number>0</number>
|
||||
</property>
|
||||
<widget class="QWidget" name="page_start">
|
||||
<widget class="QLabel" name="label_23">
|
||||
|
@ -365,7 +357,7 @@ border-radius: 4px;</string>
|
|||
<string/>
|
||||
</property>
|
||||
</widget>
|
||||
<widget class="QLineEdit" name="lineEdit_new_server_ip_3">
|
||||
<widget class="QLineEdit" name="lineEdit_start_existing_code">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>40</x>
|
||||
|
@ -384,6 +376,9 @@ color: #333333;</string>
|
|||
<property name="text">
|
||||
<string/>
|
||||
</property>
|
||||
<property name="placeholderText">
|
||||
<string>vpn://...</string>
|
||||
</property>
|
||||
</widget>
|
||||
<widget class="QPushButton" name="pushButton_new_server_connect">
|
||||
<property name="geometry">
|
||||
|
@ -1162,17 +1157,18 @@ color: #181922;
|
|||
<bool>true</bool>
|
||||
</property>
|
||||
</widget>
|
||||
<widget class="QLabel" name="label_tmp_logo">
|
||||
<widget class="QLabel" name="label_19">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>0</x>
|
||||
<y>500</y>
|
||||
<width>381</width>
|
||||
<height>131</height>
|
||||
<x>10</x>
|
||||
<y>460</y>
|
||||
<width>361</width>
|
||||
<height>141</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="styleSheet">
|
||||
<string notr="true">image: url(:/images/AmneziaVPN.png);</string>
|
||||
<string notr="true">image: url(:/images/AmneziaVPN.png);
|
||||
background-color: rgb(255, 255, 255);</string>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string/>
|
||||
|
@ -1303,7 +1299,7 @@ line-height: 25px;
|
|||
color: #181922;</string>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>These sites will open via VPN</string>
|
||||
<string>These sites will be opened using VPN</string>
|
||||
</property>
|
||||
<property name="alignment">
|
||||
<set>Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter</set>
|
||||
|
@ -1360,7 +1356,7 @@ border: 1px solid #A7A7A7;
|
|||
<set>Qt::AlignCenter</set>
|
||||
</property>
|
||||
<property name="placeholderText">
|
||||
<string>For example, rutor.org or 17.21.111.8</string>
|
||||
<string>For example, yousite.com or 17.21.111.8</string>
|
||||
</property>
|
||||
</widget>
|
||||
<widget class="QPushButton" name="pushButton_sites_add_custom">
|
||||
|
@ -1379,10 +1375,10 @@ border: 1px solid #A7A7A7;
|
|||
<cursorShape>PointingHandCursor</cursorShape>
|
||||
</property>
|
||||
<property name="styleSheet">
|
||||
<string notr="true">/* black */
|
||||
background: #181922;
|
||||
<string notr="true">background: #100A44;
|
||||
border-radius: 4px;
|
||||
font-size: 18pt;</string>
|
||||
font-size: 24px;
|
||||
color: white</string>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>+</string>
|
||||
|
@ -1407,7 +1403,7 @@ font-size: 18pt;</string>
|
|||
<string notr="true">color: #181922;</string>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Delete selected item</string>
|
||||
<string>Delete selected site</string>
|
||||
</property>
|
||||
</widget>
|
||||
<widget class="QLabel" name="label_3">
|
||||
|
@ -1432,7 +1428,7 @@ line-height: 150%;
|
|||
color: #333333;</string>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Hostname or IP address</string>
|
||||
<string>Web site or hostname or IP address</string>
|
||||
</property>
|
||||
</widget>
|
||||
</widget>
|
||||
|
@ -1947,6 +1943,9 @@ color: #333333;</string>
|
|||
<zorder>label_server_settings_server</zorder>
|
||||
</widget>
|
||||
<widget class="QWidget" name="page_share_connection">
|
||||
<property name="styleSheet">
|
||||
<string notr="true"/>
|
||||
</property>
|
||||
<widget class="QPushButton" name="pushButton_back_from_share">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
|
@ -2013,17 +2012,19 @@ color: #181922;</string>
|
|||
<bool>true</bool>
|
||||
</property>
|
||||
</widget>
|
||||
<widget class="QTextEdit" name="textEdit">
|
||||
<widget class="QTextEdit" name="textEdit_sharing_code">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>30</x>
|
||||
<y>100</y>
|
||||
<width>320</width>
|
||||
<height>151</height>
|
||||
<height>211</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="styleSheet">
|
||||
<string notr="true">background: #F5F5F5;
|
||||
<string notr="true">QTextEdit {
|
||||
|
||||
background: #F5F5F5;
|
||||
border-radius: 10px;
|
||||
|
||||
|
||||
|
@ -2036,27 +2037,32 @@ line-height: 110%;
|
|||
text-align: center;
|
||||
|
||||
color: #15CDCB;
|
||||
|
||||
}
|
||||
</string>
|
||||
</property>
|
||||
<property name="lineWrapMode">
|
||||
<enum>QTextEdit::FixedColumnWidth</enum>
|
||||
</property>
|
||||
<property name="lineWrapColumnOrWidth">
|
||||
<number>20</number>
|
||||
<number>30</number>
|
||||
</property>
|
||||
<property name="readOnly">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
<property name="html">
|
||||
<string><!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd">
|
||||
<html><head><meta name="qrichtext" content="1" /><style type="text/css">
|
||||
p, li { white-space: pre-wrap; }
|
||||
</style></head><body style=" font-family:'Consolas'; font-size:22px; font-weight:600; font-style:normal;">
|
||||
<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:20pt;">vpn:\\aosdiufhafafsuhgqejghuserhglaidhgauhgalgadg</span></p></body></html></string>
|
||||
<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:20pt;">vpn:\\xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx</span></p></body></html></string>
|
||||
</property>
|
||||
</widget>
|
||||
<widget class="QPushButton" name="pushButton_blocked_list_2">
|
||||
<widget class="QPushButton" name="pushButton_copy_sharing_code">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>20</x>
|
||||
<y>280</y>
|
||||
<y>340</y>
|
||||
<width>341</width>
|
||||
<height>40</height>
|
||||
</rect>
|
||||
|
@ -2090,7 +2096,7 @@ line-height: 21px;
|
|||
<property name="geometry">
|
||||
<rect>
|
||||
<x>30</x>
|
||||
<y>350</y>
|
||||
<y>400</y>
|
||||
<width>321</width>
|
||||
<height>101</height>
|
||||
</rect>
|
||||
|
|
|
@ -111,3 +111,71 @@ bool Utils::processIsRunning(const QString& fileName)
|
|||
#endif
|
||||
}
|
||||
|
||||
QString Utils::getIPAddress(const QString& host)
|
||||
{
|
||||
//TODO rewrite to api calls
|
||||
qDebug().noquote() << "GetIPAddress: checking " + host;
|
||||
if(host.isEmpty()) {
|
||||
qDebug().noquote() << "GetIPAddress: host is empty.";
|
||||
return QString();
|
||||
}
|
||||
|
||||
if(checkIPFormat(host)) {
|
||||
qDebug().noquote() << "GetIPAddress host is ip:" << host << host;
|
||||
return host; // it is a ip address.
|
||||
}
|
||||
QProcess ping;
|
||||
|
||||
#ifdef Q_OS_MACX
|
||||
ping.start("ping", QStringList() << "-c1" << host);
|
||||
#endif
|
||||
#ifdef Q_OS_WIN
|
||||
ping.start("ping", QStringList() << QString("/n") << "1" << QString("/w") << "1" << host);
|
||||
#endif
|
||||
ping.waitForStarted();
|
||||
|
||||
QEventLoop loop;
|
||||
loop.connect(&ping, SIGNAL(finished(int)), &loop, SLOT(quit()));
|
||||
loop.exec();
|
||||
|
||||
QString d = ping.readAll();
|
||||
if(d.size() == 0)
|
||||
return QString();
|
||||
qDebug().noquote() << d;
|
||||
|
||||
QString ip;
|
||||
#ifdef Q_OS_MACX
|
||||
ip = getStringBetween(d, "(", ")");
|
||||
#endif
|
||||
#ifdef Q_OS_WIN
|
||||
ip = getStringBetween(d, "[", "]");
|
||||
#endif
|
||||
qDebug().noquote() << "GetIPAddress:" << host << ip;
|
||||
return ip;
|
||||
}
|
||||
|
||||
QString Utils::getStringBetween(const QString& s, const QString& a, const QString& b)
|
||||
{
|
||||
int ap = s.indexOf(a), bp = s.indexOf(b, ap + a.length());
|
||||
if(ap < 0 || bp < 0)
|
||||
return QString();
|
||||
ap += a.length();
|
||||
if(bp - ap <= 0)
|
||||
return QString();
|
||||
return s.mid(ap, bp - ap).trimmed();
|
||||
}
|
||||
|
||||
bool Utils::checkIPFormat(const QString& ip)
|
||||
{
|
||||
int count = ip.count(".");
|
||||
if(count != 3)
|
||||
return false;
|
||||
|
||||
QStringList list = ip.trimmed().split(".");
|
||||
foreach(QString it, list) {
|
||||
if(it.toInt() <= 255 && it.toInt() >= 0)
|
||||
continue;
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
|
|
@ -15,6 +15,10 @@ public:
|
|||
static bool createEmptyFile(const QString& path);
|
||||
static bool initializePath(const QString& path);
|
||||
static bool processIsRunning(const QString& fileName);
|
||||
|
||||
static QString getIPAddress(const QString& host);
|
||||
static QString getStringBetween(const QString& s, const QString& a, const QString& b);
|
||||
static bool checkIPFormat(const QString& ip);
|
||||
};
|
||||
|
||||
#endif // UTILS_H
|
||||
|
|
|
@ -9,6 +9,7 @@
|
|||
#include "protocols/shadowsocksvpnprotocol.h"
|
||||
#include "utils.h"
|
||||
#include "vpnconnection.h"
|
||||
#include "communicator.h"
|
||||
|
||||
VpnConnection::VpnConnection(QObject* parent) : QObject(parent)
|
||||
{
|
||||
|
@ -22,6 +23,25 @@ void VpnConnection::onBytesChanged(quint64 receivedBytes, quint64 sentBytes)
|
|||
|
||||
void VpnConnection::onConnectionStateChanged(VpnProtocol::ConnectionState state)
|
||||
{
|
||||
// if (state == VpnProtocol::ConnectionState::Connected){
|
||||
// m_vpnProtocol->communicator()->sendMessage(Message(Message::State::FlushDnsRequest, QStringList()));
|
||||
|
||||
// // add routes
|
||||
// const QStringList &black_custom = m_settings.customIps();
|
||||
// qDebug() << "onConnect :: adding custom black routes, count:" << black_custom.size();
|
||||
|
||||
|
||||
// QStringList args;
|
||||
// args << m_vpnProtocol->vpnGateway();
|
||||
// args << black_custom;
|
||||
|
||||
// Message m(Message::State::RoutesAddRequest, args);
|
||||
// m_vpnProtocol->communicator()->sendMessage(m);
|
||||
// }
|
||||
// else if (state == VpnProtocol::ConnectionState::Error) {
|
||||
// m_vpnProtocol->communicator()->sendMessage(Message(Message::State::ClearSavedRoutesRequest, QStringList()));
|
||||
// m_vpnProtocol->communicator()->sendMessage(Message(Message::State::FlushDnsRequest, QStringList()));
|
||||
// }
|
||||
emit connectionStateChanged(state);
|
||||
}
|
||||
|
||||
|
@ -113,6 +133,9 @@ void VpnConnection::disconnectFromVpn()
|
|||
{
|
||||
qDebug() << "Disconnect from VPN";
|
||||
|
||||
// m_vpnProtocol->communicator()->sendMessage(Message(Message::State::ClearSavedRoutesRequest, QStringList()));
|
||||
// m_vpnProtocol->communicator()->sendMessage(Message(Message::State::FlushDnsRequest, QStringList()));
|
||||
|
||||
if (!m_vpnProtocol.data()) {
|
||||
return;
|
||||
}
|
||||
|
|
|
@ -7,6 +7,7 @@
|
|||
|
||||
#include "protocols/vpnprotocol.h"
|
||||
#include "core/defs.h"
|
||||
#include "settings.h"
|
||||
|
||||
using namespace amnezia;
|
||||
|
||||
|
@ -41,6 +42,9 @@ protected slots:
|
|||
protected:
|
||||
|
||||
QScopedPointer<VpnProtocol> m_vpnProtocol;
|
||||
|
||||
private:
|
||||
Settings m_settings;
|
||||
};
|
||||
|
||||
#endif // VPNCONNECTION_H
|
||||
|
|
|
@ -44,7 +44,6 @@ Rmdir /Q /S %RELEASE_DIR%
|
|||
Del %QMAKE_STASH_FILE%
|
||||
Del %TARGET_FILENAME%
|
||||
|
||||
# Checking env
|
||||
"%QT_BIN_DIR:"=%\qmake" -v
|
||||
nmake /?
|
||||
|
||||
|
@ -55,6 +54,7 @@ cd %WORK_DIR%
|
|||
set CL=/MP
|
||||
nmake /A /NOLOGO
|
||||
nmake clean
|
||||
rem if not exist "%OUT_APP_DIR:"=%\%APP_FILENAME:"=%" break
|
||||
|
||||
echo "Deploying..."
|
||||
"%QT_BIN_DIR:"=%\windeployqt" --release --force --no-translations "%OUT_APP_DIR:"=%\%APP_FILENAME:"=%"
|
||||
|
|
|
@ -6,11 +6,17 @@
|
|||
#include "localserver.h"
|
||||
#include "utils.h"
|
||||
|
||||
#include "router.h"
|
||||
|
||||
#ifdef Q_OS_WIN
|
||||
#include "tapcontroller_win.h"
|
||||
#endif
|
||||
|
||||
LocalServer::LocalServer(QObject *parent) : QObject(parent),
|
||||
m_clientConnection(nullptr),
|
||||
m_clientConnected(false)
|
||||
{
|
||||
m_server = new QLocalServer(this);
|
||||
m_server = QSharedPointer<QLocalServer>(new QLocalServer(this));
|
||||
m_server->setSocketOptions(QLocalServer::WorldAccessOption);
|
||||
|
||||
if (!m_server->listen(Utils::serverName())) {
|
||||
|
@ -18,7 +24,7 @@ LocalServer::LocalServer(QObject *parent) : QObject(parent),
|
|||
return;
|
||||
}
|
||||
|
||||
connect(m_server, &QLocalServer::newConnection, this, &LocalServer::onNewConnection);
|
||||
connect(m_server.data(), &QLocalServer::newConnection, this, &LocalServer::onNewConnection);
|
||||
|
||||
qDebug().noquote() << QString("Local server started on '%1'").arg(m_server->serverName());
|
||||
}
|
||||
|
@ -68,9 +74,16 @@ void LocalServer::onNewConnection()
|
|||
qWarning().noquote() << "Message is not valid!";
|
||||
continue;
|
||||
}
|
||||
else {
|
||||
qDebug().noquote() << QString("Got message id: '%1'").arg(static_cast<int>(incomingMessage.state()));
|
||||
//qDebug().noquote() << incomingMessage.rawData();
|
||||
}
|
||||
|
||||
switch (incomingMessage.state()) {
|
||||
case Message::State::Initialize:
|
||||
#ifdef Q_OS_WIN
|
||||
TapController::Instance().checkAndSetup();
|
||||
#endif
|
||||
sendMessage(Message(Message::State::Initialize, QStringList({"Server"})));
|
||||
break;
|
||||
case Message::State::StartRequest:
|
||||
|
@ -79,6 +92,23 @@ void LocalServer::onNewConnection()
|
|||
case Message::State::FinishRequest:
|
||||
finishProcess(incomingMessage.args());
|
||||
break;
|
||||
|
||||
case Message::State::RoutesAddRequest:
|
||||
routesAddRequest(incomingMessage.args());
|
||||
break;
|
||||
case Message::State::RouteDeleteRequest:
|
||||
routeDeleteRequest(incomingMessage.args());
|
||||
break;
|
||||
case Message::State::ClearSavedRoutesRequest:
|
||||
Router::Instance().clearSavedRoutes();
|
||||
break;
|
||||
case Message::State::FlushDnsRequest:
|
||||
Router::Instance().flushDns();
|
||||
break;
|
||||
case Message::State::InstallDriverRequest:
|
||||
checkAndInstallDriver(incomingMessage.args());
|
||||
break;
|
||||
|
||||
default:
|
||||
;
|
||||
}
|
||||
|
@ -128,6 +158,21 @@ void LocalServer::startProcess(const QStringList& messageArgs)
|
|||
m_processList.append(process);
|
||||
}
|
||||
|
||||
void LocalServer::routesAddRequest(const QStringList &messageArgs)
|
||||
{
|
||||
Router::Instance().routeAddList(messageArgs.first(), messageArgs.mid(1));
|
||||
}
|
||||
|
||||
void LocalServer::routeDeleteRequest(const QStringList &messageArgs)
|
||||
{
|
||||
Router::Instance().routeDelete(messageArgs.first());
|
||||
}
|
||||
|
||||
void LocalServer::checkAndInstallDriver(const QStringList &messageArgs)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
void LocalServer::onFinished(int exitCode, QProcess::ExitStatus exitStatus)
|
||||
{
|
||||
Q_UNUSED(exitStatus)
|
||||
|
|
|
@ -2,7 +2,9 @@
|
|||
#define LOCALSERVER_H
|
||||
|
||||
#include <QObject>
|
||||
#include <QPointer>
|
||||
#include <QProcess>
|
||||
#include <QSharedPointer>
|
||||
#include <QStringList>
|
||||
#include <QVector>
|
||||
|
||||
|
@ -34,8 +36,14 @@ private:
|
|||
void sendMessage(const Message& message);
|
||||
void startProcess(const QStringList& messageArgs);
|
||||
|
||||
QLocalServer* m_server;
|
||||
QLocalSocket* m_clientConnection;
|
||||
void routesAddRequest(const QStringList& messageArgs);
|
||||
void routeDeleteRequest(const QStringList& messageArgs);
|
||||
|
||||
void checkAndInstallDriver(const QStringList& messageArgs);
|
||||
|
||||
QSharedPointer<QLocalServer> m_server;
|
||||
QPointer <QLocalSocket> m_clientConnection;
|
||||
|
||||
QVector<QProcess*> m_processList;
|
||||
bool m_clientConnected;
|
||||
};
|
||||
|
|
|
@ -322,6 +322,6 @@ void Router::flushDns()
|
|||
|
||||
p.start(command);
|
||||
p.waitForFinished();
|
||||
qDebug().noquote() << "OUTPUT ipconfig /flushdns: " + p.readAll();
|
||||
//qDebug().noquote() << "OUTPUT ipconfig /flushdns: " + p.readAll();
|
||||
#endif
|
||||
}
|
|
@ -8,6 +8,7 @@ HEADERS = \
|
|||
../../client/utils.h \
|
||||
localserver.h \
|
||||
log.h \
|
||||
router.h \
|
||||
systemservice.h
|
||||
|
||||
SOURCES = \
|
||||
|
@ -16,8 +17,26 @@ SOURCES = \
|
|||
localserver.cpp \
|
||||
log.cpp \
|
||||
main.cpp \
|
||||
router.cpp \
|
||||
systemservice.cpp
|
||||
|
||||
win32 {
|
||||
HEADERS += \
|
||||
tapcontroller_win.h
|
||||
|
||||
SOURCES += \
|
||||
tapcontroller_win.cpp
|
||||
|
||||
LIBS += \
|
||||
-luser32 \
|
||||
-lrasapi32 \
|
||||
-lshlwapi \
|
||||
-liphlpapi \
|
||||
-lws2_32 \
|
||||
-liphlpapi \
|
||||
-lgdi32
|
||||
}
|
||||
|
||||
include(../src/qtservice.pri)
|
||||
|
||||
#CONFIG(release, debug|release) {
|
||||
|
|
364
service/server/tapcontroller_win.cpp
Normal file
364
service/server/tapcontroller_win.cpp
Normal file
|
@ -0,0 +1,364 @@
|
|||
#include <QProcess>
|
||||
#include <QDebug>
|
||||
#include <QRegularExpression>
|
||||
#include <QRegularExpressionMatchIterator>
|
||||
#include <QCoreApplication>
|
||||
|
||||
#include "tapcontroller_win.h"
|
||||
|
||||
#define TAP_EXE_ERROR { \
|
||||
qDebug() << "TapController: Can't start tapinstall.exe"; \
|
||||
return false; \
|
||||
}
|
||||
|
||||
#define TAP_NO_MATCHING_DEVICES_ERROR { \
|
||||
qDebug() << "TapController: No matching devices found"; \
|
||||
return false; \
|
||||
}
|
||||
|
||||
TapController &TapController::Instance()
|
||||
{
|
||||
static TapController s;
|
||||
return s;
|
||||
}
|
||||
|
||||
TapController::TapController()
|
||||
{
|
||||
}
|
||||
|
||||
bool TapController::checkInstaller()
|
||||
{
|
||||
QProcess tapInstallProc;
|
||||
tapInstallProc.start(getTapInstallPath(), QStringList() << "/?");
|
||||
if(!tapInstallProc.waitForStarted()) return false;
|
||||
else return true;
|
||||
}
|
||||
|
||||
bool TapController::enableTapAdapter(const QString &tapInstanceId)
|
||||
{
|
||||
QProcess tapInstallProc;
|
||||
tapInstallProc.start(getTapInstallPath(), QStringList() << "enable" << QString("@") + tapInstanceId);
|
||||
if(!tapInstallProc.waitForStarted()) TAP_EXE_ERROR ;
|
||||
|
||||
tapInstallProc.waitForFinished();
|
||||
QString output = QString(tapInstallProc.readAll());
|
||||
if (! output.contains("are enabled")) {
|
||||
qDebug() << "TapController: Failed to enable tap device";
|
||||
return false;
|
||||
}
|
||||
if (output.contains("No matching devices ")) TAP_NO_MATCHING_DEVICES_ERROR ;
|
||||
|
||||
qDebug() << "Enabled TAP Instance id:" << tapInstanceId;
|
||||
return true;
|
||||
}
|
||||
|
||||
bool TapController::disableTapAdapter(const QString &tapInstanceId)
|
||||
{
|
||||
QProcess tapInstallProc;
|
||||
tapInstallProc.start(getTapInstallPath(), QStringList() << "disable" << QString("@") + tapInstanceId);
|
||||
if(!tapInstallProc.waitForStarted()) TAP_EXE_ERROR ;
|
||||
|
||||
tapInstallProc.waitForFinished();
|
||||
QString output = QString(tapInstallProc.readAll());
|
||||
if (! output.contains("disabled")) {
|
||||
qDebug() << "TapController: Failed to disable tap device";
|
||||
return false;
|
||||
}
|
||||
if (output.contains("No matching devices ")) TAP_NO_MATCHING_DEVICES_ERROR ;
|
||||
|
||||
qDebug() << "Disabled TAP Instance id:" << tapInstanceId;
|
||||
return true;
|
||||
}
|
||||
|
||||
QStringList TapController::getTapList()
|
||||
{
|
||||
QProcess tapInstallProc;
|
||||
tapInstallProc.start(getTapInstallPath(), QStringList() << "find" << "tap0901" );
|
||||
if(!tapInstallProc.waitForStarted()) {
|
||||
qDebug() << "TapController: TapController: Can't start tapinstall.exe";
|
||||
return QStringList();
|
||||
}
|
||||
tapInstallProc.waitForFinished();
|
||||
QString output = QString( tapInstallProc.readAll() );
|
||||
output.replace("\r", "");
|
||||
if (output.contains("No matched devices found")) {
|
||||
qDebug() << "TapController: No matching device instances found";
|
||||
return QStringList();
|
||||
}
|
||||
|
||||
QStringList l = output.split("\n", QString::SkipEmptyParts);
|
||||
if (l.size() > 0) l.removeLast();
|
||||
|
||||
QStringList tapList;
|
||||
for (QString s : l) {
|
||||
if (s.contains(" ")) tapList.append(s.split(" ", QString::SkipEmptyParts).first());
|
||||
else tapList.append(s);
|
||||
}
|
||||
|
||||
return tapList;
|
||||
}
|
||||
|
||||
bool TapController::checkAndSetup()
|
||||
{
|
||||
qDebug().noquote() << "OpenVPN path" << getOpenVpnPath();
|
||||
qDebug().noquote() << "TapInstall path" << getTapInstallPath();
|
||||
qDebug().noquote() << "TapDriverDir path" << getTapDriverDir();
|
||||
//////////////////////////////////////////////
|
||||
/// Check if OpenVPN executable ready for use
|
||||
bool isOpenVpnExeExist = checkOpenVpn();
|
||||
if (!isOpenVpnExeExist) {
|
||||
qDebug() << "TapController::checkAndSetup :::: openvpn.exe not found";
|
||||
return false;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////
|
||||
/// Check if any TAP adapter ready for use
|
||||
bool isAnyAvailableTap = false;
|
||||
QStringList tapList = getTapList();
|
||||
for (const QString &tap : tapList) {
|
||||
qDebug() << "TapController: Found TAP device" << tap << ", checking...";
|
||||
if (checkDriver(tap)) {
|
||||
isAnyAvailableTap = true;
|
||||
qDebug() << "TapController: Device" << tap << "is ready for using";
|
||||
}
|
||||
else
|
||||
qDebug() << "TapController: Device" << tap << "is NOT ready for using";
|
||||
}
|
||||
|
||||
if (isAnyAvailableTap) {
|
||||
qDebug() << "TapController: Check success, found usable TAP adapter";
|
||||
return true;
|
||||
}
|
||||
else qDebug() << "TapController: Check failed, usable TAP adapter NOT found";
|
||||
|
||||
/// Try to setup driver if it's not installed
|
||||
qDebug() << "TapController: Installing TAP driver...";
|
||||
bool ok = setupDriver();
|
||||
|
||||
if (ok) qDebug() << "TapController: TAP driver successfully installed";
|
||||
else qDebug() << "TapController: Failed to install TAP driver";
|
||||
|
||||
return ok;
|
||||
}
|
||||
|
||||
bool TapController::checkDriver(const QString& tapInstanceId)
|
||||
{
|
||||
/// Check for driver nodes
|
||||
{
|
||||
QProcess tapInstallProc;
|
||||
tapInstallProc.start(getTapInstallPath(), QStringList() << "drivernodes" << QString("@") + tapInstanceId);
|
||||
if (!tapInstallProc.waitForStarted()) TAP_EXE_ERROR ;
|
||||
tapInstallProc.waitForFinished(1000);
|
||||
|
||||
QString output = QString(tapInstallProc.readAll());
|
||||
if (output.contains("No driver nodes found")) {
|
||||
qDebug() << "TapController: No driver nodes found";
|
||||
return false;
|
||||
}
|
||||
if (output.contains("No matching devices")) TAP_NO_MATCHING_DEVICES_ERROR ;
|
||||
}
|
||||
|
||||
|
||||
/// Check for files
|
||||
{
|
||||
QProcess tapInstallProc;
|
||||
tapInstallProc.start(getTapInstallPath(), QStringList() << "driverfiles" << QString("@") + tapInstanceId);
|
||||
if (!tapInstallProc.waitForStarted()) TAP_EXE_ERROR ;
|
||||
tapInstallProc.waitForFinished(1000);
|
||||
|
||||
QString output = QString(tapInstallProc.readAll());
|
||||
if (output.contains("No driver information")) {
|
||||
qDebug() << "TapController: No driver information";
|
||||
return false;
|
||||
}
|
||||
if (output.contains("No matching devices")) TAP_NO_MATCHING_DEVICES_ERROR ;
|
||||
}
|
||||
|
||||
/// Check if network adapter enabled
|
||||
bool isDisabled = false;
|
||||
{
|
||||
QProcess tapInstallProc;
|
||||
tapInstallProc.start(getTapInstallPath(), QStringList() << "status" << QString("@") + tapInstanceId);
|
||||
if(!tapInstallProc.waitForStarted()) TAP_EXE_ERROR ;
|
||||
|
||||
tapInstallProc.waitForFinished();
|
||||
QString output = QString(tapInstallProc.readAll());
|
||||
output.replace("\r", "");
|
||||
|
||||
if (output.contains("No matching devices ")) TAP_NO_MATCHING_DEVICES_ERROR ;
|
||||
|
||||
if (output.contains("is running")) {
|
||||
qDebug() << "TapController: Device" << tapInstanceId << "is active and ready";
|
||||
//return true;
|
||||
}
|
||||
else if (output.contains("is disabled")) isDisabled = true;
|
||||
else {
|
||||
qDebug() << "TapController: Device" << tapInstanceId << "is in unknown state";
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/// Disable adapter if enabled
|
||||
if (!isDisabled) {
|
||||
qDebug() << "TapController: Device" << tapInstanceId << "is enabled. Disabling before use...";
|
||||
if (!disableTapAdapter(tapInstanceId)) return false;
|
||||
}
|
||||
|
||||
/// Enable adapter
|
||||
{
|
||||
qDebug() << "TapController: Device" << tapInstanceId << "is disabled. Enabling...";
|
||||
if (!enableTapAdapter(tapInstanceId)) return false;
|
||||
}
|
||||
|
||||
/// Check again
|
||||
{
|
||||
QProcess tapInstallProc;
|
||||
tapInstallProc.start(getTapInstallPath(), QStringList() << "status" << QString("@") + tapInstanceId);
|
||||
if(!tapInstallProc.waitForStarted()) TAP_EXE_ERROR ;
|
||||
|
||||
tapInstallProc.waitForFinished();
|
||||
QString output = QString(tapInstallProc.readAll());
|
||||
|
||||
if (output.contains("is running")) return true;
|
||||
else {
|
||||
qDebug() << "TapController: tap device final check failed";
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
bool TapController::checkOpenVpn()
|
||||
{
|
||||
/// Check openvpn executable
|
||||
|
||||
QProcess openVpnProc;
|
||||
openVpnProc.start(getOpenVpnPath(), QStringList() << "--version");
|
||||
if (!openVpnProc.waitForStarted()) {
|
||||
qDebug() << "TapController: openvpn.exe NOT found";
|
||||
return false;
|
||||
}
|
||||
openVpnProc.waitForFinished(1000);
|
||||
|
||||
QString output = QString(openVpnProc.readAll());
|
||||
output.replace("\r", "");
|
||||
qDebug() << "TapController: openvpn.exe found, version:" << output;
|
||||
return true;
|
||||
}
|
||||
|
||||
QString TapController::getTapInstallPath()
|
||||
{
|
||||
#ifdef Q_OS_WIN
|
||||
return qApp->applicationDirPath() + "\\tap\\"+ QSysInfo::currentCpuArchitecture() + "\\tapinstall.exe";
|
||||
// if (QSysInfo::currentCpuArchitecture() == "i386") {
|
||||
// return qApp->applicationDirPath() + "\\openvpn\\drivers_x32\\tapinstall.exe";
|
||||
// }
|
||||
// else if (QSysInfo::currentCpuArchitecture() == "x86_64") {
|
||||
// return qApp->applicationDirPath() + "\\openvpn\\drivers_x64\\tapinstall.exe";
|
||||
// }
|
||||
// else return "";
|
||||
#endif
|
||||
return "";
|
||||
}
|
||||
|
||||
QString TapController::getOpenVpnPath()
|
||||
{
|
||||
#ifdef Q_OS_WIN
|
||||
//return qApp->applicationDirPath() + "\\openvpn\\"+ QSysInfo::currentCpuArchitecture() + "\\openvpn.exe";
|
||||
return qApp->applicationDirPath() + "\\openvpn\\i386\\openvpn.exe";
|
||||
|
||||
//return qApp->applicationDirPath() + "\\openvpn\\bin\\openvpn.exe";
|
||||
#endif
|
||||
return "";
|
||||
}
|
||||
|
||||
QString TapController::getTapDriverDir()
|
||||
{
|
||||
return qApp->applicationDirPath() + "\\tap\\"+ QSysInfo::currentCpuArchitecture() + "\\";
|
||||
|
||||
// if (QSysInfo::currentCpuArchitecture() == "i386") {
|
||||
// return qApp->applicationDirPath() + "\\openvpn\\drivers_x32\\";
|
||||
// }
|
||||
// else if (QSysInfo::currentCpuArchitecture() == "x86_64") {
|
||||
// return qApp->applicationDirPath() + "\\openvpn\\drivers_x64\\";
|
||||
// }
|
||||
// else return "";
|
||||
}
|
||||
|
||||
bool TapController::removeDriver(const QString& tapInstanceId)
|
||||
{
|
||||
/// remove tap by instance id
|
||||
{
|
||||
QProcess tapInstallProc;
|
||||
tapInstallProc.start(getTapInstallPath(), QStringList() << "remove" << QString("@") + tapInstanceId);
|
||||
if(!tapInstallProc.waitForStarted()) return false;
|
||||
|
||||
tapInstallProc.waitForFinished();
|
||||
QString output = QString( tapInstallProc.readAll() );
|
||||
if (output.contains("were removed")) {
|
||||
qDebug() << "TAP device" << tapInstanceId << "suceccfully removed";
|
||||
return true;
|
||||
}
|
||||
else {
|
||||
qDebug() << "Unable to remove TAP device" << tapInstanceId;
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bool TapController::setupDriver()
|
||||
{
|
||||
//setupDriverCertificate();
|
||||
|
||||
QStringList tapList = getTapList();
|
||||
for (QString tap : tapList) {
|
||||
if (! checkDriver(tap)) removeDriver(tap);
|
||||
}
|
||||
tapList = getTapList();
|
||||
if (! tapList.isEmpty()) {
|
||||
qDebug() << "TapController: setupDriver :::: Found drivers count" << tapList.size();
|
||||
return true;
|
||||
}
|
||||
|
||||
/// else try to install driver
|
||||
QProcess tapInstallProc;
|
||||
tapInstallProc.start(getTapInstallPath(), QStringList() << "install" << getTapDriverDir() + "OemVista.inf" << "tap0901");
|
||||
bool ok = tapInstallProc.waitForStarted();
|
||||
if (!ok) {
|
||||
qDebug() << "TapController: setupDriver failer to start tapInstallProc" << tapInstallProc.errorString();
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
tapInstallProc.waitForFinished();
|
||||
qDebug() << "TapController: setupDriver args" << tapInstallProc.arguments().join(" ");
|
||||
qDebug() << "TapController: setupDriver output" << tapInstallProc.readAll();
|
||||
|
||||
/// check again
|
||||
tapList = getTapList();
|
||||
for (QString tap : tapList) {
|
||||
if (! checkDriver(tap)) removeDriver(tap);
|
||||
}
|
||||
tapList = getTapList();
|
||||
if (!tapList.isEmpty()) {
|
||||
return true;
|
||||
}
|
||||
else {
|
||||
return false;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
bool TapController::setupDriverCertificate()
|
||||
{
|
||||
QString cert = getTapDriverDir() + "\\OpenVPN.cer";
|
||||
QProcess tapInstallProc;
|
||||
tapInstallProc.start("certutil" , QStringList() << "-addstore" << "-f" << "trustedpublisher" << cert);
|
||||
|
||||
tapInstallProc.waitForFinished();
|
||||
|
||||
QString certOutput = QString(tapInstallProc.readAll());
|
||||
qDebug() << "TapController: OpenVPN certificate installed:" << certOutput;
|
||||
return true;
|
||||
}
|
||||
|
41
service/server/tapcontroller_win.h
Normal file
41
service/server/tapcontroller_win.h
Normal file
|
@ -0,0 +1,41 @@
|
|||
#ifndef TAPCONTROLLER_H
|
||||
#define TAPCONTROLLER_H
|
||||
|
||||
#include <QObject>
|
||||
#include <QString>
|
||||
#include <QMap>
|
||||
|
||||
#define IPv6_DEBUG
|
||||
|
||||
//! The TapController class verifies Windows Tap Controller for existance on Windows platform.
|
||||
|
||||
class TapController
|
||||
{
|
||||
public:
|
||||
static TapController& Instance();
|
||||
static bool checkAndSetup();
|
||||
static QString getOpenVpnPath();
|
||||
|
||||
|
||||
bool checkInstaller();
|
||||
|
||||
static QStringList getTapList();
|
||||
static bool enableTapAdapter(const QString &tapInstanceId);
|
||||
static bool disableTapAdapter(const QString &tapInstanceId);
|
||||
private:
|
||||
explicit TapController();
|
||||
TapController(TapController const &) = delete;
|
||||
TapController& operator= (TapController const&) = delete;
|
||||
|
||||
static bool checkDriver(const QString& tapInstanceId);
|
||||
static bool checkOpenVpn();
|
||||
static QString getTapInstallPath();
|
||||
static QString getTapDriverDir();
|
||||
static bool setupDriver();
|
||||
static bool setupDriverCertificate();
|
||||
static bool removeDriver(const QString& tapInstanceId);
|
||||
|
||||
|
||||
};
|
||||
|
||||
#endif // TAPCONTROLLER_H
|
Loading…
Add table
Add a link
Reference in a new issue