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