Daiki Ueno <[email protected]> writes: > The attached is the initial implementation.
Sorry, there was a bug in the sample code. Please apply the attached patch 0004 after the previous patch set being applied. A couple of additional notes: - The connection to ssh-agent can be set non-blocking. The attached 0005-0007 are the patch set to finish the code. - As you know, there is libssh2_publickey.h which provides a data type for public keys. The ssh-agent code uses a different, minimal data type for public keys (struct libssh2_agent_publickey in libssh2.h). What do you think about using libssh2_publickey.h instead? I'm not sure if the API is still maintained. Regards, -- Daiki Ueno
>From ab03a90272f6b9ab364d31ffb12ddddcc84fc387 Mon Sep 17 00:00:00 2001 From: Daiki Ueno <[email protected]> Date: Thu, 17 Dec 2009 00:11:40 +0900 Subject: [PATCH 4/7] Fix the bug traversing identities. --- example/simple/ssh2_agent.c | 1 + 1 files changed, 1 insertions(+), 0 deletions(-) diff --git a/example/simple/ssh2_agent.c b/example/simple/ssh2_agent.c index 44335ba..b6657ed 100644 --- a/example/simple/ssh2_agent.c +++ b/example/simple/ssh2_agent.c @@ -131,6 +131,7 @@ int main(int argc, char *argv[]) username, identity->comment); break; } + prev_identity = identity; } if (rc) { fprintf(stderr, "Couldn't continue authentication\n"); -- 1.6.5.4
>From 51fe8b4bd6a3d064ec1dab32c351af11b016909e Mon Sep 17 00:00:00 2001 From: Daiki Ueno <[email protected]> Date: Thu, 17 Dec 2009 00:13:26 +0900 Subject: [PATCH 5/7] Rename session_nonblock() to _libssh2_socket_nonblock(). --- src/libssh2_priv.h | 2 ++ src/session.c | 16 ++++++++-------- 2 files changed, 10 insertions(+), 8 deletions(-) diff --git a/src/libssh2_priv.h b/src/libssh2_priv.h index 1ba9354..dc150e2 100644 --- a/src/libssh2_priv.h +++ b/src/libssh2_priv.h @@ -1143,6 +1143,8 @@ ssize_t _libssh2_send(libssh2_socket_t socket, const void *buffer, size_t length int _libssh2_wait_socket(LIBSSH2_SESSION *session); +int _libssh2_socket_nonblock(libssh2_socket_t sockfd, int nonblock); + /* These started out as private return codes for the transport layer, but was converted to using the library-wide return codes to easy propagation of the diff --git a/src/session.c b/src/session.c index 28885c5..253900b 100644 --- a/src/session.c +++ b/src/session.c @@ -254,13 +254,13 @@ banner_send(LIBSSH2_SESSION * session) } /* - * session_nonblock() sets the given socket to either blocking or - * non-blocking mode based on the 'nonblock' boolean argument. This function - * is copied from the libcurl sources with permission. + * _libssh2_socket_nonblock() sets the given socket to either blocking + * or non-blocking mode based on the 'nonblock' boolean argument. This + * function is copied from the libcurl sources with permission. */ -static int -session_nonblock(libssh2_socket_t sockfd, /* operate on this */ - int nonblock /* TRUE or FALSE */ ) +int +_libssh2_socket_nonblock(libssh2_socket_t sockfd, /* operate on this */ + int nonblock /* TRUE or FALSE */ ) { #undef SETBLOCK #define SETBLOCK 0 @@ -571,7 +571,7 @@ session_startup(LIBSSH2_SESSION *session, libssh2_socket_t sock) if (session->socket_prev_blockstate) { /* If in blocking state chang to non-blocking */ - session_nonblock(session->socket_fd, 1); + _libssh2_socket_nonblock(session->socket_fd, 1); } session->startup_state = libssh2_NB_state_created; @@ -922,7 +922,7 @@ session_free(LIBSSH2_SESSION *session) if(session->socket_prev_blockstate) /* if the socket was previously blocking, put it back so */ - session_nonblock(session->socket_fd, 0); + _libssh2_socket_nonblock(session->socket_fd, 0); if (session->server_hostkey) { LIBSSH2_FREE(session, session->server_hostkey); -- 1.6.5.4
>From e8d985878070dc497da9687d657277fda8885d4b Mon Sep 17 00:00:00 2001 From: Daiki Ueno <[email protected]> Date: Thu, 17 Dec 2009 00:14:49 +0900 Subject: [PATCH 6/7] Allow sign_callback of libssh2_userauth_publickey() to return EAGAIN. --- src/userauth.c | 27 +++++++++++++++------------ 1 files changed, 15 insertions(+), 12 deletions(-) diff --git a/src/userauth.c b/src/userauth.c index 6e28460..f339c46 100644 --- a/src/userauth.c +++ b/src/userauth.c @@ -1039,10 +1039,6 @@ userauth_publickey(LIBSSH2_SESSION *session, } if (session->userauth_pblc_state == libssh2_NB_state_sent) { - unsigned char *buf, *s; - unsigned char *sig; - unsigned long sig_len; - rc = _libssh2_packet_requirev(session, reply_codes, &session->userauth_pblc_data, &session->userauth_pblc_data_len, 0, @@ -1097,6 +1093,13 @@ userauth_publickey(LIBSSH2_SESSION *session, session->userauth_pblc_data = NULL; *session->userauth_pblc_b = 0x01; + session->userauth_pblc_state = libssh2_NB_state_sent1; + } + + if (session->userauth_pblc_state == libssh2_NB_state_sent1) { + unsigned char *buf, *s; + unsigned char *sig; + unsigned long sig_len; s = buf = LIBSSH2_ALLOC(session, 4 + session->session_id_len + session->userauth_pblc_packet_len); @@ -1115,8 +1118,11 @@ userauth_publickey(LIBSSH2_SESSION *session, session->userauth_pblc_packet_len); s += session->userauth_pblc_packet_len; - if (sign_callback(session, &sig, &sig_len, buf, s - buf, abstract)) { - LIBSSH2_FREE(session, buf); + rc = sign_callback(session, &sig, &sig_len, buf, s - buf, abstract); + LIBSSH2_FREE(session, buf); + if (rc == PACKET_EAGAIN) { + return rc; + } else if (rc) { LIBSSH2_FREE(session, session->userauth_pblc_method); session->userauth_pblc_method = NULL; LIBSSH2_FREE(session, session->userauth_pblc_packet); @@ -1125,9 +1131,6 @@ userauth_publickey(LIBSSH2_SESSION *session, return -1; } - - LIBSSH2_FREE(session, buf); - /* * If this function was restarted, pubkeydata_len might still be 0 * which will cause an unnecessary but harmless realloc here. @@ -1182,10 +1185,10 @@ userauth_publickey(LIBSSH2_SESSION *session, _libssh2_debug(session, LIBSSH2_TRACE_AUTH, "Attempting publickey authentication -- phase 2"); - session->userauth_pblc_state = libssh2_NB_state_sent1; + session->userauth_pblc_state = libssh2_NB_state_sent2; } - if (session->userauth_pblc_state == libssh2_NB_state_sent1) { + if (session->userauth_pblc_state == libssh2_NB_state_sent2) { rc = _libssh2_transport_write(session, session->userauth_pblc_packet, session->userauth_pblc_s - session->userauth_pblc_packet); @@ -1202,7 +1205,7 @@ userauth_publickey(LIBSSH2_SESSION *session, LIBSSH2_FREE(session, session->userauth_pblc_packet); session->userauth_pblc_packet = NULL; - session->userauth_pblc_state = libssh2_NB_state_sent2; + session->userauth_pblc_state = libssh2_NB_state_sent3; } /* PK_OK is no longer valid */ -- 1.6.5.4
>From a8884cca2183e37e8e2ded9b07420c0104f85d0b Mon Sep 17 00:00:00 2001 From: Daiki Ueno <[email protected]> Date: Thu, 17 Dec 2009 00:15:17 +0900 Subject: [PATCH 7/7] Inherit nonblocking setting from session. --- src/agent.c | 5 +++++ 1 files changed, 5 insertions(+), 0 deletions(-) diff --git a/src/agent.c b/src/agent.c index 9814abf..f765d34 100644 --- a/src/agent.c +++ b/src/agent.c @@ -144,6 +144,11 @@ agent_connect_unix(LIBSSH2_AGENT *agent) return -1; } + /* Inherit nonblocking setting from the current session */ + if (!libssh2_session_get_blocking(agent->session)) { + _libssh2_socket_nonblock(agent->u.fd, 1); + } + sun.sun_family = AF_UNIX; strncpy (sun.sun_path, path, sizeof sun.sun_path); if (connect(agent->u.fd, (struct sockaddr*)(&sun), sizeof sun) != 0) { -- 1.6.5.4
_______________________________________________ libssh2-devel http://cool.haxx.se/cgi-bin/mailman/listinfo/libssh2-devel
