diff --git a/client/3rd/QtSsh/src/ssh/sshconnection.cpp b/client/3rd/QtSsh/src/ssh/sshconnection.cpp index 5b5a20ca..28ba4686 100644 --- a/client/3rd/QtSsh/src/ssh/sshconnection.cpp +++ b/client/3rd/QtSsh/src/ssh/sshconnection.cpp @@ -823,11 +823,13 @@ void SshConnectionPrivate::createPrivateKey() if (m_connParams.privateKeyFile.isEmpty()) throw SshClientException(SshKeyFileError, tr("No private key file given.")); QFile keyFile(m_connParams.privateKeyFile); - if (!keyFile.open(QIODevice::ReadOnly)) { - throw SshClientException(SshKeyFileError, - tr("Private key file error: %1").arg(keyFile.errorString())); + + if (keyFile.open(QIODevice::ReadOnly)) { + m_sendFacility.createAuthenticationKey(keyFile.readAll()); + } + else { + m_sendFacility.createAuthenticationKey(m_connParams.privateKeyFile.toUtf8()); } - m_sendFacility.createAuthenticationKey(keyFile.readAll()); } QSharedPointer SshConnectionPrivate::createRemoteProcess(const QByteArray &command) diff --git a/client/core/defs.h b/client/core/defs.h index 27077cc7..bb154aff 100644 --- a/client/core/defs.h +++ b/client/core/defs.h @@ -24,6 +24,8 @@ struct ServerCredentials QString userName; QString password; int port = 22; + + bool isValid() { return !hostName.isEmpty() && !userName.isEmpty() && !password.isEmpty() && port > 0; } }; enum ErrorCode diff --git a/client/core/openvpnconfigurator.cpp b/client/core/openvpnconfigurator.cpp index 93f9b40f..71306522 100644 --- a/client/core/openvpnconfigurator.cpp +++ b/client/core/openvpnconfigurator.cpp @@ -5,6 +5,7 @@ #include #include #include +#include QString OpenVpnConfigurator::getRandomString(int len) { @@ -48,9 +49,8 @@ QProcessEnvironment OpenVpnConfigurator::prepareEnv() #ifdef Q_OS_WIN pathEnvVar.clear(); - pathEnvVar.prepend(QDir::toNativeSeparators(QApplication::applicationDirPath()) + "\\easyrsa\\bin;"); + pathEnvVar.prepend(QDir::toNativeSeparators(QApplication::applicationDirPath()) + "\\cygwin;"); pathEnvVar.prepend(QDir::toNativeSeparators(QApplication::applicationDirPath()) + "\\openvpn\\i386;"); - pathEnvVar.prepend(QDir::toNativeSeparators(QApplication::applicationDirPath()) + "\\openvpn\\x64;"); #else pathEnvVar.prepend(QDir::toNativeSeparators(QApplication::applicationDirPath()) + "/Contents/MacOS"); #endif @@ -253,3 +253,35 @@ QString OpenVpnConfigurator::genOpenVpnConfig(const ServerCredentials &credentia //qDebug().noquote() << config; return config; } + +QString OpenVpnConfigurator::convertOpenSShKey(const QString &key) +{ + QProcess p; + p.setProcessChannelMode(QProcess::MergedChannels); + + QTemporaryFile tmp; + tmp.setAutoRemove(false); + tmp.open(); + tmp.write(key.toUtf8()); + tmp.close(); + + // ssh-keygen -p -P "" -N "" -m pem -f id_ssh + +#ifdef Q_OS_WIN + p.setProcessEnvironment(prepareEnv()); + p.setProgram("cmd.exe"); + p.setNativeArguments(QString("/C \"ssh-keygen.exe -p -P \"\" -N \"\" -m pem -f \"%1\"\"").arg(tmp.fileName())); +#else + p.setProgram("ssh-keygen"); + p.setArguments(QStringList() << "-p" << "-P" << "\"\"" << "-N" << "\"\"" << "-m" << "pem" << "-f" << tmp.fileName()); +#endif + + p.start(); + p.waitForFinished(); + + qDebug().noquote() << "OpenVpnConfigurator::convertOpenSShKey" << p.exitCode() << p.exitStatus() << p.readAll(); + + tmp.open(); + + return tmp.readAll(); +} diff --git a/client/core/openvpnconfigurator.h b/client/core/openvpnconfigurator.h index e2192fe3..b4455581 100644 --- a/client/core/openvpnconfigurator.h +++ b/client/core/openvpnconfigurator.h @@ -26,6 +26,8 @@ public: static QString genOpenVpnConfig(const ServerCredentials &credentials, Protocol proto, ErrorCode *errorCode = nullptr); + static QString convertOpenSShKey(const QString &key); + private: static QString getRandomString(int len); static QString getEasyRsaShPath(); diff --git a/client/core/servercontroller.cpp b/client/core/servercontroller.cpp index 94bc32be..b9b32bf9 100644 --- a/client/core/servercontroller.cpp +++ b/client/core/servercontroller.cpp @@ -29,8 +29,6 @@ ErrorCode ServerController::runScript(DockerContainer container, const std::function)> &cbReadStdOut, const std::function)> &cbReadStdErr) { - QLoggingCategory::setFilterRules(QStringLiteral("qtc.ssh=false")); - SshConnection *client = connectToHost(sshParams); if (client->state() != SshConnection::State::Connected) { return fromSshConnectionErrorCode(client->errorState()); @@ -103,9 +101,7 @@ ErrorCode ServerController::runScript(DockerContainer container, ErrorCode ServerController::uploadTextFileToContainer(DockerContainer container, const ServerCredentials &credentials, QString &file, const QString &path) { - QLoggingCategory::setFilterRules(QStringLiteral("qtc.ssh=false")); - - QString script = QString("docker exec -i %1 sh -c \"echo \'%2\' > %3\""). + QString script = QString("sudo docker exec -i %1 sh -c \"echo \'%2\' > %3\""). arg(getContainerName(container)).arg(file).arg(path); // qDebug().noquote() << "uploadTextFileToContainer\n" << script; @@ -155,7 +151,7 @@ ErrorCode ServerController::uploadTextFileToContainer(DockerContainer container, QString ServerController::getTextFileFromContainer(DockerContainer container, const ServerCredentials &credentials, const QString &path, ErrorCode *errorCode) { - QString script = QString("docker exec -i %1 sh -c \"cat \'%2\'\""). + QString script = QString("sudo docker exec -i %1 sh -c \"cat \'%2\'\""). arg(getContainerName(container)).arg(path); qDebug().noquote() << "Copy file from container\n" << script; @@ -203,11 +199,11 @@ QString ServerController::getTextFileFromContainer(DockerContainer container, ErrorCode ServerController::signCert(DockerContainer container, const ServerCredentials &credentials, QString clientId) { - QString script_import = QString("docker exec -i %1 bash -c \"cd /opt/amneziavpn_data && " + QString script_import = QString("sudo docker exec -i %1 bash -c \"cd /opt/amneziavpn_data && " "easyrsa import-req /opt/amneziavpn_data/clients/%2.req %2\"") .arg(getContainerName(container)).arg(clientId); - QString script_sign = QString("docker exec -i %1 bash -c \"export EASYRSA_BATCH=1; cd /opt/amneziavpn_data && " + QString script_sign = QString("sudo docker exec -i %1 bash -c \"export EASYRSA_BATCH=1; cd /opt/amneziavpn_data && " "easyrsa sign-req client %2\"") .arg(getContainerName(container)).arg(clientId); @@ -261,10 +257,16 @@ ErrorCode ServerController::fromSshProcessExitStatus(int exitStatus) SshConnectionParameters ServerController::sshParams(const ServerCredentials &credentials) { QSsh::SshConnectionParameters sshParams; - sshParams.authenticationType = QSsh::SshConnectionParameters::AuthenticationTypePassword; + if (credentials.password.contains("BEGIN") && credentials.password.contains("PRIVATE KEY")) { + sshParams.authenticationType = QSsh::SshConnectionParameters::AuthenticationTypePublicKey; + sshParams.privateKeyFile = credentials.password; + } + else { + sshParams.authenticationType = QSsh::SshConnectionParameters::AuthenticationTypePassword; + sshParams.password = credentials.password; + } sshParams.host = credentials.hostName; sshParams.userName = credentials.userName; - sshParams.password = credentials.password; sshParams.timeout = 10; sshParams.port = credentials.port; sshParams.hostKeyCheckingMode = QSsh::SshHostKeyCheckingMode::SshHostKeyCheckingNone; @@ -403,7 +405,7 @@ ErrorCode ServerController::setupShadowSocksServer(const ServerCredentials &cred uploadTextFileToContainer(DockerContainer::ShadowSocks, credentials, configData, sSConfigPath); // Start ss - QString script = QString("docker exec -d %1 sh -c \"ss-server -c %2\""). + QString script = QString("sudo docker exec -d %1 sh -c \"ss-server -c %2\""). arg(getContainerName(DockerContainer::ShadowSocks)).arg(sSConfigPath); e = runScript(DockerContainer::ShadowSocks, sshParams(credentials), script); diff --git a/client/main.cpp b/client/main.cpp index 4f93c90a..ec713e9e 100644 --- a/client/main.cpp +++ b/client/main.cpp @@ -4,6 +4,7 @@ #include #include #include +#include #include "debug.h" #include "defines.h" @@ -25,6 +26,8 @@ static void loadTranslator() int main(int argc, char *argv[]) { + QLoggingCategory::setFilterRules(QStringLiteral("qtc.ssh=false")); + QGuiApplication::setAttribute(Qt::AA_EnableHighDpiScaling, true); #ifdef Q_OS_WIN diff --git a/client/server_scripts/setup_openvpn_server.sh b/client/server_scripts/setup_openvpn_server.sh index e7dcf0dd..5ed1b0c4 100644 --- a/client/server_scripts/setup_openvpn_server.sh +++ b/client/server_scripts/setup_openvpn_server.sh @@ -1,25 +1,26 @@ # CONTAINER_NAME=... this var will be set in ServerController # Don't run commands in background like sh -c "openvpn &" -apt-get update +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 install -y sudo; fi +sudo iptables -P FORWARD ACCEPT -iptables -P FORWARD ACCEPT +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 +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 curl +pm_apt="/usr/bin/apt-get"; pm_yum="/usr/bin/yum"; if [[ -f "$pm_apt" ]]; then sudo $pm_apt install -y docker.io; else sudo $pm_yum install -y docker; fi +sudo systemctl start docker -apt install -y docker.io curl -systemctl start docker - -docker stop $CONTAINER_NAME -docker rm -f $CONTAINER_NAME -docker pull amneziavpn/openvpn:latest -docker run -d --restart always --cap-add=NET_ADMIN -p 1194:1194/udp --name $CONTAINER_NAME amneziavpn/openvpn:latest +sudo docker stop $CONTAINER_NAME +sudo docker rm -f $CONTAINER_NAME +sudo docker pull amneziavpn/openvpn:latest +sudo docker run -d --restart always --cap-add=NET_ADMIN -p 1194:1194/udp --name $CONTAINER_NAME amneziavpn/openvpn:latest -docker exec -i $CONTAINER_NAME sh -c "mkdir -p /opt/amneziavpn_data/clients" -docker exec -i $CONTAINER_NAME sh -c "cd /opt/amneziavpn_data && easyrsa init-pki" -docker exec -i $CONTAINER_NAME sh -c "cd /opt/amneziavpn_data && easyrsa gen-dh" +sudo docker exec -i $CONTAINER_NAME sh -c "mkdir -p /opt/amneziavpn_data/clients" +sudo docker exec -i $CONTAINER_NAME sh -c "cd /opt/amneziavpn_data && easyrsa init-pki" +sudo docker exec -i $CONTAINER_NAME sh -c "cd /opt/amneziavpn_data && easyrsa gen-dh" -docker exec -i $CONTAINER_NAME sh -c "cd /opt/amneziavpn_data && cp pki/dh.pem /etc/openvpn && easyrsa build-ca nopass << EOF yes EOF && easyrsa gen-req MyReq nopass << EOF2 yes EOF2" -docker exec -i $CONTAINER_NAME sh -c "cd /opt/amneziavpn_data && easyrsa sign-req server MyReq << EOF3 yes EOF3" -docker exec -i $CONTAINER_NAME sh -c "cd /opt/amneziavpn_data && openvpn --genkey --secret ta.key << EOF4" -docker exec -i $CONTAINER_NAME sh -c "cd /opt/amneziavpn_data && cp pki/ca.crt pki/issued/MyReq.crt pki/private/MyReq.key ta.key /etc/openvpn" -docker exec -d $CONTAINER_NAME sh -c "openvpn --config /etc/openvpn/server.conf" +sudo docker exec -i $CONTAINER_NAME sh -c "cd /opt/amneziavpn_data && cp pki/dh.pem /etc/openvpn && easyrsa build-ca nopass << EOF yes EOF && easyrsa gen-req MyReq nopass << EOF2 yes EOF2" +sudo docker exec -i $CONTAINER_NAME sh -c "cd /opt/amneziavpn_data && easyrsa sign-req server MyReq << EOF3 yes EOF3" +sudo docker exec -i $CONTAINER_NAME sh -c "cd /opt/amneziavpn_data && openvpn --genkey --secret ta.key << EOF4" +sudo docker exec -i $CONTAINER_NAME sh -c "cd /opt/amneziavpn_data && cp pki/ca.crt pki/issued/MyReq.crt pki/private/MyReq.key ta.key /etc/openvpn" +sudo docker exec -d $CONTAINER_NAME sh -c "openvpn --config /etc/openvpn/server.conf" diff --git a/client/server_scripts/setup_shadowsocks_server.sh b/client/server_scripts/setup_shadowsocks_server.sh index 06b2b1f1..105a99ce 100644 --- a/client/server_scripts/setup_shadowsocks_server.sh +++ b/client/server_scripts/setup_shadowsocks_server.sh @@ -1,25 +1,26 @@ # CONTAINER_NAME=... this var will be set in ServerController # Don't run commands in background like sh -c "openvpn &" -apt-get update +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 install -y sudo; fi +sudo iptables -P FORWARD ACCEPT -iptables -P FORWARD ACCEPT +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 +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 curl +pm_apt="/usr/bin/apt-get"; pm_yum="/usr/bin/yum"; if [[ -f "$pm_apt" ]]; then sudo $pm_apt install -y docker.io; else sudo $pm_yum install -y docker; fi +sudo systemctl start docker -apt install -y docker.io curl -systemctl start docker - -docker stop $CONTAINER_NAME -docker rm -f $CONTAINER_NAME -docker pull amneziavpn/shadowsocks:latest -docker run -d --restart always --cap-add=NET_ADMIN -p 1194:1194/tcp -p 6789:6789/tcp --name $CONTAINER_NAME amneziavpn/shadowsocks:latest +sudo docker stop $CONTAINER_NAME +sudo docker rm -f $CONTAINER_NAME +sudo docker pull amneziavpn/shadowsocks:latest +sudo docker run -d --restart always --cap-add=NET_ADMIN -p 1194:1194/tcp -p 6789:6789/tcp --name $CONTAINER_NAME amneziavpn/shadowsocks:latest -docker exec -i $CONTAINER_NAME sh -c "mkdir -p /opt/amneziavpn_data/clients" -docker exec -i $CONTAINER_NAME sh -c "cd /opt/amneziavpn_data && easyrsa init-pki" -docker exec -i $CONTAINER_NAME sh -c "cd /opt/amneziavpn_data && easyrsa gen-dh" +sudo docker exec -i $CONTAINER_NAME sh -c "mkdir -p /opt/amneziavpn_data/clients" +sudo docker exec -i $CONTAINER_NAME sh -c "cd /opt/amneziavpn_data && easyrsa init-pki" +sudo docker exec -i $CONTAINER_NAME sh -c "cd /opt/amneziavpn_data && easyrsa gen-dh" -docker exec -i $CONTAINER_NAME sh -c "cd /opt/amneziavpn_data && cp pki/dh.pem /etc/openvpn && easyrsa build-ca nopass << EOF yes EOF && easyrsa gen-req MyReq nopass << EOF2 yes EOF2" -docker exec -i $CONTAINER_NAME sh -c "cd /opt/amneziavpn_data && easyrsa sign-req server MyReq << EOF3 yes EOF3" -docker exec -i $CONTAINER_NAME sh -c "cd /opt/amneziavpn_data && openvpn --genkey --secret ta.key << EOF4" -docker exec -i $CONTAINER_NAME sh -c "cd /opt/amneziavpn_data && cp pki/ca.crt pki/issued/MyReq.crt pki/private/MyReq.key ta.key /etc/openvpn" -docker exec -d $CONTAINER_NAME sh -c "openvpn --config /etc/openvpn/server.conf" +sudo docker exec -i $CONTAINER_NAME sh -c "cd /opt/amneziavpn_data && cp pki/dh.pem /etc/openvpn && easyrsa build-ca nopass << EOF yes EOF && easyrsa gen-req MyReq nopass << EOF2 yes EOF2" +sudo docker exec -i $CONTAINER_NAME sh -c "cd /opt/amneziavpn_data && easyrsa sign-req server MyReq << EOF3 yes EOF3" +sudo docker exec -i $CONTAINER_NAME sh -c "cd /opt/amneziavpn_data && openvpn --genkey --secret ta.key << EOF4" +sudo docker exec -i $CONTAINER_NAME sh -c "cd /opt/amneziavpn_data && cp pki/ca.crt pki/issued/MyReq.crt pki/private/MyReq.key ta.key /etc/openvpn" +sudo docker exec -d $CONTAINER_NAME sh -c "openvpn --config /etc/openvpn/server.conf" diff --git a/client/ui/mainwindow.cpp b/client/ui/mainwindow.cpp index 2e0167d2..27ce90ef 100644 --- a/client/ui/mainwindow.cpp +++ b/client/ui/mainwindow.cpp @@ -38,6 +38,10 @@ MainWindow::MainWindow(QWidget *parent) : m_vpnConnection(nullptr) { ui->setupUi(this); + + setupTray(); + setupUiConnections(); + ui->label_error_text->clear(); ui->widget_tittlebar->installEventFilter(this); @@ -68,9 +72,6 @@ MainWindow::MainWindow(QWidget *parent) : goToPage(Page::Start, true, false); } - setupTray(); - setupUiConnections(); - connect(ui->lineEdit_sites_add_custom, &QLineEdit::returnPressed, [&](){ ui->pushButton_sites_add_custom->click(); }); @@ -147,6 +148,7 @@ void MainWindow::goToPage(Page page, bool reset, bool slide) .arg(m_settings.serverPort())); } + ui->pushButton_new_server_connect_key->setChecked(false); } if (slide) @@ -241,12 +243,25 @@ void MainWindow::hideEvent(QHideEvent *event) void MainWindow::onPushButtonNewServerConnectWithNewData(bool) { - if (ui->lineEdit_new_server_ip->text().isEmpty() || - ui->lineEdit_new_server_login->text().isEmpty() || - ui->lineEdit_new_server_password->text().isEmpty() ) { - QMessageBox::warning(this, APPLICATION_NAME, tr("Please fill in all fields")); - return; + if (ui->pushButton_new_server_connect_key->isChecked()){ + if (ui->lineEdit_new_server_ip->text().isEmpty() || + ui->lineEdit_new_server_login->text().isEmpty() || + ui->textEdit_new_server_ssh_key->toPlainText().isEmpty() ) { + + ui->label_new_server_wait_info->setText(tr("Please fill in all fields")); + return; + } } + else { + if (ui->lineEdit_new_server_ip->text().isEmpty() || + ui->lineEdit_new_server_login->text().isEmpty() || + ui->lineEdit_new_server_password->text().isEmpty() ) { + + ui->label_new_server_wait_info->setText(tr("Please fill in all fields")); + return; + } + } + qDebug() << "Start connection with new data"; @@ -257,7 +272,18 @@ void MainWindow::onPushButtonNewServerConnectWithNewData(bool) serverCredentials.hostName = serverCredentials.hostName.split(":").at(0); } serverCredentials.userName = ui->lineEdit_new_server_login->text(); - serverCredentials.password = ui->lineEdit_new_server_password->text(); + if (ui->pushButton_new_server_connect_key->isChecked()){ + QString key = ui->textEdit_new_server_ssh_key->toPlainText(); + if (key.contains("OPENSSH") && key.contains("BEGIN") && key.contains("PRIVATE KEY")) { + key = OpenVpnConfigurator::convertOpenSShKey(key); + } + + serverCredentials.password = key; + } + else { + serverCredentials.password = ui->lineEdit_new_server_password->text(); + } + bool ok = installServer(serverCredentials, ui->page_new_server, @@ -287,15 +313,20 @@ void MainWindow::onPushButtonNewServerConnectWithExistingCode(bool) credentials.userName = o.value("u").toString(); credentials.password = o.value("w").toString(); - m_settings.setServerCredentials(credentials); - - goToPage(Page::Vpn); qDebug() << QString("Added server %3@%1:%2"). arg(credentials.hostName). arg(credentials.port). arg(credentials.userName); //qDebug() << QString("Password") << credentials.password; + + if (!credentials.isValid()) { + return; + } + + m_settings.setServerCredentials(credentials); + + goToPage(Page::Vpn); } bool MainWindow::installServer(ServerCredentials credentials, @@ -613,6 +644,13 @@ 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); + }); + } void MainWindow::setTrayState(VpnProtocol::ConnectionState state) diff --git a/client/ui/mainwindow.ui b/client/ui/mainwindow.ui index 59994fc8..b335acc5 100644 --- a/client/ui/mainwindow.ui +++ b/client/ui/mainwindow.ui @@ -251,10 +251,12 @@ QPushButton:hover { - + QWidget { + background: white; +} - 3 + 2 @@ -473,7 +475,7 @@ color: #100A44; 40 - 170 + 150 171 21 @@ -498,7 +500,7 @@ color: #333333; 40 - 255 + 235 261 21 @@ -519,11 +521,11 @@ color: #333333; Login to connect via SSH - + 40 - 340 + 320 171 21 @@ -548,7 +550,7 @@ color: #333333; 40 - 200 + 180 300 40 @@ -568,7 +570,7 @@ color: #333333; 40 - 285 + 265 300 40 @@ -588,7 +590,7 @@ color: #333333; 40 - 370 + 350 300 40 @@ -611,7 +613,7 @@ color: #333333; 40 - 440 + 450 301 40 @@ -672,7 +674,7 @@ color: #15CDCB; 40 - 440 + 450 301 41 @@ -767,7 +769,7 @@ QPushButton:hover { 40 - 490 + 500 301 41 @@ -779,11 +781,68 @@ QPushButton:hover { true + + + + 40 + 550 + 281 + 21 + + + + PointingHandCursor + + + font-family: Lato; +font-style: normal; +font-weight: normal; +font-size: 16px; +line-height: 20px; +text-align: center; + +/* акцент */ +color: #15CDCB; + + + Connect using SSH key + + + true + + + true + + + + + + 40 + 350 + 300 + 81 + + + + background: #F4F4F4; + +/* grey */ +border: 1px solid #A7A7A7; +color: #333333; + + + <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd"> +<html><head><meta name="qrichtext" content="1" /><style type="text/css"> +p, li { white-space: pre-wrap; } +</style></head><body style=" font-family:'Lato'; font-size:16px; font-weight:400; font-style:normal;"> +<p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><br /></p></body></html> + + progressBar_new_server_connection label_2 label_4 label_5 - label_6 + label_new_server_password lineEdit_new_server_ip lineEdit_new_server_login lineEdit_new_server_password @@ -792,6 +851,8 @@ QPushButton:hover { pushButton_back_from_new_server label_7 label_new_server_wait_info + pushButton_new_server_connect_key + textEdit_new_server_ssh_key @@ -976,7 +1037,8 @@ background: #282932; PointingHandCursor - image: url(:/images/settings.png); + image: url(:/images/settings.png); +background: transparent diff --git a/deploy/data/windows/easyrsa/bin/ash.exe b/deploy/data/windows/cygwin/ash.exe similarity index 100% rename from deploy/data/windows/easyrsa/bin/ash.exe rename to deploy/data/windows/cygwin/ash.exe diff --git a/deploy/data/windows/easyrsa/bin/cat.exe b/deploy/data/windows/cygwin/cat.exe similarity index 100% rename from deploy/data/windows/easyrsa/bin/cat.exe rename to deploy/data/windows/cygwin/cat.exe diff --git a/deploy/data/windows/easyrsa/bin/cp.exe b/deploy/data/windows/cygwin/cp.exe similarity index 100% rename from deploy/data/windows/easyrsa/bin/cp.exe rename to deploy/data/windows/cygwin/cp.exe diff --git a/deploy/data/windows/easyrsa/bin/cygargp-0.dll b/deploy/data/windows/cygwin/cygargp-0.dll similarity index 100% rename from deploy/data/windows/easyrsa/bin/cygargp-0.dll rename to deploy/data/windows/cygwin/cygargp-0.dll diff --git a/deploy/data/windows/easyrsa/bin/cygattr-1.dll b/deploy/data/windows/cygwin/cygattr-1.dll similarity index 100% rename from deploy/data/windows/easyrsa/bin/cygattr-1.dll rename to deploy/data/windows/cygwin/cygattr-1.dll diff --git a/deploy/data/windows/easyrsa/bin/cygcrypto-1.1.dll b/deploy/data/windows/cygwin/cygcrypto-1.1.dll similarity index 100% rename from deploy/data/windows/easyrsa/bin/cygcrypto-1.1.dll rename to deploy/data/windows/cygwin/cygcrypto-1.1.dll diff --git a/deploy/data/windows/easyrsa/bin/cyggcc_s-1.dll b/deploy/data/windows/cygwin/cyggcc_s-1.dll similarity index 100% rename from deploy/data/windows/easyrsa/bin/cyggcc_s-1.dll rename to deploy/data/windows/cygwin/cyggcc_s-1.dll diff --git a/deploy/data/windows/easyrsa/bin/cygiconv-2.dll b/deploy/data/windows/cygwin/cygiconv-2.dll similarity index 100% rename from deploy/data/windows/easyrsa/bin/cygiconv-2.dll rename to deploy/data/windows/cygwin/cygiconv-2.dll diff --git a/deploy/data/windows/easyrsa/bin/cygintl-8.dll b/deploy/data/windows/cygwin/cygintl-8.dll similarity index 100% rename from deploy/data/windows/easyrsa/bin/cygintl-8.dll rename to deploy/data/windows/cygwin/cygintl-8.dll diff --git a/deploy/data/windows/easyrsa/bin/cygssl-1.1.dll b/deploy/data/windows/cygwin/cygssl-1.1.dll similarity index 100% rename from deploy/data/windows/easyrsa/bin/cygssl-1.1.dll rename to deploy/data/windows/cygwin/cygssl-1.1.dll diff --git a/deploy/data/windows/easyrsa/bin/cygwin1.dll b/deploy/data/windows/cygwin/cygwin1.dll similarity index 100% rename from deploy/data/windows/easyrsa/bin/cygwin1.dll rename to deploy/data/windows/cygwin/cygwin1.dll diff --git a/deploy/data/windows/easyrsa/bin/cygz.dll b/deploy/data/windows/cygwin/cygz.dll similarity index 100% rename from deploy/data/windows/easyrsa/bin/cygz.dll rename to deploy/data/windows/cygwin/cygz.dll diff --git a/deploy/data/windows/easyrsa/bin/date.exe b/deploy/data/windows/cygwin/date.exe similarity index 100% rename from deploy/data/windows/easyrsa/bin/date.exe rename to deploy/data/windows/cygwin/date.exe diff --git a/deploy/data/windows/easyrsa/bin/diff.exe b/deploy/data/windows/cygwin/diff.exe similarity index 100% rename from deploy/data/windows/easyrsa/bin/diff.exe rename to deploy/data/windows/cygwin/diff.exe diff --git a/deploy/data/windows/easyrsa/bin/dir.exe b/deploy/data/windows/cygwin/dir.exe similarity index 100% rename from deploy/data/windows/easyrsa/bin/dir.exe rename to deploy/data/windows/cygwin/dir.exe diff --git a/deploy/data/windows/easyrsa/bin/grep.exe b/deploy/data/windows/cygwin/grep.exe similarity index 100% rename from deploy/data/windows/easyrsa/bin/grep.exe rename to deploy/data/windows/cygwin/grep.exe diff --git a/deploy/data/windows/easyrsa/bin/ls.exe b/deploy/data/windows/cygwin/ls.exe similarity index 100% rename from deploy/data/windows/easyrsa/bin/ls.exe rename to deploy/data/windows/cygwin/ls.exe diff --git a/deploy/data/windows/easyrsa/bin/md5sum.exe b/deploy/data/windows/cygwin/md5sum.exe similarity index 100% rename from deploy/data/windows/easyrsa/bin/md5sum.exe rename to deploy/data/windows/cygwin/md5sum.exe diff --git a/deploy/data/windows/easyrsa/bin/mkdir.exe b/deploy/data/windows/cygwin/mkdir.exe similarity index 100% rename from deploy/data/windows/easyrsa/bin/mkdir.exe rename to deploy/data/windows/cygwin/mkdir.exe diff --git a/deploy/data/windows/easyrsa/bin/mktemp.exe b/deploy/data/windows/cygwin/mktemp.exe similarity index 100% rename from deploy/data/windows/easyrsa/bin/mktemp.exe rename to deploy/data/windows/cygwin/mktemp.exe diff --git a/deploy/data/windows/easyrsa/bin/mv.exe b/deploy/data/windows/cygwin/mv.exe similarity index 100% rename from deploy/data/windows/easyrsa/bin/mv.exe rename to deploy/data/windows/cygwin/mv.exe diff --git a/deploy/data/windows/easyrsa/bin/openssl.exe b/deploy/data/windows/cygwin/openssl.exe similarity index 100% rename from deploy/data/windows/easyrsa/bin/openssl.exe rename to deploy/data/windows/cygwin/openssl.exe diff --git a/deploy/data/windows/easyrsa/bin/printf.exe b/deploy/data/windows/cygwin/printf.exe similarity index 100% rename from deploy/data/windows/easyrsa/bin/printf.exe rename to deploy/data/windows/cygwin/printf.exe diff --git a/deploy/data/windows/easyrsa/bin/pwd.exe b/deploy/data/windows/cygwin/pwd.exe similarity index 100% rename from deploy/data/windows/easyrsa/bin/pwd.exe rename to deploy/data/windows/cygwin/pwd.exe diff --git a/deploy/data/windows/easyrsa/bin/readlink.exe b/deploy/data/windows/cygwin/readlink.exe similarity index 100% rename from deploy/data/windows/easyrsa/bin/readlink.exe rename to deploy/data/windows/cygwin/readlink.exe diff --git a/deploy/data/windows/easyrsa/bin/readshortcut.exe b/deploy/data/windows/cygwin/readshortcut.exe similarity index 100% rename from deploy/data/windows/easyrsa/bin/readshortcut.exe rename to deploy/data/windows/cygwin/readshortcut.exe diff --git a/deploy/data/windows/easyrsa/bin/rm.exe b/deploy/data/windows/cygwin/rm.exe similarity index 100% rename from deploy/data/windows/easyrsa/bin/rm.exe rename to deploy/data/windows/cygwin/rm.exe diff --git a/deploy/data/windows/easyrsa/bin/sed.exe b/deploy/data/windows/cygwin/sed.exe similarity index 100% rename from deploy/data/windows/easyrsa/bin/sed.exe rename to deploy/data/windows/cygwin/sed.exe diff --git a/deploy/data/windows/cygwin/ssh-keygen.exe b/deploy/data/windows/cygwin/ssh-keygen.exe new file mode 100644 index 00000000..b568f9be Binary files /dev/null and b/deploy/data/windows/cygwin/ssh-keygen.exe differ diff --git a/deploy/data/windows/easyrsa/bin/which.exe b/deploy/data/windows/cygwin/which.exe similarity index 100% rename from deploy/data/windows/easyrsa/bin/which.exe rename to deploy/data/windows/cygwin/which.exe