forked from qt-creator/qt-creator
SSH: Fix TCP/IP forwarding support.
We hardcoded the remote host to the SSH server for some reason, and the originating port was bogus as well. Change-Id: I8f6700bc12f4374302dd3bfc035c9c9f060f56ef Reviewed-by: Caspar Romot <cro@icd.ee> Reviewed-by: Christian Kandeler <christian.kandeler@theqtcompany.com>
This commit is contained in:
@@ -170,11 +170,11 @@ QSsh::SftpChannel::Ptr SshChannelManager::createSftpChannel()
|
||||
return sftp;
|
||||
}
|
||||
|
||||
SshDirectTcpIpTunnel::Ptr SshChannelManager::createTunnel(quint16 remotePort,
|
||||
const SshConnectionInfo &connectionInfo)
|
||||
SshDirectTcpIpTunnel::Ptr SshChannelManager::createTunnel(const QString &originatingHost,
|
||||
quint16 originatingPort, const QString &remoteHost, quint16 remotePort)
|
||||
{
|
||||
SshDirectTcpIpTunnel::Ptr tunnel(new SshDirectTcpIpTunnel(m_nextLocalChannelId++, remotePort,
|
||||
connectionInfo, m_sendFacility));
|
||||
SshDirectTcpIpTunnel::Ptr tunnel(new SshDirectTcpIpTunnel(m_nextLocalChannelId++,
|
||||
originatingHost, originatingPort, remoteHost, remotePort, m_sendFacility));
|
||||
insertChannel(tunnel->d, tunnel);
|
||||
return tunnel;
|
||||
}
|
||||
|
@@ -37,7 +37,6 @@
|
||||
|
||||
namespace QSsh {
|
||||
class SftpChannel;
|
||||
class SshConnectionInfo;
|
||||
class SshDirectTcpIpTunnel;
|
||||
class SshRemoteProcess;
|
||||
|
||||
@@ -56,8 +55,8 @@ public:
|
||||
QSharedPointer<SshRemoteProcess> createRemoteProcess(const QByteArray &command);
|
||||
QSharedPointer<SshRemoteProcess> createRemoteShell();
|
||||
QSharedPointer<SftpChannel> createSftpChannel();
|
||||
QSharedPointer<SshDirectTcpIpTunnel> createTunnel(quint16 remotePort,
|
||||
const SshConnectionInfo &connectionInfo);
|
||||
QSharedPointer<SshDirectTcpIpTunnel> createTunnel(const QString &originatingHost,
|
||||
quint16 originatingPort, const QString &remoteHost, quint16 remotePort);
|
||||
|
||||
int channelCount() const;
|
||||
enum CloseAllMode { CloseAllRegular, CloseAllAndReset };
|
||||
|
@@ -184,10 +184,11 @@ QSharedPointer<SftpChannel> SshConnection::createSftpChannel()
|
||||
return d->createSftpChannel();
|
||||
}
|
||||
|
||||
SshDirectTcpIpTunnel::Ptr SshConnection::createTunnel(quint16 remotePort)
|
||||
SshDirectTcpIpTunnel::Ptr SshConnection::createTunnel(const QString &originatingHost,
|
||||
quint16 originatingPort, const QString &remoteHost, quint16 remotePort)
|
||||
{
|
||||
QSSH_ASSERT_AND_RETURN_VALUE(state() == Connected, SshDirectTcpIpTunnel::Ptr());
|
||||
return d->createTunnel(remotePort);
|
||||
return d->createTunnel(originatingHost, originatingPort, remoteHost, remotePort);
|
||||
}
|
||||
|
||||
int SshConnection::closeAllChannels()
|
||||
@@ -828,9 +829,10 @@ QSharedPointer<SftpChannel> SshConnectionPrivate::createSftpChannel()
|
||||
return m_channelManager->createSftpChannel();
|
||||
}
|
||||
|
||||
SshDirectTcpIpTunnel::Ptr SshConnectionPrivate::createTunnel(quint16 remotePort)
|
||||
SshDirectTcpIpTunnel::Ptr SshConnectionPrivate::createTunnel(const QString &originatingHost,
|
||||
quint16 originatingPort, const QString &remoteHost, quint16 remotePort)
|
||||
{
|
||||
return m_channelManager->createTunnel(remotePort, m_conn->connectionInfo());
|
||||
return m_channelManager->createTunnel(originatingHost, originatingPort, remoteHost, remotePort);
|
||||
}
|
||||
|
||||
const quint64 SshConnectionPrivate::InvalidSeqNr = static_cast<quint64>(-1);
|
||||
|
@@ -127,7 +127,8 @@ public:
|
||||
QSharedPointer<SshRemoteProcess> createRemoteProcess(const QByteArray &command);
|
||||
QSharedPointer<SshRemoteProcess> createRemoteShell();
|
||||
QSharedPointer<SftpChannel> createSftpChannel();
|
||||
QSharedPointer<SshDirectTcpIpTunnel> createTunnel(quint16 remotePort);
|
||||
QSharedPointer<SshDirectTcpIpTunnel> createTunnel(const QString &originatingHost,
|
||||
quint16 originatingPort, const QString &remoteHost, quint16 remotePort);
|
||||
|
||||
// -1 if an error occurred, number of channels closed otherwise.
|
||||
int closeAllChannels();
|
||||
|
@@ -89,7 +89,8 @@ public:
|
||||
QSharedPointer<SshRemoteProcess> createRemoteProcess(const QByteArray &command);
|
||||
QSharedPointer<SshRemoteProcess> createRemoteShell();
|
||||
QSharedPointer<SftpChannel> createSftpChannel();
|
||||
QSharedPointer<SshDirectTcpIpTunnel> createTunnel(quint16 remotePort);
|
||||
QSharedPointer<SshDirectTcpIpTunnel> createTunnel(const QString &originatingHost,
|
||||
quint16 originatingPort, const QString &remoteHost, quint16 remotePort);
|
||||
|
||||
SshStateInternal state() const { return m_state; }
|
||||
SshError error() const { return m_error; }
|
||||
|
@@ -38,11 +38,14 @@
|
||||
namespace QSsh {
|
||||
namespace Internal {
|
||||
|
||||
SshDirectTcpIpTunnelPrivate::SshDirectTcpIpTunnelPrivate(quint32 channelId, quint16 remotePort,
|
||||
const SshConnectionInfo &connectionInfo, SshSendFacility &sendFacility)
|
||||
SshDirectTcpIpTunnelPrivate::SshDirectTcpIpTunnelPrivate(quint32 channelId,
|
||||
const QString &originatingHost, quint16 originatingPort, const QString &remoteHost,
|
||||
quint16 remotePort, SshSendFacility &sendFacility)
|
||||
: AbstractSshChannel(channelId, sendFacility),
|
||||
m_remotePort(remotePort),
|
||||
m_connectionInfo(connectionInfo)
|
||||
m_originatingHost(originatingHost),
|
||||
m_originatingPort(originatingPort),
|
||||
m_remoteHost(remoteHost),
|
||||
m_remotePort(remotePort)
|
||||
{
|
||||
connect(this, SIGNAL(eof()), SLOT(handleEof()));
|
||||
}
|
||||
@@ -112,9 +115,11 @@ void SshDirectTcpIpTunnelPrivate::handleEof()
|
||||
|
||||
using namespace Internal;
|
||||
|
||||
SshDirectTcpIpTunnel::SshDirectTcpIpTunnel(quint32 channelId, quint16 remotePort,
|
||||
const SshConnectionInfo &connectionInfo, SshSendFacility &sendFacility)
|
||||
: d(new SshDirectTcpIpTunnelPrivate(channelId, remotePort, connectionInfo, sendFacility))
|
||||
SshDirectTcpIpTunnel::SshDirectTcpIpTunnel(quint32 channelId, const QString &originatingHost,
|
||||
quint16 originatingPort, const QString &remoteHost, quint16 remotePort,
|
||||
SshSendFacility &sendFacility)
|
||||
: d(new SshDirectTcpIpTunnelPrivate(channelId, originatingHost, originatingPort, remoteHost,
|
||||
remotePort, sendFacility))
|
||||
{
|
||||
connect(d, SIGNAL(initialized()), SIGNAL(initialized()), Qt::QueuedConnection);
|
||||
connect(d, SIGNAL(readyRead()), SIGNAL(readyRead()), Qt::QueuedConnection);
|
||||
@@ -156,9 +161,8 @@ void SshDirectTcpIpTunnel::initialize()
|
||||
try {
|
||||
QIODevice::open(QIODevice::ReadWrite);
|
||||
d->m_sendFacility.sendDirectTcpIpPacket(d->localChannelId(), d->initialWindowSize(),
|
||||
d->maxPacketSize(), d->m_connectionInfo.peerAddress.toString().toUtf8(),
|
||||
d->m_remotePort, d->m_connectionInfo.localAddress.toString().toUtf8(),
|
||||
d->m_connectionInfo.localPort);
|
||||
d->maxPacketSize(), d->m_remoteHost.toUtf8(), d->m_remotePort,
|
||||
d->m_originatingHost.toUtf8(), d->m_originatingPort);
|
||||
d->setChannelState(AbstractSshChannel::SessionRequested);
|
||||
d->m_timeoutTimer.start(d->ReplyTimeout);
|
||||
} catch (const Botan::Exception &e) { // Won't happen, but let's play it safe.
|
||||
|
@@ -37,7 +37,6 @@
|
||||
#include <QSharedPointer>
|
||||
|
||||
namespace QSsh {
|
||||
class SshConnectionInfo;
|
||||
|
||||
namespace Internal {
|
||||
class SshChannelManager;
|
||||
@@ -71,8 +70,9 @@ signals:
|
||||
void tunnelClosed();
|
||||
|
||||
private:
|
||||
SshDirectTcpIpTunnel(quint32 channelId, quint16 remotePort,
|
||||
const SshConnectionInfo &connectionInfo, Internal::SshSendFacility &sendFacility);
|
||||
SshDirectTcpIpTunnel(quint32 channelId, const QString &originatingHost,
|
||||
quint16 originatingPort, const QString &remoteHost, quint16 remotePort,
|
||||
Internal::SshSendFacility &sendFacility);
|
||||
|
||||
// QIODevice stuff
|
||||
qint64 readData(char *data, qint64 maxlen);
|
||||
|
@@ -32,8 +32,6 @@
|
||||
|
||||
#include "sshchannel_p.h"
|
||||
|
||||
#include "sshconnection.h"
|
||||
|
||||
namespace QSsh {
|
||||
class SshDirectTcpIpTunnel;
|
||||
|
||||
@@ -46,8 +44,9 @@ class SshDirectTcpIpTunnelPrivate : public AbstractSshChannel
|
||||
friend class QSsh::SshDirectTcpIpTunnel;
|
||||
|
||||
public:
|
||||
explicit SshDirectTcpIpTunnelPrivate(quint32 channelId, quint16 remotePort,
|
||||
const SshConnectionInfo &connectionInfo, SshSendFacility &sendFacility);
|
||||
explicit SshDirectTcpIpTunnelPrivate(quint32 channelId, const QString &originatingHost,
|
||||
quint16 originatingPort, const QString &remoteHost, quint16 remotePort,
|
||||
SshSendFacility &sendFacility);
|
||||
|
||||
signals:
|
||||
void initialized();
|
||||
@@ -71,8 +70,10 @@ private:
|
||||
|
||||
void closeHook();
|
||||
|
||||
const QString m_originatingHost;
|
||||
const quint16 m_originatingPort;
|
||||
const QString m_remoteHost;
|
||||
const quint16 m_remotePort;
|
||||
const SshConnectionInfo m_connectionInfo;
|
||||
QByteArray m_data;
|
||||
};
|
||||
|
||||
|
@@ -48,7 +48,7 @@ using namespace QSsh;
|
||||
Tunnel::Tunnel(const SshConnectionParameters ¶meters, QObject *parent)
|
||||
: QObject(parent),
|
||||
m_connection(new SshConnection(parameters, this)),
|
||||
m_tunnelServer(new QTcpServer(this)),
|
||||
m_targetServer(new QTcpServer(this)),
|
||||
m_expectingChannelClose(false)
|
||||
{
|
||||
connect(m_connection, SIGNAL(connected()), SLOT(handleConnected()));
|
||||
@@ -74,16 +74,17 @@ void Tunnel::handleConnectionError()
|
||||
void Tunnel::handleConnected()
|
||||
{
|
||||
std::cout << "Opening server side..." << std::endl;
|
||||
if (!m_tunnelServer->listen(QHostAddress::LocalHost)) {
|
||||
if (!m_targetServer->listen(QHostAddress::LocalHost)) {
|
||||
std::cerr << "Error opening port: "
|
||||
<< m_tunnelServer->errorString().toLocal8Bit().constData() << std::endl;
|
||||
<< m_targetServer->errorString().toLocal8Bit().constData() << std::endl;
|
||||
qApp->exit(EXIT_FAILURE);
|
||||
return;
|
||||
}
|
||||
m_forwardedPort = m_tunnelServer->serverPort();
|
||||
connect(m_tunnelServer, SIGNAL(newConnection()), SLOT(handleNewConnection()));
|
||||
m_targetPort = m_targetServer->serverPort();
|
||||
connect(m_targetServer, SIGNAL(newConnection()), SLOT(handleNewConnection()));
|
||||
|
||||
m_tunnel = m_connection->createTunnel(m_forwardedPort);
|
||||
m_tunnel = m_connection->createTunnel(QLatin1String("localhost"), 1024, // made-up values
|
||||
QLatin1String("localhost"), m_targetPort);
|
||||
connect(m_tunnel.data(), SIGNAL(initialized()), SLOT(handleInitialized()));
|
||||
connect(m_tunnel.data(), SIGNAL(error(QString)), SLOT(handleTunnelError(QString)));
|
||||
connect(m_tunnel.data(), SIGNAL(readyRead()), SLOT(handleServerData()));
|
||||
@@ -108,7 +109,7 @@ void Tunnel::handleServerData()
|
||||
if (m_dataReceivedFromServer == ServerDataPrefix + TestData) {
|
||||
std::cout << "Data exchange successful. Closing server socket..." << std::endl;
|
||||
m_expectingChannelClose = true;
|
||||
m_tunnelSocket->close();
|
||||
m_targetSocket->close();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -132,27 +133,27 @@ void Tunnel::handleTunnelClosed()
|
||||
|
||||
void Tunnel::handleNewConnection()
|
||||
{
|
||||
m_tunnelSocket = m_tunnelServer->nextPendingConnection();
|
||||
m_tunnelServer->close();
|
||||
connect(m_tunnelSocket, SIGNAL(error(QAbstractSocket::SocketError)), SLOT(handleSocketError()));
|
||||
connect(m_tunnelSocket, SIGNAL(readyRead()), SLOT(handleClientData()));
|
||||
m_targetSocket = m_targetServer->nextPendingConnection();
|
||||
m_targetServer->close();
|
||||
connect(m_targetSocket, SIGNAL(error(QAbstractSocket::SocketError)), SLOT(handleSocketError()));
|
||||
connect(m_targetSocket, SIGNAL(readyRead()), SLOT(handleClientData()));
|
||||
handleClientData();
|
||||
}
|
||||
|
||||
void Tunnel::handleSocketError()
|
||||
{
|
||||
std::cerr << "Socket error: " << m_tunnelSocket->errorString().toLocal8Bit().constData()
|
||||
std::cerr << "Socket error: " << m_targetSocket->errorString().toLocal8Bit().constData()
|
||||
<< std::endl;
|
||||
qApp->exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
void Tunnel::handleClientData()
|
||||
{
|
||||
m_dataReceivedFromClient += m_tunnelSocket->readAll();
|
||||
m_dataReceivedFromClient += m_targetSocket->readAll();
|
||||
if (m_dataReceivedFromClient == TestData) {
|
||||
std::cout << "Client data successfully received by server, now sending data to client..."
|
||||
<< std::endl;
|
||||
m_tunnelSocket->write(ServerDataPrefix + m_dataReceivedFromClient);
|
||||
m_targetSocket->write(ServerDataPrefix + m_dataReceivedFromClient);
|
||||
}
|
||||
}
|
||||
|
||||
|
@@ -68,9 +68,9 @@ private slots:
|
||||
private:
|
||||
QSsh::SshConnection * const m_connection;
|
||||
QSharedPointer<QSsh::SshDirectTcpIpTunnel> m_tunnel;
|
||||
QTcpServer * const m_tunnelServer;
|
||||
QTcpSocket *m_tunnelSocket;
|
||||
quint16 m_forwardedPort;
|
||||
QTcpServer * const m_targetServer;
|
||||
QTcpSocket *m_targetSocket;
|
||||
quint16 m_targetPort;
|
||||
QByteArray m_dataReceivedFromServer;
|
||||
QByteArray m_dataReceivedFromClient;
|
||||
bool m_expectingChannelClose;
|
||||
|
Reference in New Issue
Block a user