forked from qt-creator/qt-creator
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: Tobias Hunger <tobias.hunger@nokia.com>
This commit is contained in:
@@ -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) {
|
||||
|
Reference in New Issue
Block a user