1 /**************************************************************************
3 ** This file is part of Qt Creator
5 ** Copyright (c) 2011 Nokia Corporation and/or its subsidiary(-ies).
7 ** Contact: Nokia Corporation (info@qt.nokia.com)
10 ** GNU Lesser General Public License Usage
12 ** This file may be used under the terms of the GNU Lesser General Public
13 ** License version 2.1 as published by the Free Software Foundation and
14 ** appearing in the file LICENSE.LGPL included in the packaging of this file.
15 ** Please review the following information to ensure the GNU Lesser General
16 ** Public License version 2.1 requirements will be met:
17 ** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
19 ** In addition, as a special exception, Nokia gives you certain additional
20 ** rights. These rights are described in the Nokia Qt LGPL Exception
21 ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
25 ** Alternatively, this file may be used in accordance with the terms and
26 ** conditions contained in a signed written agreement between you and Nokia.
28 ** If you have questions regarding the use of this file, please contact
29 ** Nokia at qt-info@nokia.com.
31 **************************************************************************/
33 #include "sshchannelmanager_p.h"
35 #include "sftpchannel.h"
36 #include "sftpchannel_p.h"
37 #include "sshincomingpacket_p.h"
38 #include "sshremoteprocess.h"
39 #include "sshremoteprocess_p.h"
40 #include "sshsendfacility_p.h"
42 #include <QtCore/QList>
47 SshChannelManager::SshChannelManager(SshSendFacility &sendFacility,
49 : QObject(parent), m_sendFacility(sendFacility), m_nextLocalChannelId(0)
53 void SshChannelManager::handleChannelRequest(const SshIncomingPacket &packet)
55 lookupChannel(packet.extractRecipientChannel())
56 ->handleChannelRequest(packet);
59 void SshChannelManager::handleChannelOpen(const SshIncomingPacket &)
61 throw SSH_SERVER_EXCEPTION(SSH_DISCONNECT_PROTOCOL_ERROR,
62 "Server tried to open channel on client.");
65 void SshChannelManager::handleChannelOpenFailure(const SshIncomingPacket &packet)
67 const SshChannelOpenFailure &failure = packet.extractChannelOpenFailure();
68 ChannelIterator it = lookupChannelAsIterator(failure.localChannel);
70 it.value()->handleOpenFailure(failure.reasonString);
71 } catch (SshServerException &e) {
78 void SshChannelManager::handleChannelOpenConfirmation(const SshIncomingPacket &packet)
80 const SshChannelOpenConfirmation &confirmation
81 = packet.extractChannelOpenConfirmation();
82 lookupChannel(confirmation.localChannel)->handleOpenSuccess(confirmation.remoteChannel,
83 confirmation.remoteWindowSize, confirmation.remoteMaxPacketSize);
86 void SshChannelManager::handleChannelSuccess(const SshIncomingPacket &packet)
88 lookupChannel(packet.extractRecipientChannel())->handleChannelSuccess();
91 void SshChannelManager::handleChannelFailure(const SshIncomingPacket &packet)
93 lookupChannel(packet.extractRecipientChannel())->handleChannelFailure();
96 void SshChannelManager::handleChannelWindowAdjust(const SshIncomingPacket &packet)
98 const SshChannelWindowAdjust adjust = packet.extractWindowAdjust();
99 lookupChannel(adjust.localChannel)->handleWindowAdjust(adjust.bytesToAdd);
102 void SshChannelManager::handleChannelData(const SshIncomingPacket &packet)
104 const SshChannelData &data = packet.extractChannelData();
105 lookupChannel(data.localChannel)->handleChannelData(data.data);
108 void SshChannelManager::handleChannelExtendedData(const SshIncomingPacket &packet)
110 const SshChannelExtendedData &data = packet.extractChannelExtendedData();
111 lookupChannel(data.localChannel)->handleChannelExtendedData(data.type, data.data);
114 void SshChannelManager::handleChannelEof(const SshIncomingPacket &packet)
116 AbstractSshChannel * const channel
117 = lookupChannel(packet.extractRecipientChannel(), true);
119 channel->handleChannelEof();
122 void SshChannelManager::handleChannelClose(const SshIncomingPacket &packet)
124 const quint32 channelId = packet.extractRecipientChannel();
126 ChannelIterator it = lookupChannelAsIterator(channelId, true);
127 if (it != m_channels.end()) {
128 it.value()->handleChannelClose();
133 SshChannelManager::ChannelIterator SshChannelManager::lookupChannelAsIterator(quint32 channelId,
136 ChannelIterator it = m_channels.find(channelId);
137 if (it == m_channels.end() && !allowNotFound) {
138 throw SshServerException(SSH_DISCONNECT_PROTOCOL_ERROR,
139 "Invalid channel id.",
140 tr("Invalid channel id %1").arg(channelId));
145 AbstractSshChannel *SshChannelManager::lookupChannel(quint32 channelId,
148 ChannelIterator it = lookupChannelAsIterator(channelId, allowNotFound);
149 return it == m_channels.end() ? 0 : it.value();
152 Utils::SshRemoteProcess::Ptr SshChannelManager::createRemoteProcess(const QByteArray &command)
154 SshRemoteProcess::Ptr proc(new SshRemoteProcess(command, m_nextLocalChannelId++, m_sendFacility));
155 insertChannel(proc->d, proc);
159 Utils::SftpChannel::Ptr SshChannelManager::createSftpChannel()
161 SftpChannel::Ptr sftp(new SftpChannel(m_nextLocalChannelId++, m_sendFacility));
162 insertChannel(sftp->d, sftp);
166 void SshChannelManager::insertChannel(AbstractSshChannel *priv,
167 const QSharedPointer<QObject> &pub)
169 connect(priv, SIGNAL(timeout()), this, SIGNAL(timeout()));
170 m_channels.insert(priv->localChannelId(), priv);
171 m_sessions.insert(priv, pub);
174 void SshChannelManager::closeAllChannels()
176 for (ChannelIterator it = m_channels.begin(); it != m_channels.end(); ++it)
177 it.value()->closeChannel();
182 void SshChannelManager::removeChannel(ChannelIterator it)
184 Q_ASSERT(it != m_channels.end() && "Unexpected channel lookup failure.");
185 const int removeCount = m_sessions.remove(it.value());
186 Q_ASSERT(removeCount == 1 && "Session for channel not found.");
187 m_channels.erase(it);
190 } // namespace Internal