예제 #1
0
파일: ssh.c 프로젝트: Pating/qemu-colo
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);
}
예제 #2
0
파일: ssh.c 프로젝트: Pating/qemu-colo
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");
}
예제 #3
0
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);
}
예제 #4
0
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;

}
예제 #5
0
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;

}
예제 #6
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;
}
예제 #7
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);
}
예제 #8
0
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;
}
예제 #9
0
파일: ssh.c 프로젝트: Pating/qemu-colo
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;
}
예제 #10
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;
}
예제 #11
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);
            }
        }  
예제 #12
0
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;
}
예제 #13
0
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;
}
예제 #14
0
파일: sftp.c 프로젝트: sdgdsffdsfff/kingso
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;
}
예제 #15
0
파일: attr.c 프로젝트: aliasch/programming
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;
}
예제 #16
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);
}
예제 #17
0
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;

}
예제 #18
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;
}