1
1

Add x11 forwarding support for ssh client

Signed-off-by: Vic Lee <llyzs@163.com>
Signed-off-by: Andreas Schneider <mail@cynapses.org>
Этот коммит содержится в:
Vic Lee 2009-07-30 22:13:20 +08:00 коммит произвёл Andreas Schneider
родитель a040e2e3db
Коммит 63053541e6
4 изменённых файлов: 125 добавлений и 0 удалений

Просмотреть файл

@ -284,6 +284,9 @@ int channel_request_subsystem(ssh_channel channel, const char *system);
int channel_request_env(ssh_channel channel, const char *name, const char *value); int channel_request_env(ssh_channel channel, const char *name, const char *value);
int channel_request_exec(ssh_channel channel, const char *cmd); int channel_request_exec(ssh_channel channel, const char *cmd);
int channel_request_sftp(ssh_channel channel); int channel_request_sftp(ssh_channel channel);
int channel_request_x11(ssh_channel channel, int single_connection, const char *protocol,
const char *cookie, int screen_number);
ssh_channel channel_accept_x11(ssh_channel channel, int timeout_ms);
int channel_write(ssh_channel channel, const void *data, uint32_t len); int channel_write(ssh_channel channel, const void *data, uint32_t len);
int channel_send_eof(ssh_channel channel); int channel_send_eof(ssh_channel channel);
int channel_is_eof(ssh_channel channel); int channel_is_eof(ssh_channel channel);

Просмотреть файл

@ -26,6 +26,7 @@
#include <stdlib.h> #include <stdlib.h>
#include <stdio.h> #include <stdio.h>
#include <errno.h> #include <errno.h>
#include <time.h>
#ifndef _WIN32 #ifndef _WIN32
#include <arpa/inet.h> #include <arpa/inet.h>
@ -33,6 +34,7 @@
#include "libssh/priv.h" #include "libssh/priv.h"
#include "libssh/ssh2.h" #include "libssh/ssh2.h"
#include "libssh/server.h"
#define WINDOWBASE 128000 #define WINDOWBASE 128000
#define WINDOWLIMIT (WINDOWBASE/2) #define WINDOWLIMIT (WINDOWBASE/2)
@ -1256,6 +1258,122 @@ int channel_request_sftp( ssh_channel channel){
return channel_request_subsystem(channel, "sftp"); 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. * @brief Set environement variables.
* *

Просмотреть файл

@ -26,6 +26,8 @@ channel_request_pty_size
channel_request_sftp channel_request_sftp
channel_request_shell channel_request_shell
channel_request_subsystem channel_request_subsystem
channel_request_x11
channel_accept_x11
channel_select channel_select
channel_send_eof channel_send_eof
channel_set_blocking channel_set_blocking

Просмотреть файл

@ -187,6 +187,8 @@ SSH_0.3 {
SSH_0.4 { SSH_0.4 {
global: global:
channel_write_stderr; channel_write_stderr;
channel_request_x11;
channel_accept_x11;
sftp_extensions_get_count; sftp_extensions_get_count;
sftp_extensions_get_data; sftp_extensions_get_data;
sftp_extensions_get_name; sftp_extensions_get_name;