summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authormilo <milo@r0ot.me>2011-03-11 13:39:29 +0100
committermilo <milo@r0ot.me>2011-04-14 14:05:44 +0200
commit7cc4471168550021eec6b7b97dc24c79d4fb366d (patch)
tree3c54819ef232295fd62296d5a37d70e6ed6f2275
parent3046a5061433b7000964aec5169d127191b6aeed (diff)
downloadlibssh-7cc4471168550021eec6b7b97dc24c79d4fb366d.tar.gz
libssh-7cc4471168550021eec6b7b97dc24c79d4fb366d.tar.xz
libssh-7cc4471168550021eec6b7b97dc24c79d4fb366d.zip
Implemented X11 server side
-rw-r--r--include/libssh/libssh.h3
-rw-r--r--include/libssh/messages.h6
-rw-r--r--include/libssh/server.h7
-rw-r--r--src/channels.c63
-rw-r--r--src/messages.c35
-rw-r--r--src/server.c16
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;
}