Release 1.0 (#4)
* Crash fix in management server * Openvpn scripts fixes some refactoring * deploy fix * Scripts fix for macos * OpenVpn runtime error codes handling * MacOS deploy script fix * easyrsa scripts for MacOS * Refactoring Ui improvements Bug fixes * new server page fix
This commit is contained in:
parent
f0e5fbeda0
commit
c2a7d66cb4
35 changed files with 3758 additions and 231 deletions
|
|
@ -2,7 +2,7 @@ QT += widgets core gui network xml
|
|||
|
||||
TARGET = AmneziaVPN
|
||||
TEMPLATE = app
|
||||
CONFIG += console
|
||||
#CONFIG += console
|
||||
|
||||
DEFINES += QT_DEPRECATED_WARNINGS
|
||||
|
||||
|
|
|
|||
|
|
@ -45,7 +45,7 @@ void Communicator::onLineAvailable(const QString& line)
|
|||
emit messageReceived(message);
|
||||
}
|
||||
|
||||
bool Communicator::connected() const
|
||||
bool Communicator::isConnected() const
|
||||
{
|
||||
if (!m_localClient) {
|
||||
return false;
|
||||
|
|
@ -66,7 +66,7 @@ bool Communicator::writeData(const QString& data)
|
|||
|
||||
void Communicator::sendMessage(const Message& message)
|
||||
{
|
||||
if (!connected()) {
|
||||
if (!isConnected()) {
|
||||
return;
|
||||
}
|
||||
const QString data = message.toString();
|
||||
|
|
|
|||
|
|
@ -16,7 +16,7 @@ public:
|
|||
explicit Communicator(QObject* parent = nullptr);
|
||||
~Communicator();
|
||||
|
||||
bool connected() const;
|
||||
bool isConnected() const;
|
||||
void sendMessage(const Message& message);
|
||||
|
||||
signals:
|
||||
|
|
|
|||
|
|
@ -44,11 +44,16 @@ enum ErrorCode
|
|||
FailedToSaveConfigData,
|
||||
OpenVpnConfigMissing,
|
||||
OpenVpnManagementServerError,
|
||||
EasyRsaError,
|
||||
|
||||
// Distro errors
|
||||
AmneziaServiceConnectionFailed,
|
||||
OpenVpnExecutableMissing,
|
||||
EasyRsaExecutableMissing
|
||||
EasyRsaExecutableMissing,
|
||||
AmneziaServiceConnectionFailed,
|
||||
|
||||
// VPN errors
|
||||
OpenVpnAdaptersInUseError,
|
||||
OpenVpnUnknownError
|
||||
};
|
||||
|
||||
} // namespace amnezia
|
||||
|
|
|
|||
|
|
@ -4,7 +4,7 @@
|
|||
#include "defs.h"
|
||||
using namespace amnezia;
|
||||
|
||||
QString errorString(ErrorCode code){
|
||||
static QString errorString(ErrorCode code){
|
||||
switch (code) {
|
||||
|
||||
// General error codes
|
||||
|
|
@ -31,12 +31,17 @@ QString errorString(ErrorCode code){
|
|||
// Local errors
|
||||
case (FailedToSaveConfigData): return QObject::tr("Failed to save config to disk");
|
||||
case (OpenVpnConfigMissing): return QObject::tr("OpenVPN config missing");
|
||||
case (OpenVpnManagementServerError): return QObject::tr("OpenVpn management server error");
|
||||
case (OpenVpnManagementServerError): return QObject::tr("OpenVPN management server error");
|
||||
case (EasyRsaError): return QObject::tr("EasyRSA runtime error");
|
||||
|
||||
// Distro errors
|
||||
case (OpenVpnExecutableMissing): return QObject::tr("OpenVPN executable missing");
|
||||
case (EasyRsaExecutableMissing): return QObject::tr("EasyRsa executable missing");
|
||||
case (AmneziaServiceConnectionFailed): return QObject::tr("Amnezia helper service error");
|
||||
|
||||
// VPN errors
|
||||
case (OpenVpnAdaptersInUseError): return QObject::tr("Can't connect: another VPN connection is active");
|
||||
|
||||
case(InternalError):
|
||||
default:
|
||||
return QObject::tr("Internal error");
|
||||
|
|
|
|||
|
|
@ -21,72 +21,101 @@ QString OpenVpnConfigurator::getRandomString(int len)
|
|||
|
||||
QString OpenVpnConfigurator::getEasyRsaShPath()
|
||||
{
|
||||
#ifdef Q_OS_WIN
|
||||
// easyrsa sh path should looks like
|
||||
// "/Program Files (x86)/AmneziaVPN/easyrsa/easyrsa"
|
||||
QString easyRsaShPath = QDir::toNativeSeparators(QApplication::applicationDirPath()) + "\\easyrsa\\easyrsa";
|
||||
easyRsaShPath.replace(":", "");
|
||||
easyRsaShPath.replace("C:\\", "");
|
||||
easyRsaShPath.replace("\\", "/");
|
||||
easyRsaShPath.prepend("/");
|
||||
|
||||
return easyRsaShPath;
|
||||
//return "\"" + easyRsaShPath + "\"";
|
||||
return "\"/Program Files (x86)/AmneziaVPN/easyrsa/easyrsa\"";
|
||||
#else
|
||||
return QDir::toNativeSeparators(QApplication::applicationDirPath()) + "/easyrsa";
|
||||
#endif
|
||||
}
|
||||
|
||||
QProcessEnvironment OpenVpnConfigurator::prepareEnv()
|
||||
{
|
||||
QProcessEnvironment env = QProcessEnvironment::systemEnvironment();
|
||||
QString pathEnvVar = env.value("PATH");
|
||||
|
||||
#ifdef Q_OS_WIN
|
||||
pathEnvVar.prepend(QDir::toNativeSeparators(QApplication::applicationDirPath()) + "\\easyrsa\\bin;");
|
||||
pathEnvVar.prepend(QDir::toNativeSeparators(QApplication::applicationDirPath()) + "\\openvpn\\i386;");
|
||||
pathEnvVar.prepend(QDir::toNativeSeparators(QApplication::applicationDirPath()) + "\\openvpn\\x64;");
|
||||
#else
|
||||
pathEnvVar.prepend(QDir::toNativeSeparators(QApplication::applicationDirPath()) + "/Contents/MacOS");
|
||||
#endif
|
||||
|
||||
env.insert("PATH", pathEnvVar);
|
||||
return env;
|
||||
}
|
||||
|
||||
void OpenVpnConfigurator::initPKI(const QString &path)
|
||||
ErrorCode OpenVpnConfigurator::initPKI(const QString &path)
|
||||
{
|
||||
#ifdef Q_OS_WIN
|
||||
QProcess p;
|
||||
p.setProcessChannelMode(QProcess::MergedChannels);
|
||||
p.setProcessEnvironment(prepareEnv());
|
||||
|
||||
QString command = QString("sh.exe");
|
||||
#ifdef Q_OS_WIN
|
||||
//p.setProgram("sh.exe");
|
||||
//p.setNativeArguments(getEasyRsaShPath() + " init-pki");
|
||||
|
||||
p.setNativeArguments(getEasyRsaShPath() + " init-pki");
|
||||
p.setProgram("cmd.exe");
|
||||
p.setNativeArguments(QString("/C \"sh.exe %1\"").arg(getEasyRsaShPath() + " init-pki"));
|
||||
#else
|
||||
p.setProgram(getEasyRsaShPath());
|
||||
p.setArguments(QStringList() << "init-pki");
|
||||
#endif
|
||||
|
||||
p.setWorkingDirectory(path);
|
||||
|
||||
p.start(command);
|
||||
p.waitForFinished();
|
||||
qDebug().noquote() << p.readAll();
|
||||
// QObject::connect(&p, &QProcess::channelReadyRead, [&](){
|
||||
// qDebug().noquote() << p.readAll();
|
||||
// });
|
||||
|
||||
#endif
|
||||
p.start();
|
||||
p.waitForFinished();
|
||||
|
||||
if (p.exitCode() == 0) return ErrorCode::NoError;
|
||||
else return ErrorCode::EasyRsaError;
|
||||
}
|
||||
|
||||
QString OpenVpnConfigurator::genReq(const QString &path, const QString &clientId)
|
||||
ErrorCode OpenVpnConfigurator::genReq(const QString &path, const QString &clientId)
|
||||
{
|
||||
#ifdef Q_OS_WIN
|
||||
QProcess p;
|
||||
p.setProcessChannelMode(QProcess::MergedChannels);
|
||||
p.setProcessEnvironment(prepareEnv());
|
||||
|
||||
QString command = QString("sh.exe");
|
||||
#ifdef Q_OS_WIN
|
||||
//p.setProgram("sh.exe");
|
||||
//p.setNativeArguments(getEasyRsaShPath() + " gen-req " + clientId + " nopass");
|
||||
|
||||
p.setNativeArguments(getEasyRsaShPath() + " gen-req " + clientId + " nopass");
|
||||
p.setProgram("cmd.exe");
|
||||
p.setNativeArguments(QString("/C \"sh.exe %1\"").arg(getEasyRsaShPath() + " gen-req " + clientId + " nopass"));
|
||||
#else
|
||||
p.setArguments(QStringList() << "gen-req" << clientId << "nopass");
|
||||
p.setProgram(getEasyRsaShPath());
|
||||
#endif
|
||||
|
||||
p.setWorkingDirectory(path);
|
||||
|
||||
QObject::connect(&p, &QProcess::channelReadyRead, [&](){
|
||||
QString data = p.readAll();
|
||||
qDebug().noquote() << data;
|
||||
//qDebug().noquote() << data;
|
||||
|
||||
if (data.contains("Common Name (eg: your user, host, or server name)")) {
|
||||
p.write("\n");
|
||||
}
|
||||
});
|
||||
|
||||
p.start(command);
|
||||
p.start();
|
||||
p.waitForFinished();
|
||||
// qDebug().noquote() << p.readAll();
|
||||
|
||||
return "";
|
||||
#endif
|
||||
if (p.exitCode() == 0) return ErrorCode::NoError;
|
||||
else return ErrorCode::EasyRsaError;
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -103,7 +132,7 @@ OpenVpnConfigurator::ConnectionData OpenVpnConfigurator::createCertRequest()
|
|||
QString path = dir.path();
|
||||
|
||||
initPKI(path);
|
||||
genReq(path, connData.clientId);
|
||||
ErrorCode errorCode = genReq(path, connData.clientId);
|
||||
|
||||
|
||||
QFile req(path + "/pki/reqs/" + connData.clientId + ".req");
|
||||
|
|
@ -114,9 +143,8 @@ OpenVpnConfigurator::ConnectionData OpenVpnConfigurator::createCertRequest()
|
|||
key.open(QIODevice::ReadOnly);
|
||||
connData.privKey = key.readAll();
|
||||
|
||||
qDebug().noquote() << connData.request;
|
||||
qDebug().noquote() << connData.privKey;
|
||||
|
||||
// qDebug().noquote() << connData.request;
|
||||
// qDebug().noquote() << connData.privKey;
|
||||
|
||||
return connData;
|
||||
}
|
||||
|
|
@ -126,6 +154,11 @@ OpenVpnConfigurator::ConnectionData OpenVpnConfigurator::prepareOpenVpnConfig(co
|
|||
OpenVpnConfigurator::ConnectionData connData = OpenVpnConfigurator::createCertRequest();
|
||||
connData.host = credentials.hostName;
|
||||
|
||||
if (connData.privKey.isEmpty() || connData.request.isEmpty()) {
|
||||
*errorCode = ErrorCode::EasyRsaExecutableMissing;
|
||||
return connData;
|
||||
}
|
||||
|
||||
QString reqFileName = QString("/opt/amneziavpn_data/clients/%1.req").arg(connData.clientId);
|
||||
ErrorCode e = ServerController::uploadTextFileToContainer(credentials, connData.request, reqFileName);
|
||||
if (e) {
|
||||
|
|
|
|||
|
|
@ -29,8 +29,8 @@ private:
|
|||
static QString getEasyRsaShPath();
|
||||
|
||||
static QProcessEnvironment prepareEnv();
|
||||
static void initPKI(const QString &path);
|
||||
static QString genReq(const QString &path, const QString &clientId);
|
||||
static ErrorCode initPKI(const QString &path);
|
||||
static ErrorCode genReq(const QString &path, const QString &clientId);
|
||||
|
||||
static ConnectionData createCertRequest();
|
||||
|
||||
|
|
|
|||
|
|
@ -55,7 +55,7 @@ ErrorCode ServerController::runScript(const SshConnectionParameters &sshParams,
|
|||
// QObject::connect(proc.data(), &SshRemoteProcess::readyReadStandardOutput, [proc](){
|
||||
// QString s = proc->readAllStandardOutput();
|
||||
// if (s != "." && !s.isEmpty()) {
|
||||
// qDebug().noquote() << s << s.size();
|
||||
// qDebug().noquote() << s;
|
||||
// }
|
||||
// });
|
||||
|
||||
|
|
@ -239,7 +239,7 @@ ErrorCode ServerController::removeServer(const ServerCredentials &credentials, P
|
|||
{
|
||||
QString scriptFileName;
|
||||
|
||||
if (proto == Protocol::OpenVpn) {
|
||||
if (proto == Protocol::OpenVpn || proto == Protocol::Any) {
|
||||
scriptFileName = ":/server_scripts/remove_openvpn_server.sh";
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -49,7 +49,7 @@ void LocalClient::onReadyRead()
|
|||
if (lineLength != -1) {
|
||||
QString line = buf;
|
||||
line = line.simplified();
|
||||
qDebug().noquote() << QString("Readed line: '%1'").arg(line);
|
||||
qDebug().noquote() << QString("Read line: '%1'").arg(line);
|
||||
emit lineAvailable(line);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -60,6 +60,8 @@ int main(int argc, char *argv[])
|
|||
f.setStyleStrategy(QFont::PreferAntialias);
|
||||
app.setFont(f);
|
||||
|
||||
app.setQuitOnLastWindowClosed(false);
|
||||
|
||||
MainWindow mainWindow;
|
||||
mainWindow.show();
|
||||
|
||||
|
|
|
|||
|
|
@ -44,12 +44,12 @@ void ManagementServer::onNewConnection()
|
|||
{
|
||||
qDebug() << "New incoming connection";
|
||||
|
||||
m_socket = m_tcpServer->nextPendingConnection();
|
||||
m_socket = QPointer<QTcpSocket>(m_tcpServer->nextPendingConnection());
|
||||
m_tcpServer->close();
|
||||
|
||||
QObject::connect(m_socket, SIGNAL(disconnected()), this, SLOT(onSocketDisconnected()));
|
||||
QObject::connect(m_socket, SIGNAL(error(QAbstractSocket::SocketError)), this, SLOT(onSocketError(QAbstractSocket::SocketError)));
|
||||
QObject::connect(m_socket, SIGNAL(readyRead()), this, SLOT(onReadyRead()));
|
||||
QObject::connect(m_socket.data(), SIGNAL(disconnected()), this, SLOT(onSocketDisconnected()));
|
||||
QObject::connect(m_socket.data(), SIGNAL(error(QAbstractSocket::SocketError)), this, SLOT(onSocketError(QAbstractSocket::SocketError)));
|
||||
QObject::connect(m_socket.data(), SIGNAL(readyRead()), this, SLOT(onReadyRead()));
|
||||
}
|
||||
|
||||
void ManagementServer::onSocketError(QAbstractSocket::SocketError socketError)
|
||||
|
|
@ -61,10 +61,10 @@ void ManagementServer::onSocketError(QAbstractSocket::SocketError socketError)
|
|||
|
||||
void ManagementServer::onSocketDisconnected()
|
||||
{
|
||||
m_socket->deleteLater();
|
||||
if (m_socket) m_socket->deleteLater();
|
||||
}
|
||||
|
||||
QTcpSocket* ManagementServer::socket() const
|
||||
QPointer<QTcpSocket> ManagementServer::socket() const
|
||||
{
|
||||
if (!isOpen()) {
|
||||
return nullptr;
|
||||
|
|
@ -80,14 +80,16 @@ void ManagementServer::onReadyRead()
|
|||
bool ManagementServer::start(const QString& host, unsigned int port)
|
||||
{
|
||||
if (m_tcpServer) {
|
||||
delete m_tcpServer;
|
||||
m_tcpServer->deleteLater();
|
||||
}
|
||||
|
||||
m_tcpServer = new QTcpServer(this);
|
||||
m_tcpServer = QSharedPointer<QTcpServer>(new QTcpServer(this), [](QTcpServer *s){
|
||||
if (s) s->deleteLater();
|
||||
});
|
||||
m_tcpServer->setMaxPendingConnections(1);
|
||||
|
||||
connect(m_tcpServer, SIGNAL(acceptError(QAbstractSocket::SocketError)), this, SLOT(onAcceptError(QAbstractSocket::SocketError)));
|
||||
connect(m_tcpServer, SIGNAL(newConnection()), this, SLOT(onNewConnection()));
|
||||
connect(m_tcpServer.data(), SIGNAL(acceptError(QAbstractSocket::SocketError)), this, SLOT(onAcceptError(QAbstractSocket::SocketError)));
|
||||
connect(m_tcpServer.data(), SIGNAL(newConnection()), this, SLOT(onNewConnection()));
|
||||
|
||||
if (m_tcpServer->listen(QHostAddress(host), port)) {
|
||||
emit serverStarted();
|
||||
|
|
|
|||
|
|
@ -2,6 +2,8 @@
|
|||
#define MANAGEMENTSERVER_H
|
||||
|
||||
#include <QAbstractSocket>
|
||||
#include <QPointer>
|
||||
#include <QSharedPointer>
|
||||
#include <QString>
|
||||
|
||||
class QTcpServer;
|
||||
|
|
@ -22,7 +24,7 @@ public:
|
|||
QString readLine();
|
||||
qint64 writeCommand(const QString& message);
|
||||
|
||||
QTcpSocket* socket() const;
|
||||
QPointer<QTcpSocket> socket() const;
|
||||
|
||||
signals:
|
||||
void readyRead();
|
||||
|
|
@ -36,8 +38,8 @@ protected slots:
|
|||
void onSocketError(QAbstractSocket::SocketError socketError);
|
||||
|
||||
protected:
|
||||
QTcpServer* m_tcpServer;
|
||||
QTcpSocket* m_socket;
|
||||
QSharedPointer<QTcpServer> m_tcpServer;
|
||||
QPointer<QTcpSocket> m_socket;
|
||||
};
|
||||
|
||||
#endif // MANAGEMENTSERVER_H
|
||||
|
|
|
|||
|
|
@ -1,5 +1,6 @@
|
|||
#include <QCoreApplication>
|
||||
#include <QFileInfo>
|
||||
#include <QTcpSocket>
|
||||
|
||||
#include "communicator.h"
|
||||
#include "debug.h"
|
||||
|
|
@ -44,9 +45,12 @@ void OpenVpnProtocol::onMessageReceived(const Message& message)
|
|||
|
||||
void OpenVpnProtocol::stop()
|
||||
{
|
||||
// TODO: need refactoring
|
||||
// sendTermSignal() will evet return true while server connected
|
||||
if ((m_connectionState == VpnProtocol::ConnectionState::Preparing) ||
|
||||
(m_connectionState == VpnProtocol::ConnectionState::Connecting) ||
|
||||
(m_connectionState == VpnProtocol::ConnectionState::Connected)) {
|
||||
(m_connectionState == VpnProtocol::ConnectionState::Connected) ||
|
||||
(m_connectionState == VpnProtocol::ConnectionState::TunnelReconnecting)) {
|
||||
if (!sendTermSignal()) {
|
||||
killOpenVpnProcess();
|
||||
}
|
||||
|
|
@ -94,8 +98,11 @@ QString OpenVpnProtocol::configPath() const
|
|||
|
||||
void OpenVpnProtocol::writeCommand(const QString& command)
|
||||
{
|
||||
QTextStream stream(reinterpret_cast<QIODevice*>(m_managementServer.socket()));
|
||||
QIODevice *device = dynamic_cast<QIODevice*>(m_managementServer.socket().data());
|
||||
if (device) {
|
||||
QTextStream stream(device);
|
||||
stream << command << endl;
|
||||
}
|
||||
}
|
||||
|
||||
QString OpenVpnProtocol::openVpnExecPath() const
|
||||
|
|
@ -115,7 +122,7 @@ ErrorCode OpenVpnProtocol::start()
|
|||
m_openVpnStateSigTermHandlerTimer.stop();
|
||||
stop();
|
||||
|
||||
if (communicator() && !communicator()->connected()) {
|
||||
if (communicator() && !communicator()->isConnected()) {
|
||||
setLastError(ErrorCode::AmneziaServiceConnectionFailed);
|
||||
return lastError();
|
||||
}
|
||||
|
|
@ -206,6 +213,18 @@ void OpenVpnProtocol::onReadyReadDataFromManagementServer()
|
|||
} else if (line.contains("EXITING,SIGTER")) {
|
||||
openVpnStateSigTermHandler();
|
||||
continue;
|
||||
} else if (line.contains("RECONNECTING")) {
|
||||
setConnectionState(VpnProtocol::ConnectionState::TunnelReconnecting);
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
if (line.contains("FATAL")) {
|
||||
if (line.contains("tap-windows6 adapters on this system are currently in use or disabled")) {
|
||||
emit protocolError(ErrorCode::OpenVpnAdaptersInUseError);
|
||||
}
|
||||
else {
|
||||
emit protocolError(ErrorCode::OpenVpnUnknownError);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -15,7 +15,7 @@ class OpenVpnProtocol : public VpnProtocol
|
|||
|
||||
public:
|
||||
explicit OpenVpnProtocol(const QString& args = QString(), QObject* parent = nullptr);
|
||||
~OpenVpnProtocol();
|
||||
~OpenVpnProtocol() override;
|
||||
|
||||
ErrorCode start() override;
|
||||
void stop() override;
|
||||
|
|
|
|||
|
|
@ -3,6 +3,7 @@
|
|||
|
||||
#include "communicator.h"
|
||||
#include "vpnprotocol.h"
|
||||
#include "core/errorstrings.h"
|
||||
|
||||
Communicator* VpnProtocol::m_communicator = nullptr;
|
||||
|
||||
|
|
@ -34,7 +35,10 @@ Communicator* VpnProtocol::communicator()
|
|||
void VpnProtocol::setLastError(ErrorCode lastError)
|
||||
{
|
||||
m_lastError = lastError;
|
||||
qCritical().noquote() << m_lastError;
|
||||
if (lastError){
|
||||
setConnectionState(ConnectionState::Disconnected);
|
||||
}
|
||||
qCritical().noquote() << "VpnProtocol error, code" << m_lastError << errorString(m_lastError);
|
||||
}
|
||||
|
||||
ErrorCode VpnProtocol::lastError() const
|
||||
|
|
@ -93,14 +97,14 @@ void VpnProtocol::setConnectionState(VpnProtocol::ConnectionState state)
|
|||
QString VpnProtocol::textConnectionState(ConnectionState connectionState)
|
||||
{
|
||||
switch (connectionState) {
|
||||
case ConnectionState::Unknown: return "Unknown";
|
||||
case ConnectionState::Disconnected: return "Disconnected";
|
||||
case ConnectionState::Preparing: return "Preparing";
|
||||
case ConnectionState::Connecting: return "Connecting";
|
||||
case ConnectionState::Connected: return "Connected";
|
||||
case ConnectionState::Disconnecting: return "Disconnecting";
|
||||
case ConnectionState::TunnelReconnecting: return "TunnelReconnecting";
|
||||
case ConnectionState::Error: return "Error";
|
||||
case ConnectionState::Unknown: return tr("Unknown");
|
||||
case ConnectionState::Disconnected: return tr("Disconnected");
|
||||
case ConnectionState::Preparing: return tr("Preparing");
|
||||
case ConnectionState::Connecting: return tr("Connecting...");
|
||||
case ConnectionState::Connected: return tr("Connected");
|
||||
case ConnectionState::Disconnecting: return tr("Disconnecting...");
|
||||
case ConnectionState::TunnelReconnecting: return tr("Reconnecting...");
|
||||
case ConnectionState::Error: return tr("Error");
|
||||
default:
|
||||
;
|
||||
}
|
||||
|
|
@ -113,12 +117,12 @@ QString VpnProtocol::textConnectionState() const
|
|||
return textConnectionState(m_connectionState);
|
||||
}
|
||||
|
||||
bool VpnProtocol::connected() const
|
||||
bool VpnProtocol::onConnected() const
|
||||
{
|
||||
return m_connectionState == ConnectionState::Connected;
|
||||
}
|
||||
|
||||
bool VpnProtocol::disconnected() const
|
||||
bool VpnProtocol::onDisconnected() const
|
||||
{
|
||||
return m_connectionState == ConnectionState::Disconnected;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -25,8 +25,8 @@ public:
|
|||
static void initializeCommunicator(QObject* parent = nullptr);
|
||||
|
||||
|
||||
virtual bool connected() const;
|
||||
virtual bool disconnected() const;
|
||||
virtual bool onConnected() const;
|
||||
virtual bool onDisconnected() const;
|
||||
virtual ErrorCode start() = 0;
|
||||
virtual void stop() = 0;
|
||||
|
||||
|
|
@ -39,6 +39,7 @@ signals:
|
|||
void bytesChanged(quint64 receivedBytes, quint64 sentBytes);
|
||||
void connectionStateChanged(VpnProtocol::ConnectionState state);
|
||||
void timeoutTimerEvent();
|
||||
void protocolError(amnezia::ErrorCode e);
|
||||
|
||||
protected slots:
|
||||
virtual void onTimeout();
|
||||
|
|
|
|||
|
|
@ -23,7 +23,7 @@ public:
|
|||
void setUserName(const QString& login);
|
||||
void setPassword(const QString& password);
|
||||
void setServerName(const QString& serverName);
|
||||
void setServerPort(int serverPort);
|
||||
void setServerPort(int serverPort = 22);
|
||||
void setServerCredentials(const ServerCredentials &credentials);
|
||||
|
||||
QString userName() const { return m_userName; }
|
||||
|
|
|
|||
|
|
@ -1,5 +1,9 @@
|
|||
#include <QApplication>
|
||||
#include <QDesktopServices>
|
||||
#include <QKeyEvent>
|
||||
#include <QMenu>
|
||||
#include <QMessageBox>
|
||||
#include <QMetaEnum>
|
||||
#include <QSysInfo>
|
||||
#include <QThread>
|
||||
#include <QTimer>
|
||||
|
|
@ -38,10 +42,8 @@ MainWindow::MainWindow(QWidget *parent) :
|
|||
ui->stackedWidget_main->setSpeed(200);
|
||||
ui->stackedWidget_main->setAnimation(QEasingCurve::Linear);
|
||||
|
||||
ui->label_new_server_wait_info->setVisible(false);
|
||||
ui->progressBar_new_server_connection->setMinimum(0);
|
||||
ui->progressBar_new_server_connection->setMaximum(300);
|
||||
|
||||
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);
|
||||
|
|
@ -51,22 +53,13 @@ MainWindow::MainWindow(QWidget *parent) :
|
|||
// Post initialization
|
||||
|
||||
if (m_settings->haveAuthData()) {
|
||||
goToPage(Page::Vpn);
|
||||
goToPage(Page::Vpn, true, false);
|
||||
} else {
|
||||
goToPage(Page::Initialization);
|
||||
goToPage(Page::Start, true, false);
|
||||
}
|
||||
|
||||
//goToPage(Page::Initialization);
|
||||
|
||||
connect(ui->pushButton_blocked_list, SIGNAL(clicked(bool)), this, SLOT(onPushButtonBlockedListClicked(bool)));
|
||||
connect(ui->pushButton_connect, SIGNAL(toggled(bool)), this, SLOT(onPushButtonConnectToggled(bool)));
|
||||
connect(ui->pushButton_settings, SIGNAL(clicked(bool)), this, SLOT(onPushButtonSettingsClicked(bool)));
|
||||
|
||||
connect(ui->pushButton_back_from_sites, SIGNAL(clicked(bool)), this, SLOT(onPushButtonBackFromSitesClicked(bool)));
|
||||
connect(ui->pushButton_back_from_settings, SIGNAL(clicked(bool)), this, SLOT(onPushButtonBackFromSettingsClicked(bool)));
|
||||
connect(ui->pushButton_new_server_setup, SIGNAL(clicked(bool)), this, SLOT(onPushButtonNewServerSetup(bool)));
|
||||
connect(ui->pushButton_back_from_new_server, SIGNAL(clicked(bool)), this, SLOT(onPushButtonBackFromNewServerClicked(bool)));
|
||||
connect(ui->pushButton_new_server_connect_with_new_data, SIGNAL(clicked(bool)), this, SLOT(onPushButtonNewServerConnectWithNewData(bool)));
|
||||
setupTray();
|
||||
setupUiConnections();
|
||||
|
||||
setFixedSize(width(),height());
|
||||
|
||||
|
|
@ -78,6 +71,7 @@ MainWindow::MainWindow(QWidget *parent) :
|
|||
m_vpnConnection = new VpnConnection(this);
|
||||
connect(m_vpnConnection, SIGNAL(bytesChanged(quint64, quint64)), this, SLOT(onBytesChanged(quint64, quint64)));
|
||||
connect(m_vpnConnection, SIGNAL(connectionStateChanged(VpnProtocol::ConnectionState)), this, SLOT(onConnectionStateChanged(VpnProtocol::ConnectionState)));
|
||||
connect(m_vpnConnection, SIGNAL(vpnProtocolError(amnezia::ErrorCode)), this, SLOT(onVpnProtocolError(amnezia::ErrorCode)));
|
||||
|
||||
onConnectionStateChanged(VpnProtocol::ConnectionState::Disconnected);
|
||||
|
||||
|
|
@ -92,7 +86,7 @@ MainWindow::~MainWindow()
|
|||
for (int i = 0; i < 50; i++) {
|
||||
qApp->processEvents(QEventLoop::ExcludeUserInputEvents);
|
||||
QThread::msleep(100);
|
||||
if (m_vpnConnection->disconnected()) {
|
||||
if (m_vpnConnection->onDisconnected()) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
|
@ -103,11 +97,48 @@ MainWindow::~MainWindow()
|
|||
qDebug() << "Application closed";
|
||||
}
|
||||
|
||||
void MainWindow::goToPage(Page page)
|
||||
void MainWindow::goToPage(Page page, bool reset, bool slide)
|
||||
{
|
||||
ui->stackedWidget_main->slideInIdx(static_cast<int>(page));
|
||||
if (reset) {
|
||||
if (page == Page::NewServer) {
|
||||
ui->label_new_server_wait_info->hide();
|
||||
ui->label_new_server_wait_info->clear();
|
||||
|
||||
ui->progressBar_new_server_connection->setMinimum(0);
|
||||
ui->progressBar_new_server_connection->setMaximum(300);
|
||||
}
|
||||
if (page == Page::ServerSettings) {
|
||||
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()));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
if (slide)
|
||||
ui->stackedWidget_main->slideInWidget(getPageWidget(page));
|
||||
else
|
||||
ui->stackedWidget_main->setCurrentWidget(getPageWidget(page));
|
||||
}
|
||||
|
||||
QWidget *MainWindow::getPageWidget(MainWindow::Page page)
|
||||
{
|
||||
switch (page) {
|
||||
case(Page::Start): return ui->page_start;
|
||||
case(Page::NewServer): return ui->page_new_server;
|
||||
case(Page::Vpn): return ui->page_vpn;
|
||||
case(Page::GeneralSettings): return ui->page_general_settings;
|
||||
case(Page::ServerSettings): return ui->page_server_settings;
|
||||
case(Page::ShareConnection): return ui->page_share_connection;
|
||||
case(Page::Sites): return ui->page_sites;
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
|
||||
bool MainWindow::eventFilter(QObject *obj, QEvent *event)
|
||||
{
|
||||
if (obj == ui->widget_tittlebar) {
|
||||
|
|
@ -151,7 +182,13 @@ void MainWindow::keyPressEvent(QKeyEvent *event)
|
|||
}
|
||||
}
|
||||
|
||||
void MainWindow::onPushButtonNewServerConnectWithNewData(bool clicked)
|
||||
void MainWindow::closeEvent(QCloseEvent *event)
|
||||
{
|
||||
event->ignore();
|
||||
hide();
|
||||
}
|
||||
|
||||
void MainWindow::onPushButtonNewServerConnectWithNewData(bool)
|
||||
{
|
||||
if (ui->lineEdit_new_server_ip->text().isEmpty() ||
|
||||
ui->lineEdit_new_server_login->text().isEmpty() ||
|
||||
|
|
@ -171,48 +208,67 @@ void MainWindow::onPushButtonNewServerConnectWithNewData(bool clicked)
|
|||
serverCredentials.userName = ui->lineEdit_new_server_login->text();
|
||||
serverCredentials.password = ui->lineEdit_new_server_password->text();
|
||||
|
||||
bool ok = installServer(serverCredentials,
|
||||
ui->page_new_server,
|
||||
ui->progressBar_new_server_connection,
|
||||
ui->pushButton_new_server_connect_with_new_data,
|
||||
ui->label_new_server_wait_info);
|
||||
|
||||
if (ok) {
|
||||
m_settings->setServerCredentials(serverCredentials);
|
||||
m_settings->save();
|
||||
|
||||
ui->page_new_server->setEnabled(false);
|
||||
ui->pushButton_new_server_connect_with_new_data->setVisible(false);
|
||||
ui->label_new_server_wait_info->setVisible(true);
|
||||
goToPage(Page::Vpn);
|
||||
qApp->processEvents();
|
||||
|
||||
onConnect();
|
||||
}
|
||||
}
|
||||
|
||||
bool MainWindow::installServer(ServerCredentials credentials,
|
||||
QWidget *page, QProgressBar *progress, QPushButton *button, QLabel *info)
|
||||
{
|
||||
page->setEnabled(false);
|
||||
button->setVisible(false);
|
||||
|
||||
info->setVisible(true);
|
||||
info->setText(tr("Please wait, configuring process may take up to 5 minutes"));
|
||||
|
||||
QTimer timer;
|
||||
connect(&timer, &QTimer::timeout, [&](){
|
||||
ui->progressBar_new_server_connection->setValue(ui->progressBar_new_server_connection->value() + 1);
|
||||
connect(&timer, &QTimer::timeout, [progress](){
|
||||
progress->setValue(progress->value() + 1);
|
||||
});
|
||||
|
||||
ui->progressBar_new_server_connection->setValue(0);
|
||||
progress->setValue(0);
|
||||
timer.start(1000);
|
||||
|
||||
|
||||
ErrorCode e = ServerController::setupServer(serverCredentials, Protocol::Any);
|
||||
ErrorCode e = ServerController::setupServer(credentials, Protocol::Any);
|
||||
if (e) {
|
||||
ui->page_new_server->setEnabled(true);
|
||||
ui->pushButton_new_server_connect_with_new_data->setVisible(true);
|
||||
ui->label_new_server_wait_info->setVisible(false);
|
||||
page->setEnabled(true);
|
||||
button->setVisible(true);
|
||||
info->setVisible(false);
|
||||
|
||||
QMessageBox::warning(this, APPLICATION_NAME,
|
||||
tr("Error occurred while configuring server.") + "\n" +
|
||||
errorString(e) + "\n" +
|
||||
tr("See logs for details."));
|
||||
|
||||
return;
|
||||
return false;
|
||||
}
|
||||
|
||||
// just ui progressbar tweak
|
||||
timer.stop();
|
||||
|
||||
int remaining_val = ui->progressBar_new_server_connection->maximum() - ui->progressBar_new_server_connection->value();
|
||||
int remaining_val = progress->maximum() - progress->value();
|
||||
|
||||
if (remaining_val > 0) {
|
||||
QTimer timer1;
|
||||
QEventLoop loop1;
|
||||
|
||||
connect(&timer1, &QTimer::timeout, [&](){
|
||||
ui->progressBar_new_server_connection->setValue(ui->progressBar_new_server_connection->value() + 1);
|
||||
if (ui->progressBar_new_server_connection->value() >= ui->progressBar_new_server_connection->maximum()) {
|
||||
progress->setValue(progress->value() + 1);
|
||||
if (progress->value() >= progress->maximum()) {
|
||||
loop1.quit();
|
||||
}
|
||||
});
|
||||
|
|
@ -221,44 +277,61 @@ void MainWindow::onPushButtonNewServerConnectWithNewData(bool clicked)
|
|||
loop1.exec();
|
||||
}
|
||||
|
||||
goToPage(Page::Vpn);
|
||||
ui->pushButton_connect->setChecked(true);
|
||||
button->show();
|
||||
page->setEnabled(true);
|
||||
info->setText(tr("Amnezia server installed"));
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void MainWindow::onPushButtonReinstallServer(bool)
|
||||
{
|
||||
onDisconnect();
|
||||
installServer(m_settings->serverCredentials(),
|
||||
ui->page_server_settings,
|
||||
ui->progressBar_server_settings_reinstall,
|
||||
ui->pushButton_server_settings_reinstall,
|
||||
ui->label_server_settings_wait_info);
|
||||
}
|
||||
|
||||
void MainWindow::onPushButtonClearServer(bool)
|
||||
{
|
||||
onDisconnect();
|
||||
|
||||
ErrorCode e = ServerController::removeServer(m_settings->serverCredentials(), Protocol::Any);
|
||||
if (e) {
|
||||
QMessageBox::warning(this, APPLICATION_NAME,
|
||||
tr("Error occurred while configuring server.") + "\n" +
|
||||
errorString(e) + "\n" +
|
||||
tr("See logs for details."));
|
||||
|
||||
return;
|
||||
}
|
||||
else {
|
||||
ui->label_server_settings_wait_info->show();
|
||||
ui->label_server_settings_wait_info->setText(tr("Amnezia server successfully uninstalled"));
|
||||
}
|
||||
}
|
||||
|
||||
void MainWindow::onPushButtonForgetServer(bool)
|
||||
{
|
||||
onDisconnect();
|
||||
|
||||
m_settings->setUserName("");
|
||||
m_settings->setPassword("");
|
||||
m_settings->setServerName("");
|
||||
m_settings->setServerPort();
|
||||
|
||||
m_settings->save();
|
||||
|
||||
goToPage(Page::Start);
|
||||
}
|
||||
|
||||
void MainWindow::onBytesChanged(quint64 receivedData, quint64 sentData)
|
||||
{
|
||||
ui->label_speed_received->setText(VpnConnection::bytesToText(receivedData));
|
||||
ui->label_speed_sent->setText(VpnConnection::bytesToText(sentData));
|
||||
}
|
||||
|
||||
void MainWindow::onPushButtonBackFromNewServerClicked(bool)
|
||||
{
|
||||
goToPage(Page::Initialization);
|
||||
}
|
||||
|
||||
void MainWindow::onPushButtonNewServerSetup(bool)
|
||||
{
|
||||
goToPage(Page::NewServer);
|
||||
}
|
||||
|
||||
void MainWindow::onPushButtonBackFromSettingsClicked(bool)
|
||||
{
|
||||
goToPage(Page::Vpn);
|
||||
}
|
||||
|
||||
void MainWindow::onPushButtonBackFromSitesClicked(bool)
|
||||
{
|
||||
goToPage(Page::Vpn);
|
||||
}
|
||||
|
||||
void MainWindow::onPushButtonBlockedListClicked(bool)
|
||||
{
|
||||
goToPage(Page::Sites);
|
||||
}
|
||||
|
||||
void MainWindow::onPushButtonSettingsClicked(bool)
|
||||
{
|
||||
goToPage(Page::SomeSettings);
|
||||
qDebug() << "MainWindow::onBytesChanged" << receivedData << sentData;
|
||||
ui->label_speed_received->setText(VpnConnection::bytesPerSecToText(receivedData));
|
||||
ui->label_speed_sent->setText(VpnConnection::bytesPerSecToText(sentData));
|
||||
}
|
||||
|
||||
void MainWindow::onConnectionStateChanged(VpnProtocol::ConnectionState state)
|
||||
|
|
@ -266,6 +339,8 @@ void MainWindow::onConnectionStateChanged(VpnProtocol::ConnectionState state)
|
|||
bool pushButtonConnectEnabled = false;
|
||||
ui->label_state->setText(VpnProtocol::textConnectionState(state));
|
||||
|
||||
setTrayState(state);
|
||||
|
||||
switch (state) {
|
||||
case VpnProtocol::ConnectionState::Disconnected:
|
||||
onBytesChanged(0,0);
|
||||
|
|
@ -285,7 +360,7 @@ void MainWindow::onConnectionStateChanged(VpnProtocol::ConnectionState state)
|
|||
pushButtonConnectEnabled = false;
|
||||
break;
|
||||
case VpnProtocol::ConnectionState::TunnelReconnecting:
|
||||
pushButtonConnectEnabled = false;
|
||||
pushButtonConnectEnabled = true;
|
||||
break;
|
||||
case VpnProtocol::ConnectionState::Error:
|
||||
pushButtonConnectEnabled = true;
|
||||
|
|
@ -299,25 +374,188 @@ void MainWindow::onConnectionStateChanged(VpnProtocol::ConnectionState state)
|
|||
ui->pushButton_connect->setEnabled(pushButtonConnectEnabled);
|
||||
}
|
||||
|
||||
void MainWindow::onPushButtonConnectToggled(bool checked)
|
||||
void MainWindow::onVpnProtocolError(ErrorCode errorCode)
|
||||
{
|
||||
// TODO fix crash on Windows when starting vpn and another vpn already connected
|
||||
//QMessageBox::critical(this, APPLICATION_NAME, errorString(errorCode));
|
||||
}
|
||||
|
||||
void MainWindow::onPushButtonConnectClicked(bool checked)
|
||||
{
|
||||
if (checked) {
|
||||
onConnect();
|
||||
} else {
|
||||
onDisconnect();
|
||||
}
|
||||
}
|
||||
|
||||
void MainWindow::setupTray()
|
||||
{
|
||||
m_menu = new QMenu();
|
||||
//m_menu->setStyleSheet(styleSheet());
|
||||
|
||||
m_menu->addAction(QIcon(":/images/tray/application.png"), tr("Show") + " " + APPLICATION_NAME, this, SLOT(show()));
|
||||
m_menu->addSeparator();
|
||||
m_trayActionConnect = m_menu->addAction(tr("Connect"), this, SLOT(onConnect()));
|
||||
m_trayActionDisconnect = m_menu->addAction(tr("Disconnect"), this, SLOT(onDisconnect()));
|
||||
|
||||
m_menu->addSeparator();
|
||||
|
||||
m_menu->addAction(QIcon(":/images/tray/link.png"), tr("Visit Website"), [&](){
|
||||
QDesktopServices::openUrl(QUrl("https://amnezia.org"));
|
||||
});
|
||||
|
||||
m_menu->addAction(QIcon(":/images/tray/cancel.png"), tr("Quit") + " " + APPLICATION_NAME, this, [&](){
|
||||
QMessageBox msgBox(QMessageBox::Question, tr("Exit"), tr("Do you really want to quit?"),
|
||||
QMessageBox::Yes | QMessageBox::No, Q_NULLPTR, Qt::Dialog | Qt::MSWindowsFixedSizeDialogHint | Qt::WindowStaysOnTopHint);
|
||||
msgBox.setDefaultButton(QMessageBox::No);
|
||||
msgBox.raise();
|
||||
if (msgBox.exec() == QMessageBox::Yes) {
|
||||
qApp->quit();
|
||||
}
|
||||
});
|
||||
|
||||
m_tray.setContextMenu(m_menu);
|
||||
setTrayState(VpnProtocol::ConnectionState::Disconnected);
|
||||
|
||||
m_tray.show();
|
||||
|
||||
connect(&m_tray, &QSystemTrayIcon::activated, this, &MainWindow::onTrayActivated);
|
||||
}
|
||||
|
||||
void MainWindow::setTrayIcon(const QString &iconPath)
|
||||
{
|
||||
m_tray.setIcon(QIcon(QPixmap(iconPath).scaled(128,128)));
|
||||
}
|
||||
|
||||
MainWindow::Page MainWindow::currentPage()
|
||||
{
|
||||
QWidget *currentPage = ui->stackedWidget_main->currentWidget();
|
||||
QMetaEnum e = QMetaEnum::fromType<MainWindow::Page>();
|
||||
|
||||
for (int k = 0; k < e.keyCount(); k++) {
|
||||
Page p = static_cast<MainWindow::Page>(e.value(k));
|
||||
if (currentPage == getPageWidget(p)) return p;
|
||||
}
|
||||
|
||||
return Page::Start;
|
||||
}
|
||||
|
||||
void MainWindow::setupUiConnections()
|
||||
{
|
||||
connect(ui->pushButton_close, &QPushButton::clicked, this, [this](){
|
||||
if (currentPage() == Page::Start || currentPage() == Page::NewServer) qApp->quit();
|
||||
else hide();
|
||||
});
|
||||
connect(ui->pushButton_general_settings_exit, &QPushButton::clicked, this, [&](){ qApp->quit(); });
|
||||
connect(ui->pushButton_new_server_get_info, &QPushButton::clicked, this, [&](){
|
||||
QDesktopServices::openUrl(QUrl("https://amnezia.org"));
|
||||
});
|
||||
|
||||
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_server_settings_reinstall, SIGNAL(clicked(bool)), this, SLOT(onPushButtonReinstallServer(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_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_back_from_sites, &QPushButton::clicked, this, [this](){ goToPage(Page::Vpn); });
|
||||
connect(ui->pushButton_back_from_settings, &QPushButton::clicked, this, [this](){ goToPage(Page::Vpn); });
|
||||
connect(ui->pushButton_back_from_new_server, &QPushButton::clicked, this, [this](){ goToPage(Page::Start); });
|
||||
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); });
|
||||
|
||||
}
|
||||
|
||||
void MainWindow::setTrayState(VpnProtocol::ConnectionState state)
|
||||
{
|
||||
QString resourcesPath = ":/images/tray/%1";
|
||||
|
||||
m_trayActionDisconnect->setEnabled(state == VpnProtocol::ConnectionState::Connected);
|
||||
m_trayActionConnect->setEnabled(state == VpnProtocol::ConnectionState::Disconnected);
|
||||
|
||||
switch (state) {
|
||||
case VpnProtocol::ConnectionState::Disconnected:
|
||||
setTrayIcon(QString(resourcesPath).arg(DisconnectedTrayIconName));
|
||||
break;
|
||||
case VpnProtocol::ConnectionState::Preparing:
|
||||
setTrayIcon(QString(resourcesPath).arg(DisconnectedTrayIconName));
|
||||
break;
|
||||
case VpnProtocol::ConnectionState::Connecting:
|
||||
setTrayIcon(QString(resourcesPath).arg(DisconnectedTrayIconName));
|
||||
break;
|
||||
case VpnProtocol::ConnectionState::Connected:
|
||||
setTrayIcon(QString(resourcesPath).arg(ConnectedTrayIconName));
|
||||
break;
|
||||
case VpnProtocol::ConnectionState::Disconnecting:
|
||||
setTrayIcon(QString(resourcesPath).arg(DisconnectedTrayIconName));
|
||||
break;
|
||||
case VpnProtocol::ConnectionState::TunnelReconnecting:
|
||||
setTrayIcon(QString(resourcesPath).arg(DisconnectedTrayIconName));
|
||||
break;
|
||||
case VpnProtocol::ConnectionState::Error:
|
||||
setTrayIcon(QString(resourcesPath).arg(ErrorTrayIconName));
|
||||
break;
|
||||
case VpnProtocol::ConnectionState::Unknown:
|
||||
default:
|
||||
setTrayIcon(QString(resourcesPath).arg(DisconnectedTrayIconName));
|
||||
}
|
||||
|
||||
//#ifdef Q_OS_MAC
|
||||
// // Get theme from current user (note, this app can be launched as root application and in this case this theme can be different from theme of real current user )
|
||||
// bool darkTaskBar = MacOSFunctions::instance().isMenuBarUseDarkTheme();
|
||||
// darkTaskBar = forceUseBrightIcons ? true : darkTaskBar;
|
||||
// resourcesPath = ":/images_mac/tray_icon/%1";
|
||||
// useIconName = useIconName.replace(".png", darkTaskBar ? "@2x.png" : " dark@2x.png");
|
||||
//#endif
|
||||
|
||||
}
|
||||
|
||||
void MainWindow::onTrayActivated(QSystemTrayIcon::ActivationReason reason)
|
||||
{
|
||||
if(reason == QSystemTrayIcon::DoubleClick || reason == QSystemTrayIcon::Trigger) {
|
||||
show();
|
||||
raise();
|
||||
setWindowState(Qt::WindowActive);
|
||||
}
|
||||
}
|
||||
|
||||
void MainWindow::onConnect()
|
||||
{
|
||||
ui->pushButton_connect->setChecked(true);
|
||||
qApp->processEvents();
|
||||
|
||||
// TODO: Call connectToVpn with restricted server account
|
||||
ServerCredentials credentials = m_settings->serverCredentials();
|
||||
|
||||
ErrorCode errorCode = m_vpnConnection->connectToVpn(credentials);
|
||||
if (errorCode) {
|
||||
ui->pushButton_connect->setChecked(false);
|
||||
//ui->pushButton_connect->setChecked(false);
|
||||
QMessageBox::critical(this, APPLICATION_NAME, errorString(errorCode));
|
||||
return;
|
||||
}
|
||||
ui->pushButton_connect->setEnabled(false);
|
||||
} else {
|
||||
}
|
||||
|
||||
void MainWindow::onDisconnect()
|
||||
{
|
||||
ui->pushButton_connect->setChecked(false);
|
||||
m_vpnConnection->disconnectFromVpn();
|
||||
}
|
||||
|
||||
void MainWindow::onTrayActionConnect()
|
||||
{
|
||||
if(m_trayActionConnect->text() == tr("Connect")) {
|
||||
onConnect();
|
||||
} else if(m_trayActionConnect->text() == tr("Disconnect")) {
|
||||
onDisconnect();
|
||||
}
|
||||
}
|
||||
|
||||
void MainWindow::on_pushButton_close_clicked()
|
||||
{
|
||||
qApp->exit();
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,7 +1,11 @@
|
|||
#ifndef MAINWINDOW_H
|
||||
#define MAINWINDOW_H
|
||||
|
||||
#include <QLabel>
|
||||
#include <QMainWindow>
|
||||
#include <QProgressBar>
|
||||
#include <QPushButton>
|
||||
#include <QSystemTrayIcon>
|
||||
|
||||
#include "framelesswindow.h"
|
||||
#include "protocols/vpnprotocol.h"
|
||||
|
|
@ -29,33 +33,61 @@ public:
|
|||
explicit MainWindow(QWidget *parent = nullptr);
|
||||
~MainWindow();
|
||||
|
||||
enum class Page {Initialization = 0, NewServer = 1, Vpn = 2, Sites = 3, SomeSettings = 4, Share = 5};
|
||||
enum Page {Start, NewServer, Vpn, GeneralSettings, ServerSettings, ShareConnection, Sites};
|
||||
Q_ENUM(Page)
|
||||
|
||||
private slots:
|
||||
void onBytesChanged(quint64 receivedBytes, quint64 sentBytes);
|
||||
void onConnectionStateChanged(VpnProtocol::ConnectionState state);
|
||||
void onPushButtonBackFromNewServerClicked(bool clicked);
|
||||
void onPushButtonBackFromSettingsClicked(bool clicked);
|
||||
void onPushButtonBackFromSitesClicked(bool clicked);
|
||||
void onPushButtonBlockedListClicked(bool clicked);
|
||||
void onPushButtonConnectToggled(bool checked);
|
||||
void onPushButtonNewServerConnectWithNewData(bool clicked);
|
||||
void onPushButtonNewServerSetup(bool clicked);
|
||||
void onPushButtonSettingsClicked(bool clicked);
|
||||
void onVpnProtocolError(amnezia::ErrorCode errorCode);
|
||||
|
||||
void onPushButtonConnectClicked(bool checked);
|
||||
void onPushButtonNewServerConnectWithNewData(bool);
|
||||
|
||||
void onPushButtonReinstallServer(bool);
|
||||
void onPushButtonClearServer(bool);
|
||||
void onPushButtonForgetServer(bool);
|
||||
|
||||
void onTrayActionConnect(); // connect from context menu
|
||||
void setTrayState(VpnProtocol::ConnectionState state);
|
||||
|
||||
void onTrayActivated(QSystemTrayIcon::ActivationReason reason);
|
||||
|
||||
void onConnect();
|
||||
void onDisconnect();
|
||||
|
||||
void on_pushButton_close_clicked();
|
||||
|
||||
private:
|
||||
void goToPage(Page page);
|
||||
void goToPage(Page page, bool reset = true, bool slide = true);
|
||||
QWidget *getPageWidget(Page page);
|
||||
Page currentPage();
|
||||
|
||||
bool installServer(ServerCredentials credentials, QWidget *page, QProgressBar *progress, QPushButton *button, QLabel *info);
|
||||
|
||||
void setupTray();
|
||||
void setTrayIcon(const QString &iconPath);
|
||||
|
||||
void setupUiConnections();
|
||||
|
||||
Ui::MainWindow *ui;
|
||||
VpnConnection* m_vpnConnection;
|
||||
Settings* m_settings;
|
||||
|
||||
QAction* m_trayActionConnect;
|
||||
QAction* m_trayActionDisconnect;
|
||||
|
||||
QSystemTrayIcon m_tray;
|
||||
QMenu* m_menu;
|
||||
|
||||
bool canMove = false;
|
||||
QPoint offset;
|
||||
bool eventFilter(QObject *obj, QEvent *event) override;
|
||||
void keyPressEvent(QKeyEvent* event) override;
|
||||
void closeEvent(QCloseEvent *event) override;
|
||||
|
||||
const QString ConnectedTrayIconName = "active.png";
|
||||
const QString DisconnectedTrayIconName = "default.png";
|
||||
const QString ErrorTrayIconName = "error.png";
|
||||
};
|
||||
|
||||
#endif // MAINWINDOW_H
|
||||
|
|
|
|||
|
|
@ -269,7 +269,7 @@ QStackedWidget QWidget {
|
|||
<property name="currentIndex">
|
||||
<number>1</number>
|
||||
</property>
|
||||
<widget class="QWidget" name="page_connect_server">
|
||||
<widget class="QWidget" name="page_start">
|
||||
<widget class="QLabel" name="label_23">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
|
|
@ -671,7 +671,7 @@ border-radius: 4px;
|
|||
<string>Connect</string>
|
||||
</property>
|
||||
</widget>
|
||||
<widget class="QPushButton" name="pushButton">
|
||||
<widget class="QPushButton" name="pushButton_new_server_get_info">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>50</x>
|
||||
|
|
@ -680,6 +680,9 @@ border-radius: 4px;
|
|||
<height>21</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="cursor">
|
||||
<cursorShape>PointingHandCursor</cursorShape>
|
||||
</property>
|
||||
<property name="styleSheet">
|
||||
<string notr="true">font-family: Lato;
|
||||
font-style: normal;
|
||||
|
|
@ -815,12 +818,12 @@ QPushButton:hover {
|
|||
<zorder>lineEdit_new_server_login</zorder>
|
||||
<zorder>lineEdit_new_server_password</zorder>
|
||||
<zorder>pushButton_new_server_connect_with_new_data</zorder>
|
||||
<zorder>pushButton</zorder>
|
||||
<zorder>pushButton_new_server_get_info</zorder>
|
||||
<zorder>pushButton_back_from_new_server</zorder>
|
||||
<zorder>label_7</zorder>
|
||||
<zorder>label_new_server_wait_info</zorder>
|
||||
</widget>
|
||||
<widget class="QWidget" name="page_amnezia">
|
||||
<widget class="QWidget" name="page_vpn">
|
||||
<property name="styleSheet">
|
||||
<string notr="true"/>
|
||||
</property>
|
||||
|
|
@ -833,9 +836,6 @@ QPushButton:hover {
|
|||
<height>325</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="cursor">
|
||||
<cursorShape>PointingHandCursor</cursorShape>
|
||||
</property>
|
||||
<property name="styleSheet">
|
||||
<string notr="true">border-image: url(:/images/background_connected.png);</string>
|
||||
</property>
|
||||
|
|
@ -1011,6 +1011,9 @@ line-height: 21px;
|
|||
<height>40</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="cursor">
|
||||
<cursorShape>PointingHandCursor</cursorShape>
|
||||
</property>
|
||||
<property name="styleSheet">
|
||||
<string notr="true">QPushButton:!checked {
|
||||
image: url(:/images/connect_button_disconnected.png);
|
||||
|
|
@ -1114,6 +1117,9 @@ color: #181922;
|
|||
<property name="text">
|
||||
<string>For all connections</string>
|
||||
</property>
|
||||
<property name="checked">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
</widget>
|
||||
<widget class="QRadioButton" name="radioButton_2">
|
||||
<property name="enabled">
|
||||
|
|
@ -1131,7 +1137,7 @@ color: #181922;
|
|||
<string>For selected sites</string>
|
||||
</property>
|
||||
<property name="checked">
|
||||
<bool>true</bool>
|
||||
<bool>false</bool>
|
||||
</property>
|
||||
</widget>
|
||||
</widget>
|
||||
|
|
@ -1392,7 +1398,7 @@ color: #333333;</string>
|
|||
</property>
|
||||
</widget>
|
||||
</widget>
|
||||
<widget class="QWidget" name="page_settings">
|
||||
<widget class="QWidget" name="page_general_settings">
|
||||
<widget class="QPushButton" name="pushButton_back_from_settings">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
|
|
@ -1441,7 +1447,7 @@ QPushButton:hover {
|
|||
<string/>
|
||||
</property>
|
||||
</widget>
|
||||
<widget class="QPushButton" name="pushButton_2">
|
||||
<widget class="QPushButton" name="pushButton_server_settings">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>30</x>
|
||||
|
|
@ -1450,6 +1456,9 @@ QPushButton:hover {
|
|||
<height>30</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="cursor">
|
||||
<cursorShape>PointingHandCursor</cursorShape>
|
||||
</property>
|
||||
<property name="styleSheet">
|
||||
<string notr="true">font-family: Lato;
|
||||
font-style: normal;
|
||||
|
|
@ -1487,7 +1496,10 @@ background-repeat: no-repeat;
|
|||
<string/>
|
||||
</property>
|
||||
</widget>
|
||||
<widget class="QPushButton" name="pushButton_3">
|
||||
<widget class="QPushButton" name="pushButton_share_connection">
|
||||
<property name="enabled">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>30</x>
|
||||
|
|
@ -1496,6 +1508,9 @@ background-repeat: no-repeat;
|
|||
<height>30</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="cursor">
|
||||
<cursorShape>PointingHandCursor</cursorShape>
|
||||
</property>
|
||||
<property name="styleSheet">
|
||||
<string notr="true">font-family: Lato;
|
||||
font-style: normal;
|
||||
|
|
@ -1533,8 +1548,367 @@ background-repeat: no-repeat;
|
|||
<string/>
|
||||
</property>
|
||||
</widget>
|
||||
<widget class="QLabel" name="label_14">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>10</x>
|
||||
<y>620</y>
|
||||
<width>360</width>
|
||||
<height>1</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="styleSheet">
|
||||
<string notr="true">image: url(:/images/line.png);</string>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string/>
|
||||
</property>
|
||||
</widget>
|
||||
<widget class="QWidget" name="page_share">
|
||||
<widget class="QPushButton" name="pushButton_general_settings_exit">
|
||||
<property name="enabled">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>30</x>
|
||||
<y>570</y>
|
||||
<width>330</width>
|
||||
<height>30</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="cursor">
|
||||
<cursorShape>PointingHandCursor</cursorShape>
|
||||
</property>
|
||||
<property name="styleSheet">
|
||||
<string notr="true">font-family: Lato;
|
||||
font-style: normal;
|
||||
font-weight: bold;
|
||||
font-size: 20px;
|
||||
line-height: 25px;
|
||||
Text-align:left;
|
||||
padding-left: 30px;
|
||||
|
||||
|
||||
/* black */
|
||||
color: #100A44;
|
||||
|
||||
background-repeat: no-repeat;
|
||||
background-position: left center;</string>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Exit</string>
|
||||
</property>
|
||||
</widget>
|
||||
<widget class="QLabel" name="label_15">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>10</x>
|
||||
<y>550</y>
|
||||
<width>360</width>
|
||||
<height>1</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="styleSheet">
|
||||
<string notr="true">image: url(:/images/line.png);</string>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string/>
|
||||
</property>
|
||||
</widget>
|
||||
</widget>
|
||||
<widget class="QWidget" name="page_server_settings">
|
||||
<widget class="QLabel" name="label_server_settings_wait_info">
|
||||
<property name="enabled">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>40</x>
|
||||
<y>490</y>
|
||||
<width>301</width>
|
||||
<height>41</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Please wait, configuring process may take up to 5 minutes</string>
|
||||
</property>
|
||||
<property name="wordWrap">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
</widget>
|
||||
<widget class="QLabel" name="label_13">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>40</x>
|
||||
<y>100</y>
|
||||
<width>171</width>
|
||||
<height>21</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="styleSheet">
|
||||
<string notr="true">font-family: Lato;
|
||||
font-style: normal;
|
||||
font-weight: normal;
|
||||
font-size: 16px;
|
||||
line-height: 150%;
|
||||
|
||||
/* or 24px */
|
||||
|
||||
/* text */
|
||||
color: #333333;</string>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>You connected to</string>
|
||||
</property>
|
||||
</widget>
|
||||
<widget class="QPushButton" name="pushButton_server_settings_reinstall">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>40</x>
|
||||
<y>220</y>
|
||||
<width>301</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;
|
||||
}
|
||||
</string>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Reinstall Amnezia server</string>
|
||||
</property>
|
||||
</widget>
|
||||
<widget class="QPushButton" name="pushButton_back_from_server_settings">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>10</x>
|
||||
<y>10</y>
|
||||
<width>26</width>
|
||||
<height>20</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="cursor">
|
||||
<cursorShape>PointingHandCursor</cursorShape>
|
||||
</property>
|
||||
<property name="styleSheet">
|
||||
<string notr="true">QPushButton {
|
||||
image: url(:/images/arrow_right.png);
|
||||
image-position: left;
|
||||
text-align: left;
|
||||
/*font: 17pt "Ancient";*/
|
||||
|
||||
padding: 1px;
|
||||
image: url(:/images/arrow_left.png);
|
||||
}
|
||||
QPushButton:hover {
|
||||
padding: 0px;
|
||||
}
|
||||
|
||||
</string>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string/>
|
||||
</property>
|
||||
</widget>
|
||||
<widget class="QLabel" name="label_16">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>10</x>
|
||||
<y>40</y>
|
||||
<width>361</width>
|
||||
<height>71</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="styleSheet">
|
||||
<string notr="true">font-family: Lato;
|
||||
font-style: normal;
|
||||
font-weight: bold;
|
||||
font-size: 24px;
|
||||
line-height: 25px;
|
||||
color: #100A44;
|
||||
</string>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Your configured server</string>
|
||||
</property>
|
||||
<property name="alignment">
|
||||
<set>Qt::AlignCenter</set>
|
||||
</property>
|
||||
<property name="wordWrap">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
</widget>
|
||||
<widget class="QProgressBar" name="progressBar_server_settings_reinstall">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>40</x>
|
||||
<y>220</y>
|
||||
<width>301</width>
|
||||
<height>41</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="styleSheet">
|
||||
<string notr="true">QProgressBar{
|
||||
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;
|
||||
}
|
||||
|
||||
QProgressBar::chunk {
|
||||
background: rgba(255, 255, 255, 0.15);
|
||||
border-radius: 4px 0px 0px 4px;
|
||||
|
||||
}
|
||||
</string>
|
||||
</property>
|
||||
<property name="value">
|
||||
<number>24</number>
|
||||
</property>
|
||||
<property name="alignment">
|
||||
<set>Qt::AlignCenter</set>
|
||||
</property>
|
||||
<property name="textVisible">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
<property name="format">
|
||||
<string>Configuring...</string>
|
||||
</property>
|
||||
</widget>
|
||||
<widget class="QLabel" name="label_17">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>110</x>
|
||||
<y>590</y>
|
||||
<width>150</width>
|
||||
<height>22</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="styleSheet">
|
||||
<string notr="true">image: url(:/images/AmneziaVPN.png);</string>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string/>
|
||||
</property>
|
||||
</widget>
|
||||
<widget class="QPushButton" name="pushButton_server_settings_clear">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>40</x>
|
||||
<y>280</y>
|
||||
<width>301</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;
|
||||
}
|
||||
</string>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Clear server from Amnezia software</string>
|
||||
</property>
|
||||
</widget>
|
||||
<widget class="QPushButton" name="pushButton_server_settings_forget">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>40</x>
|
||||
<y>340</y>
|
||||
<width>301</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;
|
||||
}
|
||||
</string>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Forget this server</string>
|
||||
</property>
|
||||
</widget>
|
||||
<widget class="QLabel" name="label_server_settings_server">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>40</x>
|
||||
<y>130</y>
|
||||
<width>321</width>
|
||||
<height>41</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="styleSheet">
|
||||
<string notr="true">font-family: Lato;
|
||||
font-style: normal;
|
||||
font-weight: normal;
|
||||
font-size: 24px;
|
||||
color: #333333;</string>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>root@yourserver.org</string>
|
||||
</property>
|
||||
</widget>
|
||||
<zorder>label_server_settings_wait_info</zorder>
|
||||
<zorder>label_13</zorder>
|
||||
<zorder>pushButton_back_from_server_settings</zorder>
|
||||
<zorder>label_16</zorder>
|
||||
<zorder>progressBar_server_settings_reinstall</zorder>
|
||||
<zorder>label_17</zorder>
|
||||
<zorder>pushButton_server_settings_reinstall</zorder>
|
||||
<zorder>pushButton_server_settings_clear</zorder>
|
||||
<zorder>pushButton_server_settings_forget</zorder>
|
||||
<zorder>label_server_settings_server</zorder>
|
||||
</widget>
|
||||
<widget class="QWidget" name="page_share_connection">
|
||||
<widget class="QPushButton" name="pushButton_back_from_share">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
|
|
|
|||
|
|
@ -1,3 +1,4 @@
|
|||
#include <QApplication>
|
||||
#include <QDebug>
|
||||
#include <QFile>
|
||||
|
||||
|
|
@ -64,14 +65,23 @@ ErrorCode VpnConnection::connectToVpn(const ServerCredentials &credentials, Prot
|
|||
// TODO: Implement some behavior in case if connection not stable
|
||||
qDebug() << "Connect to VPN";
|
||||
|
||||
emit connectionStateChanged(VpnProtocol::ConnectionState::Connecting);
|
||||
qApp->processEvents();
|
||||
|
||||
if (protocol == Protocol::Any || protocol == Protocol::OpenVpn) {
|
||||
ErrorCode e = requestVpnConfig(credentials, Protocol::OpenVpn);
|
||||
if (e) {
|
||||
emit connectionStateChanged(VpnProtocol::ConnectionState::Error);
|
||||
return e;
|
||||
}
|
||||
if (m_vpnProtocol) {
|
||||
disconnect(m_vpnProtocol.data(), &VpnProtocol::protocolError, this, &VpnConnection::vpnProtocolError);
|
||||
}
|
||||
m_vpnProtocol.reset(new OpenVpnProtocol());
|
||||
connect(m_vpnProtocol.data(), &VpnProtocol::protocolError, this, &VpnConnection::vpnProtocolError);
|
||||
}
|
||||
else if (protocol == Protocol::ShadowSocks) {
|
||||
emit connectionStateChanged(VpnProtocol::ConnectionState::Error);
|
||||
return ErrorCode::NotImplementedError;
|
||||
}
|
||||
|
||||
|
|
@ -81,9 +91,10 @@ ErrorCode VpnConnection::connectToVpn(const ServerCredentials &credentials, Prot
|
|||
return m_vpnProtocol.data()->start();
|
||||
}
|
||||
|
||||
QString VpnConnection::bytesToText(quint64 bytes)
|
||||
QString VpnConnection::bytesPerSecToText(quint64 bytes)
|
||||
{
|
||||
return QString("%1 %2").arg(bytes / 1000000).arg(tr("Mbps"));
|
||||
double mbps = bytes * 8 / 1e6;
|
||||
return QString("%1 %2").arg(QString::number(mbps, 'f', 2)).arg(tr("Mbps")); // Mbit/s
|
||||
}
|
||||
|
||||
void VpnConnection::disconnectFromVpn()
|
||||
|
|
@ -96,20 +107,20 @@ void VpnConnection::disconnectFromVpn()
|
|||
m_vpnProtocol.data()->stop();
|
||||
}
|
||||
|
||||
bool VpnConnection::connected() const
|
||||
bool VpnConnection::onConnected() const
|
||||
{
|
||||
if (!m_vpnProtocol.data()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return m_vpnProtocol.data()->connected();
|
||||
return m_vpnProtocol.data()->onConnected();
|
||||
}
|
||||
|
||||
bool VpnConnection::disconnected() const
|
||||
bool VpnConnection::onDisconnected() const
|
||||
{
|
||||
if (!m_vpnProtocol.data()) {
|
||||
return true;
|
||||
}
|
||||
|
||||
return m_vpnProtocol.data()->disconnected();
|
||||
return m_vpnProtocol.data()->onDisconnected();
|
||||
}
|
||||
|
|
|
|||
|
|
@ -18,18 +18,19 @@ public:
|
|||
explicit VpnConnection(QObject* parent = nullptr);
|
||||
~VpnConnection() override = default;
|
||||
|
||||
static QString bytesToText(quint64 bytes);
|
||||
static QString bytesPerSecToText(quint64 bytes);
|
||||
|
||||
ErrorCode lastError() const;
|
||||
ErrorCode requestVpnConfig(const ServerCredentials &credentials, Protocol protocol);
|
||||
ErrorCode connectToVpn(const ServerCredentials &credentials, Protocol protocol = Protocol::Any);
|
||||
bool connected() const;
|
||||
bool disconnected() const;
|
||||
bool onConnected() const;
|
||||
bool onDisconnected() const;
|
||||
void disconnectFromVpn();
|
||||
|
||||
signals:
|
||||
void bytesChanged(quint64 receivedBytes, quint64 sentBytes);
|
||||
void connectionStateChanged(VpnProtocol::ConnectionState state);
|
||||
void vpnProtocolError(amnezia::ErrorCode error);
|
||||
|
||||
protected slots:
|
||||
void onBytesChanged(quint64 receivedBytes, quint64 sentBytes);
|
||||
|
|
|
|||
2579
deploy/data/macos/easyrsa
Executable file
2579
deploy/data/macos/easyrsa
Executable file
File diff suppressed because it is too large
Load diff
138
deploy/data/macos/openssl-easyrsa.cnf
Normal file
138
deploy/data/macos/openssl-easyrsa.cnf
Normal file
|
|
@ -0,0 +1,138 @@
|
|||
# For use with Easy-RSA 3.0+ and OpenSSL or LibreSSL
|
||||
|
||||
####################################################################
|
||||
[ ca ]
|
||||
default_ca = CA_default # The default ca section
|
||||
|
||||
####################################################################
|
||||
[ CA_default ]
|
||||
|
||||
dir = $ENV::EASYRSA_PKI # Where everything is kept
|
||||
certs = $dir # Where the issued certs are kept
|
||||
crl_dir = $dir # Where the issued crl are kept
|
||||
database = $dir/index.txt # database index file.
|
||||
new_certs_dir = $dir/certs_by_serial # default place for new certs.
|
||||
|
||||
certificate = $dir/ca.crt # The CA certificate
|
||||
serial = $dir/serial # The current serial number
|
||||
crl = $dir/crl.pem # The current CRL
|
||||
private_key = $dir/private/ca.key # The private key
|
||||
RANDFILE = $dir/.rand # private random number file
|
||||
|
||||
x509_extensions = basic_exts # The extensions to add to the cert
|
||||
|
||||
# This allows a V2 CRL. Ancient browsers don't like it, but anything Easy-RSA
|
||||
# is designed for will. In return, we get the Issuer attached to CRLs.
|
||||
crl_extensions = crl_ext
|
||||
|
||||
default_days = $ENV::EASYRSA_CERT_EXPIRE # how long to certify for
|
||||
default_crl_days= $ENV::EASYRSA_CRL_DAYS # how long before next CRL
|
||||
default_md = $ENV::EASYRSA_DIGEST # use public key default MD
|
||||
preserve = no # keep passed DN ordering
|
||||
|
||||
# This allows to renew certificates which have not been revoked
|
||||
unique_subject = no
|
||||
|
||||
# A few different ways of specifying how similar the request should look
|
||||
# For type CA, the listed attributes must be the same, and the optional
|
||||
# and supplied fields are just that :-)
|
||||
policy = policy_anything
|
||||
|
||||
# For the 'anything' policy, which defines allowed DN fields
|
||||
[ policy_anything ]
|
||||
countryName = optional
|
||||
stateOrProvinceName = optional
|
||||
localityName = optional
|
||||
organizationName = optional
|
||||
organizationalUnitName = optional
|
||||
commonName = supplied
|
||||
name = optional
|
||||
emailAddress = optional
|
||||
|
||||
####################################################################
|
||||
# Easy-RSA request handling
|
||||
# We key off $DN_MODE to determine how to format the DN
|
||||
[ req ]
|
||||
default_bits = $ENV::EASYRSA_KEY_SIZE
|
||||
default_keyfile = privkey.pem
|
||||
default_md = $ENV::EASYRSA_DIGEST
|
||||
distinguished_name = $ENV::EASYRSA_DN
|
||||
x509_extensions = easyrsa_ca # The extensions to add to the self signed cert
|
||||
|
||||
# A placeholder to handle the $EXTRA_EXTS feature:
|
||||
#%EXTRA_EXTS% # Do NOT remove or change this line as $EXTRA_EXTS support requires it
|
||||
|
||||
####################################################################
|
||||
# Easy-RSA DN (Subject) handling
|
||||
|
||||
# Easy-RSA DN for cn_only support:
|
||||
[ cn_only ]
|
||||
commonName = Common Name (eg: your user, host, or server name)
|
||||
commonName_max = 64
|
||||
commonName_default = $ENV::EASYRSA_REQ_CN
|
||||
|
||||
# Easy-RSA DN for org support:
|
||||
[ org ]
|
||||
countryName = Country Name (2 letter code)
|
||||
countryName_default = $ENV::EASYRSA_REQ_COUNTRY
|
||||
countryName_min = 2
|
||||
countryName_max = 2
|
||||
|
||||
stateOrProvinceName = State or Province Name (full name)
|
||||
stateOrProvinceName_default = $ENV::EASYRSA_REQ_PROVINCE
|
||||
|
||||
localityName = Locality Name (eg, city)
|
||||
localityName_default = $ENV::EASYRSA_REQ_CITY
|
||||
|
||||
0.organizationName = Organization Name (eg, company)
|
||||
0.organizationName_default = $ENV::EASYRSA_REQ_ORG
|
||||
|
||||
organizationalUnitName = Organizational Unit Name (eg, section)
|
||||
organizationalUnitName_default = $ENV::EASYRSA_REQ_OU
|
||||
|
||||
commonName = Common Name (eg: your user, host, or server name)
|
||||
commonName_max = 64
|
||||
commonName_default = $ENV::EASYRSA_REQ_CN
|
||||
|
||||
emailAddress = Email Address
|
||||
emailAddress_default = $ENV::EASYRSA_REQ_EMAIL
|
||||
emailAddress_max = 64
|
||||
|
||||
####################################################################
|
||||
# Easy-RSA cert extension handling
|
||||
|
||||
# This section is effectively unused as the main script sets extensions
|
||||
# dynamically. This core section is left to support the odd usecase where
|
||||
# a user calls openssl directly.
|
||||
[ basic_exts ]
|
||||
basicConstraints = CA:FALSE
|
||||
subjectKeyIdentifier = hash
|
||||
authorityKeyIdentifier = keyid,issuer:always
|
||||
|
||||
# The Easy-RSA CA extensions
|
||||
[ easyrsa_ca ]
|
||||
|
||||
# PKIX recommendations:
|
||||
|
||||
subjectKeyIdentifier=hash
|
||||
authorityKeyIdentifier=keyid:always,issuer:always
|
||||
|
||||
# This could be marked critical, but it's nice to support reading by any
|
||||
# broken clients who attempt to do so.
|
||||
basicConstraints = CA:true
|
||||
|
||||
# Limit key usage to CA tasks. If you really want to use the generated pair as
|
||||
# a self-signed cert, comment this out.
|
||||
keyUsage = cRLSign, keyCertSign
|
||||
|
||||
# nsCertType omitted by default. Let's try to let the deprecated stuff die.
|
||||
# nsCertType = sslCA
|
||||
|
||||
# CRL extensions.
|
||||
[ crl_ext ]
|
||||
|
||||
# Only issuerAltName and authorityKeyIdentifier make any sense in a CRL.
|
||||
|
||||
# issuerAltName=issuer:copy
|
||||
authorityKeyIdentifier=keyid:always,issuer:always
|
||||
|
||||
7
deploy/data/macos/x509-types/COMMON
Normal file
7
deploy/data/macos/x509-types/COMMON
Normal file
|
|
@ -0,0 +1,7 @@
|
|||
# X509 extensions added to every signed cert
|
||||
|
||||
# This file is included for every cert signed, and by default does nothing.
|
||||
# It could be used to add values every cert should have, such as a CDP as
|
||||
# demonstrated in the following example:
|
||||
|
||||
#crlDistributionPoints = URI:http://example.net/pki/my_ca.crl
|
||||
13
deploy/data/macos/x509-types/ca
Normal file
13
deploy/data/macos/x509-types/ca
Normal file
|
|
@ -0,0 +1,13 @@
|
|||
# X509 extensions for a ca
|
||||
|
||||
# Note that basicConstraints will be overridden by Easy-RSA when defining a
|
||||
# CA_PATH_LEN for CA path length limits. You could also do this here
|
||||
# manually as in the following example in place of the existing line:
|
||||
#
|
||||
# basicConstraints = CA:TRUE, pathlen:1
|
||||
|
||||
basicConstraints = CA:TRUE
|
||||
subjectKeyIdentifier = hash
|
||||
authorityKeyIdentifier = keyid:always,issuer:always
|
||||
keyUsage = cRLSign, keyCertSign
|
||||
|
||||
8
deploy/data/macos/x509-types/client
Normal file
8
deploy/data/macos/x509-types/client
Normal file
|
|
@ -0,0 +1,8 @@
|
|||
# X509 extensions for a client
|
||||
|
||||
basicConstraints = CA:FALSE
|
||||
subjectKeyIdentifier = hash
|
||||
authorityKeyIdentifier = keyid,issuer:always
|
||||
extendedKeyUsage = clientAuth
|
||||
keyUsage = digitalSignature
|
||||
|
||||
8
deploy/data/macos/x509-types/code-signing
Normal file
8
deploy/data/macos/x509-types/code-signing
Normal file
|
|
@ -0,0 +1,8 @@
|
|||
# X509 extensions for a client
|
||||
|
||||
basicConstraints = CA:FALSE
|
||||
subjectKeyIdentifier = hash
|
||||
authorityKeyIdentifier = keyid,issuer:always
|
||||
extendedKeyUsage = codeSigning
|
||||
keyUsage = digitalSignature
|
||||
|
||||
8
deploy/data/macos/x509-types/email
Normal file
8
deploy/data/macos/x509-types/email
Normal file
|
|
@ -0,0 +1,8 @@
|
|||
# X509 extensions for email
|
||||
|
||||
basicConstraints = CA:FALSE
|
||||
subjectKeyIdentifier = hash
|
||||
authorityKeyIdentifier = keyid,issuer:always
|
||||
extendedKeyUsage = emailProtection
|
||||
keyUsage = digitalSignature,keyEncipherment,nonRepudiation
|
||||
|
||||
21
deploy/data/macos/x509-types/kdc
Normal file
21
deploy/data/macos/x509-types/kdc
Normal file
|
|
@ -0,0 +1,21 @@
|
|||
# X509 extensions for a KDC server certificate
|
||||
|
||||
basicConstraints = CA:FALSE
|
||||
subjectKeyIdentifier = hash
|
||||
authorityKeyIdentifier = keyid,issuer:always
|
||||
extendedKeyUsage = 1.3.6.1.5.2.3.5
|
||||
keyUsage = nonRepudiation,digitalSignature,keyEncipherment,keyAgreement
|
||||
issuerAltName = issuer:copy
|
||||
subjectAltName = otherName:1.3.6.1.5.2.2;SEQUENCE:kdc_princ_name
|
||||
|
||||
[kdc_princ_name]
|
||||
realm = EXP:0,GeneralString:${ENV::EASYRSA_KDC_REALM}
|
||||
principal_name = EXP:1,SEQUENCE:kdc_principal_seq
|
||||
|
||||
[kdc_principal_seq]
|
||||
name_type = EXP:0,INTEGER:1
|
||||
name_string = EXP:1,SEQUENCE:kdc_principals
|
||||
|
||||
[kdc_principals]
|
||||
princ1 = GeneralString:krbtgt
|
||||
princ2 = GeneralString:${ENV::EASYRSA_KDC_REALM}
|
||||
8
deploy/data/macos/x509-types/server
Normal file
8
deploy/data/macos/x509-types/server
Normal file
|
|
@ -0,0 +1,8 @@
|
|||
# X509 extensions for a server
|
||||
|
||||
basicConstraints = CA:FALSE
|
||||
subjectKeyIdentifier = hash
|
||||
authorityKeyIdentifier = keyid,issuer:always
|
||||
extendedKeyUsage = serverAuth
|
||||
keyUsage = digitalSignature,keyEncipherment
|
||||
|
||||
8
deploy/data/macos/x509-types/serverClient
Normal file
8
deploy/data/macos/x509-types/serverClient
Normal file
|
|
@ -0,0 +1,8 @@
|
|||
# X509 extensions for a client/server
|
||||
|
||||
basicConstraints = CA:FALSE
|
||||
subjectKeyIdentifier = hash
|
||||
authorityKeyIdentifier = keyid,issuer:always
|
||||
extendedKeyUsage = serverAuth,clientAuth
|
||||
keyUsage = digitalSignature,keyEncipherment
|
||||
|
||||
BIN
deploy/data/windows/openvpn/i386/openssl.exe
Normal file
BIN
deploy/data/windows/openvpn/i386/openssl.exe
Normal file
Binary file not shown.
2
deploy/macos.sh
Normal file → Executable file
2
deploy/macos.sh
Normal file → Executable file
|
|
@ -36,7 +36,7 @@ make -j `sysctl -n hw.ncpu`
|
|||
|
||||
$QT_BIN_DIR/macdeployqt $OUT_APP_DIR/$APP_FILENAME -always-overwrite
|
||||
cp -av $RELEASE_DIR/server/release/$APP_NAME-service.app/Contents/macOS/$APP_NAME-service $BUNDLE_DIR/Contents/macOS
|
||||
cp -av $LAUNCH_DIR/data/macos/openvpn $BUNDLE_DIR/Contents/macOS
|
||||
cp -Rv $LAUNCH_DIR/data/macos/* $BUNDLE_DIR/Contents/macOS
|
||||
|
||||
mkdir -p $INSTALLER_DATA_DIR
|
||||
cp -av $LAUNCH_DIR/installer $RELEASE_DIR
|
||||
|
|
|
|||
|
|
@ -62,22 +62,22 @@ void LocalServer::onNewConnection()
|
|||
if (lineLength != -1) {
|
||||
QString line = buf;
|
||||
line = line.simplified();
|
||||
qDebug().noquote() << QString("Readed line: '%1'").arg(line);
|
||||
Message icomingMessage(line);
|
||||
if (!icomingMessage.isValid()) {
|
||||
qDebug().noquote() << QString("Read line: '%1'").arg(line);
|
||||
Message incomingMessage(line);
|
||||
if (!incomingMessage.isValid()) {
|
||||
qWarning().noquote() << "Message is not valid!";
|
||||
continue;
|
||||
}
|
||||
|
||||
switch (icomingMessage.state()) {
|
||||
switch (incomingMessage.state()) {
|
||||
case Message::State::Initialize:
|
||||
sendMessage(Message(Message::State::Initialize, QStringList({"Server"})));
|
||||
break;
|
||||
case Message::State::StartRequest:
|
||||
startProcess(icomingMessage.args());
|
||||
startProcess(incomingMessage.args());
|
||||
break;
|
||||
case Message::State::FinishRequest:
|
||||
finishProcess(icomingMessage.args());
|
||||
finishProcess(incomingMessage.args());
|
||||
break;
|
||||
default:
|
||||
;
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue