Ejemplo n.º 1
0
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");
}
Ejemplo n.º 2
0
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();
}
Ejemplo n.º 3
0
void FSSftp::CheckSFTPEagain()
{
	int e = libssh2_session_last_errno( sshSession );

	if ( e == LIBSSH2_ERROR_EAGAIN ) { return; }

	throw TransSftpError( e, sftpSession );
}
Ejemplo n.º 4
0
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;
}
Ejemplo n.º 5
0
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;
}
Ejemplo n.º 6
0
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;
}
Ejemplo n.º 7
0
Archivo: dir.c Proyecto: CTU-OSP/mc
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;
}
Ejemplo n.º 8
0
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;
}
Ejemplo n.º 9
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;
}
Ejemplo n.º 10
0
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;
}
Ejemplo n.º 11
0
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;
}
Ejemplo n.º 12
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;
    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;
}
Ejemplo n.º 13
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;
}
Ejemplo n.º 14
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 = 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;
}
Ejemplo n.º 15
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);
            }
        }  
Ejemplo n.º 16
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";
    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;
}
Ejemplo n.º 17
0
Archivo: file.c Proyecto: LubkaB/mc
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;
}
Ejemplo n.º 18
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";
    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;
}
Ejemplo n.º 19
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;
}
Ejemplo n.º 20
0
/* {{{ 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;
}
Ejemplo n.º 21
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 *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;
}
Ejemplo n.º 22
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;
}
Ejemplo n.º 23
0
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);*/
            }
        }
Ejemplo n.º 24
0
void FSSftp::CheckSessionEagain()
{
	int e = libssh2_session_last_errno( this->sshSession );

	if ( e != LIBSSH2_ERROR_EAGAIN ) { throw int( e - 1000 ); }
}
Ejemplo n.º 25
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;
    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;
}
Ejemplo n.º 26
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;
}
Ejemplo n.º 27
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;
	}

}
Ejemplo n.º 28
0
int CLibssh2::get_session_errcode() const
{
    LIBSSH2_SESSION* session = static_cast<LIBSSH2_SESSION*>(_session);
    return libssh2_session_last_errno(session);
}
Ejemplo n.º 29
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;
    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;
}
Ejemplo n.º 30
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;
}