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; }
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; }
/** * Blocks until the result code of the process has been returned. */ int process::result() { if (!my->return_code && !my->return_signal) { // we don't have any cached exit status, so wait and obtain the values now my->sshc->my->call_ssh2_function(boost::bind(libssh2_channel_wait_eof, my->chan)); my->sshc->my->call_ssh2_function_throw(boost::bind(libssh2_channel_wait_closed, my->chan), "Error waiting on socket to close: ${message}"); char* exit_signal; char* error_message; libssh2_channel_get_exit_signal(my->chan, &exit_signal, NULL, &error_message, NULL, NULL, NULL); if (exit_signal) { // process terminated with a signal my->return_signal = exit_signal; libssh2_free(my->chan->session, exit_signal); if (error_message) { my->return_signal_message = error_message; libssh2_free(my->chan->session, error_message); } } else my->return_code = libssh2_channel_get_exit_status(my->chan); } if (my->return_signal) FC_THROW("process terminated with signal ${signal}: ${signal_message}", ("signal", *my->return_signal) ("signal_message", my->return_signal_message ? *my->return_signal_message : "")); else return *my->return_code; }
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; }
void clear(LIBSSH2_SESSION *session, LIBSSH2_CHANNEL *channel, int sock) { int exitcode = 127, rc; char *exitsignal=(char *)"none"; if( rc == 0 ) { exitcode = libssh2_channel_get_exit_status( channel ); libssh2_channel_get_exit_signal(channel, &exitsignal, NULL, NULL, NULL, NULL, NULL); } libssh2_channel_free(channel); channel = NULL; libssh2_session_disconnect(session, ""); libssh2_session_free(session); close(sock); libssh2_exit(); }
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 ssh_exec(ssh_conn_t *conn, param_t *params) { LIBSSH2_CHANNEL *channel; int rc; int exitcode = 127; char *exitsignal=(char *)"none"; const char *commandline = params->command; /* Exec non-blocking on the remove host */ while( (channel = libssh2_channel_open_session(conn->session)) == NULL && libssh2_session_last_error(conn->session,NULL,NULL,0) == LIBSSH2_ERROR_EAGAIN ) { waitsocket(conn); } if( channel == NULL ) { fprintf(stderr,"Error\n"); return ( 1 ); } rc = ssh_setenv(channel, params); if(rc<0) { if(rc==LIBSSH2_ERROR_CHANNEL_REQUEST_DENIED) printf("Error: Environment variable is not accepted by target SSH server."); goto shutdown; } while( (rc = libssh2_channel_exec(channel, commandline)) == LIBSSH2_ERROR_EAGAIN ) { waitsocket(conn); } if( rc != 0 ) { fprintf(stderr,"Error\n"); return ( 1 ); } int stream_id = 0; for( ;; ) { /* loop until we block */ int rc; do { char buffer[0x4000]; rc = libssh2_channel_read_ex( channel, stream_id, buffer, sizeof(buffer) ); if( rc > 0 ) { fwrite(buffer, sizeof(char), rc, stream_id==0?stdout:stderr); }else{ if( rc != LIBSSH2_ERROR_EAGAIN ) goto shutdown; } } while( rc > 0 ); /* this is due to blocking that would occur otherwise so we loop on this condition */ if( rc == LIBSSH2_ERROR_EAGAIN ) { waitsocket(conn); } else break; stream_id = stream_id==0?1:0; } while( (rc = libssh2_channel_close(channel)) == LIBSSH2_ERROR_EAGAIN ) waitsocket(conn); if( rc == 0 ) { exitcode = libssh2_channel_get_exit_status( channel ); libssh2_channel_get_exit_signal(channel, &exitsignal, NULL, NULL, NULL, NULL, NULL); } shutdown: libssh2_channel_free(channel); channel = NULL; return exitcode; }
/** * usage: seashell-tunnel [username] [host] [target] * * First n bytes on standard input should be: * * ---------------------------------------------------------------------------------------------------------- * | length / 4 byte unsigned integer | authentication method / 1 byte | authentication data : length bytes | * ---------------------------------------------------------------------------------------------------------- * * Authentication methods: * 0 - password. * * Currently, only password authentication is supported. Therefore, * the authentication method is ignored. It might be worth looking * at supporting public key authentication in the future. This'll * require extending the connection launcher. * * Bytes after n are simply forwarded onwards with no processing applied. * * For password authentication, the null terminating byte is expected to be in the authentication data. * * seashell-tunnel will write a single ASCII 'O' (79) denoting handshake success before starting * two-way forwarding. * * IP address are also written; IPv4 passed as X.X.X.X, IPv6 as [:X:X::X] */ int main (int argc, char *argv[]) { uint32_t length = 0; uint8_t method = 0; int8_t* data = NULL; int i = 0; char stderr_buffer[4096]; ssize_t stderr_read = 0; if (argc < 4) { fprintf(stderr, "usage: %s [username] [host] [target]\n", argv[0]); return IO_ERROR; } FPRINTF_IF_DEBUG(stderr, "%s: Launching tunnel!\n", argv[1]); for (i = 0; i < 4; i++) { uint8_t buf; if (1 != read(0, &buf, 1)) { fprintf(stderr, "%s: I/O error on reading authentication packet length.\n", argv[1]); return IO_ERROR; } length |= buf << (8 * i); } FPRINTF_IF_DEBUG(stderr, "%s: Read authentication packet length.\n", argv[1]); if (1 != read(0, &method, 1)) { fprintf(stderr, "%s: I/O error on reading authentication method.\n", argv[1]); return IO_ERROR; } FPRINTF_IF_DEBUG(stderr, "%s: Read authentication method.\n", argv[1]); data = malloc(length); if (!data) { fprintf(stderr, "%s: Ran out of memory!\n", argv[1]); return OTHER_ERROR; } if (length != read(0, data, length)) { fprintf(stderr, "%s: Couldn't read authentication data!\n", argv[1]); return IO_ERROR; } FPRINTF_IF_DEBUG(stderr, "%s: Read authentication data.\n", argv[1]); /** This is where we need to handle extra authentication methods. */ int error; char* exitsignal; error = seashell_tunnel_startup(); if (error) { fprintf(stderr, "%s: Error launching libssh2!\n", argv[1]); goto end; } char remote_addr[128]; memset(remote_addr, 0, 128); int family; struct seashell_connection* conn = seashell_tunnel_connect_password( argv[2], argv[1], data, &error, remote_addr, &family, argv[3]); if (!conn) { fprintf(stderr, "%s: Error on opening tunnel to %s: %d\n", argv[1], argv[2], error); goto end; } /** Signal success */ { const int8_t success = 'O'; write(1, &success, 1); uint8_t addrlen = strlen(remote_addr); /** Write the address, formatted for URI safety. */ /** IPv6 addresses need to be formatted for safety. */ if (family == AF_INET6) { char buffer[130] = {0}; int bufferlen = snprintf(buffer, 130, "[%s]", remote_addr); write(1, &bufferlen, 1); write(1, buffer, bufferlen); } /** IPv4 addresses do not need to be formatted. */ else if (family == AF_INET) { write(1, &addrlen, 1); write(1, remote_addr, addrlen); } else { fprintf(stderr, "%s: Unknown address family %d!\n", argv[1], family); goto end; } FPRINTF_IF_DEBUG(stderr, "%s: Remote address is '%s' (%d) (%d)\n", argv[1], remote_addr, (int)addrlen, family); } FPRINTF_IF_DEBUG(stderr, "%s: Tunnel launched!\n", argv[1]); /** Now we select from fd 0, write to socket, * select from socket, write to fd 1 */ error = loop_and_copy(0, 1, conn); if (error) { fprintf(stderr, "%s: I/O error on copy: %d\n", argv[1], error); goto report_errors; } /** Make sure the remote end hung up cleanly. */ error = libssh2_channel_get_exit_status(conn->channel); libssh2_channel_get_exit_signal(conn->channel, &exitsignal, NULL, NULL, NULL, NULL, NULL); FPRINTF_IF_DEBUG(stderr, "%s: Remote end hung up with %d (%s)\n", argv[1], error, exitsignal); if (exitsignal) { error = OTHER_ERROR; } report_errors: /** Drain stderr on the SSH connection. */ while ((stderr_read = libssh2_channel_read_stderr(conn->channel, stderr_buffer, sizeof(char)*4096)) > 0) { fwrite(stderr_buffer, sizeof(char), stderr_read, stderr); } end: seashell_tunnel_free(conn); seashell_tunnel_teardown(); return error; }
void Exec::run() { qDebug() << "SecureConnection::Exec::run " << m_command; // Exececute non-blocking on the remote host libssh2_session_set_blocking(m_session, 0); LIBSSH2_CHANNEL *channel; while ( (channel = libssh2_channel_open_session(m_session)) == 0 && libssh2_session_last_error(m_session, 0, 0, 0) == LIBSSH2_ERROR_EAGAIN) { waitsocket(); } if (channel == 0) throw Exception("Failed to open exec channel"); int rc(0); QByteArray cmd(m_command.toLocal8Bit()); while ( (rc = libssh2_channel_exec(channel, cmd.data())) == LIBSSH2_ERROR_EAGAIN) { waitsocket(); } std::string output; int bytecount(0); if (rc == 0) { for ( ; ; ) { // loop until we block int bc; char buffer[0x400]; do { bc = libssh2_channel_read(channel, buffer, sizeof(buffer)); if (bc > 0) { output.append(buffer, bc); bytecount += bc; } //qDebug() <<" sleeping 5"; sleep(5); } while( bc > 0 && !m_terminate); if (m_terminate) break; // this is due to blocking that would occur // otherwise so we loop on this condition if (bc == LIBSSH2_ERROR_EAGAIN) { waitsocket(); }else { break; } } }else { m_errorMessage = "Failed to execute command: " + m_command; } while ( (rc = libssh2_channel_close(channel)) == LIBSSH2_ERROR_EAGAIN ) { waitsocket(); } if (!m_terminate) { char *exitsignal=(char *)"none"; if (rc == 0) { libssh2_channel_get_exit_signal(channel, &exitsignal, 0, 0, 0, 0, 0); } if (exitsignal) { m_errorMessage += "\nClose on channel received signal " + QString(exitsignal); } } libssh2_channel_free(channel); if (!m_errorMessage.isEmpty()) throw Exception(m_errorMessage); if (!m_terminate) m_outputMessage = QString::fromStdString(output).trimmed(); qDebug() << " return:" << m_outputMessage; }
//获取此分站范围内的设备IP std::string CEasyssh::GetDeviceMAC(void) { if (m_bIsErr) { //自动重连 ConnectAP(); return std::string("Error"); } std::string str_ip_pool = ""; char *exitsignal=(char *)"none"; int rc = 0; const char *commandline = "/usr/www/wstalist ath0"; /* Exec non-blocking on the remove host */ LIBSSH2_CHANNEL *channel; while( (channel = libssh2_channel_open_session(m_ssh_session)) == NULL && libssh2_session_last_error(m_ssh_session, NULL, NULL, 0) == LIBSSH2_ERROR_EAGAIN) { waitsocket(m_sock, m_ssh_session); } if(channel == NULL) { TRACE(_T("libssh2_channel_open_session Error\n")); return std::string("Error"); } while( (rc = libssh2_channel_exec(channel, commandline)) == LIBSSH2_ERROR_EAGAIN) { waitsocket(m_sock, m_ssh_session); } if(rc != 0) { return std::string("Error"); } for( ;; ) { /* loop until we block */ int rc; do { char buffer[0x4000]; rc = libssh2_channel_read(channel, buffer, sizeof(buffer)); if(rc > 0) { std::string str_temp(buffer, 0, rc); str_ip_pool += str_temp; } } while( rc > 0 ); /* this is due to blocking that would occur otherwise so we loop on this condition */ if( rc == LIBSSH2_ERROR_EAGAIN ) { waitsocket(m_sock, m_ssh_session); } else break; } while( (rc = libssh2_channel_close(channel)) == LIBSSH2_ERROR_EAGAIN ) waitsocket(m_sock, m_ssh_session); if( rc == 0 ) { libssh2_channel_get_exit_status(channel); libssh2_channel_get_exit_signal(channel, &exitsignal, NULL, NULL, NULL, NULL, NULL); } libssh2_channel_free(channel); channel = NULL; return str_ip_pool; }
int oph_ssh_submit(const char *cmd) { int sock; struct sockaddr_in sin; struct addrinfo hints, *result; LIBSSH2_SESSION *session; LIBSSH2_CHANNEL *channel; int rc; int exitcode; char *exitsignal = (char *) "none"; int bytecount = 0; memset(&hints, 0, sizeof(struct addrinfo)); hints.ai_family = AF_INET; hints.ai_socktype = SOCK_STREAM; hints.ai_flags = 0; hints.ai_protocol = 0; result = NULL; rc = getaddrinfo(oph_ip_target_host, NULL, &hints, &result); if (rc != 0) { pmesg_safe(&global_flag, LOG_ERROR, __FILE__, __LINE__, "Unable to resolve address from target hostname: %s\n", gai_strerror(rc)); return OPH_LIBSSH_ERROR; } sock = socket(AF_INET, SOCK_STREAM, 0); sin.sin_family = AF_INET; sin.sin_port = htons(22); sin.sin_addr.s_addr = ((struct sockaddr_in *) result->ai_addr)->sin_addr.s_addr; freeaddrinfo(result); if (connect(sock, (struct sockaddr *) (&sin), sizeof(struct sockaddr_in)) != 0) { #ifdef WIN32 closesocket(sock); #else close(sock); #endif pmesg_safe(&global_flag, LOG_ERROR, __FILE__, __LINE__, "Failed to connect to submission host\n"); return OPH_LIBSSH_ERROR; } pthread_mutex_lock(&libssh2_flag); // Lock the access to SSH library pmesg_safe(&global_flag, LOG_DEBUG, __FILE__, __LINE__, "SSH2 library locked\n"); rc = libssh2_init(0); if (rc != 0) { #ifdef WIN32 closesocket(sock); #else close(sock); #endif pthread_mutex_unlock(&libssh2_flag); pmesg_safe(&global_flag, LOG_ERROR, __FILE__, __LINE__, "libssh2 initialization failed (%d)\n", rc); return OPH_LIBSSH_ERROR; } session = libssh2_session_init(); if (!session) { #ifdef WIN32 closesocket(sock); #else close(sock); #endif libssh2_exit(); pthread_mutex_unlock(&libssh2_flag); pmesg_safe(&global_flag, LOG_ERROR, __FILE__, __LINE__, "Failed to init ssh sessione\n"); return OPH_LIBSSH_ERROR; } libssh2_session_set_blocking(session, 0); while ((rc = libssh2_session_handshake(session, sock)) == LIBSSH2_ERROR_EAGAIN); if (rc) { libssh2_session_disconnect(session, "Session disconnected"); libssh2_session_free(session); #ifdef WIN32 closesocket(sock); #else close(sock); #endif libssh2_exit(); pthread_mutex_unlock(&libssh2_flag); pmesg_safe(&global_flag, LOG_ERROR, __FILE__, __LINE__, "Failure establishing SSH session: %d\n", rc); return OPH_LIBSSH_ERROR; } while ((rc = libssh2_userauth_publickey_fromfile(session, oph_subm_user, oph_subm_user_publk, oph_subm_user_privk, "")) == LIBSSH2_ERROR_EAGAIN); if (rc) { libssh2_session_disconnect(session, "Session disconnected"); libssh2_session_free(session); #ifdef WIN32 closesocket(sock); #else close(sock); #endif libssh2_exit(); pthread_mutex_unlock(&libssh2_flag); pmesg_safe(&global_flag, LOG_ERROR, __FILE__, __LINE__, "Authentication by public key failed\n"); return OPH_LIBSSH_ERROR; } 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) { libssh2_session_disconnect(session, "Session disconnected"); libssh2_session_free(session); #ifdef WIN32 closesocket(sock); #else close(sock); #endif libssh2_exit(); pthread_mutex_unlock(&libssh2_flag); pmesg_safe(&global_flag, LOG_ERROR, __FILE__, __LINE__, "Error during opening session channel\n"); return OPH_LIBSSH_ERROR; } while ((rc = libssh2_channel_exec(channel, cmd)) == LIBSSH2_ERROR_EAGAIN) { waitsocket(sock, session); } if (rc != 0) { libssh2_channel_free(channel); libssh2_session_disconnect(session, "Session disconnected"); libssh2_session_free(session); #ifdef WIN32 closesocket(sock); #else close(sock); #endif libssh2_exit(); pthread_mutex_unlock(&libssh2_flag); pmesg_safe(&global_flag, LOG_ERROR, __FILE__, __LINE__, "Error during opening session channel\n"); return OPH_LIBSSH_ERROR; } int flag = 0; for (;;) { int rc; do { char buffer[0x4000]; rc = libssh2_channel_read(channel, buffer, sizeof(buffer)); if (rc > 0) { int i; bytecount += rc; if (!flag) { pmesg_safe(&global_flag, LOG_DEBUG, __FILE__, __LINE__, "ssh submission returned:\n"); flag = 1; } for (i = 0; i < rc; ++i) pmesg_safe(&global_flag, LOG_DEBUG, __FILE__, __LINE__, "%c\n", buffer[i]); } else if (rc != LIBSSH2_ERROR_EAGAIN) pmesg_safe(&global_flag, LOG_DEBUG, __FILE__, __LINE__, "ssh channel read returned %d\n", rc); } while (rc > 0); 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) pmesg_safe(&global_flag, LOG_DEBUG, __FILE__, __LINE__, "ssh got signal %s\n", exitsignal); else pmesg_safe(&global_flag, LOG_DEBUG, __FILE__, __LINE__, "ssh exit code %d with: bytecount %d\n", exitcode, bytecount); libssh2_channel_free(channel); channel = NULL; libssh2_session_disconnect(session, "Session ended normally"); libssh2_session_free(session); #ifdef WIN32 closesocket(sock); #else close(sock); #endif pmesg_safe(&global_flag, LOG_DEBUG, __FILE__, __LINE__, "Session ended normally\n"); libssh2_exit(); pthread_mutex_unlock(&libssh2_flag); // Release the lock for SSH library pmesg_safe(&global_flag, LOG_DEBUG, __FILE__, __LINE__, "SSH2 library unlocked\n"); return OPH_LIBSSH_OK; }