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

Reply via email to