Skip to content

Instantly share code, notes, and snippets.

@leite
Last active March 4, 2016 21:36
Show Gist options
  • Save leite/0d2cb77bd7a84954eebc to your computer and use it in GitHub Desktop.
Save leite/0d2cb77bd7a84954eebc to your computer and use it in GitHub Desktop.
test libssh connectivity and iteraction
#include <libssh/libssh.h>
#include <stdlib.h>
#include <stdio.h>
#include <errno.h>
#include <string.h>
int verify_knownhost (ssh_session session) {
int state, hlen;
unsigned char *hash = NULL;
char *hexa;
char buf[10];
state = ssh_is_server_known(session);
hlen = ssh_get_pubkey_hash(session, &hash);
if (hlen < 0)
return -1;
switch (state) {
case SSH_SERVER_KNOWN_OK:
break; // ok
case SSH_SERVER_KNOWN_CHANGED:
fprintf(stderr, "Host key for server changed: it is now:\n");
ssh_print_hexa("Public key hash", hash, hlen);
fprintf(stderr, "For security reasons, connection will be stopped\n");
free(hash);
return -1;
case SSH_SERVER_FOUND_OTHER:
fprintf(stderr, "The host key for this server was not found but an other"
"type of key exists.\n");
fprintf(stderr, "An attacker might change the default server key to"
"confuse your client into thinking the key does not exist\n");
free(hash);
return -1;
case SSH_SERVER_FILE_NOT_FOUND:
fprintf(stderr, "Could not find known host file.\n");
fprintf(stderr, "If you accept the host key here, the file will be"
"automatically created.\n");
// fallback to SSH_SERVER_NOT_KNOWN behavior
case SSH_SERVER_NOT_KNOWN:
hexa = ssh_get_hexa(hash, hlen);
fprintf(stderr,"The server is unknown. Do you trust the host key?\n");
fprintf(stderr, "Public key hash: %s\n", hexa);
free(hexa);
if (fgets(buf, sizeof(buf), stdin) == NULL) {
free(hash);
return -1;
}
if (strncasecmp(buf, "yes", 3) != 0) {
free(hash);
return -1;
}
if (ssh_write_knownhost(session) < 0) {
fprintf(stderr, "Error %s\n", strerror(errno));
free(hash);
return -1;
}
break;
case SSH_SERVER_ERROR:
fprintf(stderr, "Error %s", ssh_get_error(session));
free(hash);
return -1;
}
free(hash);
return 0;
}
int show_remote_processes (ssh_session session) {
ssh_channel channel;
int rc;
char buffer[256];
int nbytes;
channel = ssh_channel_new(session);
if (channel == NULL)
return SSH_ERROR;
rc = ssh_channel_open_session(channel);
if (rc != SSH_OK) {
ssh_channel_free(channel);
return rc;
}
rc = ssh_channel_request_exec(channel, "ps aux");
if (rc != SSH_OK) {
ssh_channel_close(channel);
ssh_channel_free(channel);
return rc;
}
nbytes = ssh_channel_read(channel, buffer, sizeof(buffer), 0);
while (nbytes > 0) {
if (write(1, buffer, nbytes) != (unsigned int) nbytes) {
ssh_channel_close(channel);
ssh_channel_free(channel);
return SSH_ERROR;
}
nbytes = ssh_channel_read(channel, buffer, sizeof(buffer), 0);
}
if (nbytes < 0) {
ssh_channel_close(channel);
ssh_channel_free(channel);
return SSH_ERROR;
}
ssh_channel_send_eof(channel);
ssh_channel_close(channel);
ssh_channel_free(channel);
return SSH_OK;
}
int show_remote_files (ssh_session session) {
ssh_channel channel;
int rc;
printf("\n getting channel \n");
channel = ssh_channel_new(session);
printf("\n got channel ? \n");
if (channel == NULL) return SSH_ERROR;
rc = ssh_channel_open_session(channel);
if (rc != SSH_OK) {
ssh_channel_free(channel);
return rc;
}
//Once a session is open, you can start the remote command with ssh_channel_request_exec():
rc = ssh_channel_request_exec(channel, "ls -l");
if (rc != SSH_OK) {
ssh_channel_close(channel);
ssh_channel_free(channel);
return rc;
}
//If the remote command displays data, you get them with ssh_channel_read(). This function returns the number of bytes read. If there is no more data to read on the channel, this function returns 0, and you can go to next step. If an error has been encountered, it returns a negative value:
char buffer[256];
int nbytes;
nbytes = ssh_channel_read(channel, buffer, sizeof(buffer), 0);
while (nbytes > 0) {
if (fwrite(buffer, 1, nbytes, stdout) != nbytes) {
ssh_channel_close(channel);
ssh_channel_free(channel);
return SSH_ERROR;
}
nbytes = ssh_channel_read(channel, buffer, sizeof(buffer), 0);
}
if (nbytes < 0) {
ssh_channel_close(channel);
ssh_channel_free(channel);
return SSH_ERROR;
}
//Once you read the result of the remote command, you send an end-of-file to the channel, close it, and free the memory that it used:
ssh_channel_send_eof(channel);
ssh_channel_close(channel);
ssh_channel_free(channel);
return SSH_OK;
}
int main () {
ssh_session session;
int rc;
int verbosity = SSH_LOG_PROTOCOL;
int port = 22;
long timeout = 15;
int blocking = 1;
char *banner;
session = ssh_new();
if (session == NULL) exit(-1);
printf("\n start \n");
//ssh_set_blocking(session, 1);
ssh_options_set(session, SSH_OPTIONS_HOST, "grex.org");
ssh_options_set(session, SSH_OPTIONS_USER, "xico");
ssh_options_set(session, SSH_OPTIONS_LOG_VERBOSITY, &verbosity);
ssh_options_set(session, SSH_OPTIONS_PORT, &port);
ssh_options_set(session, SSH_OPTIONS_TIMEOUT, &timeout);
printf("\n getting session \n");
rc = ssh_connect(session);
if (rc != SSH_OK) {
fprintf(stderr, "SSH_CONNECT: %s\n", ssh_get_error(session));
exit(-1);
}
rc = ssh_userauth_password(session, NULL, "29novell");
if (rc == SSH_AUTH_ERROR) {
fprintf(stderr, "Authentication failed: %s\n", ssh_get_error(session));
return SSH_AUTH_ERROR;
}
rc = ssh_userauth_none(session, NULL);
if (rc == SSH_AUTH_ERROR)
return rc;
printf("\n getting banner \n");
banner = ssh_get_issue_banner(session);
printf("\n got banner ? %s \n", banner);
if (banner) {
printf("%s\n", banner);
free(banner);
}
if (verify_knownhost(session) < 0) {
ssh_disconnect(session);
ssh_free(session);
exit(-1);
}
rc = show_remote_processes(session);
if (rc != SSH_OK) {
fprintf(stderr, "Error: %s\n", ssh_get_error(session));
exit(-1);
}
printf("\n show remote files \n");
rc = show_remote_files(session);
if (rc != SSH_OK) {
//ssh_channel_close(session);
//ssh_channel_free(session);
fprintf(stderr, "Error: %s\n", ssh_get_error(session));
return rc;
}
ssh_disconnect(session);
ssh_free(session);
};
@leite
Copy link
Author

