[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
HELP: I am having problems executing shell commands via libssh
[Thread Prev] | [Thread Next]
- Subject: HELP: I am having problems executing shell commands via libssh
- From: "Ryan Robinson" <ryan.macmaster.robinson@xxxxxxxxx>
- Reply-to: libssh@xxxxxxxxxx
- Date: Tue, 17 Apr 2012 10:00:44 -0400
- To: <libssh@xxxxxxxxxx>
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