int SSH2Utils::exec(const char *cmd) { m_execResultStr.clear(); int rc = -1; LIBSSH2_CHANNEL *channel; /* Exec non-blocking on the remove host */ while ((channel = libssh2_channel_open_session(m_session)) == NULL && libssh2_session_last_error(m_session, NULL, NULL, 0) == LIBSSH2_ERROR_EAGAIN) { waitsocket(); } if (channel == NULL) { fprintf(stderr, "Channel Error\n"); m_errCode = 9; return -1; } /* Request a terminal with 'vanilla' terminal emulation * See /etc/termcap for more options */ if (libssh2_channel_request_pty(channel, "vanilla")) { fprintf(stderr, "Failed requesting pty\n"); } /* Open a SHELL on that pty */ if (libssh2_channel_shell(channel)) { fprintf(stderr, "Unable to request shell on allocated pty\n"); } libssh2_channel_write(channel, cmd, strlen(cmd)); libssh2_channel_send_eof(channel); char buffer[BUF_SIZE]; memset(buffer, 0, BUF_SIZE); rc = libssh2_channel_read(channel, buffer, BUF_SIZE); if (rc > 0) { m_execResultStr.append(buffer); } m_channelExitCode = 127; while ((rc = libssh2_channel_close(channel)) == LIBSSH2_ERROR_EAGAIN) waitsocket(); if (rc == 0) { m_channelExitCode = libssh2_channel_get_exit_status(channel); } skip_shell: if (channel) { libssh2_channel_free(channel); channel = NULL; } return rc; }
int main(int argc, char *argv[]) { const char *hostname = "127.0.0.1"; const char *commandline = "uptime"; const char *username = "******"; const char *password = "******"; unsigned long hostaddr; int sock; struct sockaddr_in sin; const char *fingerprint; LIBSSH2_SESSION *session; LIBSSH2_CHANNEL *channel; int rc; int exitcode; char *exitsignal=(char *)"none"; int bytecount = 0; size_t len; LIBSSH2_KNOWNHOSTS *nh; int type; #ifdef WIN32 WSADATA wsadata; int err; err = WSAStartup(MAKEWORD(2,0), &wsadata); if (err != 0) { fprintf(stderr, "WSAStartup failed with error: %d\n", err); return 1; } #endif if (argc > 1) /* must be ip address only */ hostname = argv[1]; if (argc > 2) { username = argv[2]; } if (argc > 3) { password = argv[3]; } if (argc > 4) { commandline = argv[4]; } rc = libssh2_init (0); if (rc != 0) { fprintf (stderr, "libssh2 initialization failed (%d)\n", rc); return 1; } hostaddr = inet_addr(hostname); /* Ultra basic "connect to port 22 on localhost" * Your code is responsible for creating the socket establishing the * connection */ sock = socket(AF_INET, SOCK_STREAM, 0); sin.sin_family = AF_INET; sin.sin_port = htons(22); sin.sin_addr.s_addr = hostaddr; if (connect(sock, (struct sockaddr*)(&sin), sizeof(struct sockaddr_in)) != 0) { fprintf(stderr, "failed to connect!\n"); return -1; } /* Create a session instance */ session = libssh2_session_init(); if (!session) return -1; /* tell libssh2 we want it all done non-blocking */ libssh2_session_set_blocking(session, 0); /* ... start it up. This will trade welcome banners, exchange keys, * and setup crypto, compression, and MAC layers */ while ((rc = libssh2_session_handshake(session, sock)) == LIBSSH2_ERROR_EAGAIN); if (rc) { fprintf(stderr, "Failure establishing SSH session: %d\n", rc); return -1; } nh = libssh2_knownhost_init(session); if(!nh) { /* eeek, do cleanup here */ return 2; } /* read all hosts from here */ libssh2_knownhost_readfile(nh, "known_hosts", LIBSSH2_KNOWNHOST_FILE_OPENSSH); /* store all known hosts to here */ libssh2_knownhost_writefile(nh, "dumpfile", LIBSSH2_KNOWNHOST_FILE_OPENSSH); fingerprint = libssh2_session_hostkey(session, &len, &type); if(fingerprint) { struct libssh2_knownhost *host; #if LIBSSH2_VERSION_NUM >= 0x010206 /* introduced in 1.2.6 */ int check = libssh2_knownhost_checkp(nh, hostname, 22, fingerprint, len, LIBSSH2_KNOWNHOST_TYPE_PLAIN| LIBSSH2_KNOWNHOST_KEYENC_RAW, &host); #else /* 1.2.5 or older */ int check = libssh2_knownhost_check(nh, hostname, fingerprint, len, LIBSSH2_KNOWNHOST_TYPE_PLAIN| LIBSSH2_KNOWNHOST_KEYENC_RAW, &host); #endif fprintf(stderr, "Host check: %d, key: %s\n", check, (check <= LIBSSH2_KNOWNHOST_CHECK_MISMATCH)? host->key:"<none>"); /***** * At this point, we could verify that 'check' tells us the key is * fine or bail out. *****/ } else { /* eeek, do cleanup here */ return 3; } libssh2_knownhost_free(nh); if ( strlen(password) != 0 ) { /* We could authenticate via password */ while ((rc = libssh2_userauth_password(session, username, password)) == LIBSSH2_ERROR_EAGAIN); if (rc) { fprintf(stderr, "Authentication by password failed.\n"); goto shutdown; } } else { /* Or by public key */ while ((rc = libssh2_userauth_publickey_fromfile(session, username, "/home/user/" ".ssh/id_rsa.pub", "/home/user/" ".ssh/id_rsa", password)) == LIBSSH2_ERROR_EAGAIN); if (rc) { fprintf(stderr, "\tAuthentication by public key failed\n"); goto shutdown; } } #if 0 libssh2_trace(session, ~0 ); #endif /* Exec non-blocking on the remove host */ while( (channel = libssh2_channel_open_session(session)) == NULL && libssh2_session_last_error(session,NULL,NULL,0) == LIBSSH2_ERROR_EAGAIN ) { waitsocket(sock, session); } if( channel == NULL ) { fprintf(stderr,"Error\n"); exit( 1 ); } while( (rc = libssh2_channel_exec(channel, commandline)) == LIBSSH2_ERROR_EAGAIN ) { waitsocket(sock, session); } if( rc != 0 ) { fprintf(stderr,"Error\n"); exit( 1 ); } for( ;; ) { /* loop until we block */ int rc; do { char buffer[0x4000]; rc = libssh2_channel_read( channel, buffer, sizeof(buffer) ); if( rc > 0 ) { int i; bytecount += rc; fprintf(stderr, "We read:\n"); for( i=0; i < rc; ++i ) fputc( buffer[i], stderr); fprintf(stderr, "\n"); } else { if( rc != LIBSSH2_ERROR_EAGAIN ) /* no need to output this for the EAGAIN case */ fprintf(stderr, "libssh2_channel_read returned %d\n", rc); } } while( rc > 0 ); /* this is due to blocking that would occur otherwise so we loop on this condition */ if( rc == LIBSSH2_ERROR_EAGAIN ) { waitsocket(sock, session); } else break; } exitcode = 127; while( (rc = libssh2_channel_close(channel)) == LIBSSH2_ERROR_EAGAIN ) waitsocket(sock, session); if( rc == 0 ) { exitcode = libssh2_channel_get_exit_status( channel ); libssh2_channel_get_exit_signal(channel, &exitsignal, NULL, NULL, NULL, NULL, NULL); } if (exitsignal) fprintf(stderr, "\nGot signal: %s\n", exitsignal); else fprintf(stderr, "\nEXIT: %d bytecount: %d\n", exitcode, bytecount); libssh2_channel_free(channel); channel = NULL; shutdown: libssh2_session_disconnect(session, "Normal Shutdown, Thank you for playing"); libssh2_session_free(session); #ifdef WIN32 closesocket(sock); #else close(sock); #endif fprintf(stderr, "all done\n"); libssh2_exit(); return 0; }
static void ssh_stream_free(git_smart_subtransport_stream *stream) { ssh_stream *s = (ssh_stream *)stream; ssh_subtransport *t = OWNING_SUBTRANSPORT(s); int ret; GIT_UNUSED(ret); t->current_stream = NULL; if (s->channel) { libssh2_channel_close(s->channel); libssh2_channel_free(s->channel); s->channel = NULL; } if (s->session) { libssh2_session_free(s->session), s->session = NULL; } if (s->socket.socket) { ret = gitno_close(&s->socket); assert(!ret); } git__free(s->url); git__free(s); }
static void ssh_stream_free(git_smart_subtransport_stream *stream) { ssh_stream *s = (ssh_stream *)stream; ssh_subtransport *t = OWNING_SUBTRANSPORT(s); int ret; GIT_UNUSED(ret); t->current_stream = NULL; if (s->channel) { libssh2_channel_close(s->channel); libssh2_channel_free(s->channel); s->channel = NULL; } if (s->session) { libssh2_session_free(s->session); s->session = NULL; } if (s->socket.socket) { (void)gitno_close(&s->socket); /* can't do anything here with error return value */ } git__free(s->url); git__free(s); }
void PJSSH::ExecuteCmd(const char* aCommand) const { if( !SessionIsOk ) { std::ostringstream o; o<<"Can not execute command since the SSH session is not set up ok. " "Last error message: "; throw std::logic_error(o.str()); } // Try to open a channel to be used for executing the command. LIBSSH2_CHANNEL* channel = libssh2_channel_open_session(mSession); if( NULL == channel ) { throw std::runtime_error("Could not open communication channel for " "executing remote command."); } // Execute the command. if( -1 == libssh2_channel_exec(channel,aCommand)) { throw std::runtime_error("Failed to execute the remote command."); } // Close the channel. libssh2_channel_close(channel); // Free resources. libssh2_channel_free(channel); }
static void ssh_stream_free(git_smart_subtransport_stream *stream) { ssh_stream *s = (ssh_stream *)stream; ssh_subtransport *t; if (!stream) return; t = OWNING_SUBTRANSPORT(s); t->current_stream = NULL; if (s->channel) { libssh2_channel_close(s->channel); libssh2_channel_free(s->channel); s->channel = NULL; } if (s->session) { libssh2_session_free(s->session); s->session = NULL; } if (s->io) { git_stream_close(s->io); git_stream_free(s->io); s->io = NULL; } git__free(s->url); git__free(s); }
static void virNetSSHSessionDispose(void *obj) { virNetSSHSessionPtr sess = obj; VIR_DEBUG("sess=0x%p", sess); if (!sess) return; if (sess->channel) { libssh2_channel_send_eof(sess->channel); libssh2_channel_close(sess->channel); libssh2_channel_free(sess->channel); } libssh2_knownhost_free(sess->knownHosts); libssh2_agent_free(sess->agent); if (sess->session) { libssh2_session_disconnect(sess->session, "libvirt: virNetSSHSessionFree()"); libssh2_session_free(sess->session); } virNetSSHSessionAuthMethodsFree(sess); VIR_FREE(sess->channelCommand); VIR_FREE(sess->hostname); VIR_FREE(sess->knownHostsFile); VIR_FREE(sess->authPath); }
CURLcode Curl_scp_done(struct connectdata *conn, CURLcode status, bool premature) { struct SSHPROTO *scp = conn->data->reqdata.proto.ssh; (void)premature; /* not used */ Curl_safefree(scp->path); scp->path = NULL; if (scp->ssh_channel) { if (libssh2_channel_close(scp->ssh_channel) < 0) { infof(conn->data, "Failed to stop libssh2 channel subsystem\n"); } } if (scp->ssh_session) { libssh2_session_disconnect(scp->ssh_session, "Shutdown"); libssh2_session_free(scp->ssh_session); scp->ssh_session = NULL; } free(conn->data->reqdata.proto.ssh); conn->data->reqdata.proto.ssh = NULL; Curl_pgrsDone(conn); (void)status; /* unused */ return CURLE_OK; }
int ssh::quit_channel() { int rc; exitcode = 127; while( (rc = libssh2_channel_close(channel)) == LIBSSH2_ERROR_EAGAIN ) waitsocket(_sock_fd, session); if( rc == 0 ) { exitcode = libssh2_channel_get_exit_status( channel ); libssh2_channel_get_exit_signal(channel, &exitsignal, NULL, NULL, NULL, NULL, NULL); } if (exitsignal) { printf("\nGot signal: %s\n", exitsignal); } /* else printf("\nEXIT: %d bytecount: %d\n", exitcode, bytecount);*/ libssh2_channel_free(channel); channel = NULL; return 0; }
bool RunCommand(const char *aCommand) { if (!mSessionOK) { return false; } LIBSSH2_CHANNEL *channel = libssh2_channel_open_session(mSession); if (channel == NULL) { strcpy(mErrorMessage, "Could not open SSH2 channel"); return false; } #ifdef libssh2_session_set_timeout libssh2_session_set_timeout(mTimeout); #endif if (libssh2_channel_exec(channel, aCommand) == -1) { strcpy(mErrorMessage, "Could not execute SSH2 command"); return false; } std::string response; char buf[1025]; ssize_t size = 1024; while (size == 1024) { size = libssh2_channel_read(channel, buf, 1024); buf[size] = '\0'; response += buf; } if (mResponse) { delete [] mResponse; } mResponse = new char[response.size()+1]; strcpy(mResponse, response.c_str()); libssh2_channel_close(channel); mExitCode = libssh2_channel_get_exit_status(channel); libssh2_channel_free(channel); return true; }
int exec_shell_script(char* fname, LIBSSH2_SESSION *session, LIBSSH2_CHANNEL **channel, int sock) { int rc; if((rc=open_shell(session, channel, sock)) <0) return -1; FILE* cmdfile = fopen(fname, "r"); if(cmdfile == NULL) { printf("open file %s errno: %s\n", fname, strerror(errno)); exit(errno); } char buf[BUFSIZ]; int i; do { fgets(buf, BUFSIZ, cmdfile); if(feof(cmdfile) == 1) break; write_channel(buf, session, *channel, sock); }while(!feof(cmdfile)); strncpy(buf, "\nexit\n", 6); write_channel(buf, session, *channel, sock); read_channel(session, *channel, sock); fclose(cmdfile); // while((rc = libssh2_channel_close(*channel)) == LIBSSH2_ERROR_EAGAIN) waitsocket(sock, session); rc = libssh2_channel_close(*channel); return rc; }
void Parser::closeChannel(LIBSSH2_CHANNEL *channel) { if(channel) { //libssh2_channel_wait_closed(channel); libssh2_channel_close(channel); libssh2_channel_free(channel); // free will auto close the channel } }
static int netsnmp_ssh_close(netsnmp_transport *t) { int rc = -1; netsnmp_ssh_addr_pair *addr_pair = NULL; if (t != NULL && t->data != NULL) { addr_pair = (netsnmp_ssh_addr_pair *) t->data; } if (t != NULL && addr_pair && t->sock >= 0) { DEBUGMSGTL(("ssh", "close fd %d\n", t->sock)); if (addr_pair->channel) { libssh2_channel_close(addr_pair->channel); libssh2_channel_free(addr_pair->channel); addr_pair->channel = NULL; } if (addr_pair->session) { libssh2_session_disconnect(addr_pair->session, "Normal Shutdown"); libssh2_session_free(addr_pair->session); addr_pair->session = NULL; } #ifndef HAVE_CLOSESOCKET rc = close(t->sock); #else rc = closesocket(t->sock); #endif t->sock = -1; #ifdef SNMPSSHDOMAIN_USE_EXTERNAL_PIPE if (!addr_pair->session && !addr_pair->channel) { /* XXX: make configurable */ unlink(addr_pair->socket_path); } #else /* we're called directly by sshd and use stdin/out */ /* on the server: close stdin/out */ close(STDIN_FILENO); close(STDOUT_FILENO); #endif /* ! SNMPSSHDOMAIN_USE_EXTERNAL_PIPE */ } else { #ifndef SNMPSSHDOMAIN_USE_EXTERNAL_PIPE /* on the server: close stdin/out */ close(STDIN_FILENO); close(STDOUT_FILENO); #endif /* ! SNMPSSHDOMAIN_USE_EXTERNAL_PIPE */ } return rc; }
static PyObject * channel_close(SSH2_ChannelObj *self) { int ret; Py_BEGIN_ALLOW_THREADS ret = libssh2_channel_close(self->channel); Py_END_ALLOW_THREADS CHECK_RETURN_CODE(ret, self->session) Py_RETURN_NONE; }
int CLibssh2::close_ssh_channel(void* channel, std::string* exitsignal, std::string* errmsg) { int exitcode = 127; // 127: command not exists LIBSSH2_CHANNEL* channel_ = static_cast<LIBSSH2_CHANNEL*>(channel); while (channel_ != NULL) { int errcode = libssh2_channel_close(channel_); if (0 == errcode) { char* errmsg_ = NULL; char* exitsignal_ = NULL; exitcode = libssh2_channel_get_exit_status(channel_); if (exitcode != 0) // 0 success { // 调用端可以strerror(*exitcode)取得出错原因 libssh2_channel_get_exit_signal(channel_, &exitsignal_, NULL, &errmsg_, NULL, NULL, NULL); if (errmsg_ != NULL) { *errmsg = errmsg_; free(errmsg_); } if (exitsignal_ != NULL) { *exitsignal = exitsignal_; free(exitsignal_); } } libssh2_channel_free(channel_); channel_ = NULL; break; } else if (LIBSSH2_ERROR_EAGAIN == errcode) { if (!timedwait_socket()) { THROW_SYSCALL_EXCEPTION("channel close timeout", ETIMEDOUT, "poll"); } } else { THROW_EXCEPTION(get_session_errmsg(), errcode); } } return exitcode; }
int ssh_guac_client_free_handler(guac_client* client) { ssh_guac_client_data* guac_client_data = (ssh_guac_client_data*) client->data; /* Close SSH channel */ if (guac_client_data->term_channel != NULL) { libssh2_channel_send_eof(guac_client_data->term_channel); libssh2_channel_close(guac_client_data->term_channel); } /* Free terminal */ guac_terminal_free(guac_client_data->term); pthread_join(guac_client_data->client_thread, NULL); /* Free channels */ libssh2_channel_free(guac_client_data->term_channel); /* Clean up SFTP */ if (guac_client_data->sftp_session) libssh2_sftp_shutdown(guac_client_data->sftp_session); if (guac_client_data->sftp_ssh_session) { libssh2_session_disconnect(guac_client_data->sftp_ssh_session, "Bye"); libssh2_session_free(guac_client_data->sftp_ssh_session); } /* Free session */ if (guac_client_data->session != NULL) libssh2_session_free(guac_client_data->session); /* Free auth key */ if (guac_client_data->key != NULL) ssh_key_free(guac_client_data->key); /* Free clipboard */ guac_common_clipboard_free(guac_client_data->clipboard); /* Free cursors */ guac_ssh_cursor_free(client, guac_client_data->ibar_cursor); guac_ssh_cursor_free(client, guac_client_data->blank_cursor); /* Free generic data struct */ free(client->data); return 0; }
/* * Get DNS query using SSH transport layer. */ static ssize_t dig_ssh_request(struct ssh_session *ssh_info, char *buf, size_t buf_size, ssize_t len) { int ret; ssize_t recv_size; do { ret = libssh2_channel_write(ssh_info->channel, buf, len); if (ret < 0) { ERR("libssh2_channel_write: %d", ret); goto error; } DBG("DNS request of size %ld sent to ssh channel", len); recv_size = libssh2_channel_read(ssh_info->channel, buf, buf_size); if (recv_size < 0) { char *buf; ERR("SSH channel read failed"); libssh2_session_last_error(ssh_info->session, &buf, NULL, 0); ERR("Failure: %s", buf); } else if (recv_size == 0) { ret = libssh2_channel_eof(ssh_info->channel); if (ret) { DBG("SSH server disconnected!"); libssh2_channel_close(ssh_info->channel); libssh2_channel_free(ssh_info->channel); /* Create new channel */ ret = ssh_setup_tunnel(ssh_info, dns_ip); if (ret < 0) { goto error; } } } else { DBG("DNS reply red from ssh channel (size: %ld)", recv_size); goto end; } } while (1); end: return recv_size; error: return -1; }
int close_ssh_connection(void* ssh_session) { int ec; SSH_SESSION* p_session; p_session = (SSH_SESSION*)ssh_session; if(!(login_check(p_session))) { debug_log(SSH_TERMINAL_NO_SESSION_ERROR, "close_ssh_connection : no session."); return SSH_TERMINAL_NO_SESSION_ERROR; } if(p_session->session_param->channel != NULL) { exit_thread(ssh_session); while((ec = libssh2_channel_close(p_session->session_param->channel)) == LIBSSH2_ERROR_EAGAIN) { waitsocket(p_session->session_param->sock, p_session->session_param->session, TIMEOUT_SEC); } libssh2_channel_free(p_session->session_param->channel); p_session->session_param->channel = NULL; } while((ec = libssh2_session_disconnect(p_session->session_param->session, "normal")) == LIBSSH2_ERROR_EAGAIN) { waitsocket(p_session->session_param->sock, p_session->session_param->session, TIMEOUT_SEC); } if(ec < 0) { debug_log(SSH_TERMINAL_SESSION_DISCONNECT_ERROR, "close_ssh_connection : disconnect failed."); return SSH_TERMINAL_SESSION_DISCONNECT_ERROR; } libssh2_session_free(p_session->session_param->session); close(p_session->session_param->sock); free(p_session->session_param); ori_thread_mutex_free(p_session->thread_param->command_queue_mutex); ori_thread_mutex_free(p_session->thread_param->add_list_mutex); ori_thread_condition_free(p_session->thread_param->command_queue_condition); ori_thread_condition_free(p_session->thread_param->add_list_condition); free(p_session->thread_param); free(p_session); return 0; }
int guac_ssh_client_free_handler(guac_client* client) { guac_ssh_client* ssh_client = (guac_ssh_client*) client->data; /* Close SSH channel */ if (ssh_client->term_channel != NULL) { libssh2_channel_send_eof(ssh_client->term_channel); libssh2_channel_close(ssh_client->term_channel); } /* Free terminal (which may still be using term_channel) */ if (ssh_client->term != NULL) { guac_terminal_free(ssh_client->term); pthread_join(ssh_client->client_thread, NULL); } /* Free terminal channel now that the terminal is finished */ if (ssh_client->term_channel != NULL) libssh2_channel_free(ssh_client->term_channel); /* Clean up the SFTP filesystem object and session */ if (ssh_client->sftp_filesystem) { guac_common_ssh_destroy_sftp_filesystem(ssh_client->sftp_filesystem); guac_common_ssh_destroy_session(ssh_client->sftp_session); } /* Free interactive SSH session */ if (ssh_client->session != NULL) guac_common_ssh_destroy_session(ssh_client->session); /* Free SSH client credentials */ if (ssh_client->user != NULL) guac_common_ssh_destroy_user(ssh_client->user); /* Free parsed settings */ if (ssh_client->settings != NULL) guac_ssh_settings_free(ssh_client->settings); /* Free client structure */ free(ssh_client); guac_common_ssh_uninit(); return 0; }
static void ssh_relay_teardown_cb(obfsproxyssh_client_session_t *session) { struct evbuffer *buf; int rval; buf = bufferevent_get_input(session->socks_ev); if (1 == session->ssh_is_valid && 0 < evbuffer_get_length(buf)) { socks_relay_cb(session->socks_ev, session); return; } buf = bufferevent_get_output(session->ssh_ev); if (1 == session->ssh_is_valid && 0 < evbuffer_get_length(buf)) return; if (NULL != session->ssh_channel) { rval = libssh2_channel_close(session->ssh_channel); if (LIBSSH2_ERROR_EAGAIN == rval) return; libssh2_channel_free(session->ssh_channel); session->ssh_channel = NULL; } if (1 == session->ssh_is_valid && 0 < evbuffer_get_length(buf)) return; if (NULL != session->ssh_session) { rval = libssh2_session_disconnect(session->ssh_session, ssh_client_profile_get_disconnect_msg()); if (LIBSSH2_ERROR_EAGAIN == rval) return; libssh2_session_free(session->ssh_session); session->ssh_session = NULL; } if (1 == session->ssh_is_valid && 0 < evbuffer_get_length(buf)) return; session_free(session); }
int open_channel_and_exec(LIBSSH2_SESSION *session, int sock, const char *cmd, char **out) { int rc; LIBSSH2_CHANNEL *chan; chan = waitfor_open_channel(session, sock); if (!chan) return -1; while ((rc = libssh2_channel_exec(chan, cmd)) == LIBSSH2_ERROR_EAGAIN) waitsocket(session, sock); if (rc != 0) return -1; rc = read_channel(chan, session, sock, out); while ((rc = libssh2_channel_close(chan)) == LIBSSH2_ERROR_EAGAIN) waitsocket(session, sock); libssh2_channel_free(chan); return 0; }
@return 0 on success or negative on failure\n\ @rtype int"; static PyObject * PYLIBSSH2_Channel_close(PYLIBSSH2_CHANNEL *self, PyObject *args) { int rc; Py_BEGIN_ALLOW_THREADS rc = libssh2_channel_close(self->channel); rc = libssh2_channel_wait_closed(self->channel); Py_END_ALLOW_THREADS if (rc) { /* CLEAN: PYLIBSSH2_CHANNEL_CANT_CLOSE_MSG */ PyErr_SetString(PYLIBSSH2_Error, "Unable to close the channel."); return NULL; } return Py_BuildValue("i", rc); }
int SSH2Channel::close(ExceptionSink *xsink, int timeout_ms) { AutoLocker al(parent->m); if (check_open(xsink)) return -1; BlockingHelper bh(parent); int rc; while (true) { rc = libssh2_channel_close(channel); if (rc == LIBSSH2_ERROR_EAGAIN) { if ((rc = parent->waitSocketUnlocked(xsink, SSH2CHANNEL_TIMEOUT, "SSH2CHANNEL-CLOSE-ERROR", "SSH2Channel::close", timeout_ms))) break; continue; } if (rc < 0) parent->doSessionErrUnlocked(xsink); break; } return rc; }
int exec_one_cmd(char* cmd, LIBSSH2_SESSION *session, LIBSSH2_CHANNEL **channel, int sock) { int rc; //while((*channel = libssh2_channel_open_session(session)) == NULL && libssh2_session_last_error(session,NULL,NULL,0) == LIBSSH2_ERROR_EAGAIN ) waitsocket(sock, session); *channel = libssh2_channel_open_session(session); if( *channel == NULL ) { fprintf(stderr,"Error\n"); exit(1); } // while((rc = libssh2_channel_exec(*channel, cmd)) == LIBSSH2_ERROR_EAGAIN ) waitsocket(sock, session); rc = libssh2_channel_exec(*channel, cmd); if(rc!=0) { fprintf(stderr,"Error\n"); exit(1); } read_channel(session, *channel, sock); // while((rc = libssh2_channel_close(*channel)) == LIBSSH2_ERROR_EAGAIN) waitsocket(sock, session); rc = libssh2_channel_close(*channel); return rc; }
static int exec_channel_command_exec(SSH_SESSION* p_session, const char* command, int (*callback)(char*, const char*, void*), void* obj) { char* buffer; int buffer_length = COMMAND_RESULT_BUFFER_LENGTH; int ec; int result_code; LIBSSH2_CHANNEL* channel; while((ec = libssh2_channel_exec(p_session->session_param->channel, command)) == LIBSSH2_ERROR_EAGAIN) { waitsocket(p_session->session_param->sock, p_session->session_param->session, TIMEOUT_SEC); } if(ec < 0) { debug_log(SSH_TERMINAL_COMMAND_EXEC_ERROR, "sync_command_exec : channel exec failed."); return SSH_TERMINAL_COMMAND_EXEC_ERROR; } buffer = (char*)malloc(sizeof(char) * (buffer_length + 1)); while(1) { do{ memset(buffer, 0, buffer_length + 1); ec = libssh2_channel_read(p_session->session_param->channel, buffer, buffer_length); if(ec == 0) { ec = libssh2_channel_read_stderr(p_session->session_param->channel, buffer, buffer_length); } if(ec > 0) { callback(buffer, command, obj); } } while(ec > 0); if(ec == LIBSSH2_ERROR_EAGAIN) { waitsocket(p_session->session_param->sock, p_session->session_param->session, TIMEOUT_SEC); } else { break; } } free(buffer); if(ec < 0) { debug_log(SSH_TERMINAL_CHANNEL_READ_ERROR, "sync_command_exec : channel read failed."); result_code = SSH_TERMINAL_CHANNEL_READ_ERROR; } else { result_code = 0; } while(libssh2_channel_close(p_session->session_param->channel) == LIBSSH2_ERROR_EAGAIN) { waitsocket(p_session->session_param->sock, p_session->session_param->session, TIMEOUT_SEC); } libssh2_channel_free(p_session->session_param->channel); while((channel = libssh2_channel_open_session(p_session->session_param->session)) == NULL && libssh2_session_last_error(p_session->session_param->session, NULL, NULL, 0) == LIBSSH2_ERROR_EAGAIN) { waitsocket(p_session->session_param->sock, p_session->session_param->session, TIMEOUT_SEC); } if(channel == NULL) { result_code = SSH_TERMINAL_CHANNEL_OPEN_ERROR; } p_session->session_param->channel = channel; return result_code; }
int ssh_shell_channel_open(void* ssh_session) { SSH_SESSION* p_session; LIBSSH2_CHANNEL* channel; int ec; p_session = (SSH_SESSION*)ssh_session; if(!(login_check(p_session))) { debug_log(SSH_TERMINAL_NO_SESSION_ERROR, "ssh_shell_channel_open : no session."); return SSH_TERMINAL_NO_SESSION_ERROR; } if(p_session->session_param->channel != NULL) { debug_log(SSH_TERMINAL_ALREADY_CHANNEL_OPEN, "ssh_shell_channel_open : already channel open."); return SSH_TERMINAL_ALREADY_CHANNEL_OPEN; } while((channel = libssh2_channel_open_session(p_session->session_param->session)) == NULL && libssh2_session_last_error(p_session->session_param->session, NULL, NULL, 0) == LIBSSH2_ERROR_EAGAIN) { waitsocket(p_session->session_param->sock, p_session->session_param->session, TIMEOUT_SEC); } if(channel == NULL) { debug_log(SSH_TERMINAL_CHANNEL_OPEN_ERROR, "ssh_shell_channel_open : channel open failed."); return SSH_TERMINAL_CHANNEL_OPEN_ERROR; } while((ec = libssh2_channel_request_pty(channel, "vt100")) == LIBSSH2_ERROR_EAGAIN) { waitsocket(p_session->session_param->sock, p_session->session_param->session, TIMEOUT_SEC);; } if(ec < 0){ debug_log(SSH_TERMINAL_REQUEST_PTY_ERROR, "ssh_shell_channel_open : request pty failed."); while(libssh2_channel_close(channel) == LIBSSH2_ERROR_EAGAIN) { waitsocket(p_session->session_param->sock, p_session->session_param->session, TIMEOUT_SEC); } libssh2_channel_free(channel); return SSH_TERMINAL_REQUEST_PTY_ERROR; } while((ec = libssh2_channel_request_pty_size(channel, DEFAULT_PTY_SIZE_WIDTH, DEFAULT_PTY_SIZE_HEIGHT)) == LIBSSH2_ERROR_EAGAIN) { waitsocket(p_session->session_param->sock, p_session->session_param->session, TIMEOUT_SEC); } if(ec < 0){ debug_log(SSH_TERMINAL_REQUEST_PTY_ERROR, "ssh_shell_channel_open : request pty failed."); while(libssh2_channel_close(channel) == LIBSSH2_ERROR_EAGAIN) { waitsocket(p_session->session_param->sock, p_session->session_param->session, TIMEOUT_SEC); } libssh2_channel_free(channel); return SSH_TERMINAL_REQUEST_PTY_ERROR; } while((ec = libssh2_channel_shell(channel)) == LIBSSH2_ERROR_EAGAIN) { waitsocket(p_session->session_param->sock, p_session->session_param->session, TIMEOUT_SEC); } if(ec < 0) { debug_log(SSH_TERMINAL_SHELL_ERROR, "ssh_shell_channel_open : channel shell failed."); while(libssh2_channel_close(channel) == LIBSSH2_ERROR_EAGAIN) { waitsocket(p_session->session_param->sock, p_session->session_param->session, TIMEOUT_SEC); } libssh2_channel_free(channel); return SSH_TERMINAL_SHELL_ERROR; } p_session->session_param->channel = channel; p_session->session_param->channel_type = CHANNEL_TYPE_SHELL; return 0; }
/* example ssh.run["ls /"] */ static int ssh_run(DC_ITEM *item, AGENT_RESULT *result, const char *encoding) { const char *__function_name = "ssh_run"; zbx_sock_t s; LIBSSH2_SESSION *session; LIBSSH2_CHANNEL *channel; int auth_pw = 0, rc, ret = NOTSUPPORTED, exitcode, bytecount = 0; char buffer[MAX_BUFFER_LEN], buf[16], *userauthlist, *publickey = NULL, *privatekey = NULL, *ssherr; size_t sz; zabbix_log(LOG_LEVEL_DEBUG, "In %s()", __function_name); if (FAIL == zbx_tcp_connect(&s, CONFIG_SOURCE_IP, item->interface.addr, item->interface.port, 0)) { SET_MSG_RESULT(result, zbx_dsprintf(NULL, "Cannot connect to SSH server: %s", zbx_tcp_strerror())); goto close; } /* initializes an SSH session object */ if (NULL == (session = libssh2_session_init())) { SET_MSG_RESULT(result, zbx_strdup(NULL, "Cannot initialize SSH session")); goto tcp_close; } /* set blocking mode on session */ libssh2_session_set_blocking(session, 1); /* Create a session instance and start it up. This will trade welcome */ /* banners, exchange keys, and setup crypto, compression, and MAC layers */ if (0 != libssh2_session_startup(session, s.socket)) { libssh2_session_last_error(session, &ssherr, NULL, 0); SET_MSG_RESULT(result, zbx_dsprintf(NULL, "Cannot establish SSH session: %s", ssherr)); goto session_free; } /* check what authentication methods are available */ if (NULL != (userauthlist = libssh2_userauth_list(session, item->username, strlen(item->username)))) { if (NULL != strstr(userauthlist, "password")) auth_pw |= 1; if (NULL != strstr(userauthlist, "keyboard-interactive")) auth_pw |= 2; if (NULL != strstr(userauthlist, "publickey")) auth_pw |= 4; } else { libssh2_session_last_error(session, &ssherr, NULL, 0); SET_MSG_RESULT(result, zbx_dsprintf(NULL, "Cannot obtain authentication methods: %s", ssherr)); goto session_close; } zabbix_log(LOG_LEVEL_DEBUG, "%s() supported authentication methods:'%s'", __function_name, userauthlist); switch (item->authtype) { case ITEM_AUTHTYPE_PASSWORD: if (auth_pw & 1) { /* we could authenticate via password */ if (0 != libssh2_userauth_password(session, item->username, item->password)) { libssh2_session_last_error(session, &ssherr, NULL, 0); SET_MSG_RESULT(result, zbx_dsprintf(NULL, "Password authentication failed: %s", ssherr)); goto session_close; } else zabbix_log(LOG_LEVEL_DEBUG, "%s() password authentication succeeded", __function_name); } else if (auth_pw & 2) { /* or via keyboard-interactive */ password = item->password; if (0 != libssh2_userauth_keyboard_interactive(session, item->username, &kbd_callback)) { libssh2_session_last_error(session, &ssherr, NULL, 0); SET_MSG_RESULT(result, zbx_dsprintf(NULL, "Keyboard-interactive authentication" " failed: %s", ssherr)); goto session_close; } else zabbix_log(LOG_LEVEL_DEBUG, "%s() keyboard-interactive authentication succeeded", __function_name); } else { SET_MSG_RESULT(result, zbx_dsprintf(NULL, "Unsupported authentication method." " Supported methods: %s", userauthlist)); goto session_close; } break; case ITEM_AUTHTYPE_PUBLICKEY: if (auth_pw & 4) { if (NULL == CONFIG_SSH_KEY_LOCATION) { SET_MSG_RESULT(result, zbx_strdup(NULL, "Authentication by public key failed." " SSHKeyLocation option is not set")); goto session_close; } /* or by public key */ publickey = zbx_dsprintf(publickey, "%s/%s", CONFIG_SSH_KEY_LOCATION, item->publickey); privatekey = zbx_dsprintf(privatekey, "%s/%s", CONFIG_SSH_KEY_LOCATION, item->privatekey); if (SUCCEED != zbx_is_regular_file(publickey)) { SET_MSG_RESULT(result, zbx_dsprintf(NULL, "Cannot access public key file %s", publickey)); goto session_close; } if (SUCCEED != zbx_is_regular_file(privatekey)) { SET_MSG_RESULT(result, zbx_dsprintf(NULL, "Cannot access private key file %s", privatekey)); goto session_close; } rc = libssh2_userauth_publickey_fromfile(session, item->username, publickey, privatekey, item->password); zbx_free(publickey); zbx_free(privatekey); if (0 != rc) { libssh2_session_last_error(session, &ssherr, NULL, 0); SET_MSG_RESULT(result, zbx_dsprintf(NULL, "Public key authentication failed:" " %s", ssherr)); goto session_close; } else zabbix_log(LOG_LEVEL_DEBUG, "%s() authentication by public key succeeded", __function_name); } else { SET_MSG_RESULT(result, zbx_dsprintf(NULL, "Unsupported authentication method." " Supported methods: %s", userauthlist)); goto session_close; } break; } /* exec non-blocking on the remove host */ while (NULL == (channel = libssh2_channel_open_session(session))) { switch (libssh2_session_last_error(session, NULL, NULL, 0)) { /* marked for non-blocking I/O but the call would block. */ case LIBSSH2_ERROR_EAGAIN: waitsocket(s.socket, session); continue; default: SET_MSG_RESULT(result, zbx_strdup(NULL, "Cannot establish generic session channel")); goto session_close; } } dos2unix(item->params); /* CR+LF (Windows) => LF (Unix) */ /* request a shell on a channel and execute command */ while (0 != (rc = libssh2_channel_exec(channel, item->params))) { switch (rc) { case LIBSSH2_ERROR_EAGAIN: waitsocket(s.socket, session); continue; default: SET_MSG_RESULT(result, zbx_strdup(NULL, "Cannot request a shell")); goto channel_close; } } for (;;) { /* loop until we block */ do { if (0 < (rc = libssh2_channel_read(channel, buf, sizeof(buf)))) { sz = (size_t)rc; if (sz > MAX_BUFFER_LEN - (bytecount + 1)) sz = MAX_BUFFER_LEN - (bytecount + 1); if (0 == sz) continue; memcpy(buffer + bytecount, buf, sz); bytecount += sz; } } while (rc > 0); /* this is due to blocking that would occur otherwise so we loop on * this condition */ if (LIBSSH2_ERROR_EAGAIN == rc) waitsocket(s.socket, session); else if (rc < 0) { SET_MSG_RESULT(result, zbx_strdup(NULL, "Cannot read data from SSH server")); goto channel_close; } else break; } buffer[bytecount] = '\0'; SET_STR_RESULT(result, convert_to_utf8(buffer, bytecount, encoding)); ret = SYSINFO_RET_OK; channel_close: /* close an active data channel */ exitcode = 127; while (0 != (rc = libssh2_channel_close(channel))) { switch (rc) { case LIBSSH2_ERROR_EAGAIN: waitsocket(s.socket, session); continue; default: libssh2_session_last_error(session, &ssherr, NULL, 0); zabbix_log(LOG_LEVEL_WARNING, "%s() cannot close generic session channel: %s", __function_name, ssherr); break; } } if (0 == rc) exitcode = libssh2_channel_get_exit_status(channel); zabbix_log(LOG_LEVEL_DEBUG, "%s() exitcode: %d bytecount: %d", __function_name, exitcode, bytecount); libssh2_channel_free(channel); channel = NULL; session_close: libssh2_session_disconnect(session, "Normal Shutdown"); session_free: libssh2_session_free(session); tcp_close: zbx_tcp_close(&s); close: zabbix_log(LOG_LEVEL_DEBUG, "End of %s():%s", __function_name, zbx_result_string(ret)); return ret; }
int ssh_cmd(SSH * pSsh,char * pCmdstr) { int ret=0; int exitcode; char *exitsignal=(char *)"none"; if (NULL==pSsh || NULL==pCmdstr) { return 0; } while( (pSsh->channel = libssh2_channel_open_session(pSsh->session)) == NULL && libssh2_session_last_error(pSsh->session,NULL,NULL,0) == LIBSSH2_ERROR_EAGAIN ) { waitsocket(pSsh->sock_fd, pSsh->session); } if( pSsh->channel == NULL ) { fprintf(stderr,"Error\n"); exit( 1 ); } while( (ret = libssh2_channel_exec(pSsh->channel, pCmdstr)) == LIBSSH2_ERROR_EAGAIN ) { waitsocket(pSsh->sock_fd, pSsh->session); } if( ret != 0 ) { fprintf(stderr,"Error\n"); exit( 1 ); } for( ;; ) { /* loop until we block */ int rc; do { char buffer[0x4000]; rc = libssh2_channel_read( pSsh->channel, buffer, sizeof(buffer) ); if( rc > 0 ) { int i; for( i=0; i < rc; ++i ) fputc( buffer[i], stdout); fprintf(stderr, "\n"); } else { if( ret != LIBSSH2_ERROR_EAGAIN ) /* no need to output this for the EAGAIN case */ fprintf(stderr, "libssh2_channel_read returned %d\n", rc); } } while( ret > 0 ); /* this is due to blocking that would occur otherwise so we loop on this condition */ if( rc == LIBSSH2_ERROR_EAGAIN ) { waitsocket(pSsh->sock_fd, pSsh->session); } else break; } exitcode = 127; while( (ret = libssh2_channel_close(pSsh->channel)) == LIBSSH2_ERROR_EAGAIN ) waitsocket(pSsh->sock_fd, pSsh->session); if( ret == 0 ) { exitcode = libssh2_channel_get_exit_status( pSsh->channel ); libssh2_channel_get_exit_signal(pSsh->channel, &exitsignal, NULL, NULL, NULL, NULL, NULL); } if (exitsignal) fprintf(stderr, "\nGot signal: %s\n", exitsignal); fprintf(stderr,"\n*ssh_cmd::pcmdstr=%s\n",pCmdstr); return 0; }
int execute_command(struct remote *rm) { /* Sets up the pthread functionality of gcrypt * libssh2 doesn't do this for us so we have to do it ourselves*/ gcry_control(GCRYCTL_SET_THREAD_CBS, &gcry_threads_pthread); openlog("remote-monitor-base",LOG_PID|LOG_CONS,LOG_USER); syslog(LOG_DEBUG,"Starting SSH execution on rm->hostname: %s with rm->username: %s and port: %d",rm->hostname,rm->username,rm->port); size_t len; int type; unsigned long hostaddress; int sock; const char *fingerprint; int bytecount = 0; struct sockaddr_in sin; LIBSSH2_SESSION *session; LIBSSH2_CHANNEL *channel; LIBSSH2_KNOWNHOSTS *nh; /* results stores the output from the commands after they're executed * Each command has a corresponding result so the results array is set to the same length as the commands array */ rm->results = malloc(rm->num_commands * sizeof(char*)); for(int i = 0; i < rm->num_commands; i++) rm->results[i] = malloc(2048 * sizeof(char)); /* Initialise libssh2 and check to see if it was initialized properly * libssh2_init isn't thread safe so we need to lock the thread while it executes*/ pthread_mutex_lock(&sshinit_lock); int rc = libssh2_init(0); pthread_mutex_unlock(&sshinit_lock); if(rc!=0) { syslog(LOG_ERR,"libssh2 initilization failed"); return 1; } /* Creates a socket connection to the specified host on the specified port */ hostaddress = inet_addr(rm->hostname); sock = socket(AF_INET, SOCK_STREAM, 0); sin.sin_family = AF_INET; sin.sin_port = htons(rm->port); sin.sin_addr.s_addr = hostaddress; /* Check to see if the connection was successful */ if(connect(sock, (struct sockaddr*)(&sin), sizeof(struct sockaddr_in)) != 0) { syslog(LOG_ERR,"Failed to connect to %s on port %d", rm->hostname, rm->port); return 1; } /* Initialise the session and check for success */ session = libssh2_session_init(); if(!session) { syslog(LOG_ERR,"Error creating session on host %s", rm->hostname); return 1; } /* Disable blocking for this session */ libssh2_session_set_blocking(session,0); /* Start the session on the specified socket and check for success */ while( (rc = libssh2_session_startup(session,sock)) == LIBSSH2_ERROR_EAGAIN); if(rc) { syslog(LOG_ERR,"Failure establishing SSH session %d on host %s", rc, rm->hostname); goto error; } /* Get the current host key and check to see if it matches with any known hosts */ nh = libssh2_knownhost_init(session); if(!nh) { syslog(LOG_ERR,"Error while initialising known hosts collection on host %s",rm->hostname); goto error; } libssh2_knownhost_readfile(nh,"known_hosts",LIBSSH2_KNOWNHOST_FILE_OPENSSH); //libssh2_knownhost_writefile(nh,"dumpfile",LIBSSH2_KNOWNHOST_FILE_OPENSSH); fingerprint = libssh2_session_hostkey(session,&len,&type); if(fingerprint) { struct libssh2_knownhost *host; int check = libssh2_knownhost_checkp(nh,rm->hostname,rm->port,fingerprint,len ,LIBSSH2_KNOWNHOST_TYPE_PLAIN|LIBSSH2_KNOWNHOST_KEYENC_RAW,&host); if(check == LIBSSH2_KNOWNHOST_CHECK_MATCH) syslog(LOG_DEBUG,"Found matching host key for host %s",rm->hostname); else if(check == LIBSSH2_KNOWNHOST_CHECK_MISMATCH) syslog(LOG_ERR,"Host key was found but the key's didn't match for host %s",rm->hostname); //TODO Some sort of critical error will need to be generated here else if(check == LIBSSH2_KNOWNHOST_CHECK_NOTFOUND) syslog(LOG_ERR,"No host match was found for %s",rm->hostname); //TODO Have the ability to add the host key here else syslog(LOG_ERR,"There was a failure while attempting to match host keys for host %s",rm->hostname); } else { syslog(LOG_ERR,"Couldn't get host key for host: %s",rm->hostname); goto error; } libssh2_knownhost_free(nh); /* Authenticate with the specified rm->username and passwod and check for success */ // TODO Add ability to authenticate with a private key if( (strlen(rm->password)) != 0 ) { syslog(LOG_DEBUG,"Using rm->password authentication for host %s",rm->hostname); while( (rc = libssh2_userauth_password(session,rm->username,rm->password)) == LIBSSH2_ERROR_EAGAIN); if(rc) { syslog(LOG_ERR,"Authentication to host %s failed",rm->hostname); goto error; } } else if( ( (strlen(rm->publickey)) != 0 ) && ( ( strlen(rm->privatekey)) != 0) ) { syslog(LOG_DEBUG,"Using public key authentication for host %s",rm->hostname); while( (rc = libssh2_userauth_publickey_fromfile(session,rm->username,rm->publickey,rm->privatekey,NULL)) == LIBSSH2_ERROR_EAGAIN); switch(rc) { case 0: break; case LIBSSH2_ERROR_AUTHENTICATION_FAILED: syslog(LOG_ERR,"Authentication using the supplied key for host %s was not accepted",rm->hostname); goto error; case LIBSSH2_ERROR_PUBLICKEY_UNVERIFIED: syslog(LOG_ERR,"The rm->username/public key combination was invalid for host %s",rm->hostname); goto error; default: syslog(LOG_ERR,"Authentication to host %s failed",rm->hostname); goto error; } } /* Open a session for each command */ for(int i = 0; i < rm->num_commands; i++) { /* Open a channel on the current channel and check for success */ while( (channel = libssh2_channel_open_session(session)) == NULL && libssh2_session_last_error(session,NULL,NULL,0) == LIBSSH2_ERROR_EAGAIN) { waitsocket(sock,session); } if(channel == NULL) { syslog(LOG_ERR,"Error opening SSH channel on host %s",rm->hostname); asprintf(&(rm->results[i]),NULL); break; } /* Execute the command and check for success */ while( (rc = libssh2_channel_exec(channel,rm->commands[i])) == LIBSSH2_ERROR_EAGAIN) { waitsocket(sock,session); } if(rc!=0) { syslog(LOG_ERR,"Error while executing %s in channel on host %s",rm->commands[i],rm->hostname); asprintf(&(rm->results[i]),NULL); break; } /* Continuously read the returned stream and break once the stream has been read */ for(;;) { int rc; do { char buffer[2048]; rc = libssh2_channel_read(channel,buffer,sizeof(buffer)); if(rc > 0) { bytecount += rc; char *output; output = buffer; syslog(LOG_ERR,"Got output from command %s on host %s:%s",rm->commands[i],rm->hostname,output); /* Store the output in the results array */ asprintf(&(rm->results[i]),"%s",output); memset(buffer,0,2048); } } while(rc > 0); if(rc == LIBSSH2_ERROR_EAGAIN) { waitsocket(sock,session); } else break; } /* Close the channel and check for success */ while( (rc = libssh2_channel_close(channel)) == LIBSSH2_ERROR_EAGAIN) { waitsocket(sock,session); } if( (libssh2_channel_free(channel)) < 0) syslog(LOG_ERR,"Error while freeing channel on host %s",rm->hostname); channel = NULL; } shutdown: syslog(LOG_DEBUG,"Disconnecting SSH session for host %s",rm->hostname); libssh2_session_disconnect(session,"Normal SSH disconnection"); libssh2_session_free(session); close(sock); libssh2_exit(); closelog(); return 0; error: syslog(LOG_DEBUG,"Disconnection SSH session for host %s",rm->hostname); libssh2_session_disconnect(session,"Normal SSH disconnection"); libssh2_session_free(session); close(sock); libssh2_exit(); closelog(); return 1; }
void * CSubThread::Entry() { fd_set fds; struct timeval tv; ssize_t len, wr; char buf[20480]; int rc, i = 0; const char *shost = inet_ntoa(m_sin.sin_addr); unsigned int sport = ntohs(m_sin.sin_port); wxLogInfo(wxT("Forwarding connection from %s:%d to %s:%d"), wxString(inet_ntoa(m_sin.sin_addr), wxConvLibc).c_str(), sport, m_remote_desthost.c_str(), m_remote_destport); /* Must use blocking here to avoid connect errors */ //libssh2_session_set_blocking(m_subThreadSession, 1); while((m_channel = libssh2_channel_direct_tcpip_ex(m_subThreadSession, m_remote_desthost.mb_str(), m_remote_destport, shost, sport)) == NULL) { rc = libssh2_session_last_error(m_subThreadSession, NULL, NULL, 0); if (rc == LIBSSH2_ERROR_EAGAIN) Sleep(10); else break; } /* Must use non-blocking IO hereafter due to the current libssh2 API */ libssh2_session_set_blocking(m_subThreadSession, 0); if (!m_channel) { wxLogInfo(_("SSH error: Could not open a direct-tcpip channel!")); goto shutdown; } while (1) { FD_ZERO(&fds); FD_SET(m_forwardsock, &fds); tv.tv_sec = 0; tv.tv_usec = 100000; rc = select(m_forwardsock + 1, &fds, NULL, NULL, &tv); memset(buf, 0, sizeof(buf)); if (-1 == rc) { wxLogInfo(_("SSH error: select failed with error code %d"), wxSysErrorCode()); goto shutdown; } if (rc && FD_ISSET(m_forwardsock, &fds)) { len = recv(m_forwardsock, buf, sizeof(buf), 0); if (len < 0) { wxLogInfo(_("SSH error: read failed with error code %d"), wxSysErrorCode()); goto shutdown; } else if (0 == len) { wxLogInfo(_("The client at %s:%d disconnected!"), wxString(inet_ntoa(m_sin.sin_addr), wxConvLibc).c_str(), sport); goto shutdown; } wr = 0; do { i = libssh2_channel_write(m_channel, buf, len); if (i < 0) { wxLogInfo(_("SSH error: libssh2_channel_write with error code %d"), i); goto shutdown; } wr += i; } while (i > 0 && wr < len); } while (1) { len = libssh2_channel_read(m_channel, buf, sizeof(buf)); if (LIBSSH2_ERROR_EAGAIN == len) break; else if (len < 0) { wxLogInfo(_("SSH error: libssh2_channel_read with error code %d"), (int)len); goto shutdown; } wr = 0; while (wr < len) { i = send(m_forwardsock, buf + wr, len - wr, 0); if (i <= 0) { wxLogInfo(_("SSH error: write failed with error code %d"), wxSysErrorCode()); goto shutdown; } wr += i; } if (libssh2_channel_eof(m_channel)) { wxLogInfo(_("Connection at %s:%d disconnected by server"), wxString(inet_ntoa(m_sin.sin_addr), wxConvLibc).c_str(), sport); goto shutdown; } } } shutdown: #ifdef WIN32 closesocket(m_forwardsock); #else close(m_forwardsock); #endif if (m_channel) { libssh2_channel_close(m_channel); libssh2_channel_free(m_channel); m_channel = NULL; } return NULL; }