aboutsummaryrefslogtreecommitdiff
path: root/libssh
diff options
context:
space:
mode:
authorVic Lee <llyzs@163.com>2009-07-30 22:13:20 +0800
committerAndreas Schneider <mail@cynapses.org>2009-07-31 11:17:51 +0200
commit63053541e6bc477f0260b81871c2e8bf08e77ddd (patch)
tree4b4f82087f9e2a7736ce76780bffdbb2388fb85e /libssh
parenta040e2e3dbb18399a5c4b48d6187d18cbbd6da78 (diff)
downloadlibssh-63053541e6bc477f0260b81871c2e8bf08e77ddd.tar.gz
libssh-63053541e6bc477f0260b81871c2e8bf08e77ddd.tar.xz
libssh-63053541e6bc477f0260b81871c2e8bf08e77ddd.zip
Add x11 forwarding support for ssh client
Signed-off-by: Vic Lee <llyzs@163.com> Signed-off-by: Andreas Schneider <mail@cynapses.org>
Diffstat (limited to 'libssh')
-rw-r--r--libssh/channels.c118
-rw-r--r--libssh/libssh.def2
-rw-r--r--libssh/libssh.map2
3 files changed, 122 insertions, 0 deletions
diff --git a/libssh/channels.c b/libssh/channels.c
index 2dd9966d..cd10bc22 100644
--- a/libssh/channels.c
+++ b/libssh/channels.c
@@ -26,6 +26,7 @@
#include <stdlib.h>
#include <stdio.h>
#include <errno.h>
+#include <time.h>
#ifndef _WIN32
#include <arpa/inet.h>
@@ -33,6 +34,7 @@
#include "libssh/priv.h"
#include "libssh/ssh2.h"
+#include "libssh/server.h"
#define WINDOWBASE 128000
#define WINDOWLIMIT (WINDOWBASE/2)
@@ -1256,6 +1258,122 @@ int channel_request_sftp( ssh_channel channel){
return channel_request_subsystem(channel, "sftp");
}
+static void generate_cookie(char *s) {
+ static const char *hex = "0123456789abcdef";
+ int i;
+
+ srand ((unsigned int)time(NULL));
+ for (i = 0; i < 32; i++) {
+ s[i] = hex[rand() % 16];
+ }
+ s[32] = '\0';
+}
+
+/**
+ * @brief Sends the "x11-req" channel request over an existing session channel.
+ *
+ * This will enable redirecting the display of the remote X11 applications to
+ * local X server over an secure tunnel.
+ *
+ * @param channel An existing session channel where the remote X11
+ * applications are going to be executed.
+ *
+ * @param single_connection A boolean to mark only one X11 app will be
+ * redirected.
+ *
+ * @param protocol x11 authentication protocol. Pass NULL to use the
+ * default value MIT-MAGIC-COOKIE-1
+ *
+ * @param cookie x11 authentication cookie. Pass NULL to generate
+ * a random cookie.
+ *
+ * @param screen_number Screen number.
+ *
+ * @return SSH_OK on success\n
+ * SSH_ERROR on error
+ */
+int channel_request_x11(ssh_channel channel, int single_connection, const char *protocol,
+ const char *cookie, int screen_number) {
+ ssh_buffer buffer = NULL;
+ ssh_string p = NULL;
+ ssh_string c = NULL;
+ char s[32];
+ int rc = SSH_ERROR;
+
+ buffer = buffer_new();
+ if (buffer == NULL) {
+ goto error;
+ }
+
+ p = string_from_char(protocol ? protocol : "MIT-MAGIC-COOKIE-1");
+ if (p == NULL) {
+ goto error;
+ }
+
+ if (cookie) {
+ c = string_from_char(cookie);
+ } else {
+ generate_cookie(s);
+ c = string_from_char(s);
+ }
+ if (c == NULL) {
+ goto error;
+ }
+
+ if (buffer_add_u8(buffer, single_connection == 0 ? 0 : 1) < 0 ||
+ buffer_add_ssh_string(buffer, p) < 0 ||
+ buffer_add_ssh_string(buffer, c) < 0 ||
+ buffer_add_u32(buffer, htonl(screen_number)) < 0) {
+ goto error;
+ }
+
+ rc = channel_request(channel, "x11-req", buffer, 1);
+
+error:
+ buffer_free(buffer);
+ string_free(p);
+ string_free(c);
+ return rc;
+}
+
+/**
+ * @brief Accept an X11 forwarding channel.
+ *
+ * @param channel An x11-enabled session channel.
+ *
+ * @param timeout_ms Timeout in milli-seconds.
+ *
+ * @return Newly created channel, or NULL if no X11 request from the server
+ */
+ssh_channel channel_accept_x11(ssh_channel channel, int timeout_ms) {
+ static const struct timespec ts = {0, 50000000}; /* 50ms */
+ SSH_SESSION *session = channel->session;
+ SSH_MESSAGE *msg = NULL;
+ struct ssh_iterator *iterator;
+ int t;
+
+ for (t = timeout_ms; t >= 0; t -= 50)
+ {
+ ssh_handle_packets(session);
+
+ if (session->ssh_message_list) {
+ iterator = ssh_list_get_iterator(session->ssh_message_list);
+ while (iterator) {
+ msg = (SSH_MESSAGE*)iterator->data;
+ if (ssh_message_type(msg) == SSH_CHANNEL_REQUEST_OPEN &&
+ ssh_message_subtype(msg) == SSH_CHANNEL_X11) {
+ ssh_list_remove(session->ssh_message_list, iterator);
+ return ssh_message_channel_request_open_reply_accept(msg);
+ }
+ iterator = iterator->next;
+ }
+ }
+ nanosleep(&ts, NULL);
+ }
+
+ return NULL;
+}
+
/**
* @brief Set environement variables.
*
diff --git a/libssh/libssh.def b/libssh/libssh.def
index 0989ec3a..b679db58 100644
--- a/libssh/libssh.def
+++ b/libssh/libssh.def
@@ -26,6 +26,8 @@ channel_request_pty_size
channel_request_sftp
channel_request_shell
channel_request_subsystem
+channel_request_x11
+channel_accept_x11
channel_select
channel_send_eof
channel_set_blocking
diff --git a/libssh/libssh.map b/libssh/libssh.map
index b5d53965..c7bdd238 100644
--- a/libssh/libssh.map
+++ b/libssh/libssh.map
@@ -187,6 +187,8 @@ SSH_0.3 {
SSH_0.4 {
global:
channel_write_stderr;
+ channel_request_x11;
+ channel_accept_x11;
sftp_extensions_get_count;
sftp_extensions_get_data;
sftp_extensions_get_name;