[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

HELP: I am having problems executing shell commands via libssh


I'm trying to implement libssh as part of my application and I seem to be
having issues with ssh_channel_write() and ssh_channel_read().  Below is my
ssh.c file where I define all the functions I'm using.  If someone could
look this over and point out any obvious errors in my code I would be
grateful, as this is the first time I'm using libssh.

 

The actual problem I'm seeing is that when I execute the "debug" section of
create_ssh_session() I don't read a response from the remote computer, and
ssh_channel_poll() returns 0.

 

It's apparent in the code, but this application is written for windows
deployment.

 

// ssh.c

// functions pertaining to the application and control of ssh sessions

// through the use of libssh.h, an open source C library.

 

#include <windows.h>

#include <windef.h>

#include <stdio.h>

#include <conio.h>

#include <time.h>

#include <process.h>

#include "df13652.h"

#include "pro13652.h"

#include "resource.h"

#include "odbc_calls.h"

#include "libssh/include/libssh/libssh.h"

 

extern enum ERRORS g_status_error;

 

extern HWND

      g_hwnd;

 

extern HINSTANCE

      g_hInstance;

 

extern char 

      g_datestring[],

      g_timestring[],

      g_current_esn[],

      g_current_step[];

 

extern int

      g_nCmdShow;

 

ssh_session SBC_SSH_session = NULL;

 

ssh_channel SBC_SSH_channel = NULL;

 

HANDLE out = NULL;

HANDLE in = NULL;

HANDLE threadHandle = NULL;

 

BOOL ssh_logging = TRUE;

BOOL ssh_debug_shell = TRUE;

 

int passedParm = 0;

int threadID = 0;

int g_ssh_active = 0;

int g_wifi_error = TEST_FAILED;

int g_wifi_sl = -999;

int g_cell_error = TEST_FAILED;

int g_cell_rsi = -999;

int g_cell_data = -999;

 

char g_login_host[100];

char g_login_user[100];

char g_login_pwd[100];

int g_login_port;

char g_cell_esn[20];

char g_cell_status[20];

 

HWND dialog;

 

int verify_known_host(ssh_session session)

{

      int state, hlen;

      unsigned char *hash = NULL;

      char *hexa;

      char logbuf[256];

 

      state = ssh_is_server_known(session);

 

      hlen = ssh_get_pubkey_hash(session, &hash);

      if (hlen < 0)

            return SSH_ERROR;

 

      switch (state)

      {

      case SSH_SERVER_KNOWN_OK:

            break; /* ok */

 

      case SSH_SERVER_KNOWN_CHANGED:

            hexa = ssh_get_hexa(hash, hlen);

            sprintf(logbuf,"Host key for server changed: it is now:\n");

            sprintf(logbuf,"%s%s\n",logbuf,hexa);

            sprintf(logbuf,"%sFor security reasons, connection will be
stopped\n",logbuf);

            ssh_log_entry(logbuf);

            //free(hexa);

            //free(hash);

            return SSH_ERROR;

 

      case SSH_SERVER_FOUND_OTHER:

            sprintf(logbuf,"The host key for this server was not found but
an other type of key exists.\n");

            sprintf(logbuf,"%sAn attacker might change the default server
key to confuse your client into thinking the key does not exist\n",logbuf);

            ssh_log_entry(logbuf);

            //free(hash);

            return SSH_ERROR;

 

      case SSH_SERVER_FILE_NOT_FOUND:

            sprintf(logbuf,"Could not find known host file.\n");

            sprintf(logbuf,"%sIf you accept the host key here, the file will
be automatically created.\n",logbuf);

            if(ssh_logging)

                  ssh_log_entry(logbuf);

            /* fallback to SSH_SERVER_NOT_KNOWN behavior */

 

      case SSH_SERVER_NOT_KNOWN:

            hexa = ssh_get_hexa(hash, hlen);

            sprintf(logbuf,"The server is unknown. Public key hash: %s. Will
be accepted by default.",hexa);

            if(ssh_logging)

                  ssh_log_entry(logbuf);

            if(ssh_write_knownhost(SBC_SSH_session) == SSH_ERROR)

                  ssh_log_entry("Error saving known host info for public key
hash.");

            //free(hexa);

            break;

 

      case SSH_SERVER_ERROR:

            sprintf(logbuf,"Error %s",ssh_get_error(session));

            ssh_log_entry(logbuf);

            //free(hash);

            return SSH_ERROR;

      }

 

      //free(hash);

      return SSH_OK;

}

 

int execute_ssh_cmd(ssh_channel channel,char *cmd,int size)

{

      int ssh_ret = SSH_ERROR;

 

      char logbuf[8192];

      char act_cmd[4096];

 

      memcpy((void *)&act_cmd[0],(void *)cmd,size);

      act_cmd[size] = 0x00;

      ssh_ret = ssh_channel_write(channel,act_cmd,size);

      if(ssh_ret < 0)

      {

            sprintf(logbuf,"Write: %s failed",act_cmd);

            ssh_log_entry(logbuf);

            terminate_ssh_session();

            return SSH_ERROR;

      }

 

      if(ssh_logging)

      {

            sprintf(logbuf,"Wrote: %s",act_cmd);

            ssh_log_entry(logbuf);

      }

 

      return SSH_OK;

}

 

int execute_ssh_cmd_wait_resp(ssh_channel channel,char *cmd, char *resp,int
cmd_len)

{

      int ssh_ret = SSH_ERROR;

 

      char logbuf[8192];

      char buffer[4096];

 

      ssh_ret = execute_ssh_cmd(channel,(void *)cmd,cmd_len);

      if(ssh_ret != SSH_OK)

            return ssh_ret;

 

      ssh_ret = ssh_channel_poll(channel,0);

      if(ssh_ret)

      {

            memset(&buffer[0],0x00,sizeof(buffer));

            ssh_ret = ssh_channel_read(channel,(void
*)&buffer[0],sizeof(buffer),0);

            if(ssh_ret < 0)

            {

                  ssh_log_entry("ssh_read failed");

                  terminate_ssh_session();

                  return SSH_ERROR;

            }

 

            if(ssh_logging)

            {

                  sprintf(logbuf,"Read:   %s",buffer);

                  ssh_log_entry(logbuf);

            }

 

            strcpy(resp,buffer);

      }

      else

            resp[0] = 0x00;

 

      return SSH_OK;

}

 

int create_ssh_session(char *host, char *user, char *pwd, int port)

{

      int verbosity = SSH_LOG_RARE;

      int ssh_ret = SSH_ERROR;

      int optimeout = 2L;

 

      char logbuf[8192];

      char buffer[4096];

 

      SBC_SSH_session = ssh_new();

 

      dialog = CreateDialog(g_hInstance,"SSHINIT",g_hwnd,SSHINITDlgProc);

      SendMessage(dialog,WM_COMMAND,CHANGE_TEXT,(LPARAM)"Initializing SSH
session");

 

      if(SBC_SSH_session == NULL)

      {

            ssh_log_entry("Could not Create ssh session");

            DestroyWindow(dialog);

            return NO_SBC_CONNECTION;

      }

 

      ssh_options_set(SBC_SSH_session,SSH_OPTIONS_HOST,host);

      ssh_options_set(SBC_SSH_session,SSH_OPTIONS_USER,user);

      ssh_options_set(SBC_SSH_session,SSH_OPTIONS_PORT,&port);

      ssh_options_set(SBC_SSH_session,SSH_OPTIONS_LOG_VERBOSITY,&verbosity);

      ssh_options_set(SBC_SSH_session,SSH_OPTIONS_TIMEOUT,&optimeout);

 

      if(ssh_logging)

            ssh_log_entry("Created ssh session");

 

      ssh_ret = ssh_connect(SBC_SSH_session);

      if(ssh_ret != SSH_OK)

      {

            ssh_log_entry("Could not connect to ssh log session");

            DestroyWindow(dialog);

            return NO_SBC_CONNECTION;

      }

 

      if(ssh_logging)

            ssh_log_entry("Connected to ssh session");

      

      SendMessage(dialog,WM_COMMAND,CHANGE_TEXT,(LPARAM)"Authenticating
Host");

 

      ssh_ret = verify_known_host(SBC_SSH_session);

      if(ssh_ret != SSH_OK)

      {

            ssh_log_entry("Could not verify host");

            ssh_disconnect(SBC_SSH_session);

            ssh_free(SBC_SSH_session);

            DestroyWindow(dialog);

            return NO_SBC_CONNECTION;

      }

      

      SendMessage(dialog,WM_COMMAND,CHANGE_TEXT,(LPARAM)"Authenticating
User");

 

      ssh_ret = ssh_userauth_password(SBC_SSH_session,NULL,pwd);

      if(ssh_ret != SSH_AUTH_SUCCESS)

      {

            switch(ssh_ret)

            {

            case SSH_AUTH_ERROR:

                  sprintf(logbuf,"Serious Error occured with public key
authentication: %s",ssh_get_error(SBC_SSH_session));

                  break;

            case SSH_AUTH_DENIED:

                  sprintf(logbuf,"Authentication Denied:
%s",ssh_get_error(SBC_SSH_session));

                  break;

            case SSH_AUTH_PARTIAL:

                  sprintf(logbuf,"Partial Authentication:
%s",ssh_get_error(SBC_SSH_session));

                  break;

            default:

                  sprintf(logbuf,"Other return value:
%s",ssh_get_error(SBC_SSH_session));

            }

            ssh_log_entry(logbuf);

            ssh_free(SBC_SSH_session);

            DestroyWindow(dialog);

            return NO_SBC_CONNECTION;

      }

 

      if(ssh_logging)

            ssh_log_entry("In system");

      

      SendMessage(dialog,WM_COMMAND,CHANGE_TEXT,(LPARAM)"Creating Channel");

      

      SBC_SSH_channel = ssh_channel_new(SBC_SSH_session);

      if(SBC_SSH_channel == NULL)

      {

            ssh_log_entry("Could not create ssh channel");

            terminate_ssh_session();

            DestroyWindow(dialog);

            return SSH_ERROR;

      }

      

      SendMessage(dialog,WM_COMMAND,CHANGE_TEXT,(LPARAM)"Opening Channel");

 

      if(ssh_logging)

            ssh_log_entry("created ssh channel");

 

      ssh_ret = ssh_channel_open_session(SBC_SSH_channel);

      if(ssh_ret != SSH_OK)

      {

            ssh_log_entry("Could not open ssh channel");

            terminate_ssh_session();

            DestroyWindow(dialog);

            return SSH_ERROR;

      }

 

      if(ssh_logging)

            ssh_log_entry("ssh channel open");

 

      ssh_ret = ssh_channel_request_shell(SBC_SSH_channel);

      if(ssh_ret != SSH_OK)

      {

            ssh_log_entry("Could not open ssh shell");

            terminate_ssh_session();

            DestroyWindow(dialog);

            return SSH_ERROR;

      }

 

      if(ssh_logging)

            ssh_log_entry("ssh shell open");

 

      memset((void *)&buffer[0],0x00,sizeof(buffer));

      ssh_ret = ssh_channel_read(SBC_SSH_channel,(void
*)buffer,sizeof(buffer),0);

      if(ssh_ret < 0)

      {

            ssh_log_entry("Could not read welcome from shell");

            terminate_ssh_session();

            DestroyWindow(dialog);

            return SSH_ERROR;

      }

 

      if(ssh_logging)

      {

            sprintf(logbuf,"Read: %s",buffer);

            ssh_log_entry(logbuf);

      }

 

      if(ssh_debug_shell)

      {

            memset((void *)&buffer[0],0x00,sizeof(buffer));

            memset((void *)&logbuf[0],0x00,sizeof(logbuf));

            ssh_ret =
execute_ssh_cmd_wait_resp(SBC_SSH_channel,"ls",buffer,2);

            if(ssh_ret != SSH_OK)

            {

                  ssh_log_entry("Could not interact with shell");

                  terminate_ssh_session();

                  DestroyWindow(dialog);

                  return SSH_ERROR;

            }

            else

            {

                  sprintf(logbuf,"CMD: %s RESP: %s","ls",buffer);

                  MessageBox(g_hwnd,logbuf,"DEBUG SSH",MB_OK);

            }

      }

      DestroyWindow(dialog);

      return SSH_OK;

}

 

int log_in(char *host, char *user, char *pwd, int port)

{

      int ret_value = 0;

 

      ret_value = create_ssh_session(host,user,pwd,port);

      return IDOK;

}

 

void terminate_ssh_session(void)

{

      if(SBC_SSH_session)

      {

            if(!ssh_channel_is_closed(SBC_SSH_channel))

                  ssh_channel_free(SBC_SSH_channel);

            if(ssh_is_connected(SBC_SSH_session))

                  ssh_disconnect(SBC_SSH_session);

            ssh_free(SBC_SSH_session);

            SBC_SSH_session = NULL;

            if(ssh_logging)

                  ssh_log_entry("SSH session closed");

      }

      return;

}

 

void ssh_log_entry(char *entry)

{

      char line[8192];

 

      FILE *log = NULL;

 

      update_current_time();

 

      sprintf(line,"%s :: %s %s\n",g_datestring,g_timestring,entry);

 

      if(log = fopen("C:\\IES\\ssh.log","a"))

      {

            fprintf(log,"%s",line);

            fclose(log);

      }

      return;

}

 

After my application runs log_in() the log file looks like this:

 

Apr 17th 2012 :: 09:12:44 Created ssh session

Apr 17th 2012 :: 09:12:45 Connected to ssh session

Apr 17th 2012 :: 09:12:50 In system

Apr 17th 2012 :: 09:12:50 created ssh channel

Apr 17th 2012 :: 09:12:50 ssh channel open

Apr 17th 2012 :: 09:12:50 ssh shell open

Apr 17th 2012 :: 09:12:50 Read: Welcome to Ubuntu 11.10 (GNU/Linux
3.0.0-17-generic i686)

 

* Documentation:  https://help.ubuntu.com/

 

20 packages can be updated.

20 updates are security updates.

 

 

Apr 17th 2012 :: 09:12:50 Wrote: ls

Apr 17th 2012 :: 09:12:53 SSH session closed

 

I should be reading the response from ls, but because the poll returns 0 the
function exits.

 

Any ideas on where to look?  I have no idea.

 

Thank you for your help.  I am very gratefull.

 

 

Ryan Robinson

IES Systems, Inc.

464 Lisbon St.

PO Box 89

Canfield, OH 44406

PH: 330-533-6683 ext 112

FAX: 330-533-7293

 

 

 


Archive administrator: postmaster@lists.cynapses.org