mirror of
https://github.com/amnezia-vpn/amnezia-client.git
synced 2026-07-03 14:07:39 +02:00
Compare commits
12 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| d4c0e519d9 | |||
| 4ba964db47 | |||
| 45e5ec76dd | |||
| df27003998 | |||
| 9002568474 | |||
| 5c5411261a | |||
| acf878c8dd | |||
| 491a09b175 | |||
| 51f7e6811e | |||
| eee6b8b10f | |||
| dc4a1c6eca | |||
| 02810ff844 |
@@ -38,6 +38,7 @@ QString CloakConfigurator::genCloakConfig(const ServerCredentials &credentials,
|
||||
// transfer params to protocol runner
|
||||
config.insert(config_key::transport_proto, "$OPENVPN_TRANSPORT_PROTO");
|
||||
config.insert(config_key::remote, credentials.hostName);
|
||||
config.insert(config_key::port, "$CLOAK_SERVER_PORT");
|
||||
|
||||
QString textCfg = ServerController::replaceVars(QJsonDocument(config).toJson(),
|
||||
ServerController::genVarsForScript(credentials, container, containerConfig));
|
||||
|
||||
@@ -203,7 +203,14 @@ QString OpenVpnConfigurator::genOpenVpnConfig(const ServerCredentials &credentia
|
||||
config.replace("$OPENVPN_CA_CERT", connData.caCert);
|
||||
config.replace("$OPENVPN_CLIENT_CERT", connData.clientCert);
|
||||
config.replace("$OPENVPN_PRIV_KEY", connData.privKey);
|
||||
config.replace("$OPENVPN_TA_KEY", connData.taKey);
|
||||
|
||||
if (config.contains("$OPENVPN_TA_KEY")) {
|
||||
config.replace("$OPENVPN_TA_KEY", connData.taKey);
|
||||
}
|
||||
else {
|
||||
config.replace("<tls-auth>", "");
|
||||
config.replace("</tls-auth>", "");
|
||||
}
|
||||
|
||||
#ifdef Q_OS_MAC
|
||||
config.replace("block-outside-dns", "");
|
||||
@@ -222,6 +229,22 @@ QString OpenVpnConfigurator::processConfigWithLocalSettings(QString config)
|
||||
if (m_settings().customRouting()) {
|
||||
config.replace("redirect-gateway def1 bypass-dhcp", "");
|
||||
}
|
||||
else {
|
||||
if(!config.contains("redirect-gateway def1 bypass-dhcp")) {
|
||||
config.append("redirect-gateway def1 bypass-dhcp\n");
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef Q_OS_MAC
|
||||
config.replace("block-outside-dns", "");
|
||||
QString dnsConf = QString(
|
||||
"\nscript-security 2\n"
|
||||
"up %1/update-resolv-conf.sh\n"
|
||||
"down %1/update-resolv-conf.sh\n").
|
||||
arg(qApp->applicationDirPath());
|
||||
|
||||
config.append(dnsConf);
|
||||
#endif
|
||||
|
||||
return config;
|
||||
}
|
||||
|
||||
@@ -346,12 +346,8 @@ ErrorCode ServerController::setupContainer(const ServerCredentials &credentials,
|
||||
qDebug().noquote() << QJsonDocument(config).toJson();
|
||||
ErrorCode e = ErrorCode::NoError;
|
||||
|
||||
// e = runScript(sshParams(credentials),
|
||||
// replaceVars(amnezia::scriptData(SharedScriptType::install_docker),
|
||||
// genVarsForScript(credentials)));
|
||||
|
||||
// if (e) return e;
|
||||
|
||||
e = installDockerWorker(credentials, container);
|
||||
if (e) return e;
|
||||
|
||||
e = prepareHostWorker(credentials, container, config);
|
||||
if (e) return e;
|
||||
@@ -368,21 +364,6 @@ ErrorCode ServerController::setupContainer(const ServerCredentials &credentials,
|
||||
if (e) return e;
|
||||
|
||||
return startupContainerWorker(credentials, container, config);
|
||||
|
||||
|
||||
|
||||
|
||||
// if (container == DockerContainer::OpenVpn) {
|
||||
// return setupOpenVpnServer(credentials, config);
|
||||
// }
|
||||
// else if (container == DockerContainer::OpenVpnOverShadowSocks) {
|
||||
// return setupShadowSocksServer(credentials, config);
|
||||
// }
|
||||
// else if (container == DockerContainer::OpenVpnOverCloak) {
|
||||
// return setupOpenVpnOverCloakServer(credentials, config);
|
||||
// }
|
||||
|
||||
// return ErrorCode::NoError;
|
||||
}
|
||||
|
||||
ErrorCode ServerController::updateContainer(const ServerCredentials &credentials, DockerContainer container,
|
||||
@@ -438,33 +419,6 @@ bool ServerController::isReinstallContainerRequred(DockerContainer container, co
|
||||
return false;
|
||||
}
|
||||
|
||||
//ErrorCode ServerController::setupOpenVpnServer(const ServerCredentials &credentials, const QJsonObject &config)
|
||||
//{
|
||||
// return ErrorCode::NotImplementedError;
|
||||
//}
|
||||
|
||||
//ErrorCode ServerController::setupOpenVpnOverCloakServer(const ServerCredentials &credentials, const QJsonObject &config)
|
||||
//{
|
||||
// ErrorCode e = ErrorCode::NoError;
|
||||
// DockerContainer container = DockerContainer::OpenVpnOverCloak;
|
||||
|
||||
// e = prepareHostWorker(credentials, container, config);
|
||||
// if (e) return e;
|
||||
|
||||
// removeContainer(credentials, container);
|
||||
|
||||
// e = buildContainerWorker(credentials, container, config);
|
||||
// if (e) return e;
|
||||
|
||||
// e = runContainerWorker(credentials, container, config);
|
||||
// if (e) return e;
|
||||
|
||||
// e = configureContainerWorker(credentials, container, config);
|
||||
// if (e) return e;
|
||||
|
||||
// return startupContainerWorker(credentials, container, config);
|
||||
//}
|
||||
|
||||
ErrorCode ServerController::installDockerWorker(const ServerCredentials &credentials, DockerContainer container)
|
||||
{
|
||||
QString stdOut;
|
||||
@@ -515,9 +469,23 @@ ErrorCode ServerController::buildContainerWorker(const ServerCredentials &creden
|
||||
|
||||
ErrorCode ServerController::runContainerWorker(const ServerCredentials &credentials, DockerContainer container, const QJsonObject &config)
|
||||
{
|
||||
return runScript(sshParams(credentials),
|
||||
QString stdOut;
|
||||
auto cbReadStdOut = [&](const QString &data, QSharedPointer<QSsh::SshRemoteProcess> proc) {
|
||||
stdOut += data + "\n";
|
||||
};
|
||||
auto cbReadStdErr = [&](const QString &data, QSharedPointer<QSsh::SshRemoteProcess> proc) {
|
||||
stdOut += data + "\n";
|
||||
};
|
||||
|
||||
ErrorCode e = runScript(sshParams(credentials),
|
||||
replaceVars(amnezia::scriptData(ProtocolScriptType::run_container, container),
|
||||
genVarsForScript(credentials, container, config)));
|
||||
genVarsForScript(credentials, container, config)),
|
||||
cbReadStdOut, cbReadStdErr);
|
||||
|
||||
if (stdOut.contains("address already in use")) return ErrorCode::ServerPortAlreadyAllocatedError;
|
||||
if (stdOut.contains("is already in use by container")) return ErrorCode::ServerPortAlreadyAllocatedError;
|
||||
|
||||
return e;
|
||||
}
|
||||
|
||||
ErrorCode ServerController::configureContainerWorker(const ServerCredentials &credentials, DockerContainer container, const QJsonObject &config)
|
||||
@@ -540,58 +508,7 @@ ErrorCode ServerController::startupContainerWorker(const ServerCredentials &cred
|
||||
genVarsForScript(credentials, container, config)));
|
||||
}
|
||||
|
||||
//ErrorCode ServerController::setupShadowSocksServer(const ServerCredentials &credentials, const QJsonObject &config)
|
||||
//{
|
||||
// return ErrorCode::NotImplementedError;
|
||||
//// // Setup openvpn part
|
||||
//// QString scriptData;
|
||||
//// QString scriptFileName = ":/server_scripts/setup_shadowsocks_server.sh";
|
||||
//// QFile file(scriptFileName);
|
||||
//// if (! file.open(QIODevice::ReadOnly)) return ErrorCode::InternalError;
|
||||
|
||||
//// scriptData = file.readAll();
|
||||
//// if (scriptData.isEmpty()) return ErrorCode::InternalError;
|
||||
|
||||
//// QString stdOut;
|
||||
//// auto cbReadStdOut = [&](const QString &data, QSharedPointer<QSsh::SshRemoteProcess> proc) {
|
||||
//// stdOut += data + "\n";
|
||||
|
||||
//// if (data.contains("Automatically restart Docker daemon?")) {
|
||||
//// proc->write("yes\n");
|
||||
//// }
|
||||
//// };
|
||||
//// auto cbReadStdErr = [&](const QString &data, QSharedPointer<QSsh::SshRemoteProcess> proc) {
|
||||
//// stdOut += data + "\n";
|
||||
//// };
|
||||
|
||||
//// ErrorCode e = runScript(genVarsForScript(credentials, DockerContainer::ShadowSocks), sshParams(credentials), scriptData, cbReadStdOut, cbReadStdErr);
|
||||
//// if (e) return e;
|
||||
|
||||
//// // Create ss config
|
||||
//// QJsonObject ssConfig;
|
||||
//// ssConfig.insert("server", "0.0.0.0");
|
||||
//// ssConfig.insert("server_port", amnezia::protocols::shadowsocks::ssRemotePort());
|
||||
//// ssConfig.insert("local_port", amnezia::protocols::shadowsocks::ssContainerPort());
|
||||
//// ssConfig.insert("password", QString(QCryptographicHash::hash(credentials.password.toUtf8(), QCryptographicHash::Sha256).toHex()));
|
||||
//// ssConfig.insert("timeout", 60);
|
||||
//// ssConfig.insert("method", amnezia::protocols::shadowsocks::ssEncryption());
|
||||
//// QString configData = QJsonDocument(ssConfig).toJson();
|
||||
//// QString sSConfigPath = "/opt/amneziavpn_data/ssConfig.json";
|
||||
|
||||
//// configData.replace("\"", "\\\"");
|
||||
//// //qDebug().noquote() << configData;
|
||||
|
||||
//// uploadTextFileToContainer(DockerContainer::ShadowSocks, credentials, configData, sSConfigPath);
|
||||
|
||||
//// // Start ss
|
||||
//// QString script = QString("sudo docker exec -d %1 sh -c \"ss-server -c %2\"").
|
||||
//// arg(amnezia::containerToString(DockerContainer::ShadowSocks)).arg(sSConfigPath);
|
||||
|
||||
//// e = runScript(genVarsForScript(credentials, DockerContainer::ShadowSocks), sshParams(credentials), script);
|
||||
// // return e;
|
||||
//}
|
||||
|
||||
ServerController::Vars ServerController::genVarsForScript(const ServerCredentials &credentials, DockerContainer container, const QJsonObject &config)
|
||||
ServerController::Vars ServerController:: genVarsForScript(const ServerCredentials &credentials, DockerContainer container, const QJsonObject &config)
|
||||
{
|
||||
const QJsonObject &openvpnConfig = config.value(config_key::openvpn).toObject();
|
||||
const QJsonObject &cloakConfig = config.value(config_key::cloak).toObject();
|
||||
@@ -612,9 +529,17 @@ ServerController::Vars ServerController::genVarsForScript(const ServerCredential
|
||||
|
||||
bool isNcpDisabled = openvpnConfig.value(config_key::ncp_disable).toBool(amnezia::protocols::openvpn::defaultNcpDisable);
|
||||
vars.append({{"$OPENVPN_NCP_DISABLE", isNcpDisabled ? protocols::openvpn::ncpDisableString : "" }});
|
||||
|
||||
vars.append({{"$OPENVPN_CIPHER", openvpnConfig.value(config_key::cipher).toString(amnezia::protocols::openvpn::defaultCipher) }});
|
||||
vars.append({{"$OPENVPN_HASH", openvpnConfig.value(config_key::hash).toString(amnezia::protocols::openvpn::defaultHash) }});
|
||||
|
||||
bool isTlsAuth = openvpnConfig.value(config_key::tls_auth).toBool(amnezia::protocols::openvpn::defaultTlsAuth);
|
||||
vars.append({{"$OPENVPN_TLS_AUTH", isTlsAuth ? protocols::openvpn::tlsAuthString : "" }});
|
||||
if (!isTlsAuth) {
|
||||
// erase $OPENVPN_TA_KEY, so it will not set in OpenVpnConfigurator::genOpenVpnConfig
|
||||
vars.append({{"$OPENVPN_TA_KEY", "" }});
|
||||
}
|
||||
|
||||
// ShadowSocks vars
|
||||
vars.append({{"$SHADOWSOCKS_SERVER_PORT", ssConfig.value(config_key::port).toString(amnezia::protocols::shadowsocks::defaultPort) }});
|
||||
vars.append({{"$SHADOWSOCKS_LOCAL_PORT", ssConfig.value(config_key::local_port).toString(amnezia::protocols::shadowsocks::defaultLocalProxyPort) }});
|
||||
@@ -624,7 +549,7 @@ ServerController::Vars ServerController::genVarsForScript(const ServerCredential
|
||||
vars.append({{"$DOCKERFILE_FOLDER", "/opt/amnezia/" + amnezia::containerToString(container)}});
|
||||
|
||||
// Cloak vars
|
||||
vars.append({{"$CLOAK_SERVER_PORT", config.value(config_key::port).toString(protocols::cloak::defaultPort) }});
|
||||
vars.append({{"$CLOAK_SERVER_PORT", cloakConfig.value(config_key::port).toString(protocols::cloak::defaultPort) }});
|
||||
vars.append({{"$FAKE_WEB_SITE_ADDRESS", cloakConfig.value(config_key::site).toString(protocols::cloak::defaultRedirSite) }});
|
||||
|
||||
QString serverIp = Utils::getIPAddress(credentials.hostName);
|
||||
@@ -730,5 +655,6 @@ QString ServerController::replaceVars(const QString &script, const Vars &vars)
|
||||
//qDebug() << "Replacing" << var.first << var.second;
|
||||
s.replace(var.first, var.second);
|
||||
}
|
||||
//qDebug().noquote() << script;
|
||||
return s;
|
||||
}
|
||||
|
||||
@@ -58,11 +58,6 @@ private:
|
||||
static QSsh::SshConnection *connectToHost(const QSsh::SshConnectionParameters &sshParams);
|
||||
|
||||
static ErrorCode installDockerWorker(const ServerCredentials &credentials, DockerContainer container);
|
||||
|
||||
//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());
|
||||
|
||||
static ErrorCode prepareHostWorker(const ServerCredentials &credentials, DockerContainer container, const QJsonObject &config = QJsonObject());
|
||||
static ErrorCode buildContainerWorker(const ServerCredentials &credentials, DockerContainer container, const QJsonObject &config = QJsonObject());
|
||||
static ErrorCode runContainerWorker(const ServerCredentials &credentials, DockerContainer container, const QJsonObject &config = QJsonObject());
|
||||
|
||||
+1
-1
@@ -4,6 +4,6 @@
|
||||
#define APPLICATION_NAME "AmneziaVPN"
|
||||
#define SERVICE_NAME "AmneziaVPN-service"
|
||||
#define ORGANIZATION_NAME "AmneziaVPN.ORG"
|
||||
#define APP_VERSION "1.6.0.0"
|
||||
#define APP_VERSION "1.6.1.0"
|
||||
|
||||
#endif // DEFINES_H
|
||||
|
||||
Binary file not shown.
|
Before Width: | Height: | Size: 215 B After Width: | Height: | Size: 324 B |
+12
-5
@@ -68,18 +68,25 @@ int main(int argc, char *argv[])
|
||||
parser.addHelpOption();
|
||||
parser.addVersionOption();
|
||||
|
||||
QCommandLineOption c_autostart {{"a", "autostart"}, "System autostart"};
|
||||
parser.addOption(c_autostart);
|
||||
|
||||
parser.process(app);
|
||||
|
||||
if (!Debug::init()) {
|
||||
qWarning() << "Initialization of debug subsystem failed";
|
||||
}
|
||||
|
||||
QFont f("Lato Regular", 10);
|
||||
f.setStyleStrategy(QFont::PreferAntialias);
|
||||
app.setFont(f);
|
||||
|
||||
app.setQuitOnLastWindowClosed(false);
|
||||
|
||||
MainWindow mainWindow;
|
||||
mainWindow.show();
|
||||
|
||||
#ifdef Q_OS_WIN
|
||||
if (parser.isSet("a")) mainWindow.showOnStartup();
|
||||
else mainWindow.show();
|
||||
#else
|
||||
mainWindow.showOnStartup();
|
||||
#endif
|
||||
|
||||
if (app.isPrimary()) {
|
||||
QObject::connect(&app, &SingleApplication::instanceStarted, &mainWindow, [&](){
|
||||
|
||||
@@ -3,11 +3,11 @@ LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US
|
||||
|
||||
IDI_ICON1 ICON "../images/app.ico"
|
||||
|
||||
#define VER_FILEVERSION 1,6,0,0
|
||||
#define VER_FILEVERSION_STR "1.6.0.0\0"
|
||||
#define VER_FILEVERSION 1,6,1,0
|
||||
#define VER_FILEVERSION_STR "1.6.1.0\0"
|
||||
|
||||
#define VER_PRODUCTVERSION 1,6,0,0
|
||||
#define VER_PRODUCTVERSION_STR "1.6.0.0\0"
|
||||
#define VER_PRODUCTVERSION 1,6,1,0
|
||||
#define VER_PRODUCTVERSION_STR "1.6.1.0\0"
|
||||
|
||||
#define VER_COMPANYNAME_STR "AmneziaVPN"
|
||||
#define VER_FILEDESCRIPTION_STR "AmneziaVPN"
|
||||
|
||||
@@ -38,7 +38,7 @@ ErrorCode OpenVpnOverCloakProtocol::start()
|
||||
|
||||
QStringList args = QStringList() << "-c" << m_cloakCfgFile.fileName()
|
||||
<< "-s" << m_cloakConfig.value(config_key::remote).toString()
|
||||
<< "-p" << amnezia::protocols::cloak::defaultPort
|
||||
<< "-p" << m_cloakConfig.value(config_key::port).toString(amnezia::protocols::cloak::defaultPort)
|
||||
<< "-l" << amnezia::protocols::openvpn::defaultPort;
|
||||
|
||||
if (m_cloakConfig.value(config_key::transport_proto).toString() == protocols::UDP) {
|
||||
|
||||
@@ -29,6 +29,7 @@ constexpr char transport_proto[] = "transport_proto";
|
||||
constexpr char cipher[] = "cipher";
|
||||
constexpr char hash[] = "hash";
|
||||
constexpr char ncp_disable[] = "ncp_disable";
|
||||
constexpr char tls_auth[] = "tls_auth";
|
||||
|
||||
constexpr char site[] = "site";
|
||||
constexpr char block_outside_dns[] = "block_outside_dns";
|
||||
@@ -72,7 +73,9 @@ constexpr char defaultCipher[] = "AES-256-GCM";
|
||||
constexpr char defaultHash[] = "SHA512";
|
||||
constexpr bool defaultBlockOutsideDns = true;
|
||||
constexpr bool defaultNcpDisable = false;
|
||||
constexpr bool defaultTlsAuth = true;
|
||||
constexpr char ncpDisableString[] = "ncp-disable";
|
||||
constexpr char tlsAuthString[] = "tls-auth /opt/amnezia/openvpn/ta.key 0";
|
||||
|
||||
}
|
||||
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
pm_apt="/usr/bin/apt-get"; pm_yum="/usr/bin/yum"; if [[ -f "$pm_apt" ]]; then pm=$pm_apt; else pm=$pm_yum; fi; if [[ ! -f "/usr/bin/sudo" ]]; then $pm update -y -q; $pm install -y -q sudo; fi
|
||||
pm_apt="/usr/bin/apt-get"; pm_yum="/usr/bin/yum"; if [[ -f "$pm_apt" ]]; then pm=$pm_apt; else pm=$pm_yum; fi; sudo $pm update -y -q
|
||||
pm_apt="/usr/bin/apt-get"; pm_yum="/usr/bin/yum"; if [[ -f "$pm_apt" ]]; then pm=$pm_apt; else pm=$pm_yum; fi; sudo $pm install -y -q curl
|
||||
pm_apt="/usr/bin/apt-get"; pm_yum="/usr/bin/yum"; if [[ -f "$pm_apt" ]]; then sudo export DEBIAN_FRONTEND=noninteractive; sudo $pm_apt install -y -q docker.io; else sudo $pm_yum install -y -q docker; fi
|
||||
pm_apt="/usr/bin/apt-get"; pm_yum="/usr/bin/yum";\
|
||||
if [[ -f "$pm_apt" ]]; then pm=$pm_apt; docker_pkg="docker.io"; else pm=$pm_yum; docker_pkg="docker"; fi;\
|
||||
if [[ ! -f "/usr/bin/sudo" ]]; then $pm update -y -q; $pm install -y -q sudo; fi;\
|
||||
docker_service=$(systemctl list-units --full -all | grep docker.service);\
|
||||
if [[ -f "$pm_apt" ]]; then export DEBIAN_FRONTEND=noninteractive; fi;\
|
||||
if [[ -z "$docker_service" ]]; then sudo $pm update -y -q; sudo $pm install -y -q curl $docker_pkg; fi;\
|
||||
sudo systemctl start docker
|
||||
|
||||
|
||||
@@ -23,5 +23,5 @@ status openvpn-status.log \\n\
|
||||
verb 1 \\n\
|
||||
tls-server \\n\
|
||||
tls-version-min 1.2 \\n\
|
||||
tls-auth /opt/amnezia/openvpn/ta.key 0" >>/opt/amnezia/openvpn/server.conf'
|
||||
$OPENVPN_TLS_AUTH" >/opt/amnezia/openvpn/server.conf'
|
||||
|
||||
|
||||
@@ -23,7 +23,7 @@ status openvpn-status.log \\n\
|
||||
verb 1 \\n\
|
||||
tls-server \\n\
|
||||
tls-version-min 1.2 \\n\
|
||||
tls-auth /opt/amnezia/openvpn/ta.key 0" >>/opt/amnezia/openvpn/server.conf'
|
||||
$OPENVPN_TLS_AUTH" >/opt/amnezia/openvpn/server.conf'
|
||||
|
||||
# Cloak config
|
||||
sudo docker exec -i $CONTAINER_NAME bash -c '\
|
||||
|
||||
@@ -23,7 +23,7 @@ status openvpn-status.log \\n\
|
||||
verb 1 \\n\
|
||||
tls-server \\n\
|
||||
tls-version-min 1.2 \\n\
|
||||
tls-auth /opt/amnezia/openvpn/ta.key 0" >>/opt/amnezia/openvpn/server.conf'
|
||||
$OPENVPN_TLS_AUTH" >/opt/amnezia/openvpn/server.conf'
|
||||
|
||||
# Cloak config
|
||||
sudo docker exec -i $CONTAINER_NAME bash -c '\
|
||||
|
||||
+6
-16
@@ -23,19 +23,6 @@ class Settings : public QObject
|
||||
public:
|
||||
explicit Settings(QObject* parent = nullptr);
|
||||
|
||||
|
||||
// QString userName() const { return m_settings.value("Server/userName", QString()).toString(); }
|
||||
// void setUserName(const QString& login) { m_settings.setValue("Server/userName", login); }
|
||||
|
||||
// QString password() const { return m_settings.value("Server/password", QString()).toString(); }
|
||||
// void setPassword(const QString& password) { m_settings.setValue("Server/password", password); }
|
||||
|
||||
// QString serverName() const { return m_settings.value("Server/serverName", QString()).toString(); }
|
||||
// void setServerName(const QString& serverName) { m_settings.setValue("Server/serverName", serverName); }
|
||||
|
||||
// int serverPort() const { return m_settings.value("Server/serverPort", 22).toInt(); }
|
||||
// void setServerPort(int serverPort = 22) { m_settings.setValue("Server/serverPort", serverPort); }
|
||||
|
||||
ServerCredentials defaultServerCredentials() const;
|
||||
ServerCredentials serverCredentials(int index) const;
|
||||
//void setServerCredentials(const ServerCredentials &credentials);
|
||||
@@ -74,9 +61,12 @@ public:
|
||||
QString nextAvailableServerName() const;
|
||||
|
||||
// App settings section
|
||||
bool isAutoConnect() const { return m_settings.value("Conf/autoConnect", QString()).toBool(); }
|
||||
bool isAutoConnect() const { return m_settings.value("Conf/autoConnect", false).toBool(); }
|
||||
void setAutoConnect(bool enabled) { m_settings.setValue("Conf/autoConnect", enabled); }
|
||||
|
||||
bool isStartMinimized() const { return m_settings.value("Conf/startMinimized", false).toBool(); }
|
||||
void setStartMinimized(bool enabled) { m_settings.setValue("Conf/startMinimized", enabled); }
|
||||
|
||||
bool customRouting() const { return m_settings.value("Conf/customRouting", false).toBool(); }
|
||||
void setCustomRouting(bool customRouting) { m_settings.setValue("Conf/customRouting", customRouting); }
|
||||
|
||||
@@ -100,8 +90,8 @@ public:
|
||||
static const char cloudFlareNs1[];
|
||||
static const char cloudFlareNs2[];
|
||||
|
||||
static constexpr char openNicNs5[] = "94.103.153.176";
|
||||
static constexpr char openNicNs13[] = "144.76.103.143";
|
||||
// static constexpr char openNicNs5[] = "94.103.153.176";
|
||||
// static constexpr char openNicNs13[] = "144.76.103.143";
|
||||
|
||||
|
||||
public:
|
||||
|
||||
Binary file not shown.
File diff suppressed because it is too large
Load Diff
@@ -121,6 +121,8 @@ void SlidingStackedWidget::slideInWgtImpl(QWidget * newwidget, enum t_direction
|
||||
}
|
||||
else m_active = true;
|
||||
|
||||
m_nextWidget = newwidget;
|
||||
|
||||
enum t_direction directionhint;
|
||||
int now = currentIndex(); // currentIndex() is a function inherited from QStackedWidget
|
||||
int next = indexOf(newwidget);
|
||||
@@ -209,6 +211,18 @@ void SlidingStackedWidget::slideInWgtImpl(QWidget * newwidget, enum t_direction
|
||||
// that we implement here below in animationDoneSlot.
|
||||
}
|
||||
|
||||
void SlidingStackedWidget::setCurrentWidget(QWidget *w)
|
||||
{
|
||||
m_nextWidget = w;
|
||||
QStackedWidget::setCurrentWidget(w);
|
||||
}
|
||||
|
||||
QWidget *SlidingStackedWidget::nextWidget() const
|
||||
{
|
||||
if (m_nextWidget == nullptr) return currentWidget();
|
||||
return m_nextWidget;
|
||||
}
|
||||
|
||||
void SlidingStackedWidget::animationDoneSlot(void) {
|
||||
// when ready, call the QStackedWidget slot setCurrentIndex(int)
|
||||
setCurrentIndex(m_next); // this function is inherited from QStackedWidget
|
||||
|
||||
@@ -34,6 +34,9 @@ public:
|
||||
SlidingStackedWidget(QWidget *parent);
|
||||
~SlidingStackedWidget(void);
|
||||
|
||||
QWidget *nextWidget() const;
|
||||
void setCurrentWidget(QWidget *w);
|
||||
|
||||
public slots:
|
||||
// Some basic settings API
|
||||
void setSpeed(int speed); // animation duration in milliseconds
|
||||
@@ -77,6 +80,8 @@ protected:
|
||||
QPropertyAnimation *animnow;
|
||||
QPropertyAnimation *animnext;
|
||||
QParallelAnimationGroup *animgroup;
|
||||
|
||||
QWidget *m_nextWidget = nullptr;
|
||||
};
|
||||
|
||||
#endif // SLIDINGSTACKEDWIDGET_H
|
||||
|
||||
+332
-129
@@ -57,6 +57,11 @@ MainWindow::MainWindow(QWidget *parent) :
|
||||
|
||||
setupTray();
|
||||
setupUiConnections();
|
||||
setupNewServerConnections();
|
||||
setupWizardConnections();
|
||||
setupGeneralSettingsConnections();
|
||||
setupAppSettingsConnections();
|
||||
setupNetworkSettingsConnections();
|
||||
setupProtocolsPageConnections();
|
||||
setupNewServerPageConnections();
|
||||
setupSharePageConnections();
|
||||
@@ -69,7 +74,6 @@ MainWindow::MainWindow(QWidget *parent) :
|
||||
ui->stackedWidget_main->setSpeed(200);
|
||||
ui->stackedWidget_main->setAnimation(QEasingCurve::Linear);
|
||||
|
||||
bool needToHideCustomTitlebar = false;
|
||||
if (QOperatingSystemVersion::current() <= QOperatingSystemVersion::Windows7) {
|
||||
needToHideCustomTitlebar = true;
|
||||
}
|
||||
@@ -81,7 +85,7 @@ MainWindow::MainWindow(QWidget *parent) :
|
||||
|
||||
if (needToHideCustomTitlebar) {
|
||||
ui->widget_tittlebar->hide();
|
||||
resize(width(), height() - ui->stackedWidget_main->y());
|
||||
resize(width(), 640);
|
||||
ui->stackedWidget_main->move(0,0);
|
||||
}
|
||||
|
||||
@@ -97,6 +101,7 @@ MainWindow::MainWindow(QWidget *parent) :
|
||||
});
|
||||
|
||||
//ui->pushButton_general_settings_exit->hide();
|
||||
updateSharingPage(selectedServerIndex, m_settings.serverCredentials(selectedServerIndex), selectedDockerContainer);
|
||||
|
||||
setFixedSize(width(),height());
|
||||
|
||||
@@ -159,15 +164,36 @@ MainWindow::~MainWindow()
|
||||
qDebug() << "Application closed";
|
||||
}
|
||||
|
||||
void MainWindow::showOnStartup()
|
||||
{
|
||||
if (! m_settings.isStartMinimized()) show();
|
||||
else {
|
||||
#ifdef Q_OS_MACX
|
||||
setDockIconVisible(false);
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
void MainWindow::goToPage(Page page, bool reset, bool slide)
|
||||
{
|
||||
qDebug() << "goToPage" << page;
|
||||
//qDebug() << "goToPage" << page;
|
||||
if (ui->stackedWidget_main->nextWidget() == getPageWidget(page)) return;
|
||||
|
||||
if (reset) {
|
||||
if (page == Page::ServerSettings) {
|
||||
updateServerPage();
|
||||
}
|
||||
if (page == Page::ShareConnection) {
|
||||
|
||||
}
|
||||
if (page == Page::Wizard) {
|
||||
ui->radioButton_setup_wizard_medium->setChecked(true);
|
||||
}
|
||||
if (page == Page::WizardHigh) {
|
||||
ui->lineEdit_setup_wizard_high_website_masking->setText(protocols::cloak::defaultRedirSite);
|
||||
}
|
||||
if (page == Page::ServerConfiguring) {
|
||||
ui->progressBar_new_server_configuring->setValue(0);
|
||||
}
|
||||
if (page == Page::ServersList) {
|
||||
updateServersListPage();
|
||||
@@ -175,7 +201,7 @@ void MainWindow::goToPage(Page page, bool reset, bool slide)
|
||||
if (page == Page::Start) {
|
||||
updateStartPage();
|
||||
}
|
||||
if (page == Page::NewServer_2) {
|
||||
if (page == Page::NewServerProtocols) {
|
||||
ui->pushButton_new_server_settings_cloak->setChecked(true);
|
||||
ui->pushButton_new_server_settings_cloak->setChecked(false);
|
||||
ui->pushButton_new_server_settings_ss->setChecked(true);
|
||||
@@ -198,6 +224,9 @@ void MainWindow::goToPage(Page page, bool reset, bool slide)
|
||||
if (page == Page::AppSettings) {
|
||||
updateAppSettingsPage();
|
||||
}
|
||||
if (page == Page::NetworkSettings) {
|
||||
updateAppSettingsPage();
|
||||
}
|
||||
if (page == Page::Sites) {
|
||||
updateSitesPage();
|
||||
}
|
||||
@@ -243,7 +272,13 @@ 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::NewServerProtocols): return ui->page_new_server_protocols;
|
||||
case(Page::Wizard): return ui->page_setup_wizard;
|
||||
case(Page::WizardHigh): return ui->page_setup_wizard_high_level;
|
||||
case(Page::WizardLow): return ui->page_setup_wizard_low_level;
|
||||
case(Page::WizardMedium): return ui->page_setup_wizard_medium_level;
|
||||
case(Page::WizardVpnMode): return ui->page_setup_wizard_vpn_mode;
|
||||
case(Page::ServerConfiguring): return ui->page_new_server_configuring;
|
||||
case(Page::Vpn): return ui->page_vpn;
|
||||
case(Page::GeneralSettings): return ui->page_general_settings;
|
||||
case(Page::AppSettings): return ui->page_app_settings;
|
||||
@@ -303,12 +338,18 @@ void MainWindow::keyPressEvent(QKeyEvent *event)
|
||||
case Qt::Key_Q:
|
||||
qApp->quit();
|
||||
break;
|
||||
case Qt::Key_H:
|
||||
selectedServerIndex = m_settings.defaultServerIndex();
|
||||
selectedDockerContainer = m_settings.defaultContainer(selectedServerIndex);
|
||||
|
||||
updateSharingPage(selectedServerIndex, m_settings.serverCredentials(selectedServerIndex), selectedDockerContainer);
|
||||
goToPage(Page::ShareConnection);
|
||||
break;
|
||||
#endif
|
||||
case Qt::Key_C:
|
||||
qDebug().noquote() << "Def server" << m_settings.defaultServerIndex() << m_settings.defaultContainerName(m_settings.defaultServerIndex());
|
||||
qDebug().noquote() << QJsonDocument(m_settings.containerConfig(m_settings.defaultServerIndex(), m_settings.defaultContainer(m_settings.defaultServerIndex()))).toJson();
|
||||
//qDebug().noquote() << QJsonDocument(m_settings.serversArray()).toJson();
|
||||
break;
|
||||
#endif
|
||||
case Qt::Key_A:
|
||||
goToPage(Page::Start);
|
||||
break;
|
||||
@@ -322,10 +363,11 @@ void MainWindow::keyPressEvent(QKeyEvent *event)
|
||||
goToPage(Page::ServerVpnProtocols);
|
||||
break;
|
||||
case Qt::Key_Escape:
|
||||
if (currentPage() == Page::Vpn) break;
|
||||
if (currentPage() == Page::ServerConfiguring) break;
|
||||
if (currentPage() == Page::Start && pagesStack.size() < 2) break;
|
||||
if (! ui->stackedWidget_main->isAnimationRunning() && ui->stackedWidget_main->currentWidget()->isEnabled()) {
|
||||
if (currentPage() != Page::Vpn && currentPage() != Page::Start) {
|
||||
closePage();
|
||||
}
|
||||
closePage();
|
||||
}
|
||||
default:
|
||||
;
|
||||
@@ -334,7 +376,7 @@ void MainWindow::keyPressEvent(QKeyEvent *event)
|
||||
|
||||
void MainWindow::closeEvent(QCloseEvent *event)
|
||||
{
|
||||
if (currentPage() == Page::Start || currentPage() == Page::NewServer) qApp->quit();
|
||||
if (m_settings.serversCount() == 0) qApp->quit();
|
||||
else {
|
||||
hide();
|
||||
event->ignore();
|
||||
@@ -347,6 +389,11 @@ void MainWindow::showEvent(QShowEvent *event)
|
||||
if (!event->spontaneous()) {
|
||||
setDockIconVisible(true);
|
||||
}
|
||||
if (needToHideCustomTitlebar) {
|
||||
ui->widget_tittlebar->hide();
|
||||
resize(width(), 640);
|
||||
ui->stackedWidget_main->move(0,0);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
@@ -412,9 +459,14 @@ void MainWindow::onPushButtonNewServerConnect(bool)
|
||||
|
||||
ui->pushButton_new_server_connect->setEnabled(false);
|
||||
ui->pushButton_new_server_connect->setText(tr("Connecting..."));
|
||||
|
||||
ErrorCode e = ErrorCode::NoError;
|
||||
#ifdef Q_DEBUG
|
||||
//QString output = ServerController::checkSshConnection(serverCredentials, &e);
|
||||
#else
|
||||
QString output;
|
||||
#endif
|
||||
|
||||
bool ok = true;
|
||||
if (e) {
|
||||
ui->label_new_server_wait_info->show();
|
||||
@@ -434,59 +486,97 @@ void MainWindow::onPushButtonNewServerConnect(bool)
|
||||
ui->pushButton_new_server_connect->setText(tr("Connect"));
|
||||
|
||||
installCredentials = serverCredentials;
|
||||
if (ok) goToPage(Page::NewServer_2);
|
||||
if (ok) goToPage(Page::NewServer);
|
||||
}
|
||||
|
||||
void MainWindow::onPushButtonNewServerConnectConfigure(bool)
|
||||
QMap<DockerContainer, QJsonObject> MainWindow::getInstallConfigsFromProtocolsPage() const
|
||||
{
|
||||
QJsonObject cloakConfig {
|
||||
{ config_key::port, ui->lineEdit_new_server_cloak_port->text() },
|
||||
{ config_key::container, amnezia::containerToString(DockerContainer::OpenVpnOverCloak) },
|
||||
{ config_key::cloak, QJsonObject {
|
||||
{ config_key::port, ui->lineEdit_new_server_cloak_port->text() },
|
||||
{ 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::containerToString(DockerContainer::OpenVpnOverShadowSocks) },
|
||||
{ config_key::shadowsocks, QJsonObject {
|
||||
{ config_key::port, ui->lineEdit_new_server_ss_port->text() },
|
||||
{ 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::containerToString(DockerContainer::OpenVpn) },
|
||||
{ config_key::openvpn, QJsonObject {
|
||||
{ config_key::port, ui->lineEdit_new_server_openvpn_port->text() },
|
||||
{ config_key::transport_proto, ui->comboBox_new_server_openvpn_proto->currentText() }}
|
||||
}
|
||||
};
|
||||
|
||||
QJsonArray containerConfigs;
|
||||
QList<DockerContainer> containers;
|
||||
QMap<DockerContainer, QJsonObject> containers;
|
||||
|
||||
if (ui->checkBox_new_server_cloak->isChecked()) {
|
||||
containerConfigs.append(cloakConfig);
|
||||
containers.append(DockerContainer::OpenVpnOverCloak);
|
||||
containers.insert(DockerContainer::OpenVpnOverCloak, cloakConfig);
|
||||
}
|
||||
|
||||
if (ui->checkBox_new_server_ss->isChecked()) {
|
||||
containerConfigs.append(ssConfig);
|
||||
containers.append(DockerContainer::OpenVpnOverShadowSocks);
|
||||
containers.insert(DockerContainer::OpenVpnOverShadowSocks, ssConfig);
|
||||
}
|
||||
|
||||
if (ui->checkBox_new_server_openvpn->isChecked()) {
|
||||
containerConfigs.append(openVpnConfig);
|
||||
containers.append(DockerContainer::OpenVpnOverShadowSocks);
|
||||
containers.insert(DockerContainer::OpenVpn, openVpnConfig);
|
||||
}
|
||||
|
||||
return containers;
|
||||
}
|
||||
|
||||
QMap<DockerContainer, QJsonObject> MainWindow::getInstallConfigsFromWizardPage() const
|
||||
{
|
||||
QJsonObject cloakConfig {
|
||||
{ config_key::container, amnezia::containerToString(DockerContainer::OpenVpnOverCloak) },
|
||||
{ config_key::cloak, QJsonObject {
|
||||
{ config_key::site, ui->lineEdit_setup_wizard_high_website_masking->text() }}
|
||||
}
|
||||
};
|
||||
QJsonObject ssConfig {
|
||||
{ config_key::container, amnezia::containerToString(DockerContainer::OpenVpnOverShadowSocks) }
|
||||
};
|
||||
QJsonObject openVpnConfig {
|
||||
{ config_key::container, amnezia::containerToString(DockerContainer::OpenVpn) }
|
||||
};
|
||||
|
||||
QMap<DockerContainer, QJsonObject> containers;
|
||||
|
||||
if (ui->radioButton_setup_wizard_high->isChecked()) {
|
||||
containers.insert(DockerContainer::OpenVpnOverCloak, cloakConfig);
|
||||
}
|
||||
|
||||
if (ui->radioButton_setup_wizard_medium->isChecked()) {
|
||||
containers.insert(DockerContainer::OpenVpnOverShadowSocks, ssConfig);
|
||||
}
|
||||
|
||||
if (ui->radioButton_setup_wizard_low->isChecked()) {
|
||||
containers.insert(DockerContainer::OpenVpn, openVpnConfig);
|
||||
}
|
||||
|
||||
return containers;
|
||||
}
|
||||
|
||||
void MainWindow::installServer(const QMap<DockerContainer, QJsonObject> &containers)
|
||||
{
|
||||
if (containers.isEmpty()) return;
|
||||
|
||||
// bool ok = true;
|
||||
bool ok = installServer(installCredentials, containers, containerConfigs,
|
||||
ui->page_new_server_2,
|
||||
ui->progressBar_new_server_connection,
|
||||
ui->pushButton_new_server_connect,
|
||||
ui->label_new_server_wait_info);
|
||||
goToPage(Page::ServerConfiguring);
|
||||
QEventLoop loop;
|
||||
QTimer::singleShot(500, &loop, SLOT(quit()));
|
||||
loop.exec();
|
||||
qApp->processEvents();
|
||||
|
||||
bool ok = installContainers(installCredentials, containers,
|
||||
ui->page_new_server_configuring,
|
||||
ui->progressBar_new_server_configuring,
|
||||
nullptr,
|
||||
ui->label_new_server_configuring_wait_info);
|
||||
|
||||
if (ok) {
|
||||
QJsonObject server;
|
||||
@@ -496,14 +586,22 @@ void MainWindow::onPushButtonNewServerConnectConfigure(bool)
|
||||
server.insert(config_key::port, installCredentials.port);
|
||||
server.insert(config_key::description, m_settings.nextAvailableServerName());
|
||||
|
||||
QJsonArray containerConfigs;
|
||||
for (const QJsonObject &cfg : containers) {
|
||||
containerConfigs.append(cfg);
|
||||
}
|
||||
server.insert(config_key::containers, containerConfigs);
|
||||
server.insert(config_key::defaultContainer, containerToString(containers.first()));
|
||||
server.insert(config_key::defaultContainer, containerToString(containers.firstKey()));
|
||||
|
||||
m_settings.addServer(server);
|
||||
m_settings.setDefaultServer(m_settings.serversCount() - 1);
|
||||
|
||||
goToPage(Page::Vpn);
|
||||
setStartPage(Page::Vpn);
|
||||
qApp->processEvents();
|
||||
}
|
||||
else {
|
||||
closePage();
|
||||
}
|
||||
}
|
||||
|
||||
void MainWindow::onPushButtonNewServerImport(bool)
|
||||
@@ -534,6 +632,8 @@ void MainWindow::onPushButtonNewServerImport(bool)
|
||||
|
||||
if (credentials.isValid() || o.contains(config_key::containers)) {
|
||||
m_settings.addServer(o);
|
||||
m_settings.setDefaultServer(m_settings.serversCount() - 1);
|
||||
|
||||
setStartPage(Page::Vpn);
|
||||
}
|
||||
else {
|
||||
@@ -543,18 +643,21 @@ void MainWindow::onPushButtonNewServerImport(bool)
|
||||
|
||||
}
|
||||
|
||||
bool MainWindow::installServer(ServerCredentials credentials,
|
||||
QList<DockerContainer> containers, QJsonArray configs,
|
||||
bool MainWindow::installContainers(ServerCredentials credentials,
|
||||
const QMap<DockerContainer, QJsonObject> &containers,
|
||||
QWidget *page, QProgressBar *progress, QPushButton *button, QLabel *info)
|
||||
{
|
||||
page->setEnabled(false);
|
||||
button->setVisible(false);
|
||||
if (!progress) return false;
|
||||
|
||||
info->setVisible(true);
|
||||
info->setText(tr("Please wait, configuring process may take up to 5 minutes"));
|
||||
if (page) page->setEnabled(false);
|
||||
if (button) button->setVisible(false);
|
||||
|
||||
if (info) info->setVisible(true);
|
||||
if (info) info->setText(tr("Please wait, configuring process may take up to 5 minutes"));
|
||||
|
||||
|
||||
for (int i = 0; i < containers.size(); ++i) {
|
||||
int cnt = 0;
|
||||
for (QMap<DockerContainer, QJsonObject>::const_iterator i = containers.constBegin(); i != containers.constEnd(); i++, cnt++) {
|
||||
QTimer timer;
|
||||
connect(&timer, &QTimer::timeout, [progress](){
|
||||
progress->setValue(progress->value() + 1);
|
||||
@@ -564,16 +667,16 @@ bool MainWindow::installServer(ServerCredentials credentials,
|
||||
timer.start(1000);
|
||||
|
||||
progress->setTextVisible(true);
|
||||
progress->setFormat(QString("%1%2%3").arg(i+1).arg(tr("of")).arg(containers.size()));
|
||||
progress->setFormat(QString("Installing %1 %2 %3").arg(cnt+1).arg(tr("of")).arg(containers.size()));
|
||||
|
||||
ErrorCode e = ServerController::setupContainer(credentials, containers.at(i), configs.at(i).toObject());
|
||||
ErrorCode e = ServerController::setupContainer(credentials, i.key(), i.value());
|
||||
qDebug() << "Setup server finished with code" << e;
|
||||
ServerController::disconnectFromHost(credentials);
|
||||
|
||||
if (e) {
|
||||
page->setEnabled(true);
|
||||
button->setVisible(true);
|
||||
info->setVisible(false);
|
||||
if (page) page->setEnabled(true);
|
||||
if (button) button->setVisible(true);
|
||||
if (info) info->setVisible(false);
|
||||
|
||||
QMessageBox::warning(this, APPLICATION_NAME,
|
||||
tr("Error occurred while configuring server.") + "\n" +
|
||||
@@ -604,11 +707,9 @@ bool MainWindow::installServer(ServerCredentials credentials,
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
// button->show();
|
||||
// page->setEnabled(true);
|
||||
// info->setText(tr("Amnezia server installed"));
|
||||
if (button) button->show();
|
||||
if (page) page->setEnabled(true);
|
||||
if (info) info->setText(tr("Amnezia server installed"));
|
||||
|
||||
return true;
|
||||
}
|
||||
@@ -720,6 +821,11 @@ void MainWindow::onPushButtonForgetServer(bool)
|
||||
m_settings.setDefaultServer(m_settings.defaultServerIndex() - 1);
|
||||
}
|
||||
|
||||
if (m_settings.serversCount() == 0) {
|
||||
m_settings.setDefaultServer(-1);
|
||||
}
|
||||
|
||||
|
||||
selectedServerIndex = -1;
|
||||
|
||||
updateServersListPage();
|
||||
@@ -869,51 +975,36 @@ void MainWindow::setupUiConnections()
|
||||
else hide();
|
||||
});
|
||||
connect(ui->pushButton_general_settings_exit, &QPushButton::clicked, this, [&](){ qApp->quit(); });
|
||||
connect(ui->pushButton_new_server_get_info, &QPushButton::clicked, this, [&](){
|
||||
QDesktopServices::openUrl(QUrl("https://amnezia.org"));
|
||||
});
|
||||
|
||||
|
||||
connect(ui->pushButton_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_vpn_add_site, &QPushButton::clicked, this, [this](){ goToPage(Page::Sites); });
|
||||
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](){
|
||||
selectedServerIndex = m_settings.defaultServerIndex();
|
||||
goToPage(Page::ServerSettings);
|
||||
});
|
||||
connect(ui->pushButton_servers_list, &QPushButton::clicked, this, [this](){ goToPage(Page::ServersList); });
|
||||
connect(ui->pushButton_share_connection, &QPushButton::clicked, this, [this](){
|
||||
selectedServerIndex = m_settings.defaultServerIndex();
|
||||
selectedDockerContainer = m_settings.defaultContainer(selectedServerIndex);
|
||||
|
||||
goToPage(Page::ShareConnection);
|
||||
updateSharingPage(selectedServerIndex, m_settings.serverCredentials(selectedServerIndex), selectedDockerContainer);
|
||||
//updateShareCodePage();
|
||||
});
|
||||
|
||||
|
||||
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(); });
|
||||
connect(ui->pushButton_back_from_servers, &QPushButton::clicked, this, [this](){ closePage(); });
|
||||
connect(ui->pushButton_back_from_share, &QPushButton::clicked, this, [this](){ closePage(); });
|
||||
connect(ui->pushButton_back_from_server_vpn_protocols, &QPushButton::clicked, this, [this](){ closePage(); });
|
||||
|
||||
connect(ui->pushButton_back_from_openvpn_settings, &QPushButton::clicked, this, [this](){ closePage(); });
|
||||
connect(ui->pushButton_back_from_cloak_settings, &QPushButton::clicked, this, [this](){ closePage(); });
|
||||
connect(ui->pushButton_back_from_shadowsocks_settings, &QPushButton::clicked, this, [this](){ closePage(); });
|
||||
QVector<QPushButton *> backButtons {
|
||||
ui->pushButton_back_from_sites,
|
||||
ui->pushButton_back_from_settings,
|
||||
ui->pushButton_back_from_start,
|
||||
ui->pushButton_back_from_new_server,
|
||||
ui->pushButton_back_from_new_server_protocols,
|
||||
ui->pushButton_back_from_setup_wizard,
|
||||
ui->pushButton_back_from_setup_wizard_high,
|
||||
ui->pushButton_back_from_setup_wizard_low,
|
||||
ui->pushButton_back_from_setup_wizard_medium,
|
||||
ui->pushButton_back_from_setup_wizard_vpn_mode,
|
||||
ui->pushButton_back_from_app_settings,
|
||||
ui->pushButton_back_from_network_settings,
|
||||
ui->pushButton_back_from_server_settings,
|
||||
ui->pushButton_back_from_servers,
|
||||
ui->pushButton_back_from_share,
|
||||
ui->pushButton_back_from_server_vpn_protocols,
|
||||
ui->pushButton_back_from_openvpn_settings,
|
||||
ui->pushButton_back_from_cloak_settings,
|
||||
ui->pushButton_back_from_shadowsocks_settings
|
||||
};
|
||||
|
||||
for (QPushButton *b : backButtons) {
|
||||
connect(b, &QPushButton::clicked, this, [this](){ closePage(); });
|
||||
}
|
||||
|
||||
connect(ui->pushButton_sites_add_custom, &QPushButton::clicked, this, [this](){ onPushButtonAddCustomSitesClicked(); });
|
||||
|
||||
@@ -923,42 +1014,6 @@ void MainWindow::setupUiConnections()
|
||||
m_settings.setCustomRouting(toggled);
|
||||
});
|
||||
|
||||
connect(ui->checkBox_autostart, &QCheckBox::stateChanged, this, [this](int state){
|
||||
if (state == Qt::Unchecked) {
|
||||
ui->checkBox_autoconnect->setChecked(false);
|
||||
}
|
||||
Autostart::setAutostart(state == Qt::Checked);
|
||||
});
|
||||
|
||||
connect(ui->checkBox_autoconnect, &QCheckBox::stateChanged, this, [this](int state){
|
||||
m_settings.setAutoConnect(state == Qt::Checked);
|
||||
});
|
||||
|
||||
connect(ui->pushButton_network_settings_resetdns1, &QPushButton::clicked, this, [this](){
|
||||
m_settings.setPrimaryDns(m_settings.cloudFlareNs1);
|
||||
updateAppSettingsPage();
|
||||
});
|
||||
connect(ui->pushButton_network_settings_resetdns2, &QPushButton::clicked, this, [this](){
|
||||
m_settings.setSecondaryDns(m_settings.cloudFlareNs2);
|
||||
updateAppSettingsPage();
|
||||
});
|
||||
|
||||
connect(ui->lineEdit_network_settings_dns1, &QLineEdit::textEdited, this, [this](const QString &newText){
|
||||
if (m_ipAddressValidator.regExp().exactMatch(newText)) {
|
||||
m_settings.setPrimaryDns(newText);
|
||||
}
|
||||
});
|
||||
connect(ui->lineEdit_network_settings_dns2, &QLineEdit::textEdited, this, [this](const QString &newText){
|
||||
if (m_ipAddressValidator.regExp().exactMatch(newText)) {
|
||||
m_settings.setSecondaryDns(newText);
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
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](){
|
||||
@@ -972,8 +1027,135 @@ void MainWindow::setupUiConnections()
|
||||
connect(ui->lineEdit_server_settings_description, &QLineEdit::returnPressed, this, [this](){
|
||||
ui->lineEdit_server_settings_description->clearFocus();
|
||||
});
|
||||
}
|
||||
|
||||
void MainWindow::setupNewServerConnections()
|
||||
{
|
||||
connect(ui->pushButton_new_server_get_info, &QPushButton::clicked, this, [](){
|
||||
QDesktopServices::openUrl(QUrl("https://amnezia.org"));
|
||||
});
|
||||
|
||||
connect(ui->pushButton_new_server_connect, SIGNAL(clicked(bool)), this, SLOT(onPushButtonNewServerConnect(bool)));
|
||||
connect(ui->pushButton_new_server_import, SIGNAL(clicked(bool)), this, SLOT(onPushButtonNewServerImport(bool)));
|
||||
|
||||
connect(ui->pushButton_new_server_connect_configure, &QPushButton::clicked, this, [this](){
|
||||
installServer(getInstallConfigsFromProtocolsPage());
|
||||
});
|
||||
|
||||
}
|
||||
|
||||
void MainWindow::setupWizardConnections()
|
||||
{
|
||||
connect(ui->pushButton_new_server_wizard, &QPushButton::clicked, this, [this](){ goToPage(Page::Wizard); });
|
||||
connect(ui->pushButton_new_server_advanced, &QPushButton::clicked, this, [this](){ goToPage(Page::NewServerProtocols); });
|
||||
connect(ui->pushButton_setup_wizard_next, &QPushButton::clicked, this, [this](){
|
||||
if (ui->radioButton_setup_wizard_high->isChecked()) goToPage(Page::WizardHigh);
|
||||
else if (ui->radioButton_setup_wizard_medium->isChecked()) goToPage(Page::WizardMedium);
|
||||
else if (ui->radioButton_setup_wizard_low->isChecked()) goToPage(Page::WizardLow);
|
||||
});
|
||||
|
||||
connect(ui->pushButton_setup_wizard_high_next, &QPushButton::clicked, this, [this](){
|
||||
QString domain = ui->lineEdit_setup_wizard_high_website_masking->text();
|
||||
if (domain.isEmpty() || !domain.contains(".")) return;
|
||||
goToPage(Page::WizardVpnMode);
|
||||
});
|
||||
|
||||
connect(ui->lineEdit_setup_wizard_high_website_masking, &QLineEdit::textEdited, this, [this](){
|
||||
QString text = ui->lineEdit_setup_wizard_high_website_masking->text();
|
||||
text.replace("http://", "");
|
||||
text.replace("https://", "");
|
||||
if (text.isEmpty()) return;
|
||||
text = text.split("/").first();
|
||||
ui->lineEdit_setup_wizard_high_website_masking->setText(text);
|
||||
});
|
||||
|
||||
connect(ui->pushButton_setup_wizard_medium_next, &QPushButton::clicked, this, [this](){ goToPage(Page::WizardVpnMode); });
|
||||
|
||||
connect(ui->pushButton_setup_wizard_vpn_mode_finish, &QPushButton::clicked, this, [this](){
|
||||
installServer(getInstallConfigsFromWizardPage());
|
||||
m_settings.setCustomRouting(ui->checkBox_setup_wizard_vpn_mode->isChecked());
|
||||
});
|
||||
|
||||
connect(ui->pushButton_setup_wizard_low_finish, &QPushButton::clicked, this, [this](){
|
||||
installServer(getInstallConfigsFromWizardPage());
|
||||
});
|
||||
|
||||
connect(ui->lineEdit_setup_wizard_high_website_masking, &QLineEdit::returnPressed, this, [this](){
|
||||
ui->pushButton_setup_wizard_high_next->click();
|
||||
});
|
||||
}
|
||||
|
||||
void MainWindow::setupAppSettingsConnections()
|
||||
{
|
||||
connect(ui->checkBox_app_settings_autostart, &QCheckBox::stateChanged, this, [this](int state){
|
||||
if (state == Qt::Unchecked) {
|
||||
ui->checkBox_app_settings_autoconnect->setChecked(false);
|
||||
}
|
||||
Autostart::setAutostart(state == Qt::Checked);
|
||||
});
|
||||
|
||||
connect(ui->checkBox_app_settings_autoconnect, &QCheckBox::stateChanged, this, [this](int state){
|
||||
m_settings.setAutoConnect(state == Qt::Checked);
|
||||
});
|
||||
|
||||
connect(ui->checkBox_app_settings_start_minimized, &QCheckBox::stateChanged, this, [this](int state){
|
||||
m_settings.setStartMinimized(state == Qt::Checked);
|
||||
});
|
||||
|
||||
connect(ui->pushButton_app_settings_check_for_updates, &QPushButton::clicked, this, [this](){
|
||||
QDesktopServices::openUrl(QUrl("https://github.com/amnezia-vpn/desktop-client/releases/latest"));
|
||||
});
|
||||
|
||||
connect(ui->pushButton_app_settings_open_logs, &QPushButton::clicked, this, [this](){
|
||||
Debug::openLogsFolder();
|
||||
QDesktopServices::openUrl(QUrl::fromLocalFile(Utils::systemLogPath()));
|
||||
});
|
||||
}
|
||||
|
||||
void MainWindow::setupGeneralSettingsConnections()
|
||||
{
|
||||
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](){
|
||||
selectedServerIndex = m_settings.defaultServerIndex();
|
||||
goToPage(Page::ServerSettings);
|
||||
});
|
||||
connect(ui->pushButton_servers_list, &QPushButton::clicked, this, [this](){ goToPage(Page::ServersList); });
|
||||
connect(ui->pushButton_share_connection, &QPushButton::clicked, this, [this](){
|
||||
selectedServerIndex = m_settings.defaultServerIndex();
|
||||
selectedDockerContainer = m_settings.defaultContainer(selectedServerIndex);
|
||||
|
||||
updateSharingPage(selectedServerIndex, m_settings.serverCredentials(selectedServerIndex), selectedDockerContainer);
|
||||
goToPage(Page::ShareConnection);
|
||||
});
|
||||
|
||||
connect(ui->pushButton_general_settings_add_server, &QPushButton::clicked, this, [this](){ goToPage(Page::Start); });
|
||||
|
||||
}
|
||||
|
||||
void MainWindow::setupNetworkSettingsConnections()
|
||||
{
|
||||
connect(ui->lineEdit_network_settings_dns1, &QLineEdit::textEdited, this, [this](const QString &newText){
|
||||
if (m_ipAddressValidator.regExp().exactMatch(newText)) {
|
||||
m_settings.setPrimaryDns(newText);
|
||||
}
|
||||
});
|
||||
connect(ui->lineEdit_network_settings_dns2, &QLineEdit::textEdited, this, [this](const QString &newText){
|
||||
if (m_ipAddressValidator.regExp().exactMatch(newText)) {
|
||||
m_settings.setSecondaryDns(newText);
|
||||
}
|
||||
});
|
||||
|
||||
connect(ui->pushButton_network_settings_resetdns1, &QPushButton::clicked, this, [this](){
|
||||
m_settings.setPrimaryDns(m_settings.cloudFlareNs1);
|
||||
updateAppSettingsPage();
|
||||
});
|
||||
|
||||
connect(ui->pushButton_network_settings_resetdns2, &QPushButton::clicked, this, [this](){
|
||||
m_settings.setSecondaryDns(m_settings.cloudFlareNs2);
|
||||
updateAppSettingsPage();
|
||||
});
|
||||
}
|
||||
|
||||
void MainWindow::setupProtocolsPageConnections()
|
||||
@@ -1296,7 +1478,7 @@ void MainWindow::setupSharePageConnections()
|
||||
qApp->processEvents();
|
||||
|
||||
ServerCredentials credentials = m_settings.serverCredentials(selectedServerIndex);
|
||||
QJsonObject containerConfig; // = m_settings.containerConfig(selectedServerIndex, selectedDockerContainer);
|
||||
QJsonObject containerConfig = m_settings.containerConfig(selectedServerIndex, selectedDockerContainer);
|
||||
containerConfig.insert(config_key::container, containerToString(selectedDockerContainer));
|
||||
|
||||
ErrorCode e = ErrorCode::NoError;
|
||||
@@ -1336,17 +1518,23 @@ void MainWindow::setupSharePageConnections()
|
||||
});
|
||||
|
||||
connect(ui->pushButton_share_openvpn_generate, &QPushButton::clicked, this, [this](){
|
||||
ServerCredentials credentials = m_settings.serverCredentials(selectedServerIndex);
|
||||
const QJsonObject &containerConfig = m_settings.containerConfig(selectedServerIndex, selectedDockerContainer);
|
||||
ui->pushButton_share_openvpn_generate->setEnabled(false);
|
||||
ui->pushButton_share_openvpn_copy->setEnabled(false);
|
||||
ui->pushButton_share_openvpn_save->setEnabled(false);
|
||||
ui->pushButton_share_openvpn_generate->setText(tr("Generating..."));
|
||||
|
||||
ServerCredentials credentials = m_settings.serverCredentials(selectedServerIndex);
|
||||
const QJsonObject &containerConfig = m_settings.containerConfig(selectedServerIndex, selectedDockerContainer);
|
||||
|
||||
ErrorCode e = ErrorCode::NoError;
|
||||
QString cfg = OpenVpnConfigurator::genOpenVpnConfig(credentials, selectedDockerContainer, containerConfig, &e);
|
||||
|
||||
ui->textEdit_share_openvpn_code->setPlainText(cfg);
|
||||
|
||||
ui->pushButton_share_openvpn_generate->setEnabled(true);
|
||||
ui->pushButton_share_openvpn_copy->setEnabled(true);
|
||||
ui->pushButton_share_openvpn_save->setEnabled(true);
|
||||
ui->pushButton_share_openvpn_generate->setText(tr("Generate config"));
|
||||
});
|
||||
|
||||
connect(ui->pushButton_share_openvpn_save, &QPushButton::clicked, this, [this](){
|
||||
@@ -1570,8 +1758,9 @@ void MainWindow::updateVpnPage()
|
||||
|
||||
void MainWindow::updateAppSettingsPage()
|
||||
{
|
||||
ui->checkBox_autostart->setChecked(Autostart::isAutostart());
|
||||
ui->checkBox_autoconnect->setChecked(m_settings.isAutoConnect());
|
||||
ui->checkBox_app_settings_autostart->setChecked(Autostart::isAutostart());
|
||||
ui->checkBox_app_settings_autoconnect->setChecked(m_settings.isAutoConnect());
|
||||
ui->checkBox_app_settings_start_minimized->setChecked(m_settings.isStartMinimized());
|
||||
|
||||
ui->lineEdit_network_settings_dns1->setText(m_settings.primaryDns());
|
||||
ui->lineEdit_network_settings_dns2->setText(m_settings.secondaryDns());
|
||||
@@ -1693,6 +1882,9 @@ void MainWindow::updateOpenVpnPage(const QJsonObject &openvpnConfig, DockerConta
|
||||
bool isNcpDisabled = openvpnConfig.value(config_key::ncp_disable).toBool(protocols::openvpn::defaultNcpDisable);
|
||||
ui->checkBox_proto_openvpn_auto_encryption->setChecked(!isNcpDisabled);
|
||||
|
||||
bool isTlsAuth = openvpnConfig.value(config_key::tls_auth).toBool(protocols::openvpn::defaultTlsAuth);
|
||||
ui->checkBox_proto_openvpn_tls_auth->setChecked(isTlsAuth);
|
||||
|
||||
if (container == DockerContainer::OpenVpnOverShadowSocks) {
|
||||
ui->radioButton_proto_openvpn_udp->setEnabled(false);
|
||||
ui->radioButton_proto_openvpn_tcp->setEnabled(false);
|
||||
@@ -1770,6 +1962,7 @@ void MainWindow::updateSharingPage(int serverIndex, const ServerCredentials &cre
|
||||
ui->pushButton_share_openvpn_copy->setEnabled(false);
|
||||
ui->pushButton_share_openvpn_save->setEnabled(false);
|
||||
}
|
||||
ui->toolBox_share_connection->setCurrentWidget(ui->page_share_openvpn);
|
||||
}
|
||||
|
||||
if (container == DockerContainer::OpenVpnOverShadowSocks) {
|
||||
@@ -1803,6 +1996,12 @@ void MainWindow::updateSharingPage(int serverIndex, const ServerCredentials &cre
|
||||
ui->label_share_ss_port->setText(ssConfig.value("server_port").toString());
|
||||
ui->label_share_ss_method->setText(ssConfig.value("method").toString());
|
||||
ui->label_share_ss_password->setText(ssConfig.value("password").toString());
|
||||
|
||||
ui->toolBox_share_connection->setCurrentWidget(ui->page_share_shadowsocks);
|
||||
ui->page_share_shadowsocks->show();
|
||||
ui->page_share_shadowsocks->raise();
|
||||
qDebug() << ui->page_share_shadowsocks->size();
|
||||
ui->toolBox_share_connection->layout()->update();
|
||||
}
|
||||
|
||||
// Amnezia sharing
|
||||
@@ -1817,6 +2016,9 @@ void MainWindow::updateSharingPage(int serverIndex, const ServerCredentials &cre
|
||||
// ui->textEdit_share_amnezia_code->setPlainText(QJsonDocument(exportContainer).toJson());
|
||||
|
||||
ui->textEdit_share_amnezia_code->setPlainText(tr(""));
|
||||
repaint();
|
||||
update();
|
||||
updateGeometry();
|
||||
}
|
||||
|
||||
void MainWindow::makeSitesListItem(QListWidget *listWidget, const QString &address)
|
||||
@@ -1910,6 +2112,7 @@ QJsonObject MainWindow::getOpenVpnConfigFromPage(QJsonObject oldConfig)
|
||||
oldConfig.insert(config_key::hash, ui->comboBox_proto_openvpn_hash->currentText());
|
||||
oldConfig.insert(config_key::block_outside_dns, ui->checkBox_proto_openvpn_block_dns->isChecked());
|
||||
oldConfig.insert(config_key::port, ui->lineEdit_proto_openvpn_port->text());
|
||||
oldConfig.insert(config_key::tls_auth, ui->checkBox_proto_openvpn_tls_auth->isChecked());
|
||||
|
||||
return oldConfig;
|
||||
}
|
||||
|
||||
+19
-5
@@ -40,11 +40,15 @@ public:
|
||||
explicit MainWindow(QWidget *parent = nullptr);
|
||||
~MainWindow();
|
||||
|
||||
enum Page {Start, NewServer, NewServer_2, Vpn, GeneralSettings, AppSettings, NetworkSettings,
|
||||
ServerSettings, ServerVpnProtocols, ServersList, ShareConnection, Sites,
|
||||
enum Page {Start, NewServer, NewServerProtocols, Vpn,
|
||||
Wizard, WizardLow, WizardMedium, WizardHigh, WizardVpnMode, ServerConfiguring,
|
||||
GeneralSettings, AppSettings, NetworkSettings, ServerSettings,
|
||||
ServerVpnProtocols, ServersList, ShareConnection, Sites,
|
||||
OpenVpnSettings, ShadowSocksSettings, CloakSettings};
|
||||
Q_ENUM(Page)
|
||||
|
||||
void showOnStartup();
|
||||
|
||||
private slots:
|
||||
void onBytesChanged(quint64 receivedBytes, quint64 sentBytes);
|
||||
void onConnectionStateChanged(VpnProtocol::ConnectionState state);
|
||||
@@ -52,7 +56,7 @@ private slots:
|
||||
|
||||
void onPushButtonConnectClicked(bool checked);
|
||||
void onPushButtonNewServerConnect(bool);
|
||||
void onPushButtonNewServerConnectConfigure(bool);
|
||||
void installServer(const QMap<DockerContainer, QJsonObject> &containers);
|
||||
void onPushButtonNewServerImport(bool);
|
||||
|
||||
void onPushButtonClearServer(bool);
|
||||
@@ -79,7 +83,7 @@ private:
|
||||
QWidget *getPageWidget(Page page);
|
||||
Page currentPage();
|
||||
|
||||
bool installServer(ServerCredentials credentials, QList<DockerContainer> containers, QJsonArray configs,
|
||||
bool installContainers(ServerCredentials credentials, const QMap<DockerContainer, QJsonObject> &containers,
|
||||
QWidget *page, QProgressBar *progress, QPushButton *button, QLabel *info);
|
||||
|
||||
ErrorCode doInstallAction(const std::function<ErrorCode()> &action, QWidget *page, QProgressBar *progress, QPushButton *button, QLabel *info);
|
||||
@@ -88,6 +92,11 @@ private:
|
||||
void setTrayIcon(const QString &iconPath);
|
||||
|
||||
void setupUiConnections();
|
||||
void setupNewServerConnections();
|
||||
void setupWizardConnections();
|
||||
void setupAppSettingsConnections();
|
||||
void setupGeneralSettingsConnections();
|
||||
void setupNetworkSettingsConnections();
|
||||
void setupProtocolsPageConnections();
|
||||
void setupNewServerPageConnections();
|
||||
void setupServerSettingsPageConnections();
|
||||
@@ -117,6 +126,9 @@ private:
|
||||
QJsonObject getShadowSocksConfigFromPage(QJsonObject oldConfig);
|
||||
QJsonObject getCloakConfigFromPage(QJsonObject oldConfig);
|
||||
|
||||
QMap<DockerContainer, QJsonObject> getInstallConfigsFromProtocolsPage() const;
|
||||
QMap<DockerContainer, QJsonObject> getInstallConfigsFromWizardPage() const;
|
||||
|
||||
private:
|
||||
Ui::MainWindow *ui;
|
||||
VpnConnection* m_vpnConnection;
|
||||
@@ -137,6 +149,8 @@ private:
|
||||
|
||||
bool canMove = false;
|
||||
QPoint offset;
|
||||
bool needToHideCustomTitlebar = false;
|
||||
|
||||
bool eventFilter(QObject *obj, QEvent *event) override;
|
||||
void keyPressEvent(QKeyEvent* event) override;
|
||||
void closeEvent(QCloseEvent *event) override;
|
||||
@@ -151,7 +165,7 @@ private:
|
||||
QStack<Page> pagesStack;
|
||||
int selectedServerIndex = -1; // server index to use when proto settings page opened
|
||||
DockerContainer selectedDockerContainer; // same
|
||||
ServerCredentials installCredentials; // used to save cred between pages new_server and new_server_2
|
||||
ServerCredentials installCredentials; // used to save cred between pages new_server and new_server_protocols and wizard
|
||||
};
|
||||
|
||||
#endif // MAINWINDOW_H
|
||||
|
||||
+1468
-198
File diff suppressed because it is too large
Load Diff
@@ -105,7 +105,10 @@ QString VpnConnection::createVpnConfigurationForProto(int serverIndex,
|
||||
|
||||
QString configData;
|
||||
if (lastVpnConfig.contains(proto)) {
|
||||
configData = OpenVpnConfigurator::processConfigWithLocalSettings(lastVpnConfig.value(proto));
|
||||
configData = lastVpnConfig.value(proto);
|
||||
if (proto == Protocol::OpenVpn) {
|
||||
configData = OpenVpnConfigurator::processConfigWithLocalSettings(configData);
|
||||
}
|
||||
qDebug() << "VpnConnection::createVpnConfiguration: using saved config for" << protoToString(proto);
|
||||
}
|
||||
else {
|
||||
|
||||
Executable
+74
@@ -0,0 +1,74 @@
|
||||
#!/bin/bash
|
||||
|
||||
# Mac name-resolution updater based on @cl's script here:
|
||||
# https://blog.netnerds.net/2011/10/openvpn-update-client-dns-on-mac-os-x-using-from-the-command-line/
|
||||
# Openvpn envar parsing taken from the script in debian's openvpn package.
|
||||
# Smushed together and improved by @andrewgdotcom.
|
||||
|
||||
# Parses DHCP options from openvpn to update resolv.conf
|
||||
# To use set as 'up' and 'down' script in your openvpn *.conf:
|
||||
# up /etc/openvpn/update-resolv-conf
|
||||
# down /etc/openvpn/update-resolv-conf
|
||||
|
||||
[ "$script_type" ] || exit 0
|
||||
[ "$dev" ] || exit 0
|
||||
|
||||
PATH=$PATH:/usr/sbin/
|
||||
NMSRVRS=()
|
||||
SRCHS=()
|
||||
|
||||
# Get adapter list
|
||||
IFS=$'\n' read -d '' -ra adapters < <(networksetup -listallnetworkservices |grep -v denotes) || true
|
||||
|
||||
split_into_parts()
|
||||
{
|
||||
part1="$1"
|
||||
part2="$2"
|
||||
part3="$3"
|
||||
}
|
||||
|
||||
update_all_dns()
|
||||
{
|
||||
for adapter in "${adapters[@]}"
|
||||
do
|
||||
echo updating dns for $adapter
|
||||
# set dns server to the vpn dns server
|
||||
if [[ "${SRCHS[@]}" ]]; then
|
||||
networksetup -setsearchdomains "$adapter" "${SRCHS[@]}"
|
||||
fi
|
||||
if [[ "${NMSRVRS[@]}" ]]; then
|
||||
networksetup -setdnsservers "$adapter" "${NMSRVRS[@]}"
|
||||
fi
|
||||
done
|
||||
}
|
||||
|
||||
clear_all_dns()
|
||||
{
|
||||
for adapter in "${adapters[@]}"
|
||||
do
|
||||
echo updating dns for $adapter
|
||||
networksetup -setdnsservers "$adapter" empty
|
||||
networksetup -setsearchdomains "$adapter" empty
|
||||
done
|
||||
}
|
||||
|
||||
case "$script_type" in
|
||||
up)
|
||||
for optionvarname in ${!foreign_option_*} ; do
|
||||
option="${!optionvarname}"
|
||||
echo "$option"
|
||||
split_into_parts $option
|
||||
if [ "$part1" = "dhcp-option" ] ; then
|
||||
if [ "$part2" = "DNS" ] ; then
|
||||
NMSRVRS=(${NMSRVRS[@]} $part3)
|
||||
elif [ "$part2" = "DOMAIN" ] ; then
|
||||
SRCHS=(${SRCHS[@]} $part3)
|
||||
fi
|
||||
fi
|
||||
done
|
||||
update_all_dns
|
||||
;;
|
||||
down)
|
||||
clear_all_dns
|
||||
;;
|
||||
esac
|
||||
@@ -0,0 +1,191 @@
|
||||
; ****************************************************************************
|
||||
; * Copyright (C) 2002-2014 OpenVPN Technologies, Inc. *
|
||||
; * This program is free software; you can redistribute it and/or modify *
|
||||
; * it under the terms of the GNU General Public License version 2 *
|
||||
; * as published by the Free Software Foundation. *
|
||||
; ****************************************************************************
|
||||
|
||||
; SYNTAX CHECKER
|
||||
; cd \WINDDK\3790\tools\chkinf
|
||||
; chkinf c:\src\openvpn\tap-win32\i386\oemvista.inf
|
||||
; OUTPUT -> file:///c:/WINDDK/3790/tools/chkinf/htm/c%23+src+openvpn+tap-win32+i386+__OemWin2k.htm
|
||||
|
||||
; INSTALL/REMOVE DRIVER
|
||||
; tapinstall install OemVista.inf tapoas
|
||||
; tapinstall update OemVista.inf tapoas
|
||||
; tapinstall remove tapoas
|
||||
|
||||
;*********************************************************
|
||||
; Note to Developers:
|
||||
;
|
||||
; If you are bundling the TAP-Windows driver with your app,
|
||||
; you should try to rename it in such a way that it will
|
||||
; not collide with other instances of TAP-Windows defined
|
||||
; by other apps. Multiple versions of the TAP-Windows
|
||||
; driver, each installed by different apps, can coexist
|
||||
; on the same machine if you follow these guidelines.
|
||||
; NOTE: these instructions assume you are editing the
|
||||
; generated OemWin2k.inf file, not the source
|
||||
; OemWin2k.inf.in file which is preprocessed by winconfig
|
||||
; and uses macro definitions from settings.in.
|
||||
;
|
||||
; (1) Rename all tapXXXX instances in this file to
|
||||
; something different (use at least 5 characters
|
||||
; for this name!)
|
||||
; (2) Change the "!define TAP" definition in openvpn.nsi
|
||||
; to match what you changed tapXXXX to.
|
||||
; (3) Change TARGETNAME in SOURCES to match what you
|
||||
; changed tapXXXX to.
|
||||
; (4) Change TAP_COMPONENT_ID in common.h to match what
|
||||
; you changed tapXXXX to.
|
||||
; (5) Change SZDEPENDENCIES in service.h to match what
|
||||
; you changed tapXXXX to.
|
||||
; (6) Change DeviceDescription and Provider strings.
|
||||
; (7) Change PRODUCT_TAP_WIN_DEVICE_DESCRIPTION in constants.h to what you
|
||||
; set DeviceDescription to.
|
||||
;
|
||||
;*********************************************************
|
||||
|
||||
[Version]
|
||||
Signature = "$Windows NT$"
|
||||
CatalogFile = tap0901.cat
|
||||
ClassGUID = {4d36e972-e325-11ce-bfc1-08002be10318}
|
||||
Provider = %Provider%
|
||||
Class = Net
|
||||
|
||||
; This version number should match the version
|
||||
; number given in SOURCES.
|
||||
DriverVer=04/21/2016,9.00.00.21
|
||||
|
||||
[Strings]
|
||||
DeviceDescription = "TAP-Windows Adapter V9"
|
||||
Provider = "TAP-Windows Provider V9"
|
||||
|
||||
;----------------------------------------------------------------
|
||||
; Manufacturer + Product Section (Done)
|
||||
;----------------------------------------------------------------
|
||||
[Manufacturer]
|
||||
%Provider% = tap0901, NTamd64
|
||||
|
||||
[tap0901.NTamd64]
|
||||
%DeviceDescription% = tap0901.ndi, root\tap0901 ; Root enumerated
|
||||
%DeviceDescription% = tap0901.ndi, tap0901 ; Legacy
|
||||
|
||||
;---------------------------------------------------------------
|
||||
; Driver Section (Done)
|
||||
;---------------------------------------------------------------
|
||||
|
||||
;----------------- Characteristics ------------
|
||||
; NCF_PHYSICAL = 0x04
|
||||
; NCF_VIRTUAL = 0x01
|
||||
; NCF_SOFTWARE_ENUMERATED = 0x02
|
||||
; NCF_HIDDEN = 0x08
|
||||
; NCF_NO_SERVICE = 0x10
|
||||
; NCF_HAS_UI = 0x80
|
||||
;----------------- Characteristics ------------
|
||||
|
||||
[tap0901.ndi]
|
||||
CopyFiles = tap0901.driver, tap0901.files
|
||||
AddReg = tap0901.reg
|
||||
AddReg = tap0901.params.reg
|
||||
Characteristics =
|
||||
*IfType = 0x6 ; IF_TYPE_ETHERNET_CSMACD
|
||||
*MediaType = 0x0 ; NdisMedium802_3
|
||||
*PhysicalMediaType = 14 ; NdisPhysicalMedium802_3
|
||||
|
||||
[tap0901.ndi.Services]
|
||||
AddService = tap0901, 2, tap0901.service
|
||||
|
||||
[tap0901.reg]
|
||||
HKR, Ndi, Service, 0, "tap0901"
|
||||
HKR, Ndi\Interfaces, UpperRange, 0, "ndis5"
|
||||
HKR, Ndi\Interfaces, LowerRange, 0, "ethernet"
|
||||
HKR, , Manufacturer, 0, "%Provider%"
|
||||
HKR, , ProductName, 0, "%DeviceDescription%"
|
||||
|
||||
[tap0901.params.reg]
|
||||
HKR, Ndi\params\MTU, ParamDesc, 0, "MTU"
|
||||
HKR, Ndi\params\MTU, Type, 0, "int"
|
||||
HKR, Ndi\params\MTU, Default, 0, "1500"
|
||||
HKR, Ndi\params\MTU, Optional, 0, "0"
|
||||
HKR, Ndi\params\MTU, Min, 0, "100"
|
||||
HKR, Ndi\params\MTU, Max, 0, "1500"
|
||||
HKR, Ndi\params\MTU, Step, 0, "1"
|
||||
HKR, Ndi\params\MediaStatus, ParamDesc, 0, "Media Status"
|
||||
HKR, Ndi\params\MediaStatus, Type, 0, "enum"
|
||||
HKR, Ndi\params\MediaStatus, Default, 0, "0"
|
||||
HKR, Ndi\params\MediaStatus, Optional, 0, "0"
|
||||
HKR, Ndi\params\MediaStatus\enum, "0", 0, "Application Controlled"
|
||||
HKR, Ndi\params\MediaStatus\enum, "1", 0, "Always Connected"
|
||||
HKR, Ndi\params\MAC, ParamDesc, 0, "MAC Address"
|
||||
HKR, Ndi\params\MAC, Type, 0, "edit"
|
||||
HKR, Ndi\params\MAC, Optional, 0, "1"
|
||||
HKR, Ndi\params\AllowNonAdmin, ParamDesc, 0, "Non-Admin Access"
|
||||
HKR, Ndi\params\AllowNonAdmin, Type, 0, "enum"
|
||||
HKR, Ndi\params\AllowNonAdmin, Default, 0, "1"
|
||||
HKR, Ndi\params\AllowNonAdmin, Optional, 0, "0"
|
||||
HKR, Ndi\params\AllowNonAdmin\enum, "0", 0, "Not Allowed"
|
||||
HKR, Ndi\params\AllowNonAdmin\enum, "1", 0, "Allowed"
|
||||
|
||||
;----------------------------------------------------------------
|
||||
; Service Section
|
||||
;----------------------------------------------------------------
|
||||
|
||||
;---------- Service Type -------------
|
||||
; SERVICE_KERNEL_DRIVER = 0x01
|
||||
; SERVICE_WIN32_OWN_PROCESS = 0x10
|
||||
;---------- Service Type -------------
|
||||
|
||||
;---------- Start Mode ---------------
|
||||
; SERVICE_BOOT_START = 0x0
|
||||
; SERVICE_SYSTEM_START = 0x1
|
||||
; SERVICE_AUTO_START = 0x2
|
||||
; SERVICE_DEMAND_START = 0x3
|
||||
; SERVICE_DISABLED = 0x4
|
||||
;---------- Start Mode ---------------
|
||||
|
||||
[tap0901.service]
|
||||
DisplayName = %DeviceDescription%
|
||||
ServiceType = 1
|
||||
StartType = 3
|
||||
ErrorControl = 1
|
||||
LoadOrderGroup = NDIS
|
||||
ServiceBinary = %12%\tap0901.sys
|
||||
|
||||
;-----------------------------------------------------------------
|
||||
; File Installation
|
||||
;-----------------------------------------------------------------
|
||||
|
||||
;----------------- Copy Flags ------------
|
||||
; COPYFLG_NOSKIP = 0x02
|
||||
; COPYFLG_NOVERSIONCHECK = 0x04
|
||||
;----------------- Copy Flags ------------
|
||||
|
||||
; SourceDisksNames
|
||||
; diskid = description[, [tagfile] [, <unused>, subdir]]
|
||||
; 1 = "Intel Driver Disk 1",e100bex.sys,,
|
||||
|
||||
[SourceDisksNames]
|
||||
1 = %DeviceDescription%, tap0901.sys
|
||||
|
||||
; SourceDisksFiles
|
||||
; filename_on_source = diskID[, [subdir][, size]]
|
||||
; e100bex.sys = 1,, ; on distribution disk 1
|
||||
|
||||
[SourceDisksFiles]
|
||||
tap0901.sys = 1
|
||||
|
||||
[DestinationDirs]
|
||||
tap0901.files = 11
|
||||
tap0901.driver = 12
|
||||
|
||||
[tap0901.files]
|
||||
; TapPanel.cpl,,,6 ; COPYFLG_NOSKIP | COPYFLG_NOVERSIONCHECK
|
||||
; cipsrvr.exe,,,6 ; COPYFLG_NOSKIP | COPYFLG_NOVERSIONCHECK
|
||||
|
||||
[tap0901.driver]
|
||||
tap0901.sys,,,6 ; COPYFLG_NOSKIP | COPYFLG_NOVERSIONCHECK
|
||||
|
||||
;---------------------------------------------------------------
|
||||
; End
|
||||
;---------------------------------------------------------------
|
||||
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,4 @@
|
||||
extern "C"
|
||||
{
|
||||
void mainRouteIface(int argc, char **argv);
|
||||
}
|
||||
@@ -1,4 +1,5 @@
|
||||
#include "router_mac.h"
|
||||
#include "helper_route_mac.h"
|
||||
|
||||
#include <QProcess>
|
||||
|
||||
@@ -10,18 +11,44 @@ RouterMac &RouterMac::Instance()
|
||||
|
||||
bool RouterMac::routeAdd(const QString &ip, const QString &gw, QString mask)
|
||||
{
|
||||
// route add -host ip gw
|
||||
QProcess p;
|
||||
p.setProcessChannelMode(QProcess::MergedChannels);
|
||||
int argc = 5;
|
||||
char **argv = new char*[argc];
|
||||
|
||||
p.start("route", QStringList() << "add" << "-host" << ip << gw);
|
||||
p.waitForFinished();
|
||||
qDebug().noquote() << "OUTPUT routeAdd: " + p.readAll();
|
||||
bool ok = (p.exitCode() == 0);
|
||||
if (ok) {
|
||||
m_addedRoutes.append(ip);
|
||||
argv[0] = new char[std::string("route").length() + 1];
|
||||
strcpy(argv[0], std::string("route").c_str());
|
||||
|
||||
argv[1] = new char[std::string("add").length() + 1];
|
||||
strcpy(argv[1], std::string("add").c_str());
|
||||
|
||||
argv[2] = new char[6];
|
||||
strcpy(argv[2], std::string("-host").c_str());
|
||||
|
||||
argv[3] = new char[ip.toStdString().length() + 1];
|
||||
strcpy(argv[3], ip.toStdString().c_str());
|
||||
|
||||
argv[4] = new char[gw.toStdString().length() + 1];
|
||||
strcpy(argv[4], gw.toStdString().c_str());
|
||||
|
||||
mainRouteIface(argc, argv);
|
||||
|
||||
for (int i = 0; i < argc; i++) {
|
||||
delete [] argv[i];
|
||||
}
|
||||
return ok;
|
||||
delete[] argv;
|
||||
return true;
|
||||
|
||||
// // route add -host ip gw
|
||||
// QProcess p;
|
||||
// p.setProcessChannelMode(QProcess::MergedChannels);
|
||||
|
||||
// p.start("route", QStringList() << "add" << "-host" << ip << gw);
|
||||
// p.waitForFinished();
|
||||
// qDebug().noquote() << "OUTPUT routeAdd: " + p.readAll();
|
||||
// bool ok = (p.exitCode() == 0);
|
||||
// if (ok) {
|
||||
// m_addedRoutes.append(ip);
|
||||
// }
|
||||
// return ok;
|
||||
}
|
||||
|
||||
int RouterMac::routeAddList(const QString &gw, const QStringList &ips)
|
||||
@@ -47,13 +74,20 @@ bool RouterMac::clearSavedRoutes()
|
||||
|
||||
bool RouterMac::routeDelete(const QString &ip, const QString &gw)
|
||||
{
|
||||
if (ip == "0.0.0.0") {
|
||||
qDebug().noquote() << "Warning, trying to remove default route, skipping: " << ip << gw;
|
||||
return true;
|
||||
}
|
||||
|
||||
// route delete ip gw
|
||||
QProcess p;
|
||||
p.setProcessChannelMode(QProcess::MergedChannels);
|
||||
|
||||
p.start("route", QStringList() << "delete" << ip << gw);
|
||||
p.start("route", QStringList() << "delete" << ip);
|
||||
p.waitForFinished();
|
||||
qDebug().noquote() << "OUTPUT routeDelete: " + p.readAll();
|
||||
// skipping gw
|
||||
qDebug().noquote() << "routeDelete, skipping gw`: " << ip;
|
||||
qDebug().noquote() << "OUTPUT routeDelete: " << p.readAll();
|
||||
|
||||
return p.exitCode() == 0;
|
||||
}
|
||||
|
||||
@@ -45,9 +45,11 @@ LIBS += \
|
||||
macx {
|
||||
HEADERS += \
|
||||
router_mac.h
|
||||
helper_route_mac.h
|
||||
|
||||
SOURCES += \
|
||||
router_mac.cpp
|
||||
router_mac.cpp \
|
||||
helper_route_mac.c
|
||||
}
|
||||
|
||||
include(../src/qtservice.pri)
|
||||
|
||||
@@ -3,6 +3,7 @@
|
||||
#include <QRegularExpression>
|
||||
#include <QRegularExpressionMatchIterator>
|
||||
#include <QCoreApplication>
|
||||
#include <QOperatingSystemVersion>
|
||||
|
||||
#include "tapcontroller_win.h"
|
||||
|
||||
@@ -139,6 +140,10 @@ bool TapController::checkAndSetup()
|
||||
qDebug() << "TapController: Installing TAP driver...";
|
||||
bool ok = setupDriver();
|
||||
|
||||
if (QSysInfo::prettyProductName().contains("Server 2008")) {
|
||||
restartTapService();
|
||||
}
|
||||
|
||||
if (ok) qDebug() << "TapController: TAP driver successfully installed";
|
||||
else qDebug() << "TapController: Failed to install TAP driver";
|
||||
|
||||
@@ -253,7 +258,14 @@ bool TapController::checkOpenVpn()
|
||||
QString TapController::getTapInstallPath()
|
||||
{
|
||||
#ifdef Q_OS_WIN
|
||||
return qApp->applicationDirPath() + "\\tap\\"+ QSysInfo::currentCpuArchitecture() + "\\tapinstall.exe";
|
||||
|
||||
if (oldDriversRequired()) {
|
||||
return qApp->applicationDirPath() + "\\tap\\"+ QSysInfo::currentCpuArchitecture() + "_windows_7\\tapinstall.exe";
|
||||
}
|
||||
else {
|
||||
return qApp->applicationDirPath() + "\\tap\\"+ QSysInfo::currentCpuArchitecture() + "\\tapinstall.exe";
|
||||
}
|
||||
|
||||
// if (QSysInfo::currentCpuArchitecture() == "i386") {
|
||||
// return qApp->applicationDirPath() + "\\openvpn\\drivers_x32\\tapinstall.exe";
|
||||
// }
|
||||
@@ -269,16 +281,21 @@ QString TapController::getOpenVpnPath()
|
||||
{
|
||||
#ifdef Q_OS_WIN
|
||||
//return qApp->applicationDirPath() + "\\openvpn\\"+ QSysInfo::currentCpuArchitecture() + "\\openvpn.exe";
|
||||
return qApp->applicationDirPath() + "\\openvpn\\i386\\openvpn.exe";
|
||||
|
||||
//return qApp->applicationDirPath() + "\\openvpn\\bin\\openvpn.exe";
|
||||
return qApp->applicationDirPath() + "\\openvpn\\i386\\openvpn.exe";
|
||||
#endif
|
||||
return "";
|
||||
}
|
||||
|
||||
QString TapController::getTapDriverDir()
|
||||
{
|
||||
return qApp->applicationDirPath() + "\\tap\\"+ QSysInfo::currentCpuArchitecture() + "\\";
|
||||
if (oldDriversRequired()) {
|
||||
return qApp->applicationDirPath() + "\\tap\\"+ QSysInfo::currentCpuArchitecture() + "_windows_7\\";
|
||||
}
|
||||
else {
|
||||
return qApp->applicationDirPath() + "\\tap\\"+ QSysInfo::currentCpuArchitecture() + "\\";
|
||||
}
|
||||
|
||||
|
||||
// if (QSysInfo::currentCpuArchitecture() == "i386") {
|
||||
// return qApp->applicationDirPath() + "\\openvpn\\drivers_x32\\";
|
||||
@@ -310,9 +327,38 @@ bool TapController::removeDriver(const QString& tapInstanceId)
|
||||
}
|
||||
}
|
||||
|
||||
bool TapController::oldDriversRequired()
|
||||
{
|
||||
if (QOperatingSystemVersion::current() <= QOperatingSystemVersion::Windows7) return true;
|
||||
if (QSysInfo::prettyProductName().contains("Server 2008")) return true;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
bool TapController::restartTapService()
|
||||
{
|
||||
{
|
||||
QProcess tapRestartroc;
|
||||
tapRestartroc.start("net", QStringList() << "stop" << "TapiSrv");
|
||||
if(!tapRestartroc.waitForStarted()) return false;
|
||||
tapRestartroc.waitForFinished();
|
||||
}
|
||||
|
||||
{
|
||||
QProcess tapRestartroc;
|
||||
tapRestartroc.start("net", QStringList() << "start" << "TapiSrv");
|
||||
if(!tapRestartroc.waitForStarted()) return false;
|
||||
tapRestartroc.waitForFinished();
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool TapController::setupDriver()
|
||||
{
|
||||
//setupDriverCertificate();
|
||||
if (oldDriversRequired()) {
|
||||
setupDriverCertificate();
|
||||
}
|
||||
|
||||
QStringList tapList = getTapList();
|
||||
for (QString tap : tapList) {
|
||||
|
||||
@@ -35,6 +35,9 @@ private:
|
||||
static bool setupDriverCertificate();
|
||||
static bool removeDriver(const QString& tapInstanceId);
|
||||
|
||||
static bool oldDriversRequired();
|
||||
static bool restartTapService();
|
||||
|
||||
};
|
||||
|
||||
#endif // TAPCONTROLLER_H
|
||||
|
||||
Reference in New Issue
Block a user