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; }
int SyncTransferThread::do_touch_sftp_file_with_time(QString fileName, QDateTime time) { // sftp_open, 可以得到当前的文件属性 // sftp_close, // 修改LIBSSH2_SFTP_ATTRIBUTE中的最后修改日期 // sftp_set_stat, 修改文件的最后修改日期。 LIBSSH2_SFTP_ATTRIBUTES attr; int ret; ret = libssh2_sftp_stat(this->ssh2_sftp, GlobalOption::instance()->remote_codec->fromUnicode(fileName), &attr); if (ret != 0) { //int libssh2_session_last_error(LIBSSH2_SESSION *session, char **errmsg, int *errmsg_len, int want_buf char errmsg[200] = {0}; int emlen = 0; libssh2_session_last_error(this->ssh2_sess, (char **)&errmsg, &emlen, 0); q_debug()<<"sftp set stat error: "<<errmsg; } attr.flags = LIBSSH2_SFTP_ATTR_ACMODTIME; attr.mtime = time.toTime_t(); ret = libssh2_sftp_setstat(this->ssh2_sftp, GlobalOption::instance()->remote_codec->fromUnicode(fileName), &attr); if (ret != 0) { char errmsg[200] = {0}; int emlen = 0; libssh2_session_last_error(this->ssh2_sess, (char **)&errmsg, &emlen, 0); q_debug()<<"sftp set stat error: "<<errmsg; } return 0; }
/** * @function ssh.writeFile * * ### Synopsis * * var status = ssh.writeFile(handle, srcPath, dstPath); * var status = ssh.writeFile(handle, srcPath, dstPath, mode); * * Write file to remote server via SCP. * * @param {object} handle - opaque handle to already open SSH2 connection. * @param {string} srcPath - path to file in local file system to send. * @param {string} dstPath - path to file in remote file system to create. * @param {int} mode - desired resulting file permissions of file on remote end. * @return {boolean} success - true if the transfer succeeded, string error message if transfer failed. * * ### Note * If mode is not provided, the file mode of the file being sent will be used. */ static JSVAL ssh2_scp_send(JSARGS args) { HandleScope scope; SSH2 *ssh2 = HANDLE(args[0]); String::Utf8Value srcPath(args[1]); String::Utf8Value dstPath(args[2]); int mode; struct stat fileinfo; if (stat(*srcPath, &fileinfo) != 0) { return scope.Close(String::New(strerror(errno))); } if (args.Length() > 3) { mode = args[3]->IntegerValue(); } else { mode = fileinfo.st_mode; } mode &= 0777; int fd = open(*srcPath, O_RDONLY); if (fd < 0) { return scope.Close(String::New(strerror(errno))); } #ifdef libssh2_scp_send64 LIBSSH2_CHANNEL *channel = libssh2_scp_send64(ssh2->mSession, *dstPath, mode, fileinfo.st_size, 0, 0); #else LIBSSH2_CHANNEL *channel = libssh2_scp_send(ssh2->mSession, *dstPath, mode, fileinfo.st_size); #endif if (!channel) { char *errmsg; int errlen; libssh2_session_last_error(ssh2->mSession, &errmsg, &errlen, 0); return scope.Close(String::New(errmsg, errlen)); } char mem[1024]; ssize_t toWrite = fileinfo.st_size; while (toWrite > 0) { ssize_t nRead = read(fd, mem, 1024); if (nRead < 0) { int eNum = errno; libssh2_channel_free(channel); close(fd); return scope.Close(String::New(strerror(eNum))); } int rc = libssh2_channel_write(channel, mem, nRead); if (rc < 0) { char *errmsg; int errlen; libssh2_session_last_error(ssh2->mSession, &errmsg, &errlen, 0); libssh2_channel_free(channel); close(fd); return scope.Close(String::New(errmsg)); } toWrite -= nRead; } close(fd); libssh2_channel_free(channel); return scope.Close(True()); }
const char* ssh_strerror (LIBSSH2_SESSION* session) { char* errmsg; int errmsg_len; libssh2_session_last_error (session, &errmsg, &errmsg_len, 0); return errmsg; }
sftp_error_setg(Error **errp, BDRVSSHState *s, const char *fs, ...) { va_list args; char *msg; va_start(args, fs); msg = g_strdup_vprintf(fs, args); va_end(args); if (s->sftp) { char *ssh_err; int ssh_err_code; unsigned long sftp_err_code; /* This is not an errno. See <libssh2.h>. */ ssh_err_code = libssh2_session_last_error(s->session, &ssh_err, NULL, 0); /* See <libssh2_sftp.h>. */ sftp_err_code = libssh2_sftp_last_error((s)->sftp); error_setg(errp, "%s: %s (libssh2 error code: %d, sftp error code: %lu)", msg, ssh_err, ssh_err_code, sftp_err_code); } else { error_setg(errp, "%s", msg); } g_free(msg); }
@rtype libssh2.Channel"; static PyObject * PYLIBSSH2_Session_open_session(PYLIBSSH2_SESSION *self, PyObject *args) { int dealloc = 1; LIBSSH2_CHANNEL *channel; if (!PyArg_ParseTuple(args, "|i:open_session", &dealloc)) { return NULL; } channel = libssh2_channel_open_session(self->session); if (channel== NULL){ if (libssh2_session_last_error(self->session,NULL,NULL,0) == LIBSSH2_ERROR_EAGAIN){ return Py_BuildValue(""); } else{ PyErr_SetString(PYLIBSSH2_Error, "Failed to open channel"); return NULL; } } else { return (PyObject *)PYLIBSSH2_Channel_New(channel, dealloc); } }
x11_req() -- requests an X11 Forwarding channel\n\ "); static PyObject * PYLIBSSH2_Channel(PyObject *self, PyObject *args) { PYLIBSSH2_SESSION *session; LIBSSH2_CHANNEL *channel; int dealloc = 1; if (!PyArg_ParseTuple(args, "O|i:Channel", &session, &dealloc)) { return NULL; } channel = libssh2_channel_open_session(session->session); if (channel== NULL){ if (libssh2_session_last_error(session->session,NULL,NULL,0) == LIBSSH2_ERROR_EAGAIN){ return Py_BuildValue(""); } else{ PyErr_SetString(PYLIBSSH2_Error, "Failed to open channel"); return NULL; } } else { return (PyObject *)PYLIBSSH2_Channel_New(channel, dealloc); } }
void getClient(char * serverAddress) { int sockFd = makeSocketOrDie(); struct addrinfo * serverInfo = getServerInfo(serverAddress); printf("Connecting to server\n"); connectOrDie(sockFd, serverInfo); printf("Connected to server. Making LIBSSH2 session\n"); LIBSSH2_SESSION * session = makeSession(); libssh2_session_set_blocking(session, 1); libssh2_session_set_timeout(session, 5000); printf("Made session, handshaking\n"); int result = libssh2_session_handshake(session, sockFd); //const char * fingerprint = libssh2_hostkey_hash(session, LIBSSH_HOSTKEY_HASH_SHA1); //TODO: Match the fingerprint against something. if (result) { char * errorMessage; libssh2_session_last_error(session, &errorMessage, NULL, 0); fprintf(stderr, "Error %s handshaking\n", errorMessage); exit(EXIT_FAILURE); } printf("Handshake completed, making SFTP Session\n"); libssh2_userauth_password(session, NETID, PWD); LIBSSH2_SFTP * sftpSession = makeSFTPSession(session); printf("Started SFTP - Downloading file\n"); LIBSSH2_SFTP_HANDLE * fileHandle = libssh2_sftp_open(sftpSession, serverFilePath, LIBSSH2_FXF_READ, 0); readFile(session, sftpSession, fileHandle); libssh2_sftp_shutdown(sftpSession); libssh2_session_disconnect(session, "Done.\n"); libssh2_session_free(session); freeaddrinfo(serverInfo); close(sockFd); }
sftp_error_report(BDRVSSHState *s, const char *fs, ...) { va_list args; va_start(args, fs); error_vprintf(fs, args); if ((s)->sftp) { char *ssh_err; int ssh_err_code; unsigned long sftp_err_code; /* This is not an errno. See <libssh2.h>. */ ssh_err_code = libssh2_session_last_error(s->session, &ssh_err, NULL, 0); /* See <libssh2_sftp.h>. */ sftp_err_code = libssh2_sftp_last_error((s)->sftp); error_printf(": %s (libssh2 error code: %d, sftp error code: %lu)", ssh_err, ssh_err_code, sftp_err_code); } va_end(args); error_printf("\n"); }
static void ssh_error(LIBSSH2_SESSION *session, const char *errmsg) { char *ssherr; libssh2_session_last_error(session, &ssherr, NULL, 0); giterr_set(GITERR_SSH, "%s: %s", errmsg, ssherr); }
QString SshScpSend::send() { QFileInfo src(_source); const char *loclfile=qPrintable(src.absoluteFilePath()); _currentState = ScpPrepare; _local = fopen(loclfile, "rb"); if (!_local) { qDebug() << "ERROR : Can't open local file " << loclfile; return ""; } stat(loclfile, &_fileinfo); /* Send a file via scp. The mode parameter must only have permissions! */ #ifdef DEBUG_SCPSEND qDebug() << "DEBUG : Send to " << qPrintable(_destination + "/" + src.fileName()); #endif sshChannel = libssh2_scp_send(sshClient->session(), qPrintable(_destination + src.fileName()), _fileinfo.st_mode & 0777, (unsigned long)_fileinfo.st_size); if ((!sshChannel) && (libssh2_session_last_errno(sshClient->session()) != LIBSSH2_ERROR_EAGAIN)) { char *errmsg; int errlen; libssh2_session_last_error(sshClient->session(), &errmsg, &errlen, 0); qDebug() << "ERROR : Unable to open a session: " << errmsg; _currentState = ScpError; } #ifdef DEBUG_SCPSEND qDebug() << "DEBUG : End of send function"; #endif return _destination + src.fileName(); }
void printSftpErrorAndDie(LIBSSH2_SESSION * session, LIBSSH2_SFTP * sftpSession) { char * errorMessage; libssh2_session_last_error(session, &errorMessage, NULL, 0); fprintf(stderr, "Error %s\n", errorMessage); long lastErr = libssh2_sftp_last_error(sftpSession); fprintf(stderr, "Error code: %ld\n", lastErr); fprintf(stderr, "No such file? %d\n", lastErr == LIBSSH2_FX_NO_SUCH_FILE); exit(EXIT_FAILURE); }
LIBSSH2_CHANNEL *waitfor_open_channel(LIBSSH2_SESSION *session, int sock) { LIBSSH2_CHANNEL *chan = NULL; while (!(chan = libssh2_channel_open_session(session))) { int err = libssh2_session_last_error(session, NULL, NULL, 0); if (err != LIBSSH2_ERROR_EAGAIN) break; waitsocket(session, sock); } return chan; }
LIBSSH2_SFTP * makeSFTPSession(LIBSSH2_SESSION * session) { LIBSSH2_SFTP * result = libssh2_sftp_init(session); if (!result) { fprintf(stderr, "Failed to initiate sftp session\n"); char * errorMessage; libssh2_session_last_error(session, &errorMessage, NULL, 0); fprintf(stderr, "Error %s\n", errorMessage); exit(EXIT_FAILURE); } return result; }
void sftpfs_ssherror_to_gliberror (sftpfs_super_data_t * super_data, int libssh_errno, GError ** mcerror) { char *err = NULL; int err_len; mc_return_if_error (mcerror); libssh2_session_last_error (super_data->session, &err, &err_len, 1); mc_propagate_error (mcerror, libssh_errno, "%s", err); g_free (err); }
void print_last_session_error(const char *function) { if(connected_session) { char *message; int rc = libssh2_session_last_error(connected_session, &message, NULL, 0); fprintf(stderr, "%s failed (%d): %s\n", function, rc, message); } else { fprintf(stderr, "No session"); } }
@rtype tuple"; static PyObject * PYLIBSSH2_Session_last_error(PYLIBSSH2_SESSION *self, PyObject *args) { char *errmsg; int rc,want_buf=0; Py_BEGIN_ALLOW_THREADS rc=libssh2_session_last_error(self->session, &errmsg, NULL, want_buf); Py_END_ALLOW_THREADS return Py_BuildValue("(i,s)", rc, errmsg); }
void client_d::connect() { try { if( libssh2_init(0) < 0 ) { MACE_SSH_THROW( "Unable to init libssh2" ); } slog( "resolve %1%:%2%", hostname, port ); std::vector<mace::cmt::asio::tcp::endpoint> eps = mace::cmt::asio::tcp::resolve( hostname, boost::lexical_cast<std::string>(port)); slog( "resolved %1% options", eps.size() ); if( eps.size() == 0 ) { MACE_SSH_THROW( "Hostname '%1%' didn't resolve to any endpoints", %hostname ); } m_sock.reset( new boost::asio::ip::tcp::socket( mace::cmt::asio::default_io_service() ) ); for( uint32_t i = 0; i < eps.size(); ++i ) { try { mace::cmt::asio::tcp::connect( *m_sock, eps[i] ); endpt = eps[i]; break; } catch ( ... ) {} } slog( "Creating session" ); m_session = libssh2_session_init(); *libssh2_session_abstract(m_session) = this; BOOST_ASSERT( m_session ); // use non-blocking calls so that we know when to call wait_on_socket libssh2_session_set_blocking( m_session, 0 ); // perform the session handshake, and keep trying while EAGAIN int ec = libssh2_session_handshake( m_session, m_sock->native() ); while( ec == LIBSSH2_ERROR_EAGAIN ) { wait_on_socket(); ec = libssh2_session_handshake( m_session, m_sock->native() ); } // if there was an error, throw it. if( ec < 0 ) { char* msg; libssh2_session_last_error( m_session, &msg, 0, 0 ); MACE_SSH_THROW( "Handshake error: %1% - %2%", %ec %msg ); }
QString SshConnection::lastSessionError() { QString msg; if (m_session) { char* errorMessage; int length; int code(libssh2_session_last_error(m_session, &errorMessage, &length, 0)); if (!msg.isEmpty()) msg += "\n"; if (false) msg += "libssh2 error code " + QString::number(code) + "\n"; msg += QString(errorMessage) + "\n"; } return msg; }
std::string CLibssh2::get_session_errmsg() const { std::string result; char* errmsg; int errmsg_len = 0; LIBSSH2_SESSION* session = static_cast<LIBSSH2_SESSION*>(_session); (void)libssh2_session_last_error(session, &errmsg, &errmsg_len, 1); if (errmsg != NULL) { result = errmsg; free(errmsg); } return result; }
/* * 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; }
static CURLcode libssh2_error_to_CURLE(struct connectdata *conn) { int errorcode; struct SSHPROTO *scp = conn->data->reqdata.proto.ssh; /* Get the libssh2 error code and string */ errorcode = libssh2_session_last_error(scp->ssh_session, &scp->errorstr, NULL, 0); if (errorcode == LIBSSH2_FX_OK) return CURLE_OK; infof(conn->data, "libssh2 error %d, '%s'\n", errorcode, scp->errorstr); /* TODO: map some of the libssh2 errors to the more appropriate CURLcode error code, and possibly add a few new SSH-related one. We must however not return or even depend on libssh2 errors in the public libcurl API */ return CURLE_SSH; }
int process_d::read_some( char* data, size_t len, int stream_id ) { if( !sshc->my->m_session ) { MACE_SSH_THROW( "Session closed\n" ); } int rc; char* buf = data; size_t buflen = len; do { rc = libssh2_channel_read_ex( chan, stream_id, buf, buflen ); if( rc > 0 ) { buf += rc; buflen -= rc; return buf-data; } else if( rc == 0 ) { if( libssh2_channel_eof( chan ) ) { return -1; // eof } sshc->my->wait_on_socket(); } else { if( rc == LIBSSH2_ERROR_EAGAIN ) { if( 0 < (buf-data) ) { return buf-data; } else { sshc->my->wait_on_socket(); rc = 0; continue; } } else { char* msg; if( !sshc || !sshc->my || !sshc->my->m_session ) { MACE_SSH_THROW( "Session closed" ); } slog( "my: %1%", sshc->my ); rc = libssh2_session_last_error( sshc->my->m_session, &msg, 0, 0 ); MACE_SSH_THROW( "read failed: %1% - %2%", %rc %msg ); return buf-data; } } } while( rc >= 0 && buflen); return buf-data; }
static size_t php_ssh2_channel_stream_read(php_stream *stream, char *buf, size_t count TSRMLS_DC) { php_ssh2_channel_data *abstract = (php_ssh2_channel_data*)stream->abstract; ssize_t readstate; LIBSSH2_SESSION *session; stream->eof = libssh2_channel_eof(abstract->channel); libssh2_channel_set_blocking(abstract->channel, abstract->is_blocking); session = (LIBSSH2_SESSION *)zend_fetch_resource(NULL TSRMLS_CC, abstract->session_rsrc, PHP_SSH2_SESSION_RES_NAME, NULL, 1, le_ssh2_session); #ifdef PHP_SSH2_SESSION_TIMEOUT if (abstract->is_blocking) { libssh2_session_set_timeout(session, abstract->timeout); } #endif readstate = libssh2_channel_read_ex(abstract->channel, abstract->streamid, buf, count); #ifdef PHP_SSH2_SESSION_TIMEOUT if (abstract->is_blocking) { libssh2_session_set_timeout(session, 0); } #endif if (readstate == LIBSSH2_ERROR_EAGAIN) { readstate = 0; } if (readstate < 0) { char *error_msg = NULL; if (libssh2_session_last_error(session, &error_msg, NULL, 0) == readstate) { php_error_docref(NULL TSRMLS_CC, E_WARNING, "Failure '%s' (%ld)", error_msg, readstate); } stream->eof = 1; readstate = 0; } return readstate; }
int ssh_exec_channel_open(void* ssh_session, Boolean async_mode) { SSH_SESSION* p_session; LIBSSH2_CHANNEL* channel; p_session = (SSH_SESSION*)ssh_session; if(!(login_check(p_session))) { debug_log(SSH_TERMINAL_NO_SESSION_ERROR, "ssh_exec_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_exec_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_exec_channel_open : channel open failed."); return SSH_TERMINAL_CHANNEL_OPEN_ERROR; } p_session->session_param->channel = channel; p_session->session_param->channel_type = CHANNEL_TYPE_EXEC; p_session->session_param->async_mode = async_mode; return 0; }
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; }
static LIBSSH2_SESSION* __guac_ssh_create_session(guac_client* client, int* socket_fd) { int retval; int fd; struct addrinfo* addresses; struct addrinfo* current_address; char connected_address[1024]; char connected_port[64]; ssh_guac_client_data* client_data = (ssh_guac_client_data*) client->data; struct addrinfo hints = { .ai_family = AF_UNSPEC, .ai_socktype = SOCK_STREAM, .ai_protocol = IPPROTO_TCP }; /* Get socket */ fd = socket(AF_INET, SOCK_STREAM, 0); /* Get addresses connection */ if ((retval = getaddrinfo(client_data->hostname, client_data->port, &hints, &addresses))) { guac_client_abort(client, GUAC_PROTOCOL_STATUS_SERVER_ERROR, "Error parsing given address or port: %s", gai_strerror(retval)); return NULL; } /* Attempt connection to each address until success */ current_address = addresses; while (current_address != NULL) { int retval; /* Resolve hostname */ if ((retval = getnameinfo(current_address->ai_addr, current_address->ai_addrlen, connected_address, sizeof(connected_address), connected_port, sizeof(connected_port), NI_NUMERICHOST | NI_NUMERICSERV))) guac_client_log_info(client, "Unable to resolve host: %s", gai_strerror(retval)); /* Connect */ if (connect(fd, current_address->ai_addr, current_address->ai_addrlen) == 0) { guac_client_log_info(client, "Successfully connected to " "host %s, port %s", connected_address, connected_port); /* Done if successful connect */ break; } /* Otherwise log information regarding bind failure */ else guac_client_log_info(client, "Unable to connect to " "host %s, port %s: %s", connected_address, connected_port, strerror(errno)); current_address = current_address->ai_next; } /* If unable to connect to anything, fail */ if (current_address == NULL) { guac_client_abort(client, GUAC_PROTOCOL_STATUS_UPSTREAM_ERROR, "Unable to connect to any addresses."); return NULL; } /* Free addrinfo */ freeaddrinfo(addresses); /* Open SSH session */ LIBSSH2_SESSION* session = libssh2_session_init_ex(NULL, NULL, NULL, client); if (session == NULL) { guac_client_abort(client, GUAC_PROTOCOL_STATUS_SERVER_ERROR, "Session allocation failed."); return NULL; } /* Perform handshake */ if (libssh2_session_handshake(session, fd)) { guac_client_abort(client, GUAC_PROTOCOL_STATUS_UPSTREAM_ERROR, "SSH handshake failed."); return NULL; } /* Save file descriptor */ if (socket_fd != NULL) *socket_fd = fd; /* Authenticate with key if available */ if (client_data->key != NULL) { if (!libssh2_userauth_publickey(session, client_data->username, (unsigned char*) client_data->key->public_key, client_data->key->public_key_length, __sign_callback, (void**) client_data->key)) return session; else { char* error_message; libssh2_session_last_error(session, &error_message, NULL, 0); guac_client_abort(client, GUAC_PROTOCOL_STATUS_CLIENT_UNAUTHORIZED, "Public key authentication failed: %s", error_message); return NULL; } } /* Authenticate with password */ if (!libssh2_userauth_password(session, client_data->username, client_data->password)) return session; else { char* error_message; libssh2_session_last_error(session, &error_message, NULL, 0); guac_client_abort(client, GUAC_PROTOCOL_STATUS_CLIENT_UNAUTHORIZED, "Password authentication failed: %s", error_message); return NULL; } }