#include #include #include #include #include #include #include #include #include #include //# include #ifdef HAVE_WINDOWS_H # include #endif #ifdef HAVE_WINSOCK2_H # include #endif /* FTP-SSL test * -o sshssl sshssl.c -lssl -lcrypto -lssh2 */ // Functions void tunnel_read(int pass); void tunnel_write(char *plaintext[]); // Variables: core char buffer[256]; clock_t time_start = 0; // Variables: SSL SSL *ssl; SSL_METHOD *meth; SSL_CTX *ctx; BIO *ssl_side; BIO *net_side; // Variables: SSH LIBSSH2_SESSION *test_ssh_session; LIBSSH2_CHANNEL *test_ssh_channel; struct hostent *test_ssh_host; const char *ssh_hostname = "censored"; const char *test_ssh_user = "censored"; const char *test_ssh_pass = "censored"; int *test_ssh_sock; struct sockaddr_in test_ssh_addr; const char *remote_host = // censored const char *local_host = "127.0.0.1"; int remote_port = 21; int local_port = 21; ssh_tunnel() { printf("----------setting up SSH \"tunnel\"----------\n"); // Setting up hostnames, IPs and ports test_ssh_host = gethostbyname(ssh_hostname); bzero((char *) &test_ssh_addr, sizeof(test_ssh_addr)); test_ssh_addr.sin_family = AF_INET; bcopy((char *)test_ssh_host->h_addr, (char *)&test_ssh_addr.sin_addr.s_addr, test_ssh_host->h_length); test_ssh_addr.sin_port = htons(22); // Underlying SSH socket test_ssh_sock = socket(AF_INET, SOCK_STREAM, 0); // Connect socket to SSH host:port if (connect(test_ssh_sock,&test_ssh_addr, sizeof(test_ssh_addr)) < 0) printf("Couldn't connect to SSH server!\n"); else printf("Connected to SSH server.\n"); // Setting up the SSH session for tunneling. test_ssh_session = libssh2_session_init(); if (libssh2_session_startup(test_ssh_session, test_ssh_sock) != 0) printf("Unable to start session.\n"); if (libssh2_userauth_password(test_ssh_session, test_ssh_user, test_ssh_pass) != 0) printf("Bad user/pw.\n"); if (!(test_ssh_channel = libssh2_channel_open_session(test_ssh_session))) printf("Failed to open session"); if (libssh2_channel_shell(test_ssh_channel)) printf("Failed requesting shell.\n"); // "Tunnel" test_ssh_channel = libssh2_channel_direct_tcpip_ex(test_ssh_session, remote_host, remote_port, local_host, local_port); if (test_ssh_channel == NULL) { int error = libssh2_session_last_error(test_ssh_session, NULL, NULL, 0); printf("Unable to set up \"tunnel\" channel. (%i)\n\n\n", error); } else printf("SSH \"tunnel\" active.\n"); printf("-------------------DONE--------------------\n"); } void tunnel_read(int pass) { // Illustration 2 bzero(buffer, 256); libssh2_channel_read(test_ssh_channel, buffer, 255); printf("CHANNEL_BUFFER:\t%s", buffer); bzero(buffer, 256); } void tunnel_write(char *plaintext[]) { libssh2_channel_write(test_ssh_channel, plaintext, strlen(plaintext)); } /* Flush any data that SSL has written to the BIO, out to the network */ void ssl_wants_write(void) { char buf[1024]; size_t len; while (BIO_ctrl_pending(net_side) > 0 ) { len = BIO_read(net_side, buf, sizeof buf); libssh2_channel_write(test_ssh_channel, buf, len); } } /* SSL needs to read some data from the network to continue */ void ssl_wants_read(void) { char buf[1024]; size_t len; /* First, flush out any written data - otherwise we may deadlock */ ssl_wants_write(); len = libssh2_channel_read(test_ssh_channel, buf, sizeof buf); BIO_write(net_side, buf, len); } main() { int ret; // Start SSH "tunnel" ssh_tunnel(); // SSL setup SSL_library_init(); meth = SSLv23_method(); ctx = SSL_CTX_new(meth); ssl = SSL_new(ctx); BIO_new_bio_pair(ssl_side, net_side); SSL_set_bio(ssl, ssl_side, ssl_side); // Communicate with FTP server. Get welcome note, ask for FTP server to turn on SSL encryption. tunnel_read(0); // Reads FTP identification/welcome string tunnel_write("AUTH SSL\n"); tunnel_read(0); // AUTH SSL successful bzero(buffer, 256); do { ret = SSL_read(ssl, buffer, 255); // If necessary, SSL_read() will negotiate a TLS/SSL session, if not already explicitly performed switch (SSL_get_error(ssl, ret)) { case SSL_ERROR_WANT_READ: ssl_wants_read(); continue; case SSL_ERROR_WANT_WRITE: ssl_wants_write(); continue; default: } } while (ret < 0) printf("SSL read:\t%s\n", buffer); // Empty //printf("Handshake:\t%i\n", SSL_do_handshake(ssl)); // Currently -1: FATAL error. printf("Shutting down.\n"); SSL_shutdown(ssl); }