Add x11 forwarding support for ssh client
Signed-off-by: Vic Lee <llyzs@163.com> Signed-off-by: Andreas Schneider <mail@cynapses.org>
Этот коммит содержится в:
родитель
a040e2e3db
Коммит
63053541e6
@ -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;
|
||||||
|
Загрузка…
x
Ссылка в новой задаче
Block a user