aboutsummaryrefslogtreecommitdiff
path: root/examples/sshnetcat.c
diff options
context:
space:
mode:
Diffstat (limited to 'examples/sshnetcat.c')
-rw-r--r--examples/sshnetcat.c247
1 files changed, 247 insertions, 0 deletions
diff --git a/examples/sshnetcat.c b/examples/sshnetcat.c
new file mode 100644
index 0000000..21b9242
--- /dev/null
+++ b/examples/sshnetcat.c
@@ -0,0 +1,247 @@
+/*
+Copyright 2010 Aris Adamantiadis
+
+This file is part of the SSH Library
+
+You are free to copy this file, modify it in any way, consider it being public
+domain. This does not apply to the rest of the library though, but it is
+allowed to cut-and-paste working code from this file to any license of
+program.
+The goal is to show the API in action. It's not a reference on how terminal
+clients must be made or how a client should react.
+*/
+
+#include "config.h"
+#include <stdio.h>
+#include <unistd.h>
+#include <stdlib.h>
+#include <string.h>
+#include <termios.h>
+
+#include <sys/select.h>
+#include <sys/time.h>
+
+#include <sys/ioctl.h>
+#include <errno.h>
+#include <libssh/callbacks.h>
+#include <libssh/libssh.h>
+#include <libssh/sftp.h>
+
+#include <fcntl.h>
+
+#include "examples_common.h"
+char *host;
+const char *desthost="localhost";
+const char *port="22";
+
+#ifdef WITH_PCAP
+#include <libssh/pcap.h>
+char *pcap_file=NULL;
+#endif
+
+static void usage(){
+ fprintf(stderr,"Usage : sshnetcat [user@]host forwarded_host forwarded_port\n");
+ exit(1);
+}
+
+static int opts(int argc, char **argv){
+ int i;
+ while((i=getopt(argc,argv,"P:"))!=-1){
+ switch(i){
+#ifdef WITH_PCAP
+ case 'P':
+ pcap_file=optarg;
+ break;
+#endif
+ default:
+ fprintf(stderr,"unknown option %c\n",optopt);
+ usage();
+ }
+ }
+ if(optind < argc)
+ host=argv[optind++];
+ if(optind < argc)
+ desthost=argv[optind++];
+ if(optind < argc)
+ port=argv[optind++];
+ if(host==NULL)
+ usage();
+ return 0;
+}
+
+static void select_loop(ssh_session session,ssh_channel channel){
+ fd_set fds;
+ struct timeval timeout;
+ char buffer[4096];
+ /* channels will be set to the channels to poll.
+ * outchannels will contain the result of the poll
+ */
+ ssh_channel channels[2], outchannels[2];
+ int lus;
+ int eof=0;
+ int maxfd;
+ int ret;
+ while(channel){
+ do{
+ FD_ZERO(&fds);
+ if(!eof)
+ FD_SET(0,&fds);
+ timeout.tv_sec=30;
+ timeout.tv_usec=0;
+ FD_SET(ssh_get_fd(session),&fds);
+ maxfd=ssh_get_fd(session)+1;
+ channels[0]=channel; // set the first channel we want to read from
+ channels[1]=NULL;
+ ret=ssh_select(channels,outchannels,maxfd,&fds,&timeout);
+ if(ret==EINTR)
+ continue;
+ if(FD_ISSET(0,&fds)){
+ lus=read(0,buffer,sizeof(buffer));
+ if(lus)
+ channel_write(channel,buffer,lus);
+ else {
+ eof=1;
+ channel_send_eof(channel);
+ }
+ }
+ if(channel && channel_is_closed(channel)){
+ ssh_log(session,SSH_LOG_RARE,"exit-status : %d\n",channel_get_exit_status(channel));
+
+ channel_free(channel);
+ channel=NULL;
+ channels[0]=NULL;
+ }
+ if(outchannels[0]){
+ while(channel && channel_is_open(channel) && channel_poll(channel,0)){
+ lus=channel_read(channel,buffer,sizeof(buffer),0);
+ if(lus==-1){
+ fprintf(stderr, "Error reading channel: %s\n",
+ ssh_get_error(session));
+ return;
+ }
+ if(lus==0){
+ ssh_log(session,SSH_LOG_RARE,"EOF received\n");
+ ssh_log(session,SSH_LOG_RARE,"exit-status : %d\n",channel_get_exit_status(channel));
+
+ channel_free(channel);
+ channel=channels[0]=NULL;
+ } else
+ write(1,buffer,lus);
+ }
+ while(channel && channel_is_open(channel) && channel_poll(channel,1)){ /* stderr */
+ lus=channel_read(channel,buffer,sizeof(buffer),1);
+ if(lus==-1){
+ fprintf(stderr, "Error reading channel: %s\n",
+ ssh_get_error(session));
+ return;
+ }
+ if(lus==0){
+ ssh_log(session,SSH_LOG_RARE,"EOF received\n");
+ ssh_log(session,SSH_LOG_RARE,"exit-status : %d\n",channel_get_exit_status(channel));
+ channel_free(channel);
+ channel=channels[0]=NULL;
+ } else
+ write(2,buffer,lus);
+ }
+ }
+ if(channel && channel_is_closed(channel)){
+ channel_free(channel);
+ channel=NULL;
+ }
+ } while (ret==EINTR || ret==SSH_EINTR);
+
+ }
+}
+
+static void forwarding(ssh_session session){
+ ssh_channel channel;
+ int r;
+ channel=channel_new(session);
+ r=channel_open_forward(channel,desthost,atoi(port),"localhost",22);
+ if(r<0) {
+ printf("error forwarding port : %s\n",ssh_get_error(session));
+ return;
+ }
+ select_loop(session,channel);
+}
+
+static int client(ssh_session session){
+ int auth=0;
+ char *banner;
+ int state;
+
+ if (ssh_options_set(session, SSH_OPTIONS_HOST ,host) < 0)
+ return -1;
+ ssh_options_parse_config(session, NULL);
+
+ if(ssh_connect(session)){
+ fprintf(stderr,"Connection failed : %s\n",ssh_get_error(session));
+ return -1;
+ }
+ state=verify_knownhost(session);
+ if (state != 0)
+ return -1;
+ ssh_userauth_none(session, NULL);
+ banner=ssh_get_issue_banner(session);
+ if(banner){
+ printf("%s\n",banner);
+ free(banner);
+ }
+ auth=authenticate_console(session);
+ if(auth != SSH_AUTH_SUCCESS){
+ return -1;
+ }
+ ssh_log(session, SSH_LOG_FUNCTIONS, "Authentication success");
+ forwarding(session);
+ return 0;
+}
+
+#ifdef WITH_PCAP
+ssh_pcap_file pcap;
+void set_pcap(ssh_session session);
+void set_pcap(ssh_session session){
+ if(!pcap_file)
+ return;
+ pcap=ssh_pcap_file_new();
+ if(ssh_pcap_file_open(pcap,pcap_file) == SSH_ERROR){
+ printf("Error opening pcap file\n");
+ ssh_pcap_file_free(pcap);
+ pcap=NULL;
+ return;
+ }
+ ssh_set_pcap_file(session,pcap);
+}
+
+void cleanup_pcap(void);
+void cleanup_pcap(){
+ ssh_pcap_file_free(pcap);
+ pcap=NULL;
+}
+#endif
+
+int main(int argc, char **argv){
+ ssh_session session;
+
+ session = ssh_new();
+
+ if(ssh_options_getopt(session, &argc, argv)) {
+ fprintf(stderr, "error parsing command line :%s\n",
+ ssh_get_error(session));
+ usage();
+ }
+ opts(argc,argv);
+#ifdef WITH_PCAP
+ set_pcap(session);
+#endif
+ client(session);
+
+ ssh_disconnect(session);
+ ssh_free(session);
+#ifdef WITH_PCAP
+ cleanup_pcap();
+#endif
+
+ ssh_finalize();
+
+ return 0;
+}