Bienvenue sur le forum !

Si vous souhaitez rejoindre la communauté, cliquez sur l'un de ces boutons !

Qt 5 : 5.7.1 - Qt Creator : 4.2.0 - Qt Installer : 2.0.3 - JOM : 1.1.2 - Qt Build suite : 1.7.0 - VS Qt 5 : 2.0.0

Tunnel SSH (Qt/libssh)

Après 4 jours de travail acharné du newbie que je suis... voici....

Intégration d'un tunnel SSH (libssh) à Qt !

Quid : Un tunnel SSH permet de masquer une connexion (d'un firewall par exemple) en faisant passer la connexion d'un port Y (par exemple 4587) dans un protocole SSH (port 22, crypté, entrée du tunnel). La connexion réapparait sur le serveur SSH contacté (sortie du tunnel) et atteinte le serveur cible.

Commentaires : Le système est très simple finalement et tourne comme une horloge ! Connexion parfaite sur mysql sur de gros data (>10Mo), HTTP, etc...

Bibliothèque : libssh

ServerTCP.h

#ifndef SERVERTCP_H
#define SERVERTCP_H

#include <QObject>
#include <QTcpSocket>
#include <QTcpServer>

#include <libssh/libssh.h>
#include <stdlib.h>
#include <stdio.h>

#include <listener.h>

class ServerTCP : public QTcpServer
{
Q_OBJECT
public:
explicit ServerTCP();

~ServerTCP();

private slots :
void openLocalPortListener();
void readLocal();
void receiveRemoteToLocal(QByteArray data);

signals :
void sendLocalToRemote(QByteArray);

private :
ssh_session my_ssh_session;
ssh_channel ssh_tunnel_channel;
QTcpSocket *clientConnection;
bool error;



};

#endif // SERVERTCP_H

ServerTCP.cpp

#include "servertcp.h"


ServerTCP :: ServerTCP ()
{
int rc=0;

error = false;

my_ssh_session = ssh_new();

if (my_ssh_session == NULL) { error = true; }

ssh_options_set(my_ssh_session, SSH_OPTIONS_HOST, "remote_ssh_server.fr");
ssh_options_set(my_ssh_session, SSH_OPTIONS_USER, "remote_ssh_user");

rc = ssh_connect(my_ssh_session);
if (rc != SSH_OK) {
qDebug() << "SSH connection : Fail... : " << ssh_get_error(my_ssh_session);
ssh_free(my_ssh_session);
error = true;
} else {
qDebug() << "SSH connection : OK!";
listen(QHostAddress::Any,4587);
connect(this, SIGNAL(newConnection()), this, SLOT(openLocalPortListener()));
}
rc = ssh_userauth_password(my_ssh_session, NULL, "remote_ssh_password");
if (rc != SSH_AUTH_SUCCESS){
qDebug() << "Authenticating : Fail... : " << ssh_get_error(my_ssh_session);
ssh_disconnect(my_ssh_session);
ssh_free(my_ssh_session);
} else {
qDebug() << "Authentificating : OK!";
}

// ssh_disconnect(my_ssh_session);
// ssh_free(my_ssh_session);

}

void ServerTCP::openLocalPortListener()
{
qDebug() << "Incoming connection...";

clientConnection = nextPendingConnection();
listener *threadChannel = new listener(my_ssh_session);
connect(this, SIGNAL(sendLocalToRemote(QByteArray)), threadChannel, SLOT(receiveLocalToRemote(QByteArray)));
connect(threadChannel, SIGNAL(sendRemoteToLocal(QByteArray)), this, SLOT(receiveRemoteToLocal(QByteArray)));
threadChannel->start();


QObject:: connect(clientConnection, SIGNAL(readyRead()), this, SLOT(readLocal()));
}
void ServerTCP::readLocal()
{
QByteArray data(clientConnection->readAll());
emit sendLocalToRemote(data);
qDebug() << "Received on local socket : " << data.length() << " bytes";
}

void ServerTCP::receiveRemoteToLocal(QByteArray data)
{
clientConnection->write(data, data.length());
qDebug() << "Write on local socket : " << data.length() << " bytes";
}

ServerTCP::~ServerTCP()
{

}


listener.h

#ifndef LISTENER_H
#define LISTENER_H

#include <QObject>
#include <QThread>
#include <QByteArrayData>
#include <QDebug>

#include <libssh/libssh.h>

class listener : public QThread
{
Q_OBJECT
public:
explicit listener(ssh_session session);
void run();
~listener();

signals:
void sendRemoteToLocal(QByteArray);

public slots:
void receiveLocalToRemote(QByteArray data);
private:
ssh_channel channel;
};

#endif // LISTENER_H

listener.cpp

#include "listener.h"

listener::listener(ssh_session session)
{
int rc=0;
qDebug() << "Initialize Thread";
channel = ssh_channel_new(session);
if (channel == NULL) { qDebug() << "Initiate channel : Fail..."; } else { qDebug() << "Initiate channel : OK!"; }
rc = channel_open_forward(channel, "target_host", target_port, "local_adresse_(optionnal)", local_port_(optionnal));

if (rc != SSH_OK)
{
qDebug() << "Create forwarding : Fail..." << ssh_get_error(session);
ssh_channel_free(channel);
} else {
qDebug() << "Create forwarding : OK!";
}

}

void listener::run()
{
while(1)
{
int rec=0;
QByteArray buffer;
int totalBytes=0;
char sshBuffer[1024];



do
{
if((rec = ssh_channel_read(channel, sshBuffer, 1024,0)) < 0)
{
qDebug() << "No news about remote host...";
}
if(rec > 0)
{
buffer.append(sshBuffer, rec);
totalBytes += rec;

}
} while(rec == 1024);
if(totalBytes > 0)
{
qDebug() << "Total receive from remote : " << totalBytes << " bytes";
emit sendRemoteToLocal(buffer);
}
buffer.clear();
}

}

void listener::receiveLocalToRemote(QByteArray data)
{
ssh_channel_write(channel, data, data.length());
qDebug() << "Total emit to remote : " << data.length() << " bytes";
}

listener::~listener()
{

}


Connectez-vous ou Inscrivez-vous pour répondre.