====== 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"; /*----------------------------------*/ ...