Commit c1a89d2c authored by Christian Kandeler's avatar Christian Kandeler
Browse files

SSH: Close channels before re-using a connection.



Otherwise a new client acquiring the connection could be affected by
things happening in channels that were not opened by that client, which
would certainly be unexpected.
In particular, if the new owner of the connection runs in a different
thread than the old one, crashes could occur since the connection
assumes its channels run in the same thread.

Change-Id: I4fdf2b5a3751ed506631d6878e94342da033c31c
Reviewed-by: default avatarTobias Hunger <tobias.hunger@nokia.com>
parent 621e5c3d
......@@ -178,12 +178,14 @@ void SshChannelManager::insertChannel(AbstractSshChannel *priv,
m_sessions.insert(priv, pub);
}
void SshChannelManager::closeAllChannels()
int SshChannelManager::closeAllChannels()
{
const int count = m_channels.count();
for (ChannelIterator it = m_channels.begin(); it != m_channels.end(); ++it)
it.value()->closeChannel();
m_channels.clear();
m_sessions.clear();
return count;
}
void SshChannelManager::removeChannel(ChannelIterator it)
......
......@@ -57,7 +57,7 @@ public:
QSharedPointer<SshRemoteProcess> createRemoteProcess(const QByteArray &command);
QSharedPointer<SshRemoteProcess> createRemoteShell();
QSharedPointer<SftpChannel> createSftpChannel();
void closeAllChannels();
int closeAllChannels();
void handleChannelRequest(const SshIncomingPacket &packet);
void handleChannelOpen(const SshIncomingPacket &packet);
......
......@@ -193,6 +193,15 @@ QSharedPointer<SftpChannel> SshConnection::createSftpChannel()
return d->createSftpChannel();
}
int SshConnection::closeAllChannels()
{
try {
return d->m_channelManager->closeAllChannels();
} catch (const Botan::Exception &e) {
qDebug("%s: %s", Q_FUNC_INFO, e.what());
return -1;
}
}
namespace Internal {
......
......@@ -106,6 +106,9 @@ public:
QSharedPointer<SshRemoteProcess> createRemoteShell();
QSharedPointer<SftpChannel> createSftpChannel();
// -1 if an error occurred, number of channels closed otherwise.
int closeAllChannels();
signals:
void connected();
void disconnected();
......
......@@ -145,10 +145,15 @@ public:
break;
}
}
if (!haveConnection)
if (!haveConnection) {
// Let's nag clients who release connections with open channels.
const int channelCount = connection->closeAllChannels();
QSSH_ASSERT(channelCount == 0);
m_unacquiredConnections.append(connection);
else
} else {
doDelete = true;
}
}
if (doDelete) {
......
Supports Markdown
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