refactoring

This commit is contained in:
pokamest 2021-04-26 22:54:31 +03:00
parent 7bba7a9eab
commit 615bba69e5
23 changed files with 1692 additions and 699 deletions

View file

@ -14,11 +14,11 @@ QJsonObject CloakConfigurator::genCloakConfig(const ServerCredentials &credentia
DockerContainer container = amnezia::containerForProto(proto);
QString cloakPublicKey = ServerController::getTextFileFromContainer(container, credentials,
amnezia::protocols::cloak::ckPublicKeyPath(), &e);
amnezia::protocols::cloak::ckPublicKeyPath, &e);
cloakPublicKey.replace("\n", "");
QString cloakBypassUid = ServerController::getTextFileFromContainer(container, credentials,
amnezia::protocols::cloak::ckBypassUidKeyPath(), &e);
amnezia::protocols::cloak::ckBypassUidKeyPath, &e);
cloakBypassUid.replace("\n", "");
if (e) {
@ -32,7 +32,7 @@ QJsonObject CloakConfigurator::genCloakConfig(const ServerCredentials &credentia
config.insert("EncryptionMethod", "aes-gcm");
config.insert("UID", cloakBypassUid);
config.insert("PublicKey", cloakPublicKey);
config.insert("ServerName", amnezia::protocols::cloak::ckDefaultRedirSite());
config.insert("ServerName", amnezia::protocols::cloak::ckDefaultRedirSite);
config.insert("NumConn", 4);
config.insert("BrowserSig", "chrome");
config.insert("StreamTimeout", 300);

View file

@ -150,7 +150,7 @@ OpenVpnConfigurator::ConnectionData OpenVpnConfigurator::prepareOpenVpnConfig(co
}
QString reqFileName = QString("%1/%2.req").
arg(amnezia::protocols::openvpn::clientsDirPath()).
arg(amnezia::protocols::openvpn::clientsDirPath).
arg(connData.clientId);
DockerContainer container = amnezia::containerForProto(proto);
@ -167,16 +167,16 @@ OpenVpnConfigurator::ConnectionData OpenVpnConfigurator::prepareOpenVpnConfig(co
return connData;
}
connData.caCert = ServerController::getTextFileFromContainer(container, credentials, amnezia::protocols::openvpn::caCertPath(), &e);
connData.caCert = ServerController::getTextFileFromContainer(container, credentials, amnezia::protocols::openvpn::caCertPath, &e);
connData.clientCert = ServerController::getTextFileFromContainer(container, credentials,
QString("%1/%2.crt").arg(amnezia::protocols::openvpn::clientCertPath()).arg(connData.clientId), &e);
QString("%1/%2.crt").arg(amnezia::protocols::openvpn::clientCertPath).arg(connData.clientId), &e);
if (e) {
if (errorCode) *errorCode = e;
return connData;
}
connData.taKey = ServerController::getTextFileFromContainer(container, credentials, amnezia::protocols::openvpn::taKeyPath(), &e);
connData.taKey = ServerController::getTextFileFromContainer(container, credentials, amnezia::protocols::openvpn::taKeyPath, &e);
if (connData.caCert.isEmpty() || connData.clientCert.isEmpty() || connData.taKey.isEmpty()) {
if (errorCode) *errorCode = ErrorCode::RemoteProcessCrashError;
@ -217,7 +217,7 @@ QString OpenVpnConfigurator::genOpenVpnConfig(const ServerCredentials &credentia
config.replace("$PROTO", "udp");
else if (proto == Protocol::ShadowSocksOverOpenVpn) {
config.replace("$PROTO", "tcp");
config.replace("$LOCAL_PROXY_PORT", QString::number(amnezia::protocols::shadowsocks::ssContainerPort()));
config.replace("$LOCAL_PROXY_PORT", amnezia::protocols::shadowsocks::ssLocalProxyPort);
}
else if (proto == Protocol::OpenVpnOverCloak) {
config.replace("$PROTO", "tcp");
@ -231,7 +231,7 @@ QString OpenVpnConfigurator::genOpenVpnConfig(const ServerCredentials &credentia
}
config.replace("$REMOTE_HOST", connData.host);
config.replace("$REMOTE_PORT", amnezia::protocols::openvpn::openvpnDefaultPort());
config.replace("$REMOTE_PORT", amnezia::protocols::openvpn::openvpnDefaultPort);
config.replace("$CA_CERT", connData.caCert);
config.replace("$CLIENT_CERT", connData.clientCert);
config.replace("$PRIV_KEY", connData.privKey);
@ -284,7 +284,7 @@ ErrorCode OpenVpnConfigurator::signCert(DockerContainer container,
QString script_import = QString("sudo docker exec -i %1 bash -c \"cd /opt/amnezia/openvpn && "
"easyrsa import-req %2/%3.req %3\"")
.arg(amnezia::server::getContainerName(container))
.arg(amnezia::protocols::openvpn::clientsDirPath())
.arg(amnezia::protocols::openvpn::clientsDirPath)
.arg(clientId);
QString script_sign = QString("sudo docker exec -i %1 bash -c \"export EASYRSA_BATCH=1; cd /opt/amnezia/openvpn && "

View file

@ -21,7 +21,10 @@ QString amnezia::scriptName(SharedScriptType type)
case SharedScriptType::prepare_host: return QLatin1String("prepare_host.sh");
case SharedScriptType::install_docker: return QLatin1String("install_docker.sh");
case SharedScriptType::build_container: return QLatin1String("build_container.sh");
case SharedScriptType::remove_container: return QLatin1String("remove_container.sh");
case SharedScriptType::remove_all_containers: return QLatin1String("remove_all_containers.sh");
case SharedScriptType::setup_host_firewall: return QLatin1String("setup_host_firewall.sh");
case SharedScriptType::check_connection: return QLatin1String("check_connection.sh");
}
}

View file

@ -11,7 +11,10 @@ enum SharedScriptType {
prepare_host,
install_docker,
build_container,
remove_container,
remove_all_containers,
setup_host_firewall,
check_connection
};
enum ProtocolScriptType {
// Protocol scripts

View file

@ -9,10 +9,6 @@ namespace server {
QString getContainerName(amnezia::DockerContainer container);
QString getDockerfileFolder(amnezia::DockerContainer container);
const char vpnDefaultSubnetIp[] = "10.8.0.0";
const char vpnDefaultSubnetMask[] = "255.255.255.0";
const char vpnDefaultSubnetMaskVal[] = "24";
}
}

View file

@ -27,7 +27,12 @@ ErrorCode ServerController::runScript(const SshConnectionParameters &sshParams,
const std::function<void(const QString &, QSharedPointer<SshRemoteProcess>)> &cbReadStdErr)
{
SshConnection *client = connectToHost(sshParams);
if (client->state() != SshConnection::State::Connected) {
if (client->state() == SshConnection::State::Connecting) {
qDebug() << "ServerController::runScript aborted, connectToHost in progress";
return ErrorCode::SshTimeoutError;
}
else if (client->state() != SshConnection::State::Connected) {
qDebug() << "ServerController::runScript connectToHost error: " << fromSshConnectionErrorCode(client->errorState());
return fromSshConnectionErrorCode(client->errorState());
}
@ -260,9 +265,9 @@ QString ServerController::getTextFileFromContainer(DockerContainer container,
ErrorCode ServerController::checkOpenVpnServer(DockerContainer container, const ServerCredentials &credentials)
{
QString caCert = ServerController::getTextFileFromContainer(container,
credentials, amnezia::protocols::openvpn::caCertPath());
credentials, amnezia::protocols::openvpn::caCertPath);
QString taKey = ServerController::getTextFileFromContainer(container,
credentials, amnezia::protocols::openvpn::taKeyPath());
credentials, amnezia::protocols::openvpn::taKeyPath);
if (!caCert.isEmpty() && !taKey.isEmpty()) {
return ErrorCode::NoError;
@ -382,66 +387,42 @@ SshConnectionParameters ServerController::sshParams(const ServerCredentials &cre
return sshParams;
}
ErrorCode ServerController::removeServer(const ServerCredentials &credentials, Protocol proto)
ErrorCode ServerController::removeAllContainers(const ServerCredentials &credentials)
{
QString scriptFileName;
DockerContainer container;
if (proto == Protocol::Any) {
ErrorCode e = removeServer(credentials, Protocol::OpenVpn);
if (e) {
return e;
}
return removeServer(credentials, Protocol::ShadowSocksOverOpenVpn);
}
else if (proto == Protocol::OpenVpn) {
scriptFileName = ":/server_scripts/remove_container.sh";
container = DockerContainer::OpenVpn;
}
else if (proto == Protocol::ShadowSocksOverOpenVpn) {
scriptFileName = ":/server_scripts/remove_container.sh";
container = DockerContainer::ShadowSocksOverOpenVpn;
}
else return ErrorCode::NotImplementedError;
QString scriptData;
QFile file(scriptFileName);
if (! file.open(QIODevice::ReadOnly)) return ErrorCode::InternalError;
scriptData = file.readAll();
if (scriptData.isEmpty()) return ErrorCode::InternalError;
return runScript(sshParams(credentials), replaceVars(scriptData, genVarsForScript(credentials, container)));
return runScript(sshParams(credentials),
amnezia::scriptData(SharedScriptType::remove_all_containers));
}
ErrorCode ServerController::setupServer(const ServerCredentials &credentials, Protocol proto)
ErrorCode ServerController::removeContainer(const ServerCredentials &credentials, DockerContainer container)
{
return runScript(sshParams(credentials),
replaceVars(amnezia::scriptData(SharedScriptType::remove_container),
genVarsForScript(credentials, container)));
}
ErrorCode ServerController::setupContainer(const ServerCredentials &credentials, DockerContainer container, const QJsonObject &config)
{
ErrorCode e = runScript(sshParams(credentials),
replaceVars(amnezia::scriptData(SharedScriptType::install_docker),
genVarsForScript(credentials)));
if (e) return e;
if (proto == Protocol::OpenVpn) {
if (container == DockerContainer::OpenVpn) {
return ErrorCode::NoError;
//return setupOpenVpnServer(credentials);
//return setupOpenVpnServer(credentials, config);
}
else if (proto == Protocol::ShadowSocksOverOpenVpn) {
return setupShadowSocksServer(credentials);
else if (container == DockerContainer::ShadowSocksOverOpenVpn) {
return setupShadowSocksServer(credentials, config);
}
else if (proto == Protocol::Any) {
//return ErrorCode::NotImplementedError;
//setupOpenVpnServer(credentials);
//return setupShadowSocksServer(credentials);
return setupOpenVpnOverCloakServer(credentials);
else if (container == DockerContainer::OpenVpnOverCloak) {
return setupOpenVpnOverCloakServer(credentials, config);
}
return ErrorCode::NoError;
}
ErrorCode ServerController::setupOpenVpnServer(const ServerCredentials &credentials)
ErrorCode ServerController::setupOpenVpnServer(const ServerCredentials &credentials, const QJsonObject &config)
{
return ErrorCode::NotImplementedError;
@ -475,7 +456,7 @@ ErrorCode ServerController::setupOpenVpnServer(const ServerCredentials &credenti
// return checkOpenVpnServer(DockerContainer::OpenVpn, credentials);
}
ErrorCode ServerController::setupOpenVpnOverCloakServer(const ServerCredentials &credentials)
ErrorCode ServerController::setupOpenVpnOverCloakServer(const ServerCredentials &credentials, const QJsonObject &config)
{
ErrorCode e;
DockerContainer container = DockerContainer::OpenVpnOverCloak;
@ -490,7 +471,6 @@ ErrorCode ServerController::setupOpenVpnOverCloakServer(const ServerCredentials
amnezia::server::getDockerfileFolder(container) + "/Dockerfile");
// Setup openvpn part
QString scriptData = amnezia::scriptData(SharedScriptType::build_container);
if (scriptData.isEmpty()) return ErrorCode::InternalError;
@ -518,11 +498,6 @@ ErrorCode ServerController::setupOpenVpnOverCloakServer(const ServerCredentials
genVarsForScript(credentials, container)),
"/opt/amnezia/start.sh");
// qDebug().noquote() << "AAAA"
// << amnezia::scriptData(ProtocolScriptType::container_startup, Protocol::OpenVpnOverCloak),
// replaceVars("/opt/amnezia/start.sh",
// genVarsForScript(credentials, container));
runScript(sshParams(credentials),
replaceVars("sudo docker exec -d $CONTAINER_NAME sh -c \"chmod a+x /opt/amnezia/start.sh && /opt/amnezia/start.sh\"",
genVarsForScript(credentials, container)));
@ -531,7 +506,7 @@ ErrorCode ServerController::setupOpenVpnOverCloakServer(const ServerCredentials
return e;
}
ErrorCode ServerController::setupShadowSocksServer(const ServerCredentials &credentials)
ErrorCode ServerController::setupShadowSocksServer(const ServerCredentials &credentials, const QJsonObject &config)
{
return ErrorCode::NotImplementedError;
// // Setup openvpn part
@ -582,20 +557,20 @@ ErrorCode ServerController::setupShadowSocksServer(const ServerCredentials &cred
// return e;
}
ServerController::Vars ServerController::genVarsForScript(const ServerCredentials &credentials, DockerContainer container)
ServerController::Vars ServerController::genVarsForScript(const ServerCredentials &credentials, DockerContainer container, const QJsonObject &config)
{
Vars vars;
vars.append(qMakePair<QString, QString>("$VPN_SUBNET_IP", amnezia::server::vpnDefaultSubnetIp));
vars.append(qMakePair<QString, QString>("$VPN_SUBNET_MASK_VAL", amnezia::server::vpnDefaultSubnetMaskVal));
vars.append(qMakePair<QString, QString>("$VPN_SUBNET_MASK", amnezia::server::vpnDefaultSubnetMask));
vars.append({{"$VPN_SUBNET_IP", nonEmpty(config.value(config_key::subnet_address).toString(), amnezia::protocols::vpnDefaultSubnetAddress) }});
vars.append({{"$VPN_SUBNET_MASK_VAL", nonEmpty(config.value(config_key::subnet_mask_val).toString(), amnezia::protocols::vpnDefaultSubnetMaskVal) }});
vars.append({{"$VPN_SUBNET_MASK", nonEmpty(config.value(config_key::subnet_mask).toString(), amnezia::protocols::vpnDefaultSubnetMask) }});
vars.append(qMakePair<QString, QString>("$CONTAINER_NAME", amnezia::server::getContainerName(container)));
vars.append(qMakePair<QString, QString>("$DOCKERFILE_FOLDER", "/opt/amnezia/" + amnezia::server::getContainerName(container)));
vars.append({{"$CONTAINER_NAME", amnezia::server::getContainerName(container)}});
vars.append({{"$DOCKERFILE_FOLDER", "/opt/amnezia/" + amnezia::server::getContainerName(container)}});
QString serverIp = Utils::getIPAddress(credentials.hostName);
if (!serverIp.isEmpty()) {
vars.append(qMakePair<QString, QString>("$SERVER_IP_ADDRESS", serverIp));
vars.append({{"$SERVER_IP_ADDRESS", serverIp}});
}
else {
qWarning() << "ServerController::genVarsForScript unable to resolve address for credentials.hostName";
@ -603,23 +578,47 @@ ServerController::Vars ServerController::genVarsForScript(const ServerCredential
//
const QJsonObject &openvpnConfig = config.value(config_key::openvpn).toObject();
const QJsonObject &cloakConfig = config.value(config_key::cloak).toObject();
const QJsonObject &ssConfig = config.value(config_key::shadowsocks).toObject();
if (container == DockerContainer::OpenVpn) {
vars.append(qMakePair<QString, QString>("$SERVER_PORT", amnezia::protocols::openvpn::openvpnDefaultPort()));
vars.append({{"$DOCKER_PORT", nonEmpty(config.value(config_key::port).toString(), protocols::openvpn::openvpnDefaultPort) }});
}
else if (container == DockerContainer::OpenVpnOverCloak) {
vars.append(qMakePair<QString, QString>("$SERVER_PORT", amnezia::protocols::cloak::ckDefaultPort()));
vars.append(qMakePair<QString, QString>("$FAKE_WEB_SITE_ADDRESS", amnezia::protocols::cloak::ckDefaultRedirSite()));
vars.append({{"$DOCKER_PORT", nonEmpty(config.value(config_key::port).toString(), protocols::cloak::ckDefaultPort) }});
vars.append({{"$FAKE_WEB_SITE_ADDRESS", nonEmpty(cloakConfig.value(config_key::site).toString(), protocols::cloak::ckDefaultRedirSite) }});
}
else if (container == DockerContainer::ShadowSocksOverOpenVpn) {
vars.append(qMakePair<QString, QString>("$SERVER_PORT", "6789"));
vars.append({{"$DOCKER_PORT", nonEmpty(config.value(config_key::port).toString(), protocols::shadowsocks::ssDefaultPort) }});
}
return vars;
}
QString ServerController::checkSshConnection(const ServerCredentials &credentials, ErrorCode *errorCode)
{
QString stdOut;
auto cbReadStdOut = [&](const QString &data, QSharedPointer<QSsh::SshRemoteProcess> proc) {
stdOut += data + "\n";
};
auto cbReadStdErr = [&](const QString &data, QSharedPointer<QSsh::SshRemoteProcess> ) {
stdOut += data + "\n";
};
ErrorCode e = runScript(sshParams(credentials),
amnezia::scriptData(SharedScriptType::check_connection), cbReadStdOut, cbReadStdErr);
if (errorCode) *errorCode = e;
return stdOut;
}
SshConnection *ServerController::connectToHost(const SshConnectionParameters &sshParams)
{
SshConnection *client = acquireConnection(sshParams);
if (!client) return nullptr;
QEventLoop waitssh;
QObject::connect(client, &SshConnection::connected, &waitssh, [&]() {
@ -670,6 +669,12 @@ SshConnection *ServerController::connectToHost(const SshConnectionParameters &ss
return client;
}
void ServerController::disconnectFromHost(const ServerCredentials &credentials)
{
SshConnection *client = acquireConnection(sshParams(credentials));
if (client) client->disconnectFromHost();
}
ErrorCode ServerController::setupServerFirewall(const ServerCredentials &credentials)
{
return runScript(sshParams(credentials),

View file

@ -1,6 +1,7 @@
#ifndef SERVERCONTROLLER_H
#define SERVERCONTROLLER_H
#include <QJsonObject>
#include <QObject>
#include "sshconnection.h"
#include "sshremoteprocess.h"
@ -20,9 +21,11 @@ public:
static ErrorCode fromSshProcessExitStatus(int exitStatus);
static QSsh::SshConnectionParameters sshParams(const ServerCredentials &credentials);
static void disconnectFromHost(const ServerCredentials &credentials);
static ErrorCode removeServer(const ServerCredentials &credentials, Protocol proto);
static ErrorCode setupServer(const ServerCredentials &credentials, Protocol proto);
static ErrorCode removeAllContainers(const ServerCredentials &credentials);
static ErrorCode removeContainer(const ServerCredentials &credentials, DockerContainer container);
static ErrorCode setupContainer(const ServerCredentials &credentials, DockerContainer container, const QJsonObject &config = QJsonObject());
static ErrorCode checkOpenVpnServer(DockerContainer container, const ServerCredentials &credentials);
@ -42,16 +45,17 @@ public:
const std::function<void(const QString &, QSharedPointer<QSsh::SshRemoteProcess>)> &cbReadStdOut = nullptr,
const std::function<void(const QString &, QSharedPointer<QSsh::SshRemoteProcess>)> &cbReadStdErr = nullptr);
static Vars genVarsForScript(const ServerCredentials &credentials, DockerContainer container = DockerContainer::None);
static Vars genVarsForScript(const ServerCredentials &credentials, DockerContainer container = DockerContainer::None, const QJsonObject &config = QJsonObject());
static QString checkSshConnection(const ServerCredentials &credentials, ErrorCode *errorCode = nullptr);
private:
static QSsh::SshConnection *connectToHost(const QSsh::SshConnectionParameters &sshParams);
static ErrorCode installDocker(const ServerCredentials &credentials);
static ErrorCode setupOpenVpnServer(const ServerCredentials &credentials);
static ErrorCode setupOpenVpnOverCloakServer(const ServerCredentials &credentials);
static ErrorCode setupShadowSocksServer(const ServerCredentials &credentials);
static ErrorCode setupOpenVpnServer(const ServerCredentials &credentials, const QJsonObject &config = QJsonObject());
static ErrorCode setupOpenVpnOverCloakServer(const ServerCredentials &credentials, const QJsonObject &config = QJsonObject());
static ErrorCode setupShadowSocksServer(const ServerCredentials &credentials, const QJsonObject &config = QJsonObject());
};
#endif // SERVERCONTROLLER_H

Binary file not shown.

Before

Width:  |  Height:  |  Size: 13 KiB

After

Width:  |  Height:  |  Size: 182 B

Before After
Before After

Binary file not shown.

Before

Width:  |  Height:  |  Size: 10 KiB

After

Width:  |  Height:  |  Size: 181 B

Before After
Before After

View file

@ -38,8 +38,8 @@ ErrorCode OpenVpnOverCloakProtocol::start()
QStringList args = QStringList() << "-c" << m_cloakCfgFile.fileName()
<< "-s" << m_cloakConfig.value("Remote").toString()
<< "-p" << amnezia::protocols::cloak::ckDefaultPort()
<< "-l" << amnezia::protocols::openvpn::openvpnDefaultPort();
<< "-p" << amnezia::protocols::cloak::ckDefaultPort
<< "-l" << amnezia::protocols::openvpn::openvpnDefaultPort;
qDebug().noquote() << "OpenVpnOverCloakProtocol::start()"
<< cloakExecPath() << args.join(" ");

View file

@ -4,28 +4,73 @@
#include <QObject>
namespace amnezia {
namespace protocols {
namespace openvpn {
static QString caCertPath() { return "/opt/amnezia/openvpn/pki/ca.crt"; }
static QString clientCertPath() { return "/opt/amnezia/openvpn/pki/issued"; }
static QString taKeyPath() { return "/opt/amnezia/openvpn/ta.key"; }
static QString clientsDirPath() { return "/opt/amnezia/openvpn/clients"; }
static QString openvpnDefaultPort() { return "1194"; }
inline QString nonEmpty(const QString &val, const QString &deflt) { return val.isEmpty() ? deflt : val; }
namespace config_key {
// Json config strings
const char hostName[] = "hostName";
const char userName[] = "userName";
const char password[] = "password";
const char port[] = "port";
const char description[] = "description";
const char containers[] = "containers";
const char container[] = "container";
const char defaultContainer[] = "defaultContainer";
const char protocols[] = "protocols";
const char protocol[] = "protocol";
const char transport_protocol[] = "transport_protocol";
const char cipher[] = "cipher";
const char hash[] = "hash";
const char site[] = "site";
const char subnet_address[] = "subnet_address";
const char subnet_mask[] = "subnet_mask";
const char subnet_mask_val[] = "subnet_mask_val";
const char openvpn[] = "openvpn";
const char shadowsocks[] = "shadowsocks";
const char cloak[] = "cloak";
}
namespace protocols {
const char vpnDefaultSubnetAddress[] = "10.8.0.0";
const char vpnDefaultSubnetMask[] = "255.255.255.0";
const char vpnDefaultSubnetMaskVal[] = "24";
namespace openvpn {
const char caCertPath[] = "/opt/amnezia/openvpn/pki/ca.crt";
const char clientCertPath[] = "/opt/amnezia/openvpn/pki/issued";
const char taKeyPath[] = "/opt/amnezia/openvpn/ta.key";
const char clientsDirPath[] = "/opt/amnezia/openvpn/clients";
const char openvpnDefaultPort[] = "1194";
const char openvpnDefaultProto[] = "UDP";
const char openvpnDefaultCipher[] = "AES-256-GCM";
const char openvpnDefaultHash[] = "SHA512";
const bool blockOutsideDNS = true;
}
namespace shadowsocks {
static int ssRemotePort() { return 6789; }
static int ssContainerPort() { return 8585; }
static QString ssEncryption() { return "chacha20-ietf-poly1305"; }
const char ssDefaultPort[] = "6789";
const char ssLocalProxyPort[] = "8585";
const char ssDefaultCipher[] = "chacha20-ietf-poly1305";
}
namespace cloak {
static QString ckPublicKeyPath() { return "/opt/amnezia/cloak/cloak_public.key"; }
static QString ckBypassUidKeyPath() { return "/opt/amnezia/cloak/cloak_bypass_uid.key"; }
static QString ckAdminKeyPath() { return "/opt/amnezia/cloak/cloak_admin_uid.key"; }
static QString ckDefaultPort() { return "443"; }
static QString ckDefaultRedirSite() { return "mail.ru"; }
const char ckPublicKeyPath[] = "/opt/amnezia/cloak/cloak_public.key";
const char ckBypassUidKeyPath[] = "/opt/amnezia/cloak/cloak_bypass_uid.key";
const char ckAdminKeyPath[] = "/opt/amnezia/cloak/cloak_admin_uid.key";
const char ckDefaultPort[] = "443";
const char ckDefaultRedirSite[] = "mail.ru";
}

View file

@ -100,11 +100,11 @@ QJsonObject ShadowSocksVpnProtocol::genShadowSocksConfig(const ServerCredentials
{
QJsonObject ssConfig;
ssConfig.insert("server", credentials.hostName);
ssConfig.insert("server_port", amnezia::protocols::shadowsocks::ssRemotePort());
ssConfig.insert("local_port", amnezia::protocols::shadowsocks::ssContainerPort());
ssConfig.insert("server_port", amnezia::protocols::shadowsocks::ssDefaultPort);
ssConfig.insert("local_port", amnezia::protocols::shadowsocks::ssLocalProxyPort);
ssConfig.insert("password", QString(QCryptographicHash::hash(credentials.password.toUtf8(), QCryptographicHash::Sha256).toHex()));
ssConfig.insert("timeout", 60);
ssConfig.insert("method", amnezia::protocols::shadowsocks::ssEncryption());
ssConfig.insert("method", amnezia::protocols::shadowsocks::ssDefaultCipher);
return ssConfig;
}

View file

@ -52,5 +52,7 @@
<file>images/uncheck.png</file>
<file>images/settings_grey.png</file>
<file>images/plus.png</file>
<file>server_scripts/check_connection.sh</file>
<file>server_scripts/remove_all_containers.sh</file>
</qresource>
</RCC>

View file

@ -0,0 +1 @@
uname -a

View file

@ -5,11 +5,11 @@
#sudo docker stop $CONTAINER_NAME
#sudo docker rm -f $CONTAINER_NAME
#sudo docker pull amneziavpn/openvpn-cloak:latest
#sudo docker run -d --restart always --cap-add=NET_ADMIN -p $SERVER_PORT:443/tcp --name $CONTAINER_NAME amneziavpn/openvpn-cloak:latest
#sudo docker run -d --restart always --cap-add=NET_ADMIN -p $DOCKER_PORT:443/tcp --name $CONTAINER_NAME amneziavpn/openvpn-cloak:latest
sudo docker stop $CONTAINER_NAME
sudo docker rm -f $CONTAINER_NAME
sudo docker run -d --restart always --cap-add=NET_ADMIN -p $SERVER_PORT:443/tcp --name $CONTAINER_NAME $CONTAINER_NAME
sudo docker run -d --restart always --cap-add=NET_ADMIN -p $DOCKER_PORT:443/tcp --name $CONTAINER_NAME $CONTAINER_NAME
# Create tun device if not exist
sudo docker exec -i $CONTAINER_NAME bash -c 'mkdir -p /dev/net; if [ ! -c /dev/net/tun ]; then mknod /dev/net/tun c 10 200; fi'

View file

@ -0,0 +1,3 @@
sudo docker ps | grep amnezia | awk '{print $1}' | xargs sudo docker stop
sudo docker ps | grep amnezia | awk '{print $1}' | xargs sudo docker rm
sudo docker images -a | grep amnezia | awk '{print $3}' | xargs docker rmi

View file

@ -2,6 +2,7 @@
#include "settings.h"
#include <QDebug>
#include "protocols/protocols_defs.h"
Settings::Settings(QObject* parent) :
QObject(parent),
@ -16,11 +17,11 @@ Settings::Settings(QObject* parent) :
if (!user.isEmpty() && !password.isEmpty() && !serverName.isEmpty()){
QJsonObject server;
server.insert(userNameString, user);
server.insert(passwordString, password);
server.insert(hostNameString, serverName);
server.insert(portString, port);
server.insert(descriptionString, tr("Server #1"));
server.insert(config_key::userName, user);
server.insert(config_key::password, password);
server.insert(config_key::hostName, serverName);
server.insert(config_key::port, port);
server.insert(config_key::description, tr("Server #1"));
addServer(server);
}
@ -69,7 +70,7 @@ bool Settings::editServer(int index, const QJsonObject &server)
void Settings::setDefaultContainer(int serverIndex, DockerContainer container)
{
QJsonObject s = server(serverIndex);
s.insert(defaultContainerString, containerToString(container));
s.insert(config_key::defaultContainer, containerToString(container));
editServer(serverIndex, s);
}
@ -80,13 +81,42 @@ DockerContainer Settings::defaultContainer(int serverIndex) const
QString Settings::defaultContainerName(int serverIndex) const
{
QString name = server(serverIndex).value(defaultContainerString).toString();
QString name = server(serverIndex).value(config_key::defaultContainer).toString();
if (name.isEmpty()) {
return containerToString(DockerContainer::OpenVpnOverCloak);
}
else return name;
}
QJsonObject Settings::containerConfig(int serverIndex, DockerContainer container)
{
if (container == DockerContainer::None) return QJsonObject();
const QJsonArray &containers = server(serverIndex).value(config_key::containers).toArray();
for (const QJsonValue &val : containers) {
if (val.toObject().value(config_key::container).toString() == containerToString(container)) {
return val.toObject();
}
}
return QJsonObject();
}
QJsonObject Settings::protocolConfig(int serverIndex, DockerContainer container, Protocol proto)
{
const QJsonObject &c = containerConfig(serverIndex, container);
switch (proto) {
case Protocol::OpenVpn:
return c.value(config_key::openvpn).toObject();
case Protocol::OpenVpnOverCloak:
return c.value(config_key::openvpn).toObject();
case Protocol::ShadowSocksOverOpenVpn:
return c.value(config_key::openvpn).toObject();
default:
break;
}
}
bool Settings::haveAuthData() const
{
ServerCredentials cred = defaultServerCredentials();
@ -94,6 +124,26 @@ bool Settings::haveAuthData() const
return (!cred.hostName.isEmpty() && !cred.userName.isEmpty() && !cred.password.isEmpty());
}
QString Settings::nextAvailableServerName() const
{
int i = 0;
//bool found = false;
bool nameExist = false;
do {
i++;
nameExist = false;
for (const QJsonValue &server: serversArray()) {
if (server.toObject().value(config_key::description).toString() == tr("Server") + " " + QString::number(i)) {
nameExist = true;
break;
}
}
} while (nameExist);
return tr("Server") + " " + QString::number(i);
}
//void Settings::setServerCredentials(const ServerCredentials &credentials)
//{
// setServerName(credentials.hostName);
@ -104,13 +154,18 @@ bool Settings::haveAuthData() const
ServerCredentials Settings::defaultServerCredentials() const
{
const QJsonObject &s = defaultServer();
return serverCredentials(defaultServerIndex());
}
ServerCredentials Settings::serverCredentials(int index) const
{
const QJsonObject &s = server(index);
ServerCredentials credentials;
credentials.hostName = s.value(hostNameString).toString();
credentials.userName = s.value(userNameString).toString();
credentials.password = s.value(passwordString).toString();
credentials.port = s.value(portString).toInt();
credentials.hostName = s.value(config_key::hostName).toString();
credentials.userName = s.value(config_key::userName).toString();
credentials.password = s.value(config_key::password).toString();
credentials.port = s.value(config_key::port).toInt();
return credentials;
}

View file

@ -36,9 +36,10 @@ public:
// void setServerPort(int serverPort = 22) { m_settings.setValue("Server/serverPort", serverPort); }
ServerCredentials defaultServerCredentials() const;
ServerCredentials serverCredentials(int index) const;
//void setServerCredentials(const ServerCredentials &credentials);
QJsonArray serversArray() const {return QJsonDocument::fromJson(m_settings.value("Servers/serversList").toByteArray()).array(); }
QJsonArray serversArray() const { return QJsonDocument::fromJson(m_settings.value("Servers/serversList").toByteArray()).array(); }
void setServersArray(const QJsonArray &servers) { m_settings.setValue("Servers/serversList", QJsonDocument(servers).toJson()); }
// Servers section
@ -52,11 +53,15 @@ public:
void setDefaultServer(int index) { m_settings.setValue("Servers/defaultServerIndex", index); }
QJsonObject defaultServer() const { return server(defaultServerIndex()); }
void setDefaultContainer(int serverIndex, DockerContainer container );
void setDefaultContainer(int serverIndex, DockerContainer container);
DockerContainer defaultContainer(int serverIndex) const;
QString defaultContainerName(int serverIndex) const;
QJsonObject containerConfig(int serverIndex, DockerContainer container);
QJsonObject protocolConfig(int serverIndex, DockerContainer container, Protocol proto);
bool haveAuthData() const;
QString nextAvailableServerName() const;
// App settings section
bool isAutoConnect() const { return m_settings.value("Conf/autoConnect", QString()).toBool(); }
@ -90,21 +95,12 @@ public:
public:
// Json strings
static constexpr char hostNameString[] = "hostName";
static constexpr char userNameString[] = "userName";
static constexpr char passwordString[] = "password";
static constexpr char portString[] = "port";
static constexpr char descriptionString[] = "description";
static constexpr char defaultContainerString[] = "defaultContainer";
private:
QSettings m_settings;
};
#endif // SETTINGS_H

View file

@ -17,14 +17,16 @@
#include "core/errorstrings.h"
#include "configurators/openvpn_configurator.h"
#include "core/servercontroller.h"
#include "core/server_defs.h"
#include "protocols/protocols_defs.h"
#include "ui/qautostart.h"
#include "debug.h"
#include "defines.h"
#include "mainwindow.h"
#include "ui_mainwindow.h"
#include "utils.h"
#include "vpnconnection.h"
#include "ui_mainwindow.h"
#include "ui/server_widget.h"
#include "ui_server_widget.h"
@ -32,6 +34,8 @@
#include "ui/macos_util.h"
#endif
using namespace amnezia;
MainWindow::MainWindow(QWidget *parent) :
#ifdef Q_OS_WIN
CFramelessWindow(parent),
@ -45,7 +49,8 @@ MainWindow::MainWindow(QWidget *parent) :
setupTray();
setupUiConnections();
setupProtocolsPage();
setupProtocolsPageConnections();
setupNewServerPageConnections();
ui->label_error_text->clear();
installEventFilter(this);
@ -142,20 +147,20 @@ void MainWindow::goToPage(Page page, bool reset, bool slide)
{
qDebug() << "goToPage" << 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) {
updateSettings();
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()));
QJsonObject server = m_settings.server(selectedServerIndex);
QString port = server.value(config_key::port).toString();
ui->label_server_settings_server->setText(QString("%1@%2%3%4")
.arg(server.value(config_key::userName).toString())
.arg(server.value(config_key::hostName).toString())
.arg(port.isEmpty() ? "" : ":")
.arg(port));
ui->lineEdit_server_settings_description->setText(server.value(config_key::description).toString());
}
if (page == Page::ShareConnection) {
QJsonObject ssConfig = ShadowSocksVpnProtocol::genShadowSocksConfig(m_settings.defaultServerCredentials());
@ -175,12 +180,35 @@ void MainWindow::goToPage(Page page, bool reset, bool slide)
ui->label_share_ss_method->setText(ssConfig.value("method").toString());
ui->label_share_ss_password->setText(ssConfig.value("password").toString());
}
if (page == Page::ServerSettings) {
updateSettings();
if (page == Page::ServersList) {
updateServersPage();
}
if (page == Page::Start) {
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);
ui->pushButton_back_from_start->setVisible(!pagesStack.isEmpty());
}
if (page == Page::NewServer_2) {
ui->pushButton_new_server_settings_cloak->setChecked(true);
ui->pushButton_new_server_settings_cloak->setChecked(false);
ui->pushButton_new_server_settings_ss->setChecked(true);
ui->pushButton_new_server_settings_ss->setChecked(false);
ui->pushButton_new_server_settings_openvpn->setChecked(true);
ui->pushButton_new_server_settings_openvpn->setChecked(false);
ui->lineEdit_new_server_cloak_port->setText(amnezia::protocols::cloak::ckDefaultPort);
ui->lineEdit_new_server_cloak_site->setText(amnezia::protocols::cloak::ckDefaultRedirSite);
ui->lineEdit_new_server_ss_port->setText(amnezia::protocols::shadowsocks::ssDefaultPort);
ui->comboBox_new_server_ss_cipher->setCurrentText(amnezia::protocols::shadowsocks::ssDefaultCipher);
ui->lineEdit_new_server_openvpn_port->setText(amnezia::protocols::openvpn::openvpnDefaultPort);
ui->comboBox_new_server_openvpn_proto->setCurrentText(amnezia::protocols::openvpn::openvpnDefaultProto);
}
ui->pushButton_new_server_connect_key->setChecked(false);
}
@ -196,7 +224,7 @@ void MainWindow::goToPage(Page page, bool reset, bool slide)
void MainWindow::closePage()
{
Page prev = pagesStack.pop();
qDebug() << "closePage" << prev << "Set page" << pagesStack.top();
//qDebug() << "closePage" << prev << "Set page" << pagesStack.top();
ui->stackedWidget_main->slideInWidget(getPageWidget(pagesStack.top()), SlidingStackedWidget::LEFT2RIGHT);
}
@ -205,6 +233,7 @@ 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::NewServer_2): return ui->page_new_server_2;
case(Page::Vpn): return ui->page_vpn;
case(Page::GeneralSettings): return ui->page_general_settings;
case(Page::AppSettings): return ui->page_app_settings;
@ -268,8 +297,19 @@ void MainWindow::keyPressEvent(QKeyEvent *event)
QMessageBox::warning(this, APPLICATION_NAME, tr("Cannot open logs folder!"));
}
break;
#ifdef QT_DEBUG
case Qt::Key_Q:
qApp->quit();
case Qt::Key_C:
qDebug().noquote() << QJsonDocument(m_settings.serversArray()).toJson();
break;
#endif
case Qt::Key_A:
goToPage(Page::Start);
break;
case Qt::Key_S:
goToPage(Page::ServerSettings);
break;
default:
;
}
@ -302,7 +342,7 @@ void MainWindow::hideEvent(QHideEvent *event)
#endif
}
void MainWindow::onPushButtonNewServerConnectWithNewData(bool)
void MainWindow::onPushButtonNewServerConnect(bool)
{
if (ui->pushButton_new_server_connect_key->isChecked()){
if (ui->lineEdit_new_server_ip->text().isEmpty() ||
@ -324,7 +364,8 @@ void MainWindow::onPushButtonNewServerConnectWithNewData(bool)
}
qDebug() << "Start connection with new data";
qDebug() << "MainWindow::onPushButtonNewServerConnect checking new server";
ServerCredentials serverCredentials;
serverCredentials.hostName = ui->lineEdit_new_server_ip->text();
@ -352,24 +393,103 @@ void MainWindow::onPushButtonNewServerConnectWithNewData(bool)
serverCredentials.password = ui->lineEdit_new_server_password->text();
}
ui->pushButton_new_server_connect->setEnabled(false);
ui->pushButton_new_server_connect->setText(tr("Connecting..."));
ErrorCode e = ErrorCode::NoError;
//QString output = ServerController::checkSshConnection(serverCredentials, &e);
QString output;
bool ok = true;
if (e) {
ui->label_new_server_wait_info->show();
ui->label_new_server_wait_info->setText(errorString(e));
ok = false;
}
else {
if (output.contains("Please login as the user")) {
output.replace("\n", "");
ui->label_new_server_wait_info->show();
ui->label_new_server_wait_info->setText(output);
ok = false;
}
}
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);
ui->pushButton_new_server_connect->setEnabled(true);
ui->pushButton_new_server_connect->setText(tr("Connect"));
installCredentials = serverCredentials;
if (ok) goToPage(Page::NewServer_2);
}
void MainWindow::onPushButtonNewServerConnectConfigure(bool)
{
QJsonObject cloakConfig {
{ config_key::port, ui->lineEdit_new_server_cloak_port->text() },
{ config_key::container, amnezia::server::getContainerName(DockerContainer::OpenVpnOverCloak) },
{ config_key::cloak, QJsonObject {
{ config_key::site, ui->lineEdit_new_server_cloak_site->text() }}
}
};
QJsonObject ssConfig {
{ config_key::port, ui->lineEdit_new_server_ss_port->text() },
{ config_key::container, amnezia::server::getContainerName(DockerContainer::ShadowSocksOverOpenVpn) },
{ config_key::shadowsocks, QJsonObject {
{ config_key::cipher, ui->comboBox_new_server_ss_cipher->currentText() }}
}
};
QJsonObject openVpnConfig {
{ config_key::port, ui->lineEdit_new_server_openvpn_port->text() },
{ config_key::container, amnezia::server::getContainerName(DockerContainer::OpenVpn) },
{ config_key::openvpn, QJsonObject {
{ config_key::transport_protocol, ui->comboBox_new_server_openvpn_proto->currentText() }}
}
};
QJsonArray containerConfigs;
QList<DockerContainer> containers;
if (ui->checkBox_new_server_cloak->isChecked()) {
containerConfigs.append(cloakConfig);
containers.append(DockerContainer::OpenVpnOverCloak);
}
if (ui->checkBox_new_server_ss->isChecked()) {
containerConfigs.append(ssConfig);
containers.append(DockerContainer::ShadowSocksOverOpenVpn);
}
if (ui->checkBox_new_server_openvpn->isChecked()) {
containerConfigs.append(openVpnConfig);
containers.append(DockerContainer::ShadowSocksOverOpenVpn);
}
bool ok = true;
// bool ok = installServer(installCredentials, containers, configs,
// ui->page_new_server,
// ui->progressBar_new_server_connection,
// ui->pushButton_new_server_connect,
// ui->label_new_server_wait_info);
if (ok) {
//m_settings.setServerCredentials(serverCredentials);
QJsonObject server;
server.insert(config_key::hostName, installCredentials.hostName);
server.insert(config_key::userName, installCredentials.userName);
server.insert(config_key::password, installCredentials.password);
server.insert(config_key::port, installCredentials.port);
server.insert(config_key::description, m_settings.nextAvailableServerName());
server.insert(config_key::containers, containerConfigs);
m_settings.addServer(server);
updateSettings();
goToPage(Page::Vpn);
qApp->processEvents();
onConnect();
//onConnect();
}
}
void MainWindow::onPushButtonNewServerConnectWithExistingCode(bool)
void MainWindow::onPushButtonNewServerImport(bool)
{
QString s = ui->lineEdit_start_existing_code->text();
s.replace("vpn://", "");
@ -398,7 +518,8 @@ void MainWindow::onPushButtonNewServerConnectWithExistingCode(bool)
}
bool MainWindow::installServer(ServerCredentials credentials,
QWidget *page, QProgressBar *progress, QPushButton *button, QLabel *info)
QList<DockerContainer> containers, QJsonArray configs,
QWidget *page, QProgressBar *progress, QPushButton *button, QLabel *info)
{
page->setEnabled(false);
button->setVisible(false);
@ -406,95 +527,112 @@ bool MainWindow::installServer(ServerCredentials credentials,
info->setVisible(true);
info->setText(tr("Please wait, configuring process may take up to 5 minutes"));
QTimer timer;
connect(&timer, &QTimer::timeout, [progress](){
progress->setValue(progress->value() + 1);
});
progress->setValue(0);
timer.start(1000);
ErrorCode e = ServerController::setupServer(credentials, Protocol::Any);
qDebug() << "Setup server finished with code" << e;
if (e) {
page->setEnabled(true);
button->setVisible(true);
info->setVisible(false);
QMessageBox::warning(this, APPLICATION_NAME,
tr("Error occurred while configuring server.") + "\n" +
errorString(e));
return false;
}
// just ui progressbar tweak
timer.stop();
int remaining_val = progress->maximum() - progress->value();
if (remaining_val > 0) {
QTimer timer1;
QEventLoop loop1;
connect(&timer1, &QTimer::timeout, [&](){
for (int i = 0; i < containers.size(); ++i) {
QTimer timer;
connect(&timer, &QTimer::timeout, [progress](){
progress->setValue(progress->value() + 1);
if (progress->value() >= progress->maximum()) {
loop1.quit();
}
});
timer1.start(5);
loop1.exec();
progress->setValue(0);
timer.start(1000);
progress->setTextVisible(true);
progress->setFormat(QString("%1%2%3").arg(i+1).arg(tr("of")).arg(containers.size()));
ErrorCode e = ServerController::setupContainer(credentials, containers.at(i), configs.at(i).toObject());
qDebug() << "Setup server finished with code" << e;
ServerController::disconnectFromHost(credentials);
if (e) {
page->setEnabled(true);
button->setVisible(true);
info->setVisible(false);
QMessageBox::warning(this, APPLICATION_NAME,
tr("Error occurred while configuring server.") + "\n" +
errorString(e));
return false;
}
// just ui progressbar tweak
timer.stop();
int remaining_val = progress->maximum() - progress->value();
if (remaining_val > 0) {
QTimer timer1;
QEventLoop loop1;
connect(&timer1, &QTimer::timeout, [&](){
progress->setValue(progress->value() + 1);
if (progress->value() >= progress->maximum()) {
loop1.quit();
}
});
timer1.start(5);
loop1.exec();
}
}
button->show();
page->setEnabled(true);
info->setText(tr("Amnezia server installed"));
// button->show();
// page->setEnabled(true);
// info->setText(tr("Amnezia server installed"));
return true;
}
void MainWindow::onPushButtonReinstallServer(bool)
{
onDisconnect();
installServer(m_settings.defaultServerCredentials(),
ui->page_server_settings,
ui->progressBar_server_settings_reinstall,
ui->pushButton_server_settings_reinstall,
ui->label_server_settings_wait_info);
// onDisconnect();
// installServer(m_settings.defaultServerCredentials(),
// 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();
ui->page_server_settings->setEnabled(false);
ui->pushButton_server_settings_clear->setText(tr("Uninstalling Amnezia software..."));
ErrorCode e = ServerController::removeServer(m_settings.defaultServerCredentials(), Protocol::Any);
if (m_settings.defaultServerIndex() == selectedServerIndex) {
onDisconnect();
}
ErrorCode e = ServerController::removeContainer(m_settings.serverCredentials(selectedServerIndex), DockerContainer::None);
ServerController::disconnectFromHost(m_settings.serverCredentials(selectedServerIndex));
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"));
}
ui->page_server_settings->setEnabled(true);
ui->pushButton_server_settings_clear->setText(tr("Clear server from Amnezia software"));
}
void MainWindow::onPushButtonForgetServer(bool)
{
onDisconnect();
if (m_settings.defaultServerIndex() == selectedServerIndex) {
onDisconnect();
}
m_settings.removeServer(selectedServerIndex);
// m_settings.setUserName("");
// m_settings.setPassword("");
// m_settings.setServerName("");
// m_settings.setServerPort();
goToPage(Page::Start);
closePage();
updateServersPage();
}
void MainWindow::onBytesChanged(quint64 receivedData, quint64 sentData)
@ -638,10 +776,10 @@ void MainWindow::setupUiConnections()
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_new_server_connect, SIGNAL(clicked(bool)), this, SLOT(onPushButtonNewServerConnectWithExistingCode(bool)));
connect(ui->pushButton_new_server_connect, SIGNAL(clicked(bool)), this, SLOT(onPushButtonNewServerConnect(bool)));
connect(ui->pushButton_new_server_connect_configure, SIGNAL(clicked(bool)), this, SLOT(onPushButtonNewServerConnectConfigure(bool)));
connect(ui->pushButton_new_server_import, SIGNAL(clicked(bool)), this, SLOT(onPushButtonNewServerImport(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)));
@ -651,12 +789,15 @@ void MainWindow::setupUiConnections()
connect(ui->pushButton_settings, &QPushButton::clicked, this, [this](){ goToPage(Page::GeneralSettings); });
connect(ui->pushButton_app_settings, &QPushButton::clicked, this, [this](){ goToPage(Page::AppSettings); });
connect(ui->pushButton_network_settings, &QPushButton::clicked, this, [this](){ goToPage(Page::NetworkSettings); });
connect(ui->pushButton_server_settings, &QPushButton::clicked, this, [this](){ goToPage(Page::ServerSettings); });
connect(ui->pushButton_server_settings, &QPushButton::clicked, this, [this](){
selectedServerIndex = m_settings.defaultServerIndex();
goToPage(Page::ServerSettings);
});
connect(ui->pushButton_server_settings_protocols, &QPushButton::clicked, this, [this](){ goToPage(Page::ServerVpnProtocols); });
connect(ui->pushButton_servers_list, &QPushButton::clicked, this, [this](){ goToPage(Page::ServersList); });
connect(ui->pushButton_share_connection, &QPushButton::clicked, this, [this](){
goToPage(Page::ShareConnection);
updateShareCode();
updateShareCodePage();
});
connect(ui->pushButton_copy_sharing_code, &QPushButton::clicked, this, [this](){
@ -668,25 +809,11 @@ void MainWindow::setupUiConnections()
});
});
// 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_app_settings, &QPushButton::clicked, this, [this](){ goToPage(Page::GeneralSettings); });
// connect(ui->pushButton_back_from_network_settings, &QPushButton::clicked, this, [this](){ goToPage(Page::GeneralSettings); });
// connect(ui->pushButton_back_from_server_settings, &QPushButton::clicked, this, [this](){ goToPage(Page::GeneralSettings); });
// connect(ui->pushButton_back_from_servers, &QPushButton::clicked, this, [this](){ goToPage(Page::GeneralSettings); });
// connect(ui->pushButton_back_from_share, &QPushButton::clicked, this, [this](){ goToPage(Page::GeneralSettings); });
// connect(ui->pushButton_back_from_server_vpn_protocols, &QPushButton::clicked, this, [this](){ goToPage(Page::ServerSettings); });
// connect(ui->pushButton_back_from_server_vpn_protocols, &QPushButton::clicked, this, [this](){ goToPage(Page::ServerSettings); });
// connect(ui->pushButton_back_from_server_vpn_protocols, &QPushButton::clicked, this, [this](){ goToPage(Page::ServerSettings); });
// connect(ui->pushButton_back_from_server_vpn_protocols, &QPushButton::clicked, this, [this](){ goToPage(Page::ServerSettings); });
connect(ui->pushButton_back_from_sites, &QPushButton::clicked, this, [this](){ closePage(); });
connect(ui->pushButton_back_from_settings, &QPushButton::clicked, this, [this](){ closePage(); });
connect(ui->pushButton_back_from_start, &QPushButton::clicked, this, [this](){ closePage(); });
connect(ui->pushButton_back_from_new_server, &QPushButton::clicked, this, [this](){ closePage(); });
connect(ui->pushButton_back_from_new_server_2, &QPushButton::clicked, this, [this](){ closePage(); });
connect(ui->pushButton_back_from_app_settings, &QPushButton::clicked, this, [this](){ closePage(); });
connect(ui->pushButton_back_from_network_settings, &QPushButton::clicked, this, [this](){ closePage(); });
connect(ui->pushButton_back_from_server_settings, &QPushButton::clicked, this, [this](){ closePage(); });
@ -738,23 +865,33 @@ void MainWindow::setupUiConnections()
}
});
connect(ui->pushButton_new_server_connect_key, &QPushButton::toggled, this, [this](bool checked){
ui->label_new_server_password->setText(checked ? tr("Private key") : tr("Password"));
ui->pushButton_new_server_connect_key->setText(checked ? tr("Connect using SSH password") : tr("Connect using SSH key"));
ui->lineEdit_new_server_password->setVisible(!checked);
ui->textEdit_new_server_ssh_key->setVisible(checked);
});
connect(ui->pushButton_check_for_updates, &QPushButton::clicked, this, [this](){
QDesktopServices::openUrl(QUrl("https://github.com/amnezia-vpn/desktop-client/releases"));
});
connect(ui->pushButton_servers_add_new, &QPushButton::clicked, this, [this](){ goToPage(Page::Start); });
connect(ui->lineEdit_server_settings_description, &QLineEdit::editingFinished, this, [this](){
const QString &newText = ui->lineEdit_server_settings_description->text();
QJsonObject server = m_settings.server(selectedServerIndex);
server.insert(config_key::description, newText);
m_settings.editServer(selectedServerIndex, server);
updateServersPage();
});
connect(ui->lineEdit_server_settings_description, &QLineEdit::returnPressed, this, [this](){
ui->lineEdit_server_settings_description->clearFocus();
});
}
void MainWindow::setupProtocolsPage()
void MainWindow::setupProtocolsPageConnections()
{
QJsonObject openvpnConfig;
connect(ui->pushButton_proto_openvpn_cont_openvpn_config, &QPushButton::clicked, this, [this](){
//updateOpenVpnPage(m_settings.server(selectedServerIndex).value());
goToPage(Page::OpenVpnSettings);
});
connect(ui->pushButton_proto_ss_openvpn_cont_openvpn_config, &QPushButton::clicked, this, [this](){
@ -781,6 +918,51 @@ void MainWindow::setupProtocolsPage()
}
void MainWindow::setupNewServerPageConnections()
{
connect(ui->pushButton_connect, SIGNAL(clicked(bool)), this, SLOT(onPushButtonConnectClicked(bool)));
connect(ui->pushButton_start_switch_page, &QPushButton::toggled, this, [this](bool toggled){
if (toggled){
ui->stackedWidget_start->setCurrentWidget(ui->page_start_new_server);
ui->pushButton_start_switch_page->setText(tr("Import connection"));
}
else {
ui->stackedWidget_start->setCurrentWidget(ui->page_start_import);
ui->pushButton_start_switch_page->setText(tr("Set up your own server"));
}
//goToPage(Page::NewServer);
});
connect(ui->pushButton_new_server_connect_key, &QPushButton::toggled, this, [this](bool checked){
ui->label_new_server_password->setText(checked ? tr("Private key") : tr("Password"));
ui->pushButton_new_server_connect_key->setText(checked ? tr("Connect using SSH password") : tr("Connect using SSH key"));
ui->lineEdit_new_server_password->setVisible(!checked);
ui->textEdit_new_server_ssh_key->setVisible(checked);
});
connect(ui->pushButton_new_server_settings_cloak, &QPushButton::toggled, this, [this](bool toggle){
ui->frame_new_server_settings_cloak->setMaximumHeight(toggle * 200);
if (toggle)
ui->frame_new_server_settings_parent_cloak->layout()->addWidget(ui->frame_new_server_settings_cloak);
else
ui->frame_new_server_settings_parent_cloak->layout()->removeWidget(ui->frame_new_server_settings_cloak);
});
connect(ui->pushButton_new_server_settings_ss, &QPushButton::toggled, this, [this](bool toggle){
ui->frame_new_server_settings_ss->setMaximumHeight(toggle * 200);
if (toggle)
ui->frame_new_server_settings_parent_ss->layout()->addWidget(ui->frame_new_server_settings_ss);
else
ui->frame_new_server_settings_parent_ss->layout()->removeWidget(ui->frame_new_server_settings_ss);
});
connect(ui->pushButton_new_server_settings_openvpn, &QPushButton::toggled, this, [this](bool toggle){
ui->frame_new_server_settings_openvpn->setMaximumHeight(toggle * 200);
if (toggle)
ui->frame_new_server_settings_parent_openvpn->layout()->addWidget(ui->frame_new_server_settings_openvpn);
else
ui->frame_new_server_settings_parent_openvpn->layout()->removeWidget(ui->frame_new_server_settings_ss);
});
}
void MainWindow::setTrayState(VpnProtocol::ConnectionState state)
{
QString resourcesPath = ":/images/tray/%1";
@ -949,19 +1131,11 @@ void MainWindow::updateSettings()
ui->lineEdit_network_settings_dns1->setText(m_settings.primaryDns());
ui->lineEdit_network_settings_dns2->setText(m_settings.secondaryDns());
ui->listWidget_sites->clear();
for(const QString &site : m_settings.customSites()) {
makeSitesListItem(ui->listWidget_sites, site);
}
ui->listWidget_servers->clear();
const QJsonArray &servers = m_settings.serversArray();
int defaultServer = m_settings.defaultServerIndex();
for(int i = 0; i < servers.size(); i++) {
makeServersListItem(ui->listWidget_servers, servers.at(i).toObject(), i == defaultServer, i);
}
QJsonObject selectedServer = m_settings.server(selectedServerIndex);
QString selectedContainerName = m_settings.defaultContainerName(selectedServerIndex);
@ -974,7 +1148,20 @@ void MainWindow::updateSettings()
ui->pushButton_proto_openvpn_cont_default->setChecked(m_settings.defaultContainer(selectedServerIndex) == DockerContainer::OpenVpn);
}
void MainWindow::updateShareCode()
void MainWindow::updateServersPage()
{
ui->listWidget_servers->clear();
const QJsonArray &servers = m_settings.serversArray();
int defaultServer = m_settings.defaultServerIndex();
ui->listWidget_servers->setUpdatesEnabled(false);
for(int i = 0; i < servers.size(); i++) {
makeServersListItem(ui->listWidget_servers, servers.at(i).toObject(), i == defaultServer, i);
}
ui->listWidget_servers->setUpdatesEnabled(true);
}
void MainWindow::updateShareCodePage()
{
// QJsonObject o;
// o.insert("h", m_settings.serverName());
@ -988,6 +1175,24 @@ void MainWindow::updateShareCode()
//qDebug() << "Share code" << QJsonDocument(o).toJson();
}
void MainWindow::updateOpenVpnPage(const QJsonObject &openvpnConfig)
{
ui->lineEdit_proto_openvpn_subnet->setText(nonEmpty(openvpnConfig.value(config_key::subnet_address).toString(),
protocols::vpnDefaultSubnetAddress));
QString trasnsport = nonEmpty(openvpnConfig.value(config_key::transport_protocol).toString(),
protocols::openvpn::openvpnDefaultProto);
ui->radioButton_proto_openvpn_udp->setChecked(trasnsport == protocols::openvpn::openvpnDefaultProto);
ui->radioButton_proto_openvpn_tcp->setChecked(trasnsport != protocols::openvpn::openvpnDefaultProto);
ui->comboBox_proto_openvpn_cipher->setCurrentText(nonEmpty(openvpnConfig.value(config_key::cipher).toString(),
protocols::openvpn::openvpnDefaultCipher));
ui->comboBox_proto_openvpn_cipher->setCurrentText(nonEmpty(openvpnConfig.value(config_key::hash).toString(),
protocols::openvpn::openvpnDefaultHash));
}
void MainWindow::makeSitesListItem(QListWidget *listWidget, const QString &address)
{
QSize size(310, 25);
@ -1021,11 +1226,13 @@ void MainWindow::makeServersListItem(QListWidget *listWidget, const QJsonObject
{
QSize size(310, 70);
ServerWidget* widget = new ServerWidget(server, isDefault);
widget->resize(size);
connect(widget->ui->pushButton_default, &QPushButton::clicked, this, [this, index](){
m_settings.setDefaultServer(index);
updateSettings();
updateServersPage();
});
connect(widget->ui->pushButton_share, &QPushButton::clicked, this, [this, index](){

View file

@ -40,7 +40,7 @@ public:
explicit MainWindow(QWidget *parent = nullptr);
~MainWindow();
enum Page {Start, NewServer, Vpn, GeneralSettings, AppSettings, NetworkSettings,
enum Page {Start, NewServer, NewServer_2, Vpn, GeneralSettings, AppSettings, NetworkSettings,
ServerSettings, ServerVpnProtocols, ServersList, ShareConnection, Sites,
OpenVpnSettings, ShadowSocksSettings, CloakSettings};
Q_ENUM(Page)
@ -51,8 +51,9 @@ private slots:
void onVpnProtocolError(amnezia::ErrorCode errorCode);
void onPushButtonConnectClicked(bool checked);
void onPushButtonNewServerConnectWithNewData(bool);
void onPushButtonNewServerConnectWithExistingCode(bool);
void onPushButtonNewServerConnect(bool);
void onPushButtonNewServerConnectConfigure(bool);
void onPushButtonNewServerImport(bool);
void onPushButtonReinstallServer(bool);
void onPushButtonClearServer(bool);
@ -77,21 +78,26 @@ private:
QWidget *getPageWidget(Page page);
Page currentPage();
bool installServer(ServerCredentials credentials, QWidget *page, QProgressBar *progress, QPushButton *button, QLabel *info);
bool installServer(ServerCredentials credentials, QList<DockerContainer> containers, QJsonArray configs,
QWidget *page, QProgressBar *progress, QPushButton *button, QLabel *info);
void setupTray();
void setTrayIcon(const QString &iconPath);
void setupUiConnections();
void setupProtocolsPage();
void setupProtocolsPageConnections();
void setupNewServerPageConnections();
void updateSettings();
void updateServersPage();
void updateShareCodePage();
void updateOpenVpnPage(const QJsonObject &openvpnConfig);
void updateShareCode();
void makeSitesListItem(QListWidget* listWidget, const QString &address);
void makeServersListItem(QListWidget* listWidget, const QJsonObject &server, bool isDefault, int index);
void updateQRCodeImage(const QString &text, QLabel *label);
private:
Ui::MainWindow *ui;
VpnConnection* m_vpnConnection;
@ -123,6 +129,7 @@ private:
QStack<Page> pagesStack;
int selectedServerIndex = -1; // server index to use when proto settings page opened
ServerCredentials installCredentials; // used to save cred between pages new_server and new_server_2
};
#endif // MAINWINDOW_H

File diff suppressed because it is too large Load diff

View file

@ -2,14 +2,15 @@
#include "ui_server_widget.h"
#include "settings.h"
#include "protocols/protocols_defs.h"
ServerWidget::ServerWidget(const QJsonObject &server, bool isDefault, QWidget *parent) :
QWidget(parent),
ui(new Ui::ServerWidget)
{
ui->setupUi(this);
QString desc = server.value(Settings::descriptionString).toString();
QString address = server.value(Settings::hostNameString).toString();
QString desc = server.value(config_key::description).toString();
QString address = server.value(config_key::hostName).toString();
ui->label_address->setText(address);

View file

@ -185,6 +185,8 @@ ErrorCode VpnConnection::connectToVpn(const ServerCredentials &credentials, Prot
connect(m_vpnProtocol.data(), SIGNAL(connectionStateChanged(VpnProtocol::ConnectionState)), this, SLOT(onConnectionStateChanged(VpnProtocol::ConnectionState)));
connect(m_vpnProtocol.data(), SIGNAL(bytesChanged(quint64, quint64)), this, SLOT(onBytesChanged(quint64, quint64)));
ServerController::disconnectFromHost(credentials);
return m_vpnProtocol.data()->start();
}