From 2122fc3dcb5dcf46cd1f2f81680cf3e020ff23f7 Mon Sep 17 00:00:00 2001 From: Adley Phu Date: Tue, 18 Apr 2023 22:35:34 +0800 Subject: [PATCH] Add callback to accept forwarded-tcpip requests Signed-off-by: Adley Phu Reviewed-by: Jakub Jelen --- include/libssh/callbacks.h | 25 ++++++++++++++++++++++++ src/messages.c | 39 ++++++++++++++++++++++---------------- 2 files changed, 48 insertions(+), 16 deletions(-) diff --git a/include/libssh/callbacks.h b/include/libssh/callbacks.h index 6b7d4788..34016595 100644 --- a/include/libssh/callbacks.h +++ b/include/libssh/callbacks.h @@ -139,6 +139,26 @@ typedef ssh_channel (*ssh_channel_open_request_x11_callback) (ssh_session sessio typedef ssh_channel (*ssh_channel_open_request_auth_agent_callback) (ssh_session session, void *userdata); +/** + * @brief Handles an SSH new channel open "forwarded-tcpip" request. This + * happens when the server forwards an incoming TCP connection on a port it was + * previously requested to listen on. This is a client-side API + * @param session current session handler + * @param destination_address the address that the TCP connection connected to + * @param destination_port the port that the TCP connection connected to + * @param originator_address the originator IP address + * @param originator_port the originator port + * @param userdata Userdata to be passed to the callback function. + * @returns a valid ssh_channel handle if the request is to be allowed + * @returns NULL if the request should not be allowed + * @warning The channel pointer returned by this callback must be closed by the + * application. + */ +typedef ssh_channel (*ssh_channel_open_request_forwarded_tcpip_callback) (ssh_session session, + const char *destination_address, int destination_port, + const char *originator_address, int originator_port, + void *userdata); + /** * The structure to replace libssh functions with appropriate callbacks. */ @@ -172,6 +192,11 @@ struct ssh_callbacks_struct { /** This function will be called when an incoming "auth-agent" request is received. */ ssh_channel_open_request_auth_agent_callback channel_open_request_auth_agent_function; + /** + * This function will be called when an incoming "forwarded-tcpip" + * request is received. + */ + ssh_channel_open_request_forwarded_tcpip_callback channel_open_request_forwarded_tcpip_function; }; typedef struct ssh_callbacks_struct *ssh_callbacks; diff --git a/src/messages.c b/src/messages.c index 289dd6c2..6ec4c75a 100644 --- a/src/messages.c +++ b/src/messages.c @@ -317,6 +317,17 @@ static int ssh_execute_server_request(ssh_session session, ssh_message msg) return SSH_AGAIN; } +static int ssh_reply_channel_open_request(ssh_message msg, ssh_channel channel) +{ + if (channel != NULL) { + return ssh_message_channel_request_open_reply_accept_channel(msg, channel); + } + + ssh_message_reply_default(msg); + + return SSH_OK; +} + static int ssh_execute_client_request(ssh_session session, ssh_message msg) { ssh_channel channel = NULL; @@ -329,30 +340,26 @@ static int ssh_execute_client_request(ssh_session session, ssh_message msg) msg->channel_request_open.originator, msg->channel_request_open.originator_port, session->common.callbacks->userdata); - if (channel != NULL) { - rc = ssh_message_channel_request_open_reply_accept_channel(msg, channel); - return rc; - } else { - ssh_message_reply_default(msg); - } - - return SSH_OK; + return ssh_reply_channel_open_request(msg, channel); } else if (msg->type == SSH_REQUEST_CHANNEL_OPEN && msg->channel_request_open.type == SSH_CHANNEL_AUTH_AGENT && ssh_callbacks_exists(session->common.callbacks, channel_open_request_auth_agent_function)) { channel = session->common.callbacks->channel_open_request_auth_agent_function (session, session->common.callbacks->userdata); - if (channel != NULL) { - rc = ssh_message_channel_request_open_reply_accept_channel(msg, channel); + return ssh_reply_channel_open_request(msg, channel); + } else if (msg->type == SSH_REQUEST_CHANNEL_OPEN + && msg->channel_request_open.type == SSH_CHANNEL_FORWARDED_TCPIP + && ssh_callbacks_exists(session->common.callbacks, channel_open_request_forwarded_tcpip_function)) { + channel = session->common.callbacks->channel_open_request_forwarded_tcpip_function(session, + msg->channel_request_open.destination, + msg->channel_request_open.destination_port, + msg->channel_request_open.originator, + msg->channel_request_open.originator_port, + session->common.callbacks->userdata); - return rc; - } else { - ssh_message_reply_default(msg); - } - - return SSH_OK; + return ssh_reply_channel_open_request(msg, channel); } return rc;