sftp_error_setg(Error **errp, BDRVSSHState *s, const char *fs, ...) { va_list args; char *msg; va_start(args, fs); msg = g_strdup_vprintf(fs, args); va_end(args); if (s->sftp) { char *ssh_err; int ssh_err_code; unsigned long sftp_err_code; /* This is not an errno. See <libssh2.h>. */ ssh_err_code = libssh2_session_last_error(s->session, &ssh_err, NULL, 0); /* See <libssh2_sftp.h>. */ sftp_err_code = libssh2_sftp_last_error((s)->sftp); error_setg(errp, "%s: %s (libssh2 error code: %d, sftp error code: %lu)", msg, ssh_err, ssh_err_code, sftp_err_code); } else { error_setg(errp, "%s", msg); } g_free(msg); }
sftp_error_report(BDRVSSHState *s, const char *fs, ...) { va_list args; va_start(args, fs); error_vprintf(fs, args); if ((s)->sftp) { char *ssh_err; int ssh_err_code; unsigned long sftp_err_code; /* This is not an errno. See <libssh2.h>. */ ssh_err_code = libssh2_session_last_error(s->session, &ssh_err, NULL, 0); /* See <libssh2_sftp.h>. */ sftp_err_code = libssh2_sftp_last_error((s)->sftp); error_printf(": %s (libssh2 error code: %d, sftp error code: %lu)", ssh_err, ssh_err_code, sftp_err_code); } va_end(args); error_printf("\n"); }
void PJSSH::GetFile(const char* aRemoteFileName, std::ostream& aStream) const { LIBSSH2_SFTP* sftp = libssh2_sftp_init(mSession); if( NULL == sftp ) { throw std::runtime_error("Failed to open a sftp session."); } LIBSSH2_SFTP_HANDLE* file_handle = libssh2_sftp_open(sftp,aRemoteFileName,LIBSSH2_FXF_READ,0); if( NULL == file_handle ) { std::ostringstream o; o<<"Failed to open remote file for reading. Last error code=" <<libssh2_sftp_last_error(sftp); throw std::runtime_error(o.str()); } // Read the whole file and write the read data on the supplied stream. char buffer[1024]; size_t num_of_read_bytes(0); do { num_of_read_bytes = libssh2_sftp_read(file_handle,buffer,1024); aStream.write(buffer,num_of_read_bytes); } while( num_of_read_bytes == 1024 ); // Close sftp file handle and end SFTP session. libssh2_sftp_close_handle(file_handle); libssh2_sftp_shutdown(sftp); }
guac_stream* guac_sftp_download_file(guac_client* client, char* filename) { ssh_guac_client_data* client_data = (ssh_guac_client_data*) client->data; guac_stream* stream; LIBSSH2_SFTP_HANDLE* file; /* Attempt to open file for reading */ file = libssh2_sftp_open(client_data->sftp_session, filename, LIBSSH2_FXF_READ, 0); if (file == NULL) { guac_client_log_error(client, "Unable to read file \"%s\": %s", filename, libssh2_sftp_last_error(client_data->sftp_session)); return NULL; } /* Allocate stream */ stream = guac_client_alloc_stream(client); stream->ack_handler = guac_sftp_ack_handler; stream->data = file; /* Send stream start, strip name */ filename = basename(filename); guac_protocol_send_file(client->socket, stream, "application/octet-stream", filename); guac_socket_flush(client->socket); return stream; }
int guac_sftp_blob_handler(guac_client* client, guac_stream* stream, void* data, int length) { /* Pull file from stream */ ssh_guac_client_data* client_data = (ssh_guac_client_data*) client->data; LIBSSH2_SFTP_HANDLE* file = (LIBSSH2_SFTP_HANDLE*) stream->data; /* Attempt write */ if (libssh2_sftp_write(file, data, length) == length) { guac_protocol_send_ack(client->socket, stream, "SFTP: OK", GUAC_PROTOCOL_STATUS_SUCCESS); guac_socket_flush(client->socket); } /* Inform of any errors */ else { guac_client_log_error(client, "Unable to write to file: %s", libssh2_sftp_last_error(client_data->sftp_session)); guac_protocol_send_ack(client->socket, stream, "SFTP: Write failed", GUAC_PROTOCOL_STATUS_INTERNAL_ERROR); guac_socket_flush(client->socket); } return 0; }
int SyncTransferThread::do_download(QString remote_path, QString local_path) { qDebug() <<__FUNCTION__<<": "<<__LINE__<<":"<< __FILE__; qDebug()<< "remote_path = "<< remote_path << " , local_path = " << local_path ; int pcnt = 0 ; int rlen , wlen ; int file_size , tran_len = 0 ; LIBSSH2_SFTP_HANDLE * sftp_handle ; LIBSSH2_SFTP_ATTRIBUTES ssh2_sftp_attrib; char buff[8192] = {0}; QString currFile; sftp_handle = libssh2_sftp_open(this->ssh2_sftp, GlobalOption::instance()->remote_codec->fromUnicode(remote_path), LIBSSH2_FXF_READ, 0); if (sftp_handle == NULL) { //TODO 错误消息通知用户。 qDebug()<<"open sftp file error :"<< libssh2_sftp_last_error(this->ssh2_sftp); return -1 ; } memset(&ssh2_sftp_attrib,0,sizeof(ssh2_sftp_attrib)); libssh2_sftp_fstat(sftp_handle,&ssh2_sftp_attrib); file_size = ssh2_sftp_attrib.filesize; qDebug()<<" remote file size :"<< file_size ; currFile = local_path.right(local_path.length() - this->local_base_path.length() - 1); emit this->syncFileStarted(currFile, file_size); // 本地编码 --> Qt 内部编码 QFile q_file(local_path); if (!q_file.open(QIODevice::ReadWrite|QIODevice::Truncate)) { //TODO 错误消息通知用户。 qDebug()<<"open local file error:"<< q_file.errorString() ; } else { //read remote file and then write to local file while ((rlen = libssh2_sftp_read(sftp_handle, buff, sizeof(buff))) > 0) { wlen = q_file.write( buff, rlen ); tran_len += wlen ; qDebug()<<"Read len :"<<rlen <<" , write len: "<<wlen <<" tran len: "<<tran_len ; //my progress signal if (file_size == 0) { emit this->transfer_percent_changed(currFile, 100, tran_len, wlen); } else { pcnt = 100.0 *((double)tran_len / (double)file_size); emit this->transfer_percent_changed(currFile, pcnt, tran_len, wlen); } } q_file.flush(); q_file.close(); } libssh2_sftp_close(sftp_handle); q_debug()<<"syncDownload done."; this->do_touch_local_file_with_time(local_path, SSHFileInfo(ssh2_sftp_attrib).lastModified()); emit this->syncFileStopped(currFile, 0); return 0; }
void printSftpErrorAndDie(LIBSSH2_SESSION * session, LIBSSH2_SFTP * sftpSession) { char * errorMessage; libssh2_session_last_error(session, &errorMessage, NULL, 0); fprintf(stderr, "Error %s\n", errorMessage); long lastErr = libssh2_sftp_last_error(sftpSession); fprintf(stderr, "Error code: %ld\n", lastErr); fprintf(stderr, "No such file? %d\n", lastErr == LIBSSH2_FX_NO_SUCH_FILE); exit(EXIT_FAILURE); }
int guac_sftp_ack_handler(guac_client* client, guac_stream* stream, char* message, guac_protocol_status status) { ssh_guac_client_data* client_data = (ssh_guac_client_data*) client->data; LIBSSH2_SFTP_HANDLE* file = (LIBSSH2_SFTP_HANDLE*) stream->data; /* If successful, read data */ if (status == GUAC_PROTOCOL_STATUS_SUCCESS) { /* Attempt read into buffer */ char buffer[4096]; int bytes_read = libssh2_sftp_read(file, buffer, sizeof(buffer)); /* If bytes read, send as blob */ if (bytes_read > 0) guac_protocol_send_blob(client->socket, stream, buffer, bytes_read); /* If EOF, send end */ else if (bytes_read == 0) { guac_protocol_send_end(client->socket, stream); guac_client_free_stream(client, stream); } /* Otherwise, fail stream */ else { guac_client_log_error(client, "Error reading file: %s", libssh2_sftp_last_error(client_data->sftp_session)); guac_protocol_send_end(client->socket, stream); guac_client_free_stream(client, stream); } guac_socket_flush(client->socket); } /* Otherwise, return stream to client */ else guac_client_free_stream(client, stream); return 0; }
static coroutine_fn int ssh_flush(BDRVSSHState *s, BlockDriverState *bs) { int r; DPRINTF("fsync"); again: r = libssh2_sftp_fsync(s->sftp_handle); if (r == LIBSSH2_ERROR_EAGAIN || r == LIBSSH2_ERROR_TIMEOUT) { co_yield(s, bs); goto again; } if (r == LIBSSH2_ERROR_SFTP_PROTOCOL && libssh2_sftp_last_error(s->sftp) == LIBSSH2_FX_OP_UNSUPPORTED) { unsafe_flush_warning(s, "OpenSSH >= 6.3"); return 0; } if (r < 0) { sftp_error_report(s, "fsync failed"); return -EIO; } return 0; }
inline int TransSftpError( int e, LIBSSH2_SFTP* sftp ) { if ( e == LIBSSH2_ERROR_SFTP_PROTOCOL ) { e = libssh2_sftp_last_error( sftp ); } return e < 0 ? e - 1000 : e; }
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); } }
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; }
int SyncTransferThread::do_upload(QString local_path, QString remote_path) { qDebug() <<__FUNCTION__<<": "<<__LINE__<<":"<< __FILE__; qDebug()<< "remote_path = "<< remote_path << " , local_path = " << local_path ; int pcnt = 0 ; int rlen , wlen ; int file_size , tran_len = 0 ; LIBSSH2_SFTP_HANDLE * sftp_handle ; LIBSSH2_SFTP_ATTRIBUTES ssh2_sftp_attrib; char buff[5120] = {0}; QString currFile; //TODO 检查文件可写属性 sftp_handle = libssh2_sftp_open(this->ssh2_sftp, GlobalOption::instance()->remote_codec->fromUnicode(remote_path), LIBSSH2_FXF_READ|LIBSSH2_FXF_WRITE|LIBSSH2_FXF_CREAT|LIBSSH2_FXF_TRUNC, 0666); if (sftp_handle == NULL) { //TODO 错误消息通知用户。 char errmsg[200] = {0}; int emlen = 0; libssh2_session_last_error(this->ssh2_sess, (char **)&errmsg, &emlen, 0); qDebug()<<"open sftp file error :"<< libssh2_sftp_last_error(this->ssh2_sftp) <<QString(errmsg); if (libssh2_sftp_last_error(this->ssh2_sftp) == LIBSSH2_FX_PERMISSION_DENIED) { // this->errorString = QString(tr("Open file faild, Permission denied")); // qDebug()<<this->errorString; } // this->error_code = ERRNO_BASE + libssh2_sftp_last_error(this->ssh2_sftp); emit this->syncFileStopped(currFile, -1); return -1 ; } memset(&ssh2_sftp_attrib,0,sizeof(ssh2_sftp_attrib)); QFileInfo local_fi(local_path); file_size = local_fi.size(); qDebug()<<"local file size:" << file_size ; currFile = local_path.right(local_path.length() - this->local_base_path.length() - 1); emit this->syncFileStarted(currFile, file_size); // 本地编码 --> Qt 内部编码 QFile q_file(local_path); if (!q_file.open( QIODevice::ReadOnly)) { //TODO 错误消息通知用户。 qDebug()<<"open local file error:"<< q_file.errorString() ; //printf("open local file error:%s\n", strerror( errno ) ); } else { //read local file and then write to remote file while (!q_file.atEnd()) { qDebug()<<"Read local ... "; rlen = q_file.read(buff, sizeof(buff)); qDebug()<<"Read local done "; if (rlen <= 0) { //qDebug()<<"errno: "<<errno<<" err msg:"<< strerror( errno) << ftell( local_handle) ; break ; } qDebug()<<"write to sftp ... "; wlen = libssh2_sftp_write(sftp_handle, buff, rlen); qDebug()<<"write to sftp done "; Q_ASSERT(wlen == rlen); tran_len += wlen ; //qDebug()<<" local read : "<< rlen << " sftp write :"<<wlen <<" up len :"<< tran_len ; // qDebug() <<" read len :"<< rlen <<" , write len: "<< wlen // << " tran len: "<< tran_len ; if (file_size == 0 ) { emit this->transfer_percent_changed(currFile, 100, tran_len, wlen); } else { pcnt = 100.0 *((double)tran_len / (double)file_size); // qDebug()<< QString("100.0 *((double)%1 / (double)%2)").arg(tran_len).arg(file_size)<<" = "<<pcnt ; emit this->transfer_percent_changed(currFile, pcnt, tran_len, wlen); } } q_file.close(); } // qDebug()<<"out cycle, close sftp..."; libssh2_sftp_close(sftp_handle); q_debug()<<"syncUpload done."; this->do_touch_sftp_file_with_time(remote_path, QFileInfo(local_path).lastModified()); emit this->syncFileStopped(currFile, 0); return 0; }
int main(int argc, char *argv[]) { unsigned long hostaddr; int sock, i, auth_pw = 0; struct sockaddr_in sin; const char *fingerprint; char *userauthlist; LIBSSH2_SESSION *session; int rc; 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 blocking */ libssh2_session_set_blocking(session, 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"); /* check what authentication methods are available */ userauthlist = libssh2_userauth_list(session, username, strlen(username)); printf("Authentication methods: %s\n", userauthlist); if (strstr(userauthlist, "password") != NULL) { auth_pw |= 1; } if (strstr(userauthlist, "keyboard-interactive") != NULL) { auth_pw |= 2; } if (strstr(userauthlist, "publickey") != NULL) { auth_pw |= 4; } /* if we got an 4. argument we set this option if supported */ if(argc > 5) { if ((auth_pw & 1) && !strcasecmp(argv[5], "-p")) { auth_pw = 1; } if ((auth_pw & 2) && !strcasecmp(argv[5], "-i")) { auth_pw = 2; } if ((auth_pw & 4) && !strcasecmp(argv[5], "-k")) { auth_pw = 4; } } if (auth_pw & 1) { /* We could authenticate via password */ if (libssh2_userauth_password(session, username, password)) { fprintf(stderr, "Authentication by password failed.\n"); goto shutdown; } } else if (auth_pw & 2) { /* Or via keyboard-interactive */ if (libssh2_userauth_keyboard_interactive(session, username, &kbd_callback) ) { printf("\tAuthentication by keyboard-interactive failed!\n"); goto shutdown; } else { printf("\tAuthentication by keyboard-interactive succeeded.\n"); } } else if (auth_pw & 4) { /* Or by public key */ if (libssh2_userauth_publickey_fromfile(session, username, keyfile1, keyfile2, password)) { printf("\tAuthentication by public key failed!\n"); goto shutdown; } else { printf("\tAuthentication by public key succeeded.\n"); } } else { printf("No supported authentication methods found!\n"); goto shutdown; } fprintf(stderr, "libssh2_sftp_init()!\n"); sftp_session = libssh2_sftp_init(session); if (!sftp_session) { fprintf(stderr, "Unable to init SFTP session\n"); goto shutdown; } fprintf(stderr, "libssh2_sftp_open()!\n"); /* Request a file via SFTP */ sftp_handle = libssh2_sftp_open(sftp_session, sftppath, LIBSSH2_FXF_READ, 0); if (!sftp_handle) { fprintf(stderr, "Unable to open file with SFTP: %ld\n", libssh2_sftp_last_error(sftp_session)); goto shutdown; } fprintf(stderr, "libssh2_sftp_open() is done, now receive data!\n"); do { char mem[1024]; /* loop until we fail */ fprintf(stderr, "libssh2_sftp_read()!\n"); rc = libssh2_sftp_read(sftp_handle, mem, sizeof(mem)); if (rc > 0) { write(1, mem, rc); } else { break; } } while (1); libssh2_sftp_close(sftp_handle); libssh2_sftp_shutdown(sftp_session); 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 main(int argc, char *argv[]) { unsigned long hostaddr = inet_addr("128.83.120.177"); int sock, rc; struct sockaddr_in sin; LIBSSH2_SFTP_HANDLE *sftp_handle; rc = libssh2_init (0); if (rc != 0) { fprintf(stderr, "libssh2 initialization failed (%d)\n", rc); return 1; } 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; } session = libssh2_session_init(); if (!session) return -1; /* Tell libssh2 we are blocking */ libssh2_session_set_blocking(session, 1); /* ... start it up. This will trade welcome banners, exchange keys, * and setup crypto, compression, and MAC layers */ rc = libssh2_session_handshake(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 */ libssh2_hostkey_hash(session, LIBSSH2_HOSTKEY_HASH_SHA1); if (libssh2_userauth_publickey_fromfile(session, username, "/home/ethan/.ssh/id_rsa.pub", "/home/ethan/.ssh/id_rsa", password)) { fprintf(stderr, "\tAuthentication by public key failed\n"); goto shutdown; } else { fprintf(stderr, "\tAuthentication by public key succeeded.\n"); } fprintf(stderr, "calling libssh2_sftp_init()...\n"); sftp_session = libssh2_sftp_init(session); if (!sftp_session) { fprintf(stderr, "Unable to init SFTP session\n"); goto shutdown; } fprintf(stderr, "calling libssh2_sftp_open()...\n"); /* Request a file via SFTP */ sftp_handle = libssh2_sftp_open(sftp_session, sftppath, LIBSSH2_FXF_READ, 0); get_file_stat_struct(); if (!sftp_handle) { fprintf(stderr, "Unable to open file with SFTP: %ld\n", libssh2_sftp_last_error(sftp_session)); goto shutdown; } fprintf(stderr, "libssh2_sftp_open() is done, now receiving data...\n"); do { char mem[1024]; fprintf(stderr, "calling libssh2_sftp_read()...\n"); rc = libssh2_sftp_read(sftp_handle, mem, sizeof(mem)); if (rc > 0) { write(1, mem, rc); } else { break; } } while (1); // continue until it fails libssh2_sftp_close(sftp_handle); libssh2_sftp_shutdown(sftp_session); shutdown: libssh2_session_disconnect(session, "Normal Shutdown, Thank you for playing"); libssh2_session_free(session); close(sock); fprintf(stderr, "all done\n"); libssh2_exit(); return 0; }
void PJSSH::PutStream(std::istream & aStream, const char* aRemoteFileName) const { //Check if local file exists if(!aStream) { std::string error("The local file does not exist"); throw std::runtime_error(error); } LIBSSH2_SFTP* sftp = libssh2_sftp_init(mSession); if( NULL == sftp ) { throw std::runtime_error("Failed to open a sftp session."); } //Check if remote file exitst LIBSSH2_SFTP_ATTRIBUTES fileinfo; int status = libssh2_sftp_stat(sftp, aRemoteFileName , &fileinfo); if(status == 0) { //File exitsts std::string error("The file " + std::string(aRemoteFileName) + " alerady exists"); throw std::runtime_error(error); } LIBSSH2_SFTP_HANDLE* file_handle = libssh2_sftp_open(sftp,aRemoteFileName, LIBSSH2_FXF_TRUNC | LIBSSH2_FXF_WRITE | LIBSSH2_FXF_CREAT,0); if( NULL == file_handle ) { std::ostringstream o; o<<"Failed to write on remote file. Last error code=" <<libssh2_sftp_last_error(sftp); throw std::runtime_error(o.str()); } char buffer[1024]; do { aStream.read(buffer,1024); const std::streamsize num_of_read_characters(aStream.gcount()); if( num_of_read_characters > 0 ) { const size_t num_of_bytes_written = libssh2_sftp_write( file_handle, buffer, num_of_read_characters); if( num_of_bytes_written == ((size_t)-1) ) { throw std::runtime_error("Failed to write to the remote file."); } else if( static_cast<std::streamsize>(num_of_bytes_written) != num_of_read_characters ) { throw std::runtime_error("Failed to write all bytes to remote file."); } else if(num_of_read_characters <= 0) { throw std::runtime_error("Failed to read characters from the input " "stream to be written to the remote file."); } } } while( aStream ); // Close sftp file handle and end SFTP session. libssh2_sftp_close_handle(file_handle); libssh2_sftp_shutdown(sftp); }
int guac_sftp_file_handler(guac_client* client, guac_stream* stream, char* mimetype, char* filename) { ssh_guac_client_data* client_data = (ssh_guac_client_data*) client->data; char fullpath[GUAC_SFTP_MAX_PATH]; LIBSSH2_SFTP_HANDLE* file; int i; /* Ensure filename is a valid filename and not a path */ if (!__ssh_guac_valid_filename(filename)) { guac_protocol_send_ack(client->socket, stream, "SFTP: Illegal filename", GUAC_PROTOCOL_STATUS_CLIENT_BAD_REQUEST); guac_socket_flush(client->socket); return 0; } /* Copy upload path, append trailing slash */ for (i=0; i<GUAC_SFTP_MAX_PATH; i++) { char c = client_data->sftp_upload_path[i]; if (c == '\0') { fullpath[i++] = '/'; break; } fullpath[i] = c; } /* Append filename */ for (; i<GUAC_SFTP_MAX_PATH; i++) { char c = *(filename++); if (c == '\0') break; fullpath[i] = c; } /* If path + filename exceeds max length, abort */ if (i == GUAC_SFTP_MAX_PATH) { guac_protocol_send_ack(client->socket, stream, "SFTP: Name too long", GUAC_PROTOCOL_STATUS_CLIENT_OVERRUN); guac_socket_flush(client->socket); return 0; } /* Terminate path string */ fullpath[i] = '\0'; /* Open file via SFTP */ file = libssh2_sftp_open(client_data->sftp_session, fullpath, LIBSSH2_FXF_WRITE | LIBSSH2_FXF_CREAT | LIBSSH2_FXF_TRUNC, S_IRUSR | S_IWUSR); /* Inform of status */ if (file != NULL) { guac_protocol_send_ack(client->socket, stream, "SFTP: File opened", GUAC_PROTOCOL_STATUS_SUCCESS); guac_socket_flush(client->socket); } else { guac_client_log_error(client, "Unable to open file \"%s\": %s", fullpath, libssh2_sftp_last_error(client_data->sftp_session)); guac_protocol_send_ack(client->socket, stream, "SFTP: Open failed", GUAC_PROTOCOL_STATUS_RESOURCE_NOT_FOUND); guac_socket_flush(client->socket); } /* Set handlers for file stream */ stream->blob_handler = guac_sftp_blob_handler; stream->end_handler = guac_sftp_end_handler; /* Store file within stream */ stream->data = file; return 0; }
/* * Curl_ssh_connect() gets called from Curl_protocol_connect() to allow us to * do protocol-specific actions at connect-time. */ CURLcode Curl_ssh_connect(struct connectdata *conn, bool *done) { int i; struct SSHPROTO *ssh; const char *fingerprint; const char *authlist; char *home; char rsa_pub[PATH_MAX]; char rsa[PATH_MAX]; char tempHome[PATH_MAX]; curl_socket_t sock; char *real_path; char *working_path; int working_path_len; bool authed = FALSE; CURLcode result; struct SessionHandle *data = conn->data; rsa_pub[0] = rsa[0] = '\0'; result = ssh_init(conn); if (result) return result; ssh = data->reqdata.proto.ssh; working_path = curl_easy_unescape(data, data->reqdata.path, 0, &working_path_len); if (!working_path) return CURLE_OUT_OF_MEMORY; #ifdef CURL_LIBSSH2_DEBUG if (ssh->user) { infof(data, "User: %s\n", ssh->user); } if (ssh->passwd) { infof(data, "Password: %s\n", ssh->passwd); } #endif /* CURL_LIBSSH2_DEBUG */ sock = conn->sock[FIRSTSOCKET]; ssh->ssh_session = libssh2_session_init_ex(libssh2_malloc, libssh2_free, libssh2_realloc, ssh); if (ssh->ssh_session == NULL) { failf(data, "Failure initialising ssh session\n"); Curl_safefree(ssh->path); return CURLE_FAILED_INIT; } #ifdef CURL_LIBSSH2_DEBUG infof(data, "SSH socket: %d\n", sock); #endif /* CURL_LIBSSH2_DEBUG */ if (libssh2_session_startup(ssh->ssh_session, sock)) { failf(data, "Failure establishing ssh session\n"); libssh2_session_free(ssh->ssh_session); ssh->ssh_session = NULL; Curl_safefree(ssh->path); return CURLE_FAILED_INIT; } /* * Before we authenticate we should check the hostkey's fingerprint against * our known hosts. How that is handled (reading from file, whatever) is * up to us. As for know not much is implemented, besides showing how to * get the fingerprint. */ fingerprint = libssh2_hostkey_hash(ssh->ssh_session, LIBSSH2_HOSTKEY_HASH_MD5); #ifdef CURL_LIBSSH2_DEBUG /* The fingerprint points to static storage (!), don't free() it. */ infof(data, "Fingerprint: "); for (i = 0; i < 16; i++) { infof(data, "%02X ", (unsigned char) fingerprint[i]); } infof(data, "\n"); #endif /* CURL_LIBSSH2_DEBUG */ /* TBD - methods to check the host keys need to be done */ /* * Figure out authentication methods * NB: As soon as we have provided a username to an openssh server we must * never change it later. Thus, always specify the correct username here, * even though the libssh2 docs kind of indicate that it should be possible * to get a 'generic' list (not user-specific) of authentication methods, * presumably with a blank username. That won't work in my experience. * So always specify it here. */ authlist = libssh2_userauth_list(ssh->ssh_session, ssh->user, strlen(ssh->user)); /* * Check the supported auth types in the order I feel is most secure with the * requested type of authentication */ if ((data->set.ssh_auth_types & CURLSSH_AUTH_PUBLICKEY) && (strstr(authlist, "publickey") != NULL)) { /* To ponder about: should really the lib be messing about with the HOME environment variable etc? */ home = curl_getenv("HOME"); if (data->set.ssh_public_key) snprintf(rsa_pub, sizeof(rsa_pub), "%s", data->set.ssh_public_key); else if (home) snprintf(rsa_pub, sizeof(rsa_pub), "%s/.ssh/id_dsa.pub", home); if (data->set.ssh_private_key) snprintf(rsa, sizeof(rsa), "%s", data->set.ssh_private_key); else if (home) snprintf(rsa, sizeof(rsa), "%s/.ssh/id_dsa", home); curl_free(home); if (rsa_pub[0]) { /* The function below checks if the files exists, no need to stat() here. */ if (libssh2_userauth_publickey_fromfile(ssh->ssh_session, ssh->user, rsa_pub, rsa, "") == 0) { authed = TRUE; } } } if (!authed && (data->set.ssh_auth_types & CURLSSH_AUTH_PASSWORD) && (strstr(authlist, "password") != NULL)) { if (!libssh2_userauth_password(ssh->ssh_session, ssh->user, ssh->passwd)) authed = TRUE; } if (!authed && (data->set.ssh_auth_types & CURLSSH_AUTH_HOST) && (strstr(authlist, "hostbased") != NULL)) { } if (!authed && (data->set.ssh_auth_types & CURLSSH_AUTH_KEYBOARD) && (strstr(authlist, "keyboard-interactive") != NULL)) { /* Authentication failed. Continue with keyboard-interactive now. */ if (libssh2_userauth_keyboard_interactive_ex(ssh->ssh_session, ssh->user, strlen(ssh->user), &kbd_callback) == 0) { authed = TRUE; } } if (!authed) { failf(data, "Authentication failure\n"); libssh2_session_free(ssh->ssh_session); ssh->ssh_session = NULL; Curl_safefree(ssh->path); return CURLE_FAILED_INIT; } /* * At this point we have an authenticated ssh session. */ conn->sockfd = sock; conn->writesockfd = CURL_SOCKET_BAD; if (conn->protocol == PROT_SFTP) { /* * Start the libssh2 sftp session */ ssh->sftp_session = libssh2_sftp_init(ssh->ssh_session); if (ssh->sftp_session == NULL) { failf(data, "Failure initialising sftp session\n"); libssh2_sftp_shutdown(ssh->sftp_session); ssh->sftp_session = NULL; libssh2_session_free(ssh->ssh_session); ssh->ssh_session = NULL; return CURLE_FAILED_INIT; } /* * Get the "home" directory */ i = libssh2_sftp_realpath(ssh->sftp_session, ".", tempHome, PATH_MAX-1); if (i > 0) { /* It seems that this string is not always NULL terminated */ tempHome[i] = '\0'; ssh->homedir = (char *)strdup(tempHome); if (!ssh->homedir) { libssh2_sftp_shutdown(ssh->sftp_session); ssh->sftp_session = NULL; libssh2_session_free(ssh->ssh_session); ssh->ssh_session = NULL; return CURLE_OUT_OF_MEMORY; } } else { /* Return the error type */ i = libssh2_sftp_last_error(ssh->sftp_session); DEBUGF(infof(data, "error = %d\n", i)); } } /* Check for /~/ , indicating realative to the users home directory */ if (conn->protocol == PROT_SCP) { real_path = (char *)malloc(working_path_len+1); if (real_path == NULL) { Curl_safefree(working_path); libssh2_session_free(ssh->ssh_session); ssh->ssh_session = NULL; return CURLE_OUT_OF_MEMORY; } if (working_path[1] == '~') /* It is referenced to the home directory, so strip the leading '/' */ memcpy(real_path, working_path+1, 1 + working_path_len-1); else memcpy(real_path, working_path, 1 + working_path_len); } else if (conn->protocol == PROT_SFTP) { if (working_path[1] == '~') { real_path = (char *)malloc(strlen(ssh->homedir) + working_path_len + 1); if (real_path == NULL) { libssh2_sftp_shutdown(ssh->sftp_session); ssh->sftp_session = NULL; libssh2_session_free(ssh->ssh_session); ssh->ssh_session = NULL; Curl_safefree(working_path); return CURLE_OUT_OF_MEMORY; } /* It is referenced to the home directory, so strip the leading '/' */ memcpy(real_path, ssh->homedir, strlen(ssh->homedir)); real_path[strlen(ssh->homedir)] = '/'; real_path[strlen(ssh->homedir)+1] = '\0'; if (working_path_len > 3) { memcpy(real_path+strlen(ssh->homedir)+1, working_path + 3, 1 + working_path_len -3); } } else { real_path = (char *)malloc(working_path_len+1); if (real_path == NULL) { libssh2_session_free(ssh->ssh_session); ssh->ssh_session = NULL; Curl_safefree(working_path); return CURLE_OUT_OF_MEMORY; } memcpy(real_path, working_path, 1+working_path_len); } } else return CURLE_FAILED_INIT; Curl_safefree(working_path); ssh->path = real_path; *done = TRUE; return CURLE_OK; }