aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--include/libssh/libssh.h2
-rw-r--r--src/channels.c82
2 files changed, 84 insertions, 0 deletions
diff --git a/include/libssh/libssh.h b/include/libssh/libssh.h
index 2aef726c..b42ace86 100644
--- a/include/libssh/libssh.h
+++ b/include/libssh/libssh.h
@@ -454,6 +454,8 @@ LIBSSH_API ssh_channel ssh_channel_new(ssh_session session);
LIBSSH_API int ssh_channel_open_auth_agent(ssh_channel channel);
LIBSSH_API int ssh_channel_open_forward(ssh_channel channel, const char *remotehost,
int remoteport, const char *sourcehost, int localport);
+LIBSSH_API int ssh_channel_open_forward_unix(ssh_channel channel, const char *remotepath,
+ const char *sourcehost, int localport);
LIBSSH_API int ssh_channel_open_session(ssh_channel channel);
LIBSSH_API int ssh_channel_open_x11(ssh_channel channel, const char *orig_addr, int orig_port);
LIBSSH_API int ssh_channel_poll(ssh_channel channel, int is_stderr);
diff --git a/src/channels.c b/src/channels.c
index d339f732..7b34c389 100644
--- a/src/channels.c
+++ b/src/channels.c
@@ -996,6 +996,88 @@ error:
return rc;
}
+/**
+ * @brief Open a TCP/IP - UNIX domain socket forwarding channel.
+ *
+ * @param[in] channel An allocated channel.
+ *
+ * @param[in] remotepath The UNIX socket path on the remote machine
+ *
+ * @param[in] sourcehost The numeric IP address of the machine from where the
+ * connection request originates. This is mostly for
+ * logging purposes.
+ *
+ * @param[in] localport The port on the host from where the connection
+ * originated. This is mostly for logging purposes.
+ *
+ * @return SSH_OK on success,
+ * SSH_ERROR if an error occurred,
+ * SSH_AGAIN if in nonblocking mode and call has
+ * to be done again.
+ *
+ * @warning This function does not bind the local port and does not
+ * automatically forward the content of a socket to the channel.
+ * You still have to use channel_read and channel_write for this.
+ * @warning Requires support of OpenSSH for UNIX domain socket forwarding.
+ */
+int ssh_channel_open_forward_unix(ssh_channel channel,
+ const char *remotepath,
+ const char *sourcehost,
+ int localport)
+{
+ ssh_session session = NULL;
+ ssh_buffer payload = NULL;
+ ssh_string str = NULL;
+ int rc = SSH_ERROR;
+ int version;
+
+ if (channel == NULL) {
+ return rc;
+ }
+
+ session = channel->session;
+
+ version = ssh_get_openssh_version(session);
+ if (version == 0) {
+ ssh_set_error(session,
+ SSH_REQUEST_DENIED,
+ "We're not connected to an OpenSSH server!");
+ return SSH_ERROR;
+ }
+
+ if (remotepath == NULL || sourcehost == NULL) {
+ ssh_set_error_invalid(session);
+ return rc;
+ }
+
+ payload = ssh_buffer_new();
+ if (payload == NULL) {
+ ssh_set_error_oom(session);
+ goto error;
+ }
+
+ rc = ssh_buffer_pack(payload,
+ "ssd",
+ remotepath,
+ sourcehost,
+ localport);
+ if (rc != SSH_OK) {
+ ssh_set_error_oom(session);
+ goto error;
+ }
+
+ rc = channel_open(channel,
+ "direct-streamlocal@openssh.com",
+ CHANNEL_INITIAL_WINDOW,
+ CHANNEL_MAX_PACKET,
+ payload);
+
+error:
+ ssh_buffer_free(payload);
+ ssh_string_free(str);
+
+ return rc;
+}
/**
* @brief Close and free a channel.