Hi, sftp_RW_nonblock.c does not handle LIBSSH2_ERROR_EAGAIN, which causes the password authentication to fail. I fixed the example by taking the appropriate code from sftp_nonblock.c. Note that sftp_nonblock.c does not call select() while looping around libssh2_session_handshake(), libssh2_userauth_password(), libssh2_userauth_publickey_fromfile() and libssh2_session_disconnect() -- is that intentionally? (the call of libssh2_userauth_publickey_fromfile() is dead code anyway...)
Kamil
From 19bcd604ed41540950f59944bea1913db39ae646 Mon Sep 17 00:00:00 2001 From: Kamil Dudka <[email protected]> Date: Mon, 24 Oct 2011 16:21:25 +0200 Subject: [PATCH] example/sftp_RW_nonblock: do not ignore LIBSSH2_ERROR_EAGAIN Bug: https://bugzilla.redhat.com/745420 --- example/sftp_RW_nonblock.c | 89 +++++++++++++++++++++++++++++++++++-------- 1 files changed, 72 insertions(+), 17 deletions(-) diff --git a/example/sftp_RW_nonblock.c b/example/sftp_RW_nonblock.c index 8cb241f..babb48a 100644 --- a/example/sftp_RW_nonblock.c +++ b/example/sftp_RW_nonblock.c @@ -43,6 +43,36 @@ example uses to store the downloaded file in */ +static int waitsocket(int socket_fd, LIBSSH2_SESSION *session) +{ + struct timeval timeout; + int rc; + fd_set fd; + fd_set *writefd = NULL; + fd_set *readfd = NULL; + int dir; + + timeout.tv_sec = 10; + timeout.tv_usec = 0; + + FD_ZERO(&fd); + + FD_SET(socket_fd, &fd); + + /* now make sure we wait in the correct direction */ + dir = libssh2_session_block_directions(session); + + if(dir & LIBSSH2_SESSION_BLOCK_INBOUND) + readfd = &fd; + + if(dir & LIBSSH2_SESSION_BLOCK_OUTBOUND) + writefd = &fd; + + rc = select(socket_fd + 1, readfd, writefd, NULL, &timeout); + + return rc; +} + int main(int argc, char *argv[]) { int sock, i, auth_pw = 1; @@ -138,36 +168,61 @@ int main(int argc, char *argv[]) if (auth_pw) { /* We could authenticate via password */ - if (libssh2_userauth_password(session, username, 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 */ - if (libssh2_userauth_publickey_fromfile(session, username, - "/home/username/.ssh/id_rsa.pub", - "/home/username/.ssh/id_rsa", - password)) { + 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; } } - sftp_session = libssh2_sftp_init(session); + do { + sftp_session = libssh2_sftp_init(session); - if (!sftp_session) { - fprintf(stderr, "Unable to init SFTP session\n"); - goto shutdown; - } + 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); /* Request a file via SFTP */ - sftp_handle = - libssh2_sftp_open(sftp_session, sftppath, LIBSSH2_FXF_READ, 0); + 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); - if (!sftp_handle) { - fprintf(stderr, "Unable to open file with SFTP\n"); - goto shutdown; - } fprintf(stderr, "libssh2_sftp_open() is done, now receive data!\n"); do { do { -- 1.7.1
_______________________________________________ libssh2-devel http://cool.haxx.se/cgi-bin/mailman/listinfo/libssh2-devel
