diff --git a/doc/forwarding.dox b/doc/forwarding.dox index ca3b94f8..63008a6c 100644 --- a/doc/forwarding.dox +++ b/doc/forwarding.dox @@ -165,6 +165,8 @@ int web_server(ssh_session session) char buffer[256]; int nbytes, nwritten; int port = 0; + char *peer_address = NULL; + int peer_port = 0; char *helloworld = "" "HTTP/1.1 200 OK\n" "Content-Type: text/html\n" @@ -187,7 +189,8 @@ int web_server(ssh_session session) return rc; } - channel = ssh_channel_accept_forward(session, 60000, &port); + channel = ssh_channel_open_forward_port(session, 60000, &port, + &peer_address, &peer_port); if (channel == NULL) { fprintf(stderr, "Error waiting for incoming connection: %s\n", @@ -204,6 +207,7 @@ int web_server(ssh_session session) ssh_get_error(session)); ssh_channel_send_eof(channel); ssh_channel_free(channel); + ssh_string_free_char(peer_address); return SSH_ERROR; } if (strncmp(buffer, "GET /", 5)) continue; @@ -216,13 +220,15 @@ int web_server(ssh_session session) ssh_get_error(session)); ssh_channel_send_eof(channel); ssh_channel_free(channel); + ssh_string_free_char(peer_address); return SSH_ERROR; } - printf("Sent answer\n"); + printf("Sent answer to %s:%d\n", peer_address, peer_port); } ssh_channel_send_eof(channel); ssh_channel_free(channel); + ssh_string_free_char(peer_address); return SSH_OK; } @endcode diff --git a/include/libssh/libssh.h b/include/libssh/libssh.h index f333db24..8cbe5cd7 100644 --- a/include/libssh/libssh.h +++ b/include/libssh/libssh.h @@ -510,7 +510,12 @@ LIBSSH_API char *ssh_dirname (const char *path); LIBSSH_API int ssh_finalize(void); /* REVERSE PORT FORWARDING */ -LIBSSH_API ssh_channel ssh_channel_accept_forward(ssh_session session, +LIBSSH_API ssh_channel ssh_channel_open_forward_port(ssh_session session, + int timeout_ms, + int *destination_port, + char **originator, + int *originator_port); +SSH_DEPRECATED LIBSSH_API ssh_channel ssh_channel_accept_forward(ssh_session session, int timeout_ms, int *destination_port); LIBSSH_API int ssh_channel_cancel_forward(ssh_session session, diff --git a/src/channels.c b/src/channels.c index f19b3ce7..5339adbc 100644 --- a/src/channels.c +++ b/src/channels.c @@ -29,6 +29,7 @@ #include #include #include +#include #ifdef HAVE_SYS_TIME_H #include #endif /* HAVE_SYS_TIME_H */ @@ -2135,7 +2136,7 @@ error: } static ssh_channel ssh_channel_accept(ssh_session session, int channeltype, - int timeout_ms, int *destination_port) { + int timeout_ms, int *destination_port, char **originator, int *originator_port) { #ifndef _WIN32 static const struct timespec ts = { .tv_sec = 0, @@ -2169,6 +2170,12 @@ static ssh_channel ssh_channel_accept(ssh_session session, int channeltype, if(destination_port) { *destination_port=msg->channel_request_open.destination_port; } + if(originator) { + *originator=strdup(msg->channel_request_open.originator); + } + if(originator_port) { + *originator_port=msg->channel_request_open.originator_port; + } ssh_message_free(msg); return channel; @@ -2200,7 +2207,7 @@ static ssh_channel ssh_channel_accept(ssh_session session, int channeltype, * the server. */ ssh_channel ssh_channel_accept_x11(ssh_channel channel, int timeout_ms) { - return ssh_channel_accept(channel->session, SSH_CHANNEL_X11, timeout_ms, NULL); + return ssh_channel_accept(channel->session, SSH_CHANNEL_X11, timeout_ms, NULL, NULL, NULL); } /** @@ -2454,11 +2461,11 @@ int ssh_forward_listen(ssh_session session, const char *address, int port, int * /* DEPRECATED */ ssh_channel ssh_forward_accept(ssh_session session, int timeout_ms) { - return ssh_channel_accept(session, SSH_CHANNEL_FORWARDED_TCPIP, timeout_ms, NULL); + return ssh_channel_accept(session, SSH_CHANNEL_FORWARDED_TCPIP, timeout_ms, NULL, NULL, NULL); } /** - * @brief Accept an incoming TCP/IP forwarding channel and get information + * @brief Accept an incoming TCP/IP forwarding channel and get some information * about incomming connection * @param[in] session The ssh session to use. * @@ -2470,7 +2477,30 @@ ssh_channel ssh_forward_accept(ssh_session session, int timeout_ms) { * the server */ ssh_channel ssh_channel_accept_forward(ssh_session session, int timeout_ms, int* destination_port) { - return ssh_channel_accept(session, SSH_CHANNEL_FORWARDED_TCPIP, timeout_ms, destination_port); + return ssh_channel_accept(session, SSH_CHANNEL_FORWARDED_TCPIP, timeout_ms, destination_port, NULL, NULL); +} + +/** + * @brief Accept an incoming TCP/IP forwarding channel and get information + * about incomming connection + * @param[in] session The ssh session to use. + * + * @param[in] timeout_ms A timeout in milliseconds. + * + * @param[out] destination_port A pointer to destination port or NULL. + * + * @param[out] originator A pointer to a pointer to a string of originator host or NULL. + * That the caller is responsible for to ssh_string_free_char(). + * + * @param[out] originator_port A pointer to originator port or NULL. + * + * @return Newly created channel, or NULL if no incoming channel request from + * the server + * + * @see ssh_string_free_char() + */ +ssh_channel ssh_channel_open_forward_port(ssh_session session, int timeout_ms, int *destination_port, char **originator, int *originator_port) { + return ssh_channel_accept(session, SSH_CHANNEL_FORWARDED_TCPIP, timeout_ms, destination_port, originator, originator_port); } /** diff --git a/tests/client/torture_forward.c b/tests/client/torture_forward.c index dcbdcbdb..18b8c85f 100644 --- a/tests/client/torture_forward.c +++ b/tests/client/torture_forward.c @@ -82,6 +82,8 @@ static void torture_ssh_forward(void **state) ssh_channel c; int dport; int bound_port; + char *originator_host = NULL; + int originator_port; int rc; int verbosity = SSH_LOG_TRACE; @@ -90,7 +92,7 @@ static void torture_ssh_forward(void **state) rc = ssh_channel_listen_forward(session, "127.0.0.21", 8080, &bound_port); assert_ssh_return_code(session, rc); - c = ssh_channel_accept_forward(session, 10, &dport); + c = ssh_channel_open_forward_port(session, 10, &dport, &originator_host, &originator_port); /* We do not get a listener and run into the timeout here */ assert_null(c);