leite commented Mar 4, 2016

to compile

$ gcc test.c -o test -lssh

output

$ ./test

 start  

 getting session 
[2016/03/04 18:29:06.939970, 2] ssh_connect:  libssh 0.7.3 (c) 2003-2014 Aris Adamantiadis, Andreas Schneider, and libssh contributors. Distributed under the LGPL, please refer to COPYING file for information about your rights, using threading threads_noop
[2016/03/04 18:29:08.422517, 2] ssh_socket_connect:  Nonblocking connection socket: 3
[2016/03/04 18:29:08.422613, 2] ssh_connect:  Socket connecting, now waiting for the callbacks to work
[2016/03/04 18:29:09.614664, 1] socket_callback_connected:  Socket connection callback: 1 (0)
[2016/03/04 18:29:09.884575, 1] ssh_client_connection_callback:  SSH server banner: SSH-2.0-OpenSSH_5.9
[2016/03/04 18:29:09.884663, 1] ssh_analyze_banner:  Analyzing banner: SSH-2.0-OpenSSH_5.9
[2016/03/04 18:29:09.884698, 1] ssh_analyze_banner:  We are talking to an OpenSSH client version: 5.9 (50900)
[2016/03/04 18:29:10.687454, 2] ssh_packet_dh_reply:  Received SSH_KEXDH_REPLY
[2016/03/04 18:29:10.688393, 2] ssh_client_ecdh_reply:  SSH_MSG_NEWKEYS sent
[2016/03/04 18:29:10.688462, 2] ssh_packet_newkeys:  Received SSH_MSG_NEWKEYS
[2016/03/04 18:29:10.689565, 2] ssh_packet_newkeys:  Signature verified and valid
[2016/03/04 18:29:13.138401, 1] ssh_packet_unimplemented:  Received SSH_MSG_UNIMPLEMENTED (sequence number 5)

 getting banner  

 got banner ? (null) 
[2016/03/04 18:29:27.923684, 2] channel_open:  Creating a channel 43 with 64000 window and 32768 max packet
[2016/03/04 18:29:28.150512, 2] ssh_packet_channel_open_conf:  Received a CHANNEL_OPEN_CONFIRMATION for channel 43:0
[2016/03/04 18:29:28.150648, 2] ssh_packet_channel_open_conf:  Remote window : 0, maxpacket : 32768
[2016/03/04 18:29:28.399795, 2] channel_rcv_change_window:  Adding 2097152 bytes to channel (43:0) (from 0 bytes)
[2016/03/04 18:29:28.399909, 2] channel_request:  Channel request exec success
[2016/03/04 18:29:28.454361, 2] grow_window:  growing window (channel 43:0) to 1280000 bytes
Welcome to Grex.  This is resh.  Type 'help' if you are lost.
grex; 


Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment