[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