From b8b3a9fe45d1111b4ccc383735a6cf8bcaaf41e6 Mon Sep 17 00:00:00 2001 From: milo Date: Fri, 11 Mar 2011 13:39:29 +0100 Subject: Implemented X11 server side --- include/libssh/libssh.h | 3 ++- include/libssh/messages.h | 6 +++++ include/libssh/server.h | 7 ++++++ src/channels.c | 63 +++++++++++++++++++++++++++++++++++++++++++++++ src/messages.c | 35 ++++++++++++++++++++++++++ src/server.c | 16 ++++++++++++ 6 files changed, 129 insertions(+), 1 deletion(-) diff --git a/include/libssh/libssh.h b/include/libssh/libssh.h index 504aac9..a4d0521 100644 --- a/include/libssh/libssh.h +++ b/include/libssh/libssh.h @@ -192,7 +192,8 @@ enum ssh_channel_requests_e { SSH_CHANNEL_REQUEST_SHELL, SSH_CHANNEL_REQUEST_ENV, SSH_CHANNEL_REQUEST_SUBSYSTEM, - SSH_CHANNEL_REQUEST_WINDOW_CHANGE + SSH_CHANNEL_REQUEST_WINDOW_CHANGE, + SSH_CHANNEL_REQUEST_X11 }; enum ssh_global_requests_e { diff --git a/include/libssh/messages.h b/include/libssh/messages.h index 5001fbe..8f70b5f 100644 --- a/include/libssh/messages.h +++ b/include/libssh/messages.h @@ -74,6 +74,12 @@ struct ssh_channel_request { char *command; /* subsystem */ char *subsystem; + + /* X11 */ + uint8_t x11_single_connection; + char *x11_auth_protocol; + char *x11_auth_cookie; + uint32_t x11_screen_number; }; struct ssh_message_struct { diff --git a/include/libssh/server.h b/include/libssh/server.h index 78dea2b..cb12c13 100644 --- a/include/libssh/server.h +++ b/include/libssh/server.h @@ -325,11 +325,18 @@ LIBSSH_API const char *ssh_message_channel_request_command(ssh_message msg); LIBSSH_API const char *ssh_message_channel_request_subsystem(ssh_message msg); +LIBSSH_API int ssh_message_channel_request_x11_single_connection(ssh_message msg); +LIBSSH_API const char *ssh_message_channel_request_x11_auth_protocol(ssh_message msg); +LIBSSH_API const char *ssh_message_channel_request_x11_auth_cookie(ssh_message msg); +LIBSSH_API int ssh_message_channel_request_x11_screen_number(ssh_message msg); + LIBSSH_API const char *ssh_message_global_request_address(ssh_message msg); LIBSSH_API int ssh_message_global_request_port(ssh_message msg); LIBSSH_API int ssh_channel_open_reverse_forward(ssh_channel channel, const char *remotehost, int remoteport, const char *sourcehost, int localport); +LIBSSH_API int ssh_channel_open_x11(ssh_channel channel, + const char *orig_addr, int orig_port); LIBSSH_API int ssh_channel_request_send_exit_status(ssh_channel channel, int exit_status); diff --git a/src/channels.c b/src/channels.c index 6a4c98b..ad1ed81 100644 --- a/src/channels.c +++ b/src/channels.c @@ -2928,6 +2928,69 @@ error: return rc; } +/** + * @brief Open a X11 channel. + * + * @param[in] channel An allocated channel. + * + * @param[in] orig_addr The source host (the local server). + * + * @param[in] orig_port The source port (the local server). + * + * @return SSH_OK on success, SSH_ERROR if an error occured. + * + * @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. + */ +int ssh_channel_open_x11(ssh_channel channel, + const char *orig_addr, int orig_port) { + ssh_session session; + ssh_buffer payload = NULL; + ssh_string str = NULL; + int rc = SSH_ERROR; + + if(channel == NULL) { + return rc; + } + if(orig_addr == NULL) { + ssh_set_error_invalid(channel->session, __FUNCTION__); + return rc; + } + + + session = channel->session; + + enter_function(); + + payload = ssh_buffer_new(); + if (payload == NULL) { + ssh_set_error_oom(session); + goto error; + } + + str = ssh_string_from_char(orig_addr); + if (str == NULL) { + ssh_set_error_oom(session); + goto error; + } + + if (buffer_add_ssh_string(payload, str) < 0 || + buffer_add_u32(payload,htonl(orig_port)) < 0) { + ssh_set_error_oom(session); + goto error; + } + + rc = channel_open(channel, "x11", 64000, 32000, payload); + +error: + ssh_buffer_free(payload); + ssh_string_free(str); + + leave_function(); + return rc; +} + /** * @brief Send the exit status to the remote process (as described in RFC 4254, section 6.10). * diff --git a/src/messages.c b/src/messages.c index 5953338..dc4aabf 100644 --- a/src/messages.c +++ b/src/messages.c @@ -988,6 +988,41 @@ int ssh_message_handle_channel_request(ssh_session session, ssh_channel channel, goto end; } + if (strcmp(request, "x11-req") == 0) { + ssh_string auth_protocol = NULL; + ssh_string auth_cookie = NULL; + + buffer_get_u8(packet, &msg->channel_request.x11_single_connection); + + auth_protocol = buffer_get_ssh_string(packet); + if (auth_protocol == NULL) { + ssh_set_error_oom(session); + goto error; + } + auth_cookie = buffer_get_ssh_string(packet); + if (auth_cookie == NULL) { + ssh_set_error_oom(session); + ssh_string_free(auth_protocol); + goto error; + } + + msg->channel_request.type = SSH_CHANNEL_REQUEST_X11; + msg->channel_request.x11_auth_protocol = ssh_string_to_char(auth_protocol); + msg->channel_request.x11_auth_cookie = ssh_string_to_char(auth_cookie); + if (msg->channel_request.x11_auth_protocol == NULL || + msg->channel_request.x11_auth_cookie == NULL) { + ssh_string_free(auth_protocol); + ssh_string_free(auth_cookie); + goto error; + } + ssh_string_free(auth_protocol); + ssh_string_free(auth_cookie); + + buffer_get_u32(packet, &msg->channel_request.x11_screen_number); + + goto end; + } + msg->channel_request.type = SSH_CHANNEL_UNKNOWN; end: ssh_message_queue(session,msg); diff --git a/src/server.c b/src/server.c index 70e8359..48c7716 100644 --- a/src/server.c +++ b/src/server.c @@ -1001,6 +1001,22 @@ const char *ssh_message_channel_request_subsystem(ssh_message msg){ return msg->channel_request.subsystem; } +int ssh_message_channel_request_x11_single_connection(ssh_message msg){ + return msg->channel_request.x11_single_connection ? 1 : 0; +} + +const char *ssh_message_channel_request_x11_auth_protocol(ssh_message msg){ + return msg->channel_request.x11_auth_protocol; +} + +const char *ssh_message_channel_request_x11_auth_cookie(ssh_message msg){ + return msg->channel_request.x11_auth_cookie; +} + +int ssh_message_channel_request_x11_screen_number(ssh_message msg){ + return msg->channel_request.x11_screen_number; +} + const char *ssh_message_global_request_address(ssh_message msg){ return msg->global_request.bind_address; } -- cgit v1.2.3