Commit 5d5db225 authored by Christian Kandeler's avatar Christian Kandeler
Browse files

SSH: Don't allow external access to process runner's connection object.



It does not belong to the runner anymore after the process has finished,
so we must prevent anyone from getting a copy.
(This includes a minor API fix for RemoteLinux code that depended on
the connection being available.)

Change-Id: Icc28dc3c820f4c2210bb6fb08171cd6a84534dee
Reviewed-by: default avatarChristian Kandeler <christian.kandeler@nokia.com>
parent bddfae71
......@@ -56,12 +56,13 @@ public:
void runInTerminal(const QByteArray &command, const SshPseudoTerminal &terminal,
const SshConnectionParameters &sshParams);
QByteArray command() const { return m_command; }
Utils::SshError lastConnectionError() const { return m_lastConnectionError; }
QString lastConnectionErrorString() const { return m_lastConnectionErrorString; }
SshConnection::Ptr m_connection;
SshRemoteProcess::Ptr m_process;
signals:
void connectionError(Utils::SshError);
void connectionError();
void processStarted();
void processOutputAvailable(const QByteArray &output);
void processErrorOutputAvailable(const QByteArray &output);
......@@ -82,10 +83,13 @@ private:
void assertState(const QList<State> &allowedStates, const char *func);
void assertState(State allowedState, const char *func);
SshConnection::Ptr m_connection;
State m_state;
bool m_runInTerminal;
SshPseudoTerminal m_terminal;
QByteArray m_command;
Utils::SshError m_lastConnectionError;
QString m_lastConnectionErrorString;
};
......@@ -120,6 +124,8 @@ void SshRemoteProcessRunnerPrivate::run(const QByteArray &command,
setState(Inactive);
setState(Connecting);
m_lastConnectionError = SshNoError;
m_lastConnectionErrorString.clear();
m_command = command;
m_connection = SshConnectionManager::instance().acquireConnection(sshParams);
connect(m_connection.data(), SIGNAL(error(Utils::SshError)),
......@@ -155,8 +161,10 @@ void SshRemoteProcessRunnerPrivate::handleConnected()
void SshRemoteProcessRunnerPrivate::handleConnectionError(Utils::SshError error)
{
m_lastConnectionError = error;
m_lastConnectionErrorString = m_connection->errorString();
handleDisconnected();
emit connectionError(error);
emit connectionError();
}
void SshRemoteProcessRunnerPrivate::handleDisconnected()
......@@ -200,6 +208,7 @@ void SshRemoteProcessRunnerPrivate::setState(State state)
if (m_connection) {
disconnect(m_connection.data(), 0, this, 0);
SshConnectionManager::instance().releaseConnection(m_connection);
m_connection.clear();
}
}
}
......@@ -223,8 +232,7 @@ void SshRemoteProcessRunnerPrivate::assertState(State allowedState,
SshRemoteProcessRunner::SshRemoteProcessRunner(QObject *parent)
: QObject(parent), d(new Internal::SshRemoteProcessRunnerPrivate(this))
{
connect(d, SIGNAL(connectionError(Utils::SshError)),
SIGNAL(connectionError(Utils::SshError)));
connect(d, SIGNAL(connectionError()), SIGNAL(connectionError()));
connect(d, SIGNAL(processStarted()), SIGNAL(processStarted()));
connect(d, SIGNAL(processClosed(int)), SIGNAL(processClosed(int)));
connect(d, SIGNAL(processOutputAvailable(QByteArray)),
......@@ -245,9 +253,15 @@ void SshRemoteProcessRunner::runInTerminal(const QByteArray &command,
}
QByteArray SshRemoteProcessRunner::command() const { return d->command(); }
SshConnection::Ptr SshRemoteProcessRunner::connection() const { return d->m_connection; }
SshError SshRemoteProcessRunner::lastConnectionError() const { return d->lastConnectionError(); }
SshRemoteProcess::Ptr SshRemoteProcessRunner::process() const { return d->m_process; }
QString SshRemoteProcessRunner::lastConnectionErrorString() const
{
return d->lastConnectionErrorString();
}
} // namespace Utils
......
......@@ -53,11 +53,13 @@ public:
const SshConnectionParameters &params);
QByteArray command() const;
SshConnection::Ptr connection() const;
Utils::SshError lastConnectionError() const;
QString lastConnectionErrorString() const;
SshRemoteProcess::Ptr process() const;
signals:
void connectionError(Utils::SshError);
void connectionError();
void processStarted();
void processOutputAvailable(const QByteArray &output);
void processErrorOutputAvailable(const QByteArray &output);
......
......@@ -109,8 +109,7 @@ void MaddeDeviceTester::handleGenericTestFinished(TestResult result)
if (!m_processRunner)
m_processRunner = new SshRemoteProcessRunner(this);
connect(m_processRunner, SIGNAL(connectionError(Utils::SshError)),
SLOT(handleConnectionError()));
connect(m_processRunner, SIGNAL(connectionError()), SLOT(handleConnectionError()));
connect(m_processRunner, SIGNAL(processOutputAvailable(QByteArray)),
SLOT(handleStdout(QByteArray)));
connect(m_processRunner, SIGNAL(processErrorOutputAvailable(QByteArray)),
......@@ -137,7 +136,7 @@ void MaddeDeviceTester::handleConnectionError()
QTC_ASSERT(m_state != Inactive, return);
emit errorMessage(tr("SSH connection error: %1\n")
.arg(m_processRunner->connection()->errorString()));
.arg(m_processRunner->lastConnectionErrorString()));
m_result = TestFailure;
setFinished();
}
......
......@@ -309,7 +309,7 @@ void MaemoMountAndInstallPackageService::doInstall()
{
const QString remoteFilePath = deployMountPoint() + QLatin1Char('/')
+ QFileInfo(m_packageFilePath).fileName();
m_installer->installPackage(connection(), remoteFilePath, false);
m_installer->installPackage(deviceConfiguration(), remoteFilePath, false);
}
void MaemoMountAndInstallPackageService::cancelInstallation()
......
......@@ -388,8 +388,7 @@ void MaemoPublisherFremantleFree::uploadPackage()
if (!m_uploader)
m_uploader = new SshRemoteProcessRunner(this);
connect(m_uploader, SIGNAL(processStarted()), SLOT(handleScpStarted()));
connect(m_uploader, SIGNAL(connectionError(Utils::SshError)),
SLOT(handleConnectionError()));
connect(m_uploader, SIGNAL(connectionError()), SLOT(handleConnectionError()));
connect(m_uploader, SIGNAL(processClosed(int)), SLOT(handleUploadJobFinished(int)));
connect(m_uploader, SIGNAL(processOutputAvailable(QByteArray)),
SLOT(handleScpStdOut(QByteArray)));
......@@ -409,7 +408,7 @@ void MaemoPublisherFremantleFree::handleScpStarted()
void MaemoPublisherFremantleFree::handleConnectionError()
{
if (m_state != Inactive) {
finishWithFailure(tr("SSH error: %1").arg(m_uploader->connection()->errorString()),
finishWithFailure(tr("SSH error: %1").arg(m_uploader->lastConnectionErrorString()),
tr("Upload failed."));
}
}
......
......@@ -65,7 +65,7 @@ void MaemoRemoteCopyFacility::copyFiles(const SshConnection::Ptr &connection,
if (!m_copyRunner)
m_copyRunner = new SshRemoteProcessRunner(this);
connect(m_copyRunner, SIGNAL(connectionError(Utils::SshError)), SLOT(handleConnectionError()));
connect(m_copyRunner, SIGNAL(connectionError()), SLOT(handleConnectionError()));
connect(m_copyRunner, SIGNAL(processOutputAvailable(QByteArray)),
SLOT(handleRemoteStdout(QByteArray)));
connect(m_copyRunner, SIGNAL(processErrorOutputAvailable(QByteArray)),
......@@ -88,9 +88,8 @@ void MaemoRemoteCopyFacility::cancel()
void MaemoRemoteCopyFacility::handleConnectionError()
{
const QString errMsg = m_copyRunner->connection()->errorString();
setFinished();
emit finished(tr("Connection failed: %1").arg(errMsg));
emit finished(tr("Connection failed: %1").arg(m_copyRunner->lastConnectionErrorString()));
}
void MaemoRemoteCopyFacility::handleRemoteStdout(const QByteArray &output)
......
......@@ -159,7 +159,7 @@ void AbstractUploadAndInstallPackageService::handleUploadFinished(const QString
connect(packageInstaller(), SIGNAL(stderrData(QString)), SIGNAL(stdErrData(QString)));
connect(packageInstaller(), SIGNAL(finished(QString)),
SLOT(handleInstallationFinished(QString)));
packageInstaller()->installPackage(connection(), remoteFilePath, true);
packageInstaller()->installPackage(deviceConfiguration(), remoteFilePath, true);
}
void AbstractUploadAndInstallPackageService::handleInstallationFinished(const QString &errorMsg)
......
......@@ -61,8 +61,7 @@ void RemoteLinuxEnvironmentReader::start(const QString &environmentSetupCommand)
m_stop = false;
if (!m_remoteProcessRunner)
m_remoteProcessRunner = new Utils::SshRemoteProcessRunner(this);
connect(m_remoteProcessRunner, SIGNAL(connectionError(Utils::SshError)),
SLOT(handleConnectionFailure()));
connect(m_remoteProcessRunner, SIGNAL(connectionError()), SLOT(handleConnectionFailure()));
connect(m_remoteProcessRunner, SIGNAL(processClosed(int)), SLOT(remoteProcessFinished(int)));
connect(m_remoteProcessRunner, SIGNAL(processOutputAvailable(QByteArray)),
SLOT(remoteOutput(QByteArray)));
......@@ -87,8 +86,7 @@ void RemoteLinuxEnvironmentReader::handleConnectionFailure()
return;
disconnect(m_remoteProcessRunner, 0, this, 0);
emit error(tr("Connection error: %1")
.arg(m_remoteProcessRunner->connection()->errorString()));
emit error(tr("Connection error: %1").arg(m_remoteProcessRunner->lastConnectionErrorString()));
emit finished();
}
......
......@@ -31,12 +31,13 @@
**************************************************************************/
#include "remotelinuxpackageinstaller.h"
#include <QtCore/QByteArray>
#include "linuxdeviceconfiguration.h"
#include <utils/qtcassert.h>
#include <utils/ssh/sshconnection.h>
#include <utils/ssh/sshremoteprocessrunner.h>
#include <QtCore/QByteArray>
using namespace Utils;
namespace RemoteLinux {
......@@ -48,6 +49,7 @@ public:
AbstractRemoteLinuxPackageInstallerPrivate() : isRunning(false), installer(0), killProcess(0) {}
bool isRunning;
LinuxDeviceConfiguration::ConstPtr deviceConfig;
Utils::SshRemoteProcessRunner *installer;
Utils::SshRemoteProcessRunner *killProcess;
};
......@@ -64,17 +66,16 @@ AbstractRemoteLinuxPackageInstaller::~AbstractRemoteLinuxPackageInstaller()
delete d;
}
void AbstractRemoteLinuxPackageInstaller::installPackage(const SshConnection::Ptr &connection,
void AbstractRemoteLinuxPackageInstaller::installPackage(const LinuxDeviceConfiguration::ConstPtr &deviceConfig,
const QString &packageFilePath, bool removePackageFile)
{
QTC_ASSERT(connection && connection->state() == SshConnection::Connected
&& !d->isRunning, return);
QTC_ASSERT(!d->isRunning, return);
d->deviceConfig = deviceConfig;
prepareInstallation();
if (!d->installer)
d->installer = new SshRemoteProcessRunner(this);
connect(d->installer, SIGNAL(connectionError(Utils::SshError)),
SLOT(handleConnectionError()));
connect(d->installer, SIGNAL(connectionError()), SLOT(handleConnectionError()));
connect(d->installer, SIGNAL(processOutputAvailable(QByteArray)),
SLOT(handleInstallerOutput(QByteArray)));
connect(d->installer, SIGNAL(processErrorOutputAvailable(QByteArray)),
......@@ -84,19 +85,17 @@ void AbstractRemoteLinuxPackageInstaller::installPackage(const SshConnection::Pt
QString cmdLine = installCommandLine(packageFilePath);
if (removePackageFile)
cmdLine += QLatin1String(" && (rm ") + packageFilePath + QLatin1String(" || :)");
d->installer->run(cmdLine.toUtf8(), connection->connectionParameters());
d->installer->run(cmdLine.toUtf8(), deviceConfig->sshParameters());
d->isRunning = true;
}
void AbstractRemoteLinuxPackageInstaller::cancelInstallation()
{
QTC_ASSERT(d->installer && d->installer->connection()->state() == SshConnection::Connected
&& d->isRunning, return);
QTC_ASSERT(d->installer && d->isRunning, return);
if (!d->killProcess)
d->killProcess = new SshRemoteProcessRunner(this);
d->killProcess->run(cancelInstallationCommandLine().toUtf8(),
d->installer->connection()->connectionParameters());
d->killProcess->run(cancelInstallationCommandLine().toUtf8(), d->deviceConfig->sshParameters());
setFinished();
}
......@@ -104,7 +103,7 @@ void AbstractRemoteLinuxPackageInstaller::handleConnectionError()
{
if (!d->isRunning)
return;
emit finished(tr("Connection failure: %1").arg(d->installer->connection()->errorString()));
emit finished(tr("Connection failure: %1").arg(d->installer->lastConnectionErrorString()));
setFinished();
}
......
......@@ -38,11 +38,9 @@
#include <QtCore/QSharedPointer>
#include <QtCore/QString>
namespace Utils {
class SshConnection;
}
namespace RemoteLinux {
class LinuxDeviceConfiguration;
namespace Internal {
class AbstractRemoteLinuxPackageInstallerPrivate;
} // namespace Internal
......@@ -54,7 +52,7 @@ class REMOTELINUX_EXPORT AbstractRemoteLinuxPackageInstaller : public QObject
public:
~AbstractRemoteLinuxPackageInstaller();
void installPackage(const QSharedPointer<Utils::SshConnection> &connection,
void installPackage(const QSharedPointer<const LinuxDeviceConfiguration> &deviceConfig,
const QString &packageFilePath, bool removePackageFile);
void cancelInstallation();
......
......@@ -154,7 +154,7 @@ void AbstractRemoteLinuxProcessList::handleConnectionError()
{
QTC_ASSERT(d->state != Inactive, return);
emit error(tr("Connection failure: %1").arg(d->process.connection()->errorString()));
emit error(tr("Connection failure: %1").arg(d->process.lastConnectionErrorString()));
beginResetModel();
d->remoteProcesses.clear();
endResetModel();
......@@ -204,8 +204,7 @@ void AbstractRemoteLinuxProcessList::handleRemoteProcessFinished(int exitStatus)
void AbstractRemoteLinuxProcessList::startProcess(const QString &cmdLine)
{
connect(&d->process, SIGNAL(connectionError(Utils::SshError)),
SLOT(handleConnectionError()));
connect(&d->process, SIGNAL(connectionError()), SLOT(handleConnectionError()));
connect(&d->process, SIGNAL(processOutputAvailable(QByteArray)),
SLOT(handleRemoteStdOut(QByteArray)));
connect(&d->process, SIGNAL(processErrorOutputAvailable(QByteArray)),
......
......@@ -78,7 +78,7 @@ void RemoteLinuxUsedPortsGatherer::start(const Utils::SshConnection::Ptr &connec
d->usedPorts.clear();
d->remoteStdout.clear();
d->remoteStderr.clear();
connect(&d->procRunner, SIGNAL(connectionError(Utils::SshError)), SLOT(handleConnectionError()));
connect(&d->procRunner, SIGNAL(connectionError()), SLOT(handleConnectionError()));
connect(&d->procRunner, SIGNAL(processClosed(int)), SLOT(handleProcessClosed(int)));
connect(&d->procRunner, SIGNAL(processOutputAvailable(QByteArray)),
SLOT(handleRemoteStdOut(QByteArray)));
......@@ -150,7 +150,7 @@ void RemoteLinuxUsedPortsGatherer::handleConnectionError()
{
if (!d->running)
return;
emit error(tr("Connection error: %1").arg(d->procRunner.connection()->errorString()));
emit error(tr("Connection error: %1").arg(d->procRunner.lastConnectionErrorString()));
stop();
}
......
......@@ -71,8 +71,7 @@ void SshKeyDeployer::deployPublicKey(const SshConnectionParameters &sshParams,
return;
}
connect(&d->deployProcess, SIGNAL(connectionError(Utils::SshError)),
SLOT(handleConnectionFailure()));
connect(&d->deployProcess, SIGNAL(connectionError()), SLOT(handleConnectionFailure()));
connect(&d->deployProcess, SIGNAL(processClosed(int)), SLOT(handleKeyUploadFinished(int)));
const QByteArray command = "test -d .ssh "
"|| mkdir .ssh && chmod 0700 .ssh && echo '"
......@@ -82,9 +81,8 @@ void SshKeyDeployer::deployPublicKey(const SshConnectionParameters &sshParams,
void SshKeyDeployer::handleConnectionFailure()
{
const QString errorMsg = d->deployProcess.connection()->errorString();
cleanup();
emit error(tr("Connection failed: %1").arg(errorMsg));
emit error(tr("Connection failed: %1").arg(d->deployProcess.lastConnectionErrorString()));
}
void SshKeyDeployer::handleKeyUploadFinished(int exitStatus)
......
......@@ -203,7 +203,7 @@ void StartGdbServerDialog::startGdbServer()
void StartGdbServerDialog::handleConnectionError()
{
d->ui.textBrowser->append(tr("Connection error: %1")
.arg(d->runner.connection()->errorString()));
.arg(d->runner.lastConnectionErrorString()));
emit processAborted();
}
......@@ -238,8 +238,7 @@ void StartGdbServerDialog::handleProcessClosed(int status)
void StartGdbServerDialog::startGdbServerOnPort(int port, int pid)
{
LinuxDeviceConfiguration::ConstPtr device = d->currentDevice();
connect(&d->runner, SIGNAL(connectionError(Utils::SshError)),
SLOT(handleConnectionError()));
connect(&d->runner, SIGNAL(connectionError()), SLOT(handleConnectionError()));
connect(&d->runner, SIGNAL(processStarted()), SLOT(handleProcessStarted()));
connect(&d->runner, SIGNAL(processOutputAvailable(QByteArray)),
SLOT(handleProcessOutputAvailable(QByteArray)));
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment