forked from qt-creator/qt-creator
Ssh: Rename SshConnectionParameters into SshParameters
Move it to its own header. Get rid of SshConnection and SshConnectionManager, as they are not used anymore. Change-Id: I52fe20d7816ea57e7a7158ab2ae9565d50a76e21 Reviewed-by: Christian Kandeler <christian.kandeler@qt.io> Reviewed-by: <github-actions-qt-creator@cristianadam.eu>
This commit is contained in:
@@ -3,13 +3,7 @@ add_qtc_library(QtcSsh
|
||||
SOURCES
|
||||
ssh.qrc
|
||||
ssh_global.h
|
||||
sshconnection.cpp sshconnection.h
|
||||
sshconnectionmanager.cpp sshconnectionmanager.h
|
||||
sshkeycreationdialog.cpp sshkeycreationdialog.h sshkeycreationdialog.ui
|
||||
sshlogging.cpp sshlogging_p.h
|
||||
sshconnection.cpp sshconnection.h
|
||||
sshconnectionmanager.cpp sshconnectionmanager.h
|
||||
sshkeycreationdialog.cpp sshkeycreationdialog.h sshkeycreationdialog.ui
|
||||
sshlogging.cpp sshlogging_p.h
|
||||
sshparameters.cpp sshparameters.h
|
||||
sshsettings.cpp sshsettings.h
|
||||
)
|
||||
|
||||
@@ -18,15 +18,11 @@ Project {
|
||||
|
||||
files: [
|
||||
"ssh.qrc",
|
||||
"sshconnection.h",
|
||||
"sshconnection.cpp",
|
||||
"sshconnectionmanager.cpp",
|
||||
"sshconnectionmanager.h",
|
||||
"sshkeycreationdialog.cpp",
|
||||
"sshkeycreationdialog.h",
|
||||
"sshkeycreationdialog.ui",
|
||||
"sshlogging.cpp",
|
||||
"sshlogging_p.h",
|
||||
"sshparameters.cpp",
|
||||
"sshparameters.h",
|
||||
"sshsettings.cpp",
|
||||
"sshsettings.h",
|
||||
]
|
||||
|
||||
@@ -1,435 +0,0 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** Copyright (C) 2016 The Qt Company Ltd.
|
||||
** Contact: https://www.qt.io/licensing/
|
||||
**
|
||||
** This file is part of Qt Creator.
|
||||
**
|
||||
** Commercial License Usage
|
||||
** Licensees holding valid commercial Qt licenses may use this file in
|
||||
** accordance with the commercial license agreement provided with the
|
||||
** Software or, alternatively, in accordance with the terms contained in
|
||||
** a written agreement between you and The Qt Company. For licensing terms
|
||||
** and conditions see https://www.qt.io/terms-conditions. For further
|
||||
** information use the contact form at https://www.qt.io/contact-us.
|
||||
**
|
||||
** GNU General Public License Usage
|
||||
** Alternatively, this file may be used under the terms of the GNU
|
||||
** General Public License version 3 as published by the Free Software
|
||||
** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
|
||||
** included in the packaging of this file. Please review the following
|
||||
** information to ensure the GNU General Public License requirements will
|
||||
** be met: https://www.gnu.org/licenses/gpl-3.0.html.
|
||||
**
|
||||
****************************************************************************/
|
||||
|
||||
#include "sshconnection.h"
|
||||
|
||||
#include "sshlogging_p.h"
|
||||
#include "sshsettings.h"
|
||||
|
||||
#include <utils/environment.h>
|
||||
#include <utils/fileutils.h>
|
||||
#include <utils/hostosinfo.h>
|
||||
#include <utils/qtcassert.h>
|
||||
#include <utils/qtcprocess.h>
|
||||
|
||||
#include <QByteArrayList>
|
||||
#include <QTemporaryDir>
|
||||
#include <QTimer>
|
||||
|
||||
#include <memory>
|
||||
|
||||
/*!
|
||||
\class QSsh::SshConnection
|
||||
|
||||
\brief The SshConnection class provides an SSH connection via an OpenSSH client
|
||||
running in master mode.
|
||||
|
||||
It operates asynchronously (non-blocking) and is not thread-safe.
|
||||
|
||||
If connection sharing is turned off, the class operates as a simple factory
|
||||
for processes etc and "connecting" always succeeds. The actual connection
|
||||
is then established later, e.g. when starting the remote process.
|
||||
|
||||
*/
|
||||
|
||||
namespace QSsh {
|
||||
using namespace Internal;
|
||||
using namespace Utils;
|
||||
|
||||
SshConnectionParameters::SshConnectionParameters()
|
||||
{
|
||||
url.setPort(0);
|
||||
}
|
||||
|
||||
QStringList SshConnectionParameters::connectionOptions(const FilePath &binary) const
|
||||
{
|
||||
QString hostKeyCheckingString;
|
||||
switch (hostKeyCheckingMode) {
|
||||
case SshHostKeyCheckingNone:
|
||||
case SshHostKeyCheckingAllowNoMatch:
|
||||
// There is "accept-new" as well, but only since 7.6.
|
||||
hostKeyCheckingString = "no";
|
||||
break;
|
||||
case SshHostKeyCheckingStrict:
|
||||
hostKeyCheckingString = "yes";
|
||||
break;
|
||||
}
|
||||
|
||||
QStringList args{"-o", "StrictHostKeyChecking=" + hostKeyCheckingString,
|
||||
"-o", "Port=" + QString::number(port())};
|
||||
|
||||
if (!userName().isEmpty())
|
||||
args.append({"-o", "User=" + userName()});
|
||||
|
||||
const bool keyOnly = authenticationType ==
|
||||
SshConnectionParameters::AuthenticationTypeSpecificKey;
|
||||
if (keyOnly) {
|
||||
args << "-o" << "IdentitiesOnly=yes";
|
||||
args << "-i" << privateKeyFile.path();
|
||||
}
|
||||
if (keyOnly || SshSettings::askpassFilePath().isEmpty())
|
||||
args << "-o" << "BatchMode=yes";
|
||||
|
||||
bool useTimeout = timeout != 0;
|
||||
if (useTimeout && HostOsInfo::isWindowsHost()
|
||||
&& binary.toString().toLower().contains("/system32/")) {
|
||||
useTimeout = false;
|
||||
}
|
||||
if (useTimeout)
|
||||
args << "-o" << ("ConnectTimeout=" + QString::number(timeout));
|
||||
|
||||
return args;
|
||||
}
|
||||
|
||||
bool SshConnectionParameters::setupSshEnvironment(QtcProcess *process)
|
||||
{
|
||||
Environment env = process->controlEnvironment();
|
||||
if (env.size() == 0)
|
||||
env = Environment::systemEnvironment();
|
||||
const bool hasDisplay = env.hasKey("DISPLAY") && (env.value("DISPLAY") != QString(":0"));
|
||||
if (SshSettings::askpassFilePath().exists()) {
|
||||
env.set("SSH_ASKPASS", SshSettings::askpassFilePath().toUserOutput());
|
||||
|
||||
// OpenSSH only uses the askpass program if DISPLAY is set, regardless of the platform.
|
||||
if (!env.hasKey("DISPLAY"))
|
||||
env.set("DISPLAY", ":0");
|
||||
}
|
||||
process->setEnvironment(env);
|
||||
|
||||
// Otherwise, ssh will ignore SSH_ASKPASS and read from /dev/tty directly.
|
||||
process->setDisableUnixTerminal();
|
||||
return hasDisplay;
|
||||
}
|
||||
|
||||
|
||||
static inline bool equals(const SshConnectionParameters &p1, const SshConnectionParameters &p2)
|
||||
{
|
||||
return p1.url == p2.url
|
||||
&& p1.authenticationType == p2.authenticationType
|
||||
&& p1.privateKeyFile == p2.privateKeyFile
|
||||
&& p1.hostKeyCheckingMode == p2.hostKeyCheckingMode
|
||||
&& p1.x11DisplayName == p2.x11DisplayName
|
||||
&& p1.timeout == p2.timeout;
|
||||
}
|
||||
|
||||
bool operator==(const SshConnectionParameters &p1, const SshConnectionParameters &p2)
|
||||
{
|
||||
return equals(p1, p2);
|
||||
}
|
||||
|
||||
bool operator!=(const SshConnectionParameters &p1, const SshConnectionParameters &p2)
|
||||
{
|
||||
return !equals(p1, p2);
|
||||
}
|
||||
|
||||
struct SshConnection::SshConnectionPrivate
|
||||
{
|
||||
SshConnectionPrivate(const SshConnectionParameters &sshParameters)
|
||||
: connParams(sshParameters)
|
||||
{
|
||||
SshConnectionParameters::setupSshEnvironment(&masterProcess);
|
||||
}
|
||||
|
||||
QString fullProcessError()
|
||||
{
|
||||
QString error;
|
||||
if (masterProcess.exitStatus() != QProcess::NormalExit)
|
||||
error = masterProcess.errorString();
|
||||
const QByteArray stdErr = masterProcess.readAllStandardError();
|
||||
if (!stdErr.isEmpty()) {
|
||||
if (!error.isEmpty())
|
||||
error.append('\n');
|
||||
error.append(QString::fromLocal8Bit(stdErr));
|
||||
}
|
||||
return error;
|
||||
}
|
||||
|
||||
QString socketFilePath() const
|
||||
{
|
||||
QTC_ASSERT(masterSocketDir, return QString());
|
||||
return masterSocketDir->path() + "/cs";
|
||||
}
|
||||
|
||||
QStringList connectionOptions(const FilePath &binary) const
|
||||
{
|
||||
QStringList options = connParams.connectionOptions(binary);
|
||||
if (sharingEnabled)
|
||||
options << "-o" << ("ControlPath=" + socketFilePath());
|
||||
return options;
|
||||
}
|
||||
|
||||
QStringList connectionArgs(const FilePath &binary) const
|
||||
{
|
||||
return connectionOptions(binary) << connParams.host();
|
||||
}
|
||||
|
||||
const SshConnectionParameters connParams;
|
||||
QtcProcess masterProcess;
|
||||
QString errorString;
|
||||
std::unique_ptr<QTemporaryDir> masterSocketDir;
|
||||
State state = Unconnected;
|
||||
const bool sharingEnabled = SshSettings::connectionSharingEnabled();
|
||||
};
|
||||
|
||||
|
||||
SshConnection::SshConnection(const SshConnectionParameters &serverInfo, QObject *parent)
|
||||
: QObject(parent), d(new SshConnectionPrivate(serverInfo))
|
||||
{
|
||||
connect(&d->masterProcess, &QtcProcess::readyReadStandardOutput, [this] {
|
||||
const QByteArray reply = d->masterProcess.readAllStandardOutput();
|
||||
if (reply == "\n")
|
||||
emitConnected();
|
||||
});
|
||||
connect(&d->masterProcess, &QtcProcess::done, this, [this] {
|
||||
if (d->masterProcess.error() == QProcess::FailedToStart) {
|
||||
emitError(tr("Cannot establish SSH connection: Control process failed to start: %1")
|
||||
.arg(d->fullProcessError()));
|
||||
return;
|
||||
}
|
||||
if (d->state == Disconnecting) {
|
||||
emitDisconnected();
|
||||
return;
|
||||
}
|
||||
const QString procError = d->fullProcessError();
|
||||
QString errorMsg = tr("SSH connection failure.");
|
||||
if (!procError.isEmpty())
|
||||
errorMsg.append('\n').append(procError);
|
||||
emitError(errorMsg);
|
||||
});
|
||||
if (!d->connParams.x11DisplayName.isEmpty()) {
|
||||
Environment env = d->masterProcess.environment();
|
||||
env.set("DISPLAY", d->connParams.x11DisplayName);
|
||||
d->masterProcess.setEnvironment(env);
|
||||
}
|
||||
}
|
||||
|
||||
void SshConnection::connectToHost()
|
||||
{
|
||||
d->state = Connecting;
|
||||
QTimer::singleShot(0, this, &SshConnection::doConnectToHost);
|
||||
}
|
||||
|
||||
void SshConnection::disconnectFromHost()
|
||||
{
|
||||
switch (d->state) {
|
||||
case Connecting:
|
||||
case Connected:
|
||||
if (!d->sharingEnabled) {
|
||||
QTimer::singleShot(0, this, &SshConnection::emitDisconnected);
|
||||
return;
|
||||
}
|
||||
d->state = Disconnecting;
|
||||
if (HostOsInfo::isWindowsHost())
|
||||
d->masterProcess.kill();
|
||||
else
|
||||
d->masterProcess.terminate();
|
||||
break;
|
||||
case Unconnected:
|
||||
case Disconnecting:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
SshConnection::State SshConnection::state() const
|
||||
{
|
||||
return d->state;
|
||||
}
|
||||
|
||||
QString SshConnection::errorString() const
|
||||
{
|
||||
return d->errorString;
|
||||
}
|
||||
|
||||
SshConnectionParameters SshConnection::connectionParameters() const
|
||||
{
|
||||
return d->connParams;
|
||||
}
|
||||
|
||||
QStringList SshConnection::connectionOptions(const FilePath &binary) const
|
||||
{
|
||||
return d->connectionOptions(binary);
|
||||
}
|
||||
|
||||
bool SshConnection::sharingEnabled() const
|
||||
{
|
||||
return d->sharingEnabled;
|
||||
}
|
||||
|
||||
SshConnection::~SshConnection()
|
||||
{
|
||||
disconnect();
|
||||
disconnectFromHost();
|
||||
delete d;
|
||||
}
|
||||
|
||||
void SshConnection::doConnectToHost()
|
||||
{
|
||||
if (d->state != Connecting)
|
||||
return;
|
||||
const FilePath sshBinary = SshSettings::sshFilePath();
|
||||
if (!sshBinary.exists()) {
|
||||
emitError(tr("Cannot establish SSH connection: ssh binary \"%1\" does not exist.")
|
||||
.arg(sshBinary.toUserOutput()));
|
||||
return;
|
||||
}
|
||||
if (!d->sharingEnabled) {
|
||||
emitConnected();
|
||||
return;
|
||||
}
|
||||
d->masterSocketDir.reset(new QTemporaryDir);
|
||||
if (!d->masterSocketDir->isValid()) {
|
||||
emitError(tr("Cannot establish SSH connection: Failed to create temporary "
|
||||
"directory for control socket: %1")
|
||||
.arg(d->masterSocketDir->errorString()));
|
||||
return;
|
||||
}
|
||||
QStringList args = QStringList{"-M", "-N", "-o", "ControlPersist=no",
|
||||
"-o", "PermitLocalCommand=yes", // Enable local command
|
||||
"-o", "LocalCommand=echo"} // Local command is executed after successfully
|
||||
// connecting to the server. "echo" will print "\n"
|
||||
// on the process output if everything went fine.
|
||||
<< d->connectionArgs(sshBinary);
|
||||
if (!d->connParams.x11DisplayName.isEmpty())
|
||||
args.prepend("-X");
|
||||
qCDebug(sshLog) << "establishing connection:" << sshBinary.toUserOutput() << args;
|
||||
d->masterProcess.setCommand(CommandLine(sshBinary, args));
|
||||
d->masterProcess.start();
|
||||
}
|
||||
|
||||
void SshConnection::emitError(const QString &reason)
|
||||
{
|
||||
const State oldState = d->state;
|
||||
d->state = Unconnected;
|
||||
d->errorString = reason;
|
||||
emit errorOccurred();
|
||||
if (oldState == Connected)
|
||||
emitDisconnected();
|
||||
}
|
||||
|
||||
void SshConnection::emitConnected()
|
||||
{
|
||||
d->state = Connected;
|
||||
emit connected();
|
||||
}
|
||||
|
||||
void SshConnection::emitDisconnected()
|
||||
{
|
||||
d->state = Unconnected;
|
||||
emit disconnected();
|
||||
}
|
||||
|
||||
#ifdef WITH_TESTS
|
||||
namespace SshTest {
|
||||
const QString getHostFromEnvironment()
|
||||
{
|
||||
const QString host = QString::fromLocal8Bit(qgetenv("QTC_SSH_TEST_HOST"));
|
||||
if (host.isEmpty() && qEnvironmentVariableIsSet("QTC_SSH_TEST_DEFAULTS"))
|
||||
return QString("127.0.0.1");
|
||||
return host;
|
||||
}
|
||||
|
||||
quint16 getPortFromEnvironment()
|
||||
{
|
||||
const int port = qEnvironmentVariableIntValue("QTC_SSH_TEST_PORT");
|
||||
return port != 0 ? quint16(port) : 22;
|
||||
}
|
||||
|
||||
const QString getUserFromEnvironment()
|
||||
{
|
||||
return QString::fromLocal8Bit(qgetenv("QTC_SSH_TEST_USER"));
|
||||
}
|
||||
|
||||
const QString getKeyFileFromEnvironment()
|
||||
{
|
||||
const FilePath defaultKeyFile = FileUtils::homePath() / ".ssh/id_rsa";
|
||||
const QString keyFile = QString::fromLocal8Bit(qgetenv("QTC_SSH_TEST_KEYFILE"));
|
||||
if (keyFile.isEmpty()) {
|
||||
if (qEnvironmentVariableIsSet("QTC_SSH_TEST_DEFAULTS"))
|
||||
return defaultKeyFile.toString();
|
||||
}
|
||||
return keyFile;
|
||||
}
|
||||
|
||||
const QString userAtHost()
|
||||
{
|
||||
QString userMidFix = getUserFromEnvironment();
|
||||
if (!userMidFix.isEmpty())
|
||||
userMidFix.append('@');
|
||||
return userMidFix + getHostFromEnvironment();
|
||||
}
|
||||
|
||||
SshConnectionParameters getParameters()
|
||||
{
|
||||
SshConnectionParameters params;
|
||||
if (!qEnvironmentVariableIsSet("QTC_SSH_TEST_DEFAULTS")) {
|
||||
params.setUserName(getUserFromEnvironment());
|
||||
params.privateKeyFile = Utils::FilePath::fromUserInput(getKeyFileFromEnvironment());
|
||||
}
|
||||
params.setHost(getHostFromEnvironment());
|
||||
params.setPort(getPortFromEnvironment());
|
||||
params.timeout = 10;
|
||||
params.authenticationType = !params.privateKeyFile.isEmpty()
|
||||
? QSsh::SshConnectionParameters::AuthenticationTypeSpecificKey
|
||||
: QSsh::SshConnectionParameters::AuthenticationTypeAll;
|
||||
return params;
|
||||
}
|
||||
|
||||
bool checkParameters(const QSsh::SshConnectionParameters ¶ms)
|
||||
{
|
||||
if (qEnvironmentVariableIsSet("QTC_SSH_TEST_DEFAULTS"))
|
||||
return true;
|
||||
if (params.host().isEmpty()) {
|
||||
qWarning("No hostname provided. Set QTC_SSH_TEST_HOST.");
|
||||
return false;
|
||||
}
|
||||
if (params.userName().isEmpty())
|
||||
qWarning("No user name provided - test may fail with empty default. Set QTC_SSH_TEST_USER.");
|
||||
if (params.privateKeyFile.isEmpty()) {
|
||||
qWarning("No key file provided. Set QTC_SSH_TEST_KEYFILE.");
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
void printSetupHelp()
|
||||
{
|
||||
qInfo() << "\n\n"
|
||||
"In order to run this test properly it requires some setup (example for fedora):\n"
|
||||
"1. Run a server on the host to connect to:\n"
|
||||
" systemctl start sshd\n"
|
||||
"2. Create your own ssh key (needed only once). For fedora it needs ecdsa type:\n"
|
||||
" ssh-keygen -t ecdsa\n"
|
||||
"3. Make your public key known to the server (needed only once):\n"
|
||||
" ssh-copy-id -i [full path to your public key] [user@host]\n"
|
||||
"4. Set the env variables before executing test:\n"
|
||||
" QTC_SSH_TEST_HOST=127.0.0.1\n"
|
||||
" QTC_SSH_TEST_KEYFILE=[full path to your private key]\n"
|
||||
" QTC_SSH_TEST_USER=[your user name]\n";
|
||||
}
|
||||
|
||||
} // namespace SshTest
|
||||
#endif
|
||||
|
||||
} // namespace QSsh
|
||||
@@ -1,226 +0,0 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** Copyright (C) 2016 The Qt Company Ltd.
|
||||
** Contact: https://www.qt.io/licensing/
|
||||
**
|
||||
** This file is part of Qt Creator.
|
||||
**
|
||||
** Commercial License Usage
|
||||
** Licensees holding valid commercial Qt licenses may use this file in
|
||||
** accordance with the commercial license agreement provided with the
|
||||
** Software or, alternatively, in accordance with the terms contained in
|
||||
** a written agreement between you and The Qt Company. For licensing terms
|
||||
** and conditions see https://www.qt.io/terms-conditions. For further
|
||||
** information use the contact form at https://www.qt.io/contact-us.
|
||||
**
|
||||
** GNU General Public License Usage
|
||||
** Alternatively, this file may be used under the terms of the GNU
|
||||
** General Public License version 3 as published by the Free Software
|
||||
** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
|
||||
** included in the packaging of this file. Please review the following
|
||||
** information to ensure the GNU General Public License requirements will
|
||||
** be met: https://www.gnu.org/licenses/gpl-3.0.html.
|
||||
**
|
||||
****************************************************************************/
|
||||
|
||||
#include "sshconnectionmanager.h"
|
||||
|
||||
#include "sshconnection.h"
|
||||
#include "sshsettings.h"
|
||||
|
||||
#include <utils/qtcassert.h>
|
||||
|
||||
#include <QCoreApplication>
|
||||
#include <QHash>
|
||||
#include <QObject>
|
||||
#include <QThread>
|
||||
#include <QTimer>
|
||||
|
||||
namespace QSsh {
|
||||
namespace Internal {
|
||||
|
||||
class SshConnectionManagerPrivate : public QObject
|
||||
{
|
||||
public:
|
||||
SshConnectionManagerPrivate()
|
||||
{
|
||||
connect(&m_removalTimer, &QTimer::timeout,
|
||||
this, &SshConnectionManagerPrivate::removeInactiveConnections);
|
||||
m_removalTimer.start(SshSettings::connectionSharingTimeout() * 1000 * 60 / 2);
|
||||
}
|
||||
|
||||
~SshConnectionManagerPrivate() override
|
||||
{
|
||||
for (auto it = m_connections.cbegin(); it != m_connections.cend(); ++it) {
|
||||
SshConnection * const connection = it.key();
|
||||
const SshConnectionState &state = it.value();
|
||||
QTC_CHECK(state.refCount() == 0);
|
||||
QTC_CHECK(!state.isStale());
|
||||
disconnect(connection, nullptr, this, nullptr);
|
||||
delete connection;
|
||||
}
|
||||
}
|
||||
|
||||
SshConnection *acquireConnection(const SshConnectionParameters &sshParams)
|
||||
{
|
||||
if (SshSettings::connectionSharingEnabled()) {
|
||||
for (auto it = m_connections.begin(); it != m_connections.end(); ++it) {
|
||||
SshConnection * const connection = it.key();
|
||||
if (connection->connectionParameters() != sshParams)
|
||||
continue;
|
||||
|
||||
SshConnectionState &state = it.value();
|
||||
if (state.isStale())
|
||||
continue;
|
||||
|
||||
if (state.refCount() == 0 && connection->state() != SshConnection::Connected)
|
||||
continue;
|
||||
|
||||
state.ref();
|
||||
return connection;
|
||||
}
|
||||
}
|
||||
|
||||
SshConnection * const connection = new SshConnection(sshParams);
|
||||
if (SshSettings::connectionSharingEnabled()) {
|
||||
connect(connection, &SshConnection::disconnected,
|
||||
this, [this, connection] { cleanup(connection); });
|
||||
m_connections.insert(connection, {});
|
||||
}
|
||||
|
||||
return connection;
|
||||
}
|
||||
|
||||
void releaseConnection(SshConnection *connection)
|
||||
{
|
||||
auto it = m_connections.find(connection);
|
||||
bool doDelete = false;
|
||||
if (it == m_connections.end()) {
|
||||
QTC_ASSERT(!connection->sharingEnabled(), return);
|
||||
doDelete = true;
|
||||
} else {
|
||||
SshConnectionState &state = it.value();
|
||||
if (state.deref())
|
||||
return;
|
||||
|
||||
if (state.isStale() || connection->state() != SshConnection::Connected) {
|
||||
doDelete = true;
|
||||
m_connections.erase(it);
|
||||
}
|
||||
}
|
||||
|
||||
if (doDelete) {
|
||||
disconnect(connection, nullptr, this, nullptr);
|
||||
connection->deleteLater();
|
||||
}
|
||||
}
|
||||
|
||||
void forceNewConnection(const SshConnectionParameters &sshParams)
|
||||
{
|
||||
auto it = m_connections.begin();
|
||||
while (it != m_connections.end()) {
|
||||
SshConnection * const connection = it.key();
|
||||
if (connection->connectionParameters() != sshParams) {
|
||||
++it;
|
||||
continue;
|
||||
}
|
||||
|
||||
SshConnectionState &state = it.value();
|
||||
if (state.refCount()) {
|
||||
state.makeStale();
|
||||
++it;
|
||||
continue;
|
||||
}
|
||||
|
||||
disconnect(connection, nullptr, this, nullptr);
|
||||
delete connection;
|
||||
it = m_connections.erase(it);
|
||||
}
|
||||
}
|
||||
|
||||
private:
|
||||
void cleanup(SshConnection *connection)
|
||||
{
|
||||
auto it = m_connections.find(connection);
|
||||
if (it == m_connections.end())
|
||||
return;
|
||||
|
||||
SshConnectionState &state = it.value();
|
||||
if (state.refCount())
|
||||
return;
|
||||
|
||||
disconnect(connection, nullptr, this, nullptr);
|
||||
connection->deleteLater();
|
||||
m_connections.erase(it);
|
||||
}
|
||||
|
||||
void removeInactiveConnections()
|
||||
{
|
||||
auto it = m_connections.begin();
|
||||
while (it != m_connections.end()) {
|
||||
SshConnection * const connection = it.key();
|
||||
SshConnectionState &state = it.value();
|
||||
if (state.refCount() == 0 && state.scheduleForRemoval()) {
|
||||
disconnect(connection, nullptr, this, nullptr);
|
||||
connection->deleteLater();
|
||||
it = m_connections.erase(it);
|
||||
} else {
|
||||
++it;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private:
|
||||
struct SshConnectionState {
|
||||
void ref() { ++m_ref; m_scheduledForRemoval = false; }
|
||||
bool deref() { QTC_ASSERT(m_ref, return false); return --m_ref; }
|
||||
int refCount() const { return m_ref; }
|
||||
|
||||
void makeStale() { m_isStale = true; }
|
||||
bool isStale() const { return m_isStale; }
|
||||
|
||||
bool scheduleForRemoval()
|
||||
{
|
||||
const bool ret = m_scheduledForRemoval;
|
||||
m_scheduledForRemoval = true;
|
||||
return ret;
|
||||
}
|
||||
private:
|
||||
int m_ref = 1; // 0 means unacquired connection
|
||||
bool m_isStale = false;
|
||||
bool m_scheduledForRemoval = false;
|
||||
};
|
||||
|
||||
QHash<SshConnection *, SshConnectionState> m_connections;
|
||||
QTimer m_removalTimer;
|
||||
};
|
||||
|
||||
} // namespace Internal
|
||||
|
||||
SshConnectionManager::SshConnectionManager()
|
||||
: d(new Internal::SshConnectionManagerPrivate())
|
||||
{
|
||||
QTC_CHECK(QThread::currentThread() == qApp->thread());
|
||||
}
|
||||
|
||||
SshConnectionManager::~SshConnectionManager()
|
||||
{
|
||||
delete d;
|
||||
}
|
||||
|
||||
SshConnection *SshConnectionManager::acquireConnection(const SshConnectionParameters &sshParams)
|
||||
{
|
||||
return instance()->d->acquireConnection(sshParams);
|
||||
}
|
||||
|
||||
void SshConnectionManager::releaseConnection(SshConnection *connection)
|
||||
{
|
||||
instance()->d->releaseConnection(connection);
|
||||
}
|
||||
|
||||
void SshConnectionManager::forceNewConnection(const SshConnectionParameters &sshParams)
|
||||
{
|
||||
instance()->d->forceNewConnection(sshParams);
|
||||
}
|
||||
|
||||
} // namespace QSsh
|
||||
@@ -1,58 +0,0 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** Copyright (C) 2016 The Qt Company Ltd.
|
||||
** Contact: https://www.qt.io/licensing/
|
||||
**
|
||||
** This file is part of Qt Creator.
|
||||
**
|
||||
** Commercial License Usage
|
||||
** Licensees holding valid commercial Qt licenses may use this file in
|
||||
** accordance with the commercial license agreement provided with the
|
||||
** Software or, alternatively, in accordance with the terms contained in
|
||||
** a written agreement between you and The Qt Company. For licensing terms
|
||||
** and conditions see https://www.qt.io/terms-conditions. For further
|
||||
** information use the contact form at https://www.qt.io/contact-us.
|
||||
**
|
||||
** GNU General Public License Usage
|
||||
** Alternatively, this file may be used under the terms of the GNU
|
||||
** General Public License version 3 as published by the Free Software
|
||||
** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
|
||||
** included in the packaging of this file. Please review the following
|
||||
** information to ensure the GNU General Public License requirements will
|
||||
** be met: https://www.gnu.org/licenses/gpl-3.0.html.
|
||||
**
|
||||
****************************************************************************/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "ssh_global.h"
|
||||
|
||||
#include <utils/launcherinterface.h>
|
||||
#include <utils/singleton.h>
|
||||
|
||||
namespace QSsh {
|
||||
|
||||
class SshConnection;
|
||||
class SshConnectionParameters;
|
||||
|
||||
namespace Internal { class SshConnectionManagerPrivate; }
|
||||
|
||||
class QSSH_EXPORT SshConnectionManager final
|
||||
: public Utils::SingletonWithOptionalDependencies<SshConnectionManager,
|
||||
Utils::LauncherInterface>
|
||||
{
|
||||
public:
|
||||
static SshConnection *acquireConnection(const SshConnectionParameters &sshParams);
|
||||
static void releaseConnection(SshConnection *connection);
|
||||
// Make sure the next acquireConnection with the given parameters will return a new connection.
|
||||
static void forceNewConnection(const SshConnectionParameters &sshParams);
|
||||
|
||||
private:
|
||||
SshConnectionManager();
|
||||
~SshConnectionManager();
|
||||
|
||||
Internal::SshConnectionManagerPrivate *d;
|
||||
friend class Utils::SingletonWithOptionalDependencies<SshConnectionManager, Utils::LauncherInterface>;
|
||||
};
|
||||
|
||||
} // namespace QSsh
|
||||
@@ -1,32 +0,0 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** Copyright (C) 2016 The Qt Company Ltd.
|
||||
** Contact: https://www.qt.io/licensing/
|
||||
**
|
||||
** This file is part of Qt Creator.
|
||||
**
|
||||
** Commercial License Usage
|
||||
** Licensees holding valid commercial Qt licenses may use this file in
|
||||
** accordance with the commercial license agreement provided with the
|
||||
** Software or, alternatively, in accordance with the terms contained in
|
||||
** a written agreement between you and The Qt Company. For licensing terms
|
||||
** and conditions see https://www.qt.io/terms-conditions. For further
|
||||
** information use the contact form at https://www.qt.io/contact-us.
|
||||
**
|
||||
** GNU General Public License Usage
|
||||
** Alternatively, this file may be used under the terms of the GNU
|
||||
** General Public License version 3 as published by the Free Software
|
||||
** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
|
||||
** included in the packaging of this file. Please review the following
|
||||
** information to ensure the GNU General Public License requirements will
|
||||
** be met: https://www.gnu.org/licenses/gpl-3.0.html.
|
||||
**
|
||||
****************************************************************************/
|
||||
|
||||
#include "sshlogging_p.h"
|
||||
|
||||
namespace QSsh {
|
||||
namespace Internal {
|
||||
Q_LOGGING_CATEGORY(sshLog, "qtc.ssh", QtWarningMsg)
|
||||
} // namespace Internal
|
||||
} // namespace QSsh
|
||||
@@ -1,34 +0,0 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** Copyright (C) 2016 The Qt Company Ltd.
|
||||
** Contact: https://www.qt.io/licensing/
|
||||
**
|
||||
** This file is part of Qt Creator.
|
||||
**
|
||||
** Commercial License Usage
|
||||
** Licensees holding valid commercial Qt licenses may use this file in
|
||||
** accordance with the commercial license agreement provided with the
|
||||
** Software or, alternatively, in accordance with the terms contained in
|
||||
** a written agreement between you and The Qt Company. For licensing terms
|
||||
** and conditions see https://www.qt.io/terms-conditions. For further
|
||||
** information use the contact form at https://www.qt.io/contact-us.
|
||||
**
|
||||
** GNU General Public License Usage
|
||||
** Alternatively, this file may be used under the terms of the GNU
|
||||
** General Public License version 3 as published by the Free Software
|
||||
** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
|
||||
** included in the packaging of this file. Please review the following
|
||||
** information to ensure the GNU General Public License requirements will
|
||||
** be met: https://www.gnu.org/licenses/gpl-3.0.html.
|
||||
**
|
||||
****************************************************************************/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <QLoggingCategory>
|
||||
|
||||
namespace QSsh {
|
||||
namespace Internal {
|
||||
Q_DECLARE_LOGGING_CATEGORY(sshLog)
|
||||
} // namespace Internal
|
||||
} // namespace QSsh
|
||||
@@ -0,0 +1,222 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** Copyright (C) 2022 The Qt Company Ltd.
|
||||
** Contact: https://www.qt.io/licensing/
|
||||
**
|
||||
** This file is part of Qt Creator.
|
||||
**
|
||||
** Commercial License Usage
|
||||
** Licensees holding valid commercial Qt licenses may use this file in
|
||||
** accordance with the commercial license agreement provided with the
|
||||
** Software or, alternatively, in accordance with the terms contained in
|
||||
** a written agreement between you and The Qt Company. For licensing terms
|
||||
** and conditions see https://www.qt.io/terms-conditions. For further
|
||||
** information use the contact form at https://www.qt.io/contact-us.
|
||||
**
|
||||
** GNU General Public License Usage
|
||||
** Alternatively, this file may be used under the terms of the GNU
|
||||
** General Public License version 3 as published by the Free Software
|
||||
** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
|
||||
** included in the packaging of this file. Please review the following
|
||||
** information to ensure the GNU General Public License requirements will
|
||||
** be met: https://www.gnu.org/licenses/gpl-3.0.html.
|
||||
**
|
||||
****************************************************************************/
|
||||
|
||||
#include "sshparameters.h"
|
||||
|
||||
#include "sshsettings.h"
|
||||
|
||||
#include <utils/environment.h>
|
||||
#include <utils/fileutils.h>
|
||||
#include <utils/hostosinfo.h>
|
||||
#include <utils/qtcassert.h>
|
||||
#include <utils/qtcprocess.h>
|
||||
|
||||
#include <QDebug>
|
||||
|
||||
#include <memory>
|
||||
|
||||
using namespace Utils;
|
||||
|
||||
namespace QSsh {
|
||||
|
||||
SshParameters::SshParameters()
|
||||
{
|
||||
url.setPort(0);
|
||||
}
|
||||
|
||||
QStringList SshParameters::connectionOptions(const FilePath &binary) const
|
||||
{
|
||||
QString hostKeyCheckingString;
|
||||
switch (hostKeyCheckingMode) {
|
||||
case SshHostKeyCheckingNone:
|
||||
case SshHostKeyCheckingAllowNoMatch:
|
||||
// There is "accept-new" as well, but only since 7.6.
|
||||
hostKeyCheckingString = "no";
|
||||
break;
|
||||
case SshHostKeyCheckingStrict:
|
||||
hostKeyCheckingString = "yes";
|
||||
break;
|
||||
}
|
||||
|
||||
QStringList args{"-o", "StrictHostKeyChecking=" + hostKeyCheckingString,
|
||||
"-o", "Port=" + QString::number(port())};
|
||||
|
||||
if (!userName().isEmpty())
|
||||
args.append({"-o", "User=" + userName()});
|
||||
|
||||
const bool keyOnly = authenticationType ==
|
||||
SshParameters::AuthenticationTypeSpecificKey;
|
||||
if (keyOnly) {
|
||||
args << "-o" << "IdentitiesOnly=yes";
|
||||
args << "-i" << privateKeyFile.path();
|
||||
}
|
||||
if (keyOnly || SshSettings::askpassFilePath().isEmpty())
|
||||
args << "-o" << "BatchMode=yes";
|
||||
|
||||
bool useTimeout = timeout != 0;
|
||||
if (useTimeout && HostOsInfo::isWindowsHost()
|
||||
&& binary.toString().toLower().contains("/system32/")) {
|
||||
useTimeout = false;
|
||||
}
|
||||
if (useTimeout)
|
||||
args << "-o" << ("ConnectTimeout=" + QString::number(timeout));
|
||||
|
||||
return args;
|
||||
}
|
||||
|
||||
bool SshParameters::setupSshEnvironment(QtcProcess *process)
|
||||
{
|
||||
Environment env = process->controlEnvironment();
|
||||
if (env.size() == 0)
|
||||
env = Environment::systemEnvironment();
|
||||
const bool hasDisplay = env.hasKey("DISPLAY") && (env.value("DISPLAY") != QString(":0"));
|
||||
if (SshSettings::askpassFilePath().exists()) {
|
||||
env.set("SSH_ASKPASS", SshSettings::askpassFilePath().toUserOutput());
|
||||
|
||||
// OpenSSH only uses the askpass program if DISPLAY is set, regardless of the platform.
|
||||
if (!env.hasKey("DISPLAY"))
|
||||
env.set("DISPLAY", ":0");
|
||||
}
|
||||
process->setEnvironment(env);
|
||||
|
||||
// Otherwise, ssh will ignore SSH_ASKPASS and read from /dev/tty directly.
|
||||
process->setDisableUnixTerminal();
|
||||
return hasDisplay;
|
||||
}
|
||||
|
||||
|
||||
static inline bool equals(const SshParameters &p1, const SshParameters &p2)
|
||||
{
|
||||
return p1.url == p2.url
|
||||
&& p1.authenticationType == p2.authenticationType
|
||||
&& p1.privateKeyFile == p2.privateKeyFile
|
||||
&& p1.hostKeyCheckingMode == p2.hostKeyCheckingMode
|
||||
&& p1.x11DisplayName == p2.x11DisplayName
|
||||
&& p1.timeout == p2.timeout;
|
||||
}
|
||||
|
||||
bool operator==(const SshParameters &p1, const SshParameters &p2)
|
||||
{
|
||||
return equals(p1, p2);
|
||||
}
|
||||
|
||||
bool operator!=(const SshParameters &p1, const SshParameters &p2)
|
||||
{
|
||||
return !equals(p1, p2);
|
||||
}
|
||||
|
||||
#ifdef WITH_TESTS
|
||||
namespace SshTest {
|
||||
const QString getHostFromEnvironment()
|
||||
{
|
||||
const QString host = QString::fromLocal8Bit(qgetenv("QTC_SSH_TEST_HOST"));
|
||||
if (host.isEmpty() && qEnvironmentVariableIsSet("QTC_SSH_TEST_DEFAULTS"))
|
||||
return QString("127.0.0.1");
|
||||
return host;
|
||||
}
|
||||
|
||||
quint16 getPortFromEnvironment()
|
||||
{
|
||||
const int port = qEnvironmentVariableIntValue("QTC_SSH_TEST_PORT");
|
||||
return port != 0 ? quint16(port) : 22;
|
||||
}
|
||||
|
||||
const QString getUserFromEnvironment()
|
||||
{
|
||||
return QString::fromLocal8Bit(qgetenv("QTC_SSH_TEST_USER"));
|
||||
}
|
||||
|
||||
const QString getKeyFileFromEnvironment()
|
||||
{
|
||||
const FilePath defaultKeyFile = FileUtils::homePath() / ".ssh/id_rsa";
|
||||
const QString keyFile = QString::fromLocal8Bit(qgetenv("QTC_SSH_TEST_KEYFILE"));
|
||||
if (keyFile.isEmpty()) {
|
||||
if (qEnvironmentVariableIsSet("QTC_SSH_TEST_DEFAULTS"))
|
||||
return defaultKeyFile.toString();
|
||||
}
|
||||
return keyFile;
|
||||
}
|
||||
|
||||
const QString userAtHost()
|
||||
{
|
||||
QString userMidFix = getUserFromEnvironment();
|
||||
if (!userMidFix.isEmpty())
|
||||
userMidFix.append('@');
|
||||
return userMidFix + getHostFromEnvironment();
|
||||
}
|
||||
|
||||
SshParameters getParameters()
|
||||
{
|
||||
SshParameters params;
|
||||
if (!qEnvironmentVariableIsSet("QTC_SSH_TEST_DEFAULTS")) {
|
||||
params.setUserName(getUserFromEnvironment());
|
||||
params.privateKeyFile = FilePath::fromUserInput(getKeyFileFromEnvironment());
|
||||
}
|
||||
params.setHost(getHostFromEnvironment());
|
||||
params.setPort(getPortFromEnvironment());
|
||||
params.timeout = 10;
|
||||
params.authenticationType = !params.privateKeyFile.isEmpty()
|
||||
? QSsh::SshParameters::AuthenticationTypeSpecificKey
|
||||
: QSsh::SshParameters::AuthenticationTypeAll;
|
||||
return params;
|
||||
}
|
||||
|
||||
bool checkParameters(const QSsh::SshParameters ¶ms)
|
||||
{
|
||||
if (qEnvironmentVariableIsSet("QTC_SSH_TEST_DEFAULTS"))
|
||||
return true;
|
||||
if (params.host().isEmpty()) {
|
||||
qWarning("No hostname provided. Set QTC_SSH_TEST_HOST.");
|
||||
return false;
|
||||
}
|
||||
if (params.userName().isEmpty())
|
||||
qWarning("No user name provided - test may fail with empty default. Set QTC_SSH_TEST_USER.");
|
||||
if (params.privateKeyFile.isEmpty()) {
|
||||
qWarning("No key file provided. Set QTC_SSH_TEST_KEYFILE.");
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
void printSetupHelp()
|
||||
{
|
||||
qInfo() << "\n\n"
|
||||
"In order to run this test properly it requires some setup (example for fedora):\n"
|
||||
"1. Run a server on the host to connect to:\n"
|
||||
" systemctl start sshd\n"
|
||||
"2. Create your own ssh key (needed only once). For fedora it needs ecdsa type:\n"
|
||||
" ssh-keygen -t ecdsa\n"
|
||||
"3. Make your public key known to the server (needed only once):\n"
|
||||
" ssh-copy-id -i [full path to your public key] [user@host]\n"
|
||||
"4. Set the env variables before executing test:\n"
|
||||
" QTC_SSH_TEST_HOST=127.0.0.1\n"
|
||||
" QTC_SSH_TEST_KEYFILE=[full path to your private key]\n"
|
||||
" QTC_SSH_TEST_USER=[your user name]\n";
|
||||
}
|
||||
|
||||
} // namespace SshTest
|
||||
#endif
|
||||
|
||||
} // namespace QSsh
|
||||
@@ -1,6 +1,6 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** Copyright (C) 2016 The Qt Company Ltd.
|
||||
** Copyright (C) 2022 The Qt Company Ltd.
|
||||
** Contact: https://www.qt.io/licensing/
|
||||
**
|
||||
** This file is part of Qt Creator.
|
||||
@@ -29,14 +29,8 @@
|
||||
|
||||
#include <utils/filepath.h>
|
||||
|
||||
#include <QFlags>
|
||||
#include <QHostAddress>
|
||||
#include <QObject>
|
||||
#include <QString>
|
||||
#include <QUrl>
|
||||
|
||||
#include <memory>
|
||||
|
||||
namespace Utils { class QtcProcess; }
|
||||
|
||||
namespace QSsh {
|
||||
@@ -47,7 +41,7 @@ enum SshHostKeyCheckingMode {
|
||||
SshHostKeyCheckingAllowNoMatch,
|
||||
};
|
||||
|
||||
class QSSH_EXPORT SshConnectionParameters
|
||||
class QSSH_EXPORT SshParameters
|
||||
{
|
||||
public:
|
||||
enum AuthenticationType {
|
||||
@@ -55,7 +49,7 @@ public:
|
||||
AuthenticationTypeSpecificKey,
|
||||
};
|
||||
|
||||
SshConnectionParameters();
|
||||
SshParameters();
|
||||
|
||||
QString host() const { return url.host(); }
|
||||
quint16 port() const { return url.port(); }
|
||||
@@ -77,41 +71,8 @@ public:
|
||||
static bool setupSshEnvironment(Utils::QtcProcess *process);
|
||||
};
|
||||
|
||||
QSSH_EXPORT bool operator==(const SshConnectionParameters &p1, const SshConnectionParameters &p2);
|
||||
QSSH_EXPORT bool operator!=(const SshConnectionParameters &p1, const SshConnectionParameters &p2);
|
||||
|
||||
class QSSH_EXPORT SshConnection : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
enum State { Unconnected, Connecting, Connected, Disconnecting };
|
||||
|
||||
explicit SshConnection(const SshConnectionParameters &serverInfo, QObject *parent = nullptr);
|
||||
|
||||
void connectToHost();
|
||||
void disconnectFromHost();
|
||||
State state() const;
|
||||
QString errorString() const;
|
||||
SshConnectionParameters connectionParameters() const;
|
||||
QStringList connectionOptions(const Utils::FilePath &binary) const;
|
||||
bool sharingEnabled() const;
|
||||
~SshConnection();
|
||||
|
||||
signals:
|
||||
void connected();
|
||||
void disconnected();
|
||||
void errorOccurred();
|
||||
|
||||
private:
|
||||
void doConnectToHost();
|
||||
void emitError(const QString &reason);
|
||||
void emitConnected();
|
||||
void emitDisconnected();
|
||||
|
||||
struct SshConnectionPrivate;
|
||||
SshConnectionPrivate * const d;
|
||||
};
|
||||
QSSH_EXPORT bool operator==(const SshParameters &p1, const SshParameters &p2);
|
||||
QSSH_EXPORT bool operator!=(const SshParameters &p1, const SshParameters &p2);
|
||||
|
||||
#ifdef WITH_TESTS
|
||||
namespace SshTest {
|
||||
@@ -120,12 +81,12 @@ quint16 QSSH_EXPORT getPortFromEnvironment();
|
||||
const QString QSSH_EXPORT getUserFromEnvironment();
|
||||
const QString QSSH_EXPORT getKeyFileFromEnvironment();
|
||||
const QSSH_EXPORT QString userAtHost();
|
||||
SshConnectionParameters QSSH_EXPORT getParameters();
|
||||
bool QSSH_EXPORT checkParameters(const SshConnectionParameters ¶ms);
|
||||
SshParameters QSSH_EXPORT getParameters();
|
||||
bool QSSH_EXPORT checkParameters(const SshParameters ¶ms);
|
||||
void QSSH_EXPORT printSetupHelp();
|
||||
} // namespace SshTest
|
||||
#endif
|
||||
|
||||
} // namespace QSsh
|
||||
|
||||
Q_DECLARE_METATYPE(QSsh::SshConnectionParameters::AuthenticationType)
|
||||
Q_DECLARE_METATYPE(QSsh::SshParameters::AuthenticationType)
|
||||
@@ -63,8 +63,8 @@ SingletonStaticData &Singleton::staticData(std::type_index index)
|
||||
// Note: it's caller responsibility to ensure that this function is being called when all other
|
||||
// threads don't use any singleton. As a good practice: finish all other threads that were using
|
||||
// singletons before this function is called.
|
||||
// Some singletons (currently e.g. SshConnectionManager) can work only in main thread,
|
||||
// so this method should be called from main thread only.
|
||||
// Some singletons may work only in main thread, so this method should be called from main thread
|
||||
// only.
|
||||
void Singleton::deleteAll()
|
||||
{
|
||||
QTC_ASSERT(QThread::currentThread() == qApp->thread(), return);
|
||||
|
||||
@@ -35,8 +35,6 @@
|
||||
#include <utils/qtcassert.h>
|
||||
#include <utils/pathchooser.h>
|
||||
|
||||
#include <ssh/sshconnection.h>
|
||||
|
||||
#include <QComboBox>
|
||||
#include <QFormLayout>
|
||||
#include <QLineEdit>
|
||||
|
||||
@@ -36,7 +36,7 @@
|
||||
|
||||
#include <remotelinux/linuxprocessinterface.h>
|
||||
|
||||
#include <ssh/sshconnection.h>
|
||||
#include <ssh/sshparameters.h>
|
||||
|
||||
#include <utils/portlist.h>
|
||||
#include <utils/qtcassert.h>
|
||||
@@ -48,6 +48,7 @@
|
||||
#include <QWizard>
|
||||
|
||||
using namespace ProjectExplorer;
|
||||
using namespace QSsh;
|
||||
using namespace RemoteLinux;
|
||||
using namespace Utils;
|
||||
|
||||
@@ -178,12 +179,12 @@ void QdbDevice::setupDefaultNetworkSettings(const QString &host)
|
||||
{
|
||||
setFreePorts(Utils::PortList::fromString("10000-10100"));
|
||||
|
||||
QSsh::SshConnectionParameters parameters = sshParameters();
|
||||
SshParameters parameters = sshParameters();
|
||||
parameters.setHost(host);
|
||||
parameters.setUserName("root");
|
||||
parameters.setPort(22);
|
||||
parameters.timeout = 10;
|
||||
parameters.authenticationType = QSsh::SshConnectionParameters::AuthenticationTypeAll;
|
||||
parameters.authenticationType = SshParameters::AuthenticationTypeAll;
|
||||
setSshParameters(parameters);
|
||||
}
|
||||
|
||||
|
||||
@@ -31,8 +31,6 @@
|
||||
|
||||
#include <debugger/debuggerruncontrol.h>
|
||||
|
||||
#include <ssh/sshconnection.h>
|
||||
|
||||
#include <utils/algorithm.h>
|
||||
#include <utils/qtcprocess.h>
|
||||
#include <utils/url.h>
|
||||
|
||||
@@ -26,11 +26,13 @@
|
||||
#include "startremotedialog.h"
|
||||
|
||||
#include <coreplugin/icore.h>
|
||||
|
||||
#include <projectexplorer/devicesupport/idevice.h>
|
||||
#include <projectexplorer/kitchooser.h>
|
||||
#include <projectexplorer/kitinformation.h>
|
||||
#include <projectexplorer/runcontrol.h>
|
||||
#include <ssh/sshconnection.h>
|
||||
|
||||
#include <ssh/sshparameters.h>
|
||||
|
||||
#include <QDialogButtonBox>
|
||||
#include <QFormLayout>
|
||||
|
||||
@@ -25,20 +25,22 @@
|
||||
|
||||
#include "debuggerdialogs.h"
|
||||
|
||||
#include "cdb/cdbengine.h"
|
||||
#include "debuggerkitinformation.h"
|
||||
#include "debuggerruncontrol.h"
|
||||
#include "cdb/cdbengine.h"
|
||||
|
||||
#include <app/app_version.h>
|
||||
|
||||
#include <coreplugin/icore.h>
|
||||
|
||||
#include <projectexplorer/projectexplorerconstants.h>
|
||||
#include <projectexplorer/toolchain.h>
|
||||
|
||||
#include <app/app_version.h>
|
||||
#include <utils/pathchooser.h>
|
||||
#include <utils/fancylineedit.h>
|
||||
#include <utils/qtcassert.h>
|
||||
#include <ssh/sshparameters.h>
|
||||
|
||||
#include <ssh/sshconnection.h>
|
||||
#include <utils/fancylineedit.h>
|
||||
#include <utils/pathchooser.h>
|
||||
#include <utils/qtcassert.h>
|
||||
|
||||
#include <QButtonGroup>
|
||||
#include <QCheckBox>
|
||||
|
||||
@@ -101,7 +101,8 @@
|
||||
#include <projectexplorer/target.h>
|
||||
#include <projectexplorer/taskhub.h>
|
||||
#include <projectexplorer/toolchain.h>
|
||||
#include <ssh/sshconnection.h>
|
||||
|
||||
#include <ssh/sshparameters.h>
|
||||
|
||||
#include <texteditor/texteditor.h>
|
||||
#include <texteditor/textdocument.h>
|
||||
@@ -377,6 +378,7 @@ using namespace Debugger::Constants;
|
||||
using namespace Debugger::Internal;
|
||||
using namespace ExtensionSystem;
|
||||
using namespace ProjectExplorer;
|
||||
using namespace QSsh;
|
||||
using namespace TextEditor;
|
||||
using namespace Utils;
|
||||
|
||||
@@ -1835,7 +1837,7 @@ void DebuggerPluginPrivate::attachToQmlPort()
|
||||
qmlServer.setPort(dlg.port());
|
||||
debugger->setQmlServer(qmlServer);
|
||||
|
||||
QSsh::SshConnectionParameters sshParameters = device->sshParameters();
|
||||
SshParameters sshParameters = device->sshParameters();
|
||||
debugger->setRemoteChannel(sshParameters.host(), sshParameters.port());
|
||||
debugger->setStartMode(AttachToQmlServer);
|
||||
|
||||
|
||||
@@ -73,8 +73,6 @@
|
||||
|
||||
#include <qtsupport/qtkitinformation.h>
|
||||
|
||||
#include <ssh/sshconnection.h>
|
||||
|
||||
#include <QTcpServer>
|
||||
#include <QTimer>
|
||||
|
||||
|
||||
@@ -35,7 +35,6 @@
|
||||
#include <projectexplorer/devicesupport/idevice.h>
|
||||
#include <projectexplorer/kitinformation.h>
|
||||
#include <projectexplorer/target.h>
|
||||
#include <ssh/sshconnection.h>
|
||||
#include <utils/qtcprocess.h>
|
||||
|
||||
#include <QAction>
|
||||
|
||||
@@ -33,8 +33,6 @@
|
||||
#include <projectexplorer/projectexplorerconstants.h>
|
||||
#include <projectexplorer/runcontrol.h>
|
||||
|
||||
#include <ssh/sshconnection.h>
|
||||
|
||||
#include <utils/environment.h>
|
||||
#include <utils/hostosinfo.h>
|
||||
#include <utils/portlist.h>
|
||||
|
||||
@@ -69,4 +69,4 @@ private:
|
||||
Internal::DeviceFileSystemModelPrivate * const d;
|
||||
};
|
||||
|
||||
} // namespace QSsh;
|
||||
} // namespace ProjectExplorer;
|
||||
|
||||
@@ -25,16 +25,14 @@
|
||||
|
||||
#include "deviceusedportsgatherer.h"
|
||||
|
||||
#include <ssh/sshconnection.h>
|
||||
|
||||
#include <projectexplorer/devicesupport/idevice.h>
|
||||
#include <ssh/sshparameters.h>
|
||||
#include <utils/port.h>
|
||||
#include <utils/portlist.h>
|
||||
#include <utils/qtcassert.h>
|
||||
#include <utils/qtcprocess.h>
|
||||
#include <utils/url.h>
|
||||
|
||||
using namespace QSsh;
|
||||
using namespace Utils;
|
||||
|
||||
namespace ProjectExplorer {
|
||||
|
||||
@@ -34,7 +34,7 @@
|
||||
#include "../runconfiguration.h"
|
||||
|
||||
#include <coreplugin/icore.h>
|
||||
#include <ssh/sshconnection.h>
|
||||
#include <ssh/sshparameters.h>
|
||||
#include <utils/displayname.h>
|
||||
#include <utils/icon.h>
|
||||
#include <utils/portlist.h>
|
||||
@@ -100,6 +100,7 @@
|
||||
* Creates an identical copy of a device object.
|
||||
*/
|
||||
|
||||
using namespace QSsh;
|
||||
using namespace Utils;
|
||||
|
||||
namespace ProjectExplorer {
|
||||
@@ -130,8 +131,8 @@ const char HostKeyCheckingKey[] = "HostKeyChecking";
|
||||
const char DebugServerKey[] = "DebugServerKey";
|
||||
const char QmlRuntimeKey[] = "QmlsceneKey";
|
||||
|
||||
using AuthType = QSsh::SshConnectionParameters::AuthenticationType;
|
||||
const AuthType DefaultAuthType = QSsh::SshConnectionParameters::AuthenticationTypeAll;
|
||||
using AuthType = SshParameters::AuthenticationType;
|
||||
const AuthType DefaultAuthType = SshParameters::AuthenticationTypeAll;
|
||||
const IDevice::MachineType DefaultMachineType = IDevice::Hardware;
|
||||
|
||||
const int DefaultTimeout = 10;
|
||||
@@ -153,7 +154,7 @@ public:
|
||||
int version = 0; // This is used by devices that have been added by the SDK.
|
||||
|
||||
QReadWriteLock lock; // Currently used to protect sshParameters only
|
||||
QSsh::SshConnectionParameters sshParameters;
|
||||
SshParameters sshParameters;
|
||||
PortList freePorts;
|
||||
FilePath debugServerPath;
|
||||
FilePath debugDumperPath = Core::ICore::resourcePath("debugger/");
|
||||
@@ -633,16 +634,16 @@ void IDevice::fromMap(const QVariantMap &map)
|
||||
// Pre-4.9, the authentication enum used to have more values
|
||||
const int storedAuthType = map.value(QLatin1String(AuthKey), DefaultAuthType).toInt();
|
||||
const bool outdatedAuthType = storedAuthType
|
||||
> QSsh::SshConnectionParameters::AuthenticationTypeSpecificKey;
|
||||
> SshParameters::AuthenticationTypeSpecificKey;
|
||||
d->sshParameters.authenticationType = outdatedAuthType
|
||||
? QSsh::SshConnectionParameters::AuthenticationTypeAll
|
||||
? SshParameters::AuthenticationTypeAll
|
||||
: static_cast<AuthType>(storedAuthType);
|
||||
|
||||
d->sshParameters.privateKeyFile =
|
||||
FilePath::fromVariant(map.value(QLatin1String(KeyFileKey), defaultPrivateKeyFilePath()));
|
||||
d->sshParameters.timeout = map.value(QLatin1String(TimeoutKey), DefaultTimeout).toInt();
|
||||
d->sshParameters.hostKeyCheckingMode = static_cast<QSsh::SshHostKeyCheckingMode>
|
||||
(map.value(QLatin1String(HostKeyCheckingKey), QSsh::SshHostKeyCheckingNone).toInt());
|
||||
d->sshParameters.hostKeyCheckingMode = static_cast<SshHostKeyCheckingMode>
|
||||
(map.value(QLatin1String(HostKeyCheckingKey), SshHostKeyCheckingNone).toInt());
|
||||
|
||||
QString portsSpec = map.value(PortsSpecKey).toString();
|
||||
if (portsSpec.isEmpty())
|
||||
@@ -719,13 +720,13 @@ QString IDevice::deviceStateToString() const
|
||||
}
|
||||
}
|
||||
|
||||
QSsh::SshConnectionParameters IDevice::sshParameters() const
|
||||
SshParameters IDevice::sshParameters() const
|
||||
{
|
||||
QReadLocker locker(&d->lock);
|
||||
return d->sshParameters;
|
||||
}
|
||||
|
||||
void IDevice::setSshParameters(const QSsh::SshConnectionParameters &sshParameters)
|
||||
void IDevice::setSshParameters(const SshParameters &sshParameters)
|
||||
{
|
||||
QWriteLocker locker(&d->lock);
|
||||
d->sshParameters = sshParameters;
|
||||
|
||||
@@ -47,7 +47,7 @@ QT_BEGIN_NAMESPACE
|
||||
class QWidget;
|
||||
QT_END_NAMESPACE
|
||||
|
||||
namespace QSsh { class SshConnectionParameters; }
|
||||
namespace QSsh { class SshParameters; }
|
||||
|
||||
namespace Utils {
|
||||
class CommandLine;
|
||||
@@ -192,8 +192,8 @@ public:
|
||||
static QString defaultPrivateKeyFilePath();
|
||||
static QString defaultPublicKeyFilePath();
|
||||
|
||||
QSsh::SshConnectionParameters sshParameters() const;
|
||||
void setSshParameters(const QSsh::SshConnectionParameters &sshParameters);
|
||||
QSsh::SshParameters sshParameters() const;
|
||||
void setSshParameters(const QSsh::SshParameters &sshParameters);
|
||||
|
||||
enum ControlChannelHint { QmlControlChannel };
|
||||
virtual QUrl toolControlChannel(const ControlChannelHint &) const;
|
||||
|
||||
@@ -30,7 +30,6 @@
|
||||
#include <utils/qtcassert.h>
|
||||
#include <utils/qtcprocess.h>
|
||||
|
||||
using namespace QSsh;
|
||||
using namespace Utils;
|
||||
|
||||
namespace ProjectExplorer {
|
||||
|
||||
@@ -37,7 +37,7 @@
|
||||
|
||||
#include <docker/dockerconstants.h>
|
||||
|
||||
#include <ssh/sshconnection.h>
|
||||
#include <ssh/sshparameters.h>
|
||||
|
||||
#include <utils/algorithm.h>
|
||||
#include <utils/elidinglabel.h>
|
||||
|
||||
@@ -131,7 +131,6 @@
|
||||
#include <coreplugin/vcsmanager.h>
|
||||
#include <extensionsystem/pluginmanager.h>
|
||||
#include <extensionsystem/pluginspec.h>
|
||||
#include <ssh/sshconnection.h>
|
||||
#include <ssh/sshsettings.h>
|
||||
#include <texteditor/findinfiles.h>
|
||||
#include <texteditor/textdocument.h>
|
||||
@@ -190,6 +189,7 @@
|
||||
|
||||
using namespace Core;
|
||||
using namespace ProjectExplorer::Internal;
|
||||
using namespace QSsh;
|
||||
using namespace Utils;
|
||||
|
||||
namespace ProjectExplorer {
|
||||
@@ -2252,7 +2252,7 @@ void ProjectExplorerPlugin::extensionsInitialized()
|
||||
TaskHub::addCategory(Constants::TASK_CATEGORY_SANITIZER,
|
||||
tr("Sanitizer", "Category for sanitizer issues listed under 'Issues'"));
|
||||
|
||||
QSsh::SshSettings::loadSettings(Core::ICore::settings());
|
||||
SshSettings::loadSettings(Core::ICore::settings());
|
||||
const auto searchPathRetriever = [] {
|
||||
FilePaths searchPaths = {Core::ICore::libexecPath()};
|
||||
if (HostOsInfo::isWindowsHost()) {
|
||||
@@ -2271,7 +2271,7 @@ void ProjectExplorerPlugin::extensionsInitialized()
|
||||
}
|
||||
return searchPaths;
|
||||
};
|
||||
QSsh::SshSettings::setExtraSearchPathRetriever(searchPathRetriever);
|
||||
SshSettings::setExtraSearchPathRetriever(searchPathRetriever);
|
||||
|
||||
const auto parseIssuesAction = new QAction(tr("Parse Build Output..."), this);
|
||||
ActionContainer *mtools = ActionManager::actionContainer(Core::Constants::M_TOOLS);
|
||||
|
||||
@@ -71,8 +71,9 @@
|
||||
#include "journaldwatcher.h"
|
||||
#endif
|
||||
|
||||
using namespace Utils;
|
||||
using namespace ProjectExplorer::Internal;
|
||||
using namespace QSsh;
|
||||
using namespace Utils;
|
||||
|
||||
namespace {
|
||||
static Q_LOGGING_CATEGORY(statesLog, "qtc.projectmanager.states", QtWarningMsg)
|
||||
@@ -1119,7 +1120,7 @@ bool RunControl::showPromptToStopDialog(const QString &title,
|
||||
void RunControl::provideAskPassEntry(Environment &env)
|
||||
{
|
||||
if (env.value("SUDO_ASKPASS").isEmpty()) {
|
||||
const FilePath askpass = QSsh::SshSettings::askpassFilePath();
|
||||
const FilePath askpass = SshSettings::askpassFilePath();
|
||||
if (askpass.exists())
|
||||
env.set("SUDO_ASKPASS", askpass.toUserOutput());
|
||||
}
|
||||
|
||||
@@ -28,9 +28,11 @@
|
||||
#include "qnxconstants.h"
|
||||
|
||||
#include <remotelinux/genericlinuxdeviceconfigurationwizardpages.h>
|
||||
#include <ssh/sshparameters.h>
|
||||
#include <utils/portlist.h>
|
||||
|
||||
using namespace ProjectExplorer;
|
||||
using namespace QSsh;
|
||||
|
||||
namespace Qnx {
|
||||
namespace Internal {
|
||||
@@ -49,7 +51,7 @@ QnxDeviceWizard::QnxDeviceWizard(QWidget *parent) :
|
||||
setPage(KeyDeploymenPageId, m_keyDeploymentPage);
|
||||
setPage(FinalPageId, m_finalPage);
|
||||
m_finalPage->setCommitPage(true);
|
||||
QSsh::SshConnectionParameters sshParams;
|
||||
SshParameters sshParams;
|
||||
sshParams.timeout = 10;
|
||||
m_device = QnxDevice::create();
|
||||
m_device->setupId(IDevice::ManuallyAdded);
|
||||
|
||||
@@ -29,15 +29,12 @@
|
||||
#include <projectexplorer/devicesupport/idevice.h>
|
||||
#include <projectexplorer/kitinformation.h>
|
||||
#include <projectexplorer/target.h>
|
||||
|
||||
#include <ssh/sshconnection.h>
|
||||
#include <ssh/sshconnectionmanager.h>
|
||||
#include <ssh/sshparameters.h>
|
||||
|
||||
#include <QDateTime>
|
||||
|
||||
using namespace ProjectExplorer;
|
||||
using namespace Utils;
|
||||
using namespace QSsh;
|
||||
|
||||
namespace RemoteLinux {
|
||||
|
||||
|
||||
@@ -29,7 +29,7 @@
|
||||
#include "linuxdevice.h"
|
||||
|
||||
#include <projectexplorer/devicesupport/devicemanager.h>
|
||||
#include <ssh/sshconnection.h>
|
||||
#include <ssh/sshparameters.h>
|
||||
#include <utils/filepath.h>
|
||||
#include <utils/processinterface.h>
|
||||
|
||||
@@ -40,6 +40,7 @@
|
||||
#include <QTimer>
|
||||
|
||||
using namespace ProjectExplorer;
|
||||
using namespace QSsh;
|
||||
using namespace Utils;
|
||||
|
||||
namespace RemoteLinux {
|
||||
@@ -49,7 +50,7 @@ static const char TEST_DIR[] = "/tmp/testdir";
|
||||
|
||||
static const FilePath baseFilePath()
|
||||
{
|
||||
return FilePath::fromString("ssh://" + QSsh::SshTest::userAtHost() + QString(TEST_DIR));
|
||||
return FilePath::fromString("ssh://" + SshTest::userAtHost() + QString(TEST_DIR));
|
||||
}
|
||||
|
||||
TestLinuxDeviceFactory::TestLinuxDeviceFactory()
|
||||
@@ -63,7 +64,7 @@ TestLinuxDeviceFactory::TestLinuxDeviceFactory()
|
||||
device->setupId(IDevice::ManuallyAdded);
|
||||
device->setType("test");
|
||||
qDebug() << "device : " << device->type();
|
||||
device->setSshParameters(QSsh::SshTest::getParameters());
|
||||
device->setSshParameters(SshTest::getParameters());
|
||||
return device;
|
||||
});
|
||||
}
|
||||
@@ -71,22 +72,22 @@ TestLinuxDeviceFactory::TestLinuxDeviceFactory()
|
||||
FilePath createFile(const QString &name)
|
||||
{
|
||||
FilePath testFilePath = baseFilePath() / name;
|
||||
FilePath dummyFilePath = FilePath::fromString("ssh://" + QSsh::SshTest::userAtHost() + "/dev/null");
|
||||
FilePath dummyFilePath = FilePath::fromString("ssh://" + SshTest::userAtHost() + "/dev/null");
|
||||
dummyFilePath.copyFile(testFilePath);
|
||||
return testFilePath;
|
||||
}
|
||||
|
||||
void FileSystemAccessTest::initTestCase()
|
||||
{
|
||||
const QSsh::SshConnectionParameters params = QSsh::SshTest::getParameters();
|
||||
const SshParameters params = SshTest::getParameters();
|
||||
qDebug() << "Using following SSH parameter:"
|
||||
<< "\nHost:" << params.host()
|
||||
<< "\nPort:" << params.port()
|
||||
<< "\nUser:" << params.userName()
|
||||
<< "\nSSHKey:" << params.privateKeyFile;
|
||||
if (!QSsh::SshTest::checkParameters(params)) {
|
||||
if (!SshTest::checkParameters(params)) {
|
||||
m_skippedAtWhole = true;
|
||||
QSsh::SshTest::printSetupHelp();
|
||||
SshTest::printSetupHelp();
|
||||
QSKIP("Ensure you have added your default ssh public key to your own authorized keys and "
|
||||
"environment QTC_REMOTELINUX_SSH_DEFAULTS set or follow setup help above.");
|
||||
return;
|
||||
@@ -181,7 +182,7 @@ void FileSystemAccessTest::testDirStatus()
|
||||
|
||||
void FileSystemAccessTest::testBytesAvailable()
|
||||
{
|
||||
FilePath testFilePath = FilePath::fromString("ssh://" + QSsh::SshTest::userAtHost() + "/tmp");
|
||||
FilePath testFilePath = FilePath::fromString("ssh://" + SshTest::userAtHost() + "/tmp");
|
||||
QVERIFY(testFilePath.exists());
|
||||
QVERIFY(testFilePath.bytesAvailable() > 0);
|
||||
}
|
||||
|
||||
@@ -43,7 +43,6 @@
|
||||
#include <QString>
|
||||
|
||||
using namespace ProjectExplorer;
|
||||
using namespace QSsh;
|
||||
using namespace Utils;
|
||||
|
||||
namespace RemoteLinux {
|
||||
|
||||
@@ -31,7 +31,7 @@
|
||||
#include <utils/portlist.h>
|
||||
#include <utils/fancylineedit.h>
|
||||
#include <utils/utilsicons.h>
|
||||
#include <ssh/sshconnection.h>
|
||||
#include <ssh/sshparameters.h>
|
||||
#include <ssh/sshkeycreationdialog.h>
|
||||
|
||||
using namespace ProjectExplorer;
|
||||
@@ -83,11 +83,11 @@ GenericLinuxDeviceConfigurationWidget::~GenericLinuxDeviceConfigurationWidget()
|
||||
|
||||
void GenericLinuxDeviceConfigurationWidget::authenticationTypeChanged()
|
||||
{
|
||||
SshConnectionParameters sshParams = device()->sshParameters();
|
||||
SshParameters sshParams = device()->sshParameters();
|
||||
const bool useKeyFile = m_ui->keyButton->isChecked();
|
||||
sshParams.authenticationType = useKeyFile
|
||||
? SshConnectionParameters::AuthenticationTypeSpecificKey
|
||||
: SshConnectionParameters::AuthenticationTypeAll;
|
||||
? SshParameters::AuthenticationTypeSpecificKey
|
||||
: SshParameters::AuthenticationTypeAll;
|
||||
device()->setSshParameters(sshParams);
|
||||
m_ui->keyFileLineEdit->setEnabled(useKeyFile);
|
||||
m_ui->keyLabel->setEnabled(useKeyFile);
|
||||
@@ -95,35 +95,35 @@ void GenericLinuxDeviceConfigurationWidget::authenticationTypeChanged()
|
||||
|
||||
void GenericLinuxDeviceConfigurationWidget::hostNameEditingFinished()
|
||||
{
|
||||
SshConnectionParameters sshParams = device()->sshParameters();
|
||||
SshParameters sshParams = device()->sshParameters();
|
||||
sshParams.setHost(m_ui->hostLineEdit->text().trimmed());
|
||||
device()->setSshParameters(sshParams);
|
||||
}
|
||||
|
||||
void GenericLinuxDeviceConfigurationWidget::sshPortEditingFinished()
|
||||
{
|
||||
SshConnectionParameters sshParams = device()->sshParameters();
|
||||
SshParameters sshParams = device()->sshParameters();
|
||||
sshParams.setPort(m_ui->sshPortSpinBox->value());
|
||||
device()->setSshParameters(sshParams);
|
||||
}
|
||||
|
||||
void GenericLinuxDeviceConfigurationWidget::timeoutEditingFinished()
|
||||
{
|
||||
SshConnectionParameters sshParams = device()->sshParameters();
|
||||
SshParameters sshParams = device()->sshParameters();
|
||||
sshParams.timeout = m_ui->timeoutSpinBox->value();
|
||||
device()->setSshParameters(sshParams);
|
||||
}
|
||||
|
||||
void GenericLinuxDeviceConfigurationWidget::userNameEditingFinished()
|
||||
{
|
||||
SshConnectionParameters sshParams = device()->sshParameters();
|
||||
SshParameters sshParams = device()->sshParameters();
|
||||
sshParams.setUserName(m_ui->userLineEdit->text());
|
||||
device()->setSshParameters(sshParams);
|
||||
}
|
||||
|
||||
void GenericLinuxDeviceConfigurationWidget::keyFileEditingFinished()
|
||||
{
|
||||
SshConnectionParameters sshParams = device()->sshParameters();
|
||||
SshParameters sshParams = device()->sshParameters();
|
||||
sshParams.privateKeyFile = m_ui->keyFileLineEdit->filePath();
|
||||
device()->setSshParameters(sshParams);
|
||||
}
|
||||
@@ -154,7 +154,7 @@ void GenericLinuxDeviceConfigurationWidget::createNewKey()
|
||||
|
||||
void GenericLinuxDeviceConfigurationWidget::hostKeyCheckingChanged(bool doCheck)
|
||||
{
|
||||
SshConnectionParameters sshParams = device()->sshParameters();
|
||||
SshParameters sshParams = device()->sshParameters();
|
||||
sshParams.hostKeyCheckingMode
|
||||
= doCheck ? SshHostKeyCheckingAllowNoMatch : SshHostKeyCheckingNone;
|
||||
device()->setSshParameters(sshParams);
|
||||
@@ -192,13 +192,13 @@ void GenericLinuxDeviceConfigurationWidget::initGui()
|
||||
= new QRegularExpressionValidator(QRegularExpression(PortList::regularExpression()), this);
|
||||
m_ui->portsLineEdit->setValidator(portsValidator);
|
||||
|
||||
const SshConnectionParameters &sshParams = device()->sshParameters();
|
||||
const SshParameters &sshParams = device()->sshParameters();
|
||||
|
||||
switch (sshParams.authenticationType) {
|
||||
case SshConnectionParameters::AuthenticationTypeSpecificKey:
|
||||
case SshParameters::AuthenticationTypeSpecificKey:
|
||||
m_ui->keyButton->setChecked(true);
|
||||
break;
|
||||
case SshConnectionParameters::AuthenticationTypeAll:
|
||||
case SshParameters::AuthenticationTypeAll:
|
||||
m_ui->defaultAuthButton->setChecked(true);
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -30,6 +30,7 @@
|
||||
#include "remotelinux_constants.h"
|
||||
|
||||
#include <projectexplorer/devicesupport/idevice.h>
|
||||
#include <ssh/sshparameters.h>
|
||||
#include <utils/portlist.h>
|
||||
#include <utils/fileutils.h>
|
||||
|
||||
@@ -69,7 +70,7 @@ GenericLinuxDeviceConfigurationWizard::GenericLinuxDeviceConfigurationWizard(QWi
|
||||
d->device->setType(Constants::GenericLinuxOsType);
|
||||
d->device->setMachineType(IDevice::Hardware);
|
||||
d->device->setFreePorts(Utils::PortList::fromString(QLatin1String("10000-10100")));
|
||||
SshConnectionParameters sshParams;
|
||||
SshParameters sshParams;
|
||||
sshParams.timeout = 10;
|
||||
d->device->setSshParameters(sshParams);
|
||||
d->setupPage.setDevice(d->device);
|
||||
|
||||
@@ -30,8 +30,9 @@
|
||||
|
||||
#include <projectexplorer/devicesupport/idevice.h>
|
||||
#include <ssh/sshkeycreationdialog.h>
|
||||
#include <utils/utilsicons.h>
|
||||
#include <ssh/sshparameters.h>
|
||||
#include <utils/pathchooser.h>
|
||||
#include <utils/utilsicons.h>
|
||||
|
||||
#include <QHBoxLayout>
|
||||
#include <QLabel>
|
||||
@@ -39,6 +40,9 @@
|
||||
#include <QStringList>
|
||||
#include <QVBoxLayout>
|
||||
|
||||
using namespace QSsh;
|
||||
using namespace Utils;
|
||||
|
||||
namespace RemoteLinux {
|
||||
namespace Internal {
|
||||
|
||||
@@ -57,9 +61,6 @@ public:
|
||||
|
||||
} // namespace Internal
|
||||
|
||||
using namespace QSsh;
|
||||
using namespace Utils;
|
||||
|
||||
GenericLinuxDeviceConfigurationWizardSetupPage::GenericLinuxDeviceConfigurationWizardSetupPage(
|
||||
QWidget *parent) :
|
||||
QWizardPage(parent), d(new Internal::GenericLinuxDeviceConfigurationWizardSetupPagePrivate)
|
||||
@@ -94,7 +95,7 @@ bool GenericLinuxDeviceConfigurationWizardSetupPage::isComplete() const
|
||||
bool GenericLinuxDeviceConfigurationWizardSetupPage::validatePage()
|
||||
{
|
||||
d->device->setDisplayName(configurationName());
|
||||
SshConnectionParameters sshParams = d->device->sshParameters();
|
||||
SshParameters sshParams = d->device->sshParameters();
|
||||
sshParams.url = url();
|
||||
d->device->setSshParameters(sshParams);
|
||||
return true;
|
||||
@@ -232,8 +233,8 @@ bool GenericLinuxDeviceConfigurationWizardKeyDeploymentPage::isComplete() const
|
||||
bool GenericLinuxDeviceConfigurationWizardKeyDeploymentPage::validatePage()
|
||||
{
|
||||
if (!d->defaultKeys().contains(d->keyFileChooser.filePath())) {
|
||||
SshConnectionParameters sshParams = d->device->sshParameters();
|
||||
sshParams.authenticationType = SshConnectionParameters::AuthenticationTypeSpecificKey;
|
||||
SshParameters sshParams = d->device->sshParameters();
|
||||
sshParams.authenticationType = SshParameters::AuthenticationTypeSpecificKey;
|
||||
sshParams.privateKeyFile = d->keyFileChooser.filePath();
|
||||
d->device->setSshParameters(sshParams);
|
||||
}
|
||||
|
||||
@@ -28,8 +28,6 @@
|
||||
#include "linuxdevice.h"
|
||||
#include "remotelinux_export.h"
|
||||
|
||||
#include <ssh/sshconnection.h>
|
||||
|
||||
#include <QWizardPage>
|
||||
|
||||
namespace RemoteLinux {
|
||||
|
||||
@@ -42,7 +42,7 @@
|
||||
#include <projectexplorer/devicesupport/sshdeviceprocesslist.h>
|
||||
#include <projectexplorer/runcontrol.h>
|
||||
|
||||
#include <ssh/sshconnection.h>
|
||||
#include <ssh/sshparameters.h>
|
||||
#include <ssh/sshsettings.h>
|
||||
|
||||
#include <utils/algorithm.h>
|
||||
@@ -86,10 +86,10 @@ class SshSharedConnection : public QObject
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
explicit SshSharedConnection(const SshConnectionParameters &sshParameters, QObject *parent = nullptr);
|
||||
explicit SshSharedConnection(const SshParameters &sshParameters, QObject *parent = nullptr);
|
||||
~SshSharedConnection() override;
|
||||
|
||||
SshConnectionParameters sshParameters() const { return m_sshParameters; }
|
||||
SshParameters sshParameters() const { return m_sshParameters; }
|
||||
void ref();
|
||||
void deref();
|
||||
void makeStale();
|
||||
@@ -122,7 +122,7 @@ private:
|
||||
QStringList connectionArgs(const FilePath &binary) const
|
||||
{ return connectionOptions(binary) << m_sshParameters.host(); }
|
||||
|
||||
const SshConnectionParameters m_sshParameters;
|
||||
const SshParameters m_sshParameters;
|
||||
std::unique_ptr<QtcProcess> m_masterProcess;
|
||||
std::unique_ptr<QTemporaryDir> m_masterSocketDir;
|
||||
QTimer m_timer;
|
||||
@@ -131,7 +131,7 @@ private:
|
||||
QProcess::ProcessState m_state = QProcess::NotRunning;
|
||||
};
|
||||
|
||||
SshSharedConnection::SshSharedConnection(const SshConnectionParameters &sshParameters, QObject *parent)
|
||||
SshSharedConnection::SshSharedConnection(const SshParameters &sshParameters, QObject *parent)
|
||||
: QObject(parent), m_sshParameters(sshParameters)
|
||||
{
|
||||
}
|
||||
@@ -189,7 +189,7 @@ void SshSharedConnection::connectToHost()
|
||||
}
|
||||
|
||||
m_masterProcess.reset(new QtcProcess);
|
||||
SshConnectionParameters::setupSshEnvironment(m_masterProcess.get());
|
||||
SshParameters::setupSshEnvironment(m_masterProcess.get());
|
||||
m_timer.setSingleShot(true);
|
||||
connect(&m_timer, &QTimer::timeout, this, &SshSharedConnection::autoDestructRequested);
|
||||
connect(m_masterProcess.get(), &QtcProcess::readyReadStandardOutput, [this] {
|
||||
@@ -383,7 +383,7 @@ public:
|
||||
QByteArray outputForRunInShell(const QString &cmd);
|
||||
QByteArray outputForRunInShell(const CommandLine &cmd);
|
||||
void attachToSharedConnection(SshConnectionHandle *connectionHandle,
|
||||
const SshConnectionParameters &sshParameters);
|
||||
const SshParameters &sshParameters);
|
||||
|
||||
LinuxDevice *q = nullptr;
|
||||
QThread m_shellThread;
|
||||
@@ -426,7 +426,7 @@ public:
|
||||
LinuxDevicePrivate *m_devicePrivate = nullptr;
|
||||
|
||||
QString m_socketFilePath;
|
||||
SshConnectionParameters m_sshParameters;
|
||||
SshParameters m_sshParameters;
|
||||
bool m_connecting = false;
|
||||
bool m_killed = false;
|
||||
|
||||
@@ -720,7 +720,7 @@ void SshProcessInterfacePrivate::doStart()
|
||||
m_process.setTerminalMode(q->m_setup.m_terminalMode);
|
||||
m_process.setWriteData(q->m_setup.m_writeData);
|
||||
// TODO: what about other fields from m_setup?
|
||||
SshConnectionParameters::setupSshEnvironment(&m_process);
|
||||
SshParameters::setupSshEnvironment(&m_process);
|
||||
if (!m_sshParameters.x11DisplayName.isEmpty()) {
|
||||
Environment env = m_process.controlEnvironment();
|
||||
// Note: it seems this is no-op when shared connection is used.
|
||||
@@ -760,9 +760,9 @@ CommandLine SshProcessInterfacePrivate::fullLocalCommandLine() const
|
||||
|
||||
// ShellThreadHandler
|
||||
|
||||
static SshConnectionParameters displayless(const SshConnectionParameters &sshParameters)
|
||||
static SshParameters displayless(const SshParameters &sshParameters)
|
||||
{
|
||||
SshConnectionParameters parameters = sshParameters;
|
||||
SshParameters parameters = sshParameters;
|
||||
parameters.x11DisplayName.clear();
|
||||
return parameters;
|
||||
}
|
||||
@@ -786,13 +786,13 @@ public:
|
||||
}
|
||||
|
||||
// Call me with shell mutex locked
|
||||
bool start(const SshConnectionParameters ¶meters)
|
||||
bool start(const SshParameters ¶meters)
|
||||
{
|
||||
closeShell();
|
||||
setSshParameters(parameters);
|
||||
m_shell.reset(new QtcProcess);
|
||||
|
||||
SshConnectionParameters::setupSshEnvironment(m_shell.get());
|
||||
SshParameters::setupSshEnvironment(m_shell.get());
|
||||
|
||||
const FilePath sshPath = SshSettings::sshFilePath();
|
||||
CommandLine cmd { sshPath };
|
||||
@@ -871,10 +871,10 @@ public:
|
||||
return output;
|
||||
}
|
||||
|
||||
void setSshParameters(const SshConnectionParameters &sshParameters)
|
||||
void setSshParameters(const SshParameters &sshParameters)
|
||||
{
|
||||
QMutexLocker locker(&m_mutex);
|
||||
const SshConnectionParameters displaylessSshParameters = displayless(sshParameters);
|
||||
const SshParameters displaylessSshParameters = displayless(sshParameters);
|
||||
|
||||
if (m_displaylessSshParameters == displaylessSshParameters)
|
||||
return;
|
||||
@@ -888,7 +888,7 @@ public:
|
||||
}
|
||||
|
||||
QString attachToSharedConnection(SshConnectionHandle *connectionHandle,
|
||||
const SshConnectionParameters &sshParameters)
|
||||
const SshParameters &sshParameters)
|
||||
{
|
||||
setSshParameters(sshParameters);
|
||||
|
||||
@@ -938,7 +938,7 @@ public:
|
||||
}
|
||||
|
||||
// Call me with shell mutex locked, called from other thread
|
||||
bool isRunning(const SshConnectionParameters &sshParameters) const
|
||||
bool isRunning(const SshParameters &sshParameters) const
|
||||
{
|
||||
if (!m_shell)
|
||||
return false;
|
||||
@@ -949,7 +949,7 @@ public:
|
||||
}
|
||||
private:
|
||||
mutable QMutex m_mutex;
|
||||
SshConnectionParameters m_displaylessSshParameters;
|
||||
SshParameters m_displaylessSshParameters;
|
||||
QList<SshSharedConnection *> m_connections;
|
||||
std::unique_ptr<QtcProcess> m_shell;
|
||||
};
|
||||
@@ -1143,7 +1143,7 @@ LinuxDevicePrivate::~LinuxDevicePrivate()
|
||||
// Call me with shell mutex locked
|
||||
bool LinuxDevicePrivate::setupShell()
|
||||
{
|
||||
const SshConnectionParameters sshParameters = q->sshParameters();
|
||||
const SshParameters sshParameters = q->sshParameters();
|
||||
if (m_handler->isRunning(sshParameters))
|
||||
return true;
|
||||
|
||||
@@ -1186,7 +1186,7 @@ QByteArray LinuxDevicePrivate::outputForRunInShell(const CommandLine &cmd)
|
||||
}
|
||||
|
||||
void LinuxDevicePrivate::attachToSharedConnection(SshConnectionHandle *connectionHandle,
|
||||
const SshConnectionParameters &sshParameters)
|
||||
const SshParameters &sshParameters)
|
||||
{
|
||||
QString socketFilePath;
|
||||
QMetaObject::invokeMethod(m_handler, [this, connectionHandle, sshParameters] {
|
||||
@@ -1481,7 +1481,7 @@ protected:
|
||||
: m_method(method)
|
||||
, m_process(this)
|
||||
{
|
||||
SshConnectionParameters::setupSshEnvironment(&m_process);
|
||||
SshParameters::setupSshEnvironment(&m_process);
|
||||
connect(&m_process, &QtcProcess::readyReadStandardOutput, this, [this] {
|
||||
emit progress(QString::fromLocal8Bit(m_process.readAllStandardOutput()));
|
||||
});
|
||||
@@ -1583,7 +1583,7 @@ private:
|
||||
m_process.setStandardInputFile(m_batchFile->fileName());
|
||||
|
||||
// TODO: Add support for shared ssh connection
|
||||
const SshConnectionParameters params = displayless(m_device->sshParameters());
|
||||
const SshParameters params = displayless(m_device->sshParameters());
|
||||
m_process.setCommand(CommandLine(sftpBinary,
|
||||
params.connectionOptions(sftpBinary) << params.host()));
|
||||
m_process.start();
|
||||
@@ -1625,7 +1625,7 @@ private:
|
||||
{
|
||||
m_process.close();
|
||||
|
||||
const SshConnectionParameters parameters = displayless(m_device->sshParameters());
|
||||
const SshParameters parameters = displayless(m_device->sshParameters());
|
||||
const QStringList connectionOptions // TODO: add shared connection here
|
||||
= parameters.connectionOptions(SshSettings::sshFilePath());
|
||||
const QString sshCmdLine = ProcessArgs::joinArgs(
|
||||
|
||||
@@ -26,7 +26,7 @@
|
||||
#include "publickeydeploymentdialog.h"
|
||||
|
||||
#include <projectexplorer/devicesupport/idevice.h>
|
||||
#include <ssh/sshconnection.h>
|
||||
#include <ssh/sshparameters.h>
|
||||
#include <utils/qtcprocess.h>
|
||||
#include <utils/theme/theme.h>
|
||||
|
||||
|
||||
@@ -32,7 +32,6 @@
|
||||
#include <utils/qtcprocess.h>
|
||||
|
||||
using namespace ProjectExplorer;
|
||||
using namespace QSsh;
|
||||
using namespace Utils;
|
||||
|
||||
namespace RemoteLinux {
|
||||
|
||||
@@ -38,7 +38,6 @@
|
||||
#include <utils/qtcprocess.h>
|
||||
|
||||
using namespace ProjectExplorer;
|
||||
using namespace QSsh;
|
||||
using namespace Utils;
|
||||
|
||||
namespace RemoteLinux {
|
||||
|
||||
@@ -32,9 +32,6 @@
|
||||
#include <projectexplorer/project.h>
|
||||
#include <projectexplorer/target.h>
|
||||
|
||||
#include <ssh/sshconnection.h>
|
||||
#include <ssh/sshconnectionmanager.h>
|
||||
|
||||
#include <QDateTime>
|
||||
#include <QDir>
|
||||
#include <QFile>
|
||||
|
||||
@@ -17,7 +17,6 @@ add_subdirectory(profilewriter)
|
||||
add_subdirectory(qml)
|
||||
add_subdirectory(runextensions)
|
||||
add_subdirectory(sdktool)
|
||||
add_subdirectory(ssh)
|
||||
add_subdirectory(toolchaincache)
|
||||
add_subdirectory(tracing)
|
||||
add_subdirectory(treeviewfind)
|
||||
|
||||
@@ -20,7 +20,6 @@ Project {
|
||||
"qml/qml.qbs",
|
||||
"runextensions/runextensions.qbs",
|
||||
"sdktool/sdktool.qbs",
|
||||
"ssh/ssh.qbs",
|
||||
"toolchaincache/toolchaincache.qbs",
|
||||
"tracing/tracing.qbs",
|
||||
"treeviewfind/treeviewfind.qbs",
|
||||
|
||||
@@ -1,9 +0,0 @@
|
||||
file(RELATIVE_PATH RELATIVE_TEST_PATH "${PROJECT_BINARY_DIR}" "${CMAKE_CURRENT_BINARY_DIR}")
|
||||
file(RELATIVE_PATH TEST_RELATIVE_LIBEXEC_PATH "/${RELATIVE_TEST_PATH}" "/${IDE_LIBEXEC_PATH}")
|
||||
|
||||
add_qtc_test(tst_ssh
|
||||
DEFINES "TEST_RELATIVE_LIBEXEC_PATH=\"${TEST_RELATIVE_LIBEXEC_PATH}\""
|
||||
WITH_TESTS
|
||||
DEPENDS Utils QtcSsh
|
||||
SOURCES tst_ssh.cpp
|
||||
)
|
||||
@@ -1,17 +0,0 @@
|
||||
import qbs.FileInfo
|
||||
|
||||
QtcAutotest {
|
||||
name: "SSH autotest"
|
||||
Depends { name: "QtcSsh" }
|
||||
Depends { name: "Utils" }
|
||||
files: "tst_ssh.cpp"
|
||||
cpp.defines: {
|
||||
var defines = base;
|
||||
var absLibExecPath = FileInfo.joinPaths(qbs.installRoot, qbs.installPrefix,
|
||||
qtc.ide_libexec_path);
|
||||
var relLibExecPath = FileInfo.relativePath(destinationDirectory, absLibExecPath);
|
||||
defines.push('TEST_RELATIVE_LIBEXEC_PATH="' + relLibExecPath + '"');
|
||||
defines.push("WITH_TESTS");
|
||||
return defines;
|
||||
}
|
||||
}
|
||||
@@ -1,207 +0,0 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** Copyright (C) 2018 The Qt Company Ltd.
|
||||
** Contact: https://www.qt.io/licensing/
|
||||
**
|
||||
** This file is part of Qt Creator.
|
||||
**
|
||||
** Commercial License Usage
|
||||
** Licensees holding valid commercial Qt licenses may use this file in
|
||||
** accordance with the commercial license agreement provided with the
|
||||
** Software or, alternatively, in accordance with the terms contained in
|
||||
** a written agreement between you and The Qt Company. For licensing terms
|
||||
** and conditions see https://www.qt.io/terms-conditions. For further
|
||||
** information use the contact form at https://www.qt.io/contact-us.
|
||||
**
|
||||
** GNU General Public License Usage
|
||||
** Alternatively, this file may be used under the terms of the GNU
|
||||
** General Public License version 3 as published by the Free Software
|
||||
** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
|
||||
** included in the packaging of this file. Please review the following
|
||||
** information to ensure the GNU General Public License requirements will
|
||||
** be met: https://www.gnu.org/licenses/gpl-3.0.html.
|
||||
**
|
||||
****************************************************************************/
|
||||
|
||||
#include <ssh/sshconnection.h>
|
||||
#include <ssh/sshsettings.h>
|
||||
|
||||
#include <utils/algorithm.h>
|
||||
#include <utils/environment.h>
|
||||
#include <utils/launcherinterface.h>
|
||||
#include <utils/qtcprocess.h>
|
||||
#include <utils/singleton.h>
|
||||
#include <utils/temporarydirectory.h>
|
||||
|
||||
#include <QDateTime>
|
||||
#include <QDir>
|
||||
#include <QEventLoop>
|
||||
#include <QRandomGenerator>
|
||||
#include <QStringList>
|
||||
#include <QTemporaryDir>
|
||||
#include <QTimer>
|
||||
#include <QtTest>
|
||||
|
||||
#include <cstdlib>
|
||||
|
||||
using namespace QSsh;
|
||||
using namespace Utils;
|
||||
|
||||
class tst_Ssh : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
private slots:
|
||||
void initTestCase();
|
||||
|
||||
void errorHandling_data();
|
||||
void errorHandling();
|
||||
void pristineConnectionObject();
|
||||
void remoteProcessInput();
|
||||
void sftp();
|
||||
|
||||
void cleanupTestCase();
|
||||
private:
|
||||
bool waitForConnection(SshConnection &connection);
|
||||
};
|
||||
|
||||
void tst_Ssh::initTestCase()
|
||||
{
|
||||
const SshConnectionParameters params = SshTest::getParameters();
|
||||
if (!SshTest::checkParameters(params))
|
||||
SshTest::printSetupHelp();
|
||||
|
||||
LauncherInterface::setPathToLauncher(qApp->applicationDirPath() + '/'
|
||||
+ QLatin1String(TEST_RELATIVE_LIBEXEC_PATH));
|
||||
TemporaryDirectory::setMasterTemporaryDirectory(QDir::tempPath()
|
||||
+ "/qtc-ssh-autotest-XXXXXX");
|
||||
}
|
||||
|
||||
void tst_Ssh::errorHandling_data()
|
||||
{
|
||||
QTest::addColumn<QString>("host");
|
||||
QTest::addColumn<quint16>("port");
|
||||
QTest::addColumn<SshConnectionParameters::AuthenticationType>("authType");
|
||||
QTest::addColumn<QString>("user");
|
||||
QTest::addColumn<QString>("keyFile");
|
||||
|
||||
QTest::newRow("no host")
|
||||
<< QString("hgdfxgfhgxfhxgfchxgcf") << quint16(12345)
|
||||
<< SshConnectionParameters::AuthenticationTypeAll << QString("egal") << QString();
|
||||
const QString theHost = SshTest::getHostFromEnvironment();
|
||||
if (theHost.isEmpty())
|
||||
return;
|
||||
const quint16 thePort = SshTest::getPortFromEnvironment();
|
||||
QTest::newRow("non-existing key file")
|
||||
<< theHost << thePort << SshConnectionParameters::AuthenticationTypeSpecificKey
|
||||
<< QString("root") << QString("somefilenamethatwedontexpecttocontainavalidkey");
|
||||
}
|
||||
|
||||
void tst_Ssh::errorHandling()
|
||||
{
|
||||
if (SshSettings::sshFilePath().isEmpty())
|
||||
QSKIP("No ssh found in PATH - skipping this test.");
|
||||
|
||||
QFETCH(QString, host);
|
||||
QFETCH(quint16, port);
|
||||
QFETCH(SshConnectionParameters::AuthenticationType, authType);
|
||||
QFETCH(QString, user);
|
||||
QFETCH(QString, keyFile);
|
||||
SshConnectionParameters params;
|
||||
params.setHost(host);
|
||||
params.setPort(port);
|
||||
params.setUserName(user);
|
||||
params.timeout = 3;
|
||||
params.authenticationType = authType;
|
||||
params.privateKeyFile = FilePath::fromString(keyFile);
|
||||
SshConnection connection(params);
|
||||
QEventLoop loop;
|
||||
bool disconnected = false;
|
||||
QObject::connect(&connection, &SshConnection::connected, &loop, &QEventLoop::quit);
|
||||
QObject::connect(&connection, &SshConnection::errorOccurred, &loop, &QEventLoop::quit);
|
||||
QObject::connect(&connection, &SshConnection::disconnected,
|
||||
[&disconnected] { disconnected = true; });
|
||||
QTimer timer;
|
||||
QObject::connect(&timer, &QTimer::timeout, &loop, &QEventLoop::quit);
|
||||
timer.setSingleShot(true);
|
||||
timer.start((params.timeout + 15) * 1000);
|
||||
connection.connectToHost();
|
||||
loop.exec();
|
||||
QVERIFY(timer.isActive());
|
||||
const bool expectConnected = !SshSettings::connectionSharingEnabled();
|
||||
QCOMPARE(connection.state(), expectConnected ? SshConnection::Connected
|
||||
: SshConnection::Unconnected);
|
||||
QCOMPARE(connection.errorString().isEmpty(), expectConnected);
|
||||
QVERIFY(!disconnected);
|
||||
}
|
||||
|
||||
void tst_Ssh::pristineConnectionObject()
|
||||
{
|
||||
QSsh::SshConnection connection((SshConnectionParameters()));
|
||||
QCOMPARE(connection.state(), SshConnection::Unconnected);
|
||||
QRegularExpression assertToIgnore(
|
||||
"SOFT ASSERT: \"state\\(\\) == Connected\" in file .*[/\\\\]sshconnection.cpp, line \\d*");
|
||||
QTest::ignoreMessage(QtDebugMsg, assertToIgnore);
|
||||
}
|
||||
|
||||
void tst_Ssh::remoteProcessInput()
|
||||
{
|
||||
const SshConnectionParameters params = SshTest::getParameters();
|
||||
if (!SshTest::checkParameters(params))
|
||||
QSKIP("Insufficient setup - set QTC_SSH_TEST_* variables.");
|
||||
SshConnection connection(params);
|
||||
QVERIFY(waitForConnection(connection));
|
||||
}
|
||||
|
||||
void tst_Ssh::sftp()
|
||||
{
|
||||
// Connect to server
|
||||
const SshConnectionParameters params = SshTest::getParameters();
|
||||
if (!SshTest::checkParameters(params))
|
||||
QSKIP("Insufficient setup - set QTC_SSH_TEST_* variables.");
|
||||
SshConnection connection(params);
|
||||
QVERIFY(waitForConnection(connection));
|
||||
|
||||
// Create and upload 1000 small files and one big file
|
||||
QTemporaryDir dirForFilesToUpload;
|
||||
QTemporaryDir dirForFilesToDownload;
|
||||
QTemporaryDir dir2ForFilesToDownload;
|
||||
QVERIFY2(dirForFilesToUpload.isValid(), qPrintable(dirForFilesToUpload.errorString()));
|
||||
QVERIFY2(dirForFilesToDownload.isValid(), qPrintable(dirForFilesToDownload.errorString()));
|
||||
QVERIFY2(dir2ForFilesToDownload.isValid(), qPrintable(dirForFilesToDownload.errorString()));
|
||||
const QString bigFileName("sftpbigfile");
|
||||
QFile bigFile(dirForFilesToUpload.path() + '/' + bigFileName);
|
||||
QVERIFY2(bigFile.open(QIODevice::WriteOnly), qPrintable(bigFile.errorString()));
|
||||
const int bigFileSize = 100 * 1024 * 1024;
|
||||
const int blockSize = 8192;
|
||||
const int blockCount = bigFileSize / blockSize;
|
||||
for (int block = 0; block < blockCount; ++block) {
|
||||
int content[blockSize / sizeof(int)];
|
||||
for (size_t j = 0; j < sizeof content / sizeof content[0]; ++j)
|
||||
content[j] = QRandomGenerator::global()->generate();
|
||||
bigFile.write(reinterpret_cast<char *>(content), sizeof content);
|
||||
}
|
||||
bigFile.close();
|
||||
QVERIFY2(bigFile.error() == QFile::NoError, qPrintable(bigFile.errorString()));
|
||||
}
|
||||
|
||||
void tst_Ssh::cleanupTestCase()
|
||||
{
|
||||
Singleton::deleteAll();
|
||||
}
|
||||
|
||||
bool tst_Ssh::waitForConnection(SshConnection &connection)
|
||||
{
|
||||
QEventLoop loop;
|
||||
QObject::connect(&connection, &SshConnection::connected, &loop, &QEventLoop::quit);
|
||||
QObject::connect(&connection, &SshConnection::errorOccurred, &loop, &QEventLoop::quit);
|
||||
connection.connectToHost();
|
||||
loop.exec();
|
||||
if (!connection.errorString().isEmpty())
|
||||
qDebug() << connection.errorString();
|
||||
return connection.state() == SshConnection::Connected && connection.errorString().isEmpty();
|
||||
}
|
||||
|
||||
QTEST_MAIN(tst_Ssh)
|
||||
|
||||
#include <tst_ssh.moc>
|
||||
Reference in New Issue
Block a user