[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[PATCH] client code for agent forwarding


Hi,

It would be nice if libssh could provide agent forwarding capabilities. Below is a patch to implement this.

It adds two API calls:
-ssh_channel_request_agent_forwarding: to inform server that agent forwarding is available
-ssh_channel_accept_auth_agent_forward: to accept the agent forwarding channel initiated by the server

The patch adds one session flag to make sure to only accept agent forwarding when it was requested it, and generate an error when the server provides an agent forward channel when it was not requested.

Signed off-by: Raf D'Halleweyn <raf@xxxxxxxxxx>

diff -Nru ./include/libssh/libssh.h ../../libssh-0.7.3/include/libssh/libssh.h
--- ./include/libssh/libssh.h	2016-02-23 02:23:19.000000000 -0500
+++ ../../libssh-0.7.3/include/libssh/libssh.h	2016-02-23 21:13:53.134940031 -0500
@@ -189,7 +189,8 @@
 	SSH_CHANNEL_SESSION,
 	SSH_CHANNEL_DIRECT_TCPIP,
 	SSH_CHANNEL_FORWARDED_TCPIP,
-	SSH_CHANNEL_X11
+	SSH_CHANNEL_X11,
+	SSH_CHANNEL_FORWARDED_AUTH_AGENT
 };
 
 enum ssh_channel_requests_e {
@@ -371,6 +372,7 @@
 
 LIBSSH_API int ssh_blocking_flush(ssh_session session, int timeout);
 LIBSSH_API ssh_channel ssh_channel_accept_x11(ssh_channel channel, int timeout_ms);
+LIBSSH_API ssh_channel ssh_channel_accept_auth_agent_forward(ssh_channel channel, int timeout_ms);
 LIBSSH_API int ssh_channel_change_pty_size(ssh_channel channel,int cols,int rows);
 LIBSSH_API int ssh_channel_close(ssh_channel channel);
 LIBSSH_API void ssh_channel_free(ssh_channel channel);
@@ -391,6 +393,7 @@
 LIBSSH_API int ssh_channel_read_timeout(ssh_channel channel, void *dest, uint32_t count, int is_stderr, int timeout_ms);
 LIBSSH_API int ssh_channel_read_nonblocking(ssh_channel channel, void *dest, uint32_t count,
     int is_stderr);
+LIBSSH_API int ssh_channel_request_agent_forwarding(ssh_channel channel);
 LIBSSH_API int ssh_channel_request_env(ssh_channel channel, const char *name, const char *value);
 LIBSSH_API int ssh_channel_request_exec(ssh_channel channel, const char *cmd);
 LIBSSH_API int ssh_channel_request_pty(ssh_channel channel);
diff -Nru ./include/libssh/session.h ../../libssh-0.7.3/include/libssh/session.h
--- ./include/libssh/session.h	2016-02-15 07:42:53.000000000 -0500
+++ ../../libssh-0.7.3/include/libssh/session.h	2016-02-23 21:13:53.134940031 -0500
@@ -69,6 +69,9 @@
 /* Client successfully authenticated */
 #define SSH_SESSION_FLAG_AUTHENTICATED 2
 
+/* the channel supports auth-agent forwarding */
+#define SSH_SESSION_AUTH_AGENT_FORWARDING 0x4
+
 /* codes to use with ssh_handle_packets*() */
 /* Infinite timeout */
 #define SSH_TIMEOUT_INFINITE -1
diff -Nru ./src/channels.c ../../libssh-0.7.3/src/channels.c
--- ./src/channels.c	2016-02-23 02:16:40.000000000 -0500
+++ ../../libssh-0.7.3/src/channels.c	2016-02-23 21:13:53.142939983 -0500
@@ -1600,6 +1600,26 @@
 }
 
 /**
+ * @brief Request to establish agent forwarding
+ *
+ * @param[in]  channel  The channel to send the request.
+ *
+ * @return              SSH_OK on success,
+ *                      SSH_ERROR if an error occurred,
+ *                      SSH_AGAIN if in nonblocking mode and call has
+ *                      to be done again.
+ */
+int ssh_channel_request_agent_forwarding(ssh_channel channel) {
+  if(channel == NULL) {
+      return SSH_ERROR;
+  }
+
+  channel->session->flags |= SSH_SESSION_AUTH_AGENT_FORWARDING;
+
+  return channel_request(channel, "auth-agent-req@xxxxxxxxxxx", NULL, 0);
+}
+
+/**
  * @brief Request a pty with a specific type and size.
  *
  * @param[in]  channel  The channel to sent the request.
@@ -1982,6 +2002,21 @@
 }
 
 /**
+ * @brief Accept an auth agent forwarding channel.
+ *
+ * @param[in]  channel  An session channel on which ssh_channel_request_agent_forwarding
+ *			had previously been called.
+ *
+ * @param[in]  timeout_ms Timeout in milliseconds.
+ *
+ * @return              A newly created channel, or NULL if no auth-agent request from
+ *                      the server.
+ */
+ssh_channel ssh_channel_accept_auth_agent_forward(ssh_channel channel, int timeout_ms) {
+  return ssh_channel_accept(channel->session, SSH_CHANNEL_FORWARDED_AUTH_AGENT, timeout_ms, NULL);
+}
+
+/**
  * @internal
  *
  * @brief Handle a SSH_REQUEST_SUCCESS packet normally sent after a global
diff -Nru ./src/messages.c ../../libssh-0.7.3/src/messages.c
--- ./src/messages.c	2016-02-23 02:16:40.000000000 -0500
+++ ../../libssh-0.7.3/src/messages.c	2016-02-23 21:13:53.150939934 -0500
@@ -1070,6 +1070,18 @@
     goto end;
   }
 
+  if (strcmp(type_c,"auth-agent@xxxxxxxxxxx") == 0) {
+    if (! (session->flags & SSH_SESSION_AUTH_AGENT_FORWARDING)) {
+      /* do not establish agent forwarding if we didn't offer it! */
+      ssh_set_error(session,SSH_FATAL, "Unanounced auth-agent@xxxxxxxxxxx requested, possible server compromise");
+      goto error;
+    }
+    SSH_LOG(SSH_LOG_WARNING, "Establishing an auth-agent channel");
+
+    msg->channel_request_open.type = SSH_CHANNEL_FORWARDED_AUTH_AGENT;
+    goto end;
+  }
+
   msg->channel_request_open.type = SSH_CHANNEL_UNKNOWN;
   goto end;
 

Archive administrator: postmaster@lists.cynapses.org