commit
ff557589ee
21 changed files with 566 additions and 220 deletions
|
|
@ -11,6 +11,8 @@ include("3rd/QtSsh/src/botan/botan.pri")
|
||||||
|
|
||||||
HEADERS += \
|
HEADERS += \
|
||||||
communicator.h \
|
communicator.h \
|
||||||
|
core/defs.h \
|
||||||
|
core/errorstrings.h \
|
||||||
core/openvpnconfigurator.h \
|
core/openvpnconfigurator.h \
|
||||||
core/router.h \
|
core/router.h \
|
||||||
core/servercontroller.h \
|
core/servercontroller.h \
|
||||||
|
|
@ -19,14 +21,14 @@ HEADERS += \
|
||||||
localclient.h \
|
localclient.h \
|
||||||
managementserver.h \
|
managementserver.h \
|
||||||
message.h \
|
message.h \
|
||||||
openvpnprotocol.h \
|
|
||||||
runguard.h \
|
runguard.h \
|
||||||
settings.h \
|
settings.h \
|
||||||
ui/Controls/SlidingStackedWidget.h \
|
ui/Controls/SlidingStackedWidget.h \
|
||||||
ui/mainwindow.h \
|
ui/mainwindow.h \
|
||||||
utils.h \
|
utils.h \
|
||||||
vpnconnection.h \
|
vpnconnection.h \
|
||||||
vpnprotocol.h \
|
protocols/vpnprotocol.h \
|
||||||
|
protocols/openvpnprotocol.h \
|
||||||
|
|
||||||
SOURCES += \
|
SOURCES += \
|
||||||
communicator.cpp \
|
communicator.cpp \
|
||||||
|
|
@ -38,14 +40,14 @@ SOURCES += \
|
||||||
main.cpp \
|
main.cpp \
|
||||||
managementserver.cpp \
|
managementserver.cpp \
|
||||||
message.cpp \
|
message.cpp \
|
||||||
openvpnprotocol.cpp \
|
|
||||||
runguard.cpp \
|
runguard.cpp \
|
||||||
settings.cpp \
|
settings.cpp \
|
||||||
ui/Controls/SlidingStackedWidget.cpp \
|
ui/Controls/SlidingStackedWidget.cpp \
|
||||||
ui/mainwindow.cpp \
|
ui/mainwindow.cpp \
|
||||||
utils.cpp \
|
utils.cpp \
|
||||||
vpnconnection.cpp \
|
vpnconnection.cpp \
|
||||||
vpnprotocol.cpp \
|
protocols/vpnprotocol.cpp \
|
||||||
|
protocols/openvpnprotocol.cpp \
|
||||||
|
|
||||||
FORMS += ui/mainwindow.ui
|
FORMS += ui/mainwindow.ui
|
||||||
|
|
||||||
|
|
|
||||||
56
client/core/defs.h
Normal file
56
client/core/defs.h
Normal file
|
|
@ -0,0 +1,56 @@
|
||||||
|
#ifndef DEFS_H
|
||||||
|
#define DEFS_H
|
||||||
|
|
||||||
|
#include <QObject>
|
||||||
|
|
||||||
|
namespace amnezia {
|
||||||
|
|
||||||
|
enum class Protocol {
|
||||||
|
Any,
|
||||||
|
OpenVpn,
|
||||||
|
ShadowSocks,
|
||||||
|
WireGuard
|
||||||
|
};
|
||||||
|
|
||||||
|
struct ServerCredentials
|
||||||
|
{
|
||||||
|
QString hostName;
|
||||||
|
QString userName;
|
||||||
|
QString password;
|
||||||
|
int port = 22;
|
||||||
|
};
|
||||||
|
|
||||||
|
enum ErrorCode
|
||||||
|
{
|
||||||
|
// General error codes
|
||||||
|
NoError = 0,
|
||||||
|
UnknownError,
|
||||||
|
InternalError,
|
||||||
|
NotImplementedError,
|
||||||
|
|
||||||
|
// Server errorz
|
||||||
|
ServerCheckFailed,
|
||||||
|
|
||||||
|
// Ssh connection errors
|
||||||
|
SshSocketError, SshTimeoutError, SshProtocolError,
|
||||||
|
SshHostKeyError, SshKeyFileError, SshAuthenticationError,
|
||||||
|
SshClosedByServerError, SshInternalError,
|
||||||
|
|
||||||
|
// Ssh remote process errors
|
||||||
|
SshRemoteProcessCreationError,
|
||||||
|
FailedToStartRemoteProcessError, RemoteProcessCrashError,
|
||||||
|
|
||||||
|
// Local errors
|
||||||
|
FailedToSaveConfigData,
|
||||||
|
OpenVpnConfigMissing,
|
||||||
|
OpenVpnManagementServerError,
|
||||||
|
|
||||||
|
// Distro errors
|
||||||
|
AmneziaServiceConnectionFailed,
|
||||||
|
OpenVpnExecutableMissing,
|
||||||
|
EasyRsaExecutableMissing
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace amnezia
|
||||||
|
|
||||||
|
#endif // DEFS_H
|
||||||
47
client/core/errorstrings.h
Normal file
47
client/core/errorstrings.h
Normal file
|
|
@ -0,0 +1,47 @@
|
||||||
|
#ifndef ERRORSTRINGS_H
|
||||||
|
#define ERRORSTRINGS_H
|
||||||
|
|
||||||
|
#include "defs.h"
|
||||||
|
using namespace amnezia;
|
||||||
|
|
||||||
|
QString errorString(ErrorCode code){
|
||||||
|
switch (code) {
|
||||||
|
|
||||||
|
// General error codes
|
||||||
|
case(NoError): return QObject::tr("No error");
|
||||||
|
case(UnknownError): return QObject::tr("Unknown Error");
|
||||||
|
case(NotImplementedError): return QObject::tr("Function not implemented");
|
||||||
|
case(ServerCheckFailed): return QObject::tr("Server check failed");
|
||||||
|
|
||||||
|
// Ssh connection errors
|
||||||
|
case(SshSocketError): return QObject::tr("Ssh connection error");
|
||||||
|
case(SshTimeoutError): return QObject::tr("Ssh connection timeout");
|
||||||
|
case(SshProtocolError): return QObject::tr("Ssh protocol error");
|
||||||
|
case(SshHostKeyError): return QObject::tr("Ssh server ket check failed");
|
||||||
|
case(SshKeyFileError): return QObject::tr("Ssh key file error");
|
||||||
|
case(SshAuthenticationError): return QObject::tr("Ssh authentication error");
|
||||||
|
case(SshClosedByServerError): return QObject::tr("Ssh session closed");
|
||||||
|
case(SshInternalError): return QObject::tr("Ssh internal error");
|
||||||
|
|
||||||
|
// Ssh remote process errors
|
||||||
|
case(SshRemoteProcessCreationError): return QObject::tr("Failed to create remote process on server");
|
||||||
|
case(FailedToStartRemoteProcessError): return QObject::tr("Failed to start remote process on server");
|
||||||
|
case(RemoteProcessCrashError): return QObject::tr("Remote process on server crashed");
|
||||||
|
|
||||||
|
// 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 (OpenVpnExecutableMissing): return QObject::tr("OpenVPN executable missing");
|
||||||
|
case (EasyRsaExecutableMissing): return QObject::tr("EasyRsa executable missing");
|
||||||
|
case (AmneziaServiceConnectionFailed): return QObject::tr("Amnezia helper service error");
|
||||||
|
|
||||||
|
case(InternalError):
|
||||||
|
default:
|
||||||
|
return QObject::tr("Internal error");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
#endif // ERRORSTRINGS_H
|
||||||
|
|
@ -121,31 +121,39 @@ OpenVpnConfigurator::ConnectionData OpenVpnConfigurator::createCertRequest()
|
||||||
return connData;
|
return connData;
|
||||||
}
|
}
|
||||||
|
|
||||||
OpenVpnConfigurator::ConnectionData OpenVpnConfigurator::prepareOpenVpnConfig(const QSsh::SshConnectionParameters &sshParams)
|
OpenVpnConfigurator::ConnectionData OpenVpnConfigurator::prepareOpenVpnConfig(const ServerCredentials &credentials, ErrorCode *errorCode)
|
||||||
{
|
{
|
||||||
OpenVpnConfigurator::ConnectionData connData = OpenVpnConfigurator::createCertRequest();
|
OpenVpnConfigurator::ConnectionData connData = OpenVpnConfigurator::createCertRequest();
|
||||||
connData.host = sshParams.host;
|
connData.host = credentials.hostName;
|
||||||
|
|
||||||
QString reqFileName = QString("/opt/amneziavpn_data/clients/%1.req").arg(connData.clientId);
|
QString reqFileName = QString("/opt/amneziavpn_data/clients/%1.req").arg(connData.clientId);
|
||||||
ServerController::uploadTextFileToContainer(sshParams, connData.request, reqFileName);
|
ErrorCode e = ServerController::uploadTextFileToContainer(credentials, connData.request, reqFileName);
|
||||||
|
if (e) {
|
||||||
|
*errorCode = e;
|
||||||
|
return connData;
|
||||||
|
}
|
||||||
|
|
||||||
ServerController::signCert(sshParams, connData.clientId);
|
ServerController::signCert(credentials, connData.clientId);
|
||||||
|
|
||||||
connData.caCert = ServerController::getTextFileFromContainer(sshParams, QString("/opt/amneziavpn_data/pki/ca.crt"));
|
connData.caCert = ServerController::getTextFileFromContainer(credentials, ServerController::caCertPath(), &e);
|
||||||
connData.clientCert = ServerController::getTextFileFromContainer(sshParams, QString("/opt/amneziavpn_data/pki/issued/%1.crt").arg(connData.clientId));
|
connData.clientCert = ServerController::getTextFileFromContainer(credentials, ServerController::clientCertPath() + QString("%1.crt").arg(connData.clientId), &e);
|
||||||
connData.taKey = ServerController::getTextFileFromContainer(sshParams, QString("/opt/amneziavpn_data/ta.key"));
|
if (e) {
|
||||||
|
*errorCode = e;
|
||||||
|
return connData;
|
||||||
|
}
|
||||||
|
|
||||||
|
connData.taKey = ServerController::getTextFileFromContainer(credentials, ServerController::taKeyPath(), &e);
|
||||||
|
|
||||||
return connData;
|
return connData;
|
||||||
}
|
}
|
||||||
|
|
||||||
QString OpenVpnConfigurator::genOpenVpnConfig(const QSsh::SshConnectionParameters &sshParams)
|
QString OpenVpnConfigurator::genOpenVpnConfig(const ServerCredentials &credentials, ErrorCode *errorCode)
|
||||||
{
|
{
|
||||||
QFile configTemplFile(":/server_scripts/template.ovpn");
|
QFile configTemplFile(":/server_scripts/template.ovpn");
|
||||||
configTemplFile.open(QIODevice::ReadOnly);
|
configTemplFile.open(QIODevice::ReadOnly);
|
||||||
QString config = configTemplFile.readAll();
|
QString config = configTemplFile.readAll();
|
||||||
|
|
||||||
ConnectionData connData = prepareOpenVpnConfig(sshParams);
|
ConnectionData connData = prepareOpenVpnConfig(credentials, errorCode);
|
||||||
|
|
||||||
config.replace("$PROTO", "udp");
|
config.replace("$PROTO", "udp");
|
||||||
config.replace("$REMOTE_HOST", connData.host);
|
config.replace("$REMOTE_HOST", connData.host);
|
||||||
|
|
|
||||||
|
|
@ -3,6 +3,8 @@
|
||||||
|
|
||||||
#include <QObject>
|
#include <QObject>
|
||||||
#include <QProcessEnvironment>
|
#include <QProcessEnvironment>
|
||||||
|
|
||||||
|
#include "defs.h"
|
||||||
#include "servercontroller.h"
|
#include "servercontroller.h"
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -20,7 +22,7 @@ public:
|
||||||
QString host; // host ip
|
QString host; // host ip
|
||||||
};
|
};
|
||||||
|
|
||||||
static QString genOpenVpnConfig(const QSsh::SshConnectionParameters &sshParams);
|
static QString genOpenVpnConfig(const ServerCredentials &credentials, ErrorCode *errorCode = nullptr);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
static QString getRandomString(int len);
|
static QString getRandomString(int len);
|
||||||
|
|
@ -32,7 +34,7 @@ private:
|
||||||
|
|
||||||
static ConnectionData createCertRequest();
|
static ConnectionData createCertRequest();
|
||||||
|
|
||||||
static ConnectionData prepareOpenVpnConfig(const QSsh::SshConnectionParameters &sshParams);
|
static ConnectionData prepareOpenVpnConfig(const ServerCredentials &credentials, ErrorCode *errorCode = nullptr);
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -6,19 +6,19 @@
|
||||||
#include <QPointer>
|
#include <QPointer>
|
||||||
#include <QTimer>
|
#include <QTimer>
|
||||||
|
|
||||||
//#include "sshclient.h"
|
|
||||||
//#include "sshprocess.h"
|
|
||||||
|
|
||||||
#include "sshconnectionmanager.h"
|
#include "sshconnectionmanager.h"
|
||||||
#include "sshremoteprocess.h"
|
|
||||||
|
|
||||||
using namespace QSsh;
|
using namespace QSsh;
|
||||||
|
|
||||||
bool ServerController::runScript(const SshConnectionParameters &sshParams, QString script)
|
ErrorCode ServerController::runScript(const SshConnectionParameters &sshParams, QString script)
|
||||||
{
|
{
|
||||||
QLoggingCategory::setFilterRules(QStringLiteral("qtc.ssh=false"));
|
QLoggingCategory::setFilterRules(QStringLiteral("qtc.ssh=false"));
|
||||||
|
|
||||||
SshConnection *client = connectToHost(sshParams);
|
SshConnection *client = connectToHost(sshParams);
|
||||||
|
if (client->state() != SshConnection::State::Connected) {
|
||||||
|
return fromSshConnectionErrorCode(client->errorState());
|
||||||
|
}
|
||||||
|
|
||||||
script.replace("\r", "");
|
script.replace("\r", "");
|
||||||
|
|
||||||
|
|
@ -36,49 +36,52 @@ bool ServerController::runScript(const SshConnectionParameters &sshParams, QStri
|
||||||
|
|
||||||
if (!proc) {
|
if (!proc) {
|
||||||
qCritical() << "Failed to create SshRemoteProcess, breaking.";
|
qCritical() << "Failed to create SshRemoteProcess, breaking.";
|
||||||
return false;
|
return ErrorCode::SshRemoteProcessCreationError;
|
||||||
}
|
}
|
||||||
|
|
||||||
QEventLoop wait;
|
QEventLoop wait;
|
||||||
|
int exitStatus;
|
||||||
|
|
||||||
QObject::connect(proc.data(), &SshRemoteProcess::started, &wait, [](){
|
// QObject::connect(proc.data(), &SshRemoteProcess::started, &wait, [](){
|
||||||
qDebug() << "Command started";
|
// qDebug() << "Command started";
|
||||||
});
|
// });
|
||||||
|
|
||||||
QObject::connect(proc.data(), &SshRemoteProcess::closed, &wait, [&](int status){
|
QObject::connect(proc.data(), &SshRemoteProcess::closed, &wait, [&](int status){
|
||||||
qDebug() << "Remote process exited with status" << status;
|
exitStatus = status;
|
||||||
|
//qDebug() << "Remote process exited with status" << status;
|
||||||
wait.quit();
|
wait.quit();
|
||||||
});
|
});
|
||||||
|
|
||||||
QObject::connect(proc.data(), &SshRemoteProcess::readyReadStandardOutput, [proc](){
|
// QObject::connect(proc.data(), &SshRemoteProcess::readyReadStandardOutput, [proc](){
|
||||||
QString s = proc->readAllStandardOutput();
|
// QString s = proc->readAllStandardOutput();
|
||||||
if (s != "." && !s.isEmpty()) {
|
// if (s != "." && !s.isEmpty()) {
|
||||||
qDebug().noquote() << s;
|
// qDebug().noquote() << s << s.size();
|
||||||
}
|
// }
|
||||||
});
|
// });
|
||||||
|
|
||||||
QObject::connect(proc.data(), &SshRemoteProcess::readyReadStandardError, [proc](){
|
// QObject::connect(proc.data(), &SshRemoteProcess::readyReadStandardError, [proc](){
|
||||||
QString s = proc->readAllStandardError();
|
// QString s = proc->readAllStandardError();
|
||||||
if (s != "." && !s.isEmpty()) {
|
// if (s != "." && !s.isEmpty()) {
|
||||||
qDebug().noquote() << s;
|
// qDebug().noquote() << s;
|
||||||
}
|
// }
|
||||||
});
|
// });
|
||||||
|
|
||||||
proc->start();
|
proc->start();
|
||||||
|
|
||||||
if (i < lines.count() - 1) {
|
if (i < lines.count() - 1) {
|
||||||
wait.exec();
|
wait.exec();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (SshRemoteProcess::ExitStatus(exitStatus) != QSsh::SshRemoteProcess::ExitStatus::NormalExit) {
|
||||||
|
return fromSshProcessExitStatus(exitStatus);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
qDebug() << "ServerController::runScript finished\n";
|
qDebug() << "ServerController::runScript finished\n";
|
||||||
|
return ErrorCode::NoError;
|
||||||
// client->disconnectFromHost();
|
|
||||||
|
|
||||||
// client->deleteLater();
|
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void ServerController::uploadTextFileToContainer(const SshConnectionParameters &sshParams,
|
ErrorCode ServerController::uploadTextFileToContainer(const ServerCredentials &credentials,
|
||||||
QString &file, const QString &path)
|
QString &file, const QString &path)
|
||||||
{
|
{
|
||||||
QLoggingCategory::setFilterRules(QStringLiteral("qtc.ssh=false"));
|
QLoggingCategory::setFilterRules(QStringLiteral("qtc.ssh=false"));
|
||||||
|
|
@ -88,60 +91,85 @@ void ServerController::uploadTextFileToContainer(const SshConnectionParameters &
|
||||||
|
|
||||||
qDebug().noquote() << script;
|
qDebug().noquote() << script;
|
||||||
|
|
||||||
SshConnection *client = connectToHost(sshParams);
|
SshConnection *client = connectToHost(sshParams(credentials));
|
||||||
|
if (client->state() != SshConnection::State::Connected) {
|
||||||
|
return fromSshConnectionErrorCode(client->errorState());
|
||||||
|
}
|
||||||
|
|
||||||
QSharedPointer<SshRemoteProcess> proc = client->createRemoteProcess(script.toUtf8());
|
QSharedPointer<SshRemoteProcess> proc = client->createRemoteProcess(script.toUtf8());
|
||||||
|
|
||||||
if (!proc) {
|
if (!proc) {
|
||||||
qCritical() << "Failed to create SshRemoteProcess, breaking.";
|
qCritical() << "Failed to create SshRemoteProcess, breaking.";
|
||||||
return;
|
return ErrorCode::SshRemoteProcessCreationError;
|
||||||
}
|
}
|
||||||
|
|
||||||
QEventLoop wait;
|
QEventLoop wait;
|
||||||
|
int exitStatus = 0;
|
||||||
|
|
||||||
QObject::connect(proc.data(), &SshRemoteProcess::started, &wait, [](){
|
// QObject::connect(proc.data(), &SshRemoteProcess::started, &wait, [](){
|
||||||
qDebug() << "Command started";
|
// qDebug() << "Command started";
|
||||||
});
|
// });
|
||||||
|
|
||||||
QObject::connect(proc.data(), &SshRemoteProcess::closed, &wait, [&](int status){
|
QObject::connect(proc.data(), &SshRemoteProcess::closed, &wait, [&](int status){
|
||||||
qDebug() << "Remote process exited with status" << status;
|
//qDebug() << "Remote process exited with status" << status;
|
||||||
|
exitStatus = status;
|
||||||
wait.quit();
|
wait.quit();
|
||||||
});
|
});
|
||||||
|
|
||||||
QObject::connect(proc.data(), &SshRemoteProcess::readyReadStandardOutput, [proc](){
|
// QObject::connect(proc.data(), &SshRemoteProcess::readyReadStandardOutput, [proc](){
|
||||||
qDebug().noquote() << proc->readAllStandardOutput();
|
// qDebug().noquote() << proc->readAllStandardOutput();
|
||||||
});
|
// });
|
||||||
|
|
||||||
QObject::connect(proc.data(), &SshRemoteProcess::readyReadStandardError, [proc](){
|
// QObject::connect(proc.data(), &SshRemoteProcess::readyReadStandardError, [proc](){
|
||||||
qDebug().noquote() << proc->readAllStandardError();
|
// qDebug().noquote() << proc->readAllStandardError();
|
||||||
});
|
// });
|
||||||
|
|
||||||
proc->start();
|
proc->start();
|
||||||
wait.exec();
|
wait.exec();
|
||||||
|
|
||||||
|
return fromSshProcessExitStatus(exitStatus);
|
||||||
}
|
}
|
||||||
|
|
||||||
QString ServerController::getTextFileFromContainer(const SshConnectionParameters &sshParams, const QString &path)
|
QString ServerController::getTextFileFromContainer(const ServerCredentials &credentials, const QString &path,
|
||||||
|
ErrorCode *errorCode)
|
||||||
{
|
{
|
||||||
QString script = QString("docker exec -i amneziavpn sh -c \"cat \'%1\'\"").
|
QString script = QString("docker exec -i amneziavpn sh -c \"cat \'%1\'\"").
|
||||||
arg(path);
|
arg(path);
|
||||||
|
|
||||||
qDebug().noquote() << "Copy file from container\n" << script;
|
qDebug().noquote() << "Copy file from container\n" << script;
|
||||||
|
|
||||||
SshConnection *client = connectToHost(sshParams);
|
SshConnection *client = connectToHost(sshParams(credentials));
|
||||||
|
if (client->state() != SshConnection::State::Connected) {
|
||||||
|
if (errorCode) *errorCode = fromSshConnectionErrorCode(client->errorState());
|
||||||
|
return QString();
|
||||||
|
}
|
||||||
|
|
||||||
QSharedPointer<SshRemoteProcess> proc = client->createRemoteProcess(script.toUtf8());
|
QSharedPointer<SshRemoteProcess> proc = client->createRemoteProcess(script.toUtf8());
|
||||||
|
if (!proc) {
|
||||||
|
qCritical() << "Failed to create SshRemoteProcess, breaking.";
|
||||||
|
if (errorCode) *errorCode = ErrorCode::SshRemoteProcessCreationError;
|
||||||
|
return QString();
|
||||||
|
}
|
||||||
|
|
||||||
QEventLoop wait;
|
QEventLoop wait;
|
||||||
|
int exitStatus = 0;
|
||||||
|
|
||||||
QObject::connect(proc.data(), &SshRemoteProcess::closed, &wait, [&](int ){
|
QObject::connect(proc.data(), &SshRemoteProcess::closed, &wait, [&](int status){
|
||||||
|
exitStatus = status;
|
||||||
wait.quit();
|
wait.quit();
|
||||||
});
|
});
|
||||||
|
|
||||||
proc->start();
|
proc->start();
|
||||||
wait.exec();
|
wait.exec();
|
||||||
|
|
||||||
|
if (SshRemoteProcess::ExitStatus(exitStatus) != QSsh::SshRemoteProcess::ExitStatus::NormalExit) {
|
||||||
|
if (errorCode) *errorCode = fromSshProcessExitStatus(exitStatus);
|
||||||
|
}
|
||||||
|
|
||||||
return proc->readAllStandardOutput();
|
return proc->readAllStandardOutput();
|
||||||
}
|
}
|
||||||
|
|
||||||
bool ServerController::signCert(const SshConnectionParameters &sshParams, QString clientId)
|
ErrorCode ServerController::signCert(const ServerCredentials &credentials, QString clientId)
|
||||||
{
|
{
|
||||||
QString script_import = QString("docker exec -i amneziavpn bash -c \"cd /opt/amneziavpn_data && "
|
QString script_import = QString("docker exec -i amneziavpn bash -c \"cd /opt/amneziavpn_data && "
|
||||||
"easyrsa import-req /opt/amneziavpn_data/clients/%1.req %1 &>/dev/null\"")
|
"easyrsa import-req /opt/amneziavpn_data/clients/%1.req %1 &>/dev/null\"")
|
||||||
|
|
@ -153,55 +181,121 @@ bool ServerController::signCert(const SshConnectionParameters &sshParams, QStrin
|
||||||
|
|
||||||
QStringList script {script_import, script_sign};
|
QStringList script {script_import, script_sign};
|
||||||
|
|
||||||
return runScript(sshParams, script.join("\n"));
|
return runScript(sshParams(credentials), script.join("\n"));
|
||||||
}
|
}
|
||||||
|
|
||||||
bool ServerController::removeServer(const SshConnectionParameters &sshParams, ServerController::ServerType sType)
|
ErrorCode ServerController::checkOpenVpnServer(const ServerCredentials &credentials)
|
||||||
|
{
|
||||||
|
QString caCert = ServerController::getTextFileFromContainer(credentials, ServerController::caCertPath());
|
||||||
|
QString taKey = ServerController::getTextFileFromContainer(credentials, ServerController::taKeyPath());
|
||||||
|
|
||||||
|
if (!caCert.isEmpty() && !taKey.isEmpty()) {
|
||||||
|
return ErrorCode::NoError;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
return ErrorCode::ServerCheckFailed;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
ErrorCode ServerController::fromSshConnectionErrorCode(SshError error)
|
||||||
|
{
|
||||||
|
switch (error) {
|
||||||
|
case(SshNoError): return ErrorCode::NoError;
|
||||||
|
case(QSsh::SshSocketError): return ErrorCode::SshSocketError;
|
||||||
|
case(QSsh::SshTimeoutError): return ErrorCode::SshTimeoutError;
|
||||||
|
case(QSsh::SshProtocolError): return ErrorCode::SshProtocolError;
|
||||||
|
case(QSsh::SshHostKeyError): return ErrorCode::SshHostKeyError;
|
||||||
|
case(QSsh::SshKeyFileError): return ErrorCode::SshKeyFileError;
|
||||||
|
case(QSsh::SshAuthenticationError): return ErrorCode::SshAuthenticationError;
|
||||||
|
case(QSsh::SshClosedByServerError): return ErrorCode::SshClosedByServerError;
|
||||||
|
case(QSsh::SshInternalError): return ErrorCode::SshInternalError;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
ErrorCode ServerController::fromSshProcessExitStatus(int exitStatus)
|
||||||
|
{
|
||||||
|
switch (SshRemoteProcess::ExitStatus(exitStatus)) {
|
||||||
|
case(SshRemoteProcess::ExitStatus::NormalExit): return ErrorCode::NoError;
|
||||||
|
case(SshRemoteProcess::ExitStatus::FailedToStart): return ErrorCode::FailedToStartRemoteProcessError;
|
||||||
|
case(SshRemoteProcess::ExitStatus::CrashExit): return ErrorCode::RemoteProcessCrashError;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
SshConnectionParameters ServerController::sshParams(const ServerCredentials &credentials)
|
||||||
|
{
|
||||||
|
QSsh::SshConnectionParameters sshParams;
|
||||||
|
sshParams.authenticationType = QSsh::SshConnectionParameters::AuthenticationTypePassword;
|
||||||
|
sshParams.host = credentials.hostName;
|
||||||
|
sshParams.userName = credentials.userName;
|
||||||
|
sshParams.password = credentials.password;
|
||||||
|
sshParams.timeout = 10;
|
||||||
|
sshParams.port = credentials.port;
|
||||||
|
sshParams.hostKeyCheckingMode = QSsh::SshHostKeyCheckingMode::SshHostKeyCheckingNone;
|
||||||
|
|
||||||
|
return sshParams;
|
||||||
|
}
|
||||||
|
|
||||||
|
ErrorCode ServerController::removeServer(const ServerCredentials &credentials, Protocol proto)
|
||||||
{
|
{
|
||||||
QString scriptFileName;
|
QString scriptFileName;
|
||||||
|
|
||||||
if (sType == OpenVPN) {
|
if (proto == Protocol::OpenVpn) {
|
||||||
scriptFileName = ":/server_scripts/remove_openvpn_server.sh";
|
scriptFileName = ":/server_scripts/remove_openvpn_server.sh";
|
||||||
}
|
}
|
||||||
|
|
||||||
QString scriptData;
|
QString scriptData;
|
||||||
|
|
||||||
QFile file(scriptFileName);
|
QFile file(scriptFileName);
|
||||||
if (! file.open(QIODevice::ReadOnly)) {
|
if (! file.open(QIODevice::ReadOnly)) return ErrorCode::InternalError;
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
scriptData = file.readAll();
|
scriptData = file.readAll();
|
||||||
if (scriptData.isEmpty()) return false;
|
if (scriptData.isEmpty()) return ErrorCode::InternalError;
|
||||||
|
|
||||||
return runScript(sshParams, scriptData);
|
return runScript(sshParams(credentials), scriptData);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool ServerController::setupServer(const SshConnectionParameters &sshParams, ServerController::ServerType sType)
|
ErrorCode ServerController::setupServer(const ServerCredentials &credentials, Protocol proto)
|
||||||
{
|
{
|
||||||
QString scriptFileName;
|
if (proto == Protocol::OpenVpn) {
|
||||||
|
return setupOpenVpnServer(credentials);
|
||||||
if (sType == OpenVPN) {
|
}
|
||||||
scriptFileName = ":/server_scripts/setup_openvpn_server.sh";
|
else if (proto == Protocol::ShadowSocks) {
|
||||||
|
return setupShadowSocksServer(credentials);
|
||||||
|
}
|
||||||
|
else if (proto == Protocol::Any) {
|
||||||
|
// TODO: run concurently
|
||||||
|
return setupOpenVpnServer(credentials);
|
||||||
|
//setupShadowSocksServer(credentials);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return ErrorCode::NotImplementedError;
|
||||||
|
}
|
||||||
|
|
||||||
|
ErrorCode ServerController::setupOpenVpnServer(const ServerCredentials &credentials)
|
||||||
|
{
|
||||||
QString scriptData;
|
QString scriptData;
|
||||||
|
QString scriptFileName = ":/server_scripts/setup_openvpn_server.sh";
|
||||||
QFile file(scriptFileName);
|
QFile file(scriptFileName);
|
||||||
if (! file.open(QIODevice::ReadOnly)) {
|
if (! file.open(QIODevice::ReadOnly)) return ErrorCode::InternalError;
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
scriptData = file.readAll();
|
scriptData = file.readAll();
|
||||||
if (scriptData.isEmpty()) return false;
|
if (scriptData.isEmpty()) return ErrorCode::InternalError;
|
||||||
|
|
||||||
return runScript(sshParams, scriptData);
|
ErrorCode e = runScript(sshParams(credentials), scriptData);
|
||||||
|
if (e) return e;
|
||||||
|
|
||||||
|
//return ok;
|
||||||
|
return checkOpenVpnServer(credentials);
|
||||||
|
}
|
||||||
|
|
||||||
|
ErrorCode ServerController::setupShadowSocksServer(const ServerCredentials &credentials)
|
||||||
|
{
|
||||||
|
return ErrorCode::NotImplementedError;
|
||||||
}
|
}
|
||||||
|
|
||||||
SshConnection *ServerController::connectToHost(const SshConnectionParameters &sshParams)
|
SshConnection *ServerController::connectToHost(const SshConnectionParameters &sshParams)
|
||||||
{
|
{
|
||||||
SshConnection *client = acquireConnection(sshParams);
|
SshConnection *client = acquireConnection(sshParams);
|
||||||
//QPointer<SshConnection> client = new SshConnection(serverInfo);
|
|
||||||
|
|
||||||
QEventLoop waitssh;
|
QEventLoop waitssh;
|
||||||
QObject::connect(client, &SshConnection::connected, &waitssh, [&]() {
|
QObject::connect(client, &SshConnection::connected, &waitssh, [&]() {
|
||||||
|
|
|
||||||
|
|
@ -3,29 +3,43 @@
|
||||||
|
|
||||||
#include <QObject>
|
#include <QObject>
|
||||||
#include "sshconnection.h"
|
#include "sshconnection.h"
|
||||||
|
#include "sshremoteprocess.h"
|
||||||
|
#include "defs.h"
|
||||||
|
|
||||||
|
using namespace amnezia;
|
||||||
|
|
||||||
class ServerController : public QObject
|
class ServerController : public QObject
|
||||||
{
|
{
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
public:
|
public:
|
||||||
enum ServerType {
|
|
||||||
OpenVPN,
|
|
||||||
ShadowSocks,
|
|
||||||
WireGuard
|
|
||||||
};
|
|
||||||
|
|
||||||
static bool removeServer(const QSsh::SshConnectionParameters &sshParams, ServerType sType);
|
static ErrorCode fromSshConnectionErrorCode(QSsh::SshError error);
|
||||||
static bool setupServer(const QSsh::SshConnectionParameters &sshParams, ServerType sType);
|
|
||||||
|
|
||||||
|
// QSsh exitCode and exitStatus are different things
|
||||||
|
static ErrorCode fromSshProcessExitStatus(int exitStatus);
|
||||||
|
|
||||||
|
static QString caCertPath() { return "/opt/amneziavpn_data/pki/ca.crt"; }
|
||||||
|
static QString clientCertPath() { return "/opt/amneziavpn_data/pki/issued/"; }
|
||||||
|
static QString taKeyPath() { return "/opt/amneziavpn_data/ta.key"; }
|
||||||
|
|
||||||
|
static QSsh::SshConnectionParameters sshParams(const ServerCredentials &credentials);
|
||||||
|
|
||||||
|
static ErrorCode removeServer(const ServerCredentials &credentials, Protocol proto);
|
||||||
|
static ErrorCode setupServer(const ServerCredentials &credentials, Protocol proto);
|
||||||
|
|
||||||
|
static ErrorCode checkOpenVpnServer(const ServerCredentials &credentials);
|
||||||
|
|
||||||
|
static ErrorCode uploadTextFileToContainer(const ServerCredentials &credentials, QString &file, const QString &path);
|
||||||
|
static QString getTextFileFromContainer(const ServerCredentials &credentials, const QString &path, ErrorCode *errorCode = nullptr);
|
||||||
|
|
||||||
|
static ErrorCode signCert(const ServerCredentials &credentials, QString clientId);
|
||||||
|
|
||||||
|
private:
|
||||||
static QSsh::SshConnection *connectToHost(const QSsh::SshConnectionParameters &sshParams);
|
static QSsh::SshConnection *connectToHost(const QSsh::SshConnectionParameters &sshParams);
|
||||||
static bool runScript(const QSsh::SshConnectionParameters &sshParams, QString script);
|
static ErrorCode runScript(const QSsh::SshConnectionParameters &sshParams, QString script);
|
||||||
|
|
||||||
static void uploadTextFileToContainer(const QSsh::SshConnectionParameters &sshParams, QString &file, const QString &path);
|
static ErrorCode setupOpenVpnServer(const ServerCredentials &credentials);
|
||||||
static QString getTextFileFromContainer(const QSsh::SshConnectionParameters &sshParams, const QString &path);
|
static ErrorCode setupShadowSocksServer(const ServerCredentials &credentials);
|
||||||
|
|
||||||
static bool signCert(const QSsh::SshConnectionParameters &sshParams, QString clientId);
|
|
||||||
|
|
||||||
signals:
|
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -107,7 +107,7 @@ QString OpenVpnProtocol::openVpnExecPath() const
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
bool OpenVpnProtocol::start()
|
ErrorCode OpenVpnProtocol::start()
|
||||||
{
|
{
|
||||||
qDebug() << "Start OpenVPN connection";
|
qDebug() << "Start OpenVPN connection";
|
||||||
|
|
||||||
|
|
@ -116,18 +116,18 @@ bool OpenVpnProtocol::start()
|
||||||
stop();
|
stop();
|
||||||
|
|
||||||
if (communicator() && !communicator()->connected()) {
|
if (communicator() && !communicator()->connected()) {
|
||||||
setLastError("Communicator is not connected!");
|
setLastError(ErrorCode::AmneziaServiceConnectionFailed);
|
||||||
return false;
|
return lastError();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!QFileInfo::exists(openVpnExecPath())) {
|
if (!QFileInfo::exists(openVpnExecPath())) {
|
||||||
setLastError("OpenVPN executable does not exist!\n" + openVpnExecPath());
|
setLastError(ErrorCode::OpenVpnExecutableMissing);
|
||||||
return false;
|
return lastError();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!QFileInfo::exists(configPath())) {
|
if (!QFileInfo::exists(configPath())) {
|
||||||
setLastError("OpenVPN config file does not exist!\n" + configPath());
|
setLastError(ErrorCode::OpenVpnConfigMissing);
|
||||||
return false;
|
return lastError();
|
||||||
}
|
}
|
||||||
|
|
||||||
QString vpnLogFileNamePath = Utils::systemLogPath() + "/openvpn.log";
|
QString vpnLogFileNamePath = Utils::systemLogPath() + "/openvpn.log";
|
||||||
|
|
@ -141,14 +141,15 @@ bool OpenVpnProtocol::start()
|
||||||
});
|
});
|
||||||
|
|
||||||
if (!m_managementServer.start(m_managementHost, m_managementPort)) {
|
if (!m_managementServer.start(m_managementHost, m_managementPort)) {
|
||||||
return false;
|
setLastError(ErrorCode::OpenVpnManagementServerError);
|
||||||
|
return lastError();
|
||||||
}
|
}
|
||||||
|
|
||||||
setConnectionState(ConnectionState::Connecting);
|
setConnectionState(ConnectionState::Connecting);
|
||||||
m_communicator->sendMessage(Message(Message::State::StartRequest, args));
|
m_communicator->sendMessage(Message(Message::State::StartRequest, args));
|
||||||
startTimeoutTimer();
|
startTimeoutTimer();
|
||||||
|
|
||||||
return true;
|
return ErrorCode::NoError;
|
||||||
}
|
}
|
||||||
|
|
||||||
void OpenVpnProtocol::openVpnStateSigTermHandlerTimerEvent()
|
void OpenVpnProtocol::openVpnStateSigTermHandlerTimerEvent()
|
||||||
|
|
@ -17,7 +17,7 @@ public:
|
||||||
explicit OpenVpnProtocol(const QString& args = QString(), QObject* parent = nullptr);
|
explicit OpenVpnProtocol(const QString& args = QString(), QObject* parent = nullptr);
|
||||||
~OpenVpnProtocol();
|
~OpenVpnProtocol();
|
||||||
|
|
||||||
bool start() override;
|
ErrorCode start() override;
|
||||||
void stop() override;
|
void stop() override;
|
||||||
|
|
||||||
protected slots:
|
protected slots:
|
||||||
|
|
@ -19,11 +19,6 @@ VpnProtocol::VpnProtocol(const QString& args, QObject* parent)
|
||||||
Q_UNUSED(args)
|
Q_UNUSED(args)
|
||||||
}
|
}
|
||||||
|
|
||||||
VpnProtocol::~VpnProtocol()
|
|
||||||
{
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
void VpnProtocol::initializeCommunicator(QObject* parent)
|
void VpnProtocol::initializeCommunicator(QObject* parent)
|
||||||
{
|
{
|
||||||
if (!m_communicator) {
|
if (!m_communicator) {
|
||||||
|
|
@ -36,13 +31,13 @@ Communicator* VpnProtocol::communicator()
|
||||||
return m_communicator;
|
return m_communicator;
|
||||||
}
|
}
|
||||||
|
|
||||||
void VpnProtocol::setLastError(const QString& error)
|
void VpnProtocol::setLastError(ErrorCode lastError)
|
||||||
{
|
{
|
||||||
m_lastError = error;
|
m_lastError = lastError;
|
||||||
qCritical().noquote() << m_lastError;
|
qCritical().noquote() << m_lastError;
|
||||||
}
|
}
|
||||||
|
|
||||||
QString VpnProtocol::lastError() const
|
ErrorCode VpnProtocol::lastError() const
|
||||||
{
|
{
|
||||||
return m_lastError;
|
return m_lastError;
|
||||||
}
|
}
|
||||||
|
|
@ -4,6 +4,9 @@
|
||||||
#include <QObject>
|
#include <QObject>
|
||||||
#include <QString>
|
#include <QString>
|
||||||
|
|
||||||
|
#include "core/defs.h"
|
||||||
|
using namespace amnezia;
|
||||||
|
|
||||||
class QTimer;
|
class QTimer;
|
||||||
class Communicator;
|
class Communicator;
|
||||||
|
|
||||||
|
|
@ -13,7 +16,7 @@ class VpnProtocol : public QObject
|
||||||
|
|
||||||
public:
|
public:
|
||||||
explicit VpnProtocol(const QString& args = QString(), QObject* parent = nullptr);
|
explicit VpnProtocol(const QString& args = QString(), QObject* parent = nullptr);
|
||||||
~VpnProtocol();
|
virtual ~VpnProtocol() override = default;
|
||||||
|
|
||||||
enum class ConnectionState {Unknown, Disconnected, Preparing, Connecting, Connected, Disconnecting, TunnelReconnecting, Error};
|
enum class ConnectionState {Unknown, Disconnected, Preparing, Connecting, Connected, Disconnecting, TunnelReconnecting, Error};
|
||||||
|
|
||||||
|
|
@ -24,13 +27,13 @@ public:
|
||||||
|
|
||||||
virtual bool connected() const;
|
virtual bool connected() const;
|
||||||
virtual bool disconnected() const;
|
virtual bool disconnected() const;
|
||||||
virtual bool start() = 0;
|
virtual ErrorCode start() = 0;
|
||||||
virtual void stop() = 0;
|
virtual void stop() = 0;
|
||||||
|
|
||||||
ConnectionState connectionState() const;
|
ConnectionState connectionState() const;
|
||||||
QString lastError() const;
|
ErrorCode lastError() const;
|
||||||
QString textConnectionState() const;
|
QString textConnectionState() const;
|
||||||
void setLastError(const QString& error);
|
void setLastError(ErrorCode lastError);
|
||||||
|
|
||||||
signals:
|
signals:
|
||||||
void bytesChanged(quint64 receivedBytes, quint64 sentBytes);
|
void bytesChanged(quint64 receivedBytes, quint64 sentBytes);
|
||||||
|
|
@ -53,7 +56,7 @@ protected:
|
||||||
|
|
||||||
private:
|
private:
|
||||||
QTimer* m_timeoutTimer;
|
QTimer* m_timeoutTimer;
|
||||||
QString m_lastError;
|
ErrorCode m_lastError;
|
||||||
quint64 m_receivedBytes;
|
quint64 m_receivedBytes;
|
||||||
quint64 m_sentBytes;
|
quint64 m_sentBytes;
|
||||||
};
|
};
|
||||||
|
|
@ -37,5 +37,6 @@
|
||||||
<file>server_scripts/setup_openvpn_server.sh</file>
|
<file>server_scripts/setup_openvpn_server.sh</file>
|
||||||
<file>server_scripts/template.ovpn</file>
|
<file>server_scripts/template.ovpn</file>
|
||||||
<file>images/background_connected.png</file>
|
<file>images/background_connected.png</file>
|
||||||
|
<file>server_scripts/setup_shadowsocks_server.sh</file>
|
||||||
</qresource>
|
</qresource>
|
||||||
</RCC>
|
</RCC>
|
||||||
|
|
|
||||||
13
client/server_scripts/setup_shadowsocks_server.sh
Normal file
13
client/server_scripts/setup_shadowsocks_server.sh
Normal file
|
|
@ -0,0 +1,13 @@
|
||||||
|
#DOCKER_IMAGE="amneziavpn/shadow-vpn:latest"
|
||||||
|
#CONTAINER_NAME="shadow-vpn"
|
||||||
|
|
||||||
|
#sudo apt update
|
||||||
|
sudo apt install -y docker.io curl
|
||||||
|
sudo systemctl start docker
|
||||||
|
|
||||||
|
sudo docker stop shadow-vpn
|
||||||
|
sudo docker rm -f shadow-vpn
|
||||||
|
sudo docker pull amneziavpn/shadow-vpn:latest
|
||||||
|
sudo docker run -d --restart always --cap-add=NET_ADMIN -p 1194:1194/tcp -p 6789:6789/tcp --name shadow-vpn amneziavpn/shadow-vpn:latest
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -12,30 +12,31 @@ Settings::Settings(QObject* parent) : QObject(parent)
|
||||||
void Settings::read()
|
void Settings::read()
|
||||||
{
|
{
|
||||||
m_settings->beginGroup("Server");
|
m_settings->beginGroup("Server");
|
||||||
m_login = m_settings->value("login", QString()).toString();
|
m_userName = m_settings->value("userName", QString()).toString();
|
||||||
m_password = m_settings->value("password", QString()).toString();
|
m_password = m_settings->value("password", QString()).toString();
|
||||||
m_serverName = m_settings->value("serverName", QString()).toString();
|
m_serverName = m_settings->value("serverName", QString()).toString();
|
||||||
|
m_serverPort = m_settings->value("serverPort", 22).toInt();
|
||||||
m_settings->endGroup();
|
m_settings->endGroup();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void Settings::save()
|
void Settings::save()
|
||||||
{
|
{
|
||||||
m_settings->beginGroup("Server");
|
m_settings->beginGroup("Server");
|
||||||
m_settings->setValue("login", m_login);
|
m_settings->setValue("userName", m_userName);
|
||||||
m_settings->setValue("password", m_password);
|
m_settings->setValue("password", m_password);
|
||||||
m_settings->setValue("serverName", m_serverName);
|
m_settings->setValue("serverName", m_serverName);
|
||||||
|
m_settings->setValue("serverPort", m_serverPort);
|
||||||
m_settings->endGroup();
|
m_settings->endGroup();
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Settings::haveAuthData() const
|
bool Settings::haveAuthData() const
|
||||||
{
|
{
|
||||||
return (!serverName().isEmpty() && !login().isEmpty() && !password().isEmpty());
|
return (!serverName().isEmpty() && !userName().isEmpty() && !password().isEmpty());
|
||||||
}
|
}
|
||||||
|
|
||||||
void Settings::setLogin(const QString& login)
|
void Settings::setUserName(const QString& login)
|
||||||
{
|
{
|
||||||
m_login = login;
|
m_userName = login;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Settings::setPassword(const QString& password)
|
void Settings::setPassword(const QString& password)
|
||||||
|
|
@ -48,17 +49,26 @@ void Settings::setServerName(const QString& serverName)
|
||||||
m_serverName = serverName;
|
m_serverName = serverName;
|
||||||
}
|
}
|
||||||
|
|
||||||
QString Settings::login() const
|
void Settings::setServerPort(int serverPort)
|
||||||
{
|
{
|
||||||
return m_login;
|
m_serverPort = serverPort;
|
||||||
}
|
}
|
||||||
|
|
||||||
QString Settings::password() const
|
void Settings::setServerCredentials(const ServerCredentials &credentials)
|
||||||
{
|
{
|
||||||
return m_password;
|
setServerName(credentials.hostName);
|
||||||
|
setServerPort(credentials.port);
|
||||||
|
setUserName(credentials.userName);
|
||||||
|
setPassword(credentials.password);
|
||||||
}
|
}
|
||||||
|
|
||||||
QString Settings::serverName() const
|
ServerCredentials Settings::serverCredentials()
|
||||||
{
|
{
|
||||||
return m_serverName;
|
ServerCredentials credentials;
|
||||||
|
credentials.hostName = serverName();
|
||||||
|
credentials.userName = userName();
|
||||||
|
credentials.password = password();
|
||||||
|
credentials.port = serverPort();
|
||||||
|
|
||||||
|
return credentials;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -4,6 +4,10 @@
|
||||||
#include <QObject>
|
#include <QObject>
|
||||||
#include <QString>
|
#include <QString>
|
||||||
|
|
||||||
|
#include "core/defs.h"
|
||||||
|
|
||||||
|
using namespace amnezia;
|
||||||
|
|
||||||
class QSettings;
|
class QSettings;
|
||||||
|
|
||||||
class Settings : public QObject
|
class Settings : public QObject
|
||||||
|
|
@ -16,21 +20,27 @@ public:
|
||||||
void read();
|
void read();
|
||||||
void save();
|
void save();
|
||||||
|
|
||||||
void setLogin(const QString& login);
|
void setUserName(const QString& login);
|
||||||
void setPassword(const QString& password);
|
void setPassword(const QString& password);
|
||||||
void setServerName(const QString& serverName);
|
void setServerName(const QString& serverName);
|
||||||
|
void setServerPort(int serverPort);
|
||||||
|
void setServerCredentials(const ServerCredentials &credentials);
|
||||||
|
|
||||||
|
QString userName() const { return m_userName; }
|
||||||
|
QString password() const { return m_password; }
|
||||||
|
QString serverName() const { return m_serverName; }
|
||||||
|
int serverPort() const { return m_serverPort; }
|
||||||
|
ServerCredentials serverCredentials();
|
||||||
|
|
||||||
QString login() const;
|
|
||||||
QString password() const;
|
|
||||||
QString serverName() const;
|
|
||||||
|
|
||||||
bool haveAuthData() const;
|
bool haveAuthData() const;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
QSettings* m_settings;
|
QSettings* m_settings;
|
||||||
QString m_login;
|
QString m_userName;
|
||||||
QString m_password;
|
QString m_password;
|
||||||
QString m_serverName;
|
QString m_serverName;
|
||||||
|
int m_serverPort;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // SETTINGS_H
|
#endif // SETTINGS_H
|
||||||
|
|
|
||||||
|
|
@ -2,10 +2,14 @@
|
||||||
#include <QMessageBox>
|
#include <QMessageBox>
|
||||||
#include <QSysInfo>
|
#include <QSysInfo>
|
||||||
#include <QThread>
|
#include <QThread>
|
||||||
|
#include <QTimer>
|
||||||
|
|
||||||
#include "communicator.h"
|
#include "communicator.h"
|
||||||
|
|
||||||
|
#include "core/errorstrings.h"
|
||||||
#include "core/openvpnconfigurator.h"
|
#include "core/openvpnconfigurator.h"
|
||||||
#include "core/servercontroller.h"
|
#include "core/servercontroller.h"
|
||||||
|
|
||||||
#include "debug.h"
|
#include "debug.h"
|
||||||
#include "defines.h"
|
#include "defines.h"
|
||||||
#include "mainwindow.h"
|
#include "mainwindow.h"
|
||||||
|
|
@ -34,6 +38,10 @@ MainWindow::MainWindow(QWidget *parent) :
|
||||||
ui->stackedWidget_main->setSpeed(200);
|
ui->stackedWidget_main->setSpeed(200);
|
||||||
ui->stackedWidget_main->setAnimation(QEasingCurve::Linear);
|
ui->stackedWidget_main->setAnimation(QEasingCurve::Linear);
|
||||||
|
|
||||||
|
ui->label_new_server_wait_info->setVisible(false);
|
||||||
|
ui->progressBar_new_server_connection->setMinimum(0);
|
||||||
|
ui->progressBar_new_server_connection->setMaximum(300);
|
||||||
|
|
||||||
#ifdef Q_OS_MAC
|
#ifdef Q_OS_MAC
|
||||||
ui->widget_tittlebar->hide();
|
ui->widget_tittlebar->hide();
|
||||||
ui->stackedWidget_main->move(0,0);
|
ui->stackedWidget_main->move(0,0);
|
||||||
|
|
@ -48,6 +56,8 @@ MainWindow::MainWindow(QWidget *parent) :
|
||||||
goToPage(Page::Initialization);
|
goToPage(Page::Initialization);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//goToPage(Page::Initialization);
|
||||||
|
|
||||||
connect(ui->pushButton_blocked_list, SIGNAL(clicked(bool)), this, SLOT(onPushButtonBlockedListClicked(bool)));
|
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_connect, SIGNAL(toggled(bool)), this, SLOT(onPushButtonConnectToggled(bool)));
|
||||||
connect(ui->pushButton_settings, SIGNAL(clicked(bool)), this, SLOT(onPushButtonSettingsClicked(bool)));
|
connect(ui->pushButton_settings, SIGNAL(clicked(bool)), this, SLOT(onPushButtonSettingsClicked(bool)));
|
||||||
|
|
@ -148,28 +158,71 @@ void MainWindow::onPushButtonNewServerConnectWithNewData(bool clicked)
|
||||||
ui->lineEdit_new_server_password->text().isEmpty() ) {
|
ui->lineEdit_new_server_password->text().isEmpty() ) {
|
||||||
QMessageBox::warning(this, APPLICATION_NAME, tr("Please fill in all fields"));
|
QMessageBox::warning(this, APPLICATION_NAME, tr("Please fill in all fields"));
|
||||||
return;
|
return;
|
||||||
} else {
|
|
||||||
qDebug() << "Start connection with new data";
|
|
||||||
m_settings->setServerName(ui->lineEdit_new_server_ip->text());
|
|
||||||
m_settings->setLogin(ui->lineEdit_new_server_login->text());
|
|
||||||
m_settings->setPassword(ui->lineEdit_new_server_password->text());
|
|
||||||
m_settings->save();
|
|
||||||
|
|
||||||
//goToPage(Page::Vpn);
|
|
||||||
|
|
||||||
if (requestOvpnConfig(m_settings->serverName(), m_settings->login(), m_settings->password())) {
|
|
||||||
goToPage(Page::Vpn);
|
|
||||||
|
|
||||||
ui->pushButton_connect->setDown(true);
|
|
||||||
|
|
||||||
if (!m_vpnConnection->connectToVpn()) {
|
|
||||||
ui->pushButton_connect->setChecked(false);
|
|
||||||
QMessageBox::critical(this, APPLICATION_NAME, m_vpnConnection->lastError());
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
qDebug() << "Start connection with new data";
|
||||||
|
|
||||||
|
ServerCredentials serverCredentials;
|
||||||
|
serverCredentials.hostName = ui->lineEdit_new_server_ip->text();
|
||||||
|
if (serverCredentials.hostName.contains(":")) {
|
||||||
|
serverCredentials.port = serverCredentials.hostName.split(":").at(1).toInt();
|
||||||
|
serverCredentials.hostName = serverCredentials.hostName.split(":").at(0);
|
||||||
|
}
|
||||||
|
serverCredentials.userName = ui->lineEdit_new_server_login->text();
|
||||||
|
serverCredentials.password = ui->lineEdit_new_server_password->text();
|
||||||
|
|
||||||
|
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);
|
||||||
|
|
||||||
|
QTimer timer;
|
||||||
|
connect(&timer, &QTimer::timeout, [&](){
|
||||||
|
ui->progressBar_new_server_connection->setValue(ui->progressBar_new_server_connection->value() + 1);
|
||||||
|
});
|
||||||
|
|
||||||
|
ui->progressBar_new_server_connection->setValue(0);
|
||||||
|
timer.start(1000);
|
||||||
|
|
||||||
|
|
||||||
|
ErrorCode e = ServerController::setupServer(serverCredentials, 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);
|
||||||
|
|
||||||
|
QMessageBox::warning(this, APPLICATION_NAME,
|
||||||
|
tr("Error occurred while configuring server.") + "\n" +
|
||||||
|
errorString(e) + "\n" +
|
||||||
|
tr("See logs for details."));
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// just ui progressbar tweak
|
||||||
|
timer.stop();
|
||||||
|
|
||||||
|
int remaining_val = ui->progressBar_new_server_connection->maximum() - ui->progressBar_new_server_connection->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()) {
|
||||||
|
loop1.quit();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
timer1.start(5);
|
||||||
|
loop1.exec();
|
||||||
|
}
|
||||||
|
|
||||||
|
goToPage(Page::Vpn);
|
||||||
|
ui->pushButton_connect->setChecked(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
void MainWindow::onBytesChanged(quint64 receivedData, quint64 sentData)
|
void MainWindow::onBytesChanged(quint64 receivedData, quint64 sentData)
|
||||||
|
|
@ -249,9 +302,13 @@ void MainWindow::onConnectionStateChanged(VpnProtocol::ConnectionState state)
|
||||||
void MainWindow::onPushButtonConnectToggled(bool checked)
|
void MainWindow::onPushButtonConnectToggled(bool checked)
|
||||||
{
|
{
|
||||||
if (checked) {
|
if (checked) {
|
||||||
if (!m_vpnConnection->connectToVpn()) {
|
// 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, m_vpnConnection->lastError());
|
QMessageBox::critical(this, APPLICATION_NAME, errorString(errorCode));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
ui->pushButton_connect->setEnabled(false);
|
ui->pushButton_connect->setEnabled(false);
|
||||||
|
|
@ -260,36 +317,6 @@ void MainWindow::onPushButtonConnectToggled(bool checked)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
bool MainWindow::requestOvpnConfig(const QString& hostName, const QString& userName, const QString& password, int port, int timeout)
|
|
||||||
{
|
|
||||||
QSsh::SshConnectionParameters sshParams;
|
|
||||||
sshParams.authenticationType = QSsh::SshConnectionParameters::AuthenticationTypePassword;
|
|
||||||
sshParams.host = hostName;
|
|
||||||
sshParams.userName = userName;
|
|
||||||
sshParams.password = password;
|
|
||||||
sshParams.timeout = timeout;
|
|
||||||
sshParams.port = port;
|
|
||||||
sshParams.hostKeyCheckingMode = QSsh::SshHostKeyCheckingMode::SshHostKeyCheckingNone;
|
|
||||||
|
|
||||||
if (!ServerController::setupServer(sshParams, ServerController::OpenVPN)) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
QString configData = OpenVpnConfigurator::genOpenVpnConfig(sshParams);
|
|
||||||
if (configData.isEmpty()) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
QFile file(Utils::defaultVpnConfigFileName());
|
|
||||||
if (file.open(QIODevice::WriteOnly | QIODevice::Truncate)){
|
|
||||||
QTextStream stream(&file);
|
|
||||||
stream << configData << endl;
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
void MainWindow::on_pushButton_close_clicked()
|
void MainWindow::on_pushButton_close_clicked()
|
||||||
{
|
{
|
||||||
qApp->exit();
|
qApp->exit();
|
||||||
|
|
|
||||||
|
|
@ -4,7 +4,7 @@
|
||||||
#include <QMainWindow>
|
#include <QMainWindow>
|
||||||
|
|
||||||
#include "framelesswindow.h"
|
#include "framelesswindow.h"
|
||||||
#include "vpnprotocol.h"
|
#include "protocols/vpnprotocol.h"
|
||||||
|
|
||||||
class Settings;
|
class Settings;
|
||||||
class VpnConnection;
|
class VpnConnection;
|
||||||
|
|
@ -45,9 +45,6 @@ private slots:
|
||||||
|
|
||||||
void on_pushButton_close_clicked();
|
void on_pushButton_close_clicked();
|
||||||
|
|
||||||
protected:
|
|
||||||
bool requestOvpnConfig(const QString& hostName, const QString& userName, const QString& password, int port = 22, int timeout = 30);
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void goToPage(Page page);
|
void goToPage(Page page);
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -653,10 +653,7 @@ color: #333333;</string>
|
||||||
</property>
|
</property>
|
||||||
<property name="styleSheet">
|
<property name="styleSheet">
|
||||||
<string notr="true">QPushButton {
|
<string notr="true">QPushButton {
|
||||||
font-size: 13pt;
|
color:rgb(212, 212, 212);
|
||||||
font: "Open Sans Semibold";
|
|
||||||
color:rgb(212, 212, 212);
|
|
||||||
|
|
||||||
border-radius: 4px;
|
border-radius: 4px;
|
||||||
|
|
||||||
font-family: Lato;
|
font-family: Lato;
|
||||||
|
|
@ -708,8 +705,26 @@ color: #15CDCB;</string>
|
||||||
</rect>
|
</rect>
|
||||||
</property>
|
</property>
|
||||||
<property name="styleSheet">
|
<property name="styleSheet">
|
||||||
<string notr="true">background: #181922;
|
<string notr="true">QProgressBar{
|
||||||
border-radius: 4px;</string>
|
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>
|
||||||
<property name="value">
|
<property name="value">
|
||||||
<number>24</number>
|
<number>24</number>
|
||||||
|
|
@ -721,7 +736,7 @@ border-radius: 4px;</string>
|
||||||
<bool>true</bool>
|
<bool>true</bool>
|
||||||
</property>
|
</property>
|
||||||
<property name="format">
|
<property name="format">
|
||||||
<string>Connecting...</string>
|
<string>Configuring...</string>
|
||||||
</property>
|
</property>
|
||||||
</widget>
|
</widget>
|
||||||
<widget class="QPushButton" name="pushButton_back_from_new_server">
|
<widget class="QPushButton" name="pushButton_back_from_new_server">
|
||||||
|
|
@ -772,6 +787,25 @@ QPushButton:hover {
|
||||||
<string/>
|
<string/>
|
||||||
</property>
|
</property>
|
||||||
</widget>
|
</widget>
|
||||||
|
<widget class="QLabel" name="label_new_server_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>
|
||||||
<zorder>progressBar_new_server_connection</zorder>
|
<zorder>progressBar_new_server_connection</zorder>
|
||||||
<zorder>label_2</zorder>
|
<zorder>label_2</zorder>
|
||||||
<zorder>label_4</zorder>
|
<zorder>label_4</zorder>
|
||||||
|
|
@ -784,6 +818,7 @@ QPushButton:hover {
|
||||||
<zorder>pushButton</zorder>
|
<zorder>pushButton</zorder>
|
||||||
<zorder>pushButton_back_from_new_server</zorder>
|
<zorder>pushButton_back_from_new_server</zorder>
|
||||||
<zorder>label_7</zorder>
|
<zorder>label_7</zorder>
|
||||||
|
<zorder>label_new_server_wait_info</zorder>
|
||||||
</widget>
|
</widget>
|
||||||
<widget class="QWidget" name="page_amnezia">
|
<widget class="QWidget" name="page_amnezia">
|
||||||
<property name="styleSheet">
|
<property name="styleSheet">
|
||||||
|
|
|
||||||
|
|
@ -81,7 +81,7 @@ bool Utils::processIsRunning(const QString& fileName)
|
||||||
#ifdef Q_OS_WIN
|
#ifdef Q_OS_WIN
|
||||||
QProcess process;
|
QProcess process;
|
||||||
process.setReadChannel(QProcess::StandardOutput);
|
process.setReadChannel(QProcess::StandardOutput);
|
||||||
process.setReadChannelMode(QProcess::MergedChannels);
|
process.setProcessChannelMode(QProcess::MergedChannels);
|
||||||
process.start(QString("wmic.exe /OUTPUT:STDOUT PROCESS get %1").arg("Caption"));
|
process.start(QString("wmic.exe /OUTPUT:STDOUT PROCESS get %1").arg("Caption"));
|
||||||
process.waitForStarted();
|
process.waitForStarted();
|
||||||
process.waitForFinished();
|
process.waitForFinished();
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,11 @@
|
||||||
#include <QDebug>
|
#include <QDebug>
|
||||||
|
#include <QFile>
|
||||||
|
|
||||||
#include "openvpnprotocol.h"
|
#include <core/openvpnconfigurator.h>
|
||||||
|
#include <core/servercontroller.h>
|
||||||
|
|
||||||
|
#include "protocols/openvpnprotocol.h"
|
||||||
|
#include "utils.h"
|
||||||
#include "vpnconnection.h"
|
#include "vpnconnection.h"
|
||||||
|
|
||||||
VpnConnection::VpnConnection(QObject* parent) : QObject(parent)
|
VpnConnection::VpnConnection(QObject* parent) : QObject(parent)
|
||||||
|
|
@ -8,11 +13,6 @@ VpnConnection::VpnConnection(QObject* parent) : QObject(parent)
|
||||||
VpnProtocol::initializeCommunicator(parent);
|
VpnProtocol::initializeCommunicator(parent);
|
||||||
}
|
}
|
||||||
|
|
||||||
VpnConnection::~VpnConnection()
|
|
||||||
{
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
void VpnConnection::onBytesChanged(quint64 receivedBytes, quint64 sentBytes)
|
void VpnConnection::onBytesChanged(quint64 receivedBytes, quint64 sentBytes)
|
||||||
{
|
{
|
||||||
emit bytesChanged(receivedBytes, sentBytes);
|
emit bytesChanged(receivedBytes, sentBytes);
|
||||||
|
|
@ -23,28 +23,56 @@ void VpnConnection::onConnectionStateChanged(VpnProtocol::ConnectionState state)
|
||||||
emit connectionStateChanged(state);
|
emit connectionStateChanged(state);
|
||||||
}
|
}
|
||||||
|
|
||||||
QString VpnConnection::lastError() const
|
ErrorCode VpnConnection::lastError() const
|
||||||
{
|
{
|
||||||
if (!m_vpnProtocol.data()) {
|
if (!m_vpnProtocol.data()) {
|
||||||
return "Unnown protocol";
|
return ErrorCode::InternalError;
|
||||||
}
|
}
|
||||||
|
|
||||||
return m_vpnProtocol.data()->lastError();
|
return m_vpnProtocol.data()->lastError();
|
||||||
}
|
}
|
||||||
|
|
||||||
bool VpnConnection::connectToVpn(Protocol protocol)
|
ErrorCode VpnConnection::requestVpnConfig(const ServerCredentials &credentials, Protocol protocol)
|
||||||
{
|
{
|
||||||
|
ErrorCode errorCode = ErrorCode::NoError;
|
||||||
|
if (protocol == Protocol::OpenVpn) {
|
||||||
|
QString configData = OpenVpnConfigurator::genOpenVpnConfig(credentials, &errorCode);
|
||||||
|
if (errorCode) {
|
||||||
|
return errorCode;
|
||||||
|
}
|
||||||
|
|
||||||
|
QFile file(Utils::defaultVpnConfigFileName());
|
||||||
|
if (file.open(QIODevice::WriteOnly | QIODevice::Truncate)){
|
||||||
|
QTextStream stream(&file);
|
||||||
|
stream << configData << endl;
|
||||||
|
return ErrorCode::NoError;
|
||||||
|
}
|
||||||
|
|
||||||
|
return ErrorCode::FailedToSaveConfigData;
|
||||||
|
}
|
||||||
|
else if (protocol == Protocol::ShadowSocks) {
|
||||||
|
// Request OpenVPN config and ShadowSocks
|
||||||
|
return ErrorCode::NotImplementedError;
|
||||||
|
}
|
||||||
|
return ErrorCode::NotImplementedError;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
ErrorCode VpnConnection::connectToVpn(const ServerCredentials &credentials, Protocol protocol)
|
||||||
|
{
|
||||||
|
// TODO: Try protocols one by one in case of Protocol::Any
|
||||||
|
// TODO: Implement some behavior in case if connection not stable
|
||||||
qDebug() << "Connect to VPN";
|
qDebug() << "Connect to VPN";
|
||||||
|
|
||||||
switch (protocol) {
|
if (protocol == Protocol::Any || protocol == Protocol::OpenVpn) {
|
||||||
case Protocol::OpenVpn:
|
ErrorCode e = requestVpnConfig(credentials, Protocol::OpenVpn);
|
||||||
|
if (e) {
|
||||||
|
return e;
|
||||||
|
}
|
||||||
m_vpnProtocol.reset(new OpenVpnProtocol());
|
m_vpnProtocol.reset(new OpenVpnProtocol());
|
||||||
break;
|
}
|
||||||
;
|
else if (protocol == Protocol::ShadowSocks) {
|
||||||
default:
|
return ErrorCode::NotImplementedError;
|
||||||
// TODO, add later
|
|
||||||
return false;
|
|
||||||
;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
connect(m_vpnProtocol.data(), SIGNAL(connectionStateChanged(VpnProtocol::ConnectionState)), this, SLOT(onConnectionStateChanged(VpnProtocol::ConnectionState)));
|
connect(m_vpnProtocol.data(), SIGNAL(connectionStateChanged(VpnProtocol::ConnectionState)), this, SLOT(onConnectionStateChanged(VpnProtocol::ConnectionState)));
|
||||||
|
|
|
||||||
|
|
@ -5,7 +5,10 @@
|
||||||
#include <QString>
|
#include <QString>
|
||||||
#include <QScopedPointer>
|
#include <QScopedPointer>
|
||||||
|
|
||||||
#include "vpnprotocol.h"
|
#include "protocols/vpnprotocol.h"
|
||||||
|
#include "core/defs.h"
|
||||||
|
|
||||||
|
using namespace amnezia;
|
||||||
|
|
||||||
class VpnConnection : public QObject
|
class VpnConnection : public QObject
|
||||||
{
|
{
|
||||||
|
|
@ -13,13 +16,13 @@ class VpnConnection : public QObject
|
||||||
|
|
||||||
public:
|
public:
|
||||||
explicit VpnConnection(QObject* parent = nullptr);
|
explicit VpnConnection(QObject* parent = nullptr);
|
||||||
~VpnConnection();
|
~VpnConnection() override = default;
|
||||||
|
|
||||||
enum class Protocol{OpenVpn};
|
|
||||||
static QString bytesToText(quint64 bytes);
|
static QString bytesToText(quint64 bytes);
|
||||||
|
|
||||||
QString lastError() const;
|
ErrorCode lastError() const;
|
||||||
bool connectToVpn(Protocol protocol = Protocol::OpenVpn);
|
ErrorCode requestVpnConfig(const ServerCredentials &credentials, Protocol protocol);
|
||||||
|
ErrorCode connectToVpn(const ServerCredentials &credentials, Protocol protocol = Protocol::Any);
|
||||||
bool connected() const;
|
bool connected() const;
|
||||||
bool disconnected() const;
|
bool disconnected() const;
|
||||||
void disconnectFromVpn();
|
void disconnectFromVpn();
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue