diff options
author | milo <milo@r0ot.me> | 2011-03-11 13:39:29 +0100 |
---|---|---|
committer | milo <milo@r0ot.me> | 2011-04-14 14:05:44 +0200 |
commit | 7cc4471168550021eec6b7b97dc24c79d4fb366d (patch) | |
tree | 3c54819ef232295fd62296d5a37d70e6ed6f2275 | |
parent | 3046a5061433b7000964aec5169d127191b6aeed (diff) | |
download | libssh-7cc4471168550021eec6b7b97dc24c79d4fb366d.tar.gz libssh-7cc4471168550021eec6b7b97dc24c79d4fb366d.tar.xz libssh-7cc4471168550021eec6b7b97dc24c79d4fb366d.zip |
Implemented X11 server side
-rw-r--r-- | include/libssh/libssh.h | 3 | ||||
-rw-r--r-- | include/libssh/messages.h | 6 | ||||
-rw-r--r-- | include/libssh/server.h | 7 | ||||
-rw-r--r-- | src/channels.c | 63 | ||||
-rw-r--r-- | src/messages.c | 35 | ||||
-rw-r--r-- | src/server.c | 16 |
6 files changed, 129 insertions, 1 deletions
diff --git a/include/libssh/libssh.h b/include/libssh/libssh.h index b4a6a42f..3391ed15 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 5001fbe0..8f70b5fe 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 78dea2b1..cb12c133 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 6a4c98b2..ad1ed81d 100644 --- a/src/channels.c +++ b/src/channels.c @@ -2929,6 +2929,69 @@ error: } /** + * @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). * * Sends the exit status to the remote process. diff --git a/src/messages.c b/src/messages.c index 5953338a..dc4aabff 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 ae27efaa..e693fe95 100644 --- a/src/server.c +++ b/src/server.c @@ -1009,6 +1009,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; } |