====== Scrivere un client ssh con libssh2 ======
Autore: **//Fabio Di Matteo//** \\ Ultima revisione: **//25/07/2008//** \\
[[http://www.libssh2.org/|Libssh2]] è una libreria che implementa il protocollo SSH2 come definito nelle specifiche: SECSH-TRANS, SECSH-USERAUTH, SECSH-CONNECTION, SECSH-ARCH, SECSH-FILEXFER, SECSH-DHGEX, SECSH-NUMBERS, e SECSH-PUBLICKEY . \\
===== Dipendenze =====
* [[http://www.openssl.org/|OpenSSL]];
* [[http://www.gnupg.org/|Libgcrypt]];
* [[http://www.zlib.org/|Zlib]] (opzionale, per la compressione dei dati);
===== Prepariamo quello che serve =====
Siccome non installeremo ''libssh2'' ma la utilizzeremo piuttosto come libreria statica dobbiamo prepararci tutto l'occorrente.
- Scarichiamo [[http://www.libssh2.org/|Libssh2]] (sorgenti);
- compiliamo i sorgenti con ''./configure && make'' ;
- creiamo una directory vuota;
- copiamo nella directory vuota ''libssh2.a'' contenuta in src/.libs;
- copiamo anche tutta ''include/'' ;
- copiamo anche ''example/simple/config.h'' che è un file di configurazione della libreria (non sempre indispensabile).
Bene adesso il contenuto della nostra directory sarà questo:
config.h include libssh2.a
al quale andremo ad aggiungere :
* makefile (il nostro makefile)
* ssh2.c (il sorgente completo del nostro client);
===== Il makefile =====
Semplice e conciso:
all:
gcc -lssl -lcrypto -L/usr/lib -lz ssh2.c libssh2.a -o ssh2
come potete vedere compila staticamente ''libssh2'' ma ha comunque bisogno delle librerie dinamiche ''libssl'', ''libcrypto '' e ''libz '' le quali sono comunemente disponibili su tutte le distribuzioni GNU/Linux ma non solo.
===== Il sorgente del nostro client =====
Esegue il comando specificato nella variabile ''cmd'' (riga 35) .
#include "config.h"
#include "include/libssh2.h"
#ifdef HAVE_WINSOCK2_H
# include
#endif
#ifdef HAVE_NETINET_IN_H
# include
#endif
#ifdef HAVE_SYS_SOCKET_H
# include
#endif
# ifdef HAVE_UNISTD_H
#include
#endif
# ifdef HAVE_ARPA_INET_H
#include
#endif
#include
#include
#include
#include
#include
int main(void)
{
/*Parametri per la connessione SSH*/
char* host="127.0.0.1"; //solo ip, non risolve i nomi di host
int port=22;
char* user="utente";
char* pass="password-segreta";
char* cmd="touch PROVAAA\n";
/*----------------------------------*/
int sock;
LIBSSH2_SESSION *session; //puntatore sessione ssh
LIBSSH2_CHANNEL *channel; //puntatore shell ssh
struct sockaddr_in sin; // socket generico aperto per la connessione
/* Connessione ad un socket generico sulla porta 22 */
sock = socket(AF_INET, SOCK_STREAM, 0);
#ifndef WIN32
fcntl(sock, F_SETFL, 0);
#endif
sin.sin_family = AF_INET;
sin.sin_port = htons(port);
sin.sin_addr.s_addr = inet_addr(host);
if (connect(sock, (struct sockaddr*)(&sin), sizeof(struct sockaddr_in)) != 0) {
fprintf(stderr, "Connessione fallita!\n");
return -1;
}
session = libssh2_session_init();
if (libssh2_session_startup(session, sock)) {
/* istruzioni se la connessione fallisce */
} else {
/* istruzioni se la connessione va a buon fine */
}
/* Autenticazione */
if (libssh2_userauth_password(session, user, pass)) {
/* istruzioni se la autenticazione fallisce */
} else {
/* istruzioni se la autenticazione va a buon fine */
}
/*Apriamo un canale per scrivere i comandi*/
if (!(channel = libssh2_channel_open_session(session))) {
/* l'apertura del canale fallisce */
} else {
/* Successo, si può lanciare una shell in questo canale */
libssh2_channel_shell(channel);
}
/* Lanciamo il comando "touch PROVAAA" e premiamo invio */
libssh2_channel_write(channel, cmd, strlen(cmd));
/* Chiudiamo il canale con la shell associata adesso che abbiamo finito */
libssh2_channel_close(channel);
/* Distruggiamo il puntatore al canale*/
libssh2_channel_free(channel);
/*Ci disconnettiamo e distruggiamo il socket alla connessione */
libssh2_session_disconnect(session, "Goodbye");
libssh2_session_free(session);
return 0;
}
==== Risolvere i nomi degli host ====
Il codice di sopra non risolve i nomi host, ma se si ha l'esigenza di risolverli basta includere [[programmazione:c:una_funzione_per_risolvere_i_nomi_di_dominio]] modificare la sezione dei parametri in questo modo:
...
/*Parametri per la connessione SSH*/
char* host=resolv("localhost");
int port=22;
char* user="utente";
char* pass="password-segreta";
char* cmd="touch PROVAAA\n";
/*----------------------------------*/
...